From b0f36a0043d76436cc7ab8ff92ab99c94595d3c0 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 15 Jul 2016 06:50:47 +0200 Subject: [PATCH 0001/3374] avconv: stop using setpts for input framerate forced with -r The setpts filter does not signal to the rest of the filtergraph that the stream is CFR. Just generate the timestamps manually instead. --- avconv.c | 2 ++ avconv.h | 5 +++++ avconv_filter.c | 19 ++----------------- configure | 2 +- 4 files changed, 10 insertions(+), 18 deletions(-) diff --git a/avconv.c b/avconv.c index 3a7a898aa0fef..57c02ac4fc8f7 100644 --- a/avconv.c +++ b/avconv.c @@ -1392,6 +1392,8 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) decoded_frame->pts = guess_correct_pts(&ist->pts_ctx, decoded_frame->pts, decoded_frame->pkt_dts); + if (ist->framerate.num) + decoded_frame->pts = ist->cfr_next_pts++; if (ist->st->sample_aspect_ratio.num) decoded_frame->sample_aspect_ratio = ist->st->sample_aspect_ratio; diff --git a/avconv.h b/avconv.h index cffe11473fd4c..fcdf3d04613e2 100644 --- a/avconv.h +++ b/avconv.h @@ -269,6 +269,11 @@ typedef struct InputStream { int64_t last_dts; int64_t min_pts; /* pts with the smallest value in a current stream */ int64_t max_pts; /* pts with the higher value in a current stream */ + + // when forcing constant input framerate through -r, + // this contains the pts that will be given to the next decoded frame + int64_t cfr_next_pts; + int64_t nb_samples; /* number of samples in the last decoded audio frame before looping */ PtsCorrectionContext pts_ctx; double ts_scale; diff --git a/avconv_filter.c b/avconv_filter.c index 96277f80ebe84..b78d3bdb94976 100644 --- a/avconv_filter.c +++ b/avconv_filter.c @@ -519,6 +519,8 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter, par->height = ifilter->height; par->format = ifilter->format; par->time_base = tb; + if (ist->framerate.num) + par->frame_rate = ist->framerate; par->hw_frames_ctx = ifilter->hw_frames_ctx; ret = av_buffersrc_parameters_set(ifilter->filter, par); @@ -552,23 +554,6 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter, } } - if (ist->framerate.num) { - AVFilterContext *setpts; - - snprintf(name, sizeof(name), "force CFR for input from stream %d:%d", - ist->file_index, ist->st->index); - if ((ret = avfilter_graph_create_filter(&setpts, - avfilter_get_by_name("setpts"), - name, "N", NULL, - fg->graph)) < 0) - return ret; - - if ((ret = avfilter_link(last_filter, 0, setpts, 0)) < 0) - return ret; - - last_filter = setpts; - } - snprintf(name, sizeof(name), "trim for input stream %d:%d", ist->file_index, ist->st->index); ret = insert_trim(((f->start_time == AV_NOPTS_VALUE) || !f->accurate_seek) ? diff --git a/configure b/configure index 37c5611293534..58855193c68ec 100755 --- a/configure +++ b/configure @@ -2436,7 +2436,7 @@ swscale_deps="avutil" avconv_deps="avcodec avfilter avformat avresample swscale" avconv_select="aformat_filter anull_filter asyncts_filter atrim_filter format_filter fps_filter null_filter resample_filter scale_filter - setpts_filter trim_filter" + trim_filter" avplay_deps="avcodec avfilter avformat avresample sdl" avplay_libs='$sdl_libs' avplay_select="rdft format_filter transpose_filter hflip_filter vflip_filter" From 6f40181cad8ac04adff7bd10e1e1ab65f22bc1f0 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 13 Jul 2016 09:15:56 +0200 Subject: [PATCH 0002/3374] avconv_qsv: align the surface size to 32 This is required e.g. by HEVC. --- avconv_qsv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/avconv_qsv.c b/avconv_qsv.c index 8272f17194070..400cf22c8797d 100644 --- a/avconv_qsv.c +++ b/avconv_qsv.c @@ -76,8 +76,8 @@ int qsv_init(AVCodecContext *s) frames_ctx = (AVHWFramesContext*)ist->hw_frames_ctx->data; frames_hwctx = frames_ctx->hwctx; - frames_ctx->width = s->coded_width; - frames_ctx->height = s->coded_height; + frames_ctx->width = FFALIGN(s->coded_width, 32); + frames_ctx->height = FFALIGN(s->coded_height, 32); frames_ctx->format = AV_PIX_FMT_QSV; frames_ctx->sw_format = AV_PIX_FMT_NV12; frames_ctx->initial_pool_size = 32; From 8b7a9729aa162e2bbd571933f1aa40767f1ff47b Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 13 Jul 2016 09:16:35 +0200 Subject: [PATCH 0003/3374] avconv_qsv: use the actual pixel format provided by lavc Do not hardcode NV12. This allows 10bit decoding with -hwaccel qsv. --- avconv_qsv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avconv_qsv.c b/avconv_qsv.c index 400cf22c8797d..723c6e0224510 100644 --- a/avconv_qsv.c +++ b/avconv_qsv.c @@ -79,7 +79,7 @@ int qsv_init(AVCodecContext *s) frames_ctx->width = FFALIGN(s->coded_width, 32); frames_ctx->height = FFALIGN(s->coded_height, 32); frames_ctx->format = AV_PIX_FMT_QSV; - frames_ctx->sw_format = AV_PIX_FMT_NV12; + frames_ctx->sw_format = s->sw_pix_fmt; frames_ctx->initial_pool_size = 32; frames_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; From d59641abfd25a1007bdf4723d952887b1e3619c6 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 14 Jul 2016 12:16:17 +0200 Subject: [PATCH 0004/3374] lavc: initialize AVCodecContext.sw_pix_fmt properly Currently it's memset to 0, which is YUV420P. It should be initialized to none. --- libavcodec/options.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/options.c b/libavcodec/options.c index 18613ace965bc..00921fbec3856 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -98,6 +98,7 @@ static int init_context_defaults(AVCodecContext *s, const AVCodec *codec) s->execute2 = avcodec_default_execute2; s->sample_aspect_ratio = (AVRational){0,1}; s->pix_fmt = AV_PIX_FMT_NONE; + s->sw_pix_fmt = AV_PIX_FMT_NONE; s->sample_fmt = AV_SAMPLE_FMT_NONE; s->reordered_opaque = AV_NOPTS_VALUE; From f65285aba0df7d46298abe0c945dfee05cbc6028 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 14 Jul 2016 12:13:53 +0200 Subject: [PATCH 0005/3374] lavc: set sw_pix_fmt for hwaccel encoding --- libavcodec/utils.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libavcodec/utils.c b/libavcodec/utils.c index bc1beee4626d3..4184b95e634b9 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -1113,6 +1113,17 @@ FF_ENABLE_DEPRECATION_WARNINGS ret = AVERROR(EINVAL); goto free_and_end; } + if (avctx->sw_pix_fmt != AV_PIX_FMT_NONE && + avctx->sw_pix_fmt != frames_ctx->sw_format) { + av_log(avctx, AV_LOG_ERROR, + "Mismatching AVCodecContext.sw_pix_fmt (%s) " + "and AVHWFramesContext.sw_format (%s)\n", + av_get_pix_fmt_name(avctx->sw_pix_fmt), + av_get_pix_fmt_name(frames_ctx->sw_format)); + ret = AVERROR(EINVAL); + goto free_and_end; + } + avctx->sw_pix_fmt = frames_ctx->sw_format; } } From 21962261c74aed4df00ae8348a5e2d1ecb67c52d Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 14 Jul 2016 12:31:47 +0200 Subject: [PATCH 0006/3374] qsv: handle the semi-packed formats in map_fourcc as well This will allow using this function for encoding as well, where the input format is already the semi-packed version. --- libavcodec/qsv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index 5f7653a3bfd72..c8b397810fb9f 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -94,9 +94,11 @@ int ff_qsv_map_pixfmt(enum AVPixelFormat format, uint32_t *fourcc) switch (format) { case AV_PIX_FMT_YUV420P: case AV_PIX_FMT_YUVJ420P: + case AV_PIX_FMT_NV12: *fourcc = MFX_FOURCC_NV12; return AV_PIX_FMT_NV12; case AV_PIX_FMT_YUV420P10: + case AV_PIX_FMT_P010: *fourcc = MFX_FOURCC_P010; return AV_PIX_FMT_P010; default: From 37a9015ee84c15fec5247ba8f6577351a25fa8d2 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 22 Jun 2016 19:57:28 +0200 Subject: [PATCH 0007/3374] qsvenc: add support for p010 --- libavcodec/qsvenc.c | 16 +++++++++++++--- libavcodec/qsvenc_h264.c | 1 + libavcodec/qsvenc_hevc.c | 1 + 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index 2bb7a1de750fe..e28f3545ec70e 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -385,7 +385,16 @@ static int init_video_param(AVCodecContext *avctx, QSVEncContext *q) AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx; q->param.mfx.FrameInfo = frames_hwctx->surfaces[0].Info; } else { - q->param.mfx.FrameInfo.FourCC = MFX_FOURCC_NV12; + enum AVPixelFormat sw_format = avctx->pix_fmt == AV_PIX_FMT_QSV ? + avctx->sw_pix_fmt : avctx->pix_fmt; + const AVPixFmtDescriptor *desc; + + desc = av_pix_fmt_desc_get(sw_format); + if (!desc) + return AVERROR_BUG; + + ff_qsv_map_pixfmt(sw_format, &q->param.mfx.FrameInfo.FourCC); + q->param.mfx.FrameInfo.Width = FFALIGN(avctx->width, q->width_align); q->param.mfx.FrameInfo.Height = FFALIGN(avctx->height, 32); q->param.mfx.FrameInfo.CropX = 0; @@ -396,8 +405,9 @@ static int init_video_param(AVCodecContext *avctx, QSVEncContext *q) q->param.mfx.FrameInfo.AspectRatioH = avctx->sample_aspect_ratio.den; q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE; q->param.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420; - q->param.mfx.FrameInfo.BitDepthLuma = 8; - q->param.mfx.FrameInfo.BitDepthChroma = 8; + q->param.mfx.FrameInfo.BitDepthLuma = desc->comp[0].depth; + q->param.mfx.FrameInfo.BitDepthChroma = desc->comp[0].depth; + q->param.mfx.FrameInfo.Shift = desc->comp[0].depth > 8; } if (avctx->framerate.den > 0 && avctx->framerate.num > 0) { diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c index fc4e0b295929e..a968dcfdf5bc0 100644 --- a/libavcodec/qsvenc_h264.c +++ b/libavcodec/qsvenc_h264.c @@ -126,6 +126,7 @@ AVCodec ff_h264_qsv_encoder = { .close = qsv_enc_close, .capabilities = AV_CODEC_CAP_DELAY, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, + AV_PIX_FMT_P010, AV_PIX_FMT_QSV, AV_PIX_FMT_NONE }, .priv_class = &class, diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c index 706191dc6579a..ddb2a42ed6124 100644 --- a/libavcodec/qsvenc_hevc.c +++ b/libavcodec/qsvenc_hevc.c @@ -262,6 +262,7 @@ AVCodec ff_hevc_qsv_encoder = { .close = qsv_enc_close, .capabilities = AV_CODEC_CAP_DELAY, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, + AV_PIX_FMT_P010, AV_PIX_FMT_QSV, AV_PIX_FMT_NONE }, .priv_class = &class, From d9ec3c60143babe1bb77c268e1d5547d15acd69b Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 14 Jul 2016 12:05:58 +0200 Subject: [PATCH 0008/3374] qsvenc: take only the allocated dimensions from the frames context Other parameters, like the display size, should still be taken from the codec context. --- libavcodec/qsvenc.c | 50 ++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index e28f3545ec70e..cd321d39e2788 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -355,6 +355,9 @@ static int rc_supported(QSVEncContext *q) static int init_video_param(AVCodecContext *avctx, QSVEncContext *q) { + enum AVPixelFormat sw_format = avctx->pix_fmt == AV_PIX_FMT_QSV ? + avctx->sw_pix_fmt : avctx->pix_fmt; + const AVPixFmtDescriptor *desc; float quant; int ret; @@ -380,34 +383,31 @@ static int init_video_param(AVCodecContext *avctx, QSVEncContext *q) q->param.mfx.EncodedOrder = 0; q->param.mfx.BufferSizeInKB = 0; + desc = av_pix_fmt_desc_get(sw_format); + if (!desc) + return AVERROR_BUG; + + ff_qsv_map_pixfmt(sw_format, &q->param.mfx.FrameInfo.FourCC); + + q->param.mfx.FrameInfo.Width = FFALIGN(avctx->width, q->width_align); + q->param.mfx.FrameInfo.Height = FFALIGN(avctx->height, 32); + q->param.mfx.FrameInfo.CropX = 0; + q->param.mfx.FrameInfo.CropY = 0; + q->param.mfx.FrameInfo.CropW = avctx->width; + q->param.mfx.FrameInfo.CropH = avctx->height; + q->param.mfx.FrameInfo.AspectRatioW = avctx->sample_aspect_ratio.num; + q->param.mfx.FrameInfo.AspectRatioH = avctx->sample_aspect_ratio.den; + q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE; + q->param.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420; + q->param.mfx.FrameInfo.BitDepthLuma = desc->comp[0].depth; + q->param.mfx.FrameInfo.BitDepthChroma = desc->comp[0].depth; + q->param.mfx.FrameInfo.Shift = desc->comp[0].depth > 8; + if (avctx->hw_frames_ctx) { AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx; - q->param.mfx.FrameInfo = frames_hwctx->surfaces[0].Info; - } else { - enum AVPixelFormat sw_format = avctx->pix_fmt == AV_PIX_FMT_QSV ? - avctx->sw_pix_fmt : avctx->pix_fmt; - const AVPixFmtDescriptor *desc; - - desc = av_pix_fmt_desc_get(sw_format); - if (!desc) - return AVERROR_BUG; - - ff_qsv_map_pixfmt(sw_format, &q->param.mfx.FrameInfo.FourCC); - - q->param.mfx.FrameInfo.Width = FFALIGN(avctx->width, q->width_align); - q->param.mfx.FrameInfo.Height = FFALIGN(avctx->height, 32); - q->param.mfx.FrameInfo.CropX = 0; - q->param.mfx.FrameInfo.CropY = 0; - q->param.mfx.FrameInfo.CropW = avctx->width; - q->param.mfx.FrameInfo.CropH = avctx->height; - q->param.mfx.FrameInfo.AspectRatioW = avctx->sample_aspect_ratio.num; - q->param.mfx.FrameInfo.AspectRatioH = avctx->sample_aspect_ratio.den; - q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE; - q->param.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420; - q->param.mfx.FrameInfo.BitDepthLuma = desc->comp[0].depth; - q->param.mfx.FrameInfo.BitDepthChroma = desc->comp[0].depth; - q->param.mfx.FrameInfo.Shift = desc->comp[0].depth > 8; + q->param.mfx.FrameInfo.Width = frames_hwctx->surfaces[0].Info.Width; + q->param.mfx.FrameInfo.Height = frames_hwctx->surfaces[0].Info.Height; } if (avctx->framerate.den > 0 && avctx->framerate.num > 0) { From 95414eb2dc63a6f934275b4ed33dedd4369f2c49 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 25 Jun 2016 21:38:10 +0200 Subject: [PATCH 0009/3374] qsv: print more complete error messages Include the libmfx error code and its description --- libavcodec/qsv.c | 133 ++++++++++++++++++++++---------------- libavcodec/qsv_internal.h | 5 +- libavcodec/qsvdec.c | 11 ++-- libavcodec/qsvenc.c | 20 +++--- 4 files changed, 97 insertions(+), 72 deletions(-) diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index c8b397810fb9f..14f16bc66d834 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -54,39 +54,67 @@ int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id) return AVERROR(ENOSYS); } -int ff_qsv_error(int mfx_err) +static const struct { + mfxStatus mfxerr; + int averr; + const char *desc; +} qsv_errors[] = { + { MFX_ERR_NONE, 0, "success" }, + { MFX_ERR_UNKNOWN, AVERROR_UNKNOWN, "unknown error" }, + { MFX_ERR_NULL_PTR, AVERROR(EINVAL), "NULL pointer" }, + { MFX_ERR_UNSUPPORTED, AVERROR(ENOSYS), "unsupported" }, + { MFX_ERR_MEMORY_ALLOC, AVERROR(ENOMEM), "failed to allocate memory" }, + { MFX_ERR_NOT_ENOUGH_BUFFER, AVERROR(ENOMEM), "insufficient input/output buffer" }, + { MFX_ERR_INVALID_HANDLE, AVERROR(EINVAL), "invalid handle" }, + { MFX_ERR_LOCK_MEMORY, AVERROR(EIO), "failed to lock the memory block" }, + { MFX_ERR_NOT_INITIALIZED, AVERROR_BUG, "not initialized" }, + { MFX_ERR_NOT_FOUND, AVERROR(ENOSYS), "specified object was not found" }, + { MFX_ERR_MORE_DATA, AVERROR(EAGAIN), "expect more data at input" }, + { MFX_ERR_MORE_SURFACE, AVERROR(EAGAIN), "expect more surface at output" }, + { MFX_ERR_ABORTED, AVERROR_UNKNOWN, "operation aborted" }, + { MFX_ERR_DEVICE_LOST, AVERROR(EIO), "device lost" }, + { MFX_ERR_INCOMPATIBLE_VIDEO_PARAM, AVERROR(EINVAL), "incompatible video parameters" }, + { MFX_ERR_INVALID_VIDEO_PARAM, AVERROR(EINVAL), "invalid video parameters" }, + { MFX_ERR_UNDEFINED_BEHAVIOR, AVERROR_BUG, "undefined behavior" }, + { MFX_ERR_DEVICE_FAILED, AVERROR(EIO), "device failed" }, + { MFX_ERR_MORE_BITSTREAM, AVERROR(EAGAIN), "expect more bitstream at output" }, + { MFX_ERR_INCOMPATIBLE_AUDIO_PARAM, AVERROR(EINVAL), "incompatible audio parameters" }, + { MFX_ERR_INVALID_AUDIO_PARAM, AVERROR(EINVAL), "invalid audio parameters" }, + + { MFX_WRN_IN_EXECUTION, 0, "operation in execution" }, + { MFX_WRN_DEVICE_BUSY, 0, "device busy" }, + { MFX_WRN_VIDEO_PARAM_CHANGED, 0, "video parameters changed" }, + { MFX_WRN_PARTIAL_ACCELERATION, 0, "partial acceleration" }, + { MFX_WRN_INCOMPATIBLE_VIDEO_PARAM, 0, "incompatible video parameters" }, + { MFX_WRN_VALUE_NOT_CHANGED, 0, "value is saturated" }, + { MFX_WRN_OUT_OF_RANGE, 0, "value out of range" }, + { MFX_WRN_FILTER_SKIPPED, 0, "filter skipped" }, + { MFX_WRN_INCOMPATIBLE_AUDIO_PARAM, 0, "incompatible audio parameters" }, +}; + +int ff_qsv_map_error(mfxStatus mfx_err, const char **desc) { - switch (mfx_err) { - case MFX_ERR_NONE: - return 0; - case MFX_ERR_MEMORY_ALLOC: - case MFX_ERR_NOT_ENOUGH_BUFFER: - return AVERROR(ENOMEM); - case MFX_ERR_INVALID_HANDLE: - return AVERROR(EINVAL); - case MFX_ERR_DEVICE_FAILED: - case MFX_ERR_DEVICE_LOST: - case MFX_ERR_LOCK_MEMORY: - return AVERROR(EIO); - case MFX_ERR_NULL_PTR: - case MFX_ERR_UNDEFINED_BEHAVIOR: - case MFX_ERR_NOT_INITIALIZED: - return AVERROR_BUG; - case MFX_ERR_UNSUPPORTED: - case MFX_ERR_NOT_FOUND: - return AVERROR(ENOSYS); - case MFX_ERR_MORE_DATA: - case MFX_ERR_MORE_SURFACE: - case MFX_ERR_MORE_BITSTREAM: - return AVERROR(EAGAIN); - case MFX_ERR_INCOMPATIBLE_VIDEO_PARAM: - case MFX_ERR_INVALID_VIDEO_PARAM: - return AVERROR(EINVAL); - case MFX_ERR_ABORTED: - case MFX_ERR_UNKNOWN: - default: - return AVERROR_UNKNOWN; + int i; + for (i = 0; i < FF_ARRAY_ELEMS(qsv_errors); i++) { + if (qsv_errors[i].mfxerr == mfx_err) { + if (desc) + *desc = qsv_errors[i].desc; + return qsv_errors[i].averr; + } } + if (desc) + *desc = "unknown error"; + return AVERROR_UNKNOWN; +} + +int ff_qsv_print_error(void *log_ctx, mfxStatus err, + const char *error_string) +{ + const char *desc; + int ret; + ret = ff_qsv_map_error(err, &desc); + av_log(log_ctx, AV_LOG_ERROR, "%s: %s (%d)\n", error_string, desc, err); + return ret; } int ff_qsv_map_pixfmt(enum AVPixelFormat format, uint32_t *fourcc) @@ -138,9 +166,10 @@ static int qsv_load_plugins(mfxSession session, const char *load_plugins, ret = MFXVideoUSER_Load(session, &uid, 1); if (ret < 0) { - av_log(logctx, AV_LOG_ERROR, "Could not load the requested plugin: %s\n", - plugin); - err = ff_qsv_error(ret); + char errorbuf[128]; + snprintf(errorbuf, sizeof(errorbuf), + "Could not load the requested plugin '%s'", plugin); + err = ff_qsv_print_error(logctx, ret, errorbuf); goto load_plugin_fail; } @@ -166,10 +195,9 @@ int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session, int ret; ret = MFXInit(impl, &ver, session); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "Error initializing an internal MFX session\n"); - return ff_qsv_error(ret); - } + if (ret < 0) + return ff_qsv_print_error(avctx, ret, + "Error initializing an internal MFX session"); ret = qsv_load_plugins(*session, load_plugins, avctx); if (ret < 0) { @@ -282,10 +310,9 @@ int ff_qsv_init_session_hwcontext(AVCodecContext *avctx, mfxSession *psession, err = MFXQueryIMPL(parent_session, &impl); if (err == MFX_ERR_NONE) err = MFXQueryVersion(parent_session, &ver); - if (err != MFX_ERR_NONE) { - av_log(avctx, AV_LOG_ERROR, "Error querying the session attributes\n"); - return ff_qsv_error(err); - } + if (err != MFX_ERR_NONE) + return ff_qsv_print_error(avctx, err, + "Error querying the session attributes"); for (i = 0; i < FF_ARRAY_ELEMS(handle_types); i++) { err = MFXVideoCORE_GetHandle(parent_session, handle_types[i], &handle); @@ -301,18 +328,15 @@ int ff_qsv_init_session_hwcontext(AVCodecContext *avctx, mfxSession *psession, } err = MFXInit(impl, &ver, &session); - if (err != MFX_ERR_NONE) { - av_log(avctx, AV_LOG_ERROR, - "Error initializing a child MFX session: %d\n", err); - return ff_qsv_error(err); - } + if (err != MFX_ERR_NONE) + return ff_qsv_print_error(avctx, err, + "Error initializing a child MFX session"); if (handle) { err = MFXVideoCORE_SetHandle(session, handle_type, handle); - if (err != MFX_ERR_NONE) { - av_log(avctx, AV_LOG_ERROR, "Error setting a HW handle: %d\n", err); - return ff_qsv_error(err); - } + if (err != MFX_ERR_NONE) + return ff_qsv_print_error(avctx, err, + "Error setting a HW handle"); } ret = qsv_load_plugins(session, load_plugins, avctx); @@ -334,10 +358,9 @@ int ff_qsv_init_session_hwcontext(AVCodecContext *avctx, mfxSession *psession, qsv_frames_ctx->mids[i] = frames_hwctx->surfaces[i].Data.MemId; err = MFXVideoCORE_SetFrameAllocator(session, &frame_allocator); - if (err != MFX_ERR_NONE) { - av_log(avctx, AV_LOG_ERROR, "Error setting a frame allocator: %d\n", err); - return ff_qsv_error(err); - } + if (err != MFX_ERR_NONE) + return ff_qsv_print_error(avctx, err, + "Error setting a frame allocator"); } *psession = session; diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index e8657417f30a2..03b2f651db72a 100644 --- a/libavcodec/qsv_internal.h +++ b/libavcodec/qsv_internal.h @@ -57,7 +57,10 @@ typedef struct QSVFramesContext { /** * Convert a libmfx error code into a libav error code. */ -int ff_qsv_error(int mfx_err); +int ff_qsv_map_error(mfxStatus mfx_err, const char **desc); + +int ff_qsv_print_error(void *log_ctx, mfxStatus err, + const char *error_string); int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id); diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index 5b364896774f5..4802932ea7c92 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -161,10 +161,9 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q) param.NumExtParam = q->nb_ext_buffers; ret = MFXVideoDECODE_Init(q->session, ¶m); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "Error initializing the MFX video decoder\n"); - return ff_qsv_error(ret); - } + if (ret < 0) + return ff_qsv_print_error(avctx, ret, + "Error initializing the MFX video decoder"); q->frame_info = param.mfx.FrameInfo; @@ -298,9 +297,9 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q, ret != MFX_ERR_MORE_DATA && ret != MFX_WRN_VIDEO_PARAM_CHANGED && ret != MFX_ERR_MORE_SURFACE) { - av_log(avctx, AV_LOG_ERROR, "Error during QSV decoding.\n"); av_freep(&sync); - return ff_qsv_error(ret); + return ff_qsv_print_error(avctx, ret, + "Error during QSV decoding."); } /* make sure we do not enter an infinite loop if the SDK diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index cd321d39e2788..fbbe23c2b81f1 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -601,7 +601,8 @@ static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q) ret = MFXVideoENCODE_GetVideoParam(q->session, &q->param); if (ret < 0) - return ff_qsv_error(ret); + return ff_qsv_print_error(avctx, ret, + "Error calling GetVideoParam"); q->packet_size = q->param.mfx.BufferSizeInKB * 1000; @@ -750,10 +751,9 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q) return ret; ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "Error querying the encoding parameters\n"); - return ff_qsv_error(ret); - } + if (ret < 0) + return ff_qsv_print_error(avctx, ret, + "Error querying the encoding parameters"); if (opaque_alloc) { ret = qsv_init_opaque_alloc(avctx, q); @@ -791,10 +791,9 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q) } ret = MFXVideoENCODE_Init(q->session, &q->param); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "Error initializing the encoder\n"); - return ff_qsv_error(ret); - } + if (ret < 0) + return ff_qsv_print_error(avctx, ret, + "Error initializing the encoder"); ret = qsv_retrieve_enc_params(avctx, q); if (ret < 0) { @@ -979,7 +978,8 @@ static int encode_frame(AVCodecContext *avctx, QSVEncContext *q, av_packet_unref(&new_pkt); av_freep(&bs); av_freep(&sync); - return (ret == MFX_ERR_MORE_DATA) ? 0 : ff_qsv_error(ret); + return (ret == MFX_ERR_MORE_DATA) ? + 0 : ff_qsv_print_error(avctx, ret, "Error during encoding"); } if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM && frame->interlaced_frame) From 0956fd460681e8ccbdae19f135f0d3970bf95c2f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 14 Jul 2016 12:52:20 +0200 Subject: [PATCH 0010/3374] qsvenc: do not re-execute encoding on all positive status codes It should only be done for DEVICE_BUSY/IN_EXECUTION --- libavcodec/qsvenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index fbbe23c2b81f1..4697e1d1d1524 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -972,7 +972,7 @@ static int encode_frame(AVCodecContext *avctx, QSVEncContext *q, ret = MFXVideoENCODE_EncodeFrameAsync(q->session, NULL, surf, bs, sync); if (ret == MFX_WRN_DEVICE_BUSY) av_usleep(1); - } while (ret > 0); + } while (ret == MFX_WRN_DEVICE_BUSY || ret == MFX_WRN_IN_EXECUTION); if (ret < 0) { av_packet_unref(&new_pkt); From 8e07c22e508b349d145b9f142aa3ee8b3ce1d3a4 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 14 Jul 2016 12:56:35 +0200 Subject: [PATCH 0011/3374] qsvenc: print warnings from encode/init --- libavcodec/qsv.c | 10 ++++++++++ libavcodec/qsv_internal.h | 3 +++ libavcodec/qsvenc.c | 6 ++++++ 3 files changed, 19 insertions(+) diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index 14f16bc66d834..91195865bcb2c 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -117,6 +117,16 @@ int ff_qsv_print_error(void *log_ctx, mfxStatus err, return ret; } +int ff_qsv_print_warning(void *log_ctx, mfxStatus err, + const char *warning_string) +{ + const char *desc; + int ret; + ret = ff_qsv_map_error(err, &desc); + av_log(log_ctx, AV_LOG_WARNING, "%s: %s (%d)\n", warning_string, desc, err); + return ret; +} + int ff_qsv_map_pixfmt(enum AVPixelFormat format, uint32_t *fourcc) { switch (format) { diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index 03b2f651db72a..41f4c3ddf6048 100644 --- a/libavcodec/qsv_internal.h +++ b/libavcodec/qsv_internal.h @@ -62,6 +62,9 @@ int ff_qsv_map_error(mfxStatus mfx_err, const char **desc); int ff_qsv_print_error(void *log_ctx, mfxStatus err, const char *error_string); +int ff_qsv_print_warning(void *log_ctx, mfxStatus err, + const char *warning_string); + int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id); int ff_qsv_map_pixfmt(enum AVPixelFormat format, uint32_t *fourcc); diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index 4697e1d1d1524..ba07db6e99122 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -794,6 +794,9 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q) if (ret < 0) return ff_qsv_print_error(avctx, ret, "Error initializing the encoder"); + else if (ret > 0) + ff_qsv_print_warning(avctx, ret, + "Warning in encoder initialization"); ret = qsv_retrieve_enc_params(avctx, q); if (ret < 0) { @@ -974,6 +977,9 @@ static int encode_frame(AVCodecContext *avctx, QSVEncContext *q, av_usleep(1); } while (ret == MFX_WRN_DEVICE_BUSY || ret == MFX_WRN_IN_EXECUTION); + if (ret > 0) + ff_qsv_print_warning(avctx, ret, "Warning during encoding"); + if (ret < 0) { av_packet_unref(&new_pkt); av_freep(&bs); From ad71d3276fef0ee7e791e62bbfe9c4e540047417 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 2 Jul 2016 12:12:36 +0200 Subject: [PATCH 0012/3374] lavfi: add a QSV deinterlacing filter --- Changelog | 2 +- configure | 1 + libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/version.h | 2 +- libavfilter/vf_deinterlace_qsv.c | 580 +++++++++++++++++++++++++++++++ 6 files changed, 585 insertions(+), 2 deletions(-) create mode 100644 libavfilter/vf_deinterlace_qsv.c diff --git a/Changelog b/Changelog index b21f447984b73..d3201b3aaf05c 100644 --- a/Changelog +++ b/Changelog @@ -59,7 +59,7 @@ version : - G.729 raw demuxer - MagicYUV decoder - Duck TrueMotion 2.0 Real Time decoder -- Intel QSV video scaling filter +- Intel QSV video scaling and deinterlacing filter - OpenH264 decoder wrapper diff --git a/configure b/configure index 58855193c68ec..f12fa6fa2999e 100755 --- a/configure +++ b/configure @@ -2402,6 +2402,7 @@ blackframe_filter_deps="gpl" boxblur_filter_deps="gpl" bs2b_filter_deps="libbs2b" cropdetect_filter_deps="gpl" +deinterlace_qsv_filter_deps="libmfx" delogo_filter_deps="gpl" drawtext_filter_deps="libfreetype" frei0r_filter_deps="frei0r dlopen" diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 21515fed809c1..dea8ffa50faf7 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -47,6 +47,7 @@ OBJS-$(CONFIG_BOXBLUR_FILTER) += vf_boxblur.o OBJS-$(CONFIG_COPY_FILTER) += vf_copy.o OBJS-$(CONFIG_CROP_FILTER) += vf_crop.o OBJS-$(CONFIG_CROPDETECT_FILTER) += vf_cropdetect.o +OBJS-$(CONFIG_DEINTERLACE_QSV_FILTER) += vf_deinterlace_qsv.o OBJS-$(CONFIG_DELOGO_FILTER) += vf_delogo.o OBJS-$(CONFIG_DRAWBOX_FILTER) += vf_drawbox.o OBJS-$(CONFIG_DRAWTEXT_FILTER) += vf_drawtext.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index e3858d8d837ae..de49d65298090 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -70,6 +70,7 @@ void avfilter_register_all(void) REGISTER_FILTER(COPY, copy, vf); REGISTER_FILTER(CROP, crop, vf); REGISTER_FILTER(CROPDETECT, cropdetect, vf); + REGISTER_FILTER(DEINTERLACE_QSV,deinterlace_qsv,vf); REGISTER_FILTER(DELOGO, delogo, vf); REGISTER_FILTER(DRAWBOX, drawbox, vf); REGISTER_FILTER(DRAWTEXT, drawtext, vf); diff --git a/libavfilter/version.h b/libavfilter/version.h index e91c6e20300bb..7f3ede2d042b1 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 6 -#define LIBAVFILTER_VERSION_MINOR 5 +#define LIBAVFILTER_VERSION_MINOR 6 #define LIBAVFILTER_VERSION_MICRO 0 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vf_deinterlace_qsv.c b/libavfilter/vf_deinterlace_qsv.c new file mode 100644 index 0000000000000..b26a900c4f109 --- /dev/null +++ b/libavfilter/vf_deinterlace_qsv.c @@ -0,0 +1,580 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * deinterlace video filter - QSV + */ + +#include + +#include +#include + +#include "libavutil/avstring.h" +#include "libavutil/common.h" +#include "libavutil/hwcontext.h" +#include "libavutil/hwcontext_qsv.h" +#include "libavutil/internal.h" +#include "libavutil/mathematics.h" +#include "libavutil/opt.h" +#include "libavutil/pixdesc.h" +#include "libavutil/time.h" + +#include "avfilter.h" +#include "formats.h" +#include "internal.h" +#include "video.h" + +enum { + QSVDEINT_MORE_OUTPUT = 1, + QSVDEINT_MORE_INPUT, +}; + +typedef struct QSVFrame { + AVFrame *frame; + mfxFrameSurface1 surface; + int used; + + struct QSVFrame *next; +} QSVFrame; + +typedef struct QSVDeintContext { + const AVClass *class; + + AVBufferRef *hw_frames_ctx; + /* a clone of the main session, used internally for deinterlacing */ + mfxSession session; + + mfxMemId *mem_ids; + int nb_mem_ids; + + mfxFrameSurface1 **surface_ptrs; + int nb_surface_ptrs; + + mfxExtOpaqueSurfaceAlloc opaque_alloc; + mfxExtBuffer *ext_buffers[1]; + + QSVFrame *work_frames; + + int64_t last_pts; + + int got_output_frame; + int eof; +} QSVDeintContext; + +static void qsvdeint_uninit(AVFilterContext *ctx) +{ + QSVDeintContext *s = ctx->priv; + QSVFrame *cur; + + if (s->session) { + MFXClose(s->session); + s->session = NULL; + } + av_buffer_unref(&s->hw_frames_ctx); + + cur = s->work_frames; + while (cur) { + s->work_frames = cur->next; + av_frame_free(&cur->frame); + av_freep(&cur); + cur = s->work_frames; + } + + av_freep(&s->mem_ids); + s->nb_mem_ids = 0; + + av_freep(&s->surface_ptrs); + s->nb_surface_ptrs = 0; +} + +static int qsvdeint_query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pixel_formats[] = { + AV_PIX_FMT_QSV, AV_PIX_FMT_NONE, + }; + AVFilterFormats *pix_fmts = ff_make_format_list(pixel_formats); + + ff_set_common_formats(ctx, pix_fmts); + + return 0; +} + +static mfxStatus frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req, + mfxFrameAllocResponse *resp) +{ + AVFilterContext *ctx = pthis; + QSVDeintContext *s = ctx->priv; + + if (!(req->Type & MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET) || + !(req->Type & (MFX_MEMTYPE_FROM_VPPIN | MFX_MEMTYPE_FROM_VPPOUT)) || + !(req->Type & MFX_MEMTYPE_EXTERNAL_FRAME)) + return MFX_ERR_UNSUPPORTED; + + resp->mids = s->mem_ids; + resp->NumFrameActual = s->nb_mem_ids; + + return MFX_ERR_NONE; +} + +static mfxStatus frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp) +{ + return MFX_ERR_NONE; +} + +static mfxStatus frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) +{ + return MFX_ERR_UNSUPPORTED; +} + +static mfxStatus frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) +{ + return MFX_ERR_UNSUPPORTED; +} + +static mfxStatus frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl) +{ + *hdl = mid; + return MFX_ERR_NONE; +} + +static const mfxHandleType handle_types[] = { + MFX_HANDLE_VA_DISPLAY, + MFX_HANDLE_D3D9_DEVICE_MANAGER, + MFX_HANDLE_D3D11_DEVICE, +}; + +static int init_out_session(AVFilterContext *ctx) +{ + + QSVDeintContext *s = ctx->priv; + AVHWFramesContext *hw_frames_ctx = (AVHWFramesContext*)s->hw_frames_ctx->data; + AVQSVFramesContext *hw_frames_hwctx = hw_frames_ctx->hwctx; + AVQSVDeviceContext *device_hwctx = hw_frames_ctx->device_ctx->hwctx; + + int opaque = !!(hw_frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME); + + mfxHDL handle = NULL; + mfxHandleType handle_type; + mfxVersion ver; + mfxIMPL impl; + mfxVideoParam par; + mfxStatus err; + int i; + + /* extract the properties of the "master" session given to us */ + err = MFXQueryIMPL(device_hwctx->session, &impl); + if (err == MFX_ERR_NONE) + err = MFXQueryVersion(device_hwctx->session, &ver); + if (err != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error querying the session attributes\n"); + return AVERROR_UNKNOWN; + } + + for (i = 0; i < FF_ARRAY_ELEMS(handle_types); i++) { + err = MFXVideoCORE_GetHandle(device_hwctx->session, handle_types[i], &handle); + if (err == MFX_ERR_NONE) { + handle_type = handle_types[i]; + break; + } + } + + /* create a "slave" session with those same properties, to be used for + * actual deinterlacing */ + err = MFXInit(impl, &ver, &s->session); + if (err != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error initializing a session for deinterlacing\n"); + return AVERROR_UNKNOWN; + } + + if (handle) { + err = MFXVideoCORE_SetHandle(s->session, handle_type, handle); + if (err != MFX_ERR_NONE) + return AVERROR_UNKNOWN; + } + + memset(&par, 0, sizeof(par)); + + if (opaque) { + s->surface_ptrs = av_mallocz_array(hw_frames_hwctx->nb_surfaces, + sizeof(*s->surface_ptrs)); + if (!s->surface_ptrs) + return AVERROR(ENOMEM); + for (i = 0; i < hw_frames_hwctx->nb_surfaces; i++) + s->surface_ptrs[i] = hw_frames_hwctx->surfaces + i; + s->nb_surface_ptrs = hw_frames_hwctx->nb_surfaces; + + s->opaque_alloc.In.Surfaces = s->surface_ptrs; + s->opaque_alloc.In.NumSurface = s->nb_surface_ptrs; + s->opaque_alloc.In.Type = hw_frames_hwctx->frame_type; + + s->opaque_alloc.Out = s->opaque_alloc.In; + + s->opaque_alloc.Header.BufferId = MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION; + s->opaque_alloc.Header.BufferSz = sizeof(s->opaque_alloc); + + s->ext_buffers[0] = (mfxExtBuffer*)&s->opaque_alloc; + + par.ExtParam = s->ext_buffers; + par.NumExtParam = FF_ARRAY_ELEMS(s->ext_buffers); + + par.IOPattern = MFX_IOPATTERN_IN_OPAQUE_MEMORY | MFX_IOPATTERN_OUT_OPAQUE_MEMORY; + } else { + mfxFrameAllocator frame_allocator = { + .pthis = ctx, + .Alloc = frame_alloc, + .Lock = frame_lock, + .Unlock = frame_unlock, + .GetHDL = frame_get_hdl, + .Free = frame_free, + }; + + s->mem_ids = av_mallocz_array(hw_frames_hwctx->nb_surfaces, + sizeof(*s->mem_ids)); + if (!s->mem_ids) + return AVERROR(ENOMEM); + for (i = 0; i < hw_frames_hwctx->nb_surfaces; i++) + s->mem_ids[i] = hw_frames_hwctx->surfaces[i].Data.MemId; + s->nb_mem_ids = hw_frames_hwctx->nb_surfaces; + + err = MFXVideoCORE_SetFrameAllocator(s->session, &frame_allocator); + if (err != MFX_ERR_NONE) + return AVERROR_UNKNOWN; + + par.IOPattern = MFX_IOPATTERN_IN_VIDEO_MEMORY | MFX_IOPATTERN_OUT_VIDEO_MEMORY; + } + + par.AsyncDepth = 1; // TODO async + + par.vpp.In = hw_frames_hwctx->surfaces[0].Info; + + par.vpp.In.CropW = ctx->inputs[0]->w; + par.vpp.In.CropH = ctx->inputs[0]->h; + + if (ctx->inputs[0]->frame_rate.num) { + par.vpp.In.FrameRateExtN = ctx->inputs[0]->frame_rate.num; + par.vpp.In.FrameRateExtD = ctx->inputs[0]->frame_rate.den; + } else { + par.vpp.In.FrameRateExtN = ctx->inputs[0]->time_base.num; + par.vpp.In.FrameRateExtD = ctx->inputs[0]->time_base.den; + } + + par.vpp.Out = par.vpp.In; + + if (ctx->outputs[0]->frame_rate.num) { + par.vpp.Out.FrameRateExtN = ctx->outputs[0]->frame_rate.num; + par.vpp.Out.FrameRateExtD = ctx->outputs[0]->frame_rate.den; + } else { + par.vpp.Out.FrameRateExtN = ctx->outputs[0]->time_base.num; + par.vpp.Out.FrameRateExtD = ctx->outputs[0]->time_base.den; + } + + err = MFXVideoVPP_Init(s->session, &par); + if (err != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error opening the VPP for deinterlacing: %d\n", err); + return AVERROR_UNKNOWN; + } + + return 0; +} + +static int qsvdeint_config_props(AVFilterLink *outlink) +{ + AVFilterContext *ctx = outlink->src; + AVFilterLink *inlink = ctx->inputs[0]; + QSVDeintContext *s = ctx->priv; + int ret; + + qsvdeint_uninit(ctx); + + s->last_pts = AV_NOPTS_VALUE; + outlink->frame_rate = av_mul_q(inlink->frame_rate, + (AVRational){ 2, 1 }); + outlink->time_base = av_mul_q(inlink->time_base, + (AVRational){ 1, 2 }); + + /* check that we have a hw context */ + if (!inlink->hw_frames_ctx) { + av_log(ctx, AV_LOG_ERROR, "No hw context provided on input\n"); + return AVERROR(EINVAL); + } + + s->hw_frames_ctx = av_buffer_ref(inlink->hw_frames_ctx); + if (!s->hw_frames_ctx) + return AVERROR(ENOMEM); + + av_buffer_unref(&outlink->hw_frames_ctx); + outlink->hw_frames_ctx = av_buffer_ref(inlink->hw_frames_ctx); + if (!outlink->hw_frames_ctx) { + qsvdeint_uninit(ctx); + return AVERROR(ENOMEM); + } + + ret = init_out_session(ctx); + if (ret < 0) + return ret; + + + return 0; +} + +static void clear_unused_frames(QSVDeintContext *s) +{ + QSVFrame *cur = s->work_frames; + while (cur) { + if (!cur->surface.Data.Locked) { + av_frame_free(&cur->frame); + cur->used = 0; + } + cur = cur->next; + } +} + +static int get_free_frame(QSVDeintContext *s, QSVFrame **f) +{ + QSVFrame *frame, **last; + + clear_unused_frames(s); + + frame = s->work_frames; + last = &s->work_frames; + while (frame) { + if (!frame->used) { + *f = frame; + return 0; + } + + last = &frame->next; + frame = frame->next; + } + + frame = av_mallocz(sizeof(*frame)); + if (!frame) + return AVERROR(ENOMEM); + *last = frame; + *f = frame; + + return 0; +} + +static int submit_frame(AVFilterContext *ctx, AVFrame *frame, + mfxFrameSurface1 **surface) +{ + QSVDeintContext *s = ctx->priv; + QSVFrame *qf; + int ret; + + ret = get_free_frame(s, &qf); + if (ret < 0) + return ret; + + qf->frame = frame; + + qf->surface = *(mfxFrameSurface1*)qf->frame->data[3]; + + qf->surface.Data.Locked = 0; + qf->surface.Info.CropW = qf->frame->width; + qf->surface.Info.CropH = qf->frame->height; + + qf->surface.Info.PicStruct = !qf->frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE : + (qf->frame->top_field_first ? MFX_PICSTRUCT_FIELD_TFF : + MFX_PICSTRUCT_FIELD_BFF); + if (qf->frame->repeat_pict == 1) + qf->surface.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED; + else if (qf->frame->repeat_pict == 2) + qf->surface.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING; + else if (qf->frame->repeat_pict == 4) + qf->surface.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING; + + if (ctx->inputs[0]->frame_rate.num) { + qf->surface.Info.FrameRateExtN = ctx->inputs[0]->frame_rate.num; + qf->surface.Info.FrameRateExtD = ctx->inputs[0]->frame_rate.den; + } else { + qf->surface.Info.FrameRateExtN = ctx->inputs[0]->time_base.num; + qf->surface.Info.FrameRateExtD = ctx->inputs[0]->time_base.den; + } + + qf->surface.Data.TimeStamp = av_rescale_q(qf->frame->pts, + ctx->inputs[0]->time_base, + (AVRational){1, 90000}); + + *surface = &qf->surface; + qf->used = 1; + + return 0; +} + +static int process_frame(AVFilterContext *ctx, const AVFrame *in, + mfxFrameSurface1 *surf_in) +{ + QSVDeintContext *s = ctx->priv; + AVFilterLink *inlink = ctx->inputs[0]; + AVFilterLink *outlink = ctx->outputs[0]; + + AVFrame *out; + mfxFrameSurface1 *surf_out; + mfxSyncPoint sync = NULL; + mfxStatus err; + int ret, again = 0; + + out = av_frame_alloc(); + if (!out) + return AVERROR(ENOMEM); + + ret = av_hwframe_get_buffer(s->hw_frames_ctx, out, 0); + if (ret < 0) + goto fail; + + surf_out = (mfxFrameSurface1*)out->data[3]; + surf_out->Info.CropW = outlink->w; + surf_out->Info.CropH = outlink->h; + surf_out->Info.PicStruct = MFX_PICSTRUCT_PROGRESSIVE; + + do { + err = MFXVideoVPP_RunFrameVPPAsync(s->session, surf_in, surf_out, + NULL, &sync); + if (err == MFX_WRN_DEVICE_BUSY) + av_usleep(1); + } while (err == MFX_WRN_DEVICE_BUSY); + + if (err == MFX_ERR_MORE_DATA) { + av_frame_free(&out); + return QSVDEINT_MORE_INPUT; + } + + if ((err < 0 && err != MFX_ERR_MORE_SURFACE) || !sync) { + av_log(ctx, AV_LOG_ERROR, "Error during deinterlacing: %d\n", err); + ret = AVERROR_UNKNOWN; + goto fail; + } + if (err == MFX_ERR_MORE_SURFACE) + again = 1; + + do { + err = MFXVideoCORE_SyncOperation(s->session, sync, 1000); + } while (err == MFX_WRN_IN_EXECUTION); + if (err < 0) { + av_log(ctx, AV_LOG_ERROR, "Error synchronizing the operation: %d\n", err); + ret = AVERROR_UNKNOWN; + goto fail; + } + + ret = av_frame_copy_props(out, in); + if (ret < 0) + goto fail; + + out->width = outlink->w; + out->height = outlink->h; + out->interlaced_frame = 0; + + out->pts = av_rescale_q(out->pts, inlink->time_base, outlink->time_base); + if (out->pts == s->last_pts) + out->pts++; + s->last_pts = out->pts; + + ret = ff_filter_frame(outlink, out); + if (ret < 0) + return ret; + + return again ? QSVDEINT_MORE_OUTPUT : 0; +fail: + av_frame_free(&out); + return ret; +} + +static int qsvdeint_filter_frame(AVFilterLink *link, AVFrame *in) +{ + AVFilterContext *ctx = link->dst; + + mfxFrameSurface1 *surf_in; + int ret; + + ret = submit_frame(ctx, in, &surf_in); + if (ret < 0) { + av_frame_free(&in); + return ret; + } + + do { + ret = process_frame(ctx, in, surf_in); + if (ret < 0) + return ret; + } while (ret == QSVDEINT_MORE_OUTPUT); + + return 0; +} + +static int qsvdeint_request_frame(AVFilterLink *outlink) +{ + AVFilterContext *ctx = outlink->src; + QSVDeintContext *s = ctx->priv; + int ret = 0; + + s->got_output_frame = 0; + while (ret >= 0 && !s->got_output_frame) + ret = ff_request_frame(ctx->inputs[0]); + + return ret; +} + +#define OFFSET(x) offsetof(QSVDeintContext, x) +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM +static const AVOption options[] = { + { NULL }, +}; + +static const AVClass qsvdeint_class = { + .class_name = "deinterlace_qsv", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +static const AVFilterPad qsvdeint_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .filter_frame = qsvdeint_filter_frame, + }, + { NULL } +}; + +static const AVFilterPad qsvdeint_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = qsvdeint_config_props, + .request_frame = qsvdeint_request_frame, + }, + { NULL } +}; + +AVFilter ff_vf_deinterlace_qsv = { + .name = "deinterlace_qsv", + .description = NULL_IF_CONFIG_SMALL("QuickSync video deinterlacing"), + + .uninit = qsvdeint_uninit, + .query_formats = qsvdeint_query_formats, + + .priv_size = sizeof(QSVDeintContext), + .priv_class = &qsvdeint_class, + + .inputs = qsvdeint_inputs, + .outputs = qsvdeint_outputs, +}; From b183abfb5b6366b177cf44f244c66156257a6fd6 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Fri, 22 Jul 2016 09:33:04 +0200 Subject: [PATCH 0013/3374] vpx: Support color range The range field has been introduced in version 1.6.0 --- libavcodec/libvpxdec.c | 10 ++++++++++ libavcodec/libvpxenc.c | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/libavcodec/libvpxdec.c b/libavcodec/libvpxdec.c index 28b7733969e1d..93a720f56690a 100644 --- a/libavcodec/libvpxdec.c +++ b/libavcodec/libvpxdec.c @@ -99,6 +99,16 @@ static int vp8_decode(AVCodecContext *avctx, return ret; av_image_copy(picture->data, picture->linesize, img->planes, img->stride, avctx->pix_fmt, img->d_w, img->d_h); +#if VPX_IMAGE_ABI_VERSION >= 4 + switch (img->range) { + case VPX_CR_STUDIO_RANGE: + picture->color_range = AVCOL_RANGE_MPEG; + break; + case VPX_CR_FULL_RANGE: + picture->color_range = AVCOL_RANGE_JPEG; + break; + } +#endif *got_frame = 1; } return avpkt->size; diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c index 26afaf5f1c2db..bb4c98fea5655 100644 --- a/libavcodec/libvpxenc.c +++ b/libavcodec/libvpxenc.c @@ -552,6 +552,16 @@ static int vp8_encode(AVCodecContext *avctx, AVPacket *pkt, rawimg->stride[VPX_PLANE_U] = frame->linesize[1]; rawimg->stride[VPX_PLANE_V] = frame->linesize[2]; timestamp = frame->pts; +#if VPX_IMAGE_ABI_VERSION >= 4 + switch (frame->color_range) { + case AVCOL_RANGE_MPEG: + rawimg->range = VPX_CR_STUDIO_RANGE; + break; + case AVCOL_RANGE_JPEG: + rawimg->range = VPX_CR_FULL_RANGE; + break; + } +#endif if (frame->pict_type == AV_PICTURE_TYPE_I) flags |= VPX_EFLAG_FORCE_KF; } From 40ad05bab206c932a32171d45581080c914b06ec Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Tue, 19 Jul 2016 05:26:33 +0200 Subject: [PATCH 0014/3374] checkasm: Cast unsigned to signed Avoid a warning for passing an unsigned value to abs(), some compilers might optimize away abs(). --- tests/checkasm/checkasm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c index b0621973a6e8d..34f49c0b3711c 100644 --- a/tests/checkasm/checkasm.c +++ b/tests/checkasm/checkasm.c @@ -190,7 +190,7 @@ int float_near_ulp(float a, float b, unsigned max_ulp) return a == b; } - if (abs(x.i - y.i) <= max_ulp) + if (llabs((int64_t)x.i - y.i) <= max_ulp) return 1; return 0; From 48b80f8393d418ad35d73f5a36f5011de1928f3c Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 19 Jan 2016 17:57:03 +0100 Subject: [PATCH 0015/3374] hpeldsp: Explain why put_no_rnd_pixels_tab is larger than necessary --- libavcodec/hpeldsp.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/hpeldsp.h b/libavcodec/hpeldsp.h index d037cba14e75f..62dee6813de5c 100644 --- a/libavcodec/hpeldsp.h +++ b/libavcodec/hpeldsp.h @@ -76,6 +76,8 @@ typedef struct HpelDSPContext { * @param pixels source * @param line_size number of bytes in a horizontal line of block * @param h height + * @note The size is kept at [4][4] to match the above pixel_tabs and avoid + * out of bounds reads in the motion estimation code. */ op_pixels_func put_no_rnd_pixels_tab[4][4]; From 56af0bc10f49654b5b5f3efe82c69a13bf15fc8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 20 Jul 2016 23:39:20 +0300 Subject: [PATCH 0016/3374] configure: Check for strtoll and redirect to _strtoi64 in the msvcrt block MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows doing this redirection, if building with clang against old enough MSVC headers that lack strtoll (2012 and older). Signed-off-by: Martin Storsjö --- configure | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/configure b/configure index f12fa6fa2999e..6f5daefc362cf 100755 --- a/configure +++ b/configure @@ -4008,6 +4008,9 @@ probe_libc(){ #endif #endif EOF + if [ "$pfx" = "" ]; then + check_func strtoll || add_cflags -Dstrtoll=_strtoi64 + fi elif check_${pfx}cpp_condition stddef.h "defined __KLIBC__"; then eval ${pfx}libc_type=klibc elif check_${pfx}cpp_condition sys/cdefs.h "defined __BIONIC__"; then @@ -4979,7 +4982,6 @@ elif enabled_any msvc icl; then __declspec($_restrict) void* foo(int); EOF fi - check_func strtoll || add_cflags -Dstrtoll=_strtoi64 fi for pfx in "" host_; do From 79fb0692992c74214c6cf8e81350fc93eeffc5ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 21 Jul 2016 00:04:35 +0300 Subject: [PATCH 0017/3374] configure: Move defines for controlling MSVCRT headers to the CRT detection section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows these flags to be automatically enabled for clang, when using MSVCRT headers. Signed-off-by: Martin Storsjö --- configure | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 6f5daefc362cf..a41c1e8f8e8cb 100755 --- a/configure +++ b/configure @@ -3239,7 +3239,6 @@ probe_cc(){ _ld_lib='lib%.a' _ld_path='-libpath:' _flags='-nologo' - _cflags='-D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS' elif $_cc 2>&1 | grep -q Intel; then _type=icl _ident=$($_cc 2>&1 | head -n1) @@ -3262,7 +3261,7 @@ probe_cc(){ _flags='-nologo -Qdiag-error:4044,10157' # -Qvec- -Qsimd- to prevent miscompilation, -GS for consistency # with MSVC which enables it by default. - _cflags='-D_USE_MATH_DEFINES -Qms0 -Qvec- -Qsimd- -GS' + _cflags='-Qms0 -Qvec- -Qsimd- -GS' elif $_cc --version 2>/dev/null | grep -q ^cparser; then _type=cparser _ident=$($_cc --version | head -n1) @@ -3989,6 +3988,7 @@ probe_libc(){ vsnprintf=avpriv_vsnprintf fi fi + add_${pfx}cppflags -D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS # The MSVC 2010 headers (Win 7.0 SDK) set _WIN32_WINNT to # 0x601 by default unless something else is set by the user. # This can easily lead to us detecting functions only present From 100fb0ddfda958da70f98feac81f924c02483789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 22 Jul 2016 10:19:52 +0300 Subject: [PATCH 0018/3374] configure: Allow detecting and using LLVM lld-link as linker for windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- configure | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/configure b/configure index a41c1e8f8e8cb..c56ead757f79f 100755 --- a/configure +++ b/configure @@ -3262,6 +3262,18 @@ probe_cc(){ # -Qvec- -Qsimd- to prevent miscompilation, -GS for consistency # with MSVC which enables it by default. _cflags='-Qms0 -Qvec- -Qsimd- -GS' + elif $_cc -? 2>/dev/null | grep -q 'LLVM.*Linker'; then + # lld can emulate multiple different linkers; in ms link.exe mode, + # the -? parameter gives the help output which contains an identifyable + # string, while it gives an error in other modes. + _type=lld-link + # The link.exe mode doesn't have a switch for getting the version, + # but we can force it back to gnu mode and get the version from there. + _ident=$($_cc -flavor gnu --version) + _ld_o='-out:$@' + _flags_filter=msvc_flags + _ld_lib='lib%.a' + _ld_path='-libpath:' elif $_cc --version 2>/dev/null | grep -q ^cparser; then _type=cparser _ident=$($_cc --version | head -n1) From e46a6fb7732a7caef97a916a4f765ec0f779d195 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 25 Jul 2016 15:04:02 +0200 Subject: [PATCH 0019/3374] avconv: Check that muxing_queue exists before reading from it This avoids a segfault on nonexisting codec names. --- avconv.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/avconv.c b/avconv.c index 57c02ac4fc8f7..43d67e8d17f47 100644 --- a/avconv.c +++ b/avconv.c @@ -203,13 +203,15 @@ static void avconv_cleanup(int ret) avcodec_free_context(&ost->enc_ctx); - while (av_fifo_size(ost->muxing_queue)) { - AVPacket pkt; - av_fifo_generic_read(ost->muxing_queue, &pkt, sizeof(pkt), NULL); - av_packet_unref(&pkt); + if (ost->muxing_queue) { + while (av_fifo_size(ost->muxing_queue)) { + AVPacket pkt; + av_log(NULL, AV_LOG_INFO, "after av_fifo_size()\n"); + av_fifo_generic_read(ost->muxing_queue, &pkt, sizeof(pkt), NULL); + av_packet_unref(&pkt); + } + av_fifo_free(ost->muxing_queue); } - av_fifo_free(ost->muxing_queue); - av_freep(&output_streams[i]); } for (i = 0; i < nb_input_files; i++) { From ae90119c6701fa09ff747cca35238e36b2d2ab2f Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 25 Jul 2016 15:07:58 +0200 Subject: [PATCH 0020/3374] configure: Simplify license incompatibility check --- configure | 71 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/configure b/configure index c56ead757f79f..e366dadc1b6cc 100755 --- a/configure +++ b/configure @@ -1219,12 +1219,15 @@ EXAMPLE_LIST=" transcode_aac_example " -HWACCEL_LIBRARY_LIST=" +HWACCEL_LIBRARY_NONFREE_LIST=" cuda + libnpp +" +HWACCEL_LIBRARY_LIST=" + $HWACCEL_LIBRARY_NONFREE_LIST d3d11va dxva2 libmfx - libnpp mmal nvenc omx @@ -1233,25 +1236,45 @@ HWACCEL_LIBRARY_LIST=" vdpau " +EXTERNAL_LIBRARY_GPL_LIST=" + libcdio + libx264 + libx265 + libxavs + libxvid + x11grab +" + +EXTERNAL_LIBRARY_NONFREE_LIST=" + libfaac + libfdk_aac + openssl +" + +EXTERNAL_LIBRARY_VERSION3_LIST=" + libopencore_amrnb + libopencore_amrwb + libvo_aacenc + libvo_amrwbenc +" + EXTERNAL_LIBRARY_LIST=" + $EXTERNAL_LIBRARY_GPL_LIST + $EXTERNAL_LIBRARY_NONFREE_LIST + $EXTERNAL_LIBRARY_VERSION3_LIST avisynth bzlib frei0r gnutls libbs2b - libcdio libdc1394 libdcadec - libfaac - libfdk_aac libfontconfig libfreetype libgsm libilbc libkvazaar libmp3lame - libopencore_amrnb - libopencore_amrwb libopencv libopenh264 libopenjpeg @@ -1263,21 +1286,13 @@ EXTERNAL_LIBRARY_LIST=" libspeex libtheora libtwolame - libvo_aacenc - libvo_amrwbenc libvorbis libvpx libwavpack libwebp - libx264 - libx265 - libxavs libxcb libxcb_shm libxcb_xfixes - libxvid - openssl - x11grab zlib " @@ -4087,26 +4102,12 @@ EOF fi die_license_disabled() { - enabled $1 || { enabled $2 && die "$2 is $1 and --enable-$1 is not specified."; } -} - -die_license_disabled gpl libcdio -die_license_disabled gpl libx264 -die_license_disabled gpl libx265 -die_license_disabled gpl libxavs -die_license_disabled gpl libxvid -die_license_disabled gpl x11grab - -die_license_disabled nonfree cuda -die_license_disabled nonfree libfaac -die_license_disabled nonfree libfdk_aac -die_license_disabled nonfree libnpp -die_license_disabled nonfree openssl - -die_license_disabled version3 libopencore_amrnb -die_license_disabled version3 libopencore_amrwb -die_license_disabled version3 libvo_aacenc -die_license_disabled version3 libvo_amrwbenc + enabled $1 || { enabled $v && die "$v is $1 and --enable-$1 is not specified."; } +} + +map "die_license_disabled gpl" $EXTERNAL_LIBRARY_GPL_LIST +map "die_license_disabled nonfree" $EXTERNAL_LIBRARY_NONFREE_LIST $HWACCEL_LIBRARY_NONFREE_LIST +map "die_license_disabled version3" $EXTERNAL_LIBRARY_VERSION3_LIST enabled version3 && { enabled gpl && enable gplv3 || enable lgplv3; } From a115eb9e750543f1d8bf951414d291069bf396c2 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 25 Jul 2016 13:52:59 +0200 Subject: [PATCH 0021/3374] mimic: do not release the newly obsolete reference at the end of decoding The reference frames are used in update_thread_context(), so modifying them after finish_setup() is a race. The frame in question will be released during the next decode call. CC: libav-stable@libav.org --- libavcodec/mimic.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c index 6f43723ef678a..d7723a8ef79ce 100644 --- a/libavcodec/mimic.c +++ b/libavcodec/mimic.c @@ -445,9 +445,6 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data, ctx->prev_index = ctx->next_prev_index; ctx->cur_index = ctx->next_cur_index; - /* Only release frames that aren't used for backreferences anymore */ - ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]); - return buf_size; } From 2ac00d2d1d51047c6ce69d5fbe1a08392d142658 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Tue, 26 Jul 2016 11:42:11 +0200 Subject: [PATCH 0022/3374] mov: Validate the ID number IDs in MOV start from 1. Signed-off-by: Diego Biurrun --- libavformat/mov.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index ff39b58ef1c9a..03427d7e06ea5 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1949,8 +1949,8 @@ static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom) sc->stsc_data[i].first = avio_rb32(pb); sc->stsc_data[i].count = avio_rb32(pb); sc->stsc_data[i].id = avio_rb32(pb); - if (sc->stsc_data[i].id < 0 || sc->stsc_data[i].id > sc->stsd_count) { - sc->stsc_data[i].id = 0; + if (sc->stsc_data[i].id <= 0 || sc->stsc_data[i].id > sc->stsd_count) { + sc->stsc_data[i].id = 1; if (c->fc->error_recognition & AV_EF_EXPLODE) { av_log(c->fc, AV_LOG_ERROR, "Invalid stsc index.\n"); return AVERROR_INVALIDDATA; From a5ebe5d1217942238c641c83b24ef1106e53934a Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 18 Jul 2016 19:50:32 +0200 Subject: [PATCH 0023/3374] ac3dec: Split spx-specific code from decode_audio_block() Signed-off-by: Diego Biurrun --- libavcodec/ac3dec.c | 198 ++++++++++++++++++++++++-------------------- 1 file changed, 108 insertions(+), 90 deletions(-) diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 9b08638af0e38..4de74759814bf 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -746,6 +746,109 @@ static void decode_band_structure(GetBitContext *gbc, int blk, int eac3, memcpy(band_sizes, bnd_sz, n_bands); } +static inline int spx_strategy(AC3DecodeContext *s, int blk) +{ + GetBitContext *bc = &s->gbc; + int fbw_channels = s->fbw_channels; + int dst_start_freq, dst_end_freq, src_start_freq, + start_subband, end_subband, ch; + + /* determine which channels use spx */ + if (s->channel_mode == AC3_CHMODE_MONO) { + s->channel_uses_spx[1] = 1; + } else { + for (ch = 1; ch <= fbw_channels; ch++) + s->channel_uses_spx[ch] = get_bits1(bc); + } + + /* get the frequency bins of the spx copy region and the spx start + and end subbands */ + dst_start_freq = get_bits(bc, 2); + start_subband = get_bits(bc, 3) + 2; + if (start_subband > 7) + start_subband += start_subband - 7; + end_subband = get_bits(bc, 3) + 5; + if (end_subband > 7) + end_subband += end_subband - 7; + dst_start_freq = dst_start_freq * 12 + 25; + src_start_freq = start_subband * 12 + 25; + dst_end_freq = end_subband * 12 + 25; + + /* check validity of spx ranges */ + if (start_subband >= end_subband) { + av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension " + "range (%d >= %d)\n", start_subband, end_subband); + return AVERROR_INVALIDDATA; + } + if (dst_start_freq >= src_start_freq) { + av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension " + "copy start bin (%d >= %d)\n", dst_start_freq, src_start_freq); + return AVERROR_INVALIDDATA; + } + + s->spx_dst_start_freq = dst_start_freq; + s->spx_src_start_freq = src_start_freq; + s->spx_dst_end_freq = dst_end_freq; + + decode_band_structure(bc, blk, s->eac3, 0, + start_subband, end_subband, + ff_eac3_default_spx_band_struct, + &s->num_spx_bands, + s->spx_band_sizes); + + return 0; +} + +static inline void spx_coordinates(AC3DecodeContext *s) +{ + GetBitContext *bc = &s->gbc; + int fbw_channels = s->fbw_channels; + int ch, bnd; + + for (ch = 1; ch <= fbw_channels; ch++) { + if (s->channel_uses_spx[ch]) { + if (s->first_spx_coords[ch] || get_bits1(bc)) { + float spx_blend; + int bin, master_spx_coord; + + s->first_spx_coords[ch] = 0; + spx_blend = get_bits(bc, 5) * (1.0f / 32); + master_spx_coord = get_bits(bc, 2) * 3; + + bin = s->spx_src_start_freq; + for (bnd = 0; bnd < s->num_spx_bands; bnd++) { + int bandsize; + int spx_coord_exp, spx_coord_mant; + float nratio, sblend, nblend, spx_coord; + + /* calculate blending factors */ + bandsize = s->spx_band_sizes[bnd]; + nratio = ((float)((bin + (bandsize >> 1))) / s->spx_dst_end_freq) - spx_blend; + nratio = av_clipf(nratio, 0.0f, 1.0f); + nblend = sqrtf(3.0f * nratio); // noise is scaled by sqrt(3) + // to give unity variance + sblend = sqrtf(1.0f - nratio); + bin += bandsize; + + /* decode spx coordinates */ + spx_coord_exp = get_bits(bc, 4); + spx_coord_mant = get_bits(bc, 2); + if (spx_coord_exp == 15) spx_coord_mant <<= 1; + else spx_coord_mant += 4; + spx_coord_mant <<= (25 - spx_coord_exp - master_spx_coord); + spx_coord = spx_coord_mant * (1.0f / (1 << 23)); + + /* multiply noise and signal blending factors by spx coordinate */ + s->spx_noise_blend [ch][bnd] = nblend * spx_coord; + s->spx_signal_blend[ch][bnd] = sblend * spx_coord; + } + } + } else { + s->first_spx_coords[ch] = 1; + } + } +} + /** * Decode a single audio block from the AC-3 bitstream. */ @@ -753,7 +856,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) { int fbw_channels = s->fbw_channels; int channel_mode = s->channel_mode; - int i, bnd, seg, ch; + int i, bnd, seg, ch, ret; int different_transforms; int downmix_output; int cpl_in_use; @@ -797,51 +900,8 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) if (s->eac3 && (!blk || get_bits1(gbc))) { s->spx_in_use = get_bits1(gbc); if (s->spx_in_use) { - int dst_start_freq, dst_end_freq, src_start_freq, - start_subband, end_subband; - - /* determine which channels use spx */ - if (s->channel_mode == AC3_CHMODE_MONO) { - s->channel_uses_spx[1] = 1; - } else { - for (ch = 1; ch <= fbw_channels; ch++) - s->channel_uses_spx[ch] = get_bits1(gbc); - } - - /* get the frequency bins of the spx copy region and the spx start - and end subbands */ - dst_start_freq = get_bits(gbc, 2); - start_subband = get_bits(gbc, 3) + 2; - if (start_subband > 7) - start_subband += start_subband - 7; - end_subband = get_bits(gbc, 3) + 5; - if (end_subband > 7) - end_subband += end_subband - 7; - dst_start_freq = dst_start_freq * 12 + 25; - src_start_freq = start_subband * 12 + 25; - dst_end_freq = end_subband * 12 + 25; - - /* check validity of spx ranges */ - if (start_subband >= end_subband) { - av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension " - "range (%d >= %d)\n", start_subband, end_subband); - return AVERROR_INVALIDDATA; - } - if (dst_start_freq >= src_start_freq) { - av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension " - "copy start bin (%d >= %d)\n", dst_start_freq, src_start_freq); - return AVERROR_INVALIDDATA; - } - - s->spx_dst_start_freq = dst_start_freq; - s->spx_src_start_freq = src_start_freq; - s->spx_dst_end_freq = dst_end_freq; - - decode_band_structure(gbc, blk, s->eac3, 0, - start_subband, end_subband, - ff_eac3_default_spx_band_struct, - &s->num_spx_bands, - s->spx_band_sizes); + if ((ret = spx_strategy(s, blk)) < 0) + return ret; } else { for (ch = 1; ch <= fbw_channels; ch++) { s->channel_uses_spx[ch] = 0; @@ -851,50 +911,8 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) } /* spectral extension coordinates */ - if (s->spx_in_use) { - for (ch = 1; ch <= fbw_channels; ch++) { - if (s->channel_uses_spx[ch]) { - if (s->first_spx_coords[ch] || get_bits1(gbc)) { - float spx_blend; - int bin, master_spx_coord; - - s->first_spx_coords[ch] = 0; - spx_blend = get_bits(gbc, 5) * (1.0f/32); - master_spx_coord = get_bits(gbc, 2) * 3; - - bin = s->spx_src_start_freq; - for (bnd = 0; bnd < s->num_spx_bands; bnd++) { - int bandsize; - int spx_coord_exp, spx_coord_mant; - float nratio, sblend, nblend, spx_coord; - - /* calculate blending factors */ - bandsize = s->spx_band_sizes[bnd]; - nratio = ((float)((bin + (bandsize >> 1))) / s->spx_dst_end_freq) - spx_blend; - nratio = av_clipf(nratio, 0.0f, 1.0f); - nblend = sqrtf(3.0f * nratio); // noise is scaled by sqrt(3) - // to give unity variance - sblend = sqrtf(1.0f - nratio); - bin += bandsize; - - /* decode spx coordinates */ - spx_coord_exp = get_bits(gbc, 4); - spx_coord_mant = get_bits(gbc, 2); - if (spx_coord_exp == 15) spx_coord_mant <<= 1; - else spx_coord_mant += 4; - spx_coord_mant <<= (25 - spx_coord_exp - master_spx_coord); - spx_coord = spx_coord_mant * (1.0f / (1 << 23)); - - /* multiply noise and signal blending factors by spx coordinate */ - s->spx_noise_blend [ch][bnd] = nblend * spx_coord; - s->spx_signal_blend[ch][bnd] = sblend * spx_coord; - } - } - } else { - s->first_spx_coords[ch] = 1; - } - } - } + if (s->spx_in_use) + spx_coordinates(s); /* coupling strategy */ if (s->eac3 ? s->cpl_strategy_exists[blk] : get_bits1(gbc)) { From f0ccc65bc9ab9ddf1366066395564c71bcc825ee Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 18 Jul 2016 19:50:33 +0200 Subject: [PATCH 0024/3374] ac3dec: Split coupling-specific code from decode_audio_block() Signed-off-by: Diego Biurrun --- libavcodec/ac3dec.c | 207 +++++++++++++++++++++++++------------------- 1 file changed, 116 insertions(+), 91 deletions(-) diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 4de74759814bf..f3e3da52fb42f 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -849,6 +849,118 @@ static inline void spx_coordinates(AC3DecodeContext *s) } } +static inline int coupling_strategy(AC3DecodeContext *s, int blk, + uint8_t *bit_alloc_stages) +{ + GetBitContext *bc = &s->gbc; + int fbw_channels = s->fbw_channels; + int channel_mode = s->channel_mode; + int ch; + + memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS); + if (!s->eac3) + s->cpl_in_use[blk] = get_bits1(bc); + if (s->cpl_in_use[blk]) { + /* coupling in use */ + int cpl_start_subband, cpl_end_subband; + + if (channel_mode < AC3_CHMODE_STEREO) { + av_log(s->avctx, AV_LOG_ERROR, "coupling not allowed in mono or dual-mono\n"); + return AVERROR_INVALIDDATA; + } + + /* check for enhanced coupling */ + if (s->eac3 && get_bits1(bc)) { + /* TODO: parse enhanced coupling strategy info */ + avpriv_request_sample(s->avctx, "Enhanced coupling"); + return AVERROR_PATCHWELCOME; + } + + /* determine which channels are coupled */ + if (s->eac3 && s->channel_mode == AC3_CHMODE_STEREO) { + s->channel_in_cpl[1] = 1; + s->channel_in_cpl[2] = 1; + } else { + for (ch = 1; ch <= fbw_channels; ch++) + s->channel_in_cpl[ch] = get_bits1(bc); + } + + /* phase flags in use */ + if (channel_mode == AC3_CHMODE_STEREO) + s->phase_flags_in_use = get_bits1(bc); + + /* coupling frequency range */ + cpl_start_subband = get_bits(bc, 4); + cpl_end_subband = s->spx_in_use ? (s->spx_src_start_freq - 37) / 12 : + get_bits(bc, 4) + 3; + if (cpl_start_subband >= cpl_end_subband) { + av_log(s->avctx, AV_LOG_ERROR, "invalid coupling range (%d >= %d)\n", + cpl_start_subband, cpl_end_subband); + return AVERROR_INVALIDDATA; + } + s->start_freq[CPL_CH] = cpl_start_subband * 12 + 37; + s->end_freq[CPL_CH] = cpl_end_subband * 12 + 37; + + decode_band_structure(bc, blk, s->eac3, 0, cpl_start_subband, + cpl_end_subband, + ff_eac3_default_cpl_band_struct, + &s->num_cpl_bands, s->cpl_band_sizes); + } else { + /* coupling not in use */ + for (ch = 1; ch <= fbw_channels; ch++) { + s->channel_in_cpl[ch] = 0; + s->first_cpl_coords[ch] = 1; + } + s->first_cpl_leak = s->eac3; + s->phase_flags_in_use = 0; + } + + return 0; +} + +static inline int coupling_coordinates(AC3DecodeContext *s, int blk) +{ + GetBitContext *bc = &s->gbc; + int fbw_channels = s->fbw_channels; + int ch, bnd; + int cpl_coords_exist = 0; + + for (ch = 1; ch <= fbw_channels; ch++) { + if (s->channel_in_cpl[ch]) { + if ((s->eac3 && s->first_cpl_coords[ch]) || get_bits1(bc)) { + int master_cpl_coord, cpl_coord_exp, cpl_coord_mant; + s->first_cpl_coords[ch] = 0; + cpl_coords_exist = 1; + master_cpl_coord = 3 * get_bits(bc, 2); + for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { + cpl_coord_exp = get_bits(bc, 4); + cpl_coord_mant = get_bits(bc, 4); + if (cpl_coord_exp == 15) + s->cpl_coords[ch][bnd] = cpl_coord_mant << 22; + else + s->cpl_coords[ch][bnd] = (cpl_coord_mant + 16) << 21; + s->cpl_coords[ch][bnd] >>= (cpl_coord_exp + master_cpl_coord); + } + } else if (!blk) { + av_log(s->avctx, AV_LOG_ERROR, "new coupling coordinates must " + "be present in block 0\n"); + return AVERROR_INVALIDDATA; + } + } else { + /* channel not in coupling */ + s->first_cpl_coords[ch] = 1; + } + } + /* phase flags */ + if (s->channel_mode == AC3_CHMODE_STEREO && cpl_coords_exist) { + for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { + s->phase_flags[bnd] = s->phase_flags_in_use ? get_bits1(bc) : 0; + } + } + + return 0; +} + /** * Decode a single audio block from the AC-3 bitstream. */ @@ -916,63 +1028,8 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) /* coupling strategy */ if (s->eac3 ? s->cpl_strategy_exists[blk] : get_bits1(gbc)) { - memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS); - if (!s->eac3) - s->cpl_in_use[blk] = get_bits1(gbc); - if (s->cpl_in_use[blk]) { - /* coupling in use */ - int cpl_start_subband, cpl_end_subband; - - if (channel_mode < AC3_CHMODE_STEREO) { - av_log(s->avctx, AV_LOG_ERROR, "coupling not allowed in mono or dual-mono\n"); - return AVERROR_INVALIDDATA; - } - - /* check for enhanced coupling */ - if (s->eac3 && get_bits1(gbc)) { - /* TODO: parse enhanced coupling strategy info */ - avpriv_request_sample(s->avctx, "Enhanced coupling"); - return AVERROR_PATCHWELCOME; - } - - /* determine which channels are coupled */ - if (s->eac3 && s->channel_mode == AC3_CHMODE_STEREO) { - s->channel_in_cpl[1] = 1; - s->channel_in_cpl[2] = 1; - } else { - for (ch = 1; ch <= fbw_channels; ch++) - s->channel_in_cpl[ch] = get_bits1(gbc); - } - - /* phase flags in use */ - if (channel_mode == AC3_CHMODE_STEREO) - s->phase_flags_in_use = get_bits1(gbc); - - /* coupling frequency range */ - cpl_start_subband = get_bits(gbc, 4); - cpl_end_subband = s->spx_in_use ? (s->spx_src_start_freq - 37) / 12 : - get_bits(gbc, 4) + 3; - if (cpl_start_subband >= cpl_end_subband) { - av_log(s->avctx, AV_LOG_ERROR, "invalid coupling range (%d >= %d)\n", - cpl_start_subband, cpl_end_subband); - return AVERROR_INVALIDDATA; - } - s->start_freq[CPL_CH] = cpl_start_subband * 12 + 37; - s->end_freq[CPL_CH] = cpl_end_subband * 12 + 37; - - decode_band_structure(gbc, blk, s->eac3, 0, cpl_start_subband, - cpl_end_subband, - ff_eac3_default_cpl_band_struct, - &s->num_cpl_bands, s->cpl_band_sizes); - } else { - /* coupling not in use */ - for (ch = 1; ch <= fbw_channels; ch++) { - s->channel_in_cpl[ch] = 0; - s->first_cpl_coords[ch] = 1; - } - s->first_cpl_leak = s->eac3; - s->phase_flags_in_use = 0; - } + if ((ret = coupling_strategy(s, blk, bit_alloc_stages)) < 0) + return ret; } else if (!s->eac3) { if (!blk) { av_log(s->avctx, AV_LOG_ERROR, "new coupling strategy must " @@ -986,40 +1043,8 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) /* coupling coordinates */ if (cpl_in_use) { - int cpl_coords_exist = 0; - - for (ch = 1; ch <= fbw_channels; ch++) { - if (s->channel_in_cpl[ch]) { - if ((s->eac3 && s->first_cpl_coords[ch]) || get_bits1(gbc)) { - int master_cpl_coord, cpl_coord_exp, cpl_coord_mant; - s->first_cpl_coords[ch] = 0; - cpl_coords_exist = 1; - master_cpl_coord = 3 * get_bits(gbc, 2); - for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { - cpl_coord_exp = get_bits(gbc, 4); - cpl_coord_mant = get_bits(gbc, 4); - if (cpl_coord_exp == 15) - s->cpl_coords[ch][bnd] = cpl_coord_mant << 22; - else - s->cpl_coords[ch][bnd] = (cpl_coord_mant + 16) << 21; - s->cpl_coords[ch][bnd] >>= (cpl_coord_exp + master_cpl_coord); - } - } else if (!blk) { - av_log(s->avctx, AV_LOG_ERROR, "new coupling coordinates must " - "be present in block 0\n"); - return AVERROR_INVALIDDATA; - } - } else { - /* channel not in coupling */ - s->first_cpl_coords[ch] = 1; - } - } - /* phase flags */ - if (channel_mode == AC3_CHMODE_STEREO && cpl_coords_exist) { - for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { - s->phase_flags[bnd] = s->phase_flags_in_use? get_bits1(gbc) : 0; - } - } + if ((ret = coupling_coordinates(s, blk)) < 0) + return ret; } /* stereo rematrixing strategy and band structure */ From 3db51bf671defd47f2ec5ab67b11fb7730fb5e5a Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 18 Jul 2016 19:50:35 +0200 Subject: [PATCH 0025/3374] ac3dec: Simplify skipping skip_bits_long() can skip up to 32-bit ranges. Signed-off-by: Diego Biurrun --- libavcodec/ac3dec.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index f3e3da52fb42f..a26316453fd35 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -1271,8 +1271,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) /* unused dummy data */ if (s->skip_syntax && get_bits1(gbc)) { int skipl = get_bits(gbc, 9); - while (skipl--) - skip_bits(gbc, 8); + skip_bits_long(gbc, 8 * skipl); } /* unpack the transform coefficients From 8495d84f0101464b15517860db33e8605586d87e Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 18 Jul 2016 19:50:34 +0200 Subject: [PATCH 0026/3374] ac3dec: Add some inline hints Signed-off-by: Diego Biurrun --- libavcodec/ac3dec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index a26316453fd35..9afc54d18dd84 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -548,8 +548,8 @@ static void remove_dithering(AC3DecodeContext *s) { } } -static void decode_transform_coeffs_ch(AC3DecodeContext *s, int blk, int ch, - mant_groups *m) +static inline void decode_transform_coeffs_ch(AC3DecodeContext *s, int blk, + int ch, mant_groups *m) { if (!s->channel_uses_aht[ch]) { ac3_decode_transform_coeffs_ch(s, ch, m); @@ -568,7 +568,7 @@ static void decode_transform_coeffs_ch(AC3DecodeContext *s, int blk, int ch, /** * Decode the transform coefficients. */ -static void decode_transform_coeffs(AC3DecodeContext *s, int blk) +static inline void decode_transform_coeffs(AC3DecodeContext *s, int blk) { int ch, end; int got_cplchan = 0; From 4fef648d10bf3bcfd4b8fa5755c1128966a2427c Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 27 Jul 2016 11:25:19 +0200 Subject: [PATCH 0027/3374] Remove the legacy X11 screen grabber The XCB screen grabber is a drop-in replacement and not under GPL. --- Changelog | 1 + LICENSE | 1 - configure | 13 +- libavdevice/Makefile | 1 - libavdevice/alldevices.c | 1 - libavdevice/avdevice.h | 2 +- libavdevice/x11grab.c | 647 --------------------------------------- 7 files changed, 4 insertions(+), 662 deletions(-) delete mode 100644 libavdevice/x11grab.c diff --git a/Changelog b/Changelog index d3201b3aaf05c..0d04f476e72a8 100644 --- a/Changelog +++ b/Changelog @@ -61,6 +61,7 @@ version : - Duck TrueMotion 2.0 Real Time decoder - Intel QSV video scaling and deinterlacing filter - OpenH264 decoder wrapper +- Removed the legacy X11 screen grabber, use XCB instead version 11: diff --git a/LICENSE b/LICENSE index 1eae4e7de7926..a2de35cf6346f 100644 --- a/LICENSE +++ b/LICENSE @@ -13,7 +13,6 @@ configure to activate them. In this case, Libav's license changes to GPL v2+. Specifically, the GPL parts of Libav are -- the X11 grabber in libavdevice/x11grab.c - the texi2pod.pl tool - the following filters in libavfilter: - vf_blackframe.c diff --git a/configure b/configure index e366dadc1b6cc..45f52560fd450 100755 --- a/configure +++ b/configure @@ -227,7 +227,6 @@ External library support: --enable-libxcb-xfixes X11 mouse rendering [auto] --enable-libxvid MPEG-4 ASP video encoding --enable-openssl crypto - --enable-x11grab X11 grabbing through xlib (legacy, use xcb instead) --enable-zlib compression [autodetect] The following libraries provide various hardware acceleration features: @@ -1242,7 +1241,6 @@ EXTERNAL_LIBRARY_GPL_LIST=" libx265 libxavs libxvid - x11grab " EXTERNAL_LIBRARY_NONFREE_LIST=" @@ -2369,7 +2367,6 @@ sndio_outdev_deps="sndio_h" v4l2_indev_deps_any="linux_videodev2_h sys_videoio_h" vfwcap_indev_deps="capCreateCaptureWindow vfwcap_defines" vfwcap_indev_extralibs="-lavicap32" -x11grab_indev_deps="x11grab" x11grab_xcb_indev_deps="libxcb" # protocols @@ -4752,10 +4749,10 @@ fi check_lib X11/Xlib.h XOpenDisplay -lX11 && enable xlib -if enabled libxcb || enabled x11grab && ! disabled libxcb; then +if enabled libxcb; then check_pkg_config xcb-shape xcb/shape.h xcb_shape_rectangles || { enabled libxcb && die "ERROR: libxcb not found"; - } && disable x11grab && enable libxcb + } && enable libxcb disabled libxcb_shm || check_pkg_config xcb-shm xcb/shm.h xcb_shm_attach || { @@ -4771,12 +4768,6 @@ if enabled libxcb || enabled x11grab && ! disabled libxcb; then add_extralibs "$xcb_event_libs $xcb_shm_libs $xcb_xfixes_libs" fi -if enabled x11grab; then - enabled xlib || die "ERROR: Xlib not found" - require Xext X11/extensions/XShm.h XShmCreateImage -lXext - require Xfixes X11/extensions/Xfixes.h XFixesGetCursorImage -lXfixes -fi - enabled vaapi && check_code cc "va/va.h" "vaCreateSurfaces(0, 0, 0, 0, 0, 0, 0, 0)" || disable vaapi diff --git a/libavdevice/Makefile b/libavdevice/Makefile index b3b53da8f2481..a4c96efaf1ce1 100644 --- a/libavdevice/Makefile +++ b/libavdevice/Makefile @@ -23,7 +23,6 @@ OBJS-$(CONFIG_SNDIO_INDEV) += sndio_dec.o sndio.o OBJS-$(CONFIG_SNDIO_OUTDEV) += sndio_enc.o sndio.o OBJS-$(CONFIG_V4L2_INDEV) += v4l2.o OBJS-$(CONFIG_VFWCAP_INDEV) += vfwcap.o -OBJS-$(CONFIG_X11GRAB_INDEV) += x11grab.o OBJS-$(CONFIG_X11GRAB_XCB_INDEV) += xcbgrab.o # external libraries diff --git a/libavdevice/alldevices.c b/libavdevice/alldevices.c index 8439b5b6e3887..8541dba519491 100644 --- a/libavdevice/alldevices.c +++ b/libavdevice/alldevices.c @@ -58,7 +58,6 @@ void avdevice_register_all(void) REGISTER_INOUTDEV(SNDIO, sndio); REGISTER_INDEV (V4L2, v4l2); REGISTER_INDEV (VFWCAP, vfwcap); - REGISTER_INDEV (X11GRAB, x11grab); REGISTER_INDEV (X11GRAB_XCB, x11grab_xcb); /* external libraries */ diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h index 39166a570a98d..824ac52659b9f 100644 --- a/libavdevice/avdevice.h +++ b/libavdevice/avdevice.h @@ -36,7 +36,7 @@ * (de)muxers in libavdevice are of the AVFMT_NOFILE type (they use their own * I/O functions). The filename passed to avformat_open_input() often does not * refer to an actually existing file, but has some special device-specific - * meaning - e.g. for x11grab it is the display name. + * meaning - e.g. for x11grab_xcb it is the display name. * * To use libavdevice, simply call avdevice_register_all() to register all * compiled muxers and demuxers. They all use standard libavformat API. diff --git a/libavdevice/x11grab.c b/libavdevice/x11grab.c deleted file mode 100644 index 60e2560d6b681..0000000000000 --- a/libavdevice/x11grab.c +++ /dev/null @@ -1,647 +0,0 @@ -/* - * X11 video grab interface - * - * This file is part of Libav. - * - * Libav integration: - * Copyright (C) 2006 Clemens Fruhwirth - * Edouard Gomez - * - * This file contains code from grab.c: - * Copyright (c) 2000-2001 Fabrice Bellard - * - * This file contains code from the xvidcap project: - * Copyright (C) 1997-1998 Rasca, Berlin - * 2003-2004 Karl H. Beckers, Frankfurt - * - * Libav is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Libav is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Libav; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * X11 frame device demuxer - * @author Clemens Fruhwirth - * @author Edouard Gomez - */ - -#include "config.h" - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "libavutil/internal.h" -#include "libavutil/log.h" -#include "libavutil/opt.h" -#include "libavutil/parseutils.h" -#include "libavutil/time.h" - -#include "libavformat/avformat.h" -#include "libavformat/internal.h" - -/** X11 device demuxer context */ -typedef struct X11GrabContext { - const AVClass *class; /**< Class for private options. */ - int frame_size; /**< Size in bytes of a grabbed frame */ - AVRational time_base; /**< Time base */ - int64_t time_frame; /**< Current time */ - - char *video_size; /**< String describing video size, set by a private option. */ - int height; /**< Height of the grab frame */ - int width; /**< Width of the grab frame */ - int x_off; /**< Horizontal top-left corner coordinate */ - int y_off; /**< Vertical top-left corner coordinate */ - - Display *dpy; /**< X11 display from which x11grab grabs frames */ - XImage *image; /**< X11 image holding the grab */ - int use_shm; /**< !0 when using XShm extension */ - XShmSegmentInfo shminfo; /**< When using XShm, keeps track of XShm info */ - int draw_mouse; /**< Set by a private option. */ - int follow_mouse; /**< Set by a private option. */ - int show_region; /**< set by a private option. */ - char *framerate; /**< Set by a private option. */ - - Window region_win; /**< This is used by show_region option. */ -} X11GrabContext; - -#define REGION_WIN_BORDER 3 - -/** - * Draw grabbing region window - * - * @param s x11grab context - */ -static void x11grab_draw_region_win(X11GrabContext *s) -{ - Display *dpy = s->dpy; - Window win = s->region_win; - int screen = DefaultScreen(dpy); - GC gc = XCreateGC(dpy, win, 0, 0); - - XSetForeground(dpy, gc, WhitePixel(dpy, screen)); - XSetBackground(dpy, gc, BlackPixel(dpy, screen)); - XSetLineAttributes(dpy, gc, REGION_WIN_BORDER, LineDoubleDash, 0, 0); - XDrawRectangle(dpy, win, gc, 1, 1, - (s->width + REGION_WIN_BORDER * 2) - 1 * 2 - 1, - (s->height + REGION_WIN_BORDER * 2) - 1 * 2 - 1); - XFreeGC(dpy, gc); -} - -/** - * Initialize grabbing region window - * - * @param s x11grab context - */ -static void x11grab_region_win_init(X11GrabContext *s) -{ - Display *dpy = s->dpy; - XRectangle rect; - XSetWindowAttributes attribs = { .override_redirect = True }; - int screen = DefaultScreen(dpy); - - s->region_win = XCreateWindow(dpy, RootWindow(dpy, screen), - s->x_off - REGION_WIN_BORDER, - s->y_off - REGION_WIN_BORDER, - s->width + REGION_WIN_BORDER * 2, - s->height + REGION_WIN_BORDER * 2, - 0, CopyFromParent, - InputOutput, CopyFromParent, - CWOverrideRedirect, &attribs); - rect.x = 0; - rect.y = 0; - rect.width = s->width; - rect.height = s->height; - XShapeCombineRectangles(dpy, s->region_win, - ShapeBounding, REGION_WIN_BORDER, REGION_WIN_BORDER, - &rect, 1, ShapeSubtract, 0); - XMapWindow(dpy, s->region_win); - XSelectInput(dpy, s->region_win, ExposureMask | StructureNotifyMask); - x11grab_draw_region_win(s); -} - -static int setup_shm(AVFormatContext *s, Display *dpy, XImage **image) -{ - X11GrabContext *g = s->priv_data; - int scr = XDefaultScreen(dpy); - XImage *img = XShmCreateImage(dpy, DefaultVisual(dpy, scr), - DefaultDepth(dpy, scr), ZPixmap, NULL, - &g->shminfo, g->width, g->height); - - g->shminfo.shmid = shmget(IPC_PRIVATE, img->bytes_per_line * img->height, - IPC_CREAT | 0777); - - if (g->shminfo.shmid == -1) { - av_log(s, AV_LOG_ERROR, "Cannot get shared memory!\n"); - return AVERROR(ENOMEM); - } - - g->shminfo.shmaddr = img->data = shmat(g->shminfo.shmid, 0, 0); - g->shminfo.readOnly = False; - - if (!XShmAttach(dpy, &g->shminfo)) { - av_log(s, AV_LOG_ERROR, "Failed to attach shared memory!\n"); - /* needs some better error subroutine :) */ - return AVERROR(EIO); - } - - *image = img; - return 0; -} - -static int setup_mouse(Display *dpy, int screen) -{ - int ev_ret, ev_err; - - if (XFixesQueryExtension(dpy, &ev_ret, &ev_err)) { - Window root = RootWindow(dpy, screen); - XFixesSelectCursorInput(dpy, root, XFixesDisplayCursorNotifyMask); - return 0; - } - - return AVERROR(ENOSYS); -} - -static int pixfmt_from_image(AVFormatContext *s, XImage *image, int *pix_fmt) -{ - av_log(s, AV_LOG_DEBUG, - "Image r 0x%.6lx g 0x%.6lx b 0x%.6lx and depth %i\n", - image->red_mask, - image->green_mask, - image->blue_mask, - image->bits_per_pixel); - - switch (image->bits_per_pixel) { - case 8: - *pix_fmt = AV_PIX_FMT_PAL8; - break; - case 16: - if (image->red_mask == 0xf800 && - image->green_mask == 0x07e0 && - image->blue_mask == 0x001f) { - *pix_fmt = AV_PIX_FMT_RGB565; - } else if (image->red_mask == 0x7c00 && - image->green_mask == 0x03e0 && - image->blue_mask == 0x001f) { - *pix_fmt = AV_PIX_FMT_RGB555; - } - break; - case 24: - if (image->red_mask == 0xff0000 && - image->green_mask == 0x00ff00 && - image->blue_mask == 0x0000ff) { - *pix_fmt = AV_PIX_FMT_BGR24; - } else if (image->red_mask == 0x0000ff && - image->green_mask == 0x00ff00 && - image->blue_mask == 0xff0000) { - *pix_fmt = AV_PIX_FMT_RGB24; - } - break; - case 32: - *pix_fmt = AV_PIX_FMT_RGB32; - break; - default: - av_log(s, AV_LOG_ERROR, - "XImages with RGB mask 0x%.6lx 0x%.6lx 0x%.6lx and depth %i " - "are currently not supported.\n", - image->red_mask, - image->green_mask, - image->blue_mask, - image->bits_per_pixel); - - return AVERROR_PATCHWELCOME; - } - - return 0; -} - -/** - * Initialize the x11 grab device demuxer (public device demuxer API). - * - * @param s1 Context from avformat core - * @return
    - *
  • AVERROR(ENOMEM) no memory left
  • - *
  • AVERROR(EIO) other failure case
  • - *
  • 0 success
  • - *
- */ -static int x11grab_read_header(AVFormatContext *s1) -{ - X11GrabContext *x11grab = s1->priv_data; - Display *dpy; - AVStream *st = NULL; - XImage *image; - int x_off = 0, y_off = 0, ret = 0, screen, use_shm; - char *param, *offset; - AVRational framerate; - - param = av_strdup(s1->filename); - if (!param) - goto out; - - offset = strchr(param, '+'); - if (offset) { - sscanf(offset, "%d,%d", &x_off, &y_off); - x11grab->draw_mouse = !strstr(offset, "nomouse"); - *offset = 0; - } - - ret = av_parse_video_size(&x11grab->width, &x11grab->height, - x11grab->video_size); - if (ret < 0) { - av_log(s1, AV_LOG_ERROR, "Couldn't parse video size.\n"); - goto out; - } - - ret = av_parse_video_rate(&framerate, x11grab->framerate); - if (ret < 0) { - av_log(s1, AV_LOG_ERROR, "Could not parse framerate: %s.\n", - x11grab->framerate); - goto out; - } - av_log(s1, AV_LOG_INFO, - "device: %s -> display: %s x: %d y: %d width: %d height: %d\n", - s1->filename, param, x_off, y_off, x11grab->width, x11grab->height); - - dpy = XOpenDisplay(param); - if (!dpy) { - av_log(s1, AV_LOG_ERROR, "Could not open X display.\n"); - ret = AVERROR(EIO); - goto out; - } - - st = avformat_new_stream(s1, NULL); - if (!st) { - ret = AVERROR(ENOMEM); - goto out; - } - avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ - - screen = DefaultScreen(dpy); - - if (x11grab->follow_mouse) { - int screen_w, screen_h; - Window w; - - screen_w = DisplayWidth(dpy, screen); - screen_h = DisplayHeight(dpy, screen); - XQueryPointer(dpy, RootWindow(dpy, screen), &w, &w, &x_off, &y_off, - &ret, &ret, &ret); - x_off -= x11grab->width / 2; - y_off -= x11grab->height / 2; - x_off = FFMIN(FFMAX(x_off, 0), screen_w - x11grab->width); - y_off = FFMIN(FFMAX(y_off, 0), screen_h - x11grab->height); - av_log(s1, AV_LOG_INFO, - "followmouse is enabled, resetting grabbing region to x: %d y: %d\n", - x_off, y_off); - } - - use_shm = XShmQueryExtension(dpy); - av_log(s1, AV_LOG_INFO, - "shared memory extension %sfound\n", use_shm ? "" : "not "); - - if (use_shm && setup_shm(s1, dpy, &image) < 0) { - av_log(s1, AV_LOG_WARNING, "Falling back to XGetImage\n"); - use_shm = 0; - } - - if (!use_shm) { - image = XGetImage(dpy, RootWindow(dpy, screen), - x_off, y_off, - x11grab->width, x11grab->height, - AllPlanes, ZPixmap); - } - - if (x11grab->draw_mouse && setup_mouse(dpy, screen) < 0) { - av_log(s1, AV_LOG_WARNING, - "XFixes not available, cannot draw the mouse cursor\n"); - x11grab->draw_mouse = 0; - } - - x11grab->frame_size = x11grab->width * x11grab->height * image->bits_per_pixel / 8; - x11grab->dpy = dpy; - x11grab->time_base = (AVRational) { framerate.den, framerate.num }; - x11grab->time_frame = av_gettime() / av_q2d(x11grab->time_base); - x11grab->x_off = x_off; - x11grab->y_off = y_off; - x11grab->image = image; - x11grab->use_shm = use_shm; - - ret = pixfmt_from_image(s1, image, &st->codecpar->format); - if (ret < 0) - goto out; - - st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; - st->codecpar->codec_id = AV_CODEC_ID_RAWVIDEO; - st->codecpar->width = x11grab->width; - st->codecpar->height = x11grab->height; - st->codecpar->bit_rate = x11grab->frame_size * 1 / av_q2d(x11grab->time_base) * 8; - - st->avg_frame_rate = av_inv_q(x11grab->time_base); - -out: - av_free(param); - return ret; -} - -/** - * Paint a mouse pointer in an X11 image. - * - * @param image image to paint the mouse pointer to - * @param s context used to retrieve original grabbing rectangle - * coordinates - */ -static void paint_mouse_pointer(XImage *image, X11GrabContext *s) -{ - int x_off = s->x_off; - int y_off = s->y_off; - int width = s->width; - int height = s->height; - Display *dpy = s->dpy; - XFixesCursorImage *xcim; - int x, y; - int line, column; - int to_line, to_column; - int pixstride = image->bits_per_pixel >> 3; - /* Warning: in its insanity, xlib provides unsigned image data through a - * char* pointer, so we have to make it uint8_t to make things not break. - * Anyone who performs further investigation of the xlib API likely risks - * permanent brain damage. */ - uint8_t *pix = image->data; - - /* Code doesn't currently support 16-bit or PAL8 */ - if (image->bits_per_pixel != 24 && image->bits_per_pixel != 32) - return; - - xcim = XFixesGetCursorImage(dpy); - if (!xcim) - return; - - x = xcim->x - xcim->xhot; - y = xcim->y - xcim->yhot; - - to_line = FFMIN((y + xcim->height), (height + y_off)); - to_column = FFMIN((x + xcim->width), (width + x_off)); - - for (line = FFMAX(y, y_off); line < to_line; line++) { - for (column = FFMAX(x, x_off); column < to_column; column++) { - int xcim_addr = (line - y) * xcim->width + column - x; - int image_addr = ((line - y_off) * width + column - x_off) * pixstride; - int r = (uint8_t)(xcim->pixels[xcim_addr] >> 0); - int g = (uint8_t)(xcim->pixels[xcim_addr] >> 8); - int b = (uint8_t)(xcim->pixels[xcim_addr] >> 16); - int a = (uint8_t)(xcim->pixels[xcim_addr] >> 24); - - if (a == 255) { - pix[image_addr + 0] = r; - pix[image_addr + 1] = g; - pix[image_addr + 2] = b; - } else if (a) { - /* pixel values from XFixesGetCursorImage come premultiplied by alpha */ - pix[image_addr + 0] = r + (pix[image_addr + 0] * (255 - a) + 255 / 2) / 255; - pix[image_addr + 1] = g + (pix[image_addr + 1] * (255 - a) + 255 / 2) / 255; - pix[image_addr + 2] = b + (pix[image_addr + 2] * (255 - a) + 255 / 2) / 255; - } - } - } - - XFree(xcim); - xcim = NULL; -} - -/** - * Read new data in the image structure. - * - * @param dpy X11 display to grab from - * @param d - * @param image Image where the grab will be put - * @param x Top-Left grabbing rectangle horizontal coordinate - * @param y Top-Left grabbing rectangle vertical coordinate - * @return 0 if error, !0 if successful - */ -static int xget_zpixmap(Display *dpy, Drawable d, XImage *image, int x, int y) -{ - xGetImageReply rep; - xGetImageReq *req; - long nbytes; - - if (!image) - return 0; - - LockDisplay(dpy); - GetReq(GetImage, req); - - /* First set up the standard stuff in the request */ - req->drawable = d; - req->x = x; - req->y = y; - req->width = image->width; - req->height = image->height; - req->planeMask = (unsigned int)AllPlanes; - req->format = ZPixmap; - - if (!_XReply(dpy, (xReply *)&rep, 0, xFalse) || !rep.length) { - UnlockDisplay(dpy); - SyncHandle(); - return 0; - } - - nbytes = (long)rep.length << 2; - _XReadPad(dpy, image->data, nbytes); - - UnlockDisplay(dpy); - SyncHandle(); - return 1; -} - -/** - * Grab a frame from x11 (public device demuxer API). - * - * @param s1 Context from avformat core - * @param pkt Packet holding the brabbed frame - * @return frame size in bytes - */ -static int x11grab_read_packet(AVFormatContext *s1, AVPacket *pkt) -{ - X11GrabContext *s = s1->priv_data; - Display *dpy = s->dpy; - XImage *image = s->image; - int x_off = s->x_off; - int y_off = s->y_off; - int follow_mouse = s->follow_mouse; - int screen, pointer_x, pointer_y, _, same_screen = 1; - Window w, root; - int64_t curtime, delay; - struct timespec ts; - - /* Calculate the time of the next frame */ - s->time_frame += INT64_C(1000000); - - /* wait based on the frame rate */ - for (;;) { - curtime = av_gettime(); - delay = s->time_frame * av_q2d(s->time_base) - curtime; - if (delay <= 0) { - if (delay < INT64_C(-1000000) * av_q2d(s->time_base)) - s->time_frame += INT64_C(1000000); - break; - } - ts.tv_sec = delay / 1000000; - ts.tv_nsec = (delay % 1000000) * 1000; - nanosleep(&ts, NULL); - } - - pkt->data = image->data; - pkt->size = s->frame_size; - pkt->pts = curtime; - - screen = DefaultScreen(dpy); - root = RootWindow(dpy, screen); - - if (follow_mouse || s->draw_mouse) - same_screen = XQueryPointer(dpy, root, &w, &w, - &pointer_x, &pointer_y, &_, &_, &_); - - if (follow_mouse && same_screen) { - int screen_w, screen_h; - - screen_w = DisplayWidth(dpy, screen); - screen_h = DisplayHeight(dpy, screen); - if (follow_mouse == -1) { - // follow the mouse, put it at center of grabbing region - x_off += pointer_x - s->width / 2 - x_off; - y_off += pointer_y - s->height / 2 - y_off; - } else { - // follow the mouse, but only move the grabbing region when mouse - // reaches within certain pixels to the edge. - if (pointer_x > x_off + s->width - follow_mouse) - x_off += pointer_x - (x_off + s->width - follow_mouse); - else if (pointer_x < x_off + follow_mouse) - x_off -= (x_off + follow_mouse) - pointer_x; - if (pointer_y > y_off + s->height - follow_mouse) - y_off += pointer_y - (y_off + s->height - follow_mouse); - else if (pointer_y < y_off + follow_mouse) - y_off -= (y_off + follow_mouse) - pointer_y; - } - // adjust grabbing region position if it goes out of screen. - s->x_off = x_off = FFMIN(FFMAX(x_off, 0), screen_w - s->width); - s->y_off = y_off = FFMIN(FFMAX(y_off, 0), screen_h - s->height); - - if (s->show_region && s->region_win) - XMoveWindow(dpy, s->region_win, - s->x_off - REGION_WIN_BORDER, - s->y_off - REGION_WIN_BORDER); - } - - if (s->show_region && same_screen) { - if (s->region_win) { - XEvent evt = { .type = NoEventMask }; - // Clean up the events, and do the initial draw or redraw. - while (XCheckMaskEvent(dpy, ExposureMask | StructureNotifyMask, - &evt)) - ; - if (evt.type) - x11grab_draw_region_win(s); - } else { - x11grab_region_win_init(s); - } - } - - if (s->use_shm) { - if (!XShmGetImage(dpy, root, image, x_off, y_off, AllPlanes)) - av_log(s1, AV_LOG_INFO, "XShmGetImage() failed\n"); - } else { - if (!xget_zpixmap(dpy, root, image, x_off, y_off)) - av_log(s1, AV_LOG_INFO, "XGetZPixmap() failed\n"); - } - - if (s->draw_mouse && same_screen) - paint_mouse_pointer(image, s); - - return s->frame_size; -} - -/** - * Close x11 frame grabber (public device demuxer API). - * - * @param s1 Context from avformat core - * @return 0 success, !0 failure - */ -static int x11grab_read_close(AVFormatContext *s1) -{ - X11GrabContext *x11grab = s1->priv_data; - - /* Detach cleanly from shared mem */ - if (x11grab->use_shm) { - XShmDetach(x11grab->dpy, &x11grab->shminfo); - shmdt(x11grab->shminfo.shmaddr); - shmctl(x11grab->shminfo.shmid, IPC_RMID, NULL); - } - - /* Destroy X11 image */ - if (x11grab->image) { - XDestroyImage(x11grab->image); - x11grab->image = NULL; - } - - if (x11grab->region_win) - XDestroyWindow(x11grab->dpy, x11grab->region_win); - - /* Free X11 display */ - XCloseDisplay(x11grab->dpy); - return 0; -} - -#define OFFSET(x) offsetof(X11GrabContext, x) -#define DEC AV_OPT_FLAG_DECODING_PARAM -static const AVOption options[] = { - { "grab_x", "Initial x coordinate.", OFFSET(x_off), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, DEC }, - { "grab_y", "Initial y coordinate.", OFFSET(y_off), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, DEC }, - { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = "vga"}, 0, 0, DEC }, - { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "ntsc"}, 0, 0, DEC }, - { "draw_mouse", "Draw the mouse pointer.", OFFSET(draw_mouse), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, DEC }, - { "follow_mouse", "Move the grabbing region when the mouse pointer reaches within specified amount of pixels to the edge of region.", - OFFSET(follow_mouse), AV_OPT_TYPE_INT, { .i64 = 0 }, -1, INT_MAX, DEC, "follow_mouse" }, - { "centered", "Keep the mouse pointer at the center of grabbing region when following.", 0, AV_OPT_TYPE_CONST, { .i64 = -1 }, INT_MIN, INT_MAX, DEC, "follow_mouse" }, - { "show_region", "Show the grabbing region.", OFFSET(show_region), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, DEC }, - { NULL }, -}; - -static const AVClass x11_class = { - .class_name = "X11grab indev", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - -/** x11 grabber device demuxer declaration */ -AVInputFormat ff_x11grab_demuxer = { - .name = "x11grab", - .long_name = NULL_IF_CONFIG_SMALL("X11grab"), - .priv_data_size = sizeof(X11GrabContext), - .read_header = x11grab_read_header, - .read_packet = x11grab_read_packet, - .read_close = x11grab_read_close, - .flags = AVFMT_NOFILE, - .priv_class = &x11_class, -}; From 5ed4644d6de7f6112431dc2d9a5cfe9a0a75a688 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 27 Jul 2016 11:31:49 +0200 Subject: [PATCH 0028/3374] x11grab: Rename internal component to "xcbgrab" --- configure | 2 +- libavdevice/Makefile | 2 +- libavdevice/alldevices.c | 2 +- libavdevice/avdevice.h | 2 +- libavdevice/xcbgrab.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/configure b/configure index 45f52560fd450..66da1e48df6f2 100755 --- a/configure +++ b/configure @@ -2367,7 +2367,7 @@ sndio_outdev_deps="sndio_h" v4l2_indev_deps_any="linux_videodev2_h sys_videoio_h" vfwcap_indev_deps="capCreateCaptureWindow vfwcap_defines" vfwcap_indev_extralibs="-lavicap32" -x11grab_xcb_indev_deps="libxcb" +xcbgrab_indev_deps="libxcb" # protocols ffrtmpcrypt_protocol_deps="!librtmp_protocol" diff --git a/libavdevice/Makefile b/libavdevice/Makefile index a4c96efaf1ce1..5bb1d3f8c9e84 100644 --- a/libavdevice/Makefile +++ b/libavdevice/Makefile @@ -23,7 +23,7 @@ OBJS-$(CONFIG_SNDIO_INDEV) += sndio_dec.o sndio.o OBJS-$(CONFIG_SNDIO_OUTDEV) += sndio_enc.o sndio.o OBJS-$(CONFIG_V4L2_INDEV) += v4l2.o OBJS-$(CONFIG_VFWCAP_INDEV) += vfwcap.o -OBJS-$(CONFIG_X11GRAB_XCB_INDEV) += xcbgrab.o +OBJS-$(CONFIG_XCBGRAB_INDEV) += xcbgrab.o # external libraries OBJS-$(CONFIG_LIBCDIO_INDEV) += libcdio.o diff --git a/libavdevice/alldevices.c b/libavdevice/alldevices.c index 8541dba519491..cdbca4c8e8be0 100644 --- a/libavdevice/alldevices.c +++ b/libavdevice/alldevices.c @@ -58,7 +58,7 @@ void avdevice_register_all(void) REGISTER_INOUTDEV(SNDIO, sndio); REGISTER_INDEV (V4L2, v4l2); REGISTER_INDEV (VFWCAP, vfwcap); - REGISTER_INDEV (X11GRAB_XCB, x11grab_xcb); + REGISTER_INDEV (XCBGRAB, xcbgrab); /* external libraries */ REGISTER_INDEV (LIBCDIO, libcdio); diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h index 824ac52659b9f..74043112df6ad 100644 --- a/libavdevice/avdevice.h +++ b/libavdevice/avdevice.h @@ -36,7 +36,7 @@ * (de)muxers in libavdevice are of the AVFMT_NOFILE type (they use their own * I/O functions). The filename passed to avformat_open_input() often does not * refer to an actually existing file, but has some special device-specific - * meaning - e.g. for x11grab_xcb it is the display name. + * meaning - e.g. for xcbgrab it is the display name. * * To use libavdevice, simply call avdevice_register_all() to register all * compiled muxers and demuxers. They all use standard libavformat API. diff --git a/libavdevice/xcbgrab.c b/libavdevice/xcbgrab.c index 9b85c28e24c67..0fd99ebc9f4c8 100644 --- a/libavdevice/xcbgrab.c +++ b/libavdevice/xcbgrab.c @@ -684,7 +684,7 @@ static av_cold int xcbgrab_read_header(AVFormatContext *s) return 0; } -AVInputFormat ff_x11grab_xcb_demuxer = { +AVInputFormat ff_xcbgrab_demuxer = { .name = "x11grab", .long_name = NULL_IF_CONFIG_SMALL("X11 screen capture, using XCB"), .priv_data_size = sizeof(XCBGrabContext), From 5ebef79abecc3ffcc4ab0d46e203d13b068107c9 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 29 Jul 2016 16:18:25 +0200 Subject: [PATCH 0029/3374] Fix instances of broken indentation found by gcc 6 --- libavcodec/ivi_dsp.c | 8 +-- libavcodec/mpegvideo.c | 18 +++---- libavcodec/qdm2.c | 115 +++++++++++++++++++++-------------------- libavformat/mxfdec.c | 4 +- 4 files changed, 73 insertions(+), 72 deletions(-) diff --git a/libavcodec/ivi_dsp.c b/libavcodec/ivi_dsp.c index bf0bec152a31e..9b74f730e444a 100644 --- a/libavcodec/ivi_dsp.c +++ b/libavcodec/ivi_dsp.c @@ -542,8 +542,8 @@ void ff_ivi_inverse_slant_8x8(const int32_t *in, int16_t *out, uint32_t pitch, c } else dst[0] = dst[8] = dst[16] = dst[24] = dst[32] = dst[40] = dst[48] = dst[56] = 0; - src++; - dst++; + src++; + dst++; } #undef COMPENSATE @@ -582,8 +582,8 @@ void ff_ivi_inverse_slant_4x4(const int32_t *in, int16_t *out, uint32_t pitch, c } else dst[0] = dst[4] = dst[8] = dst[12] = 0; - src++; - dst++; + src++; + dst++; } #undef COMPENSATE diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 230154f02cf88..379b690b4dd1e 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -548,7 +548,7 @@ do {\ av_fast_malloc(&s->bitstream_buffer, &s->allocated_bitstream_buffer_size, s1->allocated_bitstream_buffer_size); - s->bitstream_buffer_size = s1->bitstream_buffer_size; + s->bitstream_buffer_size = s1->bitstream_buffer_size; memcpy(s->bitstream_buffer, s1->bitstream_buffer, s1->bitstream_buffer_size); memset(s->bitstream_buffer + s->bitstream_buffer_size, 0, @@ -850,10 +850,10 @@ av_cold int ff_mpv_common_init(MpegEncContext *s) for (i = 0; i < nb_slices; i++) { if (init_duplicate_context(s->thread_context[i]) < 0) goto fail; - s->thread_context[i]->start_mb_y = - (s->mb_height * (i) + nb_slices / 2) / nb_slices; - s->thread_context[i]->end_mb_y = - (s->mb_height * (i + 1) + nb_slices / 2) / nb_slices; + s->thread_context[i]->start_mb_y = + (s->mb_height * (i) + nb_slices / 2) / nb_slices; + s->thread_context[i]->end_mb_y = + (s->mb_height * (i + 1) + nb_slices / 2) / nb_slices; } } else { if (init_duplicate_context(s) < 0) @@ -974,10 +974,10 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s) for (i = 0; i < nb_slices; i++) { if ((err = init_duplicate_context(s->thread_context[i])) < 0) goto fail; - s->thread_context[i]->start_mb_y = - (s->mb_height * (i) + nb_slices / 2) / nb_slices; - s->thread_context[i]->end_mb_y = - (s->mb_height * (i + 1) + nb_slices / 2) / nb_slices; + s->thread_context[i]->start_mb_y = + (s->mb_height * (i) + nb_slices / 2) / nb_slices; + s->thread_context[i]->end_mb_y = + (s->mb_height * (i + 1) + nb_slices / 2) / nb_slices; } } else { if (init_duplicate_context(s) < 0) diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c index ec57b359ca38e..7a7c149c2b64c 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -722,67 +722,68 @@ static void fill_coding_method_array(sb_int8_array tone_level_idx, } tone_level_idx_temp[ch][sb][0] = tone_level_idx_temp[ch][sb][1]; } - acc = 0; - for (ch = 0; ch < nb_channels; ch++) - for (sb = 0; sb < 30; sb++) - for (j = 0; j < 64; j++) - acc += tone_level_idx_temp[ch][sb][j]; - - multres = 0x66666667LL * (acc * 10); - esp_40 = (multres >> 32) / 8 + ((multres & 0xffffffff) >> 31); - for (ch = 0; ch < nb_channels; ch++) - for (sb = 0; sb < 30; sb++) - for (j = 0; j < 64; j++) { - comp = tone_level_idx_temp[ch][sb][j]* esp_40 * 10; - if (comp < 0) - comp += 0xff; - comp /= 256; // signed shift - switch(sb) { - case 0: - if (comp < 30) - comp = 30; - comp += 15; - break; - case 1: - if (comp < 24) - comp = 24; - comp += 10; - break; - case 2: - case 3: - case 4: - if (comp < 16) - comp = 16; - } - if (comp <= 5) - tmp = 0; - else if (comp <= 10) - tmp = 10; - else if (comp <= 16) - tmp = 16; - else if (comp <= 24) - tmp = -1; - else - tmp = 0; - coding_method[ch][sb][j] = ((tmp & 0xfffa) + 30 )& 0xff; + + acc = 0; + for (ch = 0; ch < nb_channels; ch++) + for (sb = 0; sb < 30; sb++) + for (j = 0; j < 64; j++) + acc += tone_level_idx_temp[ch][sb][j]; + + multres = 0x66666667LL * (acc * 10); + esp_40 = (multres >> 32) / 8 + ((multres & 0xffffffff) >> 31); + for (ch = 0; ch < nb_channels; ch++) + for (sb = 0; sb < 30; sb++) + for (j = 0; j < 64; j++) { + comp = tone_level_idx_temp[ch][sb][j]* esp_40 * 10; + if (comp < 0) + comp += 0xff; + comp /= 256; // signed shift + switch(sb) { + case 0: + if (comp < 30) + comp = 30; + comp += 15; + break; + case 1: + if (comp < 24) + comp = 24; + comp += 10; + break; + case 2: + case 3: + case 4: + if (comp < 16) + comp = 16; } + if (comp <= 5) + tmp = 0; + else if (comp <= 10) + tmp = 10; + else if (comp <= 16) + tmp = 16; + else if (comp <= 24) + tmp = -1; + else + tmp = 0; + coding_method[ch][sb][j] = ((tmp & 0xfffa) + 30 )& 0xff; + } + for (sb = 0; sb < 30; sb++) + fix_coding_method_array(sb, nb_channels, coding_method); + for (ch = 0; ch < nb_channels; ch++) for (sb = 0; sb < 30; sb++) - fix_coding_method_array(sb, nb_channels, coding_method); - for (ch = 0; ch < nb_channels; ch++) - for (sb = 0; sb < 30; sb++) - for (j = 0; j < 64; j++) - if (sb >= 10) { - if (coding_method[ch][sb][j] < 10) - coding_method[ch][sb][j] = 10; + for (j = 0; j < 64; j++) + if (sb >= 10) { + if (coding_method[ch][sb][j] < 10) + coding_method[ch][sb][j] = 10; + } else { + if (sb >= 2) { + if (coding_method[ch][sb][j] < 16) + coding_method[ch][sb][j] = 16; } else { - if (sb >= 2) { - if (coding_method[ch][sb][j] < 16) - coding_method[ch][sb][j] = 16; - } else { - if (coding_method[ch][sb][j] < 30) - coding_method[ch][sb][j] = 30; - } + if (coding_method[ch][sb][j] < 30) + coding_method[ch][sb][j] = 30; } + } } else { // superblocktype_2_3 != 0 for (ch = 0; ch < nb_channels; ch++) for (sb = 0; sb < 30; sb++) diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index ef82f0c6d1282..449af95e7a439 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -2479,8 +2479,8 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt) if ((ret64 = avio_seek(s->pb, pos, SEEK_SET)) < 0) return ret64; - if ((ret = av_get_packet(s->pb, pkt, size)) != size) - return ret < 0 ? ret : AVERROR_EOF; + if ((ret = av_get_packet(s->pb, pkt, size)) != size) + return ret < 0 ? ret : AVERROR_EOF; pkt->stream_index = 0; From ed1cd81076434b76f37576d4d806973476a8e96c Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 30 Jul 2016 15:14:26 +0200 Subject: [PATCH 0030/3374] flac demuxer: improve probing Extend the probe function to validate the STREAMINFO block that must follow the fLaC ID tag. --- libavformat/flacdec.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c index 7a75527333e21..2f4ac56040fa0 100644 --- a/libavformat/flacdec.c +++ b/libavformat/flacdec.c @@ -177,9 +177,24 @@ static int flac_read_header(AVFormatContext *s) static int flac_probe(AVProbeData *p) { - if (p->buf_size < 4 || memcmp(p->buf, "fLaC", 4)) - return 0; - return AVPROBE_SCORE_EXTENSION; + /* file header + metadata header + checked bytes of streaminfo */ + if (p->buf_size >= 4 + 4 + 13) { + int type = p->buf[4] & 0x7f; + int size = AV_RB24(p->buf + 5); + int min_block_size = AV_RB16(p->buf + 8); + int max_block_size = AV_RB16(p->buf + 10); + int sample_rate = AV_RB24(p->buf + 18) >> 4; + + if (!memcmp(p->buf, "fLaC", 4) && + type == FLAC_METADATA_TYPE_STREAMINFO && + size == FLAC_STREAMINFO_SIZE && + min_block_size >= 16 && + max_block_size >= min_block_size && + sample_rate && sample_rate <= 655350) + return AVPROBE_SCORE_MAX; + } + + return 0; } AVInputFormat ff_flac_demuxer = { From e328178da90f44690e0076f4dbfd16da9175f441 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 30 Jul 2016 16:38:51 +0200 Subject: [PATCH 0031/3374] qsvdec: only access hwaccel_context is the pixel format is QSV We do not strictly specify that hwaccel_context must be cleared if no hwaccel is used. Reported-By: wm4 --- libavcodec/qsvdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index 4802932ea7c92..e19eba5b52ffd 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -106,7 +106,7 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q) return AVERROR(ENOMEM); } - if (avctx->hwaccel_context) { + if (avctx->pix_fmt == AV_PIX_FMT_QSV && avctx->hwaccel_context) { AVQSVContext *user_ctx = avctx->hwaccel_context; session = user_ctx->session; iopattern = user_ctx->iopattern; From 7ebdffc353f3f0827864e8e3461fdc00cc243b14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 28 Jul 2016 13:45:24 +0300 Subject: [PATCH 0032/3374] dxv: Check to make sure we don't overrun buffers on corrupt inputs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/dxv.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/libavcodec/dxv.c b/libavcodec/dxv.c index 32137f53929f9..99327dfaceaf9 100644 --- a/libavcodec/dxv.c +++ b/libavcodec/dxv.c @@ -125,7 +125,7 @@ static int dxv_decompress_dxt1(AVCodecContext *avctx) AV_WL32(ctx->tex_data + 4, bytestream2_get_le32(gbc)); /* Process input until the whole texture has been filled */ - while (pos < ctx->tex_size / 4) { + while (pos + 2 <= ctx->tex_size / 4) { CHECKPOINT(2); /* Copy two elements from a previous offset or from the input buffer */ @@ -178,7 +178,7 @@ static int dxv_decompress_dxt5(AVCodecContext *avctx) AV_WL32(ctx->tex_data + 12, bytestream2_get_le32(gbc)); /* Process input until the whole texture has been filled */ - while (pos < ctx->tex_size / 4) { + while (pos + 2 <= ctx->tex_size / 4) { if (run) { run--; @@ -207,7 +207,7 @@ static int dxv_decompress_dxt5(AVCodecContext *avctx) check += probe; } while (probe == 0xFFFF); } - while (check && pos < ctx->tex_size / 4) { + while (check && pos + 4 <= ctx->tex_size / 4) { prev = AV_RL32(ctx->tex_data + 4 * (pos - 4)); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; @@ -252,6 +252,8 @@ static int dxv_decompress_dxt5(AVCodecContext *avctx) case 2: /* Copy two dwords from a previous index */ idx = 8 + bytestream2_get_le16(gbc); + if (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4) + return AVERROR_INVALIDDATA; prev = AV_RL32(ctx->tex_data + 4 * (pos - idx)); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; @@ -274,9 +276,13 @@ static int dxv_decompress_dxt5(AVCodecContext *avctx) } CHECKPOINT(4); + if (pos + 2 > ctx->tex_size / 4) + return AVERROR_INVALIDDATA; /* Copy two elements from a previous offset or from the input buffer */ if (op) { + if (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4) + return AVERROR_INVALIDDATA; prev = AV_RL32(ctx->tex_data + 4 * (pos - idx)); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; @@ -287,6 +293,8 @@ static int dxv_decompress_dxt5(AVCodecContext *avctx) } else { CHECKPOINT(4); + if (op && (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4)) + return AVERROR_INVALIDDATA; if (op) prev = AV_RL32(ctx->tex_data + 4 * (pos - idx)); else From 25bacd0a0c32ae682e6f411b1ac9020aeaabca72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 28 Jul 2016 13:10:22 +0300 Subject: [PATCH 0033/3374] Don't use expressions with side effects in macro parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AV_WB32 can be implemented as a macro that expands its parameters multiple times (in case AV_HAVE_FAST_UNALIGNED isn't set and the compiler doesn't support GCC attributes); make sure not to read multiple times from the source in this case. Signed-off-by: Martin Storsjö --- libavcodec/dxv.c | 18 ++++++++++++------ libavformat/xmv.c | 6 ++++-- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/libavcodec/dxv.c b/libavcodec/dxv.c index 99327dfaceaf9..39b297a2356f5 100644 --- a/libavcodec/dxv.c +++ b/libavcodec/dxv.c @@ -121,8 +121,10 @@ static int dxv_decompress_dxt1(AVCodecContext *avctx) int pos = 2; /* Copy the first two elements */ - AV_WL32(ctx->tex_data, bytestream2_get_le32(gbc)); - AV_WL32(ctx->tex_data + 4, bytestream2_get_le32(gbc)); + value = bytestream2_get_le32(gbc); + AV_WL32(ctx->tex_data, value); + value = bytestream2_get_le32(gbc); + AV_WL32(ctx->tex_data + 4, value); /* Process input until the whole texture has been filled */ while (pos + 2 <= ctx->tex_size / 4) { @@ -172,10 +174,14 @@ static int dxv_decompress_dxt5(AVCodecContext *avctx) int probe, check; /* Copy the first four elements */ - AV_WL32(ctx->tex_data + 0, bytestream2_get_le32(gbc)); - AV_WL32(ctx->tex_data + 4, bytestream2_get_le32(gbc)); - AV_WL32(ctx->tex_data + 8, bytestream2_get_le32(gbc)); - AV_WL32(ctx->tex_data + 12, bytestream2_get_le32(gbc)); + value = bytestream2_get_le32(gbc); + AV_WL32(ctx->tex_data + 0, value); + value = bytestream2_get_le32(gbc); + AV_WL32(ctx->tex_data + 4, value); + value = bytestream2_get_le32(gbc); + AV_WL32(ctx->tex_data + 8, value); + value = bytestream2_get_le32(gbc); + AV_WL32(ctx->tex_data + 12, value); /* Process input until the whole texture has been filled */ while (pos + 2 <= ctx->tex_size / 4) { diff --git a/libavformat/xmv.c b/libavformat/xmv.c index b2112b0e9581d..fa391560f0568 100644 --- a/libavformat/xmv.c +++ b/libavformat/xmv.c @@ -512,8 +512,10 @@ static int xmv_fetch_video_packet(AVFormatContext *s, * WMV2 is little-endian. * TODO: This manual swap is of course suboptimal. */ - for (i = 0; i < frame_size; i += 4) - AV_WB32(pkt->data + i, avio_rl32(pb)); + for (i = 0; i < frame_size; i += 4) { + uint32_t val = avio_rl32(pb); + AV_WB32(pkt->data + i, val); + } pkt->stream_index = video->stream_index; From 014773b66bdff4de24f384066d1a85d2a5bb6774 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 28 Jul 2016 14:30:25 +0300 Subject: [PATCH 0034/3374] libavutil: Use an intermediate variable in AV_COPY*U MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If AV_RN and AV_WN are macros with multiple individual reads and writes, the previous version of the AV_COPYU macro would fail if the reads and writes overlap. This should not be any less efficient in any case, given a sensibly optimizing compiler. Signed-off-by: Martin Storsjö --- libavutil/intreadwrite.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libavutil/intreadwrite.h b/libavutil/intreadwrite.h index f77fd60f383f1..cdf1ef47ec7bb 100644 --- a/libavutil/intreadwrite.h +++ b/libavutil/intreadwrite.h @@ -467,7 +467,11 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias; * memory locations. */ -#define AV_COPYU(n, d, s) AV_WN##n(d, AV_RN##n(s)); +#define AV_COPYU(n, d, s) \ + do { \ + uint##n##_t val = AV_RN##n(s); \ + AV_WN##n(d, val); \ + } while (0) #ifndef AV_COPY16U # define AV_COPY16U(d, s) AV_COPYU(16, d, s) From 230b1c070baa3b6d4bd590426a365b843d60ff50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 1 Aug 2016 09:07:48 +0300 Subject: [PATCH 0035/3374] intreadwrite: Add intermediate variables in the byteswise AV_W*() macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids issues with expanding the argument multiple times, and makes sure that it is of the right type for the following shifts. Even if the caller of a macro could be expected not to pass parameters that have side effects if expanded multiple times, these fallback codepaths are rarely, if ever, tested, so it is expected that such issues can arise. Thefore, for safety, make sure the fallback codepaths only expand the arguments once. Signed-off-by: Martin Storsjö --- libavutil/intreadwrite.h | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/libavutil/intreadwrite.h b/libavutil/intreadwrite.h index cdf1ef47ec7bb..5f65957ce5f3b 100644 --- a/libavutil/intreadwrite.h +++ b/libavutil/intreadwrite.h @@ -210,7 +210,8 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias; ((const uint8_t*)(x))[1]) #endif #ifndef AV_WB16 -# define AV_WB16(p, d) do { \ +# define AV_WB16(p, val) do { \ + uint16_t d = val; \ ((uint8_t*)(p))[1] = (d); \ ((uint8_t*)(p))[0] = (d)>>8; \ } while(0) @@ -222,7 +223,8 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias; ((const uint8_t*)(x))[0]) #endif #ifndef AV_WL16 -# define AV_WL16(p, d) do { \ +# define AV_WL16(p, val) do { \ + uint16_t d = val; \ ((uint8_t*)(p))[0] = (d); \ ((uint8_t*)(p))[1] = (d)>>8; \ } while(0) @@ -236,7 +238,8 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias; ((const uint8_t*)(x))[3]) #endif #ifndef AV_WB32 -# define AV_WB32(p, d) do { \ +# define AV_WB32(p, val) do { \ + uint32_t d = val; \ ((uint8_t*)(p))[3] = (d); \ ((uint8_t*)(p))[2] = (d)>>8; \ ((uint8_t*)(p))[1] = (d)>>16; \ @@ -252,7 +255,8 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias; ((const uint8_t*)(x))[0]) #endif #ifndef AV_WL32 -# define AV_WL32(p, d) do { \ +# define AV_WL32(p, val) do { \ + uint32_t d = val; \ ((uint8_t*)(p))[0] = (d); \ ((uint8_t*)(p))[1] = (d)>>8; \ ((uint8_t*)(p))[2] = (d)>>16; \ @@ -272,7 +276,8 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias; (uint64_t)((const uint8_t*)(x))[7]) #endif #ifndef AV_WB64 -# define AV_WB64(p, d) do { \ +# define AV_WB64(p, val) do { \ + uint64_t d = val; \ ((uint8_t*)(p))[7] = (d); \ ((uint8_t*)(p))[6] = (d)>>8; \ ((uint8_t*)(p))[5] = (d)>>16; \ @@ -296,7 +301,8 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias; (uint64_t)((const uint8_t*)(x))[0]) #endif #ifndef AV_WL64 -# define AV_WL64(p, d) do { \ +# define AV_WL64(p, val) do { \ + uint64_t d = val; \ ((uint8_t*)(p))[0] = (d); \ ((uint8_t*)(p))[1] = (d)>>8; \ ((uint8_t*)(p))[2] = (d)>>16; \ From f79d847400d218cfd0b95f10358fe6e65ec3c9c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 1 Aug 2016 10:04:42 +0300 Subject: [PATCH 0036/3374] intreadwrite: Use the __unaligned keyword on MSVC for ARM and x86_64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AV_WN64 is meant for unaligned data, but the existing av_alias* unions (without a definition for the av_alias attribute - we don't have one for MSVC) indicate to the compiler that they would have sufficient alignment for normal access, i.e. the compiler is free to assume 8 byte alignment. On ARM, this makes sure that AV_WN64 (or two consecutive AV_WN32) is done with two str instructions instead of one strd. Signed-off-by: Martin Storsjö --- libavutil/intreadwrite.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavutil/intreadwrite.h b/libavutil/intreadwrite.h index 5f65957ce5f3b..32747b21cba01 100644 --- a/libavutil/intreadwrite.h +++ b/libavutil/intreadwrite.h @@ -197,6 +197,11 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias; # define AV_RN(s, p) (*((const __unaligned uint##s##_t*)(p))) # define AV_WN(s, p, v) (*((__unaligned uint##s##_t*)(p)) = (v)) +#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_X64)) && AV_HAVE_FAST_UNALIGNED + +# define AV_RN(s, p) (*((const __unaligned uint##s##_t*)(p))) +# define AV_WN(s, p, v) (*((__unaligned uint##s##_t*)(p)) = (v)) + #elif AV_HAVE_FAST_UNALIGNED # define AV_RN(s, p) (((const av_alias##s*)(p))->u##s) From 9806b9ab5c7fb2ac5efd8ffa8713fea0c5fd218d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 1 Aug 2016 09:04:33 +0300 Subject: [PATCH 0037/3374] Revert "Don't use expressions with side effects in macro parameters" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 25bacd0a0c32ae682e6f411b1ac9020aeaabca72. Since 230b1c070, the bytewise AV_W*() macros only expand their argument once, so revert to the more readable version of these. Signed-off-by: Martin Storsjö --- libavcodec/dxv.c | 18 ++++++------------ libavformat/xmv.c | 6 ++---- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/libavcodec/dxv.c b/libavcodec/dxv.c index 39b297a2356f5..99327dfaceaf9 100644 --- a/libavcodec/dxv.c +++ b/libavcodec/dxv.c @@ -121,10 +121,8 @@ static int dxv_decompress_dxt1(AVCodecContext *avctx) int pos = 2; /* Copy the first two elements */ - value = bytestream2_get_le32(gbc); - AV_WL32(ctx->tex_data, value); - value = bytestream2_get_le32(gbc); - AV_WL32(ctx->tex_data + 4, value); + AV_WL32(ctx->tex_data, bytestream2_get_le32(gbc)); + AV_WL32(ctx->tex_data + 4, bytestream2_get_le32(gbc)); /* Process input until the whole texture has been filled */ while (pos + 2 <= ctx->tex_size / 4) { @@ -174,14 +172,10 @@ static int dxv_decompress_dxt5(AVCodecContext *avctx) int probe, check; /* Copy the first four elements */ - value = bytestream2_get_le32(gbc); - AV_WL32(ctx->tex_data + 0, value); - value = bytestream2_get_le32(gbc); - AV_WL32(ctx->tex_data + 4, value); - value = bytestream2_get_le32(gbc); - AV_WL32(ctx->tex_data + 8, value); - value = bytestream2_get_le32(gbc); - AV_WL32(ctx->tex_data + 12, value); + AV_WL32(ctx->tex_data + 0, bytestream2_get_le32(gbc)); + AV_WL32(ctx->tex_data + 4, bytestream2_get_le32(gbc)); + AV_WL32(ctx->tex_data + 8, bytestream2_get_le32(gbc)); + AV_WL32(ctx->tex_data + 12, bytestream2_get_le32(gbc)); /* Process input until the whole texture has been filled */ while (pos + 2 <= ctx->tex_size / 4) { diff --git a/libavformat/xmv.c b/libavformat/xmv.c index fa391560f0568..b2112b0e9581d 100644 --- a/libavformat/xmv.c +++ b/libavformat/xmv.c @@ -512,10 +512,8 @@ static int xmv_fetch_video_packet(AVFormatContext *s, * WMV2 is little-endian. * TODO: This manual swap is of course suboptimal. */ - for (i = 0; i < frame_size; i += 4) { - uint32_t val = avio_rl32(pb); - AV_WB32(pkt->data + i, val); - } + for (i = 0; i < frame_size; i += 4) + AV_WB32(pkt->data + i, avio_rl32(pb)); pkt->stream_index = video->stream_index; From fc94a1acc27ab7296edce3fa81ef36691af5c134 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 1 Aug 2016 09:04:43 +0300 Subject: [PATCH 0038/3374] Revert "libavutil: Use an intermediate variable in AV_COPY*U" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 014773b66bdff4de24f384066d1a85d2a5bb6774. Since 230b1c070, the bytewise AV_W*() macros only expand their argument once, i.e. doing exactly the same change as was done in the AV_COPY*U macros, so this change is no longer necessary. Signed-off-by: Martin Storsjö --- libavutil/intreadwrite.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/libavutil/intreadwrite.h b/libavutil/intreadwrite.h index 32747b21cba01..fdb91d6bedff5 100644 --- a/libavutil/intreadwrite.h +++ b/libavutil/intreadwrite.h @@ -478,11 +478,7 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias; * memory locations. */ -#define AV_COPYU(n, d, s) \ - do { \ - uint##n##_t val = AV_RN##n(s); \ - AV_WN##n(d, val); \ - } while (0) +#define AV_COPYU(n, d, s) AV_WN##n(d, AV_RN##n(s)); #ifndef AV_COPY16U # define AV_COPY16U(d, s) AV_COPYU(16, d, s) From e723dce6f8ba1e8260433b6ecfe5a3262f4c7a99 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 1 Aug 2016 21:19:09 +0200 Subject: [PATCH 0039/3374] dvbsubdec: Use NULL instead of 0 as pointer value --- libavcodec/dvbsubdec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c index 526f12526237b..bd12b38050f07 100644 --- a/libavcodec/dvbsubdec.c +++ b/libavcodec/dvbsubdec.c @@ -344,7 +344,7 @@ static void delete_state(DVBSubContext *ctx) /* Should already be null */ if (ctx->object_list) - av_log(0, AV_LOG_ERROR, "Memory deallocation error!\n"); + av_log(NULL, AV_LOG_ERROR, "Memory deallocation error!\n"); } static av_cold int dvbsub_init_decoder(AVCodecContext *avctx) @@ -539,7 +539,7 @@ static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, } if (get_bits(&gb, 6)) - av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n"); + av_log(NULL, AV_LOG_ERROR, "DVBSub error: line overflow\n"); (*srcbuf) += (get_bits_count(&gb) + 7) >> 3; @@ -660,7 +660,7 @@ static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, } if (get_bits(&gb, 8)) - av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n"); + av_log(NULL, AV_LOG_ERROR, "DVBSub error: line overflow\n"); (*srcbuf) += (get_bits_count(&gb) + 7) >> 3; @@ -712,7 +712,7 @@ static int dvbsub_read_8bit_string(uint8_t *destbuf, int dbuf_len, } if (*(*srcbuf)++) - av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n"); + av_log(NULL, AV_LOG_ERROR, "DVBSub error: line overflow\n"); return pixels_read; } From 3ccec334b8502701e72ef13bed25913c3578022e Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 30 Jul 2016 14:33:50 +0200 Subject: [PATCH 0040/3374] sbrdsp: Move a misplaced #endif directive to the right spot --- libavcodec/sbrdsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/sbrdsp.c b/libavcodec/sbrdsp.c index b7917dc9af4ea..029433225f746 100644 --- a/libavcodec/sbrdsp.c +++ b/libavcodec/sbrdsp.c @@ -168,8 +168,8 @@ static void sbr_autocorrelate_c(const float x[40][2], float phi[3][2][2]) phi[2 - 1][1][1] = imag_sum1 + x[ 0][0] * x[ 1][1] - x[ 0][1] * x[ 1][0]; phi[0 ][0][0] = real_sum1 + x[38][0] * x[39][0] + x[38][1] * x[39][1]; phi[0 ][0][1] = imag_sum1 + x[38][0] * x[39][1] - x[38][1] * x[39][0]; -#endif } +#endif static void sbr_hf_gen_c(float (*X_high)[2], const float (*X_low)[2], const float alpha0[2], const float alpha1[2], From e5b019725f53b79159931d3a7317107cbbfd0860 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 7 Sep 2014 16:39:39 +0200 Subject: [PATCH 0041/3374] m4vdec: Check for non-startcode 00 00 00 sequences in probe This makes the m4v detection less trigger-happy. Bug-Id: 949 Signed-off-by: Diego Biurrun --- libavformat/m4vdec.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libavformat/m4vdec.c b/libavformat/m4vdec.c index 4a0af3c03735e..9d69dcc042142 100644 --- a/libavformat/m4vdec.c +++ b/libavformat/m4vdec.c @@ -33,16 +33,18 @@ static int mpeg4video_probe(AVProbeData *probe_packet) for (i = 0; i < probe_packet->buf_size; i++) { temp_buffer = (temp_buffer << 8) + probe_packet->buf[i]; - if ((temp_buffer & 0xffffff00) != 0x100) + if (temp_buffer & 0xfffffe00) + continue; + if (temp_buffer < 2) continue; if (temp_buffer == VOP_START_CODE) VOP++; else if (temp_buffer == VISUAL_OBJECT_START_CODE) VISO++; - else if (temp_buffer < 0x120) + else if (temp_buffer >= 0x100 && temp_buffer < 0x120) VO++; - else if (temp_buffer < 0x130) + else if (temp_buffer >= 0x120 && temp_buffer < 0x130) VOL++; else if (!(0x1AF < temp_buffer && temp_buffer < 0x1B7) && !(0x1B9 < temp_buffer && temp_buffer < 0x1C4)) From d3e4d406b020b0464486318aceda08bd8f69ca41 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 1 Aug 2016 07:42:30 +0200 Subject: [PATCH 0042/3374] h264dec: reset nb_slice_ctx_queued for hwaccel decoding Fixes hwaccel decoding of files with multiple slices. Found-By: Mark Thompson --- libavcodec/h264dec.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 0e318a50b1ac8..2c5a7db33abf4 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -564,9 +564,10 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size) max_slice_ctx = avctx->hwaccel ? 1 : h->nb_slice_ctx; if (h->nb_slice_ctx_queued == max_slice_ctx) { - if (avctx->hwaccel) + if (avctx->hwaccel) { ret = avctx->hwaccel->decode_slice(avctx, nal->raw_data, nal->raw_size); - else + h->nb_slice_ctx_queued = 0; + } else ret = ff_h264_execute_decode_slices(h); if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) goto end; From 3c504bc3599f00bfc5923adc114beef34bce11d0 Mon Sep 17 00:00:00 2001 From: Christophe Gisquet Date: Wed, 6 Aug 2014 07:43:39 +0000 Subject: [PATCH 0043/3374] x86: deduplicate some constants Signed-off-by: Anton Khirnov --- libavcodec/x86/constants.c | 2 ++ libavcodec/x86/constants.h | 3 +++ libavcodec/x86/h264_intrapred_10bit.asm | 2 +- libavcodec/x86/hevc_deblock.asm | 2 +- libavcodec/x86/vp8dsp.asm | 2 +- libavcodec/x86/vp9dsp.asm | 3 +-- 6 files changed, 9 insertions(+), 5 deletions(-) diff --git a/libavcodec/x86/constants.c b/libavcodec/x86/constants.c index 5b8d1b224f182..47f6ef53ae5b2 100644 --- a/libavcodec/x86/constants.c +++ b/libavcodec/x86/constants.c @@ -43,8 +43,10 @@ DECLARE_ALIGNED(16, const xmm_reg, ff_pw_64) = { 0x0040004000400040ULL, 0x004 DECLARE_ALIGNED(8, const uint64_t, ff_pw_96) = 0x0060006000600060ULL; DECLARE_ALIGNED(8, const uint64_t, ff_pw_128) = 0x0080008000800080ULL; DECLARE_ALIGNED(8, const uint64_t, ff_pw_255) = 0x00ff00ff00ff00ffULL; +DECLARE_ALIGNED(16, const xmm_reg, ff_pw_256) = { 0x0100010001000100ULL, 0x0100010001000100ULL }; DECLARE_ALIGNED(16, const xmm_reg, ff_pw_512) = { 0x0200020002000200ULL, 0x0200020002000200ULL }; DECLARE_ALIGNED(16, const xmm_reg, ff_pw_1019) = { 0x03FB03FB03FB03FBULL, 0x03FB03FB03FB03FBULL }; +DECLARE_ALIGNED(16, const xmm_reg, ff_pw_m1) = { 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL }; DECLARE_ALIGNED(16, const xmm_reg, ff_pb_0) = { 0x0000000000000000ULL, 0x0000000000000000ULL }; DECLARE_ALIGNED(16, const xmm_reg, ff_pb_1) = { 0x0101010101010101ULL, 0x0101010101010101ULL }; diff --git a/libavcodec/x86/constants.h b/libavcodec/x86/constants.h index f38fbe3425063..c3b8d501cda4a 100644 --- a/libavcodec/x86/constants.h +++ b/libavcodec/x86/constants.h @@ -42,6 +42,9 @@ extern const xmm_reg ff_pw_64; extern const uint64_t ff_pw_96; extern const uint64_t ff_pw_128; extern const uint64_t ff_pw_255; +extern const xmm_reg ff_pw_256; +extern const xmm_reg ff_pw_512; +extern const xmm_reg ff_pw_m1; extern const xmm_reg ff_pb_1; extern const xmm_reg ff_pb_3; diff --git a/libavcodec/x86/h264_intrapred_10bit.asm b/libavcodec/x86/h264_intrapred_10bit.asm index 55790a956e9a8..ecbe57b353875 100644 --- a/libavcodec/x86/h264_intrapred_10bit.asm +++ b/libavcodec/x86/h264_intrapred_10bit.asm @@ -26,6 +26,7 @@ SECTION_RODATA +cextern pw_512 cextern pw_16 cextern pw_8 cextern pw_4 @@ -35,7 +36,6 @@ cextern pw_1 pw_m32101234: dw -3, -2, -1, 0, 1, 2, 3, 4 pw_m3: times 8 dw -3 pw_pixel_max: times 8 dw ((1 << 10)-1) -pw_512: times 8 dw 512 pd_17: times 4 dd 17 pd_16: times 4 dd 16 diff --git a/libavcodec/x86/hevc_deblock.asm b/libavcodec/x86/hevc_deblock.asm index 1e895f0aa526c..153eaf7f9454f 100644 --- a/libavcodec/x86/hevc_deblock.asm +++ b/libavcodec/x86/hevc_deblock.asm @@ -27,12 +27,12 @@ SECTION_RODATA pw_pixel_max: times 8 dw ((1 << 10)-1) -pw_m1: times 8 dw -1 pw_m2: times 8 dw -2 pd_1 : times 4 dd 1 cextern pw_4 cextern pw_8 +cextern pw_m1 SECTION .text INIT_XMM sse2 diff --git a/libavcodec/x86/vp8dsp.asm b/libavcodec/x86/vp8dsp.asm index adc9730dfafae..e17d3b2132cb9 100644 --- a/libavcodec/x86/vp8dsp.asm +++ b/libavcodec/x86/vp8dsp.asm @@ -143,13 +143,13 @@ filter_h6_shuf1: db 0, 5, 1, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12 filter_h6_shuf2: db 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9 filter_h6_shuf3: db 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11 -pw_256: times 8 dw 256 pw_20091: times 4 dw 20091 pw_17734: times 4 dw 17734 cextern pw_3 cextern pw_4 cextern pw_64 +cextern pw_256 SECTION .text diff --git a/libavcodec/x86/vp9dsp.asm b/libavcodec/x86/vp9dsp.asm index 6488f3092d2e4..442fc2b8e7fe4 100644 --- a/libavcodec/x86/vp9dsp.asm +++ b/libavcodec/x86/vp9dsp.asm @@ -24,8 +24,7 @@ SECTION_RODATA -; FIXME share with vp8dsp.asm -pw_256: times 8 dw 256 +cextern pw_256 %macro F8_TAPS 8 times 8 db %1, %2 From 63ac8e2d93080b74f6be32c7c3c1a1e44aacf34e Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 23 Apr 2014 23:53:36 -0300 Subject: [PATCH 0044/3374] lavu: add LOCAL_ALIGNED_32 Signed-off-by: James Almer Signed-off-by: Anton Khirnov --- configure | 5 +++-- libavutil/internal.h | 6 ++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 66da1e48df6f2..80aa09ea4b63d 100755 --- a/configure +++ b/configure @@ -1468,6 +1468,7 @@ ARCH_FEATURES=" fast_cmov local_aligned_8 local_aligned_16 + local_aligned_32 simd_align_16 " @@ -4296,7 +4297,7 @@ elif enabled parisc; then elif enabled ppc; then - enable local_aligned_8 local_aligned_16 + enable local_aligned_8 local_aligned_16 local_aligned_32 check_inline_asm dcbzl '"dcbzl 0, %0" :: "r"(0)' check_inline_asm ibm_asm '"add 0, 0, 0"' @@ -4337,7 +4338,7 @@ elif enabled x86; then check_builtin rdtsc intrin.h "__rdtsc()" check_builtin mm_empty mmintrin.h "_mm_empty()" - enable local_aligned_8 local_aligned_16 + enable local_aligned_8 local_aligned_16 local_aligned_32 # check whether EBP is available on x86 # As 'i' is stored on the stack, this program will crash diff --git a/libavutil/internal.h b/libavutil/internal.h index b9be333b47644..d96762c75db8a 100644 --- a/libavutil/internal.h +++ b/libavutil/internal.h @@ -111,6 +111,12 @@ # define LOCAL_ALIGNED_16(t, v, ...) LOCAL_ALIGNED(16, t, v, __VA_ARGS__) #endif +#if HAVE_LOCAL_ALIGNED_32 +# define LOCAL_ALIGNED_32(t, v, ...) E1(LOCAL_ALIGNED_D(32, t, v, __VA_ARGS__,,)) +#else +# define LOCAL_ALIGNED_32(t, v, ...) LOCAL_ALIGNED(32, t, v, __VA_ARGS__) +#endif + #define FF_ALLOC_OR_GOTO(ctx, p, size, label)\ {\ p = av_malloc(size);\ From 89aebc5bcc6e23a0a79c3f51c3a55c3571692ba0 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 30 Jul 2016 20:54:42 +0200 Subject: [PATCH 0045/3374] lavc: align the linesize to 32 when AVX is enabled --- configure | 6 +++++- libavcodec/utils.c | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 80aa09ea4b63d..9f836b7d38c56 100755 --- a/configure +++ b/configure @@ -1469,7 +1469,9 @@ ARCH_FEATURES=" local_aligned_8 local_aligned_16 local_aligned_32 + simd_align simd_align_16 + simd_align_32 " BUILTIN_LIST=" @@ -1880,7 +1882,9 @@ aligned_stack_if_any="aarch64 ppc x86" fast_64bit_if_any="aarch64 alpha ia64 mips64 parisc64 ppc64 sparc64 x86_64" fast_clz_if_any="aarch64 alpha avr32 mips ppc x86" fast_unaligned_if_any="aarch64 ppc x86" +simd_align_if_any="simd_align_16 simd_align_32" simd_align_16_if_any="altivec neon sse" +simd_align_32_if_any="avx" # system capabilities symver_if_any="symver_asm_label symver_gnu_asm" @@ -5032,7 +5036,7 @@ enabled_all dxva2 CoTaskMemFree && enable dxva2_lib ! enabled_any memalign posix_memalign aligned_malloc && - enabled simd_align_16 && enable memalign_hack + enabled simd_align && enable memalign_hack map 'enabled $v && intrinsics=${v#intrinsics_}' $INTRINSICS_LIST diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 4184b95e634b9..ce86bfa2a760d 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -178,7 +178,9 @@ int ff_side_data_update_matrix_encoding(AVFrame *frame, return 0; } -#if HAVE_SIMD_ALIGN_16 +#if HAVE_SIMD_ALIGN_32 +# define STRIDE_ALIGN 32 +#elif HAVE_SIMD_ALIGN_16 # define STRIDE_ALIGN 16 #else # define STRIDE_ALIGN 8 From 89466de4aeaf5e359489b81b8a9920a2bc7936d6 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 30 Jul 2016 19:21:57 +0200 Subject: [PATCH 0046/3374] vp9/x86: rename vp9dsp to vp9mc It only contains the MC SIMD, other SIMD will go into different files. --- libavcodec/x86/Makefile | 2 +- libavcodec/x86/{vp9dsp.asm => vp9mc.asm} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename libavcodec/x86/{vp9dsp.asm => vp9mc.asm} (99%) diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile index 32086992b4881..204c856340734 100644 --- a/libavcodec/x86/Makefile +++ b/libavcodec/x86/Makefile @@ -125,4 +125,4 @@ YASM-OBJS-$(CONFIG_V210_ENCODER) += x86/v210enc.o YASM-OBJS-$(CONFIG_VORBIS_DECODER) += x86/vorbisdsp.o YASM-OBJS-$(CONFIG_VP3_DECODER) += x86/hpeldsp_vp3.o YASM-OBJS-$(CONFIG_VP6_DECODER) += x86/vp6dsp.o -YASM-OBJS-$(CONFIG_VP9_DECODER) += x86/vp9dsp.o +YASM-OBJS-$(CONFIG_VP9_DECODER) += x86/vp9mc.o diff --git a/libavcodec/x86/vp9dsp.asm b/libavcodec/x86/vp9mc.asm similarity index 99% rename from libavcodec/x86/vp9dsp.asm rename to libavcodec/x86/vp9mc.asm index 442fc2b8e7fe4..59e56687f2831 100644 --- a/libavcodec/x86/vp9dsp.asm +++ b/libavcodec/x86/vp9mc.asm @@ -1,5 +1,5 @@ ;****************************************************************************** -;* VP9 SIMD optimizations +;* VP9 motion compensation SIMD optimizations ;* ;* Copyright (c) 2013 Ronald S. Bultje ;* From 3a09494939ddb2f2fd0f8d015162d5174ec07d4c Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 24 Dec 2013 16:17:03 -0500 Subject: [PATCH 0047/3374] vp9mc/x86: add 16px functions (64bit only). Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9dsp_init.c | 5 ++ libavcodec/x86/vp9mc.asm | 122 +++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+) diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c index 833d983ab1ceb..dc08e60662692 100644 --- a/libavcodec/x86/vp9dsp_init.c +++ b/libavcodec/x86/vp9dsp_init.c @@ -64,6 +64,9 @@ ff_ ## avg ## _8tap_1d_ ## dir ## _ ## sz ## _ ## opt(uint8_t *dst, \ mc_funcs(4); mc_funcs(8); +#if ARCH_X86_64 +mc_funcs(16); +#endif #undef mc_funcs #undef mc_func @@ -95,7 +98,9 @@ ff_ ## avg ## _8tap_1d_ ## dir ## _ ## sz ## _ ## opt(uint8_t *dst, \ mc_rep_func(put, sz, hsz, v, ssse3); \ mc_rep_func(avg, sz, hsz, v, ssse3) +#if ARCH_X86_32 mc_rep_funcs(16, 8); +#endif mc_rep_funcs(32, 16); mc_rep_funcs(64, 32); diff --git a/libavcodec/x86/vp9mc.asm b/libavcodec/x86/vp9mc.asm index 59e56687f2831..152715c9b9f8a 100644 --- a/libavcodec/x86/vp9mc.asm +++ b/libavcodec/x86/vp9mc.asm @@ -144,6 +144,62 @@ INIT_XMM ssse3 filter_h_fn put filter_h_fn avg +%if ARCH_X86_64 +%macro filter_hx2_fn 1 +%assign %%px mmsize +cglobal %1_8tap_1d_h_ %+ %%px, 6, 6, 14, dst, src, dstride, sstride, h, filtery + mova m13, [pw_256] + mova m8, [filteryq+ 0] + mova m9, [filteryq+16] + mova m10, [filteryq+32] + mova m11, [filteryq+48] +.loop: + movu m0, [srcq-3] + movu m1, [srcq-2] + movu m2, [srcq-1] + movu m3, [srcq+0] + movu m4, [srcq+1] + movu m5, [srcq+2] + movu m6, [srcq+3] + movu m7, [srcq+4] + add srcq, sstrideq + SBUTTERFLY bw, 0, 1, 12 + SBUTTERFLY bw, 2, 3, 12 + SBUTTERFLY bw, 4, 5, 12 + SBUTTERFLY bw, 6, 7, 12 + pmaddubsw m0, m8 + pmaddubsw m1, m8 + pmaddubsw m2, m9 + pmaddubsw m3, m9 + pmaddubsw m4, m10 + pmaddubsw m5, m10 + pmaddubsw m6, m11 + pmaddubsw m7, m11 + paddw m0, m2 + paddw m1, m3 + paddw m4, m6 + paddw m5, m7 + paddsw m0, m4 + paddsw m1, m5 + pmulhrsw m0, m13 + pmulhrsw m1, m13 + packuswb m0, m1 +%ifidn %1, avg + pavgb m0, [dstq] +%endif + mova [dstq], m0 + add dstq, dstrideq + dec hd + jg .loop + RET +%endmacro + +INIT_XMM ssse3 +filter_hx2_fn put +filter_hx2_fn avg + +%endif ; ARCH_X86_64 + %macro filter_v_fn 1 %assign %%px mmsize/2 %if ARCH_X86_64 @@ -218,6 +274,72 @@ INIT_XMM ssse3 filter_v_fn put filter_v_fn avg +%if ARCH_X86_64 + +%macro filter_vx2_fn 1 +%assign %%px mmsize +cglobal %1_8tap_1d_v_ %+ %%px, 6, 8, 14, dst, src, dstride, sstride, h, filtery, src4, sstride3 + sub srcq, sstrideq + lea sstride3q, [sstrideq*3] + sub srcq, sstrideq + mova m13, [pw_256] + sub srcq, sstrideq + mova m8, [filteryq+ 0] + lea src4q, [srcq+sstrideq*4] + mova m9, [filteryq+16] + mova m10, [filteryq+32] + mova m11, [filteryq+48] +.loop: + ; FIXME maybe reuse loads from previous rows, or just + ; more generally unroll this to prevent multiple loads of + ; the same data? + movu m0, [srcq] + movu m1, [srcq+sstrideq] + movu m2, [srcq+sstrideq*2] + movu m3, [srcq+sstride3q] + movu m4, [src4q] + movu m5, [src4q+sstrideq] + movu m6, [src4q+sstrideq*2] + movu m7, [src4q+sstride3q] + add srcq, sstrideq + add src4q, sstrideq + SBUTTERFLY bw, 0, 1, 12 + SBUTTERFLY bw, 2, 3, 12 + SBUTTERFLY bw, 4, 5, 12 + SBUTTERFLY bw, 6, 7, 12 + pmaddubsw m0, m8 + pmaddubsw m1, m8 + pmaddubsw m2, m9 + pmaddubsw m3, m9 + pmaddubsw m4, m10 + pmaddubsw m5, m10 + pmaddubsw m6, m11 + pmaddubsw m7, m11 + paddw m0, m2 + paddw m1, m3 + paddw m4, m6 + paddw m5, m7 + paddsw m0, m4 + paddsw m1, m5 + pmulhrsw m0, m13 + pmulhrsw m1, m13 + packuswb m0, m1 +%ifidn %1, avg + pavgb m0, [dstq] +%endif + mova [dstq], m0 + add dstq, dstrideq + dec hd + jg .loop + RET +%endmacro + +INIT_XMM ssse3 +filter_vx2_fn put +filter_vx2_fn avg + +%endif ; ARCH_X86_64 + %macro fpel_fn 6 %if %2 == 4 %define %%srcfn movh From 6ab642d69d18b4ecf1ea65a4dceca159f03a0313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 15 Jan 2014 22:35:43 +0100 Subject: [PATCH 0048/3374] vp9mc/x86: simplify a few inits. Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9mc.asm | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/libavcodec/x86/vp9mc.asm b/libavcodec/x86/vp9mc.asm index 152715c9b9f8a..43989dee73d55 100644 --- a/libavcodec/x86/vp9mc.asm +++ b/libavcodec/x86/vp9mc.asm @@ -209,13 +209,11 @@ cglobal %1_8tap_1d_v_ %+ %%px, 4, 7, 11, dst, src, dstride, sstride, filtery, sr mov filteryq, r5mp %define hd r4mp %endif - sub srcq, sstrideq - lea sstride3q, [sstrideq*3] - sub srcq, sstrideq mova m6, [pw_256] - sub srcq, sstrideq + lea sstride3q, [sstrideq*3] + lea src4q, [srcq+sstrideq] + sub srcq, sstride3q mova m7, [filteryq+ 0] - lea src4q, [srcq+sstrideq*4] %if ARCH_X86_64 && mmsize > 8 mova m8, [filteryq+16] mova m9, [filteryq+32] @@ -279,13 +277,11 @@ filter_v_fn avg %macro filter_vx2_fn 1 %assign %%px mmsize cglobal %1_8tap_1d_v_ %+ %%px, 6, 8, 14, dst, src, dstride, sstride, h, filtery, src4, sstride3 - sub srcq, sstrideq - lea sstride3q, [sstrideq*3] - sub srcq, sstrideq mova m13, [pw_256] - sub srcq, sstrideq + lea sstride3q, [sstrideq*3] + lea src4q, [srcq+sstrideq] + sub srcq, sstride3q mova m8, [filteryq+ 0] - lea src4q, [srcq+sstrideq*4] mova m9, [filteryq+16] mova m10, [filteryq+32] mova m11, [filteryq+48] From 8be8444d01d850b7ff2363f6886bfa8a8ea4a449 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 18 Jan 2014 02:29:22 -0300 Subject: [PATCH 0049/3374] vp9mc/x86: rename ff_avg[48]_sse to ff_avg[48]_mmxext pavgb is an sse integer instruction, so the mmxext flag is enough Signed-off-by: James Almer Reviewed-by: "Ronald S. Bultje" Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9dsp_init.c | 11 +++++++---- libavcodec/x86/vp9mc.asm | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c index dc08e60662692..2b94af34802c8 100644 --- a/libavcodec/x86/vp9dsp_init.c +++ b/libavcodec/x86/vp9dsp_init.c @@ -40,8 +40,8 @@ fpel_func(put, 8, mmx); fpel_func(put, 16, sse); fpel_func(put, 32, sse); fpel_func(put, 64, sse); -fpel_func(avg, 4, sse); -fpel_func(avg, 8, sse); +fpel_func(avg, 4, mmxext); +fpel_func(avg, 8, mmxext); fpel_func(avg, 16, sse2); fpel_func(avg, 32, sse2); fpel_func(avg, 64, sse2); @@ -222,12 +222,15 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) init_fpel(3, 0, 8, put, mmx); } + if (EXTERNAL_MMXEXT(cpu_flags)) { + init_fpel(4, 1, 4, avg, mmxext); + init_fpel(3, 1, 8, avg, mmxext); + } + if (EXTERNAL_SSE(cpu_flags)) { init_fpel(2, 0, 16, put, sse); init_fpel(1, 0, 32, put, sse); init_fpel(0, 0, 64, put, sse); - init_fpel(4, 1, 4, avg, sse); - init_fpel(3, 1, 8, avg, sse); } if (EXTERNAL_SSE2(cpu_flags)) { diff --git a/libavcodec/x86/vp9mc.asm b/libavcodec/x86/vp9mc.asm index 43989dee73d55..4c747ab1bbae5 100644 --- a/libavcodec/x86/vp9mc.asm +++ b/libavcodec/x86/vp9mc.asm @@ -379,7 +379,7 @@ cglobal %1%2, 5, 5, 4, dst, src, dstride, sstride, h INIT_MMX mmx fpel_fn put, 4, strideq, strideq*2, stride3q, 4 fpel_fn put, 8, strideq, strideq*2, stride3q, 4 -INIT_MMX sse +INIT_MMX mmxext fpel_fn avg, 4, strideq, strideq*2, stride3q, 4 fpel_fn avg, 8, strideq, strideq*2, stride3q, 4 INIT_XMM sse From 3cda179f180e48cda9afee9b1875f10e89a848a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Fri, 28 Mar 2014 22:33:51 +0100 Subject: [PATCH 0050/3374] vp9mc/x86: rename ff_* to ff_vp9_* Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9dsp_init.c | 94 ++++++++++++++++++------------------ libavcodec/x86/vp9mc.asm | 14 +++--- 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c index 2b94af34802c8..13662961afaeb 100644 --- a/libavcodec/x86/vp9dsp_init.c +++ b/libavcodec/x86/vp9dsp_init.c @@ -29,11 +29,11 @@ #if HAVE_YASM -#define fpel_func(avg, sz, opt) \ -void ff_ ## avg ## sz ## _ ## opt(uint8_t *dst, const uint8_t *src, \ - ptrdiff_t dst_stride, \ - ptrdiff_t src_stride, \ - int h, int mx, int my) +#define fpel_func(avg, sz, opt) \ +void ff_vp9_ ## avg ## sz ## _ ## opt(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t dst_stride, \ + ptrdiff_t src_stride, \ + int h, int mx, int my) fpel_func(put, 4, mmx); fpel_func(put, 8, mmx); @@ -47,14 +47,14 @@ fpel_func(avg, 32, sse2); fpel_func(avg, 64, sse2); #undef fpel_func -#define mc_func(avg, sz, dir, opt) \ -void \ -ff_ ## avg ## _8tap_1d_ ## dir ## _ ## sz ## _ ## opt(uint8_t *dst, \ - const uint8_t *src, \ - ptrdiff_t dst_stride, \ - ptrdiff_t src_stride, \ - int h, \ - const int8_t (*filter)[16]) +#define mc_func(avg, sz, dir, opt) \ +void \ +ff_vp9_ ## avg ## _8tap_1d_ ## dir ## _ ## sz ## _ ## opt(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t dst_stride, \ + ptrdiff_t src_stride, \ + int h, \ + const int8_t (*filter)[16]) #define mc_funcs(sz) \ mc_func(put, sz, h, ssse3); \ @@ -73,19 +73,19 @@ mc_funcs(16); #define mc_rep_func(avg, sz, hsz, dir, opt) \ static av_always_inline void \ -ff_ ## avg ## _8tap_1d_ ## dir ## _ ## sz ## _ ## opt(uint8_t *dst, \ +ff_vp9_ ## avg ## _8tap_1d_ ## dir ## _ ## sz ## _ ## opt(uint8_t *dst, \ const uint8_t *src, \ ptrdiff_t dst_stride, \ ptrdiff_t src_stride, \ int h, \ const int8_t (*filter)[16]) \ { \ - ff_ ## avg ## _8tap_1d_ ## dir ## _ ## hsz ## _ ## opt(dst, src, \ + ff_vp9_ ## avg ## _8tap_1d_ ## dir ## _ ## hsz ## _ ## opt(dst, src, \ dst_stride, \ src_stride, \ h, \ filter); \ - ff_ ## avg ## _8tap_1d_ ## dir ## _ ## hsz ## _ ## opt(dst + hsz, \ + ff_vp9_ ## avg ## _8tap_1d_ ## dir ## _ ## hsz ## _ ## opt(dst + hsz, \ src + hsz, \ dst_stride, \ src_stride, \ @@ -109,23 +109,23 @@ mc_rep_funcs(64, 32); extern const int8_t ff_filters_ssse3[3][15][4][16]; -#define filter_8tap_2d_fn(op, sz, f, fname) \ -static void \ -op ## _8tap_ ## fname ## _ ## sz ## hv_ssse3(uint8_t *dst, \ - const uint8_t *src, \ - ptrdiff_t dst_stride, \ - ptrdiff_t src_stride, \ - int h, int mx, int my) \ -{ \ - LOCAL_ALIGNED_16(uint8_t, temp, [71 * 64]); \ - ff_put_8tap_1d_h_ ## sz ## _ssse3(temp, src - 3 * src_stride, \ - 64, src_stride, \ - h + 7, \ - ff_filters_ssse3[f][mx - 1]); \ - ff_ ## op ## _8tap_1d_v_ ## sz ## _ssse3(dst, temp + 3 * 64, \ - dst_stride, 64, \ - h, \ - ff_filters_ssse3[f][my - 1]); \ +#define filter_8tap_2d_fn(op, sz, f, fname) \ +static void \ +op ## _8tap_ ## fname ## _ ## sz ## hv_ssse3(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t dst_stride, \ + ptrdiff_t src_stride, \ + int h, int mx, int my) \ +{ \ + LOCAL_ALIGNED_16(uint8_t, temp, [71 * 64]); \ + ff_vp9_put_8tap_1d_h_ ## sz ## _ssse3(temp, src - 3 * src_stride, \ + 64, src_stride, \ + h + 7, \ + ff_filters_ssse3[f][mx - 1]); \ + ff_vp9_ ## op ## _8tap_1d_v_ ## sz ## _ssse3(dst, temp + 3 * 64, \ + dst_stride, 64, \ + h, \ + ff_filters_ssse3[f][my - 1]); \ } #define filters_8tap_2d_fn(op, sz) \ @@ -147,19 +147,19 @@ filters_8tap_2d_fn2(avg) #undef filters_8tap_2d_fn #undef filter_8tap_2d_fn -#define filter_8tap_1d_fn(op, sz, f, fname, dir, dvar) \ -static void \ -op ## _8tap_ ## fname ## _ ## sz ## dir ## _ssse3(uint8_t *dst, \ - const uint8_t *src, \ - ptrdiff_t dst_stride, \ - ptrdiff_t src_stride, \ - int h, int mx, \ - int my) \ -{ \ - ff_ ## op ## _8tap_1d_ ## dir ## _ ## sz ## _ssse3(dst, src, \ - dst_stride, \ - src_stride, h, \ - ff_filters_ssse3[f][dvar - 1]); \ +#define filter_8tap_1d_fn(op, sz, f, fname, dir, dvar) \ +static void \ +op ## _8tap_ ## fname ## _ ## sz ## dir ## _ssse3(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t dst_stride, \ + ptrdiff_t src_stride, \ + int h, int mx, \ + int my) \ +{ \ + ff_vp9_ ## op ## _8tap_1d_ ## dir ## _ ## sz ## _ssse3(dst, src, \ + dst_stride, \ + src_stride, h,\ + ff_filters_ssse3[f][dvar - 1]); \ } #define filters_8tap_1d_fn(op, sz, dir, dvar) \ @@ -197,7 +197,7 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) dsp->mc[idx1][FILTER_8TAP_SMOOTH ][idx2][0][0] = \ dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][0][0] = \ dsp->mc[idx1][FILTER_8TAP_SHARP ][idx2][0][0] = \ - dsp->mc[idx1][FILTER_BILINEAR ][idx2][0][0] = ff_ ## type ## sz ## _ ## opt + dsp->mc[idx1][FILTER_BILINEAR ][idx2][0][0] = ff_vp9_ ## type ## sz ## _ ## opt #define init_subpel1(idx1, idx2, idxh, idxv, sz, dir, type, opt) \ diff --git a/libavcodec/x86/vp9mc.asm b/libavcodec/x86/vp9mc.asm index 4c747ab1bbae5..41b22204c0238 100644 --- a/libavcodec/x86/vp9mc.asm +++ b/libavcodec/x86/vp9mc.asm @@ -86,7 +86,7 @@ SECTION .text %macro filter_h_fn 1 %assign %%px mmsize/2 -cglobal %1_8tap_1d_h_ %+ %%px, 6, 6, 11, dst, src, dstride, sstride, h, filtery +cglobal vp9_%1_8tap_1d_h_ %+ %%px, 6, 6, 11, dst, src, dstride, sstride, h, filtery mova m6, [pw_256] mova m7, [filteryq+ 0] %if ARCH_X86_64 && mmsize > 8 @@ -147,7 +147,7 @@ filter_h_fn avg %if ARCH_X86_64 %macro filter_hx2_fn 1 %assign %%px mmsize -cglobal %1_8tap_1d_h_ %+ %%px, 6, 6, 14, dst, src, dstride, sstride, h, filtery +cglobal vp9_%1_8tap_1d_h_ %+ %%px, 6, 6, 14, dst, src, dstride, sstride, h, filtery mova m13, [pw_256] mova m8, [filteryq+ 0] mova m9, [filteryq+16] @@ -203,9 +203,9 @@ filter_hx2_fn avg %macro filter_v_fn 1 %assign %%px mmsize/2 %if ARCH_X86_64 -cglobal %1_8tap_1d_v_ %+ %%px, 6, 8, 11, dst, src, dstride, sstride, h, filtery, src4, sstride3 +cglobal vp9_%1_8tap_1d_v_ %+ %%px, 6, 8, 11, dst, src, dstride, sstride, h, filtery, src4, sstride3 %else -cglobal %1_8tap_1d_v_ %+ %%px, 4, 7, 11, dst, src, dstride, sstride, filtery, src4, sstride3 +cglobal vp9_%1_8tap_1d_v_ %+ %%px, 4, 7, 11, dst, src, dstride, sstride, filtery, src4, sstride3 mov filteryq, r5mp %define hd r4mp %endif @@ -276,7 +276,7 @@ filter_v_fn avg %macro filter_vx2_fn 1 %assign %%px mmsize -cglobal %1_8tap_1d_v_ %+ %%px, 6, 8, 14, dst, src, dstride, sstride, h, filtery, src4, sstride3 +cglobal vp9_%1_8tap_1d_v_ %+ %%px, 6, 8, 14, dst, src, dstride, sstride, h, filtery, src4, sstride3 mova m13, [pw_256] lea sstride3q, [sstrideq*3] lea src4q, [srcq+sstrideq] @@ -346,11 +346,11 @@ filter_vx2_fn avg %endif %if %2 <= 16 -cglobal %1%2, 5, 7, 4, dst, src, dstride, sstride, h, dstride3, sstride3 +cglobal vp9_%1%2, 5, 7, 4, dst, src, dstride, sstride, h, dstride3, sstride3 lea sstride3q, [sstrideq*3] lea dstride3q, [dstrideq*3] %else -cglobal %1%2, 5, 5, 4, dst, src, dstride, sstride, h +cglobal vp9_%1%2, 5, 5, 4, dst, src, dstride, sstride, h %endif .loop: %%srcfn m0, [srcq] From 67922b4ee48b5a5850ebf2cb6fcddf5979a26f68 Mon Sep 17 00:00:00 2001 From: James Almer Date: Mon, 22 Sep 2014 21:55:13 -0300 Subject: [PATCH 0051/3374] vp9mc/x86: add AVX and AVX2 MC Roughly 25% faster MC than ssse3 for blocksizes 32 and 64. Reviewed-by: Ronald S. Bultje Signed-off-by: James Almer Signed-off-by: Anton Khirnov --- libavcodec/x86/constants.c | 3 +- libavcodec/x86/constants.h | 2 +- libavcodec/x86/vp9dsp_init.c | 210 +++++++++++++++++++++-------------- libavcodec/x86/vp9mc.asm | 74 +++++++----- 4 files changed, 178 insertions(+), 111 deletions(-) diff --git a/libavcodec/x86/constants.c b/libavcodec/x86/constants.c index 47f6ef53ae5b2..6f7dd7346e044 100644 --- a/libavcodec/x86/constants.c +++ b/libavcodec/x86/constants.c @@ -43,7 +43,8 @@ DECLARE_ALIGNED(16, const xmm_reg, ff_pw_64) = { 0x0040004000400040ULL, 0x004 DECLARE_ALIGNED(8, const uint64_t, ff_pw_96) = 0x0060006000600060ULL; DECLARE_ALIGNED(8, const uint64_t, ff_pw_128) = 0x0080008000800080ULL; DECLARE_ALIGNED(8, const uint64_t, ff_pw_255) = 0x00ff00ff00ff00ffULL; -DECLARE_ALIGNED(16, const xmm_reg, ff_pw_256) = { 0x0100010001000100ULL, 0x0100010001000100ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_256) = { 0x0100010001000100ULL, 0x0100010001000100ULL, + 0x0100010001000100ULL, 0x0100010001000100ULL }; DECLARE_ALIGNED(16, const xmm_reg, ff_pw_512) = { 0x0200020002000200ULL, 0x0200020002000200ULL }; DECLARE_ALIGNED(16, const xmm_reg, ff_pw_1019) = { 0x03FB03FB03FB03FBULL, 0x03FB03FB03FB03FBULL }; DECLARE_ALIGNED(16, const xmm_reg, ff_pw_m1) = { 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL }; diff --git a/libavcodec/x86/constants.h b/libavcodec/x86/constants.h index c3b8d501cda4a..59ff94725d50f 100644 --- a/libavcodec/x86/constants.h +++ b/libavcodec/x86/constants.h @@ -42,7 +42,7 @@ extern const xmm_reg ff_pw_64; extern const uint64_t ff_pw_96; extern const uint64_t ff_pw_128; extern const uint64_t ff_pw_255; -extern const xmm_reg ff_pw_256; +extern const ymm_reg ff_pw_256; extern const xmm_reg ff_pw_512; extern const xmm_reg ff_pw_m1; diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c index 13662961afaeb..8c4af8368c395 100644 --- a/libavcodec/x86/vp9dsp_init.c +++ b/libavcodec/x86/vp9dsp_init.c @@ -45,6 +45,10 @@ fpel_func(avg, 8, mmxext); fpel_func(avg, 16, sse2); fpel_func(avg, 32, sse2); fpel_func(avg, 64, sse2); +fpel_func(put, 32, avx); +fpel_func(put, 64, avx); +fpel_func(avg, 32, avx2); +fpel_func(avg, 64, avx2); #undef fpel_func #define mc_func(avg, sz, dir, opt) \ @@ -54,18 +58,19 @@ ff_vp9_ ## avg ## _8tap_1d_ ## dir ## _ ## sz ## _ ## opt(uint8_t *dst, ptrdiff_t dst_stride, \ ptrdiff_t src_stride, \ int h, \ - const int8_t (*filter)[16]) + const int8_t (*filter)[32]) -#define mc_funcs(sz) \ - mc_func(put, sz, h, ssse3); \ - mc_func(avg, sz, h, ssse3); \ - mc_func(put, sz, v, ssse3); \ - mc_func(avg, sz, v, ssse3) +#define mc_funcs(sz, opt) \ + mc_func(put, sz, h, opt); \ + mc_func(avg, sz, h, opt); \ + mc_func(put, sz, v, opt); \ + mc_func(avg, sz, v, opt) -mc_funcs(4); -mc_funcs(8); +mc_funcs(4, ssse3); +mc_funcs(8, ssse3); #if ARCH_X86_64 -mc_funcs(16); +mc_funcs(16, ssse3); +mc_funcs(32, avx2); #endif #undef mc_funcs @@ -78,7 +83,7 @@ ff_vp9_ ## avg ## _8tap_1d_ ## dir ## _ ## sz ## _ ## opt(uint8_t *dst, \ ptrdiff_t dst_stride, \ ptrdiff_t src_stride, \ int h, \ - const int8_t (*filter)[16]) \ + const int8_t (*filter)[32]) \ { \ ff_vp9_ ## avg ## _8tap_1d_ ## dir ## _ ## hsz ## _ ## opt(dst, src, \ dst_stride, \ @@ -92,94 +97,109 @@ ff_vp9_ ## avg ## _8tap_1d_ ## dir ## _ ## sz ## _ ## opt(uint8_t *dst, \ h, filter); \ } -#define mc_rep_funcs(sz, hsz) \ - mc_rep_func(put, sz, hsz, h, ssse3); \ - mc_rep_func(avg, sz, hsz, h, ssse3); \ - mc_rep_func(put, sz, hsz, v, ssse3); \ - mc_rep_func(avg, sz, hsz, v, ssse3) +#define mc_rep_funcs(sz, hsz, opt) \ + mc_rep_func(put, sz, hsz, h, opt); \ + mc_rep_func(avg, sz, hsz, h, opt); \ + mc_rep_func(put, sz, hsz, v, opt); \ + mc_rep_func(avg, sz, hsz, v, opt) #if ARCH_X86_32 -mc_rep_funcs(16, 8); +mc_rep_funcs(16, 8, ssse3); +#endif +mc_rep_funcs(32, 16, ssse3); +mc_rep_funcs(64, 32, ssse3); +#if ARCH_X86_64 && HAVE_AVX2_EXTERNAL +mc_rep_funcs(64, 32, avx2); #endif -mc_rep_funcs(32, 16); -mc_rep_funcs(64, 32); #undef mc_rep_funcs #undef mc_rep_func -extern const int8_t ff_filters_ssse3[3][15][4][16]; - -#define filter_8tap_2d_fn(op, sz, f, fname) \ -static void \ -op ## _8tap_ ## fname ## _ ## sz ## hv_ssse3(uint8_t *dst, \ - const uint8_t *src, \ - ptrdiff_t dst_stride, \ - ptrdiff_t src_stride, \ - int h, int mx, int my) \ -{ \ - LOCAL_ALIGNED_16(uint8_t, temp, [71 * 64]); \ - ff_vp9_put_8tap_1d_h_ ## sz ## _ssse3(temp, src - 3 * src_stride, \ - 64, src_stride, \ - h + 7, \ - ff_filters_ssse3[f][mx - 1]); \ - ff_vp9_ ## op ## _8tap_1d_v_ ## sz ## _ssse3(dst, temp + 3 * 64, \ - dst_stride, 64, \ - h, \ - ff_filters_ssse3[f][my - 1]); \ +extern const int8_t ff_filters_ssse3[3][15][4][32]; + +#define filter_8tap_2d_fn(op, sz, f, fname, align, opt) \ +static void \ +op ## _8tap_ ## fname ## _ ## sz ## hv_ ## opt(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t dst_stride, \ + ptrdiff_t src_stride, \ + int h, int mx, int my) \ +{ \ + LOCAL_ALIGNED_ ## align(uint8_t, temp, [71 * 64]); \ + ff_vp9_put_8tap_1d_h_ ## sz ## _ ## opt(temp, src - 3 * src_stride, \ + 64, src_stride, \ + h + 7, \ + ff_filters_ssse3[f][mx - 1]); \ + ff_vp9_ ## op ## _8tap_1d_v_ ## sz ## _ ## opt(dst, temp + 3 * 64, \ + dst_stride, 64, \ + h, \ + ff_filters_ssse3[f][my - 1]); \ } -#define filters_8tap_2d_fn(op, sz) \ - filter_8tap_2d_fn(op, sz, FILTER_8TAP_REGULAR, regular) \ - filter_8tap_2d_fn(op, sz, FILTER_8TAP_SHARP, sharp) \ - filter_8tap_2d_fn(op, sz, FILTER_8TAP_SMOOTH, smooth) - -#define filters_8tap_2d_fn2(op) \ - filters_8tap_2d_fn(op, 64) \ - filters_8tap_2d_fn(op, 32) \ - filters_8tap_2d_fn(op, 16) \ - filters_8tap_2d_fn(op, 8) \ - filters_8tap_2d_fn(op, 4) - -filters_8tap_2d_fn2(put) -filters_8tap_2d_fn2(avg) +#define filters_8tap_2d_fn(op, sz, align, opt) \ + filter_8tap_2d_fn(op, sz, FILTER_8TAP_REGULAR, regular, align, opt) \ + filter_8tap_2d_fn(op, sz, FILTER_8TAP_SHARP, sharp, align, opt) \ + filter_8tap_2d_fn(op, sz, FILTER_8TAP_SMOOTH, smooth, align, opt) + +#define filters_8tap_2d_fn2(op, align, opt) \ + filters_8tap_2d_fn(op, 64, align, opt) \ + filters_8tap_2d_fn(op, 32, align, opt) \ + filters_8tap_2d_fn(op, 16, align, opt) \ + filters_8tap_2d_fn(op, 8, align, opt) \ + filters_8tap_2d_fn(op, 4, align, opt) + +filters_8tap_2d_fn2(put, 16, ssse3) +filters_8tap_2d_fn2(avg, 16, ssse3) +#if ARCH_X86_64 && HAVE_AVX2_EXTERNAL +filters_8tap_2d_fn(put, 64, 32, avx2) +filters_8tap_2d_fn(put, 32, 32, avx2) +filters_8tap_2d_fn(avg, 64, 32, avx2) +filters_8tap_2d_fn(avg, 32, 32, avx2) +#endif #undef filters_8tap_2d_fn2 #undef filters_8tap_2d_fn #undef filter_8tap_2d_fn -#define filter_8tap_1d_fn(op, sz, f, fname, dir, dvar) \ -static void \ -op ## _8tap_ ## fname ## _ ## sz ## dir ## _ssse3(uint8_t *dst, \ - const uint8_t *src, \ - ptrdiff_t dst_stride, \ - ptrdiff_t src_stride, \ - int h, int mx, \ - int my) \ -{ \ - ff_vp9_ ## op ## _8tap_1d_ ## dir ## _ ## sz ## _ssse3(dst, src, \ - dst_stride, \ - src_stride, h,\ - ff_filters_ssse3[f][dvar - 1]); \ +#define filter_8tap_1d_fn(op, sz, f, fname, dir, dvar, opt) \ +static void \ +op ## _8tap_ ## fname ## _ ## sz ## dir ## _ ## opt(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t dst_stride, \ + ptrdiff_t src_stride, \ + int h, int mx, \ + int my) \ +{ \ + ff_vp9_ ## op ## _8tap_1d_ ## dir ## _ ## sz ## _ ## opt(dst, src, \ + dst_stride, \ + src_stride, h,\ + ff_filters_ssse3[f][dvar - 1]); \ } -#define filters_8tap_1d_fn(op, sz, dir, dvar) \ - filter_8tap_1d_fn(op, sz, FILTER_8TAP_REGULAR, regular, dir, dvar) \ - filter_8tap_1d_fn(op, sz, FILTER_8TAP_SHARP, sharp, dir, dvar) \ - filter_8tap_1d_fn(op, sz, FILTER_8TAP_SMOOTH, smooth, dir, dvar) - -#define filters_8tap_1d_fn2(op, sz) \ - filters_8tap_1d_fn(op, sz, h, mx) \ - filters_8tap_1d_fn(op, sz, v, my) - -#define filters_8tap_1d_fn3(op) \ - filters_8tap_1d_fn2(op, 64) \ - filters_8tap_1d_fn2(op, 32) \ - filters_8tap_1d_fn2(op, 16) \ - filters_8tap_1d_fn2(op, 8) \ - filters_8tap_1d_fn2(op, 4) - -filters_8tap_1d_fn3(put) -filters_8tap_1d_fn3(avg) +#define filters_8tap_1d_fn(op, sz, dir, dvar, opt) \ + filter_8tap_1d_fn(op, sz, FILTER_8TAP_REGULAR, regular, dir, dvar, opt) \ + filter_8tap_1d_fn(op, sz, FILTER_8TAP_SHARP, sharp, dir, dvar, opt) \ + filter_8tap_1d_fn(op, sz, FILTER_8TAP_SMOOTH, smooth, dir, dvar, opt) + +#define filters_8tap_1d_fn2(op, sz, opt) \ + filters_8tap_1d_fn(op, sz, h, mx, opt) \ + filters_8tap_1d_fn(op, sz, v, my, opt) + +#define filters_8tap_1d_fn3(op, opt) \ + filters_8tap_1d_fn2(op, 64, opt) \ + filters_8tap_1d_fn2(op, 32, opt) \ + filters_8tap_1d_fn2(op, 16, opt) \ + filters_8tap_1d_fn2(op, 8, opt) \ + filters_8tap_1d_fn2(op, 4, opt) + +filters_8tap_1d_fn3(put, ssse3) +filters_8tap_1d_fn3(avg, ssse3) +#if ARCH_X86_64 && HAVE_AVX2_EXTERNAL +filters_8tap_1d_fn2(put, 64, avx2) +filters_8tap_1d_fn2(put, 32, avx2) +filters_8tap_1d_fn2(avg, 64, avx2) +filters_8tap_1d_fn2(avg, 32, avx2) +#endif #undef filters_8tap_1d_fn #undef filters_8tap_1d_fn2 @@ -205,9 +225,12 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][idxh][idxv] = type ## _8tap_regular_ ## sz ## dir ## _ ## opt; \ dsp->mc[idx1][FILTER_8TAP_SHARP][idx2][idxh][idxv] = type ## _8tap_sharp_ ## sz ## dir ## _ ## opt +#define init_subpel2_32_64(idx, idxh, idxv, dir, type, opt) \ + init_subpel1(0, idx, idxh, idxv, 64, dir, type, opt); \ + init_subpel1(1, idx, idxh, idxv, 32, dir, type, opt) + #define init_subpel2(idx, idxh, idxv, dir, type, opt) \ - init_subpel1(0, idx, idxh, idxv, 64, dir, type, opt); \ - init_subpel1(1, idx, idxh, idxv, 32, dir, type, opt); \ + init_subpel2_32_64(idx, idxh, idxv, dir, type, opt); \ init_subpel1(2, idx, idxh, idxv, 16, dir, type, opt); \ init_subpel1(3, idx, idxh, idxv, 8, dir, type, opt); \ init_subpel1(4, idx, idxh, idxv, 4, dir, type, opt) @@ -244,6 +267,25 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) init_subpel3(1, avg, ssse3); } + if (EXTERNAL_AVX(cpu_flags)) { + init_fpel(1, 0, 32, put, avx); + init_fpel(0, 0, 64, put, avx); + } + + if (EXTERNAL_AVX2(cpu_flags)) { + init_fpel(1, 1, 32, avg, avx2); + init_fpel(0, 1, 64, avg, avx2); + +#if ARCH_X86_64 && HAVE_AVX2_EXTERNAL + init_subpel2_32_64(0, 1, 1, hv, put, avx2); + init_subpel2_32_64(0, 0, 1, v, put, avx2); + init_subpel2_32_64(0, 1, 0, h, put, avx2); + init_subpel2_32_64(1, 1, 1, hv, avg, avx2); + init_subpel2_32_64(1, 0, 1, v, avg, avx2); + init_subpel2_32_64(1, 1, 0, h, avg, avx2); +#endif /* ARCH_X86_64 && HAVE_AVX2_EXTERNAL */ + } + #undef init_fpel #undef init_subpel1 #undef init_subpel2 diff --git a/libavcodec/x86/vp9mc.asm b/libavcodec/x86/vp9mc.asm index 41b22204c0238..4f66ea1c9204a 100644 --- a/libavcodec/x86/vp9mc.asm +++ b/libavcodec/x86/vp9mc.asm @@ -22,17 +22,17 @@ %include "libavutil/x86/x86util.asm" -SECTION_RODATA +SECTION_RODATA 32 cextern pw_256 %macro F8_TAPS 8 -times 8 db %1, %2 -times 8 db %3, %4 -times 8 db %5, %6 -times 8 db %7, %8 +times 16 db %1, %2 +times 16 db %3, %4 +times 16 db %5, %6 +times 16 db %7, %8 %endmacro -; int8_t ff_filters_ssse3[3][15][4][16] +; int8_t ff_filters_ssse3[3][15][4][32] const filters_ssse3 ; smooth F8_TAPS -3, -1, 32, 64, 38, 1, -3, 0 F8_TAPS -2, -2, 29, 63, 41, 2, -3, 0 @@ -90,9 +90,9 @@ cglobal vp9_%1_8tap_1d_h_ %+ %%px, 6, 6, 11, dst, src, dstride, sstride, h, filt mova m6, [pw_256] mova m7, [filteryq+ 0] %if ARCH_X86_64 && mmsize > 8 - mova m8, [filteryq+16] - mova m9, [filteryq+32] - mova m10, [filteryq+48] + mova m8, [filteryq+32] + mova m9, [filteryq+64] + mova m10, [filteryq+96] %endif .loop: movh m0, [srcq-3] @@ -114,9 +114,9 @@ cglobal vp9_%1_8tap_1d_h_ %+ %%px, 6, 6, 11, dst, src, dstride, sstride, h, filt pmaddubsw m4, m9 pmaddubsw m1, m10 %else - pmaddubsw m2, [filteryq+16] - pmaddubsw m4, [filteryq+32] - pmaddubsw m1, [filteryq+48] + pmaddubsw m2, [filteryq+32] + pmaddubsw m4, [filteryq+64] + pmaddubsw m1, [filteryq+96] %endif paddw m0, m2 paddw m4, m1 @@ -150,9 +150,9 @@ filter_h_fn avg cglobal vp9_%1_8tap_1d_h_ %+ %%px, 6, 6, 14, dst, src, dstride, sstride, h, filtery mova m13, [pw_256] mova m8, [filteryq+ 0] - mova m9, [filteryq+16] - mova m10, [filteryq+32] - mova m11, [filteryq+48] + mova m9, [filteryq+32] + mova m10, [filteryq+64] + mova m11, [filteryq+96] .loop: movu m0, [srcq-3] movu m1, [srcq-2] @@ -198,6 +198,12 @@ INIT_XMM ssse3 filter_hx2_fn put filter_hx2_fn avg +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +filter_hx2_fn put +filter_hx2_fn avg +%endif + %endif ; ARCH_X86_64 %macro filter_v_fn 1 @@ -215,9 +221,9 @@ cglobal vp9_%1_8tap_1d_v_ %+ %%px, 4, 7, 11, dst, src, dstride, sstride, filtery sub srcq, sstride3q mova m7, [filteryq+ 0] %if ARCH_X86_64 && mmsize > 8 - mova m8, [filteryq+16] - mova m9, [filteryq+32] - mova m10, [filteryq+48] + mova m8, [filteryq+32] + mova m9, [filteryq+64] + mova m10, [filteryq+96] %endif .loop: ; FIXME maybe reuse loads from previous rows, or just more generally @@ -242,9 +248,9 @@ cglobal vp9_%1_8tap_1d_v_ %+ %%px, 4, 7, 11, dst, src, dstride, sstride, filtery pmaddubsw m4, m9 pmaddubsw m1, m10 %else - pmaddubsw m2, [filteryq+16] - pmaddubsw m4, [filteryq+32] - pmaddubsw m1, [filteryq+48] + pmaddubsw m2, [filteryq+32] + pmaddubsw m4, [filteryq+64] + pmaddubsw m1, [filteryq+96] %endif paddw m0, m2 paddw m4, m1 @@ -282,9 +288,9 @@ cglobal vp9_%1_8tap_1d_v_ %+ %%px, 6, 8, 14, dst, src, dstride, sstride, h, filt lea src4q, [srcq+sstrideq] sub srcq, sstride3q mova m8, [filteryq+ 0] - mova m9, [filteryq+16] - mova m10, [filteryq+32] - mova m11, [filteryq+48] + mova m9, [filteryq+32] + mova m10, [filteryq+64] + mova m11, [filteryq+96] .loop: ; FIXME maybe reuse loads from previous rows, or just ; more generally unroll this to prevent multiple loads of @@ -334,6 +340,12 @@ INIT_XMM ssse3 filter_vx2_fn put filter_vx2_fn avg +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +filter_vx2_fn put +filter_vx2_fn avg +%endif + %endif ; ARCH_X86_64 %macro fpel_fn 6 @@ -345,7 +357,7 @@ filter_vx2_fn avg %define %%dstfn mova %endif -%if %2 <= 16 +%if %2 <= mmsize cglobal vp9_%1%2, 5, 7, 4, dst, src, dstride, sstride, h, dstride3, sstride3 lea sstride3q, [sstrideq*3] lea dstride3q, [dstrideq*3] @@ -376,6 +388,8 @@ cglobal vp9_%1%2, 5, 5, 4, dst, src, dstride, sstride, h %define d16 16 %define s16 16 +%define d32 32 +%define s32 32 INIT_MMX mmx fpel_fn put, 4, strideq, strideq*2, stride3q, 4 fpel_fn put, 8, strideq, strideq*2, stride3q, 4 @@ -390,5 +404,15 @@ INIT_XMM sse2 fpel_fn avg, 16, strideq, strideq*2, stride3q, 4 fpel_fn avg, 32, mmsize, strideq, strideq+mmsize, 2 fpel_fn avg, 64, mmsize, mmsize*2, mmsize*3, 1 +INIT_YMM avx +fpel_fn put, 32, strideq, strideq*2, stride3q, 4 +fpel_fn put, 64, mmsize, strideq, strideq+mmsize, 2 +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +fpel_fn avg, 32, strideq, strideq*2, stride3q, 4 +fpel_fn avg, 64, mmsize, strideq, strideq+mmsize, 2 +%endif %undef s16 %undef d16 +%undef s32 +%undef d32 From 9790b44a89d191a07a9d8b361fb4d18ea15f51a1 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sun, 14 Dec 2014 20:13:24 -0500 Subject: [PATCH 0052/3374] vp9mc/x86: sse2 MC assembly. Also a slight change to the ssse3 code, which prevents a theoretical overflow in the sharp filter. Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9dsp_init.c | 184 ++++++++++++++------------ libavcodec/x86/vp9mc.asm | 246 ++++++++++++++++++++++++++++++++--- 2 files changed, 324 insertions(+), 106 deletions(-) diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c index 8c4af8368c395..41fa35a4c3014 100644 --- a/libavcodec/x86/vp9dsp_init.c +++ b/libavcodec/x86/vp9dsp_init.c @@ -51,39 +51,41 @@ fpel_func(avg, 32, avx2); fpel_func(avg, 64, avx2); #undef fpel_func -#define mc_func(avg, sz, dir, opt) \ +#define mc_func(avg, sz, dir, opt, type, f_sz) \ void \ ff_vp9_ ## avg ## _8tap_1d_ ## dir ## _ ## sz ## _ ## opt(uint8_t *dst, \ const uint8_t *src, \ ptrdiff_t dst_stride, \ ptrdiff_t src_stride, \ int h, \ - const int8_t (*filter)[32]) - -#define mc_funcs(sz, opt) \ - mc_func(put, sz, h, opt); \ - mc_func(avg, sz, h, opt); \ - mc_func(put, sz, v, opt); \ - mc_func(avg, sz, v, opt) - -mc_funcs(4, ssse3); -mc_funcs(8, ssse3); + const type (*filter)[f_sz]) + +#define mc_funcs(sz, opt, type, f_sz) \ + mc_func(put, sz, h, opt, type, f_sz); \ + mc_func(avg, sz, h, opt, type, f_sz); \ + mc_func(put, sz, v, opt, type, f_sz); \ + mc_func(avg, sz, v, opt, type, f_sz) + +mc_funcs(4, mmxext, int16_t, 8); +mc_funcs(8, sse2, int16_t, 8); +mc_funcs(4, ssse3, int8_t, 32); +mc_funcs(8, ssse3, int8_t, 32); #if ARCH_X86_64 -mc_funcs(16, ssse3); -mc_funcs(32, avx2); +mc_funcs(16, ssse3, int8_t, 32); +mc_funcs(32, avx2, int8_t, 32); #endif #undef mc_funcs #undef mc_func -#define mc_rep_func(avg, sz, hsz, dir, opt) \ +#define mc_rep_func(avg, sz, hsz, dir, opt, type, f_sz) \ static av_always_inline void \ ff_vp9_ ## avg ## _8tap_1d_ ## dir ## _ ## sz ## _ ## opt(uint8_t *dst, \ const uint8_t *src, \ ptrdiff_t dst_stride, \ ptrdiff_t src_stride, \ int h, \ - const int8_t (*filter)[32]) \ + const type (*filter)[f_sz]) \ { \ ff_vp9_ ## avg ## _8tap_1d_ ## dir ## _ ## hsz ## _ ## opt(dst, src, \ dst_stride, \ @@ -97,27 +99,31 @@ ff_vp9_ ## avg ## _8tap_1d_ ## dir ## _ ## sz ## _ ## opt(uint8_t *dst, \ h, filter); \ } -#define mc_rep_funcs(sz, hsz, opt) \ - mc_rep_func(put, sz, hsz, h, opt); \ - mc_rep_func(avg, sz, hsz, h, opt); \ - mc_rep_func(put, sz, hsz, v, opt); \ - mc_rep_func(avg, sz, hsz, v, opt) +#define mc_rep_funcs(sz, hsz, opt, type, f_sz) \ + mc_rep_func(put, sz, hsz, h, opt, type, f_sz); \ + mc_rep_func(avg, sz, hsz, h, opt, type, f_sz); \ + mc_rep_func(put, sz, hsz, v, opt, type, f_sz); \ + mc_rep_func(avg, sz, hsz, v, opt, type, f_sz) +mc_rep_funcs(16, 8, sse2, int16_t, 8); #if ARCH_X86_32 -mc_rep_funcs(16, 8, ssse3); +mc_rep_funcs(16, 8, ssse3, int8_t, 32); #endif -mc_rep_funcs(32, 16, ssse3); -mc_rep_funcs(64, 32, ssse3); +mc_rep_funcs(32, 16, sse2, int16_t, 8); +mc_rep_funcs(32, 16, ssse3, int8_t, 32); +mc_rep_funcs(64, 32, sse2, int16_t, 8); +mc_rep_funcs(64, 32, ssse3, int8_t, 32); #if ARCH_X86_64 && HAVE_AVX2_EXTERNAL -mc_rep_funcs(64, 32, avx2); +mc_rep_funcs(64, 32, avx2, int8_t, 32); #endif #undef mc_rep_funcs #undef mc_rep_func extern const int8_t ff_filters_ssse3[3][15][4][32]; +extern const int16_t ff_filters_sse2[3][15][8][8]; -#define filter_8tap_2d_fn(op, sz, f, fname, align, opt) \ +#define filter_8tap_2d_fn(op, sz, f, f_opt, fname, align, opt) \ static void \ op ## _8tap_ ## fname ## _ ## sz ## hv_ ## opt(uint8_t *dst, \ const uint8_t *src, \ @@ -129,39 +135,42 @@ op ## _8tap_ ## fname ## _ ## sz ## hv_ ## opt(uint8_t *dst, ff_vp9_put_8tap_1d_h_ ## sz ## _ ## opt(temp, src - 3 * src_stride, \ 64, src_stride, \ h + 7, \ - ff_filters_ssse3[f][mx - 1]); \ + ff_filters_ ## f_opt[f][mx - 1]); \ ff_vp9_ ## op ## _8tap_1d_v_ ## sz ## _ ## opt(dst, temp + 3 * 64, \ dst_stride, 64, \ h, \ - ff_filters_ssse3[f][my - 1]); \ + ff_filters_ ## f_opt[f][my - 1]); \ } -#define filters_8tap_2d_fn(op, sz, align, opt) \ - filter_8tap_2d_fn(op, sz, FILTER_8TAP_REGULAR, regular, align, opt) \ - filter_8tap_2d_fn(op, sz, FILTER_8TAP_SHARP, sharp, align, opt) \ - filter_8tap_2d_fn(op, sz, FILTER_8TAP_SMOOTH, smooth, align, opt) +#define filters_8tap_2d_fn(op, sz, align, opt, f_opt) \ + filter_8tap_2d_fn(op, sz, FILTER_8TAP_REGULAR, f_opt, regular, align, opt) \ + filter_8tap_2d_fn(op, sz, FILTER_8TAP_SHARP, f_opt, sharp, align, opt) \ + filter_8tap_2d_fn(op, sz, FILTER_8TAP_SMOOTH, f_opt, smooth, align, opt) -#define filters_8tap_2d_fn2(op, align, opt) \ - filters_8tap_2d_fn(op, 64, align, opt) \ - filters_8tap_2d_fn(op, 32, align, opt) \ - filters_8tap_2d_fn(op, 16, align, opt) \ - filters_8tap_2d_fn(op, 8, align, opt) \ - filters_8tap_2d_fn(op, 4, align, opt) +#define filters_8tap_2d_fn2(op, align, opt4, opt8, f_opt) \ + filters_8tap_2d_fn(op, 64, align, opt8, f_opt) \ + filters_8tap_2d_fn(op, 32, align, opt8, f_opt) \ + filters_8tap_2d_fn(op, 16, align, opt8, f_opt) \ + filters_8tap_2d_fn(op, 8, align, opt8, f_opt) \ + filters_8tap_2d_fn(op, 4, align, opt4, f_opt) -filters_8tap_2d_fn2(put, 16, ssse3) -filters_8tap_2d_fn2(avg, 16, ssse3) + +filters_8tap_2d_fn2(put, 16, mmxext, sse2, sse2) +filters_8tap_2d_fn2(avg, 16, mmxext, sse2, sse2) +filters_8tap_2d_fn2(put, 16, ssse3, ssse3, ssse3) +filters_8tap_2d_fn2(avg, 16, ssse3, ssse3, ssse3) #if ARCH_X86_64 && HAVE_AVX2_EXTERNAL -filters_8tap_2d_fn(put, 64, 32, avx2) -filters_8tap_2d_fn(put, 32, 32, avx2) -filters_8tap_2d_fn(avg, 64, 32, avx2) -filters_8tap_2d_fn(avg, 32, 32, avx2) +filters_8tap_2d_fn(put, 64, 32, avx2, ssse3) +filters_8tap_2d_fn(put, 32, 32, avx2, ssse3) +filters_8tap_2d_fn(avg, 64, 32, avx2, ssse3) +filters_8tap_2d_fn(avg, 32, 32, avx2, ssse3) #endif #undef filters_8tap_2d_fn2 #undef filters_8tap_2d_fn #undef filter_8tap_2d_fn -#define filter_8tap_1d_fn(op, sz, f, fname, dir, dvar, opt) \ +#define filter_8tap_1d_fn(op, sz, f, f_opt, fname, dir, dvar, opt) \ static void \ op ## _8tap_ ## fname ## _ ## sz ## dir ## _ ## opt(uint8_t *dst, \ const uint8_t *src, \ @@ -173,32 +182,34 @@ op ## _8tap_ ## fname ## _ ## sz ## dir ## _ ## opt(uint8_t *dst, \ ff_vp9_ ## op ## _8tap_1d_ ## dir ## _ ## sz ## _ ## opt(dst, src, \ dst_stride, \ src_stride, h,\ - ff_filters_ssse3[f][dvar - 1]); \ + ff_filters_ ## f_opt[f][dvar - 1]); \ } -#define filters_8tap_1d_fn(op, sz, dir, dvar, opt) \ - filter_8tap_1d_fn(op, sz, FILTER_8TAP_REGULAR, regular, dir, dvar, opt) \ - filter_8tap_1d_fn(op, sz, FILTER_8TAP_SHARP, sharp, dir, dvar, opt) \ - filter_8tap_1d_fn(op, sz, FILTER_8TAP_SMOOTH, smooth, dir, dvar, opt) - -#define filters_8tap_1d_fn2(op, sz, opt) \ - filters_8tap_1d_fn(op, sz, h, mx, opt) \ - filters_8tap_1d_fn(op, sz, v, my, opt) - -#define filters_8tap_1d_fn3(op, opt) \ - filters_8tap_1d_fn2(op, 64, opt) \ - filters_8tap_1d_fn2(op, 32, opt) \ - filters_8tap_1d_fn2(op, 16, opt) \ - filters_8tap_1d_fn2(op, 8, opt) \ - filters_8tap_1d_fn2(op, 4, opt) - -filters_8tap_1d_fn3(put, ssse3) -filters_8tap_1d_fn3(avg, ssse3) +#define filters_8tap_1d_fn(op, sz, dir, dvar, opt, f_opt) \ + filter_8tap_1d_fn(op, sz, FILTER_8TAP_REGULAR, f_opt, regular, dir, dvar, opt) \ + filter_8tap_1d_fn(op, sz, FILTER_8TAP_SHARP, f_opt, sharp, dir, dvar, opt) \ + filter_8tap_1d_fn(op, sz, FILTER_8TAP_SMOOTH, f_opt, smooth, dir, dvar, opt) + +#define filters_8tap_1d_fn2(op, sz, opt, f_opt) \ + filters_8tap_1d_fn(op, sz, h, mx, opt, f_opt) \ + filters_8tap_1d_fn(op, sz, v, my, opt, f_opt) + +#define filters_8tap_1d_fn3(op, opt4, opt8, f_opt) \ + filters_8tap_1d_fn2(op, 64, opt8, f_opt) \ + filters_8tap_1d_fn2(op, 32, opt8, f_opt) \ + filters_8tap_1d_fn2(op, 16, opt8, f_opt) \ + filters_8tap_1d_fn2(op, 8, opt8, f_opt) \ + filters_8tap_1d_fn2(op, 4, opt4, f_opt) + +filters_8tap_1d_fn3(put, mmxext, sse2, sse2) +filters_8tap_1d_fn3(avg, mmxext, sse2, sse2) +filters_8tap_1d_fn3(put, ssse3, ssse3, ssse3) +filters_8tap_1d_fn3(avg, ssse3, ssse3, ssse3) #if ARCH_X86_64 && HAVE_AVX2_EXTERNAL -filters_8tap_1d_fn2(put, 64, avx2) -filters_8tap_1d_fn2(put, 32, avx2) -filters_8tap_1d_fn2(avg, 64, avx2) -filters_8tap_1d_fn2(avg, 32, avx2) +filters_8tap_1d_fn2(put, 64, avx2, ssse3) +filters_8tap_1d_fn2(put, 32, avx2, ssse3) +filters_8tap_1d_fn2(avg, 64, avx2, ssse3) +filters_8tap_1d_fn2(avg, 32, avx2, ssse3) #endif #undef filters_8tap_1d_fn @@ -225,20 +236,23 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][idxh][idxv] = type ## _8tap_regular_ ## sz ## dir ## _ ## opt; \ dsp->mc[idx1][FILTER_8TAP_SHARP][idx2][idxh][idxv] = type ## _8tap_sharp_ ## sz ## dir ## _ ## opt -#define init_subpel2_32_64(idx, idxh, idxv, dir, type, opt) \ - init_subpel1(0, idx, idxh, idxv, 64, dir, type, opt); \ - init_subpel1(1, idx, idxh, idxv, 32, dir, type, opt) +#define init_subpel2(idx1, idx2, sz, type, opt) \ + init_subpel1(idx1, idx2, 1, 1, sz, hv, type, opt); \ + init_subpel1(idx1, idx2, 0, 1, sz, v, type, opt); \ + init_subpel1(idx1, idx2, 1, 0, sz, h, type, opt) + +#define init_subpel3_32_64(idx, type, opt) \ + init_subpel2(0, idx, 64, type, opt); \ + init_subpel2(1, idx, 32, type, opt) -#define init_subpel2(idx, idxh, idxv, dir, type, opt) \ - init_subpel2_32_64(idx, idxh, idxv, dir, type, opt); \ - init_subpel1(2, idx, idxh, idxv, 16, dir, type, opt); \ - init_subpel1(3, idx, idxh, idxv, 8, dir, type, opt); \ - init_subpel1(4, idx, idxh, idxv, 4, dir, type, opt) +#define init_subpel3_8to64(idx, type, opt) \ + init_subpel3_32_64(idx, type, opt); \ + init_subpel2(2, idx, 16, type, opt); \ + init_subpel2(3, idx, 8, type, opt) -#define init_subpel3(idx, type, opt) \ - init_subpel2(idx, 1, 1, hv, type, opt); \ - init_subpel2(idx, 0, 1, v, type, opt); \ - init_subpel2(idx, 1, 0, h, type, opt) +#define init_subpel3(idx, type, opt) \ + init_subpel3_8to64(idx, type, opt); \ + init_subpel2(4, idx, 4, type, opt) if (EXTERNAL_MMX(cpu_flags)) { init_fpel(4, 0, 4, put, mmx); @@ -246,6 +260,8 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) } if (EXTERNAL_MMXEXT(cpu_flags)) { + init_subpel2(4, 0, 4, put, mmxext); + init_subpel2(4, 1, 4, avg, mmxext); init_fpel(4, 1, 4, avg, mmxext); init_fpel(3, 1, 8, avg, mmxext); } @@ -257,6 +273,8 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) } if (EXTERNAL_SSE2(cpu_flags)) { + init_subpel3_8to64(0, put, sse2); + init_subpel3_8to64(1, avg, sse2); init_fpel(2, 1, 16, avg, sse2); init_fpel(1, 1, 32, avg, sse2); init_fpel(0, 1, 64, avg, sse2); @@ -277,12 +295,8 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) init_fpel(0, 1, 64, avg, avx2); #if ARCH_X86_64 && HAVE_AVX2_EXTERNAL - init_subpel2_32_64(0, 1, 1, hv, put, avx2); - init_subpel2_32_64(0, 0, 1, v, put, avx2); - init_subpel2_32_64(0, 1, 0, h, put, avx2); - init_subpel2_32_64(1, 1, 1, hv, avg, avx2); - init_subpel2_32_64(1, 0, 1, v, avg, avx2); - init_subpel2_32_64(1, 1, 0, h, avg, avx2); + init_subpel3_32_64(0, put, avx2); + init_subpel3_32_64(1, avg, avx2); #endif /* ARCH_X86_64 && HAVE_AVX2_EXTERNAL */ } diff --git a/libavcodec/x86/vp9mc.asm b/libavcodec/x86/vp9mc.asm index 4f66ea1c9204a..15e93ea6cb0bc 100644 --- a/libavcodec/x86/vp9mc.asm +++ b/libavcodec/x86/vp9mc.asm @@ -25,15 +25,28 @@ SECTION_RODATA 32 cextern pw_256 +cextern pw_64 -%macro F8_TAPS 8 +%macro F8_SSSE3_TAPS 8 times 16 db %1, %2 times 16 db %3, %4 times 16 db %5, %6 times 16 db %7, %8 %endmacro -; int8_t ff_filters_ssse3[3][15][4][32] -const filters_ssse3 ; smooth + +%macro F8_SSE2_TAPS 8 +times 8 dw %1 +times 8 dw %2 +times 8 dw %3 +times 8 dw %4 +times 8 dw %5 +times 8 dw %6 +times 8 dw %7 +times 8 dw %8 +%endmacro + +%macro FILTER 1 +const filters_%1 ; smooth F8_TAPS -3, -1, 32, 64, 38, 1, -3, 0 F8_TAPS -2, -2, 29, 63, 41, 2, -3, 0 F8_TAPS -2, -2, 26, 63, 43, 4, -4, 0 @@ -81,9 +94,102 @@ const filters_ssse3 ; smooth F8_TAPS -2, 5, -10, 27, 121, -17, 7, -3 F8_TAPS -1, 3, -6, 17, 125, -13, 5, -2 F8_TAPS 0, 1, -3, 8, 127, -7, 3, -1 +%endmacro + +%define F8_TAPS F8_SSSE3_TAPS +; int8_t ff_filters_ssse3[3][15][4][32] +FILTER ssse3 +%define F8_TAPS F8_SSE2_TAPS +; int16_t ff_filters_sse2[3][15][8][8] +FILTER sse2 SECTION .text +%macro filter_sse2_h_fn 1 +%assign %%px mmsize/2 +cglobal vp9_%1_8tap_1d_h_ %+ %%px, 6, 6, 15, dst, src, dstride, sstride, h, filtery + pxor m5, m5 + mova m6, [pw_64] + mova m7, [filteryq+ 0] +%if ARCH_X86_64 && mmsize > 8 + mova m8, [filteryq+ 16] + mova m9, [filteryq+ 32] + mova m10, [filteryq+ 48] + mova m11, [filteryq+ 64] + mova m12, [filteryq+ 80] + mova m13, [filteryq+ 96] + mova m14, [filteryq+112] +%endif +.loop: + movh m0, [srcq-3] + movh m1, [srcq-2] + movh m2, [srcq-1] + movh m3, [srcq+0] + movh m4, [srcq+1] + punpcklbw m0, m5 + punpcklbw m1, m5 + punpcklbw m2, m5 + punpcklbw m3, m5 + punpcklbw m4, m5 + pmullw m0, m7 +%if ARCH_X86_64 && mmsize > 8 + pmullw m1, m8 + pmullw m2, m9 + pmullw m3, m10 + pmullw m4, m11 +%else + pmullw m1, [filteryq+ 16] + pmullw m2, [filteryq+ 32] + pmullw m3, [filteryq+ 48] + pmullw m4, [filteryq+ 64] +%endif + paddw m0, m1 + paddw m2, m3 + paddw m0, m4 + movh m1, [srcq+2] + movh m3, [srcq+3] + movh m4, [srcq+4] + add srcq, sstrideq + punpcklbw m1, m5 + punpcklbw m3, m5 + punpcklbw m4, m5 +%if ARCH_X86_64 && mmsize > 8 + pmullw m1, m12 + pmullw m3, m13 + pmullw m4, m14 +%else + pmullw m1, [filteryq+ 80] + pmullw m3, [filteryq+ 96] + pmullw m4, [filteryq+112] +%endif + paddw m0, m1 + paddw m3, m4 + paddw m0, m6 + paddw m2, m3 + paddsw m0, m2 + psraw m0, 7 +%ifidn %1, avg + movh m1, [dstq] +%endif + packuswb m0, m0 +%ifidn %1, avg + pavgb m0, m1 +%endif + movh [dstq], m0 + add dstq, dstrideq + dec hd + jg .loop + RET +%endmacro + +INIT_MMX mmxext +filter_sse2_h_fn put +filter_sse2_h_fn avg + +INIT_XMM sse2 +filter_sse2_h_fn put +filter_sse2_h_fn avg + %macro filter_h_fn 1 %assign %%px mmsize/2 cglobal vp9_%1_8tap_1d_h_ %+ %%px, 6, 6, 11, dst, src, dstride, sstride, h, filtery @@ -118,9 +224,9 @@ cglobal vp9_%1_8tap_1d_h_ %+ %%px, 6, 6, 11, dst, src, dstride, sstride, h, filt pmaddubsw m4, [filteryq+64] pmaddubsw m1, [filteryq+96] %endif - paddw m0, m2 - paddw m4, m1 - paddsw m0, m4 + paddw m0, m4 + paddw m2, m1 + paddsw m0, m2 pmulhrsw m0, m6 %ifidn %1, avg movh m1, [dstq] @@ -175,12 +281,12 @@ cglobal vp9_%1_8tap_1d_h_ %+ %%px, 6, 6, 14, dst, src, dstride, sstride, h, filt pmaddubsw m5, m10 pmaddubsw m6, m11 pmaddubsw m7, m11 - paddw m0, m2 - paddw m1, m3 - paddw m4, m6 - paddw m5, m7 - paddsw m0, m4 - paddsw m1, m5 + paddw m0, m4 + paddw m1, m5 + paddw m2, m6 + paddw m3, m7 + paddsw m0, m2 + paddsw m1, m3 pmulhrsw m0, m13 pmulhrsw m1, m13 packuswb m0, m1 @@ -206,6 +312,104 @@ filter_hx2_fn avg %endif ; ARCH_X86_64 +%macro filter_sse2_v_fn 1 +%assign %%px mmsize/2 +%if ARCH_X86_64 +cglobal vp9_%1_8tap_1d_v_ %+ %%px, 6, 8, 15, dst, src, dstride, sstride, h, filtery, src4, sstride3 +%else +cglobal vp9_%1_8tap_1d_v_ %+ %%px, 4, 7, 15, dst, src, dstride, sstride, filtery, src4, sstride3 + mov filteryq, r5mp +%define hd r4mp +%endif + pxor m5, m5 + mova m6, [pw_64] + lea sstride3q, [sstrideq*3] + lea src4q, [srcq+sstrideq] + sub srcq, sstride3q + mova m7, [filteryq+ 0] +%if ARCH_X86_64 && mmsize > 8 + mova m8, [filteryq+ 16] + mova m9, [filteryq+ 32] + mova m10, [filteryq+ 48] + mova m11, [filteryq+ 64] + mova m12, [filteryq+ 80] + mova m13, [filteryq+ 96] + mova m14, [filteryq+112] +%endif +.loop: + ; FIXME maybe reuse loads from previous rows, or just + ; more generally unroll this to prevent multiple loads of + ; the same data? + movh m0, [srcq] + movh m1, [srcq+sstrideq] + movh m2, [srcq+sstrideq*2] + movh m3, [srcq+sstride3q] + add srcq, sstrideq + movh m4, [src4q] + punpcklbw m0, m5 + punpcklbw m1, m5 + punpcklbw m2, m5 + punpcklbw m3, m5 + punpcklbw m4, m5 + pmullw m0, m7 +%if ARCH_X86_64 && mmsize > 8 + pmullw m1, m8 + pmullw m2, m9 + pmullw m3, m10 + pmullw m4, m11 +%else + pmullw m1, [filteryq+ 16] + pmullw m2, [filteryq+ 32] + pmullw m3, [filteryq+ 48] + pmullw m4, [filteryq+ 64] +%endif + paddw m0, m1 + paddw m2, m3 + paddw m0, m4 + movh m1, [src4q+sstrideq] + movh m3, [src4q+sstrideq*2] + movh m4, [src4q+sstride3q] + add src4q, sstrideq + punpcklbw m1, m5 + punpcklbw m3, m5 + punpcklbw m4, m5 +%if ARCH_X86_64 && mmsize > 8 + pmullw m1, m12 + pmullw m3, m13 + pmullw m4, m14 +%else + pmullw m1, [filteryq+ 80] + pmullw m3, [filteryq+ 96] + pmullw m4, [filteryq+112] +%endif + paddw m0, m1 + paddw m3, m4 + paddw m0, m6 + paddw m2, m3 + paddsw m0, m2 + psraw m0, 7 +%ifidn %1, avg + movh m1, [dstq] +%endif + packuswb m0, m0 +%ifidn %1, avg + pavgb m0, m1 +%endif + movh [dstq], m0 + add dstq, dstrideq + dec hd + jg .loop + RET +%endmacro + +INIT_MMX mmxext +filter_sse2_v_fn put +filter_sse2_v_fn avg + +INIT_XMM sse2 +filter_sse2_v_fn put +filter_sse2_v_fn avg + %macro filter_v_fn 1 %assign %%px mmsize/2 %if ARCH_X86_64 @@ -252,9 +456,9 @@ cglobal vp9_%1_8tap_1d_v_ %+ %%px, 4, 7, 11, dst, src, dstride, sstride, filtery pmaddubsw m4, [filteryq+64] pmaddubsw m1, [filteryq+96] %endif - paddw m0, m2 - paddw m4, m1 - paddsw m0, m4 + paddw m0, m4 + paddw m2, m1 + paddsw m0, m2 pmulhrsw m0, m6 %ifidn %1, avg movh m1, [dstq] @@ -317,12 +521,12 @@ cglobal vp9_%1_8tap_1d_v_ %+ %%px, 6, 8, 14, dst, src, dstride, sstride, h, filt pmaddubsw m5, m10 pmaddubsw m6, m11 pmaddubsw m7, m11 - paddw m0, m2 - paddw m1, m3 - paddw m4, m6 - paddw m5, m7 - paddsw m0, m4 - paddsw m1, m5 + paddw m0, m4 + paddw m1, m5 + paddw m2, m6 + paddw m3, m7 + paddsw m0, m2 + paddsw m1, m3 pmulhrsw m0, m13 pmulhrsw m1, m13 packuswb m0, m1 From e99ecda55082cb9dde8fd349361e169dc383943a Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 15 Sep 2015 16:41:29 -0400 Subject: [PATCH 0053/3374] checkasm: add vp9 MC tests. Signed-off-by: Anton Khirnov --- tests/checkasm/Makefile | 1 + tests/checkasm/checkasm.c | 3 + tests/checkasm/checkasm.h | 1 + tests/checkasm/vp9dsp.c | 127 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 132 insertions(+) create mode 100644 tests/checkasm/vp9dsp.c diff --git a/tests/checkasm/Makefile b/tests/checkasm/Makefile index d339b755a19ee..8d3d03aa8c3b1 100644 --- a/tests/checkasm/Makefile +++ b/tests/checkasm/Makefile @@ -11,6 +11,7 @@ AVCODECOBJS-$(CONFIG_VP8DSP) += vp8dsp.o AVCODECOBJS-$(CONFIG_DCA_DECODER) += dcadsp.o synth_filter.o AVCODECOBJS-$(CONFIG_HEVC_DECODER) += hevc_mc.o hevc_idct.o AVCODECOBJS-$(CONFIG_V210_ENCODER) += v210enc.o +AVCODECOBJS-$(CONFIG_VP9_DECODER) += vp9dsp.o CHECKASMOBJS-$(CONFIG_AVCODEC) += $(AVCODECOBJS-yes) diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c index 34f49c0b3711c..86d3bab30aaad 100644 --- a/tests/checkasm/checkasm.c +++ b/tests/checkasm/checkasm.c @@ -92,6 +92,9 @@ static const struct { #endif #if CONFIG_VP8DSP { "vp8dsp", checkasm_check_vp8dsp }, +#endif +#if CONFIG_VP9_DECODER + { "vp9dsp", checkasm_check_vp9dsp }, #endif { NULL } }; diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h index 73109c3afa2ca..5e67b7d75a8df 100644 --- a/tests/checkasm/checkasm.h +++ b/tests/checkasm/checkasm.h @@ -42,6 +42,7 @@ void checkasm_check_hevc_mc(void); void checkasm_check_synth_filter(void); void checkasm_check_v210enc(void); void checkasm_check_vp8dsp(void); +void checkasm_check_vp9dsp(void); void *checkasm_check_func(void *func, const char *name, ...) av_printf_format(2, 3); int checkasm_bench_func(void); diff --git a/tests/checkasm/vp9dsp.c b/tests/checkasm/vp9dsp.c new file mode 100644 index 0000000000000..dd37077adf6f5 --- /dev/null +++ b/tests/checkasm/vp9dsp.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2015 Ronald S. Bultje + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with Libav; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include + +#include "libavutil/common.h" +#include "libavutil/internal.h" +#include "libavutil/intreadwrite.h" + +#include "libavcodec/vp9.h" + +#include "checkasm.h" + +static const uint32_t pixel_mask[3] = { 0xffffffff, 0x03ff03ff, 0x0fff0fff }; + +#define BIT_DEPTH 8 +#define SIZEOF_PIXEL ((BIT_DEPTH + 7) / 8) +#define DST_BUF_SIZE (size * size * SIZEOF_PIXEL) +#define SRC_BUF_STRIDE 72 +#define SRC_BUF_SIZE ((size + 7) * SRC_BUF_STRIDE * SIZEOF_PIXEL) +#define src (buf + 3 * SIZEOF_PIXEL * (SRC_BUF_STRIDE + 1)) + +#define randomize_buffers() \ + do { \ + uint32_t mask = pixel_mask[(BIT_DEPTH - 8) >> 1]; \ + int k; \ + for (k = 0; k < SRC_BUF_SIZE; k += 4) { \ + uint32_t r = rnd() & mask; \ + AV_WN32A(buf + k, r); \ + } \ + if (op == 1) { \ + for (k = 0; k < DST_BUF_SIZE; k += 4) { \ + uint32_t r = rnd() & mask; \ + AV_WN32A(dst0 + k, r); \ + AV_WN32A(dst1 + k, r); \ + } \ + } \ + } while (0) + +static void check_mc(void) +{ + static const char *const filter_names[4] = { + "8tap_smooth", "8tap_regular", "8tap_sharp", "bilin" + }; + static const char *const subpel_names[2][2] = { { "", "h" }, { "v", "hv" } }; + static const char *const op_names[2] = { "put", "avg" }; + + LOCAL_ALIGNED_32(uint8_t, buf, [72 * 72 * 2]); + LOCAL_ALIGNED_32(uint8_t, dst0, [64 * 64 * 2]); + LOCAL_ALIGNED_32(uint8_t, dst1, [64 * 64 * 2]); + char str[256]; + VP9DSPContext dsp; + int op, hsize, filter, dx, dy; + + declare_func_emms(AV_CPU_FLAG_MMX | AV_CPU_FLAG_MMXEXT, + void, uint8_t *dst, const uint8_t *ref, + ptrdiff_t dst_stride, ptrdiff_t ref_stride, + int h, int mx, int my); + + for (op = 0; op < 2; op++) { + ff_vp9dsp_init(&dsp); + for (hsize = 0; hsize < 5; hsize++) { + int size = 64 >> hsize; + + for (filter = 0; filter < 4; filter++) { + for (dx = 0; dx < 2; dx++) { + for (dy = 0; dy < 2; dy++) { + if (dx || dy) { + snprintf(str, sizeof(str), "%s_%s_%d%s", op_names[op], + filter_names[filter], size, + subpel_names[dy][dx]); + } else { + snprintf(str, sizeof(str), "%s%d", op_names[op], size); + } + if (check_func(dsp.mc[hsize][filter][op][dx][dy], + "vp9_%s", str)) { + int mx = dx ? 1 + (rnd() % 14) : 0; + int my = dy ? 1 + (rnd() % 14) : 0; + randomize_buffers(); + call_ref(dst0, src, + size * SIZEOF_PIXEL, + SRC_BUF_STRIDE * SIZEOF_PIXEL, + size, mx, my); + call_new(dst1, src, + size * SIZEOF_PIXEL, + SRC_BUF_STRIDE * SIZEOF_PIXEL, + size, mx, my); + if (memcmp(dst0, dst1, DST_BUF_SIZE)) + fail(); + + // SIMD implementations for each filter of subpel + // functions are identical + if (filter >= 1 && filter <= 2) continue; + + bench_new(dst1, src, size * SIZEOF_PIXEL, + SRC_BUF_STRIDE * SIZEOF_PIXEL, + size, mx, my); + } + } + } + } + } + } + report("mc"); +} + +void checkasm_check_vp9dsp(void) +{ + check_mc(); +} From 24a362569bff1d4161742fffaca80a4a4428be8a Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 2 Aug 2016 21:16:44 +0200 Subject: [PATCH 0054/3374] buffer: fix av_buffer_realloc() when the data is offset wrt buffer start In such a case behave as if the buffer was not reallocatable -- allocate a new one and copy the data (preserving just the part described by the reference passed to av_buffer_realloc). CC: libav-stable@libav.org Reported-By: wm4 --- libavutil/buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavutil/buffer.c b/libavutil/buffer.c index 6681002345949..49a1f2d39558c 100644 --- a/libavutil/buffer.c +++ b/libavutil/buffer.c @@ -170,7 +170,7 @@ int av_buffer_realloc(AVBufferRef **pbuf, int size) return 0; if (!(buf->buffer->flags & BUFFER_FLAG_REALLOCATABLE) || - !av_buffer_is_writable(buf)) { + !av_buffer_is_writable(buf) || buf->data != buf->buffer->data) { /* cannot realloc, allocate a new reallocable buffer and copy data */ AVBufferRef *new = NULL; From 0df4801105d84883071b0978cb3afc7cd5184ce8 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 7 Jan 2014 07:24:03 -0500 Subject: [PATCH 0055/3374] vp9: make mv bounds 32bit. The frame dimensions are 16bit, so the mv bounds can easily overflow int16 for large videos. Bug-Id: Handbrake/46 CC: libav-stable@libav.org Signed-off-by: Anton Khirnov --- libavcodec/vp9.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vp9.h b/libavcodec/vp9.h index b83bd618d4a4b..31509bfbc5753 100644 --- a/libavcodec/vp9.h +++ b/libavcodec/vp9.h @@ -402,7 +402,7 @@ typedef struct VP9Context { DECLARE_ALIGNED(32, int16_t, uvblock)[2][1024]; uint8_t eob[256]; uint8_t uveob[2][64]; - VP56mv min_mv, max_mv; + struct { int x, y; } min_mv, max_mv; DECLARE_ALIGNED(32, uint8_t, tmp_y)[64 * 64]; DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][32 * 32]; } VP9Context; From 0638b99cdba52554691fc668d9e477bc184c7a33 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 8 Aug 2016 21:06:03 +0200 Subject: [PATCH 0056/3374] aiff: Skip padding byte for odd-sized chunks Bug-Id: 660 --- libavformat/aiffdec.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libavformat/aiffdec.c b/libavformat/aiffdec.c index e56390937ea84..3c45c61b1a8c8 100644 --- a/libavformat/aiffdec.c +++ b/libavformat/aiffdec.c @@ -267,10 +267,14 @@ static int aiff_read_header(AVFormatContext *s) avio_read(pb, st->codecpar->extradata, size); break; default: /* Jump */ - if (size & 1) /* Always even aligned */ - size++; avio_skip(pb, size); } + + /* Skip required padding byte for odd-sized chunks. */ + if (size & 1) { + filesize--; + avio_skip(pb, 1); + } } got_sound: From ec021d48445a414325ad59a73f9cde3212b173e4 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 3 Aug 2016 09:51:06 +0200 Subject: [PATCH 0057/3374] buffer: fix av_buffer_pool_init2() documentation A non-existent av_buffer_pool_can_uninit() function is mentioned instead of av_buffer_pool_uninit(). Also, this function is to be called by the caller, not the pool itself. --- libavutil/buffer.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libavutil/buffer.h b/libavutil/buffer.h index 46779cae9b56b..58def6fbbb8a9 100644 --- a/libavutil/buffer.h +++ b/libavutil/buffer.h @@ -249,9 +249,10 @@ AVBufferPool *av_buffer_pool_init(int size, AVBufferRef* (*alloc)(int size)); * @param alloc a function that will be used to allocate new buffers when the * pool is empty. * @param pool_free a function that will be called immediately before the pool - * is freed. I.e. after av_buffer_pool_can_uninit() is called - * by the pool and all the frames are returned to the pool and - * freed. It is intended to uninitialize the user opaque data. + * is freed. I.e. after av_buffer_pool_uninit() is called + * by the caller and all the frames are returned to the pool + * and freed. It is intended to uninitialize the user opaque + * data. * @return newly created buffer pool on success, NULL on error. */ AVBufferPool *av_buffer_pool_init2(int size, void *opaque, From e9bfff1cc66c85b91b262c41e8aa5e8685606225 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 8 Aug 2016 13:32:54 +0200 Subject: [PATCH 0058/3374] lavc: free buffer_frame/pkt on avcodec_open2() failure Fixes memory leaks in some FATE tests. --- libavcodec/utils.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/utils.c b/libavcodec/utils.c index ce86bfa2a760d..837edbd4ed78d 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -1199,6 +1199,8 @@ FF_ENABLE_DEPRECATION_WARNINGS av_freep(&avctx->priv_data); if (avctx->internal) { av_frame_free(&avctx->internal->to_free); + av_frame_free(&avctx->internal->buffer_frame); + av_packet_free(&avctx->internal->buffer_pkt); av_freep(&avctx->internal->pool); } av_freep(&avctx->internal); From 04763c6f87690b31cfcd0d324cf36a451531dcd0 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 2 Aug 2016 10:43:39 +0200 Subject: [PATCH 0059/3374] h264_direct: use the reference mask from the actual reference Not from the underlying frame. Fixes races with frame threading in field-coded files, where decoding would wait for the wrong field (e.g. random failures in mixed-nal-coding). Bug-Id: 954 --- libavcodec/h264_direct.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c index 85a4760922c0b..7ec49b67f3e42 100644 --- a/libavcodec/h264_direct.c +++ b/libavcodec/h264_direct.c @@ -160,11 +160,11 @@ void ff_h264_direct_ref_list_init(const H264Context *const h, H264SliceContext * } } -static void await_reference_mb_row(const H264Context *const h, H264Picture *ref, +static void await_reference_mb_row(const H264Context *const h, H264Ref *ref, int mb_y) { int ref_field = ref->reference - 1; - int ref_field_picture = ref->field_picture; + int ref_field_picture = ref->parent->field_picture; int ref_height = 16 * h->mb_height >> ref_field_picture; if (!HAVE_THREADS || !(h->avctx->active_thread_type & FF_THREAD_FRAME)) @@ -173,7 +173,7 @@ static void await_reference_mb_row(const H264Context *const h, H264Picture *ref, /* FIXME: It can be safe to access mb stuff * even if pixels aren't deblocked yet. */ - ff_thread_await_progress(&ref->tf, + ff_thread_await_progress(&ref->parent->tf, FFMIN(16 * mb_y >> ref_field_picture, ref_height - 1), ref_field_picture && ref_field); @@ -197,7 +197,7 @@ static void pred_spatial_direct_motion(const H264Context *const h, H264SliceCont assert(sl->ref_list[1][0].reference & 3); - await_reference_mb_row(h, sl->ref_list[1][0].parent, + await_reference_mb_row(h, &sl->ref_list[1][0], sl->mb_y + !!IS_INTERLACED(*mb_type)); #define MB_TYPE_16x16_OR_INTRA (MB_TYPE_16x16 | MB_TYPE_INTRA4x4 | \ @@ -321,7 +321,7 @@ static void pred_spatial_direct_motion(const H264Context *const h, H264SliceCont } } - await_reference_mb_row(h, sl->ref_list[1][0].parent, mb_y); + await_reference_mb_row(h, &sl->ref_list[1][0], mb_y); l1mv0 = &sl->ref_list[1][0].parent->motion_val[0][h->mb2b_xy[mb_xy]]; l1mv1 = &sl->ref_list[1][0].parent->motion_val[1][h->mb2b_xy[mb_xy]]; @@ -480,7 +480,7 @@ static void pred_temp_direct_motion(const H264Context *const h, H264SliceContext assert(sl->ref_list[1][0].reference & 3); - await_reference_mb_row(h, sl->ref_list[1][0].parent, + await_reference_mb_row(h, &sl->ref_list[1][0], sl->mb_y + !!IS_INTERLACED(*mb_type)); if (IS_INTERLACED(sl->ref_list[1][0].parent->mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL @@ -545,7 +545,7 @@ static void pred_temp_direct_motion(const H264Context *const h, H264SliceContext } } - await_reference_mb_row(h, sl->ref_list[1][0].parent, mb_y); + await_reference_mb_row(h, &sl->ref_list[1][0], mb_y); l1mv0 = &sl->ref_list[1][0].parent->motion_val[0][h->mb2b_xy[mb_xy]]; l1mv1 = &sl->ref_list[1][0].parent->motion_val[1][h->mb2b_xy[mb_xy]]; From bc6e0b64a9100652c1ce52292408d8fd79930d53 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sat, 23 Nov 2013 10:27:18 -0500 Subject: [PATCH 0060/3374] vp9: split last/cur_frame from the reference buffers. We need more information from last/cur_frame than from reference buffers, so we can use a simplified structure for reference buffers, and then store mvs and segmentation map information in last/cur. This prepares the decoder for frame threading support. Signed-off-by: Anton Khirnov --- libavcodec/vp9.c | 197 ++++++++++++++++++++++++++++++------------ libavcodec/vp9.h | 22 ++++- libavcodec/vp9block.c | 74 +++++++++------- libavcodec/vp9mvs.c | 12 +-- 4 files changed, 207 insertions(+), 98 deletions(-) diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index c11e9b86018cb..11ed00e3f9481 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -34,13 +34,77 @@ #define VP9_SYNCCODE 0x498342 #define MAX_PROB 255 +static void vp9_frame_unref(AVCodecContext *avctx, VP9Frame *f) +{ + ff_thread_release_buffer(avctx, &f->tf); + av_buffer_unref(&f->segmentation_map_buf); + av_buffer_unref(&f->mv_buf); + f->segmentation_map = NULL; + f->mv = NULL; +} + +static int vp9_frame_alloc(AVCodecContext *avctx, VP9Frame *f) +{ + VP9Context *s = avctx->priv_data; + int ret, sz; + + ret = ff_thread_get_buffer(avctx, &f->tf, AV_GET_BUFFER_FLAG_REF); + if (ret < 0) + return ret; + + sz = 64 * s->sb_cols * s->sb_rows; + f->segmentation_map_buf = av_buffer_allocz(sz * sizeof(*f->segmentation_map)); + f->mv_buf = av_buffer_allocz(sz * sizeof(*f->mv)); + if (!f->segmentation_map_buf || !f->mv_buf) { + vp9_frame_unref(avctx, f); + return AVERROR(ENOMEM); + } + + f->segmentation_map = f->segmentation_map_buf->data; + f->mv = (VP9MVRefPair*)f->mv_buf->data; + + if (s->segmentation.enabled && !s->segmentation.update_map && + !s->keyframe && !s->intraonly) + memcpy(f->segmentation_map, s->frames[LAST_FRAME].segmentation_map, sz); + + return 0; +} + +static int vp9_frame_ref(VP9Frame *dst, VP9Frame *src) +{ + int ret; + + dst->segmentation_map_buf = av_buffer_ref(src->segmentation_map_buf); + dst->mv_buf = av_buffer_ref(src->mv_buf); + if (!dst->segmentation_map_buf || !dst->mv_buf) { + ret = AVERROR(ENOMEM); + goto fail; + } + + ret = ff_thread_ref_frame(&dst->tf, &src->tf); + if (ret < 0) + goto fail; + + dst->segmentation_map = src->segmentation_map; + dst->mv = src->mv; + + return 0; +fail: + av_buffer_unref(&dst->segmentation_map_buf); + av_buffer_unref(&dst->mv_buf); + return ret; +} + static void vp9_decode_flush(AVCodecContext *avctx) { VP9Context *s = avctx->priv_data; int i; + for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) + vp9_frame_unref(avctx, &s->frames[i]); + for (i = 0; i < FF_ARRAY_ELEMS(s->refs); i++) - av_frame_unref(s->refs[i]); + ff_thread_release_buffer(avctx, &s->refs[i]); } static int update_size(AVCodecContext *avctx, int w, int h) @@ -66,8 +130,7 @@ static int update_size(AVCodecContext *avctx, int w, int h) #define assign(var, type, n) var = (type)p; p += s->sb_cols * n * sizeof(*var) av_free(s->above_partition_ctx); p = av_malloc(s->sb_cols * - (240 + sizeof(*s->lflvl) + 16 * sizeof(*s->above_mv_ctx) + - 64 * s->sb_rows * (1 + sizeof(*s->mv[0]) * 2))); + (240 + sizeof(*s->lflvl) + 16 * sizeof(*s->above_mv_ctx))); if (!p) return AVERROR(ENOMEM); assign(s->above_partition_ctx, uint8_t *, 8); @@ -87,9 +150,6 @@ static int update_size(AVCodecContext *avctx, int w, int h) assign(s->above_filter_ctx, uint8_t *, 8); assign(s->lflvl, VP9Filter *, 1); assign(s->above_mv_ctx, VP56mv(*)[2], 16); - assign(s->segmentation_map, uint8_t *, 64 * s->sb_rows); - assign(s->mv[0], VP9MVRefPair *, 64 * s->sb_rows); - assign(s->mv[1], VP9MVRefPair *, 64 * s->sb_rows); #undef assign return 0; @@ -268,22 +328,22 @@ static int decode_frame_header(AVCodecContext *avctx, s->signbias[1] = get_bits1(&s->gb); s->refidx[2] = get_bits(&s->gb, 3); s->signbias[2] = get_bits1(&s->gb); - if (!s->refs[s->refidx[0]]->buf[0] || - !s->refs[s->refidx[1]]->buf[0] || - !s->refs[s->refidx[2]]->buf[0]) { + if (!s->refs[s->refidx[0]].f->buf[0] || + !s->refs[s->refidx[1]].f->buf[0] || + !s->refs[s->refidx[2]].f->buf[0]) { av_log(avctx, AV_LOG_ERROR, "Not all references are available\n"); return AVERROR_INVALIDDATA; } if (get_bits1(&s->gb)) { - w = s->refs[s->refidx[0]]->width; - h = s->refs[s->refidx[0]]->height; + w = s->refs[s->refidx[0]].f->width; + h = s->refs[s->refidx[0]].f->height; } else if (get_bits1(&s->gb)) { - w = s->refs[s->refidx[1]]->width; - h = s->refs[s->refidx[1]]->height; + w = s->refs[s->refidx[1]].f->width; + h = s->refs[s->refidx[1]].f->height; } else if (get_bits1(&s->gb)) { - w = s->refs[s->refidx[2]]->width; - h = s->refs[s->refidx[2]]->height; + w = s->refs[s->refidx[2]].f->width; + h = s->refs[s->refidx[2]].f->height; } else { w = get_bits(&s->gb, 16) + 1; h = get_bits(&s->gb, 16) + 1; @@ -679,6 +739,7 @@ static int decode_subblock(AVCodecContext *avctx, int row, int col, ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl) { VP9Context *s = avctx->priv_data; + AVFrame *f = s->frames[CUR_FRAME].tf.f; int c = ((s->above_partition_ctx[col] >> (3 - bl)) & 1) | (((s->left_partition_ctx[row & 0x7] >> (3 - bl)) & 1) << 1); int ret; @@ -702,8 +763,8 @@ static int decode_subblock(AVCodecContext *avctx, int row, int col, ret = ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, bl, bp); if (!ret) { - yoff += hbs * 8 * s->cur_frame->linesize[0]; - uvoff += hbs * 4 * s->cur_frame->linesize[1]; + yoff += hbs * 8 * f->linesize[0]; + uvoff += hbs * 4 * f->linesize[1]; ret = ff_vp9_decode_block(avctx, row + hbs, col, lflvl, yoff, uvoff, bl, bp); } @@ -726,8 +787,8 @@ static int decode_subblock(AVCodecContext *avctx, int row, int col, yoff + 8 * hbs, uvoff + 4 * hbs, bl + 1); if (!ret) { - yoff += hbs * 8 * s->cur_frame->linesize[0]; - uvoff += hbs * 4 * s->cur_frame->linesize[1]; + yoff += hbs * 8 * f->linesize[0]; + uvoff += hbs * 4 * f->linesize[1]; ret = decode_subblock(avctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); if (!ret) { @@ -758,8 +819,8 @@ static int decode_subblock(AVCodecContext *avctx, int row, int col, bp = PARTITION_SPLIT; ret = decode_subblock(avctx, row, col, lflvl, yoff, uvoff, bl + 1); if (!ret) { - yoff += hbs * 8 * s->cur_frame->linesize[0]; - uvoff += hbs * 4 * s->cur_frame->linesize[1]; + yoff += hbs * 8 * f->linesize[0]; + uvoff += hbs * 4 * f->linesize[1]; ret = decode_subblock(avctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); } @@ -782,8 +843,10 @@ static void loopfilter_subblock(AVCodecContext *avctx, VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff) { VP9Context *s = avctx->priv_data; - uint8_t *dst = s->cur_frame->data[0] + yoff, *lvl = lflvl->level; - ptrdiff_t ls_y = s->cur_frame->linesize[0], ls_uv = s->cur_frame->linesize[1]; + AVFrame *f = s->frames[CUR_FRAME].tf.f; + uint8_t *dst = f->data[0] + yoff; + ptrdiff_t ls_y = f->linesize[0], ls_uv = f->linesize[1]; + uint8_t *lvl = lflvl->level; int y, x, p; /* FIXME: In how far can we interleave the v/h loopfilter calls? E.g. @@ -860,7 +923,7 @@ static void loopfilter_subblock(AVCodecContext *avctx, VP9Filter *lflvl, // block1 // filter edges between rows, Y plane (e.g. ------) // block2 - dst = s->cur_frame->data[0] + yoff; + dst = f->data[0] + yoff; lvl = lflvl->level; for (y = 0; y < 8; y++, dst += 8 * ls_y, lvl += 8) { uint8_t *ptr = dst, *l = lvl, *vmask = lflvl->mask[0][1][y]; @@ -924,7 +987,7 @@ static void loopfilter_subblock(AVCodecContext *avctx, VP9Filter *lflvl, // same principle but for U/V planes for (p = 0; p < 2; p++) { lvl = lflvl->level; - dst = s->cur_frame->data[1 + p] + uvoff; + dst = f->data[1 + p] + uvoff; for (y = 0; y < 8; y += 4, dst += 16 * ls_uv, lvl += 32) { uint8_t *ptr = dst, *l = lvl, *hmask1 = lflvl->mask[1][0][y]; uint8_t *hmask2 = lflvl->mask[1][0][y + 2]; @@ -971,7 +1034,7 @@ static void loopfilter_subblock(AVCodecContext *avctx, VP9Filter *lflvl, } } lvl = lflvl->level; - dst = s->cur_frame->data[1 + p] + uvoff; + dst = f->data[1 + p] + uvoff; for (y = 0; y < 8; y++, dst += 4 * ls_uv) { uint8_t *ptr = dst, *l = lvl, *vmask = lflvl->mask[1][1][y]; unsigned vm = vmask[0] | vmask[1] | vmask[2]; @@ -1030,6 +1093,7 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame, const uint8_t *data, int size) { VP9Context *s = avctx->priv_data; + AVFrame *f; int ret, tile_row, tile_col, i, ref = -1, row, col; ptrdiff_t yoff = 0, uvoff = 0; @@ -1037,13 +1101,13 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, if (ret < 0) { return ret; } else if (!ret) { - if (!s->refs[ref]->buf[0]) { + if (!s->refs[ref].f->buf[0]) { av_log(avctx, AV_LOG_ERROR, "Requested reference %d not available\n", ref); return AVERROR_INVALIDDATA; } - ret = av_frame_ref(frame, s->refs[ref]); + ret = av_frame_ref(frame, s->refs[ref].f); if (ret < 0) return ret; *got_frame = 1; @@ -1052,15 +1116,21 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, data += ret; size -= ret; - s->cur_frame = frame; + vp9_frame_unref(avctx, &s->frames[LAST_FRAME]); + if (!s->keyframe && s->frames[CUR_FRAME].tf.f->buf[0]) { + ret = vp9_frame_ref(&s->frames[LAST_FRAME], &s->frames[CUR_FRAME]); + if (ret < 0) + return ret; + } - av_frame_unref(s->cur_frame); - if ((ret = ff_get_buffer(avctx, s->cur_frame, - s->refreshrefmask ? AV_GET_BUFFER_FLAG_REF : 0)) < 0) + vp9_frame_unref(avctx, &s->frames[CUR_FRAME]); + ret = vp9_frame_alloc(avctx, &s->frames[CUR_FRAME]); + if (ret < 0) return ret; - s->cur_frame->key_frame = s->keyframe; - s->cur_frame->pict_type = s->keyframe ? AV_PICTURE_TYPE_I - : AV_PICTURE_TYPE_P; + + f = s->frames[CUR_FRAME].tf.f; + f->key_frame = s->keyframe; + f->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; if (s->fullrange) avctx->color_range = AVCOL_RANGE_JPEG; @@ -1110,8 +1180,8 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, for (row = s->tiling.tile_row_start; row < s->tiling.tile_row_end; - row += 8, yoff += s->cur_frame->linesize[0] * 64, - uvoff += s->cur_frame->linesize[1] * 32) { + row += 8, yoff += f->linesize[0] * 64, + uvoff += f->linesize[1] * 32) { VP9Filter *lflvl = s->lflvl; ptrdiff_t yoff2 = yoff, uvoff2 = uvoff; @@ -1149,16 +1219,16 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, // prediction of next row of sb64s if (row + 8 < s->rows) { memcpy(s->intra_pred_data[0], - s->cur_frame->data[0] + yoff + - 63 * s->cur_frame->linesize[0], + f->data[0] + yoff + + 63 * f->linesize[0], 8 * s->cols); memcpy(s->intra_pred_data[1], - s->cur_frame->data[1] + uvoff + - 31 * s->cur_frame->linesize[1], + f->data[1] + uvoff + + 31 * f->linesize[1], 4 * s->cols); memcpy(s->intra_pred_data[2], - s->cur_frame->data[2] + uvoff + - 31 * s->cur_frame->linesize[2], + f->data[2] + uvoff + + 31 * f->linesize[2], 4 * s->cols); } @@ -1194,21 +1264,23 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, ff_vp9_adapt_probs(s); } } - FFSWAP(VP9MVRefPair *, s->mv[0], s->mv[1]); // ref frame setup for (i = 0; i < 8; i++) if (s->refreshrefmask & (1 << i)) { - av_frame_unref(s->refs[i]); - ret = av_frame_ref(s->refs[i], s->cur_frame); + ff_thread_release_buffer(avctx, &s->refs[i]); + ret = ff_thread_ref_frame(&s->refs[i], &s->frames[CUR_FRAME].tf); if (ret < 0) return ret; } - if (s->invisible) - av_frame_unref(s->cur_frame); - else + if (!s->invisible) { + av_frame_unref(frame); + ret = av_frame_ref(frame, s->frames[CUR_FRAME].tf.f); + if (ret < 0) + return ret; *got_frame = 1; + } return 0; } @@ -1267,8 +1339,15 @@ static av_cold int vp9_decode_free(AVCodecContext *avctx) VP9Context *s = avctx->priv_data; int i; - for (i = 0; i < FF_ARRAY_ELEMS(s->refs); i++) - av_frame_free(&s->refs[i]); + for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) { + vp9_frame_unref(avctx, &s->frames[i]); + av_frame_free(&s->frames[i].tf.f); + } + + for (i = 0; i < FF_ARRAY_ELEMS(s->refs); i++) { + ff_thread_release_buffer(avctx, &s->refs[i]); + av_frame_free(&s->refs[i].f); + } av_freep(&s->c_b); av_freep(&s->above_partition_ctx); @@ -1286,17 +1365,23 @@ static av_cold int vp9_decode_init(AVCodecContext *avctx) ff_vp9dsp_init(&s->dsp); ff_videodsp_init(&s->vdsp, 8); + s->frames[0].tf.f = av_frame_alloc(); + s->frames[1].tf.f = av_frame_alloc(); + if (!s->frames[0].tf.f || !s->frames[1].tf.f) + goto fail; + for (i = 0; i < FF_ARRAY_ELEMS(s->refs); i++) { - s->refs[i] = av_frame_alloc(); - if (!s->refs[i]) { - vp9_decode_free(avctx); - return AVERROR(ENOMEM); - } + s->refs[i].f = av_frame_alloc(); + if (!s->refs[i].f) + goto fail; } s->filter.sharpness = -1; return 0; +fail: + vp9_decode_free(avctx); + return AVERROR(ENOMEM); } AVCodec ff_vp9_decoder = { diff --git a/libavcodec/vp9.h b/libavcodec/vp9.h index 31509bfbc5753..8711987b8cb08 100644 --- a/libavcodec/vp9.h +++ b/libavcodec/vp9.h @@ -27,9 +27,11 @@ #include #include +#include "libavutil/buffer.h" #include "libavutil/internal.h" #include "avcodec.h" +#include "thread.h" #include "vp56.h" enum TxfmMode { @@ -225,6 +227,16 @@ typedef struct VP9Filter { [8 /* rows */][4 /* 0=16, 1=8, 2=4, 3=inner4 */]; } VP9Filter; +typedef struct VP9Frame { + ThreadFrame tf; + + uint8_t *segmentation_map; + VP9MVRefPair *mv; + + AVBufferRef *segmentation_map_buf; + AVBufferRef *mv_buf; +} VP9Frame; + enum BlockLevel { BL_64X64, BL_32X32, @@ -293,8 +305,12 @@ typedef struct VP9Context { uint8_t refidx[3]; uint8_t signbias[3]; uint8_t varcompref[2]; - AVFrame *refs[8]; - AVFrame *cur_frame; + + ThreadFrame refs[8]; + +#define CUR_FRAME 0 +#define LAST_FRAME 1 + VP9Frame frames[2]; struct { uint8_t level; @@ -392,8 +408,6 @@ typedef struct VP9Context { // whole-frame cache uint8_t *intra_pred_data[3]; - uint8_t *segmentation_map; - VP9MVRefPair *mv[2]; VP9Filter *lflvl; DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[71 * 80]; diff --git a/libavcodec/vp9block.c b/libavcodec/vp9block.c index f5f72564242de..c018fa03107fa 100644 --- a/libavcodec/vp9block.c +++ b/libavcodec/vp9block.c @@ -70,13 +70,14 @@ static void decode_mode(VP9Context *s, VP9Block *const b) vp56_rac_get_prob_branchy(&s->c, s->prob.segpred[s->above_segpred_ctx[col] + s->left_segpred_ctx[row7]]))) { + uint8_t *refsegmap = s->frames[LAST_FRAME].segmentation_map; int pred = MAX_SEGMENT - 1; int x; for (y = 0; y < h4; y++) for (x = 0; x < w4; x++) pred = FFMIN(pred, - s->segmentation_map[(y + row) * 8 * s->sb_cols + x + col]); + refsegmap[(y + row) * 8 * s->sb_cols + x + col]); b->seg_id = pred; memset(&s->above_segpred_ctx[col], 1, w4); @@ -89,8 +90,10 @@ static void decode_mode(VP9Context *s, VP9Block *const b) memset(&s->left_segpred_ctx[row7], 0, h4); } if ((s->segmentation.enabled && s->segmentation.update_map) || s->keyframe) { + uint8_t *segmap = s->frames[CUR_FRAME].segmentation_map; + for (y = 0; y < h4; y++) - memset(&s->segmentation_map[(y + row) * 8 * s->sb_cols + col], + memset(&segmap[(y + row) * 8 * s->sb_cols + col], b->seg_id, w4); } @@ -684,24 +687,25 @@ static void decode_mode(VP9Context *s, VP9Block *const b) // FIXME kinda ugly for (y = 0; y < h4; y++) { int x, o = (row + y) * s->sb_cols * 8 + col; + VP9MVRefPair *mv = &s->frames[CUR_FRAME].mv[o]; if (b->intra) { for (x = 0; x < w4; x++) { - s->mv[0][o + x].ref[0] = - s->mv[0][o + x].ref[1] = -1; + mv[x].ref[0] = + mv[x].ref[1] = -1; } } else if (b->comp) { for (x = 0; x < w4; x++) { - s->mv[0][o + x].ref[0] = b->ref[0]; - s->mv[0][o + x].ref[1] = b->ref[1]; - AV_COPY32(&s->mv[0][o + x].mv[0], &b->mv[3][0]); - AV_COPY32(&s->mv[0][o + x].mv[1], &b->mv[3][1]); + mv[x].ref[0] = b->ref[0]; + mv[x].ref[1] = b->ref[1]; + AV_COPY32(&mv[x].mv[0], &b->mv[3][0]); + AV_COPY32(&mv[x].mv[1], &b->mv[3][1]); } } else { for (x = 0; x < w4; x++) { - s->mv[0][o + x].ref[0] = b->ref[0]; - s->mv[0][o + x].ref[1] = -1; - AV_COPY32(&s->mv[0][o + x].mv[0], &b->mv[3][0]); + mv[x].ref[0] = b->ref[0]; + mv[x].ref[1] = -1; + AV_COPY32(&mv[x].mv[0], &b->mv[3][0]); } } } @@ -1071,6 +1075,7 @@ static void intra_recon(AVCodecContext *avctx, ptrdiff_t y_off, ptrdiff_t uv_off { VP9Context *s = avctx->priv_data; VP9Block *const b = &s->b; + AVFrame *f = s->frames[CUR_FRAME].tf.f; int row = b->row, col = b->col; int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n; int h4 = bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2); @@ -1078,7 +1083,7 @@ static void intra_recon(AVCodecContext *avctx, ptrdiff_t y_off, ptrdiff_t uv_off int end_y = FFMIN(2 * (s->rows - row), h4); int tx = 4 * s->lossless + b->tx, uvtx = b->uvtx + 4 * s->lossless; int uvstep1d = 1 << b->uvtx, p; - uint8_t *dst = b->dst[0], *dst_r = s->cur_frame->data[0] + y_off; + uint8_t *dst = b->dst[0], *dst_r = f->data[0] + y_off; for (n = 0, y = 0; y < end_y; y += step1d) { uint8_t *ptr = dst, *ptr_r = dst_r; @@ -1092,7 +1097,7 @@ static void intra_recon(AVCodecContext *avctx, ptrdiff_t y_off, ptrdiff_t uv_off int eob = b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n]; mode = check_intra_mode(s, mode, &a, ptr_r, - s->cur_frame->linesize[0], + f->linesize[0], ptr, b->y_stride, l, col, x, w4, row, y, b->tx, 0); s->dsp.intra_pred[b->tx][mode](ptr, b->y_stride, l, a); @@ -1100,7 +1105,7 @@ static void intra_recon(AVCodecContext *avctx, ptrdiff_t y_off, ptrdiff_t uv_off s->dsp.itxfm_add[tx][txtp](ptr, b->y_stride, s->block + 16 * n, eob); } - dst_r += 4 * s->cur_frame->linesize[0] * step1d; + dst_r += 4 * f->linesize[0] * step1d; dst += 4 * b->y_stride * step1d; } @@ -1112,7 +1117,7 @@ static void intra_recon(AVCodecContext *avctx, ptrdiff_t y_off, ptrdiff_t uv_off step = 1 << (b->uvtx * 2); for (p = 0; p < 2; p++) { dst = b->dst[1 + p]; - dst_r = s->cur_frame->data[1 + p] + uv_off; + dst_r = f->data[1 + p] + uv_off; for (n = 0, y = 0; y < end_y; y += uvstep1d) { uint8_t *ptr = dst, *ptr_r = dst_r; for (x = 0; x < end_x; @@ -1125,7 +1130,7 @@ static void intra_recon(AVCodecContext *avctx, ptrdiff_t y_off, ptrdiff_t uv_off : s->uveob[p][n]; mode = check_intra_mode(s, mode, &a, ptr_r, - s->cur_frame->linesize[1], + f->linesize[1], ptr, b->uv_stride, l, col, x, w4, row, y, b->uvtx, p + 1); s->dsp.intra_pred[b->uvtx][mode](ptr, b->uv_stride, l, a); @@ -1134,7 +1139,7 @@ static void intra_recon(AVCodecContext *avctx, ptrdiff_t y_off, ptrdiff_t uv_off s->uvblock[p] + 16 * n, eob); } - dst_r += 4 * uvstep1d * s->cur_frame->linesize[1]; + dst_r += 4 * uvstep1d * f->linesize[1]; dst += 4 * uvstep1d * b->uv_stride; } } @@ -1224,8 +1229,12 @@ static int inter_recon(AVCodecContext *avctx) VP9Context *s = avctx->priv_data; VP9Block *const b = &s->b; int row = b->row, col = b->col; - AVFrame *ref1 = s->refs[s->refidx[b->ref[0]]]; - AVFrame *ref2 = b->comp ? s->refs[s->refidx[b->ref[1]]] : NULL; + + ThreadFrame *tref1 = &s->refs[s->refidx[b->ref[0]]]; + ThreadFrame *tref2 = b->comp ? &s->refs[s->refidx[b->ref[1]]] : NULL; + AVFrame *ref1 = tref1->f; + AVFrame *ref2 = tref2 ? tref2->f : NULL; + int w = avctx->width, h = avctx->height; ptrdiff_t ls_y = b->y_stride, ls_uv = b->uv_stride; @@ -1547,6 +1556,7 @@ int ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, { VP9Context *s = avctx->priv_data; VP9Block *const b = &s->b; + AVFrame *f = s->frames[CUR_FRAME].tf.f; enum BlockSize bs = bl * 3 + bp; int ret, y, w4 = bwh_tab[1][bs][0], h4 = bwh_tab[1][bs][1], lvl; int emu[2]; @@ -1582,25 +1592,25 @@ int ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, /* Emulated overhangs if the stride of the target buffer can't hold. * This allows to support emu-edge and so on even if we have large * block overhangs. */ - emu[0] = (col + w4) * 8 > s->cur_frame->linesize[0] || + emu[0] = (col + w4) * 8 > f->linesize[0] || (row + h4) > s->rows; - emu[1] = (col + w4) * 4 > s->cur_frame->linesize[1] || + emu[1] = (col + w4) * 4 > f->linesize[1] || (row + h4) > s->rows; if (emu[0]) { b->dst[0] = s->tmp_y; b->y_stride = 64; } else { - b->dst[0] = s->cur_frame->data[0] + yoff; - b->y_stride = s->cur_frame->linesize[0]; + b->dst[0] = f->data[0] + yoff; + b->y_stride = f->linesize[0]; } if (emu[1]) { b->dst[1] = s->tmp_uv[0]; b->dst[2] = s->tmp_uv[1]; b->uv_stride = 32; } else { - b->dst[1] = s->cur_frame->data[1] + uvoff; - b->dst[2] = s->cur_frame->data[2] + uvoff; - b->uv_stride = s->cur_frame->linesize[1]; + b->dst[1] = f->data[1] + uvoff; + b->dst[2] = f->data[2] + uvoff; + b->uv_stride = f->linesize[1]; } if (b->intra) { intra_recon(avctx, yoff, uvoff); @@ -1618,9 +1628,9 @@ int ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, av_assert2(n <= 4); if (w & bw) { - s->dsp.mc[n][0][0][0][0](s->cur_frame->data[0] + yoff + o, + s->dsp.mc[n][0][0][0][0](f->data[0] + yoff + o, s->tmp_y + o, - s->cur_frame->linesize[0], + f->linesize[0], 64, h, 0, 0); o += bw; } @@ -1636,13 +1646,13 @@ int ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, av_assert2(n <= 4); if (w & bw) { - s->dsp.mc[n][0][0][0][0](s->cur_frame->data[1] + uvoff + o, + s->dsp.mc[n][0][0][0][0](f->data[1] + uvoff + o, s->tmp_uv[0] + o, - s->cur_frame->linesize[1], + f->linesize[1], 32, h, 0, 0); - s->dsp.mc[n][0][0][0][0](s->cur_frame->data[2] + uvoff + o, + s->dsp.mc[n][0][0][0][0](f->data[2] + uvoff + o, s->tmp_uv[1] + o, - s->cur_frame->linesize[2], + f->linesize[2], 32, h, 0, 0); o += bw; } diff --git a/libavcodec/vp9mvs.c b/libavcodec/vp9mvs.c index 1f65aaac0ac98..a4ce84c5f36fe 100644 --- a/libavcodec/vp9mvs.c +++ b/libavcodec/vp9mvs.c @@ -125,7 +125,7 @@ static void find_ref_mvs(VP9Context *s, } while (0) if (row > 0) { - VP9MVRefPair *mv = &s->mv[0][(row - 1) * s->sb_cols * 8 + col]; + VP9MVRefPair *mv = &s->frames[CUR_FRAME].mv[(row - 1) * s->sb_cols * 8 + col]; if (mv->ref[0] == ref) RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][0]); @@ -133,7 +133,7 @@ static void find_ref_mvs(VP9Context *s, RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][1]); } if (col > s->tiling.tile_col_start) { - VP9MVRefPair *mv = &s->mv[0][row * s->sb_cols * 8 + col - 1]; + VP9MVRefPair *mv = &s->frames[CUR_FRAME].mv[row * s->sb_cols * 8 + col - 1]; if (mv->ref[0] == ref) RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][0]); @@ -151,7 +151,7 @@ static void find_ref_mvs(VP9Context *s, if (c >= s->tiling.tile_col_start && c < s->cols && r >= 0 && r < s->rows) { - VP9MVRefPair *mv = &s->mv[0][r * s->sb_cols * 8 + c]; + VP9MVRefPair *mv = &s->frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c]; if (mv->ref[0] == ref) RETURN_MV(mv->mv[0]); @@ -162,7 +162,7 @@ static void find_ref_mvs(VP9Context *s, // MV at this position in previous frame, using same reference frame if (s->use_last_frame_mvs) { - VP9MVRefPair *mv = &s->mv[1][row * s->sb_cols * 8 + col]; + VP9MVRefPair *mv = &s->frames[LAST_FRAME].mv[row * s->sb_cols * 8 + col]; if (mv->ref[0] == ref) RETURN_MV(mv->mv[0]); @@ -186,7 +186,7 @@ static void find_ref_mvs(VP9Context *s, if (c >= s->tiling.tile_col_start && c < s->cols && r >= 0 && r < s->rows) { - VP9MVRefPair *mv = &s->mv[0][r * s->sb_cols * 8 + c]; + VP9MVRefPair *mv = &s->frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c]; if (mv->ref[0] != ref && mv->ref[0] >= 0) RETURN_SCALE_MV(mv->mv[0], @@ -203,7 +203,7 @@ static void find_ref_mvs(VP9Context *s, // MV at this position in previous frame, using different reference frame if (s->use_last_frame_mvs) { - VP9MVRefPair *mv = &s->mv[1][row * s->sb_cols * 8 + col]; + VP9MVRefPair *mv = &s->frames[LAST_FRAME].mv[row * s->sb_cols * 8 + col]; if (mv->ref[0] != ref && mv->ref[0] >= 0) RETURN_SCALE_MV(mv->mv[0], From 5b995452a63ed754545a0ac90be79fac63b3390d Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sat, 23 Nov 2013 12:10:12 -0500 Subject: [PATCH 0061/3374] vp9: allocate 'b', 'block/uvblock' and 'eob/uveob' dynamically. This will be needed for frame threading. Signed-off-by: Anton Khirnov --- libavcodec/vp9.c | 24 ++++++++++++++++++++++++ libavcodec/vp9.h | 9 ++++----- libavcodec/vp9block.c | 8 ++++---- libavcodec/vp9mvs.c | 4 ++-- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 11ed00e3f9481..497dcf2d1570b 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -152,6 +152,19 @@ static int update_size(AVCodecContext *avctx, int w, int h) assign(s->above_mv_ctx, VP56mv(*)[2], 16); #undef assign + av_freep(&s->b_base); + av_freep(&s->block_base); + s->b_base = av_malloc(sizeof(*s->b_base)); + s->block_base = av_mallocz((64 * 64 + 128) * 3); + if (!s->b_base || !s->block_base) + return AVERROR(ENOMEM); + + s->uvblock_base[0] = s->block_base + 64 * 64; + s->uvblock_base[1] = s->uvblock_base[0] + 32 * 32; + s->eob_base = (uint8_t *) (s->uvblock_base[1] + 32 * 32); + s->uveob_base[0] = s->eob_base + 256; + s->uveob_base[1] = s->uveob_base[0] + 64; + return 0; } @@ -1155,6 +1168,15 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, memset(s->above_uv_nnz_ctx[0], 0, s->sb_cols * 8); memset(s->above_uv_nnz_ctx[1], 0, s->sb_cols * 8); memset(s->above_segpred_ctx, 0, s->cols); + + s->b = s->b_base; + s->block = s->block_base; + s->uvblock[0] = s->uvblock_base[0]; + s->uvblock[1] = s->uvblock_base[1]; + s->eob = s->eob_base; + s->uveob[0] = s->uveob_base[0]; + s->uveob[1] = s->uveob_base[1]; + for (tile_row = 0; tile_row < s->tiling.tile_rows; tile_row++) { set_tile_offset(&s->tiling.tile_row_start, &s->tiling.tile_row_end, tile_row, s->tiling.log2_tile_rows, s->sb_rows); @@ -1351,6 +1373,8 @@ static av_cold int vp9_decode_free(AVCodecContext *avctx) av_freep(&s->c_b); av_freep(&s->above_partition_ctx); + av_freep(&s->b_base); + av_freep(&s->block_base); return 0; } diff --git a/libavcodec/vp9.h b/libavcodec/vp9.h index 8711987b8cb08..e59129818c6f3 100644 --- a/libavcodec/vp9.h +++ b/libavcodec/vp9.h @@ -280,7 +280,8 @@ typedef struct VP9Context { VP56RangeCoder c; VP56RangeCoder *c_b; unsigned c_b_size; - VP9Block b; + VP9Block *b; + VP9Block *b_base; // bitstream header uint8_t profile; @@ -412,10 +413,8 @@ typedef struct VP9Context { DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[71 * 80]; // block reconstruction intermediates - DECLARE_ALIGNED(32, int16_t, block)[4096]; - DECLARE_ALIGNED(32, int16_t, uvblock)[2][1024]; - uint8_t eob[256]; - uint8_t uveob[2][64]; + int16_t *block_base, *block, *uvblock_base[2], *uvblock[2]; + uint8_t *eob_base, *uveob_base[2], *eob, *uveob[2]; struct { int x, y; } min_mv, max_mv; DECLARE_ALIGNED(32, uint8_t, tmp_y)[64 * 64]; DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][32 * 32]; diff --git a/libavcodec/vp9block.c b/libavcodec/vp9block.c index c018fa03107fa..feb5e6c00f692 100644 --- a/libavcodec/vp9block.c +++ b/libavcodec/vp9block.c @@ -823,7 +823,7 @@ static int decode_block_coeffs(VP56RangeCoder *c, int16_t *coef, int n_coeffs, static int decode_coeffs(AVCodecContext *avctx) { VP9Context *s = avctx->priv_data; - VP9Block *const b = &s->b; + VP9Block *b = s->b; int row = b->row, col = b->col; uint8_t (*p)[6][11] = s->prob.coef[b->tx][0 /* y */][!b->intra]; unsigned (*c)[6][3] = s->counts.coef[b->tx][0 /* y */][!b->intra]; @@ -1074,7 +1074,7 @@ static av_always_inline int check_intra_mode(VP9Context *s, int mode, static void intra_recon(AVCodecContext *avctx, ptrdiff_t y_off, ptrdiff_t uv_off) { VP9Context *s = avctx->priv_data; - VP9Block *const b = &s->b; + VP9Block *b = s->b; AVFrame *f = s->frames[CUR_FRAME].tf.f; int row = b->row, col = b->col; int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n; @@ -1227,7 +1227,7 @@ static int inter_recon(AVCodecContext *avctx) { 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4 }, }; VP9Context *s = avctx->priv_data; - VP9Block *const b = &s->b; + VP9Block *b = s->b; int row = b->row, col = b->col; ThreadFrame *tref1 = &s->refs[s->refidx[b->ref[0]]]; @@ -1555,7 +1555,7 @@ int ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, enum BlockLevel bl, enum BlockPartition bp) { VP9Context *s = avctx->priv_data; - VP9Block *const b = &s->b; + VP9Block *b = s->b; AVFrame *f = s->frames[CUR_FRAME].tf.f; enum BlockSize bs = bl * 3 + bp; int ret, y, w4 = bwh_tab[1][bs][0], h4 = bwh_tab[1][bs][1], lvl; diff --git a/libavcodec/vp9mvs.c b/libavcodec/vp9mvs.c index a4ce84c5f36fe..5edcb1903922f 100644 --- a/libavcodec/vp9mvs.c +++ b/libavcodec/vp9mvs.c @@ -64,7 +64,7 @@ static void find_ref_mvs(VP9Context *s, [BS_4x4] = { { 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } }, }; - VP9Block *const b = &s->b; + VP9Block *b = s->b; int row = b->row, col = b->col, row7 = b->row7; const int8_t (*p)[2] = mv_ref_blk_off[b->bs]; #define INVALID_MV 0x80008000U @@ -279,7 +279,7 @@ static av_always_inline int read_mv_component(VP9Context *s, int idx, int hp) void ff_vp9_fill_mv(VP9Context *s, VP56mv *mv, int mode, int sb) { - VP9Block *const b = &s->b; + VP9Block *b = s->b; if (mode == ZEROMV) { memset(mv, 0, sizeof(*mv) * 2); From 1730a67ab99de0648dd55e81ea7fec12ab70225c Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 2 Aug 2016 07:55:31 +0200 Subject: [PATCH 0062/3374] vp9: add frame threading Signed-off-by: Anton Khirnov --- libavcodec/vp9.c | 273 ++++++++++++++++++++++++++++++++++-------- libavcodec/vp9.h | 11 ++ libavcodec/vp9block.c | 111 ++++++++++++----- libavcodec/vp9mvs.c | 4 + 4 files changed, 318 insertions(+), 81 deletions(-) diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 497dcf2d1570b..7989ca8d14b40 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -105,14 +105,20 @@ static void vp9_decode_flush(AVCodecContext *avctx) for (i = 0; i < FF_ARRAY_ELEMS(s->refs); i++) ff_thread_release_buffer(avctx, &s->refs[i]); + + s->use_last_frame_mvs = 0; + + s->alloc_width = 0; + s->alloc_height = 0; } static int update_size(AVCodecContext *avctx, int w, int h) { VP9Context *s = avctx->priv_data; uint8_t *p; + int nb_blocks, nb_superblocks; - if (s->above_partition_ctx && w == avctx->width && h == avctx->height) + if (s->above_partition_ctx && w == s->alloc_width && h == s->alloc_height) return 0; vp9_decode_flush(avctx); @@ -154,16 +160,26 @@ static int update_size(AVCodecContext *avctx, int w, int h) av_freep(&s->b_base); av_freep(&s->block_base); - s->b_base = av_malloc(sizeof(*s->b_base)); - s->block_base = av_mallocz((64 * 64 + 128) * 3); + + if (avctx->active_thread_type & FF_THREAD_FRAME) { + nb_blocks = s->cols * s->rows; + nb_superblocks = s->sb_cols * s->sb_rows; + } else { + nb_blocks = nb_superblocks = 1; + } + + s->b_base = av_malloc_array(nb_blocks, sizeof(*s->b_base)); + s->block_base = av_mallocz_array(nb_superblocks, (64 * 64 + 128) * 3); if (!s->b_base || !s->block_base) return AVERROR(ENOMEM); + s->uvblock_base[0] = s->block_base + nb_superblocks * 64 * 64; + s->uvblock_base[1] = s->uvblock_base[0] + nb_superblocks * 32 * 32; + s->eob_base = (uint8_t *)(s->uvblock_base[1] + nb_superblocks * 32 * 32); + s->uveob_base[0] = s->eob_base + nb_superblocks * 256; + s->uveob_base[1] = s->uveob_base[0] + nb_superblocks * 64; - s->uvblock_base[0] = s->block_base + 64 * 64; - s->uvblock_base[1] = s->uvblock_base[0] + 32 * 32; - s->eob_base = (uint8_t *) (s->uvblock_base[1] + 32 * 32); - s->uveob_base[0] = s->eob_base + 256; - s->uveob_base[1] = s->uveob_base[0] + 64; + s->alloc_width = w; + s->alloc_height = h; return 0; } @@ -278,7 +294,6 @@ static int decode_frame_header(AVCodecContext *avctx, last_invisible = s->invisible; s->invisible = !get_bits1(&s->gb); s->errorres = get_bits1(&s->gb); - // FIXME disable this upon resolution change s->use_last_frame_mvs = !s->errorres && !last_invisible; if (s->keyframe) { @@ -851,6 +866,61 @@ static int decode_subblock(AVCodecContext *avctx, int row, int col, return ret; } +static int decode_superblock_mem(AVCodecContext *avctx, int row, int col, struct VP9Filter *lflvl, + ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl) +{ + VP9Context *s = avctx->priv_data; + VP9Block *b = s->b; + ptrdiff_t hbs = 4 >> bl; + AVFrame *f = s->frames[CUR_FRAME].tf.f; + ptrdiff_t y_stride = f->linesize[0], uv_stride = f->linesize[1]; + int res; + + if (bl == BL_8X8) { + av_assert2(b->bl == BL_8X8); + res = ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp); + } else if (s->b->bl == bl) { + if ((res = ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp)) < 0) + return res; + if (b->bp == PARTITION_H && row + hbs < s->rows) { + yoff += hbs * 8 * y_stride; + uvoff += hbs * 4 * uv_stride; + res = ff_vp9_decode_block(avctx, row + hbs, col, lflvl, yoff, uvoff, b->bl, b->bp); + } else if (b->bp == PARTITION_V && col + hbs < s->cols) { + yoff += hbs * 8; + uvoff += hbs * 4; + res = ff_vp9_decode_block(avctx, row, col + hbs, lflvl, yoff, uvoff, b->bl, b->bp); + } + } else { + if ((res = decode_superblock_mem(avctx, row, col, lflvl, yoff, uvoff, bl + 1)) < 0) + return res; + if (col + hbs < s->cols) { // FIXME why not <=? + if (row + hbs < s->rows) { + if ((res = decode_superblock_mem(avctx, row, col + hbs, lflvl, yoff + 8 * hbs, + uvoff + 4 * hbs, bl + 1)) < 0) + return res; + yoff += hbs * 8 * y_stride; + uvoff += hbs * 4 * uv_stride; + if ((res = decode_superblock_mem(avctx, row + hbs, col, lflvl, yoff, + uvoff, bl + 1)) < 0) + return res; + res = decode_superblock_mem(avctx, row + hbs, col + hbs, lflvl, + yoff + 8 * hbs, uvoff + 4 * hbs, bl + 1); + } else { + yoff += hbs * 8; + uvoff += hbs * 4; + res = decode_superblock_mem(avctx, row, col + hbs, lflvl, yoff, uvoff, bl + 1); + } + } else if (row + hbs < s->rows) { + yoff += hbs * 8 * y_stride; + uvoff += hbs * 4 * uv_stride; + res = decode_superblock_mem(avctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); + } + } + + return res; +} + static void loopfilter_subblock(AVCodecContext *avctx, VP9Filter *lflvl, int row, int col, ptrdiff_t yoff, ptrdiff_t uvoff) @@ -1102,13 +1172,29 @@ static void set_tile_offset(int *start, int *end, int idx, int log2_n, int n) *end = FFMIN(sb_end, n) << 3; } +static int update_refs(AVCodecContext *avctx) +{ + VP9Context *s = avctx->priv_data; + int i, ret; + + for (i = 0; i < FF_ARRAY_ELEMS(s->refs); i++) + if (s->refreshrefmask & (1 << i)) { + ff_thread_release_buffer(avctx, &s->refs[i]); + ret = ff_thread_ref_frame(&s->refs[i], &s->frames[CUR_FRAME].tf); + if (ret < 0) + return ret; + } + + return 0; +} + static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, - int *got_frame, const uint8_t *data, int size) + int *got_frame, const uint8_t *data, int size, + int can_finish_setup) { VP9Context *s = avctx->priv_data; AVFrame *f; int ret, tile_row, tile_col, i, ref = -1, row, col; - ptrdiff_t yoff = 0, uvoff = 0; ret = decode_frame_header(avctx, data, size, &ref); if (ret < 0) { @@ -1157,6 +1243,29 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, case 4: avctx->colorspace = AVCOL_SPC_SMPTE240M; break; } + s->pass = s->uses_2pass = + avctx->active_thread_type & FF_THREAD_FRAME && s->refreshctx && !s->parallelmode; + + if (s->refreshctx && s->parallelmode) { + int j, k, l, m; + for (i = 0; i < 4; i++) { + for (j = 0; j < 2; j++) + for (k = 0; k < 2; k++) + for (l = 0; l < 6; l++) + for (m = 0; m < 6; m++) + memcpy(s->prob_ctx[s->framectxid].coef[i][j][k][l][m], + s->prob.coef[i][j][k][l][m], 3); + if (s->txfmmode == i) + break; + } + s->prob_ctx[s->framectxid].p = s->prob.p; + } + if ((s->parallelmode || !s->refreshctx) && + can_finish_setup && avctx->active_thread_type & FF_THREAD_FRAME) { + ff_thread_finish_setup(avctx); + s->setup_finished = 1; + } + // main tile decode loop memset(s->above_partition_ctx, 0, s->cols); memset(s->above_skip_ctx, 0, s->cols); @@ -1169,6 +1278,8 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, memset(s->above_uv_nnz_ctx[1], 0, s->sb_cols * 8); memset(s->above_segpred_ctx, 0, s->cols); + do { + ptrdiff_t yoff = 0, uvoff = 0; s->b = s->b_base; s->block = s->block_base; s->uvblock[0] = s->uvblock_base[0]; @@ -1180,6 +1291,8 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, for (tile_row = 0; tile_row < s->tiling.tile_rows; tile_row++) { set_tile_offset(&s->tiling.tile_row_start, &s->tiling.tile_row_end, tile_row, s->tiling.log2_tile_rows, s->sb_rows); + + if (s->pass != 2) { for (tile_col = 0; tile_col < s->tiling.tile_cols; tile_col++) { int64_t tile_size; @@ -1191,14 +1304,19 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, data += 4; size -= 4; } - if (tile_size > size) - return AVERROR_INVALIDDATA; + if (tile_size > size) { + ret = AVERROR_INVALIDDATA; + goto fail; + } ff_vp56_init_range_decoder(&s->c_b[tile_col], data, tile_size); - if (vp56_rac_get_prob_branchy(&s->c_b[tile_col], 128)) // marker bit - return AVERROR_INVALIDDATA; + if (vp56_rac_get_prob_branchy(&s->c_b[tile_col], 128)) { // marker bit + ret = AVERROR_INVALIDDATA; + goto fail; + } data += tile_size; size -= tile_size; } + } for (row = s->tiling.tile_row_start; row < s->tiling.tile_row_end; @@ -1228,15 +1346,26 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, col += 8, yoff2 += 64, uvoff2 += 32, lflvl++) { // FIXME integrate with lf code (i.e. zero after each // use, similar to invtxfm coefficients, or similar) - memset(lflvl->mask, 0, sizeof(lflvl->mask)); + if (s->pass != 1) + memset(lflvl->mask, 0, sizeof(lflvl->mask)); - if ((ret = decode_subblock(avctx, row, col, lflvl, - yoff2, uvoff2, BL_64X64)) < 0) - return ret; + if (s->pass == 2) { + ret = decode_superblock_mem(avctx, row, col, lflvl, + yoff2, uvoff2, BL_64X64); + } else { + ret = decode_subblock(avctx, row, col, lflvl, + yoff2, uvoff2, BL_64X64); + } + if (ret < 0) + goto fail; } - memcpy(&s->c_b[tile_col], &s->c, sizeof(s->c)); + if (s->pass != 2) + memcpy(&s->c_b[tile_col], &s->c, sizeof(s->c)); } + if (s->pass == 1) + continue; + // backup pre-loopfilter reconstruction data for intra // prediction of next row of sb64s if (row + 8 < s->rows) { @@ -1263,38 +1392,33 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, col += 8, yoff2 += 64, uvoff2 += 32, lflvl++) loopfilter_subblock(avctx, lflvl, row, col, yoff2, uvoff2); } + + // FIXME maybe we can make this more finegrained by running the + // loopfilter per-block instead of after each sbrow + // In fact that would also make intra pred left preparation easier? + ff_thread_report_progress(&s->frames[CUR_FRAME].tf, row >> 3, 0); } } - // bw adaptivity (or in case of parallel decoding mode, fw adaptivity - // probability maintenance between frames) - if (s->refreshctx) { - if (s->parallelmode) { - int j, k, l, m; - for (i = 0; i < 4; i++) { - for (j = 0; j < 2; j++) - for (k = 0; k < 2; k++) - for (l = 0; l < 6; l++) - for (m = 0; m < 6; m++) - memcpy(s->prob_ctx[s->framectxid].coef[i][j][k][l][m], - s->prob.coef[i][j][k][l][m], 3); - if (s->txfmmode == i) - break; - } - s->prob_ctx[s->framectxid].p = s->prob.p; - } else { + if (s->pass < 2 && s->refreshctx && !s->parallelmode) { ff_vp9_adapt_probs(s); + if (can_finish_setup && avctx->active_thread_type & FF_THREAD_FRAME) { + ff_thread_finish_setup(avctx); + s->setup_finished = 1; + } } - } + } while (s->pass++ == 1); +fail: + ff_thread_report_progress(&s->frames[CUR_FRAME].tf, INT_MAX, 0); + if (ret < 0) + return ret; // ref frame setup - for (i = 0; i < 8; i++) - if (s->refreshrefmask & (1 << i)) { - ff_thread_release_buffer(avctx, &s->refs[i]); - ret = ff_thread_ref_frame(&s->refs[i], &s->frames[CUR_FRAME].tf); - if (ret < 0) - return ret; - } + if (!s->setup_finished) { + ret = update_refs(avctx); + if (ret < 0) + return ret; + } if (!s->invisible) { av_frame_unref(frame); @@ -1310,10 +1434,13 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, static int vp9_decode_packet(AVCodecContext *avctx, void *frame, int *got_frame, AVPacket *avpkt) { + VP9Context *s = avctx->priv_data; const uint8_t *data = avpkt->data; int size = avpkt->size; int marker, ret; + s->setup_finished = 0; + /* Read superframe index - this is a collection of individual frames * that together lead to one visible frame */ marker = data[size - 1]; @@ -1339,7 +1466,8 @@ static int vp9_decode_packet(AVCodecContext *avctx, void *frame, return AVERROR_INVALIDDATA; } - ret = vp9_decode_frame(avctx, frame, got_frame, data, sz); + ret = vp9_decode_frame(avctx, frame, got_frame, data, sz, + !n_frames); if (ret < 0) return ret; data += sz; @@ -1351,7 +1479,7 @@ static int vp9_decode_packet(AVCodecContext *avctx, void *frame, /* If we get here, there was no valid superframe index, i.e. this is just * one whole single frame. Decode it as such from the complete input buf. */ - if ((ret = vp9_decode_frame(avctx, frame, got_frame, data, size)) < 0) + if ((ret = vp9_decode_frame(avctx, frame, got_frame, data, size, 1)) < 0) return ret; return size; } @@ -1384,6 +1512,10 @@ static av_cold int vp9_decode_init(AVCodecContext *avctx) VP9Context *s = avctx->priv_data; int i; + memset(s, 0, sizeof(*s)); + + avctx->internal->allocate_progress = 1; + avctx->pix_fmt = AV_PIX_FMT_YUV420P; ff_vp9dsp_init(&s->dsp); @@ -1408,6 +1540,49 @@ static av_cold int vp9_decode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); } +static int vp9_decode_update_thread_context(AVCodecContext *dst, const AVCodecContext *src) +{ + VP9Context *s = dst->priv_data, *ssrc = src->priv_data; + int i, ret; + + ret = update_size(dst, ssrc->alloc_width, ssrc->alloc_height); + if (ret < 0) + return ret; + + for (i = 0; i < 2; i++) { + if (s->frames[i].tf.f->data[0]) + vp9_frame_unref(dst, &s->frames[i]); + if (ssrc->frames[i].tf.f->data[0]) { + if ((ret = vp9_frame_ref(&s->frames[i], &ssrc->frames[i])) < 0) + return ret; + } + } + for (i = 0; i < FF_ARRAY_ELEMS(s->refs); i++) { + ff_thread_release_buffer(dst, &s->refs[i]); + if (ssrc->refs[i].f->buf[0]) { + ret = ff_thread_ref_frame(&s->refs[i], &ssrc->refs[i]); + if (ret < 0) + return ret; + } + } + + s->refreshrefmask = ssrc->refreshrefmask; + ret = update_refs(dst); + if (ret < 0) + return ret; + + s->invisible = ssrc->invisible; + s->keyframe = ssrc->keyframe; + s->last_uses_2pass = ssrc->uses_2pass; + + memcpy(&s->prob_ctx, &ssrc->prob_ctx, sizeof(s->prob_ctx)); + memcpy(&s->lf_delta, &ssrc->lf_delta, sizeof(s->lf_delta)); + memcpy(&s->segmentation.feat, &ssrc->segmentation.feat, + sizeof(s->segmentation.feat)); + + return 0; +} + AVCodec ff_vp9_decoder = { .name = "vp9", .long_name = NULL_IF_CONFIG_SMALL("Google VP9"), @@ -1418,5 +1593,7 @@ AVCodec ff_vp9_decoder = { .decode = vp9_decode_packet, .flush = vp9_decode_flush, .close = vp9_decode_free, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .init_thread_copy = vp9_decode_init, + .update_thread_context = vp9_decode_update_thread_context, }; diff --git a/libavcodec/vp9.h b/libavcodec/vp9.h index e59129818c6f3..25bb2d159b913 100644 --- a/libavcodec/vp9.h +++ b/libavcodec/vp9.h @@ -271,6 +271,9 @@ typedef struct VP9Block { int row, row7, col, col7; uint8_t *dst[3]; ptrdiff_t y_stride, uv_stride; + + enum BlockLevel bl; + enum BlockPartition bp; } VP9Block; typedef struct VP9Context { @@ -283,6 +286,14 @@ typedef struct VP9Context { VP9Block *b; VP9Block *b_base; + int alloc_width; + int alloc_height; + + int pass; + int uses_2pass; + int last_uses_2pass; + int setup_finished; + // bitstream header uint8_t profile; uint8_t keyframe, last_keyframe; diff --git a/libavcodec/vp9block.c b/libavcodec/vp9block.c index feb5e6c00f692..9b0d836adcabf 100644 --- a/libavcodec/vp9block.c +++ b/libavcodec/vp9block.c @@ -74,6 +74,9 @@ static void decode_mode(VP9Context *s, VP9Block *const b) int pred = MAX_SEGMENT - 1; int x; + if (!s->last_uses_2pass) + ff_thread_await_progress(&s->frames[LAST_FRAME].tf, row >> 3, 0); + for (y = 0; y < h4; y++) for (x = 0; x < w4; x++) pred = FFMIN(pred, @@ -1149,17 +1152,25 @@ static av_always_inline void mc_luma_dir(VP9Context *s, vp9_mc_func(*mc)[2], uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *ref, ptrdiff_t ref_stride, + ThreadFrame *ref_frame, ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, int bw, int bh, int w, int h) { int mx = mv->x, my = mv->y; + int th; y += my >> 3; x += mx >> 3; ref += y * ref_stride + x; mx &= 7; my &= 7; + + // we use +7 because the last 7 pixels of each sbrow can be changed in + // the longest loopfilter of the next sbrow + th = (y + bh + 4 * !!my + 7) >> 6; + ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); + // FIXME bilinear filter only needs 0/1 pixels, not 3/4 if (x < !!mx * 3 || y < !!my * 3 || x + !!mx * 4 > w - bw || y + !!my * 4 > h - bh) { @@ -1182,11 +1193,13 @@ static av_always_inline void mc_chroma_dir(VP9Context *s, vp9_mc_func(*mc)[2], ptrdiff_t src_stride_u, const uint8_t *ref_v, ptrdiff_t src_stride_v, + ThreadFrame *ref_frame, ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, int bw, int bh, int w, int h) { int mx = mv->x, my = mv->y; + int th; y += my >> 4; x += mx >> 4; @@ -1194,6 +1207,12 @@ static av_always_inline void mc_chroma_dir(VP9Context *s, vp9_mc_func(*mc)[2], ref_v += y * src_stride_v + x; mx &= 15; my &= 15; + + // we use +7 because the last 7 pixels of each sbrow can be changed in + // the longest loopfilter of the next sbrow + th = (y + bh + 4 * !!my + 7) >> 5; + ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); + // FIXME bilinear filter only needs 0/1 pixels, not 3/4 if (x < !!mx * 3 || y < !!my * 3 || x + !!mx * 4 > w - bw || y + !!my * 4 > h - bh) { @@ -1245,36 +1264,36 @@ static int inter_recon(AVCodecContext *avctx) if (b->bs > BS_8x8) { if (b->bs == BS_8x4) { mc_luma_dir(s, s->dsp.mc[3][b->filter][0], b->dst[0], ls_y, - ref1->data[0], ref1->linesize[0], + ref1->data[0], ref1->linesize[0], tref1, row << 3, col << 3, &b->mv[0][0], 8, 4, w, h); mc_luma_dir(s, s->dsp.mc[3][b->filter][0], b->dst[0] + 4 * ls_y, ls_y, - ref1->data[0], ref1->linesize[0], + ref1->data[0], ref1->linesize[0], tref1, (row << 3) + 4, col << 3, &b->mv[2][0], 8, 4, w, h); if (b->comp) { mc_luma_dir(s, s->dsp.mc[3][b->filter][1], b->dst[0], ls_y, - ref2->data[0], ref2->linesize[0], + ref2->data[0], ref2->linesize[0], tref2, row << 3, col << 3, &b->mv[0][1], 8, 4, w, h); mc_luma_dir(s, s->dsp.mc[3][b->filter][1], b->dst[0] + 4 * ls_y, ls_y, - ref2->data[0], ref2->linesize[0], + ref2->data[0], ref2->linesize[0], tref2, (row << 3) + 4, col << 3, &b->mv[2][1], 8, 4, w, h); } } else if (b->bs == BS_4x8) { mc_luma_dir(s, s->dsp.mc[4][b->filter][0], b->dst[0], ls_y, - ref1->data[0], ref1->linesize[0], + ref1->data[0], ref1->linesize[0], tref1, row << 3, col << 3, &b->mv[0][0], 4, 8, w, h); mc_luma_dir(s, s->dsp.mc[4][b->filter][0], b->dst[0] + 4, ls_y, - ref1->data[0], ref1->linesize[0], + ref1->data[0], ref1->linesize[0], tref1, row << 3, (col << 3) + 4, &b->mv[1][0], 4, 8, w, h); if (b->comp) { mc_luma_dir(s, s->dsp.mc[4][b->filter][1], b->dst[0], ls_y, - ref2->data[0], ref2->linesize[0], + ref2->data[0], ref2->linesize[0], tref2, row << 3, col << 3, &b->mv[0][1], 4, 8, w, h); mc_luma_dir(s, s->dsp.mc[4][b->filter][1], b->dst[0] + 4, ls_y, - ref2->data[0], ref2->linesize[0], + ref2->data[0], ref2->linesize[0], tref2, row << 3, (col << 3) + 4, &b->mv[1][1], 4, 8, w, h); } } else { @@ -1283,34 +1302,34 @@ static int inter_recon(AVCodecContext *avctx) // FIXME if two horizontally adjacent blocks have the same MV, // do a w8 instead of a w4 call mc_luma_dir(s, s->dsp.mc[4][b->filter][0], b->dst[0], ls_y, - ref1->data[0], ref1->linesize[0], + ref1->data[0], ref1->linesize[0], tref1, row << 3, col << 3, &b->mv[0][0], 4, 4, w, h); mc_luma_dir(s, s->dsp.mc[4][b->filter][0], b->dst[0] + 4, ls_y, - ref1->data[0], ref1->linesize[0], + ref1->data[0], ref1->linesize[0], tref1, row << 3, (col << 3) + 4, &b->mv[1][0], 4, 4, w, h); mc_luma_dir(s, s->dsp.mc[4][b->filter][0], b->dst[0] + 4 * ls_y, ls_y, - ref1->data[0], ref1->linesize[0], + ref1->data[0], ref1->linesize[0], tref1, (row << 3) + 4, col << 3, &b->mv[2][0], 4, 4, w, h); mc_luma_dir(s, s->dsp.mc[4][b->filter][0], b->dst[0] + 4 * ls_y + 4, ls_y, - ref1->data[0], ref1->linesize[0], + ref1->data[0], ref1->linesize[0], tref1, (row << 3) + 4, (col << 3) + 4, &b->mv[3][0], 4, 4, w, h); if (b->comp) { mc_luma_dir(s, s->dsp.mc[4][b->filter][1], b->dst[0], ls_y, - ref2->data[0], ref2->linesize[0], + ref2->data[0], ref2->linesize[0], tref2, row << 3, col << 3, &b->mv[0][1], 4, 4, w, h); mc_luma_dir(s, s->dsp.mc[4][b->filter][1], b->dst[0] + 4, ls_y, - ref2->data[0], ref2->linesize[0], + ref2->data[0], ref2->linesize[0], tref2, row << 3, (col << 3) + 4, &b->mv[1][1], 4, 4, w, h); mc_luma_dir(s, s->dsp.mc[4][b->filter][1], b->dst[0] + 4 * ls_y, ls_y, - ref2->data[0], ref2->linesize[0], + ref2->data[0], ref2->linesize[0], tref2, (row << 3) + 4, col << 3, &b->mv[2][1], 4, 4, w, h); mc_luma_dir(s, s->dsp.mc[4][b->filter][1], b->dst[0] + 4 * ls_y + 4, ls_y, - ref2->data[0], ref2->linesize[0], + ref2->data[0], ref2->linesize[0], tref2, (row << 3) + 4, (col << 3) + 4, &b->mv[3][1], 4, 4, w, h); } } @@ -1320,12 +1339,12 @@ static int inter_recon(AVCodecContext *avctx) int bh = bwh_tab[0][b->bs][1] * 4; mc_luma_dir(s, s->dsp.mc[bwl][b->filter][0], b->dst[0], ls_y, - ref1->data[0], ref1->linesize[0], + ref1->data[0], ref1->linesize[0], tref1, row << 3, col << 3, &b->mv[0][0], bw, bh, w, h); if (b->comp) mc_luma_dir(s, s->dsp.mc[bwl][b->filter][1], b->dst[0], ls_y, - ref2->data[0], ref2->linesize[0], + ref2->data[0], ref2->linesize[0], tref2, row << 3, col << 3, &b->mv[0][1], bw, bh, w, h); } @@ -1349,7 +1368,7 @@ static int inter_recon(AVCodecContext *avctx) mc_chroma_dir(s, s->dsp.mc[bwl][b->filter][0], b->dst[1], b->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], - ref1->data[2], ref1->linesize[2], + ref1->data[2], ref1->linesize[2], tref1, row << 2, col << 2, &mvuv, bw, bh, w, h); if (b->comp) { @@ -1364,7 +1383,7 @@ static int inter_recon(AVCodecContext *avctx) mc_chroma_dir(s, s->dsp.mc[bwl][b->filter][1], b->dst[1], b->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], - ref2->data[2], ref2->linesize[2], + ref2->data[2], ref2->linesize[2], tref2, row << 2, col << 2, &mvuv, bw, bh, w, h); } } @@ -1571,21 +1590,37 @@ int ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, s->max_mv.x = 128 + (s->cols - col - w4) * 64; s->max_mv.y = 128 + (s->rows - row - h4) * 64; - b->bs = bs; - decode_mode(s, b); - b->uvtx = b->tx - (w4 * 2 == (1 << b->tx) || h4 * 2 == (1 << b->tx)); + if (s->pass < 2) { + b->bs = bs; + b->bl = bl; + b->bp = bp; + decode_mode(s, b); + b->uvtx = b->tx - (w4 * 2 == (1 << b->tx) || h4 * 2 == (1 << b->tx)); - if (!b->skip) { - if ((ret = decode_coeffs(avctx)) < 0) - return ret; - } else { - int pl; + if (!b->skip) { + if ((ret = decode_coeffs(avctx)) < 0) + return ret; + } else { + int pl; + + memset(&s->above_y_nnz_ctx[col * 2], 0, w4 * 2); + memset(&s->left_y_nnz_ctx[(row & 7) << 1], 0, h4 * 2); + for (pl = 0; pl < 2; pl++) { + memset(&s->above_uv_nnz_ctx[pl][col], 0, w4); + memset(&s->left_uv_nnz_ctx[pl][row & 7], 0, h4); + } + } + + if (s->pass == 1) { + s->b++; + s->block += w4 * h4 * 64; + s->uvblock[0] += w4 * h4 * 16; + s->uvblock[1] += w4 * h4 * 16; + s->eob += w4 * h4 * 4; + s->uveob[0] += w4 * h4; + s->uveob[1] += w4 * h4; - memset(&s->above_y_nnz_ctx[col * 2], 0, w4 * 2); - memset(&s->left_y_nnz_ctx[(row & 7) << 1], 0, h4 * 2); - for (pl = 0; pl < 2; pl++) { - memset(&s->above_uv_nnz_ctx[pl][col], 0, w4); - memset(&s->left_uv_nnz_ctx[pl][row & 7], 0, h4); + return 0; } } @@ -1690,5 +1725,15 @@ int ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, } } + if (s->pass == 2) { + s->b++; + s->block += w4 * h4 * 64; + s->uvblock[0] += w4 * h4 * 16; + s->uvblock[1] += w4 * h4 * 16; + s->eob += w4 * h4 * 4; + s->uveob[0] += w4 * h4; + s->uveob[1] += w4 * h4; + } + return 0; } diff --git a/libavcodec/vp9mvs.c b/libavcodec/vp9mvs.c index 5edcb1903922f..dde0e84355acf 100644 --- a/libavcodec/vp9mvs.c +++ b/libavcodec/vp9mvs.c @@ -164,6 +164,9 @@ static void find_ref_mvs(VP9Context *s, if (s->use_last_frame_mvs) { VP9MVRefPair *mv = &s->frames[LAST_FRAME].mv[row * s->sb_cols * 8 + col]; + if (!s->last_uses_2pass) + ff_thread_await_progress(&s->frames[LAST_FRAME].tf, row >> 3, 0); + if (mv->ref[0] == ref) RETURN_MV(mv->mv[0]); else if (mv->ref[1] == ref) @@ -205,6 +208,7 @@ static void find_ref_mvs(VP9Context *s, if (s->use_last_frame_mvs) { VP9MVRefPair *mv = &s->frames[LAST_FRAME].mv[row * s->sb_cols * 8 + col]; + // no need to await_progress, because we already did that above if (mv->ref[0] != ref && mv->ref[0] >= 0) RETURN_SCALE_MV(mv->mv[0], s->signbias[mv->ref[0]] != s->signbias[ref]); From f2143c57b6a61fef382f3128138d8558a9bdecee Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 6 Aug 2016 10:07:53 +0200 Subject: [PATCH 0063/3374] vp9: reindent after last commit --- libavcodec/vp9.c | 240 +++++++++++++++++++++++------------------------ 1 file changed, 120 insertions(+), 120 deletions(-) diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 7989ca8d14b40..32d995f4a1297 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -1280,125 +1280,125 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, do { ptrdiff_t yoff = 0, uvoff = 0; - s->b = s->b_base; - s->block = s->block_base; - s->uvblock[0] = s->uvblock_base[0]; - s->uvblock[1] = s->uvblock_base[1]; - s->eob = s->eob_base; - s->uveob[0] = s->uveob_base[0]; - s->uveob[1] = s->uveob_base[1]; - - for (tile_row = 0; tile_row < s->tiling.tile_rows; tile_row++) { - set_tile_offset(&s->tiling.tile_row_start, &s->tiling.tile_row_end, - tile_row, s->tiling.log2_tile_rows, s->sb_rows); - - if (s->pass != 2) { - for (tile_col = 0; tile_col < s->tiling.tile_cols; tile_col++) { - int64_t tile_size; - - if (tile_col == s->tiling.tile_cols - 1 && - tile_row == s->tiling.tile_rows - 1) { - tile_size = size; - } else { - tile_size = AV_RB32(data); - data += 4; - size -= 4; - } - if (tile_size > size) { - ret = AVERROR_INVALIDDATA; - goto fail; - } - ff_vp56_init_range_decoder(&s->c_b[tile_col], data, tile_size); - if (vp56_rac_get_prob_branchy(&s->c_b[tile_col], 128)) { // marker bit - ret = AVERROR_INVALIDDATA; - goto fail; - } - data += tile_size; - size -= tile_size; - } - } - - for (row = s->tiling.tile_row_start; - row < s->tiling.tile_row_end; - row += 8, yoff += f->linesize[0] * 64, - uvoff += f->linesize[1] * 32) { - VP9Filter *lflvl = s->lflvl; - ptrdiff_t yoff2 = yoff, uvoff2 = uvoff; - - for (tile_col = 0; tile_col < s->tiling.tile_cols; tile_col++) { - set_tile_offset(&s->tiling.tile_col_start, - &s->tiling.tile_col_end, - tile_col, s->tiling.log2_tile_cols, s->sb_cols); - - memset(s->left_partition_ctx, 0, 8); - memset(s->left_skip_ctx, 0, 8); - if (s->keyframe || s->intraonly) - memset(s->left_mode_ctx, DC_PRED, 16); - else - memset(s->left_mode_ctx, NEARESTMV, 8); - memset(s->left_y_nnz_ctx, 0, 16); - memset(s->left_uv_nnz_ctx, 0, 16); - memset(s->left_segpred_ctx, 0, 8); - - memcpy(&s->c, &s->c_b[tile_col], sizeof(s->c)); - for (col = s->tiling.tile_col_start; - col < s->tiling.tile_col_end; - col += 8, yoff2 += 64, uvoff2 += 32, lflvl++) { - // FIXME integrate with lf code (i.e. zero after each - // use, similar to invtxfm coefficients, or similar) - if (s->pass != 1) - memset(lflvl->mask, 0, sizeof(lflvl->mask)); - - if (s->pass == 2) { - ret = decode_superblock_mem(avctx, row, col, lflvl, - yoff2, uvoff2, BL_64X64); + s->b = s->b_base; + s->block = s->block_base; + s->uvblock[0] = s->uvblock_base[0]; + s->uvblock[1] = s->uvblock_base[1]; + s->eob = s->eob_base; + s->uveob[0] = s->uveob_base[0]; + s->uveob[1] = s->uveob_base[1]; + + for (tile_row = 0; tile_row < s->tiling.tile_rows; tile_row++) { + set_tile_offset(&s->tiling.tile_row_start, &s->tiling.tile_row_end, + tile_row, s->tiling.log2_tile_rows, s->sb_rows); + + if (s->pass != 2) { + for (tile_col = 0; tile_col < s->tiling.tile_cols; tile_col++) { + int64_t tile_size; + + if (tile_col == s->tiling.tile_cols - 1 && + tile_row == s->tiling.tile_rows - 1) { + tile_size = size; } else { - ret = decode_subblock(avctx, row, col, lflvl, - yoff2, uvoff2, BL_64X64); + tile_size = AV_RB32(data); + data += 4; + size -= 4; + } + if (tile_size > size) { + ret = AVERROR_INVALIDDATA; + goto fail; } - if (ret < 0) + ff_vp56_init_range_decoder(&s->c_b[tile_col], data, tile_size); + if (vp56_rac_get_prob_branchy(&s->c_b[tile_col], 128)) { // marker bit + ret = AVERROR_INVALIDDATA; goto fail; + } + data += tile_size; + size -= tile_size; } - if (s->pass != 2) - memcpy(&s->c_b[tile_col], &s->c, sizeof(s->c)); } - if (s->pass == 1) - continue; - - // backup pre-loopfilter reconstruction data for intra - // prediction of next row of sb64s - if (row + 8 < s->rows) { - memcpy(s->intra_pred_data[0], - f->data[0] + yoff + - 63 * f->linesize[0], - 8 * s->cols); - memcpy(s->intra_pred_data[1], - f->data[1] + uvoff + - 31 * f->linesize[1], - 4 * s->cols); - memcpy(s->intra_pred_data[2], - f->data[2] + uvoff + - 31 * f->linesize[2], - 4 * s->cols); - } + for (row = s->tiling.tile_row_start; + row < s->tiling.tile_row_end; + row += 8, yoff += f->linesize[0] * 64, + uvoff += f->linesize[1] * 32) { + VP9Filter *lflvl = s->lflvl; + ptrdiff_t yoff2 = yoff, uvoff2 = uvoff; + + for (tile_col = 0; tile_col < s->tiling.tile_cols; tile_col++) { + set_tile_offset(&s->tiling.tile_col_start, + &s->tiling.tile_col_end, + tile_col, s->tiling.log2_tile_cols, s->sb_cols); + + memset(s->left_partition_ctx, 0, 8); + memset(s->left_skip_ctx, 0, 8); + if (s->keyframe || s->intraonly) + memset(s->left_mode_ctx, DC_PRED, 16); + else + memset(s->left_mode_ctx, NEARESTMV, 8); + memset(s->left_y_nnz_ctx, 0, 16); + memset(s->left_uv_nnz_ctx, 0, 16); + memset(s->left_segpred_ctx, 0, 8); + + memcpy(&s->c, &s->c_b[tile_col], sizeof(s->c)); + for (col = s->tiling.tile_col_start; + col < s->tiling.tile_col_end; + col += 8, yoff2 += 64, uvoff2 += 32, lflvl++) { + // FIXME integrate with lf code (i.e. zero after each + // use, similar to invtxfm coefficients, or similar) + if (s->pass != 1) + memset(lflvl->mask, 0, sizeof(lflvl->mask)); + + if (s->pass == 2) { + ret = decode_superblock_mem(avctx, row, col, lflvl, + yoff2, uvoff2, BL_64X64); + } else { + ret = decode_subblock(avctx, row, col, lflvl, + yoff2, uvoff2, BL_64X64); + } + if (ret < 0) + goto fail; + } + if (s->pass != 2) + memcpy(&s->c_b[tile_col], &s->c, sizeof(s->c)); + } - // loopfilter one row - if (s->filter.level) { - yoff2 = yoff; - uvoff2 = uvoff; - lflvl = s->lflvl; - for (col = 0; col < s->cols; - col += 8, yoff2 += 64, uvoff2 += 32, lflvl++) - loopfilter_subblock(avctx, lflvl, row, col, yoff2, uvoff2); - } + if (s->pass == 1) + continue; + + // backup pre-loopfilter reconstruction data for intra + // prediction of next row of sb64s + if (row + 8 < s->rows) { + memcpy(s->intra_pred_data[0], + f->data[0] + yoff + + 63 * f->linesize[0], + 8 * s->cols); + memcpy(s->intra_pred_data[1], + f->data[1] + uvoff + + 31 * f->linesize[1], + 4 * s->cols); + memcpy(s->intra_pred_data[2], + f->data[2] + uvoff + + 31 * f->linesize[2], + 4 * s->cols); + } + + // loopfilter one row + if (s->filter.level) { + yoff2 = yoff; + uvoff2 = uvoff; + lflvl = s->lflvl; + for (col = 0; col < s->cols; + col += 8, yoff2 += 64, uvoff2 += 32, lflvl++) + loopfilter_subblock(avctx, lflvl, row, col, yoff2, uvoff2); + } - // FIXME maybe we can make this more finegrained by running the - // loopfilter per-block instead of after each sbrow - // In fact that would also make intra pred left preparation easier? - ff_thread_report_progress(&s->frames[CUR_FRAME].tf, row >> 3, 0); + // FIXME maybe we can make this more finegrained by running the + // loopfilter per-block instead of after each sbrow + // In fact that would also make intra pred left preparation easier? + ff_thread_report_progress(&s->frames[CUR_FRAME].tf, row >> 3, 0); + } } - } if (s->pass < 2 && s->refreshctx && !s->parallelmode) { ff_vp9_adapt_probs(s); @@ -1584,16 +1584,16 @@ static int vp9_decode_update_thread_context(AVCodecContext *dst, const AVCodecCo } AVCodec ff_vp9_decoder = { - .name = "vp9", - .long_name = NULL_IF_CONFIG_SMALL("Google VP9"), - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_VP9, - .priv_data_size = sizeof(VP9Context), - .init = vp9_decode_init, - .decode = vp9_decode_packet, - .flush = vp9_decode_flush, - .close = vp9_decode_free, - .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .name = "vp9", + .long_name = NULL_IF_CONFIG_SMALL("Google VP9"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_VP9, + .priv_data_size = sizeof(VP9Context), + .init = vp9_decode_init, + .decode = vp9_decode_packet, + .flush = vp9_decode_flush, + .close = vp9_decode_free, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, .init_thread_copy = vp9_decode_init, .update_thread_context = vp9_decode_update_thread_context, }; From 602abe77b02f9702c18c2787d208fcfc9d94b70f Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 25 Jul 2016 00:33:01 +0200 Subject: [PATCH 0064/3374] avconv: Check the fifo allocation --- avconv_filter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avconv_filter.c b/avconv_filter.c index b78d3bdb94976..43308024f2535 100644 --- a/avconv_filter.c +++ b/avconv_filter.c @@ -181,7 +181,7 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in) fg->inputs[fg->nb_inputs - 1]->format = -1; fg->inputs[fg->nb_inputs - 1]->frame_queue = av_fifo_alloc(8 * sizeof(AVFrame*)); - if (!fg->inputs[fg->nb_inputs - 1]) + if (!fg->inputs[fg->nb_inputs - 1]->frame_queue) exit_program(1); GROW_ARRAY(ist->filters, ist->nb_filters); From f6d2fed811dea36c4ebaf991927e44c78eb0aca5 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Wed, 3 Aug 2016 04:21:41 +0200 Subject: [PATCH 0065/3374] avconv: Make sure that inputless filtergraphs are configured Unbreak `avconv -filter_complex testsrc`. Regression introduced in a3a0230a9870b9018dc7415ae5872784d524cfe5 --- avconv.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/avconv.c b/avconv.c index 43d67e8d17f47..59eb3009b1458 100644 --- a/avconv.c +++ b/avconv.c @@ -766,6 +766,15 @@ static int poll_filters(void) for (i = 0; i < nb_output_streams; i++) { int64_t pts = output_streams[i]->sync_opts; + if (output_streams[i]->filter && !output_streams[i]->filter->graph->graph && + !output_streams[i]->filter->graph->nb_inputs) { + ret = configure_filtergraph(output_streams[i]->filter->graph); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error reinitializing filters!\n"); + return ret; + } + } + if (!output_streams[i]->filter || output_streams[i]->finished || !output_streams[i]->filter->graph->graph) continue; From 6fc944e6136b050bf965f847bbfd69e1fe572f82 Mon Sep 17 00:00:00 2001 From: Sean McGovern Date: Fri, 12 Aug 2016 16:37:15 -0400 Subject: [PATCH 0066/3374] Prepare for 12_alpha1 Release --- RELEASE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASE b/RELEASE index e41f5e748e866..8053ae93a5e4b 100644 --- a/RELEASE +++ b/RELEASE @@ -1 +1 @@ -12_dev0 +12_alpha1 From 121f34d5f0c8d7d376829a467590fbbe4c228f4f Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Thu, 28 Jul 2016 23:28:30 +0100 Subject: [PATCH 0067/3374] hwcontext_vaapi: Try the first render node as the default DRM device If no string argument is supplied when av_hwdevice_ctx_create() is called to create a VAAPI device, we currently only try the default X11 display (that is, $DISPLAY) to find a device, and will therefore fail in the absence of an X server to connect to. Change the logic to also look for a device via the first DRM render node (that is, "/dev/dri/renderD128"), which is probably the right thing to use in most simple configurations which only have one DRM device. --- libavutil/hwcontext_vaapi.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index 506545cc28d3c..bba0c4d701149 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -924,22 +924,25 @@ static int vaapi_device_create(AVHWDeviceContext *ctx, const char *device, #endif #if HAVE_VAAPI_DRM - if (!display && device) { + if (!display) { // Try to open the device as a DRM path. - priv->drm_fd = open(device, O_RDWR); + // Default to using the first render node if the user did not + // supply a path. + const char *path = device ? device : "/dev/dri/renderD128"; + priv->drm_fd = open(path, O_RDWR); if (priv->drm_fd < 0) { av_log(ctx, AV_LOG_VERBOSE, "Cannot open DRM device %s.\n", - device); + path); } else { display = vaGetDisplayDRM(priv->drm_fd); if (!display) { av_log(ctx, AV_LOG_ERROR, "Cannot open a VA display " - "from DRM device %s.\n", device); + "from DRM device %s.\n", path); return AVERROR_UNKNOWN; } av_log(ctx, AV_LOG_VERBOSE, "Opened VA display via " - "DRM device %s.\n", device); + "DRM device %s.\n", path); } } #endif From 03adfe913062c6995136eb1ca51152b6d596c0f4 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sat, 6 Aug 2016 16:39:57 +0100 Subject: [PATCH 0068/3374] vaapi_h264: Constify pointers --- libavcodec/vaapi_h264.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c index 931357a6def13..2dd45e7428628 100644 --- a/libavcodec/vaapi_h264.c +++ b/libavcodec/vaapi_h264.c @@ -53,7 +53,7 @@ static void init_vaapi_pic(VAPictureH264 *va_pic) * supersedes pic's field type if nonzero. */ static void fill_vaapi_pic(VAPictureH264 *va_pic, - H264Picture *pic, + const H264Picture *pic, int pic_structure) { if (pic_structure == 0) @@ -91,7 +91,7 @@ typedef struct DPB { * available. The decoded picture buffer's size must be large enough * to receive the new VA API picture object. */ -static int dpb_add(DPB *dpb, H264Picture *pic) +static int dpb_add(DPB *dpb, const H264Picture *pic) { int i; @@ -123,7 +123,7 @@ static int dpb_add(DPB *dpb, H264Picture *pic) /** Fill in VA API reference frames array. */ static int fill_vaapi_ReferenceFrames(VAPictureParameterBufferH264 *pic_param, - H264Context *h) + const H264Context *h) { DPB dpb; int i; @@ -135,13 +135,13 @@ static int fill_vaapi_ReferenceFrames(VAPictureParameterBufferH264 *pic_param, init_vaapi_pic(&dpb.va_pics[i]); for (i = 0; i < h->short_ref_count; i++) { - H264Picture * const pic = h->short_ref[i]; + const H264Picture *pic = h->short_ref[i]; if (pic && pic->reference && dpb_add(&dpb, pic) < 0) return -1; } for (i = 0; i < 16; i++) { - H264Picture * const pic = h->long_ref[i]; + const H264Picture *pic = h->long_ref[i]; if (pic && pic->reference && dpb_add(&dpb, pic) < 0) return -1; } @@ -157,7 +157,7 @@ static int fill_vaapi_ReferenceFrames(VAPictureParameterBufferH264 *pic_param, * @param[in] ref_count The number of reference pictures in ref_list */ static void fill_vaapi_RefPicList(VAPictureH264 RefPicList[32], - H264Ref *ref_list, + const H264Ref *ref_list, unsigned int ref_count) { unsigned int i, n = 0; @@ -184,7 +184,7 @@ static void fill_vaapi_RefPicList(VAPictureH264 RefPicList[32], * @param[out] chroma_weight VA API plain chroma weight table * @param[out] chroma_offset VA API plain chroma offset table */ -static void fill_vaapi_plain_pred_weight_table(H264Context *h, +static void fill_vaapi_plain_pred_weight_table(const H264Context *h, int list, unsigned char *luma_weight_flag, short luma_weight[32], @@ -193,7 +193,7 @@ static void fill_vaapi_plain_pred_weight_table(H264Context *h, short chroma_weight[32][2], short chroma_offset[32][2]) { - H264SliceContext *sl = &h->slice_ctx[0]; + const H264SliceContext *sl = &h->slice_ctx[0]; unsigned int i, j; *luma_weight_flag = sl->pwt.luma_weight_flag[list]; @@ -226,7 +226,7 @@ static int vaapi_h264_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) { - H264Context * const h = avctx->priv_data; + const H264Context *h = avctx->priv_data; struct vaapi_context * const vactx = avctx->hwaccel_context; const PPS *pps = h->ps.pps; const SPS *sps = h->ps.sps; @@ -293,7 +293,7 @@ static int vaapi_h264_start_frame(AVCodecContext *avctx, static int vaapi_h264_end_frame(AVCodecContext *avctx) { struct vaapi_context * const vactx = avctx->hwaccel_context; - H264Context * const h = avctx->priv_data; + const H264Context *h = avctx->priv_data; H264SliceContext *sl = &h->slice_ctx[0]; int ret; @@ -317,8 +317,8 @@ static int vaapi_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { - H264Context * const h = avctx->priv_data; - H264SliceContext *sl = &h->slice_ctx[0]; + const H264Context *h = avctx->priv_data; + const H264SliceContext *sl = &h->slice_ctx[0]; VASliceParameterBufferH264 *slice_param; /* Fill in VASliceParameterBufferH264. */ From ee9061293e925916fe2e0b7c08fbbd1f981b1d29 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sat, 6 Aug 2016 16:40:14 +0100 Subject: [PATCH 0069/3374] vaapi_mpeg2: Constify pointers --- libavcodec/vaapi_mpeg2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/vaapi_mpeg2.c b/libavcodec/vaapi_mpeg2.c index cb7774581d432..459eb75f1c46b 100644 --- a/libavcodec/vaapi_mpeg2.c +++ b/libavcodec/vaapi_mpeg2.c @@ -26,21 +26,21 @@ #include "internal.h" /** Reconstruct bitstream f_code */ -static inline int mpeg2_get_f_code(MpegEncContext *s) +static inline int mpeg2_get_f_code(const MpegEncContext *s) { return (s->mpeg_f_code[0][0] << 12) | (s->mpeg_f_code[0][1] << 8) | (s->mpeg_f_code[1][0] << 4) | s->mpeg_f_code[1][1]; } /** Determine frame start: first field for field picture or frame picture */ -static inline int mpeg2_get_is_frame_start(MpegEncContext *s) +static inline int mpeg2_get_is_frame_start(const MpegEncContext *s) { return s->first_field || s->picture_structure == PICT_FRAME; } static int vaapi_mpeg2_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) { - struct MpegEncContext * const s = avctx->priv_data; + const MpegEncContext *s = avctx->priv_data; struct vaapi_context * const vactx = avctx->hwaccel_context; VAPictureParameterBufferMPEG2 *pic_param; VAIQMatrixBufferMPEG2 *iq_matrix; @@ -101,7 +101,7 @@ static int vaapi_mpeg2_start_frame(AVCodecContext *avctx, av_unused const uint8_ static int vaapi_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { - MpegEncContext * const s = avctx->priv_data; + const MpegEncContext *s = avctx->priv_data; VASliceParameterBufferMPEG2 *slice_param; GetBitContext gb; uint32_t quantiser_scale_code, intra_slice_flag, macroblock_offset; From 01d6f84f49a55fd591aa120960fce2b9dba92d0d Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sat, 6 Aug 2016 21:34:04 +0100 Subject: [PATCH 0070/3374] vaapi_vc1: Constify pointers --- libavcodec/vaapi_vc1.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c index 4022549dac784..efe950a56a42d 100644 --- a/libavcodec/vaapi_vc1.c +++ b/libavcodec/vaapi_vc1.c @@ -39,7 +39,7 @@ static int get_VAMvModeVC1(enum MVModes mv_mode) } /** Check whether the MVTYPEMB bitplane is present */ -static inline int vc1_has_MVTYPEMB_bitplane(VC1Context *v) +static inline int vc1_has_MVTYPEMB_bitplane(const VC1Context *v) { if (v->mv_type_is_raw) return 0; @@ -50,7 +50,7 @@ static inline int vc1_has_MVTYPEMB_bitplane(VC1Context *v) } /** Check whether the SKIPMB bitplane is present */ -static inline int vc1_has_SKIPMB_bitplane(VC1Context *v) +static inline int vc1_has_SKIPMB_bitplane(const VC1Context *v) { if (v->skip_is_raw) return 0; @@ -59,7 +59,7 @@ static inline int vc1_has_SKIPMB_bitplane(VC1Context *v) } /** Check whether the DIRECTMB bitplane is present */ -static inline int vc1_has_DIRECTMB_bitplane(VC1Context *v) +static inline int vc1_has_DIRECTMB_bitplane(const VC1Context *v) { if (v->dmb_is_raw) return 0; @@ -67,7 +67,7 @@ static inline int vc1_has_DIRECTMB_bitplane(VC1Context *v) } /** Check whether the ACPRED bitplane is present */ -static inline int vc1_has_ACPRED_bitplane(VC1Context *v) +static inline int vc1_has_ACPRED_bitplane(const VC1Context *v) { if (v->acpred_is_raw) return 0; @@ -77,7 +77,7 @@ static inline int vc1_has_ACPRED_bitplane(VC1Context *v) } /** Check whether the OVERFLAGS bitplane is present */ -static inline int vc1_has_OVERFLAGS_bitplane(VC1Context *v) +static inline int vc1_has_OVERFLAGS_bitplane(const VC1Context *v) { if (v->overflg_is_raw) return 0; @@ -89,9 +89,9 @@ static inline int vc1_has_OVERFLAGS_bitplane(VC1Context *v) } /** Reconstruct bitstream PTYPE (7.1.1.4, index into Table-35) */ -static int vc1_get_PTYPE(VC1Context *v) +static int vc1_get_PTYPE(const VC1Context *v) { - MpegEncContext * const s = &v->s; + const MpegEncContext *s = &v->s; switch (s->pict_type) { case AV_PICTURE_TYPE_I: return 0; case AV_PICTURE_TYPE_P: return v->p_frame_skipped ? 4 : 1; @@ -101,7 +101,7 @@ static int vc1_get_PTYPE(VC1Context *v) } /** Reconstruct bitstream MVMODE (7.1.1.32) */ -static inline VAMvModeVC1 vc1_get_MVMODE(VC1Context *v) +static inline VAMvModeVC1 vc1_get_MVMODE(const VC1Context *v) { if (v->s.pict_type == AV_PICTURE_TYPE_P || (v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type)) @@ -110,7 +110,7 @@ static inline VAMvModeVC1 vc1_get_MVMODE(VC1Context *v) } /** Reconstruct bitstream MVMODE2 (7.1.1.33) */ -static inline VAMvModeVC1 vc1_get_MVMODE2(VC1Context *v) +static inline VAMvModeVC1 vc1_get_MVMODE2(const VC1Context *v) { if (v->s.pict_type == AV_PICTURE_TYPE_P && v->mv_mode == MV_PMODE_INTENSITY_COMP) return get_VAMvModeVC1(v->mv_mode2); @@ -118,7 +118,7 @@ static inline VAMvModeVC1 vc1_get_MVMODE2(VC1Context *v) } /** Reconstruct bitstream TTFRM (7.1.1.41, Table-53) */ -static inline int vc1_get_TTFRM(VC1Context *v) +static inline int vc1_get_TTFRM(const VC1Context *v) { switch (v->ttfrm) { case TT_8X8: return 0; @@ -146,8 +146,8 @@ static inline void vc1_pack_bitplanes(uint8_t *bitplane, int n, const uint8_t *f static int vaapi_vc1_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) { - VC1Context * const v = avctx->priv_data; - MpegEncContext * const s = &v->s; + const VC1Context *v = avctx->priv_data; + const MpegEncContext *s = &v->s; struct vaapi_context * const vactx = avctx->hwaccel_context; VAPictureParameterBufferVC1 *pic_param; @@ -311,8 +311,8 @@ static int vaapi_vc1_start_frame(AVCodecContext *avctx, av_unused const uint8_t static int vaapi_vc1_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { - VC1Context * const v = avctx->priv_data; - MpegEncContext * const s = &v->s; + const VC1Context *v = avctx->priv_data; + const MpegEncContext *s = &v->s; VASliceParameterBufferVC1 *slice_param; /* Current bit buffer is beyond any marker for VC-1, so skip it */ From 5a667322f5cb0e77c15891fc06725c19d8f3314f Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sat, 6 Aug 2016 21:35:13 +0100 Subject: [PATCH 0071/3374] vaapi_vc1: Remove redundant version check The lowest supported VAAPI version is 0.34 (checked at configure time), so this test is no longer needed. --- libavcodec/vaapi_vc1.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c index efe950a56a42d..2fc03e68ee66a 100644 --- a/libavcodec/vaapi_vc1.c +++ b/libavcodec/vaapi_vc1.c @@ -171,9 +171,7 @@ static int vaapi_vc1_start_frame(AVCodecContext *avctx, av_unused const uint8_t pic_param->sequence_fields.bits.syncmarker = v->resync_marker; pic_param->sequence_fields.bits.rangered = v->rangered; pic_param->sequence_fields.bits.max_b_frames = s->avctx->max_b_frames; -#if VA_CHECK_VERSION(0,32,0) pic_param->sequence_fields.bits.profile = v->profile; -#endif pic_param->coded_width = s->avctx->coded_width; pic_param->coded_height = s->avctx->coded_height; pic_param->entrypoint_fields.value = 0; /* reset all bits */ From 00a0419c7f7ebce9010cba93b7ff67c9f1165815 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 29 Jul 2016 23:24:27 +0200 Subject: [PATCH 0072/3374] mathematics: Kill non-compiling disabled cruft --- libavutil/mathematics.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/libavutil/mathematics.c b/libavutil/mathematics.c index c9b24afeacde7..617726d89774e 100644 --- a/libavutil/mathematics.c +++ b/libavutil/mathematics.c @@ -58,7 +58,6 @@ int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd) else return a / c * b + (a % c * b + r) / c; } else { -#if 1 uint64_t a0 = a & 0xFFFFFFFF; uint64_t a1 = a >> 32; uint64_t b0 = b & 0xFFFFFFFF; @@ -82,14 +81,6 @@ int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd) } return t1; } -#else - AVInteger ai; - ai = av_mul_i(av_int2i(a), av_int2i(b)); - ai = av_add_i(ai, av_int2i(r)); - - return av_i2int(av_div_i(ai, av_int2i(c))); - } -#endif } int64_t av_rescale(int64_t a, int64_t b, int64_t c) From e4d5b55193109d08be47c42d320334546c006b51 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 2 Aug 2016 12:02:21 +0200 Subject: [PATCH 0073/3374] rangecoder: Kill non-compiling disabled cruft --- libavcodec/rangecoder.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/libavcodec/rangecoder.h b/libavcodec/rangecoder.h index 4c88169790828..2ead446398acd 100644 --- a/libavcodec/rangecoder.h +++ b/libavcodec/rangecoder.h @@ -117,7 +117,6 @@ static inline int get_rac(RangeCoder *c, uint8_t *const state) int range1 = (c->range * (*state)) >> 8; c->range -= range1; -#if 1 if (c->low < c->range) { *state = c->zero_state[*state]; refill(c); @@ -129,19 +128,6 @@ static inline int get_rac(RangeCoder *c, uint8_t *const state) refill(c); return 1; } -#else - { - int one_mask one_mask = (c->range - c->low - 1) >> 31; - - c->low -= c->range & one_mask; - c->range += (range1 - c->range) & one_mask; - - *state = c->zero_state[(*state) + (256 & one_mask)]; - } - refill(c); - - return one_mask & 1; -#endif } #endif /* AVCODEC_RANGECODER_H */ From d5fda00efa756387cffb4d7294691cd54cfe86cf Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 2 Aug 2016 12:00:03 +0200 Subject: [PATCH 0074/3374] mpeg4videoenc: Kill non-compiling disabled cruft --- libavcodec/mpeg4videoenc.c | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c index b694935bb2e03..8815ba85c4503 100644 --- a/libavcodec/mpeg4videoenc.c +++ b/libavcodec/mpeg4videoenc.c @@ -256,7 +256,6 @@ void ff_clean_mpeg4_qscales(MpegEncContext *s) */ static inline void mpeg4_encode_dc(PutBitContext *s, int level, int n) { -#if 1 /* DC will overflow if level is outside the [-255,255] range. */ level += 256; if (n < 4) { @@ -266,33 +265,6 @@ static inline void mpeg4_encode_dc(PutBitContext *s, int level, int n) /* chrominance */ put_bits(s, uni_DCtab_chrom_len[level], uni_DCtab_chrom_bits[level]); } -#else - int size, v; - /* find number of bits */ - size = 0; - v = abs(level); - while (v) { - v >>= 1; - size++; - } - - if (n < 4) { - /* luminance */ - put_bits(&s->pb, ff_mpeg4_DCtab_lum[size][1], ff_mpeg4_DCtab_lum[size][0]); - } else { - /* chrominance */ - put_bits(&s->pb, ff_mpeg4_DCtab_chrom[size][1], ff_mpeg4_DCtab_chrom[size][0]); - } - - /* encode remaining bits */ - if (size > 0) { - if (level < 0) - level = (-level) ^ ((1 << size) - 1); - put_bits(&s->pb, size, level); - if (size > 8) - put_bits(&s->pb, 1, 1); - } -#endif } static inline int mpeg4_get_dc_length(int level, int n) From aa37d2bf4505afc106e2a23c44afc722bb204a8e Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 30 Jul 2016 13:47:34 +0200 Subject: [PATCH 0075/3374] swscale: Kill non-compiling disabled cruft --- libswscale/swscale_internal.h | 6 ------ libswscale/utils.c | 7 ------- 2 files changed, 13 deletions(-) diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index a72ac0bd0b02e..84f8dd339f996 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -600,11 +600,6 @@ static av_always_inline int isRGB(enum AVPixelFormat pix_fmt) return (desc->flags & AV_PIX_FMT_FLAG_RGB); } -#if 0 // FIXME -#define isGray(x) \ - (!(av_pix_fmt_descriptors[x].flags & AV_PIX_FMT_FLAG_PAL) && \ - av_pix_fmt_descriptors[x].nb_components <= 2) -#else #define isGray(x) \ ((x) == AV_PIX_FMT_GRAY8 || \ (x) == AV_PIX_FMT_YA8 || \ @@ -612,7 +607,6 @@ static av_always_inline int isRGB(enum AVPixelFormat pix_fmt) (x) == AV_PIX_FMT_GRAY16LE || \ (x) == AV_PIX_FMT_YA16BE || \ (x) == AV_PIX_FMT_YA16LE) -#endif #define isRGBinInt(x) \ ((x) == AV_PIX_FMT_RGB48BE || \ diff --git a/libswscale/utils.c b/libswscale/utils.c index ba65e2a4551f0..c4fb7451ebb2f 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -372,13 +372,6 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, } coeff *= fone >> (30 + 24); } -#if 0 - else if (flags & SWS_X) { - double p = param ? param * 0.01 : 0.3; - coeff = d ? sin(d * M_PI) / (d * M_PI) : 1.0; - coeff *= pow(2.0, -p * d * d); - } -#endif else if (flags & SWS_X) { double A = param[0] != SWS_PARAM_DEFAULT ? param[0] : 1.0; double c; From a972fc1c0ab6e7f169f9145d6da46e8cedbc291c Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 2 Aug 2016 12:01:12 +0200 Subject: [PATCH 0076/3374] wma: Kill non-compiling disabled cruft --- libavcodec/wma.c | 10 ---------- libavcodec/wmaenc.c | 17 ----------------- 2 files changed, 27 deletions(-) diff --git a/libavcodec/wma.c b/libavcodec/wma.c index 85193ff3d497a..4067dff11aa5c 100644 --- a/libavcodec/wma.c +++ b/libavcodec/wma.c @@ -276,16 +276,6 @@ av_cold int ff_wma_init(AVCodecContext *avctx, int flags2) s->exponent_high_bands[k][j++] = end - start; } s->exponent_high_sizes[k] = j; -#if 0 - ff_tlog(s->avctx, "%5d: coefs_end=%d high_band_start=%d nb_high_bands=%d: ", - s->frame_len >> k, - s->coefs_end[k], - s->high_band_start[k], - s->exponent_high_sizes[k]); - for (j = 0; j < s->exponent_high_sizes[k]; j++) - ff_tlog(s->avctx, " %d", s->exponent_high_bands[k][j]); - ff_tlog(s->avctx, "\n"); -#endif /* 0 */ } } diff --git a/libavcodec/wmaenc.c b/libavcodec/wmaenc.c index e991bb89d48c3..800c000bfe8d5 100644 --- a/libavcodec/wmaenc.c +++ b/libavcodec/wmaenc.c @@ -386,7 +386,6 @@ static int encode_superframe(AVCodecContext *avctx, AVPacket *avpkt, return ret; } -#if 1 total_gain = 128; for (i = 64; i; i >>= 1) { int error = encode_frame(s, s->coefs, avpkt->data, avpkt->size, @@ -394,22 +393,6 @@ static int encode_superframe(AVCodecContext *avctx, AVPacket *avpkt, if (error < 0) total_gain -= i; } -#else - total_gain = 90; - best = encode_frame(s, s->coefs, avpkt->data, avpkt->size, total_gain); - for (i = 32; i; i >>= 1) { - int scoreL = encode_frame(s, s->coefs, avpkt->data, avpkt->size, total_gain - i); - int scoreR = encode_frame(s, s->coefs, avpkt->data, avpkt->size, total_gain + i); - av_log(NULL, AV_LOG_ERROR, "%d %d %d (%d)\n", scoreL, best, scoreR, total_gain); - if (scoreL < FFMIN(best, scoreR)) { - best = scoreL; - total_gain -= i; - } else if (scoreR < best) { - best = scoreR; - total_gain += i; - } - } -#endif /* 1 */ if ((i = encode_frame(s, s->coefs, avpkt->data, avpkt->size, total_gain)) >= 0) { av_log(avctx, AV_LOG_ERROR, "required frame size too large. please " From 562bec0e690760fb93deb2843a7237713103a191 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 30 Jul 2016 13:50:42 +0200 Subject: [PATCH 0077/3374] pnm_parser: Drop broken disabled cruft --- libavcodec/pnm_parser.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/libavcodec/pnm_parser.c b/libavcodec/pnm_parser.c index 1b81c2abf0d0e..03d2da9f96943 100644 --- a/libavcodec/pnm_parser.c +++ b/libavcodec/pnm_parser.c @@ -56,15 +56,6 @@ static int pnm_parse(AVCodecParserContext *s, AVCodecContext *avctx, } goto retry; } -#if 0 - if (pc->index && pc->index * 2 + AV_INPUT_BUFFER_PADDING_SIZE < pc->buffer_size && buf_size > pc->index) { - memcpy(pc->buffer + pc->index, buf, pc->index); - pc->index += pc->index; - buf += pc->index; - buf_size -= pc->index; - goto retry; - } -#endif next = END_NOT_FOUND; } else { next = pnmctx.bytestream - pnmctx.bytestream_start From dab2034b8679aaacd8aef832cdeb71d0ee8a3358 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 30 Jul 2016 13:50:58 +0200 Subject: [PATCH 0078/3374] roqvideoenc: Drop broken disabled cruft --- libavcodec/roqvideoenc.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c index eb021668a7517..6421ccc856136 100644 --- a/libavcodec/roqvideoenc.c +++ b/libavcodec/roqvideoenc.c @@ -735,21 +735,6 @@ static void reconstruct_and_encode_image(RoqContext *enc, RoqTempdata *tempData, /* Flush the remainder of the argument/type spool */ while (spool.typeSpoolLength) write_typecode(&spool, 0x0); - -#if 0 - uint8_t *fdata[3] = {enc->frame_to_enc->data[0], - enc->frame_to_enc->data[1], - enc->frame_to_enc->data[2]}; - uint8_t *cdata[3] = {enc->current_frame->data[0], - enc->current_frame->data[1], - enc->current_frame->data[2]}; - av_log(enc->avctx, AV_LOG_ERROR, "Expected distortion: %i Actual: %i\n", - dist, - block_sse(fdata, cdata, 0, 0, 0, 0, - enc->frame_to_enc->linesize, - enc->current_frame->linesize, - enc->width)); //WARNING: Square dimensions implied... -#endif } From d9442d13033a24b14ebae149dcdb42709430e2d9 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 30 Jul 2016 13:51:23 +0200 Subject: [PATCH 0079/3374] rm: Drop broken disabled cruft --- libavformat/rmdec.c | 13 ------------- libavformat/rmenc.c | 8 -------- 2 files changed, 21 deletions(-) diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c index 504f111ac031a..9774194e8e507 100644 --- a/libavformat/rmdec.c +++ b/libavformat/rmdec.c @@ -785,19 +785,6 @@ ff_rm_parse_packet (AVFormatContext *s, AVIOContext *pb, pkt->stream_index = st->index; -#if 0 - if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { - if(st->codecpar->codec_id == AV_CODEC_ID_RV20){ - int seq= 128*(pkt->data[2]&0x7F) + (pkt->data[3]>>1); - av_log(s, AV_LOG_DEBUG, "%d %"PRId64" %d\n", *timestamp, *timestamp*512LL/25, seq); - - seq |= (timestamp&~0x3FFF); - if(seq - timestamp > 0x2000) seq -= 0x4000; - if(seq - timestamp < -0x2000) seq += 0x4000; - } - } -#endif - pkt->pts = timestamp; if (flags & 2) pkt->flags |= AV_PKT_FLAG_KEY; diff --git a/libavformat/rmenc.c b/libavformat/rmenc.c index 8499e6384ca53..59118c94840a8 100644 --- a/libavformat/rmenc.c +++ b/libavformat/rmenc.c @@ -389,7 +389,6 @@ static int rm_write_video(AVFormatContext *s, const uint8_t *buf, int size, int /* Well, I spent some time finding the meaning of these bits. I am not sure I understood everything, but it works !! */ -#if 1 if (size > MAX_PACKET_SIZE) { avpriv_report_missing_feature(s, "Muxing packets larger than 64 kB"); return AVERROR(ENOSYS); @@ -411,13 +410,6 @@ static int rm_write_video(AVFormatContext *s, const uint8_t *buf, int size, int avio_wb16(pb, 0x4000 | size); /* total frame size */ avio_wb16(pb, 0x4000 | size); /* offset from the start or the end */ } -#else - /* full frame */ - write_packet_header(s, size + 6); - avio_w8(pb, 0xc0); - avio_wb16(pb, 0x4000 + size); /* total frame size */ - avio_wb16(pb, 0x4000 + packet_number * 126); /* position in stream */ -#endif avio_w8(pb, stream->nb_frames & 0xff); avio_write(pb, buf, size); From 263efc095e6c7ec2902119118b084cea29ea8916 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 30 Jul 2016 13:57:31 +0200 Subject: [PATCH 0080/3374] jfdct: Kill broken cruft --- libavcodec/jfdctint_template.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libavcodec/jfdctint_template.c b/libavcodec/jfdctint_template.c index 3ea2f5dadc4e0..67fb77b5e1201 100644 --- a/libavcodec/jfdctint_template.c +++ b/libavcodec/jfdctint_template.c @@ -69,12 +69,7 @@ #define GLOBAL(x) x #define RIGHT_SHIFT(x, n) ((x) >> (n)) #define MULTIPLY16C16(var,const) ((var)*(const)) - -#if 1 //def USE_ACCURATE_ROUNDING #define DESCALE(x,n) RIGHT_SHIFT((x) + (1 << ((n) - 1)), n) -#else -#define DESCALE(x,n) RIGHT_SHIFT(x, n) -#endif /* From 42c4c2d2a6dc48adb0e901ef5617acfba0a3a18e Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 30 Jul 2016 13:59:51 +0200 Subject: [PATCH 0081/3374] aac: Drop broken cruft --- libavcodec/aacsbr.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/libavcodec/aacsbr.c b/libavcodec/aacsbr.c index 3e3432c57ee5d..fc08079194938 100644 --- a/libavcodec/aacsbr.c +++ b/libavcodec/aacsbr.c @@ -918,14 +918,8 @@ static void read_sbr_extension(AACContext *ac, SpectralBandReplication *sbr, skip_bits_long(gb, *num_bits_left); // bs_fill_bits *num_bits_left = 0; } else { -#if 1 *num_bits_left -= ff_ps_read_data(ac->avctx, gb, &sbr->ps, *num_bits_left); ac->avctx->profile = FF_PROFILE_AAC_HE_V2; -#else - avpriv_report_missing_feature(ac->avctx, "Parametric Stereo"); - skip_bits_long(gb, *num_bits_left); // bs_fill_bits - *num_bits_left = 0; -#endif } break; default: From b96f0ab3d29cdd9ea9ddabfb2052f72bf8615661 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 30 Jul 2016 13:49:08 +0200 Subject: [PATCH 0082/3374] h264: Kill broken disabled cruft --- libavcodec/h264_ps.c | 31 ------------------------------- libavcodec/h264_refs.c | 9 --------- 2 files changed, 40 deletions(-) diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c index d1b428071305f..36902e8e7704f 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -713,37 +713,6 @@ int ff_h264_decode_picture_parameter_set(GetBitContext *gb, AVCodecContext *avct if (pps->slice_group_count > 1) { pps->mb_slice_group_map_type = get_ue_golomb(gb); av_log(avctx, AV_LOG_ERROR, "FMO not supported\n"); - switch (pps->mb_slice_group_map_type) { - case 0: -#if 0 - | for (i = 0; i <= num_slice_groups_minus1; i++) | | | - | run_length[i] |1 |ue(v) | -#endif - break; - case 2: -#if 0 - | for (i = 0; i < num_slice_groups_minus1; i++) { | | | - | top_left_mb[i] |1 |ue(v) | - | bottom_right_mb[i] |1 |ue(v) | - | } | | | -#endif - break; - case 3: - case 4: - case 5: -#if 0 - | slice_group_change_direction_flag |1 |u(1) | - | slice_group_change_rate_minus1 |1 |ue(v) | -#endif - break; - case 6: -#if 0 - | slice_group_id_cnt_minus1 |1 |ue(v) | - | for (i = 0; i <= slice_group_id_cnt_minus1; i++)| | | - | slice_group_id[i] |1 |u(v) | -#endif - break; - } } pps->ref_count[0] = get_ue_golomb(gb) + 1; pps->ref_count[1] = get_ue_golomb(gb) + 1; diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c index aa9e8825b95fb..3c55998424f0b 100644 --- a/libavcodec/h264_refs.c +++ b/libavcodec/h264_refs.c @@ -754,15 +754,6 @@ int ff_h264_decode_ref_pic_marking(H264SliceContext *sl, GetBitContext *gb, mmco[i].short_pic_num = (sl->curr_pic_num - get_ue_golomb(gb) - 1) & (sl->max_pic_num - 1); -#if 0 - if (mmco[i].short_pic_num >= h->short_ref_count || - !h->short_ref[mmco[i].short_pic_num]) { - av_log(s->avctx, AV_LOG_ERROR, - "illegal short ref in memory management control " - "operation %d\n", mmco); - return -1; - } -#endif } if (opcode == MMCO_SHORT2LONG || opcode == MMCO_LONG2UNUSED || opcode == MMCO_LONG || opcode == MMCO_SET_MAX_LONG) { From 17cb56b35672a2cd6ad7abe926e6cc772b8f4710 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 30 Jul 2016 15:00:32 +0200 Subject: [PATCH 0083/3374] ffv1: Remove broken disabled cruft --- libavcodec/ffv1dec.c | 5 ----- libavcodec/ffv1enc.c | 7 ------- 2 files changed, 12 deletions(-) diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index b72a9398773b4..d3169ec7c52ae 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -83,12 +83,7 @@ static inline int get_vlc_symbol(GetBitContext *gb, VlcState *const state, ff_dlog(NULL, "v:%d bias:%d error:%d drift:%d count:%d k:%d", v, state->bias, state->error_sum, state->drift, state->count, k); -#if 0 // JPEG LS - if (k == 0 && 2 * state->drift <= -state->count) - v ^= (-1); -#else v ^= ((2 * state->drift + state->count) >> 31); -#endif ret = fold(v + state->bias, bits); diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c index 3bc22ed1e51a4..0eeccfffb4f06 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -151,14 +151,7 @@ static inline void put_vlc_symbol(PutBitContext *pb, VlcState *const state, assert(k <= 13); -#if 0 // JPEG LS - if (k == 0 && 2 * state->drift <= -state->count) - code = v ^ (-1); - else - code = v; -#else code = v ^ ((2 * state->drift + state->count) >> 31); -#endif ff_dlog(NULL, "v:%d/%d bias:%d error:%d drift:%d count:%d k:%d\n", v, code, state->bias, state->error_sum, state->drift, state->count, k); From a4b1b5aa281cacde8351d9947b54ccf82ff10cd0 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 30 Jul 2016 14:11:05 +0200 Subject: [PATCH 0084/3374] wc3movie: Drop unused cruft --- libavformat/wc3movie.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libavformat/wc3movie.c b/libavformat/wc3movie.c index 2d47ad44b3172..f46b8c2f09b38 100644 --- a/libavformat/wc3movie.c +++ b/libavformat/wc3movie.c @@ -241,9 +241,6 @@ static int wc3_read_packet(AVFormatContext *s, case TEXT_TAG: /* subtitle chunk */ -#if 0 - avio_skip(pb, size); -#else if ((unsigned)size > sizeof(text) || (ret = avio_read(pb, text, size)) != size) ret = AVERROR(EIO); else { @@ -255,7 +252,6 @@ static int wc3_read_packet(AVFormatContext *s, i += text[i] + 1; av_log (s, AV_LOG_DEBUG, " fronsay: %s\n", &text[i + 1]); } -#endif break; case AUDI_TAG: From 34c22a9ca656603428b2c3490d1339c5a5966961 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 1 Aug 2016 19:59:58 +0200 Subject: [PATCH 0085/3374] faan(i)dct: Kill some disabled code --- libavcodec/faandct.c | 20 ++------------------ libavcodec/faanidct.c | 9 --------- 2 files changed, 2 insertions(+), 27 deletions(-) diff --git a/libavcodec/faandct.c b/libavcodec/faandct.c index 4053d69db1eb1..7888633d7cc51 100644 --- a/libavcodec/faandct.c +++ b/libavcodec/faandct.c @@ -97,17 +97,9 @@ static av_always_inline void row_fdct(FLOAT temp[64], int16_t *data) tmp5 += tmp6; tmp6 += tmp7; -#if 0 - { - FLOAT z5; - z5 = (tmp4 - tmp6) * A5; - z2 = tmp4 * A2 + z5; - z4 = tmp6 * A4 + z5; - } -#else z2= tmp4*(A2+A5) - tmp6*A5; z4= tmp6*(A4-A5) + tmp4*A5; -#endif + tmp5*=A1; z11= tmp7 + tmp5; @@ -159,17 +151,9 @@ void ff_faandct(int16_t *data) tmp5 += tmp6; tmp6 += tmp7; -#if 0 - { - FLOAT z5; - z5 = (tmp4 - tmp6) * A5; - z2 = tmp4 * A2 + z5; - z4 = tmp6 * A4 + z5; - } -#else z2= tmp4*(A2+A5) - tmp6*A5; z4= tmp6*(A4-A5) + tmp4*A5; -#endif + tmp5*=A1; z11= tmp7 + tmp5; diff --git a/libavcodec/faanidct.c b/libavcodec/faanidct.c index 2e9ce9ce1e249..b132f89d4d3b4 100644 --- a/libavcodec/faanidct.c +++ b/libavcodec/faanidct.c @@ -62,17 +62,8 @@ static inline void p8idct(int16_t data[64], FLOAT temp[64], uint8_t *dest, int s od07= s17 + s53; od25= (s17 - s53)*(2*A4); -#if 0 //these 2 are equivalent - { - FLOAT tmp0; - tmp0 = (d17 + d53) * (2 * A2); - od34 = d17 * (2 * B6) - tmp0; - od16 = d53 * (-2 * B2) + tmp0; - } -#else od34= d17*(2*(B6-A2)) - d53*(2*A2); od16= d53*(2*(A2-B2)) + d17*(2*A2); -#endif od16 -= od07; od25 -= od16; From b53d8c3ccfeff77874f5ca7c68136b6d87a0a69c Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 1 Aug 2016 20:21:04 +0200 Subject: [PATCH 0086/3374] mjpegdec: Drop disabled code --- libavcodec/mjpegdec.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 1f36b393a8e6e..c670f357c9e0d 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -1215,17 +1215,9 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) s->bottom_field = 1; else if (i == 1) s->bottom_field = 0; -#if 0 - skip_bits(&s->gb, 8); - skip_bits(&s->gb, 32); - skip_bits(&s->gb, 32); - len -= 10; -#endif goto out; } -// len -= 2; - if (id == AV_RL32("JFIF")) { int t_w, t_h, v1, v2; skip_bits(&s->gb, 8); /* the trailing zero-byte */ @@ -1297,16 +1289,6 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) len -= 4; /* Apple MJPEG-A */ if (id == AV_RL32("mjpg")) { -#if 0 - skip_bits(&s->gb, 32); /* field size */ - skip_bits(&s->gb, 32); /* pad field size */ - skip_bits(&s->gb, 32); /* next off */ - skip_bits(&s->gb, 32); /* quant off */ - skip_bits(&s->gb, 32); /* huff off */ - skip_bits(&s->gb, 32); /* image off */ - skip_bits(&s->gb, 32); /* scan off */ - skip_bits(&s->gb, 32); /* data off */ -#endif if (s->avctx->debug & FF_DEBUG_PICT_INFO) av_log(s->avctx, AV_LOG_INFO, "mjpeg: Apple MJPEG-A header found\n"); } From be3363f664d7314d55b42860bd4077154752d769 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 1 Aug 2016 20:39:25 +0200 Subject: [PATCH 0087/3374] nsv: Drop disabled cruft --- libavformat/nsvdec.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c index 1777a8b11cf18..05d5f8b910290 100644 --- a/libavformat/nsvdec.c +++ b/libavformat/nsvdec.c @@ -179,7 +179,6 @@ typedef struct NSVContext { int16_t avsync; AVRational framerate; uint32_t *nsvs_timestamps; - //DVDemuxContext* dv_demux; } NSVContext; static const AVCodecTag nsv_codec_video_tags[] = { @@ -230,8 +229,6 @@ static int nsv_resync(AVFormatContext *s) av_log(s, AV_LOG_TRACE, "%s(), offset = %"PRId64", state = %d\n", __FUNCTION__, avio_tell(pb), nsv->state); - //nsv->state = NSV_UNSYNC; - for (i = 0; i < NSV_MAX_RESYNC; i++) { if (pb->eof_reached) { av_log(s, AV_LOG_TRACE, "NSV EOF\n"); @@ -286,7 +283,6 @@ static int nsv_parse_NSVf_header(AVFormatContext *s) return -1; nsv->NSVf_end = size; - //s->file_size = (uint32_t)avio_rl32(pb); file_size = (uint32_t)avio_rl32(pb); av_log(s, AV_LOG_TRACE, "NSV NSVf chunk_size %u\n", size); av_log(s, AV_LOG_TRACE, "NSV NSVf file_size %u\n", file_size); From be1db21ba88fe86036fea9f8d2c1a5f47c2a0a7e Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 1 Aug 2016 20:15:07 +0200 Subject: [PATCH 0088/3374] mathops: Drop disabled alternative mid_pred() implementation --- libavcodec/mathops.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/libavcodec/mathops.h b/libavcodec/mathops.h index bd85dd79bec56..0afc82a0f5f3d 100644 --- a/libavcodec/mathops.h +++ b/libavcodec/mathops.h @@ -99,15 +99,6 @@ static av_always_inline unsigned UMULH(unsigned a, unsigned b){ #define mid_pred mid_pred static inline av_const int mid_pred(int a, int b, int c) { -#if 0 - int t= (a-b)&((a-b)>>31); - a-=t; - b+=t; - b-= (b-c)&((b-c)>>31); - b+= (a-b)&((a-b)>>31); - - return b; -#else if(a>b){ if(c>b){ if(c>a) b=a; @@ -120,7 +111,6 @@ static inline av_const int mid_pred(int a, int b, int c) } } return b; -#endif } #endif From f2f145f3032bc8808708a4bd694fbce5f1b8b63c Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 30 Jul 2016 15:30:46 +0200 Subject: [PATCH 0089/3374] msmpeg4: Drop disabled debug cruft --- libavcodec/msmpeg4dec.c | 7 ------- libavcodec/msmpeg4enc.c | 5 ----- 2 files changed, 12 deletions(-) diff --git a/libavcodec/msmpeg4dec.c b/libavcodec/msmpeg4dec.c index 06ae9be3655ca..a2d0ad4294cac 100644 --- a/libavcodec/msmpeg4dec.c +++ b/libavcodec/msmpeg4dec.c @@ -407,13 +407,6 @@ int ff_msmpeg4_decode_picture_header(MpegEncContext * s) av_log(s->avctx, AV_LOG_ERROR, "invalid picture type\n"); return -1; } -#if 0 -{ - static int had_i=0; - if(s->pict_type == AV_PICTURE_TYPE_I) had_i=1; - if(!had_i) return -1; -} -#endif s->chroma_qscale= s->qscale = get_bits(&s->gb, 5); if(s->qscale==0){ av_log(s->avctx, AV_LOG_ERROR, "invalid qscale\n"); diff --git a/libavcodec/msmpeg4enc.c b/libavcodec/msmpeg4enc.c index 21e38f985682b..6d353e5c0a8ce 100644 --- a/libavcodec/msmpeg4enc.c +++ b/libavcodec/msmpeg4enc.c @@ -314,11 +314,6 @@ void ff_msmpeg4_encode_motion(MpegEncContext * s, mx += 32; my += 32; -#if 0 - if ((unsigned)mx >= 64 || - (unsigned)my >= 64) - av_log(s->avctx, AV_LOG_ERROR, "error mx=%d my=%d\n", mx, my); -#endif mv = &ff_mv_tables[s->mv_table_index]; code = mv->table_mv_index[(mx << 6) | my]; From 0e285c2f908789e96e29bfd969ad5eaaa0eece65 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 1 Aug 2016 19:56:28 +0200 Subject: [PATCH 0090/3374] mpegvideo: Kill some disabled code --- libavcodec/mpegvideo_motion.c | 7 ------- libavcodec/mpegvideoencdsp.c | 11 ----------- 2 files changed, 18 deletions(-) diff --git a/libavcodec/mpegvideo_motion.c b/libavcodec/mpegvideo_motion.c index 958971427e376..8074dbaa9f742 100644 --- a/libavcodec/mpegvideo_motion.c +++ b/libavcodec/mpegvideo_motion.c @@ -279,13 +279,6 @@ void mpeg_motion_internal(MpegEncContext *s, uvsrc_x, uvsrc_y, v_edge_pos; ptrdiff_t uvlinesize, linesize; -#if 0 - if (s->quarter_sample) { - motion_x >>= 1; - motion_y >>= 1; - } -#endif - v_edge_pos = s->v_edge_pos >> field_based; linesize = s->current_picture.f->linesize[0] << field_based; uvlinesize = s->current_picture.f->linesize[1] << field_based; diff --git a/libavcodec/mpegvideoencdsp.c b/libavcodec/mpegvideoencdsp.c index 2011107041849..279d233fbcfd2 100644 --- a/libavcodec/mpegvideoencdsp.c +++ b/libavcodec/mpegvideoencdsp.c @@ -84,16 +84,6 @@ static int pix_norm1_c(uint8_t *pix, int line_size) for (i = 0; i < 16; i++) { for (j = 0; j < 16; j += 8) { -#if 0 - s += sq[pix[0]]; - s += sq[pix[1]]; - s += sq[pix[2]]; - s += sq[pix[3]]; - s += sq[pix[4]]; - s += sq[pix[5]]; - s += sq[pix[6]]; - s += sq[pix[7]]; -#else #if HAVE_FAST_64BIT register uint64_t x = *(uint64_t *) pix; s += sq[x & 0xff]; @@ -115,7 +105,6 @@ static int pix_norm1_c(uint8_t *pix, int line_size) s += sq[(x >> 8) & 0xff]; s += sq[(x >> 16) & 0xff]; s += sq[(x >> 24) & 0xff]; -#endif #endif pix += 8; } From 93fed46a92bab8be176d3e67be4354189a8dbe7f Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 1 Aug 2016 20:53:33 +0200 Subject: [PATCH 0091/3374] timefilter: test: Drop some disabled debug cruft --- libavdevice/tests/timefilter.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/libavdevice/tests/timefilter.c b/libavdevice/tests/timefilter.c index 8c7cba2cac205..9e8ec09662abc 100644 --- a/libavdevice/tests/timefilter.c +++ b/libavdevice/tests/timefilter.c @@ -71,20 +71,7 @@ int main(void) } } } while (better); -#if 0 - double lastfil = 9; - TimeFilter *tf = ff_timefilter_new(1, bestpar0, bestpar1); - for (i = 0; i < SAMPLES; i++) { - double filtered; - filtered = ff_timefilter_update(tf, samples[i], 1); - printf("%f %f %f %f\n", i - samples[i] + 10, filtered - samples[i], - samples[FFMAX(i, 1)] - samples[FFMAX(i - 1, 0)], filtered - lastfil); - lastfil = filtered; - } - ff_timefilter_destroy(tf); -#else printf(" [%f %f %9f]", bestpar0, bestpar1, best_error); -#endif } printf("\n"); } From 7effebde78977fafce935776153ea2f7c0981fa3 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 2 Aug 2016 11:22:11 +0200 Subject: [PATCH 0092/3374] dvbsubdec: Remove disabled, near-duplicate debug code --- libavcodec/dvbsubdec.c | 62 ++---------------------------------------- 1 file changed, 2 insertions(+), 60 deletions(-) diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c index bd12b38050f07..ccdfc01089a35 100644 --- a/libavcodec/dvbsubdec.c +++ b/libavcodec/dvbsubdec.c @@ -35,65 +35,7 @@ #define cm (ff_crop_tab + MAX_NEG_CROP) #ifdef DEBUG -#if 0 -static void png_save(const char *filename, uint8_t *bitmap, int w, int h, - uint32_t *rgba_palette) -{ - int x, y, v; - FILE *f; - char fname[40], fname2[40]; - char command[1024]; - - snprintf(fname, 40, "%s.ppm", filename); - - f = fopen(fname, "w"); - if (!f) { - perror(fname); - return; - } - fprintf(f, "P6\n" - "%d %d\n" - "%d\n", - w, h, 255); - for(y = 0; y < h; y++) { - for(x = 0; x < w; x++) { - v = rgba_palette[bitmap[y * w + x]]; - putc((v >> 16) & 0xff, f); - putc((v >> 8) & 0xff, f); - putc((v >> 0) & 0xff, f); - } - } - fclose(f); - - - snprintf(fname2, 40, "%s-a.pgm", filename); - - f = fopen(fname2, "w"); - if (!f) { - perror(fname2); - return; - } - fprintf(f, "P5\n" - "%d %d\n" - "%d\n", - w, h, 255); - for(y = 0; y < h; y++) { - for(x = 0; x < w; x++) { - v = rgba_palette[bitmap[y * w + x]]; - putc((v >> 24) & 0xff, f); - } - } - fclose(f); - - snprintf(command, 1024, "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename); - system(command); - - snprintf(command, 1024, "rm %s %s", fname, fname2); - system(command); -} -#endif - -static void png_save2(const char *filename, uint32_t *bitmap, int w, int h) +static void png_save(const char *filename, uint32_t *bitmap, int w, int h) { int x, y, v; FILE *f; @@ -1262,7 +1204,7 @@ static int save_display_set(DVBSubContext *ctx) snprintf(filename, sizeof(filename), "dvbs.%d", fileno_index); - png_save2(filename, pbuf, width, height); + png_save(filename, pbuf, width, height); av_free(pbuf); } From e2b9993558b6adee42dcc6eb385a14943aaca974 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 1 Aug 2016 20:50:48 +0200 Subject: [PATCH 0093/3374] simple_idct: x86: Drop disabled IDCT implementation This gem has been disabled since 2001. --- libavcodec/x86/simple_idct.c | 255 ----------------------------------- 1 file changed, 255 deletions(-) diff --git a/libavcodec/x86/simple_idct.c b/libavcodec/x86/simple_idct.c index 71763dbf75b0f..49784e2130f66 100644 --- a/libavcodec/x86/simple_idct.c +++ b/libavcodec/x86/simple_idct.c @@ -90,259 +90,6 @@ static inline void idct(int16_t *block) int16_t * const temp= (int16_t*)align_tmp; __asm__ volatile( -#if 0 //Alternative, simpler variant - -#define ROW_IDCT(src0, src4, src1, src5, dst, rounder, shift) \ - "movq " #src0 ", %%mm0 \n\t" /* R4 R0 r4 r0 */\ - "movq " #src4 ", %%mm1 \n\t" /* R6 R2 r6 r2 */\ - "movq " #src1 ", %%mm2 \n\t" /* R3 R1 r3 r1 */\ - "movq " #src5 ", %%mm3 \n\t" /* R7 R5 r7 r5 */\ - "movq 16(%2), %%mm4 \n\t" /* C4 C4 C4 C4 */\ - "pmaddwd %%mm0, %%mm4 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ - "movq 24(%2), %%mm5 \n\t" /* -C4 C4 -C4 C4 */\ - "pmaddwd %%mm5, %%mm0 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ - "movq 32(%2), %%mm5 \n\t" /* C6 C2 C6 C2 */\ - "pmaddwd %%mm1, %%mm5 \n\t" /* C6R6+C2R2 C6r6+C2r2 */\ - "movq 40(%2), %%mm6 \n\t" /* -C2 C6 -C2 C6 */\ - "pmaddwd %%mm6, %%mm1 \n\t" /* -C2R6+C6R2 -C2r6+C6r2 */\ - "movq 48(%2), %%mm7 \n\t" /* C3 C1 C3 C1 */\ - "pmaddwd %%mm2, %%mm7 \n\t" /* C3R3+C1R1 C3r3+C1r1 */\ - #rounder ", %%mm4 \n\t"\ - "movq %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ - "paddd %%mm5, %%mm4 \n\t" /* A0 a0 */\ - "psubd %%mm5, %%mm6 \n\t" /* A3 a3 */\ - "movq 56(%2), %%mm5 \n\t" /* C7 C5 C7 C5 */\ - "pmaddwd %%mm3, %%mm5 \n\t" /* C7R7+C5R5 C7r7+C5r5 */\ - #rounder ", %%mm0 \n\t"\ - "paddd %%mm0, %%mm1 \n\t" /* A1 a1 */\ - "paddd %%mm0, %%mm0 \n\t" \ - "psubd %%mm1, %%mm0 \n\t" /* A2 a2 */\ - "pmaddwd 64(%2), %%mm2 \n\t" /* -C7R3+C3R1 -C7r3+C3r1 */\ - "paddd %%mm5, %%mm7 \n\t" /* B0 b0 */\ - "movq 72(%2), %%mm5 \n\t" /* -C5 -C1 -C5 -C1 */\ - "pmaddwd %%mm3, %%mm5 \n\t" /* -C5R7-C1R5 -C5r7-C1r5 */\ - "paddd %%mm4, %%mm7 \n\t" /* A0+B0 a0+b0 */\ - "paddd %%mm4, %%mm4 \n\t" /* 2A0 2a0 */\ - "psubd %%mm7, %%mm4 \n\t" /* A0-B0 a0-b0 */\ - "paddd %%mm2, %%mm5 \n\t" /* B1 b1 */\ - "psrad $" #shift ", %%mm7 \n\t"\ - "psrad $" #shift ", %%mm4 \n\t"\ - "movq %%mm1, %%mm2 \n\t" /* A1 a1 */\ - "paddd %%mm5, %%mm1 \n\t" /* A1+B1 a1+b1 */\ - "psubd %%mm5, %%mm2 \n\t" /* A1-B1 a1-b1 */\ - "psrad $" #shift ", %%mm1 \n\t"\ - "psrad $" #shift ", %%mm2 \n\t"\ - "packssdw %%mm1, %%mm7 \n\t" /* A1+B1 a1+b1 A0+B0 a0+b0 */\ - "packssdw %%mm4, %%mm2 \n\t" /* A0-B0 a0-b0 A1-B1 a1-b1 */\ - "movq %%mm7, " #dst " \n\t"\ - "movq " #src1 ", %%mm1 \n\t" /* R3 R1 r3 r1 */\ - "movq 80(%2), %%mm4 \n\t" /* -C1 C5 -C1 C5 */\ - "movq %%mm2, 24+" #dst " \n\t"\ - "pmaddwd %%mm1, %%mm4 \n\t" /* -C1R3+C5R1 -C1r3+C5r1 */\ - "movq 88(%2), %%mm7 \n\t" /* C3 C7 C3 C7 */\ - "pmaddwd 96(%2), %%mm1 \n\t" /* -C5R3+C7R1 -C5r3+C7r1 */\ - "pmaddwd %%mm3, %%mm7 \n\t" /* C3R7+C7R5 C3r7+C7r5 */\ - "movq %%mm0, %%mm2 \n\t" /* A2 a2 */\ - "pmaddwd 104(%2), %%mm3 \n\t" /* -C1R7+C3R5 -C1r7+C3r5 */\ - "paddd %%mm7, %%mm4 \n\t" /* B2 b2 */\ - "paddd %%mm4, %%mm2 \n\t" /* A2+B2 a2+b2 */\ - "psubd %%mm4, %%mm0 \n\t" /* a2-B2 a2-b2 */\ - "psrad $" #shift ", %%mm2 \n\t"\ - "psrad $" #shift ", %%mm0 \n\t"\ - "movq %%mm6, %%mm4 \n\t" /* A3 a3 */\ - "paddd %%mm1, %%mm3 \n\t" /* B3 b3 */\ - "paddd %%mm3, %%mm6 \n\t" /* A3+B3 a3+b3 */\ - "psubd %%mm3, %%mm4 \n\t" /* a3-B3 a3-b3 */\ - "psrad $" #shift ", %%mm6 \n\t"\ - "packssdw %%mm6, %%mm2 \n\t" /* A3+B3 a3+b3 A2+B2 a2+b2 */\ - "movq %%mm2, 8+" #dst " \n\t"\ - "psrad $" #shift ", %%mm4 \n\t"\ - "packssdw %%mm0, %%mm4 \n\t" /* A2-B2 a2-b2 A3-B3 a3-b3 */\ - "movq %%mm4, 16+" #dst " \n\t"\ - -#define COL_IDCT(src0, src4, src1, src5, dst, shift) \ - "movq " #src0 ", %%mm0 \n\t" /* R4 R0 r4 r0 */\ - "movq " #src4 ", %%mm1 \n\t" /* R6 R2 r6 r2 */\ - "movq " #src1 ", %%mm2 \n\t" /* R3 R1 r3 r1 */\ - "movq " #src5 ", %%mm3 \n\t" /* R7 R5 r7 r5 */\ - "movq 16(%2), %%mm4 \n\t" /* C4 C4 C4 C4 */\ - "pmaddwd %%mm0, %%mm4 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ - "movq 24(%2), %%mm5 \n\t" /* -C4 C4 -C4 C4 */\ - "pmaddwd %%mm5, %%mm0 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ - "movq 32(%2), %%mm5 \n\t" /* C6 C2 C6 C2 */\ - "pmaddwd %%mm1, %%mm5 \n\t" /* C6R6+C2R2 C6r6+C2r2 */\ - "movq 40(%2), %%mm6 \n\t" /* -C2 C6 -C2 C6 */\ - "pmaddwd %%mm6, %%mm1 \n\t" /* -C2R6+C6R2 -C2r6+C6r2 */\ - "movq %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ - "movq 48(%2), %%mm7 \n\t" /* C3 C1 C3 C1 */\ - "pmaddwd %%mm2, %%mm7 \n\t" /* C3R3+C1R1 C3r3+C1r1 */\ - "paddd %%mm5, %%mm4 \n\t" /* A0 a0 */\ - "psubd %%mm5, %%mm6 \n\t" /* A3 a3 */\ - "movq %%mm0, %%mm5 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ - "paddd %%mm1, %%mm0 \n\t" /* A1 a1 */\ - "psubd %%mm1, %%mm5 \n\t" /* A2 a2 */\ - "movq 56(%2), %%mm1 \n\t" /* C7 C5 C7 C5 */\ - "pmaddwd %%mm3, %%mm1 \n\t" /* C7R7+C5R5 C7r7+C5r5 */\ - "pmaddwd 64(%2), %%mm2 \n\t" /* -C7R3+C3R1 -C7r3+C3r1 */\ - "paddd %%mm1, %%mm7 \n\t" /* B0 b0 */\ - "movq 72(%2), %%mm1 \n\t" /* -C5 -C1 -C5 -C1 */\ - "pmaddwd %%mm3, %%mm1 \n\t" /* -C5R7-C1R5 -C5r7-C1r5 */\ - "paddd %%mm4, %%mm7 \n\t" /* A0+B0 a0+b0 */\ - "paddd %%mm4, %%mm4 \n\t" /* 2A0 2a0 */\ - "psubd %%mm7, %%mm4 \n\t" /* A0-B0 a0-b0 */\ - "paddd %%mm2, %%mm1 \n\t" /* B1 b1 */\ - "psrad $" #shift ", %%mm7 \n\t"\ - "psrad $" #shift ", %%mm4 \n\t"\ - "movq %%mm0, %%mm2 \n\t" /* A1 a1 */\ - "paddd %%mm1, %%mm0 \n\t" /* A1+B1 a1+b1 */\ - "psubd %%mm1, %%mm2 \n\t" /* A1-B1 a1-b1 */\ - "psrad $" #shift ", %%mm0 \n\t"\ - "psrad $" #shift ", %%mm2 \n\t"\ - "packssdw %%mm7, %%mm7 \n\t" /* A0+B0 a0+b0 */\ - "movd %%mm7, " #dst " \n\t"\ - "packssdw %%mm0, %%mm0 \n\t" /* A1+B1 a1+b1 */\ - "movd %%mm0, 16+" #dst " \n\t"\ - "packssdw %%mm2, %%mm2 \n\t" /* A1-B1 a1-b1 */\ - "movd %%mm2, 96+" #dst " \n\t"\ - "packssdw %%mm4, %%mm4 \n\t" /* A0-B0 a0-b0 */\ - "movd %%mm4, 112+" #dst " \n\t"\ - "movq " #src1 ", %%mm0 \n\t" /* R3 R1 r3 r1 */\ - "movq 80(%2), %%mm4 \n\t" /* -C1 C5 -C1 C5 */\ - "pmaddwd %%mm0, %%mm4 \n\t" /* -C1R3+C5R1 -C1r3+C5r1 */\ - "movq 88(%2), %%mm7 \n\t" /* C3 C7 C3 C7 */\ - "pmaddwd 96(%2), %%mm0 \n\t" /* -C5R3+C7R1 -C5r3+C7r1 */\ - "pmaddwd %%mm3, %%mm7 \n\t" /* C3R7+C7R5 C3r7+C7r5 */\ - "movq %%mm5, %%mm2 \n\t" /* A2 a2 */\ - "pmaddwd 104(%2), %%mm3 \n\t" /* -C1R7+C3R5 -C1r7+C3r5 */\ - "paddd %%mm7, %%mm4 \n\t" /* B2 b2 */\ - "paddd %%mm4, %%mm2 \n\t" /* A2+B2 a2+b2 */\ - "psubd %%mm4, %%mm5 \n\t" /* a2-B2 a2-b2 */\ - "psrad $" #shift ", %%mm2 \n\t"\ - "psrad $" #shift ", %%mm5 \n\t"\ - "movq %%mm6, %%mm4 \n\t" /* A3 a3 */\ - "paddd %%mm0, %%mm3 \n\t" /* B3 b3 */\ - "paddd %%mm3, %%mm6 \n\t" /* A3+B3 a3+b3 */\ - "psubd %%mm3, %%mm4 \n\t" /* a3-B3 a3-b3 */\ - "psrad $" #shift ", %%mm6 \n\t"\ - "psrad $" #shift ", %%mm4 \n\t"\ - "packssdw %%mm2, %%mm2 \n\t" /* A2+B2 a2+b2 */\ - "packssdw %%mm6, %%mm6 \n\t" /* A3+B3 a3+b3 */\ - "movd %%mm2, 32+" #dst " \n\t"\ - "packssdw %%mm4, %%mm4 \n\t" /* A3-B3 a3-b3 */\ - "packssdw %%mm5, %%mm5 \n\t" /* A2-B2 a2-b2 */\ - "movd %%mm6, 48+" #dst " \n\t"\ - "movd %%mm4, 64+" #dst " \n\t"\ - "movd %%mm5, 80+" #dst " \n\t"\ - - -#define DC_COND_ROW_IDCT(src0, src4, src1, src5, dst, rounder, shift) \ - "movq " #src0 ", %%mm0 \n\t" /* R4 R0 r4 r0 */\ - "movq " #src4 ", %%mm1 \n\t" /* R6 R2 r6 r2 */\ - "movq " #src1 ", %%mm2 \n\t" /* R3 R1 r3 r1 */\ - "movq " #src5 ", %%mm3 \n\t" /* R7 R5 r7 r5 */\ - "movq "MANGLE(wm1010)", %%mm4 \n\t"\ - "pand %%mm0, %%mm4 \n\t"\ - "por %%mm1, %%mm4 \n\t"\ - "por %%mm2, %%mm4 \n\t"\ - "por %%mm3, %%mm4 \n\t"\ - "packssdw %%mm4,%%mm4 \n\t"\ - "movd %%mm4, %%eax \n\t"\ - "orl %%eax, %%eax \n\t"\ - "jz 1f \n\t"\ - "movq 16(%2), %%mm4 \n\t" /* C4 C4 C4 C4 */\ - "pmaddwd %%mm0, %%mm4 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ - "movq 24(%2), %%mm5 \n\t" /* -C4 C4 -C4 C4 */\ - "pmaddwd %%mm5, %%mm0 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ - "movq 32(%2), %%mm5 \n\t" /* C6 C2 C6 C2 */\ - "pmaddwd %%mm1, %%mm5 \n\t" /* C6R6+C2R2 C6r6+C2r2 */\ - "movq 40(%2), %%mm6 \n\t" /* -C2 C6 -C2 C6 */\ - "pmaddwd %%mm6, %%mm1 \n\t" /* -C2R6+C6R2 -C2r6+C6r2 */\ - "movq 48(%2), %%mm7 \n\t" /* C3 C1 C3 C1 */\ - "pmaddwd %%mm2, %%mm7 \n\t" /* C3R3+C1R1 C3r3+C1r1 */\ - #rounder ", %%mm4 \n\t"\ - "movq %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ - "paddd %%mm5, %%mm4 \n\t" /* A0 a0 */\ - "psubd %%mm5, %%mm6 \n\t" /* A3 a3 */\ - "movq 56(%2), %%mm5 \n\t" /* C7 C5 C7 C5 */\ - "pmaddwd %%mm3, %%mm5 \n\t" /* C7R7+C5R5 C7r7+C5r5 */\ - #rounder ", %%mm0 \n\t"\ - "paddd %%mm0, %%mm1 \n\t" /* A1 a1 */\ - "paddd %%mm0, %%mm0 \n\t" \ - "psubd %%mm1, %%mm0 \n\t" /* A2 a2 */\ - "pmaddwd 64(%2), %%mm2 \n\t" /* -C7R3+C3R1 -C7r3+C3r1 */\ - "paddd %%mm5, %%mm7 \n\t" /* B0 b0 */\ - "movq 72(%2), %%mm5 \n\t" /* -C5 -C1 -C5 -C1 */\ - "pmaddwd %%mm3, %%mm5 \n\t" /* -C5R7-C1R5 -C5r7-C1r5 */\ - "paddd %%mm4, %%mm7 \n\t" /* A0+B0 a0+b0 */\ - "paddd %%mm4, %%mm4 \n\t" /* 2A0 2a0 */\ - "psubd %%mm7, %%mm4 \n\t" /* A0-B0 a0-b0 */\ - "paddd %%mm2, %%mm5 \n\t" /* B1 b1 */\ - "psrad $" #shift ", %%mm7 \n\t"\ - "psrad $" #shift ", %%mm4 \n\t"\ - "movq %%mm1, %%mm2 \n\t" /* A1 a1 */\ - "paddd %%mm5, %%mm1 \n\t" /* A1+B1 a1+b1 */\ - "psubd %%mm5, %%mm2 \n\t" /* A1-B1 a1-b1 */\ - "psrad $" #shift ", %%mm1 \n\t"\ - "psrad $" #shift ", %%mm2 \n\t"\ - "packssdw %%mm1, %%mm7 \n\t" /* A1+B1 a1+b1 A0+B0 a0+b0 */\ - "packssdw %%mm4, %%mm2 \n\t" /* A0-B0 a0-b0 A1-B1 a1-b1 */\ - "movq %%mm7, " #dst " \n\t"\ - "movq " #src1 ", %%mm1 \n\t" /* R3 R1 r3 r1 */\ - "movq 80(%2), %%mm4 \n\t" /* -C1 C5 -C1 C5 */\ - "movq %%mm2, 24+" #dst " \n\t"\ - "pmaddwd %%mm1, %%mm4 \n\t" /* -C1R3+C5R1 -C1r3+C5r1 */\ - "movq 88(%2), %%mm7 \n\t" /* C3 C7 C3 C7 */\ - "pmaddwd 96(%2), %%mm1 \n\t" /* -C5R3+C7R1 -C5r3+C7r1 */\ - "pmaddwd %%mm3, %%mm7 \n\t" /* C3R7+C7R5 C3r7+C7r5 */\ - "movq %%mm0, %%mm2 \n\t" /* A2 a2 */\ - "pmaddwd 104(%2), %%mm3 \n\t" /* -C1R7+C3R5 -C1r7+C3r5 */\ - "paddd %%mm7, %%mm4 \n\t" /* B2 b2 */\ - "paddd %%mm4, %%mm2 \n\t" /* A2+B2 a2+b2 */\ - "psubd %%mm4, %%mm0 \n\t" /* a2-B2 a2-b2 */\ - "psrad $" #shift ", %%mm2 \n\t"\ - "psrad $" #shift ", %%mm0 \n\t"\ - "movq %%mm6, %%mm4 \n\t" /* A3 a3 */\ - "paddd %%mm1, %%mm3 \n\t" /* B3 b3 */\ - "paddd %%mm3, %%mm6 \n\t" /* A3+B3 a3+b3 */\ - "psubd %%mm3, %%mm4 \n\t" /* a3-B3 a3-b3 */\ - "psrad $" #shift ", %%mm6 \n\t"\ - "packssdw %%mm6, %%mm2 \n\t" /* A3+B3 a3+b3 A2+B2 a2+b2 */\ - "movq %%mm2, 8+" #dst " \n\t"\ - "psrad $" #shift ", %%mm4 \n\t"\ - "packssdw %%mm0, %%mm4 \n\t" /* A2-B2 a2-b2 A3-B3 a3-b3 */\ - "movq %%mm4, 16+" #dst " \n\t"\ - "jmp 2f \n\t"\ - "1: \n\t"\ - "pslld $16, %%mm0 \n\t"\ - "#paddd "MANGLE(d40000)", %%mm0 \n\t"\ - "psrad $13, %%mm0 \n\t"\ - "packssdw %%mm0, %%mm0 \n\t"\ - "movq %%mm0, " #dst " \n\t"\ - "movq %%mm0, 8+" #dst " \n\t"\ - "movq %%mm0, 16+" #dst " \n\t"\ - "movq %%mm0, 24+" #dst " \n\t"\ - "2: \n\t" - - -//IDCT( src0, src4, src1, src5, dst, rounder, shift) -ROW_IDCT( (%0), 8(%0), 16(%0), 24(%0), 0(%1),paddd 8(%2), 11) -/*ROW_IDCT( 32(%0), 40(%0), 48(%0), 56(%0), 32(%1), paddd (%2), 11) -ROW_IDCT( 64(%0), 72(%0), 80(%0), 88(%0), 64(%1), paddd (%2), 11) -ROW_IDCT( 96(%0),104(%0),112(%0),120(%0), 96(%1), paddd (%2), 11)*/ - -DC_COND_ROW_IDCT( 32(%0), 40(%0), 48(%0), 56(%0), 32(%1),paddd (%2), 11) -DC_COND_ROW_IDCT( 64(%0), 72(%0), 80(%0), 88(%0), 64(%1),paddd (%2), 11) -DC_COND_ROW_IDCT( 96(%0),104(%0),112(%0),120(%0), 96(%1),paddd (%2), 11) - - -//IDCT( src0, src4, src1, src5, dst, shift) -COL_IDCT( (%1), 64(%1), 32(%1), 96(%1), 0(%0), 20) -COL_IDCT( 8(%1), 72(%1), 40(%1), 104(%1), 4(%0), 20) -COL_IDCT( 16(%1), 80(%1), 48(%1), 112(%1), 8(%0), 20) -COL_IDCT( 24(%1), 88(%1), 56(%1), 120(%1), 12(%0), 20) - -#else - #define DC_COND_IDCT(src0, src4, src1, src5, dst, rounder, shift) \ "movq " #src0 ", %%mm0 \n\t" /* R4 R0 r4 r0 */\ "movq " #src4 ", %%mm1 \n\t" /* R6 R2 r6 r2 */\ @@ -1122,8 +869,6 @@ IDCT( 16(%1), 80(%1), 48(%1), 112(%1), 8(%0), 20) //IDCT( 24(%1), 88(%1), 56(%1), 120(%1), 12(%0), 20) -#endif - /* Input 00 40 04 44 20 60 24 64 From 014852e932dab6e9cf2a53e7a17ce8321f3e922c Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 1 Aug 2016 20:57:30 +0200 Subject: [PATCH 0094/3374] simple_idct: arm: Drop disabled code variant --- libavcodec/arm/simple_idct_armv5te.S | 7 ------- 1 file changed, 7 deletions(-) diff --git a/libavcodec/arm/simple_idct_armv5te.S b/libavcodec/arm/simple_idct_armv5te.S index bf509eeffcefa..b19683320ad3d 100644 --- a/libavcodec/arm/simple_idct_armv5te.S +++ b/libavcodec/arm/simple_idct_armv5te.S @@ -148,12 +148,6 @@ endfunc ldr a4, [a1] /* a4 = col[1:0] */ mov ip, #16384 sub ip, ip, #1 /* ip = W4 */ -#if 0 - mov v1, #(1<<(COL_SHIFT-1)) - smlabt v2, ip, a4, v1 /* v2 = W4*col[1] + (1<<(COL_SHIFT-1)) */ - smlabb v1, ip, a4, v1 /* v1 = W4*col[0] + (1<<(COL_SHIFT-1)) */ - ldr a4, [a1, #(16*4)] -#else mov v1, #((1<<(COL_SHIFT-1))/W4) /* this matches the C version */ add v2, v1, a4, asr #16 rsb v2, v2, v2, lsl #14 @@ -161,7 +155,6 @@ endfunc add v1, v1, a4, asr #16 ldr a4, [a1, #(16*4)] rsb v1, v1, v1, lsl #14 -#endif smulbb lr, ip, a4 smulbt a3, ip, a4 From 83b92a855e8e08bdec484e13ee5a7c8996224772 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 30 Jul 2016 14:52:20 +0200 Subject: [PATCH 0095/3374] golomb: Drop disabled cruft --- libavcodec/golomb.h | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h index 2d0be89e350e8..bf80fae117926 100644 --- a/libavcodec/golomb.h +++ b/libavcodec/golomb.h @@ -463,12 +463,6 @@ static inline void set_ue_golomb(PutBitContext *pb, int i) { assert(i >= 0); -#if 0 - if (i = 0) { - put_bits(pb, 1, 1); - return; - } -#endif if (i < 256) put_bits(pb, ff_ue_golomb_len[i], i + 1); else { @@ -496,19 +490,9 @@ static inline void set_te_golomb(PutBitContext *pb, int i, int range) */ static inline void set_se_golomb(PutBitContext *pb, int i) { -#if 0 - if (i <= 0) - i = -2 * i; - else - i = 2 * i - 1; -#elif 1 i = 2 * i - 1; if (i < 0) i ^= -1; //FIXME check if gcc does the right thing -#else - i = 2 * i - 1; - i ^= (i >> 31); -#endif set_ue_golomb(pb, i); } From f5d46d332258dcd8ca623019ece1d5e5bb74142b Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 14 Aug 2016 10:18:39 +0200 Subject: [PATCH 0096/3374] vmnc: check that subrectangles fit into their containing rectangles Fixes possible invalid writes with corrupted files. CC: libav-stable@libav.org Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind --- libavcodec/vmnc.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/libavcodec/vmnc.c b/libavcodec/vmnc.c index 3ef21341177a2..7a01f1e2e63b8 100644 --- a/libavcodec/vmnc.c +++ b/libavcodec/vmnc.c @@ -287,12 +287,24 @@ static int decode_hextile(VmncContext *c, uint8_t* dst, GetByteContext *gb, return AVERROR_INVALIDDATA; } for (k = 0; k < rects; k++) { + int rect_x, rect_y, rect_w, rect_h; if (color) fg = vmnc_get_pixel(gb, bpp, c->bigendian); xy = bytestream2_get_byte(gb); wh = bytestream2_get_byte(gb); - paint_rect(dst2, xy >> 4, xy & 0xF, - (wh>>4)+1, (wh & 0xF)+1, fg, bpp, stride); + + rect_x = xy >> 4; + rect_y = xy & 0xF; + rect_w = (wh >> 4) + 1; + rect_h = (wh & 0xF) + 1; + + if (rect_x + rect_w > bw || rect_y + rect_h > bh) { + av_log(c->avctx, AV_LOG_ERROR, "Invalid subrect\n"); + return AVERROR_INVALIDDATA; + } + + paint_rect(dst2, rect_x, rect_y, + rect_w, rect_h, fg, bpp, stride); } } } From 796dca027be09334d7bbf4f2ac1200e06bb054cb Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 14 Aug 2016 10:18:39 +0200 Subject: [PATCH 0097/3374] alac: do not return success if nothing was decoded If we encounter an END element before anything is decoded, we would return success even though the output frame has not been allocated, which is invalid. CC: libav-stable@libav.org Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind --- libavcodec/alac.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/alac.c b/libavcodec/alac.c index 1f24e1b41cc6a..0d2a7ca01df44 100644 --- a/libavcodec/alac.c +++ b/libavcodec/alac.c @@ -447,6 +447,10 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "no end tag found. incomplete packet.\n"); return AVERROR_INVALIDDATA; } + if (!alac->nb_samples) { + av_log(avctx, AV_LOG_ERROR, "No decodable data in the packet\n"); + return AVERROR_INVALIDDATA; + } if (avpkt->size * 8 - get_bits_count(&alac->gb) > 8) { av_log(avctx, AV_LOG_ERROR, "Error : %d bits left\n", From bba9d8bdfb208b0ec2ccf182530347151ee3528b Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 14 Aug 2016 10:18:39 +0200 Subject: [PATCH 0098/3374] qpeg: fix an off by 1 error in the MV check height - me_y is the line from which we read, so it must be strictly smaller than the frame height. Fixes possible invalid reads in corrupted files. Also, use a proper context for logging the error. CC: libav-stable@libav.org Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind --- libavcodec/qpeg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/qpeg.c b/libavcodec/qpeg.c index f549cd59fc5d5..3a2e56c0fb54b 100644 --- a/libavcodec/qpeg.c +++ b/libavcodec/qpeg.c @@ -161,9 +161,9 @@ static void qpeg_decode_inter(QpegContext *qctx, uint8_t *dst, /* check motion vector */ if ((me_x + filled < 0) || (me_x + me_w + filled > width) || - (height - me_y - me_h < 0) || (height - me_y > orig_height) || + (height - me_y - me_h < 0) || (height - me_y >= orig_height) || (filled + me_w > width) || (height - me_h < 0)) - av_log(NULL, AV_LOG_ERROR, "Bogus motion vector (%i,%i), block size %ix%i at %i,%i\n", + av_log(qctx->avctx, AV_LOG_ERROR, "Bogus motion vector (%i,%i), block size %ix%i at %i,%i\n", me_x, me_y, me_w, me_h, filled, height); else { /* do motion compensation */ From 409d1cd2c955485798f8b0b0147c2b899b9144ec Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 14 Aug 2016 10:18:39 +0200 Subject: [PATCH 0099/3374] cook: use the bytestream2 API for reading extradata Fixes possible invalid reads in corrupted files. CC: libav-stable@libav.org Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind --- libavcodec/cook.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/libavcodec/cook.c b/libavcodec/cook.c index f487db6a975b4..016b1d01bb8d3 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -1041,9 +1041,7 @@ static void dump_cook_context(COOKContext *q) static av_cold int cook_decode_init(AVCodecContext *avctx) { COOKContext *q = avctx->priv_data; - const uint8_t *edata_ptr = avctx->extradata; - const uint8_t *edata_ptr_end = edata_ptr + avctx->extradata_size; - int extradata_size = avctx->extradata_size; + GetByteContext gb; int s = 0; unsigned int channel_mask = 0; int samples_per_frame; @@ -1051,12 +1049,14 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) q->avctx = avctx; /* Take care of the codec specific extradata. */ - if (extradata_size < 8) { + if (avctx->extradata_size < 8) { av_log(avctx, AV_LOG_ERROR, "Necessary extradata missing!\n"); return AVERROR_INVALIDDATA; } av_log(avctx, AV_LOG_DEBUG, "codecdata_length=%d\n", avctx->extradata_size); + bytestream2_init(&gb, avctx->extradata, avctx->extradata_size); + /* Take data from the AVCodecContext (RM container). */ if (!avctx->channels) { av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n"); @@ -1068,21 +1068,15 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) ff_audiodsp_init(&q->adsp); - while (edata_ptr < edata_ptr_end) { + while (bytestream2_get_bytes_left(&gb)) { /* 8 for mono, 16 for stereo, ? for multichannel Swap to right endianness so we don't need to care later on. */ - if (extradata_size >= 8) { - q->subpacket[s].cookversion = bytestream_get_be32(&edata_ptr); - samples_per_frame = bytestream_get_be16(&edata_ptr); - q->subpacket[s].subbands = bytestream_get_be16(&edata_ptr); - extradata_size -= 8; - } - if (extradata_size >= 8) { - bytestream_get_be32(&edata_ptr); // Unknown unused - q->subpacket[s].js_subband_start = bytestream_get_be16(&edata_ptr); - q->subpacket[s].js_vlc_bits = bytestream_get_be16(&edata_ptr); - extradata_size -= 8; - } + q->subpacket[s].cookversion = bytestream2_get_be32(&gb); + samples_per_frame = bytestream2_get_be16(&gb); + q->subpacket[s].subbands = bytestream2_get_be16(&gb); + bytestream2_get_be32(&gb); // Unknown unused + q->subpacket[s].js_subband_start = bytestream2_get_be16(&gb); + q->subpacket[s].js_vlc_bits = bytestream2_get_be16(&gb); /* Initialize extradata related variables. */ q->subpacket[s].samples_per_channel = samples_per_frame / avctx->channels; @@ -1134,8 +1128,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) break; case MC_COOK: av_log(avctx, AV_LOG_DEBUG, "MULTI_CHANNEL\n"); - if (extradata_size >= 4) - channel_mask |= q->subpacket[s].channel_mask = bytestream_get_be32(&edata_ptr); + channel_mask |= q->subpacket[s].channel_mask = bytestream2_get_be32(&gb); if (av_get_channel_layout_nb_channels(q->subpacket[s].channel_mask) > 1) { q->subpacket[s].total_subbands = q->subpacket[s].subbands + From 15ee419b7abaf17f8c662c145fe93d3dbf43282b Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 14 Aug 2016 10:18:39 +0200 Subject: [PATCH 0100/3374] pcx: properly pad the scanline It is passed to the get_bits API, which requires buffers to be padded. Fixes possible invalid reads. CC: libav-stable@libav.org Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind --- libavcodec/pcx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/pcx.c b/libavcodec/pcx.c index aa69d510eaf25..77b2331f0e677 100644 --- a/libavcodec/pcx.c +++ b/libavcodec/pcx.c @@ -148,7 +148,7 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, ptr = p->data[0]; stride = p->linesize[0]; - scanline = av_malloc(bytes_per_scanline); + scanline = av_malloc(bytes_per_scanline + AV_INPUT_BUFFER_PADDING_SIZE); if (!scanline) return AVERROR(ENOMEM); From 221402c1c88b9d12130c6f5834029b535ee0e0c5 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 14 Aug 2016 10:18:39 +0200 Subject: [PATCH 0101/3374] pcx: check that the packet is large enough before reading the header Fixes possible invalid reads. CC: libav-stable@libav.org Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind --- libavcodec/pcx.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libavcodec/pcx.c b/libavcodec/pcx.c index 77b2331f0e677..2191ad1503677 100644 --- a/libavcodec/pcx.c +++ b/libavcodec/pcx.c @@ -28,6 +28,8 @@ #include "get_bits.h" #include "internal.h" +#define PCX_HEADER_SIZE 128 + /** * @return advanced src pointer */ @@ -85,6 +87,11 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, uint8_t *scanline; int ret = -1; + if (buf_size < PCX_HEADER_SIZE) { + av_log(avctx, AV_LOG_ERROR, "Packet too small\n"); + return AVERROR_INVALIDDATA; + } + if (buf[0] != 0x0a || buf[1] > 5) { av_log(avctx, AV_LOG_ERROR, "this is not PCX encoded data\n"); return AVERROR_INVALIDDATA; From 09b23786b3986502ee88d4907356979127169bdd Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 14 Aug 2016 10:18:39 +0200 Subject: [PATCH 0102/3374] pcx: use the bytestream2 API for reading from input Fixes possible invalid reads. CC: libav-stable@libav.org Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind --- libavcodec/pcx.c | 73 +++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 44 deletions(-) diff --git a/libavcodec/pcx.c b/libavcodec/pcx.c index 2191ad1503677..a2d49b454d9d9 100644 --- a/libavcodec/pcx.c +++ b/libavcodec/pcx.c @@ -33,41 +33,37 @@ /** * @return advanced src pointer */ -static const uint8_t *pcx_rle_decode(const uint8_t *src, - const uint8_t *end, - uint8_t *dst, - unsigned int bytes_per_scanline, - int compressed) +static void pcx_rle_decode(GetByteContext *gb, + uint8_t *dst, + unsigned int bytes_per_scanline, + int compressed) { unsigned int i = 0; unsigned char run, value; if (compressed) { - while (i < bytes_per_scanline && src < end) { + while (i < bytes_per_scanline && bytestream2_get_bytes_left(gb)) { run = 1; - value = *src++; - if (value >= 0xc0 && src < end) { + value = bytestream2_get_byte(gb); + if (value >= 0xc0 && bytestream2_get_bytes_left(gb)) { run = value & 0x3f; - value = *src++; + value = bytestream2_get_byte(gb); } while (i < bytes_per_scanline && run--) dst[i++] = value; } } else { - memcpy(dst, src, bytes_per_scanline); - src += bytes_per_scanline; + bytestream2_get_buffer(gb, dst, bytes_per_scanline); } - - return src; } -static void pcx_palette(const uint8_t **src, uint32_t *dst, +static void pcx_palette(GetByteContext *gb, uint32_t *dst, unsigned int pallen) { unsigned int i; for (i = 0; i < pallen; i++) - *dst++ = bytestream_get_be24(src); + *dst++ = bytestream2_get_be24(gb); if (pallen < 256) memset(dst, 0, (256 - pallen) * sizeof(*dst)); } @@ -78,12 +74,11 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; AVFrame *const p = data; + GetByteContext gb; int compressed, xmin, ymin, xmax, ymax; unsigned int w, h, bits_per_pixel, bytes_per_line, nplanes, stride, y, x, bytes_per_scanline; uint8_t *ptr; - const uint8_t *buf_end = buf + buf_size; - const uint8_t *bufstart = buf; uint8_t *scanline; int ret = -1; @@ -140,7 +135,7 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return AVERROR_INVALIDDATA; } - buf += 128; + bytestream2_init(&gb, buf + PCX_HEADER_SIZE, buf_size - PCX_HEADER_SIZE); if ((ret = ff_set_dimensions(avctx, w, h)) < 0) return ret; @@ -161,8 +156,7 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (nplanes == 3 && bits_per_pixel == 8) { for (y = 0; y < h; y++) { - buf = pcx_rle_decode(buf, buf_end, - scanline, bytes_per_scanline, compressed); + pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed); for (x = 0; x < w; x++) { ptr[3 * x] = scanline[x]; @@ -173,26 +167,12 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, ptr += stride; } } else if (nplanes == 1 && bits_per_pixel == 8) { - const uint8_t *palstart = bufstart + buf_size - 769; - - if (buf_size < 769) { - av_log(avctx, AV_LOG_ERROR, "File is too short\n"); - ret = avctx->err_recognition & AV_EF_EXPLODE ? - AVERROR_INVALIDDATA : buf_size; - goto end; - } - for (y = 0; y < h; y++, ptr += stride) { - buf = pcx_rle_decode(buf, buf_end, - scanline, bytes_per_scanline, compressed); + pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed); memcpy(ptr, scanline, w); } - if (buf != palstart) { - av_log(avctx, AV_LOG_WARNING, "image data possibly corrupted\n"); - buf = palstart; - } - if (*buf++ != 12) { + if (bytestream2_get_byte(&gb) != 12) { av_log(avctx, AV_LOG_ERROR, "expected palette after image data\n"); ret = avctx->err_recognition & AV_EF_EXPLODE ? AVERROR_INVALIDDATA : buf_size; @@ -204,8 +184,7 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, for (y = 0; y < h; y++) { init_get_bits(&s, scanline, bytes_per_scanline << 3); - buf = pcx_rle_decode(buf, buf_end, - scanline, bytes_per_scanline, compressed); + pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed); for (x = 0; x < w; x++) ptr[x] = get_bits(&s, bits_per_pixel); @@ -215,8 +194,7 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, int i; for (y = 0; y < h; y++) { - buf = pcx_rle_decode(buf, buf_end, - scanline, bytes_per_scanline, compressed); + pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed); for (x = 0; x < w; x++) { int m = 0x80 >> (x & 7), v = 0; @@ -231,15 +209,22 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } if (nplanes == 1 && bits_per_pixel == 8) { - pcx_palette(&buf, (uint32_t *)p->data[1], 256); + if (bytestream2_get_bytes_left(&gb) < 768) { + av_log(avctx, AV_LOG_ERROR, "Palette truncated\n"); + ret = AVERROR_INVALIDDATA; + goto end; + } + + pcx_palette(&gb, (uint32_t *)p->data[1], 256); } else if (bits_per_pixel < 8) { - const uint8_t *palette = bufstart + 16; - pcx_palette(&palette, (uint32_t *)p->data[1], 16); + GetByteContext gb1; + bytestream2_init(&gb1, avpkt->data + 16, 48); + pcx_palette(&gb1, (uint32_t *)p->data[1], 16); } *got_frame = 1; - ret = buf - bufstart; + ret = bytestream2_tell(&gb); end: av_free(scanline); return ret; From 33f10546ec012ad4e1054b57317885cded7e953e Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 14 Aug 2016 10:18:39 +0200 Subject: [PATCH 0103/3374] vc1: check that slices have a positive height Fixes possible invalid reads. CC: libav-stable@libav.org Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind --- libavcodec/vc1dec.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 3d042d0b0d550..b26fbf2efffce 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -881,6 +881,12 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, s->end_mb_y = (i == n_slices ) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height); else s->end_mb_y = (i <= n_slices1 + 1) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height); + + if (s->end_mb_y <= s->start_mb_y) { + av_log(v->s.avctx, AV_LOG_ERROR, "Invalid slice size\n"); + goto err; + } + ff_vc1_decode_blocks(v); if (i != n_slices) s->gb = slices[i].gb; From 6755eb5b212384e0599f7f2c5de42df49fff57de Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 14 Aug 2016 10:18:39 +0200 Subject: [PATCH 0104/3374] mss12: validate display dimensions The code currently reads the coded dimensions from the extradata, but expects the display dimensions to be set by the caller, and does not check that they are compatible (i.e. that the displayed size is smaller than the coded size). Make sure that when the display dimensions are set, they are also valid. Fixes possible invalid memory access. CC: libav-stable@libav.org Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind --- libavcodec/mss12.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libavcodec/mss12.c b/libavcodec/mss12.c index d4b621fc89b5a..b9bda16766166 100644 --- a/libavcodec/mss12.c +++ b/libavcodec/mss12.c @@ -588,6 +588,16 @@ av_cold int ff_mss12_decode_init(MSS12Context *c, int version, avctx->coded_width, avctx->coded_height); return AVERROR_INVALIDDATA; } + if (avctx->width || avctx->height) { + if (avctx->width <= 0 || avctx->width > avctx->coded_width || + avctx->height <= 0 || avctx->height > avctx->coded_height) { + av_log(avctx, AV_LOG_ERROR, "Invalid display dimensions\n"); + return AVERROR_INVALIDDATA; + } + } else { + avctx->width = avctx->coded_width; + avctx->height = avctx->coded_height; + } av_log(avctx, AV_LOG_DEBUG, "Encoder version %"PRIu32".%"PRIu32"\n", AV_RB32(avctx->extradata + 4), AV_RB32(avctx->extradata + 8)); From 46e3936fb04d06550151e667357065e3f646da1a Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 4 Aug 2016 17:01:03 +0200 Subject: [PATCH 0105/3374] configure: Set __MSVCRT_VERSION__to 0x0700 for MinGW This exposes some required functionality like _aligned_malloc() in the MinGW system headers, thus obviating the need for the memalign hack. --- configure | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configure b/configure index 9f836b7d38c56..e7bf5371f33cc 100755 --- a/configure +++ b/configure @@ -4003,6 +4003,8 @@ probe_libc(){ (__MINGW32_MAJOR_VERSION == 3 && __MINGW32_MINOR_VERSION >= 15)" || die "ERROR: MinGW32 runtime version must be >= 3.15." add_${pfx}cppflags -U__STRICT_ANSI__ -D__USE_MINGW_ANSI_STDIO=1 + check_${pfx}cpp_condition _mingw.h "__MSVCRT_VERSION__ < 0x0700__" && + add_${pfx}cppflags -D__MSVCRT_VERSION__=0x0700 eval test \$${pfx_no_}cc_type = "gcc" && add_${pfx}cppflags -D__printf__=__gnu_printf__ elif check_${pfx}cpp_condition crtversion.h "defined _VC_CRT_MAJOR_VERSION"; then From 24130234cd9dd733116d17b724ea4c8e12ce097a Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Fri, 19 Aug 2016 18:35:33 +0200 Subject: [PATCH 0106/3374] rtpdec_mpeg4: validate fmtp fields --- libavformat/rtpdec_mpeg4.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/libavformat/rtpdec_mpeg4.c b/libavformat/rtpdec_mpeg4.c index d5fea4f59c4cf..bc50da2a8bfc1 100644 --- a/libavformat/rtpdec_mpeg4.c +++ b/libavformat/rtpdec_mpeg4.c @@ -290,11 +290,22 @@ static int parse_fmtp(AVFormatContext *s, for (i = 0; attr_names[i].str; ++i) { if (!av_strcasecmp(attr, attr_names[i].str)) { if (attr_names[i].type == ATTR_NAME_TYPE_INT) { + int val = atoi(value); + if (val > 32) { + av_log(s, AV_LOG_ERROR, + "The %s field size is invalid (%d).", + attr, val); + return AVERROR_INVALIDDATA; + } *(int *)((char *)data+ - attr_names[i].offset) = atoi(value); - } else if (attr_names[i].type == ATTR_NAME_TYPE_STR) + attr_names[i].offset) = val; + } else if (attr_names[i].type == ATTR_NAME_TYPE_STR) { + char *val = av_strdup(value); + if (!val) + return AVERROR(ENOMEM); *(char **)((char *)data+ - attr_names[i].offset) = av_strdup(value); + attr_names[i].offset) = val; + } } } } From d42809f9835a4e9e5c7c63210abb09ad0ef19cfb Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sun, 24 Jul 2016 21:17:10 +0200 Subject: [PATCH 0107/3374] av1: Add codec_id and basic demuxing support Signed-off-by: Diego Biurrun --- libavcodec/avcodec.h | 1 + libavcodec/codec_desc.c | 7 +++++++ libavformat/matroska.c | 1 + libavformat/riff.c | 1 + 4 files changed, 10 insertions(+) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index ace761dd569b8..7a5f10f1c9833 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -391,6 +391,7 @@ enum AVCodecID { AV_CODEC_ID_RSCC, AV_CODEC_ID_MAGICYUV, AV_CODEC_ID_TRUEMOTION2RT, + AV_CODEC_ID_AV1, /* various PCM "codecs" */ AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 78d2cbc749eb7..18568c96227f0 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -1205,6 +1205,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0 Real Time"), .props = AV_CODEC_PROP_LOSSY, }, + { + .id = AV_CODEC_ID_AV1, + .type = AVMEDIA_TYPE_VIDEO, + .name = "av1", + .long_name = NULL_IF_CONFIG_SMALL("Alliance for Open Media AV1"), + .props = AV_CODEC_PROP_LOSSY, + }, /* image codecs */ { diff --git a/libavformat/matroska.c b/libavformat/matroska.c index c25c962363486..8842d7c4642e7 100644 --- a/libavformat/matroska.c +++ b/libavformat/matroska.c @@ -66,6 +66,7 @@ const CodecTags ff_mkv_codec_tags[]={ {"S_DVBSUB" , AV_CODEC_ID_DVB_SUBTITLE}, {"S_HDMV/PGS" , AV_CODEC_ID_HDMV_PGS_SUBTITLE}, + {"V_AV1" , AV_CODEC_ID_AV1}, {"V_DIRAC" , AV_CODEC_ID_DIRAC}, {"V_MJPEG" , AV_CODEC_ID_MJPEG}, {"V_MPEG1" , AV_CODEC_ID_MPEG1VIDEO}, diff --git a/libavformat/riff.c b/libavformat/riff.c index 1e1e4d8c618b9..54bef835ba41c 100644 --- a/libavformat/riff.c +++ b/libavformat/riff.c @@ -367,6 +367,7 @@ const AVCodecTag ff_codec_bmp_tags[] = { { AV_CODEC_ID_RSCC, MKTAG('R', 'S', 'C', 'C') }, { AV_CODEC_ID_RSCC, MKTAG('I', 'S', 'C', 'C') }, { AV_CODEC_ID_MAGICYUV, MKTAG('M', 'A', 'G', 'Y') }, + { AV_CODEC_ID_AV1, MKTAG('A', 'V', '0', '1') }, { AV_CODEC_ID_NONE, 0 } }; From 963b3ab11f98fcc4a311f0dc7b268890c5675da2 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 15 Aug 2016 19:24:05 +0200 Subject: [PATCH 0108/3374] doc: Document FATE option HWACCEL --- doc/fate.texi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/fate.texi b/doc/fate.texi index ae326fe7499d5..9b8d953d85db9 100644 --- a/doc/fate.texi +++ b/doc/fate.texi @@ -99,6 +99,11 @@ Specify or override the wrapper used to run the tests. @item GEN Set to @var{1} to generate the missing or mismatched references. + +@item HWACCEL +Specify which hardware acceleration to use while running regression tests, +by default none is used. + @end table @example From 6892df9294d93322d43255ada299507465bc93c8 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 23 Aug 2016 23:19:30 +0200 Subject: [PATCH 0109/3374] vp3: Change type of stride parameters to ptrdiff_t This avoids SIMD-optimized functions having to sign-extend their stride argument manually to be able to do pointer arithmetic. Also adjust parameter names to be "stride" everywhere. --- libavcodec/arm/vp3dsp_init_arm.c | 6 +++--- libavcodec/ppc/vp3dsp_altivec.c | 4 ++-- libavcodec/vp3dsp.c | 20 ++++++++++---------- libavcodec/vp3dsp.h | 10 +++++----- libavcodec/x86/vp3dsp.asm | 11 ----------- libavcodec/x86/vp3dsp_init.c | 15 +++++++-------- 6 files changed, 27 insertions(+), 39 deletions(-) diff --git a/libavcodec/arm/vp3dsp_init_arm.c b/libavcodec/arm/vp3dsp_init_arm.c index 11e1f1ca113ab..1c914343d33a0 100644 --- a/libavcodec/arm/vp3dsp_init_arm.c +++ b/libavcodec/arm/vp3dsp_init_arm.c @@ -23,9 +23,9 @@ #include "libavutil/arm/cpu.h" #include "libavcodec/vp3dsp.h" -void ff_vp3_idct_put_neon(uint8_t *dest, int line_size, int16_t *data); -void ff_vp3_idct_add_neon(uint8_t *dest, int line_size, int16_t *data); -void ff_vp3_idct_dc_add_neon(uint8_t *dest, int line_size, int16_t *data); +void ff_vp3_idct_put_neon(uint8_t *dest, ptrdiff_t stride, int16_t *data); +void ff_vp3_idct_add_neon(uint8_t *dest, ptrdiff_t stride, int16_t *data); +void ff_vp3_idct_dc_add_neon(uint8_t *dest, ptrdiff_t stride, int16_t *data); void ff_vp3_v_loop_filter_neon(uint8_t *, int, int *); void ff_vp3_h_loop_filter_neon(uint8_t *, int, int *); diff --git a/libavcodec/ppc/vp3dsp_altivec.c b/libavcodec/ppc/vp3dsp_altivec.c index 68e7102a539cf..1d907d7d2ed22 100644 --- a/libavcodec/ppc/vp3dsp_altivec.c +++ b/libavcodec/ppc/vp3dsp_altivec.c @@ -114,7 +114,7 @@ static inline vec_s16 M16(vec_s16 a, vec_s16 C) #define ADD8(a) vec_add(a, eight) #define SHIFT4(a) vec_sra(a, four) -static void vp3_idct_put_altivec(uint8_t *dst, int stride, int16_t block[64]) +static void vp3_idct_put_altivec(uint8_t *dst, ptrdiff_t stride, int16_t block[64]) { vec_u8 t; IDCT_START @@ -143,7 +143,7 @@ static void vp3_idct_put_altivec(uint8_t *dst, int stride, int16_t block[64]) memset(block, 0, sizeof(*block) * 64); } -static void vp3_idct_add_altivec(uint8_t *dst, int stride, int16_t block[64]) +static void vp3_idct_add_altivec(uint8_t *dst, ptrdiff_t stride, int16_t block[64]) { LOAD_ZERO; vec_u8 t, vdst; diff --git a/libavcodec/vp3dsp.c b/libavcodec/vp3dsp.c index ab65f2b763429..459441ea0757c 100644 --- a/libavcodec/vp3dsp.c +++ b/libavcodec/vp3dsp.c @@ -44,7 +44,7 @@ #define M(a, b) (((a) * (b)) >> 16) -static av_always_inline void idct(uint8_t *dst, int stride, +static av_always_inline void idct(uint8_t *dst, ptrdiff_t stride, int16_t *input, int type) { int16_t *ip = input; @@ -195,21 +195,21 @@ static av_always_inline void idct(uint8_t *dst, int stride, } } -static void vp3_idct_put_c(uint8_t *dest /* align 8 */, int line_size, +static void vp3_idct_put_c(uint8_t *dest /* align 8 */, ptrdiff_t stride, int16_t *block /* align 16 */) { - idct(dest, line_size, block, 1); + idct(dest, stride, block, 1); memset(block, 0, sizeof(*block) * 64); } -static void vp3_idct_add_c(uint8_t *dest /* align 8 */, int line_size, +static void vp3_idct_add_c(uint8_t *dest /* align 8 */, ptrdiff_t stride, int16_t *block /* align 16 */) { - idct(dest, line_size, block, 2); + idct(dest, stride, block, 2); memset(block, 0, sizeof(*block) * 64); } -static void vp3_idct_dc_add_c(uint8_t *dest /* align 8 */, int line_size, +static void vp3_idct_dc_add_c(uint8_t *dest /* align 8 */, ptrdiff_t stride, int16_t *block /* align 16 */) { int i, dc = (block[0] + 15) >> 5; @@ -223,17 +223,17 @@ static void vp3_idct_dc_add_c(uint8_t *dest /* align 8 */, int line_size, dest[5] = av_clip_uint8(dest[5] + dc); dest[6] = av_clip_uint8(dest[6] + dc); dest[7] = av_clip_uint8(dest[7] + dc); - dest += line_size; + dest += stride; } block[0] = 0; } -static void vp3_v_loop_filter_c(uint8_t *first_pixel, int stride, +static void vp3_v_loop_filter_c(uint8_t *first_pixel, ptrdiff_t stride, int *bounding_values) { unsigned char *end; int filter_value; - const int nstride = -stride; + const ptrdiff_t nstride = -stride; for (end = first_pixel + 8; first_pixel < end; first_pixel++) { filter_value = (first_pixel[2 * nstride] - first_pixel[stride]) + @@ -245,7 +245,7 @@ static void vp3_v_loop_filter_c(uint8_t *first_pixel, int stride, } } -static void vp3_h_loop_filter_c(uint8_t *first_pixel, int stride, +static void vp3_h_loop_filter_c(uint8_t *first_pixel, ptrdiff_t stride, int *bounding_values) { unsigned char *end; diff --git a/libavcodec/vp3dsp.h b/libavcodec/vp3dsp.h index 3099a7e13c664..010f905fce9d0 100644 --- a/libavcodec/vp3dsp.h +++ b/libavcodec/vp3dsp.h @@ -38,11 +38,11 @@ typedef struct VP3DSPContext { const uint8_t *b, ptrdiff_t stride, int h); - void (*idct_put)(uint8_t *dest, int line_size, int16_t *block); - void (*idct_add)(uint8_t *dest, int line_size, int16_t *block); - void (*idct_dc_add)(uint8_t *dest, int line_size, int16_t *block); - void (*v_loop_filter)(uint8_t *src, int stride, int *bounding_values); - void (*h_loop_filter)(uint8_t *src, int stride, int *bounding_values); + void (*idct_put)(uint8_t *dest, ptrdiff_t stride, int16_t *block); + void (*idct_add)(uint8_t *dest, ptrdiff_t stride, int16_t *block); + void (*idct_dc_add)(uint8_t *dest, ptrdiff_t stride, int16_t *block); + void (*v_loop_filter)(uint8_t *src, ptrdiff_t stride, int *bounding_values); + void (*h_loop_filter)(uint8_t *src, ptrdiff_t stride, int *bounding_values); } VP3DSPContext; void ff_vp3dsp_init(VP3DSPContext *c, int flags); diff --git a/libavcodec/x86/vp3dsp.asm b/libavcodec/x86/vp3dsp.asm index fc8a047224fa4..8587741f95259 100644 --- a/libavcodec/x86/vp3dsp.asm +++ b/libavcodec/x86/vp3dsp.asm @@ -104,9 +104,6 @@ SECTION .text INIT_MMX mmxext cglobal vp3_v_loop_filter, 3, 4 -%if ARCH_X86_64 - movsxd r1, r1d -%endif mov r3, r1 neg r1 movq m6, [r0+r1*2] @@ -121,9 +118,6 @@ cglobal vp3_v_loop_filter, 3, 4 RET cglobal vp3_h_loop_filter, 3, 4 -%if ARCH_X86_64 - movsxd r1, r1d -%endif lea r3, [r1*3] movd m6, [r0 -2] @@ -525,7 +519,6 @@ cglobal vp3_h_loop_filter, 3, 4 cglobal vp3_idct_put, 3, 4, 9 VP3_IDCT r2 - movsxdifnidn r1, r1d mova m4, [pb_80] lea r3, [r1*3] %assign %%i 0 @@ -582,7 +575,6 @@ cglobal vp3_idct_put, 3, 4, 9 cglobal vp3_idct_add, 3, 4, 9 VP3_IDCT r2 - movsxdifnidn r1, r1d lea r3, [r1*3] pxor m4, m4 %if mmsize == 16 @@ -689,9 +681,6 @@ vp3_idct_funcs INIT_MMX mmxext cglobal vp3_idct_dc_add, 3, 4 -%if ARCH_X86_64 - movsxd r1, r1d -%endif movsx r3, word [r2] mov word [r2], 0 lea r2, [r1*3] diff --git a/libavcodec/x86/vp3dsp_init.c b/libavcodec/x86/vp3dsp_init.c index b320dc5db93a4..043e10f720c9c 100644 --- a/libavcodec/x86/vp3dsp_init.c +++ b/libavcodec/x86/vp3dsp_init.c @@ -25,18 +25,17 @@ #include "libavcodec/vp3dsp.h" #include "config.h" -void ff_vp3_idct_put_mmx(uint8_t *dest, int line_size, int16_t *block); -void ff_vp3_idct_add_mmx(uint8_t *dest, int line_size, int16_t *block); +void ff_vp3_idct_put_mmx(uint8_t *dest, ptrdiff_t stride, int16_t *block); +void ff_vp3_idct_add_mmx(uint8_t *dest, ptrdiff_t stride, int16_t *block); -void ff_vp3_idct_put_sse2(uint8_t *dest, int line_size, int16_t *block); -void ff_vp3_idct_add_sse2(uint8_t *dest, int line_size, int16_t *block); +void ff_vp3_idct_put_sse2(uint8_t *dest, ptrdiff_t stride, int16_t *block); +void ff_vp3_idct_add_sse2(uint8_t *dest, ptrdiff_t stride, int16_t *block); -void ff_vp3_idct_dc_add_mmxext(uint8_t *dest, int line_size, - int16_t *block); +void ff_vp3_idct_dc_add_mmxext(uint8_t *dest, ptrdiff_t stride, int16_t *block); -void ff_vp3_v_loop_filter_mmxext(uint8_t *src, int stride, +void ff_vp3_v_loop_filter_mmxext(uint8_t *src, ptrdiff_t stride, int *bounding_values); -void ff_vp3_h_loop_filter_mmxext(uint8_t *src, int stride, +void ff_vp3_h_loop_filter_mmxext(uint8_t *src, ptrdiff_t stride, int *bounding_values); av_cold void ff_vp3dsp_init_x86(VP3DSPContext *c, int flags) From d9d26a3674f31f482f54e936fcb382160830877a Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 23 Aug 2016 23:23:45 +0200 Subject: [PATCH 0110/3374] vp56: Change type of stride parameters to ptrdiff_t This avoids SIMD-optimized functions having to sign-extend their line size argument manually to be able to do pointer arithmetic. --- libavcodec/arm/vp6dsp_init_arm.c | 4 ++-- libavcodec/vp56.h | 4 ++-- libavcodec/vp56dsp.c | 3 ++- libavcodec/vp56dsp.h | 10 ++++++---- libavcodec/vp6.c | 8 ++++---- libavcodec/vp6dsp.c | 2 +- libavcodec/x86/vp6dsp.asm | 5 +---- libavcodec/x86/vp6dsp_init.c | 4 ++-- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/libavcodec/arm/vp6dsp_init_arm.c b/libavcodec/arm/vp6dsp_init_arm.c index 4ec41ed9f1d79..235b0b6bf3ae2 100644 --- a/libavcodec/arm/vp6dsp_init_arm.c +++ b/libavcodec/arm/vp6dsp_init_arm.c @@ -25,8 +25,8 @@ #include "libavcodec/avcodec.h" #include "libavcodec/vp56dsp.h" -void ff_vp6_edge_filter_hor_neon(uint8_t *yuv, int stride, int t); -void ff_vp6_edge_filter_ver_neon(uint8_t *yuv, int stride, int t); +void ff_vp6_edge_filter_hor_neon(uint8_t *yuv, ptrdiff_t stride, int t); +void ff_vp6_edge_filter_ver_neon(uint8_t *yuv, ptrdiff_t stride, int t); av_cold void ff_vp6dsp_init_arm(VP56DSPContext *s, enum AVCodecID codec) { diff --git a/libavcodec/vp56.h b/libavcodec/vp56.h index f2ed770b85a82..52fe3182f4a69 100644 --- a/libavcodec/vp56.h +++ b/libavcodec/vp56.h @@ -72,7 +72,7 @@ typedef struct VP56mv { typedef void (*VP56ParseVectorAdjustment)(VP56Context *s, VP56mv *vect); typedef void (*VP56Filter)(VP56Context *s, uint8_t *dst, uint8_t *src, - int offset1, int offset2, int stride, + int offset1, int offset2, ptrdiff_t stride, VP56mv mv, int mask, int select, int luma); typedef void (*VP56ParseCoeff)(VP56Context *s); typedef void (*VP56DefaultModelsInit)(VP56Context *s); @@ -178,7 +178,7 @@ struct vp56_context { int flip; /* are we flipping ? */ int frbi; /* first row block index in MB */ int srbi; /* second row block index in MB */ - int stride[4]; /* stride for each plan */ + ptrdiff_t stride[4]; /* stride for each plan */ const uint8_t *vp56_coord_div; VP56ParseVectorAdjustment parse_vector_adjustment; diff --git a/libavcodec/vp56dsp.c b/libavcodec/vp56dsp.c index 5e09d2414e6b9..297534bbddd25 100644 --- a/libavcodec/vp56dsp.c +++ b/libavcodec/vp56dsp.c @@ -58,7 +58,8 @@ static int vp6_adjust(int v, int t) #define VP56_EDGE_FILTER(pfx, suf, pix_inc, line_inc) \ -static void pfx##_edge_filter_##suf(uint8_t *yuv, int stride, int t) \ +static void pfx ## _edge_filter_ ## suf(uint8_t *yuv, ptrdiff_t stride, \ + int t) \ { \ int pix2_inc = 2 * pix_inc; \ int i, v; \ diff --git a/libavcodec/vp56dsp.h b/libavcodec/vp56dsp.h index 389d35901ccab..d52ee660dbbd7 100644 --- a/libavcodec/vp56dsp.h +++ b/libavcodec/vp56dsp.h @@ -21,18 +21,20 @@ #ifndef AVCODEC_VP56DSP_H #define AVCODEC_VP56DSP_H +#include #include + #include "avcodec.h" typedef struct VP56DSPContext { - void (*edge_filter_hor)(uint8_t *yuv, int stride, int t); - void (*edge_filter_ver)(uint8_t *yuv, int stride, int t); + void (*edge_filter_hor)(uint8_t *yuv, ptrdiff_t stride, int t); + void (*edge_filter_ver)(uint8_t *yuv, ptrdiff_t stride, int t); - void (*vp6_filter_diag4)(uint8_t *dst, uint8_t *src, int stride, + void (*vp6_filter_diag4)(uint8_t *dst, uint8_t *src, ptrdiff_t stride, const int16_t *h_weights,const int16_t *v_weights); } VP56DSPContext; -void ff_vp6_filter_diag4_c(uint8_t *dst, uint8_t *src, int stride, +void ff_vp6_filter_diag4_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride, const int16_t *h_weights, const int16_t *v_weights); void ff_vp56dsp_init(VP56DSPContext *s, enum AVCodecID codec); diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c index c48c2b81802ee..aa0d09effbc81 100644 --- a/libavcodec/vp6.c +++ b/libavcodec/vp6.c @@ -514,7 +514,7 @@ static void vp6_parse_coeff(VP56Context *s) } } -static int vp6_block_variance(uint8_t *src, int stride) +static int vp6_block_variance(uint8_t *src, ptrdiff_t stride) { int sum = 0, square_sum = 0; int y, x; @@ -529,7 +529,7 @@ static int vp6_block_variance(uint8_t *src, int stride) return (16*square_sum - sum*sum) >> 8; } -static void vp6_filter_hv4(uint8_t *dst, uint8_t *src, int stride, +static void vp6_filter_hv4(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int delta, const int16_t *weights) { int x, y; @@ -547,7 +547,7 @@ static void vp6_filter_hv4(uint8_t *dst, uint8_t *src, int stride, } static void vp6_filter_diag2(VP56Context *s, uint8_t *dst, uint8_t *src, - int stride, int h_weight, int v_weight) + ptrdiff_t stride, int h_weight, int v_weight) { uint8_t *tmp = s->edge_emu_buffer+16; s->h264chroma.put_h264_chroma_pixels_tab[0](tmp, src, stride, 9, h_weight, 0); @@ -555,7 +555,7 @@ static void vp6_filter_diag2(VP56Context *s, uint8_t *dst, uint8_t *src, } static void vp6_filter(VP56Context *s, uint8_t *dst, uint8_t *src, - int offset1, int offset2, int stride, + int offset1, int offset2, ptrdiff_t stride, VP56mv mv, int mask, int select, int luma) { int filter4 = 0; diff --git a/libavcodec/vp6dsp.c b/libavcodec/vp6dsp.c index 54a96ed13aac4..c9968f28cf350 100644 --- a/libavcodec/vp6dsp.c +++ b/libavcodec/vp6dsp.c @@ -27,7 +27,7 @@ #include "vp56dsp.h" -void ff_vp6_filter_diag4_c(uint8_t *dst, uint8_t *src, int stride, +void ff_vp6_filter_diag4_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride, const int16_t *h_weights, const int16_t *v_weights) { int x, y; diff --git a/libavcodec/x86/vp6dsp.asm b/libavcodec/x86/vp6dsp.asm index 80f8ca5f38f46..b667d38aeae57 100644 --- a/libavcodec/x86/vp6dsp.asm +++ b/libavcodec/x86/vp6dsp.asm @@ -115,7 +115,7 @@ SECTION .text %endmacro %macro vp6_filter_diag4 0 -; void ff_vp6_filter_diag4_(uint8_t *dst, uint8_t *src, int stride, +; void ff_vp6_filter_diag4_(uint8_t *dst, uint8_t *src, ptrdiff_t stride, ; const int16_t h_weight[4], const int16_t v_weights[4]) cglobal vp6_filter_diag4, 5, 7, 8 mov r5, rsp ; backup stack pointer @@ -126,9 +126,6 @@ cglobal vp6_filter_diag4, 5, 7, 8 sub rsp, 8*15 movq m6, [pw_64] %endif -%if ARCH_X86_64 - movsxd r2, r2d -%endif sub r1, r2 diff --git a/libavcodec/x86/vp6dsp_init.c b/libavcodec/x86/vp6dsp_init.c index 9bf41783c21f2..472e03439e9f9 100644 --- a/libavcodec/x86/vp6dsp_init.c +++ b/libavcodec/x86/vp6dsp_init.c @@ -25,9 +25,9 @@ #include "libavutil/x86/cpu.h" #include "libavcodec/vp56dsp.h" -void ff_vp6_filter_diag4_mmx(uint8_t *dst, uint8_t *src, int stride, +void ff_vp6_filter_diag4_mmx(uint8_t *dst, uint8_t *src, ptrdiff_t stride, const int16_t *h_weights,const int16_t *v_weights); -void ff_vp6_filter_diag4_sse2(uint8_t *dst, uint8_t *src, int stride, +void ff_vp6_filter_diag4_sse2(uint8_t *dst, uint8_t *src, ptrdiff_t stride, const int16_t *h_weights,const int16_t *v_weights); av_cold void ff_vp6dsp_init_x86(VP56DSPContext* c, enum AVCodecID codec) From 87c6c78604e4dd16f1f45862b27ca006da010527 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 23 Aug 2016 23:26:35 +0200 Subject: [PATCH 0111/3374] vp8: Change type of stride parameters to ptrdiff_t ptrdiff_t is the correct type for array strides and similar. --- libavcodec/vp8.c | 17 +++++++++-------- libavcodec/vp8.h | 4 ++-- tests/checkasm/vp8dsp.c | 4 ++-- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index cd7f6923fbec3..546124cdf245e 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -426,7 +426,7 @@ static void copy_luma(AVFrame *dst, AVFrame *src, int width, int height) } static void fade(uint8_t *dst, uint8_t *src, - int width, int height, int linesize, + int width, int height, ptrdiff_t linesize, int alpha, int beta) { int i, j; @@ -1427,7 +1427,7 @@ void decode_mb_coeffs(VP8Context *s, VP8ThreadData *td, VP56RangeCoder *c, static av_always_inline void backup_mb_border(uint8_t *top_border, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, - int linesize, int uvlinesize, int simple) + ptrdiff_t linesize, ptrdiff_t uvlinesize, int simple) { AV_COPY128(top_border, src_y + 15 * linesize); if (!simple) { @@ -1438,7 +1438,7 @@ void backup_mb_border(uint8_t *top_border, uint8_t *src_y, static av_always_inline void xchg_mb_border(uint8_t *top_border, uint8_t *src_y, uint8_t *src_cb, - uint8_t *src_cr, int linesize, int uvlinesize, int mb_x, + uint8_t *src_cr, ptrdiff_t linesize, ptrdiff_t uvlinesize, int mb_x, int mb_y, int mb_width, int simple, int xchg) { uint8_t *top_border_m1 = top_border - 32; // for TL prediction @@ -1591,7 +1591,8 @@ void intra_predict(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3], for (y = 0; y < 4; y++) { uint8_t *topright = ptr + 4 - s->linesize; for (x = 0; x < 4; x++) { - int copy = 0, linesize = s->linesize; + int copy = 0; + ptrdiff_t linesize = s->linesize; uint8_t *dst = ptr + 4 * x; DECLARE_ALIGNED(4, uint8_t, copy_dst)[5 * 8]; @@ -1697,7 +1698,7 @@ void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst, uint8_t *src = ref->f->data[0]; if (AV_RN32A(mv)) { - int src_linesize = linesize; + ptrdiff_t src_linesize = linesize; int mx = (mv->x << 1) & 7, mx_idx = subpel_idx[0][mx]; int my = (mv->y << 1) & 7, my_idx = subpel_idx[0][my]; @@ -2041,8 +2042,8 @@ void filter_mb(VP8Context *s, uint8_t *dst[3], VP8FilterStrength *f, int filter_level = f->filter_level; int inner_limit = f->inner_limit; int inner_filter = f->inner_filter; - int linesize = s->linesize; - int uvlinesize = s->uvlinesize; + ptrdiff_t linesize = s->linesize; + ptrdiff_t uvlinesize = s->uvlinesize; static const uint8_t hev_thresh_lut[2][64] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -2128,7 +2129,7 @@ void filter_mb_simple(VP8Context *s, uint8_t *dst, VP8FilterStrength *f, int filter_level = f->filter_level; int inner_limit = f->inner_limit; int inner_filter = f->inner_filter; - int linesize = s->linesize; + ptrdiff_t linesize = s->linesize; if (!filter_level) return; diff --git a/libavcodec/vp8.h b/libavcodec/vp8.h index ba5e62a045627..65948e1d6be3a 100644 --- a/libavcodec/vp8.h +++ b/libavcodec/vp8.h @@ -143,8 +143,8 @@ typedef struct VP8Context { uint16_t mb_width; /* number of horizontal MB */ uint16_t mb_height; /* number of vertical MB */ - int linesize; - int uvlinesize; + ptrdiff_t linesize; + ptrdiff_t uvlinesize; uint8_t keyframe; uint8_t deblock_filter; diff --git a/tests/checkasm/vp8dsp.c b/tests/checkasm/vp8dsp.c index 0260d631bac14..40e40612289a8 100644 --- a/tests/checkasm/vp8dsp.c +++ b/tests/checkasm/vp8dsp.c @@ -171,7 +171,7 @@ static void check_idct_dc4(void) for (chroma = 0; chroma <= 1; chroma++) { void (*idct4dc)(uint8_t *, int16_t[4][16], ptrdiff_t) = chroma ? d.vp8_idct_dc_add4uv : d.vp8_idct_dc_add4y; if (check_func(idct4dc, "vp8_idct_dc_add4%s", chroma ? "uv" : "y")) { - int stride = chroma ? 8 : 16; + ptrdiff_t stride = chroma ? 8 : 16; int w = chroma ? 2 : 4; for (i = 0; i < 4; i++) { int blockx = 4 * (i % w); @@ -365,7 +365,7 @@ static void randomize_loopfilter_buffers(int lineoff, int str, } // Fill the buffer with random pixels -static void fill_loopfilter_buffers(uint8_t *buf, int stride, int w, int h) +static void fill_loopfilter_buffers(uint8_t *buf, ptrdiff_t stride, int w, int h) { int x, y; for (y = 0; y < h; y++) From 802727b538b484e3f9d1345bfcc4ab24cfea8898 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 24 Aug 2016 13:50:28 +0200 Subject: [PATCH 0112/3374] vp8: Update some assembly comments left unchanged in bd66f073fe7286bd3c --- libavcodec/arm/vp8dsp_armv6.S | 24 ++++++++++++------------ libavcodec/x86/vp8dsp.asm | 12 ++++++------ libavcodec/x86/vp8dsp_loopfilter.asm | 6 +++--- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/libavcodec/arm/vp8dsp_armv6.S b/libavcodec/arm/vp8dsp_armv6.S index 565361e280532..9eb9734cd3664 100644 --- a/libavcodec/arm/vp8dsp_armv6.S +++ b/libavcodec/arm/vp8dsp_armv6.S @@ -192,7 +192,7 @@ function ff_vp8_luma_dc_wht_dc_armv6, export=1 bx lr endfunc -@ void vp8_idct_add(uint8_t *dst, int16_t block[16], int stride) +@ void vp8_idct_add(uint8_t *dst, int16_t block[16], ptrdiff_t stride) function ff_vp8_idct_add_armv6, export=1 push {r4-r12, lr} sub sp, sp, #32 @@ -314,7 +314,7 @@ function ff_vp8_idct_add_armv6, export=1 pop {r4-r12, pc} endfunc -@ void vp8_idct_dc_add(uint8_t *dst, int16_t block[16], int stride) +@ void vp8_idct_dc_add(uint8_t *dst, int16_t block[16], ptrdiff_t stride) function ff_vp8_idct_dc_add_armv6, export=1 push {r4-r6, lr} add r6, r0, r2, lsl #1 @@ -355,7 +355,7 @@ function ff_vp8_idct_dc_add_armv6, export=1 pop {r4-r6, pc} endfunc -@ void vp8_idct_dc_add4uv(uint8_t *dst, int16_t block[4][16], int stride) +@ void vp8_idct_dc_add4uv(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride) function ff_vp8_idct_dc_add4uv_armv6, export=1 push {r4, lr} @@ -371,7 +371,7 @@ function ff_vp8_idct_dc_add4uv_armv6, export=1 pop {r4, pc} endfunc -@ void vp8_idct_dc_add4y(uint8_t *dst, int16_t block[4][16], int stride) +@ void vp8_idct_dc_add4y(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride) function ff_vp8_idct_dc_add4y_armv6, export=1 push {r4, lr} @@ -455,7 +455,7 @@ endfunc eor r5, r5, r2 @ *oq0 = u ^ 0x80 .endm -@ void vp8_v_loop_filter16_simple(uint8_t *dst, int stride, int flim) +@ void vp8_v_loop_filter16_simple(uint8_t *dst, ptrdiff_t stride, int flim) function ff_vp8_v_loop_filter16_simple_armv6, export=1 push {r4-r11, lr} @@ -866,7 +866,7 @@ function ff_vp8_v_loop_filter8uv_armv6, export=1 b vp8_v_loop_filter_armv6 endfunc -@ void vp8_h_loop_filter16_simple(uint8_t *dst, int stride, int flim) +@ void vp8_h_loop_filter16_simple(uint8_t *dst, ptrdiff_t stride, int flim) function ff_vp8_h_loop_filter16_simple_armv6, export=1 push {r4-r11, lr} orr r12, r2, r2, lsl #16 @@ -1113,8 +1113,8 @@ endfunc @ MC -@ void put_vp8_pixels16(uint8_t *dst, int dststride, uint8_t *src, -@ int srcstride, int h, int mx, int my) +@ void put_vp8_pixels16(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, +@ ptrdiff_t srcstride, int h, int mx, int my) function ff_put_vp8_pixels16_armv6, export=1 push {r4-r11} ldr r12, [sp, #32] @ h @@ -1137,8 +1137,8 @@ function ff_put_vp8_pixels16_armv6, export=1 bx lr endfunc -@ void put_vp8_pixels8(uint8_t *dst, int dststride, uint8_t *src, -@ int srcstride, int h, int mx, int my) +@ void put_vp8_pixels8(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, +@ ptrdiff_t srcstride, int h, int mx, int my) function ff_put_vp8_pixels8_armv6, export=1 push {r4-r11} ldr r12, [sp, #32] @ h @@ -1161,8 +1161,8 @@ function ff_put_vp8_pixels8_armv6, export=1 bx lr endfunc -@ void put_vp8_pixels4(uint8_t *dst, int dststride, uint8_t *src, -@ int srcstride, int h, int mx, int my) +@ void put_vp8_pixels4(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, +@ ptrdiff_t srcstride, int h, int mx, int my) function ff_put_vp8_pixels4_armv6, export=1 ldr r12, [sp, #0] @ h push {r4-r6,lr} diff --git a/libavcodec/x86/vp8dsp.asm b/libavcodec/x86/vp8dsp.asm index e17d3b2132cb9..b0f6b83767e40 100644 --- a/libavcodec/x86/vp8dsp.asm +++ b/libavcodec/x86/vp8dsp.asm @@ -156,8 +156,8 @@ SECTION .text ;------------------------------------------------------------------------------- ; subpel MC functions: ; -; void ff_put_vp8_epel_hv_(uint8_t *dst, int deststride, -; uint8_t *src, int srcstride, +; void ff_put_vp8_epel_hv_(uint8_t *dst, ptrdiff_t deststride, +; uint8_t *src, ptrdiff_t srcstride, ; int height, int mx, int my); ;------------------------------------------------------------------------------- @@ -884,7 +884,7 @@ cglobal put_vp8_pixels16, 5, 5, 2, dst, dststride, src, srcstride, height REP_RET ;----------------------------------------------------------------------------- -; void ff_vp8_idct_dc_add_(uint8_t *dst, int16_t block[16], int stride); +; void ff_vp8_idct_dc_add_(uint8_t *dst, int16_t block[16], ptrdiff_t stride); ;----------------------------------------------------------------------------- %macro ADD_DC 4 @@ -962,7 +962,7 @@ cglobal vp8_idct_dc_add, 3, 3, 6, dst, block, stride RET ;----------------------------------------------------------------------------- -; void ff_vp8_idct_dc_add4y_(uint8_t *dst, int16_t block[4][16], int stride); +; void ff_vp8_idct_dc_add4y_(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride); ;----------------------------------------------------------------------------- %if ARCH_X86_32 @@ -1035,7 +1035,7 @@ cglobal vp8_idct_dc_add4y, 3, 3, 6, dst, block, stride RET ;----------------------------------------------------------------------------- -; void ff_vp8_idct_dc_add4uv_(uint8_t *dst, int16_t block[4][16], int stride); +; void ff_vp8_idct_dc_add4uv_(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride); ;----------------------------------------------------------------------------- INIT_MMX mmx @@ -1077,7 +1077,7 @@ cglobal vp8_idct_dc_add4uv, 3, 3, 0, dst, block, stride RET ;----------------------------------------------------------------------------- -; void ff_vp8_idct_add_(uint8_t *dst, int16_t block[16], int stride); +; void ff_vp8_idct_add_(uint8_t *dst, int16_t block[16], ptrdiff_t stride); ;----------------------------------------------------------------------------- ; calculate %1=mul_35468(%1)-mul_20091(%2); %2=mul_20091(%1)+mul_35468(%2) diff --git a/libavcodec/x86/vp8dsp_loopfilter.asm b/libavcodec/x86/vp8dsp_loopfilter.asm index 5d792e82076a9..9ffd83a39b400 100644 --- a/libavcodec/x86/vp8dsp_loopfilter.asm +++ b/libavcodec/x86/vp8dsp_loopfilter.asm @@ -43,7 +43,7 @@ cextern pb_80 SECTION .text ;----------------------------------------------------------------------------- -; void ff_vp8_h/v_loop_filter_simple_(uint8_t *dst, int stride, int flim); +; void ff_vp8_h/v_loop_filter_simple_(uint8_t *dst, ptrdiff_t stride, int flim); ;----------------------------------------------------------------------------- ; macro called with 7 mm register indexes as argument, and 4 regular registers @@ -429,7 +429,7 @@ INIT_XMM sse4 SIMPLE_LOOPFILTER h, 5 ;----------------------------------------------------------------------------- -; void ff_vp8_h/v_loop_filter_inner_(uint8_t *dst, [uint8_t *v,] int stride, +; void ff_vp8_h/v_loop_filter_inner_(uint8_t *dst, [uint8_t *v,] ptrdiff_t stride, ; int flimE, int flimI, int hev_thr); ;----------------------------------------------------------------------------- @@ -921,7 +921,7 @@ INNER_LOOPFILTER v, 8 INNER_LOOPFILTER h, 8 ;----------------------------------------------------------------------------- -; void ff_vp8_h/v_loop_filter_mbedge_(uint8_t *dst, [uint8_t *v,] int stride, +; void ff_vp8_h/v_loop_filter_mbedge_(uint8_t *dst, [uint8_t *v,] ptrdiff_t stride, ; int flimE, int flimI, int hev_thr); ;----------------------------------------------------------------------------- From f81be06cf614919d71ded29b8f595bef40123ad8 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 24 Aug 2016 00:18:41 +0200 Subject: [PATCH 0113/3374] cavs: Change type of stride parameters to ptrdiff_t ptrdiff_t is the correct type for array strides and similar. --- libavcodec/cavs.c | 18 ++++++------- libavcodec/cavs.h | 4 +-- libavcodec/cavsdec.c | 2 +- libavcodec/cavsdsp.c | 55 +++++++++++++++++++++++++--------------- libavcodec/cavsdsp.h | 10 ++++---- libavcodec/x86/cavsdsp.c | 35 ++++++++++++++++--------- 6 files changed, 75 insertions(+), 49 deletions(-) diff --git a/libavcodec/cavs.c b/libavcodec/cavs.c index 3050b9adc5d91..cf66629ffd99f 100644 --- a/libavcodec/cavs.c +++ b/libavcodec/cavs.c @@ -246,7 +246,7 @@ void ff_cavs_load_intra_pred_chroma(AVSContext *h) } } -static void intra_pred_vert(uint8_t *d, uint8_t *top, uint8_t *left, int stride) +static void intra_pred_vert(uint8_t *d, uint8_t *top, uint8_t *left, ptrdiff_t stride) { int y; uint64_t a = AV_RN64(&top[1]); @@ -254,7 +254,7 @@ static void intra_pred_vert(uint8_t *d, uint8_t *top, uint8_t *left, int stride) *((uint64_t *)(d + y * stride)) = a; } -static void intra_pred_horiz(uint8_t *d, uint8_t *top, uint8_t *left, int stride) +static void intra_pred_horiz(uint8_t *d, uint8_t *top, uint8_t *left, ptrdiff_t stride) { int y; uint64_t a; @@ -264,7 +264,7 @@ static void intra_pred_horiz(uint8_t *d, uint8_t *top, uint8_t *left, int stride } } -static void intra_pred_dc_128(uint8_t *d, uint8_t *top, uint8_t *left, int stride) +static void intra_pred_dc_128(uint8_t *d, uint8_t *top, uint8_t *left, ptrdiff_t stride) { int y; uint64_t a = 0x8080808080808080ULL; @@ -272,7 +272,7 @@ static void intra_pred_dc_128(uint8_t *d, uint8_t *top, uint8_t *left, int strid *((uint64_t *)(d + y * stride)) = a; } -static void intra_pred_plane(uint8_t *d, uint8_t *top, uint8_t *left, int stride) +static void intra_pred_plane(uint8_t *d, uint8_t *top, uint8_t *left, ptrdiff_t stride) { int x, y, ia; int ih = 0; @@ -294,7 +294,7 @@ static void intra_pred_plane(uint8_t *d, uint8_t *top, uint8_t *left, int stride #define LOWPASS(ARRAY, INDEX) \ ((ARRAY[(INDEX) - 1] + 2 * ARRAY[(INDEX)] + ARRAY[(INDEX) + 1] + 2) >> 2) -static void intra_pred_lp(uint8_t *d, uint8_t *top, uint8_t *left, int stride) +static void intra_pred_lp(uint8_t *d, uint8_t *top, uint8_t *left, ptrdiff_t stride) { int x, y; for (y = 0; y < 8; y++) @@ -302,7 +302,7 @@ static void intra_pred_lp(uint8_t *d, uint8_t *top, uint8_t *left, int stride) d[y * stride + x] = (LOWPASS(top, x + 1) + LOWPASS(left, y + 1)) >> 1; } -static void intra_pred_down_left(uint8_t *d, uint8_t *top, uint8_t *left, int stride) +static void intra_pred_down_left(uint8_t *d, uint8_t *top, uint8_t *left, ptrdiff_t stride) { int x, y; for (y = 0; y < 8; y++) @@ -310,7 +310,7 @@ static void intra_pred_down_left(uint8_t *d, uint8_t *top, uint8_t *left, int st d[y * stride + x] = (LOWPASS(top, x + y + 2) + LOWPASS(left, x + y + 2)) >> 1; } -static void intra_pred_down_right(uint8_t *d, uint8_t *top, uint8_t *left, int stride) +static void intra_pred_down_right(uint8_t *d, uint8_t *top, uint8_t *left, ptrdiff_t stride) { int x, y; for (y = 0; y < 8; y++) @@ -323,7 +323,7 @@ static void intra_pred_down_right(uint8_t *d, uint8_t *top, uint8_t *left, int s d[y * stride + x] = LOWPASS(left, y - x); } -static void intra_pred_lp_left(uint8_t *d, uint8_t *top, uint8_t *left, int stride) +static void intra_pred_lp_left(uint8_t *d, uint8_t *top, uint8_t *left, ptrdiff_t stride) { int x, y; for (y = 0; y < 8; y++) @@ -331,7 +331,7 @@ static void intra_pred_lp_left(uint8_t *d, uint8_t *top, uint8_t *left, int stri d[y * stride + x] = LOWPASS(left, y + 1); } -static void intra_pred_lp_top(uint8_t *d, uint8_t *top, uint8_t *left, int stride) +static void intra_pred_lp_top(uint8_t *d, uint8_t *top, uint8_t *left, ptrdiff_t stride) { int x, y; for (y = 0; y < 8; y++) diff --git a/libavcodec/cavs.h b/libavcodec/cavs.h index cfae05576b06d..e8729d50cdfe6 100644 --- a/libavcodec/cavs.h +++ b/libavcodec/cavs.h @@ -226,8 +226,8 @@ typedef struct AVSContext { uint8_t intern_border_y[26]; uint8_t topleft_border_y, topleft_border_u, topleft_border_v; - void (*intra_pred_l[8])(uint8_t *d,uint8_t *top,uint8_t *left,int stride); - void (*intra_pred_c[7])(uint8_t *d,uint8_t *top,uint8_t *left,int stride); + void (*intra_pred_l[8])(uint8_t *d, uint8_t *top, uint8_t *left, ptrdiff_t stride); + void (*intra_pred_c[7])(uint8_t *d, uint8_t *top, uint8_t *left, ptrdiff_t stride); uint8_t *col_type_base; /* scaling factors for MV prediction */ diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c index a455a34bd0bf4..1c4f276373f2c 100644 --- a/libavcodec/cavsdec.c +++ b/libavcodec/cavsdec.c @@ -547,7 +547,7 @@ static inline int dequant(AVSContext *h, int16_t *level_buf, uint8_t *run_buf, */ static int decode_residual_block(AVSContext *h, GetBitContext *gb, const struct dec_2dvlc *r, int esc_golomb_order, - int qp, uint8_t *dst, int stride) + int qp, uint8_t *dst, ptrdiff_t stride) { int i, level_code, esc_code, level, run, mask, ret; int16_t level_buf[65]; diff --git a/libavcodec/cavsdsp.c b/libavcodec/cavsdsp.c index cc7898968fb84..a374dec30b92b 100644 --- a/libavcodec/cavsdsp.c +++ b/libavcodec/cavsdsp.c @@ -42,7 +42,8 @@ #define Q1 p0_p[ 1*stride] #define Q2 p0_p[ 2*stride] -static inline void loop_filter_l2(uint8_t *p0_p,int stride,int alpha, int beta) { +static inline void loop_filter_l2(uint8_t *p0_p, ptrdiff_t stride, int alpha, int beta) +{ int p0 = P0; int q0 = Q0; @@ -62,7 +63,8 @@ static inline void loop_filter_l2(uint8_t *p0_p,int stride,int alpha, int beta) } } -static inline void loop_filter_l1(uint8_t *p0_p, int stride, int alpha, int beta, int tc) { +static inline void loop_filter_l1(uint8_t *p0_p, ptrdiff_t stride, int alpha, int beta, int tc) +{ int p0 = P0; int q0 = Q0; @@ -81,7 +83,8 @@ static inline void loop_filter_l1(uint8_t *p0_p, int stride, int alpha, int beta } } -static inline void loop_filter_c2(uint8_t *p0_p,int stride,int alpha, int beta) { +static inline void loop_filter_c2(uint8_t *p0_p, ptrdiff_t stride, int alpha, int beta) +{ int p0 = P0; int q0 = Q0; @@ -99,8 +102,9 @@ static inline void loop_filter_c2(uint8_t *p0_p,int stride,int alpha, int beta) } } -static inline void loop_filter_c1(uint8_t *p0_p,int stride,int alpha, int beta, - int tc) { +static inline void loop_filter_c1(uint8_t *p0_p, ptrdiff_t stride, int alpha, int beta, + int tc) +{ if(abs(P0-Q0)>3, -tc, tc); P0 = av_clip_uint8(P0+delta); @@ -115,8 +119,9 @@ static inline void loop_filter_c1(uint8_t *p0_p,int stride,int alpha, int beta, #undef Q1 #undef Q2 -static void cavs_filter_lv_c(uint8_t *d, int stride, int alpha, int beta, int tc, - int bs1, int bs2) { +static void cavs_filter_lv_c(uint8_t *d, ptrdiff_t stride, int alpha, int beta, int tc, + int bs1, int bs2) +{ int i; if(bs1==2) for(i=0;i<16;i++) @@ -131,8 +136,9 @@ static void cavs_filter_lv_c(uint8_t *d, int stride, int alpha, int beta, int tc } } -static void cavs_filter_lh_c(uint8_t *d, int stride, int alpha, int beta, int tc, - int bs1, int bs2) { +static void cavs_filter_lh_c(uint8_t *d, ptrdiff_t stride, int alpha, int beta, int tc, + int bs1, int bs2) +{ int i; if(bs1==2) for(i=0;i<16;i++) @@ -147,8 +153,9 @@ static void cavs_filter_lh_c(uint8_t *d, int stride, int alpha, int beta, int tc } } -static void cavs_filter_cv_c(uint8_t *d, int stride, int alpha, int beta, int tc, - int bs1, int bs2) { +static void cavs_filter_cv_c(uint8_t *d, ptrdiff_t stride, int alpha, int beta, int tc, + int bs1, int bs2) +{ int i; if(bs1==2) for(i=0;i<8;i++) @@ -163,8 +170,9 @@ static void cavs_filter_cv_c(uint8_t *d, int stride, int alpha, int beta, int tc } } -static void cavs_filter_ch_c(uint8_t *d, int stride, int alpha, int beta, int tc, - int bs1, int bs2) { +static void cavs_filter_ch_c(uint8_t *d, ptrdiff_t stride, int alpha, int beta, int tc, + int bs1, int bs2) +{ int i; if(bs1==2) for(i=0;i<8;i++) @@ -185,7 +193,8 @@ static void cavs_filter_ch_c(uint8_t *d, int stride, int alpha, int beta, int tc * ****************************************************************************/ -static void cavs_idct8_add_c(uint8_t *dst, int16_t *block, int stride) { +static void cavs_idct8_add_c(uint8_t *dst, int16_t *block, ptrdiff_t stride) +{ int i; int16_t (*src)[8] = (int16_t(*)[8])block; const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP; @@ -261,7 +270,8 @@ static void cavs_idct8_add_c(uint8_t *dst, int16_t *block, int stride) { ****************************************************************************/ #define CAVS_SUBPIX(OPNAME, OP, NAME, A, B, C, D, E, F) \ -static void OPNAME ## cavs_filt8_h_ ## NAME(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ +static void OPNAME ## cavs_filt8_h_ ## NAME(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ const int h=8;\ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;\ int i;\ @@ -280,7 +290,8 @@ static void OPNAME ## cavs_filt8_h_ ## NAME(uint8_t *dst, const uint8_t *src, in }\ }\ \ -static void OPNAME ## cavs_filt8_v_ ## NAME(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ +static void OPNAME ## cavs_filt8_v_ ## NAME(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ const int w=8;\ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;\ int i;\ @@ -312,7 +323,8 @@ static void OPNAME ## cavs_filt8_v_ ## NAME(uint8_t *dst, const uint8_t *src, i }\ }\ \ -static void OPNAME ## cavs_filt16_v_ ## NAME(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ +static void OPNAME ## cavs_filt16_v_ ## NAME(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ OPNAME ## cavs_filt8_v_ ## NAME(dst , src , dstStride, srcStride);\ OPNAME ## cavs_filt8_v_ ## NAME(dst+8, src+8, dstStride, srcStride);\ src += 8*srcStride;\ @@ -321,7 +333,8 @@ static void OPNAME ## cavs_filt16_v_ ## NAME(uint8_t *dst, const uint8_t *src, i OPNAME ## cavs_filt8_v_ ## NAME(dst+8, src+8, dstStride, srcStride);\ }\ \ -static void OPNAME ## cavs_filt16_h_ ## NAME(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ +static void OPNAME ## cavs_filt16_h_ ## NAME(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ OPNAME ## cavs_filt8_h_ ## NAME(dst , src , dstStride, srcStride);\ OPNAME ## cavs_filt8_h_ ## NAME(dst+8, src+8, dstStride, srcStride);\ src += 8*srcStride;\ @@ -331,7 +344,8 @@ static void OPNAME ## cavs_filt16_h_ ## NAME(uint8_t *dst, const uint8_t *src, i }\ #define CAVS_SUBPIX_HV(OPNAME, OP, NAME, AH, BH, CH, DH, EH, FH, AV, BV, CV, DV, EV, FV, FULL) \ -static void OPNAME ## cavs_filt8_hv_ ## NAME(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dstStride, int srcStride){\ +static void OPNAME ## cavs_filt8_hv_ ## NAME(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ int16_t temp[8*(8+5)];\ int16_t *tmp = temp;\ const int h=8;\ @@ -412,7 +426,8 @@ static void OPNAME ## cavs_filt8_hv_ ## NAME(uint8_t *dst, const uint8_t *src1, }\ }\ \ -static void OPNAME ## cavs_filt16_hv_ ## NAME(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dstStride, int srcStride){ \ +static void OPNAME ## cavs_filt16_hv_ ## NAME(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ OPNAME ## cavs_filt8_hv_ ## NAME(dst , src1, src2 , dstStride, srcStride); \ OPNAME ## cavs_filt8_hv_ ## NAME(dst+8, src1+8, src2+8, dstStride, srcStride); \ src1 += 8*srcStride;\ diff --git a/libavcodec/cavsdsp.h b/libavcodec/cavsdsp.h index 248afd508c2d3..65aa38ab05883 100644 --- a/libavcodec/cavsdsp.h +++ b/libavcodec/cavsdsp.h @@ -30,11 +30,11 @@ typedef struct CAVSDSPContext { qpel_mc_func put_cavs_qpel_pixels_tab[2][16]; qpel_mc_func avg_cavs_qpel_pixels_tab[2][16]; - void (*cavs_filter_lv)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); - void (*cavs_filter_lh)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); - void (*cavs_filter_cv)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); - void (*cavs_filter_ch)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); - void (*cavs_idct8_add)(uint8_t *dst, int16_t *block, int stride); + void (*cavs_filter_lv)(uint8_t *pix, ptrdiff_t stride, int alpha, int beta, int tc, int bs1, int bs2); + void (*cavs_filter_lh)(uint8_t *pix, ptrdiff_t stride, int alpha, int beta, int tc, int bs1, int bs2); + void (*cavs_filter_cv)(uint8_t *pix, ptrdiff_t stride, int alpha, int beta, int tc, int bs1, int bs2); + void (*cavs_filter_ch)(uint8_t *pix, ptrdiff_t stride, int alpha, int beta, int tc, int bs1, int bs2); + void (*cavs_idct8_add)(uint8_t *dst, int16_t *block, ptrdiff_t stride); int idct_perm; } CAVSDSPContext; diff --git a/libavcodec/x86/cavsdsp.c b/libavcodec/x86/cavsdsp.c index 39eec4b3eeeea..b5406ef16d259 100644 --- a/libavcodec/x86/cavsdsp.c +++ b/libavcodec/x86/cavsdsp.c @@ -136,7 +136,7 @@ static inline void cavs_idct8_1d(int16_t *block, uint64_t bias) SBUTTERFLY(a,c,d,dq,q) /* a=aeim d=bfjn */\ SBUTTERFLY(t,b,c,dq,q) /* t=cgko c=dhlp */ -static void cavs_idct8_add_mmx(uint8_t *dst, int16_t *block, int stride) +static void cavs_idct8_add_mmx(uint8_t *dst, int16_t *block, ptrdiff_t stride) { int i; DECLARE_ALIGNED(8, int16_t, b2)[64]; @@ -332,7 +332,8 @@ static void cavs_idct8_add_mmx(uint8_t *dst, int16_t *block, int stride) } #define QPEL_CAVS(OPNAME, OP, MMX)\ -static void OPNAME ## cavs_qpel8_h_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ +static void OPNAME ## cavs_qpel8_h_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{\ int h=8;\ __asm__ volatile(\ "pxor %%mm7, %%mm7 \n\t"\ @@ -379,43 +380,53 @@ static void OPNAME ## cavs_qpel8_h_ ## MMX(uint8_t *dst, const uint8_t *src, int );\ }\ \ -static inline void OPNAME ## cavs_qpel8or16_v1_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h){\ +static inline void OPNAME ## cavs_qpel8or16_v1_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride, int h)\ +{ \ QPEL_CAVSVNUM(QPEL_CAVSV1,OP,ff_pw_64,ff_pw_96,ff_pw_42) \ }\ \ -static inline void OPNAME ## cavs_qpel8or16_v2_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h){\ +static inline void OPNAME ## cavs_qpel8or16_v2_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride, int h)\ +{ \ QPEL_CAVSVNUM(QPEL_CAVSV2,OP,ff_pw_4,ff_pw_5,ff_pw_5) \ }\ \ -static inline void OPNAME ## cavs_qpel8or16_v3_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h){\ +static inline void OPNAME ## cavs_qpel8or16_v3_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride, int h)\ +{ \ QPEL_CAVSVNUM(QPEL_CAVSV3,OP,ff_pw_64,ff_pw_96,ff_pw_42) \ }\ \ -static void OPNAME ## cavs_qpel8_v1_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ +static void OPNAME ## cavs_qpel8_v1_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ OPNAME ## cavs_qpel8or16_v1_ ## MMX(dst , src , dstStride, srcStride, 8);\ }\ -static void OPNAME ## cavs_qpel16_v1_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ +static void OPNAME ## cavs_qpel16_v1_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ OPNAME ## cavs_qpel8or16_v1_ ## MMX(dst , src , dstStride, srcStride, 16);\ OPNAME ## cavs_qpel8or16_v1_ ## MMX(dst+8, src+8, dstStride, srcStride, 16);\ }\ \ -static void OPNAME ## cavs_qpel8_v2_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ +static void OPNAME ## cavs_qpel8_v2_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ OPNAME ## cavs_qpel8or16_v2_ ## MMX(dst , src , dstStride, srcStride, 8);\ }\ -static void OPNAME ## cavs_qpel16_v2_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ +static void OPNAME ## cavs_qpel16_v2_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ OPNAME ## cavs_qpel8or16_v2_ ## MMX(dst , src , dstStride, srcStride, 16);\ OPNAME ## cavs_qpel8or16_v2_ ## MMX(dst+8, src+8, dstStride, srcStride, 16);\ }\ \ -static void OPNAME ## cavs_qpel8_v3_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ +static void OPNAME ## cavs_qpel8_v3_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ OPNAME ## cavs_qpel8or16_v3_ ## MMX(dst , src , dstStride, srcStride, 8);\ }\ -static void OPNAME ## cavs_qpel16_v3_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ +static void OPNAME ## cavs_qpel16_v3_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ OPNAME ## cavs_qpel8or16_v3_ ## MMX(dst , src , dstStride, srcStride, 16);\ OPNAME ## cavs_qpel8or16_v3_ ## MMX(dst+8, src+8, dstStride, srcStride, 16);\ }\ \ -static void OPNAME ## cavs_qpel16_h_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ +static void OPNAME ## cavs_qpel16_h_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ OPNAME ## cavs_qpel8_h_ ## MMX(dst , src , dstStride, srcStride);\ OPNAME ## cavs_qpel8_h_ ## MMX(dst+8, src+8, dstStride, srcStride);\ src += 8*srcStride;\ From 3fd22538bc0e0de84b31335266b4b1577d3d609e Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 24 Aug 2016 11:52:10 +0200 Subject: [PATCH 0114/3374] prores: Change type of stride parameters to ptrdiff_t This avoids SIMD-optimized functions having to sign-extend their line size argument manually to be able to do pointer arithmetic. Also adjust parameter names to be "linesize" everywhere. --- libavcodec/proresdsp.c | 6 +++--- libavcodec/proresdsp.h | 3 ++- libavcodec/proresenc.c | 19 ++++++++++--------- libavcodec/x86/proresdsp.asm | 3 +-- libavcodec/x86/proresdsp_init.c | 6 +++--- 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/libavcodec/proresdsp.c b/libavcodec/proresdsp.c index 3af2f0b9bb9b9..f782c907c0d1a 100644 --- a/libavcodec/proresdsp.c +++ b/libavcodec/proresdsp.c @@ -36,11 +36,11 @@ /** * Add bias value, clamp and output pixels of a slice */ -static void put_pixels(uint16_t *dst, int stride, const int16_t *in) +static void put_pixels(uint16_t *dst, ptrdiff_t linesize, const int16_t *in) { int x, y, src_offset, dst_offset; - for (y = 0, dst_offset = 0; y < 8; y++, dst_offset += stride) { + for (y = 0, dst_offset = 0; y < 8; y++, dst_offset += linesize) { for (x = 0; x < 8; x++) { src_offset = (y << 3) + x; @@ -49,7 +49,7 @@ static void put_pixels(uint16_t *dst, int stride, const int16_t *in) } } -static void prores_idct_put_c(uint16_t *out, int linesize, int16_t *block, const int16_t *qmat) +static void prores_idct_put_c(uint16_t *out, ptrdiff_t linesize, int16_t *block, const int16_t *qmat) { ff_prores_idct(block, qmat); put_pixels(out, linesize >> 1, block); diff --git a/libavcodec/proresdsp.h b/libavcodec/proresdsp.h index e8a3ea96a743b..7f06494daf58c 100644 --- a/libavcodec/proresdsp.h +++ b/libavcodec/proresdsp.h @@ -23,6 +23,7 @@ #ifndef AVCODEC_PRORESDSP_H #define AVCODEC_PRORESDSP_H +#include #include #define PRORES_BITS_PER_SAMPLE 10 ///< output precision of prores decoder @@ -30,7 +31,7 @@ typedef struct ProresDSPContext { int idct_permutation_type; uint8_t idct_permutation[64]; - void (* idct_put) (uint16_t *out, int linesize, int16_t *block, const int16_t *qmat); + void (*idct_put)(uint16_t *out, ptrdiff_t linesize, int16_t *block, const int16_t *qmat); } ProresDSPContext; void ff_proresdsp_init(ProresDSPContext *dsp); diff --git a/libavcodec/proresenc.c b/libavcodec/proresenc.c index 0564b12ae29d3..e4842d2993c02 100644 --- a/libavcodec/proresenc.c +++ b/libavcodec/proresenc.c @@ -192,7 +192,7 @@ typedef struct ProresContext { const uint8_t *scantable; void (*fdct)(FDCTDSPContext *fdsp, const uint16_t *src, - int linesize, int16_t *block); + ptrdiff_t linesize, int16_t *block); FDCTDSPContext fdsp; const AVFrame *pic; @@ -223,13 +223,13 @@ typedef struct ProresContext { } ProresContext; static void get_slice_data(ProresContext *ctx, const uint16_t *src, - int linesize, int x, int y, int w, int h, + ptrdiff_t linesize, int x, int y, int w, int h, int16_t *blocks, uint16_t *emu_buf, int mbs_per_slice, int blocks_per_mb, int is_chroma) { const uint16_t *esrc; const int mb_width = 4 * blocks_per_mb; - int elinesize; + ptrdiff_t elinesize; int i, j, k; for (i = 0; i < mbs_per_slice; i++, src += mb_width) { @@ -294,7 +294,7 @@ static void get_slice_data(ProresContext *ctx, const uint16_t *src, } static void get_alpha_data(ProresContext *ctx, const uint16_t *src, - int linesize, int x, int y, int w, int h, + ptrdiff_t linesize, int x, int y, int w, int h, int16_t *blocks, int mbs_per_slice, int abits) { const int slice_width = 16 * mbs_per_slice; @@ -417,7 +417,7 @@ static void encode_acs(PutBitContext *pb, int16_t *blocks, } static int encode_slice_plane(ProresContext *ctx, PutBitContext *pb, - const uint16_t *src, int linesize, + const uint16_t *src, ptrdiff_t linesize, int mbs_per_slice, int16_t *blocks, int blocks_per_mb, int plane_size_factor, const int16_t *qmat) @@ -511,7 +511,8 @@ static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, int total_size = 0; const uint16_t *src; int slice_width_factor = av_log2(mbs_per_slice); - int num_cblocks, pwidth, linesize, line_add; + int num_cblocks, pwidth, line_add; + ptrdiff_t linesize; int plane_factor, is_chroma; uint16_t *qmat; @@ -667,7 +668,7 @@ static int estimate_acs(int *error, int16_t *blocks, int blocks_per_slice, } static int estimate_slice_plane(ProresContext *ctx, int *error, int plane, - const uint16_t *src, int linesize, + const uint16_t *src, ptrdiff_t linesize, int mbs_per_slice, int blocks_per_mb, int plane_size_factor, const int16_t *qmat, ProresThreadData *td) @@ -701,7 +702,7 @@ static int est_alpha_diff(int cur, int prev, int abits) } static int estimate_alpha_plane(ProresContext *ctx, int *error, - const uint16_t *src, int linesize, + const uint16_t *src, ptrdiff_t linesize, int mbs_per_slice, int quant, int16_t *blocks) { @@ -1112,7 +1113,7 @@ static av_cold int encode_close(AVCodecContext *avctx) } static void prores_fdct(FDCTDSPContext *fdsp, const uint16_t *src, - int linesize, int16_t *block) + ptrdiff_t linesize, int16_t *block) { int x, y; const uint16_t *tsrc = src; diff --git a/libavcodec/x86/proresdsp.asm b/libavcodec/x86/proresdsp.asm index 5a329cb8987b6..9613fa1448f8b 100644 --- a/libavcodec/x86/proresdsp.asm +++ b/libavcodec/x86/proresdsp.asm @@ -326,11 +326,10 @@ SECTION .text SUMSUB_SHPK m2, m3, m4, m5, m6, m7, %2 %endmacro -; void ff_prores_idct_put_10_(uint8_t *pixels, int stride, +; void ff_prores_idct_put_10_(uint8_t *pixels, ptrdiff_t linesize, ; int16_t *block, const int16_t *qmat); %macro idct_put_fn 1 cglobal prores_idct_put_10, 4, 4, %1 - movsxd r1, r1d pxor m15, m15 ; zero ; for (i = 0; i < 8; i++) diff --git a/libavcodec/x86/proresdsp_init.c b/libavcodec/x86/proresdsp_init.c index e82dac0448306..ff4d39836b016 100644 --- a/libavcodec/x86/proresdsp_init.c +++ b/libavcodec/x86/proresdsp_init.c @@ -25,11 +25,11 @@ #include "libavcodec/idctdsp.h" #include "libavcodec/proresdsp.h" -void ff_prores_idct_put_10_sse2(uint16_t *dst, int linesize, +void ff_prores_idct_put_10_sse2(uint16_t *dst, ptrdiff_t linesize, int16_t *block, const int16_t *qmat); -void ff_prores_idct_put_10_sse4(uint16_t *dst, int linesize, +void ff_prores_idct_put_10_sse4(uint16_t *dst, ptrdiff_t linesize, int16_t *block, const int16_t *qmat); -void ff_prores_idct_put_10_avx (uint16_t *dst, int linesize, +void ff_prores_idct_put_10_avx (uint16_t *dst, ptrdiff_t linesize, int16_t *block, const int16_t *qmat); av_cold void ff_proresdsp_init_x86(ProresDSPContext *dsp) From 721d57e608dc4fd6c86f27c5ae76ef559d646220 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 24 Aug 2016 12:30:15 +0200 Subject: [PATCH 0115/3374] vp56: Separate VP5 and VP6 dsp initialization VP5 has no arch-specific optimizations (nor will it get some in the future), so it makes no sense to try to share dsp init code with VP6. --- libavcodec/arm/vp6dsp_init_arm.c | 4 +- libavcodec/vp5.c | 1 + libavcodec/vp56.c | 1 - libavcodec/vp56.h | 1 + libavcodec/vp56dsp.c | 72 +++++++++++++++++--------------- libavcodec/vp56dsp.h | 10 ++--- libavcodec/vp6.c | 1 + libavcodec/x86/vp6dsp_init.c | 2 +- 8 files changed, 49 insertions(+), 43 deletions(-) diff --git a/libavcodec/arm/vp6dsp_init_arm.c b/libavcodec/arm/vp6dsp_init_arm.c index 235b0b6bf3ae2..7e2615047bd71 100644 --- a/libavcodec/arm/vp6dsp_init_arm.c +++ b/libavcodec/arm/vp6dsp_init_arm.c @@ -22,13 +22,13 @@ #include "libavutil/attributes.h" #include "libavutil/arm/cpu.h" -#include "libavcodec/avcodec.h" + #include "libavcodec/vp56dsp.h" void ff_vp6_edge_filter_hor_neon(uint8_t *yuv, ptrdiff_t stride, int t); void ff_vp6_edge_filter_ver_neon(uint8_t *yuv, ptrdiff_t stride, int t); -av_cold void ff_vp6dsp_init_arm(VP56DSPContext *s, enum AVCodecID codec) +av_cold void ff_vp6dsp_init_arm(VP56DSPContext *s) { int cpu_flags = av_get_cpu_flags(); diff --git a/libavcodec/vp5.c b/libavcodec/vp5.c index 3e14874ba44b2..2d8ba1a0f79c2 100644 --- a/libavcodec/vp5.c +++ b/libavcodec/vp5.c @@ -270,6 +270,7 @@ static av_cold int vp5_decode_init(AVCodecContext *avctx) if ((ret = ff_vp56_init(avctx, 1, 0)) < 0) return ret; + ff_vp5dsp_init(&s->vp56dsp); s->vp56_coord_div = vp5_coord_div; s->parse_vector_adjustment = vp5_parse_vector_adjustment; s->parse_coeff = vp5_parse_coeff; diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c index 2f1de5a5a098f..39d82e9c15788 100644 --- a/libavcodec/vp56.c +++ b/libavcodec/vp56.c @@ -663,7 +663,6 @@ av_cold int ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha) ff_hpeldsp_init(&s->hdsp, avctx->flags); ff_videodsp_init(&s->vdsp, 8); ff_vp3dsp_init(&s->vp3dsp, avctx->flags); - ff_vp56dsp_init(&s->vp56dsp, avctx->codec->id); for (i = 0; i < 64; i++) { #define TRANSPOSE(x) (x >> 3) | ((x & 7) << 3) s->idct_scantable[i] = TRANSPOSE(ff_zigzag_direct[i]); diff --git a/libavcodec/vp56.h b/libavcodec/vp56.h index 52fe3182f4a69..8b7806e5befda 100644 --- a/libavcodec/vp56.h +++ b/libavcodec/vp56.h @@ -26,6 +26,7 @@ #ifndef AVCODEC_VP56_H #define AVCODEC_VP56_H +#include "avcodec.h" #include "get_bits.h" #include "hpeldsp.h" #include "bytestream.h" diff --git a/libavcodec/vp56dsp.c b/libavcodec/vp56dsp.c index 297534bbddd25..fb3b37c966944 100644 --- a/libavcodec/vp56dsp.c +++ b/libavcodec/vp56dsp.c @@ -26,6 +26,23 @@ #include "vp56dsp.h" #include "libavutil/common.h" +#define VP56_EDGE_FILTER(pfx, suf, pix_inc, line_inc) \ +static void pfx ## _edge_filter_ ## suf(uint8_t *yuv, ptrdiff_t stride, \ + int t) \ +{ \ + int pix2_inc = 2 * pix_inc; \ + int i, v; \ + \ + for (i=0; i<12; i++) { \ + v = (yuv[-pix2_inc] + 3*(yuv[0]-yuv[-pix_inc]) - yuv[pix_inc] + 4)>>3;\ + v = pfx##_adjust(v, t); \ + yuv[-pix_inc] = av_clip_uint8(yuv[-pix_inc] + v); \ + yuv[0] = av_clip_uint8(yuv[0] - v); \ + yuv += line_inc; \ + } \ +} + +#if CONFIG_VP5_DECODER /* Gives very similar result than the vp6 version except in a few cases */ static int vp5_adjust(int v, int t) { @@ -43,6 +60,18 @@ static int vp5_adjust(int v, int t) return v; } + +VP56_EDGE_FILTER(vp5, hor, 1, stride) +VP56_EDGE_FILTER(vp5, ver, stride, 1) + +av_cold void ff_vp5dsp_init(VP56DSPContext *s) +{ + s->edge_filter_hor = vp5_edge_filter_hor; + s->edge_filter_ver = vp5_edge_filter_ver; +} +#endif /* CONFIG_VP5_DECODER */ + +#if CONFIG_VP6_DECODER static int vp6_adjust(int v, int t) { int V = v, s = v >> 31; @@ -56,44 +85,19 @@ static int vp6_adjust(int v, int t) return V; } - -#define VP56_EDGE_FILTER(pfx, suf, pix_inc, line_inc) \ -static void pfx ## _edge_filter_ ## suf(uint8_t *yuv, ptrdiff_t stride, \ - int t) \ -{ \ - int pix2_inc = 2 * pix_inc; \ - int i, v; \ - \ - for (i=0; i<12; i++) { \ - v = (yuv[-pix2_inc] + 3*(yuv[0]-yuv[-pix_inc]) - yuv[pix_inc] + 4)>>3;\ - v = pfx##_adjust(v, t); \ - yuv[-pix_inc] = av_clip_uint8(yuv[-pix_inc] + v); \ - yuv[0] = av_clip_uint8(yuv[0] - v); \ - yuv += line_inc; \ - } \ -} - -VP56_EDGE_FILTER(vp5, hor, 1, stride) -VP56_EDGE_FILTER(vp5, ver, stride, 1) VP56_EDGE_FILTER(vp6, hor, 1, stride) VP56_EDGE_FILTER(vp6, ver, stride, 1) -av_cold void ff_vp56dsp_init(VP56DSPContext *s, enum AVCodecID codec) +av_cold void ff_vp6dsp_init(VP56DSPContext *s) { - if (codec == AV_CODEC_ID_VP5) { - s->edge_filter_hor = vp5_edge_filter_hor; - s->edge_filter_ver = vp5_edge_filter_ver; - } else { - s->edge_filter_hor = vp6_edge_filter_hor; - s->edge_filter_ver = vp6_edge_filter_ver; + s->edge_filter_hor = vp6_edge_filter_hor; + s->edge_filter_ver = vp6_edge_filter_ver; - if (CONFIG_VP6_DECODER) { - s->vp6_filter_diag4 = ff_vp6_filter_diag4_c; + s->vp6_filter_diag4 = ff_vp6_filter_diag4_c; - if (ARCH_ARM) - ff_vp6dsp_init_arm(s, codec); - if (ARCH_X86) - ff_vp6dsp_init_x86(s, codec); - } - } + if (ARCH_ARM) + ff_vp6dsp_init_arm(s); + if (ARCH_X86) + ff_vp6dsp_init_x86(s); } +#endif /* CONFIG_VP6_DECODER */ diff --git a/libavcodec/vp56dsp.h b/libavcodec/vp56dsp.h index d52ee660dbbd7..8bf7a4655692b 100644 --- a/libavcodec/vp56dsp.h +++ b/libavcodec/vp56dsp.h @@ -24,8 +24,6 @@ #include #include -#include "avcodec.h" - typedef struct VP56DSPContext { void (*edge_filter_hor)(uint8_t *yuv, ptrdiff_t stride, int t); void (*edge_filter_ver)(uint8_t *yuv, ptrdiff_t stride, int t); @@ -37,8 +35,10 @@ typedef struct VP56DSPContext { void ff_vp6_filter_diag4_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride, const int16_t *h_weights, const int16_t *v_weights); -void ff_vp56dsp_init(VP56DSPContext *s, enum AVCodecID codec); -void ff_vp6dsp_init_arm(VP56DSPContext *s, enum AVCodecID codec); -void ff_vp6dsp_init_x86(VP56DSPContext* c, enum AVCodecID codec); +void ff_vp5dsp_init(VP56DSPContext *s); +void ff_vp6dsp_init(VP56DSPContext *s); + +void ff_vp6dsp_init_arm(VP56DSPContext *s); +void ff_vp6dsp_init_x86(VP56DSPContext *s); #endif /* AVCODEC_VP56DSP_H */ diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c index aa0d09effbc81..40948ad0c5948 100644 --- a/libavcodec/vp6.c +++ b/libavcodec/vp6.c @@ -612,6 +612,7 @@ static av_cold int vp6_decode_init(AVCodecContext *avctx) if ((ret = ff_vp56_init(avctx, avctx->codec->id == AV_CODEC_ID_VP6, avctx->codec->id == AV_CODEC_ID_VP6A)) < 0) return ret; + ff_vp6dsp_init(&s->vp56dsp); s->vp56_coord_div = vp6_coord_div; s->parse_vector_adjustment = vp6_parse_vector_adjustment; diff --git a/libavcodec/x86/vp6dsp_init.c b/libavcodec/x86/vp6dsp_init.c index 472e03439e9f9..6d98db19d4479 100644 --- a/libavcodec/x86/vp6dsp_init.c +++ b/libavcodec/x86/vp6dsp_init.c @@ -30,7 +30,7 @@ void ff_vp6_filter_diag4_mmx(uint8_t *dst, uint8_t *src, ptrdiff_t stride, void ff_vp6_filter_diag4_sse2(uint8_t *dst, uint8_t *src, ptrdiff_t stride, const int16_t *h_weights,const int16_t *v_weights); -av_cold void ff_vp6dsp_init_x86(VP56DSPContext* c, enum AVCodecID codec) +av_cold void ff_vp6dsp_init_x86(VP56DSPContext *c) { int cpu_flags = av_get_cpu_flags(); From 4ab496261b12e20ef293b7adca4fcaef1a67c538 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 24 Aug 2016 17:00:11 +0200 Subject: [PATCH 0116/3374] libvpx: Cast a pointer to const to squelch a warning libavcodec/libvpxdec.c:100:57: warning: passing argument 3 of 'av_image_copy' from incompatible pointer type av_image_copy(picture->data, picture->linesize, img->planes, libavutil/imgutils.h:116:6: note: expected 'const uint8_t **' but argument is of type 'unsigned char **' void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], --- libavcodec/libvpxdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/libvpxdec.c b/libavcodec/libvpxdec.c index 93a720f56690a..6d3b29fefaf5e 100644 --- a/libavcodec/libvpxdec.c +++ b/libavcodec/libvpxdec.c @@ -97,7 +97,7 @@ static int vp8_decode(AVCodecContext *avctx, } if ((ret = ff_get_buffer(avctx, picture, 0)) < 0) return ret; - av_image_copy(picture->data, picture->linesize, img->planes, + av_image_copy(picture->data, picture->linesize, (const uint8_t **) img->planes, img->stride, avctx->pix_fmt, img->d_w, img->d_h); #if VPX_IMAGE_ABI_VERSION >= 4 switch (img->range) { From eb96505b761eb02b6a3efc76d854afa6a41941ff Mon Sep 17 00:00:00 2001 From: Derek Buitenhuis Date: Fri, 26 Aug 2016 14:30:06 +0100 Subject: [PATCH 0117/3374] mov: Remove ancient heuristic hack This breaks files with legitimate single-entry edit lists, and the hack, introduced in f03a081df09f9c4798a17d7e24446ed47924b11b, has no link to any known sample in its commit message. Signed-off-by: Derek Buitenhuis Signed-off-by: Luca Barbato --- libavformat/isom.h | 1 - libavformat/mov.c | 8 +------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/libavformat/isom.h b/libavformat/isom.h index 75aa70bccc443..58f0a2006213a 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -128,7 +128,6 @@ typedef struct MOVStreamContext { unsigned drefs_count; MOVDref *drefs; int dref_id; - int wrong_dts; ///< dts are wrong due to huge ctts offset (iMovie files) int width; ///< tkhd width int height; ///< tkhd height int dts_shift; ///< dts shift when ctts is negative diff --git a/libavformat/mov.c b/libavformat/mov.c index 03427d7e06ea5..89c2c23fe4720 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -2307,12 +2307,8 @@ static void mov_build_index(MOVContext *mov, AVStream *st) sc->time_offset = av_rescale(sc->time_offset, sc->time_scale, mov->time_scale); current_dts = -sc->time_offset; if (sc->ctts_data && sc->stts_data && sc->stts_data[0].duration && - sc->ctts_data[0].duration / sc->stts_data[0].duration > 16) { - /* more than 16 frames delay, dts are likely wrong - this happens with files created by iMovie */ - sc->wrong_dts = 1; + sc->ctts_data[0].duration / sc->stts_data[0].duration > 16) st->internal->avctx->has_b_frames = 1; - } } /* only use old uncompressed audio chunk demuxing when stts specifies it */ @@ -3670,8 +3666,6 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) sc->ctts_index++; sc->ctts_sample = 0; } - if (sc->wrong_dts) - pkt->dts = AV_NOPTS_VALUE; } else { int64_t next_dts = (sc->current_sample < st->nb_index_entries) ? st->index_entries[sc->current_sample].timestamp : st->duration; From 8db804e8f549d5b86a1edf62736e0ef80f160da9 Mon Sep 17 00:00:00 2001 From: Derek Buitenhuis Date: Fri, 26 Aug 2016 14:30:07 +0100 Subject: [PATCH 0118/3374] mov: Remove old b-frame/video delay heuristic This was added before edts support existed, and is no longer valid. Signed-off-by: Derek Buitenhuis Signed-off-by: Luca Barbato --- libavformat/mov.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 89c2c23fe4720..ca49716026ee6 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -2306,9 +2306,6 @@ static void mov_build_index(MOVContext *mov, AVStream *st) if (sc->time_offset < 0) sc->time_offset = av_rescale(sc->time_offset, sc->time_scale, mov->time_scale); current_dts = -sc->time_offset; - if (sc->ctts_data && sc->stts_data && sc->stts_data[0].duration && - sc->ctts_data[0].duration / sc->stts_data[0].duration > 16) - st->internal->avctx->has_b_frames = 1; } /* only use old uncompressed audio chunk demuxing when stts specifies it */ From 95f80293456d9d4b1b096621260c38bc90325ec0 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Thu, 21 Jul 2016 15:47:47 +0200 Subject: [PATCH 0119/3374] avprobe: Fix memory leak After init_opts() there needs to be an uninit_opts() call to free the swscale context and other buffers. Signed-off-by: Luca Barbato --- avprobe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avprobe.c b/avprobe.c index abaaee1374568..eff9c0d308bbe 100644 --- a/avprobe.c +++ b/avprobe.c @@ -1089,7 +1089,7 @@ int main(int argc, char **argv) avio_flush(probe_out); av_freep(&probe_out); av_freep(&buffer); - + uninit_opts(); avformat_network_deinit(); return ret; From 728e80cd2e1d4b7c3e26489efcd77bd7a9e84a99 Mon Sep 17 00:00:00 2001 From: Burt P Date: Fri, 26 Aug 2016 16:12:30 +0200 Subject: [PATCH 0120/3374] High Definition Compatible Digital (HDCD) decoder filter, using libhdcd Signed-off-by: Burt P Signed-off-by: Diego Biurrun Signed-off-by: Luca Barbato --- Changelog | 1 + configure | 4 + doc/filters.texi | 47 ++++++++++ doc/general.texi | 9 ++ libavfilter/Makefile | 1 + libavfilter/af_hdcd.c | 197 +++++++++++++++++++++++++++++++++++++++ libavfilter/allfilters.c | 1 + libavfilter/version.h | 2 +- 8 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 libavfilter/af_hdcd.c diff --git a/Changelog b/Changelog index 0d04f476e72a8..b6c8fdbf2a109 100644 --- a/Changelog +++ b/Changelog @@ -62,6 +62,7 @@ version : - Intel QSV video scaling and deinterlacing filter - OpenH264 decoder wrapper - Removed the legacy X11 screen grabber, use XCB instead +- HDCD decoding filter through libhdcd version 11: diff --git a/configure b/configure index e7bf5371f33cc..660b06284acc8 100755 --- a/configure +++ b/configure @@ -197,6 +197,7 @@ External library support: --enable-libfontconfig font configuration and management --enable-libfreetype font rendering --enable-libgsm GSM audio encoding/decoding + --enable-libhdcd HDCD decoding filter --enable-libilbc ILBC audio encoding/decoding --enable-libkvazaar HEVC video encoding --enable-libmp3lame MP3 audio encoding @@ -1270,6 +1271,7 @@ EXTERNAL_LIBRARY_LIST=" libfontconfig libfreetype libgsm + libhdcd libilbc libkvazaar libmp3lame @@ -2426,6 +2428,7 @@ frei0r_filter_deps="frei0r dlopen" frei0r_filter_extralibs='$ldl' frei0r_src_filter_deps="frei0r dlopen" frei0r_src_filter_extralibs='$ldl' +hdcd_filter_deps="libhdcd" hqdn3d_filter_deps="gpl" interlace_filter_deps="gpl" ocv_filter_deps="libopencv" @@ -4606,6 +4609,7 @@ enabled libfreetype && require_pkg_config freetype2 "ft2build.h FT_FREETYP enabled libgsm && { for gsm_hdr in "gsm.h" "gsm/gsm.h"; do check_lib "${gsm_hdr}" gsm_create -lgsm && break; done || die "ERROR: libgsm not found"; } +enabled libhdcd && require_pkg_config libhdcd "hdcd/hdcd_simple.h" hdcd_new enabled libilbc && require libilbc ilbc.h WebRtcIlbcfix_InitDecode -lilbc enabled libkvazaar && require_pkg_config "kvazaar >= 0.8.1" kvazaar.h kvz_api_get enabled libmfx && require_pkg_config libmfx "mfx/mfxvideo.h" MFXInit diff --git a/doc/filters.texi b/doc/filters.texi index 2651f170a0554..954765f08ed56 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -647,6 +647,53 @@ avconv -i fl -i fr -i fc -i sl -i sr -i lfe -filter_complex out @end example +@section hdcd + +Decodes High Definition Compatible Digital (HDCD) data. A 16-bit PCM stream with +embedded HDCD codes is expanded into a 20-bit PCM stream. + +The filter supports the Peak Extend and Low-level Gain Adjustment features +of HDCD, and detects the Transient Filter flag. + +@example +avconv -i HDCD16.flac -af hdcd OUT24.flac +@end example + +When using the filter with WAV, note that the default encoding for WAV is 16-bit, +so the resulting 20-bit stream will be truncated back to 16-bit. Use something +like @command{-acodec pcm_s24le} after the filter to get 24-bit PCM output. +@example +avconv -i HDCD16.wav -af hdcd OUT16.wav +avconv -i HDCD16.wav -af hdcd -acodec pcm_s24le OUT24.wav +@end example + +The filter accepts the following options: + +@table @option +@item analyze_mode +Replace audio with a solid tone and adjust the amplitude to signal some +specific aspect of the decoding process. The output file can be loaded in +an audio editor alongside the original to aid analysis. + +Modes are: +@table @samp +@item 0, off +Disabled +@item 1, lle +Gain adjustment level at each sample +@item 2, pe +Samples where peak extend occurs +@item 3, cdt +Samples where the code detect timer is active +@item 4, tgm +Samples where the target gain does not match between channels +@item 5, pel +Any samples above peak extend level +@item 6, ltgm +Gain adjustment level at each sample, in each channel +@end table +@end table + @section resample Convert the audio sample format, sample rate and channel layout. It is not meant to be used directly; it is inserted automatically by libavfilter diff --git a/doc/general.texi b/doc/general.texi index ea56beff92138..1708871d8a09e 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -157,6 +157,15 @@ Go to @url{https://github.com/dekkers/libilbc} and follow the instructions for installing the library. Then pass @code{--enable-libilbc} to configure to enable it. +@section libhdcd + +Libav can make use of the libhdcd library for High Definition Compatible +Digital (HDCD) decoding via the @code{hdcd} filter. + +Go to @url{https://github.com/bp0/libhdcd} and follow the instructions for +installing the library. Then pass @code{--enable-libhdcd} to configure to +enable it. + @section AviSynth Libav can read AviSynth scripts as input. To enable support you need a diff --git a/libavfilter/Makefile b/libavfilter/Makefile index dea8ffa50faf7..c3c1beaa0f360 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -34,6 +34,7 @@ OBJS-$(CONFIG_BS2B_FILTER) += af_bs2b.o OBJS-$(CONFIG_CHANNELMAP_FILTER) += af_channelmap.o OBJS-$(CONFIG_CHANNELSPLIT_FILTER) += af_channelsplit.o OBJS-$(CONFIG_COMPAND_FILTER) += af_compand.o +OBJS-$(CONFIG_HDCD_FILTER) += af_hdcd.o OBJS-$(CONFIG_JOIN_FILTER) += af_join.o OBJS-$(CONFIG_RESAMPLE_FILTER) += af_resample.o OBJS-$(CONFIG_VOLUME_FILTER) += af_volume.o diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c new file mode 100644 index 0000000000000..b9dadecca4e70 --- /dev/null +++ b/libavfilter/af_hdcd.c @@ -0,0 +1,197 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * HDCD decoding filter, using libhdcd + */ + +#include + +#include "libavutil/channel_layout.h" +#include "libavutil/opt.h" + +#include "audio.h" +#include "avfilter.h" +#include "formats.h" +#include "internal.h" + +typedef struct HDCDContext { + const AVClass *class; + + hdcd_simple *shdcd; + + /* AVOption members */ + /** analyze mode replaces the audio with a solid tone and adjusts + * the amplitude to signal some specific aspect of the decoding + * process. See docs or HDCD_ANA_* defines. */ + int analyze_mode; + /* end AVOption members */ +} HDCDContext; + +#define OFFSET(x) offsetof(HDCDContext, x) +#define A AV_OPT_FLAG_AUDIO_PARAM +#define HDCD_ANA_MAX 6 +static const AVOption hdcd_options[] = { + { "analyze_mode", "Replace audio with solid tone and signal some processing aspect in the amplitude.", + OFFSET(analyze_mode), AV_OPT_TYPE_INT, { .i64=HDCD_ANA_OFF }, 0, HDCD_ANA_MAX, A, "analyze_mode"}, + { "off", HDCD_ANA_OFF_DESC, 0, AV_OPT_TYPE_CONST, { .i64 = HDCD_ANA_OFF}, 0, 0, A, "analyze_mode" }, + { "lle", HDCD_ANA_LLE_DESC, 0, AV_OPT_TYPE_CONST, { .i64 = HDCD_ANA_LLE}, 0, 0, A, "analyze_mode" }, + { "pe", HDCD_ANA_PE_DESC, 0, AV_OPT_TYPE_CONST, { .i64 = HDCD_ANA_PE}, 0, 0, A, "analyze_mode" }, + { "cdt", HDCD_ANA_CDT_DESC, 0, AV_OPT_TYPE_CONST, { .i64 = HDCD_ANA_CDT}, 0, 0, A, "analyze_mode" }, + { "tgm", HDCD_ANA_TGM_DESC, 0, AV_OPT_TYPE_CONST, { .i64 = HDCD_ANA_TGM}, 0, 0, A, "analyze_mode" }, + { "pel", HDCD_ANA_PEL_DESC, 0, AV_OPT_TYPE_CONST, { .i64 = HDCD_ANA_PEL}, 0, 0, A, "analyze_mode" }, + { "ltgm", HDCD_ANA_LTGM_DESC, 0, AV_OPT_TYPE_CONST, { .i64 = HDCD_ANA_LTGM}, 0, 0, A, "analyze_mode" }, + { NULL } +}; + +static const AVClass hdcd_class = { + .class_name = "HDCD filter", + .item_name = av_default_item_name, + .option = hdcd_options, + .version = LIBAVFILTER_VERSION_INT, +}; + +static int filter_frame(AVFilterLink *inlink, AVFrame *in) +{ + AVFilterContext *ctx = inlink->dst; + HDCDContext *s = ctx->priv; + AVFilterLink *outlink = ctx->outputs[0]; + AVFrame *out; + const int16_t *in_data; + int32_t *out_data; + int n, result; + int channel_count = av_get_channel_layout_nb_channels(in->channel_layout); + + out = ff_get_audio_buffer(outlink, in->nb_samples); + if (!out) { + av_frame_free(&in); + return AVERROR(ENOMEM); + } + result = av_frame_copy_props(out, in); + if (result) { + av_frame_free(&out); + av_frame_free(&in); + return result; + } + + in_data = (int16_t *)in->data[0]; + out_data = (int32_t *)out->data[0]; + for (n = 0; n < in->nb_samples * channel_count; n++) + out_data[n] = in_data[n]; + + hdcd_process(s->shdcd, out_data, in->nb_samples); + + av_frame_free(&in); + return ff_filter_frame(outlink, out); +} + +static int query_formats(AVFilterContext *ctx) +{ + AVFilterFormats *in_formats, *out_formats, *sample_rates = NULL; + AVFilterChannelLayouts *layouts = NULL; + AVFilterLink *inlink = ctx->inputs[0]; + AVFilterLink *outlink = ctx->outputs[0]; + + static const enum AVSampleFormat sample_fmts_in[] = { + AV_SAMPLE_FMT_S16, + AV_SAMPLE_FMT_NONE + }; + static const enum AVSampleFormat sample_fmts_out[] = { + AV_SAMPLE_FMT_S32, + AV_SAMPLE_FMT_NONE + }; + + ff_add_channel_layout(&layouts, AV_CH_LAYOUT_STEREO); + + ff_set_common_channel_layouts(ctx, layouts); + + in_formats = ff_make_format_list(sample_fmts_in); + out_formats = ff_make_format_list(sample_fmts_out); + if (!in_formats || !out_formats) + return AVERROR(ENOMEM); + + ff_formats_ref(in_formats, &inlink->out_formats); + ff_formats_ref(out_formats, &outlink->in_formats); + + ff_add_format(&sample_rates, 44100); + ff_set_common_samplerates(ctx, sample_rates); + return 0; +} + +static av_cold void uninit(AVFilterContext *ctx) +{ + HDCDContext *s = ctx->priv; + char detect_str[256] = ""; + + /* log the HDCD decode information */ + hdcd_detect_str(s->shdcd, detect_str, sizeof(detect_str)); + av_log(ctx, AV_LOG_INFO, "%s\n", detect_str); + + hdcd_free(s->shdcd); +} + +/** callback for error logging */ +static void af_hdcd_log(const void *priv, const char *fmt, va_list args) +{ + av_vlog((AVFilterContext *)priv, AV_LOG_VERBOSE, fmt, args); +} + +static av_cold int init(AVFilterContext *ctx) +{ + HDCDContext *s = ctx->priv; + + s->shdcd = hdcd_new(); + hdcd_logger_attach(s->shdcd, af_hdcd_log, ctx); + + if (s->analyze_mode) + hdcd_analyze_mode(s->shdcd, s->analyze_mode); + av_log(ctx, AV_LOG_VERBOSE, "Analyze mode: [%d] %s\n", + s->analyze_mode, hdcd_str_analyze_mode_desc(s->analyze_mode)); + + return 0; +} + +static const AVFilterPad avfilter_af_hdcd_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_AUDIO, + .filter_frame = filter_frame, + }, + { NULL } +}; + +static const AVFilterPad avfilter_af_hdcd_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_AUDIO, + }, + { NULL } +}; + +AVFilter ff_af_hdcd = { + .name = "hdcd", + .description = NULL_IF_CONFIG_SMALL("Apply High Definition Compatible Digital (HDCD) decoding."), + .priv_size = sizeof(HDCDContext), + .priv_class = &hdcd_class, + .init = init, + .uninit = uninit, + .query_formats = query_formats, + .inputs = avfilter_af_hdcd_inputs, + .outputs = avfilter_af_hdcd_outputs, +}; diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index de49d65298090..ec27b5ae6ef65 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -57,6 +57,7 @@ void avfilter_register_all(void) REGISTER_FILTER(CHANNELMAP, channelmap, af); REGISTER_FILTER(CHANNELSPLIT, channelsplit, af); REGISTER_FILTER(COMPAND, compand, af); + REGISTER_FILTER(HDCD, hdcd, af); REGISTER_FILTER(JOIN, join, af); REGISTER_FILTER(RESAMPLE, resample, af); REGISTER_FILTER(VOLUME, volume, af); diff --git a/libavfilter/version.h b/libavfilter/version.h index 7f3ede2d042b1..febfc8fa1d4f9 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 6 -#define LIBAVFILTER_VERSION_MINOR 6 +#define LIBAVFILTER_VERSION_MINOR 7 #define LIBAVFILTER_VERSION_MICRO 0 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ From 80fc75d51e3312e1890591048eb6a3d499b6e49d Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Thu, 25 Aug 2016 11:59:59 -0400 Subject: [PATCH 0121/3374] Changelog: Mention mov with multiple stsd Signed-off-by: Luca Barbato --- Changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog b/Changelog index b6c8fdbf2a109..f39a1bb2e5f3f 100644 --- a/Changelog +++ b/Changelog @@ -60,6 +60,7 @@ version : - MagicYUV decoder - Duck TrueMotion 2.0 Real Time decoder - Intel QSV video scaling and deinterlacing filter +- Support MOV with multiple sample description tables - OpenH264 decoder wrapper - Removed the legacy X11 screen grabber, use XCB instead - HDCD decoding filter through libhdcd From 72eba6558ee4f10239ba3f472c0b033ec70082a7 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 26 Aug 2016 14:56:01 +0200 Subject: [PATCH 0122/3374] wmavoice: Simplify GetBitContext initialization --- libavcodec/wmavoice.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c index 62b603c6aa3e8..19c06f44726f6 100644 --- a/libavcodec/wmavoice.c +++ b/libavcodec/wmavoice.c @@ -1672,9 +1672,7 @@ static int check_bits_for_superframe(GetBitContext *orig_gb, const struct frame_type_desc *frame_desc; /* initialize a copy */ - init_get_bits(gb, orig_gb->buffer, orig_gb->size_in_bits); - skip_bits_long(gb, get_bits_count(orig_gb)); - assert(get_bits_left(gb) == get_bits_left(orig_gb)); + *gb = *orig_gb; /* superframe header */ if (get_bits_left(gb) < 14) From 123ccd07c55ccf075cc5daf5581237fbccb86bdb Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sat, 6 Aug 2016 18:18:40 +0100 Subject: [PATCH 0123/3374] lavc: Rewrite VAAPI decode infrastructure Moves much of the setup logic for VAAPI decoding into lavc; the user now need only provide the hw_frames_ctx. --- libavcodec/Makefile | 5 +- libavcodec/vaapi_decode.c | 534 ++++++++++++++++++++++++++++++++++++++ libavcodec/vaapi_decode.h | 90 +++++++ 3 files changed, 627 insertions(+), 2 deletions(-) create mode 100644 libavcodec/vaapi_decode.c create mode 100644 libavcodec/vaapi_decode.h diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 8eb7d362c0f37..4d04d6a113a01 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -610,7 +610,7 @@ OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcmenc.o adpcm_data.o # hardware accelerators OBJS-$(CONFIG_D3D11VA) += dxva2.o OBJS-$(CONFIG_DXVA2) += dxva2.o -OBJS-$(CONFIG_VAAPI) += vaapi.o +OBJS-$(CONFIG_VAAPI) += vaapi.o vaapi_decode.o OBJS-$(CONFIG_VDA) += vda.o OBJS-$(CONFIG_VDPAU) += vdpau.o @@ -777,7 +777,8 @@ SKIPHEADERS-$(CONFIG_NVENC) += nvenc.h SKIPHEADERS-$(CONFIG_QSV) += qsv.h qsv_internal.h SKIPHEADERS-$(CONFIG_QSVDEC) += qsvdec.h SKIPHEADERS-$(CONFIG_QSVENC) += qsvenc.h -SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_encode.h vaapi_internal.h +SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_decode.h vaapi_encode.h \ + vaapi_internal.h SKIPHEADERS-$(CONFIG_VDA) += vda.h vda_internal.h SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h vdpau_internal.h diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c new file mode 100644 index 0000000000000..78b479ff6f07e --- /dev/null +++ b/libavcodec/vaapi_decode.c @@ -0,0 +1,534 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/avassert.h" +#include "libavutil/common.h" + +#include "avcodec.h" +#include "internal.h" +#include "vaapi_decode.h" + + +int ff_vaapi_decode_make_param_buffer(AVCodecContext *avctx, + VAAPIDecodePicture *pic, + int type, + const void *data, + size_t size) +{ + VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data; + VAStatus vas; + VABufferID buffer; + + av_assert0(pic->nb_param_buffers + 1 <= MAX_PARAM_BUFFERS); + + vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context, + type, size, 1, (void*)data, &buffer); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to create parameter " + "buffer (type %d): %d (%s).\n", + type, vas, vaErrorStr(vas)); + return AVERROR(EIO); + } + + pic->param_buffers[pic->nb_param_buffers++] = buffer; + + av_log(avctx, AV_LOG_DEBUG, "Param buffer (type %d, %zu bytes) " + "is %#x.\n", type, size, buffer); + return 0; +} + + +int ff_vaapi_decode_make_slice_buffer(AVCodecContext *avctx, + VAAPIDecodePicture *pic, + const void *params_data, + size_t params_size, + const void *slice_data, + size_t slice_size) +{ + VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data; + VAStatus vas; + int index; + + av_assert0(pic->nb_slices <= pic->slices_allocated); + if (pic->nb_slices == pic->slices_allocated) { + if (pic->slices_allocated > 0) + pic->slices_allocated *= 2; + else + pic->slices_allocated = 64; + + pic->slice_buffers = + av_realloc_array(pic->slice_buffers, + pic->slices_allocated, + 2 * sizeof(*pic->slice_buffers)); + if (!pic->slice_buffers) + return AVERROR(ENOMEM); + } + av_assert0(pic->nb_slices + 1 <= pic->slices_allocated); + + index = 2 * pic->nb_slices; + + vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context, + VASliceParameterBufferType, + params_size, 1, (void*)params_data, + &pic->slice_buffers[index]); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to create slice " + "parameter buffer: %d (%s).\n", vas, vaErrorStr(vas)); + return AVERROR(EIO); + } + + av_log(avctx, AV_LOG_DEBUG, "Slice %d param buffer (%zu bytes) " + "is %#x.\n", pic->nb_slices, params_size, + pic->slice_buffers[index]); + + vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context, + VASliceDataBufferType, + slice_size, 1, (void*)slice_data, + &pic->slice_buffers[index + 1]); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to create slice " + "data buffer (size %zu): %d (%s).\n", + slice_size, vas, vaErrorStr(vas)); + vaDestroyBuffer(ctx->hwctx->display, + pic->slice_buffers[index]); + return AVERROR(EIO); + } + + av_log(avctx, AV_LOG_DEBUG, "Slice %d data buffer (%zu bytes) " + "is %#x.\n", pic->nb_slices, slice_size, + pic->slice_buffers[index + 1]); + + ++pic->nb_slices; + return 0; +} + +static void ff_vaapi_decode_destroy_buffers(AVCodecContext *avctx, + VAAPIDecodePicture *pic) +{ + VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data; + VAStatus vas; + int i; + + for (i = 0; i < pic->nb_param_buffers; i++) { + vas = vaDestroyBuffer(ctx->hwctx->display, + pic->param_buffers[i]); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to destroy " + "parameter buffer %#x: %d (%s).\n", + pic->param_buffers[i], vas, vaErrorStr(vas)); + } + } + + for (i = 0; i < 2 * pic->nb_slices; i++) { + vas = vaDestroyBuffer(ctx->hwctx->display, + pic->slice_buffers[i]); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to destroy slice " + "slice buffer %#x: %d (%s).\n", + pic->slice_buffers[i], vas, vaErrorStr(vas)); + } + } +} + +int ff_vaapi_decode_issue(AVCodecContext *avctx, + VAAPIDecodePicture *pic) +{ + VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data; + VAStatus vas; + int err, i; + + av_log(avctx, AV_LOG_DEBUG, "Decode to surface %#x.\n", + pic->output_surface); + + for (i = 0; i < pic->nb_param_buffers; i++) + vaUnmapBuffer(ctx->hwctx->display, pic->param_buffers[i]); + + vas = vaBeginPicture(ctx->hwctx->display, ctx->va_context, + pic->output_surface); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to begin picture decode " + "issue: %d (%s).\n", vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail_with_picture; + } + + vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context, + pic->param_buffers, pic->nb_param_buffers); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to upload decode " + "parameters: %d (%s).\n", vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail_with_picture; + } + + vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context, + pic->slice_buffers, 2 * pic->nb_slices); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to upload slices: " + "%d (%s).\n", vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail_with_picture; + } + + vas = vaEndPicture(ctx->hwctx->display, ctx->va_context); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to end picture decode " + "issue: %d (%s).\n", vas, vaErrorStr(vas)); + err = AVERROR(EIO); + if (ctx->hwctx->driver_quirks & + AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS) + goto fail; + else + goto fail_at_end; + } + + if (ctx->hwctx->driver_quirks & + AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS) + ff_vaapi_decode_destroy_buffers(avctx, pic); + + pic->nb_slices = 0; + pic->slices_allocated = 0; + av_freep(&pic->slice_buffers); + + return 0; + +fail_with_picture: + vas = vaEndPicture(ctx->hwctx->display, ctx->va_context); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to end picture decode " + "after error: %d (%s).\n", vas, vaErrorStr(vas)); + } +fail: + ff_vaapi_decode_destroy_buffers(avctx, pic); +fail_at_end: + return err; +} + +int ff_vaapi_decode_cancel(AVCodecContext *avctx, + VAAPIDecodePicture *pic) +{ + ff_vaapi_decode_destroy_buffers(avctx, pic); + + pic->nb_param_buffers = 0; + pic->nb_slices = 0; + pic->slices_allocated = 0; + av_freep(&pic->slice_buffers); + + return 0; +} + +static const struct { + enum AVCodecID codec_id; + int codec_profile; + VAProfile va_profile; +} vaapi_profile_map[] = { +#define MAP(c, p, v) { AV_CODEC_ID_ ## c, FF_PROFILE_ ## p, VAProfile ## v } + MAP(MPEG2VIDEO, MPEG2_SIMPLE, MPEG2Simple ), + MAP(MPEG2VIDEO, MPEG2_MAIN, MPEG2Main ), + MAP(H263, UNKNOWN, H263Baseline), + MAP(MPEG4, MPEG4_SIMPLE, MPEG4Simple ), + MAP(MPEG4, MPEG4_ADVANCED_SIMPLE, + MPEG4AdvancedSimple), + MAP(MPEG4, MPEG4_MAIN, MPEG4Main ), + MAP(H264, H264_CONSTRAINED_BASELINE, + H264ConstrainedBaseline), + MAP(H264, H264_BASELINE, H264Baseline), + MAP(H264, H264_MAIN, H264Main ), + MAP(H264, H264_HIGH, H264High ), +#if VA_CHECK_VERSION(0, 37, 0) + MAP(HEVC, HEVC_MAIN, HEVCMain ), +#endif + MAP(WMV3, VC1_SIMPLE, VC1Simple ), + MAP(WMV3, VC1_MAIN, VC1Main ), + MAP(WMV3, VC1_COMPLEX, VC1Advanced ), + MAP(WMV3, VC1_ADVANCED, VC1Advanced ), + MAP(VC1, VC1_SIMPLE, VC1Simple ), + MAP(VC1, VC1_MAIN, VC1Main ), + MAP(VC1, VC1_COMPLEX, VC1Advanced ), + MAP(VC1, VC1_ADVANCED, VC1Advanced ), +#if VA_CHECK_VERSION(0, 35, 0) + MAP(VP8, UNKNOWN, VP8Version0_3 ), +#endif +#if VA_CHECK_VERSION(0, 38, 0) + MAP(VP9, VP9_0, VP9Profile0 ), +#endif +#undef MAP +}; + +static int vaapi_decode_make_config(AVCodecContext *avctx) +{ + VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data; + + AVVAAPIHWConfig *hwconfig = NULL; + AVHWFramesConstraints *constraints = NULL; + VAStatus vas; + int err, i, j; + const AVCodecDescriptor *codec_desc; + VAProfile profile, *profile_list = NULL; + int profile_count, exact_match, alt_profile; + + // Allowing a profile mismatch can be useful because streams may + // over-declare their required capabilities - in particular, many + // H.264 baseline profile streams (notably some of those in FATE) + // only use the feature set of constrained baseline. This flag + // would have to be be set by some external means in order to + // actually be useful. (AV_HWACCEL_FLAG_IGNORE_PROFILE?) + int allow_profile_mismatch = 0; + + codec_desc = avcodec_descriptor_get(avctx->codec_id); + if (!codec_desc) { + err = AVERROR(EINVAL); + goto fail; + } + + profile_count = vaMaxNumProfiles(ctx->hwctx->display); + profile_list = av_malloc_array(profile_count, + sizeof(VAProfile)); + if (!profile_list) { + err = AVERROR(ENOMEM); + goto fail; + } + + vas = vaQueryConfigProfiles(ctx->hwctx->display, + profile_list, &profile_count); + if (vas != VA_STATUS_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed to query profiles: " + "%d (%s).\n", vas, vaErrorStr(vas)); + err = AVERROR(ENOSYS); + goto fail; + } + + profile = VAProfileNone; + exact_match = 0; + + for (i = 0; i < FF_ARRAY_ELEMS(vaapi_profile_map); i++) { + int profile_match = 0; + if (avctx->codec_id != vaapi_profile_map[i].codec_id) + continue; + if (avctx->profile == vaapi_profile_map[i].codec_profile) + profile_match = 1; + profile = vaapi_profile_map[i].va_profile; + for (j = 0; j < profile_count; j++) { + if (profile == profile_list[j]) { + exact_match = profile_match; + break; + } + } + if (j < profile_count) { + if (exact_match) + break; + alt_profile = vaapi_profile_map[i].codec_profile; + } + } + av_freep(&profile_list); + + if (profile == VAProfileNone) { + av_log(ctx, AV_LOG_ERROR, "No support for codec %s " + "profile %d.\n", codec_desc->name, avctx->profile); + err = AVERROR(ENOSYS); + goto fail; + } + if (!exact_match) { + if (allow_profile_mismatch) { + av_log(avctx, AV_LOG_VERBOSE, "Codec %s profile %d not " + "supported for hardware decode.\n", + codec_desc->name, avctx->profile); + av_log(avctx, AV_LOG_WARNING, "Using possibly-" + "incompatible profile %d instead.\n", + alt_profile); + } else { + av_log(avctx, AV_LOG_VERBOSE, "Codec %s profile %d not " + "supported for hardware decode.\n", + codec_desc->name, avctx->profile); + err = AVERROR(EINVAL); + goto fail; + } + } + + ctx->va_profile = profile; + ctx->va_entrypoint = VAEntrypointVLD; + + vas = vaCreateConfig(ctx->hwctx->display, ctx->va_profile, + ctx->va_entrypoint, NULL, 0, + &ctx->va_config); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to create decode " + "configuration: %d (%s).\n", vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail; + } + + hwconfig = av_hwdevice_hwconfig_alloc(ctx->frames->device_ref); + if (!hwconfig) { + err = AVERROR(ENOMEM); + goto fail; + } + hwconfig->config_id = ctx->va_config; + + constraints = + av_hwdevice_get_hwframe_constraints(ctx->frames->device_ref, + hwconfig); + if (!constraints) { + // Ignore. + } else { + if (avctx->coded_width < constraints->min_width || + avctx->coded_height < constraints->min_height || + avctx->coded_width > constraints->max_width || + avctx->coded_height > constraints->max_height) { + av_log(ctx, AV_LOG_ERROR, "Hardware does not support image " + "size %dx%d (constraints: width %d-%d height %d-%d).\n", + avctx->coded_width, avctx->coded_height, + constraints->min_width, constraints->max_width, + constraints->min_height, constraints->max_height); + err = AVERROR(EINVAL); + goto fail; + } + } + + av_hwframe_constraints_free(&constraints); + av_freep(&hwconfig); + + return 0; + +fail: + av_hwframe_constraints_free(&constraints); + av_freep(&hwconfig); + if (ctx->va_config != VA_INVALID_ID) { + vaDestroyConfig(ctx->hwctx->display, ctx->va_config); + ctx->va_config = VA_INVALID_ID; + } + av_freep(&profile_list); + return err; +} + +int ff_vaapi_decode_init(AVCodecContext *avctx) +{ + VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data; + VAStatus vas; + int err; + + ctx->va_config = VA_INVALID_ID; + ctx->va_context = VA_INVALID_ID; + + if (avctx->hwaccel_context) { + av_log(avctx, AV_LOG_WARNING, "Using deprecated struct " + "vaapi_context in decode.\n"); + + ctx->have_old_context = 1; + ctx->old_context = avctx->hwaccel_context; + + // Really we only want the VAAPI device context, but this + // allocates a whole generic device context because we don't + // have any other way to determine how big it should be. + ctx->device_ref = + av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_VAAPI); + if (!ctx->device_ref) { + err = AVERROR(ENOMEM); + goto fail; + } + ctx->device = (AVHWDeviceContext*)ctx->device_ref->data; + ctx->hwctx = ctx->device->hwctx; + + ctx->hwctx->display = ctx->old_context->display; + + // The old VAAPI decode setup assumed this quirk was always + // present, so set it here to avoid the behaviour changing. + ctx->hwctx->driver_quirks = + AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS; + + } else if (avctx->hw_frames_ctx) { + // This structure has a shorter lifetime than the enclosing + // AVCodecContext, so we inherit the references from there + // and do not need to make separate ones. + + ctx->frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data; + ctx->hwfc = ctx->frames->hwctx; + + ctx->device = ctx->frames->device_ctx; + ctx->hwctx = ctx->device->hwctx; + + } else { + av_log(avctx, AV_LOG_ERROR, "A hardware frames context is " + "required for VAAPI decoding.\n"); + err = AVERROR(EINVAL); + goto fail; + } + + if (ctx->have_old_context) { + ctx->va_config = ctx->old_context->config_id; + ctx->va_context = ctx->old_context->context_id; + + av_log(avctx, AV_LOG_DEBUG, "Using user-supplied decoder " + "context: %#x/%#x.\n", ctx->va_config, ctx->va_context); + } else { + err = vaapi_decode_make_config(avctx); + if (err) + goto fail; + + vas = vaCreateContext(ctx->hwctx->display, ctx->va_config, + avctx->coded_width, avctx->coded_height, + VA_PROGRESSIVE, + ctx->hwfc->surface_ids, + ctx->hwfc->nb_surfaces, + &ctx->va_context); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to create decode " + "context: %d (%s).\n", vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail; + } + + av_log(avctx, AV_LOG_DEBUG, "Decode context initialised: " + "%#x/%#x.\n", ctx->va_config, ctx->va_context); + } + + return 0; + +fail: + ff_vaapi_decode_uninit(avctx); + return err; +} + +int ff_vaapi_decode_uninit(AVCodecContext *avctx) +{ + VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data; + VAStatus vas; + + if (ctx->have_old_context) { + av_buffer_unref(&ctx->device_ref); + } else { + if (ctx->va_context != VA_INVALID_ID) { + vas = vaDestroyContext(ctx->hwctx->display, ctx->va_context); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to destroy decode " + "context %#x: %d (%s).\n", + ctx->va_context, vas, vaErrorStr(vas)); + } + } + if (ctx->va_config != VA_INVALID_ID) { + vas = vaDestroyConfig(ctx->hwctx->display, ctx->va_config); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to destroy decode " + "configuration %#x: %d (%s).\n", + ctx->va_config, vas, vaErrorStr(vas)); + } + } + } + + return 0; +} diff --git a/libavcodec/vaapi_decode.h b/libavcodec/vaapi_decode.h new file mode 100644 index 0000000000000..7882925a25ae0 --- /dev/null +++ b/libavcodec/vaapi_decode.h @@ -0,0 +1,90 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_VAAPI_DECODE_H +#define AVCODEC_VAAPI_DECODE_H + +#include + +#include "libavutil/frame.h" +#include "libavutil/hwcontext.h" +#include "libavutil/hwcontext_vaapi.h" + +#include "avcodec.h" +#include "vaapi.h" + +static inline VASurfaceID ff_vaapi_get_surface_id(AVFrame *pic) +{ + return (uintptr_t)pic->data[3]; +} + +enum { + MAX_PARAM_BUFFERS = 16, +}; + +typedef struct VAAPIDecodePicture { + VASurfaceID output_surface; + + int nb_param_buffers; + VABufferID param_buffers[MAX_PARAM_BUFFERS]; + + int nb_slices; + VABufferID *slice_buffers; + int slices_allocated; +} VAAPIDecodePicture; + +typedef struct VAAPIDecodeContext { + VAProfile va_profile; + VAEntrypoint va_entrypoint; + VAConfigID va_config; + VAContextID va_context; + + int have_old_context; + struct vaapi_context *old_context; + AVBufferRef *device_ref; + + AVHWDeviceContext *device; + AVVAAPIDeviceContext *hwctx; + + AVHWFramesContext *frames; + AVVAAPIFramesContext *hwfc; +} VAAPIDecodeContext; + + +int ff_vaapi_decode_make_param_buffer(AVCodecContext *avctx, + VAAPIDecodePicture *pic, + int type, + const void *data, + size_t size); + +int ff_vaapi_decode_make_slice_buffer(AVCodecContext *avctx, + VAAPIDecodePicture *pic, + const void *params_data, + size_t params_size, + const void *slice_data, + size_t slice_size); + +int ff_vaapi_decode_issue(AVCodecContext *avctx, + VAAPIDecodePicture *pic); +int ff_vaapi_decode_cancel(AVCodecContext *avctx, + VAAPIDecodePicture *pic); + +int ff_vaapi_decode_init(AVCodecContext *avctx); +int ff_vaapi_decode_uninit(AVCodecContext *avctx); + +#endif /* AVCODEC_VAAPI_DECODE_H */ From 2fe93244ab9465ef19c756a41524cbbf0580ee48 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sat, 6 Aug 2016 18:19:32 +0100 Subject: [PATCH 0124/3374] vaapi_h264: Convert to use the new VAAPI hwaccel code --- libavcodec/vaapi_h264.c | 235 +++++++++++++++++++++++----------------- 1 file changed, 137 insertions(+), 98 deletions(-) diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c index 2dd45e7428628..fa13fc0fbca62 100644 --- a/libavcodec/vaapi_h264.c +++ b/libavcodec/vaapi_h264.c @@ -20,10 +20,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "vaapi_internal.h" #include "h264dec.h" #include "h264_ps.h" -#include "mpegutils.h" +#include "vaapi_decode.h" /** * @file @@ -227,88 +226,102 @@ static int vaapi_h264_start_frame(AVCodecContext *avctx, av_unused uint32_t size) { const H264Context *h = avctx->priv_data; - struct vaapi_context * const vactx = avctx->hwaccel_context; + VAAPIDecodePicture *pic = h->cur_pic_ptr->hwaccel_picture_private; const PPS *pps = h->ps.pps; const SPS *sps = h->ps.sps; - VAPictureParameterBufferH264 *pic_param; - VAIQMatrixBufferH264 *iq_matrix; + VAPictureParameterBufferH264 pic_param; + VAIQMatrixBufferH264 iq_matrix; + int err; + + pic->output_surface = ff_vaapi_get_surface_id(h->cur_pic_ptr->f); + + pic_param = (VAPictureParameterBufferH264) { + .picture_width_in_mbs_minus1 = h->mb_width - 1, + .picture_height_in_mbs_minus1 = h->mb_height - 1, + .bit_depth_luma_minus8 = sps->bit_depth_luma - 8, + .bit_depth_chroma_minus8 = sps->bit_depth_chroma - 8, + .num_ref_frames = sps->ref_frame_count, + .seq_fields.bits = { + .chroma_format_idc = sps->chroma_format_idc, + .residual_colour_transform_flag = sps->residual_color_transform_flag, + .gaps_in_frame_num_value_allowed_flag = sps->gaps_in_frame_num_allowed_flag, + .frame_mbs_only_flag = sps->frame_mbs_only_flag, + .mb_adaptive_frame_field_flag = sps->mb_aff, + .direct_8x8_inference_flag = sps->direct_8x8_inference_flag, + .MinLumaBiPredSize8x8 = sps->level_idc >= 31, /* A.3.3.2 */ + .log2_max_frame_num_minus4 = sps->log2_max_frame_num - 4, + .pic_order_cnt_type = sps->poc_type, + .log2_max_pic_order_cnt_lsb_minus4 = sps->log2_max_poc_lsb - 4, + .delta_pic_order_always_zero_flag = sps->delta_pic_order_always_zero_flag, + }, + .num_slice_groups_minus1 = pps->slice_group_count - 1, + .slice_group_map_type = pps->mb_slice_group_map_type, + .slice_group_change_rate_minus1 = 0, /* FMO is not implemented */ + .pic_init_qp_minus26 = pps->init_qp - 26, + .pic_init_qs_minus26 = pps->init_qs - 26, + .chroma_qp_index_offset = pps->chroma_qp_index_offset[0], + .second_chroma_qp_index_offset = pps->chroma_qp_index_offset[1], + .pic_fields.bits = { + .entropy_coding_mode_flag = pps->cabac, + .weighted_pred_flag = pps->weighted_pred, + .weighted_bipred_idc = pps->weighted_bipred_idc, + .transform_8x8_mode_flag = pps->transform_8x8_mode, + .field_pic_flag = h->picture_structure != PICT_FRAME, + .constrained_intra_pred_flag = pps->constrained_intra_pred, + .pic_order_present_flag = pps->pic_order_present, + .deblocking_filter_control_present_flag = pps->deblocking_filter_parameters_present, + .redundant_pic_cnt_present_flag = pps->redundant_pic_cnt_present, + .reference_pic_flag = h->nal_ref_idc != 0, + }, + .frame_num = h->poc.frame_num, + }; + + fill_vaapi_pic(&pic_param.CurrPic, h->cur_pic_ptr, h->picture_structure); + err = fill_vaapi_ReferenceFrames(&pic_param, h); + if (err < 0) + goto fail; + + err = ff_vaapi_decode_make_param_buffer(avctx, pic, + VAPictureParameterBufferType, + &pic_param, sizeof(pic_param)); + if (err < 0) + goto fail; + + memcpy(iq_matrix.ScalingList4x4, + pps->scaling_matrix4, sizeof(iq_matrix.ScalingList4x4)); + memcpy(iq_matrix.ScalingList8x8[0], + pps->scaling_matrix8[0], sizeof(iq_matrix.ScalingList8x8[0])); + memcpy(iq_matrix.ScalingList8x8[1], + pps->scaling_matrix8[3], sizeof(iq_matrix.ScalingList8x8[0])); + + err = ff_vaapi_decode_make_param_buffer(avctx, pic, + VAIQMatrixBufferType, + &iq_matrix, sizeof(iq_matrix)); + if (err < 0) + goto fail; - vactx->slice_param_size = sizeof(VASliceParameterBufferH264); - - /* Fill in VAPictureParameterBufferH264. */ - pic_param = ff_vaapi_alloc_pic_param(vactx, sizeof(VAPictureParameterBufferH264)); - if (!pic_param) - return -1; - fill_vaapi_pic(&pic_param->CurrPic, h->cur_pic_ptr, h->picture_structure); - if (fill_vaapi_ReferenceFrames(pic_param, h) < 0) - return -1; - pic_param->picture_width_in_mbs_minus1 = h->mb_width - 1; - pic_param->picture_height_in_mbs_minus1 = h->mb_height - 1; - pic_param->bit_depth_luma_minus8 = sps->bit_depth_luma - 8; - pic_param->bit_depth_chroma_minus8 = sps->bit_depth_chroma - 8; - pic_param->num_ref_frames = sps->ref_frame_count; - pic_param->seq_fields.value = 0; /* reset all bits */ - pic_param->seq_fields.bits.chroma_format_idc = sps->chroma_format_idc; - pic_param->seq_fields.bits.residual_colour_transform_flag = sps->residual_color_transform_flag; /* XXX: only for 4:4:4 high profile? */ - pic_param->seq_fields.bits.gaps_in_frame_num_value_allowed_flag = sps->gaps_in_frame_num_allowed_flag; - pic_param->seq_fields.bits.frame_mbs_only_flag = sps->frame_mbs_only_flag; - pic_param->seq_fields.bits.mb_adaptive_frame_field_flag = sps->mb_aff; - pic_param->seq_fields.bits.direct_8x8_inference_flag = sps->direct_8x8_inference_flag; - pic_param->seq_fields.bits.MinLumaBiPredSize8x8 = sps->level_idc >= 31; /* A.3.3.2 */ - pic_param->seq_fields.bits.log2_max_frame_num_minus4 = sps->log2_max_frame_num - 4; - pic_param->seq_fields.bits.pic_order_cnt_type = sps->poc_type; - pic_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = sps->log2_max_poc_lsb - 4; - pic_param->seq_fields.bits.delta_pic_order_always_zero_flag = sps->delta_pic_order_always_zero_flag; - pic_param->num_slice_groups_minus1 = pps->slice_group_count - 1; - pic_param->slice_group_map_type = pps->mb_slice_group_map_type; - pic_param->slice_group_change_rate_minus1 = 0; /* XXX: unimplemented in Libav */ - pic_param->pic_init_qp_minus26 = pps->init_qp - 26; - pic_param->pic_init_qs_minus26 = pps->init_qs - 26; - pic_param->chroma_qp_index_offset = pps->chroma_qp_index_offset[0]; - pic_param->second_chroma_qp_index_offset = pps->chroma_qp_index_offset[1]; - pic_param->pic_fields.value = 0; /* reset all bits */ - pic_param->pic_fields.bits.entropy_coding_mode_flag = pps->cabac; - pic_param->pic_fields.bits.weighted_pred_flag = pps->weighted_pred; - pic_param->pic_fields.bits.weighted_bipred_idc = pps->weighted_bipred_idc; - pic_param->pic_fields.bits.transform_8x8_mode_flag = pps->transform_8x8_mode; - pic_param->pic_fields.bits.field_pic_flag = h->picture_structure != PICT_FRAME; - pic_param->pic_fields.bits.constrained_intra_pred_flag = pps->constrained_intra_pred; - pic_param->pic_fields.bits.pic_order_present_flag = pps->pic_order_present; - pic_param->pic_fields.bits.deblocking_filter_control_present_flag = pps->deblocking_filter_parameters_present; - pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = pps->redundant_pic_cnt_present; - pic_param->pic_fields.bits.reference_pic_flag = h->nal_ref_idc != 0; - pic_param->frame_num = h->poc.frame_num; - - /* Fill in VAIQMatrixBufferH264. */ - iq_matrix = ff_vaapi_alloc_iq_matrix(vactx, sizeof(VAIQMatrixBufferH264)); - if (!iq_matrix) - return -1; - memcpy(iq_matrix->ScalingList4x4, pps->scaling_matrix4, sizeof(iq_matrix->ScalingList4x4)); - memcpy(iq_matrix->ScalingList8x8[0], pps->scaling_matrix8[0], sizeof(iq_matrix->ScalingList8x8[0])); - memcpy(iq_matrix->ScalingList8x8[1], pps->scaling_matrix8[3], sizeof(iq_matrix->ScalingList8x8[0])); return 0; + +fail: + ff_vaapi_decode_cancel(avctx, pic); + return err; } /** End a hardware decoding based frame. */ static int vaapi_h264_end_frame(AVCodecContext *avctx) { - struct vaapi_context * const vactx = avctx->hwaccel_context; const H264Context *h = avctx->priv_data; + VAAPIDecodePicture *pic = h->cur_pic_ptr->hwaccel_picture_private; H264SliceContext *sl = &h->slice_ctx[0]; int ret; - ret = ff_vaapi_commit_slices(vactx); - if (ret < 0) - goto finish; - - ret = ff_vaapi_render_picture(vactx, ff_vaapi_get_surface_id(h->cur_pic_ptr->f)); + ret = ff_vaapi_decode_issue(avctx, pic); if (ret < 0) goto finish; ff_h264_draw_horiz_band(h, sl, 0, h->avctx->height); finish: - ff_vaapi_common_end_frame(avctx); return ret; } @@ -318,45 +331,71 @@ static int vaapi_h264_decode_slice(AVCodecContext *avctx, uint32_t size) { const H264Context *h = avctx->priv_data; + VAAPIDecodePicture *pic = h->cur_pic_ptr->hwaccel_picture_private; const H264SliceContext *sl = &h->slice_ctx[0]; - VASliceParameterBufferH264 *slice_param; - - /* Fill in VASliceParameterBufferH264. */ - slice_param = (VASliceParameterBufferH264 *)ff_vaapi_alloc_slice(avctx->hwaccel_context, buffer, size); - if (!slice_param) - return -1; - slice_param->slice_data_bit_offset = get_bits_count(&sl->gb); - slice_param->first_mb_in_slice = (sl->mb_y >> FIELD_OR_MBAFF_PICTURE(h)) * h->mb_width + sl->mb_x; - slice_param->slice_type = ff_h264_get_slice_type(sl); - slice_param->direct_spatial_mv_pred_flag = sl->slice_type == AV_PICTURE_TYPE_B ? sl->direct_spatial_mv_pred : 0; - slice_param->num_ref_idx_l0_active_minus1 = sl->list_count > 0 ? sl->ref_count[0] - 1 : 0; - slice_param->num_ref_idx_l1_active_minus1 = sl->list_count > 1 ? sl->ref_count[1] - 1 : 0; - slice_param->cabac_init_idc = sl->cabac_init_idc; - slice_param->slice_qp_delta = sl->qscale - h->ps.pps->init_qp; - slice_param->disable_deblocking_filter_idc = sl->deblocking_filter < 2 ? !sl->deblocking_filter : sl->deblocking_filter; - slice_param->slice_alpha_c0_offset_div2 = sl->slice_alpha_c0_offset / 2; - slice_param->slice_beta_offset_div2 = sl->slice_beta_offset / 2; - slice_param->luma_log2_weight_denom = sl->pwt.luma_log2_weight_denom; - slice_param->chroma_log2_weight_denom = sl->pwt.chroma_log2_weight_denom; - - fill_vaapi_RefPicList(slice_param->RefPicList0, sl->ref_list[0], sl->list_count > 0 ? sl->ref_count[0] : 0); - fill_vaapi_RefPicList(slice_param->RefPicList1, sl->ref_list[1], sl->list_count > 1 ? sl->ref_count[1] : 0); + VASliceParameterBufferH264 slice_param; + int err; + + slice_param = (VASliceParameterBufferH264) { + .slice_data_size = size, + .slice_data_offset = 0, + .slice_data_flag = VA_SLICE_DATA_FLAG_ALL, + .slice_data_bit_offset = get_bits_count(&sl->gb), + .first_mb_in_slice = (sl->mb_y >> FIELD_OR_MBAFF_PICTURE(h)) * h->mb_width + sl->mb_x, + .slice_type = ff_h264_get_slice_type(sl), + .direct_spatial_mv_pred_flag = sl->slice_type == AV_PICTURE_TYPE_B ? sl->direct_spatial_mv_pred : 0, + .num_ref_idx_l0_active_minus1 = sl->list_count > 0 ? sl->ref_count[0] - 1 : 0, + .num_ref_idx_l1_active_minus1 = sl->list_count > 1 ? sl->ref_count[1] - 1 : 0, + .cabac_init_idc = sl->cabac_init_idc, + .slice_qp_delta = sl->qscale - h->ps.pps->init_qp, + .disable_deblocking_filter_idc = sl->deblocking_filter < 2 ? !sl->deblocking_filter : sl->deblocking_filter, + .slice_alpha_c0_offset_div2 = sl->slice_alpha_c0_offset / 2, + .slice_beta_offset_div2 = sl->slice_beta_offset / 2, + .luma_log2_weight_denom = sl->pwt.luma_log2_weight_denom, + .chroma_log2_weight_denom = sl->pwt.chroma_log2_weight_denom, + }; + + fill_vaapi_RefPicList(slice_param.RefPicList0, sl->ref_list[0], + sl->list_count > 0 ? sl->ref_count[0] : 0); + fill_vaapi_RefPicList(slice_param.RefPicList1, sl->ref_list[1], + sl->list_count > 1 ? sl->ref_count[1] : 0); fill_vaapi_plain_pred_weight_table(h, 0, - &slice_param->luma_weight_l0_flag, slice_param->luma_weight_l0, slice_param->luma_offset_l0, - &slice_param->chroma_weight_l0_flag, slice_param->chroma_weight_l0, slice_param->chroma_offset_l0); + &slice_param.luma_weight_l0_flag, + slice_param.luma_weight_l0, + slice_param.luma_offset_l0, + &slice_param.chroma_weight_l0_flag, + slice_param.chroma_weight_l0, + slice_param.chroma_offset_l0); fill_vaapi_plain_pred_weight_table(h, 1, - &slice_param->luma_weight_l1_flag, slice_param->luma_weight_l1, slice_param->luma_offset_l1, - &slice_param->chroma_weight_l1_flag, slice_param->chroma_weight_l1, slice_param->chroma_offset_l1); + &slice_param.luma_weight_l1_flag, + slice_param.luma_weight_l1, + slice_param.luma_offset_l1, + &slice_param.chroma_weight_l1_flag, + slice_param.chroma_weight_l1, + slice_param.chroma_offset_l1); + + err = ff_vaapi_decode_make_slice_buffer(avctx, pic, + &slice_param, sizeof(slice_param), + buffer, size); + if (err) { + ff_vaapi_decode_cancel(avctx, pic); + return err; + } + return 0; } AVHWAccel ff_h264_vaapi_hwaccel = { - .name = "h264_vaapi", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_H264, - .pix_fmt = AV_PIX_FMT_VAAPI, - .start_frame = vaapi_h264_start_frame, - .end_frame = vaapi_h264_end_frame, - .decode_slice = vaapi_h264_decode_slice, + .name = "h264_vaapi", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_H264, + .pix_fmt = AV_PIX_FMT_VAAPI, + .start_frame = &vaapi_h264_start_frame, + .end_frame = &vaapi_h264_end_frame, + .decode_slice = &vaapi_h264_decode_slice, + .frame_priv_data_size = sizeof(VAAPIDecodePicture), + .init = &ff_vaapi_decode_init, + .uninit = &ff_vaapi_decode_uninit, + .priv_data_size = sizeof(VAAPIDecodeContext), }; From 102e13c353de43aa0cb1aa1843804d195c2a9164 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sat, 6 Aug 2016 18:37:47 +0100 Subject: [PATCH 0125/3374] vaapi_mpeg2: Convert to use the new VAAPI hwaccel code --- libavcodec/vaapi_mpeg2.c | 167 +++++++++++++++++++++++++-------------- 1 file changed, 106 insertions(+), 61 deletions(-) diff --git a/libavcodec/vaapi_mpeg2.c b/libavcodec/vaapi_mpeg2.c index 459eb75f1c46b..6c10578b9d4d5 100644 --- a/libavcodec/vaapi_mpeg2.c +++ b/libavcodec/vaapi_mpeg2.c @@ -22,8 +22,8 @@ #include "mpegutils.h" #include "mpegvideo.h" -#include "vaapi_internal.h" #include "internal.h" +#include "vaapi_decode.h" /** Reconstruct bitstream f_code */ static inline int mpeg2_get_f_code(const MpegEncContext *s) @@ -41,70 +41,100 @@ static inline int mpeg2_get_is_frame_start(const MpegEncContext *s) static int vaapi_mpeg2_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) { const MpegEncContext *s = avctx->priv_data; - struct vaapi_context * const vactx = avctx->hwaccel_context; - VAPictureParameterBufferMPEG2 *pic_param; - VAIQMatrixBufferMPEG2 *iq_matrix; - int i; - - vactx->slice_param_size = sizeof(VASliceParameterBufferMPEG2); - - /* Fill in VAPictureParameterBufferMPEG2 */ - pic_param = ff_vaapi_alloc_pic_param(vactx, sizeof(VAPictureParameterBufferMPEG2)); - if (!pic_param) - return -1; - pic_param->horizontal_size = s->width; - pic_param->vertical_size = s->height; - pic_param->forward_reference_picture = VA_INVALID_ID; - pic_param->backward_reference_picture = VA_INVALID_ID; - pic_param->picture_coding_type = s->pict_type; - pic_param->f_code = mpeg2_get_f_code(s); - pic_param->picture_coding_extension.value = 0; /* reset all bits */ - pic_param->picture_coding_extension.bits.intra_dc_precision = s->intra_dc_precision; - pic_param->picture_coding_extension.bits.picture_structure = s->picture_structure; - pic_param->picture_coding_extension.bits.top_field_first = s->top_field_first; - pic_param->picture_coding_extension.bits.frame_pred_frame_dct = s->frame_pred_frame_dct; - pic_param->picture_coding_extension.bits.concealment_motion_vectors = s->concealment_motion_vectors; - pic_param->picture_coding_extension.bits.q_scale_type = s->q_scale_type; - pic_param->picture_coding_extension.bits.intra_vlc_format = s->intra_vlc_format; - pic_param->picture_coding_extension.bits.alternate_scan = s->alternate_scan; - pic_param->picture_coding_extension.bits.repeat_first_field = s->repeat_first_field; - pic_param->picture_coding_extension.bits.progressive_frame = s->progressive_frame; - pic_param->picture_coding_extension.bits.is_first_field = mpeg2_get_is_frame_start(s); + VAAPIDecodePicture *pic = s->current_picture_ptr->hwaccel_picture_private; + VAPictureParameterBufferMPEG2 pic_param; + VAIQMatrixBufferMPEG2 iq_matrix; + int i, err; + + pic->output_surface = ff_vaapi_get_surface_id(s->current_picture_ptr->f); + + pic_param = (VAPictureParameterBufferMPEG2) { + .horizontal_size = s->width, + .vertical_size = s->height, + .forward_reference_picture = VA_INVALID_ID, + .backward_reference_picture = VA_INVALID_ID, + .picture_coding_type = s->pict_type, + .f_code = mpeg2_get_f_code(s), + .picture_coding_extension.bits = { + .intra_dc_precision = s->intra_dc_precision, + .picture_structure = s->picture_structure, + .top_field_first = s->top_field_first, + .frame_pred_frame_dct = s->frame_pred_frame_dct, + .concealment_motion_vectors = s->concealment_motion_vectors, + .q_scale_type = s->q_scale_type, + .intra_vlc_format = s->intra_vlc_format, + .alternate_scan = s->alternate_scan, + .repeat_first_field = s->repeat_first_field, + .progressive_frame = s->progressive_frame, + .is_first_field = mpeg2_get_is_frame_start(s), + }, + }; switch (s->pict_type) { case AV_PICTURE_TYPE_B: - pic_param->backward_reference_picture = ff_vaapi_get_surface_id(s->next_picture.f); + pic_param.backward_reference_picture = ff_vaapi_get_surface_id(s->next_picture.f); // fall-through case AV_PICTURE_TYPE_P: - pic_param->forward_reference_picture = ff_vaapi_get_surface_id(s->last_picture.f); + pic_param.forward_reference_picture = ff_vaapi_get_surface_id(s->last_picture.f); break; } - /* Fill in VAIQMatrixBufferMPEG2 */ - iq_matrix = ff_vaapi_alloc_iq_matrix(vactx, sizeof(VAIQMatrixBufferMPEG2)); - if (!iq_matrix) - return -1; - iq_matrix->load_intra_quantiser_matrix = 1; - iq_matrix->load_non_intra_quantiser_matrix = 1; - iq_matrix->load_chroma_intra_quantiser_matrix = 1; - iq_matrix->load_chroma_non_intra_quantiser_matrix = 1; + err = ff_vaapi_decode_make_param_buffer(avctx, pic, + VAPictureParameterBufferType, + &pic_param, sizeof(pic_param)); + if (err < 0) + goto fail; + + iq_matrix.load_intra_quantiser_matrix = 1; + iq_matrix.load_non_intra_quantiser_matrix = 1; + iq_matrix.load_chroma_intra_quantiser_matrix = 1; + iq_matrix.load_chroma_non_intra_quantiser_matrix = 1; for (i = 0; i < 64; i++) { int n = s->idsp.idct_permutation[ff_zigzag_direct[i]]; - iq_matrix->intra_quantiser_matrix[i] = s->intra_matrix[n]; - iq_matrix->non_intra_quantiser_matrix[i] = s->inter_matrix[n]; - iq_matrix->chroma_intra_quantiser_matrix[i] = s->chroma_intra_matrix[n]; - iq_matrix->chroma_non_intra_quantiser_matrix[i] = s->chroma_inter_matrix[n]; + iq_matrix.intra_quantiser_matrix[i] = s->intra_matrix[n]; + iq_matrix.non_intra_quantiser_matrix[i] = s->inter_matrix[n]; + iq_matrix.chroma_intra_quantiser_matrix[i] = s->chroma_intra_matrix[n]; + iq_matrix.chroma_non_intra_quantiser_matrix[i] = s->chroma_inter_matrix[n]; } + + err = ff_vaapi_decode_make_param_buffer(avctx, pic, + VAIQMatrixBufferType, + &iq_matrix, sizeof(iq_matrix)); + if (err < 0) + goto fail; + return 0; + +fail: + ff_vaapi_decode_cancel(avctx, pic); + return err; +} + +static int vaapi_mpeg2_end_frame(AVCodecContext *avctx) +{ + MpegEncContext *s = avctx->priv_data; + VAAPIDecodePicture *pic = s->current_picture_ptr->hwaccel_picture_private; + int ret; + + ret = ff_vaapi_decode_issue(avctx, pic); + if (ret < 0) + goto fail; + + ff_mpeg_draw_horiz_band(s, 0, s->avctx->height); + +fail: + return ret; } static int vaapi_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { const MpegEncContext *s = avctx->priv_data; - VASliceParameterBufferMPEG2 *slice_param; + VAAPIDecodePicture *pic = s->current_picture_ptr->hwaccel_picture_private; + VASliceParameterBufferMPEG2 slice_param; GetBitContext gb; uint32_t quantiser_scale_code, intra_slice_flag, macroblock_offset; + int err; /* Determine macroblock_offset */ init_get_bits(&gb, buffer, 8 * size); @@ -119,24 +149,39 @@ static int vaapi_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer } macroblock_offset = get_bits_count(&gb); - /* Fill in VASliceParameterBufferMPEG2 */ - slice_param = (VASliceParameterBufferMPEG2 *)ff_vaapi_alloc_slice(avctx->hwaccel_context, buffer, size); - if (!slice_param) - return -1; - slice_param->macroblock_offset = macroblock_offset; - slice_param->slice_horizontal_position = s->mb_x; - slice_param->slice_vertical_position = s->mb_y >> (s->picture_structure != PICT_FRAME); - slice_param->quantiser_scale_code = quantiser_scale_code; - slice_param->intra_slice_flag = intra_slice_flag; + slice_param = (VASliceParameterBufferMPEG2) { + .slice_data_size = size, + .slice_data_offset = 0, + .slice_data_flag = VA_SLICE_DATA_FLAG_ALL, + .macroblock_offset = macroblock_offset, + .slice_horizontal_position = s->mb_x, + .slice_vertical_position = s->mb_y >> (s->picture_structure != PICT_FRAME), + .quantiser_scale_code = quantiser_scale_code, + .intra_slice_flag = intra_slice_flag, + }; + + err = ff_vaapi_decode_make_slice_buffer(avctx, pic, + &slice_param, sizeof(slice_param), + buffer, size); + if (err < 0) { + ff_vaapi_decode_cancel(avctx, pic); + return err; + } + + return 0; } AVHWAccel ff_mpeg2_vaapi_hwaccel = { - .name = "mpeg2_vaapi", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_MPEG2VIDEO, - .pix_fmt = AV_PIX_FMT_VAAPI, - .start_frame = vaapi_mpeg2_start_frame, - .end_frame = ff_vaapi_mpeg_end_frame, - .decode_slice = vaapi_mpeg2_decode_slice, + .name = "mpeg2_vaapi", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_MPEG2VIDEO, + .pix_fmt = AV_PIX_FMT_VAAPI, + .start_frame = &vaapi_mpeg2_start_frame, + .end_frame = &vaapi_mpeg2_end_frame, + .decode_slice = &vaapi_mpeg2_decode_slice, + .frame_priv_data_size = sizeof(VAAPIDecodePicture), + .init = &ff_vaapi_decode_init, + .uninit = &ff_vaapi_decode_uninit, + .priv_data_size = sizeof(VAAPIDecodeContext), }; From 520fb77285ff0e7da1449d2b60742865b0b43ae8 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sat, 6 Aug 2016 22:12:50 +0100 Subject: [PATCH 0126/3374] vaapi_vc1: Convert to use the new VAAPI hwaccel code --- libavcodec/vaapi_vc1.c | 346 ++++++++++++++++++++++++----------------- 1 file changed, 206 insertions(+), 140 deletions(-) diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c index 2fc03e68ee66a..fe1a20fcbb990 100644 --- a/libavcodec/vaapi_vc1.c +++ b/libavcodec/vaapi_vc1.c @@ -20,8 +20,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "vaapi_internal.h" #include "internal.h" +#include "vaapi_decode.h" #include "vc1.h" #include "vc1data.h" @@ -148,143 +148,165 @@ static int vaapi_vc1_start_frame(AVCodecContext *avctx, av_unused const uint8_t { const VC1Context *v = avctx->priv_data; const MpegEncContext *s = &v->s; - struct vaapi_context * const vactx = avctx->hwaccel_context; - VAPictureParameterBufferVC1 *pic_param; - - vactx->slice_param_size = sizeof(VASliceParameterBufferVC1); - - /* Fill in VAPictureParameterBufferVC1 */ - pic_param = ff_vaapi_alloc_pic_param(vactx, sizeof(VAPictureParameterBufferVC1)); - if (!pic_param) - return -1; - pic_param->forward_reference_picture = VA_INVALID_ID; - pic_param->backward_reference_picture = VA_INVALID_ID; - pic_param->inloop_decoded_picture = VA_INVALID_ID; - pic_param->sequence_fields.value = 0; /* reset all bits */ - pic_param->sequence_fields.bits.pulldown = v->broadcast; - pic_param->sequence_fields.bits.interlace = v->interlace; - pic_param->sequence_fields.bits.tfcntrflag = v->tfcntrflag; - pic_param->sequence_fields.bits.finterpflag = v->finterpflag; - pic_param->sequence_fields.bits.psf = v->psf; - pic_param->sequence_fields.bits.multires = v->multires; - pic_param->sequence_fields.bits.overlap = v->overlap; - pic_param->sequence_fields.bits.syncmarker = v->resync_marker; - pic_param->sequence_fields.bits.rangered = v->rangered; - pic_param->sequence_fields.bits.max_b_frames = s->avctx->max_b_frames; - pic_param->sequence_fields.bits.profile = v->profile; - pic_param->coded_width = s->avctx->coded_width; - pic_param->coded_height = s->avctx->coded_height; - pic_param->entrypoint_fields.value = 0; /* reset all bits */ - pic_param->entrypoint_fields.bits.broken_link = v->broken_link; - pic_param->entrypoint_fields.bits.closed_entry = v->closed_entry; - pic_param->entrypoint_fields.bits.panscan_flag = v->panscanflag; - pic_param->entrypoint_fields.bits.loopfilter = s->loop_filter; - pic_param->conditional_overlap_flag = v->condover; - pic_param->fast_uvmc_flag = v->fastuvmc; - pic_param->range_mapping_fields.value = 0; /* reset all bits */ - pic_param->range_mapping_fields.bits.luma_flag = v->range_mapy_flag; - pic_param->range_mapping_fields.bits.luma = v->range_mapy; - pic_param->range_mapping_fields.bits.chroma_flag = v->range_mapuv_flag; - pic_param->range_mapping_fields.bits.chroma = v->range_mapuv; - pic_param->b_picture_fraction = v->bfraction_lut_index; - pic_param->cbp_table = v->cbpcy_vlc ? v->cbpcy_vlc - ff_vc1_cbpcy_p_vlc : 0; - pic_param->mb_mode_table = 0; /* XXX: interlaced frame */ - pic_param->range_reduction_frame = v->rangeredfrm; - pic_param->rounding_control = v->rnd; - pic_param->post_processing = v->postproc; - pic_param->picture_resolution_index = v->respic; - pic_param->luma_scale = v->lumscale; - pic_param->luma_shift = v->lumshift; - pic_param->picture_fields.value = 0; /* reset all bits */ - pic_param->picture_fields.bits.picture_type = vc1_get_PTYPE(v); - pic_param->picture_fields.bits.frame_coding_mode = v->fcm; - pic_param->picture_fields.bits.top_field_first = v->tff; - pic_param->picture_fields.bits.is_first_field = v->fcm == 0; /* XXX: interlaced frame */ - pic_param->picture_fields.bits.intensity_compensation = v->mv_mode == MV_PMODE_INTENSITY_COMP; - pic_param->raw_coding.value = 0; /* reset all bits */ - pic_param->raw_coding.flags.mv_type_mb = v->mv_type_is_raw; - pic_param->raw_coding.flags.direct_mb = v->dmb_is_raw; - pic_param->raw_coding.flags.skip_mb = v->skip_is_raw; - pic_param->raw_coding.flags.field_tx = 0; /* XXX: interlaced frame */ - pic_param->raw_coding.flags.forward_mb = 0; /* XXX: interlaced frame */ - pic_param->raw_coding.flags.ac_pred = v->acpred_is_raw; - pic_param->raw_coding.flags.overflags = v->overflg_is_raw; - pic_param->bitplane_present.value = 0; /* reset all bits */ - pic_param->bitplane_present.flags.bp_mv_type_mb = vc1_has_MVTYPEMB_bitplane(v); - pic_param->bitplane_present.flags.bp_direct_mb = vc1_has_DIRECTMB_bitplane(v); - pic_param->bitplane_present.flags.bp_skip_mb = vc1_has_SKIPMB_bitplane(v); - pic_param->bitplane_present.flags.bp_field_tx = 0; /* XXX: interlaced frame */ - pic_param->bitplane_present.flags.bp_forward_mb = 0; /* XXX: interlaced frame */ - pic_param->bitplane_present.flags.bp_ac_pred = vc1_has_ACPRED_bitplane(v); - pic_param->bitplane_present.flags.bp_overflags = vc1_has_OVERFLAGS_bitplane(v); - pic_param->reference_fields.value = 0; /* reset all bits */ - pic_param->reference_fields.bits.reference_distance_flag = v->refdist_flag; - pic_param->reference_fields.bits.reference_distance = 0; /* XXX: interlaced frame */ - pic_param->reference_fields.bits.num_reference_pictures = 0; /* XXX: interlaced frame */ - pic_param->reference_fields.bits.reference_field_pic_indicator = 0; /* XXX: interlaced frame */ - pic_param->mv_fields.value = 0; /* reset all bits */ - pic_param->mv_fields.bits.mv_mode = vc1_get_MVMODE(v); - pic_param->mv_fields.bits.mv_mode2 = vc1_get_MVMODE2(v); - pic_param->mv_fields.bits.mv_table = s->mv_table_index; - pic_param->mv_fields.bits.two_mv_block_pattern_table = 0; /* XXX: interlaced frame */ - pic_param->mv_fields.bits.four_mv_switch = 0; /* XXX: interlaced frame */ - pic_param->mv_fields.bits.four_mv_block_pattern_table = 0; /* XXX: interlaced frame */ - pic_param->mv_fields.bits.extended_mv_flag = v->extended_mv; - pic_param->mv_fields.bits.extended_mv_range = v->mvrange; - pic_param->mv_fields.bits.extended_dmv_flag = v->extended_dmv; - pic_param->mv_fields.bits.extended_dmv_range = 0; /* XXX: interlaced frame */ - pic_param->pic_quantizer_fields.value = 0; /* reset all bits */ - pic_param->pic_quantizer_fields.bits.dquant = v->dquant; - pic_param->pic_quantizer_fields.bits.quantizer = v->quantizer_mode; - pic_param->pic_quantizer_fields.bits.half_qp = v->halfpq; - pic_param->pic_quantizer_fields.bits.pic_quantizer_scale = v->pq; - pic_param->pic_quantizer_fields.bits.pic_quantizer_type = v->pquantizer; - pic_param->pic_quantizer_fields.bits.dq_frame = v->dquantfrm; - pic_param->pic_quantizer_fields.bits.dq_profile = v->dqprofile; - pic_param->pic_quantizer_fields.bits.dq_sb_edge = v->dqprofile == DQPROFILE_SINGLE_EDGE ? v->dqsbedge : 0; - pic_param->pic_quantizer_fields.bits.dq_db_edge = v->dqprofile == DQPROFILE_DOUBLE_EDGES ? v->dqsbedge : 0; - pic_param->pic_quantizer_fields.bits.dq_binary_level = v->dqbilevel; - pic_param->pic_quantizer_fields.bits.alt_pic_quantizer = v->altpq; - pic_param->transform_fields.value = 0; /* reset all bits */ - pic_param->transform_fields.bits.variable_sized_transform_flag = v->vstransform; - pic_param->transform_fields.bits.mb_level_transform_type_flag = v->ttmbf; - pic_param->transform_fields.bits.frame_level_transform_type = vc1_get_TTFRM(v); - pic_param->transform_fields.bits.transform_ac_codingset_idx1 = v->c_ac_table_index; - pic_param->transform_fields.bits.transform_ac_codingset_idx2 = v->y_ac_table_index; - pic_param->transform_fields.bits.intra_transform_dc_table = v->s.dc_table_index; + VAAPIDecodePicture *pic = s->current_picture_ptr->hwaccel_picture_private; + VAPictureParameterBufferVC1 pic_param; + int err; + + pic->output_surface = ff_vaapi_get_surface_id(s->current_picture_ptr->f); + + pic_param = (VAPictureParameterBufferVC1) { + .forward_reference_picture = VA_INVALID_ID, + .backward_reference_picture = VA_INVALID_ID, + .inloop_decoded_picture = VA_INVALID_ID, + .sequence_fields.bits = { + .pulldown = v->broadcast, + .interlace = v->interlace, + .tfcntrflag = v->tfcntrflag, + .finterpflag = v->finterpflag, + .psf = v->psf, + .multires = v->multires, + .overlap = v->overlap, + .syncmarker = v->resync_marker, + .rangered = v->rangered, + .max_b_frames = s->avctx->max_b_frames, + .profile = v->profile, + }, + .coded_width = s->avctx->coded_width, + .coded_height = s->avctx->coded_height, + .entrypoint_fields.bits = { + .broken_link = v->broken_link, + .closed_entry = v->closed_entry, + .panscan_flag = v->panscanflag, + .loopfilter = s->loop_filter, + }, + .conditional_overlap_flag = v->condover, + .fast_uvmc_flag = v->fastuvmc, + .range_mapping_fields.bits = { + .luma_flag = v->range_mapy_flag, + .luma = v->range_mapy, + .chroma_flag = v->range_mapuv_flag, + .chroma = v->range_mapuv, + }, + .b_picture_fraction = v->bfraction_lut_index, + .cbp_table = v->cbpcy_vlc ? v->cbpcy_vlc - ff_vc1_cbpcy_p_vlc : 0, + .mb_mode_table = 0, /* XXX: interlaced frame */ + .range_reduction_frame = v->rangeredfrm, + .rounding_control = v->rnd, + .post_processing = v->postproc, + .picture_resolution_index = v->respic, + .luma_scale = v->lumscale, + .luma_shift = v->lumshift, + .picture_fields.bits = { + .picture_type = vc1_get_PTYPE(v), + .frame_coding_mode = v->fcm, + .top_field_first = v->tff, + .is_first_field = v->fcm == 0, /* XXX: interlaced frame */ + .intensity_compensation = v->mv_mode == MV_PMODE_INTENSITY_COMP, + }, + .raw_coding.flags = { + .mv_type_mb = v->mv_type_is_raw, + .direct_mb = v->dmb_is_raw, + .skip_mb = v->skip_is_raw, + .field_tx = 0, /* XXX: interlaced frame */ + .forward_mb = 0, /* XXX: interlaced frame */ + .ac_pred = v->acpred_is_raw, + .overflags = v->overflg_is_raw, + }, + .bitplane_present.flags = { + .bp_mv_type_mb = vc1_has_MVTYPEMB_bitplane(v), + .bp_direct_mb = vc1_has_DIRECTMB_bitplane(v), + .bp_skip_mb = vc1_has_SKIPMB_bitplane(v), + .bp_field_tx = 0, /* XXX: interlaced frame */ + .bp_forward_mb = 0, /* XXX: interlaced frame */ + .bp_ac_pred = vc1_has_ACPRED_bitplane(v), + .bp_overflags = vc1_has_OVERFLAGS_bitplane(v), + }, + .reference_fields.bits = { + .reference_distance_flag = v->refdist_flag, + .reference_distance = 0, /* XXX: interlaced frame */ + .num_reference_pictures = 0, /* XXX: interlaced frame */ + .reference_field_pic_indicator = 0, /* XXX: interlaced frame */ + }, + .mv_fields.bits = { + .mv_mode = vc1_get_MVMODE(v), + .mv_mode2 = vc1_get_MVMODE2(v), + .mv_table = s->mv_table_index, + .two_mv_block_pattern_table = 0, /* XXX: interlaced frame */ + .four_mv_switch = 0, /* XXX: interlaced frame */ + .four_mv_block_pattern_table = 0, /* XXX: interlaced frame */ + .extended_mv_flag = v->extended_mv, + .extended_mv_range = v->mvrange, + .extended_dmv_flag = v->extended_dmv, + .extended_dmv_range = 0, /* XXX: interlaced frame */ + }, + .pic_quantizer_fields.bits = { + .dquant = v->dquant, + .quantizer = v->quantizer_mode, + .half_qp = v->halfpq, + .pic_quantizer_scale = v->pq, + .pic_quantizer_type = v->pquantizer, + .dq_frame = v->dquantfrm, + .dq_profile = v->dqprofile, + .dq_sb_edge = v->dqprofile == DQPROFILE_SINGLE_EDGE ? v->dqsbedge : 0, + .dq_db_edge = v->dqprofile == DQPROFILE_DOUBLE_EDGES ? v->dqsbedge : 0, + .dq_binary_level = v->dqbilevel, + .alt_pic_quantizer = v->altpq, + }, + .transform_fields.bits = { + .variable_sized_transform_flag = v->vstransform, + .mb_level_transform_type_flag = v->ttmbf, + .frame_level_transform_type = vc1_get_TTFRM(v), + .transform_ac_codingset_idx1 = v->c_ac_table_index, + .transform_ac_codingset_idx2 = v->y_ac_table_index, + .intra_transform_dc_table = v->s.dc_table_index, + }, + }; switch (s->pict_type) { case AV_PICTURE_TYPE_B: - pic_param->backward_reference_picture = ff_vaapi_get_surface_id(s->next_picture.f); + pic_param.backward_reference_picture = ff_vaapi_get_surface_id(s->next_picture.f); // fall-through case AV_PICTURE_TYPE_P: - pic_param->forward_reference_picture = ff_vaapi_get_surface_id(s->last_picture.f); + pic_param.forward_reference_picture = ff_vaapi_get_surface_id(s->last_picture.f); break; } - if (pic_param->bitplane_present.value) { + err = ff_vaapi_decode_make_param_buffer(avctx, pic, + VAPictureParameterBufferType, + &pic_param, sizeof(pic_param)); + if (err) + goto fail; + + if (pic_param.bitplane_present.value) { uint8_t *bitplane; const uint8_t *ff_bp[3]; int x, y, n; + size_t size = (s->mb_width * s->mb_height + 1) / 2; + + bitplane = av_mallocz(size); + if (!bitplane) { + err = AVERROR(ENOMEM); + goto fail; + } switch (s->pict_type) { case AV_PICTURE_TYPE_P: - ff_bp[0] = pic_param->bitplane_present.flags.bp_direct_mb ? v->direct_mb_plane : NULL; - ff_bp[1] = pic_param->bitplane_present.flags.bp_skip_mb ? s->mbskip_table : NULL; - ff_bp[2] = pic_param->bitplane_present.flags.bp_mv_type_mb ? v->mv_type_mb_plane : NULL; + ff_bp[0] = pic_param.bitplane_present.flags.bp_direct_mb ? v->direct_mb_plane : NULL; + ff_bp[1] = pic_param.bitplane_present.flags.bp_skip_mb ? s->mbskip_table : NULL; + ff_bp[2] = pic_param.bitplane_present.flags.bp_mv_type_mb ? v->mv_type_mb_plane : NULL; break; case AV_PICTURE_TYPE_B: if (!v->bi_type) { - ff_bp[0] = pic_param->bitplane_present.flags.bp_direct_mb ? v->direct_mb_plane : NULL; - ff_bp[1] = pic_param->bitplane_present.flags.bp_skip_mb ? s->mbskip_table : NULL; + ff_bp[0] = pic_param.bitplane_present.flags.bp_direct_mb ? v->direct_mb_plane : NULL; + ff_bp[1] = pic_param.bitplane_present.flags.bp_skip_mb ? s->mbskip_table : NULL; ff_bp[2] = NULL; /* XXX: interlaced frame (FORWARD plane) */ break; } /* fall-through (BI-type) */ case AV_PICTURE_TYPE_I: ff_bp[0] = NULL; /* XXX: interlaced frame (FIELDTX plane) */ - ff_bp[1] = pic_param->bitplane_present.flags.bp_ac_pred ? v->acpred_plane : NULL; - ff_bp[2] = pic_param->bitplane_present.flags.bp_overflags ? v->over_flags_plane : NULL; + ff_bp[1] = pic_param.bitplane_present.flags.bp_ac_pred ? v->acpred_plane : NULL; + ff_bp[2] = pic_param.bitplane_present.flags.bp_overflags ? v->over_flags_plane : NULL; break; default: ff_bp[0] = NULL; @@ -293,25 +315,51 @@ static int vaapi_vc1_start_frame(AVCodecContext *avctx, av_unused const uint8_t break; } - bitplane = ff_vaapi_alloc_bitplane(vactx, (s->mb_width * s->mb_height + 1) / 2); - if (!bitplane) - return -1; - n = 0; for (y = 0; y < s->mb_height; y++) for (x = 0; x < s->mb_width; x++, n++) vc1_pack_bitplanes(bitplane, n, ff_bp, x, y, s->mb_stride); if (n & 1) /* move last nibble to the high order */ bitplane[n/2] <<= 4; + + err = ff_vaapi_decode_make_param_buffer(avctx, pic, + VABitPlaneBufferType, + bitplane, size); + av_free(bitplane); + if (err) + goto fail; } return 0; + +fail: + ff_vaapi_decode_cancel(avctx, pic); + return err; +} + +static int vaapi_vc1_end_frame(AVCodecContext *avctx) +{ + VC1Context *v = avctx->priv_data; + MpegEncContext *s = &v->s; + VAAPIDecodePicture *pic = s->current_picture_ptr->hwaccel_picture_private; + int ret; + + ret = ff_vaapi_decode_issue(avctx, pic); + if (ret < 0) + goto fail; + + ff_mpeg_draw_horiz_band(s, 0, s->avctx->height); + +fail: + return ret; } static int vaapi_vc1_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { const VC1Context *v = avctx->priv_data; const MpegEncContext *s = &v->s; - VASliceParameterBufferVC1 *slice_param; + VAAPIDecodePicture *pic = s->current_picture_ptr->hwaccel_picture_private; + VASliceParameterBufferVC1 slice_param; + int err; /* Current bit buffer is beyond any marker for VC-1, so skip it */ if (avctx->codec_id == AV_CODEC_ID_VC1 && IS_MARKER(AV_RB32(buffer))) { @@ -319,33 +367,51 @@ static int vaapi_vc1_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, size -= 4; } - /* Fill in VASliceParameterBufferVC1 */ - slice_param = (VASliceParameterBufferVC1 *)ff_vaapi_alloc_slice(avctx->hwaccel_context, buffer, size); - if (!slice_param) - return -1; - slice_param->macroblock_offset = get_bits_count(&s->gb); - slice_param->slice_vertical_position = s->mb_y; + slice_param = (VASliceParameterBufferVC1) { + .slice_data_size = size, + .slice_data_offset = 0, + .slice_data_flag = VA_SLICE_DATA_FLAG_ALL, + .macroblock_offset = get_bits_count(&s->gb), + .slice_vertical_position = s->mb_y, + }; + + err = ff_vaapi_decode_make_slice_buffer(avctx, pic, + &slice_param, sizeof(slice_param), + buffer, size); + if (err < 0) { + ff_vaapi_decode_cancel(avctx, pic); + return err; + } + return 0; } #if CONFIG_WMV3_VAAPI_HWACCEL AVHWAccel ff_wmv3_vaapi_hwaccel = { - .name = "wmv3_vaapi", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_WMV3, - .pix_fmt = AV_PIX_FMT_VAAPI, - .start_frame = vaapi_vc1_start_frame, - .end_frame = ff_vaapi_mpeg_end_frame, - .decode_slice = vaapi_vc1_decode_slice, + .name = "wmv3_vaapi", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_WMV3, + .pix_fmt = AV_PIX_FMT_VAAPI, + .start_frame = &vaapi_vc1_start_frame, + .end_frame = &vaapi_vc1_end_frame, + .decode_slice = &vaapi_vc1_decode_slice, + .frame_priv_data_size = sizeof(VAAPIDecodePicture), + .init = &ff_vaapi_decode_init, + .uninit = &ff_vaapi_decode_uninit, + .priv_data_size = sizeof(VAAPIDecodeContext), }; #endif AVHWAccel ff_vc1_vaapi_hwaccel = { - .name = "vc1_vaapi", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_VC1, - .pix_fmt = AV_PIX_FMT_VAAPI, - .start_frame = vaapi_vc1_start_frame, - .end_frame = ff_vaapi_mpeg_end_frame, - .decode_slice = vaapi_vc1_decode_slice, + .name = "vc1_vaapi", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_VC1, + .pix_fmt = AV_PIX_FMT_VAAPI, + .start_frame = &vaapi_vc1_start_frame, + .end_frame = &vaapi_vc1_end_frame, + .decode_slice = &vaapi_vc1_decode_slice, + .frame_priv_data_size = sizeof(VAAPIDecodePicture), + .init = &ff_vaapi_decode_init, + .uninit = &ff_vaapi_decode_uninit, + .priv_data_size = sizeof(VAAPIDecodeContext), }; From ccd0316f7cab760a93052206e8150f6b178c1e39 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 7 Aug 2016 13:45:41 +0100 Subject: [PATCH 0127/3374] vaapi_mpeg4: Convert to use the new VAAPI hwaccel code --- libavcodec/vaapi_mpeg4.c | 215 ++++++++++++++++++++++++--------------- 1 file changed, 133 insertions(+), 82 deletions(-) diff --git a/libavcodec/vaapi_mpeg4.c b/libavcodec/vaapi_mpeg4.c index 6743e2a47800e..4413cbfe34ac1 100644 --- a/libavcodec/vaapi_mpeg4.c +++ b/libavcodec/vaapi_mpeg4.c @@ -20,11 +20,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "vaapi_internal.h" -#include "internal.h" #include "h263.h" +#include "internal.h" #include "mpeg4video.h" #include "mpegvideo.h" +#include "vaapi_decode.h" /** Reconstruct bitstream intra_dc_vlc_thr */ static int mpeg4_get_intra_dc_vlc_thr(Mpeg4DecContext *s) @@ -45,82 +45,116 @@ static int mpeg4_get_intra_dc_vlc_thr(Mpeg4DecContext *s) static int vaapi_mpeg4_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) { Mpeg4DecContext *ctx = avctx->priv_data; - MpegEncContext * const s = &ctx->m; - struct vaapi_context * const vactx = avctx->hwaccel_context; - VAPictureParameterBufferMPEG4 *pic_param; - VAIQMatrixBufferMPEG4 *iq_matrix; - int i; - - vactx->slice_param_size = sizeof(VASliceParameterBufferMPEG4); - - /* Fill in VAPictureParameterBufferMPEG4 */ - pic_param = ff_vaapi_alloc_pic_param(vactx, sizeof(VAPictureParameterBufferMPEG4)); - if (!pic_param) - return -1; - pic_param->vop_width = s->width; - pic_param->vop_height = s->height; - pic_param->forward_reference_picture = VA_INVALID_ID; - pic_param->backward_reference_picture = VA_INVALID_ID; - pic_param->vol_fields.value = 0; /* reset all bits */ - pic_param->vol_fields.bits.short_video_header = avctx->codec->id == AV_CODEC_ID_H263; - pic_param->vol_fields.bits.chroma_format = CHROMA_420; - pic_param->vol_fields.bits.interlaced = !s->progressive_sequence; - pic_param->vol_fields.bits.obmc_disable = 1; - pic_param->vol_fields.bits.sprite_enable = ctx->vol_sprite_usage; - pic_param->vol_fields.bits.sprite_warping_accuracy = s->sprite_warping_accuracy; - pic_param->vol_fields.bits.quant_type = s->mpeg_quant; - pic_param->vol_fields.bits.quarter_sample = s->quarter_sample; - pic_param->vol_fields.bits.data_partitioned = s->data_partitioning; - pic_param->vol_fields.bits.reversible_vlc = ctx->rvlc; - pic_param->vol_fields.bits.resync_marker_disable = !ctx->resync_marker; - pic_param->no_of_sprite_warping_points = ctx->num_sprite_warping_points; + MpegEncContext *s = &ctx->m; + VAAPIDecodePicture *pic = s->current_picture_ptr->hwaccel_picture_private; + VAPictureParameterBufferMPEG4 pic_param; + int i, err; + + pic->output_surface = ff_vaapi_get_surface_id(s->current_picture_ptr->f); + + pic_param = (VAPictureParameterBufferMPEG4) { + .vop_width = s->width, + .vop_height = s->height, + .forward_reference_picture = VA_INVALID_ID, + .backward_reference_picture = VA_INVALID_ID, + .vol_fields.bits = { + .short_video_header = avctx->codec->id == AV_CODEC_ID_H263, + .chroma_format = CHROMA_420, + .interlaced = !s->progressive_sequence, + .obmc_disable = 1, + .sprite_enable = ctx->vol_sprite_usage, + .sprite_warping_accuracy = s->sprite_warping_accuracy, + .quant_type = s->mpeg_quant, + .quarter_sample = s->quarter_sample, + .data_partitioned = s->data_partitioning, + .reversible_vlc = ctx->rvlc, + .resync_marker_disable = !ctx->resync_marker, + }, + .no_of_sprite_warping_points = ctx->num_sprite_warping_points, + .quant_precision = s->quant_precision, + .vop_fields.bits = { + .vop_coding_type = s->pict_type - AV_PICTURE_TYPE_I, + .backward_reference_vop_coding_type = + s->pict_type == AV_PICTURE_TYPE_B ? s->next_picture.f->pict_type - AV_PICTURE_TYPE_I : 0, + .vop_rounding_type = s->no_rounding, + .intra_dc_vlc_thr = mpeg4_get_intra_dc_vlc_thr(ctx), + .top_field_first = s->top_field_first, + .alternate_vertical_scan_flag = s->alternate_scan, + }, + .vop_fcode_forward = s->f_code, + .vop_fcode_backward = s->b_code, + .vop_time_increment_resolution = avctx->framerate.num, + .num_macroblocks_in_gob = s->mb_width * H263_GOB_HEIGHT(s->height), + .num_gobs_in_vop = + (s->mb_width * s->mb_height) / (s->mb_width * H263_GOB_HEIGHT(s->height)), + .TRB = s->pb_time, + .TRD = s->pp_time, + }; + for (i = 0; i < ctx->num_sprite_warping_points && i < 3; i++) { - pic_param->sprite_trajectory_du[i] = ctx->sprite_traj[i][0]; - pic_param->sprite_trajectory_dv[i] = ctx->sprite_traj[i][1]; + pic_param.sprite_trajectory_du[i] = ctx->sprite_traj[i][0]; + pic_param.sprite_trajectory_dv[i] = ctx->sprite_traj[i][1]; } - pic_param->quant_precision = s->quant_precision; - pic_param->vop_fields.value = 0; /* reset all bits */ - pic_param->vop_fields.bits.vop_coding_type = s->pict_type - AV_PICTURE_TYPE_I; - pic_param->vop_fields.bits.backward_reference_vop_coding_type = s->pict_type == AV_PICTURE_TYPE_B ? s->next_picture.f->pict_type - AV_PICTURE_TYPE_I : 0; - pic_param->vop_fields.bits.vop_rounding_type = s->no_rounding; - pic_param->vop_fields.bits.intra_dc_vlc_thr = mpeg4_get_intra_dc_vlc_thr(ctx); - pic_param->vop_fields.bits.top_field_first = s->top_field_first; - pic_param->vop_fields.bits.alternate_vertical_scan_flag = s->alternate_scan; - pic_param->vop_fcode_forward = s->f_code; - pic_param->vop_fcode_backward = s->b_code; - pic_param->vop_time_increment_resolution = avctx->framerate.num; - pic_param->num_macroblocks_in_gob = s->mb_width * H263_GOB_HEIGHT(s->height); - pic_param->num_gobs_in_vop = (s->mb_width * s->mb_height) / pic_param->num_macroblocks_in_gob; - pic_param->TRB = s->pb_time; - pic_param->TRD = s->pp_time; if (s->pict_type == AV_PICTURE_TYPE_B) - pic_param->backward_reference_picture = ff_vaapi_get_surface_id(s->next_picture.f); + pic_param.backward_reference_picture = ff_vaapi_get_surface_id(s->next_picture.f); if (s->pict_type != AV_PICTURE_TYPE_I) - pic_param->forward_reference_picture = ff_vaapi_get_surface_id(s->last_picture.f); + pic_param.forward_reference_picture = ff_vaapi_get_surface_id(s->last_picture.f); + + err = ff_vaapi_decode_make_param_buffer(avctx, pic, + VAPictureParameterBufferType, + &pic_param, sizeof(pic_param)); + if (err < 0) + goto fail; - /* Fill in VAIQMatrixBufferMPEG4 */ /* Only the first inverse quantisation method uses the weighting matrices */ - if (pic_param->vol_fields.bits.quant_type) { - iq_matrix = ff_vaapi_alloc_iq_matrix(vactx, sizeof(VAIQMatrixBufferMPEG4)); - if (!iq_matrix) - return -1; - iq_matrix->load_intra_quant_mat = 1; - iq_matrix->load_non_intra_quant_mat = 1; + if (pic_param.vol_fields.bits.quant_type) { + VAIQMatrixBufferMPEG4 iq_matrix; + + iq_matrix.load_intra_quant_mat = 1; + iq_matrix.load_non_intra_quant_mat = 1; for (i = 0; i < 64; i++) { int n = s->idsp.idct_permutation[ff_zigzag_direct[i]]; - iq_matrix->intra_quant_mat[i] = s->intra_matrix[n]; - iq_matrix->non_intra_quant_mat[i] = s->inter_matrix[n]; + iq_matrix.intra_quant_mat[i] = s->intra_matrix[n]; + iq_matrix.non_intra_quant_mat[i] = s->inter_matrix[n]; } + + err = ff_vaapi_decode_make_param_buffer(avctx, pic, + VAIQMatrixBufferType, + &iq_matrix, sizeof(iq_matrix)); + if (err < 0) + goto fail; } return 0; + +fail: + ff_vaapi_decode_cancel(avctx, pic); + return err; +} + +static int vaapi_mpeg4_end_frame(AVCodecContext *avctx) +{ + MpegEncContext *s = avctx->priv_data; + VAAPIDecodePicture *pic = s->current_picture_ptr->hwaccel_picture_private; + int ret; + + ret = ff_vaapi_decode_issue(avctx, pic); + if (ret < 0) + goto fail; + + ff_mpeg_draw_horiz_band(s, 0, s->avctx->height); + +fail: + return ret; } static int vaapi_mpeg4_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { - MpegEncContext * const s = avctx->priv_data; - VASliceParameterBufferMPEG4 *slice_param; + MpegEncContext *s = avctx->priv_data; + VAAPIDecodePicture *pic = s->current_picture_ptr->hwaccel_picture_private; + VASliceParameterBufferMPEG4 slice_param; + int err; /* video_plane_with_short_video_header() contains all GOBs * in-order, and this is what VA API (Intel backend) expects: only @@ -130,40 +164,57 @@ static int vaapi_mpeg4_decode_slice(AVCodecContext *avctx, const uint8_t *buffer if (avctx->codec->id == AV_CODEC_ID_H263) size = s->gb.buffer_end - buffer; - /* Fill in VASliceParameterBufferMPEG4 */ - slice_param = (VASliceParameterBufferMPEG4 *)ff_vaapi_alloc_slice(avctx->hwaccel_context, buffer, size); - if (!slice_param) - return -1; - slice_param->macroblock_offset = get_bits_count(&s->gb) % 8; - slice_param->macroblock_number = s->mb_y * s->mb_width + s->mb_x; - slice_param->quant_scale = s->qscale; + slice_param = (VASliceParameterBufferMPEG4) { + .slice_data_size = size, + .slice_data_offset = 0, + .slice_data_flag = VA_SLICE_DATA_FLAG_ALL, + .macroblock_offset = get_bits_count(&s->gb) % 8, + .macroblock_number = s->mb_y * s->mb_width + s->mb_x, + .quant_scale = s->qscale, + }; if (avctx->codec->id == AV_CODEC_ID_H263) s->mb_y = s->mb_height; + err = ff_vaapi_decode_make_slice_buffer(avctx, pic, + &slice_param, sizeof(slice_param), + buffer, size); + if (err < 0) { + ff_vaapi_decode_cancel(avctx, pic); + return err; + } + return 0; } #if CONFIG_MPEG4_VAAPI_HWACCEL AVHWAccel ff_mpeg4_vaapi_hwaccel = { - .name = "mpeg4_vaapi", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_MPEG4, - .pix_fmt = AV_PIX_FMT_VAAPI, - .start_frame = vaapi_mpeg4_start_frame, - .end_frame = ff_vaapi_mpeg_end_frame, - .decode_slice = vaapi_mpeg4_decode_slice, + .name = "mpeg4_vaapi", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_MPEG4, + .pix_fmt = AV_PIX_FMT_VAAPI, + .start_frame = &vaapi_mpeg4_start_frame, + .end_frame = &vaapi_mpeg4_end_frame, + .decode_slice = &vaapi_mpeg4_decode_slice, + .frame_priv_data_size = sizeof(VAAPIDecodePicture), + .init = &ff_vaapi_decode_init, + .uninit = &ff_vaapi_decode_uninit, + .priv_data_size = sizeof(VAAPIDecodeContext), }; #endif #if CONFIG_H263_VAAPI_HWACCEL AVHWAccel ff_h263_vaapi_hwaccel = { - .name = "h263_vaapi", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_H263, - .pix_fmt = AV_PIX_FMT_VAAPI, - .start_frame = vaapi_mpeg4_start_frame, - .end_frame = ff_vaapi_mpeg_end_frame, - .decode_slice = vaapi_mpeg4_decode_slice, + .name = "h263_vaapi", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_H263, + .pix_fmt = AV_PIX_FMT_VAAPI, + .start_frame = &vaapi_mpeg4_start_frame, + .end_frame = &vaapi_mpeg4_end_frame, + .decode_slice = &vaapi_mpeg4_decode_slice, + .frame_priv_data_size = sizeof(VAAPIDecodePicture), + .init = &ff_vaapi_decode_init, + .uninit = &ff_vaapi_decode_uninit, + .priv_data_size = sizeof(VAAPIDecodeContext), }; #endif From 3e8651a7ccd8e89cc2f162cf614a3c9f7f4d9fcf Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 31 Jul 2016 22:51:45 +0100 Subject: [PATCH 0128/3374] avconv_vaapi: Convert to use hw_frames_ctx only Most of the functionality here has moved into lavc. --- avconv_vaapi.c | 353 ++++--------------------------------------------- 1 file changed, 23 insertions(+), 330 deletions(-) diff --git a/avconv_vaapi.c b/avconv_vaapi.c index ddee72c53f3c6..584b8b4df0ffe 100644 --- a/avconv_vaapi.c +++ b/avconv_vaapi.c @@ -18,28 +18,10 @@ #include "config.h" -#include -#include - -#include -#if HAVE_VAAPI_X11 -# include -#endif -#if HAVE_VAAPI_DRM -# include -#endif - #include "libavutil/avassert.h" -#include "libavutil/avconfig.h" -#include "libavutil/buffer.h" #include "libavutil/frame.h" #include "libavutil/hwcontext.h" -#include "libavutil/hwcontext_vaapi.h" -#include "libavutil/imgutils.h" -#include "libavutil/opt.h" -#include "libavutil/pixfmt.h" - -#include "libavcodec/vaapi.h" +#include "libavutil/log.h" #include "avconv.h" @@ -60,23 +42,11 @@ typedef struct VAAPIDecoderContext { AVBufferRef *frames_ref; AVHWFramesContext *frames; - VAProfile va_profile; - VAEntrypoint va_entrypoint; - VAConfigID va_config; - VAContextID va_context; - - enum AVPixelFormat decode_format; - int decode_width; - int decode_height; - int decode_surfaces; - // The output need not have the same format, width and height as the // decoded frames - the copy for non-direct-mapped access is actually // a whole vpp instance which can do arbitrary scaling and format // conversion. enum AVPixelFormat output_format; - - struct vaapi_context decoder_vaapi_context; } VAAPIDecoderContext; @@ -144,257 +114,12 @@ static int vaapi_retrieve_data(AVCodecContext *avctx, AVFrame *input) return err; } - -static const struct { - enum AVCodecID codec_id; - int codec_profile; - VAProfile va_profile; -} vaapi_profile_map[] = { -#define MAP(c, p, v) { AV_CODEC_ID_ ## c, FF_PROFILE_ ## p, VAProfile ## v } - MAP(MPEG2VIDEO, MPEG2_SIMPLE, MPEG2Simple ), - MAP(MPEG2VIDEO, MPEG2_MAIN, MPEG2Main ), - MAP(H263, UNKNOWN, H263Baseline), - MAP(MPEG4, MPEG4_SIMPLE, MPEG4Simple ), - MAP(MPEG4, MPEG4_ADVANCED_SIMPLE, - MPEG4AdvancedSimple), - MAP(MPEG4, MPEG4_MAIN, MPEG4Main ), - MAP(H264, H264_CONSTRAINED_BASELINE, - H264ConstrainedBaseline), - MAP(H264, H264_BASELINE, H264Baseline), - MAP(H264, H264_MAIN, H264Main ), - MAP(H264, H264_HIGH, H264High ), -#if VA_CHECK_VERSION(0, 37, 0) - MAP(HEVC, HEVC_MAIN, HEVCMain ), -#endif - MAP(WMV3, VC1_SIMPLE, VC1Simple ), - MAP(WMV3, VC1_MAIN, VC1Main ), - MAP(WMV3, VC1_COMPLEX, VC1Advanced ), - MAP(WMV3, VC1_ADVANCED, VC1Advanced ), - MAP(VC1, VC1_SIMPLE, VC1Simple ), - MAP(VC1, VC1_MAIN, VC1Main ), - MAP(VC1, VC1_COMPLEX, VC1Advanced ), - MAP(VC1, VC1_ADVANCED, VC1Advanced ), -#if VA_CHECK_VERSION(0, 35, 0) - MAP(VP8, UNKNOWN, VP8Version0_3 ), -#endif -#if VA_CHECK_VERSION(0, 37, 1) - MAP(VP9, VP9_0, VP9Profile0 ), -#endif -#undef MAP -}; - -static int vaapi_build_decoder_config(VAAPIDecoderContext *ctx, - AVCodecContext *avctx, - int fallback_allowed) -{ - AVVAAPIDeviceContext *hwctx = ctx->device->hwctx; - AVVAAPIHWConfig *hwconfig = NULL; - AVHWFramesConstraints *constraints = NULL; - VAStatus vas; - int err, i, j; - int loglevel = fallback_allowed ? AV_LOG_VERBOSE : AV_LOG_ERROR; - const AVCodecDescriptor *codec_desc; - const AVPixFmtDescriptor *pix_desc; - enum AVPixelFormat pix_fmt; - VAProfile profile, *profile_list = NULL; - int profile_count, exact_match, alt_profile; - - codec_desc = avcodec_descriptor_get(avctx->codec_id); - if (!codec_desc) { - err = AVERROR(EINVAL); - goto fail; - } - - profile_count = vaMaxNumProfiles(hwctx->display); - profile_list = av_malloc(profile_count * sizeof(VAProfile)); - if (!profile_list) { - err = AVERROR(ENOMEM); - goto fail; - } - - vas = vaQueryConfigProfiles(hwctx->display, - profile_list, &profile_count); - if (vas != VA_STATUS_SUCCESS) { - av_log(ctx, loglevel, "Failed to query profiles: %d (%s).\n", - vas, vaErrorStr(vas)); - err = AVERROR(EIO); - goto fail; - } - - profile = VAProfileNone; - exact_match = 0; - - for (i = 0; i < FF_ARRAY_ELEMS(vaapi_profile_map); i++) { - int profile_match = 0; - if (avctx->codec_id != vaapi_profile_map[i].codec_id) - continue; - if (avctx->profile == vaapi_profile_map[i].codec_profile) - profile_match = 1; - profile = vaapi_profile_map[i].va_profile; - for (j = 0; j < profile_count; j++) { - if (profile == profile_list[j]) { - exact_match = profile_match; - break; - } - } - if (j < profile_count) { - if (exact_match) - break; - alt_profile = vaapi_profile_map[i].codec_profile; - } - } - av_freep(&profile_list); - - if (profile == VAProfileNone) { - av_log(ctx, loglevel, "No VAAPI support for codec %s.\n", - codec_desc->name); - err = AVERROR(ENOSYS); - goto fail; - } - if (!exact_match) { - if (fallback_allowed || !hwaccel_lax_profile_check) { - av_log(ctx, loglevel, "No VAAPI support for codec %s " - "profile %d.\n", codec_desc->name, avctx->profile); - if (!fallback_allowed) { - av_log(ctx, AV_LOG_WARNING, "If you want attempt decoding " - "anyway with a possibly-incompatible profile, add " - "the option -hwaccel_lax_profile_check.\n"); - } - err = AVERROR(EINVAL); - goto fail; - } else { - av_log(ctx, AV_LOG_WARNING, "No VAAPI support for codec %s " - "profile %d: trying instead with profile %d.\n", - codec_desc->name, avctx->profile, alt_profile); - av_log(ctx, AV_LOG_WARNING, "This may fail or give " - "incorrect results, depending on your hardware.\n"); - } - } - - ctx->va_profile = profile; - ctx->va_entrypoint = VAEntrypointVLD; - - vas = vaCreateConfig(hwctx->display, ctx->va_profile, - ctx->va_entrypoint, 0, 0, &ctx->va_config); - if (vas != VA_STATUS_SUCCESS) { - av_log(ctx, AV_LOG_ERROR, "Failed to create decode pipeline " - "configuration: %d (%s).\n", vas, vaErrorStr(vas)); - err = AVERROR(EIO); - goto fail; - } - - hwconfig = av_hwdevice_hwconfig_alloc(ctx->device_ref); - if (!hwconfig) { - err = AVERROR(ENOMEM); - goto fail; - } - hwconfig->config_id = ctx->va_config; - - constraints = av_hwdevice_get_hwframe_constraints(ctx->device_ref, - hwconfig); - if (!constraints) - goto fail; - - // Decide on the decoder target format. - // If the user specified something with -hwaccel_output_format then - // try to use that to minimise conversions later. - ctx->decode_format = AV_PIX_FMT_NONE; - if (ctx->output_format != AV_PIX_FMT_NONE && - ctx->output_format != AV_PIX_FMT_VAAPI) { - for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) { - if (constraints->valid_sw_formats[i] == ctx->decode_format) { - ctx->decode_format = ctx->output_format; - av_log(ctx, AV_LOG_DEBUG, "Using decode format %s (output " - "format).\n", av_get_pix_fmt_name(ctx->decode_format)); - break; - } - } - } - // Otherwise, we would like to try to choose something which matches the - // decoder output, but there isn't enough information available here to - // do so. Assume for now that we are always dealing with YUV 4:2:0, so - // pick a format which does that. - if (ctx->decode_format == AV_PIX_FMT_NONE) { - for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) { - pix_fmt = constraints->valid_sw_formats[i]; - pix_desc = av_pix_fmt_desc_get(pix_fmt); - if (pix_desc->nb_components == 3 && - pix_desc->log2_chroma_w == 1 && - pix_desc->log2_chroma_h == 1) { - ctx->decode_format = pix_fmt; - av_log(ctx, AV_LOG_DEBUG, "Using decode format %s (format " - "matched).\n", av_get_pix_fmt_name(ctx->decode_format)); - break; - } - } - } - // Otherwise pick the first in the list and hope for the best. - if (ctx->decode_format == AV_PIX_FMT_NONE) { - ctx->decode_format = constraints->valid_sw_formats[0]; - av_log(ctx, AV_LOG_DEBUG, "Using decode format %s (first in list).\n", - av_get_pix_fmt_name(ctx->decode_format)); - if (i > 1) { - // There was a choice, and we picked randomly. Warn the user - // that they might want to choose intelligently instead. - av_log(ctx, AV_LOG_WARNING, "Using randomly chosen decode " - "format %s.\n", av_get_pix_fmt_name(ctx->decode_format)); - } - } - - // Ensure the picture size is supported by the hardware. - ctx->decode_width = avctx->coded_width; - ctx->decode_height = avctx->coded_height; - if (ctx->decode_width < constraints->min_width || - ctx->decode_height < constraints->min_height || - ctx->decode_width > constraints->max_width || - ctx->decode_height >constraints->max_height) { - av_log(ctx, AV_LOG_ERROR, "VAAPI hardware does not support image " - "size %dx%d (constraints: width %d-%d height %d-%d).\n", - ctx->decode_width, ctx->decode_height, - constraints->min_width, constraints->max_width, - constraints->min_height, constraints->max_height); - err = AVERROR(EINVAL); - goto fail; - } - - av_hwframe_constraints_free(&constraints); - av_freep(&hwconfig); - - // Decide how many reference frames we need. This might be doable more - // nicely based on the codec and input stream? - ctx->decode_surfaces = DEFAULT_SURFACES; - // For frame-threaded decoding, one additional surfaces is needed for - // each thread. - if (avctx->active_thread_type & FF_THREAD_FRAME) - ctx->decode_surfaces += avctx->thread_count; - - return 0; - -fail: - av_hwframe_constraints_free(&constraints); - av_freep(&hwconfig); - vaDestroyConfig(hwctx->display, ctx->va_config); - av_freep(&profile_list); - return err; -} - static void vaapi_decode_uninit(AVCodecContext *avctx) { InputStream *ist = avctx->opaque; VAAPIDecoderContext *ctx = ist->hwaccel_ctx; if (ctx) { - AVVAAPIDeviceContext *hwctx = ctx->device->hwctx; - - if (ctx->va_context != VA_INVALID_ID) { - vaDestroyContext(hwctx->display, ctx->va_context); - ctx->va_context = VA_INVALID_ID; - } - if (ctx->va_config != VA_INVALID_ID) { - vaDestroyConfig(hwctx->display, ctx->va_config); - ctx->va_config = VA_INVALID_ID; - } - av_buffer_unref(&ctx->frames_ref); av_buffer_unref(&ctx->device_ref); av_free(ctx); @@ -402,19 +127,16 @@ static void vaapi_decode_uninit(AVCodecContext *avctx) av_buffer_unref(&ist->hw_frames_ctx); - ist->hwaccel_ctx = 0; - ist->hwaccel_uninit = 0; - ist->hwaccel_get_buffer = 0; - ist->hwaccel_retrieve_data = 0; + ist->hwaccel_ctx = NULL; + ist->hwaccel_uninit = NULL; + ist->hwaccel_get_buffer = NULL; + ist->hwaccel_retrieve_data = NULL; } int vaapi_decode_init(AVCodecContext *avctx) { InputStream *ist = avctx->opaque; - AVVAAPIDeviceContext *hwctx; - AVVAAPIFramesContext *avfc; VAAPIDecoderContext *ctx; - VAStatus vas; int err; int loglevel = (ist->hwaccel_id != HWACCEL_VAAPI ? AV_LOG_VERBOSE : AV_LOG_ERROR); @@ -439,20 +161,7 @@ int vaapi_decode_init(AVCodecContext *avctx) ctx->device_ref = av_buffer_ref(hw_device_ctx); ctx->device = (AVHWDeviceContext*)ctx->device_ref->data; - ctx->va_config = VA_INVALID_ID; - ctx->va_context = VA_INVALID_ID; - - hwctx = ctx->device->hwctx; - ctx->output_format = ist->hwaccel_output_format; - - err = vaapi_build_decoder_config(ctx, avctx, - ist->hwaccel_id != HWACCEL_VAAPI); - if (err < 0) { - av_log(ctx, loglevel, "No supported configuration for this codec."); - goto fail; - } - avctx->pix_fmt = ctx->output_format; ctx->frames_ref = av_hwframe_ctx_alloc(ctx->device_ref); @@ -464,11 +173,21 @@ int vaapi_decode_init(AVCodecContext *avctx) ctx->frames = (AVHWFramesContext*)ctx->frames_ref->data; - ctx->frames->format = AV_PIX_FMT_VAAPI; - ctx->frames->sw_format = ctx->decode_format; - ctx->frames->width = ctx->decode_width; - ctx->frames->height = ctx->decode_height; - ctx->frames->initial_pool_size = ctx->decode_surfaces; + ctx->frames->format = AV_PIX_FMT_VAAPI; + ctx->frames->width = avctx->coded_width; + ctx->frames->height = avctx->coded_height; + + // It would be nice if we could query the available formats here, + // but unfortunately we don't have a VAConfigID to do it with. + // For now, just assume an NV12 format (or P010 if 10-bit). + ctx->frames->sw_format = (avctx->sw_pix_fmt == AV_PIX_FMT_YUV420P10 ? + AV_PIX_FMT_P010 : AV_PIX_FMT_NV12); + + // For frame-threaded decoding, at least one additional surface + // is needed for each thread. + ctx->frames->initial_pool_size = DEFAULT_SURFACES; + if (avctx->active_thread_type & FF_THREAD_FRAME) + ctx->frames->initial_pool_size += avctx->thread_count; err = av_hwframe_ctx_init(ctx->frames_ref); if (err < 0) { @@ -477,27 +196,6 @@ int vaapi_decode_init(AVCodecContext *avctx) goto fail; } - avfc = ctx->frames->hwctx; - - vas = vaCreateContext(hwctx->display, ctx->va_config, - ctx->decode_width, ctx->decode_height, - VA_PROGRESSIVE, - avfc->surface_ids, avfc->nb_surfaces, - &ctx->va_context); - if (vas != VA_STATUS_SUCCESS) { - av_log(ctx, AV_LOG_ERROR, "Failed to create decode pipeline " - "context: %d (%s).\n", vas, vaErrorStr(vas)); - err = AVERROR(EINVAL); - goto fail; - } - - av_log(ctx, AV_LOG_DEBUG, "VAAPI decoder (re)init complete.\n"); - - // We would like to set this on the AVCodecContext for use by whoever gets - // the frames from the decoder, but unfortunately the AVCodecContext we - // have here need not be the "real" one (H.264 makes many copies for - // threading purposes). To avoid the problem, we instead store it in the - // InputStream and propagate it from there. ist->hw_frames_ctx = av_buffer_ref(ctx->frames_ref); if (!ist->hw_frames_ctx) { err = AVERROR(ENOMEM); @@ -505,14 +203,9 @@ int vaapi_decode_init(AVCodecContext *avctx) } ist->hwaccel_ctx = ctx; - ist->hwaccel_uninit = vaapi_decode_uninit; - ist->hwaccel_get_buffer = vaapi_get_buffer; - ist->hwaccel_retrieve_data = vaapi_retrieve_data; - - ctx->decoder_vaapi_context.display = hwctx->display; - ctx->decoder_vaapi_context.config_id = ctx->va_config; - ctx->decoder_vaapi_context.context_id = ctx->va_context; - avctx->hwaccel_context = &ctx->decoder_vaapi_context; + ist->hwaccel_uninit = &vaapi_decode_uninit; + ist->hwaccel_get_buffer = &vaapi_get_buffer; + ist->hwaccel_retrieve_data = &vaapi_retrieve_data; return 0; From 851960f6f8cf1f946fe42fa36cf6598fac68072c Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Wed, 24 Aug 2016 23:30:29 +0100 Subject: [PATCH 0129/3374] lavc: Remove old vaapi decode infrastructure Deprecates struct vaapi_context and the installed header vaapi.h, to be removed at the next version bump. --- doc/APIchanges | 4 + libavcodec/Makefile | 5 +- libavcodec/vaapi.c | 222 ------------------------------------ libavcodec/vaapi.h | 11 ++ libavcodec/vaapi_decode.c | 78 +++++++------ libavcodec/vaapi_decode.h | 6 + libavcodec/vaapi_internal.h | 71 ------------ libavcodec/version.h | 5 +- 8 files changed, 73 insertions(+), 329 deletions(-) delete mode 100644 libavcodec/vaapi.c delete mode 100644 libavcodec/vaapi_internal.h diff --git a/doc/APIchanges b/doc/APIchanges index 1b65c4be1fe20..c4cc0b4d0f526 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,10 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-xx-xx - xxxxxxx - lavc 59.26.0 - vaapi.h + Deprecate struct vaapi_context and the vaapi.h installed header. + Callers should set AVCodecContext.hw_frames_ctx instead. + 2016-07-20 - xxxxxxx - lavu 55.20.0 - cpu.h Add AV_CPU_FLAG_SSSE3SLOW. diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 4d04d6a113a01..974480f06dc81 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -610,7 +610,7 @@ OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcmenc.o adpcm_data.o # hardware accelerators OBJS-$(CONFIG_D3D11VA) += dxva2.o OBJS-$(CONFIG_DXVA2) += dxva2.o -OBJS-$(CONFIG_VAAPI) += vaapi.o vaapi_decode.o +OBJS-$(CONFIG_VAAPI) += vaapi_decode.o OBJS-$(CONFIG_VDA) += vda.o OBJS-$(CONFIG_VDPAU) += vdpau.o @@ -777,8 +777,7 @@ SKIPHEADERS-$(CONFIG_NVENC) += nvenc.h SKIPHEADERS-$(CONFIG_QSV) += qsv.h qsv_internal.h SKIPHEADERS-$(CONFIG_QSVDEC) += qsvdec.h SKIPHEADERS-$(CONFIG_QSVENC) += qsvenc.h -SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_decode.h vaapi_encode.h \ - vaapi_internal.h +SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_decode.h vaapi_encode.h SKIPHEADERS-$(CONFIG_VDA) += vda.h vda_internal.h SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h vdpau_internal.h diff --git a/libavcodec/vaapi.c b/libavcodec/vaapi.c deleted file mode 100644 index d2aafac38e46b..0000000000000 --- a/libavcodec/vaapi.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Video Acceleration API (video decoding) - * HW decode acceleration for MPEG-2, MPEG-4, H.264 and VC-1 - * - * Copyright (C) 2008-2009 Splitted-Desktop Systems - * - * This file is part of Libav. - * - * Libav is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * Libav is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "h264dec.h" -#include "mpegvideo.h" -#include "vaapi_internal.h" - -/** - * @addtogroup VAAPI_Decoding - * - * @{ - */ - -static void destroy_buffers(VADisplay display, VABufferID *buffers, unsigned int n_buffers) -{ - unsigned int i; - for (i = 0; i < n_buffers; i++) { - if (buffers[i]) { - vaDestroyBuffer(display, buffers[i]); - buffers[i] = 0; - } - } -} - -int ff_vaapi_render_picture(struct vaapi_context *vactx, VASurfaceID surface) -{ - VABufferID va_buffers[3]; - unsigned int n_va_buffers = 0; - - vaUnmapBuffer(vactx->display, vactx->pic_param_buf_id); - va_buffers[n_va_buffers++] = vactx->pic_param_buf_id; - - if (vactx->iq_matrix_buf_id) { - vaUnmapBuffer(vactx->display, vactx->iq_matrix_buf_id); - va_buffers[n_va_buffers++] = vactx->iq_matrix_buf_id; - } - - if (vactx->bitplane_buf_id) { - vaUnmapBuffer(vactx->display, vactx->bitplane_buf_id); - va_buffers[n_va_buffers++] = vactx->bitplane_buf_id; - } - - if (vaBeginPicture(vactx->display, vactx->context_id, - surface) != VA_STATUS_SUCCESS) - return -1; - - if (vaRenderPicture(vactx->display, vactx->context_id, - va_buffers, n_va_buffers) != VA_STATUS_SUCCESS) - return -1; - - if (vaRenderPicture(vactx->display, vactx->context_id, - vactx->slice_buf_ids, - vactx->n_slice_buf_ids) != VA_STATUS_SUCCESS) - return -1; - - if (vaEndPicture(vactx->display, vactx->context_id) != VA_STATUS_SUCCESS) - return -1; - - return 0; -} - -int ff_vaapi_commit_slices(struct vaapi_context *vactx) -{ - VABufferID *slice_buf_ids; - VABufferID slice_param_buf_id, slice_data_buf_id; - - if (vactx->slice_count == 0) - return 0; - - slice_buf_ids = - av_fast_realloc(vactx->slice_buf_ids, - &vactx->slice_buf_ids_alloc, - (vactx->n_slice_buf_ids + 2) * sizeof(slice_buf_ids[0])); - if (!slice_buf_ids) - return -1; - vactx->slice_buf_ids = slice_buf_ids; - - slice_param_buf_id = 0; - if (vaCreateBuffer(vactx->display, vactx->context_id, - VASliceParameterBufferType, - vactx->slice_param_size, - vactx->slice_count, vactx->slice_params, - &slice_param_buf_id) != VA_STATUS_SUCCESS) - return -1; - vactx->slice_count = 0; - - slice_data_buf_id = 0; - if (vaCreateBuffer(vactx->display, vactx->context_id, - VASliceDataBufferType, - vactx->slice_data_size, - 1, (void *)vactx->slice_data, - &slice_data_buf_id) != VA_STATUS_SUCCESS) - return -1; - vactx->slice_data = NULL; - vactx->slice_data_size = 0; - - slice_buf_ids[vactx->n_slice_buf_ids++] = slice_param_buf_id; - slice_buf_ids[vactx->n_slice_buf_ids++] = slice_data_buf_id; - return 0; -} - -static void *alloc_buffer(struct vaapi_context *vactx, int type, unsigned int size, uint32_t *buf_id) -{ - void *data = NULL; - - *buf_id = 0; - if (vaCreateBuffer(vactx->display, vactx->context_id, - type, size, 1, NULL, buf_id) == VA_STATUS_SUCCESS) - vaMapBuffer(vactx->display, *buf_id, &data); - - return data; -} - -void *ff_vaapi_alloc_pic_param(struct vaapi_context *vactx, unsigned int size) -{ - return alloc_buffer(vactx, VAPictureParameterBufferType, size, &vactx->pic_param_buf_id); -} - -void *ff_vaapi_alloc_iq_matrix(struct vaapi_context *vactx, unsigned int size) -{ - return alloc_buffer(vactx, VAIQMatrixBufferType, size, &vactx->iq_matrix_buf_id); -} - -uint8_t *ff_vaapi_alloc_bitplane(struct vaapi_context *vactx, uint32_t size) -{ - return alloc_buffer(vactx, VABitPlaneBufferType, size, &vactx->bitplane_buf_id); -} - -VASliceParameterBufferBase *ff_vaapi_alloc_slice(struct vaapi_context *vactx, const uint8_t *buffer, uint32_t size) -{ - uint8_t *slice_params; - VASliceParameterBufferBase *slice_param; - - if (!vactx->slice_data) - vactx->slice_data = buffer; - if (vactx->slice_data + vactx->slice_data_size != buffer) { - if (ff_vaapi_commit_slices(vactx) < 0) - return NULL; - vactx->slice_data = buffer; - } - - slice_params = - av_fast_realloc(vactx->slice_params, - &vactx->slice_params_alloc, - (vactx->slice_count + 1) * vactx->slice_param_size); - if (!slice_params) - return NULL; - vactx->slice_params = slice_params; - - slice_param = (VASliceParameterBufferBase *)(slice_params + vactx->slice_count * vactx->slice_param_size); - slice_param->slice_data_size = size; - slice_param->slice_data_offset = vactx->slice_data_size; - slice_param->slice_data_flag = VA_SLICE_DATA_FLAG_ALL; - - vactx->slice_count++; - vactx->slice_data_size += size; - return slice_param; -} - -void ff_vaapi_common_end_frame(AVCodecContext *avctx) -{ - struct vaapi_context * const vactx = avctx->hwaccel_context; - - destroy_buffers(vactx->display, &vactx->pic_param_buf_id, 1); - destroy_buffers(vactx->display, &vactx->iq_matrix_buf_id, 1); - destroy_buffers(vactx->display, &vactx->bitplane_buf_id, 1); - destroy_buffers(vactx->display, vactx->slice_buf_ids, vactx->n_slice_buf_ids); - av_freep(&vactx->slice_buf_ids); - av_freep(&vactx->slice_params); - vactx->n_slice_buf_ids = 0; - vactx->slice_buf_ids_alloc = 0; - vactx->slice_count = 0; - vactx->slice_params_alloc = 0; -} - -#if CONFIG_H263_VAAPI_HWACCEL || CONFIG_MPEG1_VAAPI_HWACCEL || \ - CONFIG_MPEG2_VAAPI_HWACCEL || CONFIG_MPEG4_VAAPI_HWACCEL || \ - CONFIG_VC1_VAAPI_HWACCEL || CONFIG_WMV3_VAAPI_HWACCEL -int ff_vaapi_mpeg_end_frame(AVCodecContext *avctx) -{ - struct vaapi_context * const vactx = avctx->hwaccel_context; - MpegEncContext *s = avctx->priv_data; - int ret; - - ret = ff_vaapi_commit_slices(vactx); - if (ret < 0) - goto finish; - - ret = ff_vaapi_render_picture(vactx, - ff_vaapi_get_surface_id(s->current_picture_ptr->f)); - if (ret < 0) - goto finish; - - ff_mpeg_draw_horiz_band(s, 0, s->avctx->height); - -finish: - ff_vaapi_common_end_frame(avctx); - return ret; -} -#endif - -/* @} */ diff --git a/libavcodec/vaapi.h b/libavcodec/vaapi.h index 39e88259d641a..ceb7904bea886 100644 --- a/libavcodec/vaapi.h +++ b/libavcodec/vaapi.h @@ -32,6 +32,12 @@ #include +#include "libavutil/attributes.h" + +#include "version.h" + +#if FF_API_VAAPI_CONTEXT + /** * @defgroup lavc_codec_hwaccel_vaapi VA API Decoding * @ingroup lavc_codec_hwaccel @@ -46,7 +52,10 @@ * during initialization or through each AVCodecContext.get_buffer() * function call. In any case, they must be valid prior to calling * decoding functions. + * + * Deprecated: use AVCodecContext.hw_frames_ctx instead. */ +attribute_deprecated struct vaapi_context { /** * Window system dependent data @@ -170,4 +179,6 @@ struct vaapi_context { /* @} */ +#endif /* FF_API_VAAPI_CONTEXT */ + #endif /* AVCODEC_VAAPI_H */ diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c index 78b479ff6f07e..51b6d47a66516 100644 --- a/libavcodec/vaapi_decode.c +++ b/libavcodec/vaapi_decode.c @@ -425,6 +425,7 @@ int ff_vaapi_decode_init(AVCodecContext *avctx) ctx->va_config = VA_INVALID_ID; ctx->va_context = VA_INVALID_ID; +#if FF_API_VAAPI_CONTEXT if (avctx->hwaccel_context) { av_log(avctx, AV_LOG_WARNING, "Using deprecated struct " "vaapi_context in decode.\n"); @@ -451,7 +452,9 @@ int ff_vaapi_decode_init(AVCodecContext *avctx) ctx->hwctx->driver_quirks = AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS; - } else if (avctx->hw_frames_ctx) { + } else +#endif + if (avctx->hw_frames_ctx) { // This structure has a shorter lifetime than the enclosing // AVCodecContext, so we inherit the references from there // and do not need to make separate ones. @@ -469,6 +472,7 @@ int ff_vaapi_decode_init(AVCodecContext *avctx) goto fail; } +#if FF_API_VAAPI_CONTEXT if (ctx->have_old_context) { ctx->va_config = ctx->old_context->config_id; ctx->va_context = ctx->old_context->context_id; @@ -476,27 +480,31 @@ int ff_vaapi_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_DEBUG, "Using user-supplied decoder " "context: %#x/%#x.\n", ctx->va_config, ctx->va_context); } else { - err = vaapi_decode_make_config(avctx); - if (err) - goto fail; +#endif - vas = vaCreateContext(ctx->hwctx->display, ctx->va_config, - avctx->coded_width, avctx->coded_height, - VA_PROGRESSIVE, - ctx->hwfc->surface_ids, - ctx->hwfc->nb_surfaces, - &ctx->va_context); - if (vas != VA_STATUS_SUCCESS) { - av_log(avctx, AV_LOG_ERROR, "Failed to create decode " - "context: %d (%s).\n", vas, vaErrorStr(vas)); - err = AVERROR(EIO); - goto fail; - } + err = vaapi_decode_make_config(avctx); + if (err) + goto fail; - av_log(avctx, AV_LOG_DEBUG, "Decode context initialised: " - "%#x/%#x.\n", ctx->va_config, ctx->va_context); + vas = vaCreateContext(ctx->hwctx->display, ctx->va_config, + avctx->coded_width, avctx->coded_height, + VA_PROGRESSIVE, + ctx->hwfc->surface_ids, + ctx->hwfc->nb_surfaces, + &ctx->va_context); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to create decode " + "context: %d (%s).\n", vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail; } + av_log(avctx, AV_LOG_DEBUG, "Decode context initialised: " + "%#x/%#x.\n", ctx->va_config, ctx->va_context); +#if FF_API_VAAPI_CONTEXT + } +#endif + return 0; fail: @@ -509,26 +517,32 @@ int ff_vaapi_decode_uninit(AVCodecContext *avctx) VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data; VAStatus vas; +#if FF_API_VAAPI_CONTEXT if (ctx->have_old_context) { av_buffer_unref(&ctx->device_ref); } else { - if (ctx->va_context != VA_INVALID_ID) { - vas = vaDestroyContext(ctx->hwctx->display, ctx->va_context); - if (vas != VA_STATUS_SUCCESS) { - av_log(avctx, AV_LOG_ERROR, "Failed to destroy decode " - "context %#x: %d (%s).\n", - ctx->va_context, vas, vaErrorStr(vas)); - } +#endif + + if (ctx->va_context != VA_INVALID_ID) { + vas = vaDestroyContext(ctx->hwctx->display, ctx->va_context); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to destroy decode " + "context %#x: %d (%s).\n", + ctx->va_context, vas, vaErrorStr(vas)); } - if (ctx->va_config != VA_INVALID_ID) { - vas = vaDestroyConfig(ctx->hwctx->display, ctx->va_config); - if (vas != VA_STATUS_SUCCESS) { - av_log(avctx, AV_LOG_ERROR, "Failed to destroy decode " - "configuration %#x: %d (%s).\n", - ctx->va_config, vas, vaErrorStr(vas)); - } + } + if (ctx->va_config != VA_INVALID_ID) { + vas = vaDestroyConfig(ctx->hwctx->display, ctx->va_config); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to destroy decode " + "configuration %#x: %d (%s).\n", + ctx->va_config, vas, vaErrorStr(vas)); } } +#if FF_API_VAAPI_CONTEXT + } +#endif + return 0; } diff --git a/libavcodec/vaapi_decode.h b/libavcodec/vaapi_decode.h index 7882925a25ae0..08b212d0302fc 100644 --- a/libavcodec/vaapi_decode.h +++ b/libavcodec/vaapi_decode.h @@ -26,7 +26,11 @@ #include "libavutil/hwcontext_vaapi.h" #include "avcodec.h" + +#include "version.h" +#if FF_API_VAAPI_CONTEXT #include "vaapi.h" +#endif static inline VASurfaceID ff_vaapi_get_surface_id(AVFrame *pic) { @@ -54,9 +58,11 @@ typedef struct VAAPIDecodeContext { VAConfigID va_config; VAContextID va_context; +#if FF_API_VAAPI_CONTEXT int have_old_context; struct vaapi_context *old_context; AVBufferRef *device_ref; +#endif AVHWDeviceContext *device; AVVAAPIDeviceContext *hwctx; diff --git a/libavcodec/vaapi_internal.h b/libavcodec/vaapi_internal.h deleted file mode 100644 index 5e2a6ca63137a..0000000000000 --- a/libavcodec/vaapi_internal.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Video Acceleration API (video decoding) - * HW decode acceleration for MPEG-2, MPEG-4, H.264 and VC-1 - * - * Copyright (C) 2008-2009 Splitted-Desktop Systems - * - * This file is part of Libav. - * - * Libav is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * Libav is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_VAAPI_INTERNAL_H -#define AVCODEC_VAAPI_INTERNAL_H - -#include -#include "vaapi.h" -#include "avcodec.h" - -/** - * @addtogroup VAAPI_Decoding - * - * @{ - */ - -/** Extract VASurfaceID from an AVFrame */ -static inline VASurfaceID ff_vaapi_get_surface_id(AVFrame *pic) -{ - return (uintptr_t)pic->data[3]; -} - -/** Common AVHWAccel.end_frame() implementation */ -void ff_vaapi_common_end_frame(AVCodecContext *avctx); - -/** Allocate a new picture parameter buffer */ -void *ff_vaapi_alloc_pic_param(struct vaapi_context *vactx, unsigned int size); - -/** Allocate a new IQ matrix buffer */ -void *ff_vaapi_alloc_iq_matrix(struct vaapi_context *vactx, unsigned int size); - -/** Allocate a new bit-plane buffer */ -uint8_t *ff_vaapi_alloc_bitplane(struct vaapi_context *vactx, uint32_t size); - -/** - * Allocate a new slice descriptor for the input slice. - * - * @param vactx the VA API context - * @param buffer the slice data buffer base - * @param size the size of the slice in bytes - * @return the newly allocated slice parameter - */ -VASliceParameterBufferBase *ff_vaapi_alloc_slice(struct vaapi_context *vactx, const uint8_t *buffer, uint32_t size); - -int ff_vaapi_mpeg_end_frame(AVCodecContext *avctx); -int ff_vaapi_commit_slices(struct vaapi_context *vactx); -int ff_vaapi_render_picture(struct vaapi_context *vactx, VASurfaceID surface); - -/* @} */ - -#endif /* AVCODEC_VAAPI_INTERNAL_H */ diff --git a/libavcodec/version.h b/libavcodec/version.h index f94470914ec89..b132bf7071bee 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 25 +#define LIBAVCODEC_VERSION_MINOR 26 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ @@ -206,5 +206,8 @@ #ifndef FF_API_GET_CONTEXT_DEFAULTS #define FF_API_GET_CONTEXT_DEFAULTS (LIBAVCODEC_VERSION_MAJOR < 59) #endif +#ifndef FF_API_VAAPI_CONTEXT +#define FF_API_VAAPI_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 59) +#endif #endif /* AVCODEC_VERSION_H */ From 24da430324735f95880c4a4a54298dc8023125bb Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 25 Aug 2016 09:59:32 +0200 Subject: [PATCH 0130/3374] Changelog: mark the release 12 branch --- Changelog | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Changelog b/Changelog index f39a1bb2e5f3f..cd0ffb52135e7 100644 --- a/Changelog +++ b/Changelog @@ -2,6 +2,9 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. version : + + +version 12: - aliases and defaults for Ogg subtypes (opus, spx) - HEVC/H.265 RTP payload format (draft v6) packetizer and depacketizer - avplay now exits by default at the end of playback From d7bc52bf456deba0f32d9fe5c288ec441f1ebef5 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 23 Aug 2016 21:46:50 +0200 Subject: [PATCH 0131/3374] imgutils: add a function for copying image data from GPU mapped memory See https://software.intel.com/en-us/articles/copying-accelerated-video-decode-frame-buffers --- doc/APIchanges | 4 ++ libavutil/imgutils.c | 75 +++++++++++++++++++++++++++++------ libavutil/imgutils.h | 18 +++++++++ libavutil/imgutils_internal.h | 30 ++++++++++++++ libavutil/version.h | 2 +- libavutil/x86/Makefile | 2 + libavutil/x86/imgutils.asm | 53 +++++++++++++++++++++++++ libavutil/x86/imgutils_init.c | 49 +++++++++++++++++++++++ 8 files changed, 219 insertions(+), 14 deletions(-) create mode 100644 libavutil/imgutils_internal.h create mode 100644 libavutil/x86/imgutils.asm create mode 100644 libavutil/x86/imgutils_init.c diff --git a/doc/APIchanges b/doc/APIchanges index c4cc0b4d0f526..a4e418acd3710 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,10 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-08-24 - xxxxxxx - lavu 55.21.0 - imgutils.h + Add av_image_copy_uc_from(), a version of av_image_copy() for copying + from GPU mapped memory. + 2016-xx-xx - xxxxxxx - lavc 59.26.0 - vaapi.h Deprecate struct vaapi_context and the vaapi.h installed header. Callers should set AVCodecContext.hw_frames_ctx instead. diff --git a/libavutil/imgutils.c b/libavutil/imgutils.c index 6c581396a3d3f..20d06ec1759e9 100644 --- a/libavutil/imgutils.c +++ b/libavutil/imgutils.c @@ -23,6 +23,7 @@ #include "common.h" #include "imgutils.h" +#include "imgutils_internal.h" #include "internal.h" #include "intreadwrite.h" #include "log.h" @@ -252,9 +253,9 @@ int av_image_check_sar(unsigned int w, unsigned int h, AVRational sar) return AVERROR(EINVAL); } -void av_image_copy_plane(uint8_t *dst, int dst_linesize, - const uint8_t *src, int src_linesize, - int bytewidth, int height) +static void image_copy_plane(uint8_t *dst, ptrdiff_t dst_linesize, + const uint8_t *src, ptrdiff_t src_linesize, + ptrdiff_t bytewidth, int height) { if (!dst || !src) return; @@ -265,9 +266,33 @@ void av_image_copy_plane(uint8_t *dst, int dst_linesize, } } -void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], - const uint8_t *src_data[4], const int src_linesizes[4], - enum AVPixelFormat pix_fmt, int width, int height) +static void image_copy_plane_uc_from(uint8_t *dst, ptrdiff_t dst_linesize, + const uint8_t *src, ptrdiff_t src_linesize, + ptrdiff_t bytewidth, int height) +{ + int ret = -1; + +#if ARCH_X86 + ret = ff_image_copy_plane_uc_from_x86(dst, dst_linesize, src, src_linesize, + bytewidth, height); +#endif + + if (ret < 0) + image_copy_plane(dst, dst_linesize, src, src_linesize, bytewidth, height); +} + +void av_image_copy_plane(uint8_t *dst, int dst_linesize, + const uint8_t *src, int src_linesize, + int bytewidth, int height) +{ + image_copy_plane(dst, dst_linesize, src, src_linesize, bytewidth, height); +} + +static void image_copy(uint8_t *dst_data[4], const ptrdiff_t dst_linesizes[4], + const uint8_t *src_data[4], const ptrdiff_t src_linesizes[4], + enum AVPixelFormat pix_fmt, int width, int height, + void (*copy_plane)(uint8_t *, ptrdiff_t, const uint8_t *, + ptrdiff_t, ptrdiff_t, int)) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); @@ -276,9 +301,9 @@ void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], if (desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) { - av_image_copy_plane(dst_data[0], dst_linesizes[0], - src_data[0], src_linesizes[0], - width, height); + copy_plane(dst_data[0], dst_linesizes[0], + src_data[0], src_linesizes[0], + width, height); /* copy the palette */ memcpy(dst_data[1], src_data[1], 4*256); } else { @@ -289,17 +314,41 @@ void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], for (i = 0; i < planes_nb; i++) { int h = height; - int bwidth = av_image_get_linesize(pix_fmt, width, i); + ptrdiff_t bwidth = av_image_get_linesize(pix_fmt, width, i); if (i == 1 || i == 2) { h = AV_CEIL_RSHIFT(height, desc->log2_chroma_h); } - av_image_copy_plane(dst_data[i], dst_linesizes[i], - src_data[i], src_linesizes[i], - bwidth, h); + copy_plane(dst_data[i], dst_linesizes[i], + src_data[i], src_linesizes[i], + bwidth, h); } } } +void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], + const uint8_t *src_data[4], const int src_linesizes[4], + enum AVPixelFormat pix_fmt, int width, int height) +{ + ptrdiff_t dst_linesizes1[4], src_linesizes1[4]; + int i; + + for (i = 0; i < 4; i++) { + dst_linesizes1[i] = dst_linesizes[i]; + src_linesizes1[i] = src_linesizes[i]; + } + + image_copy(dst_data, dst_linesizes1, src_data, src_linesizes1, pix_fmt, + width, height, image_copy_plane); +} + +void av_image_copy_uc_from(uint8_t *dst_data[4], const ptrdiff_t dst_linesizes[4], + const uint8_t *src_data[4], const ptrdiff_t src_linesizes[4], + enum AVPixelFormat pix_fmt, int width, int height) +{ + image_copy(dst_data, dst_linesizes, src_data, src_linesizes, pix_fmt, + width, height, image_copy_plane_uc_from); +} + int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4], const uint8_t *src, enum AVPixelFormat pix_fmt, int width, int height, int align) diff --git a/libavutil/imgutils.h b/libavutil/imgutils.h index 04d6138f677d7..f98a18ff219b7 100644 --- a/libavutil/imgutils.h +++ b/libavutil/imgutils.h @@ -117,6 +117,24 @@ void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], const uint8_t *src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height); +/** + * Copy image data located in uncacheable (e.g. GPU mapped) memory. Where + * available, this function will use special functionality for reading from such + * memory, which may result in greatly improved performance compared to plain + * av_image_copy(). + * + * The data pointers and the linesizes must be aligned to the maximum required + * by the CPU architecture. + * + * @note The linesize parameters have the type ptrdiff_t here, while they are + * int for av_image_copy(). + * @note On x86, the linesizes currently need to be aligned to the cacheline + * size (i.e. 64) to get improved performance. + */ +void av_image_copy_uc_from(uint8_t *dst_data[4], const ptrdiff_t dst_linesizes[4], + const uint8_t *src_data[4], const ptrdiff_t src_linesizes[4], + enum AVPixelFormat pix_fmt, int width, int height); + /** * Setup the data pointers and linesizes based on the specified image * parameters and the provided array. diff --git a/libavutil/imgutils_internal.h b/libavutil/imgutils_internal.h new file mode 100644 index 0000000000000..7a932a5f52cc5 --- /dev/null +++ b/libavutil/imgutils_internal.h @@ -0,0 +1,30 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_IMGUTILS_INTERNAL_H +#define AVUTIL_IMGUTILS_INTERNAL_H + +#include +#include + +int ff_image_copy_plane_uc_from_x86(uint8_t *dst, ptrdiff_t dst_linesize, + const uint8_t *src, ptrdiff_t src_linesize, + ptrdiff_t bytewidth, int height); + + +#endif /* AVUTIL_IMGUTILS_INTERNAL_H */ diff --git a/libavutil/version.h b/libavutil/version.h index 5cbc0e880eccb..f63dfa5d3f7cc 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -54,7 +54,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 20 +#define LIBAVUTIL_VERSION_MINOR 21 #define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ diff --git a/libavutil/x86/Makefile b/libavutil/x86/Makefile index 1e1908223358c..ffee43b1ad649 100644 --- a/libavutil/x86/Makefile +++ b/libavutil/x86/Makefile @@ -1,8 +1,10 @@ OBJS += x86/cpu.o \ x86/float_dsp_init.o \ + x86/imgutils_init.o \ x86/lls_init.o \ YASM-OBJS += x86/cpuid.o \ x86/emms.o \ x86/float_dsp.o \ + x86/imgutils.o \ x86/lls.o \ diff --git a/libavutil/x86/imgutils.asm b/libavutil/x86/imgutils.asm new file mode 100644 index 0000000000000..9c1e940822bc3 --- /dev/null +++ b/libavutil/x86/imgutils.asm @@ -0,0 +1,53 @@ +;***************************************************************************** +;* Copyright 2016 Anton Khirnov +;* +;* This file is part of Libav. +;* +;* Libav is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* Libav is distributed in the hope that it will be useful, +;* but WITHOUT ANY WARRANTY; without even the implied warranty of +;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with Libav; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION .text + +INIT_XMM sse4 +cglobal image_copy_plane_uc_from, 6, 7, 4, dst, dst_linesize, src, src_linesize, bw, height, rowpos + add dstq, bwq + add srcq, bwq + neg bwq + +.row_start + mov rowposq, bwq + +.loop + movntdqa m0, [srcq + rowposq + 0 * mmsize] + movntdqa m1, [srcq + rowposq + 1 * mmsize] + movntdqa m2, [srcq + rowposq + 2 * mmsize] + movntdqa m3, [srcq + rowposq + 3 * mmsize] + + mova [dstq + rowposq + 0 * mmsize], m0 + mova [dstq + rowposq + 1 * mmsize], m1 + mova [dstq + rowposq + 2 * mmsize], m2 + mova [dstq + rowposq + 3 * mmsize], m3 + + add rowposq, 4 * mmsize + jnz .loop + + add srcq, src_linesizeq + add dstq, dst_linesizeq + dec heightd + jnz .row_start + + RET diff --git a/libavutil/x86/imgutils_init.c b/libavutil/x86/imgutils_init.c new file mode 100644 index 0000000000000..20ee9abaa2c4d --- /dev/null +++ b/libavutil/x86/imgutils_init.c @@ -0,0 +1,49 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "libavutil/cpu.h" +#include "libavutil/error.h" +#include "libavutil/imgutils.h" +#include "libavutil/imgutils_internal.h" +#include "libavutil/internal.h" + +#include "cpu.h" + +void ff_image_copy_plane_uc_from_sse4(uint8_t *dst, ptrdiff_t dst_linesize, + const uint8_t *src, ptrdiff_t src_linesize, + ptrdiff_t bytewidth, int height); + +int ff_image_copy_plane_uc_from_x86(uint8_t *dst, ptrdiff_t dst_linesize, + const uint8_t *src, ptrdiff_t src_linesize, + ptrdiff_t bytewidth, int height) +{ + int cpu_flags = av_get_cpu_flags(); + ptrdiff_t bw_aligned = FFALIGN(bytewidth, 64); + + if (EXTERNAL_SSE4(cpu_flags) && + bw_aligned <= dst_linesize && bw_aligned <= src_linesize) + ff_image_copy_plane_uc_from_sse4(dst, dst_linesize, src, src_linesize, + bw_aligned, height); + else + return AVERROR(ENOSYS); + + return 0; +} From f01f7a7846529b7c3ef343f117eaa2c0a1457af0 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 24 Aug 2016 09:24:49 +0200 Subject: [PATCH 0132/3374] hwcontext_dxva2: use the special UC copy for downloading frames --- libavutil/hwcontext_dxva2.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libavutil/hwcontext_dxva2.c b/libavutil/hwcontext_dxva2.c index f66c0fa740bad..da89453802907 100644 --- a/libavutil/hwcontext_dxva2.c +++ b/libavutil/hwcontext_dxva2.c @@ -277,8 +277,13 @@ static int dxva2_transfer_data(AVHWFramesContext *ctx, AVFrame *dst, (uint8_t*)LockedRect.pBits, surf_linesize); if (download) { - av_image_copy(dst->data, dst->linesize, surf_data, surf_linesize, - ctx->sw_format, src->width, src->height); + ptrdiff_t src_linesize1[4], dst_linesize1[4]; + for (i = 0; i < 4; i++) { + dst_linesize1[i] = dst->linesize[i]; + src_linesize1[i] = surf_linesize[i]; + } + av_image_copy_uc_from(dst->data, dst_linesize1, surf_data, src_linesize1, + ctx->sw_format, src->width, src->height); } else { av_image_copy(surf_data, surf_linesize, src->data, src->linesize, ctx->sw_format, src->width, src->height); From 4fb311c804098d78e5ce5f527f9a9c37536d3a08 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 24 Mar 2016 20:55:19 +0100 Subject: [PATCH 0133/3374] Drop memalign hack It no longer serves a useful purpose. --- configure | 7 ------- libavutil/mem.c | 29 +++-------------------------- 2 files changed, 3 insertions(+), 33 deletions(-) diff --git a/configure b/configure index 660b06284acc8..80f39f378031a 100755 --- a/configure +++ b/configure @@ -294,7 +294,6 @@ Advanced options (experts only): --disable-safe-bitstream-reader disable buffer boundary checking in bitreaders (faster, but may crash) - --enable-memalign-hack emulate memalign, interferes with memory debuggers --enable-sram allow use of on-chip SRAM Optimization options (experts only): @@ -1354,7 +1353,6 @@ CONFIG_LIST=" $LIBRARY_LIST $PROGRAM_LIST $SUBSYSTEM_LIST - memalign_hack neon_clobber_test pic pod2man @@ -1471,7 +1469,6 @@ ARCH_FEATURES=" local_aligned_8 local_aligned_16 local_aligned_32 - simd_align simd_align_16 simd_align_32 " @@ -1884,7 +1881,6 @@ aligned_stack_if_any="aarch64 ppc x86" fast_64bit_if_any="aarch64 alpha ia64 mips64 parisc64 ppc64 sparc64 x86_64" fast_clz_if_any="aarch64 alpha avr32 mips ppc x86" fast_unaligned_if_any="aarch64 ppc x86" -simd_align_if_any="simd_align_16 simd_align_32" simd_align_16_if_any="altivec neon sse" simd_align_32_if_any="avx" @@ -5041,9 +5037,6 @@ enabled_all dxva2 CoTaskMemFree && prepend avconv_libs $($ldflags_filter "-lole32") && enable dxva2_lib -! enabled_any memalign posix_memalign aligned_malloc && - enabled simd_align && enable memalign_hack - map 'enabled $v && intrinsics=${v#intrinsics_}' $INTRINSICS_LIST for thread in $THREADS_LIST; do diff --git a/libavutil/mem.c b/libavutil/mem.c index 15c28808c1bf0..0f506d360468c 100644 --- a/libavutil/mem.c +++ b/libavutil/mem.c @@ -62,22 +62,12 @@ void free(void *ptr); void *av_malloc(size_t size) { void *ptr = NULL; -#if CONFIG_MEMALIGN_HACK - long diff; -#endif /* let's disallow possibly ambiguous cases */ if (size > (INT_MAX - 32) || !size) return NULL; -#if CONFIG_MEMALIGN_HACK - ptr = malloc(size + 32); - if (!ptr) - return ptr; - diff = ((-(long)ptr - 1) & 31) + 1; - ptr = (char *)ptr + diff; - ((char *)ptr)[-1] = diff; -#elif HAVE_POSIX_MEMALIGN +#if HAVE_POSIX_MEMALIGN if (posix_memalign(&ptr, 32, size)) ptr = NULL; #elif HAVE_ALIGNED_MALLOC @@ -116,21 +106,11 @@ void *av_malloc(size_t size) void *av_realloc(void *ptr, size_t size) { -#if CONFIG_MEMALIGN_HACK - int diff; -#endif - /* let's disallow possibly ambiguous cases */ if (size > (INT_MAX - 16)) return NULL; -#if CONFIG_MEMALIGN_HACK - //FIXME this isn't aligned correctly, though it probably isn't needed - if (!ptr) - return av_malloc(size); - diff = ((char *)ptr)[-1]; - return (char *)realloc((char *)ptr - diff, size + diff) + diff; -#elif HAVE_ALIGNED_MALLOC +#if HAVE_ALIGNED_MALLOC return _aligned_realloc(ptr, size, 32); #else return realloc(ptr, size); @@ -189,10 +169,7 @@ int av_reallocp_array(void *ptr, size_t nmemb, size_t size) void av_free(void *ptr) { -#if CONFIG_MEMALIGN_HACK - if (ptr) - free((char *)ptr - ((char *)ptr)[-1]); -#elif HAVE_ALIGNED_MALLOC +#if HAVE_ALIGNED_MALLOC _aligned_free(ptr); #else free(ptr); From 746c56b7730ce09397d3a8354acc131285e9d829 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 26 Aug 2016 12:26:50 +0200 Subject: [PATCH 0134/3374] indeo: Change type of array pitch parameters to ptrdiff_t ptrdiff_t is the correct type for array pitches and similar. --- libavcodec/indeo3.c | 14 +++++------ libavcodec/ivi.c | 8 +++---- libavcodec/ivi.h | 6 ++--- libavcodec/ivi_dsp.c | 52 ++++++++++++++++++++-------------------- libavcodec/ivi_dsp.h | 57 ++++++++++++++++++++++---------------------- 5 files changed, 69 insertions(+), 68 deletions(-) diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c index f222a06c5a600..89c11e63467ed 100644 --- a/libavcodec/indeo3.c +++ b/libavcodec/indeo3.c @@ -65,7 +65,7 @@ typedef struct Plane { uint8_t *pixels[2]; ///< pointer to the actual pixel data of the buffers above uint32_t width; uint32_t height; - uint32_t pitch; + ptrdiff_t pitch; } Plane; #define CELL_STACK_MAX 20 @@ -151,7 +151,8 @@ static av_cold int allocate_frame_buffers(Indeo3DecodeContext *ctx, AVCodecContext *avctx) { int p, luma_width, luma_height, chroma_width, chroma_height; - int luma_pitch, chroma_pitch, luma_size, chroma_size; + int luma_size, chroma_size; + ptrdiff_t luma_pitch, chroma_pitch; luma_width = ctx->width; luma_height = ctx->height; @@ -415,7 +416,7 @@ if (*data_ptr >= last_ptr) \ static int decode_cell_data(Indeo3DecodeContext *ctx, Cell *cell, uint8_t *block, uint8_t *ref_block, - int pitch, int h_zoom, int v_zoom, int mode, + ptrdiff_t row_offset, int h_zoom, int v_zoom, int mode, const vqEntry *delta[2], int swap_quads[2], const uint8_t **data_ptr, const uint8_t *last_ptr) { @@ -426,9 +427,8 @@ static int decode_cell_data(Indeo3DecodeContext *ctx, Cell *cell, unsigned int dyad1, dyad2; uint64_t pix64; int skip_flag = 0, is_top_of_cell, is_first_row = 1; - int row_offset, blk_row_offset, line_offset; + int blk_row_offset, line_offset; - row_offset = pitch; blk_row_offset = (row_offset << (2 + v_zoom)) - (cell->width << 2); line_offset = v_zoom ? row_offset : 0; @@ -1011,11 +1011,11 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, * @param[in] dst_height output plane height */ static void output_plane(const Plane *plane, int buf_sel, uint8_t *dst, - int dst_pitch, int dst_height) + ptrdiff_t dst_pitch, int dst_height) { int x,y; const uint8_t *src = plane->pixels[buf_sel]; - uint32_t pitch = plane->pitch; + ptrdiff_t pitch = plane->pitch; dst_height = FFMIN(dst_height, plane->height); for (y = 0; y < dst_height; y++) { diff --git a/libavcodec/ivi.c b/libavcodec/ivi.c index 8a5977705a6ab..57946a334952e 100644 --- a/libavcodec/ivi.c +++ b/libavcodec/ivi.c @@ -73,10 +73,10 @@ static VLC ivi_mb_vlc_tabs [8]; ///< static macroblock Huffman tables static VLC ivi_blk_vlc_tabs[8]; ///< static block Huffman tables typedef void (*ivi_mc_func) (int16_t *buf, const int16_t *ref_buf, - uint32_t pitch, int mc_type); + ptrdiff_t pitch, int mc_type); typedef void (*ivi_mc_avg_func) (int16_t *buf, const int16_t *ref_buf1, const int16_t *ref_buf2, - uint32_t pitch, int mc_type, int mc_type2); + ptrdiff_t pitch, int mc_type, int mc_type2); static int ivi_mc(IVIBandDesc *band, ivi_mc_func mc, ivi_mc_avg_func mc_avg, int offs, int mv_x, int mv_y, int mv_x2, int mv_y2, @@ -882,11 +882,11 @@ static uint16_t ivi_calc_band_checksum(IVIBandDesc *band) * @param[out] dst pointer to the buffer receiving converted pixels * @param[in] dst_pitch pitch for moving to the next y line */ -static void ivi_output_plane(IVIPlaneDesc *plane, uint8_t *dst, int dst_pitch) +static void ivi_output_plane(IVIPlaneDesc *plane, uint8_t *dst, ptrdiff_t dst_pitch) { int x, y; const int16_t *src = plane->bands[0].buf; - uint32_t pitch = plane->bands[0].pitch; + ptrdiff_t pitch = plane->bands[0].pitch; if (!src) return; diff --git a/libavcodec/ivi.h b/libavcodec/ivi.h index 9b4824b081016..4082a90de959f 100644 --- a/libavcodec/ivi.h +++ b/libavcodec/ivi.h @@ -87,8 +87,8 @@ extern const uint8_t ff_ivi_direct_scan_4x4[16]; /** * Declare inverse transform function types */ -typedef void (InvTransformPtr)(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags); -typedef void (DCTransformPtr) (const int32_t *in, int16_t *out, uint32_t pitch, int blk_size); +typedef void (InvTransformPtr)(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags); +typedef void (DCTransformPtr) (const int32_t *in, int16_t *out, ptrdiff_t pitch, int blk_size); /** @@ -153,7 +153,7 @@ typedef struct IVIBandDesc { int16_t *ref_buf; ///< pointer to the reference frame buffer (for motion compensation) int16_t *b_ref_buf; ///< pointer to the second reference frame buffer (for motion compensation) int16_t *bufs[4]; ///< array of pointers to the band buffers - int pitch; ///< pitch associated with the buffers above + ptrdiff_t pitch; ///< pitch associated with the buffers above int is_empty; ///< = 1 if this band doesn't contain any data int mb_size; ///< macroblock size int blk_size; ///< block size diff --git a/libavcodec/ivi_dsp.c b/libavcodec/ivi_dsp.c index 9b74f730e444a..b8a476deb64e3 100644 --- a/libavcodec/ivi_dsp.c +++ b/libavcodec/ivi_dsp.c @@ -31,13 +31,13 @@ #include "ivi_dsp.h" void ff_ivi_recompose53(const IVIPlaneDesc *plane, uint8_t *dst, - const int dst_pitch) + const ptrdiff_t dst_pitch) { int x, y, indx; int32_t p0, p1, p2, p3, tmp0, tmp1, tmp2; int32_t b0_1, b0_2, b1_1, b1_2, b1_3, b2_1, b2_2, b2_3, b2_4, b2_5, b2_6; int32_t b3_1, b3_2, b3_3, b3_4, b3_5, b3_6, b3_7, b3_8, b3_9; - int32_t pitch, back_pitch; + ptrdiff_t pitch, back_pitch; const short *b0_ptr, *b1_ptr, *b2_ptr, *b3_ptr; const int num_bands = 4; @@ -178,11 +178,11 @@ void ff_ivi_recompose53(const IVIPlaneDesc *plane, uint8_t *dst, } void ff_ivi_recompose_haar(const IVIPlaneDesc *plane, uint8_t *dst, - const int dst_pitch) + const ptrdiff_t dst_pitch) { int x, y, indx, b0, b1, b2, b3, p0, p1, p2, p3; const short *b0_ptr, *b1_ptr, *b2_ptr, *b3_ptr; - int32_t pitch; + ptrdiff_t pitch; /* all bands should have the same pitch */ pitch = plane->bands[0].pitch; @@ -257,7 +257,7 @@ void ff_ivi_recompose_haar(const IVIPlaneDesc *plane, uint8_t *dst, d3 = COMPENSATE(t2);\ d4 = COMPENSATE(t3); } -void ff_ivi_inverse_haar_8x8(const int32_t *in, int16_t *out, uint32_t pitch, +void ff_ivi_inverse_haar_8x8(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags) { int i, shift, sp1, sp2, sp3, sp4; @@ -312,7 +312,7 @@ void ff_ivi_inverse_haar_8x8(const int32_t *in, int16_t *out, uint32_t pitch, #undef COMPENSATE } -void ff_ivi_row_haar8(const int32_t *in, int16_t *out, uint32_t pitch, +void ff_ivi_row_haar8(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags) { int i; @@ -337,7 +337,7 @@ void ff_ivi_row_haar8(const int32_t *in, int16_t *out, uint32_t pitch, #undef COMPENSATE } -void ff_ivi_col_haar8(const int32_t *in, int16_t *out, uint32_t pitch, +void ff_ivi_col_haar8(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags) { int i; @@ -366,7 +366,7 @@ void ff_ivi_col_haar8(const int32_t *in, int16_t *out, uint32_t pitch, #undef COMPENSATE } -void ff_ivi_inverse_haar_4x4(const int32_t *in, int16_t *out, uint32_t pitch, +void ff_ivi_inverse_haar_4x4(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags) { int i, shift, sp1, sp2; @@ -413,7 +413,7 @@ void ff_ivi_inverse_haar_4x4(const int32_t *in, int16_t *out, uint32_t pitch, #undef COMPENSATE } -void ff_ivi_row_haar4(const int32_t *in, int16_t *out, uint32_t pitch, +void ff_ivi_row_haar4(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags) { int i; @@ -435,7 +435,7 @@ void ff_ivi_row_haar4(const int32_t *in, int16_t *out, uint32_t pitch, #undef COMPENSATE } -void ff_ivi_col_haar4(const int32_t *in, int16_t *out, uint32_t pitch, +void ff_ivi_col_haar4(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags) { int i; @@ -459,7 +459,7 @@ void ff_ivi_col_haar4(const int32_t *in, int16_t *out, uint32_t pitch, #undef COMPENSATE } -void ff_ivi_dc_haar_2d(const int32_t *in, int16_t *out, uint32_t pitch, +void ff_ivi_dc_haar_2d(const int32_t *in, int16_t *out, ptrdiff_t pitch, int blk_size) { int x, y; @@ -523,7 +523,7 @@ void ff_ivi_dc_haar_2d(const int32_t *in, int16_t *out, uint32_t pitch, d3 = COMPENSATE(t3);\ d4 = COMPENSATE(t4);} -void ff_ivi_inverse_slant_8x8(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags) +void ff_ivi_inverse_slant_8x8(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags) { int i; const int32_t *src; @@ -563,7 +563,7 @@ void ff_ivi_inverse_slant_8x8(const int32_t *in, int16_t *out, uint32_t pitch, c #undef COMPENSATE } -void ff_ivi_inverse_slant_4x4(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags) +void ff_ivi_inverse_slant_4x4(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags) { int i; const int32_t *src; @@ -603,7 +603,7 @@ void ff_ivi_inverse_slant_4x4(const int32_t *in, int16_t *out, uint32_t pitch, c #undef COMPENSATE } -void ff_ivi_dc_slant_2d(const int32_t *in, int16_t *out, uint32_t pitch, int blk_size) +void ff_ivi_dc_slant_2d(const int32_t *in, int16_t *out, ptrdiff_t pitch, int blk_size) { int x, y; int16_t dc_coeff; @@ -616,7 +616,7 @@ void ff_ivi_dc_slant_2d(const int32_t *in, int16_t *out, uint32_t pitch, int blk } } -void ff_ivi_row_slant8(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags) +void ff_ivi_row_slant8(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags) { int i; int t0, t1, t2, t3, t4, t5, t6, t7, t8; @@ -636,7 +636,7 @@ void ff_ivi_row_slant8(const int32_t *in, int16_t *out, uint32_t pitch, const ui #undef COMPENSATE } -void ff_ivi_dc_row_slant(const int32_t *in, int16_t *out, uint32_t pitch, int blk_size) +void ff_ivi_dc_row_slant(const int32_t *in, int16_t *out, ptrdiff_t pitch, int blk_size) { int x, y; int16_t dc_coeff; @@ -654,7 +654,7 @@ void ff_ivi_dc_row_slant(const int32_t *in, int16_t *out, uint32_t pitch, int bl } } -void ff_ivi_col_slant8(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags) +void ff_ivi_col_slant8(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags) { int i, row2, row4, row8; int t0, t1, t2, t3, t4, t5, t6, t7, t8; @@ -681,7 +681,7 @@ void ff_ivi_col_slant8(const int32_t *in, int16_t *out, uint32_t pitch, const ui #undef COMPENSATE } -void ff_ivi_dc_col_slant(const int32_t *in, int16_t *out, uint32_t pitch, int blk_size) +void ff_ivi_dc_col_slant(const int32_t *in, int16_t *out, ptrdiff_t pitch, int blk_size) { int x, y; int16_t dc_coeff; @@ -695,7 +695,7 @@ void ff_ivi_dc_col_slant(const int32_t *in, int16_t *out, uint32_t pitch, int bl } } -void ff_ivi_row_slant4(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags) +void ff_ivi_row_slant4(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags) { int i; int t0, t1, t2, t3, t4; @@ -715,7 +715,7 @@ void ff_ivi_row_slant4(const int32_t *in, int16_t *out, uint32_t pitch, const ui #undef COMPENSATE } -void ff_ivi_col_slant4(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags) +void ff_ivi_col_slant4(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags) { int i, row2; int t0, t1, t2, t3, t4; @@ -738,7 +738,7 @@ void ff_ivi_col_slant4(const int32_t *in, int16_t *out, uint32_t pitch, const ui #undef COMPENSATE } -void ff_ivi_put_pixels_8x8(const int32_t *in, int16_t *out, uint32_t pitch, +void ff_ivi_put_pixels_8x8(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags) { int x, y; @@ -748,7 +748,7 @@ void ff_ivi_put_pixels_8x8(const int32_t *in, int16_t *out, uint32_t pitch, out[x] = in[x]; } -void ff_ivi_put_dc_pixel_8x8(const int32_t *in, int16_t *out, uint32_t pitch, +void ff_ivi_put_dc_pixel_8x8(const int32_t *in, int16_t *out, ptrdiff_t pitch, int blk_size) { int y; @@ -763,9 +763,9 @@ void ff_ivi_put_dc_pixel_8x8(const int32_t *in, int16_t *out, uint32_t pitch, #define IVI_MC_TEMPLATE(size, suffix, OP) \ static void ivi_mc_ ## size ##x## size ## suffix(int16_t *buf, \ - uint32_t dpitch, \ + ptrdiff_t dpitch, \ const int16_t *ref_buf, \ - uint32_t pitch, int mc_type) \ + ptrdiff_t pitch, int mc_type) \ { \ int i, j; \ const int16_t *wptr; \ @@ -799,7 +799,7 @@ static void ivi_mc_ ## size ##x## size ## suffix(int16_t *buf, \ } \ \ void ff_ivi_mc_ ## size ##x## size ## suffix(int16_t *buf, const int16_t *ref_buf, \ - uint32_t pitch, int mc_type) \ + ptrdiff_t pitch, int mc_type) \ { \ ivi_mc_ ## size ##x## size ## suffix(buf, pitch, ref_buf, pitch, mc_type); \ } \ @@ -808,7 +808,7 @@ void ff_ivi_mc_ ## size ##x## size ## suffix(int16_t *buf, const int16_t *ref_bu void ff_ivi_mc_avg_ ## size ##x## size ## suffix(int16_t *buf, \ const int16_t *ref_buf, \ const int16_t *ref_buf2, \ - uint32_t pitch, \ + ptrdiff_t pitch, \ int mc_type, int mc_type2) \ { \ int16_t tmp[size * size]; \ diff --git a/libavcodec/ivi_dsp.h b/libavcodec/ivi_dsp.h index ac9dcbcab61ef..d9d3d17f610ac 100644 --- a/libavcodec/ivi_dsp.h +++ b/libavcodec/ivi_dsp.h @@ -29,6 +29,7 @@ #ifndef AVCODEC_IVI_DSP_H #define AVCODEC_IVI_DSP_H +#include #include #include "ivi.h" @@ -41,7 +42,7 @@ * @param[in] dst_pitch pitch of the destination buffer */ void ff_ivi_recompose53(const IVIPlaneDesc *plane, uint8_t *dst, - const int dst_pitch); + const ptrdiff_t dst_pitch); /** * Haar wavelet recomposition filter for Indeo 4 @@ -51,7 +52,7 @@ void ff_ivi_recompose53(const IVIPlaneDesc *plane, uint8_t *dst, * @param[in] dst_pitch pitch of the destination buffer */ void ff_ivi_recompose_haar(const IVIPlaneDesc *plane, uint8_t *dst, - const int dst_pitch); + const ptrdiff_t dst_pitch); /** * two-dimensional inverse Haar 8x8 transform for Indeo 4 @@ -63,7 +64,7 @@ void ff_ivi_recompose_haar(const IVIPlaneDesc *plane, uint8_t *dst, * != 0 - non_empty column, 0 - empty one * (this array must be filled by caller) */ -void ff_ivi_inverse_haar_8x8(const int32_t *in, int16_t *out, uint32_t pitch, +void ff_ivi_inverse_haar_8x8(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags); /** @@ -76,7 +77,7 @@ void ff_ivi_inverse_haar_8x8(const int32_t *in, int16_t *out, uint32_t pitch, * != 0 - non_empty column, 0 - empty one * (this array must be filled by caller) */ -void ff_ivi_row_haar8(const int32_t *in, int16_t *out, uint32_t pitch, +void ff_ivi_row_haar8(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags); /** @@ -89,7 +90,7 @@ void ff_ivi_row_haar8(const int32_t *in, int16_t *out, uint32_t pitch, * != 0 - non_empty column, 0 - empty one * (this array must be filled by caller) */ -void ff_ivi_col_haar8(const int32_t *in, int16_t *out, uint32_t pitch, +void ff_ivi_col_haar8(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags); /** @@ -102,7 +103,7 @@ void ff_ivi_col_haar8(const int32_t *in, int16_t *out, uint32_t pitch, * != 0 - non_empty column, 0 - empty one * (this array must be filled by caller) */ -void ff_ivi_inverse_haar_4x4(const int32_t *in, int16_t *out, uint32_t pitch, +void ff_ivi_inverse_haar_4x4(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags); /** @@ -115,7 +116,7 @@ void ff_ivi_inverse_haar_4x4(const int32_t *in, int16_t *out, uint32_t pitch, * != 0 - non_empty column, 0 - empty one * (this array must be filled by caller) */ -void ff_ivi_row_haar4(const int32_t *in, int16_t *out, uint32_t pitch, +void ff_ivi_row_haar4(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags); /** @@ -128,7 +129,7 @@ void ff_ivi_row_haar4(const int32_t *in, int16_t *out, uint32_t pitch, * != 0 - non_empty column, 0 - empty one * (this array must be filled by caller) */ -void ff_ivi_col_haar4(const int32_t *in, int16_t *out, uint32_t pitch, +void ff_ivi_col_haar4(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags); /** @@ -141,7 +142,7 @@ void ff_ivi_col_haar4(const int32_t *in, int16_t *out, uint32_t pitch, * @param[in] pitch pitch to move to the next y line * @param[in] blk_size transform block size */ -void ff_ivi_dc_haar_2d(const int32_t *in, int16_t *out, uint32_t pitch, +void ff_ivi_dc_haar_2d(const int32_t *in, int16_t *out, ptrdiff_t pitch, int blk_size); /** @@ -154,7 +155,7 @@ void ff_ivi_dc_haar_2d(const int32_t *in, int16_t *out, uint32_t pitch, * != 0 - non_empty column, 0 - empty one * (this array must be filled by caller) */ -void ff_ivi_inverse_slant_8x8(const int32_t *in, int16_t *out, uint32_t pitch, +void ff_ivi_inverse_slant_8x8(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags); /** @@ -167,7 +168,7 @@ void ff_ivi_inverse_slant_8x8(const int32_t *in, int16_t *out, uint32_t pitch, * != 0 - non_empty column, 0 - empty one * (this array must be filled by caller) */ -void ff_ivi_inverse_slant_4x4(const int32_t *in, int16_t *out, uint32_t pitch, +void ff_ivi_inverse_slant_4x4(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags); /** @@ -181,7 +182,7 @@ void ff_ivi_inverse_slant_4x4(const int32_t *in, int16_t *out, uint32_t pitch, * @param[in] pitch pitch to move to the next y line * @param[in] blk_size transform block size */ -void ff_ivi_dc_slant_2d(const int32_t *in, int16_t *out, uint32_t pitch, int blk_size); +void ff_ivi_dc_slant_2d(const int32_t *in, int16_t *out, ptrdiff_t pitch, int blk_size); /** * inverse 1D row slant transform @@ -191,7 +192,7 @@ void ff_ivi_dc_slant_2d(const int32_t *in, int16_t *out, uint32_t pitch, int blk * @param[in] pitch pitch to move to the next y line * @param[in] flags pointer to the array of column flags (unused here) */ -void ff_ivi_row_slant8(const int32_t *in, int16_t *out, uint32_t pitch, +void ff_ivi_row_slant8(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags); /** @@ -204,7 +205,7 @@ void ff_ivi_row_slant8(const int32_t *in, int16_t *out, uint32_t pitch, * != 0 - non_empty column, 0 - empty one * (this array must be filled by caller) */ -void ff_ivi_col_slant8(const int32_t *in, int16_t *out, uint32_t pitch, +void ff_ivi_col_slant8(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags); /** @@ -215,7 +216,7 @@ void ff_ivi_col_slant8(const int32_t *in, int16_t *out, uint32_t pitch, * @param[in] pitch pitch to move to the next y line * @param[in] flags pointer to the array of column flags (unused here) */ -void ff_ivi_row_slant4(const int32_t *in, int16_t *out, uint32_t pitch, +void ff_ivi_row_slant4(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags); /** @@ -228,29 +229,29 @@ void ff_ivi_row_slant4(const int32_t *in, int16_t *out, uint32_t pitch, * != 0 - non_empty column, 0 - empty one * (this array must be filled by caller) */ -void ff_ivi_col_slant4(const int32_t *in, int16_t *out, uint32_t pitch, +void ff_ivi_col_slant4(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags); /** * DC-only inverse row slant transform */ -void ff_ivi_dc_row_slant(const int32_t *in, int16_t *out, uint32_t pitch, int blk_size); +void ff_ivi_dc_row_slant(const int32_t *in, int16_t *out, ptrdiff_t pitch, int blk_size); /** * DC-only inverse column slant transform */ -void ff_ivi_dc_col_slant(const int32_t *in, int16_t *out, uint32_t pitch, int blk_size); +void ff_ivi_dc_col_slant(const int32_t *in, int16_t *out, ptrdiff_t pitch, int blk_size); /** * Copy the pixels into the frame buffer. */ -void ff_ivi_put_pixels_8x8(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags); +void ff_ivi_put_pixels_8x8(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags); /** * Copy the DC coefficient into the first pixel of the block and * zero all others. */ -void ff_ivi_put_dc_pixel_8x8(const int32_t *in, int16_t *out, uint32_t pitch, int blk_size); +void ff_ivi_put_dc_pixel_8x8(const int32_t *in, int16_t *out, ptrdiff_t pitch, int blk_size); /** * 8x8 block motion compensation with adding delta @@ -260,7 +261,7 @@ void ff_ivi_put_dc_pixel_8x8(const int32_t *in, int16_t *out, uint32_t pitch, in * @param[in] pitch pitch for moving to the next y line * @param[in] mc_type interpolation type */ -void ff_ivi_mc_8x8_delta(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); +void ff_ivi_mc_8x8_delta(int16_t *buf, const int16_t *ref_buf, ptrdiff_t pitch, int mc_type); /** * 4x4 block motion compensation with adding delta @@ -270,7 +271,7 @@ void ff_ivi_mc_8x8_delta(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, i * @param[in] pitch pitch for moving to the next y line * @param[in] mc_type interpolation type */ -void ff_ivi_mc_4x4_delta(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); +void ff_ivi_mc_4x4_delta(int16_t *buf, const int16_t *ref_buf, ptrdiff_t pitch, int mc_type); /** * motion compensation without adding delta @@ -280,7 +281,7 @@ void ff_ivi_mc_4x4_delta(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, i * @param[in] pitch pitch for moving to the next y line * @param[in] mc_type interpolation type */ -void ff_ivi_mc_8x8_no_delta(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); +void ff_ivi_mc_8x8_no_delta(int16_t *buf, const int16_t *ref_buf, ptrdiff_t pitch, int mc_type); /** * 4x4 block motion compensation without adding delta @@ -290,7 +291,7 @@ void ff_ivi_mc_8x8_no_delta(int16_t *buf, const int16_t *ref_buf, uint32_t pitch * @param[in] pitch pitch for moving to the next y line * @param[in] mc_type interpolation type */ -void ff_ivi_mc_4x4_no_delta(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); +void ff_ivi_mc_4x4_no_delta(int16_t *buf, const int16_t *ref_buf, ptrdiff_t pitch, int mc_type); /** * 8x8 block motion compensation with adding delta @@ -302,7 +303,7 @@ void ff_ivi_mc_4x4_no_delta(int16_t *buf, const int16_t *ref_buf, uint32_t pitch * @param[in] mc_type interpolation type for backward reference * @param[in] mc_type2 interpolation type for forward reference */ -void ff_ivi_mc_avg_8x8_delta(int16_t *buf, const int16_t *ref_buf, const int16_t *ref_buf2, uint32_t pitch, int mc_type, int mc_type2); +void ff_ivi_mc_avg_8x8_delta(int16_t *buf, const int16_t *ref_buf, const int16_t *ref_buf2, ptrdiff_t pitch, int mc_type, int mc_type2); /** * 4x4 block motion compensation with adding delta @@ -314,7 +315,7 @@ void ff_ivi_mc_avg_8x8_delta(int16_t *buf, const int16_t *ref_buf, const int16_t * @param[in] mc_type interpolation type for backward reference * @param[in] mc_type2 interpolation type for forward reference */ -void ff_ivi_mc_avg_4x4_delta(int16_t *buf, const int16_t *ref_buf, const int16_t *ref_buf2, uint32_t pitch, int mc_type, int mc_type2); +void ff_ivi_mc_avg_4x4_delta(int16_t *buf, const int16_t *ref_buf, const int16_t *ref_buf2, ptrdiff_t pitch, int mc_type, int mc_type2); /** * motion compensation without adding delta for B-frames @@ -326,7 +327,7 @@ void ff_ivi_mc_avg_4x4_delta(int16_t *buf, const int16_t *ref_buf, const int16_t * @param[in] mc_type interpolation type for backward reference * @param[in] mc_type2 interpolation type for forward reference */ -void ff_ivi_mc_avg_8x8_no_delta(int16_t *buf, const int16_t *ref_buf, const int16_t *ref_buf2, uint32_t pitch, int mc_type, int mc_type2); +void ff_ivi_mc_avg_8x8_no_delta(int16_t *buf, const int16_t *ref_buf, const int16_t *ref_buf2, ptrdiff_t pitch, int mc_type, int mc_type2); /** * 4x4 block motion compensation without adding delta for B-frames @@ -338,6 +339,6 @@ void ff_ivi_mc_avg_8x8_no_delta(int16_t *buf, const int16_t *ref_buf, const int1 * @param[in] mc_type interpolation type for backward reference * @param[in] mc_type2 interpolation type for forward reference */ -void ff_ivi_mc_avg_4x4_no_delta(int16_t *buf, const int16_t *ref_buf, const int16_t *ref_buf2, uint32_t pitch, int mc_type, int mc_type2); +void ff_ivi_mc_avg_4x4_no_delta(int16_t *buf, const int16_t *ref_buf, const int16_t *ref_buf2, ptrdiff_t pitch, int mc_type, int mc_type2); #endif /* AVCODEC_IVI_DSP_H */ From 21e500ba647aec233d5930d3d1081489d0d53ceb Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 26 Aug 2016 12:44:16 +0200 Subject: [PATCH 0135/3374] svq1dec: Change type of array pitch parameters to ptrdiff_t ptrdiff_t is the correct type for array pitches and similar. --- libavcodec/svq1dec.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c index d6f4b43539b72..cc43f1491c177 100644 --- a/libavcodec/svq1dec.c +++ b/libavcodec/svq1dec.c @@ -155,7 +155,7 @@ static const uint8_t string_table[256] = { n4 = mean + (mean >> 31) << 16 | (mean & 0xFFFF); static int svq1_decode_block_intra(GetBitContext *bitbuf, uint8_t *pixels, - int pitch) + ptrdiff_t pitch) { uint32_t bit_cache; uint8_t *list[63]; @@ -220,7 +220,7 @@ static int svq1_decode_block_intra(GetBitContext *bitbuf, uint8_t *pixels, } static int svq1_decode_block_non_intra(GetBitContext *bitbuf, uint8_t *pixels, - int pitch) + ptrdiff_t pitch) { uint32_t bit_cache; uint8_t *list[63]; @@ -304,7 +304,7 @@ static int svq1_decode_motion_vector(GetBitContext *bitbuf, svq1_pmv *mv, } static void svq1_skip_block(uint8_t *current, uint8_t *previous, - int pitch, int x, int y) + ptrdiff_t pitch, int x, int y) { uint8_t *src; uint8_t *dst; @@ -322,7 +322,7 @@ static void svq1_skip_block(uint8_t *current, uint8_t *previous, static int svq1_motion_inter_block(HpelDSPContext *hdsp, GetBitContext *bitbuf, uint8_t *current, uint8_t *previous, - int pitch, svq1_pmv *motion, int x, int y, + ptrdiff_t pitch, svq1_pmv *motion, int x, int y, int width, int height) { uint8_t *src; @@ -366,7 +366,7 @@ static int svq1_motion_inter_block(HpelDSPContext *hdsp, GetBitContext *bitbuf, static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbuf, uint8_t *current, uint8_t *previous, - int pitch, svq1_pmv *motion, int x, int y, + ptrdiff_t pitch, svq1_pmv *motion, int x, int y, int width, int height) { uint8_t *src; @@ -448,7 +448,7 @@ static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbu static int svq1_decode_delta_block(AVCodecContext *avctx, HpelDSPContext *hdsp, GetBitContext *bitbuf, uint8_t *current, uint8_t *previous, - int pitch, svq1_pmv *motion, int x, int y, + ptrdiff_t pitch, svq1_pmv *motion, int x, int y, int width, int height) { uint32_t block_type; From 73f5e17a203713c4ac4e5a821809823b383b195f Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 26 Aug 2016 12:38:33 +0200 Subject: [PATCH 0136/3374] copy_block: Change type of array stride parameters to ptrdiff_t ptrdiff_t is the correct type for array strides and similar. --- libavcodec/copy_block.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libavcodec/copy_block.h b/libavcodec/copy_block.h index 10718ccfda7eb..0b6962238522f 100644 --- a/libavcodec/copy_block.h +++ b/libavcodec/copy_block.h @@ -19,11 +19,12 @@ #ifndef AVCODEC_COPY_BLOCK_H #define AVCODEC_COPY_BLOCK_H +#include #include #include "libavutil/intreadwrite.h" -static inline void copy_block4(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h) +static inline void copy_block4(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride, int h) { int i; for (i = 0; i < h; i++) { @@ -33,7 +34,7 @@ static inline void copy_block4(uint8_t *dst, const uint8_t *src, int dstStride, } } -static inline void copy_block8(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h) +static inline void copy_block8(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride, int h) { int i; for (i = 0; i < h; i++) { @@ -43,7 +44,7 @@ static inline void copy_block8(uint8_t *dst, const uint8_t *src, int dstStride, } } -static inline void copy_block9(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h) +static inline void copy_block9(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride, int h) { int i; for (i = 0; i < h; i++) { @@ -54,7 +55,7 @@ static inline void copy_block9(uint8_t *dst, const uint8_t *src, int dstStride, } } -static inline void copy_block16(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h) +static inline void copy_block16(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride, int h) { int i; for (i = 0; i < h; i++) { @@ -64,7 +65,7 @@ static inline void copy_block16(uint8_t *dst, const uint8_t *src, int dstStride, } } -static inline void copy_block17(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h) +static inline void copy_block17(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride, int h) { int i; for (i = 0; i < h; i++) { From 5b5ed92d92252a685e891a5d636870e223b63228 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 26 Aug 2016 12:44:37 +0200 Subject: [PATCH 0137/3374] sanm: Change type of array pitch parameters to ptrdiff_t ptrdiff_t is the correct type for array pitches and similar. --- libavcodec/sanm.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c index 6436f84895d75..3d231957aed84 100644 --- a/libavcodec/sanm.c +++ b/libavcodec/sanm.c @@ -217,7 +217,7 @@ typedef struct SANMVideoContext { uint32_t pal[PALETTE_SIZE]; int16_t delta_pal[PALETTE_DELTA]; - int pitch; + ptrdiff_t pitch; int width, height; int aligned_width, aligned_height; int prev_seq; @@ -571,7 +571,7 @@ static inline void codec37_mv(uint8_t *dst, const uint8_t *src, static int old_codec37(SANMVideoContext *ctx, int top, int left, int width, int height) { - int stride = ctx->pitch; + ptrdiff_t stride = ctx->pitch; int i, j, k, t; uint8_t *dst, *prev; int skip_run = 0; @@ -809,7 +809,7 @@ static int old_codec47(SANMVideoContext *ctx, int top, { uint32_t decoded_size; int i, j; - int stride = ctx->pitch; + ptrdiff_t stride = ctx->pitch; uint8_t *dst = (uint8_t *)ctx->frm0 + left + top * stride; uint8_t *prev1 = (uint8_t *)ctx->frm1; uint8_t *prev2 = (uint8_t *)ctx->frm2; @@ -962,11 +962,11 @@ static int decode_nop(SANMVideoContext *ctx) return AVERROR_PATCHWELCOME; } -static void copy_block(uint16_t *pdest, uint16_t *psrc, int block_size, int pitch) +static void copy_block(uint16_t *pdest, uint16_t *psrc, int block_size, ptrdiff_t pitch) { uint8_t *dst = (uint8_t *)pdest; uint8_t *src = (uint8_t *)psrc; - int stride = pitch * 2; + ptrdiff_t stride = pitch * 2; switch (block_size) { case 2: @@ -981,7 +981,7 @@ static void copy_block(uint16_t *pdest, uint16_t *psrc, int block_size, int pitc } } -static void fill_block(uint16_t *pdest, uint16_t color, int block_size, int pitch) +static void fill_block(uint16_t *pdest, uint16_t color, int block_size, ptrdiff_t pitch) { int x, y; @@ -993,7 +993,7 @@ static void fill_block(uint16_t *pdest, uint16_t color, int block_size, int pitc static int draw_glyph(SANMVideoContext *ctx, uint16_t *dst, int index, uint16_t fg_color, uint16_t bg_color, int block_size, - int pitch) + ptrdiff_t pitch) { int8_t *pglyph; uint16_t colors[2] = { fg_color, bg_color }; @@ -1013,7 +1013,7 @@ static int draw_glyph(SANMVideoContext *ctx, uint16_t *dst, int index, return 0; } -static int opcode_0xf7(SANMVideoContext *ctx, int cx, int cy, int block_size, int pitch) +static int opcode_0xf7(SANMVideoContext *ctx, int cx, int cy, int block_size, ptrdiff_t pitch) { uint16_t *dst = ctx->frm0 + cx + cy * ctx->pitch; @@ -1047,7 +1047,7 @@ static int opcode_0xf7(SANMVideoContext *ctx, int cx, int cy, int block_size, in return 0; } -static int opcode_0xf8(SANMVideoContext *ctx, int cx, int cy, int block_size, int pitch) +static int opcode_0xf8(SANMVideoContext *ctx, int cx, int cy, int block_size, ptrdiff_t pitch) { uint16_t *dst = ctx->frm0 + cx + cy * ctx->pitch; @@ -1317,8 +1317,8 @@ static int copy_output(SANMVideoContext *ctx, SANMFrameHeader *hdr) { uint8_t *dst; const uint8_t *src = (uint8_t*) ctx->frm0; - int ret, dstpitch, height = ctx->height; - int srcpitch = ctx->pitch * (hdr ? sizeof(ctx->frm0[0]) : 1); + int ret, height = ctx->height; + ptrdiff_t dstpitch, srcpitch = ctx->pitch * (hdr ? sizeof(ctx->frm0[0]) : 1); if ((ret = ff_get_buffer(ctx->avctx, ctx->frame, 0)) < 0) return ret; From 2610c9528f86286e4c6e174411a26ff5b4815cde Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 17 Mar 2015 13:12:41 +0100 Subject: [PATCH 0138/3374] configure: Move initial VAAPI check to a more sensible place --- configure | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 80f39f378031a..86aa0174235f1 100755 --- a/configure +++ b/configure @@ -4579,7 +4579,6 @@ disabled zlib || check_lib zlib.h zlibVersion -lz || disable zlib disabled bzlib || check_lib2 bzlib.h BZ2_bzlibVersion -lbz2 || disable bzlib check_lib math.h sin -lm && LIBM="-lm" -enabled vaapi && require vaapi va/va.h vaInitialize -lva atan2f_args=2 ldexpf_args=2 @@ -4775,6 +4774,8 @@ if enabled libxcb; then add_extralibs "$xcb_event_libs $xcb_shm_libs $xcb_xfixes_libs" fi +enabled vaapi && require vaapi va/va.h vaInitialize -lva + enabled vaapi && check_code cc "va/va.h" "vaCreateSurfaces(0, 0, 0, 0, 0, 0, 0, 0)" || disable vaapi From b8c2d407efa41c3db6813ad67fadd51b814765bd Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 10 Apr 2015 19:29:25 +0200 Subject: [PATCH 0139/3374] configure: Simplify libopenjpeg check --- configure | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 86aa0174235f1..3229153365b93 100755 --- a/configure +++ b/configure @@ -4614,8 +4614,8 @@ enabled libopencore_amrnb && require libopencore_amrnb opencore-amrnb/interf_dec enabled libopencore_amrwb && require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb enabled libopencv && require_pkg_config opencv opencv/cv.h cvCreateImageHeader enabled libopenh264 && require_pkg_config openh264 wels/codec_api.h WelsGetCodecVersion -enabled libopenjpeg && { { check_header openjpeg.h && check_lib2 openjpeg.h opj_version -lopenjpeg -DOPJ_STATIC; } || - { require_pkg_config libopenjpeg1 openjpeg.h opj_version -DOPJ_STATIC; } } +enabled libopenjpeg && { check_lib2 openjpeg.h opj_version -lopenjpeg -DOPJ_STATIC || + require_pkg_config libopenjpeg1 openjpeg.h opj_version -DOPJ_STATIC; } enabled libopus && require_pkg_config opus opus_multistream.h opus_multistream_decoder_create enabled libpulse && require_pkg_config libpulse-simple pulse/simple.h pa_simple_new enabled librtmp && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket From 0e5dde739943168d6f61d3fb40b3f622e7abfeff Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 14 Apr 2015 13:27:32 +0200 Subject: [PATCH 0140/3374] configure: Fix --disable-pod2man / --disable-texi2html --- configure | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 3229153365b93..ea2b131a348f8 100755 --- a/configure +++ b/configure @@ -113,6 +113,8 @@ Program options: Component options: --disable-doc do not build documentation + --disable-pod2man do not build manual pages + --disable-texi2html do not build HTML documentation --disable-avdevice disable libavdevice build --disable-avcodec disable libavcodec build --disable-avformat disable libavformat build @@ -4707,8 +4709,8 @@ if check_pkg_config sdl SDL_events.h SDL_PollEvent; then enable sdl fi -pod2man --help > /dev/null 2>&1 && enable pod2man || disable pod2man -texi2html -version > /dev/null 2>&1 && enable texi2html || disable texi2html +! disabled pod2man && check_cmd pod2man --help && enable pod2man || disable pod2man +! disabled texi2html && check_cmd texi2html -version && enable texi2html || disable texi2html check_header linux/fb.h check_header linux/videodev2.h From 3aa9d37d03da3c9b482d19b3988659287815280e Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 5 Sep 2016 13:12:24 +0200 Subject: [PATCH 0141/3374] build: Fix directory dependencies of tests/pixfmts.mak target --- tests/fate/filter-video.mak | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak index d9315480e422c..82d0a62dbd81b 100644 --- a/tests/fate/filter-video.mak +++ b/tests/fate/filter-video.mak @@ -117,7 +117,7 @@ fate-filter-vflip_vflip: CMD = video_filter "vflip,vflip" tests/pixfmts.mak: TAG = GEN -tests/pixfmts.mak: avconv$(EXESUF) +tests/pixfmts.mak: avconv$(EXESUF) | tests $(M)printf "PIXFMTS = " > $@ $(Q)$(TARGET_EXEC) $(TARGET_PATH)/$< -pix_fmts list 2> /dev/null | awk 'NR > 8 && /^IO/ { printf $$2 " " }' >> $@ $(Q)printf "\n" >> $@ From ec903058447ad5be34d89533962e9ae1aa1c78f7 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 5 Sep 2016 13:13:50 +0200 Subject: [PATCH 0142/3374] configure: Simplify clock_gettime() test --- configure | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure b/configure index ea2b131a348f8..7ad920f4be5b4 100755 --- a/configure +++ b/configure @@ -4472,7 +4472,8 @@ check_func ${malloc_prefix}memalign && enable memalign check_func ${malloc_prefix}posix_memalign && enable posix_memalign check_cpp_condition unistd.h "defined(_POSIX_MONOTONIC_CLOCK)" && - check_func_headers time.h clock_gettime || { check_func_headers time.h clock_gettime -lrt && add_extralibs -lrt && LIBRT="-lrt"; } + check_func_headers time.h clock_gettime || + { check_lib2 time.h clock_gettime -lrt && LIBRT="-lrt"; } check_func fcntl check_func fork From 6b52762951fa138eef59e2628dabb389e0500e40 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 1 Sep 2016 20:45:41 +0200 Subject: [PATCH 0143/3374] error_resilience: Change type of array stride parameters to ptrdiff_t ptrdiff_t is the correct type for array strides and similar. --- libavcodec/error_resilience.c | 21 ++++++++++++--------- libavcodec/error_resilience.h | 4 ++-- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c index d53dfdd99593f..bf3a6882c729d 100644 --- a/libavcodec/error_resilience.c +++ b/libavcodec/error_resilience.c @@ -41,7 +41,7 @@ * @param stride the number of MVs to get to the next row * @param mv_step the number of MVs per row or column in a macroblock */ -static void set_mv_strides(ERContext *s, int *mv_step, int *stride) +static void set_mv_strides(ERContext *s, ptrdiff_t *mv_step, ptrdiff_t *stride) { if (s->avctx->codec_id == AV_CODEC_ID_H264) { assert(s->quarter_sample); @@ -92,7 +92,7 @@ static void put_dc(ERContext *s, uint8_t *dest_y, uint8_t *dest_cb, } } -static void filter181(int16_t *data, int width, int height, int stride) +static void filter181(int16_t *data, int width, int height, ptrdiff_t stride) { int x, y; @@ -134,7 +134,7 @@ static void filter181(int16_t *data, int width, int height, int stride) * @param h height in 8 pixel blocks */ static void guess_dc(ERContext *s, int16_t *dc, int w, - int h, int stride, int is_luma) + int h, ptrdiff_t stride, int is_luma) { int b_x, b_y; @@ -220,9 +220,10 @@ static void guess_dc(ERContext *s, int16_t *dc, int w, * @param h height in 8 pixel blocks */ static void h_block_filter(ERContext *s, uint8_t *dst, int w, - int h, int stride, int is_luma) + int h, ptrdiff_t stride, int is_luma) { - int b_x, b_y, mvx_stride, mvy_stride; + int b_x, b_y; + ptrdiff_t mvx_stride, mvy_stride; const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP; set_mv_strides(s, &mvx_stride, &mvy_stride); mvx_stride >>= is_luma; @@ -288,9 +289,10 @@ static void h_block_filter(ERContext *s, uint8_t *dst, int w, * @param h height in 8 pixel blocks */ static void v_block_filter(ERContext *s, uint8_t *dst, int w, int h, - int stride, int is_luma) + ptrdiff_t stride, int is_luma) { - int b_x, b_y, mvx_stride, mvy_stride; + int b_x, b_y; + ptrdiff_t mvx_stride, mvy_stride; const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP; set_mv_strides(s, &mvx_stride, &mvy_stride); mvx_stride >>= is_luma; @@ -359,11 +361,12 @@ static void guess_mv(ERContext *s) #define MV_FROZEN 3 #define MV_CHANGED 2 #define MV_UNCHANGED 1 - const int mb_stride = s->mb_stride; + const ptrdiff_t mb_stride = s->mb_stride; const int mb_width = s->mb_width; const int mb_height = s->mb_height; int i, depth, num_avail; - int mb_x, mb_y, mot_step, mot_stride; + int mb_x, mb_y; + ptrdiff_t mot_step, mot_stride; set_mv_strides(s, &mot_step, &mot_stride); diff --git a/libavcodec/error_resilience.h b/libavcodec/error_resilience.h index 3139880362ea8..10456525fde1f 100644 --- a/libavcodec/error_resilience.h +++ b/libavcodec/error_resilience.h @@ -57,8 +57,8 @@ typedef struct ERContext { int *mb_index2xy; int mb_num; int mb_width, mb_height; - int mb_stride; - int b8_stride; + ptrdiff_t mb_stride; + ptrdiff_t b8_stride; int error_count, error_occurred; uint8_t *error_status_table; From 52730e0f867fe77b7d2353d8b44e92edb7079ca5 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 1 Sep 2016 20:48:10 +0200 Subject: [PATCH 0144/3374] iir_filter: Change type of array stride parameters to ptrdiff_t ptrdiff_t is the correct type for array strides and similar. --- libavcodec/iirfilter.c | 7 +++++-- libavcodec/iirfilter.h | 8 +++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/libavcodec/iirfilter.c b/libavcodec/iirfilter.c index 442c8373381fc..4116d5c5032ce 100644 --- a/libavcodec/iirfilter.c +++ b/libavcodec/iirfilter.c @@ -28,6 +28,7 @@ #include "libavutil/attributes.h" #include "libavutil/common.h" +#include "libavutil/log.h" #include "iirfilter.h" @@ -278,7 +279,8 @@ av_cold struct FFIIRFilterState *ff_iir_filter_init_state(int order) void ff_iir_filter(const struct FFIIRFilterCoeffs *c, struct FFIIRFilterState *s, int size, - const int16_t *src, int sstep, int16_t *dst, int dstep) + const int16_t *src, ptrdiff_t sstep, + int16_t *dst, ptrdiff_t dstep) { if (c->order == 2) { FILTER_O2(int16_t, S16) @@ -291,7 +293,8 @@ void ff_iir_filter(const struct FFIIRFilterCoeffs *c, void ff_iir_filter_flt(const struct FFIIRFilterCoeffs *c, struct FFIIRFilterState *s, int size, - const float *src, int sstep, float *dst, int dstep) + const float *src, ptrdiff_t sstep, + float *dst, ptrdiff_t dstep) { if (c->order == 2) { FILTER_O2(float, FLT) diff --git a/libavcodec/iirfilter.h b/libavcodec/iirfilter.h index bc65a96b59bd6..052a4b386d657 100644 --- a/libavcodec/iirfilter.h +++ b/libavcodec/iirfilter.h @@ -27,7 +27,8 @@ #ifndef AVCODEC_IIRFILTER_H #define AVCODEC_IIRFILTER_H -#include "avcodec.h" +#include +#include struct FFIIRFilterCoeffs; struct FFIIRFilterState; @@ -102,7 +103,7 @@ void ff_iir_filter_free_state(struct FFIIRFilterState *state); * @param dstep destination stride */ void ff_iir_filter(const struct FFIIRFilterCoeffs *coeffs, struct FFIIRFilterState *state, - int size, const int16_t *src, int sstep, int16_t *dst, int dstep); + int size, const int16_t *src, ptrdiff_t sstep, int16_t *dst, ptrdiff_t dstep); /** * Perform IIR filtering on floating-point input samples. @@ -117,6 +118,7 @@ void ff_iir_filter(const struct FFIIRFilterCoeffs *coeffs, struct FFIIRFilterSta */ void ff_iir_filter_flt(const struct FFIIRFilterCoeffs *coeffs, struct FFIIRFilterState *state, int size, - const float *src, int sstep, float *dst, int dstep); + const float *src, ptrdiff_t sstep, + float *dst, ptrdiff_t dstep); #endif /* AVCODEC_IIRFILTER_H */ From 131a85a1fed9966bbd38517f76abfac0237e39dc Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 1 Sep 2016 21:31:22 +0200 Subject: [PATCH 0145/3374] utvideo: Change type of array stride parameters to ptrdiff_t ptrdiff_t is the correct type for array strides and similar. --- libavcodec/utvideo.h | 2 +- libavcodec/utvideodec.c | 12 ++++++------ libavcodec/utvideoenc.c | 13 +++++++------ 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/libavcodec/utvideo.h b/libavcodec/utvideo.h index 0035e9c5cef11..c7f54145f114a 100644 --- a/libavcodec/utvideo.h +++ b/libavcodec/utvideo.h @@ -77,7 +77,7 @@ typedef struct UtvideoContext { int interlaced; int frame_pred; - int slice_stride; + ptrdiff_t slice_stride; uint8_t *slice_bits, *slice_buffer[4]; int slice_bits_size; } UtvideoContext; diff --git a/libavcodec/utvideodec.c b/libavcodec/utvideodec.c index 30ca4d216439d..3a581568dd2d8 100644 --- a/libavcodec/utvideodec.c +++ b/libavcodec/utvideodec.c @@ -78,7 +78,7 @@ static int build_huff(const uint8_t *src, VLC *vlc, int *fsym) } static int decode_plane(UtvideoContext *c, int plane_no, - uint8_t *dst, int step, int stride, + uint8_t *dst, int step, ptrdiff_t stride, int width, int height, const uint8_t *src, int use_pred) { @@ -182,8 +182,8 @@ static int decode_plane(UtvideoContext *c, int plane_no, return AVERROR_INVALIDDATA; } -static void restore_rgb_planes(uint8_t *src, int step, int stride, int width, - int height) +static void restore_rgb_planes(uint8_t *src, int step, ptrdiff_t stride, + int width, int height) { int i, j; uint8_t r, g, b; @@ -200,7 +200,7 @@ static void restore_rgb_planes(uint8_t *src, int step, int stride, int width, } } -static void restore_median(uint8_t *src, int step, int stride, +static void restore_median(uint8_t *src, int step, ptrdiff_t stride, int width, int height, int slices, int rmode) { int i, j, slice; @@ -256,7 +256,7 @@ static void restore_median(uint8_t *src, int step, int stride, * so restoring function should take care of possible padding between * two parts of the same "line". */ -static void restore_median_il(uint8_t *src, int step, int stride, +static void restore_median_il(uint8_t *src, int step, ptrdiff_t stride, int width, int height, int slices, int rmode) { int i, j, slice; @@ -264,7 +264,7 @@ static void restore_median_il(uint8_t *src, int step, int stride, uint8_t *bsrc; int slice_start, slice_height; const int cmask = ~(rmode ? 3 : 1); - const int stride2 = stride << 1; + const ptrdiff_t stride2 = stride << 1; for (slice = 0; slice < slices; slice++) { slice_start = ((slice * height) / slices) & cmask; diff --git a/libavcodec/utvideoenc.c b/libavcodec/utvideoenc.c index 4eddd98e24f2c..ef51ed06dd90b 100644 --- a/libavcodec/utvideoenc.c +++ b/libavcodec/utvideoenc.c @@ -234,8 +234,9 @@ FF_ENABLE_DEPRECATION_WARNINGS return 0; } -static void mangle_rgb_planes(uint8_t *dst[4], int dst_stride, uint8_t *src, - int step, int stride, int width, int height) +static void mangle_rgb_planes(uint8_t *dst[4], ptrdiff_t dst_stride, + uint8_t *src, int step, ptrdiff_t stride, + int width, int height) { int i, j; int k = 2 * dst_stride; @@ -268,7 +269,7 @@ static void mangle_rgb_planes(uint8_t *dst[4], int dst_stride, uint8_t *src, } /* Write data to a plane with left prediction */ -static void left_predict(uint8_t *src, uint8_t *dst, int stride, +static void left_predict(uint8_t *src, uint8_t *dst, ptrdiff_t stride, int width, int height) { int i, j; @@ -285,8 +286,8 @@ static void left_predict(uint8_t *src, uint8_t *dst, int stride, } /* Write data to a plane with median prediction */ -static void median_predict(UtvideoContext *c, uint8_t *src, uint8_t *dst, int stride, - int width, int height) +static void median_predict(UtvideoContext *c, uint8_t *src, uint8_t *dst, + ptrdiff_t stride, int width, int height) { int i, j; int A, B; @@ -387,7 +388,7 @@ static int write_huff_codes(uint8_t *src, uint8_t *dst, int dst_size, } static int encode_plane(AVCodecContext *avctx, uint8_t *src, - uint8_t *dst, int stride, + uint8_t *dst, ptrdiff_t stride, int width, int height, PutByteContext *pb) { UtvideoContext *c = avctx->priv_data; From 4e528206bc4d968706401206cf54471739250ec7 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 4 Sep 2016 13:26:37 +0100 Subject: [PATCH 0146/3374] vp8: Add hwaccel hooks Also adds some extra fields to the main context structure that may be needed by a hwaccel decoder. --- libavcodec/vp8.c | 185 ++++++++++++++++++++++++++++++++--------------- libavcodec/vp8.h | 32 ++++++++ 2 files changed, 157 insertions(+), 60 deletions(-) diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index 546124cdf245e..ced49799bcf00 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -64,16 +64,30 @@ static int vp8_alloc_frame(VP8Context *s, VP8Frame *f, int ref) if ((ret = ff_thread_get_buffer(s->avctx, &f->tf, ref ? AV_GET_BUFFER_FLAG_REF : 0)) < 0) return ret; - if (!(f->seg_map = av_buffer_allocz(s->mb_width * s->mb_height))) { - ff_thread_release_buffer(s->avctx, &f->tf); - return AVERROR(ENOMEM); + if (!(f->seg_map = av_buffer_allocz(s->mb_width * s->mb_height))) + goto fail; + if (s->avctx->hwaccel) { + const AVHWAccel *hwaccel = s->avctx->hwaccel; + if (hwaccel->frame_priv_data_size) { + f->hwaccel_priv_buf = av_buffer_allocz(hwaccel->frame_priv_data_size); + if (!f->hwaccel_priv_buf) + goto fail; + f->hwaccel_picture_private = f->hwaccel_priv_buf->data; + } } return 0; + +fail: + av_buffer_unref(&f->seg_map); + ff_thread_release_buffer(s->avctx, &f->tf); + return AVERROR(ENOMEM); } static void vp8_release_frame(VP8Context *s, VP8Frame *f) { av_buffer_unref(&f->seg_map); + av_buffer_unref(&f->hwaccel_priv_buf); + f->hwaccel_picture_private = NULL; ff_thread_release_buffer(s->avctx, &f->tf); } @@ -91,6 +105,12 @@ static int vp8_ref_frame(VP8Context *s, VP8Frame *dst, VP8Frame *src) vp8_release_frame(s, dst); return AVERROR(ENOMEM); } + if (src->hwaccel_picture_private) { + dst->hwaccel_priv_buf = av_buffer_ref(src->hwaccel_priv_buf); + if (!dst->hwaccel_priv_buf) + return AVERROR(ENOMEM); + dst->hwaccel_picture_private = dst->hwaccel_priv_buf->data; + } return 0; } @@ -132,7 +152,7 @@ static VP8Frame *vp8_find_free_buffer(VP8Context *s) av_log(s->avctx, AV_LOG_FATAL, "Ran out of free frames!\n"); abort(); } - if (frame->tf.f->data[0]) + if (frame->tf.f->buf[0]) vp8_release_frame(s, frame); return frame; @@ -209,8 +229,9 @@ static void parse_segment_info(VP8Context *s) int i; s->segmentation.update_map = vp8_rac_get(c); + s->segmentation.update_feature_data = vp8_rac_get(c); - if (vp8_rac_get(c)) { // update segment feature data + if (s->segmentation.update_feature_data) { s->segmentation.absolute_vals = vp8_rac_get(c); for (i = 0; i < 4; i++) @@ -264,11 +285,14 @@ static int setup_partitions(VP8Context *s, const uint8_t *buf, int buf_size) int size = AV_RL24(sizes + 3 * i); if (buf_size - size < 0) return -1; + s->coeff_partition_size[i] = size; ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, size); buf += size; buf_size -= size; } + + s->coeff_partition_size[i] = buf_size; ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, buf_size); return 0; @@ -298,28 +322,28 @@ static void get_quants(VP8Context *s) VP56RangeCoder *c = &s->c; int i, base_qi; - int yac_qi = vp8_rac_get_uint(c, 7); - int ydc_delta = vp8_rac_get_sint(c, 4); - int y2dc_delta = vp8_rac_get_sint(c, 4); - int y2ac_delta = vp8_rac_get_sint(c, 4); - int uvdc_delta = vp8_rac_get_sint(c, 4); - int uvac_delta = vp8_rac_get_sint(c, 4); + s->quant.yac_qi = vp8_rac_get_uint(c, 7); + s->quant.ydc_delta = vp8_rac_get_sint(c, 4); + s->quant.y2dc_delta = vp8_rac_get_sint(c, 4); + s->quant.y2ac_delta = vp8_rac_get_sint(c, 4); + s->quant.uvdc_delta = vp8_rac_get_sint(c, 4); + s->quant.uvac_delta = vp8_rac_get_sint(c, 4); for (i = 0; i < 4; i++) { if (s->segmentation.enabled) { base_qi = s->segmentation.base_quant[i]; if (!s->segmentation.absolute_vals) - base_qi += yac_qi; + base_qi += s->quant.yac_qi; } else - base_qi = yac_qi; + base_qi = s->quant.yac_qi; - s->qmat[i].luma_qmul[0] = vp8_dc_qlookup[av_clip_uintp2(base_qi + ydc_delta, 7)]; + s->qmat[i].luma_qmul[0] = vp8_dc_qlookup[av_clip_uintp2(base_qi + s->quant.ydc_delta, 7)]; s->qmat[i].luma_qmul[1] = vp8_ac_qlookup[av_clip_uintp2(base_qi, 7)]; - s->qmat[i].luma_dc_qmul[0] = vp8_dc_qlookup[av_clip_uintp2(base_qi + y2dc_delta, 7)] * 2; + s->qmat[i].luma_dc_qmul[0] = vp8_dc_qlookup[av_clip_uintp2(base_qi + s->quant.y2dc_delta, 7)] * 2; /* 101581>>16 is equivalent to 155/100 */ - s->qmat[i].luma_dc_qmul[1] = vp8_ac_qlookup[av_clip_uintp2(base_qi + y2ac_delta, 7)] * 101581 >> 16; - s->qmat[i].chroma_qmul[0] = vp8_dc_qlookup[av_clip_uintp2(base_qi + uvdc_delta, 7)]; - s->qmat[i].chroma_qmul[1] = vp8_ac_qlookup[av_clip_uintp2(base_qi + uvac_delta, 7)]; + s->qmat[i].luma_dc_qmul[1] = vp8_ac_qlookup[av_clip_uintp2(base_qi + s->quant.y2ac_delta, 7)] * 101581 >> 16; + s->qmat[i].chroma_qmul[0] = vp8_dc_qlookup[av_clip_uintp2(base_qi + s->quant.uvdc_delta, 7)]; + s->qmat[i].chroma_qmul[1] = vp8_ac_qlookup[av_clip_uintp2(base_qi + s->quant.uvac_delta, 7)]; s->qmat[i].luma_dc_qmul[1] = FFMAX(s->qmat[i].luma_dc_qmul[1], 8); s->qmat[i].chroma_qmul[0] = FFMIN(s->qmat[i].chroma_qmul[0], 132); @@ -637,6 +661,8 @@ static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si buf += 3; buf_size -= 3; + s->header_partition_size = header_size; + if (s->profile > 3) av_log(s->avctx, AV_LOG_WARNING, "Unknown profile %d\n", s->profile); @@ -700,9 +726,11 @@ static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si s->filter.level = vp8_rac_get_uint(c, 6); s->filter.sharpness = vp8_rac_get_uint(c, 3); - if ((s->lf_delta.enabled = vp8_rac_get(c))) - if (vp8_rac_get(c)) + if ((s->lf_delta.enabled = vp8_rac_get(c))) { + s->lf_delta.update = vp8_rac_get(c); + if (s->lf_delta.update) update_lf_deltas(s); + } if (setup_partitions(s, buf, buf_size)) { av_log(s->avctx, AV_LOG_ERROR, "Invalid partitions\n"); @@ -741,6 +769,13 @@ static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si vp78_update_pred16x16_pred8x8_mvc_probabilities(s, VP8_MVC_SIZE); } + // Record the entropy coder state here so that hwaccels can use it. + s->c.code_word = vp56_rac_renorm(&s->c); + s->coder_state_at_header_end.input = s->c.buffer - (-s->c.bits / 8); + s->coder_state_at_header_end.range = s->c.high; + s->coder_state_at_header_end.value = s->c.code_word >> 16; + s->coder_state_at_header_end.bit_count = -s->c.bits % 8; + return 0; } @@ -2462,7 +2497,6 @@ static int vp8_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, return vp78_decode_mb_row_sliced(avctx, tdata, jobnr, threadnr, IS_VP8); } - static av_always_inline int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt, int is_vp7) @@ -2480,6 +2514,20 @@ int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (ret < 0) goto err; + if (!is_vp7 && s->pix_fmt == AV_PIX_FMT_NONE) { + enum AVPixelFormat pix_fmts[] = { + AV_PIX_FMT_YUV420P, + AV_PIX_FMT_NONE, + }; + + s->pix_fmt = ff_get_format(s->avctx, pix_fmts); + if (s->pix_fmt < 0) { + ret = AVERROR(EINVAL); + goto err; + } + avctx->pix_fmt = s->pix_fmt; + } + prev_frame = s->framep[VP56_FRAME_CURRENT]; referenced = s->update_last || s->update_golden == VP56_FRAME_CURRENT || @@ -2555,51 +2603,67 @@ int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, ff_thread_finish_setup(avctx); - s->linesize = curframe->tf.f->linesize[0]; - s->uvlinesize = curframe->tf.f->linesize[1]; + if (avctx->hwaccel) { + ret = avctx->hwaccel->start_frame(avctx, avpkt->data, avpkt->size); + if (ret < 0) + goto err; - memset(s->top_nnz, 0, s->mb_width * sizeof(*s->top_nnz)); - /* Zero macroblock structures for top/top-left prediction - * from outside the frame. */ - if (!s->mb_layout) - memset(s->macroblocks + s->mb_height * 2 - 1, 0, - (s->mb_width + 1) * sizeof(*s->macroblocks)); - if (!s->mb_layout && s->keyframe) - memset(s->intra4x4_pred_mode_top, DC_PRED, s->mb_width * 4); + ret = avctx->hwaccel->decode_slice(avctx, avpkt->data, avpkt->size); + if (ret < 0) + goto err; - memset(s->ref_count, 0, sizeof(s->ref_count)); + ret = avctx->hwaccel->end_frame(avctx); + if (ret < 0) + goto err; - if (s->mb_layout == 1) { - // Make sure the previous frame has read its segmentation map, - // if we re-use the same map. - if (prev_frame && s->segmentation.enabled && - !s->segmentation.update_map) - ff_thread_await_progress(&prev_frame->tf, 1, 0); - if (is_vp7) - vp7_decode_mv_mb_modes(avctx, curframe, prev_frame); + } else { + s->linesize = curframe->tf.f->linesize[0]; + s->uvlinesize = curframe->tf.f->linesize[1]; + + memset(s->top_nnz, 0, s->mb_width * sizeof(*s->top_nnz)); + /* Zero macroblock structures for top/top-left prediction + * from outside the frame. */ + if (!s->mb_layout) + memset(s->macroblocks + s->mb_height * 2 - 1, 0, + (s->mb_width + 1) * sizeof(*s->macroblocks)); + if (!s->mb_layout && s->keyframe) + memset(s->intra4x4_pred_mode_top, DC_PRED, s->mb_width * 4); + + memset(s->ref_count, 0, sizeof(s->ref_count)); + + if (s->mb_layout == 1) { + // Make sure the previous frame has read its segmentation map, + // if we re-use the same map. + if (prev_frame && s->segmentation.enabled && + !s->segmentation.update_map) + ff_thread_await_progress(&prev_frame->tf, 1, 0); + if (is_vp7) + vp7_decode_mv_mb_modes(avctx, curframe, prev_frame); + else + vp8_decode_mv_mb_modes(avctx, curframe, prev_frame); + } + + if (avctx->active_thread_type == FF_THREAD_FRAME) + num_jobs = 1; else - vp8_decode_mv_mb_modes(avctx, curframe, prev_frame); - } + num_jobs = FFMIN(s->num_coeff_partitions, avctx->thread_count); + s->num_jobs = num_jobs; + s->curframe = curframe; + s->prev_frame = prev_frame; + s->mv_min.y = -MARGIN; + s->mv_max.y = ((s->mb_height - 1) << 6) + MARGIN; + for (i = 0; i < MAX_THREADS; i++) { + s->thread_data[i].thread_mb_pos = 0; + s->thread_data[i].wait_mb_pos = INT_MAX; + } - if (avctx->active_thread_type == FF_THREAD_FRAME) - num_jobs = 1; - else - num_jobs = FFMIN(s->num_coeff_partitions, avctx->thread_count); - s->num_jobs = num_jobs; - s->curframe = curframe; - s->prev_frame = prev_frame; - s->mv_min.y = -MARGIN; - s->mv_max.y = ((s->mb_height - 1) << 6) + MARGIN; - for (i = 0; i < MAX_THREADS; i++) { - s->thread_data[i].thread_mb_pos = 0; - s->thread_data[i].wait_mb_pos = INT_MAX; + if (is_vp7) + avctx->execute2(avctx, vp7_decode_mb_row_sliced, s->thread_data, NULL, + num_jobs); + else + avctx->execute2(avctx, vp8_decode_mb_row_sliced, s->thread_data, NULL, + num_jobs); } - if (is_vp7) - avctx->execute2(avctx, vp7_decode_mb_row_sliced, s->thread_data, NULL, - num_jobs); - else - avctx->execute2(avctx, vp8_decode_mb_row_sliced, s->thread_data, NULL, - num_jobs); ff_thread_report_progress(&curframe->tf, INT_MAX, 0); memcpy(&s->framep[0], &s->next_framep[0], sizeof(s->framep[0]) * 4); @@ -2666,6 +2730,7 @@ int vp78_decode_init(AVCodecContext *avctx, int is_vp7) int ret; s->avctx = avctx; + s->pix_fmt = AV_PIX_FMT_NONE; avctx->pix_fmt = AV_PIX_FMT_YUV420P; avctx->internal->allocate_progress = 1; diff --git a/libavcodec/vp8.h b/libavcodec/vp8.h index 65948e1d6be3a..1870705ad2e6b 100644 --- a/libavcodec/vp8.h +++ b/libavcodec/vp8.h @@ -130,12 +130,17 @@ typedef struct VP8ThreadData { typedef struct VP8Frame { ThreadFrame tf; AVBufferRef *seg_map; + + AVBufferRef *hwaccel_priv_buf; + void *hwaccel_picture_private; } VP8Frame; #define MAX_THREADS 8 typedef struct VP8Context { VP8ThreadData *thread_data; AVCodecContext *avctx; + enum AVPixelFormat pix_fmt; + VP8Frame *framep[4]; VP8Frame *next_framep[4]; VP8Frame *curframe; @@ -165,6 +170,7 @@ typedef struct VP8Context { uint8_t enabled; uint8_t absolute_vals; uint8_t update_map; + uint8_t update_feature_data; int8_t base_quant[4]; int8_t filter_level[4]; ///< base loop filter level } segmentation; @@ -192,8 +198,19 @@ typedef struct VP8Context { int16_t chroma_qmul[2]; } qmat[4]; + // Raw quantisation values, which may be needed by hwaccel decode. + struct { + int yac_qi; + int ydc_delta; + int y2dc_delta; + int y2ac_delta; + int uvdc_delta; + int uvac_delta; + } quant; + struct { uint8_t enabled; ///< whether each mb can have a different strength based on mode/ref + uint8_t update; /** * filter strength adjustment for the following macroblock modes: @@ -221,6 +238,20 @@ typedef struct VP8Context { VP56RangeCoder c; ///< header context, includes mb modes and motion vectors + /* This contains the entropy coder state at the end of the header + * block, in the form specified by the standard. For use by + * hwaccels, so that a hardware decoder has the information to + * start decoding at the macroblock layer. + */ + struct { + const uint8_t *input; + uint32_t range; + uint32_t value; + int bit_count; + } coder_state_at_header_end; + + int header_partition_size; + /** * These are all of the updatable probabilities for binary decisions. * They are only implicitly reset on keyframes, making it quite likely @@ -258,6 +289,7 @@ typedef struct VP8Context { */ int num_coeff_partitions; VP56RangeCoder coeff_partition[8]; + int coeff_partition_size[8]; VideoDSPContext vdsp; VP8DSPContext vp8dsp; H264PredContext hpc; From a9fb134730da1f9642eb5a2baa50943b8a4aa245 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 4 Sep 2016 13:28:10 +0100 Subject: [PATCH 0147/3374] lavc/vaapi: Add VP8 decode hwaccel --- configure | 3 + libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/vaapi_vp8.c | 231 +++++++++++++++++++++++++++++++++++++++++ libavcodec/vp8.c | 3 + 5 files changed, 239 insertions(+) create mode 100644 libavcodec/vaapi_vp8.c diff --git a/configure b/configure index 7ad920f4be5b4..520f07ccffda9 100755 --- a/configure +++ b/configure @@ -2185,6 +2185,8 @@ vc1_vaapi_hwaccel_deps="vaapi" vc1_vaapi_hwaccel_select="vc1_decoder" vc1_vdpau_hwaccel_deps="vdpau" vc1_vdpau_hwaccel_select="vc1_decoder" +vp8_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferVP8" +vp8_vaapi_hwaccel_select="vp8_decoder" wmv3_d3d11va_hwaccel_select="vc1_d3d11va_hwaccel" wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel" wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel" @@ -4544,6 +4546,7 @@ check_type "windows.h dxva.h" "DXVA_PicParams_HEVC" -DWINAPI_FAMILY=WINAPI_FAMIL check_type "windows.h d3d11.h" "ID3D11VideoDecoder" check_type "d3d9.h dxva2api.h" DXVA2_ConfigPictureDecode -D_WIN32_WINNT=0x0602 +check_type "va/va.h va/va_dec_vp8.h" "VAPictureParameterBufferVP8" check_type "va/va.h va/va_vpp.h" "VAProcPipelineParameterBuffer" check_type "va/va.h va/va_enc_h264.h" "VAEncPictureParameterBufferH264" check_type "va/va.h va/va_enc_hevc.h" "VAEncPictureParameterBufferHEVC" diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 974480f06dc81..bec461b80c0e4 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -634,6 +634,7 @@ OBJS-$(CONFIG_VC1_D3D11VA_HWACCEL) += dxva2_vc1.o OBJS-$(CONFIG_VC1_DXVA2_HWACCEL) += dxva2_vc1.o OBJS-$(CONFIG_VC1_VAAPI_HWACCEL) += vaapi_vc1.o OBJS-$(CONFIG_VC1_VDPAU_HWACCEL) += vdpau_vc1.o +OBJS-$(CONFIG_VP8_VAAPI_HWACCEL) += vaapi_vp8.o # libavformat dependencies OBJS-$(CONFIG_ISO_MEDIA) += mpeg4audio.o mpegaudiodata.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index e259de2510a02..41af38eb7cdeb 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -94,6 +94,7 @@ void avcodec_register_all(void) REGISTER_HWACCEL(VC1_VAAPI, vc1_vaapi); REGISTER_HWACCEL(VC1_VDPAU, vc1_vdpau); REGISTER_HWACCEL(VC1_MMAL, vc1_mmal); + REGISTER_HWACCEL(VP8_VAAPI, vp8_vaapi); REGISTER_HWACCEL(WMV3_D3D11VA, wmv3_d3d11va); REGISTER_HWACCEL(WMV3_DXVA2, wmv3_dxva2); REGISTER_HWACCEL(WMV3_VAAPI, wmv3_vaapi); diff --git a/libavcodec/vaapi_vp8.c b/libavcodec/vaapi_vp8.c new file mode 100644 index 0000000000000..a130c04e1d181 --- /dev/null +++ b/libavcodec/vaapi_vp8.c @@ -0,0 +1,231 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "vaapi_decode.h" +#include "vp8.h" + +static VASurfaceID vaapi_vp8_surface_id(VP8Frame *vf) +{ + if (vf) + return ff_vaapi_get_surface_id(vf->tf.f); + else + return VA_INVALID_SURFACE; +} + +static int vaapi_vp8_start_frame(AVCodecContext *avctx, + av_unused const uint8_t *buffer, + av_unused uint32_t size) +{ + const VP8Context *s = avctx->priv_data; + VAAPIDecodePicture *pic = s->framep[VP56_FRAME_CURRENT]->hwaccel_picture_private; + VAPictureParameterBufferVP8 pp; + VAProbabilityDataBufferVP8 prob; + VAIQMatrixBufferVP8 quant; + int err, i, j, k; + + pic->output_surface = vaapi_vp8_surface_id(s->framep[VP56_FRAME_CURRENT]); + + pp = (VAPictureParameterBufferVP8) { + .frame_width = avctx->width, + .frame_height = avctx->height, + + .last_ref_frame = vaapi_vp8_surface_id(s->framep[VP56_FRAME_PREVIOUS]), + .golden_ref_frame = vaapi_vp8_surface_id(s->framep[VP56_FRAME_GOLDEN]), + .alt_ref_frame = vaapi_vp8_surface_id(s->framep[VP56_FRAME_GOLDEN2]), + .out_of_loop_frame = VA_INVALID_SURFACE, + + .pic_fields.bits = { + .key_frame = !s->keyframe, + .version = s->profile, + + .segmentation_enabled = s->segmentation.enabled, + .update_mb_segmentation_map = s->segmentation.update_map, + .update_segment_feature_data = s->segmentation.update_feature_data, + + .filter_type = s->filter.simple, + .sharpness_level = s->filter.sharpness, + + .loop_filter_adj_enable = s->lf_delta.enabled, + .mode_ref_lf_delta_update = s->lf_delta.update, + + .sign_bias_golden = s->sign_bias[VP56_FRAME_GOLDEN], + .sign_bias_alternate = s->sign_bias[VP56_FRAME_GOLDEN2], + + .mb_no_coeff_skip = s->mbskip_enabled, + .loop_filter_disable = s->filter.level == 0, + }, + + .prob_skip_false = s->prob->mbskip, + .prob_intra = s->prob->intra, + .prob_last = s->prob->last, + .prob_gf = s->prob->golden, + }; + + for (i = 0; i < 3; i++) + pp.mb_segment_tree_probs[i] = s->prob->segmentid[i]; + + for (i = 0; i < 4; i++) { + if (s->segmentation.enabled) { + pp.loop_filter_level[i] = s->segmentation.filter_level[i]; + if (!s->segmentation.absolute_vals) + pp.loop_filter_level[i] += s->filter.level; + } else { + pp.loop_filter_level[i] = s->filter.level; + } + pp.loop_filter_level[i] = av_clip_uintp2(pp.loop_filter_level[i], 6); + } + + for (i = 0; i < 4; i++) { + pp.loop_filter_deltas_ref_frame[i] = s->lf_delta.ref[i]; + pp.loop_filter_deltas_mode[i] = s->lf_delta.mode[i + 4]; + } + + if (s->keyframe) { + static const uint8_t keyframe_y_mode_probs[4] = { + 145, 156, 163, 128 + }; + static const uint8_t keyframe_uv_mode_probs[3] = { + 142, 114, 183 + }; + memcpy(pp.y_mode_probs, keyframe_y_mode_probs, 4); + memcpy(pp.uv_mode_probs, keyframe_uv_mode_probs, 3); + } else { + for (i = 0; i < 4; i++) + pp.y_mode_probs[i] = s->prob->pred16x16[i]; + for (i = 0; i < 3; i++) + pp.uv_mode_probs[i] = s->prob->pred8x8c[i]; + } + for (i = 0; i < 2; i++) + for (j = 0; j < 19; j++) + pp.mv_probs[i][j] = s->prob->mvc[i][j]; + + pp.bool_coder_ctx.range = s->coder_state_at_header_end.range; + pp.bool_coder_ctx.value = s->coder_state_at_header_end.value; + pp.bool_coder_ctx.count = s->coder_state_at_header_end.bit_count; + + err = ff_vaapi_decode_make_param_buffer(avctx, pic, + VAPictureParameterBufferType, + &pp, sizeof(pp)); + if (err < 0) + goto fail; + + for (i = 0; i < 4; i++) { + for (j = 0; j < 8; j++) { + static const int coeff_bands_inverse[8] = { + 0, 1, 2, 3, 5, 6, 4, 15 + }; + int coeff_pos = coeff_bands_inverse[j]; + + for (k = 0; k < 3; k++) { + memcpy(prob.dct_coeff_probs[i][j][k], + s->prob->token[i][coeff_pos][k], 11); + } + } + } + + err = ff_vaapi_decode_make_param_buffer(avctx, pic, + VAProbabilityBufferType, + &prob, sizeof(prob)); + if (err < 0) + goto fail; + + for (i = 0; i < 4; i++) { + int base_qi = s->segmentation.base_quant[i]; + if (!s->segmentation.absolute_vals) + base_qi += s->quant.yac_qi; + + quant.quantization_index[i][0] = av_clip_uintp2(base_qi, 7); + quant.quantization_index[i][1] = av_clip_uintp2(base_qi + s->quant.ydc_delta, 7); + quant.quantization_index[i][2] = av_clip_uintp2(base_qi + s->quant.y2dc_delta, 7); + quant.quantization_index[i][3] = av_clip_uintp2(base_qi + s->quant.y2ac_delta, 7); + quant.quantization_index[i][4] = av_clip_uintp2(base_qi + s->quant.uvdc_delta, 7); + quant.quantization_index[i][5] = av_clip_uintp2(base_qi + s->quant.uvac_delta, 7); + } + + err = ff_vaapi_decode_make_param_buffer(avctx, pic, + VAIQMatrixBufferType, + &quant, sizeof(quant)); + if (err < 0) + goto fail; + + return 0; + +fail: + ff_vaapi_decode_cancel(avctx, pic); + return err; +} + +static int vaapi_vp8_end_frame(AVCodecContext *avctx) +{ + const VP8Context *s = avctx->priv_data; + VAAPIDecodePicture *pic = s->framep[VP56_FRAME_CURRENT]->hwaccel_picture_private; + + return ff_vaapi_decode_issue(avctx, pic); +} + +static int vaapi_vp8_decode_slice(AVCodecContext *avctx, + const uint8_t *buffer, + uint32_t size) +{ + const VP8Context *s = avctx->priv_data; + VAAPIDecodePicture *pic = s->framep[VP56_FRAME_CURRENT]->hwaccel_picture_private; + VASliceParameterBufferVP8 sp; + int err, i; + + unsigned int header_size = 3 + 7 * s->keyframe; + const uint8_t *data = buffer + header_size; + unsigned int data_size = size - header_size; + + sp = (VASliceParameterBufferVP8) { + .slice_data_size = data_size, + .slice_data_offset = 0, + .slice_data_flag = VA_SLICE_DATA_FLAG_ALL, + + .macroblock_offset = (8 * (s->coder_state_at_header_end.input - data) - + s->coder_state_at_header_end.bit_count - 8), + .num_of_partitions = s->num_coeff_partitions + 1, + }; + + sp.partition_size[0] = s->header_partition_size - ((sp.macroblock_offset + 7) / 8); + for (i = 0; i < 8; i++) + sp.partition_size[i+1] = s->coeff_partition_size[i]; + + err = ff_vaapi_decode_make_slice_buffer(avctx, pic, &sp, sizeof(sp), data, data_size); + if (err) + goto fail; + + return 0; + +fail: + ff_vaapi_decode_cancel(avctx, pic); + return err; +} + +AVHWAccel ff_vp8_vaapi_hwaccel = { + .name = "vp8_vaapi", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_VP8, + .pix_fmt = AV_PIX_FMT_VAAPI, + .start_frame = &vaapi_vp8_start_frame, + .end_frame = &vaapi_vp8_end_frame, + .decode_slice = &vaapi_vp8_decode_slice, + .frame_priv_data_size = sizeof(VAAPIDecodePicture), + .init = &ff_vaapi_decode_init, + .uninit = &ff_vaapi_decode_uninit, + .priv_data_size = sizeof(VAAPIDecodeContext), +}; diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index ced49799bcf00..bf1b03e9f77ef 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -2516,6 +2516,9 @@ int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (!is_vp7 && s->pix_fmt == AV_PIX_FMT_NONE) { enum AVPixelFormat pix_fmts[] = { +#if CONFIG_VP8_VAAPI_HWACCEL + AV_PIX_FMT_VAAPI, +#endif AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE, }; From 11c191b52ce0768370e38a2726132f9223e701f6 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 4 Sep 2016 13:33:15 +0100 Subject: [PATCH 0148/3374] vaapi_decode: Ignore the profile when not useful Enables VP8 decoding - the decoder places the the bitstream version in the profile field, which we want to ignore. --- libavcodec/vaapi_decode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c index 51b6d47a66516..ab8445afc081d 100644 --- a/libavcodec/vaapi_decode.c +++ b/libavcodec/vaapi_decode.c @@ -320,7 +320,8 @@ static int vaapi_decode_make_config(AVCodecContext *avctx) int profile_match = 0; if (avctx->codec_id != vaapi_profile_map[i].codec_id) continue; - if (avctx->profile == vaapi_profile_map[i].codec_profile) + if (avctx->profile == vaapi_profile_map[i].codec_profile || + vaapi_profile_map[i].codec_profile == FF_PROFILE_UNKNOWN) profile_match = 1; profile = vaapi_profile_map[i].va_profile; for (j = 0; j < profile_count; j++) { From 75d642a944d5579e4ef20ff3701422a64692afcf Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Fri, 9 Sep 2016 15:59:13 +0100 Subject: [PATCH 0149/3374] vaapi_vp8: Explicitly include libva vp8 decode header With some old libva versions does not automatically include the per-codec subsidiary headers, so we need to include the right one explicitly ourselves. --- libavcodec/vaapi_vp8.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavcodec/vaapi_vp8.c b/libavcodec/vaapi_vp8.c index a130c04e1d181..70e9cec3d4ecf 100644 --- a/libavcodec/vaapi_vp8.c +++ b/libavcodec/vaapi_vp8.c @@ -16,6 +16,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include +#include + #include "vaapi_decode.h" #include "vp8.h" From e89cef40506d990a982aefedfde7d3ca4f88c524 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sun, 11 Sep 2016 01:14:37 +0200 Subject: [PATCH 0150/3374] checkasm: Read the unsigned value as it should Reading a value larger than int using atoi() may give the wrong result. --- tests/checkasm/checkasm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c index 86d3bab30aaad..5b4aa640da11c 100644 --- a/tests/checkasm/checkasm.c +++ b/tests/checkasm/checkasm.c @@ -477,7 +477,8 @@ static void print_cpu_name(void) int main(int argc, char *argv[]) { - int i, seed, ret = 0; + unsigned int seed; + int i, ret = 0; #if ARCH_ARM && HAVE_ARMV5TE_EXTERNAL if (have_vfp(av_get_cpu_flags()) || have_neon(av_get_cpu_flags())) @@ -504,7 +505,7 @@ int main(int argc, char *argv[]) argv++; } - seed = (argc > 1) ? atoi(argv[1]) : av_get_random_seed(); + seed = (argc > 1) ? strtoul(argv[1], NULL, 10) : av_get_random_seed(); fprintf(stderr, "checkasm: using random seed %u\n", seed); av_lfg_init(&checkasm_lfg, seed); From caccb3a0cdc7ee32cbed7eab156d35025133eadc Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sat, 10 Sep 2016 18:12:23 +0200 Subject: [PATCH 0151/3374] audiodsp: ppc: Add VSX variant Signed-off-by: Luca Barbato Signed-off-by: Diego Biurrun --- libavcodec/ppc/audiodsp.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/libavcodec/ppc/audiodsp.c b/libavcodec/ppc/audiodsp.c index 2a0a6d8ef0a87..289bb58c426e4 100644 --- a/libavcodec/ppc/audiodsp.c +++ b/libavcodec/ppc/audiodsp.c @@ -61,6 +61,31 @@ static int32_t scalarproduct_int16_altivec(const int16_t *v1, const int16_t *v2, #endif /* HAVE_ALTIVEC */ +#if HAVE_VSX + +static int32_t scalarproduct_int16_vsx(const int16_t *v1, const int16_t *v2, int order) +{ + int i; + LOAD_ZERO; + register vec_s16 vec1; + register vec_s32 res = vec_splat_s32(0), t; + int32_t ires; + + for (i = 0; i < order; i += 8) { + vec1 = vec_vsx_ld(0, v1); + t = vec_msum(vec1, vec_ld(0, v2), zero_s32v); + res = vec_sums(t, res); + v1 += 8; + v2 += 8; + } + res = vec_splat(res, 3); + vec_ste(res, 0, &ires); + + return ires; +} + +#endif /* HAVE_VSX */ + av_cold void ff_audiodsp_init_ppc(AudioDSPContext *c) { #if HAVE_ALTIVEC && HAVE_BIGENDIAN @@ -69,4 +94,11 @@ av_cold void ff_audiodsp_init_ppc(AudioDSPContext *c) c->scalarproduct_int16 = scalarproduct_int16_altivec; #endif /* HAVE_ALTIVEC */ + +#if HAVE_VSX + if (!PPC_VSX(av_get_cpu_flags())) + return; + + c->scalarproduct_int16 = scalarproduct_int16_vsx; +#endif /* HAVE_VSX */ } From 6ce93757ee6b81fe727bfdc9f546fd0ddf9139c3 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 9 Sep 2016 18:28:20 +0200 Subject: [PATCH 0152/3374] ppc: Update #endif comments --- libavcodec/ppc/apedsp_altivec.c | 4 ++-- libavcodec/ppc/audiodsp.c | 2 +- libavcodec/ppc/fdctdsp.c | 4 ++-- libavcodec/ppc/fmtconvert_altivec.c | 4 ++-- libavcodec/ppc/h264chroma_init.c | 4 ++-- libavcodec/ppc/h264dsp.c | 4 ++-- libavcodec/ppc/h264qpel.c | 4 ++-- libavcodec/ppc/h264qpel_template.c | 6 +++--- libavcodec/ppc/hpeldsp_altivec.c | 4 ++-- libavcodec/ppc/huffyuvdsp_altivec.c | 4 ++-- libavcodec/ppc/idctdsp.c | 4 ++-- libavcodec/ppc/me_cmp.c | 4 ++-- libavcodec/ppc/mpegaudiodsp_altivec.c | 4 ++-- libavcodec/ppc/mpegvideo_altivec.c | 4 ++-- libavcodec/ppc/mpegvideodsp.c | 4 ++-- libavcodec/ppc/mpegvideoencdsp.c | 4 ++-- libavcodec/ppc/pixblockdsp.c | 4 ++-- libavcodec/ppc/svq1enc_altivec.c | 4 ++-- libavcodec/ppc/vc1dsp_altivec.c | 4 ++-- libavcodec/ppc/vorbisdsp_altivec.c | 4 ++-- libavcodec/ppc/vp3dsp_altivec.c | 4 ++-- libavcodec/ppc/vp8dsp_altivec.c | 5 ++--- 22 files changed, 44 insertions(+), 45 deletions(-) diff --git a/libavcodec/ppc/apedsp_altivec.c b/libavcodec/ppc/apedsp_altivec.c index 3b9d045b829dd..21a3d10f18b04 100644 --- a/libavcodec/ppc/apedsp_altivec.c +++ b/libavcodec/ppc/apedsp_altivec.c @@ -69,7 +69,7 @@ static int32_t scalarproduct_and_madd_int16_altivec(int16_t *v1, return ires; } -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ av_cold void ff_apedsp_init_ppc(APEDSPContext *c) { @@ -78,5 +78,5 @@ av_cold void ff_apedsp_init_ppc(APEDSPContext *c) return; c->scalarproduct_and_madd_int16 = scalarproduct_and_madd_int16_altivec; -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ } diff --git a/libavcodec/ppc/audiodsp.c b/libavcodec/ppc/audiodsp.c index 289bb58c426e4..52a1e75cc16dc 100644 --- a/libavcodec/ppc/audiodsp.c +++ b/libavcodec/ppc/audiodsp.c @@ -59,7 +59,7 @@ static int32_t scalarproduct_int16_altivec(const int16_t *v1, const int16_t *v2, return ires; } -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ #if HAVE_VSX diff --git a/libavcodec/ppc/fdctdsp.c b/libavcodec/ppc/fdctdsp.c index 89ceb4736f198..cadca8046943a 100644 --- a/libavcodec/ppc/fdctdsp.c +++ b/libavcodec/ppc/fdctdsp.c @@ -460,7 +460,7 @@ void ff_fdct_altivec(int16_t *block) /* }}} */ } -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ av_cold void ff_fdctdsp_init_ppc(FDCTDSPContext *c, AVCodecContext *avctx, unsigned high_bit_depth) @@ -475,5 +475,5 @@ av_cold void ff_fdctdsp_init_ppc(FDCTDSPContext *c, AVCodecContext *avctx, c->fdct = ff_fdct_altivec; } } -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ } diff --git a/libavcodec/ppc/fmtconvert_altivec.c b/libavcodec/ppc/fmtconvert_altivec.c index 796c4314ea46c..153f44ac9c248 100644 --- a/libavcodec/ppc/fmtconvert_altivec.c +++ b/libavcodec/ppc/fmtconvert_altivec.c @@ -52,7 +52,7 @@ static void int32_to_float_fmul_scalar_altivec(float *dst, const int32_t *src, } } -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ av_cold void ff_fmt_convert_init_ppc(FmtConvertContext *c, AVCodecContext *avctx) @@ -62,5 +62,5 @@ av_cold void ff_fmt_convert_init_ppc(FmtConvertContext *c, return; c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_altivec; -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ } diff --git a/libavcodec/ppc/h264chroma_init.c b/libavcodec/ppc/h264chroma_init.c index 178f2397208ca..4a24b7f82fc7d 100644 --- a/libavcodec/ppc/h264chroma_init.c +++ b/libavcodec/ppc/h264chroma_init.c @@ -46,7 +46,7 @@ #undef OP_U8_ALTIVEC #undef PREFIX_h264_chroma_mc8_altivec #undef PREFIX_h264_chroma_mc8_num -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ av_cold void ff_h264chroma_init_ppc(H264ChromaContext *c, int bit_depth) { @@ -60,5 +60,5 @@ av_cold void ff_h264chroma_init_ppc(H264ChromaContext *c, int bit_depth) c->put_h264_chroma_pixels_tab[0] = put_h264_chroma_mc8_altivec; c->avg_h264_chroma_pixels_tab[0] = avg_h264_chroma_mc8_altivec; } -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ } diff --git a/libavcodec/ppc/h264dsp.c b/libavcodec/ppc/h264dsp.c index 0538dbceed9b6..a1fd5253b1848 100644 --- a/libavcodec/ppc/h264dsp.c +++ b/libavcodec/ppc/h264dsp.c @@ -746,7 +746,7 @@ static void biweight_h264_pixels ## W ## _altivec(uint8_t *dst, uint8_t *src, in H264_WEIGHT(16) H264_WEIGHT( 8) -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ av_cold void ff_h264dsp_init_ppc(H264DSPContext *c, const int bit_depth, const int chroma_format_idc) @@ -773,5 +773,5 @@ av_cold void ff_h264dsp_init_ppc(H264DSPContext *c, const int bit_depth, c->biweight_h264_pixels_tab[0] = biweight_h264_pixels16_altivec; c->biweight_h264_pixels_tab[1] = biweight_h264_pixels8_altivec; } -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ } diff --git a/libavcodec/ppc/h264qpel.c b/libavcodec/ppc/h264qpel.c index 92c86f32fc9ab..aff20c15a2d25 100644 --- a/libavcodec/ppc/h264qpel.c +++ b/libavcodec/ppc/h264qpel.c @@ -282,7 +282,7 @@ static inline void avg_pixels16_l2_altivec( uint8_t * dst, const uint8_t * src1, H264_MC(put_, 16, altivec) H264_MC(avg_, 16, altivec) -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ av_cold void ff_h264qpel_init_ppc(H264QpelContext *c, int bit_depth) { @@ -315,5 +315,5 @@ av_cold void ff_h264qpel_init_ppc(H264QpelContext *c, int bit_depth) dspfunc(avg_h264_qpel, 0, 16); #undef dspfunc } -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ } diff --git a/libavcodec/ppc/h264qpel_template.c b/libavcodec/ppc/h264qpel_template.c index fe83146e63467..6de063a7195aa 100644 --- a/libavcodec/ppc/h264qpel_template.c +++ b/libavcodec/ppc/h264qpel_template.c @@ -167,7 +167,7 @@ static void PREFIX_h264_qpel16_h_lowpass_altivec(uint8_t *dst, dst += dstStride; } } -#endif +#endif /* PREFIX_h264_qpel16_h_lowpass_altivec */ /* this code assume stride % 16 == 0 */ #ifdef PREFIX_h264_qpel16_v_lowpass_altivec @@ -277,7 +277,7 @@ static void PREFIX_h264_qpel16_v_lowpass_altivec(uint8_t *dst, dst += dstStride; } } -#endif +#endif /* PREFIX_h264_qpel16_v_lowpass_altivec */ /* this code assume stride % 16 == 0 *and* tmp is properly aligned */ #ifdef PREFIX_h264_qpel16_hv_lowpass_altivec @@ -514,4 +514,4 @@ static void PREFIX_h264_qpel16_hv_lowpass_altivec(uint8_t *dst, int16_t *tmp, dst += dstStride; } } -#endif +#endif /* PREFIX_h264_qpel16_hv_lowpass_altivec */ diff --git a/libavcodec/ppc/hpeldsp_altivec.c b/libavcodec/ppc/hpeldsp_altivec.c index 780240ba20378..82b5ce7fc7baf 100644 --- a/libavcodec/ppc/hpeldsp_altivec.c +++ b/libavcodec/ppc/hpeldsp_altivec.c @@ -445,7 +445,7 @@ static void avg_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, ptrdi pixels += line_size; } } -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ av_cold void ff_hpeldsp_init_ppc(HpelDSPContext *c, int flags) { @@ -464,5 +464,5 @@ av_cold void ff_hpeldsp_init_ppc(HpelDSPContext *c, int flags) c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_altivec; c->put_no_rnd_pixels_tab[1][3] = put_no_rnd_pixels8_xy2_altivec; c->put_no_rnd_pixels_tab[0][3] = put_no_rnd_pixels16_xy2_altivec; -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ } diff --git a/libavcodec/ppc/huffyuvdsp_altivec.c b/libavcodec/ppc/huffyuvdsp_altivec.c index 4c16283f078a0..337328ae0562e 100644 --- a/libavcodec/ppc/huffyuvdsp_altivec.c +++ b/libavcodec/ppc/huffyuvdsp_altivec.c @@ -49,7 +49,7 @@ static void add_bytes_altivec(uint8_t *dst, uint8_t *src, int w) for (; i < w; i++) dst[i] = src[i]; } -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ av_cold void ff_huffyuvdsp_init_ppc(HuffYUVDSPContext *c) { @@ -58,5 +58,5 @@ av_cold void ff_huffyuvdsp_init_ppc(HuffYUVDSPContext *c) return; c->add_bytes = add_bytes_altivec; -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ } diff --git a/libavcodec/ppc/idctdsp.c b/libavcodec/ppc/idctdsp.c index c85b58e6ff171..690b08beb8ef4 100644 --- a/libavcodec/ppc/idctdsp.c +++ b/libavcodec/ppc/idctdsp.c @@ -225,7 +225,7 @@ static void idct_add_altivec(uint8_t *dest, int stride, int16_t *blk) ADD(dest, vx7, perm1); } -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ av_cold void ff_idctdsp_init_ppc(IDCTDSPContext *c, AVCodecContext *avctx, unsigned high_bit_depth) @@ -242,5 +242,5 @@ av_cold void ff_idctdsp_init_ppc(IDCTDSPContext *c, AVCodecContext *avctx, c->perm_type = FF_IDCT_PERM_TRANSPOSE; } } -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ } diff --git a/libavcodec/ppc/me_cmp.c b/libavcodec/ppc/me_cmp.c index b074d28b5c9c7..6c70f9f0fa5a6 100644 --- a/libavcodec/ppc/me_cmp.c +++ b/libavcodec/ppc/me_cmp.c @@ -742,7 +742,7 @@ static int hadamard8_diff16_altivec(MpegEncContext *s, uint8_t *dst, } return score; } -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ av_cold void ff_me_cmp_init_ppc(MECmpContext *c, AVCodecContext *avctx) { @@ -763,5 +763,5 @@ av_cold void ff_me_cmp_init_ppc(MECmpContext *c, AVCodecContext *avctx) c->hadamard8_diff[0] = hadamard8_diff16_altivec; c->hadamard8_diff[1] = hadamard8_diff8x8_altivec; -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ } diff --git a/libavcodec/ppc/mpegaudiodsp_altivec.c b/libavcodec/ppc/mpegaudiodsp_altivec.c index 21cbcf376f46d..b3d3ed4a3e32c 100644 --- a/libavcodec/ppc/mpegaudiodsp_altivec.c +++ b/libavcodec/ppc/mpegaudiodsp_altivec.c @@ -128,7 +128,7 @@ static void apply_window_mp3(float *in, float *win, int *unused, float *out, *out = sum; } -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ av_cold void ff_mpadsp_init_ppc(MPADSPContext *s) { @@ -137,5 +137,5 @@ av_cold void ff_mpadsp_init_ppc(MPADSPContext *s) return; s->apply_window_float = apply_window_mp3; -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ } diff --git a/libavcodec/ppc/mpegvideo_altivec.c b/libavcodec/ppc/mpegvideo_altivec.c index 550a03ad412f4..a09932bdf83a4 100644 --- a/libavcodec/ppc/mpegvideo_altivec.c +++ b/libavcodec/ppc/mpegvideo_altivec.c @@ -113,7 +113,7 @@ static void dct_unquantize_h263_altivec(MpegEncContext *s, } } -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ av_cold void ff_mpv_common_init_ppc(MpegEncContext *s) { @@ -126,5 +126,5 @@ av_cold void ff_mpv_common_init_ppc(MpegEncContext *s) s->dct_unquantize_h263_intra = dct_unquantize_h263_altivec; s->dct_unquantize_h263_inter = dct_unquantize_h263_altivec; } -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ } diff --git a/libavcodec/ppc/mpegvideodsp.c b/libavcodec/ppc/mpegvideodsp.c index 0b426e5e2a866..e6c0457cd651e 100644 --- a/libavcodec/ppc/mpegvideodsp.c +++ b/libavcodec/ppc/mpegvideodsp.c @@ -123,11 +123,11 @@ static void gmc1_altivec(uint8_t *dst /* align 8 */, uint8_t *src /* align1 */, src += stride; } } -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ av_cold void ff_mpegvideodsp_init_ppc(MpegVideoDSPContext *c) { #if HAVE_ALTIVEC && HAVE_BIGENDIAN c->gmc1 = gmc1_altivec; -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ } diff --git a/libavcodec/ppc/mpegvideoencdsp.c b/libavcodec/ppc/mpegvideoencdsp.c index 7354816208c16..fa71bac0baa75 100644 --- a/libavcodec/ppc/mpegvideoencdsp.c +++ b/libavcodec/ppc/mpegvideoencdsp.c @@ -88,7 +88,7 @@ static int pix_sum_altivec(uint8_t *pix, int line_size) return s; } -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ av_cold void ff_mpegvideoencdsp_init_ppc(MpegvideoEncDSPContext *c, AVCodecContext *avctx) @@ -99,5 +99,5 @@ av_cold void ff_mpegvideoencdsp_init_ppc(MpegvideoEncDSPContext *c, c->pix_norm1 = pix_norm1_altivec; c->pix_sum = pix_sum_altivec; -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ } diff --git a/libavcodec/ppc/pixblockdsp.c b/libavcodec/ppc/pixblockdsp.c index 9cac70e2ef942..00e79495c384d 100644 --- a/libavcodec/ppc/pixblockdsp.c +++ b/libavcodec/ppc/pixblockdsp.c @@ -131,7 +131,7 @@ static void diff_pixels_altivec(int16_t *restrict block, const uint8_t *s1, } } -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ #if HAVE_VSX static void get_pixels_vsx(int16_t *restrict block, const uint8_t *pixels, @@ -180,7 +180,7 @@ av_cold void ff_pixblockdsp_init_ppc(PixblockDSPContext *c, if (!high_bit_depth) { c->get_pixels = get_pixels_altivec; } -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ #if HAVE_VSX if (!PPC_VSX(av_get_cpu_flags())) diff --git a/libavcodec/ppc/svq1enc_altivec.c b/libavcodec/ppc/svq1enc_altivec.c index 222f7c1c376b6..77d771eba6512 100644 --- a/libavcodec/ppc/svq1enc_altivec.c +++ b/libavcodec/ppc/svq1enc_altivec.c @@ -72,7 +72,7 @@ static int ssd_int8_vs_int16_altivec(const int8_t *pix1, const int16_t *pix2, return u.score[3]; } -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ av_cold void ff_svq1enc_init_ppc(SVQ1EncContext *c) { @@ -81,5 +81,5 @@ av_cold void ff_svq1enc_init_ppc(SVQ1EncContext *c) return; c->ssd_int8_vs_int16 = ssd_int8_vs_int16_altivec; -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ } diff --git a/libavcodec/ppc/vc1dsp_altivec.c b/libavcodec/ppc/vc1dsp_altivec.c index caf8721ebf72b..0eec4751dfc90 100644 --- a/libavcodec/ppc/vc1dsp_altivec.c +++ b/libavcodec/ppc/vc1dsp_altivec.c @@ -340,7 +340,7 @@ static void vc1_inv_trans_8x4_altivec(uint8_t *dest, int stride, int16_t *block) #undef OP_U8_ALTIVEC #undef PREFIX_no_rnd_vc1_chroma_mc8_altivec -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ av_cold void ff_vc1dsp_init_ppc(VC1DSPContext *dsp) { @@ -352,5 +352,5 @@ av_cold void ff_vc1dsp_init_ppc(VC1DSPContext *dsp) dsp->vc1_inv_trans_8x4 = vc1_inv_trans_8x4_altivec; dsp->put_no_rnd_vc1_chroma_pixels_tab[0] = put_no_rnd_vc1_chroma_mc8_altivec; dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = avg_no_rnd_vc1_chroma_mc8_altivec; -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ } diff --git a/libavcodec/ppc/vorbisdsp_altivec.c b/libavcodec/ppc/vorbisdsp_altivec.c index a7aad86163bc4..509d48ae0ce60 100644 --- a/libavcodec/ppc/vorbisdsp_altivec.c +++ b/libavcodec/ppc/vorbisdsp_altivec.c @@ -50,7 +50,7 @@ static void vorbis_inverse_coupling_altivec(float *mag, float *ang, vec_stl(m, 0, mag+i); } } -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ av_cold void ff_vorbisdsp_init_ppc(VorbisDSPContext *c) { @@ -59,5 +59,5 @@ av_cold void ff_vorbisdsp_init_ppc(VorbisDSPContext *c) return; c->vorbis_inverse_coupling = vorbis_inverse_coupling_altivec; -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ } diff --git a/libavcodec/ppc/vp3dsp_altivec.c b/libavcodec/ppc/vp3dsp_altivec.c index 1d907d7d2ed22..4dff4f1b966a9 100644 --- a/libavcodec/ppc/vp3dsp_altivec.c +++ b/libavcodec/ppc/vp3dsp_altivec.c @@ -175,7 +175,7 @@ static void vp3_idct_add_altivec(uint8_t *dst, ptrdiff_t stride, int16_t block[6 memset(block, 0, sizeof(*block) * 64); } -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ av_cold void ff_vp3dsp_init_ppc(VP3DSPContext *c, int flags) { @@ -185,5 +185,5 @@ av_cold void ff_vp3dsp_init_ppc(VP3DSPContext *c, int flags) c->idct_put = vp3_idct_put_altivec; c->idct_add = vp3_idct_add_altivec; -#endif +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ } diff --git a/libavcodec/ppc/vp8dsp_altivec.c b/libavcodec/ppc/vp8dsp_altivec.c index 869fe670e7a70..53fe44ab4897d 100644 --- a/libavcodec/ppc/vp8dsp_altivec.c +++ b/libavcodec/ppc/vp8dsp_altivec.c @@ -310,8 +310,7 @@ static void put_vp8_pixels16_altivec(uint8_t *dst, ptrdiff_t dstride, uint8_t *s } } -#endif /* HAVE_ALTIVEC */ - +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ av_cold void ff_vp78dsp_init_ppc(VP8DSPContext *c) { @@ -343,5 +342,5 @@ av_cold void ff_vp78dsp_init_ppc(VP8DSPContext *c) c->put_vp8_epel_pixels_tab[2][1][1] = put_vp8_epel4_h4v4_altivec; c->put_vp8_epel_pixels_tab[2][1][2] = put_vp8_epel4_h6v4_altivec; c->put_vp8_epel_pixels_tab[2][2][1] = put_vp8_epel4_h4v6_altivec; -#endif /* HAVE_ALTIVEC */ +#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ } From 468bfe38c66d4d020984158e53b09a6a5749f394 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 9 Sep 2016 18:30:51 +0200 Subject: [PATCH 0153/3374] ppc: mpegvideo: Add proper runtime AltiVec detection --- libavcodec/ppc/mpegvideodsp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/ppc/mpegvideodsp.c b/libavcodec/ppc/mpegvideodsp.c index e6c0457cd651e..eef3e1dcbe200 100644 --- a/libavcodec/ppc/mpegvideodsp.c +++ b/libavcodec/ppc/mpegvideodsp.c @@ -20,7 +20,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/cpu.h" #include "libavutil/mem.h" +#include "libavutil/ppc/cpu.h" #include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" #include "libavcodec/mpegvideodsp.h" @@ -128,6 +130,9 @@ static void gmc1_altivec(uint8_t *dst /* align 8 */, uint8_t *src /* align1 */, av_cold void ff_mpegvideodsp_init_ppc(MpegVideoDSPContext *c) { #if HAVE_ALTIVEC && HAVE_BIGENDIAN + if (!PPC_ALTIVEC(av_get_cpu_flags())) + return; + c->gmc1 = gmc1_altivec; #endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ } From ab3554e1a7c04a5ea30f9c905de92348478ef7c8 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 5 Sep 2016 10:48:37 +0200 Subject: [PATCH 0154/3374] configure: Drop check_lib()/require() in favor of check_lib2()/require2() The latter can do everything the former can do, but also handle conditions the former cannot like multiple header #includes and checking for headers and functions in a single test program, which is necessary for certain library tests. --- configure | 56 ++++++++++++++++++++----------------------------------- 1 file changed, 20 insertions(+), 36 deletions(-) diff --git a/configure b/configure index 520f07ccffda9..1f5fb8a3566ee 100755 --- a/configure +++ b/configure @@ -988,14 +988,6 @@ EOF check_lib(){ log check_lib "$@" - header="$1" - func="$2" - shift 2 - check_header $header && check_func $func "$@" && add_extralibs "$@" -} - -check_lib2(){ - log check_lib2 "$@" headers="$1" funcs="$2" shift 2 @@ -1091,19 +1083,11 @@ check_compile_assert(){ } require(){ - name="$1" - header="$2" - func="$3" - shift 3 - check_lib $header $func "$@" || die "ERROR: $name not found" -} - -require2(){ name="$1" headers="$2" func="$3" shift 3 - check_lib2 "$headers" $func "$@" || die "ERROR: $name not found" + check_lib "$headers" $func "$@" || die "ERROR: $name not found" } require_pkg_config(){ @@ -4475,7 +4459,7 @@ check_func ${malloc_prefix}posix_memalign && enable posix_memalign check_cpp_condition unistd.h "defined(_POSIX_MONOTONIC_CLOCK)" && check_func_headers time.h clock_gettime || - { check_lib2 time.h clock_gettime -lrt && LIBRT="-lrt"; } + { check_lib time.h clock_gettime -lrt && LIBRT="-lrt"; } check_func fcntl check_func fork @@ -4536,9 +4520,9 @@ check_header VideoDecodeAcceleration/VDADecoder.h check_header windows.h check_header X11/extensions/XvMClib.h -check_lib2 "windows.h shellapi.h" CommandLineToArgvW -lshell32 -check_lib2 "windows.h wincrypt.h" CryptGenRandom -ladvapi32 -check_lib2 "windows.h psapi.h" GetProcessMemoryInfo -lpsapi +check_lib "windows.h shellapi.h" CommandLineToArgvW -lshell32 +check_lib "windows.h wincrypt.h" CryptGenRandom -ladvapi32 +check_lib "windows.h psapi.h" GetProcessMemoryInfo -lpsapi check_struct "sys/time.h sys/resource.h" "struct rusage" ru_maxrss @@ -4581,8 +4565,8 @@ fi enabled pthreads && check_builtin sem_timedwait semaphore.h "sem_t *s; sem_init(s,0,0); sem_timedwait(s,0); sem_destroy(s)" -disabled zlib || check_lib zlib.h zlibVersion -lz || disable zlib -disabled bzlib || check_lib2 bzlib.h BZ2_bzlibVersion -lbz2 || disable bzlib +disabled zlib || check_lib zlib.h zlibVersion -lz || disable zlib +disabled bzlib || check_lib bzlib.h BZ2_bzlibVersion -lbz2 || disable bzlib check_lib math.h sin -lm && LIBM="-lm" @@ -4595,15 +4579,15 @@ for func in $MATH_FUNCS; do done # these are off by default, so fail if requested and not available -enabled avisynth && { check_lib2 "avisynth/avisynth_c.h windows.h" LoadLibrary || - check_lib2 "avxsynth/avxsynth_c.h dlfcn.h" dlopen -ldl || +enabled avisynth && { check_lib "avisynth/avisynth_c.h windows.h" LoadLibrary || + check_lib "avxsynth/avxsynth_c.h dlfcn.h" dlopen -ldl || die "ERROR: LoadLibrary/dlopen not found, or avisynth header not found"; } enabled cuda && check_lib cuda.h cuInit -lcuda enabled frei0r && { check_header frei0r.h || die "ERROR: frei0r.h header not found"; } enabled gnutls && require_pkg_config gnutls gnutls/gnutls.h gnutls_global_init enabled libbs2b && require_pkg_config libbs2b bs2b.h bs2b_open enabled libdcadec && require libdcadec libdcadec/dca_context.h dcadec_context_create -ldcadec -enabled libfaac && require2 libfaac "stdint.h faac.h" faacEncGetVersion -lfaac +enabled libfaac && require libfaac "stdint.h faac.h" faacEncGetVersion -lfaac enabled libfdk_aac && require_pkg_config fdk-aac "fdk-aac/aacenc_lib.h" aacEncOpen enabled libfontconfig && require_pkg_config fontconfig "fontconfig/fontconfig.h" FcInit enabled libfreetype && require_pkg_config freetype2 "ft2build.h FT_FREETYPE_H" FT_Init_FreeType @@ -4620,7 +4604,7 @@ enabled libopencore_amrnb && require libopencore_amrnb opencore-amrnb/interf_dec enabled libopencore_amrwb && require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb enabled libopencv && require_pkg_config opencv opencv/cv.h cvCreateImageHeader enabled libopenh264 && require_pkg_config openh264 wels/codec_api.h WelsGetCodecVersion -enabled libopenjpeg && { check_lib2 openjpeg.h opj_version -lopenjpeg -DOPJ_STATIC || +enabled libopenjpeg && { check_lib openjpeg.h opj_version -lopenjpeg -DOPJ_STATIC || require_pkg_config libopenjpeg1 openjpeg.h opj_version -DOPJ_STATIC; } enabled libopus && require_pkg_config opus opus_multistream.h opus_multistream_decoder_create enabled libpulse && require_pkg_config libpulse-simple pulse/simple.h pa_simple_new @@ -4688,7 +4672,7 @@ enabled openssl && { check_pkg_config openssl openssl/ssl.h SSL_librar die "ERROR: openssl not found"; } if enabled gnutls; then - { check_lib2 gmp.h mpz_export -lgmp && enable gmp; } || + { check_lib gmp.h mpz_export -lgmp && enable gmp; } || { check_lib gcrypt.h gcry_mpi_new -lgcrypt && enable gcrypt; } fi @@ -4746,16 +4730,16 @@ check_header sys/soundcard.h check_header soundcard.h enabled_any alsa_indev alsa_outdev && - check_lib2 alsa/asoundlib.h snd_pcm_htimestamp -lasound + check_lib alsa/asoundlib.h snd_pcm_htimestamp -lasound -enabled jack_indev && check_lib2 jack/jack.h jack_client_open -ljack && +enabled jack_indev && check_lib jack/jack.h jack_client_open -ljack && check_func jack_port_get_latency_range -ljack -enabled_any sndio_indev sndio_outdev && check_lib2 sndio.h sio_open -lsndio +enabled_any sndio_indev sndio_outdev && check_lib sndio.h sio_open -lsndio if enabled libcdio; then - check_lib2 "cdio/cdda.h cdio/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio || - check_lib2 "cdio/paranoia/cdda.h cdio/paranoia/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio || + check_lib "cdio/cdda.h cdio/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio || + check_lib "cdio/paranoia/cdda.h cdio/paranoia/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio || die "ERROR: No usable libcdio/cdparanoia found" fi @@ -4788,10 +4772,10 @@ enabled vaapi && if enabled vaapi ; then enabled xlib && - check_lib2 "va/va.h va/va_x11.h" vaGetDisplay -lva -lva-x11 && + check_lib "va/va.h va/va_x11.h" vaGetDisplay -lva -lva-x11 && enable vaapi_x11 - check_lib2 "va/va.h va/va_drm.h" vaGetDisplayDRM -lva -lva-drm && + check_lib "va/va.h va/va_drm.h" vaGetDisplayDRM -lva -lva-drm && enable vaapi_drm fi @@ -4800,7 +4784,7 @@ enabled vdpau && disable vdpau enabled vdpau && enabled xlib && - check_lib2 "vdpau/vdpau.h vdpau/vdpau_x11.h" vdp_device_create_x11 -lvdpau && + check_lib "vdpau/vdpau.h vdpau/vdpau_x11.h" vdp_device_create_x11 -lvdpau && enable vdpau_x11 enabled debug && add_cflags -g"$debuglevel" && add_asflags -g"$debuglevel" From de452e503734ebb0fdbce86e9d16693b3530fad3 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 6 Sep 2016 16:06:12 +0200 Subject: [PATCH 0155/3374] pixblockdsp: Change type of stride parameters to ptrdiff_t This avoids SIMD-optimized functions having to sign-extend their line size argument manually to be able to do pointer arithmetic. Also adjust parameter names to be "stride" everywhere. --- libavcodec/arm/pixblockdsp_init_arm.c | 5 +++-- libavcodec/dv.h | 2 +- libavcodec/dvenc.c | 9 +++++---- libavcodec/pixblockdsp.c | 2 +- libavcodec/pixblockdsp.h | 4 ++-- libavcodec/pixblockdsp_template.c | 4 ++-- libavcodec/ppc/pixblockdsp.c | 12 ++++++------ libavcodec/x86/pixblockdsp.asm | 7 ++----- libavcodec/x86/pixblockdsp_init.c | 6 +++--- 9 files changed, 25 insertions(+), 26 deletions(-) diff --git a/libavcodec/arm/pixblockdsp_init_arm.c b/libavcodec/arm/pixblockdsp_init_arm.c index f20769b3bc598..bb32631df49a7 100644 --- a/libavcodec/arm/pixblockdsp_init_arm.c +++ b/libavcodec/arm/pixblockdsp_init_arm.c @@ -24,9 +24,10 @@ #include "libavcodec/avcodec.h" #include "libavcodec/pixblockdsp.h" -void ff_get_pixels_armv6(int16_t *block, const uint8_t *pixels, int stride); +void ff_get_pixels_armv6(int16_t *block, const uint8_t *pixels, + ptrdiff_t stride); void ff_diff_pixels_armv6(int16_t *block, const uint8_t *s1, - const uint8_t *s2, int stride); + const uint8_t *s2, ptrdiff_t stride); av_cold void ff_pixblockdsp_init_arm(PixblockDSPContext *c, AVCodecContext *avctx, diff --git a/libavcodec/dv.h b/libavcodec/dv.h index 1d1650c5858c5..f2c7ecf3d92dc 100644 --- a/libavcodec/dv.h +++ b/libavcodec/dv.h @@ -45,7 +45,7 @@ typedef struct DVVideoContext { uint8_t dv_zigzag[2][64]; - void (*get_pixels)(int16_t *block, const uint8_t *pixels, int line_size); + void (*get_pixels)(int16_t *block, const uint8_t *pixels, ptrdiff_t linesize); void (*fdct[2])(int16_t *block); void (*idct_put[2])(uint8_t *dest, int line_size, int16_t *block); me_cmp_func ildct_cmp; diff --git a/libavcodec/dvenc.c b/libavcodec/dvenc.c index e02f349fbc6fc..399c4341f8404 100644 --- a/libavcodec/dvenc.c +++ b/libavcodec/dvenc.c @@ -197,7 +197,7 @@ static av_always_inline PutBitContext *dv_encode_ac(EncBlockInfo *bi, } static av_always_inline int dv_guess_dct_mode(DVVideoContext *s, uint8_t *data, - int linesize) + ptrdiff_t linesize) { if (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) { int ps = s->ildct_cmp(NULL, data, NULL, linesize, 8) - 400; @@ -234,8 +234,8 @@ static const int dv_weight_248[64] = { }; static av_always_inline int dv_init_enc_block(EncBlockInfo *bi, uint8_t *data, - int linesize, DVVideoContext *s, - int bias) + ptrdiff_t linesize, + DVVideoContext *s, int bias) { const int *weight; const uint8_t *zigzag_scan; @@ -413,7 +413,8 @@ static int dv_encode_video_segment(AVCodecContext *avctx, void *arg) DVVideoContext *s = avctx->priv_data; DVwork_chunk *work_chunk = arg; int mb_index, i, j; - int mb_x, mb_y, c_offset, linesize, y_stride; + int mb_x, mb_y, c_offset; + ptrdiff_t linesize, y_stride; uint8_t *y_ptr; uint8_t *dif; LOCAL_ALIGNED_8(uint8_t, scratch, [128]); diff --git a/libavcodec/pixblockdsp.c b/libavcodec/pixblockdsp.c index 71423f9cfc95d..9d68d26245acd 100644 --- a/libavcodec/pixblockdsp.c +++ b/libavcodec/pixblockdsp.c @@ -31,7 +31,7 @@ #include "pixblockdsp_template.c" static void diff_pixels_c(int16_t *restrict block, const uint8_t *s1, - const uint8_t *s2, int stride) + const uint8_t *s2, ptrdiff_t stride) { int i; diff --git a/libavcodec/pixblockdsp.h b/libavcodec/pixblockdsp.h index 8094d14b68e6d..a9d5473665eb1 100644 --- a/libavcodec/pixblockdsp.h +++ b/libavcodec/pixblockdsp.h @@ -26,11 +26,11 @@ typedef struct PixblockDSPContext { void (*get_pixels)(int16_t *block /* align 16 */, const uint8_t *pixels /* align 8 */, - int line_size); + ptrdiff_t stride); void (*diff_pixels)(int16_t *block /* align 16 */, const uint8_t *s1 /* align 8 */, const uint8_t *s2 /* align 8 */, - int stride); + ptrdiff_t stride); } PixblockDSPContext; void ff_pixblockdsp_init(PixblockDSPContext *c, AVCodecContext *avctx); diff --git a/libavcodec/pixblockdsp_template.c b/libavcodec/pixblockdsp_template.c index 71d3cf150d689..3d86e2cc6365d 100644 --- a/libavcodec/pixblockdsp_template.c +++ b/libavcodec/pixblockdsp_template.c @@ -19,7 +19,7 @@ #include "bit_depth_template.c" static void FUNCC(get_pixels)(int16_t *restrict block, const uint8_t *_pixels, - int line_size) + ptrdiff_t stride) { const pixel *pixels = (const pixel *) _pixels; int i; @@ -34,7 +34,7 @@ static void FUNCC(get_pixels)(int16_t *restrict block, const uint8_t *_pixels, block[5] = pixels[5]; block[6] = pixels[6]; block[7] = pixels[7]; - pixels += line_size / sizeof(pixel); + pixels += stride / sizeof(pixel); block += 8; } } diff --git a/libavcodec/ppc/pixblockdsp.c b/libavcodec/ppc/pixblockdsp.c index 00e79495c384d..96e702452f15e 100644 --- a/libavcodec/ppc/pixblockdsp.c +++ b/libavcodec/ppc/pixblockdsp.c @@ -36,7 +36,7 @@ #if HAVE_ALTIVEC && HAVE_BIGENDIAN static void get_pixels_altivec(int16_t *restrict block, const uint8_t *pixels, - int line_size) + ptrdiff_t stride) { int i; vec_u8 perm = vec_lvsl(0, pixels); @@ -56,12 +56,12 @@ static void get_pixels_altivec(int16_t *restrict block, const uint8_t *pixels, // Save the data to the block, we assume the block is 16-byte aligned. vec_st(shorts, i * 16, (vec_s16 *)block); - pixels += line_size; + pixels += stride; } } static void diff_pixels_altivec(int16_t *restrict block, const uint8_t *s1, - const uint8_t *s2, int stride) + const uint8_t *s2, ptrdiff_t stride) { int i; vec_u8 perm1 = vec_lvsl(0, s1); @@ -135,7 +135,7 @@ static void diff_pixels_altivec(int16_t *restrict block, const uint8_t *s1, #if HAVE_VSX static void get_pixels_vsx(int16_t *restrict block, const uint8_t *pixels, - int line_size) + ptrdiff_t stride) { int i; for (i = 0; i < 8; i++) { @@ -143,12 +143,12 @@ static void get_pixels_vsx(int16_t *restrict block, const uint8_t *pixels, vec_vsx_st(shorts, i * 16, block); - pixels += line_size; + pixels += stride; } } static void diff_pixels_vsx(int16_t *restrict block, const uint8_t *s1, - const uint8_t *s2, int stride) + const uint8_t *s2, ptrdiff_t stride) { int i; vec_s16 shorts1, shorts2; diff --git a/libavcodec/x86/pixblockdsp.asm b/libavcodec/x86/pixblockdsp.asm index c8fd1b24a1300..871244297c724 100644 --- a/libavcodec/x86/pixblockdsp.asm +++ b/libavcodec/x86/pixblockdsp.asm @@ -26,9 +26,8 @@ SECTION .text INIT_MMX mmx -; void ff_get_pixels_mmx(int16_t *block, const uint8_t *pixels, int line_size) +; void ff_get_pixels_mmx(int16_t *block, const uint8_t *pixels, ptrdiff_t stride) cglobal get_pixels, 3,4 - movsxdifnidn r2, r2d add r0, 128 mov r3, -128 pxor m7, m7 @@ -52,7 +51,6 @@ cglobal get_pixels, 3,4 INIT_XMM sse2 cglobal get_pixels, 3, 4 - movsxdifnidn r2, r2d lea r3, [r2*3] pxor m4, m4 movh m0, [r1] @@ -84,9 +82,8 @@ cglobal get_pixels, 3, 4 INIT_MMX mmx ; void ff_diff_pixels_mmx(int16_t *block, const uint8_t *s1, const uint8_t *s2, -; int stride); +; ptrdiff_t stride); cglobal diff_pixels, 4,5 - movsxdifnidn r3, r3d pxor m7, m7 add r0, 128 mov r4, -128 diff --git a/libavcodec/x86/pixblockdsp_init.c b/libavcodec/x86/pixblockdsp_init.c index 9582e0b5c2870..faa5141327e8f 100644 --- a/libavcodec/x86/pixblockdsp_init.c +++ b/libavcodec/x86/pixblockdsp_init.c @@ -23,10 +23,10 @@ #include "libavutil/x86/cpu.h" #include "libavcodec/pixblockdsp.h" -void ff_get_pixels_mmx(int16_t *block, const uint8_t *pixels, int line_size); -void ff_get_pixels_sse2(int16_t *block, const uint8_t *pixels, int line_size); +void ff_get_pixels_mmx(int16_t *block, const uint8_t *pixels, ptrdiff_t stride); +void ff_get_pixels_sse2(int16_t *block, const uint8_t *pixels, ptrdiff_t stride); void ff_diff_pixels_mmx(int16_t *block, const uint8_t *s1, const uint8_t *s2, - int stride); + ptrdiff_t stride); av_cold void ff_pixblockdsp_init_x86(PixblockDSPContext *c, AVCodecContext *avctx, From 09a145b3c837273b1379321e44386a3233156e75 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Mon, 12 Sep 2016 22:37:20 +0100 Subject: [PATCH 0156/3374] hwcontext_vdpau: Remove duplicate definition of GET_CALLBACK --- libavutil/hwcontext_vdpau.c | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/libavutil/hwcontext_vdpau.c b/libavutil/hwcontext_vdpau.c index 9722c10b877ef..4860aaabdff71 100644 --- a/libavutil/hwcontext_vdpau.c +++ b/libavutil/hwcontext_vdpau.c @@ -127,13 +127,6 @@ static int vdpau_init_pixmfts(AVHWDeviceContext *ctx) return 0; } -static int vdpau_device_init(AVHWDeviceContext *ctx) -{ - AVVDPAUDeviceContext *hwctx = ctx->hwctx; - VDPAUDeviceContext *priv = ctx->internal->priv; - VdpStatus err; - int ret; - #define GET_CALLBACK(id, result) \ do { \ void *tmp; \ @@ -142,15 +135,22 @@ do { av_log(ctx, AV_LOG_ERROR, "Error getting the " #id " callback.\n"); \ return AVERROR_UNKNOWN; \ } \ - priv->result = tmp; \ + result = tmp; \ } while (0) +static int vdpau_device_init(AVHWDeviceContext *ctx) +{ + AVVDPAUDeviceContext *hwctx = ctx->hwctx; + VDPAUDeviceContext *priv = ctx->internal->priv; + VdpStatus err; + int ret; + GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES, - get_transfer_caps); - GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, get_data); - GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR, put_data); - GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_CREATE, surf_create); - GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_DESTROY, surf_destroy); + priv->get_transfer_caps); + GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, priv->get_data); + GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR, priv->put_data); + GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_CREATE, priv->surf_create); + GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_DESTROY, priv->surf_destroy); ret = vdpau_init_pixmfts(ctx); if (ret < 0) { @@ -444,17 +444,6 @@ static int vdpau_device_create(AVHWDeviceContext *ctx, const char *device, return AVERROR_UNKNOWN; } -#define GET_CALLBACK(id, result) \ -do { \ - void *tmp; \ - err = hwctx->get_proc_address(hwctx->device, id, &tmp); \ - if (err != VDP_STATUS_OK) { \ - av_log(ctx, AV_LOG_ERROR, "Error getting the " #id " callback.\n"); \ - return AVERROR_UNKNOWN; \ - } \ - result = tmp; \ -} while (0) - GET_CALLBACK(VDP_FUNC_ID_GET_INFORMATION_STRING, get_information_string); GET_CALLBACK(VDP_FUNC_ID_DEVICE_DESTROY, priv->device_destroy); From 7081620aca36e616ea96f71fd71d2703e3abae09 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Tue, 13 Sep 2016 20:45:55 +0100 Subject: [PATCH 0157/3374] hwcontext_vdpau: Fix missing subscripts Also remove the redundant casts which were hiding the error here. --- libavutil/hwcontext_vdpau.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavutil/hwcontext_vdpau.c b/libavutil/hwcontext_vdpau.c index 4860aaabdff71..b12109c4b58c9 100644 --- a/libavutil/hwcontext_vdpau.c +++ b/libavutil/hwcontext_vdpau.c @@ -304,7 +304,7 @@ static int vdpau_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, for (i = 0; i< FF_ARRAY_ELEMS(data) && dst->data[i]; i++) { data[i] = dst->data[i]; - if (dst->linesize[i] < 0 || (uint64_t)dst->linesize > UINT32_MAX) { + if (dst->linesize[i] < 0 || dst->linesize[i] > UINT32_MAX) { av_log(ctx, AV_LOG_ERROR, "The linesize %d cannot be represented as uint32\n", dst->linesize[i]); @@ -355,7 +355,7 @@ static int vdpau_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, for (i = 0; i< FF_ARRAY_ELEMS(data) && src->data[i]; i++) { data[i] = src->data[i]; - if (src->linesize[i] < 0 || (uint64_t)src->linesize > UINT32_MAX) { + if (src->linesize[i] < 0 || src->linesize[i] > UINT32_MAX) { av_log(ctx, AV_LOG_ERROR, "The linesize %d cannot be represented as uint32\n", src->linesize[i]); From 3a9662af6c741f8354b1ca97642f78f5c02e2e8f Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Tue, 13 Sep 2016 00:25:07 +0100 Subject: [PATCH 0158/3374] vaapi_h264: Fix HRD bit_rate/cpb_size scaling There should be an extra offset of 6 on bit_rate_scale and of 4 on cpb_size_scale which were not accounted for here. --- libavcodec/vaapi_encode_h264.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index 5bd56057cdb3a..9d6ff27a96110 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -861,14 +861,14 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) // Try to scale these to a sensible range so that the // golomb encode of the value is not overlong. mseq->bit_rate_scale = - av_clip(av_log2(avctx->bit_rate) - 15, 0, 15); + av_clip_uintp2(av_log2(avctx->bit_rate) - 15 - 6, 4); mseq->bit_rate_value_minus1[0] = - (avctx->bit_rate >> mseq->bit_rate_scale) - 1; + (avctx->bit_rate >> mseq->bit_rate_scale + 6) - 1; mseq->cpb_size_scale = - av_clip(av_log2(priv->hrd_params.hrd.buffer_size) - 15, 0, 15); + av_clip_uintp2(av_log2(priv->hrd_params.hrd.buffer_size) - 15 - 4, 4); mseq->cpb_size_value_minus1[0] = - (priv->hrd_params.hrd.buffer_size >> mseq->cpb_size_scale) - 1; + (priv->hrd_params.hrd.buffer_size >> mseq->cpb_size_scale + 4) - 1; // CBR mode isn't actually available here, despite naming. mseq->cbr_flag[0] = 0; From bdf7610eb266fd3de650040c97328791868abd82 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Tue, 13 Sep 2016 20:50:57 +0100 Subject: [PATCH 0159/3374] vf_scale_vaapi: Crop input surface to active region If the input has been decoded from a stream which uses edge cropping then the whole surface need not be valid. This defines an input region for the scaler so we only use the active area of the frame. --- libavfilter/vf_scale_vaapi.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libavfilter/vf_scale_vaapi.c b/libavfilter/vf_scale_vaapi.c index 561e09c4dc649..704456dd390b7 100644 --- a/libavfilter/vf_scale_vaapi.c +++ b/libavfilter/vf_scale_vaapi.c @@ -259,6 +259,7 @@ static int scale_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame) VASurfaceID input_surface, output_surface; VAProcPipelineParameterBuffer params; VABufferID params_id; + VARectangle input_region; VAStatus vas; int err; @@ -292,8 +293,17 @@ static int scale_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame) memset(¶ms, 0, sizeof(params)); + // If there were top/left cropping, it could be taken into + // account here. + input_region = (VARectangle) { + .x = 0, + .y = 0, + .width = input_frame->width, + .height = input_frame->height, + }; + params.surface = input_surface; - params.surface_region = 0; + params.surface_region = &input_region; params.surface_color_standard = vaapi_proc_colour_standard(input_frame->colorspace); From df3795025337479a639cb3cd26c93a4e82ccd4db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 15 Sep 2016 14:21:38 +0300 Subject: [PATCH 0160/3374] rtsp: Fix a crash with the RTSP muxer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was introduced in bc2a32969e. The whole block that the statement was added to is only relevant when used as a demuxer, but the other statements there have had other if statements guarding them. Make sure to only run this whole block if being used as a demuxer. CC: libav-stable@libav.org Signed-off-by: Martin Storsjö --- libavformat/rtsp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index b9416d26066a9..84b912f7f2d8e 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -827,7 +827,8 @@ int ff_rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st) if (!rtsp_st->transport_priv) { return AVERROR(ENOMEM); - } else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RTP) { + } else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RTP && + s->iformat) { RTPDemuxContext *rtpctx = rtsp_st->transport_priv; rtpctx->ssrc = rtsp_st->ssrc; if (rtsp_st->dynamic_handler) { From bc7399934def210c2a84ea51375d50f79c676c96 Mon Sep 17 00:00:00 2001 From: Josh de Kock Date: Sun, 24 Jul 2016 20:55:42 +0100 Subject: [PATCH 0161/3374] libdc1394: Distinguish between enumeration errors and no cameras found Signed-off-by: Diego Biurrun --- libavdevice/libdc1394.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libavdevice/libdc1394.c b/libavdevice/libdc1394.c index a0ea592c9fab2..c823388a76f95 100644 --- a/libavdevice/libdc1394.c +++ b/libavdevice/libdc1394.c @@ -299,9 +299,14 @@ static int dc1394_v2_read_header(AVFormatContext *c) /* Now let us prep the hardware. */ dc1394->d = dc1394_new(); - dc1394_camera_enumerate (dc1394->d, &list); - if ( !list || list->num == 0) { - av_log(c, AV_LOG_ERROR, "Unable to look for an IIDC camera\n\n"); + if (dc1394_camera_enumerate(dc1394->d, &list) != DC1394_SUCCESS || !list) { + av_log(c, AV_LOG_ERROR, "Unable to look for an IIDC camera.\n"); + goto out; + } + + if (list->num == 0) { + av_log(c, AV_LOG_ERROR, "No cameras found.\n"); + dc1394_camera_free_list(list); goto out; } From 8c201dde0ab62e5cd581d958e78d7609e0ba710d Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 12 Sep 2016 17:42:28 +0200 Subject: [PATCH 0162/3374] build: doc: more fine-grained dependencies for generated texi files --- doc/Makefile | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/Makefile b/doc/Makefile index 2f6a5fb0c1985..c464a4869e43d 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -1,7 +1,8 @@ ALLMANPAGES = $(AVBASENAMES:%=%.1) MANPAGES = $(AVPROGS-yes:%=doc/%.1) PODPAGES = $(AVPROGS-yes:%=doc/%.pod) -HTMLPAGES = $(AVPROGS-yes:%=doc/%.html) \ +PROGSHTML = $(AVPROGS-yes:%=doc/%.html) +HTMLPAGES = $(PROGSHTML) \ doc/developer.html \ doc/faq.html \ doc/fate.html \ @@ -39,22 +40,24 @@ TEXIDEP = awk '/^@include/ { printf "$@: $(@D)/%s\n", $$2 }' <$< >$(@:%=%.d) GENTEXI = format codec GENTEXI := $(GENTEXI:%=doc/avoptions_%.texi) +$(MANPAGES) $(PODPAGES) $(PROGSHTML): $(GENTEXI) + $(GENTEXI): TAG = GENTEXI $(GENTEXI): doc/avoptions_%.texi: doc/print_options$(HOSTEXESUF) $(M)doc/print_options $* > $@ doc/%.html: TAG = HTML -doc/%.html: doc/%.texi $(SRC_PATH)/doc/t2h.init $(GENTEXI) +doc/%.html: doc/%.texi $(SRC_PATH)/doc/t2h.init $(Q)$(TEXIDEP) $(M)texi2html -I doc -monolithic --init-file $(SRC_PATH)/doc/t2h.init --output $@ $< doc/%.pod: TAG = POD -doc/%.pod: doc/%.texi $(SRC_PATH)/doc/texi2pod.pl $(GENTEXI) +doc/%.pod: doc/%.texi $(SRC_PATH)/doc/texi2pod.pl $(Q)$(TEXIDEP) $(M)$(SRC_PATH)/doc/texi2pod.pl -Idoc $< $@ doc/%.1: TAG = MAN -doc/%.1: doc/%.pod $(GENTEXI) +doc/%.1: doc/%.pod $(M)pod2man --section=1 --center=" " --release=" " $< > $@ $(DOCS) doc/doxy/html: | doc/ From 15fcf6292ed79be274c824fedb099c2665f4cc15 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Mon, 12 Sep 2016 21:52:01 +0200 Subject: [PATCH 0163/3374] build: remove hardcoded name of version header Fixes an oversight in 1316df7aa98c4. CC: libav-stable@libav.org --- version.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.sh b/version.sh index 6f72b2c2e6ee6..4689627869c6d 100755 --- a/version.sh +++ b/version.sh @@ -18,7 +18,7 @@ if [ -z "$2" ]; then fi NEW_REVISION="#define LIBAV_VERSION \"$version\"" -OLD_REVISION=$(cat version.h 2> /dev/null) +OLD_REVISION=$(cat "$2" 2> /dev/null) # Update version.h only on revision changes to avoid spurious rebuilds if test "$NEW_REVISION" != "$OLD_REVISION"; then From 136f55207521f0b03194ef5b55ba70f1635d6aee Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 12 Nov 2013 16:11:42 +0100 Subject: [PATCH 0164/3374] mpegvideo_motion: Handle edge emulation even without unrestricted_mv Fix out of bounds read. Bug-Id: 962 Found by: F4B3CD@STARLAB and Agostino Sarubbo Signed-off-by: Vittorio Giovara --- libavcodec/mpegvideo_motion.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/libavcodec/mpegvideo_motion.c b/libavcodec/mpegvideo_motion.c index 8074dbaa9f742..f6d9613b3ca85 100644 --- a/libavcodec/mpegvideo_motion.c +++ b/libavcodec/mpegvideo_motion.c @@ -210,17 +210,14 @@ static inline int hpel_motion(MpegEncContext *s, dxy |= (motion_y & 1) << 1; src += src_y * s->linesize + src_x; - if (s->unrestricted_mv) { - if ((unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x & 1) - 8, 0) || - (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y & 1) - 8, 0)) { - s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, src, - s->linesize, s->linesize, - 9, 9, - src_x, src_y, s->h_edge_pos, - s->v_edge_pos); - src = s->sc.edge_emu_buffer; - emu = 1; - } + if ((unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x & 1) - 8, 0) || + (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y & 1) - 8, 0)) { + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, src, + s->linesize, s->linesize, + 9, 9, src_x, src_y, + s->h_edge_pos, s->v_edge_pos); + src = s->sc.edge_emu_buffer; + emu = 1; } pix_op[dxy](dest, src, s->linesize, 8); return emu; From de64dd13cbd47fd54334b6aa2a2cd3c7c36daae2 Mon Sep 17 00:00:00 2001 From: Yogender Gupta Date: Sat, 17 Sep 2016 15:28:27 +0200 Subject: [PATCH 0165/3374] avcodec: Add the extended pixel format profile for HEVC It is supported by the NVIDIA video SDK 7. Signed-off-by: Luca Barbato --- doc/APIchanges | 3 +++ libavcodec/avcodec.h | 1 + libavcodec/version.h | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index a4e418acd3710..43e32623f7634 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-xx-xx - xxxxxxx - lavc 59.27.0 - avcodec.h + Add FF_PROFILE_HEVC_REXT, the extended pixel format profile for HEVC. + 2016-08-24 - xxxxxxx - lavu 55.21.0 - imgutils.h Add av_image_copy_uc_from(), a version of av_image_copy() for copying from GPU mapped memory. diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 7a5f10f1c9833..607688cf6f4c3 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -2961,6 +2961,7 @@ typedef struct AVCodecContext { #define FF_PROFILE_HEVC_MAIN 1 #define FF_PROFILE_HEVC_MAIN_10 2 #define FF_PROFILE_HEVC_MAIN_STILL_PICTURE 3 +#define FF_PROFILE_HEVC_REXT 4 /** * level diff --git a/libavcodec/version.h b/libavcodec/version.h index b132bf7071bee..20edb611d8429 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 26 +#define LIBAVCODEC_VERSION_MINOR 27 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ From 07e1f99a1bb41d1a615676140eefc85cf69fa793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 10 Sep 2016 20:41:43 +0200 Subject: [PATCH 0166/3374] x86util: Document SBUTTERFLY macro Signed-off-by: Luca Barbato --- libavutil/x86/x86util.asm | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libavutil/x86/x86util.asm b/libavutil/x86/x86util.asm index 16a9baef7a82b..bba958ebfc9c4 100644 --- a/libavutil/x86/x86util.asm +++ b/libavutil/x86/x86util.asm @@ -29,6 +29,16 @@ %include "libavutil/x86/x86inc.asm" +; Interleave low src0 with low src1 and store in src0, +; interleave high src0 with high src1 and store in src1. +; %1 - types +; %2 - index of the register with src0 +; %3 - index of the register with src1 +; %4 - index of the register for intermediate results +; example for %1 - wd: input: src0: x0 x1 x2 x3 z0 z1 z2 z3 +; src1: y0 y1 y2 y3 q0 q1 q2 q3 +; output: src0: x0 y0 x1 y1 x2 y2 x3 y3 +; src1: z0 q0 z1 q1 z2 q2 z3 q3 %macro SBUTTERFLY 4 %if avx_enabled == 0 mova m%4, m%2 From 1d6c76e11febb58738c9647c47079d02b5e10094 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 9 Aug 2016 14:17:15 +0200 Subject: [PATCH 0167/3374] audiodsp/x86: fix ff_vector_clip_int32_sse2 This version, which is the only one doing two processing cycles per loop iteration, computes the load/store indices incorrectly for the second cycle. CC: libav-stable@libav.org --- libavcodec/x86/audiodsp.asm | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/libavcodec/x86/audiodsp.asm b/libavcodec/x86/audiodsp.asm index 696a73bd81df7..dc38ada71f21b 100644 --- a/libavcodec/x86/audiodsp.asm +++ b/libavcodec/x86/audiodsp.asm @@ -80,17 +80,17 @@ cglobal vector_clip_int32%5, 5,5,%1, dst, src, min, max, len SPLATD m4 SPLATD m5 .loop: -%assign %%i 1 +%assign %%i 0 %rep %2 - mova m0, [srcq+mmsize*0*%%i] - mova m1, [srcq+mmsize*1*%%i] - mova m2, [srcq+mmsize*2*%%i] - mova m3, [srcq+mmsize*3*%%i] + mova m0, [srcq + mmsize * (0 + %%i)] + mova m1, [srcq + mmsize * (1 + %%i)] + mova m2, [srcq + mmsize * (2 + %%i)] + mova m3, [srcq + mmsize * (3 + %%i)] %if %3 - mova m7, [srcq+mmsize*4*%%i] - mova m8, [srcq+mmsize*5*%%i] - mova m9, [srcq+mmsize*6*%%i] - mova m10, [srcq+mmsize*7*%%i] + mova m7, [srcq + mmsize * (4 + %%i)] + mova m8, [srcq + mmsize * (5 + %%i)] + mova m9, [srcq + mmsize * (6 + %%i)] + mova m10, [srcq + mmsize * (7 + %%i)] %endif CLIPD m0, m4, m5, m6 CLIPD m1, m4, m5, m6 @@ -102,17 +102,17 @@ cglobal vector_clip_int32%5, 5,5,%1, dst, src, min, max, len CLIPD m9, m4, m5, m6 CLIPD m10, m4, m5, m6 %endif - mova [dstq+mmsize*0*%%i], m0 - mova [dstq+mmsize*1*%%i], m1 - mova [dstq+mmsize*2*%%i], m2 - mova [dstq+mmsize*3*%%i], m3 + mova [dstq + mmsize * (0 + %%i)], m0 + mova [dstq + mmsize * (1 + %%i)], m1 + mova [dstq + mmsize * (2 + %%i)], m2 + mova [dstq + mmsize * (3 + %%i)], m3 %if %3 - mova [dstq+mmsize*4*%%i], m7 - mova [dstq+mmsize*5*%%i], m8 - mova [dstq+mmsize*6*%%i], m9 - mova [dstq+mmsize*7*%%i], m10 + mova [dstq + mmsize * (4 + %%i)], m7 + mova [dstq + mmsize * (5 + %%i)], m8 + mova [dstq + mmsize * (6 + %%i)], m9 + mova [dstq + mmsize * (7 + %%i)], m10 %endif -%assign %%i %%i+1 +%assign %%i (%%i + 4 * (1 + %3)) %endrep add srcq, mmsize*4*(%2+%3) add dstq, mmsize*4*(%2+%3) From 75d98e30afab61542faab3c0f11880834653bd6b Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 9 Aug 2016 14:17:15 +0200 Subject: [PATCH 0168/3374] audiodsp/x86: clear the high bits of the order parameter on 64bit Also change shl to add, since it can be faster on some CPUs. CC: libav-stable@libav.org --- libavcodec/x86/audiodsp.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/x86/audiodsp.asm b/libavcodec/x86/audiodsp.asm index dc38ada71f21b..d7e63eb0cbc19 100644 --- a/libavcodec/x86/audiodsp.asm +++ b/libavcodec/x86/audiodsp.asm @@ -26,7 +26,7 @@ SECTION .text %macro SCALARPRODUCT 0 ; int ff_scalarproduct_int16(int16_t *v1, int16_t *v2, int order) cglobal scalarproduct_int16, 3,3,3, v1, v2, order - shl orderq, 1 + add orderd, orderd add v1q, orderq add v2q, orderq neg orderq From 340f12f71207513672b5165d810cb6c8622c6b21 Mon Sep 17 00:00:00 2001 From: Yogender Kumar Gupta Date: Mon, 19 Sep 2016 20:01:10 +0530 Subject: [PATCH 0169/3374] hwcontext_cuda: Add P010 and YUV444P16 pixel format Signed-off-by: Anton Khirnov --- libavutil/hwcontext_cuda.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/libavutil/hwcontext_cuda.c b/libavutil/hwcontext_cuda.c index b8781cec1b647..260783426a7f6 100644 --- a/libavutil/hwcontext_cuda.c +++ b/libavutil/hwcontext_cuda.c @@ -32,7 +32,9 @@ typedef struct CUDAFramesContext { static const enum AVPixelFormat supported_formats[] = { AV_PIX_FMT_NV12, AV_PIX_FMT_YUV420P, + AV_PIX_FMT_P010, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUV444P16, }; static void cuda_buffer_free(void *opaque, uint8_t *data) @@ -105,9 +107,15 @@ static int cuda_frames_init(AVHWFramesContext *ctx) case AV_PIX_FMT_YUV420P: size = ctx->width * ctx->height * 3 / 2; break; + case AV_PIX_FMT_P010: + size = ctx->width * ctx->height * 3; + break; case AV_PIX_FMT_YUV444P: size = ctx->width * ctx->height * 3; break; + case AV_PIX_FMT_YUV444P16: + size = ctx->width * ctx->height * 6; + break; } ctx->internal->pool_internal = av_buffer_pool_init2(size, ctx, cuda_pool_alloc, NULL); @@ -139,6 +147,12 @@ static int cuda_get_buffer(AVHWFramesContext *ctx, AVFrame *frame) frame->linesize[1] = ctx->width / 2; frame->linesize[2] = ctx->width / 2; break; + case AV_PIX_FMT_P010: + frame->data[0] = frame->buf[0]->data; + frame->data[1] = frame->data[0] + 2 * ctx->width * ctx->height; + frame->linesize[0] = 2 * ctx->width; + frame->linesize[1] = 2 * ctx->width; + break; case AV_PIX_FMT_YUV444P: frame->data[0] = frame->buf[0]->data; frame->data[1] = frame->data[0] + ctx->width * ctx->height; @@ -147,6 +161,14 @@ static int cuda_get_buffer(AVHWFramesContext *ctx, AVFrame *frame) frame->linesize[1] = ctx->width; frame->linesize[2] = ctx->width; break; + case AV_PIX_FMT_YUV444P16: + frame->data[0] = frame->buf[0]->data; + frame->data[1] = frame->data[0] + 2 * ctx->width * ctx->height; + frame->data[2] = frame->data[1] + 2 * ctx->width * ctx->height; + frame->linesize[0] = 2 * ctx->width; + frame->linesize[1] = 2 * ctx->width; + frame->linesize[2] = 2 * ctx->width; + break; default: av_frame_unref(frame); return AVERROR_BUG; From 683da86aabb4fbeddc3ead5fce737c63c0ee762c Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 4 Sep 2016 14:45:48 +0200 Subject: [PATCH 0170/3374] audiodsp: reorder arguments for vector_clipf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will make the x86 asm simpler. ARM conversion by Martin Storsjö and Janne Grunau --- libavcodec/ac3enc_float.c | 2 +- libavcodec/arm/audiodsp_init_neon.c | 3 +-- libavcodec/arm/audiodsp_neon.S | 5 ++--- libavcodec/audiodsp.c | 4 ++-- libavcodec/audiodsp.h | 3 ++- libavcodec/cook.c | 2 +- libavcodec/x86/audiodsp.h | 2 +- libavcodec/x86/audiodsp_mmx.c | 2 +- tests/checkasm/audiodsp.c | 8 ++++---- 9 files changed, 15 insertions(+), 16 deletions(-) diff --git a/libavcodec/ac3enc_float.c b/libavcodec/ac3enc_float.c index 822f431b44cf9..968cb2c533719 100644 --- a/libavcodec/ac3enc_float.c +++ b/libavcodec/ac3enc_float.c @@ -111,7 +111,7 @@ static void scale_coefficients(AC3EncodeContext *s) static void clip_coefficients(AudioDSPContext *adsp, float *coef, unsigned int len) { - adsp->vector_clipf(coef, coef, COEF_MIN, COEF_MAX, len); + adsp->vector_clipf(coef, coef, len, COEF_MIN, COEF_MAX); } diff --git a/libavcodec/arm/audiodsp_init_neon.c b/libavcodec/arm/audiodsp_init_neon.c index af532724c870e..08405cb829aad 100644 --- a/libavcodec/arm/audiodsp_init_neon.c +++ b/libavcodec/arm/audiodsp_init_neon.c @@ -25,8 +25,7 @@ #include "libavcodec/audiodsp.h" #include "audiodsp_arm.h" -void ff_vector_clipf_neon(float *dst, const float *src, float min, float max, - int len); +void ff_vector_clipf_neon(float *dst, const float *src, int len, float min, float max); void ff_vector_clip_int32_neon(int32_t *dst, const int32_t *src, int32_t min, int32_t max, unsigned int len); diff --git a/libavcodec/arm/audiodsp_neon.S b/libavcodec/arm/audiodsp_neon.S index dfb998de32375..5871b82c2ca1b 100644 --- a/libavcodec/arm/audiodsp_neon.S +++ b/libavcodec/arm/audiodsp_neon.S @@ -24,9 +24,8 @@ function ff_vector_clipf_neon, export=1 VFP vdup.32 q1, d0[1] VFP vdup.32 q0, d0[0] -NOVFP vdup.32 q0, r2 -NOVFP vdup.32 q1, r3 -NOVFP ldr r2, [sp] +NOVFP vdup.32 q0, r3 +NOVFP vld1.32 {d2[],d3[]}, [sp] vld1.f32 {q2},[r1,:128]! vmin.f32 q10, q2, q1 vld1.f32 {q3},[r1,:128]! diff --git a/libavcodec/audiodsp.c b/libavcodec/audiodsp.c index f7e6167cb0fda..776cd11ce1a20 100644 --- a/libavcodec/audiodsp.c +++ b/libavcodec/audiodsp.c @@ -55,8 +55,8 @@ static void vector_clipf_c_opposite_sign(float *dst, const float *src, } } -static void vector_clipf_c(float *dst, const float *src, - float min, float max, int len) +static void vector_clipf_c(float *dst, const float *src, int len, + float min, float max) { int i; diff --git a/libavcodec/audiodsp.h b/libavcodec/audiodsp.h index e48cdb092eec2..2b4f9d44e22d6 100644 --- a/libavcodec/audiodsp.h +++ b/libavcodec/audiodsp.h @@ -48,7 +48,8 @@ typedef struct AudioDSPContext { /* assume len is a multiple of 16, and arrays are 16-byte aligned */ void (*vector_clipf)(float *dst /* align 16 */, const float *src /* align 16 */, - float min, float max, int len /* align 16 */); + int len /* align 16 */, + float min, float max); } AudioDSPContext; void ff_audiodsp_init(AudioDSPContext *c); diff --git a/libavcodec/cook.c b/libavcodec/cook.c index 016b1d01bb8d3..c990333a7cd93 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -867,7 +867,7 @@ static inline void decode_bytes_and_gain(COOKContext *q, COOKSubpacket *p, static void saturate_output_float(COOKContext *q, float *out) { q->adsp.vector_clipf(out, q->mono_mdct_output + q->samples_per_channel, - -1.0f, 1.0f, FFALIGN(q->samples_per_channel, 8)); + FFALIGN(q->samples_per_channel, 8), -1.0f, 1.0f); } diff --git a/libavcodec/x86/audiodsp.h b/libavcodec/x86/audiodsp.h index 321056b8b7821..c87ee45193e5a 100644 --- a/libavcodec/x86/audiodsp.h +++ b/libavcodec/x86/audiodsp.h @@ -20,6 +20,6 @@ #define AVCODEC_X86_AUDIODSP_H void ff_vector_clipf_sse(float *dst, const float *src, - float min, float max, int len); + int len, float min, float max); #endif /* AVCODEC_X86_AUDIODSP_H */ diff --git a/libavcodec/x86/audiodsp_mmx.c b/libavcodec/x86/audiodsp_mmx.c index cb550598f90f4..04cbb90706b3d 100644 --- a/libavcodec/x86/audiodsp_mmx.c +++ b/libavcodec/x86/audiodsp_mmx.c @@ -23,7 +23,7 @@ #if HAVE_INLINE_ASM void ff_vector_clipf_sse(float *dst, const float *src, - float min, float max, int len) + int len, float min, float max) { x86_reg i = (len - 16) * 4; __asm__ volatile ( diff --git a/tests/checkasm/audiodsp.c b/tests/checkasm/audiodsp.c index 456b90bfeced3..40fa3844e8d35 100644 --- a/tests/checkasm/audiodsp.c +++ b/tests/checkasm/audiodsp.c @@ -120,7 +120,7 @@ void checkasm_check_audiodsp(void) int i, len; declare_func_emms(AV_CPU_FLAG_MMX, void, float *dst, const float *src, - float min, float max, unsigned int len); + int len, float min, float max); val1 = (float)rnd() / (UINT_MAX >> 1) - 1.0f; val2 = (float)rnd() / (UINT_MAX >> 1) - 1.0f; @@ -133,13 +133,13 @@ void checkasm_check_audiodsp(void) len = rnd() % 128; len = 16 * FFMAX(len, 1); - call_ref(dst0, src, min, max, len); - call_new(dst1, src, min, max, len); + call_ref(dst0, src, len, min, max); + call_new(dst1, src, len, min, max); for (i = 0; i < len; i++) { if (!float_near_ulp_array(dst0, dst1, 3, len)) fail(); } - bench_new(dst1, src, min, max, MAX_SIZE); + bench_new(dst1, src, MAX_SIZE, min, max); } report("audiodsp"); From eea9857bfd6925d0c34382c00b971ee6df12ad44 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 8 Aug 2016 21:47:20 +0200 Subject: [PATCH 0171/3374] blockdsp: drop the high_bit_depth parameter It has no effect, since the code is supposed to operate the same way for any bit depth. --- libavcodec/arm/blockdsp_arm.h | 2 +- libavcodec/arm/blockdsp_init_arm.c | 4 ++-- libavcodec/arm/blockdsp_init_neon.c | 8 +++----- libavcodec/blockdsp.c | 10 ++++------ libavcodec/blockdsp.h | 8 ++++---- libavcodec/ppc/blockdsp.c | 25 +++++++++++-------------- libavcodec/x86/blockdsp.c | 20 +++++++++----------- 7 files changed, 34 insertions(+), 43 deletions(-) diff --git a/libavcodec/arm/blockdsp_arm.h b/libavcodec/arm/blockdsp_arm.h index 6d9c2c3ed28b2..d26630e102071 100644 --- a/libavcodec/arm/blockdsp_arm.h +++ b/libavcodec/arm/blockdsp_arm.h @@ -21,6 +21,6 @@ #include "libavcodec/blockdsp.h" -void ff_blockdsp_init_neon(BlockDSPContext *c, unsigned high_bit_depth); +void ff_blockdsp_init_neon(BlockDSPContext *c); #endif /* AVCODEC_ARM_BLOCKDSP_ARM_H */ diff --git a/libavcodec/arm/blockdsp_init_arm.c b/libavcodec/arm/blockdsp_init_arm.c index a0c03674d7857..a5db20170520e 100644 --- a/libavcodec/arm/blockdsp_init_arm.c +++ b/libavcodec/arm/blockdsp_init_arm.c @@ -24,10 +24,10 @@ #include "libavcodec/blockdsp.h" #include "blockdsp_arm.h" -av_cold void ff_blockdsp_init_arm(BlockDSPContext *c, unsigned high_bit_depth) +av_cold void ff_blockdsp_init_arm(BlockDSPContext *c) { int cpu_flags = av_get_cpu_flags(); if (have_neon(cpu_flags)) - ff_blockdsp_init_neon(c, high_bit_depth); + ff_blockdsp_init_neon(c); } diff --git a/libavcodec/arm/blockdsp_init_neon.c b/libavcodec/arm/blockdsp_init_neon.c index 5081cf0cdffd1..e2857508f2937 100644 --- a/libavcodec/arm/blockdsp_init_neon.c +++ b/libavcodec/arm/blockdsp_init_neon.c @@ -28,10 +28,8 @@ void ff_clear_block_neon(int16_t *block); void ff_clear_blocks_neon(int16_t *blocks); -av_cold void ff_blockdsp_init_neon(BlockDSPContext *c, unsigned high_bit_depth) +av_cold void ff_blockdsp_init_neon(BlockDSPContext *c) { - if (!high_bit_depth) { - c->clear_block = ff_clear_block_neon; - c->clear_blocks = ff_clear_blocks_neon; - } + c->clear_block = ff_clear_block_neon; + c->clear_blocks = ff_clear_blocks_neon; } diff --git a/libavcodec/blockdsp.c b/libavcodec/blockdsp.c index e3d2ca1fdc310..a35df8c7b10eb 100644 --- a/libavcodec/blockdsp.c +++ b/libavcodec/blockdsp.c @@ -57,8 +57,6 @@ static void fill_block8_c(uint8_t *block, uint8_t value, int line_size, int h) av_cold void ff_blockdsp_init(BlockDSPContext *c, AVCodecContext *avctx) { - const unsigned high_bit_depth = avctx->bits_per_raw_sample > 8; - c->clear_block = clear_block_8_c; c->clear_blocks = clear_blocks_8_c; @@ -66,13 +64,13 @@ av_cold void ff_blockdsp_init(BlockDSPContext *c, AVCodecContext *avctx) c->fill_block_tab[1] = fill_block8_c; if (ARCH_ARM) - ff_blockdsp_init_arm(c, high_bit_depth); + ff_blockdsp_init_arm(c); if (ARCH_PPC) - ff_blockdsp_init_ppc(c, high_bit_depth); + ff_blockdsp_init_ppc(c); if (ARCH_X86) #if FF_API_XVMC - ff_blockdsp_init_x86(c, high_bit_depth, avctx); + ff_blockdsp_init_x86(c, avctx); #else - ff_blockdsp_init_x86(c, high_bit_depth); + ff_blockdsp_init_x86(c); #endif /* FF_API_XVMC */ } diff --git a/libavcodec/blockdsp.h b/libavcodec/blockdsp.h index 32c671cf5a12e..5b5639f5a68ae 100644 --- a/libavcodec/blockdsp.h +++ b/libavcodec/blockdsp.h @@ -40,13 +40,13 @@ typedef struct BlockDSPContext { void ff_blockdsp_init(BlockDSPContext *c, AVCodecContext *avctx); -void ff_blockdsp_init_arm(BlockDSPContext *c, unsigned high_bit_depth); -void ff_blockdsp_init_ppc(BlockDSPContext *c, unsigned high_bit_depth); +void ff_blockdsp_init_arm(BlockDSPContext *c); +void ff_blockdsp_init_ppc(BlockDSPContext *c); #if FF_API_XVMC -void ff_blockdsp_init_x86(BlockDSPContext *c, unsigned high_bit_depth, +void ff_blockdsp_init_x86(BlockDSPContext *c, AVCodecContext *avctx); #else -void ff_blockdsp_init_x86(BlockDSPContext *c, unsigned high_bit_depth); +void ff_blockdsp_init_x86(BlockDSPContext *c); #endif /* FF_API_XVMC */ #endif /* AVCODEC_BLOCKDSP_H */ diff --git a/libavcodec/ppc/blockdsp.c b/libavcodec/ppc/blockdsp.c index 679bc0454fee0..d2c1d0e766b24 100644 --- a/libavcodec/ppc/blockdsp.c +++ b/libavcodec/ppc/blockdsp.c @@ -143,27 +143,24 @@ static void clear_block_altivec(int16_t *block) } #endif /* HAVE_ALTIVEC */ -av_cold void ff_blockdsp_init_ppc(BlockDSPContext *c, unsigned high_bit_depth) +av_cold void ff_blockdsp_init_ppc(BlockDSPContext *c) { // common optimizations whether AltiVec is available or not - if (!high_bit_depth) { - switch (check_dcbzl_effect()) { - case 32: - c->clear_blocks = clear_blocks_dcbz32_ppc; - break; - case 128: - c->clear_blocks = clear_blocks_dcbz128_ppc; - break; - default: - break; - } + switch (check_dcbzl_effect()) { + case 32: + c->clear_blocks = clear_blocks_dcbz32_ppc; + break; + case 128: + c->clear_blocks = clear_blocks_dcbz128_ppc; + break; + default: + break; } #if HAVE_ALTIVEC if (!PPC_ALTIVEC(av_get_cpu_flags())) return; - if (!high_bit_depth) - c->clear_block = clear_block_altivec; + c->clear_block = clear_block_altivec; #endif /* HAVE_ALTIVEC */ } diff --git a/libavcodec/x86/blockdsp.c b/libavcodec/x86/blockdsp.c index f14bb1f9ad0ec..9bb5185b890d6 100644 --- a/libavcodec/x86/blockdsp.c +++ b/libavcodec/x86/blockdsp.c @@ -88,20 +88,19 @@ static void clear_blocks_sse(int16_t *blocks) #endif /* HAVE_INLINE_ASM */ #if FF_API_XVMC -av_cold void ff_blockdsp_init_x86(BlockDSPContext *c, unsigned high_bit_depth, +av_cold void ff_blockdsp_init_x86(BlockDSPContext *c, AVCodecContext *avctx) #else -av_cold void ff_blockdsp_init_x86(BlockDSPContext *c, unsigned high_bit_depth) +av_cold void ff_blockdsp_init_x86(BlockDSPContext *c) #endif /* FF_API_XVMC */ { #if HAVE_INLINE_ASM int cpu_flags = av_get_cpu_flags(); - if (!high_bit_depth) { - if (INLINE_MMX(cpu_flags)) { - c->clear_block = clear_block_mmx; - c->clear_blocks = clear_blocks_mmx; - } + if (INLINE_MMX(cpu_flags)) { + c->clear_block = clear_block_mmx; + c->clear_blocks = clear_blocks_mmx; + } #if FF_API_XVMC FF_DISABLE_DEPRECATION_WARNINGS @@ -111,10 +110,9 @@ FF_DISABLE_DEPRECATION_WARNINGS FF_ENABLE_DEPRECATION_WARNINGS #endif /* FF_API_XVMC */ - if (INLINE_SSE(cpu_flags)) { - c->clear_block = clear_block_sse; - c->clear_blocks = clear_blocks_sse; - } + if (INLINE_SSE(cpu_flags)) { + c->clear_block = clear_block_sse; + c->clear_blocks = clear_blocks_sse; } #endif /* HAVE_INLINE_ASM */ } From 2eb97af66af90ca3978229da151f0b8b3a5d9370 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 8 Aug 2016 21:58:17 +0200 Subject: [PATCH 0172/3374] checkasm: add a test for blockdsp --- tests/checkasm/Makefile | 1 + tests/checkasm/blockdsp.c | 68 +++++++++++++++++++++++++++++++++++++++ tests/checkasm/checkasm.c | 3 ++ tests/checkasm/checkasm.h | 1 + 4 files changed, 73 insertions(+) create mode 100644 tests/checkasm/blockdsp.c diff --git a/tests/checkasm/Makefile b/tests/checkasm/Makefile index 8d3d03aa8c3b1..78626339976b5 100644 --- a/tests/checkasm/Makefile +++ b/tests/checkasm/Makefile @@ -1,5 +1,6 @@ # libavcodec tests # subsystems +AVCODECOBJS-$(CONFIG_BLOCKDSP) += blockdsp.o AVCODECOBJS-$(CONFIG_BSWAPDSP) += bswapdsp.o AVCODECOBJS-$(CONFIG_FMTCONVERT) += fmtconvert.o AVCODECOBJS-$(CONFIG_H264DSP) += h264dsp.o diff --git a/tests/checkasm/blockdsp.c b/tests/checkasm/blockdsp.c new file mode 100644 index 0000000000000..6b4bc804fc6f4 --- /dev/null +++ b/tests/checkasm/blockdsp.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2015 Henrik Gramner + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with Libav; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include + +#include "checkasm.h" + +#include "libavcodec/blockdsp.h" + +#include "libavutil/common.h" +#include "libavutil/internal.h" +#include "libavutil/intreadwrite.h" + +#define randomize_buffers(size) \ + do { \ + int i; \ + for (i = 0; i < size; i++) { \ + uint16_t r = rnd(); \ + AV_WN16A(buf0 + i, r); \ + AV_WN16A(buf1 + i, r); \ + } \ + } while (0) + +#define check_clear(func, size) \ +do { \ + if (check_func(h.func, "blockdsp." #func)) { \ + declare_func_emms(AV_CPU_FLAG_MMX, void, int16_t *block); \ + randomize_buffers(size); \ + call_ref(buf0); \ + call_new(buf1); \ + if (memcmp(buf0, buf1, sizeof(*buf0) * size)) \ + fail(); \ + bench_new(buf0); \ + } \ +} while (0) + +void checkasm_check_blockdsp(void) +{ + LOCAL_ALIGNED_16(uint16_t, buf0, [6 * 8 * 8]); + LOCAL_ALIGNED_16(uint16_t, buf1, [6 * 8 * 8]); + + AVCodecContext avctx = { 0 }; + BlockDSPContext h; + + ff_blockdsp_init(&h, &avctx); + + check_clear(clear_block, 8 * 8); + check_clear(clear_blocks, 8 * 8 * 6); + + report("blockdsp"); +} diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c index 5b4aa640da11c..525284ad4b7a9 100644 --- a/tests/checkasm/checkasm.c +++ b/tests/checkasm/checkasm.c @@ -64,6 +64,9 @@ static const struct { const char *name; void (*func)(void); } tests[] = { +#if CONFIG_BLOCKDSP + { "blockdsp", checkasm_check_blockdsp }, +#endif #if CONFIG_BSWAPDSP { "bswapdsp", checkasm_check_bswapdsp }, #endif diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h index 5e67b7d75a8df..c1141aab747cc 100644 --- a/tests/checkasm/checkasm.h +++ b/tests/checkasm/checkasm.h @@ -31,6 +31,7 @@ #include "libavutil/lfg.h" #include "libavutil/timer.h" +void checkasm_check_blockdsp(void); void checkasm_check_bswapdsp(void); void checkasm_check_dcadsp(void); void checkasm_check_fmtconvert(void); From e9ef6171396dc4106526aaa86b620c61ca3d1017 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 9 Aug 2016 18:10:26 +0200 Subject: [PATCH 0173/3374] checkasm: add tests for audiodsp --- tests/checkasm/Makefile | 1 + tests/checkasm/audiodsp.c | 146 ++++++++++++++++++++++++++++++++++++++ tests/checkasm/checkasm.c | 3 + tests/checkasm/checkasm.h | 1 + 4 files changed, 151 insertions(+) create mode 100644 tests/checkasm/audiodsp.c diff --git a/tests/checkasm/Makefile b/tests/checkasm/Makefile index 78626339976b5..f66c8b934ea7e 100644 --- a/tests/checkasm/Makefile +++ b/tests/checkasm/Makefile @@ -1,5 +1,6 @@ # libavcodec tests # subsystems +AVCODECOBJS-$(CONFIG_AUDIODSP) += audiodsp.o AVCODECOBJS-$(CONFIG_BLOCKDSP) += blockdsp.o AVCODECOBJS-$(CONFIG_BSWAPDSP) += bswapdsp.o AVCODECOBJS-$(CONFIG_FMTCONVERT) += fmtconvert.o diff --git a/tests/checkasm/audiodsp.c b/tests/checkasm/audiodsp.c new file mode 100644 index 0000000000000..456b90bfeced3 --- /dev/null +++ b/tests/checkasm/audiodsp.c @@ -0,0 +1,146 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with Libav; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include + +#include "libavcodec/audiodsp.h" + +#include "libavutil/common.h" +#include "libavutil/intreadwrite.h" + +#include "checkasm.h" + +#define MAX_SIZE (32 * 128) + +#define randomize_float(buf, len) \ + do { \ + int i; \ + for (i = 0; i < len; i++) { \ + float f = (float)rnd() / (UINT_MAX >> 5) - 16.0f; \ + buf[i] = f; \ + } \ + } while (0) + +#define randomize_int(buf, len, size, bits) \ + do { \ + int i; \ + for (i = 0; i < len; i++) { \ + uint ## size ## _t r = rnd() & ((1LL << bits) - 1); \ + AV_WN ## size ## A(buf + i, -(1LL << (bits - 1)) + r); \ + } \ + } while (0) + +void checkasm_check_audiodsp(void) +{ + AudioDSPContext adsp; + + ff_audiodsp_init(&adsp); + + if (check_func(adsp.scalarproduct_int16, "audiodsp.scalarproduct_int16")) { + LOCAL_ALIGNED(32, int16_t, v1, [MAX_SIZE]); + LOCAL_ALIGNED(32, int16_t, v2, [MAX_SIZE]); + unsigned int len_bits_minus4, v1_bits, v2_bits, len; + int32_t res0, res1; + + declare_func_emms(AV_CPU_FLAG_MMX, int32_t, const int16_t *v1, const int16_t *v2, int len); + + // generate random 5-12bit vector length + len_bits_minus4 = rnd() % 8; + len = rnd() & ((1 << len_bits_minus4) - 1); + len = 16 * FFMAX(len, 1); + + // generate the bit counts for each of the vectors such that the result + // fits into int32 + v1_bits = 1 + rnd() % 15; + v2_bits = FFMIN(32 - (len_bits_minus4 + 4) - v1_bits - 1, 15); + + randomize_int(v1, MAX_SIZE, 16, v1_bits + 1); + randomize_int(v2, MAX_SIZE, 16, v2_bits + 1); + + res0 = call_ref(v1, v2, len); + res1 = call_new(v1, v2, len); + if (res0 != res1) + fail(); + bench_new(v1, v2, MAX_SIZE); + } + + if (check_func(adsp.vector_clip_int32, "audiodsp.vector_clip_int32")) { + LOCAL_ALIGNED(32, int32_t, src, [MAX_SIZE]); + LOCAL_ALIGNED(32, int32_t, dst0, [MAX_SIZE]); + LOCAL_ALIGNED(32, int32_t, dst1, [MAX_SIZE]); + int32_t val1, val2, min, max; + int len; + + declare_func_emms(AV_CPU_FLAG_MMX, void, int32_t *dst, const int32_t *src, + int32_t min, int32_t max, unsigned int len); + + val1 = ((int32_t)rnd()); + val1 = FFSIGN(val1) * (val1 & ((1 << 24) - 1)); + val2 = ((int32_t)rnd()); + val2 = FFSIGN(val2) * (val2 & ((1 << 24) - 1)); + + min = FFMIN(val1, val2); + max = FFMAX(val1, val2); + + randomize_int(src, MAX_SIZE, 32, 32); + + len = rnd() % 128; + len = 32 * FFMAX(len, 1); + + call_ref(dst0, src, min, max, len); + call_new(dst1, src, min, max, len); + if (memcmp(dst0, dst1, len * sizeof(*dst0))) + fail(); + bench_new(dst1, src, min, max, MAX_SIZE); + } + + if (check_func(adsp.vector_clipf, "audiodsp.vector_clipf")) { + LOCAL_ALIGNED(32, float, src, [MAX_SIZE]); + LOCAL_ALIGNED(32, float, dst0, [MAX_SIZE]); + LOCAL_ALIGNED(32, float, dst1, [MAX_SIZE]); + float val1, val2, min, max; + int i, len; + + declare_func_emms(AV_CPU_FLAG_MMX, void, float *dst, const float *src, + float min, float max, unsigned int len); + + val1 = (float)rnd() / (UINT_MAX >> 1) - 1.0f; + val2 = (float)rnd() / (UINT_MAX >> 1) - 1.0f; + + min = FFMIN(val1, val2); + max = FFMAX(val1, val2); + + randomize_float(src, MAX_SIZE); + + len = rnd() % 128; + len = 16 * FFMAX(len, 1); + + call_ref(dst0, src, min, max, len); + call_new(dst1, src, min, max, len); + for (i = 0; i < len; i++) { + if (!float_near_ulp_array(dst0, dst1, 3, len)) + fail(); + } + bench_new(dst1, src, min, max, MAX_SIZE); + } + + report("audiodsp"); +} diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c index 525284ad4b7a9..c279ed17fcb62 100644 --- a/tests/checkasm/checkasm.c +++ b/tests/checkasm/checkasm.c @@ -64,6 +64,9 @@ static const struct { const char *name; void (*func)(void); } tests[] = { +#if CONFIG_AUDIODSP + { "audiodsp", checkasm_check_audiodsp }, +#endif #if CONFIG_BLOCKDSP { "blockdsp", checkasm_check_blockdsp }, #endif diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h index c1141aab747cc..169aa2a600a72 100644 --- a/tests/checkasm/checkasm.h +++ b/tests/checkasm/checkasm.h @@ -31,6 +31,7 @@ #include "libavutil/lfg.h" #include "libavutil/timer.h" +void checkasm_check_audiodsp(void); void checkasm_check_blockdsp(void); void checkasm_check_bswapdsp(void); void checkasm_check_dcadsp(void); From bf58545aace7d14522ce4fa680c7b3ff62109a3a Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 9 Aug 2016 19:50:56 +0200 Subject: [PATCH 0174/3374] audiodsp: fix vector_clipf documentation The x86 version processes 16 floats per iteration, so len must be a multiple of 16. --- libavcodec/audiodsp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/audiodsp.h b/libavcodec/audiodsp.h index 58205a1f19bc2..e48cdb092eec2 100644 --- a/libavcodec/audiodsp.h +++ b/libavcodec/audiodsp.h @@ -45,7 +45,7 @@ typedef struct AudioDSPContext { */ void (*vector_clip_int32)(int32_t *dst, const int32_t *src, int32_t min, int32_t max, unsigned int len); - /* assume len is a multiple of 8, and arrays are 16-byte aligned */ + /* assume len is a multiple of 16, and arrays are 16-byte aligned */ void (*vector_clipf)(float *dst /* align 16 */, const float *src /* align 16 */, float min, float max, int len /* align 16 */); From 12004a9a7f20e44f4da2ee6c372d5e1794c8d6c5 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 9 Aug 2016 20:20:00 +0200 Subject: [PATCH 0175/3374] audiodsp/x86: yasmify vector_clipf_sse --- libavcodec/x86/Makefile | 1 - libavcodec/x86/audiodsp.asm | 43 +++++++++++++++++++++++++ libavcodec/x86/audiodsp_init.c | 2 +- libavcodec/x86/audiodsp_mmx.c | 58 ---------------------------------- 4 files changed, 44 insertions(+), 60 deletions(-) delete mode 100644 libavcodec/x86/audiodsp_mmx.c diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile index 204c856340734..872b7faddb149 100644 --- a/libavcodec/x86/Makefile +++ b/libavcodec/x86/Makefile @@ -58,7 +58,6 @@ OBJS-$(CONFIG_VP9_DECODER) += x86/vp9dsp_init.o # GCC inline assembly optimizations # subsystems -MMX-OBJS-$(CONFIG_AUDIODSP) += x86/audiodsp_mmx.o MMX-OBJS-$(CONFIG_FDCTDSP) += x86/fdct.o MMX-OBJS-$(CONFIG_HPELDSP) += x86/fpel_mmx.o \ x86/hpeldsp_mmx.o diff --git a/libavcodec/x86/audiodsp.asm b/libavcodec/x86/audiodsp.asm index d7e63eb0cbc19..1bc7e32a689dd 100644 --- a/libavcodec/x86/audiodsp.asm +++ b/libavcodec/x86/audiodsp.asm @@ -135,3 +135,46 @@ VECTOR_CLIP_INT32 11, 1, 1, 0 %else VECTOR_CLIP_INT32 6, 1, 0, 0 %endif + +; void ff_vector_clipf_sse(float *dst, const float *src, +; int len, float min, float max) +INIT_XMM sse +cglobal vector_clipf, 3, 3, 6, dst, src, len, min, max +%if ARCH_X86_32 + VBROADCASTSS m0, minm + VBROADCASTSS m1, maxm +%elif WIN64 + VBROADCASTSS m0, m3 + VBROADCASTSS m1, maxm +%else ; 64bit sysv + VBROADCASTSS m0, m0 + VBROADCASTSS m1, m1 +%endif + + movsxdifnidn lenq, lend + +.loop + mova m2, [srcq + 4 * lenq - 4 * mmsize] + mova m3, [srcq + 4 * lenq - 3 * mmsize] + mova m4, [srcq + 4 * lenq - 2 * mmsize] + mova m5, [srcq + 4 * lenq - 1 * mmsize] + + maxps m2, m0 + maxps m3, m0 + maxps m4, m0 + maxps m5, m0 + + minps m2, m1 + minps m3, m1 + minps m4, m1 + minps m5, m1 + + mova [dstq + 4 * lenq - 4 * mmsize], m2 + mova [dstq + 4 * lenq - 3 * mmsize], m3 + mova [dstq + 4 * lenq - 2 * mmsize], m4 + mova [dstq + 4 * lenq - 1 * mmsize], m5 + + sub lenq, mmsize + jg .loop + + RET diff --git a/libavcodec/x86/audiodsp_init.c b/libavcodec/x86/audiodsp_init.c index 8eb2e56bdda8a..23731158e5699 100644 --- a/libavcodec/x86/audiodsp_init.c +++ b/libavcodec/x86/audiodsp_init.c @@ -49,7 +49,7 @@ av_cold void ff_audiodsp_init_x86(AudioDSPContext *c) if (EXTERNAL_MMXEXT(cpu_flags)) c->scalarproduct_int16 = ff_scalarproduct_int16_mmxext; - if (INLINE_SSE(cpu_flags)) + if (EXTERNAL_SSE(cpu_flags)) c->vector_clipf = ff_vector_clipf_sse; if (EXTERNAL_SSE2(cpu_flags)) { diff --git a/libavcodec/x86/audiodsp_mmx.c b/libavcodec/x86/audiodsp_mmx.c deleted file mode 100644 index 04cbb90706b3d..0000000000000 --- a/libavcodec/x86/audiodsp_mmx.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This file is part of Libav. - * - * Libav is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * Libav is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#include "libavutil/x86/asm.h" -#include "audiodsp.h" - -#if HAVE_INLINE_ASM - -void ff_vector_clipf_sse(float *dst, const float *src, - int len, float min, float max) -{ - x86_reg i = (len - 16) * 4; - __asm__ volatile ( - "movss %3, %%xmm4 \n\t" - "movss %4, %%xmm5 \n\t" - "shufps $0, %%xmm4, %%xmm4 \n\t" - "shufps $0, %%xmm5, %%xmm5 \n\t" - "1: \n\t" - "movaps (%2, %0), %%xmm0 \n\t" // 3/1 on intel - "movaps 16(%2, %0), %%xmm1 \n\t" - "movaps 32(%2, %0), %%xmm2 \n\t" - "movaps 48(%2, %0), %%xmm3 \n\t" - "maxps %%xmm4, %%xmm0 \n\t" - "maxps %%xmm4, %%xmm1 \n\t" - "maxps %%xmm4, %%xmm2 \n\t" - "maxps %%xmm4, %%xmm3 \n\t" - "minps %%xmm5, %%xmm0 \n\t" - "minps %%xmm5, %%xmm1 \n\t" - "minps %%xmm5, %%xmm2 \n\t" - "minps %%xmm5, %%xmm3 \n\t" - "movaps %%xmm0, (%1, %0) \n\t" - "movaps %%xmm1, 16(%1, %0) \n\t" - "movaps %%xmm2, 32(%1, %0) \n\t" - "movaps %%xmm3, 48(%1, %0) \n\t" - "sub $64, %0 \n\t" - "jge 1b \n\t" - : "+&r" (i) - : "r" (dst), "r" (src), "m" (min), "m" (max) - : "memory"); -} - -#endif /* HAVE_INLINE_ASM */ From 352741b5ead1543d775ccf6040f33023e4491186 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sat, 24 Sep 2016 17:54:57 +0200 Subject: [PATCH 0176/3374] nvenc: Make sure that enum and array index match And use a macro to reduce the boilerplate. Signed-off-by: Luca Barbato Signed-off-by: Diego Biurrun Signed-off-by: Luca Barbato --- libavcodec/nvenc.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 1ff27a19327fa..6db5b0d89687d 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -459,18 +459,21 @@ typedef struct GUIDTuple { int flags; } GUIDTuple; +#define PRESET(name, ...) \ + [PRESET_ ## name] = { NV_ENC_PRESET_ ## name ## _GUID, __VA_ARGS__ } + static int nvec_map_preset(NVENCContext *ctx) { GUIDTuple presets[] = { - { NV_ENC_PRESET_DEFAULT_GUID }, - { NV_ENC_PRESET_HP_GUID }, - { NV_ENC_PRESET_HQ_GUID }, - { NV_ENC_PRESET_BD_GUID }, - { NV_ENC_PRESET_LOW_LATENCY_DEFAULT_GUID, NVENC_LOWLATENCY }, - { NV_ENC_PRESET_LOW_LATENCY_HP_GUID, NVENC_LOWLATENCY }, - { NV_ENC_PRESET_LOW_LATENCY_HQ_GUID, NVENC_LOWLATENCY }, - { NV_ENC_PRESET_LOSSLESS_DEFAULT_GUID, NVENC_LOSSLESS }, - { NV_ENC_PRESET_LOSSLESS_HP_GUID, NVENC_LOSSLESS }, + PRESET(DEFAULT), + PRESET(HP), + PRESET(HQ), + PRESET(BD), + PRESET(LOW_LATENCY_DEFAULT, NVENC_LOWLATENCY), + PRESET(LOW_LATENCY_HP, NVENC_LOWLATENCY), + PRESET(LOW_LATENCY_HQ, NVENC_LOWLATENCY), + PRESET(LOSSLESS_DEFAULT, NVENC_LOSSLESS), + PRESET(LOSSLESS_HP, NVENC_LOSSLESS), { { 0 } } }; @@ -482,6 +485,8 @@ static int nvec_map_preset(NVENCContext *ctx) return AVERROR(EINVAL); } +#undef PRESET + static void set_constqp(AVCodecContext *avctx, NV_ENC_RC_PARAMS *rc) { rc->rateControlMode = NV_ENC_PARAMS_RC_CONSTQP; From e02e2515b24bfc37ede6ca1744696230be55e50b Mon Sep 17 00:00:00 2001 From: Yogender Gupta Date: Sat, 24 Sep 2016 17:54:58 +0200 Subject: [PATCH 0177/3374] nvenc: Add some easier to understand presets that match x264 terminology Signed-off-by: Luca Barbato Signed-off-by: Diego Biurrun Signed-off-by: Luca Barbato --- libavcodec/nvenc.c | 10 ++++++++-- libavcodec/nvenc.h | 7 ++++++- libavcodec/nvenc_h264.c | 5 ++++- libavcodec/nvenc_hevc.c | 5 ++++- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 6db5b0d89687d..7f8737e0bf322 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -459,8 +459,10 @@ typedef struct GUIDTuple { int flags; } GUIDTuple; -#define PRESET(name, ...) \ - [PRESET_ ## name] = { NV_ENC_PRESET_ ## name ## _GUID, __VA_ARGS__ } +#define PRESET_ALIAS(alias, name, ...) \ + [PRESET_ ## alias] = { NV_ENC_PRESET_ ## name ## _GUID, __VA_ARGS__ } + +#define PRESET(name, ...) PRESET_ALIAS(name, name, __VA_ARGS__) static int nvec_map_preset(NVENCContext *ctx) { @@ -474,6 +476,9 @@ static int nvec_map_preset(NVENCContext *ctx) PRESET(LOW_LATENCY_HQ, NVENC_LOWLATENCY), PRESET(LOSSLESS_DEFAULT, NVENC_LOSSLESS), PRESET(LOSSLESS_HP, NVENC_LOSSLESS), + PRESET_ALIAS(SLOW, HQ, NVENC_TWO_PASSES), + PRESET_ALIAS(MEDIUM, HQ, NVENC_ONE_PASS), + PRESET_ALIAS(FAST, HP, NVENC_ONE_PASS), { { 0 } } }; @@ -486,6 +491,7 @@ static int nvec_map_preset(NVENCContext *ctx) } #undef PRESET +#undef PRESET_ALIAS static void set_constqp(AVCodecContext *avctx, NV_ENC_RC_PARAMS *rc) { diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h index e7e6182196d4e..26c6515c573a1 100644 --- a/libavcodec/nvenc.h +++ b/libavcodec/nvenc.h @@ -91,6 +91,9 @@ typedef struct NVENCLibraryContext enum { PRESET_DEFAULT, + PRESET_SLOW, + PRESET_MEDIUM, + PRESET_FAST, PRESET_HP, PRESET_HQ, PRESET_BD , @@ -111,7 +114,9 @@ enum { enum { NVENC_LOWLATENCY = 1, - NVENC_LOSSLESS, + NVENC_LOSSLESS = 2, + NVENC_ONE_PASS = 4, + NVENC_TWO_PASSES = 8, }; enum { diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c index ea91e077c02db..d58ee88f6b56a 100644 --- a/libavcodec/nvenc_h264.c +++ b/libavcodec/nvenc_h264.c @@ -27,8 +27,11 @@ #define OFFSET(x) offsetof(NVENCContext, x) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { - { "preset", "Set the encoding preset", OFFSET(preset), AV_OPT_TYPE_INT, { .i64 = PRESET_HQ }, PRESET_DEFAULT, PRESET_LOSSLESS_HP, VE, "preset" }, + { "preset", "Set the encoding preset", OFFSET(preset), AV_OPT_TYPE_INT, { .i64 = PRESET_MEDIUM }, PRESET_DEFAULT, PRESET_LOSSLESS_HP, VE, "preset" }, { "default", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_DEFAULT }, 0, 0, VE, "preset" }, + { "slow", "hq 2 passes", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_SLOW }, 0, 0, VE, "preset" }, + { "medium", "hq 1 pass", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_MEDIUM }, 0, 0, VE, "preset" }, + { "fast", "hp 1 pass", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_FAST }, 0, 0, VE, "preset" }, { "hp", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_HP }, 0, 0, VE, "preset" }, { "hq", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_HQ }, 0, 0, VE, "preset" }, { "bd", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_BD }, 0, 0, VE, "preset" }, diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c index 6ff350698c319..f129826834cca 100644 --- a/libavcodec/nvenc_hevc.c +++ b/libavcodec/nvenc_hevc.c @@ -27,8 +27,11 @@ #define OFFSET(x) offsetof(NVENCContext, x) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { - { "preset", "Set the encoding preset", OFFSET(preset), AV_OPT_TYPE_INT, { .i64 = PRESET_HQ }, PRESET_DEFAULT, PRESET_LOSSLESS_HP, VE, "preset" }, + { "preset", "Set the encoding preset", OFFSET(preset), AV_OPT_TYPE_INT, { .i64 = PRESET_MEDIUM }, PRESET_DEFAULT, PRESET_LOSSLESS_HP, VE, "preset" }, { "default", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_DEFAULT }, 0, 0, VE, "preset" }, + { "slow", "hq 2 passes", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_SLOW }, 0, 0, VE, "preset" }, + { "medium", "hq 1 pass", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_MEDIUM }, 0, 0, VE, "preset" }, + { "fast", "hp 1 pass", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_FAST }, 0, 0, VE, "preset" }, { "hp", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_HP }, 0, 0, VE, "preset" }, { "hq", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_HQ }, 0, 0, VE, "preset" }, { "bd", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_BD }, 0, 0, VE, "preset" }, From 358c887a9fa0fb2e7ce089eaea71ab924a3e47a7 Mon Sep 17 00:00:00 2001 From: Yogender Gupta Date: Sat, 24 Sep 2016 17:54:59 +0200 Subject: [PATCH 0178/3374] nvenc: Add support for high bitdepth Signed-off-by: Luca Barbato Signed-off-by: Diego Biurrun --- libavcodec/nvenc.c | 87 +++++++++++++++++++++++++++++++++++++++-- libavcodec/nvenc.h | 6 +++ libavcodec/nvenc_hevc.c | 8 +++- 3 files changed, 96 insertions(+), 5 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 7f8737e0bf322..14651d41c7c83 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -89,12 +89,22 @@ const enum AVPixelFormat ff_nvenc_pix_fmts[] = { AV_PIX_FMT_NV12, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV444P, +#if NVENCAPI_MAJOR_VERSION >= 7 + AV_PIX_FMT_P010, + AV_PIX_FMT_YUV444P16, +#endif #if CONFIG_CUDA AV_PIX_FMT_CUDA, #endif AV_PIX_FMT_NONE }; +#define IS_10BIT(pix_fmt) (pix_fmt == AV_PIX_FMT_P010 || \ + pix_fmt == AV_PIX_FMT_YUV444P16) + +#define IS_YUV444(pix_fmt) (pix_fmt == AV_PIX_FMT_YUV444P || \ + pix_fmt == AV_PIX_FMT_YUV444P16) + static const struct { NVENCSTATUS nverr; int averr; @@ -703,9 +713,47 @@ static int nvenc_setup_hevc_config(AVCodecContext *avctx) hevc->outputPictureTimingSEI = 1; } - /* No other profile is supported in the current SDK version 5 */ - cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN_GUID; - avctx->profile = FF_PROFILE_HEVC_MAIN; + switch (ctx->profile) { + case NV_ENC_HEVC_PROFILE_MAIN: + cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN_GUID; + avctx->profile = FF_PROFILE_HEVC_MAIN; + break; +#if NVENCAPI_MAJOR_VERSION >= 7 + case NV_ENC_HEVC_PROFILE_MAIN_10: + cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN10_GUID; + avctx->profile = FF_PROFILE_HEVC_MAIN_10; + break; + case NV_ENC_HEVC_PROFILE_REXT: + cc->profileGUID = NV_ENC_HEVC_PROFILE_FREXT_GUID; + avctx->profile = FF_PROFILE_HEVC_REXT; + break; +#endif /* NVENCAPI_MAJOR_VERSION >= 7 */ + } + + // force setting profile for various input formats + switch (ctx->data_pix_fmt) { + case AV_PIX_FMT_YUV420P: + case AV_PIX_FMT_NV12: + cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN_GUID; + avctx->profile = FF_PROFILE_HEVC_MAIN; + break; +#if NVENCAPI_MAJOR_VERSION >= 7 + case AV_PIX_FMT_P010: + cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN10_GUID; + avctx->profile = FF_PROFILE_HEVC_MAIN_10; + break; + case AV_PIX_FMT_YUV444P: + case AV_PIX_FMT_YUV444P16: + cc->profileGUID = NV_ENC_HEVC_PROFILE_FREXT_GUID; + avctx->profile = FF_PROFILE_HEVC_REXT; + break; +#endif /* NVENCAPI_MAJOR_VERSION >= 7 */ + } + +#if NVENCAPI_MAJOR_VERSION >= 7 + hevc->chromaFormatIDC = IS_YUV444(ctx->data_pix_fmt) ? 3 : 1; + hevc->pixelBitDepthMinus8 = IS_10BIT(ctx->data_pix_fmt) ? 2 : 0; +#endif /* NVENCAPI_MAJOR_VERSION >= 7 */ hevc->sliceMode = 3; hevc->sliceModeData = FFMAX(avctx->slices, 1); @@ -858,6 +906,14 @@ static int nvenc_alloc_surface(AVCodecContext *avctx, int idx) case AV_PIX_FMT_YUV444P: ctx->frames[idx].format = NV_ENC_BUFFER_FORMAT_YUV444_PL; break; +#if NVENCAPI_MAJOR_VERSION >= 7 + case AV_PIX_FMT_P010: + ctx->frames[idx].format = NV_ENC_BUFFER_FORMAT_YUV420_10BIT; + break; + case AV_PIX_FMT_YUV444P16: + ctx->frames[idx].format = NV_ENC_BUFFER_FORMAT_YUV444_10BIT; + break; +#endif /* NVENCAPI_MAJOR_VERSION >= 7 */ default: return AVERROR_BUG; } @@ -1096,6 +1152,16 @@ static int nvenc_copy_frame(NV_ENC_LOCK_INPUT_BUFFER *in, const AVFrame *frame) frame->data[1], frame->linesize[1], frame->width, frame->height >> 1); break; + case AV_PIX_FMT_P010: + av_image_copy_plane(buf, in->pitch, + frame->data[0], frame->linesize[0], + frame->width << 1, frame->height); + buf += off; + + av_image_copy_plane(buf, in->pitch, + frame->data[1], frame->linesize[1], + frame->width << 1, frame->height >> 1); + break; case AV_PIX_FMT_YUV444P: av_image_copy_plane(buf, in->pitch, frame->data[0], frame->linesize[0], @@ -1111,6 +1177,21 @@ static int nvenc_copy_frame(NV_ENC_LOCK_INPUT_BUFFER *in, const AVFrame *frame) frame->data[2], frame->linesize[2], frame->width, frame->height); break; + case AV_PIX_FMT_YUV444P16: + av_image_copy_plane(buf, in->pitch, + frame->data[0], frame->linesize[0], + frame->width << 1, frame->height); + buf += off; + + av_image_copy_plane(buf, in->pitch, + frame->data[1], frame->linesize[1], + frame->width << 1, frame->height); + buf += off; + + av_image_copy_plane(buf, in->pitch, + frame->data[2], frame->linesize[2], + frame->width << 1, frame->height); + break; default: return AVERROR_BUG; } diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h index 26c6515c573a1..fddf433d5ec81 100644 --- a/libavcodec/nvenc.h +++ b/libavcodec/nvenc.h @@ -112,6 +112,12 @@ enum { NV_ENC_H264_PROFILE_CONSTRAINED_HIGH, }; +enum { + NV_ENC_HEVC_PROFILE_MAIN, + NV_ENC_HEVC_PROFILE_MAIN_10, + NV_ENC_HEVC_PROFILE_REXT, +}; + enum { NVENC_LOWLATENCY = 1, NVENC_LOSSLESS = 2, diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c index f129826834cca..d564f07a04802 100644 --- a/libavcodec/nvenc_hevc.c +++ b/libavcodec/nvenc_hevc.c @@ -40,8 +40,12 @@ static const AVOption options[] = { { "llhp", "low latency hp", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOW_LATENCY_HP }, 0, 0, VE, "preset" }, { "lossless", "lossless", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOSSLESS_DEFAULT }, 0, 0, VE, "preset" }, { "losslesshp", "lossless hp", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOSSLESS_HP }, 0, 0, VE, "preset" }, - { "profile", "Set the encoding profile", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = FF_PROFILE_HEVC_MAIN }, FF_PROFILE_HEVC_MAIN, FF_PROFILE_HEVC_MAIN, VE, "profile" }, - { "high", "", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_HEVC_MAIN }, 0, 0, VE, "profile" }, + { "profile", "Set the encoding profile", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = NV_ENC_HEVC_PROFILE_MAIN }, NV_ENC_HEVC_PROFILE_MAIN, FF_PROFILE_HEVC_REXT, VE, "profile" }, + { "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_HEVC_PROFILE_MAIN }, 0, 0, VE, "profile" }, +#if NVENCAPI_MAJOR_VERSION >= 7 + { "main10", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_HEVC_PROFILE_MAIN_10 }, 0, 0, VE, "profile" }, + { "rext", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_HEVC_PROFILE_REXT }, 0, 0, VE, "profile" }, +#endif /* NVENCAPI_MAJOR_VERSION >= 7 */ { "level", "Set the encoding level restriction", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = NV_ENC_LEVEL_AUTOSELECT }, NV_ENC_LEVEL_AUTOSELECT, NV_ENC_LEVEL_HEVC_62, VE, "level" }, { "1.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_HEVC_1 }, 0, 0, VE, "level" }, { "2.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_HEVC_2 }, 0, 0, VE, "level" }, From 70de2ea4261f860457a04e3d0c58c5543f403325 Mon Sep 17 00:00:00 2001 From: Yogender Gupta Date: Sat, 24 Sep 2016 17:55:00 +0200 Subject: [PATCH 0179/3374] nvenc: Extended rate-control support as provided by SDK 7 Signed-off-by: Luca Barbato Signed-off-by: Diego Biurrun --- libavcodec/nvenc.c | 47 +++++++++++++++++++++++++++++++++++++++++ libavcodec/nvenc.h | 10 +++++++++ libavcodec/nvenc_h264.c | 12 +++++++++++ libavcodec/nvenc_hevc.c | 10 +++++++++ libavcodec/version.h | 2 +- 5 files changed, 80 insertions(+), 1 deletion(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 14651d41c7c83..0b6e4cef8688b 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -610,6 +610,53 @@ static void nvenc_setup_rate_control(AVCodecContext *avctx) if (rc->averageBitRate > 0) avctx->bit_rate = rc->averageBitRate; + +#if NVENCAPI_MAJOR_VERSION >= 7 + if (ctx->aq) { + ctx->config.rcParams.enableAQ = 1; + ctx->config.rcParams.aqStrength = ctx->aq_strength; + av_log(avctx, AV_LOG_VERBOSE, "AQ enabled.\n"); + } + + if (ctx->temporal_aq) { + ctx->config.rcParams.enableTemporalAQ = 1; + av_log(avctx, AV_LOG_VERBOSE, "Temporal AQ enabled.\n"); + } + + if (ctx->rc_lookahead) { + int lkd_bound = FFMIN(ctx->nb_surfaces, ctx->async_depth) - + ctx->config.frameIntervalP - 4; + + if (lkd_bound < 0) { + av_log(avctx, AV_LOG_WARNING, + "Lookahead not enabled. Increase buffer delay (-delay).\n"); + } else { + ctx->config.rcParams.enableLookahead = 1; + ctx->config.rcParams.lookaheadDepth = av_clip(ctx->rc_lookahead, 0, lkd_bound); + ctx->config.rcParams.disableIadapt = ctx->no_scenecut; + ctx->config.rcParams.disableBadapt = !ctx->b_adapt; + av_log(avctx, AV_LOG_VERBOSE, + "Lookahead enabled: depth %d, scenecut %s, B-adapt %s.\n", + ctx->config.rcParams.lookaheadDepth, + ctx->config.rcParams.disableIadapt ? "disabled" : "enabled", + ctx->config.rcParams.disableBadapt ? "disabled" : "enabled"); + } + } + + if (ctx->strict_gop) { + ctx->config.rcParams.strictGOPTarget = 1; + av_log(avctx, AV_LOG_VERBOSE, "Strict GOP target enabled.\n"); + } + + if (ctx->nonref_p) + ctx->config.rcParams.enableNonRefP = 1; + + if (ctx->zerolatency) + ctx->config.rcParams.zeroReorderDelay = 1; + + if (ctx->quality) + ctx->config.rcParams.targetQuality = ctx->quality; +#endif /* NVENCAPI_MAJOR_VERSION >= 7 */ } static int nvenc_setup_h264_config(AVCodecContext *avctx) diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h index fddf433d5ec81..dfd03b5ebd7cf 100644 --- a/libavcodec/nvenc.h +++ b/libavcodec/nvenc.h @@ -171,6 +171,16 @@ typedef struct NVENCContext { int device; int flags; int async_depth; + int rc_lookahead; + int aq; + int no_scenecut; + int b_adapt; + int temporal_aq; + int zerolatency; + int nonref_p; + int strict_gop; + int aq_strength; + int quality; } NVENCContext; int ff_nvenc_encode_init(AVCodecContext *avctx); diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c index d58ee88f6b56a..faeafe92849a3 100644 --- a/libavcodec/nvenc_h264.c +++ b/libavcodec/nvenc_h264.c @@ -77,6 +77,18 @@ static const AVOption options[] = { { "list", "List the available devices", 0, AV_OPT_TYPE_CONST, { .i64 = LIST_DEVICES }, 0, 0, VE, "device" }, { "async_depth", "Delay frame output by the given amount of frames", OFFSET(async_depth), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 0, INT_MAX, VE }, { "delay", "Delay frame output by the given amount of frames", OFFSET(async_depth), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 0, INT_MAX, VE }, +#if NVENCAPI_MAJOR_VERSION >= 7 + { "rc-lookahead", "Number of frames to look ahead for rate-control", OFFSET(rc_lookahead), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE }, + { "no-scenecut", "When lookahead is enabled, set this to 1 to disable adaptive I-frame insertion at scene cuts", OFFSET(no_scenecut), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, + { "b_adapt", "When lookahead is enabled, set this to 0 to disable adaptive B-frame decision", OFFSET(b_adapt), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE }, + { "spatial-aq", "set to 1 to enable Spatial AQ", OFFSET(aq), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, + { "temporal-aq", "set to 1 to enable Temporal AQ", OFFSET(temporal_aq), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, + { "zerolatency", "Set 1 to indicate zero latency operation (no reordering delay)", OFFSET(zerolatency), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, + { "nonref_p", "Set this to 1 to enable automatic insertion of non-reference P-frames", OFFSET(nonref_p), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, + { "strict_gop", "Set 1 to minimize GOP-to-GOP rate fluctuations", OFFSET(strict_gop), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, + { "aq-strength", "When Spatial AQ is enabled, this field is used to specify AQ strength. AQ strength scale is from 1 (low) - 15 (aggressive)", OFFSET(aq_strength), AV_OPT_TYPE_INT, { .i64 = 8 }, 1, 15, VE }, + { "cq", "Set target quality level (0 to 51, 0 means automatic) for constant quality mode in VBR rate control", OFFSET(quality), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 51, VE }, +#endif /* NVENCAPI_MAJOR_VERSION >= 7 */ { NULL } }; diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c index d564f07a04802..de9af6151f50e 100644 --- a/libavcodec/nvenc_hevc.c +++ b/libavcodec/nvenc_hevc.c @@ -77,6 +77,16 @@ static const AVOption options[] = { { "list", "List the available devices", 0, AV_OPT_TYPE_CONST, { .i64 = LIST_DEVICES }, 0, 0, VE, "device" }, { "async_depth", "Delay frame output by the given amount of frames", OFFSET(async_depth), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 0, INT_MAX, VE }, { "delay", "Delay frame output by the given amount of frames", OFFSET(async_depth), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 0, INT_MAX, VE }, +#if NVENCAPI_MAJOR_VERSION >= 7 + { "rc-lookahead", "Number of frames to look ahead for rate-control", OFFSET(rc_lookahead), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE }, + { "no-scenecut", "When lookahead is enabled, set this to 1 to disable adaptive I-frame insertion at scene cuts", OFFSET(no_scenecut), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, + { "spatial_aq", "set to 1 to enable Spatial AQ", OFFSET(aq), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, + { "zerolatency", "Set 1 to indicate zero latency operation (no reordering delay)", OFFSET(zerolatency), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, + { "nonref_p", "Set this to 1 to enable automatic insertion of non-reference P-frames", OFFSET(nonref_p), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, + { "strict_gop", "Set 1 to minimize GOP-to-GOP rate fluctuations", OFFSET(strict_gop), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, + { "aq-strength", "When Spatial AQ is enabled, this field is used to specify AQ strength. AQ strength scale is from 1 (low) - 15 (aggressive)", OFFSET(aq_strength), AV_OPT_TYPE_INT, { .i64 = 8 }, 1, 15, VE }, + { "cq", "Set target quality level (0 to 51, 0 means automatic) for constant quality mode in VBR rate control", OFFSET(quality), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 51, VE }, +#endif /* NVENCAPI_MAJOR_VERSION >= 7 */ { NULL } }; diff --git a/libavcodec/version.h b/libavcodec/version.h index 20edb611d8429..71ec9cea8bf47 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 27 -#define LIBAVCODEC_VERSION_MICRO 0 +#define LIBAVCODEC_VERSION_MICRO 1 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From de8e096c7eda2bce76efd0a1c1c89d37348c2414 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Sun, 25 Sep 2016 17:09:57 -0400 Subject: [PATCH 0180/3374] swscale: Consistently order input YUV pixel formats Follow a 420, 422, 444 order instead of a random one. This simplifies double-checking additions of new formats. Signed-off-by: Diego Biurrun --- libswscale/input.c | 58 +++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/libswscale/input.c b/libswscale/input.c index 9a4fd77f1cbee..69c67296665ca 100644 --- a/libswscale/input.c +++ b/libswscale/input.c @@ -809,42 +809,42 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) c->readChrPlanar = planar_rgb_to_uv; break; #if HAVE_BIGENDIAN - case AV_PIX_FMT_YUV444P9LE: - case AV_PIX_FMT_YUV422P9LE: case AV_PIX_FMT_YUV420P9LE: + case AV_PIX_FMT_YUV422P9LE: + case AV_PIX_FMT_YUV444P9LE: + case AV_PIX_FMT_YUV420P10LE: case AV_PIX_FMT_YUV422P10LE: case AV_PIX_FMT_YUV444P10LE: - case AV_PIX_FMT_YUV420P10LE: case AV_PIX_FMT_YUV420P16LE: case AV_PIX_FMT_YUV422P16LE: case AV_PIX_FMT_YUV444P16LE: - case AV_PIX_FMT_YUVA444P9LE: - case AV_PIX_FMT_YUVA422P9LE: case AV_PIX_FMT_YUVA420P9LE: + case AV_PIX_FMT_YUVA422P9LE: + case AV_PIX_FMT_YUVA444P9LE: + case AV_PIX_FMT_YUVA420P10LE: case AV_PIX_FMT_YUVA422P10LE: case AV_PIX_FMT_YUVA444P10LE: - case AV_PIX_FMT_YUVA420P10LE: case AV_PIX_FMT_YUVA420P16LE: case AV_PIX_FMT_YUVA422P16LE: case AV_PIX_FMT_YUVA444P16LE: c->chrToYV12 = bswap16UV_c; break; #else - case AV_PIX_FMT_YUV444P9BE: - case AV_PIX_FMT_YUV422P9BE: case AV_PIX_FMT_YUV420P9BE: - case AV_PIX_FMT_YUV444P10BE: - case AV_PIX_FMT_YUV422P10BE: + case AV_PIX_FMT_YUV422P9BE: + case AV_PIX_FMT_YUV444P9BE: case AV_PIX_FMT_YUV420P10BE: + case AV_PIX_FMT_YUV422P10BE: + case AV_PIX_FMT_YUV444P10BE: case AV_PIX_FMT_YUV420P16BE: case AV_PIX_FMT_YUV422P16BE: case AV_PIX_FMT_YUV444P16BE: - case AV_PIX_FMT_YUVA444P9BE: - case AV_PIX_FMT_YUVA422P9BE: case AV_PIX_FMT_YUVA420P9BE: + case AV_PIX_FMT_YUVA422P9BE: + case AV_PIX_FMT_YUVA444P9BE: + case AV_PIX_FMT_YUVA420P10BE: case AV_PIX_FMT_YUVA422P10BE: case AV_PIX_FMT_YUVA444P10BE: - case AV_PIX_FMT_YUVA420P10BE: case AV_PIX_FMT_YUVA420P16BE: case AV_PIX_FMT_YUVA422P16BE: case AV_PIX_FMT_YUVA444P16BE: @@ -1027,24 +1027,24 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) c->readLumPlanar = planar_rgb_to_y; break; #if HAVE_BIGENDIAN - case AV_PIX_FMT_YUV444P9LE: - case AV_PIX_FMT_YUV422P9LE: case AV_PIX_FMT_YUV420P9LE: - case AV_PIX_FMT_YUV444P10LE: - case AV_PIX_FMT_YUV422P10LE: + case AV_PIX_FMT_YUV422P9LE: + case AV_PIX_FMT_YUV444P9LE: case AV_PIX_FMT_YUV420P10LE: + case AV_PIX_FMT_YUV422P10LE: + case AV_PIX_FMT_YUV444P10LE: case AV_PIX_FMT_YUV420P16LE: case AV_PIX_FMT_YUV422P16LE: case AV_PIX_FMT_YUV444P16LE: case AV_PIX_FMT_GRAY16LE: c->lumToYV12 = bswap16Y_c; break; - case AV_PIX_FMT_YUVA444P9LE: - case AV_PIX_FMT_YUVA422P9LE: case AV_PIX_FMT_YUVA420P9LE: - case AV_PIX_FMT_YUVA444P10LE: - case AV_PIX_FMT_YUVA422P10LE: + case AV_PIX_FMT_YUVA422P9LE: + case AV_PIX_FMT_YUVA444P9LE: case AV_PIX_FMT_YUVA420P10LE: + case AV_PIX_FMT_YUVA422P10LE: + case AV_PIX_FMT_YUVA444P10LE: case AV_PIX_FMT_YUVA420P16LE: case AV_PIX_FMT_YUVA422P16LE: case AV_PIX_FMT_YUVA444P16LE: @@ -1052,24 +1052,24 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) c->alpToYV12 = bswap16Y_c; break; #else - case AV_PIX_FMT_YUV444P9BE: - case AV_PIX_FMT_YUV422P9BE: case AV_PIX_FMT_YUV420P9BE: - case AV_PIX_FMT_YUV444P10BE: - case AV_PIX_FMT_YUV422P10BE: + case AV_PIX_FMT_YUV422P9BE: + case AV_PIX_FMT_YUV444P9BE: case AV_PIX_FMT_YUV420P10BE: + case AV_PIX_FMT_YUV422P10BE: + case AV_PIX_FMT_YUV444P10BE: case AV_PIX_FMT_YUV420P16BE: case AV_PIX_FMT_YUV422P16BE: case AV_PIX_FMT_YUV444P16BE: case AV_PIX_FMT_GRAY16BE: c->lumToYV12 = bswap16Y_c; break; - case AV_PIX_FMT_YUVA444P9BE: - case AV_PIX_FMT_YUVA422P9BE: case AV_PIX_FMT_YUVA420P9BE: - case AV_PIX_FMT_YUVA444P10BE: - case AV_PIX_FMT_YUVA422P10BE: + case AV_PIX_FMT_YUVA422P9BE: + case AV_PIX_FMT_YUVA444P9BE: case AV_PIX_FMT_YUVA420P10BE: + case AV_PIX_FMT_YUVA422P10BE: + case AV_PIX_FMT_YUVA444P10BE: case AV_PIX_FMT_YUVA420P16BE: case AV_PIX_FMT_YUVA422P16BE: case AV_PIX_FMT_YUVA444P16BE: From e87a501e7d03ac68b58520108fe24ad9d0b36765 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sun, 25 Sep 2016 16:23:20 +0200 Subject: [PATCH 0181/3374] swscale: Update bitdepth range check Make sure the scaling functions for the 9-15bits are used for 9-15bits bit depths correctly. --- libswscale/swscale.c | 6 +++--- libswscale/swscale_internal.h | 2 +- libswscale/x86/swscale.c | 14 +++++++------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/libswscale/swscale.c b/libswscale/swscale.c index 131980855ccaa..142c79c14a118 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -731,7 +731,7 @@ static av_cold void sws_init_swscale(SwsContext *c) ff_sws_init_input_funcs(c); if (c->srcBpc == 8) { - if (c->dstBpc <= 10) { + if (c->dstBpc <= 15) { c->hyScale = c->hcScale = hScale8To15_c; if (c->flags & SWS_FAST_BILINEAR) { c->hyscale_fast = hyscale_fast_c; @@ -741,12 +741,12 @@ static av_cold void sws_init_swscale(SwsContext *c) c->hyScale = c->hcScale = hScale8To19_c; } } else { - c->hyScale = c->hcScale = c->dstBpc > 10 ? hScale16To19_c + c->hyScale = c->hcScale = c->dstBpc > 15 ? hScale16To19_c : hScale16To15_c; } if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) { - if (c->dstBpc <= 10) { + if (c->dstBpc <= 15) { if (c->srcRange) { c->lumConvertRange = lumRangeFromJpeg_c; c->chrConvertRange = chrRangeFromJpeg_c; diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index 84f8dd339f996..625bd864a48cb 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -569,7 +569,7 @@ static av_always_inline int is9_OR_10BPS(enum AVPixelFormat pix_fmt) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); av_assert0(desc); - return desc->comp[0].depth == 9 || desc->comp[0].depth == 10; + return desc->comp[0].depth >= 9 && desc->comp[0].depth <= 15; } static av_always_inline int isBE(enum AVPixelFormat pix_fmt) diff --git a/libswscale/x86/swscale.c b/libswscale/x86/swscale.c index ec774678d5a5d..48b5b49ce87c5 100644 --- a/libswscale/x86/swscale.c +++ b/libswscale/x86/swscale.c @@ -316,16 +316,16 @@ av_cold void ff_sws_init_swscale_x86(SwsContext *c) #define ASSIGN_SCALE_FUNC2(hscalefn, filtersize, opt1, opt2) do { \ if (c->srcBpc == 8) { \ - hscalefn = c->dstBpc <= 10 ? ff_hscale8to15_ ## filtersize ## _ ## opt2 : \ + hscalefn = c->dstBpc <= 15 ? ff_hscale8to15_ ## filtersize ## _ ## opt2 : \ ff_hscale8to19_ ## filtersize ## _ ## opt1; \ } else if (c->srcBpc == 9) { \ - hscalefn = c->dstBpc <= 10 ? ff_hscale9to15_ ## filtersize ## _ ## opt2 : \ + hscalefn = c->dstBpc <= 15 ? ff_hscale9to15_ ## filtersize ## _ ## opt2 : \ ff_hscale9to19_ ## filtersize ## _ ## opt1; \ } else if (c->srcBpc == 10) { \ - hscalefn = c->dstBpc <= 10 ? ff_hscale10to15_ ## filtersize ## _ ## opt2 : \ + hscalefn = c->dstBpc <= 15 ? ff_hscale10to15_ ## filtersize ## _ ## opt2 : \ ff_hscale10to19_ ## filtersize ## _ ## opt1; \ - } else /* c->srcBpc == 16 */ { \ - hscalefn = c->dstBpc <= 10 ? ff_hscale16to15_ ## filtersize ## _ ## opt2 : \ + } else if (c->srcBpc == 16) { \ + hscalefn = c->dstBpc <= 15 ? ff_hscale16to15_ ## filtersize ## _ ## opt2 : \ ff_hscale16to19_ ## filtersize ## _ ## opt1; \ } \ } while (0) @@ -340,14 +340,14 @@ switch(c->dstBpc){ \ case 16: do_16_case; break; \ case 10: if (!isBE(c->dstFormat)) vscalefn = ff_yuv2planeX_10_ ## opt; break; \ case 9: if (!isBE(c->dstFormat)) vscalefn = ff_yuv2planeX_9_ ## opt; break; \ - default: if (condition_8bit) vscalefn = ff_yuv2planeX_8_ ## opt; break; \ + case 8: if (condition_8bit) vscalefn = ff_yuv2planeX_8_ ## opt; break; \ } #define ASSIGN_VSCALE_FUNC(vscalefn, opt1, opt2, opt2chk) \ switch(c->dstBpc){ \ case 16: if (!isBE(c->dstFormat)) vscalefn = ff_yuv2plane1_16_ ## opt1; break; \ case 10: if (!isBE(c->dstFormat) && opt2chk) vscalefn = ff_yuv2plane1_10_ ## opt2; break; \ case 9: if (!isBE(c->dstFormat) && opt2chk) vscalefn = ff_yuv2plane1_9_ ## opt2; break; \ - default: vscalefn = ff_yuv2plane1_8_ ## opt1; break; \ + case 8: vscalefn = ff_yuv2plane1_8_ ## opt1; break; \ } #define case_rgb(x, X, opt) \ case AV_PIX_FMT_ ## X: \ From 85406e7a8d5ad12db15ef9d713d0bc3d870fafee Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sat, 24 Sep 2016 22:48:48 +0200 Subject: [PATCH 0182/3374] pixfmt: Add yuv420p12 pixel format --- libavutil/pixdesc.c | 25 +++++++++++++++++++++++ libavutil/pixfmt.h | 4 ++++ libswscale/input.c | 4 ++++ libswscale/output.c | 9 +++++++- libswscale/swscale_unscaled.c | 4 +++- libswscale/utils.c | 2 ++ tests/ref/fate/filter-pixdesc-yuv420p12be | 1 + tests/ref/fate/filter-pixdesc-yuv420p12le | 1 + tests/ref/fate/filter-pixfmts-copy | 2 ++ tests/ref/fate/filter-pixfmts-null | 2 ++ tests/ref/fate/filter-pixfmts-scale | 2 ++ tests/ref/fate/filter-pixfmts-vflip | 2 ++ 12 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 tests/ref/fate/filter-pixdesc-yuv420p12be create mode 100644 tests/ref/fate/filter-pixdesc-yuv420p12le diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index cf2ea9ca40b82..8f116fc638c3f 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -1174,6 +1174,30 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { }, .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, }, + [AV_PIX_FMT_YUV420P12LE] = { + .name = "yuv420p12le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* Y */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* U */ + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV420P12BE] = { + .name = "yuv420p12be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* Y */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* U */ + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, [AV_PIX_FMT_YUV420P16LE] = { .name = "yuv420p16le", .nb_components = 3, @@ -1842,6 +1866,7 @@ enum AVPixelFormat av_pix_fmt_swap_endianness(enum AVPixelFormat pix_fmt) PIX_FMT_SWAP_ENDIANNESS(YUV420P10); PIX_FMT_SWAP_ENDIANNESS(YUV422P10); PIX_FMT_SWAP_ENDIANNESS(YUV444P10); + PIX_FMT_SWAP_ENDIANNESS(YUV420P12); PIX_FMT_SWAP_ENDIANNESS(YUV420P16); PIX_FMT_SWAP_ENDIANNESS(YUV422P16); PIX_FMT_SWAP_ENDIANNESS(YUV444P16); diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index 8a8d624a372f5..658d5bf55b44b 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -230,6 +230,9 @@ enum AVPixelFormat { AV_PIX_FMT_P010LE, ///< like NV12, with 10bpp per component, data in the high bits, zeros in the low bits, little-endian AV_PIX_FMT_P010BE, ///< like NV12, with 10bpp per component, data in the high bits, zeros in the low bits, big-endian + AV_PIX_FMT_YUV420P12BE, ///< planar YUV 4:2:0, 18bpp, (1 Cr & Cb sample per 2x2 Y), big-endian + AV_PIX_FMT_YUV420P12LE, ///< planar YUV 4:2:0, 18bpp, (1 Cr & Cb sample per 2x2 Y), little-endian + AV_PIX_FMT_NB, ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions }; @@ -263,6 +266,7 @@ enum AVPixelFormat { #define AV_PIX_FMT_YUV420P10 AV_PIX_FMT_NE(YUV420P10BE, YUV420P10LE) #define AV_PIX_FMT_YUV422P10 AV_PIX_FMT_NE(YUV422P10BE, YUV422P10LE) #define AV_PIX_FMT_YUV444P10 AV_PIX_FMT_NE(YUV444P10BE, YUV444P10LE) +#define AV_PIX_FMT_YUV420P12 AV_PIX_FMT_NE(YUV420P12BE, YUV420P12LE) #define AV_PIX_FMT_YUV420P16 AV_PIX_FMT_NE(YUV420P16BE, YUV420P16LE) #define AV_PIX_FMT_YUV422P16 AV_PIX_FMT_NE(YUV422P16BE, YUV422P16LE) #define AV_PIX_FMT_YUV444P16 AV_PIX_FMT_NE(YUV444P16BE, YUV444P16LE) diff --git a/libswscale/input.c b/libswscale/input.c index 69c67296665ca..9c0a32c4c6fbb 100644 --- a/libswscale/input.c +++ b/libswscale/input.c @@ -815,6 +815,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_YUV420P10LE: case AV_PIX_FMT_YUV422P10LE: case AV_PIX_FMT_YUV444P10LE: + case AV_PIX_FMT_YUV420P12LE: case AV_PIX_FMT_YUV420P16LE: case AV_PIX_FMT_YUV422P16LE: case AV_PIX_FMT_YUV444P16LE: @@ -836,6 +837,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_YUV420P10BE: case AV_PIX_FMT_YUV422P10BE: case AV_PIX_FMT_YUV444P10BE: + case AV_PIX_FMT_YUV420P12BE: case AV_PIX_FMT_YUV420P16BE: case AV_PIX_FMT_YUV422P16BE: case AV_PIX_FMT_YUV444P16BE: @@ -1033,6 +1035,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_YUV420P10LE: case AV_PIX_FMT_YUV422P10LE: case AV_PIX_FMT_YUV444P10LE: + case AV_PIX_FMT_YUV420P12LE: case AV_PIX_FMT_YUV420P16LE: case AV_PIX_FMT_YUV422P16LE: case AV_PIX_FMT_YUV444P16LE: @@ -1058,6 +1061,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_YUV420P10BE: case AV_PIX_FMT_YUV422P10BE: case AV_PIX_FMT_YUV444P10BE: + case AV_PIX_FMT_YUV420P12BE: case AV_PIX_FMT_YUV420P16BE: case AV_PIX_FMT_YUV422P16BE: case AV_PIX_FMT_YUV444P16BE: diff --git a/libswscale/output.c b/libswscale/output.c index 6a51bb9bdf0bf..78ebbc6b4f112 100644 --- a/libswscale/output.c +++ b/libswscale/output.c @@ -231,6 +231,8 @@ yuv2NBPS( 9, BE, 1, 10, int16_t) yuv2NBPS( 9, LE, 0, 10, int16_t) yuv2NBPS(10, BE, 1, 10, int16_t) yuv2NBPS(10, LE, 0, 10, int16_t) +yuv2NBPS(12, BE, 1, 10, int16_t) +yuv2NBPS(12, LE, 0, 10, int16_t) yuv2NBPS(16, BE, 1, 16, int32_t) yuv2NBPS(16, LE, 0, 16, int32_t) @@ -1368,9 +1370,14 @@ av_cold void ff_sws_init_output_funcs(SwsContext *c, if (desc->comp[0].depth == 9) { *yuv2planeX = isBE(dstFormat) ? yuv2planeX_9BE_c : yuv2planeX_9LE_c; *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_9BE_c : yuv2plane1_9LE_c; - } else { + } else if (desc->comp[0].depth == 10) { *yuv2planeX = isBE(dstFormat) ? yuv2planeX_10BE_c : yuv2planeX_10LE_c; *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_10BE_c : yuv2plane1_10LE_c; + } else if (desc->comp[0].depth == 12) { + *yuv2planeX = isBE(dstFormat) ? yuv2planeX_12BE_c : yuv2planeX_12LE_c; + *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_12BE_c : yuv2plane1_12LE_c; + } else { + assert(0); } } else { *yuv2plane1 = yuv2plane1_8_c; diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index fbdc2affe12d3..87331ae818775 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -1157,8 +1157,10 @@ void ff_get_unscaled_swscale(SwsContext *c) c->chrDstVSubSample == c->chrSrcVSubSample && dstFormat != AV_PIX_FMT_NV12 && dstFormat != AV_PIX_FMT_NV21 && dstFormat != AV_PIX_FMT_P010LE && dstFormat != AV_PIX_FMT_P010BE && + dstFormat != AV_PIX_FMT_YUV420P12LE && dstFormat != AV_PIX_FMT_YUV420P12BE && srcFormat != AV_PIX_FMT_NV12 && srcFormat != AV_PIX_FMT_NV21 && - srcFormat != AV_PIX_FMT_P010LE && srcFormat != AV_PIX_FMT_P010BE)) + srcFormat != AV_PIX_FMT_P010LE && srcFormat != AV_PIX_FMT_P010BE && + srcFormat != AV_PIX_FMT_YUV420P12LE && srcFormat != AV_PIX_FMT_YUV420P12BE)) { if (isPacked(c->srcFormat)) c->swscale = packedCopyWrapper; diff --git a/libswscale/utils.c b/libswscale/utils.c index c4fb7451ebb2f..06b9c1c28bee3 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -165,6 +165,8 @@ static const FormatEntry format_entries[AV_PIX_FMT_NB] = { [AV_PIX_FMT_YUV420P9LE] = { 1, 1 }, [AV_PIX_FMT_YUV420P10BE] = { 1, 1 }, [AV_PIX_FMT_YUV420P10LE] = { 1, 1 }, + [AV_PIX_FMT_YUV420P12BE] = { 1, 1 }, + [AV_PIX_FMT_YUV420P12LE] = { 1, 1 }, [AV_PIX_FMT_YUV422P9BE] = { 1, 1 }, [AV_PIX_FMT_YUV422P9LE] = { 1, 1 }, [AV_PIX_FMT_YUV422P10BE] = { 1, 1 }, diff --git a/tests/ref/fate/filter-pixdesc-yuv420p12be b/tests/ref/fate/filter-pixdesc-yuv420p12be new file mode 100644 index 0000000000000..77cc341d9bb30 --- /dev/null +++ b/tests/ref/fate/filter-pixdesc-yuv420p12be @@ -0,0 +1 @@ +pixdesc-yuv420p12be 6d665168703a982178ac395de9be422f diff --git a/tests/ref/fate/filter-pixdesc-yuv420p12le b/tests/ref/fate/filter-pixdesc-yuv420p12le new file mode 100644 index 0000000000000..8ef325a97d863 --- /dev/null +++ b/tests/ref/fate/filter-pixdesc-yuv420p12le @@ -0,0 +1 @@ +pixdesc-yuv420p12le 0898b89cc0e0aec143fea7d3ecec991b diff --git a/tests/ref/fate/filter-pixfmts-copy b/tests/ref/fate/filter-pixfmts-copy index 2f6a71e8e1b6b..cc1e595df78fe 100644 --- a/tests/ref/fate/filter-pixfmts-copy +++ b/tests/ref/fate/filter-pixfmts-copy @@ -43,6 +43,8 @@ yuv411p fc2f303b20ae610dce86dae4a6671881 yuv420p a2117c3c5d4533dca311dc94a3d157bc yuv420p10be 7756ef359f79d63ef6f983caeaba5c51 yuv420p10le aa8abcc05010b4b0df7d924fd5887291 +yuv420p12be f93fea0e8e10e9f2d006e8f8be5b8938 +yuv420p12le 5d2810e2112328dd88ffddfb486df060 yuv420p16be 7a708532d8ac26d598ac7332e38dd2de yuv420p16le 6b868d3b0c44c6b04f39415890d6ee0b yuv420p9be 11ffb289661f4f55347d60e99dcef632 diff --git a/tests/ref/fate/filter-pixfmts-null b/tests/ref/fate/filter-pixfmts-null index 2f6a71e8e1b6b..cc1e595df78fe 100644 --- a/tests/ref/fate/filter-pixfmts-null +++ b/tests/ref/fate/filter-pixfmts-null @@ -43,6 +43,8 @@ yuv411p fc2f303b20ae610dce86dae4a6671881 yuv420p a2117c3c5d4533dca311dc94a3d157bc yuv420p10be 7756ef359f79d63ef6f983caeaba5c51 yuv420p10le aa8abcc05010b4b0df7d924fd5887291 +yuv420p12be f93fea0e8e10e9f2d006e8f8be5b8938 +yuv420p12le 5d2810e2112328dd88ffddfb486df060 yuv420p16be 7a708532d8ac26d598ac7332e38dd2de yuv420p16le 6b868d3b0c44c6b04f39415890d6ee0b yuv420p9be 11ffb289661f4f55347d60e99dcef632 diff --git a/tests/ref/fate/filter-pixfmts-scale b/tests/ref/fate/filter-pixfmts-scale index fbbc1c9f474e4..aa546752a7a11 100644 --- a/tests/ref/fate/filter-pixfmts-scale +++ b/tests/ref/fate/filter-pixfmts-scale @@ -43,6 +43,8 @@ yuv411p 091777fdfffa2dccbfd75769d1a402c7 yuv420p 4f0105b3f2008bff284de251fe61ce06 yuv420p10be caaee5d071cccf50cc51c70f7a233024 yuv420p10le 06c47286459599c62b25466e2ee3c91d +yuv420p12be b549289c041b852f0fec07d2cca5fb16 +yuv420p12le df151f2b0a8bb7062d35b515cdffca3b yuv420p16be 10ba255f3901b5d47d3ac803fb787bcf yuv420p16le 38c42f658cad8546bfc465b72f6312ab yuv420p9be 17cd0ca2d12fd972045271e06a14b711 diff --git a/tests/ref/fate/filter-pixfmts-vflip b/tests/ref/fate/filter-pixfmts-vflip index da13b160f9f81..29689db5e6d91 100644 --- a/tests/ref/fate/filter-pixfmts-vflip +++ b/tests/ref/fate/filter-pixfmts-vflip @@ -43,6 +43,8 @@ yuv411p a97d81c8a515965209127cfdc718f899 yuv420p daed3fd5e1980ccc4d4409320f16fbf6 yuv420p10be f434af8526dcda2988f15a08cdc4bf98 yuv420p10le 9dcbdb0206713a90fd03b313d99e9ff9 +yuv420p12be 5c3b2cbbb97c38b763f3da61ba5152d2 +yuv420p12le 88e20b45556294e7ca64b323cf115ceb yuv420p16be b8f1a0e4ef98903e2ef8dbce7bc812e2 yuv420p16le 3be4223322a9d904caa2ad7d4ccf3c6a yuv420p9be 34346f74216be11c38cdaeffaba250cc From 0aebbbd024762d3c9c13f4bf0607710feee5e73a Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sat, 24 Sep 2016 20:22:56 +0200 Subject: [PATCH 0183/3374] pixfmt: Add yuv422p12 pixel format --- libavutil/pixdesc.c | 25 +++++++++++++++++++++++ libavutil/pixfmt.h | 4 ++++ libswscale/input.c | 4 ++++ libswscale/swscale_unscaled.c | 4 +++- libswscale/utils.c | 2 ++ tests/ref/fate/filter-pixdesc-yuv422p12be | 1 + tests/ref/fate/filter-pixdesc-yuv422p12le | 1 + tests/ref/fate/filter-pixfmts-copy | 2 ++ tests/ref/fate/filter-pixfmts-null | 2 ++ tests/ref/fate/filter-pixfmts-scale | 2 ++ tests/ref/fate/filter-pixfmts-vflip | 2 ++ 11 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 tests/ref/fate/filter-pixdesc-yuv422p12be create mode 100644 tests/ref/fate/filter-pixdesc-yuv422p12le diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index 8f116fc638c3f..e0c7851abe593 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -1270,6 +1270,30 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { }, .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, }, + [AV_PIX_FMT_YUV422P12LE] = { + .name = "yuv422p12le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* Y */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* U */ + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV422P12BE] = { + .name = "yuv422p12be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* Y */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* U */ + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, [AV_PIX_FMT_YUV422P16LE] = { .name = "yuv422p16le", .nb_components = 3, @@ -1867,6 +1891,7 @@ enum AVPixelFormat av_pix_fmt_swap_endianness(enum AVPixelFormat pix_fmt) PIX_FMT_SWAP_ENDIANNESS(YUV422P10); PIX_FMT_SWAP_ENDIANNESS(YUV444P10); PIX_FMT_SWAP_ENDIANNESS(YUV420P12); + PIX_FMT_SWAP_ENDIANNESS(YUV422P12); PIX_FMT_SWAP_ENDIANNESS(YUV420P16); PIX_FMT_SWAP_ENDIANNESS(YUV422P16); PIX_FMT_SWAP_ENDIANNESS(YUV444P16); diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index 658d5bf55b44b..3e356afa6b34b 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -233,6 +233,9 @@ enum AVPixelFormat { AV_PIX_FMT_YUV420P12BE, ///< planar YUV 4:2:0, 18bpp, (1 Cr & Cb sample per 2x2 Y), big-endian AV_PIX_FMT_YUV420P12LE, ///< planar YUV 4:2:0, 18bpp, (1 Cr & Cb sample per 2x2 Y), little-endian + AV_PIX_FMT_YUV422P12BE, ///< planar YUV 4:2:2, 24bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian + AV_PIX_FMT_YUV422P12LE, ///< planar YUV 4:2:2, 24bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian + AV_PIX_FMT_NB, ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions }; @@ -267,6 +270,7 @@ enum AVPixelFormat { #define AV_PIX_FMT_YUV422P10 AV_PIX_FMT_NE(YUV422P10BE, YUV422P10LE) #define AV_PIX_FMT_YUV444P10 AV_PIX_FMT_NE(YUV444P10BE, YUV444P10LE) #define AV_PIX_FMT_YUV420P12 AV_PIX_FMT_NE(YUV420P12BE, YUV420P12LE) +#define AV_PIX_FMT_YUV422P12 AV_PIX_FMT_NE(YUV422P12BE, YUV422P12LE) #define AV_PIX_FMT_YUV420P16 AV_PIX_FMT_NE(YUV420P16BE, YUV420P16LE) #define AV_PIX_FMT_YUV422P16 AV_PIX_FMT_NE(YUV422P16BE, YUV422P16LE) #define AV_PIX_FMT_YUV444P16 AV_PIX_FMT_NE(YUV444P16BE, YUV444P16LE) diff --git a/libswscale/input.c b/libswscale/input.c index 9c0a32c4c6fbb..76a47001229a3 100644 --- a/libswscale/input.c +++ b/libswscale/input.c @@ -816,6 +816,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_YUV422P10LE: case AV_PIX_FMT_YUV444P10LE: case AV_PIX_FMT_YUV420P12LE: + case AV_PIX_FMT_YUV422P12LE: case AV_PIX_FMT_YUV420P16LE: case AV_PIX_FMT_YUV422P16LE: case AV_PIX_FMT_YUV444P16LE: @@ -838,6 +839,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_YUV422P10BE: case AV_PIX_FMT_YUV444P10BE: case AV_PIX_FMT_YUV420P12BE: + case AV_PIX_FMT_YUV422P12BE: case AV_PIX_FMT_YUV420P16BE: case AV_PIX_FMT_YUV422P16BE: case AV_PIX_FMT_YUV444P16BE: @@ -1036,6 +1038,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_YUV422P10LE: case AV_PIX_FMT_YUV444P10LE: case AV_PIX_FMT_YUV420P12LE: + case AV_PIX_FMT_YUV422P12LE: case AV_PIX_FMT_YUV420P16LE: case AV_PIX_FMT_YUV422P16LE: case AV_PIX_FMT_YUV444P16LE: @@ -1062,6 +1065,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_YUV422P10BE: case AV_PIX_FMT_YUV444P10BE: case AV_PIX_FMT_YUV420P12BE: + case AV_PIX_FMT_YUV422P12BE: case AV_PIX_FMT_YUV420P16BE: case AV_PIX_FMT_YUV422P16BE: case AV_PIX_FMT_YUV444P16BE: diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index 87331ae818775..31706ca4c2975 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -1158,9 +1158,11 @@ void ff_get_unscaled_swscale(SwsContext *c) dstFormat != AV_PIX_FMT_NV12 && dstFormat != AV_PIX_FMT_NV21 && dstFormat != AV_PIX_FMT_P010LE && dstFormat != AV_PIX_FMT_P010BE && dstFormat != AV_PIX_FMT_YUV420P12LE && dstFormat != AV_PIX_FMT_YUV420P12BE && + dstFormat != AV_PIX_FMT_YUV422P12LE && dstFormat != AV_PIX_FMT_YUV422P12BE && srcFormat != AV_PIX_FMT_NV12 && srcFormat != AV_PIX_FMT_NV21 && srcFormat != AV_PIX_FMT_P010LE && srcFormat != AV_PIX_FMT_P010BE && - srcFormat != AV_PIX_FMT_YUV420P12LE && srcFormat != AV_PIX_FMT_YUV420P12BE)) + srcFormat != AV_PIX_FMT_YUV420P12LE && srcFormat != AV_PIX_FMT_YUV420P12BE && + srcFormat != AV_PIX_FMT_YUV422P12LE && srcFormat != AV_PIX_FMT_YUV422P12BE)) { if (isPacked(c->srcFormat)) c->swscale = packedCopyWrapper; diff --git a/libswscale/utils.c b/libswscale/utils.c index 06b9c1c28bee3..dc442929b9680 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -171,6 +171,8 @@ static const FormatEntry format_entries[AV_PIX_FMT_NB] = { [AV_PIX_FMT_YUV422P9LE] = { 1, 1 }, [AV_PIX_FMT_YUV422P10BE] = { 1, 1 }, [AV_PIX_FMT_YUV422P10LE] = { 1, 1 }, + [AV_PIX_FMT_YUV422P12BE] = { 1, 1 }, + [AV_PIX_FMT_YUV422P12LE] = { 1, 1 }, [AV_PIX_FMT_YUV444P9BE] = { 1, 1 }, [AV_PIX_FMT_YUV444P9LE] = { 1, 1 }, [AV_PIX_FMT_YUV444P10BE] = { 1, 1 }, diff --git a/tests/ref/fate/filter-pixdesc-yuv422p12be b/tests/ref/fate/filter-pixdesc-yuv422p12be new file mode 100644 index 0000000000000..8cfd917731aba --- /dev/null +++ b/tests/ref/fate/filter-pixdesc-yuv422p12be @@ -0,0 +1 @@ +pixdesc-yuv422p12be 470f5361088e1af7f6ae70945d411a25 diff --git a/tests/ref/fate/filter-pixdesc-yuv422p12le b/tests/ref/fate/filter-pixdesc-yuv422p12le new file mode 100644 index 0000000000000..e457288969f95 --- /dev/null +++ b/tests/ref/fate/filter-pixdesc-yuv422p12le @@ -0,0 +1 @@ +pixdesc-yuv422p12le dd79803aff3bf939c818304884341c17 diff --git a/tests/ref/fate/filter-pixfmts-copy b/tests/ref/fate/filter-pixfmts-copy index cc1e595df78fe..6ffeed0544082 100644 --- a/tests/ref/fate/filter-pixfmts-copy +++ b/tests/ref/fate/filter-pixfmts-copy @@ -52,6 +52,8 @@ yuv420p9le a0c9608b2be3ca6d4e8cf625714a3833 yuv422p b082344038849f5fd444ccf2a30e3f4f yuv422p10be 43a6293e138d0ecfd3385df3dcf9b713 yuv422p10le 74da030a4efb5a20986fcead50018f4d +yuv422p12be d60480c872d6723e587199ee4ecfe86d +yuv422p12le 2cbf87d44e9c897ec6460225d47efbda yuv422p16be f7a0fb9e82805660317d07209e726100 yuv422p16le 12eeb2f95bb0d655d52e8eed1cfbf771 yuv422p9be 60daf1a7e61434b244c5a43f4449b617 diff --git a/tests/ref/fate/filter-pixfmts-null b/tests/ref/fate/filter-pixfmts-null index cc1e595df78fe..6ffeed0544082 100644 --- a/tests/ref/fate/filter-pixfmts-null +++ b/tests/ref/fate/filter-pixfmts-null @@ -52,6 +52,8 @@ yuv420p9le a0c9608b2be3ca6d4e8cf625714a3833 yuv422p b082344038849f5fd444ccf2a30e3f4f yuv422p10be 43a6293e138d0ecfd3385df3dcf9b713 yuv422p10le 74da030a4efb5a20986fcead50018f4d +yuv422p12be d60480c872d6723e587199ee4ecfe86d +yuv422p12le 2cbf87d44e9c897ec6460225d47efbda yuv422p16be f7a0fb9e82805660317d07209e726100 yuv422p16le 12eeb2f95bb0d655d52e8eed1cfbf771 yuv422p9be 60daf1a7e61434b244c5a43f4449b617 diff --git a/tests/ref/fate/filter-pixfmts-scale b/tests/ref/fate/filter-pixfmts-scale index aa546752a7a11..a56d5c776b39d 100644 --- a/tests/ref/fate/filter-pixfmts-scale +++ b/tests/ref/fate/filter-pixfmts-scale @@ -52,6 +52,8 @@ yuv420p9le 38289963713431c8b4a2e7c08b8564b6 yuv422p 66f47bfad422275bd07b2881760d09a2 yuv422p10be 00504b09c67e203fc29cac3ae2aa91db yuv422p10le b8b38a8d1f1eec3915b628c873bf756a +yuv422p12be 0ab7660a9a52abe41edf8d6b3f75942a +yuv422p12le bde450e4b79a13aaaba8233df3c51f4d yuv422p16be 2f12b4fb816afcaa77e7359b95f25532 yuv422p16le 3913bbbd4b0aa8038e8565c7312e25be yuv422p9be f86744d026c3a65d54c737a93e80093f diff --git a/tests/ref/fate/filter-pixfmts-vflip b/tests/ref/fate/filter-pixfmts-vflip index 29689db5e6d91..9e7a916fafbd1 100644 --- a/tests/ref/fate/filter-pixfmts-vflip +++ b/tests/ref/fate/filter-pixfmts-vflip @@ -52,6 +52,8 @@ yuv420p9le 8248d1c10aa86ef8e4b212a2d9fca937 yuv422p 5a58e1fe687b71e28f52aeb11b999e46 yuv422p10be adaf99408661a1dc3c667cad992c08d7 yuv422p10le bc071b965f5a1b3c7349b71bd2b4247c +yuv422p12be e1ab3898be486cd95e6332fa81570f63 +yuv422p12le 343a7281c6d30c09ed7b8be86bd6d42f yuv422p16be 1ec214fba454c456d83de5220c867ede yuv422p16le 9f9316d40597c9fb917d921bfbcd8421 yuv422p9be 98e7cefa912845b488f85508a7be7e04 From 9bd6ea5695660529b2887292874a7b9e61fc301e Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sat, 24 Sep 2016 23:09:43 +0200 Subject: [PATCH 0184/3374] pixfmt: Add yuv444p12 pixel format --- libavutil/pixdesc.c | 25 +++++++++++++++++++++++ libavutil/pixfmt.h | 4 ++++ libswscale/swscale_unscaled.c | 4 +++- libswscale/utils.c | 2 ++ tests/ref/fate/filter-pixdesc-yuv444p12be | 1 + tests/ref/fate/filter-pixdesc-yuv444p12le | 1 + tests/ref/fate/filter-pixfmts-copy | 2 ++ tests/ref/fate/filter-pixfmts-null | 2 ++ tests/ref/fate/filter-pixfmts-scale | 2 ++ tests/ref/fate/filter-pixfmts-vflip | 2 ++ 10 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 tests/ref/fate/filter-pixdesc-yuv444p12be create mode 100644 tests/ref/fate/filter-pixdesc-yuv444p12le diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index e0c7851abe593..78fbdbc01ba99 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -1342,6 +1342,30 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { }, .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, }, + [AV_PIX_FMT_YUV444P12LE] = { + .name = "yuv444p12le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* Y */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* U */ + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV444P12BE] = { + .name = "yuv444p12be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* Y */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* U */ + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, [AV_PIX_FMT_YUV444P10LE] = { .name = "yuv444p10le", .nb_components = 3, @@ -1892,6 +1916,7 @@ enum AVPixelFormat av_pix_fmt_swap_endianness(enum AVPixelFormat pix_fmt) PIX_FMT_SWAP_ENDIANNESS(YUV444P10); PIX_FMT_SWAP_ENDIANNESS(YUV420P12); PIX_FMT_SWAP_ENDIANNESS(YUV422P12); + PIX_FMT_SWAP_ENDIANNESS(YUV444P12); PIX_FMT_SWAP_ENDIANNESS(YUV420P16); PIX_FMT_SWAP_ENDIANNESS(YUV422P16); PIX_FMT_SWAP_ENDIANNESS(YUV444P16); diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index 3e356afa6b34b..908b0fe7a5bce 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -236,6 +236,9 @@ enum AVPixelFormat { AV_PIX_FMT_YUV422P12BE, ///< planar YUV 4:2:2, 24bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian AV_PIX_FMT_YUV422P12LE, ///< planar YUV 4:2:2, 24bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian + AV_PIX_FMT_YUV444P12BE, ///< planar YUV 4:4:4, 36bpp, (1 Cr & Cb sample per 1x1 Y), big-endian + AV_PIX_FMT_YUV444P12LE, ///< planar YUV 4:4:4, 36bpp, (1 Cr & Cb sample per 1x1 Y), little-endian + AV_PIX_FMT_NB, ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions }; @@ -271,6 +274,7 @@ enum AVPixelFormat { #define AV_PIX_FMT_YUV444P10 AV_PIX_FMT_NE(YUV444P10BE, YUV444P10LE) #define AV_PIX_FMT_YUV420P12 AV_PIX_FMT_NE(YUV420P12BE, YUV420P12LE) #define AV_PIX_FMT_YUV422P12 AV_PIX_FMT_NE(YUV422P12BE, YUV422P12LE) +#define AV_PIX_FMT_YUV444P12 AV_PIX_FMT_NE(YUV444P12BE, YUV444P12LE) #define AV_PIX_FMT_YUV420P16 AV_PIX_FMT_NE(YUV420P16BE, YUV420P16LE) #define AV_PIX_FMT_YUV422P16 AV_PIX_FMT_NE(YUV422P16BE, YUV422P16LE) #define AV_PIX_FMT_YUV444P16 AV_PIX_FMT_NE(YUV444P16BE, YUV444P16LE) diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index 31706ca4c2975..ad87bbcb46db0 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -1159,10 +1159,12 @@ void ff_get_unscaled_swscale(SwsContext *c) dstFormat != AV_PIX_FMT_P010LE && dstFormat != AV_PIX_FMT_P010BE && dstFormat != AV_PIX_FMT_YUV420P12LE && dstFormat != AV_PIX_FMT_YUV420P12BE && dstFormat != AV_PIX_FMT_YUV422P12LE && dstFormat != AV_PIX_FMT_YUV422P12BE && + dstFormat != AV_PIX_FMT_YUV444P12LE && dstFormat != AV_PIX_FMT_YUV444P12BE && srcFormat != AV_PIX_FMT_NV12 && srcFormat != AV_PIX_FMT_NV21 && srcFormat != AV_PIX_FMT_P010LE && srcFormat != AV_PIX_FMT_P010BE && srcFormat != AV_PIX_FMT_YUV420P12LE && srcFormat != AV_PIX_FMT_YUV420P12BE && - srcFormat != AV_PIX_FMT_YUV422P12LE && srcFormat != AV_PIX_FMT_YUV422P12BE)) + srcFormat != AV_PIX_FMT_YUV422P12LE && srcFormat != AV_PIX_FMT_YUV422P12BE && + srcFormat != AV_PIX_FMT_YUV444P12LE && srcFormat != AV_PIX_FMT_YUV444P12BE)) { if (isPacked(c->srcFormat)) c->swscale = packedCopyWrapper; diff --git a/libswscale/utils.c b/libswscale/utils.c index dc442929b9680..b7b534dceb254 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -177,6 +177,8 @@ static const FormatEntry format_entries[AV_PIX_FMT_NB] = { [AV_PIX_FMT_YUV444P9LE] = { 1, 1 }, [AV_PIX_FMT_YUV444P10BE] = { 1, 1 }, [AV_PIX_FMT_YUV444P10LE] = { 1, 1 }, + [AV_PIX_FMT_YUV444P12BE] = { 1, 1 }, + [AV_PIX_FMT_YUV444P12LE] = { 1, 1 }, [AV_PIX_FMT_GBRP] = { 1, 1 }, [AV_PIX_FMT_GBRP9LE] = { 1, 1 }, [AV_PIX_FMT_GBRP9BE] = { 1, 1 }, diff --git a/tests/ref/fate/filter-pixdesc-yuv444p12be b/tests/ref/fate/filter-pixdesc-yuv444p12be new file mode 100644 index 0000000000000..e8c1201985940 --- /dev/null +++ b/tests/ref/fate/filter-pixdesc-yuv444p12be @@ -0,0 +1 @@ +pixdesc-yuv444p12be f20564006d137df0fc6bb7466fd0fc64 diff --git a/tests/ref/fate/filter-pixdesc-yuv444p12le b/tests/ref/fate/filter-pixdesc-yuv444p12le new file mode 100644 index 0000000000000..9807ff074aac9 --- /dev/null +++ b/tests/ref/fate/filter-pixdesc-yuv444p12le @@ -0,0 +1 @@ +pixdesc-yuv444p12le 9d5db1a9354b62181e09aa93c1ffa19a diff --git a/tests/ref/fate/filter-pixfmts-copy b/tests/ref/fate/filter-pixfmts-copy index 6ffeed0544082..c712f781482b8 100644 --- a/tests/ref/fate/filter-pixfmts-copy +++ b/tests/ref/fate/filter-pixfmts-copy @@ -62,6 +62,8 @@ yuv440p 12000ce709b38aac3f7b7f59b07847ef yuv444p 628c9d1e10c22e0e512b27c0e03b46e6 yuv444p10be b60d77db54a592ed088ebf7964e2dd5e yuv444p10le 1752a238eb27fb7c746e349536f60686 +yuv444p12be be54f88f9b9034b5b9bc466132bfba10 +yuv444p12le 714c3c5789897b56cb9ae6a45688e395 yuv444p16be 8e1e2f04cb2e97f80fdfecbb2c5679a0 yuv444p16le 5677b2caa63e0c075eac6937b03cf2a6 yuv444p9be 5ab55576b180b2966e9ed5a1ea55508a diff --git a/tests/ref/fate/filter-pixfmts-null b/tests/ref/fate/filter-pixfmts-null index 6ffeed0544082..c712f781482b8 100644 --- a/tests/ref/fate/filter-pixfmts-null +++ b/tests/ref/fate/filter-pixfmts-null @@ -62,6 +62,8 @@ yuv440p 12000ce709b38aac3f7b7f59b07847ef yuv444p 628c9d1e10c22e0e512b27c0e03b46e6 yuv444p10be b60d77db54a592ed088ebf7964e2dd5e yuv444p10le 1752a238eb27fb7c746e349536f60686 +yuv444p12be be54f88f9b9034b5b9bc466132bfba10 +yuv444p12le 714c3c5789897b56cb9ae6a45688e395 yuv444p16be 8e1e2f04cb2e97f80fdfecbb2c5679a0 yuv444p16le 5677b2caa63e0c075eac6937b03cf2a6 yuv444p9be 5ab55576b180b2966e9ed5a1ea55508a diff --git a/tests/ref/fate/filter-pixfmts-scale b/tests/ref/fate/filter-pixfmts-scale index a56d5c776b39d..0a3f3f18c6ee1 100644 --- a/tests/ref/fate/filter-pixfmts-scale +++ b/tests/ref/fate/filter-pixfmts-scale @@ -62,6 +62,8 @@ yuv440p 4713a7b7ce80dd06923626d13589c098 yuv444p fd733672651ad5bbffb046fd67151fee yuv444p10be 34b38d54167df70044bdc08518d91009 yuv444p10le 0812e3371c9589c6621408812f9e7a27 +yuv444p12be 936147950ba1b511570da85a0922abf3 +yuv444p12le 4a9ec677190371ef5e342ffac1ace735 yuv444p16be e89fe5a4624ed06603580b4a74af9170 yuv444p16le 6944d11048ff4013c5e60359faf1bd2d yuv444p9be 04a950e843d099eb9ade2ddcea494fb3 diff --git a/tests/ref/fate/filter-pixfmts-vflip b/tests/ref/fate/filter-pixfmts-vflip index 9e7a916fafbd1..b8718c7375675 100644 --- a/tests/ref/fate/filter-pixfmts-vflip +++ b/tests/ref/fate/filter-pixfmts-vflip @@ -62,6 +62,8 @@ yuv440p fade395d957e1e3b117ac11c09404964 yuv444p a3c2a074c3609226bf1a0bc4de5c0e51 yuv444p10be b02fac8bc5a564a755567a86dc3ceae0 yuv444p10le 88860297f729c90526b157b6bf1e2fcf +yuv444p12be d8af56e4b09130e14a9449c84a03cab0 +yuv444p12le 0ccfbd671b8000c0f950b9dfae8ea879 yuv444p16be 26fbffad3c28aa1a6c47f2be6d146173 yuv444p16le 3d13dcea82caec9eb563a1d7a2e4b339 yuv444p9be df39c0778e5b13f306e9928c5b0ddbb2 From 2b5b1e1e9b89063d352e2efed014f9d761b85032 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Tue, 27 Sep 2016 18:13:37 +0200 Subject: [PATCH 0185/3374] swscale: Rename is9_OR_10 to match what it does It is used to select functions that work with 9-15bits. --- libswscale/output.c | 2 +- libswscale/ppc/swscale_altivec.c | 2 +- libswscale/swscale.c | 4 ++-- libswscale/swscale_internal.h | 2 +- libswscale/swscale_unscaled.c | 8 ++++---- libswscale/x86/swscale_template.c | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/libswscale/output.c b/libswscale/output.c index 93b3db65ebf20..6a51bb9bdf0bf 100644 --- a/libswscale/output.c +++ b/libswscale/output.c @@ -1364,7 +1364,7 @@ av_cold void ff_sws_init_output_funcs(SwsContext *c, if (is16BPS(dstFormat)) { *yuv2planeX = isBE(dstFormat) ? yuv2planeX_16BE_c : yuv2planeX_16LE_c; *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_16BE_c : yuv2plane1_16LE_c; - } else if (is9_OR_10BPS(dstFormat)) { + } else if (is9_15BPS(dstFormat)) { if (desc->comp[0].depth == 9) { *yuv2planeX = isBE(dstFormat) ? yuv2planeX_9BE_c : yuv2planeX_9LE_c; *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_9BE_c : yuv2plane1_9LE_c; diff --git a/libswscale/ppc/swscale_altivec.c b/libswscale/ppc/swscale_altivec.c index 004b385af2b1c..9e3ddf359d79f 100644 --- a/libswscale/ppc/swscale_altivec.c +++ b/libswscale/ppc/swscale_altivec.c @@ -298,7 +298,7 @@ av_cold void ff_sws_init_swscale_ppc(SwsContext *c) if (c->srcBpc == 8 && c->dstBpc <= 10) { c->hyScale = c->hcScale = hScale_altivec_real; } - if (!is16BPS(dstFormat) && !is9_OR_10BPS(dstFormat) && + if (!is16BPS(dstFormat) && !is9_15BPS(dstFormat) && dstFormat != AV_PIX_FMT_NV12 && dstFormat != AV_PIX_FMT_NV21 && !c->alpPixBuf) { c->yuv2planeX = yuv2planeX_altivec; diff --git a/libswscale/swscale.c b/libswscale/swscale.c index 142c79c14a118..987a3bb82007f 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -386,7 +386,7 @@ static int swscale(SwsContext *c, const uint8_t *src[], yuv2anyX_fn yuv2anyX = c->yuv2anyX; const int chrSrcSliceY = srcSliceY >> c->chrSrcVSubSample; const int chrSrcSliceH = AV_CEIL_RSHIFT(srcSliceH, c->chrSrcVSubSample); - int should_dither = is9_OR_10BPS(c->srcFormat) || + int should_dither = is9_15BPS(c->srcFormat) || is16BPS(c->srcFormat); int lastDstY; @@ -696,7 +696,7 @@ static int swscale(SwsContext *c, const uint8_t *src[], if (is16BPS(c->dstFormat)) length *= 2; - if (is9_OR_10BPS(dstFormat)) { + if (is9_15BPS(dstFormat)) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(dstFormat); fill_plane9or10(dst[3], dstStride[3], length, height, lastDstY, 255, desc->comp[3].depth, isBE(dstFormat)); diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index 625bd864a48cb..abcdb9f41b8fb 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -565,7 +565,7 @@ static av_always_inline int is16BPS(enum AVPixelFormat pix_fmt) return desc->comp[0].depth == 16; } -static av_always_inline int is9_OR_10BPS(enum AVPixelFormat pix_fmt) +static av_always_inline int is9_15BPS(enum AVPixelFormat pix_fmt) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); av_assert0(desc); diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index 0e6be515ea78a..fbdc2affe12d3 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -813,7 +813,7 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t *src[], int val = (plane == 3) ? 255 : 128; if (is16BPS(c->dstFormat)) length *= 2; - if (is9_OR_10BPS(c->dstFormat)) { + if (is9_15BPS(c->dstFormat)) { fill_plane9or10(dst[plane], dstStride[plane], length, height, y, val, desc_dst->comp[plane].depth, @@ -822,7 +822,7 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t *src[], fillPlane(dst[plane], dstStride[plane], length, height, y, val); } else { - if (is9_OR_10BPS(c->srcFormat)) { + if (is9_15BPS(c->srcFormat)) { const int src_depth = desc_src->comp[plane].depth; const int dst_depth = desc_dst->comp[plane].depth; const uint16_t *srcPtr2 = (const uint16_t *) srcPtr; @@ -862,7 +862,7 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t *src[], COPY9_OR_10TO16(AV_RL16, AV_WL16); } } - } else if (is9_OR_10BPS(c->dstFormat)) { + } else if (is9_15BPS(c->dstFormat)) { uint16_t *dstPtr2 = (uint16_t *) dstPtr; #define COPY9_OR_10TO9_OR_10(loop) \ for (i = 0; i < height; i++) { \ @@ -914,7 +914,7 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t *src[], COPY9_OR_10TO8(AV_RL16); } } - } else if (is9_OR_10BPS(c->dstFormat)) { + } else if (is9_15BPS(c->dstFormat)) { const int dst_depth = desc_dst->comp[plane].depth; uint16_t *dstPtr2 = (uint16_t *) dstPtr; diff --git a/libswscale/x86/swscale_template.c b/libswscale/x86/swscale_template.c index 3fb8bc8882831..e0d1abe207349 100644 --- a/libswscale/x86/swscale_template.c +++ b/libswscale/x86/swscale_template.c @@ -1564,7 +1564,7 @@ static av_cold void RENAME(sws_init_swscale)(SwsContext *c) { enum AVPixelFormat dstFormat = c->dstFormat; - if (!is16BPS(dstFormat) && !is9_OR_10BPS(dstFormat) && + if (!is16BPS(dstFormat) && !is9_15BPS(dstFormat) && dstFormat != AV_PIX_FMT_NV12 && dstFormat != AV_PIX_FMT_NV21) { if (!(c->flags & SWS_BITEXACT)) { if (c->flags & SWS_ACCURATE_RND) { From 0e8d1fc1f013eb805a7b66656d9452bcbca36d22 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 26 Sep 2016 18:16:39 +0200 Subject: [PATCH 0186/3374] lavu: Bump version for the 12bit Planar YUV support --- doc/APIchanges | 3 +++ libavutil/version.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index 43e32623f7634..6859081b0e5f7 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-xx-xx - xxxxxxx - lavu 55.22.0 - pixfmt.h + Add AV_PIX_FMT_YUV(420,422,444)P12. + 2016-xx-xx - xxxxxxx - lavc 59.27.0 - avcodec.h Add FF_PROFILE_HEVC_REXT, the extended pixel format profile for HEVC. diff --git a/libavutil/version.h b/libavutil/version.h index f63dfa5d3f7cc..f05e72ce1379f 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -54,7 +54,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 21 +#define LIBAVUTIL_VERSION_MINOR 22 #define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From 6c09af7e46a5a1ada67ffe832f7895cf2749130b Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 27 Sep 2016 15:47:22 +0200 Subject: [PATCH 0187/3374] APIchanges: fix a typo in the version number --- doc/APIchanges | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index 6859081b0e5f7..d0ffca2e80d4b 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -16,7 +16,7 @@ API changes, most recent first: 2016-xx-xx - xxxxxxx - lavu 55.22.0 - pixfmt.h Add AV_PIX_FMT_YUV(420,422,444)P12. -2016-xx-xx - xxxxxxx - lavc 59.27.0 - avcodec.h +2016-xx-xx - xxxxxxx - lavc 57.27.0 - avcodec.h Add FF_PROFILE_HEVC_REXT, the extended pixel format profile for HEVC. 2016-08-24 - xxxxxxx - lavu 55.21.0 - imgutils.h From 6f733ecab6faff2a16534f2ce7d2ffd41c07846b Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 21 Sep 2016 20:06:11 +0200 Subject: [PATCH 0188/3374] mpegvideo_enc: add const to the AVCodec instance --- libavcodec/mpegvideo_enc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index d738d06ee63cd..46e2e2c3fc118 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -1259,7 +1259,7 @@ static int encode_frame(AVCodecContext *c, AVFrame *frame) static int estimate_best_b_count(MpegEncContext *s) { - AVCodec *codec = avcodec_find_encoder(s->avctx->codec_id); + const AVCodec *codec = avcodec_find_encoder(s->avctx->codec_id); AVCodecContext *c = avcodec_alloc_context3(NULL); const int scale = s->brd_scale; int i, j, out_size, p_lambda, b_lambda, lambda2; From f03f78bc1c99b1e29624418e2f7315b8a47981e9 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 21 Sep 2016 20:21:58 +0200 Subject: [PATCH 0189/3374] mpegvideo_enc: handle encoding errors with b_strategy=2 --- libavcodec/mpegvideo_enc.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index 46e2e2c3fc118..6ab9ba57f5793 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -1265,6 +1265,7 @@ static int estimate_best_b_count(MpegEncContext *s) int i, j, out_size, p_lambda, b_lambda, lambda2; int64_t best_rd = INT64_MAX; int best_b_count = -1; + int ret = 0; if (!c) return AVERROR(ENOMEM); @@ -1338,6 +1339,10 @@ static int estimate_best_b_count(MpegEncContext *s) s->tmp_frames[0]->quality = 1 * FF_QP2LAMBDA; out_size = encode_frame(c, s->tmp_frames[0]); + if (out_size < 0) { + ret = out_size; + goto fail; + } //rd += (out_size * lambda2) >> FF_LAMBDA_SHIFT; @@ -1349,6 +1354,10 @@ static int estimate_best_b_count(MpegEncContext *s) s->tmp_frames[i + 1]->quality = is_p ? p_lambda : b_lambda; out_size = encode_frame(c, s->tmp_frames[i + 1]); + if (out_size < 0) { + ret = out_size; + goto fail; + } rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3); } @@ -1356,6 +1365,10 @@ static int estimate_best_b_count(MpegEncContext *s) /* get the delayed frames */ while (out_size) { out_size = encode_frame(c, NULL); + if (out_size < 0) { + ret = out_size; + goto fail; + } rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3); } @@ -1370,6 +1383,9 @@ static int estimate_best_b_count(MpegEncContext *s) avcodec_free_context(&c); return best_b_count; +fail: + avcodec_free_context(&c); + return ret; } static int select_input_picture(MpegEncContext *s) @@ -1450,6 +1466,8 @@ static int select_input_picture(MpegEncContext *s) } } else if (s->b_frame_strategy == 2) { b_frames = estimate_best_b_count(s); + if (b_frames < 0) + return b_frames; } emms_c(); From 68811a41c70f019bde6df2a4f289674228c48958 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 21 Sep 2016 20:22:14 +0200 Subject: [PATCH 0190/3374] mpegvideo_enc: use the new encoding API for b_strategy=2 --- libavcodec/mpegvideo_enc.c | 88 +++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 39 deletions(-) diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index 6ab9ba57f5793..6a7c9e500fb7e 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -1245,30 +1245,38 @@ static int skip_check(MpegEncContext *s, Picture *p, Picture *ref) static int encode_frame(AVCodecContext *c, AVFrame *frame) { AVPacket pkt = { 0 }; - int ret, got_output; + int ret; + int size = 0; av_init_packet(&pkt); - ret = avcodec_encode_video2(c, &pkt, frame, &got_output); + + ret = avcodec_send_frame(c, frame); if (ret < 0) return ret; - ret = pkt.size; - av_packet_unref(&pkt); - return ret; + do { + ret = avcodec_receive_packet(c, &pkt); + if (ret >= 0) { + size += pkt.size; + av_packet_unref(&pkt); + } else if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) + return ret; + } while (ret >= 0); + + return size; } static int estimate_best_b_count(MpegEncContext *s) { const AVCodec *codec = avcodec_find_encoder(s->avctx->codec_id); - AVCodecContext *c = avcodec_alloc_context3(NULL); const int scale = s->brd_scale; + int width = s->width >> scale; + int height = s->height >> scale; int i, j, out_size, p_lambda, b_lambda, lambda2; int64_t best_rd = INT64_MAX; int best_b_count = -1; int ret = 0; - if (!c) - return AVERROR(ENOMEM); assert(scale >= 0 && scale <= 3); //emms_c(); @@ -1281,21 +1289,6 @@ static int estimate_best_b_count(MpegEncContext *s) lambda2 = (b_lambda * b_lambda + (1 << FF_LAMBDA_SHIFT) / 2) >> FF_LAMBDA_SHIFT; - c->width = s->width >> scale; - c->height = s->height >> scale; - c->flags = AV_CODEC_FLAG_QSCALE | AV_CODEC_FLAG_PSNR; - c->flags |= s->avctx->flags & AV_CODEC_FLAG_QPEL; - c->mb_decision = s->avctx->mb_decision; - c->me_cmp = s->avctx->me_cmp; - c->mb_cmp = s->avctx->mb_cmp; - c->me_sub_cmp = s->avctx->me_sub_cmp; - c->pix_fmt = AV_PIX_FMT_YUV420P; - c->time_base = s->avctx->time_base; - c->max_b_frames = s->max_b_frames; - - if (avcodec_open2(c, codec, NULL) < 0) - return -1; - for (i = 0; i < s->max_b_frames + 2; i++) { Picture pre_input, *pre_input_ptr = i ? s->input_picture[i - 1] : s->next_picture_ptr; @@ -1313,27 +1306,46 @@ static int estimate_best_b_count(MpegEncContext *s) s->tmp_frames[i]->linesize[0], pre_input.f->data[0], pre_input.f->linesize[0], - c->width, c->height); + width, height); s->mpvencdsp.shrink[scale](s->tmp_frames[i]->data[1], s->tmp_frames[i]->linesize[1], pre_input.f->data[1], pre_input.f->linesize[1], - c->width >> 1, c->height >> 1); + width >> 1, height >> 1); s->mpvencdsp.shrink[scale](s->tmp_frames[i]->data[2], s->tmp_frames[i]->linesize[2], pre_input.f->data[2], pre_input.f->linesize[2], - c->width >> 1, c->height >> 1); + width >> 1, height >> 1); } } for (j = 0; j < s->max_b_frames + 1; j++) { + AVCodecContext *c; int64_t rd = 0; if (!s->input_picture[j]) break; - c->error[0] = c->error[1] = c->error[2] = 0; + c = avcodec_alloc_context3(NULL); + if (!c) + return AVERROR(ENOMEM); + + c->width = width; + c->height = height; + c->flags = AV_CODEC_FLAG_QSCALE | AV_CODEC_FLAG_PSNR; + c->flags |= s->avctx->flags & AV_CODEC_FLAG_QPEL; + c->mb_decision = s->avctx->mb_decision; + c->me_cmp = s->avctx->me_cmp; + c->mb_cmp = s->avctx->mb_cmp; + c->me_sub_cmp = s->avctx->me_sub_cmp; + c->pix_fmt = AV_PIX_FMT_YUV420P; + c->time_base = s->avctx->time_base; + c->max_b_frames = s->max_b_frames; + + ret = avcodec_open2(c, codec, NULL); + if (ret < 0) + goto fail; s->tmp_frames[0]->pict_type = AV_PICTURE_TYPE_I; s->tmp_frames[0]->quality = 1 * FF_QP2LAMBDA; @@ -1363,14 +1375,12 @@ static int estimate_best_b_count(MpegEncContext *s) } /* get the delayed frames */ - while (out_size) { - out_size = encode_frame(c, NULL); - if (out_size < 0) { - ret = out_size; - goto fail; - } - rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3); + out_size = encode_frame(c, NULL); + if (out_size < 0) { + ret = out_size; + goto fail; } + rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3); rd += c->error[0] + c->error[1] + c->error[2]; @@ -1378,14 +1388,14 @@ static int estimate_best_b_count(MpegEncContext *s) best_rd = rd; best_b_count = j; } - } - avcodec_free_context(&c); +fail: + avcodec_free_context(&c); + if (ret < 0) + return ret; + } return best_b_count; -fail: - avcodec_free_context(&c); - return ret; } static int select_input_picture(MpegEncContext *s) From de2ae3c1fae5a2eb539b9abd7bc2a9ca8c286ff0 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 21 Sep 2016 20:44:36 +0200 Subject: [PATCH 0191/3374] lavc: add clobber tests for the new encoding/decoding API --- configure | 8 ++++++++ libavcodec/aarch64/neontest.c | 20 ++++++++++++++++++++ libavcodec/arm/neontest.c | 20 ++++++++++++++++++++ libavcodec/x86/w64xmmtest.c | 20 ++++++++++++++++++++ 4 files changed, 68 insertions(+) diff --git a/configure b/configure index 1f5fb8a3566ee..3c416da8b8b32 100755 --- a/configure +++ b/configure @@ -4831,6 +4831,10 @@ enabled neon_clobber_test && -Wl,--wrap,avcodec_encode_audio2 \ -Wl,--wrap,avcodec_encode_video2 \ -Wl,--wrap,avcodec_encode_subtitle \ + -Wl,--wrap,avcodec_send_packet \ + -Wl,--wrap,avcodec_receive_packet \ + -Wl,--wrap,avcodec_send_frame \ + -Wl,--wrap,avcodec_receive_frame \ -Wl,--wrap,avresample_convert || disable neon_clobber_test @@ -4842,6 +4846,10 @@ enabled xmm_clobber_test && -Wl,--wrap,avcodec_encode_audio2 \ -Wl,--wrap,avcodec_encode_video2 \ -Wl,--wrap,avcodec_encode_subtitle \ + -Wl,--wrap,avcodec_send_packet \ + -Wl,--wrap,avcodec_receive_packet \ + -Wl,--wrap,avcodec_send_frame \ + -Wl,--wrap,avcodec_receive_frame \ -Wl,--wrap,avresample_convert \ -Wl,--wrap,sws_scale || disable xmm_clobber_test diff --git a/libavcodec/aarch64/neontest.c b/libavcodec/aarch64/neontest.c index 137c8e6511068..201bfb1ce7e8f 100644 --- a/libavcodec/aarch64/neontest.c +++ b/libavcodec/aarch64/neontest.c @@ -77,3 +77,23 @@ wrap(avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt, { testneonclobbers(avcodec_encode_video2, avctx, avpkt, frame, got_packet_ptr); } + +wrap(avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)) +{ + testneonclobbers(avcodec_send_packet, avctx, avpkt); +} + +wrap(avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)) +{ + testneonclobbers(avcodec_receive_packet, avctx, avpkt); +} + +wrap(avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame)) +{ + testneonclobbers(avcodec_send_frame, avctx, frame); +} + +wrap(avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)) +{ + testneonclobbers(avcodec_receive_frame, avctx, frame); +} diff --git a/libavcodec/arm/neontest.c b/libavcodec/arm/neontest.c index 692576ee45e50..67d7747571bbd 100644 --- a/libavcodec/arm/neontest.c +++ b/libavcodec/arm/neontest.c @@ -77,3 +77,23 @@ wrap(avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt, { testneonclobbers(avcodec_encode_video2, avctx, avpkt, frame, got_packet_ptr); } + +wrap(avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)) +{ + testneonclobbers(avcodec_send_packet, avctx, avpkt); +} + +wrap(avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)) +{ + testneonclobbers(avcodec_receive_packet, avctx, avpkt); +} + +wrap(avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame)) +{ + testneonclobbers(avcodec_send_frame, avctx, frame); +} + +wrap(avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)) +{ + testneonclobbers(avcodec_receive_frame, avctx, frame); +} diff --git a/libavcodec/x86/w64xmmtest.c b/libavcodec/x86/w64xmmtest.c index 400dc4df30182..8925573adee32 100644 --- a/libavcodec/x86/w64xmmtest.c +++ b/libavcodec/x86/w64xmmtest.c @@ -77,3 +77,23 @@ wrap(avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt, { testxmmclobbers(avcodec_encode_video2, avctx, avpkt, frame, got_packet_ptr); } + +wrap(avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)) +{ + testxmmclobbers(avcodec_send_packet, avctx, avpkt); +} + +wrap(avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)) +{ + testxmmclobbers(avcodec_receive_packet, avctx, avpkt); +} + +wrap(avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame)) +{ + testxmmclobbers(avcodec_send_frame, avctx, frame); +} + +wrap(avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)) +{ + testxmmclobbers(avcodec_receive_frame, avctx, frame); +} From 7bf8db4db61eb09fac00eb665d8ec58de8817da6 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 22 Sep 2016 08:40:05 +0200 Subject: [PATCH 0192/3374] tdsc: use the new decoding API --- libavcodec/tdsc.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/libavcodec/tdsc.c b/libavcodec/tdsc.c index c70c77fdfaf73..5b952b34e23ec 100644 --- a/libavcodec/tdsc.c +++ b/libavcodec/tdsc.c @@ -343,7 +343,6 @@ static int tdsc_decode_jpeg_tile(AVCodecContext *avctx, int tile_size, { TDSCContext *ctx = avctx->priv_data; AVPacket jpkt; - int got_frame = 0; int ret; /* Prepare a packet and send to the MJPEG decoder */ @@ -351,12 +350,16 @@ static int tdsc_decode_jpeg_tile(AVCodecContext *avctx, int tile_size, jpkt.data = ctx->tilebuffer; jpkt.size = tile_size; - ret = avcodec_decode_video2(ctx->jpeg_avctx, ctx->jpgframe, - &got_frame, &jpkt); - if (ret < 0 || !got_frame || ctx->jpgframe->format != AV_PIX_FMT_YUVJ420P) { + ret = avcodec_send_packet(ctx->jpeg_avctx, &jpkt); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Error submitting a packet for decoding\n"); + return ret; + } + + ret = avcodec_receive_frame(ctx->jpeg_avctx, ctx->jpgframe); + if (ret < 0 || ctx->jpgframe->format != AV_PIX_FMT_YUVJ420P) { av_log(avctx, AV_LOG_ERROR, - "JPEG decoding error (%d) for (%d) frame.\n", - ret, got_frame); + "JPEG decoding error (%d).\n", ret); /* Normally skip, error if explode */ if (avctx->err_recognition & AV_EF_EXPLODE) From 67d28f4a0fbb52d0734ca3682b85035e96d294fb Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 22 Sep 2016 09:32:08 +0200 Subject: [PATCH 0193/3374] examples/output: switch to the new encoding API --- doc/examples/output.c | 71 +++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 27 deletions(-) diff --git a/doc/examples/output.c b/doc/examples/output.c index 44a55f564545d..bb0da30041cb2 100644 --- a/doc/examples/output.c +++ b/doc/examples/output.c @@ -233,25 +233,37 @@ static AVFrame *get_audio_frame(OutputStream *ost) static int encode_audio_frame(AVFormatContext *oc, OutputStream *ost, AVFrame *frame) { - AVPacket pkt = { 0 }; // data and size must be 0; - int got_packet; + int ret; - av_init_packet(&pkt); - avcodec_encode_audio2(ost->enc, &pkt, frame, &got_packet); + ret = avcodec_send_frame(ost->enc, frame); + if (ret < 0) { + fprintf(stderr, "Error submitting a frame for encoding\n"); + exit(1); + } - if (got_packet) { - pkt.stream_index = ost->st->index; + while (ret >= 0) { + AVPacket pkt = { 0 }; // data and size must be 0; - av_packet_rescale_ts(&pkt, ost->enc->time_base, ost->st->time_base); + av_init_packet(&pkt); - /* Write the compressed frame to the media file. */ - if (av_interleaved_write_frame(oc, &pkt) != 0) { - fprintf(stderr, "Error while writing audio frame\n"); + ret = avcodec_receive_packet(ost->enc, &pkt); + if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) { + fprintf(stderr, "Error encoding a video frame\n"); exit(1); + } else if (ret >= 0) { + av_packet_rescale_ts(&pkt, ost->enc->time_base, ost->st->time_base); + pkt.stream_index = ost->st->index; + + /* Write the compressed frame to the media file. */ + ret = av_interleaved_write_frame(oc, &pkt); + if (ret < 0) { + fprintf(stderr, "Error while writing video frame\n"); + exit(1); + } } } - return (frame || got_packet) ? 0 : 1; + return ret == AVERROR_EOF; } /* @@ -517,36 +529,41 @@ static int write_video_frame(AVFormatContext *oc, OutputStream *ost) int ret; AVCodecContext *c; AVFrame *frame; - AVPacket pkt = { 0 }; - int got_packet = 0; c = ost->enc; frame = get_video_frame(ost); - av_init_packet(&pkt); - /* encode the image */ - ret = avcodec_encode_video2(c, &pkt, frame, &got_packet); + ret = avcodec_send_frame(c, frame); if (ret < 0) { - fprintf(stderr, "Error encoding a video frame\n"); + fprintf(stderr, "Error submitting a frame for encoding\n"); exit(1); } - if (got_packet) { - av_packet_rescale_ts(&pkt, c->time_base, ost->st->time_base); - pkt.stream_index = ost->st->index; + while (ret >= 0) { + AVPacket pkt = { 0 }; - /* Write the compressed frame to the media file. */ - ret = av_interleaved_write_frame(oc, &pkt); - } + av_init_packet(&pkt); - if (ret != 0) { - fprintf(stderr, "Error while writing video frame\n"); - exit(1); + ret = avcodec_receive_packet(c, &pkt); + if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) { + fprintf(stderr, "Error encoding a video frame\n"); + exit(1); + } else if (ret >= 0) { + av_packet_rescale_ts(&pkt, c->time_base, ost->st->time_base); + pkt.stream_index = ost->st->index; + + /* Write the compressed frame to the media file. */ + ret = av_interleaved_write_frame(oc, &pkt); + if (ret < 0) { + fprintf(stderr, "Error while writing video frame\n"); + exit(1); + } + } } - return (frame || got_packet) ? 0 : 1; + return ret == AVERROR_EOF; } static void close_stream(AVFormatContext *oc, OutputStream *ost) From 80a5d05108cb218e8cd2e25c6621a3bfef0a832e Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 18 Sep 2016 14:55:26 +0100 Subject: [PATCH 0194/3374] vaapi_encode: Refactor initialisation This allows better checking of capabilities and will make it easier to add more functionality later. It also commonises some duplicated code around rate control setup and adds more comments explaining the internals. --- libavcodec/vaapi_encode.c | 253 +++++++++++++++++++++----------- libavcodec/vaapi_encode.h | 96 ++++++++---- libavcodec/vaapi_encode_h264.c | 253 ++++++++++++-------------------- libavcodec/vaapi_encode_h265.c | 208 +++++++++----------------- libavcodec/vaapi_encode_mjpeg.c | 45 +++--- 5 files changed, 418 insertions(+), 437 deletions(-) diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index cdda48583fc89..41d1a6ed17d44 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -922,7 +922,7 @@ int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt, return err; } -static av_cold int vaapi_encode_check_config(AVCodecContext *avctx) +static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx) { VAAPIEncodeContext *ctx = avctx->priv_data; VAStatus vas; @@ -930,6 +930,7 @@ static av_cold int vaapi_encode_check_config(AVCodecContext *avctx) VAProfile *profiles = NULL; VAEntrypoint *entrypoints = NULL; VAConfigAttrib attr[] = { + { VAConfigAttribRTFormat }, { VAConfigAttribRateControl }, { VAConfigAttribEncMaxRefFrames }, }; @@ -1001,13 +1002,33 @@ static av_cold int vaapi_encode_check_config(AVCodecContext *avctx) continue; } switch (attr[i].type) { + case VAConfigAttribRTFormat: + if (!(ctx->va_rt_format & attr[i].value)) { + av_log(avctx, AV_LOG_ERROR, "Surface RT format %#x " + "is not supported (mask %#x).\n", + ctx->va_rt_format, attr[i].value); + err = AVERROR(EINVAL); + goto fail; + } + ctx->config_attributes[ctx->nb_config_attributes++] = + (VAConfigAttrib) { + .type = VAConfigAttribRTFormat, + .value = ctx->va_rt_format, + }; + break; case VAConfigAttribRateControl: if (!(ctx->va_rc_mode & attr[i].value)) { - av_log(avctx, AV_LOG_ERROR, "Rate control mode is not " - "supported: %x\n", attr[i].value); + av_log(avctx, AV_LOG_ERROR, "Rate control mode %#x " + "is not supported (mask: %#x).\n", + ctx->va_rc_mode, attr[i].value); err = AVERROR(EINVAL); goto fail; } + ctx->config_attributes[ctx->nb_config_attributes++] = + (VAConfigAttrib) { + .type = VAConfigAttribRateControl, + .value = ctx->va_rc_mode, + }; break; case VAConfigAttribEncMaxRefFrames: { @@ -1016,18 +1037,20 @@ static av_cold int vaapi_encode_check_config(AVCodecContext *avctx) if (avctx->gop_size > 1 && ref_l0 < 1) { av_log(avctx, AV_LOG_ERROR, "P frames are not " - "supported (%x).\n", attr[i].value); + "supported (%#x).\n", attr[i].value); err = AVERROR(EINVAL); goto fail; } if (avctx->max_b_frames > 0 && ref_l1 < 1) { av_log(avctx, AV_LOG_ERROR, "B frames are not " - "supported (%x).\n", attr[i].value); + "supported (%#x).\n", attr[i].value); err = AVERROR(EINVAL); goto fail; } } break; + default: + av_assert0(0 && "Unexpected config attribute."); } } @@ -1038,6 +1061,48 @@ static av_cold int vaapi_encode_check_config(AVCodecContext *avctx) return err; } +static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx) +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + int hrd_buffer_size; + int hrd_initial_buffer_fullness; + + if (avctx->rc_buffer_size) + hrd_buffer_size = avctx->rc_buffer_size; + else + hrd_buffer_size = avctx->bit_rate; + if (avctx->rc_initial_buffer_occupancy) + hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy; + else + hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4; + + ctx->rc_params.misc.type = VAEncMiscParameterTypeRateControl; + ctx->rc_params.rc = (VAEncMiscParameterRateControl) { + .bits_per_second = avctx->bit_rate, + .target_percentage = 66, + .window_size = 1000, + .initial_qp = (avctx->qmax >= 0 ? avctx->qmax : 40), + .min_qp = (avctx->qmin >= 0 ? avctx->qmin : 18), + .basic_unit_size = 0, + }; + ctx->global_params[ctx->nb_global_params] = + &ctx->rc_params.misc; + ctx->global_params_size[ctx->nb_global_params++] = + sizeof(ctx->rc_params); + + ctx->hrd_params.misc.type = VAEncMiscParameterTypeHRD; + ctx->hrd_params.hrd = (VAEncMiscParameterHRD) { + .initial_buffer_fullness = hrd_initial_buffer_fullness, + .buffer_size = hrd_buffer_size, + }; + ctx->global_params[ctx->nb_global_params] = + &ctx->hrd_params.misc; + ctx->global_params_size[ctx->nb_global_params++] = + sizeof(ctx->hrd_params); + + return 0; +} + static void vaapi_encode_free_output_buffer(void *opaque, uint8_t *data) { @@ -1067,7 +1132,7 @@ static AVBufferRef *vaapi_encode_alloc_output_buffer(void *opaque, // bound on that. vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context, VAEncCodedBufferType, - 3 * ctx->aligned_width * ctx->aligned_height + + 3 * ctx->surface_width * ctx->surface_height + (1 << 16), 1, 0, &buffer_id); if (vas != VA_STATUS_SUCCESS) { av_log(avctx, AV_LOG_ERROR, "Failed to create bitstream " @@ -1089,69 +1154,14 @@ static AVBufferRef *vaapi_encode_alloc_output_buffer(void *opaque, return ref; } -av_cold int ff_vaapi_encode_init(AVCodecContext *avctx, - const VAAPIEncodeType *type) +static av_cold int vaapi_encode_create_recon_frames(AVCodecContext *avctx) { VAAPIEncodeContext *ctx = avctx->priv_data; - AVVAAPIFramesContext *recon_hwctx = NULL; AVVAAPIHWConfig *hwconfig = NULL; AVHWFramesConstraints *constraints = NULL; enum AVPixelFormat recon_format; - VAStatus vas; int err, i; - if (!avctx->hw_frames_ctx) { - av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is " - "required to associate the encoding device.\n"); - return AVERROR(EINVAL); - } - - ctx->codec = type; - ctx->codec_options = ctx->codec_options_data; - - ctx->va_config = VA_INVALID_ID; - ctx->va_context = VA_INVALID_ID; - - ctx->priv_data = av_mallocz(type->priv_data_size); - if (!ctx->priv_data) { - err = AVERROR(ENOMEM); - goto fail; - } - - ctx->input_frames_ref = av_buffer_ref(avctx->hw_frames_ctx); - if (!ctx->input_frames_ref) { - err = AVERROR(ENOMEM); - goto fail; - } - ctx->input_frames = (AVHWFramesContext*)ctx->input_frames_ref->data; - - ctx->device_ref = av_buffer_ref(ctx->input_frames->device_ref); - if (!ctx->device_ref) { - err = AVERROR(ENOMEM); - goto fail; - } - ctx->device = (AVHWDeviceContext*)ctx->device_ref->data; - ctx->hwctx = ctx->device->hwctx; - - err = ctx->codec->init(avctx); - if (err < 0) - goto fail; - - err = vaapi_encode_check_config(avctx); - if (err < 0) - goto fail; - - vas = vaCreateConfig(ctx->hwctx->display, - ctx->va_profile, ctx->va_entrypoint, - ctx->config_attributes, ctx->nb_config_attributes, - &ctx->va_config); - if (vas != VA_STATUS_SUCCESS) { - av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline " - "configuration: %d (%s).\n", vas, vaErrorStr(vas)); - err = AVERROR(EIO); - goto fail; - } - hwconfig = av_hwdevice_hwconfig_alloc(ctx->device_ref); if (!hwconfig) { err = AVERROR(ENOMEM); @@ -1190,13 +1200,13 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx, av_log(avctx, AV_LOG_DEBUG, "Using %s as format of " "reconstructed frames.\n", av_get_pix_fmt_name(recon_format)); - if (ctx->aligned_width < constraints->min_width || - ctx->aligned_height < constraints->min_height || - ctx->aligned_width > constraints->max_width || - ctx->aligned_height > constraints->max_height) { + if (ctx->surface_width < constraints->min_width || + ctx->surface_height < constraints->min_height || + ctx->surface_width > constraints->max_width || + ctx->surface_height > constraints->max_height) { av_log(avctx, AV_LOG_ERROR, "Hardware does not support encoding at " "size %dx%d (constraints: width %d-%d height %d-%d).\n", - ctx->aligned_width, ctx->aligned_height, + ctx->surface_width, ctx->surface_height, constraints->min_width, constraints->max_width, constraints->min_height, constraints->max_height); err = AVERROR(EINVAL); @@ -1215,9 +1225,10 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx, ctx->recon_frames->format = AV_PIX_FMT_VAAPI; ctx->recon_frames->sw_format = recon_format; - ctx->recon_frames->width = ctx->aligned_width; - ctx->recon_frames->height = ctx->aligned_height; - ctx->recon_frames->initial_pool_size = ctx->nb_recon_frames; + ctx->recon_frames->width = ctx->surface_width; + ctx->recon_frames->height = ctx->surface_height; + ctx->recon_frames->initial_pool_size = + avctx->max_b_frames + 3; err = av_hwframe_ctx_init(ctx->recon_frames_ref); if (err < 0) { @@ -1225,10 +1236,75 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx, "frame context: %d.\n", err); goto fail; } - recon_hwctx = ctx->recon_frames->hwctx; + err = 0; + fail: + av_freep(&hwconfig); + av_hwframe_constraints_free(&constraints); + return err; +} + +av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + AVVAAPIFramesContext *recon_hwctx = NULL; + VAStatus vas; + int err; + + if (!avctx->hw_frames_ctx) { + av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is " + "required to associate the encoding device.\n"); + return AVERROR(EINVAL); + } + + ctx->codec_options = ctx->codec_options_data; + + ctx->va_config = VA_INVALID_ID; + ctx->va_context = VA_INVALID_ID; + + ctx->priv_data = av_mallocz(ctx->codec->priv_data_size); + if (!ctx->priv_data) { + err = AVERROR(ENOMEM); + goto fail; + } + + ctx->input_frames_ref = av_buffer_ref(avctx->hw_frames_ctx); + if (!ctx->input_frames_ref) { + err = AVERROR(ENOMEM); + goto fail; + } + ctx->input_frames = (AVHWFramesContext*)ctx->input_frames_ref->data; + + ctx->device_ref = av_buffer_ref(ctx->input_frames->device_ref); + if (!ctx->device_ref) { + err = AVERROR(ENOMEM); + goto fail; + } + ctx->device = (AVHWDeviceContext*)ctx->device_ref->data; + ctx->hwctx = ctx->device->hwctx; + + err = vaapi_encode_config_attributes(avctx); + if (err < 0) + goto fail; + + vas = vaCreateConfig(ctx->hwctx->display, + ctx->va_profile, ctx->va_entrypoint, + ctx->config_attributes, ctx->nb_config_attributes, + &ctx->va_config); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline " + "configuration: %d (%s).\n", vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail; + } + + err = vaapi_encode_create_recon_frames(avctx); + if (err < 0) + goto fail; + + recon_hwctx = ctx->recon_frames->hwctx; vas = vaCreateContext(ctx->hwctx->display, ctx->va_config, - ctx->aligned_width, ctx->aligned_height, + ctx->surface_width, ctx->surface_height, VA_PROGRESSIVE, recon_hwctx->surface_ids, recon_hwctx->nb_surfaces, @@ -1240,6 +1316,26 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx, goto fail; } + ctx->output_buffer_pool = + av_buffer_pool_init2(sizeof(VABufferID), avctx, + &vaapi_encode_alloc_output_buffer, NULL); + if (!ctx->output_buffer_pool) { + err = AVERROR(ENOMEM); + goto fail; + } + + if (ctx->va_rc_mode & ~VA_RC_CQP) { + err = vaapi_encode_init_rate_control(avctx); + if (err < 0) + goto fail; + } + + if (ctx->codec->configure) { + err = ctx->codec->configure(avctx); + if (err < 0) + goto fail; + } + ctx->input_order = 0; ctx->output_delay = avctx->max_b_frames; ctx->decode_delay = 1; @@ -1271,14 +1367,6 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx, } } - ctx->output_buffer_pool = - av_buffer_pool_init2(sizeof(VABufferID), avctx, - &vaapi_encode_alloc_output_buffer, NULL); - if (!ctx->output_buffer_pool) { - err = AVERROR(ENOMEM); - goto fail; - } - // All I are IDR for now. ctx->i_per_idr = 0; ctx->p_per_i = ((avctx->gop_size + avctx->max_b_frames) / @@ -1292,8 +1380,6 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx, return 0; fail: - av_freep(&hwconfig); - av_hwframe_constraints_free(&constraints); ff_vaapi_encode_close(avctx); return err; } @@ -1318,9 +1404,6 @@ av_cold int ff_vaapi_encode_close(AVCodecContext *avctx) ctx->va_config = VA_INVALID_ID; } - if (ctx->codec->close) - ctx->codec->close(avctx); - av_buffer_pool_uninit(&ctx->output_buffer_pool); av_freep(&ctx->codec_sequence_params); diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h index eede73ca97ffb..71f608751b499 100644 --- a/libavcodec/vaapi_encode.h +++ b/libavcodec/vaapi_encode.h @@ -48,15 +48,6 @@ enum { PICTURE_TYPE_B = 3, }; -enum { - // All encode operations are done independently. - ISSUE_MODE_SERIALISE_EVERYTHING = 0, - // Overlap as many operations as possible. - ISSUE_MODE_MAXIMISE_THROUGHPUT, - // Overlap operations only when satisfying parallel dependencies. - ISSUE_MODE_MINIMISE_LATENCY, -}; - typedef struct VAAPIEncodeSlice { void *priv_data; void *codec_slice_params; @@ -102,43 +93,65 @@ typedef struct VAAPIEncodeContext { // Codec-specific hooks. const struct VAAPIEncodeType *codec; + // Encoding profile (VAProfileXXX). + VAProfile va_profile; + // Encoding entrypoint (usually VAEntryointEncSlice). + VAEntrypoint va_entrypoint; + // Surface colour/sampling format (usually VA_RT_FORMAT_YUV420). + unsigned int va_rt_format; + // Rate control mode. + unsigned int va_rc_mode; + + // The required size of surfaces. This is probably the input + // size (AVCodecContext.width|height) aligned up to whatever + // block size is required by the codec. + int surface_width; + int surface_height; + + // Everything above this point must be set before calling + // ff_vaapi_encode_init(). + // Codec-specific state. void *priv_data; - VAProfile va_profile; - VAEntrypoint va_entrypoint; + // Configuration attributes to use when creating va_config. + VAConfigAttrib config_attributes[MAX_CONFIG_ATTRIBUTES]; + int nb_config_attributes; + VAConfigID va_config; VAContextID va_context; - int va_rc_mode; - AVBufferRef *device_ref; AVHWDeviceContext *device; AVVAAPIDeviceContext *hwctx; + // The hardware frame context containing the input frames. AVBufferRef *input_frames_ref; AVHWFramesContext *input_frames; - // Input size, set from input frames. - int input_width; - int input_height; - // Aligned size, set by codec init, becomes hwframe size. - int aligned_width; - int aligned_height; - - int nb_recon_frames; + // The hardware frame context containing the reconstructed frames. AVBufferRef *recon_frames_ref; AVHWFramesContext *recon_frames; + // Pool of (reusable) bitstream output buffers. AVBufferPool *output_buffer_pool; - VAConfigAttrib config_attributes[MAX_CONFIG_ATTRIBUTES]; - int nb_config_attributes; - + // Global parameters which will be applied at the start of the + // sequence (includes rate control parameters below). VAEncMiscParameterBuffer *global_params[MAX_GLOBAL_PARAMS]; size_t global_params_size[MAX_GLOBAL_PARAMS]; int nb_global_params; + // Rate control parameters. + struct { + VAEncMiscParameterBuffer misc; + VAEncMiscParameterRateControl rc; + } rc_params; + struct { + VAEncMiscParameterBuffer misc; + VAEncMiscParameterHRD hrd; + } hrd_params; + // Per-sequence parameter structure (VAEncSequenceParameterBuffer*). void *codec_sequence_params; @@ -158,7 +171,15 @@ typedef struct VAAPIEncodeContext { // Next output order index (encode order). int64_t output_order; - int issue_mode; + enum { + // All encode operations are done independently (synchronise + // immediately after every operation). + ISSUE_MODE_SERIALISE_EVERYTHING = 0, + // Overlap as many operations as possible. + ISSUE_MODE_MAXIMISE_THROUGHPUT, + // Overlap operations only when satisfying parallel dependencies. + ISSUE_MODE_MINIMISE_LATENCY, + } issue_mode; // Timestamp handling. int64_t first_pts; @@ -183,15 +204,20 @@ typedef struct VAAPIEncodeContext { typedef struct VAAPIEncodeType { - size_t priv_data_size; + size_t priv_data_size; - int (*init)(AVCodecContext *avctx); - int (*close)(AVCodecContext *avctx); + // Perform any extra codec-specific configuration after the + // codec context is initialised (set up the private data and + // add any necessary global parameters). + int (*configure)(AVCodecContext *avctx); + // The size of the parameter structures: + // sizeof(VAEnc{type}ParameterBuffer{codec}). size_t sequence_params_size; size_t picture_params_size; size_t slice_params_size; + // Fill the parameter structures. int (*init_sequence_params)(AVCodecContext *avctx); int (*init_picture_params)(AVCodecContext *avctx, VAAPIEncodePicture *pic); @@ -199,10 +225,13 @@ typedef struct VAAPIEncodeType { VAAPIEncodePicture *pic, VAAPIEncodeSlice *slice); + // The type used by the packed header: this should look like + // VAEncPackedHeader{something}. int sequence_header_type; int picture_header_type; int slice_header_type; + // Write the packed header data to the provided buffer. int (*write_sequence_header)(AVCodecContext *avctx, char *data, size_t *data_len); int (*write_picture_header)(AVCodecContext *avctx, @@ -213,10 +242,18 @@ typedef struct VAAPIEncodeType { VAAPIEncodeSlice *slice, char *data, size_t *data_len); + // Fill an extra parameter structure, which will then be + // passed to vaRenderPicture(). Will be called repeatedly + // with increasing index argument until AVERROR_EOF is + // returned. int (*write_extra_buffer)(AVCodecContext *avctx, VAAPIEncodePicture *pic, int index, int *type, char *data, size_t *data_len); + + // Write an extra packed header. Will be called repeatedly + // with increasing index argument until AVERROR_EOF is + // returned. int (*write_extra_header)(AVCodecContext *avctx, VAAPIEncodePicture *pic, int index, int *type, @@ -227,8 +264,7 @@ typedef struct VAAPIEncodeType { int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *input_image, int *got_packet); -int ff_vaapi_encode_init(AVCodecContext *avctx, - const VAAPIEncodeType *type); +int ff_vaapi_encode_init(AVCodecContext *avctx); int ff_vaapi_encode_close(AVCodecContext *avctx); #endif /* AVCODEC_VAAPI_ENCODE_H */ diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index 9d6ff27a96110..d9b186816ae19 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -148,14 +148,6 @@ typedef struct VAAPIEncodeH264Context { // Rate control configuration. int send_timing_sei; - struct { - VAEncMiscParameterBuffer misc; - VAEncMiscParameterRateControl rc; - } rc_params; - struct { - VAEncMiscParameterBuffer misc; - VAEncMiscParameterHRD hrd; - } hrd_params; #if VA_CHECK_VERSION(0, 36, 0) // Speed-quality tradeoff setting. @@ -797,16 +789,16 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) vseq->seq_fields.bits.log2_max_frame_num_minus4 = 4; vseq->seq_fields.bits.pic_order_cnt_type = 0; - if (ctx->input_width != ctx->aligned_width || - ctx->input_height != ctx->aligned_height) { + if (avctx->width != ctx->surface_width || + avctx->height != ctx->surface_height) { vseq->frame_cropping_flag = 1; vseq->frame_crop_left_offset = 0; vseq->frame_crop_right_offset = - (ctx->aligned_width - ctx->input_width) / 2; + (ctx->surface_width - avctx->width) / 2; vseq->frame_crop_top_offset = 0; vseq->frame_crop_bottom_offset = - (ctx->aligned_height - ctx->input_height) / 2; + (ctx->surface_height - avctx->height) / 2; } else { vseq->frame_cropping_flag = 0; } @@ -866,9 +858,9 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) (avctx->bit_rate >> mseq->bit_rate_scale + 6) - 1; mseq->cpb_size_scale = - av_clip_uintp2(av_log2(priv->hrd_params.hrd.buffer_size) - 15 - 4, 4); + av_clip_uintp2(av_log2(ctx->hrd_params.hrd.buffer_size) - 15 - 4, 4); mseq->cpb_size_value_minus1[0] = - (priv->hrd_params.hrd.buffer_size >> mseq->cpb_size_scale + 4) - 1; + (ctx->hrd_params.hrd.buffer_size >> mseq->cpb_size_scale + 4) - 1; // CBR mode isn't actually available here, despite naming. mseq->cbr_flag[0] = 0; @@ -880,8 +872,8 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) // This calculation can easily overflow 32 bits. mseq->initial_cpb_removal_delay = 90000 * - (uint64_t)priv->hrd_params.hrd.initial_buffer_fullness / - priv->hrd_params.hrd.buffer_size; + (uint64_t)ctx->hrd_params.hrd.initial_buffer_fullness / + ctx->hrd_params.hrd.buffer_size; mseq->initial_cpb_removal_delay_offset = 0; } else { @@ -1083,94 +1075,94 @@ static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx, return 0; } -static av_cold int vaapi_encode_h264_init_constant_bitrate(AVCodecContext *avctx) +static av_cold int vaapi_encode_h264_configure(AVCodecContext *avctx) { VAAPIEncodeContext *ctx = avctx->priv_data; VAAPIEncodeH264Context *priv = ctx->priv_data; - int hrd_buffer_size; - int hrd_initial_buffer_fullness; + VAAPIEncodeH264Options *opt = ctx->codec_options; - if (avctx->rc_buffer_size) - hrd_buffer_size = avctx->rc_buffer_size; - else - hrd_buffer_size = avctx->bit_rate; - if (avctx->rc_initial_buffer_occupancy) - hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy; - else - hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4; - - priv->rc_params.misc.type = VAEncMiscParameterTypeRateControl; - priv->rc_params.rc = (VAEncMiscParameterRateControl) { - .bits_per_second = avctx->bit_rate, - .target_percentage = 66, - .window_size = 1000, - .initial_qp = (avctx->qmax >= 0 ? avctx->qmax : 40), - .min_qp = (avctx->qmin >= 0 ? avctx->qmin : 18), - .basic_unit_size = 0, - }; - ctx->global_params[ctx->nb_global_params] = - &priv->rc_params.misc; - ctx->global_params_size[ctx->nb_global_params++] = - sizeof(priv->rc_params); - - priv->hrd_params.misc.type = VAEncMiscParameterTypeHRD; - priv->hrd_params.hrd = (VAEncMiscParameterHRD) { - .initial_buffer_fullness = hrd_initial_buffer_fullness, - .buffer_size = hrd_buffer_size, - }; - ctx->global_params[ctx->nb_global_params] = - &priv->hrd_params.misc; - ctx->global_params_size[ctx->nb_global_params++] = - sizeof(priv->hrd_params); - - // These still need to be set for pic_init_qp/slice_qp_delta. - priv->fixed_qp_idr = 26; - priv->fixed_qp_p = 26; - priv->fixed_qp_b = 26; - - av_log(avctx, AV_LOG_DEBUG, "Using constant-bitrate = %d bps.\n", - avctx->bit_rate); - return 0; -} + priv->mb_width = FFALIGN(avctx->width, 16) / 16; + priv->mb_height = FFALIGN(avctx->height, 16) / 16; + + if (ctx->va_rc_mode == VA_RC_CQP) { + priv->fixed_qp_p = opt->qp; + if (avctx->i_quant_factor > 0.0) + priv->fixed_qp_idr = (int)((priv->fixed_qp_p * avctx->i_quant_factor + + avctx->i_quant_offset) + 0.5); + else + priv->fixed_qp_idr = priv->fixed_qp_p; + if (avctx->b_quant_factor > 0.0) + priv->fixed_qp_b = (int)((priv->fixed_qp_p * avctx->b_quant_factor + + avctx->b_quant_offset) + 0.5); + else + priv->fixed_qp_b = priv->fixed_qp_p; + + av_log(avctx, AV_LOG_DEBUG, "Using fixed QP = " + "%d / %d / %d for IDR- / P- / B-frames.\n", + priv->fixed_qp_idr, priv->fixed_qp_p, priv->fixed_qp_b); + + } else if (ctx->va_rc_mode == VA_RC_CBR) { + // These still need to be set for pic_init_qp/slice_qp_delta. + priv->fixed_qp_idr = 26; + priv->fixed_qp_p = 26; + priv->fixed_qp_b = 26; + + av_log(avctx, AV_LOG_DEBUG, "Using constant-bitrate = %d bps.\n", + avctx->bit_rate); -static av_cold int vaapi_encode_h264_init_fixed_qp(AVCodecContext *avctx) -{ - VAAPIEncodeContext *ctx = avctx->priv_data; - VAAPIEncodeH264Context *priv = ctx->priv_data; - VAAPIEncodeH264Options *opt = ctx->codec_options; + } else { + av_assert0(0 && "Invalid RC mode."); + } - priv->fixed_qp_p = opt->qp; - if (avctx->i_quant_factor > 0.0) - priv->fixed_qp_idr = (int)((priv->fixed_qp_p * avctx->i_quant_factor + - avctx->i_quant_offset) + 0.5); - else - priv->fixed_qp_idr = priv->fixed_qp_p; - if (avctx->b_quant_factor > 0.0) - priv->fixed_qp_b = (int)((priv->fixed_qp_p * avctx->b_quant_factor + - avctx->b_quant_offset) + 0.5); - else - priv->fixed_qp_b = priv->fixed_qp_p; + if (opt->quality > 0) { +#if VA_CHECK_VERSION(0, 36, 0) + priv->quality_params.misc.type = + VAEncMiscParameterTypeQualityLevel; + priv->quality_params.quality.quality_level = opt->quality; + + ctx->global_params[ctx->nb_global_params] = + &priv->quality_params.misc; + ctx->global_params_size[ctx->nb_global_params++] = + sizeof(priv->quality_params); +#else + av_log(avctx, AV_LOG_WARNING, "The encode quality option is not " + "supported with this VAAPI version.\n"); +#endif + } - av_log(avctx, AV_LOG_DEBUG, "Using fixed QP = " - "%d / %d / %d for IDR- / P- / B-frames.\n", - priv->fixed_qp_idr, priv->fixed_qp_p, priv->fixed_qp_b); return 0; } -static av_cold int vaapi_encode_h264_init_internal(AVCodecContext *avctx) +static const VAAPIEncodeType vaapi_encode_type_h264 = { + .priv_data_size = sizeof(VAAPIEncodeH264Context), + + .configure = &vaapi_encode_h264_configure, + + .sequence_params_size = sizeof(VAEncSequenceParameterBufferH264), + .init_sequence_params = &vaapi_encode_h264_init_sequence_params, + + .picture_params_size = sizeof(VAEncPictureParameterBufferH264), + .init_picture_params = &vaapi_encode_h264_init_picture_params, + + .slice_params_size = sizeof(VAEncSliceParameterBufferH264), + .init_slice_params = &vaapi_encode_h264_init_slice_params, + + .sequence_header_type = VAEncPackedHeaderSequence, + .write_sequence_header = &vaapi_encode_h264_write_sequence_header, + + .slice_header_type = VAEncPackedHeaderH264_Slice, + .write_slice_header = &vaapi_encode_h264_write_slice_header, + + .write_extra_header = &vaapi_encode_h264_write_extra_header, +}; + +static av_cold int vaapi_encode_h264_init(AVCodecContext *avctx) { - static const VAConfigAttrib default_config_attributes[] = { - { .type = VAConfigAttribRTFormat, - .value = VA_RT_FORMAT_YUV420 }, - { .type = VAConfigAttribEncPackedHeaders, - .value = (VA_ENC_PACKED_HEADER_SEQUENCE | - VA_ENC_PACKED_HEADER_SLICE) }, - }; + VAAPIEncodeContext *ctx = avctx->priv_data; + VAAPIEncodeH264Options *opt = + (VAAPIEncodeH264Options*)ctx->codec_options_data; - VAAPIEncodeContext *ctx = avctx->priv_data; - VAAPIEncodeH264Context *priv = ctx->priv_data; - VAAPIEncodeH264Options *opt = ctx->codec_options; - int i, err; + ctx->codec = &vaapi_encode_type_h264; switch (avctx->profile) { case FF_PROFILE_H264_CONSTRAINED_BASELINE: @@ -1210,7 +1202,7 @@ static av_cold int vaapi_encode_h264_init_internal(AVCodecContext *avctx) return AVERROR(EINVAL); } if (opt->low_power) { -#if VA_CHECK_VERSION(0, 39, 1) +#if VA_CHECK_VERSION(0, 39, 2) ctx->va_entrypoint = VAEntrypointEncSliceLP; #else av_log(avctx, AV_LOG_ERROR, "Low-power encoding is not " @@ -1221,80 +1213,19 @@ static av_cold int vaapi_encode_h264_init_internal(AVCodecContext *avctx) ctx->va_entrypoint = VAEntrypointEncSlice; } - ctx->input_width = avctx->width; - ctx->input_height = avctx->height; - ctx->aligned_width = FFALIGN(ctx->input_width, 16); - ctx->aligned_height = FFALIGN(ctx->input_height, 16); - priv->mb_width = ctx->aligned_width / 16; - priv->mb_height = ctx->aligned_height / 16; - - for (i = 0; i < FF_ARRAY_ELEMS(default_config_attributes); i++) { - ctx->config_attributes[ctx->nb_config_attributes++] = - default_config_attributes[i]; - } + // Only 8-bit encode is supported. + ctx->va_rt_format = VA_RT_FORMAT_YUV420; - if (avctx->bit_rate > 0) { + if (avctx->bit_rate > 0) ctx->va_rc_mode = VA_RC_CBR; - err = vaapi_encode_h264_init_constant_bitrate(avctx); - } else { + else ctx->va_rc_mode = VA_RC_CQP; - err = vaapi_encode_h264_init_fixed_qp(avctx); - } - if (err < 0) - return err; - - ctx->config_attributes[ctx->nb_config_attributes++] = (VAConfigAttrib) { - .type = VAConfigAttribRateControl, - .value = ctx->va_rc_mode, - }; - if (opt->quality > 0) { -#if VA_CHECK_VERSION(0, 36, 0) - priv->quality_params.misc.type = - VAEncMiscParameterTypeQualityLevel; - priv->quality_params.quality.quality_level = opt->quality; - ctx->global_params[ctx->nb_global_params] = - &priv->quality_params.misc; - ctx->global_params_size[ctx->nb_global_params++] = - sizeof(priv->quality_params); -#else - av_log(avctx, AV_LOG_WARNING, "The encode quality option is not " - "supported with this VAAPI version.\n"); -#endif - } + ctx->surface_width = FFALIGN(avctx->width, 16); + ctx->surface_height = FFALIGN(avctx->height, 16); - ctx->nb_recon_frames = 20; - - return 0; -} - -static VAAPIEncodeType vaapi_encode_type_h264 = { - .priv_data_size = sizeof(VAAPIEncodeH264Context), - - .init = &vaapi_encode_h264_init_internal, - - .sequence_params_size = sizeof(VAEncSequenceParameterBufferH264), - .init_sequence_params = &vaapi_encode_h264_init_sequence_params, - - .picture_params_size = sizeof(VAEncPictureParameterBufferH264), - .init_picture_params = &vaapi_encode_h264_init_picture_params, - - .slice_params_size = sizeof(VAEncSliceParameterBufferH264), - .init_slice_params = &vaapi_encode_h264_init_slice_params, - - .sequence_header_type = VAEncPackedHeaderSequence, - .write_sequence_header = &vaapi_encode_h264_write_sequence_header, - - .slice_header_type = VAEncPackedHeaderH264_Slice, - .write_slice_header = &vaapi_encode_h264_write_slice_header, - - .write_extra_header = &vaapi_encode_h264_write_extra_header, -}; - -static av_cold int vaapi_encode_h264_init(AVCodecContext *avctx) -{ - return ff_vaapi_encode_init(avctx, &vaapi_encode_type_h264); + return ff_vaapi_encode_init(avctx); } #define OFFSET(x) (offsetof(VAAPIEncodeContext, codec_options_data) + \ diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c index 010db9293bd80..f5e29443effce 100644 --- a/libavcodec/vaapi_encode_h265.c +++ b/libavcodec/vaapi_encode_h265.c @@ -798,8 +798,8 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) vseq->intra_idr_period = 0; vseq->ip_period = 0; - vseq->pic_width_in_luma_samples = ctx->aligned_width; - vseq->pic_height_in_luma_samples = ctx->aligned_height; + vseq->pic_width_in_luma_samples = ctx->surface_width; + vseq->pic_height_in_luma_samples = ctx->surface_height; vseq->seq_fields.bits.chroma_format_idc = 1; // 4:2:0. vseq->seq_fields.bits.separate_colour_plane_flag = 0; @@ -911,15 +911,15 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) mseq->vps_poc_proportional_to_timing_flag = 1; mseq->vps_num_ticks_poc_diff_minus1 = 0; - if (ctx->input_width != ctx->aligned_width || - ctx->input_height != ctx->aligned_height) { + if (avctx->width != ctx->surface_width || + avctx->height != ctx->surface_height) { mseq->conformance_window_flag = 1; mseq->conf_win_left_offset = 0; mseq->conf_win_right_offset = - (ctx->aligned_width - ctx->input_width) / 2; + (ctx->surface_width - avctx->width) / 2; mseq->conf_win_top_offset = 0; mseq->conf_win_bottom_offset = - (ctx->aligned_height - ctx->input_height) / 2; + (ctx->surface_height - avctx->height) / 2; } else { mseq->conformance_window_flag = 0; } @@ -1154,93 +1154,78 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx, return 0; } -static av_cold int vaapi_encode_h265_init_constant_bitrate(AVCodecContext *avctx) +static av_cold int vaapi_encode_h265_configure(AVCodecContext *avctx) { VAAPIEncodeContext *ctx = avctx->priv_data; VAAPIEncodeH265Context *priv = ctx->priv_data; - int hrd_buffer_size; - int hrd_initial_buffer_fullness; + VAAPIEncodeH265Options *opt = ctx->codec_options; + + priv->ctu_width = FFALIGN(ctx->surface_width, 32) / 32; + priv->ctu_height = FFALIGN(ctx->surface_height, 32) / 32; + + av_log(avctx, AV_LOG_VERBOSE, "Input %ux%u -> Surface %ux%u -> CTU %ux%u.\n", + avctx->width, avctx->height, ctx->surface_width, + ctx->surface_height, priv->ctu_width, priv->ctu_height); + + if (ctx->va_rc_mode == VA_RC_CQP) { + priv->fixed_qp_p = opt->qp; + if (avctx->i_quant_factor > 0.0) + priv->fixed_qp_idr = (int)((priv->fixed_qp_p * avctx->i_quant_factor + + avctx->i_quant_offset) + 0.5); + else + priv->fixed_qp_idr = priv->fixed_qp_p; + if (avctx->b_quant_factor > 0.0) + priv->fixed_qp_b = (int)((priv->fixed_qp_p * avctx->b_quant_factor + + avctx->b_quant_offset) + 0.5); + else + priv->fixed_qp_b = priv->fixed_qp_p; + + av_log(avctx, AV_LOG_DEBUG, "Using fixed QP = " + "%d / %d / %d for IDR- / P- / B-frames.\n", + priv->fixed_qp_idr, priv->fixed_qp_p, priv->fixed_qp_b); + + } else if (ctx->va_rc_mode == VA_RC_CBR) { + // These still need to be set for pic_init_qp/slice_qp_delta. + priv->fixed_qp_idr = 30; + priv->fixed_qp_p = 30; + priv->fixed_qp_b = 30; + + av_log(avctx, AV_LOG_DEBUG, "Using constant-bitrate = %d bps.\n", + avctx->bit_rate); + + } else { + av_assert0(0 && "Invalid RC mode."); + } - if (avctx->rc_buffer_size) - hrd_buffer_size = avctx->rc_buffer_size; - else - hrd_buffer_size = avctx->bit_rate; - if (avctx->rc_initial_buffer_occupancy) - hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy; - else - hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4; - - priv->rc_params.misc.type = VAEncMiscParameterTypeRateControl; - priv->rc_params.rc = (VAEncMiscParameterRateControl) { - .bits_per_second = avctx->bit_rate, - .target_percentage = 66, - .window_size = 1000, - .initial_qp = (avctx->qmax >= 0 ? avctx->qmax : 40), - .min_qp = (avctx->qmin >= 0 ? avctx->qmin : 20), - .basic_unit_size = 0, - }; - ctx->global_params[ctx->nb_global_params] = - &priv->rc_params.misc; - ctx->global_params_size[ctx->nb_global_params++] = - sizeof(priv->rc_params); - - priv->hrd_params.misc.type = VAEncMiscParameterTypeHRD; - priv->hrd_params.hrd = (VAEncMiscParameterHRD) { - .initial_buffer_fullness = hrd_initial_buffer_fullness, - .buffer_size = hrd_buffer_size, - }; - ctx->global_params[ctx->nb_global_params] = - &priv->hrd_params.misc; - ctx->global_params_size[ctx->nb_global_params++] = - sizeof(priv->hrd_params); - - // These still need to be set for pic_init_qp/slice_qp_delta. - priv->fixed_qp_idr = 30; - priv->fixed_qp_p = 30; - priv->fixed_qp_b = 30; - - av_log(avctx, AV_LOG_DEBUG, "Using constant-bitrate = %d bps.\n", - avctx->bit_rate); return 0; } -static av_cold int vaapi_encode_h265_init_fixed_qp(AVCodecContext *avctx) -{ - VAAPIEncodeContext *ctx = avctx->priv_data; - VAAPIEncodeH265Context *priv = ctx->priv_data; - VAAPIEncodeH265Options *opt = ctx->codec_options; +static const VAAPIEncodeType vaapi_encode_type_h265 = { + .priv_data_size = sizeof(VAAPIEncodeH265Context), - priv->fixed_qp_p = opt->qp; - if (avctx->i_quant_factor > 0.0) - priv->fixed_qp_idr = (int)((priv->fixed_qp_p * avctx->i_quant_factor + - avctx->i_quant_offset) + 0.5); - else - priv->fixed_qp_idr = priv->fixed_qp_p; - if (avctx->b_quant_factor > 0.0) - priv->fixed_qp_b = (int)((priv->fixed_qp_p * avctx->b_quant_factor + - avctx->b_quant_offset) + 0.5); - else - priv->fixed_qp_b = priv->fixed_qp_p; + .configure = &vaapi_encode_h265_configure, - av_log(avctx, AV_LOG_DEBUG, "Using fixed QP = " - "%d / %d / %d for IDR- / P- / B-frames.\n", - priv->fixed_qp_idr, priv->fixed_qp_p, priv->fixed_qp_b); - return 0; -} + .sequence_params_size = sizeof(VAEncSequenceParameterBufferHEVC), + .init_sequence_params = &vaapi_encode_h265_init_sequence_params, -static av_cold int vaapi_encode_h265_init_internal(AVCodecContext *avctx) + .picture_params_size = sizeof(VAEncPictureParameterBufferHEVC), + .init_picture_params = &vaapi_encode_h265_init_picture_params, + + .slice_params_size = sizeof(VAEncSliceParameterBufferHEVC), + .init_slice_params = &vaapi_encode_h265_init_slice_params, + + .sequence_header_type = VAEncPackedHeaderSequence, + .write_sequence_header = &vaapi_encode_h265_write_sequence_header, + + .slice_header_type = VAEncPackedHeaderHEVC_Slice, + .write_slice_header = &vaapi_encode_h265_write_slice_header, +}; + +static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx) { - static const VAConfigAttrib default_config_attributes[] = { - { .type = VAConfigAttribRTFormat, - .value = VA_RT_FORMAT_YUV420 }, - { .type = VAConfigAttribEncPackedHeaders, - .value = (VA_ENC_PACKED_HEADER_SEQUENCE | - VA_ENC_PACKED_HEADER_SLICE) }, - }; + VAAPIEncodeContext *ctx = avctx->priv_data; - VAAPIEncodeContext *ctx = avctx->priv_data; - VAAPIEncodeH265Context *priv = ctx->priv_data; - int i, err; + ctx->codec = &vaapi_encode_type_h265; switch (avctx->profile) { case FF_PROFILE_HEVC_MAIN: @@ -1258,66 +1243,19 @@ static av_cold int vaapi_encode_h265_init_internal(AVCodecContext *avctx) } ctx->va_entrypoint = VAEntrypointEncSlice; - ctx->input_width = avctx->width; - ctx->input_height = avctx->height; - ctx->aligned_width = FFALIGN(ctx->input_width, 16); - ctx->aligned_height = FFALIGN(ctx->input_height, 16); - priv->ctu_width = FFALIGN(ctx->aligned_width, 32) / 32; - priv->ctu_height = FFALIGN(ctx->aligned_height, 32) / 32; - - av_log(avctx, AV_LOG_VERBOSE, "Input %ux%u -> Aligned %ux%u -> CTU %ux%u.\n", - ctx->input_width, ctx->input_height, ctx->aligned_width, - ctx->aligned_height, priv->ctu_width, priv->ctu_height); + // This will be dependent on profile when 10-bit is supported. + ctx->va_rt_format = VA_RT_FORMAT_YUV420; - for (i = 0; i < FF_ARRAY_ELEMS(default_config_attributes); i++) { - ctx->config_attributes[ctx->nb_config_attributes++] = - default_config_attributes[i]; - } - - if (avctx->bit_rate > 0) { + if (avctx->bit_rate > 0) ctx->va_rc_mode = VA_RC_CBR; - err = vaapi_encode_h265_init_constant_bitrate(avctx); - } else { + else ctx->va_rc_mode = VA_RC_CQP; - err = vaapi_encode_h265_init_fixed_qp(avctx); - } - if (err < 0) - return err; - ctx->config_attributes[ctx->nb_config_attributes++] = (VAConfigAttrib) { - .type = VAConfigAttribRateControl, - .value = ctx->va_rc_mode, - }; - ctx->nb_recon_frames = 20; + ctx->surface_width = FFALIGN(avctx->width, 16); + ctx->surface_height = FFALIGN(avctx->height, 16); - return 0; -} - -static VAAPIEncodeType vaapi_encode_type_h265 = { - .priv_data_size = sizeof(VAAPIEncodeH265Context), - - .init = &vaapi_encode_h265_init_internal, - - .sequence_params_size = sizeof(VAEncSequenceParameterBufferHEVC), - .init_sequence_params = &vaapi_encode_h265_init_sequence_params, - - .picture_params_size = sizeof(VAEncPictureParameterBufferHEVC), - .init_picture_params = &vaapi_encode_h265_init_picture_params, - - .slice_params_size = sizeof(VAEncSliceParameterBufferHEVC), - .init_slice_params = &vaapi_encode_h265_init_slice_params, - - .sequence_header_type = VAEncPackedHeaderSequence, - .write_sequence_header = &vaapi_encode_h265_write_sequence_header, - - .slice_header_type = VAEncPackedHeaderHEVC_Slice, - .write_slice_header = &vaapi_encode_h265_write_slice_header, -}; - -static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx) -{ - return ff_vaapi_encode_init(avctx, &vaapi_encode_type_h265); + return ff_vaapi_encode_init(avctx); } #define OFFSET(x) (offsetof(VAAPIEncodeContext, codec_options_data) + \ diff --git a/libavcodec/vaapi_encode_mjpeg.c b/libavcodec/vaapi_encode_mjpeg.c index e3bf191884909..8866dfba62c5f 100644 --- a/libavcodec/vaapi_encode_mjpeg.c +++ b/libavcodec/vaapi_encode_mjpeg.c @@ -277,8 +277,8 @@ static int vaapi_encode_mjpeg_init_picture_params(AVCodecContext *avctx, vpic->reconstructed_picture = pic->recon_surface; vpic->coded_buf = pic->output_buffer; - vpic->picture_width = ctx->input_width; - vpic->picture_height = ctx->input_height; + vpic->picture_width = avctx->width; + vpic->picture_height = avctx->height; vpic->pic_flags.bits.profile = 0; vpic->pic_flags.bits.progressive = 0; @@ -333,31 +333,10 @@ static int vaapi_encode_mjpeg_init_slice_params(AVCodecContext *avctx, return 0; } -static av_cold int vaapi_encode_mjpeg_init_internal(AVCodecContext *avctx) +static av_cold int vaapi_encode_mjpeg_configure(AVCodecContext *avctx) { - static const VAConfigAttrib default_config_attributes[] = { - { .type = VAConfigAttribRTFormat, - .value = VA_RT_FORMAT_YUV420 }, - { .type = VAConfigAttribEncPackedHeaders, - .value = VA_ENC_PACKED_HEADER_SEQUENCE }, - }; - VAAPIEncodeContext *ctx = avctx->priv_data; VAAPIEncodeMJPEGContext *priv = ctx->priv_data; - int i; - - ctx->va_profile = VAProfileJPEGBaseline; - ctx->va_entrypoint = VAEntrypointEncPicture; - - ctx->input_width = avctx->width; - ctx->input_height = avctx->height; - ctx->aligned_width = FFALIGN(ctx->input_width, 8); - ctx->aligned_height = FFALIGN(ctx->input_height, 8); - - for (i = 0; i < FF_ARRAY_ELEMS(default_config_attributes); i++) { - ctx->config_attributes[ctx->nb_config_attributes++] = - default_config_attributes[i]; - } priv->quality = avctx->global_quality; if (priv->quality < 1 || priv->quality > 100) { @@ -374,7 +353,7 @@ static av_cold int vaapi_encode_mjpeg_init_internal(AVCodecContext *avctx) static VAAPIEncodeType vaapi_encode_type_mjpeg = { .priv_data_size = sizeof(VAAPIEncodeMJPEGContext), - .init = &vaapi_encode_mjpeg_init_internal, + .configure = &vaapi_encode_mjpeg_configure, .picture_params_size = sizeof(VAEncPictureParameterBufferJPEG), .init_picture_params = &vaapi_encode_mjpeg_init_picture_params, @@ -390,7 +369,21 @@ static VAAPIEncodeType vaapi_encode_type_mjpeg = { static av_cold int vaapi_encode_mjpeg_init(AVCodecContext *avctx) { - return ff_vaapi_encode_init(avctx, &vaapi_encode_type_mjpeg); + VAAPIEncodeContext *ctx = avctx->priv_data; + + ctx->codec = &vaapi_encode_type_mjpeg; + + ctx->va_profile = VAProfileJPEGBaseline; + ctx->va_entrypoint = VAEntrypointEncPicture; + + ctx->va_rt_format = VA_RT_FORMAT_YUV420; + + ctx->va_rc_mode = VA_RC_CQP; + + ctx->surface_width = FFALIGN(avctx->width, 8); + ctx->surface_height = FFALIGN(avctx->height, 8); + + return ff_vaapi_encode_init(avctx); } static const AVCodecDefault vaapi_encode_mjpeg_defaults[] = { From 892bbbcdc171ff0d08d69636a240ffb95f54243c Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 18 Sep 2016 14:59:59 +0100 Subject: [PATCH 0195/3374] vaapi_encode: Check packed header capabilities This improves behaviour with drivers which do not support packed headers, such as AMD VCE on mesa/gallium. --- libavcodec/vaapi_encode.c | 36 ++++++++++++++++++++++++++------- libavcodec/vaapi_encode.h | 3 +++ libavcodec/vaapi_encode_h264.c | 4 ++++ libavcodec/vaapi_encode_h265.c | 3 +++ libavcodec/vaapi_encode_mjpeg.c | 15 ++++++++++++++ 5 files changed, 54 insertions(+), 7 deletions(-) diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index 41d1a6ed17d44..7ec53407171e9 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -237,7 +237,8 @@ static int vaapi_encode_issue(AVCodecContext *avctx, } if (pic->type == PICTURE_TYPE_IDR) { - if (ctx->codec->write_sequence_header) { + if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE && + ctx->codec->write_sequence_header) { bit_len = 8 * sizeof(data); err = ctx->codec->write_sequence_header(avctx, data, &bit_len); if (err < 0) { @@ -253,7 +254,8 @@ static int vaapi_encode_issue(AVCodecContext *avctx, } } - if (ctx->codec->write_picture_header) { + if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_PICTURE && + ctx->codec->write_picture_header) { bit_len = 8 * sizeof(data); err = ctx->codec->write_picture_header(avctx, pic, data, &bit_len); if (err < 0) { @@ -289,7 +291,8 @@ static int vaapi_encode_issue(AVCodecContext *avctx, } } - if (ctx->codec->write_extra_header) { + if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_MISC && + ctx->codec->write_extra_header) { for (i = 0;; i++) { int type; bit_len = 8 * sizeof(data); @@ -336,7 +339,8 @@ static int vaapi_encode_issue(AVCodecContext *avctx, } } - if (ctx->codec->write_slice_header) { + if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SLICE && + ctx->codec->write_slice_header) { bit_len = 8 * sizeof(data); err = ctx->codec->write_slice_header(avctx, pic, slice, data, &bit_len); @@ -930,9 +934,10 @@ static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx) VAProfile *profiles = NULL; VAEntrypoint *entrypoints = NULL; VAConfigAttrib attr[] = { - { VAConfigAttribRTFormat }, - { VAConfigAttribRateControl }, - { VAConfigAttribEncMaxRefFrames }, + { VAConfigAttribRTFormat }, + { VAConfigAttribRateControl }, + { VAConfigAttribEncMaxRefFrames }, + { VAConfigAttribEncPackedHeaders }, }; n = vaMaxNumProfiles(ctx->hwctx->display); @@ -1049,6 +1054,23 @@ static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx) } } break; + case VAConfigAttribEncPackedHeaders: + if (ctx->va_packed_headers & ~attr[i].value) { + // This isn't fatal, but packed headers are always + // preferable because they are under our control. + // When absent, the driver is generating them and some + // features may not work (e.g. VUI or SEI in H.264). + av_log(avctx, AV_LOG_WARNING, "Warning: some packed " + "headers are not supported (want %#x, got %#x).\n", + ctx->va_packed_headers, attr[i].value); + ctx->va_packed_headers &= attr[i].value; + } + ctx->config_attributes[ctx->nb_config_attributes++] = + (VAConfigAttrib) { + .type = VAConfigAttribEncPackedHeaders, + .value = ctx->va_packed_headers, + }; + break; default: av_assert0(0 && "Unexpected config attribute."); } diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h index 71f608751b499..c47d979db2c5b 100644 --- a/libavcodec/vaapi_encode.h +++ b/libavcodec/vaapi_encode.h @@ -101,6 +101,9 @@ typedef struct VAAPIEncodeContext { unsigned int va_rt_format; // Rate control mode. unsigned int va_rc_mode; + // Supported packed headers (initially the desired set, modified + // later to what is actually supported). + unsigned int va_packed_headers; // The required size of surfaces. This is probably the input // size (AVCodecContext.width|height) aligned up to whatever diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index d9b186816ae19..0cd966f662aeb 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -1221,6 +1221,10 @@ static av_cold int vaapi_encode_h264_init(AVCodecContext *avctx) else ctx->va_rc_mode = VA_RC_CQP; + ctx->va_packed_headers = + VA_ENC_PACKED_HEADER_SEQUENCE | // SPS and PPS. + VA_ENC_PACKED_HEADER_SLICE | // Slice headers. + VA_ENC_PACKED_HEADER_MISC; // SEI. ctx->surface_width = FFALIGN(avctx->width, 16); ctx->surface_height = FFALIGN(avctx->height, 16); diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c index f5e29443effce..7cd9782c204e0 100644 --- a/libavcodec/vaapi_encode_h265.c +++ b/libavcodec/vaapi_encode_h265.c @@ -1251,6 +1251,9 @@ static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx) else ctx->va_rc_mode = VA_RC_CQP; + ctx->va_packed_headers = + VA_ENC_PACKED_HEADER_SEQUENCE | // VPS, SPS and PPS. + VA_ENC_PACKED_HEADER_SLICE; // Slice headers. ctx->surface_width = FFALIGN(avctx->width, 16); ctx->surface_height = FFALIGN(avctx->height, 16); diff --git a/libavcodec/vaapi_encode_mjpeg.c b/libavcodec/vaapi_encode_mjpeg.c index 8866dfba62c5f..78d5e789f1b33 100644 --- a/libavcodec/vaapi_encode_mjpeg.c +++ b/libavcodec/vaapi_encode_mjpeg.c @@ -345,6 +345,17 @@ static av_cold int vaapi_encode_mjpeg_configure(AVCodecContext *avctx) return AVERROR(EINVAL); } + // Hack: the implementation calls the JPEG image header (which we + // will use in the same way as a slice header) generic "raw data". + // Therefore, if after the packed header capability check we have + // PACKED_HEADER_RAW_DATA available, rewrite it as + // PACKED_HEADER_SLICE so that the header-writing code can do the + // right thing. + if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_RAW_DATA) { + ctx->va_packed_headers &= ~VA_ENC_PACKED_HEADER_RAW_DATA; + ctx->va_packed_headers |= VA_ENC_PACKED_HEADER_SLICE; + } + vaapi_encode_mjpeg_init_tables(avctx); return 0; @@ -380,6 +391,10 @@ static av_cold int vaapi_encode_mjpeg_init(AVCodecContext *avctx) ctx->va_rc_mode = VA_RC_CQP; + // The JPEG image header - see note above. + ctx->va_packed_headers = + VA_ENC_PACKED_HEADER_RAW_DATA; + ctx->surface_width = FFALIGN(avctx->width, 8); ctx->surface_height = FFALIGN(avctx->height, 8); From 086e4b58b59ea3993107aa24d92bb962ec69667c Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 18 Sep 2016 16:06:55 +0100 Subject: [PATCH 0196/3374] vaapi_encode: Sync to input surface rather than output While outwardly bizarre, this change makes the behaviour consistent with other VAAPI encoders which sync to the encode /input/ picture in order to wait for /output/ from the encoder. It is not harmful on i965 (because synchronisation already happens in vaRenderPicture(), so it has no effect there), and it allows the encoder to work on mesa/gallium which assumes this behaviour. --- libavcodec/vaapi_encode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index 7ec53407171e9..dc6cdfef60868 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -109,10 +109,10 @@ static int vaapi_encode_wait(AVCodecContext *avctx, } av_log(avctx, AV_LOG_DEBUG, "Sync to pic %"PRId64"/%"PRId64" " - "(recon surface %#x).\n", pic->display_order, - pic->encode_order, pic->recon_surface); + "(input surface %#x).\n", pic->display_order, + pic->encode_order, pic->input_surface); - vas = vaSyncSurface(ctx->hwctx->display, pic->recon_surface); + vas = vaSyncSurface(ctx->hwctx->display, pic->input_surface); if (vas != VA_STATUS_SUCCESS) { av_log(avctx, AV_LOG_ERROR, "Failed to sync to picture completion: " "%d (%s).\n", vas, vaErrorStr(vas)); From 956a54129db522998a5abae869568dae2c9774cb Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Tue, 27 Sep 2016 19:08:42 +0100 Subject: [PATCH 0197/3374] vaapi_h264: Set max_num_ref_frames to 1 when not using B frames --- libavcodec/vaapi_encode_h264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index 0cd966f662aeb..020f8924e2fcf 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -778,7 +778,7 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) vseq->level_idc = avctx->level; - vseq->max_num_ref_frames = 2; + vseq->max_num_ref_frames = 1 + (avctx->max_b_frames > 0); vseq->picture_width_in_mbs = priv->mb_width; vseq->picture_height_in_mbs = priv->mb_height; From 009adfd4fbdd78a890a4a65d6f141c467bb027fa Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 16 Sep 2016 13:13:28 +0200 Subject: [PATCH 0198/3374] x86: fpel: Remove unnecessary sign extend --- libavcodec/x86/fpel.asm | 1 - 1 file changed, 1 deletion(-) diff --git a/libavcodec/x86/fpel.asm b/libavcodec/x86/fpel.asm index b581471296887..b1be289a926c1 100644 --- a/libavcodec/x86/fpel.asm +++ b/libavcodec/x86/fpel.asm @@ -35,7 +35,6 @@ INIT_MMX mmxext %define OP mova %endif cglobal %1_pixels%2, 4,5 - movsxdifnidn r2, r2d lea r4, [r2*3] .loop: OP m0, [r1] From 92c5755a185086067fe49e7e64c23a8e7011be31 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 11 Sep 2016 23:17:31 +0200 Subject: [PATCH 0199/3374] hpeldsp: arm: Update comments left behind in 25841dfe806a13de526ae09c11149ab1f83555a8 --- libavcodec/arm/hpeldsp_arm.S | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libavcodec/arm/hpeldsp_arm.S b/libavcodec/arm/hpeldsp_arm.S index 0f8092e15e5eb..6eb48379160cc 100644 --- a/libavcodec/arm/hpeldsp_arm.S +++ b/libavcodec/arm/hpeldsp_arm.S @@ -90,7 +90,7 @@ @ ---------------------------------------------------------------- function ff_put_pixels16_arm, export=1, align=5 - @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ void func(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) @ block = word aligned, pixles = unaligned pld [r1] push {r4-r11, lr} @@ -141,7 +141,7 @@ endfunc @ ---------------------------------------------------------------- function ff_put_pixels8_arm, export=1, align=5 - @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ void func(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) @ block = word aligned, pixles = unaligned pld [r1] push {r4-r5,lr} @@ -192,7 +192,7 @@ endfunc @ ---------------------------------------------------------------- function ff_put_pixels8_x2_arm, export=1, align=5 - @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ void func(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) @ block = word aligned, pixles = unaligned pld [r1] push {r4-r10,lr} @@ -250,7 +250,7 @@ function ff_put_pixels8_x2_arm, export=1, align=5 endfunc function ff_put_no_rnd_pixels8_x2_arm, export=1, align=5 - @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ void func(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) @ block = word aligned, pixles = unaligned pld [r1] push {r4-r10,lr} @@ -310,7 +310,7 @@ endfunc @ ---------------------------------------------------------------- function ff_put_pixels8_y2_arm, export=1, align=5 - @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ void func(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) @ block = word aligned, pixles = unaligned pld [r1] push {r4-r11,lr} @@ -407,7 +407,7 @@ function ff_put_pixels8_y2_arm, export=1, align=5 endfunc function ff_put_no_rnd_pixels8_y2_arm, export=1, align=5 - @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ void func(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) @ block = word aligned, pixles = unaligned pld [r1] push {r4-r11,lr} @@ -573,7 +573,7 @@ endfunc .endm function ff_put_pixels8_xy2_arm, export=1, align=5 - @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ void func(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) @ block = word aligned, pixles = unaligned pld [r1] push {r4-r11,lr} @ R14 is also called LR @@ -588,7 +588,7 @@ function ff_put_pixels8_xy2_arm, export=1, align=5 endfunc function ff_put_no_rnd_pixels8_xy2_arm, export=1, align=5 - @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ void func(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) @ block = word aligned, pixles = unaligned pld [r1] push {r4-r11,lr} From 3281d823cdc7601c4900eb103958c05f59f65555 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 8 Sep 2016 15:08:03 +0200 Subject: [PATCH 0200/3374] intrax8: Change type of array stride parameters to ptrdiff_t ptrdiff_t is the correct type for array strides and similar. Also rename all such parameters to "stride" for consistency. --- libavcodec/intrax8.c | 8 ++--- libavcodec/intrax8dsp.c | 67 +++++++++++++++++++++-------------------- libavcodec/intrax8dsp.h | 13 +++++--- 3 files changed, 46 insertions(+), 42 deletions(-) diff --git a/libavcodec/intrax8.c b/libavcodec/intrax8.c index eb4c1effd8836..9c20c8f285fcf 100644 --- a/libavcodec/intrax8.c +++ b/libavcodec/intrax8.c @@ -548,7 +548,7 @@ static void x8_ac_compensation(IntraX8Context *const w, const int direction, } static void dsp_x8_put_solidcolor(const uint8_t pix, uint8_t *dst, - const int linesize) + const ptrdiff_t linesize) { int k; for (k = 0; k < 8; k++) { @@ -700,7 +700,7 @@ static int x8_decode_intra_mb(IntraX8Context *const w, const int chroma) if (w->loopfilter) { uint8_t *ptr = w->dest[chroma]; - int linesize = w->frame->linesize[!!chroma]; + ptrdiff_t linesize = w->frame->linesize[!!chroma]; if (!((w->edges & 2) || (zeros_only && (w->orient | 4) == 4))) w->dsp.h_loop_filter(ptr, linesize, w->quant); @@ -716,8 +716,8 @@ static void x8_init_block_index(IntraX8Context *w, AVFrame *frame) { // not parent codec linesize as this would be wrong for field pics // not that IntraX8 has interlacing support ;) - const int linesize = frame->linesize[0]; - const int uvlinesize = frame->linesize[1]; + const ptrdiff_t linesize = frame->linesize[0]; + const ptrdiff_t uvlinesize = frame->linesize[1]; w->dest[0] = frame->data[0]; w->dest[1] = frame->data[1]; diff --git a/libavcodec/intrax8dsp.c b/libavcodec/intrax8dsp.c index 108cfe3bcb08d..bb74a6802c3f3 100644 --- a/libavcodec/intrax8dsp.c +++ b/libavcodec/intrax8dsp.c @@ -63,8 +63,8 @@ 4 - mb_x>= (mb_width-1) last block in the row, interpolate area #5; -*/ static void x8_setup_spatial_compensation(uint8_t *src, uint8_t *dst, - int linesize, int *range, int *psum, - int edges) + ptrdiff_t stride, int *range, + int *psum, int edges) { uint8_t *ptr; int sum; @@ -98,12 +98,12 @@ static void x8_setup_spatial_compensation(uint8_t *src, uint8_t *dst, max_pix = FFMAX(max_pix, c); dst[area2 + i] = c; - ptr += linesize; + ptr += stride; } } if (!(edges & 2)) { // (mb_y != 0) // there is row above - ptr = src - linesize; // top line + ptr = src - stride; // top line for (i = 0; i < 8; i++) { c = *(ptr + i); sum += c; @@ -117,7 +117,7 @@ static void x8_setup_spatial_compensation(uint8_t *src, uint8_t *dst, memcpy(dst + area4, ptr, 16); // both area4 and 5 } // area6 always present in the above block - memcpy(dst + area6, ptr - linesize, 8); + memcpy(dst + area6, ptr - stride, 8); } // now calculate the stuff we need if (edges & 3) { // mb_x ==0 || mb_y == 0) { @@ -131,7 +131,7 @@ static void x8_setup_spatial_compensation(uint8_t *src, uint8_t *dst, sum += avg * 9; } else { // the edge pixel, in the top line and left column - uint8_t c = *(src - 1 - linesize); + uint8_t c = *(src - 1 - stride); dst[area3] = c; sum += c; // edge pixel is not part of min/max @@ -160,7 +160,7 @@ static const uint16_t zero_prediction_weights[64 * 2] = { 317, 846, 366, 731, 458, 611, 499, 499, }; -static void spatial_compensation_0(uint8_t *src, uint8_t *dst, int linesize) +static void spatial_compensation_0(uint8_t *src, uint8_t *dst, ptrdiff_t stride) { int i, j; int x, y; @@ -208,55 +208,55 @@ static void spatial_compensation_0(uint8_t *src, uint8_t *dst, int linesize) dst[x] = ((uint32_t) top_sum[0][x] * zero_prediction_weights[y * 16 + x * 2 + 0] + (uint32_t) left_sum[0][y] * zero_prediction_weights[y * 16 + x * 2 + 1] + 0x8000) >> 16; - dst += linesize; + dst += stride; } } -static void spatial_compensation_1(uint8_t *src, uint8_t *dst, int linesize) +static void spatial_compensation_1(uint8_t *src, uint8_t *dst, ptrdiff_t stride) { int x, y; for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) dst[x] = src[area4 + FFMIN(2 * y + x + 2, 15)]; - dst += linesize; + dst += stride; } } -static void spatial_compensation_2(uint8_t *src, uint8_t *dst, int linesize) +static void spatial_compensation_2(uint8_t *src, uint8_t *dst, ptrdiff_t stride) { int x, y; for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) dst[x] = src[area4 + 1 + y + x]; - dst += linesize; + dst += stride; } } -static void spatial_compensation_3(uint8_t *src, uint8_t *dst, int linesize) +static void spatial_compensation_3(uint8_t *src, uint8_t *dst, ptrdiff_t stride) { int x, y; for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) dst[x] = src[area4 + ((y + 1) >> 1) + x]; - dst += linesize; + dst += stride; } } -static void spatial_compensation_4(uint8_t *src, uint8_t *dst, int linesize) +static void spatial_compensation_4(uint8_t *src, uint8_t *dst, ptrdiff_t stride) { int x, y; for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) dst[x] = (src[area4 + x] + src[area6 + x] + 1) >> 1; - dst += linesize; + dst += stride; } } -static void spatial_compensation_5(uint8_t *src, uint8_t *dst, int linesize) +static void spatial_compensation_5(uint8_t *src, uint8_t *dst, ptrdiff_t stride) { int x, y; @@ -267,22 +267,22 @@ static void spatial_compensation_5(uint8_t *src, uint8_t *dst, int linesize) else dst[x] = src[area4 + x - ((y + 1) >> 1)]; } - dst += linesize; + dst += stride; } } -static void spatial_compensation_6(uint8_t *src, uint8_t *dst, int linesize) +static void spatial_compensation_6(uint8_t *src, uint8_t *dst, ptrdiff_t stride) { int x, y; for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) dst[x] = src[area3 + x - y]; - dst += linesize; + dst += stride; } } -static void spatial_compensation_7(uint8_t *src, uint8_t *dst, int linesize) +static void spatial_compensation_7(uint8_t *src, uint8_t *dst, ptrdiff_t stride) { int x, y; @@ -293,55 +293,56 @@ static void spatial_compensation_7(uint8_t *src, uint8_t *dst, int linesize) else dst[x] = src[area2 + 8 - y + (x >> 1)]; } - dst += linesize; + dst += stride; } } -static void spatial_compensation_8(uint8_t *src, uint8_t *dst, int linesize) +static void spatial_compensation_8(uint8_t *src, uint8_t *dst, ptrdiff_t stride) { int x, y; for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) dst[x] = (src[area1 + 7 - y] + src[area2 + 7 - y] + 1) >> 1; - dst += linesize; + dst += stride; } } -static void spatial_compensation_9(uint8_t *src, uint8_t *dst, int linesize) +static void spatial_compensation_9(uint8_t *src, uint8_t *dst, ptrdiff_t stride) { int x, y; for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) dst[x] = src[area2 + 6 - FFMIN(x + y, 6)]; - dst += linesize; + dst += stride; } } -static void spatial_compensation_10(uint8_t *src, uint8_t *dst, int linesize) +static void spatial_compensation_10(uint8_t *src, uint8_t *dst, ptrdiff_t stride) { int x, y; for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) dst[x] = (src[area2 + 7 - y] * (8 - x) + src[area4 + x] * x + 4) >> 3; - dst += linesize; + dst += stride; } } -static void spatial_compensation_11(uint8_t *src, uint8_t *dst, int linesize) +static void spatial_compensation_11(uint8_t *src, uint8_t *dst, ptrdiff_t stride) { int x, y; for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) dst[x] = (src[area2 + 7 - y] * y + src[area4 + x] * (8 - y) + 4) >> 3; - dst += linesize; + dst += stride; } } -static void x8_loop_filter(uint8_t *ptr, const int a_stride, const int b_stride, int quant) +static void x8_loop_filter(uint8_t *ptr, const ptrdiff_t a_stride, + const ptrdiff_t b_stride, int quant) { int i, t; int p0, p1, p2, p3, p4, p5, p6, p7, p8, p9; @@ -434,12 +435,12 @@ static void x8_loop_filter(uint8_t *ptr, const int a_stride, const int b_stride, } } -static void x8_h_loop_filter(uint8_t *src, int stride, int qscale) +static void x8_h_loop_filter(uint8_t *src, ptrdiff_t stride, int qscale) { x8_loop_filter(src, stride, 1, qscale); } -static void x8_v_loop_filter(uint8_t *src, int stride, int qscale) +static void x8_v_loop_filter(uint8_t *src, ptrdiff_t stride, int qscale) { x8_loop_filter(src, 1, stride, qscale); } diff --git a/libavcodec/intrax8dsp.h b/libavcodec/intrax8dsp.h index 4ba1a0b47e714..27e71e6243631 100644 --- a/libavcodec/intrax8dsp.h +++ b/libavcodec/intrax8dsp.h @@ -19,15 +19,18 @@ #ifndef AVCODEC_INTRAX8DSP_H #define AVCODEC_INTRAX8DSP_H +#include #include typedef struct IntraX8DSPContext { - void (*v_loop_filter)(uint8_t *src, int stride, int qscale); - void (*h_loop_filter)(uint8_t *src, int stride, int qscale); + void (*v_loop_filter)(uint8_t *src, ptrdiff_t stride, int qscale); + void (*h_loop_filter)(uint8_t *src, ptrdiff_t stride, int qscale); - void (*spatial_compensation[12])(uint8_t *src, uint8_t *dst, int linesize); - void (*setup_spatial_compensation)(uint8_t *src, uint8_t *dst, int linesize, - int *range, int *sum, int edges); + void (*spatial_compensation[12])(uint8_t *src, uint8_t *dst, + ptrdiff_t stride); + void (*setup_spatial_compensation)(uint8_t *src, uint8_t *dst, + ptrdiff_t stride, int *range, + int *sum, int edges); } IntraX8DSPContext; void ff_intrax8dsp_init(IntraX8DSPContext *dsp); From b2939a75270bc7e971462648168aa3a2a48c1c8c Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 8 Sep 2016 15:13:04 +0200 Subject: [PATCH 0201/3374] blockdsp: Change type of array stride parameters to ptrdiff_t ptrdiff_t is the correct type for array strides and similar. --- libavcodec/blockdsp.c | 6 ++++-- libavcodec/blockdsp.h | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/libavcodec/blockdsp.c b/libavcodec/blockdsp.c index a35df8c7b10eb..2c396f1f610ea 100644 --- a/libavcodec/blockdsp.c +++ b/libavcodec/blockdsp.c @@ -35,7 +35,8 @@ static void clear_blocks_8_c(int16_t *blocks) memset(blocks, 0, sizeof(int16_t) * 6 * 64); } -static void fill_block16_c(uint8_t *block, uint8_t value, int line_size, int h) +static void fill_block16_c(uint8_t *block, uint8_t value, ptrdiff_t line_size, + int h) { int i; @@ -45,7 +46,8 @@ static void fill_block16_c(uint8_t *block, uint8_t value, int line_size, int h) } } -static void fill_block8_c(uint8_t *block, uint8_t value, int line_size, int h) +static void fill_block8_c(uint8_t *block, uint8_t value, ptrdiff_t line_size, + int h) { int i; diff --git a/libavcodec/blockdsp.h b/libavcodec/blockdsp.h index 5b5639f5a68ae..e555d29b6032f 100644 --- a/libavcodec/blockdsp.h +++ b/libavcodec/blockdsp.h @@ -19,6 +19,7 @@ #ifndef AVCODEC_BLOCKDSP_H #define AVCODEC_BLOCKDSP_H +#include #include #include "avcodec.h" @@ -29,7 +30,7 @@ * h for op_pixels_func is limited to { width / 2, width }, * but never larger than 16 and never smaller than 4. */ typedef void (*op_fill_func)(uint8_t *block /* align width (8 or 16) */, - uint8_t value, int line_size, int h); + uint8_t value, ptrdiff_t line_size, int h); typedef struct BlockDSPContext { void (*clear_block)(int16_t *block /* align 16 */); From 2ec9fa5ec60dcd10e1cb10d8b4e4437e634ea428 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 7 Sep 2016 17:02:06 +0200 Subject: [PATCH 0202/3374] idct: Change type of array stride parameters to ptrdiff_t ptrdiff_t is the correct type for array strides and similar. --- doc/optimization.txt | 2 +- libavcodec/arm/idct.h | 13 ++++--- libavcodec/arm/idctdsp_arm.S | 2 +- libavcodec/arm/idctdsp_init_arm.c | 15 +++++--- libavcodec/arm/idctdsp_init_armv6.c | 2 +- libavcodec/arm/simple_idct_armv6.S | 4 +- libavcodec/arm/simple_idct_neon.S | 4 +- libavcodec/arm/vc1dsp_init_neon.c | 14 +++---- libavcodec/arm/vc1dsp_neon.S | 6 +-- libavcodec/dct.h | 5 ++- libavcodec/dv.h | 2 +- libavcodec/dvdec.c | 2 +- libavcodec/faanidct.c | 10 +++-- libavcodec/faanidct.h | 5 ++- libavcodec/idctdsp.c | 10 ++--- libavcodec/idctdsp.h | 14 +++---- libavcodec/jrevdct.c | 4 +- libavcodec/ppc/idctdsp.c | 4 +- libavcodec/ppc/vc1dsp_altivec.c | 3 +- libavcodec/simple_idct.c | 12 +++--- libavcodec/simple_idct.h | 17 ++++---- libavcodec/simple_idct_template.c | 8 ++-- libavcodec/tests/dct.c | 5 ++- libavcodec/vc1dsp.c | 54 +++++++++++++------------- libavcodec/vc1dsp.h | 14 +++---- libavcodec/wmv2dsp.c | 4 +- libavcodec/wmv2dsp.h | 4 +- libavcodec/x86/idctdsp.h | 7 ++-- libavcodec/x86/idctdsp_mmx.c | 6 +-- libavcodec/x86/simple_idct.c | 4 +- libavcodec/x86/simple_idct.h | 5 ++- libavcodec/x86/vc1dsp_mmx.c | 60 ++++++++++++++--------------- libavcodec/x86/xvididct.h | 13 ++++--- libavcodec/x86/xvididct_mmx.c | 8 ++-- libavcodec/x86/xvididct_sse2.c | 4 +- libavcodec/xvididct.c | 4 +- 36 files changed, 184 insertions(+), 166 deletions(-) diff --git a/doc/optimization.txt b/doc/optimization.txt index 9847dcf20a202..be12d85545025 100644 --- a/doc/optimization.txt +++ b/doc/optimization.txt @@ -142,7 +142,7 @@ Alignment: Some instructions on some architectures have strict alignment restrictions, for example most SSE/SSE2 instructions on x86. The minimum guaranteed alignment is written in the .h files, for example: - void (*put_pixels_clamped)(const int16_t *block/*align 16*/, UINT8 *pixels/*align 8*/, int line_size); + void (*put_pixels_clamped)(const int16_t *block/*align 16*/, uint8_t *pixels/*align 8*/, ptrdiff_t stride); General Tips: diff --git a/libavcodec/arm/idct.h b/libavcodec/arm/idct.h index 168d64b6664da..db4d6c5d98589 100644 --- a/libavcodec/arm/idct.h +++ b/libavcodec/arm/idct.h @@ -19,6 +19,7 @@ #ifndef AVCODEC_ARM_IDCT_H #define AVCODEC_ARM_IDCT_H +#include #include void ff_j_rev_dct_arm(int16_t *data); @@ -26,15 +27,15 @@ void ff_j_rev_dct_arm(int16_t *data); void ff_simple_idct_arm(int16_t *data); void ff_simple_idct_armv5te(int16_t *data); -void ff_simple_idct_put_armv5te(uint8_t *dest, int line_size, int16_t *data); -void ff_simple_idct_add_armv5te(uint8_t *dest, int line_size, int16_t *data); +void ff_simple_idct_put_armv5te(uint8_t *dest, ptrdiff_t line_size, int16_t *data); +void ff_simple_idct_add_armv5te(uint8_t *dest, ptrdiff_t line_size, int16_t *data); void ff_simple_idct_armv6(int16_t *data); -void ff_simple_idct_put_armv6(uint8_t *dest, int line_size, int16_t *data); -void ff_simple_idct_add_armv6(uint8_t *dest, int line_size, int16_t *data); +void ff_simple_idct_put_armv6(uint8_t *dest, ptrdiff_t line_size, int16_t *data); +void ff_simple_idct_add_armv6(uint8_t *dest, ptrdiff_t line_size, int16_t *data); void ff_simple_idct_neon(int16_t *data); -void ff_simple_idct_put_neon(uint8_t *dest, int line_size, int16_t *data); -void ff_simple_idct_add_neon(uint8_t *dest, int line_size, int16_t *data); +void ff_simple_idct_put_neon(uint8_t *dest, ptrdiff_t line_size, int16_t *data); +void ff_simple_idct_add_neon(uint8_t *dest, ptrdiff_t line_size, int16_t *data); #endif /* AVCODEC_ARM_IDCT_H */ diff --git a/libavcodec/arm/idctdsp_arm.S b/libavcodec/arm/idctdsp_arm.S index 34f467e86f934..0d6a76b4cb368 100644 --- a/libavcodec/arm/idctdsp_arm.S +++ b/libavcodec/arm/idctdsp_arm.S @@ -22,7 +22,7 @@ #include "config.h" #include "libavutil/arm/asm.S" -@ void ff_add_pixels_clamped_arm(int16_t *block, uint8_t *dest, int stride) +@ void ff_add_pixels_clamped_arm(int16_t *block, uint8_t *dest, ptrdiff_t stride) function ff_add_pixels_clamped_arm, export=1, align=5 push {r4-r10} mov r10, #8 diff --git a/libavcodec/arm/idctdsp_init_arm.c b/libavcodec/arm/idctdsp_init_arm.c index 8207c31589bfa..8216985feb472 100644 --- a/libavcodec/arm/idctdsp_init_arm.c +++ b/libavcodec/arm/idctdsp_init_arm.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include #include "libavutil/attributes.h" @@ -30,29 +31,33 @@ #include "idctdsp_arm.h" void ff_add_pixels_clamped_arm(const int16_t *block, uint8_t *dest, - int line_size); + ptrdiff_t line_size); /* XXX: those functions should be suppressed ASAP when all IDCTs are * converted */ -static void j_rev_dct_arm_put(uint8_t *dest, int line_size, int16_t *block) +static void j_rev_dct_arm_put(uint8_t *dest, ptrdiff_t line_size, + int16_t *block) { ff_j_rev_dct_arm(block); ff_put_pixels_clamped(block, dest, line_size); } -static void j_rev_dct_arm_add(uint8_t *dest, int line_size, int16_t *block) +static void j_rev_dct_arm_add(uint8_t *dest, ptrdiff_t line_size, + int16_t *block) { ff_j_rev_dct_arm(block); ff_add_pixels_clamped(block, dest, line_size); } -static void simple_idct_arm_put(uint8_t *dest, int line_size, int16_t *block) +static void simple_idct_arm_put(uint8_t *dest, ptrdiff_t line_size, + int16_t *block) { ff_simple_idct_arm(block); ff_put_pixels_clamped(block, dest, line_size); } -static void simple_idct_arm_add(uint8_t *dest, int line_size, int16_t *block) +static void simple_idct_arm_add(uint8_t *dest, ptrdiff_t line_size, + int16_t *block) { ff_simple_idct_arm(block); ff_add_pixels_clamped(block, dest, line_size); diff --git a/libavcodec/arm/idctdsp_init_armv6.c b/libavcodec/arm/idctdsp_init_armv6.c index 8f0c49b142d25..3941ee8f0f0bd 100644 --- a/libavcodec/arm/idctdsp_init_armv6.c +++ b/libavcodec/arm/idctdsp_init_armv6.c @@ -27,7 +27,7 @@ #include "idctdsp_arm.h" void ff_add_pixels_clamped_armv6(const int16_t *block, uint8_t *pixels, - int line_size); + ptrdiff_t line_size); av_cold void ff_idctdsp_init_armv6(IDCTDSPContext *c, AVCodecContext *avctx, unsigned high_bit_depth) diff --git a/libavcodec/arm/simple_idct_armv6.S b/libavcodec/arm/simple_idct_armv6.S index 60723467a08ba..a8de990ee817b 100644 --- a/libavcodec/arm/simple_idct_armv6.S +++ b/libavcodec/arm/simple_idct_armv6.S @@ -390,7 +390,7 @@ function ff_simple_idct_armv6, export=1 pop {r4-r11, pc} endfunc -/* ff_simple_idct_add_armv6(uint8_t *dest, int line_size, int16_t *data); */ +/* ff_simple_idct_add_armv6(uint8_t *dest, ptrdiff_t line_size, int16_t *data); */ function ff_simple_idct_add_armv6, export=1 push {r0, r1, r4-r11, lr} sub sp, sp, #128 @@ -407,7 +407,7 @@ function ff_simple_idct_add_armv6, export=1 pop {r4-r11, pc} endfunc -/* ff_simple_idct_put_armv6(uint8_t *dest, int line_size, int16_t *data); */ +/* ff_simple_idct_put_armv6(uint8_t *dest, ptrdiff_t line_size, int16_t *data); */ function ff_simple_idct_put_armv6, export=1 push {r0, r1, r4-r11, lr} sub sp, sp, #128 diff --git a/libavcodec/arm/simple_idct_neon.S b/libavcodec/arm/simple_idct_neon.S index a1cde8d80a13a..9e0a97a0a8b85 100644 --- a/libavcodec/arm/simple_idct_neon.S +++ b/libavcodec/arm/simple_idct_neon.S @@ -261,7 +261,7 @@ endconst pop {r4-r7, pc} .endm -/* void ff_simple_idct_put_neon(uint8_t *dst, int line_size, int16_t *data); */ +/* void ff_simple_idct_put_neon(uint8_t *dst, ptrdiff_t line_size, int16_t *data); */ function ff_simple_idct_put_neon, export=1 idct_start r2 @@ -316,7 +316,7 @@ function idct_col4_add8_neon bx lr endfunc -/* void ff_simple_idct_add_neon(uint8_t *dst, int line_size, int16_t *data); */ +/* void ff_simple_idct_add_neon(uint8_t *dst, ptrdiff_t line_size, int16_t *data); */ function ff_simple_idct_add_neon, export=1 idct_start r2 diff --git a/libavcodec/arm/vc1dsp_init_neon.c b/libavcodec/arm/vc1dsp_init_neon.c index 9ded7a28b9d18..55d3a653502fa 100644 --- a/libavcodec/arm/vc1dsp_init_neon.c +++ b/libavcodec/arm/vc1dsp_init_neon.c @@ -25,14 +25,14 @@ #include "config.h" void ff_vc1_inv_trans_8x8_neon(int16_t *block); -void ff_vc1_inv_trans_4x8_neon(uint8_t *dest, int linesize, int16_t *block); -void ff_vc1_inv_trans_8x4_neon(uint8_t *dest, int linesize, int16_t *block); -void ff_vc1_inv_trans_4x4_neon(uint8_t *dest, int linesize, int16_t *block); +void ff_vc1_inv_trans_4x8_neon(uint8_t *dest, ptrdiff_t stride, int16_t *block); +void ff_vc1_inv_trans_8x4_neon(uint8_t *dest, ptrdiff_t stride, int16_t *block); +void ff_vc1_inv_trans_4x4_neon(uint8_t *dest, ptrdiff_t stride, int16_t *block); -void ff_vc1_inv_trans_8x8_dc_neon(uint8_t *dest, int linesize, int16_t *block); -void ff_vc1_inv_trans_4x8_dc_neon(uint8_t *dest, int linesize, int16_t *block); -void ff_vc1_inv_trans_8x4_dc_neon(uint8_t *dest, int linesize, int16_t *block); -void ff_vc1_inv_trans_4x4_dc_neon(uint8_t *dest, int linesize, int16_t *block); +void ff_vc1_inv_trans_8x8_dc_neon(uint8_t *dest, ptrdiff_t stride, int16_t *block); +void ff_vc1_inv_trans_4x8_dc_neon(uint8_t *dest, ptrdiff_t stride, int16_t *block); +void ff_vc1_inv_trans_8x4_dc_neon(uint8_t *dest, ptrdiff_t stride, int16_t *block); +void ff_vc1_inv_trans_4x4_dc_neon(uint8_t *dest, ptrdiff_t stride, int16_t *block); void ff_put_pixels8x8_neon(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int rnd); diff --git a/libavcodec/arm/vc1dsp_neon.S b/libavcodec/arm/vc1dsp_neon.S index fa87eded6157a..1653a4c5adb35 100644 --- a/libavcodec/arm/vc1dsp_neon.S +++ b/libavcodec/arm/vc1dsp_neon.S @@ -426,7 +426,7 @@ function ff_vc1_inv_trans_8x8_neon, export=1 bx lr endfunc -@ (uint8_t *dest [r0], int linesize [r1], int16_t *block [r2]) +@ (uint8_t *dest [r0], ptrdiff_t stride [r1], int16_t *block [r2]) function ff_vc1_inv_trans_8x4_neon, export=1 vld1.64 {q0-q1}, [r2,:128]! @ load 8 * 4 * 2 = 64 bytes / 16 bytes per quad = 4 quad registers vld1.64 {q2-q3}, [r2,:128] @@ -511,7 +511,7 @@ function ff_vc1_inv_trans_8x4_neon, export=1 bx lr endfunc -@ (uint8_t *dest [r0], int linesize [r1], int16_t *block [r2]) +@ (uint8_t *dest [r0], ptrdiff_t stride [r1], int16_t *block [r2]) function ff_vc1_inv_trans_4x8_neon, export=1 mov r12, #(8 * 2) @ 8 elements per line, each element 2 bytes vld4.16 {d0[], d2[], d4[], d6[]}, [r2,:64], r12 @ read each column into a q register @@ -593,7 +593,7 @@ endfunc vshr.s16 q1, q1, #\rshift @ dst[3,1] >>= rshift .endm -@ (uint8_t *dest [r0], int linesize [r1], int16_t *block [r2]) +@ (uint8_t *dest [r0], ptrdiff_t stride [r1], int16_t *block [r2]) function ff_vc1_inv_trans_4x4_neon, export=1 mov r12, #(8 * 2) @ 8 elements per line, each element 2 bytes vld4.16 {d0[], d1[], d2[], d3[]}, [r2,:64], r12 @ read each column into a register diff --git a/libavcodec/dct.h b/libavcodec/dct.h index 4a31f54fcbff4..46893a67a95bc 100644 --- a/libavcodec/dct.h +++ b/libavcodec/dct.h @@ -24,6 +24,7 @@ #ifndef AVCODEC_DCT_H #define AVCODEC_DCT_H +#include #include #include "rdft.h" @@ -59,7 +60,7 @@ void ff_fdct248_islow_8(int16_t *data); void ff_fdct248_islow_10(int16_t *data); void ff_j_rev_dct(int16_t *data); -void ff_jref_idct_put(uint8_t *dest, int line_size, int16_t *block); -void ff_jref_idct_add(uint8_t *dest, int line_size, int16_t *block); +void ff_jref_idct_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_jref_idct_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block); #endif /* AVCODEC_DCT_H */ diff --git a/libavcodec/dv.h b/libavcodec/dv.h index f2c7ecf3d92dc..9a9ebf137f01d 100644 --- a/libavcodec/dv.h +++ b/libavcodec/dv.h @@ -47,7 +47,7 @@ typedef struct DVVideoContext { void (*get_pixels)(int16_t *block, const uint8_t *pixels, ptrdiff_t linesize); void (*fdct[2])(int16_t *block); - void (*idct_put[2])(uint8_t *dest, int line_size, int16_t *block); + void (*idct_put[2])(uint8_t *dest, ptrdiff_t stride, int16_t *block); me_cmp_func ildct_cmp; DVwork_chunk work_chunks[4 * 12 * 27]; uint32_t idct_factor[2 * 4 * 16 * 64]; diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c index 463d108b2853c..eca3b86d0f1e5 100644 --- a/libavcodec/dvdec.c +++ b/libavcodec/dvdec.c @@ -52,7 +52,7 @@ typedef struct BlockInfo { const uint32_t *factor_table; const uint8_t *scan_table; uint8_t pos; /* position in block */ - void (*idct_put)(uint8_t *dest, int line_size, int16_t *block); + void (*idct_put)(uint8_t *dest, ptrdiff_t stride, int16_t *block); uint8_t partial_bit_count; uint32_t partial_bit_buffer; int shift_offset; diff --git a/libavcodec/faanidct.c b/libavcodec/faanidct.c index b132f89d4d3b4..57e52a58cab8d 100644 --- a/libavcodec/faanidct.c +++ b/libavcodec/faanidct.c @@ -47,7 +47,9 @@ B6*B0/8, B6*B1/8, B6*B2/8, B6*B3/8, B6*B4/8, B6*B5/8, B6*B6/8, B6*B7/8, B7*B0/8, B7*B1/8, B7*B2/8, B7*B3/8, B7*B4/8, B7*B5/8, B7*B6/8, B7*B7/8, }; -static inline void p8idct(int16_t data[64], FLOAT temp[64], uint8_t *dest, int stride, int x, int y, int type){ +static inline void p8idct(int16_t data[64], FLOAT temp[64], uint8_t *dest, + ptrdiff_t stride, int x, int y, int type) +{ int i; FLOAT s04, d04, s17, d17, s26, d26, s53, d53; FLOAT os07, os16, os25, os34; @@ -135,7 +137,8 @@ void ff_faanidct(int16_t block[64]){ p8idct(block, temp, NULL, 0, 8, 1, 1); } -void ff_faanidct_add(uint8_t *dest, int line_size, int16_t block[64]){ +void ff_faanidct_add(uint8_t *dest, ptrdiff_t line_size, int16_t block[64]) +{ FLOAT temp[64]; int i; @@ -148,7 +151,8 @@ void ff_faanidct_add(uint8_t *dest, int line_size, int16_t block[64]){ p8idct(NULL , temp, dest, line_size, 8, 1, 2); } -void ff_faanidct_put(uint8_t *dest, int line_size, int16_t block[64]){ +void ff_faanidct_put(uint8_t *dest, ptrdiff_t line_size, int16_t block[64]) +{ FLOAT temp[64]; int i; diff --git a/libavcodec/faanidct.h b/libavcodec/faanidct.h index 0c015201cc67a..4eedba812f1f4 100644 --- a/libavcodec/faanidct.h +++ b/libavcodec/faanidct.h @@ -22,10 +22,11 @@ #ifndef AVCODEC_FAANIDCT_H #define AVCODEC_FAANIDCT_H +#include #include void ff_faanidct(int16_t block[64]); -void ff_faanidct_add(uint8_t *dest, int line_size, int16_t block[64]); -void ff_faanidct_put(uint8_t *dest, int line_size, int16_t block[64]); +void ff_faanidct_add(uint8_t *dest, ptrdiff_t line_size, int16_t block[64]); +void ff_faanidct_put(uint8_t *dest, ptrdiff_t line_size, int16_t block[64]); #endif /* AVCODEC_FAANIDCT_H */ diff --git a/libavcodec/idctdsp.c b/libavcodec/idctdsp.c index a9b8727468ba3..5a267e408fd9a 100644 --- a/libavcodec/idctdsp.c +++ b/libavcodec/idctdsp.c @@ -79,11 +79,11 @@ av_cold void ff_init_scantable_permutation(uint8_t *idct_permutation, } } -void (*ff_put_pixels_clamped)(const int16_t *block, uint8_t *pixels, int line_size); -void (*ff_add_pixels_clamped)(const int16_t *block, uint8_t *pixels, int line_size); +void (*ff_put_pixels_clamped)(const int16_t *block, uint8_t *pixels, ptrdiff_t line_size); +void (*ff_add_pixels_clamped)(const int16_t *block, uint8_t *pixels, ptrdiff_t line_size); static void put_pixels_clamped_c(const int16_t *block, uint8_t *restrict pixels, - int line_size) + ptrdiff_t line_size) { int i; @@ -105,7 +105,7 @@ static void put_pixels_clamped_c(const int16_t *block, uint8_t *restrict pixels, static void put_signed_pixels_clamped_c(const int16_t *block, uint8_t *restrict pixels, - int line_size) + ptrdiff_t line_size) { int i, j; @@ -125,7 +125,7 @@ static void put_signed_pixels_clamped_c(const int16_t *block, } static void add_pixels_clamped_c(const int16_t *block, uint8_t *restrict pixels, - int line_size) + ptrdiff_t line_size) { int i; diff --git a/libavcodec/idctdsp.h b/libavcodec/idctdsp.h index c49a4ca15a35c..51de9bc9abeaa 100644 --- a/libavcodec/idctdsp.h +++ b/libavcodec/idctdsp.h @@ -52,13 +52,13 @@ typedef struct IDCTDSPContext { /* pixel ops : interface with DCT */ void (*put_pixels_clamped)(const int16_t *block /* align 16 */, uint8_t *pixels /* align 8 */, - int line_size); + ptrdiff_t line_size); void (*put_signed_pixels_clamped)(const int16_t *block /* align 16 */, uint8_t *pixels /* align 8 */, - int line_size); + ptrdiff_t line_size); void (*add_pixels_clamped)(const int16_t *block /* align 16 */, uint8_t *pixels /* align 8 */, - int line_size); + ptrdiff_t line_size); void (*idct)(int16_t *block /* align 16 */); @@ -68,14 +68,14 @@ typedef struct IDCTDSPContext { * @param line_size size in bytes of a horizontal line of dest */ void (*idct_put)(uint8_t *dest /* align 8 */, - int line_size, int16_t *block /* align 16 */); + ptrdiff_t line_size, int16_t *block /* align 16 */); /** * block -> idct -> add dest -> clip to unsigned 8 bit -> dest. * @param line_size size in bytes of a horizontal line of dest */ void (*idct_add)(uint8_t *dest /* align 8 */, - int line_size, int16_t *block /* align 16 */); + ptrdiff_t line_size, int16_t *block /* align 16 */); /** * IDCT input permutation. @@ -95,8 +95,8 @@ typedef struct IDCTDSPContext { enum idct_permutation_type perm_type; } IDCTDSPContext; -extern void (*ff_put_pixels_clamped)(const int16_t *block, uint8_t *pixels, int line_size); -extern void (*ff_add_pixels_clamped)(const int16_t *block, uint8_t *pixels, int line_size); +extern void (*ff_put_pixels_clamped)(const int16_t *block, uint8_t *pixels, ptrdiff_t line_size); +extern void (*ff_add_pixels_clamped)(const int16_t *block, uint8_t *pixels, ptrdiff_t line_size); void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx); diff --git a/libavcodec/jrevdct.c b/libavcodec/jrevdct.c index 96a884ae8782b..808f5838c5aad 100644 --- a/libavcodec/jrevdct.c +++ b/libavcodec/jrevdct.c @@ -943,13 +943,13 @@ void ff_j_rev_dct(DCTBLOCK data) } } -void ff_jref_idct_put(uint8_t *dest, int line_size, int16_t *block) +void ff_jref_idct_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block) { ff_j_rev_dct(block); ff_put_pixels_clamped(block, dest, line_size); } -void ff_jref_idct_add(uint8_t *dest, int line_size, int16_t *block) +void ff_jref_idct_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block) { ff_j_rev_dct(block); ff_add_pixels_clamped(block, dest, line_size); diff --git a/libavcodec/ppc/idctdsp.c b/libavcodec/ppc/idctdsp.c index 690b08beb8ef4..0aaaac0131f2d 100644 --- a/libavcodec/ppc/idctdsp.c +++ b/libavcodec/ppc/idctdsp.c @@ -153,7 +153,7 @@ static const vec_s16 constants[5] = { { 19266, 26722, 25172, 22654, 19266, 22654, 25172, 26722 } }; -static void idct_put_altivec(uint8_t *dest, int stride, int16_t *blk) +static void idct_put_altivec(uint8_t *dest, ptrdiff_t stride, int16_t *blk) { vec_s16 *block = (vec_s16 *) blk; vec_u8 tmp; @@ -182,7 +182,7 @@ static void idct_put_altivec(uint8_t *dest, int stride, int16_t *blk) COPY(dest, vx7); } -static void idct_add_altivec(uint8_t *dest, int stride, int16_t *blk) +static void idct_add_altivec(uint8_t *dest, ptrdiff_t stride, int16_t *blk) { vec_s16 *block = (vec_s16 *) blk; vec_u8 tmp; diff --git a/libavcodec/ppc/vc1dsp_altivec.c b/libavcodec/ppc/vc1dsp_altivec.c index 0eec4751dfc90..d2524215603cc 100644 --- a/libavcodec/ppc/vc1dsp_altivec.c +++ b/libavcodec/ppc/vc1dsp_altivec.c @@ -229,7 +229,8 @@ static void vc1_inv_trans_8x8_altivec(int16_t block[64]) /** Do inverse transform on 8x4 part of block */ -static void vc1_inv_trans_8x4_altivec(uint8_t *dest, int stride, int16_t *block) +static void vc1_inv_trans_8x4_altivec(uint8_t *dest, ptrdiff_t stride, + int16_t *block) { vector signed short src0, src1, src2, src3, src4, src5, src6, src7; vector signed int s0, s1, s2, s3, s4, s5, s6, s7; diff --git a/libavcodec/simple_idct.c b/libavcodec/simple_idct.c index 6ee1320394bc5..9823a6b7e51bf 100644 --- a/libavcodec/simple_idct.c +++ b/libavcodec/simple_idct.c @@ -49,7 +49,7 @@ and the butterfly must be multiplied by 0.5 * sqrt(2.0) */ #define C_SHIFT (4+1+12) -static inline void idct4col_put(uint8_t *dest, int line_size, const int16_t *col) +static inline void idct4col_put(uint8_t *dest, ptrdiff_t line_size, const int16_t *col) { int c0, c1, c2, c3, a0, a1, a2, a3; @@ -85,7 +85,7 @@ static inline void idct4col_put(uint8_t *dest, int line_size, const int16_t *col /* XXX: I think a 1.0/sqrt(2) normalization should be needed to compensate the extra butterfly stage - I don't have the full DV specification */ -void ff_simple_idct248_put(uint8_t *dest, int line_size, int16_t *block) +void ff_simple_idct248_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block) { int i; int16_t *ptr; @@ -128,7 +128,7 @@ void ff_simple_idct248_put(uint8_t *dest, int line_size, int16_t *block) #define C2 C_FIX(0.2705980501) #define C3 C_FIX(0.5) #define C_SHIFT (4+1+12) -static inline void idct4col_add(uint8_t *dest, int line_size, const int16_t *col) +static inline void idct4col_add(uint8_t *dest, ptrdiff_t line_size, const int16_t *col) { int c0, c1, c2, c3, a0, a1, a2, a3; @@ -173,7 +173,7 @@ static inline void idct4row(int16_t *row) row[3]= (c0 - c1) >> R_SHIFT; } -void ff_simple_idct84_add(uint8_t *dest, int line_size, int16_t *block) +void ff_simple_idct84_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block) { int i; @@ -188,7 +188,7 @@ void ff_simple_idct84_add(uint8_t *dest, int line_size, int16_t *block) } } -void ff_simple_idct48_add(uint8_t *dest, int line_size, int16_t *block) +void ff_simple_idct48_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block) { int i; @@ -203,7 +203,7 @@ void ff_simple_idct48_add(uint8_t *dest, int line_size, int16_t *block) } } -void ff_simple_idct44_add(uint8_t *dest, int line_size, int16_t *block) +void ff_simple_idct44_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block) { int i; diff --git a/libavcodec/simple_idct.h b/libavcodec/simple_idct.h index 7f14aae5d05d4..edc994dbf9c08 100644 --- a/libavcodec/simple_idct.h +++ b/libavcodec/simple_idct.h @@ -28,14 +28,15 @@ #ifndef AVCODEC_SIMPLE_IDCT_H #define AVCODEC_SIMPLE_IDCT_H +#include #include -void ff_simple_idct_put_8(uint8_t *dest, int line_size, int16_t *block); -void ff_simple_idct_add_8(uint8_t *dest, int line_size, int16_t *block); +void ff_simple_idct_put_8(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct_add_8(uint8_t *dest, ptrdiff_t line_size, int16_t *block); void ff_simple_idct_8(int16_t *block); -void ff_simple_idct_put_10(uint8_t *dest, int line_size, int16_t *block); -void ff_simple_idct_add_10(uint8_t *dest, int line_size, int16_t *block); +void ff_simple_idct_put_10(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct_add_10(uint8_t *dest, ptrdiff_t line_size, int16_t *block); void ff_simple_idct_10(int16_t *block); /** * Special version of ff_simple_idct_10() which does dequantization @@ -44,10 +45,10 @@ void ff_simple_idct_10(int16_t *block); */ void ff_prores_idct(int16_t *block, const int16_t *qmat); -void ff_simple_idct248_put(uint8_t *dest, int line_size, int16_t *block); +void ff_simple_idct248_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block); -void ff_simple_idct84_add(uint8_t *dest, int line_size, int16_t *block); -void ff_simple_idct48_add(uint8_t *dest, int line_size, int16_t *block); -void ff_simple_idct44_add(uint8_t *dest, int line_size, int16_t *block); +void ff_simple_idct84_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct48_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct44_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block); #endif /* AVCODEC_SIMPLE_IDCT_H */ diff --git a/libavcodec/simple_idct_template.c b/libavcodec/simple_idct_template.c index 171cdf65ff114..d10df3123ab94 100644 --- a/libavcodec/simple_idct_template.c +++ b/libavcodec/simple_idct_template.c @@ -222,7 +222,7 @@ static inline void FUNC(idctRowCondDC)(int16_t *row, int extra_shift) } \ } while (0) -static inline void FUNC(idctSparseColPut)(pixel *dest, int line_size, +static inline void FUNC(idctSparseColPut)(pixel *dest, ptrdiff_t line_size, int16_t *col) { int a0, a1, a2, a3, b0, b1, b2, b3; @@ -246,7 +246,7 @@ static inline void FUNC(idctSparseColPut)(pixel *dest, int line_size, dest[0] = av_clip_pixel((a0 - b0) >> COL_SHIFT); } -static inline void FUNC(idctSparseColAdd)(pixel *dest, int line_size, +static inline void FUNC(idctSparseColAdd)(pixel *dest, ptrdiff_t line_size, int16_t *col) { int a0, a1, a2, a3, b0, b1, b2, b3; @@ -286,7 +286,7 @@ static inline void FUNC(idctSparseCol)(int16_t *col) col[56] = ((a0 - b0) >> COL_SHIFT); } -void FUNC(ff_simple_idct_put)(uint8_t *dest_, int line_size, int16_t *block) +void FUNC(ff_simple_idct_put)(uint8_t *dest_, ptrdiff_t line_size, int16_t *block) { pixel *dest = (pixel *)dest_; int i; @@ -300,7 +300,7 @@ void FUNC(ff_simple_idct_put)(uint8_t *dest_, int line_size, int16_t *block) FUNC(idctSparseColPut)(dest + i, line_size, block + i); } -void FUNC(ff_simple_idct_add)(uint8_t *dest_, int line_size, int16_t *block) +void FUNC(ff_simple_idct_add)(uint8_t *dest_, ptrdiff_t line_size, int16_t *block) { pixel *dest = (pixel *)dest_; int i; diff --git a/libavcodec/tests/dct.c b/libavcodec/tests/dct.c index 6c6a4e0d0d27f..84ad5f3e80cb8 100644 --- a/libavcodec/tests/dct.c +++ b/libavcodec/tests/dct.c @@ -253,7 +253,7 @@ static int dct_error(const struct algo *dct, int test, int is_idct, int speed) DECLARE_ALIGNED(8, static uint8_t, img_dest)[64]; DECLARE_ALIGNED(8, static uint8_t, img_dest1)[64]; -static void idct248_ref(uint8_t *dest, int linesize, int16_t *block) +static void idct248_ref(uint8_t *dest, ptrdiff_t linesize, int16_t *block) { static int init; static double c8[8][8]; @@ -334,7 +334,8 @@ static void idct248_ref(uint8_t *dest, int linesize, int16_t *block) } static void idct248_error(const char *name, - void (*idct248_put)(uint8_t *dest, int line_size, + void (*idct248_put)(uint8_t *dest, + ptrdiff_t line_size, int16_t *block), int speed) { diff --git a/libavcodec/vc1dsp.c b/libavcodec/vc1dsp.c index cbcc8d29da0cf..e630a48e9d935 100644 --- a/libavcodec/vc1dsp.c +++ b/libavcodec/vc1dsp.c @@ -235,7 +235,7 @@ static void vc1_h_loop_filter16_c(uint8_t *src, int stride, int pq) } /* Do inverse transform on 8x8 block */ -static void vc1_inv_trans_8x8_dc_c(uint8_t *dest, int linesize, int16_t *block) +static void vc1_inv_trans_8x8_dc_c(uint8_t *dest, ptrdiff_t stride, int16_t *block) { int i; int dc = block[0]; @@ -252,7 +252,7 @@ static void vc1_inv_trans_8x8_dc_c(uint8_t *dest, int linesize, int16_t *block) dest[5] = av_clip_uint8(dest[5] + dc); dest[6] = av_clip_uint8(dest[6] + dc); dest[7] = av_clip_uint8(dest[7] + dc); - dest += linesize; + dest += stride; } } @@ -326,7 +326,7 @@ static void vc1_inv_trans_8x8_c(int16_t block[64]) } /* Do inverse transform on 8x4 part of block */ -static void vc1_inv_trans_8x4_dc_c(uint8_t *dest, int linesize, int16_t *block) +static void vc1_inv_trans_8x4_dc_c(uint8_t *dest, ptrdiff_t stride, int16_t *block) { int i; int dc = block[0]; @@ -343,11 +343,11 @@ static void vc1_inv_trans_8x4_dc_c(uint8_t *dest, int linesize, int16_t *block) dest[5] = av_clip_uint8(dest[5] + dc); dest[6] = av_clip_uint8(dest[6] + dc); dest[7] = av_clip_uint8(dest[7] + dc); - dest += linesize; + dest += stride; } } -static void vc1_inv_trans_8x4_c(uint8_t *dest, int linesize, int16_t *block) +static void vc1_inv_trans_8x4_c(uint8_t *dest, ptrdiff_t stride, int16_t *block) { int i; register int t1, t2, t3, t4, t5, t6, t7, t8; @@ -392,10 +392,10 @@ static void vc1_inv_trans_8x4_c(uint8_t *dest, int linesize, int16_t *block) t3 = 22 * src[ 8] + 10 * src[24]; t4 = 22 * src[24] - 10 * src[ 8]; - dest[0 * linesize] = av_clip_uint8(dest[0 * linesize] + ((t1 + t3) >> 7)); - dest[1 * linesize] = av_clip_uint8(dest[1 * linesize] + ((t2 - t4) >> 7)); - dest[2 * linesize] = av_clip_uint8(dest[2 * linesize] + ((t2 + t4) >> 7)); - dest[3 * linesize] = av_clip_uint8(dest[3 * linesize] + ((t1 - t3) >> 7)); + dest[0 * stride] = av_clip_uint8(dest[0 * stride] + ((t1 + t3) >> 7)); + dest[1 * stride] = av_clip_uint8(dest[1 * stride] + ((t2 - t4) >> 7)); + dest[2 * stride] = av_clip_uint8(dest[2 * stride] + ((t2 + t4) >> 7)); + dest[3 * stride] = av_clip_uint8(dest[3 * stride] + ((t1 - t3) >> 7)); src++; dest++; @@ -403,7 +403,7 @@ static void vc1_inv_trans_8x4_c(uint8_t *dest, int linesize, int16_t *block) } /* Do inverse transform on 4x8 parts of block */ -static void vc1_inv_trans_4x8_dc_c(uint8_t *dest, int linesize, int16_t *block) +static void vc1_inv_trans_4x8_dc_c(uint8_t *dest, ptrdiff_t stride, int16_t *block) { int i; int dc = block[0]; @@ -416,11 +416,11 @@ static void vc1_inv_trans_4x8_dc_c(uint8_t *dest, int linesize, int16_t *block) dest[1] = av_clip_uint8(dest[1] + dc); dest[2] = av_clip_uint8(dest[2] + dc); dest[3] = av_clip_uint8(dest[3] + dc); - dest += linesize; + dest += stride; } } -static void vc1_inv_trans_4x8_c(uint8_t *dest, int linesize, int16_t *block) +static void vc1_inv_trans_4x8_c(uint8_t *dest, ptrdiff_t stride, int16_t *block) { int i; register int t1, t2, t3, t4, t5, t6, t7, t8; @@ -461,14 +461,14 @@ static void vc1_inv_trans_4x8_c(uint8_t *dest, int linesize, int16_t *block) t3 = 9 * src[ 8] - 16 * src[24] + 4 * src[40] + 15 * src[56]; t4 = 4 * src[ 8] - 9 * src[24] + 15 * src[40] - 16 * src[56]; - dest[0 * linesize] = av_clip_uint8(dest[0 * linesize] + ((t5 + t1) >> 7)); - dest[1 * linesize] = av_clip_uint8(dest[1 * linesize] + ((t6 + t2) >> 7)); - dest[2 * linesize] = av_clip_uint8(dest[2 * linesize] + ((t7 + t3) >> 7)); - dest[3 * linesize] = av_clip_uint8(dest[3 * linesize] + ((t8 + t4) >> 7)); - dest[4 * linesize] = av_clip_uint8(dest[4 * linesize] + ((t8 - t4 + 1) >> 7)); - dest[5 * linesize] = av_clip_uint8(dest[5 * linesize] + ((t7 - t3 + 1) >> 7)); - dest[6 * linesize] = av_clip_uint8(dest[6 * linesize] + ((t6 - t2 + 1) >> 7)); - dest[7 * linesize] = av_clip_uint8(dest[7 * linesize] + ((t5 - t1 + 1) >> 7)); + dest[0 * stride] = av_clip_uint8(dest[0 * stride] + ((t5 + t1) >> 7)); + dest[1 * stride] = av_clip_uint8(dest[1 * stride] + ((t6 + t2) >> 7)); + dest[2 * stride] = av_clip_uint8(dest[2 * stride] + ((t7 + t3) >> 7)); + dest[3 * stride] = av_clip_uint8(dest[3 * stride] + ((t8 + t4) >> 7)); + dest[4 * stride] = av_clip_uint8(dest[4 * stride] + ((t8 - t4 + 1) >> 7)); + dest[5 * stride] = av_clip_uint8(dest[5 * stride] + ((t7 - t3 + 1) >> 7)); + dest[6 * stride] = av_clip_uint8(dest[6 * stride] + ((t6 - t2 + 1) >> 7)); + dest[7 * stride] = av_clip_uint8(dest[7 * stride] + ((t5 - t1 + 1) >> 7)); src++; dest++; @@ -476,7 +476,7 @@ static void vc1_inv_trans_4x8_c(uint8_t *dest, int linesize, int16_t *block) } /* Do inverse transform on 4x4 part of block */ -static void vc1_inv_trans_4x4_dc_c(uint8_t *dest, int linesize, int16_t *block) +static void vc1_inv_trans_4x4_dc_c(uint8_t *dest, ptrdiff_t stride, int16_t *block) { int i; int dc = block[0]; @@ -489,11 +489,11 @@ static void vc1_inv_trans_4x4_dc_c(uint8_t *dest, int linesize, int16_t *block) dest[1] = av_clip_uint8(dest[1] + dc); dest[2] = av_clip_uint8(dest[2] + dc); dest[3] = av_clip_uint8(dest[3] + dc); - dest += linesize; + dest += stride; } } -static void vc1_inv_trans_4x4_c(uint8_t *dest, int linesize, int16_t *block) +static void vc1_inv_trans_4x4_c(uint8_t *dest, ptrdiff_t stride, int16_t *block) { int i; register int t1, t2, t3, t4; @@ -523,10 +523,10 @@ static void vc1_inv_trans_4x4_c(uint8_t *dest, int linesize, int16_t *block) t3 = 22 * src[8] + 10 * src[24]; t4 = 22 * src[24] - 10 * src[8]; - dest[0 * linesize] = av_clip_uint8(dest[0 * linesize] + ((t1 + t3) >> 7)); - dest[1 * linesize] = av_clip_uint8(dest[1 * linesize] + ((t2 - t4) >> 7)); - dest[2 * linesize] = av_clip_uint8(dest[2 * linesize] + ((t2 + t4) >> 7)); - dest[3 * linesize] = av_clip_uint8(dest[3 * linesize] + ((t1 - t3) >> 7)); + dest[0 * stride] = av_clip_uint8(dest[0 * stride] + ((t1 + t3) >> 7)); + dest[1 * stride] = av_clip_uint8(dest[1 * stride] + ((t2 - t4) >> 7)); + dest[2 * stride] = av_clip_uint8(dest[2 * stride] + ((t2 + t4) >> 7)); + dest[3 * stride] = av_clip_uint8(dest[3 * stride] + ((t1 - t3) >> 7)); src++; dest++; diff --git a/libavcodec/vc1dsp.h b/libavcodec/vc1dsp.h index f2b0c707fddac..a9bd712025bcf 100644 --- a/libavcodec/vc1dsp.h +++ b/libavcodec/vc1dsp.h @@ -33,13 +33,13 @@ typedef struct VC1DSPContext { /* vc1 functions */ void (*vc1_inv_trans_8x8)(int16_t *b); - void (*vc1_inv_trans_8x4)(uint8_t *dest, int line_size, int16_t *block); - void (*vc1_inv_trans_4x8)(uint8_t *dest, int line_size, int16_t *block); - void (*vc1_inv_trans_4x4)(uint8_t *dest, int line_size, int16_t *block); - void (*vc1_inv_trans_8x8_dc)(uint8_t *dest, int line_size, int16_t *block); - void (*vc1_inv_trans_8x4_dc)(uint8_t *dest, int line_size, int16_t *block); - void (*vc1_inv_trans_4x8_dc)(uint8_t *dest, int line_size, int16_t *block); - void (*vc1_inv_trans_4x4_dc)(uint8_t *dest, int line_size, int16_t *block); + void (*vc1_inv_trans_8x4)(uint8_t *dest, ptrdiff_t stride, int16_t *block); + void (*vc1_inv_trans_4x8)(uint8_t *dest, ptrdiff_t stride, int16_t *block); + void (*vc1_inv_trans_4x4)(uint8_t *dest, ptrdiff_t stride, int16_t *block); + void (*vc1_inv_trans_8x8_dc)(uint8_t *dest, ptrdiff_t stride, int16_t *block); + void (*vc1_inv_trans_8x4_dc)(uint8_t *dest, ptrdiff_t stride, int16_t *block); + void (*vc1_inv_trans_4x8_dc)(uint8_t *dest, ptrdiff_t stride, int16_t *block); + void (*vc1_inv_trans_4x4_dc)(uint8_t *dest, ptrdiff_t stride, int16_t *block); void (*vc1_v_overlap)(uint8_t *src, int stride); void (*vc1_h_overlap)(uint8_t *src, int stride); void (*vc1_v_s_overlap)(int16_t *top, int16_t *bottom); diff --git a/libavcodec/wmv2dsp.c b/libavcodec/wmv2dsp.c index 2e3a3ff5527d5..90073e4b4a6d8 100644 --- a/libavcodec/wmv2dsp.c +++ b/libavcodec/wmv2dsp.c @@ -93,7 +93,7 @@ static void wmv2_idct_col(short * b) b[8 * 7] = (a0 + a2 - a1 - a5 + (1 << 13)) >> 14; } -static void wmv2_idct_add_c(uint8_t *dest, int line_size, int16_t *block) +static void wmv2_idct_add_c(uint8_t *dest, ptrdiff_t line_size, int16_t *block) { int i; @@ -116,7 +116,7 @@ static void wmv2_idct_add_c(uint8_t *dest, int line_size, int16_t *block) } } -static void wmv2_idct_put_c(uint8_t *dest, int line_size, int16_t *block) +static void wmv2_idct_put_c(uint8_t *dest, ptrdiff_t line_size, int16_t *block) { int i; diff --git a/libavcodec/wmv2dsp.h b/libavcodec/wmv2dsp.h index f2f258ed3417b..b38f4dc08f2df 100644 --- a/libavcodec/wmv2dsp.h +++ b/libavcodec/wmv2dsp.h @@ -24,8 +24,8 @@ #include "qpeldsp.h" typedef struct WMV2DSPContext { - void (*idct_add)(uint8_t *dest, int line_size, int16_t *block); - void (*idct_put)(uint8_t *dest, int line_size, int16_t *block); + void (*idct_add)(uint8_t *dest, ptrdiff_t line_size, int16_t *block); + void (*idct_put)(uint8_t *dest, ptrdiff_t line_size, int16_t *block); qpel_mc_func put_mspel_pixels_tab[8]; diff --git a/libavcodec/x86/idctdsp.h b/libavcodec/x86/idctdsp.h index 22df3dd758734..6e6c68857db65 100644 --- a/libavcodec/x86/idctdsp.h +++ b/libavcodec/x86/idctdsp.h @@ -19,13 +19,14 @@ #ifndef AVCODEC_X86_IDCTDSP_H #define AVCODEC_X86_IDCTDSP_H +#include #include void ff_add_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, - int line_size); + ptrdiff_t line_size); void ff_put_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, - int line_size); + ptrdiff_t line_size); void ff_put_signed_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, - int line_size); + ptrdiff_t line_size); #endif /* AVCODEC_X86_IDCTDSP_H */ diff --git a/libavcodec/x86/idctdsp_mmx.c b/libavcodec/x86/idctdsp_mmx.c index 7285b1d357891..523f36816b990 100644 --- a/libavcodec/x86/idctdsp_mmx.c +++ b/libavcodec/x86/idctdsp_mmx.c @@ -31,7 +31,7 @@ #if HAVE_INLINE_ASM void ff_put_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, - int line_size) + ptrdiff_t line_size) { const int16_t *p; uint8_t *pix; @@ -107,7 +107,7 @@ void ff_put_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, "movq %%mm4, (%0, %1) \n\t" void ff_put_signed_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, - int line_size) + ptrdiff_t line_size) { x86_reg line_skip = line_size; x86_reg line_skip3; @@ -124,7 +124,7 @@ void ff_put_signed_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, } void ff_add_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, - int line_size) + ptrdiff_t line_size) { const int16_t *p; uint8_t *pix; diff --git a/libavcodec/x86/simple_idct.c b/libavcodec/x86/simple_idct.c index 49784e2130f66..0939a49a3abdd 100644 --- a/libavcodec/x86/simple_idct.c +++ b/libavcodec/x86/simple_idct.c @@ -904,12 +904,12 @@ void ff_simple_idct_mmx(int16_t *block) //FIXME merge add/put into the idct -void ff_simple_idct_put_mmx(uint8_t *dest, int line_size, int16_t *block) +void ff_simple_idct_put_mmx(uint8_t *dest, ptrdiff_t line_size, int16_t *block) { idct(block); ff_put_pixels_clamped(block, dest, line_size); } -void ff_simple_idct_add_mmx(uint8_t *dest, int line_size, int16_t *block) +void ff_simple_idct_add_mmx(uint8_t *dest, ptrdiff_t line_size, int16_t *block) { idct(block); ff_add_pixels_clamped(block, dest, line_size); diff --git a/libavcodec/x86/simple_idct.h b/libavcodec/x86/simple_idct.h index 4fc29141b5d21..15784a9501a86 100644 --- a/libavcodec/x86/simple_idct.h +++ b/libavcodec/x86/simple_idct.h @@ -19,10 +19,11 @@ #ifndef AVCODEC_X86_SIMPLE_IDCT_H #define AVCODEC_X86_SIMPLE_IDCT_H +#include #include void ff_simple_idct_mmx(int16_t *block); -void ff_simple_idct_add_mmx(uint8_t *dest, int line_size, int16_t *block); -void ff_simple_idct_put_mmx(uint8_t *dest, int line_size, int16_t *block); +void ff_simple_idct_add_mmx(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct_put_mmx(uint8_t *dest, ptrdiff_t line_size, int16_t *block); #endif /* AVCODEC_X86_SIMPLE_IDCT_H */ diff --git a/libavcodec/x86/vc1dsp_mmx.c b/libavcodec/x86/vc1dsp_mmx.c index 9bbc234d25592..d64ddf0174c99 100644 --- a/libavcodec/x86/vc1dsp_mmx.c +++ b/libavcodec/x86/vc1dsp_mmx.c @@ -498,7 +498,7 @@ DECLARE_FUNCTION(3, 1) DECLARE_FUNCTION(3, 2) DECLARE_FUNCTION(3, 3) -static void vc1_inv_trans_4x4_dc_mmxext(uint8_t *dest, int linesize, +static void vc1_inv_trans_4x4_dc_mmxext(uint8_t *dest, ptrdiff_t stride, int16_t *block) { int dc = block[0]; @@ -530,14 +530,14 @@ static void vc1_inv_trans_4x4_dc_mmxext(uint8_t *dest, int linesize, "movd %%mm3, %1 \n\t" "movd %%mm4, %2 \n\t" "movd %%mm5, %3 \n\t" - :"+m"(*(uint32_t*)(dest+0*linesize)), - "+m"(*(uint32_t*)(dest+1*linesize)), - "+m"(*(uint32_t*)(dest+2*linesize)), - "+m"(*(uint32_t*)(dest+3*linesize)) + :"+m"(*(uint32_t *)(dest + 0 * stride)), + "+m"(*(uint32_t *)(dest + 1 * stride)), + "+m"(*(uint32_t *)(dest + 2 * stride)), + "+m"(*(uint32_t *)(dest + 3 * stride)) ); } -static void vc1_inv_trans_4x8_dc_mmxext(uint8_t *dest, int linesize, +static void vc1_inv_trans_4x8_dc_mmxext(uint8_t *dest, ptrdiff_t stride, int16_t *block) { int dc = block[0]; @@ -569,12 +569,12 @@ static void vc1_inv_trans_4x8_dc_mmxext(uint8_t *dest, int linesize, "movd %%mm3, %1 \n\t" "movd %%mm4, %2 \n\t" "movd %%mm5, %3 \n\t" - :"+m"(*(uint32_t*)(dest+0*linesize)), - "+m"(*(uint32_t*)(dest+1*linesize)), - "+m"(*(uint32_t*)(dest+2*linesize)), - "+m"(*(uint32_t*)(dest+3*linesize)) + :"+m"(*(uint32_t *)(dest + 0 * stride)), + "+m"(*(uint32_t *)(dest + 1 * stride)), + "+m"(*(uint32_t *)(dest + 2 * stride)), + "+m"(*(uint32_t *)(dest + 3 * stride)) ); - dest += 4*linesize; + dest += 4 * stride; __asm__ volatile( "movd %0, %%mm2 \n\t" "movd %1, %%mm3 \n\t" @@ -592,14 +592,14 @@ static void vc1_inv_trans_4x8_dc_mmxext(uint8_t *dest, int linesize, "movd %%mm3, %1 \n\t" "movd %%mm4, %2 \n\t" "movd %%mm5, %3 \n\t" - :"+m"(*(uint32_t*)(dest+0*linesize)), - "+m"(*(uint32_t*)(dest+1*linesize)), - "+m"(*(uint32_t*)(dest+2*linesize)), - "+m"(*(uint32_t*)(dest+3*linesize)) + :"+m"(*(uint32_t *)(dest + 0 * stride)), + "+m"(*(uint32_t *)(dest + 1 * stride)), + "+m"(*(uint32_t *)(dest + 2 * stride)), + "+m"(*(uint32_t *)(dest + 3 * stride)) ); } -static void vc1_inv_trans_8x4_dc_mmxext(uint8_t *dest, int linesize, +static void vc1_inv_trans_8x4_dc_mmxext(uint8_t *dest, ptrdiff_t stride, int16_t *block) { int dc = block[0]; @@ -631,14 +631,14 @@ static void vc1_inv_trans_8x4_dc_mmxext(uint8_t *dest, int linesize, "movq %%mm3, %1 \n\t" "movq %%mm4, %2 \n\t" "movq %%mm5, %3 \n\t" - :"+m"(*(uint32_t*)(dest+0*linesize)), - "+m"(*(uint32_t*)(dest+1*linesize)), - "+m"(*(uint32_t*)(dest+2*linesize)), - "+m"(*(uint32_t*)(dest+3*linesize)) + :"+m"(*(uint32_t *)(dest + 0 * stride)), + "+m"(*(uint32_t *)(dest + 1 * stride)), + "+m"(*(uint32_t *)(dest + 2 * stride)), + "+m"(*(uint32_t *)(dest + 3 * stride)) ); } -static void vc1_inv_trans_8x8_dc_mmxext(uint8_t *dest, int linesize, +static void vc1_inv_trans_8x8_dc_mmxext(uint8_t *dest, ptrdiff_t stride, int16_t *block) { int dc = block[0]; @@ -670,12 +670,12 @@ static void vc1_inv_trans_8x8_dc_mmxext(uint8_t *dest, int linesize, "movq %%mm3, %1 \n\t" "movq %%mm4, %2 \n\t" "movq %%mm5, %3 \n\t" - :"+m"(*(uint32_t*)(dest+0*linesize)), - "+m"(*(uint32_t*)(dest+1*linesize)), - "+m"(*(uint32_t*)(dest+2*linesize)), - "+m"(*(uint32_t*)(dest+3*linesize)) + :"+m"(*(uint32_t *)(dest + 0 * stride)), + "+m"(*(uint32_t *)(dest + 1 * stride)), + "+m"(*(uint32_t *)(dest + 2 * stride)), + "+m"(*(uint32_t *)(dest + 3 * stride)) ); - dest += 4*linesize; + dest += 4 * stride; __asm__ volatile( "movq %0, %%mm2 \n\t" "movq %1, %%mm3 \n\t" @@ -693,10 +693,10 @@ static void vc1_inv_trans_8x8_dc_mmxext(uint8_t *dest, int linesize, "movq %%mm3, %1 \n\t" "movq %%mm4, %2 \n\t" "movq %%mm5, %3 \n\t" - :"+m"(*(uint32_t*)(dest+0*linesize)), - "+m"(*(uint32_t*)(dest+1*linesize)), - "+m"(*(uint32_t*)(dest+2*linesize)), - "+m"(*(uint32_t*)(dest+3*linesize)) + :"+m"(*(uint32_t *)(dest + 0 * stride)), + "+m"(*(uint32_t *)(dest + 1 * stride)), + "+m"(*(uint32_t *)(dest + 2 * stride)), + "+m"(*(uint32_t *)(dest + 3 * stride)) ); } diff --git a/libavcodec/x86/xvididct.h b/libavcodec/x86/xvididct.h index 13a4e85890a2e..6640b6b78c96d 100644 --- a/libavcodec/x86/xvididct.h +++ b/libavcodec/x86/xvididct.h @@ -26,18 +26,19 @@ #ifndef AVCODEC_X86_XVIDIDCT_H #define AVCODEC_X86_XVIDIDCT_H +#include #include void ff_xvid_idct_mmx(short *block); -void ff_xvid_idct_mmx_put(uint8_t *dest, int line_size, int16_t *block); -void ff_xvid_idct_mmx_add(uint8_t *dest, int line_size, int16_t *block); +void ff_xvid_idct_mmx_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_xvid_idct_mmx_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block); void ff_xvid_idct_mmxext(short *block); -void ff_xvid_idct_mmxext_put(uint8_t *dest, int line_size, int16_t *block); -void ff_xvid_idct_mmxext_add(uint8_t *dest, int line_size, int16_t *block); +void ff_xvid_idct_mmxext_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_xvid_idct_mmxext_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block); void ff_xvid_idct_sse2(short *block); -void ff_xvid_idct_sse2_put(uint8_t *dest, int line_size, short *block); -void ff_xvid_idct_sse2_add(uint8_t *dest, int line_size, short *block); +void ff_xvid_idct_sse2_put(uint8_t *dest, ptrdiff_t line_size, short *block); +void ff_xvid_idct_sse2_add(uint8_t *dest, ptrdiff_t line_size, short *block); #endif /* AVCODEC_X86_XVIDIDCT_H */ diff --git a/libavcodec/x86/xvididct_mmx.c b/libavcodec/x86/xvididct_mmx.c index e371142974cd9..9bb407cd708b0 100644 --- a/libavcodec/x86/xvididct_mmx.c +++ b/libavcodec/x86/xvididct_mmx.c @@ -494,13 +494,13 @@ void ff_xvid_idct_mmx(short *block) :: "r" (block), "r" (rounder_0), "r" (tab_i_04_mmx), "r" (tg_1_16)); } -void ff_xvid_idct_mmx_put(uint8_t *dest, int line_size, int16_t *block) +void ff_xvid_idct_mmx_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block) { ff_xvid_idct_mmx(block); ff_put_pixels_clamped_mmx(block, dest, line_size); } -void ff_xvid_idct_mmx_add(uint8_t *dest, int line_size, int16_t *block) +void ff_xvid_idct_mmx_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block) { ff_xvid_idct_mmx(block); ff_add_pixels_clamped_mmx(block, dest, line_size); @@ -533,13 +533,13 @@ void ff_xvid_idct_mmxext(short *block) :: "r" (block), "r" (rounder_0), "r" (tab_i_04_xmm), "r" (tg_1_16)); } -void ff_xvid_idct_mmxext_put(uint8_t *dest, int line_size, int16_t *block) +void ff_xvid_idct_mmxext_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block) { ff_xvid_idct_mmxext(block); ff_put_pixels_clamped_mmx(block, dest, line_size); } -void ff_xvid_idct_mmxext_add(uint8_t *dest, int line_size, int16_t *block) +void ff_xvid_idct_mmxext_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block) { ff_xvid_idct_mmxext(block); ff_add_pixels_clamped_mmx(block, dest, line_size); diff --git a/libavcodec/x86/xvididct_sse2.c b/libavcodec/x86/xvididct_sse2.c index d4f01693ea317..f318e95999538 100644 --- a/libavcodec/x86/xvididct_sse2.c +++ b/libavcodec/x86/xvididct_sse2.c @@ -390,13 +390,13 @@ inline void ff_xvid_idct_sse2(short *block) "%eax", "%ecx", "%edx", "%esi", "memory"); } -void ff_xvid_idct_sse2_put(uint8_t *dest, int line_size, short *block) +void ff_xvid_idct_sse2_put(uint8_t *dest, ptrdiff_t line_size, short *block) { ff_xvid_idct_sse2(block); ff_put_pixels_clamped_mmx(block, dest, line_size); } -void ff_xvid_idct_sse2_add(uint8_t *dest, int line_size, short *block) +void ff_xvid_idct_sse2_add(uint8_t *dest, ptrdiff_t line_size, short *block) { ff_xvid_idct_sse2(block); ff_add_pixels_clamped_mmx(block, dest, line_size); diff --git a/libavcodec/xvididct.c b/libavcodec/xvididct.c index ca89703233fac..40bd61a5ac6cc 100644 --- a/libavcodec/xvididct.c +++ b/libavcodec/xvididct.c @@ -318,13 +318,13 @@ void ff_xvid_idct(int16_t *const in) } } -static void xvid_idct_put(uint8_t *dest, int line_size, int16_t *block) +static void xvid_idct_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block) { ff_xvid_idct(block); ff_put_pixels_clamped(block, dest, line_size); } -static void xvid_idct_add(uint8_t *dest, int line_size, int16_t *block) +static void xvid_idct_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block) { ff_xvid_idct(block); ff_add_pixels_clamped(block, dest, line_size); From e4a94d8b36c48d95a7d412c40d7b558422ff659c Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 1 Sep 2016 21:41:01 +0200 Subject: [PATCH 0203/3374] h264chroma: Change type of stride parameters to ptrdiff_t This avoids SIMD-optimized functions having to sign-extend their stride argument manually to be able to do pointer arithmetic. --- libavcodec/aarch64/h264chroma_init_aarch64.c | 12 ++++----- libavcodec/aarch64/h264cmc_neon.S | 7 ++---- libavcodec/aarch64/rv40dsp_init_aarch64.c | 16 ++++++------ libavcodec/aarch64/vc1dsp_init_aarch64.c | 16 ++++++------ libavcodec/arm/h264chroma_init_arm.c | 18 +++++++++----- libavcodec/arm/h264cmc_neon.S | 4 +-- libavcodec/arm/vc1dsp_init_neon.c | 16 ++++++------ libavcodec/h264chroma.h | 3 ++- libavcodec/h264chroma_template.c | 16 +++++++----- libavcodec/ppc/h264chroma_template.c | 9 +++++-- libavcodec/rv40dsp.c | 14 ++++++++--- libavcodec/vc1dsp.c | 8 +++--- libavcodec/x86/h264_chromamc.asm | 18 +------------- libavcodec/x86/h264_chromamc_10bit.asm | 15 +++++------ libavcodec/x86/h264chroma_init.c | 26 ++++++++++---------- libavcodec/x86/rv40dsp_init.c | 12 ++++----- libavcodec/x86/vc1dsp_init.c | 10 ++++---- 17 files changed, 110 insertions(+), 110 deletions(-) diff --git a/libavcodec/aarch64/h264chroma_init_aarch64.c b/libavcodec/aarch64/h264chroma_init_aarch64.c index c7679ab4ccaef..a37329134442b 100644 --- a/libavcodec/aarch64/h264chroma_init_aarch64.c +++ b/libavcodec/aarch64/h264chroma_init_aarch64.c @@ -28,18 +28,18 @@ #include "config.h" -void ff_put_h264_chroma_mc8_neon(uint8_t *dst, uint8_t *src, int stride, +void ff_put_h264_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int h, int x, int y); -void ff_put_h264_chroma_mc4_neon(uint8_t *dst, uint8_t *src, int stride, +void ff_put_h264_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int h, int x, int y); -void ff_put_h264_chroma_mc2_neon(uint8_t *dst, uint8_t *src, int stride, +void ff_put_h264_chroma_mc2_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int h, int x, int y); -void ff_avg_h264_chroma_mc8_neon(uint8_t *dst, uint8_t *src, int stride, +void ff_avg_h264_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int h, int x, int y); -void ff_avg_h264_chroma_mc4_neon(uint8_t *dst, uint8_t *src, int stride, +void ff_avg_h264_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int h, int x, int y); -void ff_avg_h264_chroma_mc2_neon(uint8_t *dst, uint8_t *src, int stride, +void ff_avg_h264_chroma_mc2_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int h, int x, int y); av_cold void ff_h264chroma_init_aarch64(H264ChromaContext *c, int bit_depth) diff --git a/libavcodec/aarch64/h264cmc_neon.S b/libavcodec/aarch64/h264cmc_neon.S index d1025c7a25429..edc256cbc3a68 100644 --- a/libavcodec/aarch64/h264cmc_neon.S +++ b/libavcodec/aarch64/h264cmc_neon.S @@ -21,10 +21,9 @@ #include "libavutil/aarch64/asm.S" -/* chroma_mc8(uint8_t *dst, uint8_t *src, int stride, int h, int x, int y) */ +/* chroma_mc8(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int h, int x, int y) */ .macro h264_chroma_mc8 type, codec=h264 function ff_\type\()_\codec\()_chroma_mc8_neon, export=1 - sxtw x2, w2 .ifc \type,avg mov x8, x0 .endif @@ -192,10 +191,9 @@ function ff_\type\()_\codec\()_chroma_mc8_neon, export=1 endfunc .endm -/* chroma_mc4(uint8_t *dst, uint8_t *src, int stride, int h, int x, int y) */ +/* chroma_mc4(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int h, int x, int y) */ .macro h264_chroma_mc4 type, codec=h264 function ff_\type\()_\codec\()_chroma_mc4_neon, export=1 - sxtw x2, w2 .ifc \type,avg mov x8, x0 .endif @@ -359,7 +357,6 @@ endfunc .macro h264_chroma_mc2 type function ff_\type\()_h264_chroma_mc2_neon, export=1 - sxtw x2, w2 prfm pldl1strm, [x1] prfm pldl1strm, [x1, x2] orr w7, w4, w5 diff --git a/libavcodec/aarch64/rv40dsp_init_aarch64.c b/libavcodec/aarch64/rv40dsp_init_aarch64.c index 0bb404f6d2dbf..f7fcd5b493521 100644 --- a/libavcodec/aarch64/rv40dsp_init_aarch64.c +++ b/libavcodec/aarch64/rv40dsp_init_aarch64.c @@ -25,15 +25,15 @@ #include "config.h" -void ff_put_rv40_chroma_mc8_neon(uint8_t *dst, uint8_t *src, int stride, int h, - int x, int y); -void ff_put_rv40_chroma_mc4_neon(uint8_t *dst, uint8_t *src, int stride, int h, - int x, int y); +void ff_put_rv40_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); +void ff_put_rv40_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); -void ff_avg_rv40_chroma_mc8_neon(uint8_t *dst, uint8_t *src, int stride, int h, - int x, int y); -void ff_avg_rv40_chroma_mc4_neon(uint8_t *dst, uint8_t *src, int stride, int h, - int x, int y); +void ff_avg_rv40_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); +void ff_avg_rv40_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); av_cold void ff_rv40dsp_init_aarch64(RV34DSPContext *c) { diff --git a/libavcodec/aarch64/vc1dsp_init_aarch64.c b/libavcodec/aarch64/vc1dsp_init_aarch64.c index 11cd81eb5cd4c..ab97a97740f40 100644 --- a/libavcodec/aarch64/vc1dsp_init_aarch64.c +++ b/libavcodec/aarch64/vc1dsp_init_aarch64.c @@ -25,14 +25,14 @@ #include "config.h" -void ff_put_vc1_chroma_mc8_neon(uint8_t *dst, uint8_t *src, int stride, int h, - int x, int y); -void ff_avg_vc1_chroma_mc8_neon(uint8_t *dst, uint8_t *src, int stride, int h, - int x, int y); -void ff_put_vc1_chroma_mc4_neon(uint8_t *dst, uint8_t *src, int stride, int h, - int x, int y); -void ff_avg_vc1_chroma_mc4_neon(uint8_t *dst, uint8_t *src, int stride, int h, - int x, int y); +void ff_put_vc1_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); +void ff_avg_vc1_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); +void ff_put_vc1_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); +void ff_avg_vc1_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); av_cold void ff_vc1dsp_init_aarch64(VC1DSPContext *dsp) { diff --git a/libavcodec/arm/h264chroma_init_arm.c b/libavcodec/arm/h264chroma_init_arm.c index 6f365533cf5f4..0e84362e9243f 100644 --- a/libavcodec/arm/h264chroma_init_arm.c +++ b/libavcodec/arm/h264chroma_init_arm.c @@ -26,13 +26,19 @@ #include "libavutil/arm/cpu.h" #include "libavcodec/h264chroma.h" -void ff_put_h264_chroma_mc8_neon(uint8_t *, uint8_t *, int, int, int, int); -void ff_put_h264_chroma_mc4_neon(uint8_t *, uint8_t *, int, int, int, int); -void ff_put_h264_chroma_mc2_neon(uint8_t *, uint8_t *, int, int, int, int); +void ff_put_h264_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); +void ff_put_h264_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); +void ff_put_h264_chroma_mc2_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); -void ff_avg_h264_chroma_mc8_neon(uint8_t *, uint8_t *, int, int, int, int); -void ff_avg_h264_chroma_mc4_neon(uint8_t *, uint8_t *, int, int, int, int); -void ff_avg_h264_chroma_mc2_neon(uint8_t *, uint8_t *, int, int, int, int); +void ff_avg_h264_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); +void ff_avg_h264_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); +void ff_avg_h264_chroma_mc2_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); av_cold void ff_h264chroma_init_arm(H264ChromaContext *c, int bit_depth) { diff --git a/libavcodec/arm/h264cmc_neon.S b/libavcodec/arm/h264cmc_neon.S index ee7011b00b6b8..779dc0bba6eb8 100644 --- a/libavcodec/arm/h264cmc_neon.S +++ b/libavcodec/arm/h264cmc_neon.S @@ -20,7 +20,7 @@ #include "libavutil/arm/asm.S" -/* chroma_mc8(uint8_t *dst, uint8_t *src, int stride, int h, int x, int y) */ +/* chroma_mc8(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int h, int x, int y) */ .macro h264_chroma_mc8 type, codec=h264 function ff_\type\()_\codec\()_chroma_mc8_neon, export=1 push {r4-r7, lr} @@ -195,7 +195,7 @@ T cmp r7, #0 endfunc .endm -/* chroma_mc4(uint8_t *dst, uint8_t *src, int stride, int h, int x, int y) */ +/* chroma_mc4(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int h, int x, int y) */ .macro h264_chroma_mc4 type, codec=h264 function ff_\type\()_\codec\()_chroma_mc4_neon, export=1 push {r4-r7, lr} diff --git a/libavcodec/arm/vc1dsp_init_neon.c b/libavcodec/arm/vc1dsp_init_neon.c index 55d3a653502fa..08c07c444344f 100644 --- a/libavcodec/arm/vc1dsp_init_neon.c +++ b/libavcodec/arm/vc1dsp_init_neon.c @@ -72,14 +72,14 @@ void ff_put_vc1_mspel_mc32_neon(uint8_t *dst, const uint8_t *src, void ff_put_vc1_mspel_mc33_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride, int rnd); -void ff_put_vc1_chroma_mc8_neon(uint8_t *dst, uint8_t *src, int stride, int h, - int x, int y); -void ff_avg_vc1_chroma_mc8_neon(uint8_t *dst, uint8_t *src, int stride, int h, - int x, int y); -void ff_put_vc1_chroma_mc4_neon(uint8_t *dst, uint8_t *src, int stride, int h, - int x, int y); -void ff_avg_vc1_chroma_mc4_neon(uint8_t *dst, uint8_t *src, int stride, int h, - int x, int y); +void ff_put_vc1_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); +void ff_avg_vc1_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); +void ff_put_vc1_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); +void ff_avg_vc1_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); av_cold void ff_vc1dsp_init_neon(VC1DSPContext *dsp) { diff --git a/libavcodec/h264chroma.h b/libavcodec/h264chroma.h index 93064fe06b561..9fc2a0f2e84ad 100644 --- a/libavcodec/h264chroma.h +++ b/libavcodec/h264chroma.h @@ -19,9 +19,10 @@ #ifndef AVCODEC_H264CHROMA_H #define AVCODEC_H264CHROMA_H +#include #include -typedef void (*h264_chroma_mc_func)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x, int y); +typedef void (*h264_chroma_mc_func)(uint8_t *dst /*align 8*/, uint8_t *src /*align 1*/, ptrdiff_t srcStride, int h, int x, int y); typedef struct H264ChromaContext { h264_chroma_mc_func put_h264_chroma_pixels_tab[3]; diff --git a/libavcodec/h264chroma_template.c b/libavcodec/h264chroma_template.c index 028ed132cf65e..ed364ddbdda36 100644 --- a/libavcodec/h264chroma_template.c +++ b/libavcodec/h264chroma_template.c @@ -20,11 +20,13 @@ */ #include +#include #include "bit_depth_template.c" #define H264_CHROMA_MC(OPNAME, OP)\ -static void FUNCC(OPNAME ## h264_chroma_mc2)(uint8_t *_dst/*align 8*/, uint8_t *_src/*align 1*/, int stride, int h, int x, int y){\ +static void FUNCC(OPNAME ## h264_chroma_mc2)(uint8_t *_dst /*align 8*/, uint8_t *_src /*align 1*/, ptrdiff_t stride, int h, int x, int y)\ +{\ pixel *dst = (pixel*)_dst;\ pixel *src = (pixel*)_src;\ const int A=(8-x)*(8-y);\ @@ -45,7 +47,7 @@ static void FUNCC(OPNAME ## h264_chroma_mc2)(uint8_t *_dst/*align 8*/, uint8_t * }\ } else if (B + C) {\ const int E= B+C;\ - const int step= C ? stride : 1;\ + const ptrdiff_t step = C ? stride : 1;\ for(i=0; i> 6) static void put_no_rnd_vc1_chroma_mc8_c(uint8_t *dst /* align 8 */, uint8_t *src /* align 1 */, - int stride, int h, int x, int y) + ptrdiff_t stride, int h, int x, int y) { const int A = (8 - x) * (8 - y); const int B = (x) * (8 - y); @@ -725,7 +725,7 @@ static void put_no_rnd_vc1_chroma_mc8_c(uint8_t *dst /* align 8 */, } static void put_no_rnd_vc1_chroma_mc4_c(uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y) + ptrdiff_t stride, int h, int x, int y) { const int A = (8 - x) * (8 - y); const int B = (x) * (8 - y); @@ -748,7 +748,7 @@ static void put_no_rnd_vc1_chroma_mc4_c(uint8_t *dst, uint8_t *src, #define avg2(a, b) (((a) + (b) + 1) >> 1) static void avg_no_rnd_vc1_chroma_mc8_c(uint8_t *dst /* align 8 */, uint8_t *src /* align 1 */, - int stride, int h, int x, int y) + ptrdiff_t stride, int h, int x, int y) { const int A = (8 - x) * (8 - y); const int B = (x) * (8 - y); @@ -774,7 +774,7 @@ static void avg_no_rnd_vc1_chroma_mc8_c(uint8_t *dst /* align 8 */, static void avg_no_rnd_vc1_chroma_mc4_c(uint8_t *dst /* align 8 */, uint8_t *src /* align 1 */, - int stride, int h, int x, int y) + ptrdiff_t stride, int h, int x, int y) { const int A = (8 - x) * (8 - y); const int B = ( x) * (8 - y); diff --git a/libavcodec/x86/h264_chromamc.asm b/libavcodec/x86/h264_chromamc.asm index 1447940857729..a9cac59f0fd0e 100644 --- a/libavcodec/x86/h264_chromamc.asm +++ b/libavcodec/x86/h264_chromamc.asm @@ -105,11 +105,8 @@ SECTION .text %endif ; rv40 ; void ff_put/avg_h264_chroma_mc8_*(uint8_t *dst /* align 8 */, ; uint8_t *src /* align 1 */, -; int stride, int h, int mx, int my) +; ptrdiff_t stride, int h, int mx, int my) cglobal %1_%2_chroma_mc8%3, 6, 7 + extra_regs, 0 -%if ARCH_X86_64 - movsxd r2, r2d -%endif mov r6d, r5d or r6d, r4d jne .at_least_one_non_zero @@ -291,9 +288,6 @@ cglobal %1_%2_chroma_mc8%3, 6, 7 + extra_regs, 0 %endif ; PIC %endif ; rv40 cglobal %1_%2_chroma_mc4, 6, 6 + extra_regs, 0 -%if ARCH_X86_64 - movsxd r2, r2d -%endif pxor m7, m7 movd m2, r4d ; x movd m3, r5d ; y @@ -376,10 +370,6 @@ cglobal %1_%2_chroma_mc4, 6, 6 + extra_regs, 0 %macro chroma_mc2_mmx_func 2 cglobal %1_%2_chroma_mc2, 6, 7, 0 -%if ARCH_X86_64 - movsxd r2, r2d -%endif - mov r6d, r4d shl r4d, 16 sub r4d, r6d @@ -465,9 +455,6 @@ chroma_mc4_mmx_func avg, rv40 %macro chroma_mc8_ssse3_func 2-3 cglobal %1_%2_chroma_mc8%3, 6, 7, 8 -%if ARCH_X86_64 - movsxd r2, r2d -%endif mov r6d, r5d or r6d, r4d jne .at_least_one_non_zero @@ -613,9 +600,6 @@ cglobal %1_%2_chroma_mc8%3, 6, 7, 8 %macro chroma_mc4_ssse3_func 2 cglobal %1_%2_chroma_mc4, 6, 7, 0 -%if ARCH_X86_64 - movsxd r2, r2d -%endif mov r6, r4 shl r4d, 8 sub r4d, r6d diff --git a/libavcodec/x86/h264_chromamc_10bit.asm b/libavcodec/x86/h264_chromamc_10bit.asm index 7b003515cc2b1..ff53b91c42e6c 100644 --- a/libavcodec/x86/h264_chromamc_10bit.asm +++ b/libavcodec/x86/h264_chromamc_10bit.asm @@ -57,12 +57,11 @@ SECTION .text %endmacro ;----------------------------------------------------------------------------- -; void ff_put/avg_h264_chroma_mc8(pixel *dst, pixel *src, int stride, int h, -; int mx, int my) +; void ff_put/avg_h264_chroma_mc8(pixel *dst, pixel *src, ptrdiff_t stride, +; int h, int mx, int my) ;----------------------------------------------------------------------------- %macro CHROMA_MC8 1 cglobal %1_h264_chroma_mc8_10, 6,7,8 - movsxdifnidn r2, r2d mov r6d, r5d or r6d, r4d jne .at_least_one_non_zero @@ -149,8 +148,8 @@ cglobal %1_h264_chroma_mc8_10, 6,7,8 %endmacro ;----------------------------------------------------------------------------- -; void ff_put/avg_h264_chroma_mc4(pixel *dst, pixel *src, int stride, int h, -; int mx, int my) +; void ff_put/avg_h264_chroma_mc4(pixel *dst, pixel *src, ptrdiff_t stride, +; int h, int mx, int my) ;----------------------------------------------------------------------------- ;TODO: xmm mc4 %macro MC4_OP 2 @@ -174,7 +173,6 @@ cglobal %1_h264_chroma_mc8_10, 6,7,8 %macro CHROMA_MC4 1 cglobal %1_h264_chroma_mc4_10, 6,6,7 - movsxdifnidn r2, r2d movd m2, r4m ; x movd m3, r5m ; y mova m4, [pw_8] @@ -200,12 +198,11 @@ cglobal %1_h264_chroma_mc4_10, 6,6,7 %endmacro ;----------------------------------------------------------------------------- -; void ff_put/avg_h264_chroma_mc2(pixel *dst, pixel *src, int stride, int h, -; int mx, int my) +; void ff_put/avg_h264_chroma_mc2(pixel *dst, pixel *src, ptrdiff_t stride, +; int h, int mx, int my) ;----------------------------------------------------------------------------- %macro CHROMA_MC2 1 cglobal %1_h264_chroma_mc2_10, 6,7 - movsxdifnidn r2, r2d mov r6d, r4d shl r4d, 16 sub r4d, r6d diff --git a/libavcodec/x86/h264chroma_init.c b/libavcodec/x86/h264chroma_init.c index 8ec8a79aba67f..0d5ff3d159fc8 100644 --- a/libavcodec/x86/h264chroma_init.c +++ b/libavcodec/x86/h264chroma_init.c @@ -25,38 +25,38 @@ #include "libavcodec/h264chroma.h" void ff_put_h264_chroma_mc8_rnd_mmx (uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); void ff_avg_h264_chroma_mc8_rnd_mmxext(uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); void ff_avg_h264_chroma_mc8_rnd_3dnow(uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); void ff_put_h264_chroma_mc4_mmx (uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); void ff_avg_h264_chroma_mc4_mmxext (uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); void ff_avg_h264_chroma_mc4_3dnow (uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); void ff_put_h264_chroma_mc2_mmxext (uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); void ff_avg_h264_chroma_mc2_mmxext (uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); void ff_put_h264_chroma_mc8_rnd_ssse3(uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); void ff_put_h264_chroma_mc4_ssse3 (uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); void ff_avg_h264_chroma_mc8_rnd_ssse3(uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); void ff_avg_h264_chroma_mc4_ssse3 (uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); #define CHROMA_MC(OP, NUM, DEPTH, OPT) \ void ff_ ## OP ## _h264_chroma_mc ## NUM ## _ ## DEPTH ## _ ## OPT \ (uint8_t *dst, uint8_t *src, \ - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); CHROMA_MC(put, 2, 10, mmxext) CHROMA_MC(avg, 2, 10, mmxext) diff --git a/libavcodec/x86/rv40dsp_init.c b/libavcodec/x86/rv40dsp_init.c index e006c76584cab..7bf3ecd1f3110 100644 --- a/libavcodec/x86/rv40dsp_init.c +++ b/libavcodec/x86/rv40dsp_init.c @@ -34,18 +34,18 @@ #if HAVE_YASM void ff_put_rv40_chroma_mc8_mmx (uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); void ff_avg_rv40_chroma_mc8_mmxext(uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); void ff_avg_rv40_chroma_mc8_3dnow(uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); void ff_put_rv40_chroma_mc4_mmx (uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); void ff_avg_rv40_chroma_mc4_mmxext(uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); void ff_avg_rv40_chroma_mc4_3dnow(uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); #define DECLARE_WEIGHT(opt) \ void ff_rv40_weight_func_rnd_16_##opt(uint8_t *dst, uint8_t *src1, uint8_t *src2, \ diff --git a/libavcodec/x86/vc1dsp_init.c b/libavcodec/x86/vc1dsp_init.c index aff4b264e3639..8982ff908af0b 100644 --- a/libavcodec/x86/vc1dsp_init.c +++ b/libavcodec/x86/vc1dsp_init.c @@ -71,15 +71,15 @@ static void avg_vc1_mspel_mc00_mmxext(uint8_t *dst, const uint8_t *src, #endif /* HAVE_YASM */ void ff_put_vc1_chroma_mc8_nornd_mmx (uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); void ff_avg_vc1_chroma_mc8_nornd_mmxext(uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); void ff_avg_vc1_chroma_mc8_nornd_3dnow(uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); void ff_put_vc1_chroma_mc8_nornd_ssse3(uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); void ff_avg_vc1_chroma_mc8_nornd_ssse3(uint8_t *dst, uint8_t *src, - int stride, int h, int x, int y); + ptrdiff_t stride, int h, int x, int y); av_cold void ff_vc1dsp_init_x86(VC1DSPContext *dsp) From ba479f3daafc7e4359ec1212164569ebe59f0bb7 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 1 Sep 2016 22:18:22 +0200 Subject: [PATCH 0204/3374] hevc: Change type of array stride parameters to ptrdiff_t ptrdiff_t is the correct type for array strides and similar. --- libavcodec/hevc.c | 12 ++++++------ libavcodec/hevc_filter.c | 4 ++-- libavcodec/hevcdsp_template.c | 36 +++++++++++++++++------------------ tests/checkasm/hevc_mc.c | 16 ++++++++-------- 4 files changed, 34 insertions(+), 34 deletions(-) diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c index 961991f403aa5..e38d36711e328 100644 --- a/libavcodec/hevc.c +++ b/libavcodec/hevc.c @@ -1437,11 +1437,11 @@ static int hls_pcm_sample(HEVCContext *s, int x0, int y0, int log2_cb_size) HEVCLocalContext *lc = &s->HEVClc; GetBitContext gb; int cb_size = 1 << log2_cb_size; - int stride0 = s->frame->linesize[0]; + ptrdiff_t stride0 = s->frame->linesize[0]; + ptrdiff_t stride1 = s->frame->linesize[1]; + ptrdiff_t stride2 = s->frame->linesize[2]; uint8_t *dst0 = &s->frame->data[0][y0 * stride0 + (x0 << s->ps.sps->pixel_shift)]; - int stride1 = s->frame->linesize[1]; uint8_t *dst1 = &s->frame->data[1][(y0 >> s->ps.sps->vshift[1]) * stride1 + ((x0 >> s->ps.sps->hshift[1]) << s->ps.sps->pixel_shift)]; - int stride2 = s->frame->linesize[2]; uint8_t *dst2 = &s->frame->data[2][(y0 >> s->ps.sps->vshift[2]) * stride2 + ((x0 >> s->ps.sps->hshift[2]) << s->ps.sps->pixel_shift)]; int length = cb_size * cb_size * s->ps.sps->pcm.bit_depth + ((cb_size * cb_size) >> 1) * s->ps.sps->pcm.bit_depth_chroma; @@ -1520,7 +1520,7 @@ static void luma_mc(HEVCContext *s, int16_t *dst, ptrdiff_t dststride, if (x_off < extra_left || y_off < extra_top || x_off >= pic_width - block_w - ff_hevc_qpel_extra_after[mx] || y_off >= pic_height - block_h - ff_hevc_qpel_extra_after[my]) { - const int edge_emu_stride = EDGE_EMU_BUFFER_STRIDE << s->ps.sps->pixel_shift; + const ptrdiff_t edge_emu_stride = EDGE_EMU_BUFFER_STRIDE << s->ps.sps->pixel_shift; int offset = extra_top * srcstride + (extra_left << s->ps.sps->pixel_shift); int buf_offset = extra_top * edge_emu_stride + (extra_left << s->ps.sps->pixel_shift); @@ -1575,7 +1575,7 @@ static void chroma_mc(HEVCContext *s, int16_t *dst1, int16_t *dst2, if (x_off < EPEL_EXTRA_BEFORE || y_off < EPEL_EXTRA_AFTER || x_off >= pic_width - block_w - EPEL_EXTRA_AFTER || y_off >= pic_height - block_h - EPEL_EXTRA_AFTER) { - const int edge_emu_stride = EDGE_EMU_BUFFER_STRIDE << s->ps.sps->pixel_shift; + const ptrdiff_t edge_emu_stride = EDGE_EMU_BUFFER_STRIDE << s->ps.sps->pixel_shift; int offset1 = EPEL_EXTRA_BEFORE * (src1stride + (1 << s->ps.sps->pixel_shift)); int buf_offset1 = EPEL_EXTRA_BEFORE * (edge_emu_stride + (1 << s->ps.sps->pixel_shift)); @@ -1687,7 +1687,7 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, RefPicList *refPicList = s->ref->refPicList; HEVCFrame *ref0, *ref1; - int tmpstride = MAX_PB_SIZE * sizeof(int16_t); + ptrdiff_t tmpstride = MAX_PB_SIZE * sizeof(int16_t); uint8_t *dst0 = POS(0, x0, y0); uint8_t *dst1 = POS(1, x0, y0); diff --git a/libavcodec/hevc_filter.c b/libavcodec/hevc_filter.c index 39ac4eef8e37a..5037dae7cdf0c 100644 --- a/libavcodec/hevc_filter.c +++ b/libavcodec/hevc_filter.c @@ -172,7 +172,7 @@ static int get_qPy(HEVCContext *s, int xC, int yC) } static void copy_CTB(uint8_t *dst, uint8_t *src, - int width, int height, int stride) + int width, int height, ptrdiff_t stride) { int i; @@ -273,7 +273,7 @@ static void sao_filter_CTB(HEVCContext *s, int x, int y) int chroma = c_idx ? 1 : 0; int x0 = x >> chroma; int y0 = y >> chroma; - int stride = s->frame->linesize[c_idx]; + ptrdiff_t stride = s->frame->linesize[c_idx]; int ctb_size = (1 << (s->ps.sps->log2_ctb_size)) >> s->ps.sps->hshift[c_idx]; int width = FFMIN(ctb_size, (s->ps.sps->width >> s->ps.sps->hshift[c_idx]) - x0); diff --git a/libavcodec/hevcdsp_template.c b/libavcodec/hevcdsp_template.c index 076b251344acb..cd55571290216 100644 --- a/libavcodec/hevcdsp_template.c +++ b/libavcodec/hevcdsp_template.c @@ -396,7 +396,7 @@ static void FUNC(sao_edge_filter_0)(uint8_t *_dst, uint8_t *_src, if (sao_eo_class != SAO_EO_VERT) { if (borders[0]) { int offset_val = sao_offset_val[0]; - int y_stride = 0; + ptrdiff_t y_stride = 0; for (y = 0; y < height; y++) { dst[y_stride] = av_clip_pixel(src[y_stride] + offset_val); y_stride += stride; @@ -405,7 +405,7 @@ static void FUNC(sao_edge_filter_0)(uint8_t *_dst, uint8_t *_src, } if (borders[2]) { int offset_val = sao_offset_val[0]; - int x_stride = width - 1; + ptrdiff_t x_stride = width - 1; for (x = 0; x < height; x++) { dst[x_stride] = av_clip_pixel(src[x_stride] + offset_val); x_stride += stride; @@ -422,21 +422,21 @@ static void FUNC(sao_edge_filter_0)(uint8_t *_dst, uint8_t *_src, } if (borders[3]) { int offset_val = sao_offset_val[0]; - int y_stride = stride * (height - 1); + ptrdiff_t y_stride = stride * (height - 1); for (x = init_x; x < width; x++) dst[x + y_stride] = av_clip_pixel(src[x + y_stride] + offset_val); height--; } } { - int y_stride = init_y * stride; + ptrdiff_t y_stride = init_y * stride; int pos_0_0 = pos[sao_eo_class][0][0]; int pos_0_1 = pos[sao_eo_class][0][1]; int pos_1_0 = pos[sao_eo_class][1][0]; int pos_1_1 = pos[sao_eo_class][1][1]; - int y_stride_0_1 = (init_y + pos_0_1) * stride; - int y_stride_1_1 = (init_y + pos_1_1) * stride; + ptrdiff_t y_stride_0_1 = (init_y + pos_0_1) * stride; + ptrdiff_t y_stride_1_1 = (init_y + pos_1_1) * stride; for (y = init_y; y < height; y++) { for (x = init_x; x < width; x++) { int diff0 = CMP(src[x + y_stride], src[x + pos_0_0 + y_stride_0_1]); @@ -503,7 +503,7 @@ static void FUNC(sao_edge_filter_1)(uint8_t *_dst, uint8_t *_src, if (sao_eo_class != SAO_EO_VERT) { if (borders[0]) { int offset_val = sao_offset_val[0]; - int y_stride = 0; + ptrdiff_t y_stride = 0; for (y = 0; y < height; y++) { dst[y_stride] = av_clip_pixel(src[y_stride] + offset_val); y_stride += stride; @@ -512,7 +512,7 @@ static void FUNC(sao_edge_filter_1)(uint8_t *_dst, uint8_t *_src, } if (borders[2]) { int offset_val = sao_offset_val[0]; - int x_stride = width - 1; + ptrdiff_t x_stride = width - 1; for (x = 0; x < height; x++) { dst[x_stride] = av_clip_pixel(src[x_stride] + offset_val); x_stride += stride; @@ -521,14 +521,14 @@ static void FUNC(sao_edge_filter_1)(uint8_t *_dst, uint8_t *_src, } } { - int y_stride = init_y * stride; + ptrdiff_t y_stride = init_y * stride; int pos_0_0 = pos[sao_eo_class][0][0]; int pos_0_1 = pos[sao_eo_class][0][1]; int pos_1_0 = pos[sao_eo_class][1][0]; int pos_1_1 = pos[sao_eo_class][1][1]; - int y_stride_0_1 = (init_y + pos_0_1) * stride; - int y_stride_1_1 = (init_y + pos_1_1) * stride; + ptrdiff_t y_stride_0_1 = (init_y + pos_0_1) * stride; + ptrdiff_t y_stride_1_1 = (init_y + pos_1_1) * stride; for (y = init_y; y < height; y++) { for (x = init_x; x < width; x++) { int diff0 = CMP(src[x + y_stride], src[x + pos_0_0 + y_stride_0_1]); @@ -601,21 +601,21 @@ static void FUNC(sao_edge_filter_2)(uint8_t *_dst, uint8_t *_src, } if (borders[3]) { int offset_val = sao_offset_val[0]; - int y_stride = stride * (height - 1); + ptrdiff_t y_stride = stride * (height - 1); for (x = init_x; x < width; x++) dst[x + y_stride] = av_clip_pixel(src[x + y_stride] + offset_val); height--; } } { - int y_stride = init_y * stride; + ptrdiff_t y_stride = init_y * stride; int pos_0_0 = pos[sao_eo_class][0][0]; int pos_0_1 = pos[sao_eo_class][0][1]; int pos_1_0 = pos[sao_eo_class][1][0]; int pos_1_1 = pos[sao_eo_class][1][1]; - int y_stride_0_1 = (init_y + pos_0_1) * stride; - int y_stride_1_1 = (init_y + pos_1_1) * stride; + ptrdiff_t y_stride_0_1 = (init_y + pos_0_1) * stride; + ptrdiff_t y_stride_1_1 = (init_y + pos_1_1) * stride; for (y = init_y; y < height; y++) { for (x = init_x; x < width; x++) { int diff0 = CMP(src[x + y_stride], src[x + pos_0_0 + y_stride_0_1]); @@ -681,14 +681,14 @@ static void FUNC(sao_edge_filter_3)(uint8_t *_dst, uint8_t *_src, init_y = init_x = 0; { - int y_stride = init_y * stride; + ptrdiff_t y_stride = init_y * stride; int pos_0_0 = pos[sao_eo_class][0][0]; int pos_0_1 = pos[sao_eo_class][0][1]; int pos_1_0 = pos[sao_eo_class][1][0]; int pos_1_1 = pos[sao_eo_class][1][1]; - int y_stride_0_1 = (init_y + pos_0_1) * stride; - int y_stride_1_1 = (init_y + pos_1_1) * stride; + ptrdiff_t y_stride_0_1 = (init_y + pos_0_1) * stride; + ptrdiff_t y_stride_1_1 = (init_y + pos_1_1) * stride; for (y = init_y; y < height; y++) { for (x = init_x; x < width; x++) { diff --git a/tests/checkasm/hevc_mc.c b/tests/checkasm/hevc_mc.c index 385c33eec7c50..70f35ce78a14a 100644 --- a/tests/checkasm/hevc_mc.c +++ b/tests/checkasm/hevc_mc.c @@ -105,8 +105,8 @@ static void check_unweighted_pred(HEVCDSPContext *h, uint8_t *dst0, uint8_t *dst for (i = 0; i < FF_ARRAY_ELEMS(pred_widths); i++) { const int width = pred_widths[i]; - const int srcstride = FFALIGN(width, 16) * sizeof(*src0); - const int dststride = FFALIGN(width, 16) * PIXEL_SIZE(bit_depth); + const ptrdiff_t srcstride = FFALIGN(width, 16) * sizeof(*src0); + const ptrdiff_t dststride = FFALIGN(width, 16) * PIXEL_SIZE(bit_depth); { declare_func(void, uint8_t *dst, ptrdiff_t dststride, int16_t *src, ptrdiff_t srcstride, int height); @@ -177,8 +177,8 @@ static void check_weighted_pred(HEVCDSPContext *h, uint8_t *dst0, uint8_t *dst1, for (i = 0; i < FF_ARRAY_ELEMS(pred_widths); i++) { const int width = pred_widths[i]; - const int srcstride = FFALIGN(width, 16) * sizeof(*src0); - const int dststride = FFALIGN(width, 16) * PIXEL_SIZE(bit_depth); + const ptrdiff_t srcstride = FFALIGN(width, 16) * sizeof(*src0); + const ptrdiff_t dststride = FFALIGN(width, 16) * PIXEL_SIZE(bit_depth); { declare_func(void, uint8_t denom, int16_t weight, int16_t offset, @@ -216,8 +216,8 @@ static void check_epel(HEVCDSPContext *h, int16_t *dst0, int16_t *dst1, for (j = 0; j < 2; j++) { for (k = 0; k < FF_ARRAY_ELEMS(h->put_hevc_epel[i][j]); k++) { int width = pred_widths[k] / 2; - int dststride = FFALIGN(width, 16) * sizeof(*dst0); - int srcstride = FFALIGN(width + 3, 8) * PIXEL_SIZE(bit_depth); + ptrdiff_t dststride = FFALIGN(width, 16) * sizeof(*dst0); + ptrdiff_t srcstride = FFALIGN(width + 3, 8) * PIXEL_SIZE(bit_depth); if (!check_func(h->put_hevc_epel[i][j][k], "epel_%s_%d_%d", interp_names[i][j], width, bit_depth)) continue; @@ -261,8 +261,8 @@ static void check_qpel(HEVCDSPContext *h, int16_t *dst0, int16_t *dst1, for (j = 0; j < 2; j++) { for (k = 0; k < FF_ARRAY_ELEMS(h->put_hevc_qpel[i][j]); k++) { int width = pred_widths[k]; - int dststride = FFALIGN(width, 16) * sizeof(*dst0); - int srcstride = FFALIGN(width + 7, 8) * PIXEL_SIZE(bit_depth); + ptrdiff_t dststride = FFALIGN(width, 16) * sizeof(*dst0); + ptrdiff_t srcstride = FFALIGN(width + 7, 8) * PIXEL_SIZE(bit_depth); if (!check_func(h->put_hevc_qpel[i][j][k], "qpel_%s_%d_%d", interp_names[i][j], width, bit_depth)) continue; From a339e919cad1ab0125948f0dd9d49f6cb590db89 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 7 Sep 2016 17:08:15 +0200 Subject: [PATCH 0205/3374] ea: Change type of array stride parameters to ptrdiff_t ptrdiff_t is the correct type for array strides and similar. --- libavcodec/eacmv.c | 4 ++-- libavcodec/eaidct.c | 3 ++- libavcodec/eaidct.h | 3 ++- libavcodec/eamad.c | 4 ++-- libavcodec/eatgq.c | 6 +++--- libavcodec/eatgv.c | 2 +- libavcodec/eatqi.c | 2 +- 7 files changed, 13 insertions(+), 11 deletions(-) diff --git a/libavcodec/eacmv.c b/libavcodec/eacmv.c index 9668f64fbf84b..633c26ae141e5 100644 --- a/libavcodec/eacmv.c +++ b/libavcodec/eacmv.c @@ -71,8 +71,8 @@ static void cmv_decode_intra(CmvContext * s, AVFrame *frame, } } -static void cmv_motcomp(unsigned char *dst, int dst_stride, - const unsigned char *src, int src_stride, +static void cmv_motcomp(unsigned char *dst, ptrdiff_t dst_stride, + const unsigned char *src, ptrdiff_t src_stride, int x, int y, int xoffset, int yoffset, int width, int height){ diff --git a/libavcodec/eaidct.c b/libavcodec/eaidct.c index 5b2db44affa0c..271e28cb9a6a7 100644 --- a/libavcodec/eaidct.c +++ b/libavcodec/eaidct.c @@ -77,7 +77,8 @@ static inline void ea_idct_col(int16_t *dest, const int16_t *src) { IDCT_COL(dest, src); } -void ff_ea_idct_put_c(uint8_t *dest, int linesize, int16_t *block) { +void ff_ea_idct_put_c(uint8_t *dest, ptrdiff_t linesize, int16_t *block) +{ int i; int16_t temp[64]; block[0] += 4; diff --git a/libavcodec/eaidct.h b/libavcodec/eaidct.h index e78de0417875a..395a8aefba3a2 100644 --- a/libavcodec/eaidct.h +++ b/libavcodec/eaidct.h @@ -19,8 +19,9 @@ #ifndef AVCODEC_EAIDCT_H #define AVCODEC_EAIDCT_H +#include #include -void ff_ea_idct_put_c(uint8_t *dest, int linesize, int16_t *block); +void ff_ea_idct_put_c(uint8_t *dest, ptrdiff_t linesize, int16_t *block); #endif /* AVCODEC_EAIDCT_H */ diff --git a/libavcodec/eamad.c b/libavcodec/eamad.c index 3e8d4fdd8872f..070cfdb35507f 100644 --- a/libavcodec/eamad.c +++ b/libavcodec/eamad.c @@ -80,8 +80,8 @@ static av_cold int decode_init(AVCodecContext *avctx) return 0; } -static inline void comp(unsigned char *dst, int dst_stride, - unsigned char *src, int src_stride, int add) +static inline void comp(unsigned char *dst, ptrdiff_t dst_stride, + unsigned char *src, ptrdiff_t src_stride, int add) { int j, i; for (j=0; j<8; j++) diff --git a/libavcodec/eatgq.c b/libavcodec/eatgq.c index ff0aa558f57d7..835547125e2ef 100644 --- a/libavcodec/eatgq.c +++ b/libavcodec/eatgq.c @@ -107,7 +107,7 @@ static void tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb static void tgq_idct_put_mb(TgqContext *s, int16_t (*block)[64], AVFrame *frame, int mb_x, int mb_y) { - int linesize = frame->linesize[0]; + ptrdiff_t linesize = frame->linesize[0]; uint8_t *dest_y = frame->data[0] + (mb_y * 16 * linesize) + mb_x * 16; uint8_t *dest_cb = frame->data[1] + (mb_y * 8 * frame->linesize[1]) + mb_x * 8; uint8_t *dest_cr = frame->data[2] + (mb_y * 8 * frame->linesize[2]) + mb_x * 8; @@ -123,7 +123,7 @@ static void tgq_idct_put_mb(TgqContext *s, int16_t (*block)[64], AVFrame *frame, } static inline void tgq_dconly(TgqContext *s, unsigned char *dst, - int dst_stride, int dc) + ptrdiff_t dst_stride, int dc) { int level = av_clip_uint8((dc*s->qtable[0] + 2056) >> 4); int j; @@ -134,7 +134,7 @@ static inline void tgq_dconly(TgqContext *s, unsigned char *dst, static void tgq_idct_put_mb_dconly(TgqContext *s, AVFrame *frame, int mb_x, int mb_y, const int8_t *dc) { - int linesize = frame->linesize[0]; + ptrdiff_t linesize = frame->linesize[0]; uint8_t *dest_y = frame->data[0] + (mb_y * 16 * linesize) + mb_x * 16; uint8_t *dest_cb = frame->data[1] + (mb_y * 8 * frame->linesize[1]) + mb_x * 8; uint8_t *dest_cr = frame->data[2] + (mb_y * 8 * frame->linesize[2]) + mb_x * 8; diff --git a/libavcodec/eatgv.c b/libavcodec/eatgv.c index 7f40f45618fd5..7a50d010d4ef1 100644 --- a/libavcodec/eatgv.c +++ b/libavcodec/eatgv.c @@ -225,7 +225,7 @@ static int tgv_decode_inter(TgvContext *s, AVFrame *frame, for (x = 0; x < s->avctx->width / 4; x++) { unsigned int vector = get_bits(&gb, vector_bits); const uint8_t *src; - int src_stride; + ptrdiff_t src_stride; if (vector < num_mvs) { int mx = x * 4 + s->mv_codebook[vector][0]; diff --git a/libavcodec/eatqi.c b/libavcodec/eatqi.c index f4cad9ceeae24..cb70cda7fedbf 100644 --- a/libavcodec/eatqi.c +++ b/libavcodec/eatqi.c @@ -90,7 +90,7 @@ static inline void tqi_idct_put(AVCodecContext *avctx, AVFrame *frame, int16_t (*block)[64]) { TqiContext *t = avctx->priv_data; - int linesize = frame->linesize[0]; + ptrdiff_t linesize = frame->linesize[0]; uint8_t *dest_y = frame->data[0] + t->mb_y * 16 * linesize + t->mb_x * 16; uint8_t *dest_cb = frame->data[1] + t->mb_y * 8 * frame->linesize[1] + t->mb_x * 8; uint8_t *dest_cr = frame->data[2] + t->mb_y * 8 * frame->linesize[2] + t->mb_x * 8; From 15b4f494fc6bddb8178fdb5aed18b420efc75e22 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 8 Sep 2016 16:03:46 +0200 Subject: [PATCH 0206/3374] mss*: Change type of array stride parameters to ptrdiff_t ptrdiff_t is the correct type for array strides and similar. --- libavcodec/mss12.c | 15 ++++++++------- libavcodec/mss12.h | 6 +++--- libavcodec/mss2.c | 6 +++--- libavcodec/mss2dsp.c | 28 ++++++++++++++-------------- libavcodec/mss2dsp.h | 22 ++++++++++++---------- libavcodec/mss3.c | 12 ++++++------ libavcodec/mss34dsp.c | 2 +- libavcodec/mss34dsp.h | 3 ++- libavcodec/mss4.c | 2 +- 9 files changed, 50 insertions(+), 46 deletions(-) diff --git a/libavcodec/mss12.c b/libavcodec/mss12.c index b9bda16766166..8735b85863749 100644 --- a/libavcodec/mss12.c +++ b/libavcodec/mss12.c @@ -197,7 +197,7 @@ static av_always_inline int decode_pixel(ArithCoder *acoder, PixContext *pctx, } static int decode_pixel_in_context(ArithCoder *acoder, PixContext *pctx, - uint8_t *src, int stride, int x, int y, + uint8_t *src, ptrdiff_t stride, int x, int y, int has_right) { uint8_t neighbours[4]; @@ -290,8 +290,9 @@ static int decode_pixel_in_context(ArithCoder *acoder, PixContext *pctx, } static int decode_region(ArithCoder *acoder, uint8_t *dst, uint8_t *rgb_pic, - int x, int y, int width, int height, int stride, - int rgb_stride, PixContext *pctx, const uint32_t *pal) + int x, int y, int width, int height, ptrdiff_t stride, + ptrdiff_t rgb_stride, PixContext *pctx, + const uint32_t *pal) { int i, j, p; uint8_t *rgb_dst = rgb_pic + x * 3 + y * rgb_stride; @@ -368,8 +369,8 @@ static int motion_compensation(MSS12Context const *c, } static int decode_region_masked(MSS12Context const *c, ArithCoder *acoder, - uint8_t *dst, int stride, uint8_t *mask, - int mask_stride, int x, int y, + uint8_t *dst, ptrdiff_t stride, uint8_t *mask, + ptrdiff_t mask_stride, int x, int y, int width, int height, PixContext *pctx) { @@ -466,8 +467,8 @@ static int decode_region_intra(SliceContext *sc, ArithCoder *acoder, if (!mode) { int i, j, pix, rgb_pix; - int stride = c->pal_stride; - int rgb_stride = c->rgb_stride; + ptrdiff_t stride = c->pal_stride; + ptrdiff_t rgb_stride = c->rgb_stride; uint8_t *dst = c->pal_pic + x + y * stride; uint8_t *rgb_dst = c->rgb_pic + x * 3 + y * rgb_stride; diff --git a/libavcodec/mss12.h b/libavcodec/mss12.h index 5b1fee8913e2d..8cad5dcedc5c9 100644 --- a/libavcodec/mss12.h +++ b/libavcodec/mss12.h @@ -77,12 +77,12 @@ typedef struct MSS12Context { uint32_t pal[256]; uint8_t *pal_pic; uint8_t *last_pal_pic; - int pal_stride; + ptrdiff_t pal_stride; uint8_t *mask; - int mask_stride; + ptrdiff_t mask_stride; uint8_t *rgb_pic; uint8_t *last_rgb_pic; - int rgb_stride; + ptrdiff_t rgb_stride; int free_colours; int keyframe; int mvX, mvY; diff --git a/libavcodec/mss2.c b/libavcodec/mss2.c index 866ce478dd56d..355bb32e1bba3 100644 --- a/libavcodec/mss2.c +++ b/libavcodec/mss2.c @@ -174,7 +174,7 @@ static int decode_pal_v2(MSS12Context *ctx, const uint8_t *buf, int buf_size) return 1 + ncol * 3; } -static int decode_555(GetByteContext *gB, uint16_t *dst, int stride, +static int decode_555(GetByteContext *gB, uint16_t *dst, ptrdiff_t stride, int keyframe, int w, int h) { int last_symbol = 0, repeat = 0, prev_avail = 0; @@ -232,8 +232,8 @@ static int decode_555(GetByteContext *gB, uint16_t *dst, int stride, return 0; } -static int decode_rle(GetBitContext *gb, uint8_t *pal_dst, int pal_stride, - uint8_t *rgb_dst, int rgb_stride, uint32_t *pal, +static int decode_rle(GetBitContext *gb, uint8_t *pal_dst, ptrdiff_t pal_stride, + uint8_t *rgb_dst, ptrdiff_t rgb_stride, uint32_t *pal, int keyframe, int kf_slipt, int slice, int w, int h) { uint8_t bits[270] = { 0 }; diff --git a/libavcodec/mss2dsp.c b/libavcodec/mss2dsp.c index aa13577d4861d..4de4dbac991d2 100644 --- a/libavcodec/mss2dsp.c +++ b/libavcodec/mss2dsp.c @@ -27,17 +27,17 @@ #include "libavutil/common.h" static av_always_inline void mss2_blit_wmv9_template(uint8_t *dst, - int dst_stride, + ptrdiff_t dst_stride, int gray, int use_mask, int maskcolor, const uint8_t *mask, - int mask_stride, + ptrdiff_t mask_stride, const uint8_t *srcy, - int srcy_stride, + ptrdiff_t srcy_stride, const uint8_t *srcu, const uint8_t *srcv, - int srcuv_stride, + ptrdiff_t srcuv_stride, int w, int h) { int i, j, k, r = -1; @@ -64,10 +64,10 @@ static av_always_inline void mss2_blit_wmv9_template(uint8_t *dst, } } -static void mss2_blit_wmv9_c(uint8_t *dst, int dst_stride, - const uint8_t *srcy, int srcy_stride, +static void mss2_blit_wmv9_c(uint8_t *dst, ptrdiff_t dst_stride, + const uint8_t *srcy, ptrdiff_t srcy_stride, const uint8_t *srcu, const uint8_t *srcv, - int srcuv_stride, int w, int h) + ptrdiff_t srcuv_stride, int w, int h) { mss2_blit_wmv9_template(dst, dst_stride, 0, 0, 0, NULL, 0, @@ -76,12 +76,12 @@ static void mss2_blit_wmv9_c(uint8_t *dst, int dst_stride, w, h); } -static void mss2_blit_wmv9_masked_c(uint8_t *dst, int dst_stride, +static void mss2_blit_wmv9_masked_c(uint8_t *dst, ptrdiff_t dst_stride, int maskcolor, const uint8_t *mask, - int mask_stride, - const uint8_t *srcy, int srcy_stride, + ptrdiff_t mask_stride, + const uint8_t *srcy, ptrdiff_t srcy_stride, const uint8_t *srcu, const uint8_t *srcv, - int srcuv_stride, int w, int h) + ptrdiff_t srcuv_stride, int w, int h) { mss2_blit_wmv9_template(dst, dst_stride, 0, 1, maskcolor, mask, mask_stride, @@ -90,9 +90,9 @@ static void mss2_blit_wmv9_masked_c(uint8_t *dst, int dst_stride, w, h); } -static void mss2_gray_fill_masked_c(uint8_t *dst, int dst_stride, +static void mss2_gray_fill_masked_c(uint8_t *dst, ptrdiff_t dst_stride, int maskcolor, const uint8_t *mask, - int mask_stride, int w, int h) + ptrdiff_t mask_stride, int w, int h) { mss2_blit_wmv9_template(dst, dst_stride, 1, 1, maskcolor, mask, mask_stride, @@ -101,7 +101,7 @@ static void mss2_gray_fill_masked_c(uint8_t *dst, int dst_stride, w, h); } -static void upsample_plane_c(uint8_t *plane, int plane_stride, int w, int h) +static void upsample_plane_c(uint8_t *plane, ptrdiff_t plane_stride, int w, int h) { uint8_t *src1, *src2, *dst1, *dst2, *p, a, b; int i, j; diff --git a/libavcodec/mss2dsp.h b/libavcodec/mss2dsp.h index 61c3a04fcd31c..352b851ca8486 100644 --- a/libavcodec/mss2dsp.h +++ b/libavcodec/mss2dsp.h @@ -26,23 +26,25 @@ #ifndef AVCODEC_MSS2DSP_H #define AVCODEC_MSS2DSP_H +#include #include typedef struct MSS2DSPContext { - void (*mss2_blit_wmv9)(uint8_t *dst, int dst_stride, - const uint8_t *srcy, int srcy_stride, + void (*mss2_blit_wmv9)(uint8_t *dst, ptrdiff_t dst_stride, + const uint8_t *srcy, ptrdiff_t srcy_stride, const uint8_t *srcu, const uint8_t *srcv, - int srcuv_stride, int w, int h); - void (*mss2_blit_wmv9_masked)(uint8_t *dst, int dst_stride, + ptrdiff_t srcuv_stride, int w, int h); + void (*mss2_blit_wmv9_masked)(uint8_t *dst, ptrdiff_t dst_stride, int maskcolor, const uint8_t *mask, - int mask_stride, - const uint8_t *srcy, int srcy_stride, + ptrdiff_t mask_stride, + const uint8_t *srcy, ptrdiff_t srcy_stride, const uint8_t *srcu, const uint8_t *srcv, - int srcuv_stride, int w, int h); - void (*mss2_gray_fill_masked)(uint8_t *dst, int dst_stride, + ptrdiff_t srcuv_stride, int w, int h); + void (*mss2_gray_fill_masked)(uint8_t *dst, ptrdiff_t dst_stride, int maskcolor, const uint8_t *mask, - int mask_stride, int w, int h); - void (*upsample_plane)(uint8_t *plane, int plane_stride, int w, int h); + ptrdiff_t mask_stride, int w, int h); + void (*upsample_plane)(uint8_t *plane, ptrdiff_t plane_stride, + int w, int h); } MSS2DSPContext; void ff_mss2dsp_init(MSS2DSPContext *dsp); diff --git a/libavcodec/mss3.c b/libavcodec/mss3.c index c124834036b30..6a9731b58b047 100644 --- a/libavcodec/mss3.c +++ b/libavcodec/mss3.c @@ -91,7 +91,7 @@ typedef struct ImageBlockCoder { typedef struct DCTBlockCoder { int *prev_dc; - int prev_dc_stride; + ptrdiff_t prev_dc_stride; int prev_dc_height; int quality; uint16_t qmat[64]; @@ -450,7 +450,7 @@ static int decode_coeff(RangeCoder *c, Model *m) } static void decode_fill_block(RangeCoder *c, FillBlockCoder *fc, - uint8_t *dst, int stride, int block_size) + uint8_t *dst, ptrdiff_t stride, int block_size) { int i; @@ -461,7 +461,7 @@ static void decode_fill_block(RangeCoder *c, FillBlockCoder *fc, } static void decode_image_block(RangeCoder *c, ImageBlockCoder *ic, - uint8_t *dst, int stride, int block_size) + uint8_t *dst, ptrdiff_t stride, int block_size) { int i, j; int vec_size; @@ -557,7 +557,7 @@ static int decode_dct(RangeCoder *c, DCTBlockCoder *bc, int *block, } static void decode_dct_block(RangeCoder *c, DCTBlockCoder *bc, - uint8_t *dst, int stride, int block_size, + uint8_t *dst, ptrdiff_t stride, int block_size, int *block, int mb_x, int mb_y) { int i, j; @@ -580,8 +580,8 @@ static void decode_dct_block(RangeCoder *c, DCTBlockCoder *bc, } static void decode_haar_block(RangeCoder *c, HaarBlockCoder *hc, - uint8_t *dst, int stride, int block_size, - int *block) + uint8_t *dst, ptrdiff_t stride, + int block_size, int *block) { const int hsize = block_size >> 1; int A, B, C, D, t1, t2, t3, t4; diff --git a/libavcodec/mss34dsp.c b/libavcodec/mss34dsp.c index 11abb2de11ad5..dc7967623020a 100644 --- a/libavcodec/mss34dsp.c +++ b/libavcodec/mss34dsp.c @@ -87,7 +87,7 @@ void ff_mss34_gen_quant_mat(uint16_t *qmat, int quality, int luma) #define SOP_ROW(a) ((a) << 16) + 0x2000 #define SOP_COL(a) ((a + 32) << 16) -void ff_mss34_dct_put(uint8_t *dst, int stride, int *block) +void ff_mss34_dct_put(uint8_t *dst, ptrdiff_t stride, int *block) { int i, j; int *ptr; diff --git a/libavcodec/mss34dsp.h b/libavcodec/mss34dsp.h index b2cc5501ecfac..cec82474d71ad 100644 --- a/libavcodec/mss34dsp.h +++ b/libavcodec/mss34dsp.h @@ -22,6 +22,7 @@ #ifndef AVCODEC_MSS34DSP_H #define AVCODEC_MSS34DSP_H +#include #include /** @@ -40,6 +41,6 @@ void ff_mss34_gen_quant_mat(uint16_t *qmat, int quality, int luma); * @param stride output plane stride * @param block block to transform and output */ -void ff_mss34_dct_put(uint8_t *dst, int stride, int *block); +void ff_mss34_dct_put(uint8_t *dst, ptrdiff_t stride, int *block); #endif /* AVCODEC_MSS34DSP_H */ diff --git a/libavcodec/mss4.c b/libavcodec/mss4.c index a953a5759d0c4..073e0e2da012c 100644 --- a/libavcodec/mss4.c +++ b/libavcodec/mss4.c @@ -136,7 +136,7 @@ typedef struct MSS4Context { uint16_t quant_mat[2][64]; int *prev_dc[3]; - int dc_stride[3]; + ptrdiff_t dc_stride[3]; int dc_cache[4][4]; int prev_vec[3][4]; From 2caa93b813adc5dbb7771dfe615da826a2947d18 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 20 Sep 2016 14:09:43 +0200 Subject: [PATCH 0207/3374] mpegaudiodsp: Change type of array stride parameters to ptrdiff_t This avoids SIMD-optimized functions having to sign-extend their stride argument manually to be able to do pointer arithmetic. --- libavcodec/aarch64/mpegaudiodsp_neon.S | 1 - libavcodec/mpegaudiodsp.h | 16 ++++++++++------ libavcodec/mpegaudiodsp_template.c | 4 ++-- libavcodec/ppc/mpegaudiodsp_altivec.c | 2 +- libavcodec/x86/mpegaudiodsp.c | 2 +- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/libavcodec/aarch64/mpegaudiodsp_neon.S b/libavcodec/aarch64/mpegaudiodsp_neon.S index c1edc64135f18..34181d97daa9a 100644 --- a/libavcodec/aarch64/mpegaudiodsp_neon.S +++ b/libavcodec/aarch64/mpegaudiodsp_neon.S @@ -34,7 +34,6 @@ endconst .macro apply_window type, st function ff_mpadsp_apply_window_\type\()_neon, export=1 mov x7, x0 - sxtw x4, w4 // incr add x8, x0, #512<<2 ld1 {v0.4s,v1.4s,v2.4s,v3.4s}, [x7], #64 ld1 {v4.4s,v5.4s,v6.4s,v7.4s}, [x7], #64 diff --git a/libavcodec/mpegaudiodsp.h b/libavcodec/mpegaudiodsp.h index 909c65295113d..e0e872f3b9a24 100644 --- a/libavcodec/mpegaudiodsp.h +++ b/libavcodec/mpegaudiodsp.h @@ -19,14 +19,18 @@ #ifndef AVCODEC_MPEGAUDIODSP_H #define AVCODEC_MPEGAUDIODSP_H +#include #include + #include "libavutil/common.h" typedef struct MPADSPContext { void (*apply_window_float)(float *synth_buf, float *window, - int *dither_state, float *samples, int incr); + int *dither_state, float *samples, + ptrdiff_t incr); void (*apply_window_fixed)(int32_t *synth_buf, int32_t *window, - int *dither_state, int16_t *samples, int incr); + int *dither_state, int16_t *samples, + ptrdiff_t incr); void (*dct32_float)(float *dst, const float *src); void (*dct32_fixed)(int *dst, const int *src); void (*imdct36_blocks_float)(float *out, float *buf, float *in, @@ -45,13 +49,13 @@ extern const int32_t ff_mpa_enwindow[257]; void ff_mpa_synth_filter_fixed(MPADSPContext *s, int32_t *synth_buf_ptr, int *synth_buf_offset, int32_t *window, int *dither_state, - int16_t *samples, int incr, + int16_t *samples, ptrdiff_t incr, int32_t *sb_samples); void ff_mpa_synth_filter_float(MPADSPContext *s, float *synth_buf_ptr, int *synth_buf_offset, float *window, int *dither_state, - float *samples, int incr, + float *samples, ptrdiff_t incr, float *sb_samples); void ff_mpadsp_init_aarch64(MPADSPContext *s); @@ -64,10 +68,10 @@ void ff_mpa_synth_init_fixed(int32_t *window); void ff_mpadsp_apply_window_float(float *synth_buf, float *window, int *dither_state, float *samples, - int incr); + ptrdiff_t incr); void ff_mpadsp_apply_window_fixed(int32_t *synth_buf, int32_t *window, int *dither_state, int16_t *samples, - int incr); + ptrdiff_t incr); void ff_imdct36_blocks_float(float *out, float *buf, float *in, int count, int switch_point, int block_type); diff --git a/libavcodec/mpegaudiodsp_template.c b/libavcodec/mpegaudiodsp_template.c index 621bbd4ebac70..b8836c9af781b 100644 --- a/libavcodec/mpegaudiodsp_template.c +++ b/libavcodec/mpegaudiodsp_template.c @@ -120,7 +120,7 @@ DECLARE_ALIGNED(16, MPA_INT, RENAME(ff_mpa_synth_window))[512+256]; void RENAME(ff_mpadsp_apply_window)(MPA_INT *synth_buf, MPA_INT *window, int *dither_state, OUT_INT *samples, - int incr) + ptrdiff_t incr) { register const MPA_INT *w, *w2, *p; int j; @@ -176,7 +176,7 @@ void RENAME(ff_mpadsp_apply_window)(MPA_INT *synth_buf, MPA_INT *window, void RENAME(ff_mpa_synth_filter)(MPADSPContext *s, MPA_INT *synth_buf_ptr, int *synth_buf_offset, MPA_INT *window, int *dither_state, - OUT_INT *samples, int incr, + OUT_INT *samples, ptrdiff_t incr, MPA_INT *sb_samples) { MPA_INT *synth_buf; diff --git a/libavcodec/ppc/mpegaudiodsp_altivec.c b/libavcodec/ppc/mpegaudiodsp_altivec.c index b3d3ed4a3e32c..4c07131ae276a 100644 --- a/libavcodec/ppc/mpegaudiodsp_altivec.c +++ b/libavcodec/ppc/mpegaudiodsp_altivec.c @@ -90,7 +90,7 @@ static void apply_window(const float *buf, const float *win1, } static void apply_window_mp3(float *in, float *win, int *unused, float *out, - int incr) + ptrdiff_t incr) { LOCAL_ALIGNED_16(float, suma, [17]); LOCAL_ALIGNED_16(float, sumb, [17]); diff --git a/libavcodec/x86/mpegaudiodsp.c b/libavcodec/x86/mpegaudiodsp.c index 533b4a7c3fb67..591f5270bdd02 100644 --- a/libavcodec/x86/mpegaudiodsp.c +++ b/libavcodec/x86/mpegaudiodsp.c @@ -100,7 +100,7 @@ static void apply_window(const float *buf, const float *win1, } static void apply_window_mp3(float *in, float *win, int *unused, float *out, - int incr) + ptrdiff_t incr) { LOCAL_ALIGNED_16(float, suma, [17]); LOCAL_ALIGNED_16(float, sumb, [17]); From 8d1267932ca9c2e343ef303349101bab6681d02e Mon Sep 17 00:00:00 2001 From: Hendrik Leppkes Date: Fri, 23 Sep 2016 09:52:48 +0200 Subject: [PATCH 0208/3374] x86/h264_weight: use appropriate register size for weight parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes decoding corruption on 64 bit windows. Signed-off-by: Martin Storsjö --- libavcodec/x86/h264_weight.asm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libavcodec/x86/h264_weight.asm b/libavcodec/x86/h264_weight.asm index 9ad26de832c2f..e421ec8fbe783 100644 --- a/libavcodec/x86/h264_weight.asm +++ b/libavcodec/x86/h264_weight.asm @@ -134,16 +134,16 @@ WEIGHT_FUNC_HALF_MM 8, 8 mov off_regd, r7m add off_regd, 1 or off_regd, 1 - add r4, 1 - cmp r6d, 128 + add r4d, 1 + cmp r6d, 128 je .nonnormal - cmp r5, 128 + cmp r5d, 128 jne .normal .nonnormal - sar r5, 1 - sar r6, 1 + sar r5d, 1 + sar r6d, 1 sar off_regd, 1 - sub r4, 1 + sub r4d, 1 .normal %if cpuflag(ssse3) movd m4, r5d From 83548fe894cdb455cc127f754d09905b6d23c173 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 27 Sep 2016 16:26:37 +0200 Subject: [PATCH 0209/3374] lavf: fix usage of AVIOContext.seekable It is supposed to be a flag. The only currently defined value is AVIO_SEEKABLE_NORMAL, but other ones may be added in the future. However all the current lavf code treats this field as a bool (mainly for historical reasons). Change all those cases to properly check for AVIO_SEEKABLE_NORMAL. --- libavformat/aiffdec.c | 2 +- libavformat/aiffenc.c | 2 +- libavformat/ape.c | 2 +- libavformat/apetag.c | 2 +- libavformat/asfdec.c | 8 +++++--- libavformat/asfenc.c | 4 ++-- libavformat/au.c | 2 +- libavformat/avidec.c | 5 +++-- libavformat/avienc.c | 18 +++++++++--------- libavformat/aviobuf.c | 2 +- libavformat/bink.c | 2 +- libavformat/cafdec.c | 4 ++-- libavformat/filmstripdec.c | 2 +- libavformat/flacenc.c | 2 +- libavformat/flvdec.c | 3 ++- libavformat/gxfenc.c | 2 +- libavformat/id3v1.c | 2 +- libavformat/matroskadec.c | 2 +- libavformat/matroskaenc.c | 14 +++++++------- libavformat/mmf.c | 2 +- libavformat/mov.c | 12 ++++++------ libavformat/movenc.c | 2 +- libavformat/mp3enc.c | 2 +- libavformat/mpc.c | 2 +- libavformat/mpc8.c | 2 +- libavformat/mpeg.c | 2 +- libavformat/mpegts.c | 3 ++- libavformat/mvdec.c | 4 ++-- libavformat/mxfdec.c | 4 ++-- libavformat/mxfenc.c | 2 +- libavformat/nutdec.c | 2 +- libavformat/oggdec.c | 2 +- libavformat/r3d.c | 2 +- libavformat/rmdec.c | 3 ++- libavformat/rmenc.c | 6 +++--- libavformat/rsoenc.c | 2 +- libavformat/smjpegenc.c | 2 +- libavformat/soxenc.c | 2 +- libavformat/swfenc.c | 2 +- libavformat/takdec.c | 2 +- libavformat/tty.c | 2 +- libavformat/utils.c | 2 +- libavformat/vc1testenc.c | 2 +- libavformat/voc_packet.c | 2 +- libavformat/wavdec.c | 2 +- libavformat/wavenc.c | 4 ++-- libavformat/wvdec.c | 4 ++-- libavformat/wvenc.c | 2 +- 48 files changed, 84 insertions(+), 78 deletions(-) diff --git a/libavformat/aiffdec.c b/libavformat/aiffdec.c index 3c45c61b1a8c8..481a92d351c8c 100644 --- a/libavformat/aiffdec.c +++ b/libavformat/aiffdec.c @@ -251,7 +251,7 @@ static int aiff_read_header(AVFormatContext *s) offset += avio_tell(pb); /* Compute absolute data offset */ if (st->codecpar->block_align) /* Assume COMM already parsed */ goto got_sound; - if (!pb->seekable) { + if (!(pb->seekable & AVIO_SEEKABLE_NORMAL)) { av_log(s, AV_LOG_ERROR, "file is not seekable\n"); return -1; } diff --git a/libavformat/aiffenc.c b/libavformat/aiffenc.c index 6449c00cada7d..191e746672fad 100644 --- a/libavformat/aiffenc.c +++ b/libavformat/aiffenc.c @@ -129,7 +129,7 @@ static int aiff_write_trailer(AVFormatContext *s) end_size++; } - if (s->pb->seekable) { + if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) { /* File length */ avio_seek(pb, aiff->form, SEEK_SET); avio_wb32(pb, file_size - aiff->form - 4); diff --git a/libavformat/ape.c b/libavformat/ape.c index bcc1f7aa0786d..80e337240378c 100644 --- a/libavformat/ape.c +++ b/libavformat/ape.c @@ -370,7 +370,7 @@ static int ape_read_header(AVFormatContext * s) } /* try to read APE tags */ - if (pb->seekable) { + if (pb->seekable & AVIO_SEEKABLE_NORMAL) { ff_ape_parse_tag(s); avio_seek(pb, 0, SEEK_SET); } diff --git a/libavformat/apetag.c b/libavformat/apetag.c index 044bfd8022ee7..05430dd9bcc3f 100644 --- a/libavformat/apetag.c +++ b/libavformat/apetag.c @@ -182,7 +182,7 @@ int ff_ape_write_tag(AVFormatContext *s) int64_t start, end; int size, count = 0; - if (!s->pb->seekable) + if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) return 0; start = avio_tell(s->pb); diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index 7d717890295b8..1c50ad627c3b4 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -960,7 +960,7 @@ static int asf_read_data(AVFormatContext *s, const GUIDParseTable *g) size, asf->nb_packets); avio_skip(pb, 2); // skip reserved field asf->first_packet_offset = avio_tell(pb); - if (pb->seekable && !(asf->b_flags & ASF_FLAG_BROADCAST)) + if ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !(asf->b_flags & ASF_FLAG_BROADCAST)) align_position(pb, asf->offset, asf->data_size); return 0; @@ -1738,7 +1738,9 @@ static int asf_read_header(AVFormatContext *s) size = avio_rl64(pb); align_position(pb, asf->offset, size); } - if (asf->data_reached && (!pb->seekable || (asf->b_flags & ASF_FLAG_BROADCAST))) + if (asf->data_reached && + (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || + (asf->b_flags & ASF_FLAG_BROADCAST))) break; } @@ -1747,7 +1749,7 @@ static int asf_read_header(AVFormatContext *s) ret = AVERROR_INVALIDDATA; goto failed; } - if (pb->seekable) + if (pb->seekable & AVIO_SEEKABLE_NORMAL) avio_seek(pb, asf->first_packet_offset, SEEK_SET); for (i = 0; i < asf->nb_streams; i++) { diff --git a/libavformat/asfenc.c b/libavformat/asfenc.c index dc1dd73364af1..a40c02d00d2a0 100644 --- a/libavformat/asfenc.c +++ b/libavformat/asfenc.c @@ -433,7 +433,7 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, avio_wl64(pb, play_duration); /* end time stamp (in 100ns units) */ avio_wl64(pb, send_duration); /* duration (in 100ns units) */ avio_wl64(pb, PREROLL_TIME); /* start time stamp */ - avio_wl32(pb, (asf->is_streamed || !pb->seekable) ? 3 : 2); /* ??? */ + avio_wl32(pb, (asf->is_streamed || !(pb->seekable & AVIO_SEEKABLE_NORMAL)) ? 3 : 2); /* ??? */ avio_wl32(pb, s->packet_size); /* packet size */ avio_wl32(pb, s->packet_size); /* packet size */ avio_wl32(pb, bit_rate); /* Nominal data rate in bps */ @@ -954,7 +954,7 @@ static int asf_write_trailer(AVFormatContext *s) asf_write_index(s, asf->index_ptr, asf->maximum_packet, asf->nb_index_count); avio_flush(s->pb); - if (asf->is_streamed || !s->pb->seekable) { + if (asf->is_streamed || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) { put_chunk(s, 0x4524, 0, 0); /* end of stream */ } else { /* rewrite an updated header */ diff --git a/libavformat/au.c b/libavformat/au.c index e30314239fac9..20c9d41f47091 100644 --- a/libavformat/au.c +++ b/libavformat/au.c @@ -192,7 +192,7 @@ static int au_write_trailer(AVFormatContext *s) AVIOContext *pb = s->pb; int64_t file_size; - if (s->pb->seekable) { + if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) { /* update file size */ file_size = avio_tell(pb); avio_seek(pb, 8, SEEK_SET); diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 3666b573e0b21..ddc7c2b6f45af 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -761,7 +761,8 @@ static int avi_read_header(AVFormatContext *s) break; case MKTAG('i', 'n', 'd', 'x'): pos = avio_tell(pb); - if (pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) && + if ((pb->seekable & AVIO_SEEKABLE_NORMAL) && + !(s->flags & AVFMT_FLAG_IGNIDX) && read_braindead_odml_indx(s, 0) < 0 && (s->error_recognition & AV_EF_EXPLODE)) goto fail; @@ -828,7 +829,7 @@ static int avi_read_header(AVFormatContext *s) return AVERROR_INVALIDDATA; } - if (!avi->index_loaded && pb->seekable) + if (!avi->index_loaded && (pb->seekable & AVIO_SEEKABLE_NORMAL)) avi_load_index(s); avi->index_loaded = 1; diff --git a/libavformat/avienc.c b/libavformat/avienc.c index d89fab17e8675..e4743981b8e69 100644 --- a/libavformat/avienc.c +++ b/libavformat/avienc.c @@ -189,7 +189,7 @@ static int avi_write_header(AVFormatContext *s) avio_wl32(pb, 0); avio_wl32(pb, bitrate / 8); /* XXX: not quite exact */ avio_wl32(pb, 0); /* padding */ - if (!pb->seekable) + if (!(pb->seekable & AVIO_SEEKABLE_NORMAL)) avio_wl32(pb, AVIF_TRUSTCKTYPE | AVIF_ISINTERLEAVED); /* flags */ else avio_wl32(pb, AVIF_TRUSTCKTYPE | AVIF_HASINDEX | AVIF_ISINTERLEAVED); /* flags */ @@ -261,7 +261,7 @@ static int avi_write_header(AVFormatContext *s) avio_wl32(pb, 0); /* start */ /* remember this offset to fill later */ avist->frames_hdr_strm = avio_tell(pb); - if (!pb->seekable) + if (!(pb->seekable & AVIO_SEEKABLE_NORMAL)) /* FIXME: this may be broken, but who cares */ avio_wl32(pb, AVI_MAX_RIFF_SIZE); else @@ -306,7 +306,7 @@ static int avi_write_header(AVFormatContext *s) } } - if (pb->seekable) { + if (pb->seekable & AVIO_SEEKABLE_NORMAL) { unsigned char tag[5]; int j; @@ -366,7 +366,7 @@ static int avi_write_header(AVFormatContext *s) ff_end_tag(pb, list2); } - if (pb->seekable) { + if (pb->seekable & AVIO_SEEKABLE_NORMAL) { /* AVI could become an OpenDML one, if it grows beyond 2Gb range */ avi->odml_list = ff_start_tag(pb, "JUNK"); ffio_wfourcc(pb, "odml"); @@ -403,7 +403,7 @@ static int avi_write_ix(AVFormatContext *s) char ix_tag[] = "ix00"; int i, j; - assert(pb->seekable); + assert(pb->seekable & AVIO_SEEKABLE_NORMAL); if (avi->riff_id > AVI_MASTER_INDEX_SIZE) return -1; @@ -461,7 +461,7 @@ static int avi_write_idx1(AVFormatContext *s) int i; char tag[5]; - if (pb->seekable) { + if (pb->seekable & AVIO_SEEKABLE_NORMAL) { AVIStream *avist; AVIIentry *ie = 0, *tie; int empty, stream_id = -1; @@ -528,7 +528,7 @@ static int avi_write_packet(AVFormatContext *s, AVPacket *pkt) avist->packet_count++; // Make sure to put an OpenDML chunk when the file size exceeds the limits - if (pb->seekable && + if ((pb->seekable & AVIO_SEEKABLE_NORMAL) && (avio_tell(pb) - avi->riff_start > AVI_MAX_RIFF_SIZE)) { avi_write_ix(s); ff_end_tag(pb, avi->movi_list); @@ -546,7 +546,7 @@ static int avi_write_packet(AVFormatContext *s, AVPacket *pkt) if (par->codec_type == AVMEDIA_TYPE_AUDIO) avist->audio_strm_length += size; - if (s->pb->seekable) { + if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) { int err; AVIIndex *idx = &avist->indexes; int cl = idx->entry / AVI_INDEX_CLUSTER_SIZE; @@ -588,7 +588,7 @@ static int avi_write_trailer(AVFormatContext *s) int i, j, n, nb_frames; int64_t file_size; - if (pb->seekable) { + if (pb->seekable & AVIO_SEEKABLE_NORMAL) { if (avi->riff_id == 1) { ff_end_tag(pb, avi->movi_list); res = avi_write_idx1(s); diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index 706cf5dd7f773..39a11e21c412c 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -265,7 +265,7 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence) offset1 >= 0 && offset1 < (s->buf_end - s->buffer)) { /* can do the seek inside the buffer */ s->buf_ptr = s->buffer + offset1; - } else if ((!s->seekable || + } else if ((!(s->seekable & AVIO_SEEKABLE_NORMAL) || offset1 <= s->buf_end + SHORT_SEEK_THRESHOLD - s->buffer) && !s->write_flag && offset1 >= 0 && (whence != SEEK_END || force)) { diff --git a/libavformat/bink.c b/libavformat/bink.c index 377db98971397..8f28212ab46b0 100644 --- a/libavformat/bink.c +++ b/libavformat/bink.c @@ -267,7 +267,7 @@ static int read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, in BinkDemuxContext *bink = s->priv_data; AVStream *vst = s->streams[0]; - if (!s->pb->seekable) + if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) return -1; /* seek to the first frame */ diff --git a/libavformat/cafdec.c b/libavformat/cafdec.c index 65bdcfc1ef092..efc8c49c4a877 100644 --- a/libavformat/cafdec.c +++ b/libavformat/cafdec.c @@ -249,7 +249,7 @@ static int read_header(AVFormatContext *s) /* stop at data chunk if seeking is not supported or data chunk size is unknown */ - if (found_data && (caf->data_size < 0 || !pb->seekable)) + if (found_data && (caf->data_size < 0 || !(pb->seekable & AVIO_SEEKABLE_NORMAL))) break; tag = avio_rb32(pb); @@ -262,7 +262,7 @@ static int read_header(AVFormatContext *s) avio_skip(pb, 4); /* edit count */ caf->data_start = avio_tell(pb); caf->data_size = size < 0 ? -1 : size - 4; - if (caf->data_size > 0 && pb->seekable) + if (caf->data_size > 0 && (pb->seekable & AVIO_SEEKABLE_NORMAL)) avio_skip(pb, caf->data_size); found_data = 1; break; diff --git a/libavformat/filmstripdec.c b/libavformat/filmstripdec.c index b029d8023e93a..b5dad50c37370 100644 --- a/libavformat/filmstripdec.c +++ b/libavformat/filmstripdec.c @@ -40,7 +40,7 @@ static int read_header(AVFormatContext *s) AVIOContext *pb = s->pb; AVStream *st; - if (!s->pb->seekable) + if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) return AVERROR(EIO); avio_seek(pb, avio_size(pb) - 36, SEEK_SET); diff --git a/libavformat/flacenc.c b/libavformat/flacenc.c index 3cee668afcf16..06985cf2400f9 100644 --- a/libavformat/flacenc.c +++ b/libavformat/flacenc.c @@ -130,7 +130,7 @@ static int flac_write_trailer(struct AVFormatContext *s) if (!c->write_header || !streaminfo) return 0; - if (pb->seekable) { + if (pb->seekable & AVIO_SEEKABLE_NORMAL) { /* rewrite the STREAMINFO header block data */ file_size = avio_tell(pb); avio_seek(pb, 8, SEEK_SET); diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 0d9a113edb047..b82ea3303bfe8 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -837,7 +837,8 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) // if not streamed and no duration from metadata then seek to end to find // the duration from the timestamps - if (s->pb->seekable && (!s->duration || s->duration == AV_NOPTS_VALUE) && + if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && + (!s->duration || s->duration == AV_NOPTS_VALUE) && !flv->searched_for_end) { int size; const int64_t pos = avio_tell(s->pb); diff --git a/libavformat/gxfenc.c b/libavformat/gxfenc.c index 60f88fdabd726..32714f63ae26f 100644 --- a/libavformat/gxfenc.c +++ b/libavformat/gxfenc.c @@ -633,7 +633,7 @@ static int gxf_write_header(AVFormatContext *s) uint8_t tracks[255] = {0}; int i, media_info = 0; - if (!pb->seekable) { + if (!(pb->seekable & AVIO_SEEKABLE_NORMAL)) { av_log(s, AV_LOG_ERROR, "gxf muxer does not support streamed output, patch welcome"); return -1; } diff --git a/libavformat/id3v1.c b/libavformat/id3v1.c index 87930ff361a9d..9420d9e57c8b1 100644 --- a/libavformat/id3v1.c +++ b/libavformat/id3v1.c @@ -230,7 +230,7 @@ void ff_id3v1_read(AVFormatContext *s) uint8_t buf[ID3v1_TAG_SIZE]; int64_t filesize, position = avio_tell(s->pb); - if (s->pb->seekable) { + if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) { /* XXX: change that */ filesize = avio_size(s->pb); if (filesize > 128) { diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 7ccba57fe5e3d..991f86b8d561a 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -1394,7 +1394,7 @@ static void matroska_execute_seekhead(MatroskaDemuxContext *matroska) int i; // we should not do any seeking in the streaming case - if (!matroska->ctx->pb->seekable || + if (!(matroska->ctx->pb->seekable & AVIO_SEEKABLE_NORMAL) || (matroska->ctx->flags & AVFMT_FLAG_IGNIDX)) return; diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index dd5552c369d29..cfced72adac23 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -1252,14 +1252,14 @@ static int mkv_write_header(AVFormatContext *s) return ret; } - if (!s->pb->seekable) + if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) mkv_write_seekhead(pb, mkv->main_seekhead); mkv->cues = mkv_start_cues(mkv->segment_offset); if (!mkv->cues) return AVERROR(ENOMEM); - if (pb->seekable && mkv->reserve_cues_space) { + if ((pb->seekable & AVIO_SEEKABLE_NORMAL) && mkv->reserve_cues_space) { mkv->cues_pos = avio_tell(pb); put_ebml_void(pb, mkv->reserve_cues_space); } @@ -1271,7 +1271,7 @@ static int mkv_write_header(AVFormatContext *s) // start a new cluster every 5 MB or 5 sec, or 32k / 1 sec for streaming or // after 4k and on a keyframe - if (pb->seekable) { + if (pb->seekable & AVIO_SEEKABLE_NORMAL) { if (mkv->cluster_time_limit < 0) mkv->cluster_time_limit = 5000; if (mkv->cluster_size_limit < 0) @@ -1547,7 +1547,7 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt) } ts += mkv->tracks[pkt->stream_index].ts_offset; - if (!s->pb->seekable) { + if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) { if (!mkv->dyn_bc) { ret = avio_open_dyn_buf(&mkv->dyn_bc); if (ret < 0) @@ -1613,7 +1613,7 @@ static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) // start a new cluster every 5 MB or 5 sec, or 32k / 1 sec for streaming or // after 4k and on a keyframe - if (s->pb->seekable) { + if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) { pb = s->pb; cluster_size = avio_tell(pb) - mkv->cluster_pos; } else { @@ -1666,7 +1666,7 @@ static int mkv_write_flush_packet(AVFormatContext *s, AVPacket *pkt) { MatroskaMuxContext *mkv = s->priv_data; AVIOContext *pb; - if (s->pb->seekable) + if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) pb = s->pb; else pb = mkv->dyn_bc; @@ -1717,7 +1717,7 @@ static int mkv_write_trailer(AVFormatContext *s) return ret; } - if (pb->seekable) { + if (pb->seekable & AVIO_SEEKABLE_NORMAL) { if (mkv->cues->num_entries) { if (mkv->reserve_cues_space) { int64_t cues_end; diff --git a/libavformat/mmf.c b/libavformat/mmf.c index 55aeff410f9b9..454e609e67065 100644 --- a/libavformat/mmf.c +++ b/libavformat/mmf.c @@ -140,7 +140,7 @@ static int mmf_write_trailer(AVFormatContext *s) int64_t pos, size; int gatetime; - if (s->pb->seekable) { + if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) { /* Fill in length fields */ end_tag_be(pb, mmf->awapos); end_tag_be(pb, mmf->atrpos); diff --git a/libavformat/mov.c b/libavformat/mov.c index ca49716026ee6..36e75d5c389f6 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -3270,9 +3270,9 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (err < 0) return err; if (c->found_moov && c->found_mdat && - ((!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX) || + ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX) || start_pos + a.size == avio_size(pb))) { - if (!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX) + if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX) c->next_root_atom = start_pos + a.size; return 0; } @@ -3463,7 +3463,7 @@ static int mov_read_header(AVFormatContext *s) mov->fc = s; /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */ - if (pb->seekable) + if (pb->seekable & AVIO_SEEKABLE_NORMAL) atom.size = avio_size(pb); else atom.size = INT64_MAX; @@ -3481,7 +3481,7 @@ static int mov_read_header(AVFormatContext *s) } av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb)); - if (pb->seekable && mov->chapter_track > 0) + if ((pb->seekable & AVIO_SEEKABLE_NORMAL) && mov->chapter_track > 0) mov_read_chapters(s); for (i = 0; i < s->nb_streams; i++) { @@ -3558,8 +3558,8 @@ static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st) AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample]; int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale); av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts); - if (!sample || (!s->pb->seekable && current_sample->pos < sample->pos) || - (s->pb->seekable && + if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) || + ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) || (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) { diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 31b940a4b2db0..f99617a96ee73 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -4037,7 +4037,7 @@ static int mov_write_header(AVFormatContext *s) /* Non-seekable output is ok if using fragmentation. If ism_lookahead * is enabled, we don't support non-seekable output at all. */ - if (!s->pb->seekable && + if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && (!(mov->flags & FF_MOV_FLAG_FRAGMENT) || mov->ism_lookahead)) { av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n"); return AVERROR(EINVAL); diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c index 1e2ff1aa9462c..d87d7be3f44a6 100644 --- a/libavformat/mp3enc.c +++ b/libavformat/mp3enc.c @@ -141,7 +141,7 @@ static void mp3_write_xing(AVFormatContext *s) int ver = 0; int lsf, bytes_needed; - if (!s->pb->seekable || !mp3->write_xing) + if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) || !mp3->write_xing) return; for (i = 0; i < FF_ARRAY_ELEMS(avpriv_mpa_freq_tab); i++) { diff --git a/libavformat/mpc.c b/libavformat/mpc.c index cf8fe1e136612..5be50a7c245c7 100644 --- a/libavformat/mpc.c +++ b/libavformat/mpc.c @@ -105,7 +105,7 @@ static int mpc_read_header(AVFormatContext *s) st->duration = c->fcount; /* try to read APE tags */ - if (s->pb->seekable) { + if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) { int64_t pos = avio_tell(s->pb); ff_ape_parse_tag(s); if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) diff --git a/libavformat/mpc8.c b/libavformat/mpc8.c index 2349ea5bb8fd7..bd17c19838ebb 100644 --- a/libavformat/mpc8.c +++ b/libavformat/mpc8.c @@ -252,7 +252,7 @@ static int mpc8_read_header(AVFormatContext *s) st->duration = c->samples / (1152 << (st->codecpar->extradata[1]&3)*2); size -= avio_tell(pb) - pos; - if (pb->seekable) { + if (pb->seekable & AVIO_SEEKABLE_NORMAL) { int64_t pos = avio_tell(s->pb); c->apetag_start = ff_ape_parse_tag(s); avio_seek(s->pb, pos, SEEK_SET); diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c index f63e79f673c7a..0898353ca894c 100644 --- a/libavformat/mpeg.c +++ b/libavformat/mpeg.c @@ -378,7 +378,7 @@ static int mpegps_read_pes_header(AVFormatContext *s, int i; for (i = 0; i < s->nb_streams; i++) { if (startcode == s->streams[i]->id && - s->pb->seekable /* index useless on streams anyway */) { + (s->pb->seekable & AVIO_SEEKABLE_NORMAL) /* index useless on streams anyway */) { ff_reduce_index(s, i); av_add_index_entry(s->streams[i], *ppos, dts, 0, 0, AVINDEX_KEYFRAME /* FIXME keyframe? */); diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 40672aeb9811a..28b6d37bb353c 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -2087,7 +2087,8 @@ static int mpegts_read_header(AVFormatContext *s) /* normal demux */ /* first do a scan to get all the services */ - if (avio_seek(pb, pos, SEEK_SET) < 0 && pb->seekable) + if (avio_seek(pb, pos, SEEK_SET) < 0 && + (pb->seekable & AVIO_SEEKABLE_NORMAL)) av_log(s, AV_LOG_ERROR, "Unable to seek back to the start\n"); mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1); diff --git a/libavformat/mvdec.c b/libavformat/mvdec.c index f13359c815382..52c5355e6a9fa 100644 --- a/libavformat/mvdec.c +++ b/libavformat/mvdec.c @@ -403,7 +403,7 @@ static int mv_read_packet(AVFormatContext *avctx, AVPacket *pkt) if (index->pos > pos) avio_skip(pb, index->pos - pos); else if (index->pos < pos) { - if (!pb->seekable) + if (!(pb->seekable & AVIO_SEEKABLE_NORMAL)) return AVERROR(EIO); ret = avio_seek(pb, index->pos, SEEK_SET); if (ret < 0) @@ -445,7 +445,7 @@ static int mv_read_seek(AVFormatContext *avctx, int stream_index, if ((flags & AVSEEK_FLAG_FRAME) || (flags & AVSEEK_FLAG_BYTE)) return AVERROR(ENOSYS); - if (!avctx->pb->seekable) + if (!(avctx->pb->seekable & AVIO_SEEKABLE_NORMAL)) return AVERROR(EIO); frame = av_index_search_timestamp(st, timestamp, flags); diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 449af95e7a439..1c7c280188842 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -1933,7 +1933,7 @@ static int mxf_parse_handle_essence(MXFContext *mxf) /* remember where we were so we don't end up seeking further back than this */ mxf->last_forward_tell = avio_tell(pb); - if (!pb->seekable) { + if (!(pb->seekable & AVIO_SEEKABLE_NORMAL)) { av_log(mxf->fc, AV_LOG_INFO, "file is not seekable - not parsing last partition\n"); return -1; } @@ -2080,7 +2080,7 @@ static void mxf_read_random_index_pack(AVFormatContext *s) int64_t file_size; KLVPacket klv; - if (!s->pb->seekable) + if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) return; file_size = avio_size(s->pb); diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index 1431fc65e871e..eb53dbff214f9 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -1805,7 +1805,7 @@ static int mxf_write_footer(AVFormatContext *s) mxf_write_klv_fill(s); mxf_write_random_index_pack(s); - if (s->pb->seekable) { + if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) { avio_seek(pb, 0, SEEK_SET); if (mxf->edit_unit_byte_count) { if ((err = mxf_write_partition(s, 1, 2, header_closed_partition_key, 1)) < 0) diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c index b554f85101e84..e1a9f6db0f808 100644 --- a/libavformat/nutdec.c +++ b/libavformat/nutdec.c @@ -765,7 +765,7 @@ static int nut_read_header(AVFormatContext *s) s->internal->data_offset = pos - 8; - if (bc->seekable) { + if (bc->seekable & AVIO_SEEKABLE_NORMAL) { int64_t orig_pos = avio_tell(bc); find_and_decode_index(nut); avio_seek(bc, orig_pos, SEEK_SET); diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c index 9ec24973c6642..5965a9730fa63 100644 --- a/libavformat/oggdec.c +++ b/libavformat/oggdec.c @@ -509,7 +509,7 @@ static int ogg_get_length(AVFormatContext *s) int i, ret; int64_t size, end; - if (!s->pb->seekable) + if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) return 0; // already set diff --git a/libavformat/r3d.c b/libavformat/r3d.c index 4b28379fc904b..9369cdd7dfada 100644 --- a/libavformat/r3d.c +++ b/libavformat/r3d.c @@ -184,7 +184,7 @@ static int r3d_read_header(AVFormatContext *s) s->internal->data_offset = avio_tell(s->pb); av_log(s, AV_LOG_TRACE, "data offset %#"PRIx64"\n", s->internal->data_offset); - if (!s->pb->seekable) + if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) return 0; // find REOB/REOF/REOS to load index avio_seek(s->pb, avio_size(s->pb)-48-8, SEEK_SET); diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c index 9774194e8e507..51a5bf767c4e1 100644 --- a/libavformat/rmdec.c +++ b/libavformat/rmdec.c @@ -519,7 +519,8 @@ static int rm_read_header(AVFormatContext *s) if (!data_off) data_off = avio_tell(pb) - 18; - if (indx_off && pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) && + if (indx_off && (pb->seekable & AVIO_SEEKABLE_NORMAL) && + !(s->flags & AVFMT_FLAG_IGNIDX) && avio_seek(pb, indx_off, SEEK_SET) >= 0) { rm_read_index(s); avio_seek(pb, data_off + 18, SEEK_SET); diff --git a/libavformat/rmenc.c b/libavformat/rmenc.c index 59118c94840a8..6cbe7002193de 100644 --- a/libavformat/rmenc.c +++ b/libavformat/rmenc.c @@ -123,7 +123,7 @@ static int rv10_write_header(AVFormatContext *ctx, avio_wb32(s, 0); /* data offset : will be patched after */ avio_wb16(s, ctx->nb_streams); /* num streams */ flags = 1 | 2; /* save allowed & perfect play */ - if (!s->seekable) + if (!(s->seekable & AVIO_SEEKABLE_NORMAL)) flags |= 4; /* live broadcast */ avio_wb16(s, flags); @@ -175,7 +175,7 @@ static int rv10_write_header(AVFormatContext *ctx, avio_wb32(s, 0); /* start time */ avio_wb32(s, BUFFER_DURATION); /* preroll */ /* duration */ - if (!s->seekable || !stream->total_frames) + if (!(s->seekable & AVIO_SEEKABLE_NORMAL) || !stream->total_frames) avio_wb32(s, (int)(3600 * 1000)); else avio_wb32(s, (int)(stream->total_frames * 1000 / stream->frame_rate)); @@ -433,7 +433,7 @@ static int rm_write_trailer(AVFormatContext *s) int data_size, index_pos, i; AVIOContext *pb = s->pb; - if (s->pb->seekable) { + if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) { /* end of file: finish to write header */ index_pos = avio_tell(pb); data_size = index_pos - rm->data_pos; diff --git a/libavformat/rsoenc.c b/libavformat/rsoenc.c index dd0fbf8c418ec..4f8278c4ab547 100644 --- a/libavformat/rsoenc.c +++ b/libavformat/rsoenc.c @@ -38,7 +38,7 @@ static int rso_write_header(AVFormatContext *s) return AVERROR_INVALIDDATA; } - if (!s->pb->seekable) { + if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) { av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n"); return AVERROR_INVALIDDATA; } diff --git a/libavformat/smjpegenc.c b/libavformat/smjpegenc.c index 2a9505947fe8f..91b0939cbc094 100644 --- a/libavformat/smjpegenc.c +++ b/libavformat/smjpegenc.c @@ -120,7 +120,7 @@ static int smjpeg_write_trailer(AVFormatContext *s) AVIOContext *pb = s->pb; int64_t currentpos; - if (pb->seekable) { + if (pb->seekable & AVIO_SEEKABLE_NORMAL) { currentpos = avio_tell(pb); avio_seek(pb, 12, SEEK_SET); avio_wb32(pb, smc->duration); diff --git a/libavformat/soxenc.c b/libavformat/soxenc.c index ea05f368927b9..d0f7d410d2ddd 100644 --- a/libavformat/soxenc.c +++ b/libavformat/soxenc.c @@ -98,7 +98,7 @@ static int sox_write_trailer(AVFormatContext *s) AVIOContext *pb = s->pb; AVCodecParameters *par = s->streams[0]->codecpar; - if (s->pb->seekable) { + if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) { /* update number of samples */ int64_t file_size = avio_tell(pb); int64_t num_samples = (file_size - sox->header_size - 4LL) >> 2LL; diff --git a/libavformat/swfenc.c b/libavformat/swfenc.c index f8db3e9196785..345688c654a82 100644 --- a/libavformat/swfenc.c +++ b/libavformat/swfenc.c @@ -495,7 +495,7 @@ static int swf_write_trailer(AVFormatContext *s) put_swf_end_tag(s); /* patch file size and number of frames if not streamed */ - if (s->pb->seekable && video_par) { + if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && video_par) { file_size = avio_tell(pb); avio_seek(pb, 4, SEEK_SET); avio_wl32(pb, file_size); diff --git a/libavformat/takdec.c b/libavformat/takdec.c index b28d44ce007a8..19e0e69a5ee3c 100644 --- a/libavformat/takdec.c +++ b/libavformat/takdec.c @@ -101,7 +101,7 @@ static int tak_read_header(AVFormatContext *s) case TAK_METADATA_END: { int64_t curpos = avio_tell(pb); - if (pb->seekable) { + if (pb->seekable & AVIO_SEEKABLE_NORMAL) { ff_ape_parse_tag(s); avio_seek(pb, curpos, SEEK_SET); } diff --git a/libavformat/tty.c b/libavformat/tty.c index d4c4873b81dad..f4535bbd1c464 100644 --- a/libavformat/tty.c +++ b/libavformat/tty.c @@ -103,7 +103,7 @@ static int read_header(AVFormatContext *avctx) /* simulate tty display speed */ s->chars_per_frame = FFMAX(av_q2d(st->time_base)*s->chars_per_frame, 1); - if (avctx->pb->seekable) { + if (avctx->pb->seekable & AVIO_SEEKABLE_NORMAL) { s->fsize = avio_size(avctx->pb); st->duration = (s->fsize + s->chars_per_frame - 1) / s->chars_per_frame; diff --git a/libavformat/utils.c b/libavformat/utils.c index 6df1a3219915f..0e94b15b7269b 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -1827,7 +1827,7 @@ static void estimate_timings(AVFormatContext *ic, int64_t old_offset) if ((!strcmp(ic->iformat->name, "mpeg") || !strcmp(ic->iformat->name, "mpegts")) && - file_size && ic->pb->seekable) { + file_size && (ic->pb->seekable & AVIO_SEEKABLE_NORMAL)) { /* get accurate estimate from the PTSes */ estimate_timings_from_pts(ic, old_offset); } else if (has_duration(ic)) { diff --git a/libavformat/vc1testenc.c b/libavformat/vc1testenc.c index dc23c1461ddab..c286f66a42781 100644 --- a/libavformat/vc1testenc.c +++ b/libavformat/vc1testenc.c @@ -73,7 +73,7 @@ static int vc1test_write_trailer(AVFormatContext *s) RCVContext *ctx = s->priv_data; AVIOContext *pb = s->pb; - if (s->pb->seekable) { + if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) { avio_seek(pb, 0, SEEK_SET); avio_wl24(pb, ctx->frames); avio_flush(pb); diff --git a/libavformat/voc_packet.c b/libavformat/voc_packet.c index ff48d502f2750..38650756f7448 100644 --- a/libavformat/voc_packet.c +++ b/libavformat/voc_packet.c @@ -37,7 +37,7 @@ ff_voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size) return AVERROR(EIO); voc->remaining_size = avio_rl24(pb); if (!voc->remaining_size) { - if (!s->pb->seekable) + if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) return AVERROR(EIO); voc->remaining_size = avio_size(pb) - avio_tell(pb); } diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c index 4bd2642d77def..8c78666f84522 100644 --- a/libavformat/wavdec.c +++ b/libavformat/wavdec.c @@ -289,7 +289,7 @@ static int wav_read_header(AVFormatContext *s) /* don't look for footer metadata if we can't seek or if we don't * know where the data tag ends */ - if (!pb->seekable || (!rf64 && !size)) + if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || (!rf64 && !size)) goto break_loop; break; case MKTAG('f', 'a', 'c', 't'): diff --git a/libavformat/wavenc.c b/libavformat/wavenc.c index 32d4bc184d9c1..fc7d49e6d7068 100644 --- a/libavformat/wavenc.c +++ b/libavformat/wavenc.c @@ -118,7 +118,7 @@ static int wav_write_header(AVFormatContext *s) ff_end_tag(pb, fmt); if (s->streams[0]->codecpar->codec_tag != 0x01 /* hence for all other than PCM */ - && s->pb->seekable) { + && (s->pb->seekable & AVIO_SEEKABLE_NORMAL)) { wav->fact_pos = ff_start_tag(pb, "fact"); avio_wl32(pb, 0); ff_end_tag(pb, wav->fact_pos); @@ -164,7 +164,7 @@ static int wav_write_trailer(AVFormatContext *s) avio_flush(pb); - if (s->pb->seekable) { + if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) { ff_end_tag(pb, wav->data); /* update file size */ diff --git a/libavformat/wvdec.c b/libavformat/wvdec.c index c78bac1ff9d14..717275c6a0c03 100644 --- a/libavformat/wvdec.c +++ b/libavformat/wvdec.c @@ -116,7 +116,7 @@ static int wv_read_block_header(AVFormatContext *ctx, AVIOContext *pb) } if ((rate == -1 || !chan) && !wc->block_parsed) { int64_t block_end = avio_tell(pb) + wc->header.blocksize; - if (!pb->seekable) { + if (!(pb->seekable & AVIO_SEEKABLE_NORMAL)) { av_log(ctx, AV_LOG_ERROR, "Cannot determine additional parameters\n"); return AVERROR_INVALIDDATA; @@ -237,7 +237,7 @@ static int wv_read_header(AVFormatContext *s) st->start_time = 0; st->duration = wc->header.total_samples; - if (s->pb->seekable) { + if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) { int64_t cur = avio_tell(s->pb); wc->apetag_start = ff_ape_parse_tag(s); if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) diff --git a/libavformat/wvenc.c b/libavformat/wvenc.c index a753c199dba34..63f1ea63b510f 100644 --- a/libavformat/wvenc.c +++ b/libavformat/wvenc.c @@ -60,7 +60,7 @@ static av_cold int wv_write_trailer(AVFormatContext *ctx) WvMuxContext *s = ctx->priv_data; /* update total number of samples in the first block */ - if (ctx->pb->seekable && s->samples && + if ((ctx->pb->seekable & AVIO_SEEKABLE_NORMAL) && s->samples && s->samples < UINT32_MAX) { int64_t pos = avio_tell(ctx->pb); avio_seek(ctx->pb, 12, SEEK_SET); From 75c1db6152c7c90c7ce28c9adb945028e5512c4f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 27 Sep 2016 15:37:54 +0200 Subject: [PATCH 0210/3374] avio: cosmetics, prettify AVIO_SEEKABLE_NORMAL Move the doxy above the definition, change the value itself to the (1 << n) pattern, which is more readable for flags. --- libavformat/avio.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavformat/avio.h b/libavformat/avio.h index 4bd5cb134a279..5d2f8c203107a 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -34,8 +34,10 @@ #include "libavformat/version.h" - -#define AVIO_SEEKABLE_NORMAL 0x0001 /**< Seeking works like for a local file */ +/** + * Seeking works like for a local file. + */ +#define AVIO_SEEKABLE_NORMAL (1 << 0) /** * Callback for checking whether to abort blocking functions. From 8ea35af7620e4f73f9e8c072e1c0fac9a04ec161 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 27 Sep 2016 15:44:54 +0200 Subject: [PATCH 0211/3374] avio: add a new flag for marking streams seekable by timestamp --- doc/APIchanges | 3 +++ libavformat/avio.h | 5 +++++ libavformat/aviobuf.c | 3 +++ libavformat/version.h | 4 ++-- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index d0ffca2e80d4b..6fd3959a330c9 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-xx-xx - xxxxxxx - lavf 57.08.0 - avio.h + Add AVIO_SEEKABLE_TIME flag. + 2016-xx-xx - xxxxxxx - lavu 55.22.0 - pixfmt.h Add AV_PIX_FMT_YUV(420,422,444)P12. diff --git a/libavformat/avio.h b/libavformat/avio.h index 5d2f8c203107a..49721aa1315fc 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -39,6 +39,11 @@ */ #define AVIO_SEEKABLE_NORMAL (1 << 0) +/** + * Seeking by timestamp with avio_seek_time() is possible. + */ +#define AVIO_SEEKABLE_TIME (1 << 1) + /** * Callback for checking whether to abort blocking functions. * AVERROR_EXIT is returned in this case by the interrupted diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index 39a11e21c412c..5cb733d3d8ac4 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -846,6 +846,9 @@ int ffio_fdopen(AVIOContext **s, URLContext *h) if(h->prot) { (*s)->read_pause = io_read_pause; (*s)->read_seek = io_read_seek; + + if (h->prot->url_read_seek) + (*s)->seekable |= AVIO_SEEKABLE_TIME; } (*s)->av_class = &ff_avio_class; return 0; diff --git a/libavformat/version.h b/libavformat/version.h index 1e1105fe5c5c5..a6643a9e25b64 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -30,8 +30,8 @@ #include "libavutil/version.h" #define LIBAVFORMAT_VERSION_MAJOR 57 -#define LIBAVFORMAT_VERSION_MINOR 7 -#define LIBAVFORMAT_VERSION_MICRO 1 +#define LIBAVFORMAT_VERSION_MINOR 8 +#define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ From 43717469f9daa402f6acb48997255827a56034e9 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 28 Oct 2015 15:38:20 +0100 Subject: [PATCH 0212/3374] ac3dsp: Reverse matrix in/out order in downmix() Also use (float **) instead of (float (*)[2]). This matches the matrix layout in libavresample so we can reuse assembly code between the two. Signed-off-by: Diego Biurrun --- libavcodec/ac3dec.c | 40 ++++++++++++++++++++++++------------ libavcodec/ac3dec.h | 2 +- libavcodec/ac3dsp.c | 8 ++++---- libavcodec/ac3dsp.h | 2 +- libavcodec/x86/ac3dsp_init.c | 36 +++++++++++++++++--------------- 5 files changed, 52 insertions(+), 36 deletions(-) diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 9afc54d18dd84..aba31195fb4be 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -332,47 +332,57 @@ static int parse_frame_header(AC3DecodeContext *s) * Set stereo downmixing coefficients based on frame header info. * reference: Section 7.8.2 Downmixing Into Two Channels */ -static void set_downmix_coeffs(AC3DecodeContext *s) +static int set_downmix_coeffs(AC3DecodeContext *s) { int i; float cmix = gain_levels[s-> center_mix_level]; float smix = gain_levels[s->surround_mix_level]; float norm0, norm1; + if (!s->downmix_coeffs[0]) { + s->downmix_coeffs[0] = av_malloc(2 * AC3_MAX_CHANNELS * + sizeof(**s->downmix_coeffs)); + if (!s->downmix_coeffs[0]) + return AVERROR(ENOMEM); + s->downmix_coeffs[1] = s->downmix_coeffs[0] + AC3_MAX_CHANNELS; + } + for (i = 0; i < s->fbw_channels; i++) { - s->downmix_coeffs[i][0] = gain_levels[ac3_default_coeffs[s->channel_mode][i][0]]; - s->downmix_coeffs[i][1] = gain_levels[ac3_default_coeffs[s->channel_mode][i][1]]; + s->downmix_coeffs[0][i] = gain_levels[ac3_default_coeffs[s->channel_mode][i][0]]; + s->downmix_coeffs[1][i] = gain_levels[ac3_default_coeffs[s->channel_mode][i][1]]; } if (s->channel_mode > 1 && s->channel_mode & 1) { - s->downmix_coeffs[1][0] = s->downmix_coeffs[1][1] = cmix; + s->downmix_coeffs[0][1] = s->downmix_coeffs[1][1] = cmix; } if (s->channel_mode == AC3_CHMODE_2F1R || s->channel_mode == AC3_CHMODE_3F1R) { int nf = s->channel_mode - 2; - s->downmix_coeffs[nf][0] = s->downmix_coeffs[nf][1] = smix * LEVEL_MINUS_3DB; + s->downmix_coeffs[0][nf] = s->downmix_coeffs[1][nf] = smix * LEVEL_MINUS_3DB; } if (s->channel_mode == AC3_CHMODE_2F2R || s->channel_mode == AC3_CHMODE_3F2R) { int nf = s->channel_mode - 4; - s->downmix_coeffs[nf][0] = s->downmix_coeffs[nf+1][1] = smix; + s->downmix_coeffs[0][nf] = s->downmix_coeffs[1][nf+1] = smix; } /* renormalize */ norm0 = norm1 = 0.0; for (i = 0; i < s->fbw_channels; i++) { - norm0 += s->downmix_coeffs[i][0]; - norm1 += s->downmix_coeffs[i][1]; + norm0 += s->downmix_coeffs[0][i]; + norm1 += s->downmix_coeffs[1][i]; } norm0 = 1.0f / norm0; norm1 = 1.0f / norm1; for (i = 0; i < s->fbw_channels; i++) { - s->downmix_coeffs[i][0] *= norm0; - s->downmix_coeffs[i][1] *= norm1; + s->downmix_coeffs[0][i] *= norm0; + s->downmix_coeffs[1][i] *= norm1; } if (s->output_mode == AC3_CHMODE_MONO) { for (i = 0; i < s->fbw_channels; i++) - s->downmix_coeffs[i][0] = (s->downmix_coeffs[i][0] + - s->downmix_coeffs[i][1]) * LEVEL_MINUS_3DB; + s->downmix_coeffs[0][i] = (s->downmix_coeffs[0][i] + + s->downmix_coeffs[1][i]) * LEVEL_MINUS_3DB; } + + return 0; } /** @@ -1447,7 +1457,10 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, /* set downmixing coefficients if needed */ if (s->channels != s->out_channels && !((s->output_mode & AC3_OUTPUT_LFEON) && s->fbw_channels == s->out_channels)) { - set_downmix_coeffs(s); + if ((ret = set_downmix_coeffs(s)) < 0) { + av_log(avctx, AV_LOG_ERROR, "error setting downmix coeffs\n"); + return ret; + } } } else if (!s->channels) { av_log(avctx, AV_LOG_ERROR, "unable to determine channel mode\n"); @@ -1566,6 +1579,7 @@ static av_cold int ac3_decode_end(AVCodecContext *avctx) AC3DecodeContext *s = avctx->priv_data; ff_mdct_end(&s->imdct_512); ff_mdct_end(&s->imdct_256); + av_freep(&s->downmix_coeffs[0]); return 0; } diff --git a/libavcodec/ac3dec.h b/libavcodec/ac3dec.h index 4c5359cb87077..4a7e281932601 100644 --- a/libavcodec/ac3dec.h +++ b/libavcodec/ac3dec.h @@ -147,7 +147,7 @@ typedef struct AC3DecodeContext { int fbw_channels; ///< number of full-bandwidth channels int channels; ///< number of total channels int lfe_ch; ///< index of LFE channel - float downmix_coeffs[AC3_MAX_CHANNELS][2]; ///< stereo downmix coefficients + float *downmix_coeffs[2]; ///< stereo downmix coefficients int downmixed; ///< indicates if coeffs are currently downmixed int output_mode; ///< output channel configuration int out_channels; ///< number of output channels diff --git a/libavcodec/ac3dsp.c b/libavcodec/ac3dsp.c index 38c35b187ae5a..d1bf37e943dae 100644 --- a/libavcodec/ac3dsp.c +++ b/libavcodec/ac3dsp.c @@ -171,7 +171,7 @@ static void ac3_extract_exponents_c(uint8_t *exp, int32_t *coef, int nb_coefs) } } -static void ac3_downmix_c(float **samples, float (*matrix)[2], +static void ac3_downmix_c(float **samples, float **matrix, int out_ch, int in_ch, int len) { int i, j; @@ -180,8 +180,8 @@ static void ac3_downmix_c(float **samples, float (*matrix)[2], for (i = 0; i < len; i++) { v0 = v1 = 0.0f; for (j = 0; j < in_ch; j++) { - v0 += samples[j][i] * matrix[j][0]; - v1 += samples[j][i] * matrix[j][1]; + v0 += samples[j][i] * matrix[0][j]; + v1 += samples[j][i] * matrix[1][j]; } samples[0][i] = v0; samples[1][i] = v1; @@ -190,7 +190,7 @@ static void ac3_downmix_c(float **samples, float (*matrix)[2], for (i = 0; i < len; i++) { v0 = 0.0f; for (j = 0; j < in_ch; j++) - v0 += samples[j][i] * matrix[j][0]; + v0 += samples[j][i] * matrix[0][j]; samples[0][i] = v0; } } diff --git a/libavcodec/ac3dsp.h b/libavcodec/ac3dsp.h index 6ca0c5b8e87d6..cdce21a865752 100644 --- a/libavcodec/ac3dsp.h +++ b/libavcodec/ac3dsp.h @@ -126,7 +126,7 @@ typedef struct AC3DSPContext { void (*extract_exponents)(uint8_t *exp, int32_t *coef, int nb_coefs); - void (*downmix)(float **samples, float (*matrix)[2], int out_ch, + void (*downmix)(float **samples, float **matrix, int out_ch, int in_ch, int len); /** diff --git a/libavcodec/x86/ac3dsp_init.c b/libavcodec/x86/ac3dsp_init.c index 89044f408846f..9036389296b65 100644 --- a/libavcodec/x86/ac3dsp_init.c +++ b/libavcodec/x86/ac3dsp_init.c @@ -71,8 +71,8 @@ void ff_apply_window_int16_ssse3_atom(int16_t *output, const int16_t *input, #define MIX5(mono, stereo) \ __asm__ volatile ( \ "movss 0(%1), %%xmm5 \n" \ - "movss 8(%1), %%xmm6 \n" \ - "movss 24(%1), %%xmm7 \n" \ + "movss 4(%1), %%xmm6 \n" \ + "movss 12(%1), %%xmm7 \n" \ "shufps $0, %%xmm5, %%xmm5 \n" \ "shufps $0, %%xmm6, %%xmm6 \n" \ "shufps $0, %%xmm7, %%xmm7 \n" \ @@ -97,7 +97,7 @@ void ff_apply_window_int16_ssse3_atom(int16_t *output, const int16_t *input, "add $16, %0 \n" \ "jl 1b \n" \ : "+&r"(i) \ - : "r"(matrix), \ + : "r"(matrix[0]), \ "r"(samples[0] + len), \ "r"(samples[1] + len), \ "r"(samples[2] + len), \ @@ -141,22 +141,22 @@ void ff_apply_window_int16_ssse3_atom(int16_t *output, const int16_t *input, : "memory" \ ); -static void ac3_downmix_sse(float **samples, float (*matrix)[2], +static void ac3_downmix_sse(float **samples, float **matrix, int out_ch, int in_ch, int len) { - int (*matrix_cmp)[2] = (int(*)[2])matrix; + int **matrix_cmp = (int **)matrix; intptr_t i, j, k, m; i = -len * sizeof(float); if (in_ch == 5 && out_ch == 2 && - !(matrix_cmp[0][1] | matrix_cmp[2][0] | - matrix_cmp[3][1] | matrix_cmp[4][0] | - (matrix_cmp[1][0] ^ matrix_cmp[1][1]) | - (matrix_cmp[0][0] ^ matrix_cmp[2][1]))) { + !(matrix_cmp[1][0] | matrix_cmp[0][2] | + matrix_cmp[1][3] | matrix_cmp[0][4] | + (matrix_cmp[0][1] ^ matrix_cmp[1][1]) | + (matrix_cmp[0][0] ^ matrix_cmp[1][2]))) { MIX5(IF0, IF1); } else if (in_ch == 5 && out_ch == 1 && - matrix_cmp[0][0] == matrix_cmp[2][0] && - matrix_cmp[3][0] == matrix_cmp[4][0]) { + matrix_cmp[0][0] == matrix_cmp[0][2] && + matrix_cmp[0][3] == matrix_cmp[0][4]) { MIX5(IF1, IF0); } else { DECLARE_ALIGNED(16, float, matrix_simd)[AC3_MAX_CHANNELS][2][4]; @@ -166,18 +166,20 @@ static void ac3_downmix_sse(float **samples, float (*matrix)[2], samp[j] = samples[j] + len; j = 2 * in_ch * sizeof(float); + k = in_ch * sizeof(float); __asm__ volatile ( "1: \n" + "sub $4, %1 \n" "sub $8, %0 \n" - "movss (%2, %0), %%xmm4 \n" - "movss 4(%2, %0), %%xmm5 \n" + "movss (%3, %1), %%xmm4 \n" + "movss (%4, %1), %%xmm5 \n" "shufps $0, %%xmm4, %%xmm4 \n" "shufps $0, %%xmm5, %%xmm5 \n" - "movaps %%xmm4, (%1, %0, 4) \n" - "movaps %%xmm5, 16(%1, %0, 4) \n" + "movaps %%xmm4, (%2, %0, 4) \n" + "movaps %%xmm5, 16(%2, %0, 4) \n" "jg 1b \n" - : "+&r"(j) - : "r"(matrix_simd), "r"(matrix) + : "+&r"(j), "+&r"(k) + : "r"(matrix_simd), "r"(matrix[0]), "r"(matrix[1]) : "memory" ); if (out_ch == 2) { From a9ba59591ed509fb7e6decfde8da4cbfd4ddf4b8 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 28 Oct 2015 15:38:21 +0100 Subject: [PATCH 0213/3374] ac3dsp: Add some special-case handling for the C downmix function This is about 200% faster for in-decoder downmixing of 5.0 and 5.1 content. Signed-off-by: Diego Biurrun --- libavcodec/ac3dsp.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/libavcodec/ac3dsp.c b/libavcodec/ac3dsp.c index d1bf37e943dae..8eae5ad86618d 100644 --- a/libavcodec/ac3dsp.c +++ b/libavcodec/ac3dsp.c @@ -174,9 +174,46 @@ static void ac3_extract_exponents_c(uint8_t *exp, int32_t *coef, int nb_coefs) static void ac3_downmix_c(float **samples, float **matrix, int out_ch, int in_ch, int len) { + int **matrix_cmp = (int **)matrix; int i, j; float v0, v1; - if (out_ch == 2) { + + if (in_ch == 5 && out_ch == 2 && + !(matrix_cmp[1][0] | matrix_cmp[0][2] | + matrix_cmp[1][3] | matrix_cmp[0][4] | + (matrix_cmp[0][1] ^ matrix_cmp[1][1]) | + (matrix_cmp[0][0] ^ matrix_cmp[1][2]))) { + float front_mix = matrix[0][0]; + float center_mix = matrix[0][1]; + float surround_mix = matrix[0][3]; + + for (i = 0; i < len; i++) { + v0 = samples[0][i] * front_mix + + samples[1][i] * center_mix + + samples[3][i] * surround_mix; + + v1 = samples[1][i] * center_mix + + samples[2][i] * front_mix + + samples[4][i] * surround_mix; + + samples[0][i] = v0; + samples[1][i] = v1; + } + } else if (in_ch == 5 && out_ch == 1 && + matrix_cmp[0][0] == matrix_cmp[0][2] && + matrix_cmp[0][3] == matrix_cmp[0][4]) { + float front_mix = matrix[0][0]; + float center_mix = matrix[0][1]; + float surround_mix = matrix[0][3]; + + for (i = 0; i < len; i++) { + samples[0][i] = samples[0][i] * front_mix + + samples[1][i] * center_mix + + samples[2][i] * front_mix + + samples[3][i] * surround_mix + + samples[4][i] * surround_mix; + } + } else if (out_ch == 2) { for (i = 0; i < len; i++) { v0 = v1 = 0.0f; for (j = 0; j < in_ch; j++) { From b57e38f52cc3f31a27105c28887d57cd6812c3eb Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 28 Oct 2015 15:38:22 +0100 Subject: [PATCH 0214/3374] ac3dsp: x86: Replace inline asm for in-decoder downmixing with standalone asm Adds a wrapper function for downmixing which detects channel count changes and updates the selected downmix function accordingly. Simplification and porting to current x86inc infrastructure by Diego Biurrun. Signed-off-by: Diego Biurrun --- libavcodec/ac3dec.c | 8 +- libavcodec/ac3dsp.c | 112 ++++++++++++------ libavcodec/ac3dsp.h | 9 +- libavcodec/x86/Makefile | 3 +- libavcodec/x86/ac3dsp_downmix.asm | 187 ++++++++++++++++++++++++++++++ libavcodec/x86/ac3dsp_init.c | 174 +++++++-------------------- 6 files changed, 316 insertions(+), 177 deletions(-) create mode 100644 libavcodec/x86/ac3dsp_downmix.asm diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index aba31195fb4be..ad50552ec1b09 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -1328,19 +1328,19 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) do_imdct(s, s->channels); if (downmix_output) { - s->ac3dsp.downmix(s->outptr, s->downmix_coeffs, + ff_ac3dsp_downmix(&s->ac3dsp, s->outptr, s->downmix_coeffs, s->out_channels, s->fbw_channels, 256); } } else { if (downmix_output) { - s->ac3dsp.downmix(s->xcfptr + 1, s->downmix_coeffs, + ff_ac3dsp_downmix(&s->ac3dsp, s->xcfptr + 1, s->downmix_coeffs, s->out_channels, s->fbw_channels, 256); } if (downmix_output && !s->downmixed) { s->downmixed = 1; - s->ac3dsp.downmix(s->dlyptr, s->downmix_coeffs, s->out_channels, - s->fbw_channels, 128); + ff_ac3dsp_downmix(&s->ac3dsp, s->dlyptr, s->downmix_coeffs, + s->out_channels, s->fbw_channels, 128); } do_imdct(s, s->out_channels); diff --git a/libavcodec/ac3dsp.c b/libavcodec/ac3dsp.c index 8eae5ad86618d..440bd1a9919c7 100644 --- a/libavcodec/ac3dsp.c +++ b/libavcodec/ac3dsp.c @@ -171,49 +171,53 @@ static void ac3_extract_exponents_c(uint8_t *exp, int32_t *coef, int nb_coefs) } } -static void ac3_downmix_c(float **samples, float **matrix, - int out_ch, int in_ch, int len) +static void ac3_downmix_5_to_2_symmetric_c(float **samples, float **matrix, + int len) { - int **matrix_cmp = (int **)matrix; - int i, j; + int i; float v0, v1; + float front_mix = matrix[0][0]; + float center_mix = matrix[0][1]; + float surround_mix = matrix[0][3]; - if (in_ch == 5 && out_ch == 2 && - !(matrix_cmp[1][0] | matrix_cmp[0][2] | - matrix_cmp[1][3] | matrix_cmp[0][4] | - (matrix_cmp[0][1] ^ matrix_cmp[1][1]) | - (matrix_cmp[0][0] ^ matrix_cmp[1][2]))) { - float front_mix = matrix[0][0]; - float center_mix = matrix[0][1]; - float surround_mix = matrix[0][3]; + for (i = 0; i < len; i++) { + v0 = samples[0][i] * front_mix + + samples[1][i] * center_mix + + samples[3][i] * surround_mix; - for (i = 0; i < len; i++) { - v0 = samples[0][i] * front_mix + - samples[1][i] * center_mix + - samples[3][i] * surround_mix; + v1 = samples[1][i] * center_mix + + samples[2][i] * front_mix + + samples[4][i] * surround_mix; - v1 = samples[1][i] * center_mix + - samples[2][i] * front_mix + - samples[4][i] * surround_mix; + samples[0][i] = v0; + samples[1][i] = v1; + } +} - samples[0][i] = v0; - samples[1][i] = v1; - } - } else if (in_ch == 5 && out_ch == 1 && - matrix_cmp[0][0] == matrix_cmp[0][2] && - matrix_cmp[0][3] == matrix_cmp[0][4]) { - float front_mix = matrix[0][0]; - float center_mix = matrix[0][1]; - float surround_mix = matrix[0][3]; +static void ac3_downmix_5_to_1_symmetric_c(float **samples, float **matrix, + int len) +{ + int i; + float front_mix = matrix[0][0]; + float center_mix = matrix[0][1]; + float surround_mix = matrix[0][3]; - for (i = 0; i < len; i++) { - samples[0][i] = samples[0][i] * front_mix + - samples[1][i] * center_mix + - samples[2][i] * front_mix + - samples[3][i] * surround_mix + - samples[4][i] * surround_mix; - } - } else if (out_ch == 2) { + for (i = 0; i < len; i++) { + samples[0][i] = samples[0][i] * front_mix + + samples[1][i] * center_mix + + samples[2][i] * front_mix + + samples[3][i] * surround_mix + + samples[4][i] * surround_mix; + } +} + +static void ac3_downmix_c(float **samples, float **matrix, + int out_ch, int in_ch, int len) +{ + int i, j; + float v0, v1; + + if (out_ch == 2) { for (i = 0; i < len; i++) { v0 = v1 = 0.0f; for (j = 0; j < in_ch; j++) { @@ -246,6 +250,38 @@ static void apply_window_int16_c(int16_t *output, const int16_t *input, } } +void ff_ac3dsp_downmix(AC3DSPContext *c, float **samples, float **matrix, + int out_ch, int in_ch, int len) +{ + if (c->in_channels != in_ch || c->out_channels != out_ch) { + int **matrix_cmp = (int **)matrix; + + c->in_channels = in_ch; + c->out_channels = out_ch; + c->downmix = NULL; + + if (in_ch == 5 && out_ch == 2 && + !(matrix_cmp[1][0] | matrix_cmp[0][2] | + matrix_cmp[1][3] | matrix_cmp[0][4] | + (matrix_cmp[0][1] ^ matrix_cmp[1][1]) | + (matrix_cmp[0][0] ^ matrix_cmp[1][2]))) { + c->downmix = ac3_downmix_5_to_2_symmetric_c; + } else if (in_ch == 5 && out_ch == 1 && + matrix_cmp[0][0] == matrix_cmp[0][2] && + matrix_cmp[0][3] == matrix_cmp[0][4]) { + c->downmix = ac3_downmix_5_to_1_symmetric_c; + } + + if (ARCH_X86) + ff_ac3dsp_set_downmix_x86(c); + } + + if (c->downmix) + c->downmix(samples, matrix, len); + else + ac3_downmix_c(samples, matrix, out_ch, in_ch, len); +} + av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact) { c->ac3_exponent_min = ac3_exponent_min_c; @@ -257,7 +293,9 @@ av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact) c->update_bap_counts = ac3_update_bap_counts_c; c->compute_mantissa_size = ac3_compute_mantissa_size_c; c->extract_exponents = ac3_extract_exponents_c; - c->downmix = ac3_downmix_c; + c->in_channels = 0; + c->out_channels = 0; + c->downmix = NULL; c->apply_window_int16 = apply_window_int16_c; if (ARCH_ARM) diff --git a/libavcodec/ac3dsp.h b/libavcodec/ac3dsp.h index cdce21a865752..c33a0bee84fb9 100644 --- a/libavcodec/ac3dsp.h +++ b/libavcodec/ac3dsp.h @@ -126,8 +126,9 @@ typedef struct AC3DSPContext { void (*extract_exponents)(uint8_t *exp, int32_t *coef, int nb_coefs); - void (*downmix)(float **samples, float **matrix, int out_ch, - int in_ch, int len); + int out_channels; + int in_channels; + void (*downmix)(float **samples, float **matrix, int len); /** * Apply symmetric window in 16-bit fixed-point. @@ -148,4 +149,8 @@ void ff_ac3dsp_init (AC3DSPContext *c, int bit_exact); void ff_ac3dsp_init_arm(AC3DSPContext *c, int bit_exact); void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact); +void ff_ac3dsp_downmix(AC3DSPContext *c, float **samples, float **matrix, + int out_ch, int in_ch, int len); +void ff_ac3dsp_set_downmix_x86(AC3DSPContext *c); + #endif /* AVCODEC_AC3DSP_H */ diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile index 872b7faddb149..4aae594bd8a3f 100644 --- a/libavcodec/x86/Makefile +++ b/libavcodec/x86/Makefile @@ -71,7 +71,8 @@ MMX-OBJS-$(CONFIG_MPEG4_DECODER) += x86/xvididct_mmx.o \ x86/xvididct_sse2.o # subsystems -YASM-OBJS-$(CONFIG_AC3DSP) += x86/ac3dsp.o +YASM-OBJS-$(CONFIG_AC3DSP) += x86/ac3dsp.o \ + x86/ac3dsp_downmix.o YASM-OBJS-$(CONFIG_AUDIODSP) += x86/audiodsp.o YASM-OBJS-$(CONFIG_BSWAPDSP) += x86/bswapdsp.o YASM-OBJS-$(CONFIG_DCT) += x86/dct32.o diff --git a/libavcodec/x86/ac3dsp_downmix.asm b/libavcodec/x86/ac3dsp_downmix.asm new file mode 100644 index 0000000000000..b085035ce3705 --- /dev/null +++ b/libavcodec/x86/ac3dsp_downmix.asm @@ -0,0 +1,187 @@ +;***************************************************************************** +;* x86-optimized AC-3 downmixing +;* Copyright (c) 2012 Justin Ruggles +;* +;* This file is part of Libav. +;* +;* Libav is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* Libav is distributed in the hope that it will be useful, +;* but WITHOUT ANY WARRANTY; without even the implied warranty of +;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with Libav; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +;****************************************************************************** +;* This is based on the channel mixing asm in libavresample, but it is +;* simplified for only float coefficients and only 3 to 6 channels. +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION .text + +;----------------------------------------------------------------------------- +; functions to downmix from 3 to 6 channels to mono or stereo +; void ff_ac3_downmix_*(float **samples, float **matrix, int len); +;----------------------------------------------------------------------------- + +%macro AC3_DOWNMIX 2 ; %1 = in channels, %2 = out channels +; define some names to make the code clearer +%assign in_channels %1 +%assign out_channels %2 +%assign stereo out_channels - 1 + +; determine how many matrix elements must go on the stack vs. mmregs +%assign matrix_elements in_channels * out_channels +%if stereo + %assign needed_mmregs 4 +%else + %assign needed_mmregs 3 +%endif +%assign matrix_elements_mm num_mmregs - needed_mmregs +%if matrix_elements < matrix_elements_mm + %assign matrix_elements_mm matrix_elements +%endif +%assign total_mmregs needed_mmregs+matrix_elements_mm +%if matrix_elements_mm < matrix_elements + %assign matrix_elements_stack matrix_elements - matrix_elements_mm +%else + %assign matrix_elements_stack 0 +%endif + +cglobal ac3_downmix_%1_to_%2, 3,in_channels+1,total_mmregs,0-matrix_elements_stack*mmsize, src0, src1, len, src2, src3, src4, src5 + +; load matrix pointers +%define matrix0q r1q +%define matrix1q r3q +%if stereo + mov matrix1q, [matrix0q+gprsize] +%endif + mov matrix0q, [matrix0q] + +; define matrix coeff names +%assign %%i 0 +%assign %%j needed_mmregs +%rep in_channels + %if %%i >= matrix_elements_mm + CAT_XDEFINE mx_stack_0_, %%i, 1 + CAT_XDEFINE mx_0_, %%i, [rsp+(%%i-matrix_elements_mm)*mmsize] + %else + CAT_XDEFINE mx_stack_0_, %%i, 0 + CAT_XDEFINE mx_0_, %%i, m %+ %%j + %assign %%j %%j+1 + %endif + %assign %%i %%i+1 +%endrep +%if stereo +%assign %%i 0 +%rep in_channels + %if in_channels + %%i >= matrix_elements_mm + CAT_XDEFINE mx_stack_1_, %%i, 1 + CAT_XDEFINE mx_1_, %%i, [rsp+(in_channels+%%i-matrix_elements_mm)*mmsize] + %else + CAT_XDEFINE mx_stack_1_, %%i, 0 + CAT_XDEFINE mx_1_, %%i, m %+ %%j + %assign %%j %%j+1 + %endif + %assign %%i %%i+1 +%endrep +%endif + +; load/splat matrix coeffs +%assign %%i 0 +%rep in_channels + %if mx_stack_0_ %+ %%i + VBROADCASTSS m0, [matrix0q+4*%%i] + mova mx_0_ %+ %%i, m0 + %else + VBROADCASTSS mx_0_ %+ %%i, [matrix0q+4*%%i] + %endif + %if stereo + %if mx_stack_1_ %+ %%i + VBROADCASTSS m0, [matrix1q+4*%%i] + mova mx_1_ %+ %%i, m0 + %else + VBROADCASTSS mx_1_ %+ %%i, [matrix1q+4*%%i] + %endif + %endif + %assign %%i %%i+1 +%endrep + + lea lenq, [4*r2d] + ; load channel pointers to registers +%assign %%i 1 +%rep (in_channels - 1) + mov src %+ %%i %+ q, [src0q+%%i*gprsize] + add src %+ %%i %+ q, lenq + %assign %%i %%i+1 +%endrep + mov src0q, [src0q] + add src0q, lenq + neg lenq +.loop: + %if stereo || mx_stack_0_0 + mova m0, [src0q+lenq] + %endif + %if stereo + mulps m1, m0, mx_1_0 + %endif + %if stereo || mx_stack_0_0 + mulps m0, m0, mx_0_0 + %else + mulps m0, mx_0_0, [src0q+lenq] + %endif +%assign %%i 1 +%rep (in_channels - 1) + %define src_ptr src %+ %%i %+ q + ; avoid extra load for mono if matrix is in a mm register + %if stereo || mx_stack_0_ %+ %%i + mova m2, [src_ptr+lenq] + %endif + %if stereo + FMULADD_PS m1, m2, mx_1_ %+ %%i, m1, m3 + %endif + %if stereo || mx_stack_0_ %+ %%i + FMULADD_PS m0, m2, mx_0_ %+ %%i, m0, m2 + %else + FMULADD_PS m0, mx_0_ %+ %%i, [src_ptr+lenq], m0, m1 + %endif + %assign %%i %%i+1 +%endrep + mova [src0q+lenq], m0 + %if stereo + mova [src1q+lenq], m1 + %endif + + add lenq, mmsize + jl .loop + RET +%endmacro + +%macro AC3_DOWNMIX_FUNCS 0 +%assign %%i 3 +%rep 4 + INIT_XMM sse + AC3_DOWNMIX %%i, 1 + AC3_DOWNMIX %%i, 2 + INIT_YMM avx + AC3_DOWNMIX %%i, 1 + AC3_DOWNMIX %%i, 2 + %if HAVE_FMA3_EXTERNAL + INIT_YMM fma3 + AC3_DOWNMIX %%i, 1 + AC3_DOWNMIX %%i, 2 + %endif + %assign %%i %%i+1 +%endrep +%endmacro + +AC3_DOWNMIX_FUNCS diff --git a/libavcodec/x86/ac3dsp_init.c b/libavcodec/x86/ac3dsp_init.c index 9036389296b65..6d049b37cf028 100644 --- a/libavcodec/x86/ac3dsp_init.c +++ b/libavcodec/x86/ac3dsp_init.c @@ -63,135 +63,6 @@ void ff_apply_window_int16_ssse3(int16_t *output, const int16_t *input, void ff_apply_window_int16_ssse3_atom(int16_t *output, const int16_t *input, const int16_t *window, unsigned int len); -#if HAVE_SSE_INLINE && HAVE_7REGS - -#define IF1(x) x -#define IF0(x) - -#define MIX5(mono, stereo) \ - __asm__ volatile ( \ - "movss 0(%1), %%xmm5 \n" \ - "movss 4(%1), %%xmm6 \n" \ - "movss 12(%1), %%xmm7 \n" \ - "shufps $0, %%xmm5, %%xmm5 \n" \ - "shufps $0, %%xmm6, %%xmm6 \n" \ - "shufps $0, %%xmm7, %%xmm7 \n" \ - "1: \n" \ - "movaps (%0, %2), %%xmm0 \n" \ - "movaps (%0, %3), %%xmm1 \n" \ - "movaps (%0, %4), %%xmm2 \n" \ - "movaps (%0, %5), %%xmm3 \n" \ - "movaps (%0, %6), %%xmm4 \n" \ - "mulps %%xmm5, %%xmm0 \n" \ - "mulps %%xmm6, %%xmm1 \n" \ - "mulps %%xmm5, %%xmm2 \n" \ - "mulps %%xmm7, %%xmm3 \n" \ - "mulps %%xmm7, %%xmm4 \n" \ - stereo("addps %%xmm1, %%xmm0 \n") \ - "addps %%xmm1, %%xmm2 \n" \ - "addps %%xmm3, %%xmm0 \n" \ - "addps %%xmm4, %%xmm2 \n" \ - mono("addps %%xmm2, %%xmm0 \n") \ - "movaps %%xmm0, (%0, %2) \n" \ - stereo("movaps %%xmm2, (%0, %3) \n") \ - "add $16, %0 \n" \ - "jl 1b \n" \ - : "+&r"(i) \ - : "r"(matrix[0]), \ - "r"(samples[0] + len), \ - "r"(samples[1] + len), \ - "r"(samples[2] + len), \ - "r"(samples[3] + len), \ - "r"(samples[4] + len) \ - : XMM_CLOBBERS("%xmm0", "%xmm1", "%xmm2", "%xmm3", \ - "%xmm4", "%xmm5", "%xmm6", "%xmm7",) \ - "memory" \ - ); - -#define MIX_MISC(stereo) \ - __asm__ volatile ( \ - "mov %5, %2 \n" \ - "1: \n" \ - "mov -%c7(%6, %2, %c8), %3 \n" \ - "movaps (%3, %0), %%xmm0 \n" \ - stereo("movaps %%xmm0, %%xmm1 \n") \ - "mulps %%xmm4, %%xmm0 \n" \ - stereo("mulps %%xmm5, %%xmm1 \n") \ - "2: \n" \ - "mov (%6, %2, %c8), %1 \n" \ - "movaps (%1, %0), %%xmm2 \n" \ - stereo("movaps %%xmm2, %%xmm3 \n") \ - "mulps (%4, %2, 8), %%xmm2 \n" \ - stereo("mulps 16(%4, %2, 8), %%xmm3 \n") \ - "addps %%xmm2, %%xmm0 \n" \ - stereo("addps %%xmm3, %%xmm1 \n") \ - "add $4, %2 \n" \ - "jl 2b \n" \ - "mov %5, %2 \n" \ - stereo("mov (%6, %2, %c8), %1 \n") \ - "movaps %%xmm0, (%3, %0) \n" \ - stereo("movaps %%xmm1, (%1, %0) \n") \ - "add $16, %0 \n" \ - "jl 1b \n" \ - : "+&r"(i), "=&r"(j), "=&r"(k), "=&r"(m) \ - : "r"(matrix_simd + in_ch), \ - "g"((intptr_t) - 4 * (in_ch - 1)), \ - "r"(samp + in_ch), \ - "i"(sizeof(float *)), "i"(sizeof(float *)/4) \ - : "memory" \ - ); - -static void ac3_downmix_sse(float **samples, float **matrix, - int out_ch, int in_ch, int len) -{ - int **matrix_cmp = (int **)matrix; - intptr_t i, j, k, m; - - i = -len * sizeof(float); - if (in_ch == 5 && out_ch == 2 && - !(matrix_cmp[1][0] | matrix_cmp[0][2] | - matrix_cmp[1][3] | matrix_cmp[0][4] | - (matrix_cmp[0][1] ^ matrix_cmp[1][1]) | - (matrix_cmp[0][0] ^ matrix_cmp[1][2]))) { - MIX5(IF0, IF1); - } else if (in_ch == 5 && out_ch == 1 && - matrix_cmp[0][0] == matrix_cmp[0][2] && - matrix_cmp[0][3] == matrix_cmp[0][4]) { - MIX5(IF1, IF0); - } else { - DECLARE_ALIGNED(16, float, matrix_simd)[AC3_MAX_CHANNELS][2][4]; - float *samp[AC3_MAX_CHANNELS]; - - for (j = 0; j < in_ch; j++) - samp[j] = samples[j] + len; - - j = 2 * in_ch * sizeof(float); - k = in_ch * sizeof(float); - __asm__ volatile ( - "1: \n" - "sub $4, %1 \n" - "sub $8, %0 \n" - "movss (%3, %1), %%xmm4 \n" - "movss (%4, %1), %%xmm5 \n" - "shufps $0, %%xmm4, %%xmm4 \n" - "shufps $0, %%xmm5, %%xmm5 \n" - "movaps %%xmm4, (%2, %0, 4) \n" - "movaps %%xmm5, 16(%2, %0, 4) \n" - "jg 1b \n" - : "+&r"(j), "+&r"(k) - : "r"(matrix_simd), "r"(matrix[0]), "r"(matrix[1]) - : "memory" - ); - if (out_ch == 2) { - MIX_MISC(IF1); - } else { - MIX_MISC(IF0); - } - } -} - -#endif /* HAVE_SSE_INLINE && HAVE_7REGS */ - av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact) { int cpu_flags = av_get_cpu_flags(); @@ -247,10 +118,47 @@ av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact) c->apply_window_int16 = ff_apply_window_int16_ssse3; } } +} + +#define DOWNMIX_FUNC_OPT(ch, opt) \ +void ff_ac3_downmix_ ## ch ## _to_1_ ## opt(float **samples, \ + float **matrix, int len); \ +void ff_ac3_downmix_ ## ch ## _to_2_ ## opt(float **samples, \ + float **matrix, int len); + +#define DOWNMIX_FUNCS(opt) \ + DOWNMIX_FUNC_OPT(3, opt) \ + DOWNMIX_FUNC_OPT(4, opt) \ + DOWNMIX_FUNC_OPT(5, opt) \ + DOWNMIX_FUNC_OPT(6, opt) + +DOWNMIX_FUNCS(sse) +DOWNMIX_FUNCS(avx) +DOWNMIX_FUNCS(fma3) + +void ff_ac3dsp_set_downmix_x86(AC3DSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + +#define SET_DOWNMIX(ch, suf, SUF) \ + if (ch == c->in_channels) { \ + if (EXTERNAL_ ## SUF (cpu_flags)) { \ + if (c->out_channels == 1) \ + c->downmix = ff_ac3_downmix_ ## ch ## _to_1_ ## suf; \ + else \ + c->downmix = ff_ac3_downmix_ ## ch ## _to_2_ ## suf; \ + } \ + } + +#define SET_DOWNMIX_ALL(suf, SUF) \ + SET_DOWNMIX(3, suf, SUF) \ + SET_DOWNMIX(4, suf, SUF) \ + SET_DOWNMIX(5, suf, SUF) \ + SET_DOWNMIX(6, suf, SUF) -#if HAVE_SSE_INLINE && HAVE_7REGS - if (INLINE_SSE(cpu_flags)) { - c->downmix = ac3_downmix_sse; + SET_DOWNMIX_ALL(sse, SSE) + if (!(cpu_flags & AV_CPU_FLAG_AVXSLOW)) { + SET_DOWNMIX_ALL(avx, AVX) + SET_DOWNMIX_ALL(fma3, FMA3) } -#endif } From 2124711b950b03c582a119c75f52a87acc32d6ec Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 30 Sep 2016 21:21:46 +0200 Subject: [PATCH 0215/3374] hwcontext_vaapi: add a quirk for the missing MemoryType attribute The Intel binary iHD driver does not support the VASurfaceAttribMemoryType, so surface allocation will fail when using it. --- doc/APIchanges | 3 +++ libavutil/hwcontext_vaapi.c | 8 +++++++- libavutil/hwcontext_vaapi.h | 6 ++++++ libavutil/version.h | 2 +- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 6fd3959a330c9..655783edab9c8 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-xx-xx - xxxxxxx - lavu 55.23.0 - hwcontext_vaapi.h + Add AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE. + 2016-xx-xx - xxxxxxx - lavf 57.08.0 - avio.h Add AVIO_SEEKABLE_TIME flag. diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index bba0c4d701149..cd7d43eb8d325 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -273,6 +273,11 @@ static const struct { "i965", AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS, }, + { + "Intel iHD", + "ubit", + AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE, + }, }; static int vaapi_device_init(AVHWDeviceContext *hwdev) @@ -447,7 +452,8 @@ static int vaapi_frames_init(AVHWFramesContext *hwfc) } if (!hwfc->pool) { - int need_memory_type = 1, need_pixel_format = 1; + int need_memory_type = !(hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE); + int need_pixel_format = 1; for (i = 0; i < avfc->nb_attributes; i++) { if (ctx->attributes[i].type == VASurfaceAttribMemoryType) need_memory_type = 0; diff --git a/libavutil/hwcontext_vaapi.h b/libavutil/hwcontext_vaapi.h index 0ac4caa5bb446..9f1e78a4146bb 100644 --- a/libavutil/hwcontext_vaapi.h +++ b/libavutil/hwcontext_vaapi.h @@ -45,6 +45,12 @@ enum { * separately afterwards. */ AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS = (1 << 1), + + /** + * The driver does not support the VASurfaceAttribMemoryType attribute, + * so the surface allocation code will not try to use it. + */ + AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE = (1 << 2), }; /** diff --git a/libavutil/version.h b/libavutil/version.h index f05e72ce1379f..73de00e267c3a 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -54,7 +54,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 22 +#define LIBAVUTIL_VERSION_MINOR 23 #define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From 5bf2454e7cb03609b3ec1a3cf4c22427fe5f8e36 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 1 Oct 2016 10:03:05 +0200 Subject: [PATCH 0216/3374] h264dec: support broken files with mp4 extradata/annex b data Bug-Id: 966 --- libavcodec/h264dec.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 2c5a7db33abf4..330a74dcb4a14 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -530,7 +530,24 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size) if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Error splitting the input into NAL units.\n"); - return ret; + + /* There are samples in the wild with mp4-style extradata, but Annex B + * data in the packets. If we fail parsing the packet as mp4, try it again + * as Annex B. */ + if (h->is_avc && !(avctx->err_recognition & AV_EF_EXPLODE)) { + int err = ff_h2645_packet_split(&h->pkt, buf, buf_size, avctx, 0, 0, + avctx->codec_id); + if (err >= 0) { + av_log(avctx, AV_LOG_WARNING, + "The stream seems to contain AVCC extradata with Annex B " + "formatted data, which is invalid."); + h->is_avc = 0; + ret = 0; + } + } + + if (ret < 0) + return ret; } if (avctx->active_thread_type & FF_THREAD_FRAME) From d10102d23c9467d4eb84f58e0cd12be284b982f6 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 1 Oct 2016 11:47:23 +0200 Subject: [PATCH 0217/3374] avconv: set the encoding framerate when the output is CFR --- avconv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/avconv.c b/avconv.c index 59eb3009b1458..87923b9825c69 100644 --- a/avconv.c +++ b/avconv.c @@ -1978,6 +1978,8 @@ static int init_output_stream_encode(OutputStream *ost) ost->filter->filter->inputs[0]->sample_aspect_ratio; enc_ctx->pix_fmt = ost->filter->filter->inputs[0]->format; + enc_ctx->framerate = ost->frame_rate; + ost->st->avg_frame_rate = ost->frame_rate; if (dec_ctx && From f6772e9bf8251d3943f52f6f34d97d2ce6c4b8af Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 1 Oct 2016 17:06:25 +0200 Subject: [PATCH 0218/3374] avconv: make sure the filtergraph is freed on init failure The filtergraph's existence is used in several places to mean that the filtergraph is fully configured. This causes problems if it's allocated, but the initialization fails (e.g. if a non-existent filter is specified). --- avconv_filter.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/avconv_filter.c b/avconv_filter.c index 43308024f2535..e53dcd271c32e 100644 --- a/avconv_filter.c +++ b/avconv_filter.c @@ -709,7 +709,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++) { @@ -720,12 +720,13 @@ int configure_filtergraph(FilterGraph *fg) if (simple && (!inputs || inputs->next || !outputs || outputs->next)) { av_log(NULL, AV_LOG_ERROR, "Simple filtergraph '%s' does not have " "exactly one input and output.\n", graph_desc); - 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) - return ret; + goto fail; avfilter_inout_free(&inputs); for (cur = outputs, i = 0; cur; cur = cur->next, i++) { @@ -737,7 +738,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 */ @@ -761,7 +762,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; } } @@ -770,11 +771,14 @@ 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; } } return 0; +fail: + avfilter_graph_free(&fg->graph); + return ret; } int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame) From 27085d1b47c3741cc0fac284c916127c4066d049 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 1 Oct 2016 21:07:42 +0200 Subject: [PATCH 0219/3374] avconv: only retry decoding on actual decoding errors Errors during decoding are currently considered non-fatal and do not terminate transcoding, so even if parts of the data are corrupted, the rest may be decodable. However, that should apply only to the actual decoding calls, not to the failures elsewhere (e.g. configuring filters). --- avconv.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/avconv.c b/avconv.c index 87923b9825c69..0b75cbe21498f 100644 --- a/avconv.c +++ b/avconv.c @@ -1326,7 +1326,8 @@ int guess_input_channel_layout(InputStream *ist) return 1; } -static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) +static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output, + int *decode_failed) { AVFrame *decoded_frame, *f; AVCodecContext *avctx = ist->dec_ctx; @@ -1339,6 +1340,8 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) decoded_frame = ist->decoded_frame; ret = decode(avctx, decoded_frame, got_output, pkt); + if (ret < 0) + *decode_failed = 1; if (!*got_output || ret < 0) return ret; @@ -1377,7 +1380,8 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) return err < 0 ? err : ret; } -static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) +static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, + int *decode_failed) { AVFrame *decoded_frame, *f; int i, ret = 0, err = 0; @@ -1389,6 +1393,8 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) decoded_frame = ist->decoded_frame; ret = decode(ist->dec_ctx, decoded_frame, got_output, pkt); + if (ret < 0) + *decode_failed = 1; if (!*got_output || ret < 0) return ret; @@ -1429,13 +1435,16 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) return err < 0 ? err : ret; } -static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output) +static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output, + int *decode_failed) { AVSubtitle subtitle; int i, ret = avcodec_decode_subtitle2(ist->dec_ctx, &subtitle, got_output, pkt); - if (ret < 0) + if (ret < 0) { + *decode_failed = 1; return ret; + } if (!*got_output) return ret; @@ -1491,16 +1500,19 @@ static void process_input_packet(InputStream *ist, const AVPacket *pkt, int no_e while (ist->decoding_needed && (!pkt || avpkt.size > 0)) { int ret = 0; int got_output = 0; + int decode_failed = 0; if (!repeating) ist->last_dts = ist->next_dts; switch (ist->dec_ctx->codec_type) { case AVMEDIA_TYPE_AUDIO: - ret = decode_audio (ist, repeating ? NULL : &avpkt, &got_output); + ret = decode_audio (ist, repeating ? NULL : &avpkt, &got_output, + &decode_failed); break; case AVMEDIA_TYPE_VIDEO: - ret = decode_video (ist, repeating ? NULL : &avpkt, &got_output); + ret = decode_video (ist, repeating ? NULL : &avpkt, &got_output, + &decode_failed); if (repeating && !got_output) ; else if (pkt && pkt->duration) @@ -1517,16 +1529,21 @@ static void process_input_packet(InputStream *ist, const AVPacket *pkt, int no_e case AVMEDIA_TYPE_SUBTITLE: if (repeating) break; - ret = transcode_subtitles(ist, &avpkt, &got_output); + ret = transcode_subtitles(ist, &avpkt, &got_output, &decode_failed); break; default: return; } if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n", - ist->file_index, ist->st->index); - if (exit_on_error) + if (decode_failed) { + av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n", + ist->file_index, ist->st->index); + } else { + av_log(NULL, AV_LOG_FATAL, "Error while processing the decoded " + "data for stream #%d:%d\n", ist->file_index, ist->st->index); + } + if (!decode_failed || exit_on_error) exit_program(1); break; } From 22c3ab18646924ce24dc6017a9e882ff69689e40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sun, 2 Oct 2016 15:20:13 +0200 Subject: [PATCH 0220/3374] checkasm: Add test for huffyuvdsp add_bytes Signed-off-by: Luca Barbato --- tests/checkasm/Makefile | 1 + tests/checkasm/checkasm.c | 3 ++ tests/checkasm/checkasm.h | 1 + tests/checkasm/huffyuvdsp.c | 76 +++++++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+) create mode 100644 tests/checkasm/huffyuvdsp.c diff --git a/tests/checkasm/Makefile b/tests/checkasm/Makefile index f66c8b934ea7e..9b3df55673c5d 100644 --- a/tests/checkasm/Makefile +++ b/tests/checkasm/Makefile @@ -4,6 +4,7 @@ AVCODECOBJS-$(CONFIG_AUDIODSP) += audiodsp.o AVCODECOBJS-$(CONFIG_BLOCKDSP) += blockdsp.o AVCODECOBJS-$(CONFIG_BSWAPDSP) += bswapdsp.o AVCODECOBJS-$(CONFIG_FMTCONVERT) += fmtconvert.o +AVCODECOBJS-$(CONFIG_HUFFYUVDSP) += huffyuvdsp.o AVCODECOBJS-$(CONFIG_H264DSP) += h264dsp.o AVCODECOBJS-$(CONFIG_H264PRED) += h264pred.o AVCODECOBJS-$(CONFIG_H264QPEL) += h264qpel.o diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c index c279ed17fcb62..040c4ebdb333d 100644 --- a/tests/checkasm/checkasm.c +++ b/tests/checkasm/checkasm.c @@ -93,6 +93,9 @@ static const struct { { "hevc_mc", checkasm_check_hevc_mc }, { "hevc_idct", checkasm_check_hevc_idct }, #endif +#if CONFIG_HUFFYUVDSP + { "huffyuvdsp", checkasm_check_huffyuvdsp }, +#endif #if CONFIG_V210_ENCODER { "v210enc", checkasm_check_v210enc }, #endif diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h index 169aa2a600a72..5a4c056ce2241 100644 --- a/tests/checkasm/checkasm.h +++ b/tests/checkasm/checkasm.h @@ -41,6 +41,7 @@ void checkasm_check_h264pred(void); void checkasm_check_h264qpel(void); void checkasm_check_hevc_idct(void); void checkasm_check_hevc_mc(void); +void checkasm_check_huffyuvdsp(void); void checkasm_check_synth_filter(void); void checkasm_check_v210enc(void); void checkasm_check_vp8dsp(void); diff --git a/tests/checkasm/huffyuvdsp.c b/tests/checkasm/huffyuvdsp.c new file mode 100644 index 0000000000000..59e0f6a65afd9 --- /dev/null +++ b/tests/checkasm/huffyuvdsp.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2016 Alexandra Hájková + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with Libav; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include + +#include "libavutil/common.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/mem.h" + +#include "libavcodec/huffyuvdsp.h" + +#include "checkasm.h" + +#define randomize_buffers(buf, size) \ + do { \ + int j; \ + for (j = 0; j < size; j++) \ + buf[j] = rnd() & 0xFF; \ + } while (0) + +static void check_add_bytes(HuffYUVDSPContext c, int width) +{ + uint8_t *src0 = av_mallocz(width); + uint8_t *src1 = av_mallocz(width); + uint8_t *dst0 = av_mallocz(width); + uint8_t *dst1 = av_mallocz(width); + declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, uint8_t *src, int w); + + if (!src0 || !src1 || !dst0 || !dst1) + fail(); + + randomize_buffers(src0, width); + memcpy(src1, src0, width); + + if (check_func(c.add_bytes, "add_bytes")) { + call_ref(dst0, src0, width); + call_new(dst1, src1, width); + if (memcmp(dst0, dst1, width)) + fail(); + bench_new(dst1, src1, width); + } + + av_free(src0); + av_free(src1); + av_free(dst0); + av_free(dst1); +} + +void checkasm_check_huffyuvdsp(void) +{ + HuffYUVDSPContext c; + int width = 16 * av_clip(rnd(), 16, 128); + + ff_huffyuvdsp_init(&c); + + check_add_bytes(c, width); + + report("add_bytes"); +} From 1d25a86902946dbc80bb3a38e61755181ca3af7b Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sat, 1 Oct 2016 21:23:27 +0200 Subject: [PATCH 0221/3374] huffyuvdsp: Reenable PPC optimizations --- libavcodec/huffyuvdsp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/huffyuvdsp.c b/libavcodec/huffyuvdsp.c index b5a714d072f94..ff69b45d12c37 100644 --- a/libavcodec/huffyuvdsp.c +++ b/libavcodec/huffyuvdsp.c @@ -127,6 +127,8 @@ av_cold void ff_huffyuvdsp_init(HuffYUVDSPContext *c) c->add_hfyu_left_pred = add_hfyu_left_pred_c; c->add_hfyu_left_pred_bgr32 = add_hfyu_left_pred_bgr32_c; + if (ARCH_PPC) + ff_huffyuvdsp_init_ppc(c); if (ARCH_X86) ff_huffyuvdsp_init_x86(c); } From b015872c0d0823e70776e98b865509ec1287e2f6 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sat, 1 Oct 2016 21:28:39 +0200 Subject: [PATCH 0222/3374] huffyuvdsp: Enable the altivec code for PPC little-endian as well Confirmed to work by checkasm. --- libavcodec/ppc/huffyuvdsp_altivec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/ppc/huffyuvdsp_altivec.c b/libavcodec/ppc/huffyuvdsp_altivec.c index 337328ae0562e..7c34a67ea44c4 100644 --- a/libavcodec/ppc/huffyuvdsp_altivec.c +++ b/libavcodec/ppc/huffyuvdsp_altivec.c @@ -32,7 +32,7 @@ #include "libavutil/ppc/util_altivec.h" #include "libavcodec/huffyuvdsp.h" -#if HAVE_ALTIVEC && HAVE_BIGENDIAN +#if HAVE_ALTIVEC static void add_bytes_altivec(uint8_t *dst, uint8_t *src, int w) { register int i; @@ -49,14 +49,14 @@ static void add_bytes_altivec(uint8_t *dst, uint8_t *src, int w) for (; i < w; i++) dst[i] = src[i]; } -#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ +#endif /* HAVE_ALTIVEC */ av_cold void ff_huffyuvdsp_init_ppc(HuffYUVDSPContext *c) { -#if HAVE_ALTIVEC && HAVE_BIGENDIAN +#if HAVE_ALTIVEC if (!PPC_ALTIVEC(av_get_cpu_flags())) return; c->add_bytes = add_bytes_altivec; -#endif /* HAVE_ALTIVEC && HAVE_BIGENDIAN */ +#endif /* HAVE_ALTIVEC */ } From 13f5d2bf75b95a0bfdb9940a5e359a719e242bed Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 17 Jul 2016 18:32:15 +0200 Subject: [PATCH 0223/3374] configure: check for stdatomic.h Since this is a C11 feature, it requires -std=c11. Not actually used for anything yet, that will be added in the following commits. --- configure | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 3c416da8b8b32..b3ab2260768e6 100755 --- a/configure +++ b/configure @@ -986,6 +986,19 @@ check_cpp_condition(){ EOF } +test_cflags_cpp(){ + log test_cflags_cpp "$@" + flags=$1 + condition=$2 + shift 2 + set -- $($cflags_filter "$flags") + check_cpp "$@" <= 201112L"; then + add_cflags -std=c11 +else + check_cflags -std=c99 +fi + check_cc -D_FILE_OFFSET_BITS=64 < EOF @@ -4520,6 +4542,11 @@ check_header VideoDecodeAcceleration/VDADecoder.h check_header windows.h check_header X11/extensions/XvMClib.h +# it seems there are versions of clang in some distros that try to use the +# gcc headers, which explodes for stdatomic +# so we also check that atomics actually work here +check_builtin stdatomic_h stdatomic.h "atomic_int foo; atomic_store(&foo, 0)" + check_lib "windows.h shellapi.h" CommandLineToArgvW -lshell32 check_lib "windows.h wincrypt.h" CryptGenRandom -ladvapi32 check_lib "windows.h psapi.h" GetProcessMemoryInfo -lpsapi From 4e928ef340ac20325f529d92fcbc51e768085358 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 17 Jul 2016 18:56:33 +0200 Subject: [PATCH 0224/3374] Add a compat stdatomic.h implementation based on GCC atomics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adapted from the code by Rémi Denis-Courmont from VLC --- compat/atomics/gcc/stdatomic.h | 173 +++++++++++++++++++++++++++++++++ configure | 6 ++ 2 files changed, 179 insertions(+) create mode 100644 compat/atomics/gcc/stdatomic.h diff --git a/compat/atomics/gcc/stdatomic.h b/compat/atomics/gcc/stdatomic.h new file mode 100644 index 0000000000000..67168abb5e2d5 --- /dev/null +++ b/compat/atomics/gcc/stdatomic.h @@ -0,0 +1,173 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * based on vlc_atomic.h from VLC + * Copyright (C) 2010 Rémi Denis-Courmont + */ + +#ifndef LIBAV_COMPAT_ATOMICS_GCC_STDATOMIC_H +#define LIBAV_COMPAT_ATOMICS_GCC_STDATOMIC_H + +#include +#include + +#define ATOMIC_FLAG_INIT 0 + +#define ATOMIC_VAR_INIT(value) (value) + +#define atomic_init(obj, value) \ +do { \ + *(obj) = (value); \ +} while(0) + +#define kill_dependency(y) ((void)0) + +#define atomic_thread_fence(order) \ + __sync_synchronize() + +#define atomic_signal_fence(order) \ + ((void)0) + +#define atomic_is_lock_free(obj) 0 + +typedef _Bool atomic_flag; +typedef _Bool atomic_bool; +typedef char atomic_char; +typedef signed char atomic_schar; +typedef unsigned char atomic_uchar; +typedef short atomic_short; +typedef unsigned short atomic_ushort; +typedef int atomic_int; +typedef unsigned int atomic_uint; +typedef long atomic_long; +typedef unsigned long atomic_ulong; +typedef long long atomic_llong; +typedef unsigned long long atomic_ullong; +typedef wchar_t atomic_wchar_t; +typedef int_least8_t atomic_int_least8_t; +typedef uint_least8_t atomic_uint_least8_t; +typedef int_least16_t atomic_int_least16_t; +typedef uint_least16_t atomic_uint_least16_t; +typedef int_least32_t atomic_int_least32_t; +typedef uint_least32_t atomic_uint_least32_t; +typedef int_least64_t atomic_int_least64_t; +typedef uint_least64_t atomic_uint_least64_t; +typedef int_fast8_t atomic_int_fast8_t; +typedef uint_fast8_t atomic_uint_fast8_t; +typedef int_fast16_t atomic_int_fast16_t; +typedef uint_fast16_t atomic_uint_fast16_t; +typedef int_fast32_t atomic_int_fast32_t; +typedef uint_fast32_t atomic_uint_fast32_t; +typedef int_fast64_t atomic_int_fast64_t; +typedef uint_fast64_t atomic_uint_fast64_t; +typedef intptr_t atomic_intptr_t; +typedef uintptr_t atomic_uintptr_t; +typedef size_t atomic_size_t; +typedef ptrdiff_t atomic_ptrdiff_t; +typedef intmax_t atomic_intmax_t; +typedef uintmax_t atomic_uintmax_t; + +#define atomic_store(object, desired) \ +do { \ + *(object) = (desired); \ + __sync_synchronize(); \ +} while (0) + +#define atomic_store_explicit(object, desired, order) \ + atomic_store(object, desired) + +#define atomic_load(object) \ + (__sync_synchronize(), *(object)) + +#define atomic_load_explicit(object, order) \ + atomic_load(object) + +#define atomic_exchange(object, desired) \ +({ \ + typeof(object) _obj = (object); \ + typeof(*object) _old; \ + do \ + _old = atomic_load(_obj); \ + while (!__sync_bool_compare_and_swap(_obj, _old, (desired))); \ + _old; \ +}) + +#define atomic_exchange_explicit(object, desired, order) \ + atomic_exchange(object, desired) + +#define atomic_compare_exchange_strong(object, expected, desired) \ +({ \ + typeof(object) _exp = (expected); \ + typeof(*object) _old = *_exp; \ + *_exp = __sync_val_compare_and_swap((object), _old, (desired)); \ + *_exp == _old; \ +}) + +#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \ + atomic_compare_exchange_strong(object, expected, desired) + +#define atomic_compare_exchange_weak(object, expected, desired) \ + atomic_compare_exchange_strong(object, expected, desired) + +#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \ + atomic_compare_exchange_weak(object, expected, desired) + +#define atomic_fetch_add(object, operand) \ + __sync_fetch_and_add(object, operand) + +#define atomic_fetch_add_explicit(object, operand, order) \ + atomic_fetch_add(object, operand) + +#define atomic_fetch_sub(object, operand) \ + __sync_fetch_and_sub(object, operand) + +#define atomic_fetch_sub_explicit(object, operand, order) \ + atomic_fetch_sub(object, operand) + +#define atomic_fetch_or(object, operand) \ + __sync_fetch_and_or(object, operand) + +#define atomic_fetch_or_explicit(object, operand, order) \ + atomic_fetch_or(object, operand) + +#define atomic_fetch_xor(object, operand) \ + __sync_fetch_and_sub(object, operand) + +#define atomic_fetch_xor_explicit(object, operand, order) \ + atomic_fetch_sub(object, operand) + +#define atomic_fetch_and(object, operand) \ + __sync_fetch_and_and(object, operand) + +#define atomic_fetch_and_explicit(object, operand, order) \ + atomic_fetch_and(object, operand) + +#define atomic_flag_test_and_set(object) \ + atomic_exchange(object, 1) + +#define atomic_flag_test_and_set_explicit(object, order) \ + atomic_flag_test_and_set(object) + +#define atomic_flag_clear(object) \ + atomic_store(object, 0) + +#define atomic_flag_clear_explicit(object, order) \ + atomic_flag_clear(object) + +#endif /* LIBAV_COMPAT_ATOMICS_GCC_STDATOMIC_H */ diff --git a/configure b/configure index b3ab2260768e6..114beafdc409c 100755 --- a/configure +++ b/configure @@ -5073,6 +5073,12 @@ for thread in $THREADS_LIST; do fi done +if disabled stdatomic_h; then + if enabled atomics_gcc; then + add_cppflags '-I\$(SRC_PATH)/compat/atomics/gcc' + fi +fi + enabled zlib && add_cppflags -DZLIB_CONST # conditional library dependencies, in linking order From c2755864afadfbaa349e8d583665c86fe99fa90b Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 17 Jul 2016 18:56:33 +0200 Subject: [PATCH 0225/3374] Add a compat stdatomic.h implementation based on windows atomics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adapted from the code by Rémi Denis-Courmont from VLC --- compat/atomics/win32/stdatomic.h | 179 +++++++++++++++++++++++++++++++ configure | 2 + 2 files changed, 181 insertions(+) create mode 100644 compat/atomics/win32/stdatomic.h diff --git a/compat/atomics/win32/stdatomic.h b/compat/atomics/win32/stdatomic.h new file mode 100644 index 0000000000000..bdd39337a3d11 --- /dev/null +++ b/compat/atomics/win32/stdatomic.h @@ -0,0 +1,179 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIBAV_COMPAT_ATOMICS_WIN32_STDATOMIC_H +#define LIBAV_COMPAT_ATOMICS_WIN32_STDATOMIC_H + +#include +#include +#include + +#define ATOMIC_FLAG_INIT 0 + +#define ATOMIC_VAR_INIT(value) (value) + +#define atomic_init(obj, value) \ +do { \ + *(obj) = (value); \ +} while(0) + +#define kill_dependency(y) ((void)0) + +#define atomic_thread_fence(order) \ + MemoryBarrier(); + +#define atomic_signal_fence(order) \ + ((void)0) + +#define atomic_is_lock_free(obj) 0 + +typedef intptr_t atomic_flag; +typedef intptr_t atomic_bool; +typedef intptr_t atomic_char; +typedef intptr_t atomic_schar; +typedef intptr_t atomic_uchar; +typedef intptr_t atomic_short; +typedef intptr_t atomic_ushort; +typedef intptr_t atomic_int; +typedef intptr_t atomic_uint; +typedef intptr_t atomic_long; +typedef intptr_t atomic_ulong; +typedef intptr_t atomic_llong; +typedef intptr_t atomic_ullong; +typedef intptr_t atomic_wchar_t; +typedef intptr_t atomic_int_least8_t; +typedef intptr_t atomic_uint_least8_t; +typedef intptr_t atomic_int_least16_t; +typedef intptr_t atomic_uint_least16_t; +typedef intptr_t atomic_int_least32_t; +typedef intptr_t atomic_uint_least32_t; +typedef intptr_t atomic_int_least64_t; +typedef intptr_t atomic_uint_least64_t; +typedef intptr_t atomic_int_fast8_t; +typedef intptr_t atomic_uint_fast8_t; +typedef intptr_t atomic_int_fast16_t; +typedef intptr_t atomic_uint_fast16_t; +typedef intptr_t atomic_int_fast32_t; +typedef intptr_t atomic_uint_fast32_t; +typedef intptr_t atomic_int_fast64_t; +typedef intptr_t atomic_uint_fast64_t; +typedef intptr_t atomic_intptr_t; +typedef intptr_t atomic_uintptr_t; +typedef intptr_t atomic_size_t; +typedef intptr_t atomic_ptrdiff_t; +typedef intptr_t atomic_intmax_t; +typedef intptr_t atomic_uintmax_t; + +#define atomic_store(object, desired) \ +do { \ + *(object) = (desired); \ + MemoryBarrier(); \ +} while (0) + +#define atomic_store_explicit(object, desired, order) \ + atomic_store(object, desired) + +#define atomic_load(object) \ + (MemoryBarrier(), *(object)) + +#define atomic_load_explicit(object, order) \ + atomic_load(object) + +#define atomic_exchange(object, desired) \ + InterlockedExchangePointer(object, desired); + +#define atomic_exchange_explicit(object, desired, order) \ + atomic_exchange(object, desired) + +static inline int atomic_compare_exchange_strong(intptr_t *object, intptr_t *expected, + intptr_t desired) +{ + intptr_t old = *expected; + *expected = InterlockedCompareExchangePointer(object, desired, old); + return *expected == old; +} + +#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \ + atomic_compare_exchange_strong(object, expected, desired) + +#define atomic_compare_exchange_weak(object, expected, desired) \ + atomic_compare_exchange_strong(object, expected, desired) + +#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \ + atomic_compare_exchange_weak(object, expected, desired) + +#ifdef _WIN64 +#define atomic_fetch_add(object, operand) \ + InterlockedExchangeAdd64(object, operand) + +#define atomic_fetch_sub(object, operand) \ + InterlockedExchangeAdd64(object, -(operand)) + +#define atomic_fetch_or(object, operand) \ + InterlockedOr64(object, operand) + +#define atomic_fetch_xor(object, operand) \ + InterlockedXor64(object, operand) + +#define atomic_fetch_and(object, operand) \ + InterlockedAnd64(object, operand) +#else +#define atomic_fetch_add(object, operand) \ + InterlockedExchangeAdd(object, operand) + +#define atomic_fetch_sub(object, operand) \ + InterlockedExchangeAdd(object, -(operand)) + +#define atomic_fetch_or(object, operand) \ + InterlockedOr(object, operand) + +#define atomic_fetch_xor(object, operand) \ + InterlockedXor(object, operand) + +#define atomic_fetch_and(object, operand) \ + InterlockedAnd(object, operand) +#endif /* _WIN64 */ + +#define atomic_fetch_add_explicit(object, operand, order) \ + atomic_fetch_add(object, operand) + +#define atomic_fetch_sub_explicit(object, operand, order) \ + atomic_fetch_sub(object, operand) + +#define atomic_fetch_or_explicit(object, operand, order) \ + atomic_fetch_or(object, operand) + +#define atomic_fetch_xor_explicit(object, operand, order) \ + atomic_fetch_sub(object, operand) + +#define atomic_fetch_and_explicit(object, operand, order) \ + atomic_fetch_and(object, operand) + +#define atomic_flag_test_and_set(object) \ + atomic_exchange(object, 1) + +#define atomic_flag_test_and_set_explicit(object, order) \ + atomic_flag_test_and_set(object) + +#define atomic_flag_clear(object) \ + atomic_store(object, 0) + +#define atomic_flag_clear_explicit(object, order) \ + atomic_flag_clear(object) + +#endif /* LIBAV_COMPAT_ATOMICS_WIN32_STDATOMIC_H */ diff --git a/configure b/configure index 114beafdc409c..f9969a28f0622 100755 --- a/configure +++ b/configure @@ -5076,6 +5076,8 @@ done if disabled stdatomic_h; then if enabled atomics_gcc; then add_cppflags '-I\$(SRC_PATH)/compat/atomics/gcc' + elif enabled atomics_win32; then + add_cppflags '-I\$(SRC_PATH)/compat/atomics/win32' fi fi From bb81ed476569b912a37ed553e756e123b6b13b14 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 17 Jul 2016 18:56:33 +0200 Subject: [PATCH 0226/3374] Add a compat stdatomic.h implementation based on suncc atomics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adapted from the code by Rémi Denis-Courmont from VLC --- compat/atomics/suncc/stdatomic.h | 186 +++++++++++++++++++++++++++++++ configure | 2 + 2 files changed, 188 insertions(+) create mode 100644 compat/atomics/suncc/stdatomic.h diff --git a/compat/atomics/suncc/stdatomic.h b/compat/atomics/suncc/stdatomic.h new file mode 100644 index 0000000000000..32129aae5377a --- /dev/null +++ b/compat/atomics/suncc/stdatomic.h @@ -0,0 +1,186 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIBAV_COMPAT_ATOMICS_SUNCC_STDATOMIC_H +#define LIBAV_COMPAT_ATOMICS_SUNCC_STDATOMIC_H + +#include +#include +#include +#include + +#define ATOMIC_FLAG_INIT 0 + +#define ATOMIC_VAR_INIT(value) (value) + +#define atomic_init(obj, value) \ +do { \ + *(obj) = (value); \ +} while(0) + +#define kill_dependency(y) ((void)0) + +#define atomic_thread_fence(order) \ + __machine_rw_barrier(); + +#define atomic_signal_fence(order) \ + ((void)0) + +#define atomic_is_lock_free(obj) 0 + +typedef intptr_t atomic_flag; +typedef intptr_t atomic_bool; +typedef intptr_t atomic_char; +typedef intptr_t atomic_schar; +typedef intptr_t atomic_uchar; +typedef intptr_t atomic_short; +typedef intptr_t atomic_ushort; +typedef intptr_t atomic_int; +typedef intptr_t atomic_uint; +typedef intptr_t atomic_long; +typedef intptr_t atomic_ulong; +typedef intptr_t atomic_llong; +typedef intptr_t atomic_ullong; +typedef intptr_t atomic_wchar_t; +typedef intptr_t atomic_int_least8_t; +typedef intptr_t atomic_uint_least8_t; +typedef intptr_t atomic_int_least16_t; +typedef intptr_t atomic_uint_least16_t; +typedef intptr_t atomic_int_least32_t; +typedef intptr_t atomic_uint_least32_t; +typedef intptr_t atomic_int_least64_t; +typedef intptr_t atomic_uint_least64_t; +typedef intptr_t atomic_int_fast8_t; +typedef intptr_t atomic_uint_fast8_t; +typedef intptr_t atomic_int_fast16_t; +typedef intptr_t atomic_uint_fast16_t; +typedef intptr_t atomic_int_fast32_t; +typedef intptr_t atomic_uint_fast32_t; +typedef intptr_t atomic_int_fast64_t; +typedef intptr_t atomic_uint_fast64_t; +typedef intptr_t atomic_intptr_t; +typedef intptr_t atomic_uintptr_t; +typedef intptr_t atomic_size_t; +typedef intptr_t atomic_ptrdiff_t; +typedef intptr_t atomic_intmax_t; +typedef intptr_t atomic_uintmax_t; + +static inline void atomic_store(intptr_t *object, intptr_t desired) +{ + *object = desired; + __machine_rw_barrier(); +} + +#define atomic_store_explicit(object, desired, order) \ + atomic_store(object, desired) + +static inline intptr_t atomic_load(intptr_t *object) +{ + __machine_rw_barrier(); + return *object; +} + +#define atomic_load_explicit(object, order) \ + atomic_load(object) + +#define atomic_exchange(object, desired) \ + atomic_swap_ptr(object, desired) + +#define atomic_exchange_explicit(object, desired, order) \ + atomic_exchange(object, desired) + +static inline int atomic_compare_exchange_strong(intptr_t *object, intptr_t *expected, + intptr_t desired) +{ + intptr_t old = *expected; + *expected = atomic_cas_ptr(object, old, desired); + return *expected == old; +} + +#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \ + atomic_compare_exchange_strong(object, expected, desired) + +#define atomic_compare_exchange_weak(object, expected, desired) \ + atomic_compare_exchange_strong(object, expected, desired) + +#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \ + atomic_compare_exchange_weak(object, expected, desired) + +static inline intptr_t atomic_fetch_add(intptr_t *object, intptr_t operand) +{ + return atomic_add_ptr_nv(object, operand) - operand; +} + +#define atomic_fetch_sub(object, operand) \ + atomic_fetch_add(object, -(operand)) + +static inline intptr_t atomic_fetch_or(intptr_t *object, intptr_t operand) +{ + intptr_t old; + do { + old = atomic_load(object); + } while (!atomic_compare_exchange_strong(object, old, old | operand)); + return old; +} + +static inline intptr_t atomic_fetch_xor(intptr_t *object, intptr_t operand) +{ + intptr_t old; + do { + old = atomic_load(object); + } while (!atomic_compare_exchange_strong(object, old, old ^ operand)); + return old; +} + +static inline intptr_t atomic_fetch_and(intptr_t *object, intptr_t operand) +{ + intptr_t old; + do { + old = atomic_load(object); + } while (!atomic_compare_exchange_strong(object, old, old & operand)); + return old; +} + +#define atomic_fetch_add_explicit(object, operand, order) \ + atomic_fetch_add(object, operand) + +#define atomic_fetch_sub_explicit(object, operand, order) \ + atomic_fetch_sub(object, operand) + +#define atomic_fetch_or_explicit(object, operand, order) \ + atomic_fetch_or(object, operand) + +#define atomic_fetch_xor_explicit(object, operand, order) \ + atomic_fetch_sub(object, operand) + +#define atomic_fetch_and_explicit(object, operand, order) \ + atomic_fetch_and(object, operand) + +#define atomic_flag_test_and_set(object) \ + atomic_exchange(object, 1) + +#define atomic_flag_test_and_set_explicit(object, order) \ + atomic_flag_test_and_set(object) + +#define atomic_flag_clear(object) \ + atomic_store(object, 0) + +#define atomic_flag_clear_explicit(object, order) \ + atomic_flag_clear(object) + +#endif /* LIBAV_COMPAT_ATOMICS_SUNCC_STDATOMIC_H */ diff --git a/configure b/configure index f9969a28f0622..80a4b09a190b0 100755 --- a/configure +++ b/configure @@ -5078,6 +5078,8 @@ if disabled stdatomic_h; then add_cppflags '-I\$(SRC_PATH)/compat/atomics/gcc' elif enabled atomics_win32; then add_cppflags '-I\$(SRC_PATH)/compat/atomics/win32' + elif enabled atomics_suncc; then + add_cppflags '-I\$(SRC_PATH)/compat/atomics/suncc' fi fi From f9a6a80e065cdb95b233978f1d96ec9bc863daa1 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 17 Jul 2016 18:56:33 +0200 Subject: [PATCH 0227/3374] Add a compat stdatomic.h implementation based on pthreads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adapted from the code by Rémi Denis-Courmont from VLC --- compat/atomics/pthread/stdatomic.c | 39 ++++++ compat/atomics/pthread/stdatomic.h | 197 +++++++++++++++++++++++++++++ configure | 3 + 3 files changed, 239 insertions(+) create mode 100644 compat/atomics/pthread/stdatomic.c create mode 100644 compat/atomics/pthread/stdatomic.h diff --git a/compat/atomics/pthread/stdatomic.c b/compat/atomics/pthread/stdatomic.c new file mode 100644 index 0000000000000..0d1ecfec0de17 --- /dev/null +++ b/compat/atomics/pthread/stdatomic.c @@ -0,0 +1,39 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * based on vlc_atomic.h from VLC + * Copyright (C) 2010 Rémi Denis-Courmont + */ + +#include +#include + +#include "stdatomic.h" + +static pthread_mutex_t atomic_lock = PTHREAD_MUTEX_INITIALIZER; + +void avpriv_atomic_lock(void) +{ + pthread_mutex_lock(&atomic_lock); +} + +void avpriv_atomic_unlock(void) +{ + pthread_mutex_unlock(&atomic_lock); +} diff --git a/compat/atomics/pthread/stdatomic.h b/compat/atomics/pthread/stdatomic.h new file mode 100644 index 0000000000000..a4aa9bbbed721 --- /dev/null +++ b/compat/atomics/pthread/stdatomic.h @@ -0,0 +1,197 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * based on vlc_atomic.h from VLC + * Copyright (C) 2010 Rémi Denis-Courmont + */ + +#ifndef LIBAV_COMPAT_ATOMICS_PTHREAD_STDATOMIC_H +#define LIBAV_COMPAT_ATOMICS_PTHREAD_STDATOMIC_H + +#include + +#define ATOMIC_FLAG_INIT 0 + +#define ATOMIC_VAR_INIT(value) (value) + +#define atomic_init(obj, value) \ +do { \ + *(obj) = (value); \ +} while(0) + +#define kill_dependency(y) ((void)0) + +#define atomic_signal_fence(order) \ + ((void)0) + +#define atomic_is_lock_free(obj) 0 + +typedef intptr_t atomic_flag; +typedef intptr_t atomic_bool; +typedef intptr_t atomic_char; +typedef intptr_t atomic_schar; +typedef intptr_t atomic_uchar; +typedef intptr_t atomic_short; +typedef intptr_t atomic_ushort; +typedef intptr_t atomic_int; +typedef intptr_t atomic_uint; +typedef intptr_t atomic_long; +typedef intptr_t atomic_ulong; +typedef intptr_t atomic_llong; +typedef intptr_t atomic_ullong; +typedef intptr_t atomic_wchar_t; +typedef intptr_t atomic_int_least8_t; +typedef intptr_t atomic_uint_least8_t; +typedef intptr_t atomic_int_least16_t; +typedef intptr_t atomic_uint_least16_t; +typedef intptr_t atomic_int_least32_t; +typedef intptr_t atomic_uint_least32_t; +typedef intptr_t atomic_int_least64_t; +typedef intptr_t atomic_uint_least64_t; +typedef intptr_t atomic_int_fast8_t; +typedef intptr_t atomic_uint_fast8_t; +typedef intptr_t atomic_int_fast16_t; +typedef intptr_t atomic_uint_fast16_t; +typedef intptr_t atomic_int_fast32_t; +typedef intptr_t atomic_uint_fast32_t; +typedef intptr_t atomic_int_fast64_t; +typedef intptr_t atomic_uint_fast64_t; +typedef intptr_t atomic_intptr_t; +typedef intptr_t atomic_uintptr_t; +typedef intptr_t atomic_size_t; +typedef intptr_t atomic_ptrdiff_t; +typedef intptr_t atomic_intmax_t; +typedef intptr_t atomic_uintmax_t; + +void avpriv_atomic_lock(void); +void avpriv_atomic_unlock(void); + +static inline void atomic_thread_fence(int order) +{ + avpriv_atomic_lock(); + avpriv_atomic_unlock(); +} + +static inline void atomic_store(intptr_t *object, intptr_t desired) +{ + avpriv_atomic_lock(); + *object = desired; + avpriv_atomic_unlock(); +} + +#define atomic_store_explicit(object, desired, order) \ + atomic_store(object, desired) + +static inline intptr_t atomic_load(intptr_t *object) +{ + intptr_t ret; + avpriv_atomic_lock(); + ret = *object; + avpriv_atomic_unlock(); + return ret; +} + +#define atomic_load_explicit(object, order) \ + atomic_load(object) + +static inline intptr_t atomic_exchange(intptr_t *object, intptr_t desired) +{ + intptr_t ret; + avpriv_atomic_lock(); + ret = *object; + *object = desired; + avpriv_atomic_unlock(); + return ret; +} + +#define atomic_exchange_explicit(object, desired, order) \ + atomic_exchange(object, desired) + +static inline int atomic_compare_exchange_strong(intptr_t *object, intptr_t *expected, + intptr_t desired) +{ + int ret; + avpriv_atomic_lock(); + if (*object == *expected) { + ret = 1; + *object = desired; + } else { + ret = 0; + *expected = *object; + } + avpriv_atomic_unlock(); + return ret; +} + +#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \ + atomic_compare_exchange_strong(object, expected, desired) + +#define atomic_compare_exchange_weak(object, expected, desired) \ + atomic_compare_exchange_strong(object, expected, desired) + +#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \ + atomic_compare_exchange_weak(object, expected, desired) + +#define FETCH_MODIFY(opname, op) \ +static inline intptr_t atomic_fetch_ ## opname(intptr_t *object, intptr_t operand) \ +{ \ + intptr_t ret; \ + avpriv_atomic_lock(); \ + ret = *object; \ + *object = *object op operand; \ + avpriv_atomic_unlock(); \ + return ret; \ +} + +FETCH_MODIFY(add, +) +FETCH_MODIFY(sub, -) +FETCH_MODIFY(or, |) +FETCH_MODIFY(xor, ^) +FETCH_MODIFY(and, &) + +#undef FETCH_MODIFY + +#define atomic_fetch_add_explicit(object, operand, order) \ + atomic_fetch_add(object, operand) + +#define atomic_fetch_sub_explicit(object, operand, order) \ + atomic_fetch_sub(object, operand) + +#define atomic_fetch_or_explicit(object, operand, order) \ + atomic_fetch_or(object, operand) + +#define atomic_fetch_xor_explicit(object, operand, order) \ + atomic_fetch_sub(object, operand) + +#define atomic_fetch_and_explicit(object, operand, order) \ + atomic_fetch_and(object, operand) + +#define atomic_flag_test_and_set(object) \ + atomic_exchange(object, 1) + +#define atomic_flag_test_and_set_explicit(object, order) \ + atomic_flag_test_and_set(object) + +#define atomic_flag_clear(object) \ + atomic_store(object, 0) + +#define atomic_flag_clear_explicit(object, order) \ + atomic_flag_clear(object) + +#endif /* LIBAV_COMPAT_ATOMICS_PTHREAD_STDATOMIC_H */ diff --git a/configure b/configure index 80a4b09a190b0..e61d12861dc6a 100755 --- a/configure +++ b/configure @@ -5080,6 +5080,9 @@ if disabled stdatomic_h; then add_cppflags '-I\$(SRC_PATH)/compat/atomics/win32' elif enabled atomics_suncc; then add_cppflags '-I\$(SRC_PATH)/compat/atomics/suncc' + elif enabled pthreads; then + add_compat atomics/pthread/stdatomic.o + add_cppflags '-I\$(SRC_PATH)/compat/atomics/pthread' fi fi From eb34d40354e2474517c9b9bd787e0dadc89c2a81 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 17 Jul 2016 18:56:33 +0200 Subject: [PATCH 0228/3374] Add a compat dummy stdatomic.h used when threading is disabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adapted from the code by Rémi Denis-Courmont from VLC --- compat/atomics/dummy/stdatomic.h | 176 +++++++++++++++++++++++++++++++ configure | 3 + 2 files changed, 179 insertions(+) create mode 100644 compat/atomics/dummy/stdatomic.h diff --git a/compat/atomics/dummy/stdatomic.h b/compat/atomics/dummy/stdatomic.h new file mode 100644 index 0000000000000..374e1e5e1790f --- /dev/null +++ b/compat/atomics/dummy/stdatomic.h @@ -0,0 +1,176 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * based on vlc_atomic.h from VLC + * Copyright (C) 2010 Rémi Denis-Courmont + */ + +#ifndef LIBAV_COMPAT_ATOMICS_DUMMY_STDATOMIC_H +#define LIBAV_COMPAT_ATOMICS_DUMMY_STDATOMIC_H + +#include + +#define ATOMIC_FLAG_INIT 0 + +#define ATOMIC_VAR_INIT(value) (value) + +#define atomic_init(obj, value) \ +do { \ + *(obj) = (value); \ +} while(0) + +#define kill_dependency(y) ((void)0) + +#define atomic_thread_fence(order) \ + ((void)0) + +#define atomic_signal_fence(order) \ + ((void)0) + +#define atomic_is_lock_free(obj) 0 + +typedef intptr_t atomic_flag; +typedef intptr_t atomic_bool; +typedef intptr_t atomic_char; +typedef intptr_t atomic_schar; +typedef intptr_t atomic_uchar; +typedef intptr_t atomic_short; +typedef intptr_t atomic_ushort; +typedef intptr_t atomic_int; +typedef intptr_t atomic_uint; +typedef intptr_t atomic_long; +typedef intptr_t atomic_ulong; +typedef intptr_t atomic_llong; +typedef intptr_t atomic_ullong; +typedef intptr_t atomic_wchar_t; +typedef intptr_t atomic_int_least8_t; +typedef intptr_t atomic_uint_least8_t; +typedef intptr_t atomic_int_least16_t; +typedef intptr_t atomic_uint_least16_t; +typedef intptr_t atomic_int_least32_t; +typedef intptr_t atomic_uint_least32_t; +typedef intptr_t atomic_int_least64_t; +typedef intptr_t atomic_uint_least64_t; +typedef intptr_t atomic_int_fast8_t; +typedef intptr_t atomic_uint_fast8_t; +typedef intptr_t atomic_int_fast16_t; +typedef intptr_t atomic_uint_fast16_t; +typedef intptr_t atomic_int_fast32_t; +typedef intptr_t atomic_uint_fast32_t; +typedef intptr_t atomic_int_fast64_t; +typedef intptr_t atomic_uint_fast64_t; +typedef intptr_t atomic_intptr_t; +typedef intptr_t atomic_uintptr_t; +typedef intptr_t atomic_size_t; +typedef intptr_t atomic_ptrdiff_t; +typedef intptr_t atomic_intmax_t; +typedef intptr_t atomic_uintmax_t; + +#define atomic_store(object, desired) \ +do { \ + *(object) = (desired); \ +} while (0) + +#define atomic_store_explicit(object, desired, order) \ + atomic_store(object, desired) + +#define atomic_load(object) \ + (*(object)) + +#define atomic_load_explicit(object, order) \ + atomic_load(object) + +static inline intptr_t atomic_exchange(intptr_t *object, intptr_t desired) +{ + intptr_t ret = *object; + *object = desired; + return ret; +} + +#define atomic_exchange_explicit(object, desired, order) \ + atomic_exchange(object, desired) + +static inline int atomic_compare_exchange_strong(intptr_t *object, intptr_t *expected, + intptr_t desired) +{ + int ret; + if (*object == *expected) { + *object = desired; + ret = 1; + } else { + *expected = *object; + ret = 0; + } + return ret; +} + +#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \ + atomic_compare_exchange_strong(object, expected, desired) + +#define atomic_compare_exchange_weak(object, expected, desired) \ + atomic_compare_exchange_strong(object, expected, desired) + +#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \ + atomic_compare_exchange_weak(object, expected, desired) + +#define FETCH_MODIFY(opname, op) \ +static inline intptr_t atomic_fetch_ ## opname(intptr_t *object, intptr_t operand) \ +{ \ + intptr_t ret; \ + ret = *object; \ + *object = *object op operand; \ + return ret; \ +} + +FETCH_MODIFY(add, +) +FETCH_MODIFY(sub, -) +FETCH_MODIFY(or, |) +FETCH_MODIFY(xor, ^) +FETCH_MODIFY(and, &) + +#undef FETCH_MODIFY + +#define atomic_fetch_add_explicit(object, operand, order) \ + atomic_fetch_add(object, operand) + +#define atomic_fetch_sub_explicit(object, operand, order) \ + atomic_fetch_sub(object, operand) + +#define atomic_fetch_or_explicit(object, operand, order) \ + atomic_fetch_or(object, operand) + +#define atomic_fetch_xor_explicit(object, operand, order) \ + atomic_fetch_sub(object, operand) + +#define atomic_fetch_and_explicit(object, operand, order) \ + atomic_fetch_and(object, operand) + +#define atomic_flag_test_and_set(object) \ + atomic_exchange(object, 1) + +#define atomic_flag_test_and_set_explicit(object, order) \ + atomic_flag_test_and_set(object) + +#define atomic_flag_clear(object) \ + atomic_store(object, 0) + +#define atomic_flag_clear_explicit(object, order) \ + atomic_flag_clear(object) + +#endif /* LIBAV_COMPAT_ATOMICS_DUMMY_STDATOMIC_H */ diff --git a/configure b/configure index e61d12861dc6a..7ac05cfadaacf 100755 --- a/configure +++ b/configure @@ -5083,6 +5083,9 @@ if disabled stdatomic_h; then elif enabled pthreads; then add_compat atomics/pthread/stdatomic.o add_cppflags '-I\$(SRC_PATH)/compat/atomics/pthread' + else + enabled threads && die "Threading is enabled, but no atomics are available" + add_cppflags '-I\$(SRC_PATH)/compat/atomics/dummy' fi fi From 27079a426c9d3db918b158976e44b9b143d78e1c Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 17 Jul 2016 22:24:35 +0200 Subject: [PATCH 0229/3374] buffer: convert to stdatomic --- libavutil/buffer.c | 21 +++++++++++---------- libavutil/buffer_internal.h | 5 +++-- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/libavutil/buffer.c b/libavutil/buffer.c index 49a1f2d39558c..0e2b4ef1b45b8 100644 --- a/libavutil/buffer.c +++ b/libavutil/buffer.c @@ -16,10 +16,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include #include -#include "atomic.h" #include "buffer_internal.h" #include "common.h" #include "mem.h" @@ -40,7 +40,8 @@ AVBufferRef *av_buffer_create(uint8_t *data, int size, buf->size = size; buf->free = free ? free : av_buffer_default_free; buf->opaque = opaque; - buf->refcount = 1; + + atomic_init(&buf->refcount, 1); if (flags & AV_BUFFER_FLAG_READONLY) buf->flags |= BUFFER_FLAG_READONLY; @@ -98,7 +99,7 @@ AVBufferRef *av_buffer_ref(AVBufferRef *buf) *ret = *buf; - avpriv_atomic_int_add_and_fetch(&buf->buffer->refcount, 1); + atomic_fetch_add_explicit(&buf->buffer->refcount, 1, memory_order_relaxed); return ret; } @@ -112,7 +113,7 @@ void av_buffer_unref(AVBufferRef **buf) b = (*buf)->buffer; av_freep(buf); - if (!avpriv_atomic_int_add_and_fetch(&b->refcount, -1)) { + if (atomic_fetch_add_explicit(&b->refcount, -1, memory_order_acq_rel) == 1) { b->free(b->opaque, b->data); av_freep(&b); } @@ -123,7 +124,7 @@ int av_buffer_is_writable(const AVBufferRef *buf) if (buf->buffer->flags & AV_BUFFER_FLAG_READONLY) return 0; - return avpriv_atomic_int_add_and_fetch(&buf->buffer->refcount, 0) == 1; + return atomic_load(&buf->buffer->refcount) == 1; } int av_buffer_make_writable(AVBufferRef **pbuf) @@ -209,7 +210,7 @@ AVBufferPool *av_buffer_pool_init2(int size, void *opaque, pool->alloc2 = alloc; pool->pool_free = pool_free; - avpriv_atomic_int_set(&pool->refcount, 1); + atomic_init(&pool->refcount, 1); return pool; } @@ -225,7 +226,7 @@ AVBufferPool *av_buffer_pool_init(int size, AVBufferRef* (*alloc)(int size)) pool->size = size; pool->alloc = alloc ? alloc : av_buffer_alloc; - avpriv_atomic_int_set(&pool->refcount, 1); + atomic_init(&pool->refcount, 1); return pool; } @@ -260,7 +261,7 @@ void av_buffer_pool_uninit(AVBufferPool **ppool) pool = *ppool; *ppool = NULL; - if (!avpriv_atomic_int_add_and_fetch(&pool->refcount, -1)) + if (atomic_fetch_add_explicit(&pool->refcount, -1, memory_order_acq_rel) == 1) buffer_pool_free(pool); } @@ -274,7 +275,7 @@ static void pool_release_buffer(void *opaque, uint8_t *data) pool->pool = buf; ff_mutex_unlock(&pool->mutex); - if (!avpriv_atomic_int_add_and_fetch(&pool->refcount, -1)) + if (atomic_fetch_add_explicit(&pool->refcount, -1, memory_order_acq_rel) == 1) buffer_pool_free(pool); } @@ -327,7 +328,7 @@ AVBufferRef *av_buffer_pool_get(AVBufferPool *pool) ff_mutex_unlock(&pool->mutex); if (ret) - avpriv_atomic_int_add_and_fetch(&pool->refcount, 1); + atomic_fetch_add_explicit(&pool->refcount, 1, memory_order_relaxed); return ret; } diff --git a/libavutil/buffer_internal.h b/libavutil/buffer_internal.h index 64344d8262b5f..90d68aacacbca 100644 --- a/libavutil/buffer_internal.h +++ b/libavutil/buffer_internal.h @@ -19,6 +19,7 @@ #ifndef AVUTIL_BUFFER_INTERNAL_H #define AVUTIL_BUFFER_INTERNAL_H +#include #include #include "buffer.h" @@ -40,7 +41,7 @@ struct AVBuffer { /** * number of existing AVBufferRef instances referring to this buffer */ - volatile int refcount; + atomic_uint refcount; /** * a callback for freeing the data @@ -85,7 +86,7 @@ struct AVBufferPool { * buffers have been released, then it's safe to free the pool and all * the buffers in it. */ - volatile int refcount; + atomic_uint refcount; int size; void *opaque; From 3a165c187da7d74f46f6c1778294e8c5a3a7151f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 17 Jul 2016 22:24:35 +0200 Subject: [PATCH 0230/3374] v4l2: convert to stdatomic --- libavdevice/v4l2.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c index 47241e47a1fbb..0479121d7dab8 100644 --- a/libavdevice/v4l2.c +++ b/libavdevice/v4l2.c @@ -33,6 +33,7 @@ #include "libavformat/internal.h" #include #include +#include #include #include #include @@ -42,7 +43,6 @@ #else #include #endif -#include "libavutil/atomic.h" #include "libavutil/avassert.h" #include "libavutil/imgutils.h" #include "libavutil/internal.h" @@ -70,7 +70,7 @@ struct video_data { int top_field_first; int buffers; - volatile int buffers_queued; + atomic_int buffers_queued; void **buf_start; unsigned int *buf_len; char *standard; @@ -441,7 +441,7 @@ static void mmap_release_buffer(void *opaque, uint8_t *data) av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", errbuf); } - avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1); + atomic_fetch_add(&s->buffers_queued, 1); } static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt) @@ -482,9 +482,9 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt) av_log(ctx, AV_LOG_ERROR, "Invalid buffer index received.\n"); return AVERROR(EINVAL); } - avpriv_atomic_int_add_and_fetch(&s->buffers_queued, -1); + atomic_fetch_add(&s->buffers_queued, -1); // always keep at least one buffer queued - av_assert0(avpriv_atomic_int_get(&s->buffers_queued) >= 1); + av_assert0(atomic_load(&s->buffers_queued) >= 1); if (s->frame_size > 0 && buf.bytesused != s->frame_size) { av_log(ctx, AV_LOG_ERROR, @@ -495,7 +495,7 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt) } /* Image is at s->buff_start[buf.index] */ - if (avpriv_atomic_int_get(&s->buffers_queued) == FFMAX(s->buffers / 8, 1)) { + if (atomic_load(&s->buffers_queued) == FFMAX(s->buffers / 8, 1)) { /* when we start getting low on queued buffers, fall back on copying data */ res = av_new_packet(pkt, buf.bytesused); if (res < 0) { @@ -511,7 +511,7 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt) av_packet_unref(pkt); return res; } - avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1); + atomic_fetch_add(&s->buffers_queued, 1); } else { struct buff_data *buf_descriptor; @@ -568,7 +568,7 @@ static int mmap_start(AVFormatContext *ctx) return err; } } - s->buffers_queued = s->buffers; + atomic_store(&s->buffers_queued, s->buffers); type = V4L2_BUF_TYPE_VIDEO_CAPTURE; res = ioctl(s->fd, VIDIOC_STREAMON, &type); @@ -881,7 +881,7 @@ static int v4l2_read_close(AVFormatContext *s1) { struct video_data *s = s1->priv_data; - if (avpriv_atomic_int_get(&s->buffers_queued) != s->buffers) + if (atomic_load(&s->buffers_queued) != s->buffers) av_log(s1, AV_LOG_WARNING, "Some buffers are still owned by the caller on " "close.\n"); From 8385ba53f115401a67a4748c0d107769ebfb2941 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 17 Jul 2016 22:24:35 +0200 Subject: [PATCH 0231/3374] mmaldec: convert to stdatomic --- libavcodec/mmaldec.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/libavcodec/mmaldec.c b/libavcodec/mmaldec.c index 69258a2eb66f9..924bfb2e263fb 100644 --- a/libavcodec/mmaldec.c +++ b/libavcodec/mmaldec.c @@ -31,10 +31,10 @@ #include #include #include +#include #include "avcodec.h" #include "internal.h" -#include "libavutil/atomic.h" #include "libavutil/avassert.h" #include "libavutil/buffer.h" #include "libavutil/common.h" @@ -55,7 +55,7 @@ typedef struct FFBufferEntry { // refcounting for AVFrames, we can free the MMAL_POOL_T only after all AVFrames // have been unreferenced. typedef struct FFPoolRef { - volatile int refcount; + atomic_int refcount; MMAL_POOL_T *pool; } FFPoolRef; @@ -83,7 +83,7 @@ typedef struct MMALDecodeContext { FFBufferEntry *waiting_buffers, *waiting_buffers_tail; int64_t packets_sent; - volatile int packets_buffered; + atomic_int packets_buffered; int64_t frames_output; int eos_received; int eos_sent; @@ -96,7 +96,8 @@ typedef struct MMALDecodeContext { static void ffmmal_poolref_unref(FFPoolRef *ref) { - if (ref && avpriv_atomic_int_add_and_fetch(&ref->refcount, -1) == 0) { + if (ref && + atomic_fetch_add_explicit(&ref->refcount, -1, memory_order_acq_rel) == 1) { mmal_pool_destroy(ref->pool); av_free(ref); } @@ -132,7 +133,7 @@ static int ffmmal_set_ref(AVFrame *frame, FFPoolRef *pool, return AVERROR(ENOMEM); } - avpriv_atomic_int_add_and_fetch(&ref->pool->refcount, 1); + atomic_fetch_add_explicit(&ref->pool->refcount, 1, memory_order_relaxed); mmal_buffer_header_acquire(buffer); frame->format = AV_PIX_FMT_MMAL; @@ -163,14 +164,14 @@ static void ffmmal_stop_decoder(AVCodecContext *avctx) ctx->waiting_buffers = buffer->next; if (buffer->flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END) - avpriv_atomic_int_add_and_fetch(&ctx->packets_buffered, -1); + atomic_fetch_add(&ctx->packets_buffered, -1); av_buffer_unref(&buffer->ref); av_free(buffer); } ctx->waiting_buffers_tail = NULL; - av_assert0(avpriv_atomic_int_get(&ctx->packets_buffered) == 0); + av_assert0(atomic_load(&ctx->packets_buffered) == 0); ctx->frames_output = ctx->eos_received = ctx->eos_sent = ctx->packets_sent = ctx->extradata_sent = 0; } @@ -202,7 +203,7 @@ static void input_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) FFBufferEntry *entry = buffer->user_data; av_buffer_unref(&entry->ref); if (entry->flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END) - avpriv_atomic_int_add_and_fetch(&ctx->packets_buffered, -1); + atomic_fetch_add(&ctx->packets_buffered, -1); av_free(entry); } mmal_buffer_header_release(buffer); @@ -280,7 +281,7 @@ static int ffmal_update_format(AVCodecContext *avctx) ret = AVERROR(ENOMEM); goto fail; } - ctx->pool_out->refcount = 1; + atomic_store(&ctx->pool_out->refcount, 1); if (!format_out) goto fail; @@ -522,7 +523,7 @@ static int ffmmal_add_packet(AVCodecContext *avctx, AVPacket *avpkt, if (!size) { buffer->flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END; - avpriv_atomic_int_add_and_fetch(&ctx->packets_buffered, 1); + atomic_fetch_add(&ctx->packets_buffered, 1); } if (!buffer->length) { @@ -587,7 +588,7 @@ static int ffmmal_fill_input_port(AVCodecContext *avctx) mmal_buffer_header_release(mbuffer); av_buffer_unref(&buffer->ref); if (buffer->flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END) - avpriv_atomic_int_add_and_fetch(&ctx->packets_buffered, -1); + atomic_fetch_add(&ctx->packets_buffered, -1); av_free(buffer); } @@ -666,7 +667,7 @@ static int ffmmal_read_frame(AVCodecContext *avctx, AVFrame *frame, int *got_fra // excessive buffering. // We also wait if we sent eos, but didn't receive it yet (think of decoding // stream with a very low number of frames). - if (avpriv_atomic_int_get(&ctx->packets_buffered) > MAX_DELAYED_FRAMES || + if (atomic_load(&ctx->packets_buffered) > MAX_DELAYED_FRAMES || (ctx->packets_sent && ctx->eos_sent)) { // MMAL will ignore broken input packets, which means the frame we // expect here may never arrive. Dealing with this correctly is From db2733256db323e4b88a34b135320f33274148e2 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 17 Jul 2016 23:30:52 +0200 Subject: [PATCH 0232/3374] pthread_frame: use a thread-safe way for signalling threads to die Current code uses a plain int in a racy way, which is UB. --- libavcodec/pthread_frame.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index c72da533aa65d..0549f421dbb49 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -90,6 +90,8 @@ typedef struct PerThreadContext { AVFrame *requested_frame; ///< AVFrame the codec passed to get_buffer() int requested_flags; ///< flags passed to get_buffer() for requested_frame + + int die; ///< Set when the thread should exit. } PerThreadContext; /** @@ -108,8 +110,6 @@ typedef struct FrameThreadContext { * Set for the first N packets, where N is the number of threads. * While it is set, ff_thread_en/decode_frame won't return any results. */ - - int die; ///< Set when threads should exit. } FrameThreadContext; /** @@ -122,20 +122,22 @@ typedef struct FrameThreadContext { static attribute_align_arg void *frame_worker_thread(void *arg) { PerThreadContext *p = arg; - FrameThreadContext *fctx = p->parent; AVCodecContext *avctx = p->avctx; const AVCodec *codec = avctx->codec; while (1) { - if (p->state == STATE_INPUT_READY && !fctx->die) { + if (p->state == STATE_INPUT_READY) { pthread_mutex_lock(&p->mutex); - while (p->state == STATE_INPUT_READY && !fctx->die) + while (p->state == STATE_INPUT_READY) { + if (p->die) { + pthread_mutex_unlock(&p->mutex); + goto die; + } pthread_cond_wait(&p->input_cond, &p->mutex); + } pthread_mutex_unlock(&p->mutex); } - if (fctx->die) break; - if (!codec->update_thread_context && avctx->thread_safe_callbacks) ff_thread_finish_setup(avctx); @@ -161,6 +163,7 @@ static attribute_align_arg void *frame_worker_thread(void *arg) pthread_mutex_unlock(&p->mutex); } +die: return NULL; } @@ -504,12 +507,11 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) if (fctx->prev_thread && fctx->prev_thread != fctx->threads) update_context_from_thread(fctx->threads->avctx, fctx->prev_thread->avctx, 0); - fctx->die = 1; - for (i = 0; i < thread_count; i++) { PerThreadContext *p = &fctx->threads[i]; pthread_mutex_lock(&p->mutex); + p->die = 1; pthread_cond_signal(&p->input_cond); pthread_mutex_unlock(&p->mutex); From 64a31b2854c589e4f27cd68ebe3bcceb915704e5 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 18 Jul 2016 00:04:16 +0200 Subject: [PATCH 0233/3374] pthread_frame: use atomics for PerThreadContext.state --- libavcodec/pthread_frame.c | 67 ++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 0549f421dbb49..400279010d149 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -24,6 +24,7 @@ #include "config.h" +#include #include #if HAVE_PTHREADS @@ -47,6 +48,20 @@ #include "libavutil/log.h" #include "libavutil/mem.h" +enum { + ///< Set when the thread is awaiting a packet. + STATE_INPUT_READY, + ///< Set before the codec has called ff_thread_finish_setup(). + STATE_SETTING_UP, + /** + * Set when the codec calls get_buffer(). + * State is returned to STATE_SETTING_UP afterwards. + */ + STATE_GET_BUFFER, + ///< Set after the codec has called ff_thread_finish_setup(). + STATE_SETUP_FINISHED, +}; + /** * Context used by codec threads and stored in their AVCodecInternal thread_ctx. */ @@ -70,15 +85,7 @@ typedef struct PerThreadContext { int got_frame; ///< The output of got_picture_ptr from the last avcodec_decode_video() call. int result; ///< The result of the last codec decode/encode() call. - enum { - STATE_INPUT_READY, ///< Set when the thread is awaiting a packet. - STATE_SETTING_UP, ///< Set before the codec has called ff_thread_finish_setup(). - STATE_GET_BUFFER, /**< - * Set when the codec calls get_buffer(). - * State is returned to STATE_SETTING_UP afterwards. - */ - STATE_SETUP_FINISHED ///< Set after the codec has called ff_thread_finish_setup(). - } state; + atomic_int state; /** * Array of frames passed to ff_thread_release_buffer(). @@ -126,9 +133,9 @@ static attribute_align_arg void *frame_worker_thread(void *arg) const AVCodec *codec = avctx->codec; while (1) { - if (p->state == STATE_INPUT_READY) { + if (atomic_load(&p->state) == STATE_INPUT_READY) { pthread_mutex_lock(&p->mutex); - while (p->state == STATE_INPUT_READY) { + while (atomic_load(&p->state) == STATE_INPUT_READY) { if (p->die) { pthread_mutex_unlock(&p->mutex); goto die; @@ -153,9 +160,10 @@ static attribute_align_arg void *frame_worker_thread(void *arg) av_frame_unref(p->frame); } - if (p->state == STATE_SETTING_UP) ff_thread_finish_setup(avctx); + if (atomic_load(&p->state) == STATE_SETTING_UP) + ff_thread_finish_setup(avctx); - p->state = STATE_INPUT_READY; + atomic_store(&p->state, STATE_INPUT_READY); pthread_mutex_lock(&p->progress_mutex); pthread_cond_signal(&p->output_cond); @@ -310,9 +318,9 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt) if (prev_thread) { int err; - if (prev_thread->state == STATE_SETTING_UP) { + if (atomic_load(&prev_thread->state) == STATE_SETTING_UP) { pthread_mutex_lock(&prev_thread->progress_mutex); - while (prev_thread->state == STATE_SETTING_UP) + while (atomic_load(&prev_thread->state) == STATE_SETTING_UP) pthread_cond_wait(&prev_thread->progress_cond, &prev_thread->progress_mutex); pthread_mutex_unlock(&prev_thread->progress_mutex); } @@ -327,7 +335,7 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt) av_packet_unref(&p->avpkt); av_packet_ref(&p->avpkt, avpkt); - p->state = STATE_SETTING_UP; + atomic_store(&p->state, STATE_SETTING_UP); pthread_cond_signal(&p->input_cond); pthread_mutex_unlock(&p->mutex); @@ -339,14 +347,15 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt) if (!p->avctx->thread_safe_callbacks && p->avctx->get_buffer2 != avcodec_default_get_buffer2) { - while (p->state != STATE_SETUP_FINISHED && p->state != STATE_INPUT_READY) { + while (atomic_load(&p->state) != STATE_SETUP_FINISHED && + atomic_load(&p->state) != STATE_INPUT_READY) { pthread_mutex_lock(&p->progress_mutex); - while (p->state == STATE_SETTING_UP) + while (atomic_load(&p->state) == STATE_SETTING_UP) pthread_cond_wait(&p->progress_cond, &p->progress_mutex); - if (p->state == STATE_GET_BUFFER) { + if (atomic_load_explicit(&p->state, memory_order_acquire) == STATE_GET_BUFFER) { p->result = ff_get_buffer(p->avctx, p->requested_frame, p->requested_flags); - p->state = STATE_SETTING_UP; + atomic_store(&p->state, STATE_SETTING_UP); pthread_cond_signal(&p->progress_cond); } pthread_mutex_unlock(&p->progress_mutex); @@ -400,9 +409,9 @@ int ff_thread_decode_frame(AVCodecContext *avctx, do { p = &fctx->threads[finished++]; - if (p->state != STATE_INPUT_READY) { + if (atomic_load(&p->state) != STATE_INPUT_READY) { pthread_mutex_lock(&p->progress_mutex); - while (p->state != STATE_INPUT_READY) + while (atomic_load_explicit(&p->state, memory_order_relaxed) != STATE_INPUT_READY) pthread_cond_wait(&p->output_cond, &p->progress_mutex); pthread_mutex_unlock(&p->progress_mutex); } @@ -474,7 +483,9 @@ void ff_thread_finish_setup(AVCodecContext *avctx) { if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return; pthread_mutex_lock(&p->progress_mutex); - p->state = STATE_SETUP_FINISHED; + + atomic_store(&p->state, STATE_SETUP_FINISHED); + pthread_cond_broadcast(&p->progress_cond); pthread_mutex_unlock(&p->progress_mutex); } @@ -487,9 +498,9 @@ static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count for (i = 0; i < thread_count; i++) { PerThreadContext *p = &fctx->threads[i]; - if (p->state != STATE_INPUT_READY) { + if (atomic_load(&p->state) != STATE_INPUT_READY) { pthread_mutex_lock(&p->progress_mutex); - while (p->state != STATE_INPUT_READY) + while (atomic_load(&p->state) != STATE_INPUT_READY) pthread_cond_wait(&p->output_cond, &p->progress_mutex); pthread_mutex_unlock(&p->progress_mutex); } @@ -701,7 +712,7 @@ int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags) if (!(avctx->active_thread_type & FF_THREAD_FRAME)) return ff_get_buffer(avctx, f->f, flags); - if (p->state != STATE_SETTING_UP && + if (atomic_load(&p->state) != STATE_SETTING_UP && (avctx->codec->update_thread_context || !avctx->thread_safe_callbacks)) { av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n"); return -1; @@ -725,11 +736,11 @@ int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags) } else { p->requested_frame = f->f; p->requested_flags = flags; - p->state = STATE_GET_BUFFER; + atomic_store_explicit(&p->state, STATE_GET_BUFFER, memory_order_release); pthread_mutex_lock(&p->progress_mutex); pthread_cond_signal(&p->progress_cond); - while (p->state != STATE_SETTING_UP) + while (atomic_load(&p->state) != STATE_SETTING_UP) pthread_cond_wait(&p->progress_cond, &p->progress_mutex); err = p->result; From 59c70227405c214b29971e6272f3a3ff6fcce3d0 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 18 Jul 2016 00:04:16 +0200 Subject: [PATCH 0234/3374] pthread_frame: use atomics for frame progress --- libavcodec/pthread_frame.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 400279010d149..210ee69dae4fc 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -444,9 +444,11 @@ int ff_thread_decode_frame(AVCodecContext *avctx, void ff_thread_report_progress(ThreadFrame *f, int n, int field) { PerThreadContext *p; - int *progress = f->progress ? (int*)f->progress->data : NULL; + atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL; - if (!progress || progress[field] >= n) return; + if (!progress || + atomic_load_explicit(&progress[field], memory_order_acquire) >= n) + return; p = f->owner->internal->thread_ctx; @@ -454,7 +456,9 @@ void ff_thread_report_progress(ThreadFrame *f, int n, int field) av_log(f->owner, AV_LOG_DEBUG, "%p finished %d field %d\n", progress, n, field); pthread_mutex_lock(&p->progress_mutex); - progress[field] = n; + + atomic_store(&progress[field], n); + pthread_cond_broadcast(&p->progress_cond); pthread_mutex_unlock(&p->progress_mutex); } @@ -462,9 +466,11 @@ void ff_thread_report_progress(ThreadFrame *f, int n, int field) void ff_thread_await_progress(ThreadFrame *f, int n, int field) { PerThreadContext *p; - int *progress = f->progress ? (int*)f->progress->data : NULL; + atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL; - if (!progress || progress[field] >= n) return; + if (!progress || + atomic_load_explicit(&progress[field], memory_order_acquire) >= n) + return; p = f->owner->internal->thread_ctx; @@ -472,7 +478,7 @@ void ff_thread_await_progress(ThreadFrame *f, int n, int field) av_log(f->owner, AV_LOG_DEBUG, "thread awaiting %d field %d from %p\n", n, field, progress); pthread_mutex_lock(&p->progress_mutex); - while (progress[field] < n) + while (atomic_load_explicit(&progress[field], memory_order_relaxed) < n) pthread_cond_wait(&p->progress_cond, &p->progress_mutex); pthread_mutex_unlock(&p->progress_mutex); } @@ -719,14 +725,15 @@ int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags) } if (avctx->internal->allocate_progress) { - int *progress; - f->progress = av_buffer_alloc(2 * sizeof(int)); + atomic_int *progress; + f->progress = av_buffer_alloc(2 * sizeof(*progress)); if (!f->progress) { return AVERROR(ENOMEM); } - progress = (int*)f->progress->data; + progress = (atomic_int*)f->progress->data; - progress[0] = progress[1] = -1; + atomic_store(&progress[0], -1); + atomic_store(&progress[1], -1); } pthread_mutex_lock(&p->parent->buffer_mutex); From 5cc0057f4910c8c72421b812c8f337ef6c43696c Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 29 Jul 2016 13:47:57 +0200 Subject: [PATCH 0235/3374] lavu: remove the custom atomic API It has been replaced by C11 stdatomic.h and is now unused. --- configure | 2 - libavutil/Makefile | 5 -- libavutil/atomic.c | 109 --------------------------------------- libavutil/atomic.h | 79 ---------------------------- libavutil/atomic_gcc.h | 61 ---------------------- libavutil/atomic_suncc.h | 54 ------------------- libavutil/atomic_win32.h | 53 ------------------- libavutil/tests/atomic.c | 35 ------------- tests/fate/libavutil.mak | 5 -- 9 files changed, 403 deletions(-) delete mode 100644 libavutil/atomic.c delete mode 100644 libavutil/atomic.h delete mode 100644 libavutil/atomic_gcc.h delete mode 100644 libavutil/atomic_suncc.h delete mode 100644 libavutil/atomic_win32.h delete mode 100644 libavutil/tests/atomic.c diff --git a/configure b/configure index 7ac05cfadaacf..e87366ed86b8e 100755 --- a/configure +++ b/configure @@ -1651,7 +1651,6 @@ HAVE_LIST=" $(add_suffix _external $ARCH_EXT_LIST) $(add_suffix _inline $ARCH_EXT_LIST) $ARCH_FEATURES - $ATOMICS_LIST $BUILTIN_LIST $HAVE_LIST_CMDLINE $HAVE_LIST_PUB @@ -1662,7 +1661,6 @@ HAVE_LIST=" $THREADS_LIST $TOOLCHAIN_FEATURES $TYPES_LIST - atomics_native dos_paths dxva2_lib libc_msvcrt diff --git a/libavutil/Makefile b/libavutil/Makefile index b10b4d26a6f47..fbcf1a757fd7f 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -64,7 +64,6 @@ BUILT_HEADERS = avconfig.h OBJS = adler32.o \ aes.o \ - atomic.o \ audio_fifo.o \ avstring.o \ base64.o \ @@ -123,13 +122,9 @@ SKIPHEADERS-$(CONFIG_DXVA2) += hwcontext_dxva2.h SKIPHEADERS-$(CONFIG_LIBMFX) += hwcontext_qsv.h SKIPHEADERS-$(CONFIG_VAAPI) += hwcontext_vaapi.h SKIPHEADERS-$(CONFIG_VDPAU) += hwcontext_vdpau.h -SKIPHEADERS-$(HAVE_ATOMICS_GCC) += atomic_gcc.h -SKIPHEADERS-$(HAVE_ATOMICS_SUNCC) += atomic_suncc.h -SKIPHEADERS-$(HAVE_ATOMICS_WIN32) += atomic_win32.h TESTPROGS = adler32 \ aes \ - atomic \ avstring \ base64 \ blowfish \ diff --git a/libavutil/atomic.c b/libavutil/atomic.c deleted file mode 100644 index e175a9f8edcfb..0000000000000 --- a/libavutil/atomic.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2012 Ronald S. Bultje - * - * This file is part of Libav. - * - * Libav is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * Libav is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#include "atomic.h" - -#if !HAVE_ATOMICS_NATIVE - -#if HAVE_PTHREADS - -#include - -static pthread_mutex_t atomic_lock = PTHREAD_MUTEX_INITIALIZER; - -int avpriv_atomic_int_get(volatile int *ptr) -{ - int res; - - pthread_mutex_lock(&atomic_lock); - res = *ptr; - pthread_mutex_unlock(&atomic_lock); - - return res; -} - -void avpriv_atomic_int_set(volatile int *ptr, int val) -{ - pthread_mutex_lock(&atomic_lock); - *ptr = val; - pthread_mutex_unlock(&atomic_lock); -} - -int avpriv_atomic_int_add_and_fetch(volatile int *ptr, int inc) -{ - int res; - - pthread_mutex_lock(&atomic_lock); - *ptr += inc; - res = *ptr; - pthread_mutex_unlock(&atomic_lock); - - return res; -} - -void *avpriv_atomic_ptr_cas(void * volatile *ptr, void *oldval, void *newval) -{ - void *ret; - pthread_mutex_lock(&atomic_lock); - ret = *ptr; - if (*ptr == oldval) - *ptr = newval; - pthread_mutex_unlock(&atomic_lock); - return ret; -} - -#elif !HAVE_THREADS - -int avpriv_atomic_int_get(volatile int *ptr) -{ - return *ptr; -} - -void avpriv_atomic_int_set(volatile int *ptr, int val) -{ - *ptr = val; -} - -int avpriv_atomic_int_add_and_fetch(volatile int *ptr, int inc) -{ - *ptr += inc; - return *ptr; -} - -void *avpriv_atomic_ptr_cas(void * volatile *ptr, void *oldval, void *newval) -{ - if (*ptr == oldval) { - *ptr = newval; - return oldval; - } - return *ptr; -} - -#else /* HAVE_THREADS */ - -/* This should never trigger, unless a new threading implementation - * without correct atomics dependencies in configure or a corresponding - * atomics implementation is added. */ -#error "Threading is enabled, but there is no implementation of atomic operations available" - -#endif /* HAVE_PTHREADS */ - -#endif /* !HAVE_ATOMICS_NATIVE */ diff --git a/libavutil/atomic.h b/libavutil/atomic.h deleted file mode 100644 index 57a0c19fcbaf0..0000000000000 --- a/libavutil/atomic.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2012 Ronald S. Bultje - * - * This file is part of Libav. - * - * Libav is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * Libav is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_ATOMIC_H -#define AVUTIL_ATOMIC_H - -#include "config.h" - -#if HAVE_ATOMICS_NATIVE - -#if HAVE_ATOMICS_GCC -#include "atomic_gcc.h" -#elif HAVE_ATOMICS_WIN32 -#include "atomic_win32.h" -#elif HAVE_ATOMICS_SUNCC -#include "atomic_suncc.h" -#endif - -#else - -/** - * Load the current value stored in an atomic integer. - * - * @param ptr atomic integer - * @return the current value of the atomic integer - * @note This acts as a memory barrier. - */ -int avpriv_atomic_int_get(volatile int *ptr); - -/** - * Store a new value in an atomic integer. - * - * @param ptr atomic integer - * @param val the value to store in the atomic integer - * @note This acts as a memory barrier. - */ -void avpriv_atomic_int_set(volatile int *ptr, int val); - -/** - * Add a value to an atomic integer. - * - * @param ptr atomic integer - * @param inc the value to add to the atomic integer (may be negative) - * @return the new value of the atomic integer. - * @note This does NOT act as a memory barrier. This is primarily - * intended for reference counting. - */ -int avpriv_atomic_int_add_and_fetch(volatile int *ptr, int inc); - -/** - * Atomic pointer compare and swap. - * - * @param ptr pointer to the pointer to operate on - * @param oldval do the swap if the current value of *ptr equals to oldval - * @param newval value to replace *ptr with - * @return the value of *ptr before comparison - */ -void *avpriv_atomic_ptr_cas(void * volatile *ptr, void *oldval, void *newval); - -#endif /* HAVE_ATOMICS_NATIVE */ - -#endif /* AVUTIL_ATOMIC_H */ diff --git a/libavutil/atomic_gcc.h b/libavutil/atomic_gcc.h deleted file mode 100644 index 9470e8e50b3e6..0000000000000 --- a/libavutil/atomic_gcc.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2012 Ronald S. Bultje - * - * This file is part of Libav. - * - * Libav is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * Libav is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_ATOMIC_GCC_H -#define AVUTIL_ATOMIC_GCC_H - -#include - -#include "atomic.h" - -#define avpriv_atomic_int_get atomic_int_get_gcc -static inline int atomic_int_get_gcc(volatile int *ptr) -{ - __sync_synchronize(); - return *ptr; -} - -#define avpriv_atomic_int_set atomic_int_set_gcc -static inline void atomic_int_set_gcc(volatile int *ptr, int val) -{ - *ptr = val; - __sync_synchronize(); -} - -#define avpriv_atomic_int_add_and_fetch atomic_int_add_and_fetch_gcc -static inline int atomic_int_add_and_fetch_gcc(volatile int *ptr, int inc) -{ - return __sync_add_and_fetch(ptr, inc); -} - -#define avpriv_atomic_ptr_cas atomic_ptr_cas_gcc -static inline void *atomic_ptr_cas_gcc(void * volatile *ptr, - void *oldval, void *newval) -{ -#ifdef __ARMCC_VERSION - // armcc will throw an error if ptr is not an integer type - volatile uintptr_t *tmp = (volatile uintptr_t*)ptr; - return (void*)__sync_val_compare_and_swap(tmp, oldval, newval); -#else - return __sync_val_compare_and_swap(ptr, oldval, newval); -#endif -} - -#endif /* AVUTIL_ATOMIC_GCC_H */ diff --git a/libavutil/atomic_suncc.h b/libavutil/atomic_suncc.h deleted file mode 100644 index b78c37767af4e..0000000000000 --- a/libavutil/atomic_suncc.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of Libav. - * - * Libav is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * Libav is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_ATOMIC_SUNCC_H -#define AVUTIL_ATOMIC_SUNCC_H - -#include -#include - -#include "atomic.h" - -#define avpriv_atomic_int_get atomic_int_get_suncc -static inline int atomic_int_get_suncc(volatile int *ptr) -{ - __machine_rw_barrier(); - return *ptr; -} - -#define avpriv_atomic_int_set atomic_int_set_suncc -static inline void atomic_int_set_suncc(volatile int *ptr, int val) -{ - *ptr = val; - __machine_rw_barrier(); -} - -#define avpriv_atomic_int_add_and_fetch atomic_int_add_and_fetch_suncc -static inline int atomic_int_add_and_fetch_suncc(volatile int *ptr, int inc) -{ - return atomic_add_int_nv(ptr, inc); -} - -#define avpriv_atomic_ptr_cas atomic_ptr_cas_suncc -static inline void *atomic_ptr_cas_suncc(void * volatile *ptr, - void *oldval, void *newval) -{ - return atomic_cas_ptr(ptr, oldval, newval); -} - -#endif /* AVUTIL_ATOMIC_SUNCC_H */ diff --git a/libavutil/atomic_win32.h b/libavutil/atomic_win32.h deleted file mode 100644 index 00c66cfc1d937..0000000000000 --- a/libavutil/atomic_win32.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2012 Ronald S. Bultje - * - * This file is part of Libav. - * - * Libav is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * Libav is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_ATOMIC_WIN32_H -#define AVUTIL_ATOMIC_WIN32_H - -#include - -#define avpriv_atomic_int_get atomic_int_get_win32 -static inline int atomic_int_get_win32(volatile int *ptr) -{ - MemoryBarrier(); - return *ptr; -} - -#define avpriv_atomic_int_set atomic_int_set_win32 -static inline void atomic_int_set_win32(volatile int *ptr, int val) -{ - *ptr = val; - MemoryBarrier(); -} - -#define avpriv_atomic_int_add_and_fetch atomic_int_add_and_fetch_win32 -static inline int atomic_int_add_and_fetch_win32(volatile int *ptr, int inc) -{ - return inc + InterlockedExchangeAdd(ptr, inc); -} - -#define avpriv_atomic_ptr_cas atomic_ptr_cas_win32 -static inline void *atomic_ptr_cas_win32(void * volatile *ptr, - void *oldval, void *newval) -{ - return InterlockedCompareExchangePointer(ptr, newval, oldval); -} - -#endif /* AVUTIL_ATOMIC_WIN32_H */ diff --git a/libavutil/tests/atomic.c b/libavutil/tests/atomic.c deleted file mode 100644 index 70636f42fbbd1..0000000000000 --- a/libavutil/tests/atomic.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of Libav. - * - * Libav is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * Libav is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include "libavutil/atomic.h" - -int main(void) -{ - volatile int val = 1; - int res; - - res = avpriv_atomic_int_add_and_fetch(&val, 1); - assert(res == 2); - avpriv_atomic_int_set(&val, 3); - res = avpriv_atomic_int_get(&val); - assert(res == 3); - - return 0; -} diff --git a/tests/fate/libavutil.mak b/tests/fate/libavutil.mak index 69e4042a8bf59..2824e084eb411 100644 --- a/tests/fate/libavutil.mak +++ b/tests/fate/libavutil.mak @@ -8,11 +8,6 @@ fate-aes: libavutil/tests/aes$(EXESUF) fate-aes: CMD = run libavutil/tests/aes fate-aes: REF = /dev/null -FATE_LIBAVUTIL += fate-atomic -fate-atomic: libavutil/tests/atomic$(EXESUF) -fate-atomic: CMD = run libavutil/tests/atomic -fate-atomic: REF = /dev/null - FATE_LIBAVUTIL += fate-avstring fate-avstring: libavutil/tests/avstring$(EXESUF) fate-avstring: CMD = run libavutil/tests/avstring From 314b421dd8910ebed7a8d419a0dbea239a00044e Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Fri, 30 Sep 2016 17:27:58 +0200 Subject: [PATCH 0236/3374] vaapi_encode: Decide on GOP setup before initialising sequence parameters This was always too late; several fields related to it have been incorrectly zero since the encoder was added. --- libavcodec/vaapi_encode.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index dc6cdfef60868..b600a0012124a 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -1363,6 +1363,12 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) ctx->decode_delay = 1; ctx->output_order = - ctx->output_delay - 1; + // Currently we never generate I frames, only IDR. + ctx->i_per_idr = 0; + ctx->p_per_i = ((avctx->gop_size + avctx->max_b_frames) / + (avctx->max_b_frames + 1)); + ctx->b_per_p = avctx->max_b_frames; + if (ctx->codec->sequence_params_size > 0) { ctx->codec_sequence_params = av_mallocz(ctx->codec->sequence_params_size); @@ -1389,12 +1395,6 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) } } - // All I are IDR for now. - ctx->i_per_idr = 0; - ctx->p_per_i = ((avctx->gop_size + avctx->max_b_frames) / - (avctx->max_b_frames + 1)); - ctx->b_per_p = avctx->max_b_frames; - // This should be configurable somehow. (Needs testing on a machine // where it actually overlaps properly, though.) ctx->issue_mode = ISSUE_MODE_MAXIMISE_THROUGHPUT; From 17a0f9481cf07af0feb3838ca315b970117e8000 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sat, 1 Oct 2016 10:48:44 +0200 Subject: [PATCH 0237/3374] vaapi_h264: Fix CFR mode with frame_rate set in AVCodecContext --- libavcodec/vaapi_encode_h264.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index 020f8924e2fcf..e90ed64d3c494 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -835,8 +835,8 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) vseq->vui_fields.bits.timing_info_present_flag = 1; if (avctx->framerate.num > 0 && avctx->framerate.den > 0) { - vseq->num_units_in_tick = avctx->framerate.num; - vseq->time_scale = 2 * avctx->framerate.den; + vseq->num_units_in_tick = avctx->framerate.den; + vseq->time_scale = 2 * avctx->framerate.num; mseq->fixed_frame_rate_flag = 1; } else { vseq->num_units_in_tick = avctx->time_base.num; From ec17ab381ede4f31c4bdd2767d8f62d24aaf430a Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sat, 1 Oct 2016 11:01:08 +0100 Subject: [PATCH 0238/3374] vaapi_h264: Write bitstream restriction fields --- libavcodec/vaapi_encode_h264.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index e90ed64d3c494..b550f6f24a8c7 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -84,7 +84,12 @@ typedef struct VAAPIEncodeH264MiscSequenceParams { char vcl_hrd_parameters_present_flag; char low_delay_hrd_flag; char pic_struct_present_flag; - char bitstream_restriction_flag; + + char motion_vectors_over_pic_boundaries_flag; + unsigned int max_bytes_per_pic_denom; + unsigned int max_bits_per_mb_denom; + unsigned int max_num_reorder_frames; + unsigned int max_dec_pic_buffering; unsigned int cpb_cnt_minus1; unsigned int bit_rate_scale; @@ -263,7 +268,13 @@ static void vaapi_encode_h264_write_vui(PutBitContext *pbc, u(1, vvui_field(bitstream_restriction_flag)); if (vseq->vui_fields.bits.bitstream_restriction_flag) { - av_assert0(0 && "bitstream restrictions not supported"); + u(1, mseq_var(motion_vectors_over_pic_boundaries_flag)); + ue(mseq_var(max_bytes_per_pic_denom)); + ue(mseq_var(max_bits_per_mb_denom)); + ue(vvui_field(log2_max_mv_length_horizontal)); + ue(vvui_field(log2_max_mv_length_vertical)); + ue(mseq_var(max_num_reorder_frames)); + ue(mseq_var(max_dec_pic_buffering)); } } @@ -831,6 +842,16 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) mseq->matrix_coefficients = avctx->colorspace; } + vseq->vui_fields.bits.bitstream_restriction_flag = 1; + mseq->motion_vectors_over_pic_boundaries_flag = 1; + mseq->max_bytes_per_pic_denom = 0; + mseq->max_bits_per_mb_denom = 0; + vseq->vui_fields.bits.log2_max_mv_length_horizontal = 16; + vseq->vui_fields.bits.log2_max_mv_length_vertical = 16; + + mseq->max_num_reorder_frames = (avctx->max_b_frames > 0); + mseq->max_dec_pic_buffering = vseq->max_num_ref_frames; + vseq->bits_per_second = avctx->bit_rate; vseq->vui_fields.bits.timing_info_present_flag = 1; From fc30a90898e419cee7c7cb496976da6337d0bf3e Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Fri, 30 Sep 2016 17:31:49 +0200 Subject: [PATCH 0239/3374] vaapi_h265: Fix slice header writing This was not observed earlier because the only syntax element which it normally misses with the current setup is slice_qp_delta, but that is always going to be zero (in IDR frames QP isn't varied on the slice) which will always exp-golomb code as a single 1 bit. The immediately following part is the byte alignment, which is always a 1 bit followed by 0s which are ignored, so as long as the bitstream is never aligned at that point we will never notice because the only difference is that an ignored bit is a 1 instead of a 0. --- libavcodec/vaapi_encode_h265.c | 116 ++++++++++++++++----------------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c index 7cd9782c204e0..db339aa5d7b85 100644 --- a/libavcodec/vaapi_encode_h265.c +++ b/libavcodec/vaapi_encode_h265.c @@ -616,78 +616,78 @@ static void vaapi_encode_h265_write_slice_header2(PutBitContext *pbc, if (mseq->long_term_ref_pics_present_flag) { av_assert0(0); } + } - if (vseq->seq_fields.bits.sps_temporal_mvp_enabled_flag) { - u(1, vslice_field(slice_temporal_mvp_enabled_flag)); - } + if (vseq->seq_fields.bits.sps_temporal_mvp_enabled_flag) { + u(1, vslice_field(slice_temporal_mvp_enabled_flag)); + } - if (vseq->seq_fields.bits.sample_adaptive_offset_enabled_flag) { - u(1, vslice_field(slice_sao_luma_flag)); - if (!vseq->seq_fields.bits.separate_colour_plane_flag && - vseq->seq_fields.bits.chroma_format_idc != 0) { - u(1, vslice_field(slice_sao_chroma_flag)); - } + if (vseq->seq_fields.bits.sample_adaptive_offset_enabled_flag) { + u(1, vslice_field(slice_sao_luma_flag)); + if (!vseq->seq_fields.bits.separate_colour_plane_flag && + vseq->seq_fields.bits.chroma_format_idc != 0) { + u(1, vslice_field(slice_sao_chroma_flag)); } + } - if (vslice->slice_type == P_SLICE || vslice->slice_type == B_SLICE) { - u(1, vslice_field(num_ref_idx_active_override_flag)); - if (vslice->slice_fields.bits.num_ref_idx_active_override_flag) { - ue(vslice_var(num_ref_idx_l0_active_minus1)); - if (vslice->slice_type == B_SLICE) { - ue(vslice_var(num_ref_idx_l1_active_minus1)); - } - } - - if (mseq->lists_modification_present_flag) { - av_assert0(0); - // ref_pic_lists_modification() - } + if (vslice->slice_type == P_SLICE || vslice->slice_type == B_SLICE) { + u(1, vslice_field(num_ref_idx_active_override_flag)); + if (vslice->slice_fields.bits.num_ref_idx_active_override_flag) { + ue(vslice_var(num_ref_idx_l0_active_minus1)); if (vslice->slice_type == B_SLICE) { - u(1, vslice_field(mvd_l1_zero_flag)); - } - if (mseq->cabac_init_present_flag) { - u(1, vslice_field(cabac_init_flag)); - } - if (vslice->slice_fields.bits.slice_temporal_mvp_enabled_flag) { - if (vslice->slice_type == B_SLICE) - u(1, vslice_field(collocated_from_l0_flag)); - ue(vpic->collocated_ref_pic_index, collocated_ref_idx); - } - if ((vpic->pic_fields.bits.weighted_pred_flag && - vslice->slice_type == P_SLICE) || - (vpic->pic_fields.bits.weighted_bipred_flag && - vslice->slice_type == B_SLICE)) { - av_assert0(0); - // pred_weight_table() + ue(vslice_var(num_ref_idx_l1_active_minus1)); } - ue(5 - vslice->max_num_merge_cand, five_minus_max_num_merge_cand); } - se(vslice_var(slice_qp_delta)); - if (mseq->pps_slice_chroma_qp_offsets_present_flag) { - se(vslice_var(slice_cb_qp_offset)); - se(vslice_var(slice_cr_qp_offset)); + if (mseq->lists_modification_present_flag) { + av_assert0(0); + // ref_pic_lists_modification() } - if (mseq->pps_slice_chroma_offset_list_enabled_flag) { - u(1, 0, cu_chroma_qp_offset_enabled_flag); + if (vslice->slice_type == B_SLICE) { + u(1, vslice_field(mvd_l1_zero_flag)); } - if (mseq->deblocking_filter_override_enabled_flag) { - u(1, mslice_var(deblocking_filter_override_flag)); + if (mseq->cabac_init_present_flag) { + u(1, vslice_field(cabac_init_flag)); } - if (mslice->deblocking_filter_override_flag) { - u(1, vslice_field(slice_deblocking_filter_disabled_flag)); - if (!vslice->slice_fields.bits.slice_deblocking_filter_disabled_flag) { - se(vslice_var(slice_beta_offset_div2)); - se(vslice_var(slice_tc_offset_div2)); - } + if (vslice->slice_fields.bits.slice_temporal_mvp_enabled_flag) { + if (vslice->slice_type == B_SLICE) + u(1, vslice_field(collocated_from_l0_flag)); + ue(vpic->collocated_ref_pic_index, collocated_ref_idx); } - if (vpic->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag && - (vslice->slice_fields.bits.slice_sao_luma_flag || - vslice->slice_fields.bits.slice_sao_chroma_flag || - vslice->slice_fields.bits.slice_deblocking_filter_disabled_flag)) { - u(1, vslice_field(slice_loop_filter_across_slices_enabled_flag)); + if ((vpic->pic_fields.bits.weighted_pred_flag && + vslice->slice_type == P_SLICE) || + (vpic->pic_fields.bits.weighted_bipred_flag && + vslice->slice_type == B_SLICE)) { + av_assert0(0); + // pred_weight_table() + } + ue(5 - vslice->max_num_merge_cand, five_minus_max_num_merge_cand); + } + + se(vslice_var(slice_qp_delta)); + if (mseq->pps_slice_chroma_qp_offsets_present_flag) { + se(vslice_var(slice_cb_qp_offset)); + se(vslice_var(slice_cr_qp_offset)); + } + if (mseq->pps_slice_chroma_offset_list_enabled_flag) { + u(1, 0, cu_chroma_qp_offset_enabled_flag); + } + if (mseq->deblocking_filter_override_enabled_flag) { + u(1, mslice_var(deblocking_filter_override_flag)); + } + if (mslice->deblocking_filter_override_flag) { + u(1, vslice_field(slice_deblocking_filter_disabled_flag)); + if (!vslice->slice_fields.bits.slice_deblocking_filter_disabled_flag) { + se(vslice_var(slice_beta_offset_div2)); + se(vslice_var(slice_tc_offset_div2)); } } + if (vpic->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag && + (vslice->slice_fields.bits.slice_sao_luma_flag || + vslice->slice_fields.bits.slice_sao_chroma_flag || + vslice->slice_fields.bits.slice_deblocking_filter_disabled_flag)) { + u(1, vslice_field(slice_loop_filter_across_slices_enabled_flag)); + } if (vpic->pic_fields.bits.tiles_enabled_flag || vpic->pic_fields.bits.entropy_coding_sync_enabled_flag) { From b8cac1e83066aa87e8402c146c81b77a11b5eec3 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Fri, 30 Sep 2016 17:47:19 +0200 Subject: [PATCH 0240/3374] vaapi_h265: Fix buffering parameters A decoder may need this to be set correctly to output frames in the right order. --- libavcodec/vaapi_encode_h265.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c index db339aa5d7b85..006cc2a870a3d 100644 --- a/libavcodec/vaapi_encode_h265.c +++ b/libavcodec/vaapi_encode_h265.c @@ -897,12 +897,12 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) mseq->log2_max_pic_order_cnt_lsb_minus4 = 8; mseq->vps_sub_layer_ordering_info_present_flag = 0; - mseq->vps_max_dec_pic_buffering_minus1[0] = 1; - mseq->vps_max_num_reorder_pics[0] = ctx->b_per_p; + mseq->vps_max_dec_pic_buffering_minus1[0] = (avctx->max_b_frames > 0) + 1; + mseq->vps_max_num_reorder_pics[0] = (avctx->max_b_frames > 0); mseq->vps_max_latency_increase_plus1[0] = 0; mseq->sps_sub_layer_ordering_info_present_flag = 0; - mseq->sps_max_dec_pic_buffering_minus1[0] = 1; - mseq->sps_max_num_reorder_pics[0] = ctx->b_per_p; + mseq->sps_max_dec_pic_buffering_minus1[0] = (avctx->max_b_frames > 0) + 1; + mseq->sps_max_num_reorder_pics[0] = (avctx->max_b_frames > 0); mseq->sps_max_latency_increase_plus1[0] = 0; mseq->vps_timing_info_present_flag = 1; From eaaaabf6c93321cdb78bf61dc383cf515ec12e07 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Fri, 30 Sep 2016 17:27:09 +0200 Subject: [PATCH 0241/3374] hwcontext_vaapi: Enable P010 support This is required for 10-bit surfaces. --- libavutil/hwcontext_vaapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index cd7d43eb8d325..9617979d7c967 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -109,7 +109,7 @@ static struct { MAP(YUY2, YUV422, YUYV422), MAP(Y800, YUV400, GRAY8), #ifdef VA_FOURCC_P010 - //MAP(P010, YUV420_10BPP, P010), + MAP(P010, YUV420_10BPP, P010), #endif MAP(BGRA, RGB32, BGRA), //MAP(BGRX, RGB32, BGR0), From 5a5df90d9c05d86d9b0564b8b40b6d64a324df5e Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Fri, 30 Sep 2016 11:48:43 +0100 Subject: [PATCH 0242/3374] vaapi_h265: Add main 10 encode support --- libavcodec/vaapi_encode_h265.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c index 006cc2a870a3d..8715d307dccfb 100644 --- a/libavcodec/vaapi_encode_h265.c +++ b/libavcodec/vaapi_encode_h265.c @@ -803,8 +803,10 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) vseq->seq_fields.bits.chroma_format_idc = 1; // 4:2:0. vseq->seq_fields.bits.separate_colour_plane_flag = 0; - vseq->seq_fields.bits.bit_depth_luma_minus8 = 0; // 8-bit luma. - vseq->seq_fields.bits.bit_depth_chroma_minus8 = 0; // 8-bit chroma. + vseq->seq_fields.bits.bit_depth_luma_minus8 = + avctx->profile == FF_PROFILE_HEVC_MAIN_10 ? 2 : 0; + vseq->seq_fields.bits.bit_depth_chroma_minus8 = + avctx->profile == FF_PROFILE_HEVC_MAIN_10 ? 2 : 0; // Other misc flags all zero. // These have to come from the capabilities of the encoder. We have @@ -1231,11 +1233,12 @@ static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx) case FF_PROFILE_HEVC_MAIN: case FF_PROFILE_UNKNOWN: ctx->va_profile = VAProfileHEVCMain; + ctx->va_rt_format = VA_RT_FORMAT_YUV420; break; case FF_PROFILE_HEVC_MAIN_10: - av_log(avctx, AV_LOG_ERROR, "H.265 main 10-bit profile " - "is not supported.\n"); - return AVERROR_PATCHWELCOME; + ctx->va_profile = VAProfileHEVCMain10; + ctx->va_rt_format = VA_RT_FORMAT_YUV420_10BPP; + break; default: av_log(avctx, AV_LOG_ERROR, "Unknown H.265 profile %d.\n", avctx->profile); @@ -1243,9 +1246,6 @@ static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx) } ctx->va_entrypoint = VAEntrypointEncSlice; - // This will be dependent on profile when 10-bit is supported. - ctx->va_rt_format = VA_RT_FORMAT_YUV420; - if (avctx->bit_rate > 0) ctx->va_rc_mode = VA_RC_CBR; else From 310c55f1799deab395319471a75c528d0fa7b30d Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Tue, 20 Sep 2016 15:00:31 -0400 Subject: [PATCH 0243/3374] pixfmt: Document alternative names for smpte 431 and 432 --- libavutil/pixfmt.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index 908b0fe7a5bce..3e040fb3a03c0 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -316,8 +316,8 @@ enum AVColorPrimaries { AVCOL_PRI_BT2020 = 9, ///< ITU-R BT2020 AVCOL_PRI_SMPTE428 = 10, ///< SMPTE ST 428-1 (CIE 1931 XYZ) AVCOL_PRI_SMPTEST428_1 = AVCOL_PRI_SMPTE428, - AVCOL_PRI_SMPTE431 = 11, ///< SMPTE ST 431-2 (2011) - AVCOL_PRI_SMPTE432 = 12, ///< SMPTE ST 432-1 D65 (2010) + AVCOL_PRI_SMPTE431 = 11, ///< SMPTE ST 431-2 (2011) / DCI P3 + AVCOL_PRI_SMPTE432 = 12, ///< SMPTE ST 432-1 (2010) / P3 D65 / Display P3 AVCOL_PRI_NB, ///< Not part of ABI }; From bad4aad4037f59ba0ad656164be9ab8f7a0fa2d4 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Sat, 24 Sep 2016 20:25:44 -0400 Subject: [PATCH 0244/3374] avidec: Do not special case palette on big-endian This simplifies the code a bit, does not change output data in any way. --- libavformat/avidec.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/libavformat/avidec.c b/libavformat/avidec.c index ddc7c2b6f45af..b2457d58246ed 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -652,12 +652,8 @@ static int avi_read_header(AVFormatContext *s) pal_size = FFMIN(pal_size, st->codecpar->extradata_size); pal_src = st->codecpar->extradata + st->codecpar->extradata_size - pal_size; -#if HAVE_BIGENDIAN for (i = 0; i < pal_size / 4; i++) - ast->pal[i] = av_bswap32(((uint32_t *)pal_src)[i]); -#else - memcpy(ast->pal, pal_src, pal_size); -#endif + ast->pal[i] = AV_RL32(pal_src + 4 * i); ast->has_pal = 1; } From 497c087939e32b26b792515d2dbc7e22561203f7 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Sun, 2 Oct 2016 12:24:07 -0400 Subject: [PATCH 0245/3374] avidec: Set palette alpha as fully opaque Palette format is always in RGBA. --- libavformat/avidec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/avidec.c b/libavformat/avidec.c index b2457d58246ed..b07dabd38ca27 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -653,7 +653,7 @@ static int avi_read_header(AVFormatContext *s) pal_src = st->codecpar->extradata + st->codecpar->extradata_size - pal_size; for (i = 0; i < pal_size / 4; i++) - ast->pal[i] = AV_RL32(pal_src + 4 * i); + ast->pal[i] = (0xFFu << 24) | AV_RL32(pal_src + 4 * i); ast->has_pal = 1; } From b8d5070db6313f985562865edcfd08a01c2d7503 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Tue, 20 Sep 2016 17:11:14 -0400 Subject: [PATCH 0246/3374] avcodec: Document AV_PKT_DATA_PALETTE side data type --- libavcodec/avcodec.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 607688cf6f4c3..167525dda35c0 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1189,6 +1189,11 @@ typedef struct AVCPBProperties { * @{ */ enum AVPacketSideDataType { + /** + * An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE + * bytes worth of palette. This side data signals that a new palette is + * present. + */ AV_PKT_DATA_PALETTE, /** From c19830aa2c19f9713b612f7e2fdb437df91ba266 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Mon, 19 Sep 2016 16:33:43 -0400 Subject: [PATCH 0247/3374] rscc: Support palette format Signed-off-by: Vittorio Giovara --- libavcodec/rscc.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/libavcodec/rscc.c b/libavcodec/rscc.c index 4a9178342a750..dfc2338ec99e9 100644 --- a/libavcodec/rscc.c +++ b/libavcodec/rscc.c @@ -31,7 +31,7 @@ * and it can be deflated or not. Similarly, pixel data comes after the header * and a variable size value, and it can be deflated or just raw. * - * Supports: BGRA, BGR24, RGB555, RGB8 + * Supports: PAL8, BGRA, BGR24, RGB555, RGB8 */ #include @@ -59,6 +59,8 @@ typedef struct RsccContext { unsigned int tiles_size; int component_size; + uint8_t palette[AVPALETTE_SIZE]; + /* zlib interaction */ uint8_t *inflated_buf; uLongf inflated_size; @@ -89,8 +91,8 @@ static av_cold int rscc_init(AVCodecContext *avctx) ctx->component_size = avctx->bits_per_coded_sample / 8; switch (avctx->bits_per_coded_sample) { case 8: - avpriv_report_missing_feature(avctx, "8 bits per pixel"); - return AVERROR_PATCHWELCOME; + avctx->pix_fmt = AV_PIX_FMT_PAL8; + break; case 16: avctx->pix_fmt = AV_PIX_FMT_RGB555LE; break; @@ -291,6 +293,19 @@ static int rscc_decode_frame(AVCodecContext *avctx, void *data, } else { frame->pict_type = AV_PICTURE_TYPE_P; } + + /* Palette handling */ + if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { + const uint8_t *palette = av_packet_get_side_data(avpkt, + AV_PKT_DATA_PALETTE, + NULL); + if (palette) { + frame->palette_has_changed = 1; + memcpy(ctx->palette, palette, AVPALETTE_SIZE); + } + memcpy(frame->data[1], ctx->palette, AVPALETTE_SIZE); + } + *got_frame = 1; end: From dc3fe45fca9c10c4af6bfcf48eb7b81968892ef9 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Mon, 19 Sep 2016 16:33:44 -0400 Subject: [PATCH 0248/3374] fate: Add test for rscc palette --- tests/fate/screen.mak | 3 +++ tests/ref/fate/rscc-8bit | 2 ++ 2 files changed, 5 insertions(+) create mode 100644 tests/ref/fate/rscc-8bit diff --git a/tests/fate/screen.mak b/tests/fate/screen.mak index 7e91f19d129d7..7d2f7909b7418 100644 --- a/tests/fate/screen.mak +++ b/tests/fate/screen.mak @@ -44,6 +44,9 @@ fate-g2m: $(FATE_G2M) FATE_RSCC += fate-iscc fate-iscc: CMD = framecrc -i $(TARGET_SAMPLES)/rscc/pip.avi -an +FATE_RSCC += fate-rscc-8bit +fate-rscc-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/rscc/8bpp.avi -an -pix_fmt rgb24 + FATE_RSCC += fate-rscc-16bit fate-rscc-16bit: CMD = framecrc -i $(TARGET_SAMPLES)/rscc/16bpp_555.avi -an diff --git a/tests/ref/fate/rscc-8bit b/tests/ref/fate/rscc-8bit new file mode 100644 index 0000000000000..b6371ace87b81 --- /dev/null +++ b/tests/ref/fate/rscc-8bit @@ -0,0 +1,2 @@ +#tb 0: 100/2997 +0, 0, 0, 1, 1229760, 0xfdf2e538 From a451324dddf5d2ab4bcd6aa0f546596f71bdada3 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 12 Aug 2014 18:11:05 -0400 Subject: [PATCH 0249/3374] vp9: ignore reference segmentation map if error_resilience flag is set. Fixes ffvp9_fails_where_libvpx.succeeds.webm. Bug-Id: ffmpeg/3849. Signed-off-by: Anton Khirnov --- libavcodec/vp9.c | 2 +- libavcodec/vp9block.c | 28 ++++++++++++++++------------ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 32d995f4a1297..906218565ebf0 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -64,7 +64,7 @@ static int vp9_frame_alloc(AVCodecContext *avctx, VP9Frame *f) f->mv = (VP9MVRefPair*)f->mv_buf->data; if (s->segmentation.enabled && !s->segmentation.update_map && - !s->keyframe && !s->intraonly) + !s->keyframe && !s->intraonly && !s->errorres) memcpy(f->segmentation_map, s->frames[LAST_FRAME].segmentation_map, sz); return 0; diff --git a/libavcodec/vp9block.c b/libavcodec/vp9block.c index 9b0d836adcabf..cd40c3898933f 100644 --- a/libavcodec/vp9block.c +++ b/libavcodec/vp9block.c @@ -70,18 +70,22 @@ static void decode_mode(VP9Context *s, VP9Block *const b) vp56_rac_get_prob_branchy(&s->c, s->prob.segpred[s->above_segpred_ctx[col] + s->left_segpred_ctx[row7]]))) { - uint8_t *refsegmap = s->frames[LAST_FRAME].segmentation_map; - int pred = MAX_SEGMENT - 1; - int x; - - if (!s->last_uses_2pass) - ff_thread_await_progress(&s->frames[LAST_FRAME].tf, row >> 3, 0); - - for (y = 0; y < h4; y++) - for (x = 0; x < w4; x++) - pred = FFMIN(pred, - refsegmap[(y + row) * 8 * s->sb_cols + x + col]); - b->seg_id = pred; + if (!s->errorres) { + uint8_t *refsegmap = s->frames[LAST_FRAME].segmentation_map; + int pred = MAX_SEGMENT - 1; + int x; + + if (!s->last_uses_2pass) + ff_thread_await_progress(&s->frames[LAST_FRAME].tf, row >> 3, 0); + + for (y = 0; y < h4; y++) + for (x = 0; x < w4; x++) + pred = FFMIN(pred, + refsegmap[(y + row) * 8 * s->sb_cols + x + col]); + b->seg_id = pred; + } else { + b->seg_id = 0; + } memset(&s->above_segpred_ctx[col], 1, w4); memset(&s->left_segpred_ctx[row7], 1, h4); From c935b54bd6a12714fc08d88791dadee2ba07176a Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 17 Sep 2015 11:58:10 -0400 Subject: [PATCH 0250/3374] checkasm: add VP9 loopfilter tests. The randomize_buffer() implementation assures that "most of the time", we'll do a good mix of wide16/wide8/hev/regular/no filters for complete code coverage. However, this is not mathematically assured because that would make the code either much more complex, or much less random. Some fixes and improvements by Rodger Combs Signed-off-by: Anton Khirnov --- tests/checkasm/vp9dsp.c | 159 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) diff --git a/tests/checkasm/vp9dsp.c b/tests/checkasm/vp9dsp.c index dd37077adf6f5..f0d93725ebfd2 100644 --- a/tests/checkasm/vp9dsp.c +++ b/tests/checkasm/vp9dsp.c @@ -32,6 +32,164 @@ static const uint32_t pixel_mask[3] = { 0xffffffff, 0x03ff03ff, 0x0fff0fff }; #define BIT_DEPTH 8 #define SIZEOF_PIXEL ((BIT_DEPTH + 7) / 8) + +#define setpx(a,b,c) \ + do { \ + if (SIZEOF_PIXEL == 1) { \ + buf0[(a) + (b) * jstride] = av_clip_uint8(c); \ + } else { \ + ((uint16_t *)buf0)[(a) + (b) * jstride] = av_clip_uintp2(c, BIT_DEPTH); \ + } \ + } while (0) +#define setdx(a,b,c,d) setpx(a,b,c-(d)+(rnd()%((d)*2+1))) +#define setsx(a,b,c,d) setdx(a,b,c,(d) << (BIT_DEPTH - 8)) + +static void randomize_loopfilter_buffers(int bidx, int lineoff, int str, + int bit_depth, int dir, + const int *E, const int *F, + const int *H, const int *I, + uint8_t *buf0, uint8_t *buf1) +{ + uint32_t mask = (1 << BIT_DEPTH) - 1; + int off = dir ? lineoff : lineoff * 16; + int istride = dir ? 1 : 16; + int jstride = dir ? str : 1; + int i, j; + for (i = 0; i < 2; i++) /* flat16 */ { + int idx = off + i * istride, p0, q0; + setpx(idx, 0, q0 = rnd() & mask); + setsx(idx, -1, p0 = q0, E[bidx] >> 2); + for (j = 1; j < 8; j++) { + setsx(idx, -1 - j, p0, F[bidx]); + setsx(idx, j, q0, F[bidx]); + } + } + for (i = 2; i < 4; i++) /* flat8 */ { + int idx = off + i * istride, p0, q0; + setpx(idx, 0, q0 = rnd() & mask); + setsx(idx, -1, p0 = q0, E[bidx] >> 2); + for (j = 1; j < 4; j++) { + setsx(idx, -1 - j, p0, F[bidx]); + setsx(idx, j, q0, F[bidx]); + } + for (j = 4; j < 8; j++) { + setpx(idx, -1 - j, rnd() & mask); + setpx(idx, j, rnd() & mask); + } + } + for (i = 4; i < 6; i++) /* regular */ { + int idx = off + i * istride, p2, p1, p0, q0, q1, q2; + setpx(idx, 0, q0 = rnd() & mask); + setsx(idx, 1, q1 = q0, I[bidx]); + setsx(idx, 2, q2 = q1, I[bidx]); + setsx(idx, 3, q2, I[bidx]); + setsx(idx, -1, p0 = q0, E[bidx] >> 2); + setsx(idx, -2, p1 = p0, I[bidx]); + setsx(idx, -3, p2 = p1, I[bidx]); + setsx(idx, -4, p2, I[bidx]); + for (j = 4; j < 8; j++) { + setpx(idx, -1 - j, rnd() & mask); + setpx(idx, j, rnd() & mask); + } + } + for (i = 6; i < 8; i++) /* off */ { + int idx = off + i * istride; + for (j = 0; j < 8; j++) { + setpx(idx, -1 - j, rnd() & mask); + setpx(idx, j, rnd() & mask); + } + } +} + +#define randomize_buffers(bidx, lineoff, str) \ + randomize_loopfilter_buffers(bidx, lineoff, str, BIT_DEPTH, dir, \ + E, F, H, I, buf0, buf1) + +static void check_loopfilter(void) +{ + LOCAL_ALIGNED_32(uint8_t, base0, [32 + 16 * 16 * 2]); + LOCAL_ALIGNED_32(uint8_t, base1, [32 + 16 * 16 * 2]); + VP9DSPContext dsp; + int dir, wd, wd2; + static const char *const dir_name[2] = { "h", "v" }; + static const int E[2] = { 20, 28 }, I[2] = { 10, 16 }; + static const int H[2] = { 7, 11 }, F[2] = { 1, 1 }; + declare_func(void, uint8_t *dst, ptrdiff_t stride, int E, int I, int H); + + ff_vp9dsp_init(&dsp); + + for (dir = 0; dir < 2; dir++) { + uint8_t *buf0, *buf1; + int midoff = (dir ? 8 * 8 : 8) * SIZEOF_PIXEL; + int midoff_aligned = (dir ? 8 * 8 : 16) * SIZEOF_PIXEL; + + buf0 = base0 + midoff_aligned; + buf1 = base1 + midoff_aligned; + + for (wd = 0; wd < 3; wd++) { + // 4/8/16wd_8px + if (check_func(dsp.loop_filter_8[wd][dir], + "vp9_loop_filter_%s_%d_8", + dir_name[dir], 4 << wd)) { + randomize_buffers(0, 0, 8); + memcpy(buf1 - midoff, buf0 - midoff, + 16 * 8 * SIZEOF_PIXEL); + call_ref(buf0, 16 * SIZEOF_PIXEL >> dir, E[0], I[0], H[0]); + call_new(buf1, 16 * SIZEOF_PIXEL >> dir, E[0], I[0], H[0]); + if (memcmp(buf0 - midoff, buf1 - midoff, 16 * 8 * SIZEOF_PIXEL)) + fail(); + bench_new(buf1, 16 * SIZEOF_PIXEL >> dir, E[0], I[0], H[0]); + } + } + + midoff = (dir ? 16 * 8 : 8) * SIZEOF_PIXEL; + midoff_aligned = (dir ? 16 * 8 : 16) * SIZEOF_PIXEL; + + buf0 = base0 + midoff_aligned; + buf1 = base1 + midoff_aligned; + + // 16wd_16px loopfilter + if (check_func(dsp.loop_filter_16[dir], + "vp9_loop_filter_%s_16_16", + dir_name[dir])) { + randomize_buffers(0, 0, 16); + randomize_buffers(0, 8, 16); + memcpy(buf1 - midoff, buf0 - midoff, 16 * 16 * SIZEOF_PIXEL); + call_ref(buf0, 16 * SIZEOF_PIXEL, E[0], I[0], H[0]); + call_new(buf1, 16 * SIZEOF_PIXEL, E[0], I[0], H[0]); + if (memcmp(buf0 - midoff, buf1 - midoff, 16 * 16 * SIZEOF_PIXEL)) + fail(); + bench_new(buf1, 16 * SIZEOF_PIXEL, E[0], I[0], H[0]); + } + + for (wd = 0; wd < 2; wd++) { + for (wd2 = 0; wd2 < 2; wd2++) { + // mix2 loopfilter + if (check_func(dsp.loop_filter_mix2[wd][wd2][dir], + "vp9_loop_filter_mix2_%s_%d%d_16", + dir_name[dir], 4 << wd, 4 << wd2)) { + randomize_buffers(0, 0, 16); + randomize_buffers(1, 8, 16); + memcpy(buf1 - midoff, buf0 - midoff, 16 * 16 * SIZEOF_PIXEL); +#define M(a) ((a[1] << 8) | a[0]) + call_ref(buf0, 16 * SIZEOF_PIXEL, M(E), M(I), M(H)); + call_new(buf1, 16 * SIZEOF_PIXEL, M(E), M(I), M(H)); + if (memcmp(buf0 - midoff, buf1 - midoff, 16 * 16 * SIZEOF_PIXEL)) + fail(); + bench_new(buf1, 16 * SIZEOF_PIXEL, M(E), M(I), M(H)); +#undef M + } + } + } + } + report("loopfilter"); +} + +#undef setsx +#undef setpx +#undef setdx +#undef randomize_buffers + #define DST_BUF_SIZE (size * size * SIZEOF_PIXEL) #define SRC_BUF_STRIDE 72 #define SRC_BUF_SIZE ((size + 7) * SRC_BUF_STRIDE * SIZEOF_PIXEL) @@ -123,5 +281,6 @@ static void check_mc(void) void checkasm_check_vp9dsp(void) { + check_loopfilter(); check_mc(); } From a692724c587859c8157d1aefcae9fbdb23328c61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sun, 5 Jan 2014 21:00:40 +0100 Subject: [PATCH 0251/3374] vp9lpf/x86: add x86 SSSE3/AVX SIMD for vp9_loop_filter_[vh]_16_16. Signed-off-by: Anton Khirnov --- libavcodec/x86/Makefile | 3 +- libavcodec/x86/vp9dsp_init.c | 15 + libavcodec/x86/vp9lpf.asm | 601 +++++++++++++++++++++++++++++++++++ 3 files changed, 618 insertions(+), 1 deletion(-) create mode 100644 libavcodec/x86/vp9lpf.asm diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile index 4aae594bd8a3f..a38535b98f2f8 100644 --- a/libavcodec/x86/Makefile +++ b/libavcodec/x86/Makefile @@ -125,4 +125,5 @@ YASM-OBJS-$(CONFIG_V210_ENCODER) += x86/v210enc.o YASM-OBJS-$(CONFIG_VORBIS_DECODER) += x86/vorbisdsp.o YASM-OBJS-$(CONFIG_VP3_DECODER) += x86/hpeldsp_vp3.o YASM-OBJS-$(CONFIG_VP6_DECODER) += x86/vp6dsp.o -YASM-OBJS-$(CONFIG_VP9_DECODER) += x86/vp9mc.o +YASM-OBJS-$(CONFIG_VP9_DECODER) += x86/vp9mc.o \ + x86/vp9lpf.o diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c index 41fa35a4c3014..93453b83e3347 100644 --- a/libavcodec/x86/vp9dsp_init.c +++ b/libavcodec/x86/vp9dsp_init.c @@ -217,6 +217,11 @@ filters_8tap_1d_fn2(avg, 32, avx2, ssse3) #undef filters_8tap_1d_fn3 #undef filter_8tap_1d_fn +void ff_vp9_loop_filter_v_16_16_ssse3(uint8_t *dst, ptrdiff_t stride, int E, int I, int H); +void ff_vp9_loop_filter_v_16_16_avx (uint8_t *dst, ptrdiff_t stride, int E, int I, int H); +void ff_vp9_loop_filter_h_16_16_ssse3(uint8_t *dst, ptrdiff_t stride, int E, int I, int H); +void ff_vp9_loop_filter_h_16_16_avx (uint8_t *dst, ptrdiff_t stride, int E, int I, int H); + #endif /* HAVE_YASM */ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) @@ -283,11 +288,21 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) if (EXTERNAL_SSSE3(cpu_flags)) { init_subpel3(0, put, ssse3); init_subpel3(1, avg, ssse3); + + if (ARCH_X86_64) { + dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_ssse3; + dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_ssse3; + } } if (EXTERNAL_AVX(cpu_flags)) { init_fpel(1, 0, 32, put, avx); init_fpel(0, 0, 64, put, avx); + + if (ARCH_X86_64) { + dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_avx; + dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_avx; + } } if (EXTERNAL_AVX2(cpu_flags)) { diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm new file mode 100644 index 0000000000000..8568f1d6139ae --- /dev/null +++ b/libavcodec/x86/vp9lpf.asm @@ -0,0 +1,601 @@ +;****************************************************************************** +;* VP9 loop filter SIMD optimizations +;* +;* Copyright (C) 2013-2014 Clément Bœsch +;* +;* This file is part of Libav. +;* +;* Libav is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* Libav is distributed in the hope that it will be useful, +;* but WITHOUT ANY WARRANTY; without even the implied warranty of +;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with Libav; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + + +%include "libavutil/x86/x86util.asm" + +%if ARCH_X86_64 + +SECTION_RODATA + +cextern pb_3 +cextern pb_80 + +pb_4: times 16 db 0x04 +pb_10: times 16 db 0x10 +pb_40: times 16 db 0x40 +pb_81: times 16 db 0x81 +pb_f8: times 16 db 0xf8 +pb_fe: times 16 db 0xfe + +pw_4: times 8 dw 4 +pw_8: times 8 dw 8 + +SECTION .text + +; %1 = abs(%2-%3) +%macro ABSSUB 4 ; dst, src1 (RO), src2 (RO), tmp + psubusb %1, %3, %2 + psubusb %4, %2, %3 + por %1, %4 +%endmacro + +; %1 = %1<=%2 +%macro CMP_LTE 3-4 ; src/dst, cmp, tmp, pb_80 +%if %0 == 4 + pxor %1, %4 +%endif + pcmpgtb %3, %2, %1 ; cmp > src? + pcmpeqb %1, %2 ; cmp == src? XXX: avoid this with a -1/+1 well placed? + por %1, %3 ; cmp >= src? +%endmacro + +; %1 = abs(%2-%3) <= %4 +%macro ABSSUB_CMP 6-7 [pb_80]; dst, src1, src2, cmp, tmp1, tmp2, [pb_80] + ABSSUB %1, %2, %3, %6 ; dst = abs(src1-src2) + CMP_LTE %1, %4, %6, %7 ; dst <= cmp +%endmacro + +%macro MASK_APPLY 4 ; %1=new_data/dst %2=old_data %3=mask %4=tmp + pand %1, %3 ; new &= mask + pandn %4, %3, %2 ; tmp = ~mask & old + por %1, %4 ; new&mask | old&~mask +%endmacro + +%macro FILTER_SUBx2_ADDx2 8 ; %1=dst %2=h/l %3=cache %4=sub1 %5=sub2 %6=add1 %7=add2 %8=rshift + punpck%2bw %3, %4, m0 + psubw %1, %3 + punpck%2bw %3, %5, m0 + psubw %1, %3 + punpck%2bw %3, %6, m0 + paddw %1, %3 + punpck%2bw %3, %7, m0 + paddw %3, %1 + psraw %1, %3, %8 +%endmacro + +%macro FILTER_INIT 8 ; tmp1, tmp2, cacheL, cacheH, dstp, filterid, mask, source + FILTER%6_INIT %1, l, %3 + FILTER%6_INIT %2, h, %4 + packuswb %1, %2 + MASK_APPLY %1, %8, %7, %2 + mova %5, %1 +%endmacro + +%macro FILTER_UPDATE 11-14 ; tmp1, tmp2, cacheL, cacheH, dstp, -, -, +, +, rshift, mask, [source], [preload reg + value] +%if %0 == 13 ; no source + preload + mova %12, %13 +%elif %0 == 14 ; source + preload + mova %13, %14 +%endif + FILTER_SUBx2_ADDx2 %1, l, %3, %6, %7, %8, %9, %10 + FILTER_SUBx2_ADDx2 %2, h, %4, %6, %7, %8, %9, %10 + packuswb %1, %2 +%if %0 == 12 || %0 == 14 + MASK_APPLY %1, %12, %11, %2 +%else + MASK_APPLY %1, %5, %11, %2 +%endif + mova %5, %1 +%endmacro + +%macro SRSHIFT3B_2X 4 ; reg1, reg2, [pb_10], tmp + mova %4, [pb_f8] + pand %1, %4 + pand %2, %4 + psrlq %1, 3 + psrlq %2, 3 + pxor %1, %3 + pxor %2, %3 + psubb %1, %3 + psubb %2, %3 +%endmacro + +%macro EXTRACT_POS_NEG 3 ; i8, neg, pos + pxor %3, %3 + pxor %2, %2 + pcmpgtb %3, %1 ; i8 < 0 mask + psubb %2, %1 ; neg values (only the originally - will be kept) + pand %2, %3 ; negative values of i8 (but stored as +) + pandn %3, %1 ; positive values of i8 +%endmacro + +; clip_u8(u8 + i8) +%macro SIGN_ADD 5 ; dst, u8, i8, tmp1, tmp2 + EXTRACT_POS_NEG %3, %4, %5 + psubusb %1, %2, %4 ; sub the negatives + paddusb %1, %5 ; add the positives +%endmacro + +; clip_u8(u8 - i8) +%macro SIGN_SUB 5 ; dst, u8, i8, tmp1, tmp2 + EXTRACT_POS_NEG %3, %4, %5 + psubusb %1, %2, %5 ; sub the positives + paddusb %1, %4 ; add the negatives +%endmacro + +%macro FILTER6_INIT 3 ; %1=dst %2=h/l %3=cache + punpck%2bw %1, m14, m0 ; p3: B->W + paddw %3, %1, %1 ; p3*2 + paddw %3, %1 ; p3*3 + punpck%2bw %1, m15, m0 ; p2: B->W + paddw %3, %1 ; p3*3 + p2 + paddw %3, %1 ; p3*3 + p2*2 + punpck%2bw %1, m10, m0 ; p1: B->W + paddw %3, %1 ; p3*3 + p2*2 + p1 + punpck%2bw %1, m11, m0 ; p0: B->W + paddw %3, %1 ; p3*3 + p2*2 + p1 + p0 + punpck%2bw %1, m12, m0 ; q0: B->W + paddw %3, %1 ; p3*3 + p2*2 + p1 + p0 + q0 + paddw %3, [pw_4] ; p3*3 + p2*2 + p1 + p0 + q0 + 4 + psraw %1, %3, 3 ; (p3*3 + p2*2 + p1 + p0 + q0 + 4) >> 3 +%endmacro + +%macro FILTER14_INIT 3 ; %1=dst %2=h/l %3=cache + punpck%2bw %1, m2, m0 ; p7: B->W + psllw %3, %1, 3 ; p7*8 + psubw %3, %1 ; p7*7 + punpck%2bw %1, m3, m0 ; p6: B->W + paddw %3, %1 ; p7*7 + p6 + paddw %3, %1 ; p7*7 + p6*2 + punpck%2bw %1, m8, m0 ; p5: B->W + paddw %3, %1 ; p7*7 + p6*2 + p5 + punpck%2bw %1, m9, m0 ; p4: B->W + paddw %3, %1 ; p7*7 + p6*2 + p5 + p4 + punpck%2bw %1, m14, m0 ; p3: B->W + paddw %3, %1 ; p7*7 + p6*2 + p5 + p4 + p3 + punpck%2bw %1, m15, m0 ; p2: B->W + paddw %3, %1 ; p7*7 + p6*2 + p5 + .. + p2 + punpck%2bw %1, m10, m0 ; p1: B->W + paddw %3, %1 ; p7*7 + p6*2 + p5 + .. + p1 + punpck%2bw %1, m11, m0 ; p0: B->W + paddw %3, %1 ; p7*7 + p6*2 + p5 + .. + p0 + punpck%2bw %1, m12, m0 ; q0: B->W + paddw %3, %1 ; p7*7 + p6*2 + p5 + .. + p0 + q0 + paddw %3, [pw_8] ; p7*7 + p6*2 + p5 + .. + p0 + q0 + 8 + psraw %1, %3, 4 ; (p7*7 + p6*2 + p5 + .. + p0 + q0 + 8) >> 4 +%endmacro + +%macro TRANSPOSE16x16B 17 + mova %17, m%16 + SBUTTERFLY bw, %1, %2, %16 + SBUTTERFLY bw, %3, %4, %16 + SBUTTERFLY bw, %5, %6, %16 + SBUTTERFLY bw, %7, %8, %16 + SBUTTERFLY bw, %9, %10, %16 + SBUTTERFLY bw, %11, %12, %16 + SBUTTERFLY bw, %13, %14, %16 + mova m%16, %17 + mova %17, m%14 + SBUTTERFLY bw, %15, %16, %14 + SBUTTERFLY wd, %1, %3, %14 + SBUTTERFLY wd, %2, %4, %14 + SBUTTERFLY wd, %5, %7, %14 + SBUTTERFLY wd, %6, %8, %14 + SBUTTERFLY wd, %9, %11, %14 + SBUTTERFLY wd, %10, %12, %14 + SBUTTERFLY wd, %13, %15, %14 + mova m%14, %17 + mova %17, m%12 + SBUTTERFLY wd, %14, %16, %12 + SBUTTERFLY dq, %1, %5, %12 + SBUTTERFLY dq, %2, %6, %12 + SBUTTERFLY dq, %3, %7, %12 + SBUTTERFLY dq, %4, %8, %12 + SBUTTERFLY dq, %9, %13, %12 + SBUTTERFLY dq, %10, %14, %12 + SBUTTERFLY dq, %11, %15, %12 + mova m%12, %17 + mova %17, m%8 + SBUTTERFLY dq, %12, %16, %8 + SBUTTERFLY qdq, %1, %9, %8 + SBUTTERFLY qdq, %2, %10, %8 + SBUTTERFLY qdq, %3, %11, %8 + SBUTTERFLY qdq, %4, %12, %8 + SBUTTERFLY qdq, %5, %13, %8 + SBUTTERFLY qdq, %6, %14, %8 + SBUTTERFLY qdq, %7, %15, %8 + mova m%8, %17 + mova %17, m%1 + SBUTTERFLY qdq, %8, %16, %1 + mova m%1, %17 + SWAP %2, %9 + SWAP %3, %5 + SWAP %4, %13 + SWAP %6, %11 + SWAP %8, %15 + SWAP %12, %14 +%endmacro + +%macro DEFINE_REAL_P7_TO_Q7 0 +%define P7 dst1q + 2*mstrideq +%define P6 dst1q + mstrideq +%define P5 dst1q +%define P4 dst1q + strideq +%define P3 dstq + 4*mstrideq +%define P2 dstq + mstride3q +%define P1 dstq + 2*mstrideq +%define P0 dstq + mstrideq +%define Q0 dstq +%define Q1 dstq + strideq +%define Q2 dstq + 2*strideq +%define Q3 dstq + stride3q +%define Q4 dstq + 4*strideq +%define Q5 dst2q + mstrideq +%define Q6 dst2q +%define Q7 dst2q + strideq +%endmacro + +%macro LPF_16_16 1 + lea mstrideq, [strideq] + neg mstrideq + + lea stride3q, [strideq+2*strideq] + mov mstride3q, stride3q + neg mstride3q + +%ifidn %1, h + lea dstq, [dstq + 8*strideq - 8] ; go from top center (h pos) to center left (v pos) +%endif + + lea dst1q, [dstq + 2*mstride3q] ; dst1q = &dst[stride * -6] + lea dst2q, [dstq + 2* stride3q] ; dst2q = &dst[stride * +6] + + DEFINE_REAL_P7_TO_Q7 + +%ifidn %1, h + movu m0, [P7] + movu m1, [P6] + movu m2, [P5] + movu m3, [P4] + movu m4, [P3] + movu m5, [P2] + movu m6, [P1] + movu m7, [P0] + movu m8, [Q0] + movu m9, [Q1] + movu m10, [Q2] + movu m11, [Q3] + movu m12, [Q4] + movu m13, [Q5] + movu m14, [Q6] + movu m15, [Q7] + TRANSPOSE16x16B 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, [rsp] + +%define P7 rsp + 0 +%define P6 rsp + 16 +%define P5 rsp + 32 +%define P4 rsp + 48 +%define P3 rsp + 64 +%define P2 rsp + 80 +%define P1 rsp + 96 +%define P0 rsp + 112 +%define Q0 rsp + 128 +%define Q1 rsp + 144 +%define Q2 rsp + 160 +%define Q3 rsp + 176 +%define Q4 rsp + 192 +%define Q5 rsp + 208 +%define Q6 rsp + 224 +%define Q7 rsp + 240 + + mova [P7], m0 + mova [P6], m1 + mova [P5], m2 + mova [P4], m3 + mova [P3], m4 + mova [P2], m5 + mova [P1], m6 + mova [P0], m7 + mova [Q0], m8 + mova [Q1], m9 + mova [Q2], m10 + mova [Q3], m11 + mova [Q4], m12 + mova [Q5], m13 + mova [Q6], m14 + mova [Q7], m15 +%endif + + ; calc fm mask + pxor m0, m0 + movd m2, Id + movd m3, Ed + pshufb m2, m0 ; I I I I ... + pshufb m3, m0 ; E E E E ... + mova m0, [pb_80] + pxor m2, m0 + pxor m3, m0 +%ifidn %1, v + mova m8, [P3] + mova m9, [P2] + mova m10, [P1] + mova m11, [P0] + mova m12, [Q0] + mova m13, [Q1] + mova m14, [Q2] + mova m15, [Q3] +%else + ; In case of horizontal, P3..Q3 are already present in some registers due + ; to the previous transpose, so we just swap registers. + SWAP 8, 4, 12 + SWAP 9, 5, 13 + SWAP 10, 6, 14 + SWAP 11, 7, 15 +%endif + ABSSUB_CMP m5, m8, m9, m2, m6, m7, m0 ; m5 = abs(p3-p2) <= I + ABSSUB_CMP m1, m9, m10, m2, m6, m7, m0 ; m1 = abs(p2-p1) <= I + pand m5, m1 + ABSSUB_CMP m1, m10, m11, m2, m6, m7, m0 ; m1 = abs(p1-p0) <= I + pand m5, m1 + ABSSUB_CMP m1, m12, m13, m2, m6, m7, m0 ; m1 = abs(q1-q0) <= I + pand m5, m1 + ABSSUB_CMP m1, m13, m14, m2, m6, m7, m0 ; m1 = abs(q2-q1) <= I + pand m5, m1 + ABSSUB_CMP m1, m14, m15, m2, m6, m7, m0 ; m1 = abs(q3-q2) <= I + pand m5, m1 + ABSSUB m1, m11, m12, m7 ; abs(p0-q0) + paddusb m1, m1 ; abs(p0-q0) * 2 + ABSSUB m2, m10, m13, m7 ; abs(p1-q1) + pand m2, [pb_fe] ; drop lsb so shift can work + psrlq m2, 1 ; abs(p1-q1)/2 + paddusb m1, m2 ; abs(p0-q0)*2 + abs(p1-q1)/2 + pxor m1, m0 + pcmpgtb m4, m3, m1 ; E > X? + pcmpeqb m3, m1 ; E == X? + por m3, m4 ; E >= X? + pand m3, m5 ; fm final value + + ; (m3: fm, m8..15: p3 p2 p1 p0 q0 q1 q2 q3) + ; calc flat8in and hev masks + mova m6, [pb_81] ; [1 1 1 1 ...] ^ 0x80 + ABSSUB_CMP m2, m8, m11, m6, m4, m5 ; abs(p3 - p0) <= 1 + mova m8, [pb_80] + ABSSUB_CMP m1, m9, m11, m6, m4, m5, m8 ; abs(p2 - p0) <= 1 + pand m2, m1 + ABSSUB m4, m10, m11, m5 ; abs(p1 - p0) + pxor m0, m0 + movd m7, Hd + pshufb m7, m0 ; H H H H ... + pxor m7, m8 + pxor m4, m8 + pcmpgtb m0, m4, m7 ; abs(p1 - p0) > H (1/2 hev condition) + CMP_LTE m4, m6, m5 ; abs(p1 - p0) <= 1 + pand m2, m4 ; (flat8in) + ABSSUB m4, m13, m12, m1 ; abs(q1 - q0) + pxor m4, m8 + pcmpgtb m5, m4, m7 ; abs(q1 - q0) > H (2/2 hev condition) + por m0, m5 ; hev final value + CMP_LTE m4, m6, m5 ; abs(q1 - q0) <= 1 + pand m2, m4 ; (flat8in) + ABSSUB_CMP m1, m14, m12, m6, m4, m5, m8 ; abs(q2 - q0) <= 1 + pand m2, m1 + ABSSUB_CMP m1, m15, m12, m6, m4, m5, m8 ; abs(q3 - q0) <= 1 + pand m2, m1 ; flat8in final value + + ; (m0: hev, m2: flat8in, m3: fm, m6: pb_81, m9..15: p2 p1 p0 q0 q1 q2 q3) + ; calc flat8out mask + mova m8, [P7] + mova m9, [P6] + ABSSUB_CMP m1, m8, m11, m6, m4, m5 ; abs(p7 - p0) <= 1 + ABSSUB_CMP m7, m9, m11, m6, m4, m5 ; abs(p6 - p0) <= 1 + pand m1, m7 + mova m8, [P5] + mova m9, [P4] + ABSSUB_CMP m7, m8, m11, m6, m4, m5 ; abs(p5 - p0) <= 1 + pand m1, m7 + ABSSUB_CMP m7, m9, m11, m6, m4, m5 ; abs(p4 - p0) <= 1 + pand m1, m7 + mova m14, [Q4] + mova m15, [Q5] + ABSSUB_CMP m7, m14, m12, m6, m4, m5 ; abs(q4 - q0) <= 1 + pand m1, m7 + ABSSUB_CMP m7, m15, m12, m6, m4, m5 ; abs(q5 - q0) <= 1 + pand m1, m7 + mova m14, [Q6] + mova m15, [Q7] + ABSSUB_CMP m7, m14, m12, m6, m4, m5 ; abs(q4 - q0) <= 1 + pand m1, m7 + ABSSUB_CMP m7, m15, m12, m6, m4, m5 ; abs(q5 - q0) <= 1 + pand m1, m7 ; flat8out final value + + ; if (fm) { + ; if (out && in) filter_14() + ; else if (in) filter_6() + ; else if (hev) filter_2() + ; else filter_4() + ; } + ; + ; f14: fm & out & in + ; f6: fm & ~f14 & in => fm & ~(out & in) & in => fm & ~out & in + ; f2: fm & ~f14 & ~f6 & hev => fm & ~(out & in) & ~(~out & in) & hev => fm & ~in & hev + ; f4: fm & ~f14 & ~f6 & ~f2 => fm & ~(out & in) & ~(~out & in) & ~(~in & hev) => fm & ~in & ~hev + + ; (m0: hev, m1: flat8out, m2: flat8in, m3: fm, m8..15: p5 p4 p1 p0 q0 q1 q6 q7) + ; filter2() + mova m6, [pb_80] + pxor m15, m12, m6 ; q0 ^ 0x80 + pxor m14, m11, m6 ; p0 ^ 0x80 + psubsb m15, m14 ; (signed) q0 - p0 + pxor m4, m10, m6 ; p1 ^ 0x80 + pxor m5, m13, m6 ; q1 ^ 0x80 + psubsb m4, m5 ; (signed) p1 - q1 + paddsb m4, m15 ; (q0 - p0) + (p1 - q1) + paddsb m4, m15 ; 2*(q0 - p0) + (p1 - q1) + paddsb m4, m15 ; 3*(q0 - p0) + (p1 - q1) + paddsb m6, m4, [pb_4] ; m6: f1 = clip(f + 4, 127) + paddsb m4, [pb_3] ; m4: f2 = clip(f + 3, 127) + mova m14, [pb_10] ; will be reused in filter4() + SRSHIFT3B_2X m6, m4, m14, m7 ; f1 and f2 sign byte shift by 3 + SIGN_SUB m7, m12, m6, m5, m9 ; m7 = q0 - f1 + SIGN_ADD m8, m11, m4, m5, m9 ; m8 = p0 + f2 + pandn m6, m2, m3 ; ~mask(in) & mask(fm) + pand m6, m0 ; (~mask(in) & mask(fm)) & mask(hev) + MASK_APPLY m7, m12, m6, m5 ; m7 = filter2(q0) & mask / we write it in filter4() + MASK_APPLY m8, m11, m6, m5 ; m8 = filter2(p0) & mask / we write it in filter4() + + ; (m0: hev, m1: flat8out, m2: flat8in, m3: fm, m7..m8: q0' p0', m10..13: p1 p0 q0 q1, m14: pb_10, m15: q0-p0) + ; filter4() + mova m4, m15 + paddsb m15, m4 ; 2 * (q0 - p0) + paddsb m15, m4 ; 3 * (q0 - p0) + paddsb m6, m15, [pb_4] ; m6: f1 = clip(f + 4, 127) + paddsb m15, [pb_3] ; m15: f2 = clip(f + 3, 127) + SRSHIFT3B_2X m6, m15, m14, m9 ; f1 and f2 sign byte shift by 3 + pandn m5, m2, m3 ; ~mask(in) & mask(fm) + pandn m0, m5 ; ~mask(hev) & (~mask(in) & mask(fm)) + SIGN_SUB m9, m12, m6, m4, m14 ; q0 - f1 + MASK_APPLY m9, m7, m0, m5 ; m9 = filter4(q0) & mask + mova [Q0], m9 + SIGN_ADD m7, m11, m15, m4, m14 ; p0 + f2 + MASK_APPLY m7, m8, m0, m5 ; m7 = filter4(p0) & mask + mova [P0], m7 + paddb m6, [pb_80] ; + pxor m8, m8 ; f=(f1+1)>>1 + pavgb m6, m8 ; + psubb m6, [pb_40] ; + SIGN_ADD m7, m10, m6, m8, m9 ; p1 + f + SIGN_SUB m4, m13, m6, m8, m9 ; q1 - f + MASK_APPLY m7, m10, m0, m14 ; m7 = filter4(p1) + MASK_APPLY m4, m13, m0, m14 ; m4 = filter4(q1) + mova [P1], m7 + mova [Q1], m4 + + ; (m1: flat8out, m2: flat8in, m3: fm, m10..13: p1 p0 q0 q1) + ; filter6() + pxor m0, m0 + pand m2, m3 ; mask(fm) & mask(in) + pandn m3, m1, m2 ; ~mask(out) & (mask(fm) & mask(in)) + mova m14, [P3] + mova m15, [P2] + mova m8, [Q2] + mova m9, [Q3] + FILTER_INIT m4, m5, m6, m7, [P2], 6, m3, m15 ; [p2] + FILTER_UPDATE m6, m7, m4, m5, [P1], m14, m15, m10, m13, 3, m3 ; [p1] -p3 -p2 +p1 +q1 + FILTER_UPDATE m4, m5, m6, m7, [P0], m14, m10, m11, m8, 3, m3 ; [p0] -p3 -p1 +p0 +q2 + FILTER_UPDATE m6, m7, m4, m5, [Q0], m14, m11, m12, m9, 3, m3 ; [q0] -p3 -p0 +q0 +q3 + FILTER_UPDATE m4, m5, m6, m7, [Q1], m15, m12, m13, m9, 3, m3 ; [q1] -p2 -q0 +q1 +q3 + FILTER_UPDATE m6, m7, m4, m5, [Q2], m10, m13, m8, m9, 3, m3, m8 ; [q2] -p1 -q1 +q2 +q3 + + ; (m0: 0, m1: flat8out, m2: fm & flat8in, m8..15: q2 q3 p1 p0 q0 q1 p3 p2) + ; filter14() + ; + ; m2 m3 m8 m9 m14 m15 m10 m11 m12 m13 + ; + ; q2 q3 p3 p2 p1 p0 q0 q1 + ; p6 -7 p7 p6 p5 p4 . . . . . + ; p5 -6 -p7 -p6 +p5 +q1 . . . . + ; p4 -5 -p7 -p5 +p4 +q2 . . . q2 + ; p3 -4 -p7 -p4 +p3 +q3 . . . q3 + ; p2 -3 -p7 -p3 +p2 +q4 . . . q4 + ; p1 -2 -p7 -p2 +p1 +q5 . . . q5 + ; p0 -1 -p7 -p1 +p0 +q6 . . . q6 + ; q0 +0 -p7 -p0 +q0 +q7 . . . q7 + ; q1 +1 -p6 -q0 +q1 +q7 q1 . . . + ; q2 +2 -p5 -q1 +q2 +q7 . q2 . . + ; q3 +3 -p4 -q2 +q3 +q7 . q3 . . + ; q4 +4 -p3 -q3 +q4 +q7 . q4 . . + ; q5 +5 -p2 -q4 +q5 +q7 . q5 . . + ; q6 +6 -p1 -q5 +q6 +q7 . q6 . . + + pand m1, m2 ; mask(out) & (mask(fm) & mask(in)) + mova m2, [P7] + mova m3, [P6] + mova m8, [P5] + mova m9, [P4] + FILTER_INIT m4, m5, m6, m7, [P6], 14, m1, m3 + FILTER_UPDATE m6, m7, m4, m5, [P5], m2, m3, m8, m13, 4, m1, m8 ; [p5] -p7 -p6 +p5 +q1 + FILTER_UPDATE m4, m5, m6, m7, [P4], m2, m8, m9, m13, 4, m1, m9, m13, [Q2] ; [p4] -p7 -p5 +p4 +q2 + FILTER_UPDATE m6, m7, m4, m5, [P3], m2, m9, m14, m13, 4, m1, m14, m13, [Q3] ; [p3] -p7 -p4 +p3 +q3 + FILTER_UPDATE m4, m5, m6, m7, [P2], m2, m14, m15, m13, 4, m1, m13, [Q4] ; [p2] -p7 -p3 +p2 +q4 + FILTER_UPDATE m6, m7, m4, m5, [P1], m2, m15, m10, m13, 4, m1, m13, [Q5] ; [p1] -p7 -p2 +p1 +q5 + FILTER_UPDATE m4, m5, m6, m7, [P0], m2, m10, m11, m13, 4, m1, m13, [Q6] ; [p0] -p7 -p1 +p0 +q6 + FILTER_UPDATE m6, m7, m4, m5, [Q0], m2, m11, m12, m13, 4, m1, m13, [Q7] ; [q0] -p7 -p0 +q0 +q7 + FILTER_UPDATE m4, m5, m6, m7, [Q1], m3, m12, m2, m13, 4, m1, m2, [Q1] ; [q1] -p6 -q0 +q1 +q7 + FILTER_UPDATE m6, m7, m4, m5, [Q2], m8, m2, m3, m13, 4, m1, m3, [Q2] ; [q2] -p5 -q1 +q2 +q7 + FILTER_UPDATE m4, m5, m6, m7, [Q3], m9, m3, m8, m13, 4, m1, m8, m8, [Q3] ; [q3] -p4 -q2 +q3 +q7 + FILTER_UPDATE m6, m7, m4, m5, [Q4], m14, m8, m9, m13, 4, m1, m9, m9, [Q4] ; [q4] -p3 -q3 +q4 +q7 + FILTER_UPDATE m4, m5, m6, m7, [Q5], m15, m9, m14, m13, 4, m1, m14, m14, [Q5] ; [q5] -p2 -q4 +q5 +q7 + FILTER_UPDATE m6, m7, m4, m5, [Q6], m10, m14, m15, m13, 4, m1, m15, m15, [Q6] ; [q6] -p1 -q5 +q6 +q7 + +%ifidn %1, h + mova m0, [P7] + mova m1, [P6] + mova m2, [P5] + mova m3, [P4] + mova m4, [P3] + mova m5, [P2] + mova m6, [P1] + mova m7, [P0] + mova m8, [Q0] + mova m9, [Q1] + mova m10, [Q2] + mova m11, [Q3] + mova m12, [Q4] + mova m13, [Q5] + mova m14, [Q6] + mova m15, [Q7] + TRANSPOSE16x16B 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, [rsp] + DEFINE_REAL_P7_TO_Q7 + movu [P7], m0 + movu [P6], m1 + movu [P5], m2 + movu [P4], m3 + movu [P3], m4 + movu [P2], m5 + movu [P1], m6 + movu [P0], m7 + movu [Q0], m8 + movu [Q1], m9 + movu [Q2], m10 + movu [Q3], m11 + movu [Q4], m12 + movu [Q5], m13 + movu [Q6], m14 + movu [Q7], m15 +%endif +%endmacro + +%macro LPF_16_16_VH 1 +INIT_XMM %1 +cglobal vp9_loop_filter_v_16_16, 5,10,16, dst, stride, E, I, H, mstride, dst1, dst2, stride3, mstride3 + LPF_16_16 v + RET +cglobal vp9_loop_filter_h_16_16, 5,10,16, 256, dst, stride, E, I, H, mstride, dst1, dst2, stride3, mstride3 + LPF_16_16 h + RET +%endmacro + +LPF_16_16_VH ssse3 +LPF_16_16_VH avx + +%endif ; x86-64 From 1f451eed606b680751e429660cc0945c60d0430c Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 17 Jan 2014 03:55:44 -0300 Subject: [PATCH 0252/3374] vp9lpf/x86: add ff_vp9_loop_filter_[vh]_16_16_sse2(). Similar gains in performance as the SSSE3 version Signed-off-by: James Almer Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9dsp_init.c | 19 +++++++++++++++---- libavcodec/x86/vp9lpf.asm | 14 ++++++++------ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c index 93453b83e3347..139603c82f3bb 100644 --- a/libavcodec/x86/vp9dsp_init.c +++ b/libavcodec/x86/vp9dsp_init.c @@ -217,10 +217,17 @@ filters_8tap_1d_fn2(avg, 32, avx2, ssse3) #undef filters_8tap_1d_fn3 #undef filter_8tap_1d_fn -void ff_vp9_loop_filter_v_16_16_ssse3(uint8_t *dst, ptrdiff_t stride, int E, int I, int H); -void ff_vp9_loop_filter_v_16_16_avx (uint8_t *dst, ptrdiff_t stride, int E, int I, int H); -void ff_vp9_loop_filter_h_16_16_ssse3(uint8_t *dst, ptrdiff_t stride, int E, int I, int H); -void ff_vp9_loop_filter_h_16_16_avx (uint8_t *dst, ptrdiff_t stride, int E, int I, int H); +#define lpf_funcs(size1, size2, opt) \ +void ff_vp9_loop_filter_v_##size1##_##size2##_##opt(uint8_t *dst, ptrdiff_t stride, \ + int E, int I, int H); \ +void ff_vp9_loop_filter_h_##size1##_##size2##_##opt(uint8_t *dst, ptrdiff_t stride, \ + int E, int I, int H) + +lpf_funcs(16, 16, sse2); +lpf_funcs(16, 16, ssse3); +lpf_funcs(16, 16, avx); + +#undef lpf_funcs #endif /* HAVE_YASM */ @@ -283,6 +290,10 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) init_fpel(2, 1, 16, avg, sse2); init_fpel(1, 1, 32, avg, sse2); init_fpel(0, 1, 64, avg, sse2); + if (ARCH_X86_64) { + dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_sse2; + dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_sse2; + } } if (EXTERNAL_SSSE3(cpu_flags)) { diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index 8568f1d6139ae..d4c70f5b9c674 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -327,11 +327,11 @@ SECTION .text %endif ; calc fm mask +%if cpuflag(ssse3) pxor m0, m0 - movd m2, Id - movd m3, Ed - pshufb m2, m0 ; I I I I ... - pshufb m3, m0 ; E E E E ... +%endif + SPLATB_REG m2, I, m0 ; I I I I ... + SPLATB_REG m3, E, m0 ; E E E E ... mova m0, [pb_80] pxor m2, m0 pxor m3, m0 @@ -383,9 +383,10 @@ SECTION .text ABSSUB_CMP m1, m9, m11, m6, m4, m5, m8 ; abs(p2 - p0) <= 1 pand m2, m1 ABSSUB m4, m10, m11, m5 ; abs(p1 - p0) +%if cpuflag(ssse3) pxor m0, m0 - movd m7, Hd - pshufb m7, m0 ; H H H H ... +%endif + SPLATB_REG m7, H, m0 ; H H H H ... pxor m7, m8 pxor m4, m8 pcmpgtb m0, m4, m7 ; abs(p1 - p0) > H (1/2 hev condition) @@ -595,6 +596,7 @@ cglobal vp9_loop_filter_h_16_16, 5,10,16, 256, dst, stride, E, I, H, mstride, ds RET %endmacro +LPF_16_16_VH sse2 LPF_16_16_VH ssse3 LPF_16_16_VH avx From 6bea478158910b1a5cac4f3fd739cad8ec5740ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sat, 25 Jan 2014 17:38:42 +0100 Subject: [PATCH 0253/3374] vp9lpf/x86: add ff_vp9_loop_filter_[vh]_88_16_{ssse3,avx}. Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9dsp_init.c | 6 ++ libavcodec/x86/vp9lpf.asm | 184 ++++++++++++++++++++++++++++++----- 2 files changed, 163 insertions(+), 27 deletions(-) diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c index 139603c82f3bb..00a57984fbc09 100644 --- a/libavcodec/x86/vp9dsp_init.c +++ b/libavcodec/x86/vp9dsp_init.c @@ -226,6 +226,8 @@ void ff_vp9_loop_filter_h_##size1##_##size2##_##opt(uint8_t *dst, ptrdiff_t stri lpf_funcs(16, 16, sse2); lpf_funcs(16, 16, ssse3); lpf_funcs(16, 16, avx); +lpf_funcs(88, 16, ssse3); +lpf_funcs(88, 16, avx); #undef lpf_funcs @@ -301,6 +303,8 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) init_subpel3(1, avg, ssse3); if (ARCH_X86_64) { + dsp->loop_filter_mix2[1][1][0] = ff_vp9_loop_filter_h_88_16_ssse3; + dsp->loop_filter_mix2[1][1][1] = ff_vp9_loop_filter_v_88_16_ssse3; dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_ssse3; dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_ssse3; } @@ -311,6 +315,8 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) init_fpel(0, 0, 64, put, avx); if (ARCH_X86_64) { + dsp->loop_filter_mix2[1][1][0] = ff_vp9_loop_filter_h_88_16_avx; + dsp->loop_filter_mix2[1][1][1] = ff_vp9_loop_filter_v_88_16_avx; dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_avx; dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_avx; } diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index d4c70f5b9c674..183f3f68745d3 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -40,6 +40,11 @@ pb_fe: times 16 db 0xfe pw_4: times 8 dw 4 pw_8: times 8 dw 8 +; with mix functions, two 8-bit thresholds are stored in a 16-bit storage, +; the following mask is used to splat both in the same register +mask_mix: times 8 db 0 + times 8 db 1 + SECTION .text ; %1 = abs(%2-%3) @@ -236,6 +241,38 @@ SECTION .text SWAP %12, %14 %endmacro +; transpose 16 half lines (high part) to 8 full centered lines +%macro TRANSPOSE16x8B 16 + punpcklbw m%1, m%2 + punpcklbw m%3, m%4 + punpcklbw m%5, m%6 + punpcklbw m%7, m%8 + punpcklbw m%9, m%10 + punpcklbw m%11, m%12 + punpcklbw m%13, m%14 + punpcklbw m%15, m%16 + SBUTTERFLY wd, %1, %3, %2 + SBUTTERFLY wd, %5, %7, %2 + SBUTTERFLY wd, %9, %11, %2 + SBUTTERFLY wd, %13, %15, %2 + SBUTTERFLY dq, %1, %5, %2 + SBUTTERFLY dq, %3, %7, %2 + SBUTTERFLY dq, %9, %13, %2 + SBUTTERFLY dq, %11, %15, %2 + SBUTTERFLY qdq, %1, %9, %2 + SBUTTERFLY qdq, %3, %11, %2 + SBUTTERFLY qdq, %5, %13, %2 + SBUTTERFLY qdq, %7, %15, %2 + SWAP %5, %1 + SWAP %6, %9 + SWAP %7, %1 + SWAP %8, %13 + SWAP %9, %3 + SWAP %10, %11 + SWAP %11, %1 + SWAP %12, %15 +%endmacro + %macro DEFINE_REAL_P7_TO_Q7 0 %define P7 dst1q + 2*mstrideq %define P6 dst1q + mstrideq @@ -255,7 +292,7 @@ SECTION .text %define Q7 dst2q + strideq %endmacro -%macro LPF_16_16 1 +%macro LOOPFILTER 2 ; %1=v/h %2=size1 lea mstrideq, [strideq] neg mstrideq @@ -264,7 +301,13 @@ SECTION .text neg mstride3q %ifidn %1, h +%if %2 == 88 +%define movx movh + lea dstq, [dstq + 8*strideq - 4] +%else +%define movx movu lea dstq, [dstq + 8*strideq - 8] ; go from top center (h pos) to center left (v pos) +%endif %endif lea dst1q, [dstq + 2*mstride3q] ; dst1q = &dst[stride * -6] @@ -273,24 +316,22 @@ SECTION .text DEFINE_REAL_P7_TO_Q7 %ifidn %1, h - movu m0, [P7] - movu m1, [P6] - movu m2, [P5] - movu m3, [P4] - movu m4, [P3] - movu m5, [P2] - movu m6, [P1] - movu m7, [P0] - movu m8, [Q0] - movu m9, [Q1] - movu m10, [Q2] - movu m11, [Q3] - movu m12, [Q4] - movu m13, [Q5] - movu m14, [Q6] - movu m15, [Q7] - TRANSPOSE16x16B 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, [rsp] - + movx m0, [P7] + movx m1, [P6] + movx m2, [P5] + movx m3, [P4] + movx m4, [P3] + movx m5, [P2] + movx m6, [P1] + movx m7, [P0] + movx m8, [Q0] + movx m9, [Q1] + movx m10, [Q2] + movx m11, [Q3] + movx m12, [Q4] + movx m13, [Q5] + movx m14, [Q6] + movx m15, [Q7] %define P7 rsp + 0 %define P6 rsp + 16 %define P5 rsp + 32 @@ -308,10 +349,15 @@ SECTION .text %define Q6 rsp + 224 %define Q7 rsp + 240 +%if %2 != 88 + TRANSPOSE16x16B 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, [rsp] mova [P7], m0 mova [P6], m1 mova [P5], m2 mova [P4], m3 +%else + TRANSPOSE16x8B 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 +%endif mova [P3], m4 mova [P2], m5 mova [P1], m6 @@ -320,18 +366,28 @@ SECTION .text mova [Q1], m9 mova [Q2], m10 mova [Q3], m11 +%if %2 != 88 mova [Q4], m12 mova [Q5], m13 mova [Q6], m14 mova [Q7], m15 +%endif %endif ; calc fm mask +%if %2 == 16 %if cpuflag(ssse3) pxor m0, m0 %endif SPLATB_REG m2, I, m0 ; I I I I ... SPLATB_REG m3, E, m0 ; E E E E ... +%elif %2 == 88 + mova m0, [mask_mix] + movd m2, Id + movd m3, Ed + pshufb m2, m0 + pshufb m3, m0 +%endif mova m0, [pb_80] pxor m2, m0 pxor m3, m0 @@ -383,10 +439,15 @@ SECTION .text ABSSUB_CMP m1, m9, m11, m6, m4, m5, m8 ; abs(p2 - p0) <= 1 pand m2, m1 ABSSUB m4, m10, m11, m5 ; abs(p1 - p0) +%if %2 != 88 %if cpuflag(ssse3) pxor m0, m0 %endif SPLATB_REG m7, H, m0 ; H H H H ... +%else + movd m7, Hd + pshufb m7, [mask_mix] +%endif pxor m7, m8 pxor m4, m8 pcmpgtb m0, m4, m7 ; abs(p1 - p0) > H (1/2 hev condition) @@ -403,6 +464,7 @@ SECTION .text ABSSUB_CMP m1, m15, m12, m6, m4, m5, m8 ; abs(q3 - q0) <= 1 pand m2, m1 ; flat8in final value +%if %2 != 88 ; (m0: hev, m2: flat8in, m3: fm, m6: pb_81, m9..15: p2 p1 p0 q0 q1 q2 q3) ; calc flat8out mask mova m8, [P7] @@ -428,6 +490,7 @@ SECTION .text pand m1, m7 ABSSUB_CMP m7, m15, m12, m6, m4, m5 ; abs(q5 - q0) <= 1 pand m1, m7 ; flat8out final value +%endif ; if (fm) { ; if (out && in) filter_14() @@ -441,7 +504,7 @@ SECTION .text ; f2: fm & ~f14 & ~f6 & hev => fm & ~(out & in) & ~(~out & in) & hev => fm & ~in & hev ; f4: fm & ~f14 & ~f6 & ~f2 => fm & ~(out & in) & ~(~out & in) & ~(~in & hev) => fm & ~in & ~hev - ; (m0: hev, m1: flat8out, m2: flat8in, m3: fm, m8..15: p5 p4 p1 p0 q0 q1 q6 q7) + ; (m0: hev, [m1: flat8out], m2: flat8in, m3: fm, m8..15: p5 p4 p1 p0 q0 q1 q6 q7) ; filter2() mova m6, [pb_80] pxor m15, m12, m6 ; q0 ^ 0x80 @@ -464,7 +527,7 @@ SECTION .text MASK_APPLY m7, m12, m6, m5 ; m7 = filter2(q0) & mask / we write it in filter4() MASK_APPLY m8, m11, m6, m5 ; m8 = filter2(p0) & mask / we write it in filter4() - ; (m0: hev, m1: flat8out, m2: flat8in, m3: fm, m7..m8: q0' p0', m10..13: p1 p0 q0 q1, m14: pb_10, m15: q0-p0) + ; (m0: hev, [m1: flat8out], m2: flat8in, m3: fm, m7..m8: q0' p0', m10..13: p1 p0 q0 q1, m14: pb_10, m15: q0-p0) ; filter4() mova m4, m15 paddsb m15, m4 ; 2 * (q0 - p0) @@ -491,11 +554,15 @@ SECTION .text mova [P1], m7 mova [Q1], m4 - ; (m1: flat8out, m2: flat8in, m3: fm, m10..13: p1 p0 q0 q1) + ; ([m1: flat8out], m2: flat8in, m3: fm, m10..13: p1 p0 q0 q1) ; filter6() pxor m0, m0 +%if %2 == 88 + pand m3, m2 +%else pand m2, m3 ; mask(fm) & mask(in) pandn m3, m1, m2 ; ~mask(out) & (mask(fm) & mask(in)) +%endif mova m14, [P3] mova m15, [P2] mova m8, [Q2] @@ -507,7 +574,7 @@ SECTION .text FILTER_UPDATE m4, m5, m6, m7, [Q1], m15, m12, m13, m9, 3, m3 ; [q1] -p2 -q0 +q1 +q3 FILTER_UPDATE m6, m7, m4, m5, [Q2], m10, m13, m8, m9, 3, m3, m8 ; [q2] -p1 -q1 +q2 +q3 - ; (m0: 0, m1: flat8out, m2: fm & flat8in, m8..15: q2 q3 p1 p0 q0 q1 p3 p2) + ; (m0: 0, [m1: flat8out], m2: fm & flat8in, m8..15: q2 q3 p1 p0 q0 q1 p3 p2) ; filter14() ; ; m2 m3 m8 m9 m14 m15 m10 m11 m12 m13 @@ -528,6 +595,7 @@ SECTION .text ; q5 +5 -p2 -q4 +q5 +q7 . q5 . . ; q6 +6 -p1 -q5 +q6 +q7 . q6 . . +%if %2 != 88 pand m1, m2 ; mask(out) & (mask(fm) & mask(in)) mova m2, [P7] mova m3, [P6] @@ -547,8 +615,10 @@ SECTION .text FILTER_UPDATE m6, m7, m4, m5, [Q4], m14, m8, m9, m13, 4, m1, m9, m9, [Q4] ; [q4] -p3 -q3 +q4 +q7 FILTER_UPDATE m4, m5, m6, m7, [Q5], m15, m9, m14, m13, 4, m1, m14, m14, [Q5] ; [q5] -p2 -q4 +q5 +q7 FILTER_UPDATE m6, m7, m4, m5, [Q6], m10, m14, m15, m13, 4, m1, m15, m15, [Q6] ; [q6] -p1 -q5 +q6 +q7 +%endif %ifidn %1, h +%if %2 != 88 mova m0, [P7] mova m1, [P6] mova m2, [P5] @@ -583,21 +653,81 @@ SECTION .text movu [Q5], m13 movu [Q6], m14 movu [Q7], m15 +%else + ; the following code do a transpose of 8 full lines to 16 half + ; lines (high part). It is inlined to avoid the need of a staging area + mova m0, [P3] + mova m1, [P2] + mova m2, [P1] + mova m3, [P0] + mova m4, [Q0] + mova m5, [Q1] + mova m6, [Q2] + mova m7, [Q3] + DEFINE_REAL_P7_TO_Q7 + SBUTTERFLY bw, 0, 1, 8 + SBUTTERFLY bw, 2, 3, 8 + SBUTTERFLY bw, 4, 5, 8 + SBUTTERFLY bw, 6, 7, 8 + SBUTTERFLY wd, 0, 2, 8 + SBUTTERFLY wd, 1, 3, 8 + SBUTTERFLY wd, 4, 6, 8 + SBUTTERFLY wd, 5, 7, 8 + SBUTTERFLY dq, 0, 4, 8 + SBUTTERFLY dq, 1, 5, 8 + SBUTTERFLY dq, 2, 6, 8 + SBUTTERFLY dq, 3, 7, 8 + movh [P7], m0 + punpckhqdq m0, m8 + movh [P6], m0 + movh [Q0], m1 + punpckhqdq m1, m9 + movh [Q1], m1 + movh [P3], m2 + punpckhqdq m2, m10 + movh [P2], m2 + movh [Q4], m3 + punpckhqdq m3, m11 + movh [Q5], m3 + movh [P5], m4 + punpckhqdq m4, m12 + movh [P4], m4 + movh [Q2], m5 + punpckhqdq m5, m13 + movh [Q3], m5 + movh [P1], m6 + punpckhqdq m6, m14 + movh [P0], m6 + movh [Q6], m7 + punpckhqdq m7, m8 + movh [Q7], m7 +%endif %endif + + RET %endmacro %macro LPF_16_16_VH 1 INIT_XMM %1 cglobal vp9_loop_filter_v_16_16, 5,10,16, dst, stride, E, I, H, mstride, dst1, dst2, stride3, mstride3 - LPF_16_16 v - RET + LOOPFILTER v, 16 cglobal vp9_loop_filter_h_16_16, 5,10,16, 256, dst, stride, E, I, H, mstride, dst1, dst2, stride3, mstride3 - LPF_16_16 h - RET + LOOPFILTER h, 16 +%endmacro + +%macro LPF_88_16_VH 1 +INIT_XMM %1 +cglobal vp9_loop_filter_v_88_16, 5,10,16, dst, stride, E, I, H, mstride, dst1, dst2, stride3, mstride3 + LOOPFILTER v, 88 +cglobal vp9_loop_filter_h_88_16, 5,10,16, 256, dst, stride, E, I, H, mstride, dst1, dst2, stride3, mstride3 + LOOPFILTER h, 88 %endmacro LPF_16_16_VH sse2 LPF_16_16_VH ssse3 LPF_16_16_VH avx +LPF_88_16_VH ssse3 +LPF_88_16_VH avx + %endif ; x86-64 From 92d47550ea099fde8c6f4443c94ec768e19ffd26 Mon Sep 17 00:00:00 2001 From: James Almer Date: Tue, 28 Jan 2014 04:59:45 -0300 Subject: [PATCH 0254/3374] vp9lpf/x86: add an SSE2 version of vp9_loop_filter_[vh]_88_16 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similar gains as the ssse3 version once again Additional improvements by Clément Bœsch . Signed-off-by: James Almer Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9dsp_init.c | 3 +++ libavcodec/x86/vp9lpf.asm | 20 +++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c index 00a57984fbc09..37d53d21b22e1 100644 --- a/libavcodec/x86/vp9dsp_init.c +++ b/libavcodec/x86/vp9dsp_init.c @@ -226,6 +226,7 @@ void ff_vp9_loop_filter_h_##size1##_##size2##_##opt(uint8_t *dst, ptrdiff_t stri lpf_funcs(16, 16, sse2); lpf_funcs(16, 16, ssse3); lpf_funcs(16, 16, avx); +lpf_funcs(88, 16, sse2); lpf_funcs(88, 16, ssse3); lpf_funcs(88, 16, avx); @@ -293,6 +294,8 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) init_fpel(1, 1, 32, avg, sse2); init_fpel(0, 1, 64, avg, sse2); if (ARCH_X86_64) { + dsp->loop_filter_mix2[1][1][0] = ff_vp9_loop_filter_h_88_16_sse2; + dsp->loop_filter_mix2[1][1][1] = ff_vp9_loop_filter_v_88_16_sse2; dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_sse2; dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_sse2; } diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index 183f3f68745d3..bde3fcb22b746 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -292,6 +292,17 @@ SECTION .text %define Q7 dst2q + strideq %endmacro +; ..............AB -> AAAAAAAABBBBBBBB +%macro SPLATB_MIX 1-2 [mask_mix] +%if cpuflag(ssse3) + pshufb %1, %2 +%else + punpcklbw %1, %1 + punpcklwd %1, %1 + punpckldq %1, %1 +%endif +%endmacro + %macro LOOPFILTER 2 ; %1=v/h %2=size1 lea mstrideq, [strideq] neg mstrideq @@ -382,11 +393,13 @@ SECTION .text SPLATB_REG m2, I, m0 ; I I I I ... SPLATB_REG m3, E, m0 ; E E E E ... %elif %2 == 88 +%if cpuflag(ssse3) mova m0, [mask_mix] +%endif movd m2, Id movd m3, Ed - pshufb m2, m0 - pshufb m3, m0 + SPLATB_MIX m2, m0 + SPLATB_MIX m3, m0 %endif mova m0, [pb_80] pxor m2, m0 @@ -446,7 +459,7 @@ SECTION .text SPLATB_REG m7, H, m0 ; H H H H ... %else movd m7, Hd - pshufb m7, [mask_mix] + SPLATB_MIX m7 %endif pxor m7, m8 pxor m4, m8 @@ -727,6 +740,7 @@ LPF_16_16_VH sse2 LPF_16_16_VH ssse3 LPF_16_16_VH avx +LPF_88_16_VH sse2 LPF_88_16_VH ssse3 LPF_88_16_VH avx From f2e3d706a16d51dfc6862ab0c8798fc42aa500c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Thu, 30 Jan 2014 19:01:30 +0100 Subject: [PATCH 0255/3374] vp9lpf/x86: add ff_vp9_loop_filter_h_{48,84}_16_{sse2,ssse3,avx}(). Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9dsp_init.c | 42 +++++++++++++------------ libavcodec/x86/vp9lpf.asm | 59 +++++++++++++++++++----------------- 2 files changed, 53 insertions(+), 48 deletions(-) diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c index 37d53d21b22e1..b64937249402d 100644 --- a/libavcodec/x86/vp9dsp_init.c +++ b/libavcodec/x86/vp9dsp_init.c @@ -226,6 +226,12 @@ void ff_vp9_loop_filter_h_##size1##_##size2##_##opt(uint8_t *dst, ptrdiff_t stri lpf_funcs(16, 16, sse2); lpf_funcs(16, 16, ssse3); lpf_funcs(16, 16, avx); +lpf_funcs(84, 16, sse2); +lpf_funcs(84, 16, ssse3); +lpf_funcs(84, 16, avx); +lpf_funcs(48, 16, sse2); +lpf_funcs(48, 16, ssse3); +lpf_funcs(48, 16, avx); lpf_funcs(88, 16, sse2); lpf_funcs(88, 16, ssse3); lpf_funcs(88, 16, avx); @@ -269,6 +275,19 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) init_subpel3_8to64(idx, type, opt); \ init_subpel2(4, idx, 4, type, opt) +#define init_lpf(opt) do { \ + if (ARCH_X86_64) { \ + dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_##opt; \ + dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_##opt; \ + dsp->loop_filter_mix2[0][1][0] = ff_vp9_loop_filter_h_48_16_##opt; \ + dsp->loop_filter_mix2[0][1][1] = ff_vp9_loop_filter_v_48_16_##opt; \ + dsp->loop_filter_mix2[1][0][0] = ff_vp9_loop_filter_h_84_16_##opt; \ + dsp->loop_filter_mix2[1][0][1] = ff_vp9_loop_filter_v_84_16_##opt; \ + dsp->loop_filter_mix2[1][1][0] = ff_vp9_loop_filter_h_88_16_##opt; \ + dsp->loop_filter_mix2[1][1][1] = ff_vp9_loop_filter_v_88_16_##opt; \ + } \ +} while (0) + if (EXTERNAL_MMX(cpu_flags)) { init_fpel(4, 0, 4, put, mmx); init_fpel(3, 0, 8, put, mmx); @@ -293,36 +312,19 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) init_fpel(2, 1, 16, avg, sse2); init_fpel(1, 1, 32, avg, sse2); init_fpel(0, 1, 64, avg, sse2); - if (ARCH_X86_64) { - dsp->loop_filter_mix2[1][1][0] = ff_vp9_loop_filter_h_88_16_sse2; - dsp->loop_filter_mix2[1][1][1] = ff_vp9_loop_filter_v_88_16_sse2; - dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_sse2; - dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_sse2; - } + init_lpf(sse2); } if (EXTERNAL_SSSE3(cpu_flags)) { init_subpel3(0, put, ssse3); init_subpel3(1, avg, ssse3); - - if (ARCH_X86_64) { - dsp->loop_filter_mix2[1][1][0] = ff_vp9_loop_filter_h_88_16_ssse3; - dsp->loop_filter_mix2[1][1][1] = ff_vp9_loop_filter_v_88_16_ssse3; - dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_ssse3; - dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_ssse3; - } + init_lpf(ssse3); } if (EXTERNAL_AVX(cpu_flags)) { init_fpel(1, 0, 32, put, avx); init_fpel(0, 0, 64, put, avx); - - if (ARCH_X86_64) { - dsp->loop_filter_mix2[1][1][0] = ff_vp9_loop_filter_h_88_16_avx; - dsp->loop_filter_mix2[1][1][1] = ff_vp9_loop_filter_v_88_16_avx; - dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_avx; - dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_avx; - } + init_lpf(avx); } if (EXTERNAL_AVX2(cpu_flags)) { diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index bde3fcb22b746..5377d96e7eb65 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -45,6 +45,11 @@ pw_8: times 8 dw 8 mask_mix: times 8 db 0 times 8 db 1 +mask_mix84: times 8 db 0xff + times 8 db 0x00 +mask_mix48: times 8 db 0x00 + times 8 db 0xff + SECTION .text ; %1 = abs(%2-%3) @@ -312,7 +317,7 @@ SECTION .text neg mstride3q %ifidn %1, h -%if %2 == 88 +%if %2 > 16 %define movx movh lea dstq, [dstq + 8*strideq - 4] %else @@ -360,7 +365,7 @@ SECTION .text %define Q6 rsp + 224 %define Q7 rsp + 240 -%if %2 != 88 +%if %2 == 16 TRANSPOSE16x16B 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, [rsp] mova [P7], m0 mova [P6], m1 @@ -377,7 +382,7 @@ SECTION .text mova [Q1], m9 mova [Q2], m10 mova [Q3], m11 -%if %2 != 88 +%if %2 == 16 mova [Q4], m12 mova [Q5], m13 mova [Q6], m14 @@ -392,7 +397,7 @@ SECTION .text %endif SPLATB_REG m2, I, m0 ; I I I I ... SPLATB_REG m3, E, m0 ; E E E E ... -%elif %2 == 88 +%else %if cpuflag(ssse3) mova m0, [mask_mix] %endif @@ -452,7 +457,7 @@ SECTION .text ABSSUB_CMP m1, m9, m11, m6, m4, m5, m8 ; abs(p2 - p0) <= 1 pand m2, m1 ABSSUB m4, m10, m11, m5 ; abs(p1 - p0) -%if %2 != 88 +%if %2 == 16 %if cpuflag(ssse3) pxor m0, m0 %endif @@ -476,8 +481,11 @@ SECTION .text pand m2, m1 ABSSUB_CMP m1, m15, m12, m6, m4, m5, m8 ; abs(q3 - q0) <= 1 pand m2, m1 ; flat8in final value +%if %2 == 84 || %2 == 48 + pand m2, [mask_mix%2] +%endif -%if %2 != 88 +%if %2 == 16 ; (m0: hev, m2: flat8in, m3: fm, m6: pb_81, m9..15: p2 p1 p0 q0 q1 q2 q3) ; calc flat8out mask mova m8, [P7] @@ -570,7 +578,7 @@ SECTION .text ; ([m1: flat8out], m2: flat8in, m3: fm, m10..13: p1 p0 q0 q1) ; filter6() pxor m0, m0 -%if %2 == 88 +%if %2 > 16 pand m3, m2 %else pand m2, m3 ; mask(fm) & mask(in) @@ -608,7 +616,7 @@ SECTION .text ; q5 +5 -p2 -q4 +q5 +q7 . q5 . . ; q6 +6 -p1 -q5 +q6 +q7 . q6 . . -%if %2 != 88 +%if %2 == 16 pand m1, m2 ; mask(out) & (mask(fm) & mask(in)) mova m2, [P7] mova m3, [P6] @@ -631,7 +639,7 @@ SECTION .text %endif %ifidn %1, h -%if %2 != 88 +%if %2 == 16 mova m0, [P7] mova m1, [P6] mova m2, [P5] @@ -720,28 +728,23 @@ SECTION .text RET %endmacro -%macro LPF_16_16_VH 1 -INIT_XMM %1 -cglobal vp9_loop_filter_v_16_16, 5,10,16, dst, stride, E, I, H, mstride, dst1, dst2, stride3, mstride3 - LOOPFILTER v, 16 -cglobal vp9_loop_filter_h_16_16, 5,10,16, 256, dst, stride, E, I, H, mstride, dst1, dst2, stride3, mstride3 - LOOPFILTER h, 16 +%macro LPF_16_VH 2 +INIT_XMM %2 +cglobal vp9_loop_filter_v_%1_16, 5,10,16, dst, stride, E, I, H, mstride, dst1, dst2, stride3, mstride3 + LOOPFILTER v, %1 +cglobal vp9_loop_filter_h_%1_16, 5,10,16, 256, dst, stride, E, I, H, mstride, dst1, dst2, stride3, mstride3 + LOOPFILTER h, %1 %endmacro -%macro LPF_88_16_VH 1 -INIT_XMM %1 -cglobal vp9_loop_filter_v_88_16, 5,10,16, dst, stride, E, I, H, mstride, dst1, dst2, stride3, mstride3 - LOOPFILTER v, 88 -cglobal vp9_loop_filter_h_88_16, 5,10,16, 256, dst, stride, E, I, H, mstride, dst1, dst2, stride3, mstride3 - LOOPFILTER h, 88 +%macro LPF_16_VH_ALL_OPTS 1 +LPF_16_VH %1, sse2 +LPF_16_VH %1, ssse3 +LPF_16_VH %1, avx %endmacro -LPF_16_16_VH sse2 -LPF_16_16_VH ssse3 -LPF_16_16_VH avx - -LPF_88_16_VH sse2 -LPF_88_16_VH ssse3 -LPF_88_16_VH avx +LPF_16_VH_ALL_OPTS 16 +LPF_16_VH_ALL_OPTS 48 +LPF_16_VH_ALL_OPTS 84 +LPF_16_VH_ALL_OPTS 88 %endif ; x86-64 From 0ed21bdc9e7f9ef557a7d63fbaa6ce65eb455b9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 5 Feb 2014 07:21:06 +0100 Subject: [PATCH 0256/3374] vp9lpf/x86: add ff_vp9_loop_filter_[vh]_44_16_{sse2,ssse3,avx}. Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9dsp_init.c | 5 ++ libavcodec/x86/vp9lpf.asm | 121 +++++++++++++++++++++++++++-------- 2 files changed, 99 insertions(+), 27 deletions(-) diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c index b64937249402d..88267b9fc9422 100644 --- a/libavcodec/x86/vp9dsp_init.c +++ b/libavcodec/x86/vp9dsp_init.c @@ -226,6 +226,9 @@ void ff_vp9_loop_filter_h_##size1##_##size2##_##opt(uint8_t *dst, ptrdiff_t stri lpf_funcs(16, 16, sse2); lpf_funcs(16, 16, ssse3); lpf_funcs(16, 16, avx); +lpf_funcs(44, 16, sse2); +lpf_funcs(44, 16, ssse3); +lpf_funcs(44, 16, avx); lpf_funcs(84, 16, sse2); lpf_funcs(84, 16, ssse3); lpf_funcs(84, 16, avx); @@ -279,6 +282,8 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) if (ARCH_X86_64) { \ dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_##opt; \ dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_##opt; \ + dsp->loop_filter_mix2[0][0][0] = ff_vp9_loop_filter_h_44_16_##opt; \ + dsp->loop_filter_mix2[0][0][1] = ff_vp9_loop_filter_v_44_16_##opt; \ dsp->loop_filter_mix2[0][1][0] = ff_vp9_loop_filter_h_48_16_##opt; \ dsp->loop_filter_mix2[0][1][1] = ff_vp9_loop_filter_v_48_16_##opt; \ dsp->loop_filter_mix2[1][0][0] = ff_vp9_loop_filter_h_84_16_##opt; \ diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index 5377d96e7eb65..6138da101a181 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -278,23 +278,23 @@ SECTION .text SWAP %12, %15 %endmacro -%macro DEFINE_REAL_P7_TO_Q7 0 -%define P7 dst1q + 2*mstrideq -%define P6 dst1q + mstrideq -%define P5 dst1q -%define P4 dst1q + strideq -%define P3 dstq + 4*mstrideq -%define P2 dstq + mstride3q -%define P1 dstq + 2*mstrideq -%define P0 dstq + mstrideq -%define Q0 dstq -%define Q1 dstq + strideq -%define Q2 dstq + 2*strideq -%define Q3 dstq + stride3q -%define Q4 dstq + 4*strideq -%define Q5 dst2q + mstrideq -%define Q6 dst2q -%define Q7 dst2q + strideq +%macro DEFINE_REAL_P7_TO_Q7 0-1 0 +%define P7 dst1q + 2*mstrideq + %1 +%define P6 dst1q + mstrideq + %1 +%define P5 dst1q + %1 +%define P4 dst1q + strideq + %1 +%define P3 dstq + 4*mstrideq + %1 +%define P2 dstq + mstride3q + %1 +%define P1 dstq + 2*mstrideq + %1 +%define P0 dstq + mstrideq + %1 +%define Q0 dstq + %1 +%define Q1 dstq + strideq + %1 +%define Q2 dstq + 2*strideq + %1 +%define Q3 dstq + stride3q + %1 +%define Q4 dstq + 4*strideq + %1 +%define Q5 dst2q + mstrideq + %1 +%define Q6 dst2q + %1 +%define Q7 dst2q + strideq + %1 %endmacro ; ..............AB -> AAAAAAAABBBBBBBB @@ -450,8 +450,9 @@ SECTION .text pand m3, m5 ; fm final value ; (m3: fm, m8..15: p3 p2 p1 p0 q0 q1 q2 q3) - ; calc flat8in and hev masks + ; calc flat8in (if not 44_16) and hev masks mova m6, [pb_81] ; [1 1 1 1 ...] ^ 0x80 +%if %2 != 44 ABSSUB_CMP m2, m8, m11, m6, m4, m5 ; abs(p3 - p0) <= 1 mova m8, [pb_80] ABSSUB_CMP m1, m9, m11, m6, m4, m5, m8 ; abs(p2 - p0) <= 1 @@ -484,6 +485,19 @@ SECTION .text %if %2 == 84 || %2 == 48 pand m2, [mask_mix%2] %endif +%else + mova m6, [pb_80] + movd m7, Hd + SPLATB_MIX m7 + pxor m7, m6 + ABSSUB m4, m10, m11, m1 ; abs(p1 - p0) + pxor m4, m6 + pcmpgtb m0, m4, m7 ; abs(p1 - p0) > H (1/2 hev condition) + ABSSUB m4, m13, m12, m1 ; abs(q1 - q0) + pxor m4, m6 + pcmpgtb m5, m4, m7 ; abs(q1 - q0) > H (2/2 hev condition) + por m0, m5 ; hev final value +%endif %if %2 == 16 ; (m0: hev, m2: flat8in, m3: fm, m6: pb_81, m9..15: p2 p1 p0 q0 q1 q2 q3) @@ -525,9 +539,11 @@ SECTION .text ; f2: fm & ~f14 & ~f6 & hev => fm & ~(out & in) & ~(~out & in) & hev => fm & ~in & hev ; f4: fm & ~f14 & ~f6 & ~f2 => fm & ~(out & in) & ~(~out & in) & ~(~in & hev) => fm & ~in & ~hev - ; (m0: hev, [m1: flat8out], m2: flat8in, m3: fm, m8..15: p5 p4 p1 p0 q0 q1 q6 q7) + ; (m0: hev, [m1: flat8out], [m2: flat8in], m3: fm, m8..15: p5 p4 p1 p0 q0 q1 q6 q7) ; filter2() - mova m6, [pb_80] +%if %2 != 44 + mova m6, [pb_80] ; already in m6 if 44_16 +%endif pxor m15, m12, m6 ; q0 ^ 0x80 pxor m14, m11, m6 ; p0 ^ 0x80 psubsb m15, m14 ; (signed) q0 - p0 @@ -543,12 +559,16 @@ SECTION .text SRSHIFT3B_2X m6, m4, m14, m7 ; f1 and f2 sign byte shift by 3 SIGN_SUB m7, m12, m6, m5, m9 ; m7 = q0 - f1 SIGN_ADD m8, m11, m4, m5, m9 ; m8 = p0 + f2 +%if %2 != 44 pandn m6, m2, m3 ; ~mask(in) & mask(fm) pand m6, m0 ; (~mask(in) & mask(fm)) & mask(hev) +%else + pand m6, m3, m0 +%endif MASK_APPLY m7, m12, m6, m5 ; m7 = filter2(q0) & mask / we write it in filter4() MASK_APPLY m8, m11, m6, m5 ; m8 = filter2(p0) & mask / we write it in filter4() - ; (m0: hev, [m1: flat8out], m2: flat8in, m3: fm, m7..m8: q0' p0', m10..13: p1 p0 q0 q1, m14: pb_10, m15: q0-p0) + ; (m0: hev, [m1: flat8out], [m2: flat8in], m3: fm, m7..m8: q0' p0', m10..13: p1 p0 q0 q1, m14: pb_10, m15: q0-p0) ; filter4() mova m4, m15 paddsb m15, m4 ; 2 * (q0 - p0) @@ -556,14 +576,22 @@ SECTION .text paddsb m6, m15, [pb_4] ; m6: f1 = clip(f + 4, 127) paddsb m15, [pb_3] ; m15: f2 = clip(f + 3, 127) SRSHIFT3B_2X m6, m15, m14, m9 ; f1 and f2 sign byte shift by 3 +%if %2 != 44 +%define p0tmp m7 +%define q0tmp m9 pandn m5, m2, m3 ; ~mask(in) & mask(fm) pandn m0, m5 ; ~mask(hev) & (~mask(in) & mask(fm)) - SIGN_SUB m9, m12, m6, m4, m14 ; q0 - f1 - MASK_APPLY m9, m7, m0, m5 ; m9 = filter4(q0) & mask - mova [Q0], m9 - SIGN_ADD m7, m11, m15, m4, m14 ; p0 + f2 - MASK_APPLY m7, m8, m0, m5 ; m7 = filter4(p0) & mask - mova [P0], m7 +%else +%define p0tmp m1 +%define q0tmp m2 + pandn m0, m3 +%endif + SIGN_SUB q0tmp, m12, m6, m4, m14 ; q0 - f1 + MASK_APPLY q0tmp, m7, m0, m5 ; filter4(q0) & mask + mova [Q0], q0tmp + SIGN_ADD p0tmp, m11, m15, m4, m14 ; p0 + f2 + MASK_APPLY p0tmp, m8, m0, m5 ; filter4(p0) & mask + mova [P0], p0tmp paddb m6, [pb_80] ; pxor m8, m8 ; f=(f1+1)>>1 pavgb m6, m8 ; @@ -577,6 +605,7 @@ SECTION .text ; ([m1: flat8out], m2: flat8in, m3: fm, m10..13: p1 p0 q0 q1) ; filter6() +%if %2 != 44 pxor m0, m0 %if %2 > 16 pand m3, m2 @@ -594,6 +623,7 @@ SECTION .text FILTER_UPDATE m6, m7, m4, m5, [Q0], m14, m11, m12, m9, 3, m3 ; [q0] -p3 -p0 +q0 +q3 FILTER_UPDATE m4, m5, m6, m7, [Q1], m15, m12, m13, m9, 3, m3 ; [q1] -p2 -q0 +q1 +q3 FILTER_UPDATE m6, m7, m4, m5, [Q2], m10, m13, m8, m9, 3, m3, m8 ; [q2] -p1 -q1 +q2 +q3 +%endif ; (m0: 0, [m1: flat8out], m2: fm & flat8in, m8..15: q2 q3 p1 p0 q0 q1 p3 p2) ; filter14() @@ -674,6 +704,42 @@ SECTION .text movu [Q5], m13 movu [Q6], m14 movu [Q7], m15 +%elif %2 == 44 + SWAP 0, 7 ; m0 = p1 + SWAP 3, 4 ; m3 = q1 + DEFINE_REAL_P7_TO_Q7 2 + SBUTTERFLY bw, 0, 1, 8 + SBUTTERFLY bw, 2, 3, 8 + SBUTTERFLY wd, 0, 2, 8 + SBUTTERFLY wd, 1, 3, 8 + SBUTTERFLY dq, 0, 4, 8 + SBUTTERFLY dq, 1, 5, 8 + SBUTTERFLY dq, 2, 6, 8 + SBUTTERFLY dq, 3, 7, 8 + movd [P7], m0 + punpckhqdq m0, m8 + movd [P6], m0 + movd [Q0], m1 + punpckhqdq m1, m9 + movd [Q1], m1 + movd [P3], m2 + punpckhqdq m2, m10 + movd [P2], m2 + movd [Q4], m3 + punpckhqdq m3, m11 + movd [Q5], m3 + movd [P5], m4 + punpckhqdq m4, m12 + movd [P4], m4 + movd [Q2], m5 + punpckhqdq m5, m13 + movd [Q3], m5 + movd [P1], m6 + punpckhqdq m6, m14 + movd [P0], m6 + movd [Q6], m7 + punpckhqdq m7, m8 + movd [Q7], m7 %else ; the following code do a transpose of 8 full lines to 16 half ; lines (high part). It is inlined to avoid the need of a staging area @@ -743,6 +809,7 @@ LPF_16_VH %1, avx %endmacro LPF_16_VH_ALL_OPTS 16 +LPF_16_VH_ALL_OPTS 44 LPF_16_VH_ALL_OPTS 48 LPF_16_VH_ALL_OPTS 84 LPF_16_VH_ALL_OPTS 88 From a6e288d62414c25ed173b17b48ddea947bede73e Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 19 Dec 2014 21:44:57 -0500 Subject: [PATCH 0257/3374] vp9lpf/x86: save one register in loopfilter surface coverage. Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9lpf.asm | 56 +++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index 6138da101a181..dc227056963c7 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -279,22 +279,22 @@ SECTION .text %endmacro %macro DEFINE_REAL_P7_TO_Q7 0-1 0 -%define P7 dst1q + 2*mstrideq + %1 -%define P6 dst1q + mstrideq + %1 -%define P5 dst1q + %1 -%define P4 dst1q + strideq + %1 -%define P3 dstq + 4*mstrideq + %1 -%define P2 dstq + mstride3q + %1 -%define P1 dstq + 2*mstrideq + %1 -%define P0 dstq + mstrideq + %1 -%define Q0 dstq + %1 -%define Q1 dstq + strideq + %1 -%define Q2 dstq + 2*strideq + %1 -%define Q3 dstq + stride3q + %1 -%define Q4 dstq + 4*strideq + %1 -%define Q5 dst2q + mstrideq + %1 -%define Q6 dst2q + %1 -%define Q7 dst2q + strideq + %1 +%define P7 dstq + 4*mstrideq + %1 +%define P6 dstq + mstride3q + %1 +%define P5 dstq + 2*mstrideq + %1 +%define P4 dstq + mstrideq + %1 +%define P3 dstq + %1 +%define P2 dstq + strideq + %1 +%define P1 dstq + 2* strideq + %1 +%define P0 dstq + stride3q + %1 +%define Q0 dstq + 4* strideq + %1 +%define Q1 dst2q + mstride3q + %1 +%define Q2 dst2q + 2*mstrideq + %1 +%define Q3 dst2q + mstrideq + %1 +%define Q4 dst2q + %1 +%define Q5 dst2q + strideq + %1 +%define Q6 dst2q + 2* strideq + %1 +%define Q7 dst2q + stride3q + %1 %endmacro ; ..............AB -> AAAAAAAABBBBBBBB @@ -309,26 +309,26 @@ SECTION .text %endmacro %macro LOOPFILTER 2 ; %1=v/h %2=size1 - lea mstrideq, [strideq] - neg mstrideq + mov mstrideq, strideq + neg mstrideq - lea stride3q, [strideq+2*strideq] - mov mstride3q, stride3q - neg mstride3q + lea stride3q, [strideq*3] + lea mstride3q, [mstrideq*3] %ifidn %1, h %if %2 > 16 %define movx movh - lea dstq, [dstq + 8*strideq - 4] + lea dstq, [dstq + 4*strideq - 4] %else %define movx movu - lea dstq, [dstq + 8*strideq - 8] ; go from top center (h pos) to center left (v pos) + lea dstq, [dstq + 4*strideq - 8] ; go from top center (h pos) to center left (v pos) %endif + lea dst2q, [dstq + 8*strideq] +%else + lea dstq, [dstq + 4*mstrideq] + lea dst2q, [dstq + 8*strideq] %endif - lea dst1q, [dstq + 2*mstride3q] ; dst1q = &dst[stride * -6] - lea dst2q, [dstq + 2* stride3q] ; dst2q = &dst[stride * +6] - DEFINE_REAL_P7_TO_Q7 %ifidn %1, h @@ -796,9 +796,9 @@ SECTION .text %macro LPF_16_VH 2 INIT_XMM %2 -cglobal vp9_loop_filter_v_%1_16, 5,10,16, dst, stride, E, I, H, mstride, dst1, dst2, stride3, mstride3 +cglobal vp9_loop_filter_v_%1_16, 5,10,16, dst, stride, E, I, H, mstride, dst2, stride3, mstride3 LOOPFILTER v, %1 -cglobal vp9_loop_filter_h_%1_16, 5,10,16, 256, dst, stride, E, I, H, mstride, dst1, dst2, stride3, mstride3 +cglobal vp9_loop_filter_h_%1_16, 5,10,16, 256, dst, stride, E, I, H, mstride, dst2, stride3, mstride3 LOOPFILTER h, %1 %endmacro From 6411c328a233b80faa5aa3ef4266f9a16e499699 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 19 Dec 2014 22:09:30 -0500 Subject: [PATCH 0258/3374] vp9lpf/x86: make cglobal statement more conservative in register allocation. Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9lpf.asm | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index dc227056963c7..878bc54a285a7 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -308,7 +308,20 @@ SECTION .text %endif %endmacro -%macro LOOPFILTER 2 ; %1=v/h %2=size1 +%macro LOOPFILTER 3 ; %1=v/h %2=size1 %3=stack +%if UNIX64 +cglobal vp9_loop_filter_%1_%2_16, 5, 9, 16, %3, dst, stride, E, I, H, mstride, dst2, stride3, mstride3 +%else +%if WIN64 +cglobal vp9_loop_filter_%1_%2_16, 4, 8, 16, %3, dst, stride, E, I, mstride, dst2, stride3, mstride3 +%else +cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3, dst, stride, mstride, dst2, stride3, mstride3 +%define Ed dword r2m +%define Id dword r3m +%endif +%define Hd dword r4m +%endif + mov mstrideq, strideq neg mstrideq @@ -796,10 +809,8 @@ SECTION .text %macro LPF_16_VH 2 INIT_XMM %2 -cglobal vp9_loop_filter_v_%1_16, 5,10,16, dst, stride, E, I, H, mstride, dst2, stride3, mstride3 - LOOPFILTER v, %1 -cglobal vp9_loop_filter_h_%1_16, 5,10,16, 256, dst, stride, E, I, H, mstride, dst2, stride3, mstride3 - LOOPFILTER h, %1 +LOOPFILTER v, %1, 0 +LOOPFILTER h, %1, 256 %endmacro %macro LPF_16_VH_ALL_OPTS 1 From 6e74e9636b1752e777146421ffa2b2498071e28d Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 19 Dec 2014 22:18:42 -0500 Subject: [PATCH 0259/3374] vp9lpf/x86: slightly simplify 44/48/84/88 h stores. Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9lpf.asm | 88 ++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 48 deletions(-) diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index 878bc54a285a7..d5b3fca9905eb 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -725,34 +725,34 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3, dst, stride, mstride, dst2, stri SBUTTERFLY bw, 2, 3, 8 SBUTTERFLY wd, 0, 2, 8 SBUTTERFLY wd, 1, 3, 8 - SBUTTERFLY dq, 0, 4, 8 - SBUTTERFLY dq, 1, 5, 8 - SBUTTERFLY dq, 2, 6, 8 - SBUTTERFLY dq, 3, 7, 8 movd [P7], m0 - punpckhqdq m0, m8 - movd [P6], m0 - movd [Q0], m1 - punpckhqdq m1, m9 - movd [Q1], m1 movd [P3], m2 - punpckhqdq m2, m10 - movd [P2], m2 + movd [Q0], m1 movd [Q4], m3 - punpckhqdq m3, m11 + psrldq m0, 4 + psrldq m1, 4 + psrldq m2, 4 + psrldq m3, 4 + movd [P6], m0 + movd [P2], m2 + movd [Q1], m1 movd [Q5], m3 - movd [P5], m4 - punpckhqdq m4, m12 - movd [P4], m4 - movd [Q2], m5 - punpckhqdq m5, m13 - movd [Q3], m5 - movd [P1], m6 - punpckhqdq m6, m14 - movd [P0], m6 - movd [Q6], m7 - punpckhqdq m7, m8 - movd [Q7], m7 + psrldq m0, 4 + psrldq m1, 4 + psrldq m2, 4 + psrldq m3, 4 + movd [P5], m0 + movd [P1], m2 + movd [Q2], m1 + movd [Q6], m3 + psrldq m0, 4 + psrldq m1, 4 + psrldq m2, 4 + psrldq m3, 4 + movd [P4], m0 + movd [P0], m2 + movd [Q3], m1 + movd [Q7], m3 %else ; the following code do a transpose of 8 full lines to 16 half ; lines (high part). It is inlined to avoid the need of a staging area @@ -777,30 +777,22 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3, dst, stride, mstride, dst2, stri SBUTTERFLY dq, 1, 5, 8 SBUTTERFLY dq, 2, 6, 8 SBUTTERFLY dq, 3, 7, 8 - movh [P7], m0 - punpckhqdq m0, m8 - movh [P6], m0 - movh [Q0], m1 - punpckhqdq m1, m9 - movh [Q1], m1 - movh [P3], m2 - punpckhqdq m2, m10 - movh [P2], m2 - movh [Q4], m3 - punpckhqdq m3, m11 - movh [Q5], m3 - movh [P5], m4 - punpckhqdq m4, m12 - movh [P4], m4 - movh [Q2], m5 - punpckhqdq m5, m13 - movh [Q3], m5 - movh [P1], m6 - punpckhqdq m6, m14 - movh [P0], m6 - movh [Q6], m7 - punpckhqdq m7, m8 - movh [Q7], m7 + movh [P7], m0 + movhps [P6], m0 + movh [Q0], m1 + movhps [Q1], m1 + movh [P3], m2 + movhps [P2], m2 + movh [Q4], m3 + movhps [Q5], m3 + movh [P5], m4 + movhps [P4], m4 + movh [Q2], m5 + movhps [Q3], m5 + movh [P1], m6 + movhps [P0], m6 + movh [Q6], m7 + movhps [Q7], m7 %endif %endif From 683da2788e418877808f1407d68140cafaae8b4f Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sat, 20 Dec 2014 11:13:06 -0500 Subject: [PATCH 0260/3374] vp9lpf/x86: remove unused register from ABSSUB_CMP macro. Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9lpf.asm | 42 +++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index d5b3fca9905eb..7dc40a393ca5a 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -70,9 +70,9 @@ SECTION .text %endmacro ; %1 = abs(%2-%3) <= %4 -%macro ABSSUB_CMP 6-7 [pb_80]; dst, src1, src2, cmp, tmp1, tmp2, [pb_80] - ABSSUB %1, %2, %3, %6 ; dst = abs(src1-src2) - CMP_LTE %1, %4, %6, %7 ; dst <= cmp +%macro ABSSUB_CMP 5-6 [pb_80]; dst, src1, src2, cmp, tmp, [pb_80] + ABSSUB %1, %2, %3, %5 ; dst = abs(src1-src2) + CMP_LTE %1, %4, %5, %6 ; dst <= cmp %endmacro %macro MASK_APPLY 4 ; %1=new_data/dst %2=old_data %3=mask %4=tmp @@ -439,16 +439,16 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3, dst, stride, mstride, dst2, stri SWAP 10, 6, 14 SWAP 11, 7, 15 %endif - ABSSUB_CMP m5, m8, m9, m2, m6, m7, m0 ; m5 = abs(p3-p2) <= I - ABSSUB_CMP m1, m9, m10, m2, m6, m7, m0 ; m1 = abs(p2-p1) <= I + ABSSUB_CMP m5, m8, m9, m2, m7, m0 ; m5 = abs(p3-p2) <= I + ABSSUB_CMP m1, m9, m10, m2, m7, m0 ; m1 = abs(p2-p1) <= I pand m5, m1 - ABSSUB_CMP m1, m10, m11, m2, m6, m7, m0 ; m1 = abs(p1-p0) <= I + ABSSUB_CMP m1, m10, m11, m2, m7, m0 ; m1 = abs(p1-p0) <= I pand m5, m1 - ABSSUB_CMP m1, m12, m13, m2, m6, m7, m0 ; m1 = abs(q1-q0) <= I + ABSSUB_CMP m1, m12, m13, m2, m7, m0 ; m1 = abs(q1-q0) <= I pand m5, m1 - ABSSUB_CMP m1, m13, m14, m2, m6, m7, m0 ; m1 = abs(q2-q1) <= I + ABSSUB_CMP m1, m13, m14, m2, m7, m0 ; m1 = abs(q2-q1) <= I pand m5, m1 - ABSSUB_CMP m1, m14, m15, m2, m6, m7, m0 ; m1 = abs(q3-q2) <= I + ABSSUB_CMP m1, m14, m15, m2, m7, m0 ; m1 = abs(q3-q2) <= I pand m5, m1 ABSSUB m1, m11, m12, m7 ; abs(p0-q0) paddusb m1, m1 ; abs(p0-q0) * 2 @@ -466,9 +466,9 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3, dst, stride, mstride, dst2, stri ; calc flat8in (if not 44_16) and hev masks mova m6, [pb_81] ; [1 1 1 1 ...] ^ 0x80 %if %2 != 44 - ABSSUB_CMP m2, m8, m11, m6, m4, m5 ; abs(p3 - p0) <= 1 + ABSSUB_CMP m2, m8, m11, m6, m5 ; abs(p3 - p0) <= 1 mova m8, [pb_80] - ABSSUB_CMP m1, m9, m11, m6, m4, m5, m8 ; abs(p2 - p0) <= 1 + ABSSUB_CMP m1, m9, m11, m6, m5, m8 ; abs(p2 - p0) <= 1 pand m2, m1 ABSSUB m4, m10, m11, m5 ; abs(p1 - p0) %if %2 == 16 @@ -491,9 +491,9 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3, dst, stride, mstride, dst2, stri por m0, m5 ; hev final value CMP_LTE m4, m6, m5 ; abs(q1 - q0) <= 1 pand m2, m4 ; (flat8in) - ABSSUB_CMP m1, m14, m12, m6, m4, m5, m8 ; abs(q2 - q0) <= 1 + ABSSUB_CMP m1, m14, m12, m6, m5, m8 ; abs(q2 - q0) <= 1 pand m2, m1 - ABSSUB_CMP m1, m15, m12, m6, m4, m5, m8 ; abs(q3 - q0) <= 1 + ABSSUB_CMP m1, m15, m12, m6, m5, m8 ; abs(q3 - q0) <= 1 pand m2, m1 ; flat8in final value %if %2 == 84 || %2 == 48 pand m2, [mask_mix%2] @@ -517,26 +517,26 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3, dst, stride, mstride, dst2, stri ; calc flat8out mask mova m8, [P7] mova m9, [P6] - ABSSUB_CMP m1, m8, m11, m6, m4, m5 ; abs(p7 - p0) <= 1 - ABSSUB_CMP m7, m9, m11, m6, m4, m5 ; abs(p6 - p0) <= 1 + ABSSUB_CMP m1, m8, m11, m6, m5 ; abs(p7 - p0) <= 1 + ABSSUB_CMP m7, m9, m11, m6, m5 ; abs(p6 - p0) <= 1 pand m1, m7 mova m8, [P5] mova m9, [P4] - ABSSUB_CMP m7, m8, m11, m6, m4, m5 ; abs(p5 - p0) <= 1 + ABSSUB_CMP m7, m8, m11, m6, m5 ; abs(p5 - p0) <= 1 pand m1, m7 - ABSSUB_CMP m7, m9, m11, m6, m4, m5 ; abs(p4 - p0) <= 1 + ABSSUB_CMP m7, m9, m11, m6, m5 ; abs(p4 - p0) <= 1 pand m1, m7 mova m14, [Q4] mova m15, [Q5] - ABSSUB_CMP m7, m14, m12, m6, m4, m5 ; abs(q4 - q0) <= 1 + ABSSUB_CMP m7, m14, m12, m6, m5 ; abs(q4 - q0) <= 1 pand m1, m7 - ABSSUB_CMP m7, m15, m12, m6, m4, m5 ; abs(q5 - q0) <= 1 + ABSSUB_CMP m7, m15, m12, m6, m5 ; abs(q5 - q0) <= 1 pand m1, m7 mova m14, [Q6] mova m15, [Q7] - ABSSUB_CMP m7, m14, m12, m6, m4, m5 ; abs(q4 - q0) <= 1 + ABSSUB_CMP m7, m14, m12, m6, m5 ; abs(q4 - q0) <= 1 pand m1, m7 - ABSSUB_CMP m7, m15, m12, m6, m4, m5 ; abs(q5 - q0) <= 1 + ABSSUB_CMP m7, m15, m12, m6, m5 ; abs(q5 - q0) <= 1 pand m1, m7 ; flat8out final value %endif From e4961035b288043b2b00bdc2ccbe3c31393e12d5 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sun, 21 Dec 2014 19:34:03 -0500 Subject: [PATCH 0261/3374] vp9lpf/x86: simplify ABSSUM_CMP by inverting the comparison meaning. Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9lpf.asm | 103 +++++++++++++++++++------------------- 1 file changed, 52 insertions(+), 51 deletions(-) diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index 7dc40a393ca5a..5d829959fd180 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -36,6 +36,7 @@ pb_40: times 16 db 0x40 pb_81: times 16 db 0x81 pb_f8: times 16 db 0xf8 pb_fe: times 16 db 0xfe +pb_ff: times 16 db 0xff pw_4: times 8 dw 4 pw_8: times 8 dw 8 @@ -59,20 +60,18 @@ SECTION .text por %1, %4 %endmacro -; %1 = %1<=%2 -%macro CMP_LTE 3-4 ; src/dst, cmp, tmp, pb_80 -%if %0 == 4 - pxor %1, %4 +; %1 = %1>%2 +%macro CMP_GT 2-3 ; src/dst, cmp, pb_80 +%if %0 == 3 + pxor %1, %3 %endif - pcmpgtb %3, %2, %1 ; cmp > src? - pcmpeqb %1, %2 ; cmp == src? XXX: avoid this with a -1/+1 well placed? - por %1, %3 ; cmp >= src? + pcmpgtb %1, %2 %endmacro -; %1 = abs(%2-%3) <= %4 -%macro ABSSUB_CMP 5-6 [pb_80]; dst, src1, src2, cmp, tmp, [pb_80] +; %1 = abs(%2-%3) > %4 +%macro ABSSUB_GT 5-6 [pb_80]; dst, src1, src2, cmp, tmp, [pb_80] ABSSUB %1, %2, %3, %5 ; dst = abs(src1-src2) - CMP_LTE %1, %4, %5, %6 ; dst <= cmp + CMP_GT %1, %4, %6 ; dst > cmp %endmacro %macro MASK_APPLY 4 ; %1=new_data/dst %2=old_data %3=mask %4=tmp @@ -439,17 +438,17 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3, dst, stride, mstride, dst2, stri SWAP 10, 6, 14 SWAP 11, 7, 15 %endif - ABSSUB_CMP m5, m8, m9, m2, m7, m0 ; m5 = abs(p3-p2) <= I - ABSSUB_CMP m1, m9, m10, m2, m7, m0 ; m1 = abs(p2-p1) <= I - pand m5, m1 - ABSSUB_CMP m1, m10, m11, m2, m7, m0 ; m1 = abs(p1-p0) <= I - pand m5, m1 - ABSSUB_CMP m1, m12, m13, m2, m7, m0 ; m1 = abs(q1-q0) <= I - pand m5, m1 - ABSSUB_CMP m1, m13, m14, m2, m7, m0 ; m1 = abs(q2-q1) <= I - pand m5, m1 - ABSSUB_CMP m1, m14, m15, m2, m7, m0 ; m1 = abs(q3-q2) <= I - pand m5, m1 + ABSSUB_GT m5, m8, m9, m2, m7, m0 ; m5 = abs(p3-p2) <= I + ABSSUB_GT m1, m9, m10, m2, m7, m0 ; m1 = abs(p2-p1) <= I + por m5, m1 + ABSSUB_GT m1, m10, m11, m2, m7, m0 ; m1 = abs(p1-p0) <= I + por m5, m1 + ABSSUB_GT m1, m12, m13, m2, m7, m0 ; m1 = abs(q1-q0) <= I + por m5, m1 + ABSSUB_GT m1, m13, m14, m2, m7, m0 ; m1 = abs(q2-q1) <= I + por m5, m1 + ABSSUB_GT m1, m14, m15, m2, m7, m0 ; m1 = abs(q3-q2) <= I + por m5, m1 ABSSUB m1, m11, m12, m7 ; abs(p0-q0) paddusb m1, m1 ; abs(p0-q0) * 2 ABSSUB m2, m10, m13, m7 ; abs(p1-q1) @@ -457,19 +456,19 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3, dst, stride, mstride, dst2, stri psrlq m2, 1 ; abs(p1-q1)/2 paddusb m1, m2 ; abs(p0-q0)*2 + abs(p1-q1)/2 pxor m1, m0 - pcmpgtb m4, m3, m1 ; E > X? - pcmpeqb m3, m1 ; E == X? - por m3, m4 ; E >= X? - pand m3, m5 ; fm final value + pcmpgtb m1, m3 + por m1, m5 ; fm final value + SWAP 1, 3 + pxor m3, [pb_ff] ; (m3: fm, m8..15: p3 p2 p1 p0 q0 q1 q2 q3) ; calc flat8in (if not 44_16) and hev masks mova m6, [pb_81] ; [1 1 1 1 ...] ^ 0x80 %if %2 != 44 - ABSSUB_CMP m2, m8, m11, m6, m5 ; abs(p3 - p0) <= 1 + ABSSUB_GT m2, m8, m11, m6, m5 ; abs(p3 - p0) <= 1 mova m8, [pb_80] - ABSSUB_CMP m1, m9, m11, m6, m5, m8 ; abs(p2 - p0) <= 1 - pand m2, m1 + ABSSUB_GT m1, m9, m11, m6, m5, m8 ; abs(p2 - p0) <= 1 + por m2, m1 ABSSUB m4, m10, m11, m5 ; abs(p1 - p0) %if %2 == 16 %if cpuflag(ssse3) @@ -483,18 +482,19 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3, dst, stride, mstride, dst2, stri pxor m7, m8 pxor m4, m8 pcmpgtb m0, m4, m7 ; abs(p1 - p0) > H (1/2 hev condition) - CMP_LTE m4, m6, m5 ; abs(p1 - p0) <= 1 - pand m2, m4 ; (flat8in) + CMP_GT m4, m6 ; abs(p1 - p0) <= 1 + por m2, m4 ; (flat8in) ABSSUB m4, m13, m12, m1 ; abs(q1 - q0) pxor m4, m8 pcmpgtb m5, m4, m7 ; abs(q1 - q0) > H (2/2 hev condition) por m0, m5 ; hev final value - CMP_LTE m4, m6, m5 ; abs(q1 - q0) <= 1 - pand m2, m4 ; (flat8in) - ABSSUB_CMP m1, m14, m12, m6, m5, m8 ; abs(q2 - q0) <= 1 - pand m2, m1 - ABSSUB_CMP m1, m15, m12, m6, m5, m8 ; abs(q3 - q0) <= 1 - pand m2, m1 ; flat8in final value + CMP_GT m4, m6 ; abs(q1 - q0) <= 1 + por m2, m4 ; (flat8in) + ABSSUB_GT m1, m14, m12, m6, m5, m8 ; abs(q2 - q0) <= 1 + por m2, m1 + ABSSUB_GT m1, m15, m12, m6, m5, m8 ; abs(q3 - q0) <= 1 + por m2, m1 ; flat8in final value + pxor m2, [pb_ff] %if %2 == 84 || %2 == 48 pand m2, [mask_mix%2] %endif @@ -517,27 +517,28 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3, dst, stride, mstride, dst2, stri ; calc flat8out mask mova m8, [P7] mova m9, [P6] - ABSSUB_CMP m1, m8, m11, m6, m5 ; abs(p7 - p0) <= 1 - ABSSUB_CMP m7, m9, m11, m6, m5 ; abs(p6 - p0) <= 1 - pand m1, m7 + ABSSUB_GT m1, m8, m11, m6, m5 ; abs(p7 - p0) <= 1 + ABSSUB_GT m7, m9, m11, m6, m5 ; abs(p6 - p0) <= 1 + por m1, m7 mova m8, [P5] mova m9, [P4] - ABSSUB_CMP m7, m8, m11, m6, m5 ; abs(p5 - p0) <= 1 - pand m1, m7 - ABSSUB_CMP m7, m9, m11, m6, m5 ; abs(p4 - p0) <= 1 - pand m1, m7 + ABSSUB_GT m7, m8, m11, m6, m5 ; abs(p5 - p0) <= 1 + por m1, m7 + ABSSUB_GT m7, m9, m11, m6, m5 ; abs(p4 - p0) <= 1 + por m1, m7 mova m14, [Q4] mova m15, [Q5] - ABSSUB_CMP m7, m14, m12, m6, m5 ; abs(q4 - q0) <= 1 - pand m1, m7 - ABSSUB_CMP m7, m15, m12, m6, m5 ; abs(q5 - q0) <= 1 - pand m1, m7 + ABSSUB_GT m7, m14, m12, m6, m5 ; abs(q4 - q0) <= 1 + por m1, m7 + ABSSUB_GT m7, m15, m12, m6, m5 ; abs(q5 - q0) <= 1 + por m1, m7 mova m14, [Q6] mova m15, [Q7] - ABSSUB_CMP m7, m14, m12, m6, m5 ; abs(q4 - q0) <= 1 - pand m1, m7 - ABSSUB_CMP m7, m15, m12, m6, m5 ; abs(q5 - q0) <= 1 - pand m1, m7 ; flat8out final value + ABSSUB_GT m7, m14, m12, m6, m5 ; abs(q4 - q0) <= 1 + por m1, m7 + ABSSUB_GT m7, m15, m12, m6, m5 ; abs(q5 - q0) <= 1 + por m1, m7 ; flat8out final value + pxor m1, [pb_ff] %endif ; if (fm) { From 4ce8ba72f9cbdecf3a2ee3533959e097a2095595 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Wed, 24 Dec 2014 14:22:19 -0500 Subject: [PATCH 0262/3374] vp9lpf/x86: move variable assigned inside macro branch. The value is not used outside the branch. Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9lpf.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index 5d829959fd180..0b72facc8dfb8 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -463,8 +463,8 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3, dst, stride, mstride, dst2, stri ; (m3: fm, m8..15: p3 p2 p1 p0 q0 q1 q2 q3) ; calc flat8in (if not 44_16) and hev masks - mova m6, [pb_81] ; [1 1 1 1 ...] ^ 0x80 %if %2 != 44 + mova m6, [pb_81] ; [1 1 1 1 ...] ^ 0x80 ABSSUB_GT m2, m8, m11, m6, m5 ; abs(p3 - p0) <= 1 mova m8, [pb_80] ABSSUB_GT m1, m9, m11, m6, m5, m8 ; abs(p2 - p0) <= 1 From c6375a83d1ad512ed24e8fef044f3ba17237e03e Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Wed, 24 Dec 2014 14:17:28 -0500 Subject: [PATCH 0263/3374] vp9lpf/x86: store unpacked intermediates for filter6/14 on stack. filter16 goes from 508 to 482 (h) or 346 to 314 (v) cycles; filter88 goes from 240 to 238 (h) or 174 to 165 (v) cycles, measured on TOS. Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9lpf.asm | 151 ++++++++++++++++++++------------------ 1 file changed, 79 insertions(+), 72 deletions(-) diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index 0b72facc8dfb8..e3371329a81a0 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -80,39 +80,42 @@ SECTION .text por %1, %4 ; new&mask | old&~mask %endmacro -%macro FILTER_SUBx2_ADDx2 8 ; %1=dst %2=h/l %3=cache %4=sub1 %5=sub2 %6=add1 %7=add2 %8=rshift - punpck%2bw %3, %4, m0 - psubw %1, %3 - punpck%2bw %3, %5, m0 - psubw %1, %3 - punpck%2bw %3, %6, m0 - paddw %1, %3 - punpck%2bw %3, %7, m0 +%macro FILTER_SUBx2_ADDx2 9-10 "" ; %1=dst %2=h/l %3=cache %4=stack_off %5=sub1 %6=sub2 %7=add1 %8=add2 %9=rshift, [unpack] + psubw %3, [rsp+%4+%5*32] + psubw %3, [rsp+%4+%6*32] + paddw %3, [rsp+%4+%7*32] +%ifnidn %10, "" + punpck%2bw %1, %10, m0 + mova [rsp+%4+%8*32], %1 paddw %3, %1 - psraw %1, %3, %8 +%else + paddw %3, [rsp+%4+%8*32] +%endif + psraw %1, %3, %9 %endmacro -%macro FILTER_INIT 8 ; tmp1, tmp2, cacheL, cacheH, dstp, filterid, mask, source - FILTER%6_INIT %1, l, %3 - FILTER%6_INIT %2, h, %4 +; FIXME interleave l/h better (for instruction pairing) +%macro FILTER_INIT 9 ; tmp1, tmp2, cacheL, cacheH, dstp, stack_off, filterid, mask, source + FILTER%7_INIT %1, l, %3, %6 + 0 + FILTER%7_INIT %2, h, %4, %6 + 16 packuswb %1, %2 - MASK_APPLY %1, %8, %7, %2 + MASK_APPLY %1, %9, %8, %2 mova %5, %1 %endmacro -%macro FILTER_UPDATE 11-14 ; tmp1, tmp2, cacheL, cacheH, dstp, -, -, +, +, rshift, mask, [source], [preload reg + value] -%if %0 == 13 ; no source + preload - mova %12, %13 -%elif %0 == 14 ; source + preload - mova %13, %14 + +%macro FILTER_UPDATE 12-15 "", "" ; tmp1, tmp2, cacheL, cacheH, dstp, stack_off, -, -, +, +, rshift, mask, [source], [unpack] +; FIXME interleave this properly with the subx2/addx2 +%if %0 == 15 + mova %14, %15 %endif - FILTER_SUBx2_ADDx2 %1, l, %3, %6, %7, %8, %9, %10 - FILTER_SUBx2_ADDx2 %2, h, %4, %6, %7, %8, %9, %10 + FILTER_SUBx2_ADDx2 %1, l, %3, %6 + 0, %7, %8, %9, %10, %11, %14 + FILTER_SUBx2_ADDx2 %2, h, %4, %6 + 16, %7, %8, %9, %10, %11, %14 packuswb %1, %2 -%if %0 == 12 || %0 == 14 - MASK_APPLY %1, %12, %11, %2 +%ifnidn %13, "" + MASK_APPLY %1, %13, %12, %2 %else - MASK_APPLY %1, %5, %11, %2 + MASK_APPLY %1, %5, %12, %2 %endif mova %5, %1 %endmacro @@ -152,44 +155,48 @@ SECTION .text paddusb %1, %4 ; add the negatives %endmacro -%macro FILTER6_INIT 3 ; %1=dst %2=h/l %3=cache +%macro FILTER6_INIT 4 ; %1=dst %2=h/l %3=cache, %4=stack_off punpck%2bw %1, m14, m0 ; p3: B->W + mova [rsp+%4+0*32], %1 paddw %3, %1, %1 ; p3*2 paddw %3, %1 ; p3*3 punpck%2bw %1, m15, m0 ; p2: B->W + mova [rsp+%4+1*32], %1 paddw %3, %1 ; p3*3 + p2 paddw %3, %1 ; p3*3 + p2*2 punpck%2bw %1, m10, m0 ; p1: B->W + mova [rsp+%4+2*32], %1 paddw %3, %1 ; p3*3 + p2*2 + p1 punpck%2bw %1, m11, m0 ; p0: B->W + mova [rsp+%4+3*32], %1 paddw %3, %1 ; p3*3 + p2*2 + p1 + p0 punpck%2bw %1, m12, m0 ; q0: B->W + mova [rsp+%4+4*32], %1 paddw %3, %1 ; p3*3 + p2*2 + p1 + p0 + q0 paddw %3, [pw_4] ; p3*3 + p2*2 + p1 + p0 + q0 + 4 psraw %1, %3, 3 ; (p3*3 + p2*2 + p1 + p0 + q0 + 4) >> 3 %endmacro -%macro FILTER14_INIT 3 ; %1=dst %2=h/l %3=cache +%macro FILTER14_INIT 4 ; %1=dst %2=h/l %3=cache, %4=stack_off punpck%2bw %1, m2, m0 ; p7: B->W + mova [rsp+%4+ 8*32], %1 psllw %3, %1, 3 ; p7*8 psubw %3, %1 ; p7*7 punpck%2bw %1, m3, m0 ; p6: B->W + mova [rsp+%4+ 9*32], %1 paddw %3, %1 ; p7*7 + p6 paddw %3, %1 ; p7*7 + p6*2 punpck%2bw %1, m8, m0 ; p5: B->W + mova [rsp+%4+10*32], %1 paddw %3, %1 ; p7*7 + p6*2 + p5 punpck%2bw %1, m9, m0 ; p4: B->W + mova [rsp+%4+11*32], %1 paddw %3, %1 ; p7*7 + p6*2 + p5 + p4 - punpck%2bw %1, m14, m0 ; p3: B->W - paddw %3, %1 ; p7*7 + p6*2 + p5 + p4 + p3 - punpck%2bw %1, m15, m0 ; p2: B->W - paddw %3, %1 ; p7*7 + p6*2 + p5 + .. + p2 - punpck%2bw %1, m10, m0 ; p1: B->W - paddw %3, %1 ; p7*7 + p6*2 + p5 + .. + p1 - punpck%2bw %1, m11, m0 ; p0: B->W - paddw %3, %1 ; p7*7 + p6*2 + p5 + .. + p0 - punpck%2bw %1, m12, m0 ; q0: B->W - paddw %3, %1 ; p7*7 + p6*2 + p5 + .. + p0 + q0 + paddw %3, [rsp+%4+ 0*32] ; p7*7 + p6*2 + p5 + p4 + p3 + paddw %3, [rsp+%4+ 1*32] ; p7*7 + p6*2 + p5 + .. + p2 + paddw %3, [rsp+%4+ 2*32] ; p7*7 + p6*2 + p5 + .. + p1 + paddw %3, [rsp+%4+ 3*32] ; p7*7 + p6*2 + p5 + .. + p0 + paddw %3, [rsp+%4+ 4*32] ; p7*7 + p6*2 + p5 + .. + p0 + q0 paddw %3, [pw_8] ; p7*7 + p6*2 + p5 + .. + p0 + q0 + 8 psraw %1, %3, 4 ; (p7*7 + p6*2 + p5 + .. + p0 + q0 + 8) >> 4 %endmacro @@ -307,14 +314,14 @@ SECTION .text %endif %endmacro -%macro LOOPFILTER 3 ; %1=v/h %2=size1 %3=stack +%macro LOOPFILTER 4 ; %1=v/h %2=size1 %3+%4=stack %if UNIX64 -cglobal vp9_loop_filter_%1_%2_16, 5, 9, 16, %3, dst, stride, E, I, H, mstride, dst2, stride3, mstride3 +cglobal vp9_loop_filter_%1_%2_16, 5, 9, 16, %3 + %4, dst, stride, E, I, H, mstride, dst2, stride3, mstride3 %else %if WIN64 -cglobal vp9_loop_filter_%1_%2_16, 4, 8, 16, %3, dst, stride, E, I, mstride, dst2, stride3, mstride3 +cglobal vp9_loop_filter_%1_%2_16, 4, 8, 16, %3 + %4, dst, stride, E, I, mstride, dst2, stride3, mstride3 %else -cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3, dst, stride, mstride, dst2, stride3, mstride3 +cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4, dst, stride, mstride, dst2, stride3, mstride3 %define Ed dword r2m %define Id dword r3m %endif @@ -631,12 +638,12 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3, dst, stride, mstride, dst2, stri mova m15, [P2] mova m8, [Q2] mova m9, [Q3] - FILTER_INIT m4, m5, m6, m7, [P2], 6, m3, m15 ; [p2] - FILTER_UPDATE m6, m7, m4, m5, [P1], m14, m15, m10, m13, 3, m3 ; [p1] -p3 -p2 +p1 +q1 - FILTER_UPDATE m4, m5, m6, m7, [P0], m14, m10, m11, m8, 3, m3 ; [p0] -p3 -p1 +p0 +q2 - FILTER_UPDATE m6, m7, m4, m5, [Q0], m14, m11, m12, m9, 3, m3 ; [q0] -p3 -p0 +q0 +q3 - FILTER_UPDATE m4, m5, m6, m7, [Q1], m15, m12, m13, m9, 3, m3 ; [q1] -p2 -q0 +q1 +q3 - FILTER_UPDATE m6, m7, m4, m5, [Q2], m10, m13, m8, m9, 3, m3, m8 ; [q2] -p1 -q1 +q2 +q3 + FILTER_INIT m4, m5, m6, m7, [P2], %4, 6, m3, m15 ; [p2] + FILTER_UPDATE m4, m5, m6, m7, [P1], %4, 0, 1, 2, 5, 3, m3, "", m13 ; [p1] -p3 -p2 +p1 +q1 + FILTER_UPDATE m4, m5, m6, m7, [P0], %4, 0, 2, 3, 6, 3, m3, "", m8 ; [p0] -p3 -p1 +p0 +q2 + FILTER_UPDATE m4, m5, m6, m7, [Q0], %4, 0, 3, 4, 7, 3, m3, "", m9 ; [q0] -p3 -p0 +q0 +q3 + FILTER_UPDATE m4, m5, m6, m7, [Q1], %4, 1, 4, 5, 7, 3, m3, "" ; [q1] -p2 -q0 +q1 +q3 + FILTER_UPDATE m4, m5, m6, m7, [Q2], %4, 2, 5, 6, 7, 3, m3, m8 ; [q2] -p1 -q1 +q2 +q3 %endif ; (m0: 0, [m1: flat8out], m2: fm & flat8in, m8..15: q2 q3 p1 p0 q0 q1 p3 p2) @@ -666,20 +673,20 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3, dst, stride, mstride, dst2, stri mova m3, [P6] mova m8, [P5] mova m9, [P4] - FILTER_INIT m4, m5, m6, m7, [P6], 14, m1, m3 - FILTER_UPDATE m6, m7, m4, m5, [P5], m2, m3, m8, m13, 4, m1, m8 ; [p5] -p7 -p6 +p5 +q1 - FILTER_UPDATE m4, m5, m6, m7, [P4], m2, m8, m9, m13, 4, m1, m9, m13, [Q2] ; [p4] -p7 -p5 +p4 +q2 - FILTER_UPDATE m6, m7, m4, m5, [P3], m2, m9, m14, m13, 4, m1, m14, m13, [Q3] ; [p3] -p7 -p4 +p3 +q3 - FILTER_UPDATE m4, m5, m6, m7, [P2], m2, m14, m15, m13, 4, m1, m13, [Q4] ; [p2] -p7 -p3 +p2 +q4 - FILTER_UPDATE m6, m7, m4, m5, [P1], m2, m15, m10, m13, 4, m1, m13, [Q5] ; [p1] -p7 -p2 +p1 +q5 - FILTER_UPDATE m4, m5, m6, m7, [P0], m2, m10, m11, m13, 4, m1, m13, [Q6] ; [p0] -p7 -p1 +p0 +q6 - FILTER_UPDATE m6, m7, m4, m5, [Q0], m2, m11, m12, m13, 4, m1, m13, [Q7] ; [q0] -p7 -p0 +q0 +q7 - FILTER_UPDATE m4, m5, m6, m7, [Q1], m3, m12, m2, m13, 4, m1, m2, [Q1] ; [q1] -p6 -q0 +q1 +q7 - FILTER_UPDATE m6, m7, m4, m5, [Q2], m8, m2, m3, m13, 4, m1, m3, [Q2] ; [q2] -p5 -q1 +q2 +q7 - FILTER_UPDATE m4, m5, m6, m7, [Q3], m9, m3, m8, m13, 4, m1, m8, m8, [Q3] ; [q3] -p4 -q2 +q3 +q7 - FILTER_UPDATE m6, m7, m4, m5, [Q4], m14, m8, m9, m13, 4, m1, m9, m9, [Q4] ; [q4] -p3 -q3 +q4 +q7 - FILTER_UPDATE m4, m5, m6, m7, [Q5], m15, m9, m14, m13, 4, m1, m14, m14, [Q5] ; [q5] -p2 -q4 +q5 +q7 - FILTER_UPDATE m6, m7, m4, m5, [Q6], m10, m14, m15, m13, 4, m1, m15, m15, [Q6] ; [q6] -p1 -q5 +q6 +q7 + FILTER_INIT m4, m5, m6, m7, [P6], %4, 14, m1, m3 ; [p6] + FILTER_UPDATE m4, m5, m6, m7, [P5], %4, 8, 9, 10, 5, 4, m1, m8 ; [p5] -p7 -p6 +p5 +q1 + FILTER_UPDATE m4, m5, m6, m7, [P4], %4, 8, 10, 11, 6, 4, m1, m9 ; [p4] -p7 -p5 +p4 +q2 + FILTER_UPDATE m4, m5, m6, m7, [P3], %4, 8, 11, 0, 7, 4, m1, m14 ; [p3] -p7 -p4 +p3 +q3 + FILTER_UPDATE m4, m5, m6, m7, [P2], %4, 8, 0, 1, 12, 4, m1, "", m8, [Q4] ; [p2] -p7 -p3 +p2 +q4 + FILTER_UPDATE m4, m5, m6, m7, [P1], %4, 8, 1, 2, 13, 4, m1, "", m9, [Q5] ; [p1] -p7 -p2 +p1 +q5 + FILTER_UPDATE m4, m5, m6, m7, [P0], %4, 8, 2, 3, 14, 4, m1, "", m14, [Q6] ; [p0] -p7 -p1 +p0 +q6 + FILTER_UPDATE m4, m5, m6, m7, [Q0], %4, 8, 3, 4, 15, 4, m1, "", m15, [Q7] ; [q0] -p7 -p0 +q0 +q7 + FILTER_UPDATE m4, m5, m6, m7, [Q1], %4, 9, 4, 5, 15, 4, m1, "" ; [q1] -p6 -q0 +q1 +q7 + FILTER_UPDATE m4, m5, m6, m7, [Q2], %4, 10, 5, 6, 15, 4, m1, "" ; [q2] -p5 -q1 +q2 +q7 + FILTER_UPDATE m4, m5, m6, m7, [Q3], %4, 11, 6, 7, 15, 4, m1, "" ; [q3] -p4 -q2 +q3 +q7 + FILTER_UPDATE m4, m5, m6, m7, [Q4], %4, 0, 7, 12, 15, 4, m1, m8 ; [q4] -p3 -q3 +q4 +q7 + FILTER_UPDATE m4, m5, m6, m7, [Q5], %4, 1, 12, 13, 15, 4, m1, m9 ; [q5] -p2 -q4 +q5 +q7 + FILTER_UPDATE m4, m5, m6, m7, [Q6], %4, 2, 13, 14, 15, 4, m1, m14 ; [q6] -p1 -q5 +q6 +q7 %endif %ifidn %1, h @@ -800,22 +807,22 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3, dst, stride, mstride, dst2, stri RET %endmacro -%macro LPF_16_VH 2 -INIT_XMM %2 -LOOPFILTER v, %1, 0 -LOOPFILTER h, %1, 256 +%macro LPF_16_VH 3 +INIT_XMM %3 +LOOPFILTER v, %1, %2, 0 +LOOPFILTER h, %1, %2, 256 %endmacro -%macro LPF_16_VH_ALL_OPTS 1 -LPF_16_VH %1, sse2 -LPF_16_VH %1, ssse3 -LPF_16_VH %1, avx +%macro LPF_16_VH_ALL_OPTS 2 +LPF_16_VH %1, %2, sse2 +LPF_16_VH %1, %2, ssse3 +LPF_16_VH %1, %2, avx %endmacro -LPF_16_VH_ALL_OPTS 16 -LPF_16_VH_ALL_OPTS 44 -LPF_16_VH_ALL_OPTS 48 -LPF_16_VH_ALL_OPTS 84 -LPF_16_VH_ALL_OPTS 88 +LPF_16_VH_ALL_OPTS 16, 512 +LPF_16_VH_ALL_OPTS 44, 0 +LPF_16_VH_ALL_OPTS 48, 256 +LPF_16_VH_ALL_OPTS 84, 256 +LPF_16_VH_ALL_OPTS 88, 256 %endif ; x86-64 From 7c62891efedf0102934bc18d62c6561152a4d0bc Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sat, 27 Dec 2014 14:47:07 -0500 Subject: [PATCH 0264/3374] vp9lpf/x86: save one register in SIGN_ADD/SUB. Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9lpf.asm | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index e3371329a81a0..c2afc44418263 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -142,17 +142,17 @@ SECTION .text %endmacro ; clip_u8(u8 + i8) -%macro SIGN_ADD 5 ; dst, u8, i8, tmp1, tmp2 - EXTRACT_POS_NEG %3, %4, %5 - psubusb %1, %2, %4 ; sub the negatives - paddusb %1, %5 ; add the positives +%macro SIGN_ADD 4 ; dst, u8, i8, tmp1 + EXTRACT_POS_NEG %3, %4, %1 + paddusb %1, %2 ; add the positives + psubusb %1, %4 ; sub the negatives %endmacro ; clip_u8(u8 - i8) -%macro SIGN_SUB 5 ; dst, u8, i8, tmp1, tmp2 - EXTRACT_POS_NEG %3, %4, %5 - psubusb %1, %2, %5 ; sub the positives - paddusb %1, %4 ; add the negatives +%macro SIGN_SUB 4 ; dst, u8, i8, tmp1 + EXTRACT_POS_NEG %3, %1, %4 + paddusb %1, %2 ; add the negatives + psubusb %1, %4 ; sub the positives %endmacro %macro FILTER6_INIT 4 ; %1=dst %2=h/l %3=cache, %4=stack_off @@ -578,8 +578,8 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4, dst, stride, mstride, dst2, paddsb m4, [pb_3] ; m4: f2 = clip(f + 3, 127) mova m14, [pb_10] ; will be reused in filter4() SRSHIFT3B_2X m6, m4, m14, m7 ; f1 and f2 sign byte shift by 3 - SIGN_SUB m7, m12, m6, m5, m9 ; m7 = q0 - f1 - SIGN_ADD m8, m11, m4, m5, m9 ; m8 = p0 + f2 + SIGN_SUB m7, m12, m6, m5 ; m7 = q0 - f1 + SIGN_ADD m8, m11, m4, m5 ; m8 = p0 + f2 %if %2 != 44 pandn m6, m2, m3 ; ~mask(in) & mask(fm) pand m6, m0 ; (~mask(in) & mask(fm)) & mask(hev) @@ -607,18 +607,18 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4, dst, stride, mstride, dst2, %define q0tmp m2 pandn m0, m3 %endif - SIGN_SUB q0tmp, m12, m6, m4, m14 ; q0 - f1 + SIGN_SUB q0tmp, m12, m6, m4 ; q0 - f1 MASK_APPLY q0tmp, m7, m0, m5 ; filter4(q0) & mask mova [Q0], q0tmp - SIGN_ADD p0tmp, m11, m15, m4, m14 ; p0 + f2 + SIGN_ADD p0tmp, m11, m15, m4 ; p0 + f2 MASK_APPLY p0tmp, m8, m0, m5 ; filter4(p0) & mask mova [P0], p0tmp paddb m6, [pb_80] ; pxor m8, m8 ; f=(f1+1)>>1 pavgb m6, m8 ; psubb m6, [pb_40] ; - SIGN_ADD m7, m10, m6, m8, m9 ; p1 + f - SIGN_SUB m4, m13, m6, m8, m9 ; q1 - f + SIGN_ADD m7, m10, m6, m8 ; p1 + f + SIGN_SUB m4, m13, m6, m8 ; q1 - f MASK_APPLY m7, m10, m0, m14 ; m7 = filter4(p1) MASK_APPLY m4, m13, m0, m14 ; m4 = filter4(q1) mova [P1], m7 From be10834bd9dde81fc10568b7da8ffd1493df8589 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sat, 27 Dec 2014 15:08:48 -0500 Subject: [PATCH 0265/3374] vp9lpf/x86: make filter_44_v work on 32-bit. Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9dsp_init.c | 4 +- libavcodec/x86/vp9lpf.asm | 155 ++++++++++++++++++++++------------- 2 files changed, 100 insertions(+), 59 deletions(-) diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c index 88267b9fc9422..daced21731368 100644 --- a/libavcodec/x86/vp9dsp_init.c +++ b/libavcodec/x86/vp9dsp_init.c @@ -283,7 +283,9 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_##opt; \ dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_##opt; \ dsp->loop_filter_mix2[0][0][0] = ff_vp9_loop_filter_h_44_16_##opt; \ - dsp->loop_filter_mix2[0][0][1] = ff_vp9_loop_filter_v_44_16_##opt; \ + } \ + dsp->loop_filter_mix2[0][0][1] = ff_vp9_loop_filter_v_44_16_##opt; \ + if (ARCH_X86_64) { \ dsp->loop_filter_mix2[0][1][0] = ff_vp9_loop_filter_h_48_16_##opt; \ dsp->loop_filter_mix2[0][1][1] = ff_vp9_loop_filter_v_48_16_##opt; \ dsp->loop_filter_mix2[1][0][0] = ff_vp9_loop_filter_h_84_16_##opt; \ diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index c2afc44418263..d9a6215aa4df4 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -2,6 +2,7 @@ ;* VP9 loop filter SIMD optimizations ;* ;* Copyright (C) 2013-2014 Clément Bœsch +;* Copyright (C) 2014 Ronald S. Bultje ;* ;* This file is part of Libav. ;* @@ -23,8 +24,6 @@ %include "libavutil/x86/x86util.asm" -%if ARCH_X86_64 - SECTION_RODATA cextern pb_3 @@ -55,8 +54,15 @@ SECTION .text ; %1 = abs(%2-%3) %macro ABSSUB 4 ; dst, src1 (RO), src2 (RO), tmp +%if ARCH_X86_64 psubusb %1, %3, %2 psubusb %4, %2, %3 +%else + mova %1, %3 + mova %4, %2 + psubusb %1, %2 + psubusb %4, %3 +%endif por %1, %4 %endmacro @@ -428,6 +434,7 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4, dst, stride, mstride, dst2, mova m0, [pb_80] pxor m2, m0 pxor m3, m0 +%if ARCH_X86_64 %ifidn %1, v mova m8, [P3] mova m9, [P2] @@ -445,20 +452,38 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4, dst, stride, mstride, dst2, SWAP 10, 6, 14 SWAP 11, 7, 15 %endif - ABSSUB_GT m5, m8, m9, m2, m7, m0 ; m5 = abs(p3-p2) <= I - ABSSUB_GT m1, m9, m10, m2, m7, m0 ; m1 = abs(p2-p1) <= I +%define rp3 m8 +%define rp2 m9 +%define rp1 m10 +%define rp0 m11 +%define rq0 m12 +%define rq1 m13 +%define rq2 m14 +%define rq3 m15 +%else +%define rp3 [P3] +%define rp2 [P2] +%define rp1 [P1] +%define rp0 [P0] +%define rq0 [Q0] +%define rq1 [Q1] +%define rq2 [Q2] +%define rq3 [Q3] +%endif + ABSSUB_GT m5, rp3, rp2, m2, m7, m0 ; m5 = abs(p3-p2) <= I + ABSSUB_GT m1, rp2, rp1, m2, m7, m0 ; m1 = abs(p2-p1) <= I por m5, m1 - ABSSUB_GT m1, m10, m11, m2, m7, m0 ; m1 = abs(p1-p0) <= I + ABSSUB_GT m1, rp1, rp0, m2, m7, m0 ; m1 = abs(p1-p0) <= I por m5, m1 - ABSSUB_GT m1, m12, m13, m2, m7, m0 ; m1 = abs(q1-q0) <= I + ABSSUB_GT m1, rq0, rq1, m2, m7, m0 ; m1 = abs(q1-q0) <= I por m5, m1 - ABSSUB_GT m1, m13, m14, m2, m7, m0 ; m1 = abs(q2-q1) <= I + ABSSUB_GT m1, rq1, rq2, m2, m7, m0 ; m1 = abs(q2-q1) <= I por m5, m1 - ABSSUB_GT m1, m14, m15, m2, m7, m0 ; m1 = abs(q3-q2) <= I + ABSSUB_GT m1, rq2, rq3, m2, m7, m0 ; m1 = abs(q3-q2) <= I por m5, m1 - ABSSUB m1, m11, m12, m7 ; abs(p0-q0) + ABSSUB m1, rp0, rq0, m7 ; abs(p0-q0) paddusb m1, m1 ; abs(p0-q0) * 2 - ABSSUB m2, m10, m13, m7 ; abs(p1-q1) + ABSSUB m2, rp1, rq1, m7 ; abs(p1-q1) pand m2, [pb_fe] ; drop lsb so shift can work psrlq m2, 1 ; abs(p1-q1)/2 paddusb m1, m2 ; abs(p0-q0)*2 + abs(p1-q1)/2 @@ -510,10 +535,10 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4, dst, stride, mstride, dst2, movd m7, Hd SPLATB_MIX m7 pxor m7, m6 - ABSSUB m4, m10, m11, m1 ; abs(p1 - p0) + ABSSUB m4, rp1, rp0, m1 ; abs(p1 - p0) pxor m4, m6 pcmpgtb m0, m4, m7 ; abs(p1 - p0) > H (1/2 hev condition) - ABSSUB m4, m13, m12, m1 ; abs(q1 - q0) + ABSSUB m4, rq1, rq0, m1 ; abs(q1 - q0) pxor m4, m6 pcmpgtb m5, m4, m7 ; abs(q1 - q0) > H (2/2 hev condition) por m0, m5 ; hev final value @@ -564,66 +589,74 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4, dst, stride, mstride, dst2, ; filter2() %if %2 != 44 mova m6, [pb_80] ; already in m6 if 44_16 + SWAP 2, 15 + SWAP 1, 8 %endif - pxor m15, m12, m6 ; q0 ^ 0x80 - pxor m14, m11, m6 ; p0 ^ 0x80 - psubsb m15, m14 ; (signed) q0 - p0 - pxor m4, m10, m6 ; p1 ^ 0x80 - pxor m5, m13, m6 ; q1 ^ 0x80 + pxor m2, m6, rq0 ; q0 ^ 0x80 + pxor m4, m6, rp0 ; p0 ^ 0x80 + psubsb m2, m4 ; (signed) q0 - p0 + pxor m4, m6, rp1 ; p1 ^ 0x80 + pxor m5, m6, rq1 ; q1 ^ 0x80 psubsb m4, m5 ; (signed) p1 - q1 - paddsb m4, m15 ; (q0 - p0) + (p1 - q1) - paddsb m4, m15 ; 2*(q0 - p0) + (p1 - q1) - paddsb m4, m15 ; 3*(q0 - p0) + (p1 - q1) + paddsb m4, m2 ; (q0 - p0) + (p1 - q1) + paddsb m4, m2 ; 2*(q0 - p0) + (p1 - q1) + paddsb m4, m2 ; 3*(q0 - p0) + (p1 - q1) paddsb m6, m4, [pb_4] ; m6: f1 = clip(f + 4, 127) paddsb m4, [pb_3] ; m4: f2 = clip(f + 3, 127) +%if ARCH_X86_64 mova m14, [pb_10] ; will be reused in filter4() - SRSHIFT3B_2X m6, m4, m14, m7 ; f1 and f2 sign byte shift by 3 - SIGN_SUB m7, m12, m6, m5 ; m7 = q0 - f1 - SIGN_ADD m8, m11, m4, m5 ; m8 = p0 + f2 +%define rb10 m14 +%else +%define rb10 [pb_10] +%endif + SRSHIFT3B_2X m6, m4, rb10, m7 ; f1 and f2 sign byte shift by 3 + SIGN_SUB m7, rq0, m6, m5 ; m7 = q0 - f1 + SIGN_ADD m1, rp0, m4, m5 ; m1 = p0 + f2 %if %2 != 44 - pandn m6, m2, m3 ; ~mask(in) & mask(fm) + pandn m6, m15, m3 ; ~mask(in) & mask(fm) pand m6, m0 ; (~mask(in) & mask(fm)) & mask(hev) %else pand m6, m3, m0 %endif - MASK_APPLY m7, m12, m6, m5 ; m7 = filter2(q0) & mask / we write it in filter4() - MASK_APPLY m8, m11, m6, m5 ; m8 = filter2(p0) & mask / we write it in filter4() + MASK_APPLY m7, rq0, m6, m5 ; m7 = filter2(q0) & mask / we write it in filter4() + MASK_APPLY m1, rp0, m6, m5 ; m1 = filter2(p0) & mask / we write it in filter4() - ; (m0: hev, [m1: flat8out], [m2: flat8in], m3: fm, m7..m8: q0' p0', m10..13: p1 p0 q0 q1, m14: pb_10, m15: q0-p0) + ; (m0: hev, m1: p0', m2: q0-p0, m3: fm, m7: q0', [m8: flat8out], m10..13: p1 p0 q0 q1, m14: pb_10, [m15: flat8in], ) ; filter4() - mova m4, m15 - paddsb m15, m4 ; 2 * (q0 - p0) - paddsb m15, m4 ; 3 * (q0 - p0) - paddsb m6, m15, [pb_4] ; m6: f1 = clip(f + 4, 127) - paddsb m15, [pb_3] ; m15: f2 = clip(f + 3, 127) - SRSHIFT3B_2X m6, m15, m14, m9 ; f1 and f2 sign byte shift by 3 + mova m4, m2 + paddsb m2, m4 ; 2 * (q0 - p0) + paddsb m2, m4 ; 3 * (q0 - p0) + paddsb m6, m2, [pb_4] ; m6: f1 = clip(f + 4, 127) + paddsb m2, [pb_3] ; m2: f2 = clip(f + 3, 127) + SRSHIFT3B_2X m6, m2, rb10, m4 ; f1 and f2 sign byte shift by 3 %if %2 != 44 -%define p0tmp m7 -%define q0tmp m9 - pandn m5, m2, m3 ; ~mask(in) & mask(fm) + pandn m5, m15, m3 ; ~mask(in) & mask(fm) pandn m0, m5 ; ~mask(hev) & (~mask(in) & mask(fm)) %else -%define p0tmp m1 -%define q0tmp m2 pandn m0, m3 %endif - SIGN_SUB q0tmp, m12, m6, m4 ; q0 - f1 - MASK_APPLY q0tmp, m7, m0, m5 ; filter4(q0) & mask - mova [Q0], q0tmp - SIGN_ADD p0tmp, m11, m15, m4 ; p0 + f2 - MASK_APPLY p0tmp, m8, m0, m5 ; filter4(p0) & mask - mova [P0], p0tmp + SIGN_SUB m5, rq0, m6, m4 ; q0 - f1 + MASK_APPLY m5, m7, m0, m4 ; filter4(q0) & mask + mova [Q0], m5 + SIGN_ADD m7, rp0, m2, m4 ; p0 + f2 + MASK_APPLY m7, m1, m0, m4 ; filter4(p0) & mask + mova [P0], m7 paddb m6, [pb_80] ; - pxor m8, m8 ; f=(f1+1)>>1 - pavgb m6, m8 ; + pxor m1, m1 ; f=(f1+1)>>1 + pavgb m6, m1 ; psubb m6, [pb_40] ; - SIGN_ADD m7, m10, m6, m8 ; p1 + f - SIGN_SUB m4, m13, m6, m8 ; q1 - f - MASK_APPLY m7, m10, m0, m14 ; m7 = filter4(p1) - MASK_APPLY m4, m13, m0, m14 ; m4 = filter4(q1) - mova [P1], m7 + SIGN_ADD m1, rp1, m6, m2 ; p1 + f + SIGN_SUB m4, rq1, m6, m2 ; q1 - f + MASK_APPLY m1, rp1, m0, m2 ; m1 = filter4(p1) + MASK_APPLY m4, rq1, m0, m2 ; m4 = filter4(q1) + mova [P1], m1 mova [Q1], m4 +%if %2 != 44 +SWAP 1, 8 +SWAP 2, 15 +%endif + ; ([m1: flat8out], m2: flat8in, m3: fm, m10..13: p1 p0 q0 q1) ; filter6() %if %2 != 44 @@ -726,13 +759,15 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4, dst, stride, mstride, dst2, movu [Q6], m14 movu [Q7], m15 %elif %2 == 44 - SWAP 0, 7 ; m0 = p1 + SWAP 0, 1 ; m0 = p1 + SWAP 1, 7 ; m1 = p0 + SWAP 2, 5 ; m2 = q0 SWAP 3, 4 ; m3 = q1 DEFINE_REAL_P7_TO_Q7 2 - SBUTTERFLY bw, 0, 1, 8 - SBUTTERFLY bw, 2, 3, 8 - SBUTTERFLY wd, 0, 2, 8 - SBUTTERFLY wd, 1, 3, 8 + SBUTTERFLY bw, 0, 1, 4 + SBUTTERFLY bw, 2, 3, 4 + SBUTTERFLY wd, 0, 2, 4 + SBUTTERFLY wd, 1, 3, 4 movd [P7], m0 movd [P3], m2 movd [Q0], m1 @@ -810,7 +845,9 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4, dst, stride, mstride, dst2, %macro LPF_16_VH 3 INIT_XMM %3 LOOPFILTER v, %1, %2, 0 +%if ARCH_X86_64 LOOPFILTER h, %1, %2, 256 +%endif %endmacro %macro LPF_16_VH_ALL_OPTS 2 @@ -819,10 +856,12 @@ LPF_16_VH %1, %2, ssse3 LPF_16_VH %1, %2, avx %endmacro +%if ARCH_X86_64 LPF_16_VH_ALL_OPTS 16, 512 +%endif LPF_16_VH_ALL_OPTS 44, 0 +%if ARCH_X86_64 LPF_16_VH_ALL_OPTS 48, 256 LPF_16_VH_ALL_OPTS 84, 256 LPF_16_VH_ALL_OPTS 88, 256 - -%endif ; x86-64 +%endif From 37637e65907b1a8c3731ea69c638792cb2438d0c Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sat, 27 Dec 2014 15:12:01 -0500 Subject: [PATCH 0266/3374] vp9lpf/x86: make filter_88_v work on 32-bit. Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9dsp_init.c | 2 +- libavcodec/x86/vp9lpf.asm | 155 ++++++++++++++++++++++++----------- 2 files changed, 109 insertions(+), 48 deletions(-) diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c index daced21731368..523e92c487741 100644 --- a/libavcodec/x86/vp9dsp_init.c +++ b/libavcodec/x86/vp9dsp_init.c @@ -291,8 +291,8 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) dsp->loop_filter_mix2[1][0][0] = ff_vp9_loop_filter_h_84_16_##opt; \ dsp->loop_filter_mix2[1][0][1] = ff_vp9_loop_filter_v_84_16_##opt; \ dsp->loop_filter_mix2[1][1][0] = ff_vp9_loop_filter_h_88_16_##opt; \ - dsp->loop_filter_mix2[1][1][1] = ff_vp9_loop_filter_v_88_16_##opt; \ } \ + dsp->loop_filter_mix2[1][1][1] = ff_vp9_loop_filter_v_88_16_##opt; \ } while (0) if (EXTERNAL_MMX(cpu_flags)) { diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index d9a6215aa4df4..e1c2b7b445a94 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -52,6 +52,22 @@ mask_mix48: times 8 db 0x00 SECTION .text +%macro SCRATCH 3 +%if ARCH_X86_64 + SWAP %1, %2 +%else + mova [%3], m%1 +%endif +%endmacro + +%macro UNSCRATCH 3 +%if ARCH_X86_64 + SWAP %1, %2 +%else + mova m%1, [%3] +%endif +%endmacro + ; %1 = abs(%2-%3) %macro ABSSUB 4 ; dst, src1 (RO), src2 (RO), tmp %if ARCH_X86_64 @@ -86,12 +102,26 @@ SECTION .text por %1, %4 ; new&mask | old&~mask %endmacro -%macro FILTER_SUBx2_ADDx2 9-10 "" ; %1=dst %2=h/l %3=cache %4=stack_off %5=sub1 %6=sub2 %7=add1 %8=add2 %9=rshift, [unpack] +%macro UNPACK 4 +%if ARCH_X86_64 + punpck%1bw %2, %3, %4 +%else + mova %2, %3 + punpck%1bw %2, %4 +%endif +%endmacro + +%macro FILTER_SUBx2_ADDx2 11 ; %1=dst %2=h/l %3=cache %4=stack_off %5=sub1 %6=sub2 %7=add1 + ; %8=add2 %9=rshift, [unpack], [unpack_is_mem_on_x86_32] psubw %3, [rsp+%4+%5*32] psubw %3, [rsp+%4+%6*32] paddw %3, [rsp+%4+%7*32] %ifnidn %10, "" +%if %11 == 0 punpck%2bw %1, %10, m0 +%else + UNPACK %2, %1, %10, m0 +%endif mova [rsp+%4+%8*32], %1 paddw %3, %1 %else @@ -110,13 +140,14 @@ SECTION .text %endmacro -%macro FILTER_UPDATE 12-15 "", "" ; tmp1, tmp2, cacheL, cacheH, dstp, stack_off, -, -, +, +, rshift, mask, [source], [unpack] +%macro FILTER_UPDATE 12-16 "", "", "", 0 ; tmp1, tmp2, cacheL, cacheH, dstp, stack_off, -, -, +, +, rshift, + ; mask, [source], [unpack + src], [unpack_is_mem_on_x86_32] ; FIXME interleave this properly with the subx2/addx2 -%if %0 == 15 +%ifnidn %15, "" mova %14, %15 %endif - FILTER_SUBx2_ADDx2 %1, l, %3, %6 + 0, %7, %8, %9, %10, %11, %14 - FILTER_SUBx2_ADDx2 %2, h, %4, %6 + 16, %7, %8, %9, %10, %11, %14 + FILTER_SUBx2_ADDx2 %1, l, %3, %6 + 0, %7, %8, %9, %10, %11, %14, %16 + FILTER_SUBx2_ADDx2 %2, h, %4, %6 + 16, %7, %8, %9, %10, %11, %14, %16 packuswb %1, %2 %ifnidn %13, "" MASK_APPLY %1, %13, %12, %2 @@ -162,21 +193,21 @@ SECTION .text %endmacro %macro FILTER6_INIT 4 ; %1=dst %2=h/l %3=cache, %4=stack_off - punpck%2bw %1, m14, m0 ; p3: B->W + UNPACK %2, %1, rp3, m0 ; p3: B->W mova [rsp+%4+0*32], %1 paddw %3, %1, %1 ; p3*2 paddw %3, %1 ; p3*3 - punpck%2bw %1, m15, m0 ; p2: B->W + punpck%2bw %1, m2, m0 ; p2: B->W mova [rsp+%4+1*32], %1 paddw %3, %1 ; p3*3 + p2 paddw %3, %1 ; p3*3 + p2*2 - punpck%2bw %1, m10, m0 ; p1: B->W + UNPACK %2, %1, rp1, m0 ; p1: B->W mova [rsp+%4+2*32], %1 paddw %3, %1 ; p3*3 + p2*2 + p1 - punpck%2bw %1, m11, m0 ; p0: B->W + UNPACK %2, %1, rp0, m0 ; p0: B->W mova [rsp+%4+3*32], %1 paddw %3, %1 ; p3*3 + p2*2 + p1 + p0 - punpck%2bw %1, m12, m0 ; q0: B->W + UNPACK %2, %1, rq0, m0 ; q0: B->W mova [rsp+%4+4*32], %1 paddw %3, %1 ; p3*3 + p2*2 + p1 + p0 + q0 paddw %3, [pw_4] ; p3*3 + p2*2 + p1 + p0 + q0 + 4 @@ -320,14 +351,14 @@ SECTION .text %endif %endmacro -%macro LOOPFILTER 4 ; %1=v/h %2=size1 %3+%4=stack +%macro LOOPFILTER 5 ; %1=v/h %2=size1 %3+%4=stack, %5=32bit stack only %if UNIX64 cglobal vp9_loop_filter_%1_%2_16, 5, 9, 16, %3 + %4, dst, stride, E, I, H, mstride, dst2, stride3, mstride3 %else %if WIN64 cglobal vp9_loop_filter_%1_%2_16, 4, 8, 16, %3 + %4, dst, stride, E, I, mstride, dst2, stride3, mstride3 %else -cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4, dst, stride, mstride, dst2, stride3, mstride3 +cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4 + %5, dst, stride, mstride, dst2, stride3, mstride3 %define Ed dword r2m %define Id dword r3m %endif @@ -497,11 +528,16 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4, dst, stride, mstride, dst2, ; calc flat8in (if not 44_16) and hev masks %if %2 != 44 mova m6, [pb_81] ; [1 1 1 1 ...] ^ 0x80 - ABSSUB_GT m2, m8, m11, m6, m5 ; abs(p3 - p0) <= 1 + ABSSUB_GT m2, rp3, rp0, m6, m5 ; abs(p3 - p0) <= 1 +%if ARCH_X86_64 mova m8, [pb_80] - ABSSUB_GT m1, m9, m11, m6, m5, m8 ; abs(p2 - p0) <= 1 +%define rb80 m8 +%else +%define rb80 [pb_80] +%endif + ABSSUB_GT m1, rp2, rp0, m6, m5, rb80 ; abs(p2 - p0) <= 1 por m2, m1 - ABSSUB m4, m10, m11, m5 ; abs(p1 - p0) + ABSSUB m4, rp1, rp0, m5 ; abs(p1 - p0) %if %2 == 16 %if cpuflag(ssse3) pxor m0, m0 @@ -511,20 +547,20 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4, dst, stride, mstride, dst2, movd m7, Hd SPLATB_MIX m7 %endif - pxor m7, m8 - pxor m4, m8 + pxor m7, rb80 + pxor m4, rb80 pcmpgtb m0, m4, m7 ; abs(p1 - p0) > H (1/2 hev condition) CMP_GT m4, m6 ; abs(p1 - p0) <= 1 por m2, m4 ; (flat8in) - ABSSUB m4, m13, m12, m1 ; abs(q1 - q0) - pxor m4, m8 + ABSSUB m4, rq1, rq0, m1 ; abs(q1 - q0) + pxor m4, rb80 pcmpgtb m5, m4, m7 ; abs(q1 - q0) > H (2/2 hev condition) por m0, m5 ; hev final value CMP_GT m4, m6 ; abs(q1 - q0) <= 1 por m2, m4 ; (flat8in) - ABSSUB_GT m1, m14, m12, m6, m5, m8 ; abs(q2 - q0) <= 1 + ABSSUB_GT m1, rq2, rq0, m6, m5, rb80 ; abs(q2 - q0) <= 1 por m2, m1 - ABSSUB_GT m1, m15, m12, m6, m5, m8 ; abs(q3 - q0) <= 1 + ABSSUB_GT m1, rq3, rq0, m6, m5, rb80 ; abs(q3 - q0) <= 1 por m2, m1 ; flat8in final value pxor m2, [pb_ff] %if %2 == 84 || %2 == 48 @@ -589,8 +625,10 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4, dst, stride, mstride, dst2, ; filter2() %if %2 != 44 mova m6, [pb_80] ; already in m6 if 44_16 - SWAP 2, 15 + SCRATCH 2, 15, rsp+%3+%4 +%if %2 == 16 SWAP 1, 8 +%endif %endif pxor m2, m6, rq0 ; q0 ^ 0x80 pxor m4, m6, rp0 ; p0 ^ 0x80 @@ -613,7 +651,12 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4, dst, stride, mstride, dst2, SIGN_SUB m7, rq0, m6, m5 ; m7 = q0 - f1 SIGN_ADD m1, rp0, m4, m5 ; m1 = p0 + f2 %if %2 != 44 +%if ARCH_X86_64 pandn m6, m15, m3 ; ~mask(in) & mask(fm) +%else + mova m6, [rsp+%3+%4] + pandn m6, m3 +%endif pand m6, m0 ; (~mask(in) & mask(fm)) & mask(hev) %else pand m6, m3, m0 @@ -630,7 +673,12 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4, dst, stride, mstride, dst2, paddsb m2, [pb_3] ; m2: f2 = clip(f + 3, 127) SRSHIFT3B_2X m6, m2, rb10, m4 ; f1 and f2 sign byte shift by 3 %if %2 != 44 +%if ARCH_X86_64 pandn m5, m15, m3 ; ~mask(in) & mask(fm) +%else + mova m5, [rsp+%3+%4] + pandn m5, m3 +%endif pandn m0, m5 ; ~mask(hev) & (~mask(in) & mask(fm)) %else pandn m0, m3 @@ -652,31 +700,44 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4, dst, stride, mstride, dst2, mova [P1], m1 mova [Q1], m4 -%if %2 != 44 -SWAP 1, 8 -SWAP 2, 15 -%endif - ; ([m1: flat8out], m2: flat8in, m3: fm, m10..13: p1 p0 q0 q1) ; filter6() %if %2 != 44 pxor m0, m0 %if %2 > 16 - pand m3, m2 +%if ARCH_X86_64 + pand m3, m15 +%else + pand m3, [rsp+%3+%4] +%endif %else - pand m2, m3 ; mask(fm) & mask(in) - pandn m3, m1, m2 ; ~mask(out) & (mask(fm) & mask(in)) + pand m15, m3 ; mask(fm) & mask(in) + pandn m3, m8, m15 ; ~mask(out) & (mask(fm) & mask(in)) %endif +%if ARCH_X86_64 mova m14, [P3] - mova m15, [P2] - mova m8, [Q2] mova m9, [Q3] - FILTER_INIT m4, m5, m6, m7, [P2], %4, 6, m3, m15 ; [p2] - FILTER_UPDATE m4, m5, m6, m7, [P1], %4, 0, 1, 2, 5, 3, m3, "", m13 ; [p1] -p3 -p2 +p1 +q1 - FILTER_UPDATE m4, m5, m6, m7, [P0], %4, 0, 2, 3, 6, 3, m3, "", m8 ; [p0] -p3 -p1 +p0 +q2 - FILTER_UPDATE m4, m5, m6, m7, [Q0], %4, 0, 3, 4, 7, 3, m3, "", m9 ; [q0] -p3 -p0 +q0 +q3 +%define rp3 m14 +%define rq3 m9 +%else +%define rp3 [P3] +%define rq3 [Q3] +%endif + mova m2, [P2] + mova m1, [Q2] + FILTER_INIT m4, m5, m6, m7, [P2], %4, 6, m3, m2 ; [p2] + FILTER_UPDATE m4, m5, m6, m7, [P1], %4, 0, 1, 2, 5, 3, m3, "", rq1, "", 1 ; [p1] -p3 -p2 +p1 +q1 + FILTER_UPDATE m4, m5, m6, m7, [P0], %4, 0, 2, 3, 6, 3, m3, "", m1 ; [p0] -p3 -p1 +p0 +q2 + FILTER_UPDATE m4, m5, m6, m7, [Q0], %4, 0, 3, 4, 7, 3, m3, "", rq3, "", 1 ; [q0] -p3 -p0 +q0 +q3 FILTER_UPDATE m4, m5, m6, m7, [Q1], %4, 1, 4, 5, 7, 3, m3, "" ; [q1] -p2 -q0 +q1 +q3 - FILTER_UPDATE m4, m5, m6, m7, [Q2], %4, 2, 5, 6, 7, 3, m3, m8 ; [q2] -p1 -q1 +q2 +q3 + FILTER_UPDATE m4, m5, m6, m7, [Q2], %4, 2, 5, 6, 7, 3, m3, m1 ; [q2] -p1 -q1 +q2 +q3 +%endif + +%if %2 != 44 +%if %2 == 16 +SWAP 1, 8 +%endif +SWAP 2, 15 %endif ; (m0: 0, [m1: flat8out], m2: fm & flat8in, m8..15: q2 q3 p1 p0 q0 q1 p3 p2) @@ -842,26 +903,26 @@ SWAP 2, 15 RET %endmacro -%macro LPF_16_VH 3 -INIT_XMM %3 -LOOPFILTER v, %1, %2, 0 +%macro LPF_16_VH 4 +INIT_XMM %4 +LOOPFILTER v, %1, %2, 0, %3 %if ARCH_X86_64 -LOOPFILTER h, %1, %2, 256 +LOOPFILTER h, %1, %2, 256, %3 %endif %endmacro -%macro LPF_16_VH_ALL_OPTS 2 -LPF_16_VH %1, %2, sse2 -LPF_16_VH %1, %2, ssse3 -LPF_16_VH %1, %2, avx +%macro LPF_16_VH_ALL_OPTS 2-3 0 +LPF_16_VH %1, %2, %3, sse2 +LPF_16_VH %1, %2, %3, ssse3 +LPF_16_VH %1, %2, %3, avx %endmacro %if ARCH_X86_64 LPF_16_VH_ALL_OPTS 16, 512 %endif -LPF_16_VH_ALL_OPTS 44, 0 +LPF_16_VH_ALL_OPTS 44, 0, 0 %if ARCH_X86_64 LPF_16_VH_ALL_OPTS 48, 256 LPF_16_VH_ALL_OPTS 84, 256 -LPF_16_VH_ALL_OPTS 88, 256 %endif +LPF_16_VH_ALL_OPTS 88, 256, 16 From b905e8d2fe03da1bf34ffa6e04b322f19a479143 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 26 Dec 2014 12:10:26 -0500 Subject: [PATCH 0267/3374] vp9lpf/x86: make filter_48/84_v work on 32-bit. Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9dsp_init.c | 8 ++++++-- libavcodec/x86/vp9lpf.asm | 8 +++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c index 523e92c487741..9f090534d339b 100644 --- a/libavcodec/x86/vp9dsp_init.c +++ b/libavcodec/x86/vp9dsp_init.c @@ -287,9 +287,13 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) dsp->loop_filter_mix2[0][0][1] = ff_vp9_loop_filter_v_44_16_##opt; \ if (ARCH_X86_64) { \ dsp->loop_filter_mix2[0][1][0] = ff_vp9_loop_filter_h_48_16_##opt; \ - dsp->loop_filter_mix2[0][1][1] = ff_vp9_loop_filter_v_48_16_##opt; \ + } \ + dsp->loop_filter_mix2[0][1][1] = ff_vp9_loop_filter_v_48_16_##opt; \ + if (ARCH_X86_64) { \ dsp->loop_filter_mix2[1][0][0] = ff_vp9_loop_filter_h_84_16_##opt; \ - dsp->loop_filter_mix2[1][0][1] = ff_vp9_loop_filter_v_84_16_##opt; \ + } \ + dsp->loop_filter_mix2[1][0][1] = ff_vp9_loop_filter_v_84_16_##opt; \ + if (ARCH_X86_64) { \ dsp->loop_filter_mix2[1][1][0] = ff_vp9_loop_filter_h_88_16_##opt; \ } \ dsp->loop_filter_mix2[1][1][1] = ff_vp9_loop_filter_v_88_16_##opt; \ diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index e1c2b7b445a94..150cd7388a935 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -920,9 +920,7 @@ LPF_16_VH %1, %2, %3, avx %if ARCH_X86_64 LPF_16_VH_ALL_OPTS 16, 512 %endif -LPF_16_VH_ALL_OPTS 44, 0, 0 -%if ARCH_X86_64 -LPF_16_VH_ALL_OPTS 48, 256 -LPF_16_VH_ALL_OPTS 84, 256 -%endif +LPF_16_VH_ALL_OPTS 44, 0, 0 +LPF_16_VH_ALL_OPTS 48, 256, 16 +LPF_16_VH_ALL_OPTS 84, 256, 16 LPF_16_VH_ALL_OPTS 88, 256, 16 From 5bfa96c4b30d9fdb59a8f2a9d0769a3fa2e622be Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 26 Dec 2014 14:05:23 -0500 Subject: [PATCH 0268/3374] vp9lpf/x86: make filter_16_v work on 32-bit. Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9dsp_init.c | 4 +- libavcodec/x86/vp9lpf.asm | 135 +++++++++++++++++++++++++---------- 2 files changed, 99 insertions(+), 40 deletions(-) diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c index 9f090534d339b..76bb06e61ba9e 100644 --- a/libavcodec/x86/vp9dsp_init.c +++ b/libavcodec/x86/vp9dsp_init.c @@ -281,7 +281,9 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) #define init_lpf(opt) do { \ if (ARCH_X86_64) { \ dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_##opt; \ - dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_##opt; \ + } \ + dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_##opt; \ + if (ARCH_X86_64) { \ dsp->loop_filter_mix2[0][0][0] = ff_vp9_loop_filter_h_44_16_##opt; \ } \ dsp->loop_filter_mix2[0][0][1] = ff_vp9_loop_filter_v_44_16_##opt; \ diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index 150cd7388a935..57536b9d830be 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -144,7 +144,9 @@ SECTION .text ; mask, [source], [unpack + src], [unpack_is_mem_on_x86_32] ; FIXME interleave this properly with the subx2/addx2 %ifnidn %15, "" +%if %16 == 0 || ARCH_X86_64 mova %14, %15 +%endif %endif FILTER_SUBx2_ADDx2 %1, l, %3, %6 + 0, %7, %8, %9, %10, %11, %14, %16 FILTER_SUBx2_ADDx2 %2, h, %4, %6 + 16, %7, %8, %9, %10, %11, %14, %16 @@ -197,7 +199,7 @@ SECTION .text mova [rsp+%4+0*32], %1 paddw %3, %1, %1 ; p3*2 paddw %3, %1 ; p3*3 - punpck%2bw %1, m2, m0 ; p2: B->W + punpck%2bw %1, m1, m0 ; p2: B->W mova [rsp+%4+1*32], %1 paddw %3, %1 ; p3*3 + p2 paddw %3, %1 ; p3*3 + p2*2 @@ -223,10 +225,10 @@ SECTION .text mova [rsp+%4+ 9*32], %1 paddw %3, %1 ; p7*7 + p6 paddw %3, %1 ; p7*7 + p6*2 - punpck%2bw %1, m8, m0 ; p5: B->W + UNPACK %2, %1, rp5, m0 ; p5: B->W mova [rsp+%4+10*32], %1 paddw %3, %1 ; p7*7 + p6*2 + p5 - punpck%2bw %1, m9, m0 ; p4: B->W + UNPACK %2, %1, rp4, m0 ; p4: B->W mova [rsp+%4+11*32], %1 paddw %3, %1 ; p7*7 + p6*2 + p5 + p4 paddw %3, [rsp+%4+ 0*32] ; p7*7 + p6*2 + p5 + p4 + p3 @@ -583,28 +585,56 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4 + %5, dst, stride, mstride, %if %2 == 16 ; (m0: hev, m2: flat8in, m3: fm, m6: pb_81, m9..15: p2 p1 p0 q0 q1 q2 q3) ; calc flat8out mask +%if ARCH_X86_64 mova m8, [P7] mova m9, [P6] - ABSSUB_GT m1, m8, m11, m6, m5 ; abs(p7 - p0) <= 1 - ABSSUB_GT m7, m9, m11, m6, m5 ; abs(p6 - p0) <= 1 +%define rp7 m8 +%define rp6 m9 +%else +%define rp7 [P7] +%define rp6 [P6] +%endif + ABSSUB_GT m1, rp7, rp0, m6, m5 ; abs(p7 - p0) <= 1 + ABSSUB_GT m7, rp6, rp0, m6, m5 ; abs(p6 - p0) <= 1 por m1, m7 +%if ARCH_X86_64 mova m8, [P5] mova m9, [P4] - ABSSUB_GT m7, m8, m11, m6, m5 ; abs(p5 - p0) <= 1 +%define rp5 m8 +%define rp4 m9 +%else +%define rp5 [P5] +%define rp4 [P4] +%endif + ABSSUB_GT m7, rp5, rp0, m6, m5 ; abs(p5 - p0) <= 1 por m1, m7 - ABSSUB_GT m7, m9, m11, m6, m5 ; abs(p4 - p0) <= 1 + ABSSUB_GT m7, rp4, rp0, m6, m5 ; abs(p4 - p0) <= 1 por m1, m7 +%if ARCH_X86_64 mova m14, [Q4] mova m15, [Q5] - ABSSUB_GT m7, m14, m12, m6, m5 ; abs(q4 - q0) <= 1 +%define rq4 m14 +%define rq5 m15 +%else +%define rq4 [Q4] +%define rq5 [Q5] +%endif + ABSSUB_GT m7, rq4, rq0, m6, m5 ; abs(q4 - q0) <= 1 por m1, m7 - ABSSUB_GT m7, m15, m12, m6, m5 ; abs(q5 - q0) <= 1 + ABSSUB_GT m7, rq5, rq0, m6, m5 ; abs(q5 - q0) <= 1 por m1, m7 +%if ARCH_X86_64 mova m14, [Q6] mova m15, [Q7] - ABSSUB_GT m7, m14, m12, m6, m5 ; abs(q4 - q0) <= 1 +%define rq6 m14 +%define rq7 m15 +%else +%define rq6 [Q6] +%define rq7 [Q7] +%endif + ABSSUB_GT m7, rq6, rq0, m6, m5 ; abs(q4 - q0) <= 1 por m1, m7 - ABSSUB_GT m7, m15, m12, m6, m5 ; abs(q5 - q0) <= 1 + ABSSUB_GT m7, rq7, rq0, m6, m5 ; abs(q5 - q0) <= 1 por m1, m7 ; flat8out final value pxor m1, [pb_ff] %endif @@ -627,7 +657,7 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4 + %5, dst, stride, mstride, mova m6, [pb_80] ; already in m6 if 44_16 SCRATCH 2, 15, rsp+%3+%4 %if %2 == 16 - SWAP 1, 8 + SCRATCH 1, 8, rsp+%3+%4+16 %endif %endif pxor m2, m6, rq0 ; q0 ^ 0x80 @@ -700,19 +730,24 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4 + %5, dst, stride, mstride, mova [P1], m1 mova [Q1], m4 +%if %2 != 44 + UNSCRATCH 2, 15, rsp+%3+%4 +%endif + ; ([m1: flat8out], m2: flat8in, m3: fm, m10..13: p1 p0 q0 q1) ; filter6() %if %2 != 44 pxor m0, m0 %if %2 > 16 + pand m3, m2 +%else + pand m2, m3 ; mask(fm) & mask(in) %if ARCH_X86_64 - pand m3, m15 + pandn m3, m8, m2 ; ~mask(out) & (mask(fm) & mask(in)) %else - pand m3, [rsp+%3+%4] + mova m3, [rsp+%3+%4+16] + pandn m3, m2 %endif -%else - pand m15, m3 ; mask(fm) & mask(in) - pandn m3, m8, m15 ; ~mask(out) & (mask(fm) & mask(in)) %endif %if ARCH_X86_64 mova m14, [P3] @@ -723,21 +758,18 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4 + %5, dst, stride, mstride, %define rp3 [P3] %define rq3 [Q3] %endif - mova m2, [P2] + mova m1, [P2] + FILTER_INIT m4, m5, m6, m7, [P2], %4, 6, m3, m1 ; [p2] mova m1, [Q2] - FILTER_INIT m4, m5, m6, m7, [P2], %4, 6, m3, m2 ; [p2] FILTER_UPDATE m4, m5, m6, m7, [P1], %4, 0, 1, 2, 5, 3, m3, "", rq1, "", 1 ; [p1] -p3 -p2 +p1 +q1 - FILTER_UPDATE m4, m5, m6, m7, [P0], %4, 0, 2, 3, 6, 3, m3, "", m1 ; [p0] -p3 -p1 +p0 +q2 + FILTER_UPDATE m4, m5, m6, m7, [P0], %4, 0, 2, 3, 6, 3, m3, "", m1 ; [p0] -p3 -p1 +p0 +q2 FILTER_UPDATE m4, m5, m6, m7, [Q0], %4, 0, 3, 4, 7, 3, m3, "", rq3, "", 1 ; [q0] -p3 -p0 +q0 +q3 - FILTER_UPDATE m4, m5, m6, m7, [Q1], %4, 1, 4, 5, 7, 3, m3, "" ; [q1] -p2 -q0 +q1 +q3 - FILTER_UPDATE m4, m5, m6, m7, [Q2], %4, 2, 5, 6, 7, 3, m3, m1 ; [q2] -p1 -q1 +q2 +q3 + FILTER_UPDATE m4, m5, m6, m7, [Q1], %4, 1, 4, 5, 7, 3, m3, "" ; [q1] -p2 -q0 +q1 +q3 + FILTER_UPDATE m4, m5, m6, m7, [Q2], %4, 2, 5, 6, 7, 3, m3, m1 ; [q2] -p1 -q1 +q2 +q3 %endif -%if %2 != 44 %if %2 == 16 -SWAP 1, 8 -%endif -SWAP 2, 15 + UNSCRATCH 1, 8, rsp+%3+%4+16 %endif ; (m0: 0, [m1: flat8out], m2: fm & flat8in, m8..15: q2 q3 p1 p0 q0 q1 p3 p2) @@ -765,22 +797,49 @@ SWAP 2, 15 pand m1, m2 ; mask(out) & (mask(fm) & mask(in)) mova m2, [P7] mova m3, [P6] +%if ARCH_X86_64 mova m8, [P5] mova m9, [P4] +%define rp5 m8 +%define rp4 m9 +%define rp5s m8 +%define rp4s m9 +%define rp3s m14 +%define rq4 m8 +%define rq5 m9 +%define rq6 m14 +%define rq7 m15 +%define rq4s m8 +%define rq5s m9 +%define rq6s m14 +%else +%define rp5 [P5] +%define rp4 [P4] +%define rp5s "" +%define rp4s "" +%define rp3s "" +%define rq4 [Q4] +%define rq5 [Q5] +%define rq6 [Q6] +%define rq7 [Q7] +%define rq4s "" +%define rq5s "" +%define rq6s "" +%endif FILTER_INIT m4, m5, m6, m7, [P6], %4, 14, m1, m3 ; [p6] - FILTER_UPDATE m4, m5, m6, m7, [P5], %4, 8, 9, 10, 5, 4, m1, m8 ; [p5] -p7 -p6 +p5 +q1 - FILTER_UPDATE m4, m5, m6, m7, [P4], %4, 8, 10, 11, 6, 4, m1, m9 ; [p4] -p7 -p5 +p4 +q2 - FILTER_UPDATE m4, m5, m6, m7, [P3], %4, 8, 11, 0, 7, 4, m1, m14 ; [p3] -p7 -p4 +p3 +q3 - FILTER_UPDATE m4, m5, m6, m7, [P2], %4, 8, 0, 1, 12, 4, m1, "", m8, [Q4] ; [p2] -p7 -p3 +p2 +q4 - FILTER_UPDATE m4, m5, m6, m7, [P1], %4, 8, 1, 2, 13, 4, m1, "", m9, [Q5] ; [p1] -p7 -p2 +p1 +q5 - FILTER_UPDATE m4, m5, m6, m7, [P0], %4, 8, 2, 3, 14, 4, m1, "", m14, [Q6] ; [p0] -p7 -p1 +p0 +q6 - FILTER_UPDATE m4, m5, m6, m7, [Q0], %4, 8, 3, 4, 15, 4, m1, "", m15, [Q7] ; [q0] -p7 -p0 +q0 +q7 + FILTER_UPDATE m4, m5, m6, m7, [P5], %4, 8, 9, 10, 5, 4, m1, rp5s ; [p5] -p7 -p6 +p5 +q1 + FILTER_UPDATE m4, m5, m6, m7, [P4], %4, 8, 10, 11, 6, 4, m1, rp4s ; [p4] -p7 -p5 +p4 +q2 + FILTER_UPDATE m4, m5, m6, m7, [P3], %4, 8, 11, 0, 7, 4, m1, rp3s ; [p3] -p7 -p4 +p3 +q3 + FILTER_UPDATE m4, m5, m6, m7, [P2], %4, 8, 0, 1, 12, 4, m1, "", rq4, [Q4], 1 ; [p2] -p7 -p3 +p2 +q4 + FILTER_UPDATE m4, m5, m6, m7, [P1], %4, 8, 1, 2, 13, 4, m1, "", rq5, [Q5], 1 ; [p1] -p7 -p2 +p1 +q5 + FILTER_UPDATE m4, m5, m6, m7, [P0], %4, 8, 2, 3, 14, 4, m1, "", rq6, [Q6], 1 ; [p0] -p7 -p1 +p0 +q6 + FILTER_UPDATE m4, m5, m6, m7, [Q0], %4, 8, 3, 4, 15, 4, m1, "", rq7, [Q7], 1 ; [q0] -p7 -p0 +q0 +q7 FILTER_UPDATE m4, m5, m6, m7, [Q1], %4, 9, 4, 5, 15, 4, m1, "" ; [q1] -p6 -q0 +q1 +q7 FILTER_UPDATE m4, m5, m6, m7, [Q2], %4, 10, 5, 6, 15, 4, m1, "" ; [q2] -p5 -q1 +q2 +q7 FILTER_UPDATE m4, m5, m6, m7, [Q3], %4, 11, 6, 7, 15, 4, m1, "" ; [q3] -p4 -q2 +q3 +q7 - FILTER_UPDATE m4, m5, m6, m7, [Q4], %4, 0, 7, 12, 15, 4, m1, m8 ; [q4] -p3 -q3 +q4 +q7 - FILTER_UPDATE m4, m5, m6, m7, [Q5], %4, 1, 12, 13, 15, 4, m1, m9 ; [q5] -p2 -q4 +q5 +q7 - FILTER_UPDATE m4, m5, m6, m7, [Q6], %4, 2, 13, 14, 15, 4, m1, m14 ; [q6] -p1 -q5 +q6 +q7 + FILTER_UPDATE m4, m5, m6, m7, [Q4], %4, 0, 7, 12, 15, 4, m1, rq4s ; [q4] -p3 -q3 +q4 +q7 + FILTER_UPDATE m4, m5, m6, m7, [Q5], %4, 1, 12, 13, 15, 4, m1, rq5s ; [q5] -p2 -q4 +q5 +q7 + FILTER_UPDATE m4, m5, m6, m7, [Q6], %4, 2, 13, 14, 15, 4, m1, rq6s ; [q6] -p1 -q5 +q6 +q7 %endif %ifidn %1, h @@ -917,9 +976,7 @@ LPF_16_VH %1, %2, %3, ssse3 LPF_16_VH %1, %2, %3, avx %endmacro -%if ARCH_X86_64 -LPF_16_VH_ALL_OPTS 16, 512 -%endif +LPF_16_VH_ALL_OPTS 16, 512, 32 LPF_16_VH_ALL_OPTS 44, 0, 0 LPF_16_VH_ALL_OPTS 48, 256, 16 LPF_16_VH_ALL_OPTS 84, 256, 16 From 725a216481c422a71a727771706d6343a0eaeaf8 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 26 Dec 2014 14:48:01 -0500 Subject: [PATCH 0269/3374] vp9lpf/x86: make filter_44_h work on 32-bit. Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9dsp_init.c | 4 +- libavcodec/x86/vp9lpf.asm | 140 +++++++++++++++++++---------------- 2 files changed, 78 insertions(+), 66 deletions(-) diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c index 76bb06e61ba9e..6438644867a0b 100644 --- a/libavcodec/x86/vp9dsp_init.c +++ b/libavcodec/x86/vp9dsp_init.c @@ -283,9 +283,7 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_##opt; \ } \ dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_##opt; \ - if (ARCH_X86_64) { \ - dsp->loop_filter_mix2[0][0][0] = ff_vp9_loop_filter_h_44_16_##opt; \ - } \ + dsp->loop_filter_mix2[0][0][0] = ff_vp9_loop_filter_h_44_16_##opt; \ dsp->loop_filter_mix2[0][0][1] = ff_vp9_loop_filter_v_44_16_##opt; \ if (ARCH_X86_64) { \ dsp->loop_filter_mix2[0][1][0] = ff_vp9_loop_filter_h_48_16_##opt; \ diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index 57536b9d830be..881bdab8a8ed4 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -291,38 +291,6 @@ SECTION .text SWAP %12, %14 %endmacro -; transpose 16 half lines (high part) to 8 full centered lines -%macro TRANSPOSE16x8B 16 - punpcklbw m%1, m%2 - punpcklbw m%3, m%4 - punpcklbw m%5, m%6 - punpcklbw m%7, m%8 - punpcklbw m%9, m%10 - punpcklbw m%11, m%12 - punpcklbw m%13, m%14 - punpcklbw m%15, m%16 - SBUTTERFLY wd, %1, %3, %2 - SBUTTERFLY wd, %5, %7, %2 - SBUTTERFLY wd, %9, %11, %2 - SBUTTERFLY wd, %13, %15, %2 - SBUTTERFLY dq, %1, %5, %2 - SBUTTERFLY dq, %3, %7, %2 - SBUTTERFLY dq, %9, %13, %2 - SBUTTERFLY dq, %11, %15, %2 - SBUTTERFLY qdq, %1, %9, %2 - SBUTTERFLY qdq, %3, %11, %2 - SBUTTERFLY qdq, %5, %13, %2 - SBUTTERFLY qdq, %7, %15, %2 - SWAP %5, %1 - SWAP %6, %9 - SWAP %7, %1 - SWAP %8, %13 - SWAP %9, %3 - SWAP %10, %11 - SWAP %11, %1 - SWAP %12, %15 -%endmacro - %macro DEFINE_REAL_P7_TO_Q7 0-1 0 %define P7 dstq + 4*mstrideq + %1 %define P6 dstq + mstride3q + %1 @@ -398,6 +366,7 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4 + %5, dst, stride, mstride, movx m5, [P2] movx m6, [P1] movx m7, [P0] +%if ARCH_X86_64 movx m8, [Q0] movx m9, [Q1] movx m10, [Q2] @@ -406,32 +375,67 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4 + %5, dst, stride, mstride, movx m13, [Q5] movx m14, [Q6] movx m15, [Q7] -%define P7 rsp + 0 -%define P6 rsp + 16 -%define P5 rsp + 32 -%define P4 rsp + 48 -%define P3 rsp + 64 -%define P2 rsp + 80 -%define P1 rsp + 96 -%define P0 rsp + 112 -%define Q0 rsp + 128 -%define Q1 rsp + 144 -%define Q2 rsp + 160 -%define Q3 rsp + 176 +%if %2 == 16 + TRANSPOSE16x16B 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, [rsp] +%define P7 rsp + 128 +%define P6 rsp + 144 +%define P5 rsp + 160 +%define P4 rsp + 176 %define Q4 rsp + 192 %define Q5 rsp + 208 %define Q6 rsp + 224 %define Q7 rsp + 240 - -%if %2 == 16 - TRANSPOSE16x16B 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, [rsp] mova [P7], m0 mova [P6], m1 mova [P5], m2 mova [P4], m3 %else - TRANSPOSE16x8B 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 -%endif + ; 8x16 transpose + punpcklbw m0, m1 + punpcklbw m2, m3 + punpcklbw m4, m5 + punpcklbw m6, m7 + punpcklbw m8, m9 + punpcklbw m10, m11 + punpcklbw m12, m13 + punpcklbw m14, m15 + TRANSPOSE8x8W 0, 2, 4, 6, 8, 10, 12, 14, 15 + SWAP 0, 4 + SWAP 2, 5 + SWAP 0, 6 + SWAP 0, 7 + SWAP 10, 9 + SWAP 12, 10 + SWAP 14, 11 +%endif +%else ; x86-32 + punpcklbw m0, m1 + punpcklbw m2, m3 + punpcklbw m4, m5 + punpcklbw m6, m7 + movx m1, [Q0] + movx m3, [Q1] + movx m5, [Q2] + movx m7, [Q3] + punpcklbw m1, m3 + punpcklbw m5, m7 + movx m3, [Q4] + movx m7, [Q5] + punpcklbw m3, m7 + mova [rsp], m3 + movx m3, [Q6] + movx m7, [Q7] + punpcklbw m3, m7 +%endif +%define P3 rsp + 0 +%define P2 rsp + 16 +%define P1 rsp + 32 +%define P0 rsp + 48 +%define Q0 rsp + 64 +%define Q1 rsp + 80 +%define Q2 rsp + 96 +%define Q3 rsp + 112 +%if ARCH_X86_64 mova [P3], m4 mova [P2], m5 mova [P1], m6 @@ -446,7 +450,17 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4 + %5, dst, stride, mstride, mova [Q6], m14 mova [Q7], m15 %endif +%else ; x86-32 + TRANSPOSE8x8W 0, 2, 4, 6, 1, 5, 7, 3, [rsp], [Q0], 1 + mova [P3], m0 + mova [P2], m2 + mova [P1], m4 + mova [P0], m6 + mova [Q1], m5 + mova [Q2], m7 + mova [Q3], m3 %endif +%endif ; %1 == h ; calc fm mask %if %2 == 16 @@ -962,22 +976,22 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4 + %5, dst, stride, mstride, RET %endmacro -%macro LPF_16_VH 4 -INIT_XMM %4 -LOOPFILTER v, %1, %2, 0, %3 -%if ARCH_X86_64 -LOOPFILTER h, %1, %2, 256, %3 +%macro LPF_16_VH 5 +INIT_XMM %5 +LOOPFILTER v, %1, %2, 0, %4 +%if ARCH_X86_64 || %1 == 44 +LOOPFILTER h, %1, %2, %3, %4 %endif %endmacro -%macro LPF_16_VH_ALL_OPTS 2-3 0 -LPF_16_VH %1, %2, %3, sse2 -LPF_16_VH %1, %2, %3, ssse3 -LPF_16_VH %1, %2, %3, avx +%macro LPF_16_VH_ALL_OPTS 4 +LPF_16_VH %1, %2, %3, %4, sse2 +LPF_16_VH %1, %2, %3, %4, ssse3 +LPF_16_VH %1, %2, %3, %4, avx %endmacro -LPF_16_VH_ALL_OPTS 16, 512, 32 -LPF_16_VH_ALL_OPTS 44, 0, 0 -LPF_16_VH_ALL_OPTS 48, 256, 16 -LPF_16_VH_ALL_OPTS 84, 256, 16 -LPF_16_VH_ALL_OPTS 88, 256, 16 +LPF_16_VH_ALL_OPTS 16, 512, 256, 32 +LPF_16_VH_ALL_OPTS 44, 0, 128, 0 +LPF_16_VH_ALL_OPTS 48, 256, 128, 16 +LPF_16_VH_ALL_OPTS 84, 256, 128, 16 +LPF_16_VH_ALL_OPTS 88, 256, 128, 16 From 8915320db94c9b3ceb97d6ad92addda690af8c18 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 26 Dec 2014 15:15:50 -0500 Subject: [PATCH 0270/3374] vp9lpf/x86: make filter_48/84/88_h work on 32-bit. Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9dsp_init.c | 12 ++----- libavcodec/x86/vp9lpf.asm | 62 ++++++++++++++++++++++++++---------- 2 files changed, 48 insertions(+), 26 deletions(-) diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c index 6438644867a0b..76ea48f457e42 100644 --- a/libavcodec/x86/vp9dsp_init.c +++ b/libavcodec/x86/vp9dsp_init.c @@ -285,17 +285,11 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_##opt; \ dsp->loop_filter_mix2[0][0][0] = ff_vp9_loop_filter_h_44_16_##opt; \ dsp->loop_filter_mix2[0][0][1] = ff_vp9_loop_filter_v_44_16_##opt; \ - if (ARCH_X86_64) { \ - dsp->loop_filter_mix2[0][1][0] = ff_vp9_loop_filter_h_48_16_##opt; \ - } \ + dsp->loop_filter_mix2[0][1][0] = ff_vp9_loop_filter_h_48_16_##opt; \ dsp->loop_filter_mix2[0][1][1] = ff_vp9_loop_filter_v_48_16_##opt; \ - if (ARCH_X86_64) { \ - dsp->loop_filter_mix2[1][0][0] = ff_vp9_loop_filter_h_84_16_##opt; \ - } \ + dsp->loop_filter_mix2[1][0][0] = ff_vp9_loop_filter_h_84_16_##opt; \ dsp->loop_filter_mix2[1][0][1] = ff_vp9_loop_filter_v_84_16_##opt; \ - if (ARCH_X86_64) { \ - dsp->loop_filter_mix2[1][1][0] = ff_vp9_loop_filter_h_88_16_##opt; \ - } \ + dsp->loop_filter_mix2[1][1][0] = ff_vp9_loop_filter_h_88_16_##opt; \ dsp->loop_filter_mix2[1][1][1] = ff_vp9_loop_filter_v_88_16_##opt; \ } while (0) diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index 881bdab8a8ed4..c20eeb89bfd2c 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -939,9 +939,12 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4 + %5, dst, stride, mstride, mova m3, [P0] mova m4, [Q0] mova m5, [Q1] +%if ARCH_X86_64 mova m6, [Q2] +%endif mova m7, [Q3] DEFINE_REAL_P7_TO_Q7 +%if ARCH_X86_64 SBUTTERFLY bw, 0, 1, 8 SBUTTERFLY bw, 2, 3, 8 SBUTTERFLY bw, 4, 5, 8 @@ -954,22 +957,47 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4 + %5, dst, stride, mstride, SBUTTERFLY dq, 1, 5, 8 SBUTTERFLY dq, 2, 6, 8 SBUTTERFLY dq, 3, 7, 8 - movh [P7], m0 - movhps [P6], m0 - movh [Q0], m1 - movhps [Q1], m1 - movh [P3], m2 - movhps [P2], m2 - movh [Q4], m3 - movhps [Q5], m3 - movh [P5], m4 - movhps [P4], m4 - movh [Q2], m5 - movhps [Q3], m5 - movh [P1], m6 - movhps [P0], m6 - movh [Q6], m7 - movhps [Q7], m7 +%else + SBUTTERFLY bw, 0, 1, 6 + mova [rsp+64], m1 + mova m6, [rsp+96] + SBUTTERFLY bw, 2, 3, 1 + SBUTTERFLY bw, 4, 5, 1 + SBUTTERFLY bw, 6, 7, 1 + SBUTTERFLY wd, 0, 2, 1 + mova [rsp+96], m2 + mova m1, [rsp+64] + SBUTTERFLY wd, 1, 3, 2 + SBUTTERFLY wd, 4, 6, 2 + SBUTTERFLY wd, 5, 7, 2 + SBUTTERFLY dq, 0, 4, 2 + SBUTTERFLY dq, 1, 5, 2 + movh [Q0], m1 + movhps [Q1], m1 + mova m2, [rsp+96] + SBUTTERFLY dq, 2, 6, 1 + SBUTTERFLY dq, 3, 7, 1 +%endif + SWAP 3, 6 + SWAP 1, 4 + movh [P7], m0 + movhps [P6], m0 + movh [P5], m1 + movhps [P4], m1 + movh [P3], m2 + movhps [P2], m2 + movh [P1], m3 + movhps [P0], m3 +%if ARCH_X86_64 + movh [Q0], m4 + movhps [Q1], m4 +%endif + movh [Q2], m5 + movhps [Q3], m5 + movh [Q4], m6 + movhps [Q5], m6 + movh [Q6], m7 + movhps [Q7], m7 %endif %endif @@ -979,7 +1007,7 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4 + %5, dst, stride, mstride, %macro LPF_16_VH 5 INIT_XMM %5 LOOPFILTER v, %1, %2, 0, %4 -%if ARCH_X86_64 || %1 == 44 +%if ARCH_X86_64 || %1 != 16 LOOPFILTER h, %1, %2, %3, %4 %endif %endmacro From 715f139c9bd407ef7f4d1f564ad683140ec61e6d Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 26 Dec 2014 17:50:38 -0500 Subject: [PATCH 0271/3374] vp9lpf/x86: make filter_16_h work on 32-bit. Signed-off-by: Anton Khirnov --- libavcodec/x86/vp9dsp_init.c | 4 +- libavcodec/x86/vp9lpf.asm | 191 ++++++++++++++++++++++++++++------- 2 files changed, 154 insertions(+), 41 deletions(-) diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c index 76ea48f457e42..3b9e1bb0ca421 100644 --- a/libavcodec/x86/vp9dsp_init.c +++ b/libavcodec/x86/vp9dsp_init.c @@ -279,9 +279,7 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) init_subpel2(4, idx, 4, type, opt) #define init_lpf(opt) do { \ - if (ARCH_X86_64) { \ - dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_##opt; \ - } \ + dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_##opt; \ dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_##opt; \ dsp->loop_filter_mix2[0][0][0] = ff_vp9_loop_filter_h_44_16_##opt; \ dsp->loop_filter_mix2[0][0][1] = ff_vp9_loop_filter_v_44_16_##opt; \ diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index c20eeb89bfd2c..54f20fe0903f9 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -291,6 +291,30 @@ SECTION .text SWAP %12, %14 %endmacro +%macro TRANSPOSE8x8B 13 + SBUTTERFLY bw, %1, %2, %7 + movdq%10 m%7, %9 + movdqa %11, m%2 + SBUTTERFLY bw, %3, %4, %2 + SBUTTERFLY bw, %5, %6, %2 + SBUTTERFLY bw, %7, %8, %2 + SBUTTERFLY wd, %1, %3, %2 + movdqa m%2, %11 + movdqa %11, m%3 + SBUTTERFLY wd, %2, %4, %3 + SBUTTERFLY wd, %5, %7, %3 + SBUTTERFLY wd, %6, %8, %3 + SBUTTERFLY dq, %1, %5, %3 + SBUTTERFLY dq, %2, %6, %3 + movdqa m%3, %11 + movh %12, m%2 + movhps %13, m%2 + SBUTTERFLY dq, %3, %7, %2 + SBUTTERFLY dq, %4, %8, %2 + SWAP %2, %5 + SWAP %4, %7 +%endmacro + %macro DEFINE_REAL_P7_TO_Q7 0-1 0 %define P7 dstq + 4*mstrideq + %1 %define P6 dstq + mstride3q + %1 @@ -310,6 +334,25 @@ SECTION .text %define Q7 dst2q + stride3q + %1 %endmacro +%macro DEFINE_TRANSPOSED_P7_TO_Q7 0-1 0 +%define P3 rsp + 0 + %1 +%define P2 rsp + 16 + %1 +%define P1 rsp + 32 + %1 +%define P0 rsp + 48 + %1 +%define Q0 rsp + 64 + %1 +%define Q1 rsp + 80 + %1 +%define Q2 rsp + 96 + %1 +%define Q3 rsp + 112 + %1 +%define P7 rsp + 128 + %1 +%define P6 rsp + 144 + %1 +%define P5 rsp + 160 + %1 +%define P4 rsp + 176 + %1 +%define Q4 rsp + 192 + %1 +%define Q5 rsp + 208 + %1 +%define Q6 rsp + 224 + %1 +%define Q7 rsp + 240 + %1 +%endmacro + ; ..............AB -> AAAAAAAABBBBBBBB %macro SPLATB_MIX 1-2 [mask_mix] %if cpuflag(ssse3) @@ -364,7 +407,9 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4 + %5, dst, stride, mstride, movx m3, [P4] movx m4, [P3] movx m5, [P2] +%if ARCH_X86_64 || %2 != 16 movx m6, [P1] +%endif movx m7, [P0] %if ARCH_X86_64 movx m8, [Q0] @@ -375,21 +420,14 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4 + %5, dst, stride, mstride, movx m13, [Q5] movx m14, [Q6] movx m15, [Q7] + DEFINE_TRANSPOSED_P7_TO_Q7 %if %2 == 16 TRANSPOSE16x16B 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, [rsp] -%define P7 rsp + 128 -%define P6 rsp + 144 -%define P5 rsp + 160 -%define P4 rsp + 176 -%define Q4 rsp + 192 -%define Q5 rsp + 208 -%define Q6 rsp + 224 -%define Q7 rsp + 240 mova [P7], m0 mova [P6], m1 mova [P5], m2 mova [P4], m3 -%else +%else ; %2 == 44/48/84/88 ; 8x16 transpose punpcklbw m0, m1 punpcklbw m2, m3 @@ -407,8 +445,65 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4 + %5, dst, stride, mstride, SWAP 10, 9 SWAP 12, 10 SWAP 14, 11 -%endif +%endif ; %2 + mova [P3], m4 + mova [P2], m5 + mova [P1], m6 + mova [P0], m7 + mova [Q0], m8 + mova [Q1], m9 + mova [Q2], m10 + mova [Q3], m11 +%if %2 == 16 + mova [Q4], m12 + mova [Q5], m13 + mova [Q6], m14 + mova [Q7], m15 +%endif ; %2 %else ; x86-32 +%if %2 == 16 + TRANSPOSE8x8B 0, 1, 2, 3, 4, 5, 6, 7, [P1], u, [rsp+%3+%4], [rsp+64], [rsp+80] + DEFINE_TRANSPOSED_P7_TO_Q7 + movh [P7], m0 + movh [P5], m1 + movh [P3], m2 + movh [P1], m3 + movh [Q2], m5 + movh [Q4], m6 + movh [Q6], m7 + movhps [P6], m0 + movhps [P4], m1 + movhps [P2], m2 + movhps [P0], m3 + movhps [Q3], m5 + movhps [Q5], m6 + movhps [Q7], m7 + DEFINE_REAL_P7_TO_Q7 + movx m0, [Q0] + movx m1, [Q1] + movx m2, [Q2] + movx m3, [Q3] + movx m4, [Q4] + movx m5, [Q5] + movx m7, [Q7] + TRANSPOSE8x8B 0, 1, 2, 3, 4, 5, 6, 7, [Q6], u, [rsp+%3+%4], [rsp+72], [rsp+88] + DEFINE_TRANSPOSED_P7_TO_Q7 8 + movh [P7], m0 + movh [P5], m1 + movh [P3], m2 + movh [P1], m3 + movh [Q2], m5 + movh [Q4], m6 + movh [Q6], m7 + movhps [P6], m0 + movhps [P4], m1 + movhps [P2], m2 + movhps [P0], m3 + movhps [Q3], m5 + movhps [Q5], m6 + movhps [Q7], m7 + DEFINE_TRANSPOSED_P7_TO_Q7 +%else ; %2 == 44/48/84/88 punpcklbw m0, m1 punpcklbw m2, m3 punpcklbw m4, m5 @@ -426,31 +521,7 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4 + %5, dst, stride, mstride, movx m3, [Q6] movx m7, [Q7] punpcklbw m3, m7 -%endif -%define P3 rsp + 0 -%define P2 rsp + 16 -%define P1 rsp + 32 -%define P0 rsp + 48 -%define Q0 rsp + 64 -%define Q1 rsp + 80 -%define Q2 rsp + 96 -%define Q3 rsp + 112 -%if ARCH_X86_64 - mova [P3], m4 - mova [P2], m5 - mova [P1], m6 - mova [P0], m7 - mova [Q0], m8 - mova [Q1], m9 - mova [Q2], m10 - mova [Q3], m11 -%if %2 == 16 - mova [Q4], m12 - mova [Q5], m13 - mova [Q6], m14 - mova [Q7], m15 -%endif -%else ; x86-32 + DEFINE_TRANSPOSED_P7_TO_Q7 TRANSPOSE8x8W 0, 2, 4, 6, 1, 5, 7, 3, [rsp], [Q0], 1 mova [P3], m0 mova [P2], m2 @@ -459,7 +530,8 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4 + %5, dst, stride, mstride, mova [Q1], m5 mova [Q2], m7 mova [Q3], m3 -%endif +%endif ; %2 +%endif ; x86-32/64 %endif ; %1 == h ; calc fm mask @@ -864,8 +936,11 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4 + %5, dst, stride, mstride, mova m3, [P4] mova m4, [P3] mova m5, [P2] +%if ARCH_X86_64 mova m6, [P1] +%endif mova m7, [P0] +%if ARCH_X86_64 mova m8, [Q0] mova m9, [Q1] mova m10, [Q2] @@ -892,6 +967,48 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4 + %5, dst, stride, mstride, movu [Q5], m13 movu [Q6], m14 movu [Q7], m15 +%else + DEFINE_REAL_P7_TO_Q7 + TRANSPOSE8x8B 0, 1, 2, 3, 4, 5, 6, 7, [rsp+32], a, [rsp+%3+%4], [Q0], [Q1] + movh [P7], m0 + movh [P5], m1 + movh [P3], m2 + movh [P1], m3 + movh [Q2], m5 + movh [Q4], m6 + movh [Q6], m7 + movhps [P6], m0 + movhps [P4], m1 + movhps [P2], m2 + movhps [P0], m3 + movhps [Q3], m5 + movhps [Q5], m6 + movhps [Q7], m7 + DEFINE_TRANSPOSED_P7_TO_Q7 + mova m0, [Q0] + mova m1, [Q1] + mova m2, [Q2] + mova m3, [Q3] + mova m4, [Q4] + mova m5, [Q5] + mova m7, [Q7] + DEFINE_REAL_P7_TO_Q7 8 + TRANSPOSE8x8B 0, 1, 2, 3, 4, 5, 6, 7, [rsp+224], a, [rsp+%3+%4], [Q0], [Q1] + movh [P7], m0 + movh [P5], m1 + movh [P3], m2 + movh [P1], m3 + movh [Q2], m5 + movh [Q4], m6 + movh [Q6], m7 + movhps [P6], m0 + movhps [P4], m1 + movhps [P2], m2 + movhps [P0], m3 + movhps [Q3], m5 + movhps [Q5], m6 + movhps [Q7], m7 +%endif %elif %2 == 44 SWAP 0, 1 ; m0 = p1 SWAP 1, 7 ; m1 = p0 @@ -1007,9 +1124,7 @@ cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4 + %5, dst, stride, mstride, %macro LPF_16_VH 5 INIT_XMM %5 LOOPFILTER v, %1, %2, 0, %4 -%if ARCH_X86_64 || %1 != 16 LOOPFILTER h, %1, %2, %3, %4 -%endif %endmacro %macro LPF_16_VH_ALL_OPTS 4 From be630b1e08ebe8f766b1798accd6b8e5e096f5aa Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Wed, 5 Oct 2016 12:52:00 +0200 Subject: [PATCH 0272/3374] d3d11va: Use the proper decoding slice index The decoding buffer index expected by D3D11VA is the one from the ID3D11Texture2D not the one from the ID3D11VideoDecoderOutputView array in AVD3D11VAContext. Otherwise, when providing decoder slices that do not start from 0, pictures appear in bogus order. For an invalid index crashes and image corruption can occur. Signed-off-by: Diego Biurrun --- libavcodec/dxva2.c | 11 ++++++++++- libavcodec/dxva2_internal.h | 3 --- libavcodec/version.h | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c index 91570941c376a..eeac474eaec32 100644 --- a/libavcodec/dxva2.c +++ b/libavcodec/dxva2.c @@ -42,8 +42,17 @@ unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx, unsigned i; for (i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++) - if (DXVA_CONTEXT_SURFACE(avctx, ctx, i) == surface) +#if CONFIG_D3D11VA + if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD && ctx->d3d11va.surface[i] == surface) { + D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc; + ID3D11VideoDecoderOutputView_GetDesc(ctx->d3d11va.surface[i], &viewDesc); + return viewDesc.Texture2D.ArraySlice; + } +#endif +#if CONFIG_DXVA2 + if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD && ctx->dxva2.surface[i] == surface) return i; +#endif assert(0); return 0; diff --git a/libavcodec/dxva2_internal.h b/libavcodec/dxva2_internal.h index 30aec8b93c7a6..f0fe3d61e3be4 100644 --- a/libavcodec/dxva2_internal.h +++ b/libavcodec/dxva2_internal.h @@ -69,7 +69,6 @@ typedef union { #if CONFIG_D3D11VA && CONFIG_DXVA2 #define DXVA_CONTEXT_WORKAROUND(avctx, ctx) (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.workaround : ctx->dxva2.workaround) #define DXVA_CONTEXT_COUNT(avctx, ctx) (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.surface_count : ctx->dxva2.surface_count) -#define DXVA_CONTEXT_SURFACE(avctx, ctx, i) (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.surface[i] : ctx->dxva2.surface[i]) #define DXVA_CONTEXT_DECODER(avctx, ctx) (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.decoder : ctx->dxva2.decoder) #define DXVA_CONTEXT_REPORT_ID(avctx, ctx) (*(avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? &ctx->d3d11va.report_id : &ctx->dxva2.report_id)) #define DXVA_CONTEXT_CFG(avctx, ctx) (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.cfg : ctx->dxva2.cfg) @@ -79,7 +78,6 @@ typedef union { #elif CONFIG_DXVA2 #define DXVA_CONTEXT_WORKAROUND(avctx, ctx) (ctx->dxva2.workaround) #define DXVA_CONTEXT_COUNT(avctx, ctx) (ctx->dxva2.surface_count) -#define DXVA_CONTEXT_SURFACE(avctx, ctx, i) (ctx->dxva2.surface[i]) #define DXVA_CONTEXT_DECODER(avctx, ctx) (ctx->dxva2.decoder) #define DXVA_CONTEXT_REPORT_ID(avctx, ctx) (*(&ctx->dxva2.report_id)) #define DXVA_CONTEXT_CFG(avctx, ctx) (ctx->dxva2.cfg) @@ -89,7 +87,6 @@ typedef union { #elif CONFIG_D3D11VA #define DXVA_CONTEXT_WORKAROUND(avctx, ctx) (ctx->d3d11va.workaround) #define DXVA_CONTEXT_COUNT(avctx, ctx) (ctx->d3d11va.surface_count) -#define DXVA_CONTEXT_SURFACE(avctx, ctx, i) (ctx->d3d11va.surface[i]) #define DXVA_CONTEXT_DECODER(avctx, ctx) (ctx->d3d11va.decoder) #define DXVA_CONTEXT_REPORT_ID(avctx, ctx) (*(&ctx->d3d11va.report_id)) #define DXVA_CONTEXT_CFG(avctx, ctx) (ctx->d3d11va.cfg) diff --git a/libavcodec/version.h b/libavcodec/version.h index 71ec9cea8bf47..3f217118dd305 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 27 -#define LIBAVCODEC_VERSION_MICRO 1 +#define LIBAVCODEC_VERSION_MICRO 2 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From d9dccc03890a976dba59d66ed3b5aceeaa33d14c Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 5 Oct 2016 11:39:16 +0200 Subject: [PATCH 0273/3374] hevc: x86: Refactor IDCT macro declarations --- libavcodec/x86/hevc_idct.asm | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/libavcodec/x86/hevc_idct.asm b/libavcodec/x86/hevc_idct.asm index d662aa90ba71f..71e4607dd7c29 100644 --- a/libavcodec/x86/hevc_idct.asm +++ b/libavcodec/x86/hevc_idct.asm @@ -74,34 +74,22 @@ cglobal hevc_idct_%1x%1_dc_%2, 1, 2, 1, coeff, tmp RET %endmacro -; 8-bit +%macro INIT_IDCT_DC 1 INIT_MMX mmxext -IDCT_DC_NL 4, 8 -IDCT_DC 8, 2, 8 +IDCT_DC_NL 4, %1 +IDCT_DC 8, 2, %1 INIT_XMM sse2 -IDCT_DC_NL 8, 8 -IDCT_DC 16, 4, 8 -IDCT_DC 32, 16, 8 +IDCT_DC_NL 8, %1 +IDCT_DC 16, 4, %1 +IDCT_DC 32, 16, %1 %if HAVE_AVX2_EXTERNAL INIT_YMM avx2 -IDCT_DC 16, 2, 8 -IDCT_DC 32, 8, 8 +IDCT_DC 16, 2, %1 +IDCT_DC 32, 8, %1 %endif ;HAVE_AVX2_EXTERNAL +%endmacro -; 10-bit -INIT_MMX mmxext -IDCT_DC_NL 4, 10 -IDCT_DC 8, 2, 10 - -INIT_XMM sse2 -IDCT_DC_NL 8, 10 -IDCT_DC 16, 4, 10 -IDCT_DC 32, 16, 10 - -%if HAVE_AVX2_EXTERNAL -INIT_YMM avx2 -IDCT_DC 16, 2, 10 -IDCT_DC 32, 8, 10 -%endif ;HAVE_AVX2_EXTERNAL +INIT_IDCT_DC 8 +INIT_IDCT_DC 10 From 20abcaa273a6e77d0a2e1a98c643c73562c6f8f2 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 5 Oct 2016 08:51:03 +0200 Subject: [PATCH 0274/3374] configure: #include stdint.h as part of libxavs test Unfortunately the xavs.h API header is not self-sufficient and relies on manual stdint.h inclusion by its users. --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index e87366ed86b8e..ac20cfa986e4a 100755 --- a/configure +++ b/configure @@ -4673,7 +4673,7 @@ enabled libx264 && require_pkg_config x264 "stdint.h x264.h" x264_enco enabled libx265 && require_pkg_config x265 x265.h x265_api_get && { check_cpp_condition x265.h "X265_BUILD >= 57" || die "ERROR: libx265 version must be >= 57."; } -enabled libxavs && require libxavs xavs.h xavs_encoder_encode -lxavs +enabled libxavs && require libxavs "stdint.h xavs.h" xavs_encoder_encode -lxavs enabled libxvid && require libxvid xvid.h xvid_global -lxvidcore enabled mmal && { check_lib interface/mmal/mmal.h mmal_port_connect -lmmal_core -lmmal_util -lmmal_vc_client -lbcm_host || { ! enabled cross_compile && { From 5801f9ed245ca5ebb57b0b5183de7a24aaece133 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 9 Sep 2016 01:27:41 +0200 Subject: [PATCH 0275/3374] h264_intrapred: x86: Update comments left behind in 95c89da36ebeeb96b7146c0d70f46c582397da7f --- libavcodec/x86/h264_intrapred.asm | 65 +++++++++++---------- libavcodec/x86/h264_intrapred_10bit.asm | 77 ++++++++++++++----------- 2 files changed, 76 insertions(+), 66 deletions(-) diff --git a/libavcodec/x86/h264_intrapred.asm b/libavcodec/x86/h264_intrapred.asm index df657a443c12d..1ea97fa1cac2f 100644 --- a/libavcodec/x86/h264_intrapred.asm +++ b/libavcodec/x86/h264_intrapred.asm @@ -49,7 +49,7 @@ cextern pw_17 cextern pw_32 ;----------------------------------------------------------------------------- -; void ff_pred16x16_vertical_8(uint8_t *src, int stride) +; void ff_pred16x16_vertical_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmx @@ -85,7 +85,7 @@ cglobal pred16x16_vertical_8, 2,3 REP_RET ;----------------------------------------------------------------------------- -; void ff_pred16x16_horizontal_8(uint8_t *src, int stride) +; void ff_pred16x16_horizontal_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_H 0 @@ -126,7 +126,7 @@ INIT_XMM ssse3 PRED16x16_H ;----------------------------------------------------------------------------- -; void ff_pred16x16_dc_8(uint8_t *src, int stride) +; void ff_pred16x16_dc_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_DC 0 @@ -188,7 +188,7 @@ INIT_XMM ssse3 PRED16x16_DC ;----------------------------------------------------------------------------- -; void ff_pred16x16_tm_vp8_8(uint8_t *src, int stride) +; void ff_pred16x16_tm_vp8_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_TM 0 @@ -269,7 +269,7 @@ cglobal pred16x16_tm_vp8_8, 2,6,6 REP_RET ;----------------------------------------------------------------------------- -; void ff_pred16x16_plane_*_8(uint8_t *src, int stride) +; void ff_pred16x16_plane_*_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro H264_PRED16x16_PLANE 1 @@ -550,7 +550,7 @@ H264_PRED16x16_PLANE rv40 H264_PRED16x16_PLANE svq3 ;----------------------------------------------------------------------------- -; void ff_pred8x8_plane_8(uint8_t *src, int stride) +; void ff_pred8x8_plane_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro H264_PRED8x8_PLANE 0 @@ -724,7 +724,7 @@ INIT_XMM ssse3 H264_PRED8x8_PLANE ;----------------------------------------------------------------------------- -; void ff_pred8x8_vertical_8(uint8_t *src, int stride) +; void ff_pred8x8_vertical_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmx @@ -741,7 +741,7 @@ cglobal pred8x8_vertical_8, 2,2 RET ;----------------------------------------------------------------------------- -; void ff_pred8x8_horizontal_8(uint8_t *src, int stride) +; void ff_pred8x8_horizontal_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8_H 0 @@ -769,7 +769,7 @@ INIT_MMX ssse3 PRED8x8_H ;----------------------------------------------------------------------------- -; void ff_pred8x8_top_dc_8_mmxext(uint8_t *src, int stride) +; void ff_pred8x8_top_dc_8_mmxext(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext cglobal pred8x8_top_dc_8, 2,5 @@ -803,7 +803,7 @@ cglobal pred8x8_top_dc_8, 2,5 RET ;----------------------------------------------------------------------------- -; void ff_pred8x8_dc_8_mmxext(uint8_t *src, int stride) +; void ff_pred8x8_dc_8_mmxext(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -864,7 +864,7 @@ cglobal pred8x8_dc_8, 2,5 RET ;----------------------------------------------------------------------------- -; void ff_pred8x8_dc_rv40_8(uint8_t *src, int stride) +; void ff_pred8x8_dc_rv40_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -901,7 +901,7 @@ cglobal pred8x8_dc_rv40_8, 2,7 REP_RET ;----------------------------------------------------------------------------- -; void ff_pred8x8_tm_vp8_8(uint8_t *src, int stride) +; void ff_pred8x8_tm_vp8_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8_TM 0 @@ -1014,7 +1014,7 @@ cglobal pred8x8_tm_vp8_8, 2,3,6 ;----------------------------------------------------------------------------- ; void ff_pred8x8l_top_dc_8(uint8_t *src, int has_topleft, int has_topright, -; int stride) +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_TOP_DC 0 cglobal pred8x8l_top_dc_8, 4,4 @@ -1070,7 +1070,7 @@ PRED8x8L_TOP_DC ;----------------------------------------------------------------------------- ; void ff_pred8x8l_dc_8(uint8_t *src, int has_topleft, int has_topright, -; int stride) +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_DC 0 @@ -1174,7 +1174,7 @@ PRED8x8L_DC ;----------------------------------------------------------------------------- ; void ff_pred8x8l_horizontal_8(uint8_t *src, int has_topleft, -; int has_topright, int stride) +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_HORIZONTAL 0 @@ -1246,7 +1246,7 @@ PRED8x8L_HORIZONTAL ;----------------------------------------------------------------------------- ; void ff_pred8x8l_vertical_8(uint8_t *src, int has_topleft, int has_topright, -; int stride) +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_VERTICAL 0 @@ -1297,7 +1297,7 @@ PRED8x8L_VERTICAL ;----------------------------------------------------------------------------- ; void ff_pred8x8l_down_left_8(uint8_t *src, int has_topleft, -; int has_topright, int stride) +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -1498,7 +1498,7 @@ PRED8x8L_DOWN_LEFT ;----------------------------------------------------------------------------- ; void ff_pred8x8l_down_right_8_mmxext(uint8_t *src, int has_topleft, -; int has_topright, int stride) +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -1750,7 +1750,7 @@ PRED8x8L_DOWN_RIGHT ;----------------------------------------------------------------------------- ; void ff_pred8x8l_vertical_right_8(uint8_t *src, int has_topleft, -; int has_topright, int stride) +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -1978,7 +1978,7 @@ PRED8x8L_VERTICAL_RIGHT ;----------------------------------------------------------------------------- ; void ff_pred8x8l_vertical_left_8(uint8_t *src, int has_topleft, -; int has_topright, int stride) +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_VERTICAL_LEFT 0 @@ -2068,7 +2068,7 @@ PRED8x8L_VERTICAL_LEFT ;----------------------------------------------------------------------------- ; void ff_pred8x8l_horizontal_up_8(uint8_t *src, int has_topleft, -; int has_topright, int stride) +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_HORIZONTAL_UP 0 @@ -2156,7 +2156,7 @@ PRED8x8L_HORIZONTAL_UP ;----------------------------------------------------------------------------- ; void ff_pred8x8l_horizontal_down_8(uint8_t *src, int has_topleft, -; int has_topright, int stride) +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -2404,7 +2404,8 @@ INIT_MMX ssse3 PRED8x8L_HORIZONTAL_DOWN ;------------------------------------------------------------------------------- -; void ff_pred4x4_dc_8_mmxext(uint8_t *src, const uint8_t *topright, int stride) +; void ff_pred4x4_dc_8_mmxext(uint8_t *src, const uint8_t *topright, +; ptrdiff_t stride) ;------------------------------------------------------------------------------- INIT_MMX mmxext @@ -2435,7 +2436,7 @@ cglobal pred4x4_dc_8, 3,5 ;----------------------------------------------------------------------------- ; void ff_pred4x4_tm_vp8_8_mmxext(uint8_t *src, const uint8_t *topright, -; int stride) +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED4x4_TM 0 @@ -2517,7 +2518,7 @@ cglobal pred4x4_tm_vp8_8, 3,3 ;----------------------------------------------------------------------------- ; void ff_pred4x4_vertical_vp8_8_mmxext(uint8_t *src, const uint8_t *topright, -; int stride) +; ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -2538,7 +2539,7 @@ cglobal pred4x4_vertical_vp8_8, 3,3 ;----------------------------------------------------------------------------- ; void ff_pred4x4_down_left_8_mmxext(uint8_t *src, const uint8_t *topright, -; int stride) +; ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext cglobal pred4x4_down_left_8, 3,3 @@ -2565,7 +2566,7 @@ cglobal pred4x4_down_left_8, 3,3 ;------------------------------------------------------------------------------ ; void ff_pred4x4_vertical_left_8_mmxext(uint8_t *src, const uint8_t *topright, -; int stride) +; ptrdiff_t stride) ;------------------------------------------------------------------------------ INIT_MMX mmxext @@ -2591,7 +2592,7 @@ cglobal pred4x4_vertical_left_8, 3,3 ;------------------------------------------------------------------------------ ; void ff_pred4x4_horizontal_up_8_mmxext(uint8_t *src, const uint8_t *topright, -; int stride) +; ptrdiff_t stride) ;------------------------------------------------------------------------------ INIT_MMX mmxext @@ -2625,7 +2626,8 @@ cglobal pred4x4_horizontal_up_8, 3,3 ;------------------------------------------------------------------------------ ; void ff_pred4x4_horizontal_down_8_mmxext(uint8_t *src, -; const uint8_t *topright, int stride) +; const uint8_t *topright, +; ptrdiff_t stride) ;------------------------------------------------------------------------------ INIT_MMX mmxext @@ -2661,7 +2663,8 @@ cglobal pred4x4_horizontal_down_8, 3,3 ;----------------------------------------------------------------------------- ; void ff_pred4x4_vertical_right_8_mmxext(uint8_t *src, -; const uint8_t *topright, int stride) +; const uint8_t *topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -2692,7 +2695,7 @@ cglobal pred4x4_vertical_right_8, 3,3 ;----------------------------------------------------------------------------- ; void ff_pred4x4_down_right_8_mmxext(uint8_t *src, const uint8_t *topright, -; int stride) +; ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext diff --git a/libavcodec/x86/h264_intrapred_10bit.asm b/libavcodec/x86/h264_intrapred_10bit.asm index ecbe57b353875..7ba9828e17ea9 100644 --- a/libavcodec/x86/h264_intrapred_10bit.asm +++ b/libavcodec/x86/h264_intrapred_10bit.asm @@ -50,7 +50,8 @@ SECTION .text %endmacro ;----------------------------------------------------------------------------- -; void ff_pred4x4_down_right(pixel *src, const pixel *topright, int stride) +; void ff_pred4x4_down_right_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED4x4_DR 0 cglobal pred4x4_down_right_10, 3, 3 @@ -86,7 +87,8 @@ INIT_XMM avx PRED4x4_DR ;------------------------------------------------------------------------------ -; void ff_pred4x4_vertical_right(pixel *src, const pixel *topright, int stride) +; void ff_pred4x4_vertical_right_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) ;------------------------------------------------------------------------------ %macro PRED4x4_VR 0 cglobal pred4x4_vertical_right_10, 3, 3, 6 @@ -123,7 +125,8 @@ INIT_XMM avx PRED4x4_VR ;------------------------------------------------------------------------------- -; void ff_pred4x4_horizontal_down(pixel *src, const pixel *topright, int stride) +; void ff_pred4x4_horizontal_down_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) ;------------------------------------------------------------------------------- %macro PRED4x4_HD 0 cglobal pred4x4_horizontal_down_10, 3, 3 @@ -163,7 +166,7 @@ INIT_XMM avx PRED4x4_HD ;----------------------------------------------------------------------------- -; void ff_pred4x4_dc(pixel *src, const pixel *topright, int stride) +; void ff_pred4x4_dc_10(pixel *src, const pixel *topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro HADDD 2 ; sum junk %if mmsize == 16 @@ -204,7 +207,8 @@ cglobal pred4x4_dc_10, 3, 3 RET ;----------------------------------------------------------------------------- -; void ff_pred4x4_down_left(pixel *src, const pixel *topright, int stride) +; void ff_pred4x4_down_left_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED4x4_DL 0 cglobal pred4x4_down_left_10, 3, 3 @@ -232,7 +236,8 @@ INIT_XMM avx PRED4x4_DL ;----------------------------------------------------------------------------- -; void ff_pred4x4_vertical_left(pixel *src, const pixel *topright, int stride) +; void ff_pred4x4_vertical_left_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED4x4_VL 0 cglobal pred4x4_vertical_left_10, 3, 3 @@ -259,7 +264,8 @@ INIT_XMM avx PRED4x4_VL ;----------------------------------------------------------------------------- -; void ff_pred4x4_horizontal_up(pixel *src, const pixel *topright, int stride) +; void ff_pred4x4_horizontal_up_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext cglobal pred4x4_horizontal_up_10, 3, 3 @@ -293,7 +299,7 @@ cglobal pred4x4_horizontal_up_10, 3, 3 ;----------------------------------------------------------------------------- -; void ff_pred8x8_vertical(pixel *src, int stride) +; void ff_pred8x8_vertical_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_XMM sse2 cglobal pred8x8_vertical_10, 2, 2 @@ -309,7 +315,7 @@ cglobal pred8x8_vertical_10, 2, 2 RET ;----------------------------------------------------------------------------- -; void ff_pred8x8_horizontal(pixel *src, int stride) +; void ff_pred8x8_horizontal_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_XMM sse2 cglobal pred8x8_horizontal_10, 2, 3 @@ -329,7 +335,7 @@ cglobal pred8x8_horizontal_10, 2, 3 REP_RET ;----------------------------------------------------------------------------- -; void ff_predict_8x8_dc(pixel *src, int stride) +; void ff_predict_8x8_dc_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro MOV8 2-3 ; sort of a hack, but it works @@ -416,7 +422,7 @@ INIT_XMM sse2 PRED8x8_DC pshuflw ;----------------------------------------------------------------------------- -; void ff_pred8x8_top_dc(pixel *src, int stride) +; void ff_pred8x8_top_dc_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_XMM sse2 cglobal pred8x8_top_dc_10, 2, 4 @@ -443,7 +449,7 @@ cglobal pred8x8_top_dc_10, 2, 4 RET ;----------------------------------------------------------------------------- -; void ff_pred8x8_plane(pixel *src, int stride) +; void ff_pred8x8_plane_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_XMM sse2 cglobal pred8x8_plane_10, 2, 7, 7 @@ -506,8 +512,8 @@ cglobal pred8x8_plane_10, 2, 7, 7 ;----------------------------------------------------------------------------- -; void ff_pred8x8l_128_dc(pixel *src, int has_topleft, int has_topright, -; int stride) +; void ff_pred8x8l_128_dc_10(pixel *src, int has_topleft, int has_topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_128_DC 0 cglobal pred8x8l_128_dc_10, 4, 4 @@ -531,8 +537,8 @@ INIT_XMM sse2 PRED8x8L_128_DC ;----------------------------------------------------------------------------- -; void ff_pred8x8l_top_dc(pixel *src, int has_topleft, int has_topright, -; int stride) +; void ff_pred8x8l_top_dc_10(pixel *src, int has_topleft, int has_topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_TOP_DC 0 cglobal pred8x8l_top_dc_10, 4, 4, 6 @@ -569,7 +575,8 @@ INIT_XMM avx PRED8x8L_TOP_DC ;------------------------------------------------------------------------------- -; void ff_pred8x8l_dc(pixel *src, int has_topleft, int has_topright, int stride) +; void ff_pred8x8l_dc_10(pixel *src, int has_topleft, int has_topright, +; ptrdiff_t stride) ;------------------------------------------------------------------------------- ;TODO: see if scalar is faster %macro PRED8x8L_DC 0 @@ -626,8 +633,8 @@ INIT_XMM avx PRED8x8L_DC ;----------------------------------------------------------------------------- -; void ff_pred8x8l_vertical(pixel *src, int has_topleft, int has_topright, -; int stride) +; void ff_pred8x8l_vertical_10(pixel *src, int has_topleft, int has_topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_VERTICAL 0 cglobal pred8x8l_vertical_10, 4, 4, 6 @@ -660,8 +667,8 @@ INIT_XMM avx PRED8x8L_VERTICAL ;----------------------------------------------------------------------------- -; void ff_pred8x8l_horizontal(uint8_t *src, int has_topleft, int has_topright, -; int stride) +; void ff_pred8x8l_horizontal_10(uint8_t *src, int has_topleft, +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_HORIZONTAL 0 cglobal pred8x8l_horizontal_10, 4, 4, 5 @@ -715,8 +722,8 @@ INIT_XMM avx PRED8x8L_HORIZONTAL ;----------------------------------------------------------------------------- -; void ff_pred8x8l_down_left(pixel *src, int has_topleft, int has_topright, -; int stride) +; void ff_pred8x8l_down_left_10(pixel *src, int has_topleft, int has_topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_DOWN_LEFT 0 cglobal pred8x8l_down_left_10, 4, 4, 7 @@ -782,8 +789,8 @@ INIT_XMM avx PRED8x8L_DOWN_LEFT ;----------------------------------------------------------------------------- -; void ff_pred8x8l_down_right(pixel *src, int has_topleft, int has_topright, -; int stride) +; void ff_pred8x8l_down_right_10(pixel *src, int has_topleft, +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_DOWN_RIGHT 0 ; standard forbids this when has_topleft is false @@ -855,8 +862,8 @@ INIT_XMM avx PRED8x8L_DOWN_RIGHT ;----------------------------------------------------------------------------- -; void ff_pred8x8l_vertical_right(pixel *src, int has_topleft, -; int has_topright, int stride) +; void ff_pred8x8l_vertical_right_10(pixel *src, int has_topleft, +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_VERTICAL_RIGHT 0 ; likewise with 8x8l_down_right @@ -924,8 +931,8 @@ INIT_XMM avx PRED8x8L_VERTICAL_RIGHT ;----------------------------------------------------------------------------- -; void ff_pred8x8l_horizontal_up(pixel *src, int has_topleft, -; int has_topright, int stride) +; void ff_pred8x8l_horizontal_up_10(pixel *src, int has_topleft, +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_HORIZONTAL_UP 0 cglobal pred8x8l_horizontal_up_10, 4, 4, 6 @@ -985,7 +992,7 @@ PRED8x8L_HORIZONTAL_UP ;----------------------------------------------------------------------------- -; void ff_pred16x16_vertical(pixel *src, int stride) +; void ff_pred16x16_vertical_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro MOV16 3-5 mova [%1+ 0], %2 @@ -1021,7 +1028,7 @@ INIT_XMM sse2 PRED16x16_VERTICAL ;----------------------------------------------------------------------------- -; void ff_pred16x16_horizontal(pixel *src, int stride) +; void ff_pred16x16_horizontal_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_HORIZONTAL 0 cglobal pred16x16_horizontal_10, 2, 3 @@ -1045,7 +1052,7 @@ INIT_XMM sse2 PRED16x16_HORIZONTAL ;----------------------------------------------------------------------------- -; void ff_pred16x16_dc(pixel *src, int stride) +; void ff_pred16x16_dc_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_DC 0 cglobal pred16x16_dc_10, 2, 6 @@ -1091,7 +1098,7 @@ INIT_XMM sse2 PRED16x16_DC ;----------------------------------------------------------------------------- -; void ff_pred16x16_top_dc(pixel *src, int stride) +; void ff_pred16x16_top_dc_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_TOP_DC 0 cglobal pred16x16_top_dc_10, 2, 3 @@ -1123,7 +1130,7 @@ INIT_XMM sse2 PRED16x16_TOP_DC ;----------------------------------------------------------------------------- -; void ff_pred16x16_left_dc(pixel *src, int stride) +; void ff_pred16x16_left_dc_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_LEFT_DC 0 cglobal pred16x16_left_dc_10, 2, 6 @@ -1160,7 +1167,7 @@ INIT_XMM sse2 PRED16x16_LEFT_DC ;----------------------------------------------------------------------------- -; void ff_pred16x16_128_dc(pixel *src, int stride) +; void ff_pred16x16_128_dc_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_128_DC 0 cglobal pred16x16_128_dc_10, 2,3 From e4128c08d786eb5513578e8c6063671ba03226ab Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 6 Oct 2016 15:24:04 +0200 Subject: [PATCH 0276/3374] Revert "hevc: x86: Refactor IDCT macro declarations" This reverts commit d9dccc03890a976dba59d66ed3b5aceeaa33d14c. There were outstanding objections to this commit. --- libavcodec/x86/hevc_idct.asm | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/libavcodec/x86/hevc_idct.asm b/libavcodec/x86/hevc_idct.asm index 71e4607dd7c29..d662aa90ba71f 100644 --- a/libavcodec/x86/hevc_idct.asm +++ b/libavcodec/x86/hevc_idct.asm @@ -74,22 +74,34 @@ cglobal hevc_idct_%1x%1_dc_%2, 1, 2, 1, coeff, tmp RET %endmacro -%macro INIT_IDCT_DC 1 +; 8-bit INIT_MMX mmxext -IDCT_DC_NL 4, %1 -IDCT_DC 8, 2, %1 +IDCT_DC_NL 4, 8 +IDCT_DC 8, 2, 8 INIT_XMM sse2 -IDCT_DC_NL 8, %1 -IDCT_DC 16, 4, %1 -IDCT_DC 32, 16, %1 +IDCT_DC_NL 8, 8 +IDCT_DC 16, 4, 8 +IDCT_DC 32, 16, 8 %if HAVE_AVX2_EXTERNAL INIT_YMM avx2 -IDCT_DC 16, 2, %1 -IDCT_DC 32, 8, %1 +IDCT_DC 16, 2, 8 +IDCT_DC 32, 8, 8 %endif ;HAVE_AVX2_EXTERNAL -%endmacro -INIT_IDCT_DC 8 -INIT_IDCT_DC 10 +; 10-bit +INIT_MMX mmxext +IDCT_DC_NL 4, 10 +IDCT_DC 8, 2, 10 + +INIT_XMM sse2 +IDCT_DC_NL 8, 10 +IDCT_DC 16, 4, 10 +IDCT_DC 32, 16, 10 + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +IDCT_DC 16, 2, 10 +IDCT_DC 32, 8, 10 +%endif ;HAVE_AVX2_EXTERNAL From da2848375a2e2121dad9f1e8cbd0ead4e3bf77d6 Mon Sep 17 00:00:00 2001 From: Yogender Gupta Date: Thu, 6 Oct 2016 09:10:25 +0000 Subject: [PATCH 0277/3374] nvenc: Force high_444 profile for 444 input Signed-off-by: Luca Barbato --- libavcodec/nvenc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 0b6e4cef8688b..9c35bd0d2586a 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -723,6 +723,11 @@ static int nvenc_setup_h264_config(AVCodecContext *avctx) break; } + if (ctx->data_pix_fmt == AV_PIX_FMT_YUV444P) { + cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_444_GUID; + avctx->profile = FF_PROFILE_H264_HIGH_444_PREDICTIVE; + } + h264->level = ctx->level; return 0; From cbd84b8a51aa656d71b7d6ed44bd89041ff081a8 Mon Sep 17 00:00:00 2001 From: Yogender Gupta Date: Thu, 6 Oct 2016 14:44:26 +0530 Subject: [PATCH 0278/3374] nvenc: Fix error log Signed-off-by: Luca Barbato --- libavcodec/nvenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 9c35bd0d2586a..d5bfd74e30dd6 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -928,7 +928,7 @@ static int nvenc_setup_encoder(AVCodecContext *avctx) ret = nv->nvEncInitializeEncoder(ctx->nvenc_ctx, &ctx->params); if (ret != NV_ENC_SUCCESS) - return nvenc_print_error(avctx, ret, "Cannot initialize the decoder"); + return nvenc_print_error(avctx, ret, "InitializeEncoder failed"); cpb_props = ff_add_cpb_side_data(avctx); if (!cpb_props) From 9b2ccafb480c94fd09cfb24306d5296dc013cf5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 30 Sep 2016 12:05:55 +0300 Subject: [PATCH 0279/3374] aarch64: Add missing sign extension in ff_h264_idct8_add_neon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/aarch64/h264idct_neon.S | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/aarch64/h264idct_neon.S b/libavcodec/aarch64/h264idct_neon.S index 5395e146ef081..ee2397727180b 100644 --- a/libavcodec/aarch64/h264idct_neon.S +++ b/libavcodec/aarch64/h264idct_neon.S @@ -264,6 +264,7 @@ endfunc function ff_h264_idct8_add_neon, export=1 movi v19.8H, #0 + sxtw x2, w2 ld1 {v24.8H, v25.8H}, [x1] st1 {v19.8H}, [x1], #16 st1 {v19.8H}, [x1], #16 From e3f941cb03b139b866a0ad6dc95fbe1b247d54af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sun, 18 Sep 2016 19:35:26 +0200 Subject: [PATCH 0280/3374] checkasm: add a test for HEVC IDCT Signed-off-by: Anton Khirnov --- tests/checkasm/hevc_idct.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/tests/checkasm/hevc_idct.c b/tests/checkasm/hevc_idct.c index 84760b9bfac85..dd4dc0d0646f7 100644 --- a/tests/checkasm/hevc_idct.c +++ b/tests/checkasm/hevc_idct.c @@ -35,6 +35,30 @@ } \ } while (0) +static void check_idct(HEVCDSPContext h, int bit_depth) +{ + int i; + LOCAL_ALIGNED(32, int16_t, coeffs0, [32 * 32]); + LOCAL_ALIGNED(32, int16_t, coeffs1, [32 * 32]); + + for (i = 2; i <= 5; i++) { + int block_size = 1 << i; + int size = block_size * block_size; + int col_limit = block_size; + declare_func(void, int16_t *coeffs, int col_limit); + + randomize_buffers(coeffs0, size); + memcpy(coeffs1, coeffs0, sizeof(*coeffs0) * size); + if (check_func(h.idct[i - 2], "hevc_idct_%dx%d_%d", block_size, block_size, bit_depth)) { + call_ref(coeffs0, col_limit); + call_new(coeffs1, col_limit); + if (memcmp(coeffs0, coeffs1, sizeof(*coeffs0) * size)) + fail(); + bench_new(coeffs1, col_limit); + } + } +} + static void check_idct_dc(HEVCDSPContext h, int bit_depth) { int i; @@ -49,7 +73,7 @@ static void check_idct_dc(HEVCDSPContext h, int bit_depth) randomize_buffers(coeffs0, size); memcpy(coeffs1, coeffs0, sizeof(*coeffs0) * size); - if (check_func(h.idct_dc[i - 2], "idct_%dx%d_dc_%d", block_size, block_size, bit_depth)) { + if (check_func(h.idct_dc[i - 2], "hevc_idct_%dx%d_dc_%d", block_size, block_size, bit_depth)) { call_ref(coeffs0); call_new(coeffs1); if (memcmp(coeffs0, coeffs1, sizeof(*coeffs0) * size)) @@ -70,4 +94,12 @@ void checkasm_check_hevc_idct(void) check_idct_dc(h, bit_depth); } report("idct_dc"); + + for (bit_depth = 8; bit_depth <= 10; bit_depth++) { + HEVCDSPContext h; + + ff_hevc_dsp_init(&h, bit_depth); + check_idct(h, bit_depth); + } + report("idct"); } From 112cee0241f5799edff0e4682b9e8639b046dc78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Mon, 10 Oct 2016 22:23:01 +0200 Subject: [PATCH 0281/3374] hevc: Add SSE2 and AVX IDCT Signed-off-by: Anton Khirnov --- libavcodec/x86/hevc_idct.asm | 787 +++++++++++++++++++++++++++++++++- libavcodec/x86/hevcdsp_init.c | 54 ++- 2 files changed, 811 insertions(+), 30 deletions(-) diff --git a/libavcodec/x86/hevc_idct.asm b/libavcodec/x86/hevc_idct.asm index d662aa90ba71f..f397cc1097b62 100644 --- a/libavcodec/x86/hevc_idct.asm +++ b/libavcodec/x86/hevc_idct.asm @@ -2,6 +2,7 @@ ;* SIMD-optimized IDCT functions for HEVC decoding ;* Copyright (c) 2014 Pierre-Edouard LEPERE ;* Copyright (c) 2014 James Almer +;* Copyright (c) 2016 Alexandra Hájková ;* ;* This file is part of Libav. ;* @@ -22,6 +23,217 @@ %include "libavutil/x86/x86util.asm" +SECTION_RODATA + +pd_64: times 4 dd 64 +pd_2048: times 4 dd 2048 +pd_512: times 4 dd 512 + +; 4x4 transform coeffs +cextern pw_64 +pw_64_m64: times 4 dw 64, -64 +pw_83_36: times 4 dw 83, 36 +pw_36_m83: times 4 dw 36, -83 + +; 8x8 transform coeffs +pw_89_75: times 4 dw 89, 75 +pw_50_18: times 4 dw 50, 18 + +pw_75_m18: times 4 dw 75, -18 +pw_m89_m50: times 4 dw -89, -50 + +pw_50_m89: times 4 dw 50, -89 +pw_18_75: times 4 dw 18, 75 + +pw_18_m50: times 4 dw 18, -50 +pw_75_m89: times 4 dw 75, -89 + +; 16x16 transformation coeffs +trans_coeffs16: times 4 dw 90, 87 +times 4 dw 80, 70 +times 4 dw 57, 43 +times 4 dw 25, 9 + +times 4 dw 87, 57 +times 4 dw 9, -43 +times 4 dw -80, -90 +times 4 dw -70, -25 + +times 4 dw 80, 9 +times 4 dw -70, -87 +times 4 dw -25, 57 +times 4 dw 90, 43 + +times 4 dw 70, -43 +times 4 dw -87, 9 +times 4 dw 90, 25 +times 4 dw -80, -57 + +times 4 dw 57, -80 +times 4 dw -25, 90 +times 4 dw -9, -87 +times 4 dw 43, 70 + +times 4 dw 43, -90 +times 4 dw 57, 25 +times 4 dw -87, 70 +times 4 dw 9, -80 + +times 4 dw 25, -70 +times 4 dw 90, -80 +times 4 dw 43, 9 +times 4 dw -57, 87 + +times 4 dw 9, -25 +times 4 dw 43, -57 +times 4 dw 70, -80 +times 4 dw 87, -90 + +; 32x32 transform coeffs +trans_coeff32: times 8 dw 90 +times 4 dw 88, 85 +times 4 dw 82, 78 +times 4 dw 73, 67 +times 4 dw 61, 54 +times 4 dw 46, 38 +times 4 dw 31, 22 +times 4 dw 13, 4 + +times 4 dw 90, 82 +times 4 dw 67, 46 +times 4 dw 22, -4 +times 4 dw -31, -54 +times 4 dw -73, -85 +times 4 dw -90, -88 +times 4 dw -78, -61 +times 4 dw -38, -13 + +times 4 dw 88, 67 +times 4 dw 31, -13 +times 4 dw -54, -82 +times 4 dw -90, -78 +times 4 dw -46, -4 +times 4 dw 38, 73 +times 4 dw 90, 85 +times 4 dw 61, 22 + +times 4 dw 85, 46 +times 4 dw -13, -67 +times 4 dw -90, -73 +times 4 dw -22, 38 +times 4 dw 82, 88 +times 4 dw 54, -4 +times 4 dw -61, -90 +times 4 dw -78, -31 + +times 4 dw 82, 22 +times 4 dw -54, -90 +times 4 dw -61, 13 +times 4 dw 78, 85 +times 4 dw 31, -46 +times 4 dw -90, -67 +times 4 dw 4, 73 +times 4 dw 88, 38 + +times 4 dw 78, -4 +times 4 dw -82, -73 +times 4 dw 13, 85 +times 4 dw 67, -22 +times 4 dw -88, -61 +times 4 dw 31, 90 +times 4 dw 54, -38 +times 4 dw -90, -46 + +times 4 dw 73, -31 +times 4 dw -90, -22 +times 4 dw 78, 67 +times 4 dw -38, -90 +times 4 dw -13, 82 +times 4 dw 61, -46 +times 4 dw -88, -4 +times 4 dw 85, 54 + +times 4 dw 67, -54 +times 4 dw -78, 38 +times 4 dw 85, -22 +times 4 dw -90, 4 +times 4 dw 90, 13 +times 4 dw -88, -31 +times 4 dw 82, 46 +times 4 dw -73, -61 + +times 4 dw 61, -73 +times 4 dw -46, 82 +times 4 dw 31, -88 +times 4 dw -13, 90 +times 4 dw -4, -90 +times 4 dw 22, 85 +times 4 dw -38, -78 +times 4 dw 54, 67 + +times 4 dw 54, -85 +times 4 dw -4, 88 +times 4 dw -46, -61 +times 4 dw 82, 13 +times 4 dw -90, 38 +times 4 dw 67, -78 +times 4 dw -22, 90 +times 4 dw -31, -73 + +times 4 dw 46, -90 +times 4 dw 38, 54 +times 4 dw -90, 31 +times 4 dw 61, -88 +times 4 dw 22, 67 +times 4 dw -85, 13 +times 4 dw 73, -82 +times 4 dw 4, 78 + +times 4 dw 38, -88 +times 4 dw 73, -4 +times 4 dw -67, 90 +times 4 dw -46, -31 +times 4 dw 85, -78 +times 4 dw 13, 61 +times 4 dw -90, 54 +times 4 dw 22, -82 + +times 4 dw 31, -78 +times 4 dw 90, -61 +times 4 dw 4, 54 +times 4 dw -88, 82 +times 4 dw -38, -22 +times 4 dw 73, -90 +times 4 dw 67, -13 +times 4 dw -46, 85 + +times 4 dw 22, -61 +times 4 dw 85, -90 +times 4 dw 73, -38 +times 4 dw -4, 46 +times 4 dw -78, 90 +times 4 dw -82, 54 +times 4 dw -13, -31 +times 4 dw 67, -88 + +times 4 dw 13, -38 +times 4 dw 61, -78 +times 4 dw 88, -90 +times 4 dw 85, -73 +times 4 dw 54, -31 +times 4 dw 4, 22 +times 4 dw -46, 67 +times 4 dw -82, 90 + +times 4 dw 4, -13 +times 4 dw 22, -31 +times 4 dw 38, -46 +times 4 dw 54, -61 +times 4 dw 67, -73 +times 4 dw 78, -82 +times 4 dw 85, -88 +times 4 dw 90, -90 + section .text ; void ff_hevc_idctHxW_dc_{8,10}_(int16_t *coeffs) @@ -74,34 +286,565 @@ cglobal hevc_idct_%1x%1_dc_%2, 1, 2, 1, coeff, tmp RET %endmacro -; 8-bit -INIT_MMX mmxext -IDCT_DC_NL 4, 8 -IDCT_DC 8, 2, 8 +; IDCT 4x4, expects input in m0, m1 +; %1 - shift +; %2 - 1/0 - SCALE and Transpose or not +; %3 - 1/0 add constant or not +%macro TR_4x4 3 + ; interleaves src0 with src2 to m0 + ; and src1 with scr3 to m2 + ; src0: 00 01 02 03 m0: 00 20 01 21 02 22 03 23 + ; src1: 10 11 12 13 --> + ; src2: 20 21 22 23 m1: 10 30 11 31 12 32 13 33 + ; src3: 30 31 32 33 -INIT_XMM sse2 -IDCT_DC_NL 8, 8 -IDCT_DC 16, 4, 8 -IDCT_DC 32, 16, 8 + SBUTTERFLY wd, 0, 1, 2 -%if HAVE_AVX2_EXTERNAL -INIT_YMM avx2 -IDCT_DC 16, 2, 8 -IDCT_DC 32, 8, 8 -%endif ;HAVE_AVX2_EXTERNAL + pmaddwd m2, m0, [pw_64] ; e0 + pmaddwd m3, m1, [pw_83_36] ; o0 + pmaddwd m0, [pw_64_m64] ; e1 + pmaddwd m1, [pw_36_m83] ; o1 + +%if %3 == 1 + %assign %%add 1 << (%1 - 1) + mova m4, [pd_ %+ %%add] + paddd m2, m4 + paddd m0, m4 +%endif + + SUMSUB_BADC d, 3, 2, 1, 0, 4 + +%if %2 == 1 + psrad m3, %1 ; e0 + o0 + psrad m1, %1 ; e1 + o1 + psrad m2, %1 ; e0 - o0 + psrad m0, %1 ; e1 - o1 + ;clip16 + packssdw m3, m1 + packssdw m0, m2 + ; Transpose + SBUTTERFLY wd, 3, 0, 1 + SBUTTERFLY wd, 3, 0, 1 + SWAP 3, 1, 0 +%else + SWAP 3, 2, 0 +%endif +%endmacro + +%macro DEFINE_BIAS 1 + %assign shift (20 - %1) + %assign c_add (1 << (shift - 1)) + %define arr_add pd_ %+ c_add +%endmacro + +; %1 - bit_depth +; %2 - register add constant +; is loaded to +; shift = 20 - bit_depth +%macro LOAD_BIAS 2 + DEFINE_BIAS %1 + mova %2, [arr_add] +%endmacro + +; %1, %2 - registers to load packed 16 bit values to +; %3, %4, %5, %6 - vertical offsets +; %7 - horizontal offset +%macro LOAD_BLOCK 7 + movq %1, [r0 + %3 + %7] + movhps %1, [r0 + %5 + %7] + movq %2, [r0 + %4 + %7] + movhps %2, [r0 + %6 + %7] +%endmacro + +; void ff_hevc_idct_4x4__{8,10}_(int16_t *coeffs, int col_limit) +; %1 = bitdepth +%macro IDCT_4x4 1 +cglobal hevc_idct_4x4_%1, 1, 1, 5, coeffs + mova m0, [coeffsq] + mova m1, [coeffsq + 16] + + TR_4x4 7, 1, 1 + TR_4x4 20 - %1, 1, 1 + + mova [coeffsq], m0 + mova [coeffsq + 16], m1 + RET +%endmacro + +; scale, pack (clip16) and store the residuals 0 e8[0] + o8[0] --> + %1 +; 4 at one time (4 columns) 1 e8[1] + o8[1] +; from %5: e8/16 + o8/16, with %1 offset ... +; and %3: e8/16 - o8/16, with %2 offset 6 e8[1] - o8[1] +; %4 - shift 7 e8[0] - o8[0] --> + %2 +%macro STORE_8 7 + psrad %5, %4 + psrad %3, %4 + packssdw %5, %3 + movq [coeffsq + %1], %5 + movhps [coeffsq + %2], %5 +%endmacro + +; %1 - horizontal offset +; %2 - shift +; %3, %4 - transform coeffs +; %5 - vertical offset for e8 + o8 +; %6 - vertical offset for e8 - o8 +; %7 - register with e8 inside +; %8 - block_size +; %9 - register to store e8 +o8 +; %10 - register to store e8 - o8 +%macro E8_O8 10 + pmaddwd m6, m4, %3 + pmaddwd m7, m5, %4 + + paddd m6, m7 + paddd m7, m6, %7 ; o8 + e8 + psubd %7, m6 ; e8 - o8 +%if %8 == 8 + STORE_8 %5 + %1, %6 + %1, %7, %2, m7, 0, 0 +%else + SWAP m7, %9 + SWAP %7, %10 +%endif +%endmacro + +; 8x4 residuals are processed and stored +; %1 - horizontal offset +; %2 - shift +; %3 - offset of the even row +; %4 - step: 1 for 8x8, 2 for 16x16, 4 for 32x32 +; %5 - offset of the odd row +; %6 - block size +; %7 - 1/0 add a constant in TR_4x4 or not +; I want to add a constant for 8x8 transform but not for 16x16 and 32x32 +%macro TR_8x4 7 + ; load 4 columns of even rows + LOAD_BLOCK m0, m1, 0, 2 * %4 * %3, %4 * %3, 3 * %4 * %3, %1 + + TR_4x4 %2, 0, %7 ; e8: m0, m1, m2, m3, for 4 columns only + + ; load 4 columns of odd rows + LOAD_BLOCK m4, m5, %4 * %5, 3 * %4 * %5, 5 * %4 * %5, 7 * %4 * %5, %1 + + ; 00 01 02 03 + ; 10 11 12 13 m4: 10 30 11 31 12 32 13 33 + + ; ... -- > + ; m5: 50 70 51 71 52 72 53 73 + ; 70 71 72 73 + SBUTTERFLY wd, 4, 5, 6 + + E8_O8 %1, %2, [pw_89_75], [pw_50_18], 0, %5 * 7, m0, %6, m8, m15 + E8_O8 %1, %2, [pw_75_m18], [pw_m89_m50], %5, %5 * 6, m1, %6, m9, m14 + E8_O8 %1, %2, [pw_50_m89], [pw_18_75], %5 * 2, %5 * 5, m2, %6, m10, m13 + E8_O8 %1, %2, [pw_18_m50], [pw_75_m89], %5 * 3, %5 * 4, m3, %6, m11, m12 +%endmacro + +%macro STORE_PACKED 7 + movq [r0 + %3 + %7], %1 + movhps [r0 + %4 + %7], %1 + movq [r0 + %5 + %7], %2 + movhps [r0 + %6 + %7], %2 +%endmacro + +; transpose 4x4 block packed +; in %1 and %2 registers +; %3 - temporary register +%macro TRANSPOSE_4x4 3 + SBUTTERFLY wd, %1, %2, %3 + SBUTTERFLY dq, %1, %2, %3 +%endmacro + +; %1 - horizontal offset of the block i +; %2 - vertical offset of the block i +; %3 - width in bytes +; %4 - vertical offset for the block j +; %5 - horizontal offset for the block j +%macro SWAP_BLOCKS 5 + ; M_j + LOAD_BLOCK m4, m5, %4, %4 + %3, %4 + 2 * %3, %4 + 3 * %3, %5 + TRANSPOSE_4x4 4, 5, 6 + + ; M_i + LOAD_BLOCK m6, m7, %2, %2 + %3, %2 + 2 * %3, %2 + 3 * %3, %1 + + STORE_PACKED m4, m5, %2, %2 + %3, %2 + 2 * %3, %2 + 3 * %3, %1 + + ; transpose and store M_i + SWAP m6, m4 + SWAP m7, m5 + TRANSPOSE_4x4 4, 5, 6 + STORE_PACKED m4, m5, %4, %4 + %3, %4 + 2 * %3, %4 + 3 * %3, %5 +%endmacro + +; %1 - horizontal offset +; %2 - vertical offset of the block +; %3 - width in bytes +%macro TRANSPOSE_BLOCK 3 + LOAD_BLOCK m4, m5, %2, %2 + %3, %2 + 2 * %3, %2 + 3 * %3, %1 + TRANSPOSE_4x4 4, 5, 6 + STORE_PACKED m4, m5, %2, %2 + %3, %2 + 2 * %3, %2 + 3 * %3, %1 +%endmacro -; 10-bit +%macro TRANSPOSE_8x8 0 +cglobal hevc_idct_transpose_8x8, 0, 0, 0 + ; M1 M2 ^T = M1^t M3^t + ; M3 M4 M2^t M4^t + + ; M1 4x4 block + TRANSPOSE_BLOCK 0, 0, 16 + + ; M2 and M3 + SWAP_BLOCKS 0, 64, 16, 0, 8 + + ; M4 + TRANSPOSE_BLOCK 8, 64, 16 + + ret +%endmacro + +; void ff_hevc_idct_8x8_{8,10}_(int16_t *coeffs, int col_limit) +; %1 = bitdepth +%macro IDCT_8x8 1 +cglobal hevc_idct_8x8_%1, 1, 1, 8, coeffs + TR_8x4 0, 7, 32, 1, 16, 8, 1 + TR_8x4 8, 7, 32, 1, 16, 8, 1 + + call hevc_idct_transpose_8x8_ %+ cpuname + + DEFINE_BIAS %1 + TR_8x4 0, shift, 32, 1, 16, 8, 1 + TR_8x4 8, shift, 32, 1, 16, 8, 1 + + TAIL_CALL hevc_idct_transpose_8x8_ %+ cpuname, 1 +%endmacro + +; store intermedite e32 coeffs on stack +; as 16x4 matrix +; from m10: e8 + o8, with %6 offset +; and %3: e8 - o8, with %7 offset +; %4 - shift, unused here +%macro STORE_16 7 + mova [rsp + %6], %5 + mova [rsp + %7], %3 +%endmacro + +; %1, %2 - transform constants +; %3, %4 - regs with interleaved coeffs +; %5 - 1/0 SWAP or add +; %6, %7 - registers for intermidiate sums +; %8 - accumulator register +%macro ADD_ROWS 8 + pmaddwd %6, %3, %1 + pmaddwd %7, %4, %2 + paddd %6, %7 +%if %5 == 1 + SWAP %6, %8 +%else + paddd %8, %6 +%endif +%endmacro + +; %1 - transform coeffs +; %2, %3 offsets for storing e+o/e-o back to coeffsq +; %4 - shift +; %5 - add +; %6 - block_size +; %7 - register with e16 +; %8, %9 - stack offsets for storing e+o/e-o +%macro E16_O16 9 + ADD_ROWS [%1], [%1 + 16], m0, m1, 1, m5, m6, m7 + ADD_ROWS [%1 + 2 * 16], [%1 + 3 * 16], m2, m3, 0, m5, m6, m7 + +%if %6 == 8 + paddd %7, %5 +%endif + + paddd m4, m7, %7 ; o16 + e16 + psubd %7, m7 ; e16 - o16 + STORE_%6 %2, %3, %7, %4, m4, %8, %9 +%endmacro + +%macro TR_16x4 10 + ; produce 8x4 matrix of e16 coeffs + ; for 4 first rows and store it on stack (128 bytes) + TR_8x4 %1, 7, %4, %5, %6, %8, 0 + + ; load 8 even rows + LOAD_BLOCK m0, m1, %9 * %6, %9 * 3 * %6, %9 * 5 * %6, %9 * 7 * %6, %1 + LOAD_BLOCK m2, m3, %9 * 9 * %6, %9 * 11 * %6, %9 * 13 * %6, %9 * 15 * %6, %1 + + SBUTTERFLY wd, 0, 1, 4 + SBUTTERFLY wd, 2, 3, 4 + + E16_O16 trans_coeffs16, 0 + %1, 15 * %6 + %1, %2, %3, %7, m8, 0, 15 * 16 + mova m8, %3 + E16_O16 trans_coeffs16 + 64, %6 + %1, 14 * %6 + %1, %2, m8, %7, m9, 16, 14 * 16 + E16_O16 trans_coeffs16 + 2 * 64, 2 * %6 + %1, 13 * %6 + %1, %2, m8, %7, m10, 2 * 16, 13 * 16 + E16_O16 trans_coeffs16 + 3 * 64, 3 * %6 + %1, 12 * %6 + %1, %2, m8, %7, m11, 3 * 16, 12 * 16 + E16_O16 trans_coeffs16 + 4 * 64, 4 * %6 + %1, 11 * %6 + %1, %2, m8, %7, m12, 4 * 16, 11 * 16 + E16_O16 trans_coeffs16 + 5 * 64, 5 * %6 + %1, 10 * %6 + %1, %2, m8, %7, m13, 5 * 16, 10 * 16 + E16_O16 trans_coeffs16 + 6 * 64, 6 * %6 + %1, 9 * %6 + %1, %2, m8, %7, m14, 6 * 16, 9 * 16 + E16_O16 trans_coeffs16 + 7 * 64, 7 * %6 + %1, 8 * %6 + %1, %2, m8, %7, m15, 7 * 16, 8 * 16 +%endmacro + +%macro TRANSPOSE_16x16 0 +cglobal hevc_idct_transpose_16x16, 0, 0, 0 +; M1 M2 M3 M4 ^T m1 m5 m9 m13 M_i^T = m_i +; M5 M6 M7 M8 --> m2 m6 m10 m14 +; M9 M10 M11 M12 m3 m7 m11 m15 +; M13 M14 M15 M16 m4 m8 m12 m16 + + ; M1 4x4 block + TRANSPOSE_BLOCK 0, 0, 32 + + ; M5, M2 + SWAP_BLOCKS 0, 128, 32, 0, 8 + ; M9, M3 + SWAP_BLOCKS 0, 256, 32, 0, 16 + ; M13, M4 + SWAP_BLOCKS 0, 384, 32, 0, 24 + + ;M6 + TRANSPOSE_BLOCK 8, 128, 32 + + ; M10, M7 + SWAP_BLOCKS 8, 256, 32, 128, 16 + ; M14, M8 + SWAP_BLOCKS 8, 384, 32, 128, 24 + + ;M11 + TRANSPOSE_BLOCK 16, 256, 32 + + ; M15, M12 + SWAP_BLOCKS 16, 384, 32, 256, 24 + + ;M16 + TRANSPOSE_BLOCK 24, 384, 32 + + ret +%endmacro + +; void ff_hevc_idct_16x16_{8,10}_(int16_t *coeffs, int col_limit) +; %1 = bitdepth +%macro IDCT_16x16 1 +cglobal hevc_idct_16x16_%1, 1, 2, 16, coeffs + mov r1d, 3 +.loop16: + TR_16x4 8 * r1, 7, [pd_64], 64, 2, 32, 8, 16, 1, 0 + dec r1d + jge .loop16 + + call hevc_idct_transpose_16x16_ %+ cpuname + + DEFINE_BIAS %1 + mov r1d, 3 +.loop16_2: + TR_16x4 8 * r1, shift, [arr_add], 64, 2, 32, 8, 16, 1, 1 + dec r1d + jge .loop16_2 + + TAIL_CALL hevc_idct_transpose_16x16_ %+ cpuname, 1 +%endmacro + +; scale, pack (clip16) and store the residuals 0 e32[0] + o32[0] --> %1 +; 4 at one time (4 columns) 1 e32[1] + o32[1] +; %1 - address to store e32 + o32 +; %2 - address to store e32 - e32 +; %5 - reg with e32 + o32 ... +; %3 - reg with e32 - o32 30 e32[1] - o32[1] +; %4 - shift 31 e32[0] - o32[0] --> %2 +%macro STORE_32 5 + psrad %5, %4 + psrad %3, %4 + packssdw %5, %3 + movq [%1], %5 + movhps [%2], %5 +%endmacro + +; %1 - transform coeffs +; %2 - stack offset for e32 +; %2, %3 offsets for storing e+o/e-o back to coeffsq +; %4 - shift +; %5 - stack offset of e32 +%macro E32_O32 5 + ADD_ROWS [%1], [%1 + 16], m0, m1, 1, m8, m9, m10 + ADD_ROWS [%1 + 2 * 16], [%1 + 3 * 16], m2, m3, 0, m8, m9, m10 + ADD_ROWS [%1 + 4 * 16], [%1 + 5 * 16], m4, m5, 0, m8, m9, m10 + ADD_ROWS [%1 + 6 * 16], [%1 + 7 * 16], m6, m7, 0, m8, m9, m10 + + paddd m11, m14, [rsp + %5] + paddd m12, m10, m11 ; o32 + e32 + psubd m11, m10 ; e32 - o32 + STORE_32 %2, %3, m11, %4, m12 +%endmacro + +; %1 - horizontal offset +; %2 - bitdepth +%macro TR_32x4 3 + TR_16x4 %1, 7, [pd_64], 128, 4, 64, 16, 16, 2, 0 + + LOAD_BLOCK m0, m1, 64, 3 * 64, 5 * 64, 7 * 64, %1 + LOAD_BLOCK m2, m3, 9 * 64, 11 * 64, 13 * 64, 15 * 64, %1 + LOAD_BLOCK m4, m5, 17 * 64, 19 * 64, 21 * 64, 23 * 64, %1 + LOAD_BLOCK m6, m7, 25 * 64, 27 * 64, 29 * 64, 31 * 64, %1 + + SBUTTERFLY wd, 0, 1, 8 + SBUTTERFLY wd, 2, 3, 8 + SBUTTERFLY wd, 4, 5, 8 + SBUTTERFLY wd, 6, 7, 8 + +%if %3 == 1 + %assign shift 7 + mova m14, [pd_64] +%else + LOAD_BIAS %2, m14 +%endif + + lea r2, [trans_coeff32 + 15 * 128] + lea r3, [coeffsq + %1] + lea r4, [r3 + 16 * 64] + mov r5d, 15 * 16 +%%loop: + E32_O32 r2, r3 + r5 * 4, r4, shift, r5 + sub r2, 128 + add r4, 64 + sub r5d, 16 + jge %%loop +%endmacro + +%macro TRANSPOSE_32x32 0 +cglobal hevc_idct_transpose_32x32, 0, 0, 0 + ; M0 M1 ... M7 + ; M8 M15 + ; + ; ... + ; + ; M56 M63 + + TRANSPOSE_BLOCK 0, 0, 64 ; M1 + mov r1d, 7 + mov r2d, 7 * 256 +.loop_transpose: + SWAP_BLOCKS 0, r2, 64, 0, r1 * 8 + sub r2d, 256 + dec r1d + jg .loop_transpose + + TRANSPOSE_BLOCK 8, 256, 64 ; M9 + mov r1d, 6 + mov r2d, 512 + mov r3d, 16 +.loop_transpose2: + SWAP_BLOCKS 8, r2, 64, 256, r3 + add r3d, 8 + add r2d, 256 + dec r1d + jg .loop_transpose2 + + TRANSPOSE_BLOCK 2 * 8, 2 * 256, 64 ; M9 + mov r1d, 5 + mov r2d, 768 + mov r3d, 24 +.loop_transpose3: + SWAP_BLOCKS 2 * 8, r2, 64, 2 * 256, r3 + add r3d, 8 + add r2d, 256 + dec r1d + jg .loop_transpose3 + + TRANSPOSE_BLOCK 3 * 8, 3 * 256, 64 ; M27 + mov r1d, 4 + mov r2d, 1024 + mov r3d, 32 +.loop_transpose4: + SWAP_BLOCKS 3 * 8, r2, 64, 3 * 256, r3 + add r3d, 8 + add r2d, 256 + dec r1d + jg .loop_transpose4 + + TRANSPOSE_BLOCK 4 * 8, 4 * 256, 64 ; M36 + mov r1d, 3 + mov r2d, 1280 + mov r3d, 40 +.loop_transpose5: + SWAP_BLOCKS 4 * 8, r2, 64, 4 * 256, r3 + add r3d, 8 + add r2d, 256 + dec r1d + jg .loop_transpose5 + + TRANSPOSE_BLOCK 5 * 8, 5 * 256, 64 ; M45 + SWAP_BLOCKS 5 * 8, 6 * 256, 64, 5 * 256, 6 * 8 + SWAP_BLOCKS 5 * 8, 7 * 256, 64, 5 * 256, 7 * 8 + + TRANSPOSE_BLOCK 6 * 8, 6 * 256, 64 ; M54 + SWAP_BLOCKS 6 * 8, 7 * 256, 64, 6 * 256, 7 * 8 + + TRANSPOSE_BLOCK 7 * 8, 7 * 256, 64 ; M63 + + ret +%endmacro + +; void ff_hevc_idct_32x32_{8,10}_(int16_t *coeffs, int col_limit) +; %1 = bitdepth +%macro IDCT_32x32 1 +cglobal hevc_idct_32x32_%1, 1, 6, 16, 256, coeffs + mov r1d, 7 +.loop32: + TR_32x4 8 * r1, %1, 1 + dec r1d + jge .loop32 + + call hevc_idct_transpose_32x32_ %+ cpuname + + mov r1d, 7 +.loop32_2: + TR_32x4 8 * r1, %1, 0 + dec r1d + jge .loop32_2 + + TAIL_CALL hevc_idct_transpose_32x32_ %+ cpuname, 1 +%endmacro + +%macro INIT_IDCT_DC 1 INIT_MMX mmxext -IDCT_DC_NL 4, 10 -IDCT_DC 8, 2, 10 +IDCT_DC_NL 4, %1 +IDCT_DC 8, 2, %1 INIT_XMM sse2 -IDCT_DC_NL 8, 10 -IDCT_DC 16, 4, 10 -IDCT_DC 32, 16, 10 +IDCT_DC_NL 8, %1 +IDCT_DC 16, 4, %1 +IDCT_DC 32, 16, %1 %if HAVE_AVX2_EXTERNAL -INIT_YMM avx2 -IDCT_DC 16, 2, 10 -IDCT_DC 32, 8, 10 + INIT_YMM avx2 + IDCT_DC 16, 2, %1 + IDCT_DC 32, 8, %1 %endif ;HAVE_AVX2_EXTERNAL +%endmacro + +%macro INIT_IDCT 2 +INIT_XMM %2 +%if %1 == 8 + TRANSPOSE_8x8 + %if ARCH_X86_64 + TRANSPOSE_16x16 + TRANSPOSE_32x32 + %endif +%endif +%if ARCH_X86_64 + IDCT_32x32 %1 + IDCT_16x16 %1 +%endif +IDCT_8x8 %1 +IDCT_4x4 %1 +%endmacro + +INIT_IDCT_DC 8 +INIT_IDCT_DC 10 +INIT_IDCT 8, sse2 +INIT_IDCT 8, avx +INIT_IDCT 10, sse2 +INIT_IDCT 10, avx diff --git a/libavcodec/x86/hevcdsp_init.c b/libavcodec/x86/hevcdsp_init.c index 1a675ab64d93a..0a063479039a7 100644 --- a/libavcodec/x86/hevcdsp_init.c +++ b/libavcodec/x86/hevcdsp_init.c @@ -66,17 +66,30 @@ idct_dc_proto(32,10, avx); idct_dc_proto(16,10, avx2); idct_dc_proto(32,10, avx2); -#define IDCT_FUNCS(W, opt) \ +#define IDCT_DC_FUNCS(W, opt) \ void ff_hevc_idct_ ## W ## _dc_8_ ## opt(int16_t *coeffs); \ void ff_hevc_idct_ ## W ## _dc_10_ ## opt(int16_t *coeffs) -IDCT_FUNCS(4x4, mmxext); -IDCT_FUNCS(8x8, mmxext); -IDCT_FUNCS(8x8, sse2); -IDCT_FUNCS(16x16, sse2); -IDCT_FUNCS(32x32, sse2); -IDCT_FUNCS(16x16, avx2); -IDCT_FUNCS(32x32, avx2); +IDCT_DC_FUNCS(4x4, mmxext); +IDCT_DC_FUNCS(8x8, mmxext); +IDCT_DC_FUNCS(8x8, sse2); +IDCT_DC_FUNCS(16x16, sse2); +IDCT_DC_FUNCS(32x32, sse2); +IDCT_DC_FUNCS(16x16, avx2); +IDCT_DC_FUNCS(32x32, avx2); + +#define IDCT_FUNCS(opt) \ +void ff_hevc_idct_4x4_8_ ## opt(int16_t *coeffs, int col_limit); \ +void ff_hevc_idct_4x4_10_ ## opt(int16_t *coeffs, int col_limit); \ +void ff_hevc_idct_8x8_8_ ## opt(int16_t *coeffs, int col_limit); \ +void ff_hevc_idct_8x8_10_ ## opt(int16_t *coeffs, int col_limit); \ +void ff_hevc_idct_16x16_8_ ## opt(int16_t *coeffs, int col_limit); \ +void ff_hevc_idct_16x16_10_ ## opt(int16_t *coeffs, int col_limit); \ +void ff_hevc_idct_32x32_8_ ## opt(int16_t *coeffs, int col_limit); \ +void ff_hevc_idct_32x32_10_ ## opt(int16_t *coeffs, int col_limit); + +IDCT_FUNCS(sse2) +IDCT_FUNCS(avx) #define GET_PIXELS(width, depth, cf) \ void ff_hevc_get_pixels_ ## width ## _ ## depth ## _ ## cf(int16_t *dst, ptrdiff_t dststride, \ @@ -273,6 +286,9 @@ void ff_hevc_dsp_init_x86(HEVCDSPContext *c, const int bit_depth) c->idct_dc[1] = ff_hevc_idct_8x8_dc_8_sse2; c->idct_dc[2] = ff_hevc_idct_16x16_dc_8_sse2; c->idct_dc[3] = ff_hevc_idct_32x32_dc_8_sse2; + + c->idct[0] = ff_hevc_idct_4x4_8_sse2; + c->idct[1] = ff_hevc_idct_8x8_8_sse2; SET_QPEL_FUNCS(0, 0, 8, sse2, ff_hevc_get_pixels); SET_EPEL_FUNCS(0, 0, 8, sse2, ff_hevc_get_pixels); @@ -288,6 +304,10 @@ void ff_hevc_dsp_init_x86(HEVCDSPContext *c, const int bit_depth) SET_EPEL_FUNCS(1, 0, 8, ssse3, ff_hevc_epel_v); } + if (EXTERNAL_AVX(cpu_flags)) { + c->idct[0] = ff_hevc_idct_4x4_8_avx; + c->idct[1] = ff_hevc_idct_8x8_8_avx; + } } else if (bit_depth == 10) { if (EXTERNAL_MMXEXT(cpu_flags)) { c->idct_dc[0] = ff_hevc_idct_4x4_dc_10_mmxext; @@ -301,6 +321,8 @@ void ff_hevc_dsp_init_x86(HEVCDSPContext *c, const int bit_depth) c->idct_dc[2] = ff_hevc_idct_16x16_dc_10_sse2; c->idct_dc[3] = ff_hevc_idct_32x32_dc_10_sse2; + c->idct[0] = ff_hevc_idct_4x4_10_sse2; + c->idct[1] = ff_hevc_idct_8x8_10_sse2; SET_QPEL_FUNCS(0, 0, 10, sse2, ff_hevc_get_pixels); SET_EPEL_FUNCS(0, 0, 10, sse2, ff_hevc_get_pixels); @@ -309,10 +331,18 @@ void ff_hevc_dsp_init_x86(HEVCDSPContext *c, const int bit_depth) SET_CHROMA_FUNCS(put_unweighted_pred_chroma, ff_hevc_put_unweighted_pred, 10, sse2); SET_CHROMA_FUNCS(put_unweighted_pred_avg_chroma, ff_hevc_put_unweighted_pred_avg, 10, sse2); } + if (EXTERNAL_AVX(cpu_flags)) { + c->idct[0] = ff_hevc_idct_4x4_10_avx; + c->idct[1] = ff_hevc_idct_8x8_10_avx; + } } #if ARCH_X86_64 if (bit_depth == 8) { + if (EXTERNAL_SSE2(cpu_flags)) { + c->idct[2] = ff_hevc_idct_16x16_8_sse2; + c->idct[3] = ff_hevc_idct_32x32_8_sse2; + } if (EXTERNAL_SSSE3(cpu_flags)) { c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_8_ssse3; c->hevc_h_loop_filter_luma = ff_hevc_h_loop_filter_luma_8_ssse3; @@ -330,12 +360,18 @@ void ff_hevc_dsp_init_x86(HEVCDSPContext *c, const int bit_depth) SET_QPEL_FUNCS(1, 1, 8, avx, hevc_qpel_hv); SET_EPEL_FUNCS(1, 1, 8, avx, hevc_epel_hv); #endif /* HAVE_AVX_EXTERNAL */ + c->idct[2] = ff_hevc_idct_16x16_8_avx; + c->idct[3] = ff_hevc_idct_32x32_8_avx; } if (EXTERNAL_AVX2(cpu_flags)) { c->idct_dc[2] = ff_hevc_idct_16x16_dc_8_avx2; c->idct_dc[3] = ff_hevc_idct_32x32_dc_8_avx2; } } else if (bit_depth == 10) { + if (EXTERNAL_SSE2(cpu_flags)) { + c->idct[2] = ff_hevc_idct_16x16_10_sse2; + c->idct[3] = ff_hevc_idct_32x32_10_sse2; + } if (EXTERNAL_SSSE3(cpu_flags)) { c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_10_ssse3; c->hevc_h_loop_filter_luma = ff_hevc_h_loop_filter_luma_10_ssse3; @@ -355,6 +391,8 @@ void ff_hevc_dsp_init_x86(HEVCDSPContext *c, const int bit_depth) SET_EPEL_FUNCS(1, 0, 10, avx, ff_hevc_epel_v); SET_EPEL_FUNCS(1, 1, 10, avx, hevc_epel_hv); #endif /* HAVE_AVX_EXTERNAL */ + c->idct[2] = ff_hevc_idct_16x16_10_avx; + c->idct[3] = ff_hevc_idct_32x32_10_avx; } if (EXTERNAL_AVX2(cpu_flags)) { c->idct_dc[2] = ff_hevc_idct_16x16_dc_10_avx2; From eb542106029a9b28b4f76ff7c181eb4f542da9c4 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Thu, 6 Oct 2016 18:28:50 -0400 Subject: [PATCH 0282/3374] swscale: Add missing yuv444p12 swapping Missing from 9bd6ea5695660529b2887292874a7b9e61fc301e. Signed-off-by: Vittorio Giovara Signed-off-by: Luca Barbato --- libswscale/input.c | 4 ++++ tests/ref/fate/filter-pixfmts-scale | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/libswscale/input.c b/libswscale/input.c index 76a47001229a3..e1ac48378aed2 100644 --- a/libswscale/input.c +++ b/libswscale/input.c @@ -817,6 +817,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_YUV444P10LE: case AV_PIX_FMT_YUV420P12LE: case AV_PIX_FMT_YUV422P12LE: + case AV_PIX_FMT_YUV444P12LE: case AV_PIX_FMT_YUV420P16LE: case AV_PIX_FMT_YUV422P16LE: case AV_PIX_FMT_YUV444P16LE: @@ -840,6 +841,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_YUV444P10BE: case AV_PIX_FMT_YUV420P12BE: case AV_PIX_FMT_YUV422P12BE: + case AV_PIX_FMT_YUV444P12BE: case AV_PIX_FMT_YUV420P16BE: case AV_PIX_FMT_YUV422P16BE: case AV_PIX_FMT_YUV444P16BE: @@ -1039,6 +1041,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_YUV444P10LE: case AV_PIX_FMT_YUV420P12LE: case AV_PIX_FMT_YUV422P12LE: + case AV_PIX_FMT_YUV444P12LE: case AV_PIX_FMT_YUV420P16LE: case AV_PIX_FMT_YUV422P16LE: case AV_PIX_FMT_YUV444P16LE: @@ -1066,6 +1069,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_YUV444P10BE: case AV_PIX_FMT_YUV420P12BE: case AV_PIX_FMT_YUV422P12BE: + case AV_PIX_FMT_YUV444P12BE: case AV_PIX_FMT_YUV420P16BE: case AV_PIX_FMT_YUV422P16BE: case AV_PIX_FMT_YUV444P16BE: diff --git a/tests/ref/fate/filter-pixfmts-scale b/tests/ref/fate/filter-pixfmts-scale index 0a3f3f18c6ee1..09c335b331884 100644 --- a/tests/ref/fate/filter-pixfmts-scale +++ b/tests/ref/fate/filter-pixfmts-scale @@ -62,7 +62,7 @@ yuv440p 4713a7b7ce80dd06923626d13589c098 yuv444p fd733672651ad5bbffb046fd67151fee yuv444p10be 34b38d54167df70044bdc08518d91009 yuv444p10le 0812e3371c9589c6621408812f9e7a27 -yuv444p12be 936147950ba1b511570da85a0922abf3 +yuv444p12be 4fdc4bf4036c40ff575f9bc2229bf5d6 yuv444p12le 4a9ec677190371ef5e342ffac1ace735 yuv444p16be e89fe5a4624ed06603580b4a74af9170 yuv444p16le 6944d11048ff4013c5e60359faf1bd2d From 14e7e19a90e9b45db7adeb4d40e7f16aa7404f28 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Tue, 4 Oct 2016 11:59:53 -0400 Subject: [PATCH 0283/3374] lavc: bsf: Document input/output codecparam alloc/init process --- libavcodec/avcodec.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 167525dda35c0..88e6c62272069 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -5017,12 +5017,15 @@ typedef struct AVBSFContext { void *priv_data; /** - * Parameters of the input stream. Set by the caller before av_bsf_init(). + * Parameters of the input stream. This field is allocated in + * av_bsf_alloc(), it needs to be filled by the caller before + * av_bsf_init(). */ AVCodecParameters *par_in; /** - * Parameters of the output stream. Set by the filter in av_bsf_init(). + * Parameters of the output stream. This field is allocated in + * av_bsf_alloc(), it is set by the filter in av_bsf_init(). */ AVCodecParameters *par_out; From e7e5be8635c1cf0588d2a07e59374135de6da55a Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Thu, 6 Oct 2016 18:27:24 -0400 Subject: [PATCH 0284/3374] APIchanges: Expand the name of recently added pixel formats This makes them easier to search for. --- doc/APIchanges | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index 655783edab9c8..23771b3533a8a 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -20,7 +20,7 @@ API changes, most recent first: Add AVIO_SEEKABLE_TIME flag. 2016-xx-xx - xxxxxxx - lavu 55.22.0 - pixfmt.h - Add AV_PIX_FMT_YUV(420,422,444)P12. + Add AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, and AV_PIX_FMT_YUV444P12. 2016-xx-xx - xxxxxxx - lavc 57.27.0 - avcodec.h Add FF_PROFILE_HEVC_REXT, the extended pixel format profile for HEVC. From 328ea6a9a5ab3ddeec19939e8a381cf6a704e466 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 3 Jul 2012 04:10:11 +0200 Subject: [PATCH 0285/3374] swscale: Add input support for 12-bit formats Implemented for AV_PIX_FMT_GBRP12. Signed-off-by: Vittorio Giovara --- libswscale/input.c | 34 +++++++++++++++++++++++++++++++ libswscale/ppc/swscale_altivec.c | 2 +- libswscale/utils.c | 5 ++++- libswscale/x86/swscale.c | 3 +++ libswscale/x86/swscale_template.c | 2 +- 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/libswscale/input.c b/libswscale/input.c index e1ac48378aed2..8398e4a055beb 100644 --- a/libswscale/input.c +++ b/libswscale/input.c @@ -691,6 +691,16 @@ static void planar_rgb10be_to_y(uint8_t *dst, const uint8_t *src[4], int w) planar_rgb16_to_y(dst, src, w, 10, 1); } +static void planar_rgb12le_to_y(uint8_t *dst, const uint8_t *src[4], int w) +{ + planar_rgb16_to_y(dst, src, w, 12, 0); +} + +static void planar_rgb12be_to_y(uint8_t *dst, const uint8_t *src[4], int w) +{ + planar_rgb16_to_y(dst, src, w, 12, 1); +} + static void planar_rgb16le_to_y(uint8_t *dst, const uint8_t *src[4], int w) { planar_rgb16_to_y(dst, src, w, 16, 0); @@ -744,6 +754,18 @@ static void planar_rgb10be_to_uv(uint8_t *dstU, uint8_t *dstV, planar_rgb16_to_uv(dstU, dstV, src, w, 10, 1); } +static void planar_rgb12le_to_uv(uint8_t *dstU, uint8_t *dstV, + const uint8_t *src[4], int w) +{ + planar_rgb16_to_uv(dstU, dstV, src, w, 12, 0); +} + +static void planar_rgb12be_to_uv(uint8_t *dstU, uint8_t *dstV, + const uint8_t *src[4], int w) +{ + planar_rgb16_to_uv(dstU, dstV, src, w, 12, 1); +} + static void planar_rgb16le_to_uv(uint8_t *dstU, uint8_t *dstV, const uint8_t *src[4], int w) { @@ -790,6 +812,9 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_GBRP10LE: c->readChrPlanar = planar_rgb10le_to_uv; break; + case AV_PIX_FMT_GBRP12LE: + c->readChrPlanar = planar_rgb12le_to_uv; + break; case AV_PIX_FMT_GBRAP16LE: case AV_PIX_FMT_GBRP16LE: c->readChrPlanar = planar_rgb16le_to_uv; @@ -800,6 +825,9 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_GBRP10BE: c->readChrPlanar = planar_rgb10be_to_uv; break; + case AV_PIX_FMT_GBRP12BE: + c->readChrPlanar = planar_rgb12be_to_uv; + break; case AV_PIX_FMT_GBRAP16BE: case AV_PIX_FMT_GBRP16BE: c->readChrPlanar = planar_rgb16be_to_uv; @@ -1013,6 +1041,9 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_GBRP10LE: c->readLumPlanar = planar_rgb10le_to_y; break; + case AV_PIX_FMT_GBRP12LE: + c->readLumPlanar = planar_rgb12le_to_y; + break; case AV_PIX_FMT_GBRAP16LE: case AV_PIX_FMT_GBRP16LE: c->readLumPlanar = planar_rgb16le_to_y; @@ -1023,6 +1054,9 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_GBRP10BE: c->readLumPlanar = planar_rgb10be_to_y; break; + case AV_PIX_FMT_GBRP12BE: + c->readLumPlanar = planar_rgb12be_to_y; + break; case AV_PIX_FMT_GBRAP16BE: case AV_PIX_FMT_GBRP16BE: c->readLumPlanar = planar_rgb16be_to_y; diff --git a/libswscale/ppc/swscale_altivec.c b/libswscale/ppc/swscale_altivec.c index 9e3ddf359d79f..1a2a7c4642567 100644 --- a/libswscale/ppc/swscale_altivec.c +++ b/libswscale/ppc/swscale_altivec.c @@ -295,7 +295,7 @@ av_cold void ff_sws_init_swscale_ppc(SwsContext *c) if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)) return; - if (c->srcBpc == 8 && c->dstBpc <= 10) { + if (c->srcBpc == 8 && c->dstBpc <= 12) { c->hyScale = c->hcScale = hScale_altivec_real; } if (!is16BPS(dstFormat) && !is9_15BPS(dstFormat) && diff --git a/libswscale/utils.c b/libswscale/utils.c index b7b534dceb254..55b5275e6dda8 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -184,6 +184,8 @@ static const FormatEntry format_entries[AV_PIX_FMT_NB] = { [AV_PIX_FMT_GBRP9BE] = { 1, 1 }, [AV_PIX_FMT_GBRP10LE] = { 1, 1 }, [AV_PIX_FMT_GBRP10BE] = { 1, 1 }, + [AV_PIX_FMT_GBRP12LE] = { 1, 0 }, + [AV_PIX_FMT_GBRP12BE] = { 1, 0 }, [AV_PIX_FMT_GBRP16LE] = { 1, 0 }, [AV_PIX_FMT_GBRP16BE] = { 1, 0 }, [AV_PIX_FMT_GBRAP] = { 1, 1 }, @@ -1015,6 +1017,7 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, srcFormat != AV_PIX_FMT_RGB4_BYTE && srcFormat != AV_PIX_FMT_BGR4_BYTE && srcFormat != AV_PIX_FMT_GBRP9BE && srcFormat != AV_PIX_FMT_GBRP9LE && srcFormat != AV_PIX_FMT_GBRP10BE && srcFormat != AV_PIX_FMT_GBRP10LE && + srcFormat != AV_PIX_FMT_GBRP12BE && srcFormat != AV_PIX_FMT_GBRP12LE && srcFormat != AV_PIX_FMT_GBRP16BE && srcFormat != AV_PIX_FMT_GBRP16LE && ((dstW >> c->chrDstHSubSample) <= (srcW >> 1) || (flags & SWS_FAST_BILINEAR))) @@ -1051,7 +1054,7 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, FF_ALLOC_OR_GOTO(c, c->formatConvBuffer, (FFALIGN(srcW, 16) * 2 * FFALIGN(c->srcBpc, 8) >> 3) + 16, fail); - if (INLINE_MMXEXT(cpu_flags) && c->srcBpc == 8 && c->dstBpc <= 10) { + if (INLINE_MMXEXT(cpu_flags) && c->srcBpc == 8 && c->dstBpc <= 12) { c->canMMXEXTBeUsed = (dstW >= srcW && (dstW & 31) == 0 && (srcW & 15) == 0) ? 1 : 0; if (!c->canMMXEXTBeUsed && dstW >= srcW && (srcW & 15) == 0 diff --git a/libswscale/x86/swscale.c b/libswscale/x86/swscale.c index 48b5b49ce87c5..326f824d3e5c0 100644 --- a/libswscale/x86/swscale.c +++ b/libswscale/x86/swscale.c @@ -324,6 +324,9 @@ av_cold void ff_sws_init_swscale_x86(SwsContext *c) } else if (c->srcBpc == 10) { \ hscalefn = c->dstBpc <= 15 ? ff_hscale10to15_ ## filtersize ## _ ## opt2 : \ ff_hscale10to19_ ## filtersize ## _ ## opt1; \ + } else if (c->srcBpc == 12) { \ + hscalefn = c->dstBpc <= 15 ? ff_hscale16to15_ ## filtersize ## _ ## opt2 : \ + ff_hscale16to19_ ## filtersize ## _ ## opt1; \ } else if (c->srcBpc == 16) { \ hscalefn = c->dstBpc <= 15 ? ff_hscale16to15_ ## filtersize ## _ ## opt2 : \ ff_hscale16to19_ ## filtersize ## _ ## opt1; \ diff --git a/libswscale/x86/swscale_template.c b/libswscale/x86/swscale_template.c index e0d1abe207349..5160cbde84a1e 100644 --- a/libswscale/x86/swscale_template.c +++ b/libswscale/x86/swscale_template.c @@ -1619,7 +1619,7 @@ static av_cold void RENAME(sws_init_swscale)(SwsContext *c) } } - if (c->srcBpc == 8 && c->dstBpc <= 10) { + if (c->srcBpc == 8 && c->dstBpc <= 12) { // Use the new MMX scaler if the MMXEXT one can't be used (it is faster than the x86 ASM one). #if COMPILE_TEMPLATE_MMXEXT if (c->flags & SWS_FAST_BILINEAR && c->canMMXEXTBeUsed) { From f59750641afdd6285bd977c450cc790bebb7693d Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 5 Jul 2012 04:37:12 +0200 Subject: [PATCH 0286/3374] swscale: x86: Add some forgotten 12-bit planar YUV cases Signed-off-by: Diego Biurrun --- libswscale/x86/scale.asm | 2 ++ libswscale/x86/swscale.c | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/libswscale/x86/scale.asm b/libswscale/x86/scale.asm index a4c7e1c00b9f7..982b4320473f0 100644 --- a/libswscale/x86/scale.asm +++ b/libswscale/x86/scale.asm @@ -407,11 +407,13 @@ SCALE_FUNC %1, %2, X, X8, 7, %3 SCALE_FUNCS 8, 15, %1 SCALE_FUNCS 9, 15, %2 SCALE_FUNCS 10, 15, %2 +SCALE_FUNCS 12, 15, %2 SCALE_FUNCS 16, 15, %3 %endif ; !sse4 SCALE_FUNCS 8, 19, %1 SCALE_FUNCS 9, 19, %2 SCALE_FUNCS 10, 19, %2 +SCALE_FUNCS 12, 19, %2 SCALE_FUNCS 16, 19, %3 %endmacro diff --git a/libswscale/x86/swscale.c b/libswscale/x86/swscale.c index 326f824d3e5c0..5922d3a3d09ae 100644 --- a/libswscale/x86/swscale.c +++ b/libswscale/x86/swscale.c @@ -215,10 +215,12 @@ void ff_hscale ## from_bpc ## to ## to_bpc ## _ ## filter_n ## _ ## opt( \ SCALE_FUNC(filter_n, 8, 15, opt); \ SCALE_FUNC(filter_n, 9, 15, opt); \ SCALE_FUNC(filter_n, 10, 15, opt); \ + SCALE_FUNC(filter_n, 12, 15, opt); \ SCALE_FUNC(filter_n, 16, 15, opt); \ SCALE_FUNC(filter_n, 8, 19, opt); \ SCALE_FUNC(filter_n, 9, 19, opt); \ SCALE_FUNC(filter_n, 10, 19, opt); \ + SCALE_FUNC(filter_n, 12, 19, opt); \ SCALE_FUNC(filter_n, 16, 19, opt) #define SCALE_FUNCS_MMX(opt) \ @@ -325,8 +327,8 @@ av_cold void ff_sws_init_swscale_x86(SwsContext *c) hscalefn = c->dstBpc <= 15 ? ff_hscale10to15_ ## filtersize ## _ ## opt2 : \ ff_hscale10to19_ ## filtersize ## _ ## opt1; \ } else if (c->srcBpc == 12) { \ - hscalefn = c->dstBpc <= 15 ? ff_hscale16to15_ ## filtersize ## _ ## opt2 : \ - ff_hscale16to19_ ## filtersize ## _ ## opt1; \ + hscalefn = c->dstBpc <= 15 ? ff_hscale12to15_ ## filtersize ## _ ## opt2 : \ + ff_hscale12to19_ ## filtersize ## _ ## opt1; \ } else if (c->srcBpc == 16) { \ hscalefn = c->dstBpc <= 15 ? ff_hscale16to15_ ## filtersize ## _ ## opt2 : \ ff_hscale16to19_ ## filtersize ## _ ## opt1; \ From 1e93aa69a60815d1407a6c34d8da3f83ab193ad5 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 4 Jul 2012 21:11:39 +0200 Subject: [PATCH 0287/3374] Add GBRP12 pixel format support Signed-off-by: Vittorio Giovara --- doc/APIchanges | 3 +++ libavutil/pixdesc.c | 25 +++++++++++++++++++++++++ libavutil/pixfmt.h | 4 ++++ libavutil/version.h | 2 +- 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index 23771b3533a8a..ad51f3151aa75 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-xx-xx - xxxxxxx - lavu 55.24.0 - pixfmt.h + Add AV_PIX_FMT_GBRP12(LE/BE). + 2016-xx-xx - xxxxxxx - lavu 55.23.0 - hwcontext_vaapi.h Add AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE. diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index 78fbdbc01ba99..38c99084389a0 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -1514,6 +1514,30 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { }, .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, }, + [AV_PIX_FMT_GBRP12LE] = { + .name = "gbrp12le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* R */ + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* G */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRP12BE] = { + .name = "gbrp12be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* R */ + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* G */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, [AV_PIX_FMT_GBRP16LE] = { .name = "gbrp16le", .nb_components = 3, @@ -1923,6 +1947,7 @@ enum AVPixelFormat av_pix_fmt_swap_endianness(enum AVPixelFormat pix_fmt) PIX_FMT_SWAP_ENDIANNESS(GBRP9); PIX_FMT_SWAP_ENDIANNESS(GBRP10); + PIX_FMT_SWAP_ENDIANNESS(GBRP12); PIX_FMT_SWAP_ENDIANNESS(GBRP16); PIX_FMT_SWAP_ENDIANNESS(YUVA420P9); PIX_FMT_SWAP_ENDIANNESS(YUVA422P9); diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index 3e040fb3a03c0..473f53cc11a52 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -239,6 +239,9 @@ enum AVPixelFormat { AV_PIX_FMT_YUV444P12BE, ///< planar YUV 4:4:4, 36bpp, (1 Cr & Cb sample per 1x1 Y), big-endian AV_PIX_FMT_YUV444P12LE, ///< planar YUV 4:4:4, 36bpp, (1 Cr & Cb sample per 1x1 Y), little-endian + AV_PIX_FMT_GBRP12BE, ///< planar GBR 4:4:4 36bpp, big-endian + AV_PIX_FMT_GBRP12LE, ///< planar GBR 4:4:4 36bpp, little-endian + AV_PIX_FMT_NB, ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions }; @@ -281,6 +284,7 @@ enum AVPixelFormat { #define AV_PIX_FMT_GBRP9 AV_PIX_FMT_NE(GBRP9BE , GBRP9LE) #define AV_PIX_FMT_GBRP10 AV_PIX_FMT_NE(GBRP10BE, GBRP10LE) +#define AV_PIX_FMT_GBRP12 AV_PIX_FMT_NE(GBRP12BE, GBRP12LE) #define AV_PIX_FMT_GBRP16 AV_PIX_FMT_NE(GBRP16BE, GBRP16LE) #define AV_PIX_FMT_GBRAP16 AV_PIX_FMT_NE(GBRAP16BE, GBRAP16LE) diff --git a/libavutil/version.h b/libavutil/version.h index 73de00e267c3a..7f7da809068d1 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -54,7 +54,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 23 +#define LIBAVUTIL_VERSION_MINOR 24 #define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From ef3740c3a02bb8448bf7129e336c20846731bd1c Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 10 Oct 2016 22:31:24 +0200 Subject: [PATCH 0288/3374] swscale: Enable GBRP12 output --- libswscale/output.c | 2 ++ libswscale/utils.c | 4 ++-- tests/ref/fate/filter-pixdesc-gbrp12be | 1 + tests/ref/fate/filter-pixdesc-gbrp12le | 1 + tests/ref/fate/filter-pixfmts-copy | 2 ++ tests/ref/fate/filter-pixfmts-null | 2 ++ tests/ref/fate/filter-pixfmts-scale | 2 ++ tests/ref/fate/filter-pixfmts-vflip | 2 ++ 8 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 tests/ref/fate/filter-pixdesc-gbrp12be create mode 100644 tests/ref/fate/filter-pixdesc-gbrp12le diff --git a/libswscale/output.c b/libswscale/output.c index 78ebbc6b4f112..a8845f56ace48 100644 --- a/libswscale/output.c +++ b/libswscale/output.c @@ -1455,6 +1455,8 @@ av_cold void ff_sws_init_output_funcs(SwsContext *c, case AV_PIX_FMT_GBRP9LE: case AV_PIX_FMT_GBRP10BE: case AV_PIX_FMT_GBRP10LE: + case AV_PIX_FMT_GBRP12BE: + case AV_PIX_FMT_GBRP12LE: case AV_PIX_FMT_GBRP16BE: case AV_PIX_FMT_GBRP16LE: case AV_PIX_FMT_GBRAP: diff --git a/libswscale/utils.c b/libswscale/utils.c index 55b5275e6dda8..ad5518acfc957 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -184,8 +184,8 @@ static const FormatEntry format_entries[AV_PIX_FMT_NB] = { [AV_PIX_FMT_GBRP9BE] = { 1, 1 }, [AV_PIX_FMT_GBRP10LE] = { 1, 1 }, [AV_PIX_FMT_GBRP10BE] = { 1, 1 }, - [AV_PIX_FMT_GBRP12LE] = { 1, 0 }, - [AV_PIX_FMT_GBRP12BE] = { 1, 0 }, + [AV_PIX_FMT_GBRP12LE] = { 1, 1 }, + [AV_PIX_FMT_GBRP12BE] = { 1, 1 }, [AV_PIX_FMT_GBRP16LE] = { 1, 0 }, [AV_PIX_FMT_GBRP16BE] = { 1, 0 }, [AV_PIX_FMT_GBRAP] = { 1, 1 }, diff --git a/tests/ref/fate/filter-pixdesc-gbrp12be b/tests/ref/fate/filter-pixdesc-gbrp12be new file mode 100644 index 0000000000000..4421c93a94ca9 --- /dev/null +++ b/tests/ref/fate/filter-pixdesc-gbrp12be @@ -0,0 +1 @@ +pixdesc-gbrp12be 7c924cf350433263f3413431ccba7efd diff --git a/tests/ref/fate/filter-pixdesc-gbrp12le b/tests/ref/fate/filter-pixdesc-gbrp12le new file mode 100644 index 0000000000000..1d53d0f532dea --- /dev/null +++ b/tests/ref/fate/filter-pixdesc-gbrp12le @@ -0,0 +1 @@ +pixdesc-gbrp12le 1f8101f05b641b2a46426a26139c4f5b diff --git a/tests/ref/fate/filter-pixfmts-copy b/tests/ref/fate/filter-pixfmts-copy index c712f781482b8..97acc0928aba2 100644 --- a/tests/ref/fate/filter-pixfmts-copy +++ b/tests/ref/fate/filter-pixfmts-copy @@ -16,6 +16,8 @@ gbrap 57cb1a02d6f015a4329fe367f3bdfe49 gbrp d5f73b5d3ba7f6cadbc9b4ecbc161005 gbrp10be eb19bda60ab7f893198364dff21342d6 gbrp10le 546146efb36ad2605e9f74ee5e4c2a36 +gbrp12be 3a7dd35686a7ca85cc58c44d0c5c4e96 +gbrp12le 654861b1837d312569395f598da1a2a1 gbrp9be cbe1bf8ead497a92362a749bd4b0a57e gbrp9le f88c68df5d699a4a7f1b0152df9f25fe gray 8c941e9bbf6da5336384c57f15a4a454 diff --git a/tests/ref/fate/filter-pixfmts-null b/tests/ref/fate/filter-pixfmts-null index c712f781482b8..97acc0928aba2 100644 --- a/tests/ref/fate/filter-pixfmts-null +++ b/tests/ref/fate/filter-pixfmts-null @@ -16,6 +16,8 @@ gbrap 57cb1a02d6f015a4329fe367f3bdfe49 gbrp d5f73b5d3ba7f6cadbc9b4ecbc161005 gbrp10be eb19bda60ab7f893198364dff21342d6 gbrp10le 546146efb36ad2605e9f74ee5e4c2a36 +gbrp12be 3a7dd35686a7ca85cc58c44d0c5c4e96 +gbrp12le 654861b1837d312569395f598da1a2a1 gbrp9be cbe1bf8ead497a92362a749bd4b0a57e gbrp9le f88c68df5d699a4a7f1b0152df9f25fe gray 8c941e9bbf6da5336384c57f15a4a454 diff --git a/tests/ref/fate/filter-pixfmts-scale b/tests/ref/fate/filter-pixfmts-scale index 09c335b331884..b6f38b4299923 100644 --- a/tests/ref/fate/filter-pixfmts-scale +++ b/tests/ref/fate/filter-pixfmts-scale @@ -16,6 +16,8 @@ gbrap eefdbfd1426765ce5e9790022533db0d gbrp 5d14768d2ab6cbf3879966b5d5c6befb gbrp10be 4192c246f4a52ec7a37919665190cce9 gbrp10le 170189b2c2dd46f31165d8fa6cadef0a +gbrp12be 996265700d1ef082358974f4ad6529f6 +gbrp12le 735061c07442657580577d1cede3a636 gbrp9be 01c837e1def99abec205b80d21b68bf0 gbrp9le dd982d59c3d71c3b201f2d9363d8952c gray 4c571fb634a75f177b64cee168fbf3a1 diff --git a/tests/ref/fate/filter-pixfmts-vflip b/tests/ref/fate/filter-pixfmts-vflip index b8718c7375675..6f633c6c9a021 100644 --- a/tests/ref/fate/filter-pixfmts-vflip +++ b/tests/ref/fate/filter-pixfmts-vflip @@ -16,6 +16,8 @@ gbrap 38e04cbd4dc5566586d58ffed0c6b20d gbrp 37954476d089b5b74b06891e64ad6b9e gbrp10be ec01c15ed248a72c42f84a2a8cfec56f gbrp10le be52e72a59d87a43727262bcd90967cd +gbrp12be 0e1dc666ef119651664062afa3d24aee +gbrp12le b7b27715bc9054a93ba81f110cf42ee5 gbrp9be 2ae8f0d3b079d6550a2b1d4a7c4a6e4b gbrp9le c62df0f386c957cc9cacb3c8014542eb gray 684ba667effbbf5983f46a9bea4afaae From 81f1f6c3f62b1dd5e7433583929d46958522ceb3 Mon Sep 17 00:00:00 2001 From: Kieran Kunhya Date: Mon, 8 Feb 2016 21:40:10 +0000 Subject: [PATCH 0289/3374] Add GBRAP12 pixel format support Signed-off-by: Diego Biurrun --- doc/APIchanges | 3 +++ libavcodec/utils.c | 2 ++ libavutil/pixdesc.c | 28 ++++++++++++++++++++++++++++ libavutil/pixfmt.h | 4 ++++ libavutil/version.h | 2 +- libswscale/input.c | 4 ++++ libswscale/swscale_unscaled.c | 1 + libswscale/utils.c | 2 ++ 8 files changed, 45 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index ad51f3151aa75..011ff0a6ebbc3 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-xx-xx - xxxxxxx - lavu 55.25.0 - pixfmt.h + Add AV_PIX_FMT_GBRAP12(LE/BE). + 2016-xx-xx - xxxxxxx - lavu 55.24.0 - pixfmt.h Add AV_PIX_FMT_GBRP12(LE/BE). diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 837edbd4ed78d..329233d473424 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -233,6 +233,8 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, case AV_PIX_FMT_GBRP9BE: case AV_PIX_FMT_GBRP10LE: case AV_PIX_FMT_GBRP10BE: + case AV_PIX_FMT_GBRAP12LE: + case AV_PIX_FMT_GBRAP12BE: w_align = 16; //FIXME assume 16 pixel per macroblock h_align = 16 * 2; // interlaced needs 2 macroblocks height break; diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index 38c99084389a0..80bdee74d09a5 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -1710,6 +1710,34 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { }, .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_BE, }, + [AV_PIX_FMT_GBRAP12LE] = { + .name = "gbrap12le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* R */ + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* G */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* B */ + { 3, 2, 0, 0, 12, 1, 11, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB | + AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_GBRAP12BE] = { + .name = "gbrap12be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* R */ + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* G */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* B */ + { 3, 2, 0, 0, 12, 1, 11, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | + AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, + }, }; #if FF_API_PLUS1_MINUS1 FF_ENABLE_DEPRECATION_WARNINGS diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index 473f53cc11a52..917fa579c859f 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -242,6 +242,9 @@ enum AVPixelFormat { AV_PIX_FMT_GBRP12BE, ///< planar GBR 4:4:4 36bpp, big-endian AV_PIX_FMT_GBRP12LE, ///< planar GBR 4:4:4 36bpp, little-endian + AV_PIX_FMT_GBRAP12BE, ///< planar GBR 4:4:4:4 48bpp, big-endian + AV_PIX_FMT_GBRAP12LE, ///< planar GBR 4:4:4:4 48bpp, little-endian + AV_PIX_FMT_NB, ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions }; @@ -287,6 +290,7 @@ enum AVPixelFormat { #define AV_PIX_FMT_GBRP12 AV_PIX_FMT_NE(GBRP12BE, GBRP12LE) #define AV_PIX_FMT_GBRP16 AV_PIX_FMT_NE(GBRP16BE, GBRP16LE) +#define AV_PIX_FMT_GBRAP12 AV_PIX_FMT_NE(GBRAP12BE, GBRAP12LE) #define AV_PIX_FMT_GBRAP16 AV_PIX_FMT_NE(GBRAP16BE, GBRAP16LE) #define AV_PIX_FMT_YUVA420P9 AV_PIX_FMT_NE(YUVA420P9BE , YUVA420P9LE) diff --git a/libavutil/version.h b/libavutil/version.h index 7f7da809068d1..77288f58a6066 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -54,7 +54,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 24 +#define LIBAVUTIL_VERSION_MINOR 25 #define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ diff --git a/libswscale/input.c b/libswscale/input.c index 8398e4a055beb..304466bd99d83 100644 --- a/libswscale/input.c +++ b/libswscale/input.c @@ -812,6 +812,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_GBRP10LE: c->readChrPlanar = planar_rgb10le_to_uv; break; + case AV_PIX_FMT_GBRAP12LE: case AV_PIX_FMT_GBRP12LE: c->readChrPlanar = planar_rgb12le_to_uv; break; @@ -825,6 +826,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_GBRP10BE: c->readChrPlanar = planar_rgb10be_to_uv; break; + case AV_PIX_FMT_GBRAP12BE: case AV_PIX_FMT_GBRP12BE: c->readChrPlanar = planar_rgb12be_to_uv; break; @@ -1041,6 +1043,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_GBRP10LE: c->readLumPlanar = planar_rgb10le_to_y; break; + case AV_PIX_FMT_GBRAP12LE: case AV_PIX_FMT_GBRP12LE: c->readLumPlanar = planar_rgb12le_to_y; break; @@ -1054,6 +1057,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_GBRP10BE: c->readLumPlanar = planar_rgb10be_to_y; break; + case AV_PIX_FMT_GBRAP12BE: case AV_PIX_FMT_GBRP12BE: c->readLumPlanar = planar_rgb12be_to_y; break; diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index ad87bbcb46db0..24c65ccd22d5b 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -1099,6 +1099,7 @@ void ff_get_unscaled_swscale(SwsContext *c) IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGRA64) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GRAY16) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YA16) || + IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRAP12)|| IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRAP16)|| IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB444) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB48) || diff --git a/libswscale/utils.c b/libswscale/utils.c index ad5518acfc957..5c7d6316ca6d7 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -189,6 +189,8 @@ static const FormatEntry format_entries[AV_PIX_FMT_NB] = { [AV_PIX_FMT_GBRP16LE] = { 1, 0 }, [AV_PIX_FMT_GBRP16BE] = { 1, 0 }, [AV_PIX_FMT_GBRAP] = { 1, 1 }, + [AV_PIX_FMT_GBRAP12LE] = { 1, 0 }, + [AV_PIX_FMT_GBRAP12BE] = { 1, 0 }, [AV_PIX_FMT_GBRAP16LE] = { 1, 0 }, [AV_PIX_FMT_GBRAP16BE] = { 1, 0 }, [AV_PIX_FMT_XYZ12BE] = { 0, 0, 1 }, From 881477c77bb10c3c62fda111b0f1f3554968bc78 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Wed, 12 Oct 2016 21:30:34 +0200 Subject: [PATCH 0290/3374] swscale: Add the GBRAP12 output --- libswscale/output.c | 2 ++ libswscale/utils.c | 4 ++-- tests/ref/fate/filter-pixdesc-gbrap12be | 1 + tests/ref/fate/filter-pixdesc-gbrap12le | 1 + tests/ref/fate/filter-pixfmts-copy | 2 ++ tests/ref/fate/filter-pixfmts-null | 2 ++ tests/ref/fate/filter-pixfmts-scale | 2 ++ tests/ref/fate/filter-pixfmts-vflip | 2 ++ 8 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 tests/ref/fate/filter-pixdesc-gbrap12be create mode 100644 tests/ref/fate/filter-pixdesc-gbrap12le diff --git a/libswscale/output.c b/libswscale/output.c index a8845f56ace48..d0c303c3a8327 100644 --- a/libswscale/output.c +++ b/libswscale/output.c @@ -1457,6 +1457,8 @@ av_cold void ff_sws_init_output_funcs(SwsContext *c, case AV_PIX_FMT_GBRP10LE: case AV_PIX_FMT_GBRP12BE: case AV_PIX_FMT_GBRP12LE: + case AV_PIX_FMT_GBRAP12BE: + case AV_PIX_FMT_GBRAP12LE: case AV_PIX_FMT_GBRP16BE: case AV_PIX_FMT_GBRP16LE: case AV_PIX_FMT_GBRAP: diff --git a/libswscale/utils.c b/libswscale/utils.c index 5c7d6316ca6d7..1c3bbb3305dde 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -189,8 +189,8 @@ static const FormatEntry format_entries[AV_PIX_FMT_NB] = { [AV_PIX_FMT_GBRP16LE] = { 1, 0 }, [AV_PIX_FMT_GBRP16BE] = { 1, 0 }, [AV_PIX_FMT_GBRAP] = { 1, 1 }, - [AV_PIX_FMT_GBRAP12LE] = { 1, 0 }, - [AV_PIX_FMT_GBRAP12BE] = { 1, 0 }, + [AV_PIX_FMT_GBRAP12LE] = { 1, 1 }, + [AV_PIX_FMT_GBRAP12BE] = { 1, 1 }, [AV_PIX_FMT_GBRAP16LE] = { 1, 0 }, [AV_PIX_FMT_GBRAP16BE] = { 1, 0 }, [AV_PIX_FMT_XYZ12BE] = { 0, 0, 1 }, diff --git a/tests/ref/fate/filter-pixdesc-gbrap12be b/tests/ref/fate/filter-pixdesc-gbrap12be new file mode 100644 index 0000000000000..6e27632b1a60e --- /dev/null +++ b/tests/ref/fate/filter-pixdesc-gbrap12be @@ -0,0 +1 @@ +pixdesc-gbrap12be a8ce4f5a7578f260399f86f92ae2a7be diff --git a/tests/ref/fate/filter-pixdesc-gbrap12le b/tests/ref/fate/filter-pixdesc-gbrap12le new file mode 100644 index 0000000000000..b6537a57f6169 --- /dev/null +++ b/tests/ref/fate/filter-pixdesc-gbrap12le @@ -0,0 +1 @@ +pixdesc-gbrap12le c14ff0058c8b1ccdb880386d7f9804e5 diff --git a/tests/ref/fate/filter-pixfmts-copy b/tests/ref/fate/filter-pixfmts-copy index 97acc0928aba2..d9a5166e11740 100644 --- a/tests/ref/fate/filter-pixfmts-copy +++ b/tests/ref/fate/filter-pixfmts-copy @@ -13,6 +13,8 @@ bgr565le 6a0d182c7165103b2613d1805c822f9f bgr8 36b9ef72c87da36ac547202d85a5805f bgra 56e6e1bfde40aaa27473e01b46345c82 gbrap 57cb1a02d6f015a4329fe367f3bdfe49 +gbrap12be df4b550099df0702f602a8b305702a8c +gbrap12le f947c43e494ab87410dfb2547e7e22f2 gbrp d5f73b5d3ba7f6cadbc9b4ecbc161005 gbrp10be eb19bda60ab7f893198364dff21342d6 gbrp10le 546146efb36ad2605e9f74ee5e4c2a36 diff --git a/tests/ref/fate/filter-pixfmts-null b/tests/ref/fate/filter-pixfmts-null index 97acc0928aba2..d9a5166e11740 100644 --- a/tests/ref/fate/filter-pixfmts-null +++ b/tests/ref/fate/filter-pixfmts-null @@ -13,6 +13,8 @@ bgr565le 6a0d182c7165103b2613d1805c822f9f bgr8 36b9ef72c87da36ac547202d85a5805f bgra 56e6e1bfde40aaa27473e01b46345c82 gbrap 57cb1a02d6f015a4329fe367f3bdfe49 +gbrap12be df4b550099df0702f602a8b305702a8c +gbrap12le f947c43e494ab87410dfb2547e7e22f2 gbrp d5f73b5d3ba7f6cadbc9b4ecbc161005 gbrp10be eb19bda60ab7f893198364dff21342d6 gbrp10le 546146efb36ad2605e9f74ee5e4c2a36 diff --git a/tests/ref/fate/filter-pixfmts-scale b/tests/ref/fate/filter-pixfmts-scale index b6f38b4299923..142b6371aac86 100644 --- a/tests/ref/fate/filter-pixfmts-scale +++ b/tests/ref/fate/filter-pixfmts-scale @@ -13,6 +13,8 @@ bgr565le 34438643c183ff1748cf7d71453f981c bgr8 e731ba3dbec294e1daa7313e08e88034 bgra 6e1f417ae41636f631de1cfe39ce1778 gbrap eefdbfd1426765ce5e9790022533db0d +gbrap12be c676f72b634c77b08a00ab12dc21c5dc +gbrap12le 90ca5271960dc1ebd6ebe14189223e36 gbrp 5d14768d2ab6cbf3879966b5d5c6befb gbrp10be 4192c246f4a52ec7a37919665190cce9 gbrp10le 170189b2c2dd46f31165d8fa6cadef0a diff --git a/tests/ref/fate/filter-pixfmts-vflip b/tests/ref/fate/filter-pixfmts-vflip index 6f633c6c9a021..93a292d6bc531 100644 --- a/tests/ref/fate/filter-pixfmts-vflip +++ b/tests/ref/fate/filter-pixfmts-vflip @@ -13,6 +13,8 @@ bgr565le 6f98ccb05e608863ef0912b9a6fd960b bgr8 1f916a75563e6be42c056e7d973a7356 bgra dd8eaea69683884ea45bf2fb635ce415 gbrap 38e04cbd4dc5566586d58ffed0c6b20d +gbrap12be c53126e45593f2e49451c9c9f58cffac +gbrap12le 6d5b3a8f8aae74f3542a63bcd1179a6c gbrp 37954476d089b5b74b06891e64ad6b9e gbrp10be ec01c15ed248a72c42f84a2a8cfec56f gbrp10le be52e72a59d87a43727262bcd90967cd From c9527bf3444c5332fa04931d32997308784fc862 Mon Sep 17 00:00:00 2001 From: Sean McGovern Date: Fri, 14 Oct 2016 13:52:51 -0400 Subject: [PATCH 0291/3374] Make the RELEASE file match with the most recent tag --- RELEASE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASE b/RELEASE index 8053ae93a5e4b..238ce5fc4525e 100644 --- a/RELEASE +++ b/RELEASE @@ -1 +1 @@ -12_alpha1 +13_dev0 From 7395784ba72742b6daa62d35db4028e09f3fdf06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 13 Oct 2016 15:24:54 +0300 Subject: [PATCH 0292/3374] rtmpproto: Check the return from ff_amf_read_string MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If this failed, we used to continue with an uninitialized filename buffer. CC: libav-stable@libav.org Signed-off-by: Martin Storsjö --- libavformat/rtmpproto.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index e7e2479f04e66..64024259e2ca5 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -1918,6 +1918,13 @@ static int send_invoke_response(URLContext *s, RTMPPacket *pkt) !strcmp(command, "publish")) { ret = ff_amf_read_string(&gbc, filename, sizeof(filename), &stringlen); + if (ret) { + if (ret == AVERROR(EINVAL)) + av_log(s, AV_LOG_ERROR, "Unable to parse stream name - name too long?\n"); + else + av_log(s, AV_LOG_ERROR, "Unable to parse stream name\n"); + return ret; + } // check with url if (s->filename) { pchar = strrchr(s->filename, '/'); From d6ded94036e43a04889f4ff2813a7f7dd60b82fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 13 Oct 2016 15:25:33 +0300 Subject: [PATCH 0293/3374] rtmpproto: Lengthen the filename buffer when receiving streams MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some applications such as Adobe FME append lots of parameters here, making it easily overflow the current limit. Signed-off-by: Martin Storsjö --- libavformat/rtmpproto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 64024259e2ca5..8817744e8799e 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -1891,7 +1891,7 @@ static int send_invoke_response(URLContext *s, RTMPPacket *pkt) { RTMPContext *rt = s->priv_data; double seqnum; - char filename[64]; + char filename[128]; char command[64]; int stringlen; char *pchar; From 8b5e0d17e70400eaf5dc3845b5c1df8b2b88d830 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 13 Oct 2016 16:17:11 +0300 Subject: [PATCH 0294/3374] rtmpproto: Send chunk size on the network channel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes sure that e.g. Adobe FME actually reacts to it. As long as the value we've been sending is the default one (128), the bug hasn't been noticed. Signed-off-by: Martin Storsjö --- libavformat/rtmpproto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 8817744e8799e..4107b461d1849 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -492,7 +492,7 @@ static int read_connect(URLContext *s, RTMPContext *rt) return ret; // Chunk size - if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, + if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_CHUNK_SIZE, 0, 4)) < 0) return ret; From 9f23f77a532ca9c2b7dc4b5328bc413e4f6f5b56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 14 Oct 2016 11:30:12 +0300 Subject: [PATCH 0295/3374] rtmpproto: Don't include the libavformat version as "clientid" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When acting as server, the server can include a "clientid" property in some status messages. But this should be a unique number identifying the client session, not identifying the server itself. In practice, omitting it works just as well as including this incorrect field. Signed-off-by: Martin Storsjö --- libavformat/rtmpproto.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 4107b461d1849..0097841e8109a 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -1874,9 +1874,6 @@ static int write_status(URLContext *s, RTMPPacket *pkt, ff_amf_write_string(&pp, statusmsg); ff_amf_write_field_name(&pp, "details"); ff_amf_write_string(&pp, filename); - ff_amf_write_field_name(&pp, "clientid"); - snprintf(statusmsg, sizeof(statusmsg), "%s", LIBAVFORMAT_IDENT); - ff_amf_write_string(&pp, statusmsg); ff_amf_write_object_end(&pp); spkt.size = pp - spkt.data; From 7d8d726be7dc46343ab1c98c339c1ed44bcb07c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 14 Oct 2016 15:55:52 +0300 Subject: [PATCH 0296/3374] rtmpproto: Don't include a client version in the unencrypted C1 handshake MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the public RTMP specification, these 4 bytes should be zero. librtmp in server mode assumes that the RTMPE (FP9) handshake is used if these bytes are nonzero. Signed-off-by: Martin Storsjö --- libavformat/rtmpproto.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 0097841e8109a..1ffc79a8cee7a 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -1198,10 +1198,7 @@ static int rtmp_handshake(URLContext *s, RTMPContext *rt) uint8_t tosend [RTMP_HANDSHAKE_PACKET_SIZE+1] = { 3, // unencrypted data 0, 0, 0, 0, // client uptime - RTMP_CLIENT_VER1, - RTMP_CLIENT_VER2, - RTMP_CLIENT_VER3, - RTMP_CLIENT_VER4, + 0, 0, 0, 0, // zeros }; uint8_t clientdata[RTMP_HANDSHAKE_PACKET_SIZE]; uint8_t serverdata[RTMP_HANDSHAKE_PACKET_SIZE+1]; From 20b75970e43a030f959b17ff2dfd561174b6f24e Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 13 Oct 2016 10:03:18 +0200 Subject: [PATCH 0297/3374] file protocol: handle the file: protocol string in file_check This is consistent with what file_open() does. CC: libav-stable@libav.org --- libavformat/file.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libavformat/file.c b/libavformat/file.c index 8683c1beddf4f..27ce4de6eb6ae 100644 --- a/libavformat/file.c +++ b/libavformat/file.c @@ -82,8 +82,13 @@ static int file_get_handle(URLContext *h) static int file_check(URLContext *h, int mask) { + const char *filename = h->filename; struct stat st; - int ret = stat(h->filename, &st); + int ret; + + av_strstart(filename, "file:", &filename); + + ret = stat(filename, &st); if (ret < 0) return AVERROR(errno); From 6c31ba226968f12f898120dbb928dab34e03782b Mon Sep 17 00:00:00 2001 From: James Almer Date: Thu, 13 Oct 2016 10:53:41 -0300 Subject: [PATCH 0298/3374] avformat/matroska: fix MatroskaVideoFieldOrder enum values The spec says 9: Interlaced with bottom field displayed first and top field stored first 14: Interlaced with top field displayed first and bottom field stored first And avcodec.h states AV_FIELD_TB, //< Top coded first, bottom displayed first AV_FIELD_BT, //< Bottom coded first, top displayed first Signed-off-by: James Almer Signed-off-by: Anton Khirnov --- libavformat/matroska.h | 4 ++-- libavformat/version.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libavformat/matroska.h b/libavformat/matroska.h index a13de18ef10d7..91bb978422658 100644 --- a/libavformat/matroska.h +++ b/libavformat/matroska.h @@ -233,8 +233,8 @@ typedef enum { MATROSKA_VIDEO_FIELDORDER_UNDETERMINED = 2, MATROSKA_VIDEO_FIELDORDER_TT = 1, MATROSKA_VIDEO_FIELDORDER_BB = 6, - MATROSKA_VIDEO_FIELDORDER_BT = 9, - MATROSKA_VIDEO_FIELDORDER_TB = 14, + MATROSKA_VIDEO_FIELDORDER_TB = 9, + MATROSKA_VIDEO_FIELDORDER_BT = 14, } MatroskaVideoFieldOrder; typedef enum { diff --git a/libavformat/version.h b/libavformat/version.h index a6643a9e25b64..c329c2f3024b0 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFORMAT_VERSION_MAJOR 57 -#define LIBAVFORMAT_VERSION_MINOR 8 +#define LIBAVFORMAT_VERSION_MINOR 9 #define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ From 4abe3b049d987420eb891f74a35af2cebbf52144 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 21 Aug 2016 17:14:24 +0200 Subject: [PATCH 0299/3374] hevc: rename hevc.[ch] to hevcdec.[ch] This is more consistent with the rest of libav and frees up the hevc.h name for decoder-independent shared declarations. --- libavcodec/Makefile | 2 +- libavcodec/dxva2_hevc.c | 2 +- libavcodec/hevc_cabac.c | 2 +- libavcodec/hevc_data.c | 2 +- libavcodec/hevc_filter.c | 2 +- libavcodec/hevc_mp4toannexb_bsf.c | 2 +- libavcodec/hevc_mvs.c | 2 +- libavcodec/hevc_parser.c | 2 +- libavcodec/hevc_ps.c | 2 +- libavcodec/hevc_ps_enc.c | 2 +- libavcodec/hevc_refs.c | 2 +- libavcodec/hevc_sei.c | 2 +- libavcodec/{hevc.c => hevcdec.c} | 2 +- libavcodec/{hevc.h => hevcdec.h} | 6 +++--- libavcodec/hevcdsp_template.c | 2 +- libavcodec/hevcpred.c | 2 +- libavcodec/hevcpred_template.c | 2 +- libavcodec/qsvenc_hevc.c | 2 +- libavcodec/vaapi_encode_h265.c | 2 +- libavcodec/vdpau_hevc.c | 2 +- libavformat/hevc.c | 2 +- libavformat/hevcdec.c | 2 +- 22 files changed, 24 insertions(+), 24 deletions(-) rename libavcodec/{hevc.c => hevcdec.c} (99%) rename libavcodec/{hevc.h => hevcdec.h} (99%) diff --git a/libavcodec/Makefile b/libavcodec/Makefile index bec461b80c0e4..d4579f9b97ab5 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -264,7 +264,7 @@ OBJS-$(CONFIG_H264_QSV_ENCODER) += qsvenc_h264.o OBJS-$(CONFIG_H264_VAAPI_ENCODER) += vaapi_encode_h264.o vaapi_encode_h26x.o OBJS-$(CONFIG_HAP_DECODER) += hapdec.o hap.o OBJS-$(CONFIG_HAP_ENCODER) += hapenc.o hap.o -OBJS-$(CONFIG_HEVC_DECODER) += hevc.o hevc_mvs.o hevc_ps.o hevc_sei.o \ +OBJS-$(CONFIG_HEVC_DECODER) += hevcdec.o hevc_mvs.o hevc_ps.o hevc_sei.o \ hevc_cabac.o hevc_refs.o hevcpred.o \ hevcdsp.o hevc_filter.o h2645_parse.o hevc_data.o OBJS-$(CONFIG_HEVC_NVENC_ENCODER) += nvenc_hevc.o diff --git a/libavcodec/dxva2_hevc.c b/libavcodec/dxva2_hevc.c index 5bb10d6916852..53fd638d102b6 100644 --- a/libavcodec/dxva2_hevc.c +++ b/libavcodec/dxva2_hevc.c @@ -22,7 +22,7 @@ #include "libavutil/avassert.h" -#include "hevc.h" +#include "hevcdec.h" // The headers above may include w32threads.h, which uses the original // _WIN32_WINNT define, while dxva2_internal.h redefines it to target a diff --git a/libavcodec/hevc_cabac.c b/libavcodec/hevc_cabac.c index b01808fd84b2c..eb16f57cd86f9 100644 --- a/libavcodec/hevc_cabac.c +++ b/libavcodec/hevc_cabac.c @@ -25,7 +25,7 @@ #include "libavutil/common.h" #include "cabac_functions.h" -#include "hevc.h" +#include "hevcdec.h" #define CABAC_MAX_BIN 31 diff --git a/libavcodec/hevc_data.c b/libavcodec/hevc_data.c index f4b6096aec3e4..7976c34156285 100644 --- a/libavcodec/hevc_data.c +++ b/libavcodec/hevc_data.c @@ -20,7 +20,7 @@ #include -#include "hevc.h" +#include "hevcdec.h" const uint8_t ff_hevc_diag_scan4x4_x[16] = { 0, 0, 1, 0, diff --git a/libavcodec/hevc_filter.c b/libavcodec/hevc_filter.c index 5037dae7cdf0c..4b71a8921268c 100644 --- a/libavcodec/hevc_filter.c +++ b/libavcodec/hevc_filter.c @@ -26,7 +26,7 @@ #include "libavutil/internal.h" #include "cabac_functions.h" -#include "hevc.h" +#include "hevcdec.h" #define LUMA 0 #define CB 1 diff --git a/libavcodec/hevc_mp4toannexb_bsf.c b/libavcodec/hevc_mp4toannexb_bsf.c index 8d7ac58f19598..f364fbd161845 100644 --- a/libavcodec/hevc_mp4toannexb_bsf.c +++ b/libavcodec/hevc_mp4toannexb_bsf.c @@ -27,7 +27,7 @@ #include "avcodec.h" #include "bsf.h" #include "bytestream.h" -#include "hevc.h" +#include "hevcdec.h" #define MIN_HEVCC_LENGTH 23 diff --git a/libavcodec/hevc_mvs.c b/libavcodec/hevc_mvs.c index 446b83a76289f..90aff9758e271 100644 --- a/libavcodec/hevc_mvs.c +++ b/libavcodec/hevc_mvs.c @@ -21,7 +21,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "hevc.h" +#include "hevcdec.h" static const uint8_t l0_l1_cand_idx[12][2] = { { 0, 1, }, diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c index dc5fffcb0b5cd..b68ceb985e29e 100644 --- a/libavcodec/hevc_parser.c +++ b/libavcodec/hevc_parser.c @@ -23,7 +23,7 @@ #include "libavutil/common.h" #include "golomb.h" -#include "hevc.h" +#include "hevcdec.h" #include "h2645_parse.h" #include "parser.h" diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index 5c249d88fc03c..b7b2ea92513f3 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -26,7 +26,7 @@ #include "libavutil/imgutils.h" #include "golomb.h" -#include "hevc.h" +#include "hevcdec.h" static const uint8_t default_scaling_list_intra[] = { 16, 16, 16, 16, 17, 18, 21, 24, diff --git a/libavcodec/hevc_ps_enc.c b/libavcodec/hevc_ps_enc.c index 007a1321ed8df..fdf9fb7f40bc5 100644 --- a/libavcodec/hevc_ps_enc.c +++ b/libavcodec/hevc_ps_enc.c @@ -19,7 +19,7 @@ */ #include "golomb.h" -#include "hevc.h" +#include "hevcdec.h" #include "put_bits.h" static void write_ptl_layer(PutBitContext *pb, PTLCommon *ptl) diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c index b51f2594a1869..3e056da0a91ac 100644 --- a/libavcodec/hevc_refs.c +++ b/libavcodec/hevc_refs.c @@ -26,7 +26,7 @@ #include "internal.h" #include "thread.h" -#include "hevc.h" +#include "hevcdec.h" void ff_hevc_unref_frame(HEVCContext *s, HEVCFrame *frame, int flags) { diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c index 17cef6743db40..37c80647d64be 100644 --- a/libavcodec/hevc_sei.c +++ b/libavcodec/hevc_sei.c @@ -23,7 +23,7 @@ */ #include "golomb.h" -#include "hevc.h" +#include "hevcdec.h" enum HEVC_SEI_TYPE { SEI_TYPE_BUFFERING_PERIOD = 0, diff --git a/libavcodec/hevc.c b/libavcodec/hevcdec.c similarity index 99% rename from libavcodec/hevc.c rename to libavcodec/hevcdec.c index e38d36711e328..2afd638723d88 100644 --- a/libavcodec/hevc.c +++ b/libavcodec/hevcdec.c @@ -36,7 +36,7 @@ #include "bytestream.h" #include "cabac_functions.h" #include "golomb.h" -#include "hevc.h" +#include "hevcdec.h" #include "profiles.h" const uint8_t ff_hevc_qpel_extra_before[4] = { 0, 3, 3, 3 }; diff --git a/libavcodec/hevc.h b/libavcodec/hevcdec.h similarity index 99% rename from libavcodec/hevc.h rename to libavcodec/hevcdec.h index d15af7198603d..ba261e6fec5d2 100644 --- a/libavcodec/hevc.h +++ b/libavcodec/hevcdec.h @@ -20,8 +20,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef AVCODEC_HEVC_H -#define AVCODEC_HEVC_H +#ifndef AVCODEC_HEVCDEC_H +#define AVCODEC_HEVCDEC_H #include #include @@ -1013,4 +1013,4 @@ extern const uint8_t ff_hevc_diag_scan4x4_y[16]; extern const uint8_t ff_hevc_diag_scan8x8_x[64]; extern const uint8_t ff_hevc_diag_scan8x8_y[64]; -#endif /* AVCODEC_HEVC_H */ +#endif /* AVCODEC_HEVCDEC_H */ diff --git a/libavcodec/hevcdsp_template.c b/libavcodec/hevcdsp_template.c index cd55571290216..97ce34a0ad026 100644 --- a/libavcodec/hevcdsp_template.c +++ b/libavcodec/hevcdsp_template.c @@ -21,7 +21,7 @@ */ #include "get_bits.h" -#include "hevc.h" +#include "hevcdec.h" #include "bit_depth_template.c" diff --git a/libavcodec/hevcpred.c b/libavcodec/hevcpred.c index 1ba2487a62e2f..7342b7e2ef78a 100644 --- a/libavcodec/hevcpred.c +++ b/libavcodec/hevcpred.c @@ -20,7 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "hevc.h" +#include "hevcdec.h" #define BIT_DEPTH 8 #include "hevcpred_template.c" diff --git a/libavcodec/hevcpred_template.c b/libavcodec/hevcpred_template.c index 039882bb5250c..5fe3ea39cae42 100644 --- a/libavcodec/hevcpred_template.c +++ b/libavcodec/hevcpred_template.c @@ -22,7 +22,7 @@ #include "libavutil/pixdesc.h" -#include "hevc.h" +#include "hevcdec.h" #include "bit_depth_template.c" diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c index ddb2a42ed6124..24af82c8c5144 100644 --- a/libavcodec/qsvenc_hevc.c +++ b/libavcodec/qsvenc_hevc.c @@ -30,7 +30,7 @@ #include "avcodec.h" #include "bytestream.h" #include "get_bits.h" -#include "hevc.h" +#include "hevcdec.h" #include "h2645_parse.h" #include "internal.h" #include "qsv.h" diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c index 8715d307dccfb..4853a5bbebedd 100644 --- a/libavcodec/vaapi_encode_h265.c +++ b/libavcodec/vaapi_encode_h265.c @@ -25,7 +25,7 @@ #include "libavutil/pixfmt.h" #include "avcodec.h" -#include "hevc.h" +#include "hevcdec.h" #include "internal.h" #include "put_bits.h" #include "vaapi_encode.h" diff --git a/libavcodec/vdpau_hevc.c b/libavcodec/vdpau_hevc.c index 1e5fb71cce840..9f2baa75b1418 100644 --- a/libavcodec/vdpau_hevc.c +++ b/libavcodec/vdpau_hevc.c @@ -24,7 +24,7 @@ #include "avcodec.h" #include "internal.h" -#include "hevc.h" +#include "hevcdec.h" #include "vdpau.h" #include "vdpau_internal.h" diff --git a/libavformat/hevc.c b/libavformat/hevc.c index c835f2243e0c9..b3a3603c0e0cd 100644 --- a/libavformat/hevc.c +++ b/libavformat/hevc.c @@ -20,7 +20,7 @@ #include "libavcodec/get_bits.h" #include "libavcodec/golomb.h" -#include "libavcodec/hevc.h" +#include "libavcodec/hevcdec.h" #include "libavutil/intreadwrite.h" #include "avc.h" #include "avio.h" diff --git a/libavformat/hevcdec.c b/libavformat/hevcdec.c index 65a3cdfb3c26b..75b2cd3916bc8 100644 --- a/libavformat/hevcdec.c +++ b/libavformat/hevcdec.c @@ -19,7 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "libavcodec/hevc.h" +#include "libavcodec/hevcdec.h" #include "avformat.h" #include "rawdec.h" From c359d624d3efc3fd1d83210d78c4152bd329b765 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 21 Aug 2016 17:35:28 +0200 Subject: [PATCH 0300/3374] hevcdec: move decoder-independent declarations into a separate header This way they can be reused by other code without including the whole decoder-specific hevcdec.h Also, add the HEVC_ prefix to them, since similarly named values exist for H.264 as well and are sometimes used in the same code. --- libavcodec/hevc.h | 65 ++++++++++++++++++++++++++ libavcodec/hevc_mp4toannexb_bsf.c | 6 +-- libavcodec/hevc_parser.c | 51 ++++++++++---------- libavcodec/hevc_ps.c | 16 +++---- libavcodec/hevc_refs.c | 7 +-- libavcodec/hevc_sei.c | 2 +- libavcodec/hevcdec.c | 77 ++++++++++++++++--------------- libavcodec/hevcdec.h | 74 +++++++---------------------- libavcodec/qsvenc_hevc.c | 11 +++-- libavcodec/vaapi_encode_h265.c | 22 ++++----- libavformat/hevc.c | 59 +++++++++++------------ libavformat/hevcdec.c | 20 ++++---- 12 files changed, 220 insertions(+), 190 deletions(-) create mode 100644 libavcodec/hevc.h diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h new file mode 100644 index 0000000000000..66816b840946e --- /dev/null +++ b/libavcodec/hevc.h @@ -0,0 +1,65 @@ +/* + * HEVC shared code + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_HEVC_H +#define AVCODEC_HEVC_H + +/** + * Table 7-3: NAL unit type codes + */ +enum HEVCNALUnitType { + HEVC_NAL_TRAIL_N = 0, + HEVC_NAL_TRAIL_R = 1, + HEVC_NAL_TSA_N = 2, + HEVC_NAL_TSA_R = 3, + HEVC_NAL_STSA_N = 4, + HEVC_NAL_STSA_R = 5, + HEVC_NAL_RADL_N = 6, + HEVC_NAL_RADL_R = 7, + HEVC_NAL_RASL_N = 8, + HEVC_NAL_RASL_R = 9, + HEVC_NAL_BLA_W_LP = 16, + HEVC_NAL_BLA_W_RADL = 17, + HEVC_NAL_BLA_N_LP = 18, + HEVC_NAL_IDR_W_RADL = 19, + HEVC_NAL_IDR_N_LP = 20, + HEVC_NAL_CRA_NUT = 21, + HEVC_NAL_VPS = 32, + HEVC_NAL_SPS = 33, + HEVC_NAL_PPS = 34, + HEVC_NAL_AUD = 35, + HEVC_NAL_EOS_NUT = 36, + HEVC_NAL_EOB_NUT = 37, + HEVC_NAL_FD_NUT = 38, + HEVC_NAL_SEI_PREFIX = 39, + HEVC_NAL_SEI_SUFFIX = 40, +}; + +/** + * 7.4.2.1 + */ +#define HEVC_MAX_SUB_LAYERS 7 +#define HEVC_MAX_VPS_COUNT 16 +#define HEVC_MAX_SPS_COUNT 32 +#define HEVC_MAX_PPS_COUNT 256 +#define HEVC_MAX_SHORT_TERM_RPS_COUNT 64 +#define HEVC_MAX_CU_SIZE 128 + +#endif /* AVCODEC_HEVC_H */ diff --git a/libavcodec/hevc_mp4toannexb_bsf.c b/libavcodec/hevc_mp4toannexb_bsf.c index f364fbd161845..d6b1f00047a44 100644 --- a/libavcodec/hevc_mp4toannexb_bsf.c +++ b/libavcodec/hevc_mp4toannexb_bsf.c @@ -27,7 +27,7 @@ #include "avcodec.h" #include "bsf.h" #include "bytestream.h" -#include "hevcdec.h" +#include "hevc.h" #define MIN_HEVCC_LENGTH 23 @@ -55,8 +55,8 @@ static int hevc_extradata_to_annexb(AVBSFContext *ctx) int type = bytestream2_get_byte(&gb) & 0x3f; int cnt = bytestream2_get_be16(&gb); - if (!(type == NAL_VPS || type == NAL_SPS || type == NAL_PPS || - type == NAL_SEI_PREFIX || type == NAL_SEI_SUFFIX)) { + if (!(type == HEVC_NAL_VPS || type == HEVC_NAL_SPS || type == HEVC_NAL_PPS || + type == HEVC_NAL_SEI_PREFIX || type == HEVC_NAL_SEI_SUFFIX)) { av_log(ctx, AV_LOG_ERROR, "Invalid NAL unit type in extradata: %d\n", type); ret = AVERROR_INVALIDDATA; diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c index b68ceb985e29e..49e712269bd6c 100644 --- a/libavcodec/hevc_parser.c +++ b/libavcodec/hevc_parser.c @@ -23,6 +23,7 @@ #include "libavutil/common.h" #include "golomb.h" +#include "hevc.h" #include "hevcdec.h" #include "h2645_parse.h" #include "parser.h" @@ -55,7 +56,7 @@ static int hevc_parse_slice_header(AVCodecParserContext *s, H2645NAL *nal, get_bits1(gb); // no output of prior pics pps_id = get_ue_golomb_long(gb); - if (pps_id >= MAX_PPS_COUNT || !ctx->ps.pps_list[pps_id]) { + if (pps_id >= HEVC_MAX_PPS_COUNT || !ctx->ps.pps_list[pps_id]) { av_log(avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", pps_id); return AVERROR_INVALIDDATA; } @@ -92,25 +93,25 @@ static int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf, /* ignore everything except parameter sets and VCL NALUs */ switch (nal->type) { - case NAL_VPS: ff_hevc_decode_nal_vps(&nal->gb, avctx, &ctx->ps); break; - case NAL_SPS: ff_hevc_decode_nal_sps(&nal->gb, avctx, &ctx->ps, 1); break; - case NAL_PPS: ff_hevc_decode_nal_pps(&nal->gb, avctx, &ctx->ps); break; - case NAL_TRAIL_R: - case NAL_TRAIL_N: - case NAL_TSA_N: - case NAL_TSA_R: - case NAL_STSA_N: - case NAL_STSA_R: - case NAL_BLA_W_LP: - case NAL_BLA_W_RADL: - case NAL_BLA_N_LP: - case NAL_IDR_W_RADL: - case NAL_IDR_N_LP: - case NAL_CRA_NUT: - case NAL_RADL_N: - case NAL_RADL_R: - case NAL_RASL_N: - case NAL_RASL_R: hevc_parse_slice_header(s, nal, avctx); break; + case HEVC_NAL_VPS: ff_hevc_decode_nal_vps(&nal->gb, avctx, &ctx->ps); break; + case HEVC_NAL_SPS: ff_hevc_decode_nal_sps(&nal->gb, avctx, &ctx->ps, 1); break; + case HEVC_NAL_PPS: ff_hevc_decode_nal_pps(&nal->gb, avctx, &ctx->ps); break; + case HEVC_NAL_TRAIL_R: + case HEVC_NAL_TRAIL_N: + case HEVC_NAL_TSA_N: + case HEVC_NAL_TSA_R: + case HEVC_NAL_STSA_N: + case HEVC_NAL_STSA_R: + case HEVC_NAL_BLA_W_LP: + case HEVC_NAL_BLA_W_RADL: + case HEVC_NAL_BLA_N_LP: + case HEVC_NAL_IDR_W_RADL: + case HEVC_NAL_IDR_N_LP: + case HEVC_NAL_CRA_NUT: + case HEVC_NAL_RADL_N: + case HEVC_NAL_RADL_R: + case HEVC_NAL_RASL_N: + case HEVC_NAL_RASL_R: hevc_parse_slice_header(s, nal, avctx); break; } } @@ -138,19 +139,19 @@ static int hevc_find_frame_end(AVCodecParserContext *s, const uint8_t *buf, nut = (pc->state64 >> 2 * 8 + 1) & 0x3F; // Beginning of access unit - if ((nut >= NAL_VPS && nut <= NAL_AUD) || nut == NAL_SEI_PREFIX || + if ((nut >= HEVC_NAL_VPS && nut <= HEVC_NAL_AUD) || nut == HEVC_NAL_SEI_PREFIX || (nut >= 41 && nut <= 44) || (nut >= 48 && nut <= 55)) { if (pc->frame_start_found) { pc->frame_start_found = 0; return i - 5; } - } else if (nut <= NAL_RASL_R || - (nut >= NAL_BLA_W_LP && nut <= NAL_CRA_NUT)) { + } else if (nut <= HEVC_NAL_RASL_R || + (nut >= HEVC_NAL_BLA_W_LP && nut <= HEVC_NAL_CRA_NUT)) { int first_slice_segment_in_pic_flag = buf[i] >> 7; if (first_slice_segment_in_pic_flag) { if (!pc->frame_start_found) { pc->frame_start_found = 1; - s->key_frame = nut >= NAL_BLA_W_LP && nut <= NAL_CRA_NUT; + s->key_frame = nut >= HEVC_NAL_BLA_W_LP && nut <= HEVC_NAL_CRA_NUT; } else { // First slice of next frame found pc->frame_start_found = 0; return i - 5; @@ -205,7 +206,7 @@ static int hevc_split(AVCodecContext *avctx, const uint8_t *buf, int buf_size) state = (state << 8) | buf[i]; if (((state >> 8) & 0xFFFFFF) == START_CODE) { int nut = (state >> 1) & 0x3F; - if (nut >= NAL_VPS && nut <= NAL_PPS) + if (nut >= HEVC_NAL_VPS && nut <= HEVC_NAL_PPS) has_ps = 1; else if (has_ps) return i - 3; diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index b7b2ea92513f3..520017bc6e78d 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -370,7 +370,7 @@ int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx, av_log(avctx, AV_LOG_DEBUG, "Decoding VPS\n"); vps_id = get_bits(gb, 4); - if (vps_id >= MAX_VPS_COUNT) { + if (vps_id >= HEVC_MAX_VPS_COUNT) { av_log(avctx, AV_LOG_ERROR, "VPS id out of range: %d\n", vps_id); goto err; } @@ -389,7 +389,7 @@ int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx, goto err; } - if (vps->vps_max_sub_layers > MAX_SUB_LAYERS) { + if (vps->vps_max_sub_layers > HEVC_MAX_SUB_LAYERS) { av_log(avctx, AV_LOG_ERROR, "vps_max_sub_layers out of range: %d\n", vps->vps_max_sub_layers); goto err; @@ -690,7 +690,7 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, // Coded parameters sps->vps_id = get_bits(gb, 4); - if (sps->vps_id >= MAX_VPS_COUNT) { + if (sps->vps_id >= HEVC_MAX_VPS_COUNT) { av_log(avctx, AV_LOG_ERROR, "VPS id out of range: %d\n", sps->vps_id); ret = AVERROR_INVALIDDATA; goto err; @@ -704,7 +704,7 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, } sps->max_sub_layers = get_bits(gb, 3) + 1; - if (sps->max_sub_layers > MAX_SUB_LAYERS) { + if (sps->max_sub_layers > HEVC_MAX_SUB_LAYERS) { av_log(avctx, AV_LOG_ERROR, "sps_max_sub_layers out of range: %d\n", sps->max_sub_layers); ret = AVERROR_INVALIDDATA; @@ -716,7 +716,7 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, parse_ptl(gb, avctx, &sps->ptl, sps->max_sub_layers); *sps_id = get_ue_golomb_long(gb); - if (*sps_id >= MAX_SPS_COUNT) { + if (*sps_id >= HEVC_MAX_SPS_COUNT) { av_log(avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", *sps_id); ret = AVERROR_INVALIDDATA; goto err; @@ -867,7 +867,7 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, } sps->nb_st_rps = get_ue_golomb_long(gb); - if (sps->nb_st_rps > MAX_SHORT_TERM_RPS_COUNT) { + if (sps->nb_st_rps > HEVC_MAX_SHORT_TERM_RPS_COUNT) { av_log(avctx, AV_LOG_ERROR, "Too many short term RPS: %d.\n", sps->nb_st_rps); ret = AVERROR_INVALIDDATA; @@ -1205,13 +1205,13 @@ int ff_hevc_decode_nal_pps(GetBitContext *gb, AVCodecContext *avctx, // Coded parameters pps_id = get_ue_golomb_long(gb); - if (pps_id >= MAX_PPS_COUNT) { + if (pps_id >= HEVC_MAX_PPS_COUNT) { av_log(avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", pps_id); ret = AVERROR_INVALIDDATA; goto err; } pps->sps_id = get_ue_golomb_long(gb); - if (pps->sps_id >= MAX_SPS_COUNT) { + if (pps->sps_id >= HEVC_MAX_SPS_COUNT) { av_log(avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", pps->sps_id); ret = AVERROR_INVALIDDATA; goto err; diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c index 3e056da0a91ac..82a115788783b 100644 --- a/libavcodec/hevc_refs.c +++ b/libavcodec/hevc_refs.c @@ -26,6 +26,7 @@ #include "internal.h" #include "thread.h" +#include "hevc.h" #include "hevcdec.h" void ff_hevc_unref_frame(HEVCContext *s, HEVCFrame *frame, int flags) @@ -477,9 +478,9 @@ int ff_hevc_compute_poc(HEVCContext *s, int poc_lsb) poc_msb = prev_poc_msb; // For BLA picture types, POCmsb is set to 0. - if (s->nal_unit_type == NAL_BLA_W_LP || - s->nal_unit_type == NAL_BLA_W_RADL || - s->nal_unit_type == NAL_BLA_N_LP) + if (s->nal_unit_type == HEVC_NAL_BLA_W_LP || + s->nal_unit_type == HEVC_NAL_BLA_W_RADL || + s->nal_unit_type == HEVC_NAL_BLA_N_LP) poc_msb = 0; return poc_msb + poc_lsb; diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c index 37c80647d64be..8865cecdeda99 100644 --- a/libavcodec/hevc_sei.c +++ b/libavcodec/hevc_sei.c @@ -168,7 +168,7 @@ static int decode_nal_sei_message(HEVCContext *s) byte = get_bits(gb, 8); payload_size += byte; } - if (s->nal_unit_type == NAL_SEI_PREFIX) { + if (s->nal_unit_type == HEVC_NAL_SEI_PREFIX) { return decode_nal_sei_prefix(s, payload_type, payload_size); } else { /* nal_unit_type == NAL_SEI_SUFFIX */ return decode_nal_sei_suffix(s, payload_type, payload_size); diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 2afd638723d88..1da43344a4cab 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -36,6 +36,7 @@ #include "bytestream.h" #include "cabac_functions.h" #include "golomb.h" +#include "hevc.h" #include "hevcdec.h" #include "profiles.h" @@ -461,7 +462,7 @@ static int hls_slice_header(HEVCContext *s) sh->no_output_of_prior_pics_flag = get_bits1(gb); sh->pps_id = get_ue_golomb_long(gb); - if (sh->pps_id >= MAX_PPS_COUNT || !s->ps.pps_list[sh->pps_id]) { + if (sh->pps_id >= HEVC_MAX_PPS_COUNT || !s->ps.pps_list[sh->pps_id]) { av_log(s->avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", sh->pps_id); return AVERROR_INVALIDDATA; } @@ -594,13 +595,13 @@ static int hls_slice_header(HEVCContext *s) /* 8.3.1 */ if (s->temporal_id == 0 && - s->nal_unit_type != NAL_TRAIL_N && - s->nal_unit_type != NAL_TSA_N && - s->nal_unit_type != NAL_STSA_N && - s->nal_unit_type != NAL_RADL_N && - s->nal_unit_type != NAL_RADL_R && - s->nal_unit_type != NAL_RASL_N && - s->nal_unit_type != NAL_RASL_R) + s->nal_unit_type != HEVC_NAL_TRAIL_N && + s->nal_unit_type != HEVC_NAL_TSA_N && + s->nal_unit_type != HEVC_NAL_STSA_N && + s->nal_unit_type != HEVC_NAL_RADL_N && + s->nal_unit_type != HEVC_NAL_RADL_R && + s->nal_unit_type != HEVC_NAL_RASL_N && + s->nal_unit_type != HEVC_NAL_RASL_R) s->pocTid0 = s->poc; if (s->ps.sps->sao_enabled) { @@ -2455,50 +2456,50 @@ static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal) s->temporal_id = nal->temporal_id; switch (s->nal_unit_type) { - case NAL_VPS: + case HEVC_NAL_VPS: ret = ff_hevc_decode_nal_vps(gb, s->avctx, &s->ps); if (ret < 0) goto fail; break; - case NAL_SPS: + case HEVC_NAL_SPS: ret = ff_hevc_decode_nal_sps(gb, s->avctx, &s->ps, s->apply_defdispwin); if (ret < 0) goto fail; break; - case NAL_PPS: + case HEVC_NAL_PPS: ret = ff_hevc_decode_nal_pps(gb, s->avctx, &s->ps); if (ret < 0) goto fail; break; - case NAL_SEI_PREFIX: - case NAL_SEI_SUFFIX: + case HEVC_NAL_SEI_PREFIX: + case HEVC_NAL_SEI_SUFFIX: ret = ff_hevc_decode_nal_sei(s); if (ret < 0) goto fail; break; - case NAL_TRAIL_R: - case NAL_TRAIL_N: - case NAL_TSA_N: - case NAL_TSA_R: - case NAL_STSA_N: - case NAL_STSA_R: - case NAL_BLA_W_LP: - case NAL_BLA_W_RADL: - case NAL_BLA_N_LP: - case NAL_IDR_W_RADL: - case NAL_IDR_N_LP: - case NAL_CRA_NUT: - case NAL_RADL_N: - case NAL_RADL_R: - case NAL_RASL_N: - case NAL_RASL_R: + case HEVC_NAL_TRAIL_R: + case HEVC_NAL_TRAIL_N: + case HEVC_NAL_TSA_N: + case HEVC_NAL_TSA_R: + case HEVC_NAL_STSA_N: + case HEVC_NAL_STSA_R: + case HEVC_NAL_BLA_W_LP: + case HEVC_NAL_BLA_W_RADL: + case HEVC_NAL_BLA_N_LP: + case HEVC_NAL_IDR_W_RADL: + case HEVC_NAL_IDR_N_LP: + case HEVC_NAL_CRA_NUT: + case HEVC_NAL_RADL_N: + case HEVC_NAL_RADL_R: + case HEVC_NAL_RASL_N: + case HEVC_NAL_RASL_R: ret = hls_slice_header(s); if (ret < 0) return ret; if (s->max_ra == INT_MAX) { - if (s->nal_unit_type == NAL_CRA_NUT || IS_BLA(s)) { + if (s->nal_unit_type == HEVC_NAL_CRA_NUT || IS_BLA(s)) { s->max_ra = s->poc; } else { if (IS_IDR(s)) @@ -2506,12 +2507,12 @@ static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal) } } - if ((s->nal_unit_type == NAL_RASL_R || s->nal_unit_type == NAL_RASL_N) && + if ((s->nal_unit_type == HEVC_NAL_RASL_R || s->nal_unit_type == HEVC_NAL_RASL_N) && s->poc <= s->max_ra) { s->is_decoded = 0; break; } else { - if (s->nal_unit_type == NAL_RASL_R && s->poc > s->max_ra) + if (s->nal_unit_type == HEVC_NAL_RASL_R && s->poc > s->max_ra) s->max_ra = INT_MIN; } @@ -2567,13 +2568,13 @@ static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal) } } break; - case NAL_EOS_NUT: - case NAL_EOB_NUT: + case HEVC_NAL_EOS_NUT: + case HEVC_NAL_EOB_NUT: s->seq_decode = (s->seq_decode + 1) & 0xff; s->max_ra = INT_MAX; break; - case NAL_AUD: - case NAL_FD_NUT: + case HEVC_NAL_AUD: + case HEVC_NAL_FD_NUT: break; default: av_log(s->avctx, AV_LOG_INFO, @@ -2605,8 +2606,8 @@ static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) } for (i = 0; i < s->pkt.nb_nals; i++) { - if (s->pkt.nals[i].type == NAL_EOB_NUT || - s->pkt.nals[i].type == NAL_EOS_NUT) + if (s->pkt.nals[i].type == HEVC_NAL_EOB_NUT || + s->pkt.nals[i].type == HEVC_NAL_EOS_NUT) s->eos = 1; } diff --git a/libavcodec/hevcdec.h b/libavcodec/hevcdec.h index ba261e6fec5d2..df81e55ed872a 100644 --- a/libavcodec/hevcdec.h +++ b/libavcodec/hevcdec.h @@ -34,6 +34,7 @@ #include "cabac.h" #include "get_bits.h" #include "h2645_parse.h" +#include "hevc.h" #include "hevcdsp.h" #include "internal.h" #include "thread.h" @@ -42,16 +43,6 @@ #define MAX_DPB_SIZE 16 // A.4.1 #define MAX_REFS 16 -/** - * 7.4.2.1 - */ -#define MAX_SUB_LAYERS 7 -#define MAX_VPS_COUNT 16 -#define MAX_SPS_COUNT 32 -#define MAX_PPS_COUNT 256 -#define MAX_SHORT_TERM_RPS_COUNT 64 -#define MAX_CU_SIZE 128 - //TODO: check if this is really the maximum #define MAX_TRANSFORM_DEPTH 5 @@ -80,45 +71,14 @@ #define SAMPLE(tab, x, y) ((tab)[(y) * s->sps->width + (x)]) #define SAMPLE_CTB(tab, x, y) ((tab)[(y) * min_cb_width + (x)]) -#define IS_IDR(s) (s->nal_unit_type == NAL_IDR_W_RADL || s->nal_unit_type == NAL_IDR_N_LP) -#define IS_BLA(s) (s->nal_unit_type == NAL_BLA_W_RADL || s->nal_unit_type == NAL_BLA_W_LP || \ - s->nal_unit_type == NAL_BLA_N_LP) +#define IS_IDR(s) (s->nal_unit_type == HEVC_NAL_IDR_W_RADL || s->nal_unit_type == HEVC_NAL_IDR_N_LP) +#define IS_BLA(s) (s->nal_unit_type == HEVC_NAL_BLA_W_RADL || s->nal_unit_type == HEVC_NAL_BLA_W_LP || \ + s->nal_unit_type == HEVC_NAL_BLA_N_LP) #define IS_IRAP(s) (s->nal_unit_type >= 16 && s->nal_unit_type <= 23) #define FFUDIV(a,b) (((a) > 0 ? (a) : (a) - (b) + 1) / (b)) #define FFUMOD(a,b) ((a) - (b) * FFUDIV(a,b)) -/** - * Table 7-3: NAL unit type codes - */ -enum NALUnitType { - NAL_TRAIL_N = 0, - NAL_TRAIL_R = 1, - NAL_TSA_N = 2, - NAL_TSA_R = 3, - NAL_STSA_N = 4, - NAL_STSA_R = 5, - NAL_RADL_N = 6, - NAL_RADL_R = 7, - NAL_RASL_N = 8, - NAL_RASL_R = 9, - NAL_BLA_W_LP = 16, - NAL_BLA_W_RADL = 17, - NAL_BLA_N_LP = 18, - NAL_IDR_W_RADL = 19, - NAL_IDR_N_LP = 20, - NAL_CRA_NUT = 21, - NAL_VPS = 32, - NAL_SPS = 33, - NAL_PPS = 34, - NAL_AUD = 35, - NAL_EOS_NUT = 36, - NAL_EOB_NUT = 37, - NAL_FD_NUT = 38, - NAL_SEI_PREFIX = 39, - NAL_SEI_SUFFIX = 40, -}; - enum RPSType { ST_CURR_BEF = 0, ST_CURR_AFT, @@ -349,10 +309,10 @@ typedef struct PTLCommon { typedef struct PTL { PTLCommon general_ptl; - PTLCommon sub_layer_ptl[MAX_SUB_LAYERS]; + PTLCommon sub_layer_ptl[HEVC_MAX_SUB_LAYERS]; - uint8_t sub_layer_profile_present_flag[MAX_SUB_LAYERS]; - uint8_t sub_layer_level_present_flag[MAX_SUB_LAYERS]; + uint8_t sub_layer_profile_present_flag[HEVC_MAX_SUB_LAYERS]; + uint8_t sub_layer_level_present_flag[HEVC_MAX_SUB_LAYERS]; } PTL; typedef struct HEVCVPS { @@ -362,9 +322,9 @@ typedef struct HEVCVPS { PTL ptl; int vps_sub_layer_ordering_info_present_flag; - unsigned int vps_max_dec_pic_buffering[MAX_SUB_LAYERS]; - unsigned int vps_num_reorder_pics[MAX_SUB_LAYERS]; - unsigned int vps_max_latency_increase[MAX_SUB_LAYERS]; + unsigned int vps_max_dec_pic_buffering[HEVC_MAX_SUB_LAYERS]; + unsigned int vps_num_reorder_pics[HEVC_MAX_SUB_LAYERS]; + unsigned int vps_max_latency_increase[HEVC_MAX_SUB_LAYERS]; int vps_max_layer_id; int vps_num_layer_sets; ///< vps_num_layer_sets_minus1 + 1 uint8_t vps_timing_info_present_flag; @@ -405,7 +365,7 @@ typedef struct HEVCSPS { int max_dec_pic_buffering; int num_reorder_pics; int max_latency_increase; - } temporal_layer[MAX_SUB_LAYERS]; + } temporal_layer[HEVC_MAX_SUB_LAYERS]; VUI vui; PTL ptl; @@ -414,7 +374,7 @@ typedef struct HEVCSPS { ScalingList scaling_list; unsigned int nb_st_rps; - ShortTermRPS st_rps[MAX_SHORT_TERM_RPS_COUNT]; + ShortTermRPS st_rps[HEVC_MAX_SHORT_TERM_RPS_COUNT]; uint8_t amp_enabled_flag; uint8_t sao_enabled; @@ -528,9 +488,9 @@ typedef struct HEVCPPS { } HEVCPPS; typedef struct HEVCParamSets { - AVBufferRef *vps_list[MAX_VPS_COUNT]; - AVBufferRef *sps_list[MAX_SPS_COUNT]; - AVBufferRef *pps_list[MAX_PPS_COUNT]; + AVBufferRef *vps_list[HEVC_MAX_VPS_COUNT]; + AVBufferRef *sps_list[HEVC_MAX_SPS_COUNT]; + AVBufferRef *pps_list[HEVC_MAX_PPS_COUNT]; /* currently active parameter sets */ const HEVCVPS *vps; @@ -783,7 +743,7 @@ typedef struct HEVCContext { SliceHeader sh; SAOParams *sao; DBParams *deblock; - enum NALUnitType nal_unit_type; + enum HEVCNALUnitType nal_unit_type; int temporal_id; ///< temporal_id_plus1 - 1 HEVCFrame *ref; HEVCFrame DPB[32]; @@ -832,7 +792,7 @@ typedef struct HEVCContext { H2645Packet pkt; // type of the first VCL NAL of the current frame - enum NALUnitType first_nal_type; + enum HEVCNALUnitType first_nal_type; // for checking the frame checksums struct AVMD5 *md5_ctx; diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c index 24af82c8c5144..c51309f9c68ec 100644 --- a/libavcodec/qsvenc_hevc.c +++ b/libavcodec/qsvenc_hevc.c @@ -30,6 +30,7 @@ #include "avcodec.h" #include "bytestream.h" #include "get_bits.h" +#include "hevc.h" #include "hevcdec.h" #include "h2645_parse.h" #include "internal.h" @@ -83,7 +84,7 @@ static int generate_fake_vps(QSVEncContext *q, AVCodecContext *avctx) get_bits(&gb, 1); type = get_bits(&gb, 6); - if (type != NAL_SPS) { + if (type != HEVC_NAL_SPS) { av_log(avctx, AV_LOG_ERROR, "Unexpected NAL type in the extradata: %d\n", type); av_freep(&sps_nal.rbsp_buffer); @@ -103,7 +104,7 @@ static int generate_fake_vps(QSVEncContext *q, AVCodecContext *avctx) vps.vps_max_sub_layers = sps.max_sub_layers; memcpy(&vps.ptl, &sps.ptl, sizeof(vps.ptl)); vps.vps_sub_layer_ordering_info_present_flag = 1; - for (i = 0; i < MAX_SUB_LAYERS; i++) { + for (i = 0; i < HEVC_MAX_SUB_LAYERS; i++) { vps.vps_max_dec_pic_buffering[i] = sps.temporal_layer[i].max_dec_pic_buffering; vps.vps_num_reorder_pics[i] = sps.temporal_layer[i].num_reorder_pics; vps.vps_max_latency_increase[i] = sps.temporal_layer[i].max_latency_increase; @@ -127,9 +128,9 @@ static int generate_fake_vps(QSVEncContext *q, AVCodecContext *avctx) bytestream2_init(&gbc, vps_rbsp_buf, ret); bytestream2_init_writer(&pbc, vps_buf, sizeof(vps_buf)); - bytestream2_put_be32(&pbc, 1); // startcode - bytestream2_put_byte(&pbc, NAL_VPS << 1); // NAL - bytestream2_put_byte(&pbc, 1); // header + bytestream2_put_be32(&pbc, 1); // startcode + bytestream2_put_byte(&pbc, HEVC_NAL_VPS << 1); // NAL + bytestream2_put_byte(&pbc, 1); // header while (bytestream2_get_bytes_left(&gbc)) { uint32_t b = bytestream2_peek_be24(&gbc); diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c index 4853a5bbebedd..776c228dd8874 100644 --- a/libavcodec/vaapi_encode_h265.c +++ b/libavcodec/vaapi_encode_h265.c @@ -25,7 +25,7 @@ #include "libavutil/pixfmt.h" #include "avcodec.h" -#include "hevcdec.h" +#include "hevc.h" #include "internal.h" #include "put_bits.h" #include "vaapi_encode.h" @@ -275,7 +275,7 @@ static void vaapi_encode_h265_write_vps(PutBitContext *pbc, VAAPIEncodeH265MiscSequenceParams *mseq = &priv->misc_sequence_params; int i, j; - vaapi_encode_h265_write_nal_unit_header(pbc, NAL_VPS); + vaapi_encode_h265_write_nal_unit_header(pbc, HEVC_NAL_VPS); u(4, mseq->video_parameter_set_id, vps_video_parameter_set_id); @@ -395,7 +395,7 @@ static void vaapi_encode_h265_write_sps(PutBitContext *pbc, VAAPIEncodeH265MiscSequenceParams *mseq = &priv->misc_sequence_params; int i; - vaapi_encode_h265_write_nal_unit_header(pbc, NAL_SPS); + vaapi_encode_h265_write_nal_unit_header(pbc, HEVC_NAL_SPS); u(4, mseq->video_parameter_set_id, sps_video_parameter_set_id); @@ -491,7 +491,7 @@ static void vaapi_encode_h265_write_pps(PutBitContext *pbc, VAAPIEncodeH265MiscSequenceParams *mseq = &priv->misc_sequence_params; int i; - vaapi_encode_h265_write_nal_unit_header(pbc, NAL_PPS); + vaapi_encode_h265_write_nal_unit_header(pbc, HEVC_NAL_PPS); ue(vpic->slice_pic_parameter_set_id, pps_pic_parameter_set_id); ue(mseq->seq_parameter_set_id, pps_seq_parameter_set_id); @@ -576,7 +576,7 @@ static void vaapi_encode_h265_write_slice_header2(PutBitContext *pbc, vaapi_encode_h265_write_nal_unit_header(pbc, vpic->nal_unit_type); u(1, mslice_var(first_slice_segment_in_pic_flag)); - if (vpic->nal_unit_type >= NAL_BLA_W_LP && + if (vpic->nal_unit_type >= HEVC_NAL_BLA_W_LP && vpic->nal_unit_type <= 23) u(1, mslice_var(no_output_of_prior_pics_flag)); @@ -597,8 +597,8 @@ static void vaapi_encode_h265_write_slice_header2(PutBitContext *pbc, u(1, 1, pic_output_flag); if (vseq->seq_fields.bits.separate_colour_plane_flag) u(2, vslice_field(colour_plane_id)); - if (vpic->nal_unit_type != NAL_IDR_W_RADL && - vpic->nal_unit_type != NAL_IDR_N_LP) { + if (vpic->nal_unit_type != HEVC_NAL_IDR_W_RADL && + vpic->nal_unit_type != HEVC_NAL_IDR_N_LP) { u(4 + mseq->log2_max_pic_order_cnt_lsb_minus4, (pslice->pic_order_cnt & ((1 << (mseq->log2_max_pic_order_cnt_lsb_minus4 + 4)) - 1)), @@ -998,25 +998,25 @@ static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx, switch (pic->type) { case PICTURE_TYPE_IDR: - vpic->nal_unit_type = NAL_IDR_W_RADL; + vpic->nal_unit_type = HEVC_NAL_IDR_W_RADL; vpic->pic_fields.bits.idr_pic_flag = 1; vpic->pic_fields.bits.coding_type = 1; vpic->pic_fields.bits.reference_pic_flag = 1; break; case PICTURE_TYPE_I: - vpic->nal_unit_type = NAL_TRAIL_R; + vpic->nal_unit_type = HEVC_NAL_TRAIL_R; vpic->pic_fields.bits.idr_pic_flag = 0; vpic->pic_fields.bits.coding_type = 1; vpic->pic_fields.bits.reference_pic_flag = 1; break; case PICTURE_TYPE_P: - vpic->nal_unit_type = NAL_TRAIL_R; + vpic->nal_unit_type = HEVC_NAL_TRAIL_R; vpic->pic_fields.bits.idr_pic_flag = 0; vpic->pic_fields.bits.coding_type = 2; vpic->pic_fields.bits.reference_pic_flag = 1; break; case PICTURE_TYPE_B: - vpic->nal_unit_type = NAL_TRAIL_R; + vpic->nal_unit_type = HEVC_NAL_TRAIL_R; vpic->pic_fields.bits.idr_pic_flag = 0; vpic->pic_fields.bits.coding_type = 3; vpic->pic_fields.bits.reference_pic_flag = 0; diff --git a/libavformat/hevc.c b/libavformat/hevc.c index b3a3603c0e0cd..62eefc6d29061 100644 --- a/libavformat/hevc.c +++ b/libavformat/hevc.c @@ -18,9 +18,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavcodec/avcodec.h" #include "libavcodec/get_bits.h" #include "libavcodec/golomb.h" -#include "libavcodec/hevcdec.h" +#include "libavcodec/hevc.h" #include "libavutil/intreadwrite.h" #include "avc.h" #include "avio.h" @@ -127,8 +128,8 @@ static void hvcc_parse_ptl(GetBitContext *gb, { unsigned int i; HVCCProfileTierLevel general_ptl; - uint8_t sub_layer_profile_present_flag[MAX_SUB_LAYERS]; - uint8_t sub_layer_level_present_flag[MAX_SUB_LAYERS]; + uint8_t sub_layer_profile_present_flag[HEVC_MAX_SUB_LAYERS]; + uint8_t sub_layer_level_present_flag[HEVC_MAX_SUB_LAYERS]; general_ptl.profile_space = get_bits(gb, 2); general_ptl.tier_flag = get_bits1(gb); @@ -411,7 +412,7 @@ static void skip_scaling_list_data(GetBitContext *gb) static int parse_rps(GetBitContext *gb, unsigned int rps_idx, unsigned int num_rps, - unsigned int num_delta_pocs[MAX_SHORT_TERM_RPS_COUNT]) + unsigned int num_delta_pocs[HEVC_MAX_SHORT_TERM_RPS_COUNT]) { unsigned int i; @@ -477,7 +478,7 @@ static int hvcc_parse_sps(GetBitContext *gb, HEVCDecoderConfigurationRecord *hvcc) { unsigned int i, sps_max_sub_layers_minus1, log2_max_pic_order_cnt_lsb_minus4; - unsigned int num_short_term_ref_pic_sets, num_delta_pocs[MAX_SHORT_TERM_RPS_COUNT]; + unsigned int num_short_term_ref_pic_sets, num_delta_pocs[HEVC_MAX_SHORT_TERM_RPS_COUNT]; skip_bits(gb, 4); // sps_video_parameter_set_id @@ -547,7 +548,7 @@ static int hvcc_parse_sps(GetBitContext *gb, } num_short_term_ref_pic_sets = get_ue_golomb_long(gb); - if (num_short_term_ref_pic_sets > MAX_SHORT_TERM_RPS_COUNT) + if (num_short_term_ref_pic_sets > HEVC_MAX_SHORT_TERM_RPS_COUNT) return AVERROR_INVALIDDATA; for (i = 0; i < num_short_term_ref_pic_sets; i++) { @@ -722,7 +723,7 @@ static int hvcc_array_add_nal_unit(uint8_t *nal_buf, uint32_t nal_size, * for all other arrays. When the sample entry name is ‘hev1’, the default * value of array_completeness is 0 for all arrays. */ - if (nal_type == NAL_VPS || nal_type == NAL_SPS || nal_type == NAL_PPS) + if (nal_type == HEVC_NAL_VPS || nal_type == HEVC_NAL_SPS || nal_type == HEVC_NAL_PPS) array->array_completeness = ps_array_completeness; return 0; @@ -756,20 +757,20 @@ static int hvcc_add_nal_unit(uint8_t *nal_buf, uint32_t nal_size, * and non-declarative SEI messages discarded? */ switch (nal_type) { - case NAL_VPS: - case NAL_SPS: - case NAL_PPS: - case NAL_SEI_PREFIX: - case NAL_SEI_SUFFIX: + case HEVC_NAL_VPS: + case HEVC_NAL_SPS: + case HEVC_NAL_PPS: + case HEVC_NAL_SEI_PREFIX: + case HEVC_NAL_SEI_SUFFIX: ret = hvcc_array_add_nal_unit(nal_buf, nal_size, nal_type, ps_array_completeness, hvcc); if (ret < 0) goto end; - else if (nal_type == NAL_VPS) + else if (nal_type == HEVC_NAL_VPS) ret = hvcc_parse_vps(&gbc, hvcc); - else if (nal_type == NAL_SPS) + else if (nal_type == HEVC_NAL_SPS) ret = hvcc_parse_sps(&gbc, hvcc); - else if (nal_type == NAL_PPS) + else if (nal_type == HEVC_NAL_PPS) ret = hvcc_parse_pps(&gbc, hvcc); if (ret < 0) goto end; @@ -903,21 +904,21 @@ static int hvcc_write(AVIOContext *pb, HEVCDecoderConfigurationRecord *hvcc) */ for (i = 0; i < hvcc->numOfArrays; i++) switch (hvcc->array[i].NAL_unit_type) { - case NAL_VPS: + case HEVC_NAL_VPS: vps_count += hvcc->array[i].numNalus; break; - case NAL_SPS: + case HEVC_NAL_SPS: sps_count += hvcc->array[i].numNalus; break; - case NAL_PPS: + case HEVC_NAL_PPS: pps_count += hvcc->array[i].numNalus; break; default: break; } - if (!vps_count || vps_count > MAX_VPS_COUNT || - !sps_count || sps_count > MAX_SPS_COUNT || - !pps_count || pps_count > MAX_PPS_COUNT) + if (!vps_count || vps_count > HEVC_MAX_VPS_COUNT || + !sps_count || sps_count > HEVC_MAX_SPS_COUNT || + !pps_count || pps_count > HEVC_MAX_PPS_COUNT) return AVERROR_INVALIDDATA; /* unsigned int(8) configurationVersion = 1; */ @@ -1040,9 +1041,9 @@ int ff_hevc_annexb2mp4(AVIOContext *pb, const uint8_t *buf_in, buf += 4; switch (type) { - case NAL_VPS: - case NAL_SPS: - case NAL_PPS: + case HEVC_NAL_VPS: + case HEVC_NAL_SPS: + case HEVC_NAL_PPS: num_ps++; break; default: @@ -1115,11 +1116,11 @@ int ff_isom_write_hvcc(AVIOContext *pb, const uint8_t *data, buf += 4; switch (type) { - case NAL_VPS: - case NAL_SPS: - case NAL_PPS: - case NAL_SEI_PREFIX: - case NAL_SEI_SUFFIX: + case HEVC_NAL_VPS: + case HEVC_NAL_SPS: + case HEVC_NAL_PPS: + case HEVC_NAL_SEI_PREFIX: + case HEVC_NAL_SEI_SUFFIX: ret = hvcc_add_nal_unit(buf, len, ps_array_completeness, &hvcc); if (ret < 0) goto end; diff --git a/libavformat/hevcdec.c b/libavformat/hevcdec.c index 75b2cd3916bc8..c186b1ac1dee9 100644 --- a/libavformat/hevcdec.c +++ b/libavformat/hevcdec.c @@ -19,7 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "libavcodec/hevcdec.h" +#include "libavcodec/hevc.h" #include "avformat.h" #include "rawdec.h" @@ -43,15 +43,15 @@ static int hevc_probe(AVProbeData *p) return 0; switch (type) { - case NAL_VPS: vps++; break; - case NAL_SPS: sps++; break; - case NAL_PPS: pps++; break; - case NAL_BLA_N_LP: - case NAL_BLA_W_LP: - case NAL_BLA_W_RADL: - case NAL_CRA_NUT: - case NAL_IDR_N_LP: - case NAL_IDR_W_RADL: irap++; break; + case HEVC_NAL_VPS: vps++; break; + case HEVC_NAL_SPS: sps++; break; + case HEVC_NAL_PPS: pps++; break; + case HEVC_NAL_BLA_N_LP: + case HEVC_NAL_BLA_W_LP: + case HEVC_NAL_BLA_W_RADL: + case HEVC_NAL_CRA_NUT: + case HEVC_NAL_IDR_N_LP: + case HEVC_NAL_IDR_W_RADL: irap++; break; } } } From 645c6ff4231a75a71db58c8e6d06346068d2f949 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 21 Aug 2016 17:48:01 +0200 Subject: [PATCH 0301/3374] hevcdec: drop the prototype of a non-existing function --- libavcodec/hevcdec.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/libavcodec/hevcdec.h b/libavcodec/hevcdec.h index df81e55ed872a..95662234c126e 100644 --- a/libavcodec/hevcdec.h +++ b/libavcodec/hevcdec.h @@ -957,8 +957,6 @@ int ff_hevc_cu_qp_delta_abs(HEVCContext *s); void ff_hevc_hls_filter(HEVCContext *s, int x, int y); void ff_hevc_hls_filters(HEVCContext *s, int x_ctb, int y_ctb, int ctb_size); -void ff_hevc_pps_free(HEVCPPS **ppps); - void ff_hevc_pred_init(HEVCPredContext *hpc, int bit_depth); int ff_hevc_encode_nal_vps(HEVCVPS *vps, unsigned int id, From 150c896a9e46b23b97debb0a5f66fbaeaa32f153 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 12 Oct 2016 10:21:35 +0200 Subject: [PATCH 0302/3374] hevcdec: split ff_hevc_diag_scan* declarations into a separate header This will be useful in the following commits. --- libavcodec/dxva2_hevc.c | 1 + libavcodec/hevc_data.c | 2 +- libavcodec/hevc_data.h | 31 +++++++++++++++++++++++++++++++ libavcodec/hevc_ps.c | 1 + libavcodec/hevcdec.c | 1 + libavcodec/hevcdec.h | 5 ----- libavcodec/vdpau_hevc.c | 1 + 7 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 libavcodec/hevc_data.h diff --git a/libavcodec/dxva2_hevc.c b/libavcodec/dxva2_hevc.c index 53fd638d102b6..673fada6e69c5 100644 --- a/libavcodec/dxva2_hevc.c +++ b/libavcodec/dxva2_hevc.c @@ -22,6 +22,7 @@ #include "libavutil/avassert.h" +#include "hevc_data.h" #include "hevcdec.h" // The headers above may include w32threads.h, which uses the original diff --git a/libavcodec/hevc_data.c b/libavcodec/hevc_data.c index 7976c34156285..ff9548fc6b478 100644 --- a/libavcodec/hevc_data.c +++ b/libavcodec/hevc_data.c @@ -20,7 +20,7 @@ #include -#include "hevcdec.h" +#include "hevc_data.h" const uint8_t ff_hevc_diag_scan4x4_x[16] = { 0, 0, 1, 0, diff --git a/libavcodec/hevc_data.h b/libavcodec/hevc_data.h new file mode 100644 index 0000000000000..d1d2c33411649 --- /dev/null +++ b/libavcodec/hevc_data.h @@ -0,0 +1,31 @@ +/* + * HEVC shared data tables + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_HEVC_DATA_H +#define AVCODEC_HEVC_DATA_H + +#include + +extern const uint8_t ff_hevc_diag_scan4x4_x[16]; +extern const uint8_t ff_hevc_diag_scan4x4_y[16]; +extern const uint8_t ff_hevc_diag_scan8x8_x[64]; +extern const uint8_t ff_hevc_diag_scan8x8_y[64]; + +#endif /* AVCODEC_HEVC_DATA_H */ diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index 520017bc6e78d..44db326cf32d3 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -27,6 +27,7 @@ #include "golomb.h" #include "hevcdec.h" +#include "hevc_data.h" static const uint8_t default_scaling_list_intra[] = { 16, 16, 16, 16, 17, 18, 21, 24, diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 1da43344a4cab..93eb95a26519b 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -37,6 +37,7 @@ #include "cabac_functions.h" #include "golomb.h" #include "hevc.h" +#include "hevc_data.h" #include "hevcdec.h" #include "profiles.h" diff --git a/libavcodec/hevcdec.h b/libavcodec/hevcdec.h index 95662234c126e..b4502c0ad853f 100644 --- a/libavcodec/hevcdec.h +++ b/libavcodec/hevcdec.h @@ -966,9 +966,4 @@ extern const uint8_t ff_hevc_qpel_extra_before[4]; extern const uint8_t ff_hevc_qpel_extra_after[4]; extern const uint8_t ff_hevc_qpel_extra[4]; -extern const uint8_t ff_hevc_diag_scan4x4_x[16]; -extern const uint8_t ff_hevc_diag_scan4x4_y[16]; -extern const uint8_t ff_hevc_diag_scan8x8_x[64]; -extern const uint8_t ff_hevc_diag_scan8x8_y[64]; - #endif /* AVCODEC_HEVCDEC_H */ diff --git a/libavcodec/vdpau_hevc.c b/libavcodec/vdpau_hevc.c index 9f2baa75b1418..829945614c9f4 100644 --- a/libavcodec/vdpau_hevc.c +++ b/libavcodec/vdpau_hevc.c @@ -24,6 +24,7 @@ #include "avcodec.h" #include "internal.h" +#include "hevc_data.h" #include "hevcdec.h" #include "vdpau.h" #include "vdpau_internal.h" From f6e2f8a9ffda2247bffba991450990d075ea68e3 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 21 Aug 2016 18:02:02 +0200 Subject: [PATCH 0303/3374] hevcdec: move parameter set parsing into a separate header This code is independent from the decoder, so it makes more sense for it to to have its own header. --- libavcodec/hevc.h | 5 + libavcodec/hevc_ps.c | 14 +- libavcodec/hevc_ps.h | 320 +++++++++++++++++++++++++++++++++++++++ libavcodec/hevc_ps_enc.c | 2 +- libavcodec/hevc_refs.c | 2 +- libavcodec/hevcdec.c | 2 +- libavcodec/hevcdec.h | 296 +----------------------------------- 7 files changed, 339 insertions(+), 302 deletions(-) create mode 100644 libavcodec/hevc_ps.h diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h index 66816b840946e..95366088f8a8b 100644 --- a/libavcodec/hevc.h +++ b/libavcodec/hevc.h @@ -62,4 +62,9 @@ enum HEVCNALUnitType { #define HEVC_MAX_SHORT_TERM_RPS_COUNT 64 #define HEVC_MAX_CU_SIZE 128 +#define HEVC_MAX_REFS 16 +#define HEVC_MAX_DPB_SIZE 16 // A.4.1 + +#define HEVC_MAX_LOG2_CTB_SIZE 6 + #endif /* AVCODEC_HEVC_H */ diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index 44db326cf32d3..6a8cfebaf76d3 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -26,8 +26,8 @@ #include "libavutil/imgutils.h" #include "golomb.h" -#include "hevcdec.h" #include "hevc_data.h" +#include "hevc_ps.h" static const uint8_t default_scaling_list_intra[] = { 16, 16, 16, 16, 17, 18, 21, 24, @@ -200,8 +200,8 @@ int ff_hevc_decode_short_term_rps(GetBitContext *gb, AVCodecContext *avctx, rps->num_negative_pics = get_ue_golomb_long(gb); nb_positive_pics = get_ue_golomb_long(gb); - if (rps->num_negative_pics >= MAX_REFS || - nb_positive_pics >= MAX_REFS) { + if (rps->num_negative_pics >= HEVC_MAX_REFS || + nb_positive_pics >= HEVC_MAX_REFS) { av_log(avctx, AV_LOG_ERROR, "Too many refs in a short term RPS.\n"); return AVERROR_INVALIDDATA; } @@ -406,7 +406,7 @@ int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx, vps->vps_num_reorder_pics[i] = get_ue_golomb_long(gb); vps->vps_max_latency_increase[i] = get_ue_golomb_long(gb) - 1; - if (vps->vps_max_dec_pic_buffering[i] > MAX_DPB_SIZE) { + if (vps->vps_max_dec_pic_buffering[i] > HEVC_MAX_DPB_SIZE) { av_log(avctx, AV_LOG_ERROR, "vps_max_dec_pic_buffering_minus1 out of range: %d\n", vps->vps_max_dec_pic_buffering[i] - 1); goto err; @@ -794,7 +794,7 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, sps->temporal_layer[i].max_dec_pic_buffering = get_ue_golomb_long(gb) + 1; sps->temporal_layer[i].num_reorder_pics = get_ue_golomb_long(gb); sps->temporal_layer[i].max_latency_increase = get_ue_golomb_long(gb) - 1; - if (sps->temporal_layer[i].max_dec_pic_buffering > MAX_DPB_SIZE) { + if (sps->temporal_layer[i].max_dec_pic_buffering > HEVC_MAX_DPB_SIZE) { av_log(avctx, AV_LOG_ERROR, "sps_max_dec_pic_buffering_minus1 out of range: %d\n", sps->temporal_layer[i].max_dec_pic_buffering - 1); ret = AVERROR_INVALIDDATA; @@ -804,7 +804,7 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, av_log(avctx, AV_LOG_WARNING, "sps_max_num_reorder_pics out of range: %d\n", sps->temporal_layer[i].num_reorder_pics); if (avctx->err_recognition & AV_EF_EXPLODE || - sps->temporal_layer[i].num_reorder_pics > MAX_DPB_SIZE - 1) { + sps->temporal_layer[i].num_reorder_pics > HEVC_MAX_DPB_SIZE - 1) { ret = AVERROR_INVALIDDATA; goto err; } @@ -955,7 +955,7 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, goto err; } - if (sps->log2_ctb_size > MAX_LOG2_CTB_SIZE) { + if (sps->log2_ctb_size > HEVC_MAX_LOG2_CTB_SIZE) { av_log(avctx, AV_LOG_ERROR, "CTB size out of range: 2^%d\n", sps->log2_ctb_size); goto err; } diff --git a/libavcodec/hevc_ps.h b/libavcodec/hevc_ps.h new file mode 100644 index 0000000000000..d95aa519e6fe6 --- /dev/null +++ b/libavcodec/hevc_ps.h @@ -0,0 +1,320 @@ +/* + * HEVC parameter set parsing + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_HEVC_PS_H +#define AVCODEC_HEVC_PS_H + +#include + +#include "libavutil/buffer.h" +#include "libavutil/pixfmt.h" +#include "libavutil/rational.h" + +#include "avcodec.h" +#include "get_bits.h" +#include "hevc.h" + +typedef struct ShortTermRPS { + unsigned int num_negative_pics; + int num_delta_pocs; + int rps_idx_num_delta_pocs; + int32_t delta_poc[32]; + uint8_t used[32]; +} ShortTermRPS; + +typedef struct HEVCWindow { + unsigned int left_offset; + unsigned int right_offset; + unsigned int top_offset; + unsigned int bottom_offset; +} HEVCWindow; + +typedef struct VUI { + AVRational sar; + + int overscan_info_present_flag; + int overscan_appropriate_flag; + + int video_signal_type_present_flag; + int video_format; + int video_full_range_flag; + int colour_description_present_flag; + uint8_t colour_primaries; + uint8_t transfer_characteristic; + uint8_t matrix_coeffs; + + int chroma_loc_info_present_flag; + int chroma_sample_loc_type_top_field; + int chroma_sample_loc_type_bottom_field; + int neutra_chroma_indication_flag; + + int field_seq_flag; + int frame_field_info_present_flag; + + int default_display_window_flag; + HEVCWindow def_disp_win; + + int vui_timing_info_present_flag; + uint32_t vui_num_units_in_tick; + uint32_t vui_time_scale; + int vui_poc_proportional_to_timing_flag; + int vui_num_ticks_poc_diff_one_minus1; + int vui_hrd_parameters_present_flag; + + int bitstream_restriction_flag; + int tiles_fixed_structure_flag; + int motion_vectors_over_pic_boundaries_flag; + int restricted_ref_pic_lists_flag; + int min_spatial_segmentation_idc; + int max_bytes_per_pic_denom; + int max_bits_per_min_cu_denom; + int log2_max_mv_length_horizontal; + int log2_max_mv_length_vertical; +} VUI; + +typedef struct PTLCommon { + uint8_t profile_space; + uint8_t tier_flag; + uint8_t profile_idc; + uint8_t profile_compatibility_flag[32]; + uint8_t level_idc; + uint8_t progressive_source_flag; + uint8_t interlaced_source_flag; + uint8_t non_packed_constraint_flag; + uint8_t frame_only_constraint_flag; +} PTLCommon; + +typedef struct PTL { + PTLCommon general_ptl; + PTLCommon sub_layer_ptl[HEVC_MAX_SUB_LAYERS]; + + uint8_t sub_layer_profile_present_flag[HEVC_MAX_SUB_LAYERS]; + uint8_t sub_layer_level_present_flag[HEVC_MAX_SUB_LAYERS]; +} PTL; + +typedef struct HEVCVPS { + uint8_t vps_temporal_id_nesting_flag; + int vps_max_layers; + int vps_max_sub_layers; ///< vps_max_temporal_layers_minus1 + 1 + + PTL ptl; + int vps_sub_layer_ordering_info_present_flag; + unsigned int vps_max_dec_pic_buffering[HEVC_MAX_SUB_LAYERS]; + unsigned int vps_num_reorder_pics[HEVC_MAX_SUB_LAYERS]; + unsigned int vps_max_latency_increase[HEVC_MAX_SUB_LAYERS]; + int vps_max_layer_id; + int vps_num_layer_sets; ///< vps_num_layer_sets_minus1 + 1 + uint8_t vps_timing_info_present_flag; + uint32_t vps_num_units_in_tick; + uint32_t vps_time_scale; + uint8_t vps_poc_proportional_to_timing_flag; + int vps_num_ticks_poc_diff_one; ///< vps_num_ticks_poc_diff_one_minus1 + 1 + int vps_num_hrd_parameters; +} HEVCVPS; + +typedef struct ScalingList { + /* This is a little wasteful, since sizeID 0 only needs 8 coeffs, + * and size ID 3 only has 2 arrays, not 6. */ + uint8_t sl[4][6][64]; + uint8_t sl_dc[2][6]; +} ScalingList; + +typedef struct HEVCSPS { + int vps_id; + int chroma_format_idc; + uint8_t separate_colour_plane_flag; + + ///< output (i.e. cropped) values + int output_width, output_height; + HEVCWindow output_window; + + HEVCWindow pic_conf_win; + + int bit_depth; + int pixel_shift; + enum AVPixelFormat pix_fmt; + + unsigned int log2_max_poc_lsb; + int pcm_enabled_flag; + + int max_sub_layers; + struct { + int max_dec_pic_buffering; + int num_reorder_pics; + int max_latency_increase; + } temporal_layer[HEVC_MAX_SUB_LAYERS]; + + VUI vui; + PTL ptl; + + uint8_t scaling_list_enable_flag; + ScalingList scaling_list; + + unsigned int nb_st_rps; + ShortTermRPS st_rps[HEVC_MAX_SHORT_TERM_RPS_COUNT]; + + uint8_t amp_enabled_flag; + uint8_t sao_enabled; + + uint8_t long_term_ref_pics_present_flag; + uint16_t lt_ref_pic_poc_lsb_sps[32]; + uint8_t used_by_curr_pic_lt_sps_flag[32]; + uint8_t num_long_term_ref_pics_sps; + + struct { + uint8_t bit_depth; + uint8_t bit_depth_chroma; + unsigned int log2_min_pcm_cb_size; + unsigned int log2_max_pcm_cb_size; + uint8_t loop_filter_disable_flag; + } pcm; + uint8_t sps_temporal_mvp_enabled_flag; + uint8_t sps_strong_intra_smoothing_enable_flag; + + unsigned int log2_min_cb_size; + unsigned int log2_diff_max_min_coding_block_size; + unsigned int log2_min_tb_size; + unsigned int log2_max_trafo_size; + unsigned int log2_ctb_size; + unsigned int log2_min_pu_size; + + int max_transform_hierarchy_depth_inter; + int max_transform_hierarchy_depth_intra; + + ///< coded frame dimension in various units + int width; + int height; + int ctb_width; + int ctb_height; + int ctb_size; + int min_cb_width; + int min_cb_height; + int min_tb_width; + int min_tb_height; + int min_pu_width; + int min_pu_height; + + int hshift[3]; + int vshift[3]; + + int qp_bd_offset; +} HEVCSPS; + +typedef struct HEVCPPS { + unsigned int sps_id; ///< seq_parameter_set_id + + uint8_t sign_data_hiding_flag; + + uint8_t cabac_init_present_flag; + + int num_ref_idx_l0_default_active; ///< num_ref_idx_l0_default_active_minus1 + 1 + int num_ref_idx_l1_default_active; ///< num_ref_idx_l1_default_active_minus1 + 1 + int pic_init_qp_minus26; + + uint8_t constrained_intra_pred_flag; + uint8_t transform_skip_enabled_flag; + + uint8_t cu_qp_delta_enabled_flag; + int diff_cu_qp_delta_depth; + + int cb_qp_offset; + int cr_qp_offset; + uint8_t pic_slice_level_chroma_qp_offsets_present_flag; + uint8_t weighted_pred_flag; + uint8_t weighted_bipred_flag; + uint8_t output_flag_present_flag; + uint8_t transquant_bypass_enable_flag; + + uint8_t dependent_slice_segments_enabled_flag; + uint8_t tiles_enabled_flag; + uint8_t entropy_coding_sync_enabled_flag; + + int num_tile_columns; ///< num_tile_columns_minus1 + 1 + int num_tile_rows; ///< num_tile_rows_minus1 + 1 + uint8_t uniform_spacing_flag; + uint8_t loop_filter_across_tiles_enabled_flag; + + uint8_t seq_loop_filter_across_slices_enabled_flag; + + uint8_t deblocking_filter_control_present_flag; + uint8_t deblocking_filter_override_enabled_flag; + uint8_t disable_dbf; + int beta_offset; ///< beta_offset_div2 * 2 + int tc_offset; ///< tc_offset_div2 * 2 + + uint8_t scaling_list_data_present_flag; + ScalingList scaling_list; + + uint8_t lists_modification_present_flag; + int log2_parallel_merge_level; ///< log2_parallel_merge_level_minus2 + 2 + int num_extra_slice_header_bits; + uint8_t slice_header_extension_present_flag; + + // Inferred parameters + unsigned int *column_width; ///< ColumnWidth + unsigned int *row_height; ///< RowHeight + unsigned int *col_bd; ///< ColBd + unsigned int *row_bd; ///< RowBd + int *col_idxX; + + int *ctb_addr_rs_to_ts; ///< CtbAddrRSToTS + int *ctb_addr_ts_to_rs; ///< CtbAddrTSToRS + int *tile_id; ///< TileId + int *tile_pos_rs; ///< TilePosRS + int *min_tb_addr_zs; ///< MinTbAddrZS +} HEVCPPS; + +typedef struct HEVCParamSets { + AVBufferRef *vps_list[HEVC_MAX_VPS_COUNT]; + AVBufferRef *sps_list[HEVC_MAX_SPS_COUNT]; + AVBufferRef *pps_list[HEVC_MAX_PPS_COUNT]; + + /* currently active parameter sets */ + const HEVCVPS *vps; + const HEVCSPS *sps; + const HEVCPPS *pps; +} HEVCParamSets; + +/** + * Parse the SPS from the bitstream into the provided HEVCSPS struct. + * + * @param sps_id the SPS id will be written here + * @param apply_defdispwin if set 1, the default display window from the VUI + * will be applied to the video dimensions + * @param vps_list if non-NULL, this function will validate that the SPS refers + * to an existing VPS + */ +int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, + int apply_defdispwin, AVBufferRef **vps_list, AVCodecContext *avctx); + +int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx, + HEVCParamSets *ps); +int ff_hevc_decode_nal_sps(GetBitContext *gb, AVCodecContext *avctx, + HEVCParamSets *ps, int apply_defdispwin); +int ff_hevc_decode_nal_pps(GetBitContext *gb, AVCodecContext *avctx, + HEVCParamSets *ps); + +int ff_hevc_decode_short_term_rps(GetBitContext *gb, AVCodecContext *avctx, + ShortTermRPS *rps, const HEVCSPS *sps, int is_slice_header); + +int ff_hevc_encode_nal_vps(HEVCVPS *vps, unsigned int id, + uint8_t *buf, int buf_size); + +#endif /* AVCODEC_HEVC_PS_H */ diff --git a/libavcodec/hevc_ps_enc.c b/libavcodec/hevc_ps_enc.c index fdf9fb7f40bc5..1e86757d7c3da 100644 --- a/libavcodec/hevc_ps_enc.c +++ b/libavcodec/hevc_ps_enc.c @@ -19,7 +19,7 @@ */ #include "golomb.h" -#include "hevcdec.h" +#include "hevc_ps.h" #include "put_bits.h" static void write_ptl_layer(PutBitContext *pb, PTLCommon *ptl) diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c index 82a115788783b..0b6beb590fc4a 100644 --- a/libavcodec/hevc_refs.c +++ b/libavcodec/hevc_refs.c @@ -278,7 +278,7 @@ int ff_hevc_slice_rpl(HEVCContext *s) while (rpl_tmp.nb_refs < sh->nb_refs[list_idx]) { for (i = 0; i < FF_ARRAY_ELEMS(cand_lists); i++) { RefPicList *rps = &s->rps[cand_lists[i]]; - for (j = 0; j < rps->nb_refs && rpl_tmp.nb_refs < MAX_REFS; j++) { + for (j = 0; j < rps->nb_refs && rpl_tmp.nb_refs < HEVC_MAX_REFS; j++) { rpl_tmp.list[rpl_tmp.nb_refs] = rps->list[j]; rpl_tmp.ref[rpl_tmp.nb_refs] = rps->ref[j]; rpl_tmp.isLongTerm[rpl_tmp.nb_refs] = i == 2; diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 93eb95a26519b..72fdd22c5e84a 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -628,7 +628,7 @@ static int hls_slice_header(HEVCContext *s) if (sh->slice_type == B_SLICE) sh->nb_refs[L1] = get_ue_golomb_long(gb) + 1; } - if (sh->nb_refs[L0] > MAX_REFS || sh->nb_refs[L1] > MAX_REFS) { + if (sh->nb_refs[L0] > HEVC_MAX_REFS || sh->nb_refs[L1] > HEVC_MAX_REFS) { av_log(s->avctx, AV_LOG_ERROR, "Too many refs: %d/%d.\n", sh->nb_refs[L0], sh->nb_refs[L1]); return AVERROR_INVALIDDATA; diff --git a/libavcodec/hevcdec.h b/libavcodec/hevcdec.h index b4502c0ad853f..78080eb757674 100644 --- a/libavcodec/hevcdec.h +++ b/libavcodec/hevcdec.h @@ -35,20 +35,17 @@ #include "get_bits.h" #include "h2645_parse.h" #include "hevc.h" +#include "hevc_ps.h" #include "hevcdsp.h" #include "internal.h" #include "thread.h" #include "videodsp.h" -#define MAX_DPB_SIZE 16 // A.4.1 -#define MAX_REFS 16 - //TODO: check if this is really the maximum #define MAX_TRANSFORM_DEPTH 5 #define MAX_TB_SIZE 32 #define MAX_PB_SIZE 64 -#define MAX_LOG2_CTB_SIZE 6 #define MAX_QP 51 #define DEFAULT_INTRA_TC_OFFSET 2 @@ -220,14 +217,6 @@ enum ScanType { SCAN_VERT, }; -typedef struct ShortTermRPS { - unsigned int num_negative_pics; - int num_delta_pocs; - int rps_idx_num_delta_pocs; - int32_t delta_poc[32]; - uint8_t used[32]; -} ShortTermRPS; - typedef struct LongTermRPS { int poc[32]; uint8_t used[32]; @@ -235,9 +224,9 @@ typedef struct LongTermRPS { } LongTermRPS; typedef struct RefPicList { - struct HEVCFrame *ref[MAX_REFS]; - int list[MAX_REFS]; - int isLongTerm[MAX_REFS]; + struct HEVCFrame *ref[HEVC_MAX_REFS]; + int list[HEVC_MAX_REFS]; + int isLongTerm[HEVC_MAX_REFS]; int nb_refs; } RefPicList; @@ -245,259 +234,6 @@ typedef struct RefPicListTab { RefPicList refPicList[2]; } RefPicListTab; -typedef struct HEVCWindow { - unsigned int left_offset; - unsigned int right_offset; - unsigned int top_offset; - unsigned int bottom_offset; -} HEVCWindow; - -typedef struct VUI { - AVRational sar; - - int overscan_info_present_flag; - int overscan_appropriate_flag; - - int video_signal_type_present_flag; - int video_format; - int video_full_range_flag; - int colour_description_present_flag; - uint8_t colour_primaries; - uint8_t transfer_characteristic; - uint8_t matrix_coeffs; - - int chroma_loc_info_present_flag; - int chroma_sample_loc_type_top_field; - int chroma_sample_loc_type_bottom_field; - int neutra_chroma_indication_flag; - - int field_seq_flag; - int frame_field_info_present_flag; - - int default_display_window_flag; - HEVCWindow def_disp_win; - - int vui_timing_info_present_flag; - uint32_t vui_num_units_in_tick; - uint32_t vui_time_scale; - int vui_poc_proportional_to_timing_flag; - int vui_num_ticks_poc_diff_one_minus1; - int vui_hrd_parameters_present_flag; - - int bitstream_restriction_flag; - int tiles_fixed_structure_flag; - int motion_vectors_over_pic_boundaries_flag; - int restricted_ref_pic_lists_flag; - int min_spatial_segmentation_idc; - int max_bytes_per_pic_denom; - int max_bits_per_min_cu_denom; - int log2_max_mv_length_horizontal; - int log2_max_mv_length_vertical; -} VUI; - -typedef struct PTLCommon { - uint8_t profile_space; - uint8_t tier_flag; - uint8_t profile_idc; - uint8_t profile_compatibility_flag[32]; - uint8_t level_idc; - uint8_t progressive_source_flag; - uint8_t interlaced_source_flag; - uint8_t non_packed_constraint_flag; - uint8_t frame_only_constraint_flag; -} PTLCommon; - -typedef struct PTL { - PTLCommon general_ptl; - PTLCommon sub_layer_ptl[HEVC_MAX_SUB_LAYERS]; - - uint8_t sub_layer_profile_present_flag[HEVC_MAX_SUB_LAYERS]; - uint8_t sub_layer_level_present_flag[HEVC_MAX_SUB_LAYERS]; -} PTL; - -typedef struct HEVCVPS { - uint8_t vps_temporal_id_nesting_flag; - int vps_max_layers; - int vps_max_sub_layers; ///< vps_max_temporal_layers_minus1 + 1 - - PTL ptl; - int vps_sub_layer_ordering_info_present_flag; - unsigned int vps_max_dec_pic_buffering[HEVC_MAX_SUB_LAYERS]; - unsigned int vps_num_reorder_pics[HEVC_MAX_SUB_LAYERS]; - unsigned int vps_max_latency_increase[HEVC_MAX_SUB_LAYERS]; - int vps_max_layer_id; - int vps_num_layer_sets; ///< vps_num_layer_sets_minus1 + 1 - uint8_t vps_timing_info_present_flag; - uint32_t vps_num_units_in_tick; - uint32_t vps_time_scale; - uint8_t vps_poc_proportional_to_timing_flag; - int vps_num_ticks_poc_diff_one; ///< vps_num_ticks_poc_diff_one_minus1 + 1 - int vps_num_hrd_parameters; -} HEVCVPS; - -typedef struct ScalingList { - /* This is a little wasteful, since sizeID 0 only needs 8 coeffs, - * and size ID 3 only has 2 arrays, not 6. */ - uint8_t sl[4][6][64]; - uint8_t sl_dc[2][6]; -} ScalingList; - -typedef struct HEVCSPS { - int vps_id; - int chroma_format_idc; - uint8_t separate_colour_plane_flag; - - ///< output (i.e. cropped) values - int output_width, output_height; - HEVCWindow output_window; - - HEVCWindow pic_conf_win; - - int bit_depth; - int pixel_shift; - enum AVPixelFormat pix_fmt; - - unsigned int log2_max_poc_lsb; - int pcm_enabled_flag; - - int max_sub_layers; - struct { - int max_dec_pic_buffering; - int num_reorder_pics; - int max_latency_increase; - } temporal_layer[HEVC_MAX_SUB_LAYERS]; - - VUI vui; - PTL ptl; - - uint8_t scaling_list_enable_flag; - ScalingList scaling_list; - - unsigned int nb_st_rps; - ShortTermRPS st_rps[HEVC_MAX_SHORT_TERM_RPS_COUNT]; - - uint8_t amp_enabled_flag; - uint8_t sao_enabled; - - uint8_t long_term_ref_pics_present_flag; - uint16_t lt_ref_pic_poc_lsb_sps[32]; - uint8_t used_by_curr_pic_lt_sps_flag[32]; - uint8_t num_long_term_ref_pics_sps; - - struct { - uint8_t bit_depth; - uint8_t bit_depth_chroma; - unsigned int log2_min_pcm_cb_size; - unsigned int log2_max_pcm_cb_size; - uint8_t loop_filter_disable_flag; - } pcm; - uint8_t sps_temporal_mvp_enabled_flag; - uint8_t sps_strong_intra_smoothing_enable_flag; - - unsigned int log2_min_cb_size; - unsigned int log2_diff_max_min_coding_block_size; - unsigned int log2_min_tb_size; - unsigned int log2_max_trafo_size; - unsigned int log2_ctb_size; - unsigned int log2_min_pu_size; - - int max_transform_hierarchy_depth_inter; - int max_transform_hierarchy_depth_intra; - - ///< coded frame dimension in various units - int width; - int height; - int ctb_width; - int ctb_height; - int ctb_size; - int min_cb_width; - int min_cb_height; - int min_tb_width; - int min_tb_height; - int min_pu_width; - int min_pu_height; - - int hshift[3]; - int vshift[3]; - - int qp_bd_offset; -} HEVCSPS; - -typedef struct HEVCPPS { - unsigned int sps_id; ///< seq_parameter_set_id - - uint8_t sign_data_hiding_flag; - - uint8_t cabac_init_present_flag; - - int num_ref_idx_l0_default_active; ///< num_ref_idx_l0_default_active_minus1 + 1 - int num_ref_idx_l1_default_active; ///< num_ref_idx_l1_default_active_minus1 + 1 - int pic_init_qp_minus26; - - uint8_t constrained_intra_pred_flag; - uint8_t transform_skip_enabled_flag; - - uint8_t cu_qp_delta_enabled_flag; - int diff_cu_qp_delta_depth; - - int cb_qp_offset; - int cr_qp_offset; - uint8_t pic_slice_level_chroma_qp_offsets_present_flag; - uint8_t weighted_pred_flag; - uint8_t weighted_bipred_flag; - uint8_t output_flag_present_flag; - uint8_t transquant_bypass_enable_flag; - - uint8_t dependent_slice_segments_enabled_flag; - uint8_t tiles_enabled_flag; - uint8_t entropy_coding_sync_enabled_flag; - - int num_tile_columns; ///< num_tile_columns_minus1 + 1 - int num_tile_rows; ///< num_tile_rows_minus1 + 1 - uint8_t uniform_spacing_flag; - uint8_t loop_filter_across_tiles_enabled_flag; - - uint8_t seq_loop_filter_across_slices_enabled_flag; - - uint8_t deblocking_filter_control_present_flag; - uint8_t deblocking_filter_override_enabled_flag; - uint8_t disable_dbf; - int beta_offset; ///< beta_offset_div2 * 2 - int tc_offset; ///< tc_offset_div2 * 2 - - uint8_t scaling_list_data_present_flag; - ScalingList scaling_list; - - uint8_t lists_modification_present_flag; - int log2_parallel_merge_level; ///< log2_parallel_merge_level_minus2 + 2 - int num_extra_slice_header_bits; - uint8_t slice_header_extension_present_flag; - - // Inferred parameters - unsigned int *column_width; ///< ColumnWidth - unsigned int *row_height; ///< RowHeight - unsigned int *col_bd; ///< ColBd - unsigned int *row_bd; ///< RowBd - int *col_idxX; - - int *ctb_addr_rs_to_ts; ///< CtbAddrRSToTS - int *ctb_addr_ts_to_rs; ///< CtbAddrTSToRS - int *tile_id; ///< TileId - int *tile_pos_rs; ///< TilePosRS - int *min_tb_addr_zs; ///< MinTbAddrZS -} HEVCPPS; - -typedef struct HEVCParamSets { - AVBufferRef *vps_list[HEVC_MAX_VPS_COUNT]; - AVBufferRef *sps_list[HEVC_MAX_SPS_COUNT]; - AVBufferRef *pps_list[HEVC_MAX_PPS_COUNT]; - - /* currently active parameter sets */ - const HEVCVPS *vps; - const HEVCSPS *sps; - const HEVCPPS *pps; -} HEVCParamSets; - typedef struct SliceHeader { unsigned int pps_id; @@ -819,27 +555,6 @@ typedef struct HEVCContext { int sei_hflip, sei_vflip; } HEVCContext; -int ff_hevc_decode_short_term_rps(GetBitContext *gb, AVCodecContext *avctx, - ShortTermRPS *rps, const HEVCSPS *sps, int is_slice_header); - -/** - * Parse the SPS from the bitstream into the provided HEVCSPS struct. - * - * @param sps_id the SPS id will be written here - * @param apply_defdispwin if set 1, the default display window from the VUI - * will be applied to the video dimensions - * @param vps_list if non-NULL, this function will validate that the SPS refers - * to an existing VPS - */ -int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, - int apply_defdispwin, AVBufferRef **vps_list, AVCodecContext *avctx); - -int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx, - HEVCParamSets *ps); -int ff_hevc_decode_nal_sps(GetBitContext *gb, AVCodecContext *avctx, - HEVCParamSets *ps, int apply_defdispwin); -int ff_hevc_decode_nal_pps(GetBitContext *gb, AVCodecContext *avctx, - HEVCParamSets *ps); int ff_hevc_decode_nal_sei(HEVCContext *s); /** @@ -959,9 +674,6 @@ void ff_hevc_hls_filters(HEVCContext *s, int x_ctb, int y_ctb, int ctb_size); void ff_hevc_pred_init(HEVCPredContext *hpc, int bit_depth); -int ff_hevc_encode_nal_vps(HEVCVPS *vps, unsigned int id, - uint8_t *buf, int buf_size); - extern const uint8_t ff_hevc_qpel_extra_before[4]; extern const uint8_t ff_hevc_qpel_extra_after[4]; extern const uint8_t ff_hevc_qpel_extra[4]; From 89b35a139e838deeb32ec20d8d034c81014401d0 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 21 Aug 2016 17:08:34 +0200 Subject: [PATCH 0304/3374] lavc: add a bitstream filter for extracting extradata from packets This is intended as a replacement for the 'split' function exported by some parsers. --- doc/bitstream_filters.texi | 18 ++ libavcodec/Makefile | 1 + libavcodec/bitstream_filters.c | 1 + libavcodec/extract_extradata_bsf.c | 300 +++++++++++++++++++++++++++++ libavcodec/version.h | 4 +- 5 files changed, 322 insertions(+), 2 deletions(-) create mode 100644 libavcodec/extract_extradata_bsf.c diff --git a/doc/bitstream_filters.texi b/doc/bitstream_filters.texi index 6e7f8781ee383..7ddf52e34d62e 100644 --- a/doc/bitstream_filters.texi +++ b/doc/bitstream_filters.texi @@ -21,6 +21,24 @@ Below is a description of the currently available bitstream filters. @section dump_extradata +@section extract_extradata + +Extract the in-band extradata. + +Certain codecs allow the long-term headers (e.g. MPEG-2 sequence headers, +or H.264/HEVC (VPS/)SPS/PPS) to be transmitted either "in-band" (i.e. as a part +of the bitstream containing the coded frames) or "out of band" (e.g. on the +container level). This latter form is called "extradata" in Libav terminology. + +This bitstream filter detects the in-band headers and makes them available as +extradata. + +@table @option +@item remove +When this option is enabled, the long-term headers are removed from the +bitstream after extraction. +@end table + @section h264_mp4toannexb @section imx_dump_header diff --git a/libavcodec/Makefile b/libavcodec/Makefile index d4579f9b97ab5..66a6c66a93ad8 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -748,6 +748,7 @@ OBJS-$(CONFIG_AAC_ADTSTOASC_BSF) += aac_adtstoasc_bsf.o aacadtsdec.o \ mpeg4audio.o OBJS-$(CONFIG_CHOMP_BSF) += chomp_bsf.o OBJS-$(CONFIG_DUMP_EXTRADATA_BSF) += dump_extradata_bsf.o +OBJS-$(CONFIG_EXTRACT_EXTRADATA_BSF) += extract_extradata_bsf.o OBJS-$(CONFIG_H264_MP4TOANNEXB_BSF) += h264_mp4toannexb_bsf.o OBJS-$(CONFIG_HEVC_MP4TOANNEXB_BSF) += hevc_mp4toannexb_bsf.o OBJS-$(CONFIG_IMX_DUMP_HEADER_BSF) += imx_dump_header_bsf.o diff --git a/libavcodec/bitstream_filters.c b/libavcodec/bitstream_filters.c index 3b4026cbff5c2..8a5379ec93c15 100644 --- a/libavcodec/bitstream_filters.c +++ b/libavcodec/bitstream_filters.c @@ -27,6 +27,7 @@ extern const AVBitStreamFilter ff_aac_adtstoasc_bsf; extern const AVBitStreamFilter ff_chomp_bsf; extern const AVBitStreamFilter ff_dump_extradata_bsf; +extern const AVBitStreamFilter ff_extract_extradata_bsf; extern const AVBitStreamFilter ff_h264_mp4toannexb_bsf; extern const AVBitStreamFilter ff_hevc_mp4toannexb_bsf; extern const AVBitStreamFilter ff_imx_dump_header_bsf; diff --git a/libavcodec/extract_extradata_bsf.c b/libavcodec/extract_extradata_bsf.c new file mode 100644 index 0000000000000..20b30803b8c76 --- /dev/null +++ b/libavcodec/extract_extradata_bsf.c @@ -0,0 +1,300 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/common.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/log.h" +#include "libavutil/opt.h" + +#include "avcodec.h" +#include "bsf.h" +#include "h2645_parse.h" +#include "h264.h" +#include "hevc.h" +#include "vc1_common.h" + +typedef struct ExtractExtradataContext { + const AVClass *class; + + int (*extract)(AVBSFContext *ctx, AVPacket *pkt, + uint8_t **data, int *size); + + /* AVOptions */ + int remove; +} ExtractExtradataContext; + +static int val_in_array(const int *arr, int len, int val) +{ + int i; + for (i = 0; i < len; i++) + if (arr[i] == val) + return 1; + return 0; +} + +static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt, + uint8_t **data, int *size) +{ + static const int extradata_nal_types_hevc[] = { + HEVC_NAL_VPS, HEVC_NAL_SPS, HEVC_NAL_PPS, + }; + static const int extradata_nal_types_h264[] = { + H264_NAL_SPS, H264_NAL_PPS, + }; + + ExtractExtradataContext *s = ctx->priv_data; + + H2645Packet h2645_pkt = { 0 }; + int extradata_size = 0; + const int *extradata_nal_types; + int nb_extradata_nal_types; + int i, ret = 0; + + if (ctx->par_in->codec_id == AV_CODEC_ID_HEVC) { + extradata_nal_types = extradata_nal_types_hevc; + nb_extradata_nal_types = FF_ARRAY_ELEMS(extradata_nal_types_hevc); + } else { + extradata_nal_types = extradata_nal_types_h264; + nb_extradata_nal_types = FF_ARRAY_ELEMS(extradata_nal_types_h264); + } + + ret = ff_h2645_packet_split(&h2645_pkt, pkt->data, pkt->size, + ctx, 0, 0, ctx->par_in->codec_id); + if (ret < 0) + return ret; + + for (i = 0; i < h2645_pkt.nb_nals; i++) { + H2645NAL *nal = &h2645_pkt.nals[i]; + if (val_in_array(extradata_nal_types, nb_extradata_nal_types, nal->type)) + extradata_size += nal->raw_size + 3; + } + + if (extradata_size) { + AVBufferRef *filtered_buf; + uint8_t *extradata, *filtered_data; + + if (s->remove) { + filtered_buf = av_buffer_alloc(pkt->size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!filtered_buf) + goto fail; + filtered_data = filtered_buf->data; + } + + extradata = av_malloc(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!extradata) { + av_buffer_unref(&filtered_buf); + goto fail; + } + + *data = extradata; + *size = extradata_size; + + for (i = 0; i < h2645_pkt.nb_nals; i++) { + H2645NAL *nal = &h2645_pkt.nals[i]; + if (val_in_array(extradata_nal_types, nb_extradata_nal_types, + nal->type)) { + AV_WB24(extradata, 1); // startcode + memcpy(extradata + 3, nal->raw_data, nal->raw_size); + extradata += 3 + nal->raw_size; + } else if (s->remove) { + AV_WB24(filtered_data, 1); // startcode + memcpy(filtered_data + 3, nal->raw_data, nal->raw_size); + filtered_data += 3 + nal->raw_size; + } + } + + if (s->remove) { + av_buffer_unref(&pkt->buf); + pkt->buf = filtered_buf; + pkt->data = filtered_buf->data; + pkt->size = filtered_data - filtered_buf->data; + } + } + +fail: + ff_h2645_packet_uninit(&h2645_pkt); + return ret; +} + +static int extract_extradata_vc1(AVBSFContext *ctx, AVPacket *pkt, + uint8_t **data, int *size) +{ + ExtractExtradataContext *s = ctx->priv_data; + uint32_t state = UINT32_MAX; + int has_extradata = 0, extradata_size = 0; + int i; + + for (i = 0; i < pkt->size; i++) { + state = (state << 8) | pkt->data[i]; + if (IS_MARKER(state)) { + if (state == VC1_CODE_SEQHDR || state == VC1_CODE_ENTRYPOINT) { + has_extradata = 1; + } else if (has_extradata) { + extradata_size = i - 3; + break; + } + } + } + + if (extradata_size) { + *data = av_malloc(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!*data) + return AVERROR(ENOMEM); + + memcpy(*data, pkt->data, extradata_size); + *size = extradata_size; + + if (s->remove) { + pkt->data += extradata_size; + pkt->size -= extradata_size; + } + } + + return 0; +} + +static int extract_extradata_mpeg124(AVBSFContext *ctx, AVPacket *pkt, + uint8_t **data, int *size) +{ + ExtractExtradataContext *s = ctx->priv_data; + int is_mpeg12 = ctx->par_in->codec_id == AV_CODEC_ID_MPEG1VIDEO || + ctx->par_in->codec_id == AV_CODEC_ID_MPEG2VIDEO; + uint32_t state = UINT32_MAX; + int i; + + for (i = 0; i < pkt->size; i++) { + state = (state << 8) | pkt->data[i]; + if ((is_mpeg12 && state != 0x1B3 && state != 0x1B5 && state < 0x200 && state >= 0x100) || + (!is_mpeg12 && (state == 0x1B3 || state == 0x1B6))) { + if (i > 3) { + *size = i - 3; + *data = av_malloc(*size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!*data) + return AVERROR(ENOMEM); + + memcpy(*data, pkt->data, *size); + + if (s->remove) { + pkt->data += *size; + pkt->size -= *size; + } + } + break; + } + } + return 0; +} + +static const struct { + enum AVCodecID id; + int (*extract)(AVBSFContext *ctx, AVPacket *pkt, + uint8_t **data, int *size); +} extract_tab[] = { + { AV_CODEC_ID_CAVS, extract_extradata_mpeg124 }, + { AV_CODEC_ID_H264, extract_extradata_h2645 }, + { AV_CODEC_ID_HEVC, extract_extradata_h2645 }, + { AV_CODEC_ID_MPEG1VIDEO, extract_extradata_mpeg124 }, + { AV_CODEC_ID_MPEG2VIDEO, extract_extradata_mpeg124 }, + { AV_CODEC_ID_MPEG4, extract_extradata_mpeg124 }, + { AV_CODEC_ID_VC1, extract_extradata_vc1 }, +}; + +static int extract_extradata_init(AVBSFContext *ctx) +{ + ExtractExtradataContext *s = ctx->priv_data; + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(extract_tab); i++) { + if (extract_tab[i].id == ctx->par_in->codec_id) { + s->extract = extract_tab[i].extract; + break; + } + } + if (!s->extract) + return AVERROR_BUG; + + return 0; +} + +static int extract_extradata_filter(AVBSFContext *ctx, AVPacket *out) +{ + ExtractExtradataContext *s = ctx->priv_data; + AVPacket *in; + uint8_t *extradata = NULL; + int extradata_size; + int ret = 0; + + ret = ff_bsf_get_packet(ctx, &in); + if (ret < 0) + return ret; + + ret = s->extract(ctx, in, &extradata, &extradata_size); + if (ret < 0) + goto fail; + + if (extradata) { + ret = av_packet_add_side_data(in, AV_PKT_DATA_NEW_EXTRADATA, + extradata, extradata_size); + if (ret < 0) { + av_freep(&extradata); + goto fail; + } + } + + av_packet_move_ref(out, in); + +fail: + av_packet_free(&in); + return ret; +} + +static const enum AVCodecID codec_ids[] = { + AV_CODEC_ID_CAVS, + AV_CODEC_ID_H264, + AV_CODEC_ID_HEVC, + AV_CODEC_ID_MPEG1VIDEO, + AV_CODEC_ID_MPEG2VIDEO, + AV_CODEC_ID_MPEG4, + AV_CODEC_ID_VC1, + AV_CODEC_ID_NONE, +}; + +#define OFFSET(x) offsetof(ExtractExtradataContext, x) +static const AVOption options[] = { + { "remove", "remove the extradata from the bitstream", OFFSET(remove), AV_OPT_TYPE_INT, + { .i64 = 0 }, 0, 1 }, + { NULL }, +}; + +static const AVClass extract_extradata_class = { + .class_name = "extract_extradata", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +const AVBitStreamFilter ff_extract_extradata_bsf = { + .name = "extract_extradata", + .codec_ids = codec_ids, + .priv_data_size = sizeof(ExtractExtradataContext), + .priv_class = &extract_extradata_class, + .init = extract_extradata_init, + .filter = extract_extradata_filter, +}; diff --git a/libavcodec/version.h b/libavcodec/version.h index 3f217118dd305..64b0ee6fd6d21 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 27 -#define LIBAVCODEC_VERSION_MICRO 2 +#define LIBAVCODEC_VERSION_MINOR 28 +#define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From 8e2ea691351c5079cdab245ff7bfa5c0f3e3bfe4 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 22 Sep 2016 15:24:34 +0200 Subject: [PATCH 0305/3374] lavf: use the new bitstream filter for extracting extradata This also fixes a minor bug introduced in the codecpar conversion, where the termination condition for extracting the extradata does not match the actual extradata setting code. As a result, the packet durations made up by lavf go back to their values before the codecpar conversion. That is of little consequence since that code should eventually be dropped completely. --- libavformat/internal.h | 9 +++ libavformat/utils.c | 123 ++++++++++++++++++++++++++++++++++----- tests/ref/fate/iv8-demux | 10 ++-- tests/ref/fate/wtv-demux | 68 +++++++++++----------- 4 files changed, 158 insertions(+), 52 deletions(-) diff --git a/libavformat/internal.h b/libavformat/internal.h index de55af5af4d87..52cd29b9b79b5 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -113,6 +113,15 @@ struct AVStreamInternal { enum AVCodecID orig_codec_id; + /* the context for extracting extradata in find_stream_info() + * inited=1/bsf=NULL signals that extracting is not possible (codec not + * supported) */ + struct { + AVBSFContext *bsf; + AVPacket *pkt; + int inited; + } extract_extradata; + #if FF_API_LAVF_AVCTX // whether the deprecated stream codec context needs // to be filled from the codec parameters diff --git a/libavformat/utils.c b/libavformat/utils.c index 0e94b15b7269b..1c93326ab22b6 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2089,6 +2089,104 @@ static int get_std_framerate(int i) return ((const int[]) { 24, 30, 60, 12, 15 })[i - 60 * 12] * 1000 * 12; } +static int extract_extradata_init(AVStream *st) +{ + AVStreamInternal *i = st->internal; + const AVBitStreamFilter *f; + int ret; + + f = av_bsf_get_by_name("extract_extradata"); + if (!f) + goto finish; + + i->extract_extradata.pkt = av_packet_alloc(); + if (!i->extract_extradata.pkt) + return AVERROR(ENOMEM); + + ret = av_bsf_alloc(f, &i->extract_extradata.bsf); + if (ret < 0) + goto fail; + + ret = avcodec_parameters_copy(i->extract_extradata.bsf->par_in, + st->codecpar); + if (ret < 0) + goto fail; + + i->extract_extradata.bsf->time_base_in = st->time_base; + + /* if init fails here, we assume extracting extradata is just not + * supported for this codec, so we return success */ + ret = av_bsf_init(i->extract_extradata.bsf); + if (ret < 0) { + av_bsf_free(&i->extract_extradata.bsf); + ret = 0; + } + +finish: + i->extract_extradata.inited = 1; + + return 0; +fail: + av_bsf_free(&i->extract_extradata.bsf); + av_packet_free(&i->extract_extradata.pkt); + return ret; +} + +static int extract_extradata(AVStream *st, AVPacket *pkt) +{ + AVStreamInternal *i = st->internal; + AVPacket *pkt_ref; + int ret; + + if (!i->extract_extradata.inited) { + ret = extract_extradata_init(st); + if (ret < 0) + return ret; + } + + if (i->extract_extradata.inited && !i->extract_extradata.bsf) + return 0; + + pkt_ref = i->extract_extradata.pkt; + ret = av_packet_ref(pkt_ref, pkt); + if (ret < 0) + return ret; + + ret = av_bsf_send_packet(i->extract_extradata.bsf, pkt_ref); + if (ret < 0) { + av_packet_unref(pkt_ref); + return ret; + } + + while (ret >= 0 && !i->avctx->extradata) { + int extradata_size; + uint8_t *extradata; + + ret = av_bsf_receive_packet(i->extract_extradata.bsf, pkt_ref); + if (ret < 0) { + if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) + return ret; + continue; + } + + extradata = av_packet_get_side_data(pkt_ref, AV_PKT_DATA_NEW_EXTRADATA, + &extradata_size); + + if (extradata) { + i->avctx->extradata = av_mallocz(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!i->avctx->extradata) { + av_packet_unref(pkt_ref); + return AVERROR(ENOMEM); + } + memcpy(i->avctx->extradata, extradata, extradata_size); + i->avctx->extradata_size = extradata_size; + } + av_packet_unref(pkt_ref); + } + + return 0; +} + int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) { int i, count, ret, read_size, j; @@ -2194,8 +2292,10 @@ FF_ENABLE_DEPRECATION_WARNINGS st->codec_info_nb_frames < fps_analyze_framecount && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) break; - if (st->parser && st->parser->parser->split && - !st->codecpar->extradata) + if (!st->codecpar->extradata && + !st->internal->avctx->extradata && + (!st->internal->extract_extradata.inited || + st->internal->extract_extradata.bsf)) break; if (st->first_dts == AV_NOPTS_VALUE && st->codec_info_nb_frames < ic->max_ts_probe && @@ -2331,17 +2431,10 @@ FF_ENABLE_DEPRECATION_WARNINGS break; } } - if (st->parser && st->parser->parser->split && !avctx->extradata) { - int i = st->parser->parser->split(avctx, pkt->data, pkt->size); - if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) { - avctx->extradata_size = i; - avctx->extradata = av_mallocz(avctx->extradata_size + - AV_INPUT_BUFFER_PADDING_SIZE); - if (!avctx->extradata) - return AVERROR(ENOMEM); - memcpy(avctx->extradata, pkt->data, - avctx->extradata_size); - } + if (!st->internal->avctx->extradata) { + ret = extract_extradata(st, pkt); + if (ret < 0) + goto find_stream_info_err; } /* If still no information, we try to open the codec and to @@ -2468,6 +2561,8 @@ FF_ENABLE_DEPRECATION_WARNINGS find_stream_info_err: for (i = 0; i < ic->nb_streams; i++) { av_freep(&ic->streams[i]->info); + av_bsf_free(&ic->streams[i]->internal->extract_extradata.bsf); + av_packet_free(&ic->streams[i]->internal->extract_extradata.pkt); } return ret; } @@ -2575,6 +2670,8 @@ static void free_stream(AVStream **pst) if (st->internal) { avcodec_free_context(&st->internal->avctx); + av_bsf_free(&st->internal->extract_extradata.bsf); + av_packet_free(&st->internal->extract_extradata.pkt); } av_freep(&st->internal); diff --git a/tests/ref/fate/iv8-demux b/tests/ref/fate/iv8-demux index f13e691944c93..56a54a11dbe95 100644 --- a/tests/ref/fate/iv8-demux +++ b/tests/ref/fate/iv8-demux @@ -19,8 +19,8 @@ 0, 57600, 61200, 0, 20874, 0xed0b91ec 0, 61200, 64799, 0, 20877, 0xe1623e01 0, 64799, 68399, 0, 20933, 0x19906564 -0, 68399, 72000, 0, 20891, 0x3d064fd3 -0, 72000, 75600, 0, 20834, 0xcb774dbc -0, 75600, 79200, 0, 20870, 0xbc536589 -0, 79200, 82800, 0, 21421, 0xc99a68e4 -0, 82800, 86400, 0, 12869, 0x5684e304 +0, 68399, 72000, 3600, 20891, 0x3d064fd3 +0, 72000, 75600, 3600, 20834, 0xcb774dbc +0, 75600, 79200, 3600, 20870, 0xbc536589 +0, 79200, 82800, 3600, 21421, 0xc99a68e4 +0, 82800, 86400, 3600, 12869, 0x5684e304 diff --git a/tests/ref/fate/wtv-demux b/tests/ref/fate/wtv-demux index ae44958005439..bdd6c20b427bc 100644 --- a/tests/ref/fate/wtv-demux +++ b/tests/ref/fate/wtv-demux @@ -59,83 +59,83 @@ 0, 11486331, 11486331, 400000, 6156, 0xe168394b 1, 11519998, 11519998, 240000, 576, 0x1fea1448 1, 11759998, 11759998, 240000, 576, 0x55840a01 -0, 11886331, 13086442, 400000, 23364, 0x53164f1e +0, 11886331, 13086442, 449438, 23364, 0x53164f1e 1, 11999998, 11999998, 240000, 576, 0x6c9c24ce 1, 12239998, 12239998, 240000, 576, 0x955f1e97 -0, 12286442, 12286442, 400000, 6708, 0x89877269 +0, 12286442, 12286442, 449438, 6708, 0x89877269 1, 12479998, 12479998, 240000, 576, 0x2827134f -0, 12686442, 12686442, 400000, 6908, 0x8d62a249 +0, 12686442, 12686442, 449438, 6908, 0x8d62a249 1, 12719998, 12719998, 240000, 576, 0x34a01c29 1, 12959998, 12959998, 240000, 576, 0x7d351e52 -0, 13086442, 14286442, 400000, 38156, 0xec41f682 +0, 13086442, 14286442, 449438, 38156, 0xec41f682 1, 13199998, 13199998, 240000, 576, 0x00c91d9e 1, 13439998, 13439998, 240000, 576, 0x57ea1a97 -0, 13486331, 13486331, 400000, 5764, 0xcc04534b +0, 13486331, 13486331, 449438, 5764, 0xcc04534b 1, 13679998, 13679998, 240000, 576, 0xef3a1c74 -0, 13886331, 13886331, 400000, 5388, 0xb8a1c3c5 +0, 13886331, 13886331, 449438, 5388, 0xb8a1c3c5 1, 13919998, 13919998, 240000, 576, 0x11fc217d 1, 14159998, 14159998, 240000, 576, 0x59ce20e5 -0, 14286442, 15486331, 400000, 16764, 0x59460d96 +0, 14286442, 15486331, 449438, 16764, 0x59460d96 1, 14399998, 14399998, 240000, 576, 0xaafc1dbf 1, 14639998, 14639998, 240000, 576, 0xdd941609 -0, 14686331, 14686331, 400000, 5548, 0x5c91e93d +0, 14686331, 14686331, 449438, 5548, 0x5c91e93d 1, 14879998, 14879998, 240000, 576, 0x900420b0 -0, 15086331, 15086331, 400000, 5652, 0x5e321aed +0, 15086331, 15086331, 449438, 5652, 0x5e321aed 1, 15119998, 15119998, 240000, 576, 0x5f4f1aa1 1, 15359998, 15359998, 240000, 576, 0x7d7e18de -0, 15486331, 16686331, 400000, 15564, 0xefdf5080 +0, 15486331, 16686331, 449438, 15564, 0xefdf5080 1, 15599998, 15599998, 240000, 576, 0x986c0d9d 1, 15839998, 15839998, 240000, 576, 0xcb4c21c0 -0, 15886331, 15886331, 400000, 6492, 0xd1d5c5f8 +0, 15886331, 15886331, 449438, 6492, 0xd1d5c5f8 1, 16079998, 16079998, 240000, 576, 0xbcfb1e8b -0, 16286331, 16286331, 400000, 5604, 0xf9472b44 +0, 16286331, 16286331, 449438, 5604, 0xf9472b44 1, 16319998, 16319998, 240000, 576, 0xcb541b4c 1, 16559998, 16559998, 240000, 576, 0x980426e9 -0, 16686331, 17886331, 400000, 17924, 0x45815b7b +0, 16686331, 17886331, 449438, 17924, 0x45815b7b 1, 16799998, 16799998, 240000, 576, 0x09d00aa0 1, 17039998, 17039998, 240000, 576, 0xad591374 -0, 17086442, 17086442, 400000, 5020, 0x3cc5e554 +0, 17086442, 17086442, 449438, 5020, 0x3cc5e554 1, 17279998, 17279998, 240000, 576, 0x97bf1461 -0, 17486442, 17486442, 400000, 5276, 0xa0554c12 +0, 17486442, 17486442, 449438, 5276, 0xa0554c12 1, 17519998, 17519998, 240000, 576, 0xdc871cc4 1, 17759998, 17759998, 240000, 576, 0x56781896 -0, 17886331, 19086442, 400000, 31460, 0x5765eb5f +0, 17886331, 19086442, 449438, 31460, 0x5765eb5f 1, 17999998, 17999998, 240000, 576, 0xc77714e3 1, 18239998, 18239998, 240000, 576, 0x280e18d4 -0, 18286331, 18286331, 400000, 4972, 0x91adbab7 +0, 18286331, 18286331, 449438, 4972, 0x91adbab7 1, 18479998, 18479998, 240000, 576, 0xbc0d2302 -0, 18686442, 18686442, 400000, 5580, 0xfea707cb +0, 18686442, 18686442, 449438, 5580, 0xfea707cb 1, 18719998, 18719998, 240000, 576, 0x79191384 1, 18959998, 18959998, 240000, 576, 0x65481c97 -0, 19086442, 20286331, 400000, 17412, 0x0afe4d27 +0, 19086442, 20286331, 449438, 17412, 0x0afe4d27 1, 19199998, 19199998, 240000, 576, 0xc94d227d 1, 19439998, 19439998, 240000, 576, 0xa68a1f14 -0, 19486442, 19486442, 400000, 5236, 0x03f55309 +0, 19486442, 19486442, 449438, 5236, 0x03f55309 1, 19679998, 19679998, 240000, 576, 0x6af11a5c -0, 19886331, 19886331, 400000, 4924, 0x558e753c +0, 19886331, 19886331, 449438, 4924, 0x558e753c 1, 19919998, 19919998, 240000, 576, 0x4d1019ef 1, 20159998, 20159998, 240000, 576, 0x3b1b17b5 -0, 20286331, 21486331, 400000, 15396, 0xf145d121 +0, 20286331, 21486331, 449438, 15396, 0xf145d121 1, 20399998, 20399998, 240000, 576, 0xcdd8159f 1, 20639998, 20639998, 240000, 576, 0x97cd1d06 -0, 20686331, 20686331, 400000, 4708, 0x43066a92 +0, 20686331, 20686331, 449438, 4708, 0x43066a92 1, 20879998, 20879998, 240000, 576, 0x5d1b1123 -0, 21086442, 21086442, 400000, 4332, 0x9e22bcba +0, 21086442, 21086442, 449438, 4332, 0x9e22bcba 1, 21119998, 21119998, 240000, 576, 0x888d0cb0 1, 21359998, 21359998, 240000, 576, 0x556e1dad -0, 21486331, 22686442, 400000, 12876, 0x46ff9ef4 +0, 21486331, 22686442, 449438, 12876, 0x46ff9ef4 1, 21599998, 21599998, 240000, 576, 0xf7af0bce 1, 21839998, 21839998, 240000, 576, 0xb5da160a -0, 21886442, 21886442, 400000, 5940, 0x27cba62e +0, 21886442, 21886442, 449438, 5940, 0x27cba62e 1, 22079998, 22079998, 240000, 576, 0x4a8d0e98 -0, 22286442, 22286442, 400000, 6124, 0x6bab0a6d +0, 22286442, 22286442, 449438, 6124, 0x6bab0a6d 1, 22319998, 22319998, 240000, 576, 0x183b1c7e 1, 22559998, 22559998, 240000, 576, 0xc47120e6 -0, 22686442, 23886442, 400000, 36428, 0x942f9648 +0, 22686442, 23886442, 449438, 36428, 0x942f9648 1, 22799998, 22799998, 240000, 576, 0xb1f31346 -0, 23086331, 23086331, 400000, 6660, 0x545a0db7 -0, 23486331, 23486331, 400000, 6780, 0x2d1d4189 -0, 23886442, 25086331, 400000, 16460, 0x7c3b3ca4 -0, 24286442, 24286442, 400000, 6724, 0x8538cc6f -0, 24686442, 24686442, 400000, 7068, 0x69574fd0 -0, 25086331, 26286331, 400000, 19552, 0xf230e854 +0, 23086331, 23086331, 449438, 6660, 0x545a0db7 +0, 23486331, 23486331, 449438, 6780, 0x2d1d4189 +0, 23886442, 25086331, 449438, 16460, 0x7c3b3ca4 +0, 24286442, 24286442, 449438, 6724, 0x8538cc6f +0, 24686442, 24686442, 449438, 7068, 0x69574fd0 +0, 25086331, 26286331, 449438, 19552, 0xf230e854 From a05cc56124b4f1237f6355784de821e3290ddb44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 30 Sep 2016 11:49:47 +0300 Subject: [PATCH 0306/3374] checkasm: arm/aarch64: Fix the amount of space reserved for stack parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Even if MAX_ARGS - 2 (for arm) or MAX_ARGS - 7 (for aarch64) parameters are passed on the stack to checkasm_checked_call, we actually only need to store MAX_ARGS - 4 (for arm) or MAX_ARGS - 8 (for aarch64) parameters on the stack when calling the tested function. Signed-off-by: Martin Storsjö --- tests/checkasm/aarch64/checkasm.S | 4 ++-- tests/checkasm/arm/checkasm.S | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/checkasm/aarch64/checkasm.S b/tests/checkasm/aarch64/checkasm.S index 9668518c9b00d..39e83372b78f0 100644 --- a/tests/checkasm/aarch64/checkasm.S +++ b/tests/checkasm/aarch64/checkasm.S @@ -52,7 +52,7 @@ endconst // max number of args used by any asm function. #define MAX_ARGS 15 -#define ARG_STACK ((8*(MAX_ARGS - 7) + 15) & ~15) +#define ARG_STACK ((8*(MAX_ARGS - 8) + 15) & ~15) function checkasm_checked_call, export=1 stp x29, x30, [sp, #-16]! @@ -81,7 +81,7 @@ function checkasm_checked_call, export=1 sub sp, sp, #ARG_STACK .equ pos, 0 // the first stacked arg is copied to x7 -.rept MAX_ARGS-7 +.rept MAX_ARGS-8 ldr x9, [x29, #16 + 8 + pos] str x9, [sp, #pos] .equ pos, pos + 8 diff --git a/tests/checkasm/arm/checkasm.S b/tests/checkasm/arm/checkasm.S index 098f22eaefa6b..237252f97834f 100644 --- a/tests/checkasm/arm/checkasm.S +++ b/tests/checkasm/arm/checkasm.S @@ -50,7 +50,7 @@ endconst @ max number of args used by any asm function. #define MAX_ARGS 15 -#define ARG_STACK 4*(MAX_ARGS - 2) +#define ARG_STACK 4*(MAX_ARGS - 4) @ align the used stack space to 8 to preserve the stack alignment #define ARG_STACK_A (((ARG_STACK + pushed + 7) & ~7) - pushed) @@ -74,7 +74,7 @@ function checkasm_checked_call_\variant, export=1 sub sp, sp, #ARG_STACK_A .equ pos, 0 -.rept MAX_ARGS-2 +.rept MAX_ARGS-4 ldr r12, [sp, #ARG_STACK_A + pushed + 8 + pos] str r12, [sp, #pos] .equ pos, pos + 4 From f1b3e131385176c3c9d9783b25047856a0dcebf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 30 Sep 2016 11:39:22 +0300 Subject: [PATCH 0307/3374] checkasm: aarch64: Clobber the stack before calling functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- tests/checkasm/aarch64/checkasm.S | 13 +++++++++++++ tests/checkasm/checkasm.h | 6 +++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/tests/checkasm/aarch64/checkasm.S b/tests/checkasm/aarch64/checkasm.S index 39e83372b78f0..c22204fa344d6 100644 --- a/tests/checkasm/aarch64/checkasm.S +++ b/tests/checkasm/aarch64/checkasm.S @@ -52,6 +52,19 @@ endconst // max number of args used by any asm function. #define MAX_ARGS 15 +#define CLOBBER_STACK ((8*MAX_ARGS + 15) & ~15) + +function checkasm_stack_clobber, export=1 + mov x29, sp + mov x2, #CLOBBER_STACK +1: + stp x0, x1, [sp, #-16]! + subs x2, x2, #16 + b.gt 1b + mov sp, x29 + ret +endfunc + #define ARG_STACK ((8*(MAX_ARGS - 8) + 15) & ~15) function checkasm_checked_call, export=1 diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h index 5a4c056ce2241..2defc7f905c96 100644 --- a/tests/checkasm/checkasm.h +++ b/tests/checkasm/checkasm.h @@ -134,9 +134,13 @@ extern void (*checkasm_checked_call)(void *func, int dummy, ...); #define declare_new(ret, ...) ret (*checked_call)(void *, int dummy, __VA_ARGS__) = (void *)checkasm_checked_call; #define call_new(...) checked_call(func_new, 0, __VA_ARGS__) #elif ARCH_AARCH64 && !defined(__APPLE__) +void checkasm_stack_clobber(uint64_t clobber, ...); void checkasm_checked_call(void *func, ...); #define declare_new(ret, ...) ret (*checked_call)(void *, __VA_ARGS__) = (void *)checkasm_checked_call; -#define call_new(...) checked_call(func_new, __VA_ARGS__) +#define CLOB (UINT64_C(0xdeadbeefdeadbeef)) +#define call_new(...) (checkasm_stack_clobber(CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,\ + CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB),\ + checked_call(func_new, __VA_ARGS__)) #else #define declare_new(ret, ...) #define declare_new_emms(cpu_flags, ret, ...) From c91d6a33f872574c95c8784277cf60ffcf6bff4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 30 Sep 2016 12:06:49 +0300 Subject: [PATCH 0308/3374] checkasm: aarch64: Add filler args to make sure all parameters are passed on the stack MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This, combined with clobbering the stack space prior to the call, increases the chances of finding cases where 32 bit parameters are erroneously treated as 64 bit. Signed-off-by: Martin Storsjö --- tests/checkasm/aarch64/checkasm.S | 16 ++++++---------- tests/checkasm/checkasm.h | 5 +++-- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/tests/checkasm/aarch64/checkasm.S b/tests/checkasm/aarch64/checkasm.S index c22204fa344d6..65b352104e7b2 100644 --- a/tests/checkasm/aarch64/checkasm.S +++ b/tests/checkasm/aarch64/checkasm.S @@ -93,22 +93,18 @@ function checkasm_checked_call, export=1 sub sp, sp, #ARG_STACK .equ pos, 0 -// the first stacked arg is copied to x7 .rept MAX_ARGS-8 - ldr x9, [x29, #16 + 8 + pos] + // Skip the first 8 args, that are loaded into registers + ldr x9, [x29, #16 + 8*8 + pos] str x9, [sp, #pos] .equ pos, pos + 8 .endr mov x12, x0 - mov x0, x1 - mov x1, x2 - mov x2, x3 - mov x3, x4 - mov x4, x5 - mov x5, x6 - mov x6, x7 - ldr x7, [x29, #16] + ldp x0, x1, [x29, #16] + ldp x2, x3, [x29, #32] + ldp x4, x5, [x29, #48] + ldp x6, x7, [x29, #64] blr x12 add sp, sp, #ARG_STACK stp x0, x1, [sp, #-16]! diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h index 2defc7f905c96..75aa457572f99 100644 --- a/tests/checkasm/checkasm.h +++ b/tests/checkasm/checkasm.h @@ -136,11 +136,12 @@ extern void (*checkasm_checked_call)(void *func, int dummy, ...); #elif ARCH_AARCH64 && !defined(__APPLE__) void checkasm_stack_clobber(uint64_t clobber, ...); void checkasm_checked_call(void *func, ...); -#define declare_new(ret, ...) ret (*checked_call)(void *, __VA_ARGS__) = (void *)checkasm_checked_call; +#define declare_new(ret, ...) ret (*checked_call)(void *, int, int, int, int, int, int, int, __VA_ARGS__)\ + = (void *)checkasm_checked_call; #define CLOB (UINT64_C(0xdeadbeefdeadbeef)) #define call_new(...) (checkasm_stack_clobber(CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,\ CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB),\ - checked_call(func_new, __VA_ARGS__)) + checked_call(func_new, 0, 0, 0, 0, 0, 0, 0, __VA_ARGS__)) #else #define declare_new(ret, ...) #define declare_new_emms(cpu_flags, ret, ...) From 93d5b022a9fd3a1a1f9c521a1eac7f0410e05b81 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 8 Oct 2016 16:48:29 +0200 Subject: [PATCH 0309/3374] build: Drop duplicate asm recipe And move the asm recipe to the top-level Makefile next to the other local pattern rules for .o files. --- Makefile | 5 +++++ library.mak | 5 ----- tests/checkasm/x86/Makefile | 5 ----- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 4e026b07342d4..52cb0bd80d8df 100644 --- a/Makefile +++ b/Makefile @@ -56,6 +56,11 @@ COMPILE_HOSTC = $(call COMPILE,HOSTCC) %_host.o: %.c $(COMPILE_HOSTC) +%.o: %.asm + $(DEPYASM) $(YASMFLAGS) -I $( $(@:.o=.d) + $(YASM) $(YASMFLAGS) -I $( $(@:.o=.d) - $(YASM) $(YASMFLAGS) -I $( $(@:.o=.d) - $(YASM) $(YASMFLAGS) -I $( Date: Fri, 14 Oct 2016 01:24:36 +0200 Subject: [PATCH 0310/3374] build: Drop arch-specific checkasm Makefiles They only contain one line and will never contain more. --- tests/checkasm/Makefile | 4 +++- tests/checkasm/aarch64/Makefile | 1 - tests/checkasm/arm/Makefile | 1 - tests/checkasm/x86/Makefile | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) delete mode 100644 tests/checkasm/aarch64/Makefile delete mode 100644 tests/checkasm/arm/Makefile delete mode 100644 tests/checkasm/x86/Makefile diff --git a/tests/checkasm/Makefile b/tests/checkasm/Makefile index 9b3df55673c5d..22cf3db538cb6 100644 --- a/tests/checkasm/Makefile +++ b/tests/checkasm/Makefile @@ -19,7 +19,9 @@ AVCODECOBJS-$(CONFIG_VP9_DECODER) += vp9dsp.o CHECKASMOBJS-$(CONFIG_AVCODEC) += $(AVCODECOBJS-yes) --include $(SRC_PATH)/tests/checkasm/$(ARCH)/Makefile +CHECKASMOBJS-$(ARCH_AARCH64) += aarch64/checkasm.o +CHECKASMOBJS-$(HAVE_ARMV5TE_EXTERNAL) += arm/checkasm.o +CHECKASMOBJS-$(HAVE_YASM) += x86/checkasm.o CHECKASMOBJS += $(CHECKASMOBJS-yes) checkasm.o CHECKASMOBJS := $(sort $(CHECKASMOBJS:%=tests/checkasm/%)) diff --git a/tests/checkasm/aarch64/Makefile b/tests/checkasm/aarch64/Makefile deleted file mode 100644 index 02ba6cafa984e..0000000000000 --- a/tests/checkasm/aarch64/Makefile +++ /dev/null @@ -1 +0,0 @@ -CHECKASMOBJS += aarch64/checkasm.o diff --git a/tests/checkasm/arm/Makefile b/tests/checkasm/arm/Makefile deleted file mode 100644 index 55f2383d4c29e..0000000000000 --- a/tests/checkasm/arm/Makefile +++ /dev/null @@ -1 +0,0 @@ -CHECKASMOBJS-$(HAVE_ARMV5TE_EXTERNAL) += arm/checkasm.o diff --git a/tests/checkasm/x86/Makefile b/tests/checkasm/x86/Makefile deleted file mode 100644 index e1bef760179b4..0000000000000 --- a/tests/checkasm/x86/Makefile +++ /dev/null @@ -1 +0,0 @@ -CHECKASMOBJS-$(HAVE_YASM) += x86/checkasm.o From 6be7944ee2ec2f045e6eb9a93237e992c8b20ac4 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 17 Mar 2016 10:16:13 +0100 Subject: [PATCH 0311/3374] x86: Add missing colons after assembly labels This fixes many warnings of the sort warning: label alone on a line without a colon might be in error --- libavcodec/x86/audiodsp.asm | 2 +- libavcodec/x86/dcadsp.asm | 2 +- libavcodec/x86/h264_qpel_10bit.asm | 2 +- libavcodec/x86/h264_weight.asm | 4 ++-- libavcodec/x86/hevc_mc.asm | 12 ++++++------ libavcodec/x86/v210enc.asm | 4 ++-- libavfilter/x86/vf_interlace.asm | 2 +- libavutil/x86/imgutils.asm | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/libavcodec/x86/audiodsp.asm b/libavcodec/x86/audiodsp.asm index 1bc7e32a689dd..e038c18bd8371 100644 --- a/libavcodec/x86/audiodsp.asm +++ b/libavcodec/x86/audiodsp.asm @@ -153,7 +153,7 @@ cglobal vector_clipf, 3, 3, 6, dst, src, len, min, max movsxdifnidn lenq, lend -.loop +.loop: mova m2, [srcq + 4 * lenq - 4 * mmsize] mova m3, [srcq + 4 * lenq - 3 * mmsize] mova m4, [srcq + 4 * lenq - 2 * mmsize] diff --git a/libavcodec/x86/dcadsp.asm b/libavcodec/x86/dcadsp.asm index 89d4ac489a1e4..fa8d3cb66a36f 100644 --- a/libavcodec/x86/dcadsp.asm +++ b/libavcodec/x86/dcadsp.asm @@ -238,7 +238,7 @@ cglobal synth_filter_inner, 0, 6 + 4 * ARCH_X86_64, 7 + 6 * ARCH_X86_64, \ %if ARCH_X86_32 mov buf2, synth_buf2mp %endif -.mainloop +.mainloop: ; m1 = a m2 = b m3 = c m4 = d SETZERO m3 SETZERO m4 diff --git a/libavcodec/x86/h264_qpel_10bit.asm b/libavcodec/x86/h264_qpel_10bit.asm index f92c4aab2b8d3..4557e5e209bbe 100644 --- a/libavcodec/x86/h264_qpel_10bit.asm +++ b/libavcodec/x86/h264_qpel_10bit.asm @@ -386,7 +386,7 @@ MC_CACHE MC10 ; void ff_h264_qpel_mc02(uint8_t *dst, uint8_t *src, int stride) ;----------------------------------------------------------------------------- %macro V_FILT 10 -v_filt%9_%10_10 +v_filt%9_%10_10: add r4, r2 .no_addr4: FILT_V m0, m1, m2, m3, m4, m5, m6, m7 diff --git a/libavcodec/x86/h264_weight.asm b/libavcodec/x86/h264_weight.asm index e421ec8fbe783..f9da05b215f7e 100644 --- a/libavcodec/x86/h264_weight.asm +++ b/libavcodec/x86/h264_weight.asm @@ -139,12 +139,12 @@ WEIGHT_FUNC_HALF_MM 8, 8 je .nonnormal cmp r5d, 128 jne .normal -.nonnormal +.nonnormal: sar r5d, 1 sar r6d, 1 sar off_regd, 1 sub r4d, 1 -.normal +.normal: %if cpuflag(ssse3) movd m4, r5d movd m0, r6d diff --git a/libavcodec/x86/hevc_mc.asm b/libavcodec/x86/hevc_mc.asm index 8444c415ab169..16e5eefc69950 100644 --- a/libavcodec/x86/hevc_mc.asm +++ b/libavcodec/x86/hevc_mc.asm @@ -184,7 +184,7 @@ cglobal hevc_qpel_ %+ postfix %+ _ %+ %1 %+ _8, 7, 7, 7, dst, dststride, src, sr sub src_m3, pixstride3 %endif -.loop +.loop: %assign i 0 %rep nb_blocks @@ -285,7 +285,7 @@ QPEL_8 64, 1 sub srcm3q, sstride3q %endif -.loop +.loop: %assign i 0 %rep nb_blocks @@ -444,7 +444,7 @@ cglobal hevc_epel_ %+ postfix %+ _ %+ %1 %+ _8, 7, 7, 6, dst, dststride, src, sr %endif sub srcq, pixstride -.loop +.loop: %assign i 0 %rep nb_blocks @@ -519,7 +519,7 @@ EPEL_8 32, 1 %endif sub srcq, pixstride -.loop +.loop: %assign i 0 %rep nb_blocks @@ -651,7 +651,7 @@ cglobal hevc_put_unweighted_pred_ %+ %2 %+ _ %+ %3, 5, 5, 4, dst, dststride, src %define STORE_HALF movd %endif -.loop +.loop: %assign i 0 %rep (%2 + 7) / 8 @@ -772,7 +772,7 @@ cglobal hevc_put_weighted_pred_ %+ %2 %+ _ %+ %3, 8, 8, 8, denom, weight0, offse SPLATD m3 %endif -.loop +.loop: %assign i 0 %rep (%2 + 3) / 4 diff --git a/libavcodec/x86/v210enc.asm b/libavcodec/x86/v210enc.asm index ec4309fe73997..0db0196313ea3 100644 --- a/libavcodec/x86/v210enc.asm +++ b/libavcodec/x86/v210enc.asm @@ -56,7 +56,7 @@ cglobal v210_planar_pack_10, 5, 5, 4+cpuflag(avx2), y, u, v, dst, width mova m2, [v210_enc_min_10] mova m3, [v210_enc_max_10] -.loop +.loop: movu xm0, [yq+2*widthq] %if cpuflag(avx2) vinserti128 m0, m0, [yq+2*widthq+12], 1 @@ -112,7 +112,7 @@ cglobal v210_planar_pack_8, 5, 5, 7, y, u, v, dst, width mova m5, [v210_enc_max_8] pxor m6, m6 -.loop +.loop: movu xm1, [yq+2*widthq] %if cpuflag(avx2) vinserti128 m1, m1, [yq+2*widthq+12], 1 diff --git a/libavfilter/x86/vf_interlace.asm b/libavfilter/x86/vf_interlace.asm index 85811da8d1d8b..f2344216b3d00 100644 --- a/libavfilter/x86/vf_interlace.asm +++ b/libavfilter/x86/vf_interlace.asm @@ -37,7 +37,7 @@ cglobal lowpass_line, 5, 5, 7 pcmpeqb m6, m6 -.loop +.loop: mova m0, [r3+r1] mova m1, [r3+r1+mmsize] pavgb m0, [r4+r1] diff --git a/libavutil/x86/imgutils.asm b/libavutil/x86/imgutils.asm index 9c1e940822bc3..be7a47f6d0e50 100644 --- a/libavutil/x86/imgutils.asm +++ b/libavutil/x86/imgutils.asm @@ -28,10 +28,10 @@ cglobal image_copy_plane_uc_from, 6, 7, 4, dst, dst_linesize, src, src_linesize, add srcq, bwq neg bwq -.row_start +.row_start: mov rowposq, bwq -.loop +.loop: movntdqa m0, [srcq + rowposq + 0 * mmsize] movntdqa m1, [srcq + rowposq + 1 * mmsize] movntdqa m2, [srcq + rowposq + 2 * mmsize] From f9bb356e0eb38ab4df32df8276b71a0b2626538f Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 16 Oct 2016 23:55:24 +0100 Subject: [PATCH 0312/3374] vaapi_h265: Include header for slice types The include was changed correctly in 4abe3b049d987420eb891f74a35af2cebbf52144 but then mistakenly changed back by c359d624d3efc3fd1d83210d78c4152bd329b765 (it's not just the NAL unit types which are used). --- libavcodec/vaapi_encode_h265.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c index 776c228dd8874..ed36ef4215cbe 100644 --- a/libavcodec/vaapi_encode_h265.c +++ b/libavcodec/vaapi_encode_h265.c @@ -25,7 +25,7 @@ #include "libavutil/pixfmt.h" #include "avcodec.h" -#include "hevc.h" +#include "hevcdec.h" #include "internal.h" #include "put_bits.h" #include "vaapi_encode.h" From 0cf86fabfa5820596cca2cfead63c6f8df76c3f2 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 2 Oct 2016 08:48:34 +0100 Subject: [PATCH 0313/3374] vaapi_encode: Write sequence header as extradata Only works if packed headers are supported, where we can know the output before generating the first frame. --- libavcodec/vaapi_encode.c | 22 ++++++++++++++++++++++ libavcodec/vaapi_encode.h | 2 ++ 2 files changed, 24 insertions(+) diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index b600a0012124a..11e46eabe78b3 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -1399,6 +1399,28 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) // where it actually overlaps properly, though.) ctx->issue_mode = ISSUE_MODE_MAXIMISE_THROUGHPUT; + if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE && + ctx->codec->write_sequence_header) { + char data[MAX_PARAM_BUFFER_SIZE]; + size_t bit_len = 8 * sizeof(data); + + err = ctx->codec->write_sequence_header(avctx, data, &bit_len); + if (err < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to write sequence header " + "for extradata: %d.\n", err); + goto fail; + } else { + avctx->extradata_size = (bit_len + 7) / 8; + avctx->extradata = av_mallocz(avctx->extradata_size + + AV_INPUT_BUFFER_PADDING_SIZE); + if (!avctx->extradata) { + err = AVERROR(ENOMEM); + goto fail; + } + memcpy(avctx->extradata, data, avctx->extradata_size); + } + } + return 0; fail: diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h index c47d979db2c5b..a9ab52788096a 100644 --- a/libavcodec/vaapi_encode.h +++ b/libavcodec/vaapi_encode.h @@ -235,6 +235,8 @@ typedef struct VAAPIEncodeType { int slice_header_type; // Write the packed header data to the provided buffer. + // The sequence header is also used to fill the codec extradata + // when the encoder is starting. int (*write_sequence_header)(AVCodecContext *avctx, char *data, size_t *data_len); int (*write_picture_header)(AVCodecContext *avctx, From 58224dc5f3d4fea40a8d55cca87291a960c11622 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 12 Aug 2012 17:54:30 +0200 Subject: [PATCH 0314/3374] ppc: avcodec: Drop silly "_ppc" suffixes from files in ppc subdirectories --- libavcodec/ppc/Makefile | 2 +- libavcodec/ppc/{videodsp_ppc.c => videodsp.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename libavcodec/ppc/{videodsp_ppc.c => videodsp.c} (100%) diff --git a/libavcodec/ppc/Makefile b/libavcodec/ppc/Makefile index 9234e772877ad..09eabcb83b28a 100644 --- a/libavcodec/ppc/Makefile +++ b/libavcodec/ppc/Makefile @@ -19,7 +19,7 @@ OBJS-$(CONFIG_MPEGVIDEO) += ppc/mpegvideo_altivec.o \ OBJS-$(CONFIG_MPEGVIDEOENC) += ppc/mpegvideoencdsp.o OBJS-$(CONFIG_PIXBLOCKDSP) += ppc/pixblockdsp.o OBJS-$(CONFIG_VC1DSP) += ppc/vc1dsp_altivec.o -OBJS-$(CONFIG_VIDEODSP) += ppc/videodsp_ppc.o +OBJS-$(CONFIG_VIDEODSP) += ppc/videodsp.o OBJS-$(CONFIG_VP3DSP) += ppc/vp3dsp_altivec.o OBJS-$(CONFIG_VP8DSP) += ppc/vp8dsp_altivec.o diff --git a/libavcodec/ppc/videodsp_ppc.c b/libavcodec/ppc/videodsp.c similarity index 100% rename from libavcodec/ppc/videodsp_ppc.c rename to libavcodec/ppc/videodsp.c From d32571626a2c36c026b7fa13d19ac4ed1aad75c9 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 8 Oct 2016 17:43:37 +0200 Subject: [PATCH 0315/3374] build: Add VSX-OBJS to SUBDIR_VARS The variable needs to be reset for each subdirectory. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 52cb0bd80d8df..34f0c9c278111 100644 --- a/Makefile +++ b/Makefile @@ -130,7 +130,7 @@ config.h: .config SUBDIR_VARS := CLEANFILES EXAMPLES FFLIBS HOSTPROGS TESTPROGS TOOLS \ HEADERS ARCH_HEADERS BUILT_HEADERS SKIPHEADERS \ ARMV5TE-OBJS ARMV6-OBJS ARMV8-OBJS VFP-OBJS NEON-OBJS \ - ALTIVEC-OBJS MMX-OBJS YASM-OBJS \ + ALTIVEC-OBJS VSX-OBJS MMX-OBJS YASM-OBJS \ OBJS HOSTOBJS TESTOBJS define RESET From be9dba5c8abc6ecf0b8ee4ccb11c7850327fcf8d Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 14 Oct 2016 17:25:55 -0400 Subject: [PATCH 0316/3374] swscale: Properly load alpha for planar rgb Signed-off-by: Vittorio Giovara Signed-off-by: Luca Barbato --- libswscale/input.c | 37 +++++++++++++++++++++++++++++ tests/ref/fate/filter-pixfmts-scale | 4 ++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/libswscale/input.c b/libswscale/input.c index 304466bd99d83..9f2ef72894f7b 100644 --- a/libswscale/input.c +++ b/libswscale/input.c @@ -671,6 +671,19 @@ static av_always_inline void planar_rgb16_to_y(uint8_t *_dst, const uint8_t *_sr } } +static av_always_inline void planar_rgb16_to_a(uint8_t *_dst, const uint8_t *_src[4], + int width, int bpc, int is_be) +{ + int i; + const uint16_t **src = (const uint16_t **)_src; + uint16_t *dst = (uint16_t *)_dst; + int shift = bpc < 15 ? bpc : 14; + + for (i = 0; i < width; i++) { + dst[i] = rdpx(src[3] + i) << (14 - shift); + } +} + static void planar_rgb9le_to_y(uint8_t *dst, const uint8_t *src[4], int w) { planar_rgb16_to_y(dst, src, w, 9, 0); @@ -696,21 +709,41 @@ static void planar_rgb12le_to_y(uint8_t *dst, const uint8_t *src[4], int w) planar_rgb16_to_y(dst, src, w, 12, 0); } +static void planar_rgb12le_to_a(uint8_t *dst, const uint8_t *src[4], int w) +{ + planar_rgb16_to_a(dst, src, w, 12, 0); +} + static void planar_rgb12be_to_y(uint8_t *dst, const uint8_t *src[4], int w) { planar_rgb16_to_y(dst, src, w, 12, 1); } +static void planar_rgb12be_to_a(uint8_t *dst, const uint8_t *src[4], int w) +{ + planar_rgb16_to_a(dst, src, w, 12, 1); +} + static void planar_rgb16le_to_y(uint8_t *dst, const uint8_t *src[4], int w) { planar_rgb16_to_y(dst, src, w, 16, 0); } +static void planar_rgb16le_to_a(uint8_t *dst, const uint8_t *src[4], int w) +{ + planar_rgb16_to_a(dst, src, w, 16, 0); +} + static void planar_rgb16be_to_y(uint8_t *dst, const uint8_t *src[4], int w) { planar_rgb16_to_y(dst, src, w, 16, 1); } +static void planar_rgb16be_to_a(uint8_t *dst, const uint8_t *src[4], int w) +{ + planar_rgb16_to_a(dst, src, w, 16, 1); +} + static av_always_inline void planar_rgb16_to_uv(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *_src[4], int width, int bpc, int is_be) @@ -1044,10 +1077,12 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) c->readLumPlanar = planar_rgb10le_to_y; break; case AV_PIX_FMT_GBRAP12LE: + c->readAlpPlanar = planar_rgb12le_to_a; case AV_PIX_FMT_GBRP12LE: c->readLumPlanar = planar_rgb12le_to_y; break; case AV_PIX_FMT_GBRAP16LE: + c->readAlpPlanar = planar_rgb16le_to_a; case AV_PIX_FMT_GBRP16LE: c->readLumPlanar = planar_rgb16le_to_y; break; @@ -1058,10 +1093,12 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) c->readLumPlanar = planar_rgb10be_to_y; break; case AV_PIX_FMT_GBRAP12BE: + c->readAlpPlanar = planar_rgb12be_to_a; case AV_PIX_FMT_GBRP12BE: c->readLumPlanar = planar_rgb12be_to_y; break; case AV_PIX_FMT_GBRAP16BE: + c->readAlpPlanar = planar_rgb16be_to_a; case AV_PIX_FMT_GBRP16BE: c->readLumPlanar = planar_rgb16be_to_y; break; diff --git a/tests/ref/fate/filter-pixfmts-scale b/tests/ref/fate/filter-pixfmts-scale index 142b6371aac86..97f29bed695d4 100644 --- a/tests/ref/fate/filter-pixfmts-scale +++ b/tests/ref/fate/filter-pixfmts-scale @@ -13,8 +13,8 @@ bgr565le 34438643c183ff1748cf7d71453f981c bgr8 e731ba3dbec294e1daa7313e08e88034 bgra 6e1f417ae41636f631de1cfe39ce1778 gbrap eefdbfd1426765ce5e9790022533db0d -gbrap12be c676f72b634c77b08a00ab12dc21c5dc -gbrap12le 90ca5271960dc1ebd6ebe14189223e36 +gbrap12be af4acb3ad0a6630f6ec4534e4d2e869a +gbrap12le fb66da21243e922b4e12ca05d8242c42 gbrp 5d14768d2ab6cbf3879966b5d5c6befb gbrp10be 4192c246f4a52ec7a37919665190cce9 gbrp10le 170189b2c2dd46f31165d8fa6cadef0a From 7911186ed616ae81dd8617d6d0e8b08c818db9d8 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 8 Oct 2016 17:58:02 +0200 Subject: [PATCH 0317/3374] emms: Give apriv_emms_yasm() a more general name --- libavutil/x86/emms.asm | 4 ++-- libavutil/x86/emms.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libavutil/x86/emms.asm b/libavutil/x86/emms.asm index a6851acc9906f..05557de5da6cf 100644 --- a/libavutil/x86/emms.asm +++ b/libavutil/x86/emms.asm @@ -23,8 +23,8 @@ SECTION .text ;----------------------------------------------------------------------------- -; void avpriv_emms_yasm(void) +; void avpriv_emms_asm(void) ;----------------------------------------------------------------------------- -cvisible emms_yasm, 0, 0 +cvisible emms_asm, 0, 0 emms RET diff --git a/libavutil/x86/emms.h b/libavutil/x86/emms.h index 2ed9e5d09d365..4b3ebbe7a46dc 100644 --- a/libavutil/x86/emms.h +++ b/libavutil/x86/emms.h @@ -22,7 +22,7 @@ #include "config.h" #include "libavutil/attributes.h" -void avpriv_emms_yasm(void); +void avpriv_emms_asm(void); #if HAVE_MMX_INLINE # define emms_c emms_c @@ -39,7 +39,7 @@ static av_always_inline void emms_c(void) # include # define emms_c _mm_empty #elif HAVE_MMX_EXTERNAL -# define emms_c avpriv_emms_yasm +# define emms_c avpriv_emms_asm #endif /* HAVE_MMX_INLINE */ #endif /* AVUTIL_X86_EMMS_H */ From dd5d4a0e1e3a30a254d1a57ecbdcedf230c6014b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 18 Oct 2016 13:48:56 +0300 Subject: [PATCH 0318/3374] checkasm: aarch64: Don't clobber x29 in checkasm_stack_clobber MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit x29 (FP) is a callee saved register and should be restored on return. Instead of backing up x29 and restoring it here, back up sp in a register that we are allowed to overwrite. This fixes crashes in checkasm on aarch64 since f1b3e1313851. For some reason, gcc builds didn't crash, but clang builds do. Signed-off-by: Martin Storsjö --- tests/checkasm/aarch64/checkasm.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/checkasm/aarch64/checkasm.S b/tests/checkasm/aarch64/checkasm.S index 65b352104e7b2..bc5ed9ea094a2 100644 --- a/tests/checkasm/aarch64/checkasm.S +++ b/tests/checkasm/aarch64/checkasm.S @@ -55,13 +55,13 @@ endconst #define CLOBBER_STACK ((8*MAX_ARGS + 15) & ~15) function checkasm_stack_clobber, export=1 - mov x29, sp + mov x3, sp mov x2, #CLOBBER_STACK 1: stp x0, x1, [sp, #-16]! subs x2, x2, #16 b.gt 1b - mov sp, x29 + mov sp, x3 ret endfunc From da4f8c8e35a867f2d9fed0fb75e16c81ab968637 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Tue, 18 Oct 2016 15:00:38 +0200 Subject: [PATCH 0319/3374] fate: Update filter-pixfmts-scale gbrap12le hash missing from be9dba5c8a Signed-off-by: Diego Biurrun --- tests/ref/fate/filter-pixfmts-scale | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ref/fate/filter-pixfmts-scale b/tests/ref/fate/filter-pixfmts-scale index 97f29bed695d4..2a60f72f8bd75 100644 --- a/tests/ref/fate/filter-pixfmts-scale +++ b/tests/ref/fate/filter-pixfmts-scale @@ -14,7 +14,7 @@ bgr8 e731ba3dbec294e1daa7313e08e88034 bgra 6e1f417ae41636f631de1cfe39ce1778 gbrap eefdbfd1426765ce5e9790022533db0d gbrap12be af4acb3ad0a6630f6ec4534e4d2e869a -gbrap12le fb66da21243e922b4e12ca05d8242c42 +gbrap12le 90ca5271960dc1ebd6ebe14189223e36 gbrp 5d14768d2ab6cbf3879966b5d5c6befb gbrp10be 4192c246f4a52ec7a37919665190cce9 gbrp10le 170189b2c2dd46f31165d8fa6cadef0a From b89804da9bad2d94dd95bf20ac6187447e9c17e9 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 17 Mar 2016 11:35:13 +0100 Subject: [PATCH 0320/3374] x86: videodsp: Add parentheses to expression to work around warning libavcodec/x86/videodsp.asm:128: warning: signed dword value exceeds bounds --- libavcodec/x86/videodsp.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/x86/videodsp.asm b/libavcodec/x86/videodsp.asm index 53b9e8292ce8c..b22e0fec8b7a0 100644 --- a/libavcodec/x86/videodsp.asm +++ b/libavcodec/x86/videodsp.asm @@ -110,7 +110,7 @@ cglobal emu_edge_hvar, 5, 6, 1, dst, dst_stride, start_x, n_words, h, w .x_loop: ; do { movu [dstq+wq*2], m0 ; write($reg, $mmsize) add wq, mmsize/2 ; w -= $mmsize/2 - cmp wq, -mmsize/2 ; } while (w > $mmsize/2) + cmp wq, -(mmsize/2) ; } while (w > $mmsize/2) jl .x_loop movu [dstq-mmsize], m0 ; write($reg, $mmsize) add dstq, dst_strideq ; dst += dst_stride From 1f821e5ad3f8ebacbbb362668561ad976c392c9e Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 15 Oct 2016 02:50:45 +0200 Subject: [PATCH 0321/3374] configure: Print warnings after all other output --- configure | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index ac20cfa986e4a..745b5b7b91946 100755 --- a/configure +++ b/configure @@ -5387,8 +5387,6 @@ echo "#endif /* AVUTIL_AVCONFIG_H */" >> $TMPH cp_if_changed $TMPH libavutil/avconfig.h -test -n "$WARNINGS" && printf "\n$WARNINGS" - # generate the lists of enabled components print_enabled_components(){ file=$1 @@ -5406,6 +5404,8 @@ print_enabled_components(){ print_enabled_components libavcodec/bsf_list.c AVBitStreamFilter bitstream_filters $BSF_LIST print_enabled_components libavformat/protocol_list.c URLProtocol url_protocols $PROTOCOL_LIST +test -n "$WARNINGS" && printf "\n$WARNINGS" + # build pkg-config files lib_version(){ From 788544ff0ed6fe67fda80ad6d3a0796ace035584 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 28 Sep 2016 19:14:28 +0200 Subject: [PATCH 0322/3374] audiodsp: x86: Remove pointless header file Its single forward declaration can be moved to the only place it is used, like is done for all other dsp init files. --- libavcodec/x86/audiodsp.h | 25 ------------------------- libavcodec/x86/audiodsp_init.c | 4 +++- 2 files changed, 3 insertions(+), 26 deletions(-) delete mode 100644 libavcodec/x86/audiodsp.h diff --git a/libavcodec/x86/audiodsp.h b/libavcodec/x86/audiodsp.h deleted file mode 100644 index c87ee45193e5a..0000000000000 --- a/libavcodec/x86/audiodsp.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * This file is part of Libav. - * - * Libav is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * Libav is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_X86_AUDIODSP_H -#define AVCODEC_X86_AUDIODSP_H - -void ff_vector_clipf_sse(float *dst, const float *src, - int len, float min, float max); - -#endif /* AVCODEC_X86_AUDIODSP_H */ diff --git a/libavcodec/x86/audiodsp_init.c b/libavcodec/x86/audiodsp_init.c index 23731158e5699..093f3f06726a8 100644 --- a/libavcodec/x86/audiodsp_init.c +++ b/libavcodec/x86/audiodsp_init.c @@ -23,7 +23,6 @@ #include "libavutil/cpu.h" #include "libavutil/x86/cpu.h" #include "libavcodec/audiodsp.h" -#include "audiodsp.h" int32_t ff_scalarproduct_int16_mmxext(const int16_t *v1, const int16_t *v2, int order); @@ -39,6 +38,9 @@ void ff_vector_clip_int32_int_sse2(int32_t *dst, const int32_t *src, void ff_vector_clip_int32_sse4(int32_t *dst, const int32_t *src, int32_t min, int32_t max, unsigned int len); +void ff_vector_clipf_sse(float *dst, const float *src, + int len, float min, float max); + av_cold void ff_audiodsp_init_x86(AudioDSPContext *c) { int cpu_flags = av_get_cpu_flags(); From 096a8effa3f8f3455292c958c3ed07e798def7bd Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 18 Oct 2016 20:50:03 +0200 Subject: [PATCH 0323/3374] lavf: check that the codec is supported by extract_extradata Avoids superfluous error message spam after 8e2ea691351c5079cdab245ff7bfa5c0f3e3bfe4 --- libavformat/utils.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libavformat/utils.c b/libavformat/utils.c index 1c93326ab22b6..37ba5a8626db6 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2099,6 +2099,16 @@ static int extract_extradata_init(AVStream *st) if (!f) goto finish; + /* check that the codec id is supported */ + if (f->codec_ids) { + const enum AVCodecID *ids; + for (ids = f->codec_ids; *ids != AV_CODEC_ID_NONE; ids++) + if (*ids == st->codecpar->codec_id) + break; + if (*ids == AV_CODEC_ID_NONE) + goto finish; + } + i->extract_extradata.pkt = av_packet_alloc(); if (!i->extract_extradata.pkt) return AVERROR(ENOMEM); From 0bfdcce4d42a6e654c00ea5f9237dc987626457f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 18 Oct 2016 21:14:18 +0200 Subject: [PATCH 0324/3374] hevc: move the SliceType enum to hevc.h Those values are decoder-independent and are also use by the VA-API encoder. --- libavcodec/hevc.h | 6 ++++ libavcodec/hevc_cabac.c | 3 +- libavcodec/hevc_mvs.c | 9 +++--- libavcodec/hevc_refs.c | 2 +- libavcodec/hevcdec.c | 58 +++++++++++++++++----------------- libavcodec/hevcdec.h | 8 +---- libavcodec/vaapi_encode_h265.c | 20 ++++++------ 7 files changed, 54 insertions(+), 52 deletions(-) diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h index 95366088f8a8b..bb4f6605866a2 100644 --- a/libavcodec/hevc.h +++ b/libavcodec/hevc.h @@ -52,6 +52,12 @@ enum HEVCNALUnitType { HEVC_NAL_SEI_SUFFIX = 40, }; +enum HEVCSliceType { + HEVC_SLICE_B = 0, + HEVC_SLICE_P = 1, + HEVC_SLICE_I = 2, +}; + /** * 7.4.2.1 */ diff --git a/libavcodec/hevc_cabac.c b/libavcodec/hevc_cabac.c index eb16f57cd86f9..0432330e820ac 100644 --- a/libavcodec/hevc_cabac.c +++ b/libavcodec/hevc_cabac.c @@ -25,6 +25,7 @@ #include "libavutil/common.h" #include "cabac_functions.h" +#include "hevc.h" #include "hevcdec.h" #define CABAC_MAX_BIN 31 @@ -358,7 +359,7 @@ static void cabac_init_state(HEVCContext *s) int init_type = 2 - s->sh.slice_type; int i; - if (s->sh.cabac_init_flag && s->sh.slice_type != I_SLICE) + if (s->sh.cabac_init_flag && s->sh.slice_type != HEVC_SLICE_I) init_type ^= 3; for (i = 0; i < HEVC_CONTEXTS; i++) { diff --git a/libavcodec/hevc_mvs.c b/libavcodec/hevc_mvs.c index 90aff9758e271..be32e6cd40f58 100644 --- a/libavcodec/hevc_mvs.c +++ b/libavcodec/hevc_mvs.c @@ -21,6 +21,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "hevc.h" #include "hevcdec.h" static const uint8_t l0_l1_cand_idx[12][2] = { @@ -355,7 +356,7 @@ static void derive_spatial_merge_candidates(HEVCContext *s, int x0, int y0, const int xB2_pu = xB2 >> s->ps.sps->log2_min_pu_size; const int yB2_pu = yB2 >> s->ps.sps->log2_min_pu_size; - const int nb_refs = (s->sh.slice_type == P_SLICE) ? + const int nb_refs = (s->sh.slice_type == HEVC_SLICE_P) ? s->sh.nb_refs[0] : FFMIN(s->sh.nb_refs[0], s->sh.nb_refs[1]); int check_MER = 1; int check_MER_1 = 1; @@ -473,7 +474,7 @@ static void derive_spatial_merge_candidates(HEVCContext *s, int x0, int y0, Mv mv_l0_col = { 0 }, mv_l1_col = { 0 }; int available_l0 = temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH, 0, &mv_l0_col, 0); - int available_l1 = (s->sh.slice_type == B_SLICE) ? + int available_l1 = (s->sh.slice_type == HEVC_SLICE_B) ? temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH, 0, &mv_l1_col, 1) : 0; @@ -494,7 +495,7 @@ static void derive_spatial_merge_candidates(HEVCContext *s, int x0, int y0, nb_orig_merge_cand = nb_merge_cand; // combined bi-predictive merge candidates (applies for B slices) - if (s->sh.slice_type == B_SLICE && nb_orig_merge_cand > 1 && + if (s->sh.slice_type == HEVC_SLICE_B && nb_orig_merge_cand > 1 && nb_orig_merge_cand < s->sh.max_num_merge_cand) { int comb_idx; @@ -526,7 +527,7 @@ static void derive_spatial_merge_candidates(HEVCContext *s, int x0, int y0, // append Zero motion vector candidates while (nb_merge_cand < s->sh.max_num_merge_cand) { mergecandlist[nb_merge_cand].pred_flag[0] = 1; - mergecandlist[nb_merge_cand].pred_flag[1] = s->sh.slice_type == B_SLICE; + mergecandlist[nb_merge_cand].pred_flag[1] = s->sh.slice_type == HEVC_SLICE_B; AV_ZERO32(mergecandlist[nb_merge_cand].mv + 0); AV_ZERO32(mergecandlist[nb_merge_cand].mv + 1); mergecandlist[nb_merge_cand].is_intra = 0; diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c index 0b6beb590fc4a..30409bae5f445 100644 --- a/libavcodec/hevc_refs.c +++ b/libavcodec/hevc_refs.c @@ -249,7 +249,7 @@ int ff_hevc_slice_rpl(HEVCContext *s) { SliceHeader *sh = &s->sh; - uint8_t nb_list = sh->slice_type == B_SLICE ? 2 : 1; + uint8_t nb_list = sh->slice_type == HEVC_SLICE_B ? 2 : 1; uint8_t list_idx; int i, j, ret; diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 72fdd22c5e84a..db456086f7b2c 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -243,7 +243,7 @@ static void pred_weight_table(HEVCContext *s, GetBitContext *gb) s->sh.chroma_offset_l0[i][1] = 0; } } - if (s->sh.slice_type == B_SLICE) { + if (s->sh.slice_type == HEVC_SLICE_B) { for (i = 0; i < s->sh.nb_refs[L1]; i++) { luma_weight_l1_flag[i] = get_bits1(gb); if (!luma_weight_l1_flag[i]) { @@ -520,14 +520,14 @@ static int hls_slice_header(HEVCContext *s) skip_bits(gb, 1); // slice_reserved_undetermined_flag[] sh->slice_type = get_ue_golomb_long(gb); - if (!(sh->slice_type == I_SLICE || - sh->slice_type == P_SLICE || - sh->slice_type == B_SLICE)) { + if (!(sh->slice_type == HEVC_SLICE_I || + sh->slice_type == HEVC_SLICE_P || + sh->slice_type == HEVC_SLICE_B)) { av_log(s->avctx, AV_LOG_ERROR, "Unknown slice type: %d.\n", sh->slice_type); return AVERROR_INVALIDDATA; } - if (IS_IRAP(s) && sh->slice_type != I_SLICE) { + if (IS_IRAP(s) && sh->slice_type != HEVC_SLICE_I) { av_log(s->avctx, AV_LOG_ERROR, "Inter slices in an IRAP frame.\n"); return AVERROR_INVALIDDATA; } @@ -616,16 +616,16 @@ static int hls_slice_header(HEVCContext *s) } sh->nb_refs[L0] = sh->nb_refs[L1] = 0; - if (sh->slice_type == P_SLICE || sh->slice_type == B_SLICE) { + if (sh->slice_type == HEVC_SLICE_P || sh->slice_type == HEVC_SLICE_B) { int nb_refs; sh->nb_refs[L0] = s->ps.pps->num_ref_idx_l0_default_active; - if (sh->slice_type == B_SLICE) + if (sh->slice_type == HEVC_SLICE_B) sh->nb_refs[L1] = s->ps.pps->num_ref_idx_l1_default_active; if (get_bits1(gb)) { // num_ref_idx_active_override_flag sh->nb_refs[L0] = get_ue_golomb_long(gb) + 1; - if (sh->slice_type == B_SLICE) + if (sh->slice_type == HEVC_SLICE_B) sh->nb_refs[L1] = get_ue_golomb_long(gb) + 1; } if (sh->nb_refs[L0] > HEVC_MAX_REFS || sh->nb_refs[L1] > HEVC_MAX_REFS) { @@ -649,7 +649,7 @@ static int hls_slice_header(HEVCContext *s) sh->list_entry_lx[0][i] = get_bits(gb, av_ceil_log2(nb_refs)); } - if (sh->slice_type == B_SLICE) { + if (sh->slice_type == HEVC_SLICE_B) { sh->rpl_modification_flag[1] = get_bits1(gb); if (sh->rpl_modification_flag[1] == 1) for (i = 0; i < sh->nb_refs[L1]; i++) @@ -657,7 +657,7 @@ static int hls_slice_header(HEVCContext *s) } } - if (sh->slice_type == B_SLICE) + if (sh->slice_type == HEVC_SLICE_B) sh->mvd_l1_zero_flag = get_bits1(gb); if (s->ps.pps->cabac_init_present_flag) @@ -668,7 +668,7 @@ static int hls_slice_header(HEVCContext *s) sh->collocated_ref_idx = 0; if (sh->slice_temporal_mvp_enabled_flag) { sh->collocated_list = L0; - if (sh->slice_type == B_SLICE) + if (sh->slice_type == HEVC_SLICE_B) sh->collocated_list = !get_bits1(gb); if (sh->nb_refs[sh->collocated_list] > 1) { @@ -682,8 +682,8 @@ static int hls_slice_header(HEVCContext *s) } } - if ((s->ps.pps->weighted_pred_flag && sh->slice_type == P_SLICE) || - (s->ps.pps->weighted_bipred_flag && sh->slice_type == B_SLICE)) { + if ((s->ps.pps->weighted_pred_flag && sh->slice_type == HEVC_SLICE_P) || + (s->ps.pps->weighted_bipred_flag && sh->slice_type == HEVC_SLICE_B)) { pred_weight_table(s, gb); } @@ -1632,7 +1632,7 @@ static void hevc_luma_mv_mpv_mode(HEVCContext *s, int x0, int y0, int nPbW, int mvp_flag; ff_hevc_set_neighbour_available(s, x0, y0, nPbW, nPbH); - if (s->sh.slice_type == B_SLICE) + if (s->sh.slice_type == HEVC_SLICE_B) inter_pred_idc = ff_hevc_inter_pred_idc_decode(s, nPbW, nPbH); if (inter_pred_idc != PRED_L1) { @@ -1746,8 +1746,8 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, luma_mc(s, tmp, tmpstride, ref0->frame, ¤t_mv.mv[0], x0, y0, nPbW, nPbH, pred_idx); - if ((s->sh.slice_type == P_SLICE && s->ps.pps->weighted_pred_flag) || - (s->sh.slice_type == B_SLICE && s->ps.pps->weighted_bipred_flag)) { + if ((s->sh.slice_type == HEVC_SLICE_P && s->ps.pps->weighted_pred_flag) || + (s->sh.slice_type == HEVC_SLICE_B && s->ps.pps->weighted_bipred_flag)) { s->hevcdsp.weighted_pred[pred_idx](s->sh.luma_log2_weight_denom, s->sh.luma_weight_l0[current_mv.ref_idx[0]], s->sh.luma_offset_l0[current_mv.ref_idx[0]], @@ -1759,8 +1759,8 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, chroma_mc(s, tmp, tmp2, tmpstride, ref0->frame, ¤t_mv.mv[0], x0 / 2, y0 / 2, nPbW / 2, nPbH / 2, pred_idx); - if ((s->sh.slice_type == P_SLICE && s->ps.pps->weighted_pred_flag) || - (s->sh.slice_type == B_SLICE && s->ps.pps->weighted_bipred_flag)) { + if ((s->sh.slice_type == HEVC_SLICE_P && s->ps.pps->weighted_pred_flag) || + (s->sh.slice_type == HEVC_SLICE_B && s->ps.pps->weighted_bipred_flag)) { s->hevcdsp.weighted_pred_chroma[pred_idx](s->sh.chroma_log2_weight_denom, s->sh.chroma_weight_l0[current_mv.ref_idx[0]][0], s->sh.chroma_offset_l0[current_mv.ref_idx[0]][0], @@ -1782,8 +1782,8 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, luma_mc(s, tmp, tmpstride, ref1->frame, ¤t_mv.mv[1], x0, y0, nPbW, nPbH, pred_idx); - if ((s->sh.slice_type == P_SLICE && s->ps.pps->weighted_pred_flag) || - (s->sh.slice_type == B_SLICE && s->ps.pps->weighted_bipred_flag)) { + if ((s->sh.slice_type == HEVC_SLICE_P && s->ps.pps->weighted_pred_flag) || + (s->sh.slice_type == HEVC_SLICE_B && s->ps.pps->weighted_bipred_flag)) { s->hevcdsp.weighted_pred[pred_idx](s->sh.luma_log2_weight_denom, s->sh.luma_weight_l1[current_mv.ref_idx[1]], s->sh.luma_offset_l1[current_mv.ref_idx[1]], @@ -1796,8 +1796,8 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, chroma_mc(s, tmp, tmp2, tmpstride, ref1->frame, ¤t_mv.mv[1], x0 / 2, y0 / 2, nPbW / 2, nPbH / 2, pred_idx); - if ((s->sh.slice_type == P_SLICE && s->ps.pps->weighted_pred_flag) || - (s->sh.slice_type == B_SLICE && s->ps.pps->weighted_bipred_flag)) { + if ((s->sh.slice_type == HEVC_SLICE_P && s->ps.pps->weighted_pred_flag) || + (s->sh.slice_type == HEVC_SLICE_B && s->ps.pps->weighted_bipred_flag)) { s->hevcdsp.weighted_pred_chroma[pred_idx](s->sh.chroma_log2_weight_denom, s->sh.chroma_weight_l1[current_mv.ref_idx[1]][0], s->sh.chroma_offset_l1[current_mv.ref_idx[1]][0], @@ -1821,8 +1821,8 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, luma_mc(s, tmp2, tmpstride, ref1->frame, ¤t_mv.mv[1], x0, y0, nPbW, nPbH, pred_idx); - if ((s->sh.slice_type == P_SLICE && s->ps.pps->weighted_pred_flag) || - (s->sh.slice_type == B_SLICE && s->ps.pps->weighted_bipred_flag)) { + if ((s->sh.slice_type == HEVC_SLICE_P && s->ps.pps->weighted_pred_flag) || + (s->sh.slice_type == HEVC_SLICE_B && s->ps.pps->weighted_bipred_flag)) { s->hevcdsp.weighted_pred_avg[pred_idx](s->sh.luma_log2_weight_denom, s->sh.luma_weight_l0[current_mv.ref_idx[0]], s->sh.luma_weight_l1[current_mv.ref_idx[1]], @@ -1840,8 +1840,8 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, chroma_mc(s, tmp3, tmp4, tmpstride, ref1->frame, ¤t_mv.mv[1], x0 / 2, y0 / 2, nPbW / 2, nPbH / 2, pred_idx); - if ((s->sh.slice_type == P_SLICE && s->ps.pps->weighted_pred_flag) || - (s->sh.slice_type == B_SLICE && s->ps.pps->weighted_bipred_flag)) { + if ((s->sh.slice_type == HEVC_SLICE_P && s->ps.pps->weighted_pred_flag) || + (s->sh.slice_type == HEVC_SLICE_B && s->ps.pps->weighted_bipred_flag)) { s->hevcdsp.weighted_pred_avg_chroma[pred_idx](s->sh.chroma_log2_weight_denom, s->sh.chroma_weight_l0[current_mv.ref_idx[0]][0], s->sh.chroma_weight_l1[current_mv.ref_idx[1]][0], @@ -2056,7 +2056,7 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size) } else lc->cu.cu_transquant_bypass_flag = 0; - if (s->sh.slice_type != I_SLICE) { + if (s->sh.slice_type != HEVC_SLICE_I) { uint8_t skip_flag = ff_hevc_skip_flag_decode(s, x0, y0, x_cb, y_cb); x = y_cb * min_cb_width + x_cb; @@ -2076,7 +2076,7 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size) } else { int pcm_flag = 0; - if (s->sh.slice_type != I_SLICE) + if (s->sh.slice_type != HEVC_SLICE_I) lc->cu.pred_mode = ff_hevc_pred_mode_decode(s); if (lc->cu.pred_mode != MODE_INTRA || log2_cb_size == s->ps.sps->log2_min_cb_size) { @@ -2534,7 +2534,7 @@ static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal) } if (!s->sh.dependent_slice_segment_flag && - s->sh.slice_type != I_SLICE) { + s->sh.slice_type != HEVC_SLICE_I) { ret = ff_hevc_slice_rpl(s); if (ret < 0) { av_log(s->avctx, AV_LOG_WARNING, diff --git a/libavcodec/hevcdec.h b/libavcodec/hevcdec.h index 78080eb757674..82adad20c6210 100644 --- a/libavcodec/hevcdec.h +++ b/libavcodec/hevcdec.h @@ -85,12 +85,6 @@ enum RPSType { NB_RPS_TYPE, }; -enum SliceType { - B_SLICE = 0, - P_SLICE = 1, - I_SLICE = 2, -}; - enum SyntaxElement { SAO_MERGE_FLAG = 0, SAO_TYPE_IDX, @@ -242,7 +236,7 @@ typedef struct SliceHeader { ///< address (in raster order) of the first block in the current slice unsigned int slice_addr; - enum SliceType slice_type; + enum HEVCSliceType slice_type; int pic_order_cnt_lsb; diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c index ed36ef4215cbe..ecf7973368b62 100644 --- a/libavcodec/vaapi_encode_h265.c +++ b/libavcodec/vaapi_encode_h265.c @@ -25,7 +25,7 @@ #include "libavutil/pixfmt.h" #include "avcodec.h" -#include "hevcdec.h" +#include "hevc.h" #include "internal.h" #include "put_bits.h" #include "vaapi_encode.h" @@ -630,11 +630,11 @@ static void vaapi_encode_h265_write_slice_header2(PutBitContext *pbc, } } - if (vslice->slice_type == P_SLICE || vslice->slice_type == B_SLICE) { + if (vslice->slice_type == HEVC_SLICE_P || vslice->slice_type == HEVC_SLICE_B) { u(1, vslice_field(num_ref_idx_active_override_flag)); if (vslice->slice_fields.bits.num_ref_idx_active_override_flag) { ue(vslice_var(num_ref_idx_l0_active_minus1)); - if (vslice->slice_type == B_SLICE) { + if (vslice->slice_type == HEVC_SLICE_B) { ue(vslice_var(num_ref_idx_l1_active_minus1)); } } @@ -643,21 +643,21 @@ static void vaapi_encode_h265_write_slice_header2(PutBitContext *pbc, av_assert0(0); // ref_pic_lists_modification() } - if (vslice->slice_type == B_SLICE) { + if (vslice->slice_type == HEVC_SLICE_B) { u(1, vslice_field(mvd_l1_zero_flag)); } if (mseq->cabac_init_present_flag) { u(1, vslice_field(cabac_init_flag)); } if (vslice->slice_fields.bits.slice_temporal_mvp_enabled_flag) { - if (vslice->slice_type == B_SLICE) + if (vslice->slice_type == HEVC_SLICE_B) u(1, vslice_field(collocated_from_l0_flag)); ue(vpic->collocated_ref_pic_index, collocated_ref_idx); } if ((vpic->pic_fields.bits.weighted_pred_flag && - vslice->slice_type == P_SLICE) || + vslice->slice_type == HEVC_SLICE_P) || (vpic->pic_fields.bits.weighted_bipred_flag && - vslice->slice_type == B_SLICE)) { + vslice->slice_type == HEVC_SLICE_B)) { av_assert0(0); // pred_weight_table() } @@ -1055,13 +1055,13 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx, switch (pic->type) { case PICTURE_TYPE_IDR: case PICTURE_TYPE_I: - vslice->slice_type = I_SLICE; + vslice->slice_type = HEVC_SLICE_I; break; case PICTURE_TYPE_P: - vslice->slice_type = P_SLICE; + vslice->slice_type = HEVC_SLICE_P; break; case PICTURE_TYPE_B: - vslice->slice_type = B_SLICE; + vslice->slice_type = HEVC_SLICE_B; break; default: av_assert0(0 && "invalid picture type"); From 59c90097a0eff0dc81fbec15b8900c929859d1e7 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 18 Oct 2016 21:22:22 +0200 Subject: [PATCH 0325/3374] hevc: factor out a repeated condition --- libavcodec/hevcdec.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index db456086f7b2c..e58d5f8f58630 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -1684,6 +1684,8 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, struct MvField current_mv = {{{ 0 }}}; int min_pu_width = s->ps.sps->min_pu_width; + int weighted_pred = (s->sh.slice_type == HEVC_SLICE_P && s->ps.pps->weighted_pred_flag) || + (s->sh.slice_type == HEVC_SLICE_B && s->ps.pps->weighted_bipred_flag); MvField *tab_mvf = s->ref->tab_mvf; RefPicList *refPicList = s->ref->refPicList; @@ -1746,8 +1748,7 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, luma_mc(s, tmp, tmpstride, ref0->frame, ¤t_mv.mv[0], x0, y0, nPbW, nPbH, pred_idx); - if ((s->sh.slice_type == HEVC_SLICE_P && s->ps.pps->weighted_pred_flag) || - (s->sh.slice_type == HEVC_SLICE_B && s->ps.pps->weighted_bipred_flag)) { + if (weighted_pred) { s->hevcdsp.weighted_pred[pred_idx](s->sh.luma_log2_weight_denom, s->sh.luma_weight_l0[current_mv.ref_idx[0]], s->sh.luma_offset_l0[current_mv.ref_idx[0]], @@ -1759,8 +1760,7 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, chroma_mc(s, tmp, tmp2, tmpstride, ref0->frame, ¤t_mv.mv[0], x0 / 2, y0 / 2, nPbW / 2, nPbH / 2, pred_idx); - if ((s->sh.slice_type == HEVC_SLICE_P && s->ps.pps->weighted_pred_flag) || - (s->sh.slice_type == HEVC_SLICE_B && s->ps.pps->weighted_bipred_flag)) { + if (weighted_pred) { s->hevcdsp.weighted_pred_chroma[pred_idx](s->sh.chroma_log2_weight_denom, s->sh.chroma_weight_l0[current_mv.ref_idx[0]][0], s->sh.chroma_offset_l0[current_mv.ref_idx[0]][0], @@ -1782,8 +1782,7 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, luma_mc(s, tmp, tmpstride, ref1->frame, ¤t_mv.mv[1], x0, y0, nPbW, nPbH, pred_idx); - if ((s->sh.slice_type == HEVC_SLICE_P && s->ps.pps->weighted_pred_flag) || - (s->sh.slice_type == HEVC_SLICE_B && s->ps.pps->weighted_bipred_flag)) { + if (weighted_pred) { s->hevcdsp.weighted_pred[pred_idx](s->sh.luma_log2_weight_denom, s->sh.luma_weight_l1[current_mv.ref_idx[1]], s->sh.luma_offset_l1[current_mv.ref_idx[1]], @@ -1796,8 +1795,7 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, chroma_mc(s, tmp, tmp2, tmpstride, ref1->frame, ¤t_mv.mv[1], x0 / 2, y0 / 2, nPbW / 2, nPbH / 2, pred_idx); - if ((s->sh.slice_type == HEVC_SLICE_P && s->ps.pps->weighted_pred_flag) || - (s->sh.slice_type == HEVC_SLICE_B && s->ps.pps->weighted_bipred_flag)) { + if (weighted_pred) { s->hevcdsp.weighted_pred_chroma[pred_idx](s->sh.chroma_log2_weight_denom, s->sh.chroma_weight_l1[current_mv.ref_idx[1]][0], s->sh.chroma_offset_l1[current_mv.ref_idx[1]][0], @@ -1821,8 +1819,7 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, luma_mc(s, tmp2, tmpstride, ref1->frame, ¤t_mv.mv[1], x0, y0, nPbW, nPbH, pred_idx); - if ((s->sh.slice_type == HEVC_SLICE_P && s->ps.pps->weighted_pred_flag) || - (s->sh.slice_type == HEVC_SLICE_B && s->ps.pps->weighted_bipred_flag)) { + if (weighted_pred) { s->hevcdsp.weighted_pred_avg[pred_idx](s->sh.luma_log2_weight_denom, s->sh.luma_weight_l0[current_mv.ref_idx[0]], s->sh.luma_weight_l1[current_mv.ref_idx[1]], @@ -1840,8 +1837,7 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, chroma_mc(s, tmp3, tmp4, tmpstride, ref1->frame, ¤t_mv.mv[1], x0 / 2, y0 / 2, nPbW / 2, nPbH / 2, pred_idx); - if ((s->sh.slice_type == HEVC_SLICE_P && s->ps.pps->weighted_pred_flag) || - (s->sh.slice_type == HEVC_SLICE_B && s->ps.pps->weighted_bipred_flag)) { + if (weighted_pred) { s->hevcdsp.weighted_pred_avg_chroma[pred_idx](s->sh.chroma_log2_weight_denom, s->sh.chroma_weight_l0[current_mv.ref_idx[0]][0], s->sh.chroma_weight_l1[current_mv.ref_idx[1]][0], From 7c9e2b295e4f70e8fedf9cceb12d95399a859a9c Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 19 Oct 2016 07:28:06 +0200 Subject: [PATCH 0326/3374] Makefile: fix checking whether reconfiguring is required It didn't take into account the new pattern used for bitstream filters and protocols. --- Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 34f0c9c278111..e860f2c728657 100644 --- a/Makefile +++ b/Makefile @@ -121,8 +121,13 @@ $(TOOLS): %$(EXESUF): %.o $(EXEOBJS) tools/cws2fws$(EXESUF): ELIBS = $(ZLIB) +CONFIGURABLE_COMPONENTS = \ + $(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/all*.c)) \ + $(SRC_PATH)/libavcodec/bitstream_filters.c \ + $(SRC_PATH)/libavformat/protocols.c \ + config.h: .config -.config: $(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/all*.c)) +.config: $(CONFIGURABLE_COMPONENTS) @-tput bold 2>/dev/null @-printf '\nWARNING: $(?F) newer than config.h, rerun configure\n\n' @-tput sgr0 2>/dev/null From 0d9b9bd37f43ee29ad9f709d85c8f3be9db71104 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Tue, 18 Oct 2016 18:16:29 -0400 Subject: [PATCH 0327/3374] lavu: Add JEDEC P22 color primaries --- libavcodec/options_table.h | 1 + libavcodec/version.h | 2 +- libavutil/pixdesc.c | 1 + libavutil/pixfmt.h | 1 + libavutil/version.h | 2 +- 5 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index 5090806f365e2..04cb20d1544d5 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -438,6 +438,7 @@ static const AVOption avcodec_options[] = { {"smpte428", "SMPTE 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, {"smpte431", "SMPTE 431-2", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE431 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, {"smpte432", "SMPTE 422-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE432 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"jedec-p22", "JEDEC P22", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_JEDEC_P22 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, {"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, {"smptest428_1", "SMPTE 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, {"color_trc", "color transfer characteristics", OFFSET(color_trc), AV_OPT_TYPE_INT, {.i64 = AVCOL_TRC_UNSPECIFIED }, 1, AVCOL_TRC_NB-1, V|E|D, "color_trc_type"}, diff --git a/libavcodec/version.h b/libavcodec/version.h index 64b0ee6fd6d21..6f439c02c89b6 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 28 -#define LIBAVCODEC_VERSION_MICRO 0 +#define LIBAVCODEC_VERSION_MICRO 1 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index 80bdee74d09a5..7987f292ac6a7 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -1763,6 +1763,7 @@ static const char *color_primaries_names[] = { [AVCOL_PRI_SMPTE428] = "smpte428", [AVCOL_PRI_SMPTE431] = "smpte431", [AVCOL_PRI_SMPTE432] = "smpte432", + [AVCOL_PRI_JEDEC_P22] = "jedec-p22", }; static const char *color_transfer_names[] = { diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index 917fa579c859f..0bee724998d87 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -326,6 +326,7 @@ enum AVColorPrimaries { AVCOL_PRI_SMPTEST428_1 = AVCOL_PRI_SMPTE428, AVCOL_PRI_SMPTE431 = 11, ///< SMPTE ST 431-2 (2011) / DCI P3 AVCOL_PRI_SMPTE432 = 12, ///< SMPTE ST 432-1 (2010) / P3 D65 / Display P3 + AVCOL_PRI_JEDEC_P22 = 22, ///< JEDEC P22 phosphors AVCOL_PRI_NB, ///< Not part of ABI }; diff --git a/libavutil/version.h b/libavutil/version.h index 77288f58a6066..c1cfcbba2fb17 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -54,7 +54,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 25 +#define LIBAVUTIL_VERSION_MINOR 26 #define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From 4b07ebf1eb13561492f7e3c30a67f34415016b3e Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Tue, 18 Oct 2016 18:21:31 -0400 Subject: [PATCH 0328/3374] mov: Update colr values For 'nclx', the latest edition of the standard switched from JPEG XR to 23001-8, which matches the current order of our entries. Bounds are preserved as a sanity check. For 'nclc', qtff edition 2016-09-13 introduced a few new entries. Signed-off-by: Vittorio Giovara --- libavformat/mov.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 36e75d5c389f6..fee9f36382c17 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -36,6 +36,7 @@ #include "libavutil/avstring.h" #include "libavutil/dict.h" #include "libavutil/opt.h" +#include "libavutil/pixdesc.h" #include "libavcodec/ac3tab.h" #include "avformat.h" #include "internal.h" @@ -1083,16 +1084,14 @@ static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom) st->codecpar->color_range = AVCOL_RANGE_JPEG; else st->codecpar->color_range = AVCOL_RANGE_MPEG; - /* 14496-12 references JPEG XR specs (rather than the more complete - * 23001-8) so some adjusting is required */ - if (color_primaries >= AVCOL_PRI_FILM) + + if (!av_color_primaries_name(color_primaries)) color_primaries = AVCOL_PRI_UNSPECIFIED; - if ((color_trc >= AVCOL_TRC_LINEAR && - color_trc <= AVCOL_TRC_LOG_SQRT) || - color_trc >= AVCOL_TRC_BT2020_10) + if (!av_color_transfer_name(color_trc)) color_trc = AVCOL_TRC_UNSPECIFIED; - if (color_matrix >= AVCOL_SPC_BT2020_NCL) + if (!av_color_space_name(color_matrix)) color_matrix = AVCOL_SPC_UNSPECIFIED; + st->codecpar->color_primaries = color_primaries; st->codecpar->color_trc = color_trc; st->codecpar->color_space = color_matrix; @@ -1102,17 +1101,22 @@ static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom) case 1: st->codecpar->color_primaries = AVCOL_PRI_BT709; break; case 5: st->codecpar->color_primaries = AVCOL_PRI_SMPTE170M; break; case 6: st->codecpar->color_primaries = AVCOL_PRI_SMPTE240M; break; + case 9: st->codecpar->color_primaries = AVCOL_PRI_BT2020; break; + case 10: st->codecpar->color_primaries = AVCOL_PRI_SMPTE431; break; + case 11: st->codecpar->color_primaries = AVCOL_PRI_SMPTE432; break; } /* color transfer, Table 4-5 */ switch (color_trc) { case 1: st->codecpar->color_trc = AVCOL_TRC_BT709; break; case 7: st->codecpar->color_trc = AVCOL_TRC_SMPTE240M; break; + case 17: st->codecpar->color_trc = AVCOL_TRC_SMPTE428; break; } /* color matrix, Table 4-6 */ switch (color_matrix) { case 1: st->codecpar->color_space = AVCOL_SPC_BT709; break; case 6: st->codecpar->color_space = AVCOL_SPC_BT470BG; break; case 7: st->codecpar->color_space = AVCOL_SPC_SMPTE240M; break; + case 9: st->codecpar->color_space = AVCOL_SPC_BT2020_NCL; break; } } av_log(c->fc, AV_LOG_TRACE, "\n"); From 043b0b9fb1481053b712d06d2c5b772f1845b72b Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 21 Oct 2016 13:48:20 +0200 Subject: [PATCH 0329/3374] Replace leftover uses of -aframes|-dframes|-vframes with -frames:a|d|v --- doc/avconv.texi | 13 ++++++++----- tests/fate/h264.mak | 2 +- tests/fate/video.mak | 4 ++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/doc/avconv.texi b/doc/avconv.texi index 9f2f295bd066a..002dba3184485 100644 --- a/doc/avconv.texi +++ b/doc/avconv.texi @@ -343,7 +343,8 @@ avconv -i myfile.avi -target vcd -bf 2 /tmp/vcd.mpg @end example @item -dframes @var{number} (@emph{output}) -Set the number of data frames to record. This is an alias for @code{-frames:d}. +Set the number of data frames to record. This is an obsolete alias for +@code{-frames:d}, which you should use instead. @item -frames[:@var{stream_specifier}] @var{framecount} (@emph{output,per-stream}) Stop writing to the stream after @var{framecount} frames. @@ -414,7 +415,8 @@ Disable automatically rotating video based on file metadata. @table @option @item -vframes @var{number} (@emph{output}) -Set the number of video frames to record. This is an alias for @code{-frames:v}. +Set the number of video frames to record. This is an obsolete alias for +@code{-frames:v}, which you should use instead. @item -r[:@var{stream_specifier}] @var{fps} (@emph{input/output,per-stream}) Set frame rate (Hz value, fraction or abbreviation). @@ -664,7 +666,8 @@ List all hardware acceleration methods supported in this build of avconv. @table @option @item -aframes @var{number} (@emph{output}) -Set the number of audio frames to record. This is an alias for @code{-frames:a}. +Set the number of audio frames to record. This is an obsolete alias for +@code{-frames:a}, which you should use instead. @item -ar[:@var{stream_specifier}] @var{freq} (@emph{input/output,per-stream}) Set the audio sampling frequency. For output streams it is set by default to the frequency of the corresponding input stream. For input @@ -1164,8 +1167,8 @@ output them in files named @file{foo-001.jpeg}, @file{foo-002.jpeg}, etc. Images will be rescaled to fit the new WxH values. If you want to extract just a limited number of frames, you can use the -above command in combination with the -vframes or -t option, or in -combination with -ss to start extracting from a certain point in time. +above command in combination with the @code{-frames:v} or @code{-t} option, +or in combination with -ss to start extracting from a certain point in time. For creating a video from many images: @example diff --git a/tests/fate/h264.mak b/tests/fate/h264.mak index ff1dd15109231..24e0c9c5ccaa1 100644 --- a/tests/fate/h264.mak +++ b/tests/fate/h264.mak @@ -385,7 +385,7 @@ fate-h264-bsf-mp4toannexb: CMD = md5 -i $(TARGET_SAMPLES) fate-h264-crop-to-container: CMD = framemd5 -i $(TARGET_SAMPLES)/h264/crop-to-container-dims-canon.mov fate-h264-direct-bff: CMD = framecrc -i $(TARGET_SAMPLES)/h264/direct-bff.mkv fate-h264-extreme-plane-pred: CMD = framemd5 -i $(TARGET_SAMPLES)/h264/extreme-plane-pred.h264 -fate-h264-interlace-crop: CMD = framecrc -i $(TARGET_SAMPLES)/h264/interlaced_crop.mp4 -vframes 3 +fate-h264-interlace-crop: CMD = framecrc -i $(TARGET_SAMPLES)/h264/interlaced_crop.mp4 -frames:v 3 fate-h264-intra-refresh-recovery: CMD = framecrc -i $(TARGET_SAMPLES)/h264/intra_refresh.h264 -frames:v 10 fate-h264-invalid-ref-mod: CMD = framecrc -i $(TARGET_SAMPLES)/h264/h264refframeregression.mp4 -an -frames 10 -pix_fmt yuv420p10le fate-h264-lossless: CMD = framecrc -i $(TARGET_SAMPLES)/h264/lossless.h264 diff --git a/tests/fate/video.mak b/tests/fate/video.mak index 18366e836f6f8..bd5d3ca3b2a89 100644 --- a/tests/fate/video.mak +++ b/tests/fate/video.mak @@ -219,10 +219,10 @@ FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, MJPEGB) += fate-mjpegb fate-mjpegb: CMD = framecrc -idct simple -fflags +bitexact -i $(TARGET_SAMPLES)/mjpegb/mjpegb_part.mov -an FATE_SAMPLES_AVCONV-$(call DEMDEC, MVI, MOTIONPIXELS) += fate-motionpixels -fate-motionpixels: CMD = framecrc -i $(TARGET_SAMPLES)/motion-pixels/INTRO-partial.MVI -an -pix_fmt rgb24 -vframes 111 +fate-motionpixels: CMD = framecrc -i $(TARGET_SAMPLES)/motion-pixels/INTRO-partial.MVI -an -pix_fmt rgb24 -frames:v 111 FATE_SAMPLES_AVCONV-$(call DEMDEC, MPEGTS, MPEG2VIDEO) += fate-mpeg2-field-enc -fate-mpeg2-field-enc: CMD = framecrc -flags +bitexact -idct simple -i $(TARGET_SAMPLES)/mpeg2/mpeg2_field_encoding.ts -an -vframes 30 +fate-mpeg2-field-enc: CMD = framecrc -flags +bitexact -idct simple -i $(TARGET_SAMPLES)/mpeg2/mpeg2_field_encoding.ts -an -frames:v 30 FATE_SAMPLES_AVCONV-$(call DEMDEC, MV, MVC1) += fate-mv-mvc1 fate-mv-mvc1: CMD = framecrc -i $(TARGET_SAMPLES)/mv/posture.mv -an -frames 25 -pix_fmt rgb555le From 6d5636ad9ab6bd9bedf902051d88b7044385f88b Mon Sep 17 00:00:00 2001 From: Pierre Edouard Lepere Date: Mon, 18 Aug 2014 10:01:09 +0200 Subject: [PATCH 0330/3374] hevc: x86: Add add_residual() SIMD optimizations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Initially written by Pierre Edouard Lepere , extended by James Almer . Signed-off-by: Alexandra Hájková --- libavcodec/hevcdsp.h | 2 +- libavcodec/x86/Makefile | 7 +- libavcodec/x86/hevc_add_res.asm | 369 ++++++++++++++++++++++++++++++++ libavcodec/x86/hevcdsp_init.c | 42 ++++ 4 files changed, 416 insertions(+), 4 deletions(-) create mode 100644 libavcodec/x86/hevc_add_res.asm diff --git a/libavcodec/hevcdsp.h b/libavcodec/hevcdsp.h index 199e5a9064628..49cb7110d5fe4 100644 --- a/libavcodec/hevcdsp.h +++ b/libavcodec/hevcdsp.h @@ -42,7 +42,7 @@ typedef struct HEVCDSPContext { void (*put_pcm)(uint8_t *dst, ptrdiff_t stride, int size, GetBitContext *gb, int pcm_bit_depth); - void (*add_residual[4])(uint8_t *dst, int16_t *coeffs, ptrdiff_t stride); + void (*add_residual[4])(uint8_t *dst, int16_t *res, ptrdiff_t stride); void (*dequant)(int16_t *coeffs); void (*transform_4x4_luma)(int16_t *coeffs); diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile index a38535b98f2f8..094c1fa5176c3 100644 --- a/libavcodec/x86/Makefile +++ b/libavcodec/x86/Makefile @@ -115,9 +115,10 @@ YASM-OBJS-$(CONFIG_AAC_DECODER) += x86/sbrdsp.o YASM-OBJS-$(CONFIG_APE_DECODER) += x86/apedsp.o YASM-OBJS-$(CONFIG_DCA_DECODER) += x86/dcadsp.o YASM-OBJS-$(CONFIG_DNXHD_ENCODER) += x86/dnxhdenc.o -YASM-OBJS-$(CONFIG_HEVC_DECODER) += x86/hevc_deblock.o \ - x86/hevc_mc.o \ - x86/hevc_idct.o +YASM-OBJS-$(CONFIG_HEVC_DECODER) += x86/hevc_add_res.o \ + x86/hevc_deblock.o \ + x86/hevc_idct.o \ + x86/hevc_mc.o YASM-OBJS-$(CONFIG_PNG_DECODER) += x86/pngdsp.o YASM-OBJS-$(CONFIG_PRORES_DECODER) += x86/proresdsp.o YASM-OBJS-$(CONFIG_RV40_DECODER) += x86/rv40dsp.o diff --git a/libavcodec/x86/hevc_add_res.asm b/libavcodec/x86/hevc_add_res.asm new file mode 100644 index 0000000000000..66b929c594712 --- /dev/null +++ b/libavcodec/x86/hevc_add_res.asm @@ -0,0 +1,369 @@ +; ***************************************************************************** +; * Provide SIMD optimizations for add_residual functions for HEVC decoding +; * Copyright (c) 2014 Pierre-Edouard LEPERE +; * +; * This file is part of Libav. +; * +; * Libav is free software; you can redistribute it and/or +; * modify it under the terms of the GNU Lesser General Public +; * License as published by the Free Software Foundation; either +; * version 2.1 of the License, or (at your option) any later version. +; * +; * Libav is distributed in the hope that it will be useful, +; * but WITHOUT ANY WARRANTY; without even the implied warranty of +; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; * Lesser General Public License for more details. +; * +; * You should have received a copy of the GNU Lesser General Public +; * License along with Libav; if not, write to the Free Software +; * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +; ****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION_RODATA 32 +max_pixels_10: times 16 dw ((1 << 10)-1) + +SECTION .text + +; the add_res macros and functions were largely inspired by h264_idct.asm from the x264 project +%macro ADD_RES_MMX_4_8 0 + mova m0, [r1] + mova m2, [r1+8] + pxor m1, m1 + pxor m3, m3 + psubw m1, m0 + psubw m3, m2 + packuswb m0, m2 + packuswb m1, m3 + + movd m2, [r0] + movd m3, [r0+r2] + punpckldq m2, m3 + paddusb m0, m2 + psubusb m0, m1 + movd [r0], m0 + psrlq m0, 32 + movd [r0+r2], m0 +%endmacro + + +INIT_MMX mmxext +; void ff_hevc_add_residual_4_8_mmxext(uint8_t *dst, int16_t *res, ptrdiff_t stride) +cglobal hevc_add_residual_4_8, 3, 3, 6 + ADD_RES_MMX_4_8 + add r1, 16 + lea r0, [r0+r2*2] + ADD_RES_MMX_4_8 + RET + +%macro ADD_RES_SSE_8_8 0 + pxor m3, m3 + mova m4, [r1] + mova m6, [r1+16] + mova m0, [r1+32] + mova m2, [r1+48] + psubw m5, m3, m4 + psubw m7, m3, m6 + psubw m1, m3, m0 + packuswb m4, m0 + packuswb m5, m1 + psubw m3, m2 + packuswb m6, m2 + packuswb m7, m3 + + movq m0, [r0] + movq m1, [r0+r2] + movhps m0, [r0+r2*2] + movhps m1, [r0+r3] + paddusb m0, m4 + paddusb m1, m6 + psubusb m0, m5 + psubusb m1, m7 + movq [r0], m0 + movq [r0+r2], m1 + movhps [r0+2*r2], m0 + movhps [r0+r3], m1 +%endmacro + +%macro ADD_RES_SSE_16_32_8 3 + mova xm2, [r1+%1] + mova xm6, [r1+%1+16] +%if cpuflag(avx2) + vinserti128 m2, m2, [r1+%1+32], 1 + vinserti128 m6, m6, [r1+%1+48], 1 +%endif + psubw m1, m0, m2 + psubw m5, m0, m6 + packuswb m2, m6 + packuswb m1, m5 + + mova xm4, [r1+%1+mmsize*2] + mova xm6, [r1+%1+mmsize*2+16] +%if cpuflag(avx2) + vinserti128 m4, m4, [r1+%1+96 ], 1 + vinserti128 m6, m6, [r1+%1+112], 1 +%endif + psubw m3, m0, m4 + psubw m5, m0, m6 + packuswb m4, m6 + packuswb m3, m5 + + paddusb m2, [%2] + paddusb m4, [%3] + psubusb m2, m1 + psubusb m4, m3 + mova [%2], m2 + mova [%3], m4 +%endmacro + + +%macro TRANSFORM_ADD_8 0 +; void ff_hevc_add_residual_8_8_(uint8_t *dst, int16_t *res, ptrdiff_t stride) +cglobal hevc_add_residual_8_8, 3, 4, 8 + lea r3, [r2*3] + ADD_RES_SSE_8_8 + add r1, 64 + lea r0, [r0+r2*4] + ADD_RES_SSE_8_8 + RET + +; void ff_hevc_add_residual_16_8_(uint8_t *dst, int16_t *res, ptrdiff_t stride) +cglobal hevc_add_residual_16_8, 3, 5, 7 + pxor m0, m0 + lea r3, [r2*3] + mov r4d, 4 +.loop: + ADD_RES_SSE_16_32_8 0, r0, r0+r2 + ADD_RES_SSE_16_32_8 64, r0+r2*2, r0+r3 + add r1, 128 + lea r0, [r0+r2*4] + dec r4d + jg .loop + RET + +; void ff_hevc_add_residual_32_8_(uint8_t *dst, int16_t *res, ptrdiff_t stride) +cglobal hevc_add_residual_32_8, 3, 5, 7 + pxor m0, m0 + mov r4d, 16 +.loop: + ADD_RES_SSE_16_32_8 0, r0, r0+16 + ADD_RES_SSE_16_32_8 64, r0+r2, r0+r2+16 + add r1, 128 + lea r0, [r0+r2*2] + dec r4d + jg .loop + RET +%endmacro + +INIT_XMM sse2 +TRANSFORM_ADD_8 +INIT_XMM avx +TRANSFORM_ADD_8 + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +; void ff_hevc_add_residual_32_8_avx2(uint8_t *dst, int16_t *res, ptrdiff_t stride) +cglobal hevc_add_residual_32_8, 3, 5, 7 + pxor m0, m0 + lea r3, [r2*3] + mov r4d, 8 +.loop: + ADD_RES_SSE_16_32_8 0, r0, r0+r2 + ADD_RES_SSE_16_32_8 128, r0+r2*2, r0+r3 + add r1, 256 + lea r0, [r0+r2*4] + dec r4d + jg .loop + RET +%endif ;HAVE_AVX2_EXTERNAL + +%macro ADD_RES_SSE_8_10 4 + mova m0, [%4] + mova m1, [%4+16] + mova m2, [%4+32] + mova m3, [%4+48] + paddw m0, [%1+0] + paddw m1, [%1+%2] + paddw m2, [%1+%2*2] + paddw m3, [%1+%3] + CLIPW m0, m4, m5 + CLIPW m1, m4, m5 + CLIPW m2, m4, m5 + CLIPW m3, m4, m5 + mova [%1+0], m0 + mova [%1+%2], m1 + mova [%1+%2*2], m2 + mova [%1+%3], m3 +%endmacro + +%macro ADD_RES_MMX_4_10 3 + mova m0, [%1+0] + mova m1, [%1+%2] + paddw m0, [%3] + paddw m1, [%3+8] + CLIPW m0, m2, m3 + CLIPW m1, m2, m3 + mova [%1+0], m0 + mova [%1+%2], m1 +%endmacro + +%macro ADD_RES_SSE_16_10 3 + mova m0, [%3] + mova m1, [%3+16] + mova m2, [%3+32] + mova m3, [%3+48] + paddw m0, [%1] + paddw m1, [%1+16] + paddw m2, [%1+%2] + paddw m3, [%1+%2+16] + CLIPW m0, m4, m5 + CLIPW m1, m4, m5 + CLIPW m2, m4, m5 + CLIPW m3, m4, m5 + mova [%1], m0 + mova [%1+16], m1 + mova [%1+%2], m2 + mova [%1+%2+16], m3 +%endmacro + +%macro ADD_RES_SSE_32_10 2 + mova m0, [%2] + mova m1, [%2+16] + mova m2, [%2+32] + mova m3, [%2+48] + + paddw m0, [%1] + paddw m1, [%1+16] + paddw m2, [%1+32] + paddw m3, [%1+48] + CLIPW m0, m4, m5 + CLIPW m1, m4, m5 + CLIPW m2, m4, m5 + CLIPW m3, m4, m5 + mova [%1], m0 + mova [%1+16], m1 + mova [%1+32], m2 + mova [%1+48], m3 +%endmacro + +%macro ADD_RES_AVX2_16_10 4 + mova m0, [%4] + mova m1, [%4+32] + mova m2, [%4+64] + mova m3, [%4+96] + + paddw m0, [%1+0] + paddw m1, [%1+%2] + paddw m2, [%1+%2*2] + paddw m3, [%1+%3] + + CLIPW m0, m4, m5 + CLIPW m1, m4, m5 + CLIPW m2, m4, m5 + CLIPW m3, m4, m5 + mova [%1+0], m0 + mova [%1+%2], m1 + mova [%1+%2*2], m2 + mova [%1+%3], m3 +%endmacro + +%macro ADD_RES_AVX2_32_10 3 + mova m0, [%3] + mova m1, [%3+32] + mova m2, [%3+64] + mova m3, [%3+96] + + paddw m0, [%1] + paddw m1, [%1+32] + paddw m2, [%1+%2] + paddw m3, [%1+%2+32] + + CLIPW m0, m4, m5 + CLIPW m1, m4, m5 + CLIPW m2, m4, m5 + CLIPW m3, m4, m5 + mova [%1], m0 + mova [%1+32], m1 + mova [%1+%2], m2 + mova [%1+%2+32], m3 +%endmacro + +; void ff_hevc_add_residual_<4|8|16|32>_10(pixel *dst, int16_t *block, ptrdiff_t stride) +INIT_MMX mmxext +cglobal hevc_add_residual_4_10, 3, 3, 6 + pxor m2, m2 + mova m3, [max_pixels_10] + ADD_RES_MMX_4_10 r0, r2, r1 + add r1, 16 + lea r0, [r0+2*r2] + ADD_RES_MMX_4_10 r0, r2, r1 + RET + +INIT_XMM sse2 +cglobal hevc_add_residual_8_10, 3, 4, 6 + pxor m4, m4 + mova m5, [max_pixels_10] + lea r3, [r2*3] + + ADD_RES_SSE_8_10 r0, r2, r3, r1 + lea r0, [r0+r2*4] + add r1, 64 + ADD_RES_SSE_8_10 r0, r2, r3, r1 + RET + +cglobal hevc_add_residual_16_10, 3, 5, 6 + pxor m4, m4 + mova m5, [max_pixels_10] + + mov r4d, 8 +.loop: + ADD_RES_SSE_16_10 r0, r2, r1 + lea r0, [r0+r2*2] + add r1, 64 + dec r4d + jg .loop + RET + +cglobal hevc_add_residual_32_10, 3, 5, 6 + pxor m4, m4 + mova m5, [max_pixels_10] + + mov r4d, 32 +.loop + ADD_RES_SSE_32_10 r0, r1 + lea r0, [r0+r2] + add r1, 64 + dec r4d + jg .loop + RET + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +cglobal hevc_add_residual_16_10, 3, 5, 6 + pxor m4, m4 + mova m5, [max_pixels_10] + lea r3, [r2*3] + + mov r4d, 4 +.loop + ADD_RES_AVX2_16_10 r0, r2, r3, r1 + lea r0, [r0+r2*4] + add r1, 128 + dec r4d + jg .loop + RET + +cglobal hevc_add_residual_32_10, 3, 5, 6 + pxor m4, m4 + mova m5, [max_pixels_10] + + mov r4d, 16 +.loop + ADD_RES_AVX2_32_10 r0, r2, r1 + lea r0, [r0+r2*2] + add r1, 128 + dec r4d + jg .loop + RET +%endif ;HAVE_AVX2_EXTERNAL diff --git a/libavcodec/x86/hevcdsp_init.c b/libavcodec/x86/hevcdsp_init.c index 0a063479039a7..a95fa30a95dee 100644 --- a/libavcodec/x86/hevcdsp_init.c +++ b/libavcodec/x86/hevcdsp_init.c @@ -91,6 +91,25 @@ void ff_hevc_idct_32x32_10_ ## opt(int16_t *coeffs, int col_limit); IDCT_FUNCS(sse2) IDCT_FUNCS(avx) +void ff_hevc_add_residual_4_8_mmxext(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_8_8_sse2(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_16_8_sse2(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_32_8_sse2(uint8_t *dst, int16_t *res, ptrdiff_t stride); + +void ff_hevc_add_residual_8_8_avx(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_16_8_avx(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_32_8_avx(uint8_t *dst, int16_t *res, ptrdiff_t stride); + +void ff_hevc_add_residual_32_8_avx2(uint8_t *dst, int16_t *res, ptrdiff_t stride); + +void ff_hevc_add_residual_4_10_mmxext(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_8_10_sse2(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_16_10_sse2(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_32_10_sse2(uint8_t *dst, int16_t *res, ptrdiff_t stride); + +void ff_hevc_add_residual_16_10_avx2(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_32_10_avx2(uint8_t *dst, int16_t *res, ptrdiff_t stride); + #define GET_PIXELS(width, depth, cf) \ void ff_hevc_get_pixels_ ## width ## _ ## depth ## _ ## cf(int16_t *dst, ptrdiff_t dststride, \ uint8_t *src, ptrdiff_t srcstride, \ @@ -278,17 +297,24 @@ void ff_hevc_dsp_init_x86(HEVCDSPContext *c, const int bit_depth) if (EXTERNAL_MMXEXT(cpu_flags)) { c->idct_dc[0] = ff_hevc_idct_4x4_dc_8_mmxext; c->idct_dc[1] = ff_hevc_idct_8x8_dc_8_mmxext; + + c->add_residual[0] = ff_hevc_add_residual_4_8_mmxext; } if (EXTERNAL_SSE2(cpu_flags)) { c->hevc_v_loop_filter_chroma = ff_hevc_v_loop_filter_chroma_8_sse2; c->hevc_h_loop_filter_chroma = ff_hevc_h_loop_filter_chroma_8_sse2; + c->add_residual[1] = ff_hevc_add_residual_8_8_sse2; + c->add_residual[2] = ff_hevc_add_residual_16_8_sse2; + c->add_residual[3] = ff_hevc_add_residual_32_8_sse2; + c->idct_dc[1] = ff_hevc_idct_8x8_dc_8_sse2; c->idct_dc[2] = ff_hevc_idct_16x16_dc_8_sse2; c->idct_dc[3] = ff_hevc_idct_32x32_dc_8_sse2; c->idct[0] = ff_hevc_idct_4x4_8_sse2; c->idct[1] = ff_hevc_idct_8x8_8_sse2; + SET_QPEL_FUNCS(0, 0, 8, sse2, ff_hevc_get_pixels); SET_EPEL_FUNCS(0, 0, 8, sse2, ff_hevc_get_pixels); @@ -307,11 +333,19 @@ void ff_hevc_dsp_init_x86(HEVCDSPContext *c, const int bit_depth) if (EXTERNAL_AVX(cpu_flags)) { c->idct[0] = ff_hevc_idct_4x4_8_avx; c->idct[1] = ff_hevc_idct_8x8_8_avx; + c->add_residual[1] = ff_hevc_add_residual_8_8_avx; + c->add_residual[2] = ff_hevc_add_residual_16_8_avx; + c->add_residual[3] = ff_hevc_add_residual_32_8_avx; + } + if (EXTERNAL_AVX2(cpu_flags)) { + c->add_residual[3] = ff_hevc_add_residual_32_8_avx2; } } else if (bit_depth == 10) { if (EXTERNAL_MMXEXT(cpu_flags)) { c->idct_dc[0] = ff_hevc_idct_4x4_dc_10_mmxext; c->idct_dc[1] = ff_hevc_idct_8x8_dc_10_mmxext; + + c->add_residual[0] = ff_hevc_add_residual_4_10_mmxext; } if (EXTERNAL_SSE2(cpu_flags)) { c->hevc_v_loop_filter_chroma = ff_hevc_v_loop_filter_chroma_10_sse2; @@ -330,11 +364,19 @@ void ff_hevc_dsp_init_x86(HEVCDSPContext *c, const int bit_depth) SET_LUMA_FUNCS(put_unweighted_pred_avg, ff_hevc_put_unweighted_pred_avg, 10, sse2); SET_CHROMA_FUNCS(put_unweighted_pred_chroma, ff_hevc_put_unweighted_pred, 10, sse2); SET_CHROMA_FUNCS(put_unweighted_pred_avg_chroma, ff_hevc_put_unweighted_pred_avg, 10, sse2); + + c->add_residual[1] = ff_hevc_add_residual_8_10_sse2; + c->add_residual[2] = ff_hevc_add_residual_16_10_sse2; + c->add_residual[3] = ff_hevc_add_residual_32_10_sse2; } if (EXTERNAL_AVX(cpu_flags)) { c->idct[0] = ff_hevc_idct_4x4_10_avx; c->idct[1] = ff_hevc_idct_8x8_10_avx; } + if (EXTERNAL_AVX2(cpu_flags)) { + c->add_residual[2] = ff_hevc_add_residual_16_10_avx2; + c->add_residual[3] = ff_hevc_add_residual_32_10_avx2; + } } #if ARCH_X86_64 From ed48a9d8143d2575a4458589cebde69ec326afd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Tue, 11 Oct 2016 10:44:19 +0200 Subject: [PATCH 0331/3374] checkasm: Add a test for HEVC add_residual --- tests/checkasm/Makefile | 2 +- tests/checkasm/checkasm.c | 3 +- tests/checkasm/checkasm.h | 1 + tests/checkasm/hevc_add_res.c | 85 +++++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 tests/checkasm/hevc_add_res.c diff --git a/tests/checkasm/Makefile b/tests/checkasm/Makefile index 22cf3db538cb6..dbd7393c59d48 100644 --- a/tests/checkasm/Makefile +++ b/tests/checkasm/Makefile @@ -12,7 +12,7 @@ AVCODECOBJS-$(CONFIG_VP8DSP) += vp8dsp.o # decoders/encoders AVCODECOBJS-$(CONFIG_DCA_DECODER) += dcadsp.o synth_filter.o -AVCODECOBJS-$(CONFIG_HEVC_DECODER) += hevc_mc.o hevc_idct.o +AVCODECOBJS-$(CONFIG_HEVC_DECODER) += hevc_add_res.o hevc_idct.o hevc_mc.o AVCODECOBJS-$(CONFIG_V210_ENCODER) += v210enc.o AVCODECOBJS-$(CONFIG_VP9_DECODER) += vp9dsp.o diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c index 040c4ebdb333d..5f0d8fdae6e41 100644 --- a/tests/checkasm/checkasm.c +++ b/tests/checkasm/checkasm.c @@ -90,8 +90,9 @@ static const struct { { "h264qpel", checkasm_check_h264qpel }, #endif #if CONFIG_HEVC_DECODER - { "hevc_mc", checkasm_check_hevc_mc }, + { "hevc_add_res", checkasm_check_hevc_add_res }, { "hevc_idct", checkasm_check_hevc_idct }, + { "hevc_mc", checkasm_check_hevc_mc }, #endif #if CONFIG_HUFFYUVDSP { "huffyuvdsp", checkasm_check_huffyuvdsp }, diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h index 75aa457572f99..462c908417bfd 100644 --- a/tests/checkasm/checkasm.h +++ b/tests/checkasm/checkasm.h @@ -39,6 +39,7 @@ void checkasm_check_fmtconvert(void); void checkasm_check_h264dsp(void); void checkasm_check_h264pred(void); void checkasm_check_h264qpel(void); +void checkasm_check_hevc_add_res(void); void checkasm_check_hevc_idct(void); void checkasm_check_hevc_mc(void); void checkasm_check_huffyuvdsp(void); diff --git a/tests/checkasm/hevc_add_res.c b/tests/checkasm/hevc_add_res.c new file mode 100644 index 0000000000000..2cd97eaf362af --- /dev/null +++ b/tests/checkasm/hevc_add_res.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2016 Alexandra Hájková + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with Libav; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include + +#include "libavutil/intreadwrite.h" + +#include "libavcodec/hevcdsp.h" + +#include "checkasm.h" + +#define randomize_buffers(buf, size) \ + do { \ + int j; \ + for (j = 0; j < size; j++) { \ + int16_t r = rnd(); \ + AV_WN16A(buf + j, r >> 3); \ + } \ + } while (0) + +#define randomize_buffers2(buf, size) \ + do { \ + int j; \ + for (j = 0; j < size; j++) \ + AV_WN16A(buf + j * 2, rnd() & 0x3FF); \ + } while (0) + +static void check_add_res(HEVCDSPContext h, int bit_depth) +{ + int i; + LOCAL_ALIGNED(32, int16_t, res0, [32 * 32]); + LOCAL_ALIGNED(32, int16_t, res1, [32 * 32]); + LOCAL_ALIGNED(32, uint8_t, dst0, [32 * 32 * 2]); + LOCAL_ALIGNED(32, uint8_t, dst1, [32 * 32 * 2]); + + for (i = 2; i <= 5; i++) { + int block_size = 1 << i; + int size = block_size * block_size; + ptrdiff_t stride = block_size << (bit_depth > 8); + declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, int16_t *res, ptrdiff_t stride); + + randomize_buffers(res0, size); + randomize_buffers2(dst0, size); + memcpy(res1, res0, sizeof(*res0) * size); + memcpy(dst1, dst0, size); + + if (check_func(h.add_residual[i - 2], "add_res_%dx%d_%d", block_size, block_size, bit_depth)) { + call_ref(dst0, res0, stride); + call_new(dst1, res1, stride); + if (memcmp(dst0, dst1, size)) + fail(); + bench_new(dst1, res1, stride); + } + } +} + +void checkasm_check_hevc_add_res(void) +{ + int bit_depth; + + for (bit_depth = 8; bit_depth <= 10; bit_depth++) { + HEVCDSPContext h; + + ff_hevc_dsp_init(&h, bit_depth); + check_add_res(h, bit_depth); + } + report("add_residual"); +} From 2f806622e1270d3ed1d41a53049a19673dafbe70 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 21 Oct 2016 14:17:07 +0200 Subject: [PATCH 0332/3374] bktr: Use memset(0) instead of zero initialization for struct sigaction sigaction is not defined in standards as a struct starting with another struct. Some *BSD variants do however, resulting in a warning from the zero initialization, which this change eliminates. This partially reverts a92be9b856bd11b081041c43c25d442028fe9a63. --- libavdevice/bktr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavdevice/bktr.c b/libavdevice/bktr.c index f76a1636c6d25..d91a60f169b67 100644 --- a/libavdevice/bktr.c +++ b/libavdevice/bktr.c @@ -104,7 +104,7 @@ static av_cold int bktr_init(const char *video_device, int width, int height, long ioctl_frequency; char *arg; int c; - struct sigaction act = { 0 }, old; + struct sigaction act, old; int ret; char errbuf[128]; @@ -135,6 +135,7 @@ static av_cold int bktr_init(const char *video_device, int width, int height, frequency = 0.0; } + memset(&act, 0, sizeof(act)); sigemptyset(&act.sa_mask); act.sa_handler = catchsignal; sigaction(SIGUSR1, &act, &old); From 016387fe0fe3eff1a03ec0673bf4d2967f6cad94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 21 Oct 2016 12:40:05 +0300 Subject: [PATCH 0333/3374] rtmpdh: Don't use the OpenSSL DH struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead use our own struct, which we already use when using gcrypt and gnutls. In OpenSSL 1.1, the DH struct has been made opaque. Signed-off-by: Martin Storsjö --- libavformat/rtmpdh.c | 95 +++++++++++++++++++++----------------------- libavformat/rtmpdh.h | 14 +++---- 2 files changed, 52 insertions(+), 57 deletions(-) diff --git a/libavformat/rtmpdh.c b/libavformat/rtmpdh.c index e7a83e173f713..593b2b1edd495 100644 --- a/libavformat/rtmpdh.c +++ b/libavformat/rtmpdh.c @@ -54,7 +54,6 @@ "F71C35FDAD44CFD2D74F9208BE258FF324943328F67329C0" \ "FFFFFFFFFFFFFFFF" -#if CONFIG_GMP || CONFIG_GCRYPT #if CONFIG_GMP #define bn_new(bn) \ do { \ @@ -93,7 +92,6 @@ else \ ret = 1; \ } while (0) -#define bn_modexp(bn, y, q, p) mpz_powm(bn, y, q, p) #define bn_random(bn, num_bits) \ do { \ int bits = num_bits; \ @@ -104,6 +102,11 @@ } \ mpz_fdiv_r_2exp(bn, bn, num_bits); \ } while (0) +static int bn_modexp(FFBigNum bn, FFBigNum y, FFBigNum q, FFBigNum p) +{ + mpz_powm(bn, y, q, p); + return 0; +} #elif CONFIG_GCRYPT #define bn_new(bn) bn = gcry_mpi_new(1) #define bn_free(bn) gcry_mpi_release(bn) @@ -116,13 +119,42 @@ #define bn_bn2bin(bn, buf, len) gcry_mpi_print(GCRYMPI_FMT_USG, buf, len, NULL, bn) #define bn_bin2bn(bn, buf, len) gcry_mpi_scan(&bn, GCRYMPI_FMT_USG, buf, len, NULL) #define bn_hex2bn(bn, buf, ret) ret = (gcry_mpi_scan(&bn, GCRYMPI_FMT_HEX, buf, 0, 0) == 0) -#define bn_modexp(bn, y, q, p) gcry_mpi_powm(bn, y, q, p) #define bn_random(bn, num_bits) gcry_mpi_randomize(bn, num_bits, GCRY_WEAK_RANDOM) +static int bn_modexp(FFBigNum bn, FFBigNum y, FFBigNum q, FFBigNum p) +{ + gcry_mpi_powm(bn, y, q, p); + return 0; +} +#elif CONFIG_OPENSSL +#define bn_new(bn) bn = BN_new() +#define bn_free(bn) BN_free(bn) +#define bn_set_word(bn, w) BN_set_word(bn, w) +#define bn_cmp(a, b) BN_cmp(a, b) +#define bn_copy(to, from) BN_copy(to, from) +#define bn_sub_word(bn, w) BN_sub_word(bn, w) +#define bn_cmp_1(bn) BN_cmp(bn, BN_value_one()) +#define bn_num_bytes(bn) BN_num_bytes(bn) +#define bn_bn2bin(bn, buf, len) BN_bn2bin(bn, buf) +#define bn_bin2bn(bn, buf, len) bn = BN_bin2bn(buf, len, 0) +#define bn_hex2bn(bn, buf, ret) ret = BN_hex2bn(&bn, buf) +#define bn_random(bn, num_bits) BN_rand(bn, num_bits, 0, 0) +static int bn_modexp(FFBigNum bn, FFBigNum y, FFBigNum q, FFBigNum p) +{ + BN_CTX *ctx = BN_CTX_new(); + if (!ctx) + return AVERROR(ENOMEM); + if (!BN_mod_exp(bn, y, q, p, ctx)) { + BN_CTX_free(ctx); + return AVERROR(EINVAL); + } + BN_CTX_free(ctx); + return 0; +} #endif #define MAX_BYTES 18000 -#define dh_new() av_malloc(sizeof(FF_DH)) +#define dh_new() av_mallocz(sizeof(FF_DH)) static FFBigNum dh_generate_key(FF_DH *dh) { @@ -143,7 +175,8 @@ static FFBigNum dh_generate_key(FF_DH *dh) return NULL; } - bn_modexp(dh->pub_key, dh->g, dh->priv_key, dh->p); + if (bn_modexp(dh->pub_key, dh->g, dh->priv_key, dh->p) < 0) + return NULL; return dh->pub_key; } @@ -152,12 +185,16 @@ static int dh_compute_key(FF_DH *dh, FFBigNum pub_key_bn, uint32_t secret_key_len, uint8_t *secret_key) { FFBigNum k; + int ret; bn_new(k); if (!k) return -1; - bn_modexp(k, pub_key_bn, dh->priv_key, dh->p); + if ((ret = bn_modexp(k, pub_key_bn, dh->priv_key, dh->p)) < 0) { + bn_free(k); + return ret; + } bn_bn2bin(k, secret_key, secret_key_len); bn_free(k); @@ -175,48 +212,6 @@ void ff_dh_free(FF_DH *dh) bn_free(dh->priv_key); av_free(dh); } -#elif CONFIG_OPENSSL -#define bn_new(bn) bn = BN_new() -#define bn_free(bn) BN_free(bn) -#define bn_set_word(bn, w) BN_set_word(bn, w) -#define bn_cmp(a, b) BN_cmp(a, b) -#define bn_copy(to, from) BN_copy(to, from) -#define bn_sub_word(bn, w) BN_sub_word(bn, w) -#define bn_cmp_1(bn) BN_cmp(bn, BN_value_one()) -#define bn_num_bytes(bn) BN_num_bytes(bn) -#define bn_bn2bin(bn, buf, len) BN_bn2bin(bn, buf) -#define bn_bin2bn(bn, buf, len) bn = BN_bin2bn(buf, len, 0) -#define bn_hex2bn(bn, buf, ret) ret = BN_hex2bn(&bn, buf) -#define bn_modexp(bn, y, q, p) \ - do { \ - BN_CTX *ctx = BN_CTX_new(); \ - if (!ctx) \ - return AVERROR(ENOMEM); \ - if (!BN_mod_exp(bn, y, q, p, ctx)) { \ - BN_CTX_free(ctx); \ - return AVERROR(EINVAL); \ - } \ - BN_CTX_free(ctx); \ - } while (0) - -#define dh_new() DH_new() -#define dh_generate_key(dh) DH_generate_key(dh) - -static int dh_compute_key(FF_DH *dh, FFBigNum pub_key_bn, - uint32_t secret_key_len, uint8_t *secret_key) -{ - if (secret_key_len < DH_size(dh)) - return AVERROR(EINVAL); - return DH_compute_key(secret_key, pub_key_bn, dh); -} - -void ff_dh_free(FF_DH *dh) -{ - if (!dh) - return; - DH_free(dh); -} -#endif static int dh_is_valid_public_key(FFBigNum y, FFBigNum p, FFBigNum q) { @@ -245,8 +240,10 @@ static int dh_is_valid_public_key(FFBigNum y, FFBigNum p, FFBigNum q) * random data. */ /* y must fulfill y^q mod p = 1 */ - bn_modexp(bn, y, q, p); + if ((ret = bn_modexp(bn, y, q, p)) < 0) + goto fail; + ret = AVERROR(EINVAL); if (bn_cmp_1(bn)) goto fail; diff --git a/libavformat/rtmpdh.h b/libavformat/rtmpdh.h index eb742dd937e2c..5233de090544d 100644 --- a/libavformat/rtmpdh.h +++ b/libavformat/rtmpdh.h @@ -26,7 +26,6 @@ #include "config.h" -#if CONFIG_GMP || CONFIG_GCRYPT #if CONFIG_GMP #include @@ -35,6 +34,12 @@ typedef mpz_ptr FFBigNum; #include typedef gcry_mpi_t FFBigNum; + +#elif CONFIG_OPENSSL +#include +#include + +typedef BIGNUM *FFBigNum; #endif typedef struct FF_DH { @@ -45,13 +50,6 @@ typedef struct FF_DH { long length; } FF_DH; -#elif CONFIG_OPENSSL -#include -#include - -typedef BIGNUM *FFBigNum; -typedef DH FF_DH; -#endif /** * Initialize a Diffie-Hellmann context. From ee050797664c7c74cae262ffab05006b55d47a11 Mon Sep 17 00:00:00 2001 From: Matt Oliver Date: Mon, 10 Oct 2016 06:49:54 +1100 Subject: [PATCH 0334/3374] openssl: Support version 1.1.0. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Further simplifications by Martin Storsjö, to minimize the diff. Signed-off-by: Martin Storsjö --- configure | 3 ++- libavformat/tls_openssl.c | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/configure b/configure index 745b5b7b91946..c7185e3094c1e 100755 --- a/configure +++ b/configure @@ -4689,7 +4689,8 @@ enabled omx && { check_header OMX_Core.h || add_cflags -isystem/opt/vc/include/IL ; } check_header OMX_Core.h ; } || die "ERROR: OpenMAX IL headers not found"; } -enabled openssl && { check_pkg_config openssl openssl/ssl.h SSL_library_init && { +enabled openssl && { { check_pkg_config openssl openssl/ssl.h OPENSSL_init_ssl || + check_pkg_config openssl openssl/ssl.h SSL_library_init; } && { add_cflags $openssl_cflags && add_extralibs $openssl_libs; }|| check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto || check_lib openssl/ssl.h SSL_library_init -lssl32 -leay32 || diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c index a75674e31fdfd..4d94774355f2e 100644 --- a/libavformat/tls_openssl.c +++ b/libavformat/tls_openssl.c @@ -43,6 +43,9 @@ typedef struct TLSContext { TLSShared tls_shared; SSL_CTX *ctx; SSL *ssl; +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + BIO_METHOD* url_bio_method; +#endif } TLSContext; #if HAVE_THREADS @@ -121,15 +124,25 @@ static int tls_close(URLContext *h) SSL_CTX_free(c->ctx); if (c->tls_shared.tcp) ffurl_close(c->tls_shared.tcp); +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + if (c->url_bio_method) + BIO_meth_free(c->url_bio_method); +#endif ff_openssl_deinit(); return 0; } static int url_bio_create(BIO *b) { +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + BIO_set_init(b, 1); + BIO_set_data(b, NULL); + BIO_set_flags(b, 0); +#else b->init = 1; b->ptr = NULL; b->flags = 0; +#endif return 1; } @@ -138,9 +151,15 @@ static int url_bio_destroy(BIO *b) return 1; } +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL +#define GET_BIO_DATA(x) BIO_get_data(x); +#else +#define GET_BIO_DATA(x) (x)->ptr; +#endif + static int url_bio_bread(BIO *b, char *buf, int len) { - URLContext *h = b->ptr; + URLContext *h = GET_BIO_DATA(b); int ret = ffurl_read(h, buf, len); if (ret >= 0) return ret; @@ -152,7 +171,7 @@ static int url_bio_bread(BIO *b, char *buf, int len) static int url_bio_bwrite(BIO *b, const char *buf, int len) { - URLContext *h = b->ptr; + URLContext *h = GET_BIO_DATA(b); int ret = ffurl_write(h, buf, len); if (ret >= 0) return ret; @@ -176,6 +195,7 @@ static int url_bio_bputs(BIO *b, const char *str) return url_bio_bwrite(b, str, strlen(str)); } +#if OPENSSL_VERSION_NUMBER < 0x1010000fL static BIO_METHOD url_bio_method = { .type = BIO_TYPE_SOURCE_SINK, .name = "urlprotocol bio", @@ -187,6 +207,7 @@ static BIO_METHOD url_bio_method = { .create = url_bio_create, .destroy = url_bio_destroy, }; +#endif static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options) { @@ -230,8 +251,20 @@ static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **op ret = AVERROR(EIO); goto fail; } +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + p->url_bio_method = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "urlprotocol bio"); + BIO_meth_set_write(p->url_bio_method, url_bio_bwrite); + BIO_meth_set_read(p->url_bio_method, url_bio_bread); + BIO_meth_set_puts(p->url_bio_method, url_bio_bputs); + BIO_meth_set_ctrl(p->url_bio_method, url_bio_ctrl); + BIO_meth_set_create(p->url_bio_method, url_bio_create); + BIO_meth_set_destroy(p->url_bio_method, url_bio_destroy); + bio = BIO_new(p->url_bio_method); + BIO_set_data(bio, c->tcp); +#else bio = BIO_new(&url_bio_method); bio->ptr = c->tcp; +#endif SSL_set_bio(p->ssl, bio, bio); if (!c->listen && !c->numerichost) SSL_set_tlsext_host_name(p->ssl, c->host); From 5e879b54a3a46817ea6c8a95a9aecab1176418b9 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Wed, 19 Oct 2016 23:45:46 +0100 Subject: [PATCH 0335/3374] vaapi_decode: Clear parameter buffers to fix picture reuse When decoding interlaced pictures, the structure is reused to render to the same surface twice. The parameter buffers were not being cleared, which caused the i965 driver to error out. --- libavcodec/vaapi_decode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c index ab8445afc081d..9e1087ff35555 100644 --- a/libavcodec/vaapi_decode.c +++ b/libavcodec/vaapi_decode.c @@ -201,6 +201,7 @@ int ff_vaapi_decode_issue(AVCodecContext *avctx, AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS) ff_vaapi_decode_destroy_buffers(avctx, pic); + pic->nb_param_buffers = 0; pic->nb_slices = 0; pic->slices_allocated = 0; av_freep(&pic->slice_buffers); From 754b20d7ebccbe8d316b12128c8cb433d5a516ac Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 19 Oct 2016 23:42:53 +0100 Subject: [PATCH 0336/3374] vaapi_h264: fix RefPicList[] field flags. Use new H264Ref.reference field to track field picture flags. The H264Picture.reference flag in DPB is now irrelevant here. This is a regression from git commit a12d3188, and that affected multiple interlaced video streams. Signed-off-by: Gwenole Beauchesne Signed-off-by: Mark Thompson --- libavcodec/vaapi_h264.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c index fa13fc0fbca62..7d8dc34d635a3 100644 --- a/libavcodec/vaapi_h264.c +++ b/libavcodec/vaapi_h264.c @@ -162,7 +162,8 @@ static void fill_vaapi_RefPicList(VAPictureH264 RefPicList[32], unsigned int i, n = 0; for (i = 0; i < ref_count; i++) if (ref_list[i].reference) - fill_vaapi_pic(&RefPicList[n++], ref_list[i].parent, 0); + fill_vaapi_pic(&RefPicList[n++], ref_list[i].parent, + ref_list[i].reference); for (; n < 32; n++) init_vaapi_pic(&RefPicList[n]); From 0aec37e625821040c103641eec9c1e7a1efa2952 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Wed, 19 Oct 2016 23:47:55 +0100 Subject: [PATCH 0337/3374] vaapi_decode: Remove vestigial unmap code The buffer map/unmap code was in an early version of this before it was committed, but the unmap was never removed. While wrong, this was harmless (and therefore unnoticed) because the buffers can't be mapped at this point - all drivers just did nothing with the call. --- libavcodec/vaapi_decode.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c index 9e1087ff35555..b02f2b8cf318f 100644 --- a/libavcodec/vaapi_decode.c +++ b/libavcodec/vaapi_decode.c @@ -150,14 +150,11 @@ int ff_vaapi_decode_issue(AVCodecContext *avctx, { VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data; VAStatus vas; - int err, i; + int err; av_log(avctx, AV_LOG_DEBUG, "Decode to surface %#x.\n", pic->output_surface); - for (i = 0; i < pic->nb_param_buffers; i++) - vaUnmapBuffer(ctx->hwctx->display, pic->param_buffers[i]); - vas = vaBeginPicture(ctx->hwctx->display, ctx->va_context, pic->output_surface); if (vas != VA_STATUS_SUCCESS) { From 99aeae20de4d09ea313fdc619d4e2df825155e62 Mon Sep 17 00:00:00 2001 From: Yogender Gupta Date: Mon, 24 Oct 2016 18:26:41 +0530 Subject: [PATCH 0338/3374] scale_npp: fix passthrough mode Signed-off-by: Anton Khirnov --- libavfilter/vf_scale_npp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_scale_npp.c b/libavfilter/vf_scale_npp.c index 247baf1133287..2fb4990953cb1 100644 --- a/libavfilter/vf_scale_npp.c +++ b/libavfilter/vf_scale_npp.c @@ -337,7 +337,7 @@ static int init_processing_chain(AVFilterContext *ctx, int in_width, int in_heig } if (last_stage < 0) - return AVERROR_BUG; + return 0; ctx->outputs[0]->hw_frames_ctx = av_buffer_ref(s->stages[last_stage].frames_ctx); if (!ctx->outputs[0]->hw_frames_ctx) return AVERROR(ENOMEM); From 052b97855de2396e46682bcbae97f95a258816d4 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Tue, 18 Oct 2016 14:50:45 +0200 Subject: [PATCH 0339/3374] aviocat: Support avio options Useful to test protocols that require options to be used. --- tools/aviocat.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/tools/aviocat.c b/tools/aviocat.c index 59244a8e4faec..3e49a61801555 100644 --- a/tools/aviocat.c +++ b/tools/aviocat.c @@ -26,7 +26,8 @@ static int usage(const char *argv0, int ret) { - fprintf(stderr, "%s [-b bytespersec] [-d duration] input_url output_url\n", argv0); + fprintf(stderr, "%s [-b bytespersec] [-d duration] [-oi ] [-oo ] input_url output_url\n", argv0); + fprintf(stderr, ": AVOptions expressed as key=value, :-separated\n"); return ret; } @@ -38,6 +39,8 @@ int main(int argc, char **argv) int64_t start_time; char errbuf[50]; AVIOContext *input, *output; + AVDictionary *in_opts = NULL; + AVDictionary *out_opts = NULL; av_register_all(); avformat_network_init(); @@ -49,6 +52,20 @@ int main(int argc, char **argv) } else if (!strcmp(argv[i], "-d") && i + 1 < argc) { duration = atoi(argv[i + 1]); i++; + } else if (!strcmp(argv[i], "-oi") && i + 1 < argc) { + if (av_dict_parse_string(&in_opts, argv[i + 1], "=", ":", 0) < 0) { + fprintf(stderr, "Cannot parse option string %s\n", + argv[i + 1]); + return usage(argv[0], 1); + } + i++; + } else if (!strcmp(argv[i], "-oo") && i + 1 < argc) { + if (av_dict_parse_string(&out_opts, argv[i + 1], "=", ":", 0) < 0) { + fprintf(stderr, "Cannot parse option string %s\n", + argv[i + 1]); + return usage(argv[0], 1); + } + i++; } else if (!input_url) { input_url = argv[i]; } else if (!output_url) { @@ -60,7 +77,7 @@ int main(int argc, char **argv) if (!output_url) return usage(argv[0], 1); - ret = avio_open2(&input, input_url, AVIO_FLAG_READ, NULL, NULL); + ret = avio_open2(&input, input_url, AVIO_FLAG_READ, NULL, &in_opts); if (ret) { av_strerror(ret, errbuf, sizeof(errbuf)); fprintf(stderr, "Unable to open %s: %s\n", input_url, errbuf); @@ -75,7 +92,7 @@ int main(int argc, char **argv) } bps = size / duration; } - ret = avio_open2(&output, output_url, AVIO_FLAG_WRITE, NULL, NULL); + ret = avio_open2(&output, output_url, AVIO_FLAG_WRITE, NULL, &out_opts); if (ret) { av_strerror(ret, errbuf, sizeof(errbuf)); fprintf(stderr, "Unable to open %s: %s\n", output_url, errbuf); @@ -102,6 +119,8 @@ int main(int argc, char **argv) avio_close(output); fail: + av_dict_free(&in_opts); + av_dict_free(&out_opts); avio_close(input); avformat_network_deinit(); return ret ? 1 : 0; From f22363c72968f1a1fc4881d8695ec7068b0aa03c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 25 Oct 2016 21:33:34 +0300 Subject: [PATCH 0340/3374] openssl: Avoid double semicolons after the GET_BIO_DATA macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the macro is expanded with a semicolon following it and the macro itself contains a semicolon, we ended up in double semicolons, which is treated as a statement that disallows further declarations. This avoids errors about mixed declarations and statements on gcc, after ee050797664c. Signed-off-by: Martin Storsjö --- libavformat/tls_openssl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c index 4d94774355f2e..aab885c8d33ed 100644 --- a/libavformat/tls_openssl.c +++ b/libavformat/tls_openssl.c @@ -152,9 +152,9 @@ static int url_bio_destroy(BIO *b) } #if OPENSSL_VERSION_NUMBER >= 0x1010000fL -#define GET_BIO_DATA(x) BIO_get_data(x); +#define GET_BIO_DATA(x) BIO_get_data(x) #else -#define GET_BIO_DATA(x) (x)->ptr; +#define GET_BIO_DATA(x) (x)->ptr #endif static int url_bio_bread(BIO *b, char *buf, int len) From 14cab426b03afd08bc9fe9b6e021a9543c4bdd7e Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 16 Oct 2016 08:49:40 +0200 Subject: [PATCH 0341/3374] build: Hardcode avversion.h dependency Since avversion.h is a generated header it must be created before dependencies can be determined as a side effect of compilation. Otherwise Make stops and restarts the build process to generate avversion.h and produces related error messages. --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index e860f2c728657..82e037103f6ef 100644 --- a/Makefile +++ b/Makefile @@ -180,6 +180,7 @@ GIT_LOG = $(SRC_PATH)/.git/logs/HEAD .version: $(wildcard $(GIT_LOG)) $(VERSION_SH) config.mak .version: M=@ +cmdutils.o libavutil/utils.o: avversion.h avversion.h .version: $(M)$(VERSION_SH) $(SRC_PATH) avversion.h $(EXTRA_VERSION) $(Q)touch .version From 255526998501f0040ae43fe4848c817a97fc578a Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 3 Jan 2016 20:45:48 +0100 Subject: [PATCH 0342/3374] mpegaudio: Do not print value of uninitialized variable libavcodec/mpegaudiodec_template.c:885:97: warning: variable 'x' is uninitialized when used here [-Wuninitialized] --- libavcodec/mpegaudiodec_template.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/mpegaudiodec_template.c b/libavcodec/mpegaudiodec_template.c index 9bfba6f22141e..4b90c6fb812d9 100644 --- a/libavcodec/mpegaudiodec_template.c +++ b/libavcodec/mpegaudiodec_template.c @@ -877,8 +877,8 @@ static int huffman_decode(MPADecodeContext *s, GranuleDef *g, exponent= exponents[s_index]; - ff_dlog(s->avctx, "region=%d n=%d x=%d y=%d exp=%d\n", - i, g->region_size[i] - j, x, y, exponent); + ff_dlog(s->avctx, "region=%d n=%d y=%d exp=%d\n", + i, g->region_size[i] - j, y, exponent); if (y & 16) { x = y >> 5; y = y & 0x0f; From 0574780d7a196f87ddd89d6362f4c47f3532b4c4 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 3 Jan 2016 20:46:51 +0100 Subject: [PATCH 0343/3374] h264_loopfilter: Do not print value of uninitialized variable libavcodec/h264_loopfilter.c:531:111: warning: variable 'edge' is uninitialized when used here [-Wuninitialized] --- libavcodec/h264_loopfilter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/h264_loopfilter.c b/libavcodec/h264_loopfilter.c index 5004074f0add3..f39b9517ffdbe 100644 --- a/libavcodec/h264_loopfilter.c +++ b/libavcodec/h264_loopfilter.c @@ -529,7 +529,7 @@ static av_always_inline void filter_mb_dir(const H264Context *h, H264SliceContex // Do not use s->qscale as luma quantizer because it has not the same // value in IPCM macroblocks. qp = (h->cur_pic.qscale_table[mb_xy] + h->cur_pic.qscale_table[mbn_xy] + 1) >> 1; - ff_tlog(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, tmp_linesize, tmp_uvlinesize); + ff_tlog(h->avctx, "filter mb:%d/%d dir:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, qp, tmp_linesize, tmp_uvlinesize); { int i; for (i = 0; i < 4; i++) ff_tlog(h->avctx, " bS[%d]:%d", i, bS[i]); ff_tlog(h->avctx, "\n"); } filter_mb_edgeh( &img_y[j*linesize], tmp_linesize, bS, qp, a, b, h, 0 ); chroma_qp_avg[0] = (sl->chroma_qp[0] + get_chroma_qp(h->ps.pps, 0, h->cur_pic.qscale_table[mbn_xy]) + 1) >> 1; From 0456e684394dc5a7b98ab9ebb48396d743bf3730 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 13 Mar 2015 00:38:07 +0100 Subject: [PATCH 0344/3374] audio_fifo: Drop write-only variable --- libavutil/audio_fifo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavutil/audio_fifo.c b/libavutil/audio_fifo.c index b562537cf68cf..e9244be02b83a 100644 --- a/libavutil/audio_fifo.c +++ b/libavutil/audio_fifo.c @@ -138,7 +138,7 @@ int av_audio_fifo_write(AVAudioFifo *af, void **data, int nb_samples) int av_audio_fifo_read(AVAudioFifo *af, void **data, int nb_samples) { - int i, ret, size; + int i, size; if (nb_samples < 0) return AVERROR(EINVAL); @@ -148,7 +148,7 @@ int av_audio_fifo_read(AVAudioFifo *af, void **data, int nb_samples) size = nb_samples * af->sample_size; for (i = 0; i < af->nb_buffers; i++) { - if ((ret = av_fifo_generic_read(af->buf[i], data[i], size, NULL)) < 0) + if (av_fifo_generic_read(af->buf[i], data[i], size, NULL) < 0) return AVERROR_BUG; } af->nb_samples -= nb_samples; From 47756f51fe836959ffa5c6e2baeacbd71e150069 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 11 Jan 2016 15:40:20 +0100 Subject: [PATCH 0345/3374] dnxhdenc: Drop pointless, commented-out debug output --- libavcodec/dnxhdenc.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c index c02b51ebbe7e6..0c6c59cec8627 100644 --- a/libavcodec/dnxhdenc.c +++ b/libavcodec/dnxhdenc.c @@ -822,9 +822,6 @@ static int dnxhd_encode_rdo(AVCodecContext *avctx, DNXHDEncContext *ctx) if (bits > ctx->frame_bits) break; } - // ff_dlog(ctx->m.avctx, - // "lambda %d, up %u, down %u, bits %d, frame %d\n", - // lambda, last_higher, last_lower, bits, ctx->frame_bits); if (end) { if (bits > ctx->frame_bits) return AVERROR(EINVAL); @@ -853,7 +850,6 @@ static int dnxhd_encode_rdo(AVCodecContext *avctx, DNXHDEncContext *ctx) down_step = 1<m.avctx, "out lambda %d\n", lambda); ctx->lambda = lambda; return 0; } @@ -882,10 +878,6 @@ static int dnxhd_find_qscale(DNXHDEncContext *ctx) if (bits > ctx->frame_bits) break; } - // ff_dlog(ctx->m.avctx, - // "%d, qscale %d, bits %d, frame %d, higher %d, lower %d\n", - // ctx->m.avctx->frame_number, qscale, bits, ctx->frame_bits, - // last_higher, last_lower); if (bits < ctx->frame_bits) { if (qscale == 1) return 1; @@ -914,7 +906,6 @@ static int dnxhd_find_qscale(DNXHDEncContext *ctx) return AVERROR(EINVAL); } } - //ff_dlog(ctx->m.avctx, "out qscale %d\n", qscale); ctx->qscale = qscale; return 0; } From c3dad1bf3b5e04e01c291b1ac41e6bef0adf2206 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 6 Dec 2015 15:13:44 +0100 Subject: [PATCH 0346/3374] nsv: Drop unnecessary TRACE level debug code The output is rather silly and the code uses non-standard __FUNCTION__. --- libavformat/nsvdec.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c index 05d5f8b910290..78e34d130f278 100644 --- a/libavformat/nsvdec.c +++ b/libavformat/nsvdec.c @@ -227,8 +227,6 @@ static int nsv_resync(AVFormatContext *s) uint32_t v = 0; int i; - av_log(s, AV_LOG_TRACE, "%s(), offset = %"PRId64", state = %d\n", __FUNCTION__, avio_tell(pb), nsv->state); - for (i = 0; i < NSV_MAX_RESYNC; i++) { if (pb->eof_reached) { av_log(s, AV_LOG_TRACE, "NSV EOF\n"); @@ -274,8 +272,6 @@ static int nsv_parse_NSVf_header(AVFormatContext *s) int table_entries; int table_entries_used; - av_log(s, AV_LOG_TRACE, "%s()\n", __FUNCTION__); - nsv->state = NSV_UNSYNC; /* in case we fail */ size = avio_rl32(pb); @@ -381,7 +377,6 @@ static int nsv_parse_NSVs_header(AVFormatContext *s) int i; AVStream *st; NSVStream *nst; - av_log(s, AV_LOG_TRACE, "%s()\n", __FUNCTION__); vtag = avio_rl32(pb); atag = avio_rl32(pb); @@ -493,9 +488,6 @@ static int nsv_read_header(AVFormatContext *s) NSVContext *nsv = s->priv_data; int i, err; - av_log(s, AV_LOG_TRACE, "%s()\n", __FUNCTION__); - av_log(s, AV_LOG_TRACE, "filename '%s'\n", s->filename); - nsv->state = NSV_UNSYNC; nsv->ahead[0].data = nsv->ahead[1].data = NULL; @@ -537,8 +529,6 @@ static int nsv_read_chunk(AVFormatContext *s, int fill_header) uint16_t asize; uint16_t auxsize; - av_log(s, AV_LOG_TRACE, "%s(%d)\n", __FUNCTION__, fill_header); - if (nsv->ahead[0].data || nsv->ahead[1].data) return 0; //-1; /* hey! eat what you've in your plate first! */ @@ -658,8 +648,6 @@ static int nsv_read_packet(AVFormatContext *s, AVPacket *pkt) NSVContext *nsv = s->priv_data; int i, err = 0; - av_log(s, AV_LOG_TRACE, "%s()\n", __FUNCTION__); - /* in case we don't already have something to eat ... */ if (!nsv->ahead[0].data && !nsv->ahead[1].data) err = nsv_read_chunk(s, 0); @@ -669,7 +657,6 @@ static int nsv_read_packet(AVFormatContext *s, AVPacket *pkt) /* now pick one of the plates */ for (i = 0; i < 2; i++) { if (nsv->ahead[i].data) { - av_log(s, AV_LOG_TRACE, "%s: using cached packet[%d]\n", __FUNCTION__, i); /* avoid the cost of new_packet + memcpy(->data) */ memcpy(pkt, &nsv->ahead[i], sizeof(AVPacket)); nsv->ahead[i].data = NULL; /* we ate that one */ From 07eea5a5ded1141632aefecfa59dcdc26de2d7ea Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 11 Dec 2015 18:58:12 +0100 Subject: [PATCH 0347/3374] nut: Drop pointless TRACE level debug code The code has little usefulness and uses the __PRETTY_FUNCTION__ GNU extension. --- libavformat/nutdec.c | 26 -------------------------- libavformat/nutenc.c | 20 -------------------- 2 files changed, 46 deletions(-) diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c index e1a9f6db0f808..25076631bfd7b 100644 --- a/libavformat/nutdec.c +++ b/libavformat/nutdec.c @@ -76,36 +76,10 @@ static uint64_t get_fourcc(AVIOContext *bc) return -1; } -#ifdef TRACE -static inline uint64_t get_v_trace(AVIOContext *bc, const char *file, - const char *func, int line) -{ - uint64_t v = ffio_read_varlen(bc); - - av_log(NULL, AV_LOG_DEBUG, "get_v %5"PRId64" / %"PRIX64" in %s %s:%d\n", - v, v, file, func, line); - return v; -} - -static inline int64_t get_s_trace(AVIOContext *bc, const char *file, - const char *func, int line) -{ - int64_t v = get_s(bc); - - av_log(NULL, AV_LOG_DEBUG, "get_s %5"PRId64" / %"PRIX64" in %s %s:%d\n", - v, v, file, func, line); - return v; -} - -#define ffio_read_varlen(bc) get_v_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#define get_s(bc) get_s_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#endif - static int get_packetheader(NUTContext *nut, AVIOContext *bc, int calculate_checksum, uint64_t startcode) { int64_t size; -// start = avio_tell(bc) - 8; startcode = av_be2ne64(startcode); startcode = ff_crc04C11DB7_update(0, (uint8_t*) &startcode, 8); diff --git a/libavformat/nutenc.c b/libavformat/nutenc.c index bf23b58a3bf9f..3c824a600d8b2 100644 --- a/libavformat/nutenc.c +++ b/libavformat/nutenc.c @@ -285,26 +285,6 @@ static void put_s(AVIOContext *bc, int64_t val) ff_put_v(bc, 2 * FFABS(val) - (val > 0)); } -#ifdef TRACE -static inline void ff_put_v_trace(AVIOContext *bc, uint64_t v, const char *file, - const char *func, int line) -{ - av_log(NULL, AV_LOG_DEBUG, "ff_put_v %5"PRId64" / %"PRIX64" in %s %s:%d\n", v, v, file, func, line); - - ff_put_v(bc, v); -} - -static inline void put_s_trace(AVIOContext *bc, int64_t v, const char *file, - const char *func, int line) -{ - av_log(NULL, AV_LOG_DEBUG, "put_s %5"PRId64" / %"PRIX64" in %s %s:%d\n", v, v, file, func, line); - - put_s(bc, v); -} -#define ff_put_v(bc, v) ff_put_v_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#define put_s(bc, v) put_s_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#endif - //FIXME remove calculate_checksum static void put_packet(NUTContext *nut, AVIOContext *bc, AVIOContext *dyn_bc, int calculate_checksum, uint64_t startcode) From ca1e5eea0c7b72a6e30aa6488cfeced3a4853521 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 3 Jan 2016 20:27:59 +0100 Subject: [PATCH 0348/3374] Remove some pointless TRACE level debug code This also kills some warnings with certain compiler options. --- libavformat/avidec.c | 17 ----------------- libavformat/ipmovie.c | 3 --- libavformat/mov.c | 6 ------ libavformat/nsvdec.c | 15 --------------- 4 files changed, 41 deletions(-) diff --git a/libavformat/avidec.c b/libavformat/avidec.c index b07dabd38ca27..0439c9c94cc95 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -1238,17 +1238,6 @@ static int avi_read_packet(AVFormatContext *s, AVPacket *pkt) // pkt->dts += ast->start; if (ast->sample_size) pkt->dts /= ast->sample_size; - av_log(s, AV_LOG_TRACE, - "dts:%"PRId64" offset:%"PRId64" %d/%d smpl_siz:%d " - "base:%d st:%d size:%d\n", - pkt->dts, - ast->frame_offset, - ast->scale, - ast->rate, - ast->sample_size, - AV_TIME_BASE, - avi->stream_index, - size); pkt->stream_index = avi->stream_index; if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { @@ -1453,12 +1442,6 @@ static int avi_load_index(AVFormatContext *s) break; tag = avio_rl32(pb); size = avio_rl32(pb); - av_log(s, AV_LOG_TRACE, "tag=%c%c%c%c size=0x%x\n", - tag & 0xff, - (tag >> 8) & 0xff, - (tag >> 16) & 0xff, - (tag >> 24) & 0xff, - size); if (tag == MKTAG('i', 'd', 'x', '1') && avi_read_idx1(s, size) >= 0) { diff --git a/libavformat/ipmovie.c b/libavformat/ipmovie.c index b719fed2b9aaf..5d789ffd54dcd 100644 --- a/libavformat/ipmovie.c +++ b/libavformat/ipmovie.c @@ -332,9 +332,6 @@ static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb, break; } s->frame_pts_inc = ((uint64_t)AV_RL32(&scratch[0])) * AV_RL16(&scratch[4]); - av_log(NULL, AV_LOG_TRACE, " %.2f frames/second (timer div = %d, subdiv = %d)\n", - 1000000.0 / s->frame_pts_inc, AV_RL32(&scratch[0]), - AV_RL16(&scratch[4])); break; case OPCODE_INIT_AUDIO_BUFFERS: diff --git a/libavformat/mov.c b/libavformat/mov.c index fee9f36382c17..34ab205d9c95e 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -427,9 +427,6 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_dict_set(&c->fc->metadata, key2, str, 0); } } - av_log(c->fc, AV_LOG_TRACE, "lang \"%3s\" ", language); - av_log(c->fc, AV_LOG_TRACE, "tag \"%s\" value \"%s\" atom \"%.4s\" %d %"PRId64"\n", - key, str, (char*)&atom.type, str_size_alloc, atom.size); av_freep(&str); return 0; @@ -505,7 +502,6 @@ static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom) dref->type = avio_rl32(pb); avio_rb32(pb); // version + flags - av_log(c->fc, AV_LOG_TRACE, "type %.4s size %d\n", (char*)&dref->type, size); if (dref->type == MKTAG('a','l','i','s') && size > 150) { /* macintosh alias record */ @@ -2010,7 +2006,6 @@ static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom) for (i = 0; i < entries && !pb->eof_reached; i++) { sc->stps_data[i] = avio_rb32(pb); - //av_log(c->fc, AV_LOG_TRACE, "stps %d\n", sc->stps_data[i]); } sc->stps_count = i; @@ -2053,7 +2048,6 @@ static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom) for (i = 0; i < entries && !pb->eof_reached; i++) { sc->keyframes[i] = avio_rb32(pb); - //av_log(c->fc, AV_LOG_TRACE, "keyframes[]=%d\n", sc->keyframes[i]); } sc->keyframe_count = i; diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c index 78e34d130f278..dc81cb64a25e9 100644 --- a/libavformat/nsvdec.c +++ b/libavformat/nsvdec.c @@ -212,13 +212,6 @@ static const AVCodecTag nsv_codec_audio_tags[] = { //static int nsv_load_index(AVFormatContext *s); static int nsv_read_chunk(AVFormatContext *s, int fill_header); -#define print_tag(str, tag, size) \ - av_log(NULL, AV_LOG_TRACE, "%s: tag=%c%c%c%c\n", \ - str, tag & 0xff, \ - (tag >> 8) & 0xff, \ - (tag >> 16) & 0xff, \ - (tag >> 24) & 0xff); - /* try to find something we recognize, and set the state accordingly */ static int nsv_resync(AVFormatContext *s) { @@ -405,8 +398,6 @@ static int nsv_parse_NSVs_header(AVFormatContext *s) nsv->avsync = avio_rl16(pb); nsv->framerate = framerate; - print_tag("NSV NSVs vtag", vtag, 0); - print_tag("NSV NSVs atag", atag, 0); av_log(s, AV_LOG_TRACE, "NSV NSVs vsize %dx%d\n", vwidth, vheight); /* XXX change to ap != NULL ? */ @@ -558,12 +549,6 @@ static int nsv_read_chunk(AVFormatContext *s, int fill_header) uint32_t av_unused auxtag; auxsize = avio_rl16(pb); auxtag = avio_rl32(pb); - av_log(s, AV_LOG_TRACE, "NSV aux data: '%c%c%c%c', %d bytes\n", - (auxtag & 0x0ff), - ((auxtag >> 8) & 0x0ff), - ((auxtag >> 16) & 0x0ff), - ((auxtag >> 24) & 0x0ff), - auxsize); avio_skip(pb, auxsize); vsize -= auxsize + sizeof(uint16_t) + sizeof(uint32_t); /* that's becoming brain-dead */ } From 1263b2039eb5aaf1522e9de9f07c787ab30a5f50 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 15 Dec 2015 10:50:18 +0100 Subject: [PATCH 0349/3374] Adjust printf conversion specifiers to match variable signedness --- libavcodec/dnxhddec.c | 10 ++++----- libavcodec/dvdec.c | 2 +- libavcodec/dxv.c | 2 +- libavcodec/fraps.c | 2 +- libavcodec/txd.c | 4 ++-- libavformat/mov.c | 42 +++++++++++++++++++------------------- libavformat/rtpdec_jpeg.c | 2 +- libavformat/rtpdec_xiph.c | 4 ++-- libavformat/rtpenc.c | 2 +- libswscale/tests/swscale.c | 2 +- 10 files changed, 36 insertions(+), 36 deletions(-) diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c index 50747ea489e0f..052f3d0c2b289 100644 --- a/libavcodec/dnxhddec.c +++ b/libavcodec/dnxhddec.c @@ -138,7 +138,7 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, ctx->height = AV_RB16(buf + 0x18); ctx->width = AV_RB16(buf + 0x1a); - ff_dlog(ctx->avctx, "width %d, height %d\n", ctx->width, ctx->height); + ff_dlog(ctx->avctx, "width %u, height %u\n", ctx->width, ctx->height); if (buf[0x21] == 0x58) { /* 10 bit */ ctx->bit_depth = ctx->avctx->bits_per_raw_sample = 10; @@ -185,7 +185,7 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, } if (buf_size < ctx->cid_table->coding_unit_size) { - av_log(ctx->avctx, AV_LOG_ERROR, "incorrect frame size (%d < %d).\n", + av_log(ctx->avctx, AV_LOG_ERROR, "incorrect frame size (%d < %u).\n", buf_size, ctx->cid_table->coding_unit_size); return AVERROR_INVALIDDATA; } @@ -194,7 +194,7 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, ctx->mb_height = buf[0x16d]; ff_dlog(ctx->avctx, - "mb width %d, mb height %d\n", ctx->mb_width, ctx->mb_height); + "mb width %u, mb height %u\n", ctx->mb_width, ctx->mb_height); if ((ctx->height + 15) >> 4 == ctx->mb_height && frame->interlaced_frame) ctx->height <<= 1; @@ -202,7 +202,7 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, if (ctx->mb_height > 68 || (ctx->mb_height << frame->interlaced_frame) > (ctx->height + 15) >> 4) { av_log(ctx->avctx, AV_LOG_ERROR, - "mb height too big: %d\n", ctx->mb_height); + "mb height too big: %u\n", ctx->mb_height); return AVERROR_INVALIDDATA; } @@ -442,7 +442,7 @@ static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, if ((avctx->width || avctx->height) && (ctx->width != avctx->width || ctx->height != avctx->height)) { - av_log(avctx, AV_LOG_WARNING, "frame size changed: %dx%d -> %dx%d\n", + av_log(avctx, AV_LOG_WARNING, "frame size changed: %dx%d -> %ux%u\n", avctx->width, avctx->height, ctx->width, ctx->height); first_field = 1; } diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c index eca3b86d0f1e5..777725d01836b 100644 --- a/libavcodec/dvdec.c +++ b/libavcodec/dvdec.c @@ -102,7 +102,7 @@ static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, int16_t *block) /* get the AC coefficients until last_index is reached */ for (;;) { - ff_dlog(NULL, "%2d: bits=%04x index=%d\n", pos, SHOW_UBITS(re, gb, 16), + ff_dlog(NULL, "%2d: bits=%04x index=%u\n", pos, SHOW_UBITS(re, gb, 16), re_index); /* our own optimized GET_RL_VLC */ index = NEG_USR32(re_cache, TEX_VLC_BITS); diff --git a/libavcodec/dxv.c b/libavcodec/dxv.c index 99327dfaceaf9..e96ab44e3577a 100644 --- a/libavcodec/dxv.c +++ b/libavcodec/dxv.c @@ -421,7 +421,7 @@ static int dxv_decode(AVCodecContext *avctx, void *data, if (size != bytestream2_get_bytes_left(gbc)) { av_log(avctx, AV_LOG_ERROR, - "Incomplete or invalid file (header %d, left %d).\n", + "Incomplete or invalid file (header %d, left %u).\n", size, bytestream2_get_bytes_left(gbc)); return AVERROR_INVALIDDATA; } diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c index eb61c70c49005..c4ec23e2811ad 100644 --- a/libavcodec/fraps.c +++ b/libavcodec/fraps.c @@ -164,7 +164,7 @@ static int decode_frame(AVCodecContext *avctx, if (version > 5) { av_log(avctx, AV_LOG_ERROR, - "This file is encoded with Fraps version %d. " \ + "This file is encoded with Fraps version %u. " "This codec can only decode versions <= 5.\n", version); return AVERROR_PATCHWELCOME; } diff --git a/libavcodec/txd.c b/libavcodec/txd.c index 463223c963f7d..ac46608f61633 100644 --- a/libavcodec/txd.c +++ b/libavcodec/txd.c @@ -56,7 +56,7 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, flags = bytestream2_get_byte(&gb); if (version < 8 || version > 9) { - av_log(avctx, AV_LOG_ERROR, "texture data version %i is unsupported\n", + av_log(avctx, AV_LOG_ERROR, "texture data version %u is unsupported\n", version); return AVERROR_PATCHWELCOME; } @@ -66,7 +66,7 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } else if (depth == 16 || depth == 32) { avctx->pix_fmt = AV_PIX_FMT_RGBA; } else { - av_log(avctx, AV_LOG_ERROR, "depth of %i is unsupported\n", depth); + av_log(avctx, AV_LOG_ERROR, "depth of %u is unsupported\n", depth); return AVERROR_PATCHWELCOME; } diff --git a/libavformat/mov.c b/libavformat/mov.c index 34ab205d9c95e..0d7ce3da1a1c0 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1935,7 +1935,7 @@ static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom) entries = avio_rb32(pb); - av_log(c->fc, AV_LOG_TRACE, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries); + av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries); if (!entries) return 0; @@ -2032,7 +2032,7 @@ static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom) entries = avio_rb32(pb); - av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %d\n", entries); + av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries); if (!entries) { @@ -2087,14 +2087,14 @@ static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom) } entries = avio_rb32(pb); - av_log(c->fc, AV_LOG_TRACE, "sample_size = %d sample_count = %d\n", sc->sample_size, entries); + av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries); sc->sample_count = entries; if (sample_size) return 0; if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) { - av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %d\n", field_size); + av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size); return AVERROR_INVALIDDATA; } @@ -2155,7 +2155,7 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom) avio_rb24(pb); /* flags */ entries = avio_rb32(pb); - av_log(c->fc, AV_LOG_TRACE, "track[%i].stts.entries = %i\n", + av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n", c->fc->nb_streams-1, entries); if (!entries) @@ -2215,7 +2215,7 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom) avio_rb24(pb); /* flags */ entries = avio_rb32(pb); - av_log(c->fc, AV_LOG_TRACE, "track[%i].ctts.entries = %i\n", c->fc->nb_streams-1, entries); + av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries); av_freep(&sc->ctts_data); @@ -2372,9 +2372,9 @@ static void mov_build_index(MOVContext *mov, AVStream *st) e->size = sample_size; e->min_distance = distance; e->flags = keyframe ? AVINDEX_KEYFRAME : 0; - av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", " - "size %d, distance %d, keyframe %d\n", st->index, current_sample, - current_offset, current_dts, sample_size, distance, keyframe); + av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", " + "size %u, distance %u, keyframe %d\n", st->index, current_sample, + current_offset, current_dts, sample_size, distance, keyframe); } current_offset += sample_size; @@ -2421,7 +2421,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st) total += chunk_count * count; } - av_log(mov->fc, AV_LOG_TRACE, "chunk count %d\n", total); + av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total); if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries) return; if (av_reallocp_array(&st->index_entries, @@ -2466,7 +2466,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st) } if (st->nb_index_entries >= total) { - av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %d\n", total); + av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total); return; } e = &st->index_entries[st->nb_index_entries++]; @@ -2475,9 +2475,9 @@ static void mov_build_index(MOVContext *mov, AVStream *st) e->size = size; e->min_distance = 0; e->flags = AVINDEX_KEYFRAME; - av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %d, offset %"PRIx64", dts %"PRId64", " - "size %d, duration %d\n", st->index, i, current_offset, current_dts, - size, samples); + av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", " + "size %u, duration %u\n", st->index, i, current_offset, current_dts, + size, samples); current_offset += size; current_dts += samples; @@ -2920,7 +2920,7 @@ static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom) } } if (!st) { - av_log(c->fc, AV_LOG_ERROR, "could not find corresponding track id %d\n", frag->track_id); + av_log(c->fc, AV_LOG_ERROR, "could not find corresponding track id %u\n", frag->track_id); return AVERROR_INVALIDDATA; } sc = st->priv_data; @@ -2955,7 +2955,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) } } if (!st) { - av_log(c->fc, AV_LOG_ERROR, "could not find corresponding track id %d\n", frag->track_id); + av_log(c->fc, AV_LOG_ERROR, "could not find corresponding track id %u\n", frag->track_id); return AVERROR_INVALIDDATA; } sc = st->priv_data; @@ -2964,7 +2964,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) avio_r8(pb); /* version */ flags = avio_rb24(pb); entries = avio_rb32(pb); - av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %d\n", flags, entries); + av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries); /* Always assume the presence of composition time offsets. * Without this assumption, for instance, we cannot deal with a track in fragmented movies that meet the following. @@ -3018,9 +3018,9 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) distance = 0; av_add_index_entry(st, offset, dts, sample_size, distance, keyframe ? AVINDEX_KEYFRAME : 0); - av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", " - "size %d, distance %d, keyframe %d\n", st->index, sc->sample_count+i, - offset, dts, sample_size, distance, keyframe); + av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", " + "size %u, distance %d, keyframe %d\n", st->index, sc->sample_count+i, + offset, dts, sample_size, distance, keyframe); distance++; dts += sample_duration; offset += sample_size; @@ -3146,7 +3146,7 @@ static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_log(c->fc, AV_LOG_WARNING, "multiple edit list entries, " "a/v desync might occur, patch welcome\n"); - av_log(c->fc, AV_LOG_TRACE, "track[%i].edit_count = %i\n", c->fc->nb_streams-1, edit_count); + av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count); return 0; } diff --git a/libavformat/rtpdec_jpeg.c b/libavformat/rtpdec_jpeg.c index bc86b159dea98..2cf41139c3794 100644 --- a/libavformat/rtpdec_jpeg.c +++ b/libavformat/rtpdec_jpeg.c @@ -230,7 +230,7 @@ static int jpeg_parse_packet(AVFormatContext *ctx, PayloadContext *jpeg, len -= 8; if (type > 1) { - av_log(ctx, AV_LOG_ERROR, "Unimplemented RTP/JPEG type %d\n", type); + av_log(ctx, AV_LOG_ERROR, "Unimplemented RTP/JPEG type %"PRIu8"\n", type); return AVERROR_PATCHWELCOME; } diff --git a/libavformat/rtpdec_xiph.c b/libavformat/rtpdec_xiph.c index 5ad69747039a0..7821686983e1a 100644 --- a/libavformat/rtpdec_xiph.c +++ b/libavformat/rtpdec_xiph.c @@ -247,7 +247,7 @@ parse_packed_headers(AVFormatContext *s, if (num_packed != 1 || num_headers > 3) { av_log(s, AV_LOG_ERROR, - "Unimplemented number of headers: %d packed headers, %d headers\n", + "Unimplemented number of headers: %u packed headers, %u headers\n", num_packed, num_headers); return AVERROR_PATCHWELCOME; } @@ -255,7 +255,7 @@ parse_packed_headers(AVFormatContext *s, if (packed_headers_end - packed_headers != length || length1 > length || length2 > length - length1) { av_log(s, AV_LOG_ERROR, - "Bad packed header lengths (%d,%d,%td,%d)\n", length1, + "Bad packed header lengths (%u,%u,%td,%u)\n", length1, length2, packed_headers_end - packed_headers, length); return AVERROR_INVALIDDATA; } diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index 2cae839e583ad..f43be2fe872d9 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -140,7 +140,7 @@ static int rtp_write_header(AVFormatContext *s1) } else s1->packet_size = s1->pb->max_packet_size; if (s1->packet_size <= 12) { - av_log(s1, AV_LOG_ERROR, "Max packet size %d too low\n", s1->packet_size); + av_log(s1, AV_LOG_ERROR, "Max packet size %u too low\n", s1->packet_size); return AVERROR(EIO); } s->buf = av_malloc(s1->packet_size); diff --git a/libswscale/tests/swscale.c b/libswscale/tests/swscale.c index 309ef812c7adf..853a8a7231754 100644 --- a/libswscale/tests/swscale.c +++ b/libswscale/tests/swscale.c @@ -305,7 +305,7 @@ static int fileTest(uint8_t *ref[4], int refStride[4], int w, int h, FILE *fp, ret = sscanf(buf, " %12s %dx%d -> %12s %dx%d flags=%d CRC=%x" - " SSD=%"PRId64 ", %"PRId64 ", %"PRId64 ", %"PRId64 "\n", + " SSD=%"PRIu64 ", %"PRIu64 ", %"PRIu64 ", %"PRIu64 "\n", srcStr, &srcW, &srcH, dstStr, &dstW, &dstH, &flags, &r.crc, &r.ssdY, &r.ssdU, &r.ssdV, &r.ssdA); if (ret != 12) { From fbe425c8d29e473a8f69ae2dc52b1a10b77f3b44 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 8 Dec 2015 15:57:04 +0100 Subject: [PATCH 0350/3374] hap: Adjust printf length modifiers to match variable types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit libavcodec/hapenc.c:121:20: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 4 has type ‘size_t {aka unsigned int}’ [-Wformat=] libavcodec/hapenc.c:121:20: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 5 has type ‘size_t {aka unsigned int}’ [-Wformat=] --- libavcodec/hapenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/hapenc.c b/libavcodec/hapenc.c index 9ebad4a630c48..bf2ccaa35967d 100644 --- a/libavcodec/hapenc.c +++ b/libavcodec/hapenc.c @@ -118,7 +118,7 @@ static int hap_compress_frame(AVCodecContext *avctx, uint8_t *dst) /* If there is no gain from snappy, just use the raw texture. */ if (chunk->compressed_size >= chunk->uncompressed_size) { av_log(avctx, AV_LOG_VERBOSE, - "Snappy buffer bigger than uncompressed (%lu >= %lu bytes).\n", + "Snappy buffer bigger than uncompressed (%zu >= %zu bytes).\n", chunk->compressed_size, chunk->uncompressed_size); memcpy(chunk_dst, chunk_src, chunk->uncompressed_size); chunk->compressor = HAP_COMP_NONE; From c454dfcff90f0ed39c7b0d4e85664986a8b4476c Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 11 Dec 2015 17:29:11 +0100 Subject: [PATCH 0351/3374] Use ISO C printf conversion specifiers where appropriate --- libavcodec/bitstream.c | 2 +- libavcodec/dnxhddec.c | 10 +++++----- libavcodec/dvdec.c | 2 +- libavcodec/dvdsubdec.c | 9 +++++---- libavcodec/dxv.c | 3 ++- libavformat/mov.c | 25 ++++++++++++++----------- libavformat/mov_chan.c | 5 +++-- libavformat/mpegtsenc.c | 2 +- libavformat/nsvdec.c | 22 ++++++++++++++-------- libavformat/rtpenc.c | 3 ++- 10 files changed, 48 insertions(+), 35 deletions(-) diff --git a/libavcodec/bitstream.c b/libavcodec/bitstream.c index 656ac47d9604e..c7eba2913f0bd 100644 --- a/libavcodec/bitstream.c +++ b/libavcodec/bitstream.c @@ -182,7 +182,7 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, n = codes[i].bits; code = codes[i].code; symbol = codes[i].symbol; - ff_dlog(NULL, "i=%d n=%d code=0x%x\n", i, n, code); + ff_dlog(NULL, "i=%d n=%d code=0x%"PRIx32"\n", i, n, code); if (n <= table_nb_bits) { /* no need to add another table */ j = code >> (32 - table_nb_bits); diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c index 052f3d0c2b289..75247eaff439f 100644 --- a/libavcodec/dnxhddec.c +++ b/libavcodec/dnxhddec.c @@ -122,7 +122,7 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, if (memcmp(buf, header_prefix, 5) && memcmp(buf, header_prefix444, 5)) { av_log(ctx->avctx, AV_LOG_ERROR, - "unknown header 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", + "unknown header 0x%02"PRIX8" 0x%02"PRIX8" 0x%02"PRIX8" 0x%02"PRIX8" 0x%02"PRIX8"\n", buf[0], buf[1], buf[2], buf[3], buf[4]); return AVERROR_INVALIDDATA; } @@ -131,7 +131,7 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, frame->interlaced_frame = 1; frame->top_field_first = first_field ^ ctx->cur_field; av_log(ctx->avctx, AV_LOG_DEBUG, - "interlaced %d, cur field %d\n", buf[5] & 3, ctx->cur_field); + "interlaced %"PRId8", cur field %d\n", buf[5] & 3, ctx->cur_field); } ctx->mbaff = buf[0x6] & 32; @@ -157,7 +157,7 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, ctx->avctx->pix_fmt = AV_PIX_FMT_YUV422P; ctx->decode_dct_block = dnxhd_decode_dct_block_8; } else { - av_log(ctx->avctx, AV_LOG_ERROR, "invalid bit depth value (%d).\n", + av_log(ctx->avctx, AV_LOG_ERROR, "invalid bit depth value (%"PRId8").\n", buf[0x21]); return AVERROR_INVALIDDATA; } @@ -208,10 +208,10 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, for (i = 0; i < ctx->mb_height; i++) { ctx->mb_scan_index[i] = AV_RB32(buf + 0x170 + (i << 2)); - ff_dlog(ctx->avctx, "mb scan index %d\n", ctx->mb_scan_index[i]); + ff_dlog(ctx->avctx, "mb scan index %"PRIu32"\n", ctx->mb_scan_index[i]); if (buf_size < ctx->mb_scan_index[i] + 0x280) { av_log(ctx->avctx, AV_LOG_ERROR, - "invalid mb scan index (%d < %d).\n", + "invalid mb scan index (%d < %"PRIu32").\n", buf_size, ctx->mb_scan_index[i] + 0x280); return AVERROR_INVALIDDATA; } diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c index 777725d01836b..dc37a5efddd2b 100644 --- a/libavcodec/dvdec.c +++ b/libavcodec/dvdec.c @@ -270,7 +270,7 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg) } if (mb->pos >= 64 && mb->pos < 127) av_log(avctx, AV_LOG_ERROR, - "AC EOB marker is absent pos=%d\n", mb->pos); + "AC EOB marker is absent pos=%"PRIu8"\n", mb->pos); block += 64; mb++; } diff --git a/libavcodec/dvdsubdec.c b/libavcodec/dvdsubdec.c index 6e55a09bc2dc2..86c287391ff92 100644 --- a/libavcodec/dvdsubdec.c +++ b/libavcodec/dvdsubdec.c @@ -247,7 +247,8 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header, alpha[1] = buf[pos + 1] >> 4; alpha[0] = buf[pos + 1] & 0x0f; pos += 2; - ff_dlog(NULL, "alpha=%x%x%x%x\n", alpha[0],alpha[1],alpha[2],alpha[3]); + ff_dlog(NULL, "alpha=%"PRIx8"%"PRIx8"%"PRIx8"%"PRIx8"\n", + alpha[0], alpha[1], alpha[2], alpha[3]); break; case 0x05: case 0x85: @@ -267,7 +268,7 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header, goto fail; offset1 = AV_RB16(buf + pos); offset2 = AV_RB16(buf + pos + 2); - ff_dlog(NULL, "offset1=0x%04x offset2=0x%04x\n", offset1, offset2); + ff_dlog(NULL, "offset1=0x%04"PRIx64" offset2=0x%04"PRIx64"\n", offset1, offset2); pos += 4; break; case 0x86: @@ -275,7 +276,7 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header, goto fail; offset1 = AV_RB32(buf + pos); offset2 = AV_RB32(buf + pos + 4); - ff_dlog(NULL, "offset1=0x%04x offset2=0x%04x\n", offset1, offset2); + ff_dlog(NULL, "offset1=0x%04"PRIx64" offset2=0x%04"PRIx64"\n", offset1, offset2); pos += 8; break; @@ -515,7 +516,7 @@ static int dvdsub_decode(AVCodecContext *avctx, goto no_subtitle; #if defined(DEBUG) - ff_dlog(NULL, "start=%d ms end =%d ms\n", + ff_dlog(NULL, "start=%"PRIu32" ms end =%"PRIu32" ms\n", sub->start_display_time, sub->end_display_time); ppm_save("/tmp/a.ppm", sub->rects[0]->data[0], diff --git a/libavcodec/dxv.c b/libavcodec/dxv.c index e96ab44e3577a..9b14ef46ae719 100644 --- a/libavcodec/dxv.c +++ b/libavcodec/dxv.c @@ -393,7 +393,8 @@ static int dxv_decode(AVCodecContext *avctx, void *data, ctx->tex_funct = ctx->texdsp.dxt1_block; ctx->tex_step = 8; } else { - av_log(avctx, AV_LOG_ERROR, "Unsupported header (0x%08X)\n.", tag); + av_log(avctx, AV_LOG_ERROR, + "Unsupported header (0x%08"PRIX32")\n.", tag); return AVERROR_INVALIDDATA; } ctx->tex_rat = 1; diff --git a/libavformat/mov.c b/libavformat/mov.c index 0d7ce3da1a1c0..5a46f9440ad40 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -517,7 +517,8 @@ static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (ret < 0) return ret; dref->volume[volume_len] = 0; - av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len); + av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %"PRIu16"\n", + dref->volume, volume_len); avio_skip(pb, 12); @@ -527,14 +528,15 @@ static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (ret < 0) return ret; dref->filename[len] = 0; - av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len); + av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %"PRIu16"\n", + dref->filename, len); avio_skip(pb, 16); /* read next level up_from_alias/down_to_target */ dref->nlvl_from = avio_rb16(pb); dref->nlvl_to = avio_rb16(pb); - av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n", + av_log(c->fc, AV_LOG_DEBUG, "nlvl from %"PRId16", nlvl to %"PRId16"\n", dref->nlvl_from, dref->nlvl_to); avio_skip(pb, 16); @@ -544,7 +546,8 @@ static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom) return AVERROR_EOF; type = avio_rb16(pb); len = avio_rb16(pb); - av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len); + av_log(c->fc, AV_LOG_DEBUG, "type %"PRId16", len %"PRIu16"\n", + type, len); if (len&1) len += 1; if (type == 2) { // absolute path @@ -594,7 +597,7 @@ static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom) avio_skip(pb, len); } } else { - av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x08%x size %d\n", + av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x08%"PRIx32" size %"PRIu32"\n", dref->type, size); entries--; i--; @@ -1535,7 +1538,7 @@ static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, st->codecpar->sample_rate = ((avio_rb32(pb) >> 16)); // 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); + av_log(c->fc, AV_LOG_TRACE, "version =%"PRIu16", isom =%d\n", version, c->isom); if (!c->isom) { if (version == 1) { sc->samples_per_frame = avio_rb32(pb); @@ -1832,7 +1835,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) id = mov_codec_id(st, format); av_log(c->fc, AV_LOG_TRACE, - "size=%"PRId64" format=0x%08x codec_type=%d\n", + "size=%"PRId64" format=0x%08"PRIx32" codec_type=%d\n", size, format, st->codecpar->codec_type); if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) { @@ -2575,14 +2578,14 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (mov_open_dref(c->fc, &sc->pb, c->fc->filename, dref) < 0) av_log(c->fc, AV_LOG_ERROR, "stream %d, error opening alias: path='%s', dir='%s', " - "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n", + "filename='%s', volume='%s', nlvl_from=%"PRId16", nlvl_to=%"PRId16"\n", st->index, dref->path, dref->dir, dref->filename, dref->volume, dref->nlvl_from, dref->nlvl_to); } else { av_log(c->fc, AV_LOG_WARNING, "Skipped opening external track: " "stream %d, alias: path='%s', dir='%s', " - "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d." + "filename='%s', volume='%s', nlvl_from=%"PRId16", nlvl_to=%"PRId16"." "Set enable_drefs to allow this.\n", st->index, dref->path, dref->dir, dref->filename, dref->volume, dref->nlvl_from, dref->nlvl_to); @@ -3231,8 +3234,8 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) a.size = avio_rb32(pb); a.type = avio_rl32(pb); } - av_log(c->fc, AV_LOG_TRACE, "type: %08x '%.4s' parent:'%.4s' sz: %"PRId64" %"PRId64" %"PRId64"\n", - a.type, (char*)&a.type, (char*)&atom.type, a.size, total_size, atom.size); + av_log(c->fc, AV_LOG_TRACE, "type: %08"PRIx32" '%.4s' parent:'%.4s' sz: %"PRId64" %"PRId64" %"PRId64"\n", + a.type, (char*)&a.type, (char*)&atom.type, a.size, total_size, atom.size); total_size += 8; if (a.size == 1) { /* 64 bit extended size */ a.size = avio_rb64(pb) - 8; diff --git a/libavformat/mov_chan.c b/libavformat/mov_chan.c index 19f657ad7c19e..1b05cdff4e25f 100644 --- a/libavformat/mov_chan.c +++ b/libavformat/mov_chan.c @@ -556,8 +556,9 @@ int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, bitmap = avio_rb32(pb); num_descr = avio_rb32(pb); - av_log(s, AV_LOG_TRACE, "chan: layout=%u bitmap=%u num_descr=%u\n", - layout_tag, bitmap, num_descr); + av_log(s, AV_LOG_TRACE, + "chan: layout=%"PRIu32" bitmap=%"PRIu32" num_descr=%"PRIu32"\n", + layout_tag, bitmap, num_descr); if (size < 12ULL + num_descr * 20ULL) return 0; diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index a52e684c6fda2..12c406fd51b09 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -1083,7 +1083,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) do { p = avpriv_find_start_code(p, buf_end, &state); - av_log(s, AV_LOG_TRACE, "nal %d\n", state & 0x1f); + av_log(s, AV_LOG_TRACE, "nal %"PRIu32"\n", state & 0x1f); } while (p < buf_end && (state & 0x1f) != 9 && (state & 0x1f) != 5 && (state & 0x1f) != 1); diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c index dc81cb64a25e9..c91d2a15dd985 100644 --- a/libavformat/nsvdec.c +++ b/libavformat/nsvdec.c @@ -229,7 +229,7 @@ static int nsv_resync(AVFormatContext *s) v <<= 8; v |= avio_r8(pb); if (i < 8) { - av_log(s, AV_LOG_TRACE, "NSV resync: [%d] = %02x\n", i, v & 0x0FF); + av_log(s, AV_LOG_TRACE, "NSV resync: [%d] = %02"PRIx32"\n", i, v & 0x0FF); } if ((v & 0x0000ffff) == 0xefbe) { /* BEEF */ @@ -398,7 +398,8 @@ static int nsv_parse_NSVs_header(AVFormatContext *s) nsv->avsync = avio_rl16(pb); nsv->framerate = framerate; - av_log(s, AV_LOG_TRACE, "NSV NSVs vsize %dx%d\n", vwidth, vheight); + av_log(s, AV_LOG_TRACE, "NSV NSVs vsize %"PRIu16"x%"PRIu16"\n", + vwidth, vheight); /* XXX change to ap != NULL ? */ if (s->nb_streams == 0) { /* streams not yet published, let's do that */ @@ -543,7 +544,8 @@ static int nsv_read_chunk(AVFormatContext *s, int fill_header) asize = avio_rl16(pb); vsize = (vsize << 4) | (auxcount >> 4); auxcount &= 0x0f; - av_log(s, AV_LOG_TRACE, "NSV CHUNK %d aux, %u bytes video, %d bytes audio\n", auxcount, vsize, asize); + av_log(s, AV_LOG_TRACE, "NSV CHUNK %"PRIu8" aux, %"PRIu32" bytes video, %"PRIu16" bytes audio\n", + auxcount, vsize, asize); /* skip aux stuff */ for (i = 0; i < auxcount; i++) { uint32_t av_unused auxtag; @@ -574,7 +576,8 @@ static int nsv_read_chunk(AVFormatContext *s, int fill_header) pkt->dts = nst->frame_offset; pkt->flags |= nsv->state == NSV_HAS_READ_NSVS ? AV_PKT_FLAG_KEY : 0; /* keyframe only likely on a sync frame */ for (i = 0; i < FFMIN(8, vsize); i++) - av_log(s, AV_LOG_TRACE, "NSV video: [%d] = %02x\n", i, pkt->data[i]); + av_log(s, AV_LOG_TRACE, "NSV video: [%d] = %02"PRIx8"\n", + i, pkt->data[i]); } if(st[NSV_ST_VIDEO]) ((NSVStream*)st[NSV_ST_VIDEO]->priv_data)->frame_offset++; @@ -594,11 +597,12 @@ static int nsv_read_chunk(AVFormatContext *s, int fill_header) if (!channels || !samplerate) return AVERROR_INVALIDDATA; asize-=4; - av_log(s, AV_LOG_TRACE, "NSV RAWAUDIO: bps %d, nchan %d, srate %d\n", bps, channels, samplerate); + av_log(s, AV_LOG_TRACE, "NSV RAWAUDIO: bps %"PRIu8", nchan %"PRIu8", srate %"PRIu16"\n", + bps, channels, samplerate); if (fill_header) { st[NSV_ST_AUDIO]->need_parsing = AVSTREAM_PARSE_NONE; /* we know everything */ if (bps != 16) { - av_log(s, AV_LOG_TRACE, "NSV AUDIO bit/sample != 16 (%d)!!!\n", bps); + av_log(s, AV_LOG_TRACE, "NSV AUDIO bit/sample != 16 (%"PRIu8")!!!\n", bps); } bps /= channels; // ??? if (bps == 8) @@ -607,7 +611,8 @@ static int nsv_read_chunk(AVFormatContext *s, int fill_header) channels = 1; st[NSV_ST_AUDIO]->codecpar->channels = channels; st[NSV_ST_AUDIO]->codecpar->sample_rate = samplerate; - av_log(s, AV_LOG_TRACE, "NSV RAWAUDIO: bps %d, nchan %d, srate %d\n", bps, channels, samplerate); + av_log(s, AV_LOG_TRACE, "NSV RAWAUDIO: bps %"PRIu8", nchan %"PRIu8", srate %"PRIu16"\n", + bps, channels, samplerate); } } av_get_packet(pb, pkt, asize); @@ -618,7 +623,8 @@ static int nsv_read_chunk(AVFormatContext *s, int fill_header) pkt->dts = (((NSVStream*)st[NSV_ST_VIDEO]->priv_data)->frame_offset-1); pkt->dts *= (int64_t)1000 * nsv->framerate.den; pkt->dts += (int64_t)nsv->avsync * nsv->framerate.num; - av_log(s, AV_LOG_TRACE, "NSV AUDIO: sync:%d, dts:%"PRId64, nsv->avsync, pkt->dts); + av_log(s, AV_LOG_TRACE, "NSV AUDIO: sync:%"PRId16", dts:%"PRId64, + nsv->avsync, pkt->dts); } nst->frame_offset++; } diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index f43be2fe872d9..28c309ea18485 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -259,7 +259,8 @@ static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time, int bye) RTPMuxContext *s = s1->priv_data; uint32_t rtp_ts; - av_log(s1, AV_LOG_TRACE, "RTCP: %02x %"PRIx64" %x\n", s->payload_type, ntp_time, s->timestamp); + av_log(s1, AV_LOG_TRACE, "RTCP: %02x %"PRIx64" %"PRIx32"\n", + s->payload_type, ntp_time, s->timestamp); s->last_rtcp_ntp_time = ntp_time; rtp_ts = av_rescale_q(ntp_time - s->first_rtcp_ntp_time, (AVRational){1, 1000000}, From 7a2b2b6a92c4b528ecb640790eca0aa790d858f4 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 11 Jan 2016 15:46:46 +0100 Subject: [PATCH 0352/3374] dxtory: Drop nonsense ISO C printf conversion specifiers for standard types --- libavcodec/dxtory.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/dxtory.c b/libavcodec/dxtory.c index 937b96c839e66..e2b875b5e3491 100644 --- a/libavcodec/dxtory.c +++ b/libavcodec/dxtory.c @@ -201,12 +201,12 @@ static int check_slice_size(AVCodecContext *avctx, if (slice_size > src_size - off) { av_log(avctx, AV_LOG_ERROR, - "invalid slice size %"PRIu32" (only %"PRIu32" bytes left)\n", + "invalid slice size %d (only %d bytes left)\n", slice_size, src_size - off); return AVERROR_INVALIDDATA; } if (slice_size <= 16) { - av_log(avctx, AV_LOG_ERROR, "invalid slice size %"PRIu32"\n", + av_log(avctx, AV_LOG_ERROR, "invalid slice size %d\n", slice_size); return AVERROR_INVALIDDATA; } @@ -214,7 +214,7 @@ static int check_slice_size(AVCodecContext *avctx, cur_slice_size = AV_RL32(src + off); if (cur_slice_size != slice_size - 16) { av_log(avctx, AV_LOG_ERROR, - "Slice sizes mismatch: got %"PRIu32" instead of %"PRIu32"\n", + "Slice sizes mismatch: got %d instead of %d\n", cur_slice_size, slice_size - 16); } From 3ec6f855d0f21d90a0494fb798c4cf203fdb3db0 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 11 Nov 2015 17:40:27 +0100 Subject: [PATCH 0353/3374] srt: Adjust signedness of sscanf format strings Fixes several warnings from -Wformat. --- libavcodec/srtdec.c | 2 +- libavformat/id3v2.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/srtdec.c b/libavcodec/srtdec.c index 3bee3c726fd57..4c5f6e5fe823c 100644 --- a/libavcodec/srtdec.c +++ b/libavcodec/srtdec.c @@ -192,7 +192,7 @@ static const char *read_ts(const char *buf, int *ts_start, int *ts_end, for (i=0; i<2; i++) { /* try to read timestamps in either the first or second line */ int c = sscanf(buf, "%d:%2d:%2d%*1[,.]%3d --> %d:%2d:%2d%*1[,.]%3d" - "%*[ ]X1:%u X2:%u Y1:%u Y2:%u", + "%*[ ]X1:%d X2:%d Y1:%d Y2:%d", &hs, &ms, &ss, ts_start, &he, &me, &se, ts_end, x1, x2, y1, y2); buf += strcspn(buf, "\n") + 1; diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index 5e9825de7d182..3f43b4aa8be15 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -276,7 +276,7 @@ static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, } if (!(strcmp(key, "TCON") && strcmp(key, "TCO")) && - (sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) == 1) && + (sscanf(dst, "(%u)", &genre) == 1 || sscanf(dst, "%u", &genre) == 1) && genre <= ID3v1_GENRE_MAX) { av_freep(&dst); dst = av_strdup(ff_id3v1_genre_str[genre]); From 07cac07c0c0360d67e73a7472214c79d6c520a4b Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 3 Jan 2016 20:31:13 +0100 Subject: [PATCH 0354/3374] dash: Use correct ISO C scanf conversion specifier --- libavformat/dashenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 9c7e23aa8e56a..ce018602dd05f 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -130,7 +130,7 @@ static void set_codec_str(AVFormatContext *s, AVCodecParameters *par, tags[0] = ff_mp4_obj_type; oti = av_codec_get_tag(tags, par->codec_id); if (oti) - av_strlcatf(str, size, ".%02x", oti); + av_strlcatf(str, size, ".%02"SCNx32, oti); else return; From 30015305f3b523ed7640f2c3c58b017140533c58 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 16 Dec 2015 18:02:04 +0100 Subject: [PATCH 0355/3374] Use avpriv_request_sample() where appropriate --- libavcodec/flicvideo.c | 14 +++----------- libavcodec/roqvideodec.c | 3 +-- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/libavcodec/flicvideo.c b/libavcodec/flicvideo.c index 13e6ae4b4a1a7..b4556dc1ffb42 100644 --- a/libavcodec/flicvideo.c +++ b/libavcodec/flicvideo.c @@ -116,7 +116,7 @@ static av_cold int flic_decode_init(AVCodecContext *avctx) case 15 : avctx->pix_fmt = AV_PIX_FMT_RGB555; break; case 16 : avctx->pix_fmt = AV_PIX_FMT_RGB565; break; case 24 : avctx->pix_fmt = AV_PIX_FMT_BGR24; /* Supposedly BGR, but no files to test with */ - av_log(avctx, AV_LOG_ERROR, "24Bpp FLC/FLX is unsupported due to no test files.\n"); + avpriv_request_sample(avctx, "24bpp FLC/FLX"); return AVERROR_PATCHWELCOME; default : av_log(avctx, AV_LOG_ERROR, "Unknown FLC/FLX depth of %d Bpp is unsupported.\n",depth); @@ -695,14 +695,6 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, return buf_size; } -static int flic_decode_frame_24BPP(AVCodecContext *avctx, - void *data, int *got_frame, - const uint8_t *buf, int buf_size) -{ - av_log(avctx, AV_LOG_ERROR, "24Bpp FLC Unsupported due to lack of test files.\n"); - return AVERROR_PATCHWELCOME; -} - static int flic_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) @@ -719,8 +711,8 @@ static int flic_decode_frame(AVCodecContext *avctx, buf, buf_size); } else if (avctx->pix_fmt == AV_PIX_FMT_BGR24) { - return flic_decode_frame_24BPP(avctx, data, got_frame, - buf, buf_size); + avpriv_request_sample(avctx, "24bpp FLC"); + return AVERROR_PATCHWELCOME; } /* Should not get here, ever as the pix_fmt is processed */ diff --git a/libavcodec/roqvideodec.c b/libavcodec/roqvideodec.c index 4f778dc98aef5..d141064b82b1f 100644 --- a/libavcodec/roqvideodec.c +++ b/libavcodec/roqvideodec.c @@ -164,8 +164,7 @@ static av_cold int roq_decode_init(AVCodecContext *avctx) s->avctx = avctx; if (avctx->width % 16 || avctx->height % 16) { - av_log(avctx, AV_LOG_ERROR, - "Dimensions must be a multiple of 16\n"); + avpriv_request_sample(avctx, "Dimensions not being a multiple of 16"); return AVERROR_PATCHWELCOME; } From 801ac7156d3efb8e088fb6024f568eb36a293887 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sat, 29 Oct 2016 17:00:20 +0200 Subject: [PATCH 0356/3374] qsv: Be informative when reporting that no data has been consumed --- libavcodec/qsvdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index e19eba5b52ffd..81c63b129269b 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -305,7 +305,7 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q, /* make sure we do not enter an infinite loop if the SDK * did not consume any data and did not return anything */ if (!*sync && !bs.DataOffset) { - av_log(avctx, AV_LOG_WARNING, "A decode call did not consume any data\n"); + ff_qsv_print_warning(avctx, ret, "A decode call did not consume any data"); bs.DataOffset = avpkt->size; } From c541a44e029e8a4f21db028c34fee3ad1c10a409 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sun, 30 Oct 2016 14:52:45 +0100 Subject: [PATCH 0357/3374] Revert "rtmpproto: Don't include a client version in the unencrypted C1 handshake" This reverts commit 7d8d726be7dc46343ab1c98c339c1ed44bcb07c1. --- libavformat/rtmpproto.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 1ffc79a8cee7a..0097841e8109a 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -1198,7 +1198,10 @@ static int rtmp_handshake(URLContext *s, RTMPContext *rt) uint8_t tosend [RTMP_HANDSHAKE_PACKET_SIZE+1] = { 3, // unencrypted data 0, 0, 0, 0, // client uptime - 0, 0, 0, 0, // zeros + RTMP_CLIENT_VER1, + RTMP_CLIENT_VER2, + RTMP_CLIENT_VER3, + RTMP_CLIENT_VER4, }; uint8_t clientdata[RTMP_HANDSHAKE_PACKET_SIZE]; uint8_t serverdata[RTMP_HANDSHAKE_PACKET_SIZE+1]; From dad7514f9ec8a8c5e44d70fcfbbcedeff16f7e13 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sun, 30 Oct 2016 17:44:49 +0100 Subject: [PATCH 0358/3374] xcb: Add all the libraries to the link line explicitly Avoid an underlink issue on recent distributions. CC: libav-stable@libav.org --- configure | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index c7185e3094c1e..8c2b4fdfa94c3 100755 --- a/configure +++ b/configure @@ -4786,8 +4786,8 @@ if enabled libxcb; then enabled libxcb_xfixes && die "ERROR: libxcb_xfixes not found"; } && enable libxcb_xfixes - add_cflags "$xcb_event_cflags $xcb_shm_cflags $xcb_xfixes_cflags" - add_extralibs "$xcb_event_libs $xcb_shm_libs $xcb_xfixes_libs" + add_cflags "$xcb_shape_cflags $xcb_event_cflags $xcb_shm_cflags $xcb_xfixes_cflags" + add_extralibs "$xcb_shape_libs $xcb_event_libs $xcb_shm_libs $xcb_xfixes_libs" fi enabled vaapi && require vaapi va/va.h vaInitialize -lva From 218ed7250c103a975e874fb16e8e5941f4cbe223 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 30 Oct 2016 14:57:30 +0000 Subject: [PATCH 0359/3374] openssl: Allow newer TLS versions than TLSv1 The use of TLSv1_*_method() disallows newer protocol versions; instead use SSLv23_*_method() and then explicitly disable the deprecated protocol versions which should not be supported. --- libavformat/tls_openssl.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c index aab885c8d33ed..0abccf00a9dbe 100644 --- a/libavformat/tls_openssl.c +++ b/libavformat/tls_openssl.c @@ -221,12 +221,17 @@ static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **op if ((ret = ff_tls_open_underlying(c, h, uri, options)) < 0) goto fail; - p->ctx = SSL_CTX_new(c->listen ? TLSv1_server_method() : TLSv1_client_method()); + // We want to support all versions of TLS >= 1.0, but not the deprecated + // and insecure SSLv2 and SSLv3. Despite the name, SSLv23_*_method() + // enables support for all versions of SSL and TLS, and we then disable + // support for the old protocols immediately after creating the context. + p->ctx = SSL_CTX_new(c->listen ? SSLv23_server_method() : SSLv23_client_method()); if (!p->ctx) { av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL)); ret = AVERROR(EIO); goto fail; } + SSL_CTX_set_options(p->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); if (c->ca_file) SSL_CTX_load_verify_locations(p->ctx, c->ca_file, NULL); if (c->cert_file && !SSL_CTX_use_certificate_chain_file(p->ctx, c->cert_file)) { From 7d308bf84bda78d47c01439ff625bb06624991a7 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Mon, 24 Oct 2016 17:22:54 -0400 Subject: [PATCH 0360/3374] avprobe: Add -show_stream_entry to get a single stream property This is needed for improved fate testing and it is modeled after -show_format_entry. The main behavioral difference is that when a print function is called with an empty key, rather than discarding it, the closes key in the hierarchy is used instead. Signed-off-by: Vittorio Giovara --- avprobe.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/avprobe.c b/avprobe.c index eff9c0d308bbe..ff28a0b343133 100644 --- a/avprobe.c +++ b/avprobe.c @@ -54,6 +54,11 @@ static AVDictionary *fmt_entries_to_show = NULL; static int nb_fmt_entries_to_show; static int do_show_packets = 0; static int do_show_streams = 0; +static AVDictionary *stream_entries_to_show = NULL; +static int nb_stream_entries_to_show; + +/* key used to print when probe_{int,str}(NULL, ..) is invoked */ +static const char *header_key; static int show_value_unit = 0; static int use_value_prefix = 0; @@ -78,6 +83,7 @@ static const char unit_bit_per_second_str[] = "bit/s"; static void avprobe_cleanup(int ret) { av_dict_free(&fmt_entries_to_show); + av_dict_free(&stream_entries_to_show); } /* @@ -402,6 +408,37 @@ static void show_format_entry_string(const char *key, const char *value) } } +static void show_stream_entry_header(const char *key, int value) +{ + header_key = key; +} + +static void show_stream_entry_footer(const char *key, int value) +{ + header_key = NULL; +} + +static void show_stream_entry_integer(const char *key, int64_t value) +{ + if (!key) + key = header_key; + + if (key && av_dict_get(stream_entries_to_show, key, NULL, 0)) { + if (nb_stream_entries_to_show > 1) + avio_printf(probe_out, "%s=", key); + avio_printf(probe_out, "%"PRId64"\n", value); + } +} + +static void show_stream_entry_string(const char *key, const char *value) +{ + if (key && av_dict_get(stream_entries_to_show, key, NULL, 0)) { + if (nb_stream_entries_to_show > 1) + avio_printf(probe_out, "%s=", key); + avio_printf(probe_out, "%s\n", value); + } +} + static void probe_group_enter(const char *name, int type) { int64_t count = -1; @@ -973,6 +1010,23 @@ static int opt_show_format_entry(void *optctx, const char *opt, const char *arg) return 0; } +static int opt_show_stream_entry(void *optctx, const char *opt, const char *arg) +{ + do_show_streams = 1; + nb_stream_entries_to_show++; + octx.print_header = NULL; + octx.print_footer = NULL; + octx.print_array_header = show_stream_entry_header; + octx.print_array_footer = show_stream_entry_footer; + octx.print_object_header = NULL; + octx.print_object_footer = NULL; + + octx.print_integer = show_stream_entry_integer; + octx.print_string = show_stream_entry_string; + av_dict_set(&stream_entries_to_show, arg, "", 0); + return 0; +} + static void opt_input_file(void *optctx, const char *arg) { if (input_filename) { @@ -1023,6 +1077,8 @@ static const OptionDef real_options[] = { "show a particular entry from the format/container info", "entry" }, { "show_packets", OPT_BOOL, {&do_show_packets}, "show packets info" }, { "show_streams", OPT_BOOL, {&do_show_streams}, "show streams info" }, + { "show_stream_entry", HAS_ARG, {.func_arg = opt_show_stream_entry}, + "show a particular entry from all streams", "entry" }, { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {.func_arg = opt_default}, "generic catch all option", "" }, { NULL, }, From b90c8a3d08e3f9ad4de1253376d2d1d93abb8b8c Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Mon, 24 Oct 2016 17:22:55 -0400 Subject: [PATCH 0361/3374] fate: Add tests for mov display matrix Rotation, sample/display aspect ratio and pure matrix export. Signed-off-by: Vittorio Giovara --- tests/Makefile | 1 + tests/fate-run.sh | 4 ++++ tests/fate/mov.mak | 15 +++++++++++++++ tests/ref/fate/mov-dar | 1 + tests/ref/fate/mov-display-matrix | 9 +++++++++ tests/ref/fate/mov-rotation | 1 + tests/ref/fate/mov-sar | 1 + 7 files changed, 32 insertions(+) create mode 100644 tests/fate/mov.mak create mode 100644 tests/ref/fate/mov-dar create mode 100644 tests/ref/fate/mov-display-matrix create mode 100644 tests/ref/fate/mov-rotation create mode 100644 tests/ref/fate/mov-sar diff --git a/tests/Makefile b/tests/Makefile index 36a3a72a9f4d1..0e475a28366f0 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -97,6 +97,7 @@ include $(SRC_PATH)/tests/fate/lossless-audio.mak include $(SRC_PATH)/tests/fate/lossless-video.mak include $(SRC_PATH)/tests/fate/microsoft.mak include $(SRC_PATH)/tests/fate/monkeysaudio.mak +include $(SRC_PATH)/tests/fate/mov.mak include $(SRC_PATH)/tests/fate/mp3.mak include $(SRC_PATH)/tests/fate/mpc.mak include $(SRC_PATH)/tests/fate/mpeg4.mak diff --git a/tests/fate-run.sh b/tests/fate-run.sh index d11ca3c1f7c23..b1b299a055526 100755 --- a/tests/fate-run.sh +++ b/tests/fate-run.sh @@ -76,6 +76,10 @@ probefmt(){ run avprobe -show_format_entry format_name -v 0 "$@" } +probestream(){ + run avprobe -show_stream_entry "$1" -v 0 "$2" +} + avconv(){ dec_opts="-hwaccel $hwaccel -threads $threads -thread_type $thread_type" avconv_args="-nostats -cpuflags $cpuflags" diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak new file mode 100644 index 0000000000000..909e4389d469a --- /dev/null +++ b/tests/fate/mov.mak @@ -0,0 +1,15 @@ +FATE_MOV += fate-mov-dar +fate-mov-dar: CMD = probestream display_aspect_ratio $(TARGET_SAMPLES)/mov/displaymatrix.mov + +FATE_MOV += fate-mov-display-matrix +fate-mov-display-matrix: CMD = probestream matrix $(TARGET_SAMPLES)/mov/displaymatrix.mov + +FATE_MOV += fate-mov-rotation +fate-mov-rotation: CMD = probestream rotation $(TARGET_SAMPLES)/mov/displaymatrix.mov + +FATE_MOV += fate-mov-sar +fate-mov-sar: CMD = probestream sample_aspect_ratio $(TARGET_SAMPLES)/mov/displaymatrix.mov + +$(FATE_MOV): avprobe$(EXESUF) +FATE_SAMPLES-$(call ALLYES, AVPROBE MOV_DEMUXER) += $(FATE_MOV) +fate-mov: $(FATE_MOV) diff --git a/tests/ref/fate/mov-dar b/tests/ref/fate/mov-dar new file mode 100644 index 0000000000000..38a0ac45f807b --- /dev/null +++ b/tests/ref/fate/mov-dar @@ -0,0 +1 @@ +3:1 diff --git a/tests/ref/fate/mov-display-matrix b/tests/ref/fate/mov-display-matrix new file mode 100644 index 0000000000000..64c95996a64ef --- /dev/null +++ b/tests/ref/fate/mov-display-matrix @@ -0,0 +1,9 @@ +0 +65536 +0 +-65536 +0 +0 +47185920 +0 +1073741824 diff --git a/tests/ref/fate/mov-rotation b/tests/ref/fate/mov-rotation new file mode 100644 index 0000000000000..64ded27fb26e5 --- /dev/null +++ b/tests/ref/fate/mov-rotation @@ -0,0 +1 @@ +-90 diff --git a/tests/ref/fate/mov-sar b/tests/ref/fate/mov-sar new file mode 100644 index 0000000000000..9f303fc9cb923 --- /dev/null +++ b/tests/ref/fate/mov-sar @@ -0,0 +1 @@ +9:2 From ecd2ec69ce10e13f6ede353d2def7ce9f45c1a7d Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Mon, 24 Oct 2016 17:46:47 -0400 Subject: [PATCH 0362/3374] mov: Evaluate the movie display matrix This matrix needs to be applied after all others have (currently only display matrix from trak), but cannot be handled in movie box, since streams are not allocated yet. So store it in main context, and apply it when appropriate, that is after parsing the tkhd one. Fate tests are updated accordingly. Signed-off-by: Vittorio Giovara --- libavformat/isom.h | 2 ++ libavformat/mov.c | 49 ++++++++++++++++++++++--------- tests/ref/fate/mov-dar | 2 +- tests/ref/fate/mov-display-matrix | 2 +- tests/ref/fate/mov-sar | 2 +- 5 files changed, 40 insertions(+), 17 deletions(-) diff --git a/libavformat/isom.h b/libavformat/isom.h index 58f0a2006213a..1aa20910430da 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -167,6 +167,8 @@ typedef struct MOVContext { int export_all; int export_xmp; int enable_drefs; + + int32_t movie_display_matrix[3][3]; ///< display matrix from mvhd } MOVContext; int ff_mp4_read_descr_len(AVIOContext *pb); diff --git a/libavformat/mov.c b/libavformat/mov.c index 5a46f9440ad40..194daebc6e6a0 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -950,6 +950,7 @@ static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) { + int i; time_t creation_time; int version = avio_r8(pb); /* version */ avio_rb24(pb); /* flags */ @@ -973,7 +974,12 @@ static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) avio_skip(pb, 10); /* reserved */ - avio_skip(pb, 36); /* display matrix */ + /* movie display matrix, store it in main context and use it later on */ + for (i = 0; i < 3; i++) { + c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point + c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point + c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point + } avio_rb32(pb); /* preview time */ avio_rb32(pb); /* preview duration */ @@ -2748,13 +2754,23 @@ static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; } +// return 1 when matrix is identity, 0 otherwise +#define IS_MATRIX_IDENT(matrix) \ + ( (matrix)[0][0] == (1 << 16) && \ + (matrix)[1][1] == (1 << 16) && \ + (matrix)[2][2] == (1 << 30) && \ + !(matrix)[0][1] && !(matrix)[0][2] || \ + !(matrix)[1][0] && !(matrix)[1][2] || \ + !(matrix)[2][0] && !(matrix)[2][1]) + static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) { - int i; + int i, j, e; int width; int height; int64_t disp_transform[2]; int display_matrix[3][3]; + int res_display_matrix[3][3] = { { 0 } }; AVStream *st; MOVStreamContext *sc; int version; @@ -2804,15 +2820,20 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) sc->width = width >> 16; sc->height = height >> 16; - // save the matrix when it is not the default identity - if (display_matrix[0][0] != (1 << 16) || - display_matrix[1][1] != (1 << 16) || - display_matrix[2][2] != (1 << 30) || - display_matrix[0][1] || display_matrix[0][2] || - display_matrix[1][0] || display_matrix[1][2] || - display_matrix[2][0] || display_matrix[2][1]) { - int i, j; + // apply the moov display matrix (after the tkhd one) + for (i = 0; i < 3; i++) { + const int sh[3] = { 16, 16, 30 }; + for (j = 0; j < 3; j++) { + for (e = 0; e < 3; e++) { + res_display_matrix[i][j] += + ((int64_t) display_matrix[i][e] * + c->movie_display_matrix[e][j]) >> sh[e]; + } + } + } + // save the matrix when it is not the default identity + if (!IS_MATRIX_IDENT(res_display_matrix)) { av_freep(&sc->display_matrix); sc->display_matrix = av_malloc(sizeof(int32_t) * 9); if (!sc->display_matrix) @@ -2820,7 +2841,7 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) - sc->display_matrix[i * 3 + j] = display_matrix[i][j]; + sc->display_matrix[i * 3 + j] = res_display_matrix[i][j]; } // transform the display width/height according to the matrix @@ -2829,9 +2850,9 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (width && height && sc->display_matrix) { for (i = 0; i < 2; i++) disp_transform[i] = - (int64_t) width * display_matrix[0][i] + - (int64_t) height * display_matrix[1][i] + - ((int64_t) display_matrix[2][i] << 16); + (int64_t) width * sc->display_matrix[0 + i] + + (int64_t) height * sc->display_matrix[3 + i] + + ((int64_t) sc->display_matrix[6 + i] << 16); //sample aspect ratio is new width/height divided by old width/height if (disp_transform[0] > 0 && disp_transform[1] > 0) diff --git a/tests/ref/fate/mov-dar b/tests/ref/fate/mov-dar index 38a0ac45f807b..9ca9a41bbcc85 100644 --- a/tests/ref/fate/mov-dar +++ b/tests/ref/fate/mov-dar @@ -1 +1 @@ -3:1 +3:2 diff --git a/tests/ref/fate/mov-display-matrix b/tests/ref/fate/mov-display-matrix index 64c95996a64ef..6498148147730 100644 --- a/tests/ref/fate/mov-display-matrix +++ b/tests/ref/fate/mov-display-matrix @@ -1,5 +1,5 @@ 0 -65536 +131072 0 -65536 0 diff --git a/tests/ref/fate/mov-sar b/tests/ref/fate/mov-sar index 9f303fc9cb923..291b047df496c 100644 --- a/tests/ref/fate/mov-sar +++ b/tests/ref/fate/mov-sar @@ -1 +1 @@ -9:2 +9:4 From 064f19f39e2f17927278c6ad8fe884a5b92310d6 Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 28 Oct 2016 21:44:51 -0300 Subject: [PATCH 0363/3374] avconv: support parsing bitstream filter options Example usage: avconv -i INPUT -bsf filter[=opt1=val1:opt2=val2] OUTPUT Signed-off-by: James Almer Signed-off-by: Anton Khirnov --- avconv.c | 15 ++------------- avconv.h | 1 - avconv_opt.c | 46 +++++++++++++++++++++++++++++++++++++--------- 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/avconv.c b/avconv.c index 0b75cbe21498f..4bd28e6e3b419 100644 --- a/avconv.c +++ b/avconv.c @@ -190,7 +190,6 @@ static void avconv_cleanup(int ret) for (j = 0; j < ost->nb_bitstream_filters; j++) av_bsf_free(&ost->bsf_ctx[j]); av_freep(&ost->bsf_ctx); - av_freep(&ost->bitstream_filters); av_frame_free(&ost->filtered_frame); @@ -1798,17 +1797,8 @@ static int init_output_bsfs(OutputStream *ost) if (!ost->nb_bitstream_filters) return 0; - ost->bsf_ctx = av_mallocz_array(ost->nb_bitstream_filters, sizeof(*ost->bsf_ctx)); - if (!ost->bsf_ctx) - return AVERROR(ENOMEM); - for (i = 0; i < ost->nb_bitstream_filters; i++) { - ret = av_bsf_alloc(ost->bitstream_filters[i], &ctx); - if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error allocating a bitstream filter context\n"); - return ret; - } - ost->bsf_ctx[i] = ctx; + ctx = ost->bsf_ctx[i]; ret = avcodec_parameters_copy(ctx->par_in, i ? ost->bsf_ctx[i - 1]->par_out : ost->st->codecpar); @@ -1820,12 +1810,11 @@ static int init_output_bsfs(OutputStream *ost) ret = av_bsf_init(ctx); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Error initializing bitstream filter: %s\n", - ost->bitstream_filters[i]->name); + ctx->filter->name); return ret; } } - ctx = ost->bsf_ctx[ost->nb_bitstream_filters - 1]; ret = avcodec_parameters_copy(ost->st->codecpar, ctx->par_out); if (ret < 0) return ret; diff --git a/avconv.h b/avconv.h index fcdf3d04613e2..6360f76c0bb5d 100644 --- a/avconv.h +++ b/avconv.h @@ -360,7 +360,6 @@ typedef struct OutputStream { AVRational mux_timebase; int nb_bitstream_filters; - const AVBitStreamFilter **bitstream_filters; AVBSFContext **bsf_ctx; AVCodecContext *enc_ctx; diff --git a/avconv_opt.c b/avconv_opt.c index 362a5b7f5e9b4..ba37a3a31d681 100644 --- a/avconv_opt.c +++ b/avconv_opt.c @@ -1025,26 +1025,54 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e MATCH_PER_STREAM_OPT(bitstream_filters, str, bsfs, oc, st); while (bsfs && *bsfs) { const AVBitStreamFilter *filter; - char *bsf; + const char *bsf, *bsf_options_str, *bsf_name; + AVDictionary *bsf_options = NULL; - bsf = av_get_token(&bsfs, ","); + bsf = bsf_options_str = av_get_token(&bsfs, ","); if (!bsf) exit_program(1); + bsf_name = av_get_token(&bsf_options_str, "="); + if (!bsf_name) + exit_program(1); - filter = av_bsf_get_by_name(bsf); + filter = av_bsf_get_by_name(bsf_name); if (!filter) { - av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf); + av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf_name); exit_program(1); } + if (*bsf_options_str++) { + ret = av_dict_parse_string(&bsf_options, bsf_options_str, "=", ":", 0); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error parsing options for bitstream filter %s\n", bsf_name); + exit_program(1); + } + } av_freep(&bsf); - ost->bitstream_filters = av_realloc_array(ost->bitstream_filters, - ost->nb_bitstream_filters + 1, - sizeof(*ost->bitstream_filters)); - if (!ost->bitstream_filters) + ost->bsf_ctx = av_realloc_array(ost->bsf_ctx, + ost->nb_bitstream_filters + 1, + sizeof(*ost->bsf_ctx)); + if (!ost->bsf_ctx) + exit_program(1); + + ret = av_bsf_alloc(filter, &ost->bsf_ctx[ost->nb_bitstream_filters]); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error allocating a bistream filter context\n"); exit_program(1); + } + ost->nb_bitstream_filters++; + + if (bsf_options) { + ret = av_opt_set_dict(ost->bsf_ctx[ost->nb_bitstream_filters-1]->priv_data, &bsf_options); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error setting options for bitstream filter %s\n", bsf_name); + exit_program(1); + } + assert_avoptions(bsf_options); + av_dict_free(&bsf_options); + } + av_freep(&bsf_name); - ost->bitstream_filters[ost->nb_bitstream_filters++] = filter; if (*bsfs) bsfs++; } From 40aaa8dadfd1c69ff4460d04750e1403b5535a6d Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 19 Oct 2016 21:05:22 +0200 Subject: [PATCH 0364/3374] examples/avcodec: split audio encoding into a separate example The four examples (audio/video encoding/decoding) are completely independent so it makes little sense to have them all in one file. --- configure | 2 + doc/Makefile | 3 +- doc/examples/avcodec.c | 170 ----------------------------- doc/examples/encode_audio.c | 211 ++++++++++++++++++++++++++++++++++++ 4 files changed, 215 insertions(+), 171 deletions(-) create mode 100644 doc/examples/encode_audio.c diff --git a/configure b/configure index 8c2b4fdfa94c3..28567bb7dfc3c 100755 --- a/configure +++ b/configure @@ -1210,6 +1210,7 @@ COMPONENT_LIST=" EXAMPLE_LIST=" avcodec_example + encode_audio_example filter_audio_example metadata_example output_example @@ -2435,6 +2436,7 @@ scale_vaapi_filter_deps="vaapi VAProcPipelineParameterBuffer" # examples avcodec_example_deps="avcodec avutil" +encode_audio_example_deps="avcodec avutil" filter_audio_example_deps="avfilter avutil" metadata_example_deps="avformat avutil" output_example_deps="avcodec avformat avutil swscale" diff --git a/doc/Makefile b/doc/Makefile index c464a4869e43d..738e601109e2b 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -17,12 +17,13 @@ DOCS-$(CONFIG_TEXI2HTML) += $(HTMLPAGES) DOCS = $(DOCS-yes) DOC_EXAMPLES-$(CONFIG_AVCODEC_EXAMPLE) += avcodec +DOC_EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE) += encode_audio DOC_EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE) += filter_audio DOC_EXAMPLES-$(CONFIG_METADATA_EXAMPLE) += metadata DOC_EXAMPLES-$(CONFIG_OUTPUT_EXAMPLE) += output DOC_EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE) += qsvdec DOC_EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac -ALL_DOC_EXAMPLES = avcodec filter_audio metadata output transcode_aac +ALL_DOC_EXAMPLES = avcodec encode_audio filter_audio metadata output transcode_aac DOC_EXAMPLES := $(DOC_EXAMPLES-yes:%=doc/examples/%$(EXESUF)) ALL_DOC_EXAMPLES := $(ALL_DOC_EXAMPLES:%=doc/examples/%$(EXESUF)) diff --git a/doc/examples/avcodec.c b/doc/examples/avcodec.c index 8fee5526dfae2..63812d99c3824 100644 --- a/doc/examples/avcodec.c +++ b/doc/examples/avcodec.c @@ -47,175 +47,6 @@ #define AUDIO_INBUF_SIZE 20480 #define AUDIO_REFILL_THRESH 4096 -/* check that a given sample format is supported by the encoder */ -static int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt) -{ - const enum AVSampleFormat *p = codec->sample_fmts; - - while (*p != AV_SAMPLE_FMT_NONE) { - if (*p == sample_fmt) - return 1; - p++; - } - return 0; -} - -/* just pick the highest supported samplerate */ -static int select_sample_rate(AVCodec *codec) -{ - const int *p; - int best_samplerate = 0; - - if (!codec->supported_samplerates) - return 44100; - - p = codec->supported_samplerates; - while (*p) { - best_samplerate = FFMAX(*p, best_samplerate); - p++; - } - return best_samplerate; -} - -/* select layout with the highest channel count */ -static int select_channel_layout(AVCodec *codec) -{ - const uint64_t *p; - uint64_t best_ch_layout = 0; - int best_nb_channels = 0; - - if (!codec->channel_layouts) - return AV_CH_LAYOUT_STEREO; - - p = codec->channel_layouts; - while (*p) { - int nb_channels = av_get_channel_layout_nb_channels(*p); - - if (nb_channels > best_nb_channels) { - best_ch_layout = *p; - best_nb_channels = nb_channels; - } - p++; - } - return best_ch_layout; -} - -/* - * Audio encoding example - */ -static void audio_encode_example(const char *filename) -{ - AVCodec *codec; - AVCodecContext *c= NULL; - AVFrame *frame; - AVPacket pkt; - int i, j, k, ret, got_output; - int buffer_size; - FILE *f; - uint16_t *samples; - float t, tincr; - - printf("Audio encoding\n"); - - /* find the MP2 encoder */ - codec = avcodec_find_encoder(AV_CODEC_ID_MP2); - if (!codec) { - fprintf(stderr, "codec not found\n"); - exit(1); - } - - c = avcodec_alloc_context3(codec); - - /* put sample parameters */ - c->bit_rate = 64000; - - /* check that the encoder supports s16 pcm input */ - c->sample_fmt = AV_SAMPLE_FMT_S16; - if (!check_sample_fmt(codec, c->sample_fmt)) { - fprintf(stderr, "encoder does not support %s", - av_get_sample_fmt_name(c->sample_fmt)); - exit(1); - } - - /* select other audio parameters supported by the encoder */ - c->sample_rate = select_sample_rate(codec); - c->channel_layout = select_channel_layout(codec); - c->channels = av_get_channel_layout_nb_channels(c->channel_layout); - - /* open it */ - if (avcodec_open2(c, codec, NULL) < 0) { - fprintf(stderr, "could not open codec\n"); - exit(1); - } - - f = fopen(filename, "wb"); - if (!f) { - fprintf(stderr, "could not open %s\n", filename); - exit(1); - } - - /* frame containing input raw audio */ - frame = av_frame_alloc(); - if (!frame) { - fprintf(stderr, "could not allocate audio frame\n"); - exit(1); - } - - frame->nb_samples = c->frame_size; - frame->format = c->sample_fmt; - frame->channel_layout = c->channel_layout; - - /* the codec gives us the frame size, in samples, - * we calculate the size of the samples buffer in bytes */ - buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size, - c->sample_fmt, 0); - samples = av_malloc(buffer_size); - if (!samples) { - fprintf(stderr, "could not allocate %d bytes for samples buffer\n", - buffer_size); - exit(1); - } - /* setup the data pointers in the AVFrame */ - ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt, - (const uint8_t*)samples, buffer_size, 0); - if (ret < 0) { - fprintf(stderr, "could not setup audio frame\n"); - exit(1); - } - - /* encode a single tone sound */ - t = 0; - tincr = 2 * M_PI * 440.0 / c->sample_rate; - for(i=0;i<200;i++) { - av_init_packet(&pkt); - pkt.data = NULL; // packet data will be allocated by the encoder - pkt.size = 0; - - for (j = 0; j < c->frame_size; j++) { - samples[2*j] = (int)(sin(t) * 10000); - - for (k = 1; k < c->channels; k++) - samples[2*j + k] = samples[2*j]; - t += tincr; - } - /* encode the samples */ - ret = avcodec_encode_audio2(c, &pkt, frame, &got_output); - if (ret < 0) { - fprintf(stderr, "error encoding audio frame\n"); - exit(1); - } - if (got_output) { - fwrite(pkt.data, 1, pkt.size, f); - av_packet_unref(&pkt); - } - } - fclose(f); - - av_freep(&samples); - av_frame_free(&frame); - avcodec_free_context(&c); -} - /* * Audio decoding. */ @@ -575,7 +406,6 @@ int main(int argc, char **argv) avcodec_register_all(); if (argc <= 1) { - audio_encode_example("/tmp/test.mp2"); audio_decode_example("/tmp/test.sw", "/tmp/test.mp2"); video_encode_example("/tmp/test.mpg"); diff --git a/doc/examples/encode_audio.c b/doc/examples/encode_audio.c new file mode 100644 index 0000000000000..cabe5893b040b --- /dev/null +++ b/doc/examples/encode_audio.c @@ -0,0 +1,211 @@ +/* + * copyright (c) 2001 Fabrice Bellard + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * audio encoding with libavcodec API example. + * + * @example encode_audio.c + */ + +#include +#include +#include + +#include "libavcodec/avcodec.h" + +#include "libavutil/channel_layout.h" +#include "libavutil/common.h" +#include "libavutil/frame.h" +#include "libavutil/samplefmt.h" + +/* check that a given sample format is supported by the encoder */ +static int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt) +{ + const enum AVSampleFormat *p = codec->sample_fmts; + + while (*p != AV_SAMPLE_FMT_NONE) { + if (*p == sample_fmt) + return 1; + p++; + } + return 0; +} + +/* just pick the highest supported samplerate */ +static int select_sample_rate(AVCodec *codec) +{ + const int *p; + int best_samplerate = 0; + + if (!codec->supported_samplerates) + return 44100; + + p = codec->supported_samplerates; + while (*p) { + best_samplerate = FFMAX(*p, best_samplerate); + p++; + } + return best_samplerate; +} + +/* select layout with the highest channel count */ +static int select_channel_layout(AVCodec *codec) +{ + const uint64_t *p; + uint64_t best_ch_layout = 0; + int best_nb_channels = 0; + + if (!codec->channel_layouts) + return AV_CH_LAYOUT_STEREO; + + p = codec->channel_layouts; + while (*p) { + int nb_channels = av_get_channel_layout_nb_channels(*p); + + if (nb_channels > best_nb_channels) { + best_ch_layout = *p; + best_nb_channels = nb_channels; + } + p++; + } + return best_ch_layout; +} + +int main(int argc, char **argv) +{ + const char *filename; + AVCodec *codec; + AVCodecContext *c= NULL; + AVFrame *frame; + AVPacket pkt; + int i, j, k, ret, got_output; + int buffer_size; + FILE *f; + uint16_t *samples; + float t, tincr; + + if (argc <= 1) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 0; + } + filename = argv[1]; + + /* register all the codecs */ + avcodec_register_all(); + + /* find the MP2 encoder */ + codec = avcodec_find_encoder(AV_CODEC_ID_MP2); + if (!codec) { + fprintf(stderr, "codec not found\n"); + exit(1); + } + + c = avcodec_alloc_context3(codec); + + /* put sample parameters */ + c->bit_rate = 64000; + + /* check that the encoder supports s16 pcm input */ + c->sample_fmt = AV_SAMPLE_FMT_S16; + if (!check_sample_fmt(codec, c->sample_fmt)) { + fprintf(stderr, "encoder does not support %s", + av_get_sample_fmt_name(c->sample_fmt)); + exit(1); + } + + /* select other audio parameters supported by the encoder */ + c->sample_rate = select_sample_rate(codec); + c->channel_layout = select_channel_layout(codec); + c->channels = av_get_channel_layout_nb_channels(c->channel_layout); + + /* open it */ + if (avcodec_open2(c, codec, NULL) < 0) { + fprintf(stderr, "could not open codec\n"); + exit(1); + } + + f = fopen(filename, "wb"); + if (!f) { + fprintf(stderr, "could not open %s\n", filename); + exit(1); + } + + /* frame containing input raw audio */ + frame = av_frame_alloc(); + if (!frame) { + fprintf(stderr, "could not allocate audio frame\n"); + exit(1); + } + + frame->nb_samples = c->frame_size; + frame->format = c->sample_fmt; + frame->channel_layout = c->channel_layout; + + /* the codec gives us the frame size, in samples, + * we calculate the size of the samples buffer in bytes */ + buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size, + c->sample_fmt, 0); + samples = av_malloc(buffer_size); + if (!samples) { + fprintf(stderr, "could not allocate %d bytes for samples buffer\n", + buffer_size); + exit(1); + } + /* setup the data pointers in the AVFrame */ + ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt, + (const uint8_t*)samples, buffer_size, 0); + if (ret < 0) { + fprintf(stderr, "could not setup audio frame\n"); + exit(1); + } + + /* encode a single tone sound */ + t = 0; + tincr = 2 * M_PI * 440.0 / c->sample_rate; + for(i=0;i<200;i++) { + av_init_packet(&pkt); + pkt.data = NULL; // packet data will be allocated by the encoder + pkt.size = 0; + + for (j = 0; j < c->frame_size; j++) { + samples[2*j] = (int)(sin(t) * 10000); + + for (k = 1; k < c->channels; k++) + samples[2*j + k] = samples[2*j]; + t += tincr; + } + /* encode the samples */ + ret = avcodec_encode_audio2(c, &pkt, frame, &got_output); + if (ret < 0) { + fprintf(stderr, "error encoding audio frame\n"); + exit(1); + } + if (got_output) { + fwrite(pkt.data, 1, pkt.size, f); + av_packet_unref(&pkt); + } + } + fclose(f); + + av_freep(&samples); + av_frame_free(&frame); + avcodec_free_context(&c); +} From c00a11ab383ff276a2ab2fdba577945e48d465be Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 19 Oct 2016 21:07:43 +0200 Subject: [PATCH 0365/3374] examples/encode_audio: constify AVCodec instances --- doc/examples/encode_audio.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/examples/encode_audio.c b/doc/examples/encode_audio.c index cabe5893b040b..a8e0cd04e7028 100644 --- a/doc/examples/encode_audio.c +++ b/doc/examples/encode_audio.c @@ -37,7 +37,7 @@ #include "libavutil/samplefmt.h" /* check that a given sample format is supported by the encoder */ -static int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt) +static int check_sample_fmt(const AVCodec *codec, enum AVSampleFormat sample_fmt) { const enum AVSampleFormat *p = codec->sample_fmts; @@ -50,7 +50,7 @@ static int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt) } /* just pick the highest supported samplerate */ -static int select_sample_rate(AVCodec *codec) +static int select_sample_rate(const AVCodec *codec) { const int *p; int best_samplerate = 0; @@ -67,7 +67,7 @@ static int select_sample_rate(AVCodec *codec) } /* select layout with the highest channel count */ -static int select_channel_layout(AVCodec *codec) +static int select_channel_layout(const AVCodec *codec) { const uint64_t *p; uint64_t best_ch_layout = 0; @@ -92,7 +92,7 @@ static int select_channel_layout(AVCodec *codec) int main(int argc, char **argv) { const char *filename; - AVCodec *codec; + const AVCodec *codec; AVCodecContext *c= NULL; AVFrame *frame; AVPacket pkt; From f76698e759a08e8d3b629c06edb0439f474e7fee Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 19 Oct 2016 21:21:08 +0200 Subject: [PATCH 0366/3374] examples/encode_audio: use the AVFrame API for allocating the data It is simpler and more efficient. --- doc/examples/encode_audio.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/doc/examples/encode_audio.c b/doc/examples/encode_audio.c index a8e0cd04e7028..db2440f8fa85e 100644 --- a/doc/examples/encode_audio.c +++ b/doc/examples/encode_audio.c @@ -97,7 +97,6 @@ int main(int argc, char **argv) AVFrame *frame; AVPacket pkt; int i, j, k, ret, got_output; - int buffer_size; FILE *f; uint16_t *samples; float t, tincr; @@ -159,21 +158,10 @@ int main(int argc, char **argv) frame->format = c->sample_fmt; frame->channel_layout = c->channel_layout; - /* the codec gives us the frame size, in samples, - * we calculate the size of the samples buffer in bytes */ - buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size, - c->sample_fmt, 0); - samples = av_malloc(buffer_size); - if (!samples) { - fprintf(stderr, "could not allocate %d bytes for samples buffer\n", - buffer_size); - exit(1); - } - /* setup the data pointers in the AVFrame */ - ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt, - (const uint8_t*)samples, buffer_size, 0); + /* allocate the data buffers */ + ret = av_frame_get_buffer(frame, 0); if (ret < 0) { - fprintf(stderr, "could not setup audio frame\n"); + fprintf(stderr, "could not allocate audio data buffers\n"); exit(1); } @@ -185,6 +173,13 @@ int main(int argc, char **argv) pkt.data = NULL; // packet data will be allocated by the encoder pkt.size = 0; + /* make sure the frame is writable -- makes a copy if the encoder + * kept a reference internally */ + ret = av_frame_make_writable(frame); + if (ret < 0) + exit(1); + samples = (uint16_t*)frame->data[0]; + for (j = 0; j < c->frame_size; j++) { samples[2*j] = (int)(sin(t) * 10000); @@ -205,7 +200,6 @@ int main(int argc, char **argv) } fclose(f); - av_freep(&samples); av_frame_free(&frame); avcodec_free_context(&c); } From f5df897c4b61985e3afc89ba1290649712ff438e Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 19 Oct 2016 21:05:22 +0200 Subject: [PATCH 0367/3374] examples/avcodec: split audio decoding into a separate example The four examples (audio/video encoding/decoding) are completely independent so it makes little sense to have them all in one file. --- configure | 2 + doc/Makefile | 4 +- doc/examples/avcodec.c | 97 ------------------------- doc/examples/decode_audio.c | 137 ++++++++++++++++++++++++++++++++++++ 4 files changed, 142 insertions(+), 98 deletions(-) create mode 100644 doc/examples/decode_audio.c diff --git a/configure b/configure index 28567bb7dfc3c..b19e3e13a7358 100755 --- a/configure +++ b/configure @@ -1210,6 +1210,7 @@ COMPONENT_LIST=" EXAMPLE_LIST=" avcodec_example + decode_audio_example encode_audio_example filter_audio_example metadata_example @@ -2436,6 +2437,7 @@ scale_vaapi_filter_deps="vaapi VAProcPipelineParameterBuffer" # examples avcodec_example_deps="avcodec avutil" +decode_audio_example_deps="avcodec avutil" encode_audio_example_deps="avcodec avutil" filter_audio_example_deps="avfilter avutil" metadata_example_deps="avformat avutil" diff --git a/doc/Makefile b/doc/Makefile index 738e601109e2b..326bb120b97f2 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -17,13 +17,15 @@ DOCS-$(CONFIG_TEXI2HTML) += $(HTMLPAGES) DOCS = $(DOCS-yes) DOC_EXAMPLES-$(CONFIG_AVCODEC_EXAMPLE) += avcodec +DOC_EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE) += decode_audio DOC_EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE) += encode_audio DOC_EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE) += filter_audio DOC_EXAMPLES-$(CONFIG_METADATA_EXAMPLE) += metadata DOC_EXAMPLES-$(CONFIG_OUTPUT_EXAMPLE) += output DOC_EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE) += qsvdec DOC_EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac -ALL_DOC_EXAMPLES = avcodec encode_audio filter_audio metadata output transcode_aac +ALL_DOC_EXAMPLES = avcodec decode_audio encode_audio filter_audio metadata \ + output transcode_aac DOC_EXAMPLES := $(DOC_EXAMPLES-yes:%=doc/examples/%$(EXESUF)) ALL_DOC_EXAMPLES := $(ALL_DOC_EXAMPLES:%=doc/examples/%$(EXESUF)) diff --git a/doc/examples/avcodec.c b/doc/examples/avcodec.c index 63812d99c3824..4f7dc8b28ad06 100644 --- a/doc/examples/avcodec.c +++ b/doc/examples/avcodec.c @@ -44,100 +44,6 @@ #include "libavutil/samplefmt.h" #define INBUF_SIZE 4096 -#define AUDIO_INBUF_SIZE 20480 -#define AUDIO_REFILL_THRESH 4096 - -/* - * Audio decoding. - */ -static void audio_decode_example(const char *outfilename, const char *filename) -{ - AVCodec *codec; - AVCodecContext *c= NULL; - int len; - FILE *f, *outfile; - uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; - AVPacket avpkt; - AVFrame *decoded_frame = NULL; - - av_init_packet(&avpkt); - - printf("Audio decoding\n"); - - /* find the MPEG audio decoder */ - codec = avcodec_find_decoder(AV_CODEC_ID_MP2); - if (!codec) { - fprintf(stderr, "codec not found\n"); - exit(1); - } - - c = avcodec_alloc_context3(codec); - - /* open it */ - if (avcodec_open2(c, codec, NULL) < 0) { - fprintf(stderr, "could not open codec\n"); - exit(1); - } - - f = fopen(filename, "rb"); - if (!f) { - fprintf(stderr, "could not open %s\n", filename); - exit(1); - } - outfile = fopen(outfilename, "wb"); - if (!outfile) { - av_free(c); - exit(1); - } - - /* decode until eof */ - avpkt.data = inbuf; - avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f); - - while (avpkt.size > 0) { - int got_frame = 0; - - if (!decoded_frame) { - if (!(decoded_frame = av_frame_alloc())) { - fprintf(stderr, "out of memory\n"); - exit(1); - } - } - - len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt); - if (len < 0) { - fprintf(stderr, "Error while decoding\n"); - exit(1); - } - if (got_frame) { - /* if a frame has been decoded, output it */ - int data_size = av_samples_get_buffer_size(NULL, c->channels, - decoded_frame->nb_samples, - c->sample_fmt, 1); - fwrite(decoded_frame->data[0], 1, data_size, outfile); - } - avpkt.size -= len; - avpkt.data += len; - if (avpkt.size < AUDIO_REFILL_THRESH) { - /* Refill the input buffer, to avoid trying to decode - * incomplete frames. Instead of this, one could also use - * a parser, or use a proper container format through - * libavformat. */ - memmove(inbuf, avpkt.data, avpkt.size); - avpkt.data = inbuf; - len = fread(avpkt.data + avpkt.size, 1, - AUDIO_INBUF_SIZE - avpkt.size, f); - if (len > 0) - avpkt.size += len; - } - } - - fclose(outfile); - fclose(f); - - avcodec_free_context(&c); - av_frame_free(&decoded_frame); -} /* * Video encoding example @@ -406,15 +312,12 @@ int main(int argc, char **argv) avcodec_register_all(); if (argc <= 1) { - audio_decode_example("/tmp/test.sw", "/tmp/test.mp2"); - video_encode_example("/tmp/test.mpg"); filename = "/tmp/test.mpg"; } else { filename = argv[1]; } - // audio_decode_example("/tmp/test.sw", filename); video_decode_example("/tmp/test%d.pgm", filename); return 0; diff --git a/doc/examples/decode_audio.c b/doc/examples/decode_audio.c new file mode 100644 index 0000000000000..4378281dbd3ae --- /dev/null +++ b/doc/examples/decode_audio.c @@ -0,0 +1,137 @@ +/* + * copyright (c) 2001 Fabrice Bellard + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * audio decoding with libavcodec API example + * + * @example decode_audio.c + */ + +#include +#include +#include + +#include "libavcodec/avcodec.h" + +#include "libavutil/frame.h" + +#define AUDIO_INBUF_SIZE 20480 +#define AUDIO_REFILL_THRESH 4096 + +int main(int argc, char **argv) +{ + const char *outfilename, *filename; + AVCodec *codec; + AVCodecContext *c= NULL; + int len; + FILE *f, *outfile; + uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; + AVPacket avpkt; + AVFrame *decoded_frame = NULL; + + if (argc <= 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(0); + } + filename = argv[1]; + outfilename = argv[2]; + + /* register all the codecs */ + avcodec_register_all(); + + av_init_packet(&avpkt); + + /* find the MPEG audio decoder */ + codec = avcodec_find_decoder(AV_CODEC_ID_MP2); + if (!codec) { + fprintf(stderr, "codec not found\n"); + exit(1); + } + + c = avcodec_alloc_context3(codec); + + /* open it */ + if (avcodec_open2(c, codec, NULL) < 0) { + fprintf(stderr, "could not open codec\n"); + exit(1); + } + + f = fopen(filename, "rb"); + if (!f) { + fprintf(stderr, "could not open %s\n", filename); + exit(1); + } + outfile = fopen(outfilename, "wb"); + if (!outfile) { + av_free(c); + exit(1); + } + + /* decode until eof */ + avpkt.data = inbuf; + avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f); + + while (avpkt.size > 0) { + int got_frame = 0; + + if (!decoded_frame) { + if (!(decoded_frame = av_frame_alloc())) { + fprintf(stderr, "out of memory\n"); + exit(1); + } + } + + len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt); + if (len < 0) { + fprintf(stderr, "Error while decoding\n"); + exit(1); + } + if (got_frame) { + /* if a frame has been decoded, output it */ + int data_size = av_samples_get_buffer_size(NULL, c->channels, + decoded_frame->nb_samples, + c->sample_fmt, 1); + fwrite(decoded_frame->data[0], 1, data_size, outfile); + } + avpkt.size -= len; + avpkt.data += len; + if (avpkt.size < AUDIO_REFILL_THRESH) { + /* Refill the input buffer, to avoid trying to decode + * incomplete frames. Instead of this, one could also use + * a parser, or use a proper container format through + * libavformat. */ + memmove(inbuf, avpkt.data, avpkt.size); + avpkt.data = inbuf; + len = fread(avpkt.data + avpkt.size, 1, + AUDIO_INBUF_SIZE - avpkt.size, f); + if (len > 0) + avpkt.size += len; + } + } + + fclose(outfile); + fclose(f); + + avcodec_free_context(&c); + av_frame_free(&decoded_frame); + + return 0; +} From 90265814f993098d79b0a0f40745ecdb403fbf56 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 19 Oct 2016 21:56:22 +0200 Subject: [PATCH 0368/3374] examples/decode_audio: constify the AVCodec instance --- doc/examples/decode_audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/examples/decode_audio.c b/doc/examples/decode_audio.c index 4378281dbd3ae..647893c91f5fc 100644 --- a/doc/examples/decode_audio.c +++ b/doc/examples/decode_audio.c @@ -39,7 +39,7 @@ int main(int argc, char **argv) { const char *outfilename, *filename; - AVCodec *codec; + const AVCodec *codec; AVCodecContext *c= NULL; int len; FILE *f, *outfile; From 7b1f03477f1a43d2261fbd83e50a4ad90c7f806d Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 19 Oct 2016 21:05:22 +0200 Subject: [PATCH 0369/3374] examples/avcodec: split the remaining two examples into separate files --- configure | 6 +- doc/Makefile | 12 +- doc/examples/{avcodec.c => decode_video.c} | 176 ++------------------- doc/examples/encode_video.c | 164 +++++++++++++++++++ 4 files changed, 192 insertions(+), 166 deletions(-) rename doc/examples/{avcodec.c => decode_video.c} (55%) create mode 100644 doc/examples/encode_video.c diff --git a/configure b/configure index b19e3e13a7358..9264bb5a0ef23 100755 --- a/configure +++ b/configure @@ -1209,9 +1209,10 @@ COMPONENT_LIST=" " EXAMPLE_LIST=" - avcodec_example decode_audio_example + decode_video_example encode_audio_example + encode_video_example filter_audio_example metadata_example output_example @@ -2436,9 +2437,10 @@ scale_qsv_filter_deps="libmfx" scale_vaapi_filter_deps="vaapi VAProcPipelineParameterBuffer" # examples -avcodec_example_deps="avcodec avutil" decode_audio_example_deps="avcodec avutil" +decode_video_example_deps="avcodec avutil" encode_audio_example_deps="avcodec avutil" +encode_video_example_deps="avcodec avutil" filter_audio_example_deps="avfilter avutil" metadata_example_deps="avformat avutil" output_example_deps="avcodec avformat avutil swscale" diff --git a/doc/Makefile b/doc/Makefile index 326bb120b97f2..bda815307c035 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -16,16 +16,22 @@ DOCS-$(CONFIG_POD2MAN) += $(MANPAGES) $(PODPAGES) DOCS-$(CONFIG_TEXI2HTML) += $(HTMLPAGES) DOCS = $(DOCS-yes) -DOC_EXAMPLES-$(CONFIG_AVCODEC_EXAMPLE) += avcodec DOC_EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE) += decode_audio +DOC_EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE) += decode_video DOC_EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE) += encode_audio +DOC_EXAMPLES-$(CONFIG_ENCODE_VIDEO_EXAMPLE) += encode_video DOC_EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE) += filter_audio DOC_EXAMPLES-$(CONFIG_METADATA_EXAMPLE) += metadata DOC_EXAMPLES-$(CONFIG_OUTPUT_EXAMPLE) += output DOC_EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE) += qsvdec DOC_EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac -ALL_DOC_EXAMPLES = avcodec decode_audio encode_audio filter_audio metadata \ - output transcode_aac +ALL_DOC_EXAMPLES = decode_audio \ + decode_video \ + encode_audio \ + encode_video \ + filter_audio \ + metadata output \ + transcode_aac \ DOC_EXAMPLES := $(DOC_EXAMPLES-yes:%=doc/examples/%$(EXESUF)) ALL_DOC_EXAMPLES := $(ALL_DOC_EXAMPLES:%=doc/examples/%$(EXESUF)) diff --git a/doc/examples/avcodec.c b/doc/examples/decode_video.c similarity index 55% rename from doc/examples/avcodec.c rename to doc/examples/decode_video.c index 4f7dc8b28ad06..20d11dae4e684 100644 --- a/doc/examples/avcodec.c +++ b/doc/examples/decode_video.c @@ -20,159 +20,23 @@ /** * @file - * libavcodec API use example. + * video decoding with libavcodec API example * - * @example avcodec.c - * Note that this library only handles codecs (MPEG, MPEG-4, etc...), - * not file formats (AVI, VOB, etc...). See library 'libavformat' for the - * format handling. + * @example decode_video.c */ -#include #include +#include #include -#ifdef HAVE_AV_CONFIG_H -#undef HAVE_AV_CONFIG_H -#endif - #include "libavcodec/avcodec.h" -#include "libavutil/channel_layout.h" + #include "libavutil/common.h" #include "libavutil/imgutils.h" #include "libavutil/mathematics.h" -#include "libavutil/samplefmt.h" #define INBUF_SIZE 4096 -/* - * Video encoding example - */ -static void video_encode_example(const char *filename) -{ - AVCodec *codec; - AVCodecContext *c= NULL; - int i, ret, x, y, got_output; - FILE *f; - AVFrame *picture; - AVPacket pkt; - uint8_t endcode[] = { 0, 0, 1, 0xb7 }; - - printf("Video encoding\n"); - - /* find the mpeg1video encoder */ - codec = avcodec_find_encoder(AV_CODEC_ID_MPEG1VIDEO); - if (!codec) { - fprintf(stderr, "codec not found\n"); - exit(1); - } - - c = avcodec_alloc_context3(codec); - picture = av_frame_alloc(); - - /* put sample parameters */ - c->bit_rate = 400000; - /* resolution must be a multiple of two */ - c->width = 352; - c->height = 288; - /* frames per second */ - c->time_base= (AVRational){1,25}; - c->gop_size = 10; /* emit one intra frame every ten frames */ - c->max_b_frames=1; - c->pix_fmt = AV_PIX_FMT_YUV420P; - - /* open it */ - if (avcodec_open2(c, codec, NULL) < 0) { - fprintf(stderr, "could not open codec\n"); - exit(1); - } - - f = fopen(filename, "wb"); - if (!f) { - fprintf(stderr, "could not open %s\n", filename); - exit(1); - } - - ret = av_image_alloc(picture->data, picture->linesize, c->width, c->height, - c->pix_fmt, 32); - if (ret < 0) { - fprintf(stderr, "could not alloc raw picture buffer\n"); - exit(1); - } - picture->format = c->pix_fmt; - picture->width = c->width; - picture->height = c->height; - - /* encode 1 second of video */ - for(i=0;i<25;i++) { - av_init_packet(&pkt); - pkt.data = NULL; // packet data will be allocated by the encoder - pkt.size = 0; - - fflush(stdout); - /* prepare a dummy image */ - /* Y */ - for(y=0;yheight;y++) { - for(x=0;xwidth;x++) { - picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3; - } - } - - /* Cb and Cr */ - for(y=0;yheight/2;y++) { - for(x=0;xwidth/2;x++) { - picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2; - picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5; - } - } - - picture->pts = i; - - /* encode the image */ - ret = avcodec_encode_video2(c, &pkt, picture, &got_output); - if (ret < 0) { - fprintf(stderr, "error encoding frame\n"); - exit(1); - } - - if (got_output) { - printf("encoding frame %3d (size=%5d)\n", i, pkt.size); - fwrite(pkt.data, 1, pkt.size, f); - av_packet_unref(&pkt); - } - } - - /* get the delayed frames */ - for (got_output = 1; got_output; i++) { - fflush(stdout); - - ret = avcodec_encode_video2(c, &pkt, NULL, &got_output); - if (ret < 0) { - fprintf(stderr, "error encoding frame\n"); - exit(1); - } - - if (got_output) { - printf("encoding frame %3d (size=%5d)\n", i, pkt.size); - fwrite(pkt.data, 1, pkt.size, f); - av_packet_unref(&pkt); - } - } - - /* add sequence end code to have a real MPEG file */ - fwrite(endcode, 1, sizeof(endcode), f); - fclose(f); - - avcodec_free_context(&c); - av_freep(&picture->data[0]); - av_frame_free(&picture); - printf("\n"); -} - -/* - * Video decoding example - */ - static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize, char *filename) { @@ -186,8 +50,9 @@ static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize, fclose(f); } -static void video_decode_example(const char *outfilename, const char *filename) +int main(int argc, char **argv) { + const char *filename, *outfilename; AVCodec *codec; AVCodecContext *c= NULL; int frame, got_picture, len; @@ -197,13 +62,20 @@ static void video_decode_example(const char *outfilename, const char *filename) char buf[1024]; AVPacket avpkt; + if (argc <= 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(0); + } + filename = argv[1]; + outfilename = argv[2]; + + avcodec_register_all(); + av_init_packet(&avpkt); /* set end of buffer to 0 (this ensures that no overreading happens for damaged MPEG streams) */ memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE); - printf("Video decoding\n"); - /* find the MPEG-1 video decoder */ codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO); if (!codec) { @@ -301,24 +173,6 @@ static void video_decode_example(const char *outfilename, const char *filename) avcodec_free_context(&c); av_frame_free(&picture); - printf("\n"); -} - -int main(int argc, char **argv) -{ - const char *filename; - - /* register all the codecs */ - avcodec_register_all(); - - if (argc <= 1) { - video_encode_example("/tmp/test.mpg"); - filename = "/tmp/test.mpg"; - } else { - filename = argv[1]; - } - - video_decode_example("/tmp/test%d.pgm", filename); return 0; } diff --git a/doc/examples/encode_video.c b/doc/examples/encode_video.c new file mode 100644 index 0000000000000..ca93472920d63 --- /dev/null +++ b/doc/examples/encode_video.c @@ -0,0 +1,164 @@ +/* + * copyright (c) 2001 Fabrice Bellard + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * video encoding with libavcodec API example + * + * @example encode_video.c + */ + +#include +#include +#include + +#include "libavcodec/avcodec.h" + +#include "libavutil/frame.h" +#include "libavutil/imgutils.h" + +int main(int argc, char **argv) +{ + const char *filename; + AVCodec *codec; + AVCodecContext *c= NULL; + int i, ret, x, y, got_output; + FILE *f; + AVFrame *picture; + AVPacket pkt; + uint8_t endcode[] = { 0, 0, 1, 0xb7 }; + + if (argc <= 1) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(0); + } + filename = argv[1]; + + avcodec_register_all(); + + /* find the mpeg1video encoder */ + codec = avcodec_find_encoder(AV_CODEC_ID_MPEG1VIDEO); + if (!codec) { + fprintf(stderr, "codec not found\n"); + exit(1); + } + + c = avcodec_alloc_context3(codec); + picture = av_frame_alloc(); + + /* put sample parameters */ + c->bit_rate = 400000; + /* resolution must be a multiple of two */ + c->width = 352; + c->height = 288; + /* frames per second */ + c->time_base= (AVRational){1,25}; + c->gop_size = 10; /* emit one intra frame every ten frames */ + c->max_b_frames=1; + c->pix_fmt = AV_PIX_FMT_YUV420P; + + /* open it */ + if (avcodec_open2(c, codec, NULL) < 0) { + fprintf(stderr, "could not open codec\n"); + exit(1); + } + + f = fopen(filename, "wb"); + if (!f) { + fprintf(stderr, "could not open %s\n", filename); + exit(1); + } + + ret = av_image_alloc(picture->data, picture->linesize, c->width, c->height, + c->pix_fmt, 32); + if (ret < 0) { + fprintf(stderr, "could not alloc raw picture buffer\n"); + exit(1); + } + picture->format = c->pix_fmt; + picture->width = c->width; + picture->height = c->height; + + /* encode 1 second of video */ + for(i=0;i<25;i++) { + av_init_packet(&pkt); + pkt.data = NULL; // packet data will be allocated by the encoder + pkt.size = 0; + + fflush(stdout); + /* prepare a dummy image */ + /* Y */ + for(y=0;yheight;y++) { + for(x=0;xwidth;x++) { + picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3; + } + } + + /* Cb and Cr */ + for(y=0;yheight/2;y++) { + for(x=0;xwidth/2;x++) { + picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2; + picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5; + } + } + + picture->pts = i; + + /* encode the image */ + ret = avcodec_encode_video2(c, &pkt, picture, &got_output); + if (ret < 0) { + fprintf(stderr, "error encoding frame\n"); + exit(1); + } + + if (got_output) { + printf("encoding frame %3d (size=%5d)\n", i, pkt.size); + fwrite(pkt.data, 1, pkt.size, f); + av_packet_unref(&pkt); + } + } + + /* get the delayed frames */ + for (got_output = 1; got_output; i++) { + fflush(stdout); + + ret = avcodec_encode_video2(c, &pkt, NULL, &got_output); + if (ret < 0) { + fprintf(stderr, "error encoding frame\n"); + exit(1); + } + + if (got_output) { + printf("encoding frame %3d (size=%5d)\n", i, pkt.size); + fwrite(pkt.data, 1, pkt.size, f); + av_packet_unref(&pkt); + } + } + + /* add sequence end code to have a real MPEG file */ + fwrite(endcode, 1, sizeof(endcode), f); + fclose(f); + + avcodec_free_context(&c); + av_freep(&picture->data[0]); + av_frame_free(&picture); + + return 0; +} From e02524025bce2c8bf8b5bffd96479785c75a70d4 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 20 Oct 2016 11:03:20 +0200 Subject: [PATCH 0370/3374] examples/encode_video: constify the AVCodec instance --- doc/examples/encode_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/examples/encode_video.c b/doc/examples/encode_video.c index ca93472920d63..c5f3853f83e8a 100644 --- a/doc/examples/encode_video.c +++ b/doc/examples/encode_video.c @@ -37,7 +37,7 @@ int main(int argc, char **argv) { const char *filename; - AVCodec *codec; + const AVCodec *codec; AVCodecContext *c= NULL; int i, ret, x, y, got_output; FILE *f; From d0a603a534a0ee4b255e5e72742428a7f7f42b83 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 20 Oct 2016 11:03:20 +0200 Subject: [PATCH 0371/3374] examples/encode_video: set the framerate --- doc/examples/encode_video.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/examples/encode_video.c b/doc/examples/encode_video.c index c5f3853f83e8a..b955cce4af7a0 100644 --- a/doc/examples/encode_video.c +++ b/doc/examples/encode_video.c @@ -69,7 +69,9 @@ int main(int argc, char **argv) c->width = 352; c->height = 288; /* frames per second */ - c->time_base= (AVRational){1,25}; + c->time_base = (AVRational){1, 25}; + c->framerate = (AVRational){25, 1}; + c->gop_size = 10; /* emit one intra frame every ten frames */ c->max_b_frames=1; c->pix_fmt = AV_PIX_FMT_YUV420P; From 5b4d7ac7ae5d821cfa6ab89f8eab4d31851ef32c Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 20 Oct 2016 11:03:20 +0200 Subject: [PATCH 0372/3374] examples/encode_video: use the AVFrame API for allocating the frame It is more efficient and so preferred over allocating the buffers manually. --- doc/examples/encode_video.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/doc/examples/encode_video.c b/doc/examples/encode_video.c index b955cce4af7a0..3fd2d562a3b81 100644 --- a/doc/examples/encode_video.c +++ b/doc/examples/encode_video.c @@ -88,16 +88,16 @@ int main(int argc, char **argv) exit(1); } - ret = av_image_alloc(picture->data, picture->linesize, c->width, c->height, - c->pix_fmt, 32); - if (ret < 0) { - fprintf(stderr, "could not alloc raw picture buffer\n"); - exit(1); - } picture->format = c->pix_fmt; picture->width = c->width; picture->height = c->height; + ret = av_frame_get_buffer(picture, 32); + if (ret < 0) { + fprintf(stderr, "could not alloc the frame data\n"); + exit(1); + } + /* encode 1 second of video */ for(i=0;i<25;i++) { av_init_packet(&pkt); @@ -105,6 +105,12 @@ int main(int argc, char **argv) pkt.size = 0; fflush(stdout); + + /* make sure the frame data is writable */ + ret = av_frame_make_writable(picture); + if (ret < 0) + exit(1); + /* prepare a dummy image */ /* Y */ for(y=0;yheight;y++) { @@ -159,7 +165,6 @@ int main(int argc, char **argv) fclose(f); avcodec_free_context(&c); - av_freep(&picture->data[0]); av_frame_free(&picture); return 0; From 8191f960a669819db4de33a2439ded1630b8a73e Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 20 Oct 2016 11:03:20 +0200 Subject: [PATCH 0373/3374] examples/decode_video: constify the AVCodec instance --- doc/examples/decode_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/examples/decode_video.c b/doc/examples/decode_video.c index 20d11dae4e684..4036dbe3605d3 100644 --- a/doc/examples/decode_video.c +++ b/doc/examples/decode_video.c @@ -53,7 +53,7 @@ static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize, int main(int argc, char **argv) { const char *filename, *outfilename; - AVCodec *codec; + const AVCodec *codec; AVCodecContext *c= NULL; int frame, got_picture, len; FILE *f; From 636515c324facaa14ccd8ab0732740a240a31ba9 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 20 Oct 2016 11:03:20 +0200 Subject: [PATCH 0374/3374] examples/decode_video: remove a stray unrelated comment --- doc/examples/decode_video.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/examples/decode_video.c b/doc/examples/decode_video.c index 4036dbe3605d3..43819ecc6c9b8 100644 --- a/doc/examples/decode_video.c +++ b/doc/examples/decode_video.c @@ -99,8 +99,6 @@ int main(int argc, char **argv) exit(1); } - /* the codec gives us the frame size, in samples */ - f = fopen(filename, "rb"); if (!f) { fprintf(stderr, "could not open %s\n", filename); From 85baef4ff1512bcc2544928bfa5f42072903a691 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 30 Oct 2015 15:02:04 +0100 Subject: [PATCH 0375/3374] vf_drawtext: Move static keyword to beginning of variable declaration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit libavfilter/vf_drawtext.c:226:1: warning: ‘static’ is not at beginning of declaration [-Wold-style-declaration] --- libavfilter/vf_drawtext.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index e36cfa2c006d9..994eea3c0c4f8 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -219,11 +219,10 @@ static const AVClass drawtext_class = { #define FT_ERRORDEF(e, v, s) { (e), (s) }, #define FT_ERROR_END_LIST { 0, NULL } }; -struct ft_error -{ +static struct ft_error { int err; const char *err_msg; -} static ft_errors[] = +} ft_errors[] = #include FT_ERRORS_H #define FT_ERRMSG(e) ft_errors[e].err_msg From 39cea6570c11a49b64b2ec8d71e218db03b4c742 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 9 Nov 2015 13:25:55 +0100 Subject: [PATCH 0376/3374] aactab: Move extern keyword to the front of array declarations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit libavcodec/aactab.h:49:1: warning: ‘extern’ is not at beginning of declaration [-Wold-style-declaration] --- libavcodec/aactab.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/aactab.h b/libavcodec/aactab.h index fc26db8a4d62a..b1e9510cf3a5a 100644 --- a/libavcodec/aactab.h +++ b/libavcodec/aactab.h @@ -46,8 +46,8 @@ */ DECLARE_ALIGNED(32, extern float, ff_aac_kbd_long_1024)[1024]; DECLARE_ALIGNED(32, extern float, ff_aac_kbd_short_128)[128]; -const DECLARE_ALIGNED(32, extern float, ff_aac_eld_window_512)[1920]; -const DECLARE_ALIGNED(32, extern float, ff_aac_eld_window_480)[1800]; +DECLARE_ALIGNED(32, extern const float, ff_aac_eld_window_512)[1920]; +DECLARE_ALIGNED(32, extern const float, ff_aac_eld_window_480)[1800]; // @} /* @name number of scalefactor window bands for long and short transform windows respectively From 4cf2ffb7c45840b09bc49e34da88d4053dd442cb Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 13 Mar 2015 00:35:37 +0100 Subject: [PATCH 0377/3374] idct: Have function pointer prototype match implementation libavcodec/idctdsp.c(175) : warning C4028: formal parameter 2 different from declaration --- libavcodec/idctdsp.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libavcodec/idctdsp.h b/libavcodec/idctdsp.h index 51de9bc9abeaa..c6b7aeda5f33a 100644 --- a/libavcodec/idctdsp.h +++ b/libavcodec/idctdsp.h @@ -21,6 +21,8 @@ #include +#include "config.h" + #include "avcodec.h" /** @@ -51,13 +53,13 @@ int ff_init_scantable_permutation_x86(uint8_t *idct_permutation, typedef struct IDCTDSPContext { /* pixel ops : interface with DCT */ void (*put_pixels_clamped)(const int16_t *block /* align 16 */, - uint8_t *pixels /* align 8 */, + uint8_t *restrict pixels /* align 8 */, ptrdiff_t line_size); void (*put_signed_pixels_clamped)(const int16_t *block /* align 16 */, - uint8_t *pixels /* align 8 */, + uint8_t *restrict pixels /* align 8 */, ptrdiff_t line_size); void (*add_pixels_clamped)(const int16_t *block /* align 16 */, - uint8_t *pixels /* align 8 */, + uint8_t *restrict pixels /* align 8 */, ptrdiff_t line_size); void (*idct)(int16_t *block /* align 16 */); From baab87c4f30e75ea309294b06adcd01ce678bdc5 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 13 Mar 2015 00:38:57 +0100 Subject: [PATCH 0378/3374] bink: Have function pointer prototype match implementation libavcodec/binkdsp.c(156) : warning C4028: formal parameter 1 different from declaration --- libavcodec/binkdsp.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavcodec/binkdsp.h b/libavcodec/binkdsp.h index 418afb9895184..9524fe27e899a 100644 --- a/libavcodec/binkdsp.h +++ b/libavcodec/binkdsp.h @@ -29,11 +29,13 @@ #include +#include "config.h" + typedef struct BinkDSPContext { void (*idct_put)(uint8_t *dest/*align 8*/, int line_size, int32_t *block/*align 16*/); void (*idct_add)(uint8_t *dest/*align 8*/, int line_size, int32_t *block/*align 16*/); void (*scale_block)(const uint8_t src[64]/*align 8*/, uint8_t *dst/*align 8*/, int linesize); - void (*add_pixels8)(uint8_t *pixels, int16_t *block, int line_size); + void (*add_pixels8)(uint8_t *restrict pixels, int16_t *block, int line_size); } BinkDSPContext; void ff_binkdsp_init(BinkDSPContext *c); From f4ca8ea92a8b36fe723412aefafc1b2fa89f8dc6 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 29 Oct 2015 13:39:49 +0100 Subject: [PATCH 0379/3374] rtmpproto: Restructure zlib code to avoid unreachable code warning libavformat\rtmpproto.c(1165) : warning C4702: unreachable code --- libavformat/rtmpproto.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 0097841e8109a..5298c18790b8a 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -1111,7 +1111,7 @@ static int rtmp_calc_swfhash(URLContext *s) { RTMPContext *rt = s->priv_data; uint8_t *in_data = NULL, *out_data = NULL, *swfdata; - int64_t in_size, out_size; + int64_t in_size; URLContext *stream; char swfhash[32]; int swfsize; @@ -1143,6 +1143,8 @@ static int rtmp_calc_swfhash(URLContext *s) } if (!memcmp(in_data, "CWS", 3)) { +#if CONFIG_ZLIB + int64_t out_size; /* Decompress the SWF player file using Zlib. */ if (!(out_data = av_malloc(8))) { ret = AVERROR(ENOMEM); @@ -1152,18 +1154,17 @@ static int rtmp_calc_swfhash(URLContext *s) memcpy(out_data, in_data, 8); out_size = 8; -#if CONFIG_ZLIB if ((ret = rtmp_uncompress_swfplayer(in_data + 8, in_size - 8, &out_data, &out_size)) < 0) goto fail; + swfsize = out_size; + swfdata = out_data; #else av_log(s, AV_LOG_ERROR, "Zlib is required for decompressing the SWF player file.\n"); ret = AVERROR(EINVAL); goto fail; #endif - swfsize = out_size; - swfdata = out_data; } else { swfsize = in_size; swfdata = in_data; From 2025d3787158ba272a1b8fbc0493fa20dd7a8484 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 4 Dec 2015 12:43:10 +0100 Subject: [PATCH 0380/3374] doc: Turn off noisy deprecation warnings in the option printer --- doc/print_options.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/doc/print_options.c b/doc/print_options.c index aa75a00ba2ef4..eb54f077547df 100644 --- a/doc/print_options.c +++ b/doc/print_options.c @@ -23,15 +23,21 @@ */ #include +#include #include #include -#include "libavformat/avformat.h" -#include "libavformat/options_table.h" -#include "libavcodec/avcodec.h" -#include "libavcodec/options_table.h" +#include "libavutil/attributes.h" #include "libavutil/opt.h" +/* Forcibly turn off deprecation warnings, which just add noise here. */ +#undef attribute_deprecated +#define attribute_deprecated + +#include "libavcodec/options_table.h" + +#include "libavformat/options_table.h" + static void print_usage(void) { fprintf(stderr, "Usage: enum_options type\n" From 7433feb82f75827884d909de34d341a1c4401d4a Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Mon, 31 Oct 2016 22:14:04 +0000 Subject: [PATCH 0381/3374] lavfi: Make default get_video_buffer work with hardware frames --- libavfilter/video.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/libavfilter/video.c b/libavfilter/video.c index cadac50da8c27..533946a74cd9a 100644 --- a/libavfilter/video.c +++ b/libavfilter/video.c @@ -20,6 +20,7 @@ #include #include "libavutil/buffer.h" +#include "libavutil/hwcontext.h" #include "libavutil/imgutils.h" #include "libavutil/mem.h" @@ -43,11 +44,16 @@ AVFrame *ff_default_get_video_buffer(AVFilterLink *link, int w, int h) if (!frame) return NULL; - frame->width = w; - frame->height = h; - frame->format = link->format; + if (link->hw_frames_ctx && + ((AVHWFramesContext*)link->hw_frames_ctx->data)->format == link->format) { + ret = av_hwframe_get_buffer(link->hw_frames_ctx, frame, 0); + } else { + frame->width = w; + frame->height = h; + frame->format = link->format; - ret = av_frame_get_buffer(frame, 32); + ret = av_frame_get_buffer(frame, 32); + } if (ret < 0) av_frame_free(&frame); From 7e2561fa8313982aa21f7657953eedeeb33b210d Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Mon, 31 Oct 2016 22:14:10 +0000 Subject: [PATCH 0382/3374] lavfi: Use ff_get_video_buffer in all filters using hwframes --- libavfilter/vf_deinterlace_qsv.c | 10 ++++------ libavfilter/vf_hwupload.c | 9 ++------- libavfilter/vf_hwupload_cuda.c | 6 +----- libavfilter/vf_scale_qsv.c | 6 +----- libavfilter/vf_scale_vaapi.c | 11 +++-------- 5 files changed, 11 insertions(+), 31 deletions(-) diff --git a/libavfilter/vf_deinterlace_qsv.c b/libavfilter/vf_deinterlace_qsv.c index b26a900c4f109..36eea15fcc10b 100644 --- a/libavfilter/vf_deinterlace_qsv.c +++ b/libavfilter/vf_deinterlace_qsv.c @@ -433,13 +433,11 @@ static int process_frame(AVFilterContext *ctx, const AVFrame *in, mfxStatus err; int ret, again = 0; - out = av_frame_alloc(); - if (!out) - return AVERROR(ENOMEM); - - ret = av_hwframe_get_buffer(s->hw_frames_ctx, out, 0); - if (ret < 0) + out = ff_get_video_buffer(outlink, outlink->w, outlink->h); + if (!out) { + ret = AVERROR(ENOMEM); goto fail; + } surf_out = (mfxFrameSurface1*)out->data[3]; surf_out->Info.CropW = outlink->w; diff --git a/libavfilter/vf_hwupload.c b/libavfilter/vf_hwupload.c index c438d5aac971a..8c43e0080d925 100644 --- a/libavfilter/vf_hwupload.c +++ b/libavfilter/vf_hwupload.c @@ -161,15 +161,10 @@ static int hwupload_filter_frame(AVFilterLink *link, AVFrame *input) if (input->format == outlink->format) return ff_filter_frame(outlink, input); - output = av_frame_alloc(); + output = ff_get_video_buffer(outlink, outlink->w, outlink->h); if (!output) { - err = AVERROR(ENOMEM); - goto fail; - } - - err = av_hwframe_get_buffer(ctx->hwframes_ref, output, 0); - if (err < 0) { av_log(ctx, AV_LOG_ERROR, "Failed to allocate frame to upload to.\n"); + err = AVERROR(ENOMEM); goto fail; } diff --git a/libavfilter/vf_hwupload_cuda.c b/libavfilter/vf_hwupload_cuda.c index dfb35066f604a..0ab5276933047 100644 --- a/libavfilter/vf_hwupload_cuda.c +++ b/libavfilter/vf_hwupload_cuda.c @@ -156,16 +156,12 @@ static int cudaupload_filter_frame(AVFilterLink *link, AVFrame *in) AVFrame *out = NULL; int ret; - out = av_frame_alloc(); + out = ff_get_video_buffer(outlink, outlink->w, outlink->h); if (!out) { ret = AVERROR(ENOMEM); goto fail; } - ret = av_hwframe_get_buffer(s->hwframe, out, 0); - if (ret < 0) - goto fail; - out->width = in->width; out->height = in->height; diff --git a/libavfilter/vf_scale_qsv.c b/libavfilter/vf_scale_qsv.c index e5c3da5a512b8..f7c1c550928cf 100644 --- a/libavfilter/vf_scale_qsv.c +++ b/libavfilter/vf_scale_qsv.c @@ -528,16 +528,12 @@ static int qsvscale_filter_frame(AVFilterLink *link, AVFrame *in) AVFrame *out = NULL; int ret = 0; - out = av_frame_alloc(); + out = ff_get_video_buffer(outlink, outlink->w, outlink->h); if (!out) { ret = AVERROR(ENOMEM); goto fail; } - ret = av_hwframe_get_buffer(s->out_frames_ref, out, 0); - if (ret < 0) - goto fail; - do { err = MFXVideoVPP_RunFrameVPPAsync(s->session, (mfxFrameSurface1*)in->data[3], diff --git a/libavfilter/vf_scale_vaapi.c b/libavfilter/vf_scale_vaapi.c index 704456dd390b7..67648a9aa014e 100644 --- a/libavfilter/vf_scale_vaapi.c +++ b/libavfilter/vf_scale_vaapi.c @@ -31,6 +31,7 @@ #include "avfilter.h" #include "formats.h" #include "internal.h" +#include "video.h" typedef struct ScaleVAAPIContext { const AVClass *class; @@ -274,19 +275,13 @@ static int scale_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame) av_log(ctx, AV_LOG_DEBUG, "Using surface %#x for scale input.\n", input_surface); - output_frame = av_frame_alloc(); + output_frame = ff_get_video_buffer(outlink, ctx->output_width, + ctx->output_height); if (!output_frame) { - av_log(ctx, AV_LOG_ERROR, "Failed to allocate output frame."); err = AVERROR(ENOMEM); goto fail; } - err = av_hwframe_get_buffer(ctx->output_frames_ref, output_frame, 0); - if (err < 0) { - av_log(ctx, AV_LOG_ERROR, "Failed to get surface for " - "output: %d\n.", err); - } - output_surface = (VASurfaceID)(uintptr_t)output_frame->data[3]; av_log(ctx, AV_LOG_DEBUG, "Using surface %#x for scale output.\n", output_surface); From e3fb74f7f9a8f1895381355f40c92cac3c1023d9 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Tue, 25 Oct 2016 20:42:27 +0100 Subject: [PATCH 0383/3374] lavfi: Always propagate hw_frames_ctx through links Also adds a new flag to mark filters which are aware of hwframes and will perform this task themselves, and marks all appropriate filters with this flag. This is required to allow software-mapped hardware frames to work, because we need to have the frames context available for any later mapping operation in the filter graph. The output from the filter graph should only propagate further to an encoder if the hardware format actually matches the visible format (mapped frames are valid here and have an hw_frames_ctx, but this should not be given to the encoder as its hardware context). --- avconv.c | 5 ++++- libavfilter/avfilter.c | 15 +++++++-------- libavfilter/avfilter.h | 2 ++ libavfilter/internal.h | 6 ++++++ libavfilter/vf_deinterlace_qsv.c | 2 ++ libavfilter/vf_hwdownload.c | 1 + libavfilter/vf_hwupload.c | 1 + libavfilter/vf_hwupload_cuda.c | 2 ++ libavfilter/vf_scale_npp.c | 2 ++ libavfilter/vf_scale_qsv.c | 2 ++ libavfilter/vf_scale_vaapi.c | 1 + 11 files changed, 30 insertions(+), 9 deletions(-) diff --git a/avconv.c b/avconv.c index 4bd28e6e3b419..769b9e095bb94 100644 --- a/avconv.c +++ b/avconv.c @@ -38,6 +38,7 @@ #include "libavutil/parseutils.h" #include "libavutil/samplefmt.h" #include "libavutil/fifo.h" +#include "libavutil/hwcontext.h" #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" #include "libavutil/dict.h" @@ -2035,7 +2036,9 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len) if (!av_dict_get(ost->encoder_opts, "threads", NULL, 0)) av_dict_set(&ost->encoder_opts, "threads", "auto", 0); - if (ost->filter && ost->filter->filter->inputs[0]->hw_frames_ctx) { + if (ost->filter && ost->filter->filter->inputs[0]->hw_frames_ctx && + ((AVHWFramesContext*)ost->filter->filter->inputs[0]->hw_frames_ctx->data)->format == + ost->filter->filter->inputs[0]->format) { ost->enc_ctx->hw_frames_ctx = av_buffer_ref(ost->filter->filter->inputs[0]->hw_frames_ctx); if (!ost->enc_ctx->hw_frames_ctx) return AVERROR(ENOMEM); diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 1cedb15db457e..99531e5690a72 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/avassert.h" #include "libavutil/avstring.h" #include "libavutil/buffer.h" #include "libavutil/channel_layout.h" @@ -212,14 +213,12 @@ int avfilter_config_links(AVFilterContext *filter) } if (link->src->nb_inputs && link->src->inputs[0]->hw_frames_ctx && - !link->hw_frames_ctx) { - AVHWFramesContext *input_ctx = (AVHWFramesContext*)link->src->inputs[0]->hw_frames_ctx->data; - - if (input_ctx->format == link->format) { - link->hw_frames_ctx = av_buffer_ref(link->src->inputs[0]->hw_frames_ctx); - if (!link->hw_frames_ctx) - return AVERROR(ENOMEM); - } + !(link->src->filter->flags_internal & FF_FILTER_FLAG_HWFRAME_AWARE)) { + av_assert0(!link->hw_frames_ctx && + "should not be set by non-hwframe-aware filter"); + link->hw_frames_ctx = av_buffer_ref(link->src->inputs[0]->hw_frames_ctx); + if (!link->hw_frames_ctx) + return AVERROR(ENOMEM); } if ((config_link = link->dstpad->config_props)) diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index a17b2a2f5c359..568480dd3e4d4 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -244,6 +244,8 @@ typedef struct AVFilter { int priv_size; ///< size of private data to allocate for the filter + int flags_internal; ///< Additional flags for avfilter internal use only. + /** * Used by the filter registration system. Must not be touched by any other * code. diff --git a/libavfilter/internal.h b/libavfilter/internal.h index 202c2c018df4c..a377f9b2bab7e 100644 --- a/libavfilter/internal.h +++ b/libavfilter/internal.h @@ -220,4 +220,10 @@ AVFilterContext *ff_filter_alloc(const AVFilter *filter, const char *inst_name); */ void ff_filter_graph_remove_filter(AVFilterGraph *graph, AVFilterContext *filter); +/** + * The filter is aware of hardware frames, and any hardware frame context + * should not be automatically propagated through it. + */ +#define FF_FILTER_FLAG_HWFRAME_AWARE (1 << 0) + #endif /* AVFILTER_INTERNAL_H */ diff --git a/libavfilter/vf_deinterlace_qsv.c b/libavfilter/vf_deinterlace_qsv.c index 36eea15fcc10b..5cda2868395f2 100644 --- a/libavfilter/vf_deinterlace_qsv.c +++ b/libavfilter/vf_deinterlace_qsv.c @@ -575,4 +575,6 @@ AVFilter ff_vf_deinterlace_qsv = { .inputs = qsvdeint_inputs, .outputs = qsvdeint_outputs, + + .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, }; diff --git a/libavfilter/vf_hwdownload.c b/libavfilter/vf_hwdownload.c index 42925b83d3b97..aee8d23cb78f9 100644 --- a/libavfilter/vf_hwdownload.c +++ b/libavfilter/vf_hwdownload.c @@ -212,4 +212,5 @@ AVFilter ff_vf_hwdownload = { .priv_class = &hwdownload_class, .inputs = hwdownload_inputs, .outputs = hwdownload_outputs, + .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, }; diff --git a/libavfilter/vf_hwupload.c b/libavfilter/vf_hwupload.c index 8c43e0080d925..8cca9f42e2f7b 100644 --- a/libavfilter/vf_hwupload.c +++ b/libavfilter/vf_hwupload.c @@ -233,4 +233,5 @@ AVFilter ff_vf_hwupload = { .priv_class = &hwupload_class, .inputs = hwupload_inputs, .outputs = hwupload_outputs, + .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, }; diff --git a/libavfilter/vf_hwupload_cuda.c b/libavfilter/vf_hwupload_cuda.c index 0ab5276933047..94d5013cc6ac0 100644 --- a/libavfilter/vf_hwupload_cuda.c +++ b/libavfilter/vf_hwupload_cuda.c @@ -230,4 +230,6 @@ AVFilter ff_vf_hwupload_cuda = { .inputs = cudaupload_inputs, .outputs = cudaupload_outputs, + + .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, }; diff --git a/libavfilter/vf_scale_npp.c b/libavfilter/vf_scale_npp.c index 2fb4990953cb1..0e636a997d01f 100644 --- a/libavfilter/vf_scale_npp.c +++ b/libavfilter/vf_scale_npp.c @@ -657,4 +657,6 @@ AVFilter ff_vf_scale_npp = { .inputs = nppscale_inputs, .outputs = nppscale_outputs, + + .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, }; diff --git a/libavfilter/vf_scale_qsv.c b/libavfilter/vf_scale_qsv.c index f7c1c550928cf..8ef77835dca00 100644 --- a/libavfilter/vf_scale_qsv.c +++ b/libavfilter/vf_scale_qsv.c @@ -626,4 +626,6 @@ AVFilter ff_vf_scale_qsv = { .inputs = qsvscale_inputs, .outputs = qsvscale_outputs, + + .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, }; diff --git a/libavfilter/vf_scale_vaapi.c b/libavfilter/vf_scale_vaapi.c index 67648a9aa014e..50be68eee0737 100644 --- a/libavfilter/vf_scale_vaapi.c +++ b/libavfilter/vf_scale_vaapi.c @@ -463,4 +463,5 @@ AVFilter ff_vf_scale_vaapi = { .inputs = scale_vaapi_inputs, .outputs = scale_vaapi_outputs, .priv_class = &scale_vaapi_class, + .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, }; From 2e55e26b40e269816bba54da7d0e03955731b8fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 3 Nov 2016 09:12:02 +0200 Subject: [PATCH 0384/3374] vp9: Flip the order of arguments in MC functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes it match the pattern already used for VP8 MC functions. This also makes the signature match ffmpeg's version of these functions, easing porting of code in both directions. Signed-off-by: Martin Storsjö --- libavcodec/vp9.h | 5 ++- libavcodec/vp9block.c | 16 ++++----- libavcodec/vp9dsp.c | 69 +++++++++++++++++------------------- libavcodec/x86/vp9dsp_init.c | 34 +++++++++--------- libavcodec/x86/vp9mc.asm | 20 +++++------ tests/checkasm/vp9dsp.c | 18 +++++----- 6 files changed, 77 insertions(+), 85 deletions(-) diff --git a/libavcodec/vp9.h b/libavcodec/vp9.h index 25bb2d159b913..84bed6daaf63f 100644 --- a/libavcodec/vp9.h +++ b/libavcodec/vp9.h @@ -127,9 +127,8 @@ typedef struct ProbContext { uint8_t partition[4][4][3]; } ProbContext; -typedef void (*vp9_mc_func)(uint8_t *dst, const uint8_t *ref, - ptrdiff_t dst_stride, - ptrdiff_t ref_stride, +typedef void (*vp9_mc_func)(uint8_t *dst, ptrdiff_t dst_stride, + const uint8_t *ref, ptrdiff_t ref_stride, int h, int mx, int my); typedef struct VP9DSPContext { diff --git a/libavcodec/vp9block.c b/libavcodec/vp9block.c index cd40c3898933f..5a3b35649fc01 100644 --- a/libavcodec/vp9block.c +++ b/libavcodec/vp9block.c @@ -1187,7 +1187,7 @@ static av_always_inline void mc_luma_dir(VP9Context *s, vp9_mc_func(*mc)[2], ref = s->edge_emu_buffer + !!my * 3 * 80 + !!mx * 3; ref_stride = 80; } - mc[!!mx][!!my](dst, ref, dst_stride, ref_stride, bh, mx << 1, my << 1); + mc[!!mx][!!my](dst, dst_stride, ref, ref_stride, bh, mx << 1, my << 1); } static av_always_inline void mc_chroma_dir(VP9Context *s, vp9_mc_func(*mc)[2], @@ -1227,7 +1227,7 @@ static av_always_inline void mc_chroma_dir(VP9Context *s, vp9_mc_func(*mc)[2], bw + !!mx * 7, bh + !!my * 7, x - !!mx * 3, y - !!my * 3, w, h); ref_u = s->edge_emu_buffer + !!my * 3 * 80 + !!mx * 3; - mc[!!mx][!!my](dst_u, ref_u, dst_stride, 80, bh, mx, my); + mc[!!mx][!!my](dst_u, dst_stride, ref_u, 80, bh, mx, my); s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ref_v - !!my * 3 * src_stride_v - !!mx * 3, @@ -1236,10 +1236,10 @@ static av_always_inline void mc_chroma_dir(VP9Context *s, vp9_mc_func(*mc)[2], bw + !!mx * 7, bh + !!my * 7, x - !!mx * 3, y - !!my * 3, w, h); ref_v = s->edge_emu_buffer + !!my * 3 * 80 + !!mx * 3; - mc[!!mx][!!my](dst_v, ref_v, dst_stride, 80, bh, mx, my); + mc[!!mx][!!my](dst_v, dst_stride, ref_v, 80, bh, mx, my); } else { - mc[!!mx][!!my](dst_u, ref_u, dst_stride, src_stride_u, bh, mx, my); - mc[!!mx][!!my](dst_v, ref_v, dst_stride, src_stride_v, bh, mx, my); + mc[!!mx][!!my](dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my); + mc[!!mx][!!my](dst_v, dst_stride, ref_v, src_stride_v, bh, mx, my); } } @@ -1668,8 +1668,8 @@ int ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, av_assert2(n <= 4); if (w & bw) { s->dsp.mc[n][0][0][0][0](f->data[0] + yoff + o, - s->tmp_y + o, f->linesize[0], + s->tmp_y + o, 64, h, 0, 0); o += bw; } @@ -1686,12 +1686,12 @@ int ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, av_assert2(n <= 4); if (w & bw) { s->dsp.mc[n][0][0][0][0](f->data[1] + uvoff + o, - s->tmp_uv[0] + o, f->linesize[1], + s->tmp_uv[0] + o, 32, h, 0, 0); s->dsp.mc[n][0][0][0][0](f->data[2] + uvoff + o, - s->tmp_uv[1] + o, f->linesize[2], + s->tmp_uv[1] + o, 32, h, 0, 0); o += bw; } diff --git a/libavcodec/vp9dsp.c b/libavcodec/vp9dsp.c index c83defeda3a74..af93c0d4ea8d1 100644 --- a/libavcodec/vp9dsp.c +++ b/libavcodec/vp9dsp.c @@ -1738,9 +1738,8 @@ static av_cold void vp9dsp_loopfilter_init(VP9DSPContext *dsp) dsp->loop_filter_mix2[1][1][1] = loop_filter_v_88_16_c; } -static av_always_inline void copy_c(uint8_t *dst, const uint8_t *src, - ptrdiff_t dst_stride, - ptrdiff_t src_stride, +static av_always_inline void copy_c(uint8_t *dst, ptrdiff_t dst_stride, + const uint8_t *src, ptrdiff_t src_stride, int w, int h) { do { @@ -1751,9 +1750,8 @@ static av_always_inline void copy_c(uint8_t *dst, const uint8_t *src, } while (--h); } -static av_always_inline void avg_c(uint8_t *dst, const uint8_t *src, - ptrdiff_t dst_stride, - ptrdiff_t src_stride, +static av_always_inline void avg_c(uint8_t *dst, ptrdiff_t dst_stride, + const uint8_t *src, ptrdiff_t src_stride, int w, int h) { do { @@ -1767,13 +1765,12 @@ static av_always_inline void avg_c(uint8_t *dst, const uint8_t *src, } while (--h); } -#define fpel_fn(type, sz) \ -static void type ## sz ## _c(uint8_t *dst, const uint8_t *src, \ - ptrdiff_t dst_stride, \ - ptrdiff_t src_stride, \ - int h, int mx, int my) \ -{ \ - type ## _c(dst, src, dst_stride, src_stride, sz, h); \ +#define fpel_fn(type, sz) \ +static void type ## sz ## _c(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, int mx, int my) \ +{ \ + type ## _c(dst, dst_stride, src, src_stride, sz, h); \ } #define copy_avg_fn(sz) \ @@ -1851,9 +1848,8 @@ static const int8_t vp9_subpel_filters[3][15][8] = { F[6] * src[x + +3 * stride] + \ F[7] * src[x + +4 * stride] + 64) >> 7) -static av_always_inline void do_8tap_1d_c(uint8_t *dst, const uint8_t *src, - ptrdiff_t dst_stride, - ptrdiff_t src_stride, +static av_always_inline void do_8tap_1d_c(uint8_t *dst, ptrdiff_t dst_stride, + const uint8_t *src, ptrdiff_t src_stride, int w, int h, ptrdiff_t ds, const int8_t *filter, int avg) { @@ -1873,13 +1869,13 @@ static av_always_inline void do_8tap_1d_c(uint8_t *dst, const uint8_t *src, #define filter_8tap_1d_fn(opn, opa, dir, ds) \ static av_noinline void opn ## _8tap_1d_ ## dir ## _c(uint8_t *dst, \ - const uint8_t *src, \ ptrdiff_t dst_stride, \ + const uint8_t *src, \ ptrdiff_t src_stride, \ int w, int h, \ const int8_t *filter) \ { \ - do_8tap_1d_c(dst, src, dst_stride, src_stride, w, h, ds, filter, opa); \ + do_8tap_1d_c(dst, dst_stride, src, src_stride, w, h, ds, filter, opa); \ } filter_8tap_1d_fn(put, 0, v, src_stride) @@ -1889,9 +1885,8 @@ filter_8tap_1d_fn(avg, 1, h, 1) #undef filter_8tap_1d_fn -static av_always_inline void do_8tap_2d_c(uint8_t *dst, const uint8_t *src, - ptrdiff_t dst_stride, - ptrdiff_t src_stride, +static av_always_inline void do_8tap_2d_c(uint8_t *dst, ptrdiff_t dst_stride, + const uint8_t *src, ptrdiff_t src_stride, int w, int h, const int8_t *filterx, const int8_t *filtery, int avg) { @@ -1926,14 +1921,14 @@ static av_always_inline void do_8tap_2d_c(uint8_t *dst, const uint8_t *src, #define filter_8tap_2d_fn(opn, opa) \ static av_noinline void opn ## _8tap_2d_hv_c(uint8_t *dst, \ - const uint8_t *src, \ ptrdiff_t dst_stride, \ + const uint8_t *src, \ ptrdiff_t src_stride, \ int w, int h, \ const int8_t *filterx, \ const int8_t *filtery) \ { \ - do_8tap_2d_c(dst, src, dst_stride, src_stride, \ + do_8tap_2d_c(dst, dst_stride, src, src_stride, \ w, h, filterx, filtery, opa); \ } @@ -1947,23 +1942,23 @@ filter_8tap_2d_fn(avg, 1) #define filter_fn_1d(sz, dir, dir_m, type, type_idx, avg) \ static void \ avg ## _8tap_ ## type ## _ ## sz ## dir ## _c(uint8_t *dst, \ - const uint8_t *src, \ ptrdiff_t dst_stride, \ + const uint8_t *src, \ ptrdiff_t src_stride, \ int h, int mx, int my) \ { \ - avg ## _8tap_1d_ ## dir ## _c(dst, src, dst_stride, src_stride, sz, h, \ + avg ## _8tap_1d_ ## dir ## _c(dst, dst_stride, src, src_stride, sz, h, \ vp9_subpel_filters[type_idx][dir_m - 1]); \ } #define filter_fn_2d(sz, type, type_idx, avg) \ static void avg ## _8tap_ ## type ## _ ## sz ## hv_c(uint8_t *dst, \ - const uint8_t *src, \ ptrdiff_t dst_stride, \ + const uint8_t *src, \ ptrdiff_t src_stride, \ int h, int mx, int my) \ { \ - avg ## _8tap_2d_hv_c(dst, src, dst_stride, src_stride, sz, h, \ + avg ## _8tap_2d_hv_c(dst, dst_stride, src, src_stride, sz, h, \ vp9_subpel_filters[type_idx][mx - 1], \ vp9_subpel_filters[type_idx][my - 1]); \ } @@ -1972,8 +1967,8 @@ static void avg ## _8tap_ ## type ## _ ## sz ## hv_c(uint8_t *dst, \ (src[x] + ((mxy * (src[x + stride] - src[x]) + 8) >> 4)) static av_always_inline void do_bilin_1d_c(uint8_t *dst, - const uint8_t *src, ptrdiff_t dst_stride, + const uint8_t *src, ptrdiff_t src_stride, int w, int h, ptrdiff_t ds, int mxy, int avg) @@ -1994,12 +1989,12 @@ static av_always_inline void do_bilin_1d_c(uint8_t *dst, #define bilin_1d_fn(opn, opa, dir, ds) \ static av_noinline void opn ## _bilin_1d_ ## dir ## _c(uint8_t *dst, \ - const uint8_t *src, \ ptrdiff_t dst_stride, \ + const uint8_t *src, \ ptrdiff_t src_stride, \ int w, int h, int mxy) \ { \ - do_bilin_1d_c(dst, src, dst_stride, src_stride, w, h, ds, mxy, opa); \ + do_bilin_1d_c(dst, dst_stride, src, src_stride, w, h, ds, mxy, opa); \ } bilin_1d_fn(put, 0, v, src_stride) @@ -2010,8 +2005,8 @@ bilin_1d_fn(avg, 1, h, 1) #undef bilin_1d_fn static av_always_inline void do_bilin_2d_c(uint8_t *dst, - const uint8_t *src, ptrdiff_t dst_stride, + const uint8_t *src, ptrdiff_t src_stride, int w, int h, int mx, int my, int avg) @@ -2046,13 +2041,13 @@ static av_always_inline void do_bilin_2d_c(uint8_t *dst, #define bilin_2d_fn(opn, opa) \ static av_noinline void opn ## _bilin_2d_hv_c(uint8_t *dst, \ - const uint8_t *src, \ ptrdiff_t dst_stride, \ + const uint8_t *src, \ ptrdiff_t src_stride, \ int w, int h, \ int mx, int my) \ { \ - do_bilin_2d_c(dst, src, dst_stride, src_stride, w, h, mx, my, opa); \ + do_bilin_2d_c(dst, dst_stride, src, src_stride, w, h, mx, my, opa); \ } bilin_2d_fn(put, 0) @@ -2064,23 +2059,23 @@ bilin_2d_fn(avg, 1) #define bilinf_fn_1d(sz, dir, dir_m, avg) \ static void avg ## _bilin_ ## sz ## dir ## _c(uint8_t *dst, \ - const uint8_t *src, \ ptrdiff_t dst_stride, \ + const uint8_t *src, \ ptrdiff_t src_stride, \ int h, int mx, int my) \ { \ - avg ## _bilin_1d_ ## dir ## _c(dst, src, dst_stride, src_stride, \ + avg ## _bilin_1d_ ## dir ## _c(dst, dst_stride, src, src_stride, \ sz, h, dir_m); \ } #define bilinf_fn_2d(sz, avg) \ static void avg ## _bilin_ ## sz ## hv_c(uint8_t *dst, \ - const uint8_t *src, \ ptrdiff_t dst_stride, \ + const uint8_t *src, \ ptrdiff_t src_stride, \ int h, int mx, int my) \ { \ - avg ## _bilin_2d_hv_c(dst, src, dst_stride, src_stride, \ + avg ## _bilin_2d_hv_c(dst, dst_stride, src, src_stride, \ sz, h, mx, my); \ } diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c index 3b9e1bb0ca421..58aedcbd2d492 100644 --- a/libavcodec/x86/vp9dsp_init.c +++ b/libavcodec/x86/vp9dsp_init.c @@ -29,10 +29,9 @@ #if HAVE_YASM -#define fpel_func(avg, sz, opt) \ -void ff_vp9_ ## avg ## sz ## _ ## opt(uint8_t *dst, const uint8_t *src, \ - ptrdiff_t dst_stride, \ - ptrdiff_t src_stride, \ +#define fpel_func(avg, sz, opt) \ +void ff_vp9_ ## avg ## sz ## _ ## opt(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ int h, int mx, int my) fpel_func(put, 4, mmx); @@ -54,8 +53,8 @@ fpel_func(avg, 64, avx2); #define mc_func(avg, sz, dir, opt, type, f_sz) \ void \ ff_vp9_ ## avg ## _8tap_1d_ ## dir ## _ ## sz ## _ ## opt(uint8_t *dst, \ - const uint8_t *src, \ ptrdiff_t dst_stride, \ + const uint8_t *src, \ ptrdiff_t src_stride, \ int h, \ const type (*filter)[f_sz]) @@ -81,20 +80,21 @@ mc_funcs(32, avx2, int8_t, 32); #define mc_rep_func(avg, sz, hsz, dir, opt, type, f_sz) \ static av_always_inline void \ ff_vp9_ ## avg ## _8tap_1d_ ## dir ## _ ## sz ## _ ## opt(uint8_t *dst, \ - const uint8_t *src, \ ptrdiff_t dst_stride, \ + const uint8_t *src, \ ptrdiff_t src_stride, \ int h, \ const type (*filter)[f_sz]) \ { \ - ff_vp9_ ## avg ## _8tap_1d_ ## dir ## _ ## hsz ## _ ## opt(dst, src, \ + ff_vp9_ ## avg ## _8tap_1d_ ## dir ## _ ## hsz ## _ ## opt(dst, \ dst_stride, \ + src, \ src_stride, \ h, \ filter); \ ff_vp9_ ## avg ## _8tap_1d_ ## dir ## _ ## hsz ## _ ## opt(dst + hsz, \ - src + hsz, \ dst_stride, \ + src + hsz, \ src_stride, \ h, filter); \ } @@ -126,19 +126,18 @@ extern const int16_t ff_filters_sse2[3][15][8][8]; #define filter_8tap_2d_fn(op, sz, f, f_opt, fname, align, opt) \ static void \ op ## _8tap_ ## fname ## _ ## sz ## hv_ ## opt(uint8_t *dst, \ - const uint8_t *src, \ ptrdiff_t dst_stride, \ + const uint8_t *src, \ ptrdiff_t src_stride, \ int h, int mx, int my) \ { \ LOCAL_ALIGNED_ ## align(uint8_t, temp, [71 * 64]); \ - ff_vp9_put_8tap_1d_h_ ## sz ## _ ## opt(temp, src - 3 * src_stride, \ - 64, src_stride, \ - h + 7, \ + ff_vp9_put_8tap_1d_h_ ## sz ## _ ## opt(temp, 64, \ + src - 3 * src_stride, \ + src_stride, h + 7, \ ff_filters_ ## f_opt[f][mx - 1]); \ - ff_vp9_ ## op ## _8tap_1d_v_ ## sz ## _ ## opt(dst, temp + 3 * 64, \ - dst_stride, 64, \ - h, \ + ff_vp9_ ## op ## _8tap_1d_v_ ## sz ## _ ## opt(dst, dst_stride, \ + temp + 3 * 64, 64, h, \ ff_filters_ ## f_opt[f][my - 1]); \ } @@ -173,14 +172,15 @@ filters_8tap_2d_fn(avg, 32, 32, avx2, ssse3) #define filter_8tap_1d_fn(op, sz, f, f_opt, fname, dir, dvar, opt) \ static void \ op ## _8tap_ ## fname ## _ ## sz ## dir ## _ ## opt(uint8_t *dst, \ - const uint8_t *src, \ ptrdiff_t dst_stride, \ + const uint8_t *src, \ ptrdiff_t src_stride, \ int h, int mx, \ int my) \ { \ - ff_vp9_ ## op ## _8tap_1d_ ## dir ## _ ## sz ## _ ## opt(dst, src, \ + ff_vp9_ ## op ## _8tap_1d_ ## dir ## _ ## sz ## _ ## opt(dst, \ dst_stride, \ + src, \ src_stride, h,\ ff_filters_ ## f_opt[f][dvar - 1]); \ } diff --git a/libavcodec/x86/vp9mc.asm b/libavcodec/x86/vp9mc.asm index 15e93ea6cb0bc..c9701aea182e1 100644 --- a/libavcodec/x86/vp9mc.asm +++ b/libavcodec/x86/vp9mc.asm @@ -107,7 +107,7 @@ SECTION .text %macro filter_sse2_h_fn 1 %assign %%px mmsize/2 -cglobal vp9_%1_8tap_1d_h_ %+ %%px, 6, 6, 15, dst, src, dstride, sstride, h, filtery +cglobal vp9_%1_8tap_1d_h_ %+ %%px, 6, 6, 15, dst, dstride, src, sstride, h, filtery pxor m5, m5 mova m6, [pw_64] mova m7, [filteryq+ 0] @@ -192,7 +192,7 @@ filter_sse2_h_fn avg %macro filter_h_fn 1 %assign %%px mmsize/2 -cglobal vp9_%1_8tap_1d_h_ %+ %%px, 6, 6, 11, dst, src, dstride, sstride, h, filtery +cglobal vp9_%1_8tap_1d_h_ %+ %%px, 6, 6, 11, dst, dstride, src, sstride, h, filtery mova m6, [pw_256] mova m7, [filteryq+ 0] %if ARCH_X86_64 && mmsize > 8 @@ -253,7 +253,7 @@ filter_h_fn avg %if ARCH_X86_64 %macro filter_hx2_fn 1 %assign %%px mmsize -cglobal vp9_%1_8tap_1d_h_ %+ %%px, 6, 6, 14, dst, src, dstride, sstride, h, filtery +cglobal vp9_%1_8tap_1d_h_ %+ %%px, 6, 6, 14, dst, dstride, src, sstride, h, filtery mova m13, [pw_256] mova m8, [filteryq+ 0] mova m9, [filteryq+32] @@ -315,9 +315,9 @@ filter_hx2_fn avg %macro filter_sse2_v_fn 1 %assign %%px mmsize/2 %if ARCH_X86_64 -cglobal vp9_%1_8tap_1d_v_ %+ %%px, 6, 8, 15, dst, src, dstride, sstride, h, filtery, src4, sstride3 +cglobal vp9_%1_8tap_1d_v_ %+ %%px, 6, 8, 15, dst, dstride, src, sstride, h, filtery, src4, sstride3 %else -cglobal vp9_%1_8tap_1d_v_ %+ %%px, 4, 7, 15, dst, src, dstride, sstride, filtery, src4, sstride3 +cglobal vp9_%1_8tap_1d_v_ %+ %%px, 4, 7, 15, dst, dstride, src, sstride, filtery, src4, sstride3 mov filteryq, r5mp %define hd r4mp %endif @@ -413,9 +413,9 @@ filter_sse2_v_fn avg %macro filter_v_fn 1 %assign %%px mmsize/2 %if ARCH_X86_64 -cglobal vp9_%1_8tap_1d_v_ %+ %%px, 6, 8, 11, dst, src, dstride, sstride, h, filtery, src4, sstride3 +cglobal vp9_%1_8tap_1d_v_ %+ %%px, 6, 8, 11, dst, dstride, src, sstride, h, filtery, src4, sstride3 %else -cglobal vp9_%1_8tap_1d_v_ %+ %%px, 4, 7, 11, dst, src, dstride, sstride, filtery, src4, sstride3 +cglobal vp9_%1_8tap_1d_v_ %+ %%px, 4, 7, 11, dst, dstride, src, sstride, filtery, src4, sstride3 mov filteryq, r5mp %define hd r4mp %endif @@ -486,7 +486,7 @@ filter_v_fn avg %macro filter_vx2_fn 1 %assign %%px mmsize -cglobal vp9_%1_8tap_1d_v_ %+ %%px, 6, 8, 14, dst, src, dstride, sstride, h, filtery, src4, sstride3 +cglobal vp9_%1_8tap_1d_v_ %+ %%px, 6, 8, 14, dst, dstride, src, sstride, h, filtery, src4, sstride3 mova m13, [pw_256] lea sstride3q, [sstrideq*3] lea src4q, [srcq+sstrideq] @@ -562,11 +562,11 @@ filter_vx2_fn avg %endif %if %2 <= mmsize -cglobal vp9_%1%2, 5, 7, 4, dst, src, dstride, sstride, h, dstride3, sstride3 +cglobal vp9_%1%2, 5, 7, 4, dst, dstride, src, sstride, h, dstride3, sstride3 lea sstride3q, [sstrideq*3] lea dstride3q, [dstrideq*3] %else -cglobal vp9_%1%2, 5, 5, 4, dst, src, dstride, sstride, h +cglobal vp9_%1%2, 5, 5, 4, dst, dstride, src, sstride, h %endif .loop: %%srcfn m0, [srcq] diff --git a/tests/checkasm/vp9dsp.c b/tests/checkasm/vp9dsp.c index f0d93725ebfd2..f0cc2a7e45731 100644 --- a/tests/checkasm/vp9dsp.c +++ b/tests/checkasm/vp9dsp.c @@ -228,8 +228,8 @@ static void check_mc(void) int op, hsize, filter, dx, dy; declare_func_emms(AV_CPU_FLAG_MMX | AV_CPU_FLAG_MMXEXT, - void, uint8_t *dst, const uint8_t *ref, - ptrdiff_t dst_stride, ptrdiff_t ref_stride, + void, uint8_t *dst, ptrdiff_t dst_stride, + const uint8_t *ref, ptrdiff_t ref_stride, int h, int mx, int my); for (op = 0; op < 2; op++) { @@ -252,13 +252,11 @@ static void check_mc(void) int mx = dx ? 1 + (rnd() % 14) : 0; int my = dy ? 1 + (rnd() % 14) : 0; randomize_buffers(); - call_ref(dst0, src, - size * SIZEOF_PIXEL, - SRC_BUF_STRIDE * SIZEOF_PIXEL, + call_ref(dst0, size * SIZEOF_PIXEL, + src, SRC_BUF_STRIDE * SIZEOF_PIXEL, size, mx, my); - call_new(dst1, src, - size * SIZEOF_PIXEL, - SRC_BUF_STRIDE * SIZEOF_PIXEL, + call_new(dst1, size * SIZEOF_PIXEL, + src, SRC_BUF_STRIDE * SIZEOF_PIXEL, size, mx, my); if (memcmp(dst0, dst1, DST_BUF_SIZE)) fail(); @@ -267,8 +265,8 @@ static void check_mc(void) // functions are identical if (filter >= 1 && filter <= 2) continue; - bench_new(dst1, src, size * SIZEOF_PIXEL, - SRC_BUF_STRIDE * SIZEOF_PIXEL, + bench_new(dst1, size * SIZEOF_PIXEL, + src, SRC_BUF_STRIDE * SIZEOF_PIXEL, size, mx, my); } } From ffbd1d2b0002576ef0d976a41ff959c635373fdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 3 Nov 2016 09:12:08 +0200 Subject: [PATCH 0385/3374] arm: vp9: Add NEON optimizations of VP9 MC functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. The filter coefficients are signed values, where the product of the multiplication with one individual filter coefficient doesn't overflow a 16 bit signed value (the largest filter coefficient is 127). But when the products are accumulated, the resulting sum can overflow the 16 bit signed range. Instead of accumulating in 32 bit, we accumulate the largest product (either index 3 or 4) last with a saturated addition. (The VP8 MC asm does something similar, but slightly simpler, by accumulating each half of the filter separately. In the VP9 MC filters, each half of the filter can also overflow though, so the largest component has to be handled individually.) Examples of relative speedup compared to the C version, from checkasm: Cortex A7 A8 A9 A53 vp9_avg4_neon: 1.71 1.15 1.42 1.49 vp9_avg8_neon: 2.51 3.63 3.14 2.58 vp9_avg16_neon: 2.95 6.76 3.01 2.84 vp9_avg32_neon: 3.29 6.64 2.85 3.00 vp9_avg64_neon: 3.47 6.67 3.14 2.80 vp9_avg_8tap_smooth_4h_neon: 3.22 4.73 2.76 4.67 vp9_avg_8tap_smooth_4hv_neon: 3.67 4.76 3.28 4.71 vp9_avg_8tap_smooth_4v_neon: 5.52 7.60 4.60 6.31 vp9_avg_8tap_smooth_8h_neon: 6.22 9.04 5.12 9.32 vp9_avg_8tap_smooth_8hv_neon: 6.38 8.21 5.72 8.17 vp9_avg_8tap_smooth_8v_neon: 9.22 12.66 8.15 11.10 vp9_avg_8tap_smooth_64h_neon: 7.02 10.23 5.54 11.58 vp9_avg_8tap_smooth_64hv_neon: 6.76 9.46 5.93 9.40 vp9_avg_8tap_smooth_64v_neon: 10.76 14.13 9.46 13.37 vp9_put4_neon: 1.11 1.47 1.00 1.21 vp9_put8_neon: 1.23 2.17 1.94 1.48 vp9_put16_neon: 1.63 4.02 1.73 1.97 vp9_put32_neon: 1.56 4.92 2.00 1.96 vp9_put64_neon: 2.10 5.28 2.03 2.35 vp9_put_8tap_smooth_4h_neon: 3.11 4.35 2.63 4.35 vp9_put_8tap_smooth_4hv_neon: 3.67 4.69 3.25 4.71 vp9_put_8tap_smooth_4v_neon: 5.45 7.27 4.49 6.52 vp9_put_8tap_smooth_8h_neon: 5.97 8.18 4.81 8.56 vp9_put_8tap_smooth_8hv_neon: 6.39 7.90 5.64 8.15 vp9_put_8tap_smooth_8v_neon: 9.03 11.84 8.07 11.51 vp9_put_8tap_smooth_64h_neon: 6.78 9.48 4.88 10.89 vp9_put_8tap_smooth_64hv_neon: 6.99 8.87 5.94 9.56 vp9_put_8tap_smooth_64v_neon: 10.69 13.30 9.43 14.34 For the larger 8tap filters, the speedup vs C code is around 5-14x. This is significantly faster than libvpx's implementation of the same functions, at least when comparing the put_8tap_smooth_64 functions (compared to vpx_convolve8_horiz_neon and vpx_convolve8_vert_neon from libvpx). Absolute runtimes from checkasm: Cortex A7 A8 A9 A53 vp9_put_8tap_smooth_64h_neon: 20150.3 14489.4 19733.6 10863.7 libvpx vpx_convolve8_horiz_neon: 52623.3 19736.4 21907.7 25027.7 vp9_put_8tap_smooth_64v_neon: 14455.0 12303.9 13746.4 9628.9 libvpx vpx_convolve8_vert_neon: 42090.0 17706.2 17659.9 16941.2 Thus, on the A9, the horizontal filter is only marginally faster than libvpx, while our version is significantly faster on the other cores, and the vertical filter is significantly faster on all cores. The difference is especially large on the A7. The libvpx implementation does the accumulation in 32 bit, which probably explains most of the differences. Signed-off-by: Martin Storsjö --- libavcodec/arm/Makefile | 2 + libavcodec/arm/vp9dsp_init_arm.c | 140 ++++++ libavcodec/arm/vp9mc_neon.S | 758 +++++++++++++++++++++++++++++++ libavcodec/vp9.h | 4 +- libavcodec/vp9block.c | 10 +- libavcodec/vp9dsp.c | 2 + 6 files changed, 913 insertions(+), 3 deletions(-) create mode 100644 libavcodec/arm/vp9dsp_init_arm.c create mode 100644 libavcodec/arm/vp9mc_neon.S diff --git a/libavcodec/arm/Makefile b/libavcodec/arm/Makefile index bd4dd4e4ce7a4..26382306539b6 100644 --- a/libavcodec/arm/Makefile +++ b/libavcodec/arm/Makefile @@ -45,6 +45,7 @@ OBJS-$(CONFIG_MLP_DECODER) += arm/mlpdsp_init_arm.o OBJS-$(CONFIG_RV40_DECODER) += arm/rv40dsp_init_arm.o OBJS-$(CONFIG_VORBIS_DECODER) += arm/vorbisdsp_init_arm.o OBJS-$(CONFIG_VP6_DECODER) += arm/vp6dsp_init_arm.o +OBJS-$(CONFIG_VP9_DECODER) += arm/vp9dsp_init_arm.o # ARMv5 optimizations @@ -138,3 +139,4 @@ NEON-OBJS-$(CONFIG_RV40_DECODER) += arm/rv34dsp_neon.o \ arm/rv40dsp_neon.o NEON-OBJS-$(CONFIG_VORBIS_DECODER) += arm/vorbisdsp_neon.o NEON-OBJS-$(CONFIG_VP6_DECODER) += arm/vp6dsp_neon.o +NEON-OBJS-$(CONFIG_VP9_DECODER) += arm/vp9mc_neon.o diff --git a/libavcodec/arm/vp9dsp_init_arm.c b/libavcodec/arm/vp9dsp_init_arm.c new file mode 100644 index 0000000000000..1b00177f85e9a --- /dev/null +++ b/libavcodec/arm/vp9dsp_init_arm.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2016 Google Inc. + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/arm/cpu.h" +#include "libavcodec/vp9.h" + +#define declare_fpel(type, sz) \ +void ff_vp9_##type##sz##_neon(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, int mx, int my) + +#define declare_copy_avg(sz) \ + declare_fpel(copy, sz); \ + declare_fpel(avg , sz) + +#define decl_mc_func(op, filter, dir, sz) \ +void ff_vp9_##op##_##filter##sz##_##dir##_neon(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, int mx, int my) + +#define define_8tap_2d_fn(op, filter, sz) \ +static void op##_##filter##sz##_hv_neon(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, int mx, int my) \ +{ \ + LOCAL_ALIGNED_16(uint8_t, temp, [((sz < 64 ? 2 * sz : 64) + 8) * sz]); \ + /* We only need h + 7 lines, but the horizontal filter assumes an \ + * even number of rows, so filter h + 8 lines here. */ \ + ff_vp9_put_##filter##sz##_h_neon(temp, sz, \ + src - 3 * src_stride, src_stride, \ + h + 8, mx, 0); \ + ff_vp9_##op##_##filter##sz##_v_neon(dst, dst_stride, \ + temp + 3 * sz, sz, \ + h, 0, my); \ +} + +#define decl_filter_funcs(op, dir, sz) \ + decl_mc_func(op, regular, dir, sz); \ + decl_mc_func(op, sharp, dir, sz); \ + decl_mc_func(op, smooth, dir, sz) + +#define decl_mc_funcs(sz) \ + decl_filter_funcs(put, h, sz); \ + decl_filter_funcs(avg, h, sz); \ + decl_filter_funcs(put, v, sz); \ + decl_filter_funcs(avg, v, sz); \ + decl_filter_funcs(put, hv, sz); \ + decl_filter_funcs(avg, hv, sz) + +declare_copy_avg(64); +declare_copy_avg(32); +declare_copy_avg(16); +declare_copy_avg(8); +declare_copy_avg(4); + +decl_mc_funcs(64); +decl_mc_funcs(32); +decl_mc_funcs(16); +decl_mc_funcs(8); +decl_mc_funcs(4); + +#define define_8tap_2d_funcs(sz) \ + define_8tap_2d_fn(put, regular, sz) \ + define_8tap_2d_fn(put, sharp, sz) \ + define_8tap_2d_fn(put, smooth, sz) \ + define_8tap_2d_fn(avg, regular, sz) \ + define_8tap_2d_fn(avg, sharp, sz) \ + define_8tap_2d_fn(avg, smooth, sz) + +define_8tap_2d_funcs(64) +define_8tap_2d_funcs(32) +define_8tap_2d_funcs(16) +define_8tap_2d_funcs(8) +define_8tap_2d_funcs(4) + + +av_cold void ff_vp9dsp_init_arm(VP9DSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) { +#define init_fpel(idx1, idx2, sz, type) \ + dsp->mc[idx1][FILTER_8TAP_SMOOTH ][idx2][0][0] = \ + dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][0][0] = \ + dsp->mc[idx1][FILTER_8TAP_SHARP ][idx2][0][0] = \ + dsp->mc[idx1][FILTER_BILINEAR ][idx2][0][0] = ff_vp9_##type##sz##_neon + +#define init_copy_avg(idx, sz) \ + init_fpel(idx, 0, sz, copy); \ + init_fpel(idx, 1, sz, avg) + +#define init_mc_func(idx1, idx2, op, filter, fname, dir, mx, my, sz, pfx) \ + dsp->mc[idx1][filter][idx2][mx][my] = pfx##op##_##fname##sz##_##dir##_neon + +#define init_mc_funcs(idx, dir, mx, my, sz, pfx) \ + init_mc_func(idx, 0, put, FILTER_8TAP_REGULAR, regular, dir, mx, my, sz, pfx); \ + init_mc_func(idx, 0, put, FILTER_8TAP_SHARP, sharp, dir, mx, my, sz, pfx); \ + init_mc_func(idx, 0, put, FILTER_8TAP_SMOOTH, smooth, dir, mx, my, sz, pfx); \ + init_mc_func(idx, 1, avg, FILTER_8TAP_REGULAR, regular, dir, mx, my, sz, pfx); \ + init_mc_func(idx, 1, avg, FILTER_8TAP_SHARP, sharp, dir, mx, my, sz, pfx); \ + init_mc_func(idx, 1, avg, FILTER_8TAP_SMOOTH, smooth, dir, mx, my, sz, pfx) + +#define init_mc_funcs_dirs(idx, sz) \ + init_mc_funcs(idx, h, 1, 0, sz, ff_vp9_); \ + init_mc_funcs(idx, v, 0, 1, sz, ff_vp9_); \ + init_mc_funcs(idx, hv, 1, 1, sz,) + + init_copy_avg(0, 64); + init_copy_avg(1, 32); + init_copy_avg(2, 16); + init_copy_avg(3, 8); + init_copy_avg(4, 4); + + init_mc_funcs_dirs(0, 64); + init_mc_funcs_dirs(1, 32); + init_mc_funcs_dirs(2, 16); + init_mc_funcs_dirs(3, 8); + init_mc_funcs_dirs(4, 4); + } +} diff --git a/libavcodec/arm/vp9mc_neon.S b/libavcodec/arm/vp9mc_neon.S new file mode 100644 index 0000000000000..557353cb42f3d --- /dev/null +++ b/libavcodec/arm/vp9mc_neon.S @@ -0,0 +1,758 @@ +/* + * Copyright (c) 2016 Google Inc. + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/arm/asm.S" + +const regular_filter, align=4 + .short 0, 1, -5, 126, 8, -3, 1, 0 + .short -1, 3, -10, 122, 18, -6, 2, 0 + .short -1, 4, -13, 118, 27, -9, 3, -1 + .short -1, 4, -16, 112, 37, -11, 4, -1 + .short -1, 5, -18, 105, 48, -14, 4, -1 + .short -1, 5, -19, 97, 58, -16, 5, -1 + .short -1, 6, -19, 88, 68, -18, 5, -1 + .short -1, 6, -19, 78, 78, -19, 6, -1 + .short -1, 5, -18, 68, 88, -19, 6, -1 + .short -1, 5, -16, 58, 97, -19, 5, -1 + .short -1, 4, -14, 48, 105, -18, 5, -1 + .short -1, 4, -11, 37, 112, -16, 4, -1 + .short -1, 3, -9, 27, 118, -13, 4, -1 + .short 0, 2, -6, 18, 122, -10, 3, -1 + .short 0, 1, -3, 8, 126, -5, 1, 0 +endconst + +const sharp_filter, align=4 + .short -1, 3, -7, 127, 8, -3, 1, 0 + .short -2, 5, -13, 125, 17, -6, 3, -1 + .short -3, 7, -17, 121, 27, -10, 5, -2 + .short -4, 9, -20, 115, 37, -13, 6, -2 + .short -4, 10, -23, 108, 48, -16, 8, -3 + .short -4, 10, -24, 100, 59, -19, 9, -3 + .short -4, 11, -24, 90, 70, -21, 10, -4 + .short -4, 11, -23, 80, 80, -23, 11, -4 + .short -4, 10, -21, 70, 90, -24, 11, -4 + .short -3, 9, -19, 59, 100, -24, 10, -4 + .short -3, 8, -16, 48, 108, -23, 10, -4 + .short -2, 6, -13, 37, 115, -20, 9, -4 + .short -2, 5, -10, 27, 121, -17, 7, -3 + .short -1, 3, -6, 17, 125, -13, 5, -2 + .short 0, 1, -3, 8, 127, -7, 3, -1 +endconst + +const smooth_filter, align=4 + .short -3, -1, 32, 64, 38, 1, -3, 0 + .short -2, -2, 29, 63, 41, 2, -3, 0 + .short -2, -2, 26, 63, 43, 4, -4, 0 + .short -2, -3, 24, 62, 46, 5, -4, 0 + .short -2, -3, 21, 60, 49, 7, -4, 0 + .short -1, -4, 18, 59, 51, 9, -4, 0 + .short -1, -4, 16, 57, 53, 12, -4, -1 + .short -1, -4, 14, 55, 55, 14, -4, -1 + .short -1, -4, 12, 53, 57, 16, -4, -1 + .short 0, -4, 9, 51, 59, 18, -4, -1 + .short 0, -4, 7, 49, 60, 21, -3, -2 + .short 0, -4, 5, 46, 62, 24, -3, -2 + .short 0, -4, 4, 43, 63, 26, -2, -2 + .short 0, -3, 2, 41, 63, 29, -2, -2 + .short 0, -3, 1, 38, 64, 32, -1, -3 +endconst + +@ All public functions in this file have the following signature: +@ typedef void (*vp9_mc_func)(uint8_t *dst, ptrdiff_t dst_stride, +@ const uint8_t *ref, ptrdiff_t ref_stride, +@ int h, int mx, int my); + +function ff_vp9_copy64_neon, export=1 + ldr r12, [sp] + sub r1, r1, #32 + sub r3, r3, #32 +1: + vld1.8 {q0, q1}, [r2]! + vst1.8 {q0, q1}, [r0, :128]! + vld1.8 {q2, q3}, [r2], r3 + subs r12, r12, #1 + vst1.8 {q2, q3}, [r0, :128], r1 + bne 1b + bx lr +endfunc + +function ff_vp9_avg64_neon, export=1 + push {lr} + ldr r12, [sp, #4] + sub r1, r1, #32 + sub r3, r3, #32 + mov lr, r0 +1: + vld1.8 {q8, q9}, [r2]! + vld1.8 {q0, q1}, [r0, :128]! + vld1.8 {q10, q11}, [r2], r3 + vrhadd.u8 q0, q0, q8 + vld1.8 {q2, q3}, [r0, :128], r1 + vrhadd.u8 q1, q1, q9 + vrhadd.u8 q2, q2, q10 + vst1.8 {q0, q1}, [lr, :128]! + vrhadd.u8 q3, q3, q11 + vst1.8 {q2, q3}, [lr, :128], r1 + subs r12, r12, #1 + bne 1b + pop {pc} +endfunc + +function ff_vp9_copy32_neon, export=1 + ldr r12, [sp] +1: + vld1.8 {q0, q1}, [r2], r3 + subs r12, r12, #1 + vst1.8 {q0, q1}, [r0, :128], r1 + bne 1b + bx lr +endfunc + +function ff_vp9_avg32_neon, export=1 + ldr r12, [sp] +1: + vld1.8 {q2, q3}, [r2], r3 + vld1.8 {q0, q1}, [r0, :128] + vrhadd.u8 q0, q0, q2 + vrhadd.u8 q1, q1, q3 + subs r12, r12, #1 + vst1.8 {q0, q1}, [r0, :128], r1 + bne 1b + bx lr +endfunc + +function ff_vp9_copy16_neon, export=1 + push {r4,lr} + ldr r12, [sp, #8] + add r4, r0, r1 + add lr, r2, r3 + add r1, r1, r1 + add r3, r3, r3 +1: + vld1.8 {q0}, [r2], r3 + vld1.8 {q1}, [lr], r3 + subs r12, r12, #2 + vst1.8 {q0}, [r0, :128], r1 + vst1.8 {q1}, [r4, :128], r1 + bne 1b + pop {r4,pc} +endfunc + +function ff_vp9_avg16_neon, export=1 + ldr r12, [sp] +1: + vld1.8 {q2}, [r2], r3 + vld1.8 {q0}, [r0, :128], r1 + vld1.8 {q3}, [r2], r3 + vrhadd.u8 q0, q0, q2 + vld1.8 {q1}, [r0, :128] + sub r0, r0, r1 + vrhadd.u8 q1, q1, q3 + subs r12, r12, #2 + vst1.8 {q0}, [r0, :128], r1 + vst1.8 {q1}, [r0, :128], r1 + bne 1b + bx lr +endfunc + +function ff_vp9_copy8_neon, export=1 + ldr r12, [sp] +1: + vld1.8 {d0}, [r2], r3 + vld1.8 {d1}, [r2], r3 + subs r12, r12, #2 + vst1.8 {d0}, [r0, :64], r1 + vst1.8 {d1}, [r0, :64], r1 + bne 1b + bx lr +endfunc + +function ff_vp9_avg8_neon, export=1 + ldr r12, [sp] +1: + vld1.8 {d2}, [r2], r3 + vld1.8 {d0}, [r0, :64], r1 + vld1.8 {d3}, [r2], r3 + vrhadd.u8 d0, d0, d2 + vld1.8 {d1}, [r0, :64] + sub r0, r0, r1 + vrhadd.u8 d1, d1, d3 + subs r12, r12, #2 + vst1.8 {d0}, [r0, :64], r1 + vst1.8 {d1}, [r0, :64], r1 + bne 1b + bx lr +endfunc + +function ff_vp9_copy4_neon, export=1 + ldr r12, [sp] +1: + vld1.32 {d0[]}, [r2], r3 + vld1.32 {d1[]}, [r2], r3 + vst1.32 {d0[0]}, [r0, :32], r1 + vld1.32 {d2[]}, [r2], r3 + vst1.32 {d1[0]}, [r0, :32], r1 + vld1.32 {d3[]}, [r2], r3 + subs r12, r12, #4 + vst1.32 {d2[0]}, [r0, :32], r1 + vst1.32 {d3[0]}, [r0, :32], r1 + bne 1b + bx lr +endfunc + +function ff_vp9_avg4_neon, export=1 + ldr r12, [sp] +1: + vld1.32 {d4[]}, [r2], r3 + vld1.32 {d0[]}, [r0, :32], r1 + vld1.32 {d5[]}, [r2], r3 + vrhadd.u8 d0, d0, d4 + vld1.32 {d1[]}, [r0, :32], r1 + vld1.32 {d6[]}, [r2], r3 + vrhadd.u8 d1, d1, d5 + vld1.32 {d2[]}, [r0, :32], r1 + vld1.32 {d7[]}, [r2], r3 + vrhadd.u8 d2, d2, d6 + vld1.32 {d3[]}, [r0, :32], r1 + sub r0, r0, r1, lsl #2 + subs r12, r12, #4 + vst1.32 {d0[0]}, [r0, :32], r1 + vrhadd.u8 d3, d3, d7 + vst1.32 {d1[0]}, [r0, :32], r1 + vst1.32 {d2[0]}, [r0, :32], r1 + vst1.32 {d3[0]}, [r0, :32], r1 + bne 1b + bx lr +endfunc + +@ Helper macros for vmul/vmla with a constant from either d0 or d1 depending on index +.macro vmul_lane dst, src, idx +.if \idx < 4 + vmul.s16 \dst, \src, d0[\idx] +.else + vmul.s16 \dst, \src, d1[\idx - 4] +.endif +.endm +.macro vmla_lane dst, src, idx +.if \idx < 4 + vmla.s16 \dst, \src, d0[\idx] +.else + vmla.s16 \dst, \src, d1[\idx - 4] +.endif +.endm + +@ Extract a vector from src1-src2 and src4-src5 (src1-src3 and src4-src6 +@ for size >= 16), and multiply-accumulate into dst1 and dst3 (or +@ dst1-dst2 and dst3-dst4 for size >= 16) +.macro extmla dst1, dst2, dst3, dst4, src1, src2, src3, src4, src5, src6, offset, size + vext.8 q14, \src1, \src2, #(2*\offset) + vext.8 q15, \src4, \src5, #(2*\offset) +.if \size >= 16 + vmla_lane \dst1, q14, \offset + vext.8 q5, \src2, \src3, #(2*\offset) + vmla_lane \dst3, q15, \offset + vext.8 q6, \src5, \src6, #(2*\offset) + vmla_lane \dst2, q5, \offset + vmla_lane \dst4, q6, \offset +.else + vmla_lane \dst1, q14, \offset + vmla_lane \dst3, q15, \offset +.endif +.endm +@ The same as above, but don't accumulate straight into the +@ destination, but use a temp register and accumulate with saturation. +.macro extmulqadd dst1, dst2, dst3, dst4, src1, src2, src3, src4, src5, src6, offset, size + vext.8 q14, \src1, \src2, #(2*\offset) + vext.8 q15, \src4, \src5, #(2*\offset) +.if \size >= 16 + vmul_lane q14, q14, \offset + vext.8 q5, \src2, \src3, #(2*\offset) + vmul_lane q15, q15, \offset + vext.8 q6, \src5, \src6, #(2*\offset) + vmul_lane q5, q5, \offset + vmul_lane q6, q6, \offset +.else + vmul_lane q14, q14, \offset + vmul_lane q15, q15, \offset +.endif + vqadd.s16 \dst1, \dst1, q14 + vqadd.s16 \dst3, \dst3, q15 +.if \size >= 16 + vqadd.s16 \dst2, \dst2, q5 + vqadd.s16 \dst4, \dst4, q6 +.endif +.endm + + +@ Instantiate a horizontal filter function for the given size. +@ This can work on 4, 8 or 16 pixels in parallel; for larger +@ widths it will do 16 pixels at a time and loop horizontally. +@ The actual width is passed in r5, the height in r4 and +@ the filter coefficients in r12. idx2 is the index of the largest +@ filter coefficient (3 or 4) and idx1 is the other one of them. +.macro do_8tap_h type, size, idx1, idx2 +function \type\()_8tap_\size\()h_\idx1\idx2 + sub r2, r2, #3 + add r6, r0, r1 + add r7, r2, r3 + add r1, r1, r1 + add r3, r3, r3 + @ Only size >= 16 loops horizontally and needs + @ reduced dst stride +.if \size >= 16 + sub r1, r1, r5 +.endif + @ size >= 16 loads two qwords and increments r2, + @ for size 4/8 it's enough with one qword and no + @ postincrement +.if \size >= 16 + sub r3, r3, r5 + sub r3, r3, #8 +.endif + @ Load the filter vector + vld1.16 {q0}, [r12,:128] +1: +.if \size >= 16 + mov r12, r5 +.endif + @ Load src +.if \size >= 16 + vld1.8 {d18, d19, d20}, [r2]! + vld1.8 {d24, d25, d26}, [r7]! +.else + vld1.8 {q9}, [r2] + vld1.8 {q12}, [r7] +.endif + vmovl.u8 q8, d18 + vmovl.u8 q9, d19 + vmovl.u8 q11, d24 + vmovl.u8 q12, d25 +.if \size >= 16 + vmovl.u8 q10, d20 + vmovl.u8 q13, d26 +.endif +2: + + @ Accumulate, adding idx2 last with a separate + @ saturating add. The positive filter coefficients + @ for all indices except idx2 must add up to less + @ than 127 for this not to overflow. + vmul.s16 q1, q8, d0[0] + vmul.s16 q3, q11, d0[0] +.if \size >= 16 + vmul.s16 q2, q9, d0[0] + vmul.s16 q4, q12, d0[0] +.endif + extmla q1, q2, q3, q4, q8, q9, q10, q11, q12, q13, 1, \size + extmla q1, q2, q3, q4, q8, q9, q10, q11, q12, q13, 2, \size + extmla q1, q2, q3, q4, q8, q9, q10, q11, q12, q13, \idx1, \size + extmla q1, q2, q3, q4, q8, q9, q10, q11, q12, q13, 5, \size + extmla q1, q2, q3, q4, q8, q9, q10, q11, q12, q13, 6, \size + extmla q1, q2, q3, q4, q8, q9, q10, q11, q12, q13, 7, \size + extmulqadd q1, q2, q3, q4, q8, q9, q10, q11, q12, q13, \idx2, \size + + @ Round, shift and saturate + vqrshrun.s16 d2, q1, #7 + vqrshrun.s16 d6, q3, #7 +.if \size >= 16 + vqrshrun.s16 d3, q2, #7 + vqrshrun.s16 d7, q4, #7 +.endif + @ Average +.ifc \type,avg +.if \size >= 16 + vld1.8 {q14}, [r0,:128] + vld1.8 {q15}, [r6,:128] + vrhadd.u8 q1, q1, q14 + vrhadd.u8 q3, q3, q15 +.elseif \size == 8 + vld1.8 {d28}, [r0,:64] + vld1.8 {d30}, [r6,:64] + vrhadd.u8 d2, d2, d28 + vrhadd.u8 d6, d6, d30 +.else + @ We only need d28[0], but [] is faster on some cores + vld1.32 {d28[]}, [r0,:32] + vld1.32 {d30[]}, [r6,:32] + vrhadd.u8 d2, d2, d28 + vrhadd.u8 d6, d6, d30 +.endif +.endif + @ Store and loop horizontally (for size >= 16) +.if \size >= 16 + vst1.8 {q1}, [r0,:128]! + vst1.8 {q3}, [r6,:128]! + vmov q8, q10 + vmov q11, q13 + subs r12, r12, #16 + beq 3f + vld1.8 {q10}, [r2]! + vld1.8 {q13}, [r7]! + vmovl.u8 q9, d20 + vmovl.u8 q10, d21 + vmovl.u8 q12, d26 + vmovl.u8 q13, d27 + b 2b +.elseif \size == 8 + vst1.8 {d2}, [r0,:64] + vst1.8 {d6}, [r6,:64] +.else @ \size == 4 + vst1.32 {d2[0]}, [r0,:32] + vst1.32 {d6[0]}, [r6,:32] +.endif +3: + @ Loop vertically + add r0, r0, r1 + add r6, r6, r1 + add r2, r2, r3 + add r7, r7, r3 + subs r4, r4, #2 + bne 1b +.if \size >= 16 + vpop {q4-q6} +.endif + pop {r4-r7} + bx lr +endfunc +.endm + +.macro do_8tap_h_size size +do_8tap_h put, \size, 3, 4 +do_8tap_h avg, \size, 3, 4 +do_8tap_h put, \size, 4, 3 +do_8tap_h avg, \size, 4, 3 +.endm + +do_8tap_h_size 4 +do_8tap_h_size 8 +do_8tap_h_size 16 + +.macro do_8tap_h_func type, filter, size +function ff_vp9_\type\()_\filter\()\size\()_h_neon, export=1 + push {r4-r7} +.if \size >= 16 + vpush {q4-q6} + ldr r4, [sp, #64] + ldr r5, [sp, #68] +.else + ldr r4, [sp, #16] + ldr r5, [sp, #20] +.endif + movrel r12, \filter\()_filter-16 + cmp r5, #8 + add r12, r12, r5, lsl #4 + mov r5, #\size +.if \size >= 16 + bge \type\()_8tap_16h_34 + b \type\()_8tap_16h_43 +.else + bge \type\()_8tap_\size\()h_34 + b \type\()_8tap_\size\()h_43 +.endif +endfunc +.endm + +.macro do_8tap_h_filters size +do_8tap_h_func put, regular, \size +do_8tap_h_func avg, regular, \size +do_8tap_h_func put, sharp, \size +do_8tap_h_func avg, sharp, \size +do_8tap_h_func put, smooth, \size +do_8tap_h_func avg, smooth, \size +.endm + +do_8tap_h_filters 64 +do_8tap_h_filters 32 +do_8tap_h_filters 16 +do_8tap_h_filters 8 +do_8tap_h_filters 4 + + +@ Vertical filters + +@ Round, shift and saturate and store qreg1-2 over 4 lines +.macro do_store4 qreg1, dreg1, qreg2, dreg2, tmp1, tmp2, type + vqrshrun.s16 \dreg1, \qreg1, #7 + vqrshrun.s16 \dreg2, \qreg2, #7 +.ifc \type,avg + vld1.32 {\tmp1[]}, [r0,:32], r1 + vld1.32 {\tmp2[]}, [r0,:32], r1 + vld1.32 {\tmp1[1]}, [r0,:32], r1 + vld1.32 {\tmp2[1]}, [r0,:32], r1 + vrhadd.u8 \dreg1, \dreg1, \tmp1 + vrhadd.u8 \dreg2, \dreg2, \tmp2 + sub r0, r0, r1, lsl #2 +.endif + vst1.32 {\dreg1[0]}, [r0,:32], r1 + vst1.32 {\dreg2[0]}, [r0,:32], r1 + vst1.32 {\dreg1[1]}, [r0,:32], r1 + vst1.32 {\dreg2[1]}, [r0,:32], r1 +.endm + +@ Round, shift and saturate and store qreg1-4 +.macro do_store qreg1, dreg1, qreg2, dreg2, qreg3, dreg3, qreg4, dreg4, tmp1, tmp2, tmp3, tmp4, type + vqrshrun.s16 \dreg1, \qreg1, #7 + vqrshrun.s16 \dreg2, \qreg2, #7 + vqrshrun.s16 \dreg3, \qreg3, #7 + vqrshrun.s16 \dreg4, \qreg4, #7 +.ifc \type,avg + vld1.8 {\tmp1}, [r0,:64], r1 + vld1.8 {\tmp2}, [r0,:64], r1 + vld1.8 {\tmp3}, [r0,:64], r1 + vld1.8 {\tmp4}, [r0,:64], r1 + vrhadd.u8 \dreg1, \dreg1, \tmp1 + vrhadd.u8 \dreg2, \dreg2, \tmp2 + vrhadd.u8 \dreg3, \dreg3, \tmp3 + vrhadd.u8 \dreg4, \dreg4, \tmp4 + sub r0, r0, r1, lsl #2 +.endif + vst1.8 {\dreg1}, [r0,:64], r1 + vst1.8 {\dreg2}, [r0,:64], r1 + vst1.8 {\dreg3}, [r0,:64], r1 + vst1.8 {\dreg4}, [r0,:64], r1 +.endm + +@ Evaluate the filter twice in parallel, from the inputs src1-src9 into dst1-dst2 +@ (src1-src8 into dst1, src2-src9 into dst2), adding idx2 separately +@ at the end with saturation. Indices 0 and 7 always have negative or zero +@ coefficients, so they can be accumulated into tmp1-tmp2 together with the +@ largest coefficient. +.macro convolve dst1, dst2, src1, src2, src3, src4, src5, src6, src7, src8, src9, idx1, idx2, tmp1, tmp2 + vmul.s16 \dst1, \src2, d0[1] + vmul.s16 \dst2, \src3, d0[1] + vmul.s16 \tmp1, \src1, d0[0] + vmul.s16 \tmp2, \src2, d0[0] + vmla.s16 \dst1, \src3, d0[2] + vmla.s16 \dst2, \src4, d0[2] +.if \idx1 == 3 + vmla.s16 \dst1, \src4, d0[3] + vmla.s16 \dst2, \src5, d0[3] +.else + vmla.s16 \dst1, \src5, d1[0] + vmla.s16 \dst2, \src6, d1[0] +.endif + vmla.s16 \dst1, \src6, d1[1] + vmla.s16 \dst2, \src7, d1[1] + vmla.s16 \tmp1, \src8, d1[3] + vmla.s16 \tmp2, \src9, d1[3] + vmla.s16 \dst1, \src7, d1[2] + vmla.s16 \dst2, \src8, d1[2] +.if \idx2 == 3 + vmla.s16 \tmp1, \src4, d0[3] + vmla.s16 \tmp2, \src5, d0[3] +.else + vmla.s16 \tmp1, \src5, d1[0] + vmla.s16 \tmp2, \src6, d1[0] +.endif + vqadd.s16 \dst1, \dst1, \tmp1 + vqadd.s16 \dst2, \dst2, \tmp2 +.endm + +@ Load pixels and extend them to 16 bit +.macro loadl dst1, dst2, dst3, dst4 + vld1.8 {d2}, [r2], r3 + vld1.8 {d3}, [r2], r3 + vld1.8 {d4}, [r2], r3 +.ifnb \dst4 + vld1.8 {d5}, [r2], r3 +.endif + vmovl.u8 \dst1, d2 + vmovl.u8 \dst2, d3 + vmovl.u8 \dst3, d4 +.ifnb \dst4 + vmovl.u8 \dst4, d5 +.endif +.endm + +@ Instantiate a vertical filter function for filtering 8 pixels at a time. +@ The height is passed in r4, the width in r5 and the filter coefficients +@ in r12. idx2 is the index of the largest filter coefficient (3 or 4) +@ and idx1 is the other one of them. +.macro do_8tap_8v type, idx1, idx2 +function \type\()_8tap_8v_\idx1\idx2 + sub r2, r2, r3, lsl #1 + sub r2, r2, r3 + vld1.16 {q0}, [r12, :128] +1: + mov r12, r4 + + loadl q5, q6, q7 + loadl q8, q9, q10, q11 +2: + loadl q12, q13, q14, q15 + convolve q1, q2, q5, q6, q7, q8, q9, q10, q11, q12, q13, \idx1, \idx2, q4, q5 + convolve q3, q4, q7, q8, q9, q10, q11, q12, q13, q14, q15, \idx1, \idx2, q5, q6 + do_store q1, d2, q2, d4, q3, d6, q4, d8, d3, d5, d7, d9, \type + + subs r12, r12, #4 + beq 8f + + loadl q4, q5, q6, q7 + convolve q1, q2, q9, q10, q11, q12, q13, q14, q15, q4, q5, \idx1, \idx2, q8, q9 + convolve q3, q8, q11, q12, q13, q14, q15, q4, q5, q6, q7, \idx1, \idx2, q9, q10 + do_store q1, d2, q2, d4, q3, d6, q8, d16, d3, d5, d7, d17, \type + + subs r12, r12, #4 + beq 8f + + loadl q8, q9, q10, q11 + convolve q1, q2, q13, q14, q15, q4, q5, q6, q7, q8, q9, \idx1, \idx2, q12, q13 + convolve q3, q12, q15, q4, q5, q6, q7, q8, q9, q10, q11, \idx1, \idx2, q13, q14 + do_store q1, d2, q2, d4, q3, d6, q12, d24, d3, d5, d7, d25, \type + + subs r12, r12, #4 + bne 2b + +8: + subs r5, r5, #8 + beq 9f + @ r0 -= h * dst_stride + mls r0, r1, r4, r0 + @ r2 -= h * src_stride + mls r2, r3, r4, r2 + @ r2 -= 8 * src_stride + sub r2, r2, r3, lsl #3 + @ r2 += 1 * src_stride + add r2, r2, r3 + add r2, r2, #8 + add r0, r0, #8 + b 1b +9: + vpop {q4-q7} + pop {r4-r5} + bx lr +endfunc +.endm + +do_8tap_8v put, 3, 4 +do_8tap_8v put, 4, 3 +do_8tap_8v avg, 3, 4 +do_8tap_8v avg, 4, 3 + +@ Instantiate a vertical filter function for filtering a 4 pixels wide +@ slice. The first half of the registers contain one row, while the second +@ half of a register contains the second-next row (also stored in the first +@ half of the register two steps ahead). The convolution does two outputs +@ at a time; the output of q5-q12 into one, and q4-q13 into another one. +@ The first half of first output is the first output row, the first half +@ of the other output is the second output row. The second halves of the +@ registers are rows 3 and 4. +@ This only is designed to work for 4 or 8 output lines. +.macro do_8tap_4v type, idx1, idx2 +function \type\()_8tap_4v_\idx1\idx2 + sub r2, r2, r3, lsl #1 + sub r2, r2, r3 + vld1.16 {q0}, [r12, :128] + + vld1.32 {d2[]}, [r2], r3 + vld1.32 {d3[]}, [r2], r3 + vld1.32 {d4[]}, [r2], r3 + vld1.32 {d5[]}, [r2], r3 + vld1.32 {d6[]}, [r2], r3 + vld1.32 {d7[]}, [r2], r3 + vext.8 d2, d2, d4, #4 + vld1.32 {d8[]}, [r2], r3 + vext.8 d3, d3, d5, #4 + vld1.32 {d9[]}, [r2], r3 + vmovl.u8 q5, d2 + vext.8 d4, d4, d6, #4 + vld1.32 {d28[]}, [r2], r3 + vmovl.u8 q6, d3 + vext.8 d5, d5, d7, #4 + vld1.32 {d29[]}, [r2], r3 + vmovl.u8 q7, d4 + vext.8 d6, d6, d8, #4 + vld1.32 {d30[]}, [r2], r3 + vmovl.u8 q8, d5 + vext.8 d7, d7, d9, #4 + vmovl.u8 q9, d6 + vext.8 d8, d8, d28, #4 + vmovl.u8 q10, d7 + vext.8 d9, d9, d29, #4 + vmovl.u8 q11, d8 + vext.8 d28, d28, d30, #4 + vmovl.u8 q12, d9 + vmovl.u8 q13, d28 + + convolve q1, q2, q5, q6, q7, q8, q9, q10, q11, q12, q13, \idx1, \idx2, q4, q3 + do_store4 q1, d2, q2, d4, d3, d5, \type + subs r4, r4, #4 + beq 9f + + vld1.32 {d2[]}, [r2], r3 + vld1.32 {d3[]}, [r2], r3 + vext.8 d29, d29, d2, #4 + vext.8 d30, d30, d3, #4 + vld1.32 {d2[1]}, [r2], r3 + vmovl.u8 q14, d29 + vld1.32 {d3[1]}, [r2], r3 + vmovl.u8 q15, d30 + vmovl.u8 q5, d2 + vmovl.u8 q6, d3 + + convolve q1, q2, q9, q10, q11, q12, q13, q14, q15, q5, q6, \idx1, \idx2, q4, q3 + do_store4 q1, d2, q2, d4, d3, d5, \type + +9: + vpop {q4-q7} + pop {r4-r5} + bx lr +endfunc +.endm + +do_8tap_4v put, 3, 4 +do_8tap_4v put, 4, 3 +do_8tap_4v avg, 3, 4 +do_8tap_4v avg, 4, 3 + +.macro do_8tap_v_func type, filter, size +function ff_vp9_\type\()_\filter\()\size\()_v_neon, export=1 + push {r4-r5} + vpush {q4-q7} + ldr r4, [sp, #72] + ldr r5, [sp, #80] + movrel r12, \filter\()_filter-16 + add r12, r12, r5, lsl #4 + cmp r5, #8 + mov r5, #\size +.if \size >= 8 + bge \type\()_8tap_8v_34 + b \type\()_8tap_8v_43 +.else + bge \type\()_8tap_4v_34 + b \type\()_8tap_4v_43 +.endif +endfunc +.endm + +.macro do_8tap_v_filters size +do_8tap_v_func put, regular, \size +do_8tap_v_func avg, regular, \size +do_8tap_v_func put, sharp, \size +do_8tap_v_func avg, sharp, \size +do_8tap_v_func put, smooth, \size +do_8tap_v_func avg, smooth, \size +.endm + +do_8tap_v_filters 64 +do_8tap_v_filters 32 +do_8tap_v_filters 16 +do_8tap_v_filters 8 +do_8tap_v_filters 4 diff --git a/libavcodec/vp9.h b/libavcodec/vp9.h index 84bed6daaf63f..e4b9f82689376 100644 --- a/libavcodec/vp9.h +++ b/libavcodec/vp9.h @@ -420,7 +420,8 @@ typedef struct VP9Context { // whole-frame cache uint8_t *intra_pred_data[3]; VP9Filter *lflvl; - DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[71 * 80]; + // This requires 64 + 8 rows, with 80 bytes stride + DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[72 * 80]; // block reconstruction intermediates int16_t *block_base, *block, *uvblock_base[2], *uvblock[2]; @@ -432,6 +433,7 @@ typedef struct VP9Context { void ff_vp9dsp_init(VP9DSPContext *dsp); +void ff_vp9dsp_init_arm(VP9DSPContext *dsp); void ff_vp9dsp_init_x86(VP9DSPContext *dsp); void ff_vp9_fill_mv(VP9Context *s, VP56mv *mv, int mode, int sb); diff --git a/libavcodec/vp9block.c b/libavcodec/vp9block.c index 5a3b35649fc01..54f76d6e1c461 100644 --- a/libavcodec/vp9block.c +++ b/libavcodec/vp9block.c @@ -1176,8 +1176,11 @@ static av_always_inline void mc_luma_dir(VP9Context *s, vp9_mc_func(*mc)[2], ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); // FIXME bilinear filter only needs 0/1 pixels, not 3/4 + // The arm _hv filters read one more row than what actually is + // needed, so switch to emulated edge one pixel sooner vertically + // (!!my * 5) than horizontally (!!mx * 4). if (x < !!mx * 3 || y < !!my * 3 || - x + !!mx * 4 > w - bw || y + !!my * 4 > h - bh) { + x + !!mx * 4 > w - bw || y + !!my * 5 > h - bh) { s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ref - !!my * 3 * ref_stride - !!mx * 3, 80, @@ -1218,8 +1221,11 @@ static av_always_inline void mc_chroma_dir(VP9Context *s, vp9_mc_func(*mc)[2], ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); // FIXME bilinear filter only needs 0/1 pixels, not 3/4 + // The arm _hv filters read one more row than what actually is + // needed, so switch to emulated edge one pixel sooner vertically + // (!!my * 5) than horizontally (!!mx * 4). if (x < !!mx * 3 || y < !!my * 3 || - x + !!mx * 4 > w - bw || y + !!my * 4 > h - bh) { + x + !!mx * 4 > w - bw || y + !!my * 5 > h - bh) { s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ref_u - !!my * 3 * src_stride_u - !!mx * 3, 80, diff --git a/libavcodec/vp9dsp.c b/libavcodec/vp9dsp.c index af93c0d4ea8d1..0eca389de65f4 100644 --- a/libavcodec/vp9dsp.c +++ b/libavcodec/vp9dsp.c @@ -2164,6 +2164,8 @@ av_cold void ff_vp9dsp_init(VP9DSPContext *dsp) vp9dsp_loopfilter_init(dsp); vp9dsp_mc_init(dsp); + if (ARCH_ARM) + ff_vp9dsp_init_arm(dsp); if (ARCH_X86) ff_vp9dsp_init_x86(dsp); } From 1a469a5e423bdad779b8534247dea8cc86169b88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 3 Nov 2016 10:39:24 +0200 Subject: [PATCH 0386/3374] options_table: Remove a now unnecessary include of config.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The include of config.h was added in 2012 in 1d9c2dc8, due to the use of CONFIG_SNOW_ENCODER ifdefs within options_table.h. When the snow codec was dropped later (in a0c5917f8 in 2013), this include no longer served any purpose. options_table.h is included in builds for the host as well, when building documentation. config.h should not be included in code that is built for the host, since it can contain workarounds for the target compiler/environment, like adding a missing define of restrict, defining getenv(x) to NULL for environments that lack getenv. The seemingly innocent include reordering in 2025d37871 broke builds that have getenv(x) defined to NULL in config.h (Windows CE and Windows Phone/RT), since libavcodec/options_table.h include config.h, while libavformat/options_table.h end up bringing in more system headers, and those system headers can contain a proper definition of getenv, which clash with the getenv define in config.h. This was avoided earlier as long as libavformat/options_table.h (or avformat.h) was included before libavcodec/options_table.h. This fixes builds for Windows Phone/RT and CE. Signed-off-by: Martin Storsjö --- libavcodec/options_table.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index 04cb20d1544d5..b1f9a9235c709 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -26,7 +26,6 @@ #include "libavutil/opt.h" #include "avcodec.h" #include "version.h" -#include "config.h" #define OFFSET(x) offsetof(AVCodecContext,x) #define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C From ee59f0540875ab42496af2aacddd942757707683 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 20 Sep 2016 16:00:15 +0200 Subject: [PATCH 0387/3374] intrax8: Have function signature match across declaration and definition libavcodec/intrax8.c(776) : warning C4028: formal parameter 1 different from declaration --- libavcodec/intrax8.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/intrax8.c b/libavcodec/intrax8.c index 9c20c8f285fcf..2a73a072dbfe1 100644 --- a/libavcodec/intrax8.c +++ b/libavcodec/intrax8.c @@ -769,7 +769,7 @@ av_cold void ff_intrax8_common_end(IntraX8Context *w) av_freep(&w->prediction_table); } -int ff_intrax8_decode_picture(IntraX8Context *const w, Picture *pict, +int ff_intrax8_decode_picture(IntraX8Context *w, Picture *pict, GetBitContext *gb, int *mb_x, int *mb_y, int dquant, int quant_offset, int loopfilter, int lowdelay) From 13fcdfb976038f63b9f753e2ebcc8e04d7c7abc2 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 31 Oct 2016 23:49:12 +0100 Subject: [PATCH 0388/3374] svq3: Drop unused function dctcoef_get() libavcodec/svq3.c:627:29: warning: unused function 'dctcoef_get' [-Wunused-function] --- libavcodec/svq3.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index aa85e7c59f5c3..51657372ae8cf 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -622,11 +622,6 @@ static av_always_inline void hl_decode_mb_idct_luma(SVQ3Context *s, } } -static av_always_inline int dctcoef_get(int16_t *mb, int index) -{ - return AV_RN16A(mb + index); -} - static av_always_inline void hl_decode_mb_predict_luma(SVQ3Context *s, int mb_type, const int *block_offset, From 67c65e461cb073d61ffbc78845d4a3d8f14bf481 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Thu, 3 Nov 2016 16:33:25 +0000 Subject: [PATCH 0389/3374] vf_hwupload_cuda: Fix build error Broken by e3fb74f7f9a8f1895381355f40c92cac3c1023d9. Signed-off-by: Diego Biurrun --- libavfilter/vf_hwupload_cuda.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_hwupload_cuda.c b/libavfilter/vf_hwupload_cuda.c index 94d5013cc6ac0..b5631c2b86e2d 100644 --- a/libavfilter/vf_hwupload_cuda.c +++ b/libavfilter/vf_hwupload_cuda.c @@ -151,7 +151,7 @@ static int cudaupload_config_output(AVFilterLink *outlink) static int cudaupload_filter_frame(AVFilterLink *link, AVFrame *in) { AVFilterContext *ctx = link->dst; - CudaUploadContext *s = ctx->priv; + AVFilterLink *outlink = ctx->outputs[0]; AVFrame *out = NULL; int ret; From 99ddeddc7fc996c0c1e842112928490e78542bd5 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 31 Oct 2016 23:06:54 +0100 Subject: [PATCH 0390/3374] ituh263dec: Have function signature match across declaration and definition libavcodec/ituh263dec.c(215) : warning C4028: formal parameter 1 different from declaration libavcodec/ituh263dec.c(215) : warning C4028: formal parameter 2 different from declaration --- libavcodec/h263.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libavcodec/h263.h b/libavcodec/h263.h index 42c78f4c0e518..3e54204f0fcb6 100644 --- a/libavcodec/h263.h +++ b/libavcodec/h263.h @@ -21,7 +21,11 @@ #define AVCODEC_H263_H #include + +#include "config.h" + #include "libavutil/rational.h" + #include "get_bits.h" #include "mpegvideo.h" #include "h263data.h" @@ -95,7 +99,7 @@ int av_const h263_get_picture_format(int width, int height); void ff_clean_h263_qscales(MpegEncContext *s); int ff_h263_resync(MpegEncContext *s); -const uint8_t *ff_h263_find_resync_marker(const uint8_t *p, const uint8_t *end); +const uint8_t *ff_h263_find_resync_marker(const uint8_t *restrict p, const uint8_t *restrict end); void ff_h263_encode_motion(MpegEncContext * s, int val, int f_code); From c778eb15b89d875cb246b18f65b3b4321cb1e7d6 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 31 Oct 2016 23:12:20 +0100 Subject: [PATCH 0391/3374] pixblockdsp: Have function pointer prototype match implementation libavcodec/pixblockdsp.c(58) : warning C4028: formal parameter 1 different from declaration libavcodec/pixblockdsp.c(63) : warning C4028: formal parameter 1 different from declaration libavcodec/pixblockdsp.c(66) : warning C4028: formal parameter 1 different from declaration --- libavcodec/pixblockdsp.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/pixblockdsp.h b/libavcodec/pixblockdsp.h index a9d5473665eb1..c7587cba16f0c 100644 --- a/libavcodec/pixblockdsp.h +++ b/libavcodec/pixblockdsp.h @@ -21,13 +21,15 @@ #include +#include "config.h" + #include "avcodec.h" typedef struct PixblockDSPContext { - void (*get_pixels)(int16_t *block /* align 16 */, + void (*get_pixels)(int16_t *restrict block /* align 16 */, const uint8_t *pixels /* align 8 */, ptrdiff_t stride); - void (*diff_pixels)(int16_t *block /* align 16 */, + void (*diff_pixels)(int16_t *restrict block /* align 16 */, const uint8_t *s1 /* align 8 */, const uint8_t *s2 /* align 8 */, ptrdiff_t stride); From 6354957a95022864746180525680cca872ab0e0a Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 1 Nov 2016 00:30:33 +0100 Subject: [PATCH 0392/3374] dnxhdenc: Have function pointer prototype match implementation libavcodec/dnxhdenc.c(326) : warning C4028: formal parameter 1 different from declaration libavcodec/dnxhdenc.c(329) : warning C4028: formal parameter 1 different from declaration --- libavcodec/dnxhdenc.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/dnxhdenc.h b/libavcodec/dnxhdenc.h index d3df0e00018bb..c6755f7b59c74 100644 --- a/libavcodec/dnxhdenc.h +++ b/libavcodec/dnxhdenc.h @@ -26,6 +26,8 @@ #include +#include "config.h" + #include "mpegvideo.h" #include "dnxhddata.h" @@ -93,8 +95,8 @@ typedef struct DNXHDEncContext { RCCMPEntry *mb_cmp; RCEntry (*mb_rc)[8160]; - void (*get_pixels_8x4_sym)(int16_t * /* align 16 */, - const uint8_t *, ptrdiff_t); + void (*get_pixels_8x4_sym)(int16_t *restrict /* align 16 */ block, + const uint8_t *pixels, ptrdiff_t line_size); } DNXHDEncContext; void ff_dnxhdenc_init_x86(DNXHDEncContext *ctx); From 99434f4df81b6801b2b535d5b9143305595784f6 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 1 Nov 2016 00:33:05 +0100 Subject: [PATCH 0393/3374] float_dsp: Have implementation match function pointer prototype libavutil/x86/float_dsp_init.c(144) : warning C4028: formal parameter 1 different from declaration libavutil/x86/float_dsp_init.c(144) : warning C4028: formal parameter 2 different from declaration --- libavutil/x86/float_dsp_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavutil/x86/float_dsp_init.c b/libavutil/x86/float_dsp_init.c index b70433031a8ce..dcbe3f1f3cdc9 100644 --- a/libavutil/x86/float_dsp_init.c +++ b/libavutil/x86/float_dsp_init.c @@ -54,7 +54,7 @@ void ff_vector_fmul_reverse_avx(float *dst, const float *src0, float ff_scalarproduct_float_sse(const float *v1, const float *v2, int order); -void ff_butterflies_float_sse(float *src0, float *src1, int len); +void ff_butterflies_float_sse(float *restrict src0, float *restrict src1, int len); #if HAVE_6REGS && HAVE_INLINE_ASM static void vector_fmul_window_3dnowext(float *dst, const float *src0, From 67351924fa91dea4339109100a4c0689f006581f Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 13 Mar 2015 00:39:31 +0100 Subject: [PATCH 0394/3374] Drop unreachable break and return statements --- libavcodec/bmvvideo.c | 1 - libavcodec/hevc_sei.c | 1 - libavcodec/indeo3.c | 2 -- libavcodec/sanm.c | 3 --- libavformat/rtpproto.c | 1 - libavformat/rtspdec.c | 1 - libavformat/smush.c | 1 - libavutil/opt.c | 2 -- 8 files changed, 12 deletions(-) diff --git a/libavcodec/bmvvideo.c b/libavcodec/bmvvideo.c index f4b8f29f55e4b..4fb42f0f5c2fd 100644 --- a/libavcodec/bmvvideo.c +++ b/libavcodec/bmvvideo.c @@ -191,7 +191,6 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame, if (dst == dst_end) return 0; } - return 0; } static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c index 8865cecdeda99..8c913f93a7494 100644 --- a/libavcodec/hevc_sei.c +++ b/libavcodec/hevc_sei.c @@ -173,7 +173,6 @@ static int decode_nal_sei_message(HEVCContext *s) } else { /* nal_unit_type == NAL_SEI_SUFFIX */ return decode_nal_sei_suffix(s, payload_type, payload_size); } - return 0; } static int more_rbsp_data(GetBitContext *gb) diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c index 89c11e63467ed..314548f99aba5 100644 --- a/libavcodec/indeo3.c +++ b/libavcodec/indeo3.c @@ -831,8 +831,6 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, break; } }//while - - return 0; } diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c index 3d231957aed84..7b0004925cf9a 100644 --- a/libavcodec/sanm.c +++ b/libavcodec/sanm.c @@ -926,13 +926,10 @@ static int process_frame_obj(SANMVideoContext *ctx) case 1: case 3: return old_codec1(ctx, top, left, w, h); - break; case 37: return old_codec37(ctx, top, left, w, h); - break; case 47: return old_codec47(ctx, top, left, w, h); - break; default: avpriv_request_sample(ctx->avctx, "Subcodec %d", codec); return AVERROR_PATCHWELCOME; diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c index 6582e4ad7660b..21a96d217d711 100644 --- a/libavformat/rtpproto.c +++ b/libavformat/rtpproto.c @@ -436,7 +436,6 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size) if (h->flags & AVIO_FLAG_NONBLOCK) return AVERROR(EAGAIN); } - return len; } static int rtp_write(URLContext *h, const uint8_t *buf, int size) diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c index 03374dc0e619a..8e8b3403e5a46 100644 --- a/libavformat/rtspdec.c +++ b/libavformat/rtspdec.c @@ -700,7 +700,6 @@ static int rtsp_listen(AVFormatContext *s) return AVERROR_INVALIDDATA; } } - return 0; } static int rtsp_probe(AVProbeData *p) diff --git a/libavformat/smush.c b/libavformat/smush.c index 262b9412411ee..817e736bf7d32 100644 --- a/libavformat/smush.c +++ b/libavformat/smush.c @@ -129,7 +129,6 @@ static int smush_read_header(AVFormatContext *ctx) break; default: return AVERROR_INVALIDDATA; - break; } } diff --git a/libavutil/opt.c b/libavutil/opt.c index 7cb3d66557c2f..44d62991174ac 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -240,8 +240,6 @@ static int set_string_number(void *obj, void *target_obj, const AVOption *o, con return 0; notfirst = 1; } - - return 0; } int av_opt_set(void *obj, const char *name, const char *val, int search_flags) From d06aa24ba583ad08025da9e1b29afcd8218ff9b0 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Tue, 25 Oct 2016 20:38:47 +0100 Subject: [PATCH 0395/3374] hwcontext: Hardware frame mapping Adds the new av_hwframe_map() function, which allows mapping between hardware frames and normal memory, along with internal support for implementing it. Also adds av_hwframe_ctx_create_derived(), for creating a hardware frames context associated with one device using frames mapped from another by some hardware-specific means. --- doc/APIchanges | 4 + libavutil/hwcontext.c | 239 ++++++++++++++++++++++++++++++++- libavutil/hwcontext.h | 87 ++++++++++++ libavutil/hwcontext_internal.h | 40 ++++++ libavutil/version.h | 2 +- 5 files changed, 365 insertions(+), 7 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 011ff0a6ebbc3..735b9477ace27 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,10 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-xx-xx - xxxxxxx - lavu 55.27.0 - hwcontext.h + Add av_hwframe_map() and associated AV_HWFRAME_MAP_* flags. + Add av_hwframe_ctx_create_derived(). + 2016-xx-xx - xxxxxxx - lavu 55.25.0 - pixfmt.h Add AV_PIX_FMT_GBRAP12(LE/BE). diff --git a/libavutil/hwcontext.c b/libavutil/hwcontext.c index b47ef44fa71c7..83f733e9f95f8 100644 --- a/libavutil/hwcontext.c +++ b/libavutil/hwcontext.c @@ -157,14 +157,19 @@ static void hwframe_ctx_free(void *opaque, uint8_t *data) { AVHWFramesContext *ctx = (AVHWFramesContext*)data; - if (ctx->internal->pool_internal) - av_buffer_pool_uninit(&ctx->internal->pool_internal); + if (ctx->internal->source_frames) { + av_buffer_unref(&ctx->internal->source_frames); - if (ctx->internal->hw_type->frames_uninit) - ctx->internal->hw_type->frames_uninit(ctx); + } else { + if (ctx->internal->pool_internal) + av_buffer_pool_uninit(&ctx->internal->pool_internal); - if (ctx->free) - ctx->free(ctx); + if (ctx->internal->hw_type->frames_uninit) + ctx->internal->hw_type->frames_uninit(ctx); + + if (ctx->free) + ctx->free(ctx); + } av_buffer_unref(&ctx->device_ref); @@ -266,6 +271,11 @@ int av_hwframe_ctx_init(AVBufferRef *ref) const enum AVPixelFormat *pix_fmt; int ret; + if (ctx->internal->source_frames) { + /* A derived frame context is already initialised. */ + return 0; + } + /* validate the pixel format */ for (pix_fmt = ctx->internal->hw_type->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++) { if (*pix_fmt == ctx->format) @@ -396,6 +406,35 @@ int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags) AVHWFramesContext *ctx = (AVHWFramesContext*)hwframe_ref->data; int ret; + if (ctx->internal->source_frames) { + // This is a derived frame context, so we allocate in the source + // and map the frame immediately. + AVFrame *src_frame; + + src_frame = av_frame_alloc(); + if (!src_frame) + return AVERROR(ENOMEM); + + ret = av_hwframe_get_buffer(ctx->internal->source_frames, + src_frame, 0); + if (ret < 0) + return ret; + + ret = av_hwframe_map(frame, src_frame, 0); + if (ret) { + av_log(ctx, AV_LOG_ERROR, "Failed to map frame into derived " + "frame context: %d.\n", ret); + av_frame_free(&src_frame); + return ret; + } + + // Free the source frame immediately - the mapped frame still + // contains a reference to it. + av_frame_free(&src_frame); + + return 0; + } + if (!ctx->internal->hw_type->frames_get_buffer) return AVERROR(ENOSYS); @@ -495,3 +534,191 @@ int av_hwdevice_ctx_create(AVBufferRef **pdevice_ref, enum AVHWDeviceType type, *pdevice_ref = NULL; return ret; } + +static void ff_hwframe_unmap(void *opaque, uint8_t *data) +{ + HWMapDescriptor *hwmap = (HWMapDescriptor*)data; + AVHWFramesContext *ctx = opaque; + + if (hwmap->unmap) + hwmap->unmap(ctx, hwmap); + + av_frame_free(&hwmap->source); + + av_buffer_unref(&hwmap->hw_frames_ctx); + + av_free(hwmap); +} + +int ff_hwframe_map_create(AVBufferRef *hwframe_ref, + AVFrame *dst, const AVFrame *src, + void (*unmap)(AVHWFramesContext *ctx, + HWMapDescriptor *hwmap), + void *priv) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)hwframe_ref->data; + HWMapDescriptor *hwmap; + int ret; + + hwmap = av_mallocz(sizeof(*hwmap)); + if (!hwmap) { + ret = AVERROR(ENOMEM); + goto fail; + } + + hwmap->source = av_frame_alloc(); + if (!hwmap->source) { + ret = AVERROR(ENOMEM); + goto fail; + } + ret = av_frame_ref(hwmap->source, src); + if (ret < 0) + goto fail; + + hwmap->hw_frames_ctx = av_buffer_ref(hwframe_ref); + if (!hwmap->hw_frames_ctx) { + ret = AVERROR(ENOMEM); + goto fail; + } + + hwmap->unmap = unmap; + hwmap->priv = priv; + + dst->buf[0] = av_buffer_create((uint8_t*)hwmap, sizeof(*hwmap), + &ff_hwframe_unmap, ctx, 0); + if (!dst->buf[0]) { + ret = AVERROR(ENOMEM); + goto fail; + } + + return 0; + +fail: + if (hwmap) { + av_buffer_unref(&hwmap->hw_frames_ctx); + av_frame_free(&hwmap->source); + } + av_free(hwmap); + return ret; +} + +int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags) +{ + AVHWFramesContext *src_frames, *dst_frames; + HWMapDescriptor *hwmap; + int ret; + + if (src->hw_frames_ctx && dst->hw_frames_ctx) { + src_frames = (AVHWFramesContext*)src->hw_frames_ctx->data; + dst_frames = (AVHWFramesContext*)dst->hw_frames_ctx->data; + + if ((src_frames == dst_frames && + src->format == dst_frames->sw_format && + dst->format == dst_frames->format) || + (src_frames->internal->source_frames && + src_frames->internal->source_frames->data == + (uint8_t*)dst_frames)) { + // This is an unmap operation. We don't need to directly + // do anything here other than fill in the original frame, + // because the real unmap will be invoked when the last + // reference to the mapped frame disappears. + if (!src->buf[0]) { + av_log(src_frames, AV_LOG_ERROR, "Invalid mapping " + "found when attempting unmap.\n"); + return AVERROR(EINVAL); + } + hwmap = (HWMapDescriptor*)src->buf[0]->data; + av_frame_unref(dst); + return av_frame_ref(dst, hwmap->source); + } + } + + if (src->hw_frames_ctx) { + src_frames = (AVHWFramesContext*)src->hw_frames_ctx->data; + + if (src_frames->format == src->format && + src_frames->internal->hw_type->map_from) { + ret = src_frames->internal->hw_type->map_from(src_frames, + dst, src, flags); + if (ret != AVERROR(ENOSYS)) + return ret; + } + } + + if (dst->hw_frames_ctx) { + dst_frames = (AVHWFramesContext*)dst->hw_frames_ctx->data; + + if (dst_frames->format == dst->format && + dst_frames->internal->hw_type->map_to) { + ret = dst_frames->internal->hw_type->map_to(dst_frames, + dst, src, flags); + if (ret != AVERROR(ENOSYS)) + return ret; + } + } + + return AVERROR(ENOSYS); +} + +int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx, + enum AVPixelFormat format, + AVBufferRef *derived_device_ctx, + AVBufferRef *source_frame_ctx, + int flags) +{ + AVBufferRef *dst_ref = NULL; + AVHWFramesContext *dst = NULL; + AVHWFramesContext *src = (AVHWFramesContext*)source_frame_ctx->data; + int ret; + + if (src->internal->source_frames) { + AVHWFramesContext *src_src = + (AVHWFramesContext*)src->internal->source_frames->data; + AVHWDeviceContext *dst_dev = + (AVHWDeviceContext*)derived_device_ctx->data; + + if (src_src->device_ctx == dst_dev) { + // This is actually an unmapping, so we just return a + // reference to the source frame context. + *derived_frame_ctx = + av_buffer_ref(src->internal->source_frames); + if (!*derived_frame_ctx) { + ret = AVERROR(ENOMEM); + goto fail; + } + return 0; + } + } + + dst_ref = av_hwframe_ctx_alloc(derived_device_ctx); + if (!dst_ref) { + ret = AVERROR(ENOMEM); + goto fail; + } + + dst = (AVHWFramesContext*)dst_ref->data; + + dst->format = format; + dst->sw_format = src->sw_format; + dst->width = src->width; + dst->height = src->height; + + dst->internal->source_frames = av_buffer_ref(source_frame_ctx); + if (!dst->internal->source_frames) { + ret = AVERROR(ENOMEM); + goto fail; + } + + ret = av_hwframe_ctx_init(dst_ref); + if (ret) + goto fail; + + *derived_frame_ctx = dst_ref; + return 0; + +fail: + if (dst) + av_buffer_unref(&dst->internal->source_frames); + av_buffer_unref(&dst_ref); + return ret; +} diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h index 0b12fe24bc28d..4067ff1db24c2 100644 --- a/libavutil/hwcontext.h +++ b/libavutil/hwcontext.h @@ -434,4 +434,91 @@ AVHWFramesConstraints *av_hwdevice_get_hwframe_constraints(AVBufferRef *ref, */ void av_hwframe_constraints_free(AVHWFramesConstraints **constraints); + +/** + * Flags to apply to frame mappings. + */ +enum { + /** + * The mapping must be readable. + */ + AV_HWFRAME_MAP_READ = 1 << 0, + /** + * The mapping must be writeable. + */ + AV_HWFRAME_MAP_WRITE = 1 << 1, + /** + * The mapped frame will be overwritten completely in subsequent + * operations, so the current frame data need not be loaded. Any values + * which are not overwritten are unspecified. + */ + AV_HWFRAME_MAP_OVERWRITE = 1 << 2, + /** + * The mapping must be direct. That is, there must not be any copying in + * the map or unmap steps. Note that performance of direct mappings may + * be much lower than normal memory. + */ + AV_HWFRAME_MAP_DIRECT = 1 << 3, +}; + +/** + * Map a hardware frame. + * + * This has a number of different possible effects, depending on the format + * and origin of the src and dst frames. On input, src should be a usable + * frame with valid buffers and dst should be blank (typically as just created + * by av_frame_alloc()). src should have an associated hwframe context, and + * dst may optionally have a format and associated hwframe context. + * + * If src was created by mapping a frame from the hwframe context of dst, + * then this function undoes the mapping - dst is replaced by a reference to + * the frame that src was originally mapped from. + * + * If both src and dst have an associated hwframe context, then this function + * attempts to map the src frame from its hardware context to that of dst and + * then fill dst with appropriate data to be usable there. This will only be + * possible if the hwframe contexts and associated devices are compatible - + * given compatible devices, av_hwframe_ctx_create_derived() can be used to + * create a hwframe context for dst in which mapping should be possible. + * + * If src has a hwframe context but dst does not, then the src frame is + * mapped to normal memory and should thereafter be usable as a normal frame. + * If the format is set on dst, then the mapping will attempt to create dst + * with that format and fail if it is not possible. If format is unset (is + * AV_PIX_FMT_NONE) then dst will be mapped with whatever the most appropriate + * format to use is (probably the sw_format of the src hwframe context). + * + * A return value of AVERROR(ENOSYS) indicates that the mapping is not + * possible with the given arguments and hwframe setup, while other return + * values indicate that it failed somehow. + * + * @param dst Destination frame, to contain the mapping. + * @param src Source frame, to be mapped. + * @param flags Some combination of AV_HWFRAME_MAP_* flags. + * @return Zero on success, negative AVERROR code on failure. + */ +int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags); + + +/** + * Create and initialise an AVHWFramesContext as a mapping of another existing + * AVHWFramesContext on a different device. + * + * av_hwframe_ctx_init() should not be called after this. + * + * @param derived_frame_ctx On success, a reference to the newly created + * AVHWFramesContext. + * @param derived_device_ctx A reference to the device to create the new + * AVHWFramesContext on. + * @param source_frame_ctx A reference to an existing AVHWFramesContext + * which will be mapped to the derived context. + * @param flags Currently unused; should be set to zero. + * @return Zero on success, negative AVERROR code on failure. + */ +int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx, + enum AVPixelFormat format, + AVBufferRef *derived_device_ctx, + AVBufferRef *source_frame_ctx, + int flags); + #endif /* AVUTIL_HWCONTEXT_H */ diff --git a/libavutil/hwcontext_internal.h b/libavutil/hwcontext_internal.h index a391e2599ee37..11e3a68e4cf70 100644 --- a/libavutil/hwcontext_internal.h +++ b/libavutil/hwcontext_internal.h @@ -85,6 +85,11 @@ typedef struct HWContextType { const AVFrame *src); int (*transfer_data_from)(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src); + + int (*map_to)(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src, int flags); + int (*map_from)(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src, int flags); } HWContextType; struct AVHWDeviceInternal { @@ -97,8 +102,43 @@ struct AVHWFramesInternal { void *priv; AVBufferPool *pool_internal; + + /** + * For a derived context, a reference to the original frames + * context it was derived from. + */ + AVBufferRef *source_frames; }; +typedef struct HWMapDescriptor { + /** + * A reference to the original source of the mapping. + */ + AVFrame *source; + /** + * A reference to the hardware frames context in which this + * mapping was made. May be the same as source->hw_frames_ctx, + * but need not be. + */ + AVBufferRef *hw_frames_ctx; + /** + * Unmap function. + */ + void (*unmap)(AVHWFramesContext *ctx, + struct HWMapDescriptor *hwmap); + /** + * Hardware-specific private data associated with the mapping. + */ + void *priv; +} HWMapDescriptor; + +int ff_hwframe_map_create(AVBufferRef *hwframe_ref, + AVFrame *dst, const AVFrame *src, + void (*unmap)(AVHWFramesContext *ctx, + HWMapDescriptor *hwmap), + void *priv); + + extern const HWContextType ff_hwcontext_type_cuda; extern const HWContextType ff_hwcontext_type_dxva2; extern const HWContextType ff_hwcontext_type_qsv; diff --git a/libavutil/version.h b/libavutil/version.h index c1cfcbba2fb17..9287a0b5bd6fb 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -54,7 +54,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 26 +#define LIBAVUTIL_VERSION_MINOR 27 #define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From 124e26971e69bb25f38c6c7cb3fa20c77cf10966 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Tue, 25 Oct 2016 20:40:17 +0100 Subject: [PATCH 0396/3374] lavfi: Hardware map filter Takes a frame associated with a hardware context as input and maps it to something else (another hardware frame or normal memory) for other processing. If the frame to map was originally in the target format (but mapped to something else), the original frame is output. Also supports mapping backwards, where only the output has a hardware context. The link immediately before will be supplied with mapped hardware frames which it can write directly into, and this filter then unmaps them back to the actual hardware frames. --- libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/version.h | 2 +- libavfilter/vf_hwmap.c | 335 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 338 insertions(+), 1 deletion(-) create mode 100644 libavfilter/vf_hwmap.c diff --git a/libavfilter/Makefile b/libavfilter/Makefile index c3c1beaa0f360..8b2841e03b4f2 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -62,6 +62,7 @@ OBJS-$(CONFIG_GRADFUN_FILTER) += vf_gradfun.o OBJS-$(CONFIG_HFLIP_FILTER) += vf_hflip.o OBJS-$(CONFIG_HQDN3D_FILTER) += vf_hqdn3d.o OBJS-$(CONFIG_HWDOWNLOAD_FILTER) += vf_hwdownload.o +OBJS-$(CONFIG_HWMAP_FILTER) += vf_hwmap.o OBJS-$(CONFIG_HWUPLOAD_CUDA_FILTER) += vf_hwupload_cuda.o OBJS-$(CONFIG_HWUPLOAD_FILTER) += vf_hwupload.o OBJS-$(CONFIG_INTERLACE_FILTER) += vf_interlace.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index ec27b5ae6ef65..246aed8412f6f 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -85,6 +85,7 @@ void avfilter_register_all(void) REGISTER_FILTER(HFLIP, hflip, vf); REGISTER_FILTER(HQDN3D, hqdn3d, vf); REGISTER_FILTER(HWDOWNLOAD, hwdownload, vf); + REGISTER_FILTER(HWMAP, hwmap, vf); REGISTER_FILTER(HWUPLOAD, hwupload, vf); REGISTER_FILTER(HWUPLOAD_CUDA, hwupload_cuda, vf); REGISTER_FILTER(INTERLACE, interlace, vf); diff --git a/libavfilter/version.h b/libavfilter/version.h index febfc8fa1d4f9..596701fc091cd 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 6 -#define LIBAVFILTER_VERSION_MINOR 7 +#define LIBAVFILTER_VERSION_MINOR 8 #define LIBAVFILTER_VERSION_MICRO 0 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vf_hwmap.c b/libavfilter/vf_hwmap.c new file mode 100644 index 0000000000000..11595bd6ca565 --- /dev/null +++ b/libavfilter/vf_hwmap.c @@ -0,0 +1,335 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/buffer.h" +#include "libavutil/hwcontext.h" +#include "libavutil/log.h" +#include "libavutil/opt.h" +#include "libavutil/pixdesc.h" + +#include "avfilter.h" +#include "formats.h" +#include "internal.h" +#include "video.h" + +typedef struct HWMapContext { + const AVClass *class; + + AVBufferRef *hwdevice_ref; + AVBufferRef *hwframes_ref; + + int mode; + int map_backwards; +} HWMapContext; + +static int hwmap_query_formats(AVFilterContext *avctx) +{ + ff_formats_ref(ff_all_formats(AVMEDIA_TYPE_VIDEO), + &avctx->inputs[0]->out_formats); + ff_formats_ref(ff_all_formats(AVMEDIA_TYPE_VIDEO), + &avctx->outputs[0]->in_formats); + return 0; +} + +static int hwmap_config_output(AVFilterLink *outlink) +{ + AVFilterContext *avctx = outlink->src; + HWMapContext *ctx = avctx->priv; + AVFilterLink *inlink = avctx->inputs[0]; + AVHWFramesContext *hwfc; + const AVPixFmtDescriptor *desc; + int err; + + av_log(avctx, AV_LOG_DEBUG, "Configure hwmap %s -> %s.\n", + av_get_pix_fmt_name(inlink->format), + av_get_pix_fmt_name(outlink->format)); + + if (inlink->hw_frames_ctx) { + hwfc = (AVHWFramesContext*)inlink->hw_frames_ctx->data; + + desc = av_pix_fmt_desc_get(outlink->format); + if (!desc) + return AVERROR(EINVAL); + + if (inlink->format == hwfc->format && + (desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) { + // Map between two hardware formats (including the case of + // undoing an existing mapping). + + ctx->hwdevice_ref = av_buffer_ref(avctx->hw_device_ctx); + if (!ctx->hwdevice_ref) { + err = AVERROR(ENOMEM); + goto fail; + } + + err = av_hwframe_ctx_create_derived(&ctx->hwframes_ref, + outlink->format, + ctx->hwdevice_ref, + inlink->hw_frames_ctx, 0); + if (err < 0) + goto fail; + + } else if ((outlink->format == hwfc->format && + inlink->format == hwfc->sw_format) || + inlink->format == hwfc->format) { + // Map from a hardware format to a software format, or + // undo an existing such mapping. + + ctx->hwdevice_ref = NULL; + + ctx->hwframes_ref = av_buffer_ref(inlink->hw_frames_ctx); + if (!ctx->hwframes_ref) { + err = AVERROR(ENOMEM); + goto fail; + } + + } else { + // Non-matching formats - not supported. + + av_log(avctx, AV_LOG_ERROR, "Unsupported formats for " + "hwmap: from %s (%s) to %s.\n", + av_get_pix_fmt_name(inlink->format), + av_get_pix_fmt_name(hwfc->format), + av_get_pix_fmt_name(outlink->format)); + err = AVERROR(EINVAL); + goto fail; + } + } else if (avctx->hw_device_ctx) { + // Map from a software format to a hardware format. This + // creates a new hwframe context like hwupload, but then + // returns frames mapped from that to the previous link in + // order to fill them without an additional copy. + + ctx->map_backwards = 1; + + ctx->hwdevice_ref = av_buffer_ref(avctx->hw_device_ctx); + if (!ctx->hwdevice_ref) { + err = AVERROR(ENOMEM); + goto fail; + } + + ctx->hwframes_ref = av_hwframe_ctx_alloc(ctx->hwdevice_ref); + if (!ctx->hwframes_ref) { + err = AVERROR(ENOMEM); + goto fail; + } + hwfc = (AVHWFramesContext*)ctx->hwframes_ref->data; + + hwfc->format = outlink->format; + hwfc->sw_format = inlink->format; + hwfc->width = inlink->w; + hwfc->height = inlink->h; + + err = av_hwframe_ctx_init(ctx->hwframes_ref); + if (err < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to create frame " + "context for backward mapping: %d.\n", err); + goto fail; + } + + } else { + av_log(avctx, AV_LOG_ERROR, "Mapping requires a hardware " + "context (a device, or frames on input).\n"); + return AVERROR(EINVAL); + } + + outlink->hw_frames_ctx = av_buffer_ref(ctx->hwframes_ref); + if (!outlink->hw_frames_ctx) { + err = AVERROR(ENOMEM); + goto fail; + } + + outlink->w = inlink->w; + outlink->h = inlink->h; + + return 0; + +fail: + av_buffer_unref(&ctx->hwframes_ref); + av_buffer_unref(&ctx->hwdevice_ref); + return err; +} + +static AVFrame *hwmap_get_buffer(AVFilterLink *inlink, int w, int h) +{ + AVFilterContext *avctx = inlink->dst; + AVFilterLink *outlink = avctx->outputs[0]; + HWMapContext *ctx = avctx->priv; + + if (ctx->map_backwards) { + AVFrame *src, *dst; + int err; + + src = ff_get_video_buffer(outlink, w, h); + if (!src) { + av_log(avctx, AV_LOG_ERROR, "Failed to allocate source " + "frame for software mapping.\n"); + return NULL; + } + + dst = av_frame_alloc(); + if (!dst) { + av_frame_free(&src); + return NULL; + } + + err = av_hwframe_map(dst, src, ctx->mode); + if (err) { + av_log(avctx, AV_LOG_ERROR, "Failed to map frame to " + "software: %d.\n", err); + av_frame_free(&src); + av_frame_free(&dst); + return NULL; + } + + av_frame_free(&src); + return dst; + } else { + return ff_default_get_video_buffer(inlink, w, h); + } +} + +static int hwmap_filter_frame(AVFilterLink *link, AVFrame *input) +{ + AVFilterContext *avctx = link->dst; + AVFilterLink *outlink = avctx->outputs[0]; + HWMapContext *ctx = avctx->priv; + AVFrame *map = NULL; + int err; + + av_log(ctx, AV_LOG_DEBUG, "Filter input: %s, %ux%u (%"PRId64").\n", + av_get_pix_fmt_name(input->format), + input->width, input->height, input->pts); + + map = av_frame_alloc(); + if (!map) { + err = AVERROR(ENOMEM); + goto fail; + } + + map->format = outlink->format; + map->hw_frames_ctx = av_buffer_ref(ctx->hwframes_ref); + if (!map->hw_frames_ctx) { + err = AVERROR(ENOMEM); + goto fail; + } + + if (ctx->map_backwards && !input->hw_frames_ctx) { + // If we mapped backwards from hardware to software, we need + // to attach the hardware frame context to the input frame to + // make the mapping visible to av_hwframe_map(). + input->hw_frames_ctx = av_buffer_ref(ctx->hwframes_ref); + if (!input->hw_frames_ctx) { + err = AVERROR(ENOMEM); + goto fail; + } + } + + err = av_hwframe_map(map, input, ctx->mode); + if (err < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to map frame: %d.\n", err); + goto fail; + } + + err = av_frame_copy_props(map, input); + if (err < 0) + goto fail; + + av_frame_free(&input); + + av_log(ctx, AV_LOG_DEBUG, "Filter output: %s, %ux%u (%"PRId64").\n", + av_get_pix_fmt_name(map->format), + map->width, map->height, map->pts); + + return ff_filter_frame(outlink, map); + +fail: + av_frame_free(&input); + av_frame_free(&map); + return err; +} + +static av_cold void hwmap_uninit(AVFilterContext *avctx) +{ + HWMapContext *ctx = avctx->priv; + + av_buffer_unref(&ctx->hwframes_ref); + av_buffer_unref(&ctx->hwdevice_ref); +} + +#define OFFSET(x) offsetof(HWMapContext, x) +#define FLAGS (AV_OPT_FLAG_VIDEO_PARAM) +static const AVOption hwmap_options[] = { + { "mode", "Frame mapping mode", + OFFSET(mode), AV_OPT_TYPE_FLAGS, + { .i64 = AV_HWFRAME_MAP_READ | AV_HWFRAME_MAP_WRITE }, + 0, INT_MAX, FLAGS, "mode" }, + + { "read", "Mapping should be readable", + 0, AV_OPT_TYPE_CONST, { .i64 = AV_HWFRAME_MAP_READ }, + INT_MIN, INT_MAX, FLAGS, "mode" }, + { "write", "Mapping should be writeable", + 0, AV_OPT_TYPE_CONST, { .i64 = AV_HWFRAME_MAP_WRITE }, + INT_MIN, INT_MAX, FLAGS, "mode" }, + { "overwrite", "Mapping will always overwrite the entire frame", + 0, AV_OPT_TYPE_CONST, { .i64 = AV_HWFRAME_MAP_OVERWRITE }, + INT_MIN, INT_MAX, FLAGS, "mode" }, + { "direct", "Mapping should not involve any copying", + 0, AV_OPT_TYPE_CONST, { .i64 = AV_HWFRAME_MAP_DIRECT }, + INT_MIN, INT_MAX, FLAGS, "mode" }, + + { NULL }, +}; + +static const AVClass hwmap_class = { + .class_name = "hwmap", + .item_name = av_default_item_name, + .option = hwmap_options, + .version = LIBAVUTIL_VERSION_INT, +}; + +static const AVFilterPad hwmap_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .get_video_buffer = &hwmap_get_buffer, + .filter_frame = &hwmap_filter_frame, + }, + { NULL } +}; + +static const AVFilterPad hwmap_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = &hwmap_config_output, + }, + { NULL } +}; + +AVFilter ff_vf_hwmap = { + .name = "hwmap", + .description = NULL_IF_CONFIG_SMALL("Map hardware frames"), + .uninit = &hwmap_uninit, + .priv_size = sizeof(HWMapContext), + .priv_class = &hwmap_class, + .query_formats = &hwmap_query_formats, + .inputs = hwmap_inputs, + .outputs = hwmap_outputs, + .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, +}; From 8ad9f9d675eab139aa2208722009eeed981460dd Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Tue, 25 Oct 2016 20:43:08 +0100 Subject: [PATCH 0397/3374] hwcontext_vaapi: Frame mapping support Can map to any supported software format (using a GPU copy if it doesn't actually match the surface format underneath). --- libavutil/hwcontext_vaapi.c | 93 +++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 41 deletions(-) diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index 9617979d7c967..198872963728c 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -70,20 +70,12 @@ typedef struct VAAPIFramesContext { int derive_works; } VAAPIFramesContext; -enum { - VAAPI_MAP_READ = 0x01, - VAAPI_MAP_WRITE = 0x02, - VAAPI_MAP_DIRECT = 0x04, -}; - -typedef struct VAAPISurfaceMap { - // The source hardware frame of this mapping (with hw_frames_ctx set). - const AVFrame *source; - // VAAPI_MAP_* flags which apply to this mapping. - int flags; +typedef struct VAAPIMapping { // Handle to the derived or copied image which is mapped. VAImage image; -} VAAPISurfaceMap; + // The mapping flags actually used. + int flags; +} VAAPIMapping; #define MAP(va, rt, av) { \ VA_FOURCC_ ## va, \ @@ -140,7 +132,8 @@ static int vaapi_get_image_format(AVHWDeviceContext *hwdev, for (i = 0; i < ctx->nb_formats; i++) { if (ctx->formats[i].pix_fmt == pix_fmt) { - *image_format = &ctx->formats[i].image_format; + if (image_format) + *image_format = &ctx->formats[i].image_format; return 0; } } @@ -630,17 +623,15 @@ static int vaapi_transfer_get_formats(AVHWFramesContext *hwfc, return 0; } -static void vaapi_unmap_frame(void *opaque, uint8_t *data) +static void vaapi_unmap_frame(AVHWFramesContext *hwfc, + HWMapDescriptor *hwmap) { - AVHWFramesContext *hwfc = opaque; AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; - VAAPISurfaceMap *map = (VAAPISurfaceMap*)data; - const AVFrame *src; + VAAPIMapping *map = hwmap->priv; VASurfaceID surface_id; VAStatus vas; - src = map->source; - surface_id = (VASurfaceID)(uintptr_t)src->data[3]; + surface_id = (VASurfaceID)(uintptr_t)hwmap->source->data[3]; av_log(hwfc, AV_LOG_DEBUG, "Unmap surface %#x.\n", surface_id); vas = vaUnmapBuffer(hwctx->display, map->image.buf); @@ -649,8 +640,8 @@ static void vaapi_unmap_frame(void *opaque, uint8_t *data) "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas)); } - if ((map->flags & VAAPI_MAP_WRITE) && - !(map->flags & VAAPI_MAP_DIRECT)) { + if ((map->flags & AV_HWFRAME_MAP_WRITE) && + !(map->flags & AV_HWFRAME_MAP_DIRECT)) { vas = vaPutImage(hwctx->display, surface_id, map->image.image_id, 0, 0, hwfc->width, hwfc->height, 0, 0, hwfc->width, hwfc->height); @@ -676,7 +667,7 @@ static int vaapi_map_frame(AVHWFramesContext *hwfc, VAAPIFramesContext *ctx = hwfc->internal->priv; VASurfaceID surface_id; VAImageFormat *image_format; - VAAPISurfaceMap *map; + VAAPIMapping *map; VAStatus vas; void *address = NULL; int err, i; @@ -684,13 +675,13 @@ static int vaapi_map_frame(AVHWFramesContext *hwfc, surface_id = (VASurfaceID)(uintptr_t)src->data[3]; av_log(hwfc, AV_LOG_DEBUG, "Map surface %#x.\n", surface_id); - if (!ctx->derive_works && (flags & VAAPI_MAP_DIRECT)) { + if (!ctx->derive_works && (flags & AV_HWFRAME_MAP_DIRECT)) { // Requested direct mapping but it is not possible. return AVERROR(EINVAL); } if (dst->format == AV_PIX_FMT_NONE) dst->format = hwfc->sw_format; - if (dst->format != hwfc->sw_format && (flags & VAAPI_MAP_DIRECT)) { + if (dst->format != hwfc->sw_format && (flags & AV_HWFRAME_MAP_DIRECT)) { // Requested direct mapping but the formats do not match. return AVERROR(EINVAL); } @@ -701,12 +692,10 @@ static int vaapi_map_frame(AVHWFramesContext *hwfc, return AVERROR(EINVAL); } - map = av_malloc(sizeof(VAAPISurfaceMap)); + map = av_malloc(sizeof(*map)); if (!map) return AVERROR(ENOMEM); - - map->source = src; - map->flags = flags; + map->flags = flags; map->image.image_id = VA_INVALID_ID; vas = vaSyncSurface(hwctx->display, surface_id); @@ -724,8 +713,8 @@ static int vaapi_map_frame(AVHWFramesContext *hwfc, // faster with a copy routine which is aware of the limitation, but we // assume for now that the user is not aware of that and would therefore // prefer not to be given direct-mapped memory if they request read access. - if (ctx->derive_works && - ((flags & VAAPI_MAP_DIRECT) || !(flags & VAAPI_MAP_READ))) { + if (ctx->derive_works && dst->format == hwfc->sw_format && + ((flags & AV_HWFRAME_MAP_DIRECT) || !(flags & AV_HWFRAME_MAP_READ))) { vas = vaDeriveImage(hwctx->display, surface_id, &map->image); if (vas != VA_STATUS_SUCCESS) { av_log(hwfc, AV_LOG_ERROR, "Failed to derive image from " @@ -741,7 +730,7 @@ static int vaapi_map_frame(AVHWFramesContext *hwfc, err = AVERROR(EIO); goto fail; } - map->flags |= VAAPI_MAP_DIRECT; + map->flags |= AV_HWFRAME_MAP_DIRECT; } else { vas = vaCreateImage(hwctx->display, image_format, hwfc->width, hwfc->height, &map->image); @@ -752,7 +741,7 @@ static int vaapi_map_frame(AVHWFramesContext *hwfc, err = AVERROR(EIO); goto fail; } - if (flags & VAAPI_MAP_READ) { + if (!(flags & AV_HWFRAME_MAP_OVERWRITE)) { vas = vaGetImage(hwctx->display, surface_id, 0, 0, hwfc->width, hwfc->height, map->image.image_id); if (vas != VA_STATUS_SUCCESS) { @@ -773,6 +762,11 @@ static int vaapi_map_frame(AVHWFramesContext *hwfc, goto fail; } + err = ff_hwframe_map_create(src->hw_frames_ctx, + dst, src, &vaapi_unmap_frame, map); + if (err < 0) + goto fail; + dst->width = src->width; dst->height = src->height; @@ -789,13 +783,6 @@ static int vaapi_map_frame(AVHWFramesContext *hwfc, FFSWAP(uint8_t*, dst->data[1], dst->data[2]); } - dst->buf[0] = av_buffer_create((uint8_t*)map, sizeof(*map), - &vaapi_unmap_frame, hwfc, 0); - if (!dst->buf[0]) { - err = AVERROR(ENOMEM); - goto fail; - } - return 0; fail: @@ -823,7 +810,7 @@ static int vaapi_transfer_data_from(AVHWFramesContext *hwfc, return AVERROR(ENOMEM); map->format = dst->format; - err = vaapi_map_frame(hwfc, map, src, VAAPI_MAP_READ); + err = vaapi_map_frame(hwfc, map, src, AV_HWFRAME_MAP_READ); if (err) goto fail; @@ -854,7 +841,7 @@ static int vaapi_transfer_data_to(AVHWFramesContext *hwfc, return AVERROR(ENOMEM); map->format = src->format; - err = vaapi_map_frame(hwfc, map, dst, VAAPI_MAP_WRITE); + err = vaapi_map_frame(hwfc, map, dst, AV_HWFRAME_MAP_WRITE | AV_HWFRAME_MAP_OVERWRITE); if (err) goto fail; @@ -871,6 +858,28 @@ static int vaapi_transfer_data_to(AVHWFramesContext *hwfc, return err; } +static int vaapi_map_from(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + int err; + + if (dst->format != AV_PIX_FMT_NONE) { + err = vaapi_get_image_format(hwfc->device_ctx, dst->format, NULL); + if (err < 0) + return AVERROR(ENOSYS); + } + + err = vaapi_map_frame(hwfc, dst, src, flags); + if (err) + return err; + + err = av_frame_copy_props(dst, src); + if (err) + return err; + + return 0; +} + static void vaapi_device_free(AVHWDeviceContext *ctx) { AVVAAPIDeviceContext *hwctx = ctx->hwctx; @@ -993,6 +1002,8 @@ const HWContextType ff_hwcontext_type_vaapi = { .transfer_get_formats = &vaapi_transfer_get_formats, .transfer_data_to = &vaapi_transfer_data_to, .transfer_data_from = &vaapi_transfer_data_from, + .map_to = NULL, + .map_from = &vaapi_map_from, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_VAAPI, From 392caa65df3efa8b2d48a80f08a6af4892c61c08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 4 Nov 2016 09:16:22 +0200 Subject: [PATCH 0398/3374] arm: vp9mc: Insert a literal pool at the middle of the file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes errors like this when building non-pic binaries with armv6 as baseline: Error: invalid literal constant: pool needs to be closer Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9mc_neon.S | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/arm/vp9mc_neon.S b/libavcodec/arm/vp9mc_neon.S index 557353cb42f3d..cc8f2417649a9 100644 --- a/libavcodec/arm/vp9mc_neon.S +++ b/libavcodec/arm/vp9mc_neon.S @@ -484,6 +484,7 @@ do_8tap_h_filters 16 do_8tap_h_filters 8 do_8tap_h_filters 4 +.ltorg @ Vertical filters From d1ef1b9eaa45043ea5df5a004fb37243e05da61d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 3 Nov 2016 14:14:12 +0200 Subject: [PATCH 0399/3374] configure: Silence lld-link when getting the version number MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In recent lld-link versions, this command prints the version to stdout, but also prints an error to stderr: $ lld-link -flavor gnu --version LLD 4.0.0 (trunk 285641) lld-link: error: no input files lld-link: error: target emulation unknown: -m or at least one .o file required Signed-off-by: Martin Storsjö --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 9264bb5a0ef23..23be4255ff90b 100755 --- a/configure +++ b/configure @@ -3291,7 +3291,7 @@ probe_cc(){ _type=lld-link # The link.exe mode doesn't have a switch for getting the version, # but we can force it back to gnu mode and get the version from there. - _ident=$($_cc -flavor gnu --version) + _ident=$($_cc -flavor gnu --version 2>/dev/null) _ld_o='-out:$@' _flags_filter=msvc_flags _ld_lib='lib%.a' From 3cba09e5228c889d63814dc43bc68f15c9dbac77 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 30 Oct 2015 14:04:08 +0100 Subject: [PATCH 0400/3374] x86: Drop stray semicolons after function definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit libavcodec/x86/rv40dsp_init.c:97:2: warning: ISO C does not allow extra ‘;’ outside of a function [-Wpedantic] libavcodec/x86/vp9dsp_init.c:94:40: warning: ISO C does not allow extra ‘;’ outside of a function [-Wpedantic] --- libavcodec/x86/rv40dsp_init.c | 2 +- libavcodec/x86/vp9dsp_init.c | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/libavcodec/x86/rv40dsp_init.c b/libavcodec/x86/rv40dsp_init.c index 7bf3ecd1f3110..f6d4165452e13 100644 --- a/libavcodec/x86/rv40dsp_init.c +++ b/libavcodec/x86/rv40dsp_init.c @@ -94,7 +94,7 @@ static void OP ## rv40_qpel ##SIZE ##_mc ##PH ##PV ##OPT(uint8_t *dst, \ ff_ ##OP ##rv40_qpel_h ## OPT(dst + i, stride, src + i, \ stride, SIZE, HCOFF(PH)); \ } \ -}; +} /** Declare functions for sizes 8 and 16 and given operations * and qpel position. */ diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c index 58aedcbd2d492..59cde79d89cb8 100644 --- a/libavcodec/x86/vp9dsp_init.c +++ b/libavcodec/x86/vp9dsp_init.c @@ -100,21 +100,21 @@ ff_vp9_ ## avg ## _8tap_1d_ ## dir ## _ ## sz ## _ ## opt(uint8_t *dst, \ } #define mc_rep_funcs(sz, hsz, opt, type, f_sz) \ - mc_rep_func(put, sz, hsz, h, opt, type, f_sz); \ - mc_rep_func(avg, sz, hsz, h, opt, type, f_sz); \ - mc_rep_func(put, sz, hsz, v, opt, type, f_sz); \ + mc_rep_func(put, sz, hsz, h, opt, type, f_sz) \ + mc_rep_func(avg, sz, hsz, h, opt, type, f_sz) \ + mc_rep_func(put, sz, hsz, v, opt, type, f_sz) \ mc_rep_func(avg, sz, hsz, v, opt, type, f_sz) -mc_rep_funcs(16, 8, sse2, int16_t, 8); +mc_rep_funcs(16, 8, sse2, int16_t, 8) #if ARCH_X86_32 -mc_rep_funcs(16, 8, ssse3, int8_t, 32); +mc_rep_funcs(16, 8, ssse3, int8_t, 32) #endif -mc_rep_funcs(32, 16, sse2, int16_t, 8); -mc_rep_funcs(32, 16, ssse3, int8_t, 32); -mc_rep_funcs(64, 32, sse2, int16_t, 8); -mc_rep_funcs(64, 32, ssse3, int8_t, 32); +mc_rep_funcs(32, 16, sse2, int16_t, 8) +mc_rep_funcs(32, 16, ssse3, int8_t, 32) +mc_rep_funcs(64, 32, sse2, int16_t, 8) +mc_rep_funcs(64, 32, ssse3, int8_t, 32) #if ARCH_X86_64 && HAVE_AVX2_EXTERNAL -mc_rep_funcs(64, 32, avx2, int8_t, 32); +mc_rep_funcs(64, 32, avx2, int8_t, 32) #endif #undef mc_rep_funcs From db0b3dccb3842de134721e8d5c275f56d384340d Mon Sep 17 00:00:00 2001 From: Derek Buitenhuis Date: Sun, 6 Nov 2016 14:09:37 +0000 Subject: [PATCH 0401/3374] libx265: Add option to force IDR frames MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is in the same the same vein as 380146924ecad2e05e9dcc5c3c2e1b5ba47c51e8. Signed-off-by: Derek Buitenhuis Signed-off-by: Martin Storsjö --- libavcodec/libx265.c | 5 ++++- libavcodec/version.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c index f5d3d0f3c0248..add05692c5e18 100644 --- a/libavcodec/libx265.c +++ b/libavcodec/libx265.c @@ -42,6 +42,7 @@ typedef struct libx265Context { const x265_api *api; float crf; + int forced_idr; char *preset; char *tune; char *x265_opts; @@ -263,7 +264,8 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt, x265pic.pts = pic->pts; x265pic.bitDepth = av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth; - x265pic.sliceType = pic->pict_type == AV_PICTURE_TYPE_I ? X265_TYPE_I : + x265pic.sliceType = pic->pict_type == AV_PICTURE_TYPE_I ? + (ctx->forced_idr ? X265_TYPE_IDR : X265_TYPE_I) : pic->pict_type == AV_PICTURE_TYPE_P ? X265_TYPE_P : pic->pict_type == AV_PICTURE_TYPE_B ? X265_TYPE_B : X265_TYPE_AUTO; @@ -348,6 +350,7 @@ static av_cold void libx265_encode_init_csp(AVCodec *codec) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { { "crf", "set the x265 crf", OFFSET(crf), AV_OPT_TYPE_FLOAT, { .dbl = -1 }, -1, FLT_MAX, VE }, + { "forced-idr", "if forcing keyframes, force them as IDR frames", OFFSET(forced_idr),AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, { "preset", "set the x265 preset", OFFSET(preset), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, { "tune", "set the x265 tune parameter", OFFSET(tune), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, { "x265-params", "set the x265 configuration using a :-separated list of key=value parameters", OFFSET(x265_opts), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, diff --git a/libavcodec/version.h b/libavcodec/version.h index 6f439c02c89b6..a4856bf0356fd 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 28 -#define LIBAVCODEC_VERSION_MICRO 1 +#define LIBAVCODEC_VERSION_MICRO 2 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From fabfbfe5710050812147f93a351a53fdda56ff8c Mon Sep 17 00:00:00 2001 From: Hendrik Leppkes Date: Mon, 7 Nov 2016 09:59:28 +0100 Subject: [PATCH 0402/3374] dxva2: fix surface selection when compiled with both d3d11va and dxva2 Fixes a regression introduced in be630b1e08ebe8f766b1798accd6b8e5e096f5aa Signed-off-by: Anton Khirnov --- libavcodec/dxva2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c index eeac474eaec32..9fedd03df839e 100644 --- a/libavcodec/dxva2.c +++ b/libavcodec/dxva2.c @@ -41,7 +41,7 @@ unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx, void *surface = ff_dxva2_get_surface(frame); unsigned i; - for (i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++) + for (i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++) { #if CONFIG_D3D11VA if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD && ctx->d3d11va.surface[i] == surface) { D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc; @@ -53,6 +53,7 @@ unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx, if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD && ctx->dxva2.surface[i] == surface) return i; #endif + } assert(0); return 0; From 910973765417f06a4a9ccbd006e4df74c32ecb01 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 5 Oct 2016 13:39:44 +0200 Subject: [PATCH 0403/3374] hwcontext_dxva2: frame mapping support Signed-off-by: Maxym Dmytrychenko --- libavutil/hwcontext_dxva2.c | 89 ++++++++++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 21 deletions(-) diff --git a/libavutil/hwcontext_dxva2.c b/libavutil/hwcontext_dxva2.c index da89453802907..eb1bc46398c6c 100644 --- a/libavutil/hwcontext_dxva2.c +++ b/libavutil/hwcontext_dxva2.c @@ -241,21 +241,22 @@ static int dxva2_transfer_get_formats(AVHWFramesContext *ctx, return 0; } -static int dxva2_transfer_data(AVHWFramesContext *ctx, AVFrame *dst, - const AVFrame *src) +static void dxva2_unmap_frame(AVHWFramesContext *ctx, HWMapDescriptor *hwmap) +{ + IDirect3DSurface9 *surface = (IDirect3DSurface9*)hwmap->source->data[3]; + IDirect3DSurface9_UnlockRect(surface); +} + +static int dxva2_map_frame(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src, + int flags) { - IDirect3DSurface9 *surface; + IDirect3DSurface9 *surface = (IDirect3DSurface9*)src->data[3]; D3DSURFACE_DESC surfaceDesc; D3DLOCKED_RECT LockedRect; HRESULT hr; + int i, err, nb_planes; - uint8_t *surf_data[4] = { NULL }; - int surf_linesize[4] = { 0 }; - int i; - - int download = !!src->hw_frames_ctx; - - surface = (IDirect3DSurface9*)(download ? src->data[3] : dst->data[3]); + nb_planes = av_pix_fmt_count_planes(dst->format); hr = IDirect3DSurface9_GetDesc(surface, &surfaceDesc); if (FAILED(hr)) { @@ -264,32 +265,77 @@ static int dxva2_transfer_data(AVHWFramesContext *ctx, AVFrame *dst, } hr = IDirect3DSurface9_LockRect(surface, &LockedRect, NULL, - download ? D3DLOCK_READONLY : D3DLOCK_DISCARD); + flags & AV_HWFRAME_MAP_READ ? D3DLOCK_READONLY : D3DLOCK_DISCARD); if (FAILED(hr)) { av_log(ctx, AV_LOG_ERROR, "Unable to lock DXVA2 surface\n"); return AVERROR_UNKNOWN; } - for (i = 0; download ? dst->data[i] : src->data[i]; i++) - surf_linesize[i] = LockedRect.Pitch; + err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, + dxva2_unmap_frame, NULL); + if (err < 0) + goto fail; + + for (i = 0; i < nb_planes; i++) + dst->linesize[i] = LockedRect.Pitch; + + av_image_fill_pointers(dst->data, dst->format, surfaceDesc.Height, + (uint8_t*)LockedRect.pBits, dst->linesize); + + return 0; +fail: + IDirect3DSurface9_UnlockRect(surface); + return err; +} + +static int dxva2_transfer_data(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) +{ + int download = !!src->hw_frames_ctx; + + AVFrame *map; + int ret, i; - av_image_fill_pointers(surf_data, ctx->sw_format, surfaceDesc.Height, - (uint8_t*)LockedRect.pBits, surf_linesize); + map = av_frame_alloc(); + if (!map) + return AVERROR(ENOMEM); + map->format = dst->format; + + ret = dxva2_map_frame(ctx, map, download ? src : dst, + download ? AV_HWFRAME_MAP_READ : AV_HWFRAME_MAP_WRITE); + if (ret < 0) + goto fail; if (download) { - ptrdiff_t src_linesize1[4], dst_linesize1[4]; + ptrdiff_t src_linesize[4], dst_linesize[4]; for (i = 0; i < 4; i++) { - dst_linesize1[i] = dst->linesize[i]; - src_linesize1[i] = surf_linesize[i]; + dst_linesize[i] = dst->linesize[i]; + src_linesize[i] = map->linesize[i]; } - av_image_copy_uc_from(dst->data, dst_linesize1, surf_data, src_linesize1, + av_image_copy_uc_from(dst->data, dst_linesize, map->data, src_linesize, ctx->sw_format, src->width, src->height); } else { - av_image_copy(surf_data, surf_linesize, src->data, src->linesize, + av_image_copy(map->data, map->linesize, src->data, src->linesize, ctx->sw_format, src->width, src->height); } - IDirect3DSurface9_UnlockRect(surface); +fail: + av_frame_free(&map); + return ret; +} + +static int dxva2_map_from(AVHWFramesContext *ctx, + AVFrame *dst, const AVFrame *src, int flags) +{ + int err; + + err = dxva2_map_frame(ctx, dst, src, flags); + if (err < 0) + return err; + + err = av_frame_copy_props(dst, src); + if (err < 0) + return err; return 0; } @@ -428,6 +474,7 @@ const HWContextType ff_hwcontext_type_dxva2 = { .transfer_get_formats = dxva2_transfer_get_formats, .transfer_data_to = dxva2_transfer_data, .transfer_data_from = dxva2_transfer_data, + .map_from = dxva2_map_from, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_DXVA2_VLD, AV_PIX_FMT_NONE }, }; From 10065d9324c2e35ce7040b6a2b9ebf6079bcbf42 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 10 Aug 2016 13:01:55 +0200 Subject: [PATCH 0404/3374] hwcontext_dxva2: add support for the P8 format This format is used internally by the QSV encoder to store the encoded bitstream. Signed-off-by: Maxym Dmytrychenko --- libavutil/hwcontext_dxva2.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/libavutil/hwcontext_dxva2.c b/libavutil/hwcontext_dxva2.c index eb1bc46398c6c..600cf0eec7935 100644 --- a/libavutil/hwcontext_dxva2.c +++ b/libavutil/hwcontext_dxva2.c @@ -40,6 +40,10 @@ typedef IDirect3D9* WINAPI pDirect3DCreate9(UINT); typedef HRESULT WINAPI pCreateDeviceManager9(UINT *, IDirect3DDeviceManager9 **); +typedef struct DXVA2Mapping { + uint32_t palette_dummy[256]; +} DXVA2Mapping; + typedef struct DXVA2FramesContext { IDirect3DSurface9 **surfaces_internal; int nb_surfaces_used; @@ -66,6 +70,7 @@ static const struct { } supported_formats[] = { { MKTAG('N', 'V', '1', '2'), AV_PIX_FMT_NV12 }, { MKTAG('P', '0', '1', '0'), AV_PIX_FMT_P010 }, + { D3DFMT_P8, AV_PIX_FMT_PAL8 }, }; DEFINE_GUID(video_decoder_service, 0xfc51a551, 0xd5e7, 0x11d9, 0xaf, 0x55, 0x00, 0x05, 0x4e, 0x43, 0xff, 0x02); @@ -245,12 +250,14 @@ static void dxva2_unmap_frame(AVHWFramesContext *ctx, HWMapDescriptor *hwmap) { IDirect3DSurface9 *surface = (IDirect3DSurface9*)hwmap->source->data[3]; IDirect3DSurface9_UnlockRect(surface); + av_freep(&hwmap->priv); } static int dxva2_map_frame(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src, int flags) { IDirect3DSurface9 *surface = (IDirect3DSurface9*)src->data[3]; + DXVA2Mapping *map; D3DSURFACE_DESC surfaceDesc; D3DLOCKED_RECT LockedRect; HRESULT hr; @@ -271,10 +278,16 @@ static int dxva2_map_frame(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame * return AVERROR_UNKNOWN; } + map = av_mallocz(sizeof(*map)); + if (!map) + goto fail; + err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, - dxva2_unmap_frame, NULL); - if (err < 0) + dxva2_unmap_frame, map); + if (err < 0) { + av_freep(&map); goto fail; + } for (i = 0; i < nb_planes; i++) dst->linesize[i] = LockedRect.Pitch; @@ -282,6 +295,9 @@ static int dxva2_map_frame(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame * av_image_fill_pointers(dst->data, dst->format, surfaceDesc.Height, (uint8_t*)LockedRect.pBits, dst->linesize); + if (dst->format == AV_PIX_FMT_PAL8) + dst->data[1] = (uint8_t*)map->palette_dummy; + return 0; fail: IDirect3DSurface9_UnlockRect(surface); From b115a35ea62b8f479b48d99a601f0e157517301e Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 10 Aug 2016 13:01:55 +0200 Subject: [PATCH 0405/3374] hwcontext_qsv: add support for the P8 format When using GPU surfaces with QSV, one needs to supply a frame allocator, which will be invoked to pass surface pools to libmfx. For encoding, this allocator gets invoked not only for the pool of input frames, but also for a separate pool of (apparently) reconstructed frames and another pool of MFX_FOURCC_P8, which on Windows needs to return D3DFMT_P8 D3D surfaces. Those are probably used to store the encoded bitstream on the GPU. Signed-off-by: Maxym Dmytrychenko --- libavutil/hwcontext_qsv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c index f2c80860a8ed5..3679dc01d0cda 100644 --- a/libavutil/hwcontext_qsv.c +++ b/libavutil/hwcontext_qsv.c @@ -91,6 +91,7 @@ static const struct { } supported_pixel_formats[] = { { AV_PIX_FMT_NV12, MFX_FOURCC_NV12 }, { AV_PIX_FMT_P010, MFX_FOURCC_P010 }, + { AV_PIX_FMT_PAL8, MFX_FOURCC_P8 }, }; static int qsv_device_init(AVHWDeviceContext *ctx) From b91ce4860054430d3712deb0d9487cac2fcb7d68 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 10 Aug 2016 12:54:31 +0200 Subject: [PATCH 0406/3374] hwcontext_qsv: do not fail when download/upload VPP session creation fails Certain pixel formats (e.g. P8) might not be supported for download/upload through VPP operations, but can still be used otherwise. Signed-off-by: Maxym Dmytrychenko --- libavutil/hwcontext_qsv.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c index 3679dc01d0cda..ae4b42739c6bb 100644 --- a/libavutil/hwcontext_qsv.c +++ b/libavutil/hwcontext_qsv.c @@ -450,8 +450,10 @@ static int qsv_init_internal_session(AVHWFramesContext *ctx, err = MFXVideoVPP_Init(*session, &par); if (err != MFX_ERR_NONE) { - av_log(ctx, AV_LOG_ERROR, "Error opening the internal VPP session\n"); - return AVERROR_UNKNOWN; + av_log(ctx, AV_LOG_VERBOSE, "Error opening the internal VPP session." + "Surface upload/download will not be possible\n"); + MFXClose(*session); + *session = NULL; } return 0; @@ -567,6 +569,11 @@ static int qsv_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, mfxSyncPoint sync = NULL; mfxStatus err; + if (!s->session_download) { + av_log(ctx, AV_LOG_ERROR, "Surface download not possible\n"); + return AVERROR(ENOSYS); + } + out.Info = in->Info; out.Data.PitchLow = dst->linesize[0]; out.Data.Y = dst->data[0]; @@ -606,6 +613,11 @@ static int qsv_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, mfxSyncPoint sync = NULL; mfxStatus err; + if (!s->session_upload) { + av_log(ctx, AV_LOG_ERROR, "Surface upload not possible\n"); + return AVERROR(ENOSYS); + } + in.Info = out->Info; in.Data.PitchLow = src->linesize[0]; in.Data.Y = src->data[0]; From 8ea15afbf2c1ec89b5d4bac1f0b8345e4b906a5d Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 10 Aug 2016 14:58:08 +0200 Subject: [PATCH 0407/3374] hwcontext_qsv: transfer data through the child context when VPP fails Uploading/downloading data through VPP may not work for some formats, in that case we can still try to call av_hwframe_transfer_data() on the child context. Signed-off-by: Maxym Dmytrychenko --- libavutil/hwcontext_qsv.c | 40 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c index ae4b42739c6bb..ff66af6006649 100644 --- a/libavutil/hwcontext_qsv.c +++ b/libavutil/hwcontext_qsv.c @@ -559,6 +559,40 @@ static int qsv_transfer_get_formats(AVHWFramesContext *ctx, return 0; } +static int qsv_transfer_data_child(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) +{ + QSVFramesContext *s = ctx->internal->priv; + AVHWFramesContext *child_frames_ctx = (AVHWFramesContext*)s->child_frames_ref->data; + int download = !!src->hw_frames_ctx; + mfxFrameSurface1 *surf = (mfxFrameSurface1*)(download ? src->data[3] : dst->data[3]); + + AVFrame *dummy; + int ret; + + dummy = av_frame_alloc(); + if (!dummy) + return AVERROR(ENOMEM); + + dummy->format = child_frames_ctx->format; + dummy->width = src->width; + dummy->height = src->height; + dummy->buf[0] = download ? src->buf[0] : dst->buf[0]; + dummy->data[3] = surf->Data.MemId; + dummy->hw_frames_ctx = s->child_frames_ref; + + ret = download ? av_hwframe_transfer_data(dst, dummy, 0) : + av_hwframe_transfer_data(dummy, src, 0); + + dummy->buf[0] = NULL; + dummy->data[3] = NULL; + dummy->hw_frames_ctx = NULL; + + av_frame_free(&dummy); + + return ret; +} + static int qsv_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src) { @@ -570,6 +604,9 @@ static int qsv_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, mfxStatus err; if (!s->session_download) { + if (s->child_frames_ref) + return qsv_transfer_data_child(ctx, dst, src); + av_log(ctx, AV_LOG_ERROR, "Surface download not possible\n"); return AVERROR(ENOSYS); } @@ -614,6 +651,9 @@ static int qsv_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, mfxStatus err; if (!s->session_upload) { + if (s->child_frames_ref) + return qsv_transfer_data_child(ctx, dst, src); + av_log(ctx, AV_LOG_ERROR, "Surface upload not possible\n"); return AVERROR(ENOSYS); } From e8bbacbf529049c401bfeea70d5e0b5d2c8b6de6 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 6 Oct 2016 11:33:15 +0200 Subject: [PATCH 0408/3374] hwcontext_qsv: support frame mapping Signed-off-by: Maxym Dmytrychenko --- libavutil/hwcontext_qsv.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c index ff66af6006649..3409e9b976184 100644 --- a/libavutil/hwcontext_qsv.c +++ b/libavutil/hwcontext_qsv.c @@ -559,6 +559,42 @@ static int qsv_transfer_get_formats(AVHWFramesContext *ctx, return 0; } +static int qsv_map_from(AVHWFramesContext *ctx, + AVFrame *dst, const AVFrame *src, int flags) +{ + QSVFramesContext *s = ctx->internal->priv; + mfxFrameSurface1 *surf = (mfxFrameSurface1*)src->data[3]; + AVHWFramesContext *child_frames_ctx; + + AVFrame *dummy; + int ret = 0; + + if (!s->child_frames_ref) + return AVERROR(ENOSYS); + child_frames_ctx = (AVHWFramesContext*)s->child_frames_ref->data; + + dummy = av_frame_alloc(); + if (!dummy) + return AVERROR(ENOMEM); + + dummy->buf[0] = av_buffer_ref(src->buf[0]); + dummy->hw_frames_ctx = av_buffer_ref(s->child_frames_ref); + if (!dummy->buf[0] || !dummy->hw_frames_ctx) + goto fail; + + dummy->format = child_frames_ctx->format; + dummy->width = src->width; + dummy->height = src->height; + dummy->data[3] = surf->Data.MemId; + + ret = av_hwframe_map(dst, dummy, flags); + +fail: + av_frame_free(&dummy); + + return ret; +} + static int qsv_transfer_data_child(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src) { @@ -840,6 +876,7 @@ const HWContextType ff_hwcontext_type_qsv = { .transfer_get_formats = qsv_transfer_get_formats, .transfer_data_to = qsv_transfer_data_to, .transfer_data_from = qsv_transfer_data_from, + .map_from = qsv_map_from, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_QSV, AV_PIX_FMT_NONE }, }; From 404e51478ecad060249d5b9bee6ab39a8a9d8c1c Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 9 Aug 2016 12:05:49 +0200 Subject: [PATCH 0409/3374] qsv{dec,enc}: always use an internal mfxFrameSurface1 For encoding, this avoids modifying the input surface, which we are not allowed to do. This will also be useful in the following commits. Signed-off-by: Maxym Dmytrychenko --- libavcodec/qsv_internal.h | 5 ++--- libavcodec/qsvdec.c | 32 ++++++++++++++++++-------------- libavcodec/qsvenc.c | 32 ++++++++++++++++---------------- 3 files changed, 36 insertions(+), 33 deletions(-) diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index 41f4c3ddf6048..5b015a619d7ee 100644 --- a/libavcodec/qsv_internal.h +++ b/libavcodec/qsv_internal.h @@ -38,11 +38,10 @@ typedef struct QSVFrame { AVFrame *frame; - mfxFrameSurface1 *surface; - - mfxFrameSurface1 surface_internal; + mfxFrameSurface1 surface; int queued; + int used; struct QSVFrame *next; } QSVFrame; diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index 81c63b129269b..8353d252d2b4b 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -179,17 +179,17 @@ static int alloc_frame(AVCodecContext *avctx, QSVContext *q, QSVFrame *frame) return ret; if (frame->frame->format == AV_PIX_FMT_QSV) { - frame->surface = (mfxFrameSurface1*)frame->frame->data[3]; + frame->surface = *(mfxFrameSurface1*)frame->frame->data[3]; } else { - frame->surface_internal.Info = q->frame_info; + frame->surface.Info = q->frame_info; - frame->surface_internal.Data.PitchLow = frame->frame->linesize[0]; - frame->surface_internal.Data.Y = frame->frame->data[0]; - frame->surface_internal.Data.UV = frame->frame->data[1]; - - frame->surface = &frame->surface_internal; + frame->surface.Data.PitchLow = frame->frame->linesize[0]; + frame->surface.Data.Y = frame->frame->data[0]; + frame->surface.Data.UV = frame->frame->data[1]; } + frame->used = 1; + return 0; } @@ -197,8 +197,8 @@ static void qsv_clear_unused_frames(QSVContext *q) { QSVFrame *cur = q->work_frames; while (cur) { - if (cur->surface && !cur->surface->Data.Locked && !cur->queued) { - cur->surface = NULL; + if (cur->used && !cur->surface.Data.Locked && !cur->queued) { + cur->used = 0; av_frame_unref(cur->frame); } cur = cur->next; @@ -215,11 +215,11 @@ static int get_surface(AVCodecContext *avctx, QSVContext *q, mfxFrameSurface1 ** frame = q->work_frames; last = &q->work_frames; while (frame) { - if (!frame->surface) { + if (!frame->used) { ret = alloc_frame(avctx, q, frame); if (ret < 0) return ret; - *surf = frame->surface; + *surf = &frame->surface; return 0; } @@ -241,7 +241,7 @@ static int get_surface(AVCodecContext *avctx, QSVContext *q, mfxFrameSurface1 ** if (ret < 0) return ret; - *surf = frame->surface; + *surf = &frame->surface; return 0; } @@ -250,7 +250,7 @@ static QSVFrame *find_frame(QSVContext *q, mfxFrameSurface1 *surf) { QSVFrame *cur = q->work_frames; while (cur) { - if (surf == cur->surface) + if (surf == &cur->surface) return cur; cur = cur->next; } @@ -346,7 +346,7 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q, if (ret < 0) return ret; - outsurf = out_frame->surface; + outsurf = &out_frame->surface; #if FF_API_PKT_PTS FF_DISABLE_DEPRECATION_WARNINGS @@ -364,6 +364,10 @@ FF_ENABLE_DEPRECATION_WARNINGS frame->interlaced_frame = !(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE); + /* update the surface properties */ + if (avctx->pix_fmt == AV_PIX_FMT_QSV) + ((mfxFrameSurface1*)frame->data[3])->Info = outsurf->Info; + *got_frame = 1; } diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index ba07db6e99122..3d99e846e3b2e 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -813,9 +813,9 @@ static void clear_unused_frames(QSVEncContext *q) { QSVFrame *cur = q->work_frames; while (cur) { - if (cur->surface && !cur->surface->Data.Locked) { - cur->surface = NULL; + if (cur->used && !cur->surface.Data.Locked) { av_frame_unref(cur->frame); + cur->used = 0; } cur = cur->next; } @@ -830,8 +830,9 @@ static int get_free_frame(QSVEncContext *q, QSVFrame **f) frame = q->work_frames; last = &q->work_frames; while (frame) { - if (!frame->surface) { + if (!frame->used) { *f = frame; + frame->used = 1; return 0; } @@ -850,6 +851,7 @@ static int get_free_frame(QSVEncContext *q, QSVFrame **f) *last = frame; *f = frame; + frame->used = 1; return 0; } @@ -869,7 +871,7 @@ static int submit_frame(QSVEncContext *q, const AVFrame *frame, if (ret < 0) return ret; - qf->surface = (mfxFrameSurface1*)qf->frame->data[3]; + qf->surface = *(mfxFrameSurface1*)qf->frame->data[3]; } else { /* make a copy if the input is not padded as libmfx requires */ if (frame->height & 31 || frame->linesize[0] & (q->width_align - 1)) { @@ -893,29 +895,27 @@ static int submit_frame(QSVEncContext *q, const AVFrame *frame, return ret; } - qf->surface_internal.Info = q->param.mfx.FrameInfo; + qf->surface.Info = q->param.mfx.FrameInfo; - qf->surface_internal.Info.PicStruct = + qf->surface.Info.PicStruct = !frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE : frame->top_field_first ? MFX_PICSTRUCT_FIELD_TFF : MFX_PICSTRUCT_FIELD_BFF; if (frame->repeat_pict == 1) - qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED; + qf->surface.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED; else if (frame->repeat_pict == 2) - qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING; + qf->surface.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING; else if (frame->repeat_pict == 4) - qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING; + qf->surface.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING; - qf->surface_internal.Data.PitchLow = qf->frame->linesize[0]; - qf->surface_internal.Data.Y = qf->frame->data[0]; - qf->surface_internal.Data.UV = qf->frame->data[1]; - - qf->surface = &qf->surface_internal; + qf->surface.Data.PitchLow = qf->frame->linesize[0]; + qf->surface.Data.Y = qf->frame->data[0]; + qf->surface.Data.UV = qf->frame->data[1]; } - qf->surface->Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000}); + qf->surface.Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000}); - *surface = qf->surface; + *surface = &qf->surface; return 0; } From 00aeedd84105a17f414185bd33ecadebeddb3a27 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 10 Aug 2016 08:29:23 +0200 Subject: [PATCH 0410/3374] qsv{dec,enc}: use a struct as a memory id with internal memory allocator This will allow implementing the allocator more fully, which is needed by the HEVC encoder plugin with video memory input. Signed-off-by: Maxym Dmytrychenko --- libavcodec/qsv.c | 26 +++++++++++++++++++++++--- libavcodec/qsv_internal.h | 10 ++++++++-- libavcodec/qsvdec.c | 8 ++++++++ libavcodec/qsvenc.c | 8 ++++++++ 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index 91195865bcb2c..f433b8bf6dcc4 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -144,6 +144,17 @@ int ff_qsv_map_pixfmt(enum AVPixelFormat format, uint32_t *fourcc) } } +int ff_qsv_find_surface_idx(QSVFramesContext *ctx, QSVFrame *frame) +{ + int i; + for (i = 0; i < ctx->nb_mids; i++) { + QSVMid *mid = &ctx->mids[i]; + if (mid->handle == frame->surface.Data.MemId) + return i; + } + return AVERROR_BUG; +} + static int qsv_load_plugins(mfxSession session, const char *load_plugins, void *logctx) { @@ -244,6 +255,7 @@ static mfxStatus qsv_frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req, QSVFramesContext *ctx = pthis; mfxFrameInfo *i = &req->Info; mfxFrameInfo *i1 = &ctx->info; + int j; if (!(req->Type & MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET) || !(req->Type & (MFX_MEMTYPE_FROM_DECODE | MFX_MEMTYPE_FROM_ENCODE)) || @@ -258,7 +270,13 @@ static mfxStatus qsv_frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req, return MFX_ERR_UNSUPPORTED; } - resp->mids = ctx->mids; + resp->mids = av_mallocz_array(ctx->nb_mids, sizeof(*resp->mids)); + if (!resp->mids) + return MFX_ERR_MEMORY_ALLOC; + + for (j = 0; j < ctx->nb_mids; j++) + resp->mids[j] = &ctx->mids[j]; + resp->NumFrameActual = ctx->nb_mids; return MFX_ERR_NONE; @@ -266,6 +284,7 @@ static mfxStatus qsv_frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req, static mfxStatus qsv_frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp) { + av_freep(&resp->mids); return MFX_ERR_NONE; } @@ -281,7 +300,8 @@ static mfxStatus qsv_frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) static mfxStatus qsv_frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl) { - *hdl = mid; + QSVMid *qsv_mid = (QSVMid*)mid; + *hdl = qsv_mid->handle; return MFX_ERR_NONE; } @@ -365,7 +385,7 @@ int ff_qsv_init_session_hwcontext(AVCodecContext *avctx, mfxSession *psession, qsv_frames_ctx->info = frames_hwctx->surfaces[0].Info; qsv_frames_ctx->nb_mids = frames_hwctx->nb_surfaces; for (i = 0; i < frames_hwctx->nb_surfaces; i++) - qsv_frames_ctx->mids[i] = frames_hwctx->surfaces[i].Data.MemId; + qsv_frames_ctx->mids[i].handle = frames_hwctx->surfaces[i].Data.MemId; err = MFXVideoCORE_SetFrameAllocator(session, &frame_allocator); if (err != MFX_ERR_NONE) diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index 5b015a619d7ee..8b69891aa69c8 100644 --- a/libavcodec/qsv_internal.h +++ b/libavcodec/qsv_internal.h @@ -36,6 +36,10 @@ (MFX_VERSION_MAJOR > (MAJOR) || \ MFX_VERSION_MAJOR == (MAJOR) && MFX_VERSION_MINOR >= (MINOR)) +typedef struct QSVMid { + mfxHDL handle; +} QSVMid; + typedef struct QSVFrame { AVFrame *frame; mfxFrameSurface1 surface; @@ -49,8 +53,8 @@ typedef struct QSVFrame { typedef struct QSVFramesContext { AVBufferRef *hw_frames_ctx; mfxFrameInfo info; - mfxMemId *mids; - int nb_mids; + QSVMid *mids; + int nb_mids; } QSVFramesContext; /** @@ -75,4 +79,6 @@ int ff_qsv_init_session_hwcontext(AVCodecContext *avctx, mfxSession *session, QSVFramesContext *qsv_frames_ctx, const char *load_plugins, int opaque); +int ff_qsv_find_surface_idx(QSVFramesContext *ctx, QSVFrame *frame); + #endif /* AVCODEC_QSV_INTERNAL_H */ diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index 8353d252d2b4b..398c319b300ec 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -188,6 +188,14 @@ static int alloc_frame(AVCodecContext *avctx, QSVContext *q, QSVFrame *frame) frame->surface.Data.UV = frame->frame->data[1]; } + if (q->frames_ctx.mids) { + ret = ff_qsv_find_surface_idx(&q->frames_ctx, frame); + if (ret < 0) + return ret; + + frame->surface.Data.MemId = &q->frames_ctx.mids[ret]; + } + frame->used = 1; return 0; diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index 3d99e846e3b2e..be8cbee884260 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -872,6 +872,14 @@ static int submit_frame(QSVEncContext *q, const AVFrame *frame, return ret; qf->surface = *(mfxFrameSurface1*)qf->frame->data[3]; + + if (q->frames_ctx.mids) { + ret = ff_qsv_find_surface_idx(&q->frames_ctx, qf); + if (ret < 0) + return ret; + + qf->surface.Data.MemId = &q->frames_ctx.mids[ret]; + } } else { /* make a copy if the input is not padded as libmfx requires */ if (frame->height & 31 || frame->linesize[0] & (q->width_align - 1)) { From 4ab61cd983b539749bd621ea271624ddb5196a8e Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 10 Aug 2016 09:38:21 +0200 Subject: [PATCH 0411/3374] qsv{enc,dec}: extend the internal frame allocator Handle the internal frame requests, which is required by the HEVC encoding plugin. Signed-off-by: Maxym Dmytrychenko --- libavcodec/qsv.c | 268 +++++++++++++++++++++++++++++++++----- libavcodec/qsv_internal.h | 13 +- libavcodec/qsvdec.c | 3 +- libavcodec/qsvenc.c | 3 +- 4 files changed, 252 insertions(+), 35 deletions(-) diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index f433b8bf6dcc4..6c53489373f43 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -29,6 +29,7 @@ #include "libavutil/error.h" #include "libavutil/hwcontext.h" #include "libavutil/hwcontext_qsv.h" +#include "libavutil/imgutils.h" #include "avcodec.h" #include "qsv_internal.h" @@ -127,6 +128,16 @@ int ff_qsv_print_warning(void *log_ctx, mfxStatus err, return ret; } +static enum AVPixelFormat qsv_map_fourcc(uint32_t fourcc) +{ + switch (fourcc) { + case MFX_FOURCC_NV12: return AV_PIX_FMT_NV12; + case MFX_FOURCC_P010: return AV_PIX_FMT_P010; + case MFX_FOURCC_P8: return AV_PIX_FMT_PAL8; + } + return AV_PIX_FMT_NONE; +} + int ff_qsv_map_pixfmt(enum AVPixelFormat format, uint32_t *fourcc) { switch (format) { @@ -249,53 +260,251 @@ int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session, return 0; } +static void mids_buf_free(void *opaque, uint8_t *data) +{ + AVBufferRef *hw_frames_ref = opaque; + av_buffer_unref(&hw_frames_ref); + av_freep(&data); +} + +static AVBufferRef *qsv_create_mids(AVBufferRef *hw_frames_ref) +{ + AVHWFramesContext *frames_ctx = (AVHWFramesContext*)hw_frames_ref->data; + AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx; + int nb_surfaces = frames_hwctx->nb_surfaces; + + AVBufferRef *mids_buf, *hw_frames_ref1; + QSVMid *mids; + int i; + + hw_frames_ref1 = av_buffer_ref(hw_frames_ref); + if (!hw_frames_ref1) + return NULL; + + mids = av_mallocz_array(nb_surfaces, sizeof(*mids)); + if (!mids) { + av_buffer_unref(&hw_frames_ref1); + return NULL; + } + + mids_buf = av_buffer_create((uint8_t*)mids, nb_surfaces * sizeof(*mids), + mids_buf_free, hw_frames_ref1, 0); + if (!mids_buf) { + av_buffer_unref(&hw_frames_ref1); + av_freep(&mids); + return NULL; + } + + for (i = 0; i < nb_surfaces; i++) { + QSVMid *mid = &mids[i]; + mid->handle = frames_hwctx->surfaces[i].Data.MemId; + mid->hw_frames_ref = hw_frames_ref1; + } + + return mids_buf; +} + +static int qsv_setup_mids(mfxFrameAllocResponse *resp, AVBufferRef *hw_frames_ref, + AVBufferRef *mids_buf) +{ + AVHWFramesContext *frames_ctx = (AVHWFramesContext*)hw_frames_ref->data; + AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx; + QSVMid *mids = (QSVMid*)mids_buf->data; + int nb_surfaces = frames_hwctx->nb_surfaces; + int i; + + // the allocated size of the array is two larger than the number of + // surfaces, we store the references to the frames context and the + // QSVMid array there + resp->mids = av_mallocz_array(nb_surfaces + 2, sizeof(*resp->mids)); + if (!resp->mids) + return AVERROR(ENOMEM); + + for (i = 0; i < nb_surfaces; i++) + resp->mids[i] = &mids[i]; + resp->NumFrameActual = nb_surfaces; + + resp->mids[resp->NumFrameActual] = (mfxMemId)av_buffer_ref(hw_frames_ref); + if (!resp->mids[resp->NumFrameActual]) { + av_freep(&resp->mids); + return AVERROR(ENOMEM); + } + + resp->mids[resp->NumFrameActual + 1] = av_buffer_ref(mids_buf); + if (!resp->mids[resp->NumFrameActual + 1]) { + av_buffer_unref((AVBufferRef**)&resp->mids[resp->NumFrameActual]); + av_freep(&resp->mids); + return AVERROR(ENOMEM); + } + + return 0; +} + static mfxStatus qsv_frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req, mfxFrameAllocResponse *resp) { QSVFramesContext *ctx = pthis; - mfxFrameInfo *i = &req->Info; - mfxFrameInfo *i1 = &ctx->info; - int j; + int ret; - if (!(req->Type & MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET) || - !(req->Type & (MFX_MEMTYPE_FROM_DECODE | MFX_MEMTYPE_FROM_ENCODE)) || - !(req->Type & MFX_MEMTYPE_EXTERNAL_FRAME)) - return MFX_ERR_UNSUPPORTED; - if (i->Width != i1->Width || i->Height != i1->Height || - i->FourCC != i1->FourCC || i->ChromaFormat != i1->ChromaFormat) { - av_log(ctx, AV_LOG_ERROR, "Mismatching surface properties in an " - "allocation request: %dx%d %d %d vs %dx%d %d %d\n", - i->Width, i->Height, i->FourCC, i->ChromaFormat, - i1->Width, i1->Height, i1->FourCC, i1->ChromaFormat); + /* this should only be called from an encoder or decoder and + * only allocates video memory frames */ + if (!(req->Type & (MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET | + MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET)) || + !(req->Type & (MFX_MEMTYPE_FROM_DECODE | MFX_MEMTYPE_FROM_ENCODE))) return MFX_ERR_UNSUPPORTED; - } - resp->mids = av_mallocz_array(ctx->nb_mids, sizeof(*resp->mids)); - if (!resp->mids) - return MFX_ERR_MEMORY_ALLOC; + if (req->Type & MFX_MEMTYPE_EXTERNAL_FRAME) { + /* external frames -- fill from the caller-supplied frames context */ + AVHWFramesContext *frames_ctx = (AVHWFramesContext*)ctx->hw_frames_ctx->data; + AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx; + mfxFrameInfo *i = &req->Info; + mfxFrameInfo *i1 = &frames_hwctx->surfaces[0].Info; + + if (i->Width != i1->Width || i->Height != i1->Height || + i->FourCC != i1->FourCC || i->ChromaFormat != i1->ChromaFormat) { + av_log(ctx->logctx, AV_LOG_ERROR, "Mismatching surface properties in an " + "allocation request: %dx%d %d %d vs %dx%d %d %d\n", + i->Width, i->Height, i->FourCC, i->ChromaFormat, + i1->Width, i1->Height, i1->FourCC, i1->ChromaFormat); + return MFX_ERR_UNSUPPORTED; + } + + ret = qsv_setup_mids(resp, ctx->hw_frames_ctx, ctx->mids_buf); + if (ret < 0) { + av_log(ctx->logctx, AV_LOG_ERROR, + "Error filling an external frame allocation request\n"); + return MFX_ERR_MEMORY_ALLOC; + } + } else if (req->Type & MFX_MEMTYPE_INTERNAL_FRAME) { + /* internal frames -- allocate a new hw frames context */ + AVHWFramesContext *ext_frames_ctx = (AVHWFramesContext*)ctx->hw_frames_ctx->data; + mfxFrameInfo *i = &req->Info; + + AVBufferRef *frames_ref, *mids_buf; + AVHWFramesContext *frames_ctx; + AVQSVFramesContext *frames_hwctx; + + frames_ref = av_hwframe_ctx_alloc(ext_frames_ctx->device_ref); + if (!frames_ref) + return MFX_ERR_MEMORY_ALLOC; + + frames_ctx = (AVHWFramesContext*)frames_ref->data; + frames_hwctx = frames_ctx->hwctx; + + frames_ctx->format = AV_PIX_FMT_QSV; + frames_ctx->sw_format = qsv_map_fourcc(i->FourCC); + frames_ctx->width = i->Width; + frames_ctx->height = i->Height; + frames_ctx->initial_pool_size = req->NumFrameSuggested; + + frames_hwctx->frame_type = req->Type; + + ret = av_hwframe_ctx_init(frames_ref); + if (ret < 0) { + av_log(ctx->logctx, AV_LOG_ERROR, + "Error initializing a frames context for an internal frame " + "allocation request\n"); + av_buffer_unref(&frames_ref); + return MFX_ERR_MEMORY_ALLOC; + } - for (j = 0; j < ctx->nb_mids; j++) - resp->mids[j] = &ctx->mids[j]; + mids_buf = qsv_create_mids(frames_ref); + if (!mids_buf) { + av_buffer_unref(&frames_ref); + return MFX_ERR_MEMORY_ALLOC; + } - resp->NumFrameActual = ctx->nb_mids; + ret = qsv_setup_mids(resp, frames_ref, mids_buf); + av_buffer_unref(&mids_buf); + av_buffer_unref(&frames_ref); + if (ret < 0) { + av_log(ctx->logctx, AV_LOG_ERROR, + "Error filling an internal frame allocation request\n"); + return MFX_ERR_MEMORY_ALLOC; + } + } else { + return MFX_ERR_UNSUPPORTED; + } return MFX_ERR_NONE; } static mfxStatus qsv_frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp) { + av_buffer_unref((AVBufferRef**)&resp->mids[resp->NumFrameActual]); + av_buffer_unref((AVBufferRef**)&resp->mids[resp->NumFrameActual + 1]); av_freep(&resp->mids); return MFX_ERR_NONE; } static mfxStatus qsv_frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) { - return MFX_ERR_UNSUPPORTED; + QSVMid *qsv_mid = mid; + AVHWFramesContext *hw_frames_ctx = (AVHWFramesContext*)qsv_mid->hw_frames_ref->data; + AVQSVFramesContext *hw_frames_hwctx = hw_frames_ctx->hwctx; + int size; + int ret; + mfxStatus err; + + if (qsv_mid->locked_frame) + return MFX_ERR_UNDEFINED_BEHAVIOR; + + /* Allocate a system memory frame that will hold the mapped data. */ + qsv_mid->locked_frame = av_frame_alloc(); + if (!qsv_mid->locked_frame) + return MFX_ERR_MEMORY_ALLOC; + qsv_mid->locked_frame->format = hw_frames_ctx->sw_format; + + /* wrap the provided handle in a hwaccel AVFrame */ + qsv_mid->hw_frame = av_frame_alloc(); + if (!qsv_mid->hw_frame) + goto fail; + + qsv_mid->hw_frame->data[3] = (uint8_t*)&qsv_mid->surf; + qsv_mid->hw_frame->format = AV_PIX_FMT_QSV; + + // doesn't really matter what buffer is used here + qsv_mid->hw_frame->buf[0] = av_buffer_alloc(1); + if (!qsv_mid->hw_frame->buf[0]) + goto fail; + + qsv_mid->hw_frame->width = hw_frames_ctx->width; + qsv_mid->hw_frame->height = hw_frames_ctx->height; + + qsv_mid->hw_frame->hw_frames_ctx = av_buffer_ref(qsv_mid->hw_frames_ref); + if (!qsv_mid->hw_frame->hw_frames_ctx) + goto fail; + + qsv_mid->surf.Info = hw_frames_hwctx->surfaces[0].Info; + qsv_mid->surf.Data.MemId = qsv_mid->handle; + + /* map the data to the system memory */ + ret = av_hwframe_map(qsv_mid->locked_frame, qsv_mid->hw_frame, + AV_HWFRAME_MAP_DIRECT); + if (ret < 0) + goto fail; + + ptr->Pitch = qsv_mid->locked_frame->linesize[0]; + ptr->Y = qsv_mid->locked_frame->data[0]; + ptr->U = qsv_mid->locked_frame->data[1]; + ptr->V = qsv_mid->locked_frame->data[1] + 1; + + return MFX_ERR_NONE; +fail: + av_frame_free(&qsv_mid->hw_frame); + av_frame_free(&qsv_mid->locked_frame); + return MFX_ERR_MEMORY_ALLOC; } static mfxStatus qsv_frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) { - return MFX_ERR_UNSUPPORTED; + QSVMid *qsv_mid = mid; + int ret; + + av_frame_free(&qsv_mid->locked_frame); + av_frame_free(&qsv_mid->hw_frame); + + return MFX_ERR_NONE; } static mfxStatus qsv_frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl) @@ -376,16 +585,15 @@ int ff_qsv_init_session_hwcontext(AVCodecContext *avctx, mfxSession *psession, } if (!opaque) { - av_freep(&qsv_frames_ctx->mids); - qsv_frames_ctx->mids = av_mallocz_array(frames_hwctx->nb_surfaces, - sizeof(*qsv_frames_ctx->mids)); - if (!qsv_frames_ctx->mids) - return AVERROR(ENOMEM); + qsv_frames_ctx->logctx = avctx; - qsv_frames_ctx->info = frames_hwctx->surfaces[0].Info; + /* allocate the memory ids for the external frames */ + av_buffer_unref(&qsv_frames_ctx->mids_buf); + qsv_frames_ctx->mids_buf = qsv_create_mids(qsv_frames_ctx->hw_frames_ctx); + if (!qsv_frames_ctx->mids_buf) + return AVERROR(ENOMEM); + qsv_frames_ctx->mids = (QSVMid*)qsv_frames_ctx->mids_buf->data; qsv_frames_ctx->nb_mids = frames_hwctx->nb_surfaces; - for (i = 0; i < frames_hwctx->nb_surfaces; i++) - qsv_frames_ctx->mids[i].handle = frames_hwctx->surfaces[i].Data.MemId; err = MFXVideoCORE_SetFrameAllocator(session, &frame_allocator); if (err != MFX_ERR_NONE) diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index 8b69891aa69c8..a8f486764b52a 100644 --- a/libavcodec/qsv_internal.h +++ b/libavcodec/qsv_internal.h @@ -37,7 +37,12 @@ MFX_VERSION_MAJOR == (MAJOR) && MFX_VERSION_MINOR >= (MINOR)) typedef struct QSVMid { + AVBufferRef *hw_frames_ref; mfxHDL handle; + + AVFrame *locked_frame; + AVFrame *hw_frame; + mfxFrameSurface1 surf; } QSVMid; typedef struct QSVFrame { @@ -52,7 +57,13 @@ typedef struct QSVFrame { typedef struct QSVFramesContext { AVBufferRef *hw_frames_ctx; - mfxFrameInfo info; + void *logctx; + + /* The memory ids for the external frames. + * Refcounted, since we need one reference owned by the QSVFramesContext + * (i.e. by the encoder/decoder) and another one given to the MFX session + * from the frame allocator. */ + AVBufferRef *mids_buf; QSVMid *mids; int nb_mids; } QSVFramesContext; diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index 398c319b300ec..61311005186de 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -416,8 +416,7 @@ int ff_qsv_decode_close(QSVContext *q) MFXClose(q->internal_session); av_buffer_unref(&q->frames_ctx.hw_frames_ctx); - av_freep(&q->frames_ctx.mids); - q->frames_ctx.nb_mids = 0; + av_buffer_unref(&q->frames_ctx.mids_buf); return 0; } diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index be8cbee884260..d680fc8cbc8d3 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -1093,8 +1093,7 @@ int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q) q->internal_session = NULL; av_buffer_unref(&q->frames_ctx.hw_frames_ctx); - av_freep(&q->frames_ctx.mids); - q->frames_ctx.nb_mids = 0; + av_buffer_unref(&q->frames_ctx.mids_buf); cur = q->work_frames; while (cur) { From 7471352f1915813cda725ce624607d84b5a3a61c Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Thu, 3 Nov 2016 16:03:54 +0100 Subject: [PATCH 0412/3374] pixfmt: Add GRAY12 --- doc/APIchanges | 3 +++ libavutil/pixdesc.c | 22 ++++++++++++++++++++++ libavutil/pixfmt.h | 4 ++++ libavutil/version.h | 2 +- 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index 735b9477ace27..6e0d27d993bc4 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-xx-xx - xxxxxxx - lavu 55.28.0 - pixfmt.h + Add AV_PIX_FMT_GRAY12(LE/BE). + 2016-xx-xx - xxxxxxx - lavu 55.27.0 - hwcontext.h Add av_hwframe_map() and associated AV_HWFRAME_MAP_* flags. Add av_hwframe_ctx_create_derived(). diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index 7987f292ac6a7..db90229ebc680 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -493,6 +493,27 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { }, .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, }, + [AV_PIX_FMT_GRAY12BE] = { + .name = "gray12be", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* Y */ + }, + .flags = AV_PIX_FMT_FLAG_BE, + .alias = "y12be", + }, + [AV_PIX_FMT_GRAY12LE] = { + .name = "gray12le", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* Y */ + }, + .alias = "y12le", + }, [AV_PIX_FMT_GRAY16BE] = { .name = "gray16be", .nb_components = 1, @@ -1950,6 +1971,7 @@ enum AVPixelFormat av_pix_fmt_swap_endianness(enum AVPixelFormat pix_fmt) case AV_PIX_FMT_ ## fmt ## LE: return AV_PIX_FMT_ ## fmt ## BE switch (pix_fmt) { + PIX_FMT_SWAP_ENDIANNESS(GRAY12); PIX_FMT_SWAP_ENDIANNESS(GRAY16); PIX_FMT_SWAP_ENDIANNESS(YA16); PIX_FMT_SWAP_ENDIANNESS(RGB48); diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index 0bee724998d87..5a7b78a6aab88 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -245,6 +245,9 @@ enum AVPixelFormat { AV_PIX_FMT_GBRAP12BE, ///< planar GBR 4:4:4:4 48bpp, big-endian AV_PIX_FMT_GBRAP12LE, ///< planar GBR 4:4:4:4 48bpp, little-endian + AV_PIX_FMT_GRAY12BE, ///< Y , 12bpp, big-endian + AV_PIX_FMT_GRAY12LE, ///< Y , 12bpp, little-endian + AV_PIX_FMT_NB, ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions }; @@ -259,6 +262,7 @@ enum AVPixelFormat { #define AV_PIX_FMT_BGR32 AV_PIX_FMT_NE(ABGR, RGBA) #define AV_PIX_FMT_BGR32_1 AV_PIX_FMT_NE(BGRA, ARGB) +#define AV_PIX_FMT_GRAY12 AV_PIX_FMT_NE(GRAY12BE, GRAY12LE) #define AV_PIX_FMT_GRAY16 AV_PIX_FMT_NE(GRAY16BE, GRAY16LE) #define AV_PIX_FMT_YA16 AV_PIX_FMT_NE(YA16BE, YA16LE) #define AV_PIX_FMT_RGB48 AV_PIX_FMT_NE(RGB48BE, RGB48LE) diff --git a/libavutil/version.h b/libavutil/version.h index 9287a0b5bd6fb..95aea2f67883c 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -54,7 +54,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 27 +#define LIBAVUTIL_VERSION_MINOR 28 #define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From ab839054e662d3227e1f795ba1dfd01fe1cf305c Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Thu, 3 Nov 2016 16:10:03 +0100 Subject: [PATCH 0413/3374] swscale: Add GRAY12 --- libswscale/input.c | 2 ++ libswscale/swscale_internal.h | 2 ++ libswscale/swscale_unscaled.c | 1 + libswscale/utils.c | 2 ++ tests/ref/fate/filter-pixdesc-gray12be | 1 + tests/ref/fate/filter-pixdesc-gray12le | 1 + tests/ref/fate/filter-pixfmts-copy | 2 ++ tests/ref/fate/filter-pixfmts-null | 2 ++ tests/ref/fate/filter-pixfmts-scale | 2 ++ tests/ref/fate/filter-pixfmts-vflip | 2 ++ 10 files changed, 17 insertions(+) create mode 100644 tests/ref/fate/filter-pixdesc-gray12be create mode 100644 tests/ref/fate/filter-pixdesc-gray12le diff --git a/libswscale/input.c b/libswscale/input.c index 9f2ef72894f7b..d8560a1f2b4c0 100644 --- a/libswscale/input.c +++ b/libswscale/input.c @@ -1120,6 +1120,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_YUV420P16LE: case AV_PIX_FMT_YUV422P16LE: case AV_PIX_FMT_YUV444P16LE: + case AV_PIX_FMT_GRAY12LE: case AV_PIX_FMT_GRAY16LE: c->lumToYV12 = bswap16Y_c; break; @@ -1148,6 +1149,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_YUV420P16BE: case AV_PIX_FMT_YUV422P16BE: case AV_PIX_FMT_YUV444P16BE: + case AV_PIX_FMT_GRAY12BE: case AV_PIX_FMT_GRAY16BE: c->lumToYV12 = bswap16Y_c; break; diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index abcdb9f41b8fb..e7a6eedd22b05 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -603,6 +603,8 @@ static av_always_inline int isRGB(enum AVPixelFormat pix_fmt) #define isGray(x) \ ((x) == AV_PIX_FMT_GRAY8 || \ (x) == AV_PIX_FMT_YA8 || \ + (x) == AV_PIX_FMT_GRAY12BE || \ + (x) == AV_PIX_FMT_GRAY12LE || \ (x) == AV_PIX_FMT_GRAY16BE || \ (x) == AV_PIX_FMT_GRAY16LE || \ (x) == AV_PIX_FMT_YA16BE || \ diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index 24c65ccd22d5b..d3863bba1089e 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -1097,6 +1097,7 @@ void ff_get_unscaled_swscale(SwsContext *c) IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR555) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR565) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGRA64) || + IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GRAY12) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GRAY16) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YA16) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRAP12)|| diff --git a/libswscale/utils.c b/libswscale/utils.c index 1c3bbb3305dde..6034b704658d1 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -107,6 +107,8 @@ static const FormatEntry format_entries[AV_PIX_FMT_NB] = { [AV_PIX_FMT_RGBA] = { 1, 1 }, [AV_PIX_FMT_ABGR] = { 1, 1 }, [AV_PIX_FMT_BGRA] = { 1, 1 }, + [AV_PIX_FMT_GRAY12BE] = { 1, 1 }, + [AV_PIX_FMT_GRAY12LE] = { 1, 1 }, [AV_PIX_FMT_GRAY16BE] = { 1, 1 }, [AV_PIX_FMT_GRAY16LE] = { 1, 1 }, [AV_PIX_FMT_YUV440P] = { 1, 1 }, diff --git a/tests/ref/fate/filter-pixdesc-gray12be b/tests/ref/fate/filter-pixdesc-gray12be new file mode 100644 index 0000000000000..de997347d5c28 --- /dev/null +++ b/tests/ref/fate/filter-pixdesc-gray12be @@ -0,0 +1 @@ +pixdesc-gray12be bff4fa5910e99725b275fb70270b0cf9 diff --git a/tests/ref/fate/filter-pixdesc-gray12le b/tests/ref/fate/filter-pixdesc-gray12le new file mode 100644 index 0000000000000..c2c5f68684c32 --- /dev/null +++ b/tests/ref/fate/filter-pixdesc-gray12le @@ -0,0 +1 @@ +pixdesc-gray12le d0900fab4e757ef17fff8c1ffd0b3816 diff --git a/tests/ref/fate/filter-pixfmts-copy b/tests/ref/fate/filter-pixfmts-copy index d9a5166e11740..bd16f110757c4 100644 --- a/tests/ref/fate/filter-pixfmts-copy +++ b/tests/ref/fate/filter-pixfmts-copy @@ -23,6 +23,8 @@ gbrp12le 654861b1837d312569395f598da1a2a1 gbrp9be cbe1bf8ead497a92362a749bd4b0a57e gbrp9le f88c68df5d699a4a7f1b0152df9f25fe gray 8c941e9bbf6da5336384c57f15a4a454 +gray12be aecffce8ea67ab93527dc74c1a523454 +gray12le eac4b15c8686f04ea73751294f40b8e0 gray16be 43bda75c197b0d59a9b87ee941553644 gray16le a4ea1369ef1efff0e1341a1dc42dbfdf monob e13b2cbfb93d3ed6fdc1f256662ea959 diff --git a/tests/ref/fate/filter-pixfmts-null b/tests/ref/fate/filter-pixfmts-null index d9a5166e11740..bd16f110757c4 100644 --- a/tests/ref/fate/filter-pixfmts-null +++ b/tests/ref/fate/filter-pixfmts-null @@ -23,6 +23,8 @@ gbrp12le 654861b1837d312569395f598da1a2a1 gbrp9be cbe1bf8ead497a92362a749bd4b0a57e gbrp9le f88c68df5d699a4a7f1b0152df9f25fe gray 8c941e9bbf6da5336384c57f15a4a454 +gray12be aecffce8ea67ab93527dc74c1a523454 +gray12le eac4b15c8686f04ea73751294f40b8e0 gray16be 43bda75c197b0d59a9b87ee941553644 gray16le a4ea1369ef1efff0e1341a1dc42dbfdf monob e13b2cbfb93d3ed6fdc1f256662ea959 diff --git a/tests/ref/fate/filter-pixfmts-scale b/tests/ref/fate/filter-pixfmts-scale index 2a60f72f8bd75..e1737f0b206e7 100644 --- a/tests/ref/fate/filter-pixfmts-scale +++ b/tests/ref/fate/filter-pixfmts-scale @@ -23,6 +23,8 @@ gbrp12le 735061c07442657580577d1cede3a636 gbrp9be 01c837e1def99abec205b80d21b68bf0 gbrp9le dd982d59c3d71c3b201f2d9363d8952c gray 4c571fb634a75f177b64cee168fbf3a1 +gray12be d237d56e08482038ebc5f3943d6ec8d5 +gray12le dcd15a0ed89bd019cc367b552fc9b1c0 gray16be 9b57ff7d2090b47e4427bee79dba0d9e gray16le 17d2c00c6ffe346dfb632d927ebbf30a monob e28955319a03f1850c467f8fe65b2a22 diff --git a/tests/ref/fate/filter-pixfmts-vflip b/tests/ref/fate/filter-pixfmts-vflip index 93a292d6bc531..11a48c7c71506 100644 --- a/tests/ref/fate/filter-pixfmts-vflip +++ b/tests/ref/fate/filter-pixfmts-vflip @@ -23,6 +23,8 @@ gbrp12le b7b27715bc9054a93ba81f110cf42ee5 gbrp9be 2ae8f0d3b079d6550a2b1d4a7c4a6e4b gbrp9le c62df0f386c957cc9cacb3c8014542eb gray 684ba667effbbf5983f46a9bea4afaae +gray12be e33397832d19ec628f3e887e0a16ccc7 +gray12le c8a8d7267e2595a0c4ce5d582bea23a1 gray16be 112077b2f1c85cbd44907ed271901b28 gray16le 1d7be18af19f4ff847ff4bc7c610c8cc monob 0e4946183903fea3ef246c16385e236c From 43de8b328b62cf21ec176c3989065168da471a5f Mon Sep 17 00:00:00 2001 From: Andreas Cadhalpun Date: Fri, 4 Nov 2016 23:33:02 +0100 Subject: [PATCH 0414/3374] lzf: update pointer p after realloc This fixes heap-use-after-free detected by AddressSanitizer. Signed-off-by: Andreas Cadhalpun Signed-off-by: Luca Barbato --- libavcodec/lzf.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/lzf.c b/libavcodec/lzf.c index 35b932bd087e9..0329fe0eec7a6 100644 --- a/libavcodec/lzf.c +++ b/libavcodec/lzf.c @@ -53,6 +53,7 @@ int ff_lzf_uncompress(GetByteContext *gb, uint8_t **buf, int64_t *size) ret = av_reallocp(buf, *size); if (ret < 0) return ret; + p = *buf + len; } bytestream2_get_buffer(gb, p, s); @@ -75,6 +76,7 @@ int ff_lzf_uncompress(GetByteContext *gb, uint8_t **buf, int64_t *size) ret = av_reallocp(buf, *size); if (ret < 0) return ret; + p = *buf + len; } av_memcpy_backptr(p, off, l); From 943533d64c7fa7a1b2fc9559e67652c349d21d51 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 9 Nov 2015 12:54:53 +0100 Subject: [PATCH 0415/3374] avconv: Correct function pointer assignments in options array MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes several warnings of the type avconv_opt.c:2356:5: warning: ISO C forbids initialization between function pointer and ‘void *’ [-Wpedantic] --- avconv_opt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/avconv_opt.c b/avconv_opt.c index ba37a3a31d681..1064cf4668b4d 100644 --- a/avconv_opt.c +++ b/avconv_opt.c @@ -2539,7 +2539,7 @@ const OptionDef options[] = { { "target", HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_target }, "specify target file type (\"vcd\", \"svcd\", \"dvd\"," " \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" }, - { "vsync", HAS_ARG | OPT_EXPERT, { opt_vsync }, + { "vsync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_vsync }, "video sync method", "" }, { "async", HAS_ARG | OPT_INT | OPT_EXPERT, { &audio_sync_method }, "audio sync method", "" }, @@ -2619,9 +2619,9 @@ const OptionDef options[] = { { "passlogfile", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_EXPERT | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(passlogfiles) }, "select two pass log file name prefix", "prefix" }, - { "vstats", OPT_VIDEO | OPT_EXPERT , { &opt_vstats }, + { "vstats", OPT_VIDEO | OPT_EXPERT , { .func_arg = &opt_vstats }, "dump video coding statistics to file" }, - { "vstats_file", OPT_VIDEO | HAS_ARG | OPT_EXPERT , { opt_vstats_file }, + { "vstats_file", OPT_VIDEO | HAS_ARG | OPT_EXPERT , { .func_arg = opt_vstats_file }, "dump video coding statistics to file", "file" }, { "vf", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_video_filters }, "video filters", "filter list" }, From 88f0cf8cd30c8ea283430e6710a7bd98bb9c0301 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 9 Nov 2015 12:55:37 +0100 Subject: [PATCH 0416/3374] avplay: Correct function pointer assignments in options array MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit avplay.c:2928:5: warning: ISO C forbids initialization between function pointer and ‘void *’ [-Wpedantic] --- avplay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avplay.c b/avplay.c index 47701320bcddf..e5ee9dbbef435 100644 --- a/avplay.c +++ b/avplay.c @@ -2940,7 +2940,7 @@ static const OptionDef options[] = { { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" }, { "vf", OPT_STRING | HAS_ARG, { &vfilters }, "video filters", "filter list" }, { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" }, - { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { opt_default }, "generic catch all option", "" }, + { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catchall option", "" }, { "i", 0, { NULL }, "avconv compatibility dummy option", ""}, { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" }, { "c", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_INPUT, { .off = OFF(codec_names) }, "codec name", "codec" }, From 0361e4dcb4d394c88c33364415a3b8fe315b67d1 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 3 Jan 2016 22:45:47 +0100 Subject: [PATCH 0417/3374] h264_qpel: x86: Move function with only one instance out of template macro libavcodec/x86/h264_qpel.c:392:785: warning: unused function 'ff_avg_h264_qpel8or16_hv1_lowpass_mmxext' [-Wunused-function] --- libavcodec/x86/h264_qpel.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/libavcodec/x86/h264_qpel.c b/libavcodec/x86/h264_qpel.c index 43e150c3c595b..74458259a6014 100644 --- a/libavcodec/x86/h264_qpel.c +++ b/libavcodec/x86/h264_qpel.c @@ -75,6 +75,17 @@ void ff_ ## OPNAME ## _pixels8_l2_shift5_mmxext(uint8_t *dst, const int16_t *src DEF_QPEL(avg) DEF_QPEL(put) +static av_always_inline void ff_put_h264_qpel8or16_hv1_lowpass_mmxext(int16_t *tmp, const uint8_t *src, int tmpStride, int srcStride, int size) +{ + int w = (size + 8) >> 2; + src -= 2 * srcStride + 2; + while (w--) { + ff_put_h264_qpel8or16_hv1_lowpass_op_mmxext(src, tmp, srcStride, size); + tmp += 4; + src += 4; + } +} + #define QPEL_H264(OPNAME, OP, MMX)\ static av_always_inline void ff_ ## OPNAME ## h264_qpel4_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, const uint8_t *src, int dstStride, int tmpStride, int srcStride){\ int w=3;\ @@ -95,15 +106,6 @@ static av_always_inline void ff_ ## OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(u dst += 4;\ ff_ ## OPNAME ## h264_qpel8or16_v_lowpass_op_mmxext(dst, src, dstStride, srcStride, h);\ }\ -static av_always_inline void ff_ ## OPNAME ## h264_qpel8or16_hv1_lowpass_ ## MMX(int16_t *tmp, const uint8_t *src, int tmpStride, int srcStride, int size){\ - int w = (size+8)>>2;\ - src -= 2*srcStride+2;\ - while(w--){\ - ff_ ## OPNAME ## h264_qpel8or16_hv1_lowpass_op_mmxext(src, tmp, srcStride, size);\ - tmp += 4;\ - src += 4;\ - }\ -}\ static av_always_inline void ff_ ## OPNAME ## h264_qpel8or16_hv2_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, int dstStride, int tmpStride, int size){\ int w = size>>4;\ do{\ From 17dac56b8fdd80c594c39b76de3f27a7949afbde Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Mon, 31 Oct 2016 14:50:59 -0400 Subject: [PATCH 0418/3374] lavu: Rename ycgco color space appropriately Planes are ordered as the name suggests now. Signed-off-by: Vittorio Giovara --- libavcodec/options_table.h | 3 ++- libavcodec/version.h | 2 +- libavutil/pixdesc.c | 2 +- libavutil/pixfmt.h | 3 ++- libavutil/version.h | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index b1f9a9235c709..057b1188b2eb5 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -476,11 +476,12 @@ static const AVOption avcodec_options[] = { {"bt470bg", "BT.470 BG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT470BG }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, {"smpte170m", "SMPTE 170 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE170M }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, {"smpte240m", "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE240M }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, -{"ycocg", "YCOCG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCOCG }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"ycgco", "YCGCO", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCGCO }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, {"bt2020nc", "BT.2020 NCL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, {"bt2020c", "BT.2020 CL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_CL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, {"smpte2085", "SMPTE 2085", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE2085 }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, {"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"ycocg", "YCGCO", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCGCO }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, {"bt2020_ncl", "BT.2020 NCL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, {"bt2020_cl", "BT.2020 CL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_CL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, {"color_range", "color range", OFFSET(color_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, AVCOL_RANGE_NB-1, V|E|D, "color_range_type"}, diff --git a/libavcodec/version.h b/libavcodec/version.h index a4856bf0356fd..322affcd31714 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 28 -#define LIBAVCODEC_VERSION_MICRO 2 +#define LIBAVCODEC_VERSION_MICRO 3 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index db90229ebc680..2f1adf5d8dda5 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -1818,7 +1818,7 @@ static const char *color_space_names[] = { [AVCOL_SPC_BT470BG] = "bt470bg", [AVCOL_SPC_SMPTE170M] = "smpte170m", [AVCOL_SPC_SMPTE240M] = "smpte240m", - [AVCOL_SPC_YCOCG] = "ycgco", + [AVCOL_SPC_YCGCO] = "ycgco", [AVCOL_SPC_BT2020_NCL] = "bt2020nc", [AVCOL_SPC_BT2020_CL] = "bt2020c", [AVCOL_SPC_SMPTE2085] = "smpte2085", diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index 5a7b78a6aab88..2a0c85e269979 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -374,7 +374,8 @@ enum AVColorSpace { AVCOL_SPC_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 AVCOL_SPC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC AVCOL_SPC_SMPTE240M = 7, ///< functionally identical to above - AVCOL_SPC_YCOCG = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16 + AVCOL_SPC_YCGCO = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16 + AVCOL_SPC_YCOCG = AVCOL_SPC_YCGCO, AVCOL_SPC_BT2020_NCL = 9, ///< ITU-R BT2020 non-constant luminance system AVCOL_SPC_BT2020_CL = 10, ///< ITU-R BT2020 constant luminance system AVCOL_SPC_SMPTE2085 = 11, ///< SMPTE 2085, Y'D'zD'x diff --git a/libavutil/version.h b/libavutil/version.h index 95aea2f67883c..f1102312bacc7 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -54,7 +54,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 28 +#define LIBAVUTIL_VERSION_MINOR 29 #define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From bed2c4b2652b1412b584e5545d6dd2ef8c613be0 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Wed, 2 Nov 2016 12:15:16 -0400 Subject: [PATCH 0419/3374] lavc: Add hevc main10 profile to avconv cli --- libavcodec/options_table.h | 1 + libavcodec/version.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index 057b1188b2eb5..9fff50dc6f036 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -371,6 +371,7 @@ static const AVOption avcodec_options[] = { {"dts_96_24", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_96_24 }, INT_MIN, INT_MAX, A|E, "profile"}, {"dts_hd_hra", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_HD_HRA }, INT_MIN, INT_MAX, A|E, "profile"}, {"dts_hd_ma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_HD_MA }, INT_MIN, INT_MAX, A|E, "profile"}, +{"main10", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_HEVC_MAIN_10 }, INT_MIN, INT_MAX, A|E, "profile"}, {"level", NULL, OFFSET(level), AV_OPT_TYPE_INT, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"}, {"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"}, #if FF_API_PRIVATE_OPT diff --git a/libavcodec/version.h b/libavcodec/version.h index 322affcd31714..6f58bc8c513aa 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 28 -#define LIBAVCODEC_VERSION_MICRO 3 +#define LIBAVCODEC_VERSION_MICRO 4 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From 5be21531119d7a97ebc706800d1608272ee5a507 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Wed, 2 Nov 2016 12:03:17 -0400 Subject: [PATCH 0420/3374] hevc: Move hevc_decode_extradata before frame decoding Avoids a forward-declaration in the following commit. Signed-off-by: Vittorio Giovara --- libavcodec/hevcdec.c | 148 +++++++++++++++++++++---------------------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index e58d5f8f58630..4dacdd7c88fe0 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -2698,6 +2698,80 @@ static int verify_md5(HEVCContext *s, AVFrame *frame) return 0; } +static int hevc_decode_extradata(HEVCContext *s) +{ + AVCodecContext *avctx = s->avctx; + GetByteContext gb; + int ret, i; + + bytestream2_init(&gb, avctx->extradata, avctx->extradata_size); + + if (avctx->extradata_size > 3 && + (avctx->extradata[0] || avctx->extradata[1] || + avctx->extradata[2] > 1)) { + /* It seems the extradata is encoded as hvcC format. + * Temporarily, we support configurationVersion==0 until 14496-15 3rd + * is finalized. When finalized, configurationVersion will be 1 and we + * can recognize hvcC by checking if avctx->extradata[0]==1 or not. */ + int i, j, num_arrays, nal_len_size; + + s->is_nalff = 1; + + bytestream2_skip(&gb, 21); + nal_len_size = (bytestream2_get_byte(&gb) & 3) + 1; + num_arrays = bytestream2_get_byte(&gb); + + /* nal units in the hvcC always have length coded with 2 bytes, + * so put a fake nal_length_size = 2 while parsing them */ + s->nal_length_size = 2; + + /* Decode nal units from hvcC. */ + for (i = 0; i < num_arrays; i++) { + int type = bytestream2_get_byte(&gb) & 0x3f; + int cnt = bytestream2_get_be16(&gb); + + for (j = 0; j < cnt; j++) { + // +2 for the nal size field + int nalsize = bytestream2_peek_be16(&gb) + 2; + if (bytestream2_get_bytes_left(&gb) < nalsize) { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid NAL unit size in extradata.\n"); + return AVERROR_INVALIDDATA; + } + + ret = decode_nal_units(s, gb.buffer, nalsize); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, + "Decoding nal unit %d %d from hvcC failed\n", + type, i); + return ret; + } + bytestream2_skip(&gb, nalsize); + } + } + + /* Now store right nal length size, that will be used to parse + * all other nals */ + s->nal_length_size = nal_len_size; + } else { + s->is_nalff = 0; + ret = decode_nal_units(s, avctx->extradata, avctx->extradata_size); + if (ret < 0) + return ret; + } + + /* export stream parameters from the first SPS */ + for (i = 0; i < FF_ARRAY_ELEMS(s->ps.sps_list); i++) { + if (s->ps.sps_list[i]) { + const HEVCSPS *sps = (const HEVCSPS*)s->ps.sps_list[i]->data; + export_stream_params(s->avctx, &s->ps, sps); + break; + } + } + + return 0; +} + static int hevc_decode_frame(AVCodecContext *avctx, void *data, int *got_output, AVPacket *avpkt) { @@ -2923,80 +2997,6 @@ static int hevc_update_thread_context(AVCodecContext *dst, return 0; } -static int hevc_decode_extradata(HEVCContext *s) -{ - AVCodecContext *avctx = s->avctx; - GetByteContext gb; - int ret, i; - - bytestream2_init(&gb, avctx->extradata, avctx->extradata_size); - - if (avctx->extradata_size > 3 && - (avctx->extradata[0] || avctx->extradata[1] || - avctx->extradata[2] > 1)) { - /* It seems the extradata is encoded as hvcC format. - * Temporarily, we support configurationVersion==0 until 14496-15 3rd - * is finalized. When finalized, configurationVersion will be 1 and we - * can recognize hvcC by checking if avctx->extradata[0]==1 or not. */ - int i, j, num_arrays, nal_len_size; - - s->is_nalff = 1; - - bytestream2_skip(&gb, 21); - nal_len_size = (bytestream2_get_byte(&gb) & 3) + 1; - num_arrays = bytestream2_get_byte(&gb); - - /* nal units in the hvcC always have length coded with 2 bytes, - * so put a fake nal_length_size = 2 while parsing them */ - s->nal_length_size = 2; - - /* Decode nal units from hvcC. */ - for (i = 0; i < num_arrays; i++) { - int type = bytestream2_get_byte(&gb) & 0x3f; - int cnt = bytestream2_get_be16(&gb); - - for (j = 0; j < cnt; j++) { - // +2 for the nal size field - int nalsize = bytestream2_peek_be16(&gb) + 2; - if (bytestream2_get_bytes_left(&gb) < nalsize) { - av_log(s->avctx, AV_LOG_ERROR, - "Invalid NAL unit size in extradata.\n"); - return AVERROR_INVALIDDATA; - } - - ret = decode_nal_units(s, gb.buffer, nalsize); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, - "Decoding nal unit %d %d from hvcC failed\n", - type, i); - return ret; - } - bytestream2_skip(&gb, nalsize); - } - } - - /* Now store right nal length size, that will be used to parse - * all other nals */ - s->nal_length_size = nal_len_size; - } else { - s->is_nalff = 0; - ret = decode_nal_units(s, avctx->extradata, avctx->extradata_size); - if (ret < 0) - return ret; - } - - /* export stream parameters from the first SPS */ - for (i = 0; i < FF_ARRAY_ELEMS(s->ps.sps_list); i++) { - if (s->ps.sps_list[i]) { - const HEVCSPS *sps = (const HEVCSPS*)s->ps.sps_list[i]->data; - export_stream_params(s->avctx, &s->ps, sps); - break; - } - } - - return 0; -} - static av_cold int hevc_decode_init(AVCodecContext *avctx) { HEVCContext *s = avctx->priv_data; From 2fe30b4743c0f4c3bdf37b91ae534cafa85e4036 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Mon, 7 Nov 2016 17:36:20 -0500 Subject: [PATCH 0421/3374] hevc: Allow parsing external extradata buffers --- libavcodec/hevcdec.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 4dacdd7c88fe0..d9463370bc9a4 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -2698,17 +2698,15 @@ static int verify_md5(HEVCContext *s, AVFrame *frame) return 0; } -static int hevc_decode_extradata(HEVCContext *s) +static int hevc_decode_extradata(HEVCContext *s, uint8_t *buf, int length) { AVCodecContext *avctx = s->avctx; GetByteContext gb; int ret, i; - bytestream2_init(&gb, avctx->extradata, avctx->extradata_size); + bytestream2_init(&gb, buf, length); - if (avctx->extradata_size > 3 && - (avctx->extradata[0] || avctx->extradata[1] || - avctx->extradata[2] > 1)) { + if (length > 3 && (buf[0] || buf[1] || buf[2] > 1)) { /* It seems the extradata is encoded as hvcC format. * Temporarily, we support configurationVersion==0 until 14496-15 3rd * is finalized. When finalized, configurationVersion will be 1 and we @@ -2755,7 +2753,7 @@ static int hevc_decode_extradata(HEVCContext *s) s->nal_length_size = nal_len_size; } else { s->is_nalff = 0; - ret = decode_nal_units(s, avctx->extradata, avctx->extradata_size); + ret = decode_nal_units(s, buf, length); if (ret < 0) return ret; } @@ -3009,7 +3007,7 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx) return ret; if (avctx->extradata_size > 0 && avctx->extradata) { - ret = hevc_decode_extradata(s); + ret = hevc_decode_extradata(s, avctx->extradata, avctx->extradata_size); if (ret < 0) { hevc_decode_free(avctx); return ret; From 47a795727f5433f5238a8a244cf181f61ea5af2c Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Wed, 2 Nov 2016 12:03:18 -0400 Subject: [PATCH 0422/3374] hevc: Support extradata changes from multiple stsd Signed-off-by: Vittorio Giovara --- libavcodec/hevcdec.c | 10 ++++++++++ libavformat/mov.c | 12 +++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index d9463370bc9a4..5f1b5c3c4a8fd 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -2774,6 +2774,8 @@ static int hevc_decode_frame(AVCodecContext *avctx, void *data, int *got_output, AVPacket *avpkt) { int ret; + int new_extradata_size; + uint8_t *new_extradata; HEVCContext *s = avctx->priv_data; if (!avpkt->size) { @@ -2785,6 +2787,14 @@ static int hevc_decode_frame(AVCodecContext *avctx, void *data, int *got_output, return 0; } + new_extradata = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, + &new_extradata_size); + if (new_extradata && new_extradata_size > 0) { + ret = hevc_decode_extradata(s, new_extradata, new_extradata_size); + if (ret < 0) + return ret; + } + s->ref = NULL; ret = decode_nal_units(s, avpkt->data, avpkt->size); if (ret < 0) diff --git a/libavformat/mov.c b/libavformat/mov.c index 194daebc6e6a0..d4454bb218dcd 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1780,13 +1780,11 @@ static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb, int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format); if (codec_tag && - (codec_tag == AV_RL32("hvc1") || - codec_tag == AV_RL32("hev1") || - (codec_tag != format && - // prores is allowed to have differing data format and codec tag - codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") && - (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id - : codec_tag != MKTAG('j','p','e','g'))))) { + (codec_tag != format && + // prores is allowed to have differing data format and codec tag + codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") && + (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id + : codec_tag != MKTAG('j','p','e','g')))) { /* Multiple fourcc, we skip JPEG. This is not correct, we should * export it as a separate AVStream but this needs a few changes * in the MOV demuxer, patch welcome. */ From de6e2ff3ddf506d5b487c2f226cea73e095ad6d1 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Mon, 7 Nov 2016 22:30:22 -0500 Subject: [PATCH 0423/3374] mov: Read multiple stsd from DV Signed-off-by: Vittorio Giovara --- libavformat/mov.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavformat/mov.c b/libavformat/mov.c index d4454bb218dcd..b5b2a5b0303af 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1783,6 +1783,8 @@ static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb, (codec_tag != format && // prores is allowed to have differing data format and codec tag codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") && + // so is dv (sigh) + codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") && (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id : codec_tag != MKTAG('j','p','e','g')))) { /* Multiple fourcc, we skip JPEG. This is not correct, we should From 9498237049d15812cecb79df47b196c73013908b Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 3 Nov 2016 23:40:26 +0100 Subject: [PATCH 0424/3374] checkasm: Add --test parameter to check only specific components MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Inspired by a patch from Martin Storsjö . --- tests/checkasm/checkasm.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c index 5f0d8fdae6e41..61515deb88a5b 100644 --- a/tests/checkasm/checkasm.c +++ b/tests/checkasm/checkasm.c @@ -180,6 +180,7 @@ static struct { int nop_time; int cpu_flag; const char *cpu_flag_name; + const char *test_name; } state; /* PRNG state */ @@ -470,6 +471,8 @@ static void check_cpu_flag(const char *name, int flag) state.cpu_flag_name = name; for (i = 0; tests[i].func; i++) { + if (state.test_name && strcmp(tests[i].name, state.test_name)) + continue; state.current_test_name = tests[i].name; tests[i].func(); } @@ -487,7 +490,7 @@ static void print_cpu_name(void) int main(int argc, char *argv[]) { - unsigned int seed; + unsigned int seed = av_get_random_seed(); int i, ret = 0; #if ARCH_ARM && HAVE_ARMV5TE_EXTERNAL @@ -500,22 +503,27 @@ int main(int argc, char *argv[]) return 0; } - if (argc > 1 && !strncmp(argv[1], "--bench", 7)) { + while (argc > 1) { + if (!strncmp(argv[1], "--bench", 7)) { #ifndef AV_READ_TIME - fprintf(stderr, "checkasm: --bench is not supported on your system\n"); - return 1; + fprintf(stderr, "checkasm: --bench is not supported on your system\n"); + return 1; #endif - if (argv[1][7] == '=') { - state.bench_pattern = argv[1] + 8; - state.bench_pattern_len = strlen(state.bench_pattern); - } else - state.bench_pattern = ""; + if (argv[1][7] == '=') { + state.bench_pattern = argv[1] + 8; + state.bench_pattern_len = strlen(state.bench_pattern); + } else + state.bench_pattern = ""; + } else if (!strncmp(argv[1], "--test=", 7)) { + state.test_name = argv[1] + 7; + } else { + seed = strtoul(argv[1], NULL, 10); + } argc--; argv++; } - seed = (argc > 1) ? strtoul(argv[1], NULL, 10) : av_get_random_seed(); fprintf(stderr, "checkasm: using random seed %u\n", seed); av_lfg_init(&checkasm_lfg, seed); From 4537647c0429fe7c8ee655ac3fda856ba67f58a0 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 3 Nov 2016 23:32:45 +0100 Subject: [PATCH 0425/3374] fate: checkasm: Split monolithic test into individual components --- tests/fate/checkasm.mak | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/tests/fate/checkasm.mak b/tests/fate/checkasm.mak index daefe69404bbc..939eb567cda0a 100644 --- a/tests/fate/checkasm.mak +++ b/tests/fate/checkasm.mak @@ -1,5 +1,23 @@ -fate-checkasm: tests/checkasm/checkasm$(EXESUF) -fate-checkasm: CMD = run tests/checkasm/checkasm -fate-checkasm: REF = /dev/null +FATE_CHECKASM = fate-checkasm-audiodsp \ + fate-checkasm-blockdsp \ + fate-checkasm-bswapdsp \ + fate-checkasm-dcadsp \ + fate-checkasm-fmtconvert \ + fate-checkasm-h264dsp \ + fate-checkasm-h264pred \ + fate-checkasm-h264qpel \ + fate-checkasm-hevc_add_res \ + fate-checkasm-hevc_idct \ + fate-checkasm-hevc_mc \ + fate-checkasm-huffyuvdsp \ + fate-checkasm-synth_filter \ + fate-checkasm-v210enc \ + fate-checkasm-vp8dsp \ + fate-checkasm-vp9dsp \ -FATE += fate-checkasm +$(FATE_CHECKASM): tests/checkasm/checkasm$(EXESUF) +$(FATE_CHECKASM): CMD = run tests/checkasm/checkasm --test=$(@:fate-checkasm-%=%) +$(FATE_CHECKASM): REF = /dev/null + +FATE += $(FATE_CHECKASM) +fate-checkasm: $(FATE_CHECKASM) From 59d2b00d201935c16408a2917957d89a170fe58f Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 6 Nov 2016 18:33:05 +0100 Subject: [PATCH 0426/3374] configure: Add --quiet command line parameter to suppress informative output --- configure | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 23be4255ff90b..e862757d44a24 100755 --- a/configure +++ b/configure @@ -63,6 +63,7 @@ Options: [defaults in brackets after descriptions] Help options: --help print this message + --quiet Suppress showing informative output --list-decoders show all available decoders --list-encoders show all available encoders --list-hwaccels show all available hardware accelerators @@ -1167,7 +1168,7 @@ apply(){ } cp_if_changed(){ - cmp -s "$1" "$2" && echo "$2 is unchanged" && return + cmp -s "$1" "$2" && { test "$quiet" != "yes" && echo "$2 is unchanged"; } && return mkdir -p "$(dirname $2)" $cp_f "$1" "$2" } @@ -2740,6 +2741,8 @@ for opt do ;; --help|-h) show_help ;; + --quiet|-q) quiet=yes + ;; *) optname="${opt%%=*}" optname="${optname#--}" @@ -5112,6 +5115,8 @@ expand_deps(){ map 'expand_deps $v' $LIBRARY_LIST +if test "$quiet" != "yes"; then + echo "install prefix $prefix" echo "source path $source_path" echo "C compiler $cc" @@ -5211,6 +5216,8 @@ echo "License: $license" echo "Creating config.mak and config.h..." +fi # test "$quiet" != "yes" + test -e Makefile || echo "include $source_path/Makefile" > Makefile config_files="$TMPH config.mak" From 67deba8a416d818f3d95aef0aa916589090396e2 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 16 Dec 2015 18:01:34 +0100 Subject: [PATCH 0427/3374] Use avpriv_report_missing_feature() where appropriate --- libavcodec/aacdec.c | 3 +-- libavcodec/alac.c | 8 ++++---- libavcodec/bmp.c | 3 ++- libavcodec/fraps.c | 4 +--- libavcodec/g2meet.c | 11 +++++------ libavcodec/g723_1enc.c | 3 ++- libavcodec/h264_ps.c | 5 ++--- libavcodec/hevc_ps.c | 7 +++---- libavcodec/hevc_ps_enc.c | 10 ++++++---- libavcodec/libopenjpegdec.c | 2 +- libavcodec/libopusenc.c | 5 +++-- libavcodec/mjpegdec.c | 7 ++++--- libavcodec/opus_silk.c | 2 +- libavcodec/shorten.c | 4 ++-- libavcodec/takdec.c | 2 +- libavcodec/txd.c | 7 +++---- libavcodec/vp5.c | 2 +- libavcodec/xwddec.c | 2 +- libavdevice/vfwcap.c | 3 +-- libavdevice/xcbgrab.c | 2 +- libavformat/avienc.c | 3 +-- libavformat/lxfdec.c | 5 ++--- libavformat/matroskadec.c | 7 +++---- libavformat/mpc8.c | 2 +- libavformat/oggparseopus.c | 6 +++--- libavformat/qcp.c | 4 ++-- libavformat/rsoenc.c | 2 +- libavformat/rtpdec_jpeg.c | 2 +- libavformat/rtpdec_latm.c | 6 +++--- libavformat/rtpdec_xiph.c | 14 ++++++-------- libavformat/rtsp.c | 3 +-- libavformat/spdifenc.c | 3 ++- libavformat/wvdec.c | 3 ++- 33 files changed, 73 insertions(+), 79 deletions(-) diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index 6a06062c53448..22ebcdc570569 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -1246,8 +1246,7 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics, return AVERROR_INVALIDDATA; } else { if (aot == AOT_ER_AAC_LD) { - av_log(ac->avctx, AV_LOG_ERROR, - "LTP in ER AAC LD not yet implemented.\n"); + avpriv_report_missing_feature(ac->avctx, "LTP in ER AAC LD"); return AVERROR_PATCHWELCOME; } if ((ics->ltp.present = get_bits(gb, 1))) diff --git a/libavcodec/alac.c b/libavcodec/alac.c index 0d2a7ca01df44..83d777c760a8d 100644 --- a/libavcodec/alac.c +++ b/libavcodec/alac.c @@ -266,7 +266,7 @@ static int decode_element(AVCodecContext *avctx, AVFrame *frame, int ch_index, alac->extra_bits = get_bits(&alac->gb, 2) << 3; bps = alac->sample_size - alac->extra_bits + channels - 1; if (bps > 32) { - av_log(avctx, AV_LOG_ERROR, "bps is unsupported: %d\n", bps); + avpriv_report_missing_feature(avctx, "bps %d", bps); return AVERROR_PATCHWELCOME; } @@ -424,7 +424,7 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data, break; } if (element > TYPE_CPE && element != TYPE_LFE) { - av_log(avctx, AV_LOG_ERROR, "syntax element unsupported: %d", element); + avpriv_report_missing_feature(avctx, "Syntax element %d", element); return AVERROR_PATCHWELCOME; } @@ -568,8 +568,8 @@ static av_cold int alac_decode_init(AVCodecContext * avctx) avctx->channels = alac->channels; } if (avctx->channels > ALAC_MAX_CHANNELS) { - av_log(avctx, AV_LOG_ERROR, "Unsupported channel count: %d\n", - avctx->channels); + avpriv_report_missing_feature(avctx, "Channel count %d", + avctx->channels); return AVERROR_PATCHWELCOME; } avctx->channel_layout = ff_alac_channel_layouts[alac->channels - 1]; diff --git a/libavcodec/bmp.c b/libavcodec/bmp.c index 648fa68e1ff7c..5c7acb6e72d25 100644 --- a/libavcodec/bmp.c +++ b/libavcodec/bmp.c @@ -98,7 +98,8 @@ static int bmp_decode_frame(AVCodecContext *avctx, height = bytestream_get_le16(&buf); break; default: - av_log(avctx, AV_LOG_ERROR, "unsupported BMP file, patch welcome\n"); + avpriv_report_missing_feature(avctx, "Information header size %u", + ihsize); return AVERROR_PATCHWELCOME; } diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c index c4ec23e2811ad..55051ffe7e162 100644 --- a/libavcodec/fraps.c +++ b/libavcodec/fraps.c @@ -163,9 +163,7 @@ static int decode_frame(AVCodecContext *avctx, prev_pic_bit = header & (1U << 31); /* bit 31 means same as previous pic */ if (version > 5) { - av_log(avctx, AV_LOG_ERROR, - "This file is encoded with Fraps version %u. " - "This codec can only decode versions <= 5.\n", version); + avpriv_report_missing_feature(avctx, "Fraps version %u", version); return AVERROR_PATCHWELCOME; } diff --git a/libavcodec/g2meet.c b/libavcodec/g2meet.c index a89610d6c3a93..7e90916274dd9 100644 --- a/libavcodec/g2meet.c +++ b/libavcodec/g2meet.c @@ -1424,9 +1424,8 @@ static int g2m_decode_frame(AVCodecContext *avctx, void *data, } c->compression = bytestream2_get_be32(&bc); if (c->compression != 2 && c->compression != 3) { - av_log(avctx, AV_LOG_ERROR, - "Unknown compression method %d\n", - c->compression); + avpriv_report_missing_feature(avctx, "Compression method %d", + c->compression); return AVERROR_PATCHWELCOME; } c->tile_width = bytestream2_get_be32(&bc); @@ -1453,9 +1452,9 @@ static int g2m_decode_frame(AVCodecContext *avctx, void *data, g_mask = bytestream2_get_be32(&bc); b_mask = bytestream2_get_be32(&bc); if (r_mask != 0xFF0000 || g_mask != 0xFF00 || b_mask != 0xFF) { - av_log(avctx, AV_LOG_ERROR, - "Invalid or unsupported bitmasks: R=%"PRIX32", G=%"PRIX32", B=%"PRIX32"\n", - r_mask, g_mask, b_mask); + avpriv_report_missing_feature(avctx, + "Bitmasks: R=%"PRIX32", G=%"PRIX32", B=%"PRIX32, + r_mask, g_mask, b_mask); return AVERROR_PATCHWELCOME; } } else { diff --git a/libavcodec/g723_1enc.c b/libavcodec/g723_1enc.c index 1ebd465416621..82f5cecfa248c 100644 --- a/libavcodec/g723_1enc.c +++ b/libavcodec/g723_1enc.c @@ -57,7 +57,8 @@ static av_cold int g723_1_encode_init(AVCodecContext *avctx) if (avctx->bit_rate == 6300) { p->cur_rate = RATE_6300; } else if (avctx->bit_rate == 5300) { - av_log(avctx, AV_LOG_ERROR, "Bitrate not supported yet, use 6300\n"); + av_log(avctx, AV_LOG_ERROR, "Use bitrate 6300 instead of 5300.\n"); + avpriv_report_missing_feature(avctx, "Bitrate 5300"); return AVERROR_PATCHWELCOME; } else { av_log(avctx, AV_LOG_ERROR, "Bitrate not supported, use 6300\n"); diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c index 36902e8e7704f..37c3be1cb99af 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -700,9 +700,8 @@ int ff_h264_decode_picture_parameter_set(GetBitContext *gb, AVCodecContext *avct sps = (SPS*)ps->sps_list[pps->sps_id]->data; if (sps->bit_depth_luma > 10) { - av_log(avctx, AV_LOG_ERROR, - "Unimplemented luma bit depth=%d (max=10)\n", - sps->bit_depth_luma); + avpriv_report_missing_feature(avctx, "Luma bit depth=%d (max=10)", + sps->bit_depth_luma); ret = AVERROR_PATCHWELCOME; goto fail; } diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index 6a8cfebaf76d3..c28e86b34a100 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -657,13 +657,12 @@ static int map_pixel_format(AVCodecContext *avctx, HEVCSPS *sps) case 9: sps->pix_fmt = AV_PIX_FMT_YUV420P9; break; case 10: sps->pix_fmt = AV_PIX_FMT_YUV420P10; break; default: - av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n", - sps->bit_depth); + avpriv_report_missing_feature(avctx, "Bit depth %d", + sps->bit_depth); return AVERROR_PATCHWELCOME; } } else { - av_log(avctx, AV_LOG_ERROR, - "non-4:2:0 support is currently unspecified.\n"); + avpriv_report_missing_feature(avctx, "Non-4:2:0 support"); return AVERROR_PATCHWELCOME; } diff --git a/libavcodec/hevc_ps_enc.c b/libavcodec/hevc_ps_enc.c index 1e86757d7c3da..4864e6ebfc6fa 100644 --- a/libavcodec/hevc_ps_enc.c +++ b/libavcodec/hevc_ps_enc.c @@ -90,9 +90,10 @@ int ff_hevc_encode_nal_vps(HEVCVPS *vps, unsigned int id, put_bits(&pb, 6, vps->vps_max_layer_id); set_ue_golomb(&pb, vps->vps_num_layer_sets - 1); - // writing layer_id_included_flag not supported - if (vps->vps_num_layer_sets > 1) + if (vps->vps_num_layer_sets > 1) { + avpriv_report_missing_feature(NULL, "Writing layer_id_included_flag"); return AVERROR_PATCHWELCOME; + } put_bits(&pb, 1, vps->vps_timing_info_present_flag); if (vps->vps_timing_info_present_flag) { @@ -102,9 +103,10 @@ int ff_hevc_encode_nal_vps(HEVCVPS *vps, unsigned int id, if (vps->vps_poc_proportional_to_timing_flag) set_ue_golomb(&pb, vps->vps_num_ticks_poc_diff_one - 1); - // writing HRD parameters not supported - if (vps->vps_num_hrd_parameters) + if (vps->vps_num_hrd_parameters) { + avpriv_report_missing_feature(NULL, "Writing HRD parameters"); return AVERROR_PATCHWELCOME; + } } put_bits(&pb, 1, 0); // extension flag diff --git a/libavcodec/libopenjpegdec.c b/libavcodec/libopenjpegdec.c index 401ea9b801ed5..6b8e210ac69e5 100644 --- a/libavcodec/libopenjpegdec.c +++ b/libavcodec/libopenjpegdec.c @@ -396,7 +396,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx, } break; default: - av_log(avctx, AV_LOG_ERROR, "unsupported pixel size %d\n", pixel_size); + avpriv_report_missing_feature(avctx, "Pixel size %d", pixel_size); ret = AVERROR_PATCHWELCOME; goto done; } diff --git a/libavcodec/libopusenc.c b/libavcodec/libopusenc.c index 1fb597bd3385f..500e58c85e3de 100644 --- a/libavcodec/libopusenc.c +++ b/libavcodec/libopusenc.c @@ -164,8 +164,9 @@ static int av_cold libopus_encode_init(AVCodecContext *avctx) /* FIXME: Opus can handle up to 255 channels. However, the mapping for * anything greater than 8 is undefined. */ if (avctx->channels > 8) { - av_log(avctx, AV_LOG_ERROR, - "Channel layout undefined for %d channels.\n", avctx->channels); + avpriv_report_missing_feature(avctx, + "Undefined channel layout for %d channels", + avctx->channels); return AVERROR_PATCHWELCOME; } if (!avctx->bit_rate) { diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index c670f357c9e0d..a4a6c63411d82 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -373,7 +373,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; break; default: - av_log(s->avctx, AV_LOG_ERROR, "Unhandled pixel format 0x%x\n", pix_fmt_id); + avpriv_report_missing_feature(s->avctx, "Pixel format 0x%x", pix_fmt_id); return AVERROR_PATCHWELCOME; } if (s->ls) { @@ -1035,8 +1035,9 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask, len = get_bits(&s->gb, 16); nb_components = get_bits(&s->gb, 8); if (nb_components == 0 || nb_components > MAX_COMPONENTS) { - av_log(s->avctx, AV_LOG_ERROR, - "decode_sos: nb_components (%d) unsupported\n", nb_components); + avpriv_report_missing_feature(s->avctx, + "decode_sos: nb_components (%d)", + nb_components); return AVERROR_PATCHWELCOME; } if (len != 6 + 2 * nb_components) { diff --git a/libavcodec/opus_silk.c b/libavcodec/opus_silk.c index d83fb373c6de6..5db1b26c6f807 100644 --- a/libavcodec/opus_silk.c +++ b/libavcodec/opus_silk.c @@ -1530,7 +1530,7 @@ int ff_silk_decode_superframe(SilkContext *s, OpusRangeCoder *rc, redundancy[i] = opus_rc_p2model(rc, 1); if (redundancy[i]) { - av_log(s->avctx, AV_LOG_ERROR, "LBRR frames present; this is unsupported\n"); + avpriv_report_missing_feature(s->avctx, "LBRR frames"); return AVERROR_PATCHWELCOME; } } diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c index ee6dc70942d67..00d166177996c 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -515,8 +515,8 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, case FN_BLOCKSIZE: { unsigned blocksize = get_uint(s, av_log2(s->blocksize)); if (blocksize > s->blocksize) { - av_log(avctx, AV_LOG_ERROR, - "Increasing block size is not supported\n"); + avpriv_report_missing_feature(avctx, + "Increasing block size"); return AVERROR_PATCHWELCOME; } if (!blocksize || blocksize > MAX_BLOCKSIZE) { diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c index c9db928c5c0a0..394567bbba6f7 100644 --- a/libavcodec/takdec.c +++ b/libavcodec/takdec.c @@ -702,7 +702,7 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, if (s->ti.codec != TAK_CODEC_MONO_STEREO && s->ti.codec != TAK_CODEC_MULTICHANNEL) { - av_log(avctx, AV_LOG_ERROR, "unsupported codec: %d\n", s->ti.codec); + avpriv_report_missing_feature(avctx, "TAK codec type %d", s->ti.codec); return AVERROR_PATCHWELCOME; } if (s->ti.data_type) { diff --git a/libavcodec/txd.c b/libavcodec/txd.c index ac46608f61633..db1d954032238 100644 --- a/libavcodec/txd.c +++ b/libavcodec/txd.c @@ -56,8 +56,7 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, flags = bytestream2_get_byte(&gb); if (version < 8 || version > 9) { - av_log(avctx, AV_LOG_ERROR, "texture data version %u is unsupported\n", - version); + avpriv_report_missing_feature(avctx, "Texture data version %u", version); return AVERROR_PATCHWELCOME; } @@ -66,7 +65,7 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } else if (depth == 16 || depth == 32) { avctx->pix_fmt = AV_PIX_FMT_RGBA; } else { - av_log(avctx, AV_LOG_ERROR, "depth of %u is unsupported\n", depth); + avpriv_report_missing_feature(avctx, "Color depth of %u", depth); return AVERROR_PATCHWELCOME; } @@ -143,7 +142,7 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return avpkt->size; unsupported: - av_log(avctx, AV_LOG_ERROR, "unsupported d3d format (%08x)\n", d3d_format); + avpriv_report_missing_feature(avctx, "d3d format (%08x)", d3d_format); return AVERROR_PATCHWELCOME; } diff --git a/libavcodec/vp5.c b/libavcodec/vp5.c index 2d8ba1a0f79c2..e5036e62a9ba9 100644 --- a/libavcodec/vp5.c +++ b/libavcodec/vp5.c @@ -51,7 +51,7 @@ static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, return AVERROR_INVALIDDATA; vp56_rac_gets(c, 2); if (vp56_rac_get(c)) { - av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n"); + avpriv_report_missing_feature(s->avctx, "Interlacing"); return AVERROR_PATCHWELCOME; } rows = vp56_rac_gets(c, 8); /* number of stored macroblock rows */ diff --git a/libavcodec/xwddec.c b/libavcodec/xwddec.c index 1c9874aa3276a..387b697491ed8 100644 --- a/libavcodec/xwddec.c +++ b/libavcodec/xwddec.c @@ -147,7 +147,7 @@ static int xwd_decode_frame(AVCodecContext *avctx, void *data, } if (pixformat != XWD_Z_PIXMAP) { - av_log(avctx, AV_LOG_ERROR, "pixmap format %"PRIu32" unsupported\n", pixformat); + avpriv_report_missing_feature(avctx, "Pixmap format %"PRIu32, pixformat); return AVERROR_PATCHWELCOME; } diff --git a/libavdevice/vfwcap.c b/libavdevice/vfwcap.c index 9edd2c5f302f2..3523fde6e1768 100644 --- a/libavdevice/vfwcap.c +++ b/libavdevice/vfwcap.c @@ -383,8 +383,7 @@ static int vfw_read_header(AVFormatContext *s) if (par->format == AV_PIX_FMT_NONE) { par->codec_id = vfw_codecid(biCompression); if (par->codec_id == AV_CODEC_ID_NONE) { - av_log(s, AV_LOG_ERROR, "Unknown compression type. " - "Please report verbose (-v 9) debug information.\n"); + avpriv_report_missing_feature(s, "This compression type"); vfw_read_close(s); return AVERROR_PATCHWELCOME; } diff --git a/libavdevice/xcbgrab.c b/libavdevice/xcbgrab.c index 0fd99ebc9f4c8..2913df5e9423c 100644 --- a/libavdevice/xcbgrab.c +++ b/libavdevice/xcbgrab.c @@ -500,7 +500,7 @@ static int pixfmt_from_pixmap_format(AVFormatContext *s, int depth, fmt++; } - av_log(s, AV_LOG_ERROR, "Pixmap format not mappable.\n"); + avpriv_report_missing_feature(s, "Mapping this pixmap format"); return AVERROR_PATCHWELCOME; } diff --git a/libavformat/avienc.c b/libavformat/avienc.c index e4743981b8e69..84a316f78721e 100644 --- a/libavformat/avienc.c +++ b/libavformat/avienc.c @@ -225,8 +225,7 @@ static int avi_write_header(AVFormatContext *s) // XSUB subtitles behave like video tracks, other subtitles // are not (yet) supported. if (par->codec_id != AV_CODEC_ID_XSUB) { - av_log(s, AV_LOG_ERROR, - "Subtitle streams other than DivX XSUB are not supported by the AVI muxer.\n"); + avpriv_report_missing_feature(s, "Subtitle streams other than DivX XSUB"); return AVERROR_PATCHWELCOME; } case AVMEDIA_TYPE_VIDEO: diff --git a/libavformat/lxfdec.c b/libavformat/lxfdec.c index 9c884ba9b59a4..285539c22af70 100644 --- a/libavformat/lxfdec.c +++ b/libavformat/lxfdec.c @@ -180,7 +180,7 @@ static int get_packet_header(AVFormatContext *s) st->codecpar->bits_per_coded_sample = (audio_format >> 6) & 0x3F; if (st->codecpar->bits_per_coded_sample != (audio_format & 0x3F)) { - av_log(s, AV_LOG_WARNING, "only tightly packed PCM currently supported\n"); + avpriv_report_missing_feature(s, "Not tightly packed PCM"); return AVERROR_PATCHWELCOME; } @@ -190,8 +190,7 @@ static int get_packet_header(AVFormatContext *s) case 24: st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE_PLANAR; break; case 32: st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE_PLANAR; break; default: - av_log(s, AV_LOG_WARNING, - "only 16-, 20-, 24- and 32-bit PCM currently supported\n"); + avpriv_report_missing_feature(s, "PCM not 16-, 20-, 24- or 32-bits"); return AVERROR_PATCHWELCOME; } diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 991f86b8d561a..80167309650c9 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -1947,10 +1947,9 @@ static int matroska_read_header(AVFormatContext *s) ebml.max_size > sizeof(uint64_t) || ebml.id_length > sizeof(uint32_t) || ebml.doctype_version > 3) { - av_log(matroska->ctx, AV_LOG_ERROR, - "EBML header using unsupported features\n" - "(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n", - ebml.version, ebml.doctype, ebml.doctype_version); + avpriv_report_missing_feature(matroska->ctx, + "EBML version %"PRIu64", doctype %s, doc version %"PRIu64, + ebml.version, ebml.doctype, ebml.doctype_version); ebml_free(ebml_syntax, &ebml); return AVERROR_PATCHWELCOME; } diff --git a/libavformat/mpc8.c b/libavformat/mpc8.c index bd17c19838ebb..d4005fa499949 100644 --- a/libavformat/mpc8.c +++ b/libavformat/mpc8.c @@ -228,7 +228,7 @@ static int mpc8_read_header(AVFormatContext *s) avio_skip(pb, 4); //CRC c->ver = avio_r8(pb); if(c->ver != 8){ - av_log(s, AV_LOG_ERROR, "Unknown stream version %d\n", c->ver); + avpriv_report_missing_feature(s, "Stream version %d", c->ver); return AVERROR_PATCHWELCOME; } c->samples = ffio_read_varlen(pb); diff --git a/libavformat/oggparseopus.c b/libavformat/oggparseopus.c index 915ef42babb81..f523143cabe73 100644 --- a/libavformat/oggparseopus.c +++ b/libavformat/oggparseopus.c @@ -123,9 +123,9 @@ static int opus_packet(AVFormatContext *avf, int idx) skip = FFMIN(skip, os->pduration); if (skip > 0) { os->pduration = skip < os->pduration ? os->pduration - skip : 1; - av_log(avf, AV_LOG_WARNING, - "Last packet is truncated to %d (because of unimplemented end trim support).\n", - os->pduration); + avpriv_report_missing_feature(avf, + "Last packet truncated to %u since end trim support", + os->pduration); return AVERROR_PATCHWELCOME; } } diff --git a/libavformat/qcp.c b/libavformat/qcp.c index 4069dbe8c08e5..b262d609df842 100644 --- a/libavformat/qcp.c +++ b/libavformat/qcp.c @@ -102,10 +102,10 @@ static int qcp_read_header(AVFormatContext *s) if (is_qcelp_13k_guid(buf)) { st->codecpar->codec_id = AV_CODEC_ID_QCELP; } else if (!memcmp(buf, guid_evrc, 16)) { - av_log(s, AV_LOG_ERROR, "EVRC codec is not supported.\n"); + avpriv_report_missing_feature(s, "EVRC codec"); return AVERROR_PATCHWELCOME; } else if (!memcmp(buf, guid_smv, 16)) { - av_log(s, AV_LOG_ERROR, "SMV codec is not supported.\n"); + avpriv_report_missing_feature(s, "SMV codec"); return AVERROR_PATCHWELCOME; } else { av_log(s, AV_LOG_ERROR, "Unknown codec GUID.\n"); diff --git a/libavformat/rsoenc.c b/libavformat/rsoenc.c index 4f8278c4ab547..f9dd419c4cecc 100644 --- a/libavformat/rsoenc.c +++ b/libavformat/rsoenc.c @@ -50,7 +50,7 @@ static int rso_write_header(AVFormatContext *s) } if (par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) { - av_log(s, AV_LOG_ERROR, "ADPCM in RSO not implemented\n"); + avpriv_report_missing_feature(s, "ADPCM in RSO"); return AVERROR_PATCHWELCOME; } diff --git a/libavformat/rtpdec_jpeg.c b/libavformat/rtpdec_jpeg.c index 2cf41139c3794..c3e5c8dc9ff4d 100644 --- a/libavformat/rtpdec_jpeg.c +++ b/libavformat/rtpdec_jpeg.c @@ -230,7 +230,7 @@ static int jpeg_parse_packet(AVFormatContext *ctx, PayloadContext *jpeg, len -= 8; if (type > 1) { - av_log(ctx, AV_LOG_ERROR, "Unimplemented RTP/JPEG type %"PRIu8"\n", type); + avpriv_report_missing_feature(ctx, "RTP/JPEG type %"PRIu8, type); return AVERROR_PATCHWELCOME; } diff --git a/libavformat/rtpdec_latm.c b/libavformat/rtpdec_latm.c index 6be0a25d2bf2b..df85ed3615a89 100644 --- a/libavformat/rtpdec_latm.c +++ b/libavformat/rtpdec_latm.c @@ -109,9 +109,9 @@ static int parse_fmtp_config(AVStream *st, const char *value) num_layers = get_bits(&gb, 3); if (audio_mux_version != 0 || same_time_framing != 1 || num_programs != 0 || num_layers != 0) { - av_log(NULL, AV_LOG_WARNING, "Unsupported LATM config (%d,%d,%d,%d)\n", - audio_mux_version, same_time_framing, - num_programs, num_layers); + avpriv_report_missing_feature(NULL, "LATM config (%d,%d,%d,%d)", + audio_mux_version, same_time_framing, + num_programs, num_layers); ret = AVERROR_PATCHWELCOME; goto end; } diff --git a/libavformat/rtpdec_xiph.c b/libavformat/rtpdec_xiph.c index 7821686983e1a..920a8a75bffa9 100644 --- a/libavformat/rtpdec_xiph.c +++ b/libavformat/rtpdec_xiph.c @@ -108,15 +108,14 @@ static int xiph_handle_packet(AVFormatContext *ctx, PayloadContext *data, } if (ident != data->ident) { - av_log(ctx, AV_LOG_ERROR, - "Unimplemented Xiph SDP configuration change detected\n"); + avpriv_report_missing_feature(ctx, "Xiph SDP configuration change"); return AVERROR_PATCHWELCOME; } if (tdt) { - av_log(ctx, AV_LOG_ERROR, - "Unimplemented RTP Xiph packet settings (%d,%d,%d)\n", - fragmented, tdt, num_pkts); + avpriv_report_missing_feature(ctx, + "RTP Xiph packet settings (%d,%d,%d)", + fragmented, tdt, num_pkts); return AVERROR_PATCHWELCOME; } @@ -246,9 +245,8 @@ parse_packed_headers(AVFormatContext *s, length2 = get_base128(&packed_headers, packed_headers_end); if (num_packed != 1 || num_headers > 3) { - av_log(s, AV_LOG_ERROR, - "Unimplemented number of headers: %u packed headers, %u headers\n", - num_packed, num_headers); + avpriv_report_missing_feature(s, "%u packed headers, %u headers", + num_packed, num_headers); return AVERROR_PATCHWELCOME; } diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 84b912f7f2d8e..7e5985719e900 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -1333,8 +1333,7 @@ static int rtsp_send_cmd_with_content_async(AVFormatContext *s, ffurl_write(rt->rtsp_hd_out, out_buf, strlen(out_buf)); if (send_content_length > 0 && send_content) { if (rt->control_transport == RTSP_MODE_TUNNEL) { - av_log(s, AV_LOG_ERROR, "tunneling of RTSP requests " - "with content data not supported\n"); + avpriv_report_missing_feature(s, "Tunneling of RTSP requests with content data"); return AVERROR_PATCHWELCOME; } ffurl_write(rt->rtsp_hd_out, send_content, send_content_length); diff --git a/libavformat/spdifenc.c b/libavformat/spdifenc.c index a19bcab4c938e..a9b3b522b3bb0 100644 --- a/libavformat/spdifenc.c +++ b/libavformat/spdifenc.c @@ -469,7 +469,8 @@ static int spdif_write_header(AVFormatContext *s) return AVERROR(ENOMEM); break; default: - av_log(s, AV_LOG_ERROR, "codec not supported\n"); + avpriv_report_missing_feature(s, "Codec %d", + s->streams[0]->codecpar->codec_id); return AVERROR_PATCHWELCOME; } return 0; diff --git a/libavformat/wvdec.c b/libavformat/wvdec.c index 717275c6a0c03..51aae084ea65f 100644 --- a/libavformat/wvdec.c +++ b/libavformat/wvdec.c @@ -95,7 +95,8 @@ static int wv_read_block_header(AVFormatContext *ctx, AVIOContext *pb) } if (wc->header.version < 0x402 || wc->header.version > 0x410) { - av_log(ctx, AV_LOG_ERROR, "Unsupported version %03X\n", wc->header.version); + avpriv_report_missing_feature(ctx, "WV version 0x%03X", + wc->header.version); return AVERROR_PATCHWELCOME; } From a3483f79933e8f1fd99d524e3218688e14c59150 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 8 Nov 2016 17:48:50 +0100 Subject: [PATCH 0428/3374] avconv: Drop stray leftover debug output --- avconv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/avconv.c b/avconv.c index 769b9e095bb94..97166d9e2ad6b 100644 --- a/avconv.c +++ b/avconv.c @@ -206,7 +206,6 @@ static void avconv_cleanup(int ret) if (ost->muxing_queue) { while (av_fifo_size(ost->muxing_queue)) { AVPacket pkt; - av_log(NULL, AV_LOG_INFO, "after av_fifo_size()\n"); av_fifo_generic_read(ost->muxing_queue, &pkt, sizeof(pkt), NULL); av_packet_unref(&pkt); } From 576c9003aef0fe18c0cf8da6e865211610552005 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 25 Oct 2016 22:47:00 +0200 Subject: [PATCH 0429/3374] configure: Improve output wording Also drop a redundant output line. --- configure | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/configure b/configure index e862757d44a24..7dda871f49b3c 100755 --- a/configure +++ b/configure @@ -79,7 +79,7 @@ Help options: Standard options: --logfile=FILE log tests and output to FILE [config.log] --disable-logging do not log configure debug information - --prefix=PREFIX install in PREFIX [$prefix] + --prefix=PREFIX install in PREFIX [$prefix_default] --bindir=DIR install binaries in DIR [PREFIX/bin] --datadir=DIR install data files in DIR [PREFIX/share/avconv] --docdir=DIR install documentation in DIR [PREFIX/share/doc/libav] @@ -87,7 +87,7 @@ Standard options: --shlibdir=DIR install shared libs in DIR [PREFIX/lib] --incdir=DIR install includes in DIR [PREFIX/include] --mandir=DIR install man page in DIR [PREFIX/share/man] - --enable-rpath use rpath when linking programs [USE WITH CARE] + --enable-rpath use rpath when linking programs (USE WITH CARE) Licensing options: --enable-gpl allow use of GPL code, the resulting libs @@ -100,7 +100,7 @@ Configuration options: --disable-static do not build static libraries [no] --enable-shared build shared libraries [no] --enable-small optimize for size instead of speed - --enable-runtime-cpudetect detect cpu capabilities at runtime (bigger binary) + --enable-runtime-cpudetect detect CPU capabilities at runtime (bigger binary) --enable-gray enable full grayscale support (slower color) --disable-swscale-alpha disable alpha channel support in swscale --disable-all disable building components, libraries and programs @@ -5174,7 +5174,6 @@ echo "optimize for size ${small-no}" echo "optimizations ${optimizations-no}" echo "static ${static-no}" echo "shared ${shared-no}" -echo "new filter support ${avfilter-no}" echo "network support ${network-no}" echo "threading support ${thread_type-no}" echo "safe bitstream reader ${safe_bitstream_reader-no}" @@ -5214,7 +5213,7 @@ fi echo "License: $license" -echo "Creating config.mak and config.h..." +echo "Creating configuration files ..." fi # test "$quiet" != "yes" From d1a91ebe4990001e0800ee9ac54ed2207e4f56ff Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 7 Nov 2016 22:12:23 +0100 Subject: [PATCH 0430/3374] configure: Print list of enabled programs Also drop a related and now redundant informative output line. --- configure | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 7dda871f49b3c..a6617b5758a0d 100755 --- a/configure +++ b/configure @@ -5177,7 +5177,6 @@ echo "shared ${shared-no}" echo "network support ${network-no}" echo "threading support ${thread_type-no}" echo "safe bitstream reader ${safe_bitstream_reader-no}" -echo "SDL support ${sdl-no}" test -n "$random_seed" && echo "random seed ${random_seed}" echo @@ -5193,6 +5192,10 @@ echo "Libraries:" print_enabled '' $LIBRARY_LIST | print_3_columns echo +echo "Programs:" +print_enabled '' $PROGRAM_LIST | print_3_columns +echo + for type in decoder encoder hwaccel parser demuxer muxer protocol filter bsf indev outdev; do echo "Enabled ${type}s:" eval list=\$$(toupper $type)_LIST From fe7bc1f16abaefe66d8a20f734ca3eb8a4ce4d43 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 7 Nov 2016 20:22:14 +0100 Subject: [PATCH 0431/3374] configure: Do not unconditionally check for (and enable) xlib This avoids unnecessarily linking against xlib. --- configure | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/configure b/configure index a6617b5758a0d..93edc998dccf5 100755 --- a/configure +++ b/configure @@ -4778,8 +4778,6 @@ if enabled libcdio; then die "ERROR: No usable libcdio/cdparanoia found" fi -check_lib X11/Xlib.h XOpenDisplay -lX11 && enable xlib - if enabled libxcb; then check_pkg_config xcb-shape xcb/shape.h xcb_shape_rectangles || { enabled libxcb && die "ERROR: libxcb not found"; @@ -4805,19 +4803,20 @@ enabled vaapi && check_code cc "va/va.h" "vaCreateSurfaces(0, 0, 0, 0, 0, 0, 0, 0)" || disable vaapi -if enabled vaapi ; then - enabled xlib && - check_lib "va/va.h va/va_x11.h" vaGetDisplay -lva -lva-x11 && - enable vaapi_x11 - +enabled vaapi && check_lib "va/va.h va/va_drm.h" vaGetDisplayDRM -lva -lva-drm && enable vaapi_drm -fi enabled vdpau && check_cpp_condition vdpau/vdpau.h "defined VDP_DECODER_PROFILE_MPEG4_PART2_ASP" || disable vdpau +enabled_any vaapi vdpau && check_lib X11/Xlib.h XOpenDisplay -lX11 && enable xlib + +enabled vaapi && enabled xlib && + check_lib "va/va.h va/va_x11.h" vaGetDisplay -lva -lva-x11 && + enable vaapi_x11 + enabled vdpau && enabled xlib && check_lib "vdpau/vdpau.h vdpau/vdpau_x11.h" vdp_device_create_x11 -lvdpau && enable vdpau_x11 From 831005b2302cbeb377e3f00fd18c78928bcec185 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 6 Jun 2016 19:06:30 +0200 Subject: [PATCH 0432/3374] configure: Log correct test name and use correct filter when testing objective C flags --- configure | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure b/configure index 93edc998dccf5..4cfa0662d0a0f 100755 --- a/configure +++ b/configure @@ -884,15 +884,15 @@ check_cflags(){ } test_objcflags(){ - log test_cflags "$@" - set -- $($cflags_filter "$@") + log test_objcflags "$@" + set -- $($objcflags_filter "$@") check_objcc "$@" < Date: Mon, 8 Aug 2016 20:27:43 +0200 Subject: [PATCH 0433/3374] configure: Use check_cpp in CPP flags tests --- configure | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 4cfa0662d0a0f..422036bfe627c 100755 --- a/configure +++ b/configure @@ -865,7 +865,7 @@ check_code(){ check_cppflags(){ log check_cppflags "$@" - check_cc "$@" < Date: Tue, 8 Nov 2016 20:04:18 +0100 Subject: [PATCH 0434/3374] configure: Log name and parameters of all helper functions where it makes sense --- configure | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configure b/configure index 422036bfe627c..70a0d95c50c54 100755 --- a/configure +++ b/configure @@ -1027,6 +1027,7 @@ check_exec(){ } check_exec_crash(){ + log check_exec_crash "$@" code=$(cat) # exit() is not async signal safe. _Exit (C99) and _exit (POSIX) @@ -1097,6 +1098,7 @@ check_compile_assert(){ } require(){ + log require "$@" name="$1" headers="$2" func="$3" @@ -1105,6 +1107,7 @@ require(){ } require_pkg_config(){ + log require_pkg_config "$@" pkg="$1" check_pkg_config "$@" || die "ERROR: $pkg not found" add_cflags $(get_safe "${pkg}_cflags") From 2dd464868c64fa21a6e3bd63ad364ff12999c7d0 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 27 Mar 2013 18:21:10 +0100 Subject: [PATCH 0435/3374] configure: Move license checks directly after command line parsing This will allow to error out immediately if incompatible options are passed on the command line instead of running time-consuming tests. --- configure | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/configure b/configure index 70a0d95c50c54..acc74f2a6d689 100755 --- a/configure +++ b/configure @@ -2767,6 +2767,17 @@ done disabled logging && logfile=/dev/null +# Die early if licensing-related configure options are incompatible. +die_license_disabled() { + enabled $1 || { enabled $v && die "$v is $1 and --enable-$1 is not specified."; } +} + +map "die_license_disabled gpl" $EXTERNAL_LIBRARY_GPL_LIST +map "die_license_disabled nonfree" $EXTERNAL_LIBRARY_NONFREE_LIST $HWACCEL_LIBRARY_NONFREE_LIST +map "die_license_disabled version3" $EXTERNAL_LIBRARY_VERSION3_LIST + +enabled version3 && { enabled gpl && enable gplv3 || enable lgplv3; } + # Disable all the library-specific components if the library itself # is disabled, see AVCODEC_LIST and following _LIST variables. @@ -4124,16 +4135,6 @@ EOF exit 1 fi -die_license_disabled() { - enabled $1 || { enabled $v && die "$v is $1 and --enable-$1 is not specified."; } -} - -map "die_license_disabled gpl" $EXTERNAL_LIBRARY_GPL_LIST -map "die_license_disabled nonfree" $EXTERNAL_LIBRARY_NONFREE_LIST $HWACCEL_LIBRARY_NONFREE_LIST -map "die_license_disabled version3" $EXTERNAL_LIBRARY_VERSION3_LIST - -enabled version3 && { enabled gpl && enable gplv3 || enable lgplv3; } - disabled optimizations || check_cflags -fomit-frame-pointer enable_weak_pic() { From 72a19f4013ec2c7f8581416f8ad4bf81df163fb6 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 8 Nov 2016 18:10:04 +0100 Subject: [PATCH 0436/3374] mpegaudiodsp: aarch64: Adjust function prototype after 2caa93b813adc5dbb7771dfe615da826a2947d18 --- libavcodec/aarch64/mpegaudiodsp_init.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libavcodec/aarch64/mpegaudiodsp_init.c b/libavcodec/aarch64/mpegaudiodsp_init.c index a8b2baf9553b0..849e310f629b7 100644 --- a/libavcodec/aarch64/mpegaudiodsp_init.c +++ b/libavcodec/aarch64/mpegaudiodsp_init.c @@ -16,6 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include #include "libavutil/attributes.h" @@ -24,9 +25,9 @@ #include "config.h" void ff_mpadsp_apply_window_fixed_neon(int32_t *synth_buf, int32_t *window, - int *dither, int16_t *samples, int incr); + int *dither, int16_t *samples, ptrdiff_t incr); void ff_mpadsp_apply_window_float_neon(float *synth_buf, float *window, - int *dither, float *samples, int incr); + int *dither, float *samples, ptrdiff_t incr); av_cold void ff_mpadsp_init_aarch64(MPADSPContext *s) { From 84f225684cd389747907381122c073aa1c8b6bf1 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 7 Nov 2016 14:21:18 +0100 Subject: [PATCH 0437/3374] pthread_frame: properly propagate the hw frame context across frame threads --- libavcodec/pthread_frame.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 210ee69dae4fc..671c551f29acc 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -223,6 +223,17 @@ FF_ENABLE_DEPRECATION_WARNINGS dst->hwaccel = src->hwaccel; dst->hwaccel_context = src->hwaccel_context; dst->internal->hwaccel_priv_data = src->internal->hwaccel_priv_data; + + if (!!dst->hw_frames_ctx != !!src->hw_frames_ctx || + (dst->hw_frames_ctx && dst->hw_frames_ctx->data != src->hw_frames_ctx->data)) { + av_buffer_unref(&dst->hw_frames_ctx); + + if (src->hw_frames_ctx) { + dst->hw_frames_ctx = av_buffer_ref(src->hw_frames_ctx); + if (!dst->hw_frames_ctx) + return AVERROR(ENOMEM); + } + } } if (for_user) { From f4bf236338f6001736a4784b9c23de863057a583 Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 9 Nov 2016 18:38:23 -0300 Subject: [PATCH 0438/3374] matroskaenc: fix muxing AAC streams when using aac_adtstoasc bsf aac_adtstoasc makes the aac extradata available only after the first packet is filtered, and as packet side data. Assume extradata will be available as part of the first packet if avpriv_mpeg4audio_get_config() fails the first time due to missing extradata and reserve space for the OutputSampleRate element in the Tracks master. Signed-off-by: James Almer Signed-off-by: Anton Khirnov --- libavformat/matroskaenc.c | 80 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 74 insertions(+), 6 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index cfced72adac23..55932373f5fd0 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -81,6 +81,8 @@ typedef struct mkv_cues { typedef struct mkv_track { int write_dts; + int sample_rate; + int64_t sample_rate_offset; int64_t ts_offset; } mkv_track; @@ -521,20 +523,36 @@ static int put_flac_codecpriv(AVFormatContext *s, return 0; } -static int get_aac_sample_rates(AVFormatContext *s, AVCodecParameters *par, +static int get_aac_sample_rates(AVFormatContext *s, uint8_t *extradata, int extradata_size, int *sample_rate, int *output_sample_rate) { MPEG4AudioConfig mp4ac; + int ret; - if (avpriv_mpeg4audio_get_config(&mp4ac, par->extradata, - par->extradata_size * 8, 1) < 0) { + ret = avpriv_mpeg4audio_get_config(&mp4ac, extradata, + extradata_size * 8, 1); + /* Don't abort if the failure is because of missing extradata. Assume in that + * case a bitstream filter will provide the muxer with the extradata in the + * first packet. + * Abort however if s->pb is not seekable, as we would not be able to seek back + * to write the sample rate elements once the extradata shows up, anyway. */ + if (ret < 0 && (extradata_size || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL))) { av_log(s, AV_LOG_ERROR, "Error parsing AAC extradata, unable to determine samplerate.\n"); return AVERROR(EINVAL); } - *sample_rate = mp4ac.sample_rate; - *output_sample_rate = mp4ac.ext_sample_rate; + if (ret < 0) { + /* This will only happen when this function is called while writing the + * header and no extradata is available. The space for this element has + * to be reserved for when this function is called again after the + * extradata shows up in the first packet, as there's no way to know if + * output_sample_rate will be different than sample_rate or not. */ + *output_sample_rate = *sample_rate; + } else { + *sample_rate = mp4ac.sample_rate; + *output_sample_rate = mp4ac.ext_sample_rate; + } return 0; } @@ -790,7 +808,8 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, bit_depth = av_get_bytes_per_sample(par->format) << 3; if (par->codec_id == AV_CODEC_ID_AAC) { - ret = get_aac_sample_rates(s, par, &sample_rate, &output_sample_rate); + ret = get_aac_sample_rates(s, par->extradata, par->extradata_size, &sample_rate, + &output_sample_rate); if (ret < 0) return ret; } @@ -890,6 +909,8 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, subinfo = start_ebml_master(pb, MATROSKA_ID_TRACKAUDIO, 0); put_ebml_uint (pb, MATROSKA_ID_AUDIOCHANNELS , par->channels); + + mkv->tracks[i].sample_rate_offset = avio_tell(pb); put_ebml_float (pb, MATROSKA_ID_AUDIOSAMPLINGFREQ, sample_rate); if (output_sample_rate) put_ebml_float(pb, MATROSKA_ID_AUDIOOUTSAMPLINGFREQ, output_sample_rate); @@ -909,6 +930,7 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, av_log(s, AV_LOG_ERROR, "Only audio, video, and subtitles are supported for Matroska.\n"); break; } + ret = mkv_write_codecprivate(s, pb, par, native_id, qt_id); if (ret < 0) return ret; @@ -1531,6 +1553,48 @@ static void mkv_flush_dynbuf(AVFormatContext *s) mkv->dyn_bc = NULL; } +static int mkv_check_new_extra_data(AVFormatContext *s, AVPacket *pkt) +{ + MatroskaMuxContext *mkv = s->priv_data; + AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar; + mkv_track *track = &mkv->tracks[pkt->stream_index]; + uint8_t *side_data; + int side_data_size = 0, ret; + + side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, + &side_data_size); + + switch (par->codec_id) { + case AV_CODEC_ID_AAC: + if (side_data_size && (s->pb->seekable & AVIO_SEEKABLE_NORMAL)) { + int output_sample_rate = 0; + int64_t curpos; + ret = get_aac_sample_rates(s, side_data, side_data_size, &track->sample_rate, + &output_sample_rate); + if (ret < 0) + return ret; + if (!output_sample_rate) + output_sample_rate = track->sample_rate; // Space is already reserved, so it's this or a void element. + curpos = avio_tell(s->pb); + avio_seek(s->pb, track->sample_rate_offset, SEEK_SET); + put_ebml_float(s->pb, MATROSKA_ID_AUDIOSAMPLINGFREQ, track->sample_rate); + put_ebml_float(s->pb, MATROSKA_ID_AUDIOOUTSAMPLINGFREQ, output_sample_rate); + avio_seek(s->pb, curpos, SEEK_SET); + } else if (!par->extradata_size && !track->sample_rate) { + // No extradata (codecpar or packet side data). + av_log(s, AV_LOG_ERROR, "Error parsing AAC extradata, unable to determine samplerate.\n"); + return AVERROR(EINVAL); + } + 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); + break; + } + + return 0; +} + static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt) { MatroskaMuxContext *mkv = s->priv_data; @@ -1605,6 +1669,10 @@ static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) AVIOContext *pb; int ret; + ret = mkv_check_new_extra_data(s, pkt); + if (ret < 0) + return ret; + if (mkv->tracks[pkt->stream_index].write_dts) cluster_time = pkt->dts - mkv->cluster_pts; else From 98cae966c77875e26c5958206a6cfe7eba6269e8 Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 9 Nov 2016 18:38:24 -0300 Subject: [PATCH 0439/3374] matroskaenc: write updated STREAMINFO metadata for FLAC streams if available FLAC streams originating from the FLAC encoder send updated and more complete STREAMINFO metadata as part of the last packet, so write that to CodecPrivate instead of the incomplete one available in extradata during init. Signed-off-by: James Almer Signed-off-by: Anton Khirnov --- libavformat/matroskaenc.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 55932373f5fd0..e951a0fb679cd 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -83,6 +83,7 @@ typedef struct mkv_track { int write_dts; int sample_rate; int64_t sample_rate_offset; + int64_t codecpriv_offset; int64_t ts_offset; } mkv_track; @@ -931,6 +932,7 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, break; } + mkv->tracks[i].codecpriv_offset = avio_tell(pb); ret = mkv_write_codecprivate(s, pb, par, native_id, qt_id); if (ret < 0) return ret; @@ -1586,6 +1588,31 @@ static int mkv_check_new_extra_data(AVFormatContext *s, AVPacket *pkt) return AVERROR(EINVAL); } break; + case AV_CODEC_ID_FLAC: + if (side_data_size && (s->pb->seekable & AVIO_SEEKABLE_NORMAL)) { + AVCodecParameters *codecpriv_par; + int64_t curpos; + if (side_data_size != par->extradata_size) { + av_log(s, AV_LOG_ERROR, "Invalid FLAC STREAMINFO metadata for output stream %d\n", + pkt->stream_index); + return AVERROR(EINVAL); + } + codecpriv_par = avcodec_parameters_alloc(); + if (!codecpriv_par) + return AVERROR(ENOMEM); + ret = avcodec_parameters_copy(codecpriv_par, par); + if (ret < 0) { + avcodec_parameters_free(&codecpriv_par); + return ret; + } + memcpy(codecpriv_par->extradata, side_data, side_data_size); + curpos = avio_tell(s->pb); + avio_seek(s->pb, track->codecpriv_offset, SEEK_SET); + mkv_write_codecprivate(s, s->pb, codecpriv_par, 1, 0); + avio_seek(s->pb, curpos, SEEK_SET); + avcodec_parameters_free(&codecpriv_par); + } + 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); From a4cfcddcb0f76e837d5abc06840c2b26c0e8aefc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 5 Nov 2016 13:18:53 +0200 Subject: [PATCH 0440/3374] vp9: Make the subpel filters non-static MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make them aligned, to allow efficient access to them from simd. Signed-off-by: Martin Storsjö --- libavcodec/vp9.h | 2 ++ libavcodec/vp9dsp.c | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/libavcodec/vp9.h b/libavcodec/vp9.h index e4b9f82689376..654c8ed09c032 100644 --- a/libavcodec/vp9.h +++ b/libavcodec/vp9.h @@ -431,6 +431,8 @@ typedef struct VP9Context { DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][32 * 32]; } VP9Context; +extern const int8_t ff_vp9_subpel_filters[3][15][8]; + void ff_vp9dsp_init(VP9DSPContext *dsp); void ff_vp9dsp_init_arm(VP9DSPContext *dsp); diff --git a/libavcodec/vp9dsp.c b/libavcodec/vp9dsp.c index 0eca389de65f4..a2862bd1dc32d 100644 --- a/libavcodec/vp9dsp.c +++ b/libavcodec/vp9dsp.c @@ -1786,7 +1786,7 @@ copy_avg_fn(4) #undef fpel_fn #undef copy_avg_fn -static const int8_t vp9_subpel_filters[3][15][8] = { +const DECLARE_ALIGNED(8, int8_t, ff_vp9_subpel_filters)[3][15][8] = { [FILTER_8TAP_REGULAR] = { { 0, 1, -5, 126, 8, -3, 1, 0 }, { -1, 3, -10, 122, 18, -6, 2, 0 }, @@ -1948,7 +1948,7 @@ avg ## _8tap_ ## type ## _ ## sz ## dir ## _c(uint8_t *dst, \ int h, int mx, int my) \ { \ avg ## _8tap_1d_ ## dir ## _c(dst, dst_stride, src, src_stride, sz, h, \ - vp9_subpel_filters[type_idx][dir_m - 1]); \ + ff_vp9_subpel_filters[type_idx][dir_m - 1]); \ } #define filter_fn_2d(sz, type, type_idx, avg) \ @@ -1959,8 +1959,8 @@ static void avg ## _8tap_ ## type ## _ ## sz ## hv_c(uint8_t *dst, \ int h, int mx, int my) \ { \ avg ## _8tap_2d_hv_c(dst, dst_stride, src, src_stride, sz, h, \ - vp9_subpel_filters[type_idx][mx - 1], \ - vp9_subpel_filters[type_idx][my - 1]); \ + ff_vp9_subpel_filters[type_idx][mx - 1], \ + ff_vp9_subpel_filters[type_idx][my - 1]); \ } #define FILTER_BILIN(src, x, mxy, stride) \ From c44a8a3eabcd6acd2ba79f32ec8a432e6ebe552c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 9 Nov 2016 11:47:57 +0200 Subject: [PATCH 0441/3374] aarch64: Add an offset parameter to the movrel macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With apple tools, the linker fails with errors like these, if the offset is negative: ld: in section __TEXT,__text reloc 8: symbol index out of range for architecture arm64 Signed-off-by: Martin Storsjö --- libavutil/aarch64/asm.S | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/libavutil/aarch64/asm.S b/libavutil/aarch64/asm.S index 6a7f506d130ac..0fc649ad0e782 100644 --- a/libavutil/aarch64/asm.S +++ b/libavutil/aarch64/asm.S @@ -72,15 +72,21 @@ ELF .size \name, . - \name \name: .endm -.macro movrel rd, val +.macro movrel rd, val, offset=0 #if CONFIG_PIC && defined(__APPLE__) + .if \offset < 0 adrp \rd, \val@PAGE add \rd, \rd, \val@PAGEOFF + sub \rd, \rd, -(\offset) + .else + adrp \rd, \val+(\offset)@PAGE + add \rd, \rd, \val+(\offset)@PAGEOFF + .endif #elif CONFIG_PIC - adrp \rd, \val - add \rd, \rd, :lo12:\val + adrp \rd, \val+\offset + add \rd, \rd, :lo12:\val+\offset #else - ldr \rd, =\val + ldr \rd, =\val+\offset #endif .endm From 383d96aa2229f644d9bd77b821ed3a309da5e9fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 10 Nov 2016 11:06:26 +0200 Subject: [PATCH 0442/3374] aarch64: vp9: Add NEON optimizations of VP9 MC functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. These are ported from the ARM version; it is essentially a 1:1 port with no extra added features, but with some hand tuning (especially for the plain copy/avg functions). The ARM version isn't very register starved to begin with, so there's not much to be gained from having more spare registers here - we only avoid having to clobber callee-saved registers. Examples of runtimes vs the 32 bit version, on a Cortex A53: ARM AArch64 vp9_avg4_neon: 27.2 23.7 vp9_avg8_neon: 56.5 54.7 vp9_avg16_neon: 169.9 167.4 vp9_avg32_neon: 585.8 585.2 vp9_avg64_neon: 2460.3 2294.7 vp9_avg_8tap_smooth_4h_neon: 132.7 125.2 vp9_avg_8tap_smooth_4hv_neon: 478.8 442.0 vp9_avg_8tap_smooth_4v_neon: 126.0 93.7 vp9_avg_8tap_smooth_8h_neon: 241.7 234.2 vp9_avg_8tap_smooth_8hv_neon: 690.9 646.5 vp9_avg_8tap_smooth_8v_neon: 245.0 205.5 vp9_avg_8tap_smooth_64h_neon: 11273.2 11280.1 vp9_avg_8tap_smooth_64hv_neon: 22980.6 22184.1 vp9_avg_8tap_smooth_64v_neon: 11549.7 10781.1 vp9_put4_neon: 18.0 17.2 vp9_put8_neon: 40.2 37.7 vp9_put16_neon: 97.4 99.5 vp9_put32_neon/armv8: 346.0 307.4 vp9_put64_neon/armv8: 1319.0 1107.5 vp9_put_8tap_smooth_4h_neon: 126.7 118.2 vp9_put_8tap_smooth_4hv_neon: 465.7 434.0 vp9_put_8tap_smooth_4v_neon: 113.0 86.5 vp9_put_8tap_smooth_8h_neon: 229.7 221.6 vp9_put_8tap_smooth_8hv_neon: 658.9 621.3 vp9_put_8tap_smooth_8v_neon: 215.0 187.5 vp9_put_8tap_smooth_64h_neon: 10636.7 10627.8 vp9_put_8tap_smooth_64hv_neon: 21076.8 21026.9 vp9_put_8tap_smooth_64v_neon: 9635.0 9632.4 These are generally about as fast as the corresponding ARM routines on the same CPU (at least on the A53), in most cases marginally faster. The speedup vs C code is pretty much the same as for the 32 bit case; on the A53 it's around 6-13x for ther larger 8tap filters. The exact speedup varies a little, since the C versions generally don't end up exactly as slow/fast as on 32 bit. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/Makefile | 2 + libavcodec/aarch64/vp9dsp_init_aarch64.c | 153 +++++ libavcodec/aarch64/vp9mc_neon.S | 679 +++++++++++++++++++++++ libavcodec/vp9.h | 1 + libavcodec/vp9block.c | 4 +- libavcodec/vp9dsp.c | 2 + 6 files changed, 839 insertions(+), 2 deletions(-) create mode 100644 libavcodec/aarch64/vp9dsp_init_aarch64.c create mode 100644 libavcodec/aarch64/vp9mc_neon.S diff --git a/libavcodec/aarch64/Makefile b/libavcodec/aarch64/Makefile index 764bedc927539..6f1227a004e32 100644 --- a/libavcodec/aarch64/Makefile +++ b/libavcodec/aarch64/Makefile @@ -17,6 +17,7 @@ OBJS-$(CONFIG_DCA_DECODER) += aarch64/dcadsp_init.o OBJS-$(CONFIG_RV40_DECODER) += aarch64/rv40dsp_init_aarch64.o OBJS-$(CONFIG_VC1_DECODER) += aarch64/vc1dsp_init_aarch64.o OBJS-$(CONFIG_VORBIS_DECODER) += aarch64/vorbisdsp_init.o +OBJS-$(CONFIG_VP9_DECODER) += aarch64/vp9dsp_init_aarch64.o # ARMv8 optimizations @@ -43,3 +44,4 @@ NEON-OBJS-$(CONFIG_MPEGAUDIODSP) += aarch64/mpegaudiodsp_neon.o NEON-OBJS-$(CONFIG_DCA_DECODER) += aarch64/dcadsp_neon.o \ aarch64/synth_filter_neon.o NEON-OBJS-$(CONFIG_VORBIS_DECODER) += aarch64/vorbisdsp_neon.o +NEON-OBJS-$(CONFIG_VP9_DECODER) += aarch64/vp9mc_neon.o diff --git a/libavcodec/aarch64/vp9dsp_init_aarch64.c b/libavcodec/aarch64/vp9dsp_init_aarch64.c new file mode 100644 index 0000000000000..5c4175b3f167e --- /dev/null +++ b/libavcodec/aarch64/vp9dsp_init_aarch64.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2016 Google Inc. + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/aarch64/cpu.h" +#include "libavcodec/vp9.h" + +#define declare_fpel(type, sz) \ +void ff_vp9_##type##sz##_neon(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, int mx, int my) + +#define declare_copy_avg(sz) \ + declare_fpel(copy, sz); \ + declare_fpel(avg , sz) + +#define decl_mc_func(op, filter, dir, sz) \ +void ff_vp9_##op##_##filter##sz##_##dir##_neon(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, int mx, int my) + +#define define_8tap_2d_fn(op, filter, sz) \ +static void op##_##filter##sz##_hv_neon(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, int mx, int my) \ +{ \ + LOCAL_ALIGNED_16(uint8_t, temp, [((1 + (sz < 64)) * sz + 8) * sz]); \ + /* We only need h + 7 lines, but the horizontal filter assumes an \ + * even number of rows, so filter h + 8 lines here. */ \ + ff_vp9_put_##filter##sz##_h_neon(temp, sz, \ + src - 3 * src_stride, src_stride, \ + h + 8, mx, 0); \ + ff_vp9_##op##_##filter##sz##_v_neon(dst, dst_stride, \ + temp + 3 * sz, sz, \ + h, 0, my); \ +} + +#define decl_filter_funcs(op, dir, sz) \ + decl_mc_func(op, regular, dir, sz); \ + decl_mc_func(op, sharp, dir, sz); \ + decl_mc_func(op, smooth, dir, sz) + +#define decl_mc_funcs(sz) \ + decl_filter_funcs(put, h, sz); \ + decl_filter_funcs(avg, h, sz); \ + decl_filter_funcs(put, v, sz); \ + decl_filter_funcs(avg, v, sz); \ + decl_filter_funcs(put, hv, sz); \ + decl_filter_funcs(avg, hv, sz) + +#define ff_vp9_copy32_neon ff_vp9_copy32_aarch64 +#define ff_vp9_copy64_neon ff_vp9_copy64_aarch64 + +declare_copy_avg(64); +declare_copy_avg(32); +declare_copy_avg(16); +declare_copy_avg(8); +declare_copy_avg(4); + +decl_mc_funcs(64); +decl_mc_funcs(32); +decl_mc_funcs(16); +decl_mc_funcs(8); +decl_mc_funcs(4); + +#define define_8tap_2d_funcs(sz) \ + define_8tap_2d_fn(put, regular, sz) \ + define_8tap_2d_fn(put, sharp, sz) \ + define_8tap_2d_fn(put, smooth, sz) \ + define_8tap_2d_fn(avg, regular, sz) \ + define_8tap_2d_fn(avg, sharp, sz) \ + define_8tap_2d_fn(avg, smooth, sz) + +define_8tap_2d_funcs(64) +define_8tap_2d_funcs(32) +define_8tap_2d_funcs(16) +define_8tap_2d_funcs(8) +define_8tap_2d_funcs(4) + +av_cold void ff_vp9dsp_init_aarch64(VP9DSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + +#define init_fpel(idx1, idx2, sz, type, suffix) \ + dsp->mc[idx1][FILTER_8TAP_SMOOTH ][idx2][0][0] = \ + dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][0][0] = \ + dsp->mc[idx1][FILTER_8TAP_SHARP ][idx2][0][0] = \ + dsp->mc[idx1][FILTER_BILINEAR ][idx2][0][0] = ff_vp9_##type##sz##suffix + +#define init_copy(idx, sz, suffix) \ + init_fpel(idx, 0, sz, copy, suffix) + +#define init_avg(idx, sz, suffix) \ + init_fpel(idx, 1, sz, avg, suffix) + +#define init_copy_avg(idx, sz) \ + init_copy(idx, sz, _neon); \ + init_avg (idx, sz, _neon) + + if (have_armv8(cpu_flags)) { + init_copy(0, 64, _aarch64); + init_copy(1, 32, _aarch64); + } + + if (have_neon(cpu_flags)) { +#define init_mc_func(idx1, idx2, op, filter, fname, dir, mx, my, sz, pfx) \ + dsp->mc[idx1][filter][idx2][mx][my] = pfx##op##_##fname##sz##_##dir##_neon + +#define init_mc_funcs(idx, dir, mx, my, sz, pfx) \ + init_mc_func(idx, 0, put, FILTER_8TAP_REGULAR, regular, dir, mx, my, sz, pfx); \ + init_mc_func(idx, 0, put, FILTER_8TAP_SHARP, sharp, dir, mx, my, sz, pfx); \ + init_mc_func(idx, 0, put, FILTER_8TAP_SMOOTH, smooth, dir, mx, my, sz, pfx); \ + init_mc_func(idx, 1, avg, FILTER_8TAP_REGULAR, regular, dir, mx, my, sz, pfx); \ + init_mc_func(idx, 1, avg, FILTER_8TAP_SHARP, sharp, dir, mx, my, sz, pfx); \ + init_mc_func(idx, 1, avg, FILTER_8TAP_SMOOTH, smooth, dir, mx, my, sz, pfx) + +#define init_mc_funcs_dirs(idx, sz) \ + init_mc_funcs(idx, h, 1, 0, sz, ff_vp9_); \ + init_mc_funcs(idx, v, 0, 1, sz, ff_vp9_); \ + init_mc_funcs(idx, hv, 1, 1, sz,) + + init_avg(0, 64, _neon); + init_avg(1, 32, _neon); + init_copy_avg(2, 16); + init_copy_avg(3, 8); + init_copy_avg(4, 4); + + init_mc_funcs_dirs(0, 64); + init_mc_funcs_dirs(1, 32); + init_mc_funcs_dirs(2, 16); + init_mc_funcs_dirs(3, 8); + init_mc_funcs_dirs(4, 4); + } +} diff --git a/libavcodec/aarch64/vp9mc_neon.S b/libavcodec/aarch64/vp9mc_neon.S new file mode 100644 index 0000000000000..720273b1150ae --- /dev/null +++ b/libavcodec/aarch64/vp9mc_neon.S @@ -0,0 +1,679 @@ +/* + * Copyright (c) 2016 Google Inc. + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/aarch64/asm.S" + +// All public functions in this file have the following signature: +// typedef void (*vp9_mc_func)(uint8_t *dst, ptrdiff_t dst_stride, +// const uint8_t *ref, ptrdiff_t ref_stride, +// int h, int mx, int my); + +function ff_vp9_copy64_aarch64, export=1 +1: + ldp x5, x6, [x2] + ldp x7, x8, [x2, #16] + stp x5, x6, [x0] + ldp x9, x10, [x2, #32] + stp x7, x8, [x0, #16] + subs w4, w4, #1 + ldp x11, x12, [x2, #48] + stp x9, x10, [x0, #32] + stp x11, x12, [x0, #48] + add x2, x2, x3 + add x0, x0, x1 + b.ne 1b + ret +endfunc + +function ff_vp9_avg64_neon, export=1 + mov x5, x0 +1: + ld1 {v4.16b, v5.16b, v6.16b, v7.16b}, [x2], x3 + ld1 {v0.16b, v1.16b, v2.16b, v3.16b}, [x0], x1 + ld1 {v20.16b, v21.16b, v22.16b, v23.16b}, [x2], x3 + urhadd v0.16b, v0.16b, v4.16b + urhadd v1.16b, v1.16b, v5.16b + ld1 {v16.16b, v17.16b, v18.16b, v19.16b}, [x0], x1 + urhadd v2.16b, v2.16b, v6.16b + urhadd v3.16b, v3.16b, v7.16b + subs w4, w4, #2 + urhadd v16.16b, v16.16b, v20.16b + urhadd v17.16b, v17.16b, v21.16b + st1 {v0.16b, v1.16b, v2.16b, v3.16b}, [x5], x1 + urhadd v18.16b, v18.16b, v22.16b + urhadd v19.16b, v19.16b, v23.16b + st1 {v16.16b, v17.16b, v18.16b, v19.16b}, [x5], x1 + b.ne 1b + ret +endfunc + +function ff_vp9_copy32_aarch64, export=1 +1: + ldp x5, x6, [x2] + ldp x7, x8, [x2, #16] + stp x5, x6, [x0] + subs w4, w4, #1 + stp x7, x8, [x0, #16] + add x2, x2, x3 + add x0, x0, x1 + b.ne 1b + ret +endfunc + +function ff_vp9_avg32_neon, export=1 +1: + ld1 {v2.16b, v3.16b}, [x2], x3 + ld1 {v0.16b, v1.16b}, [x0] + urhadd v0.16b, v0.16b, v2.16b + urhadd v1.16b, v1.16b, v3.16b + subs w4, w4, #1 + st1 {v0.16b, v1.16b}, [x0], x1 + b.ne 1b + ret +endfunc + +function ff_vp9_copy16_neon, export=1 + add x5, x0, x1 + lsl x1, x1, #1 + add x6, x2, x3 + lsl x3, x3, #1 +1: + ld1 {v0.16b}, [x2], x3 + ld1 {v1.16b}, [x6], x3 + ld1 {v2.16b}, [x2], x3 + ld1 {v3.16b}, [x6], x3 + subs w4, w4, #4 + st1 {v0.16b}, [x0], x1 + st1 {v1.16b}, [x5], x1 + st1 {v2.16b}, [x0], x1 + st1 {v3.16b}, [x5], x1 + b.ne 1b + ret +endfunc + +function ff_vp9_avg16_neon, export=1 + mov x5, x0 +1: + ld1 {v2.16b}, [x2], x3 + ld1 {v0.16b}, [x0], x1 + ld1 {v3.16b}, [x2], x3 + urhadd v0.16b, v0.16b, v2.16b + ld1 {v1.16b}, [x0], x1 + urhadd v1.16b, v1.16b, v3.16b + subs w4, w4, #2 + st1 {v0.16b}, [x5], x1 + st1 {v1.16b}, [x5], x1 + b.ne 1b + ret +endfunc + +function ff_vp9_copy8_neon, export=1 +1: + ld1 {v0.8b}, [x2], x3 + ld1 {v1.8b}, [x2], x3 + subs w4, w4, #2 + st1 {v0.8b}, [x0], x1 + st1 {v1.8b}, [x0], x1 + b.ne 1b + ret +endfunc + +function ff_vp9_avg8_neon, export=1 + mov x5, x0 +1: + ld1 {v2.8b}, [x2], x3 + ld1 {v0.8b}, [x0], x1 + ld1 {v3.8b}, [x2], x3 + urhadd v0.8b, v0.8b, v2.8b + ld1 {v1.8b}, [x0], x1 + urhadd v1.8b, v1.8b, v3.8b + subs w4, w4, #2 + st1 {v0.8b}, [x5], x1 + st1 {v1.8b}, [x5], x1 + b.ne 1b + ret +endfunc + +function ff_vp9_copy4_neon, export=1 +1: + ld1 {v0.s}[0], [x2], x3 + ld1 {v1.s}[0], [x2], x3 + st1 {v0.s}[0], [x0], x1 + ld1 {v2.s}[0], [x2], x3 + st1 {v1.s}[0], [x0], x1 + ld1 {v3.s}[0], [x2], x3 + subs w4, w4, #4 + st1 {v2.s}[0], [x0], x1 + st1 {v3.s}[0], [x0], x1 + b.ne 1b + ret +endfunc + +function ff_vp9_avg4_neon, export=1 + mov x5, x0 +1: + ld1 {v2.s}[0], [x2], x3 + ld1 {v0.s}[0], [x0], x1 + ld1 {v2.s}[1], [x2], x3 + ld1 {v0.s}[1], [x0], x1 + ld1 {v3.s}[0], [x2], x3 + ld1 {v1.s}[0], [x0], x1 + ld1 {v3.s}[1], [x2], x3 + ld1 {v1.s}[1], [x0], x1 + subs w4, w4, #4 + urhadd v0.8b, v0.8b, v2.8b + urhadd v1.8b, v1.8b, v3.8b + st1 {v0.s}[0], [x5], x1 + st1 {v0.s}[1], [x5], x1 + st1 {v1.s}[0], [x5], x1 + st1 {v1.s}[1], [x5], x1 + b.ne 1b + ret +endfunc + + +// Extract a vector from src1-src2 and src4-src5 (src1-src3 and src4-src6 +// for size >= 16), and multiply-accumulate into dst1 and dst3 (or +// dst1-dst2 and dst3-dst4 for size >= 16) +.macro extmla dst1, dst2, dst3, dst4, src1, src2, src3, src4, src5, src6, offset, size + ext v20.16b, \src1, \src2, #(2*\offset) + ext v22.16b, \src4, \src5, #(2*\offset) +.if \size >= 16 + mla \dst1, v20.8h, v0.h[\offset] + ext v21.16b, \src2, \src3, #(2*\offset) + mla \dst3, v22.8h, v0.h[\offset] + ext v23.16b, \src5, \src6, #(2*\offset) + mla \dst2, v21.8h, v0.h[\offset] + mla \dst4, v23.8h, v0.h[\offset] +.else + mla \dst1, v20.8h, v0.h[\offset] + mla \dst3, v22.8h, v0.h[\offset] +.endif +.endm +// The same as above, but don't accumulate straight into the +// destination, but use a temp register and accumulate with saturation. +.macro extmulqadd dst1, dst2, dst3, dst4, src1, src2, src3, src4, src5, src6, offset, size + ext v20.16b, \src1, \src2, #(2*\offset) + ext v22.16b, \src4, \src5, #(2*\offset) +.if \size >= 16 + mul v20.8h, v20.8h, v0.h[\offset] + ext v21.16b, \src2, \src3, #(2*\offset) + mul v22.8h, v22.8h, v0.h[\offset] + ext v23.16b, \src5, \src6, #(2*\offset) + mul v21.8h, v21.8h, v0.h[\offset] + mul v23.8h, v23.8h, v0.h[\offset] +.else + mul v20.8h, v20.8h, v0.h[\offset] + mul v22.8h, v22.8h, v0.h[\offset] +.endif + sqadd \dst1, \dst1, v20.8h + sqadd \dst3, \dst3, v22.8h +.if \size >= 16 + sqadd \dst2, \dst2, v21.8h + sqadd \dst4, \dst4, v23.8h +.endif +.endm + + +// Instantiate a horizontal filter function for the given size. +// This can work on 4, 8 or 16 pixels in parallel; for larger +// widths it will do 16 pixels at a time and loop horizontally. +// The actual width is passed in x5, the height in w4 and the +// filter coefficients in x9. idx2 is the index of the largest +// filter coefficient (3 or 4) and idx1 is the other one of them. +.macro do_8tap_h type, size, idx1, idx2 +function \type\()_8tap_\size\()h_\idx1\idx2 + sub x2, x2, #3 + add x6, x0, x1 + add x7, x2, x3 + add x1, x1, x1 + add x3, x3, x3 + // Only size >= 16 loops horizontally and needs + // reduced dst stride +.if \size >= 16 + sub x1, x1, x5 +.endif + // size >= 16 loads two qwords and increments r2, + // for size 4/8 it's enough with one qword and no + // postincrement +.if \size >= 16 + sub x3, x3, x5 + sub x3, x3, #8 +.endif + // Load the filter vector + ld1 {v0.8b}, [x9] + sxtl v0.8h, v0.8b +1: +.if \size >= 16 + mov x9, x5 +.endif + // Load src +.if \size >= 16 + ld1 {v4.8b, v5.8b, v6.8b}, [x2], #24 + ld1 {v16.8b, v17.8b, v18.8b}, [x7], #24 +.else + ld1 {v4.8b, v5.8b}, [x2] + ld1 {v16.8b, v17.8b}, [x7] +.endif + uxtl v4.8h, v4.8b + uxtl v5.8h, v5.8b + uxtl v16.8h, v16.8b + uxtl v17.8h, v17.8b +.if \size >= 16 + uxtl v6.8h, v6.8b + uxtl v18.8h, v18.8b +.endif +2: + + // Accumulate, adding idx2 last with a separate + // saturating add. The positive filter coefficients + // for all indices except idx2 must add up to less + // than 127 for this not to overflow. + mul v1.8h, v4.8h, v0.h[0] + mul v24.8h, v16.8h, v0.h[0] +.if \size >= 16 + mul v2.8h, v5.8h, v0.h[0] + mul v25.8h, v17.8h, v0.h[0] +.endif + extmla v1.8h, v2.8h, v24.8h, v25.8h, v4.16b, v5.16b, v6.16b, v16.16b, v17.16b, v18.16b, 1, \size + extmla v1.8h, v2.8h, v24.8h, v25.8h, v4.16b, v5.16b, v6.16b, v16.16b, v17.16b, v18.16b, 2, \size + extmla v1.8h, v2.8h, v24.8h, v25.8h, v4.16b, v5.16b, v6.16b, v16.16b, v17.16b, v18.16b, \idx1, \size + extmla v1.8h, v2.8h, v24.8h, v25.8h, v4.16b, v5.16b, v6.16b, v16.16b, v17.16b, v18.16b, 5, \size + extmla v1.8h, v2.8h, v24.8h, v25.8h, v4.16b, v5.16b, v6.16b, v16.16b, v17.16b, v18.16b, 6, \size + extmla v1.8h, v2.8h, v24.8h, v25.8h, v4.16b, v5.16b, v6.16b, v16.16b, v17.16b, v18.16b, 7, \size + extmulqadd v1.8h, v2.8h, v24.8h, v25.8h, v4.16b, v5.16b, v6.16b, v16.16b, v17.16b, v18.16b, \idx2, \size + + // Round, shift and saturate + sqrshrun v1.8b, v1.8h, #7 + sqrshrun v24.8b, v24.8h, #7 +.if \size >= 16 + sqrshrun2 v1.16b, v2.8h, #7 + sqrshrun2 v24.16b, v25.8h, #7 +.endif + // Average +.ifc \type,avg +.if \size >= 16 + ld1 {v2.16b}, [x0] + ld1 {v3.16b}, [x6] + urhadd v1.16b, v1.16b, v2.16b + urhadd v24.16b, v24.16b, v3.16b +.elseif \size == 8 + ld1 {v2.8b}, [x0] + ld1 {v3.8b}, [x6] + urhadd v1.8b, v1.8b, v2.8b + urhadd v24.8b, v24.8b, v3.8b +.else + ld1 {v2.s}[0], [x0] + ld1 {v3.s}[0], [x6] + urhadd v1.8b, v1.8b, v2.8b + urhadd v24.8b, v24.8b, v3.8b +.endif +.endif + // Store and loop horizontally (for size >= 16) +.if \size >= 16 + subs x9, x9, #16 + st1 {v1.16b}, [x0], #16 + st1 {v24.16b}, [x6], #16 + beq 3f + mov v4.16b, v6.16b + mov v16.16b, v18.16b + ld1 {v6.16b}, [x2], #16 + ld1 {v18.16b}, [x7], #16 + uxtl v5.8h, v6.8b + uxtl2 v6.8h, v6.16b + uxtl v17.8h, v18.8b + uxtl2 v18.8h, v18.16b + b 2b +.elseif \size == 8 + st1 {v1.8b}, [x0] + st1 {v24.8b}, [x6] +.else // \size == 4 + st1 {v1.s}[0], [x0] + st1 {v24.s}[0], [x6] +.endif +3: + // Loop vertically + add x0, x0, x1 + add x6, x6, x1 + add x2, x2, x3 + add x7, x7, x3 + subs w4, w4, #2 + b.ne 1b + ret +endfunc +.endm + +.macro do_8tap_h_size size +do_8tap_h put, \size, 3, 4 +do_8tap_h avg, \size, 3, 4 +do_8tap_h put, \size, 4, 3 +do_8tap_h avg, \size, 4, 3 +.endm + +do_8tap_h_size 4 +do_8tap_h_size 8 +do_8tap_h_size 16 + +.macro do_8tap_h_func type, filter, offset, size +function ff_vp9_\type\()_\filter\()\size\()_h_neon, export=1 + movrel x6, X(ff_vp9_subpel_filters), 120*\offset - 8 + cmp w5, #8 + add x9, x6, w5, uxtw #3 + mov x5, #\size +.if \size >= 16 + bge \type\()_8tap_16h_34 + b \type\()_8tap_16h_43 +.else + bge \type\()_8tap_\size\()h_34 + b \type\()_8tap_\size\()h_43 +.endif +endfunc +.endm + +.macro do_8tap_h_filters size +do_8tap_h_func put, regular, 1, \size +do_8tap_h_func avg, regular, 1, \size +do_8tap_h_func put, sharp, 2, \size +do_8tap_h_func avg, sharp, 2, \size +do_8tap_h_func put, smooth, 0, \size +do_8tap_h_func avg, smooth, 0, \size +.endm + +do_8tap_h_filters 64 +do_8tap_h_filters 32 +do_8tap_h_filters 16 +do_8tap_h_filters 8 +do_8tap_h_filters 4 + + +// Vertical filters + +// Round, shift and saturate and store reg1-reg2 over 4 lines +.macro do_store4 reg1, reg2, tmp1, tmp2, type + sqrshrun \reg1\().8b, \reg1\().8h, #7 + sqrshrun \reg2\().8b, \reg2\().8h, #7 +.ifc \type,avg + ld1 {\tmp1\().s}[0], [x7], x1 + ld1 {\tmp2\().s}[0], [x7], x1 + ld1 {\tmp1\().s}[1], [x7], x1 + ld1 {\tmp2\().s}[1], [x7], x1 + urhadd \reg1\().8b, \reg1\().8b, \tmp1\().8b + urhadd \reg2\().8b, \reg2\().8b, \tmp2\().8b +.endif + st1 {\reg1\().s}[0], [x0], x1 + st1 {\reg2\().s}[0], [x0], x1 + st1 {\reg1\().s}[1], [x0], x1 + st1 {\reg2\().s}[1], [x0], x1 +.endm + +// Round, shift and saturate and store reg1-4 +.macro do_store reg1, reg2, reg3, reg4, tmp1, tmp2, tmp3, tmp4, type + sqrshrun \reg1\().8b, \reg1\().8h, #7 + sqrshrun \reg2\().8b, \reg2\().8h, #7 + sqrshrun \reg3\().8b, \reg3\().8h, #7 + sqrshrun \reg4\().8b, \reg4\().8h, #7 +.ifc \type,avg + ld1 {\tmp1\().8b}, [x7], x1 + ld1 {\tmp2\().8b}, [x7], x1 + ld1 {\tmp3\().8b}, [x7], x1 + ld1 {\tmp4\().8b}, [x7], x1 + urhadd \reg1\().8b, \reg1\().8b, \tmp1\().8b + urhadd \reg2\().8b, \reg2\().8b, \tmp2\().8b + urhadd \reg3\().8b, \reg3\().8b, \tmp3\().8b + urhadd \reg4\().8b, \reg4\().8b, \tmp4\().8b +.endif + st1 {\reg1\().8b}, [x0], x1 + st1 {\reg2\().8b}, [x0], x1 + st1 {\reg3\().8b}, [x0], x1 + st1 {\reg4\().8b}, [x0], x1 +.endm + +// Evaluate the filter twice in parallel, from the inputs src1-src9 into dst1-dst2 +// (src1-src8 into dst1, src2-src9 into dst2), adding idx2 separately +// at the end with saturation. Indices 0 and 7 always have negative or zero +// coefficients, so they can be accumulated into tmp1-tmp2 together with the +// largest coefficient. +.macro convolve dst1, dst2, src1, src2, src3, src4, src5, src6, src7, src8, src9, idx1, idx2, tmp1, tmp2 + mul \dst1\().8h, \src2\().8h, v0.h[1] + mul \dst2\().8h, \src3\().8h, v0.h[1] + mul \tmp1\().8h, \src1\().8h, v0.h[0] + mul \tmp2\().8h, \src2\().8h, v0.h[0] + mla \dst1\().8h, \src3\().8h, v0.h[2] + mla \dst2\().8h, \src4\().8h, v0.h[2] +.if \idx1 == 3 + mla \dst1\().8h, \src4\().8h, v0.h[3] + mla \dst2\().8h, \src5\().8h, v0.h[3] +.else + mla \dst1\().8h, \src5\().8h, v0.h[4] + mla \dst2\().8h, \src6\().8h, v0.h[4] +.endif + mla \dst1\().8h, \src6\().8h, v0.h[5] + mla \dst2\().8h, \src7\().8h, v0.h[5] + mla \tmp1\().8h, \src8\().8h, v0.h[7] + mla \tmp2\().8h, \src9\().8h, v0.h[7] + mla \dst1\().8h, \src7\().8h, v0.h[6] + mla \dst2\().8h, \src8\().8h, v0.h[6] +.if \idx2 == 3 + mla \tmp1\().8h, \src4\().8h, v0.h[3] + mla \tmp2\().8h, \src5\().8h, v0.h[3] +.else + mla \tmp1\().8h, \src5\().8h, v0.h[4] + mla \tmp2\().8h, \src6\().8h, v0.h[4] +.endif + sqadd \dst1\().8h, \dst1\().8h, \tmp1\().8h + sqadd \dst2\().8h, \dst2\().8h, \tmp2\().8h +.endm + +// Load pixels and extend them to 16 bit +.macro loadl dst1, dst2, dst3, dst4 + ld1 {v1.8b}, [x2], x3 + ld1 {v2.8b}, [x2], x3 + ld1 {v3.8b}, [x2], x3 +.ifnb \dst4 + ld1 {v4.8b}, [x2], x3 +.endif + uxtl \dst1\().8h, v1.8b + uxtl \dst2\().8h, v2.8b + uxtl \dst3\().8h, v3.8b +.ifnb \dst4 + uxtl \dst4\().8h, v4.8b +.endif +.endm + +// Instantiate a vertical filter function for filtering 8 pixels at a time. +// The height is passed in x4, the width in x5 and the filter coefficients +// in x6. idx2 is the index of the largest filter coefficient (3 or 4) +// and idx1 is the other one of them. +.macro do_8tap_8v type, idx1, idx2 +function \type\()_8tap_8v_\idx1\idx2 + sub x2, x2, x3, lsl #1 + sub x2, x2, x3 + ld1 {v0.8b}, [x6] + sxtl v0.8h, v0.8b +1: +.ifc \type,avg + mov x7, x0 +.endif + mov x6, x4 + + loadl v17, v18, v19 + + loadl v20, v21, v22, v23 +2: + loadl v24, v25, v26, v27 + convolve v1, v2, v17, v18, v19, v20, v21, v22, v23, v24, v25, \idx1, \idx2, v5, v6 + convolve v3, v4, v19, v20, v21, v22, v23, v24, v25, v26, v27, \idx1, \idx2, v5, v6 + do_store v1, v2, v3, v4, v5, v6, v7, v28, \type + + subs x6, x6, #4 + b.eq 8f + + loadl v16, v17, v18, v19 + convolve v1, v2, v21, v22, v23, v24, v25, v26, v27, v16, v17, \idx1, \idx2, v5, v6 + convolve v3, v4, v23, v24, v25, v26, v27, v16, v17, v18, v19, \idx1, \idx2, v5, v6 + do_store v1, v2, v3, v4, v5, v6, v7, v28, \type + + subs x6, x6, #4 + b.eq 8f + + loadl v20, v21, v22, v23 + convolve v1, v2, v25, v26, v27, v16, v17, v18, v19, v20, v21, \idx1, \idx2, v5, v6 + convolve v3, v4, v27, v16, v17, v18, v19, v20, v21, v22, v23, \idx1, \idx2, v5, v6 + do_store v1, v2, v3, v4, v5, v6, v7, v28, \type + + subs x6, x6, #4 + b.ne 2b + +8: + subs x5, x5, #8 + b.eq 9f + // x0 -= h * dst_stride + msub x0, x1, x4, x0 + // x2 -= h * src_stride + msub x2, x3, x4, x2 + // x2 -= 8 * src_stride + sub x2, x2, x3, lsl #3 + // x2 += 1 * src_stride + add x2, x2, x3 + add x2, x2, #8 + add x0, x0, #8 + b 1b +9: + ret +endfunc +.endm + +do_8tap_8v put, 3, 4 +do_8tap_8v put, 4, 3 +do_8tap_8v avg, 3, 4 +do_8tap_8v avg, 4, 3 + + +// Instantiate a vertical filter function for filtering a 4 pixels wide +// slice. The first half of the registers contain one row, while the second +// half of a register contains the second-next row (also stored in the first +// half of the register two steps ahead). The convolution does two outputs +// at a time; the output of v17-v24 into one, and v18-v25 into another one. +// The first half of first output is the first output row, the first half +// of the other output is the second output row. The second halves of the +// registers are rows 3 and 4. +// This only is designed to work for 4 or 8 output lines. +.macro do_8tap_4v type, idx1, idx2 +function \type\()_8tap_4v_\idx1\idx2 + sub x2, x2, x3, lsl #1 + sub x2, x2, x3 + ld1 {v0.8b}, [x6] + sxtl v0.8h, v0.8b +.ifc \type,avg + mov x7, x0 +.endif + + ld1 {v1.s}[0], [x2], x3 + ld1 {v2.s}[0], [x2], x3 + ld1 {v3.s}[0], [x2], x3 + ld1 {v4.s}[0], [x2], x3 + ld1 {v5.s}[0], [x2], x3 + ld1 {v6.s}[0], [x2], x3 + trn1 v1.2s, v1.2s, v3.2s + ld1 {v7.s}[0], [x2], x3 + trn1 v2.2s, v2.2s, v4.2s + ld1 {v26.s}[0], [x2], x3 + uxtl v17.8h, v1.8b + trn1 v3.2s, v3.2s, v5.2s + ld1 {v27.s}[0], [x2], x3 + uxtl v18.8h, v2.8b + trn1 v4.2s, v4.2s, v6.2s + ld1 {v28.s}[0], [x2], x3 + uxtl v19.8h, v3.8b + trn1 v5.2s, v5.2s, v7.2s + ld1 {v29.s}[0], [x2], x3 + uxtl v20.8h, v4.8b + trn1 v6.2s, v6.2s, v26.2s + uxtl v21.8h, v5.8b + trn1 v7.2s, v7.2s, v27.2s + uxtl v22.8h, v6.8b + trn1 v26.2s, v26.2s, v28.2s + uxtl v23.8h, v7.8b + trn1 v27.2s, v27.2s, v29.2s + uxtl v24.8h, v26.8b + uxtl v25.8h, v27.8b + + convolve v1, v2, v17, v18, v19, v20, v21, v22, v23, v24, v25, \idx1, \idx2, v3, v4 + do_store4 v1, v2, v5, v6, \type + + subs x4, x4, #4 + b.eq 9f + + ld1 {v1.s}[0], [x2], x3 + ld1 {v2.s}[0], [x2], x3 + trn1 v28.2s, v28.2s, v1.2s + trn1 v29.2s, v29.2s, v2.2s + ld1 {v1.s}[1], [x2], x3 + uxtl v26.8h, v28.8b + ld1 {v2.s}[1], [x2], x3 + uxtl v27.8h, v29.8b + uxtl v28.8h, v1.8b + uxtl v29.8h, v2.8b + + convolve v1, v2, v21, v22, v23, v24, v25, v26, v27, v28, v29, \idx1, \idx2, v3, v4 + do_store4 v1, v2, v5, v6, \type + +9: + ret +endfunc +.endm + +do_8tap_4v put, 3, 4 +do_8tap_4v put, 4, 3 +do_8tap_4v avg, 3, 4 +do_8tap_4v avg, 4, 3 + + +.macro do_8tap_v_func type, filter, offset, size +function ff_vp9_\type\()_\filter\()\size\()_v_neon, export=1 + uxtw x4, w4 + movrel x5, X(ff_vp9_subpel_filters), 120*\offset - 8 + cmp w6, #8 + add x6, x5, w6, uxtw #3 + mov x5, #\size +.if \size >= 8 + b.ge \type\()_8tap_8v_34 + b \type\()_8tap_8v_43 +.else + b.ge \type\()_8tap_4v_34 + b \type\()_8tap_4v_43 +.endif +endfunc +.endm + +.macro do_8tap_v_filters size +do_8tap_v_func put, regular, 1, \size +do_8tap_v_func avg, regular, 1, \size +do_8tap_v_func put, sharp, 2, \size +do_8tap_v_func avg, sharp, 2, \size +do_8tap_v_func put, smooth, 0, \size +do_8tap_v_func avg, smooth, 0, \size +.endm + +do_8tap_v_filters 64 +do_8tap_v_filters 32 +do_8tap_v_filters 16 +do_8tap_v_filters 8 +do_8tap_v_filters 4 diff --git a/libavcodec/vp9.h b/libavcodec/vp9.h index 654c8ed09c032..6fd5ba18b4489 100644 --- a/libavcodec/vp9.h +++ b/libavcodec/vp9.h @@ -435,6 +435,7 @@ extern const int8_t ff_vp9_subpel_filters[3][15][8]; void ff_vp9dsp_init(VP9DSPContext *dsp); +void ff_vp9dsp_init_aarch64(VP9DSPContext *dsp); void ff_vp9dsp_init_arm(VP9DSPContext *dsp); void ff_vp9dsp_init_x86(VP9DSPContext *dsp); diff --git a/libavcodec/vp9block.c b/libavcodec/vp9block.c index 54f76d6e1c461..194d619ce2277 100644 --- a/libavcodec/vp9block.c +++ b/libavcodec/vp9block.c @@ -1176,7 +1176,7 @@ static av_always_inline void mc_luma_dir(VP9Context *s, vp9_mc_func(*mc)[2], ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); // FIXME bilinear filter only needs 0/1 pixels, not 3/4 - // The arm _hv filters read one more row than what actually is + // The arm/aarch64 _hv filters read one more row than what actually is // needed, so switch to emulated edge one pixel sooner vertically // (!!my * 5) than horizontally (!!mx * 4). if (x < !!mx * 3 || y < !!my * 3 || @@ -1221,7 +1221,7 @@ static av_always_inline void mc_chroma_dir(VP9Context *s, vp9_mc_func(*mc)[2], ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); // FIXME bilinear filter only needs 0/1 pixels, not 3/4 - // The arm _hv filters read one more row than what actually is + // The arm/aarch64 _hv filters read one more row than what actually is // needed, so switch to emulated edge one pixel sooner vertically // (!!my * 5) than horizontally (!!mx * 4). if (x < !!mx * 3 || y < !!my * 3 || diff --git a/libavcodec/vp9dsp.c b/libavcodec/vp9dsp.c index a2862bd1dc32d..73006fa1e6b0f 100644 --- a/libavcodec/vp9dsp.c +++ b/libavcodec/vp9dsp.c @@ -2164,6 +2164,8 @@ av_cold void ff_vp9dsp_init(VP9DSPContext *dsp) vp9dsp_loopfilter_init(dsp); vp9dsp_mc_init(dsp); + if (ARCH_AARCH64) + ff_vp9dsp_init_aarch64(dsp); if (ARCH_ARM) ff_vp9dsp_init_arm(dsp); if (ARCH_X86) From 557c1675cf0e803b2fee43b4c8b58433842c84d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 10 Nov 2016 11:07:39 +0200 Subject: [PATCH 0443/3374] arm: vp9mc: Minor adjustments from review of the aarch64 version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. The speedup for the large horizontal filters is surprisingly big on A7 and A53, while there's a minor slowdown (almost within measurement noise) on A8 and A9. Cortex A7 A8 A9 A53 orig: vp9_put_8tap_smooth_64h_neon: 20270.0 14447.3 19723.9 10910.9 new: vp9_put_8tap_smooth_64h_neon: 20165.8 14466.5 19730.2 10668.8 Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9dsp_init_arm.c | 2 +- libavcodec/arm/vp9mc_neon.S | 133 ++++++++++--------------------- 2 files changed, 44 insertions(+), 91 deletions(-) diff --git a/libavcodec/arm/vp9dsp_init_arm.c b/libavcodec/arm/vp9dsp_init_arm.c index 1b00177f85e9a..839037aed370e 100644 --- a/libavcodec/arm/vp9dsp_init_arm.c +++ b/libavcodec/arm/vp9dsp_init_arm.c @@ -43,7 +43,7 @@ static void op##_##filter##sz##_hv_neon(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *src, ptrdiff_t src_stride, \ int h, int mx, int my) \ { \ - LOCAL_ALIGNED_16(uint8_t, temp, [((sz < 64 ? 2 * sz : 64) + 8) * sz]); \ + LOCAL_ALIGNED_16(uint8_t, temp, [((1 + (sz < 64)) * sz + 8) * sz]); \ /* We only need h + 7 lines, but the horizontal filter assumes an \ * even number of rows, so filter h + 8 lines here. */ \ ff_vp9_put_##filter##sz##_h_neon(temp, sz, \ diff --git a/libavcodec/arm/vp9mc_neon.S b/libavcodec/arm/vp9mc_neon.S index cc8f2417649a9..9deb6562a5be7 100644 --- a/libavcodec/arm/vp9mc_neon.S +++ b/libavcodec/arm/vp9mc_neon.S @@ -20,60 +20,6 @@ #include "libavutil/arm/asm.S" -const regular_filter, align=4 - .short 0, 1, -5, 126, 8, -3, 1, 0 - .short -1, 3, -10, 122, 18, -6, 2, 0 - .short -1, 4, -13, 118, 27, -9, 3, -1 - .short -1, 4, -16, 112, 37, -11, 4, -1 - .short -1, 5, -18, 105, 48, -14, 4, -1 - .short -1, 5, -19, 97, 58, -16, 5, -1 - .short -1, 6, -19, 88, 68, -18, 5, -1 - .short -1, 6, -19, 78, 78, -19, 6, -1 - .short -1, 5, -18, 68, 88, -19, 6, -1 - .short -1, 5, -16, 58, 97, -19, 5, -1 - .short -1, 4, -14, 48, 105, -18, 5, -1 - .short -1, 4, -11, 37, 112, -16, 4, -1 - .short -1, 3, -9, 27, 118, -13, 4, -1 - .short 0, 2, -6, 18, 122, -10, 3, -1 - .short 0, 1, -3, 8, 126, -5, 1, 0 -endconst - -const sharp_filter, align=4 - .short -1, 3, -7, 127, 8, -3, 1, 0 - .short -2, 5, -13, 125, 17, -6, 3, -1 - .short -3, 7, -17, 121, 27, -10, 5, -2 - .short -4, 9, -20, 115, 37, -13, 6, -2 - .short -4, 10, -23, 108, 48, -16, 8, -3 - .short -4, 10, -24, 100, 59, -19, 9, -3 - .short -4, 11, -24, 90, 70, -21, 10, -4 - .short -4, 11, -23, 80, 80, -23, 11, -4 - .short -4, 10, -21, 70, 90, -24, 11, -4 - .short -3, 9, -19, 59, 100, -24, 10, -4 - .short -3, 8, -16, 48, 108, -23, 10, -4 - .short -2, 6, -13, 37, 115, -20, 9, -4 - .short -2, 5, -10, 27, 121, -17, 7, -3 - .short -1, 3, -6, 17, 125, -13, 5, -2 - .short 0, 1, -3, 8, 127, -7, 3, -1 -endconst - -const smooth_filter, align=4 - .short -3, -1, 32, 64, 38, 1, -3, 0 - .short -2, -2, 29, 63, 41, 2, -3, 0 - .short -2, -2, 26, 63, 43, 4, -4, 0 - .short -2, -3, 24, 62, 46, 5, -4, 0 - .short -2, -3, 21, 60, 49, 7, -4, 0 - .short -1, -4, 18, 59, 51, 9, -4, 0 - .short -1, -4, 16, 57, 53, 12, -4, -1 - .short -1, -4, 14, 55, 55, 14, -4, -1 - .short -1, -4, 12, 53, 57, 16, -4, -1 - .short 0, -4, 9, 51, 59, 18, -4, -1 - .short 0, -4, 7, 49, 60, 21, -3, -2 - .short 0, -4, 5, 46, 62, 24, -3, -2 - .short 0, -4, 4, 43, 63, 26, -2, -2 - .short 0, -3, 2, 41, 63, 29, -2, -2 - .short 0, -3, 1, 38, 64, 32, -1, -3 -endconst - @ All public functions in this file have the following signature: @ typedef void (*vp9_mc_func)(uint8_t *dst, ptrdiff_t dst_stride, @ const uint8_t *ref, ptrdiff_t ref_stride, @@ -156,20 +102,21 @@ function ff_vp9_copy16_neon, export=1 endfunc function ff_vp9_avg16_neon, export=1 - ldr r12, [sp] + push {lr} + ldr r12, [sp, #4] + mov lr, r0 1: vld1.8 {q2}, [r2], r3 vld1.8 {q0}, [r0, :128], r1 vld1.8 {q3}, [r2], r3 vrhadd.u8 q0, q0, q2 - vld1.8 {q1}, [r0, :128] - sub r0, r0, r1 + vld1.8 {q1}, [r0, :128], r1 vrhadd.u8 q1, q1, q3 subs r12, r12, #2 - vst1.8 {q0}, [r0, :128], r1 - vst1.8 {q1}, [r0, :128], r1 + vst1.8 {q0}, [lr, :128], r1 + vst1.8 {q1}, [lr, :128], r1 bne 1b - bx lr + pop {pc} endfunc function ff_vp9_copy8_neon, export=1 @@ -218,7 +165,9 @@ function ff_vp9_copy4_neon, export=1 endfunc function ff_vp9_avg4_neon, export=1 - ldr r12, [sp] + push {lr} + ldr r12, [sp, #4] + mov lr, r0 1: vld1.32 {d4[]}, [r2], r3 vld1.32 {d0[]}, [r0, :32], r1 @@ -231,15 +180,14 @@ function ff_vp9_avg4_neon, export=1 vld1.32 {d7[]}, [r2], r3 vrhadd.u8 d2, d2, d6 vld1.32 {d3[]}, [r0, :32], r1 - sub r0, r0, r1, lsl #2 subs r12, r12, #4 - vst1.32 {d0[0]}, [r0, :32], r1 + vst1.32 {d0[0]}, [lr, :32], r1 vrhadd.u8 d3, d3, d7 - vst1.32 {d1[0]}, [r0, :32], r1 - vst1.32 {d2[0]}, [r0, :32], r1 - vst1.32 {d3[0]}, [r0, :32], r1 + vst1.32 {d1[0]}, [lr, :32], r1 + vst1.32 {d2[0]}, [lr, :32], r1 + vst1.32 {d3[0]}, [lr, :32], r1 bne 1b - bx lr + pop {pc} endfunc @ Helper macros for vmul/vmla with a constant from either d0 or d1 depending on index @@ -327,7 +275,8 @@ function \type\()_8tap_\size\()h_\idx1\idx2 sub r3, r3, #8 .endif @ Load the filter vector - vld1.16 {q0}, [r12,:128] + vld1.8 {d0}, [r12,:64] + vmovl.s8 q0, d0 1: .if \size >= 16 mov r12, r5 @@ -397,12 +346,12 @@ function \type\()_8tap_\size\()h_\idx1\idx2 .endif @ Store and loop horizontally (for size >= 16) .if \size >= 16 + subs r12, r12, #16 vst1.8 {q1}, [r0,:128]! vst1.8 {q3}, [r6,:128]! + beq 3f vmov q8, q10 vmov q11, q13 - subs r12, r12, #16 - beq 3f vld1.8 {q10}, [r2]! vld1.8 {q13}, [r7]! vmovl.u8 q9, d20 @@ -444,7 +393,7 @@ do_8tap_h_size 4 do_8tap_h_size 8 do_8tap_h_size 16 -.macro do_8tap_h_func type, filter, size +.macro do_8tap_h_func type, filter, offset, size function ff_vp9_\type\()_\filter\()\size\()_h_neon, export=1 push {r4-r7} .if \size >= 16 @@ -455,9 +404,10 @@ function ff_vp9_\type\()_\filter\()\size\()_h_neon, export=1 ldr r4, [sp, #16] ldr r5, [sp, #20] .endif - movrel r12, \filter\()_filter-16 + movrelx r12, X(ff_vp9_subpel_filters) + add r12, r12, 120*\offset - 8 cmp r5, #8 - add r12, r12, r5, lsl #4 + add r12, r12, r5, lsl #3 mov r5, #\size .if \size >= 16 bge \type\()_8tap_16h_34 @@ -470,12 +420,12 @@ endfunc .endm .macro do_8tap_h_filters size -do_8tap_h_func put, regular, \size -do_8tap_h_func avg, regular, \size -do_8tap_h_func put, sharp, \size -do_8tap_h_func avg, sharp, \size -do_8tap_h_func put, smooth, \size -do_8tap_h_func avg, smooth, \size +do_8tap_h_func put, regular, 1, \size +do_8tap_h_func avg, regular, 1, \size +do_8tap_h_func put, sharp, 2, \size +do_8tap_h_func avg, sharp, 2, \size +do_8tap_h_func put, smooth, 0, \size +do_8tap_h_func avg, smooth, 0, \size .endm do_8tap_h_filters 64 @@ -590,7 +540,8 @@ do_8tap_h_filters 4 function \type\()_8tap_8v_\idx1\idx2 sub r2, r2, r3, lsl #1 sub r2, r2, r3 - vld1.16 {q0}, [r12, :128] + vld1.8 {d0}, [r12, :64] + vmovl.s8 q0, d0 1: mov r12, r4 @@ -660,7 +611,8 @@ do_8tap_8v avg, 4, 3 function \type\()_8tap_4v_\idx1\idx2 sub r2, r2, r3, lsl #1 sub r2, r2, r3 - vld1.16 {q0}, [r12, :128] + vld1.8 {d0}, [r12, :64] + vmovl.s8 q0, d0 vld1.32 {d2[]}, [r2], r3 vld1.32 {d3[]}, [r2], r3 @@ -723,14 +675,15 @@ do_8tap_4v put, 4, 3 do_8tap_4v avg, 3, 4 do_8tap_4v avg, 4, 3 -.macro do_8tap_v_func type, filter, size +.macro do_8tap_v_func type, filter, offset, size function ff_vp9_\type\()_\filter\()\size\()_v_neon, export=1 push {r4-r5} vpush {q4-q7} ldr r4, [sp, #72] ldr r5, [sp, #80] - movrel r12, \filter\()_filter-16 - add r12, r12, r5, lsl #4 + movrelx r12, X(ff_vp9_subpel_filters) + add r12, r12, 120*\offset - 8 + add r12, r12, r5, lsl #3 cmp r5, #8 mov r5, #\size .if \size >= 8 @@ -744,12 +697,12 @@ endfunc .endm .macro do_8tap_v_filters size -do_8tap_v_func put, regular, \size -do_8tap_v_func avg, regular, \size -do_8tap_v_func put, sharp, \size -do_8tap_v_func avg, sharp, \size -do_8tap_v_func put, smooth, \size -do_8tap_v_func avg, smooth, \size +do_8tap_v_func put, regular, 1, \size +do_8tap_v_func avg, regular, 1, \size +do_8tap_v_func put, sharp, 2, \size +do_8tap_v_func avg, sharp, 2, \size +do_8tap_v_func put, smooth, 0, \size +do_8tap_v_func avg, smooth, 0, \size .endm do_8tap_v_filters 64 From 6a62795d4051f435a9a2c59395d96913693922f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 9 Nov 2016 11:54:25 +0200 Subject: [PATCH 0444/3374] aarch64: h264idct: Use the offset parameter to movrel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/aarch64/h264idct_neon.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/aarch64/h264idct_neon.S b/libavcodec/aarch64/h264idct_neon.S index ee2397727180b..1c43c1f301e22 100644 --- a/libavcodec/aarch64/h264idct_neon.S +++ b/libavcodec/aarch64/h264idct_neon.S @@ -162,7 +162,7 @@ function ff_h264_idct_add8_neon, export=1 mov w19, w3 // stride movrel x13, X(ff_h264_idct_dc_add_neon) movrel x14, X(ff_h264_idct_add_neon) - movrel x7, scan8+16 + movrel x7, scan8, 16 mov x10, #0 mov x11, #16 1: mov w2, w19 From 905cdcaa9d081d3d945ce555b27b43a75c3af57b Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 9 Nov 2016 06:07:06 +0100 Subject: [PATCH 0445/3374] examples/decode_audio: Add missing header for av_free() --- doc/examples/decode_audio.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/examples/decode_audio.c b/doc/examples/decode_audio.c index 647893c91f5fc..b56a5ee7f2925 100644 --- a/doc/examples/decode_audio.c +++ b/doc/examples/decode_audio.c @@ -29,9 +29,10 @@ #include #include -#include "libavcodec/avcodec.h" - #include "libavutil/frame.h" +#include "libavutil/mem.h" + +#include "libavcodec/avcodec.h" #define AUDIO_INBUF_SIZE 20480 #define AUDIO_REFILL_THRESH 4096 From 824e8c284054f323f854892d1b4739239ed1fdc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 10 Nov 2016 13:23:38 +0200 Subject: [PATCH 0446/3374] arm: Clear the gp register alias at the end of functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We reset .Lpic_gp to zero at the start of each function, which means that the logic within movrelx for clearing gp when necessary will be missed. This fixes using movrelx in different functions with a different helper register. Signed-off-by: Martin Storsjö --- libavutil/arm/asm.S | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavutil/arm/asm.S b/libavutil/arm/asm.S index 1a048b56fb636..4ac0ea2e4fb15 100644 --- a/libavutil/arm/asm.S +++ b/libavutil/arm/asm.S @@ -83,6 +83,9 @@ ELF .section .note.GNU-stack,"",%progbits @ Mark stack as non-executable put_pic %(.Lpic_idx - 1) .noaltmacro .endif + .if .Lpic_gp + .unreq gp + .endif ELF .size \name, . - \name FUNC .endfunc .purgem endfunc From 11623217e3c9b859daee544e31acdd0821b61039 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 10 Nov 2016 13:25:36 +0200 Subject: [PATCH 0447/3374] arm: vp9mc: Use a different helper register for PIC loads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes crashes since 557c1675cf in linux PIC builds. Previously, movrelx silently used r12 as helper register, which doesn't work when r12 is the destination register. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9mc_neon.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/arm/vp9mc_neon.S b/libavcodec/arm/vp9mc_neon.S index 9deb6562a5be7..d3d2c7f96b3f9 100644 --- a/libavcodec/arm/vp9mc_neon.S +++ b/libavcodec/arm/vp9mc_neon.S @@ -404,7 +404,7 @@ function ff_vp9_\type\()_\filter\()\size\()_h_neon, export=1 ldr r4, [sp, #16] ldr r5, [sp, #20] .endif - movrelx r12, X(ff_vp9_subpel_filters) + movrelx r12, X(ff_vp9_subpel_filters), r6 add r12, r12, 120*\offset - 8 cmp r5, #8 add r12, r12, r5, lsl #3 @@ -680,8 +680,8 @@ function ff_vp9_\type\()_\filter\()\size\()_v_neon, export=1 push {r4-r5} vpush {q4-q7} ldr r4, [sp, #72] + movrelx r12, X(ff_vp9_subpel_filters), r5 ldr r5, [sp, #80] - movrelx r12, X(ff_vp9_subpel_filters) add r12, r12, 120*\offset - 8 add r12, r12, r5, lsl #3 cmp r5, #8 From fd0fae60372cddbe0bec8830d07e760195f80bad Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Thu, 3 Nov 2016 00:13:35 +0000 Subject: [PATCH 0448/3374] pthread_frame: Unreference hw_frames_ctx on per-thread codec contexts When decoding with threads enabled, the get_format callback will be called with one of the per-thread codec contexts rather than with the outer context. If a hwaccel is in use too, this will add a reference to the hardware frames context on that codec context, which will then propagate to all of the other per-thread contexts for decoding. Once the decoder finishes, however, the per-thread contexts are not freed normally, so these references leak. --- libavcodec/pthread_frame.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 671c551f29acc..2736a81efea77 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -571,6 +571,8 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) av_freep(&p->avctx->slice_offset); } + av_buffer_unref(&p->avctx->hw_frames_ctx); + av_freep(&p->avctx->internal); av_freep(&p->avctx); } From 0b37cd09a67c3ba4db044404b99c65a32b4ad932 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 22 Sep 2015 14:24:27 -0400 Subject: [PATCH 0449/3374] checkasm: add vp9dsp.itxfm_add tests. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This includes fixes by Henrik Gramner. The forward transforms are derived from the reference encoder. Signed-off-by: Martin Storsjö --- tests/checkasm/vp9dsp.c | 272 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 272 insertions(+) diff --git a/tests/checkasm/vp9dsp.c b/tests/checkasm/vp9dsp.c index f0cc2a7e45731..690e0cf536dad 100644 --- a/tests/checkasm/vp9dsp.c +++ b/tests/checkasm/vp9dsp.c @@ -18,13 +18,16 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include #include #include "libavutil/common.h" #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mathematics.h" #include "libavcodec/vp9.h" +#include "libavcodec/vp9data.h" #include "checkasm.h" @@ -33,6 +36,274 @@ static const uint32_t pixel_mask[3] = { 0xffffffff, 0x03ff03ff, 0x0fff0fff }; #define BIT_DEPTH 8 #define SIZEOF_PIXEL ((BIT_DEPTH + 7) / 8) +#define randomize_buffers() \ + do { \ + uint32_t mask = pixel_mask[(BIT_DEPTH - 8) >> 1]; \ + for (y = 0; y < sz; y++) { \ + for (x = 0; x < sz * SIZEOF_PIXEL; x += 4) { \ + uint32_t r = rnd() & mask; \ + AV_WN32A(dst + y * sz * SIZEOF_PIXEL + x, r); \ + AV_WN32A(src + y * sz * SIZEOF_PIXEL + x, rnd() & mask); \ + } \ + for (x = 0; x < sz; x++) { \ + if (BIT_DEPTH == 8) { \ + coef[y * sz + x] = src[y * sz + x] - dst[y * sz + x]; \ + } else { \ + ((int32_t *) coef)[y * sz + x] = \ + ((uint16_t *) src)[y * sz + x] - \ + ((uint16_t *) dst)[y * sz + x]; \ + } \ + } \ + } \ + } while(0) + +// wht function copied from libvpx +static void fwht_1d(double *out, const double *in, int sz) +{ + double t0 = in[0] + in[1]; + double t3 = in[3] - in[2]; + double t4 = trunc((t0 - t3) * 0.5); + double t1 = t4 - in[1]; + double t2 = t4 - in[2]; + + out[0] = t0 - t2; + out[1] = t2; + out[2] = t3 + t1; + out[3] = t1; +} + +// standard DCT-II +static void fdct_1d(double *out, const double *in, int sz) +{ + int k, n; + + for (k = 0; k < sz; k++) { + out[k] = 0.0; + for (n = 0; n < sz; n++) + out[k] += in[n] * cos(M_PI * (2 * n + 1) * k / (sz * 2.0)); + } + out[0] *= M_SQRT1_2; +} + +// see "Towards jointly optimal spatial prediction and adaptive transform in +// video/image coding", by J. Han, A. Saxena, and K. Rose +// IEEE Proc. ICASSP, pp. 726-729, Mar. 2010. +static void fadst4_1d(double *out, const double *in, int sz) +{ + int k, n; + + for (k = 0; k < sz; k++) { + out[k] = 0.0; + for (n = 0; n < sz; n++) + out[k] += in[n] * sin(M_PI * (n + 1) * (2 * k + 1) / (sz * 2.0 + 1.0)); + } +} + +// see "A Butterfly Structured Design of The Hybrid Transform Coding Scheme", +// by Jingning Han, Yaowu Xu, and Debargha Mukherjee +// http://static.googleusercontent.com/media/research.google.com/en//pubs/archive/41418.pdf +static void fadst_1d(double *out, const double *in, int sz) +{ + int k, n; + + for (k = 0; k < sz; k++) { + out[k] = 0.0; + for (n = 0; n < sz; n++) + out[k] += in[n] * sin(M_PI * (2 * n + 1) * (2 * k + 1) / (sz * 4.0)); + } +} + +typedef void (*ftx1d_fn)(double *out, const double *in, int sz); +static void ftx_2d(double *out, const double *in, enum TxfmMode tx, + enum TxfmType txtp, int sz) +{ + static const double scaling_factors[5][4] = { + { 4.0, 16.0 * M_SQRT1_2 / 3.0, 16.0 * M_SQRT1_2 / 3.0, 32.0 / 9.0 }, + { 2.0, 2.0, 2.0, 2.0 }, + { 1.0, 1.0, 1.0, 1.0 }, + { 0.25 }, + { 4.0 } + }; + static const ftx1d_fn ftx1d_tbl[5][4][2] = { + { + { fdct_1d, fdct_1d }, + { fadst4_1d, fdct_1d }, + { fdct_1d, fadst4_1d }, + { fadst4_1d, fadst4_1d }, + }, { + { fdct_1d, fdct_1d }, + { fadst_1d, fdct_1d }, + { fdct_1d, fadst_1d }, + { fadst_1d, fadst_1d }, + }, { + { fdct_1d, fdct_1d }, + { fadst_1d, fdct_1d }, + { fdct_1d, fadst_1d }, + { fadst_1d, fadst_1d }, + }, { + { fdct_1d, fdct_1d }, + }, { + { fwht_1d, fwht_1d }, + }, + }; + double temp[1024]; + double scaling_factor = scaling_factors[tx][txtp]; + int i, j; + + // cols + for (i = 0; i < sz; ++i) { + double temp_out[32]; + + ftx1d_tbl[tx][txtp][0](temp_out, &in[i * sz], sz); + // scale and transpose + for (j = 0; j < sz; ++j) + temp[j * sz + i] = temp_out[j] * scaling_factor; + } + + // rows + for (i = 0; i < sz; i++) + ftx1d_tbl[tx][txtp][1](&out[i * sz], &temp[i * sz], sz); +} + +static void ftx(int16_t *buf, enum TxfmMode tx, + enum TxfmType txtp, int sz, int bit_depth) +{ + double ind[1024], outd[1024]; + int n; + + emms_c(); + for (n = 0; n < sz * sz; n++) { + if (bit_depth == 8) + ind[n] = buf[n]; + else + ind[n] = ((int32_t *) buf)[n]; + } + ftx_2d(outd, ind, tx, txtp, sz); + for (n = 0; n < sz * sz; n++) { + if (bit_depth == 8) + buf[n] = lrint(outd[n]); + else + ((int32_t *) buf)[n] = lrint(outd[n]); + } +} + +static int copy_subcoefs(int16_t *out, const int16_t *in, enum TxfmMode tx, + enum TxfmType txtp, int sz, int sub, int bit_depth) +{ + // copy the topleft coefficients such that the return value (being the + // coefficient scantable index for the eob token) guarantees that only + // the topleft $sub out of $sz (where $sz >= $sub) coefficients in both + // dimensions are non-zero. This leads to braching to specific optimized + // simd versions (e.g. dc-only) so that we get full asm coverage in this + // test + + int n; + const int16_t *scan = ff_vp9_scans[tx][txtp]; + int eob; + + for (n = 0; n < sz * sz; n++) { + int rc = scan[n], rcx = rc % sz, rcy = rc / sz; + + // find eob for this sub-idct + if (rcx >= sub || rcy >= sub) + break; + + // copy coef + if (bit_depth == 8) { + out[rc] = in[rc]; + } else { + AV_COPY32(&out[rc * 2], &in[rc * 2]); + } + } + + eob = n; + + for (; n < sz * sz; n++) { + int rc = scan[n]; + + // zero + if (bit_depth == 8) { + out[rc] = 0; + } else { + AV_ZERO32(&out[rc * 2]); + } + } + + return eob; +} + +static int iszero(const int16_t *c, int sz) +{ + int n; + + for (n = 0; n < sz / sizeof(int16_t); n += 2) + if (AV_RN32A(&c[n])) + return 0; + + return 1; +} + +#define SIZEOF_COEF (2 * ((BIT_DEPTH + 7) / 8)) + +static void check_itxfm(void) +{ + LOCAL_ALIGNED_32(uint8_t, src, [32 * 32 * 2]); + LOCAL_ALIGNED(32, uint8_t, dst, [32 * 32 * 2]); + LOCAL_ALIGNED(32, uint8_t, dst0, [32 * 32 * 2]); + LOCAL_ALIGNED(32, uint8_t, dst1, [32 * 32 * 2]); + LOCAL_ALIGNED(32, int16_t, coef, [32 * 32 * 2]); + LOCAL_ALIGNED(32, int16_t, subcoef0, [32 * 32 * 2]); + LOCAL_ALIGNED(32, int16_t, subcoef1, [32 * 32 * 2]); + declare_func(void, uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob); + VP9DSPContext dsp; + int y, x, tx, txtp, sub; + static const char *const txtp_types[N_TXFM_TYPES] = { + [DCT_DCT] = "dct_dct", [DCT_ADST] = "adst_dct", + [ADST_DCT] = "dct_adst", [ADST_ADST] = "adst_adst" + }; + + ff_vp9dsp_init(&dsp); + + for (tx = TX_4X4; tx <= N_TXFM_SIZES /* 4 = lossless */; tx++) { + int sz = 4 << (tx & 3); + int n_txtps = tx < TX_32X32 ? N_TXFM_TYPES : 1; + + for (txtp = 0; txtp < n_txtps; txtp++) { + if (check_func(dsp.itxfm_add[tx][txtp], "vp9_inv_%s_%dx%d_add", + tx == 4 ? "wht_wht" : txtp_types[txtp], sz, sz)) { + randomize_buffers(); + ftx(coef, tx, txtp, sz, BIT_DEPTH); + + for (sub = (txtp == 0) ? 1 : 2; sub <= sz; sub <<= 1) { + int eob; + + if (sub < sz) { + eob = copy_subcoefs(subcoef0, coef, tx, txtp, + sz, sub, BIT_DEPTH); + } else { + eob = sz * sz; + memcpy(subcoef0, coef, sz * sz * SIZEOF_COEF); + } + + memcpy(dst0, dst, sz * sz * SIZEOF_PIXEL); + memcpy(dst1, dst, sz * sz * SIZEOF_PIXEL); + memcpy(subcoef1, subcoef0, sz * sz * SIZEOF_COEF); + call_ref(dst0, sz * SIZEOF_PIXEL, subcoef0, eob); + call_new(dst1, sz * SIZEOF_PIXEL, subcoef1, eob); + if (memcmp(dst0, dst1, sz * sz * SIZEOF_PIXEL) || + !iszero(subcoef0, sz * sz * SIZEOF_COEF) || + !iszero(subcoef1, sz * sz * SIZEOF_COEF)) + fail(); + } + bench_new(dst, sz * SIZEOF_PIXEL, coef, sz * sz); + } + } + } + report("itxfm"); +} + +#undef randomize_buffers + #define setpx(a,b,c) \ do { \ if (SIZEOF_PIXEL == 1) { \ @@ -279,6 +550,7 @@ static void check_mc(void) void checkasm_check_vp9dsp(void) { + check_itxfm(); check_loopfilter(); check_mc(); } From a67ae67083151f2f9595a1f2d17b601da19b939e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 8 Oct 2016 22:36:18 +0300 Subject: [PATCH 0450/3374] arm: vp9: Add NEON itxfm routines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. For the transforms up to 8x8, we can fit all the data (including temporaries) in registers and just do a straightforward transform of all the data. For 16x16, we do a transform of 4x16 pixels in 4 slices, using a temporary buffer. For 32x32, we transform 4x32 pixels at a time, in two steps of 4x16 pixels each. Examples of relative speedup compared to the C version, from checkasm: Cortex A7 A8 A9 A53 vp9_inv_adst_adst_4x4_add_neon: 3.39 5.83 4.17 4.01 vp9_inv_adst_adst_8x8_add_neon: 3.79 4.86 4.23 3.98 vp9_inv_adst_adst_16x16_add_neon: 3.33 4.36 4.11 4.16 vp9_inv_dct_dct_4x4_add_neon: 4.06 6.16 4.59 4.46 vp9_inv_dct_dct_8x8_add_neon: 4.61 6.01 4.98 4.86 vp9_inv_dct_dct_16x16_add_neon: 3.35 3.44 3.36 3.79 vp9_inv_dct_dct_32x32_add_neon: 3.89 3.50 3.79 4.42 vp9_inv_wht_wht_4x4_add_neon: 3.22 5.13 3.53 3.77 Thus, the speedup vs C code is around 3-6x. This is mostly marginally faster than the corresponding routines in libvpx on most cores, tested with their 32x32 idct (compared to vpx_idct32x32_1024_add_neon). These numbers are slightly in libvpx's favour since their version doesn't clear the input buffer like ours do (although the effect of that on the total runtime probably is negligible.) Cortex A7 A8 A9 A53 vp9_inv_dct_dct_32x32_add_neon: 18436.8 16874.1 14235.1 11988.9 libvpx vpx_idct32x32_1024_add_neon 20789.0 13344.3 15049.9 13030.5 Only on the Cortex A8, the libvpx function is faster. On the other cores, ours is slightly faster even though ours has got source block clearing integrated. Signed-off-by: Martin Storsjö --- libavcodec/arm/Makefile | 3 +- libavcodec/arm/vp9dsp_init_arm.c | 51 +- libavcodec/arm/vp9itxfm_neon.S | 1174 ++++++++++++++++++++++++++++++ 3 files changed, 1226 insertions(+), 2 deletions(-) create mode 100644 libavcodec/arm/vp9itxfm_neon.S diff --git a/libavcodec/arm/Makefile b/libavcodec/arm/Makefile index 26382306539b6..01630ac07a347 100644 --- a/libavcodec/arm/Makefile +++ b/libavcodec/arm/Makefile @@ -139,4 +139,5 @@ NEON-OBJS-$(CONFIG_RV40_DECODER) += arm/rv34dsp_neon.o \ arm/rv40dsp_neon.o NEON-OBJS-$(CONFIG_VORBIS_DECODER) += arm/vorbisdsp_neon.o NEON-OBJS-$(CONFIG_VP6_DECODER) += arm/vp6dsp_neon.o -NEON-OBJS-$(CONFIG_VP9_DECODER) += arm/vp9mc_neon.o +NEON-OBJS-$(CONFIG_VP9_DECODER) += arm/vp9itxfm_neon.o \ + arm/vp9mc_neon.o diff --git a/libavcodec/arm/vp9dsp_init_arm.c b/libavcodec/arm/vp9dsp_init_arm.c index 839037aed370e..f05d51d044f00 100644 --- a/libavcodec/arm/vp9dsp_init_arm.c +++ b/libavcodec/arm/vp9dsp_init_arm.c @@ -94,7 +94,7 @@ define_8tap_2d_funcs(8) define_8tap_2d_funcs(4) -av_cold void ff_vp9dsp_init_arm(VP9DSPContext *dsp) +static av_cold void vp9dsp_mc_init_arm(VP9DSPContext *dsp) { int cpu_flags = av_get_cpu_flags(); @@ -138,3 +138,52 @@ av_cold void ff_vp9dsp_init_arm(VP9DSPContext *dsp) init_mc_funcs_dirs(4, 4); } } + +#define define_itxfm(type_a, type_b, sz) \ +void ff_vp9_##type_a##_##type_b##_##sz##x##sz##_add_neon(uint8_t *_dst, \ + ptrdiff_t stride, \ + int16_t *_block, int eob) + +#define define_itxfm_funcs(sz) \ + define_itxfm(idct, idct, sz); \ + define_itxfm(iadst, idct, sz); \ + define_itxfm(idct, iadst, sz); \ + define_itxfm(iadst, iadst, sz) + +define_itxfm_funcs(4); +define_itxfm_funcs(8); +define_itxfm_funcs(16); +define_itxfm(idct, idct, 32); +define_itxfm(iwht, iwht, 4); + + +static av_cold void vp9dsp_itxfm_init_arm(VP9DSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) { +#define init_itxfm(tx, sz) \ + dsp->itxfm_add[tx][DCT_DCT] = ff_vp9_idct_idct_##sz##_add_neon; \ + dsp->itxfm_add[tx][DCT_ADST] = ff_vp9_iadst_idct_##sz##_add_neon; \ + dsp->itxfm_add[tx][ADST_DCT] = ff_vp9_idct_iadst_##sz##_add_neon; \ + dsp->itxfm_add[tx][ADST_ADST] = ff_vp9_iadst_iadst_##sz##_add_neon + +#define init_idct(tx, nm) \ + dsp->itxfm_add[tx][DCT_DCT] = \ + dsp->itxfm_add[tx][ADST_DCT] = \ + dsp->itxfm_add[tx][DCT_ADST] = \ + dsp->itxfm_add[tx][ADST_ADST] = ff_vp9_##nm##_add_neon + + init_itxfm(TX_4X4, 4x4); + init_itxfm(TX_8X8, 8x8); + init_itxfm(TX_16X16, 16x16); + init_idct(TX_32X32, idct_idct_32x32); + init_idct(4, iwht_iwht_4x4); + } +} + +av_cold void ff_vp9dsp_init_arm(VP9DSPContext *dsp) +{ + vp9dsp_mc_init_arm(dsp); + vp9dsp_itxfm_init_arm(dsp); +} diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S new file mode 100644 index 0000000000000..fca9836df6663 --- /dev/null +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -0,0 +1,1174 @@ +/* + * Copyright (c) 2016 Google Inc. + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/arm/asm.S" +#include "neon.S" + +const itxfm4_coeffs, align=4 + .short 11585, 6270, 15137, 0 +iadst4_coeffs: + .short 5283, 15212, 9929, 13377 +endconst + +const iadst8_coeffs, align=4 + .short 16305, 1606, 14449, 7723, 10394, 12665, 4756, 15679 +idct_coeffs: + .short 11585, 6270, 15137, 3196, 16069, 13623, 9102, 1606 + .short 16305, 12665, 10394, 7723, 14449, 15679, 4756, 0 + .short 804, 16364, 12140, 11003, 7005, 14811, 15426, 5520 + .short 3981, 15893, 14053, 8423, 9760, 13160, 16207, 2404 +endconst + +const iadst16_coeffs, align=4 + .short 16364, 804, 15893, 3981, 14811, 7005, 13160, 9760 + .short 11003, 12140, 8423, 14053, 5520, 15426, 2404, 16207 +endconst + +@ Do four 4x4 transposes, using q registers for the subtransposes that don't +@ need to address the individual d registers. +@ r0,r1 == rq1, r2,r3 == rq1, etc +.macro transpose16_q_4x_4x4 rq0, rq1, rq2, rq3, rq4, rq5, rq6, rq7, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15 + vtrn.32 \rq0, \rq1 + vtrn.32 \rq2, \rq3 + vtrn.32 \rq4, \rq5 + vtrn.32 \rq6, \rq7 + vtrn.16 \r0, \r1 + vtrn.16 \r2, \r3 + vtrn.16 \r4, \r5 + vtrn.16 \r6, \r7 + vtrn.16 \r8, \r9 + vtrn.16 \r10, \r11 + vtrn.16 \r12, \r13 + vtrn.16 \r14, \r15 +.endm + +@ out1 = ((in1 + in2) * d0[0] + (1 << 13)) >> 14 +@ out2 = ((in1 - in2) * d0[0] + (1 << 13)) >> 14 +@ in/out are d registers +.macro mbutterfly0 out1, out2, in1, in2, tmpd1, tmpd2, tmpq3, tmpq4, neg=0 + vadd.s16 \tmpd1, \in1, \in2 + vsub.s16 \tmpd2, \in1, \in2 + vmull.s16 \tmpq3, \tmpd1, d0[0] + vmull.s16 \tmpq4, \tmpd2, d0[0] +.if \neg > 0 + vneg.s32 \tmpq3, \tmpq3 +.endif + vrshrn.s32 \out1, \tmpq3, #14 + vrshrn.s32 \out2, \tmpq4, #14 +.endm + +@ out1,out2 = ((in1 + in2) * d0[0] + (1 << 13)) >> 14 +@ out3,out4 = ((in1 - in2) * d0[0] + (1 << 13)) >> 14 +@ Same as mbutterfly0, but with input being 2 q registers, output +@ being 4 d registers. +@ This can do with either 4 or 6 temporary q registers. +.macro dmbutterfly0 out1, out2, out3, out4, in1, in2, tmpq1, tmpq2, tmpd11, tmpd12, tmpd21, tmpd22, tmpq3, tmpq4, tmpq5, tmpq6 + vadd.s16 \tmpq1, \in1, \in2 + vsub.s16 \tmpq2, \in1, \in2 + vmull.s16 \tmpq3, \tmpd11, d0[0] + vmull.s16 \tmpq4, \tmpd12, d0[0] +.ifb \tmpq5 + vrshrn.s32 \out1, \tmpq3, #14 + vrshrn.s32 \out2, \tmpq4, #14 + vmull.s16 \tmpq3, \tmpd21, d0[0] + vmull.s16 \tmpq4, \tmpd22, d0[0] + vrshrn.s32 \out3, \tmpq3, #14 + vrshrn.s32 \out4, \tmpq4, #14 +.else + vmull.s16 \tmpq5, \tmpd21, d0[0] + vmull.s16 \tmpq6, \tmpd22, d0[0] + vrshrn.s32 \out1, \tmpq3, #14 + vrshrn.s32 \out2, \tmpq4, #14 + vrshrn.s32 \out3, \tmpq5, #14 + vrshrn.s32 \out4, \tmpq6, #14 +.endif +.endm + +@ out1 = in1 * coef1 - in2 * coef2 +@ out2 = in1 * coef2 + in2 * coef1 +@ out are 2 q registers, in are 2 d registers +.macro mbutterfly_l out1, out2, in1, in2, coef1, coef2 + vmull.s16 \out1, \in1, \coef1 + vmlsl.s16 \out1, \in2, \coef2 + vmull.s16 \out2, \in1, \coef2 + vmlal.s16 \out2, \in2, \coef1 +.endm + +@ out1,out2 = in1,in2 * coef1 - in3,in4 * coef2 +@ out3,out4 = in1,in2 * coef2 + in3,in4 * coef1 +@ out are 4 q registers, in are 4 d registers +.macro dmbutterfly_l out1, out2, out3, out4, in1, in2, in3, in4, coef1, coef2 + vmull.s16 \out1, \in1, \coef1 + vmull.s16 \out2, \in2, \coef1 + vmull.s16 \out3, \in1, \coef2 + vmull.s16 \out4, \in2, \coef2 + vmlsl.s16 \out1, \in3, \coef2 + vmlsl.s16 \out2, \in4, \coef2 + vmlal.s16 \out3, \in3, \coef1 + vmlal.s16 \out4, \in4, \coef1 +.endm + +@ in1 = (in1 * coef1 - in2 * coef2 + (1 << 13)) >> 14 +@ in2 = (in1 * coef2 + in2 * coef1 + (1 << 13)) >> 14 +@ in are 2 d registers, tmp are 2 q registers +.macro mbutterfly in1, in2, coef1, coef2, tmp1, tmp2, neg=0 + mbutterfly_l \tmp1, \tmp2, \in1, \in2, \coef1, \coef2 +.if \neg > 0 + vneg.s32 \tmp2, \tmp2 +.endif + vrshrn.s32 \in1, \tmp1, #14 + vrshrn.s32 \in2, \tmp2, #14 +.endm + +@ inout1,inout2 = (inout1,inout2 * coef1 - inout3,inout4 * coef2 + (1 << 13)) >> 14 +@ inout3,inout4 = (inout1,inout2 * coef2 + inout3,inout4 * coef1 + (1 << 13)) >> 14 +@ inout are 4 d registers, tmp are 4 q registers +.macro dmbutterfly inout1, inout2, inout3, inout4, coef1, coef2, tmp1, tmp2, tmp3, tmp4 + dmbutterfly_l \tmp1, \tmp2, \tmp3, \tmp4, \inout1, \inout2, \inout3, \inout4, \coef1, \coef2 + vrshrn.s32 \inout1, \tmp1, #14 + vrshrn.s32 \inout2, \tmp2, #14 + vrshrn.s32 \inout3, \tmp3, #14 + vrshrn.s32 \inout4, \tmp4, #14 +.endm + +@ out1 = in1 + in2 +@ out2 = in1 - in2 +.macro butterfly out1, out2, in1, in2 + vadd.s16 \out1, \in1, \in2 + vsub.s16 \out2, \in1, \in2 +.endm + +@ out1 = in1 - in2 +@ out2 = in1 + in2 +.macro butterfly_r out1, out2, in1, in2 + vsub.s16 \out1, \in1, \in2 + vadd.s16 \out2, \in1, \in2 +.endm + +@ out1 = (in1 + in2 + (1 << 13)) >> 14 +@ out2 = (in1 - in2 + (1 << 13)) >> 14 +@ out are 2 d registers, in are 2 q registers, tmp are 2 q registers +.macro butterfly_n out1, out2, in1, in2, tmp1, tmp2 + vadd.s32 \tmp1, \in1, \in2 + vsub.s32 \tmp2, \in1, \in2 + vrshrn.s32 \out1, \tmp1, #14 + vrshrn.s32 \out2, \tmp2, #14 +.endm + +@ out1,out2 = (in1,in2 + in3,in4 + (1 << 13)) >> 14 +@ out3,out4 = (in1,in2 - in3,in4 + (1 << 13)) >> 14 +@ out are 4 d registers, in are 4 q registers, tmp are 4 q registers +.macro dbutterfly_n out1, out2, out3, out4, in1, in2, in3, in4, tmp1, tmp2, tmp3, tmp4 + vadd.s32 \tmp1, \in1, \in3 + vadd.s32 \tmp2, \in2, \in4 + vsub.s32 \tmp3, \in1, \in3 + vsub.s32 \tmp4, \in2, \in4 + vrshrn.s32 \out1, \tmp1, #14 + vrshrn.s32 \out2, \tmp2, #14 + vrshrn.s32 \out3, \tmp3, #14 + vrshrn.s32 \out4, \tmp4, #14 +.endm + + +.macro iwht4 c0, c1, c2, c3 + vadd.i16 \c0, \c0, \c1 + vsub.i16 d17, \c2, \c3 + vsub.i16 d16, \c0, d17 + vshr.s16 d16, d16, #1 + vsub.i16 \c2, d16, \c1 + vsub.i16 \c1, d16, \c3 + vadd.i16 \c3, d17, \c2 + vsub.i16 \c0, \c0, \c1 +.endm + +.macro idct4 c0, c1, c2, c3 + vmull.s16 q13, \c1, d0[2] + vmull.s16 q11, \c1, d0[1] + vadd.i16 d16, \c0, \c2 + vsub.i16 d17, \c0, \c2 + vmlal.s16 q13, \c3, d0[1] + vmull.s16 q9, d16, d0[0] + vmull.s16 q10, d17, d0[0] + vmlsl.s16 q11, \c3, d0[2] + vrshrn.s32 d26, q13, #14 + vrshrn.s32 d18, q9, #14 + vrshrn.s32 d20, q10, #14 + vrshrn.s32 d22, q11, #14 + vadd.i16 \c0, d18, d26 + vsub.i16 \c3, d18, d26 + vadd.i16 \c1, d20, d22 + vsub.i16 \c2, d20, d22 +.endm + +.macro iadst4 c0, c1, c2, c3 + vmull.s16 q10, \c0, d1[0] + vmlal.s16 q10, \c2, d1[1] + vmlal.s16 q10, \c3, d1[2] + vmull.s16 q11, \c0, d1[2] + vmlsl.s16 q11, \c2, d1[0] + vsub.s16 \c0, \c0, \c2 + vmlsl.s16 q11, \c3, d1[1] + vadd.s16 \c0, \c0, \c3 + vmull.s16 q13, \c1, d1[3] + vmull.s16 q12, \c0, d1[3] + vadd.s32 q14, q10, q13 + vadd.s32 q1, q11, q13 + vrshrn.s32 \c0, q14, #14 + vadd.s32 q10, q10, q11 + vrshrn.s32 \c1, q1, #14 + vsub.s32 q10, q10, q13 + vrshrn.s32 \c2, q12, #14 + vrshrn.s32 \c3, q10, #14 +.endm + +@ The public functions in this file have got the following signature: +@ void itxfm_add(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob); + +.macro itxfm_func4x4 txfm1, txfm2 +function ff_vp9_\txfm1\()_\txfm2\()_4x4_add_neon, export=1 +.ifc \txfm1,\txfm2 +.ifc \txfm1,idct + movrel r12, itxfm4_coeffs + vld1.16 {d0}, [r12,:64] +.endif +.ifc \txfm1,iadst + movrel r12, iadst4_coeffs + vld1.16 {d1}, [r12,:64] +.endif +.else + movrel r12, itxfm4_coeffs + vld1.16 {q0}, [r12,:128] +.endif + + vmov.i16 q15, #0 +.ifc \txfm1,idct +.ifc \txfm2,idct + cmp r3, #1 + bne 1f + @ DC-only for idct/idct + vld1.16 {d4[]}, [r2,:16] + vmull.s16 q2, d4, d0[0] + vrshrn.s32 d4, q2, #14 + vmull.s16 q2, d4, d0[0] + vrshrn.s32 d4, q2, #14 + vst1.16 {d30[0]}, [r2,:16] + vdup.16 q2, d4[0] + vmov q3, q2 + b 2f +.endif +.endif + +1: + vld1.16 {d4-d7}, [r2,:128] + vst1.16 {q15}, [r2,:128]! + +.ifc \txfm1,iwht + vshr.s16 q2, q2, #2 + vshr.s16 q3, q3, #2 +.endif + + \txfm1\()4 d4, d5, d6, d7 + + vst1.16 {q15}, [r2,:128]! + @ Transpose 4x4 with 16 bit elements + vtrn.16 d4, d5 + vtrn.16 d6, d7 + vtrn.32 q2, q3 + + \txfm2\()4 d4, d5, d6, d7 +2: + vld1.32 {d0[]}, [r0,:32], r1 + vld1.32 {d0[1]}, [r0,:32], r1 +.ifnc \txfm1,iwht + vrshr.s16 q2, q2, #4 + vrshr.s16 q3, q3, #4 +.endif + vaddw.u8 q2, q2, d0 + vld1.32 {d1[]}, [r0,:32], r1 + vld1.32 {d1[1]}, [r0,:32], r1 + vqmovun.s16 d0, q2 + sub r0, r0, r1, lsl #2 + + vaddw.u8 q3, q3, d1 + vst1.32 {d0[0]}, [r0,:32], r1 + vqmovun.s16 d1, q3 + + vst1.32 {d0[1]}, [r0,:32], r1 + vst1.32 {d1[0]}, [r0,:32], r1 + vst1.32 {d1[1]}, [r0,:32], r1 + + bx lr +endfunc +.endm + +itxfm_func4x4 idct, idct +itxfm_func4x4 iadst, idct +itxfm_func4x4 idct, iadst +itxfm_func4x4 iadst, iadst +itxfm_func4x4 iwht, iwht + + +.macro idct8 + dmbutterfly0 d16, d17, d24, d25, q8, q12, q2, q4, d4, d5, d8, d9, q3, q2, q5, q4 @ q8 = t0a, q12 = t1a + dmbutterfly d20, d21, d28, d29, d0[1], d0[2], q2, q3, q4, q5 @ q10 = t2a, q14 = t3a + dmbutterfly d18, d19, d30, d31, d0[3], d1[0], q2, q3, q4, q5 @ q9 = t4a, q15 = t7a + dmbutterfly d26, d27, d22, d23, d1[1], d1[2], q2, q3, q4, q5 @ q13 = t5a, q11 = t6a + + butterfly q2, q14, q8, q14 @ q2 = t0, q14 = t3 + butterfly q3, q10, q12, q10 @ q3 = t1, q10 = t2 + butterfly q4, q13, q9, q13 @ q4 = t4, q13 = t5a + butterfly q5, q11, q15, q11 @ q5 = t7, q11 = t6a + + butterfly q8, q15, q2, q5 @ q8 = out[0], q15 = out[7] + + dmbutterfly0 d4, d5, d10, d11, q11, q13, q9, q13, d18, d19, d26, d27, q2, q5, q11, q12 @ q2 = t6, q5 = t5 + + butterfly q11, q12, q14, q4 @ q11 = out[3], q12 = out[4] + butterfly q9, q14, q3, q2 @ q9 = out[1], q14 = out[6] + butterfly_r q13, q10, q10, q5 @ q13 = out[5], q10 = out[2] +.endm + +.macro iadst8 + dmbutterfly_l q4, q5, q2, q3, d30, d31, d16, d17, d2[1], d2[0] @ q4,q5 = t1a, q2,q3 = t0a + dmbutterfly_l q8, q15, q6, q7, d22, d23, d24, d25, d3[1], d3[0] @ q8,q15 = t5a, q6,q7 = t4a + + dbutterfly_n d22, d23, d4, d5, q2, q3, q6, q7, q11, q12, q2, q3 @ q11 = t0, q2 = t4 + + dbutterfly_n d24, d25, d6, d7, q4, q5, q8, q15, q12, q3, q6, q7 @ q12 = t1, q3 = t5 + + dmbutterfly_l q6, q7, q4, q5, d26, d27, d20, d21, d2[3], d2[2] @ q6,q7 = t3a, q4,q5 = t2a + dmbutterfly_l q10, q13, q8, q15, d18, d19, d28, d29, d3[3], d3[2] @ q10,q13 = t7a, q8,q15 = t6a + + dbutterfly_n d18, d19, d8, d9, q4, q5, q8, q15, q9, q14, q4, q5 @ q9 = t2, q4 = t6 + dbutterfly_n d16, d17, d12, d13, q6, q7, q10, q13, q8, q15, q6, q7 @ q8 = t3, q6 = t7 + + butterfly q15, q12, q12, q8 @ q15 = -out[7], q12 = t3 + vneg.s16 q15, q15 @ q15 = out[7] + butterfly q8, q9, q11, q9 @ q8 = out[0], q9 = t2 + + dmbutterfly_l q10, q11, q5, q7, d4, d5, d6, d7, d0[1], d0[2] @ q10,q11 = t5a, q5,q7 = t4a + dmbutterfly_l q2, q3, q13, q14, d12, d13, d8, d9, d0[2], d0[1] @ q2,q3 = t6a, q13,q14 = t7a + + dbutterfly_n d28, d29, d8, d9, q10, q11, q13, q14, q4, q6, q10, q11 @ q14 = out[6], q4 = t7 + + dmbutterfly0 d22, d23, d24, d25, q9, q12, q6, q13, d12, d13, d26, d27, q9, q10 @ q11 = -out[3], q12 = out[4] + vneg.s16 q11, q11 @ q11 = out[3] + + dbutterfly_n d18, d19, d4, d5, q5, q7, q2, q3, q9, q10, q2, q3 @ q9 = -out[1], q2 = t6 + vneg.s16 q9, q9 @ q9 = out[1] + + dmbutterfly0 d20, d21, d26, d27, q2, q4, q3, q5, d6, d7, d10, d11, q6, q7 @ q10 = out[2], q13 = -out[5] + vneg.s16 q13, q13 @ q13 = out[5] +.endm + + +.macro itxfm_func8x8 txfm1, txfm2 +function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_neon, export=1 + @ Push q4-q7 if iadst is used, idct requires + @ a few scratch registers less, so only push q4-q5 + @ if only idct is involved. + @ The iadst also uses a few coefficients from + @ idct, so those always need to be loaded. +.ifc \txfm1,iadst + movrel r12, iadst8_coeffs + vld1.16 {q1}, [r12,:128]! + vpush {q4-q7} + vld1.16 {q0}, [r12,:128] +.else +.ifc \txfm2,iadst + movrel r12, iadst8_coeffs + vld1.16 {q1}, [r12,:128]! + vpush {q4-q7} + vld1.16 {q0}, [r12,:128] +.else + movrel r12, idct_coeffs + vpush {q4-q5} + vld1.16 {q0}, [r12,:128] +.endif +.endif + + vmov.i16 q2, #0 + vmov.i16 q3, #0 + +.ifc \txfm1,idct +.ifc \txfm2,idct + cmp r3, #1 + bne 1f + @ DC-only for idct/idct + vld1.16 {d16[]}, [r2,:16] + vmull.s16 q8, d16, d0[0] + vrshrn.s32 d16, q8, #14 + vmull.s16 q8, d16, d0[0] + vrshrn.s32 d16, q8, #14 + vdup.16 q8, d16[0] + vmov q9, q8 + vmov q10, q8 + vmov q11, q8 + vmov q12, q8 + vmov q13, q8 + vmov q14, q8 + vmov q15, q8 + vst1.16 {d4[0]}, [r2,:16] + b 2f +.endif +.endif +1: + vld1.16 {q8-q9}, [r2,:128]! + vld1.16 {q10-q11}, [r2,:128]! + vld1.16 {q12-q13}, [r2,:128]! + vld1.16 {q14-q15}, [r2,:128]! + sub r2, r2, #128 + vst1.16 {q2-q3}, [r2,:128]! + vst1.16 {q2-q3}, [r2,:128]! + vst1.16 {q2-q3}, [r2,:128]! + vst1.16 {q2-q3}, [r2,:128]! + + \txfm1\()8 + + @ Transpose 8x8 with 16 bit elements + vswp d17, d24 + vswp d19, d26 + vswp d21, d28 + vswp d23, d30 + transpose16_4x4 q8, q9, q10, q11, q12, q13, q14, q15 + + \txfm2\()8 +2: + mov r3, r0 + @ Add into the destination + vld1.8 {d4}, [r0,:64], r1 + vrshr.s16 q8, q8, #5 + vld1.8 {d5}, [r0,:64], r1 + vrshr.s16 q9, q9, #5 + vld1.8 {d6}, [r0,:64], r1 + vrshr.s16 q10, q10, #5 + vaddw.u8 q8, q8, d4 + vld1.8 {d7}, [r0,:64], r1 + vrshr.s16 q11, q11, #5 + vaddw.u8 q9, q9, d5 + vld1.8 {d8}, [r0,:64], r1 + vrshr.s16 q12, q12, #5 + vaddw.u8 q10, q10, d6 + vqmovun.s16 d4, q8 + vld1.8 {d9}, [r0,:64], r1 + vrshr.s16 q13, q13, #5 + vaddw.u8 q11, q11, d7 + vqmovun.s16 d5, q9 + vld1.8 {d10}, [r0,:64], r1 + vrshr.s16 q14, q14, #5 + vaddw.u8 q12, q12, d8 + vqmovun.s16 d6, q10 + vld1.8 {d11}, [r0,:64], r1 + vrshr.s16 q15, q15, #5 + vaddw.u8 q13, q13, d9 + vqmovun.s16 d7, q11 + + + vst1.8 {d4}, [r3,:64], r1 + vaddw.u8 q14, q14, d10 + vst1.8 {d5}, [r3,:64], r1 + vqmovun.s16 d8, q12 + vst1.8 {d6}, [r3,:64], r1 + vaddw.u8 q15, q15, d11 + vst1.8 {d7}, [r3,:64], r1 + vqmovun.s16 d9, q13 + vst1.8 {d8}, [r3,:64], r1 + vqmovun.s16 d10, q14 + vst1.8 {d9}, [r3,:64], r1 + vqmovun.s16 d11, q15 + + vst1.8 {d10}, [r3,:64], r1 + vst1.8 {d11}, [r3,:64], r1 + +.ifc \txfm1,iadst + vpop {q4-q7} +.else +.ifc \txfm2,iadst + vpop {q4-q7} +.else + vpop {q4-q5} +.endif +.endif + bx lr +endfunc +.endm + +itxfm_func8x8 idct, idct +itxfm_func8x8 iadst, idct +.ltorg +itxfm_func8x8 idct, iadst +itxfm_func8x8 iadst, iadst + + +function idct16x16_dc_add_neon + movrel r12, idct_coeffs + vld1.16 {d0}, [r12,:64] + + vmov.i16 q2, #0 + + vld1.16 {d16[]}, [r2,:16] + vmull.s16 q8, d16, d0[0] + vrshrn.s32 d16, q8, #14 + vmull.s16 q8, d16, d0[0] + vrshrn.s32 d16, q8, #14 + vdup.16 q8, d16[0] + vst1.16 {d4[0]}, [r2,:16] + + vrshr.s16 q8, q8, #6 + + mov r12, #16 +1: + @ Loop to add the constant from q8 into all 16x16 outputs + vld1.8 {q3}, [r0,:128] + vaddw.u8 q10, q8, d6 + vaddw.u8 q11, q8, d7 + vqmovun.s16 d6, q10 + vqmovun.s16 d7, q11 + vst1.8 {q3}, [r0,:128], r1 + subs r12, r12, #1 + bne 1b + + bx lr +endfunc +.ltorg + +.macro idct16 + mbutterfly0 d16, d24, d16, d24, d4, d6, q2, q3 @ d16 = t0a, d24 = t1a + mbutterfly d20, d28, d0[1], d0[2], q2, q3 @ d20 = t2a, d28 = t3a + mbutterfly d18, d30, d0[3], d1[0], q2, q3 @ d18 = t4a, d30 = t7a + mbutterfly d26, d22, d1[1], d1[2], q2, q3 @ d26 = t5a, d22 = t6a + mbutterfly d17, d31, d1[3], d2[0], q2, q3 @ d17 = t8a, d31 = t15a + mbutterfly d25, d23, d2[1], d2[2], q2, q3 @ d25 = t9a, d23 = t14a + mbutterfly d21, d27, d2[3], d3[0], q2, q3 @ d21 = t10a, d27 = t13a + mbutterfly d29, d19, d3[1], d3[2], q2, q3 @ d29 = t11a, d19 = t12a + + butterfly d4, d28, d16, d28 @ d4 = t0, d28 = t3 + butterfly d5, d20, d24, d20 @ d5 = t1, d20 = t2 + butterfly d6, d26, d18, d26 @ d6 = t4, d26 = t5 + butterfly d7, d22, d30, d22 @ d7 = t7, d22 = t6 + butterfly d16, d25, d17, d25 @ d16 = t8, d25 = t9 + butterfly d24, d21, d29, d21 @ d24 = t11, d21 = t10 + butterfly d17, d27, d19, d27 @ d17 = t12, d27 = t13 + butterfly d29, d23, d31, d23 @ d29 = t15, d23 = t14 + + mbutterfly0 d22, d26, d22, d26, d18, d30, q9, q15 @ d22 = t6a, d26 = t5a + mbutterfly d23, d25, d0[1], d0[2], q9, q15 @ d23 = t9a, d25 = t14a + mbutterfly d27, d21, d0[1], d0[2], q9, q15, neg=1 @ d27 = t13a, d21 = t10a + + butterfly d18, d7, d4, d7 @ d18 = t0a, d7 = t7a + butterfly d19, d22, d5, d22 @ d19 = t1a, d22 = t6 + butterfly d4, d26, d20, d26 @ d4 = t2a, d26 = t5 + butterfly d5, d6, d28, d6 @ d5 = t3a, d6 = t4 + butterfly d20, d28, d16, d24 @ d20 = t8a, d28 = t11a + butterfly d24, d21, d23, d21 @ d24 = t9, d21 = t10 + butterfly d23, d27, d25, d27 @ d23 = t14, d27 = t13 + butterfly d25, d29, d29, d17 @ d25 = t15a, d29 = t12a + + mbutterfly0 d27, d21, d27, d21, d16, d30, q8, q15 @ d27 = t13a, d21 = t10a + mbutterfly0 d29, d28, d29, d28, d16, d30, q8, q15 @ d29 = t12, d28 = t11 + + vswp d27, d29 @ d27 = t12, d29 = t13a + vswp d28, d27 @ d28 = t12, d27 = t11 + butterfly d16, d31, d18, d25 @ d16 = out[0], d31 = out[15] + butterfly d17, d30, d19, d23 @ d17 = out[1], d30 = out[14] + butterfly_r d25, d22, d22, d24 @ d25 = out[9], d22 = out[6] + butterfly d23, d24, d7, d20 @ d23 = out[7], d24 = out[8] + butterfly d18, d29, d4, d29 @ d18 = out[2], d29 = out[13] + butterfly d19, d28, d5, d28 @ d19 = out[3], d28 = out[12] + vmov d4, d21 @ d4 = t10a + butterfly d20, d27, d6, d27 @ d20 = out[4], d27 = out[11] + butterfly d21, d26, d26, d4 @ d21 = out[5], d26 = out[10] +.endm + +.macro iadst16 + movrel r12, iadst16_coeffs + vld1.16 {q0-q1}, [r12,:128] + + mbutterfly_l q3, q2, d31, d16, d0[1], d0[0] @ q3 = t1, q2 = t0 + mbutterfly_l q5, q4, d23, d24, d2[1], d2[0] @ q5 = t9, q4 = t8 + butterfly_n d31, d24, q3, q5, q6, q5 @ d31 = t1a, d24 = t9a + mbutterfly_l q7, q6, d29, d18, d0[3], d0[2] @ q7 = t3, q6 = t2 + butterfly_n d16, d23, q2, q4, q3, q4 @ d16 = t0a, d23 = t8a + + mbutterfly_l q3, q2, d21, d26, d2[3], d2[2] @ q3 = t11, q2 = t10 + butterfly_n d29, d26, q7, q3, q4, q3 @ d29 = t3a, d26 = t11a + mbutterfly_l q5, q4, d27, d20, d1[1], d1[0] @ q5 = t5, q4 = t4 + butterfly_n d18, d21, q6, q2, q3, q2 @ d18 = t2a, d21 = t10a + + mbutterfly_l q7, q6, d19, d28, d3[1], d3[0] @ q7 = t13, q6 = t12 + butterfly_n d20, d28, q5, q7, q2, q7 @ d20 = t5a, d28 = t13a + mbutterfly_l q3, q2, d25, d22, d1[3], d1[2] @ q3 = t7, q2 = t6 + butterfly_n d27, d19, q4, q6, q5, q6 @ d27 = t4a, d19 = t12a + + mbutterfly_l q5, q4, d17, d30, d3[3], d3[2] @ q5 = t15, q4 = t14 + movrel r12, idct_coeffs + vld1.16 {q0}, [r12,:128] + butterfly_n d22, d30, q3, q5, q6, q5 @ d22 = t7a, d30 = t15a + mbutterfly_l q7, q6, d23, d24, d0[3], d1[0] @ q7 = t9, q6 = t8 + butterfly_n d25, d17, q2, q4, q3, q4 @ d25 = t6a, d17 = t14a + + mbutterfly_l q2, q3, d28, d19, d1[0], d0[3] @ q2 = t12, q3 = t13 + butterfly_n d23, d19, q6, q2, q4, q2 @ d23 = t8a, d19 = t12a + mbutterfly_l q5, q4, d21, d26, d1[1], d1[2] @ q5 = t11, q4 = t10 + butterfly_r d4, d27, d16, d27 @ d4 = t4, d27 = t0 + butterfly_n d24, d28, q7, q3, q6, q3 @ d24 = t9a, d28 = t13a + + mbutterfly_l q6, q7, d30, d17, d1[2], d1[1] @ q6 = t14, q7 = t15 + butterfly_r d5, d20, d31, d20 @ d5 = t5, d20 = t1 + butterfly_n d21, d17, q4, q6, q3, q6 @ d21 = t10a, d17 = t14a + butterfly_n d26, d30, q5, q7, q4, q7 @ d26 = t11a, d30 = t15a + + butterfly_r d6, d25, d18, d25 @ d6 = t6, d25 = t2 + butterfly_r d7, d22, d29, d22 @ d7 = t7, d22 = t3 + + mbutterfly_l q5, q4, d19, d28, d0[1], d0[2] @ q5 = t13, q4 = t12 + mbutterfly_l q6, q7, d30, d17, d0[2], d0[1] @ q6 = t14, q7 = t15 + + butterfly_n d18, d30, q4, q6, q8, q6 @ d18 = out[2], d30 = t14a + butterfly_n d29, d17, q5, q7, q6, q7 @ d29 = -out[13], d17 = t15a + vneg.s16 d29, d29 @ d29 = out[13] + + mbutterfly_l q5, q4, d4, d5, d0[1], d0[2] @ q5 = t5a, q4 = t4a + mbutterfly_l q6, q7, d7, d6, d0[2], d0[1] @ q6 = t6a, q7 = t7a + + butterfly d2, d6, d27, d25 @ d2 = out[0], d6 = t2a + butterfly d3, d7, d23, d21 @ d3 =-out[1], d7 = t10 + + butterfly_n d19, d31, q4, q6, q2, q4 @ d19 = -out[3], d31 = t6 + vneg.s16 d19, d19 @ d19 = out[3] + butterfly_n d28, d16, q5, q7, q2, q5 @ d28 = out[12], d16 = t7 + + butterfly d5, d8, d20, d22 @ d5 =-out[15],d8 = t3a + butterfly d4, d9, d24, d26 @ d4 = out[14],d9 = t11 + + mbutterfly0 d23, d24, d6, d8, d10, d11, q6, q7, 1 @ d23 = out[7], d24 = out[8] + mbutterfly0 d20, d27, d16, d31, d10, d11, q6, q7 @ d20 = out[4], d27 = out[11] + mbutterfly0 d22, d25, d9, d7, d10, d11, q6, q7 @ d22 = out[6], d25 = out[9] + mbutterfly0 d21, d26, d30, d17, d10, d11, q6, q7, 1 @ d21 = out[5], d26 = out[10] + + vneg.s16 d31, d5 @ d31 = out[15] + vneg.s16 d17, d3 @ d17 = out[1] + + vmov d16, d2 + vmov d30, d4 +.endm + +.macro itxfm16_1d_funcs txfm +@ Read a vertical 4x16 slice out of a 16x16 matrix, do a transform on it, +@ transpose into a horizontal 16x4 slice and store. +@ r0 = dst (temp buffer) +@ r1 = unused +@ r2 = src +@ r3 = slice offset +function \txfm\()16_1d_4x16_pass1_neon + mov r12, #32 + vmov.s16 q2, #0 +.irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 + vld1.16 {d\i}, [r2,:64] + vst1.16 {d4}, [r2,:64], r12 +.endr + + \txfm\()16 + + @ Do four 4x4 transposes. Originally, d16-d31 contain the + @ 16 rows. Afterwards, d16-d19, d20-d23, d24-d27, d28-d31 + @ contain the transposed 4x4 blocks. + transpose16_q_4x_4x4 q8, q9, q10, q11, q12, q13, q14, q15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31 + + @ Store the transposed 4x4 blocks horizontally. + cmp r3, #12 + beq 1f +.irp i, 16, 20, 24, 28, 17, 21, 25, 29, 18, 22, 26, 30, 19, 23, 27, 31 + vst1.16 {d\i}, [r0,:64]! +.endr + bx lr +1: + @ Special case: For the last input column (r3 == 12), + @ which would be stored as the last row in the temp buffer, + @ don't store the first 4x4 block, but keep it in registers + @ for the first slice of the second pass (where it is the + @ last 4x4 block). + add r0, r0, #8 +.irp i, 20, 24, 28 + vst1.16 {d\i}, [r0,:64]! +.endr + add r0, r0, #8 +.irp i, 21, 25, 29 + vst1.16 {d\i}, [r0,:64]! +.endr + add r0, r0, #8 +.irp i, 22, 26, 30 + vst1.16 {d\i}, [r0,:64]! +.endr + add r0, r0, #8 +.irp i, 23, 27, 31 + vst1.16 {d\i}, [r0,:64]! +.endr + vmov d28, d16 + vmov d29, d17 + vmov d30, d18 + vmov d31, d19 + bx lr +endfunc + +@ Read a vertical 4x16 slice out of a 16x16 matrix, do a transform on it, +@ load the destination pixels (from a similar 4x16 slice), add and store back. +@ r0 = dst +@ r1 = dst stride +@ r2 = src (temp buffer) +@ r3 = slice offset +function \txfm\()16_1d_4x16_pass2_neon + mov r12, #32 +.irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 + vld1.16 {d\i}, [r2,:64], r12 +.endr + cmp r3, #0 + beq 1f +.irp i, 28, 29, 30, 31 + vld1.16 {d\i}, [r2,:64], r12 +.endr +1: + + add r3, r0, r1 + lsl r1, r1, #1 + \txfm\()16 + +.macro load_add_store coef0, coef1, coef2, coef3 + vrshr.s16 \coef0, \coef0, #6 + vrshr.s16 \coef1, \coef1, #6 + + vld1.32 {d4[]}, [r0,:32], r1 + vld1.32 {d4[1]}, [r3,:32], r1 + vrshr.s16 \coef2, \coef2, #6 + vrshr.s16 \coef3, \coef3, #6 + vld1.32 {d5[]}, [r0,:32], r1 + vld1.32 {d5[1]}, [r3,:32], r1 + vaddw.u8 \coef0, \coef0, d4 + vld1.32 {d6[]}, [r0,:32], r1 + vld1.32 {d6[1]}, [r3,:32], r1 + vaddw.u8 \coef1, \coef1, d5 + vld1.32 {d7[]}, [r0,:32], r1 + vld1.32 {d7[1]}, [r3,:32], r1 + + vqmovun.s16 d4, \coef0 + vqmovun.s16 d5, \coef1 + sub r0, r0, r1, lsl #2 + sub r3, r3, r1, lsl #2 + vaddw.u8 \coef2, \coef2, d6 + vaddw.u8 \coef3, \coef3, d7 + vst1.32 {d4[0]}, [r0,:32], r1 + vst1.32 {d4[1]}, [r3,:32], r1 + vqmovun.s16 d6, \coef2 + vst1.32 {d5[0]}, [r0,:32], r1 + vst1.32 {d5[1]}, [r3,:32], r1 + vqmovun.s16 d7, \coef3 + + vst1.32 {d6[0]}, [r0,:32], r1 + vst1.32 {d6[1]}, [r3,:32], r1 + vst1.32 {d7[0]}, [r0,:32], r1 + vst1.32 {d7[1]}, [r3,:32], r1 +.endm + load_add_store q8, q9, q10, q11 + load_add_store q12, q13, q14, q15 +.purgem load_add_store + + bx lr +endfunc +.endm + +itxfm16_1d_funcs idct +itxfm16_1d_funcs iadst + +.macro itxfm_func16x16 txfm1, txfm2 +function ff_vp9_\txfm1\()_\txfm2\()_16x16_add_neon, export=1 +.ifc \txfm1,idct +.ifc \txfm2,idct + cmp r3, #1 + beq idct16x16_dc_add_neon +.endif +.endif + push {r4-r7,lr} +.ifc \txfm1,iadst + vpush {q4-q7} +.else +.ifc \txfm2,iadst + vpush {q4-q7} +.endif +.endif + mov r7, sp + + @ Align the stack, allocate a temp buffer +T mov r12, sp +T bic r12, r12, #15 +T sub r12, r12, #512 +T mov sp, r12 +A bic sp, sp, #15 +A sub sp, sp, #512 + + mov r4, r0 + mov r5, r1 + mov r6, r2 + +.ifc \txfm1,idct + movrel r12, idct_coeffs + vld1.16 {q0-q1}, [r12,:128] +.endif + +.irp i, 0, 4, 8, 12 + add r0, sp, #(\i*32) + add r2, r6, #(\i*2) + mov r3, #\i + bl \txfm1\()16_1d_4x16_pass1_neon +.endr +.ifc \txfm2,idct + movrel r12, idct_coeffs + vld1.16 {q0-q1}, [r12,:128] +.endif +.irp i, 0, 4, 8, 12 + add r0, r4, #(\i) + mov r1, r5 + add r2, sp, #(\i*2) + mov r3, #\i + bl \txfm2\()16_1d_4x16_pass2_neon +.endr + + mov sp, r7 +.ifc \txfm1,iadst + vpop {q4-q7} +.else +.ifc \txfm2,iadst + vpop {q4-q7} +.endif +.endif + pop {r4-r7,pc} +endfunc +.endm + +itxfm_func16x16 idct, idct +itxfm_func16x16 iadst, idct +itxfm_func16x16 idct, iadst +itxfm_func16x16 iadst, iadst +.ltorg + + +function idct32x32_dc_add_neon + movrel r12, idct_coeffs + vld1.16 {d0}, [r12,:64] + + vmov.i16 q2, #0 + + vld1.16 {d16[]}, [r2,:16] + vmull.s16 q8, d16, d0[0] + vrshrn.s32 d16, q8, #14 + vmull.s16 q8, d16, d0[0] + vrshrn.s32 d16, q8, #14 + vdup.16 q8, d16[0] + vst1.16 {d4[0]}, [r2,:16] + + vrshr.s16 q8, q8, #6 + + mov r12, #32 +1: + @ Loop to add the constant from q8 into all 32x32 outputs + vld1.8 {q2-q3}, [r0,:128] + vaddw.u8 q10, q8, d4 + vaddw.u8 q11, q8, d5 + vaddw.u8 q12, q8, d6 + vaddw.u8 q13, q8, d7 + vqmovun.s16 d4, q10 + vqmovun.s16 d5, q11 + vqmovun.s16 d6, q12 + vqmovun.s16 d7, q13 + vst1.8 {q2-q3}, [r0,:128], r1 + subs r12, r12, #1 + bne 1b + + bx lr +endfunc + +.macro idct32_odd + movrel r12, idct_coeffs + add r12, r12, #32 + vld1.16 {q0-q1}, [r12,:128] + + mbutterfly d16, d31, d0[0], d0[1], q2, q3 @ d16 = t16a, d31 = t31a + mbutterfly d24, d23, d0[2], d0[3], q2, q3 @ d24 = t17a, d23 = t30a + mbutterfly d20, d27, d1[0], d1[1], q2, q3 @ d20 = t18a, d27 = t29a + mbutterfly d28, d19, d1[2], d1[3], q2, q3 @ d28 = t19a, d19 = t28a + mbutterfly d18, d29, d2[0], d2[1], q2, q3 @ d18 = t20a, d29 = t27a + mbutterfly d26, d21, d2[2], d2[3], q2, q3 @ d26 = t21a, d21 = t26a + mbutterfly d22, d25, d3[0], d3[1], q2, q3 @ d22 = t22a, d25 = t25a + mbutterfly d30, d17, d3[2], d3[3], q2, q3 @ d30 = t23a, d17 = t24a + + sub r12, r12, #32 + vld1.16 {q0}, [r12,:128] + + butterfly d4, d24, d16, d24 @ d4 = t16, d24 = t17 + butterfly d5, d20, d28, d20 @ d5 = t19, d20 = t18 + butterfly d6, d26, d18, d26 @ d6 = t20, d26 = t21 + butterfly d7, d22, d30, d22 @ d7 = t23, d22 = t22 + butterfly d28, d25, d17, d25 @ d28 = t24, d25 = t25 + butterfly d30, d21, d29, d21 @ d30 = t27, d21 = t26 + butterfly d29, d23, d31, d23 @ d29 = t31, d23 = t30 + butterfly d31, d27, d19, d27 @ d31 = t28, d27 = t29 + + mbutterfly d23, d24, d0[3], d1[0], q8, q9 @ d23 = t17a, d24 = t30a + mbutterfly d27, d20, d0[3], d1[0], q8, q9, neg=1 @ d27 = t29a, d20 = t18a + mbutterfly d21, d26, d1[1], d1[2], q8, q9 @ d21 = t21a, d26 = t26a + mbutterfly d25, d22, d1[1], d1[2], q8, q9, neg=1 @ d25 = t25a, d22 = t22a + + butterfly d16, d5, d4, d5 @ d16 = t16a, d5 = t19a + butterfly d17, d20, d23, d20 @ d17 = t17, d20 = t18 + butterfly d18, d6, d7, d6 @ d18 = t23a, d6 = t20a + butterfly d19, d21, d22, d21 @ d19 = t22, d21 = t21 + butterfly d4, d28, d28, d30 @ d4 = t24a, d28 = t27a + butterfly d23, d26, d25, d26 @ d23 = t25, d26 = t26 + butterfly d7, d29, d29, d31 @ d7 = t31a, d29 = t28a + butterfly d22, d27, d24, d27 @ d22 = t30, d27 = t29 + + mbutterfly d27, d20, d0[1], d0[2], q12, q15 @ d27 = t18a, d20 = t29a + mbutterfly d29, d5, d0[1], d0[2], q12, q15 @ d29 = t19, d5 = t28 + mbutterfly d28, d6, d0[1], d0[2], q12, q15, neg=1 @ d28 = t27, d6 = t20 + mbutterfly d26, d21, d0[1], d0[2], q12, q15, neg=1 @ d26 = t26a, d21 = t21a + + butterfly d31, d24, d7, d4 @ d31 = t31, d24 = t24 + butterfly d30, d25, d22, d23 @ d30 = t30a, d25 = t25a + butterfly_r d23, d16, d16, d18 @ d23 = t23, d16 = t16 + butterfly_r d22, d17, d17, d19 @ d22 = t22a, d17 = t17a + butterfly d18, d21, d27, d21 @ d18 = t18, d21 = t21 + butterfly_r d27, d28, d5, d28 @ d27 = t27a, d28 = t28a + butterfly d4, d26, d20, d26 @ d4 = t29, d26 = t26 + butterfly d19, d20, d29, d6 @ d19 = t19a, d20 = t20 + vmov d29, d4 @ d29 = t29 + + mbutterfly0 d27, d20, d27, d20, d4, d6, q2, q3 @ d27 = t27, d20 = t20 + mbutterfly0 d26, d21, d26, d21, d4, d6, q2, q3 @ d26 = t26a, d21 = t21a + mbutterfly0 d25, d22, d25, d22, d4, d6, q2, q3 @ d25 = t25, d22 = t22 + mbutterfly0 d24, d23, d24, d23, d4, d6, q2, q3 @ d24 = t24a, d23 = t23a +.endm + +@ Do an 32-point IDCT of a 4x32 slice out of a 32x32 matrix. +@ We don't have register space to do a single pass IDCT of 4x32 though, +@ but the 32-point IDCT can be decomposed into two 16-point IDCTs; +@ a normal IDCT16 with every other input component (the even ones, with +@ each output written twice), followed by a separate 16-point IDCT +@ of the odd inputs, added/subtracted onto the outputs of the first idct16. +@ r0 = dst (temp buffer) +@ r1 = unused +@ r2 = src +function idct32_1d_4x32_pass1_neon + movrel r12, idct_coeffs + vld1.16 {q0-q1}, [r12,:128] + + @ Double stride of the input, since we only read every other line + mov r12, #128 + vmov.s16 d4, #0 + + @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30) +.irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 + vld1.16 {d\i}, [r2,:64] + vst1.16 {d4}, [r2,:64], r12 +.endr + + idct16 + + @ Do four 4x4 transposes. Originally, d16-d31 contain the + @ 16 rows. Afterwards, d16-d19, d20-d23, d24-d27, d28-d31 + @ contain the transposed 4x4 blocks. + transpose16_q_4x_4x4 q8, q9, q10, q11, q12, q13, q14, q15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31 + @ Store the registers a, b, c, d horizontally, followed + @ by the same registers d, c, b, a mirrored. +.macro store_rev a, b, c, d +.irp i, \a, \b, \c, \d + vst1.16 {d\i}, [r0,:64]! + vrev64.16 d\i, d\i +.endr +.irp i, \d, \c, \b, \a + vst1.16 {d\i}, [r0,:64]! +.endr +.endm + store_rev 16, 20, 24, 28 + store_rev 17, 21, 25, 29 + store_rev 18, 22, 26, 30 + store_rev 19, 23, 27, 31 + sub r0, r0, #256 +.purgem store_rev + + @ Move r2 back to the start of the input, and move + @ to the first odd row + sub r2, r2, r12, lsl #4 + add r2, r2, #64 + + vmov.s16 d4, #0 + @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31) +.irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 + vld1.16 {d\i}, [r2,:64] + vst1.16 {d4}, [r2,:64], r12 +.endr + + idct32_odd + + transpose16_q_4x_4x4 q15, q14, q13, q12, q11, q10, q9, q8, d31, d30, d29, d28, d27, d26, d25, d24, d23, d22, d21, d20, d19, d18, d17, d16 + + @ Store the registers a, b, c, d horizontally, + @ adding into the output first, and then mirrored, subtracted + @ from the output. +.macro store_rev a, b, c, d +.irp i, \a, \b, \c, \d + vld1.16 {d4}, [r0,:64] + vadd.s16 d4, d4, d\i + vst1.16 {d4}, [r0,:64]! + vrev64.16 d\i, d\i +.endr +.irp i, \d, \c, \b, \a + vld1.16 {d4}, [r0,:64] + vsub.s16 d4, d4, d\i + vst1.16 {d4}, [r0,:64]! +.endr +.endm + + store_rev 31, 27, 23, 19 + store_rev 30, 26, 22, 18 + store_rev 29, 25, 21, 17 + store_rev 28, 24, 20, 16 +.purgem store_rev + bx lr +endfunc +.ltorg + +@ This is mostly the same as 4x32_pass1, but without the transpose, +@ and use the source as temp buffer between the two idct passes, and +@ add into the destination. +@ r0 = dst +@ r1 = dst stride +@ r2 = src (temp buffer) +function idct32_1d_4x32_pass2_neon + movrel r12, idct_coeffs + vld1.16 {q0-q1}, [r12,:128] + + mov r12, #128 + @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30) +.irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 + vld1.16 {d\i}, [r2,:64], r12 +.endr + sub r2, r2, r12, lsl #4 + + idct16 + +.irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 + vst1.16 {d\i}, [r2,:64], r12 +.endr + + sub r2, r2, r12, lsl #4 + add r2, r2, #64 + + @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31) +.irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 + vld1.16 {d\i}, [r2,:64], r12 +.endr + sub r2, r2, r12, lsl #4 + sub r2, r2, #64 + + idct32_odd + + mov r12, #128 +.macro load_acc_store a, b, c, d, neg=0 + vld1.16 {d4}, [r2,:64], r12 + vld1.16 {d5}, [r2,:64], r12 +.if \neg == 0 + vadd.s16 d4, d4, d\a + vld1.16 {d6}, [r2,:64], r12 + vadd.s16 d5, d5, d\b + vld1.16 {d7}, [r2,:64], r12 + vadd.s16 d6, d6, d\c + vadd.s16 d7, d7, d\d +.else + vsub.s16 d4, d4, d\a + vld1.16 {d6}, [r2,:64], r12 + vsub.s16 d5, d5, d\b + vld1.16 {d7}, [r2,:64], r12 + vsub.s16 d6, d6, d\c + vsub.s16 d7, d7, d\d +.endif + vld1.32 {d2[]}, [r0,:32], r1 + vld1.32 {d2[1]}, [r0,:32], r1 + vrshr.s16 q2, q2, #6 + vld1.32 {d3[]}, [r0,:32], r1 + vrshr.s16 q3, q3, #6 + vld1.32 {d3[1]}, [r0,:32], r1 + sub r0, r0, r1, lsl #2 + vaddw.u8 q2, q2, d2 + vaddw.u8 q3, q3, d3 + vqmovun.s16 d4, q2 + vqmovun.s16 d5, q3 + vst1.32 {d4[0]}, [r0,:32], r1 + vst1.32 {d4[1]}, [r0,:32], r1 + vst1.32 {d5[0]}, [r0,:32], r1 + vst1.32 {d5[1]}, [r0,:32], r1 +.endm + load_acc_store 31, 30, 29, 28 + load_acc_store 27, 26, 25, 24 + load_acc_store 23, 22, 21, 20 + load_acc_store 19, 18, 17, 16 + sub r2, r2, r12 + neg r12, r12 + load_acc_store 16, 17, 18, 19, 1 + load_acc_store 20, 21, 22, 23, 1 + load_acc_store 24, 25, 26, 27, 1 + load_acc_store 28, 29, 30, 31, 1 +.purgem load_acc_store + bx lr +endfunc + +function ff_vp9_idct_idct_32x32_add_neon, export=1 + cmp r3, #1 + beq idct32x32_dc_add_neon + push {r4-r7,lr} + vpush {q4-q7} + mov r7, sp + + @ Align the stack, allocate a temp buffer +T mov r12, sp +T bic r12, r12, #15 +T sub r12, r12, #2048 +T mov sp, r12 +A bic sp, sp, #15 +A sub sp, sp, #2048 + + mov r4, r0 + mov r5, r1 + mov r6, r2 + +.irp i, 0, 4, 8, 12, 16, 20, 24, 28 + add r0, sp, #(\i*64) + add r2, r6, #(\i*2) + bl idct32_1d_4x32_pass1_neon +.endr +.irp i, 0, 4, 8, 12, 16, 20, 24, 28 + add r0, r4, #(\i) + mov r1, r5 + add r2, sp, #(\i*2) + bl idct32_1d_4x32_pass2_neon +.endr + + mov sp, r7 + vpop {q4-q7} + pop {r4-r7,pc} +endfunc From 12db2832e41aa71b5903ef7fa5c59c5473ded2c5 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 12 Feb 2015 10:11:22 +0100 Subject: [PATCH 0451/3374] libxvid: Require availability of mkstemp() The replacement code uses tempnam(), which is dangerous. Such a fringe feature is not worth the trouble. --- configure | 2 +- libavcodec/libxvid_rc.c | 17 ++--------------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/configure b/configure index acc74f2a6d689..7ced8fa341d34 100755 --- a/configure +++ b/configure @@ -2290,7 +2290,7 @@ libx262_encoder_deps="libx262" libx264_encoder_deps="libx264" libx265_encoder_deps="libx265" libxavs_encoder_deps="libxavs" -libxvid_encoder_deps="libxvid" +libxvid_encoder_deps="libxvid mkstemp" # demuxers / muxers ac3_demuxer_select="ac3_parser" diff --git a/libavcodec/libxvid_rc.c b/libavcodec/libxvid_rc.c index 26f3c495c1dde..91302832e02fd 100644 --- a/libavcodec/libxvid_rc.c +++ b/libavcodec/libxvid_rc.c @@ -22,9 +22,7 @@ #include "config.h" -#if !HAVE_MKSTEMP #include -#endif #include #include @@ -35,36 +33,25 @@ #include "libxvid.h" #include "mpegvideo.h" -/* Wrapper to work around the lack of mkstemp() on mingw. - * Also, tries to create file in /tmp first, if possible. +/* Create temporary file using mkstemp(), tries /tmp first, if possible. * *prefix can be a character constant; *filename will be allocated internally. - * @return file descriptor of opened file (or -1 on error) + * Return file descriptor of opened file (or error code on error) * and opened file name in **filename. */ int ff_tempfile(const char *prefix, char **filename) { int fd = -1; -#if !HAVE_MKSTEMP - *filename = tempnam(".", prefix); -#else size_t len = strlen(prefix) + 12; /* room for "/tmp/" and "XXXXXX\0" */ *filename = av_malloc(len); -#endif - /* -----common section-----*/ if (!(*filename)) { av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot allocate file name\n"); return AVERROR(ENOMEM); } -#if !HAVE_MKSTEMP - fd = avpriv_open(*filename, O_RDWR | O_BINARY | O_CREAT, 0444); -#else snprintf(*filename, len, "/tmp/%sXXXXXX", prefix); fd = mkstemp(*filename); if (fd < 0) { snprintf(*filename, len, "./%sXXXXXX", prefix); fd = mkstemp(*filename); } -#endif - /* -----common section-----*/ if (fd < 0) { av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot open temporary file %s\n", *filename); return AVERROR(EIO); From e5e8a26dcf6d572e841a7a191e4c96524367e3f9 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 8 Dec 2015 10:21:27 +0100 Subject: [PATCH 0452/3374] libxvid: Use proper context in av_log() calls --- libavcodec/libxvid_rc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/libxvid_rc.c b/libavcodec/libxvid_rc.c index 91302832e02fd..eddbbe8c65140 100644 --- a/libavcodec/libxvid_rc.c +++ b/libavcodec/libxvid_rc.c @@ -68,7 +68,7 @@ av_cold int ff_xvid_rate_control_init(MpegEncContext *s) fd = ff_tempfile("xvidrc.", &tmp_name); if (fd < 0) { - av_log(NULL, AV_LOG_ERROR, "Can't create temporary pass2 file.\n"); + av_log(s, AV_LOG_ERROR, "Cannot create temporary pass2 file.\n"); return fd; } @@ -106,7 +106,7 @@ av_cold int ff_xvid_rate_control_init(MpegEncContext *s) if (xvid_plugin_2pass2(NULL, XVID_PLG_CREATE, &xvid_plg_create, &s->rc_context.non_lavc_opaque) < 0) { - av_log(NULL, AV_LOG_ERROR, "xvid_plugin_2pass2 failed\n"); + av_log(s, AV_LOG_ERROR, "xvid_plugin_2pass2 failed\n"); return -1; } return 0; @@ -141,7 +141,7 @@ float ff_xvid_rate_estimate_qscale(MpegEncContext *s, int dry_run) xvid_plg_data.type = s->last_pict_type; if (xvid_plugin_2pass2(s->rc_context.non_lavc_opaque, XVID_PLG_AFTER, &xvid_plg_data, NULL)) { - av_log(s->avctx, AV_LOG_ERROR, + av_log(s, AV_LOG_ERROR, "xvid_plugin_2pass2(handle, XVID_PLG_AFTER, ...) FAILED\n"); return -1; } @@ -151,7 +151,7 @@ float ff_xvid_rate_estimate_qscale(MpegEncContext *s, int dry_run) xvid_plg_data.quant = 0; if (xvid_plugin_2pass2(s->rc_context.non_lavc_opaque, XVID_PLG_BEFORE, &xvid_plg_data, NULL)) { - av_log(s->avctx, AV_LOG_ERROR, + av_log(s, AV_LOG_ERROR, "xvid_plugin_2pass2(handle, XVID_PLG_BEFORE, ...) FAILED\n"); return -1; } From f7d183f08472e566a2e6b62a80e200a12670ed0e Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 8 Dec 2015 10:22:15 +0100 Subject: [PATCH 0453/3374] libxvid: Check return value of write() call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit libavcodec/libxvid_rc.c:106:9: warning: ignoring return value of ‘write’, declared with attribute warn_unused_result [-Wunused-result] --- libavcodec/libxvid_rc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/libxvid_rc.c b/libavcodec/libxvid_rc.c index eddbbe8c65140..94301a2ac1ffc 100644 --- a/libavcodec/libxvid_rc.c +++ b/libavcodec/libxvid_rc.c @@ -87,7 +87,10 @@ av_cold int ff_xvid_rate_control_init(MpegEncContext *s) (rce->i_tex_bits + rce->p_tex_bits + rce->misc_bits + 7) / 8, (rce->header_bits + rce->mv_bits + 7) / 8); - write(fd, tmp, strlen(tmp)); + if (strlen(tmp) > write(fd, tmp, strlen(tmp))) { + av_log(s, AV_LOG_ERROR, "Cannot write to temporary pass2 file.\n"); + return AVERROR(EIO); + } } close(fd); From dd299a2d6d4d1af9528ed35a8131c35946be5973 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 10 Oct 2016 09:48:03 +0300 Subject: [PATCH 0454/3374] arm: vp9: Add NEON loop filters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. The implementation tries to have smart handling of cases where no pixels need the full filtering for the 8/16 width filters, skipping both calculation and writeback of the unmodified pixels in those cases. The actual effect of this is hard to test with checkasm though, since it tests the full filtering, and the benefit depends on how many filtered blocks use the shortcut. Examples of relative speedup compared to the C version, from checkasm: Cortex A7 A8 A9 A53 vp9_loop_filter_h_4_8_neon: 2.72 2.68 1.78 3.15 vp9_loop_filter_h_8_8_neon: 2.36 2.38 1.70 2.91 vp9_loop_filter_h_16_8_neon: 1.80 1.89 1.45 2.01 vp9_loop_filter_h_16_16_neon: 2.81 2.78 2.18 3.16 vp9_loop_filter_mix2_h_44_16_neon: 2.65 2.67 1.93 3.05 vp9_loop_filter_mix2_h_48_16_neon: 2.46 2.38 1.81 2.85 vp9_loop_filter_mix2_h_84_16_neon: 2.50 2.41 1.73 2.85 vp9_loop_filter_mix2_h_88_16_neon: 2.77 2.66 1.96 3.23 vp9_loop_filter_mix2_v_44_16_neon: 4.28 4.46 3.22 5.70 vp9_loop_filter_mix2_v_48_16_neon: 3.92 4.00 3.03 5.19 vp9_loop_filter_mix2_v_84_16_neon: 3.97 4.31 2.98 5.33 vp9_loop_filter_mix2_v_88_16_neon: 3.91 4.19 3.06 5.18 vp9_loop_filter_v_4_8_neon: 4.53 4.47 3.31 6.05 vp9_loop_filter_v_8_8_neon: 3.58 3.99 2.92 5.17 vp9_loop_filter_v_16_8_neon: 3.40 3.50 2.81 4.68 vp9_loop_filter_v_16_16_neon: 4.66 4.41 3.74 6.02 The speedup vs C code is around 2-6x. The numbers are quite inconclusive though, since the checkasm test runs multiple filterings on top of each other, so later rounds might end up with different codepaths (different decisions on which filter to apply, based on input pixel differences). Disabling the early-exit in the asm doesn't give a fair comparison either though, since the C code only does the necessary calcuations for each row. Based on START_TIMER/STOP_TIMER wrapping around a few individual functions, the speedup vs C code is around 4-9x. This is pretty similar in runtime to the corresponding routines in libvpx. (This is comparing vpx_lpf_vertical_16_neon, vpx_lpf_horizontal_edge_8_neon and vpx_lpf_horizontal_edge_16_neon to vp9_loop_filter_h_16_8_neon, vp9_loop_filter_v_16_8_neon and vp9_loop_filter_v_16_16_neon - note that the naming of horizonal and vertical is flipped between the libraries.) In order to have stable, comparable numbers, the early exits in both asm versions were disabled, forcing the full filtering codepath. Cortex A7 A8 A9 A53 vp9_loop_filter_h_16_8_neon: 597.2 472.0 482.4 415.0 libvpx vpx_lpf_vertical_16_neon: 626.0 464.5 470.7 445.0 vp9_loop_filter_v_16_8_neon: 500.2 422.5 429.7 295.0 libvpx vpx_lpf_horizontal_edge_8_neon: 586.5 414.5 415.6 383.2 vp9_loop_filter_v_16_16_neon: 905.0 784.7 791.5 546.0 libvpx vpx_lpf_horizontal_edge_16_neon: 1060.2 751.7 743.5 685.2 Our version is consistently faster on on A7 and A53, marginally slower on A8, and sometimes faster, sometimes slower on A9 (marginally slower in all three tests in this particular test run). Signed-off-by: Martin Storsjö --- libavcodec/arm/Makefile | 1 + libavcodec/arm/vp9dsp_init_arm.c | 57 +++ libavcodec/arm/vp9lpf_neon.S | 770 +++++++++++++++++++++++++++++++ 3 files changed, 828 insertions(+) create mode 100644 libavcodec/arm/vp9lpf_neon.S diff --git a/libavcodec/arm/Makefile b/libavcodec/arm/Makefile index 01630ac07a347..77452b126dd15 100644 --- a/libavcodec/arm/Makefile +++ b/libavcodec/arm/Makefile @@ -140,4 +140,5 @@ NEON-OBJS-$(CONFIG_RV40_DECODER) += arm/rv34dsp_neon.o \ NEON-OBJS-$(CONFIG_VORBIS_DECODER) += arm/vorbisdsp_neon.o NEON-OBJS-$(CONFIG_VP6_DECODER) += arm/vp6dsp_neon.o NEON-OBJS-$(CONFIG_VP9_DECODER) += arm/vp9itxfm_neon.o \ + arm/vp9lpf_neon.o \ arm/vp9mc_neon.o diff --git a/libavcodec/arm/vp9dsp_init_arm.c b/libavcodec/arm/vp9dsp_init_arm.c index f05d51d044f00..e99d931674376 100644 --- a/libavcodec/arm/vp9dsp_init_arm.c +++ b/libavcodec/arm/vp9dsp_init_arm.c @@ -182,8 +182,65 @@ static av_cold void vp9dsp_itxfm_init_arm(VP9DSPContext *dsp) } } +#define define_loop_filter(dir, wd, size) \ +void ff_vp9_loop_filter_##dir##_##wd##_##size##_neon(uint8_t *dst, ptrdiff_t stride, int E, int I, int H) + +#define define_loop_filters(wd, size) \ + define_loop_filter(h, wd, size); \ + define_loop_filter(v, wd, size) + +define_loop_filters(4, 8); +define_loop_filters(8, 8); +define_loop_filters(16, 8); +define_loop_filters(16, 16); + +#define lf_mix_fn(dir, wd1, wd2, stridea) \ +static void loop_filter_##dir##_##wd1##wd2##_16_neon(uint8_t *dst, \ + ptrdiff_t stride, \ + int E, int I, int H) \ +{ \ + ff_vp9_loop_filter_##dir##_##wd1##_8_neon(dst, stride, E & 0xff, I & 0xff, H & 0xff); \ + ff_vp9_loop_filter_##dir##_##wd2##_8_neon(dst + 8 * stridea, stride, E >> 8, I >> 8, H >> 8); \ +} + +#define lf_mix_fns(wd1, wd2) \ + lf_mix_fn(h, wd1, wd2, stride) \ + lf_mix_fn(v, wd1, wd2, sizeof(uint8_t)) + +lf_mix_fns(4, 4) +lf_mix_fns(4, 8) +lf_mix_fns(8, 4) +lf_mix_fns(8, 8) + +static av_cold void vp9dsp_loopfilter_init_arm(VP9DSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) { + dsp->loop_filter_8[0][1] = ff_vp9_loop_filter_v_4_8_neon; + dsp->loop_filter_8[0][0] = ff_vp9_loop_filter_h_4_8_neon; + dsp->loop_filter_8[1][1] = ff_vp9_loop_filter_v_8_8_neon; + dsp->loop_filter_8[1][0] = ff_vp9_loop_filter_h_8_8_neon; + dsp->loop_filter_8[2][1] = ff_vp9_loop_filter_v_16_8_neon; + dsp->loop_filter_8[2][0] = ff_vp9_loop_filter_h_16_8_neon; + + dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_neon; + dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_neon; + + dsp->loop_filter_mix2[0][0][0] = loop_filter_h_44_16_neon; + dsp->loop_filter_mix2[0][0][1] = loop_filter_v_44_16_neon; + dsp->loop_filter_mix2[0][1][0] = loop_filter_h_48_16_neon; + dsp->loop_filter_mix2[0][1][1] = loop_filter_v_48_16_neon; + dsp->loop_filter_mix2[1][0][0] = loop_filter_h_84_16_neon; + dsp->loop_filter_mix2[1][0][1] = loop_filter_v_84_16_neon; + dsp->loop_filter_mix2[1][1][0] = loop_filter_h_88_16_neon; + dsp->loop_filter_mix2[1][1][1] = loop_filter_v_88_16_neon; + } +} + av_cold void ff_vp9dsp_init_arm(VP9DSPContext *dsp) { vp9dsp_mc_init_arm(dsp); + vp9dsp_loopfilter_init_arm(dsp); vp9dsp_itxfm_init_arm(dsp); } diff --git a/libavcodec/arm/vp9lpf_neon.S b/libavcodec/arm/vp9lpf_neon.S new file mode 100644 index 0000000000000..fbf2901f75052 --- /dev/null +++ b/libavcodec/arm/vp9lpf_neon.S @@ -0,0 +1,770 @@ +/* + * Copyright (c) 2016 Google Inc. + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/arm/asm.S" +#include "neon.S" + +@ Do an 8x8 transpose, using q registers for the subtransposes that don't +@ need to address the indiviudal d registers. +@ r0,r1 == rq0, r2,r3 == rq1, etc +.macro transpose_q_8x8 rq0, rq1, rq2, rq3, r0, r1, r2, r3, r4, r5, r6, r7 + vtrn.32 \rq0, \rq2 + vtrn.32 \rq1, \rq3 + vtrn.16 \rq0, \rq1 + vtrn.16 \rq2, \rq3 + vtrn.8 \r0, \r1 + vtrn.8 \r2, \r3 + vtrn.8 \r4, \r5 + vtrn.8 \r6, \r7 +.endm + +@ Do a 4x4 transpose, using q registers for the subtransposes that don't +@ need to address the indiviudal d registers. +@ r0,r1 == rq0, r2,r3 == rq1 +.macro transpose_q_4x4 rq0, rq1, r0, r1, r2, r3 + vtrn.16 \rq0, \rq1 + vtrn.8 \r0, \r1 + vtrn.8 \r2, \r3 +.endm + +@ The input to and output from this macro is in the registers d16-d31, +@ and d0-d7 are used as scratch registers. +@ p7 = d16 .. p3 = d20, p0 = d23, q0 = d24, q3 = d27, q7 = d31 +@ Depending on the width of the loop filter, we either use d16-d19 +@ and d28-d31 as temp registers, or d8-d15. +@ tmp1,tmp2 = tmpq1, tmp3,tmp4 = tmpq2, tmp5,tmp6 = tmpq3, tmp7,tmp8 = tmpq4 +.macro loop_filter wd, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmpq1, tmpq2, tmpq3, tmpq4 + vdup.u16 q0, r2 @ E + vdup.u8 d2, r3 @ I + ldr r3, [sp] + + vabd.u8 d4, d20, d21 @ abs(p3 - p2) + vabd.u8 d5, d21, d22 @ abs(p2 - p1) + vabd.u8 d6, d22, d23 @ abs(p1 - p0) + vabd.u8 d7, d24, d25 @ abs(q0 - q1) + vabd.u8 \tmp1, d25, d26 @ abs(q1 - q2) + vabd.u8 \tmp2, d26, d27 @ abs(q2 - q3) + vmax.u8 d4, d4, d5 + vmax.u8 d5, d6, d7 + vmax.u8 \tmp1, \tmp1, \tmp2 + vabdl.u8 q3, d23, d24 @ abs(p0 - q0) + vmax.u8 d4, d4, d5 + vadd.u16 q3, q3, q3 @ abs(p0 - q0) * 2 + vabd.u8 d5, d22, d25 @ abs(p1 - q1) + vmax.u8 d4, d4, \tmp1 @ max(abs(p3 - p2), ..., abs(q2 - q3)) + vshr.u8 d5, d5, #1 + vcle.u8 d4, d4, d2 @ max(abs()) <= I + vaddw.u8 q3, q3, d5 @ abs(p0 - q0) * 2 + abs(p1 - q1) >> 1 + vcle.u16 q3, q3, q0 + vmovn.u16 d5, q3 + vand d4, d4, d5 @ fm + + vdup.u8 d3, r3 @ H + vmov r2, r3, d4 + orr r2, r2, r3 + cmp r2, #0 + @ If no pixels need filtering, just exit as soon as possible + beq 9f + +.if \wd >= 8 + vmov.u8 d0, #1 + + vabd.u8 d6, d20, d23 @ abs(p3 - p0) + vabd.u8 d2, d21, d23 @ abs(p2 - p0) + vabd.u8 d1, d22, d23 @ abs(p1 - p0) + vabd.u8 \tmp1, d25, d24 @ abs(q1 - q0) + vabd.u8 \tmp2, d26, d24 @ abs(q2 - q0) + vabd.u8 \tmp3, d27, d24 @ abs(q3 - q0) + vmax.u8 d6, d6, d2 + vmax.u8 d1, d1, \tmp1 + vmax.u8 \tmp2, \tmp2, \tmp3 +.if \wd == 16 + vabd.u8 d7, d16, d23 @ abs(p7 - p0) + vmax.u8 d6, d6, d1 + vabd.u8 d2, d17, d23 @ abs(p6 - p0) + vmax.u8 d6, d6, \tmp2 + vabd.u8 d1, d18, d23 @ abs(p5 - p0) + vcle.u8 d6, d6, d0 @ flat8in + vabd.u8 d8, d19, d23 @ abs(p4 - p0) + vand d6, d6, d4 @ flat8in && fm + vabd.u8 d9, d28, d24 @ abs(q4 - q0) + vbic d4, d4, d6 @ fm && !flat8in + vabd.u8 d10, d29, d24 @ abs(q5 - q0) + vabd.u8 d11, d30, d24 @ abs(q6 - q0) + vabd.u8 d12, d31, d24 @ abs(q7 - q0) + + vmax.u8 d7, d7, d2 + vmax.u8 d1, d1, d8 + vmax.u8 d9, d9, d10 + vmax.u8 d11, d11, d12 + @ The rest of the calculation of flat8out is interleaved below +.else + @ The rest of the calculation of flat8in is interleaved below +.endif +.endif + + @ Calculate the normal inner loop filter for 2 or 4 pixels + vabd.u8 d5, d22, d23 @ abs(p1 - p0) +.if \wd == 16 + vmax.u8 d7, d7, d1 + vmax.u8 d9, d9, d11 +.elseif \wd == 8 + vmax.u8 d6, d6, d1 +.endif + vabd.u8 d1, d25, d24 @ abs(q1 - q0) +.if \wd == 16 + vmax.u8 d7, d7, d9 +.elseif \wd == 8 + vmax.u8 d6, d6, \tmp2 +.endif + vsubl.u8 \tmpq1, d22, d25 @ p1 - q1 + vmax.u8 d5, d5, d1 @ max(abs(p1 - p0), abs(q1 - q0)) + vsubl.u8 \tmpq2, d24, d23 @ q0 - p0 + vmov.s16 \tmpq3, #3 +.if \wd == 8 + vcle.u8 d6, d6, d0 @ flat8in +.endif + vcgt.u8 d5, d5, d3 @ hev +.if \wd == 8 + vand d6, d6, d4 @ flat8in && fm +.endif + vqmovn.s16 \tmp1, \tmpq1 @ av_clip_int8(p1 - q1) +.if \wd == 16 + vcle.u8 d7, d7, d0 @ flat8out +.elseif \wd == 8 + vbic d4, d4, d6 @ fm && !flat8in +.endif + vmvn d5, d5 @ !hev +.if \wd == 16 + vand d7, d7, d6 @ flat8out && flat8in && fm +.endif + vand d5, d5, d4 @ !hev && fm && !flat8in + + vmul.s16 \tmpq2, \tmpq2, \tmpq3 @ 3 * (q0 - p0) + vbic \tmp1, \tmp1, d5 @ if (!hev) av_clip_int8 = 0 + vmov.s8 d2, #4 + vaddw.s8 \tmpq2, \tmpq2, \tmp1 @ 3 * (q0 - p0) [+ av_clip_int8(p1 - q1)] + vmov.s8 d3, #3 + vqmovn.s16 \tmp1, \tmpq2 @ f +.if \wd == 16 + vbic d6, d6, d7 @ fm && flat8in && !flat8out +.endif + + vqadd.s8 \tmp3, \tmp1, d2 @ FFMIN(f + 4, 127) + vqadd.s8 \tmp4, \tmp1, d3 @ FFMIN(f + 3, 127) + vmovl.u8 q0, d23 @ p0 + vshr.s8 \tmp3, \tmp3, #3 @ f1 + vshr.s8 \tmp4, \tmp4, #3 @ f2 + + vmovl.u8 q1, d24 @ q0 + vaddw.s8 q0, q0, \tmp4 @ p0 + f2 + vsubw.s8 q1, q1, \tmp3 @ q0 - f1 + vqmovun.s16 d0, q0 @ out p0 + vqmovun.s16 d1, q1 @ out q0 + vrshr.s8 \tmp3, \tmp3, #1 @ f = (f1 + 1) >> 1 + vbit d23, d0, d4 @ if (fm && !flat8in) + vbit d24, d1, d4 + + vmovl.u8 q0, d22 @ p1 + vmovl.u8 q1, d25 @ q1 + vaddw.s8 q0, q0, \tmp3 @ p1 + f + vsubw.s8 q1, q1, \tmp3 @ q1 - f + vqmovun.s16 d0, q0 @ out p1 + vqmovun.s16 d2, q1 @ out q1 + vbit d22, d0, d5 @ if (!hev && fm && !flat8in) + vbit d25, d2, d5 + +.if \wd >= 8 + vmov r2, r3, d6 + orr r2, r2, r3 + cmp r2, #0 + @ If no pixels need flat8in, jump to flat8out + @ (or to a writeout of the inner 4 pixels, for wd=8) + beq 6f + + @ flat8in + vaddl.u8 \tmpq1, d20, d21 + vaddl.u8 \tmpq2, d22, d25 + vaddl.u8 \tmpq3, d20, d22 + vaddl.u8 \tmpq4, d23, d26 + vadd.u16 q0, \tmpq1, \tmpq1 + vaddw.u8 q0, q0, d23 + vaddw.u8 q0, q0, d24 + vadd.u16 q0, q0, \tmpq3 + vsub.s16 \tmpq2, \tmpq2, \tmpq1 + vsub.s16 \tmpq4, \tmpq4, \tmpq3 + vrshrn.u16 d2, q0, #3 @ out p2 + + vadd.u16 q0, q0, \tmpq2 + vaddl.u8 \tmpq1, d20, d23 + vaddl.u8 \tmpq2, d24, d27 + vrshrn.u16 d3, q0, #3 @ out p1 + + vadd.u16 q0, q0, \tmpq4 + vsub.s16 \tmpq2, \tmpq2, \tmpq1 + vaddl.u8 \tmpq3, d21, d24 + vaddl.u8 \tmpq4, d25, d27 + vrshrn.u16 d4, q0, #3 @ out p0 + + vadd.u16 q0, q0, \tmpq2 + vsub.s16 \tmpq4, \tmpq4, \tmpq3 + vaddl.u8 \tmpq1, d22, d25 + vaddl.u8 \tmpq2, d26, d27 + vrshrn.u16 d5, q0, #3 @ out q0 + + vadd.u16 q0, q0, \tmpq4 + vsub.s16 \tmpq2, \tmpq2, \tmpq1 + vrshrn.u16 \tmp5, q0, #3 @ out q1 + + vadd.u16 q0, q0, \tmpq2 + @ The output here is written back into the input registers. This doesn't + @ matter for the flat8out part below, since we only update those pixels + @ which won't be touched below. + vbit d21, d2, d6 + vbit d22, d3, d6 + vbit d23, d4, d6 + vrshrn.u16 \tmp6, q0, #3 @ out q2 + vbit d24, d5, d6 + vbit d25, \tmp5, d6 + vbit d26, \tmp6, d6 +.endif +.if \wd == 16 +6: + vorr d2, d6, d7 + vmov r2, r3, d2 + orr r2, r2, r3 + cmp r2, #0 + @ If no pixels needed flat8in nor flat8out, jump to a + @ writeout of the inner 4 pixels + beq 7f + vmov r2, r3, d7 + orr r2, r2, r3 + cmp r2, #0 + @ If no pixels need flat8out, jump to a writeout of the inner 6 pixels + beq 8f + + @ flat8out + @ This writes all outputs into d2-d17 (skipping d6 and d16). + @ If this part is skipped, the output is read from d21-d26 (which is the input + @ to this section). + vshll.u8 q0, d16, #3 @ 8 * d16 + vsubw.u8 q0, q0, d16 @ 7 * d16 + vaddw.u8 q0, q0, d17 + vaddl.u8 q4, d17, d18 + vaddl.u8 q5, d19, d20 + vadd.s16 q0, q0, q4 + vaddl.u8 q4, d16, d17 + vaddl.u8 q6, d21, d22 + vadd.s16 q0, q0, q5 + vaddl.u8 q5, d18, d25 + vaddl.u8 q7, d23, d24 + vsub.s16 q5, q5, q4 + vadd.s16 q0, q0, q6 + vadd.s16 q0, q0, q7 + vaddl.u8 q6, d16, d18 + vaddl.u8 q7, d19, d26 + vrshrn.u16 d2, q0, #4 + + vadd.s16 q0, q0, q5 + vaddl.u8 q4, d16, d19 + vaddl.u8 q5, d20, d27 + vsub.s16 q7, q7, q6 + vbif d2, d17, d7 + vrshrn.u16 d3, q0, #4 + + vadd.s16 q0, q0, q7 + vaddl.u8 q6, d16, d20 + vaddl.u8 q7, d21, d28 + vsub.s16 q5, q5, q4 + vbif d3, d18, d7 + vrshrn.u16 d4, q0, #4 + + vadd.s16 q0, q0, q5 + vaddl.u8 q4, d16, d21 + vaddl.u8 q5, d22, d29 + vsub.s16 q7, q7, q6 + vbif d4, d19, d7 + vrshrn.u16 d5, q0, #4 + + vadd.s16 q0, q0, q7 + vaddl.u8 q6, d16, d22 + vaddl.u8 q7, d23, d30 + vsub.s16 q5, q5, q4 + vbif d5, d20, d7 + vrshrn.u16 d6, q0, #4 + + vadd.s16 q0, q0, q5 + vaddl.u8 q5, d16, d23 + vsub.s16 q7, q7, q6 + vaddl.u8 q6, d24, d31 + vbif d6, d21, d7 + vrshrn.u16 d8, q0, #4 + + vadd.s16 q0, q0, q7 + vsub.s16 q5, q6, q5 + vaddl.u8 q6, d17, d24 + vaddl.u8 q7, d25, d31 + vbif d8, d22, d7 + vrshrn.u16 d9, q0, #4 + + vadd.s16 q0, q0, q5 + vsub.s16 q7, q7, q6 + vaddl.u8 q6, d26, d31 + vbif d9, d23, d7 + vrshrn.u16 d10, q0, #4 + + vadd.s16 q0, q0, q7 + vaddl.u8 q7, d18, d25 + vaddl.u8 q9, d19, d26 + vsub.s16 q6, q6, q7 + vaddl.u8 q7, d27, d31 + vbif d10, d24, d7 + vrshrn.u16 d11, q0, #4 + + vadd.s16 q0, q0, q6 + vaddl.u8 q6, d20, d27 + vsub.s16 q7, q7, q9 + vaddl.u8 q9, d28, d31 + vbif d11, d25, d7 + vsub.s16 q9, q9, q6 + vrshrn.u16 d12, q0, #4 + + vadd.s16 q0, q0, q7 + vaddl.u8 q7, d21, d28 + vaddl.u8 q10, d29, d31 + vbif d12, d26, d7 + vrshrn.u16 d13, q0, #4 + + vadd.s16 q0, q0, q9 + vsub.s16 q10, q10, q7 + vaddl.u8 q9, d22, d29 + vaddl.u8 q11, d30, d31 + vbif d13, d27, d7 + vrshrn.u16 d14, q0, #4 + + vadd.s16 q0, q0, q10 + vsub.s16 q11, q11, q9 + vbif d14, d28, d7 + vrshrn.u16 d15, q0, #4 + + vadd.s16 q0, q0, q11 + vbif d15, d29, d7 + vrshrn.u16 d17, q0, #4 + vbif d17, d30, d7 +.endif +.endm + +@ For wd <= 8, we use d16-d19 and d28-d31 for temp registers, +@ while we need those for inputs/outputs in wd=16 and use d8-d15 +@ for temp registers there instead. +.macro loop_filter_4 + loop_filter 4, d16, d17, d18, d19, d28, d29, d30, d31, q8, q9, q14, q15 +.endm + +.macro loop_filter_8 + loop_filter 8, d16, d17, d18, d19, d28, d29, d30, d31, q8, q9, q14, q15 +.endm + +.macro loop_filter_16 + loop_filter 16, d8, d9, d10, d11, d12, d13, d14, d15, q4, q5, q6, q7 +.endm + + +@ The public functions in this file have got the following signature: +@ void loop_filter(uint8_t *dst, ptrdiff_t stride, int mb_lim, int lim, int hev_thr); + +function ff_vp9_loop_filter_v_4_8_neon, export=1 + sub r12, r0, r1, lsl #2 + vld1.8 {d20}, [r12,:64], r1 @ p3 + vld1.8 {d24}, [r0, :64], r1 @ q0 + vld1.8 {d21}, [r12,:64], r1 @ p2 + vld1.8 {d25}, [r0, :64], r1 @ q1 + vld1.8 {d22}, [r12,:64], r1 @ p1 + vld1.8 {d26}, [r0, :64], r1 @ q2 + vld1.8 {d23}, [r12,:64], r1 @ p0 + vld1.8 {d27}, [r0, :64], r1 @ q3 + sub r0, r0, r1, lsl #2 + sub r12, r12, r1, lsl #1 + + loop_filter_4 + + vst1.8 {d22}, [r12,:64], r1 + vst1.8 {d24}, [r0, :64], r1 + vst1.8 {d23}, [r12,:64], r1 + vst1.8 {d25}, [r0, :64], r1 +9: + bx lr +endfunc + +function ff_vp9_loop_filter_h_4_8_neon, export=1 + sub r12, r0, #4 + add r0, r12, r1, lsl #2 + vld1.8 {d20}, [r12], r1 + vld1.8 {d24}, [r0], r1 + vld1.8 {d21}, [r12], r1 + vld1.8 {d25}, [r0], r1 + vld1.8 {d22}, [r12], r1 + vld1.8 {d26}, [r0], r1 + vld1.8 {d23}, [r12], r1 + vld1.8 {d27}, [r0], r1 + + sub r12, r12, r1, lsl #2 + sub r0, r0, r1, lsl #2 + @ Move r0/r12 forward by 2 pixels; we don't need to rewrite the + @ outermost 2 pixels since they aren't changed. + add r12, r12, #2 + add r0, r0, #2 + + @ Transpose the 8x8 pixels, taking advantage of q registers, to get + @ one register per column. + transpose_q_8x8 q10, q11, q12, q13, d20, d21, d22, d23, d24, d25, d26, d27 + + loop_filter_4 + + @ We only will write the mid 4 pixels back; after the loop filter, + @ these are in d22, d23, d24, d25 (q11, q12), ordered as rows + @ (8x4 pixels). We need to transpose them to columns, done with a + @ 4x4 transpose (which in practice is two 4x4 transposes of the two + @ 4x4 halves of the 8x4 pixels; into 4x8 pixels). + transpose_q_4x4 q11, q12, d22, d23, d24, d25 + + vst1.32 {d22[0]}, [r12], r1 + vst1.32 {d22[1]}, [r0], r1 + vst1.32 {d23[0]}, [r12], r1 + vst1.32 {d23[1]}, [r0], r1 + vst1.32 {d24[0]}, [r12], r1 + vst1.32 {d24[1]}, [r0], r1 + vst1.32 {d25[0]}, [r12], r1 + vst1.32 {d25[1]}, [r0], r1 +9: + bx lr +endfunc + +function ff_vp9_loop_filter_v_8_8_neon, export=1 + sub r12, r0, r1, lsl #2 + vld1.8 {d20}, [r12,:64], r1 @ p3 + vld1.8 {d24}, [r0, :64], r1 @ q0 + vld1.8 {d21}, [r12,:64], r1 @ p2 + vld1.8 {d25}, [r0, :64], r1 @ q1 + vld1.8 {d22}, [r12,:64], r1 @ p1 + vld1.8 {d26}, [r0, :64], r1 @ q2 + vld1.8 {d23}, [r12,:64], r1 @ p0 + vld1.8 {d27}, [r0, :64], r1 @ q3 + sub r12, r12, r1, lsl #2 + sub r0, r0, r1, lsl #2 + add r12, r12, r1 + + loop_filter_8 + + vst1.8 {d21}, [r12,:64], r1 + vst1.8 {d24}, [r0, :64], r1 + vst1.8 {d22}, [r12,:64], r1 + vst1.8 {d25}, [r0, :64], r1 + vst1.8 {d23}, [r12,:64], r1 + vst1.8 {d26}, [r0, :64], r1 +9: + bx lr +6: + sub r12, r0, r1, lsl #1 + vst1.8 {d22}, [r12,:64], r1 + vst1.8 {d24}, [r0, :64], r1 + vst1.8 {d23}, [r12,:64], r1 + vst1.8 {d25}, [r0, :64], r1 + bx lr +endfunc + +function ff_vp9_loop_filter_h_8_8_neon, export=1 + sub r12, r0, #4 + add r0, r12, r1, lsl #2 + vld1.8 {d20}, [r12], r1 + vld1.8 {d24}, [r0], r1 + vld1.8 {d21}, [r12], r1 + vld1.8 {d25}, [r0], r1 + vld1.8 {d22}, [r12], r1 + vld1.8 {d26}, [r0], r1 + vld1.8 {d23}, [r12], r1 + vld1.8 {d27}, [r0], r1 + + sub r12, r12, r1, lsl #2 + sub r0, r0, r1, lsl #2 + + transpose_q_8x8 q10, q11, q12, q13, d20, d21, d22, d23, d24, d25, d26, d27 + + loop_filter_8 + + @ Even though only 6 pixels per row have been changed, we write the + @ full 8 pixel registers. + transpose_q_8x8 q10, q11, q12, q13, d20, d21, d22, d23, d24, d25, d26, d27 + + vst1.8 {d20}, [r12], r1 + vst1.8 {d24}, [r0], r1 + vst1.8 {d21}, [r12], r1 + vst1.8 {d25}, [r0], r1 + vst1.8 {d22}, [r12], r1 + vst1.8 {d26}, [r0], r1 + vst1.8 {d23}, [r12], r1 + vst1.8 {d27}, [r0], r1 +9: + bx lr +6: + @ If we didn't need to do the flat8in part, we use the same writeback + @ as in loop_filter_h_4_8. + add r12, r12, #2 + add r0, r0, #2 + transpose_q_4x4 q11, q12, d22, d23, d24, d25 + vst1.32 {d22[0]}, [r12], r1 + vst1.32 {d22[1]}, [r0], r1 + vst1.32 {d23[0]}, [r12], r1 + vst1.32 {d23[1]}, [r0], r1 + vst1.32 {d24[0]}, [r12], r1 + vst1.32 {d24[1]}, [r0], r1 + vst1.32 {d25[0]}, [r12], r1 + vst1.32 {d25[1]}, [r0], r1 + bx lr +endfunc + +function vp9_loop_filter_v_16_neon + sub r12, r0, r1, lsl #3 + @ Read p7-p0 using r12 and q0-q7 using r0 + vld1.8 {d16}, [r12,:64], r1 @ p7 + vld1.8 {d24}, [r0, :64], r1 @ q0 + vld1.8 {d17}, [r12,:64], r1 @ p6 + vld1.8 {d25}, [r0, :64], r1 @ q1 + vld1.8 {d18}, [r12,:64], r1 @ p5 + vld1.8 {d26}, [r0, :64], r1 @ q2 + vld1.8 {d19}, [r12,:64], r1 @ p4 + vld1.8 {d27}, [r0, :64], r1 @ q3 + vld1.8 {d20}, [r12,:64], r1 @ p3 + vld1.8 {d28}, [r0, :64], r1 @ q4 + vld1.8 {d21}, [r12,:64], r1 @ p2 + vld1.8 {d29}, [r0, :64], r1 @ q5 + vld1.8 {d22}, [r12,:64], r1 @ p1 + vld1.8 {d30}, [r0, :64], r1 @ q6 + vld1.8 {d23}, [r12,:64], r1 @ p0 + vld1.8 {d31}, [r0, :64], r1 @ q7 + sub r12, r12, r1, lsl #3 + sub r0, r0, r1, lsl #3 + add r12, r12, r1 + + loop_filter_16 + + @ If we did the flat8out part, we get the output in + @ d2-d17 (skipping d7 and d16). r12 points to r0 - 7 * stride, + @ store d2-d9 there, and d10-d17 into r0. + vst1.8 {d2}, [r12,:64], r1 + vst1.8 {d10}, [r0, :64], r1 + vst1.8 {d3}, [r12,:64], r1 + vst1.8 {d11}, [r0, :64], r1 + vst1.8 {d4}, [r12,:64], r1 + vst1.8 {d12}, [r0, :64], r1 + vst1.8 {d5}, [r12,:64], r1 + vst1.8 {d13}, [r0, :64], r1 + vst1.8 {d6}, [r12,:64], r1 + vst1.8 {d14}, [r0, :64], r1 + vst1.8 {d8}, [r12,:64], r1 + vst1.8 {d15}, [r0, :64], r1 + vst1.8 {d9}, [r12,:64], r1 + vst1.8 {d17}, [r0, :64], r1 + sub r0, r0, r1, lsl #3 + add r0, r0, r1 + +9: + bx lr + +8: + add r12, r12, r1, lsl #2 + @ If we didn't do the flat8out part, the output is left in the + @ input registers. + vst1.8 {d21}, [r12,:64], r1 + vst1.8 {d24}, [r0, :64], r1 + vst1.8 {d22}, [r12,:64], r1 + vst1.8 {d25}, [r0, :64], r1 + vst1.8 {d23}, [r12,:64], r1 + vst1.8 {d26}, [r0, :64], r1 + sub r0, r0, r1, lsl #1 + sub r0, r0, r1 + bx lr +7: + sub r12, r0, r1, lsl #1 + vst1.8 {d22}, [r12,:64], r1 + vst1.8 {d24}, [r0, :64], r1 + vst1.8 {d23}, [r12,:64], r1 + vst1.8 {d25}, [r0, :64], r1 + sub r0, r0, r1, lsl #1 + bx lr +endfunc + +function ff_vp9_loop_filter_v_16_8_neon, export=1 + ldr r12, [sp] + push {lr} + vpush {q4-q7} + push {r12} + bl vp9_loop_filter_v_16_neon + add sp, sp, #4 + vpop {q4-q7} + pop {pc} +endfunc + +function ff_vp9_loop_filter_v_16_16_neon, export=1 + ldr r12, [sp] + // The filter clobbers r2 and r3, but we need to keep them for the second round + push {r2, r3, lr} + vpush {q4-q7} + push {r12} + bl vp9_loop_filter_v_16_neon + add r0, #8 + ldr r2, [sp, #68] + ldr r3, [sp, #72] + bl vp9_loop_filter_v_16_neon + add sp, sp, #4 + vpop {q4-q7} + pop {r2, r3, pc} +endfunc + +function vp9_loop_filter_h_16_neon + sub r12, r0, #8 + vld1.8 {d16}, [r12,:64], r1 + vld1.8 {d24}, [r0, :64], r1 + vld1.8 {d17}, [r12,:64], r1 + vld1.8 {d25}, [r0, :64], r1 + vld1.8 {d18}, [r12,:64], r1 + vld1.8 {d26}, [r0, :64], r1 + vld1.8 {d19}, [r12,:64], r1 + vld1.8 {d27}, [r0, :64], r1 + vld1.8 {d20}, [r12,:64], r1 + vld1.8 {d28}, [r0, :64], r1 + vld1.8 {d21}, [r12,:64], r1 + vld1.8 {d29}, [r0, :64], r1 + vld1.8 {d22}, [r12,:64], r1 + vld1.8 {d30}, [r0, :64], r1 + vld1.8 {d23}, [r12,:64], r1 + vld1.8 {d31}, [r0, :64], r1 + sub r0, r0, r1, lsl #3 + sub r12, r12, r1, lsl #3 + + @ The 16x8 pixels read above is in two 8x8 blocks; the left + @ half in d16-d23, and the right half in d24-d31. Do two 8x8 transposes + @ of this, to get one column per register. This could be done with two + @ transpose_8x8 as below, but this takes advantage of the q registers. + transpose16_4x4 q8, q9, q10, q11, q12, q13, q14, q15 + vtrn.8 d16, d17 + vtrn.8 d18, d19 + vtrn.8 d20, d21 + vtrn.8 d22, d23 + vtrn.8 d24, d25 + vtrn.8 d26, d27 + vtrn.8 d28, d29 + vtrn.8 d30, d31 + + loop_filter_16 + + @ Transpose back; this is the same transpose as above, but + @ we can't take advantage of q registers for the transpose, since + @ all d registers in the transpose aren't consecutive. + transpose_8x8 d16, d2, d3, d4, d5, d6, d8, d9 + transpose_8x8 d10, d11, d12, d13, d14, d15, d17, d31 + + vst1.8 {d16}, [r12,:64], r1 + vst1.8 {d10}, [r0, :64], r1 + + vst1.8 {d2}, [r12,:64], r1 + vst1.8 {d11}, [r0, :64], r1 + + vst1.8 {d3}, [r12,:64], r1 + vst1.8 {d12}, [r0, :64], r1 + + vst1.8 {d4}, [r12,:64], r1 + vst1.8 {d13}, [r0, :64], r1 + + vst1.8 {d5}, [r12,:64], r1 + vst1.8 {d14}, [r0, :64], r1 + + vst1.8 {d6}, [r12,:64], r1 + vst1.8 {d15}, [r0, :64], r1 + + vst1.8 {d8}, [r12,:64], r1 + vst1.8 {d17}, [r0, :64], r1 + + vst1.8 {d9}, [r12,:64], r1 + vst1.8 {d31}, [r0, :64], r1 + sub r0, r0, r1, lsl #3 +9: + bx lr +8: + @ The same writeback as in loop_filter_h_8_8 + sub r12, r0, #4 + add r0, r12, r1, lsl #2 + transpose_q_8x8 q10, q11, q12, q13, d20, d21, d22, d23, d24, d25, d26, d27 + + vst1.8 {d20}, [r12], r1 + vst1.8 {d24}, [r0], r1 + vst1.8 {d21}, [r12], r1 + vst1.8 {d25}, [r0], r1 + vst1.8 {d22}, [r12], r1 + vst1.8 {d26}, [r0], r1 + vst1.8 {d23}, [r12], r1 + vst1.8 {d27}, [r0], r1 + sub r0, r0, r1, lsl #3 + add r0, r0, #4 + bx lr +7: + @ The same writeback as in loop_filter_h_4_8 + sub r12, r0, #2 + add r0, r12, r1, lsl #2 + transpose_q_4x4 q11, q12, d22, d23, d24, d25 + vst1.32 {d22[0]}, [r12], r1 + vst1.32 {d22[1]}, [r0], r1 + vst1.32 {d23[0]}, [r12], r1 + vst1.32 {d23[1]}, [r0], r1 + vst1.32 {d24[0]}, [r12], r1 + vst1.32 {d24[1]}, [r0], r1 + vst1.32 {d25[0]}, [r12], r1 + vst1.32 {d25[1]}, [r0], r1 + sub r0, r0, r1, lsl #3 + add r0, r0, #2 + bx lr +endfunc + +function ff_vp9_loop_filter_h_16_8_neon, export=1 + ldr r12, [sp] + push {lr} + vpush {q4-q7} + push {r12} + bl vp9_loop_filter_h_16_neon + add sp, sp, #4 + vpop {q4-q7} + pop {pc} +endfunc + +function ff_vp9_loop_filter_h_16_16_neon, export=1 + ldr r12, [sp] + // The filter clobbers r2 and r3, but we need to keep them for the second round + push {r2, r3, lr} + vpush {q4-q7} + push {r12} + bl vp9_loop_filter_h_16_neon + add r0, r0, r1, lsl #3 + ldr r2, [sp, #68] + ldr r3, [sp, #72] + bl vp9_loop_filter_h_16_neon + add sp, sp, #4 + vpop {q4-q7} + pop {r2, r3, pc} +endfunc From 3b50dbc51fb0978d09c1a5b83d4bf5a59d170e1e Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 13 Mar 2015 00:36:41 +0100 Subject: [PATCH 0455/3374] ratecontrol: Use correct function pointer casts instead of void* MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit libavcodec/ratecontrol.c:120:9: warning: ISO C forbids initialization between function pointer and ‘void *’ [-Wpedantic] libavcodec/ratecontrol.c:121:9: warning: ISO C forbids initialization between function pointer and ‘void *’ [-Wpedantic] --- libavcodec/ratecontrol.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c index 78a438f53d6f6..097da2ee2cc7c 100644 --- a/libavcodec/ratecontrol.c +++ b/libavcodec/ratecontrol.c @@ -472,8 +472,8 @@ av_cold int ff_rate_control_init(MpegEncContext *s) NULL }; static double (* const func1[])(void *, double) = { - (void *)bits2qp, - (void *)qp2bits, + (double (*)(void *, double)) bits2qp, + (double (*)(void *, double)) qp2bits, NULL }; static const char * const func1_names[] = { From fcbdd605b5409103c3f4bfa063ea270f2229b125 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 30 Oct 2015 15:27:56 +0100 Subject: [PATCH 0456/3374] nut: Use correct function pointer casts instead of void* Fixes several warnings of the type libavformat/nut.c:207:42: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic] --- libavformat/nut.c | 3 ++- libavformat/nutdec.c | 9 ++++++--- libavformat/nutenc.c | 3 ++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/libavformat/nut.c b/libavformat/nut.c index 828d9ca5e0b15..ec43a3f438c2e 100644 --- a/libavformat/nut.c +++ b/libavformat/nut.c @@ -204,7 +204,8 @@ int ff_nut_add_sp(NUTContext *nut, int64_t pos, int64_t back_ptr, int64_t ts) sp->pos = pos; sp->back_ptr = back_ptr; sp->ts = ts; - av_tree_insert(&nut->syncpoints, sp, (void *) ff_nut_sp_pos_cmp, &node); + av_tree_insert(&nut->syncpoints, sp, + (int (*)(void *, const void *)) ff_nut_sp_pos_cmp, &node); if (node) { av_free(sp); av_free(node); diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c index 25076631bfd7b..55c21714cebce 100644 --- a/libavformat/nutdec.c +++ b/libavformat/nutdec.c @@ -987,7 +987,8 @@ static int read_seek(AVFormatContext *s, int stream_index, pos2 = st->index_entries[index].pos; ts = st->index_entries[index].timestamp; } else { - av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pts_cmp, + av_tree_find(nut->syncpoints, &dummy, + (int (*)(void *, const void *)) ff_nut_sp_pts_cmp, (void **) next_node); av_log(s, AV_LOG_DEBUG, "%"PRIu64"-%"PRIu64" %"PRId64"-%"PRId64"\n", next_node[0]->pos, next_node[1]->pos, next_node[0]->ts, @@ -1000,7 +1001,8 @@ static int read_seek(AVFormatContext *s, int stream_index, if (!(flags & AVSEEK_FLAG_BACKWARD)) { dummy.pos = pos + 16; next_node[1] = &nopts_sp; - av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pos_cmp, + av_tree_find(nut->syncpoints, &dummy, + (int (*)(void *, const void *)) ff_nut_sp_pos_cmp, (void **) next_node); pos2 = ff_gen_search(s, -2, dummy.pos, next_node[0]->pos, next_node[1]->pos, next_node[1]->pos, @@ -1011,7 +1013,8 @@ static int read_seek(AVFormatContext *s, int stream_index, // FIXME dir but I think it does not matter } dummy.pos = pos; - sp = av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pos_cmp, + sp = av_tree_find(nut->syncpoints, &dummy, + (int (*)(void *, const void *)) ff_nut_sp_pos_cmp, NULL); assert(sp); diff --git a/libavformat/nutenc.c b/libavformat/nutenc.c index 3c824a600d8b2..57179bb885690 100644 --- a/libavformat/nutenc.c +++ b/libavformat/nutenc.c @@ -807,7 +807,8 @@ static int nut_write_packet(AVFormatContext *s, AVPacket *pkt) } if (dummy.pos == INT64_MAX) dummy.pos = 0; - sp = av_tree_find(nut->syncpoints, &dummy, (void *)ff_nut_sp_pos_cmp, + sp = av_tree_find(nut->syncpoints, &dummy, + (int (*)(void *, const void *)) ff_nut_sp_pos_cmp, NULL); nut->last_syncpoint_pos = avio_tell(bc); From 8ddfa5ae5ef64a25dd087d74954ebdb9081f0d67 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 30 Oct 2015 15:21:19 +0100 Subject: [PATCH 0457/3374] vf_drawtext: Drop wrong void* cast libavfilter/vf_drawtext.c:844:49: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic] --- libavfilter/vf_drawtext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index 994eea3c0c4f8..d119251712386 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -840,7 +840,7 @@ static int draw_glyphs(DrawTextContext *s, AVFrame *frame, continue; dummy.code = code; - glyph = av_tree_find(s->glyphs, &dummy, (void *)glyph_cmp, NULL); + glyph = av_tree_find(s->glyphs, &dummy, glyph_cmp, NULL); if (glyph->bitmap.pixel_mode != FT_PIXEL_MODE_MONO && glyph->bitmap.pixel_mode != FT_PIXEL_MODE_GRAY) From d316f9cefcd854071985c6f524a9a15348240264 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 15 Mar 2015 15:56:52 +0100 Subject: [PATCH 0458/3374] aac: Drop pointless cast --- libavcodec/aacpsy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/aacpsy.c b/libavcodec/aacpsy.c index 6cfae6bdbd9b7..272be9f1371cd 100644 --- a/libavcodec/aacpsy.c +++ b/libavcodec/aacpsy.c @@ -300,7 +300,7 @@ static av_cold int psy_3gpp_init(FFPsyContext *ctx) { ctx->model_priv_data = av_mallocz(sizeof(AacPsyContext)); if (!ctx->model_priv_data) return AVERROR(ENOMEM); - pctx = (AacPsyContext*) ctx->model_priv_data; + pctx = ctx->model_priv_data; pctx->chan_bitrate = chan_bitrate; pctx->frame_bits = chan_bitrate * AAC_BLOCK_SIZE_LONG / ctx->avctx->sample_rate; From 800d91d348c89fc8ca3fbec7696ab1ec8787acc6 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 30 Oct 2015 15:26:25 +0100 Subject: [PATCH 0459/3374] Drop pointless void* casts --- libavcodec/flac_parser.c | 2 +- libavcodec/libopenh264enc.c | 4 ++-- libavcodec/libschroedinger.c | 2 +- libavcodec/vdpau.c | 2 +- libavformat/avisynth.c | 3 +-- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/libavcodec/flac_parser.c b/libavcodec/flac_parser.c index 70b9a651e9974..cb394f2bdb374 100644 --- a/libavcodec/flac_parser.c +++ b/libavcodec/flac_parser.c @@ -588,7 +588,7 @@ static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx, read_end - read_start, NULL); } else { int8_t pad[MAX_FRAME_HEADER_SIZE] = { 0 }; - av_fifo_generic_write(fpc->fifo_buf, (void*) pad, sizeof(pad), NULL); + av_fifo_generic_write(fpc->fifo_buf, pad, sizeof(pad), NULL); } /* Tag headers and update sequences. */ diff --git a/libavcodec/libopenh264enc.c b/libavcodec/libopenh264enc.c index a09b7cf618ea9..b7c011893ea1a 100644 --- a/libavcodec/libopenh264enc.c +++ b/libavcodec/libopenh264enc.c @@ -112,10 +112,10 @@ static av_cold int svc_encode_init(AVCodecContext *avctx) // Set the logging callback function to one that uses av_log() (see implementation above). callback_function = (WelsTraceCallback) ff_libopenh264_trace_callback; - (*s->encoder)->SetOption(s->encoder, ENCODER_OPTION_TRACE_CALLBACK, (void *)&callback_function); + (*s->encoder)->SetOption(s->encoder, ENCODER_OPTION_TRACE_CALLBACK, &callback_function); // Set the AVCodecContext as the libopenh264 callback context so that it can be passed to av_log(). - (*s->encoder)->SetOption(s->encoder, ENCODER_OPTION_TRACE_CALLBACK_CONTEXT, (void *)&avctx); + (*s->encoder)->SetOption(s->encoder, ENCODER_OPTION_TRACE_CALLBACK_CONTEXT, &avctx); (*s->encoder)->GetDefaultParams(s->encoder, ¶m); diff --git a/libavcodec/libschroedinger.c b/libavcodec/libschroedinger.c index 16e0fe89b9709..af3000f371670 100644 --- a/libavcodec/libschroedinger.c +++ b/libavcodec/libschroedinger.c @@ -200,7 +200,7 @@ SchroFrame *ff_create_schro_frame(AVCodecContext *avctx, p_frame->format = schro_frame_fmt; p_frame->width = y_width; p_frame->height = y_height; - schro_frame_set_free_callback(p_frame, free_schro_frame, (void *)p_pic); + schro_frame_set_free_callback(p_frame, free_schro_frame, p_pic); for (i = 0; i < 3; ++i) { p_frame->components[i].width = i ? uv_width : y_width; diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c index f638d201159dd..d3cb188d7422d 100644 --- a/libavcodec/vdpau.c +++ b/libavcodec/vdpau.c @@ -267,7 +267,7 @@ int ff_vdpau_common_end_frame(AVCodecContext *avctx, AVFrame *frame, if (val < 0) return val; - status = vdctx->render(vdctx->decoder, surf, (void *)&pic_ctx->info, + status = vdctx->render(vdctx->decoder, surf, &pic_ctx->info, pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers); diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c index fe71a427a6875..7d5b139adeb50 100644 --- a/libavformat/avisynth.c +++ b/libavformat/avisynth.c @@ -118,8 +118,7 @@ static av_cold int avisynth_load_library(void) return AVERROR_UNKNOWN; #define LOAD_AVS_FUNC(name, continue_on_fail) \ - avs_library.name = \ - (void *)GetProcAddress(avs_library.library, #name); \ + avs_library.name = GetProcAddress(avs_library.library, #name); \ if (!continue_on_fail && !avs_library.name) \ goto fail; From 01348e411f962f5e4605d649fc9a47a54587ba8e Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 6 Dec 2015 13:04:05 +0100 Subject: [PATCH 0460/3374] avconv_opt: Consistently iterate through hwaccels array in all cases avconv_opt.c:188:19: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits] --- avconv_opt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avconv_opt.c b/avconv_opt.c index 1064cf4668b4d..4d7140dc46063 100644 --- a/avconv_opt.c +++ b/avconv_opt.c @@ -190,7 +190,7 @@ static int show_hwaccels(void *optctx, const char *opt, const char *arg) int i; printf("Supported hardware acceleration:\n"); - for (i = 0; i < FF_ARRAY_ELEMS(hwaccels) - 1; i++) { + for (i = 0; hwaccels[i].name; i++) { printf("%s\n", hwaccels[i].name); } printf("\n"); From 52d196fb30fb6628921b5f1b31e7bd11eb7e1d9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 12 Nov 2016 21:25:50 +0200 Subject: [PATCH 0461/3374] arm: vp9itxfm: Simplify txfm string comparisons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 45 ++++++++-------------------------- 1 file changed, 10 insertions(+), 35 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index fca9836df6663..cdb43b567f596 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -258,8 +258,7 @@ function ff_vp9_\txfm1\()_\txfm2\()_4x4_add_neon, export=1 .endif vmov.i16 q15, #0 -.ifc \txfm1,idct -.ifc \txfm2,idct +.ifc \txfm1\()_\txfm2,idct_idct cmp r3, #1 bne 1f @ DC-only for idct/idct @@ -273,7 +272,6 @@ function ff_vp9_\txfm1\()_\txfm2\()_4x4_add_neon, export=1 vmov q3, q2 b 2f .endif -.endif 1: vld1.16 {d4-d7}, [r2,:128] @@ -386,29 +384,21 @@ function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_neon, export=1 @ if only idct is involved. @ The iadst also uses a few coefficients from @ idct, so those always need to be loaded. -.ifc \txfm1,iadst - movrel r12, iadst8_coeffs - vld1.16 {q1}, [r12,:128]! - vpush {q4-q7} +.ifc \txfm1\()_\txfm2,idct_idct + movrel r12, idct_coeffs + vpush {q4-q5} vld1.16 {q0}, [r12,:128] .else -.ifc \txfm2,iadst movrel r12, iadst8_coeffs vld1.16 {q1}, [r12,:128]! vpush {q4-q7} vld1.16 {q0}, [r12,:128] -.else - movrel r12, idct_coeffs - vpush {q4-q5} - vld1.16 {q0}, [r12,:128] -.endif .endif vmov.i16 q2, #0 vmov.i16 q3, #0 -.ifc \txfm1,idct -.ifc \txfm2,idct +.ifc \txfm1\()_\txfm2,idct_idct cmp r3, #1 bne 1f @ DC-only for idct/idct @@ -428,7 +418,6 @@ function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_neon, export=1 vst1.16 {d4[0]}, [r2,:16] b 2f .endif -.endif 1: vld1.16 {q8-q9}, [r2,:128]! vld1.16 {q10-q11}, [r2,:128]! @@ -497,14 +486,10 @@ function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_neon, export=1 vst1.8 {d10}, [r3,:64], r1 vst1.8 {d11}, [r3,:64], r1 -.ifc \txfm1,iadst - vpop {q4-q7} +.ifc \txfm1\()_\txfm2,idct_idct + vpop {q4-q5} .else -.ifc \txfm2,iadst vpop {q4-q7} -.else - vpop {q4-q5} -.endif .endif bx lr endfunc @@ -798,19 +783,13 @@ itxfm16_1d_funcs iadst .macro itxfm_func16x16 txfm1, txfm2 function ff_vp9_\txfm1\()_\txfm2\()_16x16_add_neon, export=1 -.ifc \txfm1,idct -.ifc \txfm2,idct +.ifc \txfm1\()_\txfm2,idct_idct cmp r3, #1 beq idct16x16_dc_add_neon -.endif .endif push {r4-r7,lr} -.ifc \txfm1,iadst - vpush {q4-q7} -.else -.ifc \txfm2,iadst +.ifnc \txfm1\()_\txfm2,idct_idct vpush {q4-q7} -.endif .endif mov r7, sp @@ -850,12 +829,8 @@ A sub sp, sp, #512 .endr mov sp, r7 -.ifc \txfm1,iadst - vpop {q4-q7} -.else -.ifc \txfm2,iadst +.ifnc \txfm1\()_\txfm2,idct_idct vpop {q4-q7} -.endif .endif pop {r4-r7,pc} endfunc From 9d2afd1eb8c5cc0633062430e66326dbf98c99e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 14 Nov 2016 00:07:27 +0200 Subject: [PATCH 0462/3374] aarch64: vp9: Implement NEON loop filters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. These are ported from the ARM version; thanks to the larger amount of registers available, we can do the loop filters with 16 pixels at a time. The implementation is fully templated, with a single macro which can generate versions for both 8 and 16 pixels wide, for both 4, 8 and 16 pixels loop filters (and the 4/8 mixed versions as well). For the 8 pixel wide versions, it is pretty close in speed (the v_4_8 and v_8_8 filters are the best examples of this; the h_4_8 and h_8_8 filters seem to get some gain in the load/transpose/store part). For the 16 pixels wide ones, we get a speedup of around 1.2-1.4x compared to the 32 bit version. Examples of runtimes vs the 32 bit version, on a Cortex A53: ARM AArch64 vp9_loop_filter_h_4_8_neon: 144.0 127.2 vp9_loop_filter_h_8_8_neon: 207.0 182.5 vp9_loop_filter_h_16_8_neon: 415.0 328.7 vp9_loop_filter_h_16_16_neon: 672.0 558.6 vp9_loop_filter_mix2_h_44_16_neon: 302.0 203.5 vp9_loop_filter_mix2_h_48_16_neon: 365.0 305.2 vp9_loop_filter_mix2_h_84_16_neon: 365.0 305.2 vp9_loop_filter_mix2_h_88_16_neon: 376.0 305.2 vp9_loop_filter_mix2_v_44_16_neon: 193.2 128.2 vp9_loop_filter_mix2_v_48_16_neon: 246.7 218.4 vp9_loop_filter_mix2_v_84_16_neon: 248.0 218.5 vp9_loop_filter_mix2_v_88_16_neon: 302.0 218.2 vp9_loop_filter_v_4_8_neon: 89.0 88.7 vp9_loop_filter_v_8_8_neon: 141.0 137.7 vp9_loop_filter_v_16_8_neon: 295.0 272.7 vp9_loop_filter_v_16_16_neon: 546.0 453.7 The speedup vs C code in checkasm tests is around 2-7x, which is pretty much the same as for the 32 bit version. Even if these functions are faster than their 32 bit equivalent, the C version that we compare to also became around 1.3-1.7x faster than the C version in 32 bit. Based on START_TIMER/STOP_TIMER wrapping around a few individual functions, the speedup vs C code is around 4-5x. Examples of runtimes vs C on a Cortex A57 (for a slightly older version of the patch): A57 gcc-5.3 neon loop_filter_h_4_8_neon: 256.6 93.4 loop_filter_h_8_8_neon: 307.3 139.1 loop_filter_h_16_8_neon: 340.1 254.1 loop_filter_h_16_16_neon: 827.0 407.9 loop_filter_mix2_h_44_16_neon: 524.5 155.4 loop_filter_mix2_h_48_16_neon: 644.5 173.3 loop_filter_mix2_h_84_16_neon: 630.5 222.0 loop_filter_mix2_h_88_16_neon: 697.3 222.0 loop_filter_mix2_v_44_16_neon: 598.5 100.6 loop_filter_mix2_v_48_16_neon: 651.5 127.0 loop_filter_mix2_v_84_16_neon: 591.5 167.1 loop_filter_mix2_v_88_16_neon: 855.1 166.7 loop_filter_v_4_8_neon: 271.7 65.3 loop_filter_v_8_8_neon: 312.5 106.9 loop_filter_v_16_8_neon: 473.3 206.5 loop_filter_v_16_16_neon: 976.1 327.8 The speed-up compared to the C functions is 2.5 to 6 and the cortex-a57 is again 30-50% faster than the cortex-a53. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/Makefile | 1 + libavcodec/aarch64/vp9dsp_init_aarch64.c | 45 + libavcodec/aarch64/vp9lpf_neon.S | 1355 ++++++++++++++++++++++ 3 files changed, 1401 insertions(+) create mode 100644 libavcodec/aarch64/vp9lpf_neon.S diff --git a/libavcodec/aarch64/Makefile b/libavcodec/aarch64/Makefile index 0b06b33b55920..5c1d118383bab 100644 --- a/libavcodec/aarch64/Makefile +++ b/libavcodec/aarch64/Makefile @@ -45,4 +45,5 @@ NEON-OBJS-$(CONFIG_DCA_DECODER) += aarch64/dcadsp_neon.o \ aarch64/synth_filter_neon.o NEON-OBJS-$(CONFIG_VORBIS_DECODER) += aarch64/vorbisdsp_neon.o NEON-OBJS-$(CONFIG_VP9_DECODER) += aarch64/vp9itxfm_neon.o \ + aarch64/vp9lpf_neon.o \ aarch64/vp9mc_neon.o diff --git a/libavcodec/aarch64/vp9dsp_init_aarch64.c b/libavcodec/aarch64/vp9dsp_init_aarch64.c index da6f7f9cbf823..486ae1eefd1e4 100644 --- a/libavcodec/aarch64/vp9dsp_init_aarch64.c +++ b/libavcodec/aarch64/vp9dsp_init_aarch64.c @@ -195,8 +195,53 @@ static av_cold void vp9dsp_itxfm_init_aarch64(VP9DSPContext *dsp) } } +#define define_loop_filter(dir, wd, len) \ +void ff_vp9_loop_filter_##dir##_##wd##_##len##_neon(uint8_t *dst, ptrdiff_t stride, int E, int I, int H) + +#define define_loop_filters(wd, len) \ + define_loop_filter(h, wd, len); \ + define_loop_filter(v, wd, len) + +define_loop_filters(4, 8); +define_loop_filters(8, 8); +define_loop_filters(16, 8); + +define_loop_filters(16, 16); + +define_loop_filters(44, 16); +define_loop_filters(48, 16); +define_loop_filters(84, 16); +define_loop_filters(88, 16); + +static av_cold void vp9dsp_loopfilter_init_aarch64(VP9DSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) { + dsp->loop_filter_8[0][1] = ff_vp9_loop_filter_v_4_8_neon; + dsp->loop_filter_8[0][0] = ff_vp9_loop_filter_h_4_8_neon; + dsp->loop_filter_8[1][1] = ff_vp9_loop_filter_v_8_8_neon; + dsp->loop_filter_8[1][0] = ff_vp9_loop_filter_h_8_8_neon; + dsp->loop_filter_8[2][1] = ff_vp9_loop_filter_v_16_8_neon; + dsp->loop_filter_8[2][0] = ff_vp9_loop_filter_h_16_8_neon; + + dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_neon; + dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_neon; + + dsp->loop_filter_mix2[0][0][0] = ff_vp9_loop_filter_h_44_16_neon; + dsp->loop_filter_mix2[0][0][1] = ff_vp9_loop_filter_v_44_16_neon; + dsp->loop_filter_mix2[0][1][0] = ff_vp9_loop_filter_h_48_16_neon; + dsp->loop_filter_mix2[0][1][1] = ff_vp9_loop_filter_v_48_16_neon; + dsp->loop_filter_mix2[1][0][0] = ff_vp9_loop_filter_h_84_16_neon; + dsp->loop_filter_mix2[1][0][1] = ff_vp9_loop_filter_v_84_16_neon; + dsp->loop_filter_mix2[1][1][0] = ff_vp9_loop_filter_h_88_16_neon; + dsp->loop_filter_mix2[1][1][1] = ff_vp9_loop_filter_v_88_16_neon; + } +} + av_cold void ff_vp9dsp_init_aarch64(VP9DSPContext *dsp) { vp9dsp_mc_init_aarch64(dsp); + vp9dsp_loopfilter_init_aarch64(dsp); vp9dsp_itxfm_init_aarch64(dsp); } diff --git a/libavcodec/aarch64/vp9lpf_neon.S b/libavcodec/aarch64/vp9lpf_neon.S new file mode 100644 index 0000000000000..995a97daac71f --- /dev/null +++ b/libavcodec/aarch64/vp9lpf_neon.S @@ -0,0 +1,1355 @@ +/* + * Copyright (c) 2016 Google Inc. + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/aarch64/asm.S" +#include "neon.S" + + +// The main loop filter macro is templated and can produce filters for +// vectors of 8 or 16 bytes. The register mapping throughout the filter +// is close to identical to the arm version (please try to maintain this, +// if either is changed!). When the arm version uses e.g. d20 for the +// input variable p3, the aarch64 version uses v20.8b or v20.16b, depending +// on vector length. +// +// The number of elements in the vector is passed in via the macro parameter +// \sz, which is either .8b or .16b. For simple instructions that doesn't +// lengthen or narrow things, this can easily be templated like this: +// uabd v4\sz, v20\sz, v21\sz +// +// For instructions that lengthen or narrow content, the arm version would +// have used q registers. For these instructions, we have macros that expand +// into either a single e.g. uaddl instruction, or into a uaddl + uaddl2 +// pair, depending on the \sz parameter. Wherever the arm version would have +// used a q register, these macros instead take two v registers, i.e. q3 +// is mapped to v6+v7. For the case with 8 byte input vectors, such a +// lengthening operation is only stored in v6.8h (what was in q3 in the arm +// case), while the 16 byte input vectors will use v6.8h + v7.8h. +// Such a macro invocation would look like this: +// uaddl_sz v8.8h, v9.8h, v17, v18, \sz +// +// That is, in the 8 byte input vector case, the second register in these +// register pairs will be unused. +// Unfortunately, this makes the code quite hard to read. For readability, +// see the arm version instead. + + +.macro uabdl_sz dst1, dst2, in1, in2, sz + uabdl \dst1, \in1\().8b, \in2\().8b +.ifc \sz, .16b + uabdl2 \dst2, \in1\().16b, \in2\().16b +.endif +.endm + +.macro add_sz dst1, dst2, in1, in2, in3, in4, sz + add \dst1, \in1, \in3 +.ifc \sz, .16b + add \dst2, \in2, \in4 +.endif +.endm + +.macro sub_sz dst1, dst2, in1, in2, in3, in4, sz + sub \dst1, \in1, \in3 +.ifc \sz, .16b + sub \dst2, \in2, \in4 +.endif +.endm + +.macro uaddw_sz dst1, dst2, in1, in2, in3, sz + uaddw \dst1, \in1, \in3\().8b +.ifc \sz, .16b + uaddw2 \dst2, \in2, \in3\().16b +.endif +.endm + +.macro usubw_sz dst1, dst2, in1, in2, in3, sz + usubw \dst1, \in1, \in3\().8b +.ifc \sz, .16b + usubw2 \dst2, \in2, \in3\().16b +.endif +.endm + +.macro cmhs_sz dst1, dst2, in1, in2, in3, in4, sz + cmhs \dst1, \in1, \in3 +.ifc \sz, .16b + cmhs \dst2, \in2, \in4 +.endif +.endm + +.macro xtn_sz dst, in1, in2, sz + xtn \dst\().8b, \in1 +.ifc \sz, .16b + xtn2 \dst\().16b, \in2 +.endif +.endm + +.macro usubl_sz dst1, dst2, in1, in2, sz + usubl \dst1, \in1\().8b, \in2\().8b +.ifc \sz, .16b + usubl2 \dst2, \in1\().16b, \in2\().16b +.endif +.endm + +.macro sqxtn_sz dst, in1, in2, sz + sqxtn \dst\().8b, \in1 +.ifc \sz, .16b + sqxtn2 \dst\().16b, \in2 +.endif +.endm + +.macro sqxtun_sz dst, in1, in2, sz + sqxtun \dst\().8b, \in1 +.ifc \sz, .16b + sqxtun2 \dst\().16b, \in2 +.endif +.endm + +.macro mul_sz dst1, dst2, in1, in2, in3, in4, sz + mul \dst1, \in1, \in3 +.ifc \sz, .16b + mul \dst2, \in2, \in4 +.endif +.endm + +.macro saddw_sz dst1, dst2, in1, in2, in3, sz + saddw \dst1, \in1, \in3\().8b +.ifc \sz, .16b + saddw2 \dst2, \in2, \in3\().16b +.endif +.endm + +.macro ssubw_sz dst1, dst2, in1, in2, in3, sz + ssubw \dst1, \in1, \in3\().8b +.ifc \sz, .16b + ssubw2 \dst2, \in2, \in3\().16b +.endif +.endm + +.macro uxtl_sz dst1, dst2, in, sz + uxtl \dst1, \in\().8b +.ifc \sz, .16b + uxtl2 \dst2, \in\().16b +.endif +.endm + +.macro uaddl_sz dst1, dst2, in1, in2, sz + uaddl \dst1, \in1\().8b, \in2\().8b +.ifc \sz, .16b + uaddl2 \dst2, \in1\().16b, \in2\().16b +.endif +.endm + +.macro rshrn_sz dst, in1, in2, shift, sz + rshrn \dst\().8b, \in1, \shift +.ifc \sz, .16b + rshrn2 \dst\().16b, \in2, \shift +.endif +.endm + +.macro ushll_sz dst1, dst2, in, shift, sz + ushll \dst1, \in\().8b, \shift +.ifc \sz, .16b + ushll2 \dst2, \in\().16b, \shift +.endif +.endm + +// The input to and output from this macro is in the registers v16-v31, +// and v0-v7 are used as scratch registers. +// p7 = v16 .. p3 = v20, p0 = v23, q0 = v24, q3 = v27, q7 = v31 +// Depending on the width of the loop filter, we either use v16-v19 +// and v28-v31 as temp registers, or v8-v15. +// When comparing to the arm version, tmpq1 == tmp1 + tmp2, +// tmpq2 == tmp3 + tmp4, etc. +.macro loop_filter wd, sz, mix, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8 +.if \mix == 0 + dup v0.8h, w2 // E + dup v1.8h, w2 // E + dup v2\sz, w3 // I + dup v3\sz, w4 // H +.else + dup v0.8h, w2 // E + dup v2.8b, w3 // I + dup v3.8b, w4 // H + lsr w6, w3, #8 + lsr w7, w4, #8 + ushr v1.8h, v0.8h, #8 // E + dup v4.8b, w6 // I + bic v0.8h, #255, lsl 8 // E + dup v5.8b, w7 // H + trn1 v2.2d, v2.2d, v4.2d + trn1 v3.2d, v3.2d, v5.2d +.endif + + uabd v4\sz, v20\sz, v21\sz // abs(p3 - p2) + uabd v5\sz, v21\sz, v22\sz // abs(p2 - p1) + uabd v6\sz, v22\sz, v23\sz // abs(p1 - p0) + uabd v7\sz, v24\sz, v25\sz // abs(q0 - q1) + uabd \tmp1\sz, v25\sz, v26\sz // abs(q1 - q2) + uabd \tmp2\sz, v26\sz, v27\sz // abs(q2 - q3) + umax v4\sz, v4\sz, v5\sz + umax v5\sz, v6\sz, v7\sz + umax \tmp1\sz, \tmp1\sz, \tmp2\sz + uabdl_sz v6.8h, v7.8h, v23, v24, \sz // abs(p0 - q0) + umax v4\sz, v4\sz, v5\sz + add_sz v6.8h, v7.8h, v6.8h, v7.8h, v6.8h, v7.8h, \sz // abs(p0 - q0) * 2 + uabd v5\sz, v22\sz, v25\sz // abs(p1 - q1) + umax v4\sz, v4\sz, \tmp1\sz // max(abs(p3 - p2), ..., abs(q2 - q3)) + ushr v5\sz, v5\sz, #1 + cmhs v4\sz, v2\sz, v4\sz // max(abs()) <= I + uaddw_sz v6.8h, v7.8h, v6.8h, v7.8h, v5, \sz // abs(p0 - q0) * 2 + abs(p1 - q1) >> 1 + cmhs_sz v6.8h, v7.8h, v0.8h, v1.8h, v6.8h, v7.8h, \sz + xtn_sz v5, v6.8h, v7.8h, \sz + and v4\sz, v4\sz, v5\sz // fm + + mov x5, v4.d[0] +.ifc \sz, .16b + mov x6, v4.d[1] + orr x5, x5, x6 +.endif + // If no pixels need filtering, just exit as soon as possible + cbz x5, 9f + +.if \wd >= 8 + movi v0\sz, #1 + + uabd v6\sz, v20\sz, v23\sz // abs(p3 - p0) + uabd v2\sz, v21\sz, v23\sz // abs(p2 - p0) + uabd v1\sz, v22\sz, v23\sz // abs(p1 - p0) + uabd \tmp1\sz, v25\sz, v24\sz // abs(q1 - q0) + uabd \tmp2\sz, v26\sz, v24\sz // abs(q2 - q0) + uabd \tmp3\sz, v27\sz, v24\sz // abs(q3 - q0) + umax v6\sz, v6\sz, v2\sz + umax v1\sz, v1\sz, \tmp1\sz + umax \tmp2\sz, \tmp2\sz, \tmp3\sz +.if \wd == 16 + uabd v7\sz, v16\sz, v23\sz // abs(p7 - p0) + umax v6\sz, v6\sz, v1\sz + uabd v2\sz, v17\sz, v23\sz // abs(p6 - p0) + umax v6\sz, v6\sz, \tmp2\sz + uabd v1\sz, v18\sz, v23\sz // abs(p5 - p0) + cmhs v6\sz, v0\sz, v6\sz // flat8in + uabd v8\sz, v19\sz, v23\sz // abs(p4 - p0) + and v6\sz, v6\sz, v4\sz // flat8in && fm + uabd v9\sz, v28\sz, v24\sz // abs(q4 - q0) + bic v4\sz, v4\sz, v6\sz // fm && !flat8in + uabd v10\sz, v29\sz, v24\sz // abs(q5 - q0) + uabd v11\sz, v30\sz, v24\sz // abs(q6 - q0) + uabd v12\sz, v31\sz, v24\sz // abs(q7 - q0) + + umax v7\sz, v7\sz, v2\sz + umax v1\sz, v1\sz, v8\sz + umax v9\sz, v9\sz, v10\sz + umax v11\sz, v11\sz, v12\sz + // The rest of the calculation of flat8out is interleaved below +.else + // The rest of the calculation of flat8in is interleaved below +.endif +.endif + + // Calculate the normal inner loop filter for 2 or 4 pixels + uabd v5\sz, v22\sz, v23\sz // abs(p1 - p0) +.if \wd == 16 + umax v7\sz, v7\sz, v1\sz + umax v9\sz, v9\sz, v11\sz +.elseif \wd == 8 + umax v6\sz, v6\sz, v1\sz +.endif + uabd v1\sz, v25\sz, v24\sz // abs(q1 - q0) +.if \wd == 16 + umax v7\sz, v7\sz, v9\sz +.elseif \wd == 8 + umax v6\sz, v6\sz, \tmp2\sz +.endif + usubl_sz \tmp1\().8h, \tmp2\().8h, v22, v25, \sz // p1 - q1 + umax v5\sz, v5\sz, v1\sz // max(abs(p1 - p0), abs(q1 - q0)) +.if \mix != 0 + mov v1.d[0], x11 +.endif + usubl_sz \tmp3\().8h, \tmp4\().8h, v24, v23, \sz // q0 - p0 + movi \tmp5\().8h, #3 +.if \wd == 8 + cmhs v6\sz, v0\sz, v6\sz // flat8in +.endif +.if \mix != 0 + sxtl v1.8h, v1.8b +.endif + cmhi v5\sz, v5\sz, v3\sz // hev +.if \wd == 8 + // If a 4/8 or 8/4 mix is used, clear the relevant half of v6 +.if \mix != 0 + and v6\sz, v6\sz, v1.16b +.endif + and v6\sz, v6\sz, v4\sz // flat8in && fm +.endif + sqxtn_sz \tmp1, \tmp1\().8h, \tmp2\().8h, \sz // av_clip_int8(p1 - q1) +.if \wd == 16 + cmhs v7\sz, v0\sz, v7\sz // flat8out +.elseif \wd == 8 + bic v4\sz, v4\sz, v6\sz // fm && !flat8in +.endif + mvn v5\sz, v5\sz // !hev +.if \wd == 16 + and v7\sz, v7\sz, v6\sz // flat8out && flat8in && fm +.endif + and v5\sz, v5\sz, v4\sz // !hev && fm && !flat8in + + mul_sz \tmp3\().8h, \tmp4\().8h, \tmp3\().8h, \tmp4\().8h, \tmp5\().8h, \tmp5\().8h, \sz // 3 * (q0 - p0) + bic \tmp1\sz, \tmp1\sz, v5\sz // if (!hev) av_clip_int8 = 0 + movi v2\sz, #4 + saddw_sz \tmp3\().8h, \tmp4\().8h, \tmp3\().8h, \tmp4\().8h, \tmp1, \sz // 3 * (q0 - p0) [+ av_clip_int8(p1 - q1)] + movi v3\sz, #3 + sqxtn_sz \tmp1, \tmp3\().8h, \tmp4\().8h, \sz // f +.if \wd == 16 + bic v6\sz, v6\sz, v7\sz // fm && flat8in && !flat8out +.endif + + sqadd \tmp3\sz, \tmp1\sz, v2\sz // FFMIN(f + 4, 127) + sqadd \tmp4\sz, \tmp1\sz, v3\sz // FFMIN(f + 3, 127) + uxtl_sz v0.8h, v1.8h, v23, \sz // p0 + sshr \tmp3\sz, \tmp3\sz, #3 // f1 + sshr \tmp4\sz, \tmp4\sz, #3 // f2 + + uxtl_sz v2.8h, v3.8h, v24, \sz // q0 + saddw_sz v0.8h, v1.8h, v0.8h, v1.8h, \tmp4, \sz // p0 + f2 + ssubw_sz v2.8h, v3.8h, v2.8h, v3.8h, \tmp3, \sz // q0 - f1 + sqxtun_sz v0, v0.8h, v1.8h, \sz // out p0 + sqxtun_sz v1, v2.8h, v3.8h, \sz // out q0 + srshr \tmp3\sz, \tmp3\sz, #1 // f = (f1 + 1) >> 1 + bit v23\sz, v0\sz, v4\sz // if (fm && !flat8in) + bit v24\sz, v1\sz, v4\sz + + uxtl_sz v0.8h, v1.8h, v22, \sz // p1 + uxtl_sz v2.8h, v3.8h, v25, \sz // q1 + saddw_sz v0.8h, v1.8h, v0.8h, v1.8h, \tmp3, \sz // p1 + f + ssubw_sz v2.8h, v3.8h, v2.8h, v3.8h, \tmp3, \sz // q1 - f + sqxtun_sz v0, v0.8h, v1.8h, \sz // out p1 + sqxtun_sz v2, v2.8h, v3.8h, \sz // out q1 + bit v22\sz, v0\sz, v5\sz // if (!hev && fm && !flat8in) + bit v25\sz, v2\sz, v5\sz + +.if \wd >= 8 + mov x5, v6.d[0] +.ifc \sz, .16b + mov x6, v6.d[1] + orr x5, x5, x6 +.endif + // If no pixels need flat8in, jump to flat8out + // (or to a writeout of the inner 4 pixels, for wd=8) + cbz x5, 6f + + // flat8in + uaddl_sz \tmp1\().8h, \tmp2\().8h, v20, v21, \sz + uaddl_sz \tmp3\().8h, \tmp4\().8h, v22, v25, \sz + uaddl_sz \tmp5\().8h, \tmp6\().8h, v20, v22, \sz + uaddl_sz \tmp7\().8h, \tmp8\().8h, v23, v26, \sz + add_sz v0.8h, v1.8h, \tmp1\().8h, \tmp2\().8h, \tmp1\().8h, \tmp2\().8h, \sz + uaddw_sz v0.8h, v1.8h, v0.8h, v1.8h, v23, \sz + uaddw_sz v0.8h, v1.8h, v0.8h, v1.8h, v24, \sz + add_sz v0.8h, v1.8h, v0.8h, v1.8h, \tmp5\().8h, \tmp6\().8h, \sz + sub_sz \tmp3\().8h, \tmp4\().8h, \tmp3\().8h, \tmp4\().8h, \tmp1\().8h, \tmp2\().8h, \sz + sub_sz \tmp7\().8h, \tmp8\().8h, \tmp7\().8h, \tmp8\().8h, \tmp5\().8h, \tmp6\().8h, \sz + rshrn_sz v2, v0.8h, v1.8h, #3, \sz // out p2 + + add_sz v0.8h, v1.8h, v0.8h, v1.8h, \tmp3\().8h, \tmp4\().8h, \sz + uaddl_sz \tmp1\().8h, \tmp2\().8h, v20, v23, \sz + uaddl_sz \tmp3\().8h, \tmp4\().8h, v24, v27, \sz + rshrn_sz v3, v0.8h, v1.8h, #3, \sz // out p1 + + add_sz v0.8h, v1.8h, v0.8h, v1.8h, \tmp7\().8h, \tmp8\().8h, \sz + sub_sz \tmp3\().8h, \tmp4\().8h, \tmp3\().8h, \tmp4\().8h, \tmp1\().8h, \tmp2\().8h, \sz + uaddl_sz \tmp5\().8h, \tmp6\().8h, v21, v24, \sz + uaddl_sz \tmp7\().8h, \tmp8\().8h, v25, v27, \sz + rshrn_sz v4, v0.8h, v1.8h, #3, \sz // out p0 + + add_sz v0.8h, v1.8h, v0.8h, v1.8h, \tmp3\().8h, \tmp4\().8h, \sz + sub_sz \tmp7\().8h, \tmp8\().8h, \tmp7\().8h, \tmp8\().8h, \tmp5\().8h, \tmp6\().8h, \sz + uaddl_sz \tmp1\().8h, \tmp2\().8h, v22, v25, \sz + uaddl_sz \tmp3\().8h, \tmp4\().8h, v26, v27, \sz + rshrn_sz v5, v0.8h, v1.8h, #3, \sz // out q0 + + add_sz v0.8h, v1.8h, v0.8h, v1.8h, \tmp7\().8h, \tmp8\().8h, \sz + sub_sz \tmp3\().8h, \tmp4\().8h, \tmp3\().8h, \tmp4\().8h, \tmp1\().8h, \tmp2\().8h, \sz + rshrn_sz \tmp5, v0.8h, v1.8h, #3, \sz // out q1 + + add_sz v0.8h, v1.8h, v0.8h, v1.8h, \tmp3\().8h, \tmp4\().8h, \sz + // The output here is written back into the input registers. This doesn't + // matter for the flat8part below, since we only update those pixels + // which won't be touched below. + bit v21\sz, v2\sz, v6\sz + bit v22\sz, v3\sz, v6\sz + bit v23\sz, v4\sz, v6\sz + rshrn_sz \tmp6, v0.8h, v1.8h, #3, \sz // out q2 + bit v24\sz, v5\sz, v6\sz + bit v25\sz, \tmp5\sz, v6\sz + bit v26\sz, \tmp6\sz, v6\sz +.endif +.if \wd == 16 +6: + orr v2\sz, v6\sz, v7\sz + mov x5, v2.d[0] +.ifc \sz, .16b + mov x6, v2.d[1] + orr x5, x5, x6 +.endif + // If no pixels needed flat8in nor flat8out, jump to a + // writeout of the inner 4 pixels + cbz x5, 7f + mov x5, v7.d[0] +.ifc \sz, .16b + mov x6, v2.d[1] + orr x5, x5, x6 +.endif + // If no pixels need flat8out, jump to a writeout of the inner 6 pixels + cbz x5, 8f + + // flat8out + // This writes all outputs into v2-v17 (skipping v6 and v16). + // If this part is skipped, the output is read from v21-v26 (which is the input + // to this section). + ushll_sz v0.8h, v1.8h, v16, #3, \sz // 8 * v16 + usubw_sz v0.8h, v1.8h, v0.8h, v1.8h, v16, \sz // 7 * v16 + uaddw_sz v0.8h, v1.8h, v0.8h, v1.8h, v17, \sz + uaddl_sz v8.8h, v9.8h, v17, v18, \sz + uaddl_sz v10.8h, v11.8h, v19, v20, \sz + add_sz v0.8h, v1.8h, v0.8h, v1.8h, v8.8h, v9.8h, \sz + uaddl_sz v8.8h, v9.8h, v16, v17, \sz + uaddl_sz v12.8h, v13.8h, v21, v22, \sz + add_sz v0.8h, v1.8h, v0.8h, v1.8h, v10.8h, v11.8h, \sz + uaddl_sz v10.8h, v11.8h, v18, v25, \sz + uaddl_sz v14.8h, v15.8h, v23, v24, \sz + sub_sz v10.8h, v11.8h, v10.8h, v11.8h, v8.8h, v9.8h, \sz + add_sz v0.8h, v1.8h, v0.8h, v1.8h, v12.8h, v13.8h, \sz + add_sz v0.8h, v1.8h, v0.8h, v1.8h, v14.8h, v15.8h, \sz + uaddl_sz v12.8h, v13.8h, v16, v18, \sz + uaddl_sz v14.8h, v15.8h, v19, v26, \sz + rshrn_sz v2, v0.8h, v1.8h, #4, \sz + + add_sz v0.8h, v1.8h, v0.8h, v1.8h, v10.8h, v11.8h, \sz + uaddl_sz v8.8h, v9.8h, v16, v19, \sz + uaddl_sz v10.8h, v11.8h, v20, v27, \sz + sub_sz v14.8h, v15.8h, v14.8h, v15.8h, v12.8h, v13.8h, \sz + bif v2\sz, v17\sz, v7\sz + rshrn_sz v3, v0.8h, v1.8h, #4, \sz + + add_sz v0.8h, v1.8h, v0.8h, v1.8h, v14.8h, v15.8h, \sz + uaddl_sz v12.8h, v13.8h, v16, v20, \sz + uaddl_sz v14.8h, v15.8h, v21, v28, \sz + sub_sz v10.8h, v11.8h, v10.8h, v11.8h, v8.8h, v9.8h, \sz + bif v3\sz, v18\sz, v7\sz + rshrn_sz v4, v0.8h, v1.8h, #4, \sz + + add_sz v0.8h, v1.8h, v0.8h, v1.8h, v10.8h, v11.8h, \sz + uaddl_sz v8.8h, v9.8h, v16, v21, \sz + uaddl_sz v10.8h, v11.8h, v22, v29, \sz + sub_sz v14.8h, v15.8h, v14.8h, v15.8h, v12.8h, v13.8h, \sz + bif v4\sz, v19\sz, v7\sz + rshrn_sz v5, v0.8h, v1.8h, #4, \sz + + add_sz v0.8h, v1.8h, v0.8h, v1.8h, v14.8h, v15.8h, \sz + uaddl_sz v12.8h, v13.8h, v16, v22, \sz + uaddl_sz v14.8h, v15.8h, v23, v30, \sz + sub_sz v10.8h, v11.8h, v10.8h, v11.8h, v8.8h, v9.8h, \sz + bif v5\sz, v20\sz, v7\sz + rshrn_sz v6, v0.8h, v1.8h, #4, \sz + + add_sz v0.8h, v1.8h, v0.8h, v1.8h, v10.8h, v11.8h, \sz + uaddl_sz v10.8h, v11.8h, v16, v23, \sz + sub_sz v14.8h, v15.8h, v14.8h, v15.8h, v12.8h, v13.8h, \sz + uaddl_sz v12.8h, v13.8h, v24, v31, \sz + bif v6\sz, v21\sz, v7\sz + rshrn_sz v8, v0.8h, v1.8h, #4, \sz + + add_sz v0.8h, v1.8h, v0.8h, v1.8h, v14.8h, v15.8h, \sz + sub_sz v10.8h, v11.8h, v12.8h, v13.8h, v10.8h, v11.8h, \sz + uaddl_sz v12.8h, v13.8h, v17, v24, \sz + uaddl_sz v14.8h, v15.8h, v25, v31, \sz + bif v8\sz, v22\sz, v7\sz + rshrn_sz v9, v0.8h, v1.8h, #4, \sz + + add_sz v0.8h, v1.8h, v0.8h, v1.8h, v10.8h, v11.8h, \sz + sub_sz v14.8h, v15.8h, v14.8h, v15.8h, v12.8h, v13.8h, \sz + uaddl_sz v12.8h, v13.8h, v26, v31, \sz + bif v9\sz, v23\sz, v7\sz + rshrn_sz v10, v0.8h, v1.8h, #4, \sz + + add_sz v0.8h, v1.8h, v0.8h, v1.8h, v14.8h, v15.8h, \sz + uaddl_sz v14.8h, v15.8h, v18, v25, \sz + uaddl_sz v18.8h, v19.8h, v19, v26, \sz + sub_sz v12.8h, v13.8h, v12.8h, v13.8h, v14.8h, v15.8h, \sz + uaddl_sz v14.8h, v15.8h, v27, v31, \sz + bif v10\sz, v24\sz, v7\sz + rshrn_sz v11, v0.8h, v1.8h, #4, \sz + + add_sz v0.8h, v1.8h, v0.8h, v1.8h, v12.8h, v13.8h, \sz + uaddl_sz v12.8h, v13.8h, v20, v27, \sz + sub_sz v14.8h, v15.8h, v14.8h, v15.8h, v18.8h, v19.8h, \sz + uaddl_sz v18.8h, v19.8h, v28, v31, \sz + bif v11\sz, v25\sz, v7\sz + sub_sz v18.8h, v19.8h, v18.8h, v19.8h, v12.8h, v13.8h, \sz + rshrn_sz v12, v0.8h, v1.8h, #4, \sz + + add_sz v0.8h, v1.8h, v0.8h, v1.8h, v14.8h, v15.8h, \sz + uaddl_sz v14.8h, v15.8h, v21, v28, \sz + uaddl_sz v20.8h, v21.8h, v29, v31, \sz + bif v12\sz, v26\sz, v7\sz + rshrn_sz v13, v0.8h, v1.8h, #4, \sz + + add_sz v0.8h, v1.8h, v0.8h, v1.8h, v18.8h, v19.8h, \sz + sub_sz v20.8h, v21.8h, v20.8h, v21.8h, v14.8h, v15.8h, \sz + uaddl_sz v18.8h, v19.8h, v22, v29, \sz + uaddl_sz v22.8h, v23.8h, v30, v31, \sz + bif v13\sz, v27\sz, v7\sz + rshrn_sz v14, v0.8h, v1.8h, #4, \sz + + add_sz v0.8h, v1.8h, v0.8h, v1.8h, v20.8h, v21.8h, \sz + sub_sz v22.8h, v23.8h, v22.8h, v23.8h, v18.8h, v19.8h, \sz + bif v14\sz, v28\sz, v7\sz + rshrn_sz v15, v0.8h, v1.8h, #4, \sz + + add_sz v0.8h, v1.8h, v0.8h, v1.8h, v22.8h, v23.8h, \sz + bif v15\sz, v29\sz, v7\sz + rshrn_sz v17, v0.8h, v1.8h, #4, \sz + bif v17\sz, v30\sz, v7\sz +.endif +.endm + +// For wd <= 8, we use v16-v19 and v28-v31 for temp registers, +// while we need those for inputs/outputs in wd=16 and use v8-v15 +// for temp registers there instead. +function vp9_loop_filter_4 + loop_filter 4, .8b, 0, v16, v17, v18, v19, v28, v29, v30, v31 + ret +9: + br x10 +endfunc + +function vp9_loop_filter_4_16b_mix_44 + loop_filter 4, .16b, 44, v16, v17, v18, v19, v28, v29, v30, v31 + ret +9: + br x10 +endfunc + +function vp9_loop_filter_8 + loop_filter 8, .8b, 0, v16, v17, v18, v19, v28, v29, v30, v31 + mov x5, #0 + ret +6: + mov x5, #6 + ret +9: + br x10 +endfunc + +function vp9_loop_filter_8_16b_mix + loop_filter 8, .16b, 88, v16, v17, v18, v19, v28, v29, v30, v31 + mov x5, #0 + ret +6: + mov x5, #6 + ret +9: + br x10 +endfunc + +function vp9_loop_filter_16 + loop_filter 16, .8b, 0, v8, v9, v10, v11, v12, v13, v14, v15 + mov x5, #0 + ret +7: + mov x5, #7 + ret +8: + mov x5, #8 + ret +9: + ldp d8, d9, [sp], 0x10 + ldp d10, d11, [sp], 0x10 + ldp d12, d13, [sp], 0x10 + ldp d14, d15, [sp], 0x10 + br x10 +endfunc + +function vp9_loop_filter_16_16b + loop_filter 16, .16b, 0, v8, v9, v10, v11, v12, v13, v14, v15 + mov x5, #0 + ret +7: + mov x5, #7 + ret +8: + mov x5, #8 + ret +9: + ldp d8, d9, [sp], 0x10 + ldp d10, d11, [sp], 0x10 + ldp d12, d13, [sp], 0x10 + ldp d14, d15, [sp], 0x10 + br x10 +endfunc + +.macro loop_filter_4 + bl vp9_loop_filter_4 +.endm + +.macro loop_filter_4_16b_mix mix + bl vp9_loop_filter_4_16b_mix_\mix +.endm + +.macro loop_filter_8 + bl vp9_loop_filter_8 + cbnz x5, 6f +.endm + +.macro loop_filter_8_16b_mix mix +.if \mix == 48 + mov x11, #0xffffffff00000000 +.elseif \mix == 84 + mov x11, #0x00000000ffffffff +.else + mov x11, #0xffffffffffffffff +.endif + bl vp9_loop_filter_8_16b_mix + cbnz x5, 6f +.endm + +.macro loop_filter_16 + bl vp9_loop_filter_16 + cmp x5, 7 + b.gt 8f + b.eq 7f +.endm + +.macro loop_filter_16_16b + bl vp9_loop_filter_16_16b + cmp x5, 7 + b.gt 8f + b.eq 7f +.endm + + +// The public functions in this file have got the following signature: +// void loop_filter(uint8_t *dst, ptrdiff_t stride, int mb_lim, int lim, int hev_thr); + +function ff_vp9_loop_filter_v_4_8_neon, export=1 + mov x10, x30 + sub x9, x0, x1, lsl #2 + ld1 {v20.8b}, [x9], x1 // p3 + ld1 {v24.8b}, [x0], x1 // q0 + ld1 {v21.8b}, [x9], x1 // p2 + ld1 {v25.8b}, [x0], x1 // q1 + ld1 {v22.8b}, [x9], x1 // p1 + ld1 {v26.8b}, [x0], x1 // q2 + ld1 {v23.8b}, [x9], x1 // p0 + ld1 {v27.8b}, [x0], x1 // q3 + sub x0, x0, x1, lsl #2 + sub x9, x9, x1, lsl #1 + + loop_filter_4 + + st1 {v22.8b}, [x9], x1 + st1 {v24.8b}, [x0], x1 + st1 {v23.8b}, [x9], x1 + st1 {v25.8b}, [x0], x1 + + br x10 +endfunc + +function ff_vp9_loop_filter_v_44_16_neon, export=1 + mov x10, x30 + sub x9, x0, x1, lsl #2 + ld1 {v20.16b}, [x9], x1 // p3 + ld1 {v24.16b}, [x0], x1 // q0 + ld1 {v21.16b}, [x9], x1 // p2 + ld1 {v25.16b}, [x0], x1 // q1 + ld1 {v22.16b}, [x9], x1 // p1 + ld1 {v26.16b}, [x0], x1 // q2 + ld1 {v23.16b}, [x9], x1 // p0 + ld1 {v27.16b}, [x0], x1 // q3 + sub x0, x0, x1, lsl #2 + sub x9, x9, x1, lsl #1 + + loop_filter_4_16b_mix 44 + + st1 {v22.16b}, [x9], x1 + st1 {v24.16b}, [x0], x1 + st1 {v23.16b}, [x9], x1 + st1 {v25.16b}, [x0], x1 + + br x10 +endfunc + +function ff_vp9_loop_filter_h_4_8_neon, export=1 + mov x10, x30 + sub x9, x0, #4 + add x0, x9, x1, lsl #2 + ld1 {v20.8b}, [x9], x1 + ld1 {v24.8b}, [x0], x1 + ld1 {v21.8b}, [x9], x1 + ld1 {v25.8b}, [x0], x1 + ld1 {v22.8b}, [x9], x1 + ld1 {v26.8b}, [x0], x1 + ld1 {v23.8b}, [x9], x1 + ld1 {v27.8b}, [x0], x1 + + sub x9, x9, x1, lsl #2 + sub x0, x0, x1, lsl #2 + // Move x0/x9 forward by 2 pixels; we don't need to rewrite the + // outermost 2 pixels since they aren't changed. + add x9, x9, #2 + add x0, x0, #2 + + transpose_8x8B v20, v21, v22, v23, v24, v25, v26, v27, v28, v29 + + loop_filter_4 + + // We only will write the mid 4 pixels back; after the loop filter, + // these are in v22, v23, v24, v25, ordered as rows (8x4 pixels). + // We need to transpose them to columns, done with a 4x8 transpose + // (which in practice is two 4x4 transposes of the two 4x4 halves + // of the 8x4 pixels; into 4x8 pixels). + transpose_4x8B v22, v23, v24, v25, v26, v27, v28, v29 + st1 {v22.s}[0], [x9], x1 + st1 {v22.s}[1], [x0], x1 + st1 {v23.s}[0], [x9], x1 + st1 {v23.s}[1], [x0], x1 + st1 {v24.s}[0], [x9], x1 + st1 {v24.s}[1], [x0], x1 + st1 {v25.s}[0], [x9], x1 + st1 {v25.s}[1], [x0], x1 + + br x10 +endfunc + +function ff_vp9_loop_filter_h_44_16_neon, export=1 + mov x10, x30 + sub x9, x0, #4 + add x0, x9, x1, lsl #3 + ld1 {v20.8b}, [x9], x1 + ld1 {v20.d}[1], [x0], x1 + ld1 {v21.8b}, [x9], x1 + ld1 {v21.d}[1], [x0], x1 + ld1 {v22.8b}, [x9], x1 + ld1 {v22.d}[1], [x0], x1 + ld1 {v23.8b}, [x9], x1 + ld1 {v23.d}[1], [x0], x1 + ld1 {v24.8b}, [x9], x1 + ld1 {v24.d}[1], [x0], x1 + ld1 {v25.8b}, [x9], x1 + ld1 {v25.d}[1], [x0], x1 + ld1 {v26.8b}, [x9], x1 + ld1 {v26.d}[1], [x0], x1 + ld1 {v27.8b}, [x9], x1 + ld1 {v27.d}[1], [x0], x1 + + sub x9, x9, x1, lsl #3 + sub x0, x0, x1, lsl #3 + add x9, x9, #2 + add x0, x0, #2 + + transpose_8x16B v20, v21, v22, v23, v24, v25, v26, v27, v28, v29 + + loop_filter_4_16b_mix 44 + + transpose_4x16B v22, v23, v24, v25, v26, v27, v28, v29 + + st1 {v22.s}[0], [x9], x1 + st1 {v22.s}[2], [x0], x1 + st1 {v23.s}[0], [x9], x1 + st1 {v23.s}[2], [x0], x1 + st1 {v24.s}[0], [x9], x1 + st1 {v24.s}[2], [x0], x1 + st1 {v25.s}[0], [x9], x1 + st1 {v25.s}[2], [x0], x1 + st1 {v22.s}[1], [x9], x1 + st1 {v22.s}[3], [x0], x1 + st1 {v23.s}[1], [x9], x1 + st1 {v23.s}[3], [x0], x1 + st1 {v24.s}[1], [x9], x1 + st1 {v24.s}[3], [x0], x1 + st1 {v25.s}[1], [x9], x1 + st1 {v25.s}[3], [x0], x1 + + br x10 +endfunc + +function ff_vp9_loop_filter_v_8_8_neon, export=1 + mov x10, x30 + sub x9, x0, x1, lsl #2 + ld1 {v20.8b}, [x9], x1 // p3 + ld1 {v24.8b}, [x0], x1 // q0 + ld1 {v21.8b}, [x9], x1 // p2 + ld1 {v25.8b}, [x0], x1 // q1 + ld1 {v22.8b}, [x9], x1 // p1 + ld1 {v26.8b}, [x0], x1 // q2 + ld1 {v23.8b}, [x9], x1 // p0 + ld1 {v27.8b}, [x0], x1 // q3 + sub x9, x9, x1, lsl #2 + sub x0, x0, x1, lsl #2 + add x9, x9, x1 + + loop_filter_8 + + st1 {v21.8b}, [x9], x1 + st1 {v24.8b}, [x0], x1 + st1 {v22.8b}, [x9], x1 + st1 {v25.8b}, [x0], x1 + st1 {v23.8b}, [x9], x1 + st1 {v26.8b}, [x0], x1 + + br x10 +6: + sub x9, x0, x1, lsl #1 + st1 {v22.8b}, [x9], x1 + st1 {v24.8b}, [x0], x1 + st1 {v23.8b}, [x9], x1 + st1 {v25.8b}, [x0], x1 + br x10 +endfunc + +.macro mix_v_16 mix +function ff_vp9_loop_filter_v_\mix\()_16_neon, export=1 + mov x10, x30 + sub x9, x0, x1, lsl #2 + ld1 {v20.16b}, [x9], x1 // p3 + ld1 {v24.16b}, [x0], x1 // q0 + ld1 {v21.16b}, [x9], x1 // p2 + ld1 {v25.16b}, [x0], x1 // q1 + ld1 {v22.16b}, [x9], x1 // p1 + ld1 {v26.16b}, [x0], x1 // q2 + ld1 {v23.16b}, [x9], x1 // p0 + ld1 {v27.16b}, [x0], x1 // q3 + sub x9, x9, x1, lsl #2 + sub x0, x0, x1, lsl #2 + add x9, x9, x1 + + loop_filter_8_16b_mix \mix + + st1 {v21.16b}, [x9], x1 + st1 {v24.16b}, [x0], x1 + st1 {v22.16b}, [x9], x1 + st1 {v25.16b}, [x0], x1 + st1 {v23.16b}, [x9], x1 + st1 {v26.16b}, [x0], x1 + + br x10 +6: + sub x9, x0, x1, lsl #1 + st1 {v22.16b}, [x9], x1 + st1 {v24.16b}, [x0], x1 + st1 {v23.16b}, [x9], x1 + st1 {v25.16b}, [x0], x1 + br x10 +endfunc +.endm + +mix_v_16 48 +mix_v_16 84 +mix_v_16 88 + +function ff_vp9_loop_filter_h_8_8_neon, export=1 + mov x10, x30 + sub x9, x0, #4 + add x0, x9, x1, lsl #2 + ld1 {v20.8b}, [x9], x1 + ld1 {v24.8b}, [x0], x1 + ld1 {v21.8b}, [x9], x1 + ld1 {v25.8b}, [x0], x1 + ld1 {v22.8b}, [x9], x1 + ld1 {v26.8b}, [x0], x1 + ld1 {v23.8b}, [x9], x1 + ld1 {v27.8b}, [x0], x1 + + sub x9, x9, x1, lsl #2 + sub x0, x0, x1, lsl #2 + + transpose_8x8B v20, v21, v22, v23, v24, v25, v26, v27, v28, v29 + + loop_filter_8 + + // Even though only 6 pixels per row have been changed, we write the + // full 8 pixel registers. + transpose_8x8B v20, v21, v22, v23, v24, v25, v26, v27, v28, v29 + + st1 {v20.8b}, [x9], x1 + st1 {v24.8b}, [x0], x1 + st1 {v21.8b}, [x9], x1 + st1 {v25.8b}, [x0], x1 + st1 {v22.8b}, [x9], x1 + st1 {v26.8b}, [x0], x1 + st1 {v23.8b}, [x9], x1 + st1 {v27.8b}, [x0], x1 + + br x10 +6: + // If we didn't need to do the flat8in part, we use the same writeback + // as in loop_filter_h_4_8. + add x9, x9, #2 + add x0, x0, #2 + transpose_4x8B v22, v23, v24, v25, v26, v27, v28, v29 + st1 {v22.s}[0], [x9], x1 + st1 {v22.s}[1], [x0], x1 + st1 {v23.s}[0], [x9], x1 + st1 {v23.s}[1], [x0], x1 + st1 {v24.s}[0], [x9], x1 + st1 {v24.s}[1], [x0], x1 + st1 {v25.s}[0], [x9], x1 + st1 {v25.s}[1], [x0], x1 + br x10 +endfunc + +.macro mix_h_16 mix +function ff_vp9_loop_filter_h_\mix\()_16_neon, export=1 + mov x10, x30 + sub x9, x0, #4 + add x0, x9, x1, lsl #3 + ld1 {v20.8b}, [x9], x1 + ld1 {v20.d}[1], [x0], x1 + ld1 {v21.8b}, [x9], x1 + ld1 {v21.d}[1], [x0], x1 + ld1 {v22.8b}, [x9], x1 + ld1 {v22.d}[1], [x0], x1 + ld1 {v23.8b}, [x9], x1 + ld1 {v23.d}[1], [x0], x1 + ld1 {v24.8b}, [x9], x1 + ld1 {v24.d}[1], [x0], x1 + ld1 {v25.8b}, [x9], x1 + ld1 {v25.d}[1], [x0], x1 + ld1 {v26.8b}, [x9], x1 + ld1 {v26.d}[1], [x0], x1 + ld1 {v27.8b}, [x9], x1 + ld1 {v27.d}[1], [x0], x1 + + sub x9, x9, x1, lsl #3 + sub x0, x0, x1, lsl #3 + + transpose_8x16B v20, v21, v22, v23, v24, v25, v26, v27, v28, v29 + + loop_filter_8_16b_mix \mix + + transpose_8x16B v20, v21, v22, v23, v24, v25, v26, v27, v28, v29 + + st1 {v20.8b}, [x9], x1 + st1 {v20.d}[1], [x0], x1 + st1 {v21.8b}, [x9], x1 + st1 {v21.d}[1], [x0], x1 + st1 {v22.8b}, [x9], x1 + st1 {v22.d}[1], [x0], x1 + st1 {v23.8b}, [x9], x1 + st1 {v23.d}[1], [x0], x1 + st1 {v24.8b}, [x9], x1 + st1 {v24.d}[1], [x0], x1 + st1 {v25.8b}, [x9], x1 + st1 {v25.d}[1], [x0], x1 + st1 {v26.8b}, [x9], x1 + st1 {v26.d}[1], [x0], x1 + st1 {v27.8b}, [x9], x1 + st1 {v27.d}[1], [x0], x1 + + br x10 +6: + add x9, x9, #2 + add x0, x0, #2 + transpose_4x16B v22, v23, v24, v25, v26, v27, v28, v29 + st1 {v22.s}[0], [x9], x1 + st1 {v22.s}[2], [x0], x1 + st1 {v23.s}[0], [x9], x1 + st1 {v23.s}[2], [x0], x1 + st1 {v24.s}[0], [x9], x1 + st1 {v24.s}[2], [x0], x1 + st1 {v25.s}[0], [x9], x1 + st1 {v25.s}[2], [x0], x1 + st1 {v22.s}[1], [x9], x1 + st1 {v22.s}[3], [x0], x1 + st1 {v23.s}[1], [x9], x1 + st1 {v23.s}[3], [x0], x1 + st1 {v24.s}[1], [x9], x1 + st1 {v24.s}[3], [x0], x1 + st1 {v25.s}[1], [x9], x1 + st1 {v25.s}[3], [x0], x1 + br x10 +endfunc +.endm + +mix_h_16 48 +mix_h_16 84 +mix_h_16 88 + +function ff_vp9_loop_filter_v_16_8_neon, export=1 + mov x10, x30 + stp d14, d15, [sp, #-0x10]! + stp d12, d13, [sp, #-0x10]! + stp d10, d11, [sp, #-0x10]! + stp d8, d9, [sp, #-0x10]! + sub x9, x0, x1, lsl #3 + ld1 {v16.8b}, [x9], x1 // p7 + ld1 {v24.8b}, [x0], x1 // q0 + ld1 {v17.8b}, [x9], x1 // p6 + ld1 {v25.8b}, [x0], x1 // q1 + ld1 {v18.8b}, [x9], x1 // p5 + ld1 {v26.8b}, [x0], x1 // q2 + ld1 {v19.8b}, [x9], x1 // p4 + ld1 {v27.8b}, [x0], x1 // q3 + ld1 {v20.8b}, [x9], x1 // p3 + ld1 {v28.8b}, [x0], x1 // q4 + ld1 {v21.8b}, [x9], x1 // p2 + ld1 {v29.8b}, [x0], x1 // q5 + ld1 {v22.8b}, [x9], x1 // p1 + ld1 {v30.8b}, [x0], x1 // q6 + ld1 {v23.8b}, [x9], x1 // p0 + ld1 {v31.8b}, [x0], x1 // q7 + sub x9, x9, x1, lsl #3 + sub x0, x0, x1, lsl #3 + add x9, x9, x1 + + loop_filter_16 + + // If we did the flat8out part, we get the output in + // v2-v17 (skipping v7 and v16). x9 points to x0 - 7 * stride, + // store v2-v9 there, and v10-v17 into x0. + st1 {v2.8b}, [x9], x1 + st1 {v10.8b}, [x0], x1 + st1 {v3.8b}, [x9], x1 + st1 {v11.8b}, [x0], x1 + st1 {v4.8b}, [x9], x1 + st1 {v12.8b}, [x0], x1 + st1 {v5.8b}, [x9], x1 + st1 {v13.8b}, [x0], x1 + st1 {v6.8b}, [x9], x1 + st1 {v14.8b}, [x0], x1 + st1 {v8.8b}, [x9], x1 + st1 {v15.8b}, [x0], x1 + st1 {v9.8b}, [x9], x1 + st1 {v17.8b}, [x0], x1 +9: + ldp d8, d9, [sp], 0x10 + ldp d10, d11, [sp], 0x10 + ldp d12, d13, [sp], 0x10 + ldp d14, d15, [sp], 0x10 + br x10 +8: + add x9, x9, x1, lsl #2 + // If we didn't do the flat8out part, the output is left in the + // input registers. + st1 {v21.8b}, [x9], x1 + st1 {v24.8b}, [x0], x1 + st1 {v22.8b}, [x9], x1 + st1 {v25.8b}, [x0], x1 + st1 {v23.8b}, [x9], x1 + st1 {v26.8b}, [x0], x1 + b 9b +7: + sub x9, x0, x1, lsl #1 + st1 {v22.8b}, [x9], x1 + st1 {v24.8b}, [x0], x1 + st1 {v23.8b}, [x9], x1 + st1 {v25.8b}, [x0], x1 + b 9b +endfunc + +function ff_vp9_loop_filter_v_16_16_neon, export=1 + mov x10, x30 + stp d14, d15, [sp, #-0x10]! + stp d12, d13, [sp, #-0x10]! + stp d10, d11, [sp, #-0x10]! + stp d8, d9, [sp, #-0x10]! + sub x9, x0, x1, lsl #3 + ld1 {v16.16b}, [x9], x1 // p7 + ld1 {v24.16b}, [x0], x1 // q0 + ld1 {v17.16b}, [x9], x1 // p6 + ld1 {v25.16b}, [x0], x1 // q1 + ld1 {v18.16b}, [x9], x1 // p5 + ld1 {v26.16b}, [x0], x1 // q2 + ld1 {v19.16b}, [x9], x1 // p4 + ld1 {v27.16b}, [x0], x1 // q3 + ld1 {v20.16b}, [x9], x1 // p3 + ld1 {v28.16b}, [x0], x1 // q4 + ld1 {v21.16b}, [x9], x1 // p2 + ld1 {v29.16b}, [x0], x1 // q5 + ld1 {v22.16b}, [x9], x1 // p1 + ld1 {v30.16b}, [x0], x1 // q6 + ld1 {v23.16b}, [x9], x1 // p0 + ld1 {v31.16b}, [x0], x1 // q7 + sub x9, x9, x1, lsl #3 + sub x0, x0, x1, lsl #3 + add x9, x9, x1 + + loop_filter_16_16b + + st1 {v2.16b}, [x9], x1 + st1 {v10.16b}, [x0], x1 + st1 {v3.16b}, [x9], x1 + st1 {v11.16b}, [x0], x1 + st1 {v4.16b}, [x9], x1 + st1 {v12.16b}, [x0], x1 + st1 {v5.16b}, [x9], x1 + st1 {v13.16b}, [x0], x1 + st1 {v6.16b}, [x9], x1 + st1 {v14.16b}, [x0], x1 + st1 {v8.16b}, [x9], x1 + st1 {v15.16b}, [x0], x1 + st1 {v9.16b}, [x9], x1 + st1 {v17.16b}, [x0], x1 +9: + ldp d8, d9, [sp], 0x10 + ldp d10, d11, [sp], 0x10 + ldp d12, d13, [sp], 0x10 + ldp d14, d15, [sp], 0x10 + br x10 +8: + add x9, x9, x1, lsl #2 + st1 {v21.16b}, [x9], x1 + st1 {v24.16b}, [x0], x1 + st1 {v22.16b}, [x9], x1 + st1 {v25.16b}, [x0], x1 + st1 {v23.16b}, [x9], x1 + st1 {v26.16b}, [x0], x1 + b 9b +7: + sub x9, x0, x1, lsl #1 + st1 {v22.16b}, [x9], x1 + st1 {v24.16b}, [x0], x1 + st1 {v23.16b}, [x9], x1 + st1 {v25.16b}, [x0], x1 + b 9b +endfunc + +function ff_vp9_loop_filter_h_16_8_neon, export=1 + mov x10, x30 + stp d14, d15, [sp, #-0x10]! + stp d12, d13, [sp, #-0x10]! + stp d10, d11, [sp, #-0x10]! + stp d8, d9, [sp, #-0x10]! + sub x9, x0, #8 + ld1 {v16.8b}, [x9], x1 + ld1 {v24.8b}, [x0], x1 + ld1 {v17.8b}, [x9], x1 + ld1 {v25.8b}, [x0], x1 + ld1 {v18.8b}, [x9], x1 + ld1 {v26.8b}, [x0], x1 + ld1 {v19.8b}, [x9], x1 + ld1 {v27.8b}, [x0], x1 + ld1 {v20.8b}, [x9], x1 + ld1 {v28.8b}, [x0], x1 + ld1 {v21.8b}, [x9], x1 + ld1 {v29.8b}, [x0], x1 + ld1 {v22.8b}, [x9], x1 + ld1 {v30.8b}, [x0], x1 + ld1 {v23.8b}, [x9], x1 + ld1 {v31.8b}, [x0], x1 + sub x0, x0, x1, lsl #3 + sub x9, x9, x1, lsl #3 + + // The 16x8 pixels read above is in two 8x8 blocks; the left + // half in v16-v23, and the right half in v24-v31. Do two 8x8 transposes + // of this, to get one column per register. + transpose_8x8B v16, v17, v18, v19, v20, v21, v22, v23, v0, v1 + transpose_8x8B v24, v25, v26, v27, v28, v29, v30, v31, v0, v1 + + loop_filter_16 + + transpose_8x8B v16, v2, v3, v4, v5, v6, v8, v9, v0, v1 + transpose_8x8B v10, v11, v12, v13, v14, v15, v17, v31, v0, v1 + + st1 {v16.8b}, [x9], x1 + st1 {v10.8b}, [x0], x1 + st1 {v2.8b}, [x9], x1 + st1 {v11.8b}, [x0], x1 + st1 {v3.8b}, [x9], x1 + st1 {v12.8b}, [x0], x1 + st1 {v4.8b}, [x9], x1 + st1 {v13.8b}, [x0], x1 + st1 {v5.8b}, [x9], x1 + st1 {v14.8b}, [x0], x1 + st1 {v6.8b}, [x9], x1 + st1 {v15.8b}, [x0], x1 + st1 {v8.8b}, [x9], x1 + st1 {v17.8b}, [x0], x1 + st1 {v9.8b}, [x9], x1 + st1 {v31.8b}, [x0], x1 +9: + ldp d8, d9, [sp], 0x10 + ldp d10, d11, [sp], 0x10 + ldp d12, d13, [sp], 0x10 + ldp d14, d15, [sp], 0x10 + br x10 +8: + // The same writeback as in loop_filter_h_8_8 + sub x9, x0, #4 + add x0, x9, x1, lsl #2 + transpose_8x8B v20, v21, v22, v23, v24, v25, v26, v27, v28, v29 + + st1 {v20.8b}, [x9], x1 + st1 {v24.8b}, [x0], x1 + st1 {v21.8b}, [x9], x1 + st1 {v25.8b}, [x0], x1 + st1 {v22.8b}, [x9], x1 + st1 {v26.8b}, [x0], x1 + st1 {v23.8b}, [x9], x1 + st1 {v27.8b}, [x0], x1 + b 9b +7: + // The same writeback as in loop_filter_h_4_8 + sub x9, x0, #2 + add x0, x9, x1, lsl #2 + transpose_4x8B v22, v23, v24, v25, v26, v27, v28, v29 + st1 {v22.s}[0], [x9], x1 + st1 {v22.s}[1], [x0], x1 + st1 {v23.s}[0], [x9], x1 + st1 {v23.s}[1], [x0], x1 + st1 {v24.s}[0], [x9], x1 + st1 {v24.s}[1], [x0], x1 + st1 {v25.s}[0], [x9], x1 + st1 {v25.s}[1], [x0], x1 + b 9b +endfunc + +function ff_vp9_loop_filter_h_16_16_neon, export=1 + mov x10, x30 + stp d14, d15, [sp, #-0x10]! + stp d12, d13, [sp, #-0x10]! + stp d10, d11, [sp, #-0x10]! + stp d8, d9, [sp, #-0x10]! + sub x9, x0, #8 + ld1 {v16.8b}, [x9], x1 + ld1 {v24.8b}, [x0], x1 + ld1 {v17.8b}, [x9], x1 + ld1 {v25.8b}, [x0], x1 + ld1 {v18.8b}, [x9], x1 + ld1 {v26.8b}, [x0], x1 + ld1 {v19.8b}, [x9], x1 + ld1 {v27.8b}, [x0], x1 + ld1 {v20.8b}, [x9], x1 + ld1 {v28.8b}, [x0], x1 + ld1 {v21.8b}, [x9], x1 + ld1 {v29.8b}, [x0], x1 + ld1 {v22.8b}, [x9], x1 + ld1 {v30.8b}, [x0], x1 + ld1 {v23.8b}, [x9], x1 + ld1 {v31.8b}, [x0], x1 + ld1 {v16.d}[1], [x9], x1 + ld1 {v24.d}[1], [x0], x1 + ld1 {v17.d}[1], [x9], x1 + ld1 {v25.d}[1], [x0], x1 + ld1 {v18.d}[1], [x9], x1 + ld1 {v26.d}[1], [x0], x1 + ld1 {v19.d}[1], [x9], x1 + ld1 {v27.d}[1], [x0], x1 + ld1 {v20.d}[1], [x9], x1 + ld1 {v28.d}[1], [x0], x1 + ld1 {v21.d}[1], [x9], x1 + ld1 {v29.d}[1], [x0], x1 + ld1 {v22.d}[1], [x9], x1 + ld1 {v30.d}[1], [x0], x1 + ld1 {v23.d}[1], [x9], x1 + ld1 {v31.d}[1], [x0], x1 + sub x0, x0, x1, lsl #4 + sub x9, x9, x1, lsl #4 + + transpose_8x16B v16, v17, v18, v19, v20, v21, v22, v23, v0, v1 + transpose_8x16B v24, v25, v26, v27, v28, v29, v30, v31, v0, v1 + + loop_filter_16_16b + + transpose_8x16B v16, v2, v3, v4, v5, v6, v8, v9, v0, v1 + transpose_8x16B v10, v11, v12, v13, v14, v15, v17, v31, v0, v1 + + st1 {v16.8b}, [x9], x1 + st1 {v10.8b}, [x0], x1 + st1 {v2.8b}, [x9], x1 + st1 {v11.8b}, [x0], x1 + st1 {v3.8b}, [x9], x1 + st1 {v12.8b}, [x0], x1 + st1 {v4.8b}, [x9], x1 + st1 {v13.8b}, [x0], x1 + st1 {v5.8b}, [x9], x1 + st1 {v14.8b}, [x0], x1 + st1 {v6.8b}, [x9], x1 + st1 {v15.8b}, [x0], x1 + st1 {v8.8b}, [x9], x1 + st1 {v17.8b}, [x0], x1 + st1 {v9.8b}, [x9], x1 + st1 {v31.8b}, [x0], x1 + st1 {v16.d}[1], [x9], x1 + st1 {v10.d}[1], [x0], x1 + st1 {v2.d}[1], [x9], x1 + st1 {v11.d}[1], [x0], x1 + st1 {v3.d}[1], [x9], x1 + st1 {v12.d}[1], [x0], x1 + st1 {v4.d}[1], [x9], x1 + st1 {v13.d}[1], [x0], x1 + st1 {v5.d}[1], [x9], x1 + st1 {v14.d}[1], [x0], x1 + st1 {v6.d}[1], [x9], x1 + st1 {v15.d}[1], [x0], x1 + st1 {v8.d}[1], [x9], x1 + st1 {v17.d}[1], [x0], x1 + st1 {v9.d}[1], [x9], x1 + st1 {v31.d}[1], [x0], x1 +9: + ldp d8, d9, [sp], 0x10 + ldp d10, d11, [sp], 0x10 + ldp d12, d13, [sp], 0x10 + ldp d14, d15, [sp], 0x10 + br x10 +8: + sub x9, x0, #4 + add x0, x9, x1, lsl #3 + transpose_8x16B v20, v21, v22, v23, v24, v25, v26, v27, v28, v29 + + st1 {v20.8b}, [x9], x1 + st1 {v20.d}[1], [x0], x1 + st1 {v21.8b}, [x9], x1 + st1 {v21.d}[1], [x0], x1 + st1 {v22.8b}, [x9], x1 + st1 {v22.d}[1], [x0], x1 + st1 {v23.8b}, [x9], x1 + st1 {v23.d}[1], [x0], x1 + st1 {v24.8b}, [x9], x1 + st1 {v24.d}[1], [x0], x1 + st1 {v25.8b}, [x9], x1 + st1 {v25.d}[1], [x0], x1 + st1 {v26.8b}, [x9], x1 + st1 {v26.d}[1], [x0], x1 + st1 {v27.8b}, [x9], x1 + st1 {v27.d}[1], [x0], x1 + b 9b +7: + sub x9, x0, #2 + add x0, x9, x1, lsl #3 + transpose_4x16B v22, v23, v24, v25, v26, v27, v28, v29 + st1 {v22.s}[0], [x9], x1 + st1 {v22.s}[2], [x0], x1 + st1 {v23.s}[0], [x9], x1 + st1 {v23.s}[2], [x0], x1 + st1 {v24.s}[0], [x9], x1 + st1 {v24.s}[2], [x0], x1 + st1 {v25.s}[0], [x9], x1 + st1 {v25.s}[2], [x0], x1 + st1 {v22.s}[1], [x9], x1 + st1 {v22.s}[3], [x0], x1 + st1 {v23.s}[1], [x9], x1 + st1 {v23.s}[3], [x0], x1 + st1 {v24.s}[1], [x9], x1 + st1 {v24.s}[3], [x0], x1 + st1 {v25.s}[1], [x9], x1 + st1 {v25.s}[3], [x0], x1 + b 9b +endfunc From 3c9546dfafcdfe8e7860aff9ebbf609318220f29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 13 Nov 2016 23:53:08 +0200 Subject: [PATCH 0463/3374] aarch64: vp9: Add NEON itxfm routines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. These are ported from the ARM version; thanks to the larger amount of registers available, we can do the 16x16 and 32x32 transforms in slices 8 pixels wide instead of 4. This gives a speedup of around 1.4x compared to the 32 bit version. The fact that aarch64 doesn't have the same d/q register aliasing makes some of the macros quite a bit simpler as well. Examples of runtimes vs the 32 bit version, on a Cortex A53: ARM AArch64 vp9_inv_adst_adst_4x4_add_neon: 90.0 87.7 vp9_inv_adst_adst_8x8_add_neon: 400.0 354.7 vp9_inv_adst_adst_16x16_add_neon: 2526.5 1827.2 vp9_inv_dct_dct_4x4_add_neon: 74.0 72.7 vp9_inv_dct_dct_8x8_add_neon: 271.0 256.7 vp9_inv_dct_dct_16x16_add_neon: 1960.7 1372.7 vp9_inv_dct_dct_32x32_add_neon: 11988.9 8088.3 vp9_inv_wht_wht_4x4_add_neon: 63.0 57.7 The speedup vs C code (2-4x) is smaller than in the 32 bit case, mostly because the C code ends up significantly faster (around 1.6x faster, with GCC 5.4) when built for aarch64. Examples of runtimes vs C on a Cortex A57 (for a slightly older version of the patch): A57 gcc-5.3 neon vp9_inv_adst_adst_4x4_add_neon: 152.2 60.0 vp9_inv_adst_adst_8x8_add_neon: 948.2 288.0 vp9_inv_adst_adst_16x16_add_neon: 4830.4 1380.5 vp9_inv_dct_dct_4x4_add_neon: 153.0 58.6 vp9_inv_dct_dct_8x8_add_neon: 789.2 180.2 vp9_inv_dct_dct_16x16_add_neon: 3639.6 917.1 vp9_inv_dct_dct_32x32_add_neon: 20462.1 4985.0 vp9_inv_wht_wht_4x4_add_neon: 91.0 49.8 The asm is around factor 3-4 faster than C on the cortex-a57 and the asm is around 30-50% faster on the a57 compared to the a53. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/Makefile | 3 +- libavcodec/aarch64/vp9dsp_init_aarch64.c | 51 +- libavcodec/aarch64/vp9itxfm_neon.S | 1116 ++++++++++++++++++++++ 3 files changed, 1168 insertions(+), 2 deletions(-) create mode 100644 libavcodec/aarch64/vp9itxfm_neon.S diff --git a/libavcodec/aarch64/Makefile b/libavcodec/aarch64/Makefile index 6f1227a004e32..0b06b33b55920 100644 --- a/libavcodec/aarch64/Makefile +++ b/libavcodec/aarch64/Makefile @@ -44,4 +44,5 @@ NEON-OBJS-$(CONFIG_MPEGAUDIODSP) += aarch64/mpegaudiodsp_neon.o NEON-OBJS-$(CONFIG_DCA_DECODER) += aarch64/dcadsp_neon.o \ aarch64/synth_filter_neon.o NEON-OBJS-$(CONFIG_VORBIS_DECODER) += aarch64/vorbisdsp_neon.o -NEON-OBJS-$(CONFIG_VP9_DECODER) += aarch64/vp9mc_neon.o +NEON-OBJS-$(CONFIG_VP9_DECODER) += aarch64/vp9itxfm_neon.o \ + aarch64/vp9mc_neon.o diff --git a/libavcodec/aarch64/vp9dsp_init_aarch64.c b/libavcodec/aarch64/vp9dsp_init_aarch64.c index 5c4175b3f167e..da6f7f9cbf823 100644 --- a/libavcodec/aarch64/vp9dsp_init_aarch64.c +++ b/libavcodec/aarch64/vp9dsp_init_aarch64.c @@ -96,7 +96,7 @@ define_8tap_2d_funcs(16) define_8tap_2d_funcs(8) define_8tap_2d_funcs(4) -av_cold void ff_vp9dsp_init_aarch64(VP9DSPContext *dsp) +static av_cold void vp9dsp_mc_init_aarch64(VP9DSPContext *dsp) { int cpu_flags = av_get_cpu_flags(); @@ -151,3 +151,52 @@ av_cold void ff_vp9dsp_init_aarch64(VP9DSPContext *dsp) init_mc_funcs_dirs(4, 4); } } + +#define define_itxfm(type_a, type_b, sz) \ +void ff_vp9_##type_a##_##type_b##_##sz##x##sz##_add_neon(uint8_t *_dst, \ + ptrdiff_t stride, \ + int16_t *_block, int eob) + +#define define_itxfm_funcs(sz) \ + define_itxfm(idct, idct, sz); \ + define_itxfm(iadst, idct, sz); \ + define_itxfm(idct, iadst, sz); \ + define_itxfm(iadst, iadst, sz) + +define_itxfm_funcs(4); +define_itxfm_funcs(8); +define_itxfm_funcs(16); +define_itxfm(idct, idct, 32); +define_itxfm(iwht, iwht, 4); + + +static av_cold void vp9dsp_itxfm_init_aarch64(VP9DSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) { +#define init_itxfm(tx, sz) \ + dsp->itxfm_add[tx][DCT_DCT] = ff_vp9_idct_idct_##sz##_add_neon; \ + dsp->itxfm_add[tx][DCT_ADST] = ff_vp9_iadst_idct_##sz##_add_neon; \ + dsp->itxfm_add[tx][ADST_DCT] = ff_vp9_idct_iadst_##sz##_add_neon; \ + dsp->itxfm_add[tx][ADST_ADST] = ff_vp9_iadst_iadst_##sz##_add_neon + +#define init_idct(tx, nm) \ + dsp->itxfm_add[tx][DCT_DCT] = \ + dsp->itxfm_add[tx][ADST_DCT] = \ + dsp->itxfm_add[tx][DCT_ADST] = \ + dsp->itxfm_add[tx][ADST_ADST] = ff_vp9_##nm##_add_neon + + init_itxfm(TX_4X4, 4x4); + init_itxfm(TX_8X8, 8x8); + init_itxfm(TX_16X16, 16x16); + init_idct(TX_32X32, idct_idct_32x32); + init_idct(4, iwht_iwht_4x4); + } +} + +av_cold void ff_vp9dsp_init_aarch64(VP9DSPContext *dsp) +{ + vp9dsp_mc_init_aarch64(dsp); + vp9dsp_itxfm_init_aarch64(dsp); +} diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S new file mode 100644 index 0000000000000..9df0725e47fd5 --- /dev/null +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -0,0 +1,1116 @@ +/* + * Copyright (c) 2016 Google Inc. + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/aarch64/asm.S" +#include "neon.S" + +const itxfm4_coeffs, align=4 + .short 11585, 6270, 15137, 0 +iadst4_coeffs: + .short 5283, 15212, 9929, 13377 +endconst + +const iadst8_coeffs, align=4 + .short 16305, 1606, 14449, 7723, 10394, 12665, 4756, 15679 +idct_coeffs: + .short 11585, 6270, 15137, 3196, 16069, 13623, 9102, 1606 + .short 16305, 12665, 10394, 7723, 14449, 15679, 4756, 0 + .short 804, 16364, 12140, 11003, 7005, 14811, 15426, 5520 + .short 3981, 15893, 14053, 8423, 9760, 13160, 16207, 2404 +endconst + +const iadst16_coeffs, align=4 + .short 16364, 804, 15893, 3981, 14811, 7005, 13160, 9760 + .short 11003, 12140, 8423, 14053, 5520, 15426, 2404, 16207 +endconst + +// out1 = ((in1 + in2) * d0[0] + (1 << 13)) >> 14 +// out2 = ((in1 - in2) * d0[0] + (1 << 13)) >> 14 +// in/out are .8h registers; this can do with 4 temp registers, but is +// more efficient if 6 temp registers are available. +.macro dmbutterfly0 out1, out2, in1, in2, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, neg=0 +.if \neg > 0 + neg \tmp4\().4h, v0.4h +.endif + add \tmp1\().8h, \in1\().8h, \in2\().8h + sub \tmp2\().8h, \in1\().8h, \in2\().8h +.if \neg > 0 + smull \tmp3\().4s, \tmp1\().4h, \tmp4\().h[0] + smull2 \tmp4\().4s, \tmp1\().8h, \tmp4\().h[0] +.else + smull \tmp3\().4s, \tmp1\().4h, v0.h[0] + smull2 \tmp4\().4s, \tmp1\().8h, v0.h[0] +.endif +.ifb \tmp5 + rshrn \out1\().4h, \tmp3\().4s, #14 + rshrn2 \out1\().8h, \tmp4\().4s, #14 + smull \tmp3\().4s, \tmp2\().4h, v0.h[0] + smull2 \tmp4\().4s, \tmp2\().8h, v0.h[0] + rshrn \out2\().4h, \tmp3\().4s, #14 + rshrn2 \out2\().8h, \tmp4\().4s, #14 +.else + smull \tmp5\().4s, \tmp2\().4h, v0.h[0] + smull2 \tmp6\().4s, \tmp2\().8h, v0.h[0] + rshrn \out1\().4h, \tmp3\().4s, #14 + rshrn2 \out1\().8h, \tmp4\().4s, #14 + rshrn \out2\().4h, \tmp5\().4s, #14 + rshrn2 \out2\().8h, \tmp6\().4s, #14 +.endif +.endm + +// out1,out2 = in1 * coef1 - in2 * coef2 +// out3,out4 = in1 * coef2 + in2 * coef1 +// out are 4 x .4s registers, in are 2 x .8h registers +.macro dmbutterfly_l out1, out2, out3, out4, in1, in2, coef1, coef2 + smull \out1\().4s, \in1\().4h, \coef1 + smull2 \out2\().4s, \in1\().8h, \coef1 + smull \out3\().4s, \in1\().4h, \coef2 + smull2 \out4\().4s, \in1\().8h, \coef2 + smlsl \out1\().4s, \in2\().4h, \coef2 + smlsl2 \out2\().4s, \in2\().8h, \coef2 + smlal \out3\().4s, \in2\().4h, \coef1 + smlal2 \out4\().4s, \in2\().8h, \coef1 +.endm + +// inout1 = (inout1 * coef1 - inout2 * coef2 + (1 << 13)) >> 14 +// inout2 = (inout1 * coef2 + inout2 * coef1 + (1 << 13)) >> 14 +// inout are 2 x .8h registers +.macro dmbutterfly inout1, inout2, coef1, coef2, tmp1, tmp2, tmp3, tmp4, neg=0 + dmbutterfly_l \tmp1, \tmp2, \tmp3, \tmp4, \inout1, \inout2, \coef1, \coef2 +.if \neg > 0 + neg \tmp3\().4s, \tmp3\().4s + neg \tmp4\().4s, \tmp4\().4s +.endif + rshrn \inout1\().4h, \tmp1\().4s, #14 + rshrn2 \inout1\().8h, \tmp2\().4s, #14 + rshrn \inout2\().4h, \tmp3\().4s, #14 + rshrn2 \inout2\().8h, \tmp4\().4s, #14 +.endm + +// out1 = in1 + in2 +// out2 = in1 - in2 +.macro butterfly_8h out1, out2, in1, in2 + add \out1\().8h, \in1\().8h, \in2\().8h + sub \out2\().8h, \in1\().8h, \in2\().8h +.endm + +// out1 = in1 - in2 +// out2 = in1 + in2 +.macro butterfly_8h_r out1, out2, in1, in2 + sub \out1\().8h, \in1\().8h, \in2\().8h + add \out2\().8h, \in1\().8h, \in2\().8h +.endm + +// out1 = (in1,in2 + in3,in4 + (1 << 13)) >> 14 +// out2 = (in1,in2 - in3,in4 + (1 << 13)) >> 14 +// out are 2 x .8h registers, in are 4 x .4s registers +.macro dbutterfly_n out1, out2, in1, in2, in3, in4, tmp1, tmp2, tmp3, tmp4 + add \tmp1\().4s, \in1\().4s, \in3\().4s + add \tmp2\().4s, \in2\().4s, \in4\().4s + sub \tmp3\().4s, \in1\().4s, \in3\().4s + sub \tmp4\().4s, \in2\().4s, \in4\().4s + rshrn \out1\().4h, \tmp1\().4s, #14 + rshrn2 \out1\().8h, \tmp2\().4s, #14 + rshrn \out2\().4h, \tmp3\().4s, #14 + rshrn2 \out2\().8h, \tmp4\().4s, #14 +.endm + +.macro iwht4 c0, c1, c2, c3 + add \c0\().4h, \c0\().4h, \c1\().4h + sub v17.4h, \c2\().4h, \c3\().4h + sub v16.4h, \c0\().4h, v17.4h + sshr v16.4h, v16.4h, #1 + sub \c2\().4h, v16.4h, \c1\().4h + sub \c1\().4h, v16.4h, \c3\().4h + add \c3\().4h, v17.4h, \c2\().4h + sub \c0\().4h, \c0\().4h, \c1\().4h +.endm + +.macro idct4 c0, c1, c2, c3 + smull v22.4s, \c1\().4h, v0.h[2] + smull v20.4s, \c1\().4h, v0.h[1] + add v16.4h, \c0\().4h, \c2\().4h + sub v17.4h, \c0\().4h, \c2\().4h + smlal v22.4s, \c3\().4h, v0.h[1] + smull v18.4s, v16.4h, v0.h[0] + smull v19.4s, v17.4h, v0.h[0] + smlsl v20.4s, \c3\().4h, v0.h[2] + rshrn v22.4h, v22.4s, #14 + rshrn v18.4h, v18.4s, #14 + rshrn v19.4h, v19.4s, #14 + rshrn v20.4h, v20.4s, #14 + add \c0\().4h, v18.4h, v22.4h + sub \c3\().4h, v18.4h, v22.4h + add \c1\().4h, v19.4h, v20.4h + sub \c2\().4h, v19.4h, v20.4h +.endm + +.macro iadst4 c0, c1, c2, c3 + smull v16.4s, \c0\().4h, v0.h[4] + smlal v16.4s, \c2\().4h, v0.h[5] + smlal v16.4s, \c3\().4h, v0.h[6] + smull v17.4s, \c0\().4h, v0.h[6] + smlsl v17.4s, \c2\().4h, v0.h[4] + sub \c0\().4h, \c0\().4h, \c2\().4h + smlsl v17.4s, \c3\().4h, v0.h[5] + add \c0\().4h, \c0\().4h, \c3\().4h + smull v19.4s, \c1\().4h, v0.h[7] + smull v18.4s, \c0\().4h, v0.h[7] + add v20.4s, v16.4s, v19.4s + add v21.4s, v17.4s, v19.4s + rshrn \c0\().4h, v20.4s, #14 + add v16.4s, v16.4s, v17.4s + rshrn \c1\().4h, v21.4s, #14 + sub v16.4s, v16.4s, v19.4s + rshrn \c2\().4h, v18.4s, #14 + rshrn \c3\().4h, v16.4s, #14 +.endm + +// The public functions in this file have got the following signature: +// void itxfm_add(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob); + +.macro itxfm_func4x4 txfm1, txfm2 +function ff_vp9_\txfm1\()_\txfm2\()_4x4_add_neon, export=1 +.ifc \txfm1,\txfm2 +.ifc \txfm1,idct + movrel x4, itxfm4_coeffs + ld1 {v0.4h}, [x4] +.endif +.ifc \txfm1,iadst + movrel x4, iadst4_coeffs + ld1 {v0.d}[1], [x4] +.endif +.else + movrel x4, itxfm4_coeffs + ld1 {v0.8h}, [x4] +.endif + + movi v31.8h, #0 +.ifc \txfm1\()_\txfm2,idct_idct + cmp x3, #1 + b.ne 1f + // DC-only for idct/idct + ld1r {v2.4h}, [x2] + smull v2.4s, v2.4h, v0.h[0] + rshrn v2.4h, v2.4s, #14 + smull v2.4s, v2.4h, v0.h[0] + rshrn v2.4h, v2.4s, #14 + st1 {v31.h}[0], [x2] + dup v4.4h, v2.h[0] + mov v5.16b, v4.16b + mov v6.16b, v4.16b + mov v7.16b, v4.16b + b 2f +.endif + +1: + ld1 {v4.4h,v5.4h,v6.4h,v7.4h}, [x2] + st1 {v31.8h}, [x2], #16 + +.ifc \txfm1,iwht + sshr v4.4h, v4.4h, #2 + sshr v5.4h, v5.4h, #2 + sshr v6.4h, v6.4h, #2 + sshr v7.4h, v7.4h, #2 +.endif + + \txfm1\()4 v4, v5, v6, v7 + + st1 {v31.8h}, [x2], #16 + // Transpose 4x4 with 16 bit elements + transpose_4x4H v4, v5, v6, v7, v16, v17, v18, v19 + + \txfm2\()4 v4, v5, v6, v7 +2: + ld1r {v0.2s}, [x0], x1 + ld1r {v1.2s}, [x0], x1 +.ifnc \txfm1,iwht + srshr v4.4h, v4.4h, #4 + srshr v5.4h, v5.4h, #4 + srshr v6.4h, v6.4h, #4 + srshr v7.4h, v7.4h, #4 +.endif + uaddw v4.8h, v4.8h, v0.8b + uaddw v5.8h, v5.8h, v1.8b + ld1r {v2.2s}, [x0], x1 + ld1r {v3.2s}, [x0], x1 + sqxtun v0.8b, v4.8h + sqxtun v1.8b, v5.8h + sub x0, x0, x1, lsl #2 + + uaddw v6.8h, v6.8h, v2.8b + uaddw v7.8h, v7.8h, v3.8b + st1 {v0.s}[0], [x0], x1 + sqxtun v2.8b, v6.8h + sqxtun v3.8b, v7.8h + + st1 {v1.s}[0], [x0], x1 + st1 {v2.s}[0], [x0], x1 + st1 {v3.s}[0], [x0], x1 + + ret +endfunc +.endm + +itxfm_func4x4 idct, idct +itxfm_func4x4 iadst, idct +itxfm_func4x4 idct, iadst +itxfm_func4x4 iadst, iadst +itxfm_func4x4 iwht, iwht + + +.macro idct8 + dmbutterfly0 v16, v20, v16, v20, v2, v3, v4, v5, v6, v7 // v16 = t0a, v20 = t1a + dmbutterfly v18, v22, v0.h[1], v0.h[2], v2, v3, v4, v5 // v18 = t2a, v22 = t3a + dmbutterfly v17, v23, v0.h[3], v0.h[4], v2, v3, v4, v5 // v17 = t4a, v23 = t7a + dmbutterfly v21, v19, v0.h[5], v0.h[6], v2, v3, v4, v5 // v21 = t5a, v19 = t6a + + butterfly_8h v24, v25, v16, v22 // v24 = t0, v25 = t3 + butterfly_8h v28, v29, v17, v21 // v28 = t4, v29 = t5a + butterfly_8h v30, v31, v23, v19 // v30 = t7, v31 = t6a + butterfly_8h v26, v27, v20, v18 // v26 = t1, v27 = t2 + + dmbutterfly0 v31, v29, v31, v29, v2, v3, v4, v5, v6, v7 // v31 = t6, v29 = t5 + + butterfly_8h v16, v23, v24, v30 // v16 = out[0], v23 = out[7] + butterfly_8h v17, v22, v26, v31 // v17 = out[1], v22 = out[6] + butterfly_8h v18, v21, v27, v29 // q13 = out[2], q10 = out[5] + butterfly_8h v19, v20, v25, v28 // v17 = out[3], q12 = out[4] +.endm + +.macro iadst8 + dmbutterfly_l v24, v25, v26, v27, v23, v16, v1.h[1], v1.h[0] // v24,v25 = t1a, v26,v27 = t0a + dmbutterfly_l v28, v29, v30, v31, v21, v18, v1.h[3], v1.h[2] // v28,v29 = t3a, v30,v31 = t2a + dmbutterfly_l v2, v3, v4, v5, v19, v20, v1.h[5], v1.h[4] // v2,v3 = t5a, v4,v5 = t4a + dmbutterfly_l v16, v18, v21, v23, v17, v22, v1.h[7], v1.h[6] // v16,v18 = t7a, v21,v23 = t6a + + dbutterfly_n v4, v5, v26, v27, v4, v5, v6, v7, v26, v27 // v4 = t0, v5 = t4 + dbutterfly_n v2, v3, v24, v25, v2, v3, v6, v7, v26, v27 // v2 = t1, v3 = t5 + dbutterfly_n v24, v25, v30, v31, v21, v23, v6, v7, v26, v27 // v24 = t2, v25 = t6 + dbutterfly_n v30, v31, v28, v29, v16, v18, v6, v7, v26, v27 // v30 = t3, v31 = t7 + + butterfly_8h v16, v6, v4, v24 // v16 = out[0], v6 = t2 + butterfly_8h v23, v7, v2, v30 // v23 = -out[7], v7 = t3 + neg v23.8h, v23.8h // v23 = out[7] + + dmbutterfly0 v19, v20, v6, v7, v24, v26, v27, v28, v29, v30 // v19 = -out[3], v20 = out[4] + neg v19.8h, v19.8h // v19 = out[3] + + dmbutterfly_l v26, v27, v28, v29, v5, v3, v0.h[1], v0.h[2] // v26,v27 = t5a, v28,v29 = t4a + dmbutterfly_l v2, v3, v4, v5, v31, v25, v0.h[2], v0.h[1] // v2,v3 = t6a, v4,v5 = t7a + + dbutterfly_n v17, v30, v28, v29, v2, v3, v6, v7, v24, v25 // v17 = -out[1], v30 = t6 + dbutterfly_n v22, v31, v26, v27, v4, v5, v6, v7, v24, v25 // v22 = out[6], v31 = t7 + neg v17.8h, v17.8h // v17 = out[1] + + dmbutterfly0 v18, v21, v30, v31, v2, v3, v4, v5, v6, v7 // v18 = out[2], v21 = -out[5] + neg v21.8h, v21.8h // v21 = out[5] +.endm + + +.macro itxfm_func8x8 txfm1, txfm2 +function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_neon, export=1 + // The iadst also uses a few coefficients from + // idct, so those always need to be loaded. +.ifc \txfm1\()_\txfm2,idct_idct + movrel x4, idct_coeffs + ld1 {v0.8h}, [x4] +.else + movrel x4, iadst8_coeffs + ld1 {v1.8h}, [x4], #16 + ld1 {v0.8h}, [x4] +.endif + + movi v2.16b, #0 + movi v3.16b, #0 + movi v4.16b, #0 + movi v5.16b, #0 + +.ifc \txfm1\()_\txfm2,idct_idct + cmp x3, #1 + b.ne 1f + // DC-only for idct/idct + ld1r {v2.4h}, [x2] + smull v2.4s, v2.4h, v0.h[0] + rshrn v2.4h, v2.4s, #14 + smull v2.4s, v2.4h, v0.h[0] + rshrn v2.4h, v2.4s, #14 + st1 {v3.h}[0], [x2] + dup v16.8h, v2.h[0] + mov v17.16b, v16.16b + mov v18.16b, v16.16b + mov v19.16b, v16.16b + mov v20.16b, v16.16b + mov v21.16b, v16.16b + mov v22.16b, v16.16b + mov v23.16b, v16.16b + b 2f +.endif +1: + ld1 {v16.16b,v17.16b,v18.16b,v19.16b}, [x2], #64 + ld1 {v20.16b,v21.16b,v22.16b,v23.16b}, [x2], #64 + sub x2, x2, #128 + st1 {v2.16b,v3.16b,v4.16b,v5.16b}, [x2], #64 + st1 {v2.16b,v3.16b,v4.16b,v5.16b}, [x2], #64 + + \txfm1\()8 + + // Transpose 8x8 with 16 bit elements + transpose_8x8H v16, v17, v18, v19, v20, v21, v22, v23, v24, v25 + + \txfm2\()8 +2: + mov x3, x0 + // Add into the destination + ld1 {v0.8b}, [x0], x1 + srshr v16.8h, v16.8h, #5 + ld1 {v1.8b}, [x0], x1 + srshr v17.8h, v17.8h, #5 + ld1 {v2.8b}, [x0], x1 + srshr v18.8h, v18.8h, #5 + uaddw v16.8h, v16.8h, v0.8b + ld1 {v3.8b}, [x0], x1 + srshr v19.8h, v19.8h, #5 + uaddw v17.8h, v17.8h, v1.8b + ld1 {v4.8b}, [x0], x1 + srshr v20.8h, v20.8h, #5 + uaddw v18.8h, v18.8h, v2.8b + sqxtun v0.8b, v16.8h + ld1 {v5.8b}, [x0], x1 + srshr v21.8h, v21.8h, #5 + uaddw v19.8h, v19.8h, v3.8b + sqxtun v1.8b, v17.8h + ld1 {v6.8b}, [x0], x1 + srshr v22.8h, v22.8h, #5 + uaddw v20.8h, v20.8h, v4.8b + sqxtun v2.8b, v18.8h + ld1 {v7.8b}, [x0], x1 + srshr v23.8h, v23.8h, #5 + uaddw v21.8h, v21.8h, v5.8b + sqxtun v3.8b, v19.8h + + st1 {v0.8b}, [x3], x1 + uaddw v22.8h, v22.8h, v6.8b + st1 {v1.8b}, [x3], x1 + sqxtun v4.8b, v20.8h + st1 {v2.8b}, [x3], x1 + uaddw v23.8h, v23.8h, v7.8b + st1 {v3.8b}, [x3], x1 + sqxtun v5.8b, v21.8h + st1 {v4.8b}, [x3], x1 + sqxtun v6.8b, v22.8h + st1 {v5.8b}, [x3], x1 + sqxtun v7.8b, v23.8h + + st1 {v6.8b}, [x3], x1 + st1 {v7.8b}, [x3], x1 + + ret +endfunc +.endm + +itxfm_func8x8 idct, idct +itxfm_func8x8 iadst, idct +itxfm_func8x8 idct, iadst +itxfm_func8x8 iadst, iadst + + +function idct16x16_dc_add_neon + movrel x4, idct_coeffs + ld1 {v0.4h}, [x4] + + movi v1.4h, #0 + + ld1r {v2.4h}, [x2] + smull v2.4s, v2.4h, v0.h[0] + rshrn v2.4h, v2.4s, #14 + smull v2.4s, v2.4h, v0.h[0] + rshrn v2.4h, v2.4s, #14 + dup v2.8h, v2.h[0] + st1 {v1.h}[0], [x2] + + srshr v2.8h, v2.8h, #6 + + mov x4, #16 +1: + // Loop to add the constant from v2 into all 16x16 outputs + ld1 {v3.16b}, [x0] + uaddw v4.8h, v2.8h, v3.8b + uaddw2 v5.8h, v2.8h, v3.16b + sqxtun v4.8b, v4.8h + sqxtun2 v4.16b, v5.8h + st1 {v4.16b}, [x0], x1 + subs x4, x4, #1 + b.ne 1b + + ret +endfunc + +.macro idct16 + dmbutterfly0 v16, v24, v16, v24, v2, v3, v4, v5, v6, v7 // v16 = t0a, v24 = t1a + dmbutterfly v20, v28, v0.h[1], v0.h[2], v2, v3, v4, v5 // v20 = t2a, v28 = t3a + dmbutterfly v18, v30, v0.h[3], v0.h[4], v2, v3, v4, v5 // v18 = t4a, v30 = t7a + dmbutterfly v26, v22, v0.h[5], v0.h[6], v2, v3, v4, v5 // v26 = t5a, v22 = t6a + dmbutterfly v17, v31, v0.h[7], v1.h[0], v2, v3, v4, v5 // v17 = t8a, v31 = t15a + dmbutterfly v25, v23, v1.h[1], v1.h[2], v2, v3, v4, v5 // v25 = t9a, v23 = t14a + dmbutterfly v21, v27, v1.h[3], v1.h[4], v2, v3, v4, v5 // v21 = t10a, v27 = t13a + dmbutterfly v29, v19, v1.h[5], v1.h[6], v2, v3, v4, v5 // v29 = t11a, v19 = t12a + + butterfly_8h v4, v28, v16, v28 // v4 = t0, v28 = t3 + butterfly_8h v5, v20, v24, v20 // v5 = t1, v20 = t2 + butterfly_8h v6, v26, v18, v26 // v6 = t4, v26 = t5 + butterfly_8h v7, v22, v30, v22 // v7 = t7, v22 = t6 + butterfly_8h v16, v25, v17, v25 // v16 = t8, v25 = t9 + butterfly_8h v24, v21, v29, v21 // v24 = t11, v21 = t10 + butterfly_8h v17, v27, v19, v27 // v17 = t12, v27 = t13 + butterfly_8h v29, v23, v31, v23 // v29 = t15, v23 = t14 + + dmbutterfly0 v22, v26, v22, v26, v2, v3, v18, v19, v30, v31 // v22 = t6a, v26 = t5a + dmbutterfly v23, v25, v0.h[1], v0.h[2], v18, v19, v30, v31 // v23 = t9a, v25 = t14a + dmbutterfly v27, v21, v0.h[1], v0.h[2], v18, v19, v30, v31, neg=1 // v27 = t13a, v21 = t10a + + butterfly_8h v18, v7, v4, v7 // v18 = t0a, v7 = t7a + butterfly_8h v19, v22, v5, v22 // v19 = t1a, v22 = t6 + butterfly_8h v4, v26, v20, v26 // v4 = t2a, v26 = t5 + butterfly_8h v5, v6, v28, v6 // v5 = t3a, v6 = t4 + butterfly_8h v20, v28, v16, v24 // v20 = t8a, v28 = t11a + butterfly_8h v24, v21, v23, v21 // v24 = t9, v21 = t10 + butterfly_8h v23, v27, v25, v27 // v23 = t14, v27 = t13 + butterfly_8h v25, v29, v29, v17 // v25 = t15a, v29 = t12a + + dmbutterfly0 v2, v3, v27, v21, v2, v3, v16, v17, v30, v31 // v2 = t13a, v3 = t10a + dmbutterfly0 v28, v27, v29, v28, v21, v29, v16, v17, v30, v31 // v28 = t12, v27 = t11 + + butterfly_8h v16, v31, v18, v25 // v16 = out[0], v31 = out[15] + butterfly_8h v17, v30, v19, v23 // v17 = out[1], v30 = out[14] + butterfly_8h_r v25, v22, v22, v24 // v25 = out[9], v22 = out[6] + butterfly_8h v23, v24, v7, v20 // v23 = out[7], v24 = out[8] + butterfly_8h v18, v29, v4, v2 // v18 = out[2], v29 = out[13] + butterfly_8h v19, v28, v5, v28 // v19 = out[3], v28 = out[12] + butterfly_8h v20, v27, v6, v27 // v20 = out[4], v27 = out[11] + butterfly_8h v21, v26, v26, v3 // v21 = out[5], v26 = out[10] +.endm + +.macro iadst16 + ld1 {v0.8h,v1.8h}, [x11] + + dmbutterfly_l v6, v7, v4, v5, v31, v16, v0.h[1], v0.h[0] // v6,v7 = t1, v4,v5 = t0 + dmbutterfly_l v10, v11, v8, v9, v23, v24, v1.h[1], v1.h[0] // v10,v11 = t9, v8,v9 = t8 + dbutterfly_n v31, v24, v6, v7, v10, v11, v12, v13, v10, v11 // v31 = t1a, v24 = t9a + dmbutterfly_l v14, v15, v12, v13, v29, v18, v0.h[3], v0.h[2] // v14,v15 = t3, v12,v13 = t2 + dbutterfly_n v16, v23, v4, v5, v8, v9, v6, v7, v8, v9 // v16 = t0a, v23 = t8a + + dmbutterfly_l v6, v7, v4, v5, v21, v26, v1.h[3], v1.h[2] // v6,v7 = t11, v4,v5 = t10 + dbutterfly_n v29, v26, v14, v15, v6, v7, v8, v9, v6, v7 // v29 = t3a, v26 = t11a + dmbutterfly_l v10, v11, v8, v9, v27, v20, v0.h[5], v0.h[4] // v10,v11 = t5, v8,v9 = t4 + dbutterfly_n v18, v21, v12, v13, v4, v5, v6, v7, v4, v5 // v18 = t2a, v21 = t10a + + dmbutterfly_l v14, v15, v12, v13, v19, v28, v1.h[5], v1.h[4] // v14,v15 = t13, v12,v13 = t12 + dbutterfly_n v20, v28, v10, v11, v14, v15, v4, v5, v14, v15 // v20 = t5a, v28 = t13a + dmbutterfly_l v6, v7, v4, v5, v25, v22, v0.h[7], v0.h[6] // v6,v7 = t7, v4,v5 = t6 + dbutterfly_n v27, v19, v8, v9, v12, v13, v10, v11, v12, v13 // v27 = t4a, v19 = t12a + + dmbutterfly_l v10, v11, v8, v9, v17, v30, v1.h[7], v1.h[6] // v10,v11 = t15, v8,v9 = t14 + ld1 {v0.8h}, [x10] + dbutterfly_n v22, v30, v6, v7, v10, v11, v12, v13, v10, v11 // v22 = t7a, v30 = t15a + dmbutterfly_l v14, v15, v12, v13, v23, v24, v0.h[3], v0.h[4] // v14,v15 = t9, v12,v13 = t8 + dbutterfly_n v25, v17, v4, v5, v8, v9, v6, v7, v8, v9 // v25 = t6a, v17 = t14a + + dmbutterfly_l v4, v5, v6, v7, v28, v19, v0.h[4], v0.h[3] // v4,v5 = t12, v6,v7 = t13 + dbutterfly_n v23, v19, v12, v13, v4, v5, v8, v9, v4, v5 // v23 = t8a, v19 = t12a + dmbutterfly_l v10, v11, v8, v9, v21, v26, v0.h[5], v0.h[6] // v10,v11 = t11, v8,v9 = t10 + butterfly_8h_r v4, v27, v16, v27 // v4 = t4, v27 = t0 + dbutterfly_n v24, v28, v14, v15, v6, v7, v12, v13, v6, v7 // v24 = t9a, v28 = t13a + + dmbutterfly_l v12, v13, v14, v15, v30, v17, v0.h[6], v0.h[5] // v12,v13 = t14, v14,v15 = t15 + butterfly_8h_r v5, v20, v31, v20 // v5 = t5, v20 = t1 + dbutterfly_n v21, v17, v8, v9, v12, v13, v6, v7, v12, v13 // v21 = t10a, v17 = t14a + dbutterfly_n v26, v30, v10, v11, v14, v15, v8, v9, v14, v15 // v26 = t11a, v30 = t15a + + butterfly_8h_r v6, v25, v18, v25 // v6 = t6, v25 = t2 + butterfly_8h_r v7, v22, v29, v22 // v7 = t7, v22 = t3 + + dmbutterfly_l v10, v11, v8, v9, v19, v28, v0.h[1], v0.h[2] // v10,v11 = t13, v8,v9 = t12 + dmbutterfly_l v12, v13, v14, v15, v30, v17, v0.h[2], v0.h[1] // v12,v13 = t14, v14,v15 = t15 + + dbutterfly_n v18, v30, v8, v9, v12, v13, v16, v17, v12, v13 // v18 = out[2], v30 = t14a + dbutterfly_n v29, v17, v10, v11, v14, v15, v12, v13, v14, v15 // v29 = -out[13], v17 = t15a + neg v29.8h, v29.8h // v29 = out[13] + + dmbutterfly_l v10, v11, v8, v9, v4, v5, v0.h[1], v0.h[2] // v10,v11 = t5a, v8,v9 = t4a + dmbutterfly_l v12, v13, v14, v15, v7, v6, v0.h[2], v0.h[1] // v12,v13 = t6a, v14,v15 = t7a + + butterfly_8h v2, v6, v27, v25 // v2 = out[0], v6 = t2a + butterfly_8h v3, v7, v23, v21 // v3 =-out[1], v7 = t10 + + dbutterfly_n v19, v31, v8, v9, v12, v13, v4, v5, v8, v9 // v19 = -out[3], v31 = t6 + neg v19.8h, v19.8h // v19 = out[3] + dbutterfly_n v28, v16, v10, v11, v14, v15, v4, v5, v10, v11 // v28 = out[12], v16 = t7 + + butterfly_8h v5, v8, v20, v22 // v5 =-out[15],v8 = t3a + butterfly_8h v4, v9, v24, v26 // v4 = out[14],v9 = t11 + + dmbutterfly0 v23, v24, v6, v8, v10, v11, v12, v13, v14, v15, 1 // v23 = out[7], v24 = out[8] + dmbutterfly0 v21, v26, v30, v17, v10, v11, v12, v13, v14, v15, 1 // v21 = out[5], v26 = out[10] + dmbutterfly0 v20, v27, v16, v31, v10, v11, v12, v13, v14, v15 // v20 = out[4], v27 = out[11] + dmbutterfly0 v22, v25, v9, v7, v10, v11, v12, v13, v14, v15 // v22 = out[6], v25 = out[9] + + neg v31.8h, v5.8h // v31 = out[15] + neg v17.8h, v3.8h // v17 = out[1] + + mov v16.16b, v2.16b + mov v30.16b, v4.16b +.endm + +// Helper macros; we can't use these expressions directly within +// e.g. .irp due to the extra concatenation \(). Therefore wrap +// them in macros to allow using .irp below. +.macro load i, src, inc + ld1 {v\i\().8h}, [\src], \inc +.endm +.macro store i, dst, inc + st1 {v\i\().8h}, [\dst], \inc +.endm +.macro load_clear i, src, inc + ld1 {v\i\().8h}, [\src] + st1 {v2.8h}, [\src], \inc +.endm + +// Read a vertical 8x16 slice out of a 16x16 matrix, do a transform on it, +// transpose into a horizontal 16x8 slice and store. +// x0 = dst (temp buffer) +// x1 = unused +// x2 = src +// x3 = slice offset +.macro itxfm16_1d_funcs txfm +function \txfm\()16_1d_8x16_pass1_neon + mov x9, #32 + movi v2.8h, #0 +.irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 + load_clear \i, x2, x9 +.endr + + \txfm\()16 + + // Do two 8x8 transposes. Originally, v16-v31 contain the + // 16 rows. Afterwards, v16-v23 and v24-v31 contain the two + // transposed 8x8 blocks. + transpose_8x8H v16, v17, v18, v19, v20, v21, v22, v23, v2, v3 + transpose_8x8H v24, v25, v26, v27, v28, v29, v30, v31, v2, v3 + + // Store the transposed 8x8 blocks horizontally. + cmp x3, #8 + b.eq 1f +.irp i, 16, 24, 17, 25, 18, 26, 19, 27, 20, 28, 21, 29, 22, 30, 23, 31 + store \i, x0, #16 +.endr + ret +1: + // Special case: For the last input column (x3 == 8), + // which would be stored as the last row in the temp buffer, + // don't store the first 8x8 block, but keep it in registers + // for the first slice of the second pass (where it is the + // last 8x8 block). +.irp i, 24, 25, 26, 27, 28, 29, 30, 31 + add x0, x0, #16 + store \i, x0, #16 +.endr + mov v24.16b, v16.16b + mov v25.16b, v17.16b + mov v26.16b, v18.16b + mov v27.16b, v19.16b + mov v28.16b, v20.16b + mov v29.16b, v21.16b + mov v30.16b, v22.16b + mov v31.16b, v23.16b + ret +endfunc + +// Read a vertical 8x16 slice out of a 16x16 matrix, do a transform on it, +// load the destination pixels (from a similar 8x16 slice), add and store back. +// x0 = dst +// x1 = dst stride +// x2 = src (temp buffer) +// x3 = slice offset +function \txfm\()16_1d_8x16_pass2_neon + mov x9, #32 +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + load \i, x2, x9 +.endr + cbz x3, 1f +.irp i, 24, 25, 26, 27, 28, 29, 30, 31 + load \i, x2, x9 +.endr +1: + + add x3, x0, x1 + lsl x1, x1, #1 + \txfm\()16 + +.macro load_add_store coef0, coef1, coef2, coef3, coef4, coef5, coef6, coef7, tmp1, tmp2 + srshr \coef0, \coef0, #6 + ld1 {v2.8b}, [x0], x1 + srshr \coef1, \coef1, #6 + ld1 {v3.8b}, [x3], x1 + srshr \coef2, \coef2, #6 + ld1 {v4.8b}, [x0], x1 + srshr \coef3, \coef3, #6 + uaddw \coef0, \coef0, v2.8b + ld1 {v5.8b}, [x3], x1 + uaddw \coef1, \coef1, v3.8b + srshr \coef4, \coef4, #6 + ld1 {v6.8b}, [x0], x1 + srshr \coef5, \coef5, #6 + ld1 {v7.8b}, [x3], x1 + sqxtun v2.8b, \coef0 + srshr \coef6, \coef6, #6 + sqxtun v3.8b, \coef1 + srshr \coef7, \coef7, #6 + uaddw \coef2, \coef2, v4.8b + ld1 {\tmp1}, [x0], x1 + uaddw \coef3, \coef3, v5.8b + ld1 {\tmp2}, [x3], x1 + sqxtun v4.8b, \coef2 + sub x0, x0, x1, lsl #2 + sub x3, x3, x1, lsl #2 + sqxtun v5.8b, \coef3 + uaddw \coef4, \coef4, v6.8b + st1 {v2.8b}, [x0], x1 + uaddw \coef5, \coef5, v7.8b + st1 {v3.8b}, [x3], x1 + sqxtun v6.8b, \coef4 + st1 {v4.8b}, [x0], x1 + sqxtun v7.8b, \coef5 + st1 {v5.8b}, [x3], x1 + uaddw \coef6, \coef6, \tmp1 + st1 {v6.8b}, [x0], x1 + uaddw \coef7, \coef7, \tmp2 + st1 {v7.8b}, [x3], x1 + sqxtun \tmp1, \coef6 + sqxtun \tmp2, \coef7 + st1 {\tmp1}, [x0], x1 + st1 {\tmp2}, [x3], x1 +.endm + load_add_store v16.8h, v17.8h, v18.8h, v19.8h, v20.8h, v21.8h, v22.8h, v23.8h, v16.8b, v17.8b + load_add_store v24.8h, v25.8h, v26.8h, v27.8h, v28.8h, v29.8h, v30.8h, v31.8h, v16.8b, v17.8b +.purgem load_add_store + + ret +endfunc +.endm + +itxfm16_1d_funcs idct +itxfm16_1d_funcs iadst + +.macro itxfm_func16x16 txfm1, txfm2 +function ff_vp9_\txfm1\()_\txfm2\()_16x16_add_neon, export=1 +.ifc \txfm1\()_\txfm2,idct_idct + cmp x3, #1 + b.eq idct16x16_dc_add_neon +.endif + mov x15, x30 + // iadst16 requires clobbering v8-v15, but idct16 doesn't need to. +.ifnc \txfm1\()_\txfm2,idct_idct + stp d14, d15, [sp, #-0x10]! + stp d12, d13, [sp, #-0x10]! + stp d10, d11, [sp, #-0x10]! + stp d8, d9, [sp, #-0x10]! +.endif + + sub sp, sp, #512 + + mov x4, x0 + mov x5, x1 + mov x6, x2 + + movrel x10, idct_coeffs +.ifnc \txfm1\()_\txfm2,idct_idct + movrel x11, iadst16_coeffs +.endif +.ifc \txfm1,idct + ld1 {v0.8h,v1.8h}, [x10] +.endif + +.irp i, 0, 8 + add x0, sp, #(\i*32) + add x2, x6, #(\i*2) + mov x3, #\i + bl \txfm1\()16_1d_8x16_pass1_neon +.endr +.ifc \txfm1\()_\txfm2,iadst_idct + ld1 {v0.8h,v1.8h}, [x10] +.endif +.irp i, 0, 8 + add x0, x4, #(\i) + mov x1, x5 + add x2, sp, #(\i*2) + mov x3, #\i + bl \txfm2\()16_1d_8x16_pass2_neon +.endr + + add sp, sp, #512 +.ifnc \txfm1\()_\txfm2,idct_idct + ldp d8, d9, [sp], 0x10 + ldp d10, d11, [sp], 0x10 + ldp d12, d13, [sp], 0x10 + ldp d14, d15, [sp], 0x10 +.endif + br x15 +endfunc +.endm + +itxfm_func16x16 idct, idct +itxfm_func16x16 iadst, idct +itxfm_func16x16 idct, iadst +itxfm_func16x16 iadst, iadst + + +function idct32x32_dc_add_neon + movrel x4, idct_coeffs + ld1 {v0.4h}, [x4] + + movi v1.4h, #0 + + ld1r {v2.4h}, [x2] + smull v2.4s, v2.4h, v0.h[0] + rshrn v2.4h, v2.4s, #14 + smull v2.4s, v2.4h, v0.h[0] + rshrn v2.4h, v2.4s, #14 + dup v2.8h, v2.h[0] + st1 {v1.h}[0], [x2] + + srshr v0.8h, v2.8h, #6 + + mov x4, #32 +1: + // Loop to add the constant v0 into all 32x32 outputs + ld1 {v1.16b,v2.16b}, [x0] + uaddw v3.8h, v0.8h, v1.8b + uaddw2 v4.8h, v0.8h, v1.16b + uaddw v5.8h, v0.8h, v2.8b + uaddw2 v6.8h, v0.8h, v2.16b + sqxtun v3.8b, v3.8h + sqxtun2 v3.16b, v4.8h + sqxtun v4.8b, v5.8h + sqxtun2 v4.16b, v6.8h + st1 {v3.16b,v4.16b}, [x0], x1 + subs x4, x4, #1 + b.ne 1b + + ret +endfunc + +.macro idct32_odd + ld1 {v0.8h,v1.8h}, [x11] + + dmbutterfly v16, v31, v0.h[0], v0.h[1], v4, v5, v6, v7 // v16 = t16a, v31 = t31a + dmbutterfly v24, v23, v0.h[2], v0.h[3], v4, v5, v6, v7 // v24 = t17a, v23 = t30a + dmbutterfly v20, v27, v0.h[4], v0.h[5], v4, v5, v6, v7 // v20 = t18a, v27 = t29a + dmbutterfly v28, v19, v0.h[6], v0.h[7], v4, v5, v6, v7 // v28 = t19a, v19 = t28a + dmbutterfly v18, v29, v1.h[0], v1.h[1], v4, v5, v6, v7 // v18 = t20a, v29 = t27a + dmbutterfly v26, v21, v1.h[2], v1.h[3], v4, v5, v6, v7 // v26 = t21a, v21 = t26a + dmbutterfly v22, v25, v1.h[4], v1.h[5], v4, v5, v6, v7 // v22 = t22a, v25 = t25a + dmbutterfly v30, v17, v1.h[6], v1.h[7], v4, v5, v6, v7 // v30 = t23a, v17 = t24a + + ld1 {v0.8h}, [x10] + + butterfly_8h v4, v24, v16, v24 // v4 = t16, v24 = t17 + butterfly_8h v5, v20, v28, v20 // v5 = t19, v20 = t18 + butterfly_8h v6, v26, v18, v26 // v6 = t20, v26 = t21 + butterfly_8h v7, v22, v30, v22 // v7 = t23, v22 = t22 + butterfly_8h v28, v25, v17, v25 // v28 = t24, v25 = t25 + butterfly_8h v30, v21, v29, v21 // v30 = t27, v21 = t26 + butterfly_8h v29, v23, v31, v23 // v29 = t31, v23 = t30 + butterfly_8h v31, v27, v19, v27 // v31 = t28, v27 = t29 + + dmbutterfly v23, v24, v0.h[3], v0.h[4], v16, v17, v18, v19 // v23 = t17a, v24 = t30a + dmbutterfly v27, v20, v0.h[3], v0.h[4], v16, v17, v18, v19, neg=1 // v27 = t29a, v20 = t18a + dmbutterfly v21, v26, v0.h[5], v0.h[6], v16, v17, v18, v19 // v21 = t21a, v26 = t26a + dmbutterfly v25, v22, v0.h[5], v0.h[6], v16, v17, v18, v19, neg=1 // v25 = t25a, v22 = t22a + + butterfly_8h v16, v5, v4, v5 // v16 = t16a, v5 = t19a + butterfly_8h v17, v20, v23, v20 // v17 = t17, v20 = t18 + butterfly_8h v18, v6, v7, v6 // v18 = t23a, v6 = t20a + butterfly_8h v19, v21, v22, v21 // v19 = t22, v21 = t21 + butterfly_8h v4, v28, v28, v30 // v4 = t24a, v28 = t27a + butterfly_8h v23, v26, v25, v26 // v23 = t25, v26 = t26 + butterfly_8h v7, v3, v29, v31 // v7 = t31a, v3 = t28a + butterfly_8h v22, v27, v24, v27 // v22 = t30, v27 = t29 + + dmbutterfly v27, v20, v0.h[1], v0.h[2], v24, v25, v30, v31 // v27 = t18a, v20 = t29a + dmbutterfly v3, v5, v0.h[1], v0.h[2], v24, v25, v30, v31 // v3 = t19, v5 = t28 + dmbutterfly v28, v6, v0.h[1], v0.h[2], v24, v25, v30, v31, neg=1 // v28 = t27, v6 = t20 + dmbutterfly v26, v21, v0.h[1], v0.h[2], v24, v25, v30, v31, neg=1 // v26 = t26a, v21 = t21a + + butterfly_8h v31, v24, v7, v4 // v31 = t31, v24 = t24 + butterfly_8h v30, v25, v22, v23 // v30 = t30a, v25 = t25a + butterfly_8h_r v23, v16, v16, v18 // v23 = t23, v16 = t16 + butterfly_8h_r v22, v17, v17, v19 // v22 = t22a, v17 = t17a + butterfly_8h v18, v21, v27, v21 // v18 = t18, v21 = t21 + butterfly_8h_r v27, v28, v5, v28 // v27 = t27a, v28 = t28a + butterfly_8h v29, v26, v20, v26 // v29 = t29, v26 = t26 + butterfly_8h v19, v20, v3, v6 // v19 = t19a, v20 = t20 + + dmbutterfly0 v27, v20, v27, v20, v2, v3, v4, v5, v6, v7 // v27 = t27, v20 = t20 + dmbutterfly0 v26, v21, v26, v21, v2, v3, v4, v5, v6, v7 // v26 = t26a, v21 = t21a + dmbutterfly0 v25, v22, v25, v22, v2, v3, v4, v5, v6, v7 // v25 = t25, v22 = t22 + dmbutterfly0 v24, v23, v24, v23, v2, v3, v4, v5, v6, v7 // v24 = t24a, v23 = t23a +.endm + +// Do an 32-point IDCT of a 8x32 slice out of a 32x32 matrix. +// The 32-point IDCT can be decomposed into two 16-point IDCTs; +// a normal IDCT16 with every other input component (the even ones, with +// each output written twice), followed by a separate 16-point IDCT +// of the odd inputs, added/subtracted onto the outputs of the first idct16. +// x0 = dst (temp buffer) +// x1 = unused +// x2 = src +// x10 = idct_coeffs +// x11 = idct_coeffs + 32 +function idct32_1d_8x32_pass1_neon + ld1 {v0.8h,v1.8h}, [x10] + + // Double stride of the input, since we only read every other line + mov x9, #128 + movi v4.8h, #0 + + // v16 = IN(0), v17 = IN(2) ... v31 = IN(30) +.irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 + ld1 {v\i\().8h}, [x2] + st1 {v4.8h}, [x2], x9 +.endr + + idct16 + + // Do two 8x8 transposes. Originally, v16-v31 contain the + // 16 rows. Afterwards, v16-v23 and v24-v31 contain the + // two transposed 8x8 blocks. + transpose_8x8H v16, v17, v18, v19, v20, v21, v22, v23, v2, v3 + transpose_8x8H v24, v25, v26, v27, v28, v29, v30, v31, v2, v3 + + // Store the registers a, b horizontally, followed by the + // same registers b, a mirrored. +.macro store_rev a, b + // There's no rev128 instruction, but we reverse each 64 bit + // half, and then flip them using an ext with 8 bytes offset. + rev64 v1.8h, v\b\().8h + st1 {v\a\().8h}, [x0], #16 + rev64 v0.8h, v\a\().8h + ext v1.16b, v1.16b, v1.16b, #8 + st1 {v\b\().8h}, [x0], #16 + ext v0.16b, v0.16b, v0.16b, #8 + st1 {v1.8h}, [x0], #16 + st1 {v0.8h}, [x0], #16 +.endm + store_rev 16, 24 + store_rev 17, 25 + store_rev 18, 26 + store_rev 19, 27 + store_rev 20, 28 + store_rev 21, 29 + store_rev 22, 30 + store_rev 23, 31 + sub x0, x0, #512 +.purgem store_rev + + // Move x2 back to the start of the input, and move + // to the first odd row + sub x2, x2, x9, lsl #4 + add x2, x2, #64 + + movi v4.8h, #0 + // v16 = IN(1), v17 = IN(3) ... v31 = IN(31) +.irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 + ld1 {v\i\().8h}, [x2] + st1 {v4.8h}, [x2], x9 +.endr + + idct32_odd + + transpose_8x8H v31, v30, v29, v28, v27, v26, v25, v24, v2, v3 + transpose_8x8H v23, v22, v21, v20, v19, v18, v17, v16, v2, v3 + + // Store the registers a, b horizontally, + // adding into the output first, and the mirrored, + // subtracted from the output. +.macro store_rev a, b + ld1 {v4.8h}, [x0] + rev64 v1.8h, v\b\().8h + add v4.8h, v4.8h, v\a\().8h + rev64 v0.8h, v\a\().8h + st1 {v4.8h}, [x0], #16 + ext v1.16b, v1.16b, v1.16b, #8 + ld1 {v5.8h}, [x0] + ext v0.16b, v0.16b, v0.16b, #8 + add v5.8h, v5.8h, v\b\().8h + st1 {v5.8h}, [x0], #16 + ld1 {v6.8h}, [x0] + sub v6.8h, v6.8h, v1.8h + st1 {v6.8h}, [x0], #16 + ld1 {v7.8h}, [x0] + sub v7.8h, v7.8h, v0.8h + st1 {v7.8h}, [x0], #16 +.endm + + store_rev 31, 23 + store_rev 30, 22 + store_rev 29, 21 + store_rev 28, 20 + store_rev 27, 19 + store_rev 26, 18 + store_rev 25, 17 + store_rev 24, 16 +.purgem store_rev + ret +endfunc + +// This is mostly the same as 8x32_pass1, but without the transpose, +// and use the source as temp buffer between the two idct passes, and +// add into the destination. +// x0 = dst +// x1 = dst stride +// x2 = src (temp buffer) +// x10 = idct_coeffs +// x11 = idct_coeffs + 32 +function idct32_1d_8x32_pass2_neon + ld1 {v0.8h,v1.8h}, [x10] + + mov x9, #128 + // v16 = IN(0), v17 = IN(2) ... v31 = IN(30) +.irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 + ld1 {v\i\().8h}, [x2], x9 +.endr + sub x2, x2, x9, lsl #4 + + idct16 + + mov x9, #128 +.irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 + st1 {v\i\().8h}, [x2], x9 +.endr + + sub x2, x2, x9, lsl #4 + add x2, x2, #64 + + // v16 = IN(1), v17 = IN(3) ... v31 = IN(31) +.irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 + ld1 {v\i\().8h}, [x2], x9 +.endr + sub x2, x2, x9, lsl #4 + sub x2, x2, #64 + + idct32_odd + + mov x9, #128 +.macro load_acc_store a, b, c, d, neg=0 + ld1 {v4.8h}, [x2], x9 + ld1 {v5.8h}, [x2], x9 +.if \neg == 0 + add v4.8h, v4.8h, v\a\().8h + ld1 {v6.8h}, [x2], x9 + add v5.8h, v5.8h, v\b\().8h + ld1 {v7.8h}, [x2], x9 + add v6.8h, v6.8h, v\c\().8h + add v7.8h, v7.8h, v\d\().8h +.else + sub v4.8h, v4.8h, v\a\().8h + ld1 {v6.8h}, [x2], x9 + sub v5.8h, v5.8h, v\b\().8h + ld1 {v7.8h}, [x2], x9 + sub v6.8h, v6.8h, v\c\().8h + sub v7.8h, v7.8h, v\d\().8h +.endif + ld1 {v0.8b}, [x0], x1 + ld1 {v1.8b}, [x0], x1 + srshr v4.8h, v4.8h, #6 + ld1 {v2.8b}, [x0], x1 + srshr v5.8h, v5.8h, #6 + uaddw v4.8h, v4.8h, v0.8b + ld1 {v3.8b}, [x0], x1 + srshr v6.8h, v6.8h, #6 + uaddw v5.8h, v5.8h, v1.8b + srshr v7.8h, v7.8h, #6 + sub x0, x0, x1, lsl #2 + uaddw v6.8h, v6.8h, v2.8b + sqxtun v4.8b, v4.8h + uaddw v7.8h, v7.8h, v3.8b + sqxtun v5.8b, v5.8h + st1 {v4.8b}, [x0], x1 + sqxtun v6.8b, v6.8h + st1 {v5.8b}, [x0], x1 + sqxtun v7.8b, v7.8h + st1 {v6.8b}, [x0], x1 + st1 {v7.8b}, [x0], x1 +.endm + load_acc_store 31, 30, 29, 28 + load_acc_store 27, 26, 25, 24 + load_acc_store 23, 22, 21, 20 + load_acc_store 19, 18, 17, 16 + sub x2, x2, x9 + neg x9, x9 + load_acc_store 16, 17, 18, 19, 1 + load_acc_store 20, 21, 22, 23, 1 + load_acc_store 24, 25, 26, 27, 1 + load_acc_store 28, 29, 30, 31, 1 +.purgem load_acc_store + ret +endfunc + +function ff_vp9_idct_idct_32x32_add_neon, export=1 + cmp x3, #1 + b.eq idct32x32_dc_add_neon + + movrel x10, idct_coeffs + add x11, x10, #32 + + mov x15, x30 + + stp d14, d15, [sp, #-0x10]! + stp d12, d13, [sp, #-0x10]! + stp d10, d11, [sp, #-0x10]! + stp d8, d9, [sp, #-0x10]! + + sub sp, sp, #2048 + + mov x4, x0 + mov x5, x1 + mov x6, x2 + +.irp i, 0, 8, 16, 24 + add x0, sp, #(\i*64) + add x2, x6, #(\i*2) + bl idct32_1d_8x32_pass1_neon +.endr +.irp i, 0, 8, 16, 24 + add x0, x4, #(\i) + mov x1, x5 + add x2, sp, #(\i*2) + bl idct32_1d_8x32_pass2_neon +.endr + + add sp, sp, #2048 + + ldp d8, d9, [sp], 0x10 + ldp d10, d11, [sp], 0x10 + ldp d12, d13, [sp], 0x10 + ldp d14, d15, [sp], 0x10 + + br x15 +endfunc From 31756abe29eb039a11c59a42cb12e0cc2aef3b97 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Mon, 14 Nov 2016 01:16:00 +0100 Subject: [PATCH 0464/3374] aarch64: vp9: loop_filter: fix typo in skip flatout8 check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 16_16 loop filter functions could miss an early exit before flatout8. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9lpf_neon.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/aarch64/vp9lpf_neon.S b/libavcodec/aarch64/vp9lpf_neon.S index 995a97daac71f..c1b0c884db227 100644 --- a/libavcodec/aarch64/vp9lpf_neon.S +++ b/libavcodec/aarch64/vp9lpf_neon.S @@ -413,7 +413,7 @@ cbz x5, 7f mov x5, v7.d[0] .ifc \sz, .16b - mov x6, v2.d[1] + mov x6, v7.d[1] orr x5, x5, x6 .endif // If no pixels need flat8out, jump to a writeout of the inner 6 pixels From cd1047f3911fa0d34c86f470537f343d23c8b956 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Wed, 26 Oct 2016 21:26:10 +0100 Subject: [PATCH 0465/3374] qsvdec: Pass the correct profile to libmfx This was correct for H.26[45], because libmfx uses the same values derived from profile_idc and the constraint_set flags, but it is wrong for other codecs. Also avoid passing FF_LEVEL_UNKNOWN (-99) as the level, as this is certainly invalid. --- libavcodec/qsv.c | 16 ++++++++++++++++ libavcodec/qsv_internal.h | 1 + libavcodec/qsvdec.c | 4 ++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index 6c53489373f43..f292082f421c1 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -55,6 +55,22 @@ int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id) return AVERROR(ENOSYS); } +int ff_qsv_profile_to_mfx(enum AVCodecID codec_id, int profile) +{ + if (profile == FF_PROFILE_UNKNOWN) + return MFX_PROFILE_UNKNOWN; + switch (codec_id) { + case AV_CODEC_ID_H264: + case AV_CODEC_ID_HEVC: + return profile; + case AV_CODEC_ID_VC1: + return 4 * profile + 1; + case AV_CODEC_ID_MPEG2VIDEO: + return 0x10 * profile; + } + return MFX_PROFILE_UNKNOWN; +} + static const struct { mfxStatus mfxerr; int averr; diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index a8f486764b52a..7ac347ea2118c 100644 --- a/libavcodec/qsv_internal.h +++ b/libavcodec/qsv_internal.h @@ -80,6 +80,7 @@ int ff_qsv_print_warning(void *log_ctx, mfxStatus err, const char *warning_string); int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id); +int ff_qsv_profile_to_mfx(enum AVCodecID codec_id, int profile); int ff_qsv_map_pixfmt(enum AVPixelFormat format, uint32_t *fourcc); diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index 61311005186de..9b5dc1df81880 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -144,8 +144,8 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q) return ret; param.mfx.CodecId = ret; - param.mfx.CodecProfile = avctx->profile; - param.mfx.CodecLevel = avctx->level; + param.mfx.CodecProfile = ff_qsv_profile_to_mfx(avctx->codec_id, avctx->profile); + param.mfx.CodecLevel = avctx->level == FF_LEVEL_UNKNOWN ? MFX_LEVEL_UNKNOWN : avctx->level; param.mfx.FrameInfo.BitDepthLuma = desc->comp[0].depth; param.mfx.FrameInfo.BitDepthChroma = desc->comp[0].depth; From 3297577f3eac1c87d48dedd527942de2bd28e7a5 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Wed, 26 Oct 2016 21:12:02 +0100 Subject: [PATCH 0466/3374] mpegvideo: Return correct coded frame sizes from parser --- libavcodec/mpegvideo_parser.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/mpegvideo_parser.c b/libavcodec/mpegvideo_parser.c index 36303752eea8e..27f2985509c0a 100644 --- a/libavcodec/mpegvideo_parser.c +++ b/libavcodec/mpegvideo_parser.c @@ -151,8 +151,10 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s, if (pix_fmt != AV_PIX_FMT_NONE) { s->format = pix_fmt; - s->width = s->coded_width = pc->width; - s->height = s->coded_height = pc->height; + s->width = pc->width; + s->height = pc->height; + s->coded_width = FFALIGN(pc->width, 16); + s->coded_height = FFALIGN(pc->height, 16); } #if FF_API_AVCTX_TIMEBASE From 030d84fa2e35af0e77516735de35bf1a52371c86 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Wed, 26 Oct 2016 21:27:49 +0100 Subject: [PATCH 0467/3374] qsvdec: Pass field order information to libmfx The VC-1 decoder fails to initialise if this is not set. --- libavcodec/qsvdec.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index 9b5dc1df81880..d61ec7d0aa306 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -155,6 +155,21 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q) param.mfx.FrameInfo.Height = frame_height; param.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420; + switch (avctx->field_order) { + case AV_FIELD_PROGRESSIVE: + param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE; + break; + case AV_FIELD_TT: + param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_FIELD_TFF; + break; + case AV_FIELD_BB: + param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_FIELD_BFF; + break; + default: + param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_UNKNOWN; + break; + } + param.IOPattern = q->iopattern; param.AsyncDepth = q->async_depth; param.ExtParam = q->ext_buffers; @@ -485,6 +500,7 @@ int ff_qsv_process_data(AVCodecContext *avctx, QSVContext *q, avctx->height = q->parser->height; avctx->coded_width = q->parser->coded_width; avctx->coded_height = q->parser->coded_height; + avctx->field_order = q->parser->field_order; avctx->level = q->avctx_internal->level; avctx->profile = q->avctx_internal->profile; From 0940b748bdba36c4894fc8ea6be631d821fdf578 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 30 Oct 2016 16:58:23 +0000 Subject: [PATCH 0468/3374] qsvdec: Only warn about unconsumed data if it happens more than once --- libavcodec/qsvdec.c | 6 +++++- libavcodec/qsvdec.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index d61ec7d0aa306..9e5b1b345dc12 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -328,8 +328,12 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q, /* make sure we do not enter an infinite loop if the SDK * did not consume any data and did not return anything */ if (!*sync && !bs.DataOffset) { - ff_qsv_print_warning(avctx, ret, "A decode call did not consume any data"); bs.DataOffset = avpkt->size; + ++q->zero_consume_run; + if (q->zero_consume_run > 1) + ff_qsv_print_warning(avctx, ret, "A decode call did not consume any data"); + } else { + q->zero_consume_run = 0; } if (*sync) { diff --git a/libavcodec/qsvdec.h b/libavcodec/qsvdec.h index d807864aa56df..c6ec99af1528e 100644 --- a/libavcodec/qsvdec.h +++ b/libavcodec/qsvdec.h @@ -51,6 +51,7 @@ typedef struct QSVContext { QSVFrame *work_frames; AVFifoBuffer *async_fifo; + int zero_consume_run; // the internal parser and codec context for parsing the data AVCodecParserContext *parser; From fea4dc05b41f5465bedc786b67966f204ec6150c Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Wed, 26 Oct 2016 21:13:45 +0100 Subject: [PATCH 0469/3374] vc1: Return stream format information from parser --- libavcodec/vc1_parser.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libavcodec/vc1_parser.c b/libavcodec/vc1_parser.c index 38b62f72bd7ae..7234db69ae68a 100644 --- a/libavcodec/vc1_parser.c +++ b/libavcodec/vc1_parser.c @@ -108,6 +108,14 @@ static void vc1_extract_header(AVCodecParserContext *s, AVCodecContext *avctx, break; } + s->format = vpc->v.chromaformat == 1 ? AV_PIX_FMT_YUV420P + : AV_PIX_FMT_NONE; + if (avctx->width && avctx->height) { + s->width = avctx->width; + s->height = avctx->height; + s->coded_width = FFALIGN(avctx->coded_width, 16); + s->coded_height = FFALIGN(avctx->coded_height, 16); + } } static int vc1_parse(AVCodecParserContext *s, From b6582b29277e00e5d49f400e58beefa5a21d83b8 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Wed, 26 Oct 2016 21:29:08 +0100 Subject: [PATCH 0470/3374] qsv: Add VC-1 decoder It uses the same code as the MPEG-2 decoder, so the file is renamed to contain all "other" (that is, not H.26[45]) codecs. --- configure | 3 + libavcodec/Makefile | 3 +- libavcodec/allcodecs.c | 2 + libavcodec/{qsvdec_mpeg2.c => qsvdec_other.c} | 75 ++++++++++++++----- 4 files changed, 64 insertions(+), 19 deletions(-) rename libavcodec/{qsvdec_mpeg2.c => qsvdec_other.c} (72%) diff --git a/configure b/configure index 7ced8fa341d34..e9615fc2e979d 100755 --- a/configure +++ b/configure @@ -2184,6 +2184,7 @@ vc1_dxva2_hwaccel_select="vc1_decoder" vc1_mmal_decoder_deps="mmal" vc1_mmal_decoder_select="mmal" vc1_mmal_hwaccel_deps="mmal" +vc1_qsv_hwaccel_deps="libmfx" vc1_vaapi_hwaccel_deps="vaapi" vc1_vaapi_hwaccel_select="vc1_decoder" vc1_vdpau_hwaccel_deps="vdpau" @@ -2226,6 +2227,8 @@ mpeg2_qsv_decoder_deps="libmfx" mpeg2_qsv_decoder_select="qsvdec mpeg2_qsv_hwaccel mpegvideo_parser" mpeg2_qsv_encoder_deps="libmfx" mpeg2_qsv_encoder_select="qsvenc" +vc1_qsv_decoder_deps="libmfx" +vc1_qsv_decoder_select="qsvdec vc1_qsv_hwaccel vc1_parser" nvenc_h264_encoder_deps="nvenc" nvenc_hevc_encoder_deps="nvenc" diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 66a6c66a93ad8..08b510a976e7b 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -328,7 +328,7 @@ OBJS-$(CONFIG_MPC8_DECODER) += mpc8.o mpc.o OBJS-$(CONFIG_MPEG_XVMC_DECODER) += mpegvideo_xvmc.o OBJS-$(CONFIG_MPEG1VIDEO_DECODER) += mpeg12dec.o mpeg12.o mpeg12data.o OBJS-$(CONFIG_MPEG1VIDEO_ENCODER) += mpeg12enc.o mpeg12.o -OBJS-$(CONFIG_MPEG2_QSV_DECODER) += qsvdec_mpeg2.o +OBJS-$(CONFIG_MPEG2_QSV_DECODER) += qsvdec_other.o OBJS-$(CONFIG_MPEG2_QSV_ENCODER) += qsvenc_mpeg2.o OBJS-$(CONFIG_MPEG2VIDEO_DECODER) += mpeg12dec.o mpeg12.o mpeg12data.o OBJS-$(CONFIG_MPEG2VIDEO_ENCODER) += mpeg12enc.o mpeg12.o @@ -461,6 +461,7 @@ OBJS-$(CONFIG_VC1_DECODER) += vc1dec.o vc1_block.o vc1_loopfilter.o msmpeg4dec.o msmpeg4.o msmpeg4data.o \ wmv2data.o OBJS-$(CONFIG_VC1_MMAL_DECODER) += mmaldec.o +OBJS-$(CONFIG_VC1_QSV_DECODER) += qsvdec_other.o OBJS-$(CONFIG_VCR1_DECODER) += vcr1.o OBJS-$(CONFIG_VMDAUDIO_DECODER) += vmdaudio.o OBJS-$(CONFIG_VMDVIDEO_DECODER) += vmdvideo.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 41af38eb7cdeb..a66403a3daa40 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -91,6 +91,7 @@ void avcodec_register_all(void) REGISTER_HWACCEL(MPEG4_VDPAU, mpeg4_vdpau); REGISTER_HWACCEL(VC1_D3D11VA, vc1_d3d11va); REGISTER_HWACCEL(VC1_DXVA2, vc1_dxva2); + REGISTER_HWACCEL(VC1_QSV, vc1_qsv); REGISTER_HWACCEL(VC1_VAAPI, vc1_vaapi); REGISTER_HWACCEL(VC1_VDPAU, vc1_vdpau); REGISTER_HWACCEL(VC1_MMAL, vc1_mmal); @@ -280,6 +281,7 @@ void avcodec_register_all(void) REGISTER_DECODER(VC1, vc1); REGISTER_DECODER(VC1IMAGE, vc1image); REGISTER_DECODER(VC1_MMAL, vc1_mmal); + REGISTER_DECODER(VC1_QSV, vc1_qsv); REGISTER_DECODER(VCR1, vcr1); REGISTER_DECODER(VMDVIDEO, vmdvideo); REGISTER_DECODER(VMNC, vmnc); diff --git a/libavcodec/qsvdec_mpeg2.c b/libavcodec/qsvdec_other.c similarity index 72% rename from libavcodec/qsvdec_mpeg2.c rename to libavcodec/qsvdec_other.c index 2daad566ebe0b..53a1bc82549ef 100644 --- a/libavcodec/qsvdec_mpeg2.c +++ b/libavcodec/qsvdec_other.c @@ -1,5 +1,5 @@ /* - * Intel MediaSDK QSV based MPEG-2 decoder + * Intel MediaSDK QSV based MPEG-2 and VC-1 decoders * * copyright (c) 2015 Anton Khirnov * @@ -36,16 +36,16 @@ #include "qsvdec.h" #include "qsv.h" -typedef struct QSVMPEG2Context { +typedef struct QSVOtherContext { AVClass *class; QSVContext qsv; AVFifoBuffer *packet_fifo; AVPacket input_ref; -} QSVMPEG2Context; +} QSVOtherContext; -static void qsv_clear_buffers(QSVMPEG2Context *s) +static void qsv_clear_buffers(QSVOtherContext *s) { AVPacket pkt; while (av_fifo_size(s->packet_fifo) >= sizeof(pkt)) { @@ -58,7 +58,7 @@ static void qsv_clear_buffers(QSVMPEG2Context *s) static av_cold int qsv_decode_close(AVCodecContext *avctx) { - QSVMPEG2Context *s = avctx->priv_data; + QSVOtherContext *s = avctx->priv_data; ff_qsv_decode_close(&s->qsv); @@ -71,7 +71,7 @@ static av_cold int qsv_decode_close(AVCodecContext *avctx) static av_cold int qsv_decode_init(AVCodecContext *avctx) { - QSVMPEG2Context *s = avctx->priv_data; + QSVOtherContext *s = avctx->priv_data; int ret; s->packet_fifo = av_fifo_alloc(sizeof(AVPacket)); @@ -89,7 +89,7 @@ static av_cold int qsv_decode_init(AVCodecContext *avctx) static int qsv_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { - QSVMPEG2Context *s = avctx->priv_data; + QSVOtherContext *s = avctx->priv_data; AVFrame *frame = data; int ret; @@ -134,27 +134,30 @@ static int qsv_decode_frame(AVCodecContext *avctx, void *data, static void qsv_decode_flush(AVCodecContext *avctx) { - QSVMPEG2Context *s = avctx->priv_data; + QSVOtherContext *s = avctx->priv_data; qsv_clear_buffers(s); ff_qsv_decode_flush(avctx, &s->qsv); } +#define OFFSET(x) offsetof(QSVOtherContext, x) +#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM +static const AVOption options[] = { + { "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 0, INT_MAX, VD }, + { NULL }, +}; + +#if CONFIG_MPEG2_QSV_HWACCEL AVHWAccel ff_mpeg2_qsv_hwaccel = { .name = "mpeg2_qsv", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MPEG2VIDEO, .pix_fmt = AV_PIX_FMT_QSV, }; +#endif -#define OFFSET(x) offsetof(QSVMPEG2Context, x) -#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM -static const AVOption options[] = { - { "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 0, INT_MAX, VD }, - { NULL }, -}; - -static const AVClass class = { +#if CONFIG_MPEG2_QSV_DECODER +static const AVClass mpeg2_qsv_class = { .class_name = "mpeg2_qsv", .item_name = av_default_item_name, .option = options, @@ -164,7 +167,7 @@ static const AVClass class = { AVCodec ff_mpeg2_qsv_decoder = { .name = "mpeg2_qsv", .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 video (Intel Quick Sync Video acceleration)"), - .priv_data_size = sizeof(QSVMPEG2Context), + .priv_data_size = sizeof(QSVOtherContext), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MPEG2VIDEO, .init = qsv_decode_init, @@ -172,8 +175,44 @@ AVCodec ff_mpeg2_qsv_decoder = { .flush = qsv_decode_flush, .close = qsv_decode_close, .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1, - .priv_class = &class, + .priv_class = &mpeg2_qsv_class, + .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, + AV_PIX_FMT_QSV, + AV_PIX_FMT_NONE }, +}; +#endif + +#if CONFIG_VC1_QSV_HWACCEL +AVHWAccel ff_vc1_qsv_hwaccel = { + .name = "vc1_qsv", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_VC1, + .pix_fmt = AV_PIX_FMT_QSV, +}; +#endif + +#if CONFIG_VC1_QSV_DECODER +static const AVClass vc1_qsv_class = { + .class_name = "vc1_qsv", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_vc1_qsv_decoder = { + .name = "vc1_qsv", + .long_name = NULL_IF_CONFIG_SMALL("VC-1 video (Intel Quick Sync Video acceleration)"), + .priv_data_size = sizeof(QSVOtherContext), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_VC1, + .init = qsv_decode_init, + .decode = qsv_decode_frame, + .flush = qsv_decode_flush, + .close = qsv_decode_close, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1, + .priv_class = &vc1_qsv_class, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, AV_PIX_FMT_QSV, AV_PIX_FMT_NONE }, }; +#endif From 182cf170a544bce069c8690c90b49381150a1f10 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Thu, 27 Oct 2016 20:02:29 +0100 Subject: [PATCH 0471/3374] vp8: Return stream format information from parser --- libavcodec/vp8_parser.c | 49 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/libavcodec/vp8_parser.c b/libavcodec/vp8_parser.c index 8f6459ccec2d7..fad652dbea1c7 100644 --- a/libavcodec/vp8_parser.c +++ b/libavcodec/vp8_parser.c @@ -1,6 +1,4 @@ /* - * Copyright (C) 2008 Michael Niedermayer - * * This file is part of Libav. * * Libav is free software; you can redistribute it and/or @@ -18,15 +16,56 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "parser.h" +#include "libavutil/intreadwrite.h" + +#include "avcodec.h" static int parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size) { - s->pict_type = (buf[0] & 0x01) ? AV_PICTURE_TYPE_P - : AV_PICTURE_TYPE_I; + unsigned int frame_type; + unsigned int profile; + + if (buf_size < 3) + return AVERROR_INVALIDDATA; + + frame_type = buf[0] & 1; + profile = (buf[0] >> 1) & 7; + if (profile > 3) { + av_log(avctx, AV_LOG_ERROR, "Invalid profile %u.\n", profile); + return AVERROR_INVALIDDATA; + } + + avctx->profile = profile; + s->key_frame = frame_type == 0; + s->pict_type = frame_type ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; + s->format = AV_PIX_FMT_YUV420P; + s->field_order = AV_FIELD_PROGRESSIVE; + s->picture_structure = AV_PICTURE_STRUCTURE_FRAME; + + if (frame_type == 0) { + unsigned int sync_code; + unsigned int width, height; + + if (buf_size < 10) + return AVERROR_INVALIDDATA; + + sync_code = AV_RL24(buf + 3); + if (sync_code != 0x2a019d) { + av_log(avctx, AV_LOG_ERROR, "Invalid sync code %06x.\n", sync_code); + return AVERROR_INVALIDDATA; + } + + width = AV_RL16(buf + 6) & 0x3fff; + height = AV_RL16(buf + 8) & 0x3fff; + + s->width = width; + s->height = height; + s->coded_width = FFALIGN(width, 16); + s->coded_height = FFALIGN(height, 16); + } *poutbuf = buf; *poutbuf_size = buf_size; From e0b164576f7467b7b1127c18175e215dc1df011f Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Thu, 27 Oct 2016 20:33:56 +0100 Subject: [PATCH 0472/3374] qsv: Add VP8 decoder --- configure | 3 +++ libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 2 ++ libavcodec/qsv.c | 8 +++++++ libavcodec/qsvdec_other.c | 48 ++++++++++++++++++++++++++++++++++++++- 5 files changed, 61 insertions(+), 1 deletion(-) diff --git a/configure b/configure index e9615fc2e979d..b4e2792b024cd 100755 --- a/configure +++ b/configure @@ -2189,6 +2189,7 @@ vc1_vaapi_hwaccel_deps="vaapi" vc1_vaapi_hwaccel_select="vc1_decoder" vc1_vdpau_hwaccel_deps="vdpau" vc1_vdpau_hwaccel_select="vc1_decoder" +vp8_qsv_hwaccel_deps="libmfx" vp8_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferVP8" vp8_vaapi_hwaccel_select="vp8_decoder" wmv3_d3d11va_hwaccel_select="vc1_d3d11va_hwaccel" @@ -2229,6 +2230,8 @@ mpeg2_qsv_encoder_deps="libmfx" mpeg2_qsv_encoder_select="qsvenc" vc1_qsv_decoder_deps="libmfx" vc1_qsv_decoder_select="qsvdec vc1_qsv_hwaccel vc1_parser" +vp8_qsv_decoder_deps="libmfx" +vp8_qsv_decoder_select="qsvdec vp8_qsv_hwaccel vp8_parser" nvenc_h264_encoder_deps="nvenc" nvenc_hevc_encoder_deps="nvenc" diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 08b510a976e7b..f0752a2cfbbf6 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -476,6 +476,7 @@ OBJS-$(CONFIG_VP6_DECODER) += vp6.o vp56.o vp56data.o \ vp6dsp.o vp56rac.o OBJS-$(CONFIG_VP7_DECODER) += vp8.o vp56rac.o OBJS-$(CONFIG_VP8_DECODER) += vp8.o vp56rac.o +OBJS-$(CONFIG_VP8_QSV_DECODER) += qsvdec_other.o OBJS-$(CONFIG_VP9_DECODER) += vp9.o vp9data.o vp9dsp.o \ vp9block.o vp9prob.o vp9mvs.o vp56rac.o OBJS-$(CONFIG_VQA_DECODER) += vqavideo.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index a66403a3daa40..591fd87339f8d 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -95,6 +95,7 @@ void avcodec_register_all(void) REGISTER_HWACCEL(VC1_VAAPI, vc1_vaapi); REGISTER_HWACCEL(VC1_VDPAU, vc1_vdpau); REGISTER_HWACCEL(VC1_MMAL, vc1_mmal); + REGISTER_HWACCEL(VP8_QSV, vp8_qsv); REGISTER_HWACCEL(VP8_VAAPI, vp8_vaapi); REGISTER_HWACCEL(WMV3_D3D11VA, wmv3_d3d11va); REGISTER_HWACCEL(WMV3_DXVA2, wmv3_dxva2); @@ -292,6 +293,7 @@ void avcodec_register_all(void) REGISTER_DECODER(VP6F, vp6f); REGISTER_DECODER(VP7, vp7); REGISTER_DECODER(VP8, vp8); + REGISTER_DECODER(VP8_QSV, vp8_qsv); REGISTER_DECODER(VP9, vp9); REGISTER_DECODER(VQA, vqa); REGISTER_DECODER(WEBP, webp); diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index f292082f421c1..45e9b7aa48de1 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -34,6 +34,10 @@ #include "avcodec.h" #include "qsv_internal.h" +#if QSV_VERSION_ATLEAST(1, 12) +#include "mfx/mfxvp8.h" +#endif + int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id) { switch (codec_id) { @@ -48,6 +52,10 @@ int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id) return MFX_CODEC_MPEG2; case AV_CODEC_ID_VC1: return MFX_CODEC_VC1; +#if QSV_VERSION_ATLEAST(1, 12) + case AV_CODEC_ID_VP8: + return MFX_CODEC_VP8; +#endif default: break; } diff --git a/libavcodec/qsvdec_other.c b/libavcodec/qsvdec_other.c index 53a1bc82549ef..3ea1859bf8afd 100644 --- a/libavcodec/qsvdec_other.c +++ b/libavcodec/qsvdec_other.c @@ -1,5 +1,5 @@ /* - * Intel MediaSDK QSV based MPEG-2 and VC-1 decoders + * Intel MediaSDK QSV based MPEG-2, VC-1 and VP8 decoders * * copyright (c) 2015 Anton Khirnov * @@ -74,6 +74,17 @@ static av_cold int qsv_decode_init(AVCodecContext *avctx) QSVOtherContext *s = avctx->priv_data; int ret; +#if CONFIG_VP8_QSV_DECODER + if (avctx->codec_id == AV_CODEC_ID_VP8) { + static const char *uid_vp8dec_hw = "f622394d8d87452f878c51f2fc9b4131"; + + av_freep(&s->qsv.load_plugins); + s->qsv.load_plugins = av_strdup(uid_vp8dec_hw); + if (!s->qsv.load_plugins) + return AVERROR(ENOMEM); + } +#endif + s->packet_fifo = av_fifo_alloc(sizeof(AVPacket)); if (!s->packet_fifo) { ret = AVERROR(ENOMEM); @@ -216,3 +227,38 @@ AVCodec ff_vc1_qsv_decoder = { AV_PIX_FMT_NONE }, }; #endif + +#if CONFIG_VP8_QSV_HWACCEL +AVHWAccel ff_vp8_qsv_hwaccel = { + .name = "vp8_qsv", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_VP8, + .pix_fmt = AV_PIX_FMT_QSV, +}; +#endif + +#if CONFIG_VP8_QSV_DECODER +static const AVClass vp8_qsv_class = { + .class_name = "vp8_qsv", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_vp8_qsv_decoder = { + .name = "vp8_qsv", + .long_name = NULL_IF_CONFIG_SMALL("VP8 video (Intel Quick Sync Video acceleration)"), + .priv_data_size = sizeof(QSVOtherContext), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_VP8, + .init = qsv_decode_init, + .decode = qsv_decode_frame, + .flush = qsv_decode_flush, + .close = qsv_decode_close, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1, + .priv_class = &vp8_qsv_class, + .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, + AV_PIX_FMT_QSV, + AV_PIX_FMT_NONE }, +}; +#endif From fbd1f7639d0142c391bec85d1d840c835210843f Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 4 Jan 2016 11:14:51 +0100 Subject: [PATCH 0473/3374] af_asyncts: Use llabs instead of labs for 64-bit variable libavfilter/af_asyncts.c:212:9: warning: absolute value function 'labs' given an argument of type 'int64_t' (aka 'long long') but has parameter of type 'long' which may cause truncation of value [-Wabsolute-value] --- libavfilter/af_asyncts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/af_asyncts.c b/libavfilter/af_asyncts.c index e662c842aca9e..862b7a8cbd83f 100644 --- a/libavfilter/af_asyncts.c +++ b/libavfilter/af_asyncts.c @@ -209,7 +209,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) delta = pts - s->pts - get_delay(s); out_size = avresample_available(s->avr); - if (labs(delta) > s->min_delta || + if (llabs(delta) > s->min_delta || (s->first_frame && delta && s->first_pts != AV_NOPTS_VALUE)) { av_log(ctx, AV_LOG_VERBOSE, "Discontinuity - %"PRId64" samples.\n", delta); out_size = av_clipl_int32((int64_t)out_size + delta); From f7407f56cbf820a147bd77d728ac9a72c587cc56 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 11 Dec 2015 17:37:01 +0100 Subject: [PATCH 0474/3374] golomb: Replace __PRETTY_FUNCTION__ with __func__ for tracing The former is a GNU extension while the latter is C99. --- libavcodec/golomb.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h index bf80fae117926..9fafbcda70b71 100644 --- a/libavcodec/golomb.h +++ b/libavcodec/golomb.h @@ -449,10 +449,10 @@ static inline int get_te(GetBitContext *s, int r, char *file, const char *func, return i; } -#define get_ue_golomb(a) get_ue(a, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#define get_se_golomb(a) get_se(a, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#define get_te_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#define get_te0_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__) +#define get_ue_golomb(a) get_ue(a, __FILE__, __func__, __LINE__) +#define get_se_golomb(a) get_se(a, __FILE__, __func__, __LINE__) +#define get_te_golomb(a, r) get_te(a, r, __FILE__, __func__, __LINE__) +#define get_te0_golomb(a, r) get_te(a, r, __FILE__, __func__, __LINE__) #endif /* TRACE */ From ffe89e1edb0281ff65d1bda88253784e9283b717 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 10 Nov 2016 17:11:42 +0100 Subject: [PATCH 0475/3374] configure: Move mjpeg_vaapi_decoder dependency declarations to the right place --- configure | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index b4e2792b024cd..647087802a16f 100755 --- a/configure +++ b/configure @@ -2014,8 +2014,6 @@ mimic_decoder_select="blockdsp bswapdsp hpeldsp idctdsp" mjpeg_decoder_select="blockdsp hpeldsp idctdsp jpegtables" mjpeg_encoder_select="aandcttables jpegtables mpegvideoenc" mjpegb_decoder_select="mjpeg_decoder" -mjpeg_vaapi_encoder_deps="VAEncPictureParameterBufferJPEG" -mjpeg_vaapi_encoder_select="vaapi_encode jpegtables" mlp_decoder_select="mlp_parser" motionpixels_decoder_select="bswapdsp" mp1_decoder_select="mpegaudio" @@ -2158,6 +2156,8 @@ hevc_dxva2_hwaccel_select="hevc_decoder" hevc_qsv_hwaccel_deps="libmfx" hevc_vdpau_hwaccel_deps="vdpau VdpPictureInfoHEVC" hevc_vdpau_hwaccel_select="hevc_decoder" +mjpeg_vaapi_encoder_deps="VAEncPictureParameterBufferJPEG" +mjpeg_vaapi_encoder_select="vaapi_encode jpegtables" mpeg1_vdpau_hwaccel_deps="vdpau" mpeg1_vdpau_hwaccel_select="mpeg1video_decoder" mpeg2_d3d11va_hwaccel_deps="d3d11va" From e17567a831dede1f24e3a1a4c305a93012d7a8ce Mon Sep 17 00:00:00 2001 From: Gianluigi Tiesi Date: Fri, 19 Sep 2014 04:49:36 +0200 Subject: [PATCH 0476/3374] libilbc: support for latest git of libilbc In the latest git commits of libilbc developers removed WebRtc_xxx typedefs. This commit uses int types instead. It's safe to apply also for previous versions since WebRtc_Word16 was always a typedef of int16_t and WebRtc_UWord16 a typedef of uint16_t. Reviewed-by: Timothy Gu Signed-off-by: Diego Biurrun --- libavcodec/libilbc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libavcodec/libilbc.c b/libavcodec/libilbc.c index c5053f012b5e3..a5b2f3a18bdff 100644 --- a/libavcodec/libilbc.c +++ b/libavcodec/libilbc.c @@ -95,8 +95,7 @@ static int ilbc_decode_frame(AVCodecContext *avctx, void *data, return ret; } - WebRtcIlbcfix_DecodeImpl((WebRtc_Word16*) frame->data[0], - (const WebRtc_UWord16*) buf, &s->decoder, 1); + WebRtcIlbcfix_DecodeImpl((int16_t *) frame->data[0], (const uint16_t *) buf, &s->decoder, 1); *got_frame_ptr = 1; @@ -168,7 +167,7 @@ static int ilbc_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, return ret; } - WebRtcIlbcfix_EncodeImpl((WebRtc_UWord16*) avpkt->data, (const WebRtc_Word16*) frame->data[0], &s->encoder); + WebRtcIlbcfix_EncodeImpl((uint16_t *) avpkt->data, (const int16_t *) frame->data[0], &s->encoder); avpkt->size = s->encoder.no_of_bytes; *got_packet_ptr = 1; From d7595de0b25e7064fd9e06dea5d0425536cef6dc Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Mon, 14 Nov 2016 00:13:34 +0100 Subject: [PATCH 0477/3374] aarch64: vp9: use alternative returns in the core loop filter function Since aarch64 has enough free general purpose registers use them to branch to the appropiate storage code. 1-2 cycles faster for the functions using loop_filter 8/16, ... on a cortex-a53. Mixed results (up to 2 cycles faster/slower) on a cortex-a57. --- libavcodec/aarch64/vp9lpf_neon.S | 48 ++++++++++++-------------------- 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/libavcodec/aarch64/vp9lpf_neon.S b/libavcodec/aarch64/vp9lpf_neon.S index c1b0c884db227..392794be55504 100644 --- a/libavcodec/aarch64/vp9lpf_neon.S +++ b/libavcodec/aarch64/vp9lpf_neon.S @@ -410,15 +410,19 @@ .endif // If no pixels needed flat8in nor flat8out, jump to a // writeout of the inner 4 pixels - cbz x5, 7f + cbnz x5, 1f + br x14 +1: mov x5, v7.d[0] .ifc \sz, .16b mov x6, v7.d[1] orr x5, x5, x6 .endif // If no pixels need flat8out, jump to a writeout of the inner 6 pixels - cbz x5, 8f + cbnz x5, 1f + br x15 +1: // flat8out // This writes all outputs into v2-v17 (skipping v6 and v16). // If this part is skipped, the output is read from v21-v26 (which is the input @@ -549,35 +553,24 @@ endfunc function vp9_loop_filter_8 loop_filter 8, .8b, 0, v16, v17, v18, v19, v28, v29, v30, v31 - mov x5, #0 ret 6: - mov x5, #6 - ret + br x13 9: br x10 endfunc function vp9_loop_filter_8_16b_mix loop_filter 8, .16b, 88, v16, v17, v18, v19, v28, v29, v30, v31 - mov x5, #0 ret 6: - mov x5, #6 - ret + br x13 9: br x10 endfunc function vp9_loop_filter_16 loop_filter 16, .8b, 0, v8, v9, v10, v11, v12, v13, v14, v15 - mov x5, #0 - ret -7: - mov x5, #7 - ret -8: - mov x5, #8 ret 9: ldp d8, d9, [sp], 0x10 @@ -589,13 +582,6 @@ endfunc function vp9_loop_filter_16_16b loop_filter 16, .16b, 0, v8, v9, v10, v11, v12, v13, v14, v15 - mov x5, #0 - ret -7: - mov x5, #7 - ret -8: - mov x5, #8 ret 9: ldp d8, d9, [sp], 0x10 @@ -614,11 +600,14 @@ endfunc .endm .macro loop_filter_8 + // calculate alternative 'return' targets + adr x13, 6f bl vp9_loop_filter_8 - cbnz x5, 6f .endm .macro loop_filter_8_16b_mix mix + // calculate alternative 'return' targets + adr x13, 6f .if \mix == 48 mov x11, #0xffffffff00000000 .elseif \mix == 84 @@ -627,21 +616,20 @@ endfunc mov x11, #0xffffffffffffffff .endif bl vp9_loop_filter_8_16b_mix - cbnz x5, 6f .endm .macro loop_filter_16 + // calculate alternative 'return' targets + adr x14, 7f + adr x15, 8f bl vp9_loop_filter_16 - cmp x5, 7 - b.gt 8f - b.eq 7f .endm .macro loop_filter_16_16b + // calculate alternative 'return' targets + adr x14, 7f + adr x15, 8f bl vp9_loop_filter_16_16b - cmp x5, 7 - b.gt 8f - b.eq 7f .endm From e7ae8f7a715843a5089d18e033afb3ee19ab3057 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Mon, 14 Nov 2016 22:35:13 +0100 Subject: [PATCH 0478/3374] aarch64: vp9: loop filter: replace 'orr; cbn?z' with 'adds; b.{eq,ne}; The latter is 1 cycle faster on a cortex-53 and since the operands are bytewise (or larger) bitmask (impossible to overflow to zero) both are equivalent. --- libavcodec/aarch64/vp9lpf_neon.S | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/libavcodec/aarch64/vp9lpf_neon.S b/libavcodec/aarch64/vp9lpf_neon.S index 392794be55504..e9c7d9edc8029 100644 --- a/libavcodec/aarch64/vp9lpf_neon.S +++ b/libavcodec/aarch64/vp9lpf_neon.S @@ -218,13 +218,15 @@ xtn_sz v5, v6.8h, v7.8h, \sz and v4\sz, v4\sz, v5\sz // fm + // If no pixels need filtering, just exit as soon as possible mov x5, v4.d[0] .ifc \sz, .16b mov x6, v4.d[1] - orr x5, x5, x6 -.endif - // If no pixels need filtering, just exit as soon as possible + adds x5, x5, x6 + b.eq 9f +.else cbz x5, 9f +.endif .if \wd >= 8 movi v0\sz, #1 @@ -344,15 +346,17 @@ bit v22\sz, v0\sz, v5\sz // if (!hev && fm && !flat8in) bit v25\sz, v2\sz, v5\sz + // If no pixels need flat8in, jump to flat8out + // (or to a writeout of the inner 4 pixels, for wd=8) .if \wd >= 8 mov x5, v6.d[0] .ifc \sz, .16b mov x6, v6.d[1] - orr x5, x5, x6 -.endif - // If no pixels need flat8in, jump to flat8out - // (or to a writeout of the inner 4 pixels, for wd=8) + adds x5, x5, x6 + b.eq 6f +.else cbz x5, 6f +.endif // flat8in uaddl_sz \tmp1\().8h, \tmp2\().8h, v20, v21, \sz @@ -406,20 +410,25 @@ mov x5, v2.d[0] .ifc \sz, .16b mov x6, v2.d[1] - orr x5, x5, x6 + adds x5, x5, x6 + b.ne 1f +.else + cbnz x5, 1f .endif // If no pixels needed flat8in nor flat8out, jump to a // writeout of the inner 4 pixels - cbnz x5, 1f br x14 1: + mov x5, v7.d[0] .ifc \sz, .16b mov x6, v7.d[1] - orr x5, x5, x6 + adds x5, x5, x6 + b.ne 1f +.else + cbnz x5, 1f .endif // If no pixels need flat8out, jump to a writeout of the inner 6 pixels - cbnz x5, 1f br x15 1: From 81d7f0bbca837afda1f7e60d3ae52ab1360ab44b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 14 Nov 2016 23:44:06 +0200 Subject: [PATCH 0479/3374] checkasm: vp9dsp: Benchmark the dc-only version of idct_idct separately MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dc-only mode is already checked to work correctly above, but this allows benchmarking this mode for performance tuning, and allows making sure that it actually is correctly hooked up. Signed-off-by: Martin Storsjö --- tests/checkasm/vp9dsp.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/checkasm/vp9dsp.c b/tests/checkasm/vp9dsp.c index 690e0cf536dad..b9d1c73ea4086 100644 --- a/tests/checkasm/vp9dsp.c +++ b/tests/checkasm/vp9dsp.c @@ -297,6 +297,12 @@ static void check_itxfm(void) } bench_new(dst, sz * SIZEOF_PIXEL, coef, sz * sz); } + if (txtp == 0 && tx != 4) { + if (check_func(dsp.itxfm_add[tx][txtp], "vp9_inv_%s_%dx%d_dc_add", + txtp_types[txtp], sz, sz)) { + bench_new(dst, sz * SIZEOF_PIXEL, coef, 1); + } + } } } report("itxfm"); From d5d62ce6d643de704e7bd62a2375e6391c0ffb9a Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Tue, 15 Nov 2016 10:14:30 -0500 Subject: [PATCH 0480/3374] mov: Fix identity matrix boolean logic This prevented the code from correctly exporting the rotation matrix which caused a few samples to be displayed wrong. Introduced in ecd2ec69ce10e13f6ede353d2def7c. Signed-off-by: Vittorio Giovara --- libavformat/mov.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index b5b2a5b0303af..df29f2a6055c3 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -2759,8 +2759,8 @@ static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom) ( (matrix)[0][0] == (1 << 16) && \ (matrix)[1][1] == (1 << 16) && \ (matrix)[2][2] == (1 << 30) && \ - !(matrix)[0][1] && !(matrix)[0][2] || \ - !(matrix)[1][0] && !(matrix)[1][2] || \ + !(matrix)[0][1] && !(matrix)[0][2] && \ + !(matrix)[1][0] && !(matrix)[1][2] && \ !(matrix)[2][0] && !(matrix)[2][1]) static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) From 481ff3cf018811ba3235f1c236e970f32a6300b9 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Tue, 8 Nov 2016 16:47:38 -0500 Subject: [PATCH 0481/3374] fate: Add h264 and hevc extradata reload tests Signed-off-by: Vittorio Giovara --- tests/fate/h264.mak | 5 +++++ tests/fate/hevc.mak | 5 +++++ tests/ref/fate/h264-extradata-reload | 5 +++++ tests/ref/fate/hevc-extradata-reload | 5 +++++ 4 files changed, 20 insertions(+) create mode 100644 tests/ref/fate/h264-extradata-reload create mode 100644 tests/ref/fate/hevc-extradata-reload diff --git a/tests/fate/h264.mak b/tests/fate/h264.mak index 24e0c9c5ccaa1..635abcd7b900a 100644 --- a/tests/fate/h264.mak +++ b/tests/fate/h264.mak @@ -185,6 +185,10 @@ FATE_H264 := $(FATE_H264:%=fate-h264-conformance-%) \ FATE_H264-$(call DEMDEC, H264, H264) += $(FATE_H264) FATE_H264-$(call DEMDEC, MOV, H264) += fate-h264-crop-to-container + +# this sample has two stsd entries and needs to reload extradata +FATE_H264-$(call DEMDEC, MOV, H264) += fate-h264-extradata-reload + FATE_H264-$(call DEMDEC, MOV, H264) += fate-h264-interlace-crop # this sample has invalid reference list modification, but decodes fine @@ -384,6 +388,7 @@ fate-h264-conformance-sva_nl2_e: CMD = framecrc -i $(TARGET_SAM fate-h264-bsf-mp4toannexb: CMD = md5 -i $(TARGET_SAMPLES)/h264/interlaced_crop.mp4 -vcodec copy -bsf h264_mp4toannexb -f h264 fate-h264-crop-to-container: CMD = framemd5 -i $(TARGET_SAMPLES)/h264/crop-to-container-dims-canon.mov fate-h264-direct-bff: CMD = framecrc -i $(TARGET_SAMPLES)/h264/direct-bff.mkv +fate-h264-extradata-reload: CMD = framemd5 -i $(TARGET_SAMPLES)/h264/extradata-reload-multi-stsd.mov fate-h264-extreme-plane-pred: CMD = framemd5 -i $(TARGET_SAMPLES)/h264/extreme-plane-pred.h264 fate-h264-interlace-crop: CMD = framecrc -i $(TARGET_SAMPLES)/h264/interlaced_crop.mp4 -frames:v 3 fate-h264-intra-refresh-recovery: CMD = framecrc -i $(TARGET_SAMPLES)/h264/intra_refresh.h264 -frames:v 10 diff --git a/tests/fate/hevc.mak b/tests/fate/hevc.mak index fc4ce23bb776e..5446969a7d72e 100644 --- a/tests/fate/hevc.mak +++ b/tests/fate/hevc.mak @@ -160,6 +160,11 @@ FATE_HEVC += fate-hevc-paramchange-yuv420p-yuv420p10 FATE_HEVC-$(call DEMDEC, HEVC, HEVC) += $(FATE_HEVC) +# this sample has two stsd entries and needs to reload extradata +FATE_HEVC-$(call DEMDEC, MOV, HEVC) += fate-hevc-extradata-reload + +fate-hevc-extradata-reload: CMD = framemd5 -i $(TARGET_SAMPLES)/hevc/extradata-reload-multi-stsd.mov + FATE_SAMPLES_AVCONV += $(FATE_HEVC-yes) fate-hevc: $(FATE_HEVC-yes) diff --git a/tests/ref/fate/h264-extradata-reload b/tests/ref/fate/h264-extradata-reload new file mode 100644 index 0000000000000..53e47aa2962f1 --- /dev/null +++ b/tests/ref/fate/h264-extradata-reload @@ -0,0 +1,5 @@ +#tb 0: 1/25 +0, 0, 0, 1, 49152, ae09c88e87e3ea0aa8ad267ee91222e5 +0, 1, 1, 1, 49152, 7ccd8321a6e23ae1f82bd323c8376524 +0, 2, 2, 1, 49152, 8ed93ab585ff9848801cc28b75b5e12d +0, 3, 3, 1, 49152, 0049913870ddb62ffc535282018766f4 diff --git a/tests/ref/fate/hevc-extradata-reload b/tests/ref/fate/hevc-extradata-reload new file mode 100644 index 0000000000000..9fcab7150dec8 --- /dev/null +++ b/tests/ref/fate/hevc-extradata-reload @@ -0,0 +1,5 @@ +#tb 0: 1/25 +0, 0, 0, 1, 24576, 0d01217c5d1ec6799643fc7d75ba2337 +0, 1, 1, 1, 24576, f73d9cca9b4c1765d0ead242c3f0c339 +0, 2, 2, 1, 24576, 39a8714d763c623ae7f6faae34e107d1 +0, 3, 3, 1, 24576, 5db2600aa268b4fd28b64ab28a096f32 From bcefafa226dcda23d4d9af9601d19389cb918a5b Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Mon, 8 Aug 2016 19:24:18 -0400 Subject: [PATCH 0482/3374] avisynth: Fix setting stream timebase Stream timebase should be set using avpriv_set_pts_info, otherwise avctx->pkt_timebase is not correct, leading to A/V desync. Signed-off-by: Marton Balint Reviewed-by: Stephen Hutchinson Signed-off-by: Diego Biurrun --- libavformat/avisynth.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c index 7d5b139adeb50..0e1365bf87d96 100644 --- a/libavformat/avisynth.c +++ b/libavformat/avisynth.c @@ -237,13 +237,12 @@ static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st) st->codecpar->width = avs->vi->width; st->codecpar->height = avs->vi->height; - st->time_base = (AVRational) { avs->vi->fps_denominator, - avs->vi->fps_numerator }; st->avg_frame_rate = (AVRational) { avs->vi->fps_numerator, avs->vi->fps_denominator }; st->start_time = 0; st->duration = avs->vi->num_frames; st->nb_frames = avs->vi->num_frames; + avpriv_set_pts_info(st, 32, avs->vi->fps_denominator, avs->vi->fps_numerator); switch (avs->vi->pixel_type) { #ifdef USING_AVISYNTH @@ -311,9 +310,8 @@ static int avisynth_create_stream_audio(AVFormatContext *s, AVStream *st) st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; st->codecpar->sample_rate = avs->vi->audio_samples_per_second; st->codecpar->channels = avs->vi->nchannels; - st->time_base = (AVRational) { 1, - avs->vi->audio_samples_per_second }; - st->duration = avs->vi->num_audio_samples; + st->duration = avs->vi->num_audio_samples; + avpriv_set_pts_info(st, 64, 1, avs->vi->audio_samples_per_second); switch (avs->vi->sample_type) { case AVS_SAMPLE_INT8: From aaae59700f7fc10fd80cb93b38c5d109900872d9 Mon Sep 17 00:00:00 2001 From: Stephen Hutchinson Date: Mon, 8 Aug 2016 19:24:19 -0400 Subject: [PATCH 0483/3374] avisynth: Simplify the pix_fmt check for the newer AviSynth API The values don't need to be hardcoded since the correct values are returned by avs_bits_per_pixel. Signed-off-by: Diego Biurrun --- libavformat/avisynth.c | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c index 0e1365bf87d96..b919801316a77 100644 --- a/libavformat/avisynth.c +++ b/libavformat/avisynth.c @@ -69,10 +69,6 @@ typedef struct AviSynthLibrary { AVSC_DECLARE_FUNC(avs_get_pitch_p); AVSC_DECLARE_FUNC(avs_get_read_ptr_p); AVSC_DECLARE_FUNC(avs_get_row_size_p); - AVSC_DECLARE_FUNC(avs_is_yv24); - AVSC_DECLARE_FUNC(avs_is_yv16); - AVSC_DECLARE_FUNC(avs_is_yv411); - AVSC_DECLARE_FUNC(avs_is_y8); #endif #undef AVSC_DECLARE_FUNC } AviSynthLibrary; @@ -142,10 +138,6 @@ static av_cold int avisynth_load_library(void) LOAD_AVS_FUNC(avs_get_pitch_p, 1); LOAD_AVS_FUNC(avs_get_read_ptr_p, 1); LOAD_AVS_FUNC(avs_get_row_size_p, 1); - LOAD_AVS_FUNC(avs_is_yv24, 1); - LOAD_AVS_FUNC(avs_is_yv16, 1); - LOAD_AVS_FUNC(avs_is_yv411, 1); - LOAD_AVS_FUNC(avs_is_y8, 1); #endif #undef LOAD_AVS_FUNC @@ -465,20 +457,11 @@ static int avisynth_read_packet_video(AVFormatContext *s, AVPacket *pkt, return 0; #ifdef USING_AVISYNTH - /* Define the bpp values for the new AviSynth 2.6 colorspaces. - * Since AvxSynth doesn't have these functions, special-case - * it in order to avoid implicit declaration errors. */ - - if (avs_library.avs_is_yv24(avs->vi)) - bits = 24; - else if (avs_library.avs_is_yv16(avs->vi)) - bits = 16; - else if (avs_library.avs_is_yv411(avs->vi)) - bits = 12; - else if (avs_library.avs_is_y8(avs->vi)) - bits = 8; - else - bits = avs_library.avs_bits_per_pixel(avs->vi); + /* avs_bits_per_pixel changed to AVSC_API with AviSynth 2.6, which + * requires going through avs_library, while AvxSynth has it under + * the older AVSC_INLINE type, so special-case this. */ + + bits = avs_library.avs_bits_per_pixel(avs->vi); #else bits = avs_bits_per_pixel(avs->vi); #endif From 3cc3463f306f425f76bd962755df1132eeac6dfa Mon Sep 17 00:00:00 2001 From: Stephen Hutchinson Date: Wed, 26 Oct 2016 22:54:18 -0400 Subject: [PATCH 0484/3374] avisynth: Support pix_fmts added to AviSynth+ A number of new pix_fmts* have been added to AviSynth+: 16-bit packed RGB and RGBA 10-, 12-, 14, and 16-bit YUV 4:2:0, 4:2:2, and 4:4:4 8-, 10-, 12-, 14-, and 16-bit Planar RGB 8-, 10-, 12-, 14-, and 16-bit Planar YUVA and Planar RGBA 10-, 12-, 14-, and 16-bit GRAY variants 32-bit floating point Planar YUV(A), Planar RGB(A), and GRAY *some of which are not currently available pix_fmts here and were not added to the demuxer due to this Signed-off-by: Diego Biurrun --- libavformat/avisynth.c | 166 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 165 insertions(+), 1 deletion(-) diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c index b919801316a77..fd5f323e136f4 100644 --- a/libavformat/avisynth.c +++ b/libavformat/avisynth.c @@ -19,8 +19,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/attributes.h" #include "libavutil/internal.h" + #include "libavcodec/internal.h" + #include "avformat.h" #include "internal.h" #include "config.h" @@ -69,6 +72,8 @@ typedef struct AviSynthLibrary { AVSC_DECLARE_FUNC(avs_get_pitch_p); AVSC_DECLARE_FUNC(avs_get_read_ptr_p); AVSC_DECLARE_FUNC(avs_get_row_size_p); + AVSC_DECLARE_FUNC(avs_is_planar_rgb); + AVSC_DECLARE_FUNC(avs_is_planar_rgba); #endif #undef AVSC_DECLARE_FUNC } AviSynthLibrary; @@ -96,6 +101,14 @@ static const int avs_planes_packed[1] = { 0 }; static const int avs_planes_grey[1] = { AVS_PLANAR_Y }; static const int avs_planes_yuv[3] = { AVS_PLANAR_Y, AVS_PLANAR_U, AVS_PLANAR_V }; +#ifdef USING_AVISYNTH +static const int avs_planes_rgb[3] = { AVS_PLANAR_G, AVS_PLANAR_B, + AVS_PLANAR_R }; +static const int avs_planes_yuva[4] = { AVS_PLANAR_Y, AVS_PLANAR_U, + AVS_PLANAR_V, AVS_PLANAR_A }; +static const int avs_planes_rgba[4] = { AVS_PLANAR_G, AVS_PLANAR_B, + AVS_PLANAR_R, AVS_PLANAR_A }; +#endif /* A conflict between C++ global objects, atexit, and dynamic loading requires * us to register our own atexit handler to prevent double freeing. */ @@ -138,6 +151,8 @@ static av_cold int avisynth_load_library(void) LOAD_AVS_FUNC(avs_get_pitch_p, 1); LOAD_AVS_FUNC(avs_get_read_ptr_p, 1); LOAD_AVS_FUNC(avs_get_row_size_p, 1); + LOAD_AVS_FUNC(avs_is_planar_rgb, 1); + LOAD_AVS_FUNC(avs_is_planar_rgba, 1); #endif #undef LOAD_AVS_FUNC @@ -222,7 +237,7 @@ static av_cold void avisynth_atexit_handler(void) static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st) { AviSynthContext *avs = s->priv_data; - int planar = 0; // 0: packed, 1: YUV, 2: Y8 + int planar = 0; // 0: packed, 1: YUV, 2: Y8, 3: Planar RGB, 4: YUVA, 5: Planar RGBA st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; st->codecpar->codec_id = AV_CODEC_ID_RAWVIDEO; @@ -238,6 +253,116 @@ static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st) switch (avs->vi->pixel_type) { #ifdef USING_AVISYNTH + /* 10~16-bit YUV pix_fmts (AviSynth+) */ + case AVS_CS_YUV444P10: + st->codecpar->format = AV_PIX_FMT_YUV444P10; + planar = 1; + break; + case AVS_CS_YUV422P10: + st->codecpar->format = AV_PIX_FMT_YUV422P10; + planar = 1; + break; + case AVS_CS_YUV420P10: + st->codecpar->format = AV_PIX_FMT_YUV420P10; + planar = 1; + break; + case AVS_CS_YUV444P12: + st->codecpar->format = AV_PIX_FMT_YUV444P12; + planar = 1; + break; + case AVS_CS_YUV422P12: + st->codecpar->format = AV_PIX_FMT_YUV422P12; + planar = 1; + break; + case AVS_CS_YUV420P12: + st->codecpar->format = AV_PIX_FMT_YUV420P12; + planar = 1; + break; + case AVS_CS_YUV444P16: + st->codecpar->format = AV_PIX_FMT_YUV444P16; + planar = 1; + break; + case AVS_CS_YUV422P16: + st->codecpar->format = AV_PIX_FMT_YUV422P16; + planar = 1; + break; + case AVS_CS_YUV420P16: + st->codecpar->format = AV_PIX_FMT_YUV420P16; + planar = 1; + break; + /* 8~16-bit YUV pix_fmts with Alpha (AviSynth+) */ + case AVS_CS_YUVA444: + st->codecpar->format = AV_PIX_FMT_YUVA444P; + planar = 4; + break; + case AVS_CS_YUVA422: + st->codecpar->format = AV_PIX_FMT_YUVA422P; + planar = 4; + break; + case AVS_CS_YUVA420: + st->codecpar->format = AV_PIX_FMT_YUVA420P; + planar = 4; + break; + case AVS_CS_YUVA444P10: + st->codecpar->format = AV_PIX_FMT_YUVA444P10; + planar = 4; + break; + case AVS_CS_YUVA422P10: + st->codecpar->format = AV_PIX_FMT_YUVA422P10; + planar = 4; + break; + case AVS_CS_YUVA420P10: + st->codecpar->format = AV_PIX_FMT_YUVA420P10; + planar = 4; + break; + case AVS_CS_YUVA444P16: + st->codecpar->format = AV_PIX_FMT_YUVA444P16; + planar = 4; + break; + case AVS_CS_YUVA422P16: + st->codecpar->format = AV_PIX_FMT_YUVA422P16; + planar = 4; + break; + case AVS_CS_YUVA420P16: + st->codecpar->format = AV_PIX_FMT_YUVA420P16; + planar = 4; + break; + /* Planar RGB pix_fmts (AviSynth+) */ + case AVS_CS_RGBP: + st->codecpar->format = AV_PIX_FMT_GBRP; + planar = 3; + break; + case AVS_CS_RGBP10: + st->codecpar->format = AV_PIX_FMT_GBRP10; + planar = 3; + break; + case AVS_CS_RGBP12: + st->codecpar->format = AV_PIX_FMT_GBRP12; + planar = 3; + break; + case AVS_CS_RGBP16: + st->codecpar->format = AV_PIX_FMT_GBRP16; + planar = 3; + break; + /* Planar RGB pix_fmts with Alpha (AviSynth+) */ + case AVS_CS_RGBAP: + st->codecpar->format = AV_PIX_FMT_GBRAP; + planar = 5; + break; + case AVS_CS_RGBAP12: + st->codecpar->format = AV_PIX_FMT_GBRAP12; + planar = 5; + break; + case AVS_CS_RGBAP16: + st->codecpar->format = AV_PIX_FMT_GBRAP16; + planar = 5; + break; + /* GRAY16 (AviSynth+) */ + case AVS_CS_Y16: + st->codecpar->format = AV_PIX_FMT_GRAY16; + planar = 2; + break; + /* pix_fmts added in AviSynth 2.6 */ case AVS_CS_YV24: st->codecpar->format = AV_PIX_FMT_YUV444P; planar = 1; @@ -254,7 +379,15 @@ static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st) st->codecpar->format = AV_PIX_FMT_GRAY8; planar = 2; break; + /* 16-bit packed RGB pix_fmts (AviSynth+) */ + case AVS_CS_BGR48: + st->codecpar->format = AV_PIX_FMT_BGR48; + break; + case AVS_CS_BGR64: + st->codecpar->format = AV_PIX_FMT_BGRA64; + break; #endif + /* AviSynth 2.5 and AvxSynth pix_fmts */ case AVS_CS_BGR24: st->codecpar->format = AV_PIX_FMT_BGR24; break; @@ -280,6 +413,20 @@ static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st) } switch (planar) { +#ifdef USING_AVISYNTH + case 5: // Planar RGB + Alpha + avs->n_planes = 4; + avs->planes = avs_planes_rgba; + break; + case 4: // YUV + Alpha + avs->n_planes = 4; + avs->planes = avs_planes_yuva; + break; + case 3: // Planar RGB + avs->n_planes = 3; + avs->planes = avs_planes_rgb; + break; +#endif case 2: // Y8 avs->n_planes = 1; avs->planes = avs_planes_grey; @@ -447,6 +594,7 @@ static int avisynth_read_packet_video(AVFormatContext *s, AVPacket *pkt, const unsigned char *src_p; int n, i, plane, rowsize, planeheight, pitch, bits; const char *error; + int avsplus av_unused; if (avs->curr_frame >= avs->vi->num_frames) return AVERROR_EOF; @@ -457,6 +605,13 @@ static int avisynth_read_packet_video(AVFormatContext *s, AVPacket *pkt, return 0; #ifdef USING_AVISYNTH + /* Detect whether we're using AviSynth 2.6 or AviSynth+ by + * looking for whether avs_is_planar_rgb exists. */ + if (GetProcAddress(avs_library.library, "avs_is_planar_rgb") == NULL) + avsplus = 0; + else + avsplus = 1; + /* avs_bits_per_pixel changed to AVSC_API with AviSynth 2.6, which * requires going through avs_library, while AvxSynth has it under * the older AVSC_INLINE type, so special-case this. */ @@ -513,6 +668,15 @@ static int avisynth_read_packet_video(AVFormatContext *s, AVPacket *pkt, pitch = -pitch; } +#ifdef USING_AVISYNTH + /* Flip Planar RGB video */ + if (avsplus && (avs_library.avs_is_planar_rgb(avs->vi) || + avs_library.avs_is_planar_rgba(avs->vi))) { + src_p = src_p + (planeheight - 1) * pitch; + pitch = -pitch; + } +#endif + avs_library.avs_bit_blt(avs->env, dst_p, rowsize, src_p, pitch, rowsize, planeheight); dst_p += rowsize * planeheight; From bf8646274b3ea2d9a193edfdbd70a3bb5c6dd74f Mon Sep 17 00:00:00 2001 From: Stephen Hutchinson Date: Fri, 28 Oct 2016 20:52:11 -0400 Subject: [PATCH 0485/3374] doc: Add note about recent regression in AviSynth+ Signed-off-by: Diego Biurrun --- doc/general.texi | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/doc/general.texi b/doc/general.texi index 1708871d8a09e..7b1f11cf48d40 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -181,6 +181,19 @@ For Windows, supported AviSynth variants are provides a GNU-style Makefile which can install just the headers using @code{make install PREFIX=/install/prefix}. +@float NOTE +There is currently a regression in AviSynth+'s @code{capi.h} header as of +October 2016, which interferes with the ability for builds of Libav to use +MSVC-built binaries of AviSynth. Until this is resolved, you can make sure +a known good version is installed by checking out a version from before +the regression occurred: + +@code{git clone -b MT git://github.com/AviSynth/AviSynthPlus.git @* +cd AviSynthPlus @* +git checkout -b oldheader b4f292b4dbfad149697fb65c6a037bb3810813f9 @* +make install PREFIX=/install/prefix} +@end float + @float NOTE When using AviSynth+'s installed headers, the user must also pass the avisynth/ include directory to @code{--extra-cflags}. For example, From bfe92dfe60f601b3f20a918ffcc0acdf40a5955c Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 16 Nov 2016 09:34:38 +0000 Subject: [PATCH 0486/3374] Ignore all generated example binaries --- doc/examples/.gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/examples/.gitignore b/doc/examples/.gitignore index 3f60af76f159e..01bf9641e6d6f 100644 --- a/doc/examples/.gitignore +++ b/doc/examples/.gitignore @@ -1,5 +1,10 @@ /avcodec +/decode_audio +/decode_video +/encode_audio +/encode_video /filter_audio /metadata /output +/qsvdec /transcode_aac From bb265b764a055f2dc576b9aec62460d9580868f4 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 8 Dec 2015 16:54:07 +0100 Subject: [PATCH 0487/3374] examples/transcode_aac: Drop pointless return value const qualifier doc/examples/transcode_aac.c:52:20: warning: type qualifiers ignored on function return type [-Wignored-qualifiers] --- doc/examples/transcode_aac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/examples/transcode_aac.c b/doc/examples/transcode_aac.c index be86fe5d3ba6d..5c640d9ce25ee 100644 --- a/doc/examples/transcode_aac.c +++ b/doc/examples/transcode_aac.c @@ -49,7 +49,7 @@ * @param error Error code to be converted * @return Corresponding error text (not thread-safe) */ -static char *const get_error_text(const int error) +static char *get_error_text(const int error) { static char error_buffer[255]; av_strerror(error, error_buffer, sizeof(error_buffer)); From 715b8243460836fb7dd15bf7e41668e773beb276 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 15 Nov 2016 16:17:05 +0100 Subject: [PATCH 0488/3374] qsv: Drop some unused variables --- libavcodec/qsv.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index 45e9b7aa48de1..ab48bb0dfb84b 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -466,9 +466,7 @@ static mfxStatus qsv_frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) QSVMid *qsv_mid = mid; AVHWFramesContext *hw_frames_ctx = (AVHWFramesContext*)qsv_mid->hw_frames_ref->data; AVQSVFramesContext *hw_frames_hwctx = hw_frames_ctx->hwctx; - int size; int ret; - mfxStatus err; if (qsv_mid->locked_frame) return MFX_ERR_UNDEFINED_BEHAVIOR; @@ -523,7 +521,6 @@ static mfxStatus qsv_frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) static mfxStatus qsv_frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) { QSVMid *qsv_mid = mid; - int ret; av_frame_free(&qsv_mid->locked_frame); av_frame_free(&qsv_mid->hw_frame); From 76167140a91c081a0cf9d0abcaa4da18d1bacadb Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 15 Nov 2016 16:19:30 +0100 Subject: [PATCH 0489/3374] qsvdec: Drop stray extra braces around initializer libavcodec/qsvdec.c:93:5: warning: braces around scalar initializer --- libavcodec/qsvdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index 9e5b1b345dc12..b6fead0b8428b 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -90,7 +90,7 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q) const AVPixFmtDescriptor *desc; mfxSession session = NULL; int iopattern = 0; - mfxVideoParam param = { { 0 } }; + mfxVideoParam param = { 0 }; int frame_width = avctx->coded_width; int frame_height = avctx->coded_height; int ret; From d860a3cc0a12360a92b9ffd179a0c34413beaf88 Mon Sep 17 00:00:00 2001 From: Christian Suloway Date: Mon, 1 Dec 2014 12:55:28 -0600 Subject: [PATCH 0490/3374] crypto: Add encryption support Signed-off-by: Christian Suloway Signed-off-by: Michael Niedermayer Signed-off-by: Luca Barbato --- libavformat/crypto.c | 167 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 146 insertions(+), 21 deletions(-) diff --git a/libavformat/crypto.c b/libavformat/crypto.c index 55430c48e54a6..bb4adb688a18c 100644 --- a/libavformat/crypto.c +++ b/libavformat/crypto.c @@ -41,14 +41,32 @@ typedef struct CryptoContext { int keylen; uint8_t *iv; int ivlen; - struct AVAES *aes; + uint8_t *decrypt_key; + int decrypt_keylen; + uint8_t *decrypt_iv; + int decrypt_ivlen; + uint8_t *encrypt_key; + int encrypt_keylen; + uint8_t *encrypt_iv; + int encrypt_ivlen; + struct AVAES *aes_decrypt; + struct AVAES *aes_encrypt; + uint8_t *write_buf; + unsigned int write_buf_size; + uint8_t pad[BLOCKSIZE]; + int pad_len; } CryptoContext; #define OFFSET(x) offsetof(CryptoContext, x) #define D AV_OPT_FLAG_DECODING_PARAM +#define E AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { - {"key", "AES decryption key", OFFSET(key), AV_OPT_TYPE_BINARY, .flags = D }, - {"iv", "AES decryption initialization vector", OFFSET(iv), AV_OPT_TYPE_BINARY, .flags = D }, + {"key", "AES encryption/decryption key", OFFSET(key), AV_OPT_TYPE_BINARY, .flags = D|E }, + {"iv", "AES encryption/decryption initialization vector", OFFSET(iv), AV_OPT_TYPE_BINARY, .flags = D|E }, + {"decryption_key", "AES decryption key", OFFSET(decrypt_key), AV_OPT_TYPE_BINARY, .flags = D }, + {"decryption_iv", "AES decryption initialization vector", OFFSET(decrypt_iv), AV_OPT_TYPE_BINARY, .flags = D }, + {"encryption_key", "AES encryption key", OFFSET(encrypt_key), AV_OPT_TYPE_BINARY, .flags = E }, + {"encryption_iv", "AES encryption initialization vector", OFFSET(encrypt_iv), AV_OPT_TYPE_BINARY, .flags = E }, { NULL } }; @@ -59,6 +77,34 @@ static const AVClass crypto_class = { .version = LIBAVUTIL_VERSION_INT, }; +static int set_aes_arg(URLContext *h, uint8_t **buf, int *buf_len, + uint8_t *default_buf, int default_buf_len, + const char *desc) +{ + if (!*buf_len) { + if (!default_buf_len) { + av_log(h, AV_LOG_ERROR, "%s not set\n", desc); + return AVERROR(EINVAL); + } else if (default_buf_len != BLOCKSIZE) { + av_log(h, AV_LOG_ERROR, + "invalid %s size (%d bytes, block size is %d)\n", + desc, default_buf_len, BLOCKSIZE); + return AVERROR(EINVAL); + } + *buf = av_malloc(default_buf_len); + if (!*buf) + return AVERROR(ENOMEM); + memcpy(*buf, default_buf, default_buf_len); + *buf_len = default_buf_len; + } else if (*buf_len != BLOCKSIZE) { + av_log(h, AV_LOG_ERROR, + "invalid %s size (%d bytes, block size is %d)\n", + desc, *buf_len, BLOCKSIZE); + return AVERROR(EINVAL); + } + return 0; +} + static int crypto_open(URLContext *h, const char *uri, int flags) { const char *nested_url; @@ -72,28 +118,52 @@ static int crypto_open(URLContext *h, const char *uri, int flags) goto err; } - if (c->keylen < BLOCKSIZE || c->ivlen < BLOCKSIZE) { - av_log(h, AV_LOG_ERROR, "Key or IV not set\n"); - ret = AVERROR(EINVAL); - goto err; + if (flags & AVIO_FLAG_READ) { + if ((ret = set_aes_arg(h, &c->decrypt_key, &c->decrypt_keylen, + c->key, c->keylen, "decryption key")) < 0) + goto err; + if ((ret = set_aes_arg(h, &c->decrypt_iv, &c->decrypt_ivlen, + c->iv, c->ivlen, "decryption IV")) < 0) + goto err; } + if (flags & AVIO_FLAG_WRITE) { - av_log(h, AV_LOG_ERROR, "Only decryption is supported currently\n"); - ret = AVERROR(ENOSYS); - goto err; + if ((ret = set_aes_arg(h, &c->encrypt_key, &c->encrypt_keylen, + c->key, c->keylen, "encryption key")) < 0) + if (ret < 0) + goto err; + if ((ret = set_aes_arg(h, &c->encrypt_iv, &c->encrypt_ivlen, + c->iv, c->ivlen, "encryption IV")) < 0) + goto err; } - if ((ret = ffurl_open(&c->hd, nested_url, AVIO_FLAG_READ, + + if ((ret = ffurl_open(&c->hd, nested_url, flags, &h->interrupt_callback, NULL, h->protocols, h)) < 0) { - av_log(h, AV_LOG_ERROR, "Unable to open input\n"); + av_log(h, AV_LOG_ERROR, "Unable to open resource: %s\n", nested_url); goto err; } - c->aes = av_aes_alloc(); - if (!c->aes) { - ret = AVERROR(ENOMEM); - goto err; + + if (flags & AVIO_FLAG_READ) { + c->aes_decrypt = av_aes_alloc(); + if (!c->aes_decrypt) { + ret = AVERROR(ENOMEM); + goto err; + } + ret = av_aes_init(c->aes_decrypt, c->decrypt_key, BLOCKSIZE * 8, 1); + if (ret < 0) + goto err; } - av_aes_init(c->aes, c->key, 128, 1); + if (flags & AVIO_FLAG_WRITE) { + c->aes_encrypt = av_aes_alloc(); + if (!c->aes_encrypt) { + ret = AVERROR(ENOMEM); + goto err; + } + ret = av_aes_init(c->aes_encrypt, c->encrypt_key, BLOCKSIZE * 8, 0); + if (ret < 0) + goto err; + } h->is_streamed = 1; @@ -131,8 +201,8 @@ static int crypto_read(URLContext *h, uint8_t *buf, int size) return AVERROR_EOF; if (!c->eof) blocks--; - av_aes_crypt(c->aes, c->outbuffer, c->inbuffer + c->indata_used, blocks, - c->iv, 1); + av_aes_crypt(c->aes_decrypt, c->outbuffer, c->inbuffer + c->indata_used, + blocks, c->decrypt_iv, 1); c->outdata = BLOCKSIZE * blocks; c->outptr = c->outbuffer; c->indata_used += BLOCKSIZE * blocks; @@ -150,19 +220,74 @@ static int crypto_read(URLContext *h, uint8_t *buf, int size) goto retry; } +static int crypto_write(URLContext *h, const uint8_t *buf, int size) +{ + CryptoContext *c = h->priv_data; + int total_size, blocks, pad_len, out_size; + int ret = 0; + + total_size = size + c->pad_len; + pad_len = total_size % BLOCKSIZE; + out_size = total_size - pad_len; + blocks = out_size / BLOCKSIZE; + + if (out_size) { + av_fast_malloc(&c->write_buf, &c->write_buf_size, out_size); + + if (!c->write_buf) + return AVERROR(ENOMEM); + + if (c->pad_len) { + memcpy(&c->pad[c->pad_len], buf, BLOCKSIZE - c->pad_len); + av_aes_crypt(c->aes_encrypt, c->write_buf, c->pad, 1, c->encrypt_iv, 0); + blocks--; + } + + av_aes_crypt(c->aes_encrypt, + &c->write_buf[c->pad_len ? BLOCKSIZE : 0], + &buf[c->pad_len ? BLOCKSIZE - c->pad_len : 0], + blocks, c->encrypt_iv, 0); + + ret = ffurl_write(c->hd, c->write_buf, out_size); + if (ret < 0) + return ret; + + memcpy(c->pad, &buf[size - pad_len], pad_len); + } else + memcpy(&c->pad[c->pad_len], buf, size); + + c->pad_len = pad_len; + + return size; +} + static int crypto_close(URLContext *h) { CryptoContext *c = h->priv_data; + int ret = 0; + + if (c->aes_encrypt) { + uint8_t out_buf[BLOCKSIZE]; + int pad = BLOCKSIZE - c->pad_len; + + memset(&c->pad[c->pad_len], pad, pad); + av_aes_crypt(c->aes_encrypt, out_buf, c->pad, 1, c->encrypt_iv, 0); + ret = ffurl_write(c->hd, out_buf, BLOCKSIZE); + } + if (c->hd) ffurl_close(c->hd); - av_freep(&c->aes); - return 0; + av_freep(&c->aes_decrypt); + av_freep(&c->aes_encrypt); + av_freep(&c->write_buf); + return ret; } const URLProtocol ff_crypto_protocol = { .name = "crypto", .url_open = crypto_open, .url_read = crypto_read, + .url_write = crypto_write, .url_close = crypto_close, .priv_data_size = sizeof(CryptoContext), .priv_data_class = &crypto_class, From 0a4b9d0ccd10b3c39105f99bd320f696f69a75a2 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Tue, 11 Oct 2016 12:15:50 +0200 Subject: [PATCH 0491/3374] hlsenc: Add encryption support Partially based on Christian Suloway work. --- doc/muxers.texi | 13 +++ libavformat/hlsenc.c | 216 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 211 insertions(+), 18 deletions(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index 58801aa1ad045..5430da78501a5 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -122,6 +122,19 @@ Explicitly set whether the client MAY (1) or MUST NOT (0) cache media segments @item -hls_version @var{version} Set the protocol version. Enables or disables version-specific features such as the integer (version 2) or decimal EXTINF values (version 3). +@item -hls_enc @var{enc} +Enable (1) or disable (0) the AES128 encryption. +When enabled every segment generated is encrypted and the encryption key +is saved as @var{playlist name}.key. +@item -hls_enc_key @var{key} +Use the specified hex-coded 16byte key to encrypt the segments, by default it +is randomly generated. +@item -hls_enc_key_url @var{keyurl} +If set, @var{keyurl} is prepended instead of @var{baseurl} to the key filename +in the playlist. +@item -hls_enc_iv @var{iv} +Use a specified hex-coded 16byte initialization vector for every segment instead +of the autogenerated ones. @end table @anchor{image2} diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 96b780fe37776..5eebec8511679 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -22,10 +22,20 @@ #include #include +#include + +#if CONFIG_GCRYPT +#include +#elif CONFIG_OPENSSL +#include +#endif + #include "libavutil/mathematics.h" #include "libavutil/parseutils.h" #include "libavutil/avstring.h" +#include "libavutil/intreadwrite.h" #include "libavutil/opt.h" +#include "libavutil/random_seed.h" #include "libavutil/log.h" #include "avformat.h" @@ -60,8 +70,112 @@ typedef struct HLSContext { ListEntry *end_list; char *basename; char *baseurl; + + int encrypt; // Set by a private option. + char *key; // Set by a private option. + int key_len; + char *key_url; // Set by a private option. + char *iv; // Set by a private option. + int iv_len; + + char *key_basename; + + AVDictionary *enc_opts; } HLSContext; + +static int randomize(uint8_t *buf, int len) +{ +#if CONFIG_GCRYPT + gcry_randomize(buf, len, GCRY_VERY_STRONG_RANDOM); + return 0; +#elif CONFIG_OPENSSL + if (RAND_bytes(buf, len)) + return 0; +#else + return AVERROR(ENOSYS); +#endif +} + +static void free_encryption(AVFormatContext *s) +{ + HLSContext *hls = s->priv_data; + + av_dict_free(&hls->enc_opts); + + av_freep(&hls->key_basename); +} + +static int dict_set_bin(AVDictionary **dict, const char *key, uint8_t *buf) +{ + char hex[33]; + + ff_data_to_hex(hex, buf, sizeof(buf), 0); + hex[32] = '\0'; + + return av_dict_set(dict, key, hex, 0); +} + +static int setup_encryption(AVFormatContext *s) +{ + HLSContext *hls = s->priv_data; + AVIOContext *out = NULL; + int len, ret; + uint8_t buf[16]; + uint8_t *k; + + len = strlen(hls->basename) + 4 + 1; + hls->key_basename = av_mallocz(len); + if (!hls->key_basename) + return AVERROR(ENOMEM); + + av_strlcpy(hls->key_basename, hls->basename + 7, len); + av_strlcat(hls->key_basename, ".key", len); + + if (hls->key) { + if (hls->key_len != 16) { + av_log(s, AV_LOG_ERROR, + "Invalid key size %d, expected 16-bytes hex-coded key\n", + hls->key_len); + return AVERROR(EINVAL); + } + + if ((ret = dict_set_bin(&hls->enc_opts, "key", hls->key)) < 0) + return ret; + k = hls->key; + } else { + if ((ret = randomize(buf, sizeof(buf))) < 0) { + av_log(s, AV_LOG_ERROR, "Cannot generate a strong random key\n"); + return ret; + } + + if ((ret = dict_set_bin(&hls->enc_opts, "key", buf)) < 0) + return ret; + k = buf; + } + + if (hls->iv) { + if (hls->iv_len != 16) { + av_log(s, AV_LOG_ERROR, + "Invalid key size %d, expected 16-bytes hex-coded initialization vector\n", + hls->iv_len); + return AVERROR(EINVAL); + } + + if ((ret = dict_set_bin(&hls->enc_opts, "iv", hls->iv)) < 0) + return ret; + } + + if ((ret = s->io_open(s, &out, hls->key_basename, AVIO_FLAG_WRITE, NULL)) < 0) + return ret; + + avio_write(out, k, 16); + + avio_close(out); + + return 0; +} + static int hls_mux_init(AVFormatContext *s) { HLSContext *hls = s->priv_data; @@ -165,6 +279,24 @@ static int hls_window(AVFormatContext *s, int last) sequence); for (en = hls->list; en; en = en->next) { + if (hls->encrypt) { + char *key_url; + + if (hls->key_url) + key_url = hls->key_url; + else + key_url = hls->baseurl; + + avio_printf(out, "#EXT-X-KEY:METHOD=AES-128"); + avio_printf(out, ",URI=\""); + if (key_url) + avio_printf(out, "%s", key_url); + avio_printf(out, "%s\"", av_basename(hls->key_basename)); + if (hls->iv) + avio_printf(out, ",IV=\"0x%s\"", hls->iv); + avio_printf(out, "\n"); + } + if (hls->version > 2) avio_printf(out, "#EXTINF:%f\n", (double)en->duration / AV_TIME_BASE); @@ -191,18 +323,75 @@ static int hls_start(AVFormatContext *s) HLSContext *c = s->priv_data; AVFormatContext *oc = c->avf; int err = 0; + AVDictionary *opts = NULL; + if (av_get_frame_filename(oc->filename, sizeof(oc->filename), c->basename, c->wrap ? c->sequence % c->wrap : c->sequence) < 0) return AVERROR(EINVAL); c->number++; - if ((err = s->io_open(s, &oc->pb, oc->filename, AVIO_FLAG_WRITE, NULL)) < 0) + if (c->encrypt) { + if ((err = av_dict_copy(&opts, c->enc_opts, 0)) < 0) + return err; + if (!c->iv) { + uint8_t iv[16] = { 0 }; + char buf[33]; + + AV_WB64(iv + 8, c->sequence); + ff_data_to_hex(buf, iv, sizeof(iv), 0); + buf[32] = '\0'; + + if ((err = av_dict_set(&opts, "iv", buf, 0)) < 0) + goto fail; + } + } + + if ((err = s->io_open(s, &oc->pb, oc->filename, AVIO_FLAG_WRITE, &opts)) < 0) return err; if (oc->oformat->priv_class && oc->priv_data) av_opt_set(oc->priv_data, "mpegts_flags", "resend_headers", 0); +fail: + av_dict_free(&opts); + + return err; +} + +static int hls_setup(AVFormatContext *s) +{ + HLSContext *hls = s->priv_data; + const char *pattern = "%d.ts"; + int basename_size = strlen(s->filename) + strlen(pattern) + 1; + char *p; + + if (hls->encrypt) + basename_size += 7; + + hls->basename = av_mallocz(basename_size); + if (!hls->basename) + return AVERROR(ENOMEM); + + // TODO: support protocol nesting? + if (hls->encrypt) + strcpy(hls->basename, "crypto:"); + + av_strlcat(hls->basename, s->filename, basename_size); + + p = strrchr(hls->basename, '.'); + + if (p) + *p = '\0'; + + if (hls->encrypt) { + int ret = setup_encryption(s); + if (ret < 0) + return ret; + } + + av_strlcat(hls->basename, pattern, basename_size); + return 0; } @@ -210,9 +399,6 @@ static int hls_write_header(AVFormatContext *s) { HLSContext *hls = s->priv_data; int ret, i; - char *p; - const char *pattern = "%d.ts"; - int basename_size = strlen(s->filename) + strlen(pattern) + 1; hls->sequence = hls->start_sequence; hls->recording_time = hls->time * AV_TIME_BASE; @@ -234,21 +420,8 @@ static int hls_write_header(AVFormatContext *s) goto fail; } - hls->basename = av_malloc(basename_size); - - if (!hls->basename) { - ret = AVERROR(ENOMEM); + if ((ret = hls_setup(s)) < 0) goto fail; - } - - strcpy(hls->basename, s->filename); - - p = strrchr(hls->basename, '.'); - - if (p) - *p = '\0'; - - av_strlcat(hls->basename, pattern, basename_size); if ((ret = hls_mux_init(s)) < 0) goto fail; @@ -265,6 +438,8 @@ static int hls_write_header(AVFormatContext *s) av_free(hls->basename); if (hls->avf) avformat_free_context(hls->avf); + + free_encryption(s); } return ret; } @@ -332,6 +507,7 @@ static int hls_write_trailer(struct AVFormatContext *s) hls_window(s, 1); free_entries(hls); + free_encryption(s); return 0; } @@ -345,6 +521,10 @@ static const AVOption options[] = { {"hls_allow_cache", "explicitly set whether the client MAY (1) or MUST NOT (0) cache media segments", OFFSET(allowcache), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, E}, {"hls_base_url", "url to prepend to each playlist entry", OFFSET(baseurl), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E}, {"hls_version", "protocol version", OFFSET(version), AV_OPT_TYPE_INT, {.i64 = 3}, 2, 3, E}, + {"hls_enc", "AES128 encryption support", OFFSET(encrypt), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, E}, + {"hls_enc_key", "use the specified hex-coded 16byte key to encrypt the segments", OFFSET(key), AV_OPT_TYPE_BINARY, .flags = E}, + {"hls_enc_key_url", "url to access the key to decrypt the segments", OFFSET(key_url), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E}, + {"hls_enc_iv", "use the specified hex-coded 16byte initialization vector", OFFSET(iv), AV_OPT_TYPE_BINARY, .flags = E}, { NULL }, }; From adb0e941c329a4778ade6dd0a326274472992f54 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Thu, 17 Nov 2016 19:41:12 +0100 Subject: [PATCH 0492/3374] avpacket: Mark src pointer as constant --- libavcodec/avcodec.h | 4 ++-- libavcodec/avpacket.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 88e6c62272069..a004e6bccea2d 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3832,7 +3832,7 @@ AVPacket *av_packet_alloc(void); * @see av_packet_alloc * @see av_packet_ref */ -AVPacket *av_packet_clone(AVPacket *src); +AVPacket *av_packet_clone(const AVPacket *src); /** * Free the packet, if the packet is reference counted, it will be @@ -3986,7 +3986,7 @@ void av_packet_free_side_data(AVPacket *pkt); * * @return 0 on success, a negative AVERROR on error. */ -int av_packet_ref(AVPacket *dst, AVPacket *src); +int av_packet_ref(AVPacket *dst, const AVPacket *src); /** * Wipe the packet. diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index 76fc4eb78f103..f2b0a296b8019 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -352,7 +352,7 @@ void av_packet_unref(AVPacket *pkt) pkt->size = 0; } -int av_packet_ref(AVPacket *dst, AVPacket *src) +int av_packet_ref(AVPacket *dst, const AVPacket *src) { int ret; @@ -384,7 +384,7 @@ int av_packet_ref(AVPacket *dst, AVPacket *src) return ret; } -AVPacket *av_packet_clone(AVPacket *src) +AVPacket *av_packet_clone(const AVPacket *src) { AVPacket *ret = av_packet_alloc(); From 0d3176e32f351d18d6174d8b05796829a75a4c6b Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 7 Nov 2016 13:34:21 +0100 Subject: [PATCH 0493/3374] hwcontext_dxva2: do not assume the destination format during mapping is always the right one Handle the cases where it is unsupported or unset. --- libavutil/hwcontext_dxva2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavutil/hwcontext_dxva2.c b/libavutil/hwcontext_dxva2.c index 600cf0eec7935..8a050719b746e 100644 --- a/libavutil/hwcontext_dxva2.c +++ b/libavutil/hwcontext_dxva2.c @@ -345,6 +345,10 @@ static int dxva2_map_from(AVHWFramesContext *ctx, { int err; + if (dst->format != AV_PIX_FMT_NONE && dst->format != ctx->sw_format) + return AVERROR(ENOSYS); + dst->format = ctx->sw_format; + err = dxva2_map_frame(ctx, dst, src, flags); if (err < 0) return err; From 9d7026574bbbe67d004a1c32911da75375692967 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 7 Nov 2016 13:42:50 +0100 Subject: [PATCH 0494/3374] hwcontext_dxva2: fix handling of the mapping flags D3DLOCK_READONLY properly corresponds to the absence of the write flag, not to the presence of the read flag, while D3DLOCK_DISCARD is equivalent to the overwrite flag. --- libavutil/hwcontext_dxva2.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libavutil/hwcontext_dxva2.c b/libavutil/hwcontext_dxva2.c index 8a050719b746e..1dc351a356f18 100644 --- a/libavutil/hwcontext_dxva2.c +++ b/libavutil/hwcontext_dxva2.c @@ -262,6 +262,7 @@ static int dxva2_map_frame(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame * D3DLOCKED_RECT LockedRect; HRESULT hr; int i, err, nb_planes; + int lock_flags = 0; nb_planes = av_pix_fmt_count_planes(dst->format); @@ -271,8 +272,12 @@ static int dxva2_map_frame(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame * return AVERROR_UNKNOWN; } - hr = IDirect3DSurface9_LockRect(surface, &LockedRect, NULL, - flags & AV_HWFRAME_MAP_READ ? D3DLOCK_READONLY : D3DLOCK_DISCARD); + if (!(flags & AV_HWFRAME_MAP_WRITE)) + lock_flags |= D3DLOCK_READONLY; + if (flags & AV_HWFRAME_MAP_OVERWRITE) + lock_flags |= D3DLOCK_DISCARD; + + hr = IDirect3DSurface9_LockRect(surface, &LockedRect, NULL, lock_flags); if (FAILED(hr)) { av_log(ctx, AV_LOG_ERROR, "Unable to lock DXVA2 surface\n"); return AVERROR_UNKNOWN; @@ -318,7 +323,8 @@ static int dxva2_transfer_data(AVHWFramesContext *ctx, AVFrame *dst, map->format = dst->format; ret = dxva2_map_frame(ctx, map, download ? src : dst, - download ? AV_HWFRAME_MAP_READ : AV_HWFRAME_MAP_WRITE); + download ? AV_HWFRAME_MAP_READ : + AV_HWFRAME_MAP_WRITE | AV_HWFRAME_MAP_OVERWRITE); if (ret < 0) goto fail; From 5a1d605ceae448b476a525f7368ec452000d1f26 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 7 Nov 2016 14:05:49 +0100 Subject: [PATCH 0495/3374] hwcontext_dxva2: split transfer_data() into upload/download functions Just the presence of a hw frames context is not enough to detect whether the transfer is an upload or a download, because hw frames mapped to system memory will have a hw frames context attached. --- libavutil/hwcontext_dxva2.c | 53 +++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/libavutil/hwcontext_dxva2.c b/libavutil/hwcontext_dxva2.c index 1dc351a356f18..3fe19a6b65046 100644 --- a/libavutil/hwcontext_dxva2.c +++ b/libavutil/hwcontext_dxva2.c @@ -309,12 +309,34 @@ static int dxva2_map_frame(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame * return err; } -static int dxva2_transfer_data(AVHWFramesContext *ctx, AVFrame *dst, - const AVFrame *src) +static int dxva2_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) { - int download = !!src->hw_frames_ctx; + AVFrame *map; + int ret; + + map = av_frame_alloc(); + if (!map) + return AVERROR(ENOMEM); + map->format = dst->format; + + ret = dxva2_map_frame(ctx, map, dst, AV_HWFRAME_MAP_WRITE | AV_HWFRAME_MAP_OVERWRITE); + if (ret < 0) + goto fail; + av_image_copy(map->data, map->linesize, src->data, src->linesize, + ctx->sw_format, src->width, src->height); + +fail: + av_frame_free(&map); + return ret; +} + +static int dxva2_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) +{ AVFrame *map; + ptrdiff_t src_linesize[4], dst_linesize[4]; int ret, i; map = av_frame_alloc(); @@ -322,25 +344,16 @@ static int dxva2_transfer_data(AVHWFramesContext *ctx, AVFrame *dst, return AVERROR(ENOMEM); map->format = dst->format; - ret = dxva2_map_frame(ctx, map, download ? src : dst, - download ? AV_HWFRAME_MAP_READ : - AV_HWFRAME_MAP_WRITE | AV_HWFRAME_MAP_OVERWRITE); + ret = dxva2_map_frame(ctx, map, src, AV_HWFRAME_MAP_READ); if (ret < 0) goto fail; - if (download) { - ptrdiff_t src_linesize[4], dst_linesize[4]; - for (i = 0; i < 4; i++) { - dst_linesize[i] = dst->linesize[i]; - src_linesize[i] = map->linesize[i]; - } - av_image_copy_uc_from(dst->data, dst_linesize, map->data, src_linesize, - ctx->sw_format, src->width, src->height); - } else { - av_image_copy(map->data, map->linesize, src->data, src->linesize, - ctx->sw_format, src->width, src->height); + for (i = 0; i < 4; i++) { + dst_linesize[i] = dst->linesize[i]; + src_linesize[i] = map->linesize[i]; } - + av_image_copy_uc_from(dst->data, dst_linesize, map->data, src_linesize, + ctx->sw_format, src->width, src->height); fail: av_frame_free(&map); return ret; @@ -498,8 +511,8 @@ const HWContextType ff_hwcontext_type_dxva2 = { .frames_uninit = dxva2_frames_uninit, .frames_get_buffer = dxva2_get_buffer, .transfer_get_formats = dxva2_transfer_get_formats, - .transfer_data_to = dxva2_transfer_data, - .transfer_data_from = dxva2_transfer_data, + .transfer_data_to = dxva2_transfer_data_to, + .transfer_data_from = dxva2_transfer_data_from, .map_from = dxva2_map_from, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_DXVA2_VLD, AV_PIX_FMT_NONE }, From e18ba2dfd2d19aedc8afccf011d5fd0833352423 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 7 Nov 2016 14:12:17 +0100 Subject: [PATCH 0496/3374] hwcontext_dxva2: make sure the sw frame format is the right one during transfer --- libavutil/hwcontext_dxva2.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libavutil/hwcontext_dxva2.c b/libavutil/hwcontext_dxva2.c index 3fe19a6b65046..ccf03c8e9ff9b 100644 --- a/libavutil/hwcontext_dxva2.c +++ b/libavutil/hwcontext_dxva2.c @@ -315,6 +315,9 @@ static int dxva2_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, AVFrame *map; int ret; + if (src->format != ctx->sw_format) + return AVERROR(ENOSYS); + map = av_frame_alloc(); if (!map) return AVERROR(ENOMEM); @@ -339,6 +342,9 @@ static int dxva2_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, ptrdiff_t src_linesize[4], dst_linesize[4]; int ret, i; + if (dst->format != ctx->sw_format) + return AVERROR(ENOSYS); + map = av_frame_alloc(); if (!map) return AVERROR(ENOMEM); From dd3d7ddf2a508b15877bb978c2309f777853a228 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Fri, 22 Apr 2016 09:43:52 +0200 Subject: [PATCH 0497/3374] lavc: add a new bitstream reader to replace get_bits The new bit reader features a simpler API and an implementation without stacks of nested macros. Signed-off-by: Anton Khirnov --- libavcodec/bitstream.h | 387 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 387 insertions(+) create mode 100644 libavcodec/bitstream.h diff --git a/libavcodec/bitstream.h b/libavcodec/bitstream.h new file mode 100644 index 0000000000000..996e32e83b91a --- /dev/null +++ b/libavcodec/bitstream.h @@ -0,0 +1,387 @@ +/* + * Copyright (c) 2016 Alexandra Hájková + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * functions for reading bits from a buffer + */ + +#ifndef AVCODEC_BITSTREAM_H +#define AVCODEC_BITSTREAM_H + +#include + +#include "libavutil/common.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/log.h" + +#include "mathops.h" +#include "vlc.h" + +typedef struct BitstreamContext { + uint64_t bits; // stores bits read from the buffer + const uint8_t *buffer, *buffer_end; + const uint8_t *ptr; // position inside a buffer + unsigned bits_left; // number of bits left in bits field + unsigned size_in_bits; +} BitstreamContext; + +static inline void refill_64(BitstreamContext *bc) +{ + if (bc->ptr >= bc->buffer_end) + return; + +#ifdef BITSTREAM_READER_LE + bc->bits = AV_RL64(bc->ptr); +#else + bc->bits = AV_RB64(bc->ptr); +#endif + bc->ptr += 8; + bc->bits_left = 64; +} + +static inline void refill_32(BitstreamContext *bc) +{ + if (bc->ptr >= bc->buffer_end) + return; + +#ifdef BITSTREAM_READER_LE + bc->bits = (uint64_t)AV_RL32(bc->ptr) << bc->bits_left | bc->bits; +#else + bc->bits = bc->bits | (uint64_t)AV_RB32(bc->ptr) << (32 - bc->bits_left); +#endif + bc->ptr += 4; + bc->bits_left += 32; +} + +/* Initialize BitstreamContext. Input buffer must have an additional zero + * padding of AV_INPUT_BUFFER_PADDING_SIZE bytes at the end. */ +static inline int bitstream_init(BitstreamContext *bc, const uint8_t *buffer, + unsigned bit_size) +{ + unsigned buffer_size; + + if (bit_size > INT_MAX - 7 || !buffer) { + buffer = + bc->buffer = + bc->ptr = NULL; + bc->bits_left = 0; + return AVERROR_INVALIDDATA; + } + + buffer_size = (bit_size + 7) >> 3; + + bc->buffer = buffer; + bc->buffer_end = buffer + buffer_size; + bc->ptr = bc->buffer; + bc->size_in_bits = bit_size; + bc->bits_left = 0; + bc->bits = 0; + + refill_64(bc); + + return 0; +} + +/* Initialize BitstreamContext with buffer size in bytes instead of bits. */ +static inline int bitstream_init8(BitstreamContext *bc, const uint8_t *buffer, + unsigned byte_size) +{ + if (byte_size > INT_MAX / 8) + return AVERROR_INVALIDDATA; + return bitstream_init(bc, buffer, byte_size * 8); +} + +/* Return number of bits already read. */ +static inline int bitstream_tell(const BitstreamContext *bc) +{ + return (bc->ptr - bc->buffer) * 8 - bc->bits_left; +} + +/* Return buffer size in bits. */ +static inline int bitstream_tell_size(const BitstreamContext *bc) +{ + return bc->size_in_bits; +} + +/* Return the number of the bits left in a buffer. */ +static inline int bitstream_bits_left(const BitstreamContext *bc) +{ + return (bc->buffer - bc->ptr) * 8 + bc->size_in_bits + bc->bits_left; +} + +static inline uint64_t get_val(BitstreamContext *bc, unsigned n) +{ +#ifdef BITSTREAM_READER_LE + uint64_t ret = bc->bits & ((UINT64_C(1) << n) - 1); + bc->bits >>= n; +#else + uint64_t ret = bc->bits >> (64 - n); + bc->bits <<= n; +#endif + bc->bits_left -= n; + + return ret; +} + +/* Return one bit from the buffer. */ +static inline unsigned bitstream_read_bit(BitstreamContext *bc) +{ + if (!bc->bits_left) + refill_64(bc); + + return get_val(bc, 1); +} + +/* Return n bits from the buffer. n has to be in the 0-63 range. */ +static inline uint64_t bitstream_read_63(BitstreamContext *bc, unsigned n) +{ + uint64_t ret = 0; +#ifdef BITSTREAM_READER_LE + uint64_t left = 0; +#endif + + if (!n) + return 0; + + if (n > bc->bits_left) { + n -= bc->bits_left; +#ifdef BITSTREAM_READER_LE + left = bc->bits_left; +#endif + ret = get_val(bc, bc->bits_left); + refill_64(bc); + } + +#ifdef BITSTREAM_READER_LE + ret = get_val(bc, n) << left | ret; +#else + ret = get_val(bc, n) | ret << n; +#endif + + return ret; +} + +/* Return n bits from the buffer. n has to be in the 0-32 range. */ +static inline uint32_t bitstream_read(BitstreamContext *bc, unsigned n) +{ + if (!n) + return 0; + + if (n > bc->bits_left) { + refill_32(bc); + if (bc->bits_left < 32) + bc->bits_left = n; + } + + return get_val(bc, n); +} + +/* Return n bits from the buffer as a signed integer. + * n has to be in the 0-32 range. */ +static inline int32_t bitstream_read_signed(BitstreamContext *bc, unsigned n) +{ + return sign_extend(bitstream_read(bc, n), n); +} + +static inline unsigned show_val(const BitstreamContext *bc, unsigned n) +{ +#ifdef BITSTREAM_READER_LE + return bc->bits & ((UINT64_C(1) << n) - 1); +#else + return bc->bits >> (64 - n); +#endif +} + +/* Return n bits from the buffer, but do not change the buffer state. + * n has to be in the 0-32 range. */ +static inline unsigned bitstream_peek(BitstreamContext *bc, unsigned n) +{ + if (n > bc->bits_left) + refill_32(bc); + + return show_val(bc, n); +} + +/* Return n bits from the buffer as a signed integer, but do not change the + * buffer state. n has to be in the 0-32 range. */ +static inline int bitstream_peek_signed(BitstreamContext *bc, unsigned n) +{ + return sign_extend(bitstream_peek(bc, n), n); +} + +static inline void skip_remaining(BitstreamContext *bc, unsigned n) +{ +#ifdef BITSTREAM_READER_LE + bc->bits >>= n; +#else + bc->bits <<= n; +#endif + bc->bits_left -= n; +} + +/* Skip n bits in the buffer. */ +static inline void bitstream_skip(BitstreamContext *bc, unsigned n) +{ + if (n <= bc->bits_left) + skip_remaining(bc, n); + else { + n -= bc->bits_left; + skip_remaining(bc, bc->bits_left); + if (n >= 64) { + unsigned skip = n / 8; + + n -= skip * 8; + bc->ptr += skip; + } + refill_64(bc); + if (n) + skip_remaining(bc, n); + } +} + +/* Seek to the given bit position. */ +static inline void bitstream_seek(BitstreamContext *bc, unsigned pos) +{ + bc->ptr = bc->buffer; + bc->bits = 0; + bc->bits_left = 0; + + bitstream_skip(bc, pos); +} + +/* Skip bits to a byte boundary. */ +static inline const uint8_t *bitstream_align(BitstreamContext *bc) +{ + unsigned n = -bitstream_tell(bc) & 7; + if (n) + bitstream_skip(bc, n); + return bc->buffer + (bitstream_tell(bc) >> 3); +} + +/* Read MPEG-1 dc-style VLC (sign bit + mantissa with no MSB). + * If MSB not set it is negative. */ +static inline int bitstream_read_xbits(BitstreamContext *bc, unsigned length) +{ + int32_t cache = bitstream_peek(bc, 32); + int sign = ~cache >> 31; + skip_remaining(bc, length); + + return ((((uint32_t)(sign ^ cache)) >> (32 - length)) ^ sign) - sign; +} + +/* Return the LUT element for the given bitstream configuration. */ +static inline int set_idx(BitstreamContext *bc, int code, int *n, int *nb_bits, + VLC_TYPE (*table)[2]) +{ + unsigned idx; + + *nb_bits = -*n; + idx = bitstream_peek(bc, *nb_bits) + code; + *n = table[idx][1]; + + return table[idx][0]; +} + +/** + * Parse a VLC code. + * @param bits is the number of bits which will be read at once, must be + * identical to nb_bits in init_vlc() + * @param max_depth is the number of times bits bits must be read to completely + * read the longest VLC code + * = (max_vlc_length + bits - 1) / bits + * If the VLC code is invalid and max_depth = 1, then no bits will be removed. + * If the VLC code is invalid and max_depth > 1, then the number of bits removed + * is undefined. */ +static inline int bitstream_read_vlc(BitstreamContext *bc, VLC_TYPE (*table)[2], + int bits, int max_depth) +{ + int nb_bits; + unsigned idx = bitstream_peek(bc, bits); + int code = table[idx][0]; + int n = table[idx][1]; + + if (max_depth > 1 && n < 0) { + skip_remaining(bc, bits); + code = set_idx(bc, code, &n, &nb_bits, table); + if (max_depth > 2 && n < 0) { + skip_remaining(bc, nb_bits); + code = set_idx(bc, code, &n, &nb_bits, table); + } + } + skip_remaining(bc, n); + + return code; +} + +#define BITSTREAM_RL_VLC(level, run, bc, table, bits, max_depth) \ + do { \ + int n, nb_bits; \ + unsigned index = bitstream_peek(bc, bits); \ + level = table[index].level; \ + n = table[index].len; \ + \ + if (max_depth > 1 && n < 0) { \ + bitstream_skip(bc, bits); \ + \ + nb_bits = -n; \ + \ + index = bitstream_peek(bc, nb_bits) + level; \ + level = table[index].level; \ + n = table[index].len; \ + if (max_depth > 2 && n < 0) { \ + bitstream_skip(bc, nb_bits); \ + nb_bits = -n; \ + \ + index = bitstream_peek(bc, nb_bits) + level; \ + level = table[index].level; \ + n = table[index].len; \ + } \ + } \ + run = table[index].run; \ + bitstream_skip(bc, n); \ + } while (0) + +/* Return decoded truncated unary code for the values 0, 1, 2. */ +static inline int bitstream_decode012(BitstreamContext *bc) +{ + if (!bitstream_read_bit(bc)) + return 0; + else + return bitstream_read_bit(bc) + 1; +} + +/* Return decoded truncated unary code for the values 2, 1, 0. */ +static inline int bitstream_decode210(BitstreamContext *bc) +{ + if (bitstream_read_bit(bc)) + return 0; + else + return 2 - bitstream_read_bit(bc); +} + +/* Read sign bit and flip the sign of the provided value accordingly. */ +static inline int bitstream_apply_sign(BitstreamContext *bc, int val) +{ + int sign = bitstream_read_signed(bc, 1); + return (val ^ sign) - sign; +} + +#endif /* AVCODEC_BITSTREAM_H */ From d182d8a6d3203f7fbab11179e88f26b8befe899e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 6 Feb 2016 21:41:31 +0100 Subject: [PATCH 0498/3374] cllc: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/cllc.c | 88 +++++++++++++++++++---------------------------- 1 file changed, 36 insertions(+), 52 deletions(-) diff --git a/libavcodec/cllc.c b/libavcodec/cllc.c index cdbed74474e30..bac2b730e1b90 100644 --- a/libavcodec/cllc.c +++ b/libavcodec/cllc.c @@ -23,11 +23,13 @@ #include #include "libavutil/intreadwrite.h" + +#include "bitstream.h" #include "bswapdsp.h" #include "canopus.h" -#include "get_bits.h" #include "avcodec.h" #include "internal.h" +#include "vlc.h" typedef struct CLLCContext { AVCodecContext *avctx; @@ -37,7 +39,7 @@ typedef struct CLLCContext { int swapped_buf_size; } CLLCContext; -static int read_code_table(CLLCContext *ctx, GetBitContext *gb, VLC *vlc) +static int read_code_table(CLLCContext *ctx, BitstreamContext *bc, VLC *vlc) { uint8_t symbols[256]; uint8_t bits[256]; @@ -49,10 +51,10 @@ static int read_code_table(CLLCContext *ctx, GetBitContext *gb, VLC *vlc) count = 0; num_codes_sum = 0; - num_lens = get_bits(gb, 5); + num_lens = bitstream_read(bc, 5); for (i = 0; i < num_lens; i++) { - num_codes = get_bits(gb, 9); + num_codes = bitstream_read(bc, 9); num_codes_sum += num_codes; if (num_codes_sum > 256) { @@ -64,7 +66,7 @@ static int read_code_table(CLLCContext *ctx, GetBitContext *gb, VLC *vlc) } for (j = 0; j < num_codes; j++) { - symbols[count] = get_bits(gb, 8); + symbols[count] = bitstream_read(bc, 8); bits[count] = i + 1; codes[count] = prefix++; @@ -82,7 +84,7 @@ static int read_code_table(CLLCContext *ctx, GetBitContext *gb, VLC *vlc) * Unlike the RGB24 read/restore, which reads in a component at a time, * ARGB read/restore reads in ARGB quads. */ -static int read_argb_line(CLLCContext *ctx, GetBitContext *gb, int *top_left, +static int read_argb_line(CLLCContext *ctx, BitstreamContext *bc, int *top_left, VLC *vlc, uint8_t *outbuf) { uint8_t *dst; @@ -90,8 +92,6 @@ static int read_argb_line(CLLCContext *ctx, GetBitContext *gb, int *top_left, int code; int i; - OPEN_READER(bits, gb); - dst = outbuf; pred[0] = top_left[0]; pred[1] = top_left[1]; @@ -100,8 +100,7 @@ static int read_argb_line(CLLCContext *ctx, GetBitContext *gb, int *top_left, for (i = 0; i < ctx->avctx->width; i++) { /* Always get the alpha component */ - UPDATE_CACHE(bits, gb); - GET_VLC(code, bits, gb, vlc[0].table, 7, 2); + code = bitstream_read_vlc(bc, vlc[0].table, 7, 2); pred[0] += code; dst[0] = pred[0]; @@ -109,22 +108,19 @@ static int read_argb_line(CLLCContext *ctx, GetBitContext *gb, int *top_left, /* Skip the components if they are entirely transparent */ if (dst[0]) { /* Red */ - UPDATE_CACHE(bits, gb); - GET_VLC(code, bits, gb, vlc[1].table, 7, 2); + code = bitstream_read_vlc(bc, vlc[1].table, 7, 2); pred[1] += code; dst[1] = pred[1]; /* Green */ - UPDATE_CACHE(bits, gb); - GET_VLC(code, bits, gb, vlc[2].table, 7, 2); + code = bitstream_read_vlc(bc, vlc[2].table, 7, 2); pred[2] += code; dst[2] = pred[2]; /* Blue */ - UPDATE_CACHE(bits, gb); - GET_VLC(code, bits, gb, vlc[3].table, 7, 2); + code = bitstream_read_vlc(bc, vlc[3].table, 7, 2); pred[3] += code; dst[3] = pred[3]; @@ -137,8 +133,6 @@ static int read_argb_line(CLLCContext *ctx, GetBitContext *gb, int *top_left, dst += 4; } - CLOSE_READER(bits, gb); - top_left[0] = outbuf[0]; /* Only stash components if they are not transparent */ @@ -151,65 +145,55 @@ static int read_argb_line(CLLCContext *ctx, GetBitContext *gb, int *top_left, return 0; } -static int read_rgb24_component_line(CLLCContext *ctx, GetBitContext *gb, +static int read_rgb24_component_line(CLLCContext *ctx, BitstreamContext *bc, int *top_left, VLC *vlc, uint8_t *outbuf) { uint8_t *dst; int pred, code; int i; - OPEN_READER(bits, gb); - dst = outbuf; pred = *top_left; /* Simultaneously read and restore the line */ for (i = 0; i < ctx->avctx->width; i++) { - UPDATE_CACHE(bits, gb); - GET_VLC(code, bits, gb, vlc->table, 7, 2); + code = bitstream_read_vlc(bc, vlc->table, 7, 2); pred += code; dst[0] = pred; dst += 3; } - CLOSE_READER(bits, gb); - /* Stash the first pixel */ *top_left = outbuf[0]; return 0; } -static int read_yuv_component_line(CLLCContext *ctx, GetBitContext *gb, +static int read_yuv_component_line(CLLCContext *ctx, BitstreamContext *bc, int *top_left, VLC *vlc, uint8_t *outbuf, int is_chroma) { int pred, code; int i; - OPEN_READER(bits, gb); - pred = *top_left; /* Simultaneously read and restore the line */ for (i = 0; i < ctx->avctx->width >> is_chroma; i++) { - UPDATE_CACHE(bits, gb); - GET_VLC(code, bits, gb, vlc->table, 7, 2); + code = bitstream_read_vlc(bc, vlc->table, 7, 2); pred += code; outbuf[i] = pred; } - CLOSE_READER(bits, gb); - /* Stash the first pixel */ *top_left = outbuf[0]; return 0; } -static int decode_argb_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) +static int decode_argb_frame(CLLCContext *ctx, BitstreamContext *bc, AVFrame *pic) { AVCodecContext *avctx = ctx->avctx; uint8_t *dst; @@ -225,11 +209,11 @@ static int decode_argb_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) dst = pic->data[0]; - skip_bits(gb, 16); + bitstream_skip(bc, 16); /* Read in code table for each plane */ for (i = 0; i < 4; i++) { - ret = read_code_table(ctx, gb, &vlc[i]); + ret = read_code_table(ctx, bc, &vlc[i]); if (ret < 0) { for (j = 0; j <= i; j++) ff_free_vlc(&vlc[j]); @@ -242,7 +226,7 @@ static int decode_argb_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) /* Read in and restore every line */ for (i = 0; i < avctx->height; i++) { - read_argb_line(ctx, gb, pred, vlc, dst); + read_argb_line(ctx, bc, pred, vlc, dst); dst += pic->linesize[0]; } @@ -253,7 +237,7 @@ static int decode_argb_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) return 0; } -static int decode_rgb24_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) +static int decode_rgb24_frame(CLLCContext *ctx, BitstreamContext *bc, AVFrame *pic) { AVCodecContext *avctx = ctx->avctx; uint8_t *dst; @@ -268,11 +252,11 @@ static int decode_rgb24_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) dst = pic->data[0]; - skip_bits(gb, 16); + bitstream_skip(bc, 16); /* Read in code table for each plane */ for (i = 0; i < 3; i++) { - ret = read_code_table(ctx, gb, &vlc[i]); + ret = read_code_table(ctx, bc, &vlc[i]); if (ret < 0) { for (j = 0; j <= i; j++) ff_free_vlc(&vlc[j]); @@ -286,7 +270,7 @@ static int decode_rgb24_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) /* Read in and restore every line */ for (i = 0; i < avctx->height; i++) { for (j = 0; j < 3; j++) - read_rgb24_component_line(ctx, gb, &pred[j], &vlc[j], &dst[j]); + read_rgb24_component_line(ctx, bc, &pred[j], &vlc[j], &dst[j]); dst += pic->linesize[0]; } @@ -297,7 +281,7 @@ static int decode_rgb24_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) return 0; } -static int decode_yuv_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) +static int decode_yuv_frame(CLLCContext *ctx, BitstreamContext *bc, AVFrame *pic) { AVCodecContext *avctx = ctx->avctx; uint8_t block; @@ -315,9 +299,9 @@ static int decode_yuv_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) dst[1] = pic->data[1]; dst[2] = pic->data[2]; - skip_bits(gb, 8); + bitstream_skip(bc, 8); - block = get_bits(gb, 8); + block = bitstream_read(bc, 8); if (block) { avpriv_request_sample(ctx->avctx, "Blocked YUV"); return AVERROR_PATCHWELCOME; @@ -325,7 +309,7 @@ static int decode_yuv_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) /* Read in code table for luma and chroma */ for (i = 0; i < 2; i++) { - ret = read_code_table(ctx, gb, &vlc[i]); + ret = read_code_table(ctx, bc, &vlc[i]); if (ret < 0) { for (j = 0; j <= i; j++) ff_free_vlc(&vlc[j]); @@ -338,9 +322,9 @@ static int decode_yuv_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) /* Read in and restore every line */ for (i = 0; i < avctx->height; i++) { - read_yuv_component_line(ctx, gb, &pred[0], &vlc[0], dst[0], 0); /* Y */ - read_yuv_component_line(ctx, gb, &pred[1], &vlc[1], dst[1], 1); /* U */ - read_yuv_component_line(ctx, gb, &pred[2], &vlc[1], dst[2], 1); /* V */ + read_yuv_component_line(ctx, bc, &pred[0], &vlc[0], dst[0], 0); /* Y */ + read_yuv_component_line(ctx, bc, &pred[1], &vlc[1], dst[1], 1); /* U */ + read_yuv_component_line(ctx, bc, &pred[2], &vlc[1], dst[2], 1); /* V */ for (j = 0; j < 3; j++) dst[j] += pic->linesize[j]; @@ -360,7 +344,7 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data, uint8_t *src = avpkt->data; uint32_t info_tag, info_offset; int data_size; - GetBitContext gb; + BitstreamContext bc; int coding_type, ret; if (avpkt->size < 4 + 4) { @@ -398,7 +382,7 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data, ctx->bdsp.bswap16_buf((uint16_t *) ctx->swapped_buf, (uint16_t *) src, data_size / 2); - init_get_bits(&gb, ctx->swapped_buf, data_size * 8); + bitstream_init8(&bc, ctx->swapped_buf, data_size); /* * Read in coding type. The types are as follows: @@ -422,7 +406,7 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data, return ret; } - ret = decode_yuv_frame(ctx, &gb, pic); + ret = decode_yuv_frame(ctx, &bc, pic); if (ret < 0) return ret; @@ -438,7 +422,7 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data, return ret; } - ret = decode_rgb24_frame(ctx, &gb, pic); + ret = decode_rgb24_frame(ctx, &bc, pic); if (ret < 0) return ret; @@ -453,7 +437,7 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data, return ret; } - ret = decode_argb_frame(ctx, &gb, pic); + ret = decode_argb_frame(ctx, &bc, pic); if (ret < 0) return ret; From adb1ebb36cdfa787e97eb705a73aa551caed39b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Wed, 17 Feb 2016 18:16:06 +0100 Subject: [PATCH 0499/3374] eamad: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/eamad.c | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/libavcodec/eamad.c b/libavcodec/eamad.c index 070cfdb35507f..7509c2ddd430b 100644 --- a/libavcodec/eamad.c +++ b/libavcodec/eamad.c @@ -29,16 +29,17 @@ */ #include "avcodec.h" +#include "bitstream.h" #include "blockdsp.h" #include "bytestream.h" #include "bswapdsp.h" -#include "get_bits.h" #include "aandcttab.h" #include "eaidct.h" #include "idctdsp.h" #include "internal.h" #include "mpeg12data.h" #include "mpeg12vlc.h" +#include "vlc.h" #define EA_PREAMBLE_SIZE 8 #define MADk_TAG MKTAG('M', 'A', 'D', 'k') /* MAD I-frame */ @@ -51,7 +52,7 @@ typedef struct MadContext { BswapDSPContext bbdsp; IDCTDSPContext idsp; AVFrame *last_frame; - GetBitContext gb; + BitstreamContext bc; void *bitstream_buf; unsigned int bitstream_buf_size; DECLARE_ALIGNED(16, int16_t, block)[64]; @@ -129,17 +130,15 @@ static inline void decode_block_intra(MadContext *s, int16_t * block) const uint8_t *scantable = s->scantable.permutated; int16_t *quant_matrix = s->quant_matrix; - block[0] = (128 + get_sbits(&s->gb, 8)) * quant_matrix[0]; + block[0] = (128 + bitstream_read_signed(&s->bc, 8)) * quant_matrix[0]; /* The RL decoder is derived from mpeg1_decode_block_intra; Escaped level and run values a decoded differently */ i = 0; { - OPEN_READER(re, &s->gb); /* now quantify & encode AC coefficients */ for (;;) { - UPDATE_CACHE(re, &s->gb); - GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); + BITSTREAM_RL_VLC(level, run, &s->bc, rl->rl_vlc[0], TEX_VLC_BITS, 2); if (level == 127) { break; @@ -153,15 +152,12 @@ static inline void decode_block_intra(MadContext *s, int16_t * block) j = scantable[i]; level = (level*quant_matrix[j]) >> 4; level = (level-1)|1; - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - LAST_SKIP_BITS(re, &s->gb, 1); + level = bitstream_apply_sign(&s->bc, level); } else { /* escape */ - UPDATE_CACHE(re, &s->gb); - level = SHOW_SBITS(re, &s->gb, 10); SKIP_BITS(re, &s->gb, 10); + level = bitstream_read_signed(&s->bc, 10); - UPDATE_CACHE(re, &s->gb); - run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6); + run = bitstream_read(&s->bc, 6) + 1; i += run; if (i > 63) { @@ -183,17 +179,17 @@ static inline void decode_block_intra(MadContext *s, int16_t * block) block[j] = level; } - CLOSE_READER(re, &s->gb); } } -static int decode_motion(GetBitContext *gb) +static int decode_motion(BitstreamContext *bc) { int value = 0; - if (get_bits1(gb)) { - if (get_bits1(gb)) + + if (bitstream_read_bit(bc)) { + if (bitstream_read_bit(bc)) value = -17; - value += get_bits(gb, 4) + 1; + value += bitstream_read(bc, 4) + 1; } return value; } @@ -205,11 +201,11 @@ static void decode_mb(MadContext *s, AVFrame *frame, int inter) int j; if (inter) { - int v = decode210(&s->gb); + int v = bitstream_decode210(&s->bc); if (v < 2) { - mv_map = v ? get_bits(&s->gb, 6) : 63; - mv_x = decode_motion(&s->gb); - mv_y = decode_motion(&s->gb); + mv_map = v ? bitstream_read(&s->bc, 6) : 63; + mv_x = decode_motion(&s->bc); + mv_y = decode_motion(&s->bc); } else { mv_map = 0; } @@ -217,7 +213,7 @@ static void decode_mb(MadContext *s, AVFrame *frame, int inter) for (j=0; j<6; j++) { if (mv_map & (1<gb); + int add = 2 * decode_motion(&s->bc); comp_block(s, frame, s->mb_x, s->mb_y, j, mv_x, mv_y, add); } else { s->bdsp.clear_block(s->block); @@ -299,7 +295,7 @@ static int decode_frame(AVCodecContext *avctx, return AVERROR(ENOMEM); s->bbdsp.bswap16_buf(s->bitstream_buf, (const uint16_t *)(buf + bytestream2_tell(&gb)), bytestream2_get_bytes_left(&gb) / 2); - init_get_bits(&s->gb, s->bitstream_buf, 8*(bytestream2_get_bytes_left(&gb))); + bitstream_init8(&s->bc, s->bitstream_buf, bytestream2_get_bytes_left(&gb)); for (s->mb_y=0; s->mb_y < (avctx->height+15)/16; s->mb_y++) for (s->mb_x=0; s->mb_x < (avctx->width +15)/16; s->mb_x++) From 7d957b3f477a8cb333f8ef2697c9aa5363ad0c9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 9 Apr 2016 20:31:47 +0200 Subject: [PATCH 0500/3374] ea: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/eatgq.c | 34 +++++++++++++++++----------------- libavcodec/eatgv.c | 22 +++++++++++----------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/libavcodec/eatgq.c b/libavcodec/eatgq.c index 835547125e2ef..9abedcc7838f6 100644 --- a/libavcodec/eatgq.c +++ b/libavcodec/eatgq.c @@ -31,9 +31,9 @@ #define BITSTREAM_READER_LE #include "aandcttab.h" #include "avcodec.h" +#include "bitstream.h" #include "bytestream.h" #include "eaidct.h" -#include "get_bits.h" #include "idctdsp.h" #include "internal.h" @@ -58,44 +58,44 @@ static av_cold int tgq_decode_init(AVCodecContext *avctx) return 0; } -static void tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb) +static void tgq_decode_block(TgqContext *s, int16_t block[64], BitstreamContext *bc) { uint8_t *perm = s->scantable.permutated; int i, j, value; - block[0] = get_sbits(gb, 8) * s->qtable[0]; + block[0] = bitstream_read_signed(bc, 8) * s->qtable[0]; for (i = 1; i < 64;) { - switch (show_bits(gb, 3)) { + switch (bitstream_peek(bc, 3)) { case 4: block[perm[i++]] = 0; case 0: block[perm[i++]] = 0; - skip_bits(gb, 3); + bitstream_skip(bc, 3); break; case 5: case 1: - skip_bits(gb, 2); - value = get_bits(gb, 6); + bitstream_skip(bc, 2); + value = bitstream_read(bc, 6); for (j = 0; j < value; j++) block[perm[i++]] = 0; break; case 6: - skip_bits(gb, 3); + bitstream_skip(bc, 3); block[perm[i]] = -s->qtable[perm[i]]; i++; break; case 2: - skip_bits(gb, 3); + bitstream_skip(bc, 3); block[perm[i]] = s->qtable[perm[i]]; i++; break; case 7: // 111b case 3: // 011b - skip_bits(gb, 2); - if (show_bits(gb, 6) == 0x3F) { - skip_bits(gb, 6); - block[perm[i]] = get_sbits(gb, 8) * s->qtable[perm[i]]; + bitstream_skip(bc, 2); + if (bitstream_peek(bc, 6) == 0x3F) { + bitstream_skip(bc, 6); + block[perm[i]] = bitstream_read_signed(bc, 8) * s->qtable[perm[i]]; } else { - block[perm[i]] = get_sbits(gb, 6) * s->qtable[perm[i]]; + block[perm[i]] = bitstream_read_signed(bc, 6) * s->qtable[perm[i]]; } i++; break; @@ -156,10 +156,10 @@ static void tgq_decode_mb(TgqContext *s, AVFrame *frame, int mb_y, int mb_x) mode = bytestream2_get_byte(&s->gb); if (mode > 12) { - GetBitContext gb; - init_get_bits(&gb, s->gb.buffer, FFMIN(s->gb.buffer_end - s->gb.buffer, mode) * 8); + BitstreamContext bc; + bitstream_init(&bc, s->gb.buffer, FFMIN(s->gb.buffer_end - s->gb.buffer, mode) * 8); for (i = 0; i < 6; i++) - tgq_decode_block(s, s->block[i], &gb); + tgq_decode_block(s, s->block[i], &bc); tgq_idct_put_mb(s, s->block, frame, mb_x, mb_y); bytestream2_skip(&s->gb, mode); } else { diff --git a/libavcodec/eatgv.c b/libavcodec/eatgv.c index 7a50d010d4ef1..549b5b6d3ca41 100644 --- a/libavcodec/eatgv.c +++ b/libavcodec/eatgv.c @@ -33,7 +33,7 @@ #define BITSTREAM_READER_LE #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "internal.h" #define EA_PREAMBLE_SIZE 8 @@ -153,7 +153,7 @@ static int tgv_decode_inter(TgvContext *s, AVFrame *frame, int num_blocks_packed; int vector_bits; int i,j,x,y; - GetBitContext gb; + BitstreamContext bc; int mvbits; const uint8_t *blocks_raw; @@ -166,7 +166,7 @@ static int tgv_decode_inter(TgvContext *s, AVFrame *frame, vector_bits = AV_RL16(&buf[6]); buf += 12; - if (vector_bits > MIN_CACHE_BITS || !vector_bits) { + if (vector_bits > 32 || !vector_bits) { av_log(s->avctx, AV_LOG_ERROR, "Invalid value for motion vector bits: %d\n", vector_bits); return AVERROR_INVALIDDATA; @@ -195,10 +195,10 @@ static int tgv_decode_inter(TgvContext *s, AVFrame *frame, if (buf + (mvbits >> 3) + 16 * num_blocks_raw + 8 * num_blocks_packed > buf_end) return AVERROR_INVALIDDATA; - init_get_bits(&gb, buf, mvbits); + bitstream_init(&bc, buf, mvbits); for (i = 0; i < num_mvs; i++) { - s->mv_codebook[i][0] = get_sbits(&gb, 10); - s->mv_codebook[i][1] = get_sbits(&gb, 10); + s->mv_codebook[i][0] = bitstream_read_signed(&bc, 10); + s->mv_codebook[i][1] = bitstream_read_signed(&bc, 10); } buf += mvbits >> 3; @@ -207,23 +207,23 @@ static int tgv_decode_inter(TgvContext *s, AVFrame *frame, buf += num_blocks_raw * 16; /* read compressed blocks */ - init_get_bits(&gb, buf, (buf_end - buf) << 3); + bitstream_init(&bc, buf, (buf_end - buf) << 3); for (i = 0; i < num_blocks_packed; i++) { int tmp[4]; for (j = 0; j < 4; j++) - tmp[j] = get_bits(&gb, 8); + tmp[j] = bitstream_read(&bc, 8); for (j = 0; j < 16; j++) - s->block_codebook[i][15-j] = tmp[get_bits(&gb, 2)]; + s->block_codebook[i][15-j] = tmp[bitstream_read(&bc, 2)]; } - if (get_bits_left(&gb) < vector_bits * + if (bitstream_bits_left(&bc) < vector_bits * (s->avctx->height / 4) * (s->avctx->width / 4)) return AVERROR_INVALIDDATA; /* read vectors and build frame */ for (y = 0; y < s->avctx->height / 4; y++) for (x = 0; x < s->avctx->width / 4; x++) { - unsigned int vector = get_bits(&gb, vector_bits); + unsigned int vector = bitstream_read(&bc, vector_bits); const uint8_t *src; ptrdiff_t src_stride; From b25180801bd0a544e5c49efb92dbe78904289a8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Mon, 21 Mar 2016 20:46:58 +0100 Subject: [PATCH 0501/3374] on2avc: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/on2avc.c | 64 +++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/libavcodec/on2avc.c b/libavcodec/on2avc.c index 2a528c6f3be2c..1b81980f7dd70 100644 --- a/libavcodec/on2avc.c +++ b/libavcodec/on2avc.c @@ -22,11 +22,13 @@ #include "libavutil/channel_layout.h" #include "libavutil/float_dsp.h" + #include "avcodec.h" +#include "bitstream.h" #include "bytestream.h" #include "fft.h" -#include "get_bits.h" #include "internal.h" +#include "vlc.h" #include "on2avcdata.h" @@ -84,11 +86,11 @@ typedef struct On2AVCContext { DECLARE_ALIGNED(32, float, short_win)[ON2AVC_SUBFRAME_SIZE / 8]; } On2AVCContext; -static void on2avc_read_ms_info(On2AVCContext *c, GetBitContext *gb) +static void on2avc_read_ms_info(On2AVCContext *c, BitstreamContext *bc) { int w, b, band_off = 0; - c->ms_present = get_bits1(gb); + c->ms_present = bitstream_read_bit(bc); if (!c->ms_present) return; for (w = 0; w < c->num_windows; w++) { @@ -100,12 +102,12 @@ static void on2avc_read_ms_info(On2AVCContext *c, GetBitContext *gb) continue; } for (b = 0; b < c->num_bands; b++) - c->ms_info[band_off++] = get_bits1(gb); + c->ms_info[band_off++] = bitstream_read_bit(bc); } } // do not see Table 17 in ISO/IEC 13818-7 -static int on2avc_decode_band_types(On2AVCContext *c, GetBitContext *gb) +static int on2avc_decode_band_types(On2AVCContext *c, BitstreamContext *bc) { int bits_per_sect = c->is_long ? 5 : 3; int esc_val = (1 << bits_per_sect) - 1; @@ -113,10 +115,10 @@ static int on2avc_decode_band_types(On2AVCContext *c, GetBitContext *gb) int band = 0, i, band_type, run_len, run; while (band < num_bands) { - band_type = get_bits(gb, 4); + band_type = bitstream_read(bc, 4); run_len = 1; do { - run = get_bits(gb, bits_per_sect); + run = bitstream_read(bc, bits_per_sect); run_len += run; } while (run == esc_val); if (band + run_len > num_bands) { @@ -135,7 +137,7 @@ static int on2avc_decode_band_types(On2AVCContext *c, GetBitContext *gb) // completely not like Table 18 in ISO/IEC 13818-7 // (no intensity stereo, different coding for the first coefficient) -static int on2avc_decode_band_scales(On2AVCContext *c, GetBitContext *gb) +static int on2avc_decode_band_scales(On2AVCContext *c, BitstreamContext *bc) { int w, w2, b, scale, first = 1; int band_off = 0; @@ -165,10 +167,10 @@ static int on2avc_decode_band_scales(On2AVCContext *c, GetBitContext *gb) } } if (first) { - scale = get_bits(gb, 7); + scale = bitstream_read(bc, 7); first = 0; } else { - scale += get_vlc2(gb, c->scale_diff.table, 9, 3) - 60; + scale += bitstream_read_vlc(bc, c->scale_diff.table, 9, 3) - 60; } if (scale < 0 || scale > 127) { av_log(c->avctx, AV_LOG_ERROR, "Invalid scale value %d\n", @@ -188,13 +190,13 @@ static inline float on2avc_scale(int v, float scale) } // spectral data is coded completely differently - there are no unsigned codebooks -static int on2avc_decode_quads(On2AVCContext *c, GetBitContext *gb, float *dst, +static int on2avc_decode_quads(On2AVCContext *c, BitstreamContext *bc, float *dst, int dst_size, int type, float band_scale) { int i, j, val, val1; for (i = 0; i < dst_size; i += 4) { - val = get_vlc2(gb, c->cb_vlc[type].table, 9, 3); + val = bitstream_read_vlc(bc, c->cb_vlc[type].table, 9, 3); for (j = 0; j < 4; j++) { val1 = sign_extend((val >> (12 - j * 4)) & 0xF, 4); @@ -205,11 +207,11 @@ static int on2avc_decode_quads(On2AVCContext *c, GetBitContext *gb, float *dst, return 0; } -static inline int get_egolomb(GetBitContext *gb) +static inline int get_egolomb(BitstreamContext *bc) { int v = 4; - while (get_bits1(gb)) { + while (bitstream_read_bit(bc)) { v++; if (v > 30) { av_log(NULL, AV_LOG_WARNING, "Too large golomb code in get_egolomb.\n"); @@ -218,27 +220,27 @@ static inline int get_egolomb(GetBitContext *gb) } } - return (1 << v) + get_bits_long(gb, v); + return (1 << v) + bitstream_read(bc, v); } -static int on2avc_decode_pairs(On2AVCContext *c, GetBitContext *gb, float *dst, +static int on2avc_decode_pairs(On2AVCContext *c, BitstreamContext *bc, float *dst, int dst_size, int type, float band_scale) { int i, val, val1, val2, sign; for (i = 0; i < dst_size; i += 2) { - val = get_vlc2(gb, c->cb_vlc[type].table, 9, 3); + val = bitstream_read_vlc(bc, c->cb_vlc[type].table, 9, 3); val1 = sign_extend(val >> 8, 8); val2 = sign_extend(val & 0xFF, 8); if (type == ON2AVC_ESC_CB) { if (val1 <= -16 || val1 >= 16) { sign = 1 - (val1 < 0) * 2; - val1 = sign * get_egolomb(gb); + val1 = sign * get_egolomb(bc); } if (val2 <= -16 || val2 >= 16) { sign = 1 - (val2 < 0) * 2; - val2 = sign * get_egolomb(gb); + val2 = sign * get_egolomb(bc); } } @@ -249,15 +251,15 @@ static int on2avc_decode_pairs(On2AVCContext *c, GetBitContext *gb, float *dst, return 0; } -static int on2avc_read_channel_data(On2AVCContext *c, GetBitContext *gb, int ch) +static int on2avc_read_channel_data(On2AVCContext *c, BitstreamContext *bc, int ch) { int ret; int w, b, band_idx; float *coeff_ptr; - if ((ret = on2avc_decode_band_types(c, gb)) < 0) + if ((ret = on2avc_decode_band_types(c, bc)) < 0) return ret; - if ((ret = on2avc_decode_band_scales(c, gb)) < 0) + if ((ret = on2avc_decode_band_scales(c, bc)) < 0) return ret; coeff_ptr = c->coeffs[ch]; @@ -273,10 +275,10 @@ static int on2avc_read_channel_data(On2AVCContext *c, GetBitContext *gb, int ch) continue; } if (band_type < 9) - on2avc_decode_quads(c, gb, coeff_ptr, band_size, band_type, + on2avc_decode_quads(c, bc, coeff_ptr, band_size, band_type, c->band_scales[band_idx + b]); else - on2avc_decode_pairs(c, gb, coeff_ptr, band_size, band_type, + on2avc_decode_pairs(c, bc, coeff_ptr, band_size, band_type, c->band_scales[band_idx + b]); coeff_ptr += band_size; } @@ -797,16 +799,16 @@ static int on2avc_reconstruct_channel(On2AVCContext *c, int channel, static int on2avc_decode_subframe(On2AVCContext *c, const uint8_t *buf, int buf_size, AVFrame *dst, int offset) { - GetBitContext gb; + BitstreamContext bc; int i, ret; - init_get_bits(&gb, buf, buf_size * 8); - if (get_bits1(&gb)) { + bitstream_init8(&bc, buf, buf_size); + if (bitstream_read_bit(&bc)) { av_log(c->avctx, AV_LOG_ERROR, "enh bit set\n"); return AVERROR_INVALIDDATA; } c->prev_window_type = c->window_type; - c->window_type = get_bits(&gb, 3); + c->window_type = bitstream_read(&bc, 3); if (c->window_type >= WINDOW_TYPE_EXT4 && c->avctx->channels == 1) { av_log(c->avctx, AV_LOG_ERROR, "stereo mode window for mono audio\n"); return AVERROR_INVALIDDATA; @@ -819,11 +821,11 @@ static int on2avc_decode_subframe(On2AVCContext *c, const uint8_t *buf, c->grouping[0] = 1; for (i = 1; i < c->num_windows; i++) - c->grouping[i] = !get_bits1(&gb); + c->grouping[i] = !bitstream_read_bit(&bc); - on2avc_read_ms_info(c, &gb); + on2avc_read_ms_info(c, &bc); for (i = 0; i < c->avctx->channels; i++) - if ((ret = on2avc_read_channel_data(c, &gb, i)) < 0) + if ((ret = on2avc_read_channel_data(c, &bc, i)) < 0) return AVERROR_INVALIDDATA; if (c->avctx->channels == 2 && c->ms_present) on2avc_apply_ms(c); From ed006ae4e2534084552a791a6fe9ebce1fa27a23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Thu, 7 Apr 2016 12:32:52 +0200 Subject: [PATCH 0502/3374] 4xm: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/4xm.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index b2d4db26b0555..ee9d0205d5a82 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -29,11 +29,12 @@ #include "libavutil/frame.h" #include "libavutil/imgutils.h" #include "libavutil/intreadwrite.h" + #include "avcodec.h" +#include "bitstream.h" #include "blockdsp.h" #include "bswapdsp.h" #include "bytestream.h" -#include "get_bits.h" #include "internal.h" #define BLOCK_TYPE_VLC_BITS 5 @@ -136,8 +137,8 @@ typedef struct FourXContext { BswapDSPContext bbdsp; uint16_t *frame_buffer; uint16_t *last_frame_buffer; - GetBitContext pre_gb; ///< ac/dc prefix - GetBitContext gb; + BitstreamContext pre_bc; // ac/dc prefix + BitstreamContext bc; GetByteContext g; GetByteContext g2; int mv[256]; @@ -352,8 +353,8 @@ static int decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, return AVERROR_INVALIDDATA; h = 1 << log2h; - code = get_vlc2(&f->gb, block_type_vlc[1 - (f->version > 1)][index].table, - BLOCK_TYPE_VLC_BITS, 1); + code = bitstream_read_vlc(&f->bc, block_type_vlc[1 - (f->version > 1)][index].table, + BLOCK_TYPE_VLC_BITS, 1); if (code < 0 || code > 6) return AVERROR_INVALIDDATA; @@ -453,7 +454,7 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length) bitstream_size / 4); memset((uint8_t*)f->bitstream_buffer + bitstream_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); - init_get_bits(&f->gb, f->bitstream_buffer, 8 * bitstream_size); + bitstream_init(&f->bc, f->bitstream_buffer, 8 * bitstream_size); wordstream_offset = extra + bitstream_size; bytestream_offset = extra + bitstream_size + wordstream_size; @@ -484,19 +485,19 @@ static int decode_i_block(FourXContext *f, int16_t *block) int code, i, j, level, val; /* DC coef */ - val = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3); + val = bitstream_read_vlc(&f->pre_bc, f->pre_vlc.table, ACDC_VLC_BITS, 3); if (val >> 4) av_log(f->avctx, AV_LOG_ERROR, "error dc run != 0\n"); if (val) - val = get_xbits(&f->gb, val); + val = bitstream_read_xbits(&f->bc, val); val = val * dequant_table[0] + f->last_dc; f->last_dc = block[0] = val; /* AC coefs */ i = 1; for (;;) { - code = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3); + code = bitstream_read_vlc(&f->pre_bc, f->pre_vlc.table, ACDC_VLC_BITS, 3); /* EOB */ if (code == 0) @@ -504,7 +505,7 @@ static int decode_i_block(FourXContext *f, int16_t *block) if (code == 0xf0) { i += 16; } else { - level = get_xbits(&f->gb, code & 0xf); + level = bitstream_read_xbits(&f->bc, code & 0xf); i += code >> 4; if (i >= 64) { av_log(f->avctx, AV_LOG_ERROR, "run %d oveflow\n", i); @@ -764,7 +765,7 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length) return AVERROR_INVALIDDATA; } - init_get_bits(&f->gb, buf + 4, 8 * bitstream_size); + bitstream_init(&f->bc, buf + 4, 8 * bitstream_size); prestream_size = length + buf - prestream; @@ -776,7 +777,7 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length) prestream_size / 4); memset((uint8_t*)f->bitstream_buffer + prestream_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); - init_get_bits(&f->pre_gb, f->bitstream_buffer, 8 * prestream_size); + bitstream_init(&f->pre_bc, f->bitstream_buffer, 8 * prestream_size); f->last_dc = 0 * 128 * 8 * 8; @@ -789,7 +790,7 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length) } } - if (get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3) != 256) + if (bitstream_read_vlc(&f->pre_bc, f->pre_vlc.table, ACDC_VLC_BITS, 3) != 256) av_log(f->avctx, AV_LOG_ERROR, "end mismatch\n"); return 0; From 012c4511539f9f8e252c49d08c7e528973a22193 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Thu, 7 Apr 2016 21:38:52 +0200 Subject: [PATCH 0503/3374] adpcm: Convert to the new bitstream header Signed-off-by: Anton Khirnov --- libavcodec/adpcm.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 3ab16dd0b41ce..fe51c0d00815e 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -29,8 +29,9 @@ * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "put_bits.h" #include "bytestream.h" #include "adpcm.h" @@ -366,32 +367,33 @@ static int xa_decode(AVCodecContext *avctx, int16_t *out0, int16_t *out1, static void adpcm_swf_decode(AVCodecContext *avctx, const uint8_t *buf, int buf_size, int16_t *samples) { ADPCMDecodeContext *c = avctx->priv_data; - GetBitContext gb; + BitstreamContext bc; const int *table; int k0, signmask, nb_bits, count; int size = buf_size*8; int i; - init_get_bits(&gb, buf, size); + bitstream_init(&bc, buf, size); //read bits & initial values - nb_bits = get_bits(&gb, 2)+2; + nb_bits = bitstream_read(&bc, 2)+2; table = swf_index_tables[nb_bits-2]; k0 = 1 << (nb_bits-2); signmask = 1 << (nb_bits-1); - while (get_bits_count(&gb) <= size - 22*avctx->channels) { + while (bitstream_tell(&bc) <= size - 22 * avctx->channels) { for (i = 0; i < avctx->channels; i++) { - *samples++ = c->status[i].predictor = get_sbits(&gb, 16); - c->status[i].step_index = get_bits(&gb, 6); + *samples++ = + c->status[i].predictor = bitstream_read_signed(&bc, 16); + c->status[i].step_index = bitstream_read(&bc, 6); } - for (count = 0; get_bits_count(&gb) <= size - nb_bits*avctx->channels && count < 4095; count++) { + for (count = 0; bitstream_tell(&bc) <= size - nb_bits * avctx->channels && count < 4095; count++) { int i; for (i = 0; i < avctx->channels; i++) { // similar to IMA adpcm - int delta = get_bits(&gb, nb_bits); + int delta = bitstream_read(&bc, nb_bits); int step = ff_adpcm_step_table[c->status[i].step_index]; long vpdiff = 0; // vpdiff = (delta+0.5)*step/4 int k = k0; From 41679be1a2d82847a834a839356dfddc162bbb3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Fri, 8 Apr 2016 20:13:19 +0200 Subject: [PATCH 0504/3374] asvdec: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/asv.h | 4 ++-- libavcodec/asvdec.c | 54 ++++++++++++++++++++++----------------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/libavcodec/asv.h b/libavcodec/asv.h index 18f7a9571d065..7c4e4fd92a2c5 100644 --- a/libavcodec/asv.h +++ b/libavcodec/asv.h @@ -31,11 +31,11 @@ #include "libavutil/mem.h" #include "avcodec.h" +#include "bitstream.h" #include "blockdsp.h" #include "bswapdsp.h" #include "fdctdsp.h" #include "idctdsp.h" -#include "get_bits.h" #include "pixblockdsp.h" #include "put_bits.h" @@ -47,7 +47,7 @@ typedef struct ASV1Context { IDCTDSPContext idsp; PixblockDSPContext pdsp; PutBitContext pb; - GetBitContext gb; + BitstreamContext bc; ScanTable scantable; int inv_qscale; int mb_width; diff --git a/libavcodec/asvdec.c b/libavcodec/asvdec.c index f17f06465cd44..cbda63d3b0c75 100644 --- a/libavcodec/asvdec.c +++ b/libavcodec/asvdec.c @@ -70,27 +70,27 @@ static av_cold void init_vlcs(ASV1Context *a) } // FIXME write a reversed bitstream reader to avoid the double reverse -static inline int asv2_get_bits(GetBitContext *gb, int n) +static inline int asv2_get_bits(BitstreamContext *bc, int n) { - return ff_reverse[get_bits(gb, n) << (8 - n)]; + return ff_reverse[bitstream_read(bc, n) << (8 - n)]; } -static inline int asv1_get_level(GetBitContext *gb) +static inline int asv1_get_level(BitstreamContext *bc) { - int code = get_vlc2(gb, level_vlc.table, VLC_BITS, 1); + int code = bitstream_read_vlc(bc, level_vlc.table, VLC_BITS, 1); if (code == 3) - return get_sbits(gb, 8); + return bitstream_read_signed(bc, 8); else return code - 3; } -static inline int asv2_get_level(GetBitContext *gb) +static inline int asv2_get_level(BitstreamContext *bc) { - int code = get_vlc2(gb, asv2_level_vlc.table, ASV2_LEVEL_VLC_BITS, 1); + int code = bitstream_read_vlc(bc, asv2_level_vlc.table, ASV2_LEVEL_VLC_BITS, 1); if (code == 31) - return (int8_t) asv2_get_bits(gb, 8); + return (int8_t) asv2_get_bits(bc, 8); else return code - 31; } @@ -99,10 +99,10 @@ static inline int asv1_decode_block(ASV1Context *a, int16_t block[64]) { int i; - block[0] = 8 * get_bits(&a->gb, 8); + block[0] = 8 * bitstream_read(&a->bc, 8); for (i = 0; i < 11; i++) { - const int ccp = get_vlc2(&a->gb, ccp_vlc.table, VLC_BITS, 1); + const int ccp = bitstream_read_vlc(&a->bc, ccp_vlc.table, VLC_BITS, 1); if (ccp) { if (ccp == 16) @@ -113,13 +113,13 @@ static inline int asv1_decode_block(ASV1Context *a, int16_t block[64]) } if (ccp & 8) - block[a->scantable.permutated[4 * i + 0]] = (asv1_get_level(&a->gb) * a->intra_matrix[4 * i + 0]) >> 4; + block[a->scantable.permutated[4 * i + 0]] = (asv1_get_level(&a->bc) * a->intra_matrix[4 * i + 0]) >> 4; if (ccp & 4) - block[a->scantable.permutated[4 * i + 1]] = (asv1_get_level(&a->gb) * a->intra_matrix[4 * i + 1]) >> 4; + block[a->scantable.permutated[4 * i + 1]] = (asv1_get_level(&a->bc) * a->intra_matrix[4 * i + 1]) >> 4; if (ccp & 2) - block[a->scantable.permutated[4 * i + 2]] = (asv1_get_level(&a->gb) * a->intra_matrix[4 * i + 2]) >> 4; + block[a->scantable.permutated[4 * i + 2]] = (asv1_get_level(&a->bc) * a->intra_matrix[4 * i + 2]) >> 4; if (ccp & 1) - block[a->scantable.permutated[4 * i + 3]] = (asv1_get_level(&a->gb) * a->intra_matrix[4 * i + 3]) >> 4; + block[a->scantable.permutated[4 * i + 3]] = (asv1_get_level(&a->bc) * a->intra_matrix[4 * i + 3]) >> 4; } } @@ -130,32 +130,32 @@ static inline int asv2_decode_block(ASV1Context *a, int16_t block[64]) { int i, count, ccp; - count = asv2_get_bits(&a->gb, 4); + count = asv2_get_bits(&a->bc, 4); - block[0] = 8 * asv2_get_bits(&a->gb, 8); + block[0] = 8 * asv2_get_bits(&a->bc, 8); - ccp = get_vlc2(&a->gb, dc_ccp_vlc.table, VLC_BITS, 1); + ccp = bitstream_read_vlc(&a->bc, dc_ccp_vlc.table, VLC_BITS, 1); if (ccp) { if (ccp & 4) - block[a->scantable.permutated[1]] = (asv2_get_level(&a->gb) * a->intra_matrix[1]) >> 4; + block[a->scantable.permutated[1]] = (asv2_get_level(&a->bc) * a->intra_matrix[1]) >> 4; if (ccp & 2) - block[a->scantable.permutated[2]] = (asv2_get_level(&a->gb) * a->intra_matrix[2]) >> 4; + block[a->scantable.permutated[2]] = (asv2_get_level(&a->bc) * a->intra_matrix[2]) >> 4; if (ccp & 1) - block[a->scantable.permutated[3]] = (asv2_get_level(&a->gb) * a->intra_matrix[3]) >> 4; + block[a->scantable.permutated[3]] = (asv2_get_level(&a->bc) * a->intra_matrix[3]) >> 4; } for (i = 1; i < count + 1; i++) { - const int ccp = get_vlc2(&a->gb, ac_ccp_vlc.table, VLC_BITS, 1); + const int ccp = bitstream_read_vlc(&a->bc, ac_ccp_vlc.table, VLC_BITS, 1); if (ccp) { if (ccp & 8) - block[a->scantable.permutated[4 * i + 0]] = (asv2_get_level(&a->gb) * a->intra_matrix[4 * i + 0]) >> 4; + block[a->scantable.permutated[4 * i + 0]] = (asv2_get_level(&a->bc) * a->intra_matrix[4 * i + 0]) >> 4; if (ccp & 4) - block[a->scantable.permutated[4 * i + 1]] = (asv2_get_level(&a->gb) * a->intra_matrix[4 * i + 1]) >> 4; + block[a->scantable.permutated[4 * i + 1]] = (asv2_get_level(&a->bc) * a->intra_matrix[4 * i + 1]) >> 4; if (ccp & 2) - block[a->scantable.permutated[4 * i + 2]] = (asv2_get_level(&a->gb) * a->intra_matrix[4 * i + 2]) >> 4; + block[a->scantable.permutated[4 * i + 2]] = (asv2_get_level(&a->bc) * a->intra_matrix[4 * i + 2]) >> 4; if (ccp & 1) - block[a->scantable.permutated[4 * i + 3]] = (asv2_get_level(&a->gb) * a->intra_matrix[4 * i + 3]) >> 4; + block[a->scantable.permutated[4 * i + 3]] = (asv2_get_level(&a->bc) * a->intra_matrix[4 * i + 3]) >> 4; } } @@ -232,7 +232,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, a->bitstream_buffer[i] = ff_reverse[buf[i]]; } - init_get_bits(&a->gb, a->bitstream_buffer, buf_size * 8); + bitstream_init(&a->bc, a->bitstream_buffer, buf_size * 8); for (mb_y = 0; mb_y < a->mb_height2; mb_y++) { for (mb_x = 0; mb_x < a->mb_width2; mb_x++) { @@ -267,7 +267,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, emms_c(); - return (get_bits_count(&a->gb) + 31) / 32 * 4; + return (bitstream_tell(&a->bc) + 31) / 32 * 4; } static av_cold int decode_init(AVCodecContext *avctx) From 027211920222b2b63ca07d712b3771a14add9aab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sun, 17 Apr 2016 17:06:09 +0200 Subject: [PATCH 0505/3374] atrac: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/atrac1.c | 34 ++++++++-------- libavcodec/atrac3.c | 97 +++++++++++++++++++++++---------------------- 2 files changed, 67 insertions(+), 64 deletions(-) diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c index e938976d88e2d..60be85358889f 100644 --- a/libavcodec/atrac1.c +++ b/libavcodec/atrac1.c @@ -33,8 +33,9 @@ #include #include "libavutil/float_dsp.h" + #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "fft.h" #include "internal.h" #include "sinewin.h" @@ -164,30 +165,31 @@ static int at1_imdct_block(AT1SUCtx* su, AT1Ctx *q) * Parse the block size mode byte */ -static int at1_parse_bsm(GetBitContext* gb, int log2_block_cnt[AT1_QMF_BANDS]) +static int at1_parse_bsm(BitstreamContext *bc, + int log2_block_cnt[AT1_QMF_BANDS]) { int log2_block_count_tmp, i; for (i = 0; i < 2; i++) { /* low and mid band */ - log2_block_count_tmp = get_bits(gb, 2); + log2_block_count_tmp = bitstream_read(bc, 2); if (log2_block_count_tmp & 1) return AVERROR_INVALIDDATA; log2_block_cnt[i] = 2 - log2_block_count_tmp; } /* high band */ - log2_block_count_tmp = get_bits(gb, 2); + log2_block_count_tmp = bitstream_read(bc, 2); if (log2_block_count_tmp != 0 && log2_block_count_tmp != 3) return AVERROR_INVALIDDATA; log2_block_cnt[IDX_HIGH_BAND] = 3 - log2_block_count_tmp; - skip_bits(gb, 2); + bitstream_skip(bc, 2); return 0; } -static int at1_unpack_dequant(GetBitContext* gb, AT1SUCtx* su, +static int at1_unpack_dequant(BitstreamContext *bc, AT1SUCtx *su, float spec[AT1_SU_SAMPLES]) { int bits_used, band_num, bfu_num, i; @@ -195,22 +197,22 @@ static int at1_unpack_dequant(GetBitContext* gb, AT1SUCtx* su, uint8_t idsfs[AT1_MAX_BFU]; ///< the scalefactor indexes for each BFU /* parse the info byte (2nd byte) telling how much BFUs were coded */ - su->num_bfus = bfu_amount_tab1[get_bits(gb, 3)]; + su->num_bfus = bfu_amount_tab1[bitstream_read(bc, 3)]; /* calc number of consumed bits: num_BFUs * (idwl(4bits) + idsf(6bits)) + log2_block_count(8bits) + info_byte(8bits) + info_byte_copy(8bits) + log2_block_count_copy(8bits) */ bits_used = su->num_bfus * 10 + 32 + - bfu_amount_tab2[get_bits(gb, 2)] + - (bfu_amount_tab3[get_bits(gb, 3)] << 1); + bfu_amount_tab2[bitstream_read(bc, 2)] + + (bfu_amount_tab3[bitstream_read(bc, 3)] << 1); /* get word length index (idwl) for each BFU */ for (i = 0; i < su->num_bfus; i++) - idwls[i] = get_bits(gb, 4); + idwls[i] = bitstream_read(bc, 4); /* get scalefactor index (idsf) for each BFU */ for (i = 0; i < su->num_bfus; i++) - idsfs[i] = get_bits(gb, 6); + idsfs[i] = bitstream_read(bc, 6); /* zero idwl/idsf for empty BFUs */ for (i = su->num_bfus; i < AT1_MAX_BFU; i++) @@ -240,7 +242,7 @@ static int at1_unpack_dequant(GetBitContext* gb, AT1SUCtx* su, /* read in a quantized spec and convert it to * signed int and then inverse quantization */ - spec[pos+i] = get_sbits(gb, word_len) * scale_factor * max_quant; + spec[pos+i] = bitstream_read_signed(bc, word_len) * scale_factor * max_quant; } } else { /* word_len = 0 -> empty BFU, zero all specs in the emty BFU */ memset(&spec[pos], 0, num_specs * sizeof(float)); @@ -277,7 +279,7 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data, int buf_size = avpkt->size; AT1Ctx *q = avctx->priv_data; int ch, ret; - GetBitContext gb; + BitstreamContext bc; if (buf_size < 212 * avctx->channels) { @@ -295,14 +297,14 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data, for (ch = 0; ch < avctx->channels; ch++) { AT1SUCtx* su = &q->SUs[ch]; - init_get_bits(&gb, &buf[212 * ch], 212 * 8); + bitstream_init(&bc, &buf[212 * ch], 212 * 8); /* parse block_size_mode, 1st byte */ - ret = at1_parse_bsm(&gb, su->log2_block_count); + ret = at1_parse_bsm(&bc, su->log2_block_count); if (ret < 0) return ret; - ret = at1_unpack_dequant(&gb, su, q->spec); + ret = at1_unpack_dequant(&bc, su, q->spec); if (ret < 0) return ret; diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index 2e1fd3c13362b..be32a0ec864d8 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -38,10 +38,11 @@ #include "libavutil/attributes.h" #include "libavutil/float_dsp.h" + #include "avcodec.h" +#include "bitstream.h" #include "bytestream.h" #include "fft.h" -#include "get_bits.h" #include "internal.h" #include "atrac.h" @@ -80,7 +81,7 @@ typedef struct ChannelUnit { } ChannelUnit; typedef struct ATRAC3Context { - GetBitContext gb; + BitstreamContext bc; //@{ /** stream data */ int coding_mode; @@ -203,7 +204,7 @@ static av_cold int atrac3_decode_close(AVCodecContext *avctx) * @param mantissas mantissa output table * @param num_codes number of values to get */ -static void read_quant_spectral_coeffs(GetBitContext *gb, int selector, +static void read_quant_spectral_coeffs(BitstreamContext *bc, int selector, int coding_flag, int *mantissas, int num_codes) { @@ -219,7 +220,7 @@ static void read_quant_spectral_coeffs(GetBitContext *gb, int selector, if (selector > 1) { for (i = 0; i < num_codes; i++) { if (num_bits) - code = get_sbits(gb, num_bits); + code = bitstream_read_signed(bc, num_bits); else code = 0; mantissas[i] = code; @@ -227,7 +228,7 @@ static void read_quant_spectral_coeffs(GetBitContext *gb, int selector, } else { for (i = 0; i < num_codes; i++) { if (num_bits) - code = get_bits(gb, num_bits); // num_bits is always 4 in this case + code = bitstream_read(bc, num_bits); // num_bits is always 4 in this case else code = 0; mantissas[i * 2 ] = mantissa_clc_tab[code >> 2]; @@ -238,8 +239,8 @@ static void read_quant_spectral_coeffs(GetBitContext *gb, int selector, /* variable length coding (VLC) */ if (selector != 1) { for (i = 0; i < num_codes; i++) { - huff_symb = get_vlc2(gb, spectral_coeff_tab[selector-1].table, - spectral_coeff_tab[selector-1].bits, 3); + huff_symb = bitstream_read_vlc(bc, spectral_coeff_tab[selector-1].table, + spectral_coeff_tab[selector-1].bits, 3); huff_symb += 1; code = huff_symb >> 1; if (huff_symb & 1) @@ -248,8 +249,8 @@ static void read_quant_spectral_coeffs(GetBitContext *gb, int selector, } } else { for (i = 0; i < num_codes; i++) { - huff_symb = get_vlc2(gb, spectral_coeff_tab[selector - 1].table, - spectral_coeff_tab[selector - 1].bits, 3); + huff_symb = bitstream_read_vlc(bc, spectral_coeff_tab[selector - 1].table, + spectral_coeff_tab[selector - 1].bits, 3); mantissas[i * 2 ] = mantissa_vlc_tab[huff_symb * 2 ]; mantissas[i * 2 + 1] = mantissa_vlc_tab[huff_symb * 2 + 1]; } @@ -262,24 +263,24 @@ static void read_quant_spectral_coeffs(GetBitContext *gb, int selector, * * @return subband count, fix for broken specification/files */ -static int decode_spectrum(GetBitContext *gb, float *output) +static int decode_spectrum(BitstreamContext *bc, float *output) { int num_subbands, coding_mode, i, j, first, last, subband_size; int subband_vlc_index[32], sf_index[32]; int mantissas[128]; float scale_factor; - num_subbands = get_bits(gb, 5); // number of coded subbands - coding_mode = get_bits1(gb); // coding Mode: 0 - VLC/ 1-CLC + num_subbands = bitstream_read(bc, 5); // number of coded subbands + coding_mode = bitstream_read_bit(bc); // coding Mode: 0 - VLC/ 1 - CLC /* get the VLC selector table for the subbands, 0 means not coded */ for (i = 0; i <= num_subbands; i++) - subband_vlc_index[i] = get_bits(gb, 3); + subband_vlc_index[i] = bitstream_read(bc, 3); /* read the scale factor indexes from the stream */ for (i = 0; i <= num_subbands; i++) { if (subband_vlc_index[i] != 0) - sf_index[i] = get_bits(gb, 6); + sf_index[i] = bitstream_read(bc, 6); } for (i = 0; i <= num_subbands; i++) { @@ -292,7 +293,7 @@ static int decode_spectrum(GetBitContext *gb, float *output) /* decode spectral coefficients for this subband */ /* TODO: This can be done faster is several blocks share the * same VLC selector (subband_vlc_index) */ - read_quant_spectral_coeffs(gb, subband_vlc_index[i], coding_mode, + read_quant_spectral_coeffs(bc, subband_vlc_index[i], coding_mode, mantissas, subband_size); /* decode the scale factor for this subband */ @@ -320,7 +321,7 @@ static int decode_spectrum(GetBitContext *gb, float *output) * @param components tonal components * @param num_bands number of coded bands */ -static int decode_tonal_components(GetBitContext *gb, +static int decode_tonal_components(BitstreamContext *bc, TonalComponent *components, int num_bands) { int i, b, c, m; @@ -328,13 +329,13 @@ static int decode_tonal_components(GetBitContext *gb, int band_flags[4], mantissa[8]; int component_count = 0; - nb_components = get_bits(gb, 5); + nb_components = bitstream_read(bc, 5); /* no tonal components */ if (nb_components == 0) return 0; - coding_mode_selector = get_bits(gb, 2); + coding_mode_selector = bitstream_read(bc, 2); if (coding_mode_selector == 2) return AVERROR_INVALIDDATA; @@ -344,16 +345,16 @@ static int decode_tonal_components(GetBitContext *gb, int coded_values_per_component, quant_step_index; for (b = 0; b <= num_bands; b++) - band_flags[b] = get_bits1(gb); + band_flags[b] = bitstream_read_bit(bc); - coded_values_per_component = get_bits(gb, 3); + coded_values_per_component = bitstream_read(bc, 3); - quant_step_index = get_bits(gb, 3); + quant_step_index = bitstream_read(bc, 3); if (quant_step_index <= 1) return AVERROR_INVALIDDATA; if (coding_mode_selector == 3) - coding_mode = get_bits1(gb); + coding_mode = bitstream_read_bit(bc); for (b = 0; b < (num_bands + 1) * 4; b++) { int coded_components; @@ -361,18 +362,18 @@ static int decode_tonal_components(GetBitContext *gb, if (band_flags[b >> 2] == 0) continue; - coded_components = get_bits(gb, 3); + coded_components = bitstream_read(bc, 3); for (c = 0; c < coded_components; c++) { TonalComponent *cmp = &components[component_count]; int sf_index, coded_values, max_coded_values; float scale_factor; - sf_index = get_bits(gb, 6); + sf_index = bitstream_read(bc, 6); if (component_count >= 64) return AVERROR_INVALIDDATA; - cmp->pos = b * 64 + get_bits(gb, 6); + cmp->pos = b * 64 + bitstream_read(bc, 6); max_coded_values = SAMPLES_PER_FRAME - cmp->pos; coded_values = coded_values_per_component + 1; @@ -381,7 +382,7 @@ static int decode_tonal_components(GetBitContext *gb, scale_factor = ff_atrac_sf_table[sf_index] * inv_max_quant[quant_step_index]; - read_quant_spectral_coeffs(gb, quant_step_index, coding_mode, + read_quant_spectral_coeffs(bc, quant_step_index, coding_mode, mantissa, coded_values); cmp->num_coefs = coded_values; @@ -404,7 +405,7 @@ static int decode_tonal_components(GetBitContext *gb, * @param block the gainblock for the current band * @param num_bands amount of coded bands */ -static int decode_gain_control(GetBitContext *gb, GainBlock *block, +static int decode_gain_control(BitstreamContext *bc, GainBlock *block, int num_bands) { int i, j; @@ -413,13 +414,13 @@ static int decode_gain_control(GetBitContext *gb, GainBlock *block, AtracGainInfo *gain = block->g_block; for (i = 0; i <= num_bands; i++) { - gain[i].num_points = get_bits(gb, 3); + gain[i].num_points = bitstream_read(bc, 3); level = gain[i].lev_code; loc = gain[i].loc_code; for (j = 0; j < gain[i].num_points; j++) { - level[j] = get_bits(gb, 4); - loc[j] = get_bits(gb, 5); + level[j] = bitstream_read(bc, 4); + loc[j] = bitstream_read(bc, 5); if (j && loc[j] <= loc[j - 1]) return AVERROR_INVALIDDATA; } @@ -567,7 +568,7 @@ static void channel_weighting(float *su1, float *su2, int *p3) * @param channel_num channel number * @param coding_mode the coding mode (JOINT_STEREO or regular stereo/mono) */ -static int decode_channel_sound_unit(ATRAC3Context *q, GetBitContext *gb, +static int decode_channel_sound_unit(ATRAC3Context *q, BitstreamContext *bc, ChannelUnit *snd, float *output, int channel_num, int coding_mode) { @@ -576,30 +577,30 @@ static int decode_channel_sound_unit(ATRAC3Context *q, GetBitContext *gb, GainBlock *gain2 = &snd->gain_block[1 - snd->gc_blk_switch]; if (coding_mode == JOINT_STEREO && channel_num == 1) { - if (get_bits(gb, 2) != 3) { + if (bitstream_read(bc, 2) != 3) { av_log(NULL,AV_LOG_ERROR,"JS mono Sound Unit id != 3.\n"); return AVERROR_INVALIDDATA; } } else { - if (get_bits(gb, 6) != 0x28) { + if (bitstream_read(bc, 6) != 0x28) { av_log(NULL,AV_LOG_ERROR,"Sound Unit id != 0x28.\n"); return AVERROR_INVALIDDATA; } } /* number of coded QMF bands */ - snd->bands_coded = get_bits(gb, 2); + snd->bands_coded = bitstream_read(bc, 2); - ret = decode_gain_control(gb, gain2, snd->bands_coded); + ret = decode_gain_control(bc, gain2, snd->bands_coded); if (ret) return ret; - snd->num_components = decode_tonal_components(gb, snd->components, + snd->num_components = decode_tonal_components(bc, snd->components, snd->bands_coded); if (snd->num_components < 0) return snd->num_components; - num_subbands = decode_spectrum(gb, snd->spectrum); + num_subbands = decode_spectrum(bc, snd->spectrum); /* Merge the decoded spectrum and tonal components. */ last_tonal = add_tonal_components(snd->spectrum, snd->num_components, @@ -644,9 +645,9 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *databuf, if (q->coding_mode == JOINT_STEREO) { /* channel coupling mode */ /* decode Sound Unit 1 */ - init_get_bits(&q->gb, databuf, avctx->block_align * 8); + bitstream_init(&q->bc, databuf, avctx->block_align * 8); - ret = decode_channel_sound_unit(q, &q->gb, q->units, out_samples[0], 0, + ret = decode_channel_sound_unit(q, &q->bc, q->units, out_samples[0], 0, JOINT_STEREO); if (ret != 0) return ret; @@ -673,22 +674,22 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *databuf, /* set the bitstream reader at the start of the second Sound Unit*/ - init_get_bits(&q->gb, ptr1, (avctx->block_align - i) * 8); + bitstream_init(&q->bc, ptr1, (avctx->block_align - i) * 8); /* Fill the Weighting coeffs delay buffer */ memmove(q->weighting_delay, &q->weighting_delay[2], 4 * sizeof(*q->weighting_delay)); - q->weighting_delay[4] = get_bits1(&q->gb); - q->weighting_delay[5] = get_bits(&q->gb, 3); + q->weighting_delay[4] = bitstream_read_bit(&q->bc); + q->weighting_delay[5] = bitstream_read(&q->bc, 3); for (i = 0; i < 4; i++) { q->matrix_coeff_index_prev[i] = q->matrix_coeff_index_now[i]; q->matrix_coeff_index_now[i] = q->matrix_coeff_index_next[i]; - q->matrix_coeff_index_next[i] = get_bits(&q->gb, 2); + q->matrix_coeff_index_next[i] = bitstream_read(&q->bc, 2); } /* Decode Sound Unit 2. */ - ret = decode_channel_sound_unit(q, &q->gb, &q->units[1], + ret = decode_channel_sound_unit(q, &q->bc, &q->units[1], out_samples[1], 1, JOINT_STEREO); if (ret != 0) return ret; @@ -704,11 +705,11 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *databuf, /* Decode the channel sound units. */ for (i = 0; i < avctx->channels; i++) { /* Set the bitstream reader at the start of a channel sound unit. */ - init_get_bits(&q->gb, - databuf + i * avctx->block_align / avctx->channels, - avctx->block_align * 8 / avctx->channels); + bitstream_init(&q->bc, + databuf + i * avctx->block_align / avctx->channels, + avctx->block_align * 8 / avctx->channels); - ret = decode_channel_sound_unit(q, &q->gb, &q->units[i], + ret = decode_channel_sound_unit(q, &q->bc, &q->units[i], out_samples[i], i, q->coding_mode); if (ret != 0) return ret; From edd4c19a781124cbdb3598f94ec3a0d9ff7058cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 9 Apr 2016 14:47:04 +0200 Subject: [PATCH 0506/3374] atrac3plus: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/atrac3plus.c | 525 +++++++++++++++++++------------------ libavcodec/atrac3plus.h | 7 +- libavcodec/atrac3plusdec.c | 15 +- 3 files changed, 275 insertions(+), 272 deletions(-) diff --git a/libavcodec/atrac3plus.c b/libavcodec/atrac3plus.c index 076fb844a7c0c..2731a80725b7e 100644 --- a/libavcodec/atrac3plus.c +++ b/libavcodec/atrac3plus.c @@ -26,8 +26,9 @@ */ #include "libavutil/avassert.h" + #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "atrac3plus.h" #include "atrac3plus_data.h" @@ -212,20 +213,20 @@ av_cold void ff_atrac3p_init_vlcs(AVCodec *codec) /** * Decode number of coded quantization units. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in,out] chan ptr to the channel parameters * @param[in,out] ctx ptr to the channel unit context * @param[in] avctx ptr to the AVCodecContext * @return result code: 0 = OK, otherwise - error code */ -static int num_coded_units(GetBitContext *gb, Atrac3pChanParams *chan, +static int num_coded_units(BitstreamContext *bc, Atrac3pChanParams *chan, Atrac3pChanUnitCtx *ctx, AVCodecContext *avctx) { - chan->fill_mode = get_bits(gb, 2); + chan->fill_mode = bitstream_read(bc, 2); if (!chan->fill_mode) { chan->num_coded_vals = ctx->num_quant_units; } else { - chan->num_coded_vals = get_bits(gb, 5); + chan->num_coded_vals = bitstream_read(bc, 5); if (chan->num_coded_vals > ctx->num_quant_units) { av_log(avctx, AV_LOG_ERROR, "Invalid number of transmitted units!\n"); @@ -233,7 +234,7 @@ static int num_coded_units(GetBitContext *gb, Atrac3pChanParams *chan, } if (chan->fill_mode == 3) - chan->split_point = get_bits(gb, 2) + (chan->ch_num << 1) + 1; + chan->split_point = bitstream_read(bc, 2) + (chan->ch_num << 1) + 1; } return 0; @@ -318,21 +319,21 @@ static inline void unpack_vq_shape(int start_val, const int8_t *shape_vec, } } -#define UNPACK_SF_VQ_SHAPE(gb, dst, num_vals) \ - start_val = get_bits((gb), 6); \ - unpack_vq_shape(start_val, &atrac3p_sf_shapes[get_bits((gb), 6)][0], \ +#define UNPACK_SF_VQ_SHAPE(bc, dst, num_vals) \ + start_val = bitstream_read((bc), 6); \ + unpack_vq_shape(start_val, &atrac3p_sf_shapes[bitstream_read((bc), 6)][0], \ (dst), (num_vals)) /** * Decode word length for each quantization unit of a channel. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in,out] ctx ptr to the channel unit context * @param[in] ch_num channel to process * @param[in] avctx ptr to the AVCodecContext * @return result code: 0 = OK, otherwise - error code */ -static int decode_channel_wordlen(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, +static int decode_channel_wordlen(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, int ch_num, AVCodecContext *avctx) { int i, weight_idx = 0, delta, diff, pos, delta_bits, min_val, flag, @@ -343,107 +344,107 @@ static int decode_channel_wordlen(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, chan->fill_mode = 0; - switch (get_bits(gb, 2)) { /* switch according to coding mode */ + switch (bitstream_read(bc, 2)) { /* switch according to coding mode */ case 0: /* coded using constant number of bits */ for (i = 0; i < ctx->num_quant_units; i++) - chan->qu_wordlen[i] = get_bits(gb, 3); + chan->qu_wordlen[i] = bitstream_read(bc, 3); break; case 1: if (ch_num) { - if ((ret = num_coded_units(gb, chan, ctx, avctx)) < 0) + if ((ret = num_coded_units(bc, chan, ctx, avctx)) < 0) return ret; if (chan->num_coded_vals) { - vlc_tab = &wl_vlc_tabs[get_bits(gb, 2)]; + vlc_tab = &wl_vlc_tabs[bitstream_read(bc, 2)]; for (i = 0; i < chan->num_coded_vals; i++) { - delta = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + delta = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1); chan->qu_wordlen[i] = (ref_chan->qu_wordlen[i] + delta) & 7; } } } else { - weight_idx = get_bits(gb, 2); - if ((ret = num_coded_units(gb, chan, ctx, avctx)) < 0) + weight_idx = bitstream_read(bc, 2); + if ((ret = num_coded_units(bc, chan, ctx, avctx)) < 0) return ret; if (chan->num_coded_vals) { - pos = get_bits(gb, 5); + pos = bitstream_read(bc, 5); if (pos > chan->num_coded_vals) { av_log(avctx, AV_LOG_ERROR, "WL mode 1: invalid position!\n"); return AVERROR_INVALIDDATA; } - delta_bits = get_bits(gb, 2); - min_val = get_bits(gb, 3); + delta_bits = bitstream_read(bc, 2); + min_val = bitstream_read(bc, 3); for (i = 0; i < pos; i++) - chan->qu_wordlen[i] = get_bits(gb, 3); + chan->qu_wordlen[i] = bitstream_read(bc, 3); for (i = pos; i < chan->num_coded_vals; i++) - chan->qu_wordlen[i] = (min_val + get_bitsz(gb, delta_bits)) & 7; + chan->qu_wordlen[i] = (min_val + bitstream_read(bc, delta_bits)) & 7; } } break; case 2: - if ((ret = num_coded_units(gb, chan, ctx, avctx)) < 0) + if ((ret = num_coded_units(bc, chan, ctx, avctx)) < 0) return ret; if (ch_num && chan->num_coded_vals) { - vlc_tab = &wl_vlc_tabs[get_bits(gb, 2)]; - delta = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + vlc_tab = &wl_vlc_tabs[bitstream_read(bc, 2)]; + delta = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1); chan->qu_wordlen[0] = (ref_chan->qu_wordlen[0] + delta) & 7; for (i = 1; i < chan->num_coded_vals; i++) { diff = ref_chan->qu_wordlen[i] - ref_chan->qu_wordlen[i - 1]; - delta = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + delta = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1); chan->qu_wordlen[i] = (chan->qu_wordlen[i - 1] + diff + delta) & 7; } } else if (chan->num_coded_vals) { - flag = get_bits(gb, 1); - vlc_tab = &wl_vlc_tabs[get_bits(gb, 1)]; + flag = bitstream_read(bc, 1); + vlc_tab = &wl_vlc_tabs[bitstream_read(bc, 1)]; - start_val = get_bits(gb, 3); + start_val = bitstream_read(bc, 3); unpack_vq_shape(start_val, - &atrac3p_wl_shapes[start_val][get_bits(gb, 4)][0], + &atrac3p_wl_shapes[start_val][bitstream_read(bc, 4)][0], chan->qu_wordlen, chan->num_coded_vals); if (!flag) { for (i = 0; i < chan->num_coded_vals; i++) { - delta = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + delta = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1); chan->qu_wordlen[i] = (chan->qu_wordlen[i] + delta) & 7; } } else { for (i = 0; i < (chan->num_coded_vals & - 2); i += 2) - if (!get_bits1(gb)) { + if (!bitstream_read_bit(bc)) { chan->qu_wordlen[i] = (chan->qu_wordlen[i] + - get_vlc2(gb, vlc_tab->table, - vlc_tab->bits, 1)) & 7; + bitstream_read_vlc(bc, vlc_tab->table, + vlc_tab->bits, 1)) & 7; chan->qu_wordlen[i + 1] = (chan->qu_wordlen[i + 1] + - get_vlc2(gb, vlc_tab->table, - vlc_tab->bits, 1)) & 7; + bitstream_read_vlc(bc, vlc_tab->table, + vlc_tab->bits, 1)) & 7; } if (chan->num_coded_vals & 1) chan->qu_wordlen[i] = (chan->qu_wordlen[i] + - get_vlc2(gb, vlc_tab->table, - vlc_tab->bits, 1)) & 7; + bitstream_read_vlc(bc, vlc_tab->table, + vlc_tab->bits, 1)) & 7; } } break; case 3: - weight_idx = get_bits(gb, 2); - if ((ret = num_coded_units(gb, chan, ctx, avctx)) < 0) + weight_idx = bitstream_read(bc, 2); + if ((ret = num_coded_units(bc, chan, ctx, avctx)) < 0) return ret; if (chan->num_coded_vals) { - vlc_tab = &wl_vlc_tabs[get_bits(gb, 2)]; + vlc_tab = &wl_vlc_tabs[bitstream_read(bc, 2)]; /* first coefficient is coded directly */ - chan->qu_wordlen[0] = get_bits(gb, 3); + chan->qu_wordlen[0] = bitstream_read(bc, 3); for (i = 1; i < chan->num_coded_vals; i++) { - delta = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + delta = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1); chan->qu_wordlen[i] = (chan->qu_wordlen[i - 1] + delta) & 7; } } @@ -452,7 +453,7 @@ static int decode_channel_wordlen(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, if (chan->fill_mode == 2) { for (i = chan->num_coded_vals; i < ctx->num_quant_units; i++) - chan->qu_wordlen[i] = ch_num ? get_bits1(gb) : 1; + chan->qu_wordlen[i] = ch_num ? bitstream_read_bit(bc) : 1; } else if (chan->fill_mode == 3) { pos = ch_num ? chan->num_coded_vals + chan->split_point : ctx->num_quant_units - chan->split_point; @@ -469,13 +470,13 @@ static int decode_channel_wordlen(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, /** * Decode scale factor indexes for each quant unit of a channel. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in,out] ctx ptr to the channel unit context * @param[in] ch_num channel to process * @param[in] avctx ptr to the AVCodecContext * @return result code: 0 = OK, otherwise - error code */ -static int decode_channel_sf_idx(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, +static int decode_channel_sf_idx(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, int ch_num, AVCodecContext *avctx) { int i, weight_idx = 0, delta, diff, num_long_vals, @@ -484,40 +485,40 @@ static int decode_channel_sf_idx(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, Atrac3pChanParams *chan = &ctx->channels[ch_num]; Atrac3pChanParams *ref_chan = &ctx->channels[0]; - switch (get_bits(gb, 2)) { /* switch according to coding mode */ + switch (bitstream_read(bc, 2)) { /* switch according to coding mode */ case 0: /* coded using constant number of bits */ for (i = 0; i < ctx->used_quant_units; i++) - chan->qu_sf_idx[i] = get_bits(gb, 6); + chan->qu_sf_idx[i] = bitstream_read(bc, 6); break; case 1: if (ch_num) { - vlc_tab = &sf_vlc_tabs[get_bits(gb, 2)]; + vlc_tab = &sf_vlc_tabs[bitstream_read(bc, 2)]; for (i = 0; i < ctx->used_quant_units; i++) { - delta = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + delta = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1); chan->qu_sf_idx[i] = (ref_chan->qu_sf_idx[i] + delta) & 0x3F; } } else { - weight_idx = get_bits(gb, 2); + weight_idx = bitstream_read(bc, 2); if (weight_idx == 3) { - UNPACK_SF_VQ_SHAPE(gb, chan->qu_sf_idx, ctx->used_quant_units); + UNPACK_SF_VQ_SHAPE(bc, chan->qu_sf_idx, ctx->used_quant_units); - num_long_vals = get_bits(gb, 5); - delta_bits = get_bits(gb, 2); - min_val = get_bits(gb, 4) - 7; + num_long_vals = bitstream_read(bc, 5); + delta_bits = bitstream_read(bc, 2); + min_val = bitstream_read(bc, 4) - 7; for (i = 0; i < num_long_vals; i++) chan->qu_sf_idx[i] = (chan->qu_sf_idx[i] + - get_bits(gb, 4) - 7) & 0x3F; + bitstream_read(bc, 4) - 7) & 0x3F; /* all others are: min_val + delta */ for (i = num_long_vals; i < ctx->used_quant_units; i++) chan->qu_sf_idx[i] = (chan->qu_sf_idx[i] + min_val + - get_bitsz(gb, delta_bits)) & 0x3F; + bitstream_read(bc, delta_bits)) & 0x3F; } else { - num_long_vals = get_bits(gb, 5); - delta_bits = get_bits(gb, 3); - min_val = get_bits(gb, 6); + num_long_vals = bitstream_read(bc, 5); + delta_bits = bitstream_read(bc, 3); + min_val = bitstream_read(bc, 6); if (num_long_vals > ctx->used_quant_units || delta_bits == 7) { av_log(avctx, AV_LOG_ERROR, "SF mode 1: invalid parameters!\n"); @@ -526,34 +527,34 @@ static int decode_channel_sf_idx(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, /* read full-precision SF indexes */ for (i = 0; i < num_long_vals; i++) - chan->qu_sf_idx[i] = get_bits(gb, 6); + chan->qu_sf_idx[i] = bitstream_read(bc, 6); /* all others are: min_val + delta */ for (i = num_long_vals; i < ctx->used_quant_units; i++) chan->qu_sf_idx[i] = (min_val + - get_bitsz(gb, delta_bits)) & 0x3F; + bitstream_read(bc, delta_bits)) & 0x3F; } } break; case 2: if (ch_num) { - vlc_tab = &sf_vlc_tabs[get_bits(gb, 2)]; + vlc_tab = &sf_vlc_tabs[bitstream_read(bc, 2)]; - delta = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + delta = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1); chan->qu_sf_idx[0] = (ref_chan->qu_sf_idx[0] + delta) & 0x3F; for (i = 1; i < ctx->used_quant_units; i++) { diff = ref_chan->qu_sf_idx[i] - ref_chan->qu_sf_idx[i - 1]; - delta = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + delta = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1); chan->qu_sf_idx[i] = (chan->qu_sf_idx[i - 1] + diff + delta) & 0x3F; } } else { - vlc_tab = &sf_vlc_tabs[get_bits(gb, 2) + 4]; + vlc_tab = &sf_vlc_tabs[bitstream_read(bc, 2) + 4]; - UNPACK_SF_VQ_SHAPE(gb, chan->qu_sf_idx, ctx->used_quant_units); + UNPACK_SF_VQ_SHAPE(bc, chan->qu_sf_idx, ctx->used_quant_units); for (i = 0; i < ctx->used_quant_units; i++) { - delta = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + delta = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1); chan->qu_sf_idx[i] = (chan->qu_sf_idx[i] + sign_extend(delta, 4)) & 0x3F; } @@ -565,29 +566,29 @@ static int decode_channel_sf_idx(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, for (i = 0; i < ctx->used_quant_units; i++) chan->qu_sf_idx[i] = ref_chan->qu_sf_idx[i]; } else { - weight_idx = get_bits(gb, 2); - vlc_sel = get_bits(gb, 2); + weight_idx = bitstream_read(bc, 2); + vlc_sel = bitstream_read(bc, 2); vlc_tab = &sf_vlc_tabs[vlc_sel]; if (weight_idx == 3) { vlc_tab = &sf_vlc_tabs[vlc_sel + 4]; - UNPACK_SF_VQ_SHAPE(gb, chan->qu_sf_idx, ctx->used_quant_units); + UNPACK_SF_VQ_SHAPE(bc, chan->qu_sf_idx, ctx->used_quant_units); - diff = (get_bits(gb, 4) + 56) & 0x3F; - chan->qu_sf_idx[0] = (chan->qu_sf_idx[0] + diff) & 0x3F; + diff = (bitstream_read(bc, 4) + 56) & 0x3F; + chan->qu_sf_idx[0] = (chan->qu_sf_idx[0] + diff) & 0x3F; for (i = 1; i < ctx->used_quant_units; i++) { - delta = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + delta = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1); diff = (diff + sign_extend(delta, 4)) & 0x3F; chan->qu_sf_idx[i] = (diff + chan->qu_sf_idx[i]) & 0x3F; } } else { /* 1st coefficient is coded directly */ - chan->qu_sf_idx[0] = get_bits(gb, 6); + chan->qu_sf_idx[0] = bitstream_read(bc, 6); for (i = 1; i < ctx->used_quant_units; i++) { - delta = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + delta = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1); chan->qu_sf_idx[i] = (chan->qu_sf_idx[i - 1] + delta) & 0x3F; } } @@ -604,13 +605,13 @@ static int decode_channel_sf_idx(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, /** * Decode word length information for each channel. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in,out] ctx ptr to the channel unit context * @param[in] num_channels number of channels to process * @param[in] avctx ptr to the AVCodecContext * @return result code: 0 = OK, otherwise - error code */ -static int decode_quant_wordlen(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, +static int decode_quant_wordlen(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, int num_channels, AVCodecContext *avctx) { int ch_num, i, ret; @@ -619,7 +620,7 @@ static int decode_quant_wordlen(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, memset(ctx->channels[ch_num].qu_wordlen, 0, sizeof(ctx->channels[ch_num].qu_wordlen)); - if ((ret = decode_channel_wordlen(gb, ctx, ch_num, avctx)) < 0) + if ((ret = decode_channel_wordlen(bc, ctx, ch_num, avctx)) < 0) return ret; } @@ -637,13 +638,13 @@ static int decode_quant_wordlen(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, /** * Decode scale factor indexes for each channel. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in,out] ctx ptr to the channel unit context * @param[in] num_channels number of channels to process * @param[in] avctx ptr to the AVCodecContext * @return result code: 0 = OK, otherwise - error code */ -static int decode_scale_factors(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, +static int decode_scale_factors(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, int num_channels, AVCodecContext *avctx) { int ch_num, ret; @@ -655,7 +656,7 @@ static int decode_scale_factors(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, memset(ctx->channels[ch_num].qu_sf_idx, 0, sizeof(ctx->channels[ch_num].qu_sf_idx)); - if ((ret = decode_channel_sf_idx(gb, ctx, ch_num, avctx)) < 0) + if ((ret = decode_channel_sf_idx(bc, ctx, ch_num, avctx)) < 0) return ret; } @@ -665,18 +666,18 @@ static int decode_scale_factors(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, /** * Decode number of code table values. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in,out] ctx ptr to the channel unit context * @param[in] avctx ptr to the AVCodecContext * @return result code: 0 = OK, otherwise - error code */ -static int get_num_ct_values(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, +static int get_num_ct_values(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, AVCodecContext *avctx) { int num_coded_vals; - if (get_bits1(gb)) { - num_coded_vals = get_bits(gb, 5); + if (bitstream_read_bit(bc)) { + num_coded_vals = bitstream_read(bc, 5); if (num_coded_vals > ctx->used_quant_units) { av_log(avctx, AV_LOG_ERROR, "Invalid number of code table indexes: %d!\n", num_coded_vals); @@ -688,7 +689,7 @@ static int get_num_ct_values(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, } #define DEC_CT_IDX_COMMON(OP) \ - num_vals = get_num_ct_values(gb, ctx, avctx); \ + num_vals = get_num_ct_values(bc, ctx, avctx); \ if (num_vals < 0) \ return num_vals; \ \ @@ -697,33 +698,33 @@ static int get_num_ct_values(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, chan->qu_tab_idx[i] = OP; \ } else if (ch_num && ref_chan->qu_wordlen[i]) \ /* get clone master flag */ \ - chan->qu_tab_idx[i] = get_bits1(gb); \ + chan->qu_tab_idx[i] = bitstream_read_bit(bc); \ } -#define CODING_DIRECT get_bits(gb, num_bits) +#define CODING_DIRECT bitstream_read(bc, num_bits) -#define CODING_VLC get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1) +#define CODING_VLC bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1) #define CODING_VLC_DELTA \ (!i) ? CODING_VLC \ - : (pred + get_vlc2(gb, delta_vlc->table, \ - delta_vlc->bits, 1)) & mask; \ + : (pred + bitstream_read_vlc(bc, delta_vlc->table, \ + delta_vlc->bits, 1)) & mask; \ pred = chan->qu_tab_idx[i] #define CODING_VLC_DIFF \ (ref_chan->qu_tab_idx[i] + \ - get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1)) & mask + bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1)) & mask /** * Decode code table indexes for each quant unit of a channel. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in,out] ctx ptr to the channel unit context * @param[in] ch_num channel to process * @param[in] avctx ptr to the AVCodecContext * @return result code: 0 = OK, otherwise - error code */ -static int decode_channel_code_tab(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, +static int decode_channel_code_tab(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, int ch_num, AVCodecContext *avctx) { int i, num_vals, num_bits, pred; @@ -732,9 +733,9 @@ static int decode_channel_code_tab(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, Atrac3pChanParams *chan = &ctx->channels[ch_num]; Atrac3pChanParams *ref_chan = &ctx->channels[0]; - chan->table_type = get_bits1(gb); + chan->table_type = bitstream_read_bit(bc); - switch (get_bits(gb, 2)) { /* switch according to coding mode */ + switch (bitstream_read(bc, 2)) { /* switch according to coding mode */ case 0: /* directly coded */ num_bits = ctx->use_full_table + 2; DEC_CT_IDX_COMMON(CODING_DIRECT); @@ -770,13 +771,13 @@ static int decode_channel_code_tab(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, /** * Decode code table indexes for each channel. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in,out] ctx ptr to the channel unit context * @param[in] num_channels number of channels to process * @param[in] avctx ptr to the AVCodecContext * @return result code: 0 = OK, otherwise - error code */ -static int decode_code_table_indexes(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, +static int decode_code_table_indexes(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, int num_channels, AVCodecContext *avctx) { int ch_num, ret; @@ -784,13 +785,13 @@ static int decode_code_table_indexes(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, if (!ctx->used_quant_units) return 0; - ctx->use_full_table = get_bits1(gb); + ctx->use_full_table = bitstream_read_bit(bc); for (ch_num = 0; ch_num < num_channels; ch_num++) { memset(ctx->channels[ch_num].qu_tab_idx, 0, sizeof(ctx->channels[ch_num].qu_tab_idx)); - if ((ret = decode_channel_code_tab(gb, ctx, ch_num, avctx)) < 0) + if ((ret = decode_channel_code_tab(bc, ctx, ch_num, avctx)) < 0) return ret; } @@ -803,13 +804,13 @@ static int decode_code_table_indexes(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, * This is a generalized version for all known coding modes. * Its speed can be improved by creating separate functions for each mode. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in] tab code table telling how to decode spectral lines * @param[in] vlc_tab ptr to the huffman table associated with the code table * @param[out] out pointer to buffer where decoded data should be stored * @param[in] num_specs number of spectral lines to decode */ -static void decode_qu_spectra(GetBitContext *gb, const Atrac3pSpecCodeTab *tab, +static void decode_qu_spectra(BitstreamContext *bc, const Atrac3pSpecCodeTab *tab, VLC *vlc_tab, int16_t *out, const int num_specs) { int i, j, pos, cf; @@ -820,15 +821,15 @@ static void decode_qu_spectra(GetBitContext *gb, const Atrac3pSpecCodeTab *tab, unsigned val, mask = (1 << bits) - 1; for (pos = 0; pos < num_specs;) { - if (group_size == 1 || get_bits1(gb)) { + if (group_size == 1 || bitstream_read_bit(bc)) { for (j = 0; j < group_size; j++) { - val = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + val = bitstream_read_vlc(bc, vlc_tab->table, vlc_tab->bits, 1); for (i = 0; i < num_coeffs; i++) { cf = val & mask; if (is_signed) cf = sign_extend(cf, bits); - else if (cf && get_bits1(gb)) + else if (cf && bitstream_read_bit(bc)) cf = -cf; out[pos++] = cf; @@ -843,12 +844,12 @@ static void decode_qu_spectra(GetBitContext *gb, const Atrac3pSpecCodeTab *tab, /** * Decode huffman-coded IMDCT spectrum for all channels. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in,out] ctx ptr to the channel unit context * @param[in] num_channels number of channels to process * @param[in] avctx ptr to the AVCodecContext */ -static void decode_spectrum(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, +static void decode_spectrum(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, int num_channels, AVCodecContext *avctx) { int i, ch_num, qu, wordlen, codetab, tab_index, num_specs; @@ -880,7 +881,7 @@ static void decode_spectrum(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, if (tab->redirect >= 0) tab_index = tab->redirect; - decode_qu_spectra(gb, tab, &spec_vlc_tabs[tab_index], + decode_qu_spectra(bc, tab, &spec_vlc_tabs[tab_index], &chan->spectrum[ff_atrac3p_qu_to_spec_pos[qu]], num_specs); } else if (ch_num && ctx->channels[0].qu_wordlen[qu] && !codetab) { @@ -900,7 +901,7 @@ static void decode_spectrum(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, if (ctx->used_quant_units > 2) { num_specs = atrac3p_subband_to_num_powgrps[ctx->num_coded_subbands - 1]; for (i = 0; i < num_specs; i++) - chan->power_levs[i] = get_bits(gb, 4); + chan->power_levs[i] = bitstream_read(bc, 4); } } } @@ -913,22 +914,22 @@ static void decode_spectrum(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, * Otherwise, all necessary bits will be directly stored * prefixed by two signal bits = 1,1. * - * @param[in] gb ptr to the GetBitContext + * @param[in] bc ptr to the BitstreamContext * @param[out] out where to place decoded flags * @param[in] num_flags number of flags to process * @return: 0 = all flag bits are zero, 1 = there is at least one non-zero flag bit */ -static int get_subband_flags(GetBitContext *gb, uint8_t *out, int num_flags) +static int get_subband_flags(BitstreamContext *bc, uint8_t *out, int num_flags) { int i, result; memset(out, 0, num_flags); - result = get_bits1(gb); + result = bitstream_read_bit(bc); if (result) { - if (get_bits1(gb)) + if (bitstream_read_bit(bc)) for (i = 0; i < num_flags; i++) - out[i] = get_bits1(gb); + out[i] = bitstream_read_bit(bc); else memset(out, 1, num_flags); } @@ -939,63 +940,63 @@ static int get_subband_flags(GetBitContext *gb, uint8_t *out, int num_flags) /** * Decode mdct window shape flags for all channels. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in,out] ctx ptr to the channel unit context * @param[in] num_channels number of channels to process */ -static void decode_window_shape(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, +static void decode_window_shape(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, int num_channels) { int ch_num; for (ch_num = 0; ch_num < num_channels; ch_num++) - get_subband_flags(gb, ctx->channels[ch_num].wnd_shape, + get_subband_flags(bc, ctx->channels[ch_num].wnd_shape, ctx->num_subbands); } /** * Decode number of gain control points. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in,out] ctx ptr to the channel unit context * @param[in] ch_num channel to process * @param[in] coded_subbands number of subbands to process * @return result code: 0 = OK, otherwise - error code */ -static int decode_gainc_npoints(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, +static int decode_gainc_npoints(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, int ch_num, int coded_subbands) { int i, delta, delta_bits, min_val; Atrac3pChanParams *chan = &ctx->channels[ch_num]; Atrac3pChanParams *ref_chan = &ctx->channels[0]; - switch (get_bits(gb, 2)) { /* switch according to coding mode */ + switch (bitstream_read(bc, 2)) { /* switch according to coding mode */ case 0: /* fixed-length coding */ for (i = 0; i < coded_subbands; i++) - chan->gain_data[i].num_points = get_bits(gb, 3); + chan->gain_data[i].num_points = bitstream_read(bc, 3); break; case 1: /* variable-length coding */ for (i = 0; i < coded_subbands; i++) chan->gain_data[i].num_points = - get_vlc2(gb, gain_vlc_tabs[0].table, - gain_vlc_tabs[0].bits, 1); + bitstream_read_vlc(bc, gain_vlc_tabs[0].table, + gain_vlc_tabs[0].bits, 1); break; case 2: if (ch_num) { /* VLC modulo delta to master channel */ for (i = 0; i < coded_subbands; i++) { - delta = get_vlc2(gb, gain_vlc_tabs[1].table, - gain_vlc_tabs[1].bits, 1); + delta = bitstream_read_vlc(bc, gain_vlc_tabs[1].table, + gain_vlc_tabs[1].bits, 1); chan->gain_data[i].num_points = (ref_chan->gain_data[i].num_points + delta) & 7; } } else { /* VLC modulo delta to previous */ chan->gain_data[0].num_points = - get_vlc2(gb, gain_vlc_tabs[0].table, - gain_vlc_tabs[0].bits, 1); + bitstream_read_vlc(bc, gain_vlc_tabs[0].table, + gain_vlc_tabs[0].bits, 1); for (i = 1; i < coded_subbands; i++) { - delta = get_vlc2(gb, gain_vlc_tabs[1].table, - gain_vlc_tabs[1].bits, 1); + delta = bitstream_read_vlc(bc, gain_vlc_tabs[1].table, + gain_vlc_tabs[1].bits, 1); chan->gain_data[i].num_points = (chan->gain_data[i - 1].num_points + delta) & 7; } @@ -1007,11 +1008,11 @@ static int decode_gainc_npoints(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, chan->gain_data[i].num_points = ref_chan->gain_data[i].num_points; } else { /* shorter delta to min */ - delta_bits = get_bits(gb, 2); - min_val = get_bits(gb, 3); + delta_bits = bitstream_read(bc, 2); + min_val = bitstream_read(bc, 3); for (i = 0; i < coded_subbands; i++) { - chan->gain_data[i].num_points = min_val + get_bitsz(gb, delta_bits); + chan->gain_data[i].num_points = min_val + bitstream_read(bc, delta_bits); if (chan->gain_data[i].num_points > 7) return AVERROR_INVALIDDATA; } @@ -1038,23 +1039,23 @@ static inline void gainc_level_mode3s(AtracGainInfo *dst, AtracGainInfo *ref) /** * Implements coding mode 1 (master) for gain compensation levels. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in] ctx ptr to the channel unit context * @param[out] dst ptr to the output array */ -static inline void gainc_level_mode1m(GetBitContext *gb, +static inline void gainc_level_mode1m(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, AtracGainInfo *dst) { int i, delta; if (dst->num_points > 0) - dst->lev_code[0] = get_vlc2(gb, gain_vlc_tabs[2].table, - gain_vlc_tabs[2].bits, 1); + dst->lev_code[0] = bitstream_read_vlc(bc, gain_vlc_tabs[2].table, + gain_vlc_tabs[2].bits, 1); for (i = 1; i < dst->num_points; i++) { - delta = get_vlc2(gb, gain_vlc_tabs[3].table, - gain_vlc_tabs[3].bits, 1); + delta = bitstream_read_vlc(bc, gain_vlc_tabs[3].table, + gain_vlc_tabs[3].bits, 1); dst->lev_code[i] = (dst->lev_code[i - 1] + delta) & 0xF; } } @@ -1062,58 +1063,58 @@ static inline void gainc_level_mode1m(GetBitContext *gb, /** * Decode level code for each gain control point. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in,out] ctx ptr to the channel unit context * @param[in] ch_num channel to process * @param[in] coded_subbands number of subbands to process * @return result code: 0 = OK, otherwise - error code */ -static int decode_gainc_levels(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, +static int decode_gainc_levels(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, int ch_num, int coded_subbands) { int sb, i, delta, delta_bits, min_val, pred; Atrac3pChanParams *chan = &ctx->channels[ch_num]; Atrac3pChanParams *ref_chan = &ctx->channels[0]; - switch (get_bits(gb, 2)) { /* switch according to coding mode */ + switch (bitstream_read(bc, 2)) { /* switch according to coding mode */ case 0: /* fixed-length coding */ for (sb = 0; sb < coded_subbands; sb++) for (i = 0; i < chan->gain_data[sb].num_points; i++) - chan->gain_data[sb].lev_code[i] = get_bits(gb, 4); + chan->gain_data[sb].lev_code[i] = bitstream_read(bc, 4); break; case 1: if (ch_num) { /* VLC modulo delta to master channel */ for (sb = 0; sb < coded_subbands; sb++) for (i = 0; i < chan->gain_data[sb].num_points; i++) { - delta = get_vlc2(gb, gain_vlc_tabs[5].table, - gain_vlc_tabs[5].bits, 1); + delta = bitstream_read_vlc(bc, gain_vlc_tabs[5].table, + gain_vlc_tabs[5].bits, 1); pred = (i >= ref_chan->gain_data[sb].num_points) ? 7 : ref_chan->gain_data[sb].lev_code[i]; chan->gain_data[sb].lev_code[i] = (pred + delta) & 0xF; } } else { /* VLC modulo delta to previous */ for (sb = 0; sb < coded_subbands; sb++) - gainc_level_mode1m(gb, ctx, &chan->gain_data[sb]); + gainc_level_mode1m(bc, ctx, &chan->gain_data[sb]); } break; case 2: if (ch_num) { /* VLC modulo delta to previous or clone master */ for (sb = 0; sb < coded_subbands; sb++) if (chan->gain_data[sb].num_points > 0) { - if (get_bits1(gb)) - gainc_level_mode1m(gb, ctx, &chan->gain_data[sb]); + if (bitstream_read_bit(bc)) + gainc_level_mode1m(bc, ctx, &chan->gain_data[sb]); else gainc_level_mode3s(&chan->gain_data[sb], &ref_chan->gain_data[sb]); } } else { /* VLC modulo delta to lev_codes of previous subband */ if (chan->gain_data[0].num_points > 0) - gainc_level_mode1m(gb, ctx, &chan->gain_data[0]); + gainc_level_mode1m(bc, ctx, &chan->gain_data[0]); for (sb = 1; sb < coded_subbands; sb++) for (i = 0; i < chan->gain_data[sb].num_points; i++) { - delta = get_vlc2(gb, gain_vlc_tabs[4].table, - gain_vlc_tabs[4].bits, 1); + delta = bitstream_read_vlc(bc, gain_vlc_tabs[4].table, + gain_vlc_tabs[4].bits, 1); pred = (i >= chan->gain_data[sb - 1].num_points) ? 7 : chan->gain_data[sb - 1].lev_code[i]; chan->gain_data[sb].lev_code[i] = (pred + delta) & 0xF; @@ -1126,12 +1127,12 @@ static int decode_gainc_levels(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, gainc_level_mode3s(&chan->gain_data[sb], &ref_chan->gain_data[sb]); } else { /* shorter delta to min */ - delta_bits = get_bits(gb, 2); - min_val = get_bits(gb, 4); + delta_bits = bitstream_read(bc, 2); + min_val = bitstream_read(bc, 4); for (sb = 0; sb < coded_subbands; sb++) for (i = 0; i < chan->gain_data[sb].num_points; i++) { - chan->gain_data[sb].lev_code[i] = min_val + get_bitsz(gb, delta_bits); + chan->gain_data[sb].lev_code[i] = min_val + bitstream_read(bc, delta_bits); if (chan->gain_data[sb].lev_code[i] > 15) return AVERROR_INVALIDDATA; } @@ -1145,35 +1146,35 @@ static int decode_gainc_levels(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, /** * Implements coding mode 0 for gain compensation locations. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in] ctx ptr to the channel unit context * @param[out] dst ptr to the output array * @param[in] pos position of the value to be processed */ -static inline void gainc_loc_mode0(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, +static inline void gainc_loc_mode0(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, AtracGainInfo *dst, int pos) { int delta_bits; if (!pos || dst->loc_code[pos - 1] < 15) - dst->loc_code[pos] = get_bits(gb, 5); + dst->loc_code[pos] = bitstream_read(bc, 5); else if (dst->loc_code[pos - 1] >= 30) dst->loc_code[pos] = 31; else { delta_bits = av_log2(30 - dst->loc_code[pos - 1]) + 1; dst->loc_code[pos] = dst->loc_code[pos - 1] + - get_bits(gb, delta_bits) + 1; + bitstream_read(bc, delta_bits) + 1; } } /** * Implements coding mode 1 for gain compensation locations. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in] ctx ptr to the channel unit context * @param[out] dst ptr to the output array */ -static inline void gainc_loc_mode1(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, +static inline void gainc_loc_mode1(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, AtracGainInfo *dst) { int i; @@ -1181,7 +1182,7 @@ static inline void gainc_loc_mode1(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, if (dst->num_points > 0) { /* 1st coefficient is stored directly */ - dst->loc_code[0] = get_bits(gb, 5); + dst->loc_code[0] = bitstream_read(bc, 5); for (i = 1; i < dst->num_points; i++) { /* switch VLC according to the curve direction @@ -1190,7 +1191,7 @@ static inline void gainc_loc_mode1(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, ? &gain_vlc_tabs[7] : &gain_vlc_tabs[9]; dst->loc_code[i] = dst->loc_code[i - 1] + - get_vlc2(gb, tab->table, tab->bits, 1); + bitstream_read_vlc(bc, tab->table, tab->bits, 1); } } } @@ -1198,14 +1199,14 @@ static inline void gainc_loc_mode1(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, /** * Decode location code for each gain control point. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in,out] ctx ptr to the channel unit context * @param[in] ch_num channel to process * @param[in] coded_subbands number of subbands to process * @param[in] avctx ptr to the AVCodecContext * @return result code: 0 = OK, otherwise - error code */ -static int decode_gainc_loc_codes(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, +static int decode_gainc_loc_codes(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, int ch_num, int coded_subbands, AVCodecContext *avctx) { @@ -1215,11 +1216,11 @@ static int decode_gainc_loc_codes(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, Atrac3pChanParams *chan = &ctx->channels[ch_num]; Atrac3pChanParams *ref_chan = &ctx->channels[0]; - switch (get_bits(gb, 2)) { /* switch according to coding mode */ + switch (bitstream_read(bc, 2)) { /* switch according to coding mode */ case 0: /* sequence of numbers in ascending order */ for (sb = 0; sb < coded_subbands; sb++) for (i = 0; i < chan->gain_data[sb].num_points; i++) - gainc_loc_mode0(gb, ctx, &chan->gain_data[sb], i); + gainc_loc_mode0(bc, ctx, &chan->gain_data[sb], i); break; case 1: if (ch_num) { @@ -1230,8 +1231,8 @@ static int decode_gainc_loc_codes(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, ref = &ref_chan->gain_data[sb]; /* 1st value is vlc-coded modulo delta to master */ - delta = get_vlc2(gb, gain_vlc_tabs[10].table, - gain_vlc_tabs[10].bits, 1); + delta = bitstream_read_vlc(bc, gain_vlc_tabs[10].table, + gain_vlc_tabs[10].bits, 1); pred = ref->num_points > 0 ? ref->loc_code[0] : 0; dst->loc_code[0] = (pred + delta) & 0x1F; @@ -1241,19 +1242,19 @@ static int decode_gainc_loc_codes(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, /* ascending curve */ if (more_than_ref) { delta = - get_vlc2(gb, gain_vlc_tabs[9].table, - gain_vlc_tabs[9].bits, 1); + bitstream_read_vlc(bc, gain_vlc_tabs[9].table, + gain_vlc_tabs[9].bits, 1); dst->loc_code[i] = dst->loc_code[i - 1] + delta; } else { - if (get_bits1(gb)) - gainc_loc_mode0(gb, ctx, dst, i); // direct coding + if (bitstream_read_bit(bc)) + gainc_loc_mode0(bc, ctx, dst, i); // direct coding else dst->loc_code[i] = ref->loc_code[i]; // clone master } } else { /* descending curve */ tab = more_than_ref ? &gain_vlc_tabs[7] : &gain_vlc_tabs[10]; - delta = get_vlc2(gb, tab->table, tab->bits, 1); + delta = bitstream_read_vlc(bc, tab->table, tab->bits, 1); if (more_than_ref) dst->loc_code[i] = dst->loc_code[i - 1] + delta; else @@ -1263,7 +1264,7 @@ static int decode_gainc_loc_codes(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, } } else /* VLC delta to previous */ for (sb = 0; sb < coded_subbands; sb++) - gainc_loc_mode1(gb, ctx, &chan->gain_data[sb]); + gainc_loc_mode1(bc, ctx, &chan->gain_data[sb]); break; case 2: if (ch_num) { @@ -1272,8 +1273,8 @@ static int decode_gainc_loc_codes(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, continue; dst = &chan->gain_data[sb]; ref = &ref_chan->gain_data[sb]; - if (dst->num_points > ref->num_points || get_bits1(gb)) - gainc_loc_mode1(gb, ctx, dst); + if (dst->num_points > ref->num_points || bitstream_read_bit(bc)) + gainc_loc_mode1(bc, ctx, dst); else /* clone master for the whole subband */ for (i = 0; i < chan->gain_data[sb].num_points; i++) dst->loc_code[i] = ref->loc_code[i]; @@ -1281,7 +1282,7 @@ static int decode_gainc_loc_codes(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, } else { /* data for the first subband is coded directly */ for (i = 0; i < chan->gain_data[0].num_points; i++) - gainc_loc_mode0(gb, ctx, &chan->gain_data[0], i); + gainc_loc_mode0(bc, ctx, &chan->gain_data[0], i); for (sb = 1; sb < coded_subbands; sb++) { if (chan->gain_data[sb].num_points <= 0) @@ -1290,8 +1291,8 @@ static int decode_gainc_loc_codes(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, /* 1st value is vlc-coded modulo delta to the corresponding * value of the previous subband if any or zero */ - delta = get_vlc2(gb, gain_vlc_tabs[6].table, - gain_vlc_tabs[6].bits, 1); + delta = bitstream_read_vlc(bc, gain_vlc_tabs[6].table, + gain_vlc_tabs[6].bits, 1); pred = dst[-1].num_points > 0 ? dst[-1].loc_code[0] : 0; dst->loc_code[0] = (pred + delta) & 0x1F; @@ -1302,7 +1303,7 @@ static int decode_gainc_loc_codes(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, * presence of prediction. */ tab = &gain_vlc_tabs[(dst->lev_code[i] > dst->lev_code[i - 1]) * 2 + more_than_ref + 6]; - delta = get_vlc2(gb, tab->table, tab->bits, 1); + delta = bitstream_read_vlc(bc, tab->table, tab->bits, 1); if (more_than_ref) dst->loc_code[i] = dst->loc_code[i - 1] + delta; else @@ -1316,19 +1317,19 @@ static int decode_gainc_loc_codes(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, for (sb = 0; sb < coded_subbands; sb++) for (i = 0; i < chan->gain_data[sb].num_points; i++) { if (i >= ref_chan->gain_data[sb].num_points) - gainc_loc_mode0(gb, ctx, &chan->gain_data[sb], i); + gainc_loc_mode0(bc, ctx, &chan->gain_data[sb], i); else chan->gain_data[sb].loc_code[i] = ref_chan->gain_data[sb].loc_code[i]; } } else { /* shorter delta to min */ - delta_bits = get_bits(gb, 2) + 1; - min_val = get_bits(gb, 5); + delta_bits = bitstream_read(bc, 2) + 1; + min_val = bitstream_read(bc, 5); for (sb = 0; sb < coded_subbands; sb++) for (i = 0; i < chan->gain_data[sb].num_points; i++) chan->gain_data[sb].loc_code[i] = min_val + i + - get_bits(gb, delta_bits); + bitstream_read(bc, delta_bits); } break; } @@ -1353,13 +1354,13 @@ static int decode_gainc_loc_codes(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, /** * Decode gain control data for all channels. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in,out] ctx ptr to the channel unit context * @param[in] num_channels number of channels to process * @param[in] avctx ptr to the AVCodecContext * @return result code: 0 = OK, otherwise - error code */ -static int decode_gainc_data(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, +static int decode_gainc_data(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, int num_channels, AVCodecContext *avctx) { int ch_num, coded_subbands, sb, ret; @@ -1368,16 +1369,16 @@ static int decode_gainc_data(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, memset(ctx->channels[ch_num].gain_data, 0, sizeof(*ctx->channels[ch_num].gain_data) * ATRAC3P_SUBBANDS); - if (get_bits1(gb)) { /* gain control data present? */ - coded_subbands = get_bits(gb, 4) + 1; - if (get_bits1(gb)) /* is high band gain data replication on? */ - ctx->channels[ch_num].num_gain_subbands = get_bits(gb, 4) + 1; + if (bitstream_read_bit(bc)) { /* gain control data present? */ + coded_subbands = bitstream_read(bc, 4) + 1; + if (bitstream_read_bit(bc)) /* is high band gain data replication on? */ + ctx->channels[ch_num].num_gain_subbands = bitstream_read(bc, 4) + 1; else ctx->channels[ch_num].num_gain_subbands = coded_subbands; - if ((ret = decode_gainc_npoints(gb, ctx, ch_num, coded_subbands)) < 0 || - (ret = decode_gainc_levels(gb, ctx, ch_num, coded_subbands)) < 0 || - (ret = decode_gainc_loc_codes(gb, ctx, ch_num, coded_subbands, avctx)) < 0) + if ((ret = decode_gainc_npoints(bc, ctx, ch_num, coded_subbands)) < 0 || + (ret = decode_gainc_levels(bc, ctx, ch_num, coded_subbands)) < 0 || + (ret = decode_gainc_loc_codes(bc, ctx, ch_num, coded_subbands, avctx)) < 0) return ret; if (coded_subbands > 0) { /* propagate gain data if requested */ @@ -1396,29 +1397,29 @@ static int decode_gainc_data(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, /** * Decode envelope for all tones of a channel. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in,out] ctx ptr to the channel unit context * @param[in] ch_num channel to process * @param[in] band_has_tones ptr to an array of per-band-flags: * 1 - tone data present */ -static void decode_tones_envelope(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, +static void decode_tones_envelope(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, int ch_num, int band_has_tones[]) { int sb; Atrac3pWavesData *dst = ctx->channels[ch_num].tones_info; Atrac3pWavesData *ref = ctx->channels[0].tones_info; - if (!ch_num || !get_bits1(gb)) { /* mode 0: fixed-length coding */ + if (!ch_num || !bitstream_read_bit(bc)) { /* mode 0: fixed-length coding */ for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) { if (!band_has_tones[sb]) continue; - dst[sb].pend_env.has_start_point = get_bits1(gb); + dst[sb].pend_env.has_start_point = bitstream_read_bit(bc); dst[sb].pend_env.start_pos = dst[sb].pend_env.has_start_point - ? get_bits(gb, 5) : -1; - dst[sb].pend_env.has_stop_point = get_bits1(gb); + ? bitstream_read(bc, 5) : -1; + dst[sb].pend_env.has_stop_point = bitstream_read_bit(bc); dst[sb].pend_env.stop_pos = dst[sb].pend_env.has_stop_point - ? get_bits(gb, 5) : 32; + ? bitstream_read(bc, 5) : 32; } } else { /* mode 1(slave only): copy master */ for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) { @@ -1435,7 +1436,7 @@ static void decode_tones_envelope(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, /** * Decode number of tones for each subband of a channel. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in,out] ctx ptr to the channel unit context * @param[in] ch_num channel to process * @param[in] band_has_tones ptr to an array of per-band-flags: @@ -1443,7 +1444,7 @@ static void decode_tones_envelope(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, * @param[in] avctx ptr to the AVCodecContext * @return result code: 0 = OK, otherwise - error code */ -static int decode_band_numwavs(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, +static int decode_band_numwavs(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, int ch_num, int band_has_tones[], AVCodecContext *avctx) { @@ -1451,25 +1452,25 @@ static int decode_band_numwavs(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, Atrac3pWavesData *dst = ctx->channels[ch_num].tones_info; Atrac3pWavesData *ref = ctx->channels[0].tones_info; - mode = get_bits(gb, ch_num + 1); + mode = bitstream_read(bc, ch_num + 1); switch (mode) { case 0: /** fixed-length coding */ for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) if (band_has_tones[sb]) - dst[sb].num_wavs = get_bits(gb, 4); + dst[sb].num_wavs = bitstream_read(bc, 4); break; case 1: /** variable-length coding */ for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) if (band_has_tones[sb]) dst[sb].num_wavs = - get_vlc2(gb, tone_vlc_tabs[1].table, - tone_vlc_tabs[1].bits, 1); + bitstream_read_vlc(bc, tone_vlc_tabs[1].table, + tone_vlc_tabs[1].bits, 1); break; case 2: /** VLC modulo delta to master (slave only) */ for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) if (band_has_tones[sb]) { - delta = get_vlc2(gb, tone_vlc_tabs[2].table, - tone_vlc_tabs[2].bits, 1); + delta = bitstream_read_vlc(bc, tone_vlc_tabs[2].table, + tone_vlc_tabs[2].bits, 1); delta = sign_extend(delta, 3); dst[sb].num_wavs = (ref[sb].num_wavs + delta) & 0xF; } @@ -1501,13 +1502,13 @@ static int decode_band_numwavs(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, /** * Decode frequency information for each subband of a channel. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in,out] ctx ptr to the channel unit context * @param[in] ch_num channel to process * @param[in] band_has_tones ptr to an array of per-band-flags: * 1 - tone data present */ -static void decode_tones_frequency(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, +static void decode_tones_frequency(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, int ch_num, int band_has_tones[]) { int sb, i, direction, nbits, pred, delta; @@ -1515,26 +1516,26 @@ static void decode_tones_frequency(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, Atrac3pWavesData *dst = ctx->channels[ch_num].tones_info; Atrac3pWavesData *ref = ctx->channels[0].tones_info; - if (!ch_num || !get_bits1(gb)) { /* mode 0: fixed-length coding */ + if (!ch_num || !bitstream_read_bit(bc)) { /* mode 0: fixed-length coding */ for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) { if (!band_has_tones[sb] || !dst[sb].num_wavs) continue; iwav = &ctx->waves_info->waves[dst[sb].start_index]; - direction = (dst[sb].num_wavs > 1) ? get_bits1(gb) : 0; + direction = (dst[sb].num_wavs > 1) ? bitstream_read_bit(bc) : 0; if (direction) { /** packed numbers in descending order */ if (dst[sb].num_wavs) - iwav[dst[sb].num_wavs - 1].freq_index = get_bits(gb, 10); + iwav[dst[sb].num_wavs - 1].freq_index = bitstream_read(bc, 10); for (i = dst[sb].num_wavs - 2; i >= 0 ; i--) { nbits = av_log2(iwav[i+1].freq_index) + 1; - iwav[i].freq_index = get_bits(gb, nbits); + iwav[i].freq_index = bitstream_read(bc, nbits); } } else { /** packed numbers in ascending order */ for (i = 0; i < dst[sb].num_wavs; i++) { if (!i || iwav[i - 1].freq_index < 512) - iwav[i].freq_index = get_bits(gb, 10); + iwav[i].freq_index = bitstream_read(bc, 10); else { nbits = av_log2(1023 - iwav[i - 1].freq_index) + 1; - iwav[i].freq_index = get_bits(gb, nbits) + + iwav[i].freq_index = bitstream_read(bc, nbits) + 1024 - (1 << nbits); } } @@ -1547,8 +1548,8 @@ static void decode_tones_frequency(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, iwav = &ctx->waves_info->waves[ref[sb].start_index]; owav = &ctx->waves_info->waves[dst[sb].start_index]; for (i = 0; i < dst[sb].num_wavs; i++) { - delta = get_vlc2(gb, tone_vlc_tabs[6].table, - tone_vlc_tabs[6].bits, 1); + delta = bitstream_read_vlc(bc, tone_vlc_tabs[6].table, + tone_vlc_tabs[6].bits, 1); delta = sign_extend(delta, 8); pred = (i < ref[sb].num_wavs) ? iwav[i].freq_index : (ref[sb].num_wavs ? iwav[ref[sb].num_wavs - 1].freq_index : 0); @@ -1561,13 +1562,13 @@ static void decode_tones_frequency(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, /** * Decode amplitude information for each subband of a channel. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in,out] ctx ptr to the channel unit context * @param[in] ch_num channel to process * @param[in] band_has_tones ptr to an array of per-band-flags: * 1 - tone data present */ -static void decode_tones_amplitude(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, +static void decode_tones_amplitude(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, int ch_num, int band_has_tones[]) { int mode, sb, j, i, diff, maxdiff, fi, delta, pred; @@ -1601,7 +1602,7 @@ static void decode_tones_amplitude(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, } } - mode = get_bits(gb, ch_num + 1); + mode = bitstream_read(bc, ch_num + 1); switch (mode) { case 0: /** fixed-length coding */ @@ -1610,9 +1611,9 @@ static void decode_tones_amplitude(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, continue; if (ctx->waves_info->amplitude_mode) for (i = 0; i < dst[sb].num_wavs; i++) - ctx->waves_info->waves[dst[sb].start_index + i].amp_sf = get_bits(gb, 6); + ctx->waves_info->waves[dst[sb].start_index + i].amp_sf = bitstream_read(bc, 6); else - ctx->waves_info->waves[dst[sb].start_index].amp_sf = get_bits(gb, 6); + ctx->waves_info->waves[dst[sb].start_index].amp_sf = bitstream_read(bc, 6); } break; case 1: /** min + VLC delta */ @@ -1622,12 +1623,12 @@ static void decode_tones_amplitude(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, if (ctx->waves_info->amplitude_mode) for (i = 0; i < dst[sb].num_wavs; i++) ctx->waves_info->waves[dst[sb].start_index + i].amp_sf = - get_vlc2(gb, tone_vlc_tabs[3].table, - tone_vlc_tabs[3].bits, 1) + 20; + bitstream_read_vlc(bc, tone_vlc_tabs[3].table, + tone_vlc_tabs[3].bits, 1) + 20; else ctx->waves_info->waves[dst[sb].start_index].amp_sf = - get_vlc2(gb, tone_vlc_tabs[4].table, - tone_vlc_tabs[4].bits, 1) + 24; + bitstream_read_vlc(bc, tone_vlc_tabs[4].table, + tone_vlc_tabs[4].bits, 1) + 24; } break; case 2: /** VLC modulo delta to master (slave only) */ @@ -1635,8 +1636,8 @@ static void decode_tones_amplitude(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, if (!band_has_tones[sb] || !dst[sb].num_wavs) continue; for (i = 0; i < dst[sb].num_wavs; i++) { - delta = get_vlc2(gb, tone_vlc_tabs[5].table, - tone_vlc_tabs[5].bits, 1); + delta = bitstream_read_vlc(bc, tone_vlc_tabs[5].table, + tone_vlc_tabs[5].bits, 1); delta = sign_extend(delta, 5); pred = refwaves[dst[sb].start_index + i] >= 0 ? ctx->waves_info->waves[refwaves[dst[sb].start_index + i]].amp_sf : 34; @@ -1661,13 +1662,13 @@ static void decode_tones_amplitude(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, /** * Decode phase information for each subband of a channel. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in,out] ctx ptr to the channel unit context * @param[in] ch_num channel to process * @param[in] band_has_tones ptr to an array of per-band-flags: * 1 - tone data present */ -static void decode_tones_phase(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, +static void decode_tones_phase(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, int ch_num, int band_has_tones[]) { int sb, i; @@ -1679,20 +1680,20 @@ static void decode_tones_phase(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, continue; wparam = &ctx->waves_info->waves[dst[sb].start_index]; for (i = 0; i < dst[sb].num_wavs; i++) - wparam[i].phase_index = get_bits(gb, 5); + wparam[i].phase_index = bitstream_read(bc, 5); } } /** * Decode tones info for all channels. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in,out] ctx ptr to the channel unit context * @param[in] num_channels number of channels to process * @param[in] avctx ptr to the AVCodecContext * @return result code: 0 = OK, otherwise - error code */ -static int decode_tones_info(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, +static int decode_tones_info(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, int num_channels, AVCodecContext *avctx) { int ch_num, i, ret; @@ -1702,26 +1703,26 @@ static int decode_tones_info(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, memset(ctx->channels[ch_num].tones_info, 0, sizeof(*ctx->channels[ch_num].tones_info) * ATRAC3P_SUBBANDS); - ctx->waves_info->tones_present = get_bits1(gb); + ctx->waves_info->tones_present = bitstream_read_bit(bc); if (!ctx->waves_info->tones_present) return 0; memset(ctx->waves_info->waves, 0, sizeof(ctx->waves_info->waves)); - ctx->waves_info->amplitude_mode = get_bits1(gb); + ctx->waves_info->amplitude_mode = bitstream_read_bit(bc); if (!ctx->waves_info->amplitude_mode) { avpriv_report_missing_feature(avctx, "GHA amplitude mode 0"); return AVERROR_PATCHWELCOME; } ctx->waves_info->num_tone_bands = - get_vlc2(gb, tone_vlc_tabs[0].table, - tone_vlc_tabs[0].bits, 1) + 1; + bitstream_read_vlc(bc, tone_vlc_tabs[0].table, + tone_vlc_tabs[0].bits, 1) + 1; if (num_channels == 2) { - get_subband_flags(gb, ctx->waves_info->tone_sharing, ctx->waves_info->num_tone_bands); - get_subband_flags(gb, ctx->waves_info->tone_master, ctx->waves_info->num_tone_bands); - if (get_subband_flags(gb, ctx->waves_info->phase_shift, + get_subband_flags(bc, ctx->waves_info->tone_sharing, ctx->waves_info->num_tone_bands); + get_subband_flags(bc, ctx->waves_info->tone_master, ctx->waves_info->num_tone_bands); + if (get_subband_flags(bc, ctx->waves_info->phase_shift, ctx->waves_info->num_tone_bands)) { avpriv_report_missing_feature(avctx, "GHA Phase shifting"); return AVERROR_PATCHWELCOME; @@ -1734,14 +1735,14 @@ static int decode_tones_info(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, for (i = 0; i < ctx->waves_info->num_tone_bands; i++) band_has_tones[i] = !ch_num ? 1 : !ctx->waves_info->tone_sharing[i]; - decode_tones_envelope(gb, ctx, ch_num, band_has_tones); - if ((ret = decode_band_numwavs(gb, ctx, ch_num, band_has_tones, + decode_tones_envelope(bc, ctx, ch_num, band_has_tones); + if ((ret = decode_band_numwavs(bc, ctx, ch_num, band_has_tones, avctx)) < 0) return ret; - decode_tones_frequency(gb, ctx, ch_num, band_has_tones); - decode_tones_amplitude(gb, ctx, ch_num, band_has_tones); - decode_tones_phase(gb, ctx, ch_num, band_has_tones); + decode_tones_frequency(bc, ctx, ch_num, band_has_tones); + decode_tones_amplitude(bc, ctx, ch_num, band_has_tones); + decode_tones_phase(bc, ctx, ch_num, band_has_tones); } if (num_channels == 2) { @@ -1758,13 +1759,13 @@ static int decode_tones_info(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, return 0; } -int ff_atrac3p_decode_channel_unit(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, +int ff_atrac3p_decode_channel_unit(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, int num_channels, AVCodecContext *avctx) { int ret; /* parse sound header */ - ctx->num_quant_units = get_bits(gb, 5) + 1; + ctx->num_quant_units = bitstream_read(bc, 5) + 1; if (ctx->num_quant_units > 28 && ctx->num_quant_units < 32) { av_log(avctx, AV_LOG_ERROR, "Invalid number of quantization units: %d!\n", @@ -1772,10 +1773,10 @@ int ff_atrac3p_decode_channel_unit(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, return AVERROR_INVALIDDATA; } - ctx->mute_flag = get_bits1(gb); + ctx->mute_flag = bitstream_read_bit(bc); /* decode various sound parameters */ - if ((ret = decode_quant_wordlen(gb, ctx, num_channels, avctx)) < 0) + if ((ret = decode_quant_wordlen(bc, ctx, num_channels, avctx)) < 0) return ret; ctx->num_subbands = atrac3p_qu_to_subband[ctx->num_quant_units - 1] + 1; @@ -1783,32 +1784,32 @@ int ff_atrac3p_decode_channel_unit(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, ? atrac3p_qu_to_subband[ctx->used_quant_units - 1] + 1 : 0; - if ((ret = decode_scale_factors(gb, ctx, num_channels, avctx)) < 0) + if ((ret = decode_scale_factors(bc, ctx, num_channels, avctx)) < 0) return ret; - if ((ret = decode_code_table_indexes(gb, ctx, num_channels, avctx)) < 0) + if ((ret = decode_code_table_indexes(bc, ctx, num_channels, avctx)) < 0) return ret; - decode_spectrum(gb, ctx, num_channels, avctx); + decode_spectrum(bc, ctx, num_channels, avctx); if (num_channels == 2) { - get_subband_flags(gb, ctx->swap_channels, ctx->num_coded_subbands); - get_subband_flags(gb, ctx->negate_coeffs, ctx->num_coded_subbands); + get_subband_flags(bc, ctx->swap_channels, ctx->num_coded_subbands); + get_subband_flags(bc, ctx->negate_coeffs, ctx->num_coded_subbands); } - decode_window_shape(gb, ctx, num_channels); + decode_window_shape(bc, ctx, num_channels); - if ((ret = decode_gainc_data(gb, ctx, num_channels, avctx)) < 0) + if ((ret = decode_gainc_data(bc, ctx, num_channels, avctx)) < 0) return ret; - if ((ret = decode_tones_info(gb, ctx, num_channels, avctx)) < 0) + if ((ret = decode_tones_info(bc, ctx, num_channels, avctx)) < 0) return ret; /* decode global noise info */ - ctx->noise_present = get_bits1(gb); + ctx->noise_present = bitstream_read_bit(bc); if (ctx->noise_present) { - ctx->noise_level_index = get_bits(gb, 4); - ctx->noise_table_index = get_bits(gb, 4); + ctx->noise_level_index = bitstream_read(bc, 4); + ctx->noise_table_index = bitstream_read(bc, 4); } return 0; diff --git a/libavcodec/atrac3plus.h b/libavcodec/atrac3plus.h index e56c4441b6627..cca399adabaa5 100644 --- a/libavcodec/atrac3plus.h +++ b/libavcodec/atrac3plus.h @@ -31,10 +31,11 @@ #include #include "libavutil/float_dsp.h" + #include "atrac.h" +#include "bitstream.h" #include "avcodec.h" #include "fft.h" -#include "get_bits.h" /** Global unit sizes */ #define ATRAC3P_SUBBANDS 16 ///< number of PQF subbands @@ -163,13 +164,13 @@ void ff_atrac3p_init_vlcs(AVCodec *codec); /** * Decode bitstream data of a channel unit. * - * @param[in] gb the GetBit context + * @param[in] bc the Bitstream context * @param[in,out] ctx ptr to the channel unit context * @param[in] num_channels number of channels to process * @param[in] avctx ptr to the AVCodecContext * @return result code: 0 = OK, otherwise - error code */ -int ff_atrac3p_decode_channel_unit(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, +int ff_atrac3p_decode_channel_unit(BitstreamContext *bc, Atrac3pChanUnitCtx *ctx, int num_channels, AVCodecContext *avctx); /** diff --git a/libavcodec/atrac3plusdec.c b/libavcodec/atrac3plusdec.c index 4a742c159e78e..17774d5657850 100644 --- a/libavcodec/atrac3plusdec.c +++ b/libavcodec/atrac3plusdec.c @@ -39,14 +39,15 @@ #include "libavutil/channel_layout.h" #include "libavutil/float_dsp.h" + #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "internal.h" #include "atrac.h" #include "atrac3plus.h" typedef struct ATRAC3PContext { - GetBitContext gb; + BitstreamContext bc; AVFloatDSPContext fdsp; DECLARE_ALIGNED(32, float, samples)[2][ATRAC3P_FRAME_SAMPLES]; ///< quantized MDCT spectrum @@ -334,16 +335,16 @@ static int atrac3p_decode_frame(AVCodecContext *avctx, void *data, return ret; } - if ((ret = init_get_bits8(&ctx->gb, avpkt->data, avpkt->size)) < 0) + if ((ret = bitstream_init8(&ctx->bc, avpkt->data, avpkt->size)) < 0) return ret; - if (get_bits1(&ctx->gb)) { + if (bitstream_read_bit(&ctx->bc)) { av_log(avctx, AV_LOG_ERROR, "Invalid start bit!\n"); return AVERROR_INVALIDDATA; } - while (get_bits_left(&ctx->gb) >= 2 && - (ch_unit_id = get_bits(&ctx->gb, 2)) != CH_UNIT_TERMINATOR) { + while (bitstream_bits_left(&ctx->bc) >= 2 && + (ch_unit_id = bitstream_read(&ctx->bc, 2)) != CH_UNIT_TERMINATOR) { if (ch_unit_id == CH_UNIT_EXTENSION) { avpriv_report_missing_feature(avctx, "Channel unit extension"); return AVERROR_PATCHWELCOME; @@ -358,7 +359,7 @@ static int atrac3p_decode_frame(AVCodecContext *avctx, void *data, ctx->ch_units[ch_block].unit_type = ch_unit_id; channels_to_process = ch_unit_id + 1; - if ((ret = ff_atrac3p_decode_channel_unit(&ctx->gb, + if ((ret = ff_atrac3p_decode_channel_unit(&ctx->bc, &ctx->ch_units[ch_block], channels_to_process, avctx)) < 0) From dae9b0b9c6dbe3349b6350fd02d60810660e7bf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 9 Apr 2016 15:51:58 +0200 Subject: [PATCH 0507/3374] avs: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/avs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavcodec/avs.c b/libavcodec/avs.c index 0d127f85d11b3..bea01a265621a 100644 --- a/libavcodec/avs.c +++ b/libavcodec/avs.c @@ -20,7 +20,7 @@ */ #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "internal.h" typedef struct AvsContext { @@ -57,7 +57,7 @@ avs_decode_frame(AVCodecContext * avctx, int i, j, x, y, stride, ret, vect_w = 3, vect_h = 3; AvsVideoSubType sub_type; AvsBlockType type; - GetBitContext change_map; + BitstreamContext change_map; if ((ret = ff_reget_buffer(avctx, p)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); @@ -125,13 +125,13 @@ avs_decode_frame(AVCodecContext * avctx, int map_size = ((318 / vect_w + 7) / 8) * (198 / vect_h); if (buf_end - table < map_size) return AVERROR_INVALIDDATA; - init_get_bits(&change_map, table, map_size * 8); + bitstream_init(&change_map, table, map_size * 8); table += map_size; } for (y=0; y<198; y+=vect_h) { for (x=0; x<318; x+=vect_w) { - if (sub_type == AVS_I_FRAME || get_bits1(&change_map)) { + if (sub_type == AVS_I_FRAME || bitstream_read_bit(&change_map)) { if (buf_end - table < 1) return AVERROR_INVALIDDATA; vect = &buf[*table++ * (vect_w * vect_h)]; @@ -145,7 +145,7 @@ avs_decode_frame(AVCodecContext * avctx, } } if (sub_type != AVS_I_FRAME) - align_get_bits(&change_map); + bitstream_align(&change_map); } if ((ret = av_frame_ref(picture, p)) < 0) From 9a23b599431cf24ebf976a30d8c7a070ce57c3e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 9 Apr 2016 15:59:51 +0200 Subject: [PATCH 0508/3374] bink: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/bink.c | 264 ++++++++++++++++++++++------------------------ 1 file changed, 128 insertions(+), 136 deletions(-) diff --git a/libavcodec/bink.c b/libavcodec/bink.c index 74336974d023d..74db80a2be597 100644 --- a/libavcodec/bink.c +++ b/libavcodec/bink.c @@ -28,8 +28,8 @@ #include "avcodec.h" #include "binkdata.h" #include "binkdsp.h" +#include "bitstream.h" #include "blockdsp.h" -#include "get_bits.h" #include "hpeldsp.h" #include "internal.h" #include "mathops.h" @@ -93,8 +93,9 @@ typedef struct Tree { uint8_t syms[16]; ///< leaf value to symbol mapping } Tree; -#define GET_HUFF(gb, tree) (tree).syms[get_vlc2(gb, bink_trees[(tree).vlc_num].table,\ - bink_trees[(tree).vlc_num].bits, 1)] +#define GET_HUFF(bc, tree) \ + (tree).syms[bitstream_read_vlc(bc, bink_trees[(tree).vlc_num].table, \ + bink_trees[(tree).vlc_num].bits, 1)] /** * data structure used for decoding single Bink data type @@ -204,18 +205,18 @@ static av_cold void free_bundles(BinkContext *c) /** * Merge two consequent lists of equal size depending on bits read. * - * @param gb context for reading bits + * @param bc context for reading bits * @param dst buffer where merged list will be written to * @param src pointer to the head of the first list (the second lists starts at src+size) * @param size input lists size */ -static void merge(GetBitContext *gb, uint8_t *dst, uint8_t *src, int size) +static void merge(BitstreamContext *bc, uint8_t *dst, uint8_t *src, int size) { uint8_t *src2 = src + size; int size2 = size; do { - if (!get_bits1(gb)) { + if (!bitstream_read_bit(bc)) { *dst++ = *src++; size--; } else { @@ -233,37 +234,37 @@ static void merge(GetBitContext *gb, uint8_t *dst, uint8_t *src, int size) /** * Read information about Huffman tree used to decode data. * - * @param gb context for reading bits + * @param bc context for reading bits * @param tree pointer for storing tree data */ -static void read_tree(GetBitContext *gb, Tree *tree) +static void read_tree(BitstreamContext *bc, Tree *tree) { uint8_t tmp1[16] = { 0 }, tmp2[16], *in = tmp1, *out = tmp2; int i, t, len; - tree->vlc_num = get_bits(gb, 4); + tree->vlc_num = bitstream_read(bc, 4); if (!tree->vlc_num) { for (i = 0; i < 16; i++) tree->syms[i] = i; return; } - if (get_bits1(gb)) { - len = get_bits(gb, 3); + if (bitstream_read_bit(bc)) { + len = bitstream_read(bc, 3); for (i = 0; i <= len; i++) { - tree->syms[i] = get_bits(gb, 4); + tree->syms[i] = bitstream_read(bc, 4); tmp1[tree->syms[i]] = 1; } for (i = 0; i < 16 && len < 16 - 1; i++) if (!tmp1[i]) tree->syms[++len] = i; } else { - len = get_bits(gb, 2); + len = bitstream_read(bc, 2); for (i = 0; i < 16; i++) in[i] = i; for (i = 0; i <= len; i++) { int size = 1 << i; for (t = 0; t < 16; t += size << 1) - merge(gb, out + t, in + t, size); + merge(bc, out + t, in + t, size); FFSWAP(uint8_t*, in, out); } memcpy(tree->syms, in, 16); @@ -273,21 +274,21 @@ static void read_tree(GetBitContext *gb, Tree *tree) /** * Prepare bundle for decoding data. * - * @param gb context for reading bits + * @param bc context for reading bits * @param c decoder context * @param bundle_num number of the bundle to initialize */ -static void read_bundle(GetBitContext *gb, BinkContext *c, int bundle_num) +static void read_bundle(BitstreamContext *bc, BinkContext *c, int bundle_num) { int i; if (bundle_num == BINK_SRC_COLORS) { for (i = 0; i < 16; i++) - read_tree(gb, &c->col_high[i]); + read_tree(bc, &c->col_high[i]); c->col_lastval = 0; } if (bundle_num != BINK_SRC_INTRA_DC && bundle_num != BINK_SRC_INTER_DC) - read_tree(gb, &c->bundle[bundle_num].tree); + read_tree(bc, &c->bundle[bundle_num].tree); c->bundle[bundle_num].cur_dec = c->bundle[bundle_num].cur_ptr = c->bundle[bundle_num].data; } @@ -295,66 +296,64 @@ static void read_bundle(GetBitContext *gb, BinkContext *c, int bundle_num) /** * common check before starting decoding bundle data * - * @param gb context for reading bits + * @param bc context for reading bits * @param b bundle * @param t variable where number of elements to decode will be stored */ -#define CHECK_READ_VAL(gb, b, t) \ +#define CHECK_READ_VAL(bc, b, t) \ if (!b->cur_dec || (b->cur_dec > b->cur_ptr)) \ return 0; \ - t = get_bits(gb, b->len); \ + t = bitstream_read(bc, b->len); \ if (!t) { \ b->cur_dec = NULL; \ return 0; \ } \ -static int read_runs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) +static int read_runs(AVCodecContext *avctx, BitstreamContext *bc, Bundle *b) { int t, v; const uint8_t *dec_end; - CHECK_READ_VAL(gb, b, t); + CHECK_READ_VAL(bc, b, t); dec_end = b->cur_dec + t; if (dec_end > b->data_end) { av_log(avctx, AV_LOG_ERROR, "Run value went out of bounds\n"); return AVERROR_INVALIDDATA; } - if (get_bits1(gb)) { - v = get_bits(gb, 4); + if (bitstream_read_bit(bc)) { + v = bitstream_read(bc, 4); memset(b->cur_dec, v, t); b->cur_dec += t; } else { while (b->cur_dec < dec_end) - *b->cur_dec++ = GET_HUFF(gb, b->tree); + *b->cur_dec++ = GET_HUFF(bc, b->tree); } return 0; } -static int read_motion_values(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) +static int read_motion_values(AVCodecContext *avctx, BitstreamContext *bc, Bundle *b) { - int t, sign, v; + int t, v; const uint8_t *dec_end; - CHECK_READ_VAL(gb, b, t); + CHECK_READ_VAL(bc, b, t); dec_end = b->cur_dec + t; if (dec_end > b->data_end) { av_log(avctx, AV_LOG_ERROR, "Too many motion values\n"); return AVERROR_INVALIDDATA; } - if (get_bits1(gb)) { - v = get_bits(gb, 4); + if (bitstream_read_bit(bc)) { + v = bitstream_read(bc, 4); if (v) { - sign = -get_bits1(gb); - v = (v ^ sign) - sign; + v = bitstream_apply_sign(bc, v); } memset(b->cur_dec, v, t); b->cur_dec += t; } else { while (b->cur_dec < dec_end) { - v = GET_HUFF(gb, b->tree); + v = GET_HUFF(bc, b->tree); if (v) { - sign = -get_bits1(gb); - v = (v ^ sign) - sign; + v = bitstream_apply_sign(bc, v); } *b->cur_dec++ = v; } @@ -364,25 +363,25 @@ static int read_motion_values(AVCodecContext *avctx, GetBitContext *gb, Bundle * static const uint8_t bink_rlelens[4] = { 4, 8, 12, 32 }; -static int read_block_types(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) +static int read_block_types(AVCodecContext *avctx, BitstreamContext *bc, Bundle *b) { int t, v; int last = 0; const uint8_t *dec_end; - CHECK_READ_VAL(gb, b, t); + CHECK_READ_VAL(bc, b, t); dec_end = b->cur_dec + t; if (dec_end > b->data_end) { av_log(avctx, AV_LOG_ERROR, "Too many block type values\n"); return AVERROR_INVALIDDATA; } - if (get_bits1(gb)) { - v = get_bits(gb, 4); + if (bitstream_read_bit(bc)) { + v = bitstream_read(bc, 4); memset(b->cur_dec, v, t); b->cur_dec += t; } else { while (b->cur_dec < dec_end) { - v = GET_HUFF(gb, b->tree); + v = GET_HUFF(bc, b->tree); if (v < 12) { last = v; *b->cur_dec++ = v; @@ -399,40 +398,40 @@ static int read_block_types(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) return 0; } -static int read_patterns(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) +static int read_patterns(AVCodecContext *avctx, BitstreamContext *bc, Bundle *b) { int t, v; const uint8_t *dec_end; - CHECK_READ_VAL(gb, b, t); + CHECK_READ_VAL(bc, b, t); dec_end = b->cur_dec + t; if (dec_end > b->data_end) { av_log(avctx, AV_LOG_ERROR, "Too many pattern values\n"); return AVERROR_INVALIDDATA; } while (b->cur_dec < dec_end) { - v = GET_HUFF(gb, b->tree); - v |= GET_HUFF(gb, b->tree) << 4; + v = GET_HUFF(bc, b->tree); + v |= GET_HUFF(bc, b->tree) << 4; *b->cur_dec++ = v; } return 0; } -static int read_colors(GetBitContext *gb, Bundle *b, BinkContext *c) +static int read_colors(BitstreamContext *bc, Bundle *b, BinkContext *c) { int t, sign, v; const uint8_t *dec_end; - CHECK_READ_VAL(gb, b, t); + CHECK_READ_VAL(bc, b, t); dec_end = b->cur_dec + t; if (dec_end > b->data_end) { av_log(c->avctx, AV_LOG_ERROR, "Too many color values\n"); return AVERROR_INVALIDDATA; } - if (get_bits1(gb)) { - c->col_lastval = GET_HUFF(gb, c->col_high[c->col_lastval]); - v = GET_HUFF(gb, b->tree); + if (bitstream_read_bit(bc)) { + c->col_lastval = GET_HUFF(bc, c->col_high[c->col_lastval]); + v = GET_HUFF(bc, b->tree); v = (c->col_lastval << 4) | v; if (c->version < 'i') { sign = ((int8_t) v) >> 7; @@ -443,8 +442,8 @@ static int read_colors(GetBitContext *gb, Bundle *b, BinkContext *c) b->cur_dec += t; } else { while (b->cur_dec < dec_end) { - c->col_lastval = GET_HUFF(gb, c->col_high[c->col_lastval]); - v = GET_HUFF(gb, b->tree); + c->col_lastval = GET_HUFF(bc, c->col_high[c->col_lastval]); + v = GET_HUFF(bc, b->tree); v = (c->col_lastval << 4) | v; if (c->version < 'i') { sign = ((int8_t) v) >> 7; @@ -460,18 +459,17 @@ static int read_colors(GetBitContext *gb, Bundle *b, BinkContext *c) /** number of bits used to store first DC value in bundle */ #define DC_START_BITS 11 -static int read_dcs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b, +static int read_dcs(AVCodecContext *avctx, BitstreamContext *bc, Bundle *b, int start_bits, int has_sign) { - int i, j, len, len2, bsize, sign, v, v2; + int i, j, len, len2, bsize, v, v2; int16_t *dst = (int16_t*)b->cur_dec; int16_t *dst_end = (int16_t*)b->data_end; - CHECK_READ_VAL(gb, b, len); - v = get_bits(gb, start_bits - has_sign); + CHECK_READ_VAL(bc, b, len); + v = bitstream_read(bc, start_bits - has_sign); if (v && has_sign) { - sign = -get_bits1(gb); - v = (v ^ sign) - sign; + v = bitstream_apply_sign(bc, v); } if (dst_end - dst < 1) return AVERROR_INVALIDDATA; @@ -481,13 +479,12 @@ static int read_dcs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b, len2 = FFMIN(len - i, 8); if (dst_end - dst < len2) return AVERROR_INVALIDDATA; - bsize = get_bits(gb, 4); + bsize = bitstream_read(bc, 4); if (bsize) { for (j = 0; j < len2; j++) { - v2 = get_bits(gb, bsize); + v2 = bitstream_read(bc, bsize); if (v2) { - sign = -get_bits1(gb); - v2 = (v2 ^ sign) - sign; + v2 = bitstream_apply_sign(bc, v2); } v += v2; *dst++ = v; @@ -539,7 +536,7 @@ static av_cold void binkb_init_bundles(BinkContext *c) binkb_init_bundle(c, i); } -static int binkb_read_bundle(BinkContext *c, GetBitContext *gb, int bundle_num) +static int binkb_read_bundle(BinkContext *c, BitstreamContext *bc, int bundle_num) { const int bits = binkb_bundle_sizes[bundle_num]; const int mask = 1 << (bits - 1); @@ -547,26 +544,26 @@ static int binkb_read_bundle(BinkContext *c, GetBitContext *gb, int bundle_num) Bundle *b = &c->bundle[bundle_num]; int i, len; - CHECK_READ_VAL(gb, b, len); + CHECK_READ_VAL(bc, b, len); if (b->data_end - b->cur_dec < len * (1 + (bits > 8))) return AVERROR_INVALIDDATA; if (bits <= 8) { if (!issigned) { for (i = 0; i < len; i++) - *b->cur_dec++ = get_bits(gb, bits); + *b->cur_dec++ = bitstream_read(bc, bits); } else { for (i = 0; i < len; i++) - *b->cur_dec++ = get_bits(gb, bits) - mask; + *b->cur_dec++ = bitstream_read(bc, bits) - mask; } } else { int16_t *dst = (int16_t*)b->cur_dec; if (!issigned) { for (i = 0; i < len; i++) - *dst++ = get_bits(gb, bits); + *dst++ = bitstream_read(bc, bits); } else { for (i = 0; i < len; i++) - *dst++ = get_bits(gb, bits) - mask; + *dst++ = bitstream_read(bc, bits) - mask; } b->cur_dec = (uint8_t*)dst; } @@ -590,18 +587,19 @@ static inline int binkb_get_value(BinkContext *c, int bundle_num) /** * Read 8x8 block of DCT coefficients. * - * @param gb context for reading bits + * @param bc context for reading bits * @param block place for storing coefficients * @param scan scan order table * @param quant_matrices quantization matrices * @return 0 for success, negative value in other cases */ -static int read_dct_coeffs(GetBitContext *gb, int32_t block[64], const uint8_t *scan, +static int read_dct_coeffs(BitstreamContext *bc, int32_t block[64], + const uint8_t *scan, const int32_t quant_matrices[16][64], int q) { int coef_list[128]; int mode_list[128]; - int i, t, bits, ccoef, mode, sign; + int i, t, bits, ccoef, mode; int list_start = 64, list_end = 64, list_pos; int coef_count = 0; int coef_idx[64]; @@ -615,10 +613,10 @@ static int read_dct_coeffs(GetBitContext *gb, int32_t block[64], const uint8_t * coef_list[list_end] = 2; mode_list[list_end++] = 3; coef_list[list_end] = 3; mode_list[list_end++] = 3; - for (bits = get_bits(gb, 4) - 1; bits >= 0; bits--) { + for (bits = bitstream_read(bc, 4) - 1; bits >= 0; bits--) { list_pos = list_start; while (list_pos < list_end) { - if (!(mode_list[list_pos] | coef_list[list_pos]) || !get_bits1(gb)) { + if (!(mode_list[list_pos] | coef_list[list_pos]) || !bitstream_read_bit(bc)) { list_pos++; continue; } @@ -634,16 +632,15 @@ static int read_dct_coeffs(GetBitContext *gb, int32_t block[64], const uint8_t * mode_list[list_pos++] = 0; } for (i = 0; i < 4; i++, ccoef++) { - if (get_bits1(gb)) { + if (bitstream_read_bit(bc)) { coef_list[--list_start] = ccoef; mode_list[ list_start] = 3; } else { if (!bits) { - t = 1 - (get_bits1(gb) << 1); + t = 1 - (bitstream_read_bit(bc) << 1); } else { - t = get_bits(gb, bits) | 1 << bits; - sign = -get_bits1(gb); - t = (t ^ sign) - sign; + t = bitstream_read(bc, bits) | 1 << bits; + t = bitstream_apply_sign(bc, t); } block[scan[ccoef]] = t; coef_idx[coef_count++] = ccoef; @@ -660,11 +657,10 @@ static int read_dct_coeffs(GetBitContext *gb, int32_t block[64], const uint8_t * break; case 3: if (!bits) { - t = 1 - (get_bits1(gb) << 1); + t = 1 - (bitstream_read_bit(bc) << 1); } else { - t = get_bits(gb, bits) | 1 << bits; - sign = -get_bits1(gb); - t = (t ^ sign) - sign; + t = bitstream_read(bc, bits) | 1 << bits; + t = bitstream_apply_sign(bc, t); } block[scan[ccoef]] = t; coef_idx[coef_count++] = ccoef; @@ -676,7 +672,7 @@ static int read_dct_coeffs(GetBitContext *gb, int32_t block[64], const uint8_t * } if (q == -1) { - quant_idx = get_bits(gb, 4); + quant_idx = bitstream_read(bc, 4); } else { quant_idx = q; } @@ -698,16 +694,16 @@ static int read_dct_coeffs(GetBitContext *gb, int32_t block[64], const uint8_t * /** * Read 8x8 block with residue after motion compensation. * - * @param gb context for reading bits + * @param bc context for reading bits * @param block place to store read data * @param masks_count number of masks to decode * @return 0 on success, negative value in other cases */ -static int read_residue(GetBitContext *gb, int16_t block[64], int masks_count) +static int read_residue(BitstreamContext *bc, int16_t block[64], int masks_count) { int coef_list[128]; int mode_list[128]; - int i, sign, mask, ccoef, mode; + int i, mask, ccoef, mode; int list_start = 64, list_end = 64, list_pos; int nz_coeff[64]; int nz_coeff_count = 0; @@ -717,9 +713,9 @@ static int read_residue(GetBitContext *gb, int16_t block[64], int masks_count) coef_list[list_end] = 44; mode_list[list_end++] = 0; coef_list[list_end] = 0; mode_list[list_end++] = 2; - for (mask = 1 << get_bits(gb, 3); mask; mask >>= 1) { + for (mask = 1 << bitstream_read(bc, 3); mask; mask >>= 1) { for (i = 0; i < nz_coeff_count; i++) { - if (!get_bits1(gb)) + if (!bitstream_read_bit(bc)) continue; if (block[nz_coeff[i]] < 0) block[nz_coeff[i]] -= mask; @@ -731,7 +727,7 @@ static int read_residue(GetBitContext *gb, int16_t block[64], int masks_count) } list_pos = list_start; while (list_pos < list_end) { - if (!(coef_list[list_pos] | mode_list[list_pos]) || !get_bits1(gb)) { + if (!(coef_list[list_pos] | mode_list[list_pos]) || !bitstream_read_bit(bc)) { list_pos++; continue; } @@ -747,13 +743,12 @@ static int read_residue(GetBitContext *gb, int16_t block[64], int masks_count) mode_list[list_pos++] = 0; } for (i = 0; i < 4; i++, ccoef++) { - if (get_bits1(gb)) { + if (bitstream_read_bit(bc)) { coef_list[--list_start] = ccoef; mode_list[ list_start] = 3; } else { nz_coeff[nz_coeff_count++] = bink_scan[ccoef]; - sign = -get_bits1(gb); - block[bink_scan[ccoef]] = (mask ^ sign) - sign; + block[bink_scan[ccoef]] = bitstream_apply_sign(bc, mask); masks_count--; if (masks_count < 0) return 0; @@ -770,8 +765,7 @@ static int read_residue(GetBitContext *gb, int16_t block[64], int masks_count) break; case 3: nz_coeff[nz_coeff_count++] = bink_scan[ccoef]; - sign = -get_bits1(gb); - block[bink_scan[ccoef]] = (mask ^ sign) - sign; + block[bink_scan[ccoef]] = bitstream_apply_sign(bc, mask); coef_list[list_pos] = 0; mode_list[list_pos++] = 0; masks_count--; @@ -798,7 +792,7 @@ static inline void put_pixels8x8_overlapped(uint8_t *dst, uint8_t *src, int stri memcpy(dst + i*stride, tmp + i*8, 8); } -static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, +static int binkb_decode_plane(BinkContext *c, AVFrame *frame, BitstreamContext *bc, int plane_idx, int is_key, int is_chroma) { int blk, ret; @@ -826,7 +820,7 @@ static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, for (by = 0; by < bh; by++) { for (i = 0; i < BINKB_NB_SRC; i++) { - if ((ret = binkb_read_bundle(c, gb, i)) < 0) + if ((ret = binkb_read_bundle(c, bc, i)) < 0) return ret; } @@ -837,13 +831,11 @@ static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, case 0: break; case 1: - scan = bink_patterns[get_bits(gb, 4)]; + scan = bink_patterns[bitstream_read(bc, 4)]; i = 0; do { - int mode, run; - - mode = get_bits1(gb); - run = get_bits(gb, binkb_runbits[i]) + 1; + int mode = bitstream_read_bit(bc); + int run = bitstream_read(bc, binkb_runbits[i]) + 1; i += run; if (i > 64) { @@ -866,7 +858,7 @@ static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, memset(dctblock, 0, sizeof(*dctblock) * 64); dctblock[0] = binkb_get_value(c, BINKB_SRC_INTRA_DC); qp = binkb_get_value(c, BINKB_SRC_INTRA_Q); - read_dct_coeffs(gb, dctblock, bink_scan, binkb_intra_quant, qp); + read_dct_coeffs(bc, dctblock, bink_scan, binkb_intra_quant, qp); c->binkdsp.idct_put(dst, stride, dctblock); break; case 3: @@ -882,7 +874,7 @@ static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, } c->bdsp.clear_block(block); v = binkb_get_value(c, BINKB_SRC_INTER_COEFS); - read_residue(gb, block, v); + read_residue(bc, block, v); c->binkdsp.add_pixels8(dst, block, stride); break; case 4: @@ -899,7 +891,7 @@ static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, memset(dctblock, 0, sizeof(*dctblock) * 64); dctblock[0] = binkb_get_value(c, BINKB_SRC_INTER_DC); qp = binkb_get_value(c, BINKB_SRC_INTER_Q); - read_dct_coeffs(gb, dctblock, bink_scan, binkb_inter_quant, qp); + read_dct_coeffs(bc, dctblock, bink_scan, binkb_inter_quant, qp); c->binkdsp.idct_add(dst, stride, dctblock); break; case 5: @@ -938,8 +930,8 @@ static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, } } } - if (get_bits_count(gb) & 0x1F) //next plane data starts at 32-bit boundary - skip_bits_long(gb, 32 - (get_bits_count(gb) & 0x1F)); + if (bitstream_tell(bc) & 0x1F) // next plane data starts at 32-bit boundary + bitstream_skip(bc, 32 - (bitstream_tell(bc) & 0x1F)); return 0; } @@ -962,7 +954,7 @@ static int bink_put_pixels(BinkContext *c, return 0; } -static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, +static int bink_decode_plane(BinkContext *c, AVFrame *frame, BitstreamContext *bc, int plane_idx, int is_chroma) { int blk, ret; @@ -982,7 +974,7 @@ static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, init_lengths(c, FFMAX(width, 8), bw); for (i = 0; i < BINK_NB_SRC; i++) - read_bundle(gb, c, i); + read_bundle(bc, c, i); ref_start = c->last->data[plane_idx] ? c->last->data[plane_idx] : frame->data[plane_idx]; @@ -993,23 +985,23 @@ static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, coordmap[i] = (i & 7) + (i >> 3) * stride; for (by = 0; by < bh; by++) { - if ((ret = read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_BLOCK_TYPES])) < 0) + if ((ret = read_block_types(c->avctx, bc, &c->bundle[BINK_SRC_BLOCK_TYPES])) < 0) return ret; - if ((ret = read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_SUB_BLOCK_TYPES])) < 0) + if ((ret = read_block_types(c->avctx, bc, &c->bundle[BINK_SRC_SUB_BLOCK_TYPES])) < 0) return ret; - if ((ret = read_colors(gb, &c->bundle[BINK_SRC_COLORS], c)) < 0) + if ((ret = read_colors(bc, &c->bundle[BINK_SRC_COLORS], c)) < 0) return ret; - if ((ret = read_patterns(c->avctx, gb, &c->bundle[BINK_SRC_PATTERN])) < 0) + if ((ret = read_patterns(c->avctx, bc, &c->bundle[BINK_SRC_PATTERN])) < 0) return ret; - if ((ret = read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_X_OFF])) < 0) + if ((ret = read_motion_values(c->avctx, bc, &c->bundle[BINK_SRC_X_OFF])) < 0) return ret; - if ((ret = read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_Y_OFF])) < 0) + if ((ret = read_motion_values(c->avctx, bc, &c->bundle[BINK_SRC_Y_OFF])) < 0) return ret; - if ((ret = read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0)) < 0) + if ((ret = read_dcs(c->avctx, bc, &c->bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0)) < 0) return ret; - if ((ret = read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1)) < 0) + if ((ret = read_dcs(c->avctx, bc, &c->bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1)) < 0) return ret; - if ((ret = read_runs(c->avctx, gb, &c->bundle[BINK_SRC_RUN])) < 0) + if ((ret = read_runs(c->avctx, bc, &c->bundle[BINK_SRC_RUN])) < 0) return ret; if (by == bh) @@ -1034,7 +1026,7 @@ static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, blk = get_value(c, BINK_SRC_SUB_BLOCK_TYPES); switch (blk) { case RUN_BLOCK: - scan = bink_patterns[get_bits(gb, 4)]; + scan = bink_patterns[bitstream_read(bc, 4)]; i = 0; do { int run = get_value(c, BINK_SRC_RUN) + 1; @@ -1044,7 +1036,7 @@ static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); return AVERROR_INVALIDDATA; } - if (get_bits1(gb)) { + if (bitstream_read_bit(bc)) { v = get_value(c, BINK_SRC_COLORS); for (j = 0; j < run; j++) ublock[*scan++] = v; @@ -1059,7 +1051,7 @@ static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, case INTRA_BLOCK: memset(dctblock, 0, sizeof(*dctblock) * 64); dctblock[0] = get_value(c, BINK_SRC_INTRA_DC); - read_dct_coeffs(gb, dctblock, bink_scan, bink_intra_quant, -1); + read_dct_coeffs(bc, dctblock, bink_scan, bink_intra_quant, -1); c->binkdsp.idct_put(ublock, 8, dctblock); break; case FILL_BLOCK: @@ -1097,7 +1089,7 @@ static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, return ret; break; case RUN_BLOCK: - scan = bink_patterns[get_bits(gb, 4)]; + scan = bink_patterns[bitstream_read(bc, 4)]; i = 0; do { int run = get_value(c, BINK_SRC_RUN) + 1; @@ -1107,7 +1099,7 @@ static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); return AVERROR_INVALIDDATA; } - if (get_bits1(gb)) { + if (bitstream_read_bit(bc)) { v = get_value(c, BINK_SRC_COLORS); for (j = 0; j < run; j++) dst[coordmap[*scan++]] = v; @@ -1125,14 +1117,14 @@ static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, if (ret < 0) return ret; c->bdsp.clear_block(block); - v = get_bits(gb, 7); - read_residue(gb, block, v); + v = bitstream_read(bc, 7); + read_residue(bc, block, v); c->binkdsp.add_pixels8(dst, block, stride); break; case INTRA_BLOCK: memset(dctblock, 0, sizeof(*dctblock) * 64); dctblock[0] = get_value(c, BINK_SRC_INTRA_DC); - read_dct_coeffs(gb, dctblock, bink_scan, bink_intra_quant, -1); + read_dct_coeffs(bc, dctblock, bink_scan, bink_intra_quant, -1); c->binkdsp.idct_put(dst, stride, dctblock); break; case FILL_BLOCK: @@ -1146,7 +1138,7 @@ static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, return ret; memset(dctblock, 0, sizeof(*dctblock) * 64); dctblock[0] = get_value(c, BINK_SRC_INTER_DC); - read_dct_coeffs(gb, dctblock, bink_scan, bink_inter_quant, -1); + read_dct_coeffs(bc, dctblock, bink_scan, bink_inter_quant, -1); c->binkdsp.idct_add(dst, stride, dctblock); break; case PATTERN_BLOCK: @@ -1169,8 +1161,8 @@ static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, } } } - if (get_bits_count(gb) & 0x1F) //next plane data starts at 32-bit boundary - skip_bits_long(gb, 32 - (get_bits_count(gb) & 0x1F)); + if (bitstream_tell(bc) & 0x1F) // next plane data starts at 32-bit boundary + bitstream_skip(bc, 32 - (bitstream_tell(bc) & 0x1F)); return 0; } @@ -1179,7 +1171,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac { BinkContext * const c = avctx->priv_data; AVFrame *frame = data; - GetBitContext gb; + BitstreamContext bc; int plane, plane_idx, ret; int bits_count = pkt->size << 3; @@ -1197,28 +1189,28 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac return ret; } - init_get_bits(&gb, pkt->data, bits_count); + bitstream_init(&bc, pkt->data, bits_count); if (c->has_alpha) { if (c->version >= 'i') - skip_bits_long(&gb, 32); - if ((ret = bink_decode_plane(c, frame, &gb, 3, 0)) < 0) + bitstream_skip(&bc, 32); + if ((ret = bink_decode_plane(c, frame, &bc, 3, 0)) < 0) return ret; } if (c->version >= 'i') - skip_bits_long(&gb, 32); + bitstream_skip(&bc, 32); for (plane = 0; plane < 3; plane++) { plane_idx = (!plane || !c->swap_planes) ? plane : (plane ^ 3); if (c->version > 'b') { - if ((ret = bink_decode_plane(c, frame, &gb, plane_idx, !!plane)) < 0) + if ((ret = bink_decode_plane(c, frame, &bc, plane_idx, !!plane)) < 0) return ret; } else { - if ((ret = binkb_decode_plane(c, frame, &gb, plane_idx, + if ((ret = binkb_decode_plane(c, frame, &bc, plane_idx, !avctx->frame_number, !!plane)) < 0) return ret; } - if (get_bits_count(&gb) >= bits_count) + if (bitstream_tell(&bc) >= bits_count) break; } emms_c(); From 0977a7c2f6302508e5180f0f82139c8c8cf4a131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 9 Apr 2016 16:11:42 +0200 Subject: [PATCH 0509/3374] binkaudio: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/binkaudio.c | 59 +++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c index 2638eb2b04ca4..cf61135529a84 100644 --- a/libavcodec/binkaudio.c +++ b/libavcodec/binkaudio.c @@ -33,8 +33,8 @@ #define BITSTREAM_READER_LE #include "avcodec.h" +#include "bitstream.h" #include "dct.h" -#include "get_bits.h" #include "internal.h" #include "rdft.h" #include "wma_freqs.h" @@ -45,7 +45,7 @@ static float quant_table[96]; #define BINK_BLOCK_MAX_SIZE (MAX_CHANNELS << 11) typedef struct BinkAudioContext { - GetBitContext gb; + BitstreamContext bc; int version_b; ///< Bink version 'b' int first; int channels; @@ -143,11 +143,11 @@ static av_cold int decode_init(AVCodecContext *avctx) return 0; } -static float get_float(GetBitContext *gb) +static float get_float(BitstreamContext *bc) { - int power = get_bits(gb, 5); - float f = ldexpf(get_bits_long(gb, 23), power - 23); - if (get_bits1(gb)) + int power = bitstream_read(bc, 5); + float f = ldexpf(bitstream_read(bc, 23), power - 23); + if (bitstream_read_bit(bc)) f = -f; return f; } @@ -166,30 +166,30 @@ static int decode_block(BinkAudioContext *s, float **out, int use_dct) int ch, i, j, k; float q, quant[25]; int width, coeff; - GetBitContext *gb = &s->gb; + BitstreamContext *bc = &s->bc; if (use_dct) - skip_bits(gb, 2); + bitstream_skip(bc, 2); for (ch = 0; ch < s->channels; ch++) { FFTSample *coeffs = out[ch]; if (s->version_b) { - if (get_bits_left(gb) < 64) + if (bitstream_bits_left(bc) < 64) return AVERROR_INVALIDDATA; - coeffs[0] = av_int2float(get_bits_long(gb, 32)) * s->root; - coeffs[1] = av_int2float(get_bits_long(gb, 32)) * s->root; + coeffs[0] = av_int2float(bitstream_read(bc, 32)) * s->root; + coeffs[1] = av_int2float(bitstream_read(bc, 32)) * s->root; } else { - if (get_bits_left(gb) < 58) + if (bitstream_bits_left(bc) < 58) return AVERROR_INVALIDDATA; - coeffs[0] = get_float(gb) * s->root; - coeffs[1] = get_float(gb) * s->root; + coeffs[0] = get_float(bc) * s->root; + coeffs[1] = get_float(bc) * s->root; } - if (get_bits_left(gb) < s->num_bands * 8) + if (bitstream_bits_left(bc) < s->num_bands * 8) return AVERROR_INVALIDDATA; for (i = 0; i < s->num_bands; i++) { - int value = get_bits(gb, 8); + int value = bitstream_read(bc, 8); quant[i] = quant_table[FFMIN(value, 95)]; } @@ -202,9 +202,9 @@ static int decode_block(BinkAudioContext *s, float **out, int use_dct) if (s->version_b) { j = i + 16; } else { - int v = get_bits1(gb); + int v = bitstream_read_bit(bc); if (v) { - v = get_bits(gb, 4); + v = bitstream_read(bc, 4); j = i + rle_length_tab[v] * 8; } else { j = i + 8; @@ -213,7 +213,7 @@ static int decode_block(BinkAudioContext *s, float **out, int use_dct) j = FFMIN(j, s->frame_len); - width = get_bits(gb, 4); + width = bitstream_read(bc, 4); if (width == 0) { memset(coeffs + i, 0, (j - i) * sizeof(*coeffs)); i = j; @@ -223,10 +223,10 @@ static int decode_block(BinkAudioContext *s, float **out, int use_dct) while (i < j) { if (s->bands[k] == i) q = quant[k++]; - coeff = get_bits(gb, width); + coeff = bitstream_read(bc, width); if (coeff) { int v; - v = get_bits1(gb); + v = bitstream_read_bit(bc); if (v) coeffs[i] = -q * coeff; else @@ -278,10 +278,11 @@ static av_cold int decode_end(AVCodecContext *avctx) return 0; } -static void get_bits_align32(GetBitContext *s) +static void get_bits_align32(BitstreamContext *s) { - int n = (-get_bits_count(s)) & 31; - if (n) skip_bits(s, n); + int n = (-bitstream_tell(s)) & 31; + if (n) + bitstream_skip(s, n); } static int decode_frame(AVCodecContext *avctx, void *data, @@ -289,10 +290,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, { BinkAudioContext *s = avctx->priv_data; AVFrame *frame = data; - GetBitContext *gb = &s->gb; + BitstreamContext *bc = &s->bc; int ret, consumed = 0; - if (!get_bits_left(gb)) { + if (!bitstream_bits_left(bc)) { uint8_t *buf; /* handle end-of-stream */ if (!avpkt->size) { @@ -308,11 +309,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, return AVERROR(ENOMEM); s->packet_buffer = buf; memcpy(s->packet_buffer, avpkt->data, avpkt->size); - init_get_bits(gb, s->packet_buffer, avpkt->size * 8); + bitstream_init(bc, s->packet_buffer, avpkt->size * 8); consumed = avpkt->size; /* skip reported size */ - skip_bits_long(gb, 32); + bitstream_skip(bc, 32); } /* get output buffer */ @@ -327,7 +328,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "Incomplete packet\n"); return AVERROR_INVALIDDATA; } - get_bits_align32(gb); + get_bits_align32(bc); frame->nb_samples = s->block_size / avctx->channels; *got_frame_ptr = 1; From b4c0daa83c0c5e7505703af65de95fb22d6cbe72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 9 Apr 2016 16:20:13 +0200 Subject: [PATCH 0510/3374] cdxl: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/cdxl.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/libavcodec/cdxl.c b/libavcodec/cdxl.c index 99e96eb502cac..4c0410dd212eb 100644 --- a/libavcodec/cdxl.c +++ b/libavcodec/cdxl.c @@ -21,8 +21,9 @@ #include "libavutil/intreadwrite.h" #include "libavutil/imgutils.h" + #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "internal.h" #define BIT_PLANAR 0x00 @@ -69,30 +70,30 @@ static void import_palette(CDXLVideoContext *c, uint32_t *new_palette) static void bitplanar2chunky(CDXLVideoContext *c, int linesize, uint8_t *out) { - GetBitContext gb; + BitstreamContext bc; int x, y, plane; - init_get_bits(&gb, c->video, c->video_size * 8); + bitstream_init(&bc, c->video, c->video_size * 8); for (plane = 0; plane < c->bpp; plane++) { for (y = 0; y < c->avctx->height; y++) { for (x = 0; x < c->avctx->width; x++) - out[linesize * y + x] |= get_bits1(&gb) << plane; - skip_bits(&gb, c->padded_bits); + out[linesize * y + x] |= bitstream_read_bit(&bc) << plane; + bitstream_skip(&bc, c->padded_bits); } } } static void bitline2chunky(CDXLVideoContext *c, int linesize, uint8_t *out) { - GetBitContext gb; + BitstreamContext bc; int x, y, plane; - init_get_bits(&gb, c->video, c->video_size * 8); + bitstream_init(&bc, c->video, c->video_size * 8); for (y = 0; y < c->avctx->height; y++) { for (plane = 0; plane < c->bpp; plane++) { for (x = 0; x < c->avctx->width; x++) - out[linesize * y + x] |= get_bits1(&gb) << plane; - skip_bits(&gb, c->padded_bits); + out[linesize * y + x] |= bitstream_read_bit(&bc) << plane; + bitstream_skip(&bc, c->padded_bits); } } } From e561146611f5cf410df78b53a4ca5cded2272fd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 9 Apr 2016 17:34:03 +0200 Subject: [PATCH 0511/3374] cljrdec: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/cljrdec.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libavcodec/cljrdec.c b/libavcodec/cljrdec.c index 33d8023429bf2..833707b0999f1 100644 --- a/libavcodec/cljrdec.c +++ b/libavcodec/cljrdec.c @@ -25,7 +25,7 @@ */ #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "internal.h" static int decode_frame(AVCodecContext *avctx, @@ -34,7 +34,7 @@ static int decode_frame(AVCodecContext *avctx, { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - GetBitContext gb; + BitstreamContext bc; AVFrame * const p = data; int x, y, ret; @@ -56,20 +56,20 @@ static int decode_frame(AVCodecContext *avctx, p->pict_type = AV_PICTURE_TYPE_I; p->key_frame = 1; - init_get_bits(&gb, buf, buf_size * 8); + bitstream_init(&bc, buf, buf_size * 8); for (y = 0; y < avctx->height; y++) { uint8_t *luma = &p->data[0][y * p->linesize[0]]; uint8_t *cb = &p->data[1][y * p->linesize[1]]; uint8_t *cr = &p->data[2][y * p->linesize[2]]; for (x = 0; x < avctx->width; x += 4) { - luma[3] = get_bits(&gb, 5) << 3; - luma[2] = get_bits(&gb, 5) << 3; - luma[1] = get_bits(&gb, 5) << 3; - luma[0] = get_bits(&gb, 5) << 3; + luma[3] = bitstream_read(&bc, 5) << 3; + luma[2] = bitstream_read(&bc, 5) << 3; + luma[1] = bitstream_read(&bc, 5) << 3; + luma[0] = bitstream_read(&bc, 5) << 3; luma += 4; - *(cb++) = get_bits(&gb, 6) << 2; - *(cr++) = get_bits(&gb, 6) << 2; + *(cb++) = bitstream_read(&bc, 6) << 2; + *(cr++) = bitstream_read(&bc, 6) << 2; } } From 942e84d2a3c41a9392743ea6b1cb24ca8163d678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 9 Apr 2016 18:00:37 +0200 Subject: [PATCH 0512/3374] cook: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/cook.c | 53 ++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/libavcodec/cook.c b/libavcodec/cook.c index c990333a7cd93..c3304eae2e3dc 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -47,7 +47,7 @@ #include "audiodsp.h" #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "bytestream.h" #include "fft.h" #include "internal.h" @@ -124,7 +124,7 @@ typedef struct cook { AVCodecContext* avctx; AudioDSPContext adsp; - GetBitContext gb; + BitstreamContext bc; /* stream data */ int num_vectors; int samples_per_channel; @@ -325,23 +325,23 @@ static av_cold int cook_decode_close(AVCodecContext *avctx) /** * Fill the gain array for the timedomain quantization. * - * @param gb pointer to the GetBitContext + * @param bc pointer to the BitstreamContext * @param gaininfo array[9] of gain indexes */ -static void decode_gain_info(GetBitContext *gb, int *gaininfo) +static void decode_gain_info(BitstreamContext *bc, int *gaininfo) { int i, n; - while (get_bits1(gb)) { + while (bitstream_read_bit(bc)) { /* NOTHING */ } - n = get_bits_count(gb) - 1; // amount of elements*2 to update + n = bitstream_tell(bc) - 1; // amount of elements * 2 to update i = 0; while (n--) { - int index = get_bits(gb, 3); - int gain = get_bits1(gb) ? get_bits(gb, 4) - 7 : -1; + int index = bitstream_read(bc, 3); + int gain = bitstream_read_bit(bc) ? bitstream_read(bc, 4) - 7 : -1; while (i <= index) gaininfo[i++] = gain; @@ -361,7 +361,7 @@ static int decode_envelope(COOKContext *q, COOKSubpacket *p, { int i, j, vlc_index; - quant_index_table[0] = get_bits(&q->gb, 6) - 6; // This is used later in categorize + quant_index_table[0] = bitstream_read(&q->bc, 6) - 6; // This is used later in categorize for (i = 1; i < p->total_subbands; i++) { vlc_index = i; @@ -375,8 +375,8 @@ static int decode_envelope(COOKContext *q, COOKSubpacket *p, if (vlc_index > 13) vlc_index = 13; // the VLC tables >13 are identical to No. 13 - j = get_vlc2(&q->gb, q->envelope_quant_index[vlc_index - 1].table, - q->envelope_quant_index[vlc_index - 1].bits, 2); + j = bitstream_read_vlc(&q->bc, q->envelope_quant_index[vlc_index - 1].table, + q->envelope_quant_index[vlc_index - 1].bits, 2); quant_index_table[i] = quant_index_table[i - 1] + j - 12; // differential encoding if (quant_index_table[i] > 63 || quant_index_table[i] < -63) { av_log(q->avctx, AV_LOG_ERROR, @@ -408,7 +408,7 @@ static void categorize(COOKContext *q, COOKSubpacket *p, int *quant_index_table, int tmp_categorize_array1_idx = p->numvector_size; int tmp_categorize_array2_idx = p->numvector_size; - bits_left = p->bits_per_subpacket - get_bits_count(&q->gb); + bits_left = p->bits_per_subpacket - bitstream_tell(&q->bc); if (bits_left > q->samples_per_channel) bits_left = q->samples_per_channel + @@ -554,8 +554,8 @@ static int unpack_SQVH(COOKContext *q, COOKSubpacket *p, int category, vd = vd_tab[category]; result = 0; for (i = 0; i < vpr_tab[category]; i++) { - vlc = get_vlc2(&q->gb, q->sqvh[category].table, q->sqvh[category].bits, 3); - if (p->bits_per_subpacket < get_bits_count(&q->gb)) { + vlc = bitstream_read_vlc(&q->bc, q->sqvh[category].table, q->sqvh[category].bits, 3); + if (p->bits_per_subpacket < bitstream_tell(&q->bc)) { vlc = 0; result = 1; } @@ -566,8 +566,8 @@ static int unpack_SQVH(COOKContext *q, COOKSubpacket *p, int category, } for (j = 0; j < vd; j++) { if (subband_coef_index[i * vd + j]) { - if (get_bits_count(&q->gb) < p->bits_per_subpacket) { - subband_coef_sign[i * vd + j] = get_bits1(&q->gb); + if (bitstream_tell(&q->bc) < p->bits_per_subpacket) { + subband_coef_sign[i * vd + j] = bitstream_read_bit(&q->bc); } else { result = 1; subband_coef_sign[i * vd + j] = 0; @@ -634,7 +634,7 @@ static int mono_decode(COOKContext *q, COOKSubpacket *p, float *mlt_buffer) if ((res = decode_envelope(q, p, quant_index_table)) < 0) return res; - q->num_vectors = get_bits(&q->gb, p->log2_numvector_size); + q->num_vectors = bitstream_read(&q->bc, p->log2_numvector_size); categorize(q, p, quant_index_table, category, category_index); expand_category(q, category, category_index); decode_vectors(q, p, category, quant_index_table, mlt_buffer); @@ -739,7 +739,7 @@ static void imlt_gain(COOKContext *q, float *inbuffer, static void decouple_info(COOKContext *q, COOKSubpacket *p, int *decouple_tab) { int i; - int vlc = get_bits1(&q->gb); + int vlc = bitstream_read_bit(&q->bc); int start = cplband[p->js_subband_start]; int end = cplband[p->subbands - 1]; int length = end - start + 1; @@ -749,12 +749,13 @@ static void decouple_info(COOKContext *q, COOKSubpacket *p, int *decouple_tab) if (vlc) for (i = 0; i < length; i++) - decouple_tab[start + i] = get_vlc2(&q->gb, - p->channel_coupling.table, - p->channel_coupling.bits, 2); + decouple_tab[start + i] = + bitstream_read_vlc(&q->bc, + p->channel_coupling.table, + p->channel_coupling.bits, 2); else for (i = 0; i < length; i++) - decouple_tab[start + i] = get_bits(&q->gb, p->js_vlc_bits); + decouple_tab[start + i] = bitstream_read(&q->bc, p->js_vlc_bits); } /* @@ -850,9 +851,9 @@ static inline void decode_bytes_and_gain(COOKContext *q, COOKSubpacket *p, offset = decode_bytes(inbuffer, q->decoded_bytes_buffer, p->bits_per_subpacket / 8); - init_get_bits(&q->gb, q->decoded_bytes_buffer + offset, - p->bits_per_subpacket); - decode_gain_info(&q->gb, gains_ptr->now); + bitstream_init(&q->bc, q->decoded_bytes_buffer + offset, + p->bits_per_subpacket); + decode_gain_info(&q->bc, gains_ptr->now); /* Swap current and previous gains */ FFSWAP(int *, gains_ptr->now, gains_ptr->previous); @@ -994,7 +995,7 @@ static int cook_decode_frame(AVCodecContext *avctx, void *data, offset += q->subpacket[i].size; chidx += q->subpacket[i].num_channels; av_log(avctx, AV_LOG_DEBUG, "subpacket[%i] %i %i\n", - i, q->subpacket[i].size * 8, get_bits_count(&q->gb)); + i, q->subpacket[i].size * 8, bitstream_tell(&q->bc)); } /* Discard the first two frames: no valid audio. */ From 928f8c7ce360f464f1c5d3a363b2d4b1eb7c471f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 9 Apr 2016 18:58:25 +0200 Subject: [PATCH 0513/3374] dss_sp: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/dss_sp.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/libavcodec/dss_sp.c b/libavcodec/dss_sp.c index 20b05287a70b1..44d98d8cf99d9 100644 --- a/libavcodec/dss_sp.c +++ b/libavcodec/dss_sp.c @@ -25,7 +25,7 @@ #include "libavutil/opt.h" #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "internal.h" #define SUBFRAMES 4 @@ -302,7 +302,7 @@ static av_cold int dss_sp_decode_init(AVCodecContext *avctx) static void dss_sp_unpack_coeffs(DssSpContext *p, const uint8_t *src) { - GetBitContext gb; + BitstreamContext bc; DssSpFrame *fparam = &p->fparam; int i; int subframe_idx; @@ -315,24 +315,24 @@ static void dss_sp_unpack_coeffs(DssSpContext *p, const uint8_t *src) p->bits[i + 1] = src[i]; } - init_get_bits(&gb, p->bits, DSS_SP_FRAME_SIZE * 8); + bitstream_init(&bc, p->bits, DSS_SP_FRAME_SIZE * 8); for (i = 0; i < 2; i++) - fparam->filter_idx[i] = get_bits(&gb, 5); + fparam->filter_idx[i] = bitstream_read(&bc, 5); for (; i < 8; i++) - fparam->filter_idx[i] = get_bits(&gb, 4); + fparam->filter_idx[i] = bitstream_read(&bc, 4); for (; i < 14; i++) - fparam->filter_idx[i] = get_bits(&gb, 3); + fparam->filter_idx[i] = bitstream_read(&bc, 3); for (subframe_idx = 0; subframe_idx < 4; subframe_idx++) { - fparam->sf_adaptive_gain[subframe_idx] = get_bits(&gb, 5); + fparam->sf_adaptive_gain[subframe_idx] = bitstream_read(&bc, 5); - fparam->sf[subframe_idx].combined_pulse_pos = get_bits_long(&gb, 31); + fparam->sf[subframe_idx].combined_pulse_pos = bitstream_read(&bc, 31); - fparam->sf[subframe_idx].gain = get_bits(&gb, 6); + fparam->sf[subframe_idx].gain = bitstream_read(&bc, 6); for (i = 0; i < 7; i++) - fparam->sf[subframe_idx].pulse_val[i] = get_bits(&gb, 3); + fparam->sf[subframe_idx].pulse_val[i] = bitstream_read(&bc, 3); } for (subframe_idx = 0; subframe_idx < 4; subframe_idx++) { @@ -394,7 +394,7 @@ static void dss_sp_unpack_coeffs(DssSpContext *p, const uint8_t *src) } } - combined_pitch = get_bits(&gb, 24); + combined_pitch = bitstream_read(&bc, 24); fparam->pitch_lag[0] = (combined_pitch % 151) + 36; From d8618570beb52001c0e8960777bab6158a60b3f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 9 Apr 2016 19:05:56 +0200 Subject: [PATCH 0514/3374] dvdsubdec: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/dvdsubdec.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/libavcodec/dvdsubdec.c b/libavcodec/dvdsubdec.c index 86c287391ff92..b02bb6b93f4bf 100644 --- a/libavcodec/dvdsubdec.c +++ b/libavcodec/dvdsubdec.c @@ -20,7 +20,7 @@ */ #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "internal.h" #include "libavutil/attributes.h" @@ -50,13 +50,13 @@ static void yuv_a_to_rgba(const uint8_t *ycbcr, const uint8_t *alpha, uint32_t * } } -static int decode_run_2bit(GetBitContext *gb, int *color) +static int decode_run_2bit(BitstreamContext *bc, int *color) { unsigned int v, t; v = 0; for (t = 1; v < t && t <= 0x40; t <<= 2) - v = (v << 4) | get_bits(gb, 4); + v = (v << 4) | bitstream_read(bc, 4); *color = v & 3; if (v < 4) { /* Code for fill rest of line */ return INT_MAX; @@ -64,23 +64,23 @@ static int decode_run_2bit(GetBitContext *gb, int *color) return v >> 2; } -static int decode_run_8bit(GetBitContext *gb, int *color) +static int decode_run_8bit(BitstreamContext *bc, int *color) { int len; - int has_run = get_bits1(gb); - if (get_bits1(gb)) - *color = get_bits(gb, 8); + int has_run = bitstream_read_bit(bc); + if (bitstream_read_bit(bc)) + *color = bitstream_read(bc, 8); else - *color = get_bits(gb, 2); + *color = bitstream_read(bc, 2); if (has_run) { - if (get_bits1(gb)) { - len = get_bits(gb, 7); + if (bitstream_read_bit(bc)) { + len = bitstream_read(bc, 7); if (len == 0) len = INT_MAX; else len += 9; } else - len = get_bits(gb, 3) + 2; + len = bitstream_read(bc, 3) + 2; } else len = 1; return len; @@ -89,24 +89,24 @@ static int decode_run_8bit(GetBitContext *gb, int *color) static int decode_rle(uint8_t *bitmap, int linesize, int w, int h, const uint8_t *buf, int start, int buf_size, int is_8bit) { - GetBitContext gb; + BitstreamContext bc; int bit_len; int x, y, len, color; uint8_t *d; bit_len = (buf_size - start) * 8; - init_get_bits(&gb, buf + start, bit_len); + bitstream_init(&bc, buf + start, bit_len); x = 0; y = 0; d = bitmap; for(;;) { - if (get_bits_count(&gb) > bit_len) + if (bitstream_tell(&bc) > bit_len) return -1; if (is_8bit) - len = decode_run_8bit(&gb, &color); + len = decode_run_8bit(&bc, &color); else - len = decode_run_2bit(&gb, &color); + len = decode_run_2bit(&bc, &color); len = FFMIN(len, w - x); memset(d + x, color, len); x += len; @@ -117,7 +117,7 @@ static int decode_rle(uint8_t *bitmap, int linesize, int w, int h, d += linesize; x = 0; /* byte align */ - align_get_bits(&gb); + bitstream_align(&bc); } } return 0; From c43eb731721ac1009c2b4ca13f90ef00280119c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 9 Apr 2016 20:36:57 +0200 Subject: [PATCH 0515/3374] escape124: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/escape124.c | 85 ++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 44 deletions(-) diff --git a/libavcodec/escape124.c b/libavcodec/escape124.c index 6d1b487d1beea..879f00a73cd0a 100644 --- a/libavcodec/escape124.c +++ b/libavcodec/escape124.c @@ -21,7 +21,7 @@ #define BITSTREAM_READER_LE #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "internal.h" typedef union MacroBlock { @@ -48,8 +48,9 @@ typedef struct Escape124Context { CodeBook codebooks[3]; } Escape124Context; -static int can_safely_read(GetBitContext* gb, int bits) { - return get_bits_left(gb) >= bits; +static int can_safely_read(BitstreamContext *bc, int bits) +{ + return bitstream_bits_left(bc) >= bits; } /** @@ -86,13 +87,13 @@ static av_cold int escape124_decode_close(AVCodecContext *avctx) return 0; } -static CodeBook unpack_codebook(GetBitContext* gb, unsigned depth, +static CodeBook unpack_codebook(BitstreamContext *bc, unsigned depth, unsigned size) { unsigned i, j; CodeBook cb = { 0 }; - if (!can_safely_read(gb, size * 34)) + if (!can_safely_read(bc, size * 34)) return cb; if (size >= INT_MAX / sizeof(MacroBlock)) @@ -104,9 +105,9 @@ static CodeBook unpack_codebook(GetBitContext* gb, unsigned depth, cb.depth = depth; cb.size = size; for (i = 0; i < size; i++) { - unsigned mask_bits = get_bits(gb, 4); - unsigned color0 = get_bits(gb, 15); - unsigned color1 = get_bits(gb, 15); + unsigned mask_bits = bitstream_read(bc, 4); + unsigned color0 = bitstream_read(bc, 15); + unsigned color1 = bitstream_read(bc, 15); for (j = 0; j < 4; j++) { if (mask_bits & (1 << j)) @@ -118,47 +119,43 @@ static CodeBook unpack_codebook(GetBitContext* gb, unsigned depth, return cb; } -static unsigned decode_skip_count(GetBitContext* gb) +static unsigned decode_skip_count(BitstreamContext *bc) { unsigned value; // This function reads a maximum of 23 bits, // which is within the padding space - if (!can_safely_read(gb, 1)) + if (!can_safely_read(bc, 1)) return -1; - value = get_bits1(gb); + value = bitstream_read_bit(bc); if (!value) return value; - value += get_bits(gb, 3); + value += bitstream_read(bc, 3); if (value != (1 + ((1 << 3) - 1))) return value; - value += get_bits(gb, 7); + value += bitstream_read(bc, 7); if (value != (1 + ((1 << 3) - 1)) + ((1 << 7) - 1)) return value; - return value + get_bits(gb, 12); + return value + bitstream_read(bc, 12); } -static MacroBlock decode_macroblock(Escape124Context* s, GetBitContext* gb, - int* codebook_index, int superblock_index) +static MacroBlock decode_macroblock(Escape124Context *s, BitstreamContext *bc, + int *codebook_index, int superblock_index) { // This function reads a maximum of 22 bits; the callers // guard this function appropriately unsigned block_index, depth; - int value = get_bits1(gb); + int value = bitstream_read_bit(bc); if (value) { static const char transitions[3][2] = { {2, 1}, {0, 2}, {1, 0} }; - value = get_bits1(gb); + value = bitstream_read_bit(bc); *codebook_index = transitions[*codebook_index][value]; } depth = s->codebooks[*codebook_index].depth; - - // depth = 0 means that this shouldn't read any bits; - // in theory, this is the same as get_bits(gb, 0), but - // that doesn't actually work. - block_index = get_bitsz(gb, depth); + block_index = bitstream_read(bc, depth); if (*codebook_index == 1) { block_index += superblock_index << s->codebooks[1].depth; @@ -208,7 +205,7 @@ static int escape124_decode_frame(AVCodecContext *avctx, Escape124Context *s = avctx->priv_data; AVFrame *frame = data; - GetBitContext gb; + BitstreamContext bc; unsigned frame_flags, frame_size; unsigned i; @@ -220,15 +217,15 @@ static int escape124_decode_frame(AVCodecContext *avctx, unsigned old_stride, new_stride; int ret; - init_get_bits(&gb, buf, buf_size * 8); + bitstream_init(&bc, buf, buf_size * 8); // This call also guards the potential depth reads for the // codebook unpacking. - if (!can_safely_read(&gb, 64)) + if (!can_safely_read(&bc, 64)) return -1; - frame_flags = get_bits_long(&gb, 32); - frame_size = get_bits_long(&gb, 32); + frame_flags = bitstream_read(&bc, 32); + frame_size = bitstream_read(&bc, 32); // Leave last frame unchanged // FIXME: Is this necessary? I haven't seen it in any real samples @@ -251,10 +248,10 @@ static int escape124_decode_frame(AVCodecContext *avctx, if (i == 2) { // This codebook can be cut off at places other than // powers of 2, leaving some of the entries undefined. - cb_size = get_bits_long(&gb, 20); + cb_size = bitstream_read(&bc, 20); cb_depth = av_log2(cb_size - 1) + 1; } else { - cb_depth = get_bits(&gb, 4); + cb_depth = bitstream_read(&bc, 4); if (i == 0) { // This is the most basic codebook: pow(2,depth) entries // for a depth-length key @@ -267,7 +264,7 @@ static int escape124_decode_frame(AVCodecContext *avctx, } } av_free(s->codebooks[i].blocks); - s->codebooks[i] = unpack_codebook(&gb, cb_depth, cb_size); + s->codebooks[i] = unpack_codebook(&bc, cb_depth, cb_size); if (!s->codebooks[i].blocks) return -1; } @@ -292,7 +289,7 @@ static int escape124_decode_frame(AVCodecContext *avctx, if (skip == -1) { // Note that this call will make us skip the rest of the blocks // if the frame prematurely ends - skip = decode_skip_count(&gb); + skip = decode_skip_count(&bc); } if (skip) { @@ -302,10 +299,10 @@ static int escape124_decode_frame(AVCodecContext *avctx, copy_superblock(sb.pixels, 8, old_frame_data, old_stride); - while (can_safely_read(&gb, 1) && !get_bits1(&gb)) { + while (can_safely_read(&bc, 1) && !bitstream_read_bit(&bc)) { unsigned mask; - mb = decode_macroblock(s, &gb, &cb_index, superblock_index); - mask = get_bits(&gb, 16); + mb = decode_macroblock(s, &bc, &cb_index, superblock_index); + mask = bitstream_read(&bc, 16); multi_mask |= mask; for (i = 0; i < 16; i++) { if (mask & mask_matrix[i]) { @@ -314,29 +311,29 @@ static int escape124_decode_frame(AVCodecContext *avctx, } } - if (can_safely_read(&gb, 1) && !get_bits1(&gb)) { - unsigned inv_mask = get_bits(&gb, 4); + if (can_safely_read(&bc, 1) && !bitstream_read_bit(&bc)) { + unsigned inv_mask = bitstream_read(&bc, 4); for (i = 0; i < 4; i++) { if (inv_mask & (1 << i)) { multi_mask ^= 0xF << i*4; } else { - multi_mask ^= get_bits(&gb, 4) << i*4; + multi_mask ^= bitstream_read(&bc, 4) << i * 4; } } for (i = 0; i < 16; i++) { if (multi_mask & mask_matrix[i]) { - if (!can_safely_read(&gb, 1)) + if (!can_safely_read(&bc, 1)) break; - mb = decode_macroblock(s, &gb, &cb_index, + mb = decode_macroblock(s, &bc, &cb_index, superblock_index); insert_mb_into_sb(&sb, mb, i); } } } else if (frame_flags & (1 << 16)) { - while (can_safely_read(&gb, 1) && !get_bits1(&gb)) { - mb = decode_macroblock(s, &gb, &cb_index, superblock_index); - insert_mb_into_sb(&sb, mb, get_bits(&gb, 4)); + while (can_safely_read(&bc, 1) && !bitstream_read_bit(&bc)) { + mb = decode_macroblock(s, &bc, &cb_index, superblock_index); + insert_mb_into_sb(&sb, mb, bitstream_read(&bc, 4)); } } @@ -358,7 +355,7 @@ static int escape124_decode_frame(AVCodecContext *avctx, av_log(NULL, AV_LOG_DEBUG, "Escape sizes: %i, %i, %i\n", - frame_size, buf_size, get_bits_count(&gb) / 8); + frame_size, buf_size, bitstream_tell(&bc) / 8); av_frame_unref(s->frame); if ((ret = av_frame_ref(s->frame, frame)) < 0) From 2906d8dcb39751fc16d5585f3751da3174b8e2bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 9 Apr 2016 20:47:04 +0200 Subject: [PATCH 0516/3374] escape130: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/escape130.c | 46 +++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/libavcodec/escape130.c b/libavcodec/escape130.c index bfc1f3f09e64a..544f36d1ac056 100644 --- a/libavcodec/escape130.c +++ b/libavcodec/escape130.c @@ -24,7 +24,7 @@ #define BITSTREAM_READER_LE #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "internal.h" typedef struct Escape130Context { @@ -163,23 +163,23 @@ static av_cold int escape130_decode_close(AVCodecContext *avctx) return 0; } -static int decode_skip_count(GetBitContext* gb) +static int decode_skip_count(BitstreamContext *bc) { int value; - value = get_bits1(gb); + value = bitstream_read_bit(bc); if (value) return 0; - value = get_bits(gb, 3); + value = bitstream_read(bc, 3); if (value) return value; - value = get_bits(gb, 8); + value = bitstream_read(bc, 8); if (value) return value + 7; - value = get_bits(gb, 15); + value = bitstream_read(bc, 15); if (value) return value + 262; @@ -193,7 +193,7 @@ static int escape130_decode_frame(AVCodecContext *avctx, void *data, int buf_size = avpkt->size; Escape130Context *s = avctx->priv_data; AVFrame *pic = data; - GetBitContext gb; + BitstreamContext bc; int ret; uint8_t *old_y, *old_cb, *old_cr, @@ -216,7 +216,7 @@ static int escape130_decode_frame(AVCodecContext *avctx, void *data, if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) return ret; - init_get_bits(&gb, buf + 16, (buf_size - 16) * 8); + bitstream_init(&bc, buf + 16, (buf_size - 16) * 8); new_y = s->new_y; new_cb = s->new_u; @@ -235,7 +235,7 @@ static int escape130_decode_frame(AVCodecContext *avctx, void *data, // Note that this call will make us skip the rest of the blocks // if the frame ends prematurely. if (skip == -1) - skip = decode_skip_count(&gb); + skip = decode_skip_count(&bc); if (skip == -1) { av_log(avctx, AV_LOG_ERROR, "Error decoding skip value\n"); return AVERROR_INVALIDDATA; @@ -250,31 +250,31 @@ static int escape130_decode_frame(AVCodecContext *avctx, void *data, cb = old_cb[0]; cr = old_cr[0]; } else { - if (get_bits1(&gb)) { - unsigned sign_selector = get_bits(&gb, 6); - unsigned difference_selector = get_bits(&gb, 2); - y_avg = 2 * get_bits(&gb, 5); + if (bitstream_read_bit(&bc)) { + unsigned sign_selector = bitstream_read(&bc, 6); + unsigned difference_selector = bitstream_read(&bc, 2); + y_avg = 2 * bitstream_read(&bc, 5); for (i = 0; i < 4; i++) { y[i] = av_clip(y_avg + offset_table[difference_selector] * sign_table[sign_selector][i], 0, 63); } - } else if (get_bits1(&gb)) { - if (get_bits1(&gb)) { - y_avg = get_bits(&gb, 6); + } else if (bitstream_read_bit(&bc)) { + if (bitstream_read_bit(&bc)) { + y_avg = bitstream_read(&bc, 6); } else { - unsigned adjust_index = get_bits(&gb, 3); + unsigned adjust_index = bitstream_read(&bc, 3); y_avg = (y_avg + luma_adjust[adjust_index]) & 63; } for (i = 0; i < 4; i++) y[i] = y_avg; } - if (get_bits1(&gb)) { - if (get_bits1(&gb)) { - cb = get_bits(&gb, 5); - cr = get_bits(&gb, 5); + if (bitstream_read_bit(&bc)) { + if (bitstream_read_bit(&bc)) { + cb = bitstream_read(&bc, 5); + cr = bitstream_read(&bc, 5); } else { - unsigned adjust_index = get_bits(&gb, 3); + unsigned adjust_index = bitstream_read(&bc, 3); cb = (cb + chroma_adjust[0][adjust_index]) & 31; cr = (cr + chroma_adjust[1][adjust_index]) & 31; } @@ -333,7 +333,7 @@ static int escape130_decode_frame(AVCodecContext *avctx, void *data, } ff_dlog(avctx, "Frame data: provided %d bytes, used %d bytes\n", - buf_size, get_bits_count(&gb) >> 3); + buf_size, bitstream_tell(&bc) >> 3); FFSWAP(uint8_t*, s->old_y, s->new_y); FFSWAP(uint8_t*, s->old_u, s->new_u); From 8df1ac6b785a1a159cdffed1eec1ab2a8df66460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 9 Apr 2016 21:00:43 +0200 Subject: [PATCH 0517/3374] exr: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/exr.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libavcodec/exr.c b/libavcodec/exr.c index d10841d8d643f..28cee8413426b 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -39,8 +39,8 @@ #include "libavutil/opt.h" #include "avcodec.h" +#include "bitstream.h" #include "bytestream.h" -#include "get_bits.h" #include "internal.h" #include "mathops.h" #include "thread.h" @@ -379,16 +379,16 @@ static void huf_canonical_code_table(uint64_t *hcode) static int huf_unpack_enc_table(GetByteContext *gb, int32_t im, int32_t iM, uint64_t *hcode) { - GetBitContext gbit; - int ret = init_get_bits8(&gbit, gb->buffer, bytestream2_get_bytes_left(gb)); + BitstreamContext bc; + int ret = bitstream_init8(&bc, gb->buffer, bytestream2_get_bytes_left(gb)); if (ret < 0) return ret; for (; im <= iM; im++) { - uint64_t l = hcode[im] = get_bits(&gbit, 6); + uint64_t l = hcode[im] = bitstream_read(&bc, 6); if (l == LONG_ZEROCODE_RUN) { - int zerun = get_bits(&gbit, 8) + SHORTEST_LONG_RUN; + int zerun = bitstream_read(&bc, 8) + SHORTEST_LONG_RUN; if (im + zerun > iM + 1) return AVERROR_INVALIDDATA; @@ -410,7 +410,7 @@ static int huf_unpack_enc_table(GetByteContext *gb, } } - bytestream2_skip(gb, (get_bits_count(&gbit) + 7) / 8); + bytestream2_skip(gb, (bitstream_tell(&bc) + 7) / 8); huf_canonical_code_table(hcode); return 0; From 418ccdd7034e4cbbb991a4fb47753d76286998f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 9 Apr 2016 21:04:29 +0200 Subject: [PATCH 0518/3374] faxcompr: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/faxcompr.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/libavcodec/faxcompr.c b/libavcodec/faxcompr.c index 4cbda3f1263fe..8a9010d40c08c 100644 --- a/libavcodec/faxcompr.c +++ b/libavcodec/faxcompr.c @@ -25,7 +25,7 @@ * @author Konstantin Shishkov */ #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "put_bits.h" #include "faxcompr.h" @@ -123,7 +123,7 @@ av_cold void ff_ccitt_unpack_init(void) } -static int decode_group3_1d_line(AVCodecContext *avctx, GetBitContext *gb, +static int decode_group3_1d_line(AVCodecContext *avctx, BitstreamContext *bc, unsigned int pix_left, int *runs, const int *runend) { @@ -131,7 +131,7 @@ static int decode_group3_1d_line(AVCodecContext *avctx, GetBitContext *gb, unsigned int run = 0; unsigned int t; for (;;) { - t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2); + t = bitstream_read_vlc(bc, ccitt_vlc[mode].table, 9, 2); run += t; if (t < 64) { *runs++ = run; @@ -157,7 +157,7 @@ static int decode_group3_1d_line(AVCodecContext *avctx, GetBitContext *gb, return 0; } -static int decode_group3_2d_line(AVCodecContext *avctx, GetBitContext *gb, +static int decode_group3_2d_line(AVCodecContext *avctx, BitstreamContext *bc, unsigned int width, int *runs, const int *runend, const int *ref) { @@ -168,7 +168,7 @@ static int decode_group3_2d_line(AVCodecContext *avctx, GetBitContext *gb, runend--; // for the last written 0 while (offs < width) { - int cmode = get_vlc2(gb, ccitt_group3_2d_vlc.table, 9, 1); + int cmode = bitstream_read_vlc(bc, ccitt_group3_2d_vlc.table, 9, 1); if (cmode == -1) { av_log(avctx, AV_LOG_ERROR, "Incorrect mode VLC\n"); return AVERROR_INVALIDDATA; @@ -188,7 +188,7 @@ static int decode_group3_2d_line(AVCodecContext *avctx, GetBitContext *gb, for (k = 0; k < 2; k++) { run = 0; for (;;) { - t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2); + t = bitstream_read_vlc(bc, ccitt_vlc[mode].table, 9, 2); if (t == -1) { av_log(avctx, AV_LOG_ERROR, "Incorrect code\n"); return AVERROR_INVALIDDATA; @@ -258,12 +258,12 @@ static void put_line(uint8_t *dst, int size, int width, const int *runs) flush_put_bits(&pb); } -static int find_group3_syncmarker(GetBitContext *gb, int srcsize) +static int find_group3_syncmarker(BitstreamContext *bc, int srcsize) { unsigned int state = -1; - srcsize -= get_bits_count(gb); + srcsize -= bitstream_tell(bc); while (srcsize-- > 0) { - state += state + get_bits1(gb); + state += state + bitstream_read_bit(bc); if ((state & 0xFFF) == 1) return 0; } @@ -275,7 +275,7 @@ int ff_ccitt_unpack(AVCodecContext *avctx, const uint8_t *src, int srcsize, enum TiffCompr compr, int opts) { int j; - GetBitContext gb; + BitstreamContext bc; int *runs, *ref = NULL, *runend; int ret; int runsize = avctx->width + 2; @@ -289,27 +289,27 @@ int ff_ccitt_unpack(AVCodecContext *avctx, const uint8_t *src, int srcsize, ref[0] = avctx->width; ref[1] = 0; ref[2] = 0; - init_get_bits(&gb, src, srcsize * 8); + bitstream_init(&bc, src, srcsize * 8); for (j = 0; j < height; j++) { runend = runs + runsize; if (compr == TIFF_G4) { - ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend, + ret = decode_group3_2d_line(avctx, &bc, avctx->width, runs, runend, ref); if (ret < 0) goto fail; } else { int g3d1 = (compr == TIFF_G3) && !(opts & 1); if (compr != TIFF_CCITT_RLE && - find_group3_syncmarker(&gb, srcsize * 8) < 0) + find_group3_syncmarker(&bc, srcsize * 8) < 0) break; - if (compr == TIFF_CCITT_RLE || g3d1 || get_bits1(&gb)) - ret = decode_group3_1d_line(avctx, &gb, avctx->width, runs, + if (compr == TIFF_CCITT_RLE || g3d1 || bitstream_read_bit(&bc)) + ret = decode_group3_1d_line(avctx, &bc, avctx->width, runs, runend); else - ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, + ret = decode_group3_2d_line(avctx, &bc, avctx->width, runs, runend, ref); if (compr == TIFF_CCITT_RLE) - align_get_bits(&gb); + bitstream_align(&bc); } if (avctx->err_recognition & AV_EF_EXPLODE && ret < 0) goto fail; From 692ba4fe6445581cee4d414ee29538f1dce7fd8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sun, 10 Apr 2016 11:08:09 +0200 Subject: [PATCH 0519/3374] flashsv: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/flashsv.c | 57 ++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/libavcodec/flashsv.c b/libavcodec/flashsv.c index 2cf8f3f5841fe..20fa7bc1aff3d 100644 --- a/libavcodec/flashsv.c +++ b/libavcodec/flashsv.c @@ -38,9 +38,10 @@ #include #include "libavutil/intreadwrite.h" + #include "avcodec.h" +#include "bitstream.h" #include "bytestream.h" -#include "get_bits.h" #include "internal.h" typedef struct BlockInfo { @@ -175,7 +176,7 @@ static int flashsv2_prime(FlashSVContext *s, uint8_t *src, int size) } static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt, - GetBitContext *gb, int block_size, + BitstreamContext *bc, int block_size, int width, int height, int x_pos, int y_pos, int blk_idx) { @@ -194,7 +195,7 @@ static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt, if (ret < 0) return ret; } - s->zstream.next_in = avpkt->data + get_bits_count(gb) / 8; + s->zstream.next_in = avpkt->data + bitstream_tell(bc) / 8; s->zstream.avail_in = block_size; s->zstream.next_out = s->tmpblock; s->zstream.avail_out = s->block_size * 3; @@ -210,7 +211,7 @@ static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt, } if (s->is_keyframe) { - s->blocks[blk_idx].pos = s->keyframedata + (get_bits_count(gb) / 8); + s->blocks[blk_idx].pos = s->keyframedata + (bitstream_tell(bc) / 8); s->blocks[blk_idx].size = block_size; } @@ -233,7 +234,7 @@ static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt, x_pos, s->diff_height, width, s->frame->linesize[0], s->pal); } - skip_bits_long(gb, 8 * block_size); /* skip the consumed bits */ + bitstream_skip(bc, 8 * block_size); /* skip the consumed bits */ return 0; } @@ -259,7 +260,7 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, int buf_size = avpkt->size; FlashSVContext *s = avctx->priv_data; int h_blocks, v_blocks, h_part, v_part, i, j, ret; - GetBitContext gb; + BitstreamContext bc; /* no supplementary picture */ if (buf_size == 0) @@ -267,21 +268,21 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, if (buf_size < 4) return -1; - init_get_bits(&gb, avpkt->data, buf_size * 8); + bitstream_init(&bc, avpkt->data, buf_size * 8); /* start to parse the bitstream */ - s->block_width = 16 * (get_bits(&gb, 4) + 1); - s->image_width = get_bits(&gb, 12); - s->block_height = 16 * (get_bits(&gb, 4) + 1); - s->image_height = get_bits(&gb, 12); + s->block_width = 16 * (bitstream_read(&bc, 4) + 1); + s->image_width = bitstream_read(&bc, 12); + s->block_height = 16 * (bitstream_read(&bc, 4) + 1); + s->image_height = bitstream_read(&bc, 12); if (s->ver == 2) { - skip_bits(&gb, 6); - if (get_bits1(&gb)) { + bitstream_skip(&bc, 6); + if (bitstream_read_bit(&bc)) { avpriv_request_sample(avctx, "iframe"); return AVERROR_PATCHWELCOME; } - if (get_bits1(&gb)) { + if (bitstream_read_bit(&bc)) { avpriv_request_sample(avctx, "Custom palette"); return AVERROR_PATCHWELCOME; } @@ -371,7 +372,7 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, int has_diff = 0; /* get the size of the compressed zlib chunk */ - int size = get_bits(&gb, 16); + int size = bitstream_read(&bc, 16); s->color_depth = 0; s->zlibprime_curr = 0; @@ -379,17 +380,17 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, s->diff_start = 0; s->diff_height = cur_blk_height; - if (8 * size > get_bits_left(&gb)) { + if (8 * size > bitstream_bits_left(&bc)) { av_frame_unref(s->frame); return AVERROR_INVALIDDATA; } if (s->ver == 2 && size) { - skip_bits(&gb, 3); - s->color_depth = get_bits(&gb, 2); - has_diff = get_bits1(&gb); - s->zlibprime_curr = get_bits1(&gb); - s->zlibprime_prev = get_bits1(&gb); + bitstream_skip(&bc, 3); + s->color_depth = bitstream_read(&bc, 2); + has_diff = bitstream_read_bit(&bc); + s->zlibprime_curr = bitstream_read_bit(&bc); + s->zlibprime_prev = bitstream_read_bit(&bc); if (s->color_depth != 0 && s->color_depth != 2) { av_log(avctx, AV_LOG_ERROR, @@ -404,8 +405,8 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, "Inter frame without keyframe\n"); return AVERROR_INVALIDDATA; } - s->diff_start = get_bits(&gb, 8); - s->diff_height = get_bits(&gb, 8); + s->diff_start = bitstream_read(&bc, 8); + s->diff_height = bitstream_read(&bc, 8); if (s->diff_start + s->diff_height > cur_blk_height) { av_log(avctx, AV_LOG_ERROR, "Block parameters invalid: %d + %d > %d\n", @@ -422,8 +423,8 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_prev\n", i, j); if (s->zlibprime_curr) { - int col = get_bits(&gb, 8); - int row = get_bits(&gb, 8); + int col = bitstream_read(&bc, 8); + int row = bitstream_read(&bc, 8); av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_curr %dx%d\n", i, j, col, row); size -= 2; @@ -451,7 +452,7 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, /* skip unchanged blocks, which have size 0 */ if (size) { - if (flashsv_decode_block(avctx, avpkt, &gb, size, + if (flashsv_decode_block(avctx, avpkt, &bc, size, cur_blk_width, cur_blk_height, x_pos, y_pos, i + j * (h_blocks + !!h_part))) @@ -477,9 +478,9 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, *got_frame = 1; - if ((get_bits_count(&gb) / 8) != buf_size) + if ((bitstream_tell(&bc) / 8) != buf_size) av_log(avctx, AV_LOG_ERROR, "buffer not fully consumed (%d != %d)\n", - buf_size, (get_bits_count(&gb) / 8)); + buf_size, (bitstream_tell(&bc) / 8)); /* report that the buffer was completely consumed */ return buf_size; From b37b681f7734533dd6dc2ede8aa9d5c2607e0c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sun, 10 Apr 2016 11:12:27 +0200 Subject: [PATCH 0520/3374] fraps: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/fraps.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c index 55051ffe7e162..22379911330e1 100644 --- a/libavcodec/fraps.c +++ b/libavcodec/fraps.c @@ -32,7 +32,7 @@ */ #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "huffman.h" #include "bytestream.h" #include "bswapdsp.h" @@ -94,7 +94,7 @@ static int fraps2_decode_plane(FrapsContext *s, uint8_t *dst, int stride, int w, const int step) { int i, j, ret; - GetBitContext gb; + BitstreamContext bc; VLC vlc; Node nodes[512]; @@ -111,10 +111,10 @@ static int fraps2_decode_plane(FrapsContext *s, uint8_t *dst, int stride, int w, s->bdsp.bswap_buf((uint32_t *) s->tmpbuf, (const uint32_t *) src, size >> 2); - init_get_bits(&gb, s->tmpbuf, size * 8); + bitstream_init(&bc, s->tmpbuf, size * 8); for (j = 0; j < h; j++) { for (i = 0; i < w*step; i += step) { - dst[i] = get_vlc2(&gb, vlc.table, VLC_BITS, 3); + dst[i] = bitstream_read_vlc(&bc, vlc.table, VLC_BITS, 3); /* lines are stored as deltas between previous lines * and we need to add 0x80 to the first lines of chroma planes */ @@ -122,7 +122,7 @@ static int fraps2_decode_plane(FrapsContext *s, uint8_t *dst, int stride, int w, dst[i] += dst[i - stride]; else if (Uoff) dst[i] += 0x80; - if (get_bits_left(&gb) < 0) { + if (bitstream_bits_left(&bc) < 0) { ff_free_vlc(&vlc); return AVERROR_INVALIDDATA; } From 799703c3ea3d20c2bdf0f7d8b5015bd3069b2801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sun, 10 Apr 2016 11:16:15 +0200 Subject: [PATCH 0521/3374] g2meet: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/g2meet.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/libavcodec/g2meet.c b/libavcodec/g2meet.c index 7e90916274dd9..4a7f5a3666988 100644 --- a/libavcodec/g2meet.c +++ b/libavcodec/g2meet.c @@ -31,10 +31,10 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "bitstream.h" #include "blockdsp.h" #include "bytestream.h" #include "elsdec.h" -#include "get_bits.h" #include "idctdsp.h" #include "internal.h" #include "jpegtables.h" @@ -236,7 +236,7 @@ static void jpg_unescape(const uint8_t *src, int src_size, *dst_size = dst - dst_start; } -static int jpg_decode_block(JPGContext *c, GetBitContext *gb, +static int jpg_decode_block(JPGContext *c, BitstreamContext *bc, int plane, int16_t *block) { int dc, val, pos; @@ -244,18 +244,18 @@ static int jpg_decode_block(JPGContext *c, GetBitContext *gb, const uint8_t *qmat = is_chroma ? chroma_quant : luma_quant; c->bdsp.clear_block(block); - dc = get_vlc2(gb, c->dc_vlc[is_chroma].table, 9, 3); + dc = bitstream_read_vlc(bc, c->dc_vlc[is_chroma].table, 9, 3); if (dc < 0) return AVERROR_INVALIDDATA; if (dc) - dc = get_xbits(gb, dc); + dc = bitstream_read_xbits(bc, dc); dc = dc * qmat[0] + c->prev_dc[plane]; block[0] = dc; c->prev_dc[plane] = dc; pos = 0; while (pos < 63) { - val = get_vlc2(gb, c->ac_vlc[is_chroma].table, 9, 3); + val = bitstream_read_vlc(bc, c->ac_vlc[is_chroma].table, 9, 3); if (val < 0) return AVERROR_INVALIDDATA; pos += val >> 4; @@ -265,7 +265,7 @@ static int jpg_decode_block(JPGContext *c, GetBitContext *gb, if (val) { int nbits = val; - val = get_xbits(gb, nbits); + val = bitstream_read_xbits(bc, nbits); val *= qmat[ff_zigzag_direct[pos]]; block[c->scantable.permutated[pos]] = val; } @@ -286,7 +286,7 @@ static int jpg_decode_data(JPGContext *c, int width, int height, const uint8_t *mask, int mask_stride, int num_mbs, int swapuv) { - GetBitContext gb; + BitstreamContext bc; int mb_w, mb_h, mb_x, mb_y, i, j; int bx, by; int unesc_size; @@ -298,7 +298,7 @@ static int jpg_decode_data(JPGContext *c, int width, int height, return ret; jpg_unescape(src, src_size, c->buf, &unesc_size); memset(c->buf + unesc_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); - init_get_bits(&gb, c->buf, unesc_size * 8); + bitstream_init(&bc, c->buf, unesc_size * 8); width = FFALIGN(width, 16); mb_w = width >> 4; @@ -325,14 +325,14 @@ static int jpg_decode_data(JPGContext *c, int width, int height, if (mask && !mask[mb_x * 2 + i + j * mask_stride]) continue; num_mbs--; - if ((ret = jpg_decode_block(c, &gb, 0, + if ((ret = jpg_decode_block(c, &bc, 0, c->block[i + j * 2])) != 0) return ret; c->idsp.idct(c->block[i + j * 2]); } } for (i = 1; i < 3; i++) { - if ((ret = jpg_decode_block(c, &gb, i, c->block[i + 3])) != 0) + if ((ret = jpg_decode_block(c, &bc, i, c->block[i + 3])) != 0) return ret; c->idsp.idct(c->block[i + 3]); } @@ -1011,11 +1011,11 @@ static void kempf_restore_buf(const uint8_t *src, int len, int width, int height, const uint8_t *pal, int npal, int tidx) { - GetBitContext gb; + BitstreamContext bc; int i, j, nb, col; int align_width = FFALIGN(width, 16); - init_get_bits(&gb, src, len * 8); + bitstream_init(&bc, src, len * 8); if (npal <= 2) nb = 1; else if (npal <= 4) nb = 2; @@ -1023,16 +1023,16 @@ static void kempf_restore_buf(const uint8_t *src, int len, else nb = 8; for (j = 0; j < height; j++, dst += stride, jpeg_tile += tile_stride) { - if (get_bits(&gb, 8)) + if (bitstream_read(&bc, 8)) continue; for (i = 0; i < width; i++) { - col = get_bits(&gb, nb); + col = bitstream_read(&bc, nb); if (col != tidx) memcpy(dst + i * 3, pal + col * 3, 3); else memcpy(dst + i * 3, jpeg_tile + i * 3, 3); } - skip_bits_long(&gb, nb * (align_width - width)); + bitstream_skip(&bc, nb * (align_width - width)); } } From 2188d53906015ea5dd5b2e446f8e5374beacbffe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Mon, 18 Apr 2016 10:38:43 +0200 Subject: [PATCH 0522/3374] g72x: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/g722dec.c | 13 ++++---- libavcodec/g723_1dec.c | 72 +++++++++++++++++++++--------------------- libavcodec/g726.c | 11 ++++--- 3 files changed, 49 insertions(+), 47 deletions(-) diff --git a/libavcodec/g722dec.c b/libavcodec/g722dec.c index c4c0ec8feefe1..bfd4b420b2591 100644 --- a/libavcodec/g722dec.c +++ b/libavcodec/g722dec.c @@ -36,8 +36,9 @@ #include "libavutil/channel_layout.h" #include "libavutil/opt.h" + #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "g722.h" #include "internal.h" @@ -92,7 +93,7 @@ static int g722_decode_frame(AVCodecContext *avctx, void *data, int j, ret; const int skip = 8 - c->bits_per_codeword; const int16_t *quantizer_table = low_inv_quants[skip]; - GetBitContext gb; + BitstreamContext bc; /* get output buffer */ frame->nb_samples = avpkt->size * 2; @@ -102,15 +103,15 @@ static int g722_decode_frame(AVCodecContext *avctx, void *data, } out_buf = (int16_t *)frame->data[0]; - init_get_bits(&gb, avpkt->data, avpkt->size * 8); + bitstream_init(&bc, avpkt->data, avpkt->size * 8); for (j = 0; j < avpkt->size; j++) { int ilow, ihigh, rlow, rhigh, dhigh; int xout[2]; - ihigh = get_bits(&gb, 2); - ilow = get_bits(&gb, 6 - skip); - skip_bits(&gb, skip); + ihigh = bitstream_read(&bc, 2); + ilow = bitstream_read(&bc, 6 - skip); + bitstream_skip(&bc, skip); rlow = av_clip_intp2((c->band[0].scale_factor * quantizer_table[ilow] >> 10) + c->band[0].s_predictor, 14); diff --git a/libavcodec/g723_1dec.c b/libavcodec/g723_1dec.c index f50bed134e946..2ea3bbffa51c7 100644 --- a/libavcodec/g723_1dec.c +++ b/libavcodec/g723_1dec.c @@ -32,8 +32,8 @@ #define BITSTREAM_READER_LE #include "acelp_vectors.h" #include "avcodec.h" +#include "bitstream.h" #include "celp_filters.h" -#include "get_bits.h" #include "internal.h" #include "g723_1.h" @@ -68,14 +68,14 @@ static av_cold int g723_1_decode_init(AVCodecContext *avctx) static int unpack_bitstream(G723_1_Context *p, const uint8_t *buf, int buf_size) { - GetBitContext gb; + BitstreamContext bc; int ad_cb_len; int temp, info_bits, i; - init_get_bits(&gb, buf, buf_size * 8); + bitstream_init(&bc, buf, buf_size * 8); /* Extract frame type and rate info */ - info_bits = get_bits(&gb, 2); + info_bits = bitstream_read(&bc, 2); if (info_bits == 3) { p->cur_frame_type = UNTRANSMITTED_FRAME; @@ -83,13 +83,13 @@ static int unpack_bitstream(G723_1_Context *p, const uint8_t *buf, } /* Extract 24 bit lsp indices, 8 bit for each band */ - p->lsp_index[2] = get_bits(&gb, 8); - p->lsp_index[1] = get_bits(&gb, 8); - p->lsp_index[0] = get_bits(&gb, 8); + p->lsp_index[2] = bitstream_read(&bc, 8); + p->lsp_index[1] = bitstream_read(&bc, 8); + p->lsp_index[0] = bitstream_read(&bc, 8); if (info_bits == 2) { p->cur_frame_type = SID_FRAME; - p->subframe[0].amp_index = get_bits(&gb, 6); + p->subframe[0].amp_index = bitstream_read(&bc, 6); return 0; } @@ -97,23 +97,23 @@ static int unpack_bitstream(G723_1_Context *p, const uint8_t *buf, p->cur_rate = info_bits ? RATE_5300 : RATE_6300; p->cur_frame_type = ACTIVE_FRAME; - p->pitch_lag[0] = get_bits(&gb, 7); + p->pitch_lag[0] = bitstream_read(&bc, 7); if (p->pitch_lag[0] > 123) /* test if forbidden code */ return -1; p->pitch_lag[0] += PITCH_MIN; - p->subframe[1].ad_cb_lag = get_bits(&gb, 2); + p->subframe[1].ad_cb_lag = bitstream_read(&bc, 2); - p->pitch_lag[1] = get_bits(&gb, 7); + p->pitch_lag[1] = bitstream_read(&bc, 7); if (p->pitch_lag[1] > 123) return -1; p->pitch_lag[1] += PITCH_MIN; - p->subframe[3].ad_cb_lag = get_bits(&gb, 2); + p->subframe[3].ad_cb_lag = bitstream_read(&bc, 2); p->subframe[0].ad_cb_lag = 1; p->subframe[2].ad_cb_lag = 1; for (i = 0; i < SUBFRAMES; i++) { /* Extract combined gain */ - temp = get_bits(&gb, 12); + temp = bitstream_read(&bc, 12); ad_cb_len = 170; p->subframe[i].dirac_train = 0; if (p->cur_rate == RATE_6300 && p->pitch_lag[i >> 1] < SUBFRAME_LEN - 2) { @@ -130,16 +130,16 @@ static int unpack_bitstream(G723_1_Context *p, const uint8_t *buf, } } - p->subframe[0].grid_index = get_bits(&gb, 1); - p->subframe[1].grid_index = get_bits(&gb, 1); - p->subframe[2].grid_index = get_bits(&gb, 1); - p->subframe[3].grid_index = get_bits(&gb, 1); + p->subframe[0].grid_index = bitstream_read(&bc, 1); + p->subframe[1].grid_index = bitstream_read(&bc, 1); + p->subframe[2].grid_index = bitstream_read(&bc, 1); + p->subframe[3].grid_index = bitstream_read(&bc, 1); if (p->cur_rate == RATE_6300) { - skip_bits(&gb, 1); /* skip reserved bit */ + bitstream_skip(&bc, 1); /* skip reserved bit */ /* Compute pulse_pos index using the 13-bit combined position index */ - temp = get_bits(&gb, 13); + temp = bitstream_read(&bc, 13); p->subframe[0].pulse_pos = temp / 810; temp -= p->subframe[0].pulse_pos * 810; @@ -150,28 +150,28 @@ static int unpack_bitstream(G723_1_Context *p, const uint8_t *buf, p->subframe[3].pulse_pos = temp - p->subframe[2].pulse_pos * 9; p->subframe[0].pulse_pos = (p->subframe[0].pulse_pos << 16) + - get_bits(&gb, 16); + bitstream_read(&bc, 16); p->subframe[1].pulse_pos = (p->subframe[1].pulse_pos << 14) + - get_bits(&gb, 14); + bitstream_read(&bc, 14); p->subframe[2].pulse_pos = (p->subframe[2].pulse_pos << 16) + - get_bits(&gb, 16); + bitstream_read(&bc, 16); p->subframe[3].pulse_pos = (p->subframe[3].pulse_pos << 14) + - get_bits(&gb, 14); + bitstream_read(&bc, 14); - p->subframe[0].pulse_sign = get_bits(&gb, 6); - p->subframe[1].pulse_sign = get_bits(&gb, 5); - p->subframe[2].pulse_sign = get_bits(&gb, 6); - p->subframe[3].pulse_sign = get_bits(&gb, 5); + p->subframe[0].pulse_sign = bitstream_read(&bc, 6); + p->subframe[1].pulse_sign = bitstream_read(&bc, 5); + p->subframe[2].pulse_sign = bitstream_read(&bc, 6); + p->subframe[3].pulse_sign = bitstream_read(&bc, 5); } else { /* 5300 bps */ - p->subframe[0].pulse_pos = get_bits(&gb, 12); - p->subframe[1].pulse_pos = get_bits(&gb, 12); - p->subframe[2].pulse_pos = get_bits(&gb, 12); - p->subframe[3].pulse_pos = get_bits(&gb, 12); - - p->subframe[0].pulse_sign = get_bits(&gb, 4); - p->subframe[1].pulse_sign = get_bits(&gb, 4); - p->subframe[2].pulse_sign = get_bits(&gb, 4); - p->subframe[3].pulse_sign = get_bits(&gb, 4); + p->subframe[0].pulse_pos = bitstream_read(&bc, 12); + p->subframe[1].pulse_pos = bitstream_read(&bc, 12); + p->subframe[2].pulse_pos = bitstream_read(&bc, 12); + p->subframe[3].pulse_pos = bitstream_read(&bc, 12); + + p->subframe[0].pulse_sign = bitstream_read(&bc, 4); + p->subframe[1].pulse_sign = bitstream_read(&bc, 4); + p->subframe[2].pulse_sign = bitstream_read(&bc, 4); + p->subframe[3].pulse_sign = bitstream_read(&bc, 4); } return 0; diff --git a/libavcodec/g726.c b/libavcodec/g726.c index e783e74c90dbd..007cdb63ccdea 100644 --- a/libavcodec/g726.c +++ b/libavcodec/g726.c @@ -25,9 +25,10 @@ #include "libavutil/channel_layout.h" #include "libavutil/opt.h" + #include "avcodec.h" +#include "bitstream.h" #include "internal.h" -#include "get_bits.h" #include "put_bits.h" /** @@ -429,7 +430,7 @@ static int g726_decode_frame(AVCodecContext *avctx, void *data, int buf_size = avpkt->size; G726Context *c = avctx->priv_data; int16_t *samples; - GetBitContext gb; + BitstreamContext bc; int out_samples, ret; out_samples = buf_size * 8 / c->code_size; @@ -442,12 +443,12 @@ static int g726_decode_frame(AVCodecContext *avctx, void *data, } samples = (int16_t *)frame->data[0]; - init_get_bits(&gb, buf, buf_size * 8); + bitstream_init(&bc, buf, buf_size * 8); while (out_samples--) - *samples++ = g726_decode(c, get_bits(&gb, c->code_size)); + *samples++ = g726_decode(c, bitstream_read(&bc, c->code_size)); - if (get_bits_left(&gb) > 0) + if (bitstream_bits_left(&bc) > 0) av_log(avctx, AV_LOG_ERROR, "Frame invalidly split, missing parser?\n"); *got_frame_ptr = 1; From b2c56301f9458207cfd16c66dc2f3ce15a336651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sun, 10 Apr 2016 11:34:09 +0200 Subject: [PATCH 0523/3374] gsm: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/gsmdec.c | 11 ++++++----- libavcodec/gsmdec_template.c | 34 +++++++++++++++++----------------- libavcodec/msgsmdec.c | 9 +++++---- 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/libavcodec/gsmdec.c b/libavcodec/gsmdec.c index a333e58bdc282..d727cf9ccf364 100644 --- a/libavcodec/gsmdec.c +++ b/libavcodec/gsmdec.c @@ -25,8 +25,9 @@ */ #include "libavutil/channel_layout.h" + #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "internal.h" #include "msgsmdec.h" @@ -67,7 +68,7 @@ static int gsm_decode_frame(AVCodecContext *avctx, void *data, { AVFrame *frame = data; int res; - GetBitContext gb; + BitstreamContext bc; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; int16_t *samples; @@ -87,10 +88,10 @@ static int gsm_decode_frame(AVCodecContext *avctx, void *data, switch (avctx->codec_id) { case AV_CODEC_ID_GSM: - init_get_bits(&gb, buf, buf_size * 8); - if (get_bits(&gb, 4) != 0xd) + bitstream_init(&bc, buf, buf_size * 8); + if (bitstream_read(&bc, 4) != 0xd) av_log(avctx, AV_LOG_WARNING, "Missing GSM magic!\n"); - res = gsm_decode_block(avctx, samples, &gb, GSM_13000); + res = gsm_decode_block(avctx, samples, &bc, GSM_13000); if (res < 0) return res; break; diff --git a/libavcodec/gsmdec_template.c b/libavcodec/gsmdec_template.c index 2794bd1132b9b..7437908ae5fe6 100644 --- a/libavcodec/gsmdec_template.c +++ b/libavcodec/gsmdec_template.c @@ -24,17 +24,17 @@ * GSM decoder */ -#include "get_bits.h" +#include "bitstream.h" #include "gsm.h" #include "gsmdec_data.h" -static void apcm_dequant_add(GetBitContext *gb, int16_t *dst, const int *frame_bits) +static void apcm_dequant_add(BitstreamContext *bc, int16_t *dst, const int *frame_bits) { int i, val; - int maxidx = get_bits(gb, 6); + int maxidx = bitstream_read(bc, 6); const int16_t *tab = ff_gsm_dequant_tab[maxidx]; for (i = 0; i < 13; i++) { - val = get_bits(gb, frame_bits[i]); + val = bitstream_read(bc, frame_bits[i]); dst[3 * i] += tab[ff_gsm_requant_tab[frame_bits[i]][val]]; } } @@ -120,28 +120,28 @@ static int postprocess(int16_t *data, int msr) } static int gsm_decode_block(AVCodecContext *avctx, int16_t *samples, - GetBitContext *gb, int mode) + BitstreamContext *bc, int mode) { GSMContext *ctx = avctx->priv_data; int i; int16_t *ref_dst = ctx->ref_buf + 120; int *lar = ctx->lar[ctx->lar_idx]; - lar[0] = decode_log_area(get_bits(gb, 6), 13107, 1 << 15); - lar[1] = decode_log_area(get_bits(gb, 6), 13107, 1 << 15); - lar[2] = decode_log_area(get_bits(gb, 5), 13107, (1 << 14) + 2048*2); - lar[3] = decode_log_area(get_bits(gb, 5), 13107, (1 << 14) - 2560*2); - lar[4] = decode_log_area(get_bits(gb, 4), 19223, (1 << 13) + 94*2); - lar[5] = decode_log_area(get_bits(gb, 4), 17476, (1 << 13) - 1792*2); - lar[6] = decode_log_area(get_bits(gb, 3), 31454, (1 << 12) - 341*2); - lar[7] = decode_log_area(get_bits(gb, 3), 29708, (1 << 12) - 1144*2); + lar[0] = decode_log_area(bitstream_read(bc, 6), 13107, 1 << 15); + lar[1] = decode_log_area(bitstream_read(bc, 6), 13107, 1 << 15); + lar[2] = decode_log_area(bitstream_read(bc, 5), 13107, (1 << 14) + 2048 * 2); + lar[3] = decode_log_area(bitstream_read(bc, 5), 13107, (1 << 14) - 2560 * 2); + lar[4] = decode_log_area(bitstream_read(bc, 4), 19223, (1 << 13) + 94 * 2); + lar[5] = decode_log_area(bitstream_read(bc, 4), 17476, (1 << 13) - 1792 * 2); + lar[6] = decode_log_area(bitstream_read(bc, 3), 31454, (1 << 12) - 341 * 2); + lar[7] = decode_log_area(bitstream_read(bc, 3), 29708, (1 << 12) - 1144 * 2); for (i = 0; i < 4; i++) { - int lag = get_bits(gb, 7); - int gain_idx = get_bits(gb, 2); - int offset = get_bits(gb, 2); + int lag = bitstream_read(bc, 7); + int gain_idx = bitstream_read(bc, 2); + int offset = bitstream_read(bc, 2); lag = av_clip(lag, 40, 120); long_term_synth(ref_dst, lag, gain_idx); - apcm_dequant_add(gb, ref_dst + offset, ff_gsm_apcm_bits[mode][i]); + apcm_dequant_add(bc, ref_dst + offset, ff_gsm_apcm_bits[mode][i]); ref_dst += 40; } memcpy(ctx->ref_buf, ctx->ref_buf + 160, 120 * sizeof(*ctx->ref_buf)); diff --git a/libavcodec/msgsmdec.c b/libavcodec/msgsmdec.c index 92b5ae6be86a5..c26efa9fae04a 100644 --- a/libavcodec/msgsmdec.c +++ b/libavcodec/msgsmdec.c @@ -21,6 +21,7 @@ #define BITSTREAM_READER_LE #include "avcodec.h" +#include "bitstream.h" #include "gsm.h" #include "msgsmdec.h" @@ -30,10 +31,10 @@ int ff_msgsm_decode_block(AVCodecContext *avctx, int16_t *samples, const uint8_t *buf, int mode) { int res; - GetBitContext gb; - init_get_bits(&gb, buf, GSM_MS_BLOCK_SIZE * 8); - res = gsm_decode_block(avctx, samples, &gb, mode); + BitstreamContext bc; + bitstream_init(&bc, buf, GSM_MS_BLOCK_SIZE * 8); + res = gsm_decode_block(avctx, samples, &bc, mode); if (res < 0) return res; - return gsm_decode_block(avctx, samples + GSM_FRAME_SIZE, &gb, mode); + return gsm_decode_block(avctx, samples + GSM_FRAME_SIZE, &bc, mode); } From c5e01d91702b082ac1b5c2101f1d84dd5017e4ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sun, 10 Apr 2016 12:00:56 +0200 Subject: [PATCH 0524/3374] hq_hqa: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/hq_hqa.c | 48 ++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/libavcodec/hq_hqa.c b/libavcodec/hq_hqa.c index 98bd596439a0c..0d03e593f39e6 100644 --- a/libavcodec/hq_hqa.c +++ b/libavcodec/hq_hqa.c @@ -24,8 +24,8 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "bitstream.h" #include "canopus.h" -#include "get_bits.h" #include "internal.h" #include "hq_hqa.h" @@ -59,7 +59,7 @@ static inline void put_blocks(HQContext *c, AVFrame *pic, pic->linesize[plane] << ilace, block1); } -static int hq_decode_block(HQContext *c, GetBitContext *gb, int16_t block[64], +static int hq_decode_block(HQContext *c, BitstreamContext *bc, int16_t block[64], int qsel, int is_chroma, int is_hqa) { const int32_t *q; @@ -68,15 +68,15 @@ static int hq_decode_block(HQContext *c, GetBitContext *gb, int16_t block[64], memset(block, 0, 64 * sizeof(*block)); if (!is_hqa) { - block[0] = get_sbits(gb, 9) << 6; - q = ff_hq_quants[qsel][is_chroma][get_bits(gb, 2)]; + block[0] = bitstream_read_signed(bc, 9) << 6; + q = ff_hq_quants[qsel][is_chroma][bitstream_read(bc, 2)]; } else { - q = ff_hq_quants[qsel][is_chroma][get_bits(gb, 2)]; - block[0] = get_sbits(gb, 9) << 6; + q = ff_hq_quants[qsel][is_chroma][bitstream_read(bc, 2)]; + block[0] = bitstream_read_signed(bc, 9) << 6; } for (;;) { - val = get_vlc2(gb, c->hq_ac_vlc.table, 9, 2); + val = bitstream_read_vlc(bc, c->hq_ac_vlc.table, 9, 2); if (val < 0) return AVERROR_INVALIDDATA; @@ -91,16 +91,16 @@ static int hq_decode_block(HQContext *c, GetBitContext *gb, int16_t block[64], } static int hq_decode_mb(HQContext *c, AVFrame *pic, - GetBitContext *gb, int x, int y) + BitstreamContext *bc, int x, int y) { int qgroup, flag; int i, ret; - qgroup = get_bits(gb, 4); - flag = get_bits1(gb); + qgroup = bitstream_read(bc, 4); + flag = bitstream_read_bit(bc); for (i = 0; i < 8; i++) { - ret = hq_decode_block(c, gb, c->block[i], qgroup, i >= 4, 0); + ret = hq_decode_block(c, bc, c->block[i], qgroup, i >= 4, 0); if (ret < 0) return ret; } @@ -117,7 +117,7 @@ static int hq_decode_frame(HQContext *ctx, AVFrame *pic, int prof_num, size_t data_size) { const HQProfile *profile; - GetBitContext gb; + BitstreamContext bc; const uint8_t *perm, *src = ctx->gbc.buffer; uint32_t slice_off[21]; int slice, start_off, next_off, i, ret; @@ -160,11 +160,11 @@ static int hq_decode_frame(HQContext *ctx, AVFrame *pic, "Invalid slice size %zu.\n", data_size); break; } - init_get_bits(&gb, src + slice_off[slice], - (slice_off[slice + 1] - slice_off[slice]) * 8); + bitstream_init(&bc, src + slice_off[slice], + (slice_off[slice + 1] - slice_off[slice]) * 8); for (i = 0; i < (next_off - start_off) * profile->tab_w; i++) { - ret = hq_decode_mb(ctx, pic, &gb, perm[0] * 16, perm[1] * 16); + ret = hq_decode_mb(ctx, pic, &bc, perm[0] * 16, perm[1] * 16); if (ret < 0) { av_log(ctx->avctx, AV_LOG_ERROR, "Error decoding macroblock %d at slice %d.\n", i, slice); @@ -178,12 +178,12 @@ static int hq_decode_frame(HQContext *ctx, AVFrame *pic, } static int hqa_decode_mb(HQContext *c, AVFrame *pic, int qgroup, - GetBitContext *gb, int x, int y) + BitstreamContext *bc, int x, int y) { int flag = 0; int i, ret, cbp; - cbp = get_vlc2(gb, c->hqa_cbp_vlc.table, 5, 1); + cbp = bitstream_read_vlc(bc, c->hqa_cbp_vlc.table, 5, 1); for (i = 0; i < 12; i++) memset(c->block[i], 0, sizeof(*c->block)); @@ -191,7 +191,7 @@ static int hqa_decode_mb(HQContext *c, AVFrame *pic, int qgroup, c->block[i][0] = -128 * (1 << 6); if (cbp) { - flag = get_bits1(gb); + flag = bitstream_read_bit(bc); cbp |= cbp << 4; if (cbp & 0x3) @@ -201,7 +201,7 @@ static int hqa_decode_mb(HQContext *c, AVFrame *pic, int qgroup, for (i = 0; i < 12; i++) { if (!(cbp & (1 << i))) continue; - ret = hq_decode_block(c, gb, c->block[i], qgroup, i >= 8, 1); + ret = hq_decode_block(c, bc, c->block[i], qgroup, i >= 8, 1); if (ret < 0) return ret; } @@ -217,7 +217,7 @@ static int hqa_decode_mb(HQContext *c, AVFrame *pic, int qgroup, return 0; } -static int hqa_decode_slice(HQContext *ctx, AVFrame *pic, GetBitContext *gb, +static int hqa_decode_slice(HQContext *ctx, AVFrame *pic, BitstreamContext *bc, int quant, int slice_no, int w, int h) { int i, j, off; @@ -226,7 +226,7 @@ static int hqa_decode_slice(HQContext *ctx, AVFrame *pic, GetBitContext *gb, for (i = 0; i < h; i += 16) { off = (slice_no * 16 + i * 3) & 0x70; for (j = off; j < w; j += 128) { - ret = hqa_decode_mb(ctx, pic, quant, gb, j, i); + ret = hqa_decode_mb(ctx, pic, quant, bc, j, i); if (ret < 0) { av_log(ctx->avctx, AV_LOG_ERROR, "Error decoding macroblock at %dx%d.\n", i, j); @@ -240,7 +240,7 @@ static int hqa_decode_slice(HQContext *ctx, AVFrame *pic, GetBitContext *gb, static int hqa_decode_frame(HQContext *ctx, AVFrame *pic, size_t data_size) { - GetBitContext gb; + BitstreamContext bc; const int num_slices = 8; uint32_t slice_off[9]; int i, slice, ret; @@ -285,10 +285,10 @@ static int hqa_decode_frame(HQContext *ctx, AVFrame *pic, size_t data_size) "Invalid slice size %zu.\n", data_size); break; } - init_get_bits(&gb, src + slice_off[slice], + bitstream_init(&bc, src + slice_off[slice], (slice_off[slice + 1] - slice_off[slice]) * 8); - ret = hqa_decode_slice(ctx, pic, &gb, quant, slice, width, height); + ret = hqa_decode_slice(ctx, pic, &bc, quant, slice, width, height); if (ret < 0) return ret; } From 1df549bfa2bacceb6f119f2aa1146c22ac841243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sun, 10 Apr 2016 12:09:58 +0200 Subject: [PATCH 0525/3374] hqx: Convert to the new bitstream header Signed-off-by: Anton Khirnov --- libavcodec/hqx.c | 64 ++++++++++++++++++++++++------------------------ libavcodec/hqx.h | 5 ++-- 2 files changed, 35 insertions(+), 34 deletions(-) diff --git a/libavcodec/hqx.c b/libavcodec/hqx.c index 7411d3f2523a7..3c359e3863aa6 100644 --- a/libavcodec/hqx.c +++ b/libavcodec/hqx.c @@ -24,8 +24,8 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "bitstream.h" #include "canopus.h" -#include "get_bits.h" #include "internal.h" #include "hqx.h" @@ -95,23 +95,23 @@ static inline void put_blocks(HQXContext *ctx, int plane, lsize * fields, block1, quant); } -static inline void hqx_get_ac(GetBitContext *gb, const HQXAC *ac, +static inline void hqx_get_ac(BitstreamContext *bc, const HQXAC *ac, int *run, int *lev) { int val; - val = show_bits(gb, ac->lut_bits); + val = bitstream_peek(bc, ac->lut_bits); if (ac->lut[val].bits == -1) { - GetBitContext gb2 = *gb; - skip_bits(&gb2, ac->lut_bits); - val = ac->lut[val].lev + show_bits(&gb2, ac->extra_bits); + BitstreamContext bc2 = *bc; + bitstream_skip(&bc2, ac->lut_bits); + val = ac->lut[val].lev + bitstream_peek(&bc2, ac->extra_bits); } *run = ac->lut[val].run; *lev = ac->lut[val].lev; - skip_bits(gb, ac->lut[val].bits); + bitstream_skip(bc, ac->lut[val].bits); } -static int decode_block(GetBitContext *gb, VLC *vlc, +static int decode_block(BitstreamContext *bc, VLC *vlc, const int *quants, int dcb, int16_t block[64], int *last_dc) { @@ -120,14 +120,14 @@ static int decode_block(GetBitContext *gb, VLC *vlc, int run, lev, pos = 1; memset(block, 0, 64 * sizeof(*block)); - dc = get_vlc2(gb, vlc->table, HQX_DC_VLC_BITS, 2); + dc = bitstream_read_vlc(bc, vlc->table, HQX_DC_VLC_BITS, 2); if (dc < 0) return AVERROR_INVALIDDATA; *last_dc += dc; block[0] = sign_extend(*last_dc << (12 - dcb), 12); - q = quants[get_bits(gb, 2)]; + q = quants[bitstream_read(bc, 2)]; if (q >= 128) ac_idx = HQX_AC_Q128; else if (q >= 64) @@ -142,7 +142,7 @@ static int decode_block(GetBitContext *gb, VLC *vlc, ac_idx = HQX_AC_Q0; do { - hqx_get_ac(gb, &ff_hqx_ac[ac_idx], &run, &lev); + hqx_get_ac(bc, &ff_hqx_ac[ac_idx], &run, &lev); pos += run; if (pos >= 64) break; @@ -155,24 +155,24 @@ static int decode_block(GetBitContext *gb, VLC *vlc, static int hqx_decode_422(HQXContext *ctx, int slice_no, int x, int y) { HQXSlice *slice = &ctx->slice[slice_no]; - GetBitContext *gb = &slice->gb; + BitstreamContext *bc = &slice->bc; const int *quants; int flag; int last_dc; int i, ret; if (ctx->interlaced) - flag = get_bits1(gb); + flag = bitstream_read_bit(bc); else flag = 0; - quants = hqx_quants[get_bits(gb, 4)]; + quants = hqx_quants[bitstream_read(bc, 4)]; for (i = 0; i < 8; i++) { int vlc_index = ctx->dcb - 9; if (i == 0 || i == 4 || i == 6) last_dc = 0; - ret = decode_block(gb, &ctx->dc_vlc[vlc_index], quants, + ret = decode_block(bc, &ctx->dc_vlc[vlc_index], quants, ctx->dcb, slice->block[i], &last_dc); if (ret < 0) return ret; @@ -189,14 +189,14 @@ static int hqx_decode_422(HQXContext *ctx, int slice_no, int x, int y) static int hqx_decode_422a(HQXContext *ctx, int slice_no, int x, int y) { HQXSlice *slice = &ctx->slice[slice_no]; - GetBitContext *gb = &slice->gb; + BitstreamContext *bc = &slice->bc; const int *quants; int flag = 0; int last_dc; int i, ret; int cbp; - cbp = get_vlc2(gb, ctx->cbp_vlc.table, ctx->cbp_vlc.bits, 1); + cbp = bitstream_read_vlc(bc, ctx->cbp_vlc.table, ctx->cbp_vlc.bits, 1); for (i = 0; i < 12; i++) memset(slice->block[i], 0, sizeof(**slice->block) * 64); @@ -204,9 +204,9 @@ static int hqx_decode_422a(HQXContext *ctx, int slice_no, int x, int y) slice->block[i][0] = -0x800; if (cbp) { if (ctx->interlaced) - flag = get_bits1(gb); + flag = bitstream_read_bit(bc); - quants = hqx_quants[get_bits(gb, 4)]; + quants = hqx_quants[bitstream_read(bc, 4)]; cbp |= cbp << 4; // alpha CBP if (cbp & 0x3) // chroma CBP - top @@ -218,7 +218,7 @@ static int hqx_decode_422a(HQXContext *ctx, int slice_no, int x, int y) last_dc = 0; if (cbp & (1 << i)) { int vlc_index = ctx->dcb - 9; - ret = decode_block(gb, &ctx->dc_vlc[vlc_index], quants, + ret = decode_block(bc, &ctx->dc_vlc[vlc_index], quants, ctx->dcb, slice->block[i], &last_dc); if (ret < 0) return ret; @@ -239,24 +239,24 @@ static int hqx_decode_422a(HQXContext *ctx, int slice_no, int x, int y) static int hqx_decode_444(HQXContext *ctx, int slice_no, int x, int y) { HQXSlice *slice = &ctx->slice[slice_no]; - GetBitContext *gb = &slice->gb; + BitstreamContext *bc = &slice->bc; const int *quants; int flag; int last_dc; int i, ret; if (ctx->interlaced) - flag = get_bits1(gb); + flag = bitstream_read_bit(bc); else flag = 0; - quants = hqx_quants[get_bits(gb, 4)]; + quants = hqx_quants[bitstream_read(bc, 4)]; for (i = 0; i < 12; i++) { int vlc_index = ctx->dcb - 9; if (i == 0 || i == 4 || i == 8) last_dc = 0; - ret = decode_block(gb, &ctx->dc_vlc[vlc_index], quants, + ret = decode_block(bc, &ctx->dc_vlc[vlc_index], quants, ctx->dcb, slice->block[i], &last_dc); if (ret < 0) return ret; @@ -275,14 +275,14 @@ static int hqx_decode_444(HQXContext *ctx, int slice_no, int x, int y) static int hqx_decode_444a(HQXContext *ctx, int slice_no, int x, int y) { HQXSlice *slice = &ctx->slice[slice_no]; - GetBitContext *gb = &slice->gb; + BitstreamContext *bc = &slice->bc; const int *quants; int flag = 0; int last_dc; int i, ret; int cbp; - cbp = get_vlc2(gb, ctx->cbp_vlc.table, ctx->cbp_vlc.bits, 1); + cbp = bitstream_read_vlc(bc, ctx->cbp_vlc.table, ctx->cbp_vlc.bits, 1); for (i = 0; i < 16; i++) memset(slice->block[i], 0, sizeof(**slice->block) * 64); @@ -290,9 +290,9 @@ static int hqx_decode_444a(HQXContext *ctx, int slice_no, int x, int y) slice->block[i][0] = -0x800; if (cbp) { if (ctx->interlaced) - flag = get_bits1(gb); + flag = bitstream_read_bit(bc); - quants = hqx_quants[get_bits(gb, 4)]; + quants = hqx_quants[bitstream_read(bc, 4)]; cbp |= cbp << 4; // alpha CBP cbp |= cbp << 8; // chroma CBP @@ -301,7 +301,7 @@ static int hqx_decode_444a(HQXContext *ctx, int slice_no, int x, int y) last_dc = 0; if (cbp & (1 << i)) { int vlc_index = ctx->dcb - 9; - ret = decode_block(gb, &ctx->dc_vlc[vlc_index], quants, + ret = decode_block(bc, &ctx->dc_vlc[vlc_index], quants, ctx->dcb, slice->block[i], &last_dc); if (ret < 0) return ret; @@ -392,9 +392,9 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, return AVERROR_INVALIDDATA; } - ret = init_get_bits8(&ctx->slice[slice_no].gb, - ctx->src + slice_off[slice_no], - slice_off[slice_no + 1] - slice_off[slice_no]); + ret = bitstream_init8(&ctx->slice[slice_no].bc, + ctx->src + slice_off[slice_no], + slice_off[slice_no + 1] - slice_off[slice_no]); if (ret < 0) return ret; diff --git a/libavcodec/hqx.h b/libavcodec/hqx.h index 7f329712fde01..e8f7c627fb70a 100644 --- a/libavcodec/hqx.h +++ b/libavcodec/hqx.h @@ -25,7 +25,8 @@ #include "libavutil/frame.h" #include "libavutil/mem.h" -#include "get_bits.h" + +#include "bitstream.h" #include "hqxdsp.h" enum HQXACMode { @@ -55,7 +56,7 @@ typedef int (*mb_decode_func)(struct HQXContext *ctx, int slice_no, int x, int y); typedef struct HQXSlice { - GetBitContext gb; + BitstreamContext bc; DECLARE_ALIGNED(16, int16_t, block)[16][64]; } HQXSlice; From 15d4dbfd4ade51eb55737f33236f142f88206d1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Tue, 12 Apr 2016 17:24:55 +0200 Subject: [PATCH 0526/3374] jvdec: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/jvdec.c | 52 +++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/libavcodec/jvdec.c b/libavcodec/jvdec.c index c532b75a25985..37a2770063eeb 100644 --- a/libavcodec/jvdec.c +++ b/libavcodec/jvdec.c @@ -28,8 +28,8 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "bitstream.h" #include "blockdsp.h" -#include "get_bits.h" #include "internal.h" typedef struct JvContext { @@ -62,84 +62,84 @@ static av_cold int decode_init(AVCodecContext *avctx) /** * Decode 2x2 block */ -static inline void decode2x2(GetBitContext *gb, uint8_t *dst, int linesize) +static inline void decode2x2(BitstreamContext *bc, uint8_t *dst, int linesize) { int i, j, v[2]; - switch (get_bits(gb, 2)) { + switch (bitstream_read(bc, 2)) { case 1: - v[0] = get_bits(gb, 8); + v[0] = bitstream_read(bc, 8); for (j = 0; j < 2; j++) memset(dst + j * linesize, v[0], 2); break; case 2: - v[0] = get_bits(gb, 8); - v[1] = get_bits(gb, 8); + v[0] = bitstream_read(bc, 8); + v[1] = bitstream_read(bc, 8); for (j = 0; j < 2; j++) for (i = 0; i < 2; i++) - dst[j * linesize + i] = v[get_bits1(gb)]; + dst[j * linesize + i] = v[bitstream_read_bit(bc)]; break; case 3: for (j = 0; j < 2; j++) for (i = 0; i < 2; i++) - dst[j * linesize + i] = get_bits(gb, 8); + dst[j * linesize + i] = bitstream_read(bc, 8); } } /** * Decode 4x4 block */ -static inline void decode4x4(GetBitContext *gb, uint8_t *dst, int linesize) +static inline void decode4x4(BitstreamContext *bc, uint8_t *dst, int linesize) { int i, j, v[2]; - switch (get_bits(gb, 2)) { + switch (bitstream_read(bc, 2)) { case 1: - v[0] = get_bits(gb, 8); + v[0] = bitstream_read(bc, 8); for (j = 0; j < 4; j++) memset(dst + j * linesize, v[0], 4); break; case 2: - v[0] = get_bits(gb, 8); - v[1] = get_bits(gb, 8); + v[0] = bitstream_read(bc, 8); + v[1] = bitstream_read(bc, 8); for (j = 2; j >= 0; j -= 2) { for (i = 0; i < 4; i++) - dst[j * linesize + i] = v[get_bits1(gb)]; + dst[j * linesize + i] = v[bitstream_read_bit(bc)]; for (i = 0; i < 4; i++) - dst[(j + 1) * linesize + i] = v[get_bits1(gb)]; + dst[(j + 1) * linesize + i] = v[bitstream_read_bit(bc)]; } break; case 3: for (j = 0; j < 4; j += 2) for (i = 0; i < 4; i += 2) - decode2x2(gb, dst + j * linesize + i, linesize); + decode2x2(bc, dst + j * linesize + i, linesize); } } /** * Decode 8x8 block */ -static inline void decode8x8(GetBitContext *gb, uint8_t *dst, int linesize, +static inline void decode8x8(BitstreamContext *bc, uint8_t *dst, int linesize, BlockDSPContext *bdsp) { int i, j, v[2]; - switch (get_bits(gb, 2)) { + switch (bitstream_read(bc, 2)) { case 1: - v[0] = get_bits(gb, 8); + v[0] = bitstream_read(bc, 8); bdsp->fill_block_tab[1](dst, v[0], linesize, 8); break; case 2: - v[0] = get_bits(gb, 8); - v[1] = get_bits(gb, 8); + v[0] = bitstream_read(bc, 8); + v[1] = bitstream_read(bc, 8); for (j = 7; j >= 0; j--) for (i = 0; i < 8; i++) - dst[j * linesize + i] = v[get_bits1(gb)]; + dst[j * linesize + i] = v[bitstream_read_bit(bc)]; break; case 3: for (j = 0; j < 8; j += 4) for (i = 0; i < 8; i += 4) - decode4x4(gb, dst + j * linesize + i, linesize); + decode4x4(bc, dst + j * linesize + i, linesize); } } @@ -163,12 +163,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } if (video_type == 0 || video_type == 1) { - GetBitContext gb; - init_get_bits(&gb, buf, 8 * FFMIN(video_size, buf_end - buf)); + BitstreamContext bc; + bitstream_init(&bc, buf, 8 * FFMIN(video_size, buf_end - buf)); for (j = 0; j < avctx->height; j += 8) for (i = 0; i < avctx->width; i += 8) - decode8x8(&gb, + decode8x8(&bc, s->frame->data[0] + j * s->frame->linesize[0] + i, s->frame->linesize[0], &s->bdsp); From 6f94a64bd6ae14d592835369a954e1378b79d786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Tue, 12 Apr 2016 18:24:27 +0200 Subject: [PATCH 0527/3374] nellymoser: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/nellymoserdec.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libavcodec/nellymoserdec.c b/libavcodec/nellymoserdec.c index 355935f97c371..390872c89aef4 100644 --- a/libavcodec/nellymoserdec.c +++ b/libavcodec/nellymoserdec.c @@ -38,8 +38,8 @@ #define BITSTREAM_READER_LE #include "avcodec.h" +#include "bitstream.h" #include "fft.h" -#include "get_bits.h" #include "internal.h" #include "nellymoser.h" #include "sinewin.h" @@ -48,7 +48,7 @@ typedef struct NellyMoserDecodeContext { AVCodecContext* avctx; AVLFG random_state; - GetBitContext gb; + BitstreamContext bc; float scale_bias; AVFloatDSPContext fdsp; FFTContext imdct_ctx; @@ -67,14 +67,14 @@ static void nelly_decode_block(NellyMoserDecodeContext *s, int bits[NELLY_BUF_LEN]; unsigned char v; - init_get_bits(&s->gb, block, NELLY_BLOCK_LEN * 8); + bitstream_init(&s->bc, block, NELLY_BLOCK_LEN * 8); bptr = buf; pptr = pows; - val = ff_nelly_init_table[get_bits(&s->gb, 6)]; + val = ff_nelly_init_table[bitstream_read(&s->bc, 6)]; for (i=0 ; i 0) - val += ff_nelly_delta_table[get_bits(&s->gb, 5)]; + val += ff_nelly_delta_table[bitstream_read(&s->bc, 5)]; pval = -pow(2, val/2048) * s->scale_bias; for (j = 0; j < ff_nelly_band_sizes_table[i]; j++) { *bptr++ = val; @@ -88,8 +88,8 @@ static void nelly_decode_block(NellyMoserDecodeContext *s, for (i = 0; i < 2; i++) { aptr = audio + i * NELLY_BUF_LEN; - init_get_bits(&s->gb, block, NELLY_BLOCK_LEN * 8); - skip_bits_long(&s->gb, NELLY_HEADER_BITS + i*NELLY_DETAIL_BITS); + bitstream_init(&s->bc, block, NELLY_BLOCK_LEN * 8); + bitstream_skip(&s->bc, NELLY_HEADER_BITS + i * NELLY_DETAIL_BITS); for (j = 0; j < NELLY_FILL_LEN; j++) { if (bits[j] <= 0) { @@ -97,7 +97,7 @@ static void nelly_decode_block(NellyMoserDecodeContext *s, if (av_lfg_get(&s->random_state) & 1) aptr[j] *= -1.0; } else { - v = get_bits(&s->gb, bits[j]); + v = bitstream_read(&s->bc, bits[j]); aptr[j] = ff_nelly_dequantization_table[(1< Date: Tue, 12 Apr 2016 18:28:14 +0200 Subject: [PATCH 0528/3374] opus: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/opus.h | 6 +++--- libavcodec/opusdec.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libavcodec/opus.h b/libavcodec/opus.h index 55c91fa01202e..fbf67c9b9f698 100644 --- a/libavcodec/opus.h +++ b/libavcodec/opus.h @@ -32,7 +32,7 @@ #include "libavresample/avresample.h" #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #define MAX_FRAME_SIZE 1275 #define MAX_FRAMES 48 @@ -92,7 +92,7 @@ typedef struct RawBitsContext { } RawBitsContext; typedef struct OpusRangeCoder { - GetBitContext gb; + BitstreamContext bc; RawBitsContext rb; unsigned int range; unsigned int value; @@ -196,7 +196,7 @@ typedef struct OpusContext { static av_always_inline void opus_rc_normalize(OpusRangeCoder *rc) { while (rc->range <= 1<<23) { - rc->value = ((rc->value << 8) | (get_bits(&rc->gb, 8) ^ 0xFF)) & ((1u << 31) - 1); + rc->value = ((rc->value << 8) | (bitstream_read(&rc->bc, 8) ^ 0xFF)) & ((1u << 31) - 1); rc->range <<= 8; rc->total_read_bits += 8; } diff --git a/libavcodec/opusdec.c b/libavcodec/opusdec.c index 92e651c787fab..163f0d5ed5a69 100644 --- a/libavcodec/opusdec.c +++ b/libavcodec/opusdec.c @@ -43,9 +43,9 @@ #include "libavresample/avresample.h" #include "avcodec.h" +#include "bitstream.h" #include "celp_filters.h" #include "fft.h" -#include "get_bits.h" #include "internal.h" #include "mathops.h" #include "opus.h" @@ -80,12 +80,12 @@ static int get_silk_samplerate(int config) */ static int opus_rc_init(OpusRangeCoder *rc, const uint8_t *data, int size) { - int ret = init_get_bits8(&rc->gb, data, size); + int ret = bitstream_init8(&rc->bc, data, size); if (ret < 0) return ret; rc->range = 128; - rc->value = 127 - get_bits(&rc->gb, 7); + rc->value = 127 - bitstream_read(&rc->bc, 7); rc->total_read_bits = 9; opus_rc_normalize(rc); From 770406d1e8291dbfd846210d08c1b322d30c8142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Tue, 12 Apr 2016 18:32:50 +0200 Subject: [PATCH 0529/3374] pcx: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/pcx.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libavcodec/pcx.c b/libavcodec/pcx.c index a2d49b454d9d9..ece885e6e01c5 100644 --- a/libavcodec/pcx.c +++ b/libavcodec/pcx.c @@ -23,9 +23,10 @@ */ #include "libavutil/imgutils.h" + #include "avcodec.h" +#include "bitstream.h" #include "bytestream.h" -#include "get_bits.h" #include "internal.h" #define PCX_HEADER_SIZE 128 @@ -179,15 +180,15 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, goto end; } } else if (nplanes == 1) { /* all packed formats, max. 16 colors */ - GetBitContext s; + BitstreamContext s; for (y = 0; y < h; y++) { - init_get_bits(&s, scanline, bytes_per_scanline << 3); + bitstream_init(&s, scanline, bytes_per_scanline << 3); pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed); for (x = 0; x < w; x++) - ptr[x] = get_bits(&s, bits_per_pixel); + ptr[x] = bitstream_read(&s, bits_per_pixel); ptr += stride; } } else { /* planar, 4, 8 or 16 colors */ From 0dabd329e84a6a7b074fa55da844fc827a47aa01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Tue, 12 Apr 2016 18:39:16 +0200 Subject: [PATCH 0530/3374] qcelp: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/qcelpdec.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libavcodec/qcelpdec.c b/libavcodec/qcelpdec.c index e9e73475c33c0..9d5e13a117d3e 100644 --- a/libavcodec/qcelpdec.c +++ b/libavcodec/qcelpdec.c @@ -31,9 +31,10 @@ #include "libavutil/channel_layout.h" #include "libavutil/float_dsp.h" + #include "avcodec.h" +#include "bitstream.h" #include "internal.h" -#include "get_bits.h" #include "qcelpdata.h" #include "celp_filters.h" #include "acelp_filters.h" @@ -53,7 +54,7 @@ typedef enum { } qcelp_packet_rate; typedef struct QCELPContext { - GetBitContext gb; + BitstreamContext bc; qcelp_packet_rate bitrate; QCELPFrame frame; /**< unpacked data frame */ @@ -718,12 +719,12 @@ static int qcelp_decode_frame(AVCodecContext *avctx, void *data, qcelp_unpacking_bitmaps_lengths[q->bitrate]; uint8_t *unpacked_data = (uint8_t *)&q->frame; - init_get_bits(&q->gb, buf, 8 * buf_size); + bitstream_init(&q->bc, buf, 8 * buf_size); memset(&q->frame, 0, sizeof(QCELPFrame)); for (; bitmaps < bitmaps_end; bitmaps++) - unpacked_data[bitmaps->index] |= get_bits(&q->gb, bitmaps->bitlen) << bitmaps->bitpos; + unpacked_data[bitmaps->index] |= bitstream_read(&q->bc, bitmaps->bitlen) << bitmaps->bitpos; // Check for erasures/blanks on rates 1, 1/4 and 1/8. if (q->frame.reserved) { From 0b5a26e8bcd219efe5da3a6d39b588fabf91f2b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Tue, 12 Apr 2016 18:50:57 +0200 Subject: [PATCH 0531/3374] qdm2: Convert to the new bitstream reader Signed-off-by: Anton Khirnov --- libavcodec/qdm2.c | 200 +++++++++++++++++++++++----------------------- 1 file changed, 100 insertions(+), 100 deletions(-) diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c index 7a7c149c2b64c..781999aa101cb 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -39,7 +39,7 @@ #define BITSTREAM_READER_LE #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "internal.h" #include "mpegaudio.h" #include "mpegaudiodsp.h" @@ -361,31 +361,31 @@ static av_cold void qdm2_init_vlc(void) INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); } -static int qdm2_get_vlc(GetBitContext *gb, VLC *vlc, int flag, int depth) +static int qdm2_get_vlc(BitstreamContext *bc, VLC *vlc, int flag, int depth) { int value; - value = get_vlc2(gb, vlc->table, vlc->bits, depth); + value = bitstream_read_vlc(bc, vlc->table, vlc->bits, depth); /* stage-2, 3 bits exponent escape sequence */ if (value-- == 0) - value = get_bits(gb, get_bits(gb, 3) + 1); + value = bitstream_read(bc, bitstream_read(bc, 3) + 1); /* stage-3, optional */ if (flag) { int tmp = vlc_stage3_values[value]; if ((value & ~3) > 0) - tmp += get_bits(gb, (value >> 2)); + tmp += bitstream_read(bc, value >> 2); value = tmp; } return value; } -static int qdm2_get_se_vlc(VLC *vlc, GetBitContext *gb, int depth) +static int qdm2_get_se_vlc(VLC *vlc, BitstreamContext *bc, int depth) { - int value = qdm2_get_vlc(gb, vlc, 0, depth); + int value = qdm2_get_vlc(bc, vlc, 0, depth); return (value & 1) ? ((value + 1) >> 1) : -(value >> 1); } @@ -412,35 +412,35 @@ static uint16_t qdm2_packet_checksum(const uint8_t *data, int length, int value) /** * Fill a QDM2SubPacket structure with packet type, size, and data pointer. * - * @param gb bitreader context + * @param bc bitreader context * @param sub_packet packet under analysis */ -static void qdm2_decode_sub_packet_header(GetBitContext *gb, +static void qdm2_decode_sub_packet_header(BitstreamContext *bc, QDM2SubPacket *sub_packet) { - sub_packet->type = get_bits(gb, 8); + sub_packet->type = bitstream_read(bc, 8); if (sub_packet->type == 0) { sub_packet->size = 0; sub_packet->data = NULL; } else { - sub_packet->size = get_bits(gb, 8); + sub_packet->size = bitstream_read(bc, 8); if (sub_packet->type & 0x80) { sub_packet->size <<= 8; - sub_packet->size |= get_bits(gb, 8); + sub_packet->size |= bitstream_read(bc, 8); sub_packet->type &= 0x7f; } if (sub_packet->type == 0x7f) - sub_packet->type |= (get_bits(gb, 8) << 8); + sub_packet->type |= bitstream_read(bc, 8) << 8; // FIXME: this depends on bitreader-internal data - sub_packet->data = &gb->buffer[get_bits_count(gb) / 8]; + sub_packet->data = &bc->buffer[bitstream_tell(bc) / 8]; } av_log(NULL, AV_LOG_DEBUG, "Subpacket: type=%d size=%d start_offs=%x\n", - sub_packet->type, sub_packet->size, get_bits_count(gb) / 8); + sub_packet->type, sub_packet->size, bitstream_tell(bc) / 8); } /** @@ -799,12 +799,12 @@ static void fill_coding_method_array(sb_int8_array tone_level_idx, * sb 8-sb_used. * * @param q context - * @param gb bitreader context + * @param bc bitreader context * @param length packet length in bits * @param sb_min lower subband processed (sb_min included) * @param sb_max higher subband processed (sb_max excluded) */ -static void synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, +static void synthfilt_build_sb_samples(QDM2Context *q, BitstreamContext *bc, int length, int sb_min, int sb_max) { int sb, j, k, n, ch, run, channels; @@ -830,12 +830,12 @@ static void synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, else if (sb >= 24) joined_stereo = 1; else - joined_stereo = (get_bits_left(gb) >= 1) ? get_bits1(gb) : 0; + joined_stereo = (bitstream_bits_left(bc) >= 1) ? bitstream_read_bit(bc) : 0; if (joined_stereo) { - if (get_bits_left(gb) >= 16) + if (bitstream_bits_left(bc) >= 16) for (j = 0; j < 16; j++) - sign_bits[j] = get_bits1(gb); + sign_bits[j] = bitstream_read_bit(bc); for (j = 0; j < 64; j++) if (q->coding_method[1][sb][j] > q->coding_method[0][sb][j]) @@ -851,22 +851,22 @@ static void synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, for (ch = 0; ch < channels; ch++) { FIX_NOISE_IDX(q->noise_idx); - zero_encoding = (get_bits_left(gb) >= 1) ? get_bits1(gb) : 0; + zero_encoding = (bitstream_bits_left(bc) >= 1) ? bitstream_read_bit(bc) : 0; type34_predictor = 0.0; type34_first = 1; for (j = 0; j < 128; ) { switch (q->coding_method[ch][sb][j / 2]) { case 8: - if (get_bits_left(gb) >= 10) { + if (bitstream_bits_left(bc) >= 10) { if (zero_encoding) { for (k = 0; k < 5; k++) { if ((j + 2 * k) >= 128) break; - samples[2 * k] = get_bits1(gb) ? dequant_1bit[joined_stereo][2 * get_bits1(gb)] : 0; + samples[2 * k] = bitstream_read_bit(bc) ? dequant_1bit[joined_stereo][2 * bitstream_read_bit(bc)] : 0; } } else { - n = get_bits(gb, 8); + n = bitstream_read(bc, 8); for (k = 0; k < 5; k++) samples[2 * k] = dequant_1bit[joined_stereo][random_dequant_index[n][k]]; } @@ -880,10 +880,10 @@ static void synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, break; case 10: - if (get_bits_left(gb) >= 1) { + if (bitstream_bits_left(bc) >= 1) { float f = 0.81; - if (get_bits1(gb)) + if (bitstream_read_bit(bc)) f = -f; f -= noise_samples[((sb + 1) * (j +5 * ch + 1)) & 127] * 9.0 / 40.0; samples[0] = f; @@ -894,15 +894,15 @@ static void synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, break; case 16: - if (get_bits_left(gb) >= 10) { + if (bitstream_bits_left(bc) >= 10) { if (zero_encoding) { for (k = 0; k < 5; k++) { if ((j + k) >= 128) break; - samples[k] = (get_bits1(gb) == 0) ? 0 : dequant_1bit[joined_stereo][2 * get_bits1(gb)]; + samples[k] = (bitstream_read_bit(bc) == 0) ? 0 : dequant_1bit[joined_stereo][2 * bitstream_read_bit(bc)]; } } else { - n = get_bits (gb, 8); + n = bitstream_read (bc, 8); for (k = 0; k < 5; k++) samples[k] = dequant_1bit[joined_stereo][random_dequant_index[n][k]]; } @@ -914,8 +914,8 @@ static void synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, break; case 24: - if (get_bits_left(gb) >= 7) { - n = get_bits(gb, 7); + if (bitstream_bits_left(bc) >= 7) { + n = bitstream_read(bc, 7); for (k = 0; k < 3; k++) samples[k] = (random_dequant_type24[n][k] - 2.0) * 0.5; } else { @@ -926,8 +926,8 @@ static void synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, break; case 30: - if (get_bits_left(gb) >= 4) { - unsigned index = qdm2_get_vlc(gb, &vlc_tab_type30, 0, 1); + if (bitstream_bits_left(bc) >= 4) { + unsigned index = qdm2_get_vlc(bc, &vlc_tab_type30, 0, 1); if (index < FF_ARRAY_ELEMS(type30_dequant)) { samples[0] = type30_dequant[index]; } else @@ -939,14 +939,14 @@ static void synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, break; case 34: - if (get_bits_left(gb) >= 7) { + if (bitstream_bits_left(bc) >= 7) { if (type34_first) { - type34_div = (float)(1 << get_bits(gb, 2)); - samples[0] = ((float)get_bits(gb, 5) - 16.0) / 15.0; + type34_div = (float)(1 << bitstream_read(bc, 2)); + samples[0] = ((float)bitstream_read(bc, 5) - 16.0) / 15.0; type34_predictor = samples[0]; type34_first = 0; } else { - unsigned index = qdm2_get_vlc(gb, &vlc_tab_type34, 0, 1); + unsigned index = qdm2_get_vlc(bc, &vlc_tab_type34, 0, 1); if (index < FF_ARRAY_ELEMS(type34_delta)) { samples[0] = type34_delta[index] / type34_div + type34_predictor; type34_predictor = samples[0]; @@ -998,27 +998,27 @@ static void synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, * same VLC tables as process_subpacket_9 are used. * * @param quantized_coeffs pointer to quantized_coeffs[ch][0] - * @param gb bitreader context + * @param bc bitreader context */ static void init_quantized_coeffs_elem0(int8_t *quantized_coeffs, - GetBitContext *gb) + BitstreamContext *bc) { int i, k, run, level, diff; - if (get_bits_left(gb) < 16) + if (bitstream_bits_left(bc) < 16) return; - level = qdm2_get_vlc(gb, &vlc_tab_level, 0, 2); + level = qdm2_get_vlc(bc, &vlc_tab_level, 0, 2); quantized_coeffs[0] = level; for (i = 0; i < 7; ) { - if (get_bits_left(gb) < 16) + if (bitstream_bits_left(bc) < 16) break; - run = qdm2_get_vlc(gb, &vlc_tab_run, 0, 1) + 1; + run = qdm2_get_vlc(bc, &vlc_tab_run, 0, 1) + 1; - if (get_bits_left(gb) < 16) + if (bitstream_bits_left(bc) < 16) break; - diff = qdm2_get_se_vlc(&vlc_tab_diff, gb, 2); + diff = qdm2_get_se_vlc(&vlc_tab_diff, bc, 2); for (k = 1; k <= run; k++) quantized_coeffs[i + k] = (level + ((k * diff) / run)); @@ -1035,16 +1035,16 @@ static void init_quantized_coeffs_elem0(int8_t *quantized_coeffs, * data from packet 10 * * @param q context - * @param gb bitreader context + * @param bc bitreader context */ -static void init_tone_level_dequantization(QDM2Context *q, GetBitContext *gb) +static void init_tone_level_dequantization(QDM2Context *q, BitstreamContext *bc) { int sb, j, k, n, ch; for (ch = 0; ch < q->nb_channels; ch++) { - init_quantized_coeffs_elem0(q->quantized_coeffs[ch][0], gb); + init_quantized_coeffs_elem0(q->quantized_coeffs[ch][0], bc); - if (get_bits_left(gb) < 16) { + if (bitstream_bits_left(bc) < 16) { memset(q->quantized_coeffs[ch][0], 0, 8); break; } @@ -1055,13 +1055,13 @@ static void init_tone_level_dequantization(QDM2Context *q, GetBitContext *gb) for (sb = 0; sb < n; sb++) for (ch = 0; ch < q->nb_channels; ch++) for (j = 0; j < 8; j++) { - if (get_bits_left(gb) < 1) + if (bitstream_bits_left(bc) < 1) break; - if (get_bits1(gb)) { + if (bitstream_read_bit(bc)) { for (k=0; k < 8; k++) { - if (get_bits_left(gb) < 16) + if (bitstream_bits_left(bc) < 16) break; - q->tone_level_idx_hi1[ch][sb][j][k] = qdm2_get_vlc(gb, &vlc_tab_tone_level_idx_hi1, 0, 2); + q->tone_level_idx_hi1[ch][sb][j][k] = qdm2_get_vlc(bc, &vlc_tab_tone_level_idx_hi1, 0, 2); } } else { for (k=0; k < 8; k++) @@ -1073,9 +1073,9 @@ static void init_tone_level_dequantization(QDM2Context *q, GetBitContext *gb) for (sb = 0; sb < n; sb++) for (ch = 0; ch < q->nb_channels; ch++) { - if (get_bits_left(gb) < 16) + if (bitstream_bits_left(bc) < 16) break; - q->tone_level_idx_hi2[ch][sb] = qdm2_get_vlc(gb, &vlc_tab_tone_level_idx_hi2, 0, 2); + q->tone_level_idx_hi2[ch][sb] = qdm2_get_vlc(bc, &vlc_tab_tone_level_idx_hi2, 0, 2); if (sb > 19) q->tone_level_idx_hi2[ch][sb] -= 16; else @@ -1088,9 +1088,9 @@ static void init_tone_level_dequantization(QDM2Context *q, GetBitContext *gb) for (sb = 0; sb < n; sb++) for (ch = 0; ch < q->nb_channels; ch++) for (j = 0; j < 8; j++) { - if (get_bits_left(gb) < 16) + if (bitstream_bits_left(bc) < 16) break; - q->tone_level_idx_mid[ch][sb][j] = qdm2_get_vlc(gb, &vlc_tab_tone_level_idx_mid, 0, 2) - 32; + q->tone_level_idx_mid[ch][sb][j] = qdm2_get_vlc(bc, &vlc_tab_tone_level_idx_mid, 0, 2) - 32; } } @@ -1102,21 +1102,21 @@ static void init_tone_level_dequantization(QDM2Context *q, GetBitContext *gb) */ static void process_subpacket_9(QDM2Context *q, QDM2SubPNode *node) { - GetBitContext gb; + BitstreamContext bc; int i, j, k, n, ch, run, level, diff; - init_get_bits(&gb, node->packet->data, node->packet->size * 8); + bitstream_init(&bc, node->packet->data, node->packet->size * 8); n = coeff_per_sb_for_avg[q->coeff_per_sb_select][QDM2_SB_USED(q->sub_sampling) - 1] + 1; for (i = 1; i < n; i++) for (ch = 0; ch < q->nb_channels; ch++) { - level = qdm2_get_vlc(&gb, &vlc_tab_level, 0, 2); + level = qdm2_get_vlc(&bc, &vlc_tab_level, 0, 2); q->quantized_coeffs[ch][i][0] = level; for (j = 0; j < (8 - 1); ) { - run = qdm2_get_vlc(&gb, &vlc_tab_run, 0, 1) + 1; - diff = qdm2_get_se_vlc(&vlc_tab_diff, &gb, 2); + run = qdm2_get_vlc(&bc, &vlc_tab_run, 0, 1) + 1; + diff = qdm2_get_se_vlc(&vlc_tab_diff, &bc, 2); for (k = 1; k <= run; k++) q->quantized_coeffs[ch][i][j + k] = (level + ((k * diff) / run)); @@ -1139,11 +1139,11 @@ static void process_subpacket_9(QDM2Context *q, QDM2SubPNode *node) */ static void process_subpacket_10(QDM2Context *q, QDM2SubPNode *node) { - GetBitContext gb; + BitstreamContext bc; if (node) { - init_get_bits(&gb, node->packet->data, node->packet->size * 8); - init_tone_level_dequantization(q, &gb); + bitstream_init(&bc, node->packet->data, node->packet->size * 8); + init_tone_level_dequantization(q, &bc); fill_tone_level_array(q, 1); } else { fill_tone_level_array(q, 0); @@ -1158,16 +1158,16 @@ static void process_subpacket_10(QDM2Context *q, QDM2SubPNode *node) */ static void process_subpacket_11(QDM2Context *q, QDM2SubPNode *node) { - GetBitContext gb; + BitstreamContext bc; int length = 0; if (node) { length = node->packet->size * 8; - init_get_bits(&gb, node->packet->data, length); + bitstream_init(&bc, node->packet->data, length); } if (length >= 32) { - int c = get_bits(&gb, 13); + int c = bitstream_read(&bc, 13); if (c > 3) fill_coding_method_array(q->tone_level_idx, @@ -1176,7 +1176,7 @@ static void process_subpacket_11(QDM2Context *q, QDM2SubPNode *node) q->superblocktype_2_3, q->cm_table_select); } - synthfilt_build_sb_samples(q, &gb, length, 0, 8); + synthfilt_build_sb_samples(q, &bc, length, 0, 8); } /** @@ -1187,15 +1187,15 @@ static void process_subpacket_11(QDM2Context *q, QDM2SubPNode *node) */ static void process_subpacket_12(QDM2Context *q, QDM2SubPNode *node) { - GetBitContext gb; + BitstreamContext bc; int length = 0; if (node) { length = node->packet->size * 8; - init_get_bits(&gb, node->packet->data, length); + bitstream_init(&bc, node->packet->data, length); } - synthfilt_build_sb_samples(q, &gb, length, 8, QDM2_SB_USED(q->sub_sampling)); + synthfilt_build_sb_samples(q, &bc, length, 8, QDM2_SB_USED(q->sub_sampling)); } /* @@ -1238,7 +1238,7 @@ static void process_synthesis_subpackets(QDM2Context *q, QDM2SubPNode *list) */ static void qdm2_decode_super_block(QDM2Context *q) { - GetBitContext gb; + BitstreamContext bc; QDM2SubPacket header, *packet; int i, packet_bytes, sub_packet_size, sub_packets_D; unsigned int next_index = 0; @@ -1252,8 +1252,8 @@ static void qdm2_decode_super_block(QDM2Context *q) average_quantized_coeffs(q); // average elements in quantized_coeffs[max_ch][10][8] - init_get_bits(&gb, q->compressed_data, q->compressed_size * 8); - qdm2_decode_sub_packet_header(&gb, &header); + bitstream_init(&bc, q->compressed_data, q->compressed_size * 8); + qdm2_decode_sub_packet_header(&bc, &header); if (header.type < 2 || header.type >= 8) { q->has_errors = 1; @@ -1262,13 +1262,13 @@ static void qdm2_decode_super_block(QDM2Context *q) } q->superblocktype_2_3 = (header.type == 2 || header.type == 3); - packet_bytes = (q->compressed_size - get_bits_count(&gb) / 8); + packet_bytes = (q->compressed_size - bitstream_tell(&bc) / 8); - init_get_bits(&gb, header.data, header.size * 8); + bitstream_init(&bc, header.data, header.size * 8); if (header.type == 2 || header.type == 4 || header.type == 5) { - int csum = 257 * get_bits(&gb, 8); - csum += 2 * get_bits(&gb, 8); + int csum = 257 * bitstream_read(&bc, 8); + csum += 2 * bitstream_read(&bc, 8); csum = qdm2_packet_checksum(q->compressed_data, q->checksum_size, csum); @@ -1300,8 +1300,8 @@ static void qdm2_decode_super_block(QDM2Context *q) q->sub_packet_list_A[i - 1].next = &q->sub_packet_list_A[i]; /* seek to next block */ - init_get_bits(&gb, header.data, header.size * 8); - skip_bits(&gb, next_index * 8); + bitstream_init(&bc, header.data, header.size * 8); + bitstream_skip(&bc, next_index * 8); if (next_index >= header.size) break; @@ -1309,8 +1309,8 @@ static void qdm2_decode_super_block(QDM2Context *q) /* decode subpacket */ packet = &q->sub_packets[i]; - qdm2_decode_sub_packet_header(&gb, packet); - next_index = packet->size + get_bits_count(&gb) / 8; + qdm2_decode_sub_packet_header(&bc, packet); + next_index = packet->size + bitstream_tell(&bc) / 8; sub_packet_size = ((packet->size > 0xff) ? 1 : 0) + packet->size + 2; if (packet->type == 0) @@ -1336,10 +1336,10 @@ static void qdm2_decode_super_block(QDM2Context *q) QDM2_LIST_ADD(q->sub_packet_list_D, sub_packets_D, packet); } else if (packet->type == 13) { for (j = 0; j < 6; j++) - q->fft_level_exp[j] = get_bits(&gb, 6); + q->fft_level_exp[j] = bitstream_read(&bc, 6); } else if (packet->type == 14) { for (j = 0; j < 6; j++) - q->fft_level_exp[j] = qdm2_get_vlc(&gb, &fft_level_exp_vlc, 0, 2); + q->fft_level_exp[j] = qdm2_get_vlc(&bc, &fft_level_exp_vlc, 0, 2); } else if (packet->type == 15) { SAMPLES_NEEDED_2("packet type 15") return; @@ -1377,7 +1377,7 @@ static void qdm2_fft_init_coefficient(QDM2Context *q, int sub_packet, } static void qdm2_fft_decode_tones(QDM2Context *q, int duration, - GetBitContext *gb, int b) + BitstreamContext *bc, int b) { int channel, stereo, phase, exp; int local_int_4, local_int_8, stereo_phase, local_int_10; @@ -1393,7 +1393,7 @@ static void qdm2_fft_decode_tones(QDM2Context *q, int duration, while (1) { if (q->superblocktype_2_3) { - while ((n = qdm2_get_vlc(gb, &vlc_tab_fft_tone_offset[local_int_8], 1, 2)) < 2) { + while ((n = qdm2_get_vlc(bc, &vlc_tab_fft_tone_offset[local_int_8], 1, 2)) < 2) { offset = 1; if (n == 0) { local_int_4 += local_int_10; @@ -1405,7 +1405,7 @@ static void qdm2_fft_decode_tones(QDM2Context *q, int duration, } offset += (n - 2); } else { - offset += qdm2_get_vlc(gb, &vlc_tab_fft_tone_offset[local_int_8], 1, 2); + offset += qdm2_get_vlc(bc, &vlc_tab_fft_tone_offset[local_int_8], 1, 2); while (offset >= (local_int_10 - 1)) { offset += (1 - (local_int_10 - 1)); local_int_4 += local_int_10; @@ -1421,24 +1421,24 @@ static void qdm2_fft_decode_tones(QDM2Context *q, int duration, return; if (q->nb_channels > 1) { - channel = get_bits1(gb); - stereo = get_bits1(gb); + channel = bitstream_read_bit(bc); + stereo = bitstream_read_bit(bc); } else { channel = 0; stereo = 0; } - exp = qdm2_get_vlc(gb, (b ? &fft_level_exp_vlc : &fft_level_exp_alt_vlc), 0, 2); + exp = qdm2_get_vlc(bc, (b ? &fft_level_exp_vlc : &fft_level_exp_alt_vlc), 0, 2); exp += q->fft_level_exp[fft_level_index_table[local_int_14]]; exp = (exp < 0) ? 0 : exp; - phase = get_bits(gb, 3); + phase = bitstream_read(bc, 3); stereo_exp = 0; stereo_phase = 0; if (stereo) { - stereo_exp = (exp - qdm2_get_vlc(gb, &fft_stereo_exp_vlc, 0, 1)); - stereo_phase = (phase - qdm2_get_vlc(gb, &fft_stereo_phase_vlc, 0, 1)); + stereo_exp = (exp - qdm2_get_vlc(bc, &fft_stereo_exp_vlc, 0, 1)); + stereo_phase = (phase - qdm2_get_vlc(bc, &fft_stereo_phase_vlc, 0, 1)); if (stereo_phase < 0) stereo_phase += 8; } @@ -1460,7 +1460,7 @@ static void qdm2_fft_decode_tones(QDM2Context *q, int duration, static void qdm2_decode_fft_packets(QDM2Context *q) { int i, j, min, max, value, type, unknown_flag; - GetBitContext gb; + BitstreamContext bc; if (!q->sub_packet_list_B[0].packet) return; @@ -1495,7 +1495,7 @@ static void qdm2_decode_fft_packets(QDM2Context *q) return; /* decode FFT tones */ - init_get_bits(&gb, packet->data, packet->size * 8); + bitstream_init(&bc, packet->data, packet->size * 8); if (packet->type >= 32 && packet->type < 48 && !fft_subpackets[packet->type - 16]) unknown_flag = 1; @@ -1508,15 +1508,15 @@ static void qdm2_decode_fft_packets(QDM2Context *q) int duration = q->sub_sampling + 5 - (type & 15); if (duration >= 0 && duration < 4) - qdm2_fft_decode_tones(q, duration, &gb, unknown_flag); + qdm2_fft_decode_tones(q, duration, &bc, unknown_flag); } else if (type == 31) { for (j = 0; j < 4; j++) - qdm2_fft_decode_tones(q, j, &gb, unknown_flag); + qdm2_fft_decode_tones(q, j, &bc, unknown_flag); } else if (type == 46) { for (j = 0; j < 6; j++) - q->fft_level_exp[j] = get_bits(&gb, 6); + q->fft_level_exp[j] = bitstream_read(&bc, 6); for (j = 0; j < 4; j++) - qdm2_fft_decode_tones(q, j, &gb, unknown_flag); + qdm2_fft_decode_tones(q, j, &bc, unknown_flag); } } // Loop on B packets From 3c7fa8cbb93dba96acb12aef6e00d929c1da1ae8 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Fri, 18 Nov 2016 10:56:01 +0100 Subject: [PATCH 0532/3374] hlsenc: Fix the openssl support --- libavformat/hlsenc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 5eebec8511679..625531b881d6d 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -92,6 +92,7 @@ static int randomize(uint8_t *buf, int len) #elif CONFIG_OPENSSL if (RAND_bytes(buf, len)) return 0; + return AVERROR(EIO); #else return AVERROR(ENOSYS); #endif From e5b0fc170f85b00f7dd0ac514918fb5c95253d39 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Fri, 18 Nov 2016 09:36:59 +0200 Subject: [PATCH 0533/3374] arm: vp9itxfm: Simplify the stack alignment code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is one instruction less for thumb, and only have got 1/2 arm/thumb specific instructions. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index cdb43b567f596..5d73d84d1f38c 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -791,15 +791,13 @@ function ff_vp9_\txfm1\()_\txfm2\()_16x16_add_neon, export=1 .ifnc \txfm1\()_\txfm2,idct_idct vpush {q4-q7} .endif - mov r7, sp @ Align the stack, allocate a temp buffer -T mov r12, sp -T bic r12, r12, #15 -T sub r12, r12, #512 -T mov sp, r12 -A bic sp, sp, #15 -A sub sp, sp, #512 +T mov r7, sp +T and r7, r7, #15 +A and r7, sp, #15 + add r7, r7, #512 + sub sp, sp, r7 mov r4, r0 mov r5, r1 @@ -828,7 +826,7 @@ A sub sp, sp, #512 bl \txfm2\()16_1d_4x16_pass2_neon .endr - mov sp, r7 + add sp, sp, r7 .ifnc \txfm1\()_\txfm2,idct_idct vpop {q4-q7} .endif @@ -1117,15 +1115,13 @@ function ff_vp9_idct_idct_32x32_add_neon, export=1 beq idct32x32_dc_add_neon push {r4-r7,lr} vpush {q4-q7} - mov r7, sp @ Align the stack, allocate a temp buffer -T mov r12, sp -T bic r12, r12, #15 -T sub r12, r12, #2048 -T mov sp, r12 -A bic sp, sp, #15 -A sub sp, sp, #2048 +T mov r7, sp +T and r7, r7, #15 +A and r7, sp, #15 + add r7, r7, #2048 + sub sp, sp, r7 mov r4, r0 mov r5, r1 @@ -1143,7 +1139,7 @@ A sub sp, sp, #2048 bl idct32_1d_4x32_pass2_neon .endr - mov sp, r7 + add sp, sp, r7 vpop {q4-q7} pop {r4-r7,pc} endfunc From 4d960a11855f4212eb3a4e470ce890db7f01df29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 18 Nov 2016 12:09:06 +0200 Subject: [PATCH 0534/3374] aarch64: vp9itxfm: Use w3 instead of x3 for the int eob parameter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The clobbering tests in checkasm are only invoked when testing correctness, so this bug didn't show up when benchmarking the dc-only version. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index 9df0725e47fd5..65406b9e1a262 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -204,7 +204,7 @@ function ff_vp9_\txfm1\()_\txfm2\()_4x4_add_neon, export=1 movi v31.8h, #0 .ifc \txfm1\()_\txfm2,idct_idct - cmp x3, #1 + cmp w3, #1 b.ne 1f // DC-only for idct/idct ld1r {v2.4h}, [x2] @@ -344,7 +344,7 @@ function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_neon, export=1 movi v5.16b, #0 .ifc \txfm1\()_\txfm2,idct_idct - cmp x3, #1 + cmp w3, #1 b.ne 1f // DC-only for idct/idct ld1r {v2.4h}, [x2] @@ -722,7 +722,7 @@ itxfm16_1d_funcs iadst .macro itxfm_func16x16 txfm1, txfm2 function ff_vp9_\txfm1\()_\txfm2\()_16x16_add_neon, export=1 .ifc \txfm1\()_\txfm2,idct_idct - cmp x3, #1 + cmp w3, #1 b.eq idct16x16_dc_add_neon .endif mov x15, x30 @@ -1074,7 +1074,7 @@ function idct32_1d_8x32_pass2_neon endfunc function ff_vp9_idct_idct_32x32_add_neon, export=1 - cmp x3, #1 + cmp w3, #1 b.eq idct32x32_dc_add_neon movrel x10, idct_coeffs From a1d9de304fe63614e3aa8117fef17491fa80093d Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 9 Nov 2016 22:09:38 +0100 Subject: [PATCH 0535/3374] Fix some mismatches between function parameter and doxygen parameter names. --- libavcodec/avcodec.h | 2 +- libavresample/avresample.h | 4 ++-- libavutil/hwcontext.h | 2 +- libavutil/imgutils.h | 4 ++-- libavutil/stereo3d.h | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index a004e6bccea2d..e75d300ba0bc0 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3838,7 +3838,7 @@ AVPacket *av_packet_clone(const AVPacket *src); * Free the packet, if the packet is reference counted, it will be * unreferenced first. * - * @param packet packet to be freed. The pointer will be set to NULL. + * @param pkt packet to be freed. The pointer will be set to NULL. * @note passing NULL is a no-op. */ void av_packet_free(AVPacket **pkt); diff --git a/libavresample/avresample.h b/libavresample/avresample.h index c66798c08cee4..3f9b9433c1265 100644 --- a/libavresample/avresample.h +++ b/libavresample/avresample.h @@ -490,8 +490,8 @@ int avresample_convert_frame(AVAudioResampleContext *avr, * @see avresample_close(); * * @param avr audio resample context - * @param output output AVFrame - * @param input input AVFrame + * @param out output AVFrame + * @param in input AVFrame * @return 0 on success, AVERROR on failure. */ int avresample_config(AVAudioResampleContext *avr, AVFrame *out, AVFrame *in); diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h index 4067ff1db24c2..1181659b96e6f 100644 --- a/libavutil/hwcontext.h +++ b/libavutil/hwcontext.h @@ -418,7 +418,7 @@ void *av_hwdevice_hwconfig_alloc(AVBufferRef *device_ctx); * configuration is provided, returns the maximum possible capabilities * of the device. * - * @param device_ctx a reference to the associated AVHWDeviceContext. + * @param ref a reference to the associated AVHWDeviceContext. * @param hwconfig a filled HW-specific configuration structure, or NULL * to return the maximum possible capabilities of the device. * @return AVHWFramesConstraints structure describing the constraints diff --git a/libavutil/imgutils.h b/libavutil/imgutils.h index f98a18ff219b7..67063a2947072 100644 --- a/libavutil/imgutils.h +++ b/libavutil/imgutils.h @@ -152,7 +152,7 @@ void av_image_copy_uc_from(uint8_t *dst_data[4], const ptrdiff_t dst_lines * one call, use av_image_alloc(). * * @param dst_data data pointers to be filled in - * @param dst_linesizes linesizes for the image in dst_data to be filled in + * @param dst_linesize linesizes for the image in dst_data to be filled in * @param src buffer which will contain or contains the actual image data, can be NULL * @param pix_fmt the pixel format of the image * @param width the width of the image in pixels @@ -182,7 +182,7 @@ int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, * @param dst a buffer into which picture data will be copied * @param dst_size the size in bytes of dst * @param src_data pointers containing the source image data - * @param src_linesizes linesizes for the image in src_data + * @param src_linesize linesizes for the image in src_data * @param pix_fmt the pixel format of the source image * @param width the width of the source image in pixels * @param height the height of the source image in pixels diff --git a/libavutil/stereo3d.h b/libavutil/stereo3d.h index aea1b7052b78c..28156fc710a93 100644 --- a/libavutil/stereo3d.h +++ b/libavutil/stereo3d.h @@ -161,7 +161,7 @@ const char *av_stereo3d_type_name(unsigned int type); /** * Get the AVStereo3DType form a human-readable name. * - * @param type The input string. + * @param name The input string. * * @return The AVStereo3DType value, or -1 if not found. */ From 81a3c42abe17e757fe890607f67201a240648993 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 9 Nov 2016 22:10:39 +0100 Subject: [PATCH 0536/3374] Drop some bogus Doxygen documentation. --- libavcodec/vorbis_parser.h | 3 --- libavutil/hwcontext.h | 2 -- 2 files changed, 5 deletions(-) diff --git a/libavcodec/vorbis_parser.h b/libavcodec/vorbis_parser.h index f97a523fb795f..88d4d59f6e63c 100644 --- a/libavcodec/vorbis_parser.h +++ b/libavcodec/vorbis_parser.h @@ -32,9 +32,6 @@ typedef struct AVVorbisParseContext AVVorbisParseContext; /** * Allocate and initialize the Vorbis parser using headers in the extradata. - * - * @param avctx codec context - * @param s Vorbis parser context */ AVVorbisParseContext *av_vorbis_parse_init(const uint8_t *extradata, int extradata_size); diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h index 1181659b96e6f..037ca64224d23 100644 --- a/libavutil/hwcontext.h +++ b/libavutil/hwcontext.h @@ -225,8 +225,6 @@ typedef struct AVHWFramesContext { /** * Allocate an AVHWDeviceContext for a given pixel format. * - * @param format a hwaccel pixel format (AV_PIX_FMT_FLAG_HWACCEL must be set - * on the corresponding format descriptor) * @return a reference to the newly created AVHWDeviceContext on success or NULL * on failure. */ From 97cd7a3dc005a0ad1656dbb2af92e9c5d0731f21 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 8 Mar 2016 22:53:42 +0100 Subject: [PATCH 0537/3374] rtpdec_mpeg4: const correctness for parse_fmtp_config() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit libavformat/rtpdec_mpeg4.c:282:38: warning: passing argument 2 of ‘parse_fmtp_config’ discards ‘const’ qualifier from pointer target type --- libavformat/rtpdec_mpeg4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/rtpdec_mpeg4.c b/libavformat/rtpdec_mpeg4.c index bc50da2a8bfc1..00a732b1cc536 100644 --- a/libavformat/rtpdec_mpeg4.c +++ b/libavformat/rtpdec_mpeg4.c @@ -97,7 +97,7 @@ static void close_context(PayloadContext *data) av_free(data->mode); } -static int parse_fmtp_config(AVCodecParameters *par, char *value) +static int parse_fmtp_config(AVCodecParameters *par, const char *value) { /* decode the hexa encoded parameter */ int len = ff_hex_to_data(NULL, value); From bdbb8c68668b7610f5a310f5bbb246d2b950426d Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 17 Nov 2016 20:39:06 +0100 Subject: [PATCH 0538/3374] doc: Add libxavs section --- doc/general.texi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/general.texi b/doc/general.texi index 7b1f11cf48d40..d232300028bf0 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -95,6 +95,14 @@ Go to @url{http://www.wavpack.com/} and follow the instructions for installing the library. Then pass @code{--enable-libwavpack} to configure to enable it. +@section libxavs + +Libav can make use of the libxavs library for Xavs encoding. + +Go to @url{http://xavs.sf.net/} and follow the instructions for +installing the library. Then pass @code{--enable-libxavs} to configure to +enable it. + @section OpenH264 Libav can make use of the OpenH264 library for H.264 encoding and decoding. From 5eef983297b5e2eaa785f1e832622480eaa84103 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 11 Dec 2015 12:26:19 +0100 Subject: [PATCH 0539/3374] ape: Restructure DEBUG ifdefs to avoid unused function parameter warnings --- libavformat/ape.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavformat/ape.c b/libavformat/ape.c index 80e337240378c..010b795c593fa 100644 --- a/libavformat/ape.c +++ b/libavformat/ape.c @@ -94,9 +94,9 @@ static int ape_probe(AVProbeData * p) return 0; } +#ifdef DEBUG static void ape_dumpinfo(AVFormatContext * s, APEContext * ape_ctx) { -#ifdef DEBUG int i; av_log(s, AV_LOG_DEBUG, "Descriptor Block:\n\n"); @@ -154,8 +154,10 @@ static void ape_dumpinfo(AVFormatContext * s, APEContext * ape_ctx) av_log(s, AV_LOG_DEBUG, "junklength = %"PRIu32"\n", ape_ctx->junklength); av_log(s, AV_LOG_DEBUG, "firstframe = %"PRIu32"\n", ape_ctx->firstframe); av_log(s, AV_LOG_DEBUG, "totalsamples = %"PRIu32"\n", ape_ctx->totalsamples); -#endif } +#else +#define ape_dumpinfo(s, ape_ctx) do {} while(0) +#endif static int ape_read_header(AVFormatContext * s) { From 367f95af555d096bbc448f185f1902378b2fe805 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 11 Dec 2015 20:46:56 +0100 Subject: [PATCH 0540/3374] ac3enc: Restructure DEBUG ifdefs to avoid unused function parameter warnings --- libavcodec/ac3enc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c index da141e1acb3ff..48bc2e79de193 100644 --- a/libavcodec/ac3enc.c +++ b/libavcodec/ac3enc.c @@ -1676,9 +1676,9 @@ void ff_ac3_output_frame(AC3EncodeContext *s, unsigned char *frame) } +#ifdef DEBUG static void dprint_options(AC3EncodeContext *s) { -#ifdef DEBUG AVCodecContext *avctx = s->avctx; AC3EncOptions *opt = &s->options; char strbuf[32]; @@ -1787,8 +1787,10 @@ static void dprint_options(AC3EncodeContext *s) ff_dlog(avctx, "extended bitstream info 2: {not written}\n"); } } -#endif } +#else +#define dprint_options(x) do {} while(0) +#endif #define FLT_OPTION_THRESHOLD 0.01 From 6427379f23eb4d2b82d8d274c616f68b65a2f723 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 11 Dec 2015 21:08:48 +0100 Subject: [PATCH 0541/3374] als: Restructure DEBUG ifdefs to avoid unused function parameter warnings --- libavcodec/alsdec.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c index f356a70104875..af514870ef8ff 100644 --- a/libavcodec/alsdec.c +++ b/libavcodec/alsdec.c @@ -246,9 +246,9 @@ typedef struct ALSBlockData { } ALSBlockData; +#ifdef DEBUG static av_cold void dprint_specific_config(ALSDecContext *ctx) { -#ifdef DEBUG AVCodecContext *avctx = ctx->avctx; ALSSpecificConfig *sconf = &ctx->sconf; @@ -270,8 +270,10 @@ static av_cold void dprint_specific_config(ALSDecContext *ctx) ff_dlog(avctx, "chan_sort = %i\n", sconf->chan_sort); ff_dlog(avctx, "RLSLMS = %i\n", sconf->rlslms); ff_dlog(avctx, "chan_config_info = %i\n", sconf->chan_config_info); -#endif } +#else +#define dprint_specific_config(x) do {} while(0) +#endif /** Read an ALSSpecificConfig from a buffer into the output struct. From b8cd7a3c8df2c3aac8d7a0b5a02d83caf61bd769 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 11 Dec 2015 19:52:36 +0100 Subject: [PATCH 0542/3374] dvbsub: Check for errors from system() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit libavcodec/dvbsubdec.c:145:5: warning: ignoring return value of ‘system’, declared with attribute warn_unused_result [-Wunused-result] libavcodec/dvbsubdec.c:148:5: warning: ignoring return value of ‘system’, declared with attribute warn_unused_result [-Wunused-result] --- libavcodec/dvbsubdec.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c index ccdfc01089a35..e512b97a07e97 100644 --- a/libavcodec/dvbsubdec.c +++ b/libavcodec/dvbsubdec.c @@ -84,10 +84,16 @@ static void png_save(const char *filename, uint32_t *bitmap, int w, int h) fclose(f); snprintf(command, sizeof(command), "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename); - system(command); + if (system(command) != 0) { + printf("Error running pnmtopng\n"); + return; + } snprintf(command, sizeof(command), "rm %s %s", fname, fname2); - system(command); + if (system(command) != 0) { + printf("Error removing %s and %s\n", fname, fname2); + return; + } } #endif From b34c6cd57a2e8aad5f773aea933f77883de320ec Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 11 Dec 2015 20:17:31 +0100 Subject: [PATCH 0543/3374] dvbsub: cosmetics: Group all debug code together --- libavcodec/dvbsubdec.c | 126 ++++++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 64 deletions(-) diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c index e512b97a07e97..c3248c99191e8 100644 --- a/libavcodec/dvbsubdec.c +++ b/libavcodec/dvbsubdec.c @@ -34,69 +34,6 @@ #define cm (ff_crop_tab + MAX_NEG_CROP) -#ifdef DEBUG -static void png_save(const char *filename, uint32_t *bitmap, int w, int h) -{ - int x, y, v; - FILE *f; - char fname[40], fname2[40]; - char command[1024]; - - snprintf(fname, sizeof(fname), "%s.ppm", filename); - - f = fopen(fname, "w"); - if (!f) { - perror(fname); - return; - } - fprintf(f, "P6\n" - "%d %d\n" - "%d\n", - w, h, 255); - for(y = 0; y < h; y++) { - for(x = 0; x < w; x++) { - v = bitmap[y * w + x]; - putc((v >> 16) & 0xff, f); - putc((v >> 8) & 0xff, f); - putc((v >> 0) & 0xff, f); - } - } - fclose(f); - - - snprintf(fname2, sizeof(fname2), "%s-a.pgm", filename); - - f = fopen(fname2, "w"); - if (!f) { - perror(fname2); - return; - } - fprintf(f, "P5\n" - "%d %d\n" - "%d\n", - w, h, 255); - for(y = 0; y < h; y++) { - for(x = 0; x < w; x++) { - v = bitmap[y * w + x]; - putc((v >> 24) & 0xff, f); - } - } - fclose(f); - - snprintf(command, sizeof(command), "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename); - if (system(command) != 0) { - printf("Error running pnmtopng\n"); - return; - } - - snprintf(command, sizeof(command), "rm %s %s", fname, fname2); - if (system(command) != 0) { - printf("Error removing %s and %s\n", fname, fname2); - return; - } -} -#endif - #define RGBA(r,g,b,a) (((unsigned)(a) << 24) | ((r) << 16) | ((g) << 8) | (b)) typedef struct DVBSubCLUT { @@ -1123,6 +1060,67 @@ static int dvbsub_parse_page_segment(AVCodecContext *avctx, #ifdef DEBUG +static void png_save(const char *filename, uint32_t *bitmap, int w, int h) +{ + int x, y, v; + FILE *f; + char fname[40], fname2[40]; + char command[1024]; + + snprintf(fname, sizeof(fname), "%s.ppm", filename); + + f = fopen(fname, "w"); + if (!f) { + perror(fname); + return; + } + fprintf(f, "P6\n" + "%d %d\n" + "%d\n", + w, h, 255); + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + v = bitmap[y * w + x]; + putc((v >> 16) & 0xff, f); + putc((v >> 8) & 0xff, f); + putc((v >> 0) & 0xff, f); + } + } + fclose(f); + + + snprintf(fname2, sizeof(fname2), "%s-a.pgm", filename); + + f = fopen(fname2, "w"); + if (!f) { + perror(fname2); + return; + } + fprintf(f, "P5\n" + "%d %d\n" + "%d\n", + w, h, 255); + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + v = bitmap[y * w + x]; + putc((v >> 24) & 0xff, f); + } + } + fclose(f); + + snprintf(command, sizeof(command), "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename); + if (system(command) != 0) { + printf("Error running pnmtopng\n"); + return; + } + + snprintf(command, sizeof(command), "rm %s %s", fname, fname2); + if (system(command) != 0) { + printf("Error removing %s and %s\n", fname, fname2); + return; + } +} + static int save_display_set(DVBSubContext *ctx) { DVBSubRegion *region; @@ -1218,7 +1216,7 @@ static int save_display_set(DVBSubContext *ctx) fileno_index++; return 0; } -#endif +#endif /* DEBUG */ static int dvbsub_parse_display_definition_segment(AVCodecContext *avctx, const uint8_t *buf, From f92d7bdfddfaac04b3bb31f2749d173ca1d8ba6d Mon Sep 17 00:00:00 2001 From: Andreas Cadhalpun Date: Mon, 14 Nov 2016 21:41:45 +0100 Subject: [PATCH 0544/3374] libopusdec: default to stereo for invalid number of channels This fixes an out-of-bounds read if avc->channels is 0. Signed-off-by: Andreas Cadhalpun Signed-off-by: Anton Khirnov --- libavcodec/libopusdec.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libavcodec/libopusdec.c b/libavcodec/libopusdec.c index c6e15738808e5..75eaf9bd48c9e 100644 --- a/libavcodec/libopusdec.c +++ b/libavcodec/libopusdec.c @@ -42,6 +42,12 @@ static av_cold int libopus_decode_init(AVCodecContext *avc) int ret, channel_map = 0, gain_db = 0, nb_streams, nb_coupled; uint8_t mapping_arr[8] = { 0, 1 }, *mapping; + if (avc->channels <= 0) { + av_log(avc, AV_LOG_WARNING, + "Invalid number of channels %d, defaulting to stereo\n", avc->channels); + avc->channels = 2; + } + avc->sample_rate = 48000; avc->sample_fmt = avc->request_sample_fmt == AV_SAMPLE_FMT_FLT ? AV_SAMPLE_FMT_FLT : AV_SAMPLE_FMT_S16; From 1dd2b6c91ca5f26207805720d4f5564de60b241b Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 12 Oct 2016 13:14:17 +0200 Subject: [PATCH 0545/3374] examples/qsvdec: switch to the hwcontext API The code now does not depend on VA and will work on windows as well. --- configure | 2 +- doc/examples/qsvdec.c | 317 +++++++----------------------------------- 2 files changed, 52 insertions(+), 267 deletions(-) diff --git a/configure b/configure index 647087802a16f..beab6ba68755f 100755 --- a/configure +++ b/configure @@ -2454,7 +2454,7 @@ encode_video_example_deps="avcodec avutil" filter_audio_example_deps="avfilter avutil" metadata_example_deps="avformat avutil" output_example_deps="avcodec avformat avutil swscale" -qsvdec_example_deps="avcodec avutil libmfx h264_qsv_decoder vaapi_x11" +qsvdec_example_deps="avcodec avutil libmfx h264_qsv_decoder" transcode_aac_example_deps="avcodec avformat avresample" # libraries, in linking order diff --git a/doc/examples/qsvdec.c b/doc/examples/qsvdec.c index aaecd81d4ca52..141c581f7f7e8 100644 --- a/doc/examples/qsvdec.c +++ b/doc/examples/qsvdec.c @@ -26,185 +26,55 @@ * * @example qsvdec.c * This example shows how to do QSV-accelerated H.264 decoding with output - * frames in the VA-API video surfaces. + * frames in the GPU video surfaces. */ #include "config.h" #include -#include - -#include -#include -#include - #include "libavformat/avformat.h" #include "libavformat/avio.h" #include "libavcodec/avcodec.h" -#include "libavcodec/qsv.h" +#include "libavutil/buffer.h" #include "libavutil/error.h" +#include "libavutil/hwcontext.h" +#include "libavutil/hwcontext_qsv.h" #include "libavutil/mem.h" typedef struct DecodeContext { - mfxSession mfx_session; - VADisplay va_dpy; - - VASurfaceID *surfaces; - mfxMemId *surface_ids; - int *surface_used; - int nb_surfaces; - - mfxFrameInfo frame_info; + AVBufferRef *hw_device_ref; } DecodeContext; -static mfxStatus frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req, - mfxFrameAllocResponse *resp) -{ - DecodeContext *decode = pthis; - int err, i; - - if (decode->surfaces) { - fprintf(stderr, "Multiple allocation requests.\n"); - return MFX_ERR_MEMORY_ALLOC; - } - if (!(req->Type & MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET)) { - fprintf(stderr, "Unsupported surface type: %d\n", req->Type); - return MFX_ERR_UNSUPPORTED; - } - if (req->Info.BitDepthLuma != 8 || req->Info.BitDepthChroma != 8 || - req->Info.Shift || req->Info.FourCC != MFX_FOURCC_NV12 || - req->Info.ChromaFormat != MFX_CHROMAFORMAT_YUV420) { - fprintf(stderr, "Unsupported surface properties.\n"); - return MFX_ERR_UNSUPPORTED; - } - - decode->surfaces = av_malloc_array (req->NumFrameSuggested, sizeof(*decode->surfaces)); - decode->surface_ids = av_malloc_array (req->NumFrameSuggested, sizeof(*decode->surface_ids)); - decode->surface_used = av_mallocz_array(req->NumFrameSuggested, sizeof(*decode->surface_used)); - if (!decode->surfaces || !decode->surface_ids || !decode->surface_used) - goto fail; - - err = vaCreateSurfaces(decode->va_dpy, VA_RT_FORMAT_YUV420, - req->Info.Width, req->Info.Height, - decode->surfaces, req->NumFrameSuggested, - NULL, 0); - if (err != VA_STATUS_SUCCESS) { - fprintf(stderr, "Error allocating VA surfaces\n"); - goto fail; - } - decode->nb_surfaces = req->NumFrameSuggested; - - for (i = 0; i < decode->nb_surfaces; i++) - decode->surface_ids[i] = &decode->surfaces[i]; - - resp->mids = decode->surface_ids; - resp->NumFrameActual = decode->nb_surfaces; - - decode->frame_info = req->Info; - - return MFX_ERR_NONE; -fail: - av_freep(&decode->surfaces); - av_freep(&decode->surface_ids); - av_freep(&decode->surface_used); - - return MFX_ERR_MEMORY_ALLOC; -} - -static mfxStatus frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp) -{ - return MFX_ERR_NONE; -} - -static mfxStatus frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) -{ - return MFX_ERR_UNSUPPORTED; -} - -static mfxStatus frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) -{ - return MFX_ERR_UNSUPPORTED; -} - -static mfxStatus frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl) -{ - *hdl = mid; - return MFX_ERR_NONE; -} - -static void free_surfaces(DecodeContext *decode) -{ - if (decode->surfaces) - vaDestroySurfaces(decode->va_dpy, decode->surfaces, decode->nb_surfaces); - av_freep(&decode->surfaces); - av_freep(&decode->surface_ids); - av_freep(&decode->surface_used); - decode->nb_surfaces = 0; -} - -static void free_buffer(void *opaque, uint8_t *data) -{ - int *used = opaque; - *used = 0; - av_freep(&data); -} - -static int get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) -{ - DecodeContext *decode = avctx->opaque; - - mfxFrameSurface1 *surf; - AVBufferRef *surf_buf; - int idx; - - for (idx = 0; idx < decode->nb_surfaces; idx++) { - if (!decode->surface_used[idx]) - break; - } - if (idx == decode->nb_surfaces) { - fprintf(stderr, "No free surfaces\n"); - return AVERROR(ENOMEM); - } - - surf = av_mallocz(sizeof(*surf)); - if (!surf) - return AVERROR(ENOMEM); - surf_buf = av_buffer_create((uint8_t*)surf, sizeof(*surf), free_buffer, - &decode->surface_used[idx], AV_BUFFER_FLAG_READONLY); - if (!surf_buf) { - av_freep(&surf); - return AVERROR(ENOMEM); - } - - surf->Info = decode->frame_info; - surf->Data.MemId = &decode->surfaces[idx]; - - frame->buf[0] = surf_buf; - frame->data[3] = (uint8_t*)surf; - - decode->surface_used[idx] = 1; - - return 0; -} - static int get_format(AVCodecContext *avctx, const enum AVPixelFormat *pix_fmts) { while (*pix_fmts != AV_PIX_FMT_NONE) { if (*pix_fmts == AV_PIX_FMT_QSV) { - if (!avctx->hwaccel_context) { - DecodeContext *decode = avctx->opaque; - AVQSVContext *qsv = av_qsv_alloc_context(); - if (!qsv) - return AV_PIX_FMT_NONE; - - qsv->session = decode->mfx_session; - qsv->iopattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY; - - avctx->hwaccel_context = qsv; - } + DecodeContext *decode = avctx->opaque; + AVHWFramesContext *frames_ctx; + AVQSVFramesContext *frames_hwctx; + int ret; + + /* create a pool of surfaces to be used by the decoder */ + avctx->hw_frames_ctx = av_hwframe_ctx_alloc(decode->hw_device_ref); + if (!avctx->hw_frames_ctx) + return AV_PIX_FMT_NONE; + frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; + frames_hwctx = frames_ctx->hwctx; + + frames_ctx->format = AV_PIX_FMT_QSV; + frames_ctx->sw_format = avctx->sw_pix_fmt; + frames_ctx->width = FFALIGN(avctx->coded_width, 32); + frames_ctx->height = FFALIGN(avctx->coded_height, 32); + frames_ctx->initial_pool_size = 32; + + frames_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; + + ret = av_hwframe_ctx_init(avctx->hw_frames_ctx); + if (ret < 0) + return AV_PIX_FMT_NONE; return AV_PIX_FMT_QSV; } @@ -218,8 +88,8 @@ static int get_format(AVCodecContext *avctx, const enum AVPixelFormat *pix_fmts) } static int decode_packet(DecodeContext *decode, AVCodecContext *decoder_ctx, - AVFrame *frame, AVPacket *pkt, - AVIOContext *output_ctx) + AVFrame *frame, AVFrame *sw_frame, + AVPacket *pkt, AVIOContext *output_ctx) { int ret = 0; int got_frame = 1; @@ -238,61 +108,20 @@ static int decode_packet(DecodeContext *decode, AVCodecContext *decoder_ctx, * We just retrieve the raw data and write it to a file, which is rather * useless but pedagogic. */ if (got_frame) { - mfxFrameSurface1 *surf = (mfxFrameSurface1*)frame->data[3]; - VASurfaceID surface = *(VASurfaceID*)surf->Data.MemId; - - VAImageFormat img_fmt = { - .fourcc = VA_FOURCC_NV12, - .byte_order = VA_LSB_FIRST, - .bits_per_pixel = 8, - .depth = 8, - }; - - VAImage img; - - VAStatus err; - uint8_t *data; int i, j; - img.buf = VA_INVALID_ID; - img.image_id = VA_INVALID_ID; - - err = vaCreateImage(decode->va_dpy, &img_fmt, - frame->width, frame->height, &img); - if (err != VA_STATUS_SUCCESS) { - fprintf(stderr, "Error creating an image: %s\n", - vaErrorStr(err)); - ret = AVERROR_UNKNOWN; + ret = av_hwframe_transfer_data(sw_frame, frame, 0); + if (ret < 0) { + fprintf(stderr, "Error transferring the data to system memory\n"); goto fail; } - err = vaGetImage(decode->va_dpy, surface, 0, 0, - frame->width, frame->height, - img.image_id); - if (err != VA_STATUS_SUCCESS) { - fprintf(stderr, "Error getting an image: %s\n", - vaErrorStr(err)); - ret = AVERROR_UNKNOWN; - goto fail; - } - - err = vaMapBuffer(decode->va_dpy, img.buf, (void**)&data); - if (err != VA_STATUS_SUCCESS) { - fprintf(stderr, "Error mapping the image buffer: %s\n", - vaErrorStr(err)); - ret = AVERROR_UNKNOWN; - goto fail; - } - - for (i = 0; i < img.num_planes; i++) - for (j = 0; j < (img.height >> (i > 0)); j++) - avio_write(output_ctx, data + img.offsets[i] + j * img.pitches[i], img.width); + for (i = 0; i < FF_ARRAY_ELEMS(sw_frame->data) && sw_frame->data[i]; i++) + for (j = 0; j < (sw_frame->height >> (i > 0)); j++) + avio_write(output_ctx, sw_frame->data[i] + j * sw_frame->linesize[i], sw_frame->width); fail: - if (img.buf != VA_INVALID_ID) - vaUnmapBuffer(decode->va_dpy, img.buf); - if (img.image_id != VA_INVALID_ID) - vaDestroyImage(decode->va_dpy, img.image_id); + av_frame_unref(sw_frame); av_frame_unref(frame); if (ret < 0) @@ -311,28 +140,13 @@ int main(int argc, char **argv) const AVCodec *decoder; AVPacket pkt = { 0 }; - AVFrame *frame = NULL; + AVFrame *frame = NULL, *sw_frame = NULL; DecodeContext decode = { NULL }; - Display *dpy = NULL; - int va_ver_major, va_ver_minor; - - mfxIMPL mfx_impl = MFX_IMPL_AUTO_ANY; - mfxVersion mfx_ver = { { 1, 1 } }; - - mfxFrameAllocator frame_allocator = { - .pthis = &decode, - .Alloc = frame_alloc, - .Lock = frame_lock, - .Unlock = frame_unlock, - .GetHDL = frame_get_hdl, - .Free = frame_free, - }; - AVIOContext *output_ctx = NULL; - int ret, i, err; + int ret, i; av_register_all(); @@ -362,35 +176,14 @@ int main(int argc, char **argv) goto finish; } - /* initialize VA-API */ - dpy = XOpenDisplay(NULL); - if (!dpy) { - fprintf(stderr, "Cannot open the X display\n"); - goto finish; - } - decode.va_dpy = vaGetDisplay(dpy); - if (!decode.va_dpy) { - fprintf(stderr, "Cannot open the VA display\n"); - goto finish; - } - - err = vaInitialize(decode.va_dpy, &va_ver_major, &va_ver_minor); - if (err != VA_STATUS_SUCCESS) { - fprintf(stderr, "Cannot initialize VA: %s\n", vaErrorStr(err)); - goto finish; - } - fprintf(stderr, "Initialized VA v%d.%d\n", va_ver_major, va_ver_minor); - - /* initialize an MFX session */ - err = MFXInit(mfx_impl, &mfx_ver, &decode.mfx_session); - if (err != MFX_ERR_NONE) { - fprintf(stderr, "Error initializing an MFX session\n"); + /* open the hardware device */ + ret = av_hwdevice_ctx_create(&decode.hw_device_ref, AV_HWDEVICE_TYPE_QSV, + "auto", NULL, 0); + if (ret < 0) { + fprintf(stderr, "Cannot open the hardware device\n"); goto finish; } - MFXVideoCORE_SetHandle(decode.mfx_session, MFX_HANDLE_VA_DISPLAY, decode.va_dpy); - MFXVideoCORE_SetFrameAllocator(decode.mfx_session, &frame_allocator); - /* initialize the decoder */ decoder = avcodec_find_decoder_by_name("h264_qsv"); if (!decoder) { @@ -418,7 +211,6 @@ int main(int argc, char **argv) decoder_ctx->refcounted_frames = 1; decoder_ctx->opaque = &decode; - decoder_ctx->get_buffer2 = get_buffer; decoder_ctx->get_format = get_format; ret = avcodec_open2(decoder_ctx, NULL, NULL); @@ -434,8 +226,9 @@ int main(int argc, char **argv) goto finish; } - frame = av_frame_alloc(); - if (!frame) { + frame = av_frame_alloc(); + sw_frame = av_frame_alloc(); + if (!frame || !sw_frame) { ret = AVERROR(ENOMEM); goto finish; } @@ -447,7 +240,7 @@ int main(int argc, char **argv) break; if (pkt.stream_index == video_st->index) - ret = decode_packet(&decode, decoder_ctx, frame, &pkt, output_ctx); + ret = decode_packet(&decode, decoder_ctx, frame, sw_frame, &pkt, output_ctx); av_packet_unref(&pkt); } @@ -455,7 +248,7 @@ int main(int argc, char **argv) /* flush the decoder */ pkt.data = NULL; pkt.size = 0; - ret = decode_packet(&decode, decoder_ctx, frame, &pkt, output_ctx); + ret = decode_packet(&decode, decoder_ctx, frame, sw_frame, &pkt, output_ctx); finish: if (ret < 0) { @@ -467,19 +260,11 @@ int main(int argc, char **argv) avformat_close_input(&input_ctx); av_frame_free(&frame); + av_frame_free(&sw_frame); - if (decoder_ctx) - av_freep(&decoder_ctx->hwaccel_context); avcodec_free_context(&decoder_ctx); - free_surfaces(&decode); - - if (decode.mfx_session) - MFXClose(decode.mfx_session); - if (decode.va_dpy) - vaTerminate(decode.va_dpy); - if (dpy) - XCloseDisplay(dpy); + av_buffer_unref(&decode.hw_device_ref); avio_close(output_ctx); From 44c9f374f188f92927b7a4aad2101289d446b814 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 12 Oct 2016 14:16:47 +0200 Subject: [PATCH 0546/3374] examples/qsvdec: convert to the new decoding API --- doc/examples/qsvdec.c | 48 ++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/doc/examples/qsvdec.c b/doc/examples/qsvdec.c index 141c581f7f7e8..46e6ddcb0dc63 100644 --- a/doc/examples/qsvdec.c +++ b/doc/examples/qsvdec.c @@ -92,41 +92,43 @@ static int decode_packet(DecodeContext *decode, AVCodecContext *decoder_ctx, AVPacket *pkt, AVIOContext *output_ctx) { int ret = 0; - int got_frame = 1; - while (pkt->size > 0 || (!pkt->data && got_frame)) { - ret = avcodec_decode_video2(decoder_ctx, frame, &got_frame, pkt); - if (ret < 0) { + ret = avcodec_send_packet(decoder_ctx, pkt); + if (ret < 0) { + fprintf(stderr, "Error during decoding\n"); + return ret; + } + + while (ret >= 0) { + int i, j; + + ret = avcodec_receive_frame(decoder_ctx, frame); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + break; + else if (ret < 0) { fprintf(stderr, "Error during decoding\n"); return ret; } - pkt->data += ret; - pkt->size -= ret; - /* A real program would do something useful with the decoded frame here. * We just retrieve the raw data and write it to a file, which is rather * useless but pedagogic. */ - if (got_frame) { - int i, j; - - ret = av_hwframe_transfer_data(sw_frame, frame, 0); - if (ret < 0) { - fprintf(stderr, "Error transferring the data to system memory\n"); - goto fail; - } + ret = av_hwframe_transfer_data(sw_frame, frame, 0); + if (ret < 0) { + fprintf(stderr, "Error transferring the data to system memory\n"); + goto fail; + } - for (i = 0; i < FF_ARRAY_ELEMS(sw_frame->data) && sw_frame->data[i]; i++) - for (j = 0; j < (sw_frame->height >> (i > 0)); j++) - avio_write(output_ctx, sw_frame->data[i] + j * sw_frame->linesize[i], sw_frame->width); + for (i = 0; i < FF_ARRAY_ELEMS(sw_frame->data) && sw_frame->data[i]; i++) + for (j = 0; j < (sw_frame->height >> (i > 0)); j++) + avio_write(output_ctx, sw_frame->data[i] + j * sw_frame->linesize[i], sw_frame->width); fail: - av_frame_unref(sw_frame); - av_frame_unref(frame); + av_frame_unref(sw_frame); + av_frame_unref(frame); - if (ret < 0) - return ret; - } + if (ret < 0) + return ret; } return 0; From f27e262dbdea1991b22e08b639ac03e642a3482c Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 19 Oct 2016 21:33:52 +0200 Subject: [PATCH 0547/3374] examples/encode_audio: switch to the new audio encoding API --- doc/examples/encode_audio.c | 59 +++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/doc/examples/encode_audio.c b/doc/examples/encode_audio.c index db2440f8fa85e..a32fcc9004d4d 100644 --- a/doc/examples/encode_audio.c +++ b/doc/examples/encode_audio.c @@ -89,14 +89,42 @@ static int select_channel_layout(const AVCodec *codec) return best_ch_layout; } +static void encode(AVCodecContext *ctx, AVFrame *frame, AVPacket *pkt, + FILE *output) +{ + int ret; + + /* send the frame for encoding */ + ret = avcodec_send_frame(ctx, frame); + if (ret < 0) { + fprintf(stderr, "error sending the frame to the encoder\n"); + exit(1); + } + + /* read all the available output packets (in general there may be any + * number of them */ + while (ret >= 0) { + ret = avcodec_receive_packet(ctx, pkt); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + return; + else if (ret < 0) { + fprintf(stderr, "error encoding audio frame\n"); + exit(1); + } + + fwrite(pkt->data, 1, pkt->size, output); + av_packet_unref(pkt); + } +} + int main(int argc, char **argv) { const char *filename; const AVCodec *codec; AVCodecContext *c= NULL; AVFrame *frame; - AVPacket pkt; - int i, j, k, ret, got_output; + AVPacket *pkt; + int i, j, k, ret; FILE *f; uint16_t *samples; float t, tincr; @@ -147,6 +175,13 @@ int main(int argc, char **argv) exit(1); } + /* packet for holding encoded output */ + pkt = av_packet_alloc(); + if (!pkt) { + fprintf(stderr, "could not allocate the packet\n"); + exit(1); + } + /* frame containing input raw audio */ frame = av_frame_alloc(); if (!frame) { @@ -169,10 +204,6 @@ int main(int argc, char **argv) t = 0; tincr = 2 * M_PI * 440.0 / c->sample_rate; for(i=0;i<200;i++) { - av_init_packet(&pkt); - pkt.data = NULL; // packet data will be allocated by the encoder - pkt.size = 0; - /* make sure the frame is writable -- makes a copy if the encoder * kept a reference internally */ ret = av_frame_make_writable(frame); @@ -187,19 +218,15 @@ int main(int argc, char **argv) samples[2*j + k] = samples[2*j]; t += tincr; } - /* encode the samples */ - ret = avcodec_encode_audio2(c, &pkt, frame, &got_output); - if (ret < 0) { - fprintf(stderr, "error encoding audio frame\n"); - exit(1); - } - if (got_output) { - fwrite(pkt.data, 1, pkt.size, f); - av_packet_unref(&pkt); - } + encode(c, frame, pkt, f); } + + /* flush the encoder */ + encode(c, NULL, pkt, f); + fclose(f); av_frame_free(&frame); + av_packet_free(&pkt); avcodec_free_context(&c); } From 0946c754d99c05413e813ee515039adcf0f9232a Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 19 Oct 2016 21:56:22 +0200 Subject: [PATCH 0548/3374] examples/decode_audio: use a parser for splitting the input Do not rely on the decoder handling this, as it's not guaranteed to work. --- doc/examples/decode_audio.c | 82 ++++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 28 deletions(-) diff --git a/doc/examples/decode_audio.c b/doc/examples/decode_audio.c index b56a5ee7f2925..d2150a67c14e4 100644 --- a/doc/examples/decode_audio.c +++ b/doc/examples/decode_audio.c @@ -37,14 +37,40 @@ #define AUDIO_INBUF_SIZE 20480 #define AUDIO_REFILL_THRESH 4096 +static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, + FILE *outfile) +{ + int len, got_frame; + + while (pkt->size > 0) { + len = avcodec_decode_audio4(dec_ctx, frame, &got_frame, pkt); + if (len < 0) { + fprintf(stderr, "Error while decoding\n"); + exit(1); + } + if (got_frame) { + /* if a frame has been decoded, output it */ + int data_size = av_samples_get_buffer_size(NULL, dec_ctx->channels, + frame->nb_samples, + dec_ctx->sample_fmt, 1); + fwrite(frame->data[0], 1, data_size, outfile); + } + pkt->size -= len; + pkt->data += len; + } +} + int main(int argc, char **argv) { const char *outfilename, *filename; const AVCodec *codec; AVCodecContext *c= NULL; - int len; + AVCodecParserContext *parser = NULL; + int len, ret; FILE *f, *outfile; uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; + uint8_t *data; + size_t data_size; AVPacket avpkt; AVFrame *decoded_frame = NULL; @@ -67,6 +93,12 @@ int main(int argc, char **argv) exit(1); } + parser = av_parser_init(codec->id); + if (!parser) { + fprintf(stderr, "parser not found\n"); + exit(1); + } + c = avcodec_alloc_context3(codec); /* open it */ @@ -87,12 +119,10 @@ int main(int argc, char **argv) } /* decode until eof */ - avpkt.data = inbuf; - avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f); - - while (avpkt.size > 0) { - int got_frame = 0; + data = inbuf; + data_size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f); + while (data_size > 0) { if (!decoded_frame) { if (!(decoded_frame = av_frame_alloc())) { fprintf(stderr, "out of memory\n"); @@ -100,31 +130,26 @@ int main(int argc, char **argv) } } - len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt); - if (len < 0) { - fprintf(stderr, "Error while decoding\n"); + ret = av_parser_parse2(parser, c, &avpkt.data, &avpkt.size, + data, data_size, + AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0); + if (ret < 0) { + fprintf(stderr, "Error while parsing\n"); exit(1); } - if (got_frame) { - /* if a frame has been decoded, output it */ - int data_size = av_samples_get_buffer_size(NULL, c->channels, - decoded_frame->nb_samples, - c->sample_fmt, 1); - fwrite(decoded_frame->data[0], 1, data_size, outfile); - } - avpkt.size -= len; - avpkt.data += len; - if (avpkt.size < AUDIO_REFILL_THRESH) { - /* Refill the input buffer, to avoid trying to decode - * incomplete frames. Instead of this, one could also use - * a parser, or use a proper container format through - * libavformat. */ - memmove(inbuf, avpkt.data, avpkt.size); - avpkt.data = inbuf; - len = fread(avpkt.data + avpkt.size, 1, - AUDIO_INBUF_SIZE - avpkt.size, f); + data += ret; + data_size -= ret; + + if (avpkt.size) + decode(c, &avpkt, decoded_frame, outfile); + + if (data_size < AUDIO_REFILL_THRESH) { + memmove(inbuf, data, data_size); + data = inbuf; + len = fread(data + data_size, 1, + AUDIO_INBUF_SIZE - data_size, f); if (len > 0) - avpkt.size += len; + data_size += len; } } @@ -132,6 +157,7 @@ int main(int argc, char **argv) fclose(f); avcodec_free_context(&c); + av_parser_close(parser); av_frame_free(&decoded_frame); return 0; From 3d66717f7cb5555257244be8f5bce172ed3af7ac Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 19 Oct 2016 21:56:22 +0200 Subject: [PATCH 0549/3374] examples/decode_audio: use the new audio decoding API --- doc/examples/decode_audio.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/doc/examples/decode_audio.c b/doc/examples/decode_audio.c index d2150a67c14e4..5e128f8f19aa8 100644 --- a/doc/examples/decode_audio.c +++ b/doc/examples/decode_audio.c @@ -40,23 +40,29 @@ static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile) { - int len, got_frame; + int ret, data_size; - while (pkt->size > 0) { - len = avcodec_decode_audio4(dec_ctx, frame, &got_frame, pkt); - if (len < 0) { - fprintf(stderr, "Error while decoding\n"); + /* send the packet with the compressed data to the decoder */ + ret = avcodec_send_packet(dec_ctx, pkt); + if (ret < 0) { + fprintf(stderr, "Error submitting the packet to the decoder\n"); + exit(1); + } + + /* read all the output frames (in general there may be any number of them */ + while (ret >= 0) { + ret = avcodec_receive_frame(dec_ctx, frame); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + return; + else if (ret < 0) { + fprintf(stderr, "Error during decoding\n"); exit(1); } - if (got_frame) { - /* if a frame has been decoded, output it */ - int data_size = av_samples_get_buffer_size(NULL, dec_ctx->channels, - frame->nb_samples, - dec_ctx->sample_fmt, 1); - fwrite(frame->data[0], 1, data_size, outfile); - } - pkt->size -= len; - pkt->data += len; + + data_size = av_samples_get_buffer_size(NULL, dec_ctx->channels, + frame->nb_samples, + dec_ctx->sample_fmt, 1); + fwrite(frame->data[0], 1, data_size, outfile); } } From 45a1ce2ff7688656aacd53c27de5815a7ec13afe Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 19 Oct 2016 21:56:22 +0200 Subject: [PATCH 0550/3374] examples/decode_audio: handle planar audio now produced by the MP2 decoder --- doc/examples/decode_audio.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/doc/examples/decode_audio.c b/doc/examples/decode_audio.c index 5e128f8f19aa8..c00d4888b2c2e 100644 --- a/doc/examples/decode_audio.c +++ b/doc/examples/decode_audio.c @@ -29,6 +29,7 @@ #include #include +#include "libavutil/channel_layout.h" #include "libavutil/frame.h" #include "libavutil/mem.h" @@ -40,7 +41,8 @@ static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile) { - int ret, data_size; + int16_t *interleave_buf; + int ret, data_size, i; /* send the packet with the compressed data to the decoder */ ret = avcodec_send_packet(dec_ctx, pkt); @@ -59,10 +61,28 @@ static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, exit(1); } - data_size = av_samples_get_buffer_size(NULL, dec_ctx->channels, - frame->nb_samples, - dec_ctx->sample_fmt, 1); - fwrite(frame->data[0], 1, data_size, outfile); + /* the stream parameters may change at any time, check that they are + * what we expect */ + if (av_get_channel_layout_nb_channels(frame->channel_layout) != 2 || + frame->format != AV_SAMPLE_FMT_S16P) { + fprintf(stderr, "Unsupported frame parameters\n"); + exit(1); + } + + /* The decoded data is signed 16-bit planar -- each channel in its own + * buffer. We interleave the two channels manually here, but using + * libavresample is recommended instead. */ + data_size = sizeof(*interleave_buf) * 2 * frame->nb_samples; + interleave_buf = av_malloc(data_size); + if (!interleave_buf) + exit(1); + + for (i = 0; i < frame->nb_samples; i++) { + interleave_buf[2 * i] = ((int16_t*)frame->data[0])[i]; + interleave_buf[2 * i + 1] = ((int16_t*)frame->data[1])[i]; + } + fwrite(interleave_buf, 1, data_size, outfile); + av_freep(&interleave_buf); } } From 9a38184a143a1560814b084aebe628f8df46e666 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 19 Oct 2016 21:56:22 +0200 Subject: [PATCH 0551/3374] examples/decode_audio: allocate the packet dynamically AVPackets on stack are discouraged now. --- doc/examples/decode_audio.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/doc/examples/decode_audio.c b/doc/examples/decode_audio.c index c00d4888b2c2e..e7b27d3ada414 100644 --- a/doc/examples/decode_audio.c +++ b/doc/examples/decode_audio.c @@ -97,7 +97,7 @@ int main(int argc, char **argv) uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; uint8_t *data; size_t data_size; - AVPacket avpkt; + AVPacket *pkt; AVFrame *decoded_frame = NULL; if (argc <= 2) { @@ -110,7 +110,7 @@ int main(int argc, char **argv) /* register all the codecs */ avcodec_register_all(); - av_init_packet(&avpkt); + pkt = av_packet_alloc(); /* find the MPEG audio decoder */ codec = avcodec_find_decoder(AV_CODEC_ID_MP2); @@ -156,7 +156,7 @@ int main(int argc, char **argv) } } - ret = av_parser_parse2(parser, c, &avpkt.data, &avpkt.size, + ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size, data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0); if (ret < 0) { @@ -166,8 +166,8 @@ int main(int argc, char **argv) data += ret; data_size -= ret; - if (avpkt.size) - decode(c, &avpkt, decoded_frame, outfile); + if (pkt->size) + decode(c, pkt, decoded_frame, outfile); if (data_size < AUDIO_REFILL_THRESH) { memmove(inbuf, data, data_size); @@ -185,6 +185,7 @@ int main(int argc, char **argv) avcodec_free_context(&c); av_parser_close(parser); av_frame_free(&decoded_frame); + av_packet_free(&pkt); return 0; } From fee0f1de2c6a9924acb74013436dbea8f2bd1ecb Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 19 Oct 2016 21:56:22 +0200 Subject: [PATCH 0552/3374] examples/decode_audio: flush the decoder --- doc/examples/decode_audio.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/examples/decode_audio.c b/doc/examples/decode_audio.c index e7b27d3ada414..d952b4923b982 100644 --- a/doc/examples/decode_audio.c +++ b/doc/examples/decode_audio.c @@ -179,6 +179,11 @@ int main(int argc, char **argv) } } + /* flush the decoder */ + pkt->data = NULL; + pkt->size = 0; + decode(c, pkt, decoded_frame, outfile); + fclose(outfile); fclose(f); From 5f102a9559099429826e84758b8b5182244c52db Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 20 Oct 2016 11:03:20 +0200 Subject: [PATCH 0553/3374] examples/encode_video: switch to the new encoding API --- doc/examples/encode_video.c | 59 +++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/doc/examples/encode_video.c b/doc/examples/encode_video.c index 3fd2d562a3b81..2ff6354354d31 100644 --- a/doc/examples/encode_video.c +++ b/doc/examples/encode_video.c @@ -34,12 +34,39 @@ #include "libavutil/frame.h" #include "libavutil/imgutils.h" +static void encode(AVCodecContext *enc_ctx, AVFrame *frame, AVPacket *pkt, + FILE *outfile) +{ + int ret; + + /* send the frame to the encoder */ + ret = avcodec_send_frame(enc_ctx, frame); + if (ret < 0) { + fprintf(stderr, "error sending a frame for encoding\n"); + exit(1); + } + + while (ret >= 0) { + ret = avcodec_receive_packet(enc_ctx, pkt); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + return; + else if (ret < 0) { + fprintf(stderr, "error during encoding\n"); + exit(1); + } + + printf("encoded frame %3"PRId64" (size=%5d)\n", pkt->pts, pkt->size); + fwrite(pkt->data, 1, pkt->size, outfile); + av_packet_unref(pkt); + } +} + int main(int argc, char **argv) { const char *filename; const AVCodec *codec; AVCodecContext *c= NULL; - int i, ret, x, y, got_output; + int i, ret, x, y; FILE *f; AVFrame *picture; AVPacket pkt; @@ -130,35 +157,11 @@ int main(int argc, char **argv) picture->pts = i; /* encode the image */ - ret = avcodec_encode_video2(c, &pkt, picture, &got_output); - if (ret < 0) { - fprintf(stderr, "error encoding frame\n"); - exit(1); - } - - if (got_output) { - printf("encoding frame %3d (size=%5d)\n", i, pkt.size); - fwrite(pkt.data, 1, pkt.size, f); - av_packet_unref(&pkt); - } + encode(c, picture, &pkt, f); } - /* get the delayed frames */ - for (got_output = 1; got_output; i++) { - fflush(stdout); - - ret = avcodec_encode_video2(c, &pkt, NULL, &got_output); - if (ret < 0) { - fprintf(stderr, "error encoding frame\n"); - exit(1); - } - - if (got_output) { - printf("encoding frame %3d (size=%5d)\n", i, pkt.size); - fwrite(pkt.data, 1, pkt.size, f); - av_packet_unref(&pkt); - } - } + /* flush the encoder */ + encode(c, NULL, &pkt, f); /* add sequence end code to have a real MPEG file */ fwrite(endcode, 1, sizeof(endcode), f); From 59ab9e8ba1df7e3347a4cd2bd56c32e74aede802 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 20 Oct 2016 11:03:20 +0200 Subject: [PATCH 0554/3374] examples/encode_video: allocate the packet dynamically AVPackets on stack are discouraged. --- doc/examples/encode_video.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/doc/examples/encode_video.c b/doc/examples/encode_video.c index 2ff6354354d31..cb128361d53aa 100644 --- a/doc/examples/encode_video.c +++ b/doc/examples/encode_video.c @@ -69,7 +69,7 @@ int main(int argc, char **argv) int i, ret, x, y; FILE *f; AVFrame *picture; - AVPacket pkt; + AVPacket *pkt; uint8_t endcode[] = { 0, 0, 1, 0xb7 }; if (argc <= 1) { @@ -90,6 +90,10 @@ int main(int argc, char **argv) c = avcodec_alloc_context3(codec); picture = av_frame_alloc(); + pkt = av_packet_alloc(); + if (!pkt) + exit(1); + /* put sample parameters */ c->bit_rate = 400000; /* resolution must be a multiple of two */ @@ -127,10 +131,6 @@ int main(int argc, char **argv) /* encode 1 second of video */ for(i=0;i<25;i++) { - av_init_packet(&pkt); - pkt.data = NULL; // packet data will be allocated by the encoder - pkt.size = 0; - fflush(stdout); /* make sure the frame data is writable */ @@ -157,11 +157,11 @@ int main(int argc, char **argv) picture->pts = i; /* encode the image */ - encode(c, picture, &pkt, f); + encode(c, picture, pkt, f); } /* flush the encoder */ - encode(c, NULL, &pkt, f); + encode(c, NULL, pkt, f); /* add sequence end code to have a real MPEG file */ fwrite(endcode, 1, sizeof(endcode), f); @@ -169,6 +169,7 @@ int main(int argc, char **argv) avcodec_free_context(&c); av_frame_free(&picture); + av_packet_free(&pkt); return 0; } From f78d360bba6dcfb585847a49a84e89c25950fbdb Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 19 Oct 2016 21:56:22 +0200 Subject: [PATCH 0555/3374] examples/decode_video: use a parser for splitting the input Do not rely on the decoder handling this, as it's not guaranteed to work. --- doc/examples/decode_video.c | 113 ++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 57 deletions(-) diff --git a/doc/examples/decode_video.c b/doc/examples/decode_video.c index 43819ecc6c9b8..4c1068bef339e 100644 --- a/doc/examples/decode_video.c +++ b/doc/examples/decode_video.c @@ -50,16 +50,45 @@ static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize, fclose(f); } +static void decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt, + const char *filename) +{ + char buf[1024]; + int ret, got_picture; + + while (pkt->size > 0) { + ret = avcodec_decode_video2(dec_ctx, frame, &got_picture, pkt); + if (ret < 0) { + fprintf(stderr, "Error while decoding frame %d\n", dec_ctx->frame_number); + exit(1); + } + if (got_picture) { + printf("saving frame %3d\n", dec_ctx->frame_number); + fflush(stdout); + + /* the picture is allocated by the decoder. no need to + free it */ + snprintf(buf, sizeof(buf), filename, dec_ctx->frame_number); + pgm_save(frame->data[0], frame->linesize[0], + frame->width, frame->height, buf); + } + pkt->size -= ret; + pkt->data += ret; + } +} + int main(int argc, char **argv) { const char *filename, *outfilename; const AVCodec *codec; + AVCodecParserContext *parser; AVCodecContext *c= NULL; - int frame, got_picture, len; FILE *f; AVFrame *picture; uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; - char buf[1024]; + uint8_t *data; + size_t data_size; + int ret; AVPacket avpkt; if (argc <= 2) { @@ -83,12 +112,15 @@ int main(int argc, char **argv) exit(1); } + parser = av_parser_init(codec->id); + if (!parser) { + fprintf(stderr, "parser not found\n"); + exit(1); + } + c = avcodec_alloc_context3(codec); picture = av_frame_alloc(); - if (codec->capabilities & AV_CODEC_CAP_TRUNCATED) - c->flags |= AV_CODEC_FLAG_TRUNCATED; // we do not send complete frames - /* For some codecs, such as msmpeg4 and mpeg4, width and height MUST be initialized there because this information is not available in the bitstream. */ @@ -105,70 +137,37 @@ int main(int argc, char **argv) exit(1); } - frame = 0; - for(;;) { - avpkt.size = fread(inbuf, 1, INBUF_SIZE, f); - if (avpkt.size == 0) + while (!feof(f)) { + /* read raw data from the input file */ + data_size = fread(inbuf, 1, INBUF_SIZE, f); + if (!data_size) break; - /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio) - and this is the only method to use them because you cannot - know the compressed data size before analysing it. - - BUT some other codecs (msmpeg4, mpeg4) are inherently frame - based, so you must call them with all the data for one - frame exactly. You must also initialize 'width' and - 'height' before initializing them. */ - - /* NOTE2: some codecs allow the raw parameters (frame size, - sample rate) to be changed at any frame. We handle this, so - you should also take care of it */ - - /* here, we use a stream based decoder (mpeg1video), so we - feed decoder and see if it could decode a frame */ - avpkt.data = inbuf; - while (avpkt.size > 0) { - len = avcodec_decode_video2(c, picture, &got_picture, &avpkt); - if (len < 0) { - fprintf(stderr, "Error while decoding frame %d\n", frame); + /* use the parser to split the data into frames */ + data = inbuf; + while (data_size > 0) { + ret = av_parser_parse2(parser, c, &avpkt.data, &avpkt.size, + data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0); + if (ret < 0) { + fprintf(stderr, "Error while parsing\n"); exit(1); } - if (got_picture) { - printf("saving frame %3d\n", frame); - fflush(stdout); - - /* the picture is allocated by the decoder. no need to - free it */ - snprintf(buf, sizeof(buf), outfilename, frame); - pgm_save(picture->data[0], picture->linesize[0], - c->width, c->height, buf); - frame++; - } - avpkt.size -= len; - avpkt.data += len; + data += ret; + data_size -= ret; + + if (avpkt.size) + decode(c, picture, &avpkt, outfilename); } } - /* Some codecs, such as MPEG, transmit the I- and P-frame with a - latency of one frame. You must do the following to have a - chance to get the last frame of the video. */ + /* flush the decoder */ avpkt.data = NULL; avpkt.size = 0; - len = avcodec_decode_video2(c, picture, &got_picture, &avpkt); - if (got_picture) { - printf("saving last frame %3d\n", frame); - fflush(stdout); - - /* the picture is allocated by the decoder. no need to - free it */ - snprintf(buf, sizeof(buf), outfilename, frame); - pgm_save(picture->data[0], picture->linesize[0], - c->width, c->height, buf); - frame++; - } + decode(c, picture, &avpkt, outfilename); fclose(f); + av_parser_close(parser); avcodec_free_context(&c); av_frame_free(&picture); From 728ea23cce07467b732f538c87c13da13dd6dcf3 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 19 Oct 2016 21:56:22 +0200 Subject: [PATCH 0556/3374] examples/decode_video: switch to the new decoding API --- doc/examples/decode_video.c | 43 ++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/doc/examples/decode_video.c b/doc/examples/decode_video.c index 4c1068bef339e..74146432c02cf 100644 --- a/doc/examples/decode_video.c +++ b/doc/examples/decode_video.c @@ -54,26 +54,31 @@ static void decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt, const char *filename) { char buf[1024]; - int ret, got_picture; + int ret; + + ret = avcodec_send_packet(dec_ctx, pkt); + if (ret < 0) { + fprintf(stderr, "Error sending a packet for decoding\n"); + exit(1); + } - while (pkt->size > 0) { - ret = avcodec_decode_video2(dec_ctx, frame, &got_picture, pkt); - if (ret < 0) { - fprintf(stderr, "Error while decoding frame %d\n", dec_ctx->frame_number); + while (ret >= 0) { + ret = avcodec_receive_frame(dec_ctx, frame); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + return; + else if (ret < 0) { + fprintf(stderr, "Error during decoding\n"); exit(1); } - if (got_picture) { - printf("saving frame %3d\n", dec_ctx->frame_number); - fflush(stdout); - - /* the picture is allocated by the decoder. no need to - free it */ - snprintf(buf, sizeof(buf), filename, dec_ctx->frame_number); - pgm_save(frame->data[0], frame->linesize[0], - frame->width, frame->height, buf); - } - pkt->size -= ret; - pkt->data += ret; + + printf("saving frame %3d\n", dec_ctx->frame_number); + fflush(stdout); + + /* the picture is allocated by the decoder. no need to + free it */ + snprintf(buf, sizeof(buf), filename, dec_ctx->frame_number); + pgm_save(frame->data[0], frame->linesize[0], + frame->width, frame->height, buf); } } @@ -161,9 +166,7 @@ int main(int argc, char **argv) } /* flush the decoder */ - avpkt.data = NULL; - avpkt.size = 0; - decode(c, picture, &avpkt, outfilename); + decode(c, picture, NULL, outfilename); fclose(f); From c7ab0eb3050acdd3b8cab2c55fc9c1b2e8610a65 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 20 Oct 2016 11:03:20 +0200 Subject: [PATCH 0557/3374] examples/decode_video: allocate the packet dynamically AVPackets on stack are discouraged. --- doc/examples/decode_video.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/doc/examples/decode_video.c b/doc/examples/decode_video.c index 74146432c02cf..d6803ef97036e 100644 --- a/doc/examples/decode_video.c +++ b/doc/examples/decode_video.c @@ -94,7 +94,7 @@ int main(int argc, char **argv) uint8_t *data; size_t data_size; int ret; - AVPacket avpkt; + AVPacket *pkt; if (argc <= 2) { fprintf(stderr, "Usage: %s \n", argv[0]); @@ -105,7 +105,9 @@ int main(int argc, char **argv) avcodec_register_all(); - av_init_packet(&avpkt); + pkt = av_packet_alloc(); + if (!pkt) + exit(1); /* set end of buffer to 0 (this ensures that no overreading happens for damaged MPEG streams) */ memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE); @@ -151,7 +153,7 @@ int main(int argc, char **argv) /* use the parser to split the data into frames */ data = inbuf; while (data_size > 0) { - ret = av_parser_parse2(parser, c, &avpkt.data, &avpkt.size, + ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size, data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0); if (ret < 0) { fprintf(stderr, "Error while parsing\n"); @@ -160,8 +162,8 @@ int main(int argc, char **argv) data += ret; data_size -= ret; - if (avpkt.size) - decode(c, picture, &avpkt, outfilename); + if (pkt->size) + decode(c, picture, pkt, outfilename); } } @@ -173,6 +175,7 @@ int main(int argc, char **argv) av_parser_close(parser); avcodec_free_context(&c); av_frame_free(&picture); + av_packet_free(&pkt); return 0; } From aa498c3183236a93206b4a0e8225b9db0660b50d Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 19 Nov 2016 15:33:58 -0300 Subject: [PATCH 0558/3374] avpacket: fix leak on realloc in av_packet_add_side_data() If realloc fails, the pointer is overwritten and the previously allocated buffer is leaked, which goes against the expected functionality of keeping the packet unchanged in case of error. Signed-off-by: James Almer Signed-off-by: Anton Khirnov --- libavcodec/avpacket.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index f2b0a296b8019..93e9eb6ae7d69 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -240,16 +240,17 @@ FF_ENABLE_DEPRECATION_WARNINGS int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t *data, size_t size) { + AVPacketSideData *tmp; int elems = pkt->side_data_elems; if ((unsigned)elems + 1 > INT_MAX / sizeof(*pkt->side_data)) return AVERROR(ERANGE); - pkt->side_data = av_realloc(pkt->side_data, - (elems + 1) * sizeof(*pkt->side_data)); - if (!pkt->side_data) + tmp = av_realloc(pkt->side_data, (elems + 1) * sizeof(*tmp)); + if (!tmp) return AVERROR(ENOMEM); + pkt->side_data = tmp; pkt->side_data[elems].data = data; pkt->side_data[elems].size = size; pkt->side_data[elems].type = type; From 286ab878bd39b56008035638227b3ecb8ec5bbb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 21 May 2013 10:21:37 +0300 Subject: [PATCH 0559/3374] fate.sh: Allow setting other make flags for running tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If makeopts_fate is set, these makeopts are used for running the tests instead of the normal makeopts. If it isn't set, the normal makeopts variable is used as before. This is useful if remote testing on a lesser machine where a large number of parallel jobs might be undesireable, while wanting to speed up the build with many parallel processes. Signed-off-by: Martin Storsjö --- doc/fate.texi | 2 ++ tests/fate.sh | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/fate.texi b/doc/fate.texi index 9b8d953d85db9..9e654e79a1c60 100644 --- a/doc/fate.texi +++ b/doc/fate.texi @@ -159,6 +159,8 @@ extra_conf= # extra configure options not covered above #make= # name of GNU make if not 'make' makeopts= # extra options passed to 'make' +#makeopts_fate= # extra options passed to 'make' when running tests, + # defaulting to makeopts above if this is not set #tar= # command to create a tar archive from its arguments on # stdout, defaults to 'tar c' @end example diff --git a/tests/fate.sh b/tests/fate.sh index b8ee1ae549ff1..f7ca89135cc20 100755 --- a/tests/fate.sh +++ b/tests/fate.sh @@ -73,7 +73,7 @@ compile()( fate()( test "$build_only" = "yes" && return cd ${build} || return - ${make} ${makeopts} -k fate + ${make} ${makeopts_fate-${makeopts}} -k fate ) clean(){ From 79ff9935ae4ae90a4dd485bd9a3a440281d866b2 Mon Sep 17 00:00:00 2001 From: James Almer Date: Tue, 22 Nov 2016 17:16:48 -0500 Subject: [PATCH 0560/3374] utils: Add av_stream_add_side_data() Functionally similar to av_packet_add_side_data(). Allows the use of an already allocated buffer as stream side data. Signed-off-by: James Almer Signed-off-by: Vittorio Giovara --- doc/APIchanges | 3 +++ libavformat/avformat.h | 15 +++++++++++++++ libavformat/utils.c | 37 +++++++++++++++++++++++++++---------- libavformat/version.h | 2 +- 4 files changed, 46 insertions(+), 11 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 6e0d27d993bc4..90c65007649e8 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-xx-xx - xxxxxxx - lavf 57.10.0 - avformat.h + Add av_stream_add_side_data(). + 2016-xx-xx - xxxxxxx - lavu 55.28.0 - pixfmt.h Add AV_PIX_FMT_GRAY12(LE/BE). diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 65c3d90d4b2cb..547b88b2f1c14 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1399,6 +1399,21 @@ const AVClass *avformat_get_class(void); */ AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c); +/** + * Wrap an existing array as stream side data. + * + * @param st stream + * @param type side information type + * @param data the side data array. It must be allocated with the av_malloc() + * family of functions. The ownership of the data is transferred to + * st. + * @param size side information size + * @return zero on success, a negative AVERROR code on failure. On failure, + * the stream is unchanged and the data remains owned by the caller. + */ +int av_stream_add_side_data(AVStream *st, enum AVPacketSideDataType type, + uint8_t *data, size_t size); + /** * Allocate new information from stream. * diff --git a/libavformat/utils.c b/libavformat/utils.c index 37ba5a8626db6..8fa89eb790991 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -3388,15 +3388,11 @@ uint8_t *av_stream_get_side_data(AVStream *st, enum AVPacketSideDataType type, return NULL; } -uint8_t *av_stream_new_side_data(AVStream *st, enum AVPacketSideDataType type, - int size) +int av_stream_add_side_data(AVStream *st, enum AVPacketSideDataType type, + uint8_t *data, size_t size) { AVPacketSideData *sd, *tmp; int i; - uint8_t *data = av_malloc(size); - - if (!data) - return NULL; for (i = 0; i < st->nb_side_data; i++) { sd = &st->side_data[i]; @@ -3405,14 +3401,16 @@ uint8_t *av_stream_new_side_data(AVStream *st, enum AVPacketSideDataType type, av_freep(&sd->data); sd->data = data; sd->size = size; - return sd->data; + return 0; } } - tmp = av_realloc_array(st->side_data, st->nb_side_data + 1, sizeof(*tmp)); + if ((unsigned) st->nb_side_data + 1 >= INT_MAX / sizeof(*st->side_data)) + return AVERROR(ERANGE); + + tmp = av_realloc(st->side_data, (st->nb_side_data + 1) * sizeof(*tmp)); if (!tmp) { - av_freep(&data); - return NULL; + return AVERROR(ENOMEM); } st->side_data = tmp; @@ -3422,6 +3420,25 @@ uint8_t *av_stream_new_side_data(AVStream *st, enum AVPacketSideDataType type, sd->type = type; sd->data = data; sd->size = size; + + return 0; +} + +uint8_t *av_stream_new_side_data(AVStream *st, enum AVPacketSideDataType type, + int size) +{ + int ret; + uint8_t *data = av_malloc(size); + + if (!data) + return NULL; + + ret = av_stream_add_side_data(st, type, data, size); + if (ret < 0) { + av_freep(&data); + return NULL; + } + return data; } diff --git a/libavformat/version.h b/libavformat/version.h index c329c2f3024b0..c6085f85916b8 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFORMAT_VERSION_MAJOR 57 -#define LIBAVFORMAT_VERSION_MINOR 9 +#define LIBAVFORMAT_VERSION_MINOR 10 #define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ From 1893495e1d023365b4aa24e5e1bd1b24ad5d34fd Mon Sep 17 00:00:00 2001 From: James Almer Date: Mon, 21 Nov 2016 18:54:29 -0500 Subject: [PATCH 0561/3374] mov: Use av_stream_add_side_data() for displaymatrix side data Signed-off-by: James Almer Signed-off-by: Vittorio Giovara --- libavformat/mov.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index df29f2a6055c3..28adce76c3c8b 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -3545,20 +3545,12 @@ static int mov_read_header(AVFormatContext *s) break; case AVMEDIA_TYPE_VIDEO: if (sc->display_matrix) { - AVPacketSideData *sd, *tmp; - - tmp = av_realloc_array(st->side_data, - st->nb_side_data + 1, sizeof(*tmp)); - if (!tmp) - return AVERROR(ENOMEM); - - st->side_data = tmp; - st->nb_side_data++; + err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, + (uint8_t *)sc->display_matrix, + sizeof(int32_t) * 9); + if (err < 0) + return err; - sd = &st->side_data[st->nb_side_data - 1]; - sd->type = AV_PKT_DATA_DISPLAYMATRIX; - sd->size = sizeof(int32_t) * 9; - sd->data = (uint8_t*)sc->display_matrix; sc->display_matrix = NULL; } break; From 12ab667e219e7fbf8e9aef3731039b75c822df25 Mon Sep 17 00:00:00 2001 From: James Almer Date: Tue, 22 Nov 2016 15:50:28 -0500 Subject: [PATCH 0562/3374] matroska: use av_stream_add_side_data() for stereo3d side data Signed-off-by: James Almer Signed-off-by: Vittorio Giovara --- libavformat/matroska.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/libavformat/matroska.c b/libavformat/matroska.c index 8842d7c4642e7..a8f5e981b5067 100644 --- a/libavformat/matroska.c +++ b/libavformat/matroska.c @@ -115,26 +115,13 @@ const AVMetadataConv ff_mkv_metadata_conv[] = { int ff_mkv_stereo3d_conv(AVStream *st, MatroskaVideoStereoModeType stereo_mode) { - AVPacketSideData *sd, *tmp; AVStereo3D *stereo; + int ret; stereo = av_stereo3d_alloc(); if (!stereo) return AVERROR(ENOMEM); - tmp = av_realloc_array(st->side_data, st->nb_side_data + 1, sizeof(*tmp)); - if (!tmp) { - av_freep(&stereo); - return AVERROR(ENOMEM); - } - st->side_data = tmp; - st->nb_side_data++; - - sd = &st->side_data[st->nb_side_data - 1]; - sd->type = AV_PKT_DATA_STEREO3D; - sd->data = (uint8_t *)stereo; - sd->size = sizeof(*stereo); - // note: the missing breaks are intentional switch (stereo_mode) { case MATROSKA_VIDEO_STEREOMODE_TYPE_MONO: @@ -172,5 +159,12 @@ int ff_mkv_stereo3d_conv(AVStream *st, MatroskaVideoStereoModeType stereo_mode) break; } + ret = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D, (uint8_t *)stereo, + sizeof(*stereo)); + if (ret < 0) { + av_freep(&stereo); + return ret; + } + return 0; } From effc1430b2fe5997d9d55bf28dc507c27125eb27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 18 Nov 2016 10:09:12 +0200 Subject: [PATCH 0563/3374] Revert "checkasm: vp9dsp: Benchmark the dc-only version of idct_idct separately" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 81d7f0bbca837afda1f7e60d3ae52ab1360ab44b. Instead of just benchmarking dc separately, test all relevant subparts (in the next commit). Signed-off-by: Martin Storsjö --- tests/checkasm/vp9dsp.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/checkasm/vp9dsp.c b/tests/checkasm/vp9dsp.c index b9d1c73ea4086..690e0cf536dad 100644 --- a/tests/checkasm/vp9dsp.c +++ b/tests/checkasm/vp9dsp.c @@ -297,12 +297,6 @@ static void check_itxfm(void) } bench_new(dst, sz * SIZEOF_PIXEL, coef, sz * sz); } - if (txtp == 0 && tx != 4) { - if (check_func(dsp.itxfm_add[tx][txtp], "vp9_inv_%s_%dx%d_dc_add", - txtp_types[txtp], sz, sz)) { - bench_new(dst, sz * SIZEOF_PIXEL, coef, 1); - } - } } } report("itxfm"); From 06fec74cacbb0ef7f3e5ea0e6c9ced1b6fd7565d Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 18 Nov 2016 00:17:02 +0200 Subject: [PATCH 0564/3374] checkasm: vp9dsp: benchmark all sub-IDCTs (but not WHT or ADST). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- tests/checkasm/vp9dsp.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/tests/checkasm/vp9dsp.c b/tests/checkasm/vp9dsp.c index 690e0cf536dad..25f9dd1f9d0d9 100644 --- a/tests/checkasm/vp9dsp.c +++ b/tests/checkasm/vp9dsp.c @@ -269,14 +269,20 @@ static void check_itxfm(void) int n_txtps = tx < TX_32X32 ? N_TXFM_TYPES : 1; for (txtp = 0; txtp < n_txtps; txtp++) { - if (check_func(dsp.itxfm_add[tx][txtp], "vp9_inv_%s_%dx%d_add", - tx == 4 ? "wht_wht" : txtp_types[txtp], sz, sz)) { - randomize_buffers(); - ftx(coef, tx, txtp, sz, BIT_DEPTH); - - for (sub = (txtp == 0) ? 1 : 2; sub <= sz; sub <<= 1) { + // skip testing sub-IDCTs for WHT or ADST since they don't + // implement it in any of the SIMD functions. If they do, + // consider changing this to ensure we have complete test + // coverage + for (sub = (txtp == 0 && tx < 4) ? 1 : sz; sub <= sz; sub <<= 1) { + if (check_func(dsp.itxfm_add[tx][txtp], + "vp9_inv_%s_%dx%d_sub%d_add", + tx == 4 ? "wht_wht" : txtp_types[txtp], + sz, sz, sub)) { int eob; + randomize_buffers(); + ftx(coef, tx, txtp, sz, BIT_DEPTH); + if (sub < sz) { eob = copy_subcoefs(subcoef0, coef, tx, txtp, sz, sub, BIT_DEPTH); @@ -294,8 +300,9 @@ static void check_itxfm(void) !iszero(subcoef0, sz * sz * SIZEOF_COEF) || !iszero(subcoef1, sz * sz * SIZEOF_COEF)) fail(); + + bench_new(dst, sz * SIZEOF_PIXEL, coef, eob); } - bench_new(dst, sz * SIZEOF_PIXEL, coef, sz * sz); } } } From 721bc37522c5c1d6a8c3cea5e9c3fcde8d256c05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 22 Nov 2016 11:32:25 +0200 Subject: [PATCH 0565/3374] arm/aarch64: vp9itxfm: Fix indentation of macro arguments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 16 ++++++++-------- libavcodec/arm/vp9itxfm_neon.S | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index 65406b9e1a262..2dc6b7524a0af 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -969,14 +969,14 @@ function idct32_1d_8x32_pass1_neon st1 {v7.8h}, [x0], #16 .endm - store_rev 31, 23 - store_rev 30, 22 - store_rev 29, 21 - store_rev 28, 20 - store_rev 27, 19 - store_rev 26, 18 - store_rev 25, 17 - store_rev 24, 16 + store_rev 31, 23 + store_rev 30, 22 + store_rev 29, 21 + store_rev 28, 20 + store_rev 27, 19 + store_rev 26, 18 + store_rev 25, 17 + store_rev 24, 16 .purgem store_rev ret endfunc diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index 5d73d84d1f38c..acb1c6d8b6b05 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -1017,10 +1017,10 @@ function idct32_1d_4x32_pass1_neon .endr .endm - store_rev 31, 27, 23, 19 - store_rev 30, 26, 22, 18 - store_rev 29, 25, 21, 17 - store_rev 28, 24, 20, 16 + store_rev 31, 27, 23, 19 + store_rev 30, 26, 22, 18 + store_rev 29, 25, 21, 17 + store_rev 28, 24, 20, 16 .purgem store_rev bx lr endfunc From 79566ec8c77969d5f9be533de04b1349834cca62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 22 Nov 2016 13:52:55 +0200 Subject: [PATCH 0566/3374] arm: vp9itxfm: Rename a macro parameter to fit better MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the same parameter is used for both input and output, the name inout is more fitting. This matches the naming used below in the dmbutterfly macro. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index acb1c6d8b6b05..01944bd38f7dc 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -125,16 +125,16 @@ endconst vmlal.s16 \out4, \in4, \coef1 .endm -@ in1 = (in1 * coef1 - in2 * coef2 + (1 << 13)) >> 14 -@ in2 = (in1 * coef2 + in2 * coef1 + (1 << 13)) >> 14 -@ in are 2 d registers, tmp are 2 q registers -.macro mbutterfly in1, in2, coef1, coef2, tmp1, tmp2, neg=0 - mbutterfly_l \tmp1, \tmp2, \in1, \in2, \coef1, \coef2 +@ inout1 = (inout1 * coef1 - inout2 * coef2 + (1 << 13)) >> 14 +@ inout2 = (inout1 * coef2 + inout2 * coef1 + (1 << 13)) >> 14 +@ inout are 2 d registers, tmp are 2 q registers +.macro mbutterfly inout1, inout2, coef1, coef2, tmp1, tmp2, neg=0 + mbutterfly_l \tmp1, \tmp2, \inout1, \inout2, \coef1, \coef2 .if \neg > 0 vneg.s32 \tmp2, \tmp2 .endif - vrshrn.s32 \in1, \tmp1, #14 - vrshrn.s32 \in2, \tmp2, #14 + vrshrn.s32 \inout1, \tmp1, #14 + vrshrn.s32 \inout2, \tmp2, #14 .endm @ inout1,inout2 = (inout1,inout2 * coef1 - inout3,inout4 * coef2 + (1 << 13)) >> 14 From 7d8075cf471459dee372595c74b7f28cb4e9a05d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Wed, 13 Apr 2016 11:53:47 +0200 Subject: [PATCH 0567/3374] ra144: Convert to the new bitstream reader --- libavcodec/ra144dec.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/libavcodec/ra144dec.c b/libavcodec/ra144dec.c index 289535741fe2d..35ee697731572 100644 --- a/libavcodec/ra144dec.c +++ b/libavcodec/ra144dec.c @@ -23,8 +23,9 @@ */ #include "libavutil/channel_layout.h" + #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "internal.h" #include "ra144.h" @@ -46,12 +47,12 @@ static av_cold int ra144_decode_init(AVCodecContext * avctx) } static void do_output_subblock(RA144Context *ractx, const uint16_t *lpc_coefs, - int gval, GetBitContext *gb) + int gval, BitstreamContext *bc) { - int cba_idx = get_bits(gb, 7); // index of the adaptive CB, 0 if none - int gain = get_bits(gb, 8); - int cb1_idx = get_bits(gb, 7); - int cb2_idx = get_bits(gb, 7); + int cba_idx = bitstream_read(bc, 7); // index of the adaptive CB, 0 if none + int gain = bitstream_read(bc, 8); + int cb1_idx = bitstream_read(bc, 7); + int cb2_idx = bitstream_read(bc, 7); ff_subblock_synthesis(ractx, lpc_coefs, cba_idx, cb1_idx, cb2_idx, gval, gain); @@ -74,7 +75,7 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *data, unsigned int energy; RA144Context *ractx = avctx->priv_data; - GetBitContext gb; + BitstreamContext bc; if (buf_size < FRAMESIZE) { av_log(avctx, AV_LOG_ERROR, @@ -91,15 +92,15 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *data, } samples = (int16_t *)frame->data[0]; - init_get_bits(&gb, buf, FRAMESIZE * 8); + bitstream_init(&bc, buf, FRAMESIZE * 8); for (i = 0; i < LPC_ORDER; i++) - lpc_refl[i] = ff_lpc_refl_cb[i][get_bits(&gb, sizes[i])]; + lpc_refl[i] = ff_lpc_refl_cb[i][bitstream_read(&bc, sizes[i])]; ff_eval_coefs(ractx->lpc_coef[0], lpc_refl); ractx->lpc_refl_rms[0] = ff_rms(lpc_refl); - energy = ff_energy_tab[get_bits(&gb, 5)]; + energy = ff_energy_tab[bitstream_read(&bc, 5)]; refl_rms[0] = ff_interp(ractx, block_coefs[0], 1, 1, ractx->old_energy); refl_rms[1] = ff_interp(ractx, block_coefs[1], 2, @@ -111,7 +112,7 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *data, ff_int_to_int16(block_coefs[3], ractx->lpc_coef[0]); for (i=0; i < NBLOCKS; i++) { - do_output_subblock(ractx, block_coefs[i], refl_rms[i], &gb); + do_output_subblock(ractx, block_coefs[i], refl_rms[i], &bc); for (j=0; j < BLOCKSIZE; j++) *samples++ = av_clip_int16(ractx->curr_sblock[j + 10] << 2); From c60cda7cb476315fd7f6d28715316b1aff2e080a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Wed, 13 Apr 2016 19:34:49 +0200 Subject: [PATCH 0568/3374] ra288: Convert to the new bitstream reader --- libavcodec/ra288.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavcodec/ra288.c b/libavcodec/ra288.c index 96d8d1ece171c..bc3fe29dc1491 100644 --- a/libavcodec/ra288.c +++ b/libavcodec/ra288.c @@ -25,8 +25,8 @@ #define BITSTREAM_READER_LE #include "avcodec.h" +#include "bitstream.h" #include "celp_filters.h" -#include "get_bits.h" #include "internal.h" #include "lpc.h" #include "ra288.h" @@ -181,7 +181,7 @@ static int ra288_decode_frame(AVCodecContext * avctx, void *data, float *out; int i, ret; RA288Context *ractx = avctx->priv_data; - GetBitContext gb; + BitstreamContext bc; if (buf_size < avctx->block_align) { av_log(avctx, AV_LOG_ERROR, @@ -198,11 +198,11 @@ static int ra288_decode_frame(AVCodecContext * avctx, void *data, } out = (float *)frame->data[0]; - init_get_bits(&gb, buf, avctx->block_align * 8); + bitstream_init(&bc, buf, avctx->block_align * 8); for (i=0; i < RA288_BLOCKS_PER_FRAME; i++) { - float gain = amptable[get_bits(&gb, 3)]; - int cb_coef = get_bits(&gb, 6 + (i&1)); + float gain = amptable[bitstream_read(&bc, 3)]; + int cb_coef = bitstream_read(&bc, 6 + (i & 1)); decode(ractx, gain, cb_coef); From f26cbb555b9547b7a532c7a0d883579a52815b1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Wed, 13 Apr 2016 19:41:09 +0200 Subject: [PATCH 0569/3374] rtjpeg: Convert to the new bitstream reader --- libavcodec/rtjpeg.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/libavcodec/rtjpeg.c b/libavcodec/rtjpeg.c index 67eeff8f4a615..baa1f7857df85 100644 --- a/libavcodec/rtjpeg.c +++ b/libavcodec/rtjpeg.c @@ -18,8 +18,10 @@ * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + #include "libavutil/common.h" -#include "get_bits.h" + +#include "bitstream.h" #include "rtjpeg.h" #define PUT_COEFF(c) \ @@ -28,34 +30,36 @@ /// aligns the bitstream to the given power of two #define ALIGN(a) \ - n = (-get_bits_count(gb)) & (a - 1); \ - if (n) {skip_bits(gb, n);} + n = (-bitstream_tell(bc)) & (a - 1); \ + if (n) \ + bitstream_skip(bc, n); /** * @brief read one block from stream - * @param gb contains stream data + * @param bc contains stream data * @param block where data is written to * @param scan array containing the mapping stream address -> block position * @param quant quantization factors * @return 0 means the block is not coded, < 0 means an error occurred. * - * Note: GetBitContext is used to make the code simpler, since all data is + * Note: BitstreamContext is used to make the code simpler, since all data is * aligned this could be done faster in a different way, e.g. as it is done * in MPlayer libmpcodecs/native/rtjpegn.c. */ -static inline int get_block(GetBitContext *gb, int16_t *block, const uint8_t *scan, - const uint32_t *quant) { +static inline int get_block(BitstreamContext *bc, int16_t *block, + const uint8_t *scan, const uint32_t *quant) +{ int coeff, i, n; int8_t ac; - uint8_t dc = get_bits(gb, 8); + uint8_t dc = bitstream_read(bc, 8); // block not coded if (dc == 255) return 0; // number of non-zero coefficients - coeff = get_bits(gb, 6); - if (get_bits_left(gb) < (coeff << 1)) + coeff = bitstream_read(bc, 6); + if (bitstream_bits_left(bc) < (coeff << 1)) return AVERROR_INVALIDDATA; // normally we would only need to clear the (63 - coeff) last values, @@ -64,7 +68,7 @@ static inline int get_block(GetBitContext *gb, int16_t *block, const uint8_t *sc // 2 bits per coefficient while (coeff) { - ac = get_sbits(gb, 2); + ac = bitstream_read_signed(bc, 2); if (ac == -2) break; // continue with more bits PUT_COEFF(ac); @@ -72,10 +76,10 @@ static inline int get_block(GetBitContext *gb, int16_t *block, const uint8_t *sc // 4 bits per coefficient ALIGN(4); - if (get_bits_left(gb) < (coeff << 2)) + if (bitstream_bits_left(bc) < (coeff << 2)) return AVERROR_INVALIDDATA; while (coeff) { - ac = get_sbits(gb, 4); + ac = bitstream_read_signed(bc, 4); if (ac == -8) break; // continue with more bits PUT_COEFF(ac); @@ -83,10 +87,10 @@ static inline int get_block(GetBitContext *gb, int16_t *block, const uint8_t *sc // 8 bits per coefficient ALIGN(8); - if (get_bits_left(gb) < (coeff << 3)) + if (bitstream_bits_left(bc) < (coeff << 3)) return AVERROR_INVALIDDATA; while (coeff) { - ac = get_sbits(gb, 8); + ac = bitstream_read_signed(bc, 8); PUT_COEFF(ac); } @@ -105,19 +109,19 @@ static inline int get_block(GetBitContext *gb, int16_t *block, const uint8_t *sc */ int ff_rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f, const uint8_t *buf, int buf_size) { - GetBitContext gb; + BitstreamContext bc; int w = c->w / 16, h = c->h / 16; int x, y, ret; uint8_t *y1 = f->data[0], *y2 = f->data[0] + 8 * f->linesize[0]; uint8_t *u = f->data[1], *v = f->data[2]; - if ((ret = init_get_bits8(&gb, buf, buf_size)) < 0) + if ((ret = bitstream_init8(&bc, buf, buf_size)) < 0) return ret; for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { #define BLOCK(quant, dst, stride) do { \ - int res = get_block(&gb, block, c->scan, quant); \ + int res = get_block(&bc, block, c->scan, quant); \ if (res < 0) \ return res; \ if (res > 0) \ @@ -142,7 +146,7 @@ int ff_rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f, u += 8 * (f->linesize[1] - w); v += 8 * (f->linesize[2] - w); } - return get_bits_count(&gb) / 8; + return bitstream_tell(&bc) / 8; } /** From 087bc8d70415b3b50db4dbf5adf49cf071281874 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Wed, 13 Apr 2016 19:49:21 +0200 Subject: [PATCH 0570/3374] sipr: Convert to the new bitstream reader --- libavcodec/sipr.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/libavcodec/sipr.c b/libavcodec/sipr.c index 686b3e2154af2..cf29d3bba7cc1 100644 --- a/libavcodec/sipr.c +++ b/libavcodec/sipr.c @@ -31,7 +31,7 @@ #define BITSTREAM_READER_LE #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "internal.h" #include "lsp.h" #include "acelp_vectors.h" @@ -188,28 +188,28 @@ static void pitch_sharpening(int pitch_lag_int, float beta, /** * Extract decoding parameters from the input bitstream. * @param parms parameters structure - * @param pgb pointer to initialized GetBitContext structure + * @param bc pointer to initialized BitstreamContext structure */ -static void decode_parameters(SiprParameters* parms, GetBitContext *pgb, +static void decode_parameters(SiprParameters* parms, BitstreamContext *bc, const SiprModeParam *p) { int i, j; if (p->ma_predictor_bits) - parms->ma_pred_switch = get_bits(pgb, p->ma_predictor_bits); + parms->ma_pred_switch = bitstream_read(bc, p->ma_predictor_bits); for (i = 0; i < 5; i++) - parms->vq_indexes[i] = get_bits(pgb, p->vq_indexes_bits[i]); + parms->vq_indexes[i] = bitstream_read(bc, p->vq_indexes_bits[i]); for (i = 0; i < p->subframe_count; i++) { - parms->pitch_delay[i] = get_bits(pgb, p->pitch_delay_bits[i]); + parms->pitch_delay[i] = bitstream_read(bc, p->pitch_delay_bits[i]); if (p->gp_index_bits) - parms->gp_index[i] = get_bits(pgb, p->gp_index_bits); + parms->gp_index[i] = bitstream_read(bc, p->gp_index_bits); for (j = 0; j < p->number_of_fc_indexes; j++) - parms->fc_indexes[i][j] = get_bits(pgb, p->fc_index_bits[j]); + parms->fc_indexes[i][j] = bitstream_read(bc, p->fc_index_bits[j]); - parms->gc_index[i] = get_bits(pgb, p->gc_index_bits); + parms->gc_index[i] = bitstream_read(bc, p->gc_index_bits); } } @@ -527,7 +527,7 @@ static int sipr_decode_frame(AVCodecContext *avctx, void *data, const uint8_t *buf=avpkt->data; SiprParameters parm; const SiprModeParam *mode_par = &modes[ctx->mode]; - GetBitContext gb; + BitstreamContext bc; float *samples; int subframe_size = ctx->mode == MODE_16k ? L_SUBFR_16k : SUBFR_SIZE; int i, ret; @@ -549,10 +549,10 @@ static int sipr_decode_frame(AVCodecContext *avctx, void *data, } samples = (float *)frame->data[0]; - init_get_bits(&gb, buf, mode_par->bits_per_frame); + bitstream_init(&bc, buf, mode_par->bits_per_frame); for (i = 0; i < mode_par->frames_per_packet; i++) { - decode_parameters(&parm, &gb, mode_par); + decode_parameters(&parm, &bc, mode_par); ctx->decode_frame(ctx, &parm, samples); From 6efbc88a5cf40c8e6f3c4f7897caf83165920d3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Wed, 13 Apr 2016 19:56:53 +0200 Subject: [PATCH 0571/3374] smacker: Convert to the new bitstream reader --- libavcodec/smacker.c | 143 +++++++++++++++++++++++-------------------- 1 file changed, 75 insertions(+), 68 deletions(-) diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c index e3e54752a747c..027728e387be2 100644 --- a/libavcodec/smacker.c +++ b/libavcodec/smacker.c @@ -35,8 +35,8 @@ #define BITSTREAM_READER_LE #include "avcodec.h" +#include "bitstream.h" #include "bytestream.h" -#include "get_bits.h" #include "internal.h" #include "mathops.h" @@ -93,9 +93,10 @@ enum SmkBlockTypes { /** * Decode local frame tree */ -static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, uint32_t prefix, int length) +static int smacker_decode_tree(BitstreamContext *bc, HuffContext *hc, + uint32_t prefix, int length) { - if(!get_bits1(gb)){ //Leaf + if (!bitstream_read_bit(bc)) { // Leaf if(hc->current >= 256){ av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); return -1; @@ -107,7 +108,7 @@ static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, uint32_t pref hc->bits[hc->current] = 0; hc->lengths[hc->current] = 0; } - hc->values[hc->current] = get_bits(gb, 8); + hc->values[hc->current] = bitstream_read(bc, 8); hc->current++; if(hc->maxlength < length) hc->maxlength = length; @@ -115,26 +116,27 @@ static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, uint32_t pref } else { //Node int r; length++; - r = smacker_decode_tree(gb, hc, prefix, length); + r = smacker_decode_tree(bc, hc, prefix, length); if(r) return r; - return smacker_decode_tree(gb, hc, prefix | (1 << (length - 1)), length); + return smacker_decode_tree(bc, hc, prefix | (1 << (length - 1)), length); } } /** * Decode header tree */ -static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx) +static int smacker_decode_bigtree(BitstreamContext *bc, HuffContext *hc, + DBCtx *ctx) { if (hc->current + 1 >= hc->length) { av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); return -1; } - if(!get_bits1(gb)){ //Leaf + if (!bitstream_read_bit(bc)) { // Leaf int val, i1, i2; - i1 = ctx->v1->table ? get_vlc2(gb, ctx->v1->table, SMKTREE_BITS, 3) : 0; - i2 = ctx->v2->table ? get_vlc2(gb, ctx->v2->table, SMKTREE_BITS, 3) : 0; + i1 = ctx->v1->table ? bitstream_read_vlc(bc, ctx->v1->table, SMKTREE_BITS, 3) : 0; + i2 = ctx->v2->table ? bitstream_read_vlc(bc, ctx->v2->table, SMKTREE_BITS, 3) : 0; if (i1 < 0 || i2 < 0) return -1; val = ctx->recode1[i1] | (ctx->recode2[i2] << 8); @@ -155,12 +157,12 @@ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx int r = 0, r_new, t; t = hc->current++; - r = smacker_decode_bigtree(gb, hc, ctx); + r = smacker_decode_bigtree(bc, hc, ctx); if(r < 0) return r; hc->values[t] = SMK_NODE | r; r++; - r_new = smacker_decode_bigtree(gb, hc, ctx); + r_new = smacker_decode_bigtree(bc, hc, ctx); if (r_new < 0) return r_new; return r + r_new; @@ -170,7 +172,8 @@ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx /** * Store large tree as Libav's vlc codes */ -static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int **recodes, int *last, int size) +static int smacker_decode_header_tree(SmackVContext *smk, BitstreamContext *bc, + int **recodes, int *last, int size) { int res; HuffContext huff; @@ -204,9 +207,9 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int goto error; } - if(get_bits1(gb)) { - smacker_decode_tree(gb, &tmp1, 0, 0); - skip_bits1(gb); + if (bitstream_read_bit(bc)) { + smacker_decode_tree(bc, &tmp1, 0, 0); + bitstream_skip(bc, 1); res = init_vlc(&vlc[0], SMKTREE_BITS, tmp1.length, tmp1.lengths, sizeof(int), sizeof(int), tmp1.bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); @@ -218,9 +221,9 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int } else { av_log(smk->avctx, AV_LOG_ERROR, "Skipping low bytes tree\n"); } - if(get_bits1(gb)){ - smacker_decode_tree(gb, &tmp2, 0, 0); - skip_bits1(gb); + if (bitstream_read_bit(bc)) { + smacker_decode_tree(bc, &tmp2, 0, 0); + bitstream_skip(bc, 1); res = init_vlc(&vlc[1], SMKTREE_BITS, tmp2.length, tmp2.lengths, sizeof(int), sizeof(int), tmp2.bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); @@ -233,12 +236,12 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int av_log(smk->avctx, AV_LOG_ERROR, "Skipping high bytes tree\n"); } - escapes[0] = get_bits(gb, 8); - escapes[0] |= get_bits(gb, 8) << 8; - escapes[1] = get_bits(gb, 8); - escapes[1] |= get_bits(gb, 8) << 8; - escapes[2] = get_bits(gb, 8); - escapes[2] |= get_bits(gb, 8) << 8; + escapes[0] = bitstream_read(bc, 8); + escapes[0] |= bitstream_read(bc, 8) << 8; + escapes[1] = bitstream_read(bc, 8); + escapes[1] |= bitstream_read(bc, 8) << 8; + escapes[2] = bitstream_read(bc, 8); + escapes[2] |= bitstream_read(bc, 8) << 8; last[0] = last[1] = last[2] = -1; @@ -260,9 +263,9 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int goto error; } - if (smacker_decode_bigtree(gb, &huff, &ctx) < 0) + if (smacker_decode_bigtree(bc, &huff, &ctx) < 0) err = -1; - skip_bits1(gb); + bitstream_skip(bc, 1); if(ctx.last[0] == -1) ctx.last[0] = huff.current++; if(ctx.last[1] == -1) ctx.last[1] = huff.current++; if(ctx.last[2] == -1) ctx.last[2] = huff.current++; @@ -291,7 +294,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int } static int decode_header_trees(SmackVContext *smk) { - GetBitContext gb; + BitstreamContext bc; int mmap_size, mclr_size, full_size, type_size; mmap_size = AV_RL32(smk->avctx->extradata); @@ -299,9 +302,9 @@ static int decode_header_trees(SmackVContext *smk) { full_size = AV_RL32(smk->avctx->extradata + 8); type_size = AV_RL32(smk->avctx->extradata + 12); - init_get_bits(&gb, smk->avctx->extradata + 16, (smk->avctx->extradata_size - 16) * 8); + bitstream_init(&bc, smk->avctx->extradata + 16, (smk->avctx->extradata_size - 16) * 8); - if(!get_bits1(&gb)) { + if (!bitstream_read_bit(&bc)) { av_log(smk->avctx, AV_LOG_INFO, "Skipping MMAP tree\n"); smk->mmap_tbl = av_malloc(sizeof(int) * 2); if (!smk->mmap_tbl) @@ -309,10 +312,10 @@ static int decode_header_trees(SmackVContext *smk) { smk->mmap_tbl[0] = 0; smk->mmap_last[0] = smk->mmap_last[1] = smk->mmap_last[2] = 1; } else { - if (smacker_decode_header_tree(smk, &gb, &smk->mmap_tbl, smk->mmap_last, mmap_size)) + if (smacker_decode_header_tree(smk, &bc, &smk->mmap_tbl, smk->mmap_last, mmap_size)) return -1; } - if(!get_bits1(&gb)) { + if (!bitstream_read_bit(&bc)) { av_log(smk->avctx, AV_LOG_INFO, "Skipping MCLR tree\n"); smk->mclr_tbl = av_malloc(sizeof(int) * 2); if (!smk->mclr_tbl) @@ -320,10 +323,10 @@ static int decode_header_trees(SmackVContext *smk) { smk->mclr_tbl[0] = 0; smk->mclr_last[0] = smk->mclr_last[1] = smk->mclr_last[2] = 1; } else { - if (smacker_decode_header_tree(smk, &gb, &smk->mclr_tbl, smk->mclr_last, mclr_size)) + if (smacker_decode_header_tree(smk, &bc, &smk->mclr_tbl, smk->mclr_last, mclr_size)) return -1; } - if(!get_bits1(&gb)) { + if (!bitstream_read_bit(&bc)) { av_log(smk->avctx, AV_LOG_INFO, "Skipping FULL tree\n"); smk->full_tbl = av_malloc(sizeof(int) * 2); if (!smk->full_tbl) @@ -331,10 +334,10 @@ static int decode_header_trees(SmackVContext *smk) { smk->full_tbl[0] = 0; smk->full_last[0] = smk->full_last[1] = smk->full_last[2] = 1; } else { - if (smacker_decode_header_tree(smk, &gb, &smk->full_tbl, smk->full_last, full_size)) + if (smacker_decode_header_tree(smk, &bc, &smk->full_tbl, smk->full_last, full_size)) return -1; } - if(!get_bits1(&gb)) { + if (!bitstream_read_bit(&bc)) { av_log(smk->avctx, AV_LOG_INFO, "Skipping TYPE tree\n"); smk->type_tbl = av_malloc(sizeof(int) * 2); if (!smk->type_tbl) @@ -342,7 +345,7 @@ static int decode_header_trees(SmackVContext *smk) { smk->type_tbl[0] = 0; smk->type_last[0] = smk->type_last[1] = smk->type_last[2] = 1; } else { - if (smacker_decode_header_tree(smk, &gb, &smk->type_tbl, smk->type_last, type_size)) + if (smacker_decode_header_tree(smk, &bc, &smk->type_tbl, smk->type_last, type_size)) return -1; } @@ -354,12 +357,14 @@ static av_always_inline void last_reset(int *recode, int *last) { } /* get code and update history */ -static av_always_inline int smk_get_code(GetBitContext *gb, int *recode, int *last) { +static av_always_inline int smk_get_code(BitstreamContext *bc, int *recode, + int *last) +{ register int *table = recode; int v; while(*table & SMK_NODE) { - if(get_bits1(gb)) + if (bitstream_read_bit(bc)) table += (*table) & (~SMK_NODE); table++; } @@ -380,7 +385,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, uint8_t *out; uint32_t *pal; GetByteContext gb2; - GetBitContext gb; + BitstreamContext bc; int blocks, blk, bw, bh; int i, ret; int stride; @@ -412,7 +417,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, last_reset(smk->mclr_tbl, smk->mclr_last); last_reset(smk->full_tbl, smk->full_last); last_reset(smk->type_tbl, smk->type_last); - init_get_bits(&gb, avpkt->data + 769, (avpkt->size - 769) * 8); + bitstream_init(&bc, avpkt->data + 769, (avpkt->size - 769) * 8); blk = 0; bw = avctx->width >> 2; @@ -424,15 +429,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, int type, run, mode; uint16_t pix; - type = smk_get_code(&gb, smk->type_tbl, smk->type_last); + type = smk_get_code(&bc, smk->type_tbl, smk->type_last); run = block_runs[(type >> 2) & 0x3F]; switch(type & 3){ case SMK_BLK_MONO: while(run-- && blk < blocks){ int clr, map; int hi, lo; - clr = smk_get_code(&gb, smk->mclr_tbl, smk->mclr_last); - map = smk_get_code(&gb, smk->mmap_tbl, smk->mmap_last); + clr = smk_get_code(&bc, smk->mclr_tbl, smk->mclr_last); + map = smk_get_code(&bc, smk->mmap_tbl, smk->mmap_last); out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; hi = clr >> 8; lo = clr & 0xFF; @@ -450,30 +455,32 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, case SMK_BLK_FULL: mode = 0; if(avctx->codec_tag == MKTAG('S', 'M', 'K', '4')) { // In case of Smacker v4 we have three modes - if(get_bits1(&gb)) mode = 1; - else if(get_bits1(&gb)) mode = 2; + if (bitstream_read_bit(&bc)) + mode = 1; + else if (bitstream_read_bit(&bc)) + mode = 2; } while(run-- && blk < blocks){ out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; switch(mode){ case 0: for(i = 0; i < 4; i++) { - pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); + pix = smk_get_code(&bc, smk->full_tbl, smk->full_last); AV_WL16(out+2,pix); - pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); + pix = smk_get_code(&bc, smk->full_tbl, smk->full_last); AV_WL16(out,pix); out += stride; } break; case 1: - pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); + pix = smk_get_code(&bc, smk->full_tbl, smk->full_last); out[0] = out[1] = pix & 0xFF; out[2] = out[3] = pix >> 8; out += stride; out[0] = out[1] = pix & 0xFF; out[2] = out[3] = pix >> 8; out += stride; - pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); + pix = smk_get_code(&bc, smk->full_tbl, smk->full_last); out[0] = out[1] = pix & 0xFF; out[2] = out[3] = pix >> 8; out += stride; @@ -484,8 +491,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, case 2: for(i = 0; i < 2; i++) { uint16_t pix1, pix2; - pix2 = smk_get_code(&gb, smk->full_tbl, smk->full_last); - pix1 = smk_get_code(&gb, smk->full_tbl, smk->full_last); + pix2 = smk_get_code(&bc, smk->full_tbl, smk->full_last); + pix1 = smk_get_code(&bc, smk->full_tbl, smk->full_last); AV_WL16(out,pix1); AV_WL16(out+2,pix2); out += stride; @@ -593,7 +600,7 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, AVFrame *frame = data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - GetBitContext gb; + BitstreamContext bc; HuffContext h[4] = { { 0 } }; VLC vlc[4] = { { 0 } }; int16_t *samples; @@ -611,15 +618,15 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, unp_size = AV_RL32(buf); - init_get_bits(&gb, buf + 4, (buf_size - 4) * 8); + bitstream_init(&bc, buf + 4, (buf_size - 4) * 8); - if(!get_bits1(&gb)){ + if (!bitstream_read_bit(&bc)) { av_log(avctx, AV_LOG_INFO, "Sound: no data\n"); *got_frame_ptr = 0; return 1; } - stereo = get_bits1(&gb); - bits = get_bits1(&gb); + stereo = bitstream_read_bit(&bc); + bits = bitstream_read_bit(&bc); if (stereo ^ (avctx->channels != 1)) { av_log(avctx, AV_LOG_ERROR, "channels mismatch\n"); return AVERROR(EINVAL); @@ -650,12 +657,12 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, ret = AVERROR(ENOMEM); goto error; } - skip_bits1(&gb); - if (smacker_decode_tree(&gb, &h[i], 0, 0) < 0) { + bitstream_skip(&bc, 1); + if (smacker_decode_tree(&bc, &h[i], 0, 0) < 0) { ret = AVERROR_INVALIDDATA; goto error; } - skip_bits1(&gb); + bitstream_skip(&bc, 1); if(h[i].current > 1) { res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length, h[i].lengths, sizeof(int), sizeof(int), @@ -670,18 +677,18 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, /* this codec relies on wraparound instead of clipping audio */ if(bits) { //decode 16-bit data for(i = stereo; i >= 0; i--) - pred[i] = sign_extend(av_bswap16(get_bits(&gb, 16)), 16); + pred[i] = sign_extend(av_bswap16(bitstream_read(&bc, 16)), 16); for(i = 0; i <= stereo; i++) *samples++ = pred[i]; for(; i < unp_size / 2; i++) { if(i & stereo) { if(vlc[2].table) - res = get_vlc2(&gb, vlc[2].table, SMKTREE_BITS, 3); + res = bitstream_read_vlc(&bc, vlc[2].table, SMKTREE_BITS, 3); else res = 0; val = h[2].values[res]; if(vlc[3].table) - res = get_vlc2(&gb, vlc[3].table, SMKTREE_BITS, 3); + res = bitstream_read_vlc(&bc, vlc[3].table, SMKTREE_BITS, 3); else res = 0; val |= h[3].values[res] << 8; @@ -689,12 +696,12 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, *samples++ = pred[1]; } else { if(vlc[0].table) - res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); + res = bitstream_read_vlc(&bc, vlc[0].table, SMKTREE_BITS, 3); else res = 0; val = h[0].values[res]; if(vlc[1].table) - res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); + res = bitstream_read_vlc(&bc, vlc[1].table, SMKTREE_BITS, 3); else res = 0; val |= h[1].values[res] << 8; @@ -704,20 +711,20 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, } } else { //8-bit data for(i = stereo; i >= 0; i--) - pred[i] = get_bits(&gb, 8); + pred[i] = bitstream_read(&bc, 8); for(i = 0; i <= stereo; i++) *samples8++ = pred[i]; for(; i < unp_size; i++) { if(i & stereo){ if(vlc[1].table) - res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); + res = bitstream_read_vlc(&bc, vlc[1].table, SMKTREE_BITS, 3); else res = 0; pred[1] += sign_extend(h[1].values[res], 8); *samples8++ = pred[1]; } else { if(vlc[0].table) - res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); + res = bitstream_read_vlc(&bc, vlc[0].table, SMKTREE_BITS, 3); else res = 0; pred[0] += sign_extend(h[0].values[res], 8); From 9f78e3a46d15abbdc900d755818ef235ae5e886c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Wed, 13 Apr 2016 20:25:22 +0200 Subject: [PATCH 0572/3374] svq1dec: Convert to the new bitstream reader --- libavcodec/svq1dec.c | 120 +++++++++++++++++++++---------------------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c index cc43f1491c177..2ab0f238bbb67 100644 --- a/libavcodec/svq1dec.c +++ b/libavcodec/svq1dec.c @@ -33,7 +33,7 @@ */ #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "h263.h" #include "hpeldsp.h" #include "internal.h" @@ -55,7 +55,7 @@ typedef struct svq1_pmv_s { typedef struct SVQ1Context { HpelDSPContext hdsp; - GetBitContext gb; + BitstreamContext bc; AVFrame *prev; uint8_t *pkt_swapped; @@ -111,7 +111,7 @@ static const uint8_t string_table[256] = { break; \ } \ /* divide block if next bit set */ \ - if (get_bits1(bitbuf) == 0) \ + if (bitstream_read_bit(bc) == 0) \ break; \ /* add child nodes */ \ list[n++] = list[i]; \ @@ -145,7 +145,7 @@ static const uint8_t string_table[256] = { #define SVQ1_CALC_CODEBOOK_ENTRIES(cbook) \ codebook = (const uint32_t *)cbook[level]; \ if (stages > 0) \ - bit_cache = get_bits(bitbuf, 4 * stages); \ + bit_cache = bitstream_read(bc, 4 * stages); \ /* calculate codebook entries for this vector */ \ for (j = 0; j < stages; j++) { \ entries[j] = (((bit_cache >> (4 * (stages - j - 1))) & 0xF) + \ @@ -154,7 +154,7 @@ static const uint8_t string_table[256] = { mean -= stages * 128; \ n4 = mean + (mean >> 31) << 16 | (mean & 0xFFFF); -static int svq1_decode_block_intra(GetBitContext *bitbuf, uint8_t *pixels, +static int svq1_decode_block_intra(BitstreamContext *bc, uint8_t *pixels, ptrdiff_t pitch) { uint32_t bit_cache; @@ -180,7 +180,7 @@ static int svq1_decode_block_intra(GetBitContext *bitbuf, uint8_t *pixels, height = 1 << ((3 + level) / 2); /* get number of stages (-1 skips vector, 0 for mean only) */ - stages = get_vlc2(bitbuf, svq1_intra_multistage[level].table, 3, 3) - 1; + stages = bitstream_read_vlc(bc, svq1_intra_multistage[level].table, 3, 3) - 1; if (stages == -1) { for (y = 0; y < height; y++) @@ -195,7 +195,7 @@ static int svq1_decode_block_intra(GetBitContext *bitbuf, uint8_t *pixels, return AVERROR_INVALIDDATA; /* invalid vector */ } - mean = get_vlc2(bitbuf, svq1_intra_mean.table, 8, 3); + mean = bitstream_read_vlc(bc, svq1_intra_mean.table, 8, 3); if (stages == 0) { for (y = 0; y < height; y++) @@ -219,7 +219,7 @@ static int svq1_decode_block_intra(GetBitContext *bitbuf, uint8_t *pixels, return 0; } -static int svq1_decode_block_non_intra(GetBitContext *bitbuf, uint8_t *pixels, +static int svq1_decode_block_non_intra(BitstreamContext *bc, uint8_t *pixels, ptrdiff_t pitch) { uint32_t bit_cache; @@ -245,7 +245,7 @@ static int svq1_decode_block_non_intra(GetBitContext *bitbuf, uint8_t *pixels, height = 1 << ((3 + level) / 2); /* get number of stages (-1 skips vector, 0 for mean only) */ - stages = get_vlc2(bitbuf, svq1_inter_multistage[level].table, 3, 2) - 1; + stages = bitstream_read_vlc(bc, svq1_inter_multistage[level].table, 3, 2) - 1; if (stages == -1) continue; /* skip vector */ @@ -257,7 +257,7 @@ static int svq1_decode_block_non_intra(GetBitContext *bitbuf, uint8_t *pixels, return AVERROR_INVALIDDATA; /* invalid vector */ } - mean = get_vlc2(bitbuf, svq1_inter_mean.table, 9, 3) - 256; + mean = bitstream_read_vlc(bc, svq1_inter_mean.table, 9, 3) - 256; SVQ1_CALC_CODEBOOK_ENTRIES(ff_svq1_inter_codebooks); @@ -277,7 +277,7 @@ static int svq1_decode_block_non_intra(GetBitContext *bitbuf, uint8_t *pixels, return 0; } -static int svq1_decode_motion_vector(GetBitContext *bitbuf, svq1_pmv *mv, +static int svq1_decode_motion_vector(BitstreamContext *bc, svq1_pmv *mv, svq1_pmv **pmv) { int diff; @@ -285,11 +285,11 @@ static int svq1_decode_motion_vector(GetBitContext *bitbuf, svq1_pmv *mv, for (i = 0; i < 2; i++) { /* get motion code */ - diff = get_vlc2(bitbuf, svq1_motion_component.table, 7, 2); + diff = bitstream_read_vlc(bc, svq1_motion_component.table, 7, 2); if (diff < 0) return AVERROR_INVALIDDATA; else if (diff) { - if (get_bits1(bitbuf)) + if (bitstream_read_bit(bc)) diff = -diff; } @@ -320,7 +320,7 @@ static void svq1_skip_block(uint8_t *current, uint8_t *previous, } } -static int svq1_motion_inter_block(HpelDSPContext *hdsp, GetBitContext *bitbuf, +static int svq1_motion_inter_block(HpelDSPContext *hdsp, BitstreamContext *bc, uint8_t *current, uint8_t *previous, ptrdiff_t pitch, svq1_pmv *motion, int x, int y, int width, int height) @@ -341,7 +341,7 @@ static int svq1_motion_inter_block(HpelDSPContext *hdsp, GetBitContext *bitbuf, pmv[2] = &motion[x / 8 + 4]; } - result = svq1_decode_motion_vector(bitbuf, &mv, pmv); + result = svq1_decode_motion_vector(bc, &mv, pmv); if (result != 0) return result; @@ -364,7 +364,7 @@ static int svq1_motion_inter_block(HpelDSPContext *hdsp, GetBitContext *bitbuf, return 0; } -static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbuf, +static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, BitstreamContext *bc, uint8_t *current, uint8_t *previous, ptrdiff_t pitch, svq1_pmv *motion, int x, int y, int width, int height) @@ -385,7 +385,7 @@ static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbu pmv[2] = &motion[(x / 8) + 4]; } - result = svq1_decode_motion_vector(bitbuf, &mv, pmv); + result = svq1_decode_motion_vector(bc, &mv, pmv); if (result != 0) return result; @@ -398,7 +398,7 @@ static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbu } else { pmv[1] = &motion[(x / 8) + 3]; } - result = svq1_decode_motion_vector(bitbuf, &motion[0], pmv); + result = svq1_decode_motion_vector(bc, &motion[0], pmv); if (result != 0) return result; @@ -407,7 +407,7 @@ static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbu pmv[1] = &motion[0]; pmv[2] = &motion[(x / 8) + 1]; - result = svq1_decode_motion_vector(bitbuf, &motion[(x / 8) + 2], pmv); + result = svq1_decode_motion_vector(bc, &motion[(x / 8) + 2], pmv); if (result != 0) return result; @@ -416,7 +416,7 @@ static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbu pmv[2] = &motion[(x / 8) + 2]; pmv[3] = &motion[(x / 8) + 3]; - result = svq1_decode_motion_vector(bitbuf, pmv[3], pmv); + result = svq1_decode_motion_vector(bc, pmv[3], pmv); if (result != 0) return result; @@ -446,7 +446,7 @@ static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbu } static int svq1_decode_delta_block(AVCodecContext *avctx, HpelDSPContext *hdsp, - GetBitContext *bitbuf, + BitstreamContext *bc, uint8_t *current, uint8_t *previous, ptrdiff_t pitch, svq1_pmv *motion, int x, int y, int width, int height) @@ -455,7 +455,7 @@ static int svq1_decode_delta_block(AVCodecContext *avctx, HpelDSPContext *hdsp, int result = 0; /* get block type */ - block_type = get_vlc2(bitbuf, svq1_block_type.table, 2, 2); + block_type = bitstream_read_vlc(bc, svq1_block_type.table, 2, 2); /* reset motion vectors */ if (block_type == SVQ1_BLOCK_SKIP || block_type == SVQ1_BLOCK_INTRA) { @@ -473,45 +473,45 @@ static int svq1_decode_delta_block(AVCodecContext *avctx, HpelDSPContext *hdsp, break; case SVQ1_BLOCK_INTER: - result = svq1_motion_inter_block(hdsp, bitbuf, current, previous, + result = svq1_motion_inter_block(hdsp, bc, current, previous, pitch, motion, x, y, width, height); if (result != 0) { ff_dlog(avctx, "Error in svq1_motion_inter_block %i\n", result); break; } - result = svq1_decode_block_non_intra(bitbuf, current, pitch); + result = svq1_decode_block_non_intra(bc, current, pitch); break; case SVQ1_BLOCK_INTER_4V: - result = svq1_motion_inter_4v_block(hdsp, bitbuf, current, previous, + result = svq1_motion_inter_4v_block(hdsp, bc, current, previous, pitch, motion, x, y, width, height); if (result != 0) { ff_dlog(avctx, "Error in svq1_motion_inter_4v_block %i\n", result); break; } - result = svq1_decode_block_non_intra(bitbuf, current, pitch); + result = svq1_decode_block_non_intra(bc, current, pitch); break; case SVQ1_BLOCK_INTRA: - result = svq1_decode_block_intra(bitbuf, current, pitch); + result = svq1_decode_block_intra(bc, current, pitch); break; } return result; } -static void svq1_parse_string(GetBitContext *bitbuf, uint8_t *out) +static void svq1_parse_string(BitstreamContext *bc, uint8_t *out) { uint8_t seed; int i; - out[0] = get_bits(bitbuf, 8); + out[0] = bitstream_read(bc, 8); seed = string_table[out[0]]; for (i = 1; i <= out[0]; i++) { - out[i] = get_bits(bitbuf, 8) ^ seed; + out[i] = bitstream_read(bc, 8) ^ seed; seed = string_table[out[i] ^ seed]; } } @@ -519,14 +519,14 @@ static void svq1_parse_string(GetBitContext *bitbuf, uint8_t *out) static int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame) { SVQ1Context *s = avctx->priv_data; - GetBitContext *bitbuf = &s->gb; + BitstreamContext *bc = &s->bc; int frame_size_code; - skip_bits(bitbuf, 8); /* temporal_reference */ + bitstream_skip(bc, 8); /* temporal_reference */ /* frame type */ s->nonref = 0; - switch (get_bits(bitbuf, 2)) { + switch (bitstream_read(bc, 2)) { case 0: frame->pict_type = AV_PICTURE_TYPE_I; break; @@ -543,10 +543,9 @@ static int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame) if (frame->pict_type == AV_PICTURE_TYPE_I) { /* unknown fields */ if (s->frame_code == 0x50 || s->frame_code == 0x60) { - int csum = get_bits(bitbuf, 16); + int csum = bitstream_read(bc, 16); - csum = ff_svq1_packet_checksum(bitbuf->buffer, - bitbuf->size_in_bits >> 3, + csum = ff_svq1_packet_checksum(bc->buffer, bc->size_in_bits >> 3, csum); ff_dlog(avctx, "%s checksum (%02x) for packet data\n", @@ -556,23 +555,23 @@ static int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame) if ((s->frame_code ^ 0x10) >= 0x50) { uint8_t msg[256]; - svq1_parse_string(bitbuf, msg); + svq1_parse_string(bc, msg); av_log(avctx, AV_LOG_INFO, "embedded message: \"%s\"\n", (char *)msg); } - skip_bits(bitbuf, 2); - skip_bits(bitbuf, 2); - skip_bits1(bitbuf); + bitstream_skip(bc, 2); + bitstream_skip(bc, 2); + bitstream_skip(bc, 1); /* load frame size */ - frame_size_code = get_bits(bitbuf, 3); + frame_size_code = bitstream_read(bc, 3); if (frame_size_code == 7) { /* load width, height (12 bits each) */ - s->width = get_bits(bitbuf, 12); - s->height = get_bits(bitbuf, 12); + s->width = bitstream_read(bc, 12); + s->height = bitstream_read(bc, 12); if (!s->width || !s->height) return AVERROR_INVALIDDATA; @@ -584,22 +583,22 @@ static int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame) } /* unknown fields */ - if (get_bits1(bitbuf) == 1) { - skip_bits1(bitbuf); /* use packet checksum if (1) */ - skip_bits1(bitbuf); /* component checksums after image data if (1) */ + if (bitstream_read_bit(bc) == 1) { + bitstream_skip(bc, 1); /* use packet checksum if (1) */ + bitstream_skip(bc, 1); /* component checksums after image data if (1) */ - if (get_bits(bitbuf, 2) != 0) + if (bitstream_read(bc, 2) != 0) return AVERROR_INVALIDDATA; } - if (get_bits1(bitbuf) == 1) { - skip_bits1(bitbuf); - skip_bits(bitbuf, 4); - skip_bits1(bitbuf); - skip_bits(bitbuf, 2); + if (bitstream_read_bit(bc) == 1) { + bitstream_skip(bc, 1); + bitstream_skip(bc, 4); + bitstream_skip(bc, 1); + bitstream_skip(bc, 2); - while (get_bits1(bitbuf) == 1) - skip_bits(bitbuf, 8); + while (bitstream_read_bit(bc) == 1) + bitstream_skip(bc, 8); } return 0; @@ -617,10 +616,10 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, svq1_pmv *pmv; /* initialize bit buffer */ - init_get_bits(&s->gb, buf, buf_size * 8); + bitstream_init(&s->bc, buf, buf_size * 8); /* decode frame header */ - s->frame_code = get_bits(&s->gb, 22); + s->frame_code = bitstream_read(&s->bc, 22); if ((s->frame_code & ~0x70) || !(s->frame_code & 0x60)) return AVERROR_INVALIDDATA; @@ -642,13 +641,14 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, memcpy(s->pkt_swapped, buf, buf_size); buf = s->pkt_swapped; - init_get_bits(&s->gb, buf, buf_size * 8); - skip_bits(&s->gb, 22); src = (uint32_t *)(s->pkt_swapped + 4); for (i = 0; i < 4; i++) src[i] = ((src[i] << 16) | (src[i] >> 16)) ^ src[7 - i]; + + bitstream_init(&s->bc, buf, buf_size * 8); + bitstream_skip(&s->bc, 22); } result = svq1_decode_frame_header(avctx, cur); @@ -695,7 +695,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, /* keyframe */ for (y = 0; y < height; y += 16) { for (x = 0; x < width; x += 16) { - result = svq1_decode_block_intra(&s->gb, ¤t[x], + result = svq1_decode_block_intra(&s->bc, ¤t[x], linesize); if (result != 0) { av_log(avctx, AV_LOG_INFO, @@ -721,7 +721,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, for (y = 0; y < height; y += 16) { for (x = 0; x < width; x += 16) { result = svq1_decode_delta_block(avctx, &s->hdsp, - &s->gb, ¤t[x], + &s->bc, ¤t[x], previous, linesize, pmv, x, y, width, height); if (result != 0) { From 9ab1a3e28371f599afe05aea9f7ca75fd8eb3c3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 23 Apr 2016 15:11:27 +0200 Subject: [PATCH 0573/3374] truemotion2: Convert to the new bitstream reader --- libavcodec/truemotion2.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/libavcodec/truemotion2.c b/libavcodec/truemotion2.c index 172644007c501..99884be4bbe9b 100644 --- a/libavcodec/truemotion2.c +++ b/libavcodec/truemotion2.c @@ -27,9 +27,9 @@ #include #include "avcodec.h" +#include "bitstream.h" #include "bswapdsp.h" #include "bytestream.h" -#include "get_bits.h" #include "internal.h" #define TM2_ESCAPE 0x80000000 @@ -62,7 +62,7 @@ typedef struct TM2Context { AVCodecContext *avctx; AVFrame *pic; - GetBitContext gb; + BitstreamContext bc; BswapDSPContext bdsp; /* TM2 streams */ @@ -117,7 +117,7 @@ static int tm2_read_tree(TM2Context *ctx, uint32_t prefix, int length, TM2Huff * return AVERROR_INVALIDDATA; } - if (!get_bits1(&ctx->gb)) { /* literal */ + if (!bitstream_read_bit(&ctx->bc)) { /* literal */ if (length == 0) { length = 1; } @@ -125,7 +125,7 @@ static int tm2_read_tree(TM2Context *ctx, uint32_t prefix, int length, TM2Huff * av_log(ctx->avctx, AV_LOG_DEBUG, "Too many literals\n"); return AVERROR_INVALIDDATA; } - huff->nums[huff->num] = get_bits_long(&ctx->gb, huff->val_bits); + huff->nums[huff->num] = bitstream_read(&ctx->bc, huff->val_bits); huff->bits[huff->num] = prefix; huff->lens[huff->num] = length; huff->num++; @@ -144,10 +144,10 @@ static int tm2_build_huff_table(TM2Context *ctx, TM2Codes *code) TM2Huff huff; int res = 0; - huff.val_bits = get_bits(&ctx->gb, 5); - huff.max_bits = get_bits(&ctx->gb, 5); - huff.min_bits = get_bits(&ctx->gb, 5); - huff.nodes = get_bits_long(&ctx->gb, 17); + huff.val_bits = bitstream_read(&ctx->bc, 5); + huff.max_bits = bitstream_read(&ctx->bc, 5); + huff.min_bits = bitstream_read(&ctx->bc, 5); + huff.nodes = bitstream_read(&ctx->bc, 17); huff.num = 0; /* check for correct codes parameters */ @@ -222,10 +222,10 @@ static void tm2_free_codes(TM2Codes *code) ff_free_vlc(&code->vlc); } -static inline int tm2_get_token(GetBitContext *gb, TM2Codes *code) +static inline int tm2_get_token(BitstreamContext *bc, TM2Codes *code) { int val; - val = get_vlc2(gb, code->vlc.table, code->bits, 1); + val = bitstream_read_vlc(bc, code->vlc.table, code->bits, 1); return code->recode[val]; } @@ -254,8 +254,8 @@ static int tm2_read_deltas(TM2Context *ctx, int stream_id) int d, mb; int i, v; - d = get_bits(&ctx->gb, 9); - mb = get_bits(&ctx->gb, 5); + d = bitstream_read(&ctx->bc, 9); + mb = bitstream_read(&ctx->bc, 5); if ((d < 1) || (d > TM2_DELTAS) || (mb < 1) || (mb > 32)) { av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect delta table: %i deltas x %i bits\n", d, mb); @@ -263,7 +263,7 @@ static int tm2_read_deltas(TM2Context *ctx, int stream_id) } for (i = 0; i < d; i++) { - v = get_bits_long(&ctx->gb, mb); + v = bitstream_read(&ctx->bc, mb); if (v & (1 << (mb - 1))) ctx->deltas[stream_id][i] = v - (1 << mb); else @@ -306,10 +306,10 @@ static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, i pos = bytestream2_tell(&gb); if (skip <= pos) return AVERROR_INVALIDDATA; - init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8); + bitstream_init(&ctx->bc, buf + pos, (skip - pos) * 8); if ((ret = tm2_read_deltas(ctx, stream_id)) < 0) return ret; - bytestream2_skip(&gb, ((get_bits_count(&ctx->gb) + 31) >> 5) << 2); + bytestream2_skip(&gb, ((bitstream_tell(&ctx->bc) + 31) >> 5) << 2); } } /* skip unused fields */ @@ -323,10 +323,10 @@ static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, i pos = bytestream2_tell(&gb); if (skip <= pos) return AVERROR_INVALIDDATA; - init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8); + bitstream_init(&ctx->bc, buf + pos, (skip - pos) * 8); if ((ret = tm2_build_huff_table(ctx, &codes)) < 0) return ret; - bytestream2_skip(&gb, ((get_bits_count(&ctx->gb) + 31) >> 5) << 2); + bytestream2_skip(&gb, ((bitstream_tell(&ctx->bc) + 31) >> 5) << 2); toks >>= 1; /* check if we have sane number of tokens */ @@ -342,13 +342,13 @@ static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, i pos = bytestream2_tell(&gb); if (skip <= pos) return AVERROR_INVALIDDATA; - init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8); + bitstream_init(&ctx->bc, buf + pos, (skip - pos) * 8); for (i = 0; i < toks; i++) { - if (get_bits_left(&ctx->gb) <= 0) { + if (bitstream_bits_left(&ctx->bc) <= 0) { av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of tokens: %i\n", toks); return AVERROR_INVALIDDATA; } - ctx->tokens[stream_id][i] = tm2_get_token(&ctx->gb, &codes); + ctx->tokens[stream_id][i] = tm2_get_token(&ctx->bc, &codes); if (stream_id <= TM2_MOT && ctx->tokens[stream_id][i] >= TM2_DELTAS) { av_log(ctx->avctx, AV_LOG_ERROR, "Invalid delta token index %d for type %d, n=%d\n", ctx->tokens[stream_id][i], stream_id, i); From 0ac07d0b8d75cce10a139c868d415284a9d2ca48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 23 Apr 2016 15:13:41 +0200 Subject: [PATCH 0574/3374] tiertex: Convert to the new bitstream reader --- libavcodec/tiertexseqv.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/libavcodec/tiertexseqv.c b/libavcodec/tiertexseqv.c index 8ca7edfeac99f..d95226678b1e7 100644 --- a/libavcodec/tiertexseqv.c +++ b/libavcodec/tiertexseqv.c @@ -26,7 +26,7 @@ #define BITSTREAM_READER_LE #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "internal.h" @@ -41,18 +41,18 @@ static const unsigned char *seq_unpack_rle_block(const unsigned char *src, unsigned char *dst, int dst_size) { int i, len, sz; - GetBitContext gb; + BitstreamContext bc; int code_table[64]; /* get the rle codes */ - init_get_bits(&gb, src, (src_end - src) * 8); + bitstream_init(&bc, src, (src_end - src) * 8); for (i = 0, sz = 0; i < 64 && sz < dst_size; i++) { - if (get_bits_left(&gb) < 4) + if (bitstream_bits_left(&bc) < 4) return NULL; - code_table[i] = get_sbits(&gb, 4); + code_table[i] = bitstream_read_signed(&bc, 4); sz += FFABS(code_table[i]); } - src += (get_bits_count(&gb) + 7) / 8; + src += (bitstream_tell(&bc) + 7) / 8; /* do the rle unpacking */ for (i = 0; i < 64 && dst_size > 0; i++) { @@ -81,7 +81,7 @@ static const unsigned char *seq_decode_op1(SeqVideoContext *seq, { const unsigned char *color_table; int b, i, len, bits; - GetBitContext gb; + BitstreamContext bc; unsigned char block[8 * 8]; if (src_end - src < 1) @@ -113,10 +113,11 @@ static const unsigned char *seq_decode_op1(SeqVideoContext *seq, return NULL; color_table = src; src += len; - init_get_bits(&gb, src, bits * 8 * 8); src += bits * 8; + bitstream_init(&bc, src, bits * 8 * 8); + src += bits * 8; for (b = 0; b < 8; b++) { for (i = 0; i < 8; i++) - dst[i] = color_table[get_bits(&gb, bits)]; + dst[i] = color_table[bitstream_read(&bc, bits)]; dst += seq->frame->linesize[0]; } } @@ -164,7 +165,7 @@ static const unsigned char *seq_decode_op3(SeqVideoContext *seq, static int seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int data_size) { const unsigned char *data_end = data + data_size; - GetBitContext gb; + BitstreamContext bc; int flags, i, j, x, y, op; unsigned char c[3]; unsigned char *dst; @@ -187,11 +188,12 @@ static int seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int if (flags & 2) { if (data_end - data < 128) return AVERROR_INVALIDDATA; - init_get_bits(&gb, data, 128 * 8); data += 128; + bitstream_init(&bc, data, 128 * 8); + data += 128; for (y = 0; y < 128; y += 8) for (x = 0; x < 256; x += 8) { dst = &seq->frame->data[0][y * seq->frame->linesize[0] + x]; - op = get_bits(&gb, 2); + op = bitstream_read(&bc, 2); switch (op) { case 1: data = seq_decode_op1(seq, data, data_end, dst); From 8e4cadea5d20e463e9d6cf00fc58841f17c811e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Thu, 14 Apr 2016 10:32:31 +0200 Subject: [PATCH 0575/3374] truespeech: Convert to the new bitstream reader --- libavcodec/truespeech.c | 88 +++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/libavcodec/truespeech.c b/libavcodec/truespeech.c index b2195baef4047..48e2126ba6473 100644 --- a/libavcodec/truespeech.c +++ b/libavcodec/truespeech.c @@ -21,12 +21,14 @@ #include "libavutil/channel_layout.h" #include "libavutil/intreadwrite.h" + #include "avcodec.h" +#include "bitstream.h" #include "bswapdsp.h" -#include "get_bits.h" #include "internal.h" #include "truespeech_data.h" + /** * @file * TrueSpeech decoder. @@ -77,50 +79,50 @@ static av_cold int truespeech_decode_init(AVCodecContext * avctx) static void truespeech_read_frame(TSContext *dec, const uint8_t *input) { - GetBitContext gb; + BitstreamContext bc; dec->bdsp.bswap_buf((uint32_t *) dec->buffer, (const uint32_t *) input, 8); - init_get_bits(&gb, dec->buffer, 32 * 8); - - dec->vector[7] = ts_codebook[7][get_bits(&gb, 3)]; - dec->vector[6] = ts_codebook[6][get_bits(&gb, 3)]; - dec->vector[5] = ts_codebook[5][get_bits(&gb, 3)]; - dec->vector[4] = ts_codebook[4][get_bits(&gb, 4)]; - dec->vector[3] = ts_codebook[3][get_bits(&gb, 4)]; - dec->vector[2] = ts_codebook[2][get_bits(&gb, 4)]; - dec->vector[1] = ts_codebook[1][get_bits(&gb, 5)]; - dec->vector[0] = ts_codebook[0][get_bits(&gb, 5)]; - dec->flag = get_bits1(&gb); - - dec->offset1[0] = get_bits(&gb, 4) << 4; - dec->offset2[3] = get_bits(&gb, 7); - dec->offset2[2] = get_bits(&gb, 7); - dec->offset2[1] = get_bits(&gb, 7); - dec->offset2[0] = get_bits(&gb, 7); - - dec->offset1[1] = get_bits(&gb, 4); - dec->pulseval[1] = get_bits(&gb, 14); - dec->pulseval[0] = get_bits(&gb, 14); - - dec->offset1[1] |= get_bits(&gb, 4) << 4; - dec->pulseval[3] = get_bits(&gb, 14); - dec->pulseval[2] = get_bits(&gb, 14); - - dec->offset1[0] |= get_bits1(&gb); - dec->pulsepos[0] = get_bits_long(&gb, 27); - dec->pulseoff[0] = get_bits(&gb, 4); - - dec->offset1[0] |= get_bits1(&gb) << 1; - dec->pulsepos[1] = get_bits_long(&gb, 27); - dec->pulseoff[1] = get_bits(&gb, 4); - - dec->offset1[0] |= get_bits1(&gb) << 2; - dec->pulsepos[2] = get_bits_long(&gb, 27); - dec->pulseoff[2] = get_bits(&gb, 4); - - dec->offset1[0] |= get_bits1(&gb) << 3; - dec->pulsepos[3] = get_bits_long(&gb, 27); - dec->pulseoff[3] = get_bits(&gb, 4); + bitstream_init(&bc, dec->buffer, 32 * 8); + + dec->vector[7] = ts_codebook[7][bitstream_read(&bc, 3)]; + dec->vector[6] = ts_codebook[6][bitstream_read(&bc, 3)]; + dec->vector[5] = ts_codebook[5][bitstream_read(&bc, 3)]; + dec->vector[4] = ts_codebook[4][bitstream_read(&bc, 4)]; + dec->vector[3] = ts_codebook[3][bitstream_read(&bc, 4)]; + dec->vector[2] = ts_codebook[2][bitstream_read(&bc, 4)]; + dec->vector[1] = ts_codebook[1][bitstream_read(&bc, 5)]; + dec->vector[0] = ts_codebook[0][bitstream_read(&bc, 5)]; + dec->flag = bitstream_read_bit(&bc); + + dec->offset1[0] = bitstream_read(&bc, 4) << 4; + dec->offset2[3] = bitstream_read(&bc, 7); + dec->offset2[2] = bitstream_read(&bc, 7); + dec->offset2[1] = bitstream_read(&bc, 7); + dec->offset2[0] = bitstream_read(&bc, 7); + + dec->offset1[1] = bitstream_read(&bc, 4); + dec->pulseval[1] = bitstream_read(&bc, 14); + dec->pulseval[0] = bitstream_read(&bc, 14); + + dec->offset1[1] |= bitstream_read(&bc, 4) << 4; + dec->pulseval[3] = bitstream_read(&bc, 14); + dec->pulseval[2] = bitstream_read(&bc, 14); + + dec->offset1[0] |= bitstream_read_bit(&bc); + dec->pulsepos[0] = bitstream_read(&bc, 27); + dec->pulseoff[0] = bitstream_read(&bc, 4); + + dec->offset1[0] |= bitstream_read_bit(&bc) << 1; + dec->pulsepos[1] = bitstream_read(&bc, 27); + dec->pulseoff[1] = bitstream_read(&bc, 4); + + dec->offset1[0] |= bitstream_read_bit(&bc) << 2; + dec->pulsepos[2] = bitstream_read(&bc, 27); + dec->pulseoff[2] = bitstream_read(&bc, 4); + + dec->offset1[0] |= bitstream_read_bit(&bc) << 3; + dec->pulsepos[3] = bitstream_read(&bc, 27); + dec->pulseoff[3] = bitstream_read(&bc, 4); } static void truespeech_correlate_filter(TSContext *dec) From 0bea79afa6cc71e38d58350d05cdeb33e97f6234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Thu, 14 Apr 2016 10:42:27 +0200 Subject: [PATCH 0576/3374] tscc2: Convert to the new bitstream reader --- libavcodec/tscc2.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/libavcodec/tscc2.c b/libavcodec/tscc2.c index d3d45e4d226a8..d86428afc6f8a 100644 --- a/libavcodec/tscc2.c +++ b/libavcodec/tscc2.c @@ -28,8 +28,8 @@ #define BITSTREAM_READER_LE #include "avcodec.h" +#include "bitstream.h" #include "bytestream.h" -#include "get_bits.h" #include "internal.h" #include "mathops.h" #include "tscc2data.h" @@ -41,7 +41,7 @@ typedef struct TSCC2Context { uint8_t *slice_quants; int quant[2]; int q[2][3]; - GetBitContext gb; + BitstreamContext bc; VLC dc_vlc, nc_vlc[NUM_VLC_SETS], ac_vlc[NUM_VLC_SETS]; int block[16]; @@ -127,21 +127,21 @@ static void tscc2_idct4_put(int *in, int q[3], uint8_t *dst, int stride) static int tscc2_decode_mb(TSCC2Context *c, int *q, int vlc_set, uint8_t *dst, int stride, int plane) { - GetBitContext *gb = &c->gb; + BitstreamContext *bc = &c->bc; int prev_dc, dc, nc, ac, bpos, val; int i, j, k, l; - if (get_bits1(gb)) { - if (get_bits1(gb)) { - val = get_bits(gb, 8); + if (bitstream_read_bit(bc)) { + if (bitstream_read_bit(bc)) { + val = bitstream_read(bc, 8); for (i = 0; i < 8; i++, dst += stride) memset(dst, val, 16); } else { - if (get_bits_left(gb) < 16 * 8 * 8) + if (bitstream_bits_left(bc) < 16 * 8 * 8) return AVERROR_INVALIDDATA; for (i = 0; i < 8; i++) { for (j = 0; j < 16; j++) - dst[j] = get_bits(gb, 8); + dst[j] = bitstream_read(bc, 8); dst += stride; } } @@ -152,30 +152,30 @@ static int tscc2_decode_mb(TSCC2Context *c, int *q, int vlc_set, for (j = 0; j < 2; j++) { for (k = 0; k < 4; k++) { if (!(j | k)) { - dc = get_bits(gb, 8); + dc = bitstream_read(bc, 8); } else { - dc = get_vlc2(gb, c->dc_vlc.table, 9, 2); + dc = bitstream_read_vlc(bc, c->dc_vlc.table, 9, 2); if (dc == -1) return AVERROR_INVALIDDATA; if (dc == 0x100) - dc = get_bits(gb, 8); + dc = bitstream_read(bc, 8); } dc = (dc + prev_dc) & 0xFF; prev_dc = dc; c->block[0] = dc; - nc = get_vlc2(gb, c->nc_vlc[vlc_set].table, 9, 1); + nc = bitstream_read_vlc(bc, c->nc_vlc[vlc_set].table, 9, 1); if (nc == -1) return AVERROR_INVALIDDATA; bpos = 1; memset(c->block + 1, 0, 15 * sizeof(*c->block)); for (l = 0; l < nc; l++) { - ac = get_vlc2(gb, c->ac_vlc[vlc_set].table, 9, 2); + ac = bitstream_read_vlc(bc, c->ac_vlc[vlc_set].table, 9, 2); if (ac == -1) return AVERROR_INVALIDDATA; if (ac == 0x1000) - ac = get_bits(gb, 12); + ac = bitstream_read(bc, 12); bpos += ac & 0xF; if (bpos >= 16) return AVERROR_INVALIDDATA; @@ -195,7 +195,7 @@ static int tscc2_decode_slice(TSCC2Context *c, int mb_y, int i, mb_x, q, ret; int off; - init_get_bits(&c->gb, buf, buf_size * 8); + bitstream_init(&c->bc, buf, buf_size * 8); for (mb_x = 0; mb_x < c->mb_width; mb_x++) { q = c->slice_quants[mb_x + c->mb_width * mb_y]; From 85f760fedd49816f3a197da22f4c8e33d1b3dda7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Thu, 14 Apr 2016 10:59:22 +0200 Subject: [PATCH 0577/3374] twinvq: Convert to the new bitstream reader --- libavcodec/twinvq_data.h | 2 +- libavcodec/twinvqdec.c | 42 ++++++++++++++++++++-------------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/libavcodec/twinvq_data.h b/libavcodec/twinvq_data.h index 01a54a5ea87a4..cc7ba59093302 100644 --- a/libavcodec/twinvq_data.h +++ b/libavcodec/twinvq_data.h @@ -130,7 +130,7 @@ static const uint16_t bark_tab_s44_128[] = { /** * TwinVQ codebooks. They are coded in a struct so we can use code such as * - * float val = tab.fcb0808l[get_bits(gb, 12)]; + * float val = tab.fcb0808l[bitstream_read(bc, 12)]; * * without risking a segfault on malformed files. */ diff --git a/libavcodec/twinvqdec.c b/libavcodec/twinvqdec.c index 56df10557a687..6355ad4ed2926 100644 --- a/libavcodec/twinvqdec.c +++ b/libavcodec/twinvqdec.c @@ -23,8 +23,9 @@ #include #include "libavutil/channel_layout.h" + #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "internal.h" #include "twinvq.h" #include "twinvq_data.h" @@ -235,7 +236,7 @@ static void dec_bark_env(TwinVQContext *tctx, const uint8_t *in, int use_hist, } } -static void read_cb_data(TwinVQContext *tctx, GetBitContext *gb, +static void read_cb_data(TwinVQContext *tctx, BitstreamContext *bc, uint8_t *dst, enum TwinVQFrameType ftype) { int i; @@ -243,8 +244,8 @@ static void read_cb_data(TwinVQContext *tctx, GetBitContext *gb, for (i = 0; i < tctx->n_div[ftype]; i++) { int bs_second_part = (i >= tctx->bits_main_spec_change[ftype]); - *dst++ = get_bits(gb, tctx->bits_main_spec[0][ftype][bs_second_part]); - *dst++ = get_bits(gb, tctx->bits_main_spec[1][ftype][bs_second_part]); + *dst++ = bitstream_read(bc, tctx->bits_main_spec[0][ftype][bs_second_part]); + *dst++ = bitstream_read(bc, tctx->bits_main_spec[1][ftype][bs_second_part]); } } @@ -255,13 +256,13 @@ static int twinvq_read_bitstream(AVCodecContext *avctx, TwinVQContext *tctx, const TwinVQModeTab *mtab = tctx->mtab; int channels = tctx->avctx->channels; int sub; - GetBitContext gb; + BitstreamContext bc; int i, j, k; - init_get_bits(&gb, buf, buf_size * 8); - skip_bits(&gb, get_bits(&gb, 8)); + bitstream_init(&bc, buf, buf_size * 8); + bitstream_skip(&bc, bitstream_read(&bc, 8)); - bits->window_type = get_bits(&gb, TWINVQ_WINDOW_TYPE_BITS); + bits->window_type = bitstream_read(&bc, TWINVQ_WINDOW_TYPE_BITS); if (bits->window_type > 8) { av_log(avctx, AV_LOG_ERROR, "Invalid window type, broken sample?\n"); @@ -272,43 +273,42 @@ static int twinvq_read_bitstream(AVCodecContext *avctx, TwinVQContext *tctx, sub = mtab->fmode[bits->ftype].sub; - read_cb_data(tctx, &gb, bits->main_coeffs, bits->ftype); + read_cb_data(tctx, &bc, bits->main_coeffs, bits->ftype); for (i = 0; i < channels; i++) for (j = 0; j < sub; j++) for (k = 0; k < mtab->fmode[bits->ftype].bark_n_coef; k++) bits->bark1[i][j][k] = - get_bits(&gb, mtab->fmode[bits->ftype].bark_n_bit); + bitstream_read(&bc, mtab->fmode[bits->ftype].bark_n_bit); for (i = 0; i < channels; i++) for (j = 0; j < sub; j++) - bits->bark_use_hist[i][j] = get_bits1(&gb); + bits->bark_use_hist[i][j] = bitstream_read_bit(&bc); if (bits->ftype == TWINVQ_FT_LONG) { for (i = 0; i < channels; i++) - bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS); + bits->gain_bits[i] = bitstream_read(&bc, TWINVQ_GAIN_BITS); } else { for (i = 0; i < channels; i++) { - bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS); + bits->gain_bits[i] = bitstream_read(&bc, TWINVQ_GAIN_BITS); for (j = 0; j < sub; j++) - bits->sub_gain_bits[i * sub + j] = get_bits(&gb, - TWINVQ_SUB_GAIN_BITS); + bits->sub_gain_bits[i * sub + j] = bitstream_read(&bc, TWINVQ_SUB_GAIN_BITS); } } for (i = 0; i < channels; i++) { - bits->lpc_hist_idx[i] = get_bits(&gb, mtab->lsp_bit0); - bits->lpc_idx1[i] = get_bits(&gb, mtab->lsp_bit1); + bits->lpc_hist_idx[i] = bitstream_read(&bc, mtab->lsp_bit0); + bits->lpc_idx1[i] = bitstream_read(&bc, mtab->lsp_bit1); for (j = 0; j < mtab->lsp_split; j++) - bits->lpc_idx2[i][j] = get_bits(&gb, mtab->lsp_bit2); + bits->lpc_idx2[i][j] = bitstream_read(&bc, mtab->lsp_bit2); } if (bits->ftype == TWINVQ_FT_LONG) { - read_cb_data(tctx, &gb, bits->ppc_coeffs, 3); + read_cb_data(tctx, &bc, bits->ppc_coeffs, 3); for (i = 0; i < channels; i++) { - bits->p_coef[i] = get_bits(&gb, mtab->ppc_period_bit); - bits->g_coef[i] = get_bits(&gb, mtab->pgain_bit); + bits->p_coef[i] = bitstream_read(&bc, mtab->ppc_period_bit); + bits->g_coef[i] = bitstream_read(&bc, mtab->pgain_bit); } } From 104a4289f925c600c13035de6c282fe656510a27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Thu, 14 Apr 2016 11:07:15 +0200 Subject: [PATCH 0578/3374] utvideodec: Convert to the new bitstream reader --- libavcodec/utvideodec.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/libavcodec/utvideodec.c b/libavcodec/utvideodec.c index 3a581568dd2d8..29de815d4e0cb 100644 --- a/libavcodec/utvideodec.c +++ b/libavcodec/utvideodec.c @@ -28,10 +28,11 @@ #include #include "libavutil/intreadwrite.h" + #include "avcodec.h" +#include "bitstream.h" #include "bswapdsp.h" #include "bytestream.h" -#include "get_bits.h" #include "thread.h" #include "utvideo.h" @@ -85,7 +86,7 @@ static int decode_plane(UtvideoContext *c, int plane_no, int i, j, slice, pix; int sstart, send; VLC vlc; - GetBitContext gb; + BitstreamContext bc; int prev, fsym; const int cmask = ~(!plane_no && c->avctx->pix_fmt == AV_PIX_FMT_YUV420P); @@ -146,17 +147,17 @@ static int decode_plane(UtvideoContext *c, int plane_no, c->bdsp.bswap_buf((uint32_t *) c->slice_bits, (uint32_t *) c->slice_bits, (slice_data_end - slice_data_start + 3) >> 2); - init_get_bits(&gb, c->slice_bits, slice_size * 8); + bitstream_init(&bc, c->slice_bits, slice_size * 8); prev = 0x80; for (j = sstart; j < send; j++) { for (i = 0; i < width * step; i += step) { - if (get_bits_left(&gb) <= 0) { + if (bitstream_bits_left(&bc) <= 0) { av_log(c->avctx, AV_LOG_ERROR, "Slice decoding ran out of bits\n"); goto fail; } - pix = get_vlc2(&gb, vlc.table, vlc.bits, 4); + pix = bitstream_read_vlc(&bc, vlc.table, vlc.bits, 4); if (pix < 0) { av_log(c->avctx, AV_LOG_ERROR, "Decoding error\n"); goto fail; @@ -169,9 +170,9 @@ static int decode_plane(UtvideoContext *c, int plane_no, } dest += stride; } - if (get_bits_left(&gb) > 32) + if (bitstream_bits_left(&bc) > 32) av_log(c->avctx, AV_LOG_WARNING, - "%d bits left after decoding slice\n", get_bits_left(&gb)); + "%d bits left after decoding slice\n", bitstream_bits_left(&bc)); } ff_free_vlc(&vlc); From e5bdfc679004199c4a1837e256046331e5e4e713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Thu, 14 Apr 2016 11:52:48 +0200 Subject: [PATCH 0579/3374] vble: Convert to the new bitstream reader --- libavcodec/vble.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/libavcodec/vble.c b/libavcodec/vble.c index 1a78036731227..fef10903ddeb1 100644 --- a/libavcodec/vble.c +++ b/libavcodec/vble.c @@ -28,7 +28,7 @@ #define BITSTREAM_READER_LE #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "huffyuvdsp.h" #include "internal.h" #include "mathops.h" @@ -41,18 +41,18 @@ typedef struct VBLEContext { uint8_t *val; /* First holds the lengths of vlc symbols and then their values */ } VBLEContext; -static uint8_t vble_read_reverse_unary(GetBitContext *gb) +static uint8_t vble_read_reverse_unary(BitstreamContext *bc) { /* At most we need to read 9 bits total to get indices up to 8 */ - uint8_t val = show_bits(gb, 8); + uint8_t val = bitstream_peek(bc, 8); if (val) { val = 7 - av_log2_16bit(ff_reverse[val]); - skip_bits(gb, val + 1); + bitstream_skip(bc, val + 1); return val; } else { - skip_bits(gb, 8); - if (get_bits1(gb)) + bitstream_skip(bc, 8); + if (bitstream_read_bit(bc)) return 8; } @@ -60,13 +60,13 @@ static uint8_t vble_read_reverse_unary(GetBitContext *gb) return UINT8_MAX; } -static int vble_unpack(VBLEContext *ctx, GetBitContext *gb) +static int vble_unpack(VBLEContext *ctx, BitstreamContext *bc) { int i; /* Read all the lengths in first */ for (i = 0; i < ctx->size; i++) { - ctx->val[i] = vble_read_reverse_unary(gb); + ctx->val[i] = vble_read_reverse_unary(bc); if (ctx->val[i] == UINT8_MAX) return -1; @@ -74,12 +74,12 @@ static int vble_unpack(VBLEContext *ctx, GetBitContext *gb) for (i = 0; i < ctx->size; i++) { /* Check we have enough bits left */ - if (get_bits_left(gb) < ctx->val[i]) + if (bitstream_bits_left(bc) < ctx->val[i]) return -1; /* get_bits can't take a length of 0 */ if (ctx->val[i]) - ctx->val[i] = (1 << ctx->val[i]) + get_bits(gb, ctx->val[i]) - 1; + ctx->val[i] = (1 << ctx->val[i]) + bitstream_read(bc, ctx->val[i]) - 1; } return 0; @@ -118,7 +118,7 @@ static int vble_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, { VBLEContext *ctx = avctx->priv_data; AVFrame *pic = data; - GetBitContext gb; + BitstreamContext bc; const uint8_t *src = avpkt->data; int version; int offset = 0; @@ -140,10 +140,10 @@ static int vble_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (version != 1) av_log(avctx, AV_LOG_WARNING, "Unsupported VBLE Version: %d\n", version); - init_get_bits(&gb, src + 4, (avpkt->size - 4) * 8); + bitstream_init(&bc, src + 4, (avpkt->size - 4) * 8); /* Unpack */ - if (vble_unpack(ctx, &gb) < 0) { + if (vble_unpack(ctx, &bc) < 0) { av_log(avctx, AV_LOG_ERROR, "Invalid Code\n"); return AVERROR_INVALIDDATA; } From 0536e7d78248d8c563f21271fa5ace0b4f38c727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Thu, 14 Apr 2016 11:59:21 +0200 Subject: [PATCH 0580/3374] vima: Convert to the new bitstream reader --- libavcodec/vima.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/libavcodec/vima.c b/libavcodec/vima.c index 6f539a86b62c2..0db18972a2318 100644 --- a/libavcodec/vima.c +++ b/libavcodec/vima.c @@ -29,7 +29,7 @@ #include "adpcm_data.h" #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "internal.h" static int predict_table_init = 0; @@ -118,7 +118,7 @@ static av_cold int decode_init(AVCodecContext *avctx) static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *pkt) { - GetBitContext gb; + BitstreamContext bc; AVFrame *frame = data; int16_t pcm_data[2]; uint32_t samples; @@ -129,19 +129,19 @@ static int decode_frame(AVCodecContext *avctx, void *data, if (pkt->size < 13) return AVERROR_INVALIDDATA; - if ((ret = init_get_bits8(&gb, pkt->data, pkt->size)) < 0) + if ((ret = bitstream_init8(&bc, pkt->data, pkt->size)) < 0) return ret; - samples = get_bits_long(&gb, 32); + samples = bitstream_read(&bc, 32); if (samples == 0xffffffff) { - skip_bits_long(&gb, 32); - samples = get_bits_long(&gb, 32); + bitstream_skip(&bc, 32); + samples = bitstream_read(&bc, 32); } if (samples > pkt->size * 2) return AVERROR_INVALIDDATA; - channel_hint[0] = get_sbits(&gb, 8); + channel_hint[0] = bitstream_read_signed(&bc, 8); if (channel_hint[0] & 0x80) { channel_hint[0] = ~channel_hint[0]; channels = 2; @@ -149,10 +149,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, avctx->channels = channels; avctx->channel_layout = (channels == 2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; - pcm_data[0] = get_sbits(&gb, 16); + pcm_data[0] = bitstream_read_signed(&bc, 16); if (channels > 1) { - channel_hint[1] = get_sbits(&gb, 8); - pcm_data[1] = get_sbits(&gb, 16); + channel_hint[1] = bitstream_read_signed(&bc, 8); + pcm_data[1] = bitstream_read_signed(&bc, 16); } frame->nb_samples = samples; @@ -170,7 +170,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, step_index = av_clip(step_index, 0, 88); lookup_size = size_table[step_index]; - lookup = get_bits(&gb, lookup_size); + lookup = bitstream_read(&bc, lookup_size); highbit = 1 << (lookup_size - 1); lowbits = highbit - 1; @@ -180,7 +180,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, highbit = 0; if (lookup == lowbits) { - output = get_sbits(&gb, 16); + output = bitstream_read_signed(&bc, 16); } else { int predict_index, diff; From f9c59f26c852cec4dd7e5c04d26ec284a796a919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Fri, 15 Apr 2016 10:50:38 +0200 Subject: [PATCH 0581/3374] wnv1: Convert to the new bitstream reader --- libavcodec/wnv1.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavcodec/wnv1.c b/libavcodec/wnv1.c index d0304c97ad60d..80d66ae96cbea 100644 --- a/libavcodec/wnv1.c +++ b/libavcodec/wnv1.c @@ -25,7 +25,7 @@ */ #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "internal.h" #include "mathops.h" @@ -34,7 +34,7 @@ typedef struct WNV1Context { AVCodecContext *avctx; int shift; - GetBitContext gb; + BitstreamContext bc; } WNV1Context; static const uint16_t code_tab[16][2] = { @@ -49,10 +49,10 @@ static VLC code_vlc; /* returns modified base_value */ static inline int wnv1_get_code(WNV1Context *w, int base_value) { - int v = get_vlc2(&w->gb, code_vlc.table, CODE_VLC_BITS, 1); + int v = bitstream_read_vlc(&w->bc, code_vlc.table, CODE_VLC_BITS, 1); if (v == 15) - return ff_reverse[get_bits(&w->gb, 8 - w->shift)]; + return ff_reverse[bitstream_read(&w->bc, 8 - w->shift)]; else return base_value + ((v - 7) << w->shift); } @@ -90,7 +90,7 @@ static int decode_frame(AVCodecContext *avctx, for (i = 8; i < buf_size; i++) rbuf[i] = ff_reverse[buf[i]]; - init_get_bits(&l->gb, rbuf + 8, (buf_size - 8) * 8); + bitstream_init(&l->bc, rbuf + 8, (buf_size - 8) * 8); if (buf[2] >> 4 == 6) l->shift = 2; From be35ef92a418916f0fceaf18af5f5b768c44117f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Fri, 15 Apr 2016 10:57:22 +0200 Subject: [PATCH 0582/3374] xan: Convert to the new bitstream reader --- libavcodec/xan.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/xan.c b/libavcodec/xan.c index c16c651d7bcc0..33149e5ff7e32 100644 --- a/libavcodec/xan.c +++ b/libavcodec/xan.c @@ -37,8 +37,8 @@ #define BITSTREAM_READER_LE #include "avcodec.h" +#include "bitstream.h" #include "bytestream.h" -#include "get_bits.h" #include "internal.h" #define RUNTIME_GAMMA 0 @@ -124,15 +124,15 @@ static int xan_huffman_decode(unsigned char *dest, int dest_len, unsigned char val = ival; unsigned char *dest_end = dest + dest_len; unsigned char *dest_start = dest; - GetBitContext gb; + BitstreamContext bc; if (ptr_len < 0) return AVERROR_INVALIDDATA; - init_get_bits(&gb, ptr, ptr_len * 8); + bitstream_init(&bc, ptr, ptr_len * 8); while (val != 0x16) { - unsigned idx = val - 0x17 + get_bits1(&gb) * byte; + unsigned idx = val - 0x17 + bitstream_read_bit(&bc) * byte; if (idx >= 2 * byte) return AVERROR_INVALIDDATA; val = src[idx]; From 178b4ea5f9a43009781311af2737284fdca48a5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Fri, 15 Apr 2016 11:03:55 +0200 Subject: [PATCH 0583/3374] xsubdec: Convert to the new bitstream reader --- libavcodec/xsubdec.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/libavcodec/xsubdec.c b/libavcodec/xsubdec.c index 3af300c22bd21..a07f94ce7379d 100644 --- a/libavcodec/xsubdec.c +++ b/libavcodec/xsubdec.c @@ -21,8 +21,9 @@ #include "libavutil/mathematics.h" #include "libavutil/imgutils.h" + #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "bytestream.h" static av_cold int decode_init(AVCodecContext *avctx) { @@ -55,7 +56,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *bitmap; int w, h, x, y, i; int64_t packet_time = 0; - GetBitContext gb; + BitstreamContext bc; int has_alpha = avctx->codec_tag == MKTAG('D','X','S','A'); memset(sub, 0, sizeof(*sub)); @@ -146,15 +147,15 @@ FF_ENABLE_DEPRECATION_WARNINGS #endif // process RLE-compressed data - init_get_bits(&gb, buf, (buf_end - buf) * 8); + bitstream_init(&bc, buf, (buf_end - buf) * 8); bitmap = sub->rects[0]->data[0]; for (y = 0; y < h; y++) { // interlaced: do odd lines if (y == (h + 1) / 2) bitmap = sub->rects[0]->data[0] + w; for (x = 0; x < w; ) { - int log2 = ff_log2_tab[show_bits(&gb, 8)]; - int run = get_bits(&gb, 14 - 4 * (log2 >> 1)); - int color = get_bits(&gb, 2); + int log2 = ff_log2_tab[bitstream_peek(&bc, 8)]; + int run = bitstream_read(&bc, 14 - 4 * (log2 >> 1)); + int color = bitstream_read(&bc, 2); run = FFMIN(run, w - x); // run length 0 means till end of row if (!run) run = w - x; @@ -164,7 +165,7 @@ FF_ENABLE_DEPRECATION_WARNINGS } // interlaced, skip every second line bitmap += w; - align_get_bits(&gb); + bitstream_align(&bc); } *data_size = 1; return buf_size; From 8d1997add6220b7d956dcfdcc9f711efb56ca30d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 16 Apr 2016 17:46:29 +0200 Subject: [PATCH 0584/3374] mpegts: Convert to the new bitstream reader --- libavformat/mpegts.c | 48 +++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 28b6d37bb353c..50244041119c5 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -26,9 +26,11 @@ #include "libavutil/dict.h" #include "libavutil/mathematics.h" #include "libavutil/opt.h" + +#include "libavcodec/bitstream.h" #include "libavcodec/bytestream.h" -#include "libavcodec/get_bits.h" #include "libavcodec/opus.h" + #include "avformat.h" #include "mpegts.h" #include "internal.h" @@ -735,56 +737,56 @@ static void new_pes_packet(PESContext *pes, AVPacket *pkt) static int read_sl_header(PESContext *pes, SLConfigDescr *sl, const uint8_t *buf, int buf_size) { - GetBitContext gb; + BitstreamContext bc; int au_start_flag = 0, au_end_flag = 0, ocr_flag = 0, idle_flag = 0; int padding_flag = 0, padding_bits = 0, inst_bitrate_flag = 0; int dts_flag = -1, cts_flag = -1; int64_t dts = AV_NOPTS_VALUE, cts = AV_NOPTS_VALUE; - init_get_bits(&gb, buf, buf_size * 8); + bitstream_init(&bc, buf, buf_size * 8); if (sl->use_au_start) - au_start_flag = get_bits1(&gb); + au_start_flag = bitstream_read_bit(&bc); if (sl->use_au_end) - au_end_flag = get_bits1(&gb); + au_end_flag = bitstream_read_bit(&bc); if (!sl->use_au_start && !sl->use_au_end) au_start_flag = au_end_flag = 1; if (sl->ocr_len > 0) - ocr_flag = get_bits1(&gb); + ocr_flag = bitstream_read_bit(&bc); if (sl->use_idle) - idle_flag = get_bits1(&gb); + idle_flag = bitstream_read_bit(&bc); if (sl->use_padding) - padding_flag = get_bits1(&gb); + padding_flag = bitstream_read_bit(&bc); if (padding_flag) - padding_bits = get_bits(&gb, 3); + padding_bits = bitstream_read(&bc, 3); if (!idle_flag && (!padding_flag || padding_bits != 0)) { if (sl->packet_seq_num_len) - skip_bits_long(&gb, sl->packet_seq_num_len); + bitstream_skip(&bc, sl->packet_seq_num_len); if (sl->degr_prior_len) - if (get_bits1(&gb)) - skip_bits(&gb, sl->degr_prior_len); + if (bitstream_read_bit(&bc)) + bitstream_skip(&bc, sl->degr_prior_len); if (ocr_flag) - skip_bits_long(&gb, sl->ocr_len); + bitstream_skip(&bc, sl->ocr_len); if (au_start_flag) { if (sl->use_rand_acc_pt) - get_bits1(&gb); + bitstream_read_bit(&bc); if (sl->au_seq_num_len > 0) - skip_bits_long(&gb, sl->au_seq_num_len); + bitstream_skip(&bc, sl->au_seq_num_len); if (sl->use_timestamps) { - dts_flag = get_bits1(&gb); - cts_flag = get_bits1(&gb); + dts_flag = bitstream_read_bit(&bc); + cts_flag = bitstream_read_bit(&bc); } } if (sl->inst_bitrate_len) - inst_bitrate_flag = get_bits1(&gb); + inst_bitrate_flag = bitstream_read_bit(&bc); if (dts_flag == 1) - dts = get_bits64(&gb, sl->timestamp_len); + dts = bitstream_read_63(&bc, sl->timestamp_len); if (cts_flag == 1) - cts = get_bits64(&gb, sl->timestamp_len); + cts = bitstream_read_63(&bc, sl->timestamp_len); if (sl->au_len > 0) - skip_bits_long(&gb, sl->au_len); + bitstream_skip(&bc, sl->au_len); if (inst_bitrate_flag) - skip_bits_long(&gb, sl->inst_bitrate_len); + bitstream_skip(&bc, sl->inst_bitrate_len); } if (dts != AV_NOPTS_VALUE) @@ -795,7 +797,7 @@ static int read_sl_header(PESContext *pes, SLConfigDescr *sl, if (sl->timestamp_len && sl->timestamp_res) avpriv_set_pts_info(pes->st, sl->timestamp_len, 1, sl->timestamp_res); - return (get_bits_count(&gb) + 7) >> 3; + return (bitstream_tell(&bc) + 7) >> 3; } /* return non zero if a packet could be constructed */ From 2cef81a87cd88cf7904ef815ee109e3611fe3fa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 16 Apr 2016 17:51:16 +0200 Subject: [PATCH 0585/3374] ogg: Convert to the new bitstream reader --- libavformat/oggparseflac.c | 22 +++++++++++--------- libavformat/oggparsetheora.c | 39 +++++++++++++++++++----------------- 2 files changed, 33 insertions(+), 28 deletions(-) diff --git a/libavformat/oggparseflac.c b/libavformat/oggparseflac.c index dab1040cc43a2..90b1495c51be3 100644 --- a/libavformat/oggparseflac.c +++ b/libavformat/oggparseflac.c @@ -19,8 +19,10 @@ */ #include -#include "libavcodec/get_bits.h" + +#include "libavcodec/bitstream.h" #include "libavcodec/flac.h" + #include "avformat.h" #include "internal.h" #include "oggdec.h" @@ -33,28 +35,28 @@ flac_header (AVFormatContext * s, int idx) struct ogg *ogg = s->priv_data; struct ogg_stream *os = ogg->streams + idx; AVStream *st = s->streams[idx]; - GetBitContext gb; + BitstreamContext bc; int mdt; if (os->buf[os->pstart] == 0xff) return 0; - init_get_bits(&gb, os->buf + os->pstart, os->psize*8); - skip_bits1(&gb); /* metadata_last */ - mdt = get_bits(&gb, 7); + bitstream_init(&bc, os->buf + os->pstart, os->psize * 8); + bitstream_skip(&bc, 1); /* metadata_last */ + mdt = bitstream_read(&bc, 7); if (mdt == OGG_FLAC_METADATA_TYPE_STREAMINFO) { uint8_t *streaminfo_start = os->buf + os->pstart + 5 + 4 + 4 + 4; uint32_t samplerate; - skip_bits_long(&gb, 4*8); /* "FLAC" */ - if(get_bits(&gb, 8) != 1) /* unsupported major version */ + bitstream_skip(&bc, 4 * 8); /* "FLAC" */ + if (bitstream_read(&bc, 8) != 1) /* unsupported major version */ return -1; - skip_bits_long(&gb, 8 + 16); /* minor version + header count */ - skip_bits_long(&gb, 4*8); /* "fLaC" */ + bitstream_skip(&bc, 8 + 16); /* minor version + header count */ + bitstream_skip(&bc, 4 * 8); /* "fLaC" */ /* METADATA_BLOCK_HEADER */ - if (get_bits_long(&gb, 32) != FLAC_STREAMINFO_SIZE) + if (bitstream_read(&bc, 32) != FLAC_STREAMINFO_SIZE) return -1; st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; diff --git a/libavformat/oggparsetheora.c b/libavformat/oggparsetheora.c index 1e7a776c06683..da47a0cd899d3 100644 --- a/libavformat/oggparsetheora.c +++ b/libavformat/oggparsetheora.c @@ -23,8 +23,11 @@ **/ #include + #include "libavutil/bswap.h" -#include "libavcodec/get_bits.h" + +#include "libavcodec/bitstream.h" + #include "avformat.h" #include "internal.h" #include "oggdec.h" @@ -57,41 +60,41 @@ static int theora_header(AVFormatContext *s, int idx) switch (os->buf[os->pstart]) { case 0x80: { - GetBitContext gb; + BitstreamContext bc; AVRational timebase; - init_get_bits(&gb, os->buf + os->pstart, os->psize * 8); + bitstream_init(&bc, os->buf + os->pstart, os->psize * 8); /* 0x80"theora" */ - skip_bits_long(&gb, 7 * 8); + bitstream_skip(&bc, 7 * 8); - thp->version = get_bits_long(&gb, 24); + thp->version = bitstream_read(&bc, 24); if (thp->version < 0x030100) { av_log(s, AV_LOG_ERROR, "Too old or unsupported Theora (%x)\n", thp->version); return AVERROR(ENOSYS); } - st->codecpar->width = get_bits(&gb, 16) << 4; - st->codecpar->height = get_bits(&gb, 16) << 4; + st->codecpar->width = bitstream_read(&bc, 16) << 4; + st->codecpar->height = bitstream_read(&bc, 16) << 4; if (thp->version >= 0x030400) - skip_bits(&gb, 100); + bitstream_skip(&bc, 100); if (thp->version >= 0x030200) { - int width = get_bits_long(&gb, 24); - int height = get_bits_long(&gb, 24); + int width = bitstream_read(&bc, 24); + int height = bitstream_read(&bc, 24); if (width <= st->codecpar->width && width > st->codecpar->width - 16 && height <= st->codecpar->height && height > st->codecpar->height - 16) { st->codecpar->width = width; st->codecpar->height = height; } - skip_bits(&gb, 16); + bitstream_skip(&bc, 16); } - timebase.den = get_bits_long(&gb, 32); - timebase.num = get_bits_long(&gb, 32); + timebase.den = bitstream_read(&bc, 32); + timebase.num = bitstream_read(&bc, 32); if (!(timebase.num > 0 && timebase.den > 0)) { av_log(s, AV_LOG_WARNING, "Invalid time base in theora stream, assuming 25 FPS\n"); timebase.num = 1; @@ -99,15 +102,15 @@ static int theora_header(AVFormatContext *s, int idx) } avpriv_set_pts_info(st, 64, timebase.num, timebase.den); - st->sample_aspect_ratio.num = get_bits_long(&gb, 24); - st->sample_aspect_ratio.den = get_bits_long(&gb, 24); + st->sample_aspect_ratio.num = bitstream_read(&bc, 24); + st->sample_aspect_ratio.den = bitstream_read(&bc, 24); if (thp->version >= 0x030200) - skip_bits_long(&gb, 38); + bitstream_skip(&bc, 38); if (thp->version >= 0x304000) - skip_bits(&gb, 2); + bitstream_skip(&bc, 2); - thp->gpshift = get_bits(&gb, 5); + thp->gpshift = bitstream_read(&bc, 5); thp->gpmask = (1 << thp->gpshift) - 1; st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; From 2dbe2aa2c2d4f02d2669feae45dee4fc45414813 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 16 Apr 2016 17:58:30 +0200 Subject: [PATCH 0586/3374] rdt: Convert to the new bitstream reader --- libavformat/rdt.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/libavformat/rdt.c b/libavformat/rdt.c index eb718cfe815b0..da5ff59c22a5d 100644 --- a/libavformat/rdt.c +++ b/libavformat/rdt.c @@ -25,6 +25,8 @@ * @author Ronald S. Bultje */ +#include "libavcodec/bitstream.h" + #include "avformat.h" #include "libavutil/avstring.h" #include "rtpdec.h" @@ -34,7 +36,6 @@ #include "rm.h" #include "internal.h" #include "avio_internal.h" -#include "libavcodec/get_bits.h" struct RDTDemuxContext { AVFormatContext *ic; /**< the containing (RTSP) demux context */ @@ -191,7 +192,7 @@ ff_rdt_parse_header(const uint8_t *buf, int len, int *pset_id, int *pseq_no, int *pstream_id, int *pis_keyframe, uint32_t *ptimestamp) { - GetBitContext gb; + BitstreamContext bc; int consumed = 0, set_id, seq_no, stream_id, is_keyframe, len_included, need_reliable; uint32_t timestamp; @@ -261,24 +262,24 @@ ff_rdt_parse_header(const uint8_t *buf, int len, * [2] http://www.wireshark.org/docs/dfref/r/rdt.html and * http://anonsvn.wireshark.org/viewvc/trunk/epan/dissectors/packet-rdt.c */ - init_get_bits(&gb, buf, len << 3); - len_included = get_bits1(&gb); - need_reliable = get_bits1(&gb); - set_id = get_bits(&gb, 5); - skip_bits(&gb, 1); - seq_no = get_bits(&gb, 16); + bitstream_init(&bc, buf, len << 3); + len_included = bitstream_read_bit(&bc); + need_reliable = bitstream_read_bit(&bc); + set_id = bitstream_read(&bc, 5); + bitstream_skip(&bc, 1); + seq_no = bitstream_read(&bc, 16); if (len_included) - skip_bits(&gb, 16); - skip_bits(&gb, 2); - stream_id = get_bits(&gb, 5); - is_keyframe = !get_bits1(&gb); - timestamp = get_bits_long(&gb, 32); + bitstream_skip(&bc, 16); + bitstream_skip(&bc, 2); + stream_id = bitstream_read(&bc, 5); + is_keyframe = !bitstream_read_bit(&bc); + timestamp = bitstream_read(&bc, 32); if (set_id == 0x1f) - set_id = get_bits(&gb, 16); + set_id = bitstream_read(&bc, 16); if (need_reliable) - skip_bits(&gb, 16); + bitstream_skip(&bc, 16); if (stream_id == 0x1f) - stream_id = get_bits(&gb, 16); + stream_id = bitstream_read(&bc, 16); if (pset_id) *pset_id = set_id; if (pseq_no) *pseq_no = seq_no; @@ -286,7 +287,7 @@ ff_rdt_parse_header(const uint8_t *buf, int len, if (pis_keyframe) *pis_keyframe = is_keyframe; if (ptimestamp) *ptimestamp = timestamp; - return consumed + (get_bits_count(&gb) >> 3); + return consumed + (bitstream_tell(&bc) >> 3); } /**< return 0 on packet, no more left, 1 on packet, 1 on partial packet... */ From 2f99117f6ff24ce5be2abb9e014cb8b86c2aa0e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 22 Nov 2016 15:47:17 +0200 Subject: [PATCH 0587/3374] aarch64: vp9itxfm: Don't repeatedly set x9 when nothing overwrites it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index 2dc6b7524a0af..f4194a670f738 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -599,9 +599,9 @@ endfunc // x1 = unused // x2 = src // x3 = slice offset +// x9 = input stride .macro itxfm16_1d_funcs txfm function \txfm\()16_1d_8x16_pass1_neon - mov x9, #32 movi v2.8h, #0 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 load_clear \i, x2, x9 @@ -649,8 +649,8 @@ endfunc // x1 = dst stride // x2 = src (temp buffer) // x3 = slice offset +// x9 = temp buffer stride function \txfm\()16_1d_8x16_pass2_neon - mov x9, #32 .irp i, 16, 17, 18, 19, 20, 21, 22, 23 load \i, x2, x9 .endr @@ -747,6 +747,7 @@ function ff_vp9_\txfm1\()_\txfm2\()_16x16_add_neon, export=1 .ifc \txfm1,idct ld1 {v0.8h,v1.8h}, [x10] .endif + mov x9, #32 .irp i, 0, 8 add x0, sp, #(\i*32) @@ -882,13 +883,12 @@ endfunc // x0 = dst (temp buffer) // x1 = unused // x2 = src +// x9 = double input stride // x10 = idct_coeffs // x11 = idct_coeffs + 32 function idct32_1d_8x32_pass1_neon ld1 {v0.8h,v1.8h}, [x10] - // Double stride of the input, since we only read every other line - mov x9, #128 movi v4.8h, #0 // v16 = IN(0), v17 = IN(2) ... v31 = IN(30) @@ -987,12 +987,13 @@ endfunc // x0 = dst // x1 = dst stride // x2 = src (temp buffer) +// x7 = negative double temp buffer stride +// x9 = double temp buffer stride // x10 = idct_coeffs // x11 = idct_coeffs + 32 function idct32_1d_8x32_pass2_neon ld1 {v0.8h,v1.8h}, [x10] - mov x9, #128 // v16 = IN(0), v17 = IN(2) ... v31 = IN(30) .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 ld1 {v\i\().8h}, [x2], x9 @@ -1001,7 +1002,6 @@ function idct32_1d_8x32_pass2_neon idct16 - mov x9, #128 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 st1 {v\i\().8h}, [x2], x9 .endr @@ -1018,11 +1018,10 @@ function idct32_1d_8x32_pass2_neon idct32_odd - mov x9, #128 .macro load_acc_store a, b, c, d, neg=0 +.if \neg == 0 ld1 {v4.8h}, [x2], x9 ld1 {v5.8h}, [x2], x9 -.if \neg == 0 add v4.8h, v4.8h, v\a\().8h ld1 {v6.8h}, [x2], x9 add v5.8h, v5.8h, v\b\().8h @@ -1030,10 +1029,12 @@ function idct32_1d_8x32_pass2_neon add v6.8h, v6.8h, v\c\().8h add v7.8h, v7.8h, v\d\().8h .else + ld1 {v4.8h}, [x2], x7 + ld1 {v5.8h}, [x2], x7 sub v4.8h, v4.8h, v\a\().8h - ld1 {v6.8h}, [x2], x9 + ld1 {v6.8h}, [x2], x7 sub v5.8h, v5.8h, v\b\().8h - ld1 {v7.8h}, [x2], x9 + ld1 {v7.8h}, [x2], x7 sub v6.8h, v6.8h, v\c\().8h sub v7.8h, v7.8h, v\d\().8h .endif @@ -1064,7 +1065,6 @@ function idct32_1d_8x32_pass2_neon load_acc_store 23, 22, 21, 20 load_acc_store 19, 18, 17, 16 sub x2, x2, x9 - neg x9, x9 load_acc_store 16, 17, 18, 19, 1 load_acc_store 20, 21, 22, 23, 1 load_acc_store 24, 25, 26, 27, 1 @@ -1093,6 +1093,10 @@ function ff_vp9_idct_idct_32x32_add_neon, export=1 mov x5, x1 mov x6, x2 + // Double stride of the input, since we only read every other line + mov x9, #128 + neg x7, x9 + .irp i, 0, 8, 16, 24 add x0, sp, #(\i*64) add x2, x6, #(\i*2) From 537b5b773b317af79d3a5b576ee9683e15ed84f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 23 Nov 2016 23:27:26 +0200 Subject: [PATCH 0588/3374] rtmpdh: Do global initialization before running the test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The rtmpdh code can use crypto libraries which may require a process global init. (gcrypt is one of the libraries where the rtmpdh test code can fail if global init hasn't been done, depending on gcrypt version.) Signed-off-by: Martin Storsjö --- libavformat/tests/rtmpdh.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavformat/tests/rtmpdh.c b/libavformat/tests/rtmpdh.c index c25ca91b7e05e..cf567fb39b67b 100644 --- a/libavformat/tests/rtmpdh.c +++ b/libavformat/tests/rtmpdh.c @@ -16,6 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavformat/avformat.h" #include "libavformat/rtmpdh.c" #include @@ -150,6 +151,7 @@ static int test_ref_data(void) int main(void) { + avformat_network_init(); if (test_random_shared_secret() < 0) return 1; if (test_ref_data() < 0) From 233d50b275dd7cf6cc0656851e670e1b2dfba56f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 13 Sep 2012 12:55:32 +0300 Subject: [PATCH 0589/3374] qt-faststart: Do not try to use fancy 64-bit seeking functions on mingw32ce These functions are not available on mingw32ce. Signed-off-by: Diego Biurrun --- tools/qt-faststart.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/qt-faststart.c b/tools/qt-faststart.c index 0db5ca21384c5..b798ccd4bf5c8 100644 --- a/tools/qt-faststart.c +++ b/tools/qt-faststart.c @@ -29,7 +29,10 @@ #include #include -#ifdef __MINGW32__ +#ifdef __MINGW32CE__ +#define fseeko(x, y, z) fseek(x, y, z) +#define ftello(x) ftell(x) +#elif defined(__MINGW32__) #undef fseeko #define fseeko(x, y, z) fseeko64(x, y, z) #undef ftello From bd9cd04626a98a752c5771d057a6b86779359904 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 22 Nov 2016 08:46:07 +0100 Subject: [PATCH 0590/3374] w32pthreads: Fix function pointer casts This eliminates a handful of warnings at every inclusion of the header. --- compat/w32pthreads.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/compat/w32pthreads.h b/compat/w32pthreads.h index 2fe2a5ab979ff..f38f767d8fb45 100644 --- a/compat/w32pthreads.h +++ b/compat/w32pthreads.h @@ -382,18 +382,18 @@ static av_unused void w32thread_init(void) #if _WIN32_WINNT < 0x0600 HANDLE kernel_dll = GetModuleHandle(TEXT("kernel32.dll")); /* if one is available, then they should all be available */ - cond_init = - (void*)GetProcAddress(kernel_dll, "InitializeConditionVariable"); - cond_broadcast = - (void*)GetProcAddress(kernel_dll, "WakeAllConditionVariable"); - cond_signal = - (void*)GetProcAddress(kernel_dll, "WakeConditionVariable"); - cond_wait = - (void*)GetProcAddress(kernel_dll, "SleepConditionVariableCS"); - initonce_begin = - (void*)GetProcAddress(kernel_dll, "InitOnceBeginInitialize"); - initonce_complete = - (void*)GetProcAddress(kernel_dll, "InitOnceComplete"); + cond_init = (void (WINAPI*)(pthread_cond_t *)) + GetProcAddress(kernel_dll, "InitializeConditionVariable"); + cond_broadcast = (void (WINAPI*)(pthread_cond_t *)) + GetProcAddress(kernel_dll, "WakeAllConditionVariable"); + cond_signal = (void (WINAPI*)(pthread_cond_t *)) + GetProcAddress(kernel_dll, "WakeConditionVariable"); + cond_wait = (BOOL (WINAPI*)(pthread_cond_t *, pthread_mutex_t *, DWORD)) + GetProcAddress(kernel_dll, "SleepConditionVariableCS"); + initonce_begin = (BOOL (WINAPI*)(pthread_once_t *, DWORD, BOOL *, void **)) + GetProcAddress(kernel_dll, "InitOnceBeginInitialize"); + initonce_complete = (BOOL (WINAPI*)(pthread_once_t *, DWORD, void *)) + GetProcAddress(kernel_dll, "InitOnceComplete"); #endif } From 5bcc6f76f180d0f88269018727c92fc562fb8abb Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 22 Nov 2016 08:18:38 +0100 Subject: [PATCH 0591/3374] configure: Disable warning C4703 with MSVC This disables warnings about potentially uninitialized local pointer variables. Disabling the warning is in line with what we do for gcc. --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index beab6ba68755f..42c18487788b8 100755 --- a/configure +++ b/configure @@ -3056,7 +3056,7 @@ msvc_flags(){ -Wall) echo -W4 -wd4244 -wd4127 -wd4018 -wd4389 \ -wd4146 -wd4057 -wd4204 -wd4706 -wd4305 \ -wd4152 -wd4324 -we4013 -wd4100 -wd4214 \ - -wd4273 -wd4554 -wd4701 ;; + -wd4273 -wd4554 -wd4701 -wd4703 ;; esac done } From 6a1ea4ec932f4fc9fdc00ec51ee070b298ddb35f Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Fri, 18 Nov 2016 21:06:40 +0100 Subject: [PATCH 0592/3374] arm: warn/error on movrelx usage problematic with PIC on ELF The warning has false positives but our asm does not trigger it. For new code false positives can only be avoided by changing the register allocation. --- libavutil/arm/asm.S | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libavutil/arm/asm.S b/libavutil/arm/asm.S index 4ac0ea2e4fb15..a791e80c57d9c 100644 --- a/libavutil/arm/asm.S +++ b/libavutil/arm/asm.S @@ -184,6 +184,15 @@ T ldr \rd, [\rd] .endm .macro movrelx rd, val, gp + .ifc \rd,\gp + .error "movrelx needs two distinct registers" + .endif + .ifc \rd\()_\gp,r12_ + .warning "movrelx rd=\rd without explicit set gp" + .endif + .ifc \rd\()_\gp,ip_ + .warning "movrelx rd=\rd without explicit set gp" + .endif #if CONFIG_PIC && defined(__ELF__) .ifnb \gp .if .Lpic_gp From 30f0d1b997f15d667c05feab0b54f0b2814ba7a9 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 22 Nov 2016 08:11:59 +0100 Subject: [PATCH 0593/3374] configure: Remove old avisynth support leftover --- configure | 1 - 1 file changed, 1 deletion(-) diff --git a/configure b/configure index 42c18487788b8..78f1cac81cbbd 100755 --- a/configure +++ b/configure @@ -3039,7 +3039,6 @@ msvc_common_flags(){ -mthumb) ;; -march=*) ;; -lz) echo zlib.lib ;; - -lavifil32) echo vfw32.lib ;; -lavicap32) echo vfw32.lib user32.lib ;; -lx264) echo libx264.lib ;; -l*) echo ${flag#-l}.lib ;; From 04698d528cac334b6b5cabd3384f01406a766285 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 23 Nov 2016 08:54:01 +0100 Subject: [PATCH 0594/3374] configure: Use correct variable name in libsnappy test --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 78f1cac81cbbd..f204dc28d5958 100755 --- a/configure +++ b/configure @@ -4653,7 +4653,7 @@ enabled libopus && require_pkg_config opus opus_multistream.h opus_mul enabled libpulse && require_pkg_config libpulse-simple pulse/simple.h pa_simple_new enabled librtmp && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket enabled libschroedinger && require_pkg_config schroedinger-1.0 schroedinger/schro.h schro_init -enabled libsnappy && require snappy snappy-c.h snappy_compress -lsnappy +enabled libsnappy && require libsnappy snappy-c.h snappy_compress -lsnappy enabled libspeex && require_pkg_config speex speex/speex.h speex_decoder_init -lspeex enabled libtheora && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg enabled libtwolame && require libtwolame twolame.h twolame_init -ltwolame From ce6f780bc6656ad3895f81a988b239ad3c8af4b8 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 22 Nov 2016 16:51:04 +0100 Subject: [PATCH 0595/3374] configure: Add missing asyncts filter, movie filter, and output example deps Also add a missing avcodec.h #include in the movie filter. --- configure | 7 +++++-- libavfilter/vsrc_movie.c | 4 ++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/configure b/configure index f204dc28d5958..eb5147615cc18 100755 --- a/configure +++ b/configure @@ -2426,6 +2426,7 @@ unix_protocol_deps="sys_un_h" unix_protocol_select="network" # filters +asyncts_filter_deps="avresample" blackframe_filter_deps="gpl" boxblur_filter_deps="gpl" bs2b_filter_deps="libbs2b" @@ -2440,6 +2441,7 @@ frei0r_src_filter_extralibs='$ldl' hdcd_filter_deps="libhdcd" hqdn3d_filter_deps="gpl" interlace_filter_deps="gpl" +movie_filter_deps="avcodec avformat" ocv_filter_deps="libopencv" resample_filter_deps="avresample" scale_filter_deps="swscale" @@ -2453,7 +2455,7 @@ encode_audio_example_deps="avcodec avutil" encode_video_example_deps="avcodec avutil" filter_audio_example_deps="avfilter avutil" metadata_example_deps="avformat avutil" -output_example_deps="avcodec avformat avutil swscale" +output_example_deps="avcodec avformat avresample avutil swscale" qsvdec_example_deps="avcodec avutil libmfx h264_qsv_decoder" transcode_aac_example_deps="avcodec avformat avresample" @@ -5109,7 +5111,8 @@ enabled zlib && add_cppflags -DZLIB_CONST # conditional library dependencies, in linking order enabled movie_filter && prepend avfilter_deps "avformat avcodec" -enabled resample_filter && prepend avfilter_deps "avresample" +enabled_any asyncts_filter resample_filter && + prepend avfilter_deps "avresample" enabled scale_filter && prepend avfilter_deps "swscale" enabled opus_decoder && prepend avcodec_deps "avresample" diff --git a/libavfilter/vsrc_movie.c b/libavfilter/vsrc_movie.c index 5989a59190963..7fc99258488b5 100644 --- a/libavfilter/vsrc_movie.c +++ b/libavfilter/vsrc_movie.c @@ -35,7 +35,11 @@ #include "libavutil/avstring.h" #include "libavutil/opt.h" #include "libavutil/imgutils.h" + +#include "libavcodec/avcodec.h" + #include "libavformat/avformat.h" + #include "avfilter.h" #include "formats.h" #include "internal.h" From bf2f748fc74fff5272075e1fe1c07b4152421526 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 23 Nov 2016 09:27:28 +0100 Subject: [PATCH 0596/3374] configure: Use correct libm linker flag during math function checks --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index eb5147615cc18..bfae451257d54 100755 --- a/configure +++ b/configure @@ -4620,7 +4620,7 @@ ldexpf_args=2 powf_args=2 for func in $MATH_FUNCS; do - eval check_mathfunc $func \${${func}_args:-1} + eval check_mathfunc $func \${${func}_args:-1} $LIBM done # these are off by default, so fail if requested and not available From e122b12c88487ac8766ff4eb071856b0666f0134 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 23 Nov 2016 16:42:00 +0100 Subject: [PATCH 0597/3374] build: Drop gcrypt support GnuTLS in combination with gcrypt has been deprecated since 2010. --- configure | 8 ++------ libavformat/hlsenc.c | 9 ++------- libavformat/rtmpdh.c | 18 ------------------ libavformat/rtmpdh.h | 5 ----- libavformat/tls_gnutls.c | 10 ---------- 5 files changed, 4 insertions(+), 46 deletions(-) diff --git a/configure b/configure index bfae451257d54..d0bec323c1df5 100755 --- a/configure +++ b/configure @@ -1700,7 +1700,6 @@ CONFIG_EXTRA=" flacdsp fmtconvert g722dsp - gcrypt gmp golomb gplv3 @@ -2387,7 +2386,7 @@ xcbgrab_indev_deps="libxcb" # protocols ffrtmpcrypt_protocol_deps="!librtmp_protocol" -ffrtmpcrypt_protocol_deps_any="gcrypt gmp openssl" +ffrtmpcrypt_protocol_deps_any="gmp openssl" ffrtmpcrypt_protocol_select="tcp_protocol" ffrtmphttp_protocol_deps="!librtmp_protocol" ffrtmphttp_protocol_select="http_protocol" @@ -4717,10 +4716,7 @@ enabled openssl && { { check_pkg_config openssl openssl/ssl.h OPENSSL_ check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 || die "ERROR: openssl not found"; } -if enabled gnutls; then - { check_lib gmp.h mpz_export -lgmp && enable gmp; } || - { check_lib gcrypt.h gcry_mpi_new -lgcrypt && enable gcrypt; } -fi +enabled gnutls && check_lib gmp.h mpz_export -lgmp && enable gmp # libdc1394 check if enabled libdc1394; then diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 625531b881d6d..05c9adb959ff8 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -24,9 +24,7 @@ #include -#if CONFIG_GCRYPT -#include -#elif CONFIG_OPENSSL +#if CONFIG_OPENSSL #include #endif @@ -86,10 +84,7 @@ typedef struct HLSContext { static int randomize(uint8_t *buf, int len) { -#if CONFIG_GCRYPT - gcry_randomize(buf, len, GCRY_VERY_STRONG_RANDOM); - return 0; -#elif CONFIG_OPENSSL +#if CONFIG_OPENSSL if (RAND_bytes(buf, len)) return 0; return AVERROR(EIO); diff --git a/libavformat/rtmpdh.c b/libavformat/rtmpdh.c index 593b2b1edd495..0593eac943ffd 100644 --- a/libavformat/rtmpdh.c +++ b/libavformat/rtmpdh.c @@ -107,24 +107,6 @@ static int bn_modexp(FFBigNum bn, FFBigNum y, FFBigNum q, FFBigNum p) mpz_powm(bn, y, q, p); return 0; } -#elif CONFIG_GCRYPT -#define bn_new(bn) bn = gcry_mpi_new(1) -#define bn_free(bn) gcry_mpi_release(bn) -#define bn_set_word(bn, w) gcry_mpi_set_ui(bn, w) -#define bn_cmp(a, b) gcry_mpi_cmp(a, b) -#define bn_copy(to, from) gcry_mpi_set(to, from) -#define bn_sub_word(bn, w) gcry_mpi_sub_ui(bn, bn, w) -#define bn_cmp_1(bn) gcry_mpi_cmp_ui(bn, 1) -#define bn_num_bytes(bn) (gcry_mpi_get_nbits(bn) + 7) / 8 -#define bn_bn2bin(bn, buf, len) gcry_mpi_print(GCRYMPI_FMT_USG, buf, len, NULL, bn) -#define bn_bin2bn(bn, buf, len) gcry_mpi_scan(&bn, GCRYMPI_FMT_USG, buf, len, NULL) -#define bn_hex2bn(bn, buf, ret) ret = (gcry_mpi_scan(&bn, GCRYMPI_FMT_HEX, buf, 0, 0) == 0) -#define bn_random(bn, num_bits) gcry_mpi_randomize(bn, num_bits, GCRY_WEAK_RANDOM) -static int bn_modexp(FFBigNum bn, FFBigNum y, FFBigNum q, FFBigNum p) -{ - gcry_mpi_powm(bn, y, q, p); - return 0; -} #elif CONFIG_OPENSSL #define bn_new(bn) bn = BN_new() #define bn_free(bn) BN_free(bn) diff --git a/libavformat/rtmpdh.h b/libavformat/rtmpdh.h index 5233de090544d..b4d6121d85292 100644 --- a/libavformat/rtmpdh.h +++ b/libavformat/rtmpdh.h @@ -30,11 +30,6 @@ #include typedef mpz_ptr FFBigNum; -#elif CONFIG_GCRYPT -#include - -typedef gcry_mpi_t FFBigNum; - #elif CONFIG_OPENSSL #include #include diff --git a/libavformat/tls_gnutls.c b/libavformat/tls_gnutls.c index 3e29a45ce4995..f8a612ad9b8c0 100644 --- a/libavformat/tls_gnutls.c +++ b/libavformat/tls_gnutls.c @@ -35,12 +35,6 @@ #include "libavutil/opt.h" #include "libavutil/parseutils.h" -#if HAVE_THREADS && GNUTLS_VERSION_NUMBER <= 0x020b00 -#include -#include "libavutil/thread.h" -GCRY_THREAD_OPTION_PTHREAD_IMPL; -#endif - typedef struct TLSContext { const AVClass *class; TLSShared tls_shared; @@ -52,10 +46,6 @@ typedef struct TLSContext { void ff_gnutls_init(void) { avpriv_lock_avformat(); -#if HAVE_THREADS && GNUTLS_VERSION_NUMBER < 0x020b00 - if (gcry_control(GCRYCTL_ANY_INITIALIZATION_P) == 0) - gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); -#endif gnutls_global_init(); avpriv_unlock_avformat(); } From dc4b62502876c0ebeeba317233cd1348c5b0b2b7 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 23 Nov 2016 13:02:52 +0100 Subject: [PATCH 0598/3374] tta: use get_unary() instead of a custom implementation Signed-off-by: Diego Biurrun --- libavcodec/tta.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/libavcodec/tta.c b/libavcodec/tta.c index 2b57406686bcf..2ac825554ec15 100644 --- a/libavcodec/tta.c +++ b/libavcodec/tta.c @@ -35,6 +35,7 @@ #include "avcodec.h" #include "get_bits.h" #include "internal.h" +#include "unary.h" #define FORMAT_SIMPLE 1 #define FORMAT_ENCRYPTED 2 @@ -171,16 +172,6 @@ static void rice_init(TTARice *c, uint32_t k0, uint32_t k1) c->sum1 = shift_16[k1]; } -static int tta_get_unary(GetBitContext *gb) -{ - int ret = 0; - - // count ones - while (get_bits_left(gb) > 0 && get_bits1(gb)) - ret++; - return ret; -} - static int tta_check_crc(TTAContext *s, const uint8_t *buf, int buf_size) { uint32_t crc, CRC; @@ -352,7 +343,7 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, uint32_t unary, depth, k; int32_t value; - unary = tta_get_unary(&s->gb); + unary = get_unary(&s->gb, 0, get_bits_left(&s->gb)); if (unary == 0) { depth = 0; From 4adbb44ad154cec05e87de60bb827a13c0fe87df Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 23 Nov 2016 13:02:53 +0100 Subject: [PATCH 0599/3374] tta: avoid undefined shifts Signed-off-by: Diego Biurrun --- libavcodec/tta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/tta.c b/libavcodec/tta.c index 2ac825554ec15..5532580e02239 100644 --- a/libavcodec/tta.c +++ b/libavcodec/tta.c @@ -360,7 +360,7 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, } if (k) { - if (k > MIN_CACHE_BITS) { + if (k >= 32 || unary > INT32_MAX >> k) { ret = AVERROR_INVALIDDATA; goto error; } From d30719e62de68975cbc7ffd318df03a183037563 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Fri, 25 Nov 2016 12:36:05 +0000 Subject: [PATCH 0600/3374] hwcontext_vaapi: Don't abort on failing to allocate from a fixed-size pool --- libavutil/hwcontext_vaapi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index 198872963728c..b2e212c1fe518 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -388,6 +388,10 @@ static AVBufferRef *vaapi_pool_alloc(void *opaque, int size) VAStatus vas; AVBufferRef *ref; + if (hwfc->initial_pool_size > 0 && + avfc->nb_surfaces >= hwfc->initial_pool_size) + return NULL; + vas = vaCreateSurfaces(hwctx->display, ctx->rt_format, hwfc->width, hwfc->height, &surface_id, 1, From e22c63ac74b2968075be8bf0d2deb1ee63b28976 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 4 Jan 2016 11:50:22 +0100 Subject: [PATCH 0601/3374] ac3enc: Reshuffle some float/fixed-mode ifdefs to avoid a dummy function --- libavcodec/ac3enc_fixed.c | 2 ++ libavcodec/ac3enc_float.c | 10 ---------- libavcodec/ac3enc_template.c | 4 +--- 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c index 2bb82ef3b67c3..c26f9c05d4979 100644 --- a/libavcodec/ac3enc_fixed.c +++ b/libavcodec/ac3enc_fixed.c @@ -38,6 +38,8 @@ static const AVClass ac3enc_class = { "Fixed-Point AC-3 Encoder", av_default_item_name, ac3_options, LIBAVUTIL_VERSION_INT }; +static int normalize_samples(AC3EncodeContext *s); + #include "ac3enc_template.c" diff --git a/libavcodec/ac3enc_float.c b/libavcodec/ac3enc_float.c index 968cb2c533719..5bae4bcb3cf5a 100644 --- a/libavcodec/ac3enc_float.c +++ b/libavcodec/ac3enc_float.c @@ -82,16 +82,6 @@ av_cold int ff_ac3_float_mdct_init(AC3EncodeContext *s) } -/* - * Normalize the input samples. - * Not needed for the floating-point encoder. - */ -static int normalize_samples(AC3EncodeContext *s) -{ - return 0; -} - - /* * Scale MDCT coefficients from float to 24-bit fixed-point. */ diff --git a/libavcodec/ac3enc_template.c b/libavcodec/ac3enc_template.c index ec8ec4ef6a316..eefcef5b014f2 100644 --- a/libavcodec/ac3enc_template.c +++ b/libavcodec/ac3enc_template.c @@ -40,8 +40,6 @@ static void scale_coefficients(AC3EncodeContext *s); -static int normalize_samples(AC3EncodeContext *s); - static void clip_coefficients(AudioDSPContext *adsp, CoefType *coef, unsigned int len); @@ -110,10 +108,10 @@ static void apply_mdct(AC3EncodeContext *s) #else s->ac3dsp.apply_window_int16(s->windowed_samples, input_samples, s->mdct_window, AC3_WINDOW_SIZE); -#endif if (s->fixed_point) block->coeff_shift[ch+1] = normalize_samples(s); +#endif s->mdct.mdct_calcw(&s->mdct, block->mdct_coef[ch+1], s->windowed_samples); From f0d3e43bd77b3194a28d75884cf83083b188bf30 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 4 Jan 2016 11:58:21 +0100 Subject: [PATCH 0602/3374] ac3enc: Reshuffle functions to avoid forward declarations --- libavcodec/ac3enc_fixed.c | 58 +++++++++++++++--------------- libavcodec/ac3enc_float.c | 70 ++++++++++++++++++------------------ libavcodec/ac3enc_template.c | 9 ----- 3 files changed, 64 insertions(+), 73 deletions(-) diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c index c26f9c05d4979..c1cf8256b219a 100644 --- a/libavcodec/ac3enc_fixed.c +++ b/libavcodec/ac3enc_fixed.c @@ -38,36 +38,6 @@ static const AVClass ac3enc_class = { "Fixed-Point AC-3 Encoder", av_default_item_name, ac3_options, LIBAVUTIL_VERSION_INT }; -static int normalize_samples(AC3EncodeContext *s); - -#include "ac3enc_template.c" - - -/** - * Finalize MDCT and free allocated memory. - * - * @param s AC-3 encoder private context - */ -av_cold void AC3_NAME(mdct_end)(AC3EncodeContext *s) -{ - ff_mdct_end(&s->mdct); -} - - -/** - * Initialize MDCT tables. - * - * @param s AC-3 encoder private context - * @return 0 on success, negative error code on failure - */ -av_cold int AC3_NAME(mdct_init)(AC3EncodeContext *s) -{ - int ret = ff_mdct_init(&s->mdct, 9, 0, -1.0); - s->mdct_window = ff_ac3_window; - return ret; -} - - /* * Normalize the input samples to use the maximum available precision. * This assumes signed 16-bit input samples. @@ -126,6 +96,34 @@ static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl) } +#include "ac3enc_template.c" + + +/** + * Finalize MDCT and free allocated memory. + * + * @param s AC-3 encoder private context + */ +av_cold void AC3_NAME(mdct_end)(AC3EncodeContext *s) +{ + ff_mdct_end(&s->mdct); +} + + +/** + * Initialize MDCT tables. + * + * @param s AC-3 encoder private context + * @return 0 on success, negative error code on failure + */ +av_cold int AC3_NAME(mdct_init)(AC3EncodeContext *s) +{ + int ret = ff_mdct_init(&s->mdct, 9, 0, -1.0); + s->mdct_window = ff_ac3_window; + return ret; +} + + static av_cold int ac3_fixed_encode_init(AVCodecContext *avctx) { AC3EncodeContext *s = avctx->priv_data; diff --git a/libavcodec/ac3enc_float.c b/libavcodec/ac3enc_float.c index 5bae4bcb3cf5a..249f9edd11c62 100644 --- a/libavcodec/ac3enc_float.c +++ b/libavcodec/ac3enc_float.c @@ -39,6 +39,42 @@ static const AVClass ac3enc_class = { "AC-3 Encoder", av_default_item_name, ac3_options, LIBAVUTIL_VERSION_INT }; + +/* + * Scale MDCT coefficients from float to 24-bit fixed-point. + */ +static void scale_coefficients(AC3EncodeContext *s) +{ + int chan_size = AC3_MAX_COEFS * s->num_blocks; + int cpl = s->cpl_on; + s->ac3dsp.float_to_fixed24(s->fixed_coef_buffer + (chan_size * !cpl), + s->mdct_coef_buffer + (chan_size * !cpl), + chan_size * (s->channels + cpl)); +} + + +/* + * Clip MDCT coefficients to allowable range. + */ +static void clip_coefficients(AudioDSPContext *adsp, float *coef, + unsigned int len) +{ + adsp->vector_clipf(coef, coef, len, COEF_MIN, COEF_MAX); +} + + +/* + * Calculate a single coupling coordinate. + */ +static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl) +{ + float coord = 0.125; + if (energy_cpl > 0) + coord *= sqrtf(energy_ch / energy_cpl); + return FFMIN(coord, COEF_MAX); +} + + #include "ac3enc_template.c" @@ -82,40 +118,6 @@ av_cold int ff_ac3_float_mdct_init(AC3EncodeContext *s) } -/* - * Scale MDCT coefficients from float to 24-bit fixed-point. - */ -static void scale_coefficients(AC3EncodeContext *s) -{ - int chan_size = AC3_MAX_COEFS * s->num_blocks; - int cpl = s->cpl_on; - s->ac3dsp.float_to_fixed24(s->fixed_coef_buffer + (chan_size * !cpl), - s->mdct_coef_buffer + (chan_size * !cpl), - chan_size * (s->channels + cpl)); -} - - -/* - * Clip MDCT coefficients to allowable range. - */ -static void clip_coefficients(AudioDSPContext *adsp, float *coef, - unsigned int len) -{ - adsp->vector_clipf(coef, coef, len, COEF_MIN, COEF_MAX); -} - - -/* - * Calculate a single coupling coordinate. - */ -static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl) -{ - float coord = 0.125; - if (energy_cpl > 0) - coord *= sqrtf(energy_ch / energy_cpl); - return FFMIN(coord, COEF_MAX); -} - av_cold int ff_ac3_float_encode_init(AVCodecContext *avctx) { AC3EncodeContext *s = avctx->priv_data; diff --git a/libavcodec/ac3enc_template.c b/libavcodec/ac3enc_template.c index eefcef5b014f2..ef40b5a0d6acd 100644 --- a/libavcodec/ac3enc_template.c +++ b/libavcodec/ac3enc_template.c @@ -36,15 +36,6 @@ #include "ac3enc.h" #include "eac3enc.h" -/* prototypes for static functions in ac3enc_fixed.c and ac3enc_float.c */ - -static void scale_coefficients(AC3EncodeContext *s); - -static void clip_coefficients(AudioDSPContext *adsp, CoefType *coef, - unsigned int len); - -static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl); - int AC3_NAME(allocate_sample_buffers)(AC3EncodeContext *s) { From eb135516e6f61481877163bfc55a3161d4544092 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 4 Jan 2016 11:59:38 +0100 Subject: [PATCH 0603/3374] ac3enc: Avoid unnecessary macro indirections --- libavcodec/ac3enc_fixed.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c index c1cf8256b219a..cb1c58d578080 100644 --- a/libavcodec/ac3enc_fixed.c +++ b/libavcodec/ac3enc_fixed.c @@ -104,7 +104,7 @@ static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl) * * @param s AC-3 encoder private context */ -av_cold void AC3_NAME(mdct_end)(AC3EncodeContext *s) +av_cold void ff_ac3_fixed_mdct_end(AC3EncodeContext *s) { ff_mdct_end(&s->mdct); } @@ -116,7 +116,7 @@ av_cold void AC3_NAME(mdct_end)(AC3EncodeContext *s) * @param s AC-3 encoder private context * @return 0 on success, negative error code on failure */ -av_cold int AC3_NAME(mdct_init)(AC3EncodeContext *s) +av_cold int ff_ac3_fixed_mdct_init(AC3EncodeContext *s) { int ret = ff_mdct_init(&s->mdct, 9, 0, -1.0); s->mdct_window = ff_ac3_window; From d0c84c41d33ffd270d5f9fe0290e08341397fdee Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 28 Nov 2016 20:52:47 +0100 Subject: [PATCH 0604/3374] avconv: Fix the audio next dts computation Use the correct timebase. CC: libav-stable@libav.org --- avconv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avconv.c b/avconv.c index 97166d9e2ad6b..5c31332812b74 100644 --- a/avconv.c +++ b/avconv.c @@ -1350,7 +1350,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output, /* if the decoder provides a pts, use it instead of the last packet pts. the decoder could be delaying output by a packet or more. */ if (decoded_frame->pts != AV_NOPTS_VALUE) - ist->next_dts = decoded_frame->pts; + ist->next_dts = av_rescale_q(decoded_frame->pts, ist->st->time_base, AV_TIME_BASE_Q); else if (pkt && pkt->pts != AV_NOPTS_VALUE) { decoded_frame->pts = pkt->pts; } From 1762a39e09a3edc27d1ef7bc50070f496b893aa4 Mon Sep 17 00:00:00 2001 From: Andreas Cadhalpun Date: Thu, 24 Nov 2016 23:57:46 +0100 Subject: [PATCH 0605/3374] mss2: only use error correction for matching block counts This fixes a heap-buffer-overflow in ff_er_frame_end when decoding mss2 with coded_width/coded_height larger than width/height. Signed-off-by: Andreas Cadhalpun Signed-off-by: Luca Barbato --- libavcodec/mss2.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libavcodec/mss2.c b/libavcodec/mss2.c index 355bb32e1bba3..6fcadb16c9c45 100644 --- a/libavcodec/mss2.c +++ b/libavcodec/mss2.c @@ -416,7 +416,13 @@ static int decode_wmv9(AVCodecContext *avctx, const uint8_t *buf, int buf_size, ff_vc1_decode_blocks(v); - ff_er_frame_end(&s->er); + if (v->end_mb_x == s->mb_width && s->end_mb_y == s->mb_height) { + ff_er_frame_end(&s->er); + } else { + av_log(v->s.avctx, AV_LOG_WARNING, + "disabling error correction due to block count mismatch %dx%d != %dx%d\n", + v->end_mb_x, s->end_mb_y, s->mb_width, s->mb_height); + } ff_mpv_frame_end(s); From 45d199d5b0b7f09eb9baa29929a3bd07ed46223b Mon Sep 17 00:00:00 2001 From: James Almer Date: Thu, 24 Nov 2016 21:10:47 -0300 Subject: [PATCH 0606/3374] aac_adtstoasc_bsf: validate and forward extradata if the stream is already ASC Fixes AAC AudioSpecificConfig passthrough. Signed-off-by: James Almer Signed-off-by: Anton Khirnov --- libavcodec/aac_adtstoasc_bsf.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/libavcodec/aac_adtstoasc_bsf.c b/libavcodec/aac_adtstoasc_bsf.c index 9168e2b0f3236..08d60eb06ffcb 100644 --- a/libavcodec/aac_adtstoasc_bsf.c +++ b/libavcodec/aac_adtstoasc_bsf.c @@ -135,8 +135,16 @@ static int aac_adtstoasc_filter(AVBSFContext *bsfc, AVPacket *out) static int aac_adtstoasc_init(AVBSFContext *ctx) { - av_freep(&ctx->par_out->extradata); - ctx->par_out->extradata_size = 0; + /* Validate the extradata if the stream is already MPEG-4 AudioSpecificConfig */ + if (ctx->par_in->extradata) { + MPEG4AudioConfig mp4ac; + int ret = avpriv_mpeg4audio_get_config(&mp4ac, ctx->par_in->extradata, + ctx->par_in->extradata_size * 8, 1); + if (ret < 0) { + av_log(ctx, AV_LOG_ERROR, "Error parsing AudioSpecificConfig extradata!\n"); + return ret; + } + } return 0; } From 328cd2b599bc2d0d38f3c12606fa2a66eeec016e Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 26 Oct 2016 08:10:19 +0200 Subject: [PATCH 0607/3374] lavc: move encoding-related code from utils.c to a new file --- libavcodec/Makefile | 1 + libavcodec/encode.c | 360 ++++++++++++++++++++++++++++++++++++++++++++ libavcodec/utils.c | 331 ---------------------------------------- 3 files changed, 361 insertions(+), 331 deletions(-) create mode 100644 libavcodec/encode.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index f0752a2cfbbf6..fe723155a5816 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -25,6 +25,7 @@ OBJS = allcodecs.o \ d3d11va.o \ dirac.o \ dv_profile.o \ + encode.o \ imgconvert.o \ log2_tab.o \ mathtables.o \ diff --git a/libavcodec/encode.c b/libavcodec/encode.c new file mode 100644 index 0000000000000..fc27a070e1650 --- /dev/null +++ b/libavcodec/encode.c @@ -0,0 +1,360 @@ +/* + * generic encoding-related code + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/avassert.h" +#include "libavutil/frame.h" +#include "libavutil/imgutils.h" +#include "libavutil/internal.h" +#include "libavutil/samplefmt.h" + +#include "avcodec.h" +#include "internal.h" + +int ff_alloc_packet(AVPacket *avpkt, int size) +{ + if (size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) + return AVERROR(EINVAL); + + if (avpkt->data) { + AVBufferRef *buf = avpkt->buf; + + if (avpkt->size < size) + return AVERROR(EINVAL); + + av_init_packet(avpkt); + avpkt->buf = buf; + avpkt->size = size; + return 0; + } else { + return av_new_packet(avpkt, size); + } +} + +/** + * Pad last frame with silence. + */ +static int pad_last_frame(AVCodecContext *s, AVFrame **dst, const AVFrame *src) +{ + AVFrame *frame = NULL; + int ret; + + if (!(frame = av_frame_alloc())) + return AVERROR(ENOMEM); + + frame->format = src->format; + frame->channel_layout = src->channel_layout; + frame->nb_samples = s->frame_size; + ret = av_frame_get_buffer(frame, 32); + if (ret < 0) + goto fail; + + ret = av_frame_copy_props(frame, src); + if (ret < 0) + goto fail; + + if ((ret = av_samples_copy(frame->extended_data, src->extended_data, 0, 0, + src->nb_samples, s->channels, s->sample_fmt)) < 0) + goto fail; + if ((ret = av_samples_set_silence(frame->extended_data, src->nb_samples, + frame->nb_samples - src->nb_samples, + s->channels, s->sample_fmt)) < 0) + goto fail; + + *dst = frame; + + return 0; + +fail: + av_frame_free(&frame); + return ret; +} + +int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, + AVPacket *avpkt, + const AVFrame *frame, + int *got_packet_ptr) +{ + AVFrame tmp; + AVFrame *padded_frame = NULL; + int ret; + int user_packet = !!avpkt->data; + + *got_packet_ptr = 0; + + if (!avctx->codec->encode2) { + av_log(avctx, AV_LOG_ERROR, "This encoder requires using the avcodec_send_frame() API.\n"); + return AVERROR(ENOSYS); + } + + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) && !frame) { + av_packet_unref(avpkt); + av_init_packet(avpkt); + return 0; + } + + /* ensure that extended_data is properly set */ + if (frame && !frame->extended_data) { + if (av_sample_fmt_is_planar(avctx->sample_fmt) && + avctx->channels > AV_NUM_DATA_POINTERS) { + av_log(avctx, AV_LOG_ERROR, "Encoding to a planar sample format, " + "with more than %d channels, but extended_data is not set.\n", + AV_NUM_DATA_POINTERS); + return AVERROR(EINVAL); + } + av_log(avctx, AV_LOG_WARNING, "extended_data is not set.\n"); + + tmp = *frame; + tmp.extended_data = tmp.data; + frame = &tmp; + } + + /* extract audio service type metadata */ + if (frame) { + AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_AUDIO_SERVICE_TYPE); + if (sd && sd->size >= sizeof(enum AVAudioServiceType)) + avctx->audio_service_type = *(enum AVAudioServiceType*)sd->data; + } + + /* check for valid frame size */ + if (frame) { + if (avctx->codec->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME) { + if (frame->nb_samples > avctx->frame_size) + return AVERROR(EINVAL); + } else if (!(avctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) { + if (frame->nb_samples < avctx->frame_size && + !avctx->internal->last_audio_frame) { + ret = pad_last_frame(avctx, &padded_frame, frame); + if (ret < 0) + return ret; + + frame = padded_frame; + avctx->internal->last_audio_frame = 1; + } + + if (frame->nb_samples != avctx->frame_size) { + ret = AVERROR(EINVAL); + goto end; + } + } + } + + ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr); + if (!ret) { + if (*got_packet_ptr) { + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) { + if (avpkt->pts == AV_NOPTS_VALUE) + avpkt->pts = frame->pts; + if (!avpkt->duration) + avpkt->duration = ff_samples_to_time_base(avctx, + frame->nb_samples); + } + avpkt->dts = avpkt->pts; + } else { + avpkt->size = 0; + } + + if (!user_packet && avpkt->size) { + ret = av_buffer_realloc(&avpkt->buf, avpkt->size); + if (ret >= 0) + avpkt->data = avpkt->buf->data; + } + + avctx->frame_number++; + } + + if (ret < 0 || !*got_packet_ptr) { + av_packet_unref(avpkt); + av_init_packet(avpkt); + goto end; + } + + /* NOTE: if we add any audio encoders which output non-keyframe packets, + * this needs to be moved to the encoders, but for now we can do it + * here to simplify things */ + avpkt->flags |= AV_PKT_FLAG_KEY; + +end: + av_frame_free(&padded_frame); + +#if FF_API_AUDIOENC_DELAY + avctx->delay = avctx->initial_padding; +#endif + + return ret; +} + +int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, + AVPacket *avpkt, + const AVFrame *frame, + int *got_packet_ptr) +{ + int ret; + int user_packet = !!avpkt->data; + + *got_packet_ptr = 0; + + if (!avctx->codec->encode2) { + av_log(avctx, AV_LOG_ERROR, "This encoder requires using the avcodec_send_frame() API.\n"); + return AVERROR(ENOSYS); + } + + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) && !frame) { + av_packet_unref(avpkt); + av_init_packet(avpkt); + avpkt->size = 0; + return 0; + } + + if (av_image_check_size(avctx->width, avctx->height, 0, avctx)) + return AVERROR(EINVAL); + + av_assert0(avctx->codec->encode2); + + ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr); + if (!ret) { + if (!*got_packet_ptr) + avpkt->size = 0; + else if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) + avpkt->pts = avpkt->dts = frame->pts; + + if (!user_packet && avpkt->size) { + ret = av_buffer_realloc(&avpkt->buf, avpkt->size); + if (ret >= 0) + avpkt->data = avpkt->buf->data; + } + + avctx->frame_number++; + } + + if (ret < 0 || !*got_packet_ptr) + av_packet_unref(avpkt); + + emms_c(); + return ret; +} + +int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, + const AVSubtitle *sub) +{ + int ret; + if (sub->start_display_time) { + av_log(avctx, AV_LOG_ERROR, "start_display_time must be 0.\n"); + return -1; + } + if (sub->num_rects == 0 || !sub->rects) + return -1; + ret = avctx->codec->encode_sub(avctx, buf, buf_size, sub); + avctx->frame_number++; + return ret; +} + +static int do_encode(AVCodecContext *avctx, const AVFrame *frame, int *got_packet) +{ + int ret; + *got_packet = 0; + + av_packet_unref(avctx->internal->buffer_pkt); + avctx->internal->buffer_pkt_valid = 0; + + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { + ret = avcodec_encode_video2(avctx, avctx->internal->buffer_pkt, + frame, got_packet); + } else if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) { + ret = avcodec_encode_audio2(avctx, avctx->internal->buffer_pkt, + frame, got_packet); + } else { + ret = AVERROR(EINVAL); + } + + if (ret >= 0 && *got_packet) { + // Encoders must always return ref-counted buffers. + // Side-data only packets have no data and can be not ref-counted. + av_assert0(!avctx->internal->buffer_pkt->data || avctx->internal->buffer_pkt->buf); + avctx->internal->buffer_pkt_valid = 1; + ret = 0; + } else { + av_packet_unref(avctx->internal->buffer_pkt); + } + + return ret; +} + +int attribute_align_arg avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame) +{ + if (!avcodec_is_open(avctx) || !av_codec_is_encoder(avctx->codec)) + return AVERROR(EINVAL); + + if (avctx->internal->draining) + return AVERROR_EOF; + + if (!frame) { + avctx->internal->draining = 1; + + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) + return 0; + } + + if (avctx->codec->send_frame) + return avctx->codec->send_frame(avctx, frame); + + // Emulation via old API. Do it here instead of avcodec_receive_packet, because: + // 1. if the AVFrame is not refcounted, the copying will be much more + // expensive than copying the packet data + // 2. assume few users use non-refcounted AVPackets, so usually no copy is + // needed + + if (avctx->internal->buffer_pkt_valid) + return AVERROR(EAGAIN); + + return do_encode(avctx, frame, &(int){0}); +} + +int attribute_align_arg avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) +{ + av_packet_unref(avpkt); + + if (!avcodec_is_open(avctx) || !av_codec_is_encoder(avctx->codec)) + return AVERROR(EINVAL); + + if (avctx->codec->receive_packet) { + if (avctx->internal->draining && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) + return AVERROR_EOF; + return avctx->codec->receive_packet(avctx, avpkt); + } + + // Emulation via old API. + + if (!avctx->internal->buffer_pkt_valid) { + int got_packet; + int ret; + if (!avctx->internal->draining) + return AVERROR(EAGAIN); + ret = do_encode(avctx, NULL, &got_packet); + if (ret < 0) + return ret; + if (ret >= 0 && !got_packet) + return AVERROR_EOF; + } + + av_packet_move_ref(avpkt, avctx->internal->buffer_pkt); + avctx->internal->buffer_pkt_valid = 0; + return 0; +} diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 329233d473424..d8ba1d59c9ee6 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -1210,244 +1210,6 @@ FF_ENABLE_DEPRECATION_WARNINGS goto end; } -int ff_alloc_packet(AVPacket *avpkt, int size) -{ - if (size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) - return AVERROR(EINVAL); - - if (avpkt->data) { - AVBufferRef *buf = avpkt->buf; - - if (avpkt->size < size) - return AVERROR(EINVAL); - - av_init_packet(avpkt); - avpkt->buf = buf; - avpkt->size = size; - return 0; - } else { - return av_new_packet(avpkt, size); - } -} - -/** - * Pad last frame with silence. - */ -static int pad_last_frame(AVCodecContext *s, AVFrame **dst, const AVFrame *src) -{ - AVFrame *frame = NULL; - int ret; - - if (!(frame = av_frame_alloc())) - return AVERROR(ENOMEM); - - frame->format = src->format; - frame->channel_layout = src->channel_layout; - frame->nb_samples = s->frame_size; - ret = av_frame_get_buffer(frame, 32); - if (ret < 0) - goto fail; - - ret = av_frame_copy_props(frame, src); - if (ret < 0) - goto fail; - - if ((ret = av_samples_copy(frame->extended_data, src->extended_data, 0, 0, - src->nb_samples, s->channels, s->sample_fmt)) < 0) - goto fail; - if ((ret = av_samples_set_silence(frame->extended_data, src->nb_samples, - frame->nb_samples - src->nb_samples, - s->channels, s->sample_fmt)) < 0) - goto fail; - - *dst = frame; - - return 0; - -fail: - av_frame_free(&frame); - return ret; -} - -int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, - AVPacket *avpkt, - const AVFrame *frame, - int *got_packet_ptr) -{ - AVFrame tmp; - AVFrame *padded_frame = NULL; - int ret; - int user_packet = !!avpkt->data; - - *got_packet_ptr = 0; - - if (!avctx->codec->encode2) { - av_log(avctx, AV_LOG_ERROR, "This encoder requires using the avcodec_send_frame() API.\n"); - return AVERROR(ENOSYS); - } - - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) && !frame) { - av_packet_unref(avpkt); - av_init_packet(avpkt); - return 0; - } - - /* ensure that extended_data is properly set */ - if (frame && !frame->extended_data) { - if (av_sample_fmt_is_planar(avctx->sample_fmt) && - avctx->channels > AV_NUM_DATA_POINTERS) { - av_log(avctx, AV_LOG_ERROR, "Encoding to a planar sample format, " - "with more than %d channels, but extended_data is not set.\n", - AV_NUM_DATA_POINTERS); - return AVERROR(EINVAL); - } - av_log(avctx, AV_LOG_WARNING, "extended_data is not set.\n"); - - tmp = *frame; - tmp.extended_data = tmp.data; - frame = &tmp; - } - - /* extract audio service type metadata */ - if (frame) { - AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_AUDIO_SERVICE_TYPE); - if (sd && sd->size >= sizeof(enum AVAudioServiceType)) - avctx->audio_service_type = *(enum AVAudioServiceType*)sd->data; - } - - /* check for valid frame size */ - if (frame) { - if (avctx->codec->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME) { - if (frame->nb_samples > avctx->frame_size) - return AVERROR(EINVAL); - } else if (!(avctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) { - if (frame->nb_samples < avctx->frame_size && - !avctx->internal->last_audio_frame) { - ret = pad_last_frame(avctx, &padded_frame, frame); - if (ret < 0) - return ret; - - frame = padded_frame; - avctx->internal->last_audio_frame = 1; - } - - if (frame->nb_samples != avctx->frame_size) { - ret = AVERROR(EINVAL); - goto end; - } - } - } - - ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr); - if (!ret) { - if (*got_packet_ptr) { - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) { - if (avpkt->pts == AV_NOPTS_VALUE) - avpkt->pts = frame->pts; - if (!avpkt->duration) - avpkt->duration = ff_samples_to_time_base(avctx, - frame->nb_samples); - } - avpkt->dts = avpkt->pts; - } else { - avpkt->size = 0; - } - - if (!user_packet && avpkt->size) { - ret = av_buffer_realloc(&avpkt->buf, avpkt->size); - if (ret >= 0) - avpkt->data = avpkt->buf->data; - } - - avctx->frame_number++; - } - - if (ret < 0 || !*got_packet_ptr) { - av_packet_unref(avpkt); - av_init_packet(avpkt); - goto end; - } - - /* NOTE: if we add any audio encoders which output non-keyframe packets, - * this needs to be moved to the encoders, but for now we can do it - * here to simplify things */ - avpkt->flags |= AV_PKT_FLAG_KEY; - -end: - av_frame_free(&padded_frame); - -#if FF_API_AUDIOENC_DELAY - avctx->delay = avctx->initial_padding; -#endif - - return ret; -} - -int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, - AVPacket *avpkt, - const AVFrame *frame, - int *got_packet_ptr) -{ - int ret; - int user_packet = !!avpkt->data; - - *got_packet_ptr = 0; - - if (!avctx->codec->encode2) { - av_log(avctx, AV_LOG_ERROR, "This encoder requires using the avcodec_send_frame() API.\n"); - return AVERROR(ENOSYS); - } - - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) && !frame) { - av_packet_unref(avpkt); - av_init_packet(avpkt); - avpkt->size = 0; - return 0; - } - - if (av_image_check_size(avctx->width, avctx->height, 0, avctx)) - return AVERROR(EINVAL); - - av_assert0(avctx->codec->encode2); - - ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr); - if (!ret) { - if (!*got_packet_ptr) - avpkt->size = 0; - else if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - avpkt->pts = avpkt->dts = frame->pts; - - if (!user_packet && avpkt->size) { - ret = av_buffer_realloc(&avpkt->buf, avpkt->size); - if (ret >= 0) - avpkt->data = avpkt->buf->data; - } - - avctx->frame_number++; - } - - if (ret < 0 || !*got_packet_ptr) - av_packet_unref(avpkt); - - emms_c(); - return ret; -} - -int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, - const AVSubtitle *sub) -{ - int ret; - if (sub->start_display_time) { - av_log(avctx, AV_LOG_ERROR, "start_display_time must be 0.\n"); - return -1; - } - if (sub->num_rects == 0 || !sub->rects) - return -1; - ret = avctx->codec->encode_sub(avctx, buf, buf_size, sub); - avctx->frame_number++; - return ret; -} - static int apply_param_change(AVCodecContext *avctx, AVPacket *avpkt) { int size = 0, ret; @@ -1849,99 +1611,6 @@ int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *fr return 0; } -static int do_encode(AVCodecContext *avctx, const AVFrame *frame, int *got_packet) -{ - int ret; - *got_packet = 0; - - av_packet_unref(avctx->internal->buffer_pkt); - avctx->internal->buffer_pkt_valid = 0; - - if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { - ret = avcodec_encode_video2(avctx, avctx->internal->buffer_pkt, - frame, got_packet); - } else if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) { - ret = avcodec_encode_audio2(avctx, avctx->internal->buffer_pkt, - frame, got_packet); - } else { - ret = AVERROR(EINVAL); - } - - if (ret >= 0 && *got_packet) { - // Encoders must always return ref-counted buffers. - // Side-data only packets have no data and can be not ref-counted. - av_assert0(!avctx->internal->buffer_pkt->data || avctx->internal->buffer_pkt->buf); - avctx->internal->buffer_pkt_valid = 1; - ret = 0; - } else { - av_packet_unref(avctx->internal->buffer_pkt); - } - - return ret; -} - -int attribute_align_arg avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame) -{ - if (!avcodec_is_open(avctx) || !av_codec_is_encoder(avctx->codec)) - return AVERROR(EINVAL); - - if (avctx->internal->draining) - return AVERROR_EOF; - - if (!frame) { - avctx->internal->draining = 1; - - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - return 0; - } - - if (avctx->codec->send_frame) - return avctx->codec->send_frame(avctx, frame); - - // Emulation via old API. Do it here instead of avcodec_receive_packet, because: - // 1. if the AVFrame is not refcounted, the copying will be much more - // expensive than copying the packet data - // 2. assume few users use non-refcounted AVPackets, so usually no copy is - // needed - - if (avctx->internal->buffer_pkt_valid) - return AVERROR(EAGAIN); - - return do_encode(avctx, frame, &(int){0}); -} - -int attribute_align_arg avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) -{ - av_packet_unref(avpkt); - - if (!avcodec_is_open(avctx) || !av_codec_is_encoder(avctx->codec)) - return AVERROR(EINVAL); - - if (avctx->codec->receive_packet) { - if (avctx->internal->draining && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - return AVERROR_EOF; - return avctx->codec->receive_packet(avctx, avpkt); - } - - // Emulation via old API. - - if (!avctx->internal->buffer_pkt_valid) { - int got_packet; - int ret; - if (!avctx->internal->draining) - return AVERROR(EAGAIN); - ret = do_encode(avctx, NULL, &got_packet); - if (ret < 0) - return ret; - if (ret >= 0 && !got_packet) - return AVERROR_EOF; - } - - av_packet_move_ref(avpkt, avctx->internal->buffer_pkt); - avctx->internal->buffer_pkt_valid = 0; - return 0; -} - av_cold int avcodec_close(AVCodecContext *avctx) { int i; From 3fe2a01df7f2c193805809f57b61d79607572351 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 26 Oct 2016 08:10:19 +0200 Subject: [PATCH 0608/3374] lavc: move decoding-related code from utils.c to a new file --- libavcodec/Makefile | 1 + libavcodec/decode.c | 924 ++++++++++++++++++++++++++++++++++++++++++++ libavcodec/utils.c | 889 ------------------------------------------ 3 files changed, 925 insertions(+), 889 deletions(-) create mode 100644 libavcodec/decode.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index fe723155a5816..dee3d1398e11a 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -23,6 +23,7 @@ OBJS = allcodecs.o \ bsf.o \ codec_desc.o \ d3d11va.o \ + decode.o \ dirac.o \ dv_profile.o \ encode.o \ diff --git a/libavcodec/decode.c b/libavcodec/decode.c new file mode 100644 index 0000000000000..42bcee2d179aa --- /dev/null +++ b/libavcodec/decode.c @@ -0,0 +1,924 @@ +/* + * generic decoding-related code + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "config.h" + +#include "libavutil/avassert.h" +#include "libavutil/common.h" +#include "libavutil/frame.h" +#include "libavutil/hwcontext.h" +#include "libavutil/imgutils.h" + +#include "avcodec.h" +#include "bytestream.h" +#include "internal.h" +#include "thread.h" + +static int apply_param_change(AVCodecContext *avctx, AVPacket *avpkt) +{ + int size = 0, ret; + const uint8_t *data; + uint32_t flags; + + data = av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, &size); + if (!data) + return 0; + + if (!(avctx->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE)) { + av_log(avctx, AV_LOG_ERROR, "This decoder does not support parameter " + "changes, but PARAM_CHANGE side data was sent to it.\n"); + ret = AVERROR(EINVAL); + goto fail2; + } + + if (size < 4) + goto fail; + + flags = bytestream_get_le32(&data); + size -= 4; + + if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT) { + if (size < 4) + goto fail; + avctx->channels = bytestream_get_le32(&data); + size -= 4; + } + if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) { + if (size < 8) + goto fail; + avctx->channel_layout = bytestream_get_le64(&data); + size -= 8; + } + if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) { + if (size < 4) + goto fail; + avctx->sample_rate = bytestream_get_le32(&data); + size -= 4; + } + if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) { + if (size < 8) + goto fail; + avctx->width = bytestream_get_le32(&data); + avctx->height = bytestream_get_le32(&data); + size -= 8; + ret = ff_set_dimensions(avctx, avctx->width, avctx->height); + if (ret < 0) + goto fail2; + } + + return 0; +fail: + av_log(avctx, AV_LOG_ERROR, "PARAM_CHANGE side data too small.\n"); + ret = AVERROR_INVALIDDATA; +fail2: + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n"); + if (avctx->err_recognition & AV_EF_EXPLODE) + return ret; + } + return 0; +} + +static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame) +{ + int ret; + + /* move the original frame to our backup */ + av_frame_unref(avci->to_free); + av_frame_move_ref(avci->to_free, frame); + + /* now copy everything except the AVBufferRefs back + * note that we make a COPY of the side data, so calling av_frame_free() on + * the caller's frame will work properly */ + ret = av_frame_copy_props(frame, avci->to_free); + if (ret < 0) + return ret; + + memcpy(frame->data, avci->to_free->data, sizeof(frame->data)); + memcpy(frame->linesize, avci->to_free->linesize, sizeof(frame->linesize)); + if (avci->to_free->extended_data != avci->to_free->data) { + int planes = av_get_channel_layout_nb_channels(avci->to_free->channel_layout); + int size = planes * sizeof(*frame->extended_data); + + if (!size) { + av_frame_unref(frame); + return AVERROR_BUG; + } + + frame->extended_data = av_malloc(size); + if (!frame->extended_data) { + av_frame_unref(frame); + return AVERROR(ENOMEM); + } + memcpy(frame->extended_data, avci->to_free->extended_data, + size); + } else + frame->extended_data = frame->data; + + frame->format = avci->to_free->format; + frame->width = avci->to_free->width; + frame->height = avci->to_free->height; + frame->channel_layout = avci->to_free->channel_layout; + frame->nb_samples = avci->to_free->nb_samples; + + return 0; +} + +static int do_decode(AVCodecContext *avctx, AVPacket *pkt) +{ + int got_frame; + int ret; + + av_assert0(!avctx->internal->buffer_frame->buf[0]); + + if (!pkt) + pkt = avctx->internal->buffer_pkt; + + // This is the lesser evil. The field is for compatibility with legacy users + // of the legacy API, and users using the new API should not be forced to + // even know about this field. + avctx->refcounted_frames = 1; + + // Some codecs (at least wma lossless) will crash when feeding drain packets + // after EOF was signaled. + if (avctx->internal->draining_done) + return AVERROR_EOF; + + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { + ret = avcodec_decode_video2(avctx, avctx->internal->buffer_frame, + &got_frame, pkt); + if (ret >= 0) + ret = pkt->size; + } else if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) { + ret = avcodec_decode_audio4(avctx, avctx->internal->buffer_frame, + &got_frame, pkt); + } else { + ret = AVERROR(EINVAL); + } + + if (ret < 0) + return ret; + + if (avctx->internal->draining && !got_frame) + avctx->internal->draining_done = 1; + + if (ret >= pkt->size) { + av_packet_unref(avctx->internal->buffer_pkt); + } else { + int consumed = ret; + + if (pkt != avctx->internal->buffer_pkt) { + av_packet_unref(avctx->internal->buffer_pkt); + if ((ret = av_packet_ref(avctx->internal->buffer_pkt, pkt)) < 0) + return ret; + } + + avctx->internal->buffer_pkt->data += consumed; + avctx->internal->buffer_pkt->size -= consumed; + avctx->internal->buffer_pkt->pts = AV_NOPTS_VALUE; + avctx->internal->buffer_pkt->dts = AV_NOPTS_VALUE; + } + + if (got_frame) + av_assert0(avctx->internal->buffer_frame->buf[0]); + + return 0; +} + +int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt) +{ + int ret; + + if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec)) + return AVERROR(EINVAL); + + if (avctx->internal->draining) + return AVERROR_EOF; + + if (!avpkt || !avpkt->size) { + avctx->internal->draining = 1; + avpkt = NULL; + + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) + return 0; + } + + if (avctx->codec->send_packet) { + if (avpkt) { + ret = apply_param_change(avctx, (AVPacket *)avpkt); + if (ret < 0) + return ret; + } + return avctx->codec->send_packet(avctx, avpkt); + } + + // Emulation via old API. Assume avpkt is likely not refcounted, while + // decoder output is always refcounted, and avoid copying. + + if (avctx->internal->buffer_pkt->size || avctx->internal->buffer_frame->buf[0]) + return AVERROR(EAGAIN); + + // The goal is decoding the first frame of the packet without using memcpy, + // because the common case is having only 1 frame per packet (especially + // with video, but audio too). In other cases, it can't be avoided, unless + // the user is feeding refcounted packets. + return do_decode(avctx, (AVPacket *)avpkt); +} + +int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame) +{ + int ret; + + av_frame_unref(frame); + + if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec)) + return AVERROR(EINVAL); + + if (avctx->codec->receive_frame) { + if (avctx->internal->draining && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) + return AVERROR_EOF; + return avctx->codec->receive_frame(avctx, frame); + } + + // Emulation via old API. + + if (!avctx->internal->buffer_frame->buf[0]) { + if (!avctx->internal->buffer_pkt->size && !avctx->internal->draining) + return AVERROR(EAGAIN); + + while (1) { + if ((ret = do_decode(avctx, avctx->internal->buffer_pkt)) < 0) { + av_packet_unref(avctx->internal->buffer_pkt); + return ret; + } + // Some audio decoders may consume partial data without returning + // a frame (fate-wmapro-2ch). There is no way to make the caller + // call avcodec_receive_frame() again without returning a frame, + // so try to decode more in these cases. + if (avctx->internal->buffer_frame->buf[0] || + !avctx->internal->buffer_pkt->size) + break; + } + } + + if (!avctx->internal->buffer_frame->buf[0]) + return avctx->internal->draining ? AVERROR_EOF : AVERROR(EAGAIN); + + av_frame_move_ref(frame, avctx->internal->buffer_frame); + return 0; +} + +int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, + int *got_picture_ptr, + AVPacket *avpkt) +{ + AVCodecInternal *avci = avctx->internal; + int ret; + + *got_picture_ptr = 0; + if ((avctx->coded_width || avctx->coded_height) && av_image_check_size(avctx->coded_width, avctx->coded_height, 0, avctx)) + return -1; + + if (!avctx->codec->decode) { + av_log(avctx, AV_LOG_ERROR, "This decoder requires using the avcodec_send_packet() API.\n"); + return AVERROR(ENOSYS); + } + + avctx->internal->pkt = avpkt; + ret = apply_param_change(avctx, avpkt); + if (ret < 0) + return ret; + + av_frame_unref(picture); + + if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size || + (avctx->active_thread_type & FF_THREAD_FRAME)) { + if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) + ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr, + avpkt); + else { + ret = avctx->codec->decode(avctx, picture, got_picture_ptr, + avpkt); + if (!(avctx->codec->caps_internal & FF_CODEC_CAP_SETS_PKT_DTS)) + picture->pkt_dts = avpkt->dts; + /* get_buffer is supposed to set frame parameters */ + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DR1)) { + picture->sample_aspect_ratio = avctx->sample_aspect_ratio; + picture->width = avctx->width; + picture->height = avctx->height; + picture->format = avctx->pix_fmt; + } + } + + emms_c(); //needed to avoid an emms_c() call before every return; + + if (*got_picture_ptr) { + if (!avctx->refcounted_frames) { + int err = unrefcount_frame(avci, picture); + if (err < 0) + return err; + } + + avctx->frame_number++; + } else + av_frame_unref(picture); + } else + ret = 0; + +#if FF_API_AVCTX_TIMEBASE + if (avctx->framerate.num > 0 && avctx->framerate.den > 0) + avctx->time_base = av_inv_q(avctx->framerate); +#endif + + return ret; +} + +int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, + AVFrame *frame, + int *got_frame_ptr, + AVPacket *avpkt) +{ + AVCodecInternal *avci = avctx->internal; + int ret = 0; + + *got_frame_ptr = 0; + + if (!avctx->codec->decode) { + av_log(avctx, AV_LOG_ERROR, "This decoder requires using the avcodec_send_packet() API.\n"); + return AVERROR(ENOSYS); + } + + avctx->internal->pkt = avpkt; + + if (!avpkt->data && avpkt->size) { + av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n"); + return AVERROR(EINVAL); + } + + ret = apply_param_change(avctx, avpkt); + if (ret < 0) + return ret; + + av_frame_unref(frame); + + if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size) { + ret = avctx->codec->decode(avctx, frame, got_frame_ptr, avpkt); + if (ret >= 0 && *got_frame_ptr) { + avctx->frame_number++; + frame->pkt_dts = avpkt->dts; + if (frame->format == AV_SAMPLE_FMT_NONE) + frame->format = avctx->sample_fmt; + + if (!avctx->refcounted_frames) { + int err = unrefcount_frame(avci, frame); + if (err < 0) + return err; + } + } else + av_frame_unref(frame); + } + + + return ret; +} + +int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, + int *got_sub_ptr, + AVPacket *avpkt) +{ + int ret; + + avctx->internal->pkt = avpkt; + *got_sub_ptr = 0; + ret = avctx->codec->decode(avctx, sub, got_sub_ptr, avpkt); + if (*got_sub_ptr) + avctx->frame_number++; + return ret; +} + +static int is_hwaccel_pix_fmt(enum AVPixelFormat pix_fmt) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + return desc->flags & AV_PIX_FMT_FLAG_HWACCEL; +} + +enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum AVPixelFormat *fmt) +{ + while (*fmt != AV_PIX_FMT_NONE && is_hwaccel_pix_fmt(*fmt)) + ++fmt; + return fmt[0]; +} + +static AVHWAccel *find_hwaccel(enum AVCodecID codec_id, + enum AVPixelFormat pix_fmt) +{ + AVHWAccel *hwaccel = NULL; + + while ((hwaccel = av_hwaccel_next(hwaccel))) + if (hwaccel->id == codec_id + && hwaccel->pix_fmt == pix_fmt) + return hwaccel; + return NULL; +} + +static int setup_hwaccel(AVCodecContext *avctx, + const enum AVPixelFormat fmt, + const char *name) +{ + AVHWAccel *hwa = find_hwaccel(avctx->codec_id, fmt); + int ret = 0; + + if (!hwa) { + av_log(avctx, AV_LOG_ERROR, + "Could not find an AVHWAccel for the pixel format: %s", + name); + return AVERROR(ENOENT); + } + + if (hwa->priv_data_size) { + avctx->internal->hwaccel_priv_data = av_mallocz(hwa->priv_data_size); + if (!avctx->internal->hwaccel_priv_data) + return AVERROR(ENOMEM); + } + + if (hwa->init) { + ret = hwa->init(avctx); + if (ret < 0) { + av_freep(&avctx->internal->hwaccel_priv_data); + return ret; + } + } + + avctx->hwaccel = hwa; + + return 0; +} + +int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) +{ + const AVPixFmtDescriptor *desc; + enum AVPixelFormat *choices; + enum AVPixelFormat ret; + unsigned n = 0; + + while (fmt[n] != AV_PIX_FMT_NONE) + ++n; + + av_assert0(n >= 1); + avctx->sw_pix_fmt = fmt[n - 1]; + av_assert2(!is_hwaccel_pix_fmt(avctx->sw_pix_fmt)); + + choices = av_malloc_array(n + 1, sizeof(*choices)); + if (!choices) + return AV_PIX_FMT_NONE; + + memcpy(choices, fmt, (n + 1) * sizeof(*choices)); + + for (;;) { + if (avctx->hwaccel && avctx->hwaccel->uninit) + avctx->hwaccel->uninit(avctx); + av_freep(&avctx->internal->hwaccel_priv_data); + avctx->hwaccel = NULL; + + av_buffer_unref(&avctx->hw_frames_ctx); + + ret = avctx->get_format(avctx, choices); + + desc = av_pix_fmt_desc_get(ret); + if (!desc) { + ret = AV_PIX_FMT_NONE; + break; + } + + if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) + break; + + if (avctx->hw_frames_ctx) { + AVHWFramesContext *hw_frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; + if (hw_frames_ctx->format != ret) { + av_log(avctx, AV_LOG_ERROR, "Format returned from get_buffer() " + "does not match the format of provided AVHWFramesContext\n"); + ret = AV_PIX_FMT_NONE; + break; + } + } + + if (!setup_hwaccel(avctx, ret, desc->name)) + break; + + /* Remove failed hwaccel from choices */ + for (n = 0; choices[n] != ret; n++) + av_assert0(choices[n] != AV_PIX_FMT_NONE); + + do + choices[n] = choices[n + 1]; + while (choices[n++] != AV_PIX_FMT_NONE); + } + + av_freep(&choices); + return ret; +} + +static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame) +{ + FramePool *pool = avctx->internal->pool; + int i, ret; + + switch (avctx->codec_type) { + case AVMEDIA_TYPE_VIDEO: { + uint8_t *data[4]; + int linesize[4]; + int size[4] = { 0 }; + int w = frame->width; + int h = frame->height; + int tmpsize, unaligned; + + if (pool->format == frame->format && + pool->width == frame->width && pool->height == frame->height) + return 0; + + avcodec_align_dimensions2(avctx, &w, &h, pool->stride_align); + + do { + // NOTE: do not align linesizes individually, this breaks e.g. assumptions + // that linesize[0] == 2*linesize[1] in the MPEG-encoder for 4:2:2 + av_image_fill_linesizes(linesize, avctx->pix_fmt, w); + // increase alignment of w for next try (rhs gives the lowest bit set in w) + w += w & ~(w - 1); + + unaligned = 0; + for (i = 0; i < 4; i++) + unaligned |= linesize[i] % pool->stride_align[i]; + } while (unaligned); + + tmpsize = av_image_fill_pointers(data, avctx->pix_fmt, h, + NULL, linesize); + if (tmpsize < 0) + return -1; + + for (i = 0; i < 3 && data[i + 1]; i++) + size[i] = data[i + 1] - data[i]; + size[i] = tmpsize - (data[i] - data[0]); + + for (i = 0; i < 4; i++) { + av_buffer_pool_uninit(&pool->pools[i]); + pool->linesize[i] = linesize[i]; + if (size[i]) { + pool->pools[i] = av_buffer_pool_init(size[i] + 16, NULL); + if (!pool->pools[i]) { + ret = AVERROR(ENOMEM); + goto fail; + } + } + } + pool->format = frame->format; + pool->width = frame->width; + pool->height = frame->height; + + break; + } + case AVMEDIA_TYPE_AUDIO: { + int ch = av_get_channel_layout_nb_channels(frame->channel_layout); + int planar = av_sample_fmt_is_planar(frame->format); + int planes = planar ? ch : 1; + + if (pool->format == frame->format && pool->planes == planes && + pool->channels == ch && frame->nb_samples == pool->samples) + return 0; + + av_buffer_pool_uninit(&pool->pools[0]); + ret = av_samples_get_buffer_size(&pool->linesize[0], ch, + frame->nb_samples, frame->format, 0); + if (ret < 0) + goto fail; + + pool->pools[0] = av_buffer_pool_init(pool->linesize[0], NULL); + if (!pool->pools[0]) { + ret = AVERROR(ENOMEM); + goto fail; + } + + pool->format = frame->format; + pool->planes = planes; + pool->channels = ch; + pool->samples = frame->nb_samples; + break; + } + default: av_assert0(0); + } + return 0; +fail: + for (i = 0; i < 4; i++) + av_buffer_pool_uninit(&pool->pools[i]); + pool->format = -1; + pool->planes = pool->channels = pool->samples = 0; + pool->width = pool->height = 0; + return ret; +} + +static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame) +{ + FramePool *pool = avctx->internal->pool; + int planes = pool->planes; + int i; + + frame->linesize[0] = pool->linesize[0]; + + if (planes > AV_NUM_DATA_POINTERS) { + frame->extended_data = av_mallocz(planes * sizeof(*frame->extended_data)); + frame->nb_extended_buf = planes - AV_NUM_DATA_POINTERS; + frame->extended_buf = av_mallocz(frame->nb_extended_buf * + sizeof(*frame->extended_buf)); + if (!frame->extended_data || !frame->extended_buf) { + av_freep(&frame->extended_data); + av_freep(&frame->extended_buf); + return AVERROR(ENOMEM); + } + } else + frame->extended_data = frame->data; + + for (i = 0; i < FFMIN(planes, AV_NUM_DATA_POINTERS); i++) { + frame->buf[i] = av_buffer_pool_get(pool->pools[0]); + if (!frame->buf[i]) + goto fail; + frame->extended_data[i] = frame->data[i] = frame->buf[i]->data; + } + for (i = 0; i < frame->nb_extended_buf; i++) { + frame->extended_buf[i] = av_buffer_pool_get(pool->pools[0]); + if (!frame->extended_buf[i]) + goto fail; + frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data; + } + + if (avctx->debug & FF_DEBUG_BUFFERS) + av_log(avctx, AV_LOG_DEBUG, "default_get_buffer called on frame %p", frame); + + return 0; +fail: + av_frame_unref(frame); + return AVERROR(ENOMEM); +} + +static int video_get_buffer(AVCodecContext *s, AVFrame *pic) +{ + FramePool *pool = s->internal->pool; + int i; + + if (pic->data[0]) { + av_log(s, AV_LOG_ERROR, "pic->data[0]!=NULL in avcodec_default_get_buffer\n"); + return -1; + } + + memset(pic->data, 0, sizeof(pic->data)); + pic->extended_data = pic->data; + + for (i = 0; i < 4 && pool->pools[i]; i++) { + pic->linesize[i] = pool->linesize[i]; + + pic->buf[i] = av_buffer_pool_get(pool->pools[i]); + if (!pic->buf[i]) + goto fail; + + pic->data[i] = pic->buf[i]->data; + } + for (; i < AV_NUM_DATA_POINTERS; i++) { + pic->data[i] = NULL; + pic->linesize[i] = 0; + } + if (pic->data[1] && !pic->data[2]) + avpriv_set_systematic_pal2((uint32_t *)pic->data[1], s->pix_fmt); + + if (s->debug & FF_DEBUG_BUFFERS) + av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p\n", pic); + + return 0; +fail: + av_frame_unref(pic); + return AVERROR(ENOMEM); +} + +int avcodec_default_get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags) +{ + int ret; + + if (avctx->hw_frames_ctx) + return av_hwframe_get_buffer(avctx->hw_frames_ctx, frame, 0); + + if ((ret = update_frame_pool(avctx, frame)) < 0) + return ret; + + switch (avctx->codec_type) { + case AVMEDIA_TYPE_VIDEO: + return video_get_buffer(avctx, frame); + case AVMEDIA_TYPE_AUDIO: + return audio_get_buffer(avctx, frame); + default: + return -1; + } +} + +int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) +{ + AVPacket *pkt = avctx->internal->pkt; + int i; + struct { + enum AVPacketSideDataType packet; + enum AVFrameSideDataType frame; + } sd[] = { + { AV_PKT_DATA_REPLAYGAIN , AV_FRAME_DATA_REPLAYGAIN }, + { AV_PKT_DATA_DISPLAYMATRIX, AV_FRAME_DATA_DISPLAYMATRIX }, + { AV_PKT_DATA_STEREO3D, AV_FRAME_DATA_STEREO3D }, + { AV_PKT_DATA_AUDIO_SERVICE_TYPE, AV_FRAME_DATA_AUDIO_SERVICE_TYPE }, + }; + + frame->color_primaries = avctx->color_primaries; + frame->color_trc = avctx->color_trc; + frame->colorspace = avctx->colorspace; + frame->color_range = avctx->color_range; + frame->chroma_location = avctx->chroma_sample_location; + + frame->reordered_opaque = avctx->reordered_opaque; + if (!pkt) { +#if FF_API_PKT_PTS +FF_DISABLE_DEPRECATION_WARNINGS + frame->pkt_pts = AV_NOPTS_VALUE; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + frame->pts = AV_NOPTS_VALUE; + return 0; + } + +#if FF_API_PKT_PTS +FF_DISABLE_DEPRECATION_WARNINGS + frame->pkt_pts = pkt->pts; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + frame->pts = pkt->pts; + + for (i = 0; i < FF_ARRAY_ELEMS(sd); i++) { + int size; + uint8_t *packet_sd = av_packet_get_side_data(pkt, sd[i].packet, &size); + if (packet_sd) { + AVFrameSideData *frame_sd = av_frame_new_side_data(frame, + sd[i].frame, + size); + if (!frame_sd) + return AVERROR(ENOMEM); + + memcpy(frame_sd->data, packet_sd, size); + } + } + + return 0; +} + +int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) +{ + const AVHWAccel *hwaccel = avctx->hwaccel; + int override_dimensions = 1; + int ret; + + switch (avctx->codec_type) { + case AVMEDIA_TYPE_VIDEO: + if (frame->width <= 0 || frame->height <= 0) { + frame->width = FFMAX(avctx->width, avctx->coded_width); + frame->height = FFMAX(avctx->height, avctx->coded_height); + override_dimensions = 0; + } + if (frame->format < 0) + frame->format = avctx->pix_fmt; + if (!frame->sample_aspect_ratio.num) + frame->sample_aspect_ratio = avctx->sample_aspect_ratio; + + if (av_image_check_sar(frame->width, frame->height, + frame->sample_aspect_ratio) < 0) { + av_log(avctx, AV_LOG_WARNING, "ignoring invalid SAR: %u/%u\n", + frame->sample_aspect_ratio.num, + frame->sample_aspect_ratio.den); + frame->sample_aspect_ratio = (AVRational){ 0, 1 }; + } + + if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0) + return ret; + break; + case AVMEDIA_TYPE_AUDIO: + if (!frame->sample_rate) + frame->sample_rate = avctx->sample_rate; + if (frame->format < 0) + frame->format = avctx->sample_fmt; + if (!frame->channel_layout) { + if (avctx->channel_layout) { + if (av_get_channel_layout_nb_channels(avctx->channel_layout) != + avctx->channels) { + av_log(avctx, AV_LOG_ERROR, "Inconsistent channel " + "configuration.\n"); + return AVERROR(EINVAL); + } + + frame->channel_layout = avctx->channel_layout; + } else { + if (avctx->channels > FF_SANE_NB_CHANNELS) { + av_log(avctx, AV_LOG_ERROR, "Too many channels: %d.\n", + avctx->channels); + return AVERROR(ENOSYS); + } + + frame->channel_layout = av_get_default_channel_layout(avctx->channels); + if (!frame->channel_layout) + frame->channel_layout = (1ULL << avctx->channels) - 1; + } + } + break; + default: return AVERROR(EINVAL); + } + + ret = ff_decode_frame_props(avctx, frame); + if (ret < 0) + return ret; + + if (hwaccel) { + if (hwaccel->alloc_frame) { + ret = hwaccel->alloc_frame(avctx, frame); + goto end; + } + } else + avctx->sw_pix_fmt = avctx->pix_fmt; + + ret = avctx->get_buffer2(avctx, frame, flags); + +end: + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && !override_dimensions) { + frame->width = avctx->width; + frame->height = avctx->height; + } + + return ret; +} + +int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame) +{ + AVFrame *tmp; + int ret; + + av_assert0(avctx->codec_type == AVMEDIA_TYPE_VIDEO); + + if (!frame->data[0]) + return ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF); + + if (av_frame_is_writable(frame)) + return ff_decode_frame_props(avctx, frame); + + tmp = av_frame_alloc(); + if (!tmp) + return AVERROR(ENOMEM); + + av_frame_move_ref(tmp, frame); + + ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF); + if (ret < 0) { + av_frame_free(&tmp); + return ret; + } + + av_frame_copy(frame, tmp); + av_frame_free(&tmp); + + return 0; +} + +void avcodec_flush_buffers(AVCodecContext *avctx) +{ + avctx->internal->draining = 0; + avctx->internal->draining_done = 0; + av_frame_unref(avctx->internal->buffer_frame); + av_packet_unref(avctx->internal->buffer_pkt); + avctx->internal->buffer_pkt_valid = 0; + + if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) + ff_thread_flush(avctx); + else if (avctx->codec->flush) + avctx->codec->flush(avctx); + + if (!avctx->refcounted_frames) + av_frame_unref(avctx->internal->to_free); +} diff --git a/libavcodec/utils.c b/libavcodec/utils.c index d8ba1d59c9ee6..0b44bb64647cc 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -335,373 +335,6 @@ int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels, return ret; } -static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame) -{ - FramePool *pool = avctx->internal->pool; - int i, ret; - - switch (avctx->codec_type) { - case AVMEDIA_TYPE_VIDEO: { - uint8_t *data[4]; - int linesize[4]; - int size[4] = { 0 }; - int w = frame->width; - int h = frame->height; - int tmpsize, unaligned; - - if (pool->format == frame->format && - pool->width == frame->width && pool->height == frame->height) - return 0; - - avcodec_align_dimensions2(avctx, &w, &h, pool->stride_align); - - do { - // NOTE: do not align linesizes individually, this breaks e.g. assumptions - // that linesize[0] == 2*linesize[1] in the MPEG-encoder for 4:2:2 - av_image_fill_linesizes(linesize, avctx->pix_fmt, w); - // increase alignment of w for next try (rhs gives the lowest bit set in w) - w += w & ~(w - 1); - - unaligned = 0; - for (i = 0; i < 4; i++) - unaligned |= linesize[i] % pool->stride_align[i]; - } while (unaligned); - - tmpsize = av_image_fill_pointers(data, avctx->pix_fmt, h, - NULL, linesize); - if (tmpsize < 0) - return -1; - - for (i = 0; i < 3 && data[i + 1]; i++) - size[i] = data[i + 1] - data[i]; - size[i] = tmpsize - (data[i] - data[0]); - - for (i = 0; i < 4; i++) { - av_buffer_pool_uninit(&pool->pools[i]); - pool->linesize[i] = linesize[i]; - if (size[i]) { - pool->pools[i] = av_buffer_pool_init(size[i] + 16, NULL); - if (!pool->pools[i]) { - ret = AVERROR(ENOMEM); - goto fail; - } - } - } - pool->format = frame->format; - pool->width = frame->width; - pool->height = frame->height; - - break; - } - case AVMEDIA_TYPE_AUDIO: { - int ch = av_get_channel_layout_nb_channels(frame->channel_layout); - int planar = av_sample_fmt_is_planar(frame->format); - int planes = planar ? ch : 1; - - if (pool->format == frame->format && pool->planes == planes && - pool->channels == ch && frame->nb_samples == pool->samples) - return 0; - - av_buffer_pool_uninit(&pool->pools[0]); - ret = av_samples_get_buffer_size(&pool->linesize[0], ch, - frame->nb_samples, frame->format, 0); - if (ret < 0) - goto fail; - - pool->pools[0] = av_buffer_pool_init(pool->linesize[0], NULL); - if (!pool->pools[0]) { - ret = AVERROR(ENOMEM); - goto fail; - } - - pool->format = frame->format; - pool->planes = planes; - pool->channels = ch; - pool->samples = frame->nb_samples; - break; - } - default: av_assert0(0); - } - return 0; -fail: - for (i = 0; i < 4; i++) - av_buffer_pool_uninit(&pool->pools[i]); - pool->format = -1; - pool->planes = pool->channels = pool->samples = 0; - pool->width = pool->height = 0; - return ret; -} - -static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame) -{ - FramePool *pool = avctx->internal->pool; - int planes = pool->planes; - int i; - - frame->linesize[0] = pool->linesize[0]; - - if (planes > AV_NUM_DATA_POINTERS) { - frame->extended_data = av_mallocz(planes * sizeof(*frame->extended_data)); - frame->nb_extended_buf = planes - AV_NUM_DATA_POINTERS; - frame->extended_buf = av_mallocz(frame->nb_extended_buf * - sizeof(*frame->extended_buf)); - if (!frame->extended_data || !frame->extended_buf) { - av_freep(&frame->extended_data); - av_freep(&frame->extended_buf); - return AVERROR(ENOMEM); - } - } else - frame->extended_data = frame->data; - - for (i = 0; i < FFMIN(planes, AV_NUM_DATA_POINTERS); i++) { - frame->buf[i] = av_buffer_pool_get(pool->pools[0]); - if (!frame->buf[i]) - goto fail; - frame->extended_data[i] = frame->data[i] = frame->buf[i]->data; - } - for (i = 0; i < frame->nb_extended_buf; i++) { - frame->extended_buf[i] = av_buffer_pool_get(pool->pools[0]); - if (!frame->extended_buf[i]) - goto fail; - frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data; - } - - if (avctx->debug & FF_DEBUG_BUFFERS) - av_log(avctx, AV_LOG_DEBUG, "default_get_buffer called on frame %p", frame); - - return 0; -fail: - av_frame_unref(frame); - return AVERROR(ENOMEM); -} - -static int video_get_buffer(AVCodecContext *s, AVFrame *pic) -{ - FramePool *pool = s->internal->pool; - int i; - - if (pic->data[0]) { - av_log(s, AV_LOG_ERROR, "pic->data[0]!=NULL in avcodec_default_get_buffer\n"); - return -1; - } - - memset(pic->data, 0, sizeof(pic->data)); - pic->extended_data = pic->data; - - for (i = 0; i < 4 && pool->pools[i]; i++) { - pic->linesize[i] = pool->linesize[i]; - - pic->buf[i] = av_buffer_pool_get(pool->pools[i]); - if (!pic->buf[i]) - goto fail; - - pic->data[i] = pic->buf[i]->data; - } - for (; i < AV_NUM_DATA_POINTERS; i++) { - pic->data[i] = NULL; - pic->linesize[i] = 0; - } - if (pic->data[1] && !pic->data[2]) - avpriv_set_systematic_pal2((uint32_t *)pic->data[1], s->pix_fmt); - - if (s->debug & FF_DEBUG_BUFFERS) - av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p\n", pic); - - return 0; -fail: - av_frame_unref(pic); - return AVERROR(ENOMEM); -} - -int avcodec_default_get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags) -{ - int ret; - - if (avctx->hw_frames_ctx) - return av_hwframe_get_buffer(avctx->hw_frames_ctx, frame, 0); - - if ((ret = update_frame_pool(avctx, frame)) < 0) - return ret; - - switch (avctx->codec_type) { - case AVMEDIA_TYPE_VIDEO: - return video_get_buffer(avctx, frame); - case AVMEDIA_TYPE_AUDIO: - return audio_get_buffer(avctx, frame); - default: - return -1; - } -} - -int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) -{ - AVPacket *pkt = avctx->internal->pkt; - int i; - struct { - enum AVPacketSideDataType packet; - enum AVFrameSideDataType frame; - } sd[] = { - { AV_PKT_DATA_REPLAYGAIN , AV_FRAME_DATA_REPLAYGAIN }, - { AV_PKT_DATA_DISPLAYMATRIX, AV_FRAME_DATA_DISPLAYMATRIX }, - { AV_PKT_DATA_STEREO3D, AV_FRAME_DATA_STEREO3D }, - { AV_PKT_DATA_AUDIO_SERVICE_TYPE, AV_FRAME_DATA_AUDIO_SERVICE_TYPE }, - }; - - frame->color_primaries = avctx->color_primaries; - frame->color_trc = avctx->color_trc; - frame->colorspace = avctx->colorspace; - frame->color_range = avctx->color_range; - frame->chroma_location = avctx->chroma_sample_location; - - frame->reordered_opaque = avctx->reordered_opaque; - if (!pkt) { -#if FF_API_PKT_PTS -FF_DISABLE_DEPRECATION_WARNINGS - frame->pkt_pts = AV_NOPTS_VALUE; -FF_ENABLE_DEPRECATION_WARNINGS -#endif - frame->pts = AV_NOPTS_VALUE; - return 0; - } - -#if FF_API_PKT_PTS -FF_DISABLE_DEPRECATION_WARNINGS - frame->pkt_pts = pkt->pts; -FF_ENABLE_DEPRECATION_WARNINGS -#endif - frame->pts = pkt->pts; - - for (i = 0; i < FF_ARRAY_ELEMS(sd); i++) { - int size; - uint8_t *packet_sd = av_packet_get_side_data(pkt, sd[i].packet, &size); - if (packet_sd) { - AVFrameSideData *frame_sd = av_frame_new_side_data(frame, - sd[i].frame, - size); - if (!frame_sd) - return AVERROR(ENOMEM); - - memcpy(frame_sd->data, packet_sd, size); - } - } - - return 0; -} - -int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) -{ - const AVHWAccel *hwaccel = avctx->hwaccel; - int override_dimensions = 1; - int ret; - - switch (avctx->codec_type) { - case AVMEDIA_TYPE_VIDEO: - if (frame->width <= 0 || frame->height <= 0) { - frame->width = FFMAX(avctx->width, avctx->coded_width); - frame->height = FFMAX(avctx->height, avctx->coded_height); - override_dimensions = 0; - } - if (frame->format < 0) - frame->format = avctx->pix_fmt; - if (!frame->sample_aspect_ratio.num) - frame->sample_aspect_ratio = avctx->sample_aspect_ratio; - - if (av_image_check_sar(frame->width, frame->height, - frame->sample_aspect_ratio) < 0) { - av_log(avctx, AV_LOG_WARNING, "ignoring invalid SAR: %u/%u\n", - frame->sample_aspect_ratio.num, - frame->sample_aspect_ratio.den); - frame->sample_aspect_ratio = (AVRational){ 0, 1 }; - } - - if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0) - return ret; - break; - case AVMEDIA_TYPE_AUDIO: - if (!frame->sample_rate) - frame->sample_rate = avctx->sample_rate; - if (frame->format < 0) - frame->format = avctx->sample_fmt; - if (!frame->channel_layout) { - if (avctx->channel_layout) { - if (av_get_channel_layout_nb_channels(avctx->channel_layout) != - avctx->channels) { - av_log(avctx, AV_LOG_ERROR, "Inconsistent channel " - "configuration.\n"); - return AVERROR(EINVAL); - } - - frame->channel_layout = avctx->channel_layout; - } else { - if (avctx->channels > FF_SANE_NB_CHANNELS) { - av_log(avctx, AV_LOG_ERROR, "Too many channels: %d.\n", - avctx->channels); - return AVERROR(ENOSYS); - } - - frame->channel_layout = av_get_default_channel_layout(avctx->channels); - if (!frame->channel_layout) - frame->channel_layout = (1ULL << avctx->channels) - 1; - } - } - break; - default: return AVERROR(EINVAL); - } - - ret = ff_decode_frame_props(avctx, frame); - if (ret < 0) - return ret; - - if (hwaccel) { - if (hwaccel->alloc_frame) { - ret = hwaccel->alloc_frame(avctx, frame); - goto end; - } - } else - avctx->sw_pix_fmt = avctx->pix_fmt; - - ret = avctx->get_buffer2(avctx, frame, flags); - -end: - if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && !override_dimensions) { - frame->width = avctx->width; - frame->height = avctx->height; - } - - return ret; -} - -int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame) -{ - AVFrame *tmp; - int ret; - - av_assert0(avctx->codec_type == AVMEDIA_TYPE_VIDEO); - - if (!frame->data[0]) - return ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF); - - if (av_frame_is_writable(frame)) - return ff_decode_frame_props(avctx, frame); - - tmp = av_frame_alloc(); - if (!tmp) - return AVERROR(ENOMEM); - - av_frame_move_ref(tmp, frame); - - ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF); - if (ret < 0) { - av_frame_free(&tmp); - return ret; - } - - av_frame_copy(frame, tmp); - av_frame_free(&tmp); - - return 0; -} - int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2), void *arg, int *ret, int count, int size) { int i; @@ -726,129 +359,6 @@ int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, return 0; } -static int is_hwaccel_pix_fmt(enum AVPixelFormat pix_fmt) -{ - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); - return desc->flags & AV_PIX_FMT_FLAG_HWACCEL; -} - -enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum AVPixelFormat *fmt) -{ - while (*fmt != AV_PIX_FMT_NONE && is_hwaccel_pix_fmt(*fmt)) - ++fmt; - return fmt[0]; -} - -static AVHWAccel *find_hwaccel(enum AVCodecID codec_id, - enum AVPixelFormat pix_fmt) -{ - AVHWAccel *hwaccel = NULL; - - while ((hwaccel = av_hwaccel_next(hwaccel))) - if (hwaccel->id == codec_id - && hwaccel->pix_fmt == pix_fmt) - return hwaccel; - return NULL; -} - -static int setup_hwaccel(AVCodecContext *avctx, - const enum AVPixelFormat fmt, - const char *name) -{ - AVHWAccel *hwa = find_hwaccel(avctx->codec_id, fmt); - int ret = 0; - - if (!hwa) { - av_log(avctx, AV_LOG_ERROR, - "Could not find an AVHWAccel for the pixel format: %s", - name); - return AVERROR(ENOENT); - } - - if (hwa->priv_data_size) { - avctx->internal->hwaccel_priv_data = av_mallocz(hwa->priv_data_size); - if (!avctx->internal->hwaccel_priv_data) - return AVERROR(ENOMEM); - } - - if (hwa->init) { - ret = hwa->init(avctx); - if (ret < 0) { - av_freep(&avctx->internal->hwaccel_priv_data); - return ret; - } - } - - avctx->hwaccel = hwa; - - return 0; -} - -int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) -{ - const AVPixFmtDescriptor *desc; - enum AVPixelFormat *choices; - enum AVPixelFormat ret; - unsigned n = 0; - - while (fmt[n] != AV_PIX_FMT_NONE) - ++n; - - av_assert0(n >= 1); - avctx->sw_pix_fmt = fmt[n - 1]; - av_assert2(!is_hwaccel_pix_fmt(avctx->sw_pix_fmt)); - - choices = av_malloc_array(n + 1, sizeof(*choices)); - if (!choices) - return AV_PIX_FMT_NONE; - - memcpy(choices, fmt, (n + 1) * sizeof(*choices)); - - for (;;) { - if (avctx->hwaccel && avctx->hwaccel->uninit) - avctx->hwaccel->uninit(avctx); - av_freep(&avctx->internal->hwaccel_priv_data); - avctx->hwaccel = NULL; - - av_buffer_unref(&avctx->hw_frames_ctx); - - ret = avctx->get_format(avctx, choices); - - desc = av_pix_fmt_desc_get(ret); - if (!desc) { - ret = AV_PIX_FMT_NONE; - break; - } - - if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) - break; - - if (avctx->hw_frames_ctx) { - AVHWFramesContext *hw_frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; - if (hw_frames_ctx->format != ret) { - av_log(avctx, AV_LOG_ERROR, "Format returned from get_buffer() " - "does not match the format of provided AVHWFramesContext\n"); - ret = AV_PIX_FMT_NONE; - break; - } - } - - if (!setup_hwaccel(avctx, ret, desc->name)) - break; - - /* Remove failed hwaccel from choices */ - for (n = 0; choices[n] != ret; n++) - av_assert0(choices[n] != AV_PIX_FMT_NONE); - - do - choices[n] = choices[n + 1]; - while (choices[n++] != AV_PIX_FMT_NONE); - } - - av_freep(&choices); - return ret; -} - int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options) { int ret = 0; @@ -1210,244 +720,6 @@ FF_ENABLE_DEPRECATION_WARNINGS goto end; } -static int apply_param_change(AVCodecContext *avctx, AVPacket *avpkt) -{ - int size = 0, ret; - const uint8_t *data; - uint32_t flags; - - data = av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, &size); - if (!data) - return 0; - - if (!(avctx->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE)) { - av_log(avctx, AV_LOG_ERROR, "This decoder does not support parameter " - "changes, but PARAM_CHANGE side data was sent to it.\n"); - ret = AVERROR(EINVAL); - goto fail2; - } - - if (size < 4) - goto fail; - - flags = bytestream_get_le32(&data); - size -= 4; - - if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT) { - if (size < 4) - goto fail; - avctx->channels = bytestream_get_le32(&data); - size -= 4; - } - if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) { - if (size < 8) - goto fail; - avctx->channel_layout = bytestream_get_le64(&data); - size -= 8; - } - if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) { - if (size < 4) - goto fail; - avctx->sample_rate = bytestream_get_le32(&data); - size -= 4; - } - if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) { - if (size < 8) - goto fail; - avctx->width = bytestream_get_le32(&data); - avctx->height = bytestream_get_le32(&data); - size -= 8; - ret = ff_set_dimensions(avctx, avctx->width, avctx->height); - if (ret < 0) - goto fail2; - } - - return 0; -fail: - av_log(avctx, AV_LOG_ERROR, "PARAM_CHANGE side data too small.\n"); - ret = AVERROR_INVALIDDATA; -fail2: - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n"); - if (avctx->err_recognition & AV_EF_EXPLODE) - return ret; - } - return 0; -} - -static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame) -{ - int ret; - - /* move the original frame to our backup */ - av_frame_unref(avci->to_free); - av_frame_move_ref(avci->to_free, frame); - - /* now copy everything except the AVBufferRefs back - * note that we make a COPY of the side data, so calling av_frame_free() on - * the caller's frame will work properly */ - ret = av_frame_copy_props(frame, avci->to_free); - if (ret < 0) - return ret; - - memcpy(frame->data, avci->to_free->data, sizeof(frame->data)); - memcpy(frame->linesize, avci->to_free->linesize, sizeof(frame->linesize)); - if (avci->to_free->extended_data != avci->to_free->data) { - int planes = av_get_channel_layout_nb_channels(avci->to_free->channel_layout); - int size = planes * sizeof(*frame->extended_data); - - if (!size) { - av_frame_unref(frame); - return AVERROR_BUG; - } - - frame->extended_data = av_malloc(size); - if (!frame->extended_data) { - av_frame_unref(frame); - return AVERROR(ENOMEM); - } - memcpy(frame->extended_data, avci->to_free->extended_data, - size); - } else - frame->extended_data = frame->data; - - frame->format = avci->to_free->format; - frame->width = avci->to_free->width; - frame->height = avci->to_free->height; - frame->channel_layout = avci->to_free->channel_layout; - frame->nb_samples = avci->to_free->nb_samples; - - return 0; -} - -int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, - int *got_picture_ptr, - AVPacket *avpkt) -{ - AVCodecInternal *avci = avctx->internal; - int ret; - - *got_picture_ptr = 0; - if ((avctx->coded_width || avctx->coded_height) && av_image_check_size(avctx->coded_width, avctx->coded_height, 0, avctx)) - return -1; - - if (!avctx->codec->decode) { - av_log(avctx, AV_LOG_ERROR, "This decoder requires using the avcodec_send_packet() API.\n"); - return AVERROR(ENOSYS); - } - - avctx->internal->pkt = avpkt; - ret = apply_param_change(avctx, avpkt); - if (ret < 0) - return ret; - - av_frame_unref(picture); - - if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size || - (avctx->active_thread_type & FF_THREAD_FRAME)) { - if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) - ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr, - avpkt); - else { - ret = avctx->codec->decode(avctx, picture, got_picture_ptr, - avpkt); - if (!(avctx->codec->caps_internal & FF_CODEC_CAP_SETS_PKT_DTS)) - picture->pkt_dts = avpkt->dts; - /* get_buffer is supposed to set frame parameters */ - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DR1)) { - picture->sample_aspect_ratio = avctx->sample_aspect_ratio; - picture->width = avctx->width; - picture->height = avctx->height; - picture->format = avctx->pix_fmt; - } - } - - emms_c(); //needed to avoid an emms_c() call before every return; - - if (*got_picture_ptr) { - if (!avctx->refcounted_frames) { - int err = unrefcount_frame(avci, picture); - if (err < 0) - return err; - } - - avctx->frame_number++; - } else - av_frame_unref(picture); - } else - ret = 0; - -#if FF_API_AVCTX_TIMEBASE - if (avctx->framerate.num > 0 && avctx->framerate.den > 0) - avctx->time_base = av_inv_q(avctx->framerate); -#endif - - return ret; -} - -int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, - AVFrame *frame, - int *got_frame_ptr, - AVPacket *avpkt) -{ - AVCodecInternal *avci = avctx->internal; - int ret = 0; - - *got_frame_ptr = 0; - - if (!avctx->codec->decode) { - av_log(avctx, AV_LOG_ERROR, "This decoder requires using the avcodec_send_packet() API.\n"); - return AVERROR(ENOSYS); - } - - avctx->internal->pkt = avpkt; - - if (!avpkt->data && avpkt->size) { - av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n"); - return AVERROR(EINVAL); - } - - ret = apply_param_change(avctx, avpkt); - if (ret < 0) - return ret; - - av_frame_unref(frame); - - if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size) { - ret = avctx->codec->decode(avctx, frame, got_frame_ptr, avpkt); - if (ret >= 0 && *got_frame_ptr) { - avctx->frame_number++; - frame->pkt_dts = avpkt->dts; - if (frame->format == AV_SAMPLE_FMT_NONE) - frame->format = avctx->sample_fmt; - - if (!avctx->refcounted_frames) { - int err = unrefcount_frame(avci, frame); - if (err < 0) - return err; - } - } else - av_frame_unref(frame); - } - - - return ret; -} - -int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, - int *got_sub_ptr, - AVPacket *avpkt) -{ - int ret; - - avctx->internal->pkt = avpkt; - *got_sub_ptr = 0; - ret = avctx->codec->decode(avctx, sub, got_sub_ptr, avpkt); - if (*got_sub_ptr) - avctx->frame_number++; - return ret; -} - void avsubtitle_free(AVSubtitle *sub) { int i; @@ -1467,150 +739,6 @@ void avsubtitle_free(AVSubtitle *sub) memset(sub, 0, sizeof(AVSubtitle)); } -static int do_decode(AVCodecContext *avctx, AVPacket *pkt) -{ - int got_frame; - int ret; - - av_assert0(!avctx->internal->buffer_frame->buf[0]); - - if (!pkt) - pkt = avctx->internal->buffer_pkt; - - // This is the lesser evil. The field is for compatibility with legacy users - // of the legacy API, and users using the new API should not be forced to - // even know about this field. - avctx->refcounted_frames = 1; - - // Some codecs (at least wma lossless) will crash when feeding drain packets - // after EOF was signaled. - if (avctx->internal->draining_done) - return AVERROR_EOF; - - if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { - ret = avcodec_decode_video2(avctx, avctx->internal->buffer_frame, - &got_frame, pkt); - if (ret >= 0) - ret = pkt->size; - } else if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) { - ret = avcodec_decode_audio4(avctx, avctx->internal->buffer_frame, - &got_frame, pkt); - } else { - ret = AVERROR(EINVAL); - } - - if (ret < 0) - return ret; - - if (avctx->internal->draining && !got_frame) - avctx->internal->draining_done = 1; - - if (ret >= pkt->size) { - av_packet_unref(avctx->internal->buffer_pkt); - } else { - int consumed = ret; - - if (pkt != avctx->internal->buffer_pkt) { - av_packet_unref(avctx->internal->buffer_pkt); - if ((ret = av_packet_ref(avctx->internal->buffer_pkt, pkt)) < 0) - return ret; - } - - avctx->internal->buffer_pkt->data += consumed; - avctx->internal->buffer_pkt->size -= consumed; - avctx->internal->buffer_pkt->pts = AV_NOPTS_VALUE; - avctx->internal->buffer_pkt->dts = AV_NOPTS_VALUE; - } - - if (got_frame) - av_assert0(avctx->internal->buffer_frame->buf[0]); - - return 0; -} - -int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt) -{ - int ret; - - if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec)) - return AVERROR(EINVAL); - - if (avctx->internal->draining) - return AVERROR_EOF; - - if (!avpkt || !avpkt->size) { - avctx->internal->draining = 1; - avpkt = NULL; - - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - return 0; - } - - if (avctx->codec->send_packet) { - if (avpkt) { - ret = apply_param_change(avctx, (AVPacket *)avpkt); - if (ret < 0) - return ret; - } - return avctx->codec->send_packet(avctx, avpkt); - } - - // Emulation via old API. Assume avpkt is likely not refcounted, while - // decoder output is always refcounted, and avoid copying. - - if (avctx->internal->buffer_pkt->size || avctx->internal->buffer_frame->buf[0]) - return AVERROR(EAGAIN); - - // The goal is decoding the first frame of the packet without using memcpy, - // because the common case is having only 1 frame per packet (especially - // with video, but audio too). In other cases, it can't be avoided, unless - // the user is feeding refcounted packets. - return do_decode(avctx, (AVPacket *)avpkt); -} - -int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame) -{ - int ret; - - av_frame_unref(frame); - - if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec)) - return AVERROR(EINVAL); - - if (avctx->codec->receive_frame) { - if (avctx->internal->draining && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - return AVERROR_EOF; - return avctx->codec->receive_frame(avctx, frame); - } - - // Emulation via old API. - - if (!avctx->internal->buffer_frame->buf[0]) { - if (!avctx->internal->buffer_pkt->size && !avctx->internal->draining) - return AVERROR(EAGAIN); - - while (1) { - if ((ret = do_decode(avctx, avctx->internal->buffer_pkt)) < 0) { - av_packet_unref(avctx->internal->buffer_pkt); - return ret; - } - // Some audio decoders may consume partial data without returning - // a frame (fate-wmapro-2ch). There is no way to make the caller - // call avcodec_receive_frame() again without returning a frame, - // so try to decode more in these cases. - if (avctx->internal->buffer_frame->buf[0] || - !avctx->internal->buffer_pkt->size) - break; - } - } - - if (!avctx->internal->buffer_frame->buf[0]) - return avctx->internal->draining ? AVERROR_EOF : AVERROR(EAGAIN); - - av_frame_move_ref(frame, avctx->internal->buffer_frame); - return 0; -} - av_cold int avcodec_close(AVCodecContext *avctx) { int i; @@ -1953,23 +1081,6 @@ const char *avcodec_license(void) return LICENSE_PREFIX LIBAV_LICENSE + sizeof(LICENSE_PREFIX) - 1; } -void avcodec_flush_buffers(AVCodecContext *avctx) -{ - avctx->internal->draining = 0; - avctx->internal->draining_done = 0; - av_frame_unref(avctx->internal->buffer_frame); - av_packet_unref(avctx->internal->buffer_pkt); - avctx->internal->buffer_pkt_valid = 0; - - if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) - ff_thread_flush(avctx); - else if (avctx->codec->flush) - avctx->codec->flush(avctx); - - if (!avctx->refcounted_frames) - av_frame_unref(avctx->internal->to_free); -} - int av_get_exact_bits_per_sample(enum AVCodecID codec_id) { switch (codec_id) { From 239d02eff3ffe9f7d40caa21dde50fb4a0e94c24 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 24 Nov 2016 12:46:30 +0100 Subject: [PATCH 0609/3374] avisynth: Cast to the right type when loading avisynth library functions Fixes a number of related warnings. --- libavformat/avisynth.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c index fd5f323e136f4..d3b3ec478ef8a 100644 --- a/libavformat/avisynth.c +++ b/libavformat/avisynth.c @@ -127,7 +127,8 @@ static av_cold int avisynth_load_library(void) return AVERROR_UNKNOWN; #define LOAD_AVS_FUNC(name, continue_on_fail) \ - avs_library.name = GetProcAddress(avs_library.library, #name); \ + avs_library.name = (name ## _func) \ + GetProcAddress(avs_library.library, #name); \ if (!continue_on_fail && !avs_library.name) \ goto fail; From 3ee5f25d37315b27f0e2d47aa69fc445545ee2e3 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 24 Nov 2016 12:46:31 +0100 Subject: [PATCH 0610/3374] dxva2: Adjust printf length modifiers where appropriate --- libavcodec/dxva2.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c index 9fedd03df839e..60639935a8335 100644 --- a/libavcodec/dxva2.c +++ b/libavcodec/dxva2.c @@ -83,7 +83,7 @@ int ff_dxva2_commit_buffer(AVCodecContext *avctx, &dxva_data, &dxva_size); #endif if (FAILED(hr)) { - av_log(avctx, AV_LOG_ERROR, "Failed to get a buffer for %u: 0x%lx\n", + av_log(avctx, AV_LOG_ERROR, "Failed to get a buffer for %u: 0x%x\n", type, hr); return -1; } @@ -125,7 +125,7 @@ int ff_dxva2_commit_buffer(AVCodecContext *avctx, #endif if (FAILED(hr)) { av_log(avctx, AV_LOG_ERROR, - "Failed to release buffer type %u: 0x%lx\n", + "Failed to release buffer type %u: 0x%x\n", type, hr); result = -1; } @@ -179,7 +179,7 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame, } while(1); if (FAILED(hr)) { - av_log(avctx, AV_LOG_ERROR, "Failed to begin frame: 0x%lx\n", hr); + av_log(avctx, AV_LOG_ERROR, "Failed to begin frame: 0x%x\n", hr); #if CONFIG_D3D11VA if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) if (D3D11VA_CONTEXT(ctx)->context_mutex != INVALID_HANDLE_VALUE) @@ -278,7 +278,7 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame, } #endif if (FAILED(hr)) { - av_log(avctx, AV_LOG_ERROR, "Failed to execute: 0x%lx\n", hr); + av_log(avctx, AV_LOG_ERROR, "Failed to execute: 0x%x\n", hr); result = -1; } @@ -295,7 +295,7 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame, hr = IDirectXVideoDecoder_EndFrame(DXVA2_CONTEXT(ctx)->decoder, NULL); #endif if (FAILED(hr)) { - av_log(avctx, AV_LOG_ERROR, "Failed to end frame: 0x%lx\n", hr); + av_log(avctx, AV_LOG_ERROR, "Failed to end frame: 0x%x\n", hr); result = -1; } From 212c6a1d70df011b6f2a2aa02f7677503287bd00 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 11 May 2016 08:59:17 +0200 Subject: [PATCH 0611/3374] mjpegdec: Check return values of functions that may fail --- libavcodec/mjpegdec.c | 70 +++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index a4a6c63411d82..f6e903853901a 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -68,25 +68,42 @@ static int build_vlc(VLC *vlc, const uint8_t *bits_table, huff_code, 2, 2, huff_sym, 2, 2, use_static); } -static void build_basic_mjpeg_vlc(MJpegDecodeContext *s) +static int build_basic_mjpeg_vlc(MJpegDecodeContext *s) { - build_vlc(&s->vlcs[0][0], avpriv_mjpeg_bits_dc_luminance, - avpriv_mjpeg_val_dc, 12, 0, 0); - build_vlc(&s->vlcs[0][1], avpriv_mjpeg_bits_dc_chrominance, - avpriv_mjpeg_val_dc, 12, 0, 0); - build_vlc(&s->vlcs[1][0], avpriv_mjpeg_bits_ac_luminance, - avpriv_mjpeg_val_ac_luminance, 251, 0, 1); - build_vlc(&s->vlcs[1][1], avpriv_mjpeg_bits_ac_chrominance, - avpriv_mjpeg_val_ac_chrominance, 251, 0, 1); - build_vlc(&s->vlcs[2][0], avpriv_mjpeg_bits_ac_luminance, - avpriv_mjpeg_val_ac_luminance, 251, 0, 0); - build_vlc(&s->vlcs[2][1], avpriv_mjpeg_bits_ac_chrominance, - avpriv_mjpeg_val_ac_chrominance, 251, 0, 0); + int ret; + + if ((ret = build_vlc(&s->vlcs[0][0], avpriv_mjpeg_bits_dc_luminance, + avpriv_mjpeg_val_dc, 12, 0, 0)) < 0) + return ret; + + if ((ret = build_vlc(&s->vlcs[0][1], avpriv_mjpeg_bits_dc_chrominance, + avpriv_mjpeg_val_dc, 12, 0, 0)) < 0) + return ret; + + if ((ret = build_vlc(&s->vlcs[1][0], avpriv_mjpeg_bits_ac_luminance, + avpriv_mjpeg_val_ac_luminance, 251, 0, 1)) < 0) + return ret; + + if ((ret = build_vlc(&s->vlcs[1][1], avpriv_mjpeg_bits_ac_chrominance, + avpriv_mjpeg_val_ac_chrominance, 251, 0, 1)) < 0) + return ret; + + if ((ret = build_vlc(&s->vlcs[2][0], avpriv_mjpeg_bits_ac_luminance, + avpriv_mjpeg_val_ac_luminance, 251, 0, 0)) < 0) + return ret; + + if ((ret = build_vlc(&s->vlcs[2][1], avpriv_mjpeg_bits_ac_chrominance, + avpriv_mjpeg_val_ac_chrominance, 251, 0, 0)) < 0) + return ret; + + + return 0; } av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx) { MJpegDecodeContext *s = avctx->priv_data; + int ret; if (!s->picture_ptr) { s->picture = av_frame_alloc(); @@ -109,12 +126,13 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx) avctx->chroma_sample_location = AVCHROMA_LOC_CENTER; avctx->colorspace = AVCOL_SPC_BT470BG; - build_basic_mjpeg_vlc(s); + if ((ret = build_basic_mjpeg_vlc(s)) < 0) + return ret; if (s->extern_huff) { - int ret; av_log(avctx, AV_LOG_INFO, "mjpeg: using external huffman table\n"); - init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size * 8); + if ((ret = init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size * 8)) < 0) + return ret; if ((ret = ff_mjpeg_decode_dht(s))) { av_log(avctx, AV_LOG_ERROR, "mjpeg: error using external huffman table\n"); @@ -248,7 +266,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) height= s->height; av_log(s->avctx, AV_LOG_DEBUG, "sof0: picture: %dx%d\n", width, height); - if (av_image_check_size(width, height, 0, s->avctx)) + if (av_image_check_size(width, height, 0, s->avctx) < 0) return AVERROR_INVALIDDATA; nb_components = get_bits(&s->gb, 8); @@ -686,6 +704,9 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int predictor, av_fast_malloc(&s->ljpeg_buffer, &s->ljpeg_buffer_size, (unsigned)s->mb_width * 4 * sizeof(s->ljpeg_buffer[0][0])); + if (!s->ljpeg_buffer) + return AVERROR(ENOMEM); + buffer = s->ljpeg_buffer; for (i = 0; i < 3; i++) @@ -1502,14 +1523,15 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, av_log(avctx, AV_LOG_DEBUG, "startcode: %X\n", start_code); /* process markers */ - if (start_code >= 0xd0 && start_code <= 0xd7) + if (start_code >= 0xd0 && start_code <= 0xd7) { av_log(avctx, AV_LOG_DEBUG, "restart marker: %d\n", start_code & 0x0f); /* APP fields */ - else if (start_code >= APP0 && start_code <= APP15) - mjpeg_decode_app(s); + } else if (start_code >= APP0 && start_code <= APP15) { + if ((ret = mjpeg_decode_app(s)) < 0) + return ret; /* Comment */ - else if (start_code == COM) { + } else if (start_code == COM) { ret = mjpeg_decode_com(s); if (ret < 0) return ret; @@ -1528,7 +1550,8 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, /* nothing to do on SOI */ break; case DQT: - ff_mjpeg_decode_dqt(s); + if ((ret = ff_mjpeg_decode_dqt(s)) < 0) + return ret; break; case DHT: if ((ret = ff_mjpeg_decode_dht(s)) < 0) { @@ -1623,7 +1646,8 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, goto eoi_parser; break; case DRI: - mjpeg_decode_dri(s); + if ((ret = mjpeg_decode_dri(s)) < 0) + return ret; break; case SOF5: case SOF6: From d4f2a681cb6d4e913f1c879ad376313255d6cf4c Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 10 Nov 2016 11:20:29 +0100 Subject: [PATCH 0612/3374] configure: MMAL-related decoders should depend on, not select, mmal --- configure | 3 --- 1 file changed, 3 deletions(-) diff --git a/configure b/configure index d0bec323c1df5..30d1c7ed5781e 100755 --- a/configure +++ b/configure @@ -2136,7 +2136,6 @@ h264_d3d11va_hwaccel_select="h264_decoder" h264_dxva2_hwaccel_deps="dxva2" h264_dxva2_hwaccel_select="h264_decoder" h264_mmal_decoder_deps="mmal" -h264_mmal_decoder_select="mmal" h264_mmal_hwaccel_deps="mmal" h264_omx_encoder_deps="omx" h264_qsv_hwaccel_deps="libmfx" @@ -2164,7 +2163,6 @@ mpeg2_d3d11va_hwaccel_select="mpeg2video_decoder" mpeg2_dxva2_hwaccel_deps="dxva2" mpeg2_dxva2_hwaccel_select="mpeg2video_decoder" mpeg2_mmal_decoder_deps="mmal" -mpeg2_mmal_decoder_select="mmal" mpeg2_mmal_hwaccel_deps="mmal" mpeg2_qsv_hwaccel_deps="libmfx" mpeg2_vaapi_hwaccel_deps="vaapi" @@ -2181,7 +2179,6 @@ vc1_d3d11va_hwaccel_select="vc1_decoder" vc1_dxva2_hwaccel_deps="dxva2" vc1_dxva2_hwaccel_select="vc1_decoder" vc1_mmal_decoder_deps="mmal" -vc1_mmal_decoder_select="mmal" vc1_mmal_hwaccel_deps="mmal" vc1_qsv_hwaccel_deps="libmfx" vc1_vaapi_hwaccel_deps="vaapi" From 9254344e11f9b016088ec6250724f74377f5d7a0 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 16 Nov 2016 18:38:52 +0100 Subject: [PATCH 0613/3374] configure: Move hardware-accelerated codec deps out of hwaccel section --- configure | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/configure b/configure index 30d1c7ed5781e..c01996aebe00f 100755 --- a/configure +++ b/configure @@ -2135,9 +2135,7 @@ h264_d3d11va_hwaccel_deps="d3d11va" h264_d3d11va_hwaccel_select="h264_decoder" h264_dxva2_hwaccel_deps="dxva2" h264_dxva2_hwaccel_select="h264_decoder" -h264_mmal_decoder_deps="mmal" h264_mmal_hwaccel_deps="mmal" -h264_omx_encoder_deps="omx" h264_qsv_hwaccel_deps="libmfx" h264_vaapi_hwaccel_deps="vaapi" h264_vaapi_hwaccel_select="h264_decoder" @@ -2154,22 +2152,18 @@ hevc_dxva2_hwaccel_select="hevc_decoder" hevc_qsv_hwaccel_deps="libmfx" hevc_vdpau_hwaccel_deps="vdpau VdpPictureInfoHEVC" hevc_vdpau_hwaccel_select="hevc_decoder" -mjpeg_vaapi_encoder_deps="VAEncPictureParameterBufferJPEG" -mjpeg_vaapi_encoder_select="vaapi_encode jpegtables" mpeg1_vdpau_hwaccel_deps="vdpau" mpeg1_vdpau_hwaccel_select="mpeg1video_decoder" mpeg2_d3d11va_hwaccel_deps="d3d11va" mpeg2_d3d11va_hwaccel_select="mpeg2video_decoder" mpeg2_dxva2_hwaccel_deps="dxva2" mpeg2_dxva2_hwaccel_select="mpeg2video_decoder" -mpeg2_mmal_decoder_deps="mmal" mpeg2_mmal_hwaccel_deps="mmal" mpeg2_qsv_hwaccel_deps="libmfx" mpeg2_vaapi_hwaccel_deps="vaapi" mpeg2_vaapi_hwaccel_select="mpeg2video_decoder" mpeg2_vdpau_hwaccel_deps="vdpau" mpeg2_vdpau_hwaccel_select="mpeg2video_decoder" -mpeg4_omx_encoder_deps="omx" mpeg4_vaapi_hwaccel_deps="vaapi" mpeg4_vaapi_hwaccel_select="mpeg4_decoder" mpeg4_vdpau_hwaccel_deps="vdpau" @@ -2178,7 +2172,6 @@ vc1_d3d11va_hwaccel_deps="d3d11va" vc1_d3d11va_hwaccel_select="vc1_decoder" vc1_dxva2_hwaccel_deps="dxva2" vc1_dxva2_hwaccel_select="vc1_decoder" -vc1_mmal_decoder_deps="mmal" vc1_mmal_hwaccel_deps="mmal" vc1_qsv_hwaccel_deps="libmfx" vc1_vaapi_hwaccel_deps="vaapi" @@ -2205,14 +2198,15 @@ vaapi_encode_deps="vaapi" hwupload_cuda_filter_deps="cuda" scale_npp_filter_deps="cuda libnpp" +h264_mmal_decoder_deps="mmal" h264_nvenc_encoder_deps="nvenc" +h264_omx_encoder_deps="omx" h264_qsv_decoder_deps="libmfx" h264_qsv_decoder_select="h264_mp4toannexb_bsf h264_parser qsvdec h264_qsv_hwaccel" h264_qsv_encoder_deps="libmfx" h264_qsv_encoder_select="qsvenc" h264_vaapi_encoder_deps="VAEncPictureParameterBufferH264" h264_vaapi_encoder_select="vaapi_encode golomb" - hevc_nvenc_encoder_deps="nvenc" hevc_qsv_decoder_deps="libmfx" hevc_qsv_encoder_deps="libmfx" @@ -2220,10 +2214,15 @@ hevc_qsv_decoder_select="hevc_mp4toannexb_bsf hevc_parser hevc_qsv_hwaccel qsvde hevc_qsv_encoder_select="qsvenc" hevc_vaapi_encoder_deps="VAEncPictureParameterBufferHEVC" hevc_vaapi_encoder_select="vaapi_encode golomb" +mjpeg_vaapi_encoder_deps="VAEncPictureParameterBufferJPEG" +mjpeg_vaapi_encoder_select="vaapi_encode jpegtables" +mpeg2_mmal_decoder_deps="mmal" mpeg2_qsv_decoder_deps="libmfx" mpeg2_qsv_decoder_select="qsvdec mpeg2_qsv_hwaccel mpegvideo_parser" mpeg2_qsv_encoder_deps="libmfx" mpeg2_qsv_encoder_select="qsvenc" +mpeg4_omx_encoder_deps="omx" +vc1_mmal_decoder_deps="mmal" vc1_qsv_decoder_deps="libmfx" vc1_qsv_decoder_select="qsvdec vc1_qsv_hwaccel vc1_parser" vp8_qsv_decoder_deps="libmfx" From 8b56dbe7435d8cfe3964f447fc45fe98db5d9042 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 10 Nov 2016 00:07:06 +0100 Subject: [PATCH 0614/3374] configure: Do not add newlines in filter()/filter_out() functions --- configure | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index c01996aebe00f..e5a9b969cb7ea 100755 --- a/configure +++ b/configure @@ -429,7 +429,7 @@ filter(){ pat=$1 shift for v; do - eval "case $v in $pat) echo $v ;; esac" + eval "case $v in $pat) printf '%s ' $v ;; esac" done } @@ -437,7 +437,7 @@ filter_out(){ pat=$1 shift for v; do - eval "case $v in $pat) ;; *) echo $v ;; esac" + eval "case $v in $pat) ;; *) printf '%s ' $v ;; esac" done } From c21d78a903da378af48c9e5f971fe989592ddb65 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 23 Nov 2016 12:15:00 +0100 Subject: [PATCH 0615/3374] configure: Integrate X11 checks into vaapi/vdpau checks --- configure | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/configure b/configure index e5a9b969cb7ea..71141c2d30831 100755 --- a/configure +++ b/configure @@ -1680,7 +1680,6 @@ HAVE_LIST=" vaapi_drm vaapi_x11 vdpau_x11 - xlib " # options emitted with CONFIG_ prefix but not available on the command line @@ -4810,18 +4809,16 @@ enabled vaapi && check_lib "va/va.h va/va_drm.h" vaGetDisplayDRM -lva -lva-drm && enable vaapi_drm +enabled vaapi && + check_lib "va/va.h va/va_x11.h" vaGetDisplay -lva -lva-x11 -lX11 && + enable vaapi_x11 + enabled vdpau && check_cpp_condition vdpau/vdpau.h "defined VDP_DECODER_PROFILE_MPEG4_PART2_ASP" || disable vdpau -enabled_any vaapi vdpau && check_lib X11/Xlib.h XOpenDisplay -lX11 && enable xlib - -enabled vaapi && enabled xlib && - check_lib "va/va.h va/va_x11.h" vaGetDisplay -lva -lva-x11 && - enable vaapi_x11 - -enabled vdpau && enabled xlib && - check_lib "vdpau/vdpau.h vdpau/vdpau_x11.h" vdp_device_create_x11 -lvdpau && +enabled vdpau && + check_lib "vdpau/vdpau.h vdpau/vdpau_x11.h" vdp_device_create_x11 -lvdpau -lX11 && enable vdpau_x11 enabled debug && add_cflags -g"$debuglevel" && add_asflags -g"$debuglevel" From 0983f9117f31521643162cb85380672495a9de1b Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 3 Jan 2016 22:45:19 +0100 Subject: [PATCH 0616/3374] metasound: Drop unused tables --- libavcodec/metasound_data.c | 183 ------------------------------------ 1 file changed, 183 deletions(-) diff --git a/libavcodec/metasound_data.c b/libavcodec/metasound_data.c index 8aa53e556cbe7..b399b750f2c2c 100644 --- a/libavcodec/metasound_data.c +++ b/libavcodec/metasound_data.c @@ -12739,185 +12739,6 @@ static const float lsp16[] = { -0.0429, -0.0615, -0.0893, -0.0618, -0.0384, -0.0134, -0.0232, -0.0238, }; -static const float lsp16s[] = { - 0.1813, 0.3911, 0.6301, 0.8012, 1.0057, 1.2041, 1.4271, 1.6943, - 1.9402, 2.1733, 2.3521, 2.4989, 2.5839, 2.6846, 2.7634, 2.8950, - 0.1311, 0.3183, 0.4659, 0.5601, 0.6658, 0.7828, 1.0065, 1.2717, - 1.5185, 1.7339, 1.9530, 2.2189, 2.3739, 2.4991, 2.6984, 2.9256, - 0.1627, 0.4519, 0.6323, 0.7012, 0.7848, 0.9801, 1.1810, 1.3222, - 1.5413, 1.8129, 1.9338, 2.0809, 2.3180, 2.5189, 2.7066, 2.9514, - 0.1475, 0.2447, 0.4240, 0.5669, 0.7872, 0.9838, 1.1823, 1.3814, - 1.5358, 1.6820, 1.8794, 2.1419, 2.4132, 2.6112, 2.7911, 2.9511, - 0.1224, 0.2876, 0.5013, 0.6985, 0.8902, 1.0901, 1.2835, 1.4768, - 1.6596, 1.8538, 2.0467, 2.2304, 2.4124, 2.5942, 2.7729, 2.9531, - 0.1741, 0.3034, 0.4677, 0.5879, 0.7258, 0.9648, 1.1417, 1.3220, - 1.5081, 1.7151, 1.9212, 2.1286, 2.3208, 2.4938, 2.6765, 2.8891, - 0.1657, 0.3174, 0.4907, 0.6559, 0.8295, 1.0254, 1.2071, 1.3880, - 1.5737, 1.7845, 1.9027, 2.1139, 2.3323, 2.5157, 2.7323, 2.9015, - 0.1592, 0.2758, 0.4417, 0.6315, 0.8257, 0.9873, 1.1277, 1.2830, - 1.4337, 1.6315, 1.8899, 2.1356, 2.3572, 2.5632, 2.7468, 2.9420, - 0.1524, 0.4325, 0.5931, 0.7036, 0.7696, 0.8923, 1.1739, 1.4773, - 1.6609, 1.7911, 1.9666, 2.1972, 2.3754, 2.5045, 2.6613, 2.8882, - 0.2130, 0.3013, 0.3721, 0.4257, 0.5079, 0.7015, 0.9815, 1.2554, - 1.4648, 1.6966, 1.9138, 2.1075, 2.3318, 2.5292, 2.7453, 2.9347, - 0.1142, 0.3748, 0.6205, 0.7642, 0.8121, 0.9022, 0.9843, 1.1558, - 1.4467, 1.7422, 1.9574, 2.1302, 2.3812, 2.5898, 2.7720, 2.9583, - 0.1255, 0.2339, 0.3570, 0.5323, 0.7458, 1.0003, 1.1729, 1.3567, - 1.5217, 1.6977, 1.8924, 2.0942, 2.3145, 2.5408, 2.7553, 2.9337, - 0.1316, 0.2289, 0.4327, 0.6663, 0.8509, 0.9994, 1.1697, 1.3804, - 1.5609, 1.6903, 1.8572, 2.1019, 2.3687, 2.5789, 2.7715, 2.9472, - 0.1502, 0.2546, 0.3883, 0.5333, 0.6976, 0.9163, 1.1071, 1.3364, - 1.5420, 1.7525, 1.8948, 2.0839, 2.2819, 2.4651, 2.6875, 2.8987, - 0.1593, 0.3014, 0.4573, 0.6354, 0.8157, 0.9805, 1.1783, 1.3747, - 1.5678, 1.7326, 1.9286, 2.1340, 2.3253, 2.5280, 2.7180, 2.9298, - 0.1811, 0.3167, 0.4655, 0.6507, 0.8198, 1.0075, 1.1892, 1.3743, - 1.5227, 1.7090, 1.8849, 2.0743, 2.2750, 2.4830, 2.6896, 2.8953, - 0.1846, 0.3577, 0.5315, 0.7290, 0.9176, 1.1016, 1.2654, 1.4525, - 1.6315, 1.8268, 2.0238, 2.1934, 2.3868, 2.5753, 2.7682, 2.9469, - 0.0876, 0.1439, 0.2048, 0.3654, 0.6281, 0.8853, 1.0907, 1.2992, - 1.5227, 1.7373, 1.9395, 2.1419, 2.3488, 2.5486, 2.7466, 2.9348, - 0.1391, 0.4170, 0.6561, 0.7953, 0.8734, 0.9986, 1.1870, 1.4520, - 1.6042, 1.7910, 2.0135, 2.1870, 2.3358, 2.5066, 2.7409, 2.9955, - 0.0804, 0.1355, 0.2599, 0.4998, 0.7408, 0.9474, 1.1276, 1.3428, - 1.5556, 1.7712, 1.9699, 2.1535, 2.3605, 2.5548, 2.7489, 2.9325, - 0.1304, 0.3087, 0.4979, 0.6584, 0.8414, 1.0329, 1.2244, 1.4189, - 1.6118, 1.8200, 1.9985, 2.1893, 2.3915, 2.5794, 2.7647, 2.9344, - 0.1895, 0.2849, 0.3705, 0.4126, 0.6265, 0.9207, 1.1774, 1.3762, - 1.5757, 1.7728, 1.9568, 2.1662, 2.3615, 2.5575, 2.7561, 2.9416, - 0.1800, 0.3078, 0.4805, 0.6796, 0.8503, 1.0046, 1.1703, 1.3269, - 1.4862, 1.6502, 1.8454, 2.0873, 2.3175, 2.5356, 2.7516, 2.9469, - 0.1950, 0.3233, 0.4568, 0.5940, 0.7589, 0.9978, 1.1701, 1.3383, - 1.5017, 1.6565, 1.8243, 2.0605, 2.2938, 2.5147, 2.7419, 2.9396, - 0.2531, 0.4391, 0.5790, 0.7170, 0.8998, 1.1430, 1.3577, 1.5326, - 1.6328, 1.7627, 1.9726, 2.1762, 2.3563, 2.5478, 2.7385, 2.9067, - 0.1805, 0.2788, 0.3591, 0.3881, 0.5441, 0.8055, 1.0766, 1.3165, - 1.5316, 1.7508, 1.9477, 2.1374, 2.3438, 2.5484, 2.7501, 2.9410, - 0.2044, 0.3671, 0.5396, 0.7042, 0.8582, 0.9831, 1.1261, 1.3194, - 1.4769, 1.6979, 1.8717, 2.0463, 2.2620, 2.4739, 2.7054, 2.9208, - 0.1048, 0.2175, 0.4206, 0.5923, 0.7483, 0.9400, 1.1356, 1.3799, - 1.5958, 1.7320, 1.8984, 2.1296, 2.3594, 2.5492, 2.7387, 2.9305, - 0.0842, 0.1729, 0.3951, 0.6447, 0.8688, 1.0605, 1.2472, 1.4330, - 1.6232, 1.8144, 2.0216, 2.1915, 2.3878, 2.5763, 2.7685, 2.9464, - 0.1461, 0.2593, 0.4105, 0.5677, 0.7328, 0.8919, 1.0484, 1.2302, - 1.4386, 1.6635, 1.8873, 2.1024, 2.3116, 2.5268, 2.7273, 2.9269, - 0.1503, 0.3108, 0.4756, 0.6731, 0.8600, 1.0233, 1.2115, 1.3971, - 1.5915, 1.7892, 1.9517, 2.1603, 2.3487, 2.5460, 2.7308, 2.8998, - 0.2163, 0.3669, 0.5125, 0.6709, 0.8143, 0.9930, 1.2095, 1.4205, - 1.6176, 1.7112, 1.8398, 2.0896, 2.3513, 2.5290, 2.6667, 2.8960, - 0.2133, 0.4382, 0.6287, 0.8702, 1.1088, 1.3749, 1.6062, 1.7446, - 1.8333, 1.9122, 1.9614, 2.0669, 2.1789, 2.3449, 2.6038, 2.8849, - 0.1598, 0.2719, 0.3877, 0.4815, 0.5926, 0.7795, 1.0449, 1.3045, - 1.5210, 1.7391, 1.9462, 2.1397, 2.3553, 2.5458, 2.7540, 2.9392, - 0.2918, 0.5607, 0.6801, 0.7404, 0.8285, 0.9431, 1.1579, 1.4080, - 1.6332, 1.8472, 1.9738, 2.0771, 2.2890, 2.5178, 2.7445, 2.9830, - 0.1664, 0.2842, 0.3965, 0.5463, 0.8162, 1.0346, 1.1849, 1.3446, - 1.5122, 1.7563, 1.9960, 2.2002, 2.3796, 2.5689, 2.7712, 2.9550, - 0.0911, 0.2397, 0.5052, 0.7868, 1.0299, 1.1311, 1.2244, 1.3333, - 1.4395, 1.6790, 1.9369, 2.1717, 2.3689, 2.5538, 2.7340, 2.9326, - 0.1647, 0.2931, 0.3836, 0.4978, 0.6255, 0.9243, 1.1339, 1.3001, - 1.5269, 1.8010, 1.9715, 2.1419, 2.3784, 2.5503, 2.6719, 2.8745, - 0.2440, 0.3802, 0.4756, 0.6613, 0.8627, 1.0292, 1.2291, 1.4060, - 1.5198, 1.7354, 1.9044, 2.1010, 2.3147, 2.4996, 2.7171, 2.9041, - 0.1590, 0.2876, 0.4572, 0.5996, 0.7713, 0.9490, 1.1205, 1.2815, - 1.4516, 1.6385, 1.8179, 2.0457, 2.2759, 2.4785, 2.6861, 2.9080, - 0.2297, 0.4309, 0.5712, 0.6717, 0.8138, 1.0463, 1.2492, 1.4560, - 1.6796, 1.8458, 1.9642, 2.1452, 2.3636, 2.5395, 2.7456, 2.9495, - 0.2975, 0.4678, 0.4996, 0.5809, 0.6279, 0.6884, 0.8606, 1.1386, - 1.4412, 1.6876, 1.8760, 2.0932, 2.3178, 2.5166, 2.7345, 2.9280, - 0.1278, 0.3737, 0.6004, 0.7069, 0.8147, 1.0180, 1.2581, 1.3812, - 1.4855, 1.7268, 1.9970, 2.1258, 2.2936, 2.5702, 2.7563, 2.8983, - 0.1314, 0.2508, 0.3999, 0.5680, 0.7424, 0.9367, 1.1286, 1.3175, - 1.5336, 1.7404, 1.9317, 2.1404, 2.3514, 2.5562, 2.7510, 2.9402, - 0.1043, 0.2367, 0.4293, 0.6376, 0.8160, 0.9836, 1.1779, 1.3850, - 1.5835, 1.7875, 1.9765, 2.1593, 2.3654, 2.5577, 2.7465, 2.9398, - 0.1529, 0.2515, 0.3454, 0.4374, 0.7011, 0.9015, 1.0744, 1.3532, - 1.5699, 1.7545, 2.0021, 2.1259, 2.2278, 2.4546, 2.7264, 2.9425, - 0.1429, 0.2808, 0.4395, 0.6334, 0.8069, 0.9705, 1.1520, 1.3250, - 1.5109, 1.7285, 1.9356, 2.1469, 2.3479, 2.5554, 2.7512, 2.9348, - 0.1625, 0.3022, 0.4756, 0.6315, 0.8032, 0.9924, 1.1596, 1.3204, - 1.4994, 1.6929, 1.8955, 2.1090, 2.3025, 2.5018, 2.6908, 2.8980, - 0.1692, 0.3427, 0.5228, 0.7756, 0.9688, 1.0950, 1.3056, 1.4360, - 1.5675, 1.8049, 1.9376, 2.1151, 2.3407, 2.5012, 2.7192, 2.9258, - 0.0474, 0.1251, 0.1939, 0.3841, 0.6501, 0.9231, 1.1153, 1.3240, - 1.5478, 1.7599, 1.9651, 2.1510, 2.3645, 2.5552, 2.7542, 2.9393, - 0.2196, 0.4656, 0.7492, 0.9922, 1.1678, 1.2489, 1.3112, 1.3657, - 1.4223, 1.5302, 1.7212, 1.9996, 2.2523, 2.4844, 2.7036, 2.9145, - 0.1128, 0.2368, 0.3704, 0.5476, 0.7723, 0.9968, 1.1930, 1.3992, - 1.6013, 1.7957, 1.9888, 2.1857, 2.3825, 2.5705, 2.7616, 2.9434, - 0.1341, 0.2768, 0.4510, 0.6359, 0.8332, 1.0335, 1.2004, 1.3952, - 1.5762, 1.7681, 1.9815, 2.1735, 2.3657, 2.5552, 2.7514, 2.9498, - 0.1247, 0.2559, 0.3516, 0.4726, 0.6861, 0.9483, 1.1852, 1.3858, - 1.5851, 1.7815, 1.9778, 2.1737, 2.3729, 2.5664, 2.7620, 2.9429, - 0.1988, 0.3320, 0.4777, 0.6737, 0.8425, 1.0265, 1.1694, 1.3655, - 1.5463, 1.7135, 1.9385, 2.1650, 2.3529, 2.5367, 2.7545, 2.9585, - 0.1376, 0.2620, 0.4273, 0.6169, 0.7755, 0.9441, 1.1169, 1.3157, - 1.5179, 1.7020, 1.8931, 2.1059, 2.3112, 2.5136, 2.7169, 2.9198, - 0.2112, 0.4385, 0.6091, 0.7618, 0.9553, 1.1543, 1.3445, 1.5396, - 1.7153, 1.9192, 2.1263, 2.3593, 2.5958, 2.8171, 2.9394, 3.0409, - 0.1347, 0.2099, 0.2646, 0.3453, 0.5266, 0.7869, 1.0513, 1.2795, - 1.4880, 1.7181, 1.9294, 2.1332, 2.3362, 2.5442, 2.7433, 2.9362, - 0.3141, 0.5935, 0.7517, 0.8313, 0.8568, 0.9570, 1.0250, 1.1275, - 1.3422, 1.6303, 1.8577, 2.0705, 2.2957, 2.5095, 2.7244, 2.9262, - 0.0962, 0.2116, 0.3961, 0.5641, 0.7122, 0.8883, 1.1023, 1.3481, - 1.5623, 1.7554, 1.9618, 2.1675, 2.3706, 2.5556, 2.7430, 2.9337, - 0.0898, 0.1510, 0.3060, 0.5820, 0.8221, 1.0388, 1.2261, 1.4289, - 1.6054, 1.8103, 1.9941, 2.1844, 2.3742, 2.5711, 2.7632, 2.9474, - 0.1326, 0.2316, 0.3761, 0.5177, 0.6782, 0.8761, 1.0952, 1.3175, - 1.5078, 1.7034, 1.9051, 2.1245, 2.3424, 2.5484, 2.7444, 2.9389, - 0.1740, 0.3293, 0.5174, 0.6824, 0.8394, 1.0372, 1.2046, 1.3723, - 1.5656, 1.7444, 1.9442, 2.1386, 2.3139, 2.4960, 2.7071, 2.9297, - 0.2304, 0.3775, 0.4865, 0.6182, 0.7842, 0.9208, 1.1151, 1.2843, - 1.4641, 1.6988, 1.9209, 2.1260, 2.3099, 2.5229, 2.7414, 2.9276, - 0.0094, 0.0261, -0.0037, 0.0041, -0.0092, -0.0044, -0.0232, -0.0073, - -0.0047, -0.0021, 0.0250, -0.0580, -0.0140, -0.0342, -0.0586, 0.0020, - 0.0449, 0.0155, -0.0523, -0.0279, 0.0299, -0.0183, -0.0736, -0.0639, - -0.0017, 0.0336, 0.0209, 0.0046, 0.0077, -0.0148, -0.0114, -0.0120, - 0.0115, -0.0050, 0.0445, 0.0048, 0.0188, -0.0137, -0.0080, 0.0239, - -0.0184, -0.0524, -0.0195, -0.0126, 0.0284, 0.0632, 0.0141, -0.0093, - -0.0096, 0.0196, 0.0230, 0.0379, 0.0308, 0.0237, -0.0224, -0.0600, - -0.0755, -0.1074, -0.0988, -0.0606, -0.1038, -0.1552, -0.1480, -0.0672, - 0.0504, 0.0676, 0.0336, -0.0042, 0.0729, 0.1013, 0.0868, 0.0846, - 0.0954, 0.0515, -0.0066, -0.0851, -0.0485, 0.0294, 0.0395, 0.0087, - 0.0078, 0.0446, 0.0881, 0.0672, -0.0384, -0.0025, 0.0415, 0.0353, - 0.0080, 0.0052, 0.0190, 0.0182, 0.0069, 0.0168, 0.0374, 0.0037, - -0.0292, -0.0429, 0.0302, 0.0681, -0.0233, -0.0238, -0.0003, -0.0043, - 0.0054, -0.0029, -0.0149, 0.0642, 0.0622, 0.0341, -0.0232, -0.0461, - -0.0082, -0.0469, -0.0618, -0.0326, -0.0452, -0.0649, -0.0597, -0.0398, - -0.0318, -0.0116, 0.0011, 0.0009, -0.0384, -0.0384, -0.0156, -0.0260, - -0.0007, 0.0473, 0.0111, -0.0358, -0.0484, -0.0204, -0.0029, -0.0090, - -0.0285, -0.0495, -0.0376, 0.0917, 0.1192, 0.1026, 0.0745, 0.0397, - 0.0463, 0.0253, 0.0025, 0.0465, 0.0100, 0.0488, 0.0416, 0.0223, - 0.0263, 0.0072, -0.0053, 0.0595, 0.0060, -0.0518, -0.0316, -0.0043, - -0.0133, -0.0233, -0.0075, -0.0251, 0.0277, -0.0067, -0.0136, -0.0004, - 0.0235, 0.0112, -0.0182, -0.0324, -0.0210, -0.0035, -0.0395, -0.0384, - 0.0005, -0.0150, -0.0356, 0.0127, -0.0033, -0.0034, 0.0205, 0.0747, - 0.1138, 0.1015, 0.0995, -0.0161, -0.0045, 0.0129, 0.0472, 0.0575, - 0.0222, 0.0091, 0.0037, -0.0471, 0.0371, 0.0132, 0.0208, 0.0247, - 0.0117, 0.0164, 0.0225, 0.0124, -0.0023, 0.0088, -0.0046, 0.0047, - -0.0393, 0.0018, 0.0148, 0.0020, 0.0044, 0.0165, 0.0229, -0.0208, - -0.0477, -0.0310, -0.0164, -0.0390, -0.0764, -0.0525, -0.0094, 0.0075, - -0.0102, -0.0045, -0.0504, -0.0709, 0.0822, 0.0710, 0.0426, 0.0014, - -0.0371, -0.0400, -0.0157, -0.0155, -0.0173, -0.0138, -0.0015, 0.0134, - -0.0418, -0.0682, -0.0256, 0.0050, 0.0360, 0.0354, 0.0074, -0.0396, - -0.0235, 0.0284, 0.0494, 0.0153, 0.0448, 0.0025, -0.0061, 0.0252, - 0.1000, 0.2260, 0.2158, 0.2116, 0.2198, 0.2055, 0.2110, 0.1873, - 0.1907, 0.2071, 0.2164, 0.2009, 0.2059, 0.2124, 0.2141, 0.2093, - 0.0875, 0.0981, 0.1177, 0.1071, 0.1033, 0.1248, 0.1048, 0.1238, - 0.1166, 0.1008, 0.1062, 0.0992, 0.0994, 0.1067, 0.0999, 0.1187, - 0.0750, 0.0794, 0.0828, 0.0854, 0.0859, 0.0801, 0.0891, 0.0933, - 0.0969, 0.0920, 0.0915, 0.0862, 0.0868, 0.0891, 0.0842, 0.0824, - 0.0625, 0.0930, 0.0815, 0.0853, 0.0898, 0.0828, 0.0822, 0.0910, - 0.0873, 0.0906, 0.0856, 0.0840, 0.0774, 0.0785, 0.0684, 0.0711, - 0.3319, 0.4219, 0.4588, 0.4090, 0.4092, 0.4014, 0.3548, 0.3353, - 0.3708, 0.3352, 0.3720, 0.3538, 0.4084, 0.4289, 0.4060, 0.4210, - 0.0588, 0.0209, -0.0082, -0.0115, -0.0343, -0.0621, -0.0541, -0.0346, - -0.0346, -0.0366, -0.0220, -0.0265, -0.0102, 0.0374, 0.0306, 0.0404, - 0.0306, 0.0090, -0.0054, 0.0333, 0.0047, 0.0238, 0.0141, 0.0165, - 0.0306, 0.0420, 0.0159, 0.0124, 0.0414, 0.0158, -0.0237, 0.0141, - 0.0765, 0.0057, -0.0260, -0.0426, -0.0395, -0.0126, -0.0579, -0.0417, - -0.0429, -0.0615, -0.0893, -0.0618, -0.0384, -0.0134, -0.0232, -0.0238, -}; - static const float lsp22[] = { 0.0664, 0.1875, 0.4300, 0.6730, 0.8793, 1.0640, 1.2563, 1.4433, 1.6394, 1.8176, 2.0029, 2.1921, 2.3796, 2.5671, 2.7595, 2.9536, @@ -15117,10 +14938,6 @@ static const uint16_t bark_tab_s16_128[] = { 2, 2, 2, 3, 3, 5, 7, 12, 25, 67 }; -static const uint16_t bark_tab_s16_64[] = { - 1, 1, 2, 2, 3, 6, 11, 38 -}; - static const uint16_t bark_tab_l16s_1024[] = { 9, 9, 8, 9, 10, 9, 10, 10, 10, 12, 11, 13, 13, 14, 16, 17, From 5c89022542ce8521d89ef58858342a7bc1c3cd0d Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 17 Nov 2016 20:41:33 +0100 Subject: [PATCH 0617/3374] hevc: Drop pointless av_unused attribute --- libavcodec/hevc_cabac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/hevc_cabac.c b/libavcodec/hevc_cabac.c index 0432330e820ac..23e05e25b517e 100644 --- a/libavcodec/hevc_cabac.c +++ b/libavcodec/hevc_cabac.c @@ -33,7 +33,7 @@ /** * number of bin by SyntaxElement. */ -av_unused static const int8_t num_bins_in_se[] = { +static const int8_t num_bins_in_se[] = { 1, // sao_merge_flag 1, // sao_type_idx 0, // sao_eo_class From e4382a4ab48138d43a19ea0da96f536a5e49b50c Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 11 Jan 2016 15:36:12 +0100 Subject: [PATCH 0618/3374] hevc: Eliminate pointless variable indirection --- libavcodec/hevcdec.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 5f1b5c3c4a8fd..9dd86c289e669 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -1167,9 +1167,7 @@ static void hls_residual_coding(HEVCContext *s, int x0, int y0, trans_coeff_level = 1 + coeff_abs_level_greater1_flag[n]; if (trans_coeff_level == ((m < 8) ? ((n == first_greater1_coeff_idx) ? 3 : 2) : 1)) { - int last_coeff_abs_level_remaining = ff_hevc_coeff_abs_level_remaining(s, trans_coeff_level, c_rice_param); - - trans_coeff_level += last_coeff_abs_level_remaining; + trans_coeff_level += ff_hevc_coeff_abs_level_remaining(s, trans_coeff_level, c_rice_param); if ((trans_coeff_level) > (3 * (1 << c_rice_param))) c_rice_param = FFMIN(c_rice_param + 1, 4); } From c4c5f5386c83bb8d66f8d67cd8533c8697f06d04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Fri, 22 Nov 2013 20:16:09 +0100 Subject: [PATCH 0619/3374] vp9dsp: add DC only versions for idct/idct. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit before: time ./avconv -v 0 -nostats -threads 1 -i sintel_vp9_500kbps.webm -f null - real 0m11.125s user 0m11.059s sys 0m0.050s time ./avconv -v 0 -nostats -threads 1 -i sintel_vp9_500kbps.webm -f null - real 0m10.944s user 0m10.819s sys 0m0.064s after: time ./avconv -v 0 -nostats -threads 1 -i sintel_vp9_500kbps.webm -f null - real 0m8.153s user 0m8.034s sys 0m0.050s time ./avconv -v 0 -nostats -threads 1 -i sintel_vp9_500kbps.webm -f null - real 0m8.038s user 0m7.980s sys 0m0.039s Signed-off-by: Martin Storsjö --- libavcodec/vp9dsp.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/libavcodec/vp9dsp.c b/libavcodec/vp9dsp.c index 73006fa1e6b0f..7f863943284b8 100644 --- a/libavcodec/vp9dsp.c +++ b/libavcodec/vp9dsp.c @@ -944,7 +944,7 @@ static av_cold void vp9dsp_intrapred_init(VP9DSPContext *dsp) #undef init_intra_pred } -#define itxfm_wrapper(type_a, type_b, sz, bits) \ +#define itxfm_wrapper(type_a, type_b, sz, bits, has_dconly) \ static void \ type_a ## _ ## type_b ## _ ## sz ## x ## sz ## _add_c(uint8_t *dst, \ ptrdiff_t stride, \ @@ -953,6 +953,22 @@ type_a ## _ ## type_b ## _ ## sz ## x ## sz ## _add_c(uint8_t *dst, \ { \ int i, j; \ int16_t tmp[sz * sz], out[sz]; \ + \ + if (has_dconly && eob == 1) { \ + const int t = (((block[0] * 11585 + (1 << 13)) >> 14) \ + * 11585 + (1 << 13)) >> 14; \ + block[0] = 0; \ + for (i = 0; i < sz; i++) { \ + for (j = 0; j < sz; j++) \ + dst[j * stride] = \ + av_clip_uint8(dst[j * stride] + \ + (bits ? (t + (1 << (bits - 1))) >> bits \ + : t)); \ + dst++; \ + } \ + return; \ + } \ + \ for (i = 0; i < sz; i++) \ type_a ## sz ## _1d(tmp + i * sz, block + i, sz, 0); \ memset(block, 0, sz * sz * sizeof(*block)); \ @@ -967,11 +983,11 @@ type_a ## _ ## type_b ## _ ## sz ## x ## sz ## _add_c(uint8_t *dst, \ } \ } -#define itxfm_wrap(sz, bits) \ - itxfm_wrapper(idct, idct, sz, bits) \ - itxfm_wrapper(iadst, idct, sz, bits) \ - itxfm_wrapper(idct, iadst, sz, bits) \ - itxfm_wrapper(iadst, iadst, sz, bits) +#define itxfm_wrap(sz, bits) \ + itxfm_wrapper(idct, idct, sz, bits, 1) \ + itxfm_wrapper(iadst, idct, sz, bits, 0) \ + itxfm_wrapper(idct, iadst, sz, bits, 0) \ + itxfm_wrapper(iadst, iadst, sz, bits, 0) #define IN(x) in[x * stride] @@ -1490,7 +1506,7 @@ static av_always_inline void idct32_1d(int16_t *out, const int16_t *in, out[31] = t0 - t31; } -itxfm_wrapper(idct, idct, 32, 6) +itxfm_wrapper(idct, idct, 32, 6, 1) static av_always_inline void iwht4_1d(int16_t *out, const int16_t *in, ptrdiff_t stride, int pass) @@ -1523,7 +1539,7 @@ static av_always_inline void iwht4_1d(int16_t *out, const int16_t *in, out[3] = t3; } -itxfm_wrapper(iwht, iwht, 4, 0) +itxfm_wrapper(iwht, iwht, 4, 0, 0) #undef IN #undef itxfm_wrapper From 3c87039a404c5659ae9bf7454a04e186532eb40b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 28 Nov 2016 11:05:18 +0200 Subject: [PATCH 0620/3374] arm: vp9itxfm: Only reload the idct coeffs for the iadst_idct combination MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids reloading them if they haven't been clobbered, if the first pass also was idct. This is similar to what was done in the aarch64 version. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index 01944bd38f7dc..2049241d088a0 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -814,7 +814,7 @@ A and r7, sp, #15 mov r3, #\i bl \txfm1\()16_1d_4x16_pass1_neon .endr -.ifc \txfm2,idct +.ifc \txfm1\()_\txfm2,iadst_idct movrel r12, idct_coeffs vld1.16 {q0-q1}, [r12,:128] .endif From 9c8bc74c2b40537b0997f646c87c008042d788c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 18 Nov 2016 11:37:16 +0200 Subject: [PATCH 0621/3374] arm: vp9itxfm: Skip empty slices in the first pass of idct_idct 16x16 and 32x32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. Previously all subpartitions except the eob=1 (DC) case ran with the same runtime: Cortex A7 A8 A9 A53 vp9_inv_dct_dct_16x16_sub16_add_neon: 3188.1 2435.4 2499.0 1969.0 vp9_inv_dct_dct_32x32_sub32_add_neon: 18531.7 16582.3 14207.6 12000.3 By skipping individual 4x16 or 4x32 pixel slices in the first pass, we reduce the runtime of these functions like this: vp9_inv_dct_dct_16x16_sub1_add_neon: 274.6 189.5 211.7 235.8 vp9_inv_dct_dct_16x16_sub2_add_neon: 2064.0 1534.8 1719.4 1248.7 vp9_inv_dct_dct_16x16_sub4_add_neon: 2135.0 1477.2 1736.3 1249.5 vp9_inv_dct_dct_16x16_sub8_add_neon: 2446.7 1828.7 1993.6 1494.7 vp9_inv_dct_dct_16x16_sub12_add_neon: 2832.4 2118.3 2266.5 1735.1 vp9_inv_dct_dct_16x16_sub16_add_neon: 3211.7 2475.3 2523.5 1983.1 vp9_inv_dct_dct_32x32_sub1_add_neon: 756.2 456.7 862.0 553.9 vp9_inv_dct_dct_32x32_sub2_add_neon: 10682.2 8190.4 8539.2 6762.5 vp9_inv_dct_dct_32x32_sub4_add_neon: 10813.5 8014.9 8518.3 6762.8 vp9_inv_dct_dct_32x32_sub8_add_neon: 11859.6 9313.0 9347.4 7514.5 vp9_inv_dct_dct_32x32_sub12_add_neon: 12946.6 10752.4 10192.2 8280.2 vp9_inv_dct_dct_32x32_sub16_add_neon: 14074.6 11946.5 11001.4 9008.6 vp9_inv_dct_dct_32x32_sub20_add_neon: 15269.9 13662.7 11816.1 9762.6 vp9_inv_dct_dct_32x32_sub24_add_neon: 16327.9 14940.1 12626.7 10516.0 vp9_inv_dct_dct_32x32_sub28_add_neon: 17462.7 15776.1 13446.2 11264.7 vp9_inv_dct_dct_32x32_sub32_add_neon: 18575.5 17157.0 14249.3 12015.1 I.e. in general a very minor overhead for the full subpartition case due to the additional loads and cmps, but a significant speedup for the cases when we only need to process a small part of the actual input data. In common VP9 content in a few inspected clips, 70-90% of the non-dc-only 16x16 and 32x32 IDCTs only have nonzero coefficients in the upper left 8x8 or 16x16 subpartitions respectively. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 75 ++++++++++++++++++++++++++++++---- tests/checkasm/vp9dsp.c | 6 ++- 2 files changed, 70 insertions(+), 11 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index 2049241d088a0..5abe435be9e99 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -659,9 +659,8 @@ endfunc @ Read a vertical 4x16 slice out of a 16x16 matrix, do a transform on it, @ transpose into a horizontal 16x4 slice and store. @ r0 = dst (temp buffer) -@ r1 = unused +@ r1 = slice offset @ r2 = src -@ r3 = slice offset function \txfm\()16_1d_4x16_pass1_neon mov r12, #32 vmov.s16 q2, #0 @@ -678,14 +677,14 @@ function \txfm\()16_1d_4x16_pass1_neon transpose16_q_4x_4x4 q8, q9, q10, q11, q12, q13, q14, q15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31 @ Store the transposed 4x4 blocks horizontally. - cmp r3, #12 + cmp r1, #12 beq 1f .irp i, 16, 20, 24, 28, 17, 21, 25, 29, 18, 22, 26, 30, 19, 23, 27, 31 vst1.16 {d\i}, [r0,:64]! .endr bx lr 1: - @ Special case: For the last input column (r3 == 12), + @ Special case: For the last input column (r1 == 12), @ which would be stored as the last row in the temp buffer, @ don't store the first 4x4 block, but keep it in registers @ for the first slice of the second pass (where it is the @@ -781,15 +780,22 @@ endfunc itxfm16_1d_funcs idct itxfm16_1d_funcs iadst +@ This is the minimum eob value for each subpartition, in increments of 4 +const min_eob_idct_idct_16, align=4 + .short 0, 10, 38, 89 +endconst + .macro itxfm_func16x16 txfm1, txfm2 function ff_vp9_\txfm1\()_\txfm2\()_16x16_add_neon, export=1 .ifc \txfm1\()_\txfm2,idct_idct cmp r3, #1 beq idct16x16_dc_add_neon .endif - push {r4-r7,lr} + push {r4-r8,lr} .ifnc \txfm1\()_\txfm2,idct_idct vpush {q4-q7} +.else + movrel r8, min_eob_idct_idct_16 + 2 .endif @ Align the stack, allocate a temp buffer @@ -810,10 +816,36 @@ A and r7, sp, #15 .irp i, 0, 4, 8, 12 add r0, sp, #(\i*32) +.ifc \txfm1\()_\txfm2,idct_idct +.if \i > 0 + ldrh_post r1, r8, #2 + cmp r3, r1 + it le + movle r1, #(16 - \i)/4 + ble 1f +.endif +.endif + mov r1, #\i add r2, r6, #(\i*2) - mov r3, #\i bl \txfm1\()16_1d_4x16_pass1_neon .endr + +.ifc \txfm1\()_\txfm2,idct_idct + b 3f +1: + @ For all-zero slices in pass 1, set d28-d31 to zero, for the in-register + @ passthrough of coefficients to pass 2 and clear the end of the temp buffer + vmov.i16 q14, #0 + vmov.i16 q15, #0 +2: + subs r1, r1, #1 +.rept 4 + vst1.16 {q14-q15}, [r0,:128]! +.endr + bne 2b +3: +.endif + .ifc \txfm1\()_\txfm2,iadst_idct movrel r12, idct_coeffs vld1.16 {q0-q1}, [r12,:128] @@ -830,7 +862,7 @@ A and r7, sp, #15 .ifnc \txfm1\()_\txfm2,idct_idct vpop {q4-q7} .endif - pop {r4-r7,pc} + pop {r4-r8,pc} endfunc .endm @@ -1110,11 +1142,16 @@ function idct32_1d_4x32_pass2_neon bx lr endfunc +const min_eob_idct_idct_32, align=4 + .short 0, 9, 34, 70, 135, 240, 336, 448 +endconst + function ff_vp9_idct_idct_32x32_add_neon, export=1 cmp r3, #1 beq idct32x32_dc_add_neon - push {r4-r7,lr} + push {r4-r8,lr} vpush {q4-q7} + movrel r8, min_eob_idct_idct_32 + 2 @ Align the stack, allocate a temp buffer T mov r7, sp @@ -1129,9 +1166,29 @@ A and r7, sp, #15 .irp i, 0, 4, 8, 12, 16, 20, 24, 28 add r0, sp, #(\i*64) +.if \i > 0 + ldrh_post r1, r8, #2 + cmp r3, r1 + it le + movle r1, #(32 - \i)/2 + ble 1f +.endif add r2, r6, #(\i*2) bl idct32_1d_4x32_pass1_neon .endr + b 3f + +1: + @ Write zeros to the temp buffer for pass 2 + vmov.i16 q14, #0 + vmov.i16 q15, #0 +2: + subs r1, r1, #1 +.rept 4 + vst1.16 {q14-q15}, [r0,:128]! +.endr + bne 2b +3: .irp i, 0, 4, 8, 12, 16, 20, 24, 28 add r0, r4, #(\i) mov r1, r5 @@ -1141,5 +1198,5 @@ A and r7, sp, #15 add sp, sp, r7 vpop {q4-q7} - pop {r4-r7,pc} + pop {r4-r8,pc} endfunc diff --git a/tests/checkasm/vp9dsp.c b/tests/checkasm/vp9dsp.c index 25f9dd1f9d0d9..39b82e165b388 100644 --- a/tests/checkasm/vp9dsp.c +++ b/tests/checkasm/vp9dsp.c @@ -272,8 +272,10 @@ static void check_itxfm(void) // skip testing sub-IDCTs for WHT or ADST since they don't // implement it in any of the SIMD functions. If they do, // consider changing this to ensure we have complete test - // coverage - for (sub = (txtp == 0 && tx < 4) ? 1 : sz; sub <= sz; sub <<= 1) { + // coverage. Test sub=1 for dc-only, then 2, 4, 8, 12, etc, + // since the arm version can distinguish them at that level. + for (sub = (txtp == 0 && tx < 4) ? 1 : sz; sub <= sz; + sub < 4 ? (sub <<= 1) : (sub += 4)) { if (check_func(dsp.itxfm_add[tx][txtp], "vp9_inv_%s_%dx%d_sub%d_add", tx == 4 ? "wht_wht" : txtp_types[txtp], From cad42fadcd2c2ae1b3676bb398844a1f521a2d7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 18 Nov 2016 12:26:04 +0200 Subject: [PATCH 0622/3374] aarch64: vp9itxfm: Skip empty slices in the first pass of idct_idct 16x16 and 32x32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. Previously all subpartitions except the eob=1 (DC) case ran with the same runtime: vp9_inv_dct_dct_16x16_sub16_add_neon: 1373.2 vp9_inv_dct_dct_32x32_sub32_add_neon: 8089.0 By skipping individual 8x16 or 8x32 pixel slices in the first pass, we reduce the runtime of these functions like this: vp9_inv_dct_dct_16x16_sub1_add_neon: 235.3 vp9_inv_dct_dct_16x16_sub2_add_neon: 1036.7 vp9_inv_dct_dct_16x16_sub4_add_neon: 1036.7 vp9_inv_dct_dct_16x16_sub8_add_neon: 1036.7 vp9_inv_dct_dct_16x16_sub12_add_neon: 1372.1 vp9_inv_dct_dct_16x16_sub16_add_neon: 1372.1 vp9_inv_dct_dct_32x32_sub1_add_neon: 555.1 vp9_inv_dct_dct_32x32_sub2_add_neon: 5190.2 vp9_inv_dct_dct_32x32_sub4_add_neon: 5180.0 vp9_inv_dct_dct_32x32_sub8_add_neon: 5183.1 vp9_inv_dct_dct_32x32_sub12_add_neon: 6161.5 vp9_inv_dct_dct_32x32_sub16_add_neon: 6155.5 vp9_inv_dct_dct_32x32_sub20_add_neon: 7136.3 vp9_inv_dct_dct_32x32_sub24_add_neon: 7128.4 vp9_inv_dct_dct_32x32_sub28_add_neon: 8098.9 vp9_inv_dct_dct_32x32_sub32_add_neon: 8098.8 I.e. in general a very minor overhead for the full subpartition case due to the additional cmps, but a significant speedup for the cases when we only need to process a small part of the actual input data. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 61 +++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 5 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index f4194a670f738..053d46fd08fad 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -588,6 +588,9 @@ endfunc .macro store i, dst, inc st1 {v\i\().8h}, [\dst], \inc .endm +.macro movi_v i, size, imm + movi v\i\()\size, \imm +.endm .macro load_clear i, src, inc ld1 {v\i\().8h}, [\src] st1 {v2.8h}, [\src], \inc @@ -596,9 +599,8 @@ endfunc // Read a vertical 8x16 slice out of a 16x16 matrix, do a transform on it, // transpose into a horizontal 16x8 slice and store. // x0 = dst (temp buffer) -// x1 = unused +// x1 = slice offset // x2 = src -// x3 = slice offset // x9 = input stride .macro itxfm16_1d_funcs txfm function \txfm\()16_1d_8x16_pass1_neon @@ -616,14 +618,14 @@ function \txfm\()16_1d_8x16_pass1_neon transpose_8x8H v24, v25, v26, v27, v28, v29, v30, v31, v2, v3 // Store the transposed 8x8 blocks horizontally. - cmp x3, #8 + cmp x1, #8 b.eq 1f .irp i, 16, 24, 17, 25, 18, 26, 19, 27, 20, 28, 21, 29, 22, 30, 23, 31 store \i, x0, #16 .endr ret 1: - // Special case: For the last input column (x3 == 8), + // Special case: For the last input column (x1 == 8), // which would be stored as the last row in the temp buffer, // don't store the first 8x8 block, but keep it in registers // for the first slice of the second pass (where it is the @@ -751,13 +753,36 @@ function ff_vp9_\txfm1\()_\txfm2\()_16x16_add_neon, export=1 .irp i, 0, 8 add x0, sp, #(\i*32) +.ifc \txfm1\()_\txfm2,idct_idct +.if \i == 8 + cmp w3, #38 + b.le 1f +.endif +.endif + mov x1, #\i add x2, x6, #(\i*2) - mov x3, #\i bl \txfm1\()16_1d_8x16_pass1_neon .endr .ifc \txfm1\()_\txfm2,iadst_idct ld1 {v0.8h,v1.8h}, [x10] .endif + +.ifc \txfm1\()_\txfm2,idct_idct + b 3f +1: + // Set v24-v31 to zero, for the in-register passthrough of + // coefficients to pass 2. Since we only do two slices, this can + // only ever happen for the second slice. So we only need to store + // zeros to the temp buffer for the second half of the buffer. + // Move x0 to the second half, and use x9 == 32 as increment. + add x0, x0, #16 +.irp i, 24, 25, 26, 27, 28, 29, 30, 31 + movi_v \i, .16b, #0 + st1 {v24.8h}, [x0], x9 +.endr +3: +.endif + .irp i, 0, 8 add x0, x4, #(\i) mov x1, x5 @@ -1073,12 +1098,17 @@ function idct32_1d_8x32_pass2_neon ret endfunc +const min_eob_idct_idct_32, align=4 + .short 0, 34, 135, 336 +endconst + function ff_vp9_idct_idct_32x32_add_neon, export=1 cmp w3, #1 b.eq idct32x32_dc_add_neon movrel x10, idct_coeffs add x11, x10, #32 + movrel x12, min_eob_idct_idct_32 + 2 mov x15, x30 @@ -1099,9 +1129,30 @@ function ff_vp9_idct_idct_32x32_add_neon, export=1 .irp i, 0, 8, 16, 24 add x0, sp, #(\i*64) +.if \i > 0 + ldrh w1, [x12], #2 + cmp w3, w1 + mov x1, #(32 - \i)/4 + b.le 1f +.endif add x2, x6, #(\i*2) bl idct32_1d_8x32_pass1_neon .endr + b 3f + +1: + // Write zeros to the temp buffer for pass 2 + movi v16.8h, #0 + movi v17.8h, #0 + movi v18.8h, #0 + movi v19.8h, #0 +2: + subs x1, x1, #1 +.rept 4 + st1 {v16.8h-v19.8h}, [x0], #64 +.endr + b.ne 2b +3: .irp i, 0, 8, 16, 24 add x0, x4, #(\i) mov x1, x5 From 0a35f128f3c6e0ae9a0a2236c557602c108da269 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 9 Mar 2016 10:27:12 +0100 Subject: [PATCH 0623/3374] cabac: x86: Give optimizations header a more meaningful name --- libavcodec/h264_cabac.c | 2 +- libavcodec/x86/{h264_i386.h => h264_cabac.c} | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) rename libavcodec/x86/{h264_i386.h => h264_cabac.c} (98%) diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c index ae1ef6b08c037..b28e486e52e96 100644 --- a/libavcodec/h264_cabac.c +++ b/libavcodec/h264_cabac.c @@ -41,7 +41,7 @@ #include "mpegutils.h" #if ARCH_X86 -#include "x86/h264_i386.h" +#include "x86/h264_cabac.c" #endif #include diff --git a/libavcodec/x86/h264_i386.h b/libavcodec/x86/h264_cabac.c similarity index 98% rename from libavcodec/x86/h264_i386.h rename to libavcodec/x86/h264_cabac.c index ad57aa91ab0c7..475c450118ac2 100644 --- a/libavcodec/x86/h264_i386.h +++ b/libavcodec/x86/h264_cabac.c @@ -22,13 +22,10 @@ /** * @file * H.264 / AVC / MPEG-4 part10 codec. - * non-MMX i386-specific optimizations for H.264 + * non-SIMD x86-specific optimizations for H.264 * @author Michael Niedermayer */ -#ifndef AVCODEC_X86_H264_I386_H -#define AVCODEC_X86_H264_I386_H - #include #include "libavcodec/cabac.h" @@ -201,4 +198,3 @@ static int decode_significance_8x8_x86(CABACContext *c, #endif /* HAVE_7REGS && !defined(BROKEN_RELOCATIONS) */ #endif /* HAVE_INLINE_ASM */ -#endif /* AVCODEC_X86_H264_I386_H */ From ff9db5cfd14558df9cfcc54d6c062bc34bf1f341 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Wed, 30 Nov 2016 17:09:33 -0500 Subject: [PATCH 0624/3374] lavc: Use a stricter check for the color properties values Signed-off-by: Vittorio Giovara --- libavcodec/h264_ps.c | 8 +++++--- libavcodec/hevc_ps.c | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c index 37c3be1cb99af..8a64a33780011 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -191,11 +191,13 @@ static inline int decode_vui_parameters(GetBitContext *gb, AVCodecContext *avctx sps->color_primaries = get_bits(gb, 8); /* colour_primaries */ sps->color_trc = get_bits(gb, 8); /* transfer_characteristics */ sps->colorspace = get_bits(gb, 8); /* matrix_coefficients */ - if (sps->color_primaries >= AVCOL_PRI_NB) + + // Set invalid values to "unspecified" + if (!av_color_primaries_name(sps->color_primaries)) sps->color_primaries = AVCOL_PRI_UNSPECIFIED; - if (sps->color_trc >= AVCOL_TRC_NB) + if (!av_color_transfer_name(sps->color_trc)) sps->color_trc = AVCOL_TRC_UNSPECIFIED; - if (sps->colorspace >= AVCOL_SPC_NB) + if (!av_color_space_name(sps->colorspace)) sps->colorspace = AVCOL_SPC_UNSPECIFIED; } } diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index c28e86b34a100..2471907077d63 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -497,11 +497,11 @@ static void decode_vui(GetBitContext *gb, AVCodecContext *avctx, vui->matrix_coeffs = get_bits(gb, 8); // Set invalid values to "unspecified" - if (vui->colour_primaries >= AVCOL_PRI_NB) + if (!av_color_primaries_name(vui->colour_primaries)) vui->colour_primaries = AVCOL_PRI_UNSPECIFIED; - if (vui->transfer_characteristic >= AVCOL_TRC_NB) + if (!av_color_transfer_name(vui->transfer_characteristic)) vui->transfer_characteristic = AVCOL_TRC_UNSPECIFIED; - if (vui->matrix_coeffs >= AVCOL_SPC_NB) + if (!av_color_space_name(vui->matrix_coeffs)) vui->matrix_coeffs = AVCOL_SPC_UNSPECIFIED; } } From 5168026a05258537f1c48ca95c1776b1554997f4 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Wed, 30 Nov 2016 17:09:34 -0500 Subject: [PATCH 0625/3374] options_table: Do not rely on enum size as option bound Signed-off-by: Vittorio Giovara --- libavcodec/options_table.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index 9fff50dc6f036..4deb2235520db 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -426,7 +426,7 @@ static const AVOption avcodec_options[] = { {"rc_max_vbv_use", NULL, OFFSET(rc_max_available_vbv_use), AV_OPT_TYPE_FLOAT, {.dbl = 1.0/3 }, 0.0, FLT_MAX, V|E}, {"rc_min_vbv_use", NULL, OFFSET(rc_min_vbv_overflow_use), AV_OPT_TYPE_FLOAT, {.dbl = 3 }, 0.0, FLT_MAX, V|E}, {"ticks_per_frame", NULL, OFFSET(ticks_per_frame), AV_OPT_TYPE_INT, {.i64 = 1 }, 1, INT_MAX, A|V|E|D}, -{"color_primaries", "color primaries", OFFSET(color_primaries), AV_OPT_TYPE_INT, {.i64 = AVCOL_PRI_UNSPECIFIED }, 1, AVCOL_PRI_NB-1, V|E|D, "color_primaries_type"}, +{"color_primaries", "color primaries", OFFSET(color_primaries), AV_OPT_TYPE_INT, {.i64 = AVCOL_PRI_UNSPECIFIED }, 1, INT_MAX, V|E|D, "color_primaries_type"}, {"bt709", "BT.709", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT709 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, {"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, {"bt470m", "BT.470 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT470M }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, @@ -441,7 +441,7 @@ static const AVOption avcodec_options[] = { {"jedec-p22", "JEDEC P22", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_JEDEC_P22 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, {"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, {"smptest428_1", "SMPTE 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, -{"color_trc", "color transfer characteristics", OFFSET(color_trc), AV_OPT_TYPE_INT, {.i64 = AVCOL_TRC_UNSPECIFIED }, 1, AVCOL_TRC_NB-1, V|E|D, "color_trc_type"}, +{"color_trc", "color transfer characteristics", OFFSET(color_trc), AV_OPT_TYPE_INT, {.i64 = AVCOL_TRC_UNSPECIFIED }, 1, INT_MAX, V|E|D, "color_trc_type"}, {"bt709", "BT.709", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT709 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, {"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, {"gamma22", "BT.470 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA22 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, @@ -469,7 +469,7 @@ static const AVOption avcodec_options[] = { {"bt2020_12bit", "BT.2020 - 12 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_12 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, {"smptest2084", "SMPTE 2084", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE2084 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, {"smptest428_1", "SMPTE 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, -{"colorspace", "color space", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64 = AVCOL_SPC_UNSPECIFIED }, 0, AVCOL_SPC_NB-1, V|E|D, "colorspace_type"}, +{"colorspace", "color space", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64 = AVCOL_SPC_UNSPECIFIED }, 0, INT_MAX, V|E|D, "colorspace_type"}, {"rgb", "RGB", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_RGB }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, {"bt709", "BT.709", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT709 }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, {"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, @@ -485,14 +485,14 @@ static const AVOption avcodec_options[] = { {"ycocg", "YCGCO", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCGCO }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, {"bt2020_ncl", "BT.2020 NCL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, {"bt2020_cl", "BT.2020 CL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_CL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, -{"color_range", "color range", OFFSET(color_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, AVCOL_RANGE_NB-1, V|E|D, "color_range_type"}, +{"color_range", "color range", OFFSET(color_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, INT_MAX, V|E|D, "color_range_type"}, {"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, {"tv", "MPEG (219*2^(n-8))", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, {"pc", "JPEG (2^n-1)", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, {"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, {"mpeg", "MPEG (219*2^(n-8))", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, {"jpeg", "JPEG (2^n-1)", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, -{"chroma_sample_location", "chroma sample location", OFFSET(chroma_sample_location), AV_OPT_TYPE_INT, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, 0, AVCHROMA_LOC_NB-1, V|E|D, "chroma_sample_location_type"}, +{"chroma_sample_location", "chroma sample location", OFFSET(chroma_sample_location), AV_OPT_TYPE_INT, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, 0, INT_MAX, V|E|D, "chroma_sample_location_type"}, {"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"}, {"left", "Left", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_LEFT }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"}, {"center", "Center", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_CENTER }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"}, @@ -516,7 +516,7 @@ static const AVOption avcodec_options[] = { {"em", "Emergency", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_EMERGENCY }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, {"vo", "Voice Over", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_VOICE_OVER }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, {"ka", "Karaoke", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_KARAOKE }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, -{"request_sample_fmt", NULL, OFFSET(request_sample_fmt), AV_OPT_TYPE_INT, {.i64 = AV_SAMPLE_FMT_NONE }, AV_SAMPLE_FMT_NONE, AV_SAMPLE_FMT_NB-1, A|D, "request_sample_fmt"}, +{"request_sample_fmt", NULL, OFFSET(request_sample_fmt), AV_OPT_TYPE_INT, {.i64 = AV_SAMPLE_FMT_NONE }, AV_SAMPLE_FMT_NONE, INT_MAX, A|D, "request_sample_fmt"}, {"u8" , "8-bit unsigned integer", 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_U8 }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, {"s16", "16-bit signed integer", 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_S16 }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, {"s32", "32-bit signed integer", 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_S32 }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, From 706af9227b58657c73e3a4df3689da734f010500 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Thu, 1 Dec 2016 15:17:27 -0500 Subject: [PATCH 0626/3374] lavu: Document the color properties enumeration values origin --- libavutil/pixfmt.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index 2a0c85e269979..41498ccef7691 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -313,6 +313,7 @@ enum AVPixelFormat { /** * Chromaticity coordinates of the source primaries. + * These values match the ones defined by ISO/IEC 23001-8_2013 § 7.1. */ enum AVColorPrimaries { AVCOL_PRI_RESERVED0 = 0, @@ -336,6 +337,7 @@ enum AVColorPrimaries { /** * Color Transfer Characteristic. + * These values match the ones defined by ISO/IEC 23001-8_2013 § 7.2. */ enum AVColorTransferCharacteristic { AVCOL_TRC_RESERVED0 = 0, @@ -364,6 +366,7 @@ enum AVColorTransferCharacteristic { /** * YUV colorspace type. + * These values match the ones defined by ISO/IEC 23001-8_2013 § 7.3. */ enum AVColorSpace { AVCOL_SPC_RGB = 0, ///< order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB) From a91f1023bc06091ef84dce0f1e12b72d7f3ba3ca Mon Sep 17 00:00:00 2001 From: Aleksandr Slobodeniuk Date: Fri, 2 Dec 2016 15:21:12 +0300 Subject: [PATCH 0627/3374] examples: fix a typo in an error message Signed-off-by: Vittorio Giovara --- doc/examples/transcode_aac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/examples/transcode_aac.c b/doc/examples/transcode_aac.c index 5c640d9ce25ee..d547b326ab284 100644 --- a/doc/examples/transcode_aac.c +++ b/doc/examples/transcode_aac.c @@ -580,7 +580,7 @@ static int init_output_frame(AVFrame **frame, * sure that the audio frame can hold as many samples as specified. */ if ((error = av_frame_get_buffer(*frame, 0)) < 0) { - fprintf(stderr, "Could allocate output frame samples (error '%s')\n", + fprintf(stderr, "Could not allocate output frame samples (error '%s')\n", get_error_text(error)); av_frame_free(frame); return error; From 518a22471e40604a158180a0660aabeeec65e07f Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Fri, 2 Dec 2016 13:11:43 +0100 Subject: [PATCH 0628/3374] configure: Be more helpful when requiring options set Be explicit about which options should be set. --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 71141c2d30831..d1fffbce8c89c 100755 --- a/configure +++ b/configure @@ -2896,7 +2896,7 @@ test -n "$cross_prefix" && enable cross_compile if enabled cross_compile; then test -n "$arch" && test -n "$target_os" || - die "Must specify target arch and OS when cross-compiling" + die "Must specify target arch (--arch) and OS (--target-os) when cross-compiling" fi ar_default="${cross_prefix}${ar_default}" From d82d5379caca21005d8906829b35361c4a65408e Mon Sep 17 00:00:00 2001 From: Wan-Teh Chang Date: Wed, 30 Nov 2016 11:52:41 -0800 Subject: [PATCH 0629/3374] mmaldec: initialize refcount using atomic_init() This is how we initialize refcount in libavutil/buffer.c. Signed-off-by: Wan-Teh Chang Signed-off-by: Vittorio Giovara --- libavcodec/mmaldec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/mmaldec.c b/libavcodec/mmaldec.c index 924bfb2e263fb..e64ddbabce13d 100644 --- a/libavcodec/mmaldec.c +++ b/libavcodec/mmaldec.c @@ -281,7 +281,7 @@ static int ffmal_update_format(AVCodecContext *avctx) ret = AVERROR(ENOMEM); goto fail; } - atomic_store(&ctx->pool_out->refcount, 1); + atomic_init(&ctx->pool_out->refcount, 1); if (!format_out) goto fail; From 33a2b73b98374de4781ae0497cf74b2ce07a9615 Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 30 Nov 2016 11:12:40 -0300 Subject: [PATCH 0630/3374] mpeg4audio: correctly propagate meaningful error values Signed-off-by: James Almer --- libavcodec/mpeg4audio.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libavcodec/mpeg4audio.c b/libavcodec/mpeg4audio.c index 2363cb637d413..af8e6552ffb99 100644 --- a/libavcodec/mpeg4audio.c +++ b/libavcodec/mpeg4audio.c @@ -33,10 +33,10 @@ static int parse_config_ALS(GetBitContext *gb, MPEG4AudioConfig *c) { if (get_bits_left(gb) < 112) - return -1; + return AVERROR_INVALIDDATA; if (get_bits_long(gb, 32) != MKBETAG('A','L','S','\0')) - return -1; + return AVERROR_INVALIDDATA; // override AudioSpecificConfig channel configuration and sample rate // which are buggy in old ALS conformance files @@ -116,8 +116,9 @@ int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, specific_config_bitindex = get_bits_count(&gb); - if (parse_config_ALS(&gb, c)) - return -1; + ret = parse_config_ALS(&gb, c); + if (ret < 0) + return ret; } if (c->ext_object_type != AOT_SBR && sync_extension) { From 984e50e74ba71301720652e56232161a994bd0b5 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 16 Mar 2015 19:21:14 +0100 Subject: [PATCH 0631/3374] build: Add -Wpedantic and -Wextra to extra warning flags Also drop -Winline from set of warning flags as it only produces noise. --- configure | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/configure b/configure index d1fffbce8c89c..983d56bbf72d2 100755 --- a/configure +++ b/configure @@ -4834,8 +4834,12 @@ check_cflags -Wtype-limits check_cflags -Wundef check_cflags -Wmissing-prototypes check_cflags -Wstrict-prototypes -enabled extra_warnings && check_cflags -Winline -enabled extra_warnings && check_cflags -Wcast-qual + +if enabled extra_warnings; then + check_cflags -Wcast-qual + check_cflags -Wextra + check_cflags -Wpedantic +fi check_disable_warning(){ warning_flag=-W${1#-Wno-} From 2575b1917b2703fae41a4b4901ad85c888374dfd Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 9 Mar 2016 15:39:29 +0100 Subject: [PATCH 0632/3374] build: Add separate flags for checkheaders targets This allows filtering out some warning noise. --- common.mak | 1 + configure | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/common.mak b/common.mak index 8f6a61f905d4e..372464821c993 100644 --- a/common.mak +++ b/common.mak @@ -33,6 +33,7 @@ ALLHEADERS := $(subst $(SRC_DIR)/,$(SUBDIR),$(wildcard $(SRC_DIR)/*.h $(SRC_DIR) SKIPHEADERS += $(ARCH_HEADERS:%=$(ARCH)/%) $(SKIPHEADERS-) SKIPHEADERS := $(SKIPHEADERS:%=$(SUBDIR)%) HOBJS = $(filter-out $(SKIPHEADERS:.h=.h.o),$(ALLHEADERS:.h=.h.o)) +$(HOBJS): CCFLAGS += $(CFLAGS_HEADERS) checkheaders: $(HOBJS) .SECONDARY: $(HOBJS:.o=.c) diff --git a/configure b/configure index 983d56bbf72d2..e1f7725eb00cf 100755 --- a/configure +++ b/configure @@ -4851,6 +4851,14 @@ check_disable_warning -Wno-switch check_disable_warning -Wno-format-zero-length check_disable_warning -Wno-pointer-sign +check_disable_warning_headers(){ + warning_flag=-W${1#-Wno-} + test_cflags $warning_flag && append cflags_headers $1 +} + +check_disable_warning_headers -Wno-deprecated-declarations +check_disable_warning_headers -Wno-unused-variable + # add some linker flags check_ldflags -Wl,--warn-common check_ldflags -Wl,-rpath-link=libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil:libavresample @@ -5315,6 +5323,7 @@ TARGET_EXEC=$target_exec $target_exec_args TARGET_PATH=$target_path TARGET_SAMPLES=${target_samples:-\$(SAMPLES)} CFLAGS-avplay=$sdl_cflags +CFLAGS_HEADERS=$cflags_headers ZLIB=$($ldflags_filter -lz) LIB_INSTALL_EXTRA_CMD=$LIB_INSTALL_EXTRA_CMD EXTRALIBS=$extralibs From 4a1ef543983b7480e2822f6ac281ba361d1f893d Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 29 Nov 2016 12:44:23 +0100 Subject: [PATCH 0633/3374] build: Drop support for old versions of libdc1394 The libdc1394 API transition was finished close to a decade ago. --- configure | 12 +--- libavdevice/libdc1394.c | 149 ++-------------------------------------- 2 files changed, 7 insertions(+), 154 deletions(-) diff --git a/configure b/configure index e1f7725eb00cf..f67accf4820ad 100755 --- a/configure +++ b/configure @@ -1671,8 +1671,6 @@ HAVE_LIST=" dos_paths dxva2_lib libc_msvcrt - libdc1394_1 - libdc1394_2 MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS sdl section_data_rel_ro @@ -4625,6 +4623,7 @@ enabled cuda && check_lib cuda.h cuInit -lcuda enabled frei0r && { check_header frei0r.h || die "ERROR: frei0r.h header not found"; } enabled gnutls && require_pkg_config gnutls gnutls/gnutls.h gnutls_global_init enabled libbs2b && require_pkg_config libbs2b bs2b.h bs2b_open +enabled libdc1394 && require_pkg_config libdc1394-2 dc1394/dc1394.h dc1394_new enabled libdcadec && require libdcadec libdcadec/dca_context.h dcadec_context_create -ldcadec enabled libfaac && require libfaac "stdint.h faac.h" faacEncGetVersion -lfaac enabled libfdk_aac && require_pkg_config fdk-aac "fdk-aac/aacenc_lib.h" aacEncOpen @@ -4713,15 +4712,6 @@ enabled openssl && { { check_pkg_config openssl openssl/ssl.h OPENSSL_ enabled gnutls && check_lib gmp.h mpz_export -lgmp && enable gmp -# libdc1394 check -if enabled libdc1394; then - { require_pkg_config libdc1394-2 dc1394/dc1394.h dc1394_new && - enable libdc1394_2; } || - { check_lib libdc1394/dc1394_control.h dc1394_create_handle -ldc1394_control -lraw1394 && - enable libdc1394_1; } || - die "ERROR: No version of libdc1394 found " -fi - if enabled nvenc; then check_header nvEncodeAPI.h || die "ERROR: nvEncodeAPI.h not found." check_cpp_condition nvEncodeAPI.h "NVENCAPI_MAJOR_VERSION >= 6" || diff --git a/libavdevice/libdc1394.c b/libavdevice/libdc1394.c index c823388a76f95..0fa3786170b03 100644 --- a/libavdevice/libdc1394.c +++ b/libavdevice/libdc1394.c @@ -20,26 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "config.h" - -#if HAVE_LIBDC1394_2 #include -#elif HAVE_LIBDC1394_1 -#include -#include - -#define DC1394_VIDEO_MODE_320x240_YUV422 MODE_320x240_YUV422 -#define DC1394_VIDEO_MODE_640x480_YUV411 MODE_640x480_YUV411 -#define DC1394_VIDEO_MODE_640x480_YUV422 MODE_640x480_YUV422 -#define DC1394_FRAMERATE_1_875 FRAMERATE_1_875 -#define DC1394_FRAMERATE_3_75 FRAMERATE_3_75 -#define DC1394_FRAMERATE_7_5 FRAMERATE_7_5 -#define DC1394_FRAMERATE_15 FRAMERATE_15 -#define DC1394_FRAMERATE_30 FRAMERATE_30 -#define DC1394_FRAMERATE_60 FRAMERATE_60 -#define DC1394_FRAMERATE_120 FRAMERATE_120 -#define DC1394_FRAMERATE_240 FRAMERATE_240 -#endif #include "libavutil/imgutils.h" #include "libavutil/internal.h" @@ -54,15 +35,9 @@ typedef struct dc1394_data { AVClass *class; -#if HAVE_LIBDC1394_1 - raw1394handle_t handle; - dc1394_cameracapture camera; - int channel; -#elif HAVE_LIBDC1394_2 dc1394_t *d; dc1394camera_t *camera; dc1394video_frame_t *frame; -#endif int current_frame; int frame_rate; /**< frames per 1000 seconds (fps * 1000) */ char *video_size; /**< String describing video size, set by a private option. */ @@ -104,9 +79,6 @@ struct dc1394_frame_rate { #define OFFSET(x) offsetof(dc1394_data, x) #define DEC AV_OPT_FLAG_DECODING_PARAM static const AVOption options[] = { -#if HAVE_LIBDC1394_1 - { "channel", "", offsetof(dc1394_data, channel), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, -#endif { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = "qvga"}, 0, 0, DEC }, { "pixel_format", "", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = "uyvy422"}, 0, 0, DEC }, { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "ntsc"}, 0, 0, DEC }, @@ -191,102 +163,7 @@ static inline int dc1394_read_common(AVFormatContext *c, return ret; } -#if HAVE_LIBDC1394_1 -static int dc1394_v1_read_header(AVFormatContext *c) -{ - dc1394_data* dc1394 = c->priv_data; - AVStream* vst; - nodeid_t* camera_nodes; - int res; - struct dc1394_frame_format *fmt = NULL; - struct dc1394_frame_rate *fps = NULL; - - if (dc1394_read_common(c, &fmt, &fps) != 0) - return -1; - - /* Now let us prep the hardware. */ - dc1394->handle = dc1394_create_handle(0); /* FIXME: gotta have ap->port */ - if (!dc1394->handle) { - av_log(c, AV_LOG_ERROR, "Can't acquire dc1394 handle on port %d\n", 0 /* ap->port */); - goto out; - } - camera_nodes = dc1394_get_camera_nodes(dc1394->handle, &res, 1); - if (!camera_nodes || camera_nodes[dc1394->channel] == DC1394_NO_CAMERA) { - av_log(c, AV_LOG_ERROR, "There's no IIDC camera on the channel %d\n", dc1394->channel); - goto out_handle; - } - res = dc1394_dma_setup_capture(dc1394->handle, camera_nodes[dc1394->channel], - 0, - FORMAT_VGA_NONCOMPRESSED, - fmt->frame_size_id, - SPEED_400, - fps->frame_rate_id, 8, 1, - c->filename, - &dc1394->camera); - dc1394_free_camera_nodes(camera_nodes); - if (res != DC1394_SUCCESS) { - av_log(c, AV_LOG_ERROR, "Can't prepare camera for the DMA capture\n"); - goto out_handle; - } - - res = dc1394_start_iso_transmission(dc1394->handle, dc1394->camera.node); - if (res != DC1394_SUCCESS) { - av_log(c, AV_LOG_ERROR, "Can't start isochronous transmission\n"); - goto out_handle_dma; - } - - return 0; - -out_handle_dma: - dc1394_dma_unlisten(dc1394->handle, &dc1394->camera); - dc1394_dma_release_camera(dc1394->handle, &dc1394->camera); -out_handle: - dc1394_destroy_handle(dc1394->handle); -out: - return -1; -} - -static int dc1394_v1_read_packet(AVFormatContext *c, AVPacket *pkt) -{ - struct dc1394_data *dc1394 = c->priv_data; - int res; - - /* discard stale frame */ - if (dc1394->current_frame++) { - if (dc1394_dma_done_with_buffer(&dc1394->camera) != DC1394_SUCCESS) - av_log(c, AV_LOG_ERROR, "failed to release %d frame\n", dc1394->current_frame); - } - - res = dc1394_dma_single_capture(&dc1394->camera); - - if (res == DC1394_SUCCESS) { - pkt->data = (uint8_t *)dc1394->camera.capture_buffer; - pkt->size = dc1394->size; - pkt->pts = (dc1394->current_frame * 1000000) / dc1394->frame_rate; - pkt->flags |= AV_PKT_FLAG_KEY; - pkt->stream_index = dc1394->stream_index; - } else { - av_log(c, AV_LOG_ERROR, "DMA capture failed\n"); - return AVERROR_INVALIDDATA; - } - - return pkt->size; -} - -static int dc1394_v1_close(AVFormatContext * context) -{ - struct dc1394_data *dc1394 = context->priv_data; - - dc1394_stop_iso_transmission(dc1394->handle, dc1394->camera.node); - dc1394_dma_unlisten(dc1394->handle, &dc1394->camera); - dc1394_dma_release_camera(dc1394->handle, &dc1394->camera); - dc1394_destroy_handle(dc1394->handle); - - return 0; -} - -#elif HAVE_LIBDC1394_2 -static int dc1394_v2_read_header(AVFormatContext *c) +static int dc1394_read_header(AVFormatContext *c) { dc1394_data* dc1394 = c->priv_data; dc1394camera_list_t *list; @@ -364,7 +241,7 @@ static int dc1394_v2_read_header(AVFormatContext *c) return -1; } -static int dc1394_v2_read_packet(AVFormatContext *c, AVPacket *pkt) +static int dc1394_read_packet(AVFormatContext *c, AVPacket *pkt) { struct dc1394_data *dc1394 = c->priv_data; int res; @@ -390,7 +267,7 @@ static int dc1394_v2_read_packet(AVFormatContext *c, AVPacket *pkt) return pkt->size; } -static int dc1394_v2_close(AVFormatContext * context) +static int dc1394_close(AVFormatContext * context) { struct dc1394_data *dc1394 = context->priv_data; @@ -406,23 +283,9 @@ AVInputFormat ff_libdc1394_demuxer = { .name = "libdc1394", .long_name = NULL_IF_CONFIG_SMALL("dc1394 v.2 A/V grab"), .priv_data_size = sizeof(struct dc1394_data), - .read_header = dc1394_v2_read_header, - .read_packet = dc1394_v2_read_packet, - .read_close = dc1394_v2_close, - .flags = AVFMT_NOFILE, - .priv_class = &libdc1394_class, -}; - -#endif -#if HAVE_LIBDC1394_1 -AVInputFormat ff_libdc1394_demuxer = { - .name = "libdc1394", - .long_name = NULL_IF_CONFIG_SMALL("dc1394 v.1 A/V grab"), - .priv_data_size = sizeof(struct dc1394_data), - .read_header = dc1394_v1_read_header, - .read_packet = dc1394_v1_read_packet, - .read_close = dc1394_v1_close, + .read_header = dc1394_read_header, + .read_packet = dc1394_read_packet, + .read_close = dc1394_close, .flags = AVFMT_NOFILE, .priv_class = &libdc1394_class, }; -#endif From 3794062ab1a13442b06f6d76c54dce51ffa54697 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 29 Nov 2016 15:09:35 +0100 Subject: [PATCH 0634/3374] Remove Plan 9 support Supporting the system was a nice joke for the 9 release, but it has run its course. Nowadays Plan 9 receives no testing and has no practical usefulness. --- Makefile | 4 +-- compat/plan9/head | 10 ------- compat/plan9/main.c | 34 ---------------------- compat/plan9/printf | 2 -- configure | 18 +----------- doc/platform.texi | 63 ---------------------------------------- libavformat/os_support.h | 2 +- library.mak | 2 +- tests/checkasm/Makefile | 2 +- 9 files changed, 6 insertions(+), 131 deletions(-) delete mode 100755 compat/plan9/head delete mode 100644 compat/plan9/main.c delete mode 100755 compat/plan9/printf diff --git a/Makefile b/Makefile index 82e037103f6ef..f5bbc8b626da3 100644 --- a/Makefile +++ b/Makefile @@ -116,7 +116,7 @@ FF_STATIC_DEP_LIBS := $(STATIC_DEP_LIBS) all: $(AVPROGS) -$(TOOLS): %$(EXESUF): %.o $(EXEOBJS) +$(TOOLS): %$(EXESUF): %.o $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) tools/cws2fws$(EXESUF): ELIBS = $(ZLIB) @@ -157,7 +157,7 @@ $(foreach D,$(FFLIBS),$(eval $(call DOSUBDIR,lib$(D)))) include $(SRC_PATH)/doc/Makefile define DOPROG -OBJS-$(1) += $(1).o $(EXEOBJS) $(OBJS-$(1)-yes) +OBJS-$(1) += $(1).o $(OBJS-$(1)-yes) $(1)$(EXESUF): $$(OBJS-$(1)) $$(OBJS-$(1)): CFLAGS += $(CFLAGS-$(1)) $(1)$(EXESUF): LDFLAGS += $(LDFLAGS-$(1)) diff --git a/compat/plan9/head b/compat/plan9/head deleted file mode 100755 index 2840b2d50f9a7..0000000000000 --- a/compat/plan9/head +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -n=10 - -case "$1" in - -n) n=$2; shift 2 ;; - -n*) n=${1#-n}; shift ;; -esac - -exec sed ${n}q "$@" diff --git a/compat/plan9/main.c b/compat/plan9/main.c deleted file mode 100644 index 97d70678a6cbf..0000000000000 --- a/compat/plan9/main.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of Libav. - * - * Libav is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * Libav is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -int plan9_main(int argc, char **argv); - -#undef main -int main(int argc, char **argv) -{ - /* The setfcr() function in lib9 is broken, must use asm. */ -#ifdef __i386 - short fcr; - __asm__ volatile ("fstcw %0 \n" - "or $63, %0 \n" - "fldcw %0 \n" - : "=m"(fcr)); -#endif - - return plan9_main(argc, argv); -} diff --git a/compat/plan9/printf b/compat/plan9/printf deleted file mode 100755 index 1a70a9e91a9dd..0000000000000 --- a/compat/plan9/printf +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec awk "BEGIN { for (i = 2; i < ARGC; i++) printf \"$1\", ARGV[i] }" "$@" diff --git a/configure b/configure index f67accf4820ad..1ae4ab2b0a264 100755 --- a/configure +++ b/configure @@ -1173,7 +1173,7 @@ apply(){ cp_if_changed(){ cmp -s "$1" "$2" && { test "$quiet" != "yes" && echo "$2 is unchanged"; } && return mkdir -p "$(dirname $2)" - $cp_f "$1" "$2" + cp -f "$1" "$2" } # CONFIG_LIST contains configurable options, while HAVE_LIST is for @@ -2491,7 +2491,6 @@ shlibdir_default="$libdir_default" ar_default="ar" cc_default="gcc" host_cc_default="gcc" -cp_f="cp -f" ln_s="ln -s -f" nm_default="nm -g" objformat="elf" @@ -3985,17 +3984,6 @@ case $target_os in ;; minix) ;; - plan9) - add_cppflags -D_C99_SNPRINTF_EXTENSION \ - -D_REENTRANT_SOURCE \ - -D_RESEARCH_SOURCE \ - -DFD_SETSIZE=96 \ - -DHAVE_SOCK_OPTS - add_compat strtod.o strtod=avpriv_strtod - network_extralibs='-lbsd' - exeobjs=compat/plan9/main.o - cp_f='cp' - ;; none) ;; *) @@ -5056,9 +5044,6 @@ case $target_os in osf1) enabled ccc && add_ldflags '-Wl,-expect_unresolved,*' ;; - plan9) - add_cppflags -Dmain=plan9_main - ;; esac enabled asm || { arch=c; disable $ARCH_LIST $ARCH_EXT_LIST; } @@ -5318,7 +5303,6 @@ ZLIB=$($ldflags_filter -lz) LIB_INSTALL_EXTRA_CMD=$LIB_INSTALL_EXTRA_CMD EXTRALIBS=$extralibs COMPAT_OBJS=$compat_objs -EXEOBJS=$exeobjs INSTALL=install LIBTARGET=${LIBTARGET} SLIBNAME=${SLIBNAME} diff --git a/doc/platform.texi b/doc/platform.texi index 4feb50f7ecb50..74b014e138aab 100644 --- a/doc/platform.texi +++ b/doc/platform.texi @@ -336,67 +336,4 @@ and for a build with shared libraries ./configure --target-os=mingw32 --enable-shared --disable-static --extra-cflags=-mno-cygwin --extra-libs=-mno-cygwin @end example -@chapter Plan 9 - -The native @uref{http://plan9.bell-labs.com/plan9/, Plan 9} compiler -does not implement all the C99 features needed by Libav so the gcc -port must be used. Furthermore, a few items missing from the C -library and shell environment need to be fixed. - -@itemize - -@item GNU awk, grep, make, and sed - -Working packages of these tools can be found at -@uref{http://code.google.com/p/ports2plan9/downloads/list, ports2plan9}. -They can be installed with @uref{http://9front.org/, 9front's} @code{pkg} -utility by setting @code{pkgpath} to -@code{http://ports2plan9.googlecode.com/files/}. - -@item Missing/broken @code{head} and @code{printf} commands - -Replacements adequate for building Libav can be found in the -@code{compat/plan9} directory. Place these somewhere they will be -found by the shell. These are not full implementations of the -commands and are @emph{not} suitable for general use. - -@item Missing C99 @code{stdint.h} and @code{inttypes.h} - -Replacement headers are available from -@url{http://code.google.com/p/plan9front/issues/detail?id=152}. - -@item Missing or non-standard library functions - -Some functions in the C library are missing or incomplete. The -@code{@uref{http://ports2plan9.googlecode.com/files/gcc-apelibs-1207.tbz, -gcc-apelibs-1207}} package from -@uref{http://code.google.com/p/ports2plan9/downloads/list, ports2plan9} -includes an updated C library, but installing the full package gives -unusable executables. Instead, keep the files from @code{gccbin.tgz} -under @code{/386/lib/gnu}. From the @code{libc.a} archive in the -@code{gcc-apelibs-1207} package, extract the following object files and -turn them into a library: - -@itemize -@item @code{strerror.o} -@item @code{strtoll.o} -@item @code{snprintf.o} -@item @code{vsnprintf.o} -@item @code{vfprintf.o} -@item @code{_IO_getc.o} -@item @code{_IO_putc.o} -@end itemize - -Use the @code{--extra-libs} option of @code{configure} to inform the -build system of this library. - -@item FPU exceptions enabled by default - -Unlike most other systems, Plan 9 enables FPU exceptions by default. -These must be disabled before calling any Libav functions. While the -included tools will do this automatically, other users of the -libraries must do it themselves. - -@end itemize - @bye diff --git a/libavformat/os_support.h b/libavformat/os_support.h index 6cc6d9aa2b797..965e16fa5e937 100644 --- a/libavformat/os_support.h +++ b/libavformat/os_support.h @@ -59,7 +59,7 @@ static inline int is_dos_path(const char *path) return 0; } -#if defined(__OS2__) || defined(__Plan9__) +#if defined(__OS2__) #define SHUT_RD 0 #define SHUT_WR 1 #define SHUT_RDWR 2 diff --git a/library.mak b/library.mak index b456d80cd19fc..14fd5beba1e74 100644 --- a/library.mak +++ b/library.mak @@ -27,7 +27,7 @@ define RULES $(TOOLS): THISLIB = $(FULLNAME:%=$(LD_LIB)) $(TESTPROGS): THISLIB = $(SUBDIR)$(LIBNAME) -$(TESTPROGS) $(TOOLS): %$(EXESUF): %.o $(EXEOBJS) +$(TESTPROGS) $(TOOLS): %$(EXESUF): %.o $$(LD) $(LDFLAGS) $(LDEXEFLAGS) $$(LD_O) $$(filter %.o,$$^) $$(THISLIB) $(FFEXTRALIBS) $$(ELIBS) $(SUBDIR)lib$(NAME).ver: $(SUBDIR)lib$(NAME).v $(OBJS) diff --git a/tests/checkasm/Makefile b/tests/checkasm/Makefile index dbd7393c59d48..639a08e0a608c 100644 --- a/tests/checkasm/Makefile +++ b/tests/checkasm/Makefile @@ -34,7 +34,7 @@ OBJDIRS += $(CHECKASMDIRS) CHECKASM := tests/checkasm/checkasm$(EXESUF) -$(CHECKASM): $(EXEOBJS) $(CHECKASMOBJS) $(FF_STATIC_DEP_LIBS) +$(CHECKASM): $(CHECKASMOBJS) $(FF_STATIC_DEP_LIBS) $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $(CHECKASMOBJS) $(FF_STATIC_DEP_LIBS) $(EXTRALIBS) checkasm: $(CHECKASM) From 1ea77aae927c7310034b1f75d4f1c2676fe641f2 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 29 Nov 2016 17:34:15 +0100 Subject: [PATCH 0635/3374] configure: Drop bogus xcb_event variables --- configure | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 1ae4ab2b0a264..22ec4f79e9046 100755 --- a/configure +++ b/configure @@ -4773,8 +4773,8 @@ if enabled libxcb; then enabled libxcb_xfixes && die "ERROR: libxcb_xfixes not found"; } && enable libxcb_xfixes - add_cflags "$xcb_shape_cflags $xcb_event_cflags $xcb_shm_cflags $xcb_xfixes_cflags" - add_extralibs "$xcb_shape_libs $xcb_event_libs $xcb_shm_libs $xcb_xfixes_libs" + add_cflags "$xcb_shape_cflags $xcb_shm_cflags $xcb_xfixes_cflags" + add_extralibs "$xcb_shape_libs $xcb_shm_libs $xcb_xfixes_libs" fi enabled vaapi && require vaapi va/va.h vaInitialize -lva From 14bba44fb23c63bf82b2c15f5c754b2fed7dbea9 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 25 Mar 2013 14:59:50 +0100 Subject: [PATCH 0636/3374] build: Drop support for configuring library name suffixes It is of doubtful utility, adds complexity and no known users exist. --- common.mak | 3 +-- configure | 34 +++++++++++++--------------------- library.mak | 2 +- 3 files changed, 15 insertions(+), 24 deletions(-) diff --git a/common.mak b/common.mak index 372464821c993..7773693b96bab 100644 --- a/common.mak +++ b/common.mak @@ -11,8 +11,7 @@ OBJS += $(OBJS-yes) FFLIBS := $($(NAME)_FFLIBS) $(FFLIBS-yes) $(FFLIBS) TESTPROGS += $(TESTPROGS-yes) -LDLIBS = $(FFLIBS:%=%$(BUILDSUF)) -FFEXTRALIBS := $(LDLIBS:%=$(LD_LIB)) $(EXTRALIBS) +FFEXTRALIBS := $(FFLIBS:%=$(LD_LIB)) $(EXTRALIBS) OBJS := $(sort $(OBJS:%=$(SUBDIR)%)) TESTOBJS := $(TESTOBJS:%=$(SUBDIR)tests/%) $(TESTPROGS:%=$(SUBDIR)tests/%.o) diff --git a/configure b/configure index 22ec4f79e9046..03806f60ad11a 100755 --- a/configure +++ b/configure @@ -283,7 +283,6 @@ Toolchain options: --extra-libs=ELIBS add ELIBS [$ELIBS] --extra-version=STRING version string suffix [] --optflags=OPTFLAGS override optimization-related compiler flags - --build-suffix=SUFFIX library name suffix [] --enable-pic build position-independent code --enable-thumb compile for Thumb instruction set --enable-lto use link-time optimization @@ -1787,7 +1786,6 @@ CMDLINE_SET=" ar arch as - build_suffix cc objcc cpu @@ -2529,11 +2527,10 @@ enable d3d11va dxva2 vda vdpau SHFLAGS='-shared -Wl,-soname,$$(@F)' LIBPREF="lib" LIBSUF=".a" -FULLNAME='$(NAME)$(BUILDSUF)' -LIBNAME='$(LIBPREF)$(FULLNAME)$(LIBSUF)' +LIBNAME='$(LIBPREF)$(NAME)$(LIBSUF)' SLIBPREF="lib" SLIBSUF=".so" -SLIBNAME='$(SLIBPREF)$(FULLNAME)$(SLIBSUF)' +SLIBNAME='$(SLIBPREF)$(NAME)$(SLIBSUF)' SLIBNAME_WITH_VERSION='$(SLIBNAME).$(LIBVERSION)' SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)' LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"' @@ -3843,8 +3840,8 @@ case $target_os in enabled x86_32 && append SHFLAGS -Wl,-read_only_relocs,suppress add_ldflags -Wl,-dynamic,-search_paths_first SLIBSUF=".dylib" - SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME).$(LIBVERSION)$(SLIBSUF)' - SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME).$(LIBMAJOR)$(SLIBSUF)' + SLIBNAME_WITH_VERSION='$(SLIBPREF)$(NAME).$(LIBVERSION)$(SLIBSUF)' + SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(NAME).$(LIBMAJOR)$(SLIBSUF)' objformat="macho" enabled x86_64 && objformat="macho64" enabled_any pic shared || @@ -3872,8 +3869,8 @@ case $target_os in shlibdir_default="$bindir_default" SLIBPREF="" SLIBSUF=".dll" - SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF)' - SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)' + SLIBNAME_WITH_VERSION='$(SLIBPREF)$(NAME)-$(LIBVERSION)$(SLIBSUF)' + SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(NAME)-$(LIBMAJOR)$(SLIBSUF)' SLIB_EXTRA_CMD=-'sed -e "s/ @[^ ]*//" $$(@:$(SLIBSUF)=.orig.def) > $$(@:$(SLIBSUF)=.def); $(DLLTOOL) -m $(LIBTARGET) -d $$(@:$(SLIBSUF)=.def) -l $(SUBDIR)$(SLIBNAME:$(SLIBSUF)=.lib) -D $(SLIBNAME_WITH_MAJOR)' SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)' SLIB_INSTALL_LINKS= @@ -3897,8 +3894,8 @@ case $target_os in shlibdir_default="$bindir_default" SLIBPREF="" SLIBSUF=".dll" - SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF)' - SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)' + SLIBNAME_WITH_VERSION='$(SLIBPREF)$(NAME)-$(LIBVERSION)$(SLIBSUF)' + SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(NAME)-$(LIBMAJOR)$(SLIBSUF)' SLIB_CREATE_DEF_CMD='$(SRC_PATH)/compat/windows/makedef $(SUBDIR)lib$(NAME).ver $(OBJS) > $$(@:$(SLIBSUF)=.def)' SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)' SLIB_INSTALL_LINKS= @@ -3914,12 +3911,12 @@ case $target_os in shlibdir_default="$bindir_default" SLIBPREF="cyg" SLIBSUF=".dll" - SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF)' - SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)' + SLIBNAME_WITH_VERSION='$(SLIBPREF)$(NAME)-$(LIBVERSION)$(SLIBSUF)' + SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(NAME)-$(LIBMAJOR)$(SLIBSUF)' SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)' SLIB_INSTALL_LINKS= - SLIB_INSTALL_EXTRA_LIB='lib$(FULLNAME).dll.a' - SHFLAGS='-shared -Wl,--out-implib,$(SUBDIR)lib$(FULLNAME).dll.a' + SLIB_INSTALL_EXTRA_LIB='lib$(NAME).dll.a' + SHFLAGS='-shared -Wl,--out-implib,$(SUBDIR)lib$(NAME).dll.a' objformat="win32" enable dos_paths ;; @@ -5113,9 +5110,6 @@ if test "$host_cc" != "$cc"; then echo "host C library $host_libc_type" fi echo "ARCH $arch ($cpu)" -if test "$build_suffix" != ""; then - echo "build suffix $build_suffix" -fi if test "$extra_version" != ""; then echo "version string suffix $extra_version" fi @@ -5264,8 +5258,6 @@ LDEXEFLAGS=$LDEXEFLAGS SHFLAGS=$(echo $($ldflags_filter $SHFLAGS)) STRIPFLAGS=$STRIPFLAGS YASMFLAGS=$YASMFLAGS -BUILDSUF=$build_suffix -FULLNAME=$FULLNAME LIBPREF=$LIBPREF LIBSUF=$LIBSUF LIBNAME=$LIBNAME @@ -5417,7 +5409,7 @@ lib_version(){ pkgconfig_generate(){ name=$1 - shortname=${name#lib}${build_suffix} + shortname=${name#lib} comment=$2 version=$3 libs=$4 diff --git a/library.mak b/library.mak index 14fd5beba1e74..bf1853f98967d 100644 --- a/library.mak +++ b/library.mak @@ -24,7 +24,7 @@ install-libs-$(CONFIG_STATIC): install-lib$(NAME)-static install-libs-$(CONFIG_SHARED): install-lib$(NAME)-shared define RULES -$(TOOLS): THISLIB = $(FULLNAME:%=$(LD_LIB)) +$(TOOLS): THISLIB = $(NAME:%=$(LD_LIB)) $(TESTPROGS): THISLIB = $(SUBDIR)$(LIBNAME) $(TESTPROGS) $(TOOLS): %$(EXESUF): %.o From 6ef3360a38efe027cb6ebf9785870048ca7eb38b Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 2 Dec 2016 13:06:02 +0100 Subject: [PATCH 0637/3374] configure: Add misssing qpeldsp dependency to mss2 decoder --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 03806f60ad11a..e348f3be65937 100755 --- a/configure +++ b/configure @@ -2036,7 +2036,7 @@ msmpeg4v2_decoder_select="h263_decoder" msmpeg4v2_encoder_select="h263_encoder" msmpeg4v3_decoder_select="h263_decoder" msmpeg4v3_encoder_select="h263_encoder" -mss2_decoder_select="error_resilience mpeg_er mpegvideo vc1_decoder" +mss2_decoder_select="error_resilience mpeg_er mpegvideo qpeldsp vc1_decoder" mts2_decoder_select="mss34dsp" mxpeg_decoder_select="mjpeg_decoder" nellymoser_decoder_select="mdct sinewin" From 39ecf0588fb2ea4ff9b22c89e836b07f9fe2d24f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Wed, 6 Apr 2016 20:26:48 +0200 Subject: [PATCH 0638/3374] webp: Convert to the new bitstream reader --- libavcodec/webp.c | 106 ++++++++++++++++++++++------------------------ 1 file changed, 50 insertions(+), 56 deletions(-) diff --git a/libavcodec/webp.c b/libavcodec/webp.c index b26399c504904..a6ab52bf83721 100644 --- a/libavcodec/webp.c +++ b/libavcodec/webp.c @@ -41,8 +41,8 @@ #define BITSTREAM_READER_LE #include "avcodec.h" +#include "bitstream.h" #include "bytestream.h" -#include "get_bits.h" #include "internal.h" #include "thread.h" #include "vp8.h" @@ -183,7 +183,7 @@ typedef struct ImageContext { typedef struct WebPContext { VP8Context v; /* VP8 Context used for lossy decoding */ - GetBitContext gb; /* bitstream reader for main image chunk */ + BitstreamContext bc; /* bitstream reader for main image chunk */ AVFrame *alpha_frame; /* AVFrame for alpha data decompressed from VP8L */ AVCodecContext *avctx; /* parent AVCodecContext */ int initialized; /* set once the VP8 context is initialized */ @@ -232,47 +232,41 @@ static void image_ctx_free(ImageContext *img) * - assumes 8-bit table to make reversal simpler * - assumes max depth of 2 since the max code length for WebP is 15 */ -static av_always_inline int webp_get_vlc(GetBitContext *gb, VLC_TYPE (*table)[2]) +static av_always_inline int webp_get_vlc(BitstreamContext *bc, VLC_TYPE (*table)[2]) { int n, nb_bits; unsigned int index; int code; - OPEN_READER(re, gb); - UPDATE_CACHE(re, gb); - - index = SHOW_UBITS(re, gb, 8); + index = bitstream_peek(bc, 8); index = ff_reverse[index]; code = table[index][0]; n = table[index][1]; if (n < 0) { - LAST_SKIP_BITS(re, gb, 8); - UPDATE_CACHE(re, gb); + bitstream_skip(bc, 8); nb_bits = -n; - index = SHOW_UBITS(re, gb, nb_bits); + index = bitstream_peek(bc, nb_bits); index = (ff_reverse[index] >> (8 - nb_bits)) + code; code = table[index][0]; n = table[index][1]; } - SKIP_BITS(re, gb, n); - - CLOSE_READER(re, gb); + bitstream_skip(bc, n); return code; } -static int huff_reader_get_symbol(HuffReader *r, GetBitContext *gb) +static int huff_reader_get_symbol(HuffReader *r, BitstreamContext *bc) { if (r->simple) { if (r->nb_symbols == 1) return r->simple_symbols[0]; else - return r->simple_symbols[get_bits1(gb)]; + return r->simple_symbols[bitstream_read_bit(bc)]; } else - return webp_get_vlc(gb, r->vlc.table); + return webp_get_vlc(bc, r->vlc.table); } static int huff_reader_build_canonical(HuffReader *r, int *code_lengths, @@ -339,15 +333,15 @@ static int huff_reader_build_canonical(HuffReader *r, int *code_lengths, static void read_huffman_code_simple(WebPContext *s, HuffReader *hc) { - hc->nb_symbols = get_bits1(&s->gb) + 1; + hc->nb_symbols = bitstream_read_bit(&s->bc) + 1; - if (get_bits1(&s->gb)) - hc->simple_symbols[0] = get_bits(&s->gb, 8); + if (bitstream_read_bit(&s->bc)) + hc->simple_symbols[0] = bitstream_read(&s->bc, 8); else - hc->simple_symbols[0] = get_bits1(&s->gb); + hc->simple_symbols[0] = bitstream_read_bit(&s->bc); if (hc->nb_symbols == 2) - hc->simple_symbols[1] = get_bits(&s->gb, 8); + hc->simple_symbols[1] = bitstream_read(&s->bc, 8); hc->simple = 1; } @@ -359,13 +353,13 @@ static int read_huffman_code_normal(WebPContext *s, HuffReader *hc, int *code_lengths = NULL; int code_length_code_lengths[NUM_CODE_LENGTH_CODES] = { 0 }; int i, symbol, max_symbol, prev_code_len, ret; - int num_codes = 4 + get_bits(&s->gb, 4); + int num_codes = 4 + bitstream_read(&s->bc, 4); if (num_codes > NUM_CODE_LENGTH_CODES) return AVERROR_INVALIDDATA; for (i = 0; i < num_codes; i++) - code_length_code_lengths[code_length_code_order[i]] = get_bits(&s->gb, 3); + code_length_code_lengths[code_length_code_order[i]] = bitstream_read(&s->bc, 3); ret = huff_reader_build_canonical(&code_len_hc, code_length_code_lengths, NUM_CODE_LENGTH_CODES); @@ -378,9 +372,9 @@ static int read_huffman_code_normal(WebPContext *s, HuffReader *hc, goto finish; } - if (get_bits1(&s->gb)) { - int bits = 2 + 2 * get_bits(&s->gb, 3); - max_symbol = 2 + get_bits(&s->gb, bits); + if (bitstream_read_bit(&s->bc)) { + int bits = 2 + 2 * bitstream_read(&s->bc, 3); + max_symbol = 2 + bitstream_read(&s->bc, bits); if (max_symbol > alphabet_size) { av_log(s->avctx, AV_LOG_ERROR, "max symbol %d > alphabet size %d\n", max_symbol, alphabet_size); @@ -398,7 +392,7 @@ static int read_huffman_code_normal(WebPContext *s, HuffReader *hc, if (!max_symbol--) break; - code_len = huff_reader_get_symbol(&code_len_hc, &s->gb); + code_len = huff_reader_get_symbol(&code_len_hc, &s->bc); if (code_len < 16) { /* Code length code [0..15] indicates literal code lengths. */ code_lengths[symbol++] = code_len; @@ -411,18 +405,18 @@ static int read_huffman_code_normal(WebPContext *s, HuffReader *hc, /* Code 16 repeats the previous non-zero value [3..6] times, * i.e., 3 + ReadBits(2) times. If code 16 is used before a * non-zero value has been emitted, a value of 8 is repeated. */ - repeat = 3 + get_bits(&s->gb, 2); + repeat = 3 + bitstream_read(&s->bc, 2); length = prev_code_len; break; case 17: /* Code 17 emits a streak of zeros [3..10], i.e., * 3 + ReadBits(3) times. */ - repeat = 3 + get_bits(&s->gb, 3); + repeat = 3 + bitstream_read(&s->bc, 3); break; case 18: /* Code 18 emits a streak of zeros of length [11..138], i.e., * 11 + ReadBits(7) times. */ - repeat = 11 + get_bits(&s->gb, 7); + repeat = 11 + bitstream_read(&s->bc, 7); break; } if (symbol + repeat > alphabet_size) { @@ -449,7 +443,7 @@ static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role, int w, int h); #define PARSE_BLOCK_SIZE(w, h) do { \ - block_bits = get_bits(&s->gb, 3) + 2; \ + block_bits = bitstream_read(&s->bc, 3) + 2; \ blocks_w = FFALIGN((w), 1 << block_bits) >> block_bits; \ blocks_h = FFALIGN((h), 1 << block_bits) >> block_bits; \ } while (0) @@ -526,7 +520,7 @@ static int parse_transform_color_indexing(WebPContext *s) int width_bits, index_size, ret, x; uint8_t *ct; - index_size = get_bits(&s->gb, 8) + 1; + index_size = bitstream_read(&s->bc, 8) + 1; if (index_size <= 2) width_bits = 3; @@ -606,8 +600,8 @@ static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role, if (ret < 0) return ret; - if (get_bits1(&s->gb)) { - img->color_cache_bits = get_bits(&s->gb, 4); + if (bitstream_read_bit(&s->bc)) { + img->color_cache_bits = bitstream_read(&s->bc, 4); if (img->color_cache_bits < 1 || img->color_cache_bits > 11) { av_log(s->avctx, AV_LOG_ERROR, "invalid color cache bits: %d\n", img->color_cache_bits); @@ -622,7 +616,7 @@ static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role, } img->nb_huffman_groups = 1; - if (role == IMAGE_ROLE_ARGB && get_bits1(&s->gb)) { + if (role == IMAGE_ROLE_ARGB && bitstream_read_bit(&s->bc)) { ret = decode_entropy_image(s); if (ret < 0) return ret; @@ -641,7 +635,7 @@ static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role, if (!j && img->color_cache_bits > 0) alphabet_size += 1 << img->color_cache_bits; - if (get_bits1(&s->gb)) { + if (bitstream_read_bit(&s->bc)) { read_huffman_code_simple(s, &hg[j]); } else { ret = read_huffman_code_normal(s, &hg[j], alphabet_size); @@ -660,14 +654,14 @@ static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role, int v; hg = get_huffman_group(s, img, x, y); - v = huff_reader_get_symbol(&hg[HUFF_IDX_GREEN], &s->gb); + v = huff_reader_get_symbol(&hg[HUFF_IDX_GREEN], &s->bc); if (v < NUM_LITERAL_CODES) { /* literal pixel values */ uint8_t *p = GET_PIXEL(img->frame, x, y); p[2] = v; - p[1] = huff_reader_get_symbol(&hg[HUFF_IDX_RED], &s->gb); - p[3] = huff_reader_get_symbol(&hg[HUFF_IDX_BLUE], &s->gb); - p[0] = huff_reader_get_symbol(&hg[HUFF_IDX_ALPHA], &s->gb); + p[1] = huff_reader_get_symbol(&hg[HUFF_IDX_RED], &s->bc); + p[3] = huff_reader_get_symbol(&hg[HUFF_IDX_BLUE], &s->bc); + p[0] = huff_reader_get_symbol(&hg[HUFF_IDX_ALPHA], &s->bc); if (img->color_cache_bits) color_cache_put(img, AV_RB32(p)); x++; @@ -686,9 +680,9 @@ static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role, } else { int extra_bits = (prefix_code - 2) >> 1; int offset = 2 + (prefix_code & 1) << extra_bits; - length = offset + get_bits(&s->gb, extra_bits) + 1; + length = offset + bitstream_read(&s->bc, extra_bits) + 1; } - prefix_code = huff_reader_get_symbol(&hg[HUFF_IDX_DIST], &s->gb); + prefix_code = huff_reader_get_symbol(&hg[HUFF_IDX_DIST], &s->bc); if (prefix_code > 39) { av_log(s->avctx, AV_LOG_ERROR, "distance prefix code too large: %d\n", prefix_code); @@ -699,7 +693,7 @@ static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role, } else { int extra_bits = prefix_code - 2 >> 1; int offset = 2 + (prefix_code & 1) << extra_bits; - distance = offset + get_bits(&s->gb, extra_bits) + 1; + distance = offset + bitstream_read(&s->bc, extra_bits) + 1; } /* find reference location */ @@ -1034,7 +1028,7 @@ static int apply_color_indexing_transform(WebPContext *s) pal = &s->image[IMAGE_ROLE_COLOR_INDEXING]; if (pal->size_reduction > 0) { - GetBitContext gb_g; + BitstreamContext bc_g; uint8_t *line; int pixel_bits = 8 >> pal->size_reduction; @@ -1045,15 +1039,15 @@ static int apply_color_indexing_transform(WebPContext *s) for (y = 0; y < img->frame->height; y++) { p = GET_PIXEL(img->frame, 0, y); memcpy(line, p, img->frame->linesize[0]); - init_get_bits(&gb_g, line, img->frame->linesize[0] * 8); - skip_bits(&gb_g, 16); + bitstream_init(&bc_g, line, img->frame->linesize[0] * 8); + bitstream_skip(&bc_g, 16); i = 0; for (x = 0; x < img->frame->width; x++) { p = GET_PIXEL(img->frame, x, y); - p[2] = get_bits(&gb_g, pixel_bits); + p[2] = bitstream_read(&bc_g, pixel_bits); i++; if (i == 1 << pal->size_reduction) { - skip_bits(&gb_g, 24); + bitstream_skip(&bc_g, 24); i = 0; } } @@ -1089,18 +1083,18 @@ static int vp8_lossless_decode_frame(AVCodecContext *avctx, AVFrame *p, avctx->pix_fmt = AV_PIX_FMT_ARGB; } - ret = init_get_bits(&s->gb, data_start, data_size * 8); + ret = bitstream_init(&s->bc, data_start, data_size * 8); if (ret < 0) return ret; if (!is_alpha_chunk) { - if (get_bits(&s->gb, 8) != 0x2F) { + if (bitstream_read(&s->bc, 8) != 0x2F) { av_log(avctx, AV_LOG_ERROR, "Invalid WebP Lossless signature\n"); return AVERROR_INVALIDDATA; } - w = get_bits(&s->gb, 14) + 1; - h = get_bits(&s->gb, 14) + 1; + w = bitstream_read(&s->bc, 14) + 1; + h = bitstream_read(&s->bc, 14) + 1; if (s->width && s->width != w) { av_log(avctx, AV_LOG_WARNING, "Width mismatch. %d != %d\n", s->width, w); @@ -1116,9 +1110,9 @@ static int vp8_lossless_decode_frame(AVCodecContext *avctx, AVFrame *p, if (ret < 0) return ret; - s->has_alpha = get_bits1(&s->gb); + s->has_alpha = bitstream_read_bit(&s->bc); - if (get_bits(&s->gb, 3) != 0x0) { + if (bitstream_read(&s->bc, 3) != 0x0) { av_log(avctx, AV_LOG_ERROR, "Invalid WebP Lossless version\n"); return AVERROR_INVALIDDATA; } @@ -1133,8 +1127,8 @@ static int vp8_lossless_decode_frame(AVCodecContext *avctx, AVFrame *p, s->nb_transforms = 0; s->reduced_width = 0; used = 0; - while (get_bits1(&s->gb)) { - enum TransformType transform = get_bits(&s->gb, 2); + while (bitstream_read_bit(&s->bc)) { + enum TransformType transform = bitstream_read(&s->bc, 2); s->transforms[s->nb_transforms++] = transform; if (used & (1 << transform)) { av_log(avctx, AV_LOG_ERROR, "Transform %d used more than once\n", From f5b7bd2a7c3f3498119f7c4484962e15e8f2ad26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sun, 10 Apr 2016 12:24:42 +0200 Subject: [PATCH 0639/3374] imc: Convert to the new bitstream reader --- libavcodec/imc.c | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/libavcodec/imc.c b/libavcodec/imc.c index 9a6912dc13278..01ab0125f2cca 100644 --- a/libavcodec/imc.c +++ b/libavcodec/imc.c @@ -37,9 +37,10 @@ #include "libavutil/channel_layout.h" #include "libavutil/float_dsp.h" #include "libavutil/internal.h" + #include "avcodec.h" +#include "bitstream.h" #include "bswapdsp.h" -#include "get_bits.h" #include "fft.h" #include "internal.h" #include "sinewin.h" @@ -91,7 +92,7 @@ typedef struct IMCContext { //@} float sqrt_tab[30]; - GetBitContext gb; + BitstreamContext bc; BswapDSPContext bdsp; AVFloatDSPContext fdsp; @@ -328,12 +329,12 @@ static void imc_read_level_coeffs(IMCContext *q, int stream_format_code, if (stream_format_code & 4) start = 1; if (start) - levlCoeffs[0] = get_bits(&q->gb, 7); + levlCoeffs[0] = bitstream_read(&q->bc, 7); for (i = start; i < BANDS; i++) { - levlCoeffs[i] = get_vlc2(&q->gb, hufftab[cb_sel[i]]->table, - hufftab[cb_sel[i]]->bits, 2); + levlCoeffs[i] = bitstream_read_vlc(&q->bc, hufftab[cb_sel[i]]->table, + hufftab[cb_sel[i]]->bits, 2); if (levlCoeffs[i] == 17) - levlCoeffs[i] += get_bits(&q->gb, 4); + levlCoeffs[i] += bitstream_read(&q->bc, 4); } } @@ -342,10 +343,10 @@ static void imc_read_level_coeffs_raw(IMCContext *q, int stream_format_code, { int i; - q->coef0_pos = get_bits(&q->gb, 5); - levlCoeffs[0] = get_bits(&q->gb, 7); + q->coef0_pos = bitstream_read(&q->bc, 5); + levlCoeffs[0] = bitstream_read(&q->bc, 7); for (i = 1; i < BANDS; i++) - levlCoeffs[i] = get_bits(&q->gb, 4); + levlCoeffs[i] = bitstream_read(&q->bc, 4); } static void imc_decode_level_coefficients(IMCContext *q, int *levlCoeffBuf, @@ -612,19 +613,19 @@ static void imc_get_skip_coeff(IMCContext *q, IMCChannel *chctx) chctx->skipFlagBits[i] = band_tab[i + 1] - band_tab[i]; for (j = band_tab[i]; j < band_tab[i + 1]; j++) { - chctx->skipFlags[j] = get_bits1(&q->gb); + chctx->skipFlags[j] = bitstream_read_bit(&q->bc); if (chctx->skipFlags[j]) chctx->skipFlagCount[i]++; } } else { for (j = band_tab[i]; j < band_tab[i + 1] - 1; j += 2) { - if (!get_bits1(&q->gb)) { // 0 + if (!bitstream_read_bit(&q->bc)) { // 0 chctx->skipFlagBits[i]++; chctx->skipFlags[j] = 1; chctx->skipFlags[j + 1] = 1; chctx->skipFlagCount[i] += 2; } else { - if (get_bits1(&q->gb)) { // 11 + if (bitstream_read_bit(&q->bc)) { // 11 chctx->skipFlagBits[i] += 2; chctx->skipFlags[j] = 0; chctx->skipFlags[j + 1] = 1; @@ -632,7 +633,7 @@ static void imc_get_skip_coeff(IMCContext *q, IMCChannel *chctx) } else { chctx->skipFlagBits[i] += 3; chctx->skipFlags[j + 1] = 0; - if (!get_bits1(&q->gb)) { // 100 + if (!bitstream_read_bit(&q->bc)) { // 100 chctx->skipFlags[j] = 1; chctx->skipFlagCount[i]++; } else { // 101 @@ -644,7 +645,7 @@ static void imc_get_skip_coeff(IMCContext *q, IMCChannel *chctx) if (j < band_tab[i + 1]) { chctx->skipFlagBits[i]++; - if ((chctx->skipFlags[j] = get_bits1(&q->gb))) + if ((chctx->skipFlags[j] = bitstream_read_bit(&q->bc))) chctx->skipFlagCount[i]++; } } @@ -781,13 +782,13 @@ static int imc_get_coeffs(IMCContext *q, IMCChannel *chctx) cw_len = chctx->CWlengthT[j]; cw = 0; - if (get_bits_count(&q->gb) + cw_len > 512) { + if (bitstream_tell(&q->bc) + cw_len > 512) { ff_dlog(NULL, "Band %i coeff %i cw_len %i\n", i, j, cw_len); return AVERROR_INVALIDDATA; } if (cw_len && (!chctx->bandFlagsBuf[i] || !chctx->skipFlags[j])) - cw = get_bits(&q->gb, cw_len); + cw = bitstream_read(&q->bc, cw_len); chctx->codewords[j] = cw; } @@ -851,13 +852,13 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch) /* Check the frame header */ - imc_hdr = get_bits(&q->gb, 9); + imc_hdr = bitstream_read(&q->bc, 9); if (imc_hdr & 0x18) { av_log(avctx, AV_LOG_ERROR, "frame header check failed!\n"); av_log(avctx, AV_LOG_ERROR, "got %X.\n", imc_hdr); return AVERROR_INVALIDDATA; } - stream_format_code = get_bits(&q->gb, 3); + stream_format_code = bitstream_read(&q->bc, 3); if (stream_format_code & 0x04) chctx->decoder_reset = 1; @@ -870,7 +871,7 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch) chctx->decoder_reset = 0; } - flag = get_bits1(&q->gb); + flag = bitstream_read_bit(&q->bc); if (stream_format_code & 0x1) imc_read_level_coeffs_raw(q, stream_format_code, chctx->levlCoeffBuf); else @@ -908,7 +909,7 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch) memset(chctx->bandFlagsBuf, 0, BANDS * sizeof(int)); for (i = 0; i < BANDS - 1; i++) if (chctx->bandWidthT[i]) - chctx->bandFlagsBuf[i] = get_bits1(&q->gb); + chctx->bandFlagsBuf[i] = bitstream_read_bit(&q->bc); imc_calculate_coeffs(q, chctx->flcoeffs1, chctx->flcoeffs2, chctx->bandWidthT, chctx->flcoeffs3, @@ -943,7 +944,7 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch) } if ((ret = bit_allocation(q, chctx, stream_format_code, - 512 - bitscount - get_bits_count(&q->gb), + 512 - bitscount - bitstream_tell(&q->bc), flag)) < 0) { av_log(avctx, AV_LOG_ERROR, "Bit allocations failed\n"); chctx->decoder_reset = 1; @@ -1015,7 +1016,7 @@ static int imc_decode_frame(AVCodecContext *avctx, void *data, q->bdsp.bswap16_buf(buf16, (const uint16_t *) buf, IMC_BLOCK_SIZE / 2); - init_get_bits(&q->gb, (const uint8_t*)buf16, IMC_BLOCK_SIZE * 8); + bitstream_init(&q->bc, (const uint8_t*)buf16, IMC_BLOCK_SIZE * 8); buf += IMC_BLOCK_SIZE; From c3defda0d80e19146e71c7adbdfd9c251f36d8bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Mon, 18 Apr 2016 10:49:08 +0200 Subject: [PATCH 0640/3374] indeo: Convert to the new bitstream reader --- libavcodec/indeo2.c | 16 ++--- libavcodec/indeo3.c | 19 +++--- libavcodec/indeo4.c | 158 +++++++++++++++++++++++--------------------- libavcodec/indeo5.c | 127 ++++++++++++++++++----------------- libavcodec/ivi.c | 71 ++++++++++---------- libavcodec/ivi.h | 11 +-- 6 files changed, 206 insertions(+), 196 deletions(-) diff --git a/libavcodec/indeo2.c b/libavcodec/indeo2.c index 3154e2314c422..de2a9bb2f1293 100644 --- a/libavcodec/indeo2.c +++ b/libavcodec/indeo2.c @@ -28,7 +28,7 @@ #define BITSTREAM_READER_LE #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "indeo2data.h" #include "internal.h" #include "mathops.h" @@ -36,7 +36,7 @@ typedef struct Ir2Context{ AVCodecContext *avctx; AVFrame *picture; - GetBitContext gb; + BitstreamContext bc; int decode_delta; } Ir2Context; @@ -44,9 +44,9 @@ typedef struct Ir2Context{ static VLC ir2_vlc; /* Indeo 2 codes are in range 0x01..0x7F and 0x81..0x90 */ -static inline int ir2_get_code(GetBitContext *gb) +static inline int ir2_get_code(BitstreamContext *bc) { - return get_vlc2(gb, ir2_vlc.table, CODE_VLC_BITS, 1) + 1; + return bitstream_read_vlc(bc, ir2_vlc.table, CODE_VLC_BITS, 1) + 1; } static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst, @@ -63,7 +63,7 @@ static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst /* first line contain absolute values, other lines contain deltas */ while (out < width) { - c = ir2_get_code(&ctx->gb); + c = ir2_get_code(&ctx->bc); if (c >= 0x80) { /* we have a run */ c -= 0x7F; if (out + c*2 > width) @@ -80,7 +80,7 @@ static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst for (j = 1; j < height; j++) { out = 0; while (out < width) { - c = ir2_get_code(&ctx->gb); + c = ir2_get_code(&ctx->bc); if (c >= 0x80) { /* we have a skip */ c -= 0x7F; if (out + c*2 > width) @@ -119,7 +119,7 @@ static int ir2_decode_plane_inter(Ir2Context *ctx, int width, int height, uint8_ for (j = 0; j < height; j++) { out = 0; while (out < width) { - c = ir2_get_code(&ctx->gb); + c = ir2_get_code(&ctx->bc); if (c >= 0x80) { /* we have a skip */ c -= 0x7F; out += c * 2; @@ -171,7 +171,7 @@ static int ir2_decode_frame(AVCodecContext *avctx, buf[i] = ff_reverse[buf[i]]; #endif - init_get_bits(&s->gb, buf + start, (buf_size - start) * 8); + bitstream_init(&s->bc, buf + start, (buf_size - start) * 8); ltab = buf[0x22] & 3; ctab = buf[0x22] >> 2; diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c index 314548f99aba5..1b5b6505d67dc 100644 --- a/libavcodec/indeo3.c +++ b/libavcodec/indeo3.c @@ -31,9 +31,10 @@ #include "libavutil/imgutils.h" #include "libavutil/intreadwrite.h" + #include "avcodec.h" +#include "bitstream.h" #include "bytestream.h" -#include "get_bits.h" #include "hpeldsp.h" #include "internal.h" @@ -83,7 +84,7 @@ typedef struct Indeo3DecodeContext { AVCodecContext *avctx; HpelDSPContext hdsp; - GetBitContext gb; + BitstreamContext bc; int need_resync; int skip_bits; const uint8_t *next_cell_data; @@ -725,8 +726,8 @@ enum { ctx->need_resync = 1 #define RESYNC_BITSTREAM \ - if (ctx->need_resync && !(get_bits_count(&ctx->gb) & 7)) { \ - skip_bits_long(&ctx->gb, ctx->skip_bits); \ + if (ctx->need_resync && !(bitstream_tell(&ctx->bc) & 7)) { \ + bitstream_skip(&ctx->bc, ctx->skip_bits); \ ctx->skip_bits = 0; \ ctx->need_resync = 0; \ } @@ -773,7 +774,7 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, while (1) { /* loop until return */ RESYNC_BITSTREAM; - switch (code = get_bits(&ctx->gb, 2)) { + switch (code = bitstream_read(&ctx->bc, 2)) { case H_SPLIT: case V_SPLIT: if (parse_bintree(ctx, avctx, plane, code, &curr_cell, depth - 1, strip_width)) @@ -785,7 +786,7 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, curr_cell.tree = 1; /* enter the VQ tree */ } else { /* VQ tree NULL code */ RESYNC_BITSTREAM; - code = get_bits(&ctx->gb, 2); + code = bitstream_read(&ctx->bc, 2); if (code >= 2) { av_log(avctx, AV_LOG_ERROR, "Invalid VQ_NULL code: %d\n", code); return AVERROR_INVALIDDATA; @@ -805,7 +806,7 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, unsigned mv_idx; /* get motion vector index and setup the pointer to the mv set */ if (!ctx->need_resync) - ctx->next_cell_data = &ctx->gb.buffer[(get_bits_count(&ctx->gb) + 7) >> 3]; + ctx->next_cell_data = &ctx->bc.buffer[(bitstream_tell(&ctx->bc) + 7) >> 3]; mv_idx = *(ctx->next_cell_data++); if (mv_idx >= ctx->num_vectors) { av_log(avctx, AV_LOG_ERROR, "motion vector index out of range\n"); @@ -816,7 +817,7 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, UPDATE_BITPOS(8); } else { /* VQ tree DATA code */ if (!ctx->need_resync) - ctx->next_cell_data = &ctx->gb.buffer[(get_bits_count(&ctx->gb) + 7) >> 3]; + ctx->next_cell_data = &ctx->bc.buffer[(bitstream_tell(&ctx->bc) + 7) >> 3]; CHECK_CELL bytes_used = decode_cell(ctx, avctx, plane, &curr_cell, @@ -856,7 +857,7 @@ static int decode_plane(Indeo3DecodeContext *ctx, AVCodecContext *avctx, ctx->mc_vectors = num_vectors ? data : 0; /* init the bitreader */ - init_get_bits(&ctx->gb, &data[num_vectors * 2], (data_size - num_vectors * 2) << 3); + bitstream_init(&ctx->bc, &data[num_vectors * 2], (data_size - num_vectors * 2) << 3); ctx->skip_bits = 0; ctx->need_resync = 0; diff --git a/libavcodec/indeo4.c b/libavcodec/indeo4.c index ab42e7bca9ed9..4b3f903e3b67e 100644 --- a/libavcodec/indeo4.c +++ b/libavcodec/indeo4.c @@ -29,7 +29,7 @@ #define BITSTREAM_READER_LE #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "indeo4data.h" #include "internal.h" #include "ivi.h" @@ -70,19 +70,19 @@ static const struct { * - 4 wavelet bands per plane, size factor 1:4, code pattern: 2,3,3,3,3 * Anything else is either unsupported or corrupt. * - * @param[in,out] gb the GetBit context + * @param[in,out] bc the Bitstream context * @return number of wavelet bands or 0 on error */ -static int decode_plane_subdivision(GetBitContext *gb) +static int decode_plane_subdivision(BitstreamContext *bc) { int i; - switch (get_bits(gb, 2)) { + switch (bitstream_read(bc, 2)) { case 3: return 1; case 2: for (i = 0; i < 4; i++) - if (get_bits(gb, 2) != 3) + if (bitstream_read(bc, 2) != 3) return 0; return 4; default: @@ -107,13 +107,13 @@ static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx) int pic_size_indx, i, p; IVIPicConfig pic_conf; - if (get_bits(&ctx->gb, 18) != 0x3FFF8) { + if (bitstream_read(&ctx->bc, 18) != 0x3FFF8) { av_log(avctx, AV_LOG_ERROR, "Invalid picture start code!\n"); return AVERROR_INVALIDDATA; } ctx->prev_frame_type = ctx->frame_type; - ctx->frame_type = get_bits(&ctx->gb, 3); + ctx->frame_type = bitstream_read(&ctx->bc, 3); if (ctx->frame_type == 7) { av_log(avctx, AV_LOG_ERROR, "Invalid frame type: %d\n", ctx->frame_type); return AVERROR_INVALIDDATA; @@ -122,15 +122,15 @@ static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx) if (ctx->frame_type == IVI4_FRAMETYPE_BIDIR) ctx->has_b_frames = 1; - ctx->has_transp = get_bits1(&ctx->gb); + ctx->has_transp = bitstream_read_bit(&ctx->bc); /* unknown bit: Mac decoder ignores this bit, XANIM returns error */ - if (get_bits1(&ctx->gb)) { + if (bitstream_read_bit(&ctx->bc)) { av_log(avctx, AV_LOG_ERROR, "Sync bit is set!\n"); return AVERROR_INVALIDDATA; } - ctx->data_size = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 24) : 0; + ctx->data_size = bitstream_read_bit(&ctx->bc) ? bitstream_read(&ctx->bc, 24) : 0; /* null frames don't contain anything else so we just return */ if (ctx->frame_type >= IVI4_FRAMETYPE_NULL_FIRST) { @@ -141,32 +141,32 @@ static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx) /* Check key lock status. If enabled - ignore lock word. */ /* Usually we have to prompt the user for the password, but */ /* we don't do that because Indeo 4 videos can be decoded anyway */ - if (get_bits1(&ctx->gb)) { - skip_bits_long(&ctx->gb, 32); + if (bitstream_read_bit(&ctx->bc)) { + bitstream_skip(&ctx->bc, 32); ff_dlog(avctx, "Password-protected clip!\n"); } - pic_size_indx = get_bits(&ctx->gb, 3); + pic_size_indx = bitstream_read(&ctx->bc, 3); if (pic_size_indx == IVI4_PIC_SIZE_ESC) { - pic_conf.pic_height = get_bits(&ctx->gb, 16); - pic_conf.pic_width = get_bits(&ctx->gb, 16); + pic_conf.pic_height = bitstream_read(&ctx->bc, 16); + pic_conf.pic_width = bitstream_read(&ctx->bc, 16); } else { pic_conf.pic_height = ivi4_common_pic_sizes[pic_size_indx * 2 + 1]; pic_conf.pic_width = ivi4_common_pic_sizes[pic_size_indx * 2 ]; } /* Decode tile dimensions. */ - ctx->uses_tiling = get_bits1(&ctx->gb); + ctx->uses_tiling = bitstream_read_bit(&ctx->bc); if (ctx->uses_tiling) { - pic_conf.tile_height = scale_tile_size(pic_conf.pic_height, get_bits(&ctx->gb, 4)); - pic_conf.tile_width = scale_tile_size(pic_conf.pic_width, get_bits(&ctx->gb, 4)); + pic_conf.tile_height = scale_tile_size(pic_conf.pic_height, bitstream_read(&ctx->bc, 4)); + pic_conf.tile_width = scale_tile_size(pic_conf.pic_width, bitstream_read(&ctx->bc, 4)); } else { pic_conf.tile_height = pic_conf.pic_height; pic_conf.tile_width = pic_conf.pic_width; } /* Decode chroma subsampling. We support only 4:4 aka YVU9. */ - if (get_bits(&ctx->gb, 2)) { + if (bitstream_read(&ctx->bc, 2)) { av_log(avctx, AV_LOG_ERROR, "Only YVU9 picture format is supported!\n"); return AVERROR_INVALIDDATA; } @@ -174,9 +174,9 @@ static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx) pic_conf.chroma_width = (pic_conf.pic_width + 3) >> 2; /* decode subdivision of the planes */ - pic_conf.luma_bands = decode_plane_subdivision(&ctx->gb); + pic_conf.luma_bands = decode_plane_subdivision(&ctx->bc); if (pic_conf.luma_bands) - pic_conf.chroma_bands = decode_plane_subdivision(&ctx->gb); + pic_conf.chroma_bands = decode_plane_subdivision(&ctx->bc); ctx->is_scalable = pic_conf.luma_bands != 1 || pic_conf.chroma_bands != 1; if (ctx->is_scalable && (pic_conf.luma_bands != 4 || pic_conf.chroma_bands != 1)) { av_log(avctx, AV_LOG_ERROR, "Scalability: unsupported subdivision! Luma bands: %d, chroma bands: %d\n", @@ -210,40 +210,40 @@ static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx) } } - ctx->frame_num = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 20) : 0; + ctx->frame_num = bitstream_read_bit(&ctx->bc) ? bitstream_read(&ctx->bc, 20) : 0; /* skip decTimeEst field if present */ - if (get_bits1(&ctx->gb)) - skip_bits(&ctx->gb, 8); + if (bitstream_read_bit(&ctx->bc)) + bitstream_skip(&ctx->bc, 8); /* decode macroblock and block huffman codebooks */ - if (ff_ivi_dec_huff_desc(&ctx->gb, get_bits1(&ctx->gb), IVI_MB_HUFF, &ctx->mb_vlc, avctx) || - ff_ivi_dec_huff_desc(&ctx->gb, get_bits1(&ctx->gb), IVI_BLK_HUFF, &ctx->blk_vlc, avctx)) + if (ff_ivi_dec_huff_desc(&ctx->bc, bitstream_read_bit(&ctx->bc), IVI_MB_HUFF, &ctx->mb_vlc, avctx) || + ff_ivi_dec_huff_desc(&ctx->bc, bitstream_read_bit(&ctx->bc), IVI_BLK_HUFF, &ctx->blk_vlc, avctx)) return AVERROR_INVALIDDATA; - ctx->rvmap_sel = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 3) : 8; + ctx->rvmap_sel = bitstream_read_bit(&ctx->bc) ? bitstream_read(&ctx->bc, 3) : 8; - ctx->in_imf = get_bits1(&ctx->gb); - ctx->in_q = get_bits1(&ctx->gb); + ctx->in_imf = bitstream_read_bit(&ctx->bc); + ctx->in_q = bitstream_read_bit(&ctx->bc); - ctx->pic_glob_quant = get_bits(&ctx->gb, 5); + ctx->pic_glob_quant = bitstream_read(&ctx->bc, 5); /* TODO: ignore this parameter if unused */ - ctx->unknown1 = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 3) : 0; + ctx->unknown1 = bitstream_read_bit(&ctx->bc) ? bitstream_read(&ctx->bc, 3) : 0; - ctx->checksum = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 16) : 0; + ctx->checksum = bitstream_read_bit(&ctx->bc) ? bitstream_read(&ctx->bc, 16) : 0; /* skip picture header extension if any */ - while (get_bits1(&ctx->gb)) { + while (bitstream_read_bit(&ctx->bc)) { ff_dlog(avctx, "Pic hdr extension encountered!\n"); - skip_bits(&ctx->gb, 8); + bitstream_skip(&ctx->bc, 8); } - if (get_bits1(&ctx->gb)) { + if (bitstream_read_bit(&ctx->bc)) { av_log(avctx, AV_LOG_ERROR, "Bad blocks bits encountered!\n"); } - align_get_bits(&ctx->gb); + bitstream_align(&ctx->bc); return 0; } @@ -263,22 +263,22 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, int plane, band_num, indx, transform_id, scan_indx; int i; - plane = get_bits(&ctx->gb, 2); - band_num = get_bits(&ctx->gb, 4); + plane = bitstream_read(&ctx->bc, 2); + band_num = bitstream_read(&ctx->bc, 4); if (band->plane != plane || band->band_num != band_num) { av_log(avctx, AV_LOG_ERROR, "Invalid band header sequence!\n"); return AVERROR_INVALIDDATA; } - band->is_empty = get_bits1(&ctx->gb); + band->is_empty = bitstream_read_bit(&ctx->bc); if (!band->is_empty) { int old_blk_size = band->blk_size; /* skip header size * If header size is not given, header size is 4 bytes. */ - if (get_bits1(&ctx->gb)) - skip_bits(&ctx->gb, 16); + if (bitstream_read_bit(&ctx->bc)) + bitstream_skip(&ctx->bc, 16); - band->is_halfpel = get_bits(&ctx->gb, 2); + band->is_halfpel = bitstream_read(&ctx->bc, 2); if (band->is_halfpel >= 2) { av_log(avctx, AV_LOG_ERROR, "Invalid/unsupported mv resolution: %d!\n", band->is_halfpel); @@ -287,11 +287,11 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, if (!band->is_halfpel) ctx->uses_fullpel = 1; - band->checksum_present = get_bits1(&ctx->gb); + band->checksum_present = bitstream_read_bit(&ctx->bc); if (band->checksum_present) - band->checksum = get_bits(&ctx->gb, 16); + band->checksum = bitstream_read(&ctx->bc, 16); - indx = get_bits(&ctx->gb, 2); + indx = bitstream_read(&ctx->bc, 2); if (indx == 3) { av_log(avctx, AV_LOG_ERROR, "Invalid block size!\n"); return AVERROR_INVALIDDATA; @@ -299,13 +299,13 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, band->mb_size = 16 >> indx; band->blk_size = 8 >> (indx >> 1); - band->inherit_mv = get_bits1(&ctx->gb); - band->inherit_qdelta = get_bits1(&ctx->gb); + band->inherit_mv = bitstream_read_bit(&ctx->bc); + band->inherit_qdelta = bitstream_read_bit(&ctx->bc); - band->glob_quant = get_bits(&ctx->gb, 5); + band->glob_quant = bitstream_read(&ctx->bc, 5); - if (!get_bits1(&ctx->gb) || ctx->frame_type == IVI4_FRAMETYPE_INTRA) { - transform_id = get_bits(&ctx->gb, 5); + if (!bitstream_read_bit(&ctx->bc) || ctx->frame_type == IVI4_FRAMETYPE_INTRA) { + transform_id = bitstream_read(&ctx->bc, 5); if (transform_id >= FF_ARRAY_ELEMS(transforms) || !transforms[transform_id].inv_trans) { avpriv_request_sample(avctx, "Transform %d", transform_id); @@ -331,7 +331,7 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, if (band->blk_size != band->transform_size) return AVERROR_INVALIDDATA; - scan_indx = get_bits(&ctx->gb, 4); + scan_indx = bitstream_read(&ctx->bc, 4); if (scan_indx == 15) { av_log(avctx, AV_LOG_ERROR, "Custom scan pattern encountered!\n"); return AVERROR_INVALIDDATA; @@ -344,7 +344,7 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, band->scan = scan_index_to_tab[scan_indx]; - band->quant_mat = get_bits(&ctx->gb, 5); + band->quant_mat = bitstream_read(&ctx->bc, 5); if (band->quant_mat >= FF_ARRAY_ELEMS(quant_index_to_tab)) { if (band->quant_mat == 31) @@ -370,20 +370,20 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, } /* decode block huffman codebook */ - if (!get_bits1(&ctx->gb)) + if (!bitstream_read_bit(&ctx->bc)) band->blk_vlc.tab = ctx->blk_vlc.tab; else - if (ff_ivi_dec_huff_desc(&ctx->gb, 1, IVI_BLK_HUFF, + if (ff_ivi_dec_huff_desc(&ctx->bc, 1, IVI_BLK_HUFF, &band->blk_vlc, avctx)) return AVERROR_INVALIDDATA; /* select appropriate rvmap table for this band */ - band->rvmap_sel = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 3) : 8; + band->rvmap_sel = bitstream_read_bit(&ctx->bc) ? bitstream_read(&ctx->bc, 3) : 8; /* decode rvmap probability corrections if any */ band->num_corr = 0; /* there is no corrections */ - if (get_bits1(&ctx->gb)) { - band->num_corr = get_bits(&ctx->gb, 8); /* get number of correction pairs */ + if (bitstream_read_bit(&ctx->bc)) { + band->num_corr = bitstream_read(&ctx->bc, 8); /* get number of correction pairs */ if (band->num_corr > 61) { av_log(avctx, AV_LOG_ERROR, "Too many corrections: %d\n", band->num_corr); @@ -392,7 +392,7 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, /* read correction pairs */ for (i = 0; i < band->num_corr * 2; i++) - band->corr[i] = get_bits(&ctx->gb, 8); + band->corr[i] = bitstream_read(&ctx->bc, 8); } } @@ -408,7 +408,7 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, band->intra_scale = NULL; band->inter_scale = NULL; - align_get_bits(&ctx->gb); + bitstream_align(&ctx->bc); return 0; } @@ -453,7 +453,7 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, mb->b_mv_x = mb->b_mv_y = 0; - if (get_bits1(&ctx->gb)) { + if (bitstream_read_bit(&ctx->bc)) { if (ctx->frame_type == IVI4_FRAMETYPE_INTRA) { av_log(avctx, AV_LOG_ERROR, "Empty macroblock in an INTRA picture!\n"); return AVERROR_INVALIDDATA; @@ -463,8 +463,9 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, mb->q_delta = 0; if (!band->plane && !band->band_num && ctx->in_q) { - mb->q_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table, - IVI_VLC_BITS, 1); + mb->q_delta = bitstream_read_vlc(&ctx->bc, + ctx->mb_vlc.tab->table, + IVI_VLC_BITS, 1); mb->q_delta = IVI_TOSIGNED(mb->q_delta); } @@ -489,18 +490,19 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, ctx->frame_type == IVI4_FRAMETYPE_INTRA1) { mb->type = 0; /* mb_type is always INTRA for intra-frames */ } else { - mb->type = get_bits(&ctx->gb, mb_type_bits); + mb->type = bitstream_read(&ctx->bc, mb_type_bits); } - mb->cbp = get_bits(&ctx->gb, blks_per_mb); + mb->cbp = bitstream_read(&ctx->bc, blks_per_mb); mb->q_delta = 0; if (band->inherit_qdelta) { if (ref_mb) mb->q_delta = ref_mb->q_delta; } else if (mb->cbp || (!band->plane && !band->band_num && ctx->in_q)) { - mb->q_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table, - IVI_VLC_BITS, 1); + mb->q_delta = bitstream_read_vlc(&ctx->bc, + ctx->mb_vlc.tab->table, + IVI_VLC_BITS, 1); mb->q_delta = IVI_TOSIGNED(mb->q_delta); } @@ -519,22 +521,24 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, } } else { /* decode motion vector deltas */ - mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table, - IVI_VLC_BITS, 1); + mv_delta = bitstream_read_vlc(&ctx->bc, + ctx->mb_vlc.tab->table, + IVI_VLC_BITS, 1); mv_y += IVI_TOSIGNED(mv_delta); - mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table, - IVI_VLC_BITS, 1); + mv_delta = bitstream_read_vlc(&ctx->bc, + ctx->mb_vlc.tab->table, + IVI_VLC_BITS, 1); mv_x += IVI_TOSIGNED(mv_delta); mb->mv_x = mv_x; mb->mv_y = mv_y; if (mb->type == 3) { - mv_delta = get_vlc2(&ctx->gb, - ctx->mb_vlc.tab->table, - IVI_VLC_BITS, 1); + mv_delta = bitstream_read_vlc(&ctx->bc, + ctx->mb_vlc.tab->table, + IVI_VLC_BITS, 1); mv_y += IVI_TOSIGNED(mv_delta); - mv_delta = get_vlc2(&ctx->gb, - ctx->mb_vlc.tab->table, - IVI_VLC_BITS, 1); + mv_delta = bitstream_read_vlc(&ctx->bc, + ctx->mb_vlc.tab->table, + IVI_VLC_BITS, 1); mv_x += IVI_TOSIGNED(mv_delta); mb->b_mv_x = -mv_x; mb->b_mv_y = -mv_y; @@ -558,7 +562,7 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, offs += row_offset; } - align_get_bits(&ctx->gb); + bitstream_align(&ctx->bc); return 0; } diff --git a/libavcodec/indeo5.c b/libavcodec/indeo5.c index bed915370ad1c..70ae1d324b506 100644 --- a/libavcodec/indeo5.c +++ b/libavcodec/indeo5.c @@ -29,7 +29,7 @@ #define BITSTREAM_READER_LE #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "ivi.h" #include "ivi_dsp.h" #include "indeo5data.h" @@ -63,14 +63,14 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) IVIBandDesc *band, *band1, *band2; IVIPicConfig pic_conf; - ctx->gop_flags = get_bits(&ctx->gb, 8); + ctx->gop_flags = bitstream_read(&ctx->bc, 8); - ctx->gop_hdr_size = (ctx->gop_flags & 1) ? get_bits(&ctx->gb, 16) : 0; + ctx->gop_hdr_size = (ctx->gop_flags & 1) ? bitstream_read(&ctx->bc, 16) : 0; if (ctx->gop_flags & IVI5_IS_PROTECTED) - ctx->lock_word = get_bits_long(&ctx->gb, 32); + ctx->lock_word = bitstream_read(&ctx->bc, 32); - tile_size = (ctx->gop_flags & 0x40) ? 64 << get_bits(&ctx->gb, 2) : 0; + tile_size = (ctx->gop_flags & 0x40) ? 64 << bitstream_read(&ctx->bc, 2) : 0; if (tile_size > 256) { av_log(avctx, AV_LOG_ERROR, "Invalid tile size: %d\n", tile_size); return AVERROR_INVALIDDATA; @@ -78,8 +78,8 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) /* decode number of wavelet bands */ /* num_levels * 3 + 1 */ - pic_conf.luma_bands = get_bits(&ctx->gb, 2) * 3 + 1; - pic_conf.chroma_bands = get_bits1(&ctx->gb) * 3 + 1; + pic_conf.luma_bands = bitstream_read(&ctx->bc, 2) * 3 + 1; + pic_conf.chroma_bands = bitstream_read_bit(&ctx->bc) * 3 + 1; ctx->is_scalable = pic_conf.luma_bands != 1 || pic_conf.chroma_bands != 1; if (ctx->is_scalable && (pic_conf.luma_bands != 4 || pic_conf.chroma_bands != 1)) { av_log(avctx, AV_LOG_ERROR, "Scalability: unsupported subdivision! Luma bands: %d, chroma bands: %d\n", @@ -87,10 +87,10 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) return AVERROR_INVALIDDATA; } - pic_size_indx = get_bits(&ctx->gb, 4); + pic_size_indx = bitstream_read(&ctx->bc, 4); if (pic_size_indx == IVI5_PIC_SIZE_ESC) { - pic_conf.pic_height = get_bits(&ctx->gb, 13); - pic_conf.pic_width = get_bits(&ctx->gb, 13); + pic_conf.pic_height = bitstream_read(&ctx->bc, 13); + pic_conf.pic_width = bitstream_read(&ctx->bc, 13); } else { pic_conf.pic_height = ivi5_common_pic_sizes[pic_size_indx * 2 + 1] << 2; pic_conf.pic_width = ivi5_common_pic_sizes[pic_size_indx * 2 ] << 2; @@ -126,10 +126,10 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) for (i = 0; i < (!p ? pic_conf.luma_bands : pic_conf.chroma_bands); i++) { band = &ctx->planes[p].bands[i]; - band->is_halfpel = get_bits1(&ctx->gb); + band->is_halfpel = bitstream_read_bit(&ctx->bc); - mb_size = get_bits1(&ctx->gb); - blk_size = 8 >> get_bits1(&ctx->gb); + mb_size = bitstream_read_bit(&ctx->bc); + blk_size = 8 >> bitstream_read_bit(&ctx->bc); mb_size = blk_size << !mb_size; blk_size_changed = mb_size != band->mb_size || blk_size != band->blk_size; @@ -138,7 +138,7 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) band->blk_size = blk_size; } - if (get_bits1(&ctx->gb)) { + if (bitstream_read_bit(&ctx->bc)) { avpriv_report_missing_feature(avctx, "Extended transform info"); return AVERROR_PATCHWELCOME; } @@ -206,7 +206,7 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) band->inter_scale = ivi5_scale_quant_4x4_inter; } - if (get_bits(&ctx->gb, 2)) { + if (bitstream_read(&ctx->bc, 2)) { av_log(avctx, AV_LOG_ERROR, "End marker missing!\n"); return AVERROR_INVALIDDATA; } @@ -245,27 +245,27 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) } if (ctx->gop_flags & 8) { - if (get_bits(&ctx->gb, 3)) { + if (bitstream_read(&ctx->bc, 3)) { av_log(avctx, AV_LOG_ERROR, "Alignment bits are not zero!\n"); return AVERROR_INVALIDDATA; } - if (get_bits1(&ctx->gb)) - skip_bits_long(&ctx->gb, 24); /* skip transparency fill color */ + if (bitstream_read_bit(&ctx->bc)) + bitstream_skip(&ctx->bc, 24); /* skip transparency fill color */ } - align_get_bits(&ctx->gb); + bitstream_align(&ctx->bc); - skip_bits(&ctx->gb, 23); /* FIXME: unknown meaning */ + bitstream_skip(&ctx->bc, 23); /* FIXME: unknown meaning */ /* skip GOP extension if any */ - if (get_bits1(&ctx->gb)) { + if (bitstream_read_bit(&ctx->bc)) { do { - i = get_bits(&ctx->gb, 16); + i = bitstream_read(&ctx->bc, 16); } while (i & 0x8000); } - align_get_bits(&ctx->gb); + bitstream_align(&ctx->bc); return 0; } @@ -274,15 +274,16 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) /** * Skip a header extension. * - * @param[in,out] gb the GetBit context + * @param[in,out] bc the Bitstream context */ -static inline void skip_hdr_extension(GetBitContext *gb) +static inline void skip_hdr_extension(BitstreamContext *bc) { int i, len; do { - len = get_bits(gb, 8); - for (i = 0; i < len; i++) skip_bits(gb, 8); + len = bitstream_read(bc, 8); + for (i = 0; i < len; i++) + bitstream_skip(bc, 8); } while(len); } @@ -298,19 +299,19 @@ static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx) { int ret; - if (get_bits(&ctx->gb, 5) != 0x1F) { + if (bitstream_read(&ctx->bc, 5) != 0x1F) { av_log(avctx, AV_LOG_ERROR, "Invalid picture start code!\n"); return AVERROR_INVALIDDATA; } ctx->prev_frame_type = ctx->frame_type; - ctx->frame_type = get_bits(&ctx->gb, 3); + ctx->frame_type = bitstream_read(&ctx->bc, 3); if (ctx->frame_type >= 5) { av_log(avctx, AV_LOG_ERROR, "Invalid frame type: %d \n", ctx->frame_type); return AVERROR_INVALIDDATA; } - ctx->frame_num = get_bits(&ctx->gb, 8); + ctx->frame_num = bitstream_read(&ctx->bc, 8); if (ctx->frame_type == FRAMETYPE_INTRA) { if ((ret = decode_gop_header(ctx, avctx)) < 0) { @@ -322,26 +323,26 @@ static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx) } if (ctx->frame_type != FRAMETYPE_NULL) { - ctx->frame_flags = get_bits(&ctx->gb, 8); + ctx->frame_flags = bitstream_read(&ctx->bc, 8); - ctx->pic_hdr_size = (ctx->frame_flags & 1) ? get_bits_long(&ctx->gb, 24) : 0; + ctx->pic_hdr_size = (ctx->frame_flags & 1) ? bitstream_read(&ctx->bc, 24) : 0; - ctx->checksum = (ctx->frame_flags & 0x10) ? get_bits(&ctx->gb, 16) : 0; + ctx->checksum = (ctx->frame_flags & 0x10) ? bitstream_read(&ctx->bc, 16) : 0; /* skip unknown extension if any */ if (ctx->frame_flags & 0x20) - skip_hdr_extension(&ctx->gb); /* XXX: untested */ + skip_hdr_extension(&ctx->bc); /* XXX: untested */ /* decode macroblock huffman codebook */ - ret = ff_ivi_dec_huff_desc(&ctx->gb, ctx->frame_flags & 0x40, + ret = ff_ivi_dec_huff_desc(&ctx->bc, ctx->frame_flags & 0x40, IVI_MB_HUFF, &ctx->mb_vlc, avctx); if (ret < 0) return ret; - skip_bits(&ctx->gb, 3); /* FIXME: unknown meaning! */ + bitstream_skip(&ctx->bc, 3); /* FIXME: unknown meaning! */ } - align_get_bits(&ctx->gb); + bitstream_align(&ctx->bc); return 0; } @@ -361,14 +362,14 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, int i, ret; uint8_t band_flags; - band_flags = get_bits(&ctx->gb, 8); + band_flags = bitstream_read(&ctx->bc, 8); if (band_flags & 1) { band->is_empty = 1; return 0; } - band->data_size = (ctx->frame_flags & 0x80) ? get_bits_long(&ctx->gb, 24) : 0; + band->data_size = (ctx->frame_flags & 0x80) ? bitstream_read(&ctx->bc, 24) : 0; band->inherit_mv = band_flags & 2; band->inherit_qdelta = band_flags & 8; @@ -378,7 +379,7 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, /* decode rvmap probability corrections if any */ band->num_corr = 0; /* there are no corrections */ if (band_flags & 0x10) { - band->num_corr = get_bits(&ctx->gb, 8); /* get number of correction pairs */ + band->num_corr = bitstream_read(&ctx->bc, 8); /* get number of correction pairs */ if (band->num_corr > 61) { av_log(avctx, AV_LOG_ERROR, "Too many corrections: %d\n", band->num_corr); @@ -387,31 +388,31 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, /* read correction pairs */ for (i = 0; i < band->num_corr * 2; i++) - band->corr[i] = get_bits(&ctx->gb, 8); + band->corr[i] = bitstream_read(&ctx->bc, 8); } /* select appropriate rvmap table for this band */ - band->rvmap_sel = (band_flags & 0x40) ? get_bits(&ctx->gb, 3) : 8; + band->rvmap_sel = (band_flags & 0x40) ? bitstream_read(&ctx->bc, 3) : 8; /* decode block huffman codebook */ - ret = ff_ivi_dec_huff_desc(&ctx->gb, band_flags & 0x80, IVI_BLK_HUFF, + ret = ff_ivi_dec_huff_desc(&ctx->bc, band_flags & 0x80, IVI_BLK_HUFF, &band->blk_vlc, avctx); if (ret < 0) return ret; - band->checksum_present = get_bits1(&ctx->gb); + band->checksum_present = bitstream_read_bit(&ctx->bc); if (band->checksum_present) - band->checksum = get_bits(&ctx->gb, 16); + band->checksum = bitstream_read(&ctx->bc, 16); - band->glob_quant = get_bits(&ctx->gb, 5); + band->glob_quant = bitstream_read(&ctx->bc, 5); /* skip unknown extension if any */ if (band_flags & 0x20) { /* XXX: untested */ - align_get_bits(&ctx->gb); - skip_hdr_extension(&ctx->gb); + bitstream_align(&ctx->bc); + skip_hdr_extension(&ctx->bc); } - align_get_bits(&ctx->gb); + bitstream_align(&ctx->bc); return 0; } @@ -461,7 +462,7 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, mb->ypos = y; mb->buf_offs = mb_offset; - if (get_bits1(&ctx->gb)) { + if (bitstream_read_bit(&ctx->bc)) { if (ctx->frame_type == FRAMETYPE_INTRA) { av_log(avctx, AV_LOG_ERROR, "Empty macroblock in an INTRA picture!\n"); return AVERROR_INVALIDDATA; @@ -471,8 +472,9 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, mb->q_delta = 0; if (!band->plane && !band->band_num && (ctx->frame_flags & 8)) { - mb->q_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table, - IVI_VLC_BITS, 1); + mb->q_delta = bitstream_read_vlc(&ctx->bc, + ctx->mb_vlc.tab->table, + IVI_VLC_BITS, 1); mb->q_delta = IVI_TOSIGNED(mb->q_delta); } @@ -493,11 +495,11 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, } else if (ctx->frame_type == FRAMETYPE_INTRA) { mb->type = 0; /* mb_type is always INTRA for intra-frames */ } else { - mb->type = get_bits1(&ctx->gb); + mb->type = bitstream_read_bit(&ctx->bc); } blks_per_mb = band->mb_size != band->blk_size ? 4 : 1; - mb->cbp = get_bits(&ctx->gb, blks_per_mb); + mb->cbp = bitstream_read(&ctx->bc, blks_per_mb); mb->q_delta = 0; if (band->qdelta_present) { @@ -505,8 +507,9 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, if (ref_mb) mb->q_delta = ref_mb->q_delta; } else if (mb->cbp || (!band->plane && !band->band_num && (ctx->frame_flags & 8))) { - mb->q_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table, - IVI_VLC_BITS, 1); + mb->q_delta = bitstream_read_vlc(&ctx->bc, + ctx->mb_vlc.tab->table, + IVI_VLC_BITS, 1); mb->q_delta = IVI_TOSIGNED(mb->q_delta); } } @@ -525,11 +528,13 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, } } else { /* decode motion vector deltas */ - mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table, - IVI_VLC_BITS, 1); + mv_delta = bitstream_read_vlc(&ctx->bc, + ctx->mb_vlc.tab->table, + IVI_VLC_BITS, 1); mv_y += IVI_TOSIGNED(mv_delta); - mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table, - IVI_VLC_BITS, 1); + mv_delta = bitstream_read_vlc(&ctx->bc, + ctx->mb_vlc.tab->table, + IVI_VLC_BITS, 1); mv_x += IVI_TOSIGNED(mv_delta); mb->mv_x = mv_x; mb->mv_y = mv_y; @@ -546,7 +551,7 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, offs += row_offset; } - align_get_bits(&ctx->gb); + bitstream_align(&ctx->bc); return 0; } diff --git a/libavcodec/ivi.c b/libavcodec/ivi.c index 57946a334952e..a83773443ccfc 100644 --- a/libavcodec/ivi.c +++ b/libavcodec/ivi.c @@ -33,7 +33,7 @@ #define BITSTREAM_READER_LE #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "internal.h" #include "mathops.h" #include "ivi.h" @@ -225,7 +225,7 @@ static int ivi_huff_desc_cmp(const IVIHuffDesc *desc1, memcmp(desc1->xbits, desc2->xbits, desc1->num_rows); } -int ff_ivi_dec_huff_desc(GetBitContext *gb, int desc_coded, int which_tab, +int ff_ivi_dec_huff_desc(BitstreamContext *bc, int desc_coded, int which_tab, IVIHuffTab *huff_tab, AVCodecContext *avctx) { int i, result; @@ -238,17 +238,17 @@ int ff_ivi_dec_huff_desc(GetBitContext *gb, int desc_coded, int which_tab, return 0; } - huff_tab->tab_sel = get_bits(gb, 3); + huff_tab->tab_sel = bitstream_read(bc, 3); if (huff_tab->tab_sel == 7) { /* custom huffman table (explicitly encoded) */ - new_huff.num_rows = get_bits(gb, 4); + new_huff.num_rows = bitstream_read(bc, 4); if (!new_huff.num_rows) { av_log(avctx, AV_LOG_ERROR, "Empty custom Huffman table!\n"); return AVERROR_INVALIDDATA; } for (i = 0; i < new_huff.num_rows; i++) - new_huff.xbits[i] = get_bits(gb, 4); + new_huff.xbits[i] = bitstream_read(bc, 4); /* Have we got the same custom table? Rebuild if not. */ if (ivi_huff_desc_cmp(&new_huff, &huff_tab->cust_desc)) { @@ -461,22 +461,22 @@ av_cold int ff_ivi_init_tiles(IVIPlaneDesc *planes, * if (tile_data_size >= 255) than this field four is byte long: 0xFF X1 X2 X3 * where X1-X3 is size of the tile data * - * @param[in,out] gb the GetBit context + * @param[in,out] bc the Bitstream context * @return size of the tile data in bytes */ -static int ivi_dec_tile_data_size(GetBitContext *gb) +static int ivi_dec_tile_data_size(BitstreamContext *bc) { int len; len = 0; - if (get_bits1(gb)) { - len = get_bits(gb, 8); + if (bitstream_read_bit(bc)) { + len = bitstream_read(bc, 8); if (len == 255) - len = get_bits_long(gb, 24); + len = bitstream_read(bc, 24); } /* align the bitstream reader on the byte boundary */ - align_get_bits(gb); + bitstream_align(bc); return len; } @@ -500,7 +500,7 @@ static int ivi_dc_transform(IVIBandDesc *band, int *prev_dc, int buf_offs, return 0; } -static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band, +static int ivi_decode_coded_blocks(BitstreamContext *bc, IVIBandDesc *band, ivi_mc_func mc, ivi_mc_avg_func mc_avg, int mv_x, int mv_y, int mv_x2, int mv_y2, @@ -536,16 +536,15 @@ static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band, /* zero column flags */ memset(col_flags, 0, sizeof(col_flags)); while (scan_pos <= num_coeffs) { - sym = get_vlc2(gb, band->blk_vlc.tab->table, - IVI_VLC_BITS, 1); + sym = bitstream_read_vlc(bc, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); if (sym == rvmap->eob_sym) break; /* End of block */ /* Escape - run/val explicitly coded using 3 vlc codes */ if (sym == rvmap->esc_sym) { - run = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1) + 1; - lo = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); - hi = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); + run = bitstream_read_vlc(bc, band->blk_vlc.tab->table, IVI_VLC_BITS, 1) + 1; + lo = bitstream_read_vlc(bc, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); + hi = bitstream_read_vlc(bc, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); /* merge them and convert into signed val */ val = IVI_TOSIGNED((hi << 6) | lo); } else { @@ -601,12 +600,12 @@ static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band, * dequantize them, apply inverse transform and motion compensation * in order to reconstruct the picture. * - * @param[in,out] gb the GetBit context + * @param[in,out] bc the Bitstream context * @param[in] band pointer to the band descriptor * @param[in] tile pointer to the tile descriptor * @return result code: 0 - OK, -1 = error (corrupted blocks data) */ -static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, +static int ivi_decode_blocks(BitstreamContext *bc, IVIBandDesc *band, IVITile *tile, AVCodecContext *avctx) { int mbn, blk, num_blocks, blk_size, ret, is_intra; @@ -710,7 +709,7 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, } if (cbp & 1) { /* block coded ? */ - ret = ivi_decode_coded_blocks(gb, band, mc_with_delta_func, + ret = ivi_decode_coded_blocks(bc, band, mc_with_delta_func, mc_avg_with_delta_func, mv_x, mv_y, mv_x2, mv_y2, &prev_dc, is_intra, @@ -739,7 +738,7 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, }// for blk }// for mbn - align_get_bits(gb); + bitstream_align(bc); return 0; } @@ -925,7 +924,7 @@ static int decode_band(IVI45DecContext *ctx, band->ref_buf = band->bufs[ctx->ref_buf]; band->b_ref_buf = 0; } - band->data_ptr = ctx->frame_data + (get_bits_count(&ctx->gb) >> 3); + band->data_ptr = ctx->frame_data + (bitstream_tell(&ctx->bc) >> 3); result = ctx->decode_band_hdr(ctx, band, avctx); if (result) { @@ -949,7 +948,7 @@ static int decode_band(IVI45DecContext *ctx, FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]); } - pos = get_bits_count(&ctx->gb); + pos = bitstream_tell(&ctx->bc); for (t = 0; t < band->num_tiles; t++) { tile = &band->tiles[t]; @@ -959,7 +958,7 @@ static int decode_band(IVI45DecContext *ctx, band->mb_size, tile->mb_size); return AVERROR_INVALIDDATA; } - tile->is_empty = get_bits1(&ctx->gb); + tile->is_empty = bitstream_read_bit(&ctx->bc); if (tile->is_empty) { result = ivi_process_empty_tile(avctx, band, tile, (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3)); @@ -967,7 +966,7 @@ static int decode_band(IVI45DecContext *ctx, break; ff_dlog(avctx, "Empty tile encountered!\n"); } else { - tile->data_size = ivi_dec_tile_data_size(&ctx->gb); + tile->data_size = ivi_dec_tile_data_size(&ctx->bc); if (!tile->data_size) { av_log(avctx, AV_LOG_ERROR, "Tile data size is zero!\n"); return AVERROR_INVALIDDATA; @@ -977,14 +976,14 @@ static int decode_band(IVI45DecContext *ctx, if (result < 0) break; - result = ivi_decode_blocks(&ctx->gb, band, tile, avctx); + result = ivi_decode_blocks(&ctx->bc, band, tile, avctx); if (result < 0) { av_log(avctx, AV_LOG_ERROR, "Corrupted tile data encountered!\n"); break; } - if (((get_bits_count(&ctx->gb) - pos) >> 3) != tile->data_size) { + if (((bitstream_tell(&ctx->bc) - pos) >> 3) != tile->data_size) { av_log(avctx, AV_LOG_ERROR, "Tile data_size mismatch!\n"); result = AVERROR_INVALIDDATA; @@ -1016,7 +1015,7 @@ static int decode_band(IVI45DecContext *ctx, } #endif - align_get_bits(&ctx->gb); + bitstream_align(&ctx->bc); return result; } @@ -1030,7 +1029,7 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, int buf_size = avpkt->size; int result, p, b; - init_get_bits(&ctx->gb, buf, buf_size * 8); + bitstream_init(&ctx->bc, buf, buf_size * 8); ctx->frame_data = buf; ctx->frame_size = buf_size; @@ -1122,14 +1121,14 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (ctx->is_indeo4 && ctx->frame_type == IVI4_FRAMETYPE_INTRA) { int left; - while (get_bits(&ctx->gb, 8)); // skip version string - left = get_bits_count(&ctx->gb) & 0x18; - skip_bits_long(&ctx->gb, 64 - left); - if (get_bits_left(&ctx->gb) > 18 && - show_bits_long(&ctx->gb, 21) == 0xBFFF8) { // syncheader + inter type + while (bitstream_read(&ctx->bc, 8)); // skip version string + left = bitstream_tell(&ctx->bc) & 0x18; + bitstream_skip(&ctx->bc, 64 - left); + if (bitstream_bits_left(&ctx->bc) > 18 && + bitstream_peek(&ctx->bc, 21) == 0xBFFF8) { // syncheader + inter type AVPacket pkt; - pkt.data = avpkt->data + (get_bits_count(&ctx->gb) >> 3); - pkt.size = get_bits_left(&ctx->gb) >> 3; + pkt.data = avpkt->data + (bitstream_tell(&ctx->bc) >> 3); + pkt.size = bitstream_bits_left(&ctx->bc) >> 3; ff_ivi_decode_frame(avctx, ctx->p_frame, &ctx->got_p_frame, &pkt); } } diff --git a/libavcodec/ivi.h b/libavcodec/ivi.h index 4082a90de959f..bbc88423409c3 100644 --- a/libavcodec/ivi.h +++ b/libavcodec/ivi.h @@ -29,10 +29,11 @@ #ifndef AVCODEC_IVI_H #define AVCODEC_IVI_H -#include "avcodec.h" -#include "get_bits.h" #include +#include "avcodec.h" +#include "bitstream.h" + /** * Indeo 4 frame types. */ @@ -210,7 +211,7 @@ typedef struct IVIPicConfig { } IVIPicConfig; typedef struct IVI45DecContext { - GetBitContext gb; + BitstreamContext bc; RVMapDesc rvmap_tabs[9]; ///< local corrected copy of the static rvmap tables uint32_t frame_num; @@ -302,14 +303,14 @@ void ff_ivi_init_static_vlc(void); * Decode a huffman codebook descriptor from the bitstream * and select specified huffman table. * - * @param[in,out] gb the GetBit context + * @param[in,out] bc the Bitstream context * @param[in] desc_coded flag signalling if table descriptor was coded * @param[in] which_tab codebook purpose (IVI_MB_HUFF or IVI_BLK_HUFF) * @param[out] huff_tab pointer to the descriptor of the selected table * @param[in] avctx AVCodecContext pointer * @return zero on success, negative value otherwise */ -int ff_ivi_dec_huff_desc(GetBitContext *gb, int desc_coded, int which_tab, +int ff_ivi_dec_huff_desc(BitstreamContext *bc, int desc_coded, int which_tab, IVIHuffTab *huff_tab, AVCodecContext *avctx); /** From 6fad5abcadd4373dc8ba900491a5a3c1a91851e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sun, 10 Apr 2016 20:05:32 +0200 Subject: [PATCH 0641/3374] lagarith: Convert to the new bitstream reader --- libavcodec/lagarith.c | 22 +++++++++++----------- libavcodec/lagarithrac.c | 12 ++++++------ libavcodec/lagarithrac.h | 6 ++++-- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c index 55e10bce55f83..d9667b7afced7 100644 --- a/libavcodec/lagarith.c +++ b/libavcodec/lagarith.c @@ -28,7 +28,7 @@ #include #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "mathops.h" #include "huffyuvdsp.h" #include "lagarithrac.h" @@ -101,7 +101,7 @@ static uint8_t lag_calc_zero_run(int8_t x) return (x << 1) ^ (x >> 7); } -static int lag_decode_prob(GetBitContext *gb, uint32_t *value) +static int lag_decode_prob(BitstreamContext *bc, uint32_t *value) { static const uint8_t series[] = { 1, 2, 3, 5, 8, 13, 21 }; int i; @@ -114,7 +114,7 @@ static int lag_decode_prob(GetBitContext *gb, uint32_t *value) if (prevbit && bit) break; prevbit = bit; - bit = get_bits1(gb); + bit = bitstream_read_bit(bc); if (bit && !prevbit) bits += series[i]; } @@ -127,7 +127,7 @@ static int lag_decode_prob(GetBitContext *gb, uint32_t *value) return 0; } - val = get_bits_long(gb, bits); + val = bitstream_read(bc, bits); val |= 1 << bits; *value = val - 1; @@ -135,7 +135,7 @@ static int lag_decode_prob(GetBitContext *gb, uint32_t *value) return 0; } -static int lag_read_prob_header(lag_rac *rac, GetBitContext *gb) +static int lag_read_prob_header(lag_rac *rac, BitstreamContext *bc) { int i, j, scale_factor; unsigned prob, cumulative_target; @@ -146,7 +146,7 @@ static int lag_read_prob_header(lag_rac *rac, GetBitContext *gb) rac->prob[257] = UINT_MAX; /* Read probabilities from bitstream */ for (i = 1; i < 257; i++) { - if (lag_decode_prob(gb, &rac->prob[i]) < 0) { + if (lag_decode_prob(bc, &rac->prob[i]) < 0) { av_log(rac->avctx, AV_LOG_ERROR, "Invalid probability encountered.\n"); return -1; } @@ -156,7 +156,7 @@ static int lag_read_prob_header(lag_rac *rac, GetBitContext *gb) } cumul_prob += rac->prob[i]; if (!rac->prob[i]) { - if (lag_decode_prob(gb, &prob)) { + if (lag_decode_prob(bc, &prob)) { av_log(rac->avctx, AV_LOG_ERROR, "Invalid probability run encountered.\n"); return -1; } @@ -422,7 +422,7 @@ static int lag_decode_arith_plane(LagarithContext *l, uint8_t *dst, uint32_t length; uint32_t offset = 1; int esc_count = src[0]; - GetBitContext gb; + BitstreamContext bc; lag_rac rac; const uint8_t *src_end = src + src_size; @@ -436,12 +436,12 @@ static int lag_decode_arith_plane(LagarithContext *l, uint8_t *dst, offset += 4; } - init_get_bits(&gb, src + offset, src_size * 8); + bitstream_init(&bc, src + offset, src_size * 8); - if (lag_read_prob_header(&rac, &gb) < 0) + if (lag_read_prob_header(&rac, &bc) < 0) return -1; - ff_lag_rac_init(&rac, &gb, length - stride); + ff_lag_rac_init(&rac, &bc, length - stride); for (i = 0; i < height; i++) read += lag_decode_line(l, &rac, dst + (i * stride), width, diff --git a/libavcodec/lagarithrac.c b/libavcodec/lagarithrac.c index f9e4e5c9288cc..7441dc7e83a01 100644 --- a/libavcodec/lagarithrac.c +++ b/libavcodec/lagarithrac.c @@ -27,20 +27,20 @@ * @author David Conrad */ -#include "get_bits.h" +#include "bitstream.h" #include "lagarithrac.h" -void ff_lag_rac_init(lag_rac *l, GetBitContext *gb, int length) +void ff_lag_rac_init(lag_rac *l, BitstreamContext *bc, int length) { int i, j, left; /* According to reference decoder "1st byte is garbage", - * however, it gets skipped by the call to align_get_bits() + * however, it gets skipped by the call to bitstream_align() */ - align_get_bits(gb); - left = get_bits_left(gb) >> 3; + bitstream_align(bc); + left = bitstream_bits_left(bc) >> 3; l->bytestream_start = - l->bytestream = gb->buffer + get_bits_count(gb) / 8; + l->bytestream = bc->buffer + bitstream_tell(bc) / 8; l->bytestream_end = l->bytestream_start + FFMIN(length, left); l->range = 0x80; diff --git a/libavcodec/lagarithrac.h b/libavcodec/lagarithrac.h index e4f066e445b69..3b30b15e12c7f 100644 --- a/libavcodec/lagarithrac.h +++ b/libavcodec/lagarithrac.h @@ -31,10 +31,12 @@ #define AVCODEC_LAGARITHRAC_H #include + #include "libavutil/common.h" #include "libavutil/intreadwrite.h" + #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" typedef struct lag_rac { AVCodecContext *avctx; @@ -51,7 +53,7 @@ typedef struct lag_rac { uint8_t range_hash[256]; /**< Hash table mapping upper byte to approximate symbol. */ } lag_rac; -void ff_lag_rac_init(lag_rac *l, GetBitContext *gb, int length); +void ff_lag_rac_init(lag_rac *l, BitstreamContext *bc, int length); /* TODO: Optimize */ static inline void lag_rac_refill(lag_rac *l) From cdc6727c3e0a934960d29ac1414976ef9cd04340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sun, 10 Apr 2016 20:16:42 +0200 Subject: [PATCH 0642/3374] metasound: Convert to the new bitstream reader --- libavcodec/metasound.c | 44 +++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/libavcodec/metasound.c b/libavcodec/metasound.c index a3b210e7446b0..ac6d9cd1c068e 100644 --- a/libavcodec/metasound.c +++ b/libavcodec/metasound.c @@ -30,8 +30,8 @@ #define BITSTREAM_READER_LE #include "avcodec.h" +#include "bitstream.h" #include "fft.h" -#include "get_bits.h" #include "internal.h" #include "lsp.h" #include "sinewin.h" @@ -149,7 +149,7 @@ static void dec_bark_env(TwinVQContext *tctx, const uint8_t *in, int use_hist, } } -static void read_cb_data(TwinVQContext *tctx, GetBitContext *gb, +static void read_cb_data(TwinVQContext *tctx, BitstreamContext *bc, uint8_t *dst, enum TwinVQFrameType ftype) { int i; @@ -157,8 +157,8 @@ static void read_cb_data(TwinVQContext *tctx, GetBitContext *gb, for (i = 0; i < tctx->n_div[ftype]; i++) { int bs_second_part = (i >= tctx->bits_main_spec_change[ftype]); - *dst++ = get_bits(gb, tctx->bits_main_spec[0][ftype][bs_second_part]); - *dst++ = get_bits(gb, tctx->bits_main_spec[1][ftype][bs_second_part]); + *dst++ = bitstream_read(bc, tctx->bits_main_spec[0][ftype][bs_second_part]); + *dst++ = bitstream_read(bc, tctx->bits_main_spec[1][ftype][bs_second_part]); } } @@ -169,16 +169,16 @@ static int metasound_read_bitstream(AVCodecContext *avctx, TwinVQContext *tctx, const TwinVQModeTab *mtab = tctx->mtab; int channels = tctx->avctx->channels; int sub; - GetBitContext gb; + BitstreamContext bc; int i, j, k; - init_get_bits(&gb, buf, buf_size * 8); + bitstream_init(&bc, buf, buf_size * 8); for (tctx->cur_frame = 0; tctx->cur_frame < tctx->frames_per_packet; tctx->cur_frame++) { bits = tctx->bits + tctx->cur_frame; - bits->window_type = get_bits(&gb, TWINVQ_WINDOW_TYPE_BITS); + bits->window_type = bitstream_read(&bc, TWINVQ_WINDOW_TYPE_BITS); if (bits->window_type > 8) { av_log(avctx, AV_LOG_ERROR, "Invalid window type, broken sample?\n"); @@ -190,51 +190,51 @@ static int metasound_read_bitstream(AVCodecContext *avctx, TwinVQContext *tctx, sub = mtab->fmode[bits->ftype].sub; if (bits->ftype != TWINVQ_FT_SHORT && !tctx->is_6kbps) - get_bits(&gb, 2); + bitstream_read(&bc, 2); - read_cb_data(tctx, &gb, bits->main_coeffs, bits->ftype); + read_cb_data(tctx, &bc, bits->main_coeffs, bits->ftype); for (i = 0; i < channels; i++) for (j = 0; j < sub; j++) for (k = 0; k < mtab->fmode[bits->ftype].bark_n_coef; k++) bits->bark1[i][j][k] = - get_bits(&gb, mtab->fmode[bits->ftype].bark_n_bit); + bitstream_read(&bc, mtab->fmode[bits->ftype].bark_n_bit); for (i = 0; i < channels; i++) for (j = 0; j < sub; j++) - bits->bark_use_hist[i][j] = get_bits1(&gb); + bits->bark_use_hist[i][j] = bitstream_read_bit(&bc); if (bits->ftype == TWINVQ_FT_LONG) { for (i = 0; i < channels; i++) - bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS); + bits->gain_bits[i] = bitstream_read(&bc, TWINVQ_GAIN_BITS); } else { for (i = 0; i < channels; i++) { - bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS); + bits->gain_bits[i] = bitstream_read(&bc, TWINVQ_GAIN_BITS); for (j = 0; j < sub; j++) bits->sub_gain_bits[i * sub + j] = - get_bits(&gb, TWINVQ_SUB_GAIN_BITS); + bitstream_read(&bc, TWINVQ_SUB_GAIN_BITS); } } for (i = 0; i < channels; i++) { - bits->lpc_hist_idx[i] = get_bits(&gb, mtab->lsp_bit0); - bits->lpc_idx1[i] = get_bits(&gb, mtab->lsp_bit1); + bits->lpc_hist_idx[i] = bitstream_read(&bc, mtab->lsp_bit0); + bits->lpc_idx1[i] = bitstream_read(&bc, mtab->lsp_bit1); for (j = 0; j < mtab->lsp_split; j++) - bits->lpc_idx2[i][j] = get_bits(&gb, mtab->lsp_bit2); + bits->lpc_idx2[i][j] = bitstream_read(&bc, mtab->lsp_bit2); } if (bits->ftype == TWINVQ_FT_LONG) { - read_cb_data(tctx, &gb, bits->ppc_coeffs, 3); + read_cb_data(tctx, &bc, bits->ppc_coeffs, 3); for (i = 0; i < channels; i++) { - bits->p_coef[i] = get_bits(&gb, mtab->ppc_period_bit); - bits->g_coef[i] = get_bits(&gb, mtab->pgain_bit); + bits->p_coef[i] = bitstream_read(&bc, mtab->ppc_period_bit); + bits->g_coef[i] = bitstream_read(&bc, mtab->pgain_bit); } } // subframes are aligned to nibbles - if (get_bits_count(&gb) & 3) - skip_bits(&gb, 4 - (get_bits_count(&gb) & 3)); + if (bitstream_tell(&bc) & 3) + bitstream_skip(&bc, 4 - (bitstream_tell(&bc) & 3)); } return 0; From 6c916192f3d7441f5896f6c0fe151874fcd91fe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sun, 10 Apr 2016 20:20:10 +0200 Subject: [PATCH 0643/3374] mimic: Convert to the new bitstream reader --- libavcodec/mimic.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c index d7723a8ef79ce..34d2587cfe66e 100644 --- a/libavcodec/mimic.c +++ b/libavcodec/mimic.c @@ -24,9 +24,9 @@ #include #include "avcodec.h" +#include "bitstream.h" #include "blockdsp.h" #include "internal.h" -#include "get_bits.h" #include "bytestream.h" #include "bswapdsp.h" #include "hpeldsp.h" @@ -51,7 +51,7 @@ typedef struct MimicContext { DECLARE_ALIGNED(16, int16_t, dct_block)[64]; - GetBitContext gb; + BitstreamContext bc; ScanTable scantable; BlockDSPContext bdsp; BswapDSPContext bbdsp; @@ -232,14 +232,14 @@ static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale) ctx->bdsp.clear_block(block); - block[0] = get_bits(&ctx->gb, 8) << 3; + block[0] = bitstream_read(&ctx->bc, 8) << 3; for (pos = 1; pos < num_coeffs; pos++) { uint32_t vlc, num_bits; int value; int coeff; - vlc = get_vlc2(&ctx->gb, ctx->vlc.table, ctx->vlc.bits, 3); + vlc = bitstream_read_vlc(&ctx->bc, ctx->vlc.table, ctx->vlc.bits, 3); if (!vlc) /* end-of-block code */ return 0; if (vlc == -1) @@ -252,7 +252,7 @@ static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale) if (pos >= 64) return AVERROR_INVALIDDATA; - value = get_bits(&ctx->gb, num_bits); + value = bitstream_read(&ctx->bc, num_bits); /* Libav's IDCT behaves somewhat different from the original code, so * a factor of 4 was added to the input */ @@ -286,13 +286,13 @@ static int decode(MimicContext *ctx, int quality, int num_coeffs, for (x = 0; x < ctx->num_hblocks[plane]; x++) { /* Check for a change condition in the current block. * - iframes always change. - * - Luma plane changes on get_bits1 == 0 - * - Chroma planes change on get_bits1 == 1 */ - if (is_iframe || get_bits1(&ctx->gb) == is_chroma) { + * - Luma plane changes on bitstream_read_bit == 0 + * - Chroma planes change on bitstream_read_bit == 1 */ + if (is_iframe || bitstream_read_bit(&ctx->bc) == is_chroma) { /* Luma planes may use a backreference from the 15 last - * frames preceding the previous. (get_bits1 == 1) + * frames preceding the previous. (bitstream_read_bit == 1) * Chroma planes don't use backreferences. */ - if (is_chroma || is_iframe || !get_bits1(&ctx->gb)) { + if (is_chroma || is_iframe || !bitstream_read_bit(&ctx->bc)) { if ((ret = vlc_decode_block(ctx, num_coeffs, qscale)) < 0) { av_log(ctx->avctx, AV_LOG_ERROR, "Error decoding " @@ -301,7 +301,7 @@ static int decode(MimicContext *ctx, int quality, int num_coeffs, } ctx->idsp.idct_put(dst, stride, ctx->dct_block); } else { - unsigned int backref = get_bits(&ctx->gb, 4); + unsigned int backref = bitstream_read(&ctx->bc, 4); int index = (ctx->cur_index + backref) & 15; uint8_t *p = ctx->frames[index].f->data[0]; @@ -426,7 +426,7 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data, ctx->bbdsp.bswap_buf(ctx->swap_buf, (const uint32_t *) (buf + MIMIC_HEADER_SIZE), swap_buf_size >> 2); - init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3); + bitstream_init(&ctx->bc, ctx->swap_buf, swap_buf_size << 3); res = decode(ctx, quality, num_coeffs, !is_pframe); ff_thread_report_progress(&ctx->frames[ctx->cur_index], INT_MAX, 0); From 0fdc9f81a00f0f32eb93c324bad65d8014deb4dd Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 4 Dec 2016 13:13:19 +0000 Subject: [PATCH 0644/3374] build: Add missing hevc_ps dependency for QSV HEVC encoder --- libavcodec/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/Makefile b/libavcodec/Makefile index dee3d1398e11a..e38e74189c099 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -271,7 +271,8 @@ OBJS-$(CONFIG_HEVC_DECODER) += hevcdec.o hevc_mvs.o hevc_ps.o hevc_se hevcdsp.o hevc_filter.o h2645_parse.o hevc_data.o OBJS-$(CONFIG_HEVC_NVENC_ENCODER) += nvenc_hevc.o OBJS-$(CONFIG_HEVC_QSV_DECODER) += qsvdec_h2645.o -OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc_ps_enc.o h2645_parse.o +OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc_ps_enc.o \ + h2645_parse.o hevc_ps.o hevc_data.o OBJS-$(CONFIG_HEVC_VAAPI_ENCODER) += vaapi_encode_h265.o vaapi_encode_h26x.o OBJS-$(CONFIG_HNM4_VIDEO_DECODER) += hnm4video.o OBJS-$(CONFIG_HQ_HQA_DECODER) += hq_hqa.o hq_hqadata.o hq_hqadsp.o \ From e1dc5358af0dadef548114ec9cabba766b7c6260 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 3 Dec 2016 11:25:02 +0100 Subject: [PATCH 0645/3374] build: Create a component for MPEG audio header decoding Fixes standalone compilation of the libmp3lame encoder. --- configure | 7 +++++-- libavcodec/Makefile | 10 ++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/configure b/configure index e348f3be65937..495611987b881 100755 --- a/configure +++ b/configure @@ -1724,6 +1724,7 @@ CONFIG_EXTRA=" mpeg_er mpegaudio mpegaudiodsp + mpegaudioheader mpegvideo mpegvideoenc mss34dsp @@ -1907,7 +1908,7 @@ mdct_select="fft" rdft_select="fft" me_cmp_select="fdctdsp idctdsp pixblockdsp" mpeg_er_select="error_resilience" -mpegaudio_select="mpegaudiodsp" +mpegaudio_select="mpegaudiodsp mpegaudioheader" mpegaudiodsp_select="dct" mpegvideo_select="blockdsp hpeldsp idctdsp me_cmp mpeg_er videodsp" mpegvideoenc_select="me_cmp mpegvideo pixblockdsp qpeldsp" @@ -2229,6 +2230,7 @@ nvenc_hevc_encoder_deps="nvenc" # parsers h264_parser_select="golomb h264dsp h264parse" hevc_parser_select="golomb" +mpegaudio_parser_select="mpegaudioheader" mpegvideo_parser_select="mpegvideo" mpeg4video_parser_select="error_resilience h263dsp mpegvideo qpeldsp" vc1_parser_select="vc1dsp" @@ -2251,7 +2253,7 @@ libilbc_decoder_deps="libilbc" libilbc_encoder_deps="libilbc" libkvazaar_encoder_deps="libkvazaar" libmp3lame_encoder_deps="libmp3lame" -libmp3lame_encoder_select="audio_frame_queue" +libmp3lame_encoder_select="audio_frame_queue mpegaudioheader" libopencore_amrnb_decoder_deps="libopencore_amrnb" libopencore_amrnb_encoder_deps="libopencore_amrnb" libopencore_amrnb_encoder_select="audio_frame_queue" @@ -2319,6 +2321,7 @@ mov_demuxer_select="iso_media riffdec" mov_demuxer_suggest="zlib" mov_muxer_select="iso_media riffenc rtpenc_chain" mp3_demuxer_select="mpegaudio_parser" +mp3_muxer_select="mpegaudioheader" mp4_muxer_select="mov_muxer" mpegts_demuxer_select="iso_media" mpegts_muxer_select="adts_muxer latm_muxer" diff --git a/libavcodec/Makefile b/libavcodec/Makefile index e38e74189c099..0beeda4ea26a8 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -82,12 +82,12 @@ OBJS-$(CONFIG_LZF) += lzf.o OBJS-$(CONFIG_MDCT) += mdct_fixed.o mdct_float.o OBJS-$(CONFIG_ME_CMP) += me_cmp.o OBJS-$(CONFIG_MPEG_ER) += mpeg_er.o -OBJS-$(CONFIG_MPEGAUDIO) += mpegaudio.o mpegaudiodata.o \ - mpegaudiodecheader.o +OBJS-$(CONFIG_MPEGAUDIO) += mpegaudio.o OBJS-$(CONFIG_MPEGAUDIODSP) += mpegaudiodsp.o \ mpegaudiodsp_data.o \ mpegaudiodsp_fixed.o \ mpegaudiodsp_float.o +OBJS-$(CONFIG_MPEGAUDIOHEADER) += mpegaudiodecheader.o mpegaudiodata.o OBJS-$(CONFIG_MPEGVIDEO) += mpegvideo.o mpegvideodsp.o rl.o \ mpegvideo_motion.o mpegutils.o \ mpegvideodata.o mpegpicture.o @@ -651,7 +651,6 @@ OBJS-$(CONFIG_LATM_MUXER) += mpeg4audio.o OBJS-$(CONFIG_MATROSKA_AUDIO_MUXER) += mpeg4audio.o OBJS-$(CONFIG_MATROSKA_MUXER) += mpeg4audio.o OBJS-$(CONFIG_MOV_DEMUXER) += ac3tab.o -OBJS-$(CONFIG_MP3_MUXER) += mpegaudiodata.o mpegaudiodecheader.o OBJS-$(CONFIG_NUT_MUXER) += mpegaudiodata.o OBJS-$(CONFIG_SPDIF_DEMUXER) += aacadtsdec.o mpeg4audio.o OBJS-$(CONFIG_SPDIF_MUXER) += dca.o @@ -670,7 +669,7 @@ OBJS-$(CONFIG_LIBGSM_MS_ENCODER) += libgsmenc.o OBJS-$(CONFIG_LIBILBC_DECODER) += libilbc.o OBJS-$(CONFIG_LIBILBC_ENCODER) += libilbc.o OBJS-$(CONFIG_LIBKVAZAAR_ENCODER) += libkvazaar.o -OBJS-$(CONFIG_LIBMP3LAME_ENCODER) += libmp3lame.o mpegaudiodecheader.o +OBJS-$(CONFIG_LIBMP3LAME_ENCODER) += libmp3lame.o OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER) += libopencore-amr.o OBJS-$(CONFIG_LIBOPENCORE_AMRNB_ENCODER) += libopencore-amr.o OBJS-$(CONFIG_LIBOPENCORE_AMRWB_DECODER) += libopencore-amr.o @@ -733,8 +732,7 @@ OBJS-$(CONFIG_MLP_PARSER) += mlp_parser.o mlp.o OBJS-$(CONFIG_MPEG4VIDEO_PARSER) += mpeg4video_parser.o h263.o \ mpeg4videodec.o mpeg4video.o \ ituh263dec.o h263dec.o h263data.o -OBJS-$(CONFIG_MPEGAUDIO_PARSER) += mpegaudio_parser.o \ - mpegaudiodecheader.o mpegaudiodata.o +OBJS-$(CONFIG_MPEGAUDIO_PARSER) += mpegaudio_parser.o OBJS-$(CONFIG_MPEGVIDEO_PARSER) += mpegvideo_parser.o \ mpeg12.o mpeg12data.o OBJS-$(CONFIG_OPUS_PARSER) += opus_parser.o opus.o vorbis_data.o From 660470cd62c59f25cc52c731af6230e7bc1aba62 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 3 Dec 2016 11:56:37 +0100 Subject: [PATCH 0646/3374] build: Add missing audio_frame_queue dependency for libwavpack encoder --- configure | 1 + 1 file changed, 1 insertion(+) diff --git a/configure b/configure index 495611987b881..43506debdc6a8 100755 --- a/configure +++ b/configure @@ -2283,6 +2283,7 @@ libvpx_vp8_encoder_deps="libvpx" libvpx_vp9_decoder_deps="libvpx" libvpx_vp9_encoder_deps="libvpx" libwavpack_encoder_deps="libwavpack" +libwavpack_encoder_select="audio_frame_queue" libwebp_encoder_deps="libwebp" libx262_encoder_deps="libx262" libx264_encoder_deps="libx264" From ffb9025f39b274abfc4ad2b264205a44cc0238a4 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 4 Dec 2016 13:40:13 +0100 Subject: [PATCH 0647/3374] configure: Simplify MMAL check --- configure | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/configure b/configure index 43506debdc6a8..e5a787198d36f 100755 --- a/configure +++ b/configure @@ -4678,13 +4678,12 @@ enabled libx265 && require_pkg_config x265 x265.h x265_api_get && enabled libxavs && require libxavs "stdint.h xavs.h" xavs_encoder_encode -lxavs enabled libxvid && require libxvid xvid.h xvid_global -lxvidcore enabled mmal && { check_lib interface/mmal/mmal.h mmal_port_connect -lmmal_core -lmmal_util -lmmal_vc_client -lbcm_host || - { ! enabled cross_compile && { - add_cflags -isystem/opt/vc/include/ -isystem/opt/vc/include/interface/vmcs_host/linux -isystem/opt/vc/include/interface/vcos/pthreads -fgnu89-inline ; - add_extralibs -L/opt/vc/lib/ -lmmal_core -lmmal_util -lmmal_vc_client -lbcm_host ; - check_lib interface/mmal/mmal.h mmal_port_connect ; } - check_lib interface/mmal/mmal.h mmal_port_connect ; } || - die "ERROR: mmal not found"; } -enabled mmal && check_func_headers interface/mmal/mmal.h "MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS" + { ! enabled cross_compile && + add_cflags -isystem/opt/vc/include/ -isystem/opt/vc/include/interface/vmcs_host/linux -isystem/opt/vc/include/interface/vcos/pthreads -fgnu89-inline && + add_ldflags -L/opt/vc/lib/ && + check_lib interface/mmal/mmal.h mmal_port_connect -lmmal_core -lmmal_util -lmmal_vc_client -lbcm_host; } || + die "ERROR: mmal not found" && + check_func_headers interface/mmal/mmal.h "MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS"; } enabled omx_rpi && enable omx enabled omx && { check_header OMX_Core.h || { ! enabled cross_compile && enabled omx_rpi && { From 2a096440768b1086bb437939f827b8b7a5716bf7 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 16 Nov 2016 18:10:35 +0100 Subject: [PATCH 0648/3374] configure: Separate package name and version requirements in helper functions The unadorned package name is needed to derive package-related variable names. --- configure | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/configure b/configure index e5a787198d36f..37482cf1ef558 100755 --- a/configure +++ b/configure @@ -1009,11 +1009,12 @@ check_lib(){ check_pkg_config(){ log check_pkg_config "$@" - pkg="$1" + pkg_version="$1" + pkg="${1%% *}" headers="$2" funcs="$3" shift 3 - check_cmd $pkg_config --exists --print-errors $pkg || return + check_cmd $pkg_config --exists --print-errors $pkg_version || return pkg_cflags=$($pkg_config --cflags $pkg_config_flags $pkg) pkg_libs=$($pkg_config --libs $pkg_config_flags $pkg) check_func_headers "$headers" "$funcs" $pkg_cflags $pkg_libs "$@" && @@ -1098,17 +1099,18 @@ check_compile_assert(){ require(){ log require "$@" - name="$1" + name_version="$1" headers="$2" func="$3" shift 3 - check_lib "$headers" $func "$@" || die "ERROR: $name not found" + check_lib "$headers" $func "$@" || die "ERROR: $name_version not found" } require_pkg_config(){ log require_pkg_config "$@" - pkg="$1" - check_pkg_config "$@" || die "ERROR: $pkg not found" + pkg_version="$1" + pkg="${1%% *}" + check_pkg_config "$@" || die "ERROR: $pkg_version not found" add_cflags $(get_safe "${pkg}_cflags") add_extralibs $(get_safe "${pkg}_libs") } From 5d45fe7da972da528915fbdfe3dbf22eb2effd01 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 22 Nov 2016 16:20:31 +0100 Subject: [PATCH 0649/3374] build: Add EXTRALIBS to TOOLS linker command EXTRALIBS contains general and platform-specific extra libraries that should be part of all linker commands. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f5bbc8b626da3..5aa2ab4557b1a 100644 --- a/Makefile +++ b/Makefile @@ -117,7 +117,7 @@ FF_STATIC_DEP_LIBS := $(STATIC_DEP_LIBS) all: $(AVPROGS) $(TOOLS): %$(EXESUF): %.o - $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) + $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(EXTRALIBS) $(ELIBS) tools/cws2fws$(EXESUF): ELIBS = $(ZLIB) From 29d2e03ed96d9f7b8cb2cc87dca0a63c2a6eff70 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 28 Nov 2016 08:55:31 +0100 Subject: [PATCH 0650/3374] configure: Simplify and fix avfoundation indev handling Handle extralibs in the standard way, add missing pthreads dependency. Also globally check for -fobj-arc with Objective-C compilers since that option is useful for other Objective-C code as well. --- configure | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/configure b/configure index 37482cf1ef558..fae5be0b95e95 100755 --- a/configure +++ b/configure @@ -2362,7 +2362,8 @@ xwma_demuxer_select="riffdec" # indevs / outdevs alsa_indev_deps="alsa_asoundlib_h snd_pcm_htimestamp" alsa_outdev_deps="alsa_asoundlib_h" -avfoundation_indev_deps="AVFoundation_AVFoundation_h" +avfoundation_indev_deps="AVFoundation_AVFoundation_h objc_arc pthreads" +avfoundation_indev_extralibs="-framework Foundation -framework AVFoundation -framework CoreVideo -framework CoreMedia" bktr_indev_deps_any="dev_bktr_ioctl_bt848_h machine_ioctl_bt848_h dev_video_bktr_ioctl_bt848_h dev_ic_bt8xx_h" dv1394_indev_deps="dv1394" dv1394_indev_select="dv_demuxer" @@ -4721,10 +4722,7 @@ check_header linux/fb.h check_header linux/videodev2.h check_struct linux/videodev2.h "struct v4l2_frmivalenum" discrete -check_header AVFoundation/AVFoundation.h && - check_objcflags -fobjc-arc && - add_extralibs -framework Foundation -framework AVFoundation -framework CoreVideo -framework CoreMedia || - disable AVFoundation_AVFoundation_h +check_header AVFoundation/AVFoundation.h check_header sys/videoio.h @@ -4839,6 +4837,8 @@ check_disable_warning_headers(){ check_disable_warning_headers -Wno-deprecated-declarations check_disable_warning_headers -Wno-unused-variable +check_objcflags -fobjc-arc && enable objc_arc + # add some linker flags check_ldflags -Wl,--warn-common check_ldflags -Wl,-rpath-link=libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil:libavresample From 601f8dde13ccd0e1993b7840a0304fa2cfe53432 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 5 Dec 2016 17:09:50 +0100 Subject: [PATCH 0651/3374] configure: Move COMPONENT_LIST to the bottom of CONFIG_LIST This ensures that dependencies are resolved correctly. COMPONENT_LIST can contain parts that depend on previous entries of CONFIG_LIST. --- configure | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure b/configure index fae5be0b95e95..61ce40ef3501a 100755 --- a/configure +++ b/configure @@ -1350,8 +1350,8 @@ SUBSYSTEM_LIST=" rdft " +# COMPONENT_LIST needs to come last to ensure correct dependency checking CONFIG_LIST=" - $COMPONENT_LIST $EXAMPLE_LIST $EXTERNAL_LIBRARY_LIST $HWACCEL_LIBRARY_LIST @@ -1367,6 +1367,7 @@ CONFIG_LIST=" thumb valgrind_backtrace xmm_clobber_test + $COMPONENT_LIST " THREADS_LIST=" From 3d6135eacf3b6a82c3024620c6a28169960464a7 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 2 Dec 2016 12:33:50 +0100 Subject: [PATCH 0652/3374] configure: Simplify OMX check --- configure | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/configure b/configure index 61ce40ef3501a..a4ba2bff61a6d 100755 --- a/configure +++ b/configure @@ -2190,6 +2190,7 @@ nvenc_deps_any="dlopen LoadLibrary" nvenc_extralibs='$ldl' omx_deps="dlopen pthreads" omx_extralibs='$ldl' +omx_rpi_select="omx" qsvdec_select="qsv" qsvenc_select="qsv" vaapi_encode_deps="vaapi" @@ -4688,12 +4689,10 @@ enabled mmal && { check_lib interface/mmal/mmal.h mmal_port_connect check_lib interface/mmal/mmal.h mmal_port_connect -lmmal_core -lmmal_util -lmmal_vc_client -lbcm_host; } || die "ERROR: mmal not found" && check_func_headers interface/mmal/mmal.h "MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS"; } -enabled omx_rpi && enable omx -enabled omx && { check_header OMX_Core.h || - { ! enabled cross_compile && enabled omx_rpi && { - add_cflags -isystem/opt/vc/include/IL ; } - check_header OMX_Core.h ; } || +enabled omx_rpi && { check_header OMX_Core.h || + { ! enabled cross_compile && add_cflags -isystem/opt/vc/include/IL && check_header OMX_Core.h ; } || die "ERROR: OpenMAX IL headers not found"; } +enabled omx && { check_header OMX_Core.h || die "ERROR: OpenMAX IL headers not found"; } enabled openssl && { { check_pkg_config openssl openssl/ssl.h OPENSSL_init_ssl || check_pkg_config openssl openssl/ssl.h SSL_library_init; } && { add_cflags $openssl_cflags && add_extralibs $openssl_libs; }|| From 9265364bec0af2e8b7c3a6de7bfc8291a0b70bca Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 14 Nov 2016 17:22:51 +0100 Subject: [PATCH 0653/3374] build: Separate avisynth and avxsynth support This simplifies the code. --- configure | 13 ++++++++----- libavformat/Makefile | 2 +- libavformat/avisynth.c | 19 +++++++++---------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/configure b/configure index a4ba2bff61a6d..e986aa6b8d01a 100755 --- a/configure +++ b/configure @@ -188,6 +188,7 @@ External library support: themselves, not all their features will necessarily be usable by Libav. --enable-avisynth video frameserver + --enable-avxsynth Linux version of AviSynth --enable-bzlib bzip2 compression [autodetect] --enable-frei0r video filtering plugins --enable-gnutls crypto @@ -1268,6 +1269,7 @@ EXTERNAL_LIBRARY_LIST=" $EXTERNAL_LIBRARY_NONFREE_LIST $EXTERNAL_LIBRARY_VERSION3_LIST avisynth + avxsynth bzlib frei0r gnutls @@ -2243,6 +2245,10 @@ vc1_parser_select="vc1dsp" mjpeg2jpeg_bsf_select="jpegtables" # external libraries +avisynth_deps="LoadLibrary" +avxsynth_deps="dlopen" +avisynth_demuxer_deps_any="avisynth avxsynth" +avisynth_demuxer_select="riffdec" libdcadec_decoder_deps="libdcadec" libfaac_encoder_deps="libfaac" libfaac_encoder_select="audio_frame_queue" @@ -2302,8 +2308,6 @@ asf_muxer_select="riffenc" asf_stream_muxer_select="asf_muxer" avi_demuxer_select="iso_media riffdec" avi_muxer_select="riffenc" -avisynth_demuxer_deps="avisynth" -avisynth_demuxer_select="riffdec" caf_demuxer_select="iso_media riffdec" dash_muxer_select="mp4_muxer" dirac_demuxer_select="dirac_parser" @@ -4610,9 +4614,8 @@ for func in $MATH_FUNCS; do done # these are off by default, so fail if requested and not available -enabled avisynth && { check_lib "avisynth/avisynth_c.h windows.h" LoadLibrary || - check_lib "avxsynth/avxsynth_c.h dlfcn.h" dlopen -ldl || - die "ERROR: LoadLibrary/dlopen not found, or avisynth header not found"; } +enabled avisynth && { check_header avisynth/avisynth_c.h || die "ERROR: avisynth/avisynth_c.h header not found"; } +enabled avxsynth && require avxsynth "avxsynth/avxsynth_c.h dlfcn.h" dlopen -ldl enabled cuda && check_lib cuda.h cuInit -lcuda enabled frei0r && { check_header frei0r.h || die "ERROR: frei0r.h header not found"; } enabled gnutls && require_pkg_config gnutls gnutls/gnutls.h gnutls_global_init diff --git a/libavformat/Makefile b/libavformat/Makefile index d06d5d6d82c33..6146cbe12a8d8 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -85,7 +85,6 @@ OBJS-$(CONFIG_AU_DEMUXER) += au.o pcm.o OBJS-$(CONFIG_AU_MUXER) += au.o rawenc.o OBJS-$(CONFIG_AVI_DEMUXER) += avidec.o OBJS-$(CONFIG_AVI_MUXER) += avienc.o -OBJS-$(CONFIG_AVISYNTH) += avisynth.o OBJS-$(CONFIG_AVM2_MUXER) += swfenc.o swf.o OBJS-$(CONFIG_AVS_DEMUXER) += avs.o voc_packet.o voc.o OBJS-$(CONFIG_BETHSOFTVID_DEMUXER) += bethsoftvid.o @@ -379,6 +378,7 @@ OBJS-$(CONFIG_YUV4MPEGPIPE_DEMUXER) += yuv4mpegdec.o OBJS-$(CONFIG_YUV4MPEGPIPE_MUXER) += yuv4mpegenc.o # external libraries +OBJS-$(CONFIG_AVISYNTH_DEMUXER) += avisynth.o OBJS-$(CONFIG_LIBRTMP) += librtmp.o # protocols I/O diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c index d3b3ec478ef8a..d0fe0fd7ea421 100644 --- a/libavformat/avisynth.c +++ b/libavformat/avisynth.c @@ -32,12 +32,11 @@ #define AVSC_NO_DECLSPEC /* Platform-specific directives for AviSynth vs AvxSynth. */ -#ifdef _WIN32 +#if CONFIG_AVISYNTH #include #undef EXTERN_C #include #define AVISYNTH_LIB "avisynth" - #define USING_AVISYNTH #else #include #include @@ -66,7 +65,7 @@ typedef struct AviSynthLibrary { AVSC_DECLARE_FUNC(avs_release_value); AVSC_DECLARE_FUNC(avs_release_video_frame); AVSC_DECLARE_FUNC(avs_take_clip); -#ifdef USING_AVISYNTH +#if CONFIG_AVISYNTH AVSC_DECLARE_FUNC(avs_bits_per_pixel); AVSC_DECLARE_FUNC(avs_get_height_p); AVSC_DECLARE_FUNC(avs_get_pitch_p); @@ -146,7 +145,7 @@ static av_cold int avisynth_load_library(void) LOAD_AVS_FUNC(avs_release_value, 0); LOAD_AVS_FUNC(avs_release_video_frame, 0); LOAD_AVS_FUNC(avs_take_clip, 0); -#ifdef USING_AVISYNTH +#if CONFIG_AVISYNTH LOAD_AVS_FUNC(avs_bits_per_pixel, 1); LOAD_AVS_FUNC(avs_get_height_p, 1); LOAD_AVS_FUNC(avs_get_pitch_p, 1); @@ -253,7 +252,7 @@ static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st) avpriv_set_pts_info(st, 32, avs->vi->fps_denominator, avs->vi->fps_numerator); switch (avs->vi->pixel_type) { -#ifdef USING_AVISYNTH +#if CONFIG_AVISYNTH /* 10~16-bit YUV pix_fmts (AviSynth+) */ case AVS_CS_YUV444P10: st->codecpar->format = AV_PIX_FMT_YUV444P10; @@ -509,7 +508,7 @@ static int avisynth_open_file(AVFormatContext *s) AviSynthContext *avs = s->priv_data; AVS_Value arg, val; int ret; -#ifdef USING_AVISYNTH +#if CONFIG_AVISYNTH char filename_ansi[MAX_PATH * 4]; wchar_t filename_wc[MAX_PATH * 4]; #endif @@ -517,7 +516,7 @@ static int avisynth_open_file(AVFormatContext *s) if (ret = avisynth_context_create(s)) return ret; -#ifdef USING_AVISYNTH +#if CONFIG_AVISYNTH /* Convert UTF-8 to ANSI code page */ MultiByteToWideChar(CP_UTF8, 0, s->filename, -1, filename_wc, MAX_PATH * 4); WideCharToMultiByte(CP_THREAD_ACP, 0, filename_wc, -1, filename_ansi, @@ -541,7 +540,7 @@ static int avisynth_open_file(AVFormatContext *s) avs->clip = avs_library.avs_take_clip(val, avs->env); avs->vi = avs_library.avs_get_video_info(avs->clip); -#ifdef USING_AVISYNTH +#if CONFIG_AVISYNTH /* On Windows, libav supports AviSynth interface version 6 or higher. * This includes AviSynth 2.6 RC1 or higher, and AviSynth+ r1718 or higher, * and excludes 2.5 and the 2.6 alphas. Since AvxSynth identifies itself @@ -605,7 +604,7 @@ static int avisynth_read_packet_video(AVFormatContext *s, AVPacket *pkt, if (discard) return 0; -#ifdef USING_AVISYNTH +#if CONFIG_AVISYNTH /* Detect whether we're using AviSynth 2.6 or AviSynth+ by * looking for whether avs_is_planar_rgb exists. */ if (GetProcAddress(avs_library.library, "avs_is_planar_rgb") == NULL) @@ -649,7 +648,7 @@ static int avisynth_read_packet_video(AVFormatContext *s, AVPacket *pkt, dst_p = pkt->data; for (i = 0; i < avs->n_planes; i++) { plane = avs->planes[i]; -#ifdef USING_AVISYNTH +#if CONFIG_AVISYNTH src_p = avs_library.avs_get_read_ptr_p(frame, plane); pitch = avs_library.avs_get_pitch_p(frame, plane); From 404cb74793284aa03e2e1a7e911c980c4cba0e9e Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 4 Dec 2016 11:06:47 +0100 Subject: [PATCH 0654/3374] configure: Pass CFLAGS_HEADERS through the right CFLAGS filter The generic parameter names used for CFLAGS in configure must be filtered for each compiler and replaced by the equivalent flag for that compiler. --- configure | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/configure b/configure index e986aa6b8d01a..4c11e5e033821 100755 --- a/configure +++ b/configure @@ -716,6 +716,10 @@ add_cflags(){ append CFLAGS $($cflags_filter "$@") } +add_cflags_headers(){ + append CFLAGS_HEADERS $($cflags_filter "$@") +} + add_asflags(){ append ASFLAGS $($asflags_filter "$@") } @@ -4834,7 +4838,7 @@ check_disable_warning -Wno-pointer-sign check_disable_warning_headers(){ warning_flag=-W${1#-Wno-} - test_cflags $warning_flag && append cflags_headers $1 + test_cflags $warning_flag && add_cflags_headers $1 } check_disable_warning_headers -Wno-deprecated-declarations @@ -5298,7 +5302,7 @@ TARGET_EXEC=$target_exec $target_exec_args TARGET_PATH=$target_path TARGET_SAMPLES=${target_samples:-\$(SAMPLES)} CFLAGS-avplay=$sdl_cflags -CFLAGS_HEADERS=$cflags_headers +CFLAGS_HEADERS=$CFLAGS_HEADERS ZLIB=$($ldflags_filter -lz) LIB_INSTALL_EXTRA_CMD=$LIB_INSTALL_EXTRA_CMD EXTRALIBS=$extralibs From f22da2cdf90dc892d483e2d4003cffc0500816f6 Mon Sep 17 00:00:00 2001 From: Wan-Teh Chang Date: Fri, 2 Dec 2016 11:27:17 -0800 Subject: [PATCH 0655/3374] configure: add -fPIE instead of -pie to C flags for ThreadSanitizer -pie was added to C flags for ThreadSanitizer in commit 19f251a2882a8d0779b432e63bf282e4d9c443bb. Under clang 3.8.0, the -pie flag causes a compiler warning and a linker error when running configure --toolchain=clang-tsan. Here is an excerpt from config.log: clang ... -fsanitize=thread -pie -std=c11 -fomit-frame-pointer -pthread -c -o /tmp/ffconf.A8SsaoCF.o /tmp/ffconf.JdpujQlD.c clang: warning: argument unused during compilation: '-pie' clang -fsanitize=thread -pie -Wl,--as-needed -o /tmp/ffconf.2iYA4bsw /tmp/ffconf.A8SsaoCF.o -lm -lm -lbz2 -lz -pthread /usr/bin/ld: /tmp/ffconf.A8SsaoCF.o: relocation R_X86_64_PC32 against undefined symbol `atan2f@@GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: final link failed: Bad value clang: error: linker command failed with exit code 1 (use -v to see invocation) To be conservative, I changed -pie to -fPIE. But the documentation seems to imply just -fsanitize=thread is enough: http://clang.llvm.org/docs/ThreadSanitizer.html https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual Signed-off-by: Wan-Teh Chang Signed-off-by: Luca Barbato --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 4c11e5e033821..118309061359d 100755 --- a/configure +++ b/configure @@ -2819,7 +2819,7 @@ case "$toolchain" in ;; *-tsan) cc_default="${toolchain%-tsan}" - add_cflags -fsanitize=thread -pie + add_cflags -fsanitize=thread -fPIE add_ldflags -fsanitize=thread -pie case "$toolchain" in gcc-tsan) From 4104cc56225f29ce1cded8b2876f8748460232a6 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 4 Dec 2016 22:01:50 +0100 Subject: [PATCH 0656/3374] build: Warn that reconfiguration is necessary if version.h files changed The library versions are stored in the config.mak file and are used to derive shared library names. --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5aa2ab4557b1a..a7dcb6c53a65c 100644 --- a/Makefile +++ b/Makefile @@ -123,13 +123,14 @@ tools/cws2fws$(EXESUF): ELIBS = $(ZLIB) CONFIGURABLE_COMPONENTS = \ $(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/all*.c)) \ + $(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/version.h)) \ $(SRC_PATH)/libavcodec/bitstream_filters.c \ $(SRC_PATH)/libavformat/protocols.c \ config.h: .config .config: $(CONFIGURABLE_COMPONENTS) @-tput bold 2>/dev/null - @-printf '\nWARNING: $(?F) newer than config.h, rerun configure\n\n' + @-printf '\nWARNING: $(?) newer than config.h, rerun configure\n\n' @-tput sgr0 2>/dev/null SUBDIR_VARS := CLEANFILES EXAMPLES FFLIBS HOSTPROGS TESTPROGS TOOLS \ From 3e105d08848162b90d886bde59c010d4b0362a4b Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 5 Dec 2016 18:38:53 +0100 Subject: [PATCH 0657/3374] build: Move entries related to building TOOLS to a subdirectory Makefile --- Makefile | 8 +------- tools/Makefile | 11 +++++++++++ 2 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 tools/Makefile diff --git a/Makefile b/Makefile index a7dcb6c53a65c..b090007f1e755 100644 --- a/Makefile +++ b/Makefile @@ -90,8 +90,6 @@ OBJS-avconv-$(HAVE_VDPAU_X11) += avconv_vdpau.o TESTTOOLS = audiogen videogen rotozoom tiny_psnr base64 HOSTPROGS := $(TESTTOOLS:%=tests/%) doc/print_options -TOOLS = qt-faststart trasher -TOOLS-$(CONFIG_ZLIB) += cws2fws # $(FFLIBS-yes) needs to be in linking order FFLIBS-$(CONFIG_AVDEVICE) += avdevice @@ -108,6 +106,7 @@ DATA_FILES := $(wildcard $(SRC_PATH)/presets/*.avpreset) SKIPHEADERS = cmdutils_common_opts.h \ compat/w32pthreads.h +include $(SRC_PATH)/tools/Makefile include $(SRC_PATH)/common.mak FF_EXTRALIBS := $(FFEXTRALIBS) @@ -171,10 +170,6 @@ $(foreach P,$(PROGS),$(eval $(call DOPROG,$(P:$(EXESUF)=)))) $(PROGS): %$(EXESUF): %.o $(FF_DEP_LIBS) $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $(OBJS-$*) $(FF_EXTRALIBS) -OBJDIRS += tools - --include $(wildcard tools/*.d) - VERSION_SH = $(SRC_PATH)/version.sh GIT_LOG = $(SRC_PATH)/.git/logs/HEAD @@ -219,7 +214,6 @@ uninstall-data: clean:: $(RM) $(ALLAVPROGS) $(RM) $(CLEANSUFFIXES) - $(RM) $(CLEANSUFFIXES:%=tools/%) $(RM) -rf coverage.info lcov distclean:: diff --git a/tools/Makefile b/tools/Makefile new file mode 100644 index 0000000000000..372287b4522f9 --- /dev/null +++ b/tools/Makefile @@ -0,0 +1,11 @@ +TOOLS = qt-faststart trasher +TOOLS-$(CONFIG_ZLIB) += cws2fws + +tools/cws2fws$(EXESUF): ELIBS = $(ZLIB) + +OBJDIRS += tools + +clean:: + $(RM) $(CLEANSUFFIXES:%=tools/%) + +-include $(wildcard tools/*.d) From 6bd9590b33742f1cceecc0c0d81b3caf3d8a4e1a Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 3 Dec 2016 15:36:32 +0100 Subject: [PATCH 0658/3374] build: Have old H.264/HEVC nvenc encoders select their new counterparts This makes sense and takes care of missing build dependencies. --- configure | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 118309061359d..98b123aee84a3 100755 --- a/configure +++ b/configure @@ -2234,8 +2234,8 @@ vc1_qsv_decoder_select="qsvdec vc1_qsv_hwaccel vc1_parser" vp8_qsv_decoder_deps="libmfx" vp8_qsv_decoder_select="qsvdec vp8_qsv_hwaccel vp8_parser" -nvenc_h264_encoder_deps="nvenc" -nvenc_hevc_encoder_deps="nvenc" +nvenc_h264_encoder_select="h264_nvenc_encoder" +nvenc_hevc_encoder_select="hevc_nvenc_encoder" # parsers h264_parser_select="golomb h264dsp h264parse" From c833c2034f4ee77fe2ee3470f3f5f84415673b3b Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 7 Dec 2016 15:27:37 +0100 Subject: [PATCH 0659/3374] build: Ensure that the "all" target appears before all Makefile includes Otherwise builds without explicit target result in silent no-ops. --- Makefile | 3 +++ common.mak | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index b090007f1e755..ec04d19d79906 100644 --- a/Makefile +++ b/Makefile @@ -106,6 +106,9 @@ DATA_FILES := $(wildcard $(SRC_PATH)/presets/*.avpreset) SKIPHEADERS = cmdutils_common_opts.h \ compat/w32pthreads.h +# first so "all" becomes default target +all: all-yes + include $(SRC_PATH)/tools/Makefile include $(SRC_PATH)/common.mak diff --git a/common.mak b/common.mak index 7773693b96bab..d73addeffe927 100644 --- a/common.mak +++ b/common.mak @@ -2,9 +2,6 @@ # common bits used by all libraries # -# first so "all" becomes default target -all: all-yes - include $(SRC_PATH)/arch.mak OBJS += $(OBJS-yes) From 624aa8ab221cf34693f9a8c5ab67219cf560f2bb Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 3 Dec 2016 15:55:21 +0000 Subject: [PATCH 0660/3374] build: Add missing Makefile entries and ifdefs for QSV hwaccels --- libavcodec/Makefile | 5 +++++ libavcodec/qsvdec_h2645.c | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 0beeda4ea26a8..1d70fc1cd80a8 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -622,24 +622,29 @@ OBJS-$(CONFIG_VDPAU) += vdpau.o OBJS-$(CONFIG_H263_VAAPI_HWACCEL) += vaapi_mpeg4.o OBJS-$(CONFIG_H264_D3D11VA_HWACCEL) += dxva2_h264.o OBJS-$(CONFIG_H264_DXVA2_HWACCEL) += dxva2_h264.o +OBJS-$(CONFIG_H264_QSV_HWACCEL) += qsvdec_h2645.o OBJS-$(CONFIG_H264_VAAPI_HWACCEL) += vaapi_h264.o OBJS-$(CONFIG_H264_VDA_HWACCEL) += vda_h264.o OBJS-$(CONFIG_H264_VDPAU_HWACCEL) += vdpau_h264.o OBJS-$(CONFIG_HEVC_D3D11VA_HWACCEL) += dxva2_hevc.o OBJS-$(CONFIG_HEVC_DXVA2_HWACCEL) += dxva2_hevc.o +OBJS-$(CONFIG_HEVC_QSV_HWACCEL) += qsvdec_h2645.o OBJS-$(CONFIG_HEVC_VDPAU_HWACCEL) += vdpau_hevc.o OBJS-$(CONFIG_MPEG1_VDPAU_HWACCEL) += vdpau_mpeg12.o OBJS-$(CONFIG_MPEG2_D3D11VA_HWACCEL) += dxva2_mpeg2.o OBJS-$(CONFIG_MPEG2_DXVA2_HWACCEL) += dxva2_mpeg2.o +OBJS-$(CONFIG_MPEG2_QSV_HWACCEL) += qsvdec_other.o OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL) += vaapi_mpeg2.o OBJS-$(CONFIG_MPEG2_VDPAU_HWACCEL) += vdpau_mpeg12.o OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL) += vaapi_mpeg4.o OBJS-$(CONFIG_MPEG4_VDPAU_HWACCEL) += vdpau_mpeg4.o OBJS-$(CONFIG_VC1_D3D11VA_HWACCEL) += dxva2_vc1.o OBJS-$(CONFIG_VC1_DXVA2_HWACCEL) += dxva2_vc1.o +OBJS-$(CONFIG_VC1_QSV_HWACCEL) += qsvdec_other.o OBJS-$(CONFIG_VC1_VAAPI_HWACCEL) += vaapi_vc1.o OBJS-$(CONFIG_VC1_VDPAU_HWACCEL) += vdpau_vc1.o OBJS-$(CONFIG_VP8_VAAPI_HWACCEL) += vaapi_vp8.o +OBJS-$(CONFIG_VP8_QSV_HWACCEL) += qsvdec_other.o # libavformat dependencies OBJS-$(CONFIG_ISO_MEDIA) += mpeg4audio.o mpegaudiodata.o diff --git a/libavcodec/qsvdec_h2645.c b/libavcodec/qsvdec_h2645.c index a26f1505e5399..34b12cb0dbb07 100644 --- a/libavcodec/qsvdec_h2645.c +++ b/libavcodec/qsvdec_h2645.c @@ -228,14 +228,16 @@ static void qsv_decode_flush(AVCodecContext *avctx) #define OFFSET(x) offsetof(QSVH2645Context, x) #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM -#if CONFIG_HEVC_QSV_DECODER +#if CONFIG_HEVC_QSV_HWACCEL AVHWAccel ff_hevc_qsv_hwaccel = { .name = "hevc_qsv", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_HEVC, .pix_fmt = AV_PIX_FMT_QSV, }; +#endif +#if CONFIG_HEVC_QSV_DECODER static const AVOption hevc_options[] = { { "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 0, INT_MAX, VD }, @@ -275,14 +277,16 @@ AVCodec ff_hevc_qsv_decoder = { }; #endif -#if CONFIG_H264_QSV_DECODER +#if CONFIG_H264_QSV_HWACCEL AVHWAccel ff_h264_qsv_hwaccel = { .name = "h264_qsv", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .pix_fmt = AV_PIX_FMT_QSV, }; +#endif +#if CONFIG_H264_QSV_DECODER static const AVOption options[] = { { "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 0, INT_MAX, VD }, { NULL }, From 075acbb6ff5740b2eea1bb7dd3afbc8e66e2ebf8 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Thu, 10 Nov 2016 14:26:18 -0500 Subject: [PATCH 0661/3374] lavu: Add a video section to Doxygen documentation Fill it with AVStereo3D and AVDisplayMatrix documentation. Apply the necessary changes to make verbatim code look good in doxygen. Signed-off-by: Vittorio Giovara --- libavutil/avutil.h | 6 ++++++ libavutil/display.h | 27 +++++++++++++++++++++++++++ libavutil/stereo3d.h | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/libavutil/avutil.h b/libavutil/avutil.h index c49685aecfad9..2339fe3c9c204 100644 --- a/libavutil/avutil.h +++ b/libavutil/avutil.h @@ -115,6 +115,12 @@ * * @} * + * @defgroup lavu_video Video related + * + * @{ + * + * @} + * * @defgroup lavu_audio Audio related * * @{ diff --git a/libavutil/display.h b/libavutil/display.h index dba3b1e60d1f5..2d869fcd16866 100644 --- a/libavutil/display.h +++ b/libavutil/display.h @@ -18,21 +18,37 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +/** + * @file + * Display matrix + */ + #ifndef AVUTIL_DISPLAY_H #define AVUTIL_DISPLAY_H #include /** + * @addtogroup lavu_video + * @{ + * + * @defgroup lavu_video_display Display transformation matrix functions + * @{ + */ + +/** + * @addtogroup lavu_video_display * The display transformation matrix specifies an affine transformation that * should be applied to video frames for correct presentation. It is compatible * with the matrices stored in the ISO/IEC 14496-12 container format. * * The data is a 3x3 matrix represented as a 9-element array: * + * @code{.unparsed} * | a b u | * (a, b, u, c, d, v, x, y, w) -> | c d v | * | x y w | + * @endcode * * All numbers are stored in native endianness, as 16.16 fixed-point values, * except for u, v and w, which are stored as 2.30 fixed-point values. @@ -40,15 +56,21 @@ * The transformation maps a point (p, q) in the source (pre-transformation) * frame to the point (p', q') in the destination (post-transformation) frame as * follows: + * + * @code{.unparsed} * | a b u | * (p, q, 1) . | c d v | = z * (p', q', 1) * | x y w | + * @endcode * * The transformation can also be more explicitly written in components as * follows: + * + * @code{.unparsed} * p' = (a * p + c * q + x) / z; * q' = (b * p + d * q + y) / z; * z = u * p + v * q + w + * @endcode */ /** @@ -83,4 +105,9 @@ void av_display_rotation_set(int32_t matrix[9], double angle); */ void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip); +/** + * @} + * @} + */ + #endif /* AVUTIL_DISPLAY_H */ diff --git a/libavutil/stereo3d.h b/libavutil/stereo3d.h index 28156fc710a93..0fa9f63a2ca63 100644 --- a/libavutil/stereo3d.h +++ b/libavutil/stereo3d.h @@ -18,6 +18,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +/** + * @file + * Stereoscopic video + */ + #ifndef AVUTIL_STEREO3D_H #define AVUTIL_STEREO3D_H @@ -25,6 +30,21 @@ #include "frame.h" +/** + * @addtogroup lavu_video + * @{ + * + * @defgroup lavu_video_stereo3d Stereo3D types and functions + * @{ + */ + +/** + * @addtogroup lavu_video_stereo3d + * A stereoscopic video file consists in multiple views embedded in a single + * frame, usually describing two views of a scene. This file describes all + * possible codec-independent view arrangements. + * */ + /** * List of possible 3D Types */ @@ -37,41 +57,49 @@ enum AVStereo3DType { /** * Views are next to each other. * + * @code{.unparsed} * LLLLRRRR * LLLLRRRR * LLLLRRRR * ... + * @endcode */ AV_STEREO3D_SIDEBYSIDE, /** * Views are on top of each other. * + * @code{.unparsed} * LLLLLLLL * LLLLLLLL * RRRRRRRR * RRRRRRRR + * @endcode */ AV_STEREO3D_TOPBOTTOM, /** * Views are alternated temporally. * + * @code{.unparsed} * frame0 frame1 frame2 ... * LLLLLLLL RRRRRRRR LLLLLLLL * LLLLLLLL RRRRRRRR LLLLLLLL * LLLLLLLL RRRRRRRR LLLLLLLL * ... ... ... + * @endcode */ AV_STEREO3D_FRAMESEQUENCE, /** * Views are packed in a checkerboard-like structure per pixel. * + * @code{.unparsed} * LRLRLRLR * RLRLRLRL * LRLRLRLR * ... + * @endcode */ AV_STEREO3D_CHECKERBOARD, @@ -79,30 +107,36 @@ enum AVStereo3DType { * Views are next to each other, but when upscaling * apply a checkerboard pattern. * + * @code{.unparsed} * LLLLRRRR L L L L R R R R * LLLLRRRR => L L L L R R R R * LLLLRRRR L L L L R R R R * LLLLRRRR L L L L R R R R + * @endcode */ AV_STEREO3D_SIDEBYSIDE_QUINCUNX, /** * Views are packed per line, as if interlaced. * + * @code{.unparsed} * LLLLLLLL * RRRRRRRR * LLLLLLLL * ... + * @endcode */ AV_STEREO3D_LINES, /** * Views are packed per column. * + * @code{.unparsed} * LRLRLRLR * LRLRLRLR * LRLRLRLR * ... + * @endcode */ AV_STEREO3D_COLUMNS, }; @@ -167,4 +201,9 @@ const char *av_stereo3d_type_name(unsigned int type); */ int av_stereo3d_from_name(const char *name); +/** + * @} + * @} + */ + #endif /* AVUTIL_STEREO3D_H */ From c70add61d1551bf31734f7ef7d87824ff5389280 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Mon, 7 Nov 2016 13:09:03 -0500 Subject: [PATCH 0662/3374] lavu: Add AVSphericalMapping type and frame side data While no decoder currently exports spherical information, this type represents a frame property that has to be passed through from container to frames. Signed-off-by: Vittorio Giovara --- doc/APIchanges | 4 ++ libavutil/Makefile | 2 + libavutil/frame.h | 6 ++ libavutil/spherical.c | 34 +++++++++++ libavutil/spherical.h | 137 ++++++++++++++++++++++++++++++++++++++++++ libavutil/version.h | 2 +- 6 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 libavutil/spherical.c create mode 100644 libavutil/spherical.h diff --git a/doc/APIchanges b/doc/APIchanges index 90c65007649e8..c330310cabee9 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,10 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-xx-xx - xxxxxxx - lavu 55.30.0 - spherical.h + Add AV_FRAME_DATA_SPHERICAL value, av_spherical_alloc() API and + AVSphericalMapping type to export and describe spherical video properties. + 2016-xx-xx - xxxxxxx - lavf 57.10.0 - avformat.h Add av_stream_add_side_data(). diff --git a/libavutil/Makefile b/libavutil/Makefile index fbcf1a757fd7f..28372c9befe28 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -48,6 +48,7 @@ HEADERS = adler32.h \ replaygain.h \ samplefmt.h \ sha.h \ + spherical.h \ stereo3d.h \ time.h \ version.h \ @@ -102,6 +103,7 @@ OBJS = adler32.o \ rc4.o \ samplefmt.o \ sha.o \ + spherical.o \ stereo3d.o \ time.o \ tree.o \ diff --git a/libavutil/frame.h b/libavutil/frame.h index 12624d797f022..4052199fd3e3e 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -92,6 +92,12 @@ enum AVFrameSideDataType { * enum AVAudioServiceType defined in avcodec.h. */ AV_FRAME_DATA_AUDIO_SERVICE_TYPE, + + /** + * The data represents the AVSphericalMapping structure defined in + * libavutil/spherical.h. + */ + AV_FRAME_DATA_SPHERICAL, }; enum AVActiveFormatDescription { diff --git a/libavutil/spherical.c b/libavutil/spherical.c new file mode 100644 index 0000000000000..f6e53d1bd2f14 --- /dev/null +++ b/libavutil/spherical.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016 Vittorio Giovara + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "mem.h" +#include "spherical.h" + +AVSphericalMapping *av_spherical_alloc(size_t *size) +{ + AVSphericalMapping *spherical = av_mallocz(sizeof(AVSphericalMapping)); + if (!spherical) + return NULL; + + if (size) + *size = sizeof(*spherical); + + return spherical; +} diff --git a/libavutil/spherical.h b/libavutil/spherical.h new file mode 100644 index 0000000000000..8ecaefd946db5 --- /dev/null +++ b/libavutil/spherical.h @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2016 Vittorio Giovara + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Spherical video + */ + +#ifndef AVUTIL_SPHERICAL_H +#define AVUTIL_SPHERICAL_H + +/** + * @addtogroup lavu_video + * @{ + * + * @defgroup lavu_video_spherical Spherical video mapping + * @{ + */ + +/** + * @addtogroup lavu_video_spherical + * A spherical video file contains surfaces that need to be mapped onto a + * sphere. Depending on how the frame was converted, a different distortion + * transformation or surface recomposition function needs to be applied before + * the video should be mapped and displayed. + */ + +/** + * Projection of the video surface(s) on a sphere. + */ +enum AVSphericalProjection { + /** + * Video represents a sphere mapped on a flat surface using + * equirectangular projection. + */ + AV_SPHERICAL_EQUIRECTANGULAR, + + /** + * Video frame is split into 6 faces of a cube, and arranged on a + * 3x2 layout. Faces are oriented upwards for the front, left, right, + * and back faces. The up face is oriented so the top of the face is + * forwards and the down face is oriented so the top of the face is + * to the back. + */ + AV_SPHERICAL_CUBEMAP, +}; + +/** + * This structure describes how to handle spherical videos, outlining + * information about projection, initial layout, and any other view modifier. + * + * @note The struct must be allocated with av_spherical_alloc() and + * its size is not a part of the public ABI. + */ +typedef struct AVSphericalMapping { + /** + * Projection type. + */ + enum AVSphericalProjection projection; + + /** + * @name Initial orientation + * @{ + * There fields describe additional rotations applied to the sphere after + * the video frame is mapped onto it. The sphere is rotated around the + * viewer, who remains stationary. The order of transformation is always + * yaw, followed by pitch, and finally by roll. + * + * The coordinate system matches the one defined in OpenGL, where the + * forward vector (z) is coming out of screen, and it is equivalent to + * a rotation matrix of R = r_y(yaw) * r_x(pitch) * r_z(roll). + * + * A positive yaw rotates the portion of the sphere in front of the viewer + * toward their right. A positive pitch rotates the portion of the sphere + * in front of the viewer upwards. A positive roll tilts the portion of + * the sphere in front of the viewer to the viewer's right. + * + * These values are exported as 16.16 fixed point. + * + * See this equirectangular projection as example: + * + * @code{.unparsed} + * Yaw + * -180 0 180 + * 90 +-------------+-------------+ 180 + * | | | up + * P | | | y| forward + * i | ^ | | /z + * t 0 +-------------X-------------+ 0 Roll | / + * c | | | | / + * h | | | 0|/_____right + * | | | x + * -90 +-------------+-------------+ -180 + * + * X - the default camera center + * ^ - the default up vector + * @endcode + */ + int32_t yaw; ///< Rotation around the up vector [-180, 180]. + int32_t pitch; ///< Rotation around the right vector [-90, 90]. + int32_t roll; ///< Rotation around the forward vector [-180, 180]. + /** + * @} + */ +} AVSphericalMapping; + +/** + * Allocate a AVSphericalVideo structure and initialize its fields to default + * values. + * + * @return the newly allocated struct or NULL on failure + */ +AVSphericalMapping *av_spherical_alloc(size_t *size); + +/** + * @} + * @} + */ + +#endif /* AVUTIL_SPHERICAL_H */ diff --git a/libavutil/version.h b/libavutil/version.h index f1102312bacc7..e9940f2518af2 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -54,7 +54,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 29 +#define LIBAVUTIL_VERSION_MINOR 30 #define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From 2fb6acd9c28907e4f8c0510099a4603ea6caf861 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Wed, 2 Nov 2016 11:28:54 -0400 Subject: [PATCH 0663/3374] lavc: Add spherical packet side data API Signed-off-by: Vittorio Giovara --- avprobe.c | 21 +++++++++++++++++++++ doc/APIchanges | 4 ++++ libavcodec/avcodec.h | 6 ++++++ libavcodec/decode.c | 1 + libavcodec/version.h | 4 ++-- libavformat/dump.c | 30 ++++++++++++++++++++++++++++++ libavutil/version.h | 2 +- 7 files changed, 65 insertions(+), 3 deletions(-) diff --git a/avprobe.c b/avprobe.c index ff28a0b343133..8142ce2966840 100644 --- a/avprobe.c +++ b/avprobe.c @@ -27,6 +27,7 @@ #include "libavutil/display.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" +#include "libavutil/spherical.h" #include "libavutil/stereo3d.h" #include "libavutil/dict.h" #include "libavutil/libm.h" @@ -766,6 +767,7 @@ static void show_stream(InputFile *ifile, InputStream *ist) for (i = 0; i < stream->nb_side_data; i++) { const AVPacketSideData* sd = &stream->side_data[i]; AVStereo3D *stereo; + AVSphericalMapping *spherical; switch (sd->type) { case AV_PKT_DATA_DISPLAYMATRIX: @@ -786,6 +788,25 @@ static void show_stream(InputFile *ifile, InputStream *ist) !!(stereo->flags & AV_STEREO3D_FLAG_INVERT)); probe_object_footer("stereo3d"); break; + case AV_PKT_DATA_SPHERICAL: + spherical = (AVSphericalMapping *)sd->data; + probe_object_header("spherical"); + + if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR) + probe_str("projection", "equirectangular"); + else if (spherical->projection == AV_SPHERICAL_CUBEMAP) + probe_str("projection", "cubemap"); + else + probe_str("projection", "unknown"); + + probe_object_header("orientation"); + probe_int("yaw", (double) spherical->yaw / (1 << 16)); + probe_int("pitch", (double) spherical->pitch / (1 << 16)); + probe_int("roll", (double) spherical->roll / (1 << 16)); + probe_object_footer("orientation"); + + probe_object_footer("spherical"); + break; } } probe_object_footer("sidedata"); diff --git a/doc/APIchanges b/doc/APIchanges index c330310cabee9..d5dc5edaa5808 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,10 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-xx-xx - xxxxxxx - lavc 57.29.0 - avcodec.h + Add AV_PKT_DATA_SPHERICAL packet side data to export AVSphericalMapping + information from containers. + 2016-xx-xx - xxxxxxx - lavu 55.30.0 - spherical.h Add AV_FRAME_DATA_SPHERICAL value, av_spherical_alloc() API and AVSphericalMapping type to export and describe spherical video properties. diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index e75d300ba0bc0..6e1ed74e08001 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1289,6 +1289,12 @@ enum AVPacketSideDataType { * This side data corresponds to the AVCPBProperties struct. */ AV_PKT_DATA_CPB_PROPERTIES, + + /** + * This side data should be associated with a video stream and corresponds + * to the AVSphericalMapping structure. + */ + AV_PKT_DATA_SPHERICAL, }; typedef struct AVPacketSideData { diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 42bcee2d179aa..00085c3b4dcc8 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -747,6 +747,7 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) } sd[] = { { AV_PKT_DATA_REPLAYGAIN , AV_FRAME_DATA_REPLAYGAIN }, { AV_PKT_DATA_DISPLAYMATRIX, AV_FRAME_DATA_DISPLAYMATRIX }, + { AV_PKT_DATA_SPHERICAL, AV_FRAME_DATA_SPHERICAL }, { AV_PKT_DATA_STEREO3D, AV_FRAME_DATA_STEREO3D }, { AV_PKT_DATA_AUDIO_SERVICE_TYPE, AV_FRAME_DATA_AUDIO_SERVICE_TYPE }, }; diff --git a/libavcodec/version.h b/libavcodec/version.h index 6f58bc8c513aa..adab9b47a3446 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 28 -#define LIBAVCODEC_VERSION_MICRO 4 +#define LIBAVCODEC_VERSION_MINOR 30 +#define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavformat/dump.c b/libavformat/dump.c index 3b50f5d944227..660df0a533f44 100644 --- a/libavformat/dump.c +++ b/libavformat/dump.c @@ -27,6 +27,7 @@ #include "libavutil/log.h" #include "libavutil/mathematics.h" #include "libavutil/replaygain.h" +#include "libavutil/spherical.h" #include "libavutil/stereo3d.h" #include "avformat.h" @@ -306,6 +307,31 @@ static void dump_cpb(void *ctx, AVPacketSideData *sd) cpb->vbv_delay); } +static void dump_spherical(void *ctx, AVPacketSideData *sd) +{ + AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data; + double yaw, pitch, roll; + + if (sd->size < sizeof(*spherical)) { + av_log(ctx, AV_LOG_INFO, "invalid data"); + return; + } + + if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR) + av_log(ctx, AV_LOG_INFO, "equirectangular "); + else if (spherical->projection == AV_SPHERICAL_CUBEMAP) + av_log(ctx, AV_LOG_INFO, "cubemap "); + else { + av_log(ctx, AV_LOG_WARNING, "unknown"); + return; + } + + yaw = ((double)spherical->yaw) / (1 << 16); + pitch = ((double)spherical->pitch) / (1 << 16); + roll = ((double)spherical->roll) / (1 << 16); + av_log(ctx, AV_LOG_INFO, "(%f/%f/%f) ", yaw, pitch, roll); +} + static void dump_sidedata(void *ctx, AVStream *st, const char *indent) { int i; @@ -354,6 +380,10 @@ static void dump_sidedata(void *ctx, AVStream *st, const char *indent) av_log(ctx, AV_LOG_INFO, "cpb: "); dump_cpb(ctx, &sd); break; + case AV_PKT_DATA_SPHERICAL: + av_log(ctx, AV_LOG_INFO, "spherical: "); + dump_spherical(ctx, &sd); + break; default: av_log(ctx, AV_LOG_WARNING, "unknown side data type %d (%d bytes)", sd.type, sd.size); diff --git a/libavutil/version.h b/libavutil/version.h index e9940f2518af2..f1102312bacc7 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -54,7 +54,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 30 +#define LIBAVUTIL_VERSION_MINOR 29 #define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From e90137c045721a1635cc241eb1e1be1126389c38 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Wed, 2 Nov 2016 11:29:15 -0400 Subject: [PATCH 0664/3374] mov: Export spherical information This implements Spherical Video V1 and V2, as described in the spatial-media collection by Google. Signed-off-by: Vittorio Giovara --- Changelog | 1 + libavformat/isom.h | 6 + libavformat/mov.c | 262 ++++++++++++++++++++++++++++++++++++++++++ libavformat/version.h | 2 +- 4 files changed, 270 insertions(+), 1 deletion(-) diff --git a/Changelog b/Changelog index cd0ffb52135e7..feb151cf3cb96 100644 --- a/Changelog +++ b/Changelog @@ -2,6 +2,7 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. version : +- Support for spherical videos version 12: diff --git a/libavformat/isom.h b/libavformat/isom.h index 1aa20910430da..fa73ad91bb6cd 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -24,6 +24,9 @@ #ifndef AVFORMAT_ISOM_H #define AVFORMAT_ISOM_H +#include "libavutil/spherical.h" +#include "libavutil/stereo3d.h" + #include "avio.h" #include "internal.h" #include "dv.h" @@ -145,6 +148,9 @@ typedef struct MOVStreamContext { int stsd_count; int32_t *display_matrix; + AVStereo3D *stereo3d; + AVSphericalMapping *spherical; + size_t spherical_size; } MOVStreamContext; typedef struct MOVContext { diff --git a/libavformat/mov.c b/libavformat/mov.c index 28adce76c3c8b..7fe639dd5ed2f 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -37,6 +37,8 @@ #include "libavutil/dict.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" +#include "libavutil/spherical.h" +#include "libavutil/stereo3d.h" #include "libavcodec/ac3tab.h" #include "avformat.h" #include "internal.h" @@ -3174,6 +3176,242 @@ static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; } +static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ + AVStream *st; + MOVStreamContext *sc; + enum AVStereo3DType type; + int mode; + + if (c->fc->nb_streams < 1) + return 0; + + st = c->fc->streams[c->fc->nb_streams - 1]; + sc = st->priv_data; + + if (atom.size < 5) { + av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n"); + return AVERROR_INVALIDDATA; + } + avio_skip(pb, 4); /* version + flags */ + + mode = avio_r8(pb); + switch (mode) { + case 0: + type = AV_STEREO3D_2D; + break; + case 1: + type = AV_STEREO3D_TOPBOTTOM; + break; + case 2: + type = AV_STEREO3D_SIDEBYSIDE; + break; + default: + av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode); + return 0; + } + + sc->stereo3d = av_stereo3d_alloc(); + if (!sc->stereo3d) + return AVERROR(ENOMEM); + + sc->stereo3d->type = type; + return 0; +} + +static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ + AVStream *st; + MOVStreamContext *sc; + int size; + int32_t yaw, pitch, roll; + uint32_t tag; + enum AVSphericalProjection projection; + + if (c->fc->nb_streams < 1) + return 0; + + st = c->fc->streams[c->fc->nb_streams - 1]; + sc = st->priv_data; + + if (atom.size < 8) { + av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n"); + return AVERROR_INVALIDDATA; + } + + size = avio_rb32(pb); + if (size > atom.size) + return AVERROR_INVALIDDATA; + + tag = avio_rl32(pb); + if (tag != MKTAG('s','v','h','d')) { + av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n"); + return 0; + } + avio_skip(pb, 4); /* version + flags */ + avio_skip(pb, avio_r8(pb)); /* metadata_source */ + + size = avio_rb32(pb); + if (size > atom.size) + return AVERROR_INVALIDDATA; + + tag = avio_rl32(pb); + if (tag != MKTAG('p','r','o','j')) { + av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n"); + return 0; + } + + size = avio_rb32(pb); + if (size > atom.size) + return AVERROR_INVALIDDATA; + + tag = avio_rl32(pb); + if (tag != MKTAG('p','r','h','d')) { + av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n"); + return 0; + } + avio_skip(pb, 4); /* version + flags */ + + /* 16.16 fixed point */ + yaw = avio_rb32(pb); + pitch = avio_rb32(pb); + roll = avio_rb32(pb); + + size = avio_rb32(pb); + if (size > atom.size) + return AVERROR_INVALIDDATA; + + tag = avio_rl32(pb); + avio_skip(pb, 4); /* version + flags */ + switch (tag) { + case MKTAG('c','b','m','p'): + projection = AV_SPHERICAL_CUBEMAP; + break; + case MKTAG('e','q','u','i'): + projection = AV_SPHERICAL_EQUIRECTANGULAR; + break; + default: + av_log(c->fc, AV_LOG_ERROR, "Unknown projection type\n"); + return 0; + } + + sc->spherical = av_spherical_alloc(&sc->spherical_size); + if (!sc->spherical) + return AVERROR(ENOMEM); + + sc->spherical->projection = projection; + + sc->spherical->yaw = yaw; + sc->spherical->pitch = pitch; + sc->spherical->roll = roll; + + return 0; +} + +static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len) +{ + int ret = 0; + uint8_t *buffer = av_malloc(len + 1); + const char *val; + + if (!buffer) + return AVERROR(ENOMEM); + buffer[len] = '\0'; + + ret = ffio_read_size(pb, buffer, len); + if (ret < 0) + goto out; + + /* Check for mandatory keys and values, try to support XML as best-effort */ + if (av_stristr(buffer, "") && + (val = av_stristr(buffer, "")) && + av_stristr(val, "true") && + (val = av_stristr(buffer, "")) && + av_stristr(val, "true") && + (val = av_stristr(buffer, "")) && + av_stristr(val, "equirectangular")) { + sc->spherical = av_spherical_alloc(&sc->spherical_size); + if (!sc->spherical) + goto out; + + sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR; + + if (av_stristr(buffer, "")) { + enum AVStereo3DType mode; + + if (av_stristr(buffer, "left-right")) + mode = AV_STEREO3D_SIDEBYSIDE; + else if (av_stristr(buffer, "top-bottom")) + mode = AV_STEREO3D_TOPBOTTOM; + else + mode = AV_STEREO3D_2D; + + sc->stereo3d = av_stereo3d_alloc(); + if (!sc->stereo3d) + goto out; + + sc->stereo3d->type = mode; + } + + /* orientation */ + val = av_stristr(buffer, ""); + if (val) + sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16); + val = av_stristr(buffer, ""); + if (val) + sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16); + val = av_stristr(buffer, ""); + if (val) + sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16); + } + +out: + av_free(buffer); + return ret; +} + +static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ + AVStream *st; + MOVStreamContext *sc; + int ret; + + uint8_t uuid[16]; + static const uint8_t uuid_spherical[] = { + 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93, + 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd, + }; + + if (atom.size < sizeof(uuid) || atom.size == INT64_MAX) + return AVERROR_INVALIDDATA; + + if (c->fc->nb_streams < 1) + return 0; + st = c->fc->streams[c->fc->nb_streams - 1]; + sc = st->priv_data; + + ret = ffio_read_size(pb, uuid, sizeof(uuid)); + if (ret < 0) + return ret; + + if (!memcmp(uuid, uuid_spherical, sizeof(uuid)) && !sc->spherical) { + size_t len = atom.size - sizeof(uuid); + ret = mov_parse_uuid_spherical(sc, pb, len); + if (ret < 0) + return ret; + if (!sc->spherical) + av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n"); + } else { + int i; + av_log(c->fc, AV_LOG_VERBOSE, "Unknown UUID found: 0x"); + for (i = 0; i < sizeof(uuid); i++) + av_log(c->fc, AV_LOG_WARNING, "%02x", uuid[i]); + av_log(c->fc, AV_LOG_WARNING, "\n"); + } + + return 0; +} + static const MOVParseTableEntry mov_default_parse_table[] = { { MKTAG('a','v','s','s'), mov_read_extradata }, { MKTAG('c','h','p','l'), mov_read_chpl }, @@ -3235,6 +3473,9 @@ static const MOVParseTableEntry mov_default_parse_table[] = { { MKTAG('d','v','c','1'), mov_read_dvc1 }, { MKTAG('s','b','g','p'), mov_read_sbgp }, { MKTAG('h','v','c','C'), mov_read_glbl }, +{ MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */ +{ MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */ +{ MKTAG('u','u','i','d'), mov_read_uuid }, /* universal unique identifier */ { MKTAG('-','-','-','-'), mov_read_custom }, { 0, NULL } }; @@ -3463,6 +3704,9 @@ static int mov_read_close(AVFormatContext *s) av_free(sc->extradata[j]); av_freep(&sc->extradata); av_freep(&sc->extradata_size); + + av_freep(&sc->stereo3d); + av_freep(&sc->spherical); } if (mov->dv_demux) { @@ -3553,6 +3797,24 @@ static int mov_read_header(AVFormatContext *s) sc->display_matrix = NULL; } + if (sc->stereo3d) { + err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D, + (uint8_t *)sc->stereo3d, + sizeof(*sc->stereo3d)); + if (err < 0) + return err; + + sc->stereo3d = NULL; + } + if (sc->spherical) { + err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL, + (uint8_t *)sc->spherical, + sc->spherical_size); + if (err < 0) + return err; + + sc->spherical = NULL; + } break; } } diff --git a/libavformat/version.h b/libavformat/version.h index c6085f85916b8..ad7997ec4fd1c 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -31,7 +31,7 @@ #define LIBAVFORMAT_VERSION_MAJOR 57 #define LIBAVFORMAT_VERSION_MINOR 10 -#define LIBAVFORMAT_VERSION_MICRO 0 +#define LIBAVFORMAT_VERSION_MICRO 1 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ From 68f8db610871b810ba3ae946538d43a9e7cedf1e Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Thu, 1 Dec 2016 12:38:18 -0500 Subject: [PATCH 0665/3374] avprobe: Allow specifying multiple stream entries to be shown --- avprobe.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/avprobe.c b/avprobe.c index 8142ce2966840..f0c942ad637d7 100644 --- a/avprobe.c +++ b/avprobe.c @@ -1033,6 +1033,8 @@ static int opt_show_format_entry(void *optctx, const char *opt, const char *arg) static int opt_show_stream_entry(void *optctx, const char *opt, const char *arg) { + const char *p = arg; + do_show_streams = 1; nb_stream_entries_to_show++; octx.print_header = NULL; @@ -1044,7 +1046,19 @@ static int opt_show_stream_entry(void *optctx, const char *opt, const char *arg) octx.print_integer = show_stream_entry_integer; octx.print_string = show_stream_entry_string; - av_dict_set(&stream_entries_to_show, arg, "", 0); + + while (*p) { + char *val = av_get_token(&p, ","); + if (!val) + return AVERROR(ENOMEM); + + av_dict_set(&stream_entries_to_show, val, "", 0); + + av_free(val); + if (*p) + p++; + } + return 0; } @@ -1099,7 +1113,7 @@ static const OptionDef real_options[] = { { "show_packets", OPT_BOOL, {&do_show_packets}, "show packets info" }, { "show_streams", OPT_BOOL, {&do_show_streams}, "show streams info" }, { "show_stream_entry", HAS_ARG, {.func_arg = opt_show_stream_entry}, - "show a particular entry from all streams", "entry" }, + "show a particular entry from all streams (comma separated)", "entry" }, { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {.func_arg = opt_default}, "generic catch all option", "" }, { NULL, }, From cf1cae58b015427918ecfa507a045aae4cf398fd Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Wed, 30 Nov 2016 17:53:38 -0500 Subject: [PATCH 0666/3374] fate: Add spherical and stereo3d mov tests --- tests/fate/mov.mak | 6 ++++++ tests/ref/fate/mov-spherical | 4 ++++ tests/ref/fate/mov-stereo3d | 1 + 3 files changed, 11 insertions(+) create mode 100644 tests/ref/fate/mov-spherical create mode 100644 tests/ref/fate/mov-stereo3d diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak index 909e4389d469a..57cbb1cac0e72 100644 --- a/tests/fate/mov.mak +++ b/tests/fate/mov.mak @@ -10,6 +10,12 @@ fate-mov-rotation: CMD = probestream rotation $(TARGET_SAMPLES)/mov/displaymatri FATE_MOV += fate-mov-sar fate-mov-sar: CMD = probestream sample_aspect_ratio $(TARGET_SAMPLES)/mov/displaymatrix.mov +FATE_MOV += fate-mov-spherical +fate-mov-spherical: CMD = probestream projection,yaw,pitch,roll $(TARGET_SAMPLES)/mov/spherical.mov + +FATE_MOV += fate-mov-stereo3d +fate-mov-stereo3d: CMD = probestream type $(TARGET_SAMPLES)/mov/spherical.mov + $(FATE_MOV): avprobe$(EXESUF) FATE_SAMPLES-$(call ALLYES, AVPROBE MOV_DEMUXER) += $(FATE_MOV) fate-mov: $(FATE_MOV) diff --git a/tests/ref/fate/mov-spherical b/tests/ref/fate/mov-spherical new file mode 100644 index 0000000000000..760ae880e8817 --- /dev/null +++ b/tests/ref/fate/mov-spherical @@ -0,0 +1,4 @@ +equirectangular +45 +30 +15 diff --git a/tests/ref/fate/mov-stereo3d b/tests/ref/fate/mov-stereo3d new file mode 100644 index 0000000000000..fe909bb197ca4 --- /dev/null +++ b/tests/ref/fate/mov-stereo3d @@ -0,0 +1 @@ +2D From f912fd767e55bbb5a1554bd99bacab007659609c Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 8 Dec 2016 19:47:58 +0100 Subject: [PATCH 0667/3374] Add missing #includes for standalone spherical-information-related headers --- libavformat/isom.h | 3 +++ libavutil/spherical.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/libavformat/isom.h b/libavformat/isom.h index fa73ad91bb6cd..85b876106ff5d 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -24,6 +24,9 @@ #ifndef AVFORMAT_ISOM_H #define AVFORMAT_ISOM_H +#include +#include + #include "libavutil/spherical.h" #include "libavutil/stereo3d.h" diff --git a/libavutil/spherical.h b/libavutil/spherical.h index 8ecaefd946db5..0045eb974aef7 100644 --- a/libavutil/spherical.h +++ b/libavutil/spherical.h @@ -26,6 +26,9 @@ #ifndef AVUTIL_SPHERICAL_H #define AVUTIL_SPHERICAL_H +#include +#include + /** * @addtogroup lavu_video * @{ From fbec58daa2351cbe9fc758d8735c23ff03313db4 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 3 Dec 2016 15:26:40 +0100 Subject: [PATCH 0668/3374] build: Add an internal component for hevc_ps code This allows expressing dependencies in a more correct way. --- configure | 10 ++++++---- libavcodec/Makefile | 7 ++++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/configure b/configure index 98b123aee84a3..c48f352d3f785 100755 --- a/configure +++ b/configure @@ -1714,6 +1714,7 @@ CONFIG_EXTRA=" h264parse h264pred h264qpel + hevc_ps hpeldsp huffman huffyuvdsp @@ -1912,6 +1913,7 @@ error_resilience_select="me_cmp" faandct_deps="faan fdctdsp" faanidct_deps="faan idctdsp" h264dsp_select="startcode" +hevc_ps_select="golomb" intrax8_select="blockdsp idctdsp" mdct_select="fft" rdft_select="fft" @@ -1996,7 +1998,7 @@ h264_decoder_suggest="error_resilience" hap_decoder_select="snappy texturedsp" hap_encoder_deps="libsnappy" hap_encoder_select="texturedspenc" -hevc_decoder_select="bswapdsp cabac golomb videodsp" +hevc_decoder_select="bswapdsp cabac hevc_ps videodsp" huffyuv_decoder_select="bswapdsp huffyuvdsp" huffyuv_encoder_select="bswapdsp huffman huffyuvencdsp" iac_decoder_select="imc_decoder" @@ -2215,9 +2217,9 @@ h264_vaapi_encoder_deps="VAEncPictureParameterBufferH264" h264_vaapi_encoder_select="vaapi_encode golomb" hevc_nvenc_encoder_deps="nvenc" hevc_qsv_decoder_deps="libmfx" -hevc_qsv_encoder_deps="libmfx" hevc_qsv_decoder_select="hevc_mp4toannexb_bsf hevc_parser hevc_qsv_hwaccel qsvdec" -hevc_qsv_encoder_select="qsvenc" +hevc_qsv_encoder_deps="libmfx" +hevc_qsv_encoder_select="hevc_ps qsvenc" hevc_vaapi_encoder_deps="VAEncPictureParameterBufferHEVC" hevc_vaapi_encoder_select="vaapi_encode golomb" mjpeg_vaapi_encoder_deps="VAEncPictureParameterBufferJPEG" @@ -2239,7 +2241,7 @@ nvenc_hevc_encoder_select="hevc_nvenc_encoder" # parsers h264_parser_select="golomb h264dsp h264parse" -hevc_parser_select="golomb" +hevc_parser_select="hevc_ps" mpegaudio_parser_select="mpegaudioheader" mpegvideo_parser_select="mpegvideo" mpeg4video_parser_select="error_resilience h263dsp mpegvideo qpeldsp" diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 1d70fc1cd80a8..eeac45d4c82a9 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -65,6 +65,7 @@ OBJS-$(CONFIG_H264DSP) += h264dsp.o h264idct.o OBJS-$(CONFIG_H264PARSE) += h264_parse.o h2645_parse.o h264_ps.o OBJS-$(CONFIG_H264PRED) += h264pred.o OBJS-$(CONFIG_H264QPEL) += h264qpel.o +OBJS-$(CONFIG_HEVC_PS) += hevc_ps.o OBJS-$(CONFIG_HPELDSP) += hpeldsp.o OBJS-$(CONFIG_HUFFMAN) += huffman.o OBJS-$(CONFIG_HUFFYUVDSP) += huffyuvdsp.o @@ -266,13 +267,13 @@ OBJS-$(CONFIG_H264_QSV_ENCODER) += qsvenc_h264.o OBJS-$(CONFIG_H264_VAAPI_ENCODER) += vaapi_encode_h264.o vaapi_encode_h26x.o OBJS-$(CONFIG_HAP_DECODER) += hapdec.o hap.o OBJS-$(CONFIG_HAP_ENCODER) += hapenc.o hap.o -OBJS-$(CONFIG_HEVC_DECODER) += hevcdec.o hevc_mvs.o hevc_ps.o hevc_sei.o \ +OBJS-$(CONFIG_HEVC_DECODER) += hevcdec.o hevc_mvs.o hevc_sei.o \ hevc_cabac.o hevc_refs.o hevcpred.o \ hevcdsp.o hevc_filter.o h2645_parse.o hevc_data.o OBJS-$(CONFIG_HEVC_NVENC_ENCODER) += nvenc_hevc.o OBJS-$(CONFIG_HEVC_QSV_DECODER) += qsvdec_h2645.o OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc_ps_enc.o \ - h2645_parse.o hevc_ps.o hevc_data.o + h2645_parse.o hevc_data.o OBJS-$(CONFIG_HEVC_VAAPI_ENCODER) += vaapi_encode_h265.o vaapi_encode_h26x.o OBJS-$(CONFIG_HNM4_VIDEO_DECODER) += hnm4video.o OBJS-$(CONFIG_HQ_HQA_DECODER) += hq_hqa.o hq_hqadata.o hq_hqadsp.o \ @@ -731,7 +732,7 @@ OBJS-$(CONFIG_GSM_PARSER) += gsm_parser.o OBJS-$(CONFIG_H261_PARSER) += h261_parser.o OBJS-$(CONFIG_H263_PARSER) += h263_parser.o OBJS-$(CONFIG_H264_PARSER) += h264_parser.o h264_sei.o h264data.o -OBJS-$(CONFIG_HEVC_PARSER) += hevc_parser.o h2645_parse.o hevc_ps.o hevc_data.o +OBJS-$(CONFIG_HEVC_PARSER) += hevc_parser.o h2645_parse.o hevc_data.o OBJS-$(CONFIG_MJPEG_PARSER) += mjpeg_parser.o OBJS-$(CONFIG_MLP_PARSER) += mlp_parser.o mlp.o OBJS-$(CONFIG_MPEG4VIDEO_PARSER) += mpeg4video_parser.o h263.o \ From f55c0a64ae40dc8e0a131a590e123cd14d0c0f7a Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 7 Dec 2016 12:48:31 +0100 Subject: [PATCH 0669/3374] build: Drop stray golomb dependencies --- configure | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/configure b/configure index c48f352d3f785..c755aabb2d767 100755 --- a/configure +++ b/configure @@ -1971,13 +1971,13 @@ eamad_decoder_select="aandcttables blockdsp bswapdsp idctdsp mpegvideo" eatgq_decoder_select="aandcttables idctdsp" eatqi_decoder_select="aandcttables blockdsp bswapdsp idctdsp" exr_decoder_deps="zlib" -ffv1_decoder_select="golomb rangecoder" +ffv1_decoder_select="rangecoder" ffv1_encoder_select="rangecoder" ffvhuff_decoder_select="huffyuv_decoder" ffvhuff_encoder_select="huffyuv_encoder" fic_decoder_select="golomb" -flac_decoder_select="flacdsp golomb" -flac_encoder_select="bswapdsp flacdsp golomb lpc" +flac_decoder_select="flacdsp" +flac_encoder_select="bswapdsp flacdsp lpc" flashsv_decoder_deps="zlib" flashsv_encoder_deps="zlib" flashsv2_decoder_deps="zlib" @@ -2007,12 +2007,10 @@ indeo3_decoder_select="hpeldsp" indeo4_decoder_select="ividsp" indeo5_decoder_select="ividsp" interplay_video_decoder_select="hpeldsp" -jpegls_decoder_select="golomb mjpeg_decoder" -jpegls_encoder_select="golomb" +jpegls_decoder_select="mjpeg_decoder" jv_decoder_select="blockdsp" lagarith_decoder_select="huffyuvdsp" ljpeg_encoder_select="aandcttables idctdsp jpegtables" -loco_decoder_select="golomb" magicyuv_decoder_select="huffyuvdsp" mdec_decoder_select="blockdsp idctdsp mpegvideo" metasound_decoder_select="lsp mdct sinewin" @@ -2074,7 +2072,6 @@ rv20_encoder_select="h263_encoder" rv30_decoder_select="error_resilience golomb h264chroma h264pred h264qpel mpeg_er mpegvideo rv34dsp videodsp" rv40_decoder_select="error_resilience golomb h264chroma h264pred h264qpel mpeg_er mpegvideo rv34dsp videodsp" screenpresso_decoder_deps="zlib" -shorten_decoder_select="golomb" sipr_decoder_select="lsp" sp5x_decoder_select="mjpeg_decoder" svq1_decoder_select="hpeldsp" From 892acc70105df9e6f7773bdde85b3e9541098525 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 7 Dec 2016 19:43:57 +0100 Subject: [PATCH 0670/3374] configure: Fail if cuda was enabled and is not available This is the standard behavior for external libraries. --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index c755aabb2d767..165aa8075d68e 100755 --- a/configure +++ b/configure @@ -4619,7 +4619,7 @@ done # these are off by default, so fail if requested and not available enabled avisynth && { check_header avisynth/avisynth_c.h || die "ERROR: avisynth/avisynth_c.h header not found"; } enabled avxsynth && require avxsynth "avxsynth/avxsynth_c.h dlfcn.h" dlopen -ldl -enabled cuda && check_lib cuda.h cuInit -lcuda +enabled cuda && require cuda cuda.h cuInit -lcuda enabled frei0r && { check_header frei0r.h || die "ERROR: frei0r.h header not found"; } enabled gnutls && require_pkg_config gnutls gnutls/gnutls.h gnutls_global_init enabled libbs2b && require_pkg_config libbs2b bs2b.h bs2b_open From d5759701a82926059ae3e2530805e900041a5419 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 6 Dec 2016 23:25:58 +0100 Subject: [PATCH 0671/3374] libkvazaar: Add missing header #includes This fixes compilation after the next version bump. --- libavcodec/libkvazaar.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/libkvazaar.c b/libavcodec/libkvazaar.c index 19122e07175d1..efc98f1f65b55 100644 --- a/libavcodec/libkvazaar.c +++ b/libavcodec/libkvazaar.c @@ -21,12 +21,16 @@ */ #include +#include #include +#include "libavutil/attributes.h" #include "libavutil/dict.h" #include "libavutil/error.h" #include "libavutil/imgutils.h" #include "libavutil/internal.h" +#include "libavutil/log.h" +#include "libavutil/mem.h" #include "libavutil/pixdesc.h" #include "libavutil/opt.h" From 8c3a643808fc89c8003478ea952187cd9fe5d27a Mon Sep 17 00:00:00 2001 From: Andreas Cadhalpun Date: Sun, 13 Nov 2016 23:24:45 +0100 Subject: [PATCH 0672/3374] libschroedingerdec: don't produce empty frames They are not valid and can cause problems/crashes for API users. Signed-off-by: Andreas Cadhalpun --- libavcodec/libschroedingerdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/libschroedingerdec.c b/libavcodec/libschroedingerdec.c index f173f92f043b6..56b2f6d778a77 100644 --- a/libavcodec/libschroedingerdec.c +++ b/libavcodec/libschroedingerdec.c @@ -307,7 +307,7 @@ static int libschroedinger_decode_frame(AVCodecContext *avctx, /* Grab next frame to be returned from the top of the queue. */ framewithpts = ff_schro_queue_pop(&p_schro_params->dec_frame_queue); - if (framewithpts && framewithpts->frame) { + if (framewithpts && framewithpts->frame && framewithpts->frame->components[0].stride) { if (ff_get_buffer(avctx, avframe, 0) < 0) { av_log(avctx, AV_LOG_ERROR, "Unable to allocate buffer\n"); return AVERROR(ENOMEM); From dc2ad094931de2b28c63eaa5614756ed74e2579e Mon Sep 17 00:00:00 2001 From: Andreas Cadhalpun Date: Fri, 2 Dec 2016 22:52:44 +0100 Subject: [PATCH 0673/3374] libschroedingerdec: fix leaking of framewithpts Also preserve the return value from ff_get_buffer(). Signed-off-by: Andreas Cadhalpun Signed-off-by: Vittorio Giovara --- libavcodec/libschroedingerdec.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/libavcodec/libschroedingerdec.c b/libavcodec/libschroedingerdec.c index 56b2f6d778a77..69eed01ce0e8c 100644 --- a/libavcodec/libschroedingerdec.c +++ b/libavcodec/libschroedingerdec.c @@ -218,6 +218,7 @@ static int libschroedinger_decode_frame(AVCodecContext *avctx, int outer = 1; SchroParseUnitContext parse_ctx; LibSchroFrameContext *framewithpts = NULL; + int ret; *got_frame = 0; @@ -308,9 +309,9 @@ static int libschroedinger_decode_frame(AVCodecContext *avctx, framewithpts = ff_schro_queue_pop(&p_schro_params->dec_frame_queue); if (framewithpts && framewithpts->frame && framewithpts->frame->components[0].stride) { - if (ff_get_buffer(avctx, avframe, 0) < 0) { + if ((ret = ff_get_buffer(avctx, avframe, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "Unable to allocate buffer\n"); - return AVERROR(ENOMEM); + goto end; } memcpy(avframe->data[0], @@ -337,15 +338,17 @@ FF_ENABLE_DEPRECATION_WARNINGS avframe->linesize[2] = framewithpts->frame->components[2].stride; *got_frame = 1; - - /* Now free the frame resources. */ - libschroedinger_decode_frame_free(framewithpts->frame); - av_free(framewithpts); } else { data = NULL; *got_frame = 0; } - return buf_size; + ret = buf_size; +end: + /* Now free the frame resources. */ + if (framewithpts && framewithpts->frame) + libschroedinger_decode_frame_free(framewithpts->frame); + av_freep(&framewithpts); + return ret; } From 2170017a1cd033b6f28e16476921022712a522d8 Mon Sep 17 00:00:00 2001 From: Wan-Teh Chang Date: Wed, 7 Dec 2016 16:16:02 -0800 Subject: [PATCH 0674/3374] avutil: fix data race in av_get_cpu_flags() Make the one-time initialization in av_get_cpu_flags() thread-safe. The static variables |flags|, |cpuflags_mask|, and |checked| in libavutil/cpu.c are read and written using normal load and store operations. These are considered as data races. The fix is to use atomic load and store operations. Remove the |checked| variable because the invalid value of -1 for |flags| can be used to indicate the same condition. Rename |flags| to |cpu_flags| and move it to file scope. The fix can be verified by running the libavutil/tests/cpu_init.c test program under ThreadSanitizer: ./configure --toolchain=clang-tsan make libavutil/tests/cpu_init libavutil/tests/cpu_init There should be no warnings from ThreadSanitizer. Co-author: Dmitry Vyukov of Google, who suggested the data race fix. Signed-off-by: Wan-Teh Chang --- libavutil/Makefile | 2 ++ libavutil/cpu.c | 34 ++++++++++---------- libavutil/cpu.h | 2 -- libavutil/tests/.gitignore | 1 + libavutil/tests/cpu_init.c | 65 ++++++++++++++++++++++++++++++++++++++ tests/fate/libavutil.mak | 6 ++++ 6 files changed, 92 insertions(+), 18 deletions(-) create mode 100644 libavutil/tests/cpu_init.c diff --git a/libavutil/Makefile b/libavutil/Makefile index 28372c9befe28..f34c79950ef2b 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -145,3 +145,5 @@ TESTPROGS = adler32 \ sha \ tree \ xtea \ + +TESTPROGS-$(HAVE_THREADS) += cpu_init diff --git a/libavutil/cpu.c b/libavutil/cpu.c index 7d7390a7566f9..0109c9e8d1a26 100644 --- a/libavutil/cpu.c +++ b/libavutil/cpu.c @@ -17,6 +17,7 @@ */ #include +#include #include "cpu.h" #include "cpu_internal.h" @@ -42,34 +43,35 @@ #include #endif -static int cpuflags_mask = -1, checked; +static atomic_int cpu_flags = ATOMIC_VAR_INIT(-1); -int av_get_cpu_flags(void) +static int get_cpu_flags(void) { - static int flags; - - if (checked) - return flags; - if (ARCH_AARCH64) - flags = ff_get_cpu_flags_aarch64(); + return ff_get_cpu_flags_aarch64(); if (ARCH_ARM) - flags = ff_get_cpu_flags_arm(); + return ff_get_cpu_flags_arm(); if (ARCH_PPC) - flags = ff_get_cpu_flags_ppc(); + return ff_get_cpu_flags_ppc(); if (ARCH_X86) - flags = ff_get_cpu_flags_x86(); - - flags &= cpuflags_mask; - checked = 1; + return ff_get_cpu_flags_x86(); + return 0; +} +int av_get_cpu_flags(void) +{ + int flags = atomic_load_explicit(&cpu_flags, memory_order_relaxed); + if (flags == -1) { + flags = get_cpu_flags(); + atomic_store_explicit(&cpu_flags, flags, memory_order_relaxed); + } return flags; } void av_set_cpu_flags_mask(int mask) { - cpuflags_mask = mask; - checked = 0; + atomic_store_explicit(&cpu_flags, get_cpu_flags() & mask, + memory_order_relaxed); } int av_parse_cpu_flags(const char *s) diff --git a/libavutil/cpu.h b/libavutil/cpu.h index deff4ccf55f61..c205ee16f6631 100644 --- a/libavutil/cpu.h +++ b/libavutil/cpu.h @@ -73,8 +73,6 @@ int av_get_cpu_flags(void); /** * Set a mask on flags returned by av_get_cpu_flags(). * This function is mainly useful for testing. - * - * @warning this function is not thread safe. */ void av_set_cpu_flags_mask(int mask); diff --git a/libavutil/tests/.gitignore b/libavutil/tests/.gitignore index c4d1d065fb214..c8f37a7f90c70 100644 --- a/libavutil/tests/.gitignore +++ b/libavutil/tests/.gitignore @@ -5,6 +5,7 @@ /base64 /blowfish /cpu +/cpu_init /crc /des /eval diff --git a/libavutil/tests/cpu_init.c b/libavutil/tests/cpu_init.c new file mode 100644 index 0000000000000..beb95c911fb50 --- /dev/null +++ b/libavutil/tests/cpu_init.c @@ -0,0 +1,65 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * This test program tests whether the one-time initialization in + * av_get_cpu_flags() has data races. + */ + +#include +#include + +#include "libavutil/cpu.h" +#include "libavutil/thread.h" + +static void *thread_main(void *arg) +{ + int *flags = arg; + + *flags = av_get_cpu_flags(); + return NULL; +} + +int main(void) +{ + int cpu_flags1; + int cpu_flags2; + int ret; + pthread_t thread1; + pthread_t thread2; + + if ((ret = pthread_create(&thread1, NULL, thread_main, &cpu_flags1))) { + fprintf(stderr, "pthread_create failed: %s.\n", strerror(ret)); + return 1; + } + if ((ret = pthread_create(&thread2, NULL, thread_main, &cpu_flags2))) { + fprintf(stderr, "pthread_create failed: %s.\n", strerror(ret)); + return 1; + } + pthread_join(thread1, NULL); + pthread_join(thread2, NULL); + + if (cpu_flags1 < 0) + return 2; + if (cpu_flags2 < 0) + return 2; + if (cpu_flags1 != cpu_flags2) + return 3; + + return 0; +} diff --git a/tests/fate/libavutil.mak b/tests/fate/libavutil.mak index 2824e084eb411..8b174113701a6 100644 --- a/tests/fate/libavutil.mak +++ b/tests/fate/libavutil.mak @@ -25,6 +25,11 @@ fate-cpu: libavutil/tests/cpu$(EXESUF) fate-cpu: CMD = run libavutil/tests/cpu $(CPUFLAGS:%=-c%) $(THREADS:%=-t%) fate-cpu: REF = /dev/null +FATE_LIBAVUTIL-$(HAVE_THREADS) += fate-cpu_init +fate-cpu_init: libavutil/tests/cpu_init$(EXESUF) +fate-cpu_init: CMD = run libavutil/tests/cpu_init +fate-cpu_init: REF = /dev/null + FATE_LIBAVUTIL += fate-crc fate-crc: libavutil/tests/crc$(EXESUF) fate-crc: CMD = run libavutil/tests/crc @@ -73,5 +78,6 @@ FATE_LIBAVUTIL += fate-xtea fate-xtea: libavutil/tests/xtea$(EXESUF) fate-xtea: CMD = run libavutil/tests/xtea +FATE_LIBAVUTIL += $(FATE_LIBAVUTIL-yes) FATE-$(CONFIG_AVUTIL) += $(FATE_LIBAVUTIL) fate-libavutil: $(FATE_LIBAVUTIL) From 6a93b596c5c3af31b843d63013a7985ffeea354d Mon Sep 17 00:00:00 2001 From: Wan-Teh Chang Date: Fri, 2 Dec 2016 16:56:16 -0800 Subject: [PATCH 0675/3374] compat/atomics: add typecasts in atomic_compare_exchange_strong() The Solaris and Windows emulations of atomic_compare_exchange_strong() need typecasts to avoid compiler warnings, because the functions they call expect a void* pointer but an intptr_t integer is passed. Note that the emulations of atomic_compare_exchange_strong() (except the gcc version) only work for atomic_intptr_t because of the type of the second argument (|expected|). See http://en.cppreference.com/w/c/atomic: _Bool atomic_compare_exchange_strong( volatile A* obj, C* expected, C desired ); The types of the first argument and second argument are different (|A| and |C|, respectively). |C| is the non-atomic type corresponding to |A|. In the emulations of atomic_compare_exchange_strong(), |C| is intptr_t. This implies |A| can only be sig_intptr_t. Signed-off-by: Wan-Teh Chang --- compat/atomics/suncc/stdatomic.h | 2 +- compat/atomics/win32/stdatomic.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/compat/atomics/suncc/stdatomic.h b/compat/atomics/suncc/stdatomic.h index 32129aae5377a..aef498d022c68 100644 --- a/compat/atomics/suncc/stdatomic.h +++ b/compat/atomics/suncc/stdatomic.h @@ -108,7 +108,7 @@ static inline int atomic_compare_exchange_strong(intptr_t *object, intptr_t *exp intptr_t desired) { intptr_t old = *expected; - *expected = atomic_cas_ptr(object, old, desired); + *expected = (intptr_t)atomic_cas_ptr(object, (void *)old, (void *)desired); return *expected == old; } diff --git a/compat/atomics/win32/stdatomic.h b/compat/atomics/win32/stdatomic.h index bdd39337a3d11..9cfdaa523ffbd 100644 --- a/compat/atomics/win32/stdatomic.h +++ b/compat/atomics/win32/stdatomic.h @@ -104,7 +104,8 @@ static inline int atomic_compare_exchange_strong(intptr_t *object, intptr_t *exp intptr_t desired) { intptr_t old = *expected; - *expected = InterlockedCompareExchangePointer(object, desired, old); + *expected = (intptr_t)InterlockedCompareExchangePointer( + (PVOID *)object, (PVOID)desired, (PVOID)old); return *expected == old; } From d32bdadda86b35c2960e4de877cf081b9d2dadb3 Mon Sep 17 00:00:00 2001 From: Timothy Gu Date: Mon, 5 Dec 2016 10:21:11 -0800 Subject: [PATCH 0676/3374] qsvdec: Fix memory leak on error Bug-Id: CID 1396851 Signed-off-by: Vittorio Giovara --- libavcodec/qsvdec.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index b6fead0b8428b..b83b0fcda82f3 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -306,8 +306,10 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q, do { ret = get_surface(avctx, q, &insurf); - if (ret < 0) + if (ret < 0) { + av_freep(&sync); return ret; + } ret = MFXVideoDECODE_DecodeFrameAsync(q->session, avpkt->size ? &bs : NULL, insurf, &outsurf, sync); From d3da8a0035734529c4e26696c9a0c6cb56633838 Mon Sep 17 00:00:00 2001 From: Timothy Gu Date: Mon, 5 Dec 2016 09:29:12 -0800 Subject: [PATCH 0677/3374] omx: Fix allocation check Also use av_mallocz_array(). Bug-Id: CID 1396839 Signed-off-by: Vittorio Giovara --- libavcodec/omx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/omx.c b/libavcodec/omx.c index 0c61c2f536904..05c874323c1df 100644 --- a/libavcodec/omx.c +++ b/libavcodec/omx.c @@ -352,12 +352,12 @@ static av_cold int find_component(OMXContext *omx_context, void *logctx, av_log(logctx, AV_LOG_WARNING, "No component for role %s found\n", role); return AVERROR_ENCODER_NOT_FOUND; } - components = av_mallocz(sizeof(char*) * num); + components = av_mallocz_array(num, sizeof(*components)); if (!components) return AVERROR(ENOMEM); for (i = 0; i < num; i++) { components[i] = av_mallocz(OMX_MAX_STRINGNAME_SIZE); - if (!components) { + if (!components[i]) { ret = AVERROR(ENOMEM); goto end; } From fc85646ad495f3418042468da415af73a7a07334 Mon Sep 17 00:00:00 2001 From: Andreas Cadhalpun Date: Thu, 24 Nov 2016 01:06:35 +0100 Subject: [PATCH 0678/3374] libopusdec: fix out-of-bounds read Signed-off-by: Andreas Cadhalpun --- libavcodec/libopusdec.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libavcodec/libopusdec.c b/libavcodec/libopusdec.c index 75eaf9bd48c9e..781635615c488 100644 --- a/libavcodec/libopusdec.c +++ b/libavcodec/libopusdec.c @@ -48,6 +48,13 @@ static av_cold int libopus_decode_init(AVCodecContext *avc) avc->channels = 2; } + avc->channels = avc->extradata_size >= 10 ? avc->extradata[9] : (avc->channels == 1) ? 1 : 2; + if (avc->channels <= 0) { + av_log(avc, AV_LOG_WARNING, + "Invalid number of channels %d, defaulting to stereo\n", avc->channels); + avc->channels = 2; + } + avc->sample_rate = 48000; avc->sample_fmt = avc->request_sample_fmt == AV_SAMPLE_FMT_FLT ? AV_SAMPLE_FMT_FLT : AV_SAMPLE_FMT_S16; From 3f75e5116b900f1428aa13041fc7d6301bf1988a Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Tue, 6 Dec 2016 02:56:24 +0100 Subject: [PATCH 0679/3374] avio: Keep track of the amount of data written Make avio_size() work with any write AVIOContext. --- libavformat/avio.h | 1 + libavformat/aviobuf.c | 13 ++++++++++--- libavformat/version.h | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/libavformat/avio.h b/libavformat/avio.h index 49721aa1315fc..7bf7985c5e04a 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -176,6 +176,7 @@ typedef struct AVIOContext { */ enum AVIODataMarkerType current_type; int64_t last_time; + int64_t written; } AVIOContext; /** diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index 5cb733d3d8ac4..6d83a9661b34f 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -168,18 +168,22 @@ AVIOContext *avio_alloc_context( static void flush_buffer(AVIOContext *s) { if (s->buf_ptr > s->buffer) { + int size = s->buf_ptr - s->buffer; if (!s->error) { int ret = 0; if (s->write_data_type) ret = s->write_data_type(s->opaque, s->buffer, - s->buf_ptr - s->buffer, + size, s->current_type, s->last_time); else if (s->write_packet) ret = s->write_packet(s->opaque, s->buffer, - s->buf_ptr - s->buffer); + size); if (ret < 0) { s->error = ret; + } else { + if (s->pos + size > s->written) + s->written = s->pos + size; } } if (s->current_type == AVIO_DATA_MARKER_SYNC_POINT || @@ -192,7 +196,7 @@ static void flush_buffer(AVIOContext *s) s->buf_ptr - s->checksum_ptr); s->checksum_ptr = s->buffer; } - s->pos += s->buf_ptr - s->buffer; + s->pos += size; } s->buf_ptr = s->buffer; } @@ -301,6 +305,9 @@ int64_t avio_size(AVIOContext *s) if (!s) return AVERROR(EINVAL); + if (s->written) + return s->written; + if (!s->seek) return AVERROR(ENOSYS); size = s->seek(s->opaque, 0, AVSEEK_SIZE); diff --git a/libavformat/version.h b/libavformat/version.h index ad7997ec4fd1c..3fa2c4443b0a4 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -31,7 +31,7 @@ #define LIBAVFORMAT_VERSION_MAJOR 57 #define LIBAVFORMAT_VERSION_MINOR 10 -#define LIBAVFORMAT_VERSION_MICRO 1 +#define LIBAVFORMAT_VERSION_MICRO 2 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ From 4efea4ce75fbea3e5f8be8040068bfaaffbb2718 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Mon, 5 Dec 2016 17:45:06 -0500 Subject: [PATCH 0680/3374] APIChanges: Mention where release 12 was cut Signed-off-by: Vittorio Giovara --- doc/APIchanges | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/APIchanges b/doc/APIchanges index d5dc5edaa5808..7633c99181378 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -57,6 +57,10 @@ API changes, most recent first: Deprecate struct vaapi_context and the vaapi.h installed header. Callers should set AVCodecContext.hw_frames_ctx instead. +------------------------------8<------------------------------------- + 12 branch was cut here +----------------------------->8-------------------------------------- + 2016-07-20 - xxxxxxx - lavu 55.20.0 - cpu.h Add AV_CPU_FLAG_SSSE3SLOW. From dbfe60caca2e8323efa7aba6762dce7be2eba390 Mon Sep 17 00:00:00 2001 From: Ruta Gadkari Date: Thu, 8 Dec 2016 15:04:46 +0530 Subject: [PATCH 0681/3374] vf_hwupload_cuda: Add min/max limits for device option --- libavfilter/vf_hwupload_cuda.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_hwupload_cuda.c b/libavfilter/vf_hwupload_cuda.c index b5631c2b86e2d..adb2e812dc56d 100644 --- a/libavfilter/vf_hwupload_cuda.c +++ b/libavfilter/vf_hwupload_cuda.c @@ -187,7 +187,7 @@ static int cudaupload_filter_frame(AVFilterLink *link, AVFrame *in) #define OFFSET(x) offsetof(CudaUploadContext, x) #define FLAGS AV_OPT_FLAG_VIDEO_PARAM static const AVOption options[] = { - { "device", "Number of the device to use", OFFSET(device_idx), AV_OPT_TYPE_INT, { .i64 = 0 }, .flags = FLAGS }, + { "device", "Number of the device to use", OFFSET(device_idx), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS }, { NULL }, }; From 92e6b31c3b31be5d6fcad6bf0030bea86a1c8360 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 7 Dec 2016 20:36:41 +0100 Subject: [PATCH 0682/3374] dxva2: Adjust multiple inclusion guard names to follow convention --- libavcodec/dxva2.h | 6 +++--- libavcodec/dxva2_internal.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libavcodec/dxva2.h b/libavcodec/dxva2.h index ec448a4c2cd24..d940b47fe5879 100644 --- a/libavcodec/dxva2.h +++ b/libavcodec/dxva2.h @@ -20,8 +20,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef AVCODEC_DXVA_H -#define AVCODEC_DXVA_H +#ifndef AVCODEC_DXVA2_H +#define AVCODEC_DXVA2_H /** * @file @@ -90,4 +90,4 @@ struct dxva_context { * @} */ -#endif /* AVCODEC_DXVA_H */ +#endif /* AVCODEC_DXVA2_H */ diff --git a/libavcodec/dxva2_internal.h b/libavcodec/dxva2_internal.h index f0fe3d61e3be4..2d7939e7c1201 100644 --- a/libavcodec/dxva2_internal.h +++ b/libavcodec/dxva2_internal.h @@ -20,8 +20,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef AVCODEC_DXVA_INTERNAL_H -#define AVCODEC_DXVA_INTERNAL_H +#ifndef AVCODEC_DXVA2_INTERNAL_H +#define AVCODEC_DXVA2_INTERNAL_H #define COBJMACROS @@ -114,4 +114,4 @@ int ff_dxva2_common_end_frame(AVCodecContext *, AVFrame *, DECODER_BUFFER_DESC *bs, DECODER_BUFFER_DESC *slice)); -#endif /* AVCODEC_DXVA_INTERNAL_H */ +#endif /* AVCODEC_DXVA2_INTERNAL_H */ From 932cc6496ef6ab0e589ea51d3adefe5b7d7f1e2a Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 8 Dec 2016 19:58:12 +0100 Subject: [PATCH 0683/3374] vdpau: Do not #include vdpau_x11.h from the main vdpau header That header should only be included in the special bits that use X11 code. --- libavcodec/vdpau.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h index 967c72838fd87..acd63ccfafb74 100644 --- a/libavcodec/vdpau.h +++ b/libavcodec/vdpau.h @@ -50,7 +50,6 @@ */ #include -#include #include "libavutil/attributes.h" From af451ac0de6776e97d6a3ff95eac257b7964002e Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 8 Dec 2016 11:52:32 +0100 Subject: [PATCH 0684/3374] configure: Drop redundant and partly bogus vaapi/vdpau header checks These are taken care of more correctly by the library checks. --- configure | 4 ---- 1 file changed, 4 deletions(-) diff --git a/configure b/configure index 165aa8075d68e..fc2c54aad3423 100755 --- a/configure +++ b/configure @@ -2128,10 +2128,8 @@ zmbv_encoder_deps="zlib" # hardware accelerators d3d11va_deps="d3d11_h dxva_h ID3D11VideoDecoder" dxva2_deps="dxva2api_h DXVA2_ConfigPictureDecode" -vaapi_deps="va_va_h" vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads" vda_extralibs="-framework CoreFoundation -framework VideoDecodeAcceleration -framework QuartzCore" -vdpau_deps="vdpau_vdpau_h vdpau_vdpau_x11_h" h263_vaapi_hwaccel_deps="vaapi" h263_vaapi_hwaccel_select="h263_decoder" @@ -4547,8 +4545,6 @@ check_header sys/time.h check_header sys/un.h check_header unistd.h check_header valgrind/valgrind.h -check_header vdpau/vdpau.h -check_header vdpau/vdpau_x11.h check_header VideoDecodeAcceleration/VDADecoder.h check_header windows.h check_header X11/extensions/XvMClib.h From 1818a640cfdccd52e97edf13564f45bc3d0d93eb Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 8 Dec 2016 11:49:34 +0100 Subject: [PATCH 0685/3374] build: Fix dependencies for alsa/jack/sndio support These components should depend on the availability of the respective libraries, not just on the availability of the respective headers. --- configure | 11 +++++------ libavdevice/Makefile | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/configure b/configure index fc2c54aad3423..ac47c3d835b62 100755 --- a/configure +++ b/configure @@ -2367,23 +2367,23 @@ xmv_demuxer_select="riffdec" xwma_demuxer_select="riffdec" # indevs / outdevs -alsa_indev_deps="alsa_asoundlib_h snd_pcm_htimestamp" -alsa_outdev_deps="alsa_asoundlib_h" +alsa_indev_deps="alsa" +alsa_outdev_deps="alsa" avfoundation_indev_deps="AVFoundation_AVFoundation_h objc_arc pthreads" avfoundation_indev_extralibs="-framework Foundation -framework AVFoundation -framework CoreVideo -framework CoreMedia" bktr_indev_deps_any="dev_bktr_ioctl_bt848_h machine_ioctl_bt848_h dev_video_bktr_ioctl_bt848_h dev_ic_bt8xx_h" dv1394_indev_deps="dv1394" dv1394_indev_select="dv_demuxer" fbdev_indev_deps="linux_fb_h" -jack_indev_deps="jack_jack_h" +jack_indev_deps="jack" jack_indev_deps_any="sem_timedwait dispatch_dispatch_h" libcdio_indev_deps="libcdio" libdc1394_indev_deps="libdc1394" oss_indev_deps_any="soundcard_h sys_soundcard_h" oss_outdev_deps_any="soundcard_h sys_soundcard_h" pulse_indev_deps="libpulse" -sndio_indev_deps="sndio_h" -sndio_outdev_deps="sndio_h" +sndio_indev_deps="sndio" +sndio_outdev_deps="sndio" v4l2_indev_deps_any="linux_videodev2_h sys_videoio_h" vfwcap_indev_deps="capCreateCaptureWindow vfwcap_defines" vfwcap_indev_extralibs="-lavicap32" @@ -4742,7 +4742,6 @@ check_cpp_condition vfw.h "WM_CAP_DRIVER_CONNECT > WM_USER" && enable vfwcap_def check_header dev/video/bktr/ioctl_bt848.h; } || check_header dev/ic/bt8xx.h -check_header sndio.h check_header sys/soundcard.h check_header soundcard.h diff --git a/libavdevice/Makefile b/libavdevice/Makefile index 5bb1d3f8c9e84..664fa0f9ffebb 100644 --- a/libavdevice/Makefile +++ b/libavdevice/Makefile @@ -29,7 +29,7 @@ OBJS-$(CONFIG_XCBGRAB_INDEV) += xcbgrab.o OBJS-$(CONFIG_LIBCDIO_INDEV) += libcdio.o OBJS-$(CONFIG_LIBDC1394_INDEV) += libdc1394.o -SKIPHEADERS-$(HAVE_ALSA_ASOUNDLIB_H) += alsa.h -SKIPHEADERS-$(HAVE_SNDIO_H) += sndio.h +SKIPHEADERS-$(HAVE_ALSA) += alsa.h +SKIPHEADERS-$(HAVE_SNDIO) += sndio.h TESTPROGS-$(CONFIG_JACK_INDEV) += timefilter From a7101eb40e69ada3872ec5aebe9c5c165745fb3a Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 8 Dec 2016 10:33:58 +0100 Subject: [PATCH 0686/3374] configure: Simplify some library checks via check_lib() --- configure | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/configure b/configure index ac47c3d835b62..6ff5863491f77 100755 --- a/configure +++ b/configure @@ -4506,7 +4506,7 @@ check_func mkstemp check_func mmap check_func mprotect # Solaris has nanosleep in -lrt, OpenSolaris no longer needs that -check_func_headers time.h nanosleep || { check_func_headers time.h nanosleep -lrt && add_extralibs -lrt; } +check_func_headers time.h nanosleep || check_lib time.h nanosleep -lrt check_func sched_getaffinity check_func setrlimit check_func strerror_r @@ -4581,14 +4581,12 @@ fi # do this before the optional library checks as some of them require pthreads if ! disabled pthreads && ! enabled w32threads; then enable pthreads - if check_func pthread_join -pthread; then + if check_lib pthread.h pthread_join -pthread; then add_cflags -pthread - add_extralibs -pthread - elif check_func pthread_join -pthreads; then + elif check_lib pthread.h pthread_join -pthreads; then add_cflags -pthreads - add_extralibs -pthreads - elif check_func pthread_join -lpthreadGC2; then - add_extralibs -lpthreadGC2 + elif check_lib pthread.h pthread_join -lpthreadGC2; then + : elif check_lib pthread.h pthread_join -lpthread; then : elif ! check_func pthread_join; then From 0507cd5b9f3c3769645bc6e9177eaf760f490d1c Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 6 Dec 2016 18:19:09 +0100 Subject: [PATCH 0687/3374] build: Rename host_libs/HOSTLIBS variables to host_extralibs/HOSTEXTRALIBS This is more in line with the other related variable names. --- common.mak | 2 +- configure | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/common.mak b/common.mak index d73addeffe927..70ebd4b7ab362 100644 --- a/common.mak +++ b/common.mak @@ -39,7 +39,7 @@ $(HOSTOBJS): %.o: %.c $(COMPILE_HOSTC) $(HOSTPROGS): %$(HOSTEXESUF): %.o - $(HOSTLD) $(HOSTLDFLAGS) $(HOSTLD_O) $^ $(HOSTLIBS) + $(HOSTLD) $(HOSTLDFLAGS) $(HOSTLD_O) $^ $(HOSTEXTRALIBS) $(OBJS): | $(sort $(dir $(OBJS))) $(HOBJS): | $(sort $(dir $(HOBJS))) diff --git a/configure b/configure index 6ff5863491f77..dc540f6d9b452 100755 --- a/configure +++ b/configure @@ -1807,9 +1807,9 @@ CMDLINE_SET=" extra_version host_cc host_cflags + host_extralibs host_ld host_ldflags - host_libs host_os ld logfile @@ -2572,7 +2572,7 @@ HOSTCC_E='-E -o $@' HOSTCC_O='-o $@' HOSTLD_O='-o $@' -host_libs='-lm' +host_extralibs='-lm' host_cflags_filter=echo host_ldflags_filter=echo @@ -3809,7 +3809,7 @@ case $target_os in haiku) prefix_default="/boot/common" network_extralibs="-lnetwork" - host_libs= + host_extralibs= ;; sunos) SHFLAGS='-shared -Wl,-h,$$(@F)' @@ -5281,7 +5281,7 @@ HOSTCFLAGS=$host_cflags HOSTCPPFLAGS=$host_cppflags HOSTEXESUF=$HOSTEXESUF HOSTLDFLAGS=$host_ldflags -HOSTLIBS=$host_libs +HOSTEXTRALIBS=$host_extralibs DEPHOSTCC=$host_cc DEPHOSTCCFLAGS=$DEPHOSTCCFLAGS \$(HOSTCCFLAGS) HOSTCCDEP=$HOSTCCDEP From be2d555c980220e65d0ca5c3d78e6cc1e24451a5 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 8 Dec 2016 15:44:45 +0100 Subject: [PATCH 0688/3374] build: Use _extralibs variable names instead of _libs everywhere This makes naming more consistent and simplifies extralibs-related changes. --- Makefile | 2 +- configure | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index ec04d19d79906..d4c2b8e7d78e6 100644 --- a/Makefile +++ b/Makefile @@ -164,7 +164,7 @@ OBJS-$(1) += $(1).o $(OBJS-$(1)-yes) $(1)$(EXESUF): $$(OBJS-$(1)) $$(OBJS-$(1)): CFLAGS += $(CFLAGS-$(1)) $(1)$(EXESUF): LDFLAGS += $(LDFLAGS-$(1)) -$(1)$(EXESUF): FF_EXTRALIBS += $(LIBS-$(1)) +$(1)$(EXESUF): FF_EXTRALIBS += $(EXTRALIBS-$(1)) -include $$(OBJS-$(1):.o=.d) endef diff --git a/configure b/configure index dc540f6d9b452..f5c0b116296c0 100755 --- a/configure +++ b/configure @@ -1023,8 +1023,8 @@ check_pkg_config(){ pkg_cflags=$($pkg_config --cflags $pkg_config_flags $pkg) pkg_libs=$($pkg_config --libs $pkg_config_flags $pkg) check_func_headers "$headers" "$funcs" $pkg_cflags $pkg_libs "$@" && - set_safe "${pkg}_cflags" $pkg_cflags && - set_safe "${pkg}_libs" $pkg_libs + set_safe "${pkg}_cflags" $pkg_cflags && + set_safe "${pkg}_extralibs" $pkg_libs } check_exec(){ @@ -1117,7 +1117,7 @@ require_pkg_config(){ pkg="${1%% *}" check_pkg_config "$@" || die "ERROR: $pkg_version not found" add_cflags $(get_safe "${pkg}_cflags") - add_extralibs $(get_safe "${pkg}_libs") + add_extralibs $(get_safe "${pkg}_extralibs") } hostcc_e(){ @@ -2477,7 +2477,7 @@ avconv_select="aformat_filter anull_filter asyncts_filter atrim_filter format_fi fps_filter null_filter resample_filter scale_filter trim_filter" avplay_deps="avcodec avfilter avformat avresample sdl" -avplay_libs='$sdl_libs' +avplay_extralibs='$sdl_extralibs' avplay_select="rdft format_filter transpose_filter hflip_filter vflip_filter" avprobe_deps="avcodec avformat" @@ -4695,7 +4695,7 @@ enabled omx_rpi && { check_header OMX_Core.h || enabled omx && { check_header OMX_Core.h || die "ERROR: OpenMAX IL headers not found"; } enabled openssl && { { check_pkg_config openssl openssl/ssl.h OPENSSL_init_ssl || check_pkg_config openssl openssl/ssl.h SSL_library_init; } && { - add_cflags $openssl_cflags && add_extralibs $openssl_libs; }|| + add_cflags $openssl_cflags && add_extralibs $openssl_extralibs; } || check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto || check_lib openssl/ssl.h SSL_library_init -lssl32 -leay32 || check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 || @@ -4773,7 +4773,7 @@ if enabled libxcb; then } && enable libxcb_xfixes add_cflags "$xcb_shape_cflags $xcb_shm_cflags $xcb_xfixes_cflags" - add_extralibs "$xcb_shape_libs $xcb_shm_libs $xcb_xfixes_libs" + add_extralibs "$xcb_shape_extralibs $xcb_shm_extralibs $xcb_xfixes_extralibs" fi enabled vaapi && require vaapi va/va.h vaInitialize -lva @@ -5329,12 +5329,12 @@ map 'get_version $v' $LIBRARY_LIST map 'eval echo "${v}_FFLIBS=\$${v}_deps" >> config.mak' $LIBRARY_LIST -print_program_libs(){ - eval "program_libs=\$${1}_libs" - eval echo "LIBS-${1}=${program_libs}" >> config.mak +print_program_extralibs(){ + eval "program_extralibs=\$${1}_extralibs" + eval echo "EXTRALIBS-${1}=${program_extralibs}" >> config.mak } -map 'print_program_libs $v' $PROGRAM_LIST +map 'print_program_extralibs $v' $PROGRAM_LIST cat > $TMPH < Date: Sat, 10 Dec 2016 15:06:34 +0100 Subject: [PATCH 0689/3374] configure: Fix _libs vs. _extralibs oversight --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index f5c0b116296c0..731986abebb0e 100755 --- a/configure +++ b/configure @@ -5055,7 +5055,7 @@ check_deps $CONFIG_LIST \ $ALL_COMPONENTS \ enabled_all dxva2 CoTaskMemFree && - prepend avconv_libs $($ldflags_filter "-lole32") && + prepend avconv_extralibs $($ldflags_filter "-lole32") && enable dxva2_lib map 'enabled $v && intrinsics=${v#intrinsics_}' $INTRINSICS_LIST From f8a1ead0ae4402df0503c83f213f57b785a5f20f Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 9 Dec 2016 15:45:05 +0100 Subject: [PATCH 0690/3374] build: Add -D_XOPEN_SOURCE=600 to CPPFLAGS on Cygwin This is required to make certain math defines visible on modern Cygwin. --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 731986abebb0e..804eee6df7ca2 100755 --- a/configure +++ b/configure @@ -4017,7 +4017,7 @@ probe_libc(){ # MinGW headers can be installed on Cygwin, so check for newlib first. elif check_${pfx}cpp_condition newlib.h "defined _NEWLIB_VERSION"; then eval ${pfx}libc_type=newlib - add_${pfx}cppflags -U__STRICT_ANSI__ + add_${pfx}cppflags -U__STRICT_ANSI__ -D_XOPEN_SOURCE=600 # MinGW64 is backwards compatible with MinGW32, so check for it first. elif check_${pfx}cpp_condition _mingw.h "defined __MINGW64_VERSION_MAJOR"; then eval ${pfx}libc_type=mingw64 From ade370a4d7eab1866b6023c91c135d27c77ca465 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Thu, 24 Nov 2016 23:27:11 +0000 Subject: [PATCH 0691/3374] lavfi: Add VAAPI deinterlacer --- configure | 1 + libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/version.h | 2 +- libavfilter/vf_deinterlace_vaapi.c | 625 +++++++++++++++++++++++++++++ 5 files changed, 629 insertions(+), 1 deletion(-) create mode 100644 libavfilter/vf_deinterlace_vaapi.c diff --git a/configure b/configure index 804eee6df7ca2..d88329c71fa2a 100755 --- a/configure +++ b/configure @@ -2436,6 +2436,7 @@ boxblur_filter_deps="gpl" bs2b_filter_deps="libbs2b" cropdetect_filter_deps="gpl" deinterlace_qsv_filter_deps="libmfx" +deinterlace_vaapi_filter_deps="vaapi" delogo_filter_deps="gpl" drawtext_filter_deps="libfreetype" frei0r_filter_deps="frei0r dlopen" diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 8b2841e03b4f2..646a5b5a26f52 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -49,6 +49,7 @@ OBJS-$(CONFIG_COPY_FILTER) += vf_copy.o OBJS-$(CONFIG_CROP_FILTER) += vf_crop.o OBJS-$(CONFIG_CROPDETECT_FILTER) += vf_cropdetect.o OBJS-$(CONFIG_DEINTERLACE_QSV_FILTER) += vf_deinterlace_qsv.o +OBJS-$(CONFIG_DEINTERLACE_VAAPI_FILTER) += vf_deinterlace_vaapi.o OBJS-$(CONFIG_DELOGO_FILTER) += vf_delogo.o OBJS-$(CONFIG_DRAWBOX_FILTER) += vf_drawbox.o OBJS-$(CONFIG_DRAWTEXT_FILTER) += vf_drawtext.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 246aed8412f6f..3f09f46bb974e 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -72,6 +72,7 @@ void avfilter_register_all(void) REGISTER_FILTER(CROP, crop, vf); REGISTER_FILTER(CROPDETECT, cropdetect, vf); REGISTER_FILTER(DEINTERLACE_QSV,deinterlace_qsv,vf); + REGISTER_FILTER(DEINTERLACE_VAAPI, deinterlace_vaapi, vf); REGISTER_FILTER(DELOGO, delogo, vf); REGISTER_FILTER(DRAWBOX, drawbox, vf); REGISTER_FILTER(DRAWTEXT, drawtext, vf); diff --git a/libavfilter/version.h b/libavfilter/version.h index 596701fc091cd..969f8101cd688 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 6 -#define LIBAVFILTER_VERSION_MINOR 8 +#define LIBAVFILTER_VERSION_MINOR 9 #define LIBAVFILTER_VERSION_MICRO 0 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vf_deinterlace_vaapi.c b/libavfilter/vf_deinterlace_vaapi.c new file mode 100644 index 0000000000000..022baa11fc26b --- /dev/null +++ b/libavfilter/vf_deinterlace_vaapi.c @@ -0,0 +1,625 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include + +#include "libavutil/avassert.h" +#include "libavutil/hwcontext.h" +#include "libavutil/hwcontext_vaapi.h" +#include "libavutil/mem.h" +#include "libavutil/opt.h" +#include "libavutil/pixdesc.h" + +#include "avfilter.h" +#include "formats.h" +#include "internal.h" +#include "video.h" + +#define MAX_REFERENCES 8 + +typedef struct DeintVAAPIContext { + const AVClass *class; + + AVVAAPIDeviceContext *hwctx; + AVBufferRef *device_ref; + + int mode; + + int valid_ids; + VAConfigID va_config; + VAContextID va_context; + + AVBufferRef *input_frames_ref; + AVHWFramesContext *input_frames; + + AVBufferRef *output_frames_ref; + AVHWFramesContext *output_frames; + int output_height; + int output_width; + + VAProcFilterCapDeinterlacing + deint_caps[VAProcDeinterlacingCount]; + int nb_deint_caps; + VAProcPipelineCaps pipeline_caps; + + int queue_depth; + int queue_count; + AVFrame *frame_queue[MAX_REFERENCES]; + + VABufferID filter_buffer; +} DeintVAAPIContext; + +static const char *deint_vaapi_mode_name(int mode) +{ + switch (mode) { +#define D(name) case VAProcDeinterlacing ## name: return #name + D(Bob); + D(Weave); + D(MotionAdaptive); + D(MotionCompensated); +#undef D + default: + return "Invalid"; + } +} + +static int deint_vaapi_query_formats(AVFilterContext *avctx) +{ + enum AVPixelFormat pix_fmts[] = { + AV_PIX_FMT_VAAPI, AV_PIX_FMT_NONE, + }; + + ff_formats_ref(ff_make_format_list(pix_fmts), + &avctx->inputs[0]->out_formats); + ff_formats_ref(ff_make_format_list(pix_fmts), + &avctx->outputs[0]->in_formats); + + return 0; +} + +static int deint_vaapi_pipeline_uninit(AVFilterContext *avctx) +{ + DeintVAAPIContext *ctx = avctx->priv; + int i; + + for (i = 0; i < ctx->queue_count; i++) + av_frame_free(&ctx->frame_queue[i]); + ctx->queue_count = 0; + + if (ctx->filter_buffer != VA_INVALID_ID) { + vaDestroyBuffer(ctx->hwctx->display, ctx->filter_buffer); + ctx->filter_buffer = VA_INVALID_ID; + } + + if (ctx->va_context != VA_INVALID_ID) { + vaDestroyContext(ctx->hwctx->display, ctx->va_context); + ctx->va_context = VA_INVALID_ID; + } + + if (ctx->va_config != VA_INVALID_ID) { + vaDestroyConfig(ctx->hwctx->display, ctx->va_config); + ctx->va_config = VA_INVALID_ID; + } + + av_buffer_unref(&ctx->device_ref); + ctx->hwctx = NULL; + + return 0; +} + +static int deint_vaapi_config_input(AVFilterLink *inlink) +{ + AVFilterContext *avctx = inlink->dst; + DeintVAAPIContext *ctx = avctx->priv; + + deint_vaapi_pipeline_uninit(avctx); + + if (!inlink->hw_frames_ctx) { + av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is " + "required to associate the processing device.\n"); + return AVERROR(EINVAL); + } + + ctx->input_frames_ref = av_buffer_ref(inlink->hw_frames_ctx); + ctx->input_frames = (AVHWFramesContext*)ctx->input_frames_ref->data; + + return 0; +} + +static int deint_vaapi_build_filter_params(AVFilterContext *avctx) +{ + DeintVAAPIContext *ctx = avctx->priv; + VAStatus vas; + VAProcFilterParameterBufferDeinterlacing params; + int i; + + ctx->nb_deint_caps = VAProcDeinterlacingCount; + vas = vaQueryVideoProcFilterCaps(ctx->hwctx->display, + ctx->va_context, + VAProcFilterDeinterlacing, + &ctx->deint_caps, + &ctx->nb_deint_caps); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to query deinterlacing " + "caps: %d (%s).\n", vas, vaErrorStr(vas)); + return AVERROR(EIO); + } + + if (ctx->mode == VAProcDeinterlacingNone) { + for (i = 0; i < ctx->nb_deint_caps; i++) { + if (ctx->deint_caps[i].type > ctx->mode) + ctx->mode = ctx->deint_caps[i].type; + } + av_log(avctx, AV_LOG_VERBOSE, "Picking %d (%s) as default " + "deinterlacing mode.\n", ctx->mode, + deint_vaapi_mode_name(ctx->mode)); + } else { + for (i = 0; i < ctx->nb_deint_caps; i++) { + if (ctx->deint_caps[i].type == ctx->mode) + break; + } + if (i >= ctx->nb_deint_caps) { + av_log(avctx, AV_LOG_ERROR, "Deinterlacing mode %d (%s) is " + "not supported.\n", ctx->mode, + deint_vaapi_mode_name(ctx->mode)); + } + } + + params.type = VAProcFilterDeinterlacing; + params.algorithm = ctx->mode; + params.flags = 0; + + av_assert0(ctx->filter_buffer == VA_INVALID_ID); + vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context, + VAProcFilterParameterBufferType, + sizeof(params), 1, ¶ms, + &ctx->filter_buffer); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to create deinterlace " + "parameter buffer: %d (%s).\n", vas, vaErrorStr(vas)); + return AVERROR(EIO); + } + + vas = vaQueryVideoProcPipelineCaps(ctx->hwctx->display, + ctx->va_context, + &ctx->filter_buffer, 1, + &ctx->pipeline_caps); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to query pipeline " + "caps: %d (%s).\n", vas, vaErrorStr(vas)); + return AVERROR(EIO); + } + + ctx->queue_depth = ctx->pipeline_caps.num_backward_references + + ctx->pipeline_caps.num_forward_references + 1; + if (ctx->queue_depth > MAX_REFERENCES) { + av_log(avctx, AV_LOG_ERROR, "Pipeline requires too many " + "references (%u forward, %u back).\n", + ctx->pipeline_caps.num_forward_references, + ctx->pipeline_caps.num_backward_references); + return AVERROR(ENOSYS); + } + + return 0; +} + +static int deint_vaapi_config_output(AVFilterLink *outlink) +{ + AVFilterContext *avctx = outlink->src; + DeintVAAPIContext *ctx = avctx->priv; + AVVAAPIHWConfig *hwconfig = NULL; + AVHWFramesConstraints *constraints = NULL; + AVVAAPIFramesContext *va_frames; + VAStatus vas; + int err; + + deint_vaapi_pipeline_uninit(avctx); + + av_assert0(ctx->input_frames); + ctx->device_ref = av_buffer_ref(ctx->input_frames->device_ref); + ctx->hwctx = ((AVHWDeviceContext*)ctx->device_ref->data)->hwctx; + + ctx->output_width = ctx->input_frames->width; + ctx->output_height = ctx->input_frames->height; + + av_assert0(ctx->va_config == VA_INVALID_ID); + vas = vaCreateConfig(ctx->hwctx->display, VAProfileNone, + VAEntrypointVideoProc, 0, 0, &ctx->va_config); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to create processing pipeline " + "config: %d (%s).\n", vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail; + } + + hwconfig = av_hwdevice_hwconfig_alloc(ctx->device_ref); + if (!hwconfig) { + err = AVERROR(ENOMEM); + goto fail; + } + hwconfig->config_id = ctx->va_config; + + constraints = av_hwdevice_get_hwframe_constraints(ctx->device_ref, + hwconfig); + if (!constraints) { + err = AVERROR(ENOMEM); + goto fail; + } + + if (ctx->output_width < constraints->min_width || + ctx->output_height < constraints->min_height || + ctx->output_width > constraints->max_width || + ctx->output_height > constraints->max_height) { + av_log(avctx, AV_LOG_ERROR, "Hardware does not support " + "deinterlacing to size %dx%d " + "(constraints: width %d-%d height %d-%d).\n", + ctx->output_width, ctx->output_height, + constraints->min_width, constraints->max_width, + constraints->min_height, constraints->max_height); + err = AVERROR(EINVAL); + goto fail; + } + + err = deint_vaapi_build_filter_params(avctx); + if (err < 0) + goto fail; + + ctx->output_frames_ref = av_hwframe_ctx_alloc(ctx->device_ref); + if (!ctx->output_frames_ref) { + av_log(avctx, AV_LOG_ERROR, "Failed to create HW frame context " + "for output.\n"); + err = AVERROR(ENOMEM); + goto fail; + } + + ctx->output_frames = (AVHWFramesContext*)ctx->output_frames_ref->data; + + ctx->output_frames->format = AV_PIX_FMT_VAAPI; + ctx->output_frames->sw_format = ctx->input_frames->sw_format; + ctx->output_frames->width = ctx->output_width; + ctx->output_frames->height = ctx->output_height; + + // The number of output frames we need is determined by what follows + // the filter. If it's an encoder with complex frame reference + // structures then this could be very high. + ctx->output_frames->initial_pool_size = 10; + + err = av_hwframe_ctx_init(ctx->output_frames_ref); + if (err < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to initialise VAAPI frame " + "context for output: %d\n", err); + goto fail; + } + + va_frames = ctx->output_frames->hwctx; + + av_assert0(ctx->va_context == VA_INVALID_ID); + vas = vaCreateContext(ctx->hwctx->display, ctx->va_config, + ctx->output_width, ctx->output_height, 0, + va_frames->surface_ids, va_frames->nb_surfaces, + &ctx->va_context); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to create processing pipeline " + "context: %d (%s).\n", vas, vaErrorStr(vas)); + return AVERROR(EIO); + } + + outlink->w = ctx->output_width; + outlink->h = ctx->output_height; + + outlink->hw_frames_ctx = av_buffer_ref(ctx->output_frames_ref); + if (!outlink->hw_frames_ctx) { + err = AVERROR(ENOMEM); + goto fail; + } + + av_freep(&hwconfig); + av_hwframe_constraints_free(&constraints); + return 0; + +fail: + av_buffer_unref(&ctx->output_frames_ref); + av_freep(&hwconfig); + av_hwframe_constraints_free(&constraints); + return err; +} + +static int vaapi_proc_colour_standard(enum AVColorSpace av_cs) +{ + switch(av_cs) { +#define CS(av, va) case AVCOL_SPC_ ## av: return VAProcColorStandard ## va; + CS(BT709, BT709); + CS(BT470BG, BT470BG); + CS(SMPTE170M, SMPTE170M); + CS(SMPTE240M, SMPTE240M); +#undef CS + default: + return VAProcColorStandardNone; + } +} + +static int deint_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame) +{ + AVFilterContext *avctx = inlink->dst; + AVFilterLink *outlink = avctx->outputs[0]; + DeintVAAPIContext *ctx = avctx->priv; + AVFrame *output_frame = NULL; + VASurfaceID input_surface, output_surface; + VASurfaceID backward_references[MAX_REFERENCES]; + VASurfaceID forward_references[MAX_REFERENCES]; + VAProcPipelineParameterBuffer params; + VAProcFilterParameterBufferDeinterlacing *filter_params; + VARectangle input_region; + VABufferID params_id; + VAStatus vas; + void *filter_params_addr = NULL; + int err, i; + + av_log(avctx, AV_LOG_DEBUG, "Filter input: %s, %ux%u (%"PRId64").\n", + av_get_pix_fmt_name(input_frame->format), + input_frame->width, input_frame->height, input_frame->pts); + + if (ctx->queue_count < ctx->queue_depth) { + ctx->frame_queue[ctx->queue_count++] = input_frame; + if (ctx->queue_count < ctx->queue_depth) { + // Need more reference surfaces before we can continue. + return 0; + } + } else { + av_frame_free(&ctx->frame_queue[0]); + for (i = 0; i + 1 < ctx->queue_count; i++) + ctx->frame_queue[i] = ctx->frame_queue[i + 1]; + ctx->frame_queue[i] = input_frame; + } + + input_frame = + ctx->frame_queue[ctx->pipeline_caps.num_backward_references]; + input_surface = (VASurfaceID)(uintptr_t)input_frame->data[3]; + for (i = 0; i < ctx->pipeline_caps.num_backward_references; i++) + backward_references[i] = (VASurfaceID)(uintptr_t) + ctx->frame_queue[ctx->pipeline_caps.num_backward_references - + i - 1]->data[3]; + for (i = 0; i < ctx->pipeline_caps.num_forward_references; i++) + forward_references[i] = (VASurfaceID)(uintptr_t) + ctx->frame_queue[ctx->pipeline_caps.num_backward_references + + i + 1]->data[3]; + + av_log(avctx, AV_LOG_DEBUG, "Using surface %#x for " + "deinterlace input.\n", input_surface); + av_log(avctx, AV_LOG_DEBUG, "Backward references:"); + for (i = 0; i < ctx->pipeline_caps.num_backward_references; i++) + av_log(avctx, AV_LOG_DEBUG, " %#x", backward_references[i]); + av_log(avctx, AV_LOG_DEBUG, "\n"); + av_log(avctx, AV_LOG_DEBUG, "Forward references:"); + for (i = 0; i < ctx->pipeline_caps.num_forward_references; i++) + av_log(avctx, AV_LOG_DEBUG, " %#x", forward_references[i]); + av_log(avctx, AV_LOG_DEBUG, "\n"); + + output_frame = ff_get_video_buffer(outlink, ctx->output_width, + ctx->output_height); + if (!output_frame) { + err = AVERROR(ENOMEM); + goto fail; + } + + output_surface = (VASurfaceID)(uintptr_t)output_frame->data[3]; + av_log(avctx, AV_LOG_DEBUG, "Using surface %#x for " + "deinterlace output.\n", output_surface); + + memset(¶ms, 0, sizeof(params)); + + input_region = (VARectangle) { + .x = 0, + .y = 0, + .width = input_frame->width, + .height = input_frame->height, + }; + + params.surface = input_surface; + params.surface_region = &input_region; + params.surface_color_standard = + vaapi_proc_colour_standard(input_frame->colorspace); + + params.output_region = NULL; + params.output_background_color = 0xff000000; + params.output_color_standard = params.surface_color_standard; + + params.pipeline_flags = 0; + params.filter_flags = VA_FRAME_PICTURE; + + vas = vaMapBuffer(ctx->hwctx->display, ctx->filter_buffer, + &filter_params_addr); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to map filter parameter " + "buffer: %d (%s).\n", vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail; + } + filter_params = filter_params_addr; + filter_params->flags = 0; + if (input_frame->interlaced_frame && !input_frame->top_field_first) + filter_params->flags |= VA_DEINTERLACING_BOTTOM_FIELD_FIRST; + filter_params_addr = NULL; + vas = vaUnmapBuffer(ctx->hwctx->display, ctx->filter_buffer); + if (vas != VA_STATUS_SUCCESS) + av_log(avctx, AV_LOG_ERROR, "Failed to unmap filter parameter " + "buffer: %d (%s).\n", vas, vaErrorStr(vas)); + + params.filters = &ctx->filter_buffer; + params.num_filters = 1; + + params.forward_references = forward_references; + params.num_forward_references = + ctx->pipeline_caps.num_forward_references; + params.backward_references = backward_references; + params.num_backward_references = + ctx->pipeline_caps.num_backward_references; + + vas = vaBeginPicture(ctx->hwctx->display, + ctx->va_context, output_surface); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to attach new picture: " + "%d (%s).\n", vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail; + } + + vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context, + VAProcPipelineParameterBufferType, + sizeof(params), 1, ¶ms, ¶ms_id); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer: " + "%d (%s).\n", vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail_after_begin; + } + av_log(avctx, AV_LOG_DEBUG, "Pipeline parameter buffer is %#x.\n", + params_id); + + vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context, + ¶ms_id, 1); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to render parameter buffer: " + "%d (%s).\n", vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail_after_begin; + } + + vas = vaEndPicture(ctx->hwctx->display, ctx->va_context); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to start picture processing: " + "%d (%s).\n", vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail_after_render; + } + + if (ctx->hwctx->driver_quirks & + AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS) { + vas = vaDestroyBuffer(ctx->hwctx->display, params_id); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to free parameter buffer: " + "%d (%s).\n", vas, vaErrorStr(vas)); + // And ignore. + } + } + + err = av_frame_copy_props(output_frame, input_frame); + if (err < 0) + goto fail; + + av_log(avctx, AV_LOG_DEBUG, "Filter output: %s, %ux%u (%"PRId64").\n", + av_get_pix_fmt_name(output_frame->format), + output_frame->width, output_frame->height, output_frame->pts); + + return ff_filter_frame(outlink, output_frame); + +fail_after_begin: + vaRenderPicture(ctx->hwctx->display, ctx->va_context, ¶ms_id, 1); +fail_after_render: + vaEndPicture(ctx->hwctx->display, ctx->va_context); +fail: + if (filter_params_addr) + vaUnmapBuffer(ctx->hwctx->display, ctx->filter_buffer); + av_frame_free(&output_frame); + return err; +} + +static av_cold int deint_vaapi_init(AVFilterContext *avctx) +{ + DeintVAAPIContext *ctx = avctx->priv; + + ctx->va_config = VA_INVALID_ID; + ctx->va_context = VA_INVALID_ID; + ctx->filter_buffer = VA_INVALID_ID; + ctx->valid_ids = 1; + + return 0; +} + +static av_cold void deint_vaapi_uninit(AVFilterContext *avctx) +{ + DeintVAAPIContext *ctx = avctx->priv; + + if (ctx->valid_ids) + deint_vaapi_pipeline_uninit(avctx); + + av_buffer_unref(&ctx->input_frames_ref); + av_buffer_unref(&ctx->output_frames_ref); + av_buffer_unref(&ctx->device_ref); +} + +#define OFFSET(x) offsetof(DeintVAAPIContext, x) +#define FLAGS (AV_OPT_FLAG_VIDEO_PARAM) +static const AVOption deint_vaapi_options[] = { + { "mode", "Deinterlacing mode", + OFFSET(mode), AV_OPT_TYPE_INT, { .i64 = VAProcDeinterlacingNone }, + VAProcDeinterlacingNone, VAProcDeinterlacingCount - 1, FLAGS, "mode" }, + { "default", "Use the highest-numbered (and therefore possibly most advanced) deinterlacing algorithm", + 0, AV_OPT_TYPE_CONST, { .i64 = VAProcDeinterlacingNone }, .unit = "mode" }, + { "bob", "Use the bob deinterlacing algorithm", + 0, AV_OPT_TYPE_CONST, { .i64 = VAProcDeinterlacingBob }, .unit = "mode" }, + { "weave", "Use the weave deinterlacing algorithm", + 0, AV_OPT_TYPE_CONST, { .i64 = VAProcDeinterlacingWeave }, .unit = "mode" }, + { "motion_adaptive", "Use the motion adaptive deinterlacing algorithm", + 0, AV_OPT_TYPE_CONST, { .i64 = VAProcDeinterlacingMotionAdaptive }, .unit = "mode" }, + { "motion_compensated", "Use the motion compensated deinterlacing algorithm", + 0, AV_OPT_TYPE_CONST, { .i64 = VAProcDeinterlacingMotionCompensated }, .unit = "mode" }, + { NULL }, +}; + +static const AVClass deint_vaapi_class = { + .class_name = "deinterlace_vaapi", + .item_name = av_default_item_name, + .option = deint_vaapi_options, + .version = LIBAVUTIL_VERSION_INT, +}; + +static const AVFilterPad deint_vaapi_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .filter_frame = &deint_vaapi_filter_frame, + .config_props = &deint_vaapi_config_input, + }, + { NULL } +}; + +static const AVFilterPad deint_vaapi_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = &deint_vaapi_config_output, + }, + { NULL } +}; + +AVFilter ff_vf_deinterlace_vaapi = { + .name = "deinterlace_vaapi", + .description = NULL_IF_CONFIG_SMALL("Deinterlacing of VAAPI surfaces"), + .priv_size = sizeof(DeintVAAPIContext), + .init = &deint_vaapi_init, + .uninit = &deint_vaapi_uninit, + .query_formats = &deint_vaapi_query_formats, + .inputs = deint_vaapi_inputs, + .outputs = deint_vaapi_outputs, + .priv_class = &deint_vaapi_class, + .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, +}; From 7d81698b89172d2dcf1b78d4b42ba86262360559 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Tue, 29 Nov 2016 22:13:58 +0000 Subject: [PATCH 0692/3374] vaapi_h265: Fix CFR mode with framerate set in AVCodecContext Same issue as 17a0f9481cf07af0feb3838ca315b970117e8000. --- libavcodec/vaapi_encode_h265.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c index ecf7973368b62..ade7d4a933a27 100644 --- a/libavcodec/vaapi_encode_h265.c +++ b/libavcodec/vaapi_encode_h265.c @@ -825,8 +825,8 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) vseq->bits_per_second = avctx->bit_rate; if (avctx->framerate.num > 0 && avctx->framerate.den > 0) { - vseq->vui_num_units_in_tick = avctx->framerate.num; - vseq->vui_time_scale = avctx->framerate.den; + vseq->vui_num_units_in_tick = avctx->framerate.den; + vseq->vui_time_scale = avctx->framerate.num; } else { vseq->vui_num_units_in_tick = avctx->time_base.num; vseq->vui_time_scale = avctx->time_base.den; From ac648bb835edd3f67bda2267d0e72e5e582eb5a1 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 8 Dec 2016 09:55:26 +0100 Subject: [PATCH 0693/3374] dxva2: Simplify some ifdefs --- libavcodec/dxva2_internal.h | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/libavcodec/dxva2_internal.h b/libavcodec/dxva2_internal.h index 2d7939e7c1201..e7a973410544f 100644 --- a/libavcodec/dxva2_internal.h +++ b/libavcodec/dxva2_internal.h @@ -32,11 +32,6 @@ #if CONFIG_DXVA2 #include "dxva2.h" -#endif -#if CONFIG_D3D11VA -#include "d3d11va.h" -#endif -#if HAVE_DXVA_H /* When targeting WINAPI_FAMILY_PHONE_APP or WINAPI_FAMILY_APP, dxva.h * defines nothing. Force the struct definitions to be visible. */ #undef WINAPI_FAMILY @@ -45,6 +40,9 @@ #define _CRT_BUILD_DESKTOP_APP 0 #include #endif +#if CONFIG_D3D11VA +#include "d3d11va.h" +#endif #include "avcodec.h" @@ -59,12 +57,8 @@ typedef union { #endif } AVDXVAContext; -#if CONFIG_D3D11VA #define D3D11VA_CONTEXT(ctx) (&ctx->d3d11va) -#endif -#if CONFIG_DXVA2 #define DXVA2_CONTEXT(ctx) (&ctx->dxva2) -#endif #if CONFIG_D3D11VA && CONFIG_DXVA2 #define DXVA_CONTEXT_WORKAROUND(avctx, ctx) (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.workaround : ctx->dxva2.workaround) From a6901b9c6bd51396c1159f1a07f9f5042328cda6 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 3 Dec 2016 13:16:13 +0100 Subject: [PATCH 0694/3374] Drop libxvid rate control support for mpegvideo encoding The feature has outlived is usefulness and complicates the code. --- libavcodec/Makefile | 1 - libavcodec/libxvid.c | 31 ++++++- libavcodec/libxvid.h | 38 -------- libavcodec/libxvid_rc.c | 181 ------------------------------------- libavcodec/mpegvideo.h | 4 +- libavcodec/mpegvideo_enc.c | 30 ------ 6 files changed, 30 insertions(+), 255 deletions(-) delete mode 100644 libavcodec/libxvid.h delete mode 100644 libavcodec/libxvid_rc.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index eeac45d4c82a9..7bbc01c3b5f63 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -76,7 +76,6 @@ OBJS-$(CONFIG_IMDCT15) += imdct15.o OBJS-$(CONFIG_INTRAX8) += intrax8.o intrax8dsp.o OBJS-$(CONFIG_IVIDSP) += ivi_dsp.o OBJS-$(CONFIG_JPEGTABLES) += jpegtables.o -OBJS-$(CONFIG_LIBXVID) += libxvid_rc.o OBJS-$(CONFIG_LPC) += lpc.o OBJS-$(CONFIG_LSP) += lsp.o OBJS-$(CONFIG_LZF) += lzf.o diff --git a/libavcodec/libxvid.c b/libavcodec/libxvid.c index 9cbe9c17fa78c..1e8dc5d01b799 100644 --- a/libavcodec/libxvid.c +++ b/libavcodec/libxvid.c @@ -26,6 +26,7 @@ */ #include +#include #include #include #include @@ -39,7 +40,6 @@ #include "avcodec.h" #include "internal.h" -#include "libxvid.h" #include "mpegutils.h" /** @@ -359,6 +359,33 @@ static void xvid_correct_framerate(AVCodecContext *avctx) } } +/* Create temporary file using mkstemp(), tries /tmp first, if possible. + * *prefix can be a character constant; *filename will be allocated internally. + * Return file descriptor of opened file (or error code on error) + * and opened file name in **filename. */ +static int xvid_tempfile(AVCodecContext *avctx, const char *prefix, + char **filename) +{ + int fd = -1; + size_t len = strlen(prefix) + 12; /* room for "/tmp/" and "XXXXXX\0" */ + *filename = av_malloc(len); + if (!(*filename)) { + av_log(avctx, AV_LOG_ERROR, "xvid_tempfile: Cannot allocate file name\n"); + return AVERROR(ENOMEM); + } + snprintf(*filename, len, "/tmp/%sXXXXXX", prefix); + fd = mkstemp(*filename); + if (fd < 0) { + snprintf(*filename, len, "./%sXXXXXX", prefix); + fd = mkstemp(*filename); + } + if (fd < 0) { + av_log(avctx, AV_LOG_ERROR, "xvid_tempfile: Cannot open temporary file %s\n", *filename); + return AVERROR(EIO); + } + return fd; /* success */ +} + static av_cold int xvid_encode_init(AVCodecContext *avctx) { int xerr, i; @@ -519,7 +546,7 @@ FF_ENABLE_DEPRECATION_WARNINGS rc2pass2.version = XVID_VERSION; rc2pass2.bitrate = avctx->bit_rate; - fd = ff_tempfile("xvidff.", &x->twopassfile); + fd = xvid_tempfile(avctx, "xvidff.", &x->twopassfile); if (fd < 0) { av_log(avctx, AV_LOG_ERROR, "Xvid: Cannot write 2-pass pipe\n"); return fd; diff --git a/libavcodec/libxvid.h b/libavcodec/libxvid.h deleted file mode 100644 index 4535898530ecb..0000000000000 --- a/libavcodec/libxvid.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * copyright (C) 2006 Corey Hickey - * - * This file is part of Libav. - * - * Libav is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * Libav is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_LIBXVID_H -#define AVCODEC_LIBXVID_H - -/** - * @file - * common functions for use with the Xvid wrappers - */ - -int ff_tempfile(const char *prefix, char **filename); - -struct MpegEncContext; - -/* rate control */ -int ff_xvid_rate_control_init(struct MpegEncContext *s); -void ff_xvid_rate_control_uninit(struct MpegEncContext *s); -float ff_xvid_rate_estimate_qscale(struct MpegEncContext *s, int dry_run); - -#endif /* AVCODEC_LIBXVID_H */ diff --git a/libavcodec/libxvid_rc.c b/libavcodec/libxvid_rc.c deleted file mode 100644 index 94301a2ac1ffc..0000000000000 --- a/libavcodec/libxvid_rc.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Xvid rate control wrapper for lavc video encoders - * - * Copyright (c) 2006 Michael Niedermayer - * - * This file is part of Libav. - * - * Libav is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * Libav is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" - -#include -#include -#include - -#include "libavutil/attributes.h" -#include "libavutil/internal.h" - -#include "avcodec.h" -#include "libxvid.h" -#include "mpegvideo.h" - -/* Create temporary file using mkstemp(), tries /tmp first, if possible. - * *prefix can be a character constant; *filename will be allocated internally. - * Return file descriptor of opened file (or error code on error) - * and opened file name in **filename. */ -int ff_tempfile(const char *prefix, char **filename) -{ - int fd = -1; - size_t len = strlen(prefix) + 12; /* room for "/tmp/" and "XXXXXX\0" */ - *filename = av_malloc(len); - if (!(*filename)) { - av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot allocate file name\n"); - return AVERROR(ENOMEM); - } - snprintf(*filename, len, "/tmp/%sXXXXXX", prefix); - fd = mkstemp(*filename); - if (fd < 0) { - snprintf(*filename, len, "./%sXXXXXX", prefix); - fd = mkstemp(*filename); - } - if (fd < 0) { - av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot open temporary file %s\n", *filename); - return AVERROR(EIO); - } - return fd; /* success */ -} - -av_cold int ff_xvid_rate_control_init(MpegEncContext *s) -{ - char *tmp_name; - int fd, i; - xvid_plg_create_t xvid_plg_create = { 0 }; - xvid_plugin_2pass2_t xvid_2pass2 = { 0 }; - - fd = ff_tempfile("xvidrc.", &tmp_name); - if (fd < 0) { - av_log(s, AV_LOG_ERROR, "Cannot create temporary pass2 file.\n"); - return fd; - } - - for (i = 0; i < s->rc_context.num_entries; i++) { - static const char frame_types[] = " ipbs"; - char tmp[256]; - RateControlEntry *rce; - - rce = &s->rc_context.entry[i]; - - snprintf(tmp, sizeof(tmp), "%c %d %d %d %d %d %d\n", - frame_types[rce->pict_type], - (int) lrintf(rce->qscale / FF_QP2LAMBDA), - rce->i_count, s->mb_num - rce->i_count - rce->skip_count, - rce->skip_count, - (rce->i_tex_bits + rce->p_tex_bits + rce->misc_bits + 7) / 8, - (rce->header_bits + rce->mv_bits + 7) / 8); - - if (strlen(tmp) > write(fd, tmp, strlen(tmp))) { - av_log(s, AV_LOG_ERROR, "Cannot write to temporary pass2 file.\n"); - return AVERROR(EIO); - } - } - - close(fd); - - xvid_2pass2.version = XVID_MAKE_VERSION(1, 1, 0); - xvid_2pass2.filename = tmp_name; - xvid_2pass2.bitrate = s->avctx->bit_rate; - xvid_2pass2.vbv_size = s->avctx->rc_buffer_size; - xvid_2pass2.vbv_maxrate = s->avctx->rc_max_rate; - xvid_2pass2.vbv_initial = s->avctx->rc_initial_buffer_occupancy; - - xvid_plg_create.version = XVID_MAKE_VERSION(1, 1, 0); - xvid_plg_create.fbase = s->avctx->time_base.den; - xvid_plg_create.fincr = s->avctx->time_base.num; - xvid_plg_create.param = &xvid_2pass2; - - if (xvid_plugin_2pass2(NULL, XVID_PLG_CREATE, &xvid_plg_create, - &s->rc_context.non_lavc_opaque) < 0) { - av_log(s, AV_LOG_ERROR, "xvid_plugin_2pass2 failed\n"); - return -1; - } - return 0; -} - -float ff_xvid_rate_estimate_qscale(MpegEncContext *s, int dry_run) -{ - xvid_plg_data_t xvid_plg_data = { 0 }; - - xvid_plg_data.version = XVID_MAKE_VERSION(1, 1, 0); - xvid_plg_data.width = s->width; - xvid_plg_data.height = s->height; - xvid_plg_data.mb_width = s->mb_width; - xvid_plg_data.mb_height = s->mb_height; - xvid_plg_data.fbase = s->avctx->time_base.den; - xvid_plg_data.fincr = s->avctx->time_base.num; - xvid_plg_data.min_quant[0] = s->avctx->qmin; - xvid_plg_data.min_quant[1] = s->avctx->qmin; - xvid_plg_data.min_quant[2] = s->avctx->qmin; // FIXME i/b factor & offset - xvid_plg_data.max_quant[0] = s->avctx->qmax; - xvid_plg_data.max_quant[1] = s->avctx->qmax; - xvid_plg_data.max_quant[2] = s->avctx->qmax; // FIXME i/b factor & offset - xvid_plg_data.bquant_offset = 0; // 100 * s->avctx->b_quant_offset; - xvid_plg_data.bquant_ratio = 100; // * s->avctx->b_quant_factor; - - if (!s->rc_context.dry_run_qscale) { - if (s->picture_number) { - xvid_plg_data.length = - xvid_plg_data.stats.length = (s->frame_bits + 7) / 8; - xvid_plg_data.frame_num = s->rc_context.last_picture_number; - xvid_plg_data.quant = s->qscale; - xvid_plg_data.type = s->last_pict_type; - if (xvid_plugin_2pass2(s->rc_context.non_lavc_opaque, - XVID_PLG_AFTER, &xvid_plg_data, NULL)) { - av_log(s, AV_LOG_ERROR, - "xvid_plugin_2pass2(handle, XVID_PLG_AFTER, ...) FAILED\n"); - return -1; - } - } - s->rc_context.last_picture_number = - xvid_plg_data.frame_num = s->picture_number; - xvid_plg_data.quant = 0; - if (xvid_plugin_2pass2(s->rc_context.non_lavc_opaque, - XVID_PLG_BEFORE, &xvid_plg_data, NULL)) { - av_log(s, AV_LOG_ERROR, - "xvid_plugin_2pass2(handle, XVID_PLG_BEFORE, ...) FAILED\n"); - return -1; - } - s->rc_context.dry_run_qscale = xvid_plg_data.quant; - } - xvid_plg_data.quant = s->rc_context.dry_run_qscale; - if (!dry_run) - s->rc_context.dry_run_qscale = 0; - - // FIXME this is not exactly identical to Xvid - if (s->pict_type == AV_PICTURE_TYPE_B) - return xvid_plg_data.quant * FF_QP2LAMBDA * s->avctx->b_quant_factor + - s->avctx->b_quant_offset; - else - return xvid_plg_data.quant * FF_QP2LAMBDA; -} - -av_cold void ff_xvid_rate_control_uninit(MpegEncContext *s) -{ - xvid_plg_destroy_t xvid_plg_destroy; - - xvid_plugin_2pass2(s->rc_context.non_lavc_opaque, XVID_PLG_DESTROY, - &xvid_plg_destroy, NULL); -} diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index 932a6f2b34c57..f096b8a0fa8fb 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -356,7 +356,6 @@ typedef struct MpegEncContext { int prev_mb_info, last_mb_info; uint8_t *mb_info_ptr; int mb_info_size; - int rc_strategy; /* H.263+ specific */ int umvplus; ///< == H.263+ && unrestricted_mv @@ -602,8 +601,7 @@ FF_MPV_OPT_CMP_FUNC, \ {"lmax", "maximum Lagrange factor (VBR)", FF_MPV_OFFSET(lmax), AV_OPT_TYPE_INT, {.i64 = 31*FF_QP2LAMBDA }, 0, INT_MAX, FF_MPV_OPT_FLAGS }, \ {"ibias", "intra quant bias", FF_MPV_OFFSET(intra_quant_bias), AV_OPT_TYPE_INT, {.i64 = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \ {"pbias", "inter quant bias", FF_MPV_OFFSET(inter_quant_bias), AV_OPT_TYPE_INT, {.i64 = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \ -{"rc_strategy", "ratecontrol method", FF_MPV_OFFSET(rc_strategy), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, FF_MPV_OPT_FLAGS }, \ -{"motion_est", "motion estimation algorithm", FF_MPV_OFFSET(motion_est), AV_OPT_TYPE_INT, {.i64 = FF_ME_EPZS }, FF_ME_ZERO, FF_ME_XONE, FF_MPV_OPT_FLAGS, "motion_est" }, \ +{"motion_est", "motion estimation algorithm", FF_MPV_OFFSET(motion_est), AV_OPT_TYPE_INT, {.i64 = FF_ME_EPZS }, FF_ME_ZERO, FF_ME_XONE, FF_MPV_OPT_FLAGS, "motion_est" }, \ { "zero", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_ZERO }, 0, 0, FF_MPV_OPT_FLAGS, "motion_est" }, \ { "epzs", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_EPZS }, 0, 0, FF_MPV_OPT_FLAGS, "motion_est" }, \ { "xone", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_XONE }, 0, 0, FF_MPV_OPT_FLAGS, "motion_est" }, \ diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index 6a7c9e500fb7e..40c044d703271 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -60,7 +60,6 @@ #include "bytestream.h" #include "wmv2.h" #include "rv10.h" -#include "libxvid.h" #include #define QUANT_BIAS_SHIFT 8 @@ -872,28 +871,9 @@ FF_ENABLE_DEPRECATION_WARNINGS 31, 0); } -#if FF_API_RC_STRATEGY -FF_DISABLE_DEPRECATION_WARNINGS - if (!s->rc_strategy) - s->rc_strategy = s->avctx->rc_strategy; -FF_ENABLE_DEPRECATION_WARNINGS -#endif - if (ff_rate_control_init(s) < 0) return -1; - if ((s->avctx->flags & AV_CODEC_FLAG_PASS2) && s->rc_strategy == 1) { -#if CONFIG_LIBXVID - ret = ff_xvid_rate_control_init(s); -#else - ret = AVERROR(ENOSYS); - av_log(s->avctx, AV_LOG_ERROR, - "Xvid ratecontrol requires libavcodec compiled with Xvid support.\n"); -#endif - if (ret < 0) - return ret; - } - #if FF_API_ERROR_RATE FF_DISABLE_DEPRECATION_WARNINGS if (avctx->error_rate) @@ -987,11 +967,6 @@ av_cold int ff_mpv_encode_end(AVCodecContext *avctx) int i; ff_rate_control_uninit(s); -#if CONFIG_LIBXVID - if ((avctx->flags & AV_CODEC_FLAG_PASS2) && s->rc_strategy == 1) - ff_xvid_rate_control_uninit(s); -#endif - ff_mpv_common_end(s); if (CONFIG_MJPEG_ENCODER && s->out_format == FMT_MJPEG) @@ -3438,11 +3413,6 @@ static int estimate_qp(MpegEncContext *s, int dry_run){ if(!dry_run) s->next_lambda= 0; } else if (!s->fixed_qscale) { int quality; -#if CONFIG_LIBXVID - if ((s->avctx->flags & AV_CODEC_FLAG_PASS2) && s->rc_strategy == 1) - quality = ff_xvid_rate_estimate_qscale(s, dry_run); - else -#endif quality = ff_rate_estimate_qscale(s, dry_run); s->current_picture_ptr->f->quality = s->current_picture.f->quality = quality; From f1248fae90b45501af4e8743d373e79191470331 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 22 Nov 2016 08:21:48 +0100 Subject: [PATCH 0695/3374] configure: Handle dxva2 optional components in the standard way --- configure | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/configure b/configure index d88329c71fa2a..6feaa64d78da8 100755 --- a/configure +++ b/configure @@ -4518,7 +4518,6 @@ check_func usleep check_func_headers io.h setmode check_func_headers stdlib.h getenv -check_func_headers windows.h CoTaskMemFree -lole32 check_func_headers windows.h GetProcessAffinityMask check_func_headers windows.h GetProcessTimes check_func_headers windows.h GetSystemTimeAsFileTime @@ -4777,6 +4776,10 @@ if enabled libxcb; then add_extralibs "$xcb_shape_extralibs $xcb_shm_extralibs $xcb_xfixes_extralibs" fi +enabled dxva2 && + check_lib windows.h CoTaskMemFree -lole32 && + enable dxva2_lib + enabled vaapi && require vaapi va/va.h vaInitialize -lva enabled vaapi && @@ -5055,10 +5058,6 @@ check_deps $CONFIG_LIST \ $HAVE_LIST \ $ALL_COMPONENTS \ -enabled_all dxva2 CoTaskMemFree && - prepend avconv_extralibs $($ldflags_filter "-lole32") && - enable dxva2_lib - map 'enabled $v && intrinsics=${v#intrinsics_}' $INTRINSICS_LIST for thread in $THREADS_LIST; do From fc368497f2fff54ddf5316224c573c9d1939fb25 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 11 Dec 2016 17:01:33 +0100 Subject: [PATCH 0696/3374] configure: Add missing dxva2 dependency for dxva2_lib --- configure | 1 + 1 file changed, 1 insertion(+) diff --git a/configure b/configure index 6feaa64d78da8..6d809f7780e07 100755 --- a/configure +++ b/configure @@ -2128,6 +2128,7 @@ zmbv_encoder_deps="zlib" # hardware accelerators d3d11va_deps="d3d11_h dxva_h ID3D11VideoDecoder" dxva2_deps="dxva2api_h DXVA2_ConfigPictureDecode" +dxva2_lib_deps="dxva2" vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads" vda_extralibs="-framework CoreFoundation -framework VideoDecodeAcceleration -framework QuartzCore" From b0e6b3f4777910d61083976aa9fc78a1e0731aae Mon Sep 17 00:00:00 2001 From: Alexandra Hajkova Date: Sun, 11 Dec 2016 12:10:19 +0100 Subject: [PATCH 0697/3374] hevc: ppc: Add HEVC 4x4 IDCT for PowerPC Signed-off-by: Diego Biurrun --- libavcodec/hevcdsp.c | 2 + libavcodec/hevcdsp.h | 1 + libavcodec/ppc/Makefile | 1 + libavcodec/ppc/hevcdsp.c | 108 ++++++++++++++++++++++++++++++ libavcodec/ppc/hevcdsp_template.c | 48 +++++++++++++ 5 files changed, 160 insertions(+) create mode 100644 libavcodec/ppc/hevcdsp.c create mode 100644 libavcodec/ppc/hevcdsp_template.c diff --git a/libavcodec/hevcdsp.c b/libavcodec/hevcdsp.c index 7c191986a013b..8ae023b49826f 100644 --- a/libavcodec/hevcdsp.c +++ b/libavcodec/hevcdsp.c @@ -245,6 +245,8 @@ void ff_hevc_dsp_init(HEVCDSPContext *hevcdsp, int bit_depth) break; } + if (ARCH_PPC) + ff_hevc_dsp_init_ppc(hevcdsp, bit_depth); if (ARCH_X86) ff_hevc_dsp_init_x86(hevcdsp, bit_depth); } diff --git a/libavcodec/hevcdsp.h b/libavcodec/hevcdsp.h index 49cb7110d5fe4..2f4ff0111f5d9 100644 --- a/libavcodec/hevcdsp.h +++ b/libavcodec/hevcdsp.h @@ -115,6 +115,7 @@ typedef struct HEVCDSPContext { void ff_hevc_dsp_init(HEVCDSPContext *hpc, int bit_depth); +void ff_hevc_dsp_init_ppc(HEVCDSPContext *c, const int bit_depth); void ff_hevc_dsp_init_x86(HEVCDSPContext *c, const int bit_depth); extern const int16_t ff_hevc_epel_coeffs[7][16]; diff --git a/libavcodec/ppc/Makefile b/libavcodec/ppc/Makefile index 09eabcb83b28a..4b92add3d00f4 100644 --- a/libavcodec/ppc/Makefile +++ b/libavcodec/ppc/Makefile @@ -25,6 +25,7 @@ OBJS-$(CONFIG_VP8DSP) += ppc/vp8dsp_altivec.o # decoders/encoders OBJS-$(CONFIG_APE_DECODER) += ppc/apedsp_altivec.o +OBJS-$(CONFIG_HEVC_DECODER) += ppc/hevcdsp.o OBJS-$(CONFIG_SVQ1_ENCODER) += ppc/svq1enc_altivec.o OBJS-$(CONFIG_VORBIS_DECODER) += ppc/vorbisdsp_altivec.o OBJS-$(CONFIG_VP7_DECODER) += ppc/vp8dsp_altivec.o diff --git a/libavcodec/ppc/hevcdsp.c b/libavcodec/ppc/hevcdsp.c new file mode 100644 index 0000000000000..9200e27e6588c --- /dev/null +++ b/libavcodec/ppc/hevcdsp.c @@ -0,0 +1,108 @@ +/* SIMD-optimized IDCT functions for HEVC decoding + * Copyright (c) Alexandra Hajkova + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#if HAVE_ALTIVEC_H +#include +#endif + +#include "libavutil/cpu.h" +#include "libavutil/ppc/cpu.h" +#include "libavutil/ppc/types_altivec.h" +#include "libavutil/ppc/util_altivec.h" + +#include "libavcodec/hevcdsp.h" + +#if HAVE_ALTIVEC +static const vector int16_t trans4[4] = { + { 64, 64, 64, 64, 64, 64, 64, 64 }, + { 83, 36, 83, 36, 83, 36, 83, 36 }, + { 64, -64, 64, -64, 64, -64, 64, -64 }, + { 36, -83, 36, -83, 36, -83, 36, -83 }, +}; + +static const vec_u8 mask[2] = { + { 0x00, 0x01, 0x08, 0x09, 0x10, 0x11, 0x18, 0x19, 0x02, 0x03, 0x0A, 0x0B, 0x12, 0x13, 0x1A, 0x1B }, + { 0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D, 0x06, 0x07, 0x0E, 0x0F, 0x16, 0x17, 0x1E, 0x1F }, +}; + +static void transform4x4(vector int16_t src_01, vector int16_t src_23, + vector int32_t res[4], const int shift, int16_t *coeffs) +{ + vector int16_t src_02, src_13; + vector int32_t zero = vec_splat_s32(0); + vector int32_t e0, o0, e1, o1; + vector int32_t add; + + src_13 = vec_mergel(src_01, src_23); + src_02 = vec_mergeh(src_01, src_23); + + e0 = vec_msums(src_02, trans4[0], zero); + o0 = vec_msums(src_13, trans4[1], zero); + e1 = vec_msums(src_02, trans4[2], zero); + o1 = vec_msums(src_13, trans4[3], zero); + + add = vec_sl(vec_splat_s32(1), vec_splat_u32(shift - 1)); + e0 = vec_add(e0, add); + e1 = vec_add(e1, add); + + res[0] = vec_add(e0, o0); + res[1] = vec_add(e1, o1); + res[2] = vec_sub(e1, o1); + res[3] = vec_sub(e0, o0); +} + +static void scale(vector int32_t res[4], vector int16_t res_packed[2], int shift) +{ + int i; + vector unsigned int v_shift = vec_splat_u32(shift); + + for (i = 0; i < 4; i++) + res[i] = vec_sra(res[i], v_shift); + + // clip16 + res_packed[0] = vec_packs(res[0], res[1]); + res_packed[1] = vec_packs(res[2], res[3]); +} + +#define FUNCDECL(a, depth) a ## _ ## depth ## _altivec +#define FUNC(a, b) FUNCDECL(a, b) + +#define BIT_DEPTH 8 +#include "hevcdsp_template.c" +#undef BIT_DEPTH + +#define BIT_DEPTH 10 +#include "hevcdsp_template.c" +#undef BIT_DEPTH +#endif /* HAVE_ALTIVEC */ + +av_cold void ff_hevc_dsp_init_ppc(HEVCDSPContext *c, const int bit_depth) +{ +#if HAVE_ALTIVEC + if (!PPC_ALTIVEC(av_get_cpu_flags())) + return; + + if (bit_depth == 8) + c->idct[0] = ff_hevc_idct_4x4_8_altivec; + if (bit_depth == 10) + c->idct[0] = ff_hevc_idct_4x4_10_altivec; +#endif /* HAVE_ALTIVEC */ +} diff --git a/libavcodec/ppc/hevcdsp_template.c b/libavcodec/ppc/hevcdsp_template.c new file mode 100644 index 0000000000000..a68ee18dbb38b --- /dev/null +++ b/libavcodec/ppc/hevcdsp_template.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) Alexandra Hajkova + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +static void FUNC(ff_hevc_idct_4x4, BIT_DEPTH)(int16_t *coeffs, int col_limit) +{ + const int shift = 7; + const int shift2 = 20 - BIT_DEPTH; + vector int16_t src_01, src_23; + vector int32_t res[4]; + vector int16_t res_packed[2]; + + src_01 = vec_ld(0, coeffs); + src_23 = vec_ld(16, coeffs); + + transform4x4(src_01, src_23, res, shift, coeffs); + src_01 = vec_packs(res[0], res[1]); + src_23 = vec_packs(res[2], res[3]); + scale(res, res_packed, shift); + // transpose + src_01 = vec_perm(res_packed[0], res_packed[1], mask[0]); + src_23 = vec_perm(res_packed[0], res_packed[1], mask[1]); + + transform4x4(src_01, src_23, res, shift2, coeffs); + scale(res, res_packed, shift2); + // transpose + src_01 = vec_perm(res_packed[0], res_packed[1], mask[0]); + src_23 = vec_perm(res_packed[0], res_packed[1], mask[1]); + + vec_st(src_01, 0, coeffs); + vec_st(src_23, 16, coeffs); +} From 6aa4ba7131b6e8668e33430e18101a051fe492eb Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 12 Dec 2016 12:38:06 +0100 Subject: [PATCH 0698/3374] dxva2: Keep code shared between dxva2 and d3d11va under the correct #if This partially reverts commit ac648bb835edd3f67bda2267d0e72e5e582eb5a1. --- libavcodec/dxva2_internal.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libavcodec/dxva2_internal.h b/libavcodec/dxva2_internal.h index e7a973410544f..499b37c190c13 100644 --- a/libavcodec/dxva2_internal.h +++ b/libavcodec/dxva2_internal.h @@ -32,6 +32,11 @@ #if CONFIG_DXVA2 #include "dxva2.h" +#endif +#if CONFIG_D3D11VA +#include "d3d11va.h" +#endif +#if HAVE_DXVA_H /* When targeting WINAPI_FAMILY_PHONE_APP or WINAPI_FAMILY_APP, dxva.h * defines nothing. Force the struct definitions to be visible. */ #undef WINAPI_FAMILY @@ -40,9 +45,6 @@ #define _CRT_BUILD_DESKTOP_APP 0 #include #endif -#if CONFIG_D3D11VA -#include "d3d11va.h" -#endif #include "avcodec.h" From 0309ddcfb25fd44883bfcdb07509eb4907576b97 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 2 Dec 2016 13:21:02 +0100 Subject: [PATCH 0699/3374] lavc: handle MP3 in get_audio_frame_duration() --- libavcodec/utils.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 0b44bb64647cc..5350eb819a920 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -1186,6 +1186,9 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba, if (id == AV_CODEC_ID_BINKAUDIO_DCT) return (480 << (sr / 22050)) / ch; } + + if (id == AV_CODEC_ID_MP3) + return sr <= 24000 ? 576 : 1152; } if (ba > 0) { From 47e547b321338c73c21fa623789f1efbd80a297a Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 24 May 2016 15:09:29 +0200 Subject: [PATCH 0700/3374] lavc: add a null bitstream filter It is useful for testing/debugging and will also be used as the default filter in the following commit adding pre-decode filtering to avoid having a separate non-filtered codepath. --- doc/bitstream_filters.texi | 3 +++ libavcodec/Makefile | 1 + libavcodec/bitstream_filters.c | 1 + libavcodec/null_bsf.c | 43 ++++++++++++++++++++++++++++++++++ 4 files changed, 48 insertions(+) create mode 100644 libavcodec/null_bsf.c diff --git a/doc/bitstream_filters.texi b/doc/bitstream_filters.texi index 7ddf52e34d62e..2e13cbe180f15 100644 --- a/doc/bitstream_filters.texi +++ b/doc/bitstream_filters.texi @@ -90,6 +90,9 @@ avconv -i frame_%d.jpg -c:v copy rotated.avi @section noise +@section null +This bitstream filter passes the packets through unchanged. + @section remove_extradata @c man end BITSTREAM FILTERS diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 7bbc01c3b5f63..d571d8def3411 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -764,6 +764,7 @@ OBJS-$(CONFIG_MJPEG2JPEG_BSF) += mjpeg2jpeg_bsf.o OBJS-$(CONFIG_MJPEGA_DUMP_HEADER_BSF) += mjpega_dump_header_bsf.o OBJS-$(CONFIG_MOV2TEXTSUB_BSF) += movsub_bsf.o OBJS-$(CONFIG_NOISE_BSF) += noise_bsf.o +OBJS-$(CONFIG_NULL_BSF) += null_bsf.o OBJS-$(CONFIG_REMOVE_EXTRADATA_BSF) += remove_extradata_bsf.o OBJS-$(CONFIG_TEXT2MOVSUB_BSF) += movsub_bsf.o diff --git a/libavcodec/bitstream_filters.c b/libavcodec/bitstream_filters.c index 8a5379ec93c15..ee9e4bade5d08 100644 --- a/libavcodec/bitstream_filters.c +++ b/libavcodec/bitstream_filters.c @@ -34,6 +34,7 @@ extern const AVBitStreamFilter ff_imx_dump_header_bsf; extern const AVBitStreamFilter ff_mjpeg2jpeg_bsf; extern const AVBitStreamFilter ff_mjpega_dump_header_bsf; extern const AVBitStreamFilter ff_mov2textsub_bsf; +extern const AVBitStreamFilter ff_null_bsf; extern const AVBitStreamFilter ff_text2movsub_bsf; extern const AVBitStreamFilter ff_noise_bsf; extern const AVBitStreamFilter ff_remove_extradata_bsf; diff --git a/libavcodec/null_bsf.c b/libavcodec/null_bsf.c new file mode 100644 index 0000000000000..0fe4f3529f3d5 --- /dev/null +++ b/libavcodec/null_bsf.c @@ -0,0 +1,43 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Null bitstream filter -- pass the input through unchanged. + */ + +#include "avcodec.h" +#include "bsf.h" + +static int null_filter(AVBSFContext *ctx, AVPacket *out) +{ + AVPacket *in; + int ret; + + ret = ff_bsf_get_packet(ctx, &in); + if (ret < 0) + return ret; + av_packet_move_ref(out, in); + av_packet_free(&in); + return 0; +} + +const AVBitStreamFilter ff_null_bsf = { + .name = "null", + .filter = null_filter, +}; From 549d0bdca53af7a6e0c612ab4b03baecf3a5878f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 26 Oct 2016 13:41:12 +0200 Subject: [PATCH 0701/3374] decode: be more explicit about storing the last packet properties The current code stores a pointer to the packet passed to the decoder, which is then used during get_buffer() for timestamps and side data passthrough. However, since this is a pointer to user data which we do not own, storing it is potentially dangerous. It is also ill defined for the new decoding API with split input/output. Fix this problem by making an explicit internally owned copy of the packet properties. --- libavcodec/decode.c | 33 ++++++++++++++++++++------------- libavcodec/internal.h | 6 +++--- libavcodec/pthread_frame.c | 2 +- libavcodec/utils.c | 8 ++++++++ 4 files changed, 32 insertions(+), 17 deletions(-) diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 00085c3b4dcc8..b02278d3a68bc 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -99,6 +99,14 @@ static int apply_param_change(AVCodecContext *avctx, AVPacket *avpkt) return 0; } +static int extract_packet_props(AVCodecInternal *avci, const AVPacket *pkt) +{ + av_packet_unref(avci->last_pkt_props); + if (pkt) + return av_packet_copy_props(avci->last_pkt_props, pkt); + return 0; +} + static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame) { int ret; @@ -304,7 +312,10 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi return AVERROR(ENOSYS); } - avctx->internal->pkt = avpkt; + ret = extract_packet_props(avci, avpkt); + if (ret < 0) + return ret; + ret = apply_param_change(avctx, avpkt); if (ret < 0) return ret; @@ -368,7 +379,9 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, return AVERROR(ENOSYS); } - avctx->internal->pkt = avpkt; + ret = extract_packet_props(avci, avpkt); + if (ret < 0) + return ret; if (!avpkt->data && avpkt->size) { av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n"); @@ -408,7 +421,10 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, { int ret; - avctx->internal->pkt = avpkt; + ret = extract_packet_props(avctx->internal, avpkt); + if (ret < 0) + return ret; + *got_sub_ptr = 0; ret = avctx->codec->decode(avctx, sub, got_sub_ptr, avpkt); if (*got_sub_ptr) @@ -739,7 +755,7 @@ int avcodec_default_get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) { - AVPacket *pkt = avctx->internal->pkt; + AVPacket *pkt = avctx->internal->last_pkt_props; int i; struct { enum AVPacketSideDataType packet; @@ -759,15 +775,6 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) frame->chroma_location = avctx->chroma_sample_location; frame->reordered_opaque = avctx->reordered_opaque; - if (!pkt) { -#if FF_API_PKT_PTS -FF_DISABLE_DEPRECATION_WARNINGS - frame->pkt_pts = AV_NOPTS_VALUE; -FF_ENABLE_DEPRECATION_WARNINGS -#endif - frame->pts = AV_NOPTS_VALUE; - return 0; - } #if FF_API_PKT_PTS FF_DISABLE_DEPRECATION_WARNINGS diff --git a/libavcodec/internal.h b/libavcodec/internal.h index 4bde09ab8adc2..2ca7a45e811b8 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -131,10 +131,10 @@ typedef struct AVCodecInternal { void *thread_ctx; /** - * Current packet as passed into the decoder, to avoid having to pass the - * packet into every function. + * Properties (timestamps+side data) extracted from the last packet passed + * for decoding. */ - AVPacket *pkt; + AVPacket *last_pkt_props; /** * hwaccel-specific private data diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 2736a81efea77..75f4ff46247fd 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -656,7 +656,7 @@ int ff_frame_thread_init(AVCodecContext *avctx) } *copy->internal = *src->internal; copy->internal->thread_ctx = p; - copy->internal->pkt = &p->avpkt; + copy->internal->last_pkt_props = &p->avpkt; if (!i) { src = copy; diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 5350eb819a920..b569b48f7a843 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -433,6 +433,12 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code goto free_and_end; } + avctx->internal->last_pkt_props = av_packet_alloc(); + if (!avctx->internal->last_pkt_props) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } + if (codec->priv_data_size > 0) { if (!avctx->priv_data) { avctx->priv_data = av_mallocz(codec->priv_data_size); @@ -713,6 +719,7 @@ FF_ENABLE_DEPRECATION_WARNINGS av_frame_free(&avctx->internal->to_free); av_frame_free(&avctx->internal->buffer_frame); av_packet_free(&avctx->internal->buffer_pkt); + av_packet_free(&avctx->internal->last_pkt_props); av_freep(&avctx->internal->pool); } av_freep(&avctx->internal); @@ -753,6 +760,7 @@ av_cold int avcodec_close(AVCodecContext *avctx) av_frame_free(&avctx->internal->to_free); av_frame_free(&avctx->internal->buffer_frame); av_packet_free(&avctx->internal->buffer_pkt); + av_packet_free(&avctx->internal->last_pkt_props); for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++) av_buffer_pool_uninit(&pool->pools[i]); av_freep(&avctx->internal->pool); From 061a0c14bb5767bca72e3a7227ca400de439ba09 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 26 Oct 2016 13:59:15 +0200 Subject: [PATCH 0702/3374] decode: restructure the core decoding code Currently, the new decoding API is pretty much just a wrapper around the old deprecated one. This is problematic, since it interferes with making full use of the flexibility added by the new API. The old API should also be removed at some future point. Reorganize the code so that the new send_packet/receive_frame functions call the actual decoding directly and change the old deprecated avcodec_decode_* functions into wrappers around the new API. The new internal API for decoders is now changing as well. Before this commit, it mirrors the public API, so the decoders need to implement send_packet() and receive_frame() callbacks. This turns out to require awkward constructs in both the decoders and the generic code. After this commit, the decoders only implement the receive_frame() callback and call a new internal function, ff_decode_get_packet() to obtain input data, in the same manner to how the bitstream filters now work. avcodec will now always make a reference to the input packet, which means that non-refcounted input packets will be copied. Keeping the previous behaviour, where this copy could sometimes be avoided, would make the code significantly more complex and fragile for only dubious gains, since packets are typically small and everyone who cares about performance should use refcounted packets anyway. --- libavcodec/avcodec.h | 18 +- libavcodec/decode.c | 391 +++++++++++++++++++++++------------------- libavcodec/decode.h | 35 ++++ libavcodec/internal.h | 17 ++ libavcodec/utils.c | 22 ++- 5 files changed, 294 insertions(+), 189 deletions(-) create mode 100644 libavcodec/decode.h diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 6e1ed74e08001..1827711b50694 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3217,20 +3217,22 @@ typedef struct AVCodec { int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, AVPacket *avpkt); int (*close)(AVCodecContext *); /** - * Decode/encode API with decoupled packet/frame dataflow. The API is the + * Encode API with decoupled packet/frame dataflow. The API is the * same as the avcodec_ prefixed APIs (avcodec_send_frame() etc.), except * that: * - never called if the codec is closed or the wrong type, - * - AVPacket parameter change side data is applied right before calling - * AVCodec->send_packet, - * - if AV_CODEC_CAP_DELAY is not set, drain packets or frames are never sent, - * - only one drain packet is ever passed down (until the next flush()), - * - a drain AVPacket is always NULL (no need to check for avpkt->size). + * - if AV_CODEC_CAP_DELAY is not set, drain frames are never sent, + * - only one drain frame is ever passed down, */ int (*send_frame)(AVCodecContext *avctx, const AVFrame *frame); - int (*send_packet)(AVCodecContext *avctx, const AVPacket *avpkt); - int (*receive_frame)(AVCodecContext *avctx, AVFrame *frame); int (*receive_packet)(AVCodecContext *avctx, AVPacket *avpkt); + + /** + * Decode API with decoupled packet/frame dataflow. This function is called + * to get one output frame. It should call ff_decode_get_packet() to obtain + * input data. + */ + int (*receive_frame)(AVCodecContext *avctx, AVFrame *frame); /** * Flush buffers. * Will be called when seeking diff --git a/libavcodec/decode.c b/libavcodec/decode.c index b02278d3a68bc..a1908ecf4b056 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -24,6 +24,7 @@ #include "config.h" #include "libavutil/avassert.h" +#include "libavutil/avstring.h" #include "libavutil/common.h" #include "libavutil/frame.h" #include "libavutil/hwcontext.h" @@ -31,6 +32,7 @@ #include "avcodec.h" #include "bytestream.h" +#include "decode.h" #include "internal.h" #include "thread.h" @@ -152,109 +154,188 @@ static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame) return 0; } -static int do_decode(AVCodecContext *avctx, AVPacket *pkt) +int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt) { - int got_frame; + AVCodecInternal *avci = avctx->internal; int ret; - av_assert0(!avctx->internal->buffer_frame->buf[0]); + if (avci->draining) + return AVERROR_EOF; + + if (!avci->buffer_pkt->data && !avci->buffer_pkt->side_data_elems) + return AVERROR(EAGAIN); + + av_packet_move_ref(pkt, avci->buffer_pkt); + + ret = extract_packet_props(avctx->internal, pkt); + if (ret < 0) + goto finish; + + ret = apply_param_change(avctx, pkt); + if (ret < 0) + goto finish; + + if (avctx->codec->receive_frame) + avci->compat_decode_consumed += pkt->size; - if (!pkt) - pkt = avctx->internal->buffer_pkt; + return 0; +finish: + av_packet_unref(pkt); + return ret; +} + +/* + * The core of the receive_frame_wrapper for the decoders implementing + * the simple API. Certain decoders might consume partial packets without + * returning any output, so this function needs to be called in a loop until it + * returns EAGAIN. + **/ +static int decode_simple_internal(AVCodecContext *avctx, AVFrame *frame) +{ + AVCodecInternal *avci = avctx->internal; + DecodeSimpleContext *ds = &avci->ds; + AVPacket *pkt = ds->in_pkt; + int got_frame; + int ret; - // This is the lesser evil. The field is for compatibility with legacy users - // of the legacy API, and users using the new API should not be forced to - // even know about this field. - avctx->refcounted_frames = 1; + if (!pkt->data && !avci->draining) { + av_packet_unref(pkt); + ret = ff_decode_get_packet(avctx, pkt); + if (ret < 0 && ret != AVERROR_EOF) + return ret; + } // Some codecs (at least wma lossless) will crash when feeding drain packets // after EOF was signaled. - if (avctx->internal->draining_done) + if (avci->draining_done) + return AVERROR_EOF; + + if (!pkt->data && + !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY || + avctx->active_thread_type & FF_THREAD_FRAME)) return AVERROR_EOF; - if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { - ret = avcodec_decode_video2(avctx, avctx->internal->buffer_frame, - &got_frame, pkt); - if (ret >= 0) - ret = pkt->size; - } else if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) { - ret = avcodec_decode_audio4(avctx, avctx->internal->buffer_frame, - &got_frame, pkt); + got_frame = 0; + + if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) { + ret = ff_thread_decode_frame(avctx, frame, &got_frame, pkt); } else { - ret = AVERROR(EINVAL); + ret = avctx->codec->decode(avctx, frame, &got_frame, pkt); + + if (!(avctx->codec->caps_internal & FF_CODEC_CAP_SETS_PKT_DTS)) + frame->pkt_dts = pkt->dts; + /* get_buffer is supposed to set frame parameters */ + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DR1)) { + frame->sample_aspect_ratio = avctx->sample_aspect_ratio; + frame->width = avctx->width; + frame->height = avctx->height; + frame->format = avctx->codec->type == AVMEDIA_TYPE_VIDEO ? + avctx->pix_fmt : avctx->sample_fmt; + } } - if (ret < 0) - return ret; + emms_c(); + + if (!got_frame) + av_frame_unref(frame); + + if (ret >= 0 && avctx->codec->type == AVMEDIA_TYPE_VIDEO) + ret = pkt->size; + +#if FF_API_AVCTX_TIMEBASE + if (avctx->framerate.num > 0 && avctx->framerate.den > 0) + avctx->time_base = av_inv_q(avctx->framerate); +#endif if (avctx->internal->draining && !got_frame) - avctx->internal->draining_done = 1; + avci->draining_done = 1; + + avci->compat_decode_consumed += ret; - if (ret >= pkt->size) { - av_packet_unref(avctx->internal->buffer_pkt); + if (ret >= pkt->size || ret < 0) { + av_packet_unref(pkt); } else { int consumed = ret; - if (pkt != avctx->internal->buffer_pkt) { - av_packet_unref(avctx->internal->buffer_pkt); - if ((ret = av_packet_ref(avctx->internal->buffer_pkt, pkt)) < 0) - return ret; - } - - avctx->internal->buffer_pkt->data += consumed; - avctx->internal->buffer_pkt->size -= consumed; - avctx->internal->buffer_pkt->pts = AV_NOPTS_VALUE; - avctx->internal->buffer_pkt->dts = AV_NOPTS_VALUE; + pkt->data += consumed; + pkt->size -= consumed; + pkt->pts = AV_NOPTS_VALUE; + pkt->dts = AV_NOPTS_VALUE; + avci->last_pkt_props->pts = AV_NOPTS_VALUE; + avci->last_pkt_props->dts = AV_NOPTS_VALUE; } if (got_frame) - av_assert0(avctx->internal->buffer_frame->buf[0]); + av_assert0(frame->buf[0]); + + return ret < 0 ? ret : 0; +} + +static int decode_simple_receive_frame(AVCodecContext *avctx, AVFrame *frame) +{ + int ret; + + while (!frame->buf[0]) { + ret = decode_simple_internal(avctx, frame); + if (ret < 0) + return ret; + } return 0; } -int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt) +static int decode_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame) { + AVCodecInternal *avci = avctx->internal; int ret; + av_assert0(!frame->buf[0]); + + if (avctx->codec->receive_frame) + ret = avctx->codec->receive_frame(avctx, frame); + else + ret = decode_simple_receive_frame(avctx, frame); + + if (ret == AVERROR_EOF) + avci->draining_done = 1; + + return ret; +} + +int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt) +{ + AVCodecInternal *avci = avctx->internal; + int ret = 0; + if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec)) return AVERROR(EINVAL); if (avctx->internal->draining) return AVERROR_EOF; + if (avci->buffer_pkt->data || avci->buffer_pkt->side_data_elems) + return AVERROR(EAGAIN); + if (!avpkt || !avpkt->size) { avctx->internal->draining = 1; - avpkt = NULL; - - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - return 0; + } else { + ret = av_packet_ref(avci->buffer_pkt, avpkt); + if (ret < 0) + return ret; } - if (avctx->codec->send_packet) { - if (avpkt) { - ret = apply_param_change(avctx, (AVPacket *)avpkt); - if (ret < 0) - return ret; - } - return avctx->codec->send_packet(avctx, avpkt); + if (!avci->buffer_frame->buf[0]) { + ret = decode_receive_frame_internal(avctx, avci->buffer_frame); + if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) + return ret; } - // Emulation via old API. Assume avpkt is likely not refcounted, while - // decoder output is always refcounted, and avoid copying. - - if (avctx->internal->buffer_pkt->size || avctx->internal->buffer_frame->buf[0]) - return AVERROR(EAGAIN); - - // The goal is decoding the first frame of the packet without using memcpy, - // because the common case is having only 1 frame per packet (especially - // with video, but audio too). In other cases, it can't be avoided, unless - // the user is feeding refcounted packets. - return do_decode(avctx, (AVPacket *)avpkt); + return 0; } int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame) { + AVCodecInternal *avci = avctx->internal; int ret; av_frame_unref(frame); @@ -262,157 +343,104 @@ int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *fr if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec)) return AVERROR(EINVAL); - if (avctx->codec->receive_frame) { - if (avctx->internal->draining && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - return AVERROR_EOF; - return avctx->codec->receive_frame(avctx, frame); - } - - // Emulation via old API. - - if (!avctx->internal->buffer_frame->buf[0]) { - if (!avctx->internal->buffer_pkt->size && !avctx->internal->draining) - return AVERROR(EAGAIN); - - while (1) { - if ((ret = do_decode(avctx, avctx->internal->buffer_pkt)) < 0) { - av_packet_unref(avctx->internal->buffer_pkt); - return ret; - } - // Some audio decoders may consume partial data without returning - // a frame (fate-wmapro-2ch). There is no way to make the caller - // call avcodec_receive_frame() again without returning a frame, - // so try to decode more in these cases. - if (avctx->internal->buffer_frame->buf[0] || - !avctx->internal->buffer_pkt->size) - break; - } + if (avci->buffer_frame->buf[0]) { + av_frame_move_ref(frame, avci->buffer_frame); + } else { + ret = decode_receive_frame_internal(avctx, frame); + if (ret < 0) + return ret; } - if (!avctx->internal->buffer_frame->buf[0]) - return avctx->internal->draining ? AVERROR_EOF : AVERROR(EAGAIN); + avctx->frame_number++; - av_frame_move_ref(frame, avctx->internal->buffer_frame); return 0; } -int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, - int *got_picture_ptr, - AVPacket *avpkt) +static int compat_decode(AVCodecContext *avctx, AVFrame *frame, + int *got_frame, AVPacket *pkt) { AVCodecInternal *avci = avctx->internal; int ret; - *got_picture_ptr = 0; - if ((avctx->coded_width || avctx->coded_height) && av_image_check_size(avctx->coded_width, avctx->coded_height, 0, avctx)) - return -1; + av_assert0(avci->compat_decode_consumed == 0); - if (!avctx->codec->decode) { - av_log(avctx, AV_LOG_ERROR, "This decoder requires using the avcodec_send_packet() API.\n"); - return AVERROR(ENOSYS); - } + *got_frame = 0; + avci->compat_decode = 1; - ret = extract_packet_props(avci, avpkt); - if (ret < 0) - return ret; + if (avci->compat_decode_partial_size > 0 && + avci->compat_decode_partial_size != pkt->size) { + av_log(avctx, AV_LOG_ERROR, + "Got unexpected packet size after a partial decode\n"); + ret = AVERROR(EINVAL); + goto finish; + } - ret = apply_param_change(avctx, avpkt); - if (ret < 0) - return ret; + if (!avci->compat_decode_partial_size) { + ret = avcodec_send_packet(avctx, pkt); + if (ret == AVERROR_EOF) + ret = 0; + else if (ret == AVERROR(EAGAIN)) { + /* we fully drain all the output in each decode call, so this should not + * ever happen */ + ret = AVERROR_BUG; + goto finish; + } else if (ret < 0) + goto finish; + } - av_frame_unref(picture); - - if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size || - (avctx->active_thread_type & FF_THREAD_FRAME)) { - if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) - ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr, - avpkt); - else { - ret = avctx->codec->decode(avctx, picture, got_picture_ptr, - avpkt); - if (!(avctx->codec->caps_internal & FF_CODEC_CAP_SETS_PKT_DTS)) - picture->pkt_dts = avpkt->dts; - /* get_buffer is supposed to set frame parameters */ - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DR1)) { - picture->sample_aspect_ratio = avctx->sample_aspect_ratio; - picture->width = avctx->width; - picture->height = avctx->height; - picture->format = avctx->pix_fmt; - } + while (ret >= 0) { + ret = avcodec_receive_frame(avctx, frame); + if (ret < 0) { + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + ret = 0; + goto finish; } - emms_c(); //needed to avoid an emms_c() call before every return; - - if (*got_picture_ptr) { + if (frame != avci->compat_decode_frame) { if (!avctx->refcounted_frames) { - int err = unrefcount_frame(avci, picture); - if (err < 0) - return err; + ret = unrefcount_frame(avci, frame); + if (ret < 0) + goto finish; } - avctx->frame_number++; - } else - av_frame_unref(picture); - } else - ret = 0; + *got_frame = 1; + frame = avci->compat_decode_frame; + } else { + if (!avci->compat_decode_warned) { + av_log(avctx, AV_LOG_WARNING, "The deprecated avcodec_decode_* " + "API cannot return all the frames for this decoder. " + "Some frames will be dropped. Update your code to the " + "new decoding API to fix this.\n"); + avci->compat_decode_warned = 1; + } + } -#if FF_API_AVCTX_TIMEBASE - if (avctx->framerate.num > 0 && avctx->framerate.den > 0) - avctx->time_base = av_inv_q(avctx->framerate); -#endif + if (avci->draining || avci->compat_decode_consumed < pkt->size) + break; + } + +finish: + if (ret == 0) + ret = FFMIN(avci->compat_decode_consumed, pkt->size); + avci->compat_decode_consumed = 0; + avci->compat_decode_partial_size = (ret >= 0) ? pkt->size - ret : 0; return ret; } +int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, + int *got_picture_ptr, + AVPacket *avpkt) +{ + return compat_decode(avctx, picture, got_picture_ptr, avpkt); +} + int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, AVPacket *avpkt) { - AVCodecInternal *avci = avctx->internal; - int ret = 0; - - *got_frame_ptr = 0; - - if (!avctx->codec->decode) { - av_log(avctx, AV_LOG_ERROR, "This decoder requires using the avcodec_send_packet() API.\n"); - return AVERROR(ENOSYS); - } - - ret = extract_packet_props(avci, avpkt); - if (ret < 0) - return ret; - - if (!avpkt->data && avpkt->size) { - av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n"); - return AVERROR(EINVAL); - } - - ret = apply_param_change(avctx, avpkt); - if (ret < 0) - return ret; - - av_frame_unref(frame); - - if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size) { - ret = avctx->codec->decode(avctx, frame, got_frame_ptr, avpkt); - if (ret >= 0 && *got_frame_ptr) { - avctx->frame_number++; - frame->pkt_dts = avpkt->dts; - if (frame->format == AV_SAMPLE_FMT_NONE) - frame->format = avctx->sample_fmt; - - if (!avctx->refcounted_frames) { - int err = unrefcount_frame(avci, frame); - if (err < 0) - return err; - } - } else - av_frame_unref(frame); - } - - - return ret; + return compat_decode(avctx, frame, got_frame_ptr, avpkt); } int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, @@ -919,9 +947,12 @@ void avcodec_flush_buffers(AVCodecContext *avctx) avctx->internal->draining = 0; avctx->internal->draining_done = 0; av_frame_unref(avctx->internal->buffer_frame); + av_frame_unref(avctx->internal->compat_decode_frame); av_packet_unref(avctx->internal->buffer_pkt); avctx->internal->buffer_pkt_valid = 0; + av_packet_unref(avctx->internal->ds.in_pkt); + if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) ff_thread_flush(avctx); else if (avctx->codec->flush) diff --git a/libavcodec/decode.h b/libavcodec/decode.h new file mode 100644 index 0000000000000..21c7c3e07ae15 --- /dev/null +++ b/libavcodec/decode.h @@ -0,0 +1,35 @@ +/* + * generic decoding-related code + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_DECODE_H +#define AVCODEC_DECODE_H + +/** + * Called by decoders to get the next packet for decoding. + * + * @param pkt An empty packet to be filled with data. + * @return 0 if a new reference has been successfully written to pkt + * AVERROR(EAGAIN) if no data is currently available + * AVERROR_EOF if and end of stream has been reached, so no more data + * will be available + */ +int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt); + +#endif /* AVCODEC_DECODE_H */ diff --git a/libavcodec/internal.h b/libavcodec/internal.h index 2ca7a45e811b8..dc24e8f764690 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -94,6 +94,11 @@ typedef struct FramePool { int samples; } FramePool; +typedef struct DecodeSimpleContext { + AVPacket *in_pkt; + AVFrame *out_frame; +} DecodeSimpleContext; + typedef struct AVCodecInternal { /** * Whether the parent AVCodecContext is a copy of the context which had @@ -130,6 +135,8 @@ typedef struct AVCodecInternal { void *thread_ctx; + DecodeSimpleContext ds; + /** * Properties (timestamps+side data) extracted from the last packet passed * for decoding. @@ -153,6 +160,16 @@ typedef struct AVCodecInternal { int buffer_pkt_valid; // encoding: packet without data can be valid AVFrame *buffer_frame; int draining_done; + /* set to 1 when the caller is using the old decoding API */ + int compat_decode; + int compat_decode_warned; + /* this variable is set by the decoder internals to signal to the old + * API compat wrappers the amount of data consumed from the last packet */ + size_t compat_decode_consumed; + /* when a partial packet has been consumed, this stores the remaining size + * of the packet (that should be submitted in the next decode call */ + size_t compat_decode_partial_size; + AVFrame *compat_decode_frame; } AVCodecInternal; struct AVCodecDefault { diff --git a/libavcodec/utils.c b/libavcodec/utils.c index b569b48f7a843..8a422d766922f 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -100,7 +100,7 @@ int av_codec_is_encoder(const AVCodec *codec) int av_codec_is_decoder(const AVCodec *codec) { - return codec && (codec->decode || codec->send_packet); + return codec && (codec->decode || codec->receive_frame); } av_cold void avcodec_register(AVCodec *codec) @@ -421,6 +421,12 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code goto free_and_end; } + avctx->internal->compat_decode_frame = av_frame_alloc(); + if (!avctx->internal->compat_decode_frame) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } + avctx->internal->buffer_frame = av_frame_alloc(); if (!avctx->internal->buffer_frame) { ret = AVERROR(ENOMEM); @@ -433,6 +439,12 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code goto free_and_end; } + avctx->internal->ds.in_pkt = av_packet_alloc(); + if (!avctx->internal->ds.in_pkt) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } + avctx->internal->last_pkt_props = av_packet_alloc(); if (!avctx->internal->last_pkt_props) { ret = AVERROR(ENOMEM); @@ -717,9 +729,13 @@ FF_ENABLE_DEPRECATION_WARNINGS av_freep(&avctx->priv_data); if (avctx->internal) { av_frame_free(&avctx->internal->to_free); + av_frame_free(&avctx->internal->compat_decode_frame); av_frame_free(&avctx->internal->buffer_frame); av_packet_free(&avctx->internal->buffer_pkt); av_packet_free(&avctx->internal->last_pkt_props); + + av_packet_free(&avctx->internal->ds.in_pkt); + av_freep(&avctx->internal->pool); } av_freep(&avctx->internal); @@ -758,9 +774,13 @@ av_cold int avcodec_close(AVCodecContext *avctx) if (avctx->codec && avctx->codec->close) avctx->codec->close(avctx); av_frame_free(&avctx->internal->to_free); + av_frame_free(&avctx->internal->compat_decode_frame); av_frame_free(&avctx->internal->buffer_frame); av_packet_free(&avctx->internal->buffer_pkt); av_packet_free(&avctx->internal->last_pkt_props); + + av_packet_free(&avctx->internal->ds.in_pkt); + for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++) av_buffer_pool_uninit(&pool->pools[i]); av_freep(&avctx->internal->pool); From 972c71e9cb63e24f57ee481e413199c7d88a8813 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 12 Nov 2016 17:43:55 +0100 Subject: [PATCH 0703/3374] lavc: add support for filtering packets before decoding --- configure | 1 + libavcodec/avcodec.h | 6 ++ libavcodec/decode.c | 163 ++++++++++++++++++++++++++++++++++++++---- libavcodec/decode.h | 2 + libavcodec/internal.h | 6 ++ libavcodec/utils.c | 3 + 6 files changed, 169 insertions(+), 12 deletions(-) diff --git a/configure b/configure index 6d809f7780e07..05047e9a15eaa 100755 --- a/configure +++ b/configure @@ -2467,6 +2467,7 @@ transcode_aac_example_deps="avcodec avformat avresample" # libraries, in linking order avcodec_deps="avutil" +avcodec_select="null_bsf" avdevice_deps="avformat avcodec avutil" avfilter_deps="avutil" avformat_deps="avcodec avutil" diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 1827711b50694..0997141e2c157 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3243,6 +3243,12 @@ typedef struct AVCodec { * See FF_CODEC_CAP_* in internal.h */ int caps_internal; + + /** + * Decoding only, a comma-separated list of bitstream filters to apply to + * packets before decoding. + */ + const char *bsfs; } AVCodec; /** diff --git a/libavcodec/decode.c b/libavcodec/decode.c index a1908ecf4b056..0fd41ab48219d 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -154,6 +154,116 @@ static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame) return 0; } +static int bsfs_init(AVCodecContext *avctx) +{ + AVCodecInternal *avci = avctx->internal; + DecodeFilterContext *s = &avci->filter; + const char *bsfs_str; + int ret; + + if (s->nb_bsfs) + return 0; + + bsfs_str = avctx->codec->bsfs ? avctx->codec->bsfs : "null"; + while (bsfs_str && *bsfs_str) { + AVBSFContext **tmp; + const AVBitStreamFilter *filter; + char *bsf; + + bsf = av_get_token(&bsfs_str, ","); + if (!bsf) { + ret = AVERROR(ENOMEM); + goto fail; + } + + filter = av_bsf_get_by_name(bsf); + if (!filter) { + av_log(avctx, AV_LOG_ERROR, "A non-existing bitstream filter %s " + "requested by a decoder. This is a bug, please report it.\n", + bsf); + ret = AVERROR_BUG; + av_freep(&bsf); + goto fail; + } + av_freep(&bsf); + + tmp = av_realloc_array(s->bsfs, s->nb_bsfs + 1, sizeof(*s->bsfs)); + if (!tmp) { + ret = AVERROR(ENOMEM); + goto fail; + } + s->bsfs = tmp; + s->nb_bsfs++; + + ret = av_bsf_alloc(filter, &s->bsfs[s->nb_bsfs - 1]); + if (ret < 0) + goto fail; + + if (s->nb_bsfs == 1) { + /* We do not currently have an API for passing the input timebase into decoders, + * but no filters used here should actually need it. + * So we make up some plausible-looking number (the MPEG 90kHz timebase) */ + s->bsfs[s->nb_bsfs - 1]->time_base_in = (AVRational){ 1, 90000 }; + ret = avcodec_parameters_from_context(s->bsfs[s->nb_bsfs - 1]->par_in, + avctx); + } else { + s->bsfs[s->nb_bsfs - 1]->time_base_in = s->bsfs[s->nb_bsfs - 2]->time_base_out; + ret = avcodec_parameters_copy(s->bsfs[s->nb_bsfs - 1]->par_in, + s->bsfs[s->nb_bsfs - 2]->par_out); + } + if (ret < 0) + goto fail; + + ret = av_bsf_init(s->bsfs[s->nb_bsfs - 1]); + if (ret < 0) + goto fail; + } + + return 0; +fail: + ff_decode_bsfs_uninit(avctx); + return ret; +} + +/* try to get one output packet from the filter chain */ +static int bsfs_poll(AVCodecContext *avctx, AVPacket *pkt) +{ + DecodeFilterContext *s = &avctx->internal->filter; + int idx, ret; + + /* start with the last filter in the chain */ + idx = s->nb_bsfs - 1; + while (idx >= 0) { + /* request a packet from the currently selected filter */ + ret = av_bsf_receive_packet(s->bsfs[idx], pkt); + if (ret == AVERROR(EAGAIN)) { + /* no packets available, try the next filter up the chain */ + ret = 0; + idx--; + continue; + } else if (ret < 0 && ret != AVERROR_EOF) { + return ret; + } + + /* got a packet or EOF -- pass it to the caller or to the next filter + * down the chain */ + if (idx == s->nb_bsfs - 1) { + return ret; + } else { + idx++; + ret = av_bsf_send_packet(s->bsfs[idx], ret < 0 ? NULL : pkt); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, + "Error pre-processing a packet before decoding\n"); + av_packet_unref(pkt); + return ret; + } + } + } + + return AVERROR(EAGAIN); +} + int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt) { AVCodecInternal *avci = avctx->internal; @@ -162,10 +272,11 @@ int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt) if (avci->draining) return AVERROR_EOF; - if (!avci->buffer_pkt->data && !avci->buffer_pkt->side_data_elems) - return AVERROR(EAGAIN); - - av_packet_move_ref(pkt, avci->buffer_pkt); + ret = bsfs_poll(avctx, pkt); + if (ret == AVERROR_EOF) + avci->draining = 1; + if (ret < 0) + return ret; ret = extract_packet_props(avctx->internal, pkt); if (ret < 0) @@ -313,17 +424,23 @@ int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacke if (avctx->internal->draining) return AVERROR_EOF; - if (avci->buffer_pkt->data || avci->buffer_pkt->side_data_elems) - return AVERROR(EAGAIN); + ret = bsfs_init(avctx); + if (ret < 0) + return ret; - if (!avpkt || !avpkt->size) { - avctx->internal->draining = 1; - } else { + av_packet_unref(avci->buffer_pkt); + if (avpkt && (avpkt->data || avpkt->side_data_elems)) { ret = av_packet_ref(avci->buffer_pkt, avpkt); if (ret < 0) return ret; } + ret = av_bsf_send_packet(avci->filter.bsfs[0], avci->buffer_pkt); + if (ret < 0) { + av_packet_unref(avci->buffer_pkt); + return ret; + } + if (!avci->buffer_frame->buf[0]) { ret = decode_receive_frame_internal(avctx, avci->buffer_frame); if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) @@ -343,6 +460,10 @@ int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *fr if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec)) return AVERROR(EINVAL); + ret = bsfs_init(avctx); + if (ret < 0) + return ret; + if (avci->buffer_frame->buf[0]) { av_frame_move_ref(frame, avci->buffer_frame); } else { @@ -415,13 +536,18 @@ static int compat_decode(AVCodecContext *avctx, AVFrame *frame, } } - if (avci->draining || avci->compat_decode_consumed < pkt->size) + if (avci->draining || (!avctx->codec->bsfs && avci->compat_decode_consumed < pkt->size)) break; } finish: - if (ret == 0) - ret = FFMIN(avci->compat_decode_consumed, pkt->size); + if (ret == 0) { + /* if there are any bsfs then assume full packet is always consumed */ + if (avctx->codec->bsfs) + ret = pkt->size; + else + ret = FFMIN(avci->compat_decode_consumed, pkt->size); + } avci->compat_decode_consumed = 0; avci->compat_decode_partial_size = (ret >= 0) ? pkt->size - ret : 0; @@ -958,6 +1084,19 @@ void avcodec_flush_buffers(AVCodecContext *avctx) else if (avctx->codec->flush) avctx->codec->flush(avctx); + ff_decode_bsfs_uninit(avctx); + if (!avctx->refcounted_frames) av_frame_unref(avctx->internal->to_free); } + +void ff_decode_bsfs_uninit(AVCodecContext *avctx) +{ + DecodeFilterContext *s = &avctx->internal->filter; + int i; + + for (i = 0; i < s->nb_bsfs; i++) + av_bsf_free(&s->bsfs[i]); + av_freep(&s->bsfs); + s->nb_bsfs = 0; +} diff --git a/libavcodec/decode.h b/libavcodec/decode.h index 21c7c3e07ae15..c1e6457f77e0f 100644 --- a/libavcodec/decode.h +++ b/libavcodec/decode.h @@ -32,4 +32,6 @@ */ int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt); +void ff_decode_bsfs_uninit(AVCodecContext *avctx); + #endif /* AVCODEC_DECODE_H */ diff --git a/libavcodec/internal.h b/libavcodec/internal.h index dc24e8f764690..796d45ff6ebf8 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -99,6 +99,11 @@ typedef struct DecodeSimpleContext { AVFrame *out_frame; } DecodeSimpleContext; +typedef struct DecodeFilterContext { + AVBSFContext **bsfs; + int nb_bsfs; +} DecodeFilterContext; + typedef struct AVCodecInternal { /** * Whether the parent AVCodecContext is a copy of the context which had @@ -136,6 +141,7 @@ typedef struct AVCodecInternal { void *thread_ctx; DecodeSimpleContext ds; + DecodeFilterContext filter; /** * Properties (timestamps+side data) extracted from the last packet passed diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 8a422d766922f..2978109a23d41 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -40,6 +40,7 @@ #include "libavutil/samplefmt.h" #include "libavutil/dict.h" #include "avcodec.h" +#include "decode.h" #include "libavutil/opt.h" #include "me_cmp.h" #include "mpegvideo.h" @@ -789,6 +790,8 @@ av_cold int avcodec_close(AVCodecContext *avctx) avctx->hwaccel->uninit(avctx); av_freep(&avctx->internal->hwaccel_priv_data); + ff_decode_bsfs_uninit(avctx); + av_freep(&avctx->internal); } From 8fb4210ad8785c01fccf2fc59af6a6fa2892b6b2 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 13 Nov 2016 09:09:06 +0100 Subject: [PATCH 0704/3374] qsvdec_h2645: switch to the new generic filtering mechanism Drop the internal manual conversion from the MP4 format to Annex B. --- libavcodec/qsvdec_h2645.c | 74 ++++++--------------------------------- 1 file changed, 11 insertions(+), 63 deletions(-) diff --git a/libavcodec/qsvdec_h2645.c b/libavcodec/qsvdec_h2645.c index 34b12cb0dbb07..6624fbecc77f3 100644 --- a/libavcodec/qsvdec_h2645.c +++ b/libavcodec/qsvdec_h2645.c @@ -49,12 +49,9 @@ typedef struct QSVH2645Context { int load_plugin; - // the filter for converting to Annex B - AVBSFContext *bsf; - AVFifoBuffer *packet_fifo; - AVPacket pkt_filtered; + AVPacket buffer_pkt; } QSVH2645Context; static void qsv_clear_buffers(QSVH2645Context *s) @@ -65,9 +62,7 @@ static void qsv_clear_buffers(QSVH2645Context *s) av_packet_unref(&pkt); } - av_bsf_free(&s->bsf); - - av_packet_unref(&s->pkt_filtered); + av_packet_unref(&s->buffer_pkt); } static av_cold int qsv_decode_close(AVCodecContext *avctx) @@ -120,37 +115,6 @@ static av_cold int qsv_decode_init(AVCodecContext *avctx) return ret; } -static int qsv_init_bsf(AVCodecContext *avctx, QSVH2645Context *s) -{ - const char *filter_name = avctx->codec_id == AV_CODEC_ID_HEVC ? - "hevc_mp4toannexb" : "h264_mp4toannexb"; - const AVBitStreamFilter *filter; - int ret; - - if (s->bsf) - return 0; - - filter = av_bsf_get_by_name(filter_name); - if (!filter) - return AVERROR_BUG; - - ret = av_bsf_alloc(filter, &s->bsf); - if (ret < 0) - return ret; - - ret = avcodec_parameters_from_context(s->bsf->par_in, avctx); - if (ret < 0) - return ret; - - s->bsf->time_base_in = avctx->time_base; - - ret = av_bsf_init(s->bsf); - if (ret < 0) - return ret; - - return ret; -} - static int qsv_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { @@ -158,11 +122,6 @@ static int qsv_decode_frame(AVCodecContext *avctx, void *data, AVFrame *frame = data; int ret; - /* make sure the bitstream filter is initialized */ - ret = qsv_init_bsf(avctx, s); - if (ret < 0) - return ret; - /* buffer the input packet */ if (avpkt->size) { AVPacket input_ref = { 0 }; @@ -182,36 +141,23 @@ static int qsv_decode_frame(AVCodecContext *avctx, void *data, /* process buffered data */ while (!*got_frame) { - /* prepare the input data -- convert to Annex B if needed */ - if (s->pkt_filtered.size <= 0) { - AVPacket input_ref; - + /* prepare the input data */ + if (s->buffer_pkt.size <= 0) { /* no more data */ if (av_fifo_size(s->packet_fifo) < sizeof(AVPacket)) return avpkt->size ? avpkt->size : ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, avpkt); - av_packet_unref(&s->pkt_filtered); - - av_fifo_generic_read(s->packet_fifo, &input_ref, sizeof(input_ref), NULL); - ret = av_bsf_send_packet(s->bsf, &input_ref); - if (ret < 0) { - av_packet_unref(&input_ref); - return ret; - } + av_packet_unref(&s->buffer_pkt); - ret = av_bsf_receive_packet(s->bsf, &s->pkt_filtered); - if (ret < 0) - av_packet_move_ref(&s->pkt_filtered, &input_ref); - else - av_packet_unref(&input_ref); + av_fifo_generic_read(s->packet_fifo, &s->buffer_pkt, sizeof(s->buffer_pkt), NULL); } - ret = ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, &s->pkt_filtered); + ret = ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, &s->buffer_pkt); if (ret < 0) return ret; - s->pkt_filtered.size -= ret; - s->pkt_filtered.data += ret; + s->buffer_pkt.size -= ret; + s->buffer_pkt.data += ret; } return avpkt->size; @@ -274,6 +220,7 @@ AVCodec ff_hevc_qsv_decoder = { AV_PIX_FMT_P010, AV_PIX_FMT_QSV, AV_PIX_FMT_NONE }, + .bsfs = "hevc_mp4toannexb", }; #endif @@ -315,5 +262,6 @@ AVCodec ff_h264_qsv_decoder = { AV_PIX_FMT_P010, AV_PIX_FMT_QSV, AV_PIX_FMT_NONE }, + .bsfs = "h264_mp4toannexb", }; #endif From 03a80925effc2698d21dc0b00290eecf42dd9e68 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 13 Nov 2016 11:00:02 +0100 Subject: [PATCH 0705/3374] lavc: add a bitstream filter for splitting VP9 superframes Partially based on code by Ronald S. Bultje . --- doc/bitstream_filters.texi | 4 + libavcodec/Makefile | 1 + libavcodec/bitstream_filters.c | 1 + libavcodec/vp9_superframe_split_bsf.c | 146 ++++++++++++++++++++++++++ 4 files changed, 152 insertions(+) create mode 100644 libavcodec/vp9_superframe_split_bsf.c diff --git a/doc/bitstream_filters.texi b/doc/bitstream_filters.texi index 2e13cbe180f15..49b8a645d0bb6 100644 --- a/doc/bitstream_filters.texi +++ b/doc/bitstream_filters.texi @@ -95,4 +95,8 @@ This bitstream filter passes the packets through unchanged. @section remove_extradata +@section vp9_superframe_split + +Split VP9 superframes into single frames. + @c man end BITSTREAM FILTERS diff --git a/libavcodec/Makefile b/libavcodec/Makefile index d571d8def3411..f07253a84db3c 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -767,6 +767,7 @@ OBJS-$(CONFIG_NOISE_BSF) += noise_bsf.o OBJS-$(CONFIG_NULL_BSF) += null_bsf.o OBJS-$(CONFIG_REMOVE_EXTRADATA_BSF) += remove_extradata_bsf.o OBJS-$(CONFIG_TEXT2MOVSUB_BSF) += movsub_bsf.o +OBJS-$(CONFIG_VP9_SUPERFRAME_SPLIT_BSF) += vp9_superframe_split_bsf.o # thread libraries OBJS-$(HAVE_LIBC_MSVCRT) += file_open.o diff --git a/libavcodec/bitstream_filters.c b/libavcodec/bitstream_filters.c index ee9e4bade5d08..1cea6d77afe9a 100644 --- a/libavcodec/bitstream_filters.c +++ b/libavcodec/bitstream_filters.c @@ -38,6 +38,7 @@ extern const AVBitStreamFilter ff_null_bsf; extern const AVBitStreamFilter ff_text2movsub_bsf; extern const AVBitStreamFilter ff_noise_bsf; extern const AVBitStreamFilter ff_remove_extradata_bsf; +extern const AVBitStreamFilter ff_vp9_superframe_split_bsf; #include "libavcodec/bsf_list.c" diff --git a/libavcodec/vp9_superframe_split_bsf.c b/libavcodec/vp9_superframe_split_bsf.c new file mode 100644 index 0000000000000..4e635a307027c --- /dev/null +++ b/libavcodec/vp9_superframe_split_bsf.c @@ -0,0 +1,146 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * This bitstream filter splits VP9 superframes into packets containing + * just one frame. + */ + +#include + +#include "avcodec.h" +#include "bsf.h" +#include "bitstream.h" +#include "bytestream.h" + +typedef struct VP9SFSplitContext { + AVPacket *buffer_pkt; + + int nb_frames; + int next_frame; + size_t next_frame_offset; + int sizes[8]; +} VP9SFSplitContext; + +static int vp9_superframe_split_filter(AVBSFContext *ctx, AVPacket *out) +{ + VP9SFSplitContext *s = ctx->priv_data; + AVPacket *in; + int i, j, ret, marker; + int is_superframe = !!s->buffer_pkt; + + if (!s->buffer_pkt) { + ret = ff_bsf_get_packet(ctx, &s->buffer_pkt); + if (ret < 0) + return ret; + in = s->buffer_pkt; + + marker = in->data[in->size - 1]; + if ((marker & 0xe0) == 0xc0) { + int length_size = 1 + ((marker >> 3) & 0x3); + int nb_frames = 1 + (marker & 0x7); + int idx_size = 2 + nb_frames * length_size; + + if (in->size >= idx_size && in->data[in->size - idx_size] == marker) { + GetByteContext bc; + int total_size = 0; + + bytestream2_init(&bc, in->data + in->size + 1 - idx_size, + nb_frames * length_size); + + for (i = 0; i < nb_frames; i++) { + int frame_size = 0; + for (j = 0; j < length_size; j++) + frame_size |= bytestream2_get_byte(&bc) << (j * 8); + + total_size += frame_size; + if (total_size > in->size - idx_size) { + av_log(ctx, AV_LOG_ERROR, + "Invalid frame size in a superframe: %d\n", frame_size); + ret = AVERROR(EINVAL); + goto fail; + } + s->sizes[i] = frame_size; + } + s->nb_frames = nb_frames; + s->next_frame = 0; + s->next_frame_offset = 0; + is_superframe = 1; + } + } + } + + if (is_superframe) { + BitstreamContext bc; + int profile, invisible = 0; + + ret = av_packet_ref(out, s->buffer_pkt); + if (ret < 0) + goto fail; + + out->data += s->next_frame_offset; + out->size = s->sizes[s->next_frame]; + + s->next_frame_offset += out->size; + s->next_frame++; + + if (s->next_frame >= s->nb_frames) + av_packet_free(&s->buffer_pkt); + + ret = bitstream_init8(&bc, out->data, out->size); + if (ret < 0) + goto fail; + + bitstream_read(&bc, 2); // frame_marker + profile = bitstream_read(&bc, 1); + profile |= bitstream_read(&bc, 1) << 1; + if (profile == 3) + bitstream_read(&bc, 1); + if (!bitstream_read(&bc, 1)) { + bitstream_read(&bc, 1); + invisible = !bitstream_read(&bc, 1); + } + + if (invisible) + out->pts = AV_NOPTS_VALUE; + + } else { + av_packet_move_ref(out, s->buffer_pkt); + av_packet_free(&s->buffer_pkt); + } + + return 0; +fail: + av_packet_free(&s->buffer_pkt); + return ret; +} + +static void vp9_superframe_split_uninit(AVBSFContext *ctx) +{ + VP9SFSplitContext *s = ctx->priv_data; + av_packet_free(&s->buffer_pkt); +} + +const AVBitStreamFilter ff_vp9_superframe_split_bsf = { + .name = "vp9_superframe_split", + .priv_data_size = sizeof(VP9SFSplitContext), + .close = vp9_superframe_split_uninit, + .filter = vp9_superframe_split_filter, + .codec_ids = (const enum AVCodecID []){ AV_CODEC_ID_VP9, AV_CODEC_ID_NONE }, +}; From fa1749dd34c55fb997c97dfc4da9383c9976ab91 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 13 Nov 2016 11:24:16 +0100 Subject: [PATCH 0706/3374] vp9: split superframes in the filtering stage before actual decoding Significantly increases the efficiency of frame threading, since individual frames in a superframe can now be decoded in parallel. --- configure | 2 +- libavcodec/vp9.c | 74 +++++++++--------------------------------------- 2 files changed, 14 insertions(+), 62 deletions(-) diff --git a/configure b/configure index 05047e9a15eaa..fb82fc4d47461 100755 --- a/configure +++ b/configure @@ -2105,7 +2105,7 @@ vp6a_decoder_select="vp6_decoder" vp6f_decoder_select="vp6_decoder" vp7_decoder_select="h264pred videodsp vp8dsp" vp8_decoder_select="h264pred videodsp vp8dsp" -vp9_decoder_select="videodsp" +vp9_decoder_select="videodsp vp9_superframe_split_bsf" webp_decoder_select="vp8_decoder" wmapro_decoder_select="mdct sinewin wma_freqs" wmav1_decoder_select="mdct sinewin wma_freqs" diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 906218565ebf0..48f8afe9ca652 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -1188,14 +1188,18 @@ static int update_refs(AVCodecContext *avctx) return 0; } -static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, - int *got_frame, const uint8_t *data, int size, - int can_finish_setup) +static int vp9_decode_frame(AVCodecContext *avctx, void *output, + int *got_frame, AVPacket *pkt) { VP9Context *s = avctx->priv_data; + AVFrame *frame = output; + const uint8_t *data = pkt->data; + int size = pkt->size; AVFrame *f; int ret, tile_row, tile_col, i, ref = -1, row, col; + s->setup_finished = 0; + ret = decode_frame_header(avctx, data, size, &ref); if (ret < 0) { return ret; @@ -1210,7 +1214,7 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, if (ret < 0) return ret; *got_frame = 1; - return 0; + return pkt->size; } data += ret; size -= ret; @@ -1261,7 +1265,7 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, s->prob_ctx[s->framectxid].p = s->prob.p; } if ((s->parallelmode || !s->refreshctx) && - can_finish_setup && avctx->active_thread_type & FF_THREAD_FRAME) { + avctx->active_thread_type & FF_THREAD_FRAME) { ff_thread_finish_setup(avctx); s->setup_finished = 1; } @@ -1402,7 +1406,7 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, if (s->pass < 2 && s->refreshctx && !s->parallelmode) { ff_vp9_adapt_probs(s); - if (can_finish_setup && avctx->active_thread_type & FF_THREAD_FRAME) { + if (avctx->active_thread_type & FF_THREAD_FRAME) { ff_thread_finish_setup(avctx); s->setup_finished = 1; } @@ -1428,60 +1432,7 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, *got_frame = 1; } - return 0; -} - -static int vp9_decode_packet(AVCodecContext *avctx, void *frame, - int *got_frame, AVPacket *avpkt) -{ - VP9Context *s = avctx->priv_data; - const uint8_t *data = avpkt->data; - int size = avpkt->size; - int marker, ret; - - s->setup_finished = 0; - - /* Read superframe index - this is a collection of individual frames - * that together lead to one visible frame */ - marker = data[size - 1]; - if ((marker & 0xe0) == 0xc0) { - int nbytes = 1 + ((marker >> 3) & 0x3); - int n_frames = 1 + (marker & 0x7); - int idx_sz = 2 + n_frames * nbytes; - - if (size >= idx_sz && data[size - idx_sz] == marker) { - const uint8_t *idx = data + size + 1 - idx_sz; - - while (n_frames--) { - unsigned sz = AV_RL32(idx); - - if (nbytes < 4) - sz &= (1 << (8 * nbytes)) - 1; - idx += nbytes; - - if (sz > size) { - av_log(avctx, AV_LOG_ERROR, - "Superframe packet size too big: %u > %d\n", - sz, size); - return AVERROR_INVALIDDATA; - } - - ret = vp9_decode_frame(avctx, frame, got_frame, data, sz, - !n_frames); - if (ret < 0) - return ret; - data += sz; - size -= sz; - } - return avpkt->size; - } - } - - /* If we get here, there was no valid superframe index, i.e. this is just - * one whole single frame. Decode it as such from the complete input buf. */ - if ((ret = vp9_decode_frame(avctx, frame, got_frame, data, size, 1)) < 0) - return ret; - return size; + return pkt->size; } static av_cold int vp9_decode_free(AVCodecContext *avctx) @@ -1590,10 +1541,11 @@ AVCodec ff_vp9_decoder = { .id = AV_CODEC_ID_VP9, .priv_data_size = sizeof(VP9Context), .init = vp9_decode_init, - .decode = vp9_decode_packet, + .decode = vp9_decode_frame, .flush = vp9_decode_flush, .close = vp9_decode_free, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, .init_thread_copy = vp9_decode_init, .update_thread_context = vp9_decode_update_thread_context, + .bsfs = "vp9_superframe_split", }; From 730c02326094bcfb1fa67f10a7e7b22f03f5a88f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 24 Nov 2016 23:05:20 +0100 Subject: [PATCH 0707/3374] binkaudio: switch to the new send/receive API It is more natural for this codec and allows to avoid awkward constructs like "consuming 0 bytes from input". Also, keep a reference to the input packet to avoid unnecessary copying. --- libavcodec/binkaudio.c | 58 +++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c index cf61135529a84..51fb6c83cee0c 100644 --- a/libavcodec/binkaudio.c +++ b/libavcodec/binkaudio.c @@ -35,6 +35,7 @@ #include "avcodec.h" #include "bitstream.h" #include "dct.h" +#include "decode.h" #include "internal.h" #include "rdft.h" #include "wma_freqs.h" @@ -57,7 +58,7 @@ typedef struct BinkAudioContext { float root; DECLARE_ALIGNED(32, FFTSample, coeffs)[BINK_BLOCK_MAX_SIZE]; float previous[MAX_CHANNELS][BINK_BLOCK_MAX_SIZE / 16]; ///< coeffs from previous audio block - uint8_t *packet_buffer; + AVPacket *pkt; union { RDFTContext rdft; DCTContext dct; @@ -140,6 +141,10 @@ static av_cold int decode_init(AVCodecContext *avctx) else return -1; + s->pkt = av_packet_alloc(); + if (!s->pkt) + return AVERROR(ENOMEM); + return 0; } @@ -269,12 +274,13 @@ static av_cold int decode_end(AVCodecContext *avctx) { BinkAudioContext * s = avctx->priv_data; av_freep(&s->bands); - av_freep(&s->packet_buffer); if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT) ff_rdft_end(&s->trans.rdft); else if (CONFIG_BINKAUDIO_DCT_DECODER) ff_dct_end(&s->trans.dct); + av_packet_free(&s->pkt); + return 0; } @@ -285,32 +291,26 @@ static void get_bits_align32(BitstreamContext *s) bitstream_skip(s, n); } -static int decode_frame(AVCodecContext *avctx, void *data, - int *got_frame_ptr, AVPacket *avpkt) +static int binkaudio_receive_frame(AVCodecContext *avctx, AVFrame *frame) { BinkAudioContext *s = avctx->priv_data; - AVFrame *frame = data; BitstreamContext *bc = &s->bc; - int ret, consumed = 0; + int ret; - if (!bitstream_bits_left(bc)) { - uint8_t *buf; - /* handle end-of-stream */ - if (!avpkt->size) { - *got_frame_ptr = 0; - return 0; - } - if (avpkt->size < 4) { + if (!s->pkt->data) { + ret = ff_decode_get_packet(avctx, s->pkt); + if (ret < 0) + return ret; + + if (s->pkt->size < 4) { av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } - buf = av_realloc(s->packet_buffer, avpkt->size + AV_INPUT_BUFFER_PADDING_SIZE); - if (!buf) - return AVERROR(ENOMEM); - s->packet_buffer = buf; - memcpy(s->packet_buffer, avpkt->data, avpkt->size); - bitstream_init(bc, s->packet_buffer, avpkt->size * 8); - consumed = avpkt->size; + + ret = bitstream_init8(bc, s->pkt->data, s->pkt->size); + if (ret < 0) + goto fail; /* skip reported size */ bitstream_skip(bc, 32); @@ -329,11 +329,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } get_bits_align32(bc); + if (!bitstream_bits_left(bc)) { + memset(bc, 0, sizeof(*bc)); + av_packet_unref(s->pkt); + } frame->nb_samples = s->block_size / avctx->channels; - *got_frame_ptr = 1; - return consumed; + return 0; +fail: + av_packet_unref(s->pkt); + return ret; } AVCodec ff_binkaudio_rdft_decoder = { @@ -344,7 +350,7 @@ AVCodec ff_binkaudio_rdft_decoder = { .priv_data_size = sizeof(BinkAudioContext), .init = decode_init, .close = decode_end, - .decode = decode_frame, + .receive_frame = binkaudio_receive_frame, .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1, }; @@ -356,6 +362,6 @@ AVCodec ff_binkaudio_dct_decoder = { .priv_data_size = sizeof(BinkAudioContext), .init = decode_init, .close = decode_end, - .decode = decode_frame, + .receive_frame = binkaudio_receive_frame, .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1, }; From 86157e6db2c7a9222f77fa7e7f50fb9aebc3aa81 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 2 Oct 2016 15:39:10 +0200 Subject: [PATCH 0708/3374] hevc: decouple calling get_format() from exporting the SPS parameters This makes sure ff_get_format() does not get called unnecessarily from update_thread_context(). --- libavcodec/hevcdec.c | 49 +++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 9dd86c289e669..27fd6832ab2e3 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -380,24 +380,10 @@ static void export_stream_params(AVCodecContext *avctx, const HEVCParamSets *ps, num, den, 1 << 30); } -static int set_sps(HEVCContext *s, const HEVCSPS *sps) +static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) { #define HWACCEL_MAX (CONFIG_HEVC_DXVA2_HWACCEL + CONFIG_HEVC_D3D11VA_HWACCEL + CONFIG_HEVC_VDPAU_HWACCEL) enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmt = pix_fmts; - int ret; - - pic_arrays_free(s); - s->ps.sps = NULL; - s->ps.vps = NULL; - - if (!sps) - return 0; - - ret = pic_arrays_init(s, sps); - if (ret < 0) - goto fail; - - export_stream_params(s->avctx, &s->ps, sps); if (sps->pix_fmt == AV_PIX_FMT_YUV420P || sps->pix_fmt == AV_PIX_FMT_YUVJ420P || sps->pix_fmt == AV_PIX_FMT_YUV420P10) { @@ -417,10 +403,28 @@ static int set_sps(HEVCContext *s, const HEVCSPS *sps) *fmt++ = sps->pix_fmt; *fmt = AV_PIX_FMT_NONE; - ret = ff_get_format(s->avctx, pix_fmts); + return ff_get_format(s->avctx, pix_fmts); +} + +static int set_sps(HEVCContext *s, const HEVCSPS *sps, + enum AVPixelFormat pix_fmt) +{ + int ret; + + pic_arrays_free(s); + s->ps.sps = NULL; + s->ps.vps = NULL; + + if (!sps) + return 0; + + ret = pic_arrays_init(s, sps); if (ret < 0) goto fail; - s->avctx->pix_fmt = ret; + + export_stream_params(s->avctx, &s->ps, sps); + + s->avctx->pix_fmt = pix_fmt; ff_hevc_pred_init(&s->hpc, sps->bit_depth); ff_hevc_dsp_init (&s->hevcdsp, sps->bit_depth); @@ -475,10 +479,17 @@ static int hls_slice_header(HEVCContext *s) s->ps.pps = (HEVCPPS*)s->ps.pps_list[sh->pps_id]->data; if (s->ps.sps != (HEVCSPS*)s->ps.sps_list[s->ps.pps->sps_id]->data) { + enum AVPixelFormat pix_fmt; + s->ps.sps = (HEVCSPS*)s->ps.sps_list[s->ps.pps->sps_id]->data; ff_hevc_clear_refs(s); - ret = set_sps(s, s->ps.sps); + + pix_fmt = get_format(s, s->ps.sps); + if (pix_fmt < 0) + return pix_fmt; + + ret = set_sps(s, s->ps.sps, pix_fmt); if (ret < 0) return ret; @@ -2985,7 +2996,7 @@ static int hevc_update_thread_context(AVCodecContext *dst, } if (s->ps.sps != s0->ps.sps) - ret = set_sps(s, s0->ps.sps); + ret = set_sps(s, s0->ps.sps, src->pix_fmt); s->seq_decode = s0->seq_decode; s->seq_output = s0->seq_output; From 5c7f2cf81df06614f255f061850132355a01d75e Mon Sep 17 00:00:00 2001 From: Derek Buitenhuis Date: Mon, 12 Dec 2016 14:33:27 +0000 Subject: [PATCH 0709/3374] h264_slice: Wait for refs to be available before we use them in error concealment This could happen when there was a frame number gap and frame threading was used. Debugging-by: Ronald S. Bultje Debugging-by: Justin Ruggles Signed-off-by: Derek Buitenhuis CC:libav-stable@libav.org Signed-off-by: Anton Khirnov --- libavcodec/h264_slice.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 8d79740a7f5cf..1b91088f52fff 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1404,6 +1404,9 @@ static int h264_field_start(H264Context *h, const H264SliceContext *sl, h->short_ref[0]->f->width == prev->f->width && h->short_ref[0]->f->height == prev->f->height && h->short_ref[0]->f->format == prev->f->format) { + ff_thread_await_progress(&prev->tf, INT_MAX, 0); + if (prev->field_picture) + ff_thread_await_progress(&prev->tf, INT_MAX, 1); av_image_copy(h->short_ref[0]->f->data, h->short_ref[0]->f->linesize, (const uint8_t **)prev->f->data, From e94b9313b21c3d91a36ef064f7fe3e867616f47f Mon Sep 17 00:00:00 2001 From: Derek Buitenhuis Date: Mon, 12 Dec 2016 14:33:28 +0000 Subject: [PATCH 0710/3374] fate: Add h264 test for frame num gaps Signed-off-by: Derek Buitenhuis Signed-off-by: Anton Khirnov --- tests/fate/h264.mak | 2 ++ tests/ref/fate/h264-missing-frame | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 tests/ref/fate/h264-missing-frame diff --git a/tests/fate/h264.mak b/tests/fate/h264.mak index 635abcd7b900a..3d6fde7bdb732 100644 --- a/tests/fate/h264.mak +++ b/tests/fate/h264.mak @@ -182,6 +182,7 @@ FATE_H264 := $(FATE_H264:%=fate-h264-conformance-%) \ fate-h264-extreme-plane-pred \ fate-h264-intra-refresh-recovery \ fate-h264-lossless \ + fate-h264-missing-frame \ FATE_H264-$(call DEMDEC, H264, H264) += $(FATE_H264) FATE_H264-$(call DEMDEC, MOV, H264) += fate-h264-crop-to-container @@ -397,5 +398,6 @@ fate-h264-lossless: CMD = framecrc -i $(TARGET_SAM fate-h264-mixed-nal-coding: CMD = framecrc -i $(TARGET_SAMPLES)/h264/mixed-nal-coding.mp4 fate-h264-twofields-packet: CMD = framecrc -i $(TARGET_SAMPLES)/h264/twofields_packet.mp4 -an -frames 30 fate-h264-unescaped-extradata: CMD = framecrc -i $(TARGET_SAMPLES)/h264/unescaped_extradata.mp4 -an -frames 10 +fate-h264-missing-frame: CMD = framecrc -i $(TARGET_SAMPLES)/h264/nondeterministic_cut.h264 fate-h264-reinit-%: CMD = framecrc -i $(TARGET_SAMPLES)/h264/$(@:fate-h264-%=%).h264 -vf format=yuv444p10le,scale=w=352:h=288 diff --git a/tests/ref/fate/h264-missing-frame b/tests/ref/fate/h264-missing-frame new file mode 100644 index 0000000000000..61c5f2fab56b8 --- /dev/null +++ b/tests/ref/fate/h264-missing-frame @@ -0,0 +1,31 @@ +#tb 0: 1/25 +0, 0, 0, 1, 2332800, 0x009dacb8 +0, 1, 1, 1, 2332800, 0xb1e50764 +0, 2, 2, 1, 2332800, 0xe29481e0 +0, 3, 3, 1, 2332800, 0x0b1b4de4 +0, 4, 4, 1, 2332800, 0x726a644c +0, 5, 5, 1, 2332800, 0x7a09c4a5 +0, 6, 6, 1, 2332800, 0x2e9059ea +0, 7, 7, 1, 2332800, 0x52071fdc +0, 8, 8, 1, 2332800, 0x4fa00417 +0, 9, 9, 1, 2332800, 0x6037fb4d +0, 10, 10, 1, 2332800, 0x887ffae2 +0, 11, 11, 1, 2332800, 0x887ffae2 +0, 12, 12, 1, 2332800, 0x887ffae2 +0, 13, 13, 1, 2332800, 0x887ffae2 +0, 14, 14, 1, 2332800, 0x887ffae2 +0, 15, 15, 1, 2332800, 0x887ffae2 +0, 16, 16, 1, 2332800, 0x887ffae2 +0, 17, 17, 1, 2332800, 0x887ffae2 +0, 18, 18, 1, 2332800, 0x887ffae2 +0, 19, 19, 1, 2332800, 0x887ffae2 +0, 20, 20, 1, 2332800, 0x887ffae2 +0, 21, 21, 1, 2332800, 0x887ffae2 +0, 22, 22, 1, 2332800, 0x887ffae2 +0, 23, 23, 1, 2332800, 0x887ffae2 +0, 24, 24, 1, 2332800, 0x887ffae2 +0, 25, 25, 1, 2332800, 0x887ffae2 +0, 26, 26, 1, 2332800, 0x887ffae2 +0, 27, 27, 1, 2332800, 0x887ffae2 +0, 28, 28, 1, 2332800, 0x887ffae2 +0, 29, 29, 1, 2332800, 0x824bb91b From 343e2833994655c252d5236a3394bf6db7a4d8b1 Mon Sep 17 00:00:00 2001 From: Wan-Teh Chang Date: Fri, 9 Dec 2016 09:54:47 -0800 Subject: [PATCH 0711/3374] pthread_frame: use better memory orders for frame progress This improves commit 59c70227405c214b29971e6272f3a3ff6fcce3d0. In ff_thread_report_progress(), the fast code path can load progress[field] with the relaxed memory order, and the slow code path can store progress[field] with the release memory order. These changes are mainly intended to avoid confusion when one inspects the source code. They are unlikely to have measurable performance improvement. ff_thread_report_progress() and ff_thread_await_progress() form a pair. ff_thread_await_progress() reads progress[field] with the acquire memory order (in the fast code path). Therefore, one expects to see ff_thread_report_progress() write progress[field] with the matching release memory order. In the fast code path in ff_thread_report_progress(), the atomic load of progress[field] doesn't need the acquire memory order because the calling thread is trying to make the data it just decoded visible to the other threads, rather than trying to read the data decoded by other threads. In ff_thread_get_buffer(), initialize progress[0] and progress[1] using atomic_init(). Signed-off-by: Wan-Teh Chang Signed-off-by: Anton Khirnov --- libavcodec/pthread_frame.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 75f4ff46247fd..2a800e1e35838 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -458,7 +458,7 @@ void ff_thread_report_progress(ThreadFrame *f, int n, int field) atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL; if (!progress || - atomic_load_explicit(&progress[field], memory_order_acquire) >= n) + atomic_load_explicit(&progress[field], memory_order_relaxed) >= n) return; p = f->owner->internal->thread_ctx; @@ -468,7 +468,7 @@ void ff_thread_report_progress(ThreadFrame *f, int n, int field) pthread_mutex_lock(&p->progress_mutex); - atomic_store(&progress[field], n); + atomic_store_explicit(&progress[field], n, memory_order_release); pthread_cond_broadcast(&p->progress_cond); pthread_mutex_unlock(&p->progress_mutex); @@ -745,8 +745,8 @@ int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags) } progress = (atomic_int*)f->progress->data; - atomic_store(&progress[0], -1); - atomic_store(&progress[1], -1); + atomic_init(&progress[0], -1); + atomic_init(&progress[1], -1); } pthread_mutex_lock(&p->parent->buffer_mutex); From 554e55bbf0e4a3640a784cb512b816e776c56333 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 14 Dec 2016 14:05:16 +0100 Subject: [PATCH 0712/3374] decode.h: Add missing headers to fix standalone compilation --- libavcodec/decode.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/decode.h b/libavcodec/decode.h index c1e6457f77e0f..2f29cf61070cc 100644 --- a/libavcodec/decode.h +++ b/libavcodec/decode.h @@ -21,6 +21,8 @@ #ifndef AVCODEC_DECODE_H #define AVCODEC_DECODE_H +#include "avcodec.h" + /** * Called by decoders to get the next packet for decoding. * From 39929e55eb13eeb8dfbe1bc99301fecf6b8942dd Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 13 Dec 2016 13:45:11 +0100 Subject: [PATCH 0713/3374] ppc: hevcdsp: Use shorthands for vector types This is more consistent and fixes compilation with clang. --- libavcodec/ppc/hevcdsp.c | 18 +++++++++--------- libavcodec/ppc/hevcdsp_template.c | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/libavcodec/ppc/hevcdsp.c b/libavcodec/ppc/hevcdsp.c index 9200e27e6588c..442af9fdc21b4 100644 --- a/libavcodec/ppc/hevcdsp.c +++ b/libavcodec/ppc/hevcdsp.c @@ -31,7 +31,7 @@ #include "libavcodec/hevcdsp.h" #if HAVE_ALTIVEC -static const vector int16_t trans4[4] = { +static const vec_s16 trans4[4] = { { 64, 64, 64, 64, 64, 64, 64, 64 }, { 83, 36, 83, 36, 83, 36, 83, 36 }, { 64, -64, 64, -64, 64, -64, 64, -64 }, @@ -43,13 +43,13 @@ static const vec_u8 mask[2] = { { 0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D, 0x06, 0x07, 0x0E, 0x0F, 0x16, 0x17, 0x1E, 0x1F }, }; -static void transform4x4(vector int16_t src_01, vector int16_t src_23, - vector int32_t res[4], const int shift, int16_t *coeffs) +static void transform4x4(vec_s16 src_01, vec_s16 src_23, vec_s32 res[4], + const int shift, int16_t *coeffs) { - vector int16_t src_02, src_13; - vector int32_t zero = vec_splat_s32(0); - vector int32_t e0, o0, e1, o1; - vector int32_t add; + vec_s16 src_02, src_13; + vec_s32 zero = vec_splat_s32(0); + vec_s32 e0, o0, e1, o1; + vec_s32 add; src_13 = vec_mergel(src_01, src_23); src_02 = vec_mergeh(src_01, src_23); @@ -69,10 +69,10 @@ static void transform4x4(vector int16_t src_01, vector int16_t src_23, res[3] = vec_sub(e0, o0); } -static void scale(vector int32_t res[4], vector int16_t res_packed[2], int shift) +static void scale(vec_s32 res[4], vec_s16 res_packed[2], int shift) { int i; - vector unsigned int v_shift = vec_splat_u32(shift); + vec_u32 v_shift = vec_splat_u32(shift); for (i = 0; i < 4; i++) res[i] = vec_sra(res[i], v_shift); diff --git a/libavcodec/ppc/hevcdsp_template.c b/libavcodec/ppc/hevcdsp_template.c index a68ee18dbb38b..368ae914774b5 100644 --- a/libavcodec/ppc/hevcdsp_template.c +++ b/libavcodec/ppc/hevcdsp_template.c @@ -22,9 +22,9 @@ static void FUNC(ff_hevc_idct_4x4, BIT_DEPTH)(int16_t *coeffs, int col_limit) { const int shift = 7; const int shift2 = 20 - BIT_DEPTH; - vector int16_t src_01, src_23; - vector int32_t res[4]; - vector int16_t res_packed[2]; + vec_s16 src_01, src_23; + vec_s32 res[4]; + vec_s16 res_packed[2]; src_01 = vec_ld(0, coeffs); src_23 = vec_ld(16, coeffs); From ea7ee4b4e381e0fa731458de0cbf740430eeb013 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 12 Dec 2016 16:00:04 +0100 Subject: [PATCH 0714/3374] ppc: Centralize compiler-specific altivec.h #include handling in one place Also move #includes into canonical order where appropriate. --- libavcodec/ppc/apedsp_altivec.c | 6 ++---- libavcodec/ppc/audiodsp.c | 5 +---- libavcodec/ppc/blockdsp.c | 7 +++---- libavcodec/ppc/fdctdsp.c | 6 +++--- libavcodec/ppc/h264chroma_init.c | 3 ++- libavcodec/ppc/h264dsp.c | 1 - libavcodec/ppc/h264qpel.c | 4 +++- libavcodec/ppc/hevcdsp.c | 5 +---- libavcodec/ppc/hpeldsp_altivec.c | 7 ++----- libavcodec/ppc/huffyuvdsp_altivec.c | 5 +---- libavcodec/ppc/idctdsp.c | 9 ++++----- libavcodec/ppc/mdct_init.c | 3 ++- libavcodec/ppc/me_cmp.c | 5 +---- libavcodec/ppc/mpegvideo_altivec.c | 3 ++- libavcodec/ppc/mpegvideodsp.c | 2 +- libavcodec/ppc/mpegvideoencdsp.c | 6 ++---- libavcodec/ppc/pixblockdsp.c | 5 +---- libavcodec/ppc/svq1enc_altivec.c | 9 +++------ libavcodec/ppc/vc1dsp_altivec.c | 3 ++- libavcodec/ppc/vorbisdsp_altivec.c | 6 +++--- libavcodec/ppc/vp3dsp_altivec.c | 3 ++- libavcodec/ppc/vp8dsp_altivec.c | 4 +++- libswscale/swscale_internal.h | 5 +---- 23 files changed, 45 insertions(+), 67 deletions(-) diff --git a/libavcodec/ppc/apedsp_altivec.c b/libavcodec/ppc/apedsp_altivec.c index 21a3d10f18b04..7c9d02ae2da96 100644 --- a/libavcodec/ppc/apedsp_altivec.c +++ b/libavcodec/ppc/apedsp_altivec.c @@ -19,14 +19,12 @@ */ #include "config.h" -#if HAVE_ALTIVEC_H -#include -#endif #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/ppc/cpu.h" -#include "libavutil/ppc/types_altivec.h" +#include "libavutil/ppc/util_altivec.h" + #include "libavcodec/apedsp.h" #if HAVE_ALTIVEC && HAVE_BIGENDIAN diff --git a/libavcodec/ppc/audiodsp.c b/libavcodec/ppc/audiodsp.c index 52a1e75cc16dc..371e0d1e2e8b2 100644 --- a/libavcodec/ppc/audiodsp.c +++ b/libavcodec/ppc/audiodsp.c @@ -24,15 +24,12 @@ */ #include "config.h" -#if HAVE_ALTIVEC_H -#include -#endif #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/ppc/cpu.h" -#include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" + #include "libavcodec/audiodsp.h" #if HAVE_ALTIVEC && HAVE_BIGENDIAN diff --git a/libavcodec/ppc/blockdsp.c b/libavcodec/ppc/blockdsp.c index d2c1d0e766b24..ee5139a93172a 100644 --- a/libavcodec/ppc/blockdsp.c +++ b/libavcodec/ppc/blockdsp.c @@ -21,16 +21,15 @@ */ #include "config.h" -#if HAVE_ALTIVEC_H -#include -#endif + #include #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/mem.h" #include "libavutil/ppc/cpu.h" -#include "libavutil/ppc/types_altivec.h" +#include "libavutil/ppc/util_altivec.h" + #include "libavcodec/blockdsp.h" /* ***** WARNING ***** WARNING ***** WARNING ***** */ diff --git a/libavcodec/ppc/fdctdsp.c b/libavcodec/ppc/fdctdsp.c index cadca8046943a..36d4b4e4bae30 100644 --- a/libavcodec/ppc/fdctdsp.c +++ b/libavcodec/ppc/fdctdsp.c @@ -19,14 +19,14 @@ */ #include "config.h" -#if HAVE_ALTIVEC_H -#include -#endif #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/ppc/cpu.h" +#include "libavutil/ppc/util_altivec.h" + #include "libavcodec/fdctdsp.h" + #include "fdct.h" #if HAVE_ALTIVEC && HAVE_BIGENDIAN diff --git a/libavcodec/ppc/h264chroma_init.c b/libavcodec/ppc/h264chroma_init.c index 4a24b7f82fc7d..f8392c2ee210e 100644 --- a/libavcodec/ppc/h264chroma_init.c +++ b/libavcodec/ppc/h264chroma_init.c @@ -19,12 +19,13 @@ */ #include "config.h" + #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/intreadwrite.h" #include "libavutil/ppc/cpu.h" -#include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" + #include "libavcodec/h264chroma.h" #if HAVE_ALTIVEC && HAVE_BIGENDIAN diff --git a/libavcodec/ppc/h264dsp.c b/libavcodec/ppc/h264dsp.c index a1fd5253b1848..9247cdfb790a8 100644 --- a/libavcodec/ppc/h264dsp.c +++ b/libavcodec/ppc/h264dsp.c @@ -28,7 +28,6 @@ #include "libavutil/intreadwrite.h" #include "libavutil/mem.h" #include "libavutil/ppc/cpu.h" -#include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" #include "libavcodec/h264dec.h" diff --git a/libavcodec/ppc/h264qpel.c b/libavcodec/ppc/h264qpel.c index aff20c15a2d25..5da09bf46eb3f 100644 --- a/libavcodec/ppc/h264qpel.c +++ b/libavcodec/ppc/h264qpel.c @@ -19,13 +19,15 @@ */ #include "config.h" + #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/intreadwrite.h" #include "libavutil/ppc/cpu.h" -#include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" + #include "libavcodec/h264qpel.h" + #include "hpeldsp_altivec.h" #if HAVE_ALTIVEC && HAVE_BIGENDIAN diff --git a/libavcodec/ppc/hevcdsp.c b/libavcodec/ppc/hevcdsp.c index 442af9fdc21b4..f77943b51f898 100644 --- a/libavcodec/ppc/hevcdsp.c +++ b/libavcodec/ppc/hevcdsp.c @@ -19,13 +19,10 @@ */ #include "config.h" -#if HAVE_ALTIVEC_H -#include -#endif +#include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/ppc/cpu.h" -#include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" #include "libavcodec/hevcdsp.h" diff --git a/libavcodec/ppc/hpeldsp_altivec.c b/libavcodec/ppc/hpeldsp_altivec.c index 82b5ce7fc7baf..405b91841e3ea 100644 --- a/libavcodec/ppc/hpeldsp_altivec.c +++ b/libavcodec/ppc/hpeldsp_altivec.c @@ -22,16 +22,13 @@ #include "config.h" -#if HAVE_ALTIVEC_H -#include -#endif - #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/ppc/cpu.h" -#include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" + #include "libavcodec/hpeldsp.h" + #include "hpeldsp_altivec.h" #if HAVE_ALTIVEC && HAVE_BIGENDIAN diff --git a/libavcodec/ppc/huffyuvdsp_altivec.c b/libavcodec/ppc/huffyuvdsp_altivec.c index 7c34a67ea44c4..dff29022a863a 100644 --- a/libavcodec/ppc/huffyuvdsp_altivec.c +++ b/libavcodec/ppc/huffyuvdsp_altivec.c @@ -21,15 +21,12 @@ */ #include "config.h" -#if HAVE_ALTIVEC_H -#include -#endif #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/ppc/cpu.h" -#include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" + #include "libavcodec/huffyuvdsp.h" #if HAVE_ALTIVEC diff --git a/libavcodec/ppc/idctdsp.c b/libavcodec/ppc/idctdsp.c index 0aaaac0131f2d..dc22e152697c5 100644 --- a/libavcodec/ppc/idctdsp.c +++ b/libavcodec/ppc/idctdsp.c @@ -30,17 +30,16 @@ * IDCT function itself was to factor out the partial transposition, and to * perform a full transpose at the end of the function. */ +#include "config.h" + #include #include -#include "config.h" -#if HAVE_ALTIVEC_H -#include -#endif #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/ppc/cpu.h" -#include "libavutil/ppc/types_altivec.h" +#include "libavutil/ppc/util_altivec.h" + #include "libavcodec/idctdsp.h" #if HAVE_ALTIVEC && HAVE_BIGENDIAN diff --git a/libavcodec/ppc/mdct_init.c b/libavcodec/ppc/mdct_init.c index d3582bc00aed9..73200a0f9becc 100644 --- a/libavcodec/ppc/mdct_init.c +++ b/libavcodec/ppc/mdct_init.c @@ -21,10 +21,11 @@ */ #include "config.h" + #include "libavutil/cpu.h" #include "libavutil/ppc/cpu.h" -#include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" + #include "libavcodec/fft.h" /** diff --git a/libavcodec/ppc/me_cmp.c b/libavcodec/ppc/me_cmp.c index 6c70f9f0fa5a6..4e4d8da628d54 100644 --- a/libavcodec/ppc/me_cmp.c +++ b/libavcodec/ppc/me_cmp.c @@ -21,15 +21,12 @@ */ #include "config.h" -#if HAVE_ALTIVEC_H -#include -#endif #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/ppc/cpu.h" -#include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" + #include "libavcodec/avcodec.h" #include "libavcodec/mpegvideo.h" #include "libavcodec/me_cmp.h" diff --git a/libavcodec/ppc/mpegvideo_altivec.c b/libavcodec/ppc/mpegvideo_altivec.c index a09932bdf83a4..89e15a4a7f176 100644 --- a/libavcodec/ppc/mpegvideo_altivec.c +++ b/libavcodec/ppc/mpegvideo_altivec.c @@ -25,11 +25,12 @@ #include #include "config.h" + #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/ppc/cpu.h" -#include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" + #include "libavcodec/mpegvideo.h" #if HAVE_ALTIVEC && HAVE_BIGENDIAN diff --git a/libavcodec/ppc/mpegvideodsp.c b/libavcodec/ppc/mpegvideodsp.c index eef3e1dcbe200..44ae126774ff8 100644 --- a/libavcodec/ppc/mpegvideodsp.c +++ b/libavcodec/ppc/mpegvideodsp.c @@ -23,8 +23,8 @@ #include "libavutil/cpu.h" #include "libavutil/mem.h" #include "libavutil/ppc/cpu.h" -#include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" + #include "libavcodec/mpegvideodsp.h" #if HAVE_ALTIVEC && HAVE_BIGENDIAN diff --git a/libavcodec/ppc/mpegvideoencdsp.c b/libavcodec/ppc/mpegvideoencdsp.c index fa71bac0baa75..d11f05bf1e7da 100644 --- a/libavcodec/ppc/mpegvideoencdsp.c +++ b/libavcodec/ppc/mpegvideoencdsp.c @@ -17,16 +17,14 @@ */ #include "config.h" + #include -#if HAVE_ALTIVEC_H -#include -#endif #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/ppc/cpu.h" -#include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" + #include "libavcodec/mpegvideoencdsp.h" #if HAVE_ALTIVEC && HAVE_BIGENDIAN diff --git a/libavcodec/ppc/pixblockdsp.c b/libavcodec/ppc/pixblockdsp.c index 96e702452f15e..c9e598b704768 100644 --- a/libavcodec/ppc/pixblockdsp.c +++ b/libavcodec/ppc/pixblockdsp.c @@ -21,15 +21,12 @@ */ #include "config.h" -#if HAVE_ALTIVEC_H -#include -#endif #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/ppc/cpu.h" -#include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" + #include "libavcodec/avcodec.h" #include "libavcodec/pixblockdsp.h" diff --git a/libavcodec/ppc/svq1enc_altivec.c b/libavcodec/ppc/svq1enc_altivec.c index 77d771eba6512..e155f885cd052 100644 --- a/libavcodec/ppc/svq1enc_altivec.c +++ b/libavcodec/ppc/svq1enc_altivec.c @@ -18,18 +18,15 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include - #include "config.h" -#if HAVE_ALTIVEC_H -#include -#endif + +#include #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/ppc/cpu.h" -#include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" + #include "libavcodec/svq1enc.h" #if HAVE_ALTIVEC && HAVE_BIGENDIAN diff --git a/libavcodec/ppc/vc1dsp_altivec.c b/libavcodec/ppc/vc1dsp_altivec.c index d2524215603cc..fc825023589f5 100644 --- a/libavcodec/ppc/vc1dsp_altivec.c +++ b/libavcodec/ppc/vc1dsp_altivec.c @@ -20,11 +20,12 @@ */ #include "config.h" + #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/ppc/cpu.h" -#include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" + #include "libavcodec/vc1dsp.h" #if HAVE_ALTIVEC && HAVE_BIGENDIAN diff --git a/libavcodec/ppc/vorbisdsp_altivec.c b/libavcodec/ppc/vorbisdsp_altivec.c index 509d48ae0ce60..52c29527ba0db 100644 --- a/libavcodec/ppc/vorbisdsp_altivec.c +++ b/libavcodec/ppc/vorbisdsp_altivec.c @@ -19,12 +19,12 @@ */ #include "config.h" -#if HAVE_ALTIVEC_H -#include -#endif + #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/ppc/cpu.h" +#include "libavutil/ppc/util_altivec.h" + #include "libavcodec/vorbisdsp.h" #if HAVE_ALTIVEC && HAVE_BIGENDIAN diff --git a/libavcodec/ppc/vp3dsp_altivec.c b/libavcodec/ppc/vp3dsp_altivec.c index 4dff4f1b966a9..2b7cc9d503670 100644 --- a/libavcodec/ppc/vp3dsp_altivec.c +++ b/libavcodec/ppc/vp3dsp_altivec.c @@ -21,11 +21,12 @@ #include #include "config.h" + #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/ppc/cpu.h" -#include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" + #include "libavcodec/vp3dsp.h" #if HAVE_ALTIVEC && HAVE_BIGENDIAN diff --git a/libavcodec/ppc/vp8dsp_altivec.c b/libavcodec/ppc/vp8dsp_altivec.c index 53fe44ab4897d..6857e6b6a2263 100644 --- a/libavcodec/ppc/vp8dsp_altivec.c +++ b/libavcodec/ppc/vp8dsp_altivec.c @@ -21,12 +21,14 @@ */ #include "config.h" + #include "libavutil/cpu.h" #include "libavutil/mem.h" #include "libavutil/ppc/cpu.h" -#include "libavutil/ppc/types_altivec.h" #include "libavutil/ppc/util_altivec.h" + #include "libavcodec/vp8dsp.h" + #include "hpeldsp_altivec.h" #if HAVE_ALTIVEC && HAVE_BIGENDIAN diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index e7a6eedd22b05..adfe1708e19b7 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -23,16 +23,13 @@ #include "config.h" -#if HAVE_ALTIVEC_H -#include -#endif - #include "libavutil/avassert.h" #include "libavutil/avutil.h" #include "libavutil/common.h" #include "libavutil/log.h" #include "libavutil/pixfmt.h" #include "libavutil/pixdesc.h" +#include "libavutil/ppc/util_altivec.h" #define STR(s) AV_TOSTRING(s) // AV_STRINGIFY is too long From 05a603a94e4b3eeefa5e18ae653a848001461e89 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 13 Dec 2016 13:50:10 +0100 Subject: [PATCH 0715/3374] ppc: Merge types_altivec.h into util_altivec.h There is no point in keeping the two separate. --- libavutil/ppc/types_altivec.h | 47 ----------------------------------- libavutil/ppc/util_altivec.h | 23 ++++++++++++++++- 2 files changed, 22 insertions(+), 48 deletions(-) delete mode 100644 libavutil/ppc/types_altivec.h diff --git a/libavutil/ppc/types_altivec.h b/libavutil/ppc/types_altivec.h deleted file mode 100644 index 0a4eaf885f797..0000000000000 --- a/libavutil/ppc/types_altivec.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2006 Guillaume Poirier - * - * This file is part of Libav. - * - * Libav is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * Libav is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_PPC_TYPES_ALTIVEC_H -#define AVUTIL_PPC_TYPES_ALTIVEC_H - -/*********************************************************************** - * Vector types - **********************************************************************/ -#define vec_u8 vector unsigned char -#define vec_s8 vector signed char -#define vec_u16 vector unsigned short -#define vec_s16 vector signed short -#define vec_u32 vector unsigned int -#define vec_s32 vector signed int -#define vec_f vector float - -/*********************************************************************** - * Null vector - **********************************************************************/ -#define LOAD_ZERO const vec_u8 zerov = vec_splat_u8( 0 ) - -#define zero_u8v (vec_u8) zerov -#define zero_s8v (vec_s8) zerov -#define zero_u16v (vec_u16) zerov -#define zero_s16v (vec_s16) zerov -#define zero_u32v (vec_u32) zerov -#define zero_s32v (vec_s32) zerov - -#endif /* AVUTIL_PPC_TYPES_ALTIVEC_H */ diff --git a/libavutil/ppc/util_altivec.h b/libavutil/ppc/util_altivec.h index 02cff186f9726..5a16e8de13ca5 100644 --- a/libavutil/ppc/util_altivec.h +++ b/libavutil/ppc/util_altivec.h @@ -32,7 +32,28 @@ #include #endif -#include "types_altivec.h" +/*********************************************************************** + * Vector types + **********************************************************************/ +#define vec_u8 vector unsigned char +#define vec_s8 vector signed char +#define vec_u16 vector unsigned short +#define vec_s16 vector signed short +#define vec_u32 vector unsigned int +#define vec_s32 vector signed int +#define vec_f vector float + +/*********************************************************************** + * Null vector + **********************************************************************/ +#define LOAD_ZERO const vec_u8 zerov = vec_splat_u8( 0 ) + +#define zero_u8v (vec_u8) zerov +#define zero_s8v (vec_s8) zerov +#define zero_u16v (vec_u16) zerov +#define zero_s16v (vec_s16) zerov +#define zero_u32v (vec_u32) zerov +#define zero_s32v (vec_s32) zerov #if HAVE_ALTIVEC From 2425d7329fdccfa9954faba748f3865151354f0c Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 8 Dec 2016 20:40:34 +0100 Subject: [PATCH 0716/3374] arm64: replace 'bic' with immediate with 'and' with inverted immediate The former is not an official pseudo instruction although gas and llvm's internal assembler support it. Fixes a build error with xcode 6.2 reported by Memphiz on github. --- libavcodec/aarch64/synth_filter_neon.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/aarch64/synth_filter_neon.S b/libavcodec/aarch64/synth_filter_neon.S index 9551bff8e3371..b001c737da984 100644 --- a/libavcodec/aarch64/synth_filter_neon.S +++ b/libavcodec/aarch64/synth_filter_neon.S @@ -50,7 +50,7 @@ function ff_synth_filter_float_neon, export=1 add x1, x1, x7, lsl #2 // synth_buf sub w8, w7, #32 stp x5, x1, [sp, #16] - bic x7, x7, #63 + and x7, x7, #~63 and w8, w8, #511 stp x7, x30, [sp, #32] str w8, [x2] From cdcfa97dc49d83b5eefd0a651db6bb0a6f98e8f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 15 Dec 2016 09:45:49 +0200 Subject: [PATCH 0717/3374] libavformat: Fix a faulty api deprecation guard in prepare_input_packet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This seems to have been added by mistake in 11de006b, by not noticing the negation for the existing condition. This block does not contain any code that accesses the codec field in AVStream. This function is meant to serve as a complement to compute_pkt_fields2, which is guarded by FF_API_COMPUTE_PKT_FIELDS2 && FF_API_LAVF_AVCTX. Signed-off-by: Martin Storsjö --- libavformat/mux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/mux.c b/libavformat/mux.c index 37c4541ad9dfb..2561a6d6f958c 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -423,7 +423,7 @@ static int prepare_input_packet(AVFormatContext *s, AVPacket *pkt) if (ret < 0) return ret; -#if !FF_API_COMPUTE_PKT_FIELDS2 && FF_API_LAVF_AVCTX +#if !FF_API_COMPUTE_PKT_FIELDS2 || !FF_API_LAVF_AVCTX /* sanitize the timestamps */ if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) { AVStream *st = s->streams[pkt->stream_index]; From a4fec9a7eab842ea5eea1b1ee98624356cb31422 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 5 Dec 2016 11:14:51 +0100 Subject: [PATCH 0718/3374] rtmppkt: Check for packet size mismatches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When receiving fragmented packets, the first packet declares the size, and the later ones normally are small follow-on packets that don't repeat the size and the other header fields. But technically, the later fragments also can have a full header, declaring a different size than the previous packet. If the follow-on packet declares a larger size than the initial one, we could end up writing outside of the allocation. This fixes out of bounds writes. Found-by: Paul Cher Reviewed-by: Paul Cher CC: libav-stable@libav.org Signed-off-by: Martin Storsjö --- libavformat/rtmppkt.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c index f8c51d01fade3..1cb30786794ec 100644 --- a/libavformat/rtmppkt.c +++ b/libavformat/rtmppkt.c @@ -235,6 +235,14 @@ static int rtmp_packet_read_one_chunk(URLContext *h, RTMPPacket *p, if (hdr != RTMP_PS_TWELVEBYTES) timestamp += prev_pkt[channel_id].timestamp; + if (prev_pkt[channel_id].read && size != prev_pkt[channel_id].size) { + av_log(h, AV_LOG_ERROR, "RTMP packet size mismatch %d != %d\n", + size, prev_pkt[channel_id].size); + ff_rtmp_packet_destroy(&prev_pkt[channel_id]); + prev_pkt[channel_id].read = 0; + return AVERROR_INVALIDDATA; + } + if (!prev_pkt[channel_id].read) { if ((ret = ff_rtmp_packet_create(p, channel_id, type, timestamp, size)) < 0) From ef9a711be718ed3802a263d1d9ed340a4aaef224 Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Thu, 15 Dec 2016 18:00:55 +0100 Subject: [PATCH 0719/3374] configure: put d3d11 check in alphabetical order --- configure | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index fb82fc4d47461..25640ebb7fae1 100755 --- a/configure +++ b/configure @@ -1514,6 +1514,7 @@ HEADERS_LIST=" arpa_inet_h cdio_paranoia_h cdio_paranoia_paranoia_h + d3d11_h dispatch_dispatch_h dev_bktr_ioctl_bt848_h dev_bktr_ioctl_meteor_h @@ -1522,7 +1523,6 @@ HEADERS_LIST=" dev_video_meteor_ioctl_meteor_h direct_h dlfcn_h - d3d11_h dxva_h gsm_h io_h @@ -4530,9 +4530,9 @@ check_func_headers windows.h Sleep check_func_headers windows.h VirtualAlloc check_struct windows.h "CONDITION_VARIABLE" Ptr +check_header d3d11.h check_header direct.h check_header dlfcn.h -check_header d3d11.h check_header dxva.h check_header dxva2api.h check_header io.h From f7174d7ed045445d00a6d557236737d09ad32343 Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Thu, 15 Dec 2016 18:00:56 +0100 Subject: [PATCH 0720/3374] configure: fix linking with MSVC when using --disable-optimizations Without any optimization flags, MSVC does no dead code elimination (DCE) at all, even for the most trivial cases. DCE is a prerequisite for building libav correctly, otherwise there are undefined references to functions for other architectures and disabled components. -O1 is the minimal optimization flag for MSVC that does include DCE. --- configure | 1 + 1 file changed, 1 insertion(+) diff --git a/configure b/configure index 25640ebb7fae1..2ecd0ed71894e 100755 --- a/configure +++ b/configure @@ -3279,6 +3279,7 @@ probe_cc(){ _DEPFLAGS='$(CPPFLAGS) $(CFLAGS) -showIncludes -Zs' _cflags_speed="-O2" _cflags_size="-O1" + _cflags_noopt="-O1" if $_cc -nologo- 2>&1 | grep -q Linker; then _ld_o='-out:$@' else From 1faffe7e8fab21186a233011bc8a62f47962e2cd Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 15 Dec 2016 18:59:46 +0100 Subject: [PATCH 0721/3374] configure: Disentangle vfw32 and user32 lib handling Check for and link against user32 instead, which also fixes the missing dependency of dxva2 on user32 with MSVC. --- configure | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/configure b/configure index 2ecd0ed71894e..19dbdf2b79b63 100755 --- a/configure +++ b/configure @@ -2387,7 +2387,6 @@ sndio_indev_deps="sndio" sndio_outdev_deps="sndio" v4l2_indev_deps_any="linux_videodev2_h sys_videoio_h" vfwcap_indev_deps="capCreateCaptureWindow vfwcap_defines" -vfwcap_indev_extralibs="-lavicap32" xcbgrab_indev_deps="libxcb" # protocols @@ -3046,7 +3045,6 @@ msvc_common_flags(){ -mthumb) ;; -march=*) ;; -lz) echo zlib.lib ;; - -lavicap32) echo vfw32.lib user32.lib ;; -lx264) echo libx264.lib ;; -l*) echo ${flag#-l}.lib ;; -L*) echo -libpath:${flag#-L} ;; @@ -4729,7 +4727,8 @@ check_header AVFoundation/AVFoundation.h check_header sys/videoio.h -check_func_headers "windows.h vfw.h" capCreateCaptureWindow "$vfwcap_indev_extralibs" +check_lib "windows.h winuser.h" GetShellWindow -luser32 +check_lib "windows.h vfw.h" capCreateCaptureWindow -lvfw32 # check that WM_CAP_DRIVER_CONNECT is defined to the proper value # w32api 3.12 had it defined wrong check_cpp_condition vfw.h "WM_CAP_DRIVER_CONNECT > WM_USER" && enable vfwcap_defines From ee480790c7eeb03c9cebd8971c46e0cb7db65277 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 8 Dec 2016 10:16:34 +0100 Subject: [PATCH 0722/3374] build: Add name parameter to check_lib() helper function This allows enabling or disabling the library-related variables from within the function instead of doing it manually outside of it. --- configure | 90 +++++++++++++++++++++++++++---------------------------- 1 file changed, 44 insertions(+), 46 deletions(-) diff --git a/configure b/configure index 19dbdf2b79b63..365bbb2bf293d 100755 --- a/configure +++ b/configure @@ -1006,10 +1006,13 @@ EOF check_lib(){ log check_lib "$@" - headers="$1" - funcs="$2" - shift 2 - check_func_headers "$headers" "$funcs" "$@" && add_extralibs "$@" + name="$1" + headers="$2" + funcs="$3" + shift 3 + disable $name + check_func_headers "$headers" "$funcs" "$@" && + enable $name && add_extralibs "$@" } check_pkg_config(){ @@ -1105,10 +1108,11 @@ check_compile_assert(){ require(){ log require "$@" name_version="$1" + name="${1%% *}" headers="$2" func="$3" shift 3 - check_lib "$headers" $func "$@" || die "ERROR: $name_version not found" + check_lib $name "$headers" $func "$@" || die "ERROR: $name_version not found" } require_pkg_config(){ @@ -2386,7 +2390,7 @@ pulse_indev_deps="libpulse" sndio_indev_deps="sndio" sndio_outdev_deps="sndio" v4l2_indev_deps_any="linux_videodev2_h sys_videoio_h" -vfwcap_indev_deps="capCreateCaptureWindow vfwcap_defines" +vfwcap_indev_deps="vfw32 vfwcap_defines" xcbgrab_indev_deps="libxcb" # protocols @@ -4492,7 +4496,7 @@ check_func ${malloc_prefix}posix_memalign && enable posix_memalign check_cpp_condition unistd.h "defined(_POSIX_MONOTONIC_CLOCK)" && check_func_headers time.h clock_gettime || - { check_lib time.h clock_gettime -lrt && LIBRT="-lrt"; } + { check_lib clock_gettime time.h clock_gettime -lrt && LIBRT="-lrt"; } check_func fcntl check_func fork @@ -4508,7 +4512,7 @@ check_func mkstemp check_func mmap check_func mprotect # Solaris has nanosleep in -lrt, OpenSolaris no longer needs that -check_func_headers time.h nanosleep || check_lib time.h nanosleep -lrt +check_func_headers time.h nanosleep || check_lib nanosleep time.h nanosleep -lrt check_func sched_getaffinity check_func setrlimit check_func strerror_r @@ -4555,9 +4559,9 @@ check_header X11/extensions/XvMClib.h # so we also check that atomics actually work here check_builtin stdatomic_h stdatomic.h "atomic_int foo; atomic_store(&foo, 0)" -check_lib "windows.h shellapi.h" CommandLineToArgvW -lshell32 -check_lib "windows.h wincrypt.h" CryptGenRandom -ladvapi32 -check_lib "windows.h psapi.h" GetProcessMemoryInfo -lpsapi +check_lib shell32 "windows.h shellapi.h" CommandLineToArgvW -lshell32 +check_lib wincrypt "windows.h wincrypt.h" CryptGenRandom -ladvapi32 +check_lib psapi "windows.h psapi.h" GetProcessMemoryInfo -lpsapi check_struct "sys/time.h sys/resource.h" "struct rusage" ru_maxrss @@ -4574,34 +4578,32 @@ check_type "va/va.h va/va_enc_jpeg.h" "VAEncPictureParameterBufferJPEG" check_type "vdpau/vdpau.h" "VdpPictureInfoHEVC" if ! disabled w32threads && ! enabled pthreads; then - check_func_headers "windows.h process.h" _beginthreadex && - enable w32threads || disable w32threads + check_lib w32threads "windows.h process.h" _beginthreadex fi # check for some common methods of building with pthread support # do this before the optional library checks as some of them require pthreads if ! disabled pthreads && ! enabled w32threads; then - enable pthreads - if check_lib pthread.h pthread_join -pthread; then + if check_lib pthreads pthread.h pthread_join -pthread; then add_cflags -pthread - elif check_lib pthread.h pthread_join -pthreads; then + elif check_lib pthreads pthread.h pthread_join -pthreads; then add_cflags -pthreads - elif check_lib pthread.h pthread_join -lpthreadGC2; then + elif check_lib pthreads pthread.h pthread_join -lpthreadGC2; then : - elif check_lib pthread.h pthread_join -lpthread; then + elif check_lib pthreads pthread.h pthread_join -lpthread; then : - elif ! check_func pthread_join; then - disable pthreads + elif check_func pthread_join; then + enable pthreads fi fi enabled pthreads && check_builtin sem_timedwait semaphore.h "sem_t *s; sem_init(s,0,0); sem_timedwait(s,0); sem_destroy(s)" -disabled zlib || check_lib zlib.h zlibVersion -lz || disable zlib -disabled bzlib || check_lib bzlib.h BZ2_bzlibVersion -lbz2 || disable bzlib +disabled zlib || check_lib zlib zlib.h zlibVersion -lz +disabled bzlib || check_lib bzlib bzlib.h BZ2_bzlibVersion -lbz2 -check_lib math.h sin -lm && LIBM="-lm" +check_lib libm math.h sin -lm && LIBM="-lm" atan2f_args=2 ldexpf_args=2 @@ -4625,7 +4627,7 @@ enabled libfdk_aac && require_pkg_config fdk-aac "fdk-aac/aacenc_lib.h" a enabled libfontconfig && require_pkg_config fontconfig "fontconfig/fontconfig.h" FcInit enabled libfreetype && require_pkg_config freetype2 "ft2build.h FT_FREETYPE_H" FT_Init_FreeType enabled libgsm && { for gsm_hdr in "gsm.h" "gsm/gsm.h"; do - check_lib "${gsm_hdr}" gsm_create -lgsm && break; + check_lib libgsm "${gsm_hdr}" gsm_create -lgsm && break; done || die "ERROR: libgsm not found"; } enabled libhdcd && require_pkg_config libhdcd "hdcd/hdcd_simple.h" hdcd_new enabled libilbc && require libilbc ilbc.h WebRtcIlbcfix_InitDecode -lilbc @@ -4637,7 +4639,7 @@ enabled libopencore_amrnb && require libopencore_amrnb opencore-amrnb/interf_dec enabled libopencore_amrwb && require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb enabled libopencv && require_pkg_config opencv opencv/cv.h cvCreateImageHeader enabled libopenh264 && require_pkg_config openh264 wels/codec_api.h WelsGetCodecVersion -enabled libopenjpeg && { check_lib openjpeg.h opj_version -lopenjpeg -DOPJ_STATIC || +enabled libopenjpeg && { check_lib libopenjpeg openjpeg.h opj_version -lopenjpeg -DOPJ_STATIC || require_pkg_config libopenjpeg1 openjpeg.h opj_version -DOPJ_STATIC; } enabled libopus && require_pkg_config opus opus_multistream.h opus_multistream_decoder_create enabled libpulse && require_pkg_config libpulse-simple pulse/simple.h pa_simple_new @@ -4683,11 +4685,11 @@ enabled libx265 && require_pkg_config x265 x265.h x265_api_get && die "ERROR: libx265 version must be >= 57."; } enabled libxavs && require libxavs "stdint.h xavs.h" xavs_encoder_encode -lxavs enabled libxvid && require libxvid xvid.h xvid_global -lxvidcore -enabled mmal && { check_lib interface/mmal/mmal.h mmal_port_connect -lmmal_core -lmmal_util -lmmal_vc_client -lbcm_host || +enabled mmal && { check_lib mmal interface/mmal/mmal.h mmal_port_connect -lmmal_core -lmmal_util -lmmal_vc_client -lbcm_host || { ! enabled cross_compile && add_cflags -isystem/opt/vc/include/ -isystem/opt/vc/include/interface/vmcs_host/linux -isystem/opt/vc/include/interface/vcos/pthreads -fgnu89-inline && add_ldflags -L/opt/vc/lib/ && - check_lib interface/mmal/mmal.h mmal_port_connect -lmmal_core -lmmal_util -lmmal_vc_client -lbcm_host; } || + check_lib mmal interface/mmal/mmal.h mmal_port_connect -lmmal_core -lmmal_util -lmmal_vc_client -lbcm_host; } || die "ERROR: mmal not found" && check_func_headers interface/mmal/mmal.h "MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS"; } enabled omx_rpi && { check_header OMX_Core.h || @@ -4697,12 +4699,12 @@ enabled omx && { check_header OMX_Core.h || die "ERROR: OpenMAX IL enabled openssl && { { check_pkg_config openssl openssl/ssl.h OPENSSL_init_ssl || check_pkg_config openssl openssl/ssl.h SSL_library_init; } && { add_cflags $openssl_cflags && add_extralibs $openssl_extralibs; } || - check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto || - check_lib openssl/ssl.h SSL_library_init -lssl32 -leay32 || - check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 || + check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto || + check_lib openssl openssl/ssl.h SSL_library_init -lssl32 -leay32 || + check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 || die "ERROR: openssl not found"; } -enabled gnutls && check_lib gmp.h mpz_export -lgmp && enable gmp +enabled gnutls && check_lib gmp gmp.h mpz_export -lgmp if enabled nvenc; then check_header nvEncodeAPI.h || die "ERROR: nvEncodeAPI.h not found." @@ -4727,8 +4729,8 @@ check_header AVFoundation/AVFoundation.h check_header sys/videoio.h -check_lib "windows.h winuser.h" GetShellWindow -luser32 -check_lib "windows.h vfw.h" capCreateCaptureWindow -lvfw32 +check_lib user32 "windows.h winuser.h" GetShellWindow -luser32 +check_lib vfw32 "windows.h vfw.h" capCreateCaptureWindow -lvfw32 # check that WM_CAP_DRIVER_CONNECT is defined to the proper value # w32api 3.12 had it defined wrong check_cpp_condition vfw.h "WM_CAP_DRIVER_CONNECT > WM_USER" && enable vfwcap_defines @@ -4746,16 +4748,16 @@ check_header sys/soundcard.h check_header soundcard.h enabled_any alsa_indev alsa_outdev && - check_lib alsa/asoundlib.h snd_pcm_htimestamp -lasound + check_lib alsa alsa/asoundlib.h snd_pcm_htimestamp -lasound -enabled jack_indev && check_lib jack/jack.h jack_client_open -ljack && +enabled jack_indev && check_lib jack jack/jack.h jack_client_open -ljack && check_func jack_port_get_latency_range -ljack -enabled_any sndio_indev sndio_outdev && check_lib sndio.h sio_open -lsndio +enabled_any sndio_indev sndio_outdev && check_lib sndio sndio.h sio_open -lsndio if enabled libcdio; then - check_lib "cdio/cdda.h cdio/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio || - check_lib "cdio/paranoia/cdda.h cdio/paranoia/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio || + check_lib libcdio "cdio/cdda.h cdio/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio || + check_lib libcdio "cdio/paranoia/cdda.h cdio/paranoia/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio || die "ERROR: No usable libcdio/cdparanoia found" fi @@ -4779,8 +4781,7 @@ if enabled libxcb; then fi enabled dxva2 && - check_lib windows.h CoTaskMemFree -lole32 && - enable dxva2_lib + check_lib dxva2_lib windows.h CoTaskMemFree -lole32 enabled vaapi && require vaapi va/va.h vaInitialize -lva @@ -4789,20 +4790,17 @@ enabled vaapi && disable vaapi enabled vaapi && - check_lib "va/va.h va/va_drm.h" vaGetDisplayDRM -lva -lva-drm && - enable vaapi_drm + check_lib vaapi_drm "va/va.h va/va_drm.h" vaGetDisplayDRM -lva -lva-drm enabled vaapi && - check_lib "va/va.h va/va_x11.h" vaGetDisplay -lva -lva-x11 -lX11 && - enable vaapi_x11 + check_lib vaapi_x11 "va/va.h va/va_x11.h" vaGetDisplay -lva -lva-x11 -lX11 enabled vdpau && check_cpp_condition vdpau/vdpau.h "defined VDP_DECODER_PROFILE_MPEG4_PART2_ASP" || disable vdpau enabled vdpau && - check_lib "vdpau/vdpau.h vdpau/vdpau_x11.h" vdp_device_create_x11 -lvdpau -lX11 && - enable vdpau_x11 + check_lib vdpau_x11 "vdpau/vdpau.h vdpau/vdpau_x11.h" vdp_device_create_x11 -lvdpau -lX11 enabled debug && add_cflags -g"$debuglevel" && add_asflags -g"$debuglevel" From 0fea8555ae25124c21f4c4f55a5fa76e9169aa03 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 14 Dec 2016 13:22:19 +0100 Subject: [PATCH 0723/3374] v4l2: use codec descriptors for mapping a codec name to id This mapping has nothing to do with decoder implementations, so using decoder names is wrong. --- libavdevice/v4l2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c index 0479121d7dab8..a8afe8ab589bf 100644 --- a/libavdevice/v4l2.c +++ b/libavdevice/v4l2.c @@ -771,16 +771,16 @@ static int v4l2_read_header(AVFormatContext *s1) } if (s->pixel_format) { - AVCodec *codec = avcodec_find_decoder_by_name(s->pixel_format); + const AVCodecDescriptor *desc = avcodec_descriptor_get_by_name(s->pixel_format); - if (codec) { - s1->video_codec_id = codec->id; + if (desc) { + s1->video_codec_id = desc->id; st->need_parsing = AVSTREAM_PARSE_HEADERS; } pix_fmt = av_get_pix_fmt(s->pixel_format); - if (pix_fmt == AV_PIX_FMT_NONE && !codec) { + if (pix_fmt == AV_PIX_FMT_NONE && !desc) { av_log(s1, AV_LOG_ERROR, "No such input format: %s.\n", s->pixel_format); From 373fd76b4dbd9aa03ed28e502f33f2ca8c1ce19a Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 18 Dec 2016 22:06:32 +0100 Subject: [PATCH 0724/3374] hevcdec: do not set decoder-global SPS prematurely It should only be set after the decoder state has been fully initialized for using that SPS. Fixes possible invalid reads on get_format() failure. CC: libav-stable@libav.org --- libavcodec/hevcdec.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 27fd6832ab2e3..147243e3fe527 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -479,17 +479,16 @@ static int hls_slice_header(HEVCContext *s) s->ps.pps = (HEVCPPS*)s->ps.pps_list[sh->pps_id]->data; if (s->ps.sps != (HEVCSPS*)s->ps.sps_list[s->ps.pps->sps_id]->data) { + const HEVCSPS *sps = (HEVCSPS*)s->ps.sps_list[s->ps.pps->sps_id]->data; enum AVPixelFormat pix_fmt; - s->ps.sps = (HEVCSPS*)s->ps.sps_list[s->ps.pps->sps_id]->data; - ff_hevc_clear_refs(s); - pix_fmt = get_format(s, s->ps.sps); + pix_fmt = get_format(s, sps); if (pix_fmt < 0) return pix_fmt; - ret = set_sps(s, s->ps.sps, pix_fmt); + ret = set_sps(s, sps, pix_fmt); if (ret < 0) return ret; From 8dfba25ce89b62c80ba83e2116d549176c376144 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 3 Dec 2016 15:21:40 +0100 Subject: [PATCH 0725/3374] pthread_frame: ensure the threads don't run simultaneously with hwaccel --- libavcodec/h263dec.c | 2 +- libavcodec/h264dec.c | 2 +- libavcodec/pthread_frame.c | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index e4a7227575cd7..921ff5fb98557 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -558,7 +558,7 @@ int ff_h263_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if ((ret = ff_mpv_frame_start(s, avctx)) < 0) return ret; - if (!s->divx_packed && !avctx->hwaccel) + if (!s->divx_packed) ff_thread_finish_setup(avctx); if (avctx->hwaccel) { diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 330a74dcb4a14..83b3ab3be1ea1 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -573,7 +573,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size) if ((err = ff_h264_queue_decode_slice(h, nal))) break; - if (avctx->active_thread_type & FF_THREAD_FRAME && !h->avctx->hwaccel && + if (avctx->active_thread_type & FF_THREAD_FRAME && i >= nals_needed && !h->setup_finished && h->cur_pic_ptr) { ff_thread_finish_setup(avctx); h->setup_finished = 1; diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 2a800e1e35838..fd35456f59c57 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -99,6 +99,8 @@ typedef struct PerThreadContext { int requested_flags; ///< flags passed to get_buffer() for requested_frame int die; ///< Set when the thread should exit. + + int hwaccel_serializing; } PerThreadContext; /** @@ -109,6 +111,11 @@ typedef struct FrameThreadContext { PerThreadContext *prev_thread; ///< The last thread submit_packet() was called on. pthread_mutex_t buffer_mutex; ///< Mutex used to protect get/release_buffer(). + /** + * This lock is used for ensuring threads run in serial when hwaccel + * is used. + */ + pthread_mutex_t hwaccel_mutex; int next_decoding; ///< The next context to submit a packet to. int next_finished; ///< The next context to return output from. @@ -149,6 +156,22 @@ static attribute_align_arg void *frame_worker_thread(void *arg) ff_thread_finish_setup(avctx); pthread_mutex_lock(&p->mutex); + + /* If a decoder supports hwaccel, then it must call ff_get_format(). + * Since that call must happen before ff_thread_finish_setup(), the + * decoder is required to implement update_thread_context() and call + * ff_thread_finish_setup() manually. Therefore the above + * ff_thread_finish_setup() call did not happen and hwaccel_serializing + * cannot be true here. */ + av_assert0(!p->hwaccel_serializing); + + /* if the previous thread uses hwaccel then we take the lock to ensure + * the threads don't run concurrently */ + if (avctx->hwaccel) { + pthread_mutex_lock(&p->parent->hwaccel_mutex); + p->hwaccel_serializing = 1; + } + av_frame_unref(p->frame); p->got_frame = 0; p->result = codec->decode(avctx, p->frame, &p->got_frame, &p->avpkt); @@ -163,6 +186,11 @@ static attribute_align_arg void *frame_worker_thread(void *arg) if (atomic_load(&p->state) == STATE_SETTING_UP) ff_thread_finish_setup(avctx); + if (p->hwaccel_serializing) { + p->hwaccel_serializing = 0; + pthread_mutex_unlock(&p->parent->hwaccel_mutex); + } + atomic_store(&p->state, STATE_INPUT_READY); pthread_mutex_lock(&p->progress_mutex); @@ -499,6 +527,11 @@ void ff_thread_finish_setup(AVCodecContext *avctx) { if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return; + if (avctx->hwaccel && !p->hwaccel_serializing) { + pthread_mutex_lock(&p->parent->hwaccel_mutex); + p->hwaccel_serializing = 1; + } + pthread_mutex_lock(&p->progress_mutex); atomic_store(&p->state, STATE_SETUP_FINISHED); @@ -579,6 +612,7 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) av_freep(&fctx->threads); pthread_mutex_destroy(&fctx->buffer_mutex); + pthread_mutex_destroy(&fctx->hwaccel_mutex); av_freep(&avctx->internal->thread_ctx); } @@ -620,6 +654,7 @@ int ff_frame_thread_init(AVCodecContext *avctx) } pthread_mutex_init(&fctx->buffer_mutex, NULL); + pthread_mutex_init(&fctx->hwaccel_mutex, NULL); fctx->delaying = 1; for (i = 0; i < thread_count; i++) { From d4a91e65343be5d79a4afa61c791191e1b57499a Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 24 Nov 2016 15:14:22 +0100 Subject: [PATCH 0726/3374] pthread_frame: do not run hwaccel decoding asynchronously unless it's safe Certain hardware decoding APIs are not guaranteed to be thread-safe, so having the user access decoded hardware surfaces while the decoder is running in another thread can cause failures (this is mainly known to happen with DXVA2). For such hwaccels, only allow the decoding thread to run while the user is inside a lavc decode call (avcodec_send_packet/receive_frame). --- libavcodec/avcodec.h | 5 ++++ libavcodec/hwaccel.h | 24 ++++++++++++++++++ libavcodec/pthread_frame.c | 52 +++++++++++++++++++++++++++++++++----- libavcodec/vaapi_h264.c | 2 ++ libavcodec/vaapi_mpeg2.c | 2 ++ libavcodec/vaapi_mpeg4.c | 3 +++ libavcodec/vaapi_vc1.c | 3 +++ libavcodec/vaapi_vp8.c | 2 ++ libavcodec/vdpau_h264.c | 2 ++ libavcodec/vdpau_hevc.c | 2 ++ libavcodec/vdpau_mpeg12.c | 3 +++ libavcodec/vdpau_mpeg4.c | 2 ++ libavcodec/vdpau_vc1.c | 3 +++ libavcodec/version.h | 2 +- 14 files changed, 100 insertions(+), 7 deletions(-) create mode 100644 libavcodec/hwaccel.h diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 0997141e2c157..95da50b0e7d8b 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3375,6 +3375,11 @@ typedef struct AVHWAccel { * AVCodecInternal.hwaccel_priv_data. */ int priv_data_size; + + /** + * Internal hwaccel capabilities. + */ + int caps_internal; } AVHWAccel; /** diff --git a/libavcodec/hwaccel.h b/libavcodec/hwaccel.h new file mode 100644 index 0000000000000..60dbe81c8bcd8 --- /dev/null +++ b/libavcodec/hwaccel.h @@ -0,0 +1,24 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_HWACCEL_H +#define AVCODEC_HWACCEL_H + +#define HWACCEL_CAP_ASYNC_SAFE (1 << 0) + +#endif /* AVCODEC_HWACCEL_H */ diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index fd35456f59c57..f3a74c0bd84da 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -34,6 +34,7 @@ #endif #include "avcodec.h" +#include "hwaccel.h" #include "internal.h" #include "pthread_internal.h" #include "thread.h" @@ -101,6 +102,7 @@ typedef struct PerThreadContext { int die; ///< Set when the thread should exit. int hwaccel_serializing; + int async_serializing; } PerThreadContext; /** @@ -116,6 +118,7 @@ typedef struct FrameThreadContext { * is used. */ pthread_mutex_t hwaccel_mutex; + pthread_mutex_t async_mutex; int next_decoding; ///< The next context to submit a packet to. int next_finished; ///< The next context to return output from. @@ -191,6 +194,11 @@ static attribute_align_arg void *frame_worker_thread(void *arg) pthread_mutex_unlock(&p->parent->hwaccel_mutex); } + if (p->async_serializing) { + p->async_serializing = 0; + pthread_mutex_unlock(&p->parent->async_mutex); + } + atomic_store(&p->state, STATE_INPUT_READY); pthread_mutex_lock(&p->progress_mutex); @@ -414,7 +422,11 @@ int ff_thread_decode_frame(AVCodecContext *avctx, FrameThreadContext *fctx = avctx->internal->thread_ctx; int finished = fctx->next_finished; PerThreadContext *p; - int err; + int err, ret; + + /* release the async lock, permitting blocked hwaccel threads to + * go forward while we are in this function */ + pthread_mutex_unlock(&fctx->async_mutex); /* * Submit a packet to the next decoding thread. @@ -422,9 +434,11 @@ int ff_thread_decode_frame(AVCodecContext *avctx, p = &fctx->threads[fctx->next_decoding]; err = update_context_from_user(p->avctx, avctx); - if (err) return err; + if (err) + goto finish; err = submit_packet(p, avpkt); - if (err) return err; + if (err) + goto finish; /* * If we're still receiving the initial packets, don't return a frame. @@ -434,8 +448,10 @@ int ff_thread_decode_frame(AVCodecContext *avctx, if (fctx->next_decoding >= (avctx->thread_count-1)) fctx->delaying = 0; *got_picture_ptr=0; - if (avpkt->size) - return avpkt->size; + if (avpkt->size) { + ret = avpkt->size; + goto finish; + } } /* @@ -477,7 +493,12 @@ int ff_thread_decode_frame(AVCodecContext *avctx, fctx->next_finished = finished; /* return the size of the consumed packet if no error occurred */ - return (p->result >= 0) ? avpkt->size : p->result; + ret = (p->result >= 0) ? avpkt->size : p->result; +finish: + pthread_mutex_lock(&fctx->async_mutex); + if (err < 0) + return err; + return ret; } void ff_thread_report_progress(ThreadFrame *f, int n, int field) @@ -532,6 +553,13 @@ void ff_thread_finish_setup(AVCodecContext *avctx) { p->hwaccel_serializing = 1; } + /* this assumes that no hwaccel calls happen before ff_thread_finish_setup() */ + if (avctx->hwaccel && + !(avctx->hwaccel->caps_internal & HWACCEL_CAP_ASYNC_SAFE)) { + p->async_serializing = 1; + pthread_mutex_lock(&p->parent->async_mutex); + } + pthread_mutex_lock(&p->progress_mutex); atomic_store(&p->state, STATE_SETUP_FINISHED); @@ -545,6 +573,8 @@ static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count { int i; + pthread_mutex_unlock(&fctx->async_mutex); + for (i = 0; i < thread_count; i++) { PerThreadContext *p = &fctx->threads[i]; @@ -555,6 +585,8 @@ static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count pthread_mutex_unlock(&p->progress_mutex); } } + + pthread_mutex_lock(&fctx->async_mutex); } void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) @@ -613,6 +645,10 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) av_freep(&fctx->threads); pthread_mutex_destroy(&fctx->buffer_mutex); pthread_mutex_destroy(&fctx->hwaccel_mutex); + + pthread_mutex_unlock(&fctx->async_mutex); + pthread_mutex_destroy(&fctx->async_mutex); + av_freep(&avctx->internal->thread_ctx); } @@ -655,6 +691,10 @@ int ff_frame_thread_init(AVCodecContext *avctx) pthread_mutex_init(&fctx->buffer_mutex, NULL); pthread_mutex_init(&fctx->hwaccel_mutex, NULL); + + pthread_mutex_init(&fctx->async_mutex, NULL); + pthread_mutex_lock(&fctx->async_mutex); + fctx->delaying = 1; for (i = 0; i < thread_count; i++) { diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c index 7d8dc34d635a3..f765523005a11 100644 --- a/libavcodec/vaapi_h264.c +++ b/libavcodec/vaapi_h264.c @@ -22,6 +22,7 @@ #include "h264dec.h" #include "h264_ps.h" +#include "hwaccel.h" #include "vaapi_decode.h" /** @@ -399,4 +400,5 @@ AVHWAccel ff_h264_vaapi_hwaccel = { .init = &ff_vaapi_decode_init, .uninit = &ff_vaapi_decode_uninit, .priv_data_size = sizeof(VAAPIDecodeContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; diff --git a/libavcodec/vaapi_mpeg2.c b/libavcodec/vaapi_mpeg2.c index 6c10578b9d4d5..a14d115fb065a 100644 --- a/libavcodec/vaapi_mpeg2.c +++ b/libavcodec/vaapi_mpeg2.c @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "hwaccel.h" #include "mpegutils.h" #include "mpegvideo.h" #include "internal.h" @@ -184,4 +185,5 @@ AVHWAccel ff_mpeg2_vaapi_hwaccel = { .init = &ff_vaapi_decode_init, .uninit = &ff_vaapi_decode_uninit, .priv_data_size = sizeof(VAAPIDecodeContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; diff --git a/libavcodec/vaapi_mpeg4.c b/libavcodec/vaapi_mpeg4.c index 4413cbfe34ac1..b4819b804f4ae 100644 --- a/libavcodec/vaapi_mpeg4.c +++ b/libavcodec/vaapi_mpeg4.c @@ -21,6 +21,7 @@ */ #include "h263.h" +#include "hwaccel.h" #include "internal.h" #include "mpeg4video.h" #include "mpegvideo.h" @@ -200,6 +201,7 @@ AVHWAccel ff_mpeg4_vaapi_hwaccel = { .init = &ff_vaapi_decode_init, .uninit = &ff_vaapi_decode_uninit, .priv_data_size = sizeof(VAAPIDecodeContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; #endif @@ -216,5 +218,6 @@ AVHWAccel ff_h263_vaapi_hwaccel = { .init = &ff_vaapi_decode_init, .uninit = &ff_vaapi_decode_uninit, .priv_data_size = sizeof(VAAPIDecodeContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; #endif diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c index fe1a20fcbb990..42634f2baf4b6 100644 --- a/libavcodec/vaapi_vc1.c +++ b/libavcodec/vaapi_vc1.c @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "hwaccel.h" #include "internal.h" #include "vaapi_decode.h" #include "vc1.h" @@ -399,6 +400,7 @@ AVHWAccel ff_wmv3_vaapi_hwaccel = { .init = &ff_vaapi_decode_init, .uninit = &ff_vaapi_decode_uninit, .priv_data_size = sizeof(VAAPIDecodeContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; #endif @@ -414,4 +416,5 @@ AVHWAccel ff_vc1_vaapi_hwaccel = { .init = &ff_vaapi_decode_init, .uninit = &ff_vaapi_decode_uninit, .priv_data_size = sizeof(VAAPIDecodeContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; diff --git a/libavcodec/vaapi_vp8.c b/libavcodec/vaapi_vp8.c index 70e9cec3d4ecf..1ba5c7ec94172 100644 --- a/libavcodec/vaapi_vp8.c +++ b/libavcodec/vaapi_vp8.c @@ -19,6 +19,7 @@ #include #include +#include "hwaccel.h" #include "vaapi_decode.h" #include "vp8.h" @@ -231,4 +232,5 @@ AVHWAccel ff_vp8_vaapi_hwaccel = { .init = &ff_vaapi_decode_init, .uninit = &ff_vaapi_decode_uninit, .priv_data_size = sizeof(VAAPIDecodeContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; diff --git a/libavcodec/vdpau_h264.c b/libavcodec/vdpau_h264.c index 3e13b7616083e..a18941848a281 100644 --- a/libavcodec/vdpau_h264.c +++ b/libavcodec/vdpau_h264.c @@ -27,6 +27,7 @@ #include "internal.h" #include "h264dec.h" #include "h264_ps.h" +#include "hwaccel.h" #include "mpegutils.h" #include "vdpau.h" #include "vdpau_internal.h" @@ -273,4 +274,5 @@ AVHWAccel ff_h264_vdpau_hwaccel = { .init = vdpau_h264_init, .uninit = ff_vdpau_common_uninit, .priv_data_size = sizeof(VDPAUContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; diff --git a/libavcodec/vdpau_hevc.c b/libavcodec/vdpau_hevc.c index 829945614c9f4..399253e2975f4 100644 --- a/libavcodec/vdpau_hevc.c +++ b/libavcodec/vdpau_hevc.c @@ -26,6 +26,7 @@ #include "internal.h" #include "hevc_data.h" #include "hevcdec.h" +#include "hwaccel.h" #include "vdpau.h" #include "vdpau_internal.h" @@ -424,4 +425,5 @@ AVHWAccel ff_hevc_vdpau_hwaccel = { .init = vdpau_hevc_init, .uninit = ff_vdpau_common_uninit, .priv_data_size = sizeof(VDPAUContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; diff --git a/libavcodec/vdpau_mpeg12.c b/libavcodec/vdpau_mpeg12.c index cb6f81a76d972..2af3201e9560b 100644 --- a/libavcodec/vdpau_mpeg12.c +++ b/libavcodec/vdpau_mpeg12.c @@ -24,6 +24,7 @@ #include #include "avcodec.h" +#include "hwaccel.h" #include "mpegvideo.h" #include "vdpau.h" #include "vdpau_internal.h" @@ -114,6 +115,7 @@ AVHWAccel ff_mpeg1_vdpau_hwaccel = { .init = vdpau_mpeg1_init, .uninit = ff_vdpau_common_uninit, .priv_data_size = sizeof(VDPAUContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; #endif @@ -148,5 +150,6 @@ AVHWAccel ff_mpeg2_vdpau_hwaccel = { .init = vdpau_mpeg2_init, .uninit = ff_vdpau_common_uninit, .priv_data_size = sizeof(VDPAUContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; #endif diff --git a/libavcodec/vdpau_mpeg4.c b/libavcodec/vdpau_mpeg4.c index fcad42f0a45d3..4f3d6e54484b1 100644 --- a/libavcodec/vdpau_mpeg4.c +++ b/libavcodec/vdpau_mpeg4.c @@ -24,6 +24,7 @@ #include #include "avcodec.h" +#include "hwaccel.h" #include "mpeg4video.h" #include "vdpau.h" #include "vdpau_internal.h" @@ -118,4 +119,5 @@ AVHWAccel ff_mpeg4_vdpau_hwaccel = { .init = vdpau_mpeg4_init, .uninit = ff_vdpau_common_uninit, .priv_data_size = sizeof(VDPAUContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; diff --git a/libavcodec/vdpau_vc1.c b/libavcodec/vdpau_vc1.c index 4f87c52ecc99d..251d1aae5d674 100644 --- a/libavcodec/vdpau_vc1.c +++ b/libavcodec/vdpau_vc1.c @@ -24,6 +24,7 @@ #include #include "avcodec.h" +#include "hwaccel.h" #include "vc1.h" #include "vdpau.h" #include "vdpau_internal.h" @@ -143,6 +144,7 @@ AVHWAccel ff_wmv3_vdpau_hwaccel = { .init = vdpau_vc1_init, .uninit = ff_vdpau_common_uninit, .priv_data_size = sizeof(VDPAUContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; #endif @@ -158,4 +160,5 @@ AVHWAccel ff_vc1_vdpau_hwaccel = { .init = vdpau_vc1_init, .uninit = ff_vdpau_common_uninit, .priv_data_size = sizeof(VDPAUContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; diff --git a/libavcodec/version.h b/libavcodec/version.h index adab9b47a3446..3756275086abe 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 30 -#define LIBAVCODEC_VERSION_MICRO 0 +#define LIBAVCODEC_VERSION_MICRO 1 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From 1783d7ec03d730c5bd96c07bc5fa7aa566f85c66 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 15 Dec 2016 10:23:26 +0100 Subject: [PATCH 0727/3374] Changelog: add some missing entries --- Changelog | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Changelog b/Changelog index feb151cf3cb96..ab7f1b6bb0d70 100644 --- a/Changelog +++ b/Changelog @@ -3,6 +3,9 @@ releases are sorted from youngest to oldest. version : - Support for spherical videos +- Intel QSV-accelerated VP8 and VC-1 decoding +- VAAPI-accelerated VP8 decoding +- VAAPI-accelerated deinterlacing version 12: From ea8b730d8e67152107d7fcdd5590bbb51ec236b1 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 2 Oct 2016 08:51:32 +0200 Subject: [PATCH 0728/3374] hevcdec: add a VAAPI hwaccel Partially based on a patch by Timo Rothenpieler . Additional scaling list handling fix by Jun Zhao . --- Changelog | 2 +- configure | 3 + libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/hevcdec.c | 6 +- libavcodec/vaapi_decode.c | 1 + libavcodec/vaapi_hevc.c | 439 ++++++++++++++++++++++++++++++++++++++ libavcodec/version.h | 2 +- 8 files changed, 452 insertions(+), 3 deletions(-) create mode 100644 libavcodec/vaapi_hevc.c diff --git a/Changelog b/Changelog index ab7f1b6bb0d70..e17ef204a6c5e 100644 --- a/Changelog +++ b/Changelog @@ -4,7 +4,7 @@ releases are sorted from youngest to oldest. version : - Support for spherical videos - Intel QSV-accelerated VP8 and VC-1 decoding -- VAAPI-accelerated VP8 decoding +- VAAPI-accelerated VP8 and HEVC decoding - VAAPI-accelerated deinterlacing diff --git a/configure b/configure index 365bbb2bf293d..d30d38445e14f 100755 --- a/configure +++ b/configure @@ -2157,6 +2157,8 @@ hevc_d3d11va_hwaccel_select="hevc_decoder" hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC" hevc_dxva2_hwaccel_select="hevc_decoder" hevc_qsv_hwaccel_deps="libmfx" +hevc_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferHEVC" +hevc_vaapi_hwaccel_select="hevc_decoder" hevc_vdpau_hwaccel_deps="vdpau VdpPictureInfoHEVC" hevc_vdpau_hwaccel_select="hevc_decoder" mpeg1_vdpau_hwaccel_deps="vdpau" @@ -4569,6 +4571,7 @@ check_type "windows.h dxva.h" "DXVA_PicParams_HEVC" -DWINAPI_FAMILY=WINAPI_FAMIL check_type "windows.h d3d11.h" "ID3D11VideoDecoder" check_type "d3d9.h dxva2api.h" DXVA2_ConfigPictureDecode -D_WIN32_WINNT=0x0602 +check_type "va/va.h va/va_dec_hevc.h" "VAPictureParameterBufferHEVC" check_type "va/va.h va/va_dec_vp8.h" "VAPictureParameterBufferVP8" check_type "va/va.h va/va_vpp.h" "VAProcPipelineParameterBuffer" check_type "va/va.h va/va_enc_h264.h" "VAEncPictureParameterBufferH264" diff --git a/libavcodec/Makefile b/libavcodec/Makefile index f07253a84db3c..239a4c0f0a3fa 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -629,6 +629,7 @@ OBJS-$(CONFIG_H264_VDPAU_HWACCEL) += vdpau_h264.o OBJS-$(CONFIG_HEVC_D3D11VA_HWACCEL) += dxva2_hevc.o OBJS-$(CONFIG_HEVC_DXVA2_HWACCEL) += dxva2_hevc.o OBJS-$(CONFIG_HEVC_QSV_HWACCEL) += qsvdec_h2645.o +OBJS-$(CONFIG_HEVC_VAAPI_HWACCEL) += vaapi_hevc.o OBJS-$(CONFIG_HEVC_VDPAU_HWACCEL) += vdpau_hevc.o OBJS-$(CONFIG_MPEG1_VDPAU_HWACCEL) += vdpau_mpeg12.o OBJS-$(CONFIG_MPEG2_D3D11VA_HWACCEL) += dxva2_mpeg2.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 591fd87339f8d..74cbc8ff03b18 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -79,6 +79,7 @@ void avcodec_register_all(void) REGISTER_HWACCEL(HEVC_D3D11VA, hevc_d3d11va); REGISTER_HWACCEL(HEVC_DXVA2, hevc_dxva2); REGISTER_HWACCEL(HEVC_QSV, hevc_qsv); + REGISTER_HWACCEL(HEVC_VAAPI, hevc_vaapi); REGISTER_HWACCEL(HEVC_VDPAU, hevc_vdpau); REGISTER_HWACCEL(MPEG1_VDPAU, mpeg1_vdpau); REGISTER_HWACCEL(MPEG2_D3D11VA, mpeg2_d3d11va); diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 147243e3fe527..8326690038c0b 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -382,13 +382,17 @@ static void export_stream_params(AVCodecContext *avctx, const HEVCParamSets *ps, static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) { - #define HWACCEL_MAX (CONFIG_HEVC_DXVA2_HWACCEL + CONFIG_HEVC_D3D11VA_HWACCEL + CONFIG_HEVC_VDPAU_HWACCEL) + #define HWACCEL_MAX (CONFIG_HEVC_DXVA2_HWACCEL + CONFIG_HEVC_D3D11VA_HWACCEL + \ + CONFIG_HEVC_VAAPI_HWACCEL + CONFIG_HEVC_VDPAU_HWACCEL) enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmt = pix_fmts; if (sps->pix_fmt == AV_PIX_FMT_YUV420P || sps->pix_fmt == AV_PIX_FMT_YUVJ420P || sps->pix_fmt == AV_PIX_FMT_YUV420P10) { #if CONFIG_HEVC_DXVA2_HWACCEL *fmt++ = AV_PIX_FMT_DXVA2_VLD; +#endif +#if CONFIG_HEVC_VAAPI_HWACCEL + *fmt++ = AV_PIX_FMT_VAAPI; #endif } if (sps->pix_fmt == AV_PIX_FMT_YUV420P || sps->pix_fmt == AV_PIX_FMT_YUVJ420P) { diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c index b02f2b8cf318f..88bd889515c6f 100644 --- a/libavcodec/vaapi_decode.c +++ b/libavcodec/vaapi_decode.c @@ -250,6 +250,7 @@ static const struct { MAP(H264, H264_HIGH, H264High ), #if VA_CHECK_VERSION(0, 37, 0) MAP(HEVC, HEVC_MAIN, HEVCMain ), + MAP(HEVC, HEVC_MAIN_10, HEVCMain10 ), #endif MAP(WMV3, VC1_SIMPLE, VC1Simple ), MAP(WMV3, VC1_MAIN, VC1Main ), diff --git a/libavcodec/vaapi_hevc.c b/libavcodec/vaapi_hevc.c new file mode 100644 index 0000000000000..4b4d8782acd91 --- /dev/null +++ b/libavcodec/vaapi_hevc.c @@ -0,0 +1,439 @@ +/* + * HEVC HW decode acceleration through VA API + * + * Copyright (C) 2015 Timo Rothenpieler + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "avcodec.h" +#include "hevcdec.h" +#include "hwaccel.h" +#include "vaapi_decode.h" + +typedef struct VAAPIDecodePictureHEVC { + VAPictureParameterBufferHEVC pic_param; + VASliceParameterBufferHEVC last_slice_param; + const uint8_t *last_buffer; + size_t last_size; + + VAAPIDecodePicture pic; +} VAAPIDecodePictureHEVC; + +static void init_vaapi_pic(VAPictureHEVC *va_pic) +{ + va_pic->picture_id = VA_INVALID_ID; + va_pic->flags = VA_PICTURE_HEVC_INVALID; + va_pic->pic_order_cnt = 0; +} + +static void fill_vaapi_pic(VAPictureHEVC *va_pic, const HEVCFrame *pic, int rps_type) +{ + va_pic->picture_id = ff_vaapi_get_surface_id(pic->frame); + va_pic->pic_order_cnt = pic->poc; + va_pic->flags = rps_type; + + if (pic->flags & HEVC_FRAME_FLAG_LONG_REF) + va_pic->flags |= VA_PICTURE_HEVC_LONG_TERM_REFERENCE; + + if (pic->frame->interlaced_frame) { + va_pic->flags |= VA_PICTURE_HEVC_FIELD_PIC; + + if (!pic->frame->top_field_first) + va_pic->flags |= VA_PICTURE_HEVC_BOTTOM_FIELD; + } +} + +static int find_frame_rps_type(const HEVCContext *h, const HEVCFrame *pic) +{ + VASurfaceID pic_surf = ff_vaapi_get_surface_id(pic->frame); + int i; + + for (i = 0; i < h->rps[ST_CURR_BEF].nb_refs; i++) { + if (pic_surf == ff_vaapi_get_surface_id(h->rps[ST_CURR_BEF].ref[i]->frame)) + return VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE; + } + + for (i = 0; i < h->rps[ST_CURR_AFT].nb_refs; i++) { + if (pic_surf == ff_vaapi_get_surface_id(h->rps[ST_CURR_AFT].ref[i]->frame)) + return VA_PICTURE_HEVC_RPS_ST_CURR_AFTER; + } + + for (i = 0; i < h->rps[LT_CURR].nb_refs; i++) { + if (pic_surf == ff_vaapi_get_surface_id(h->rps[LT_CURR].ref[i]->frame)) + return VA_PICTURE_HEVC_RPS_LT_CURR; + } + + return 0; +} + +static void fill_vaapi_reference_frames(const HEVCContext *h, VAPictureParameterBufferHEVC *pp) +{ + const HEVCFrame *current_picture = h->ref; + int i, j, rps_type; + + for (i = 0, j = 0; i < FF_ARRAY_ELEMS(pp->ReferenceFrames); i++) { + const HEVCFrame *frame = NULL; + + while (!frame && j < FF_ARRAY_ELEMS(h->DPB)) { + if (&h->DPB[j] != current_picture && (h->DPB[j].flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF))) + frame = &h->DPB[j]; + j++; + } + + init_vaapi_pic(&pp->ReferenceFrames[i]); + + if (frame) { + rps_type = find_frame_rps_type(h, frame); + fill_vaapi_pic(&pp->ReferenceFrames[i], frame, rps_type); + } + } +} + +static int vaapi_hevc_start_frame(AVCodecContext *avctx, + av_unused const uint8_t *buffer, + av_unused uint32_t size) +{ + const HEVCContext *h = avctx->priv_data; + VAAPIDecodePictureHEVC *pic = h->ref->hwaccel_picture_private; + const HEVCSPS *sps = h->ps.sps; + const HEVCPPS *pps = h->ps.pps; + + const ScalingList *scaling_list = NULL; + int err, i; + + pic->pic.output_surface = ff_vaapi_get_surface_id(h->ref->frame); + + pic->pic_param = (VAPictureParameterBufferHEVC) { + .pic_fields.value = 0, + .slice_parsing_fields.value = 0, + .pic_width_in_luma_samples = sps->width, + .pic_height_in_luma_samples = sps->height, + .log2_min_luma_coding_block_size_minus3 = sps->log2_min_cb_size - 3, + .sps_max_dec_pic_buffering_minus1 = sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering - 1, + .log2_diff_max_min_luma_coding_block_size = sps->log2_diff_max_min_coding_block_size, + .log2_min_transform_block_size_minus2 = sps->log2_min_tb_size - 2, + .log2_diff_max_min_transform_block_size = sps->log2_max_trafo_size - sps->log2_min_tb_size, + .max_transform_hierarchy_depth_inter = sps->max_transform_hierarchy_depth_inter, + .max_transform_hierarchy_depth_intra = sps->max_transform_hierarchy_depth_intra, + .num_short_term_ref_pic_sets = sps->nb_st_rps, + .num_long_term_ref_pic_sps = sps->num_long_term_ref_pics_sps, + .num_ref_idx_l0_default_active_minus1 = pps->num_ref_idx_l0_default_active - 1, + .num_ref_idx_l1_default_active_minus1 = pps->num_ref_idx_l1_default_active - 1, + .init_qp_minus26 = pps->pic_init_qp_minus26, + .pps_cb_qp_offset = pps->cb_qp_offset, + .pps_cr_qp_offset = pps->cr_qp_offset, + .pcm_sample_bit_depth_luma_minus1 = sps->pcm.bit_depth - 1, + .pcm_sample_bit_depth_chroma_minus1 = sps->pcm.bit_depth_chroma - 1, + .log2_min_pcm_luma_coding_block_size_minus3 = sps->pcm.log2_min_pcm_cb_size - 3, + .log2_diff_max_min_pcm_luma_coding_block_size = sps->pcm.log2_max_pcm_cb_size - sps->pcm.log2_min_pcm_cb_size, + .diff_cu_qp_delta_depth = pps->diff_cu_qp_delta_depth, + .pps_beta_offset_div2 = pps->beta_offset / 2, + .pps_tc_offset_div2 = pps->tc_offset / 2, + .log2_parallel_merge_level_minus2 = pps->log2_parallel_merge_level - 2, + .bit_depth_luma_minus8 = sps->bit_depth - 8, + .bit_depth_chroma_minus8 = sps->bit_depth - 8, + .log2_max_pic_order_cnt_lsb_minus4 = sps->log2_max_poc_lsb - 4, + .num_extra_slice_header_bits = pps->num_extra_slice_header_bits, + .pic_fields.bits = { + .chroma_format_idc = sps->chroma_format_idc, + .tiles_enabled_flag = pps->tiles_enabled_flag, + .separate_colour_plane_flag = sps->separate_colour_plane_flag, + .pcm_enabled_flag = sps->pcm_enabled_flag, + .scaling_list_enabled_flag = sps->scaling_list_enable_flag, + .transform_skip_enabled_flag = pps->transform_skip_enabled_flag, + .amp_enabled_flag = sps->amp_enabled_flag, + .strong_intra_smoothing_enabled_flag = sps->sps_strong_intra_smoothing_enable_flag, + .sign_data_hiding_enabled_flag = pps->sign_data_hiding_flag, + .constrained_intra_pred_flag = pps->constrained_intra_pred_flag, + .cu_qp_delta_enabled_flag = pps->cu_qp_delta_enabled_flag, + .weighted_pred_flag = pps->weighted_pred_flag, + .weighted_bipred_flag = pps->weighted_bipred_flag, + .transquant_bypass_enabled_flag = pps->transquant_bypass_enable_flag, + .entropy_coding_sync_enabled_flag = pps->entropy_coding_sync_enabled_flag, + .pps_loop_filter_across_slices_enabled_flag = pps->seq_loop_filter_across_slices_enabled_flag, + .loop_filter_across_tiles_enabled_flag = pps->loop_filter_across_tiles_enabled_flag, + .pcm_loop_filter_disabled_flag = sps->pcm.loop_filter_disable_flag, + }, + .slice_parsing_fields.bits = { + .lists_modification_present_flag = pps->lists_modification_present_flag, + .long_term_ref_pics_present_flag = sps->long_term_ref_pics_present_flag, + .sps_temporal_mvp_enabled_flag = sps->sps_temporal_mvp_enabled_flag, + .cabac_init_present_flag = pps->cabac_init_present_flag, + .output_flag_present_flag = pps->output_flag_present_flag, + .dependent_slice_segments_enabled_flag = pps->dependent_slice_segments_enabled_flag, + .pps_slice_chroma_qp_offsets_present_flag = pps->pic_slice_level_chroma_qp_offsets_present_flag, + .sample_adaptive_offset_enabled_flag = sps->sao_enabled, + .deblocking_filter_override_enabled_flag = pps->deblocking_filter_override_enabled_flag, + .pps_disable_deblocking_filter_flag = pps->disable_dbf, + .slice_segment_header_extension_present_flag = pps->slice_header_extension_present_flag, + .RapPicFlag = IS_IRAP(h), + .IdrPicFlag = IS_IDR(h), + .IntraPicFlag = IS_IRAP(h), + }, + }; + + fill_vaapi_pic(&pic->pic_param.CurrPic, h->ref, 0); + fill_vaapi_reference_frames(h, &pic->pic_param); + + if (pps->tiles_enabled_flag) { + pic->pic_param.num_tile_columns_minus1 = pps->num_tile_columns - 1; + pic->pic_param.num_tile_rows_minus1 = pps->num_tile_rows - 1; + + for (i = 0; i < pps->num_tile_columns; i++) + pic->pic_param.column_width_minus1[i] = pps->column_width[i] - 1; + + for (i = 0; i < pps->num_tile_rows; i++) + pic->pic_param.row_height_minus1[i] = pps->row_height[i] - 1; + } + + if (h->sh.short_term_ref_pic_set_sps_flag == 0 && h->sh.short_term_rps) { + pic->pic_param.st_rps_bits = h->sh.short_term_ref_pic_set_size; + } else { + pic->pic_param.st_rps_bits = 0; + } + + err = ff_vaapi_decode_make_param_buffer(avctx, &pic->pic, + VAPictureParameterBufferType, + &pic->pic_param, sizeof(pic->pic_param)); + if (err < 0) + goto fail; + + if (pps->scaling_list_data_present_flag) + scaling_list = &pps->scaling_list; + else if (sps->scaling_list_enable_flag) + scaling_list = &sps->scaling_list; + + if (scaling_list) { + VAIQMatrixBufferHEVC iq_matrix; + int j; + + for (i = 0; i < 6; i++) { + for (j = 0; j < 16; j++) + iq_matrix.ScalingList4x4[i][j] = scaling_list->sl[0][i][j]; + for (j = 0; j < 64; j++) { + iq_matrix.ScalingList8x8[i][j] = scaling_list->sl[1][i][j]; + iq_matrix.ScalingList16x16[i][j] = scaling_list->sl[2][i][j]; + if (i < 2) + iq_matrix.ScalingList32x32[i][j] = scaling_list->sl[3][i][j]; + } + iq_matrix.ScalingListDC16x16[i] = scaling_list->sl_dc[0][i]; + if (i < 2) + iq_matrix.ScalingListDC32x32[i] = scaling_list->sl_dc[1][i]; + } + + err = ff_vaapi_decode_make_param_buffer(avctx, &pic->pic, + VAIQMatrixBufferType, + &iq_matrix, sizeof(iq_matrix)); + if (err < 0) + goto fail; + } + + return 0; + +fail: + ff_vaapi_decode_cancel(avctx, &pic->pic); + return err; +} + +static int vaapi_hevc_end_frame(AVCodecContext *avctx) +{ + const HEVCContext *h = avctx->priv_data; + VAAPIDecodePictureHEVC *pic = h->ref->hwaccel_picture_private; + int ret; + + if (pic->last_size) { + pic->last_slice_param.LongSliceFlags.fields.LastSliceOfPic = 1; + ret = ff_vaapi_decode_make_slice_buffer(avctx, &pic->pic, + &pic->last_slice_param, sizeof(pic->last_slice_param), + pic->last_buffer, pic->last_size); + if (ret < 0) + goto fail; + } + + + ret = ff_vaapi_decode_issue(avctx, &pic->pic); + if (ret < 0) + goto fail; + + return 0; +fail: + ff_vaapi_decode_cancel(avctx, &pic->pic); + return ret; +} + +static void fill_pred_weight_table(const HEVCContext *h, + const SliceHeader *sh, + VASliceParameterBufferHEVC *slice_param) +{ + int i; + + memset(slice_param->delta_luma_weight_l0, 0, sizeof(slice_param->delta_luma_weight_l0)); + memset(slice_param->delta_luma_weight_l1, 0, sizeof(slice_param->delta_luma_weight_l1)); + memset(slice_param->luma_offset_l0, 0, sizeof(slice_param->luma_offset_l0)); + memset(slice_param->luma_offset_l1, 0, sizeof(slice_param->luma_offset_l1)); + memset(slice_param->delta_chroma_weight_l0, 0, sizeof(slice_param->delta_chroma_weight_l0)); + memset(slice_param->delta_chroma_weight_l1, 0, sizeof(slice_param->delta_chroma_weight_l1)); + memset(slice_param->ChromaOffsetL0, 0, sizeof(slice_param->ChromaOffsetL0)); + memset(slice_param->ChromaOffsetL1, 0, sizeof(slice_param->ChromaOffsetL1)); + + slice_param->delta_chroma_log2_weight_denom = 0; + slice_param->luma_log2_weight_denom = 0; + + if (sh->slice_type == HEVC_SLICE_I || + (sh->slice_type == HEVC_SLICE_P && !h->ps.pps->weighted_pred_flag) || + (sh->slice_type == HEVC_SLICE_B && !h->ps.pps->weighted_bipred_flag)) + return; + + slice_param->luma_log2_weight_denom = sh->luma_log2_weight_denom; + + if (h->ps.sps->chroma_format_idc) { + slice_param->delta_chroma_log2_weight_denom = sh->chroma_log2_weight_denom - sh->luma_log2_weight_denom; + } + + for (i = 0; i < 15 && i < sh->nb_refs[L0]; i++) { + slice_param->delta_luma_weight_l0[i] = sh->luma_weight_l0[i] - (1 << sh->luma_log2_weight_denom); + slice_param->luma_offset_l0[i] = sh->luma_offset_l0[i]; + slice_param->delta_chroma_weight_l0[i][0] = sh->chroma_weight_l0[i][0] - (1 << sh->chroma_log2_weight_denom); + slice_param->delta_chroma_weight_l0[i][1] = sh->chroma_weight_l0[i][1] - (1 << sh->chroma_log2_weight_denom); + slice_param->ChromaOffsetL0[i][0] = sh->chroma_offset_l0[i][0]; + slice_param->ChromaOffsetL0[i][1] = sh->chroma_offset_l0[i][1]; + } + + if (sh->slice_type == HEVC_SLICE_B) { + for (i = 0; i < 15 && i < sh->nb_refs[L1]; i++) { + slice_param->delta_luma_weight_l1[i] = sh->luma_weight_l1[i] - (1 << sh->luma_log2_weight_denom); + slice_param->luma_offset_l1[i] = sh->luma_offset_l1[i]; + slice_param->delta_chroma_weight_l1[i][0] = sh->chroma_weight_l1[i][0] - (1 << sh->chroma_log2_weight_denom); + slice_param->delta_chroma_weight_l1[i][1] = sh->chroma_weight_l1[i][1] - (1 << sh->chroma_log2_weight_denom); + slice_param->ChromaOffsetL1[i][0] = sh->chroma_offset_l1[i][0]; + slice_param->ChromaOffsetL1[i][1] = sh->chroma_offset_l1[i][1]; + } + } +} + +static uint8_t get_ref_pic_index(const HEVCContext *h, const HEVCFrame *frame) +{ + VAAPIDecodePictureHEVC *pic = h->ref->hwaccel_picture_private; + VAPictureParameterBufferHEVC *pp = &pic->pic_param; + uint8_t i; + + if (!frame) + return 0xff; + + for (i = 0; i < FF_ARRAY_ELEMS(pp->ReferenceFrames); i++) { + VASurfaceID pid = pp->ReferenceFrames[i].picture_id; + int poc = pp->ReferenceFrames[i].pic_order_cnt; + if (pid != VA_INVALID_ID && pid == ff_vaapi_get_surface_id(frame->frame) && poc == frame->poc) + return i; + } + + return 0xff; +} + +static int vaapi_hevc_decode_slice(AVCodecContext *avctx, + const uint8_t *buffer, + uint32_t size) +{ + const HEVCContext *h = avctx->priv_data; + const SliceHeader *sh = &h->sh; + VAAPIDecodePictureHEVC *pic = h->ref->hwaccel_picture_private; + + int nb_list = (sh->slice_type == HEVC_SLICE_B) ? + 2 : (sh->slice_type == HEVC_SLICE_I ? 0 : 1); + + int err, i, list_idx; + + if (!sh->first_slice_in_pic_flag) { + err = ff_vaapi_decode_make_slice_buffer(avctx, &pic->pic, + &pic->last_slice_param, sizeof(pic->last_slice_param), + pic->last_buffer, pic->last_size); + pic->last_buffer = NULL; + pic->last_size = 0; + if (err) { + ff_vaapi_decode_cancel(avctx, &pic->pic); + return err; + } + } + + pic->last_slice_param = (VASliceParameterBufferHEVC) { + .slice_data_size = size, + .slice_data_offset = 0, + .slice_data_flag = VA_SLICE_DATA_FLAG_ALL, + /* Add 1 to the bits count here to account for the byte_alignment bit, which + * always is at least one bit and not accounted for otherwise. */ + .slice_data_byte_offset = (get_bits_count(&h->HEVClc.gb) + 1 + 7) / 8, + .slice_segment_address = sh->slice_segment_addr, + .slice_qp_delta = sh->slice_qp_delta, + .slice_cb_qp_offset = sh->slice_cb_qp_offset, + .slice_cr_qp_offset = sh->slice_cr_qp_offset, + .slice_beta_offset_div2 = sh->beta_offset / 2, + .slice_tc_offset_div2 = sh->tc_offset / 2, + .collocated_ref_idx = sh->slice_temporal_mvp_enabled_flag ? sh->collocated_ref_idx : 0xFF, + .five_minus_max_num_merge_cand = sh->slice_type == HEVC_SLICE_I ? 0 : 5 - sh->max_num_merge_cand, + .num_ref_idx_l0_active_minus1 = sh->nb_refs[L0] ? sh->nb_refs[L0] - 1 : 0, + .num_ref_idx_l1_active_minus1 = sh->nb_refs[L1] ? sh->nb_refs[L1] - 1 : 0, + + .LongSliceFlags.fields = { + .dependent_slice_segment_flag = sh->dependent_slice_segment_flag, + .slice_type = sh->slice_type, + .color_plane_id = sh->colour_plane_id, + .mvd_l1_zero_flag = sh->mvd_l1_zero_flag, + .cabac_init_flag = sh->cabac_init_flag, + .slice_temporal_mvp_enabled_flag = sh->slice_temporal_mvp_enabled_flag, + .slice_deblocking_filter_disabled_flag = sh->disable_deblocking_filter_flag, + .collocated_from_l0_flag = sh->collocated_list == L0 ? 1 : 0, + .slice_loop_filter_across_slices_enabled_flag = sh->slice_loop_filter_across_slices_enabled_flag, + .slice_sao_luma_flag = sh->slice_sample_adaptive_offset_flag[0], + .slice_sao_chroma_flag = sh->slice_sample_adaptive_offset_flag[1], + }, + }; + + memset(pic->last_slice_param.RefPicList, 0xFF, sizeof(pic->last_slice_param.RefPicList)); + + for (list_idx = 0; list_idx < nb_list; list_idx++) { + RefPicList *rpl = &h->ref->refPicList[list_idx]; + + for (i = 0; i < rpl->nb_refs; i++) + pic->last_slice_param.RefPicList[list_idx][i] = get_ref_pic_index(h, rpl->ref[i]); + } + + fill_pred_weight_table(h, sh, &pic->last_slice_param); + + pic->last_buffer = buffer; + pic->last_size = size; + + return 0; +} + +AVHWAccel ff_hevc_vaapi_hwaccel = { + .name = "hevc_vaapi", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_HEVC, + .pix_fmt = AV_PIX_FMT_VAAPI, + .start_frame = vaapi_hevc_start_frame, + .end_frame = vaapi_hevc_end_frame, + .decode_slice = vaapi_hevc_decode_slice, + .frame_priv_data_size = sizeof(VAAPIDecodePictureHEVC), + .init = ff_vaapi_decode_init, + .uninit = ff_vaapi_decode_uninit, + .priv_data_size = sizeof(VAAPIDecodeContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, +}; diff --git a/libavcodec/version.h b/libavcodec/version.h index 3756275086abe..5b6fb6ce592ba 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 30 -#define LIBAVCODEC_VERSION_MICRO 1 +#define LIBAVCODEC_VERSION_MICRO 2 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From cfa4eb4fba782f3f37a33be997b27a91a07053c9 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 19 Dec 2016 08:13:28 +0100 Subject: [PATCH 0729/3374] vaapi_decode: use the correct logging context --- libavcodec/vaapi_decode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c index 88bd889515c6f..42f03ab1414cf 100644 --- a/libavcodec/vaapi_decode.c +++ b/libavcodec/vaapi_decode.c @@ -306,7 +306,7 @@ static int vaapi_decode_make_config(AVCodecContext *avctx) vas = vaQueryConfigProfiles(ctx->hwctx->display, profile_list, &profile_count); if (vas != VA_STATUS_SUCCESS) { - av_log(ctx, AV_LOG_ERROR, "Failed to query profiles: " + av_log(avctx, AV_LOG_ERROR, "Failed to query profiles: " "%d (%s).\n", vas, vaErrorStr(vas)); err = AVERROR(ENOSYS); goto fail; @@ -338,7 +338,7 @@ static int vaapi_decode_make_config(AVCodecContext *avctx) av_freep(&profile_list); if (profile == VAProfileNone) { - av_log(ctx, AV_LOG_ERROR, "No support for codec %s " + av_log(avctx, AV_LOG_ERROR, "No support for codec %s " "profile %d.\n", codec_desc->name, avctx->profile); err = AVERROR(ENOSYS); goto fail; @@ -390,7 +390,7 @@ static int vaapi_decode_make_config(AVCodecContext *avctx) avctx->coded_height < constraints->min_height || avctx->coded_width > constraints->max_width || avctx->coded_height > constraints->max_height) { - av_log(ctx, AV_LOG_ERROR, "Hardware does not support image " + av_log(avctx, AV_LOG_ERROR, "Hardware does not support image " "size %dx%d (constraints: width %d-%d height %d-%d).\n", avctx->coded_width, avctx->coded_height, constraints->min_width, constraints->max_width, From 46191a2da16f751e53d93646ae1388d421d12bee Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 17 Dec 2016 14:17:20 +0100 Subject: [PATCH 0730/3374] mov: fix a possible invalid read in mov_read_mac_string() When the input string is too large, so the second condition in if () fails, the code will erroneously execute the else branch, indexing the mac_to_unicode table with a negative index. CC: libav-stable@libav.org Bug-Id: 1000 Found-By: Kamil Frankowicz --- libavformat/mov.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 7fe639dd5ed2f..ed10a15625168 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -161,7 +161,11 @@ static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len, for (i = 0; i < len; i++) { uint8_t t, c = avio_r8(pb); - if (c < 0x80 && p < end) + + if (p >= end) + continue; + + if (c < 0x80) *p++ = c; else PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;); From 58405de0951a843765625159402870c1eea3c3b1 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 17 Dec 2016 15:07:51 +0100 Subject: [PATCH 0731/3374] mpegvideo_parser: avoid signed overflow in bitrate calculation CC: libav-stable@libav.org Bug-Id: 981 Found-By: Agostino Sarubbo --- libavcodec/mpegvideo_parser.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libavcodec/mpegvideo_parser.c b/libavcodec/mpegvideo_parser.c index 27f2985509c0a..500d1240efa1f 100644 --- a/libavcodec/mpegvideo_parser.c +++ b/libavcodec/mpegvideo_parser.c @@ -97,7 +97,14 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s, pc->width |=(horiz_size_ext << 12); pc->height |=( vert_size_ext << 12); - avctx->bit_rate += (bit_rate_ext << 18) * 400; + + bit_rate_ext <<= 18; + if (bit_rate_ext < INT_MAX / 400 && + bit_rate_ext * 400 < INT_MAX - avctx->bit_rate) { + avctx->bit_rate += bit_rate_ext * 400; + } else + avctx->bit_rate = 0; + if(did_set_size) ff_set_dimensions(avctx, pc->width, pc->height); avctx->framerate.num = pc->frame_rate.num * (frame_rate_ext_n + 1) * 2; From e807491fc6a336e4becc0cbc981274a8fde18aba Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 17 Dec 2016 15:07:51 +0100 Subject: [PATCH 0732/3374] mpeg12dec: avoid signed overflow in bitrate calculation CC: libav-stable@libav.org Bug-Id: 981 Found-By: Agostino Sarubbo --- libavcodec/mpeg12dec.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c index 2d9c99d63fa62..310169becc0ef 100644 --- a/libavcodec/mpeg12dec.c +++ b/libavcodec/mpeg12dec.c @@ -1358,8 +1358,17 @@ static void mpeg_decode_sequence_extension(Mpeg1Context *s1) vert_size_ext = get_bits(&s->gb, 2); s->width |= (horiz_size_ext << 12); s->height |= (vert_size_ext << 12); - bit_rate_ext = get_bits(&s->gb, 12); /* XXX: handle it */ - s->bit_rate += (bit_rate_ext << 18) * 400; + + bit_rate_ext = get_bits(&s->gb, 12) << 18; + if (bit_rate_ext < INT_MAX / 400 && + bit_rate_ext * 400 < INT_MAX - s->bit_rate) { + s->bit_rate += bit_rate_ext * 400; + } else { + av_log(s->avctx, AV_LOG_WARNING, "Invalid bit rate extension value: %d\n", + bit_rate_ext >> 18); + s->bit_rate = 0; + } + skip_bits1(&s->gb); /* marker */ s->avctx->rc_buffer_size += get_bits(&s->gb, 8) * 1024 * 16 << 10; From c2fa6bb0e8703a7a6aa10e11f9ab36094416d83f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 17 Dec 2016 17:04:55 +0100 Subject: [PATCH 0733/3374] mpeg12dec: move setting first_field to mpeg_field_start() For field picture, the first_field is set based on its previous value. Before this commit, first_field is set when reading the picture coding extension. However, in corrupted files there may be multiple picture coding extension headers, so the final value of first_field that is actually used during decoding can be wrong. That can lead to various undefined behaviour, like predicting from a non-existing field. Fix this problem, by setting first_field in mpeg_field_start(), which should be called exactly once per field. CC: libav-stable@libav.org Bug-ID: 999 --- libavcodec/mpeg12dec.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c index 310169becc0ef..afdd652b6afee 100644 --- a/libavcodec/mpeg12dec.c +++ b/libavcodec/mpeg12dec.c @@ -1536,10 +1536,8 @@ static void mpeg_decode_picture_coding_extension(Mpeg1Context *s1) av_log(s->avctx, AV_LOG_WARNING, "invalid frame_pred_frame_dct\n"); if (s->picture_structure == PICT_FRAME) { - s->first_field = 0; s->v_edge_pos = 16 * s->mb_height; } else { - s->first_field ^= 1; s->v_edge_pos = 8 * s->mb_height; memset(s->mbskip_table, 0, s->mb_stride * s->mb_height); } @@ -1570,6 +1568,11 @@ static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size) Mpeg1Context *s1 = (Mpeg1Context *) s; int ret; + if (s->picture_structure == PICT_FRAME) + s->first_field = 0; + else + s->first_field ^= 1; + /* start frame decoding */ if (s->first_field || s->picture_structure == PICT_FRAME) { AVFrameSideData *pan_scan; From 45286a625c6ced1f5c4c842244cbb4509429abba Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 18 Dec 2016 11:29:25 +0100 Subject: [PATCH 0734/3374] h264dec: make sure to only end a field if it has been started Calling ff_h264_field_end() when the per-field state is not properly initialized leads to all kinds of undefined behaviour. CC: libav-stable@libav.org Bug-Id: 977 978 992 --- libavcodec/h264_picture.c | 1 + libavcodec/h264_slice.c | 4 ++-- libavcodec/h264dec.c | 3 ++- libavcodec/h264dec.h | 5 +++++ 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/libavcodec/h264_picture.c b/libavcodec/h264_picture.c index e22852a24fa4a..24ba79df0e38a 100644 --- a/libavcodec/h264_picture.c +++ b/libavcodec/h264_picture.c @@ -194,6 +194,7 @@ int ff_h264_field_end(H264Context *h, H264SliceContext *sl, int in_setup) emms_c(); h->current_slice = 0; + h->field_started = 0; return err; } diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 1b91088f52fff..db7628cf9778d 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1884,9 +1884,8 @@ int ff_h264_queue_decode_slice(H264Context *h, const H2645NAL *nal) sl = h->slice_ctx; } - if (h->current_slice && h->cur_pic_ptr && FIELD_PICTURE(h)) { + if (h->field_started) ff_h264_field_end(h, sl, 1); - } h->current_slice = 0; if (!h->first_field) { @@ -1902,6 +1901,7 @@ int ff_h264_queue_decode_slice(H264Context *h, const H2645NAL *nal) ret = h264_field_start(h, sl, nal); if (ret < 0) return ret; + h->field_started = 1; } } diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 83b3ab3be1ea1..54ded03bd84e9 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -757,7 +757,8 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data, if (!(avctx->flags2 & AV_CODEC_FLAG2_CHUNKS) || (h->mb_y >= h->mb_height && h->mb_height)) { - ff_h264_field_end(h, &h->slice_ctx[0], 0); + if (h->field_started) + ff_h264_field_end(h, &h->slice_ctx[0], 0); *got_frame = 0; if (h->output_frame->buf[0]) { diff --git a/libavcodec/h264dec.h b/libavcodec/h264dec.h index f934fc40b84a7..2ffe4deda08bd 100644 --- a/libavcodec/h264dec.h +++ b/libavcodec/h264dec.h @@ -509,6 +509,11 @@ typedef struct H264Context { * slices) anymore */ int setup_finished; + /* This is set to 1 if h264_field_start() has been called successfully, + * so all per-field state is properly initialized and we can decode + * the slice data */ + int field_started; + AVFrame *output_frame; int enable_er; From fa64aea12ee69a32b916fefdef1c819f97e2cb9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Wed, 8 Jun 2016 11:31:33 +0200 Subject: [PATCH 0735/3374] unary: Convert to the new bitstream reader --- libavcodec/aic.c | 2 +- libavcodec/alac.c | 2 +- libavcodec/alsdec.c | 3 ++- libavcodec/apedec.c | 2 +- libavcodec/dca_xll.c | 2 +- libavcodec/dxtory.c | 2 +- libavcodec/ituh263dec.c | 2 +- libavcodec/mss4.c | 2 +- libavcodec/ralf.c | 2 +- libavcodec/takdec.c | 2 +- libavcodec/tta.c | 2 +- libavcodec/unary.h | 19 ++++++------- libavcodec/unary_legacy.h | 56 +++++++++++++++++++++++++++++++++++++++ libavcodec/vc1.c | 2 +- libavcodec/vc1_block.c | 2 +- libavcodec/wavpack.c | 2 +- libavformat/mpc8.c | 3 ++- 17 files changed, 83 insertions(+), 24 deletions(-) create mode 100644 libavcodec/unary_legacy.h diff --git a/libavcodec/aic.c b/libavcodec/aic.c index 7c6ddddb0a233..2c9b6f80985ab 100644 --- a/libavcodec/aic.c +++ b/libavcodec/aic.c @@ -29,7 +29,7 @@ #include "golomb.h" #include "idctdsp.h" #include "thread.h" -#include "unary.h" +#include "unary_legacy.h" #define AIC_HDR_SIZE 24 #define AIC_BAND_COEFFS (64 + 32 + 192 + 96) diff --git a/libavcodec/alac.c b/libavcodec/alac.c index 83d777c760a8d..aef68e76a3bcc 100644 --- a/libavcodec/alac.c +++ b/libavcodec/alac.c @@ -52,8 +52,8 @@ #include "get_bits.h" #include "bytestream.h" #include "internal.h" -#include "unary.h" #include "mathops.h" +#include "unary_legacy.h" #include "alac_data.h" #define ALAC_EXTRADATA_SIZE 36 diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c index af514870ef8ff..9fd2827dcdb37 100644 --- a/libavcodec/alsdec.c +++ b/libavcodec/alsdec.c @@ -29,12 +29,13 @@ #include "avcodec.h" #include "get_bits.h" -#include "unary.h" #include "mpeg4audio.h" #include "bytestream.h" #include "bgmc.h" #include "bswapdsp.h" #include "internal.h" +#include "unary_legacy.h" + #include "libavutil/samplefmt.h" #include "libavutil/crc.h" diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index 2f6448867a1aa..69ded9a670176 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -31,7 +31,7 @@ #include "bytestream.h" #include "internal.h" #include "get_bits.h" -#include "unary.h" +#include "unary_legacy.h" /** * @file diff --git a/libavcodec/dca_xll.c b/libavcodec/dca_xll.c index 5a558b8c48870..5d76793fbbd14 100644 --- a/libavcodec/dca_xll.c +++ b/libavcodec/dca_xll.c @@ -29,7 +29,7 @@ #include "dca.h" #include "dcadata.h" #include "get_bits.h" -#include "unary.h" +#include "unary_legacy.h" /* Sign as bit 0 */ static inline int get_bits_sm(GetBitContext *s, unsigned n) diff --git a/libavcodec/dxtory.c b/libavcodec/dxtory.c index e2b875b5e3491..b0fae2f5ef91e 100644 --- a/libavcodec/dxtory.c +++ b/libavcodec/dxtory.c @@ -30,7 +30,7 @@ #include "bytestream.h" #include "get_bits.h" #include "internal.h" -#include "unary.h" +#include "unary_legacy.h" static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size, diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c index 9199f5c28dbe0..ca0dd2c0d957a 100644 --- a/libavcodec/ituh263dec.c +++ b/libavcodec/ituh263dec.c @@ -40,7 +40,7 @@ #include "internal.h" #include "mathops.h" #include "mpegutils.h" -#include "unary.h" +#include "unary_legacy.h" #include "flv.h" #include "rv10.h" #include "mpeg4video.h" diff --git a/libavcodec/mss4.c b/libavcodec/mss4.c index 073e0e2da012c..0acdb99b7adda 100644 --- a/libavcodec/mss4.c +++ b/libavcodec/mss4.c @@ -30,7 +30,7 @@ #include "get_bits.h" #include "internal.h" #include "mss34dsp.h" -#include "unary.h" +#include "unary_legacy.h" #define HEADER_SIZE 8 diff --git a/libavcodec/ralf.c b/libavcodec/ralf.c index bed5adfe0039b..9812837570ca5 100644 --- a/libavcodec/ralf.c +++ b/libavcodec/ralf.c @@ -32,7 +32,7 @@ #include "get_bits.h" #include "golomb.h" #include "internal.h" -#include "unary.h" +#include "unary_legacy.h" #include "ralfdata.h" #define FILTER_NONE 0 diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c index 394567bbba6f7..e7320c66d4eb2 100644 --- a/libavcodec/takdec.c +++ b/libavcodec/takdec.c @@ -32,7 +32,7 @@ #include "audiodsp.h" #include "avcodec.h" #include "internal.h" -#include "unary.h" +#include "unary_legacy.h" #include "tak.h" #define MAX_SUBFRAMES 8 // max number of subframes per channel diff --git a/libavcodec/tta.c b/libavcodec/tta.c index 5532580e02239..0f67a0575d391 100644 --- a/libavcodec/tta.c +++ b/libavcodec/tta.c @@ -35,7 +35,7 @@ #include "avcodec.h" #include "get_bits.h" #include "internal.h" -#include "unary.h" +#include "unary_legacy.h" #define FORMAT_SIMPLE 1 #define FORMAT_ENCRYPTED 2 diff --git a/libavcodec/unary.h b/libavcodec/unary.h index d14929f797de9..29920178173d9 100644 --- a/libavcodec/unary.h +++ b/libavcodec/unary.h @@ -21,36 +21,37 @@ #ifndef AVCODEC_UNARY_H #define AVCODEC_UNARY_H -#include "get_bits.h" +#include "bitstream.h" /** * Get unary code of limited length - * @param gb GetBitContext + * @param bc BitstreamContext * @param[in] stop The bitstop value (unary code of 1's or 0's) * @param[in] len Maximum length * @return Unary length/index */ -static inline int get_unary(GetBitContext *gb, int stop, int len) +static inline int get_unary(BitstreamContext *bc, int stop, int len) { int i; - for(i = 0; i < len && get_bits1(gb) != stop; i++); + for (i = 0; i < len && bitstream_read_bit(bc) != stop; i++) + ; return i; } /** * Get unary code terminated by a 0 with a maximum length of 33 - * @param gb GetBitContext + * @param bc BitstreamContext * @return Unary length/index */ -static inline int get_unary_0_33(GetBitContext *gb) +static inline int get_unary_0_33(BitstreamContext *bc) { - return get_unary(gb, 0, 33); + return get_unary(bc, 0, 33); } -static inline int get_unary_0_9(GetBitContext *gb) +static inline int get_unary_0_9(BitstreamContext *bc) { - return get_unary(gb, 0, 9); + return get_unary(bc, 0, 9); } #endif /* AVCODEC_UNARY_H */ diff --git a/libavcodec/unary_legacy.h b/libavcodec/unary_legacy.h new file mode 100644 index 0000000000000..d14929f797de9 --- /dev/null +++ b/libavcodec/unary_legacy.h @@ -0,0 +1,56 @@ +/* + * copyright (c) 2004 Michael Niedermayer + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_UNARY_H +#define AVCODEC_UNARY_H + +#include "get_bits.h" + +/** + * Get unary code of limited length + * @param gb GetBitContext + * @param[in] stop The bitstop value (unary code of 1's or 0's) + * @param[in] len Maximum length + * @return Unary length/index + */ +static inline int get_unary(GetBitContext *gb, int stop, int len) +{ + int i; + + for(i = 0; i < len && get_bits1(gb) != stop; i++); + return i; +} + +/** + * Get unary code terminated by a 0 with a maximum length of 33 + * @param gb GetBitContext + * @return Unary length/index + */ +static inline int get_unary_0_33(GetBitContext *gb) +{ + return get_unary(gb, 0, 33); +} + +static inline int get_unary_0_9(GetBitContext *gb) +{ + return get_unary(gb, 0, 9); +} + +#endif /* AVCODEC_UNARY_H */ diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 7a93e971bce66..8eba65c1d04c3 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -30,10 +30,10 @@ #include "internal.h" #include "avcodec.h" #include "mpegvideo.h" +#include "unary_legacy.h" #include "vc1.h" #include "vc1data.h" #include "wmv2data.h" -#include "unary.h" #include "simple_idct.h" /***********************************************************************/ diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index 0e1018ce9b76f..d8f45f91dca88 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -30,7 +30,7 @@ #include "mpegutils.h" #include "mpegvideo.h" #include "msmpeg4data.h" -#include "unary.h" +#include "unary_legacy.h" #include "vc1.h" #include "vc1_pred.h" #include "vc1acdata.h" diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index 7f55f515a3adf..b8adb3d4841db 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -26,7 +26,7 @@ #include "bytestream.h" #include "get_bits.h" #include "internal.h" -#include "unary.h" +#include "unary_legacy.h" /** * @file diff --git a/libavformat/mpc8.c b/libavformat/mpc8.c index d4005fa499949..132e3cd9073de 100644 --- a/libavformat/mpc8.c +++ b/libavformat/mpc8.c @@ -20,7 +20,8 @@ */ #include "libavcodec/get_bits.h" -#include "libavcodec/unary.h" +#include "libavcodec/unary_legacy.h" + #include "apetag.h" #include "avformat.h" #include "internal.h" From 00c72a1e01a904cf914cd219f0db9457cb321d40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sun, 10 Apr 2016 20:47:11 +0200 Subject: [PATCH 0736/3374] mlp: Convert to the new bitstream reader --- libavcodec/mlp_parser.c | 63 ++++++------- libavcodec/mlp_parser.h | 4 +- libavcodec/mlpdec.c | 201 ++++++++++++++++++++-------------------- 3 files changed, 136 insertions(+), 132 deletions(-) diff --git a/libavcodec/mlp_parser.c b/libavcodec/mlp_parser.c index e8fb4f5f4d95a..45764e83f218c 100644 --- a/libavcodec/mlp_parser.c +++ b/libavcodec/mlp_parser.c @@ -29,7 +29,8 @@ #include "libavutil/channel_layout.h" #include "libavutil/crc.h" #include "libavutil/internal.h" -#include "get_bits.h" + +#include "bitstream.h" #include "parser.h" #include "mlp_parser.h" #include "mlp.h" @@ -139,67 +140,67 @@ static int ff_mlp_get_major_sync_size(const uint8_t * buf, int bufsize) /** Read a major sync info header - contains high level information about * the stream - sample rate, channel arrangement etc. Most of this * information is not actually necessary for decoding, only for playback. - * gb must be a freshly initialized GetBitContext with no bits read. + * bc must be a freshly-initialized BitstreamContext with no bits read. */ -int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb) +int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, BitstreamContext *bc) { int ratebits, channel_arrangement, header_size; uint16_t checksum; - assert(get_bits_count(gb) == 0); + assert(bitstream_tell(bc) == 0); - header_size = ff_mlp_get_major_sync_size(gb->buffer, gb->size_in_bits >> 3); - if (header_size < 0 || gb->size_in_bits < header_size << 3) { + header_size = ff_mlp_get_major_sync_size(bc->buffer, bc->size_in_bits >> 3); + if (header_size < 0 || bc->size_in_bits < header_size << 3) { av_log(log, AV_LOG_ERROR, "packet too short, unable to read major sync\n"); return -1; } - checksum = ff_mlp_checksum16(gb->buffer, header_size - 2); - if (checksum != AV_RL16(gb->buffer+header_size-2)) { + checksum = ff_mlp_checksum16(bc->buffer, header_size - 2); + if (checksum != AV_RL16(bc->buffer + header_size - 2)) { av_log(log, AV_LOG_ERROR, "major sync info header checksum error\n"); return AVERROR_INVALIDDATA; } - if (get_bits_long(gb, 24) != 0xf8726f) /* Sync words */ + if (bitstream_read(bc, 24) != 0xf8726f) /* Sync words */ return AVERROR_INVALIDDATA; - mh->stream_type = get_bits(gb, 8); + mh->stream_type = bitstream_read(bc, 8); mh->header_size = header_size; if (mh->stream_type == 0xbb) { - mh->group1_bits = mlp_quants[get_bits(gb, 4)]; - mh->group2_bits = mlp_quants[get_bits(gb, 4)]; + mh->group1_bits = mlp_quants[bitstream_read(bc, 4)]; + mh->group2_bits = mlp_quants[bitstream_read(bc, 4)]; - ratebits = get_bits(gb, 4); + ratebits = bitstream_read(bc, 4); mh->group1_samplerate = mlp_samplerate(ratebits); - mh->group2_samplerate = mlp_samplerate(get_bits(gb, 4)); + mh->group2_samplerate = mlp_samplerate(bitstream_read(bc, 4)); - skip_bits(gb, 11); + bitstream_skip(bc, 11); - channel_arrangement = get_bits(gb, 5); + channel_arrangement = bitstream_read(bc, 5); mh->channels_mlp = mlp_channels[channel_arrangement]; mh->channel_layout_mlp = mlp_layout[channel_arrangement]; } else if (mh->stream_type == 0xba) { mh->group1_bits = 24; // TODO: Is this information actually conveyed anywhere? mh->group2_bits = 0; - ratebits = get_bits(gb, 4); + ratebits = bitstream_read(bc, 4); mh->group1_samplerate = mlp_samplerate(ratebits); mh->group2_samplerate = 0; - skip_bits(gb, 4); + bitstream_skip(bc, 4); - mh->channel_modifier_thd_stream0 = get_bits(gb, 2); - mh->channel_modifier_thd_stream1 = get_bits(gb, 2); + mh->channel_modifier_thd_stream0 = bitstream_read(bc, 2); + mh->channel_modifier_thd_stream1 = bitstream_read(bc, 2); - channel_arrangement = get_bits(gb, 5); + channel_arrangement = bitstream_read(bc, 5); mh->channels_thd_stream1 = truehd_channels(channel_arrangement); mh->channel_layout_thd_stream1 = truehd_layout(channel_arrangement); - mh->channel_modifier_thd_stream2 = get_bits(gb, 2); + mh->channel_modifier_thd_stream2 = bitstream_read(bc, 2); - channel_arrangement = get_bits(gb, 13); + channel_arrangement = bitstream_read(bc, 13); mh->channels_thd_stream2 = truehd_channels(channel_arrangement); mh->channel_layout_thd_stream2 = truehd_layout(channel_arrangement); } else @@ -208,15 +209,15 @@ int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb) mh->access_unit_size = 40 << (ratebits & 7); mh->access_unit_size_pow2 = 64 << (ratebits & 7); - skip_bits_long(gb, 48); + bitstream_skip(bc, 48); - mh->is_vbr = get_bits1(gb); + mh->is_vbr = bitstream_read_bit(bc); - mh->peak_bitrate = (get_bits(gb, 15) * mh->group1_samplerate + 8) >> 4; + mh->peak_bitrate = (bitstream_read(bc, 15) * mh->group1_samplerate + 8) >> 4; - mh->num_substreams = get_bits(gb, 4); + mh->num_substreams = bitstream_read(bc, 4); - skip_bits_long(gb, 4 + (header_size - 17) * 8); + bitstream_skip(bc, 4 + (header_size - 17) * 8); return 0; } @@ -328,11 +329,11 @@ static int mlp_parse(AVCodecParserContext *s, goto lost_sync; } } else { - GetBitContext gb; + BitstreamContext bc; MLPHeaderInfo mh; - init_get_bits(&gb, buf + 4, (buf_size - 4) << 3); - if (ff_mlp_read_major_sync(avctx, &mh, &gb) < 0) + bitstream_init(&bc, buf + 4, (buf_size - 4) << 3); + if (ff_mlp_read_major_sync(avctx, &mh, &bc) < 0) goto lost_sync; avctx->bits_per_raw_sample = mh.group1_bits; diff --git a/libavcodec/mlp_parser.h b/libavcodec/mlp_parser.h index 8a2ae133b6e69..871b96db20486 100644 --- a/libavcodec/mlp_parser.h +++ b/libavcodec/mlp_parser.h @@ -27,7 +27,7 @@ #ifndef AVCODEC_MLP_PARSER_H #define AVCODEC_MLP_PARSER_H -#include "get_bits.h" +#include "bitstream.h" typedef struct MLPHeaderInfo { @@ -61,6 +61,6 @@ typedef struct MLPHeaderInfo } MLPHeaderInfo; -int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb); +int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, BitstreamContext *bc); #endif /* AVCODEC_MLP_PARSER_H */ diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c index 8cfeea6175641..40889161f81a4 100644 --- a/libavcodec/mlpdec.c +++ b/libavcodec/mlpdec.c @@ -26,13 +26,14 @@ #include -#include "avcodec.h" #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" #include "libavutil/channel_layout.h" -#include "get_bits.h" -#include "internal.h" #include "libavutil/crc.h" + +#include "avcodec.h" +#include "bitstream.h" +#include "internal.h" #include "parser.h" #include "mlp_parser.h" #include "mlpdsp.h" @@ -233,7 +234,7 @@ static inline int32_t calculate_sign_huff(MLPDecodeContext *m, /** Read a sample, consisting of either, both or neither of entropy-coded MSBs * and plain LSBs. */ -static inline int read_huff_channels(MLPDecodeContext *m, GetBitContext *gbp, +static inline int read_huff_channels(MLPDecodeContext *m, BitstreamContext *bc, unsigned int substr, unsigned int pos) { SubStream *s = &m->substream[substr]; @@ -241,7 +242,7 @@ static inline int read_huff_channels(MLPDecodeContext *m, GetBitContext *gbp, for (mat = 0; mat < s->num_primitive_matrices; mat++) if (s->lsb_bypass[mat]) - m->bypassed_lsbs[pos + s->blockpos][mat] = get_bits1(gbp); + m->bypassed_lsbs[pos + s->blockpos][mat] = bitstream_read_bit(bc); for (channel = s->min_channel; channel <= s->max_channel; channel++) { ChannelParams *cp = &s->channel_params[channel]; @@ -251,14 +252,15 @@ static inline int read_huff_channels(MLPDecodeContext *m, GetBitContext *gbp, int result = 0; if (codebook > 0) - result = get_vlc2(gbp, huff_vlc[codebook-1].table, - VLC_BITS, (9 + VLC_BITS - 1) / VLC_BITS); + result = bitstream_read_vlc(bc, huff_vlc[codebook-1].table, + VLC_BITS, + (9 + VLC_BITS - 1) / VLC_BITS); if (result < 0) return AVERROR_INVALIDDATA; if (lsb_bits > 0) - result = (result << lsb_bits) + get_bits(gbp, lsb_bits); + result = (result << lsb_bits) + bitstream_read(bc, lsb_bits); result += cp->sign_huff_offset; result <<= quant_step_size; @@ -288,12 +290,12 @@ static av_cold int mlp_decode_init(AVCodecContext *avctx) * information is not actually necessary for decoding, only for playback. */ -static int read_major_sync(MLPDecodeContext *m, GetBitContext *gb) +static int read_major_sync(MLPDecodeContext *m, BitstreamContext *bc) { MLPHeaderInfo mh; int substr, ret; - if ((ret = ff_mlp_read_major_sync(m->avctx, &mh, gb)) != 0) + if ((ret = ff_mlp_read_major_sync(m->avctx, &mh, bc)) != 0) return ret; if (mh.group1_bits == 0) { @@ -441,7 +443,7 @@ static int read_major_sync(MLPDecodeContext *m, GetBitContext *gb) * required to decode the audio that do not change very often. Generally * (always) present only in blocks following a major sync. */ -static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, +static int read_restart_header(MLPDecodeContext *m, BitstreamContext *bc, const uint8_t *buf, unsigned int substr) { SubStream *s = &m->substream[substr]; @@ -449,13 +451,13 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, int sync_word, tmp; uint8_t checksum; uint8_t lossless_check; - int start_count = get_bits_count(gbp); + int start_count = bitstream_tell(bc); int min_channel, max_channel, max_matrix_channel; const int std_max_matrix_channel = m->avctx->codec_id == AV_CODEC_ID_MLP ? MAX_MATRIX_CHANNEL_MLP : MAX_MATRIX_CHANNEL_TRUEHD; - sync_word = get_bits(gbp, 13); + sync_word = bitstream_read(bc, 13); if (sync_word != 0x31ea >> 1) { av_log(m->avctx, AV_LOG_ERROR, @@ -463,18 +465,18 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, return AVERROR_INVALIDDATA; } - s->noise_type = get_bits1(gbp); + s->noise_type = bitstream_read_bit(bc); if (m->avctx->codec_id == AV_CODEC_ID_MLP && s->noise_type) { av_log(m->avctx, AV_LOG_ERROR, "MLP must have 0x31ea sync word.\n"); return AVERROR_INVALIDDATA; } - skip_bits(gbp, 16); /* Output timestamp */ + bitstream_skip(bc, 16); /* Output timestamp */ - min_channel = get_bits(gbp, 4); - max_channel = get_bits(gbp, 4); - max_matrix_channel = get_bits(gbp, 4); + min_channel = bitstream_read(bc, 4); + max_channel = bitstream_read(bc, 4); + max_matrix_channel = bitstream_read(bc, 4); if (max_matrix_channel > std_max_matrix_channel) { av_log(m->avctx, AV_LOG_ERROR, @@ -518,13 +520,13 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, m->max_decoded_substream = substr; } - s->noise_shift = get_bits(gbp, 4); - s->noisegen_seed = get_bits(gbp, 23); + s->noise_shift = bitstream_read(bc, 4); + s->noisegen_seed = bitstream_read(bc, 23); - skip_bits(gbp, 19); + bitstream_skip(bc, 19); - s->data_check_present = get_bits1(gbp); - lossless_check = get_bits(gbp, 8); + s->data_check_present = bitstream_read_bit(bc); + lossless_check = bitstream_read(bc, 8); if (substr == m->max_decoded_substream && s->lossless_check_data != 0xffffffff) { tmp = xor_32_to_8(s->lossless_check_data); @@ -534,12 +536,12 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, lossless_check, tmp); } - skip_bits(gbp, 16); + bitstream_skip(bc, 16); memset(s->ch_assign, 0, sizeof(s->ch_assign)); for (ch = 0; ch <= s->max_matrix_channel; ch++) { - int ch_assign = get_bits(gbp, 6); + int ch_assign = bitstream_read(bc, 6); if (m->avctx->codec_id == AV_CODEC_ID_TRUEHD) { uint64_t channel = thd_channel_layout_extract_channel(s->ch_layout, ch_assign); @@ -555,9 +557,9 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, s->ch_assign[ch_assign] = ch; } - checksum = ff_mlp_restart_checksum(buf, get_bits_count(gbp) - start_count); + checksum = ff_mlp_restart_checksum(buf, bitstream_tell(bc) - start_count); - if (checksum != get_bits(gbp, 8)) + if (checksum != bitstream_read(bc, 8)) av_log(m->avctx, AV_LOG_ERROR, "restart header checksum error\n"); /* Set default decoding parameters. */ @@ -597,7 +599,7 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, /** Read parameters for one of the prediction filters. */ -static int read_filter_params(MLPDecodeContext *m, GetBitContext *gbp, +static int read_filter_params(MLPDecodeContext *m, BitstreamContext *bc, unsigned int substr, unsigned int channel, unsigned int filter) { @@ -615,7 +617,7 @@ static int read_filter_params(MLPDecodeContext *m, GetBitContext *gbp, return AVERROR_INVALIDDATA; } - order = get_bits(gbp, 4); + order = bitstream_read(bc, 4); if (order > max_order) { av_log(m->avctx, AV_LOG_ERROR, "%cIR filter order %d is greater than maximum %d.\n", @@ -628,10 +630,10 @@ static int read_filter_params(MLPDecodeContext *m, GetBitContext *gbp, int32_t *fcoeff = s->channel_params[channel].coeff[filter]; int coeff_bits, coeff_shift; - fp->shift = get_bits(gbp, 4); + fp->shift = bitstream_read(bc, 4); - coeff_bits = get_bits(gbp, 5); - coeff_shift = get_bits(gbp, 3); + coeff_bits = bitstream_read(bc, 5); + coeff_shift = bitstream_read(bc, 3); if (coeff_bits < 1 || coeff_bits > 16) { av_log(m->avctx, AV_LOG_ERROR, "%cIR filter coeff_bits must be between 1 and 16.\n", @@ -646,9 +648,9 @@ static int read_filter_params(MLPDecodeContext *m, GetBitContext *gbp, } for (i = 0; i < order; i++) - fcoeff[i] = get_sbits(gbp, coeff_bits) << coeff_shift; + fcoeff[i] = bitstream_read_signed(bc, coeff_bits) << coeff_shift; - if (get_bits1(gbp)) { + if (bitstream_read_bit(bc)) { int state_bits, state_shift; if (filter == FIR) { @@ -657,13 +659,13 @@ static int read_filter_params(MLPDecodeContext *m, GetBitContext *gbp, return AVERROR_INVALIDDATA; } - state_bits = get_bits(gbp, 4); - state_shift = get_bits(gbp, 4); + state_bits = bitstream_read(bc, 4); + state_shift = bitstream_read(bc, 4); /* TODO: Check validity of state data. */ for (i = 0; i < order; i++) - fp->state[i] = get_sbits(gbp, state_bits) << state_shift; + fp->state[i] = bitstream_read_signed(bc, state_bits) << state_shift; } } @@ -672,7 +674,8 @@ static int read_filter_params(MLPDecodeContext *m, GetBitContext *gbp, /** Read parameters for primitive matrices. */ -static int read_matrix_params(MLPDecodeContext *m, unsigned int substr, GetBitContext *gbp) +static int read_matrix_params(MLPDecodeContext *m, unsigned int substr, + BitstreamContext *bc) { SubStream *s = &m->substream[substr]; unsigned int mat, ch; @@ -685,7 +688,7 @@ static int read_matrix_params(MLPDecodeContext *m, unsigned int substr, GetBitCo return AVERROR_INVALIDDATA; } - s->num_primitive_matrices = get_bits(gbp, 4); + s->num_primitive_matrices = bitstream_read(bc, 4); if (s->num_primitive_matrices > max_primitive_matrices) { av_log(m->avctx, AV_LOG_ERROR, @@ -696,9 +699,9 @@ static int read_matrix_params(MLPDecodeContext *m, unsigned int substr, GetBitCo for (mat = 0; mat < s->num_primitive_matrices; mat++) { int frac_bits, max_chan; - s->matrix_out_ch[mat] = get_bits(gbp, 4); - frac_bits = get_bits(gbp, 4); - s->lsb_bypass [mat] = get_bits1(gbp); + s->matrix_out_ch[mat] = bitstream_read(bc, 4); + frac_bits = bitstream_read(bc, 4); + s->lsb_bypass[mat] = bitstream_read_bit(bc); if (s->matrix_out_ch[mat] > s->max_matrix_channel) { av_log(m->avctx, AV_LOG_ERROR, @@ -718,14 +721,14 @@ static int read_matrix_params(MLPDecodeContext *m, unsigned int substr, GetBitCo for (ch = 0; ch <= max_chan; ch++) { int coeff_val = 0; - if (get_bits1(gbp)) - coeff_val = get_sbits(gbp, frac_bits + 2); + if (bitstream_read_bit(bc)) + coeff_val = bitstream_read_signed(bc, frac_bits + 2); s->matrix_coeff[mat][ch] = coeff_val << (14 - frac_bits); } if (s->noise_type) - s->matrix_noise_shift[mat] = get_bits(gbp, 4); + s->matrix_noise_shift[mat] = bitstream_read(bc, 4); else s->matrix_noise_shift[mat] = 0; } @@ -736,7 +739,7 @@ static int read_matrix_params(MLPDecodeContext *m, unsigned int substr, GetBitCo /** Read channel parameters. */ static int read_channel_params(MLPDecodeContext *m, unsigned int substr, - GetBitContext *gbp, unsigned int ch) + BitstreamContext *bc, unsigned int ch) { SubStream *s = &m->substream[substr]; ChannelParams *cp = &s->channel_params[ch]; @@ -745,13 +748,13 @@ static int read_channel_params(MLPDecodeContext *m, unsigned int substr, int ret; if (s->param_presence_flags & PARAM_FIR) - if (get_bits1(gbp)) - if ((ret = read_filter_params(m, gbp, substr, ch, FIR)) < 0) + if (bitstream_read_bit(bc)) + if ((ret = read_filter_params(m, bc, substr, ch, FIR)) < 0) return ret; if (s->param_presence_flags & PARAM_IIR) - if (get_bits1(gbp)) - if ((ret = read_filter_params(m, gbp, substr, ch, IIR)) < 0) + if (bitstream_read_bit(bc)) + if ((ret = read_filter_params(m, bc, substr, ch, IIR)) < 0) return ret; if (fir->order + iir->order > 8) { @@ -774,11 +777,11 @@ static int read_channel_params(MLPDecodeContext *m, unsigned int substr, fir->shift = iir->shift; if (s->param_presence_flags & PARAM_HUFFOFFSET) - if (get_bits1(gbp)) - cp->huff_offset = get_sbits(gbp, 15); + if (bitstream_read_bit(bc)) + cp->huff_offset = bitstream_read_signed(bc, 15); - cp->codebook = get_bits(gbp, 2); - cp->huff_lsbs = get_bits(gbp, 5); + cp->codebook = bitstream_read(bc, 2); + cp->huff_lsbs = bitstream_read(bc, 5); if (cp->huff_lsbs > 24) { av_log(m->avctx, AV_LOG_ERROR, "Invalid huff_lsbs.\n"); @@ -793,7 +796,7 @@ static int read_channel_params(MLPDecodeContext *m, unsigned int substr, /** Read decoding parameters that change more often than those in the restart * header. */ -static int read_decoding_params(MLPDecodeContext *m, GetBitContext *gbp, +static int read_decoding_params(MLPDecodeContext *m, BitstreamContext *bc, unsigned int substr) { SubStream *s = &m->substream[substr]; @@ -801,12 +804,12 @@ static int read_decoding_params(MLPDecodeContext *m, GetBitContext *gbp, int ret; if (s->param_presence_flags & PARAM_PRESENCE) - if (get_bits1(gbp)) - s->param_presence_flags = get_bits(gbp, 8); + if (bitstream_read_bit(bc)) + s->param_presence_flags = bitstream_read(bc, 8); if (s->param_presence_flags & PARAM_BLOCKSIZE) - if (get_bits1(gbp)) { - s->blocksize = get_bits(gbp, 9); + if (bitstream_read_bit(bc)) { + s->blocksize = bitstream_read(bc, 9); if (s->blocksize < 8 || s->blocksize > m->access_unit_size) { av_log(m->avctx, AV_LOG_ERROR, "Invalid blocksize."); s->blocksize = 0; @@ -815,14 +818,14 @@ static int read_decoding_params(MLPDecodeContext *m, GetBitContext *gbp, } if (s->param_presence_flags & PARAM_MATRIX) - if (get_bits1(gbp)) - if ((ret = read_matrix_params(m, substr, gbp)) < 0) + if (bitstream_read_bit(bc)) + if ((ret = read_matrix_params(m, substr, bc)) < 0) return ret; if (s->param_presence_flags & PARAM_OUTSHIFT) - if (get_bits1(gbp)) { + if (bitstream_read_bit(bc)) { for (ch = 0; ch <= s->max_matrix_channel; ch++) - s->output_shift[ch] = get_sbits(gbp, 4); + s->output_shift[ch] = bitstream_read_signed(bc, 4); if (substr == m->max_decoded_substream) m->dsp.mlp_pack_output = m->dsp.mlp_select_pack_output(s->ch_assign, s->output_shift, @@ -831,18 +834,18 @@ static int read_decoding_params(MLPDecodeContext *m, GetBitContext *gbp, } if (s->param_presence_flags & PARAM_QUANTSTEP) - if (get_bits1(gbp)) + if (bitstream_read_bit(bc)) for (ch = 0; ch <= s->max_channel; ch++) { ChannelParams *cp = &s->channel_params[ch]; - s->quant_step_size[ch] = get_bits(gbp, 4); + s->quant_step_size[ch] = bitstream_read(bc, 4); cp->sign_huff_offset = calculate_sign_huff(m, substr, ch); } for (ch = s->min_channel; ch <= s->max_channel; ch++) - if (get_bits1(gbp)) - if ((ret = read_channel_params(m, substr, gbp, ch)) < 0) + if (bitstream_read_bit(bc)) + if ((ret = read_channel_params(m, substr, bc, ch)) < 0) return ret; return 0; @@ -880,7 +883,7 @@ static void filter_channel(MLPDecodeContext *m, unsigned int substr, /** Read a block of PCM residual data (or actual if no filtering active). */ -static int read_block_data(MLPDecodeContext *m, GetBitContext *gbp, +static int read_block_data(MLPDecodeContext *m, BitstreamContext *bc, unsigned int substr) { SubStream *s = &m->substream[substr]; @@ -888,8 +891,8 @@ static int read_block_data(MLPDecodeContext *m, GetBitContext *gbp, int ret; if (s->data_check_present) { - expected_stream_pos = get_bits_count(gbp); - expected_stream_pos += get_bits(gbp, 16); + expected_stream_pos = bitstream_tell(bc); + expected_stream_pos += bitstream_read(bc, 16); avpriv_request_sample(m->avctx, "Substreams with VLC block size check info"); } @@ -903,7 +906,7 @@ static int read_block_data(MLPDecodeContext *m, GetBitContext *gbp, s->blocksize * sizeof(m->bypassed_lsbs[0])); for (i = 0; i < s->blocksize; i++) - if ((ret = read_huff_channels(m, gbp, substr, i)) < 0) + if ((ret = read_huff_channels(m, bc, substr, i)) < 0) return ret; for (ch = s->min_channel; ch <= s->max_channel; ch++) @@ -912,9 +915,9 @@ static int read_block_data(MLPDecodeContext *m, GetBitContext *gbp, s->blockpos += s->blocksize; if (s->data_check_present) { - if (get_bits_count(gbp) != expected_stream_pos) + if (bitstream_tell(bc) != expected_stream_pos) av_log(m->avctx, AV_LOG_ERROR, "block data length mismatch\n"); - skip_bits(gbp, 8); + bitstream_skip(bc, 8); } return 0; @@ -1074,7 +1077,7 @@ static int read_access_unit(AVCodecContext *avctx, void* data, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; MLPDecodeContext *m = avctx->priv_data; - GetBitContext gb; + BitstreamContext bc; unsigned int length, substr; unsigned int substream_start; unsigned int header_size = 4; @@ -1092,11 +1095,11 @@ static int read_access_unit(AVCodecContext *avctx, void* data, if (length < 4 || length > buf_size) return AVERROR_INVALIDDATA; - init_get_bits(&gb, (buf + 4), (length - 4) * 8); + bitstream_init(&bc, (buf + 4), (length - 4) * 8); m->is_major_sync_unit = 0; - if (show_bits_long(&gb, 31) == (0xf8726fba >> 1)) { - if (read_major_sync(m, &gb) < 0) + if (bitstream_peek(&bc, 31) == (0xf8726fba >> 1)) { + if (read_major_sync(m, &bc) < 0) goto error; m->is_major_sync_unit = 1; header_size += m->major_sync_header_size; @@ -1114,12 +1117,12 @@ static int read_access_unit(AVCodecContext *avctx, void* data, for (substr = 0; substr < m->num_substreams; substr++) { int extraword_present, checkdata_present, end, nonrestart_substr; - extraword_present = get_bits1(&gb); - nonrestart_substr = get_bits1(&gb); - checkdata_present = get_bits1(&gb); - skip_bits1(&gb); + extraword_present = bitstream_read_bit(&bc); + nonrestart_substr = bitstream_read_bit(&bc); + checkdata_present = bitstream_read_bit(&bc); + bitstream_skip(&bc, 1); - end = get_bits(&gb, 12) * 2; + end = bitstream_read(&bc, 12) * 2; substr_header_size += 2; @@ -1128,7 +1131,7 @@ static int read_access_unit(AVCodecContext *avctx, void* data, av_log(m->avctx, AV_LOG_ERROR, "There must be no extraword for MLP.\n"); goto error; } - skip_bits(&gb, 16); + bitstream_skip(&bc, 16); substr_header_size += 2; } @@ -1172,47 +1175,47 @@ static int read_access_unit(AVCodecContext *avctx, void* data, for (substr = 0; substr <= m->max_decoded_substream; substr++) { SubStream *s = &m->substream[substr]; - init_get_bits(&gb, buf, substream_data_len[substr] * 8); + bitstream_init(&bc, buf, substream_data_len[substr] * 8); m->matrix_changed = 0; memset(m->filter_changed, 0, sizeof(m->filter_changed)); s->blockpos = 0; do { - if (get_bits1(&gb)) { - if (get_bits1(&gb)) { + if (bitstream_read_bit(&bc)) { + if (bitstream_read_bit(&bc)) { /* A restart header should be present. */ - if (read_restart_header(m, &gb, buf, substr) < 0) + if (read_restart_header(m, &bc, buf, substr) < 0) goto next_substr; s->restart_seen = 1; } if (!s->restart_seen) goto next_substr; - if (read_decoding_params(m, &gb, substr) < 0) + if (read_decoding_params(m, &bc, substr) < 0) goto next_substr; } if (!s->restart_seen) goto next_substr; - if ((ret = read_block_data(m, &gb, substr)) < 0) + if ((ret = read_block_data(m, &bc, substr)) < 0) return ret; - if (get_bits_count(&gb) >= substream_data_len[substr] * 8) + if (bitstream_tell(&bc) >= substream_data_len[substr] * 8) goto substream_length_mismatch; - } while (!get_bits1(&gb)); + } while (!bitstream_read_bit(&bc)); - skip_bits(&gb, (-get_bits_count(&gb)) & 15); + bitstream_skip(&bc, (-bitstream_tell(&bc)) & 15); - if (substream_data_len[substr] * 8 - get_bits_count(&gb) >= 32) { + if (substream_data_len[substr] * 8 - bitstream_tell(&bc) >= 32) { int shorten_by; - if (get_bits(&gb, 16) != 0xD234) + if (bitstream_read(&bc, 16) != 0xD234) return AVERROR_INVALIDDATA; - shorten_by = get_bits(&gb, 16); + shorten_by = bitstream_read(&bc, 16); if (m->avctx->codec_id == AV_CODEC_ID_TRUEHD && shorten_by & 0x2000) s->blockpos -= FFMIN(shorten_by & 0x1FFF, s->blockpos); else if (m->avctx->codec_id == AV_CODEC_ID_MLP && shorten_by != 0xD234) @@ -1225,19 +1228,19 @@ static int read_access_unit(AVCodecContext *avctx, void* data, if (substream_parity_present[substr]) { uint8_t parity, checksum; - if (substream_data_len[substr] * 8 - get_bits_count(&gb) != 16) + if (substream_data_len[substr] * 8 - bitstream_tell(&bc) != 16) goto substream_length_mismatch; parity = ff_mlp_calculate_parity(buf, substream_data_len[substr] - 2); checksum = ff_mlp_checksum8 (buf, substream_data_len[substr] - 2); - if ((get_bits(&gb, 8) ^ parity) != 0xa9 ) + if ((bitstream_read(&bc, 8) ^ parity) != 0xa9) av_log(m->avctx, AV_LOG_ERROR, "Substream %d parity check failed.\n", substr); - if ( get_bits(&gb, 8) != checksum) + if (bitstream_read(&bc, 8) != checksum) av_log(m->avctx, AV_LOG_ERROR, "Substream %d checksum failed.\n" , substr); } - if (substream_data_len[substr] * 8 != get_bits_count(&gb)) + if (substream_data_len[substr] * 8 != bitstream_tell(&bc)) goto substream_length_mismatch; next_substr: From fc322d6a70189da24dbd445c710bb214eb031ce7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Thu, 14 Apr 2016 10:54:11 +0200 Subject: [PATCH 0737/3374] tta: Convert to the new bitstream reader --- libavcodec/tta.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/libavcodec/tta.c b/libavcodec/tta.c index 0f67a0575d391..7fe11f5830140 100644 --- a/libavcodec/tta.c +++ b/libavcodec/tta.c @@ -33,9 +33,9 @@ #define BITSTREAM_READER_LE #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "internal.h" -#include "unary_legacy.h" +#include "unary.h" #define FORMAT_SIMPLE 1 #define FORMAT_ENCRYPTED 2 @@ -60,7 +60,7 @@ typedef struct TTAChannel { typedef struct TTAContext { AVCodecContext *avctx; - GetBitContext gb; + BitstreamContext bc; const AVCRC *crc_table; int format, channels, bps; @@ -197,18 +197,17 @@ static av_cold int tta_decode_init(AVCodecContext * avctx) if (avctx->extradata_size < 30) return -1; - init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size * 8); - if (show_bits_long(&s->gb, 32) == AV_RL32("TTA1")) - { + bitstream_init(&s->bc, avctx->extradata, avctx->extradata_size * 8); + if (bitstream_peek(&s->bc, 32) == AV_RL32("TTA1")) { if (avctx->err_recognition & AV_EF_CRCCHECK) { s->crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE); tta_check_crc(s, avctx->extradata, 18); } /* signature */ - skip_bits_long(&s->gb, 32); + bitstream_skip(&s->bc, 32); - s->format = get_bits(&s->gb, 16); + s->format = bitstream_read(&s->bc, 16); if (s->format > 2) { av_log(s->avctx, AV_LOG_ERROR, "Invalid format\n"); return -1; @@ -217,12 +216,13 @@ static av_cold int tta_decode_init(AVCodecContext * avctx) avpriv_report_missing_feature(s->avctx, "Encrypted TTA"); return AVERROR_PATCHWELCOME; } - avctx->channels = s->channels = get_bits(&s->gb, 16); - avctx->bits_per_coded_sample = get_bits(&s->gb, 16); + avctx->channels = + s->channels = bitstream_read(&s->bc, 16); + avctx->bits_per_coded_sample = bitstream_read(&s->bc, 16); s->bps = (avctx->bits_per_coded_sample + 7) / 8; - avctx->sample_rate = get_bits_long(&s->gb, 32); - s->data_length = get_bits_long(&s->gb, 32); - skip_bits_long(&s->gb, 32); // CRC32 of header + avctx->sample_rate = bitstream_read(&s->bc, 32); + s->data_length = bitstream_read(&s->bc, 32); + bitstream_skip(&s->bc, 32); // CRC32 of header if (s->channels == 0) { av_log(s->avctx, AV_LOG_ERROR, "Invalid number of channels\n"); @@ -272,8 +272,8 @@ static av_cold int tta_decode_init(AVCodecContext * avctx) if (ret < 0 && avctx->err_recognition & AV_EF_EXPLODE) return AVERROR_INVALIDDATA; } - skip_bits_long(&s->gb, 32 * total_frames); - skip_bits_long(&s->gb, 32); // CRC32 of seektable + bitstream_skip(&s->bc, 32 * total_frames); + bitstream_skip(&s->bc, 32); // CRC32 of seektable if(s->frame_length >= UINT_MAX / (s->channels * sizeof(int32_t))){ av_log(avctx, AV_LOG_ERROR, "frame_length too large\n"); @@ -315,7 +315,7 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - init_get_bits(&s->gb, buf, buf_size*8); + bitstream_init(&s->bc, buf, buf_size * 8); /* get output buffer */ frame->nb_samples = framelen; @@ -343,7 +343,7 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, uint32_t unary, depth, k; int32_t value; - unary = get_unary(&s->gb, 0, get_bits_left(&s->gb)); + unary = get_unary(&s->bc, 0, bitstream_bits_left(&s->bc)); if (unary == 0) { depth = 0; @@ -354,7 +354,7 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, unary--; } - if (get_bits_left(&s->gb) < k) { + if (bitstream_bits_left(&s->bc) < k) { ret = AVERROR_INVALIDDATA; goto error; } @@ -364,7 +364,7 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, ret = AVERROR_INVALIDDATA; goto error; } - value = (unary << k) + get_bits(&s->gb, k); + value = (unary << k) + bitstream_read(&s->bc, k); } else value = unary; @@ -414,19 +414,19 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, cur_chan = 0; i++; // check for last frame - if (i == s->last_frame_length && get_bits_left(&s->gb) / 8 == 4) { + if (i == s->last_frame_length && bitstream_bits_left(&s->bc) / 8 == 4) { frame->nb_samples = framelen = s->last_frame_length; break; } } } - align_get_bits(&s->gb); - if (get_bits_left(&s->gb) < 32) { + bitstream_align(&s->bc); + if (bitstream_bits_left(&s->bc) < 32) { ret = AVERROR_INVALIDDATA; goto error; } - skip_bits_long(&s->gb, 32); // frame crc + bitstream_skip(&s->bc, 32); // frame CRC // convert to output buffer if (s->bps == 2) { From a0c443a3980dc22eb02b067ac4cb9ffa2f9b04d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 19 Dec 2016 10:38:33 +0200 Subject: [PATCH 0738/3374] aarch64: vp9itxfm: Use the offset parameter to movrel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes build failures for iOS, broken since cad42fadcd2c. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index 053d46fd08fad..7ce6df0a6de21 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -1108,7 +1108,7 @@ function ff_vp9_idct_idct_32x32_add_neon, export=1 movrel x10, idct_coeffs add x11, x10, #32 - movrel x12, min_eob_idct_idct_32 + 2 + movrel x12, min_eob_idct_idct_32, 2 mov x15, x30 From 5b26d3b789bd19a32dbe1e9c7ccab9498de7ee9b Mon Sep 17 00:00:00 2001 From: Ruta Gadkari Date: Mon, 19 Dec 2016 16:44:04 +0530 Subject: [PATCH 0739/3374] nvenc: Update check for lookahead By default it is -1. Signed-off-by: Luca Barbato --- libavcodec/nvenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index d5bfd74e30dd6..4054e43eecd57 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -623,7 +623,7 @@ static void nvenc_setup_rate_control(AVCodecContext *avctx) av_log(avctx, AV_LOG_VERBOSE, "Temporal AQ enabled.\n"); } - if (ctx->rc_lookahead) { + if (ctx->rc_lookahead > 0) { int lkd_bound = FFMIN(ctx->nb_surfaces, ctx->async_depth) - ctx->config.frameIntervalP - 4; From f9edc734e0ca3f6ef06c1ad0bd2c19c0c66f1ffa Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 19 Dec 2016 12:20:14 +0100 Subject: [PATCH 0740/3374] ratecontrol: Drop xvid-rc-related struct members unused after a6901b9c6 --- libavcodec/ratecontrol.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libavcodec/ratecontrol.h b/libavcodec/ratecontrol.h index 2976806c8e90d..7c289c6fbe6d9 100644 --- a/libavcodec/ratecontrol.h +++ b/libavcodec/ratecontrol.h @@ -79,10 +79,6 @@ typedef struct RateControlContext{ uint64_t qscale_sum[5]; int frame_count[5]; int last_non_b_pict_type; - - void *non_lavc_opaque; ///< context for non lavc rc code (for example xvid) - float dry_run_qscale; ///< for xvid rc - int last_picture_number; ///< for xvid rc AVExpr * rc_eq_eval; }RateControlContext; From 11a9320de54759340531177c9f2b1e31e6112cc2 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 26 Mar 2013 01:11:11 +0100 Subject: [PATCH 0741/3374] build: Move build-system-related helper files to a separate subdirectory This unclutters the top-level directory and groups related files together. --- .gitignore | 3 ++- Makefile | 19 ++++++++++--------- avbuild/.gitignore | 4 ++++ arch.mak => avbuild/arch.mak | 0 common.mak => avbuild/common.mak | 2 +- library.mak => avbuild/library.mak | 2 +- version.sh => avbuild/version.sh | 0 configure | 23 ++++++++++++----------- tests/fate.sh | 4 ++-- 9 files changed, 32 insertions(+), 25 deletions(-) create mode 100644 avbuild/.gitignore rename arch.mak => avbuild/arch.mak (100%) rename common.mak => avbuild/common.mak (98%) rename library.mak => avbuild/library.mak (98%) rename version.sh => avbuild/version.sh (100%) diff --git a/.gitignore b/.gitignore index e71246c724abf..f6d97b05f5379 100644 --- a/.gitignore +++ b/.gitignore @@ -23,7 +23,8 @@ /avplay /avprobe /avversion.h -/config.* +/config.asm +/config.h /coverage.info /lcov/ /mapfile diff --git a/Makefile b/Makefile index d4c2b8e7d78e6..c9fa162d8d62c 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -include config.mak +include avbuild/config.mak vpath %.c $(SRC_PATH) vpath %.m $(SRC_PATH) @@ -110,7 +110,7 @@ SKIPHEADERS = cmdutils_common_opts.h \ all: all-yes include $(SRC_PATH)/tools/Makefile -include $(SRC_PATH)/common.mak +include $(SRC_PATH)/avbuild/common.mak FF_EXTRALIBS := $(FFEXTRALIBS) FF_DEP_LIBS := $(DEP_LIBS) @@ -129,8 +129,8 @@ CONFIGURABLE_COMPONENTS = \ $(SRC_PATH)/libavcodec/bitstream_filters.c \ $(SRC_PATH)/libavformat/protocols.c \ -config.h: .config -.config: $(CONFIGURABLE_COMPONENTS) +config.h: avbuild/.config +avbuild/.config: $(CONFIGURABLE_COMPONENTS) @-tput bold 2>/dev/null @-printf '\nWARNING: $(?) newer than config.h, rerun configure\n\n' @-tput sgr0 2>/dev/null @@ -152,7 +152,7 @@ SUBDIR := $(1)/ include $(SRC_PATH)/$(1)/Makefile -include $(SRC_PATH)/$(1)/$(ARCH)/Makefile -include $(SRC_PATH)/$(1)/$(INTRINSICS)/Makefile -include $(SRC_PATH)/library.mak +include $(SRC_PATH)/avbuild/library.mak endef $(foreach D,$(FFLIBS),$(eval $(call DOSUBDIR,lib$(D)))) @@ -173,10 +173,10 @@ $(foreach P,$(PROGS),$(eval $(call DOPROG,$(P:$(EXESUF)=)))) $(PROGS): %$(EXESUF): %.o $(FF_DEP_LIBS) $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $(OBJS-$*) $(FF_EXTRALIBS) -VERSION_SH = $(SRC_PATH)/version.sh +VERSION_SH = $(SRC_PATH)/avbuild/version.sh GIT_LOG = $(SRC_PATH)/.git/logs/HEAD -.version: $(wildcard $(GIT_LOG)) $(VERSION_SH) config.mak +.version: $(wildcard $(GIT_LOG)) $(VERSION_SH) avbuild/config.mak .version: M=@ cmdutils.o libavutil/utils.o: avversion.h @@ -221,8 +221,9 @@ clean:: distclean:: $(RM) $(DISTCLEANSUFFIXES) - $(RM) config.* .config libavutil/avconfig.h .version avversion.h \ - mapfile libavcodec/bsf_list.c libavformat/protocol_list.c + $(RM) .version avversion.h config.asm config.h mapfile \ + avbuild/.config avbuild/config.* libavutil/avconfig.h \ + libavcodec/bsf_list.c libavformat/protocol_list.c config: $(SRC_PATH)/configure $(value LIBAV_CONFIGURATION) diff --git a/avbuild/.gitignore b/avbuild/.gitignore new file mode 100644 index 0000000000000..693b7aa0d3e77 --- /dev/null +++ b/avbuild/.gitignore @@ -0,0 +1,4 @@ +/.config +/config.fate +/config.log +/config.mak diff --git a/arch.mak b/avbuild/arch.mak similarity index 100% rename from arch.mak rename to avbuild/arch.mak diff --git a/common.mak b/avbuild/common.mak similarity index 98% rename from common.mak rename to avbuild/common.mak index 70ebd4b7ab362..96762949ccc8e 100644 --- a/common.mak +++ b/avbuild/common.mak @@ -2,7 +2,7 @@ # common bits used by all libraries # -include $(SRC_PATH)/arch.mak +include $(SRC_PATH)/avbuild/arch.mak OBJS += $(OBJS-yes) FFLIBS := $($(NAME)_FFLIBS) $(FFLIBS-yes) $(FFLIBS) diff --git a/library.mak b/avbuild/library.mak similarity index 98% rename from library.mak rename to avbuild/library.mak index bf1853f98967d..9215a93a2c94a 100644 --- a/library.mak +++ b/avbuild/library.mak @@ -1,4 +1,4 @@ -include $(SRC_PATH)/common.mak +include $(SRC_PATH)/avbuild/common.mak LIBVERSION := $(lib$(NAME)_VERSION) LIBMAJOR := $(lib$(NAME)_VERSION_MAJOR) diff --git a/version.sh b/avbuild/version.sh similarity index 100% rename from version.sh rename to avbuild/version.sh diff --git a/configure b/configure index d30d38445e14f..bcc5f6ec7268d 100755 --- a/configure +++ b/configure @@ -77,7 +77,7 @@ Help options: --list-filters show all available filters Standard options: - --logfile=FILE log tests and output to FILE [config.log] + --logfile=FILE log tests and output to FILE [avbuild/config.log] --disable-logging do not log configure debug information --prefix=PREFIX install in PREFIX [$prefix_default] --bindir=DIR install binaries in DIR [PREFIX/bin] @@ -2495,7 +2495,7 @@ texi2html_deps="doc" # default parameters -logfile="config.log" +logfile="avbuild/config.log" # installation paths prefix_default="/usr/local" @@ -2808,6 +2808,7 @@ disable_components(){ map 'disable_components $v' $LIBRARY_LIST +mkdir -p avbuild echo "# $0 $LIBAV_CONFIGURATION" > $logfile set >> $logfile @@ -4123,7 +4124,7 @@ esc(){ echo "$*" | sed 's/%/%25/g;s/:/%3a/g' } -echo "config:$arch:$subarch:$cpu:$target_os:$(esc $cc_ident):$(esc $LIBAV_CONFIGURATION)" >config.fate +echo "config:$arch:$subarch:$cpu:$target_os:$(esc $cc_ident):$(esc $LIBAV_CONFIGURATION)" > avbuild/config.fate check_cpp_condition stdlib.h "defined(__PIC__) || defined(__pic__) || defined(PIC)" && enable_weak pic @@ -5210,9 +5211,9 @@ fi # test "$quiet" != "yes" test -e Makefile || echo "include $source_path/Makefile" > Makefile -config_files="$TMPH config.mak" +config_files="$TMPH avbuild/config.mak" -cat > config.mak < avbuild/config.mak <> config.mak - eval echo "${lcname}_VERSION_MAJOR=\$${name}_VERSION_MAJOR" >> config.mak - eval echo "${lcname}_VERSION_MINOR=\$${name}_VERSION_MINOR" >> config.mak + eval echo "${lcname}_VERSION=\$${name}_VERSION" >> avbuild/config.mak + eval echo "${lcname}_VERSION_MAJOR=\$${name}_VERSION_MAJOR" >> avbuild/config.mak + eval echo "${lcname}_VERSION_MINOR=\$${name}_VERSION_MINOR" >> avbuild/config.mak } map 'get_version $v' $LIBRARY_LIST -map 'eval echo "${v}_FFLIBS=\$${v}_deps" >> config.mak' $LIBRARY_LIST +map 'eval echo "${v}_FFLIBS=\$${v}_deps" >> avbuild/config.mak' $LIBRARY_LIST print_program_extralibs(){ eval "program_extralibs=\$${1}_extralibs" - eval echo "EXTRALIBS-${1}=${program_extralibs}" >> config.mak + eval echo "EXTRALIBS-${1}=${program_extralibs}" >> avbuild/config.mak } map 'print_program_extralibs $v' $PROGRAM_LIST @@ -5373,7 +5374,7 @@ echo "#endif /* LIBAV_CONFIG_H */" >> $TMPH # Do not overwrite an unchanged config.h to avoid superfluous rebuilds. cp_if_changed $TMPH config.h -touch .config +touch avbuild/.config enabled yasm && cp_if_changed $TMPASM config.asm diff --git a/tests/fate.sh b/tests/fate.sh index f7ca89135cc20..4608d2ddf79a3 100755 --- a/tests/fate.sh +++ b/tests/fate.sh @@ -83,7 +83,7 @@ clean(){ report(){ date=$(date -u +%Y%m%d%H%M%S) echo "fate:1:${date}:${slot}:${version}:$1:$2:${branch}:${comment}" >report - cat ${build}/config.fate ${build}/tests/data/fate/*.rep >>report 2>/dev/null + cat ${build}/avbuild/config.fate ${build}/tests/data/fate/*.rep >> report 2> /dev/null test -n "$fate_recv" && $tar report *.log | gzip | $fate_recv } @@ -105,7 +105,7 @@ test -d "$src" && update || checkout || die "Error fetching source" cd ${workdir} -version=$(${src}/version.sh ${src}) +version=$(${src}/avbuild/version.sh ${src}) test "$version" = "$(cat version-$slot 2>/dev/null)" && exit 0 echo ${version} >version-$slot From edb434873238876790f6a17bb65490cc29a1d176 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 17 Dec 2016 20:01:07 +0100 Subject: [PATCH 0742/3374] build: Store library version numbers in .version files This moves work from the configure to the Make stage where it can be parallelized and ensures that shared libraries are built with the right version number in the filename. --- Makefile | 2 +- avbuild/common.mak | 2 +- avbuild/library.mak | 5 +++++ avbuild/libversion.sh | 15 +++++++++++++++ configure | 13 ------------- 5 files changed, 22 insertions(+), 15 deletions(-) create mode 100755 avbuild/libversion.sh diff --git a/Makefile b/Makefile index c9fa162d8d62c..6036e447db760 100644 --- a/Makefile +++ b/Makefile @@ -67,7 +67,7 @@ COMPILE_HOSTC = $(call COMPILE,HOSTCC) %.h.c: $(Q)echo '#include "$*.h"' >$@ -%.c %.h %.ver: TAG = GEN +%.c %.h %.ver %.version: TAG = GEN AVPROGS-$(CONFIG_AVCONV) += avconv AVPROGS-$(CONFIG_AVPLAY) += avplay diff --git a/avbuild/common.mak b/avbuild/common.mak index 96762949ccc8e..236380effcd28 100644 --- a/avbuild/common.mak +++ b/avbuild/common.mak @@ -49,7 +49,7 @@ $(TOOLOBJS): | tools OBJDIRS := $(OBJDIRS) $(dir $(OBJS) $(HOBJS) $(HOSTOBJS) $(TESTOBJS)) -CLEANSUFFIXES = *.d *.o *~ *.h.c *.gcda *.gcno *.map *.ver +CLEANSUFFIXES = *.d *.o *~ *.h.c *.gcda *.gcno *.map *.ver *.version DISTCLEANSUFFIXES = *.pc LIBSUFFIXES = *.a *.lib *.so *.so.* *.dylib *.dll *.def *.dll.a diff --git a/avbuild/library.mak b/avbuild/library.mak index 9215a93a2c94a..45152bebe87a1 100644 --- a/avbuild/library.mak +++ b/avbuild/library.mak @@ -1,5 +1,7 @@ include $(SRC_PATH)/avbuild/common.mak +-include $(SUBDIR)lib$(NAME).version + LIBVERSION := $(lib$(NAME)_VERSION) LIBMAJOR := $(lib$(NAME)_VERSION_MAJOR) LIBMINOR := $(lib$(NAME)_VERSION_MINOR) @@ -30,6 +32,9 @@ $(TESTPROGS): THISLIB = $(SUBDIR)$(LIBNAME) $(TESTPROGS) $(TOOLS): %$(EXESUF): %.o $$(LD) $(LDFLAGS) $(LDEXEFLAGS) $$(LD_O) $$(filter %.o,$$^) $$(THISLIB) $(FFEXTRALIBS) $$(ELIBS) +$(SUBDIR)lib$(NAME).version: $(SUBDIR)version.h | $(SUBDIR) + $$(M) $$(SRC_PATH)/avbuild/libversion.sh $(NAME) $$< > $$@ + $(SUBDIR)lib$(NAME).ver: $(SUBDIR)lib$(NAME).v $(OBJS) $$(M)sed 's/MAJOR/$(lib$(NAME)_VERSION_MAJOR)/' $$< | $(VERSION_SCRIPT_POSTPROCESS_CMD) > $$@ diff --git a/avbuild/libversion.sh b/avbuild/libversion.sh new file mode 100755 index 0000000000000..30046b1d25177 --- /dev/null +++ b/avbuild/libversion.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +toupper(){ + echo "$@" | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ +} + +name=lib$1 +ucname=$(toupper ${name}) +file=$2 + +eval $(awk "/#define ${ucname}_VERSION_M/ { print \$2 \"=\" \$3 }" "$file") +eval ${ucname}_VERSION=\$${ucname}_VERSION_MAJOR.\$${ucname}_VERSION_MINOR.\$${ucname}_VERSION_MICRO +eval echo "${name}_VERSION=\$${ucname}_VERSION" +eval echo "${name}_VERSION_MAJOR=\$${ucname}_VERSION_MAJOR" +eval echo "${name}_VERSION_MINOR=\$${ucname}_VERSION_MINOR" diff --git a/configure b/configure index bcc5f6ec7268d..2671b5a02b4c2 100755 --- a/configure +++ b/configure @@ -5318,19 +5318,6 @@ VERSION_SCRIPT_POSTPROCESS_CMD=${VERSION_SCRIPT_POSTPROCESS_CMD} SAMPLES:=${samples:-\$(LIBAV_SAMPLES)} EOF -get_version(){ - lcname=lib${1} - name=$(toupper $lcname) - file=$source_path/$lcname/version.h - eval $(awk "/#define ${name}_VERSION_M/ { print \$2 \"=\" \$3 }" "$file") - eval ${name}_VERSION=\$${name}_VERSION_MAJOR.\$${name}_VERSION_MINOR.\$${name}_VERSION_MICRO - eval echo "${lcname}_VERSION=\$${name}_VERSION" >> avbuild/config.mak - eval echo "${lcname}_VERSION_MAJOR=\$${name}_VERSION_MAJOR" >> avbuild/config.mak - eval echo "${lcname}_VERSION_MINOR=\$${name}_VERSION_MINOR" >> avbuild/config.mak -} - -map 'get_version $v' $LIBRARY_LIST - map 'eval echo "${v}_FFLIBS=\$${v}_deps" >> avbuild/config.mak' $LIBRARY_LIST print_program_extralibs(){ From 92db5083077a8b0f8e1050507671b456fd155125 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 20 Dec 2016 14:27:19 +0100 Subject: [PATCH 0743/3374] build: Generate pkg-config files from Make and not from configure This moves work from the configure to the Make stage where it can be parallelized and ensures that pkgconfig files are updated when library versions change. Bug-Id: 449 --- Makefile | 3 +- avbuild/.gitignore | 1 + avbuild/library.mak | 7 ++-- avbuild/pkgconfig_generate.sh | 50 ++++++++++++++++++++++++++ configure | 67 ++++++++++++----------------------- libavcodec/Makefile | 1 + libavdevice/Makefile | 1 + libavfilter/Makefile | 1 + libavformat/Makefile | 1 + libavresample/Makefile | 1 + libavutil/Makefile | 1 + libswscale/Makefile | 1 + 12 files changed, 86 insertions(+), 49 deletions(-) create mode 100755 avbuild/pkgconfig_generate.sh diff --git a/Makefile b/Makefile index 6036e447db760..a9f5f9a8e9c1c 100644 --- a/Makefile +++ b/Makefile @@ -67,7 +67,7 @@ COMPILE_HOSTC = $(call COMPILE,HOSTCC) %.h.c: $(Q)echo '#include "$*.h"' >$@ -%.c %.h %.ver %.version: TAG = GEN +%.c %.h %.pc %.ver %.version: TAG = GEN AVPROGS-$(CONFIG_AVCONV) += avconv AVPROGS-$(CONFIG_AVPLAY) += avplay @@ -125,7 +125,6 @@ tools/cws2fws$(EXESUF): ELIBS = $(ZLIB) CONFIGURABLE_COMPONENTS = \ $(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/all*.c)) \ - $(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/version.h)) \ $(SRC_PATH)/libavcodec/bitstream_filters.c \ $(SRC_PATH)/libavformat/protocols.c \ diff --git a/avbuild/.gitignore b/avbuild/.gitignore index 693b7aa0d3e77..38ed170752cc5 100644 --- a/avbuild/.gitignore +++ b/avbuild/.gitignore @@ -2,3 +2,4 @@ /config.fate /config.log /config.mak +/config.sh diff --git a/avbuild/library.mak b/avbuild/library.mak index 45152bebe87a1..e5f6d7d288aa5 100644 --- a/avbuild/library.mak +++ b/avbuild/library.mak @@ -9,8 +9,8 @@ INCINSTDIR := $(INCDIR)/lib$(NAME) INSTHEADERS := $(INSTHEADERS) $(HEADERS:%=$(SUBDIR)%) -all-$(CONFIG_STATIC): $(SUBDIR)$(LIBNAME) -all-$(CONFIG_SHARED): $(SUBDIR)$(SLIBNAME) +all-$(CONFIG_STATIC): $(SUBDIR)$(LIBNAME) $(SUBDIR)lib$(NAME).pc +all-$(CONFIG_SHARED): $(SUBDIR)$(SLIBNAME) $(SUBDIR)lib$(NAME).pc LIBOBJS := $(OBJS) $(SUBDIR)%.h.o $(TESTOBJS) $(LIBOBJS) $(LIBOBJS:.o=.i): CPPFLAGS += -DHAVE_AV_CONFIG_H @@ -35,6 +35,9 @@ $(TESTPROGS) $(TOOLS): %$(EXESUF): %.o $(SUBDIR)lib$(NAME).version: $(SUBDIR)version.h | $(SUBDIR) $$(M) $$(SRC_PATH)/avbuild/libversion.sh $(NAME) $$< > $$@ +$(SUBDIR)lib$(NAME).pc: $(SUBDIR)version.h | $(SUBDIR) + $$(M) $$(SRC_PATH)/avbuild/pkgconfig_generate.sh $(NAME) "$(DESC)" + $(SUBDIR)lib$(NAME).ver: $(SUBDIR)lib$(NAME).v $(OBJS) $$(M)sed 's/MAJOR/$(lib$(NAME)_VERSION_MAJOR)/' $$< | $(VERSION_SCRIPT_POSTPROCESS_CMD) > $$@ diff --git a/avbuild/pkgconfig_generate.sh b/avbuild/pkgconfig_generate.sh new file mode 100755 index 0000000000000..33e188f5ea739 --- /dev/null +++ b/avbuild/pkgconfig_generate.sh @@ -0,0 +1,50 @@ +#!/bin/sh + +. avbuild/config.sh + +if test "$shared" = "yes"; then + shared=true +else + shared=false +fi + +shortname=$1 +name=lib${shortname} +comment=$2 +libs=$(eval echo \$extralibs_${shortname}) +requires=$(eval echo \$requires_${shortname}) +requires=${requires%, } + +version=$(grep ${name}_VERSION= $name/${name}.version | cut -d= -f2) + +cat < $name/$name.pc +prefix=$prefix +exec_prefix=\${prefix} +libdir=$libdir +includedir=$incdir + +Name: $name +Description: $comment +Version: $version +Requires: $($shared || echo $requires) +Requires.private: $($shared && echo $requires) +Conflicts: +Libs: -L\${libdir} -l${shortname} $($shared || echo $libs) +Libs.private: $($shared && echo $libs) +Cflags: -I\${includedir} +EOF + +cat < $name/$name-uninstalled.pc +prefix= +exec_prefix= +libdir=\${pcfiledir} +includedir=${source_path} + +Name: $name +Description: $comment +Version: $version +Requires: $requires +Conflicts: +Libs: \${libdir}/${LIBPREF}${shortname}${LIBSUF} $libs +Cflags: -I\${includedir} +EOF diff --git a/configure b/configure index 2671b5a02b4c2..8e402383d8230 100755 --- a/configure +++ b/configure @@ -5402,52 +5402,29 @@ lib_version(){ eval printf "\"lib${1} >= \$LIB$(toupper ${1})_VERSION, \"" } -pkgconfig_generate(){ - name=$1 - shortname=${name#lib} - comment=$2 - version=$3 - libs=$4 - requires=$(map 'lib_version $v' $(eval echo \$${name#lib}_deps)) - requires=${requires%, } - enabled ${name#lib} || return 0 - mkdir -p $name - cat < $name/$name.pc +cat > avbuild/config.sh < $name/$name-uninstalled.pc -prefix= -exec_prefix= -libdir=\${pcfiledir} -includedir=${source_path} - -Name: $name -Description: $comment -Version: $version -Requires: $requires -Conflicts: -Libs: \${libdir}/${LIBPREF}${shortname}${LIBSUF} $libs -Cflags: -I\${includedir} -EOF -} - -pkgconfig_generate libavutil "Libav utility library" "$LIBAVUTIL_VERSION" "$LIBRT $LIBM" -pkgconfig_generate libavcodec "Libav codec library" "$LIBAVCODEC_VERSION" "$extralibs" -pkgconfig_generate libavformat "Libav container format library" "$LIBAVFORMAT_VERSION" "$extralibs" -pkgconfig_generate libavdevice "Libav device handling library" "$LIBAVDEVICE_VERSION" "$extralibs" -pkgconfig_generate libavfilter "Libav video filtering library" "$LIBAVFILTER_VERSION" "$extralibs" -pkgconfig_generate libavresample "Libav audio resampling library" "$LIBAVRESAMPLE_VERSION" "$LIBM" -pkgconfig_generate libswscale "Libav image rescaling library" "$LIBSWSCALE_VERSION" "$LIBM" diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 239a4c0f0a3fa..b3cee1d0cacd3 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -1,4 +1,5 @@ NAME = avcodec +DESC = Libav codec library HEADERS = avcodec.h \ avfft.h \ diff --git a/libavdevice/Makefile b/libavdevice/Makefile index 664fa0f9ffebb..ab8931c639011 100644 --- a/libavdevice/Makefile +++ b/libavdevice/Makefile @@ -1,4 +1,5 @@ NAME = avdevice +DESC = Libav device handling library HEADERS = avdevice.h \ version.h \ diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 646a5b5a26f52..c8d1515d2c9e0 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -1,4 +1,5 @@ NAME = avfilter +DESC = Libav video filtering library HEADERS = avfilter.h \ avfiltergraph.h \ diff --git a/libavformat/Makefile b/libavformat/Makefile index 6146cbe12a8d8..f363955e0e3a2 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -1,4 +1,5 @@ NAME = avformat +DESC = Libav container format library HEADERS = avformat.h \ avio.h \ diff --git a/libavresample/Makefile b/libavresample/Makefile index b9ca49119409d..928b721cc202c 100644 --- a/libavresample/Makefile +++ b/libavresample/Makefile @@ -1,4 +1,5 @@ NAME = avresample +DESC = Libav audio resampling library HEADERS = avresample.h \ version.h \ diff --git a/libavutil/Makefile b/libavutil/Makefile index f34c79950ef2b..60e180c79d940 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -1,4 +1,5 @@ NAME = avutil +DESC = Libav utility library HEADERS = adler32.h \ aes.h \ diff --git a/libswscale/Makefile b/libswscale/Makefile index c9b2fc9c468a4..a9502f6f2919f 100644 --- a/libswscale/Makefile +++ b/libswscale/Makefile @@ -1,4 +1,5 @@ NAME = swscale +DESC = Libav image rescaling library HEADERS = swscale.h \ version.h \ From 0b77a5933635293508e7289e7cf191ed166cf070 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 21 Dec 2016 11:25:34 +0100 Subject: [PATCH 0744/3374] Use correct printf conversion specifiers for POSIX integer types --- libavcodec/dxv.c | 2 +- libavcodec/hqx.c | 2 +- libavcodec/mpegaudiodec_template.c | 2 +- libavcodec/parser.c | 4 ++-- libavcodec/pngdec.c | 2 +- libavcodec/vorbisdec.c | 6 +++--- libavcodec/wmaprodec.c | 4 ++-- libavformat/mov.c | 2 +- libavformat/movenc.c | 2 +- libavformat/mux.c | 2 +- libavformat/omaenc.c | 2 +- libavformat/rmdec.c | 2 +- libavformat/rpl.c | 4 ++-- libavformat/xwma.c | 2 +- 14 files changed, 19 insertions(+), 19 deletions(-) diff --git a/libavcodec/dxv.c b/libavcodec/dxv.c index 9b14ef46ae719..41cac73e5e778 100644 --- a/libavcodec/dxv.c +++ b/libavcodec/dxv.c @@ -366,7 +366,7 @@ static int dxv_decode(AVCodecContext *avctx, void *data, break; case MKBETAG('Y', 'C', 'G', '6'): case MKBETAG('Y', 'G', '1', '0'): - avpriv_report_missing_feature(avctx, "Tag 0x%08X", tag); + avpriv_report_missing_feature(avctx, "Tag 0x%08"PRIX32"", tag); return AVERROR_PATCHWELCOME; default: /* Old version does not have a real header, just size and type. */ diff --git a/libavcodec/hqx.c b/libavcodec/hqx.c index 3c359e3863aa6..2d1abf0ccadd5 100644 --- a/libavcodec/hqx.c +++ b/libavcodec/hqx.c @@ -417,7 +417,7 @@ static int hqx_decode_frame(AVCodecContext *avctx, void *data, info_tag = AV_RL32(src); if (info_tag == MKTAG('I', 'N', 'F', 'O')) { - unsigned info_offset = AV_RL32(src + 4); + uint32_t info_offset = AV_RL32(src + 4); if (info_offset > INT_MAX || info_offset + 8 > avpkt->size) { av_log(avctx, AV_LOG_ERROR, "Invalid INFO header offset: 0x%08"PRIX32" is too large.\n", diff --git a/libavcodec/mpegaudiodec_template.c b/libavcodec/mpegaudiodec_template.c index 4b90c6fb812d9..e9ea65eed17b7 100644 --- a/libavcodec/mpegaudiodec_template.c +++ b/libavcodec/mpegaudiodec_template.c @@ -274,7 +274,7 @@ static av_cold void decode_init_static(void) scale_factor_mult[i][0] = MULLx(norm, FIXR(1.0 * 2.0), FRAC_BITS); scale_factor_mult[i][1] = MULLx(norm, FIXR(0.7937005259 * 2.0), FRAC_BITS); scale_factor_mult[i][2] = MULLx(norm, FIXR(0.6299605249 * 2.0), FRAC_BITS); - ff_dlog(NULL, "%d: norm=%x s=%x %x %x\n", i, norm, + ff_dlog(NULL, "%d: norm=%x s=%"PRIx32" %"PRIx32" %"PRIx32"\n", i, norm, scale_factor_mult[i][0], scale_factor_mult[i][1], scale_factor_mult[i][2]); diff --git a/libavcodec/parser.c b/libavcodec/parser.c index 355187ae45ba5..3ef1249341e06 100644 --- a/libavcodec/parser.c +++ b/libavcodec/parser.c @@ -228,7 +228,7 @@ int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_size) { if (pc->overread) { - ff_dlog(NULL, "overread %d, state:%X next:%d index:%d o_index:%d\n", + ff_dlog(NULL, "overread %d, state:%"PRIX32" next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); ff_dlog(NULL, "%X %X %X %X\n", (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]); @@ -285,7 +285,7 @@ int ff_combine_frame(ParseContext *pc, int next, } if (pc->overread) { - ff_dlog(NULL, "overread %d, state:%X next:%d index:%d o_index:%d\n", + ff_dlog(NULL, "overread %d, state:%"PRIX32" next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); ff_dlog(NULL, "%X %X %X %X\n", (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]); diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index a6ab6656247df..d59409764d442 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -453,7 +453,7 @@ static int decode_frame(AVCodecContext *avctx, if (length > 0x7fffffff) goto fail; tag = bytestream2_get_le32(&s->gb); - ff_dlog(avctx, "png: tag=%c%c%c%c length=%u\n", + ff_dlog(avctx, "png: tag=%c%c%c%c length=%"PRIu32"\n", (tag & 0xff), ((tag >> 8) & 0xff), ((tag >> 16) & 0xff), diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c index 8b800fd439826..9289c82cf449a 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -715,7 +715,7 @@ static int vorbis_parse_setup_hdr_residues(vorbis_context *vc) if (!res_setup->classifs) return AVERROR(ENOMEM); - ff_dlog(NULL, " begin %d end %d part.size %d classif.s %d classbook %d \n", + ff_dlog(NULL, " begin %"PRIu32" end %"PRIu32" part.size %u classif.s %"PRIu8" classbook %"PRIu8"\n", res_setup->begin, res_setup->end, res_setup->partition_size, res_setup->classifications, res_setup->classbook); @@ -855,7 +855,7 @@ static int create_map(vorbis_context *vc, unsigned floor_number) } for (idx = 0; idx <= n; ++idx) { - ff_dlog(NULL, "floor0 map: map at pos %d is %d\n", idx, map[idx]); + ff_dlog(NULL, "floor0 map: map at pos %d is %"PRId32"\n", idx, map[idx]); } return 0; @@ -988,7 +988,7 @@ static int vorbis_parse_id_hdr(vorbis_context *vc) ff_mdct_init(&vc->mdct[0], bl0, 1, -1.0); ff_mdct_init(&vc->mdct[1], bl1, 1, -1.0); - ff_dlog(NULL, " vorbis version %d \n audio_channels %d \n audio_samplerate %d \n bitrate_max %d \n bitrate_nom %d \n bitrate_min %d \n blk_0 %d blk_1 %d \n ", + ff_dlog(NULL, " vorbis version %"PRIu32" \n audio_channels %"PRIu8" \n audio_samplerate %"PRIu32" \n bitrate_max %"PRIu32" \n bitrate_nom %"PRIu32" \n bitrate_min %"PRIu32" \n blk_0 %"PRIu32" blk_1 %"PRIu32" \n ", vc->version, vc->audio_channels, vc->audio_samplerate, vc->bitrate_maximum, vc->bitrate_nominal, vc->bitrate_minimum, vc->blocksize[0], vc->blocksize[1]); /* diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index daeaa79a7b0e8..08b41f446fe80 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -607,8 +607,8 @@ static int decode_tilehdr(WMAProDecodeCtx *s) int i; int offset = 0; for (i = 0; i < s->channel[c].num_subframes; i++) { - ff_dlog(s->avctx, "frame[%i] channel[%i] subframe[%i]" - " len %i\n", s->frame_num, c, i, + ff_dlog(s->avctx, "frame[%"PRIi32"] channel[%i] subframe[%i]" + " len %"PRIu16"\n", s->frame_num, c, i, s->channel[c].subframe_len[i]); s->channel[c].subframe_offset[i] = offset; offset += s->channel[c].subframe_len[i]; diff --git a/libavformat/mov.c b/libavformat/mov.c index ed10a15625168..8b38fa43b8bf1 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -634,7 +634,7 @@ static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom) ctype = avio_rl32(pb); type = avio_rl32(pb); /* component subtype */ - av_log(c->fc, AV_LOG_TRACE, "ctype= %.4s (0x%08x)\n", (char*)&ctype, ctype); + av_log(c->fc, AV_LOG_TRACE, "ctype= %.4s (0x%08"PRIx32")\n", (char *)&ctype, ctype); av_log(c->fc, AV_LOG_TRACE, "stype= %.4s\n", (char*)&type); if (type == MKTAG('v','i','d','e')) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index f99617a96ee73..3dd882c2639c8 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -1377,7 +1377,7 @@ static int mov_write_hdlr_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra track->par->codec_tag); av_log(s, AV_LOG_WARNING, - "Unknown hldr_type for %s / 0x%04X, writing dummy values\n", + "Unknown hldr_type for %s / 0x%04"PRIX32", writing dummy values\n", tag_buf, track->par->codec_tag); } if (track->st) { diff --git a/libavformat/mux.c b/libavformat/mux.c index 2561a6d6f958c..a85c3c79db09d 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -205,7 +205,7 @@ FF_ENABLE_DEPRECATION_WARNINGS char tagbuf[32]; av_get_codec_tag_string(tagbuf, sizeof(tagbuf), par->codec_tag); av_log(s, AV_LOG_ERROR, - "Tag %s/0x%08x incompatible with output codec id '%d'\n", + "Tag %s/0x%08"PRIx32" incompatible with output codec id '%d'\n", tagbuf, par->codec_tag, par->codec_id); ret = AVERROR_INVALIDDATA; goto fail; diff --git a/libavformat/omaenc.c b/libavformat/omaenc.c index 50f369d967f03..793d0fd34535e 100644 --- a/libavformat/omaenc.c +++ b/libavformat/omaenc.c @@ -84,7 +84,7 @@ static av_cold int oma_write_header(AVFormatContext *s) (par->block_align/8 - 1)); break; default: - av_log(s, AV_LOG_ERROR, "OMA: unsupported codec tag %d for write\n", + av_log(s, AV_LOG_ERROR, "OMA: unsupported codec tag %"PRIu32" for write\n", par->codec_tag); } for (i = 0; i < (EA3_HEADER_SIZE - 36)/4; i++) diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c index 51a5bf767c4e1..2e93f1d4e86f0 100644 --- a/libavformat/rmdec.c +++ b/libavformat/rmdec.c @@ -319,7 +319,7 @@ int ff_rm_read_mdpr_codecdata(AVFormatContext *s, AVIOContext *pb, st->codecpar->codec_tag = avio_rl32(pb); st->codecpar->codec_id = ff_codec_get_id(ff_rm_codec_tags, st->codecpar->codec_tag); - av_log(s, AV_LOG_TRACE, "%X %X\n", st->codecpar->codec_tag, MKTAG('R', 'V', '2', '0')); + av_log(s, AV_LOG_TRACE, "%"PRIX32" %X\n", st->codecpar->codec_tag, MKTAG('R', 'V', '2', '0')); if (st->codecpar->codec_id == AV_CODEC_ID_NONE) goto fail1; st->codecpar->width = avio_rb16(pb); diff --git a/libavformat/rpl.c b/libavformat/rpl.c index 0fa940e52473b..6f6119c685dee 100644 --- a/libavformat/rpl.c +++ b/libavformat/rpl.c @@ -171,7 +171,7 @@ static int rpl_read_header(AVFormatContext *s) break; default: av_log(s, AV_LOG_WARNING, - "RPL video format %i not supported yet!\n", + "RPL video format %"PRIu32" not supported yet!\n", vst->codecpar->codec_tag); vst->codecpar->codec_id = AV_CODEC_ID_NONE; } @@ -236,7 +236,7 @@ static int rpl_read_header(AVFormatContext *s) rpl->frames_per_chunk = read_line_and_int(pb, &error); // video frames per chunk if (rpl->frames_per_chunk > 1 && vst->codecpar->codec_tag != 124) av_log(s, AV_LOG_WARNING, - "Don't know how to split frames for video format %i. " + "Don't know how to split frames for video format %"PRIu32". " "Video stream will be broken!\n", vst->codecpar->codec_tag); number_of_chunks = read_line_and_int(pb, &error); // number of chunks in the file diff --git a/libavformat/xwma.c b/libavformat/xwma.c index e6e72d9b520f3..006f60d33e757 100644 --- a/libavformat/xwma.c +++ b/libavformat/xwma.c @@ -86,7 +86,7 @@ static int xwma_read_header(AVFormatContext *s) * anyway. */ if (st->codecpar->codec_id != AV_CODEC_ID_WMAV2) { - avpriv_request_sample(s, "Unexpected codec (tag 0x04%x; id %d)", + avpriv_request_sample(s, "Unexpected codec (tag 0x04%"PRIx32"; id %d)", st->codecpar->codec_tag, st->codecpar->codec_id); } else { /* In all xWMA files I have seen, there is no extradata. But the WMA From 131644677970a3c4a0096270ea2a5b5d437c2e63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 15 Dec 2016 10:24:20 +0200 Subject: [PATCH 0745/3374] http: Check for negative chunk sizes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A negative chunk size is illegal and would end up used as length for memcpy, where it would lead to memory accesses out of bounds. Found-by: Paul Cher CC: libav-stable@libav.org Signed-off-by: Martin Storsjö --- libavformat/http.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libavformat/http.c b/libavformat/http.c index 8fe8d11e1edfd..00cf29500151e 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -784,8 +784,9 @@ static int http_read_stream(URLContext *h, uint8_t *buf, int size) av_log(NULL, AV_LOG_TRACE, "Chunked encoding data size: %"PRId64"'\n", s->chunksize); - - if (!s->chunksize) + if (s->chunksize < 0) + return AVERROR_INVALIDDATA; + else if (!s->chunksize) return 0; break; } From 0982152c3fb05365597978c5d7cfeeb7ced01723 Mon Sep 17 00:00:00 2001 From: John Stebbins Date: Thu, 22 Dec 2016 09:23:30 -0800 Subject: [PATCH 0746/3374] matroskadec: fix SRT subtitle duration The codec id for SRT was changed and conditionals were not updated. --- libavformat/matroskadec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 80167309650c9..a3954b0c4e98d 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -2439,11 +2439,11 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska, else pkt->pts = timecode; pkt->pos = pos; - if (track->type != MATROSKA_TRACK_TYPE_SUBTITLE || st->codecpar->codec_id == AV_CODEC_ID_TEXT) + if (track->type != MATROSKA_TRACK_TYPE_SUBTITLE || st->codecpar->codec_id == AV_CODEC_ID_SRT) pkt->duration = duration; #if FF_API_CONVERGENCE_DURATION FF_DISABLE_DEPRECATION_WARNINGS - if (st->codecpar->codec_id == AV_CODEC_ID_TEXT) + if (st->codecpar->codec_id == AV_CODEC_ID_SRT) pkt->convergence_duration = duration; FF_ENABLE_DEPRECATION_WARNINGS #endif From 53618054b64ce4dab459d23a7efebe9d5afc4855 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 24 Dec 2016 11:36:53 +0100 Subject: [PATCH 0747/3374] parser: Add missing #include for printing ISO C99 conversion specifiers --- libavcodec/parser.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/parser.c b/libavcodec/parser.c index 3ef1249341e06..b74c22bdc7097 100644 --- a/libavcodec/parser.c +++ b/libavcodec/parser.c @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include #include From 8a34f3659371680ca523aecfd9098c28f0f809eb Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 25 Dec 2016 18:25:41 +0100 Subject: [PATCH 0748/3374] build: Add version numbers to "Requires" entries in pkg-config files The (required) version numbers disappeared after edb4348732. --- avbuild/pkgconfig_generate.sh | 10 +++++++++- configure | 20 ++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/avbuild/pkgconfig_generate.sh b/avbuild/pkgconfig_generate.sh index 33e188f5ea739..c7bc65254d083 100755 --- a/avbuild/pkgconfig_generate.sh +++ b/avbuild/pkgconfig_generate.sh @@ -12,7 +12,15 @@ shortname=$1 name=lib${shortname} comment=$2 libs=$(eval echo \$extralibs_${shortname}) -requires=$(eval echo \$requires_${shortname}) +deps=$(eval echo \$${shortname}_deps) + +for dep in $deps; do + depname=lib${dep} + . ${depname}/${depname}.version + depversion=$(eval echo \$${depname}_VERSION) + requires="$requires ${depname} >= ${depversion}, " +done + requires=${requires%, } version=$(grep ${name}_VERSION= $name/${name}.version | cut -d= -f2) diff --git a/configure b/configure index 8e402383d8230..09674aad4d659 100755 --- a/configure +++ b/configure @@ -5396,11 +5396,7 @@ print_enabled_components libavformat/protocol_list.c URLProtocol url_protocols $ test -n "$WARNINGS" && printf "\n$WARNINGS" -# build pkg-config files - -lib_version(){ - eval printf "\"lib${1} >= \$LIB$(toupper ${1})_VERSION, \"" -} +# Settings for pkg-config files cat > avbuild/config.sh <> avbuild/config.sh +done From 35d1f726eb9fdd376ab900587fb02122b72f2b9a Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Wed, 28 Dec 2016 00:19:49 +0200 Subject: [PATCH 0749/3374] fate: Add --ignore-tests configure option for omitting specific FATE tests This can be useful to filter out noise in known-broken scenarios like miscompilation by legacy compilers and similar. Originally based on a patch by Diego Biurrun. Signed-off-by: Diego Biurrun --- configure | 11 +++++++++++ doc/fate.texi | 1 + tests/Makefile | 4 +++- tests/fate-run.sh | 9 +++++++-- tests/fate.sh | 1 + 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/configure b/configure index 09674aad4d659..d8b59e2548ab4 100755 --- a/configure +++ b/configure @@ -348,6 +348,8 @@ Developer options (useful when working on Libav itself): --random-seed=VALUE seed value for --enable/disable-random --disable-valgrind-backtrace do not print a backtrace under Valgrind (only applies to --disable-optimizations builds) + --ignore-tests=TESTS comma-separated list (without "fate-" prefix + in the name) of tests whose result is ignored NOTE: Object files are built at the place where configure is launched. EOF @@ -1815,6 +1817,7 @@ CMDLINE_SET=" host_ld host_ldflags host_os + ignore_tests ld logfile malloc_prefix @@ -5192,6 +5195,13 @@ for type in decoder encoder hwaccel parser demuxer muxer protocol filter bsf ind echo done +if test -n "$ignore_tests"; then + ignore_tests=$(echo $ignore_tests | tr ',' ' ') + echo "Ignored FATE tests:" + echo $ignore_tests | print_3_columns + echo +fi + license="LGPL version 2.1 or later" if enabled nonfree; then license="nonfree and unredistributable" @@ -5316,6 +5326,7 @@ SLIB_INSTALL_EXTRA_LIB=${SLIB_INSTALL_EXTRA_LIB} SLIB_INSTALL_EXTRA_SHLIB=${SLIB_INSTALL_EXTRA_SHLIB} VERSION_SCRIPT_POSTPROCESS_CMD=${VERSION_SCRIPT_POSTPROCESS_CMD} SAMPLES:=${samples:-\$(LIBAV_SAMPLES)} +IGNORE_TESTS=$ignore_tests EOF map 'eval echo "${v}_FFLIBS=\$${v}_deps" >> avbuild/config.mak' $LIBRARY_LIST diff --git a/doc/fate.texi b/doc/fate.texi index 9e654e79a1c60..b1bfa2e7edfeb 100644 --- a/doc/fate.texi +++ b/doc/fate.texi @@ -139,6 +139,7 @@ workdir= # directory in which to do all the work fate_recv="ssh -T fate@@fate.libav.org" # command to submit report comment= # optional description build_only= # set to "yes" for a compile-only instance that skips tests +ignore_tests= # the following are optional and map to configure options arch= diff --git a/tests/Makefile b/tests/Makefile index 0e475a28366f0..30e06e8fdd312 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -143,11 +143,13 @@ endif FATE_UTILS = base64 tiny_psnr +$(addprefix fate-, $(IGNORE_TESTS)): REPORT=ignore + fate: $(FATE) $(FATE): $(FATE_UTILS:%=tests/%$(HOSTEXESUF)) @echo "TEST $(@:fate-%=%)" - $(Q)$(SRC_PATH)/tests/fate-run.sh $@ "$(SAMPLES)" "$(TARGET_EXEC)" "$(TARGET_PATH)" '$(CMD)' '$(CMP)' '$(REF)' '$(FUZZ)' '$(THREADS)' '$(THREAD_TYPE)' '$(CPUFLAGS)' '$(CMP_SHIFT)' '$(CMP_TARGET)' '$(SIZE_TOLERANCE)' '$(CMP_UNIT)' '$(GEN)' '$(HWACCEL)' + $(Q)$(SRC_PATH)/tests/fate-run.sh $@ "$(SAMPLES)" "$(TARGET_EXEC)" "$(TARGET_PATH)" '$(CMD)' '$(CMP)' '$(REF)' '$(FUZZ)' '$(THREADS)' '$(THREAD_TYPE)' '$(CPUFLAGS)' '$(CMP_SHIFT)' '$(CMP_TARGET)' '$(SIZE_TOLERANCE)' '$(CMP_UNIT)' '$(GEN)' '$(HWACCEL)' '$(REPORT)' fate-list: @printf '%s\n' $(sort $(FATE)) diff --git a/tests/fate-run.sh b/tests/fate-run.sh index b1b299a055526..27cd6261a50a0 100755 --- a/tests/fate-run.sh +++ b/tests/fate-run.sh @@ -24,6 +24,7 @@ size_tolerance=${14:-0} cmp_unit=${15:-2} gen=${16:-no} hwaccel=${17:-none} +report_type=${18:-standard} outdir="tests/data/fate" outfile="${outdir}/${test}" @@ -212,13 +213,17 @@ if test -e "$ref" || test $cmp = "oneline" ; then esac cmperr=$? test $err = 0 && err=$cmperr - test $err = 0 || cat $cmpfile + if [ "$report_type" = "ignore" ]; then + test $err = 0 || echo "IGNORE fate-${test}" && err=0 + else + test $err = 0 || cat $cmpfile + fi else echo "reference file '$ref' not found" err=1 fi -if [ $err -eq 0 ]; then +if [ $err -eq 0 ] && test $report_type = "standard" ; then unset cmpo erro else cmpo="$($base64 <$cmpfile)" diff --git a/tests/fate.sh b/tests/fate.sh index 4608d2ddf79a3..c93e20a4642a9 100755 --- a/tests/fate.sh +++ b/tests/fate.sh @@ -47,6 +47,7 @@ configure()( --prefix="${inst}" \ --samples="${samples}" \ --enable-gpl \ + ${ignore_tests:+--ignore-tests="$ignore_tests"} \ ${arch:+--arch=$arch} \ ${cpu:+--cpu="$cpu"} \ ${toolchain:+--toolchain="$toolchain"} \ From 5c83b4d550ea42653fece092987bab56ccc32ead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 29 Dec 2016 00:15:17 +0200 Subject: [PATCH 0750/3374] fate: Unset the sig variable if ignoring a test failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise the .rep file would still contain a signal instead of a zero, even if the process returned success. Signed-off-by: Martin Storsjö --- tests/fate-run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fate-run.sh b/tests/fate-run.sh index 27cd6261a50a0..e1aaf647faf47 100755 --- a/tests/fate-run.sh +++ b/tests/fate-run.sh @@ -214,7 +214,7 @@ if test -e "$ref" || test $cmp = "oneline" ; then cmperr=$? test $err = 0 && err=$cmperr if [ "$report_type" = "ignore" ]; then - test $err = 0 || echo "IGNORE fate-${test}" && err=0 + test $err = 0 || echo "IGNORE fate-${test}" && err=0 && unset sig else test $err = 0 || cat $cmpfile fi From eef860dd92538764f4ab7872812914ff10384268 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 29 Dec 2016 14:20:51 +0200 Subject: [PATCH 0751/3374] fate: Tweak printing of ignored tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use a tab instead of two spaces, skip the fate prefix for the test name. This makes IGNORE line fit in even better with the other make printouts. Signed-off-by: Martin Storsjö --- tests/fate-run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fate-run.sh b/tests/fate-run.sh index e1aaf647faf47..623fd635a02f2 100755 --- a/tests/fate-run.sh +++ b/tests/fate-run.sh @@ -214,7 +214,7 @@ if test -e "$ref" || test $cmp = "oneline" ; then cmperr=$? test $err = 0 && err=$cmperr if [ "$report_type" = "ignore" ]; then - test $err = 0 || echo "IGNORE fate-${test}" && err=0 && unset sig + test $err = 0 || echo "IGNORE\t${test}" && err=0 && unset sig else test $err = 0 || cat $cmpfile fi From ee164727dd64c199b87118917e674b17c25e0da3 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 29 Dec 2016 14:34:52 +0100 Subject: [PATCH 0752/3374] configure: Fix typo in incdir variable written to config.sh This fixes includedir lines in pkg-config files broken after 92db508307. --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index d8b59e2548ab4..9cd4fe6b471c3 100755 --- a/configure +++ b/configure @@ -5414,7 +5414,7 @@ cat > avbuild/config.sh < Date: Sun, 1 Jan 2017 16:31:15 -0500 Subject: [PATCH 0753/3374] cmdutils: update copyright year to 2017 CC: libav-stable@libav.org --- cmdutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmdutils.c b/cmdutils.c index 291365501b54c..b0445eb85b1b6 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -58,7 +58,7 @@ struct SwsContext *sws_opts; AVDictionary *format_opts, *codec_opts, *resample_opts; -static const int this_year = 2016; +static const int this_year = 2017; void init_opts(void) { From c536e5e8698110c139b1c17938998a5547550aa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 9 Dec 2016 12:36:28 +0200 Subject: [PATCH 0754/3374] arm: vp9mc: Fix vertical alignment of operands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9mc_neon.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/arm/vp9mc_neon.S b/libavcodec/arm/vp9mc_neon.S index d3d2c7f96b3f9..a5413a3c9f5ce 100644 --- a/libavcodec/arm/vp9mc_neon.S +++ b/libavcodec/arm/vp9mc_neon.S @@ -79,7 +79,7 @@ function ff_vp9_avg32_neon, export=1 vrhadd.u8 q0, q0, q2 vrhadd.u8 q1, q1, q3 subs r12, r12, #1 - vst1.8 {q0, q1}, [r0, :128], r1 + vst1.8 {q0, q1}, [r0, :128], r1 bne 1b bx lr endfunc @@ -408,7 +408,7 @@ function ff_vp9_\type\()_\filter\()\size\()_h_neon, export=1 add r12, r12, 120*\offset - 8 cmp r5, #8 add r12, r12, r5, lsl #3 - mov r5, #\size + mov r5, #\size .if \size >= 16 bge \type\()_8tap_16h_34 b \type\()_8tap_16h_43 @@ -543,7 +543,7 @@ function \type\()_8tap_8v_\idx1\idx2 vld1.8 {d0}, [r12, :64] vmovl.s8 q0, d0 1: - mov r12, r4 + mov r12, r4 loadl q5, q6, q7 loadl q8, q9, q10, q11 From 65074791e8f8397600aacc9801efdd17777eb6e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 15 Dec 2016 12:00:18 +0200 Subject: [PATCH 0755/3374] aarch64: vp9dsp: Fix vertical alignment in the init file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9dsp_init_aarch64.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/aarch64/vp9dsp_init_aarch64.c b/libavcodec/aarch64/vp9dsp_init_aarch64.c index 486ae1eefd1e4..3ce2c1b2b961d 100644 --- a/libavcodec/aarch64/vp9dsp_init_aarch64.c +++ b/libavcodec/aarch64/vp9dsp_init_aarch64.c @@ -100,7 +100,7 @@ static av_cold void vp9dsp_mc_init_aarch64(VP9DSPContext *dsp) { int cpu_flags = av_get_cpu_flags(); -#define init_fpel(idx1, idx2, sz, type, suffix) \ +#define init_fpel(idx1, idx2, sz, type, suffix) \ dsp->mc[idx1][FILTER_8TAP_SMOOTH ][idx2][0][0] = \ dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][0][0] = \ dsp->mc[idx1][FILTER_8TAP_SHARP ][idx2][0][0] = \ @@ -125,7 +125,7 @@ static av_cold void vp9dsp_mc_init_aarch64(VP9DSPContext *dsp) #define init_mc_func(idx1, idx2, op, filter, fname, dir, mx, my, sz, pfx) \ dsp->mc[idx1][filter][idx2][mx][my] = pfx##op##_##fname##sz##_##dir##_neon -#define init_mc_funcs(idx, dir, mx, my, sz, pfx) \ +#define init_mc_funcs(idx, dir, mx, my, sz, pfx) \ init_mc_func(idx, 0, put, FILTER_8TAP_REGULAR, regular, dir, mx, my, sz, pfx); \ init_mc_func(idx, 0, put, FILTER_8TAP_SHARP, sharp, dir, mx, my, sz, pfx); \ init_mc_func(idx, 0, put, FILTER_8TAP_SMOOTH, smooth, dir, mx, my, sz, pfx); \ @@ -133,7 +133,7 @@ static av_cold void vp9dsp_mc_init_aarch64(VP9DSPContext *dsp) init_mc_func(idx, 1, avg, FILTER_8TAP_SHARP, sharp, dir, mx, my, sz, pfx); \ init_mc_func(idx, 1, avg, FILTER_8TAP_SMOOTH, smooth, dir, mx, my, sz, pfx) -#define init_mc_funcs_dirs(idx, sz) \ +#define init_mc_funcs_dirs(idx, sz) \ init_mc_funcs(idx, h, 1, 0, sz, ff_vp9_); \ init_mc_funcs(idx, v, 0, 1, sz, ff_vp9_); \ init_mc_funcs(idx, hv, 1, 1, sz,) From 85ad5ea72ce3983947a3b07e4b35c66cb16dfaba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 16 Dec 2016 22:59:45 +0200 Subject: [PATCH 0756/3374] aarch64: vp9mc: Fix a comment to refer to a register with the right name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9mc_neon.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/aarch64/vp9mc_neon.S b/libavcodec/aarch64/vp9mc_neon.S index 720273b1150ae..c1f1876fce5b9 100644 --- a/libavcodec/aarch64/vp9mc_neon.S +++ b/libavcodec/aarch64/vp9mc_neon.S @@ -250,7 +250,7 @@ function \type\()_8tap_\size\()h_\idx1\idx2 .if \size >= 16 sub x1, x1, x5 .endif - // size >= 16 loads two qwords and increments r2, + // size >= 16 loads two qwords and increments x2, // for size 4/8 it's enough with one qword and no // postincrement .if \size >= 16 From d08e02d929ff8be5f56bb1da0e439bf1ae557552 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sat, 10 Dec 2016 15:57:01 +0000 Subject: [PATCH 0757/3374] vaapi_h265: Fix build failure with old libva without 10-bit surfaces 10-bit surface support was added in libva 1.6.2, earlier versions support H.265 encoding in 8-bit only. --- libavcodec/vaapi_encode_h265.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c index ade7d4a933a27..e9133b4313db7 100644 --- a/libavcodec/vaapi_encode_h265.c +++ b/libavcodec/vaapi_encode_h265.c @@ -1236,9 +1236,15 @@ static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx) ctx->va_rt_format = VA_RT_FORMAT_YUV420; break; case FF_PROFILE_HEVC_MAIN_10: +#ifdef VA_RT_FORMAT_YUV420_10BPP ctx->va_profile = VAProfileHEVCMain10; ctx->va_rt_format = VA_RT_FORMAT_YUV420_10BPP; break; +#else + av_log(avctx, AV_LOG_ERROR, "10-bit encoding is not " + "supported with this VAAPI version.\n"); + return AVERROR(ENOSYS); +#endif default: av_log(avctx, AV_LOG_ERROR, "Unknown H.265 profile %d.\n", avctx->profile); From 9b1db2d33883c6ff3f8c7b2453146501ba14ca20 Mon Sep 17 00:00:00 2001 From: Jun Zhao Date: Fri, 11 Nov 2016 14:53:49 +0800 Subject: [PATCH 0758/3374] vaapi_h264: Fix POC on IDR frames In H.264 section 8.2.1, we have that "The bitstream shall not contain data that result in Min(TopFieldOrderCnt, BottomFieldOrderCnt) not equal to 0 for a coded IDR frame". This fixes the encoder to always conform to this - previously the POC values formed an unbroken sequence, not resetting to zero on IDR frames. Signed-off-by: Mark Thompson --- libavcodec/vaapi_encode_h264.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index b550f6f24a8c7..deb99a7d2f435 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -146,6 +146,7 @@ typedef struct VAAPIEncodeH264Context { int fixed_qp_b; int next_frame_num; + int64_t last_idr_frame; int64_t idr_pic_count; int cpb_delay; @@ -960,6 +961,7 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, vpic->frame_num = 0; priv->next_frame_num = 1; priv->cpb_delay = 0; + priv->last_idr_frame = pic->display_order; } else { vpic->frame_num = priv->next_frame_num; if (pic->type != PICTURE_TYPE_B) { @@ -976,8 +978,8 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, vpic->CurrPic.picture_id = pic->recon_surface; vpic->CurrPic.frame_idx = vpic->frame_num; vpic->CurrPic.flags = 0; - vpic->CurrPic.TopFieldOrderCnt = pic->display_order; - vpic->CurrPic.BottomFieldOrderCnt = pic->display_order; + vpic->CurrPic.TopFieldOrderCnt = pic->display_order - priv->last_idr_frame; + vpic->CurrPic.BottomFieldOrderCnt = pic->display_order - priv->last_idr_frame; for (i = 0; i < pic->nb_refs; i++) { VAAPIEncodePicture *ref = pic->refs[i]; @@ -985,8 +987,8 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, vpic->ReferenceFrames[i].picture_id = ref->recon_surface; vpic->ReferenceFrames[i].frame_idx = ref->encode_order; vpic->ReferenceFrames[i].flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE; - vpic->ReferenceFrames[i].TopFieldOrderCnt = ref->display_order; - vpic->ReferenceFrames[i].BottomFieldOrderCnt = ref->display_order; + vpic->ReferenceFrames[i].TopFieldOrderCnt = ref->display_order - priv->last_idr_frame; + vpic->ReferenceFrames[i].BottomFieldOrderCnt = ref->display_order - priv->last_idr_frame; } for (; i < FF_ARRAY_ELEMS(vpic->ReferenceFrames); i++) { vpic->ReferenceFrames[i].picture_id = VA_INVALID_ID; @@ -1057,7 +1059,7 @@ static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx, vslice->pic_parameter_set_id = vpic->pic_parameter_set_id; vslice->idr_pic_id = priv->idr_pic_count++; - vslice->pic_order_cnt_lsb = pic->display_order & + vslice->pic_order_cnt_lsb = (pic->display_order - priv->last_idr_frame) & ((1 << (4 + vseq->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4)) - 1); for (i = 0; i < FF_ARRAY_ELEMS(vslice->RefPicList0); i++) { From 9026ec8aaf5fa19cb4fb266c16f608af0d863b2b Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 28 Dec 2016 13:15:14 +0100 Subject: [PATCH 0759/3374] matroskadec: make sure not to leave EbmlBin in an inconsistent state If a read fails, the current code will free the data but leave the size non-zero. Make sure the size is zeroed in such a case. CC: libav-stable@libav.org Bug-Id: 1001 Found-By: Kamil Frankowicz Signed-off-by: Sean McGovern --- libavformat/matroskadec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index a3954b0c4e98d..4e121b6afe3e2 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -750,16 +750,19 @@ static int ebml_read_ascii(AVIOContext *pb, int size, char **str) static int ebml_read_binary(AVIOContext *pb, int length, EbmlBin *bin) { av_free(bin->data); + bin->size = 0; + if (!(bin->data = av_mallocz(length + AV_INPUT_BUFFER_PADDING_SIZE))) return AVERROR(ENOMEM); - bin->size = length; bin->pos = avio_tell(pb); if (avio_read(pb, bin->data, length) != length) { av_freep(&bin->data); return AVERROR(EIO); } + bin->size = length; + return 0; } From f8a42d4f260db3eae4399fa8bd8c8c2c1d38f23a Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Tue, 3 Jan 2017 17:31:48 +0100 Subject: [PATCH 0760/3374] dxva2: Make ff_dxva2_get_surface() static and drop its name prefix Signed-off-by: Diego Biurrun --- libavcodec/dxva2.c | 8 ++++---- libavcodec/dxva2_internal.h | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c index 60639935a8335..6fc4f97d74eef 100644 --- a/libavcodec/dxva2.c +++ b/libavcodec/dxva2.c @@ -29,7 +29,7 @@ #include "avcodec.h" #include "dxva2_internal.h" -void *ff_dxva2_get_surface(const AVFrame *frame) +static void *get_surface(const AVFrame *frame) { return frame->data[3]; } @@ -38,7 +38,7 @@ unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx, const AVDXVAContext *ctx, const AVFrame *frame) { - void *surface = ff_dxva2_get_surface(frame); + void *surface = get_surface(frame); unsigned i; for (i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++) { @@ -158,14 +158,14 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame, if (D3D11VA_CONTEXT(ctx)->context_mutex != INVALID_HANDLE_VALUE) WaitForSingleObjectEx(D3D11VA_CONTEXT(ctx)->context_mutex, INFINITE, FALSE); hr = ID3D11VideoContext_DecoderBeginFrame(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, - ff_dxva2_get_surface(frame), + get_surface(frame), 0, NULL); } #endif #if CONFIG_DXVA2 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) hr = IDirectXVideoDecoder_BeginFrame(DXVA2_CONTEXT(ctx)->decoder, - ff_dxva2_get_surface(frame), + get_surface(frame), NULL); #endif if (hr != E_PENDING || ++runs > 50) diff --git a/libavcodec/dxva2_internal.h b/libavcodec/dxva2_internal.h index 499b37c190c13..a2ebc2a55e6a2 100644 --- a/libavcodec/dxva2_internal.h +++ b/libavcodec/dxva2_internal.h @@ -91,8 +91,6 @@ typedef union { #define DXVA_CONTEXT_CFG_RESIDACCEL(avctx, ctx) (ctx->d3d11va.cfg->ConfigResidDiffAccelerator) #endif -void *ff_dxva2_get_surface(const AVFrame *frame); - unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx, const AVDXVAContext *, const AVFrame *frame); From 0ac2d86c4758e1419934905b6c092910296aa16a Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Tue, 3 Jan 2017 17:31:49 +0100 Subject: [PATCH 0761/3374] dxva2: Factorize DXVA context validity test into a single macro Signed-off-by: Diego Biurrun --- libavcodec/dxva2_h264.c | 4 +--- libavcodec/dxva2_hevc.c | 4 +--- libavcodec/dxva2_internal.h | 5 +++++ libavcodec/dxva2_mpeg2.c | 4 +--- libavcodec/dxva2_vc1.c | 4 +--- 5 files changed, 9 insertions(+), 12 deletions(-) diff --git a/libavcodec/dxva2_h264.c b/libavcodec/dxva2_h264.c index 5622c228c773e..84959c532dafa 100644 --- a/libavcodec/dxva2_h264.c +++ b/libavcodec/dxva2_h264.c @@ -445,9 +445,7 @@ static int dxva2_h264_start_frame(AVCodecContext *avctx, AVDXVAContext *ctx = avctx->hwaccel_context; struct dxva2_picture_context *ctx_pic = h->cur_pic_ptr->hwaccel_picture_private; - if (DXVA_CONTEXT_DECODER(avctx, ctx) == NULL || - DXVA_CONTEXT_CFG(avctx, ctx) == NULL || - DXVA_CONTEXT_COUNT(avctx, ctx) <= 0) + if (!DXVA_CONTEXT_VALID(avctx, ctx)) return -1; assert(ctx_pic); diff --git a/libavcodec/dxva2_hevc.c b/libavcodec/dxva2_hevc.c index 673fada6e69c5..17548d25bb381 100644 --- a/libavcodec/dxva2_hevc.c +++ b/libavcodec/dxva2_hevc.c @@ -365,9 +365,7 @@ static int dxva2_hevc_start_frame(AVCodecContext *avctx, AVDXVAContext *ctx = avctx->hwaccel_context; struct hevc_dxva2_picture_context *ctx_pic = h->ref->hwaccel_picture_private; - if (DXVA_CONTEXT_DECODER(avctx, ctx) == NULL || - DXVA_CONTEXT_CFG(avctx, ctx) == NULL || - DXVA_CONTEXT_COUNT(avctx, ctx) <= 0) + if (!DXVA_CONTEXT_VALID(avctx, ctx)) return -1; av_assert0(ctx_pic); diff --git a/libavcodec/dxva2_internal.h b/libavcodec/dxva2_internal.h index a2ebc2a55e6a2..daf54b20e5c09 100644 --- a/libavcodec/dxva2_internal.h +++ b/libavcodec/dxva2_internal.h @@ -71,6 +71,9 @@ typedef union { #define DXVA_CONTEXT_CFG_BITSTREAM(avctx, ctx) (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.cfg->ConfigBitstreamRaw : ctx->dxva2.cfg->ConfigBitstreamRaw) #define DXVA_CONTEXT_CFG_INTRARESID(avctx, ctx) (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.cfg->ConfigIntraResidUnsigned : ctx->dxva2.cfg->ConfigIntraResidUnsigned) #define DXVA_CONTEXT_CFG_RESIDACCEL(avctx, ctx) (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.cfg->ConfigResidDiffAccelerator : ctx->dxva2.cfg->ConfigResidDiffAccelerator) +#define DXVA_CONTEXT_VALID(avctx, ctx) (DXVA_CONTEXT_DECODER(avctx, ctx) && \ + DXVA_CONTEXT_CFG(avctx, ctx) && \ + DXVA_CONTEXT_COUNT(avctx, ctx)) #elif CONFIG_DXVA2 #define DXVA_CONTEXT_WORKAROUND(avctx, ctx) (ctx->dxva2.workaround) #define DXVA_CONTEXT_COUNT(avctx, ctx) (ctx->dxva2.surface_count) @@ -80,6 +83,7 @@ typedef union { #define DXVA_CONTEXT_CFG_BITSTREAM(avctx, ctx) (ctx->dxva2.cfg->ConfigBitstreamRaw) #define DXVA_CONTEXT_CFG_INTRARESID(avctx, ctx) (ctx->dxva2.cfg->ConfigIntraResidUnsigned) #define DXVA_CONTEXT_CFG_RESIDACCEL(avctx, ctx) (ctx->dxva2.cfg->ConfigResidDiffAccelerator) +#define DXVA_CONTEXT_VALID(avctx, ctx) (ctx->dxva2.decoder && ctx->dxva2.cfg && ctx->dxva2.surface_count) #elif CONFIG_D3D11VA #define DXVA_CONTEXT_WORKAROUND(avctx, ctx) (ctx->d3d11va.workaround) #define DXVA_CONTEXT_COUNT(avctx, ctx) (ctx->d3d11va.surface_count) @@ -89,6 +93,7 @@ typedef union { #define DXVA_CONTEXT_CFG_BITSTREAM(avctx, ctx) (ctx->d3d11va.cfg->ConfigBitstreamRaw) #define DXVA_CONTEXT_CFG_INTRARESID(avctx, ctx) (ctx->d3d11va.cfg->ConfigIntraResidUnsigned) #define DXVA_CONTEXT_CFG_RESIDACCEL(avctx, ctx) (ctx->d3d11va.cfg->ConfigResidDiffAccelerator) +#define DXVA_CONTEXT_VALID(avctx, ctx) (ctx->d3d11va.decoder && ctx->d3d11va.cfg && ctx->d3d11va.surface_count) #endif unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx, diff --git a/libavcodec/dxva2_mpeg2.c b/libavcodec/dxva2_mpeg2.c index 2d88f9b8045e7..a45904963c101 100644 --- a/libavcodec/dxva2_mpeg2.c +++ b/libavcodec/dxva2_mpeg2.c @@ -263,9 +263,7 @@ static int dxva2_mpeg2_start_frame(AVCodecContext *avctx, struct dxva2_picture_context *ctx_pic = s->current_picture_ptr->hwaccel_picture_private; - if (DXVA_CONTEXT_DECODER(avctx, ctx) == NULL || - DXVA_CONTEXT_CFG(avctx, ctx) == NULL || - DXVA_CONTEXT_COUNT(avctx, ctx) <= 0) + if (!DXVA_CONTEXT_VALID(avctx, ctx)) return -1; assert(ctx_pic); diff --git a/libavcodec/dxva2_vc1.c b/libavcodec/dxva2_vc1.c index d170e182377b9..0672c97a48e09 100644 --- a/libavcodec/dxva2_vc1.c +++ b/libavcodec/dxva2_vc1.c @@ -264,9 +264,7 @@ static int dxva2_vc1_start_frame(AVCodecContext *avctx, AVDXVAContext *ctx = avctx->hwaccel_context; struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->hwaccel_picture_private; - if (DXVA_CONTEXT_DECODER(avctx, ctx) == NULL || - DXVA_CONTEXT_CFG(avctx, ctx) == NULL || - DXVA_CONTEXT_COUNT(avctx, ctx) <= 0) + if (!DXVA_CONTEXT_VALID(avctx, ctx)) return -1; assert(ctx_pic); From 2835e9a9fd2b355e7936d1024ff1bf5fe454e428 Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Wed, 4 Jan 2017 09:39:31 +0100 Subject: [PATCH 0762/3374] hevcdec: add P010 support for D3D11VA Given it's the same API than DVXA2 I don't know why the same output was not enabled for both. Signed-off-by: Anton Khirnov --- libavcodec/hevcdec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 8326690038c0b..700b5f09a0b61 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -388,6 +388,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) if (sps->pix_fmt == AV_PIX_FMT_YUV420P || sps->pix_fmt == AV_PIX_FMT_YUVJ420P || sps->pix_fmt == AV_PIX_FMT_YUV420P10) { +#if CONFIG_HEVC_D3D11VA_HWACCEL + *fmt++ = AV_PIX_FMT_D3D11VA_VLD; +#endif #if CONFIG_HEVC_DXVA2_HWACCEL *fmt++ = AV_PIX_FMT_DXVA2_VLD; #endif @@ -396,9 +399,6 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) #endif } if (sps->pix_fmt == AV_PIX_FMT_YUV420P || sps->pix_fmt == AV_PIX_FMT_YUVJ420P) { -#if CONFIG_HEVC_D3D11VA_HWACCEL - *fmt++ = AV_PIX_FMT_D3D11VA_VLD; -#endif #if CONFIG_HEVC_VDPAU_HWACCEL *fmt++ = AV_PIX_FMT_VDPAU; #endif From 4e62b57ee03928c12a3119dcaf78ffa1f4d6985f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 30 Dec 2016 21:45:51 +0200 Subject: [PATCH 0763/3374] fate: Skip the checkasm test if CONFIG_STATIC is disabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When building DLLs with MSVC, CONFIG_STATIC is disabled (see d66c52c2b3694 for a more verbose explanation) since the built object files can't be linked statically (which checkasm does). This worked up until recently, only by luck. Signed-off-by: Martin Storsjö --- tests/fate/checkasm.mak | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fate/checkasm.mak b/tests/fate/checkasm.mak index 939eb567cda0a..5721f1f53c0d8 100644 --- a/tests/fate/checkasm.mak +++ b/tests/fate/checkasm.mak @@ -19,5 +19,5 @@ $(FATE_CHECKASM): tests/checkasm/checkasm$(EXESUF) $(FATE_CHECKASM): CMD = run tests/checkasm/checkasm --test=$(@:fate-checkasm-%=%) $(FATE_CHECKASM): REF = /dev/null -FATE += $(FATE_CHECKASM) +FATE-$(CONFIG_STATIC) += $(FATE_CHECKASM) fate-checkasm: $(FATE_CHECKASM) From e199a8099411d0992c3ed278287a81f1d791199c Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 9 Jan 2017 11:09:16 +0100 Subject: [PATCH 0764/3374] Changelog: mention the new avbuild/ directory Especially config.log is often read by users trying to compile Libav, so its move should be documented. --- Changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog b/Changelog index e17ef204a6c5e..70d6a4a46b690 100644 --- a/Changelog +++ b/Changelog @@ -6,6 +6,7 @@ version : - Intel QSV-accelerated VP8 and VC-1 decoding - VAAPI-accelerated VP8 and HEVC decoding - VAAPI-accelerated deinterlacing +- config.log and other configuration files moved into avbuild/ directory version 12: From 3cba1ad76d362c994fa98fb686e04e20826fb579 Mon Sep 17 00:00:00 2001 From: Henrik Gramner Date: Sun, 25 Dec 2016 20:24:59 +0100 Subject: [PATCH 0765/3374] x86inc: Avoid using eax/rax for storing the stack pointer When allocating stack space with an alignment requirement that is larger than the current stack alignment we need to store a copy of the original stack pointer in order to be able to restore it later. If we chose to use another register for this purpose we should not pick eax/rax since it can be overwritten as a return value. Signed-off-by: Anton Khirnov --- libavutil/x86/x86inc.asm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libavutil/x86/x86inc.asm b/libavutil/x86/x86inc.asm index dca1f78409039..7941af304a73d 100644 --- a/libavutil/x86/x86inc.asm +++ b/libavutil/x86/x86inc.asm @@ -385,7 +385,14 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 %ifnum %1 %if %1 != 0 && required_stack_alignment > STACK_ALIGNMENT %if %1 > 0 + ; Reserve an additional register for storing the original stack pointer, but avoid using + ; eax/rax for this purpose since it can potentially get overwritten as a return value. %assign regs_used (regs_used + 1) + %if ARCH_X86_64 && regs_used == 7 + %assign regs_used 8 + %elif ARCH_X86_64 == 0 && regs_used == 1 + %assign regs_used 2 + %endif %endif %if ARCH_X86_64 && regs_used < 5 + UNIX64 * 3 ; Ensure that we don't clobber any registers containing arguments. For UNIX64 we also preserve r6 (rax) From e7de05f98f630b5b3a5e441c8fa763e6d89b8851 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 27 Dec 2016 18:16:36 +0100 Subject: [PATCH 0766/3374] h264dec: drop a redundant check Cropping parameters are already checked for validity during SPS parsing, no need to check them again. --- libavcodec/h264_slice.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index db7628cf9778d..1b35c2baaf6d3 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -803,23 +803,6 @@ static int init_dimensions(H264Context *h) height = h->avctx->height; } - if (width <= 0 || height <= 0) { - av_log(h->avctx, AV_LOG_ERROR, "Invalid cropped dimensions: %dx%d.\n", - width, height); - if (h->avctx->err_recognition & AV_EF_EXPLODE) - return AVERROR_INVALIDDATA; - - av_log(h->avctx, AV_LOG_WARNING, "Ignoring cropping information.\n"); - sps->crop_bottom = - sps->crop_top = - sps->crop_right = - sps->crop_left = - sps->crop = 0; - - width = h->width; - height = h->height; - } - h->avctx->coded_width = h->width; h->avctx->coded_height = h->height; h->avctx->width = width; From f1af37b51033ad90e56a8d7dfcc366f2bd9d2fed Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 27 Dec 2016 18:54:47 +0100 Subject: [PATCH 0767/3374] h264dec: make ff_h264_decode_init() static It is not called from outside h264dec.c anymore. --- libavcodec/h264dec.c | 4 ++-- libavcodec/h264dec.h | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 54ded03bd84e9..e111d40c35787 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -361,7 +361,7 @@ static av_cold int h264_decode_end(AVCodecContext *avctx) static AVOnce h264_vlc_init = AV_ONCE_INIT; -av_cold int ff_h264_decode_init(AVCodecContext *avctx) +static av_cold int h264_decode_init(AVCodecContext *avctx) { H264Context *h = avctx->priv_data; int ret; @@ -795,7 +795,7 @@ AVCodec ff_h264_decoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .priv_data_size = sizeof(H264Context), - .init = ff_h264_decode_init, + .init = h264_decode_init, .close = h264_decode_end, .decode = h264_decode_frame, .capabilities = /*AV_CODEC_CAP_DRAW_HORIZ_BAND |*/ AV_CODEC_CAP_DR1 | diff --git a/libavcodec/h264dec.h b/libavcodec/h264dec.h index 2ffe4deda08bd..5957e795e6bd0 100644 --- a/libavcodec/h264dec.h +++ b/libavcodec/h264dec.h @@ -553,7 +553,6 @@ int ff_h264_decode_ref_pic_marking(H264SliceContext *sl, GetBitContext *gb, const H2645NAL *nal, void *logctx); void ff_h264_hl_decode_mb(const H264Context *h, H264SliceContext *sl); -int ff_h264_decode_init(AVCodecContext *avctx); void ff_h264_decode_init_vlc(void); /** From e435beb1ea5380a90774dbf51fdc8c941e486551 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 15 Dec 2016 12:46:03 +0100 Subject: [PATCH 0768/3374] crypto: consistently use size_t as type for length parameters size_t is the correct type to use for sizes. --- doc/APIchanges | 4 ++++ libavutil/md5.c | 8 ++++++++ libavutil/md5.h | 8 +++++++- libavutil/sha.c | 6 +++++- libavutil/sha.h | 9 +++++++-- libavutil/version.h | 3 +++ 6 files changed, 34 insertions(+), 4 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 7633c99181378..942337903f178 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,10 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-xx-xx - xxxxxxx + Change av_sha_update() and av_md5_sum()/av_md5_update() length + parameter type to size_t at next major bump. + 2016-xx-xx - xxxxxxx - lavc 57.29.0 - avcodec.h Add AV_PKT_DATA_SPHERICAL packet side data to export AVSphericalMapping information from containers. diff --git a/libavutil/md5.c b/libavutil/md5.c index 94f068109c046..1946d783172ac 100644 --- a/libavutil/md5.c +++ b/libavutil/md5.c @@ -146,7 +146,11 @@ void av_md5_init(AVMD5 *ctx) ctx->ABCD[3] = 0x67452301; } +#if FF_API_CRYPTO_SIZE_T void av_md5_update(AVMD5 *ctx, const uint8_t *src, const int len) +#else +void av_md5_update(AVMD5 *ctx, const uint8_t *src, size_t len) +#endif { int i, j; @@ -177,7 +181,11 @@ void av_md5_final(AVMD5 *ctx, uint8_t *dst) AV_WL32(dst + 4 * i, ctx->ABCD[3 - i]); } +#if FF_API_CRYPTO_SIZE_T void av_md5_sum(uint8_t *dst, const uint8_t *src, const int len) +#else +void av_md5_sum(uint8_t *dst, const uint8_t *src, size_t len) +#endif { AVMD5 ctx; diff --git a/libavutil/md5.h b/libavutil/md5.h index c26318c01d932..55e7c2341793f 100644 --- a/libavutil/md5.h +++ b/libavutil/md5.h @@ -21,6 +21,7 @@ #ifndef AVUTIL_MD5_H #define AVUTIL_MD5_H +#include #include #include "attributes.h" @@ -36,9 +37,14 @@ struct AVMD5; struct AVMD5 *av_md5_alloc(void); void av_md5_init(struct AVMD5 *ctx); -void av_md5_update(struct AVMD5 *ctx, const uint8_t *src, const int len); void av_md5_final(struct AVMD5 *ctx, uint8_t *dst); +#if FF_API_CRYPTO_SIZE_T +void av_md5_update(struct AVMD5 *ctx, const uint8_t *src, const int len); void av_md5_sum(uint8_t *dst, const uint8_t *src, const int len); +#else +void av_md5_update(struct AVMD5 *ctx, const uint8_t *src, size_t len); +void av_md5_sum(uint8_t *dst, const uint8_t *src, size_t len); +#endif /** * @} diff --git a/libavutil/sha.c b/libavutil/sha.c index 404effade2ebc..03f93aed8ce43 100644 --- a/libavutil/sha.c +++ b/libavutil/sha.c @@ -290,7 +290,11 @@ av_cold int av_sha_init(AVSHA *ctx, int bits) return 0; } -void av_sha_update(AVSHA* ctx, const uint8_t* data, unsigned int len) +#if FF_API_CRYPTO_SIZE_T +void av_sha_update(struct AVSHA *ctx, const uint8_t *data, unsigned int len) +#else +void av_sha_update(struct AVSHA *ctx, const uint8_t *data, size_t len) +#endif { unsigned int i, j; diff --git a/libavutil/sha.h b/libavutil/sha.h index 86ea0b065eaff..c0c7cd1af1560 100644 --- a/libavutil/sha.h +++ b/libavutil/sha.h @@ -21,6 +21,7 @@ #ifndef AVUTIL_SHA_H #define AVUTIL_SHA_H +#include #include #include "attributes.h" @@ -51,11 +52,15 @@ int av_sha_init(struct AVSHA* context, int bits); /** * Update hash value. * - * @param context hash function context + * @param ctx hash function context * @param data input data to update hash with * @param len input data length */ -void av_sha_update(struct AVSHA* context, const uint8_t* data, unsigned int len); +#if FF_API_CRYPTO_SIZE_T +void av_sha_update(struct AVSHA *ctx, const uint8_t *data, unsigned int len); +#else +void av_sha_update(struct AVSHA *ctx, const uint8_t *data, size_t len); +#endif /** * Finish hashing and output digest value. diff --git a/libavutil/version.h b/libavutil/version.h index f1102312bacc7..3733fea810224 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -105,6 +105,9 @@ #ifndef FF_API_PKT_PTS #define FF_API_PKT_PTS (LIBAVUTIL_VERSION_MAJOR < 56) #endif +#ifndef FF_API_CRYPTO_SIZE_T +#define FF_API_CRYPTO_SIZE_T (LIBAVUTIL_VERSION_MAJOR < 56) +#endif /** From d7fe11634c1ad3433d5ea5a08604692d583fea2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sun, 10 Apr 2016 21:41:02 +0200 Subject: [PATCH 0769/3374] motionpixels: Convert to the new bitstream reader --- libavcodec/motionpixels.c | 77 ++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/libavcodec/motionpixels.c b/libavcodec/motionpixels.c index a18541b85246d..333f18fdb25c1 100644 --- a/libavcodec/motionpixels.c +++ b/libavcodec/motionpixels.c @@ -20,7 +20,7 @@ */ #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "bswapdsp.h" #include "internal.h" @@ -87,17 +87,18 @@ static av_cold int mp_decode_init(AVCodecContext *avctx) return 0; } -static void mp_read_changes_map(MotionPixelsContext *mp, GetBitContext *gb, int count, int bits_len, int read_color) +static void mp_read_changes_map(MotionPixelsContext *mp, BitstreamContext *bc, + int count, int bits_len, int read_color) { uint16_t *pixels; int offset, w, h, color = 0, x, y, i; while (count--) { - offset = get_bits_long(gb, mp->offset_bits_len); - w = get_bits(gb, bits_len) + 1; - h = get_bits(gb, bits_len) + 1; + offset = bitstream_read(bc, mp->offset_bits_len); + w = bitstream_read(bc, bits_len) + 1; + h = bitstream_read(bc, bits_len) + 1; if (read_color) - color = get_bits(gb, 15); + color = bitstream_read(bc, 15); x = offset % mp->avctx->width; y = offset / mp->avctx->width; if (y >= mp->avctx->height) @@ -116,16 +117,17 @@ static void mp_read_changes_map(MotionPixelsContext *mp, GetBitContext *gb, int } } -static void mp_get_code(MotionPixelsContext *mp, GetBitContext *gb, int size, int code) +static void mp_get_code(MotionPixelsContext *mp, BitstreamContext *bc, + int size, int code) { - while (get_bits1(gb)) { + while (bitstream_read_bit(bc)) { ++size; if (size > mp->max_codes_bits) { av_log(mp->avctx, AV_LOG_ERROR, "invalid code size %d/%d\n", size, mp->max_codes_bits); return; } code <<= 1; - mp_get_code(mp, gb, size, code + 1); + mp_get_code(mp, bc, size, code + 1); } if (mp->current_codes_count >= MAX_HUFF_CODES) { av_log(mp->avctx, AV_LOG_ERROR, "too many codes\n"); @@ -135,18 +137,18 @@ static void mp_get_code(MotionPixelsContext *mp, GetBitContext *gb, int size, in mp->codes[mp->current_codes_count++].size = size; } -static void mp_read_codes_table(MotionPixelsContext *mp, GetBitContext *gb) +static void mp_read_codes_table(MotionPixelsContext *mp, BitstreamContext *bc) { if (mp->codes_count == 1) { - mp->codes[0].delta = get_bits(gb, 4); + mp->codes[0].delta = bitstream_read(bc, 4); } else { int i; - mp->max_codes_bits = get_bits(gb, 4); + mp->max_codes_bits = bitstream_read(bc, 4); for (i = 0; i < mp->codes_count; ++i) - mp->codes[i].delta = get_bits(gb, 4); + mp->codes[i].delta = bitstream_read(bc, 4); mp->current_codes_count = 0; - mp_get_code(mp, gb, 0, 0); + mp_get_code(mp, bc, 0, 0); } } @@ -175,16 +177,16 @@ static void mp_set_rgb_from_yuv(MotionPixelsContext *mp, int x, int y, const Yuv *(uint16_t *)&mp->frame->data[0][y * mp->frame->linesize[0] + x * 2] = color; } -static int mp_get_vlc(MotionPixelsContext *mp, GetBitContext *gb) +static int mp_get_vlc(MotionPixelsContext *mp, BitstreamContext *bc) { int i; - i = (mp->codes_count == 1) ? 0 : get_vlc2(gb, mp->vlc.table, mp->max_codes_bits, 1); + i = (mp->codes_count == 1) ? 0 : bitstream_read_vlc(bc, mp->vlc.table, mp->max_codes_bits, 1); i = FFMIN(i, FF_ARRAY_ELEMS(mp->codes) - 1); return mp->codes[i].delta; } -static void mp_decode_line(MotionPixelsContext *mp, GetBitContext *gb, int y) +static void mp_decode_line(MotionPixelsContext *mp, BitstreamContext *bc, int y) { YuvPixel p; const int y0 = y * mp->avctx->width; @@ -211,13 +213,13 @@ static void mp_decode_line(MotionPixelsContext *mp, GetBitContext *gb, int y) memset(mp->gradient_scale, 1, sizeof(mp->gradient_scale)); p = mp_get_yuv_from_rgb(mp, x - 1, y); } else { - p.y += mp_gradient(mp, 0, mp_get_vlc(mp, gb)); + p.y += mp_gradient(mp, 0, mp_get_vlc(mp, bc)); p.y = av_clip_uintp2(p.y, 5); if ((x & 3) == 0) { if ((y & 3) == 0) { - p.v += mp_gradient(mp, 1, mp_get_vlc(mp, gb)); + p.v += mp_gradient(mp, 1, mp_get_vlc(mp, bc)); p.v = av_clip_intp2(p.v, 5); - p.u += mp_gradient(mp, 2, mp_get_vlc(mp, gb)); + p.u += mp_gradient(mp, 2, mp_get_vlc(mp, bc)); p.u = av_clip_intp2(p.u, 5); mp->hpt[((y / 4) * mp->avctx->width + x) / 4] = p; } else { @@ -231,7 +233,8 @@ static void mp_decode_line(MotionPixelsContext *mp, GetBitContext *gb, int y) } } -static void mp_decode_frame_helper(MotionPixelsContext *mp, GetBitContext *gb) +static void mp_decode_frame_helper(MotionPixelsContext *mp, + BitstreamContext *bc) { YuvPixel p; int y, y0; @@ -241,12 +244,12 @@ static void mp_decode_frame_helper(MotionPixelsContext *mp, GetBitContext *gb) memset(mp->gradient_scale, 1, sizeof(mp->gradient_scale)); p = mp_get_yuv_from_rgb(mp, 0, y); } else { - p.y += mp_gradient(mp, 0, mp_get_vlc(mp, gb)); + p.y += mp_gradient(mp, 0, mp_get_vlc(mp, bc)); p.y = av_clip_uintp2(p.y, 5); if ((y & 3) == 0) { - p.v += mp_gradient(mp, 1, mp_get_vlc(mp, gb)); + p.v += mp_gradient(mp, 1, mp_get_vlc(mp, bc)); p.v = av_clip_intp2(p.v, 5); - p.u += mp_gradient(mp, 2, mp_get_vlc(mp, gb)); + p.u += mp_gradient(mp, 2, mp_get_vlc(mp, bc)); p.u = av_clip_intp2(p.u, 5); } mp->vpt[y] = p; @@ -255,7 +258,7 @@ static void mp_decode_frame_helper(MotionPixelsContext *mp, GetBitContext *gb) } for (y0 = 0; y0 < 2; ++y0) for (y = y0; y < mp->avctx->height; y += 2) - mp_decode_line(mp, gb, y); + mp_decode_line(mp, bc, y); } static int mp_decode_frame(AVCodecContext *avctx, @@ -265,7 +268,7 @@ static int mp_decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; MotionPixelsContext *mp = avctx->priv_data; - GetBitContext gb; + BitstreamContext bc; int i, count1, count2, sz, ret; if ((ret = ff_reget_buffer(avctx, mp->frame)) < 0) { @@ -282,29 +285,29 @@ static int mp_decode_frame(AVCodecContext *avctx, if (buf_size & 3) memcpy(mp->bswapbuf + (buf_size & ~3), buf + (buf_size & ~3), buf_size & 3); memset(mp->bswapbuf + buf_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); - init_get_bits(&gb, mp->bswapbuf, buf_size * 8); + bitstream_init(&bc, mp->bswapbuf, buf_size * 8); memset(mp->changes_map, 0, avctx->width * avctx->height); for (i = !(avctx->extradata[1] & 2); i < 2; ++i) { - count1 = get_bits(&gb, 12); - count2 = get_bits(&gb, 12); - mp_read_changes_map(mp, &gb, count1, 8, i); - mp_read_changes_map(mp, &gb, count2, 4, i); + count1 = bitstream_read(&bc, 12); + count2 = bitstream_read(&bc, 12); + mp_read_changes_map(mp, &bc, count1, 8, i); + mp_read_changes_map(mp, &bc, count2, 4, i); } - mp->codes_count = get_bits(&gb, 4); + mp->codes_count = bitstream_read(&bc, 4); if (mp->codes_count == 0) goto end; if (mp->changes_map[0] == 0) { - *(uint16_t *)mp->frame->data[0] = get_bits(&gb, 15); + *(uint16_t *)mp->frame->data[0] = bitstream_read(&bc, 15); mp->changes_map[0] = 1; } - mp_read_codes_table(mp, &gb); + mp_read_codes_table(mp, &bc); - sz = get_bits(&gb, 18); + sz = bitstream_read(&bc, 18); if (avctx->extradata[0] != 5) - sz += get_bits(&gb, 18); + sz += bitstream_read(&bc, 18); if (sz == 0) goto end; @@ -312,7 +315,7 @@ static int mp_decode_frame(AVCodecContext *avctx, goto end; if (init_vlc(&mp->vlc, mp->max_codes_bits, mp->codes_count, &mp->codes[0].size, sizeof(HuffCode), 1, &mp->codes[0].code, sizeof(HuffCode), 4, 0)) goto end; - mp_decode_frame_helper(mp, &gb); + mp_decode_frame_helper(mp, &bc); ff_free_vlc(&mp->vlc); end: From 00b6a765430e5c5cacf0bd1be8b318d631cd4e14 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 5 Feb 2015 19:45:41 +0100 Subject: [PATCH 0770/3374] hmac: Explicitly convert types at function pointer assignment Fixes a number of warnings of the type libavutil/hmac.c:61:21: warning: assignment from incompatible pointer type --- libavutil/hmac.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/libavutil/hmac.c b/libavutil/hmac.c index 378be62fd3ce7..7528fd3b82927 100644 --- a/libavutil/hmac.c +++ b/libavutil/hmac.c @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include +#include #include #include "attributes.h" @@ -25,16 +27,25 @@ #include "md5.h" #include "sha.h" #include "mem.h" +#include "version.h" #define MAX_HASHLEN 32 #define MAX_BLOCKLEN 64 +typedef void (*hmac_final)(void *ctx, uint8_t *dst); +#if FF_API_CRYPTO_SIZE_T +typedef void (*hmac_update)(void *ctx, const uint8_t *src, int len); +#else +typedef void (*hmac_update)(void *ctx, const uint8_t *src, size_t len); +#endif +typedef void (*hmac_init)(void *ctx); + struct AVHMAC { void *hash; int blocklen, hashlen; - void (*final)(void*, uint8_t*); - void (*update)(void*, const uint8_t*, int len); - void (*init)(void*); + hmac_final final; + hmac_update update; + hmac_init init; uint8_t key[MAX_BLOCKLEN]; int keylen; }; @@ -58,33 +69,33 @@ AVHMAC *av_hmac_alloc(enum AVHMACType type) case AV_HMAC_MD5: c->blocklen = 64; c->hashlen = 16; - c->init = av_md5_init; - c->update = av_md5_update; - c->final = av_md5_final; + c->init = (hmac_init) av_md5_init; + c->update = (hmac_update) av_md5_update; + c->final = (hmac_final) av_md5_final; c->hash = av_md5_alloc(); break; case AV_HMAC_SHA1: c->blocklen = 64; c->hashlen = 20; c->init = sha160_init; - c->update = av_sha_update; - c->final = av_sha_final; + c->update = (hmac_update) av_sha_update; + c->final = (hmac_final) av_sha_final; c->hash = av_sha_alloc(); break; case AV_HMAC_SHA224: c->blocklen = 64; c->hashlen = 28; c->init = sha224_init; - c->update = av_sha_update; - c->final = av_sha_final; + c->update = (hmac_update) av_sha_update; + c->final = (hmac_final) av_sha_final; c->hash = av_sha_alloc(); break; case AV_HMAC_SHA256: c->blocklen = 64; c->hashlen = 32; c->init = sha256_init; - c->update = av_sha_update; - c->final = av_sha_final; + c->update = (hmac_update) av_sha_update; + c->final = (hmac_final) av_sha_final; c->hash = av_sha_alloc(); break; default: From 9aec009f65f737c7566b2329b5cbd975665d1e02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Tue, 12 Apr 2016 12:29:20 +0200 Subject: [PATCH 0771/3374] dvbsubdec: Convert to the new bitstream reader --- libavcodec/dvbsubdec.c | 68 +++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c index c3248c99191e8..2b9760fb35c8f 100644 --- a/libavcodec/dvbsubdec.c +++ b/libavcodec/dvbsubdec.c @@ -20,7 +20,7 @@ */ #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "bytestream.h" #include "internal.h" #include "libavutil/colorspace.h" @@ -330,16 +330,16 @@ static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, const uint8_t **srcbuf, int buf_size, int non_mod, uint8_t *map_table) { - GetBitContext gb; + BitstreamContext bc; int bits; int run_length; int pixels_read = 0; - init_get_bits(&gb, *srcbuf, buf_size << 3); + bitstream_init(&bc, *srcbuf, buf_size << 3); - while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) { - bits = get_bits(&gb, 2); + while (bitstream_tell(&bc) < buf_size << 3 && pixels_read < dbuf_len) { + bits = bitstream_read(&bc, 2); if (bits) { if (non_mod != 1 || bits != 1) { @@ -350,10 +350,10 @@ static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, } pixels_read++; } else { - bits = get_bits1(&gb); + bits = bitstream_read_bit(&bc); if (bits == 1) { - run_length = get_bits(&gb, 3) + 3; - bits = get_bits(&gb, 2); + run_length = bitstream_read(&bc, 3) + 3; + bits = bitstream_read(&bc, 2); if (non_mod == 1 && bits == 1) pixels_read += run_length; @@ -366,12 +366,12 @@ static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, } } } else { - bits = get_bits1(&gb); + bits = bitstream_read_bit(&bc); if (bits == 0) { - bits = get_bits(&gb, 2); + bits = bitstream_read(&bc, 2); if (bits == 2) { - run_length = get_bits(&gb, 4) + 12; - bits = get_bits(&gb, 2); + run_length = bitstream_read(&bc, 4) + 12; + bits = bitstream_read(&bc, 2); if (non_mod == 1 && bits == 1) pixels_read += run_length; @@ -384,8 +384,8 @@ static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, } } } else if (bits == 3) { - run_length = get_bits(&gb, 8) + 29; - bits = get_bits(&gb, 2); + run_length = bitstream_read(&bc, 8) + 29; + bits = bitstream_read(&bc, 2); if (non_mod == 1 && bits == 1) pixels_read += run_length; @@ -408,7 +408,7 @@ static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, *destbuf++ = bits; } } else { - (*srcbuf) += (get_bits_count(&gb) + 7) >> 3; + *srcbuf += (bitstream_tell(&bc) + 7) >> 3; return pixels_read; } } else { @@ -423,10 +423,10 @@ static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, } } - if (get_bits(&gb, 6)) + if (bitstream_read(&bc, 6)) av_log(NULL, AV_LOG_ERROR, "DVBSub error: line overflow\n"); - (*srcbuf) += (get_bits_count(&gb) + 7) >> 3; + *srcbuf += (bitstream_tell(&bc) + 7) >> 3; return pixels_read; } @@ -435,16 +435,16 @@ static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, const uint8_t **srcbuf, int buf_size, int non_mod, uint8_t *map_table) { - GetBitContext gb; + BitstreamContext bc; int bits; int run_length; int pixels_read = 0; - init_get_bits(&gb, *srcbuf, buf_size << 3); + bitstream_init(&bc, *srcbuf, buf_size << 3); - while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) { - bits = get_bits(&gb, 4); + while (bitstream_tell(&bc) < buf_size << 3 && pixels_read < dbuf_len) { + bits = bitstream_read(&bc, 4); if (bits) { if (non_mod != 1 || bits != 1) { @@ -455,12 +455,12 @@ static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, } pixels_read++; } else { - bits = get_bits1(&gb); + bits = bitstream_read_bit(&bc); if (bits == 0) { - run_length = get_bits(&gb, 3); + run_length = bitstream_read(&bc, 3); if (run_length == 0) { - (*srcbuf) += (get_bits_count(&gb) + 7) >> 3; + *srcbuf += (bitstream_tell(&bc) + 7) >> 3; return pixels_read; } @@ -476,10 +476,10 @@ static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, pixels_read++; } } else { - bits = get_bits1(&gb); + bits = bitstream_read_bit(&bc); if (bits == 0) { - run_length = get_bits(&gb, 2) + 4; - bits = get_bits(&gb, 4); + run_length = bitstream_read(&bc, 2) + 4; + bits = bitstream_read(&bc, 4); if (non_mod == 1 && bits == 1) pixels_read += run_length; @@ -492,10 +492,10 @@ static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, } } } else { - bits = get_bits(&gb, 2); + bits = bitstream_read(&bc, 2); if (bits == 2) { - run_length = get_bits(&gb, 4) + 9; - bits = get_bits(&gb, 4); + run_length = bitstream_read(&bc, 4) + 9; + bits = bitstream_read(&bc, 4); if (non_mod == 1 && bits == 1) pixels_read += run_length; @@ -508,8 +508,8 @@ static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, } } } else if (bits == 3) { - run_length = get_bits(&gb, 8) + 25; - bits = get_bits(&gb, 4); + run_length = bitstream_read(&bc, 8) + 25; + bits = bitstream_read(&bc, 4); if (non_mod == 1 && bits == 1) pixels_read += run_length; @@ -544,10 +544,10 @@ static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, } } - if (get_bits(&gb, 8)) + if (bitstream_read(&bc, 8)) av_log(NULL, AV_LOG_ERROR, "DVBSub error: line overflow\n"); - (*srcbuf) += (get_bits_count(&gb) + 7) >> 3; + *srcbuf += (bitstream_tell(&bc) + 7) >> 3; return pixels_read; } From 4e2505103146c539c6277b8d9d7e6840f6f1db07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Tue, 12 Apr 2016 12:32:06 +0200 Subject: [PATCH 0772/3374] adx: Convert to the new bitstream reader --- libavcodec/adxdec.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index dc587b2733485..a3344ae695872 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -20,9 +20,10 @@ */ #include "libavutil/intreadwrite.h" + #include "avcodec.h" #include "adx.h" -#include "get_bits.h" +#include "bitstream.h" #include "internal.h" /** @@ -66,7 +67,7 @@ static int adx_decode(ADXContext *c, int16_t *out, int offset, const uint8_t *in, int ch) { ADXChannelState *prev = &c->prev[ch]; - GetBitContext gb; + BitstreamContext bc; int scale = AV_RB16(in); int i; int s0, s1, s2, d; @@ -75,12 +76,12 @@ static int adx_decode(ADXContext *c, int16_t *out, int offset, if (scale & 0x8000) return -1; - init_get_bits(&gb, in + 2, (BLOCK_SIZE - 2) * 8); + bitstream_init(&bc, in + 2, (BLOCK_SIZE - 2) * 8); out += offset; s1 = prev->s1; s2 = prev->s2; for (i = 0; i < BLOCK_SAMPLES; i++) { - d = get_sbits(&gb, 4); + d = bitstream_read_signed(&bc, 4); s0 = ((d << COEFF_BITS) * scale + c->coeff[0] * s1 + c->coeff[1] * s2) >> COEFF_BITS; s2 = s1; s1 = av_clip_int16(s0); From bd6496fa07e32fd09ceb79404f9af43df959bcb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Tue, 12 Apr 2016 17:18:09 +0200 Subject: [PATCH 0773/3374] interplayvideo: Convert to the new bitstream reader --- libavcodec/interplayvideo.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/interplayvideo.c b/libavcodec/interplayvideo.c index e0d1e91992fe2..fab9f2724c99f 100644 --- a/libavcodec/interplayvideo.c +++ b/libavcodec/interplayvideo.c @@ -40,8 +40,8 @@ #define BITSTREAM_READER_LE #include "avcodec.h" +#include "bitstream.h" #include "bytestream.h" -#include "get_bits.h" #include "hpeldsp.h" #include "internal.h" @@ -881,7 +881,7 @@ static void ipvideo_decode_opcodes(IpvideoContext *s, AVFrame *frame) int x, y; unsigned char opcode; int ret; - GetBitContext gb; + BitstreamContext bc; bytestream2_skip(&s->stream_ptr, 14); /* data starts 14 bytes in */ if (!s->is_16bpp) { @@ -898,10 +898,10 @@ static void ipvideo_decode_opcodes(IpvideoContext *s, AVFrame *frame) s->upper_motion_limit_offset = (s->avctx->height - 8) * frame->linesize[0] + (s->avctx->width - 8) * (1 + s->is_16bpp); - init_get_bits(&gb, s->decoding_map, s->decoding_map_size * 8); + bitstream_init(&bc, s->decoding_map, s->decoding_map_size * 8); for (y = 0; y < s->avctx->height; y += 8) { for (x = 0; x < s->avctx->width; x += 8) { - opcode = get_bits(&gb, 4); + opcode = bitstream_read(&bc, 4); ff_dlog(s->avctx, " block @ (%3d, %3d): encoding 0x%X, data ptr offset %d\n", From 37fab0661a760b2a9d727939d72e629acee1a6ef Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Wed, 4 Jan 2017 23:17:23 +0000 Subject: [PATCH 0774/3374] vaapi_encode: Fix GOP sizing This change makes the configured GOP size be respected exactly - previously the value could be exceeded slightly due to flaws in the frame type selection logic. --- libavcodec/vaapi_encode.c | 78 ++++++++++++++++++--------------------- libavcodec/vaapi_encode.h | 4 +- 2 files changed, 36 insertions(+), 46 deletions(-) diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index 11e46eabe78b3..c670ae62dfadd 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -635,50 +635,33 @@ static int vaapi_encode_get_next(AVCodecContext *avctx, } } - if (ctx->input_order == 0) { - // First frame is always an IDR frame. - av_assert0(!ctx->pic_start && !ctx->pic_end); - - pic = vaapi_encode_alloc(); - if (!pic) - return AVERROR(ENOMEM); - - pic->type = PICTURE_TYPE_IDR; - pic->display_order = 0; - pic->encode_order = 0; - - ctx->pic_start = ctx->pic_end = pic; - - *pic_out = pic; - return 0; - } - pic = vaapi_encode_alloc(); if (!pic) return AVERROR(ENOMEM); - if (ctx->p_per_i == 0 || ctx->p_counter == ctx->p_per_i) { - if (ctx->i_per_idr == 0 || ctx->i_counter == ctx->i_per_idr) { - pic->type = PICTURE_TYPE_IDR; - ctx->i_counter = 0; - } else { - pic->type = PICTURE_TYPE_I; - ++ctx->i_counter; - } + if (ctx->input_order == 0 || ctx->gop_counter >= avctx->gop_size) { + pic->type = PICTURE_TYPE_IDR; + ctx->gop_counter = 1; + ctx->p_counter = 0; + } else if (ctx->p_counter >= ctx->p_per_i) { + pic->type = PICTURE_TYPE_I; + ++ctx->gop_counter; ctx->p_counter = 0; } else { pic->type = PICTURE_TYPE_P; pic->refs[0] = ctx->pic_end; pic->nb_refs = 1; + ++ctx->gop_counter; ++ctx->p_counter; } start = end = pic; if (pic->type != PICTURE_TYPE_IDR) { // If that was not an IDR frame, add B-frames display-before and - // encode-after it. + // encode-after it, but not exceeding the GOP size. - for (i = 0; i < ctx->b_per_p; i++) { + for (i = 0; i < ctx->b_per_p && + ctx->gop_counter < avctx->gop_size; i++) { pic = vaapi_encode_alloc(); if (!pic) goto fail; @@ -692,23 +675,32 @@ static int vaapi_encode_get_next(AVCodecContext *avctx, pic->display_order = ctx->input_order + ctx->b_per_p - i - 1; pic->encode_order = pic->display_order + 1; start = pic; + + ++ctx->gop_counter; } } - for (i = 0, pic = start; pic; i++, pic = pic->next) { - pic->display_order = ctx->input_order + i; - if (end->type == PICTURE_TYPE_IDR) - pic->encode_order = ctx->input_order + i; - else if (pic == end) - pic->encode_order = ctx->input_order; - else - pic->encode_order = ctx->input_order + i + 1; - } + if (ctx->input_order == 0) { + pic->display_order = 0; + pic->encode_order = 0; - av_assert0(ctx->pic_end); - ctx->pic_end->next = start; - ctx->pic_end = end; + ctx->pic_start = ctx->pic_end = pic; + } else { + for (i = 0, pic = start; pic; i++, pic = pic->next) { + pic->display_order = ctx->input_order + i; + if (end->type == PICTURE_TYPE_IDR) + pic->encode_order = ctx->input_order + i; + else if (pic == end) + pic->encode_order = ctx->input_order; + else + pic->encode_order = ctx->input_order + i + 1; + } + + av_assert0(ctx->pic_end); + ctx->pic_end->next = start; + ctx->pic_end = end; + } *pic_out = start; av_log(avctx, AV_LOG_DEBUG, "Pictures:"); @@ -1249,8 +1241,9 @@ static av_cold int vaapi_encode_create_recon_frames(AVCodecContext *avctx) ctx->recon_frames->sw_format = recon_format; ctx->recon_frames->width = ctx->surface_width; ctx->recon_frames->height = ctx->surface_height; - ctx->recon_frames->initial_pool_size = - avctx->max_b_frames + 3; + // At most three IDR/I/P frames and two runs of B frames can be in + // flight at any one time. + ctx->recon_frames->initial_pool_size = 3 + 2 * avctx->max_b_frames; err = av_hwframe_ctx_init(ctx->recon_frames_ref); if (err < 0) { @@ -1364,7 +1357,6 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) ctx->output_order = - ctx->output_delay - 1; // Currently we never generate I frames, only IDR. - ctx->i_per_idr = 0; ctx->p_per_i = ((avctx->gop_size + avctx->max_b_frames) / (avctx->max_b_frames + 1)); ctx->b_per_p = avctx->max_b_frames; diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h index a9ab52788096a..e8ed4fdb4e9f3 100644 --- a/libavcodec/vaapi_encode.h +++ b/libavcodec/vaapi_encode.h @@ -190,11 +190,9 @@ typedef struct VAAPIEncodeContext { int64_t ts_ring[MAX_REORDER_DELAY * 3]; // Frame type decision. - int i_per_idr; int p_per_i; int b_per_p; - int idr_counter; - int i_counter; + int gop_counter; int p_counter; int end_of_stream; From a3c3a5eac20a51d402c332cdf5220fff40a7943f Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Mon, 12 Dec 2016 21:25:28 +0000 Subject: [PATCH 0775/3374] vaapi_encode: Support forcing IDR frames via AVFrame.pict_type --- libavcodec/vaapi_encode.c | 27 +++++++++++++++++++++++---- libavcodec/vaapi_encode.h | 1 + 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index c670ae62dfadd..c93bfcc0b10f9 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -590,6 +590,10 @@ static int vaapi_encode_step(AVCodecContext *avctx, } else if (ctx->issue_mode == ISSUE_MODE_MAXIMISE_THROUGHPUT) { int activity; + // Run through the list of all available pictures repeatedly + // and issue the first one found which has all dependencies + // available (including previously-issued but not necessarily + // completed pictures). do { activity = 0; for (pic = ctx->pic_start; pic; pic = pic->next) { @@ -605,9 +609,15 @@ static int vaapi_encode_step(AVCodecContext *avctx, if (err < 0) return err; activity = 1; + // Start again from the beginning of the list, + // because issuing this picture may have satisfied + // forward dependencies of earlier ones. + break; } } while(activity); + // If we had a defined target for this step then it will + // always have been issued by now. if (target) { av_assert0(target->encode_issued && "broken dependencies?"); } @@ -639,8 +649,10 @@ static int vaapi_encode_get_next(AVCodecContext *avctx, if (!pic) return AVERROR(ENOMEM); - if (ctx->input_order == 0 || ctx->gop_counter >= avctx->gop_size) { + if (ctx->input_order == 0 || ctx->force_idr || + ctx->gop_counter >= avctx->gop_size) { pic->type = PICTURE_TYPE_IDR; + ctx->force_idr = 0; ctx->gop_counter = 1; ctx->p_counter = 0; } else if (ctx->p_counter >= ctx->p_per_i) { @@ -722,7 +734,7 @@ static int vaapi_encode_get_next(AVCodecContext *avctx, return AVERROR(ENOMEM); } -static int vaapi_encode_mangle_end(AVCodecContext *avctx) +static int vaapi_encode_truncate_gop(AVCodecContext *avctx) { VAAPIEncodeContext *ctx = avctx->priv_data; VAAPIEncodePicture *pic, *last_pic, *next; @@ -772,7 +784,7 @@ static int vaapi_encode_mangle_end(AVCodecContext *avctx) // mangle anything. } - av_log(avctx, AV_LOG_DEBUG, "Pictures at end of stream:"); + av_log(avctx, AV_LOG_DEBUG, "Pictures ending truncated GOP:"); for (pic = ctx->pic_start; pic; pic = pic->next) { av_log(avctx, AV_LOG_DEBUG, " %s (%"PRId64"/%"PRId64")", picture_type_name[pic->type], @@ -826,6 +838,13 @@ int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt, av_log(avctx, AV_LOG_DEBUG, "Encode frame: %ux%u (%"PRId64").\n", input_image->width, input_image->height, input_image->pts); + if (input_image->pict_type == AV_PICTURE_TYPE_I) { + err = vaapi_encode_truncate_gop(avctx); + if (err < 0) + goto fail; + ctx->force_idr = 1; + } + err = vaapi_encode_get_next(avctx, &pic); if (err) { av_log(avctx, AV_LOG_ERROR, "Input setup failed: %d.\n", err); @@ -854,7 +873,7 @@ int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt, } else { if (!ctx->end_of_stream) { - err = vaapi_encode_mangle_end(avctx); + err = vaapi_encode_truncate_gop(avctx); if (err < 0) goto fail; ctx->end_of_stream = 1; diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h index e8ed4fdb4e9f3..2a72510b83193 100644 --- a/libavcodec/vaapi_encode.h +++ b/libavcodec/vaapi_encode.h @@ -192,6 +192,7 @@ typedef struct VAAPIEncodeContext { // Frame type decision. int p_per_i; int b_per_p; + int force_idr; int gop_counter; int p_counter; int end_of_stream; From 89725a8512721fffd190021ded2d3f5b42e20e2a Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Wed, 4 Jan 2017 23:05:10 +0000 Subject: [PATCH 0776/3374] vaapi_h264: Scale log2_max_pic_order_cnt_lsb with max_b_frames Before this change, it was possible to overflow pic_order_cnt_lsb and generate a stream with invalid POC numbering. This makes sure that the field is large enough that a single IDR B* P sequence uses fewer than half the available POC lsb values. --- libavcodec/vaapi_encode_h264.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index deb99a7d2f435..74e7cb1c16f5a 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -800,6 +800,8 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) vseq->seq_fields.bits.direct_8x8_inference_flag = 1; vseq->seq_fields.bits.log2_max_frame_num_minus4 = 4; vseq->seq_fields.bits.pic_order_cnt_type = 0; + vseq->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = + av_clip(av_log2(avctx->max_b_frames + 1) - 2, 0, 12); if (avctx->width != ctx->surface_width || avctx->height != ctx->surface_height) { From 2a2889e130fee6d3c11e506328388afb317626ed Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 5 Jan 2017 17:02:31 +0100 Subject: [PATCH 0777/3374] build: Remove stray duplicate conditional variable declaration --- Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Makefile b/Makefile index a9f5f9a8e9c1c..d480ea5c373a2 100644 --- a/Makefile +++ b/Makefile @@ -121,8 +121,6 @@ all: $(AVPROGS) $(TOOLS): %$(EXESUF): %.o $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(EXTRALIBS) $(ELIBS) -tools/cws2fws$(EXESUF): ELIBS = $(ZLIB) - CONFIGURABLE_COMPONENTS = \ $(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/all*.c)) \ $(SRC_PATH)/libavcodec/bitstream_filters.c \ From 122de16dd8108a59a55d30543c9f28b5f61b02d1 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 17 May 2011 17:06:57 +0200 Subject: [PATCH 0778/3374] Replace cmdutils_common_opts.h by a macro --- Makefile | 3 +-- avconv_opt.c | 2 +- avplay.c | 2 +- avprobe.c | 2 +- cmdutils.h | 20 ++++++++++++++++++++ cmdutils_common_opts.h | 18 ------------------ 6 files changed, 24 insertions(+), 23 deletions(-) delete mode 100644 cmdutils_common_opts.h diff --git a/Makefile b/Makefile index d480ea5c373a2..98eb3ab1d95f9 100644 --- a/Makefile +++ b/Makefile @@ -103,8 +103,7 @@ FFLIBS := avutil DATA_FILES := $(wildcard $(SRC_PATH)/presets/*.avpreset) -SKIPHEADERS = cmdutils_common_opts.h \ - compat/w32pthreads.h +SKIPHEADERS = compat/w32pthreads.h # first so "all" becomes default target all: all-yes diff --git a/avconv_opt.c b/avconv_opt.c index 4d7140dc46063..8b43f0f4e2bb3 100644 --- a/avconv_opt.c +++ b/avconv_opt.c @@ -2474,7 +2474,7 @@ int avconv_parse_options(int argc, char **argv) #define OFFSET(x) offsetof(OptionsContext, x) const OptionDef options[] = { /* main options */ -#include "cmdutils_common_opts.h" + CMDUTILS_COMMON_OPTIONS { "f", HAS_ARG | OPT_STRING | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(format) }, "force format", "fmt" }, diff --git a/avplay.c b/avplay.c index e5ee9dbbef435..18879e16bcc53 100644 --- a/avplay.c +++ b/avplay.c @@ -2904,7 +2904,7 @@ static int opt_duration(void *optctx, const char *opt, const char *arg) #define OFF(x) offsetof(PlayerState, x) static const OptionDef options[] = { -#include "cmdutils_common_opts.h" + CMDUTILS_COMMON_OPTIONS { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" }, { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" }, { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" }, diff --git a/avprobe.c b/avprobe.c index f0c942ad637d7..a24e6440eb613 100644 --- a/avprobe.c +++ b/avprobe.c @@ -1094,7 +1094,7 @@ static int opt_pretty(void *optctx, const char *opt, const char *arg) } static const OptionDef real_options[] = { -#include "cmdutils_common_opts.h" + CMDUTILS_COMMON_OPTIONS { "f", HAS_ARG, {.func_arg = opt_format}, "force format", "format" }, { "of", HAS_ARG, {.func_arg = opt_output_format}, "output the document either as ini or json", "output_format" }, { "unit", OPT_BOOL, {&show_value_unit}, diff --git a/cmdutils.h b/cmdutils.h index 45d98586fa58a..cc78ac5911de9 100644 --- a/cmdutils.h +++ b/cmdutils.h @@ -182,6 +182,26 @@ typedef struct OptionDef { void show_help_options(const OptionDef *options, const char *msg, int req_flags, int rej_flags, int alt_flags); +#define CMDUTILS_COMMON_OPTIONS \ + { "L", OPT_EXIT, { .func_arg = show_license }, "show license" }, \ + { "h", OPT_EXIT, { .func_arg = show_help }, "show help", "topic" }, \ + { "?", OPT_EXIT, { .func_arg = show_help }, "show help", "topic" }, \ + { "help", OPT_EXIT, { .func_arg = show_help }, "show help", "topic" }, \ + { "-help", OPT_EXIT, { .func_arg = show_help }, "show help", "topic" }, \ + { "version", OPT_EXIT, { .func_arg = show_version }, "show version" }, \ + { "formats", OPT_EXIT, { .func_arg = show_formats }, "show available formats" }, \ + { "codecs", OPT_EXIT, { .func_arg = show_codecs }, "show available codecs" }, \ + { "decoders", OPT_EXIT, { .func_arg = show_decoders }, "show available decoders" }, \ + { "encoders", OPT_EXIT, { .func_arg = show_encoders }, "show available encoders" }, \ + { "bsfs", OPT_EXIT, { .func_arg = show_bsfs }, "show available bit stream filters" }, \ + { "protocols", OPT_EXIT, { .func_arg = show_protocols }, "show available protocols" }, \ + { "filters", OPT_EXIT, { .func_arg = show_filters }, "show available filters" }, \ + { "pix_fmts", OPT_EXIT, { .func_arg = show_pix_fmts }, "show available pixel formats" }, \ + { "sample_fmts", OPT_EXIT, { .func_arg = show_sample_fmts }, "show available audio sample formats" }, \ + { "loglevel", HAS_ARG, { .func_arg = opt_loglevel }, "set libav* logging level", "loglevel" }, \ + { "v", HAS_ARG, { .func_arg = opt_loglevel }, "set libav* logging level", "loglevel" }, \ + { "cpuflags", HAS_ARG | OPT_EXPERT, { .func_arg = opt_cpuflags }, "set CPU flags mask", "mask" }, \ + /** * Show help for all options with given flags in class and all its * children. diff --git a/cmdutils_common_opts.h b/cmdutils_common_opts.h deleted file mode 100644 index 8693f59c561ee..0000000000000 --- a/cmdutils_common_opts.h +++ /dev/null @@ -1,18 +0,0 @@ - { "L" , OPT_EXIT, {.func_arg = show_license}, "show license" }, - { "h" , OPT_EXIT, {.func_arg = show_help}, "show help", "topic" }, - { "?" , OPT_EXIT, {.func_arg = show_help}, "show help", "topic" }, - { "help" , OPT_EXIT, {.func_arg = show_help}, "show help", "topic" }, - { "-help" , OPT_EXIT, {.func_arg = show_help}, "show help", "topic" }, - { "version" , OPT_EXIT, {.func_arg = show_version}, "show version" }, - { "formats" , OPT_EXIT, {.func_arg = show_formats }, "show available formats" }, - { "codecs" , OPT_EXIT, {.func_arg = show_codecs }, "show available codecs" }, - { "decoders" , OPT_EXIT, {.func_arg = show_decoders }, "show available decoders" }, - { "encoders" , OPT_EXIT, {.func_arg = show_encoders }, "show available encoders" }, - { "bsfs" , OPT_EXIT, {.func_arg = show_bsfs }, "show available bit stream filters" }, - { "protocols" , OPT_EXIT, {.func_arg = show_protocols}, "show available protocols" }, - { "filters" , OPT_EXIT, {.func_arg = show_filters }, "show available filters" }, - { "pix_fmts" , OPT_EXIT, {.func_arg = show_pix_fmts }, "show available pixel formats" }, - { "sample_fmts", OPT_EXIT, {.func_arg = show_sample_fmts }, "show available audio sample formats" }, - { "loglevel" , HAS_ARG, {.func_arg = opt_loglevel}, "set libav* logging level", "loglevel" }, - { "v", HAS_ARG, {.func_arg = opt_loglevel}, "set libav* logging level", "loglevel" }, - { "cpuflags", HAS_ARG | OPT_EXPERT, { .func_arg = opt_cpuflags }, "set CPU flags mask", "mask" }, From f67235a28cef44fcd97ae74ad53bbbc0d7f63d60 Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Wed, 4 Jan 2017 13:44:12 +0100 Subject: [PATCH 0779/3374] dxva2: get the slice number directly from the surface in D3D11VA No need to loop through the known surfaces, we'll use the requested surface anyway. The loop is only done for DXVA2. Signed-off-by: Anton Khirnov --- libavcodec/dxva2.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c index 6fc4f97d74eef..b0452b6a9ade6 100644 --- a/libavcodec/dxva2.c +++ b/libavcodec/dxva2.c @@ -41,19 +41,19 @@ unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx, void *surface = get_surface(frame); unsigned i; - for (i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++) { #if CONFIG_D3D11VA - if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD && ctx->d3d11va.surface[i] == surface) { - D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc; - ID3D11VideoDecoderOutputView_GetDesc(ctx->d3d11va.surface[i], &viewDesc); - return viewDesc.Texture2D.ArraySlice; - } + if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) { + D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc; + ID3D11VideoDecoderOutputView_GetDesc((ID3D11VideoDecoderOutputView*) surface, &viewDesc); + return viewDesc.Texture2D.ArraySlice; + } #endif #if CONFIG_DXVA2 + for (i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++) { if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD && ctx->dxva2.surface[i] == surface) return i; -#endif } +#endif assert(0); return 0; From ac3c3ee678e51b05a2a7c30ce79465db46ba01fa Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Tue, 3 Jan 2017 17:31:51 +0100 Subject: [PATCH 0780/3374] dxva2: allow an empty array of ID3D11VideoDecoderOutputView We can pick the correct slice index directly from the ID3D11VideoDecoderOutputView casted from data[3]. Signed-off-by: Anton Khirnov --- libavcodec/dxva2_internal.h | 4 ++-- libavcodec/version.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/dxva2_internal.h b/libavcodec/dxva2_internal.h index daf54b20e5c09..8b774b14f31e6 100644 --- a/libavcodec/dxva2_internal.h +++ b/libavcodec/dxva2_internal.h @@ -73,7 +73,7 @@ typedef union { #define DXVA_CONTEXT_CFG_RESIDACCEL(avctx, ctx) (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.cfg->ConfigResidDiffAccelerator : ctx->dxva2.cfg->ConfigResidDiffAccelerator) #define DXVA_CONTEXT_VALID(avctx, ctx) (DXVA_CONTEXT_DECODER(avctx, ctx) && \ DXVA_CONTEXT_CFG(avctx, ctx) && \ - DXVA_CONTEXT_COUNT(avctx, ctx)) + (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD || ctx->dxva2.surface_count)) #elif CONFIG_DXVA2 #define DXVA_CONTEXT_WORKAROUND(avctx, ctx) (ctx->dxva2.workaround) #define DXVA_CONTEXT_COUNT(avctx, ctx) (ctx->dxva2.surface_count) @@ -93,7 +93,7 @@ typedef union { #define DXVA_CONTEXT_CFG_BITSTREAM(avctx, ctx) (ctx->d3d11va.cfg->ConfigBitstreamRaw) #define DXVA_CONTEXT_CFG_INTRARESID(avctx, ctx) (ctx->d3d11va.cfg->ConfigIntraResidUnsigned) #define DXVA_CONTEXT_CFG_RESIDACCEL(avctx, ctx) (ctx->d3d11va.cfg->ConfigResidDiffAccelerator) -#define DXVA_CONTEXT_VALID(avctx, ctx) (ctx->d3d11va.decoder && ctx->d3d11va.cfg && ctx->d3d11va.surface_count) +#define DXVA_CONTEXT_VALID(avctx, ctx) (ctx->d3d11va.decoder && ctx->d3d11va.cfg) #endif unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx, diff --git a/libavcodec/version.h b/libavcodec/version.h index 5b6fb6ce592ba..7348a0c267262 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 30 -#define LIBAVCODEC_VERSION_MICRO 2 +#define LIBAVCODEC_VERSION_MICRO 3 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From b68e353136db6f963212c457281d9716516cdc59 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 7 Jan 2017 21:06:16 +0100 Subject: [PATCH 0781/3374] qsvdec: do not sync PIX_FMT_QSV surfaces Introducing enforced sync points in arbitrary places is bad for performance. Since the vast majority of receiving code (QSV VPP or encoders, retrieving frames through hwcontext) will do the syncing, this change should not be visible to most callers. But bumping micro just in case. This is also consistent with what VAAPI hwaccel does. --- libavcodec/qsvdec.c | 8 +++++--- libavcodec/version.h | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index b83b0fcda82f3..0cbe5094c76ae 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -363,9 +363,11 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q, av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL); out_frame->queued = 0; - do { - ret = MFXVideoCORE_SyncOperation(q->session, *sync, 1000); - } while (ret == MFX_WRN_IN_EXECUTION); + if (avctx->pix_fmt != AV_PIX_FMT_QSV) { + do { + ret = MFXVideoCORE_SyncOperation(q->session, *sync, 1000); + } while (ret == MFX_WRN_IN_EXECUTION); + } av_freep(&sync); diff --git a/libavcodec/version.h b/libavcodec/version.h index 7348a0c267262..106543de531f2 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 30 -#define LIBAVCODEC_VERSION_MICRO 3 +#define LIBAVCODEC_VERSION_MICRO 4 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From 52627248e49e58eb4b78e4fcda90a64f4c476ea3 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 18 Dec 2016 12:30:27 +0100 Subject: [PATCH 0782/3374] frame: add a cropping rectangle to AVFrame Extend the width/height doxy to clarify that it should store coded values. --- doc/APIchanges | 4 ++++ libavutil/frame.c | 4 ++++ libavutil/frame.h | 28 +++++++++++++++++++++++++++- libavutil/version.h | 2 +- 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 942337903f178..ba137650b611b 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,10 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-xx-xx - xxxxxxx - lavu 55.30.0 - frame.h + Add AVFrame.crop_left/right/top/bottom fields for attaching cropping + information to video frames. + 2016-xx-xx - xxxxxxx Change av_sha_update() and av_md5_sum()/av_md5_update() length parameter type to size_t at next major bump. diff --git a/libavutil/frame.c b/libavutil/frame.c index 1c14f5f03f094..aafaa57d8b556 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -390,6 +390,10 @@ int av_frame_copy_props(AVFrame *dst, const AVFrame *src) dst->key_frame = src->key_frame; dst->pict_type = src->pict_type; dst->sample_aspect_ratio = src->sample_aspect_ratio; + dst->crop_top = src->crop_top; + dst->crop_bottom = src->crop_bottom; + dst->crop_left = src->crop_left; + dst->crop_right = src->crop_right; dst->pts = src->pts; dst->repeat_pict = src->repeat_pict; dst->interlaced_frame = src->interlaced_frame; diff --git a/libavutil/frame.h b/libavutil/frame.h index 4052199fd3e3e..c718f7bd62cc9 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -25,6 +25,7 @@ #ifndef AVUTIL_FRAME_H #define AVUTIL_FRAME_H +#include #include #include "avutil.h" @@ -180,9 +181,18 @@ typedef struct AVFrame { uint8_t **extended_data; /** - * width and height of the video frame + * @name Video dimensions + * Video frames only. The coded dimensions (in pixels) of the video frame, + * i.e. the size of the rectangle that contains some well-defined values. + * + * @note The part of the frame intended for display/presentation is further + * restricted by the @ref cropping "Cropping rectangle". + * @{ */ int width, height; + /** + * @} + */ /** * number of audio samples (per channel) described by this frame @@ -369,6 +379,22 @@ typedef struct AVFrame { * AVHWFramesContext describing the frame. */ AVBufferRef *hw_frames_ctx; + + /** + * @anchor cropping + * @name Cropping + * Video frames only. The number of pixels to discard from the the + * top/bottom/left/right border of the frame to obtain the sub-rectangle of + * the frame intended for presentation. + * @{ + */ + size_t crop_top; + size_t crop_bottom; + size_t crop_left; + size_t crop_right; + /** + * @} + */ } AVFrame; /** diff --git a/libavutil/version.h b/libavutil/version.h index 3733fea810224..7856a0acc3f9f 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -54,7 +54,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 29 +#define LIBAVUTIL_VERSION_MINOR 30 #define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From 019ab88a95cb31b698506d90e8ce56695a7f1cc5 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 18 Dec 2016 16:42:24 +0100 Subject: [PATCH 0783/3374] lavc: add an option for exporting cropping information to the caller Also, add generic code for handling cropping, so the decoders can export just the cropping size and not bother with the rest. --- doc/APIchanges | 4 ++ libavcodec/avcodec.h | 27 +++++++++ libavcodec/decode.c | 117 ++++++++++++++++++++++++++++++++++++- libavcodec/internal.h | 6 ++ libavcodec/options_table.h | 1 + libavcodec/version.h | 4 +- 6 files changed, 156 insertions(+), 3 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index ba137650b611b..c8c2a219f63d7 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,10 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-xx-xx - xxxxxxx - lavc 57.31.0 - avcodec.h + Add AVCodecContext.apply_cropping to control whether cropping + is handled by libavcodec or the caller. + 2016-xx-xx - xxxxxxx - lavu 55.30.0 - frame.h Add AVFrame.crop_left/right/top/bottom fields for attaching cropping information to video frames. diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 95da50b0e7d8b..18721561d54c8 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3112,6 +3112,33 @@ typedef struct AVCodecContext { * This field should be set before avcodec_open2() is called. */ AVBufferRef *hw_frames_ctx; + + /** + * Video decoding only. Certain video codecs support cropping, meaning that + * only a sub-rectangle of the decoded frame is intended for display. This + * option controls how cropping is handled by libavcodec. + * + * When set to 1 (the default), libavcodec will apply cropping internally. + * I.e. it will modify the output frame width/height fields and offset the + * data pointers (only by as much as possible while preserving alignment, or + * by the full amount if the AV_CODEC_FLAG_UNALIGNED flag is set) so that + * the frames output by the decoder refer only to the cropped area. The + * crop_* fields of the output frames will be zero. + * + * When set to 0, the width/height fields of the output frames will be set + * to the coded dimensions and the crop_* fields will describe the cropping + * rectangle. Applying the cropping is left to the caller. + * + * @warning When hardware acceleration with opaque output frames is used, + * libavcodec is unable to apply cropping from the top/left border. + * + * @note when this option is set to zero, the width/height fields of the + * AVCodecContext and output AVFrames have different meanings. The codec + * context fields store display dimensions (with the coded dimensions in + * coded_width/height), while the frame fields store the coded dimensions + * (with the display dimensions being determined by the crop_* fields). + */ + int apply_cropping; } AVCodecContext; /** diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 0fd41ab48219d..f4088cdae8d6a 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -29,6 +29,7 @@ #include "libavutil/frame.h" #include "libavutil/hwcontext.h" #include "libavutil/imgutils.h" +#include "libavutil/intmath.h" #include "avcodec.h" #include "bytestream.h" @@ -450,6 +451,111 @@ int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacke return 0; } +static int calc_cropping_offsets(size_t offsets[4], const AVFrame *frame, + const AVPixFmtDescriptor *desc) +{ + int i, j; + + for (i = 0; frame->data[i]; i++) { + const AVComponentDescriptor *comp = NULL; + int shift_x = (i == 1 || i == 2) ? desc->log2_chroma_w : 0; + int shift_y = (i == 1 || i == 2) ? desc->log2_chroma_h : 0; + + if (desc->flags & (AV_PIX_FMT_FLAG_PAL | AV_PIX_FMT_FLAG_PSEUDOPAL) && i == 1) { + offsets[i] = 0; + break; + } + + /* find any component descriptor for this plane */ + for (j = 0; j < desc->nb_components; j++) { + if (desc->comp[j].plane == i) { + comp = &desc->comp[j]; + break; + } + } + if (!comp) + return AVERROR_BUG; + + offsets[i] = (frame->crop_top >> shift_y) * frame->linesize[i] + + (frame->crop_left >> shift_x) * comp->step; + } + + return 0; +} + +static int apply_cropping(AVCodecContext *avctx, AVFrame *frame) +{ + const AVPixFmtDescriptor *desc; + size_t offsets[4]; + int i; + + /* make sure we are noisy about decoders returning invalid cropping data */ + if (frame->crop_left >= INT_MAX - frame->crop_right || + frame->crop_top >= INT_MAX - frame->crop_bottom || + (frame->crop_left + frame->crop_right) >= frame->width || + (frame->crop_top + frame->crop_bottom) >= frame->height) { + av_log(avctx, AV_LOG_WARNING, + "Invalid cropping information set by a decoder: %zu/%zu/%zu/%zu " + "(frame size %dx%d). This is a bug, please report it\n", + frame->crop_left, frame->crop_right, frame->crop_top, frame->crop_bottom, + frame->width, frame->height); + frame->crop_left = 0; + frame->crop_right = 0; + frame->crop_top = 0; + frame->crop_bottom = 0; + return 0; + } + + if (!avctx->apply_cropping) + return 0; + + desc = av_pix_fmt_desc_get(frame->format); + if (!desc) + return AVERROR_BUG; + + /* Apply just the right/bottom cropping for hwaccel formats. Bitstream + * formats cannot be easily handled here either (and corresponding decoders + * should not export any cropping anyway), so do the same for those as well. + * */ + if (desc->flags & (AV_PIX_FMT_FLAG_BITSTREAM | AV_PIX_FMT_FLAG_HWACCEL)) { + frame->width -= frame->crop_right; + frame->height -= frame->crop_bottom; + frame->crop_right = 0; + frame->crop_bottom = 0; + return 0; + } + + /* calculate the offsets for each plane */ + calc_cropping_offsets(offsets, frame, desc); + + /* adjust the offsets to avoid breaking alignment */ + if (!(avctx->flags & AV_CODEC_FLAG_UNALIGNED)) { + int min_log2_align = INT_MAX; + + for (i = 0; frame->data[i]; i++) { + int log2_align = offsets[i] ? av_ctz(offsets[i]) : INT_MAX; + min_log2_align = FFMIN(log2_align, min_log2_align); + } + + if (min_log2_align < 5) { + frame->crop_left &= ~((1 << min_log2_align) - 1); + calc_cropping_offsets(offsets, frame, desc); + } + } + + for (i = 0; frame->data[i]; i++) + frame->data[i] += offsets[i]; + + frame->width -= (frame->crop_left + frame->crop_right); + frame->height -= (frame->crop_top + frame->crop_bottom); + frame->crop_left = 0; + frame->crop_right = 0; + frame->crop_top = 0; + frame->crop_bottom = 0; + + return 0; +} + int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame) { AVCodecInternal *avci = avctx->internal; @@ -472,6 +578,14 @@ int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *fr return ret; } + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { + ret = apply_cropping(avctx, frame); + if (ret < 0) { + av_frame_unref(frame); + return ret; + } + } + avctx->frame_number++; return 0; @@ -1029,7 +1143,8 @@ int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) ret = avctx->get_buffer2(avctx, frame, flags); end: - if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && !override_dimensions) { + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && !override_dimensions && + !(avctx->codec->caps_internal & FF_CODEC_CAP_EXPORTS_CROPPING)) { frame->width = avctx->width; frame->height = avctx->height; } diff --git a/libavcodec/internal.h b/libavcodec/internal.h index 796d45ff6ebf8..5b82504bfb37b 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -53,6 +53,12 @@ * from the input AVPacket. */ #define FF_CODEC_CAP_SETS_PKT_DTS (1 << 2) +/** + * The decoder sets the cropping fields in the output frames manually. + * If this cap is set, the generic code will initialize output frame + * dimensions to coded rather than display values. + */ +#define FF_CODEC_CAP_EXPORTS_CROPPING (1 << 3) #ifdef DEBUG # define ff_dlog(ctx, ...) av_log(ctx, AV_LOG_DEBUG, __VA_ARGS__) diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index 4deb2235520db..3ac53fb748b5e 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -531,6 +531,7 @@ static const AVOption avcodec_options[] = { #if FF_API_SIDEDATA_ONLY_PKT {"side_data_only_packets", NULL, OFFSET(side_data_only_packets), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, A|V|E }, #endif +{"apply_cropping", NULL, OFFSET(apply_cropping), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, V | D }, {NULL}, }; diff --git a/libavcodec/version.h b/libavcodec/version.h index 106543de531f2..df0c01f4ccda5 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 30 -#define LIBAVCODEC_VERSION_MICRO 4 +#define LIBAVCODEC_VERSION_MINOR 31 +#define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From a02ae1c6837a54ed9e7735da2b1f789b2f4b6e13 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 18 Dec 2016 21:11:47 +0100 Subject: [PATCH 0784/3374] hevcdec: export cropping information instead of handling it internally --- libavcodec/hevc_parser.c | 6 ++++-- libavcodec/hevc_ps.c | 33 ++++++++++++--------------------- libavcodec/hevc_ps.h | 2 -- libavcodec/hevc_refs.c | 19 ++++--------------- libavcodec/hevcdec.c | 7 ++++--- libavcodec/hevcdec.h | 2 -- 6 files changed, 24 insertions(+), 45 deletions(-) diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c index 49e712269bd6c..74a0257073d13 100644 --- a/libavcodec/hevc_parser.c +++ b/libavcodec/hevc_parser.c @@ -49,6 +49,7 @@ static int hevc_parse_slice_header(AVCodecParserContext *s, H2645NAL *nal, HEVCPPS *pps; HEVCSPS *sps; + HEVCWindow *ow; unsigned int pps_id; get_bits1(gb); // first slice in pic @@ -62,12 +63,13 @@ static int hevc_parse_slice_header(AVCodecParserContext *s, H2645NAL *nal, } pps = (HEVCPPS*)ctx->ps.pps_list[pps_id]->data; sps = (HEVCSPS*)ctx->ps.sps_list[pps->sps_id]->data; + ow = &sps->output_window; /* export the stream parameters */ s->coded_width = sps->width; s->coded_height = sps->height; - s->width = sps->output_width; - s->height = sps->output_height; + s->width = sps->width - ow->left_offset - ow->right_offset; + s->height = sps->height - ow->top_offset - ow->bottom_offset; s->format = sps->pix_fmt; avctx->profile = sps->ptl.general_ptl.profile_idc; avctx->level = sps->ptl.general_ptl.level_idc; diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index 2471907077d63..4a5a47e20e50e 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -682,6 +682,7 @@ static int map_pixel_format(AVCodecContext *avctx, HEVCSPS *sps) int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, int apply_defdispwin, AVBufferRef **vps_list, AVCodecContext *avctx) { + HEVCWindow *ow; int ret = 0; int log2_diff_max_min_transform_block_size; int bit_depth_chroma, start, vui_present, sublayer_ordering_info; @@ -902,32 +903,21 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, sps->output_window.top_offset += sps->vui.def_disp_win.top_offset; sps->output_window.bottom_offset += sps->vui.def_disp_win.bottom_offset; } - if (sps->output_window.left_offset & (0x1F >> (sps->pixel_shift)) && - !(avctx->flags & AV_CODEC_FLAG_UNALIGNED)) { - sps->output_window.left_offset &= ~(0x1F >> (sps->pixel_shift)); - av_log(avctx, AV_LOG_WARNING, "Reducing left output window to %d " - "chroma samples to preserve alignment.\n", - sps->output_window.left_offset); - } - sps->output_width = sps->width - - (sps->output_window.left_offset + sps->output_window.right_offset); - sps->output_height = sps->height - - (sps->output_window.top_offset + sps->output_window.bottom_offset); - if (sps->output_width <= 0 || sps->output_height <= 0) { - av_log(avctx, AV_LOG_WARNING, "Invalid visible frame dimensions: %dx%d.\n", - sps->output_width, sps->output_height); + + ow = &sps->output_window; + if (ow->left_offset >= INT_MAX - ow->right_offset || + ow->top_offset >= INT_MAX - ow->bottom_offset || + ow->left_offset + ow->right_offset >= sps->width || + ow->top_offset + ow->bottom_offset >= sps->height) { + av_log(avctx, AV_LOG_WARNING, "Invalid cropping offsets: %u/%u/%u/%u\n", + ow->left_offset, ow->right_offset, ow->top_offset, ow->bottom_offset); if (avctx->err_recognition & AV_EF_EXPLODE) { ret = AVERROR_INVALIDDATA; goto err; } av_log(avctx, AV_LOG_WARNING, "Displaying the whole video surface.\n"); - sps->output_window.left_offset = - sps->output_window.right_offset = - sps->output_window.top_offset = - sps->output_window.bottom_offset = 0; - sps->output_width = sps->width; - sps->output_height = sps->height; + memset(ow, 0, sizeof(*ow)); } // Inferred parameters @@ -1008,7 +998,8 @@ int ff_hevc_decode_nal_sps(GetBitContext *gb, AVCodecContext *avctx, "Parsed SPS: id %d; coded wxh: %dx%d; " "cropped wxh: %dx%d; pix_fmt: %s.\n", sps_id, sps->width, sps->height, - sps->output_width, sps->output_height, + sps->width - (sps->output_window.left_offset + sps->output_window.right_offset), + sps->height - (sps->output_window.top_offset + sps->output_window.bottom_offset), av_get_pix_fmt_name(sps->pix_fmt)); } diff --git a/libavcodec/hevc_ps.h b/libavcodec/hevc_ps.h index d95aa519e6fe6..89a481ba8e756 100644 --- a/libavcodec/hevc_ps.h +++ b/libavcodec/hevc_ps.h @@ -141,8 +141,6 @@ typedef struct HEVCSPS { int chroma_format_idc; uint8_t separate_colour_plane_flag; - ///< output (i.e. cropped) values - int output_width, output_height; HEVCWindow output_window; HEVCWindow pic_conf_win; diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c index 30409bae5f445..0c1918793ed58 100644 --- a/libavcodec/hevc_refs.c +++ b/libavcodec/hevc_refs.c @@ -162,7 +162,10 @@ int ff_hevc_set_new_ref(HEVCContext *s, AVFrame **frame, int poc) ref->poc = poc; ref->sequence = s->seq_decode; - ref->window = s->ps.sps->output_window; + ref->frame->crop_left = s->ps.sps->output_window.left_offset; + ref->frame->crop_right = s->ps.sps->output_window.right_offset; + ref->frame->crop_top = s->ps.sps->output_window.top_offset; + ref->frame->crop_bottom = s->ps.sps->output_window.bottom_offset; return 0; } @@ -193,26 +196,12 @@ int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush) if (nb_output) { HEVCFrame *frame = &s->DPB[min_idx]; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->frame->format); - int pixel_shift; - - if (!desc) - return AVERROR_BUG; - - pixel_shift = desc->comp[0].depth > 8; ret = av_frame_ref(out, frame->frame); ff_hevc_unref_frame(s, frame, HEVC_FRAME_FLAG_OUTPUT); if (ret < 0) return ret; - for (i = 0; i < 3; i++) { - int hshift = (i > 0) ? desc->log2_chroma_w : 0; - int vshift = (i > 0) ? desc->log2_chroma_h : 0; - int off = ((frame->window.left_offset >> hshift) << pixel_shift) + - (frame->window.top_offset >> vshift) * out->linesize[i]; - out->data[i] += off; - } av_log(s->avctx, AV_LOG_DEBUG, "Output frame with POC %d.\n", frame->poc); return 1; diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 700b5f09a0b61..a4c936ee05381 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -338,13 +338,14 @@ static void export_stream_params(AVCodecContext *avctx, const HEVCParamSets *ps, const HEVCSPS *sps) { const HEVCVPS *vps = (const HEVCVPS*)ps->vps_list[sps->vps_id]->data; + const HEVCWindow *ow = &sps->output_window; unsigned int num = 0, den = 0; avctx->pix_fmt = sps->pix_fmt; avctx->coded_width = sps->width; avctx->coded_height = sps->height; - avctx->width = sps->output_width; - avctx->height = sps->output_height; + avctx->width = sps->width - ow->left_offset - ow->right_offset; + avctx->height = sps->height - ow->top_offset - ow->bottom_offset; avctx->has_b_frames = sps->temporal_layer[sps->max_sub_layers - 1].num_reorder_pics; avctx->profile = sps->ptl.general_ptl.profile_idc; avctx->level = sps->ptl.general_ptl.level_idc; @@ -2864,7 +2865,6 @@ static int hevc_ref_frame(HEVCContext *s, HEVCFrame *dst, HEVCFrame *src) dst->poc = src->poc; dst->ctb_count = src->ctb_count; - dst->window = src->window; dst->flags = src->flags; dst->sequence = src->sequence; @@ -3092,4 +3092,5 @@ AVCodec ff_hevc_decoder = { .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_FRAME_THREADS, .profiles = NULL_IF_CONFIG_SMALL(ff_hevc_profiles), + .caps_internal = FF_CODEC_CAP_EXPORTS_CROPPING, }; diff --git a/libavcodec/hevcdec.h b/libavcodec/hevcdec.h index 82adad20c6210..ff192f67aeb90 100644 --- a/libavcodec/hevcdec.h +++ b/libavcodec/hevcdec.h @@ -374,8 +374,6 @@ typedef struct HEVCFrame { int poc; struct HEVCFrame *collocated_ref; - HEVCWindow window; - AVBufferRef *tab_mvf_buf; AVBufferRef *rpl_tab_buf; AVBufferRef *rpl_buf; From 4fded0480f20f4d7ca5e776a85574de34dfead14 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 27 Dec 2016 19:07:18 +0100 Subject: [PATCH 0785/3374] h264dec: be more explicit in handling container cropping The current condition can trigger in cases where it shouldn't, with unexpected results. Make sure that: - container cropping is really based on the original dimensions from the caller - those dimenions are discarded on size change The code is still quite hacky and eventually should be deprecated and removed, with the decision about which cropping is used delegated to the caller. --- libavcodec/h264_slice.c | 15 +++++++++++---- libavcodec/h264dec.c | 3 +++ libavcodec/h264dec.h | 5 +++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 1b35c2baaf6d3..a54d3816e43d9 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -378,6 +378,8 @@ int ff_h264_update_thread_context(AVCodecContext *dst, h->avctx->coded_width = h1->avctx->coded_width; h->avctx->width = h1->avctx->width; h->avctx->height = h1->avctx->height; + h->width_from_caller = h1->width_from_caller; + h->height_from_caller = h1->height_from_caller; h->coded_picture_number = h1->coded_picture_number; h->first_field = h1->first_field; h->picture_structure = h1->picture_structure; @@ -797,10 +799,15 @@ static int init_dimensions(H264Context *h) int height = h->height - (sps->crop_top + sps->crop_bottom); /* handle container cropping */ - if (FFALIGN(h->avctx->width, 16) == FFALIGN(width, 16) && - FFALIGN(h->avctx->height, 16) == FFALIGN(height, 16)) { - width = h->avctx->width; - height = h->avctx->height; + if (h->width_from_caller > 0 && h->height_from_caller > 0 && + !sps->crop_top && !sps->crop_left && + FFALIGN(h->width_from_caller, 16) == FFALIGN(width, 16) && + FFALIGN(h->height_from_caller, 16) == FFALIGN(height, 16)) { + width = h->width_from_caller; + height = h->height_from_caller; + } else { + h->width_from_caller = 0; + h->height_from_caller = 0; } h->avctx->coded_width = h->width; diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index e111d40c35787..3209c1d4dff0a 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -285,6 +285,9 @@ static int h264_init_context(AVCodecContext *avctx, H264Context *h) h->avctx = avctx; + h->width_from_caller = avctx->width; + h->height_from_caller = avctx->height; + h->picture_structure = PICT_FRAME; h->workaround_bugs = avctx->workaround_bugs; h->flags = avctx->flags; diff --git a/libavcodec/h264dec.h b/libavcodec/h264dec.h index 5957e795e6bd0..0a9896ac8ab78 100644 --- a/libavcodec/h264dec.h +++ b/libavcodec/h264dec.h @@ -514,6 +514,11 @@ typedef struct H264Context { * the slice data */ int field_started; + /* original AVCodecContext dimensions, used to handle container + * cropping */ + int width_from_caller; + int height_from_caller; + AVFrame *output_frame; int enable_er; From c3e84820d67cb1d8cfb4196f9b43971308a81571 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 18 Dec 2016 21:11:47 +0100 Subject: [PATCH 0786/3374] h264dec: export cropping information instead of handling it internally --- libavcodec/h264_ps.c | 9 --------- libavcodec/h264_slice.c | 21 +++++++++++++++++++-- libavcodec/h264dec.c | 26 +++----------------------- libavcodec/h264dec.h | 5 +++++ 4 files changed, 27 insertions(+), 34 deletions(-) diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c index 8a64a33780011..7ee3876c8bdad 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -498,15 +498,6 @@ int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx, int step_x = 1 << hsub; int step_y = (2 - sps->frame_mbs_only_flag) << vsub; - if (crop_left & (0x1F >> (sps->bit_depth_luma > 8)) && - !(avctx->flags & AV_CODEC_FLAG_UNALIGNED)) { - crop_left &= ~(0x1F >> (sps->bit_depth_luma > 8)); - av_log(avctx, AV_LOG_WARNING, - "Reducing left cropping to %d " - "chroma samples to preserve alignment.\n", - crop_left); - } - if (INT_MAX / step_x <= crop_left || INT_MAX / step_x - crop_left <= crop_right || 16 * sps->mb_width <= step_x * (crop_left + crop_right) || diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index a54d3816e43d9..3749d1f2caceb 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -473,6 +473,11 @@ static int h264_frame_start(H264Context *h) pic->f->pict_type = h->slice_ctx[0].slice_type; + pic->f->crop_left = h->crop_left; + pic->f->crop_right = h->crop_right; + pic->f->crop_top = h->crop_top; + pic->f->crop_bottom = h->crop_bottom; + if (CONFIG_ERROR_RESILIENCE && h->enable_er) ff_er_frame_start(&h->slice_ctx[0].er); @@ -795,8 +800,12 @@ static enum AVPixelFormat get_pixel_format(H264Context *h) static int init_dimensions(H264Context *h) { SPS *sps = h->ps.sps; - int width = h->width - (sps->crop_right + sps->crop_left); - int height = h->height - (sps->crop_top + sps->crop_bottom); + int cr = sps->crop_right; + int cl = sps->crop_left; + int ct = sps->crop_top; + int cb = sps->crop_bottom; + int width = h->width - (cr + cl); + int height = h->height - (ct + cb); /* handle container cropping */ if (h->width_from_caller > 0 && h->height_from_caller > 0 && @@ -805,6 +814,10 @@ static int init_dimensions(H264Context *h) FFALIGN(h->height_from_caller, 16) == FFALIGN(height, 16)) { width = h->width_from_caller; height = h->height_from_caller; + cl = 0; + ct = 0; + cr = h->width - width; + cb = h->height - height; } else { h->width_from_caller = 0; h->height_from_caller = 0; @@ -814,6 +827,10 @@ static int init_dimensions(H264Context *h) h->avctx->coded_height = h->height; h->avctx->width = width; h->avctx->height = height; + h->crop_right = cr; + h->crop_left = cl; + h->crop_top = ct; + h->crop_bottom = cb; return 0; } diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 3209c1d4dff0a..834c60c38c7e3 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -661,26 +661,6 @@ static int get_consumed_bytes(int pos, int buf_size) return pos; } -static int output_frame(H264Context *h, AVFrame *dst, AVFrame *src) -{ - int i; - int ret = av_frame_ref(dst, src); - if (ret < 0) - return ret; - - if (!h->ps.sps || !h->ps.sps->crop) - return 0; - - for (i = 0; i < 3; i++) { - int hshift = (i > 0) ? h->chroma_x_shift : 0; - int vshift = (i > 0) ? h->chroma_y_shift : 0; - int off = ((h->ps.sps->crop_left >> hshift) << h->pixel_shift) + - (h->ps.sps->crop_top >> vshift) * dst->linesize[i]; - dst->data[i] += off; - } - return 0; -} - static int h264_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { @@ -722,7 +702,7 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data, h->delayed_pic[i] = h->delayed_pic[i + 1]; if (out) { - ret = output_frame(h, pict, out->f); + ret = av_frame_ref(pict, out->f); if (ret < 0) return ret; *got_frame = 1; @@ -765,7 +745,7 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data, *got_frame = 0; if (h->output_frame->buf[0]) { - ret = output_frame(h, pict, h->output_frame) ; + ret = av_frame_ref(pict, h->output_frame); av_frame_unref(h->output_frame); if (ret < 0) return ret; @@ -804,7 +784,7 @@ AVCodec ff_h264_decoder = { .capabilities = /*AV_CODEC_CAP_DRAW_HORIZ_BAND |*/ AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS, - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING, .flush = flush_dpb, .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_h264_update_thread_context), diff --git a/libavcodec/h264dec.h b/libavcodec/h264dec.h index 0a9896ac8ab78..fc7beeb9944e8 100644 --- a/libavcodec/h264dec.h +++ b/libavcodec/h264dec.h @@ -372,6 +372,11 @@ typedef struct H264Context { */ int picture_idr; + int crop_left; + int crop_right; + int crop_top; + int crop_bottom; + int8_t(*intra4x4_pred_mode); H264PredContext hpc; From 1202b712690c14f0efb06e4ad8b06c5b3df6822a Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 18 Dec 2016 21:11:47 +0100 Subject: [PATCH 0787/3374] theora: export cropping information instead of handling it internally --- libavcodec/vp3.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index 26374cc5d3bc8..cb8925ba4c5a7 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -1983,6 +1983,7 @@ static int vp3_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { + AVFrame *frame = data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; Vp3DecodeContext *s = avctx->priv_data; @@ -2122,12 +2123,12 @@ static int vp3_decode_frame(AVCodecContext *avctx, /* output frame, offset as needed */ if ((ret = av_frame_ref(data, s->current_frame.f)) < 0) return ret; - for (i = 0; i < 3; i++) { - AVFrame *dst = data; - int off = (s->offset_x >> (i && s->chroma_y_shift)) + - (s->offset_y >> (i && s->chroma_y_shift)) * dst->linesize[i]; - dst->data[i] += off; - } + + frame->crop_left = s->offset_x; + frame->crop_right = avctx->coded_width - avctx->width - s->offset_x; + frame->crop_top = s->offset_y; + frame->crop_bottom = avctx->coded_height - avctx->height - s->offset_y; + *got_frame = 1; if (!HAVE_THREADS || !(s->avctx->active_thread_type & FF_THREAD_FRAME)) { @@ -2290,13 +2291,6 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) // to normal axis ([0,0] upper left) s->offset_x = offset_x; s->offset_y = s->height - visible_height - offset_y; - - if ((s->offset_x & 0x1F) && !(avctx->flags & AV_CODEC_FLAG_UNALIGNED)) { - s->offset_x &= ~0x1F; - av_log(avctx, AV_LOG_WARNING, "Reducing offset_x from %d to %d" - "chroma samples to preserve alignment.\n", - offset_x, s->offset_x); - } } if (colorspace == 1) @@ -2499,7 +2493,8 @@ AVCodec ff_theora_decoder = { AV_CODEC_CAP_FRAME_THREADS, .flush = vp3_decode_flush, .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy), - .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context) + .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context), + .caps_internal = FF_CODEC_CAP_EXPORTS_CROPPING, }; #endif From f8f7ad758d0e1f36915467567f4d75541d98c12f Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Wed, 14 Dec 2016 11:58:18 +0100 Subject: [PATCH 0788/3374] qsv: Set the correct range for la_depth Setting an invalid range for it makes the encoder behave inconsistently. --- libavcodec/qsvenc.c | 2 +- libavcodec/qsvenc.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index d680fc8cbc8d3..85af146ad8169 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -273,7 +273,7 @@ static int select_rc_mode(AVCodecContext *avctx, QSVEncContext *q) const char *rc_desc; mfxU16 rc_mode; - int want_la = q->la_depth >= 0; + int want_la = q->la_depth >= 10; int want_qscale = !!(avctx->flags & AV_CODEC_FLAG_QSCALE); int want_vcm = q->vcm; diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h index 7ac5dc700b4ff..13e4c47481b86 100644 --- a/libavcodec/qsvenc.h +++ b/libavcodec/qsvenc.h @@ -55,7 +55,8 @@ { "fast", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_BEST_SPEED }, INT_MIN, INT_MAX, VE, "preset" }, \ { "medium", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_BALANCED }, INT_MIN, INT_MAX, VE, "preset" }, \ { "slow", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_BEST_QUALITY }, INT_MIN, INT_MAX, VE, "preset" }, \ -{ "la_depth", "Number of frames to analyze before encoding.", OFFSET(qsv.la_depth), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT16_MAX, VE }, \ +{ "la_depth", "Number of frames to analyze before encoding.", OFFSET(qsv.la_depth), AV_OPT_TYPE_INT, { .i64 = 9 }, 9, 100, VE, "la_depth" }, \ +{ "unset", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 9 }, INT_MIN, INT_MAX, VE, "la_depth" }, \ { "vcm", "Use the video conferencing mode ratecontrol", OFFSET(qsv.vcm), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, \ { "rdo", "Enable rate distortion optimization", OFFSET(qsv.rdo), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, \ { "max_frame_size", "Maximum encoded frame size in bytes", OFFSET(qsv.max_frame_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, UINT16_MAX, VE }, \ From 44129e38047b6a27291e487c2084894958c6f399 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Thu, 15 Dec 2016 18:59:41 +0100 Subject: [PATCH 0789/3374] avconv: Do not pass NULL to avio_tell The null demuxer does not have a backing AVIOContext. --- avconv.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/avconv.c b/avconv.c index 5c31332812b74..fe606250feb8a 100644 --- a/avconv.c +++ b/avconv.c @@ -909,7 +909,7 @@ static void print_report(int is_last_report, int64_t timer_start) char buf[1024]; OutputStream *ost; AVFormatContext *oc; - int64_t total_size; + int64_t total_size = 0; AVCodecContext *enc; int frame_number, vid, i; double bitrate, ti1, pts; @@ -934,16 +934,17 @@ static void print_report(int is_last_report, int64_t timer_start) oc = output_files[0]->ctx; - - total_size = avio_size(oc->pb); - if (total_size <= 0) // FIXME improve avio_size() so it works with non seekable output too - total_size = avio_tell(oc->pb); - if (total_size < 0) { - char errbuf[128]; - av_strerror(total_size, errbuf, sizeof(errbuf)); - av_log(NULL, AV_LOG_VERBOSE, "Bitrate not available, " - "avio_tell() failed: %s\n", errbuf); - total_size = 0; + if (oc->pb) { + total_size = avio_size(oc->pb); + if (total_size <= 0) // FIXME improve avio_size() so it works with non seekable output too + total_size = avio_tell(oc->pb); + if (total_size < 0) { + char errbuf[128]; + av_strerror(total_size, errbuf, sizeof(errbuf)); + av_log(NULL, AV_LOG_VERBOSE, "Bitrate not available, " + "avio_tell() failed: %s\n", errbuf); + total_size = 0; + } } buf[0] = '\0'; From a895292f2734b4aacd2f2c2db6c07ff5a6d535c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 16 Apr 2016 12:17:24 +0200 Subject: [PATCH 0790/3374] mov: Convert to the new bitstream reader --- libavformat/mov.c | 10 ++++++---- libavformat/movenc.c | 41 +++++++++++++++++++++-------------------- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 8b38fa43b8bf1..37afe79df029a 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -39,13 +39,15 @@ #include "libavutil/pixdesc.h" #include "libavutil/spherical.h" #include "libavutil/stereo3d.h" + #include "libavcodec/ac3tab.h" +#include "libavcodec/bitstream.h" + #include "avformat.h" #include "internal.h" #include "avio_internal.h" #include "riff.h" #include "isom.h" -#include "libavcodec/get_bits.h" #include "id3v1.h" #include "mov_chan.h" #include "replaygain.h" @@ -2078,7 +2080,7 @@ static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom) AVStream *st; MOVStreamContext *sc; unsigned int i, entries, sample_size, field_size, num_bytes; - GetBitContext gb; + BitstreamContext bc; unsigned char* buf; int ret; @@ -2136,10 +2138,10 @@ static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom) return ret; } - init_get_bits(&gb, buf, 8*num_bytes); + bitstream_init(&bc, buf, 8 * num_bytes); for (i = 0; i < entries && !pb->eof_reached; i++) { - sc->sample_sizes[i] = get_bits_long(&gb, field_size); + sc->sample_sizes[i] = bitstream_read(&bc, field_size); sc->data_size += sc->sample_sizes[i]; } diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 3dd882c2639c8..ac76dedca40fc 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -31,7 +31,8 @@ #include "avio.h" #include "isom.h" #include "avc.h" -#include "libavcodec/get_bits.h" + +#include "libavcodec/bitstream.h" #include "libavcodec/put_bits.h" #include "libavcodec/vc1_common.h" #include "internal.h" @@ -240,7 +241,7 @@ static int mov_write_amr_tag(AVIOContext *pb, MOVTrack *track) static int mov_write_ac3_tag(AVIOContext *pb, MOVTrack *track) { - GetBitContext gbc; + BitstreamContext bc; PutBitContext pbc; uint8_t buf[3]; int fscod, bsid, bsmod, acmod, lfeon, frmsizecod; @@ -251,21 +252,21 @@ static int mov_write_ac3_tag(AVIOContext *pb, MOVTrack *track) avio_wb32(pb, 11); ffio_wfourcc(pb, "dac3"); - init_get_bits(&gbc, track->vos_data + 4, (track->vos_len - 4) * 8); - fscod = get_bits(&gbc, 2); - frmsizecod = get_bits(&gbc, 6); - bsid = get_bits(&gbc, 5); - bsmod = get_bits(&gbc, 3); - acmod = get_bits(&gbc, 3); + bitstream_init(&bc, track->vos_data + 4, (track->vos_len - 4) * 8); + fscod = bitstream_read(&bc, 2); + frmsizecod = bitstream_read(&bc, 6); + bsid = bitstream_read(&bc, 5); + bsmod = bitstream_read(&bc, 3); + acmod = bitstream_read(&bc, 3); if (acmod == 2) { - skip_bits(&gbc, 2); // dsurmod + bitstream_skip(&bc, 2); // dsurmod } else { if ((acmod & 1) && acmod != 1) - skip_bits(&gbc, 2); // cmixlev + bitstream_skip(&bc, 2); // cmixlev if (acmod & 4) - skip_bits(&gbc, 2); // surmixlev + bitstream_skip(&bc, 2); // surmixlev } - lfeon = get_bits1(&gbc); + lfeon = bitstream_read_bit(&bc); init_put_bits(&pbc, buf, sizeof(buf)); put_bits(&pbc, 2, fscod); @@ -462,28 +463,28 @@ static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf) return AVERROR(ENOMEM); start = find_next_marker(track->vos_data, end); for (next = start; next < end; start = next) { - GetBitContext gb; + BitstreamContext bc; int size; next = find_next_marker(start + 4, end); size = next - start - 4; if (size <= 0) continue; unescaped_size = vc1_unescape_buffer(start + 4, size, unescaped); - init_get_bits(&gb, unescaped, 8 * unescaped_size); + bitstream_init(&bc, unescaped, 8 * unescaped_size); if (AV_RB32(start) == VC1_CODE_SEQHDR) { - int profile = get_bits(&gb, 2); + int profile = bitstream_read(&bc, 2); if (profile != PROFILE_ADVANCED) { av_free(unescaped); return AVERROR(ENOSYS); } seq_found = 1; - level = get_bits(&gb, 3); + level = bitstream_read(&bc, 3); /* chromaformat, frmrtq_postproc, bitrtq_postproc, postprocflag, * width, height */ - skip_bits_long(&gb, 2 + 3 + 5 + 1 + 2*12); - skip_bits(&gb, 1); /* broadcast */ - interlace = get_bits1(&gb); - skip_bits(&gb, 4); /* tfcntrflag, finterpflag, reserved, psf */ + bitstream_skip(&bc, 2 + 3 + 5 + 1 + 2 * 12); + bitstream_skip(&bc, 1); /* broadcast */ + interlace = bitstream_read_bit(&bc); + bitstream_skip(&bc, 4); /* tfcntrflag, finterpflag, reserved, psf */ } } if (!seq_found) { From b1e7394ea0428318c0407a6c030577196fe834a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sun, 17 Apr 2016 16:59:24 +0200 Subject: [PATCH 0791/3374] rtp: Convert to the new bitstream reader --- libavformat/rtpdec_h261.c | 19 ++++++++++--------- libavformat/rtpdec_h263_rfc2190.c | 19 ++++++++++--------- libavformat/rtpdec_latm.c | 24 +++++++++++++----------- libavformat/rtpdec_mpeg4.c | 16 +++++++++------- libavformat/rtpdec_qt.c | 31 ++++++++++++++++--------------- libavformat/rtpenc_h263_rfc2190.c | 29 +++++++++++++++-------------- 6 files changed, 73 insertions(+), 65 deletions(-) diff --git a/libavformat/rtpdec_h261.c b/libavformat/rtpdec_h261.c index 00086c21c54dd..b1bd1e04756bf 100644 --- a/libavformat/rtpdec_h261.c +++ b/libavformat/rtpdec_h261.c @@ -19,7 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "libavcodec/get_bits.h" +#include "libavcodec/bitstream.h" + #include "avformat.h" #include "avio_internal.h" #include "rtpdec_formats.h" @@ -118,18 +119,18 @@ static int h261_handle_packet(AVFormatContext *ctx, PayloadContext *rtp_h261_ctx avio_w8(rtp_h261_ctx->buf, rtp_h261_ctx->endbyte); } else { /* ebit/sbit values inconsistent, assuming packet loss */ - GetBitContext gb; - init_get_bits(&gb, buf, len*8 - ebit); - skip_bits(&gb, sbit); + BitstreamContext bc; + bitstream_init(&bc, buf, len * 8 - ebit); + bitstream_skip(&bc, sbit); if (rtp_h261_ctx->endbyte_bits) { - rtp_h261_ctx->endbyte |= get_bits(&gb, 8 - rtp_h261_ctx->endbyte_bits); + rtp_h261_ctx->endbyte |= bitstream_read(&bc, 8 - rtp_h261_ctx->endbyte_bits); avio_w8(rtp_h261_ctx->buf, rtp_h261_ctx->endbyte); } - while (get_bits_left(&gb) >= 8) - avio_w8(rtp_h261_ctx->buf, get_bits(&gb, 8)); - rtp_h261_ctx->endbyte_bits = get_bits_left(&gb); + while (bitstream_bits_left(&bc) >= 8) + avio_w8(rtp_h261_ctx->buf, bitstream_read(&bc, 8)); + rtp_h261_ctx->endbyte_bits = bitstream_bits_left(&bc); if (rtp_h261_ctx->endbyte_bits) - rtp_h261_ctx->endbyte = get_bits(&gb, rtp_h261_ctx->endbyte_bits) << + rtp_h261_ctx->endbyte = bitstream_read(&bc, rtp_h261_ctx->endbyte_bits) << (8 - rtp_h261_ctx->endbyte_bits); ebit = 0; len = 0; diff --git a/libavformat/rtpdec_h263_rfc2190.c b/libavformat/rtpdec_h263_rfc2190.c index 019eea779b162..5744d71da0fe6 100644 --- a/libavformat/rtpdec_h263_rfc2190.c +++ b/libavformat/rtpdec_h263_rfc2190.c @@ -30,7 +30,8 @@ #include "rtpdec_formats.h" #include "libavutil/attributes.h" #include "libavutil/intreadwrite.h" -#include "libavcodec/get_bits.h" + +#include "libavcodec/bitstream.h" struct PayloadContext { AVIOContext *buf; @@ -141,18 +142,18 @@ static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data, avio_w8(data->buf, data->endbyte); } else { /* Start/end skip bits not matching - missed packets? */ - GetBitContext gb; - init_get_bits(&gb, buf, len*8 - ebit); - skip_bits(&gb, sbit); + BitstreamContext bc; + bitstream_init(&bc, buf, len * 8 - ebit); + bitstream_skip(&bc, sbit); if (data->endbyte_bits) { - data->endbyte |= get_bits(&gb, 8 - data->endbyte_bits); + data->endbyte |= bitstream_read(&bc, 8 - data->endbyte_bits); avio_w8(data->buf, data->endbyte); } - while (get_bits_left(&gb) >= 8) - avio_w8(data->buf, get_bits(&gb, 8)); - data->endbyte_bits = get_bits_left(&gb); + while (bitstream_bits_left(&bc) >= 8) + avio_w8(data->buf, bitstream_read(&bc, 8)); + data->endbyte_bits = bitstream_bits_left(&bc); if (data->endbyte_bits) - data->endbyte = get_bits(&gb, data->endbyte_bits) << + data->endbyte = bitstream_read(&bc, data->endbyte_bits) << (8 - data->endbyte_bits); ebit = 0; len = 0; diff --git a/libavformat/rtpdec_latm.c b/libavformat/rtpdec_latm.c index df85ed3615a89..bb826269b0b2a 100644 --- a/libavformat/rtpdec_latm.c +++ b/libavformat/rtpdec_latm.c @@ -19,11 +19,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/avstring.h" + +#include "libavcodec/bitstream.h" + #include "avio_internal.h" #include "rtpdec_formats.h" #include "internal.h" -#include "libavutil/avstring.h" -#include "libavcodec/get_bits.h" struct PayloadContext { AVIOContext *dyn_buf; @@ -92,7 +94,7 @@ static int latm_parse_packet(AVFormatContext *ctx, PayloadContext *data, static int parse_fmtp_config(AVStream *st, const char *value) { int len = ff_hex_to_data(NULL, value), i, ret = 0; - GetBitContext gb; + BitstreamContext bc; uint8_t *config; int audio_mux_version, same_time_framing, num_programs, num_layers; @@ -101,12 +103,12 @@ static int parse_fmtp_config(AVStream *st, const char *value) if (!config) return AVERROR(ENOMEM); ff_hex_to_data(config, value); - init_get_bits(&gb, config, len*8); - audio_mux_version = get_bits(&gb, 1); - same_time_framing = get_bits(&gb, 1); - skip_bits(&gb, 6); /* num_sub_frames */ - num_programs = get_bits(&gb, 4); - num_layers = get_bits(&gb, 3); + bitstream_init(&bc, config, len * 8); + audio_mux_version = bitstream_read(&bc, 1); + same_time_framing = bitstream_read(&bc, 1); + bitstream_skip(&bc, 6); /* num_sub_frames */ + num_programs = bitstream_read(&bc, 4); + num_layers = bitstream_read(&bc, 3); if (audio_mux_version != 0 || same_time_framing != 1 || num_programs != 0 || num_layers != 0) { avpriv_report_missing_feature(NULL, "LATM config (%d,%d,%d,%d)", @@ -116,7 +118,7 @@ static int parse_fmtp_config(AVStream *st, const char *value) goto end; } av_freep(&st->codecpar->extradata); - st->codecpar->extradata_size = (get_bits_left(&gb) + 7)/8; + st->codecpar->extradata_size = (bitstream_bits_left(&bc) + 7) / 8; st->codecpar->extradata = av_mallocz(st->codecpar->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); if (!st->codecpar->extradata) { @@ -124,7 +126,7 @@ static int parse_fmtp_config(AVStream *st, const char *value) goto end; } for (i = 0; i < st->codecpar->extradata_size; i++) - st->codecpar->extradata[i] = get_bits(&gb, 8); + st->codecpar->extradata[i] = bitstream_read(&bc, 8); end: av_free(config); diff --git a/libavformat/rtpdec_mpeg4.c b/libavformat/rtpdec_mpeg4.c index 00a732b1cc536..b3cd6c94041d3 100644 --- a/libavformat/rtpdec_mpeg4.c +++ b/libavformat/rtpdec_mpeg4.c @@ -27,11 +27,13 @@ * @author Romain Degez */ -#include "rtpdec_formats.h" -#include "internal.h" #include "libavutil/attributes.h" #include "libavutil/avstring.h" -#include "libavcodec/get_bits.h" + +#include "libavcodec/bitstream.h" + +#include "rtpdec_formats.h" +#include "internal.h" #define MAX_AAC_HBR_FRAME_SIZE 8191 @@ -113,7 +115,7 @@ static int parse_fmtp_config(AVCodecParameters *par, const char *value) static int rtp_parse_mp4_au(PayloadContext *data, const uint8_t *buf, int len) { int au_headers_length, au_header_size, i; - GetBitContext getbitcontext; + BitstreamContext bctx; if (len < 2) return AVERROR_INVALIDDATA; @@ -134,7 +136,7 @@ static int rtp_parse_mp4_au(PayloadContext *data, const uint8_t *buf, int len) if (len < data->au_headers_length_bytes) return AVERROR_INVALIDDATA; - init_get_bits(&getbitcontext, buf, data->au_headers_length_bytes * 8); + bitstream_init(&bctx, buf, data->au_headers_length_bytes * 8); /* XXX: Wrong if optional additional sections are present (cts, dts etc...) */ au_header_size = data->sizelength + data->indexlength; @@ -151,8 +153,8 @@ static int rtp_parse_mp4_au(PayloadContext *data, const uint8_t *buf, int len) } for (i = 0; i < data->nb_au_headers; ++i) { - data->au_headers[i].size = get_bits_long(&getbitcontext, data->sizelength); - data->au_headers[i].index = get_bits_long(&getbitcontext, data->indexlength); + data->au_headers[i].size = bitstream_read(&bctx, data->sizelength); + data->au_headers[i].index = bitstream_read(&bctx, data->indexlength); } return 0; diff --git a/libavformat/rtpdec_qt.c b/libavformat/rtpdec_qt.c index 97df21091698a..2c0f8188b6551 100644 --- a/libavformat/rtpdec_qt.c +++ b/libavformat/rtpdec_qt.c @@ -25,13 +25,14 @@ * @author Ronald S. Bultje */ +#include "libavcodec/bitstream.h" + #include "avformat.h" #include "internal.h" #include "avio_internal.h" #include "rtp.h" #include "rtpdec.h" #include "isom.h" -#include "libavcodec/get_bits.h" struct PayloadContext { AVPacket pkt; @@ -45,7 +46,7 @@ static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt, int len, uint16_t seq, int flags) { AVIOContext pb; - GetBitContext gb; + BitstreamContext bc; int packing_scheme, has_payload_desc, has_packet_info, alen, has_marker_bit = flags & RTP_FLAG_MARKER, keyframe; @@ -71,38 +72,38 @@ static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt, * The RTP payload is described in: * http://developer.apple.com/quicktime/icefloe/dispatch026.html */ - init_get_bits(&gb, buf, len << 3); + bitstream_init(&bc, buf, len << 3); ffio_init_context(&pb, buf, len, 0, NULL, NULL, NULL, NULL); if (len < 4) return AVERROR_INVALIDDATA; - skip_bits(&gb, 4); // version - if ((packing_scheme = get_bits(&gb, 2)) == 0) + bitstream_skip(&bc, 4); // version + if ((packing_scheme = bitstream_read(&bc, 2)) == 0) return AVERROR_INVALIDDATA; - keyframe = get_bits1(&gb); - has_payload_desc = get_bits1(&gb); - has_packet_info = get_bits1(&gb); - skip_bits(&gb, 23); // reserved:7, cache payload info:1, payload ID:15 + keyframe = bitstream_read_bit(&bc); + has_payload_desc = bitstream_read_bit(&bc); + has_packet_info = bitstream_read_bit(&bc); + bitstream_skip(&bc, 23); // reserved:7, cache payload info:1, payload ID:15 if (has_payload_desc) { int data_len, pos, is_start, is_finish; uint32_t tag; - pos = get_bits_count(&gb) >> 3; + pos = bitstream_tell(&bc) >> 3; if (pos + 12 > len) return AVERROR_INVALIDDATA; - skip_bits(&gb, 2); // has non-I-frames:1, is sparse:1 - is_start = get_bits1(&gb); - is_finish = get_bits1(&gb); + bitstream_skip(&bc, 2); // has non-I-frames:1, is sparse:1 + is_start = bitstream_read_bit(&bc); + is_finish = bitstream_read_bit(&bc); if (!is_start || !is_finish) { avpriv_request_sample(s, "RTP-X-QT with payload description " "split over several packets"); return AVERROR_PATCHWELCOME; } - skip_bits(&gb, 12); // reserved - data_len = get_bits(&gb, 16); + bitstream_skip(&bc, 12); // reserved + data_len = bitstream_read(&bc, 16); avio_seek(&pb, pos + 4, SEEK_SET); tag = avio_rl32(&pb); diff --git a/libavformat/rtpenc_h263_rfc2190.c b/libavformat/rtpenc_h263_rfc2190.c index b8d7a0ab1c4c0..750a52bcd861f 100644 --- a/libavformat/rtpenc_h263_rfc2190.c +++ b/libavformat/rtpenc_h263_rfc2190.c @@ -19,10 +19,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavcodec/bitstream.h" +#include "libavcodec/put_bits.h" + #include "avformat.h" #include "rtpenc.h" -#include "libavcodec/put_bits.h" -#include "libavcodec/get_bits.h" struct H263Info { int src; @@ -103,7 +104,7 @@ void ff_rtp_send_h263_rfc2190(AVFormatContext *s1, const uint8_t *buf, int size, { RTPMuxContext *s = s1->priv_data; int len, sbits = 0, ebits = 0; - GetBitContext gb; + BitstreamContext bc; struct H263Info info = { 0 }; struct H263State state = { 0 }; int mb_info_pos = 0, mb_info_count = mb_info_size / 12; @@ -111,17 +112,17 @@ void ff_rtp_send_h263_rfc2190(AVFormatContext *s1, const uint8_t *buf, int size, s->timestamp = s->cur_timestamp; - init_get_bits(&gb, buf, size*8); - if (get_bits(&gb, 22) == 0x20) { /* Picture Start Code */ - info.tr = get_bits(&gb, 8); - skip_bits(&gb, 2); /* PTYPE start, H.261 disambiguation */ - skip_bits(&gb, 3); /* Split screen, document camera, freeze picture release */ - info.src = get_bits(&gb, 3); - info.i = get_bits(&gb, 1); - info.u = get_bits(&gb, 1); - info.s = get_bits(&gb, 1); - info.a = get_bits(&gb, 1); - info.pb = get_bits(&gb, 1); + bitstream_init(&bc, buf, size * 8); + if (bitstream_read(&bc, 22) == 0x20) { /* Picture Start Code */ + info.tr = bitstream_read(&bc, 8); + bitstream_skip(&bc, 2); /* PTYPE start, H.261 disambiguation */ + bitstream_skip(&bc, 3); /* Split screen, document camera, freeze picture release */ + info.src = bitstream_read(&bc, 3); + info.i = bitstream_read(&bc, 1); + info.u = bitstream_read(&bc, 1); + info.s = bitstream_read(&bc, 1); + info.a = bitstream_read(&bc, 1); + info.pb = bitstream_read(&bc, 1); } while (size > 0) { From 4795e4f61f993940c5384044caff56cc15078698 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Thu, 7 Apr 2016 22:04:58 +0200 Subject: [PATCH 0792/3374] alac: Convert to the new bitstream reader --- libavcodec/alac.c | 65 ++++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/libavcodec/alac.c b/libavcodec/alac.c index aef68e76a3bcc..0f1c59e48662e 100644 --- a/libavcodec/alac.c +++ b/libavcodec/alac.c @@ -48,19 +48,20 @@ #include #include "libavutil/channel_layout.h" + #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "bytestream.h" #include "internal.h" #include "mathops.h" -#include "unary_legacy.h" +#include "unary.h" #include "alac_data.h" #define ALAC_EXTRADATA_SIZE 36 typedef struct ALACContext { AVCodecContext *avctx; - GetBitContext gb; + BitstreamContext bc; int channels; int32_t *predict_error_buffer[2]; @@ -77,24 +78,24 @@ typedef struct ALACContext { int nb_samples; /**< number of samples in the current frame */ } ALACContext; -static inline unsigned int decode_scalar(GetBitContext *gb, int k, int bps) +static inline unsigned int decode_scalar(BitstreamContext *bc, int k, int bps) { - unsigned int x = get_unary_0_9(gb); + unsigned int x = get_unary_0_9(bc); if (x > 8) { /* RICE THRESHOLD */ /* use alternative encoding */ - x = get_bits_long(gb, bps); + x = bitstream_read(bc, bps); } else if (k != 1) { - int extrabits = show_bits(gb, k); + int extrabits = bitstream_peek(bc, k); /* multiply x by 2^k - 1, as part of their strange algorithm */ x = (x << k) - x; if (extrabits > 1) { x += extrabits - 1; - skip_bits(gb, k); + bitstream_skip(bc, k); } else - skip_bits(gb, k - 1); + bitstream_skip(bc, k - 1); } return x; } @@ -113,7 +114,7 @@ static void rice_decompress(ALACContext *alac, int32_t *output_buffer, /* calculate rice param and decode next value */ k = av_log2((history >> 9) + 3); k = FFMIN(k, alac->rice_limit); - x = decode_scalar(&alac->gb, k, bps); + x = decode_scalar(&alac->bc, k, bps); x += sign_modifier; sign_modifier = 0; output_buffer[i] = (x >> 1) ^ -(x & 1); @@ -132,7 +133,7 @@ static void rice_decompress(ALACContext *alac, int32_t *output_buffer, /* calculate rice param and decode block size */ k = 7 - av_log2(history) + ((history + 16) >> 6); k = FFMIN(k, alac->rice_limit); - block_size = decode_scalar(&alac->gb, k, 16); + block_size = decode_scalar(&alac->bc, k, 16); if (block_size > 0) { if (block_size >= nb_samples - i) { @@ -257,13 +258,13 @@ static int decode_element(AVCodecContext *avctx, AVFrame *frame, int ch_index, uint32_t output_samples; int i, ch; - skip_bits(&alac->gb, 4); /* element instance tag */ - skip_bits(&alac->gb, 12); /* unused header bits */ + bitstream_skip(&alac->bc, 4); /* element instance tag */ + bitstream_skip(&alac->bc, 12); /* unused header bits */ /* the number of output samples is stored in the frame */ - has_size = get_bits1(&alac->gb); + has_size = bitstream_read_bit(&alac->bc); - alac->extra_bits = get_bits(&alac->gb, 2) << 3; + alac->extra_bits = bitstream_read(&alac->bc, 2) << 3; bps = alac->sample_size - alac->extra_bits + channels - 1; if (bps > 32) { avpriv_report_missing_feature(avctx, "bps %d", bps); @@ -271,10 +272,10 @@ static int decode_element(AVCodecContext *avctx, AVFrame *frame, int ch_index, } /* whether the frame is compressed */ - is_compressed = !get_bits1(&alac->gb); + is_compressed = !bitstream_read_bit(&alac->bc); if (has_size) - output_samples = get_bits_long(&alac->gb, 32); + output_samples = bitstream_read(&alac->bc, 32); else output_samples = alac->max_samples_per_frame; if (!output_samples || output_samples > alac->max_samples_per_frame) { @@ -313,27 +314,27 @@ static int decode_element(AVCodecContext *avctx, AVFrame *frame, int ch_index, return AVERROR(ENOSYS); } - decorr_shift = get_bits(&alac->gb, 8); - decorr_left_weight = get_bits(&alac->gb, 8); + decorr_shift = bitstream_read(&alac->bc, 8); + decorr_left_weight = bitstream_read(&alac->bc, 8); for (ch = 0; ch < channels; ch++) { - prediction_type[ch] = get_bits(&alac->gb, 4); - lpc_quant[ch] = get_bits(&alac->gb, 4); - rice_history_mult[ch] = get_bits(&alac->gb, 3); - lpc_order[ch] = get_bits(&alac->gb, 5); + prediction_type[ch] = bitstream_read(&alac->bc, 4); + lpc_quant[ch] = bitstream_read(&alac->bc, 4); + rice_history_mult[ch] = bitstream_read(&alac->bc, 3); + lpc_order[ch] = bitstream_read(&alac->bc, 5); if (lpc_order[ch] >= alac->max_samples_per_frame) return AVERROR_INVALIDDATA; /* read the predictor table */ for (i = lpc_order[ch] - 1; i >= 0; i--) - lpc_coefs[ch][i] = get_sbits(&alac->gb, 16); + lpc_coefs[ch][i] = bitstream_read_signed(&alac->bc, 16); } if (alac->extra_bits) { for (i = 0; i < alac->nb_samples; i++) { for (ch = 0; ch < channels; ch++) - alac->extra_bits_buffer[ch][i] = get_bits(&alac->gb, alac->extra_bits); + alac->extra_bits_buffer[ch][i] = bitstream_read(&alac->bc, alac->extra_bits); } } for (ch = 0; ch < channels; ch++) { @@ -366,7 +367,7 @@ static int decode_element(AVCodecContext *avctx, AVFrame *frame, int ch_index, for (i = 0; i < alac->nb_samples; i++) { for (ch = 0; ch < channels; ch++) { alac->output_samples_buffer[ch][i] = - get_sbits_long(&alac->gb, alac->sample_size); + bitstream_read_signed(&alac->bc, alac->sample_size); } } alac->extra_bits = 0; @@ -412,13 +413,13 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data, int channels; int ch, ret, got_end; - init_get_bits(&alac->gb, avpkt->data, avpkt->size * 8); + bitstream_init8(&alac->bc, avpkt->data, avpkt->size); got_end = 0; alac->nb_samples = 0; ch = 0; - while (get_bits_left(&alac->gb) >= 3) { - element = get_bits(&alac->gb, 3); + while (bitstream_bits_left(&alac->bc) >= 3) { + element = bitstream_read(&alac->bc, 3); if (element == TYPE_END) { got_end = 1; break; @@ -438,7 +439,7 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data, ret = decode_element(avctx, frame, ff_alac_channel_layout_offsets[alac->channels - 1][ch], channels); - if (ret < 0 && get_bits_left(&alac->gb)) + if (ret < 0 && bitstream_bits_left(&alac->bc)) return ret; ch += channels; @@ -452,9 +453,9 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - if (avpkt->size * 8 - get_bits_count(&alac->gb) > 8) { + if (avpkt->size * 8 - bitstream_tell(&alac->bc) > 8) { av_log(avctx, AV_LOG_ERROR, "Error : %d bits left\n", - avpkt->size * 8 - get_bits_count(&alac->gb)); + avpkt->size * 8 - bitstream_tell(&alac->bc)); } *got_frame_ptr = 1; From fb59f87ce72035b940c3f5045884098b9324e1b2 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Fri, 13 Jan 2017 10:53:35 +0100 Subject: [PATCH 0793/3374] nvenc: Explicitly push the cuda context on encoding Make sure that NVENC does not misbehave if other cuda usages happen in the application. --- libavcodec/nvenc.c | 7 +++++++ libavcodec/nvenc.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 4054e43eecd57..fe7b7f40f0d78 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -178,6 +178,7 @@ static av_cold int nvenc_load_libraries(AVCodecContext *avctx) nvel->cu_device_compute_capability = cuDeviceComputeCapability; nvel->cu_ctx_create = cuCtxCreate_v2; nvel->cu_ctx_pop_current = cuCtxPopCurrent_v2; + nvel->cu_ctx_push_current = cuCtxPushCurrent_v2; nvel->cu_ctx_destroy = cuCtxDestroy_v2; #else LOAD_LIBRARY(nvel->cuda, CUDA_LIBNAME); @@ -190,6 +191,7 @@ static av_cold int nvenc_load_libraries(AVCodecContext *avctx) "cuDeviceComputeCapability"); LOAD_SYMBOL(nvel->cu_ctx_create, nvel->cuda, "cuCtxCreate_v2"); LOAD_SYMBOL(nvel->cu_ctx_pop_current, nvel->cuda, "cuCtxPopCurrent_v2"); + LOAD_SYMBOL(nvel->cu_ctx_push_current, nvel->cuda, "cuCtxPushCurrent_v2"); LOAD_SYMBOL(nvel->cu_ctx_destroy, nvel->cuda, "cuCtxDestroy_v2"); #endif @@ -1522,9 +1524,11 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet) { NVENCContext *ctx = avctx->priv_data; + NVENCLibraryContext *nvel = &ctx->nvel; NV_ENCODE_API_FUNCTION_LIST *nv = &ctx->nvel.nvenc_funcs; NV_ENC_PIC_PARAMS params = { 0 }; NVENCFrame *nvenc_frame = NULL; + CUcontext dummy; int enc_ret, ret; params.version = NV_ENC_PIC_PARAMS_VER; @@ -1570,7 +1574,10 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, params.encodePicFlags = NV_ENC_PIC_FLAG_EOS; } + nvel->cu_ctx_push_current(ctx->cu_context); enc_ret = nv->nvEncEncodePicture(ctx->nvenc_ctx, ¶ms); + nvel->cu_ctx_pop_current(&dummy); + if (enc_ret != NV_ENC_SUCCESS && enc_ret != NV_ENC_ERR_NEED_MORE_INPUT) return nvenc_print_error(avctx, enc_ret, "Error encoding the frame"); diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h index dfd03b5ebd7cf..6df45480a9429 100644 --- a/libavcodec/nvenc.h +++ b/libavcodec/nvenc.h @@ -66,6 +66,7 @@ typedef CUresult(CUDAAPI *PCUDEVICEGETNAME)(char *name, int len, CUdevice dev); typedef CUresult(CUDAAPI *PCUDEVICECOMPUTECAPABILITY)(int *major, int *minor, CUdevice dev); typedef CUresult(CUDAAPI *PCUCTXCREATE)(CUcontext *pctx, unsigned int flags, CUdevice dev); typedef CUresult(CUDAAPI *PCUCTXPOPCURRENT)(CUcontext *pctx); +typedef CUresult(CUDAAPI *PCUCTXPUSHCURRENT)(CUcontext ctx); typedef CUresult(CUDAAPI *PCUCTXDESTROY)(CUcontext ctx); typedef NVENCSTATUS (NVENCAPI *PNVENCODEAPICREATEINSTANCE)(NV_ENCODE_API_FUNCTION_LIST *functionList); @@ -84,6 +85,7 @@ typedef struct NVENCLibraryContext PCUDEVICECOMPUTECAPABILITY cu_device_compute_capability; PCUCTXCREATE cu_ctx_create; PCUCTXPOPCURRENT cu_ctx_pop_current; + PCUCTXPUSHCURRENT cu_ctx_push_current; PCUCTXDESTROY cu_ctx_destroy; NV_ENCODE_API_FUNCTION_LIST nvenc_funcs; From 54dcd2288546e135986338107ea87db1fcedd633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Fri, 8 Apr 2016 19:22:46 +0200 Subject: [PATCH 0794/3374] als: Convert to the new bitstream reader --- libavcodec/alsdec.c | 232 ++++++++++++++++++++++---------------------- libavcodec/bgmc.c | 16 +-- libavcodec/bgmc.h | 16 +-- 3 files changed, 134 insertions(+), 130 deletions(-) diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c index 9fd2827dcdb37..5f09a9d4b95ac 100644 --- a/libavcodec/alsdec.c +++ b/libavcodec/alsdec.c @@ -28,13 +28,13 @@ #include #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "mpeg4audio.h" #include "bytestream.h" #include "bgmc.h" #include "bswapdsp.h" #include "internal.h" -#include "unary_legacy.h" +#include "unary.h" #include "libavutil/samplefmt.h" #include "libavutil/crc.h" @@ -192,7 +192,7 @@ typedef struct ALSChannelData { typedef struct ALSDecContext { AVCodecContext *avctx; ALSSpecificConfig sconf; - GetBitContext gb; + BitstreamContext bc; BswapDSPContext bdsp; const AVCRC *crc_table; uint32_t crc_org; ///< CRC value of the original input data @@ -281,7 +281,7 @@ static av_cold void dprint_specific_config(ALSDecContext *ctx) */ static av_cold int read_specific_config(ALSDecContext *ctx) { - GetBitContext gb; + BitstreamContext bc; uint64_t ht_size; int i, config_offset; MPEG4AudioConfig m4ac; @@ -289,7 +289,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx) AVCodecContext *avctx = ctx->avctx; uint32_t als_id, header_size, trailer_size; - init_get_bits(&gb, avctx->extradata, avctx->extradata_size * 8); + bitstream_init8(&bc, avctx->extradata, avctx->extradata_size); config_offset = avpriv_mpeg4audio_get_config(&m4ac, avctx->extradata, avctx->extradata_size * 8, 1); @@ -297,40 +297,40 @@ static av_cold int read_specific_config(ALSDecContext *ctx) if (config_offset < 0) return AVERROR_INVALIDDATA; - skip_bits_long(&gb, config_offset); + bitstream_skip(&bc, config_offset); - if (get_bits_left(&gb) < (30 << 3)) + if (bitstream_bits_left(&bc) < (30 << 3)) return AVERROR_INVALIDDATA; // read the fixed items - als_id = get_bits_long(&gb, 32); + als_id = bitstream_read(&bc, 32); avctx->sample_rate = m4ac.sample_rate; - skip_bits_long(&gb, 32); // sample rate already known - sconf->samples = get_bits_long(&gb, 32); + bitstream_skip(&bc, 32); // sample rate already known + sconf->samples = bitstream_read(&bc, 32); avctx->channels = m4ac.channels; - skip_bits(&gb, 16); // number of channels already known - skip_bits(&gb, 3); // skip file_type - sconf->resolution = get_bits(&gb, 3); - sconf->floating = get_bits1(&gb); - sconf->msb_first = get_bits1(&gb); - sconf->frame_length = get_bits(&gb, 16) + 1; - sconf->ra_distance = get_bits(&gb, 8); - sconf->ra_flag = get_bits(&gb, 2); - sconf->adapt_order = get_bits1(&gb); - sconf->coef_table = get_bits(&gb, 2); - sconf->long_term_prediction = get_bits1(&gb); - sconf->max_order = get_bits(&gb, 10); - sconf->block_switching = get_bits(&gb, 2); - sconf->bgmc = get_bits1(&gb); - sconf->sb_part = get_bits1(&gb); - sconf->joint_stereo = get_bits1(&gb); - sconf->mc_coding = get_bits1(&gb); - sconf->chan_config = get_bits1(&gb); - sconf->chan_sort = get_bits1(&gb); - sconf->crc_enabled = get_bits1(&gb); - sconf->rlslms = get_bits1(&gb); - skip_bits(&gb, 5); // skip 5 reserved bits - skip_bits1(&gb); // skip aux_data_enabled + bitstream_skip(&bc, 16); // number of channels already known + bitstream_skip(&bc, 3); // skip file_type + sconf->resolution = bitstream_read(&bc, 3); + sconf->floating = bitstream_read_bit(&bc); + sconf->msb_first = bitstream_read_bit(&bc); + sconf->frame_length = bitstream_read(&bc, 16) + 1; + sconf->ra_distance = bitstream_read(&bc, 8); + sconf->ra_flag = bitstream_read(&bc, 2); + sconf->adapt_order = bitstream_read_bit(&bc); + sconf->coef_table = bitstream_read(&bc, 2); + sconf->long_term_prediction = bitstream_read_bit(&bc); + sconf->max_order = bitstream_read(&bc, 10); + sconf->block_switching = bitstream_read(&bc, 2); + sconf->bgmc = bitstream_read_bit(&bc); + sconf->sb_part = bitstream_read_bit(&bc); + sconf->joint_stereo = bitstream_read_bit(&bc); + sconf->mc_coding = bitstream_read_bit(&bc); + sconf->chan_config = bitstream_read_bit(&bc); + sconf->chan_sort = bitstream_read_bit(&bc); + sconf->crc_enabled = bitstream_read_bit(&bc); + sconf->rlslms = bitstream_read_bit(&bc); + bitstream_skip(&bc, 5); // skip 5 reserved bits + bitstream_skip(&bc, 1); // skip aux_data_enabled // check for ALSSpecificConfig struct @@ -341,7 +341,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx) // read channel config if (sconf->chan_config) - sconf->chan_config_info = get_bits(&gb, 16); + sconf->chan_config_info = bitstream_read(&bc, 16); // TODO: use this to set avctx->channel_layout @@ -349,16 +349,16 @@ static av_cold int read_specific_config(ALSDecContext *ctx) if (sconf->chan_sort && avctx->channels > 1) { int chan_pos_bits = av_ceil_log2(avctx->channels); int bits_needed = avctx->channels * chan_pos_bits + 7; - if (get_bits_left(&gb) < bits_needed) + if (bitstream_bits_left(&bc) < bits_needed) return AVERROR_INVALIDDATA; if (!(sconf->chan_pos = av_malloc(avctx->channels * sizeof(*sconf->chan_pos)))) return AVERROR(ENOMEM); for (i = 0; i < avctx->channels; i++) - sconf->chan_pos[i] = get_bits(&gb, chan_pos_bits); + sconf->chan_pos[i] = bitstream_read(&bc, chan_pos_bits); - align_get_bits(&gb); + bitstream_align(&bc); // TODO: use this to actually do channel sorting } else { sconf->chan_sort = 0; @@ -367,11 +367,11 @@ static av_cold int read_specific_config(ALSDecContext *ctx) // read fixed header and trailer sizes, // if size = 0xFFFFFFFF then there is no data field! - if (get_bits_left(&gb) < 64) + if (bitstream_bits_left(&bc) < 64) return AVERROR_INVALIDDATA; - header_size = get_bits_long(&gb, 32); - trailer_size = get_bits_long(&gb, 32); + header_size = bitstream_read(&bc, 32); + trailer_size = bitstream_read(&bc, 32); if (header_size == 0xFFFFFFFF) header_size = 0; if (trailer_size == 0xFFFFFFFF) @@ -381,26 +381,26 @@ static av_cold int read_specific_config(ALSDecContext *ctx) // skip the header and trailer data - if (get_bits_left(&gb) < ht_size) + if (bitstream_bits_left(&bc) < ht_size) return AVERROR_INVALIDDATA; if (ht_size > INT32_MAX) return AVERROR_PATCHWELCOME; - skip_bits_long(&gb, ht_size); + bitstream_skip(&bc, ht_size); // initialize CRC calculation if (sconf->crc_enabled) { - if (get_bits_left(&gb) < 32) + if (bitstream_bits_left(&bc) < 32) return AVERROR_INVALIDDATA; if (avctx->err_recognition & AV_EF_CRCCHECK) { ctx->crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE); ctx->crc = 0xFFFFFFFF; - ctx->crc_org = ~get_bits_long(&gb, 32); + ctx->crc_org = ~bitstream_read(&bc, 32); } else - skip_bits_long(&gb, 32); + bitstream_skip(&bc, 32); } @@ -463,15 +463,15 @@ static void parse_bs_info(const uint32_t bs_info, unsigned int n, /** Read and decode a Rice codeword. */ -static int32_t decode_rice(GetBitContext *gb, unsigned int k) +static int32_t decode_rice(BitstreamContext *bc, unsigned int k) { - int max = get_bits_left(gb) - k; - int q = get_unary(gb, 0, max); - int r = k ? get_bits1(gb) : !(q & 1); + int max = bitstream_bits_left(bc) - k; + int q = get_unary(bc, 0, max); + int r = k ? bitstream_read_bit(bc) : !(q & 1); if (k > 1) { q <<= (k - 1); - q += get_bits_long(gb, k - 1); + q += bitstream_read(bc, k - 1); } else if (!k) { q >>= 1; } @@ -505,13 +505,13 @@ static void get_block_sizes(ALSDecContext *ctx, unsigned int *div_blocks, uint32_t *bs_info) { ALSSpecificConfig *sconf = &ctx->sconf; - GetBitContext *gb = &ctx->gb; + BitstreamContext *bc = &ctx->bc; unsigned int *ptr_div_blocks = div_blocks; unsigned int b; if (sconf->block_switching) { unsigned int bs_info_len = 1 << (sconf->block_switching + 2); - *bs_info = get_bits_long(gb, bs_info_len); + *bs_info = bitstream_read(bc, bs_info_len); *bs_info <<= (32 - bs_info_len); } @@ -558,18 +558,18 @@ static void read_const_block_data(ALSDecContext *ctx, ALSBlockData *bd) { ALSSpecificConfig *sconf = &ctx->sconf; AVCodecContext *avctx = ctx->avctx; - GetBitContext *gb = &ctx->gb; + BitstreamContext *bc = &ctx->bc; *bd->raw_samples = 0; - *bd->const_block = get_bits1(gb); // 1 = constant value, 0 = zero block (silence) - bd->js_blocks = get_bits1(gb); + *bd->const_block = bitstream_read_bit(bc); // 1 = constant value, 0 = zero block (silence) + bd->js_blocks = bitstream_read_bit(bc); // skip 5 reserved bits - skip_bits(gb, 5); + bitstream_skip(bc, 5); if (*bd->const_block) { unsigned int const_val_bits = sconf->floating ? 24 : avctx->bits_per_raw_sample; - *bd->raw_samples = get_sbits_long(gb, const_val_bits); + *bd->raw_samples = bitstream_read_signed(bc, const_val_bits); } // ensure constant block decoding by reusing this field @@ -597,7 +597,7 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) { ALSSpecificConfig *sconf = &ctx->sconf; AVCodecContext *avctx = ctx->avctx; - GetBitContext *gb = &ctx->gb; + BitstreamContext *bc = &ctx->bc; unsigned int k; unsigned int s[8]; unsigned int sx[8]; @@ -613,7 +613,7 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) *bd->const_block = 0; *bd->opt_order = 1; - bd->js_blocks = get_bits1(gb); + bd->js_blocks = bitstream_read_bit(bc); opt_order = *bd->opt_order; @@ -622,9 +622,9 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) log2_sub_blocks = 0; } else { if (sconf->bgmc && sconf->sb_part) - log2_sub_blocks = get_bits(gb, 2); + log2_sub_blocks = bitstream_read(bc, 2); else - log2_sub_blocks = 2 * get_bits1(gb); + log2_sub_blocks = 2 * bitstream_read_bit(bc); } sub_blocks = 1 << log2_sub_blocks; @@ -640,18 +640,18 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) sb_length = bd->block_length >> log2_sub_blocks; if (sconf->bgmc) { - s[0] = get_bits(gb, 8 + (sconf->resolution > 1)); + s[0] = bitstream_read(bc, 8 + (sconf->resolution > 1)); for (k = 1; k < sub_blocks; k++) - s[k] = s[k - 1] + decode_rice(gb, 2); + s[k] = s[k - 1] + decode_rice(bc, 2); for (k = 0; k < sub_blocks; k++) { sx[k] = s[k] & 0x0F; s [k] >>= 4; } } else { - s[0] = get_bits(gb, 4 + (sconf->resolution > 1)); + s[0] = bitstream_read(bc, 4 + (sconf->resolution > 1)); for (k = 1; k < sub_blocks; k++) - s[k] = s[k - 1] + decode_rice(gb, 0); + s[k] = s[k - 1] + decode_rice(bc, 0); } for (k = 1; k < sub_blocks; k++) if (s[k] > 32) { @@ -659,8 +659,8 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) return AVERROR_INVALIDDATA; } - if (get_bits1(gb)) - *bd->shift_lsbs = get_bits(gb, 4) + 1; + if (bitstream_read_bit(bc)) + *bd->shift_lsbs = bitstream_read(bc, 4) + 1; *bd->store_prev_samples = (bd->js_blocks && bd->raw_other) || *bd->shift_lsbs; @@ -669,7 +669,7 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) if (sconf->adapt_order && sconf->max_order) { int opt_order_length = av_ceil_log2(av_clip((bd->block_length >> 3) - 1, 2, sconf->max_order + 1)); - *bd->opt_order = get_bits(gb, opt_order_length); + *bd->opt_order = bitstream_read(bc, opt_order_length); if (*bd->opt_order > sconf->max_order) { *bd->opt_order = sconf->max_order; av_log(avctx, AV_LOG_ERROR, "Predictor order too large!\n"); @@ -688,15 +688,15 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) add_base = 0x7F; // read coefficient 0 - quant_cof[0] = 32 * parcor_scaled_values[get_bits(gb, 7)]; + quant_cof[0] = 32 * parcor_scaled_values[bitstream_read(bc, 7)]; // read coefficient 1 if (opt_order > 1) - quant_cof[1] = -32 * parcor_scaled_values[get_bits(gb, 7)]; + quant_cof[1] = -32 * parcor_scaled_values[bitstream_read(bc, 7)]; // read coefficients 2 to opt_order for (k = 2; k < opt_order; k++) - quant_cof[k] = get_bits(gb, 7); + quant_cof[k] = bitstream_read(bc, 7); } else { int k_max; add_base = 1; @@ -706,7 +706,7 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) for (k = 0; k < k_max; k++) { int rice_param = parcor_rice_table[sconf->coef_table][k][1]; int offset = parcor_rice_table[sconf->coef_table][k][0]; - quant_cof[k] = decode_rice(gb, rice_param) + offset; + quant_cof[k] = decode_rice(bc, rice_param) + offset; if (quant_cof[k] < -64 || quant_cof[k] > 63) { av_log(avctx, AV_LOG_ERROR, "quant_cof %"PRIu32" is out of range\n", @@ -718,11 +718,11 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) // read coefficients 20 to 126 k_max = FFMIN(opt_order, 127); for (; k < k_max; k++) - quant_cof[k] = decode_rice(gb, 2) + (k & 1); + quant_cof[k] = decode_rice(bc, 2) + (k & 1); // read coefficients 127 to opt_order for (; k < opt_order; k++) - quant_cof[k] = decode_rice(gb, 1); + quant_cof[k] = decode_rice(bc, 1); quant_cof[0] = 32 * parcor_scaled_values[quant_cof[0] + 64]; @@ -737,22 +737,22 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) // read LTP gain and lag values if (sconf->long_term_prediction) { - *bd->use_ltp = get_bits1(gb); + *bd->use_ltp = bitstream_read_bit(bc); if (*bd->use_ltp) { int r, c; - bd->ltp_gain[0] = decode_rice(gb, 1) << 3; - bd->ltp_gain[1] = decode_rice(gb, 2) << 3; + bd->ltp_gain[0] = decode_rice(bc, 1) << 3; + bd->ltp_gain[1] = decode_rice(bc, 2) << 3; - r = get_unary(gb, 0, 3); - c = get_bits(gb, 2); + r = get_unary(bc, 0, 3); + c = bitstream_read(bc, 2); bd->ltp_gain[2] = ltp_gain_values[r][c]; - bd->ltp_gain[3] = decode_rice(gb, 2) << 3; - bd->ltp_gain[4] = decode_rice(gb, 1) << 3; + bd->ltp_gain[3] = decode_rice(bc, 2) << 3; + bd->ltp_gain[4] = decode_rice(bc, 1) << 3; - *bd->ltp_lag = get_bits(gb, ctx->ltp_lag_length); + *bd->ltp_lag = bitstream_read(bc, ctx->ltp_lag_length); *bd->ltp_lag += FFMAX(4, opt_order + 1); } } @@ -760,11 +760,11 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) // read first value and residuals in case of a random access block if (bd->ra_block) { if (opt_order) - bd->raw_samples[0] = decode_rice(gb, avctx->bits_per_raw_sample - 4); + bd->raw_samples[0] = decode_rice(bc, avctx->bits_per_raw_sample - 4); if (opt_order > 1) - bd->raw_samples[1] = decode_rice(gb, FFMIN(s[0] + 3, ctx->s_max)); + bd->raw_samples[1] = decode_rice(bc, FFMIN(s[0] + 3, ctx->s_max)); if (opt_order > 2) - bd->raw_samples[2] = decode_rice(gb, FFMIN(s[0] + 1, ctx->s_max)); + bd->raw_samples[2] = decode_rice(bc, FFMIN(s[0] + 1, ctx->s_max)); start = FFMIN(opt_order, 3); } @@ -780,7 +780,7 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) unsigned int low; unsigned int value; - ff_bgmc_decode_init(gb, &high, &low, &value); + ff_bgmc_decode_init(bc, &high, &low, &value); current_res = bd->raw_samples + start; @@ -790,13 +790,13 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) k [sb] = s[sb] > b ? s[sb] - b : 0; delta[sb] = 5 - s[sb] + k[sb]; - ff_bgmc_decode(gb, sb_len, current_res, - delta[sb], sx[sb], &high, &low, &value, ctx->bgmc_lut, ctx->bgmc_lut_status); + ff_bgmc_decode(bc, sb_len, current_res, delta[sb], sx[sb], &high, + &low, &value, ctx->bgmc_lut, ctx->bgmc_lut_status); current_res += sb_len; } - ff_bgmc_decode_end(gb); + ff_bgmc_decode_end(bc); // read least significant bits and tails @@ -814,7 +814,7 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) unsigned int max_msb = (2 + (sx[sb] > 2) + (sx[sb] > 10)) << (5 - delta[sb]); - res = decode_rice(gb, cur_s); + res = decode_rice(bc, cur_s); if (res >= 0) { res += (max_msb ) << cur_k; @@ -832,7 +832,7 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) if (cur_k) { res <<= cur_k; - res |= get_bits_long(gb, cur_k); + res |= bitstream_read(bc, cur_k); } } @@ -844,11 +844,11 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) for (sb = 0; sb < sub_blocks; sb++, start = 0) for (; start < sb_length; start++) - *current_res++ = decode_rice(gb, s[sb]); + *current_res++ = decode_rice(bc, s[sb]); } if (!sconf->mc_coding || ctx->js_switch) - align_get_bits(gb); + bitstream_align(bc); return 0; } @@ -968,11 +968,11 @@ static int decode_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) static int read_block(ALSDecContext *ctx, ALSBlockData *bd) { int ret = 0; - GetBitContext *gb = &ctx->gb; + BitstreamContext *bc = &ctx->bc; *bd->shift_lsbs = 0; // read block type flag and read the samples accordingly - if (get_bits1(gb)) { + if (bitstream_read_bit(bc)) { ret = read_var_block_data(ctx, bd); } else { read_const_block_data(ctx, bd); @@ -1163,9 +1163,9 @@ static int decode_blocks(ALSDecContext *ctx, unsigned int ra_frame, return ret; } -static inline int als_weighting(GetBitContext *gb, int k, int off) +static inline int als_weighting(BitstreamContext *bc, int k, int off) { - int idx = av_clip(decode_rice(gb, k) + off, + int idx = av_clip(decode_rice(bc, k) + off, 0, FF_ARRAY_ELEMS(mcc_weightings) - 1); return mcc_weightings[idx]; } @@ -1174,13 +1174,13 @@ static inline int als_weighting(GetBitContext *gb, int k, int off) */ static int read_channel_data(ALSDecContext *ctx, ALSChannelData *cd, int c) { - GetBitContext *gb = &ctx->gb; + BitstreamContext *bc = &ctx->bc; ALSChannelData *current = cd; unsigned int channels = ctx->avctx->channels; int entries = 0; - while (entries < channels && !(current->stop_flag = get_bits1(gb))) { - current->master_channel = get_bits_long(gb, av_ceil_log2(channels)); + while (entries < channels && !(current->stop_flag = bitstream_read_bit(bc))) { + current->master_channel = bitstream_read(bc, av_ceil_log2(channels)); if (current->master_channel >= channels) { av_log(ctx->avctx, AV_LOG_ERROR, "Invalid master channel!\n"); @@ -1188,18 +1188,18 @@ static int read_channel_data(ALSDecContext *ctx, ALSChannelData *cd, int c) } if (current->master_channel != c) { - current->time_diff_flag = get_bits1(gb); - current->weighting[0] = als_weighting(gb, 1, 16); - current->weighting[1] = als_weighting(gb, 2, 14); - current->weighting[2] = als_weighting(gb, 1, 16); + current->time_diff_flag = bitstream_read_bit(bc); + current->weighting[0] = als_weighting(bc, 1, 16); + current->weighting[1] = als_weighting(bc, 2, 14); + current->weighting[2] = als_weighting(bc, 1, 16); if (current->time_diff_flag) { - current->weighting[3] = als_weighting(gb, 1, 16); - current->weighting[4] = als_weighting(gb, 1, 16); - current->weighting[5] = als_weighting(gb, 1, 16); + current->weighting[3] = als_weighting(bc, 1, 16); + current->weighting[4] = als_weighting(bc, 1, 16); + current->weighting[5] = als_weighting(bc, 1, 16); - current->time_diff_sign = get_bits1(gb); - current->time_diff_index = get_bits(gb, ctx->ltp_lag_length - 3) + 3; + current->time_diff_sign = bitstream_read_bit(bc); + current->time_diff_index = bitstream_read(bc, ctx->ltp_lag_length - 3) + 3; } } @@ -1212,7 +1212,7 @@ static int read_channel_data(ALSDecContext *ctx, ALSChannelData *cd, int c) return AVERROR_INVALIDDATA; } - align_get_bits(gb); + bitstream_align(bc); return 0; } @@ -1328,7 +1328,7 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame) { ALSSpecificConfig *sconf = &ctx->sconf; AVCodecContext *avctx = ctx->avctx; - GetBitContext *gb = &ctx->gb; + BitstreamContext *bc = &ctx->bc; unsigned int div_blocks[32]; ///< block sizes. unsigned int c; unsigned int js_blocks[2]; @@ -1337,11 +1337,11 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame) // skip the size of the ra unit if present in the frame if (sconf->ra_flag == RA_FLAG_FRAMES && ra_frame) - skip_bits_long(gb, 32); + bitstream_skip(bc, 32); if (sconf->mc_coding && sconf->joint_stereo) { - ctx->js_switch = get_bits1(gb); - align_get_bits(gb); + ctx->js_switch = bitstream_read_bit(bc); + bitstream_align(bc); } if (!sconf->mc_coding || ctx->js_switch) { @@ -1481,7 +1481,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, int invalid_frame, ret; unsigned int c, sample, ra_frame, bytes_read, shift; - init_get_bits(&ctx->gb, buffer, buffer_size * 8); + bitstream_init8(&ctx->bc, buffer, buffer_size); // In the case that the distance between random access frames is set to zero // (sconf->ra_distance == 0) no frame is treated as a random access frame. @@ -1586,7 +1586,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, *got_frame_ptr = 1; bytes_read = invalid_frame ? buffer_size : - (get_bits_count(&ctx->gb) + 7) >> 3; + (bitstream_tell(&ctx->bc) + 7) >> 3; return bytes_read; } diff --git a/libavcodec/bgmc.c b/libavcodec/bgmc.c index ad8baaecacae7..1de67537af646 100644 --- a/libavcodec/bgmc.c +++ b/libavcodec/bgmc.c @@ -26,6 +26,8 @@ */ #include "libavutil/attributes.h" + +#include "bitstream.h" #include "bgmc.h" #define FREQ_BITS 14 // bits used by frequency counters @@ -485,24 +487,26 @@ av_cold void ff_bgmc_end(uint8_t **cf_lut, int **cf_lut_status) /** Initialize decoding and reads the first value */ -void ff_bgmc_decode_init(GetBitContext *gb, unsigned int *h, +void ff_bgmc_decode_init(BitstreamContext *bc, unsigned int *h, unsigned int *l, unsigned int *v) { *h = TOP_VALUE; *l = 0; - *v = get_bits_long(gb, VALUE_BITS); + *v = bitstream_read(bc, VALUE_BITS); } /** Finish decoding */ -void ff_bgmc_decode_end(GetBitContext *gb) +void ff_bgmc_decode_end(BitstreamContext *bc) { - skip_bits_long(gb, -(VALUE_BITS - 2)); + unsigned pos = bitstream_tell(bc) - VALUE_BITS + 2; + + bitstream_seek(bc, pos); } /** Read and decode a block Gilbert-Moore coded symbol */ -void ff_bgmc_decode(GetBitContext *gb, unsigned int num, int32_t *dst, +void ff_bgmc_decode(BitstreamContext *bc, unsigned int num, int32_t *dst, int delta, unsigned int sx, unsigned int *h, unsigned int *l, unsigned int *v, uint8_t *cf_lut, int *cf_lut_status) @@ -547,7 +551,7 @@ void ff_bgmc_decode(GetBitContext *gb, unsigned int num, int32_t *dst, low *= 2; high = 2 * high + 1; - value = 2 * value + get_bits1(gb); + value = 2 * value + bitstream_read_bit(bc); } *dst++ = symbol; diff --git a/libavcodec/bgmc.h b/libavcodec/bgmc.h index 3d5b49034da78..68a4cf1d94f30 100644 --- a/libavcodec/bgmc.h +++ b/libavcodec/bgmc.h @@ -31,7 +31,7 @@ #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" int ff_bgmc_init(AVCodecContext *avctx, uint8_t **cf_lut, int **cf_lut_status); @@ -40,17 +40,17 @@ int ff_bgmc_init(AVCodecContext *avctx, uint8_t **cf_lut, int **cf_lut_status); void ff_bgmc_end(uint8_t **cf_lut, int **cf_lut_status); -void ff_bgmc_decode_init(GetBitContext *gb, - unsigned int *h, unsigned int *l, unsigned int *v); +void ff_bgmc_decode_init(BitstreamContext *bc, + unsigned int *h, unsigned int *l, unsigned int *v); -void ff_bgmc_decode_end(GetBitContext *gb); +void ff_bgmc_decode_end(BitstreamContext *bc); -void ff_bgmc_decode(GetBitContext *gb, unsigned int num, int32_t *dst, - int delta, unsigned int sx, - unsigned int *h, unsigned int *l, unsigned int *v, - uint8_t *cf_lut, int *cf_lut_status); +void ff_bgmc_decode(BitstreamContext *bc, unsigned int num, int32_t *dst, + int delta, unsigned int sx, + unsigned int *h, unsigned int *l, unsigned int *v, + uint8_t *cf_lut, int *cf_lut_status); #endif /* AVCODEC_BGMC_H */ From 00b775dda2b3f78ae60ff3278d3b3d6545883a83 Mon Sep 17 00:00:00 2001 From: Derek Buitenhuis Date: Wed, 11 Jan 2017 13:12:19 -0500 Subject: [PATCH 0795/3374] hevc: Mark as having threadsafe init Signed-off-by: Derek Buitenhuis Signed-off-by: Anton Khirnov --- libavcodec/hevcdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index a4c936ee05381..dcb2453a20a79 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -3092,5 +3092,5 @@ AVCodec ff_hevc_decoder = { .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_FRAME_THREADS, .profiles = NULL_IF_CONFIG_SMALL(ff_hevc_profiles), - .caps_internal = FF_CODEC_CAP_EXPORTS_CROPPING, + .caps_internal = FF_CODEC_CAP_EXPORTS_CROPPING | FF_CODEC_CAP_INIT_THREADSAFE, }; From 296eff4d9dc53d441b672319524a051d04f4a8cf Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 22 May 2016 21:09:58 +0200 Subject: [PATCH 0796/3374] zmbvenc: get rid of a global table --- libavcodec/zmbvenc.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/libavcodec/zmbvenc.c b/libavcodec/zmbvenc.c index 4436bb3c5158e..e7b39f41c781f 100644 --- a/libavcodec/zmbvenc.c +++ b/libavcodec/zmbvenc.c @@ -54,16 +54,18 @@ typedef struct ZmbvEncContext { int comp_size; int keyint, curfrm; z_stream zstream; + + int score_tab[256]; } ZmbvEncContext; -static int score_tab[256]; /** Block comparing function * XXX should be optimized and moved to DSPContext * TODO handle out of edge ME */ -static inline int block_cmp(uint8_t *src, int stride, uint8_t *src2, int stride2, - int bw, int bh, int *xored) +static inline int block_cmp(ZmbvEncContext *c, uint8_t *src, int stride, + uint8_t *src2, int stride2, int bw, int bh, + int *xored) { int sum = 0; int i, j; @@ -81,7 +83,7 @@ static inline int block_cmp(uint8_t *src, int stride, uint8_t *src2, int stride2 } for(i = 1; i < 256; i++) - sum += score_tab[histogram[i]]; + sum += c->score_tab[histogram[i]]; return sum; } @@ -97,14 +99,14 @@ static int zmbv_me(ZmbvEncContext *c, uint8_t *src, int sstride, uint8_t *prev, *mx = *my = 0; bw = FFMIN(ZMBV_BLOCK, c->avctx->width - x); bh = FFMIN(ZMBV_BLOCK, c->avctx->height - y); - bv = block_cmp(src, sstride, prev, pstride, bw, bh, xored); + bv = block_cmp(c, src, sstride, prev, pstride, bw, bh, xored); if(!bv) return 0; for(ty = FFMAX(y - c->range, 0); ty < FFMIN(y + c->range, c->avctx->height - bh); ty++){ for(tx = FFMAX(x - c->range, 0); tx < FFMIN(x + c->range, c->avctx->width - bw); tx++){ if(tx == x && ty == y) continue; // we already tested this block dx = tx - x; dy = ty - y; - tv = block_cmp(src, sstride, prev + dx + dy*pstride, pstride, bw, bh, xored); + tv = block_cmp(c, src, sstride, prev + dx + dy * pstride, pstride, bw, bh, xored); if(tv < bv){ bv = tv; *mx = dx; @@ -279,7 +281,7 @@ static av_cold int encode_init(AVCodecContext *avctx) int lvl = 9; for(i=1; i<256; i++) - score_tab[i]= -i * log(i/(double)(ZMBV_BLOCK*ZMBV_BLOCK)) * (256/M_LN2); + c->score_tab[i] = -i * log(i / (double)(ZMBV_BLOCK * ZMBV_BLOCK)) * (256 / M_LN2); c->avctx = avctx; From b4a911c189962e563a09fb0efaf6fa9ab56263a4 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 22 May 2016 21:20:31 +0200 Subject: [PATCH 0797/3374] mpegvideoenc: make a table const --- libavcodec/x86/mpegvideoenc.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libavcodec/x86/mpegvideoenc.c b/libavcodec/x86/mpegvideoenc.c index 47349d17ecfe8..ead2ed1757bc8 100644 --- a/libavcodec/x86/mpegvideoenc.c +++ b/libavcodec/x86/mpegvideoenc.c @@ -28,7 +28,12 @@ #include "libavcodec/mpegvideo.h" /* not permutated inverse zigzag_direct + 1 for MMX quantizer */ -DECLARE_ALIGNED(16, static uint16_t, inv_zigzag_direct16)[64]; +DECLARE_ALIGNED(16, static const uint16_t, inv_zigzag_direct16)[64] = { + 1, 2, 6, 7, 15, 16, 28, 29, 3, 5, 8, 14, 17, 27, 30, 43, 4, 9, 13, + 18, 26, 31, 42, 44, 10, 12, 19, 25, 32, 41, 45, 54, 11, 20, 24, 33, 40, 46, + 53, 55, 21, 23, 34, 39, 47, 52, 56, 61, 22, 35, 38, 48, 51, 57, 60, 62, 36, + 37, 49, 50, 58, 59, 63, 64, +}; #if HAVE_MMX_INLINE #define COMPILE_TEMPLATE_MMXEXT 0 @@ -196,10 +201,6 @@ static void denoise_dct_sse2(MpegEncContext *s, int16_t *block){ av_cold void ff_mpv_encode_init_x86(MpegEncContext *s) { const int dct_algo = s->avctx->dct_algo; - int i; - - for (i = 0; i < 64; i++) - inv_zigzag_direct16[ff_zigzag_direct[i]] = i + 1; if (dct_algo == FF_DCT_AUTO || dct_algo == FF_DCT_MMX) { #if HAVE_MMX_INLINE From 4d49a4c55054571b56d3b1b1cd9fb9ac4c2bea6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Fri, 8 Apr 2016 19:49:07 +0200 Subject: [PATCH 0798/3374] apedec: Convert to the new bitstream reader --- libavcodec/apedec.c | 47 +++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index 69ded9a670176..da45e85e51afe 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -25,13 +25,14 @@ #include "libavutil/avassert.h" #include "libavutil/channel_layout.h" #include "libavutil/opt.h" + #include "apedsp.h" #include "avcodec.h" +#include "bitstream.h" #include "bswapdsp.h" #include "bytestream.h" #include "internal.h" -#include "get_bits.h" -#include "unary_legacy.h" +#include "unary.h" /** * @file @@ -162,7 +163,7 @@ typedef struct APEContext { APERice riceX; ///< rice code parameters for the second channel APERice riceY; ///< rice code parameters for the first channel APEFilter filters[APE_FILTER_LEVELS][2]; ///< filters used for reconstruction - GetBitContext gb; + BitstreamContext bc; uint8_t *data; ///< current frame data uint8_t *data_end; ///< frame data end @@ -484,24 +485,24 @@ static inline void update_rice(APERice *rice, unsigned int x) rice->k++; } -static inline int get_rice_ook(GetBitContext *gb, int k) +static inline int get_rice_ook(BitstreamContext *bc, int k) { unsigned int x; - x = get_unary(gb, 1, get_bits_left(gb)); + x = get_unary(bc, 1, bitstream_bits_left(bc)); if (k) - x = (x << k) | get_bits(gb, k); + x = (x << k) | bitstream_read(bc, k); return x; } -static inline int ape_decode_value_3860(APEContext *ctx, GetBitContext *gb, +static inline int ape_decode_value_3860(APEContext *ctx, BitstreamContext *bc, APERice *rice) { unsigned int x, overflow; - overflow = get_unary(gb, 1, get_bits_left(gb)); + overflow = get_unary(bc, 1, bitstream_bits_left(bc)); if (ctx->fileversion > 3880) { while (overflow >= 16) { @@ -513,7 +514,7 @@ static inline int ape_decode_value_3860(APEContext *ctx, GetBitContext *gb, if (!rice->k) x = overflow; else - x = (overflow << rice->k) + get_bits(gb, rice->k); + x = (overflow << rice->k) + bitstream_read(bc, rice->k); rice->ksum += x - (rice->ksum + 8 >> 4); if (rice->ksum < (rice->k ? 1 << (rice->k + 4) : 0)) @@ -607,7 +608,7 @@ static inline int ape_decode_value_3990(APEContext *ctx, APERice *rice) return -(x >> 1); } -static void decode_array_0000(APEContext *ctx, GetBitContext *gb, +static void decode_array_0000(APEContext *ctx, BitstreamContext *bc, int32_t *out, APERice *rice, int blockstodecode) { int i; @@ -615,19 +616,19 @@ static void decode_array_0000(APEContext *ctx, GetBitContext *gb, rice->ksum = 0; for (i = 0; i < FFMIN(blockstodecode, 5); i++) { - out[i] = get_rice_ook(&ctx->gb, 10); + out[i] = get_rice_ook(&ctx->bc, 10); rice->ksum += out[i]; } rice->k = av_log2(rice->ksum / 10) + 1; for (; i < FFMIN(blockstodecode, 64); i++) { - out[i] = get_rice_ook(&ctx->gb, rice->k); + out[i] = get_rice_ook(&ctx->bc, rice->k); rice->ksum += out[i]; rice->k = av_log2(rice->ksum / ((i + 1) * 2)) + 1; } ksummax = 1 << rice->k + 7; ksummin = rice->k ? (1 << rice->k + 6) : 0; for (; i < blockstodecode; i++) { - out[i] = get_rice_ook(&ctx->gb, rice->k); + out[i] = get_rice_ook(&ctx->bc, rice->k); rice->ksum += out[i] - out[i - 64]; while (rice->ksum < ksummin) { rice->k--; @@ -653,15 +654,15 @@ static void decode_array_0000(APEContext *ctx, GetBitContext *gb, static void entropy_decode_mono_0000(APEContext *ctx, int blockstodecode) { - decode_array_0000(ctx, &ctx->gb, ctx->decoded[0], &ctx->riceY, + decode_array_0000(ctx, &ctx->bc, ctx->decoded[0], &ctx->riceY, blockstodecode); } static void entropy_decode_stereo_0000(APEContext *ctx, int blockstodecode) { - decode_array_0000(ctx, &ctx->gb, ctx->decoded[0], &ctx->riceY, + decode_array_0000(ctx, &ctx->bc, ctx->decoded[0], &ctx->riceY, blockstodecode); - decode_array_0000(ctx, &ctx->gb, ctx->decoded[1], &ctx->riceX, + decode_array_0000(ctx, &ctx->bc, ctx->decoded[1], &ctx->riceX, blockstodecode); } @@ -670,7 +671,7 @@ static void entropy_decode_mono_3860(APEContext *ctx, int blockstodecode) int32_t *decoded0 = ctx->decoded[0]; while (blockstodecode--) - *decoded0++ = ape_decode_value_3860(ctx, &ctx->gb, &ctx->riceY); + *decoded0++ = ape_decode_value_3860(ctx, &ctx->bc, &ctx->riceY); } static void entropy_decode_stereo_3860(APEContext *ctx, int blockstodecode) @@ -680,9 +681,9 @@ static void entropy_decode_stereo_3860(APEContext *ctx, int blockstodecode) int blocks = blockstodecode; while (blockstodecode--) - *decoded0++ = ape_decode_value_3860(ctx, &ctx->gb, &ctx->riceY); + *decoded0++ = ape_decode_value_3860(ctx, &ctx->bc, &ctx->riceY); while (blocks--) - *decoded1++ = ape_decode_value_3860(ctx, &ctx->gb, &ctx->riceX); + *decoded1++ = ape_decode_value_3860(ctx, &ctx->bc, &ctx->riceX); } static void entropy_decode_mono_3900(APEContext *ctx, int blockstodecode) @@ -747,7 +748,7 @@ static int init_entropy_decoder(APEContext *ctx) return AVERROR_INVALIDDATA; ctx->CRC = bytestream_get_be32(&ctx->ptr); } else { - ctx->CRC = get_bits_long(&ctx->gb, 32); + ctx->CRC = bitstream_read(&ctx->bc, 32); } /* Read the frame flags if they exist */ @@ -1480,11 +1481,11 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data, } s->ptr += offset; } else { - init_get_bits(&s->gb, s->ptr, (s->data_end - s->ptr) * 8); + bitstream_init8(&s->bc, s->ptr, s->data_end - s->ptr); if (s->fileversion > 3800) - skip_bits_long(&s->gb, offset * 8); + bitstream_skip(&s->bc, offset * 8); else - skip_bits_long(&s->gb, offset); + bitstream_skip(&s->bc, offset); } if (!nblocks || nblocks > INT_MAX) { From fd8de7f2d8c31195d309247cb129c0ad787ef76e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 9 Apr 2016 19:37:46 +0200 Subject: [PATCH 0799/3374] dxtory: Convert to the new bitstream reader --- libavcodec/dxtory.c | 88 ++++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/libavcodec/dxtory.c b/libavcodec/dxtory.c index b0fae2f5ef91e..05de4ac837e7c 100644 --- a/libavcodec/dxtory.c +++ b/libavcodec/dxtory.c @@ -27,10 +27,10 @@ #define BITSTREAM_READER_LE #include "avcodec.h" +#include "bitstream.h" #include "bytestream.h" -#include "get_bits.h" #include "internal.h" -#include "unary_legacy.h" +#include "unary.h" static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size, @@ -176,13 +176,13 @@ static const uint8_t def_lru[8] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0x static const uint8_t def_lru_555[8] = { 0x00, 0x08, 0x10, 0x18, 0x1F }; static const uint8_t def_lru_565[8] = { 0x00, 0x08, 0x10, 0x20, 0x30, 0x3F }; -static inline uint8_t decode_sym(GetBitContext *gb, uint8_t lru[8]) +static inline uint8_t decode_sym(BitstreamContext *bc, uint8_t lru[8]) { uint8_t c, val; - c = get_unary(gb, 0, 8); + c = get_unary(bc, 0, 8); if (!c) { - val = get_bits(gb, 8); + val = bitstream_read(bc, 8); memmove(lru + 1, lru, sizeof(*lru) * (8 - 1)); } else { val = lru[c - 1]; @@ -243,14 +243,14 @@ static int load_buffer(AVCodecContext *avctx, return 0; } -static inline uint8_t decode_sym_565(GetBitContext *gb, uint8_t lru[8], +static inline uint8_t decode_sym_565(BitstreamContext *bc, uint8_t lru[8], int bits) { uint8_t c, val; - c = get_unary(gb, 0, bits); + c = get_unary(bc, 0, bits); if (!c) { - val = get_bits(gb, bits); + val = bitstream_read(bc, bits); memmove(lru + 1, lru, sizeof(*lru) * (6 - 1)); } else { val = lru[c - 1]; @@ -261,7 +261,7 @@ static inline uint8_t decode_sym_565(GetBitContext *gb, uint8_t lru[8], return val; } -typedef int (*decode_slice_func)(GetBitContext *gb, AVFrame *frame, +typedef int (*decode_slice_func)(BitstreamContext *bc, AVFrame *frame, int line, int height, uint8_t lru[3][8]); typedef void (*setup_lru_func)(uint8_t lru[3][8]); @@ -273,7 +273,7 @@ static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic, enum AVPixelFormat fmt) { GetByteContext gb; - GetBitContext gb2; + BitstreamContext bc; int nslices, slice, line = 0; uint32_t off, slice_size; uint8_t lru[3][8]; @@ -296,9 +296,9 @@ static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic, if (ret < 0) return ret; - init_get_bits(&gb2, src + off + 16, (slice_size - 16) * 8); + bitstream_init8(&bc, src + off + 16, slice_size - 16); - line += decode_slice(&gb2, pic, line, avctx->height - line, lru); + line += decode_slice(&bc, pic, line, avctx->height - line, lru); off += slice_size; } @@ -315,7 +315,7 @@ static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic, } av_always_inline -static int dx2_decode_slice_5x5(GetBitContext *gb, AVFrame *frame, +static int dx2_decode_slice_5x5(BitstreamContext *bc, AVFrame *frame, int line, int left, uint8_t lru[3][8], int is_565) { @@ -325,11 +325,11 @@ static int dx2_decode_slice_5x5(GetBitContext *gb, AVFrame *frame, int stride = frame->linesize[0]; uint8_t *dst = frame->data[0] + stride * line; - for (y = 0; y < left && get_bits_left(gb) > 16; y++) { + for (y = 0; y < left && bitstream_bits_left(bc) > 16; y++) { for (x = 0; x < width; x++) { - b = decode_sym_565(gb, lru[0], 5); - g = decode_sym_565(gb, lru[1], is_565 ? 6 : 5); - r = decode_sym_565(gb, lru[2], 5); + b = decode_sym_565(bc, lru[0], 5); + g = decode_sym_565(bc, lru[1], is_565 ? 6 : 5); + r = decode_sym_565(bc, lru[2], 5); dst[x * 3 + 0] = (r << 3) | (r >> 2); dst[x * 3 + 1] = is_565 ? (g << 2) | (g >> 4) : (g << 3) | (g >> 2); dst[x * 3 + 2] = (b << 3) | (b >> 2); @@ -355,16 +355,16 @@ static void setup_lru_565(uint8_t lru[3][8]) memcpy(lru[2], def_lru_555, 8 * sizeof(*def_lru)); } -static int dx2_decode_slice_555(GetBitContext *gb, AVFrame *frame, +static int dx2_decode_slice_555(BitstreamContext *bc, AVFrame *frame, int line, int left, uint8_t lru[3][8]) { - return dx2_decode_slice_5x5(gb, frame, line, left, lru, 0); + return dx2_decode_slice_5x5(bc, frame, line, left, lru, 0); } -static int dx2_decode_slice_565(GetBitContext *gb, AVFrame *frame, +static int dx2_decode_slice_565(BitstreamContext *bc, AVFrame *frame, int line, int left, uint8_t lru[3][8]) { - return dx2_decode_slice_5x5(gb, frame, line, left, lru, 1); + return dx2_decode_slice_5x5(bc, frame, line, left, lru, 1); } static int dxtory_decode_v2_565(AVCodecContext *avctx, AVFrame *pic, @@ -383,7 +383,7 @@ static int dxtory_decode_v2_565(AVCodecContext *avctx, AVFrame *pic, fmt); } -static int dx2_decode_slice_rgb(GetBitContext *gb, AVFrame *frame, +static int dx2_decode_slice_rgb(BitstreamContext *bc, AVFrame *frame, int line, int left, uint8_t lru[3][8]) { int x, y; @@ -391,11 +391,11 @@ static int dx2_decode_slice_rgb(GetBitContext *gb, AVFrame *frame, int stride = frame->linesize[0]; uint8_t *dst = frame->data[0] + stride * line; - for (y = 0; y < left && get_bits_left(gb) > 16; y++) { + for (y = 0; y < left && bitstream_bits_left(bc) > 16; y++) { for (x = 0; x < width; x++) { - dst[x * 3 + 0] = decode_sym(gb, lru[0]); - dst[x * 3 + 1] = decode_sym(gb, lru[1]); - dst[x * 3 + 2] = decode_sym(gb, lru[2]); + dst[x * 3 + 0] = decode_sym(bc, lru[0]); + dst[x * 3 + 1] = decode_sym(bc, lru[1]); + dst[x * 3 + 2] = decode_sym(bc, lru[2]); } dst += stride; @@ -421,7 +421,7 @@ static int dxtory_decode_v2_rgb(AVCodecContext *avctx, AVFrame *pic, AV_PIX_FMT_BGR24); } -static int dx2_decode_slice_410(GetBitContext *gb, AVFrame *frame, +static int dx2_decode_slice_410(BitstreamContext *bc, AVFrame *frame, int line, int left, uint8_t lru[3][8]) { @@ -436,13 +436,13 @@ static int dx2_decode_slice_410(GetBitContext *gb, AVFrame *frame, uint8_t *U = frame->data[1] + (ustride >> 2) * line; uint8_t *V = frame->data[2] + (vstride >> 2) * line; - for (y = 0; y < left - 3 && get_bits_left(gb) > 16; y += 4) { + for (y = 0; y < left - 3 && bitstream_bits_left(bc) > 16; y += 4) { for (x = 0; x < width; x += 4) { for (j = 0; j < 4; j++) for (i = 0; i < 4; i++) - Y[x + i + j * ystride] = decode_sym(gb, lru[0]); - U[x >> 2] = decode_sym(gb, lru[1]) ^ 0x80; - V[x >> 2] = decode_sym(gb, lru[2]) ^ 0x80; + Y[x + i + j * ystride] = decode_sym(bc, lru[0]); + U[x >> 2] = decode_sym(bc, lru[1]) ^ 0x80; + V[x >> 2] = decode_sym(bc, lru[2]) ^ 0x80; } Y += ystride << 2; @@ -463,7 +463,7 @@ static int dxtory_decode_v2_410(AVCodecContext *avctx, AVFrame *pic, AV_PIX_FMT_YUV410P); } -static int dx2_decode_slice_420(GetBitContext *gb, AVFrame *frame, +static int dx2_decode_slice_420(BitstreamContext *bc, AVFrame *frame, int line, int left, uint8_t lru[3][8]) { @@ -480,14 +480,14 @@ static int dx2_decode_slice_420(GetBitContext *gb, AVFrame *frame, uint8_t *V = frame->data[2] + (vstride >> 1) * line; - for (y = 0; y < left - 1 && get_bits_left(gb) > 16; y += 2) { + for (y = 0; y < left - 1 && bitstream_bits_left(bc) > 16; y += 2) { for (x = 0; x < width; x += 2) { - Y[x + 0 + 0 * ystride] = decode_sym(gb, lru[0]); - Y[x + 1 + 0 * ystride] = decode_sym(gb, lru[0]); - Y[x + 0 + 1 * ystride] = decode_sym(gb, lru[0]); - Y[x + 1 + 1 * ystride] = decode_sym(gb, lru[0]); - U[x >> 1] = decode_sym(gb, lru[1]) ^ 0x80; - V[x >> 1] = decode_sym(gb, lru[2]) ^ 0x80; + Y[x + 0 + 0 * ystride] = decode_sym(bc, lru[0]); + Y[x + 1 + 0 * ystride] = decode_sym(bc, lru[0]); + Y[x + 0 + 1 * ystride] = decode_sym(bc, lru[0]); + Y[x + 1 + 1 * ystride] = decode_sym(bc, lru[0]); + U[x >> 1] = decode_sym(bc, lru[1]) ^ 0x80; + V[x >> 1] = decode_sym(bc, lru[2]) ^ 0x80; } Y += ystride << 1; @@ -507,7 +507,7 @@ static int dxtory_decode_v2_420(AVCodecContext *avctx, AVFrame *pic, AV_PIX_FMT_YUV420P); } -static int dx2_decode_slice_444(GetBitContext *gb, AVFrame *frame, +static int dx2_decode_slice_444(BitstreamContext *bc, AVFrame *frame, int line, int left, uint8_t lru[3][8]) { @@ -523,11 +523,11 @@ static int dx2_decode_slice_444(GetBitContext *gb, AVFrame *frame, uint8_t *U = frame->data[1] + ustride * line; uint8_t *V = frame->data[2] + vstride * line; - for (y = 0; y < left && get_bits_left(gb) > 16; y++) { + for (y = 0; y < left && bitstream_bits_left(bc) > 16; y++) { for (x = 0; x < width; x++) { - Y[x] = decode_sym(gb, lru[0]); - U[x] = decode_sym(gb, lru[1]) ^ 0x80; - V[x] = decode_sym(gb, lru[2]) ^ 0x80; + Y[x] = decode_sym(bc, lru[0]); + U[x] = decode_sym(bc, lru[1]) ^ 0x80; + V[x] = decode_sym(bc, lru[2]) ^ 0x80; } Y += ystride; From 7ff018c1cb43a5fe5ee2049d325cdd785852067a Mon Sep 17 00:00:00 2001 From: Dave Yeo Date: Fri, 20 Jan 2017 22:19:56 -0800 Subject: [PATCH 0800/3374] OS/2: Try to commit memory above 1GB Signed-off-by: Dave Yeo Signed-off-by: Diego Biurrun --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 9cd4fe6b471c3..53dd809b86e03 100755 --- a/configure +++ b/configure @@ -3964,7 +3964,7 @@ case $target_os in ln_s="cp -f" objformat="aout" add_cppflags -D_GNU_SOURCE - add_ldflags -Zomf -Zbin-files -Zargs-wild -Zmap + add_ldflags -Zomf -Zbin-files -Zargs-wild -Zhigh-mem -Zmap SHFLAGS='$(SUBDIR)$(NAME).def -Zdll -Zomf' LIBSUF="_s.a" SLIBPREF="" From 5c0e2b13eb79b455b15355d64f7993b0f66ea9ec Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 6 Dec 2015 12:45:10 +0100 Subject: [PATCH 0801/3374] swscale-test: const correctness for pointer variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit libswscale/swscale-test.c:369:20: warning: passing argument 2 of ‘sws_scale’ from incompatible pointer type [-Wincompatible-pointer-types] libswscale/swscale.h:207:5: note: expected ‘const uint8_t * const* {aka const unsigned char * const*}’ but argument is of type ‘uint8_t ** {aka unsigned char **}’ --- libswscale/tests/swscale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libswscale/tests/swscale.c b/libswscale/tests/swscale.c index 853a8a7231754..364e2a75eb41c 100644 --- a/libswscale/tests/swscale.c +++ b/libswscale/tests/swscale.c @@ -345,7 +345,7 @@ int main(int argc, char **argv) enum AVPixelFormat srcFormat = AV_PIX_FMT_NONE; enum AVPixelFormat dstFormat = AV_PIX_FMT_NONE; uint8_t *rgb_data = av_malloc(W * H * 4); - uint8_t *rgb_src[4] = { rgb_data, NULL, NULL, NULL }; + const uint8_t *rgb_src[4] = { rgb_data, NULL, NULL, NULL }; int rgb_stride[4] = { 4 * W, 0, 0, 0 }; uint8_t *data = av_malloc(4 * W * H); uint8_t *src[4] = { data, data + W * H, data + W * H * 2, data + W * H * 3 }; From b83aea73404f6f9314e72fe5d6238deaffa12b2c Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 16 Oct 2016 12:33:45 +0200 Subject: [PATCH 0802/3374] des-test: Pass the proper types to av_des_*() functions Fixes a number of incompatible pointer type warnings. --- libavutil/tests/des.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/libavutil/tests/des.c b/libavutil/tests/des.c index 1e7a2fa50a90c..b94f6638a75a0 100644 --- a/libavutil/tests/des.c +++ b/libavutil/tests/des.c @@ -67,19 +67,22 @@ static int run_test(int cbc, int decrypt) } } +union word_byte { + uint64_t word; + uint8_t byte[8]; +}; + int main(void) { AVDES d; int i; - uint64_t key[3]; - uint64_t data; - uint64_t ct; + union word_byte key[3], data, ct; uint64_t roundkeys[16]; srand(av_gettime()); - key[0] = AV_RB64(test_key); - data = AV_RB64(plain); - gen_roundkeys(roundkeys, key[0]); - if (des_encdec(data, roundkeys, 0) != AV_RB64(crypt)) { + key[0].word = AV_RB64(test_key); + data.word = AV_RB64(plain); + gen_roundkeys(roundkeys, key[0].word); + if (des_encdec(data.word, roundkeys, 0) != AV_RB64(crypt)) { printf("Test 1 failed\n"); return 1; } @@ -94,15 +97,15 @@ int main(void) return 1; } for (i = 0; i < 1000; i++) { - key[0] = rand64(); - key[1] = rand64(); - key[2] = rand64(); - data = rand64(); - av_des_init(&d, key, 192, 0); - av_des_crypt(&d, &ct, &data, 1, NULL, 0); - av_des_init(&d, key, 192, 1); - av_des_crypt(&d, &ct, &ct, 1, NULL, 1); - if (ct != data) { + key[0].word = rand64(); + key[1].word = rand64(); + key[2].word = rand64(); + data.word = rand64(); + av_des_init(&d, key[0].byte, 192, 0); + av_des_crypt(&d, ct.byte, data.byte, 1, NULL, 0); + av_des_init(&d, key[0].byte, 192, 1); + av_des_crypt(&d, ct.byte, ct.byte, 1, NULL, 1); + if (ct.word != data.word) { printf("Test 2 failed\n"); return 1; } From 6668bc80b5eeae16c35302cfa6325219f7ce2da7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Mon, 18 Apr 2016 10:56:03 +0200 Subject: [PATCH 0803/3374] mpc: Convert to the new bitstream reader --- libavcodec/mpc7.c | 73 +++++++++++++++++++++------------------- libavcodec/mpc8.c | 83 +++++++++++++++++++++++----------------------- libavformat/mpc8.c | 26 +++++++-------- 3 files changed, 94 insertions(+), 88 deletions(-) diff --git a/libavcodec/mpc7.c b/libavcodec/mpc7.c index 28b51922ecc28..5d749106de345 100644 --- a/libavcodec/mpc7.c +++ b/libavcodec/mpc7.c @@ -28,8 +28,9 @@ #include "libavutil/channel_layout.h" #include "libavutil/internal.h" #include "libavutil/lfg.h" + #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "internal.h" #include "mpegaudiodsp.h" @@ -53,7 +54,7 @@ static av_cold int mpc7_decode_init(AVCodecContext * avctx) { int i, j; MPCContext *c = avctx->priv_data; - GetBitContext gb; + BitstreamContext bc; LOCAL_ALIGNED_16(uint8_t, buf, [16]); static int vlc_initialized = 0; @@ -78,18 +79,18 @@ static av_cold int mpc7_decode_init(AVCodecContext * avctx) ff_mpadsp_init(&c->mpadsp); c->bdsp.bswap_buf((uint32_t *) buf, (const uint32_t *) avctx->extradata, 4); ff_mpc_init(); - init_get_bits(&gb, buf, 128); + bitstream_init(&bc, buf, 128); - c->IS = get_bits1(&gb); - c->MSS = get_bits1(&gb); - c->maxbands = get_bits(&gb, 6); + c->IS = bitstream_read_bit(&bc); + c->MSS = bitstream_read_bit(&bc); + c->maxbands = bitstream_read(&bc, 6); if(c->maxbands >= BANDS){ av_log(avctx, AV_LOG_ERROR, "Too many bands: %i\n", c->maxbands); return -1; } - skip_bits_long(&gb, 88); - c->gapless = get_bits1(&gb); - c->lastframelen = get_bits(&gb, 11); + bitstream_skip(&bc, 88); + c->gapless = bitstream_read_bit(&bc); + c->lastframelen = bitstream_read(&bc, 11); av_log(avctx, AV_LOG_DEBUG, "IS: %d, MSS: %d, TG: %d, LFL: %d, bands: %d\n", c->IS, c->MSS, c->gapless, c->lastframelen, c->maxbands); c->frames_to_skip = 0; @@ -143,7 +144,7 @@ static av_cold int mpc7_decode_init(AVCodecContext * avctx) /** * Fill samples for given subband */ -static inline void idx_to_quant(MPCContext *c, GetBitContext *gb, int idx, int *dst) +static inline void idx_to_quant(MPCContext *c, BitstreamContext *bc, int idx, int *dst) { int i, i1, t; switch(idx){ @@ -153,43 +154,43 @@ static inline void idx_to_quant(MPCContext *c, GetBitContext *gb, int idx, int * } break; case 1: - i1 = get_bits1(gb); + i1 = bitstream_read_bit(bc); for(i = 0; i < SAMPLES_PER_BAND/3; i++){ - t = get_vlc2(gb, quant_vlc[0][i1].table, 9, 2); + t = bitstream_read_vlc(bc, quant_vlc[0][i1].table, 9, 2); *dst++ = mpc7_idx30[t]; *dst++ = mpc7_idx31[t]; *dst++ = mpc7_idx32[t]; } break; case 2: - i1 = get_bits1(gb); + i1 = bitstream_read_bit(bc); for(i = 0; i < SAMPLES_PER_BAND/2; i++){ - t = get_vlc2(gb, quant_vlc[1][i1].table, 9, 2); + t = bitstream_read_vlc(bc, quant_vlc[1][i1].table, 9, 2); *dst++ = mpc7_idx50[t]; *dst++ = mpc7_idx51[t]; } break; case 3: case 4: case 5: case 6: case 7: - i1 = get_bits1(gb); + i1 = bitstream_read_bit(bc); for(i = 0; i < SAMPLES_PER_BAND; i++) - *dst++ = get_vlc2(gb, quant_vlc[idx-1][i1].table, 9, 2) - mpc7_quant_vlc_off[idx-1]; + *dst++ = bitstream_read_vlc(bc, quant_vlc[idx - 1][i1].table, 9, 2) - mpc7_quant_vlc_off[idx - 1]; break; case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: t = (1 << (idx - 2)) - 1; for(i = 0; i < SAMPLES_PER_BAND; i++) - *dst++ = get_bits(gb, idx - 1) - t; + *dst++ = bitstream_read(bc, idx - 1) - t; break; default: // case 0 and -2..-17 return; } } -static int get_scale_idx(GetBitContext *gb, int ref) +static int get_scale_idx(BitstreamContext *bc, int ref) { - int t = get_vlc2(gb, dscf_vlc.table, MPC7_DSCF_BITS, 1) - 7; + int t = bitstream_read_vlc(bc, dscf_vlc.table, MPC7_DSCF_BITS, 1) - 7; if (t == 8) - return get_bits(gb, 6); + return bitstream_read(bc, 6); return av_clip_uintp2(ref + t, 7); } @@ -200,7 +201,7 @@ static int mpc7_decode_frame(AVCodecContext * avctx, void *data, const uint8_t *buf = avpkt->data; int buf_size; MPCContext *c = avctx->priv_data; - GetBitContext gb; + BitstreamContext bc; int i, ch; int mb = -1; Band *bands = c->bands; @@ -237,45 +238,49 @@ static int mpc7_decode_frame(AVCodecContext * avctx, void *data, return AVERROR(ENOMEM); c->bdsp.bswap_buf((uint32_t *) c->bits, (const uint32_t *) buf, buf_size >> 2); - init_get_bits(&gb, c->bits, buf_size * 8); - skip_bits_long(&gb, skip); + bitstream_init(&bc, c->bits, buf_size * 8); + bitstream_skip(&bc, skip); /* read subband indexes */ for(i = 0; i <= c->maxbands; i++){ for(ch = 0; ch < 2; ch++){ int t = 4; - if(i) t = get_vlc2(&gb, hdr_vlc.table, MPC7_HDR_BITS, 1) - 5; - if(t == 4) bands[i].res[ch] = get_bits(&gb, 4); + if (i) + t = bitstream_read_vlc(&bc, hdr_vlc.table, MPC7_HDR_BITS, 1) - 5; + if (t == 4) + bands[i].res[ch] = bitstream_read(&bc, 4); else bands[i].res[ch] = av_clip(bands[i-1].res[ch] + t, 0, 17); } if(bands[i].res[0] || bands[i].res[1]){ mb = i; - if(c->MSS) bands[i].msf = get_bits1(&gb); + if (c->MSS) + bands[i].msf = bitstream_read_bit(&bc); } } /* get scale indexes coding method */ for(i = 0; i <= mb; i++) for(ch = 0; ch < 2; ch++) - if(bands[i].res[ch]) bands[i].scfi[ch] = get_vlc2(&gb, scfi_vlc.table, MPC7_SCFI_BITS, 1); + if (bands[i].res[ch]) + bands[i].scfi[ch] = bitstream_read_vlc(&bc, scfi_vlc.table, MPC7_SCFI_BITS, 1); /* get scale indexes */ for(i = 0; i <= mb; i++){ for(ch = 0; ch < 2; ch++){ if(bands[i].res[ch]){ bands[i].scf_idx[ch][2] = c->oldDSCF[ch][i]; - bands[i].scf_idx[ch][0] = get_scale_idx(&gb, bands[i].scf_idx[ch][2]); + bands[i].scf_idx[ch][0] = get_scale_idx(&bc, bands[i].scf_idx[ch][2]); switch(bands[i].scfi[ch]){ case 0: - bands[i].scf_idx[ch][1] = get_scale_idx(&gb, bands[i].scf_idx[ch][0]); - bands[i].scf_idx[ch][2] = get_scale_idx(&gb, bands[i].scf_idx[ch][1]); + bands[i].scf_idx[ch][1] = get_scale_idx(&bc, bands[i].scf_idx[ch][0]); + bands[i].scf_idx[ch][2] = get_scale_idx(&bc, bands[i].scf_idx[ch][1]); break; case 1: - bands[i].scf_idx[ch][1] = get_scale_idx(&gb, bands[i].scf_idx[ch][0]); + bands[i].scf_idx[ch][1] = get_scale_idx(&bc, bands[i].scf_idx[ch][0]); bands[i].scf_idx[ch][2] = bands[i].scf_idx[ch][1]; break; case 2: bands[i].scf_idx[ch][1] = bands[i].scf_idx[ch][0]; - bands[i].scf_idx[ch][2] = get_scale_idx(&gb, bands[i].scf_idx[ch][1]); + bands[i].scf_idx[ch][2] = get_scale_idx(&bc, bands[i].scf_idx[ch][1]); break; case 3: bands[i].scf_idx[ch][2] = bands[i].scf_idx[ch][1] = bands[i].scf_idx[ch][0]; @@ -290,11 +295,11 @@ static int mpc7_decode_frame(AVCodecContext * avctx, void *data, off = 0; for(i = 0; i < BANDS; i++, off += SAMPLES_PER_BAND) for(ch = 0; ch < 2; ch++) - idx_to_quant(c, &gb, bands[i].res[ch], c->Q[ch] + off); + idx_to_quant(c, &bc, bands[i].res[ch], c->Q[ch] + off); ff_mpc_dequantize_and_synth(c, mb, (int16_t **)frame->extended_data, 2); - bits_used = get_bits_count(&gb); + bits_used = bitstream_tell(&bc); bits_avail = buf_size * 8; if (!last_frame && ((bits_avail < bits_used) || (bits_used + 32 <= bits_avail))) { av_log(avctx, AV_LOG_ERROR, "Error decoding frame: used %i of %i bits\n", bits_used, bits_avail); diff --git a/libavcodec/mpc8.c b/libavcodec/mpc8.c index 84dbb61f7d395..cf621afb12569 100644 --- a/libavcodec/mpc8.c +++ b/libavcodec/mpc8.c @@ -27,8 +27,9 @@ #include "libavutil/channel_layout.h" #include "libavutil/lfg.h" + #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "internal.h" #include "mpegaudiodsp.h" @@ -42,22 +43,22 @@ static VLC q1_vlc, q2_vlc[2], q3_vlc[2], quant_vlc[4][2], q9up_vlc; static const int q3_offsets[2] = { MPC8_Q3_OFFSET, MPC8_Q4_OFFSET }; static const int quant_offsets[6] = { MPC8_Q5_OFFSET, MPC8_Q6_OFFSET, MPC8_Q7_OFFSET, MPC8_Q8_OFFSET }; -static inline int mpc8_dec_base(GetBitContext *gb, int k, int n) +static inline int mpc8_dec_base(BitstreamContext *bc, int k, int n) { int len = mpc8_cnk_len[k-1][n-1] - 1; - int code = len ? get_bits_long(gb, len) : 0; + int code = len ? bitstream_read(bc, len) : 0; if (code >= mpc8_cnk_lost[k-1][n-1]) - code = ((code << 1) | get_bits1(gb)) - mpc8_cnk_lost[k-1][n-1]; + code = ((code << 1) | bitstream_read_bit(bc)) - mpc8_cnk_lost[k - 1][n - 1]; return code; } -static inline int mpc8_dec_enum(GetBitContext *gb, int k, int n) +static inline int mpc8_dec_enum(BitstreamContext *bc, int k, int n) { int bits = 0; const uint32_t * C = mpc8_cnk[k-1]; - int code = mpc8_dec_base(gb, k, n); + int code = mpc8_dec_base(bc, k, n); do { n--; @@ -72,18 +73,18 @@ static inline int mpc8_dec_enum(GetBitContext *gb, int k, int n) return bits; } -static inline int mpc8_get_mod_golomb(GetBitContext *gb, int m) +static inline int mpc8_get_mod_golomb(BitstreamContext *bc, int m) { if(mpc8_cnk_len[0][m] < 1) return 0; - return mpc8_dec_base(gb, 1, m+1); + return mpc8_dec_base(bc, 1, m + 1); } -static int mpc8_get_mask(GetBitContext *gb, int size, int t) +static int mpc8_get_mask(BitstreamContext *bc, int size, int t) { int mask = 0; if(t && t != size) - mask = mpc8_dec_enum(gb, FFMIN(t, size - t), size); + mask = mpc8_dec_enum(bc, FFMIN(t, size - t), size); if((t << 1) > size) mask = ~mask; return mask; @@ -97,7 +98,7 @@ static av_cold int mpc8_decode_init(AVCodecContext * avctx) { int i; MPCContext *c = avctx->priv_data; - GetBitContext gb; + BitstreamContext bc; static int vlc_initialized = 0; int channels; @@ -122,17 +123,17 @@ static av_cold int mpc8_decode_init(AVCodecContext * avctx) ff_mpc_init(); - init_get_bits(&gb, avctx->extradata, 16); + bitstream_init(&bc, avctx->extradata, 16); - skip_bits(&gb, 3);//sample rate - c->maxbands = get_bits(&gb, 5) + 1; - channels = get_bits(&gb, 4) + 1; + bitstream_skip(&bc, 3); // sample rate + c->maxbands = bitstream_read(&bc, 5) + 1; + channels = bitstream_read(&bc, 4) + 1; if (channels > 2) { avpriv_request_sample(avctx, "Multichannel MPC SV8"); return AVERROR_PATCHWELCOME; } - c->MSS = get_bits1(&gb); - c->frames = 1 << (get_bits(&gb, 3) * 2); + c->MSS = bitstream_read_bit(&bc); + c->frames = 1 << (bitstream_read(&bc, 3) * 2); avctx->sample_fmt = AV_SAMPLE_FMT_S16P; avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; @@ -238,7 +239,7 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; MPCContext *c = avctx->priv_data; - GetBitContext gb2, *gb = &gb2; + BitstreamContext bc2, *bc = &bc2; int i, j, k, ch, cnt, res, t; Band *bands = c->bands; int off; @@ -258,13 +259,13 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data, memset(c->Q, 0, sizeof(c->Q)); c->last_bits_used = 0; } - init_get_bits(gb, buf, buf_size * 8); - skip_bits(gb, c->last_bits_used & 7); + bitstream_init(bc, buf, buf_size * 8); + bitstream_skip(bc, c->last_bits_used & 7); if(keyframe) - maxband = mpc8_get_mod_golomb(gb, c->maxbands + 1); + maxband = mpc8_get_mod_golomb(bc, c->maxbands + 1); else{ - maxband = c->last_max_band + get_vlc2(gb, band_vlc.table, MPC8_BANDS_BITS, 2); + maxband = c->last_max_band + bitstream_read_vlc(bc, band_vlc.table, MPC8_BANDS_BITS, 2); if(maxband > 32) maxband -= 33; } if(maxband > c->maxbands + 1) @@ -276,7 +277,7 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data, last[0] = last[1] = 0; for(i = maxband - 1; i >= 0; i--){ for(ch = 0; ch < 2; ch++){ - last[ch] = get_vlc2(gb, res_vlc[last[ch] > 2].table, MPC8_RES_BITS, 2) + last[ch]; + last[ch] = bitstream_read_vlc(bc, res_vlc[last[ch] > 2].table, MPC8_RES_BITS, 2) + last[ch]; if(last[ch] > 15) last[ch] -= 17; bands[i].res[ch] = last[ch]; } @@ -288,8 +289,8 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data, for(i = 0; i < maxband; i++) if(bands[i].res[0] || bands[i].res[1]) cnt++; - t = mpc8_get_mod_golomb(gb, cnt); - mask = mpc8_get_mask(gb, cnt, t); + t = mpc8_get_mod_golomb(bc, cnt); + mask = mpc8_get_mask(bc, cnt, t); for(i = maxband - 1; i >= 0; i--) if(bands[i].res[0] || bands[i].res[1]){ bands[i].msf = mask & 1; @@ -309,7 +310,7 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data, if(bands[i].res[0] || bands[i].res[1]){ cnt = !!bands[i].res[0] + !!bands[i].res[1] - 1; if(cnt >= 0){ - t = get_vlc2(gb, scfi_vlc[cnt].table, scfi_vlc[cnt].bits, 1); + t = bitstream_read_vlc(bc, scfi_vlc[cnt].table, scfi_vlc[cnt].bits, 1); if(bands[i].res[0]) bands[i].scfi[0] = t >> (2 * cnt); if(bands[i].res[1]) bands[i].scfi[1] = t & 3; } @@ -321,21 +322,21 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data, if(!bands[i].res[ch]) continue; if(c->oldDSCF[ch][i]){ - bands[i].scf_idx[ch][0] = get_bits(gb, 7) - 6; + bands[i].scf_idx[ch][0] = bitstream_read(bc, 7) - 6; c->oldDSCF[ch][i] = 0; }else{ - t = get_vlc2(gb, dscf_vlc[1].table, MPC8_DSCF1_BITS, 2); + t = bitstream_read_vlc(bc, dscf_vlc[1].table, MPC8_DSCF1_BITS, 2); if(t == 64) - t += get_bits(gb, 6); + t += bitstream_read(bc, 6); bands[i].scf_idx[ch][0] = ((bands[i].scf_idx[ch][2] + t - 25) & 0x7F) - 6; } for(j = 0; j < 2; j++){ if((bands[i].scfi[ch] << j) & 2) bands[i].scf_idx[ch][j + 1] = bands[i].scf_idx[ch][j]; else{ - t = get_vlc2(gb, dscf_vlc[0].table, MPC8_DSCF0_BITS, 2); + t = bitstream_read_vlc(bc, dscf_vlc[0].table, MPC8_DSCF0_BITS, 2); if(t == 31) - t = 64 + get_bits(gb, 6); + t = 64 + bitstream_read(bc, 6); bands[i].scf_idx[ch][j + 1] = ((bands[i].scf_idx[ch][j] + t - 25) & 0x7F) - 6; } } @@ -354,16 +355,16 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data, break; case 1: for(j = 0; j < SAMPLES_PER_BAND; j += SAMPLES_PER_BAND / 2){ - cnt = get_vlc2(gb, q1_vlc.table, MPC8_Q1_BITS, 2); - t = mpc8_get_mask(gb, 18, cnt); + cnt = bitstream_read_vlc(bc, q1_vlc.table, MPC8_Q1_BITS, 2); + t = mpc8_get_mask(bc, 18, cnt); for(k = 0; k < SAMPLES_PER_BAND / 2; k++, t <<= 1) - c->Q[ch][off + j + k] = (t & 0x20000) ? (get_bits1(gb) << 1) - 1 : 0; + c->Q[ch][off + j + k] = (t & 0x20000) ? (bitstream_read_bit(bc) << 1) - 1 : 0; } break; case 2: cnt = 6;//2*mpc8_thres[res] for(j = 0; j < SAMPLES_PER_BAND; j += 3){ - t = get_vlc2(gb, q2_vlc[cnt > 3].table, MPC8_Q2_BITS, 2); + t = bitstream_read_vlc(bc, q2_vlc[cnt > 3].table, MPC8_Q2_BITS, 2); c->Q[ch][off + j + 0] = mpc8_idx50[t]; c->Q[ch][off + j + 1] = mpc8_idx51[t]; c->Q[ch][off + j + 2] = mpc8_idx52[t]; @@ -373,7 +374,7 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data, case 3: case 4: for(j = 0; j < SAMPLES_PER_BAND; j += 2){ - t = get_vlc2(gb, q3_vlc[res - 3].table, MPC8_Q3_BITS, 2) + q3_offsets[res - 3]; + t = bitstream_read_vlc(bc, q3_vlc[res - 3].table, MPC8_Q3_BITS, 2) + q3_offsets[res - 3]; c->Q[ch][off + j + 1] = t >> 4; c->Q[ch][off + j + 0] = (t & 8) ? (t & 0xF) - 16 : (t & 0xF); } @@ -384,17 +385,17 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data, case 8: cnt = 2 * mpc8_thres[res]; for(j = 0; j < SAMPLES_PER_BAND; j++){ - t = get_vlc2(gb, quant_vlc[res - 5][cnt > mpc8_thres[res]].table, quant_vlc[res - 5][cnt > mpc8_thres[res]].bits, 2) + quant_offsets[res - 5]; + t = bitstream_read_vlc(bc, quant_vlc[res - 5][cnt > mpc8_thres[res]].table, quant_vlc[res - 5][cnt > mpc8_thres[res]].bits, 2) + quant_offsets[res - 5]; c->Q[ch][off + j] = t; cnt = (cnt >> 1) + FFABS(c->Q[ch][off + j]); } break; default: for(j = 0; j < SAMPLES_PER_BAND; j++){ - c->Q[ch][off + j] = get_vlc2(gb, q9up_vlc.table, MPC8_Q9UP_BITS, 2); + c->Q[ch][off + j] = bitstream_read_vlc(bc, q9up_vlc.table, MPC8_Q9UP_BITS, 2); if(res != 9){ c->Q[ch][off + j] <<= res - 9; - c->Q[ch][off + j] |= get_bits(gb, res - 9); + c->Q[ch][off + j] |= bitstream_read(bc, res - 9); } c->Q[ch][off + j] -= (1 << (res - 2)) - 1; } @@ -408,8 +409,8 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data, c->cur_frame++; - c->last_bits_used = get_bits_count(gb); - if(get_bits_left(gb) < 8) // we have only padding left + c->last_bits_used = bitstream_tell(bc); + if (bitstream_bits_left(bc) < 8) // we have only padding left c->last_bits_used = buf_size << 3; if(c->cur_frame >= c->frames) c->cur_frame = 0; diff --git a/libavformat/mpc8.c b/libavformat/mpc8.c index 132e3cd9073de..c4027e5d88a65 100644 --- a/libavformat/mpc8.c +++ b/libavformat/mpc8.c @@ -19,8 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "libavcodec/get_bits.h" -#include "libavcodec/unary_legacy.h" +#include "libavcodec/bitstream.h" +#include "libavcodec/unary.h" #include "apetag.h" #include "avformat.h" @@ -107,17 +107,17 @@ static int mpc8_probe(AVProbeData *p) return 0; } -static inline int64_t gb_get_v(GetBitContext *gb) +static inline int64_t gb_get_v(BitstreamContext *bc) { int64_t v = 0; int bits = 0; - while(get_bits1(gb) && bits < 64-7){ + while (bitstream_read_bit(bc) && bits < 64 - 7) { v <<= 7; - v |= get_bits(gb, 7); + v |= bitstream_read(bc, 7); bits += 7; } v <<= 7; - v |= get_bits(gb, 7); + v |= bitstream_read(bc, 7); return v; } @@ -138,7 +138,7 @@ static void mpc8_parse_seektable(AVFormatContext *s, int64_t off) int64_t size, pos, ppos[2]; uint8_t *buf; int i, t, seekd; - GetBitContext gb; + BitstreamContext bc; if (s->nb_streams == 0) { av_log(s, AV_LOG_ERROR, "No stream added before parsing seek table\n"); @@ -158,21 +158,21 @@ static void mpc8_parse_seektable(AVFormatContext *s, int64_t off) if(!(buf = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE))) return; avio_read(s->pb, buf, size); - init_get_bits(&gb, buf, size * 8); - size = gb_get_v(&gb); + bitstream_init8(&bc, buf, size); + size = gb_get_v(&bc); if(size > UINT_MAX/4 || size > c->samples/1152){ av_log(s, AV_LOG_ERROR, "Seek table is too big\n"); return; } - seekd = get_bits(&gb, 4); + seekd = bitstream_read(&bc, 4); for(i = 0; i < 2; i++){ - pos = gb_get_v(&gb) + c->header_pos; + pos = gb_get_v(&bc) + c->header_pos; ppos[1 - i] = pos; av_add_index_entry(s->streams[0], pos, i, 0, 0, AVINDEX_KEYFRAME); } for(; i < size; i++){ - t = get_unary(&gb, 1, 33) << 12; - t += get_bits(&gb, 12); + t = get_unary(&bc, 1, 33) << 12; + t += bitstream_read(&bc, 12); if(t & 1) t = -(t & ~1); pos = (t >> 1) + ppos[0]*2 - ppos[1]; From e7f24c9ffc6a12a37016914859a74c3127868996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Fri, 15 Apr 2016 10:45:11 +0200 Subject: [PATCH 0804/3374] wavpack: Convert to the new bitstream reader --- libavcodec/wavpack.c | 92 ++++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index b8adb3d4841db..66430b90e36a2 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -23,10 +23,10 @@ #define BITSTREAM_READER_LE #include "avcodec.h" +#include "bitstream.h" #include "bytestream.h" -#include "get_bits.h" #include "internal.h" -#include "unary_legacy.h" +#include "unary.h" /** * @file @@ -109,10 +109,10 @@ typedef struct WavpackFrameContext { int stereo, stereo_in; int joint; uint32_t CRC; - GetBitContext gb; + BitstreamContext bc; int got_extra_bits; uint32_t crc_extra_bits; - GetBitContext gb_extra_bits; + BitstreamContext bc_extra_bits; int data_size; // in bits int samples; int terms; @@ -240,7 +240,7 @@ static av_always_inline int wp_log2(int32_t val) } \ } -static av_always_inline int get_tail(GetBitContext *gb, int k) +static av_always_inline int get_tail(BitstreamContext *bc, int k) { int p, e, res; @@ -248,9 +248,9 @@ static av_always_inline int get_tail(GetBitContext *gb, int k) return 0; p = av_log2(k); e = (1 << (p + 1)) - k - 1; - res = get_bitsz(gb, p); + res = bitstream_read(bc, p); if (res >= e) - res = (res << 1) - e + get_bits1(gb); + res = (res << 1) - e + bitstream_read_bit(bc); return res; } @@ -288,7 +288,7 @@ static void update_error_limit(WavpackFrameContext *ctx) } } -static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, +static int wv_get_value(WavpackFrameContext *ctx, BitstreamContext *bc, int channel, int *last) { int t, t2; @@ -306,13 +306,13 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, return 0; } } else { - t = get_unary_0_33(gb); + t = get_unary_0_33(bc); if (t >= 2) { - if (get_bits_left(gb) < t - 1) + if (bitstream_bits_left(bc) < t - 1) goto error; - t = get_bits(gb, t - 1) | (1 << (t - 1)); + t = bitstream_read(bc, t - 1) | (1 << (t - 1)); } else { - if (get_bits_left(gb) < 0) + if (bitstream_bits_left(bc) < 0) goto error; } ctx->zeroes = t; @@ -329,19 +329,19 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, t = 0; ctx->zero = 0; } else { - t = get_unary_0_33(gb); - if (get_bits_left(gb) < 0) + t = get_unary_0_33(bc); + if (bitstream_bits_left(bc) < 0) goto error; if (t == 16) { - t2 = get_unary_0_33(gb); + t2 = get_unary_0_33(bc); if (t2 < 2) { - if (get_bits_left(gb) < 0) + if (bitstream_bits_left(bc) < 0) goto error; t += t2; } else { - if (get_bits_left(gb) < t2 - 1) + if (bitstream_bits_left(bc) < t2 - 1) goto error; - t += get_bits(gb, t2 - 1) | (1 << (t2 - 1)); + t += bitstream_read(bc, t2 - 1) | (1 << (t2 - 1)); } } @@ -381,15 +381,15 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, INC_MED(2); } if (!c->error_limit) { - ret = base + get_tail(gb, add); - if (get_bits_left(gb) <= 0) + ret = base + get_tail(bc, add); + if (bitstream_bits_left(bc) <= 0) goto error; } else { int mid = (base * 2 + add + 1) >> 1; while (add > c->error_limit) { - if (get_bits_left(gb) <= 0) + if (bitstream_bits_left(bc) <= 0) goto error; - if (get_bits1(gb)) { + if (bitstream_read_bit(bc)) { add -= (mid - base); base = mid; } else @@ -398,7 +398,7 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, } ret = mid; } - sign = get_bits1(gb); + sign = bitstream_read_bit(bc); if (ctx->hybrid_bitrate) c->slow_level += wp_log2(ret) - LEVEL_DECAY(c->slow_level); return sign ? ~ret : ret; @@ -417,8 +417,8 @@ static inline int wv_get_value_integer(WavpackFrameContext *s, uint32_t *crc, S <<= s->extra_bits; if (s->got_extra_bits && - get_bits_left(&s->gb_extra_bits) >= s->extra_bits) { - S |= get_bits(&s->gb_extra_bits, s->extra_bits); + bitstream_bits_left(&s->bc_extra_bits) >= s->extra_bits) { + S |= bitstream_read(&s->bc_extra_bits, s->extra_bits); *crc = *crc * 9 + (S & 0xffff) * 3 + ((unsigned)S >> 16); } } @@ -444,7 +444,7 @@ static float wv_get_value_float(WavpackFrameContext *s, uint32_t *crc, int S) if (s->got_extra_bits) { const int max_bits = 1 + 23 + 8 + 1; - const int left_bits = get_bits_left(&s->gb_extra_bits); + const int left_bits = bitstream_bits_left(&s->bc_extra_bits); if (left_bits + 8 * AV_INPUT_BUFFER_PADDING_SIZE < max_bits) return 0.0; @@ -456,8 +456,8 @@ static float wv_get_value_float(WavpackFrameContext *s, uint32_t *crc, int S) if (sign) S = -S; if (S >= 0x1000000) { - if (s->got_extra_bits && get_bits1(&s->gb_extra_bits)) - S = get_bits(&s->gb_extra_bits, 23); + if (s->got_extra_bits && bitstream_read_bit(&s->bc_extra_bits)) + S = bitstream_read(&s->bc_extra_bits, 23); else S = 0; exp = 255; @@ -473,11 +473,11 @@ static float wv_get_value_float(WavpackFrameContext *s, uint32_t *crc, int S) if ((s->float_flag & WV_FLT_SHIFT_ONES) || (s->got_extra_bits && (s->float_flag & WV_FLT_SHIFT_SAME) && - get_bits1(&s->gb_extra_bits))) { + bitstream_read_bit(&s->bc_extra_bits))) { S |= (1 << shift) - 1; } else if (s->got_extra_bits && (s->float_flag & WV_FLT_SHIFT_SENT)) { - S |= get_bits(&s->gb_extra_bits, shift); + S |= bitstream_read(&s->bc_extra_bits, shift); } } } else { @@ -488,14 +488,14 @@ static float wv_get_value_float(WavpackFrameContext *s, uint32_t *crc, int S) sign = 0; exp = 0; if (s->got_extra_bits && (s->float_flag & WV_FLT_ZERO_SENT)) { - if (get_bits1(&s->gb_extra_bits)) { - S = get_bits(&s->gb_extra_bits, 23); + if (bitstream_read_bit(&s->bc_extra_bits)) { + S = bitstream_read(&s->bc_extra_bits, 23); if (s->float_max_exp >= 25) - exp = get_bits(&s->gb_extra_bits, 8); - sign = get_bits1(&s->gb_extra_bits); + exp = bitstream_read(&s->bc_extra_bits, 8); + sign = bitstream_read_bit(&s->bc_extra_bits); } else { if (s->float_flag & WV_FLT_ZERO_SIGN) - sign = get_bits1(&s->gb_extra_bits); + sign = bitstream_read_bit(&s->bc_extra_bits); } } } @@ -527,7 +527,7 @@ static inline int wv_check_crc(WavpackFrameContext *s, uint32_t crc, return 0; } -static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb, +static inline int wv_unpack_stereo(WavpackFrameContext *s, BitstreamContext *bc, void *dst_l, void *dst_r, const int type) { int i, j, count = 0; @@ -545,10 +545,10 @@ static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb, s->one = s->zero = s->zeroes = 0; do { - L = wv_get_value(s, gb, 0, &last); + L = wv_get_value(s, bc, 0, &last); if (last) break; - R = wv_get_value(s, gb, 1, &last); + R = wv_get_value(s, bc, 1, &last); if (last) break; for (i = 0; i < s->terms; i++) { @@ -645,7 +645,7 @@ static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb, return 0; } -static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb, +static inline int wv_unpack_mono(WavpackFrameContext *s, BitstreamContext *bc, void *dst, const int type) { int i, j, count = 0; @@ -660,7 +660,7 @@ static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb, s->one = s->zero = s->zeroes = 0; do { - T = wv_get_value(s, gb, 0, &last); + T = wv_get_value(s, bc, 0, &last); S = 0; if (last) break; @@ -990,7 +990,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, case WP_ID_DATA: s->sc.offset = bytestream2_tell(&gb); s->sc.size = size * 8; - init_get_bits(&s->gb, gb.buffer, size * 8); + bitstream_init8(&s->bc, gb.buffer, size); s->data_size = size * 8; bytestream2_skip(&gb, size); got_bs = 1; @@ -1004,8 +1004,8 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, } s->extra_sc.offset = bytestream2_tell(&gb); s->extra_sc.size = size * 8; - init_get_bits(&s->gb_extra_bits, gb.buffer, size * 8); - s->crc_extra_bits = get_bits_long(&s->gb_extra_bits, 32); + bitstream_init8(&s->bc_extra_bits, gb.buffer, size); + s->crc_extra_bits = bitstream_read(&s->bc_extra_bits, 32); bytestream2_skip(&gb, size); s->got_extra_bits = 1; break; @@ -1084,7 +1084,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, return AVERROR_INVALIDDATA; } if (s->got_extra_bits && avctx->sample_fmt != AV_SAMPLE_FMT_FLTP) { - const int size = get_bits_left(&s->gb_extra_bits); + const int size = bitstream_bits_left(&s->bc_extra_bits); const int wanted = s->samples * s->extra_bits << s->stereo_in; if (size < wanted) { av_log(avctx, AV_LOG_ERROR, "Too small EXTRABITS\n"); @@ -1134,11 +1134,11 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, wc->ch_offset += 1 + s->stereo; if (s->stereo_in) { - ret = wv_unpack_stereo(s, &s->gb, samples_l, samples_r, avctx->sample_fmt); + ret = wv_unpack_stereo(s, &s->bc, samples_l, samples_r, avctx->sample_fmt); if (ret < 0) return ret; } else { - ret = wv_unpack_mono(s, &s->gb, samples_l, avctx->sample_fmt); + ret = wv_unpack_mono(s, &s->bc, samples_l, avctx->sample_fmt); if (ret < 0) return ret; From b061f298f7f2c227c12dd76a15041ec0a66eeca0 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 21 Jun 2016 14:39:18 +0200 Subject: [PATCH 0805/3374] truemotion2rt: Convert to the new bitstream reader --- libavcodec/truemotion2rt.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libavcodec/truemotion2rt.c b/libavcodec/truemotion2rt.c index ed7fb68899638..e6dbad8fcf134 100644 --- a/libavcodec/truemotion2rt.c +++ b/libavcodec/truemotion2rt.c @@ -29,11 +29,11 @@ #define BITSTREAM_READER_LE #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "internal.h" typedef struct TrueMotion2RTContext { - GetBitContext gb; + BitstreamContext bc; int delta_size; int hscale; } TrueMotion2RTContext; @@ -107,7 +107,7 @@ static int truemotion2rt_decode_frame(AVCodecContext *avctx, void *data, { TrueMotion2RTContext *s = avctx->priv_data; AVFrame * const p = data; - GetBitContext *gb = &s->gb; + BitstreamContext *bc = &s->bc; uint8_t *dst; int x, y, delta_mode; int ret; @@ -116,7 +116,7 @@ static int truemotion2rt_decode_frame(AVCodecContext *avctx, void *data, if (ret < 0) return ret; - ret = init_get_bits8(gb, avpkt->data + ret, avpkt->size - ret); + ret = bitstream_init8(bc, avpkt->data + ret, avpkt->size - ret); if (ret < 0) return ret; @@ -124,13 +124,13 @@ static int truemotion2rt_decode_frame(AVCodecContext *avctx, void *data, if (ret < 0) return ret; - skip_bits(gb, 32); + bitstream_skip(bc, 32); delta_mode = s->delta_size - 2; dst = p->data[0]; for (y = 0; y < avctx->height; y++) { int diff = 0; for (x = 0; x < avctx->width; x += s->hscale) { - diff += delta_tabs[delta_mode][get_bits(gb, s->delta_size)]; + diff += delta_tabs[delta_mode][bitstream_read(bc, s->delta_size)]; dst[x] = av_clip_uint8((y ? dst[x - p->linesize[0]] : 0) + diff); } dst += p->linesize[0]; @@ -156,7 +156,7 @@ static int truemotion2rt_decode_frame(AVCodecContext *avctx, void *data, for (y = 0; y < avctx->height >> 2; y++) { int diff = 0; for (x = 0; x < avctx->width >> 2; x += s->hscale) { - diff += delta_tabs[delta_mode][get_bits(gb, s->delta_size)]; + diff += delta_tabs[delta_mode][bitstream_read(bc, s->delta_size)]; dst[x] = av_clip_uint8((y ? dst[x - p->linesize[1]] : 128) + diff); } dst += p->linesize[1]; @@ -182,7 +182,7 @@ static int truemotion2rt_decode_frame(AVCodecContext *avctx, void *data, for (y = 0; y < avctx->height >> 2; y++) { int diff = 0; for (x = 0; x < avctx->width >> 2; x += s->hscale) { - diff += delta_tabs[delta_mode][get_bits(gb, s->delta_size)]; + diff += delta_tabs[delta_mode][bitstream_read(bc, s->delta_size)]; dst[x] = av_clip_uint8((y ? dst[x - p->linesize[2]] : 128) + diff); } dst += p->linesize[2]; From 2e0e150144d6c8fe641a45141638559fbf4d9642 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 21 Jun 2016 14:35:53 +0200 Subject: [PATCH 0806/3374] magicyuv: Convert to the new bitstream reader --- libavcodec/magicyuv.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/libavcodec/magicyuv.c b/libavcodec/magicyuv.c index 310ead4b06d3e..027143fc875ec 100644 --- a/libavcodec/magicyuv.c +++ b/libavcodec/magicyuv.c @@ -22,14 +22,15 @@ #include #include -#include "../libavutil/pixdesc.h" +#include "libavutil/pixdesc.h" #include "avcodec.h" +#include "bitstream.h" #include "bytestream.h" -#include "get_bits.h" #include "huffyuvdsp.h" #include "internal.h" #include "thread.h" +#include "vlc.h" typedef struct Slice { uint32_t start; @@ -108,7 +109,7 @@ static int magy_decode_slice(AVCodecContext *avctx, void *tdata, int interlaced = s->interlaced; AVFrame *p = s->p; int i, k, x; - GetBitContext gb; + BitstreamContext bc; uint8_t *dst; for (i = 0; i < s->planes; i++) { @@ -119,20 +120,20 @@ static int magy_decode_slice(AVCodecContext *avctx, void *tdata, ptrdiff_t fake_stride = p->linesize[i] * (1 + interlaced); ptrdiff_t stride = p->linesize[i]; int flags, pred; - int ret = init_get_bits8(&gb, s->buf + s->slices[i][j].start, - s->slices[i][j].size); + int ret = bitstream_init8(&bc, s->buf + s->slices[i][j].start, + s->slices[i][j].size); if (ret < 0) return ret; - flags = get_bits(&gb, 8); - pred = get_bits(&gb, 8); + flags = bitstream_read(&bc, 8); + pred = bitstream_read(&bc, 8); dst = p->data[i] + j * sheight * stride; if (flags & 1) { for (k = 0; k < height; k++) { for (x = 0; x < width; x++) - dst[x] = get_bits(&gb, 8); + dst[x] = bitstream_read(&bc, 8); dst += stride; } @@ -140,10 +141,10 @@ static int magy_decode_slice(AVCodecContext *avctx, void *tdata, for (k = 0; k < height; k++) { for (x = 0; x < width; x++) { int pix; - if (get_bits_left(&gb) <= 0) + if (bitstream_bits_left(&bc) <= 0) return AVERROR_INVALIDDATA; - pix = get_vlc2(&gb, s->vlc[i].table, s->vlc[i].bits, 3); + pix = bitstream_read_vlc(&bc, s->vlc[i].table, s->vlc[i].bits, 3); if (pix < 0) return AVERROR_INVALIDDATA; @@ -238,7 +239,7 @@ static int magy_decode_frame(AVCodecContext *avctx, void *data, ThreadFrame frame = { .f = data }; AVFrame *p = data; GetByteContext gbyte; - GetBitContext gbit; + BitstreamContext bc; uint32_t first_offset, offset, next_offset, header_size, slice_width; int width, height, format, version, table_size; int ret, i, j, k; @@ -370,16 +371,16 @@ static int magy_decode_frame(AVCodecContext *avctx, void *data, if (table_size < 2) return AVERROR_INVALIDDATA; - ret = init_get_bits8(&gbit, avpkt->data + bytestream2_tell(&gbyte), table_size); + ret = bitstream_init8(&bc, avpkt->data + bytestream2_tell(&gbyte), table_size); if (ret < 0) return ret; memset(s->len, 0, sizeof(s->len)); j = i = 0; - while (get_bits_left(&gbit) >= 8) { - int b = get_bits(&gbit, 4); - int x = get_bits(&gbit, 4); - int l = get_bitsz(&gbit, b) + 1; + while (bitstream_bits_left(&bc) >= 8) { + int b = bitstream_read(&bc, 4); + int x = bitstream_read(&bc, 4); + int l = bitstream_read(&bc, b) + 1; for (k = 0; k < l; k++) if (j + k < 256) From 381a4e31a6b801a046e38b0e2b08fb61499157a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Wed, 13 Apr 2016 21:00:34 +0200 Subject: [PATCH 0807/3374] tak: Convert to the new bitstream reader --- libavcodec/tak.c | 49 +++++++------ libavcodec/tak.h | 10 +-- libavcodec/tak_parser.c | 15 ++-- libavcodec/takdec.c | 158 ++++++++++++++++++++-------------------- libavformat/takdec.c | 13 ++-- 5 files changed, 125 insertions(+), 120 deletions(-) diff --git a/libavcodec/tak.c b/libavcodec/tak.c index bd82c3d1939e8..c90e55ad6ab88 100644 --- a/libavcodec/tak.c +++ b/libavcodec/tak.c @@ -24,6 +24,7 @@ #include "libavutil/intreadwrite.h" #define BITSTREAM_READER_LE +#include "bitstream.h" #include "tak.h" static const uint16_t frame_duration_type_quants[] = { @@ -85,30 +86,30 @@ int ff_tak_check_crc(const uint8_t *buf, unsigned int buf_size) return 0; } -void avpriv_tak_parse_streaminfo(GetBitContext *gb, TAKStreamInfo *s) +void avpriv_tak_parse_streaminfo(BitstreamContext *bc, TAKStreamInfo *s) { uint64_t channel_mask = 0; int frame_type, i; - s->codec = get_bits(gb, TAK_ENCODER_CODEC_BITS); - skip_bits(gb, TAK_ENCODER_PROFILE_BITS); + s->codec = bitstream_read(bc, TAK_ENCODER_CODEC_BITS); + bitstream_skip(bc, TAK_ENCODER_PROFILE_BITS); - frame_type = get_bits(gb, TAK_SIZE_FRAME_DURATION_BITS); - s->samples = get_bits64(gb, TAK_SIZE_SAMPLES_NUM_BITS); + frame_type = bitstream_read(bc, TAK_SIZE_FRAME_DURATION_BITS); + s->samples = bitstream_read_63(bc, TAK_SIZE_SAMPLES_NUM_BITS); - s->data_type = get_bits(gb, TAK_FORMAT_DATA_TYPE_BITS); - s->sample_rate = get_bits(gb, TAK_FORMAT_SAMPLE_RATE_BITS) + + s->data_type = bitstream_read(bc, TAK_FORMAT_DATA_TYPE_BITS); + s->sample_rate = bitstream_read(bc, TAK_FORMAT_SAMPLE_RATE_BITS) + TAK_SAMPLE_RATE_MIN; - s->bps = get_bits(gb, TAK_FORMAT_BPS_BITS) + + s->bps = bitstream_read(bc, TAK_FORMAT_BPS_BITS) + TAK_BPS_MIN; - s->channels = get_bits(gb, TAK_FORMAT_CHANNEL_BITS) + + s->channels = bitstream_read(bc, TAK_FORMAT_CHANNEL_BITS) + TAK_CHANNELS_MIN; - if (get_bits1(gb)) { - skip_bits(gb, TAK_FORMAT_VALID_BITS); - if (get_bits1(gb)) { + if (bitstream_read_bit(bc)) { + bitstream_skip(bc, TAK_FORMAT_VALID_BITS); + if (bitstream_read_bit(bc)) { for (i = 0; i < s->channels; i++) { - int value = get_bits(gb, TAK_FORMAT_CH_LAYOUT_BITS); + int value = bitstream_read(bc, TAK_FORMAT_CH_LAYOUT_BITS); if (value > 0 && value <= 18) channel_mask |= 1 << (value - 1); @@ -120,33 +121,33 @@ void avpriv_tak_parse_streaminfo(GetBitContext *gb, TAKStreamInfo *s) s->frame_samples = tak_get_nb_samples(s->sample_rate, frame_type); } -int ff_tak_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb, +int ff_tak_decode_frame_header(AVCodecContext *avctx, BitstreamContext *bc, TAKStreamInfo *ti, int log_level_offset) { - if (get_bits(gb, TAK_FRAME_HEADER_SYNC_ID_BITS) != TAK_FRAME_HEADER_SYNC_ID) { + if (bitstream_read(bc, TAK_FRAME_HEADER_SYNC_ID_BITS) != TAK_FRAME_HEADER_SYNC_ID) { av_log(avctx, AV_LOG_ERROR + log_level_offset, "missing sync id\n"); return AVERROR_INVALIDDATA; } - ti->flags = get_bits(gb, TAK_FRAME_HEADER_FLAGS_BITS); - ti->frame_num = get_bits(gb, TAK_FRAME_HEADER_NO_BITS); + ti->flags = bitstream_read(bc, TAK_FRAME_HEADER_FLAGS_BITS); + ti->frame_num = bitstream_read(bc, TAK_FRAME_HEADER_NO_BITS); if (ti->flags & TAK_FRAME_FLAG_IS_LAST) { - ti->last_frame_samples = get_bits(gb, TAK_FRAME_HEADER_SAMPLE_COUNT_BITS) + 1; - skip_bits(gb, 2); + ti->last_frame_samples = bitstream_read(bc, TAK_FRAME_HEADER_SAMPLE_COUNT_BITS) + 1; + bitstream_skip(bc, 2); } else { ti->last_frame_samples = 0; } if (ti->flags & TAK_FRAME_FLAG_HAS_INFO) { - avpriv_tak_parse_streaminfo(gb, ti); + avpriv_tak_parse_streaminfo(bc, ti); - if (get_bits(gb, 6)) - skip_bits(gb, 25); - align_get_bits(gb); + if (bitstream_read(bc, 6)) + bitstream_skip(bc, 25); + bitstream_align(bc); } - skip_bits(gb, 24); + bitstream_skip(bc, 24); return 0; } diff --git a/libavcodec/tak.h b/libavcodec/tak.h index 19b1c47521b65..c752062521830 100644 --- a/libavcodec/tak.h +++ b/libavcodec/tak.h @@ -30,7 +30,7 @@ #include #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #define TAK_FORMAT_DATA_TYPE_BITS 3 #define TAK_FORMAT_SAMPLE_RATE_BITS 18 @@ -145,21 +145,21 @@ int ff_tak_check_crc(const uint8_t *buf, unsigned int buf_size); /** * Parse the Streaminfo metadata block. - * @param[in] gb pointer to GetBitContext + * @param[in] bc pointer to BitstreamContext * @param[out] s storage for parsed information */ -void avpriv_tak_parse_streaminfo(GetBitContext *gb, TAKStreamInfo *s); +void avpriv_tak_parse_streaminfo(BitstreamContext *bc, TAKStreamInfo *s); /** * Validate and decode a frame header. * @param avctx AVCodecContext to use as av_log() context - * @param[in] gb GetBitContext from which to read frame header + * @param[in] bc BitstreamContext from which to read frame header * @param[out] s frame information * @param log_level_offset log level offset, can be used to silence * error messages. * @return non-zero on error, 0 if OK */ -int ff_tak_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb, +int ff_tak_decode_frame_header(AVCodecContext *avctx, BitstreamContext *bc, TAKStreamInfo *s, int log_level_offset); #endif /* AVCODEC_TAK_H */ diff --git a/libavcodec/tak_parser.c b/libavcodec/tak_parser.c index 9ac1deb9f70a3..82fb7e8c6bfd5 100644 --- a/libavcodec/tak_parser.c +++ b/libavcodec/tak_parser.c @@ -25,6 +25,7 @@ **/ #define BITSTREAM_READER_LE +#include "bitstream.h" #include "parser.h" #include "tak.h" @@ -47,14 +48,14 @@ static int tak_parse(AVCodecParserContext *s, AVCodecContext *avctx, TAKParseContext *t = s->priv_data; ParseContext *pc = &t->pc; int next = END_NOT_FOUND; - GetBitContext gb; + BitstreamContext bc; int consumed = 0; int needed = buf_size ? TAK_MAX_FRAME_HEADER_BYTES : 8; if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { TAKStreamInfo ti; - init_get_bits(&gb, buf, buf_size); - if (!ff_tak_decode_frame_header(avctx, &gb, &ti, 127)) + bitstream_init(&bc, buf, buf_size); + if (!ff_tak_decode_frame_header(avctx, &bc, &ti, 127)) s->duration = t->ti.last_frame_samples ? t->ti.last_frame_samples : t->ti.frame_samples; *poutbuf = buf; @@ -79,14 +80,14 @@ static int tak_parse(AVCodecParserContext *s, AVCodecContext *avctx, pc->buffer[t->index + 1] == 0xA0) { TAKStreamInfo ti; - init_get_bits(&gb, pc->buffer + t->index, - 8 * (pc->index - t->index)); - if (!ff_tak_decode_frame_header(avctx, &gb, + bitstream_init8(&bc, pc->buffer + t->index, + pc->index - t->index); + if (!ff_tak_decode_frame_header(avctx, &bc, pc->frame_start_found ? &ti : &t->ti, 127) && !ff_tak_check_crc(pc->buffer + t->index, - get_bits_count(&gb) / 8)) { + bitstream_tell(&bc) / 8)) { if (!pc->frame_start_found) { pc->frame_start_found = 1; s->duration = t->ti.last_frame_samples ? diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c index e7320c66d4eb2..11c04f4ff43f1 100644 --- a/libavcodec/takdec.c +++ b/libavcodec/takdec.c @@ -31,8 +31,9 @@ #define BITSTREAM_READER_LE #include "audiodsp.h" #include "avcodec.h" +#include "bitstream.h" #include "internal.h" -#include "unary_legacy.h" +#include "unary.h" #include "tak.h" #define MAX_SUBFRAMES 8 // max number of subframes per channel @@ -49,7 +50,7 @@ typedef struct TAKDecContext { AVCodecContext *avctx; // parent AVCodecContext AudioDSPContext adsp; TAKStreamInfo ti; - GetBitContext gb; // bitstream reader initialized to start at the current frame + BitstreamContext bc; // bitstream reader initialized to start at the current frame int uval; int nb_samples; // number of samples in the current frame @@ -238,7 +239,7 @@ static void decode_lpc(int32_t *coeffs, int mode, int length) } } -static int decode_segment(GetBitContext *gb, int mode, int32_t *decoded, +static int decode_segment(BitstreamContext *bc, int mode, int32_t *decoded, int len) { struct CParam code; @@ -254,20 +255,20 @@ static int decode_segment(GetBitContext *gb, int mode, int32_t *decoded, code = xcodes[mode - 1]; for (i = 0; i < len; i++) { - int x = get_bits_long(gb, code.init); - if (x >= code.escape && get_bits1(gb)) { + int x = bitstream_read(bc, code.init); + if (x >= code.escape && bitstream_read_bit(bc)) { x |= 1 << code.init; if (x >= code.aescape) { - int scale = get_unary(gb, 1, 9); + int scale = get_unary(bc, 1, 9); if (scale == 9) { - int scale_bits = get_bits(gb, 3); + int scale_bits = bitstream_read(bc, 3); if (scale_bits > 0) { if (scale_bits == 7) { - scale_bits += get_bits(gb, 5); + scale_bits += bitstream_read(bc, 5); if (scale_bits > 29) return AVERROR_INVALIDDATA; } - scale = get_bits_long(gb, scale_bits) + 1; + scale = bitstream_read(bc, scale_bits) + 1; x += code.scale * scale; } x += code.bias; @@ -284,13 +285,13 @@ static int decode_segment(GetBitContext *gb, int mode, int32_t *decoded, static int decode_residues(TAKDecContext *s, int32_t *decoded, int length) { - GetBitContext *gb = &s->gb; + BitstreamContext *bc = &s->bc; int i, mode, ret; if (length > s->nb_samples) return AVERROR_INVALIDDATA; - if (get_bits1(gb)) { + if (bitstream_read_bit(bc)) { int wlength, rval; int coding_mode[128]; @@ -306,20 +307,21 @@ static int decode_residues(TAKDecContext *s, int32_t *decoded, int length) if (wlength <= 1 || wlength > 128) return AVERROR_INVALIDDATA; - coding_mode[0] = mode = get_bits(gb, 6); + coding_mode[0] = + mode = bitstream_read(bc, 6); for (i = 1; i < wlength; i++) { - int c = get_unary(gb, 1, 6); + int c = get_unary(bc, 1, 6); switch (c) { case 6: - mode = get_bits(gb, 6); + mode = bitstream_read(bc, 6); break; case 5: case 4: case 3: { /* mode += sign ? (1 - c) : (c - 1) */ - int sign = get_bits1(gb); + int sign = bitstream_read_bit(bc); mode += (-sign ^ (c - 1)) + sign; break; } @@ -349,23 +351,23 @@ static int decode_residues(TAKDecContext *s, int32_t *decoded, int length) break; } while (coding_mode[i] == mode); - if ((ret = decode_segment(gb, mode, decoded, len)) < 0) + if ((ret = decode_segment(bc, mode, decoded, len)) < 0) return ret; decoded += len; } } else { - mode = get_bits(gb, 6); - if ((ret = decode_segment(gb, mode, decoded, length)) < 0) + mode = bitstream_read(bc, 6); + if ((ret = decode_segment(bc, mode, decoded, length)) < 0) return ret; } return 0; } -static int get_bits_esc4(GetBitContext *gb) +static int bits_esc4(BitstreamContext *bc) { - if (get_bits1(gb)) - return get_bits(gb, 4) + 1; + if (bitstream_read_bit(bc)) + return bitstream_read(bc, 4) + 1; else return 0; } @@ -373,23 +375,23 @@ static int get_bits_esc4(GetBitContext *gb) static void decode_filter_coeffs(TAKDecContext *s, int filter_order, int size, int filter_quant, int16_t *filter) { - GetBitContext *gb = &s->gb; + BitstreamContext *bc = &s->bc; int i, j, a, b; int filter_tmp[MAX_PREDICTORS]; int16_t predictors[MAX_PREDICTORS]; - predictors[0] = get_sbits(gb, 10); - predictors[1] = get_sbits(gb, 10); - predictors[2] = get_sbits(gb, size) << (10 - size); - predictors[3] = get_sbits(gb, size) << (10 - size); + predictors[0] = bitstream_read_signed(bc, 10); + predictors[1] = bitstream_read_signed(bc, 10); + predictors[2] = bitstream_read_signed(bc, size) << (10 - size); + predictors[3] = bitstream_read_signed(bc, size) << (10 - size); if (filter_order > 4) { int av_uninit(code_size); - int code_size_base = size - get_bits1(gb); + int code_size_base = size - bitstream_read_bit(bc); for (i = 4; i < filter_order; i++) { if (!(i & 3)) - code_size = code_size_base - get_bits(gb, 2); - predictors[i] = get_sbits(gb, code_size) << (10 - size); + code_size = code_size_base - bitstream_read(bc, 2); + predictors[i] = bitstream_read_signed(bc, code_size) << (10 - size); } } @@ -421,18 +423,18 @@ static int decode_subframe(TAKDecContext *s, int32_t *decoded, int subframe_size, int prev_subframe_size) { LOCAL_ALIGNED_16(int16_t, filter, [MAX_PREDICTORS]); - GetBitContext *gb = &s->gb; + BitstreamContext *bc = &s->bc; int i, ret; int dshift, size, filter_quant, filter_order; memset(filter, 0, MAX_PREDICTORS * sizeof(*filter)); - if (!get_bits1(gb)) + if (!bitstream_read_bit(bc)) return decode_residues(s, decoded, subframe_size); - filter_order = predictor_sizes[get_bits(gb, 4)]; + filter_order = predictor_sizes[bitstream_read(bc, 4)]; - if (prev_subframe_size > 0 && get_bits1(gb)) { + if (prev_subframe_size > 0 && bitstream_read_bit(bc)) { if (filter_order > prev_subframe_size) return AVERROR_INVALIDDATA; @@ -447,7 +449,7 @@ static int decode_subframe(TAKDecContext *s, int32_t *decoded, if (filter_order > subframe_size) return AVERROR_INVALIDDATA; - lpc_mode = get_bits(gb, 2); + lpc_mode = bitstream_read(bc, 2); if (lpc_mode > 2) return AVERROR_INVALIDDATA; @@ -458,12 +460,12 @@ static int decode_subframe(TAKDecContext *s, int32_t *decoded, decode_lpc(decoded, lpc_mode, filter_order); } - dshift = get_bits_esc4(gb); - size = get_bits1(gb) + 6; + dshift = bits_esc4(bc); + size = bitstream_read_bit(bc) + 6; filter_quant = 10; - if (get_bits1(gb)) { - filter_quant -= get_bits(gb, 3) + 1; + if (bitstream_read_bit(bc)) { + filter_quant -= bitstream_read(bc, 3) + 1; if (filter_quant < 3) return AVERROR_INVALIDDATA; } @@ -502,35 +504,35 @@ static int decode_subframe(TAKDecContext *s, int32_t *decoded, static int decode_channel(TAKDecContext *s, int chan) { AVCodecContext *avctx = s->avctx; - GetBitContext *gb = &s->gb; + BitstreamContext *bc = &s->bc; int32_t *decoded = s->decoded[chan]; int left = s->nb_samples - 1; int i, prev, ret, nb_subframes; int subframe_len[MAX_SUBFRAMES]; - s->sample_shift[chan] = get_bits_esc4(gb); + s->sample_shift[chan] = bits_esc4(bc); if (s->sample_shift[chan] >= avctx->bits_per_coded_sample) return AVERROR_INVALIDDATA; /* NOTE: TAK 2.2.0 appears to set the sample value to 0 if * bits_per_coded_sample - sample_shift is 1, but this produces - * non-bit-exact output. Reading the 1 bit using get_sbits() instead - * of skipping it produces bit-exact output. This has been reported - * to the TAK author. */ - *decoded++ = get_sbits(gb, - avctx->bits_per_coded_sample - - s->sample_shift[chan]); - s->lpc_mode[chan] = get_bits(gb, 2); - nb_subframes = get_bits(gb, 3) + 1; + * non-bit-exact output. Reading the 1 bit using bitstream_read_signed() + * instead of skipping it produces bit-exact output. This has been + * reported to the TAK author. */ + *decoded++ = bitstream_read_signed(bc, + avctx->bits_per_coded_sample - + s->sample_shift[chan]); + s->lpc_mode[chan] = bitstream_read(bc, 2); + nb_subframes = bitstream_read(bc, 3) + 1; i = 0; if (nb_subframes > 1) { - if (get_bits_left(gb) < (nb_subframes - 1) * 6) + if (bitstream_bits_left(bc) < (nb_subframes - 1) * 6) return AVERROR_INVALIDDATA; prev = 0; for (; i < nb_subframes - 1; i++) { - int subframe_end = get_bits(gb, 6) * s->subframe_scale; + int subframe_end = bitstream_read(bc, 6) * s->subframe_scale; if (subframe_end <= prev) return AVERROR_INVALIDDATA; subframe_len[i] = subframe_end - prev; @@ -556,7 +558,7 @@ static int decode_channel(TAKDecContext *s, int chan) static int decorrelate(TAKDecContext *s, int c1, int c2, int length) { - GetBitContext *gb = &s->gb; + BitstreamContext *bc = &s->bc; int32_t *p1 = s->decoded[c1] + 1; int32_t *p2 = s->decoded[c2] + 1; int i; @@ -589,8 +591,8 @@ static int decorrelate(TAKDecContext *s, int c1, int c2, int length) case 4: /* side/left with scale factor */ FFSWAP(int32_t*, p1, p2); case 5: /* side/right with scale factor */ - dshift = get_bits_esc4(gb); - dfactor = get_sbits(gb, 10); + dshift = bits_esc4(bc); + dfactor = bitstream_read_signed(bc, 10); for (i = 0; i < length; i++) { int32_t a = p1[i]; int32_t b = p2[i]; @@ -610,15 +612,15 @@ static int decorrelate(TAKDecContext *s, int c1, int c2, int length) if (length < 256) return AVERROR_INVALIDDATA; - dshift = get_bits_esc4(gb); - filter_order = 8 << get_bits1(gb); - dval1 = get_bits1(gb); - dval2 = get_bits1(gb); + dshift = bits_esc4(bc); + filter_order = 8 << bitstream_read_bit(bc); + dval1 = bitstream_read_bit(bc); + dval2 = bitstream_read_bit(bc); for (i = 0; i < filter_order; i++) { if (!(i & 3)) - code_size = 14 - get_bits(gb, 3); - filter[i] = get_sbits(gb, code_size); + code_size = 14 - bitstream_read(bc, 3); + filter[i] = bitstream_read_signed(bc, code_size); } order_half = filter_order / 2; @@ -675,15 +677,15 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, { TAKDecContext *s = avctx->priv_data; AVFrame *frame = data; - GetBitContext *gb = &s->gb; + BitstreamContext *bc = &s->bc; int chan, i, ret, hsize; if (pkt->size < TAK_MIN_FRAME_HEADER_BYTES) return AVERROR_INVALIDDATA; - init_get_bits(gb, pkt->data, pkt->size * 8); + bitstream_init8(bc, pkt->data, pkt->size); - if ((ret = ff_tak_decode_frame_header(avctx, gb, &s->ti, 0)) < 0) + if ((ret = ff_tak_decode_frame_header(avctx, bc, &s->ti, 0)) < 0) return ret; if (s->ti.flags & TAK_FRAME_FLAG_HAS_METADATA) { @@ -691,7 +693,7 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_PATCHWELCOME; } - hsize = get_bits_count(gb) / 8; + hsize = bitstream_tell(bc) / 8; if (avctx->err_recognition & AV_EF_CRCCHECK) { if (ff_tak_check_crc(pkt->data, hsize)) { av_log(avctx, AV_LOG_ERROR, "CRC error\n"); @@ -769,7 +771,7 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, for (chan = 0; chan < avctx->channels; chan++) { int32_t *decoded = s->decoded[chan]; for (i = 0; i < s->nb_samples; i++) - decoded[i] = get_sbits(gb, avctx->bits_per_coded_sample); + decoded[i] = bitstream_read_signed(bc, avctx->bits_per_coded_sample); } } else { if (s->ti.codec == TAK_CODEC_MONO_STEREO) { @@ -778,25 +780,25 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, return ret; if (avctx->channels == 2) { - if (get_bits1(gb)) { + if (bitstream_read_bit(bc)) { // some kind of subframe length, but it seems to be unused - skip_bits(gb, 6); + bitstream_skip(bc, 6); } - s->dmode = get_bits(gb, 3); + s->dmode = bitstream_read(bc, 3); if (ret = decorrelate(s, 0, 1, s->nb_samples - 1)) return ret; } } else if (s->ti.codec == TAK_CODEC_MULTICHANNEL) { - if (get_bits1(gb)) { + if (bitstream_read_bit(bc)) { int ch_mask = 0; - chan = get_bits(gb, 4) + 1; + chan = bitstream_read(bc, 4) + 1; if (chan > avctx->channels) return AVERROR_INVALIDDATA; for (i = 0; i < chan; i++) { - int nbit = get_bits(gb, 4); + int nbit = bitstream_read(bc, 4); if (nbit >= avctx->channels) return AVERROR_INVALIDDATA; @@ -804,10 +806,10 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, if (ch_mask & 1 << nbit) return AVERROR_INVALIDDATA; - s->mcdparams[i].present = get_bits1(gb); + s->mcdparams[i].present = bitstream_read_bit(bc); if (s->mcdparams[i].present) { - s->mcdparams[i].index = get_bits(gb, 2); - s->mcdparams[i].chan2 = get_bits(gb, 4); + s->mcdparams[i].index = bitstream_read(bc, 2); + s->mcdparams[i].chan2 = bitstream_read(bc, 4); if (s->mcdparams[i].chan2 >= avctx->channels) { av_log(avctx, AV_LOG_ERROR, "invalid channel 2 (%d) for %d channel(s)\n", @@ -867,16 +869,16 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, } } - align_get_bits(gb); - skip_bits(gb, 24); - if (get_bits_left(gb) < 0) + bitstream_align(bc); + bitstream_skip(bc, 24); + if (bitstream_bits_left(bc) < 0) av_log(avctx, AV_LOG_DEBUG, "overread\n"); - else if (get_bits_left(gb) > 0) + else if (bitstream_bits_left(bc) > 0) av_log(avctx, AV_LOG_DEBUG, "underread\n"); if (avctx->err_recognition & AV_EF_CRCCHECK) { if (ff_tak_check_crc(pkt->data + hsize, - get_bits_count(gb) / 8 - hsize)) { + bitstream_tell(bc) / 8 - hsize)) { av_log(avctx, AV_LOG_ERROR, "CRC error\n"); if (avctx->err_recognition & AV_EF_EXPLODE) return AVERROR_INVALIDDATA; diff --git a/libavformat/takdec.c b/libavformat/takdec.c index 19e0e69a5ee3c..4b3037d9ca8e3 100644 --- a/libavformat/takdec.c +++ b/libavformat/takdec.c @@ -20,6 +20,7 @@ */ #define BITSTREAM_READER_LE +#include "libavcodec/bitstream.h" #include "libavcodec/tak.h" #include "apetag.h" @@ -43,7 +44,7 @@ static int tak_read_header(AVFormatContext *s) { TAKDemuxContext *tc = s->priv_data; AVIOContext *pb = s->pb; - GetBitContext gb; + BitstreamContext bc; AVStream *st; uint8_t *buffer = NULL; int ret; @@ -82,7 +83,7 @@ static int tak_read_header(AVFormatContext *s) return AVERROR(EIO); } - init_get_bits(&gb, buffer, size * 8); + bitstream_init8(&bc, buffer, size); break; case TAK_METADATA_MD5: { uint8_t md5[16]; @@ -118,7 +119,7 @@ static int tak_read_header(AVFormatContext *s) if (type == TAK_METADATA_STREAMINFO) { TAKStreamInfo ti; - avpriv_tak_parse_streaminfo(&gb, &ti); + avpriv_tak_parse_streaminfo(&bc, &ti); if (ti.samples > 0) st->duration = ti.samples; st->codecpar->bits_per_coded_sample = ti.bps; @@ -135,12 +136,12 @@ static int tak_read_header(AVFormatContext *s) if (size != 11) return AVERROR_INVALIDDATA; tc->mlast_frame = 1; - tc->data_end = get_bits64(&gb, TAK_LAST_FRAME_POS_BITS) + - get_bits(&gb, TAK_LAST_FRAME_SIZE_BITS); + tc->data_end = bitstream_read_63(&bc, TAK_LAST_FRAME_POS_BITS) + + bitstream_read(&bc, TAK_LAST_FRAME_SIZE_BITS); av_freep(&buffer); } else if (type == TAK_METADATA_ENCODER) { av_log(s, AV_LOG_VERBOSE, "encoder version: %0X\n", - get_bits_long(&gb, TAK_ENCODER_VERSION_BITS)); + bitstream_read(&bc, TAK_ENCODER_VERSION_BITS)); av_freep(&buffer); } } From bf38959a30ecba4e4ee95d4f2a80ba7ece4f34be Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 15 Dec 2016 12:20:06 +0100 Subject: [PATCH 0808/3374] configure: Move optflags checks to a more sensible place --- configure | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/configure b/configure index 53dd809b86e03..e79c6225fbf51 100755 --- a/configure +++ b/configure @@ -4926,6 +4926,9 @@ check_optflags(){ enabled lto && check_ldflags "$@" } +check_optflags $optflags +check_optflags -fno-math-errno +check_optflags -fno-signed-zeros if enabled lto; then test "$cc_type" != "$ld_type" && die "LTO requires same compiler and linker" @@ -4933,10 +4936,6 @@ if enabled lto; then check_ldflags -flto $cpuflags fi -check_optflags $optflags -check_optflags -fno-math-errno -check_optflags -fno-signed-zeros - if enabled icc; then # Just warnings, no remarks check_cflags -w1 From 9bf262f4c6e14f43f291cdb745ed372884ee2a7f Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 19 Jan 2017 11:36:52 +0100 Subject: [PATCH 0809/3374] configure: Use proper compiler-specific speed flags for hostcc --- configure | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure b/configure index e79c6225fbf51..f1867532a03ba 100755 --- a/configure +++ b/configure @@ -3372,6 +3372,7 @@ set_ccvars CC probe_cc hostcc "$host_cc" host_cflags_filter=$_flags_filter +host_cflags_speed=$_cflags_speed add_host_cflags $_flags $_cflags set_ccvars HOSTCC @@ -3759,7 +3760,7 @@ EOF add_host_cppflags -D_ISOC99_SOURCE check_host_cflags -std=c99 check_host_cflags -Wall -check_host_cflags -O3 +check_host_cflags $host_cflags_speed check_64bit(){ arch32=$1 From 562ef82d6a7f96f6b9da1219a5aaf7d9d7056f1b Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Thu, 26 Jan 2017 00:06:50 +0100 Subject: [PATCH 0810/3374] fifo: Return the correct AVERROR value --- libavutil/fifo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavutil/fifo.c b/libavutil/fifo.c index a42899c2b302a..2eb931e166994 100644 --- a/libavutil/fifo.c +++ b/libavutil/fifo.c @@ -68,7 +68,7 @@ int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size) AVFifoBuffer *f2 = av_fifo_alloc(new_size); if (!f2) - return -1; + return AVERROR(ENOMEM); av_fifo_generic_read(f, f2->buffer, len, NULL); f2->wptr += len; f2->wndx += len; From f96d07f4ec4193fb5293d7ac8f1324aac3c3ea07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 25 Jan 2017 15:11:23 +0200 Subject: [PATCH 0811/3374] configure: Add quotes around a variable which might be empty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we only have a target compiler but no host compiler, the $type variable will be empty once. (Currently we fail to do a cross build if no host compiler is available due to using the host compiler for processing option lists though. But despite that, this comparison in configure needs quotes.) Signed-off-by: Martin Storsjö --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index f1867532a03ba..7570c0a38883b 100755 --- a/configure +++ b/configure @@ -5033,7 +5033,7 @@ fi for pfx in "" host_; do varname=${pfx%_}cc_type eval "type=\$$varname" - if [ $type = "msvc" ]; then + if [ "$type" = "msvc" ]; then check_${pfx}cc < Date: Wed, 25 Jan 2017 18:40:51 +0100 Subject: [PATCH 0812/3374] build: Detect blocks C language extension and add it as VDA dependency Newer versions of OS X use the blocks extension in VDA-related headers. Some compilers, like current gcc, do not support the blocks extension and fail to compile code using those headers. --- configure | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 7570c0a38883b..04b19211cf341 100755 --- a/configure +++ b/configure @@ -1639,6 +1639,7 @@ TOOLCHAIN_FEATURES=" asm_mod_q attribute_may_alias attribute_packed + blocks_extension ebp_available ebx_available gnu_as @@ -2136,7 +2137,7 @@ zmbv_encoder_deps="zlib" d3d11va_deps="d3d11_h dxva_h ID3D11VideoDecoder" dxva2_deps="dxva2api_h DXVA2_ConfigPictureDecode" dxva2_lib_deps="dxva2" -vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads" +vda_deps="VideoDecodeAcceleration_VDADecoder_h blocks_extension pthreads" vda_extralibs="-framework CoreFoundation -framework VideoDecodeAcceleration -framework QuartzCore" h263_vaapi_hwaccel_deps="vaapi" @@ -4850,6 +4851,10 @@ check_disable_warning_headers -Wno-unused-variable check_objcflags -fobjc-arc && enable objc_arc +check_cc < Date: Wed, 14 Dec 2016 20:35:18 +0100 Subject: [PATCH 0813/3374] build: Map -Wall compiler flag to -W3 for MSVC and -Wextra to -W4 These are more appropriate warning level equivalents. --- configure | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 04b19211cf341..dde78b8657570 100755 --- a/configure +++ b/configure @@ -3045,6 +3045,7 @@ msvc_common_flags(){ # specific filters, they must be specified here as well or else the # generic catch all at the bottom will print the original flag. -Wall) ;; + -Wextra) ;; -std=c99) ;; # Common flags -fomit-frame-pointer) ;; @@ -3068,7 +3069,9 @@ msvc_flags(){ msvc_common_flags "$@" for flag; do case $flag in - -Wall) echo -W4 -wd4244 -wd4127 -wd4018 -wd4389 \ + -Wall) echo -W3 -wd4018 -wd4146 -wd4244 -wd4305 \ + -wd4554 ;; + -Wextra) echo -W4 -wd4244 -wd4127 -wd4018 -wd4389 \ -wd4146 -wd4057 -wd4204 -wd4706 -wd4305 \ -wd4152 -wd4324 -we4013 -wd4100 -wd4214 \ -wd4273 -wd4554 -wd4701 -wd4703 ;; From 1ae6cb7d6e4fee30754a46bc91f40ff75ac4412a Mon Sep 17 00:00:00 2001 From: Anton Schubert Date: Fri, 27 Jan 2017 00:25:07 +0100 Subject: [PATCH 0814/3374] dashenc: fix ISO8601 UTC parsing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Appends Z to timestamp to force ISO8601 datetime parsing as UTC. Without Z, some browsers (Chrome) interpret the timestamp as localtime and others (Firefox) interpret it as UTC. Signed-off-by: Anton Schubert Signed-off-by: Martin Storsjö --- libavformat/dashenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index ce018602dd05f..2b27950262e4c 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -429,7 +429,7 @@ static void format_date_now(char *buf, int size) struct tm *ptm, tmbuf; ptm = gmtime_r(&t, &tmbuf); if (ptm) { - if (!strftime(buf, size, "%Y-%m-%dT%H:%M:%S", ptm)) + if (!strftime(buf, size, "%Y-%m-%dT%H:%M:%SZ", ptm)) buf[0] = '\0'; } } From 95f1004bdfdf2d26c330c1d4b7c4ac9352d60b18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Gro=C3=9Fe?= Date: Fri, 27 Jan 2017 00:25:08 +0100 Subject: [PATCH 0815/3374] dashenc: add mandatory id to AdaptationSet and Period in manifest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Peter Große Signed-off-by: Martin Storsjö --- libavformat/dashenc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 2b27950262e4c..865f50a1cfeb9 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -439,7 +439,7 @@ static int write_manifest(AVFormatContext *s, int final) DASHContext *c = s->priv_data; AVIOContext *out; char temp_filename[1024]; - int ret, i; + int ret, i, as_id = 0; AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0); snprintf(temp_filename, sizeof(temp_filename), "%s.tmp", s->filename); @@ -494,15 +494,15 @@ static int write_manifest(AVFormatContext *s, int final) OutputStream *os = &c->streams[0]; int start_index = FFMAX(os->nb_segments - c->window_size, 0); int64_t start_time = av_rescale_q(os->segments[start_index]->time, s->streams[0]->time_base, AV_TIME_BASE_Q); - avio_printf(out, "\t\n"); } else { - avio_printf(out, "\t\n"); + avio_printf(out, "\t\n"); } if (c->has_video) { - avio_printf(out, "\t\t\n"); + avio_printf(out, "\t\t\n", as_id++); for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; OutputStream *os = &c->streams[i]; @@ -515,7 +515,7 @@ static int write_manifest(AVFormatContext *s, int final) avio_printf(out, "\t\t\n"); } if (c->has_audio) { - avio_printf(out, "\t\t\n"); + avio_printf(out, "\t\t\n", as_id++); for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; OutputStream *os = &c->streams[i]; From 3c2717e48dd8c5115f2be35c2afcabd8a1f67aee Mon Sep 17 00:00:00 2001 From: Anton Schubert Date: Fri, 27 Jan 2017 00:25:09 +0100 Subject: [PATCH 0816/3374] dashenc: increase buffer time hint in the manifest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit to avoid rebuffering on the clientside for difficult network conditions. Signed-off-by: Anton Schubert Signed-off-by: Martin Storsjö --- libavformat/dashenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 865f50a1cfeb9..44785cd90d042 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -481,7 +481,7 @@ static int write_manifest(AVFormatContext *s, int final) } } avio_printf(out, "\tminBufferTime=\""); - write_time(out, c->last_duration); + write_time(out, c->last_duration * 2); avio_printf(out, "\">\n"); avio_printf(out, "\t\n"); if (title) { From ca6ae3b77a7e6600e517723b90e57527a47809de Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Mon, 9 Jan 2017 19:17:37 +0000 Subject: [PATCH 0817/3374] vaapi_encode: Add MPEG-2 support --- Changelog | 1 + configure | 3 + libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/vaapi_encode.c | 1 + libavcodec/vaapi_encode.h | 5 +- libavcodec/vaapi_encode_mpeg2.c | 470 ++++++++++++++++++++++++++++++++ libavcodec/version.h | 2 +- 8 files changed, 481 insertions(+), 3 deletions(-) create mode 100644 libavcodec/vaapi_encode_mpeg2.c diff --git a/Changelog b/Changelog index 70d6a4a46b690..be90b36aa14f9 100644 --- a/Changelog +++ b/Changelog @@ -7,6 +7,7 @@ version : - VAAPI-accelerated VP8 and HEVC decoding - VAAPI-accelerated deinterlacing - config.log and other configuration files moved into avbuild/ directory +- VAAPI-accelerated MPEG-2 encoding version 12: diff --git a/configure b/configure index dde78b8657570..f183544ae68c7 100755 --- a/configure +++ b/configure @@ -2235,6 +2235,8 @@ mpeg2_qsv_decoder_deps="libmfx" mpeg2_qsv_decoder_select="qsvdec mpeg2_qsv_hwaccel mpegvideo_parser" mpeg2_qsv_encoder_deps="libmfx" mpeg2_qsv_encoder_select="qsvenc" +mpeg2_vaapi_encoder_deps="VAEncPictureParameterBufferMPEG2" +mpeg2_vaapi_encoder_select="vaapi_encode" mpeg4_omx_encoder_deps="omx" vc1_mmal_decoder_deps="mmal" vc1_qsv_decoder_deps="libmfx" @@ -4586,6 +4588,7 @@ check_type "va/va.h va/va_vpp.h" "VAProcPipelineParameterBuffer" check_type "va/va.h va/va_enc_h264.h" "VAEncPictureParameterBufferH264" check_type "va/va.h va/va_enc_hevc.h" "VAEncPictureParameterBufferHEVC" check_type "va/va.h va/va_enc_jpeg.h" "VAEncPictureParameterBufferJPEG" +check_type "va/va.h va/va_enc_mpeg2.h" "VAEncPictureParameterBufferMPEG2" check_type "vdpau/vdpau.h" "VdpPictureInfoHEVC" diff --git a/libavcodec/Makefile b/libavcodec/Makefile index b3cee1d0cacd3..19489fa7a9416 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -337,6 +337,7 @@ OBJS-$(CONFIG_MPEG2_QSV_ENCODER) += qsvenc_mpeg2.o OBJS-$(CONFIG_MPEG2VIDEO_DECODER) += mpeg12dec.o mpeg12.o mpeg12data.o OBJS-$(CONFIG_MPEG2VIDEO_ENCODER) += mpeg12enc.o mpeg12.o OBJS-$(CONFIG_MPEG2_MMAL_DECODER) += mmaldec.o +OBJS-$(CONFIG_MPEG2_VAAPI_ENCODER) += vaapi_encode_mpeg2.o OBJS-$(CONFIG_MPEG4_DECODER) += xvididct.o OBJS-$(CONFIG_MPEG4_OMX_ENCODER) += omx.o OBJS-$(CONFIG_MSA1_DECODER) += mss3.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 74cbc8ff03b18..92b9ce18c5872 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -505,6 +505,7 @@ void avcodec_register_all(void) REGISTER_ENCODER(HEVC_VAAPI, hevc_vaapi); REGISTER_ENCODER(MJPEG_VAAPI, mjpeg_vaapi); REGISTER_ENCODER(MPEG2_QSV, mpeg2_qsv); + REGISTER_ENCODER(MPEG2_VAAPI, mpeg2_vaapi); REGISTER_ENCODER(MPEG4_OMX, mpeg4_omx); #if FF_API_NVENC_OLD_NAME REGISTER_ENCODER(NVENC_H264, nvenc_h264); diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index c93bfcc0b10f9..9895c5a311bb5 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -320,6 +320,7 @@ static int vaapi_encode_issue(AVCodecContext *avctx, err = AVERROR(ENOMEM); goto fail; } + slice->index = i; pic->slices[i] = slice; if (ctx->codec->slice_params_size > 0) { diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h index 2a72510b83193..3954999f19748 100644 --- a/libavcodec/vaapi_encode.h +++ b/libavcodec/vaapi_encode.h @@ -35,8 +35,8 @@ enum { MAX_CONFIG_ATTRIBUTES = 4, MAX_GLOBAL_PARAMS = 4, MAX_PICTURE_REFERENCES = 2, - MAX_PICTURE_SLICES = 1, - MAX_PARAM_BUFFERS = 16, + MAX_PICTURE_SLICES = 112, + MAX_PARAM_BUFFERS = 128, MAX_REORDER_DELAY = 16, MAX_PARAM_BUFFER_SIZE = 1024, }; @@ -49,6 +49,7 @@ enum { }; typedef struct VAAPIEncodeSlice { + int index; void *priv_data; void *codec_slice_params; } VAAPIEncodeSlice; diff --git a/libavcodec/vaapi_encode_mpeg2.c b/libavcodec/vaapi_encode_mpeg2.c new file mode 100644 index 0000000000000..634178521f2f9 --- /dev/null +++ b/libavcodec/vaapi_encode_mpeg2.c @@ -0,0 +1,470 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "libavutil/avassert.h" +#include "libavutil/common.h" +#include "libavutil/internal.h" +#include "libavutil/opt.h" +#include "libavutil/pixfmt.h" + +#include "avcodec.h" +#include "internal.h" +#include "mpegvideo.h" +#include "put_bits.h" +#include "vaapi_encode.h" + +typedef struct VAAPIEncodeMPEG2Context { + int mb_width; + int mb_height; + + int quant_i; + int quant_p; + int quant_b; + + int64_t last_i_frame; + + unsigned int bit_rate; + unsigned int vbv_buffer_size; +} VAAPIEncodeMPEG2Context; + + +#define vseq_var(name) vseq->name, name +#define vseqext_field(name) vseq->sequence_extension.bits.name, name +#define vgop_field(name) vseq->gop_header.bits.name, name +#define vpic_var(name) vpic->name, name +#define vpcext_field(name) vpic->picture_coding_extension.bits.name, name +#define vcomp_field(name) vpic->composite_display.bits.name, name + +#define u2(width, value, name) put_bits(&pbc, width, value) +#define u(width, ...) u2(width, __VA_ARGS__) + +static int vaapi_encode_mpeg2_write_sequence_header(AVCodecContext *avctx, + char *data, size_t *data_len) +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + VAEncSequenceParameterBufferMPEG2 *vseq = ctx->codec_sequence_params; + VAAPIEncodeMPEG2Context *priv = ctx->priv_data; + PutBitContext pbc; + + init_put_bits(&pbc, data, 8 * *data_len); + + u(32, SEQ_START_CODE, sequence_header_code); + + u(12, vseq->picture_width, horizontal_size_value); + u(12, vseq->picture_height, vertical_size_value); + u(4, vseq_var(aspect_ratio_information)); + u(4, 8, frame_rate_code); + u(18, priv->bit_rate & 0x3fff, bit_rate_value); + u(1, 1, marker_bit); + u(10, priv->vbv_buffer_size & 0x3ff, vbv_buffer_size_value); + u(1, 0, constrained_parameters_flag); + u(1, 0, load_intra_quantiser_matrix); + // intra_quantiser_matrix[64] + u(1, 0, load_non_intra_quantiser_matrix); + // non_intra_quantiser_matrix[64] + + while (put_bits_count(&pbc) % 8) + u(1, 0, zero_bit); + + u(32, EXT_START_CODE, extension_start_code); + u(4, 1, extension_start_code_identifier); + u(8, vseqext_field(profile_and_level_indication)); + u(1, vseqext_field(progressive_sequence)); + u(2, vseqext_field(chroma_format)); + u(2, 0, horizontal_size_extension); + u(2, 0, vertical_size_extension); + u(12, priv->bit_rate >> 18, bit_rate_extension); + u(1, 1, marker_bit); + u(8, priv->vbv_buffer_size >> 10, vbv_buffer_size_extension); + u(1, vseqext_field(low_delay)); + u(2, vseqext_field(frame_rate_extension_n)); + u(2, vseqext_field(frame_rate_extension_d)); + + while (put_bits_count(&pbc) % 8) + u(1, 0, zero_bit); + + u(32, GOP_START_CODE, group_start_code); + u(25, vgop_field(time_code)); + u(1, vgop_field(closed_gop)); + u(1, vgop_field(broken_link)); + + while (put_bits_count(&pbc) % 8) + u(1, 0, zero_bit); + + *data_len = put_bits_count(&pbc); + flush_put_bits(&pbc); + + return 0; +} + +static int vaapi_encode_mpeg2_write_picture_header(AVCodecContext *avctx, + VAAPIEncodePicture *pic, + char *data, size_t *data_len) +{ + VAEncPictureParameterBufferMPEG2 *vpic = pic->codec_picture_params; + int picture_coding_type; + PutBitContext pbc; + + init_put_bits(&pbc, data, 8 * *data_len); + + u(32, PICTURE_START_CODE, picture_start_code); + u(10, vpic_var(temporal_reference)); + + switch (vpic->picture_type) { + case VAEncPictureTypeIntra: + picture_coding_type = AV_PICTURE_TYPE_I; + break; + case VAEncPictureTypePredictive: + picture_coding_type = AV_PICTURE_TYPE_P; + break; + case VAEncPictureTypeBidirectional: + picture_coding_type = AV_PICTURE_TYPE_B; + break; + default: + av_assert0(0 && "invalid picture_coding_type"); + } + u(3, picture_coding_type, picture_coding_type); + u(16, 0xffff, vbv_delay); + if (picture_coding_type == 2 || picture_coding_type == 3) { + u(1, 0, full_pel_forward_vector); + u(3, 7, forward_f_code); + } + if (picture_coding_type == 3) { + u(1, 0, full_pel_backward_vector); + u(3, 7, backward_f_code); + } + u(1, 0, extra_bit_picture); + + while (put_bits_count(&pbc) % 8) + u(1, 0, zero_bit); + + u(32, EXT_START_CODE, extension_start_code); + u(4, 8, extension_start_code_identifier); + u(4, vpic_var(f_code[0][0])); + u(4, vpic_var(f_code[0][1])); + u(4, vpic_var(f_code[1][0])); + u(4, vpic_var(f_code[1][1])); + u(2, vpcext_field(intra_dc_precision)); + u(2, vpcext_field(picture_structure)); + u(1, vpcext_field(top_field_first)); + u(1, vpcext_field(frame_pred_frame_dct)); + u(1, vpcext_field(concealment_motion_vectors)); + u(1, vpcext_field(q_scale_type)); + u(1, vpcext_field(intra_vlc_format)); + u(1, vpcext_field(alternate_scan)); + u(1, vpcext_field(repeat_first_field)); + u(1, 1, chroma_420_type); + u(1, vpcext_field(progressive_frame)); + u(1, vpcext_field(composite_display_flag)); + if (vpic->picture_coding_extension.bits.composite_display_flag) { + u(1, vcomp_field(v_axis)); + u(3, vcomp_field(field_sequence)); + u(1, vcomp_field(sub_carrier)); + u(7, vcomp_field(burst_amplitude)); + u(8, vcomp_field(sub_carrier_phase)); + } + + while (put_bits_count(&pbc) % 8) + u(1, 0, zero_bit); + + *data_len = put_bits_count(&pbc); + flush_put_bits(&pbc); + + return 0; +} + +static int vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx) +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + VAEncSequenceParameterBufferMPEG2 *vseq = ctx->codec_sequence_params; + VAEncPictureParameterBufferMPEG2 *vpic = ctx->codec_picture_params; + VAAPIEncodeMPEG2Context *priv = ctx->priv_data; + + vseq->intra_period = avctx->gop_size; + vseq->ip_period = ctx->b_per_p + 1; + + vseq->picture_width = avctx->width; + vseq->picture_height = avctx->height; + + vseq->bits_per_second = avctx->bit_rate; + if (avctx->framerate.num > 0 && avctx->framerate.den > 0) + vseq->frame_rate = (float)avctx->framerate.num / avctx->framerate.den; + else + vseq->frame_rate = (float)avctx->time_base.num / avctx->time_base.den; + + vseq->aspect_ratio_information = 1; + vseq->vbv_buffer_size = avctx->rc_buffer_size / (16 * 1024); + + vseq->sequence_extension.bits.profile_and_level_indication = + avctx->profile << 4 | avctx->level; + vseq->sequence_extension.bits.progressive_sequence = 1; + vseq->sequence_extension.bits.chroma_format = 1; + vseq->sequence_extension.bits.low_delay = 0; + vseq->sequence_extension.bits.frame_rate_extension_n = 0; + vseq->sequence_extension.bits.frame_rate_extension_d = 0; + + vseq->new_gop_header = 0; + vseq->gop_header.bits.time_code = 0; + vseq->gop_header.bits.closed_gop = 1; + vseq->gop_header.bits.broken_link = 0; + + vpic->forward_reference_picture = VA_INVALID_ID; + vpic->backward_reference_picture = VA_INVALID_ID; + vpic->reconstructed_picture = VA_INVALID_ID; + + vpic->coded_buf = VA_INVALID_ID; + + vpic->temporal_reference = 0; + vpic->f_code[0][0] = 15; + vpic->f_code[0][1] = 15; + vpic->f_code[1][0] = 15; + vpic->f_code[1][1] = 15; + + vpic->picture_coding_extension.bits.intra_dc_precision = 0; + vpic->picture_coding_extension.bits.picture_structure = 3; + vpic->picture_coding_extension.bits.top_field_first = 0; + vpic->picture_coding_extension.bits.frame_pred_frame_dct = 1; + vpic->picture_coding_extension.bits.concealment_motion_vectors = 0; + vpic->picture_coding_extension.bits.q_scale_type = 0; + vpic->picture_coding_extension.bits.intra_vlc_format = 0; + vpic->picture_coding_extension.bits.alternate_scan = 0; + vpic->picture_coding_extension.bits.repeat_first_field = 0; + vpic->picture_coding_extension.bits.progressive_frame = 1; + vpic->picture_coding_extension.bits.composite_display_flag = 0; + + priv->bit_rate = (avctx->bit_rate + 399) / 400; + priv->vbv_buffer_size = avctx->rc_buffer_size / (16 * 1024); + + return 0; +} + +static int vaapi_encode_mpeg2_init_picture_params(AVCodecContext *avctx, + VAAPIEncodePicture *pic) +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + VAEncPictureParameterBufferMPEG2 *vpic = pic->codec_picture_params; + VAAPIEncodeMPEG2Context *priv = ctx->priv_data; + int fch, fcv; + + switch (avctx->level) { + case 4: // High. + case 6: // High 1440. + fch = 9; + fcv = 5; + break; + case 8: // Main. + fch = 8; + fcv = 5; + break; + case 10: // Low. + default: + fch = 7; + fcv = 4; + break; + } + + switch (pic->type) { + case PICTURE_TYPE_IDR: + case PICTURE_TYPE_I: + vpic->picture_type = VAEncPictureTypeIntra; + priv->last_i_frame = pic->display_order; + break; + case PICTURE_TYPE_P: + vpic->picture_type = VAEncPictureTypePredictive; + vpic->forward_reference_picture = pic->refs[0]->recon_surface; + vpic->f_code[0][0] = fch; + vpic->f_code[0][1] = fcv; + break; + case PICTURE_TYPE_B: + vpic->picture_type = VAEncPictureTypeBidirectional; + vpic->forward_reference_picture = pic->refs[0]->recon_surface; + vpic->backward_reference_picture = pic->refs[1]->recon_surface; + vpic->f_code[0][0] = fch; + vpic->f_code[0][1] = fcv; + vpic->f_code[1][0] = fch; + vpic->f_code[1][1] = fcv; + break; + default: + av_assert0(0 && "invalid picture type"); + } + + vpic->reconstructed_picture = pic->recon_surface; + vpic->coded_buf = pic->output_buffer; + + vpic->temporal_reference = pic->display_order - priv->last_i_frame; + + pic->nb_slices = priv->mb_height; + + return 0; +} + +static int vaapi_encode_mpeg2_init_slice_params(AVCodecContext *avctx, + VAAPIEncodePicture *pic, + VAAPIEncodeSlice *slice) +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + VAEncSliceParameterBufferMPEG2 *vslice = slice->codec_slice_params; + VAAPIEncodeMPEG2Context *priv = ctx->priv_data; + int qp; + + vslice->macroblock_address = priv->mb_width * slice->index; + vslice->num_macroblocks = priv->mb_width; + + switch (pic->type) { + case PICTURE_TYPE_IDR: + case PICTURE_TYPE_I: + qp = priv->quant_i; + break; + case PICTURE_TYPE_P: + qp = priv->quant_p; + break; + case PICTURE_TYPE_B: + qp = priv->quant_b; + break; + default: + av_assert0(0 && "invalid picture type"); + } + + vslice->quantiser_scale_code = qp; + vslice->is_intra_slice = (pic->type == PICTURE_TYPE_IDR || + pic->type == PICTURE_TYPE_I); + + return 0; +} + +static av_cold int vaapi_encode_mpeg2_configure(AVCodecContext *avctx) +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + VAAPIEncodeMPEG2Context *priv = ctx->priv_data; + + priv->mb_width = FFALIGN(avctx->width, 16) / 16; + priv->mb_height = FFALIGN(avctx->height, 16) / 16; + + if (ctx->va_rc_mode == VA_RC_CQP) { + priv->quant_p = av_clip(avctx->global_quality, 1, 31); + if (avctx->i_quant_factor > 0.0) + priv->quant_i = av_clip((avctx->global_quality * + avctx->i_quant_factor + + avctx->i_quant_offset) + 0.5, + 1, 31); + else + priv->quant_i = priv->quant_p; + if (avctx->b_quant_factor > 0.0) + priv->quant_b = av_clip((avctx->global_quality * + avctx->b_quant_factor + + avctx->b_quant_offset) + 0.5, + 1, 31); + else + priv->quant_b = priv->quant_p; + + av_log(avctx, AV_LOG_DEBUG, "Using fixed quantiser " + "%d / %d / %d for I- / P- / B-frames.\n", + priv->quant_i, priv->quant_p, priv->quant_b); + + } else { + av_assert0(0 && "Invalid RC mode."); + } + + return 0; +} + +static const VAAPIEncodeType vaapi_encode_type_mpeg2 = { + .priv_data_size = sizeof(VAAPIEncodeMPEG2Context), + + .configure = &vaapi_encode_mpeg2_configure, + + .sequence_params_size = sizeof(VAEncSequenceParameterBufferMPEG2), + .init_sequence_params = &vaapi_encode_mpeg2_init_sequence_params, + + .picture_params_size = sizeof(VAEncPictureParameterBufferMPEG2), + .init_picture_params = &vaapi_encode_mpeg2_init_picture_params, + + .slice_params_size = sizeof(VAEncSliceParameterBufferMPEG2), + .init_slice_params = &vaapi_encode_mpeg2_init_slice_params, + + .sequence_header_type = VAEncPackedHeaderSequence, + .write_sequence_header = &vaapi_encode_mpeg2_write_sequence_header, + + .picture_header_type = VAEncPackedHeaderPicture, + .write_picture_header = &vaapi_encode_mpeg2_write_picture_header, +}; + +static av_cold int vaapi_encode_mpeg2_init(AVCodecContext *avctx) +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + + ctx->codec = &vaapi_encode_type_mpeg2; + + switch (avctx->profile) { + case FF_PROFILE_MPEG2_SIMPLE: + ctx->va_profile = VAProfileMPEG2Simple; + break; + case FF_PROFILE_MPEG2_MAIN: + ctx->va_profile = VAProfileMPEG2Main; + break; + default: + av_log(avctx, AV_LOG_ERROR, "Unknown MPEG-2 profile %d.\n", + avctx->profile); + return AVERROR(EINVAL); + } + + ctx->va_entrypoint = VAEntrypointEncSlice; + ctx->va_rt_format = VA_RT_FORMAT_YUV420; + ctx->va_rc_mode = VA_RC_CQP; + + ctx->va_packed_headers = VA_ENC_PACKED_HEADER_SEQUENCE | + VA_ENC_PACKED_HEADER_PICTURE; + + ctx->surface_width = FFALIGN(avctx->width, 16); + ctx->surface_height = FFALIGN(avctx->height, 16); + + return ff_vaapi_encode_init(avctx); +} + +static const AVCodecDefault vaapi_encode_mpeg2_defaults[] = { + { "profile", "4" }, + { "level", "4" }, + { "bf", "1" }, + { "g", "120" }, + { "i_qfactor", "1.0" }, + { "i_qoffset", "0.0" }, + { "b_qfactor", "1.2" }, + { "b_qoffset", "0.0" }, + { "global_quality", "10" }, + { NULL }, +}; + +AVCodec ff_mpeg2_vaapi_encoder = { + .name = "mpeg2_vaapi", + .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 (VAAPI)"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_MPEG2VIDEO, + .priv_data_size = sizeof(VAAPIEncodeContext), + .init = &vaapi_encode_mpeg2_init, + .encode2 = &ff_vaapi_encode2, + .close = &ff_vaapi_encode_close, + .capabilities = AV_CODEC_CAP_DELAY, + .defaults = vaapi_encode_mpeg2_defaults, + .pix_fmts = (const enum AVPixelFormat[]) { + AV_PIX_FMT_VAAPI, + AV_PIX_FMT_NONE, + }, +}; diff --git a/libavcodec/version.h b/libavcodec/version.h index df0c01f4ccda5..271bc9d6b0cbe 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 31 +#define LIBAVCODEC_VERSION_MINOR 32 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ From 11e225db31dcad57e2219ad8dfae2ac027af53d6 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Wed, 25 Jan 2017 15:59:09 +0100 Subject: [PATCH 0818/3374] rtmp: Account for bytes_read wraparound Servers seem to be happy to receive the wrapped-around value as long as they receive a report, otherwise they timeout. Initially reported and analyzed by Thomas Bernhard. --- libavformat/rtmpproto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 5298c18790b8a..49a40dd66ab82 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -2416,7 +2416,7 @@ static int get_packet(URLContext *s, int for_header) rt->last_timestamp = rpkt.timestamp; rt->bytes_read += ret; - if (rt->bytes_read > rt->last_bytes_read + rt->client_report_size) { + if (rt->bytes_read - rt->last_bytes_read > rt->client_report_size) { av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n"); if ((ret = gen_bytes_read(s, rt, rpkt.timestamp + 1)) < 0) return ret; From 78489822074096e3ae0f3c3b70accace955086f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Sun, 21 Sep 2014 11:38:25 +0200 Subject: [PATCH 0819/3374] configure: Place all temporary files in one separate directory Place all temporary files within a single, quasi-atomically created temporary directory rather than relying on unsafe 'mktemp -u'. This prevents possible race conditions in case two parallel 'mktemp -u' calls returned the same path. Additionally, it reduces TMPDIR pollution by keeping all test files in a single subdirectory. Signed-off-by: Diego Biurrun --- configure | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/configure b/configure index f183544ae68c7..a46e670ecd41c 100755 --- a/configure +++ b/configure @@ -2959,19 +2959,23 @@ if ! check_cmd mktemp -u XXXXXX; then # simple replacement for missing mktemp # NOT SAFE FOR GENERAL USE mktemp(){ - echo "${2%%XXX*}.${HOSTNAME}.${UID}.$$" + tmpname="${2%%XXX*}.${HOSTNAME}.${UID}.$$" + echo "$tmpname" + mkdir "$tmpname" } fi +AVTMPDIR=$(mktemp -d "${TMPDIR}/avconf.XXXXXXXX" 2> /dev/null) || + die "Unable to create temporary directory in $TMPDIR." + tmpfile(){ - tmp=$(mktemp -u "${TMPDIR}/ffconf.XXXXXXXX")$2 && - (set -C; exec > $tmp) 2>/dev/null || - die "Unable to create temporary file in $TMPDIR." - append TMPFILES $tmp + tmp="${AVTMPDIR}/test"$2 + (set -C; exec > $tmp) 2> /dev/null || + die "Unable to create temporary file in $AVTMPDIR." eval $1=$tmp } -trap 'rm -f -- $TMPFILES' EXIT +trap 'rm -rf -- "$AVTMPDIR"' EXIT tmpfile TMPASM .asm tmpfile TMPC .c From ba6a49e60bdd61b6d02c2b26daa01942c35f39cc Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 21 Sep 2014 11:48:21 +0200 Subject: [PATCH 0820/3374] configure: Clean up temporary files on interrupt --- configure | 1 + 1 file changed, 1 insertion(+) diff --git a/configure b/configure index a46e670ecd41c..9c277fa3c2ac2 100755 --- a/configure +++ b/configure @@ -2976,6 +2976,7 @@ tmpfile(){ } trap 'rm -rf -- "$AVTMPDIR"' EXIT +trap 'exit 2' INT tmpfile TMPASM .asm tmpfile TMPC .c From 1920382aa9f21d7ed1a3c2214990da8d2b067a92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Gro=C3=9Fe?= Date: Sun, 29 Jan 2017 20:41:22 +0100 Subject: [PATCH 0821/3374] dashenc: add option to provide UTC timing source MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If set, adds a UTCTiming tag in the manifest. This is part of the recommendations listed in the "Guidelines for Implementations: DASH-IF Interoperability Points" [1][2] Section 4.7 describes means for the Availability Time Synchronization. A usable default is "https://time.akamai.com/?iso" [1] http://dashif.org/guidelines/ [2] http://dashif.org/wp-content/uploads/2016/12/DASH-IF-IOP-v4.0-clean.pdf (current version as of writing) Signed-off-by: Peter Große Signed-off-by: Martin Storsjö --- libavformat/dashenc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 44785cd90d042..198932caa4f47 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -94,6 +94,7 @@ typedef struct DASHContext { const char *single_file_name; const char *init_seg_name; const char *media_seg_name; + const char *utc_timing_url; } DASHContext; static int dash_write(void *opaque, uint8_t *buf, int buf_size) @@ -490,6 +491,9 @@ static int write_manifest(AVFormatContext *s, int final) av_free(escaped); } avio_printf(out, "\t\n"); + if (c->utc_timing_url) + avio_printf(out, "\t\n", c->utc_timing_url); + if (c->window_size && s->nb_streams > 0 && c->streams[0].nb_segments > 0 && !c->use_template) { OutputStream *os = &c->streams[0]; int start_index = FFMAX(os->nb_segments - c->window_size, 0); @@ -981,6 +985,7 @@ static const AVOption options[] = { { "single_file_name", "DASH-templated name to be used for baseURL. Implies storing all segments in one file, accessed using byte ranges", OFFSET(single_file_name), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E }, { "init_seg_name", "DASH-templated name to used for the initialization segment", OFFSET(init_seg_name), AV_OPT_TYPE_STRING, {.str = "init-stream$RepresentationID$.m4s"}, 0, 0, E }, { "media_seg_name", "DASH-templated name to used for the media segments", OFFSET(media_seg_name), AV_OPT_TYPE_STRING, {.str = "chunk-stream$RepresentationID$-$Number%05d$.m4s"}, 0, 0, E }, + { "utc_timing_url", "URL of the page that will return the UTC timestamp in ISO format", OFFSET(utc_timing_url), AV_OPT_TYPE_STRING, { 0 }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM }, { NULL }, }; From e519dcd937c7c98815ba9884867590e302272016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Gro=C3=9Fe?= Date: Sun, 29 Jan 2017 15:26:25 +0100 Subject: [PATCH 0822/3374] dashenc: separate segments based on current segment duration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current implementation creates new segments comparing pkt->pts - first_pts > nb_segs * min_seg_duration This works fine, but if the keyframe interval is smaller than "min_seg_duration" segments shorter than the minimum segment duration are created. Example: keyint=50, min_seg_duration=3000000 segment 1 contains keyframe 1 (duration=2s < total_duration=3s) and keyframe 2 (duration=4s >= total_duration=3s) segment 2 contains keyframe 3 (duration=6s >= total_duration=6s) segment 3 contains keyframe 4 (duration=8s < total_duration=9s) and keyframe 5 (duration=10s >= total_duration=9s) ... Segment 2 is only 2s long, shorter than min_seg_duration = 3s. To fix this, new segments are created based on the actual written duration. Otherwise the option name "min_seg_duration" is misleading. Signed-off-by: Peter Große Signed-off-by: Martin Storsjö --- libavformat/dashenc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 198932caa4f47..98722cd24e341 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -868,7 +868,6 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) DASHContext *c = s->priv_data; AVStream *st = s->streams[pkt->stream_index]; OutputStream *os = &c->streams[pkt->stream_index]; - int64_t seg_end_duration = (os->segment_index) * (int64_t) c->min_seg_duration; int ret; ret = update_stream_extradata(s, os, st->codecpar); @@ -898,8 +897,8 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) if ((!c->has_video || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && pkt->flags & AV_PKT_FLAG_KEY && os->packets_written && - av_compare_ts(pkt->pts - os->first_pts, st->time_base, - seg_end_duration, AV_TIME_BASE_Q) >= 0) { + av_compare_ts(pkt->pts - os->start_pts, st->time_base, + c->min_seg_duration, AV_TIME_BASE_Q) >= 0) { int64_t prev_duration = c->last_duration; c->last_duration = av_rescale_q(pkt->pts - os->start_pts, From 9df9309d233f59d9706444a1e24ac24139f2640d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Gro=C3=9Fe?= Date: Mon, 30 Jan 2017 13:49:44 +0100 Subject: [PATCH 0823/3374] dashenc: calculate stream bitrate from first segment if not available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bandwidth information is required in the manifest, but not always provided by the demuxer. In that case calculate the bandwith based on the size and duration of the first segment. Signed-off-by: Peter Große Signed-off-by: Martin Storsjö --- libavformat/dashenc.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 98722cd24e341..21acb9006ca24 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -834,6 +834,16 @@ static int dash_flush(AVFormatContext *s, int final, int stream) if (ret < 0) break; } + + if (!os->bit_rate) { + // calculate average bitrate of first segment + int64_t bitrate = (int64_t) range_length * 8 * AV_TIME_BASE / (os->max_pts - os->start_pts); + if (bitrate >= 0) { + os->bit_rate = bitrate; + snprintf(os->bandwidth_str, sizeof(os->bandwidth_str), + " bandwidth=\"%d\"", os->bit_rate); + } + } 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); } From 3d23a5f96ad72961c14ba3a0c2add8f2ab374b61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Gro=C3=9Fe?= Date: Sun, 29 Jan 2017 15:26:27 +0100 Subject: [PATCH 0824/3374] dashenc: add support for assigning streams to AdaptationSets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also makes sure all streams are assigned to exactly one AdaptationSet. This patch is originally based partially on code by Vignesh Venkatasubramanian. Signed-off-by: Peter Große Signed-off-by: Martin Storsjö --- libavformat/dashenc.c | 204 +++++++++++++++++++++++++++++++++++------- 1 file changed, 173 insertions(+), 31 deletions(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 21acb9006ca24..e69e63e9ab99f 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -24,6 +24,7 @@ #include #endif +#include "libavutil/avutil.h" #include "libavutil/avstring.h" #include "libavutil/intreadwrite.h" #include "libavutil/mathematics.h" @@ -57,9 +58,14 @@ typedef struct Segment { int n; } Segment; +typedef struct AdaptationSet { + char id[10]; + enum AVMediaType media_type; +} AdaptationSet; + typedef struct OutputStream { AVFormatContext *ctx; - int ctx_inited; + int ctx_inited, as_idx; uint8_t iobuf[32768]; AVIOContext *out; int packets_written; @@ -78,6 +84,9 @@ typedef struct OutputStream { typedef struct DASHContext { const AVClass *class; /* Class for private options. */ + char *adaptation_sets; + AdaptationSet *as; + int nb_as; int window_size; int extra_window_size; int min_seg_duration; @@ -86,7 +95,7 @@ typedef struct DASHContext { int use_timeline; int single_file; OutputStream *streams; - int has_video, has_audio; + int has_video; int64_t last_duration; int64_t total_duration; char availability_start_time[100]; @@ -175,6 +184,12 @@ static void dash_free(AVFormatContext *s) { DASHContext *c = s->priv_data; int i, j; + + if (c->as) { + av_freep(&c->as); + c->nb_as = 0; + } + if (!c->streams) return; for (i = 0; i < s->nb_streams; i++) { @@ -435,12 +450,160 @@ static void format_date_now(char *buf, int size) } } +static int write_adaptation_set(AVFormatContext *s, AVIOContext *out, int as_index) +{ + DASHContext *c = s->priv_data; + AdaptationSet *as = &c->as[as_index]; + int i; + + avio_printf(out, "\t\t\n", + as->id, as->media_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio"); + + for (i = 0; i < s->nb_streams; i++) { + OutputStream *os = &c->streams[i]; + + if (os->as_idx - 1 != as_index) + continue; + + if (as->media_type == AVMEDIA_TYPE_VIDEO) { + avio_printf(out, "\t\t\t\n", + i, os->codec_str, os->bandwidth_str, s->streams[i]->codecpar->width, s->streams[i]->codecpar->height); + } else { + avio_printf(out, "\t\t\t\n", + i, os->codec_str, os->bandwidth_str, s->streams[i]->codecpar->sample_rate); + avio_printf(out, "\t\t\t\t\n", + s->streams[i]->codecpar->channels); + } + output_segment_list(os, out, c); + avio_printf(out, "\t\t\t\n"); + } + avio_printf(out, "\t\t\n"); + + return 0; +} + +static int add_adaptation_set(AVFormatContext *s, AdaptationSet **as, enum AVMediaType type) +{ + DASHContext *c = s->priv_data; + + void *mem = av_realloc(c->as, sizeof(*c->as) * (c->nb_as + 1)); + if (!mem) + return AVERROR(ENOMEM); + c->as = mem; + ++c->nb_as; + + *as = &c->as[c->nb_as - 1]; + memset(*as, 0, sizeof(**as)); + (*as)->media_type = type; + + return 0; +} + +static int parse_adaptation_sets(AVFormatContext *s) +{ + DASHContext *c = s->priv_data; + const char *p = c->adaptation_sets; + enum { new_set, parse_id, parsing_streams } state; + AdaptationSet *as; + int i, n, ret; + enum AVMediaType types[] = { AVMEDIA_TYPE_VIDEO, AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_UNKNOWN }; + + // default: one AdaptationSet for each media type + if (!p) { + for (n = 0; types[n] != AVMEDIA_TYPE_UNKNOWN; n++) { + int as_idx = 0; + + for (i = 0; i < s->nb_streams; i++) { + if (s->streams[i]->codecpar->codec_type != types[n]) + continue; + + if (!as_idx) { + if ((ret = add_adaptation_set(s, &as, types[n])) < 0) + return ret; + as_idx = c->nb_as; + + snprintf(as->id, sizeof(as->id), "%d", i); + } + c->streams[i].as_idx = as_idx; + } + } + goto end; + } + + // syntax id=0,streams=0,1,2 id=1,streams=3,4 and so on + state = new_set; + while (*p) { + if (*p == ' ') { + p++; + continue; + } else if (state == new_set && av_strstart(p, "id=", &p)) { + + if ((ret = add_adaptation_set(s, &as, AVMEDIA_TYPE_UNKNOWN)) < 0) + return ret; + + n = strcspn(p, ","); + snprintf(as->id, sizeof(as->id), "%.*s", n, p); + + p += n; + if (*p) + p++; + state = parse_id; + } else if (state == parse_id && av_strstart(p, "streams=", &p)) { + state = parsing_streams; + } else if (state == parsing_streams) { + AdaptationSet *as = &c->as[c->nb_as - 1]; + OutputStream *os; + char idx_str[8], *end_str; + + n = strcspn(p, " ,"); + snprintf(idx_str, sizeof(idx_str), "%.*s", n, p); + p += n; + + i = strtol(idx_str, &end_str, 10); + if (idx_str == end_str || i < 0 || i >= s->nb_streams) { + av_log(s, AV_LOG_ERROR, "Selected stream \"%s\" not found!\n", idx_str); + return AVERROR(EINVAL); + } + + os = &c->streams[i]; + if (as->media_type == AVMEDIA_TYPE_UNKNOWN) { + as->media_type = s->streams[i]->codecpar->codec_type; + } else if (as->media_type != s->streams[i]->codecpar->codec_type) { + av_log(s, AV_LOG_ERROR, "Mixing codec types within an AdaptationSet is not allowed\n"); + return AVERROR(EINVAL); + } else if (os->as_idx) { + av_log(s, AV_LOG_ERROR, "Assigning a stream to more than one AdaptationSet is not allowed\n"); + return AVERROR(EINVAL); + } + os->as_idx = c->nb_as; + + if (*p == ' ') + state = new_set; + if (*p) + p++; + } else { + return AVERROR(EINVAL); + } + } + +end: + // check for unassigned streams + for (i = 0; i < s->nb_streams; i++) { + OutputStream *os = &c->streams[i]; + if (!os->as_idx) { + av_log(s, AV_LOG_ERROR, "Stream %d is not mapped to an AdaptationSet\n", i); + return AVERROR(EINVAL); + } + } + return 0; +} + static int write_manifest(AVFormatContext *s, int final) { DASHContext *c = s->priv_data; AVIOContext *out; char temp_filename[1024]; - int ret, i, as_id = 0; + int ret, i; AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0); snprintf(temp_filename, sizeof(temp_filename), "%s.tmp", s->filename); @@ -505,32 +668,9 @@ static int write_manifest(AVFormatContext *s, int final) avio_printf(out, "\t\n"); } - if (c->has_video) { - avio_printf(out, "\t\t\n", as_id++); - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - OutputStream *os = &c->streams[i]; - if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO) - continue; - avio_printf(out, "\t\t\t\n", i, os->codec_str, os->bandwidth_str, st->codecpar->width, st->codecpar->height); - output_segment_list(&c->streams[i], out, c); - avio_printf(out, "\t\t\t\n"); - } - avio_printf(out, "\t\t\n"); - } - if (c->has_audio) { - avio_printf(out, "\t\t\n", as_id++); - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - OutputStream *os = &c->streams[i]; - if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) - continue; - avio_printf(out, "\t\t\t\n", i, os->codec_str, os->bandwidth_str, st->codecpar->sample_rate); - avio_printf(out, "\t\t\t\t\n", st->codecpar->channels); - output_segment_list(&c->streams[i], out, c); - avio_printf(out, "\t\t\t\n"); - } - avio_printf(out, "\t\t\n"); + for (i = 0; i < c->nb_as; i++) { + if ((ret = write_adaptation_set(s, out, i)) < 0) + return ret; } avio_printf(out, "\t\n"); avio_printf(out, "\n"); @@ -578,6 +718,9 @@ static int dash_write_header(AVFormatContext *s) goto fail; } + if ((ret = parse_adaptation_sets(s)) < 0) + goto fail; + for (i = 0; i < s->nb_streams; i++) { OutputStream *os = &c->streams[i]; AVFormatContext *ctx; @@ -657,8 +800,6 @@ static int dash_write_header(AVFormatContext *s) s->avoid_negative_ts = ctx->avoid_negative_ts; if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) c->has_video = 1; - else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) - c->has_audio = 1; set_codec_str(s, st->codecpar, os->codec_str, sizeof(os->codec_str)); os->first_pts = AV_NOPTS_VALUE; @@ -984,6 +1125,7 @@ static int dash_write_trailer(AVFormatContext *s) #define OFFSET(x) offsetof(DASHContext, x) #define E AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { + { "adaptation_sets", "Adaptation sets. Syntax: id=0,streams=0,1,2 id=1,streams=3,4 and so on", OFFSET(adaptation_sets), AV_OPT_TYPE_STRING, { 0 }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM }, { "window_size", "number of segments kept in the manifest", OFFSET(window_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, E }, { "extra_window_size", "number of segments kept outside of the manifest before removing from disk", OFFSET(extra_window_size), AV_OPT_TYPE_INT, { .i64 = 5 }, 0, INT_MAX, E }, { "min_seg_duration", "minimum segment duration (in microseconds)", OFFSET(min_seg_duration), AV_OPT_TYPE_INT64, { .i64 = 5000000 }, 0, INT_MAX, E }, From efd2fc41b3f0749f9715d50b581f22bbaa8c5b99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Gro=C3=9Fe?= Date: Sun, 29 Jan 2017 15:26:28 +0100 Subject: [PATCH 0825/3374] dashenc: allow assigning all streams of a media type to an AdaptationSet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using the characters "v" or "a" instead of stream index numbers for assigning streams in the adaption_set option, all streams matching that given type will be added to the AdaptationSet. Signed-off-by: Peter Große Signed-off-by: Martin Storsjö --- libavformat/dashenc.c | 61 +++++++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index e69e63e9ab99f..12e6f9b5d970d 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -499,6 +499,24 @@ static int add_adaptation_set(AVFormatContext *s, AdaptationSet **as, enum AVMed return 0; } +static int adaptation_set_add_stream(AVFormatContext *s, int as_idx, int i) +{ + DASHContext *c = s->priv_data; + AdaptationSet *as = &c->as[as_idx - 1]; + OutputStream *os = &c->streams[i]; + + if (as->media_type != s->streams[i]->codecpar->codec_type) { + av_log(s, AV_LOG_ERROR, "Codec type of stream %d doesn't match AdaptationSet's media type\n", i); + return AVERROR(EINVAL); + } else if (os->as_idx) { + av_log(s, AV_LOG_ERROR, "Stream %d is already assigned to an AdaptationSet\n", i); + return AVERROR(EINVAL); + } + os->as_idx = as_idx; + + return 0; +} + static int parse_adaptation_sets(AVFormatContext *s) { DASHContext *c = s->priv_data; @@ -552,30 +570,41 @@ static int parse_adaptation_sets(AVFormatContext *s) state = parsing_streams; } else if (state == parsing_streams) { AdaptationSet *as = &c->as[c->nb_as - 1]; - OutputStream *os; char idx_str[8], *end_str; n = strcspn(p, " ,"); snprintf(idx_str, sizeof(idx_str), "%.*s", n, p); p += n; - i = strtol(idx_str, &end_str, 10); - if (idx_str == end_str || i < 0 || i >= s->nb_streams) { - av_log(s, AV_LOG_ERROR, "Selected stream \"%s\" not found!\n", idx_str); - return AVERROR(EINVAL); - } + // if value is "a" or "v", map all streams of that type + if (as->media_type == AVMEDIA_TYPE_UNKNOWN && (idx_str[0] == 'v' || idx_str[0] == 'a')) { + enum AVMediaType type = (idx_str[0] == 'v') ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO; + av_log(s, AV_LOG_DEBUG, "Map all streams of type %s\n", idx_str); + + for (i = 0; i < s->nb_streams; i++) { + if (s->streams[i]->codecpar->codec_type != type) + continue; + + as->media_type = s->streams[i]->codecpar->codec_type; + + if ((ret = adaptation_set_add_stream(s, c->nb_as, i)) < 0) + return ret; + } + } else { // select single stream + i = strtol(idx_str, &end_str, 10); + if (idx_str == end_str || i < 0 || i >= s->nb_streams) { + av_log(s, AV_LOG_ERROR, "Selected stream \"%s\" not found!\n", idx_str); + return AVERROR(EINVAL); + } + av_log(s, AV_LOG_DEBUG, "Map stream %d\n", i); + + if (as->media_type == AVMEDIA_TYPE_UNKNOWN) { + as->media_type = s->streams[i]->codecpar->codec_type; + } - os = &c->streams[i]; - if (as->media_type == AVMEDIA_TYPE_UNKNOWN) { - as->media_type = s->streams[i]->codecpar->codec_type; - } else if (as->media_type != s->streams[i]->codecpar->codec_type) { - av_log(s, AV_LOG_ERROR, "Mixing codec types within an AdaptationSet is not allowed\n"); - return AVERROR(EINVAL); - } else if (os->as_idx) { - av_log(s, AV_LOG_ERROR, "Assigning a stream to more than one AdaptationSet is not allowed\n"); - return AVERROR(EINVAL); + if ((ret = adaptation_set_add_stream(s, c->nb_as, i)) < 0) + return ret; } - os->as_idx = c->nb_as; if (*p == ' ') state = new_set; From ca9bc9de690258d4761a19b0df6e9c9113b80115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Gro=C3=9Fe?= Date: Sun, 29 Jan 2017 15:26:29 +0100 Subject: [PATCH 0826/3374] dashenc: default to one AdaptationSet per stream MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously all mapped streams of a media type (video, audio) where assigned to a single AdaptationSet. Using the DASH live profile it is mandatory, that the segments of all representations are aligned, which is currently not enforced. This leads to problems when using video streams with different key frame intervals. So to play safe, default to one AdaptationSet per stream, unless overwritten by explicit assignment. To get the old assignment scheme, use -adaptation_sets "id=0,streams=v id=1,streams=a" Signed-off-by: Peter Große Signed-off-by: Martin Storsjö --- libavformat/dashenc.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 12e6f9b5d970d..286b24def3853 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -524,26 +524,15 @@ static int parse_adaptation_sets(AVFormatContext *s) enum { new_set, parse_id, parsing_streams } state; AdaptationSet *as; int i, n, ret; - enum AVMediaType types[] = { AVMEDIA_TYPE_VIDEO, AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_UNKNOWN }; - // default: one AdaptationSet for each media type + // default: one AdaptationSet for each stream if (!p) { - for (n = 0; types[n] != AVMEDIA_TYPE_UNKNOWN; n++) { - int as_idx = 0; - - for (i = 0; i < s->nb_streams; i++) { - if (s->streams[i]->codecpar->codec_type != types[n]) - continue; - - if (!as_idx) { - if ((ret = add_adaptation_set(s, &as, types[n])) < 0) - return ret; - as_idx = c->nb_as; + for (i = 0; i < s->nb_streams; i++) { + if ((ret = add_adaptation_set(s, &as, s->streams[i]->codecpar->codec_type)) < 0) + return ret; + snprintf(as->id, sizeof(as->id), "%d", i); - snprintf(as->id, sizeof(as->id), "%d", i); - } - c->streams[i].as_idx = as_idx; - } + c->streams[i].as_idx = c->nb_as; } goto end; } From dce2929efa8e82b0832a828f7e8cb81ff8c20a4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Gro=C3=9Fe?= Date: Sun, 29 Jan 2017 15:26:30 +0100 Subject: [PATCH 0827/3374] dashenc: copy language and role metadata from streams assigned to sets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Peter Große Signed-off-by: Martin Storsjö --- libavformat/dashenc.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 286b24def3853..8b70278b39135 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -61,6 +61,7 @@ typedef struct Segment { typedef struct AdaptationSet { char id[10]; enum AVMediaType media_type; + AVDictionary *metadata; } AdaptationSet; typedef struct OutputStream { @@ -186,6 +187,8 @@ static void dash_free(AVFormatContext *s) int i, j; if (c->as) { + for (i = 0; i < c->nb_as; i++) + av_dict_free(&c->as[i].metadata); av_freep(&c->as); c->nb_as = 0; } @@ -454,10 +457,19 @@ static int write_adaptation_set(AVFormatContext *s, AVIOContext *out, int as_ind { DASHContext *c = s->priv_data; AdaptationSet *as = &c->as[as_index]; + AVDictionaryEntry *lang, *role; int i; - avio_printf(out, "\t\t\n", + avio_printf(out, "\t\tid, as->media_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio"); + lang = av_dict_get(as->metadata, "language", NULL, 0); + if (lang) + avio_printf(out, " lang=\"%s\"", lang->value); + avio_printf(out, ">\n"); + + role = av_dict_get(as->metadata, "role", NULL, 0); + if (role) + avio_printf(out, "\t\t\t\n", role->value); for (i = 0; i < s->nb_streams; i++) { OutputStream *os = &c->streams[i]; @@ -697,6 +709,14 @@ static int write_manifest(AVFormatContext *s, int final) return ff_rename(temp_filename, s->filename); } +static int dict_copy_entry(AVDictionary **dst, const AVDictionary *src, const char *key) +{ + AVDictionaryEntry *entry = av_dict_get(src, key, NULL, 0); + if (entry) + av_dict_set(dst, key, entry->value, AV_DICT_DONT_OVERWRITE); + return 0; +} + static int dash_write_header(AVFormatContext *s) { DASHContext *c = s->priv_data; @@ -741,6 +761,7 @@ static int dash_write_header(AVFormatContext *s) for (i = 0; i < s->nb_streams; i++) { OutputStream *os = &c->streams[i]; + AdaptationSet *as = &c->as[os->as_idx - 1]; AVFormatContext *ctx; AVStream *st; AVDictionary *opts = NULL; @@ -760,6 +781,10 @@ static int dash_write_header(AVFormatContext *s) } } + // copy AdaptationSet language and role from stream metadata + dict_copy_entry(&as->metadata, s->streams[i]->metadata, "language"); + dict_copy_entry(&as->metadata, s->streams[i]->metadata, "role"); + ctx = avformat_alloc_context(); if (!ctx) { ret = AVERROR(ENOMEM); From 01f1f017d831cf14617aaaeafcec3ae3a81efce7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Gro=C3=9Fe?= Date: Sun, 29 Jan 2017 15:26:31 +0100 Subject: [PATCH 0828/3374] dashenc: use avio_dynbuf instead of packet_write callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dash_write function drops data, if no IOContext is initialized. Since the mp4 muxer is used in "frag_custom" mode, data is only written when calling av_write_frame(NULL) explicitly and thus there will be no data loss. To add support for webm as subordinate muxer, which doesn't have such a mode, a dynamic buffer is required to provide an always initialized IOContext. Signed-off-by: Peter Große Signed-off-by: Martin Storsjö --- libavformat/dashenc.c | 61 +++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 8b70278b39135..78ebc0628a7c1 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -67,11 +67,10 @@ typedef struct AdaptationSet { typedef struct OutputStream { AVFormatContext *ctx; int ctx_inited, as_idx; - uint8_t iobuf[32768]; AVIOContext *out; int packets_written; char initfile[1024]; - int64_t init_start_pos; + int64_t init_start_pos, pos; int init_range_length; int nb_segments, segments_size, segment_index; Segment **segments; @@ -107,14 +106,6 @@ typedef struct DASHContext { const char *utc_timing_url; } DASHContext; -static int dash_write(void *opaque, uint8_t *buf, int buf_size) -{ - OutputStream *os = opaque; - if (os->out) - avio_write(os->out, buf, buf_size); - return buf_size; -} - // RFC 6381 static void set_codec_str(AVFormatContext *s, AVCodecParameters *par, char *str, int size) @@ -181,6 +172,28 @@ static void set_codec_str(AVFormatContext *s, AVCodecParameters *par, } } +static int flush_dynbuf(OutputStream *os, int *range_length) +{ + uint8_t *buffer; + + if (!os->ctx->pb) { + return AVERROR(EINVAL); + } + + // flush + av_write_frame(os->ctx, NULL); + avio_flush(os->ctx->pb); + + // write out to file + *range_length = avio_close_dyn_buf(os->ctx->pb, &buffer); + os->ctx->pb = NULL; + avio_write(os->out, buffer, *range_length); + av_free(buffer); + + // re-open buffer + return avio_open_dyn_buf(&os->ctx->pb); +} + static void dash_free(AVFormatContext *s) { DASHContext *c = s->priv_data; @@ -200,7 +213,7 @@ static void dash_free(AVFormatContext *s) if (os->ctx && os->ctx_inited) av_write_trailer(os->ctx); if (os->ctx && os->ctx->pb) - av_free(os->ctx->pb); + ffio_free_dyn_buf(&os->ctx->pb); ff_format_io_close(s, &os->out); if (os->ctx) avformat_free_context(os->ctx); @@ -806,11 +819,8 @@ static int dash_write_header(AVFormatContext *s) st->time_base = s->streams[i]->time_base; ctx->avoid_negative_ts = s->avoid_negative_ts; - ctx->pb = avio_alloc_context(os->iobuf, sizeof(os->iobuf), AVIO_FLAG_WRITE, os, NULL, dash_write, NULL); - if (!ctx->pb) { - ret = AVERROR(ENOMEM); + if ((ret = avio_open_dyn_buf(&ctx->pb)) < 0) goto fail; - } if (c->single_file) { if (c->single_file_name) @@ -966,7 +976,6 @@ static int dash_flush(AVFormatContext *s, int final, int stream) for (i = 0; i < s->nb_streams; i++) { OutputStream *os = &c->streams[i]; char filename[1024] = "", full_path[1024], temp_path[1024]; - int64_t start_pos; int range_length, index_length = 0; if (!os->packets_written) @@ -985,14 +994,14 @@ static int dash_flush(AVFormatContext *s, int final, int stream) } if (!os->init_range_length) { - av_write_frame(os->ctx, NULL); - os->init_range_length = avio_tell(os->ctx->pb); + ret = flush_dynbuf(os, &range_length); + if (ret < 0) + break; + os->pos = os->init_range_length = range_length; if (!c->single_file) ff_format_io_close(s, &os->out); } - start_pos = avio_tell(os->ctx->pb); - 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); @@ -1005,13 +1014,13 @@ static int dash_flush(AVFormatContext *s, int final, int stream) snprintf(full_path, sizeof(full_path), "%s%s", c->dirname, os->initfile); } - av_write_frame(os->ctx, NULL); - avio_flush(os->ctx->pb); + ret = flush_dynbuf(os, &range_length); + if (ret < 0) + break; os->packets_written = 0; - range_length = avio_tell(os->ctx->pb) - start_pos; if (c->single_file) { - find_index_range(s, full_path, start_pos, &index_length); + find_index_range(s, full_path, os->pos, &index_length); } else { ff_format_io_close(s, &os->out); ret = ff_rename(temp_path, full_path); @@ -1028,8 +1037,10 @@ static int dash_flush(AVFormatContext *s, int final, int stream) " bandwidth=\"%d\"", os->bit_rate); } } - add_segment(os, filename, os->start_pts, os->max_pts - os->start_pts, start_pos, range_length, index_length); + add_segment(os, filename, os->start_pts, os->max_pts - os->start_pts, os->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); + + os->pos += range_length; } if (c->window_size || (final && c->remove_at_exit)) { From 7295b7373862ee54903b33d6ef3335531dfa93ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Gro=C3=9Fe?= Date: Sun, 29 Jan 2017 15:26:32 +0100 Subject: [PATCH 0829/3374] dashenc: add webm support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use webm muxer for VP8, VP9 and Opus codec, mp4 muxer otherwise. Signed-off-by: Peter Große Signed-off-by: Martin Storsjö --- libavformat/dashenc.c | 103 +++++++++++++++++++++++++++++++++--------- libavformat/version.h | 2 +- 2 files changed, 83 insertions(+), 22 deletions(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 78ebc0628a7c1..7134af4978b2c 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -68,6 +68,7 @@ typedef struct OutputStream { AVFormatContext *ctx; int ctx_inited, as_idx; AVIOContext *out; + char format_name[8]; int packets_written; char initfile[1024]; int64_t init_start_pos, pos; @@ -106,12 +107,32 @@ typedef struct DASHContext { const char *utc_timing_url; } DASHContext; -// RFC 6381 +static struct codec_string { + int id; + const char *str; +} codecs[] = { + { AV_CODEC_ID_VP8, "vp8" }, + { AV_CODEC_ID_VP9, "vp9" }, + { AV_CODEC_ID_VORBIS, "vorbis" }, + { AV_CODEC_ID_OPUS, "opus" }, + { 0, NULL } +}; + static void set_codec_str(AVFormatContext *s, AVCodecParameters *par, char *str, int size) { const AVCodecTag *tags[2] = { NULL, NULL }; uint32_t tag; + int i; + + // common Webm codecs are not part of RFC 6381 + for (i = 0; codecs[i].id; i++) + if (codecs[i].id == par->codec_id) { + av_strlcpy(str, codecs[i].str, size); + return; + } + + // for codecs part of RFC 6381 if (par->codec_type == AVMEDIA_TYPE_VIDEO) tags[0] = ff_codec_movvideo_tags; else if (par->codec_type == AVMEDIA_TYPE_AUDIO) @@ -194,6 +215,21 @@ static int flush_dynbuf(OutputStream *os, int *range_length) return avio_open_dyn_buf(&os->ctx->pb); } +static int flush_init_segment(AVFormatContext *s, OutputStream *os) +{ + DASHContext *c = s->priv_data; + int ret, range_length; + + ret = flush_dynbuf(os, &range_length); + if (ret < 0) + return ret; + + os->pos = os->init_range_length = range_length; + if (!c->single_file) + ff_format_io_close(s, &os->out); + return 0; +} + static void dash_free(AVFormatContext *s) { DASHContext *c = s->priv_data; @@ -491,11 +527,11 @@ static int write_adaptation_set(AVFormatContext *s, AVIOContext *out, int as_ind continue; if (as->media_type == AVMEDIA_TYPE_VIDEO) { - avio_printf(out, "\t\t\t\n", - i, os->codec_str, os->bandwidth_str, s->streams[i]->codecpar->width, s->streams[i]->codecpar->height); + avio_printf(out, "\t\t\t\n", + i, os->format_name, os->codec_str, os->bandwidth_str, s->streams[i]->codecpar->width, s->streams[i]->codecpar->height); } else { - avio_printf(out, "\t\t\t\n", - i, os->codec_str, os->bandwidth_str, s->streams[i]->codecpar->sample_rate); + avio_printf(out, "\t\t\t\n", + i, os->format_name, os->codec_str, os->bandwidth_str, s->streams[i]->codecpar->sample_rate); avio_printf(out, "\t\t\t\t\n", s->streams[i]->codecpar->channels); } @@ -730,11 +766,18 @@ static int dict_copy_entry(AVDictionary **dst, const AVDictionary *src, const ch return 0; } +static int dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags) +{ + char valuestr[22]; + snprintf(valuestr, sizeof(valuestr), "%"PRId64, value); + flags &= ~AV_DICT_DONT_STRDUP_VAL; + return av_dict_set(pm, key, valuestr, flags); +} + static int dash_write_header(AVFormatContext *s) { DASHContext *c = s->priv_data; int ret = 0, i; - AVOutputFormat *oformat; char *ptr; char basename[1024]; @@ -757,12 +800,6 @@ static int dash_write_header(AVFormatContext *s) if (ptr) *ptr = '\0'; - oformat = av_guess_format("mp4", NULL, NULL); - if (!oformat) { - ret = AVERROR_MUXER_NOT_FOUND; - goto fail; - } - c->streams = av_mallocz(sizeof(*c->streams) * s->nb_streams); if (!c->streams) { ret = AVERROR(ENOMEM); @@ -803,8 +840,24 @@ static int dash_write_header(AVFormatContext *s) ret = AVERROR(ENOMEM); goto fail; } + + // choose muxer based on codec: webm for VP8/9 and opus, mp4 otherwise + // note: os->format_name is also used as part of the mimetype of the + // representation, e.g. video/ + if (s->streams[i]->codecpar->codec_id == AV_CODEC_ID_VP8 || + s->streams[i]->codecpar->codec_id == AV_CODEC_ID_VP9 || + s->streams[i]->codecpar->codec_id == AV_CODEC_ID_OPUS || + s->streams[i]->codecpar->codec_id == AV_CODEC_ID_VORBIS) { + snprintf(os->format_name, sizeof(os->format_name), "webm"); + } else { + snprintf(os->format_name, sizeof(os->format_name), "mp4"); + } + ctx->oformat = av_guess_format(os->format_name, NULL, NULL); + if (!ctx->oformat) { + ret = AVERROR_MUXER_NOT_FOUND; + goto fail; + } os->ctx = ctx; - ctx->oformat = oformat; ctx->interrupt_callback = s->interrupt_callback; ctx->opaque = s->opaque; ctx->io_close = s->io_close; @@ -836,7 +889,12 @@ static int dash_write_header(AVFormatContext *s) goto fail; os->init_start_pos = 0; - av_dict_set(&opts, "movflags", "frag_custom+dash+delay_moov", 0); + if (!strcmp(os->format_name, "mp4")) { + av_dict_set(&opts, "movflags", "frag_custom+dash+delay_moov", 0); + } else { + dict_set_int(&opts, "cluster_time_limit", c->min_seg_duration / 1000, 0); + dict_set_int(&opts, "cluster_size_limit", 5 * 1024 * 1024, 0); // set a large cluster size limit + } if ((ret = avformat_write_header(ctx, &opts)) < 0) { goto fail; } @@ -846,6 +904,13 @@ static int dash_write_header(AVFormatContext *s) av_log(s, AV_LOG_VERBOSE, "Representation %d init segment will be written to: %s\n", i, filename); + // Flush init segment + // except for mp4, since delay_moov is set and the init segment + // is then flushed after the first packets + if (strcmp(os->format_name, "mp4")) { + flush_init_segment(s, os); + } + s->streams[i]->time_base = st->time_base; // If the muxer wants to shift timestamps, request to have them shifted // already before being handed to this muxer, so we don't have mismatches @@ -994,12 +1059,7 @@ static int dash_flush(AVFormatContext *s, int final, int stream) } if (!os->init_range_length) { - ret = flush_dynbuf(os, &range_length); - if (ret < 0) - break; - os->pos = os->init_range_length = range_length; - if (!c->single_file) - ff_format_io_close(s, &os->out); + flush_init_segment(s, os); } if (!c->single_file) { @@ -1009,7 +1069,8 @@ static int dash_flush(AVFormatContext *s, int final, int stream) ret = s->io_open(s, &os->out, temp_path, AVIO_FLAG_WRITE, NULL); if (ret < 0) break; - write_styp(os->ctx->pb); + if (!strcmp(os->format_name, "mp4")) + write_styp(os->ctx->pb); } else { snprintf(full_path, sizeof(full_path), "%s%s", c->dirname, os->initfile); } diff --git a/libavformat/version.h b/libavformat/version.h index 3fa2c4443b0a4..65d5754630daf 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -31,7 +31,7 @@ #define LIBAVFORMAT_VERSION_MAJOR 57 #define LIBAVFORMAT_VERSION_MINOR 10 -#define LIBAVFORMAT_VERSION_MICRO 2 +#define LIBAVFORMAT_VERSION_MICRO 3 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ From c5c663541739cb813a2a5668ee8339b535b35d7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Gro=C3=9Fe?= Date: Sun, 29 Jan 2017 15:26:33 +0100 Subject: [PATCH 0830/3374] doc: add dash muxer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Peter Große Signed-off-by: Martin Storsjö --- doc/muxers.texi | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/doc/muxers.texi b/doc/muxers.texi index 5430da78501a5..62cd8d025b142 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -53,6 +53,68 @@ avconv -i INPUT -c:a pcm_u8 -c:v mpeg2video -f crc - See also the @ref{framecrc} muxer. +@anchor{dash} +@section dash + +Dynamic Adaptive Streaming over HTTP (DASH) muxer that creates segments +and manifest files according to the MPEG-DASH standard ISO/IEC 23009-1:2014. + +For more information see: + +@itemize @bullet +@item +ISO DASH Specification: @url{http://standards.iso.org/ittf/PubliclyAvailableStandards/c065274_ISO_IEC_23009-1_2014.zip} +@item +WebM DASH Specification: @url{https://sites.google.com/a/webmproject.org/wiki/adaptive-streaming/webm-dash-specification} +@end itemize + +It creates a MPD manifest file and segment files for each stream. + +The segment filename might contain pre-defined identifiers used with SegmentTemplate +as defined in section 5.3.9.4.4 of the standard. Available identifiers are "$RepresentationID$", +"$Number$", "$Bandwidth$" and "$Time$". + +@example +avconv -re -i -map 0 -map 0 -c:a libfdk_aac -c:v libx264 +-b:v:0 800k -b:v:1 300k -s:v:1 320x170 -profile:v:1 baseline +-profile:v:0 main -bf 1 -keyint_min 120 -g 120 -sc_threshold 0 +-b_strategy 0 -ar:a:1 22050 -use_timeline 1 -use_template 1 +-window_size 5 -adaptation_sets "id=0,streams=v id=1,streams=a" +-f dash /path/to/out.mpd +@end example + +@table @option +@item -min_seg_duration @var{microseconds} +Set the segment length in microseconds. +@item -window_size @var{size} +Set the maximum number of segments kept in the manifest. +@item -extra_window_size @var{size} +Set the maximum number of segments kept outside of the manifest before removing from disk. +@item -remove_at_exit @var{remove} +Enable (1) or disable (0) removal of all segments when finished. +@item -use_template @var{template} +Enable (1) or disable (0) use of SegmentTemplate instead of SegmentList. +@item -use_timeline @var{timeline} +Enable (1) or disable (0) use of SegmentTimeline in SegmentTemplate. +@item -single_file @var{single_file} +Enable (1) or disable (0) storing all segments in one file, accessed using byte ranges. +@item -single_file_name @var{file_name} +DASH-templated name to be used for baseURL. Implies @var{single_file} set to "1". +@item -init_seg_name @var{init_name} +DASH-templated name to used for the initialization segment. Default is "init-stream$RepresentationID$.m4s" +@item -media_seg_name @var{segment_name} +DASH-templated name to used for the media segments. Default is "chunk-stream$RepresentationID$-$Number%05d$.m4s" +@item -utc_timing_url @var{utc_url} +URL of the page that will return the UTC timestamp in ISO format. Example: "https://time.akamai.com/?iso" +@item -adaptation_sets @var{adaptation_sets} +Assign streams to AdaptationSets. Syntax is "id=x,streams=a,b,c id=y,streams=d,e" with x and y being the IDs +of the adaptation sets and a,b,c,d and e are the indices of the mapped streams. + +To map all video (or audio) streams to an AdaptationSet, "v" (or "a") can be used as stream identifier instead of IDs. + +When no assignment is defined, this defaults to an AdaptationSet for each stream. +@end table + @anchor{framecrc} @section framecrc From f033ba470fbab1ff6838666d4d86411effa97b27 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 29 Jan 2017 14:11:03 +0000 Subject: [PATCH 0831/3374] vaapi_encode: Support VBR mode This includes a backward-compatibility hack to choose CBR anyway on old drivers which have no CBR support, so that existing programs will continue to work their options now map to VBR. --- libavcodec/vaapi_encode.c | 42 ++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index 9895c5a311bb5..e9aa48606a0eb 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -1034,6 +1034,19 @@ static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx) }; break; case VAConfigAttribRateControl: + // Hack for backward compatibility: CBR was the only + // usable RC mode for a long time, so old drivers will + // only have it. Normal default options may now choose + // VBR and then fail, however, so override it here with + // CBR if that is the only supported mode. + if (ctx->va_rc_mode == VA_RC_VBR && + !(attr[i].value & VA_RC_VBR) && + (attr[i].value & VA_RC_CBR)) { + av_log(avctx, AV_LOG_WARNING, "VBR rate control is " + "not supported with this driver version; " + "using CBR instead.\n"); + ctx->va_rc_mode = VA_RC_CBR; + } if (!(ctx->va_rc_mode & attr[i].value)) { av_log(avctx, AV_LOG_ERROR, "Rate control mode %#x " "is not supported (mask: %#x).\n", @@ -1098,6 +1111,9 @@ static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx) static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx) { VAAPIEncodeContext *ctx = avctx->priv_data; + int rc_bits_per_second; + int rc_target_percentage; + int rc_window_size; int hrd_buffer_size; int hrd_initial_buffer_fullness; @@ -1110,13 +1126,29 @@ static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx) else hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4; + if (ctx->va_rc_mode == VA_RC_CBR) { + rc_bits_per_second = avctx->bit_rate; + rc_target_percentage = 100; + rc_window_size = 1000; + } else { + if (avctx->rc_max_rate < avctx->bit_rate) { + // Max rate is unset or invalid, just use the normal bitrate. + rc_bits_per_second = avctx->bit_rate; + rc_target_percentage = 100; + } else { + rc_bits_per_second = avctx->rc_max_rate; + rc_target_percentage = (avctx->bit_rate * 100) / rc_bits_per_second; + } + rc_window_size = (hrd_buffer_size * 1000) / avctx->bit_rate; + } + ctx->rc_params.misc.type = VAEncMiscParameterTypeRateControl; ctx->rc_params.rc = (VAEncMiscParameterRateControl) { - .bits_per_second = avctx->bit_rate, - .target_percentage = 66, - .window_size = 1000, - .initial_qp = (avctx->qmax >= 0 ? avctx->qmax : 40), - .min_qp = (avctx->qmin >= 0 ? avctx->qmin : 18), + .bits_per_second = rc_bits_per_second, + .target_percentage = rc_target_percentage, + .window_size = rc_window_size, + .initial_qp = 0, + .min_qp = (avctx->qmin > 0 ? avctx->qmin : 0), .basic_unit_size = 0, }; ctx->global_params[ctx->nb_global_params] = From eddfb57210298a0a94472794485400a3a6c76196 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 29 Jan 2017 14:12:20 +0000 Subject: [PATCH 0832/3374] vaapi_h264: Enable VBR mode Default to using VBR when a target bitrate is set, unless the max rate is also set and matches the target. Changes to the Intel driver mean that min_qp is also respected in this case, so set a codec default to unset the value rather than using the current default inherited from the MPEG-4 part 2 encoder. --- libavcodec/vaapi_encode_h264.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index 74e7cb1c16f5a..b918e0d75e88e 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -1126,13 +1126,15 @@ static av_cold int vaapi_encode_h264_configure(AVCodecContext *avctx) "%d / %d / %d for IDR- / P- / B-frames.\n", priv->fixed_qp_idr, priv->fixed_qp_p, priv->fixed_qp_b); - } else if (ctx->va_rc_mode == VA_RC_CBR) { + } else if (ctx->va_rc_mode == VA_RC_CBR || + ctx->va_rc_mode == VA_RC_VBR) { // These still need to be set for pic_init_qp/slice_qp_delta. priv->fixed_qp_idr = 26; priv->fixed_qp_p = 26; priv->fixed_qp_b = 26; - av_log(avctx, AV_LOG_DEBUG, "Using constant-bitrate = %d bps.\n", + av_log(avctx, AV_LOG_DEBUG, "Using %s-bitrate = %d bps.\n", + ctx->va_rc_mode == VA_RC_CBR ? "constant" : "variable", avctx->bit_rate); } else { @@ -1241,9 +1243,12 @@ static av_cold int vaapi_encode_h264_init(AVCodecContext *avctx) // Only 8-bit encode is supported. ctx->va_rt_format = VA_RT_FORMAT_YUV420; - if (avctx->bit_rate > 0) - ctx->va_rc_mode = VA_RC_CBR; - else + if (avctx->bit_rate > 0) { + if (avctx->rc_max_rate == avctx->bit_rate) + ctx->va_rc_mode = VA_RC_CBR; + else + ctx->va_rc_mode = VA_RC_VBR; + } else ctx->va_rc_mode = VA_RC_CQP; ctx->va_packed_headers = @@ -1281,6 +1286,7 @@ static const AVCodecDefault vaapi_encode_h264_defaults[] = { { "i_qoffset", "0.0" }, { "b_qfactor", "1.2" }, { "b_qoffset", "0.0" }, + { "qmin", "0" }, { NULL }, }; From ff35aa8ca4069bf1543adeec4c28e51e4a012eee Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Tue, 29 Nov 2016 22:12:46 +0000 Subject: [PATCH 0833/3374] vaapi_encode: Pass framerate parameters to driver Only do this when building for a recent VAAPI version - initial driver implementations were confused about the interpretation of the framerate field, but hopefully this will be consistent everywhere once 0.40.0 is released. --- libavcodec/vaapi_encode.c | 18 ++++++++++++++++++ libavcodec/vaapi_encode.h | 4 ++++ 2 files changed, 22 insertions(+) diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index e9aa48606a0eb..8238952543fcb 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -1116,6 +1116,7 @@ static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx) int rc_window_size; int hrd_buffer_size; int hrd_initial_buffer_fullness; + int fr_num, fr_den; if (avctx->rc_buffer_size) hrd_buffer_size = avctx->rc_buffer_size; @@ -1166,6 +1167,23 @@ static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx) ctx->global_params_size[ctx->nb_global_params++] = sizeof(ctx->hrd_params); + if (avctx->framerate.num > 0 && avctx->framerate.den > 0) + av_reduce(&fr_num, &fr_den, + avctx->framerate.num, avctx->framerate.den, 65535); + else + av_reduce(&fr_num, &fr_den, + avctx->time_base.den, avctx->time_base.num, 65535); + + ctx->fr_params.misc.type = VAEncMiscParameterTypeFrameRate; + ctx->fr_params.fr.framerate = (unsigned int)fr_den << 16 | fr_num; + +#if VA_CHECK_VERSION(0, 40, 0) + ctx->global_params[ctx->nb_global_params] = + &ctx->fr_params.misc; + ctx->global_params_size[ctx->nb_global_params++] = + sizeof(ctx->fr_params); +#endif + return 0; } diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h index 3954999f19748..fc62365148c79 100644 --- a/libavcodec/vaapi_encode.h +++ b/libavcodec/vaapi_encode.h @@ -155,6 +155,10 @@ typedef struct VAAPIEncodeContext { VAEncMiscParameterBuffer misc; VAEncMiscParameterHRD hrd; } hrd_params; + struct { + VAEncMiscParameterBuffer misc; + VAEncMiscParameterFrameRate fr; + } fr_params; // Per-sequence parameter structure (VAEncSequenceParameterBuffer*). void *codec_sequence_params; From ca62236a89f47bd871eaf69d8d9e837c93c55a6c Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Tue, 29 Nov 2016 20:38:29 +0000 Subject: [PATCH 0834/3374] vaapi_encode: Add VP8 support --- Changelog | 2 +- configure | 3 + libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/vaapi_encode_vp8.c | 268 ++++++++++++++++++++++++++++++++++ libavcodec/version.h | 2 +- 6 files changed, 275 insertions(+), 2 deletions(-) create mode 100644 libavcodec/vaapi_encode_vp8.c diff --git a/Changelog b/Changelog index be90b36aa14f9..713883d5f5eb4 100644 --- a/Changelog +++ b/Changelog @@ -7,7 +7,7 @@ version : - VAAPI-accelerated VP8 and HEVC decoding - VAAPI-accelerated deinterlacing - config.log and other configuration files moved into avbuild/ directory -- VAAPI-accelerated MPEG-2 encoding +- VAAPI-accelerated MPEG-2 and VP8 encoding version 12: diff --git a/configure b/configure index 9c277fa3c2ac2..3904b41e36a34 100755 --- a/configure +++ b/configure @@ -2243,6 +2243,8 @@ vc1_qsv_decoder_deps="libmfx" vc1_qsv_decoder_select="qsvdec vc1_qsv_hwaccel vc1_parser" vp8_qsv_decoder_deps="libmfx" vp8_qsv_decoder_select="qsvdec vp8_qsv_hwaccel vp8_parser" +vp8_vaapi_encoder_deps="VAEncPictureParameterBufferVP8" +vp8_vaapi_encoder_select="vaapi_encode" nvenc_h264_encoder_select="h264_nvenc_encoder" nvenc_hevc_encoder_select="hevc_nvenc_encoder" @@ -4594,6 +4596,7 @@ check_type "va/va.h va/va_enc_h264.h" "VAEncPictureParameterBufferH264" check_type "va/va.h va/va_enc_hevc.h" "VAEncPictureParameterBufferHEVC" check_type "va/va.h va/va_enc_jpeg.h" "VAEncPictureParameterBufferJPEG" check_type "va/va.h va/va_enc_mpeg2.h" "VAEncPictureParameterBufferMPEG2" +check_type "va/va.h va/va_enc_vp8.h" "VAEncPictureParameterBufferVP8" check_type "vdpau/vdpau.h" "VdpPictureInfoHEVC" diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 19489fa7a9416..7d28d6685e0b4 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -482,6 +482,7 @@ OBJS-$(CONFIG_VP6_DECODER) += vp6.o vp56.o vp56data.o \ OBJS-$(CONFIG_VP7_DECODER) += vp8.o vp56rac.o OBJS-$(CONFIG_VP8_DECODER) += vp8.o vp56rac.o OBJS-$(CONFIG_VP8_QSV_DECODER) += qsvdec_other.o +OBJS-$(CONFIG_VP8_VAAPI_ENCODER) += vaapi_encode_vp8.o OBJS-$(CONFIG_VP9_DECODER) += vp9.o vp9data.o vp9dsp.o \ vp9block.o vp9prob.o vp9mvs.o vp56rac.o OBJS-$(CONFIG_VQA_DECODER) += vqavideo.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 92b9ce18c5872..46c42c578a7aa 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -511,6 +511,7 @@ void avcodec_register_all(void) REGISTER_ENCODER(NVENC_H264, nvenc_h264); REGISTER_ENCODER(NVENC_HEVC, nvenc_hevc); #endif + REGISTER_ENCODER(VP8_VAAPI, vp8_vaapi); /* parsers */ REGISTER_PARSER(AAC, aac); diff --git a/libavcodec/vaapi_encode_vp8.c b/libavcodec/vaapi_encode_vp8.c new file mode 100644 index 0000000000000..d1a8087b82352 --- /dev/null +++ b/libavcodec/vaapi_encode_vp8.c @@ -0,0 +1,268 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "libavutil/avassert.h" +#include "libavutil/common.h" +#include "libavutil/internal.h" +#include "libavutil/opt.h" +#include "libavutil/pixfmt.h" + +#include "avcodec.h" +#include "internal.h" +#include "vaapi_encode.h" + + +typedef struct VAAPIEncodeVP8Context { + int q_index_i; + int q_index_p; +} VAAPIEncodeVP8Context; + +typedef struct VAAPIEncodeVP8Options { + int loop_filter_level; + int loop_filter_sharpness; +} VAAPIEncodeVP8Options; + + +#define vseq_var(name) vseq->name, name +#define vseq_field(name) vseq->seq_fields.bits.name, name +#define vpic_var(name) vpic->name, name +#define vpic_field(name) vpic->pic_fields.bits.name, name + + +static int vaapi_encode_vp8_init_sequence_params(AVCodecContext *avctx) +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + VAEncSequenceParameterBufferVP8 *vseq = ctx->codec_sequence_params; + + vseq->frame_width = avctx->width; + vseq->frame_height = avctx->height; + + vseq->frame_width_scale = 0; + vseq->frame_height_scale = 0; + + vseq->error_resilient = 0; + vseq->kf_auto = 0; + + if (!(ctx->va_rc_mode & VA_RC_CQP)) { + vseq->bits_per_second = avctx->bit_rate; + vseq->intra_period = avctx->gop_size; + } + + return 0; +} + +static int vaapi_encode_vp8_init_picture_params(AVCodecContext *avctx, + VAAPIEncodePicture *pic) +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + VAEncPictureParameterBufferVP8 *vpic = pic->codec_picture_params; + VAAPIEncodeVP8Options *opt = ctx->codec_options; + int i; + + vpic->reconstructed_frame = pic->recon_surface; + + vpic->coded_buf = pic->output_buffer; + + switch (pic->type) { + case PICTURE_TYPE_IDR: + case PICTURE_TYPE_I: + av_assert0(pic->nb_refs == 0); + vpic->ref_flags.bits.force_kf = 1; + vpic->ref_last_frame = + vpic->ref_gf_frame = + vpic->ref_arf_frame = + VA_INVALID_SURFACE; + break; + case PICTURE_TYPE_P: + av_assert0(pic->nb_refs == 1); + vpic->ref_flags.bits.no_ref_last = 0; + vpic->ref_flags.bits.no_ref_gf = 1; + vpic->ref_flags.bits.no_ref_arf = 1; + vpic->ref_last_frame = + vpic->ref_gf_frame = + vpic->ref_arf_frame = + pic->refs[0]->recon_surface; + break; + default: + av_assert0(0 && "invalid picture type"); + } + + vpic->pic_flags.bits.frame_type = (pic->type != PICTURE_TYPE_IDR); + vpic->pic_flags.bits.show_frame = 1; + + vpic->pic_flags.bits.refresh_last = 1; + vpic->pic_flags.bits.refresh_golden_frame = 1; + vpic->pic_flags.bits.refresh_alternate_frame = 1; + + vpic->pic_flags.bits.version = 0; + vpic->pic_flags.bits.loop_filter_type = 0; + for (i = 0; i < 4; i++) + vpic->loop_filter_level[i] = opt->loop_filter_level; + vpic->sharpness_level = opt->loop_filter_sharpness; + + vpic->clamp_qindex_low = 0; + vpic->clamp_qindex_high = 127; + + return 0; +} + +static int vaapi_encode_vp8_write_quant_table(AVCodecContext *avctx, + VAAPIEncodePicture *pic, + int index, int *type, + char *data, size_t *data_len) +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + VAAPIEncodeVP8Context *priv = ctx->priv_data; + VAQMatrixBufferVP8 quant; + int i, q; + + if (index > 0) + return AVERROR_EOF; + + if (*data_len < sizeof(quant)) + return AVERROR(EINVAL); + *type = VAQMatrixBufferType; + *data_len = sizeof(quant); + + if (pic->type == PICTURE_TYPE_P) + q = priv->q_index_p; + else + q = priv->q_index_i; + + for (i = 0; i < 4; i++) + quant.quantization_index[i] = q; + for (i = 0; i < 5; i++) + quant.quantization_index_delta[i] = 0; + + memcpy(data, &quant, sizeof(quant)); + return 0; +} + +static av_cold int vaapi_encode_vp8_configure(AVCodecContext *avctx) +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + VAAPIEncodeVP8Context *priv = ctx->priv_data; + + priv->q_index_p = av_clip(avctx->global_quality, 0, 127); + if (avctx->i_quant_factor > 0.0) + priv->q_index_i = av_clip((avctx->global_quality * + avctx->i_quant_factor + + avctx->i_quant_offset) + 0.5, + 0, 127); + else + priv->q_index_i = priv->q_index_p; + + return 0; +} + +static const VAAPIEncodeType vaapi_encode_type_vp8 = { + .configure = &vaapi_encode_vp8_configure, + + .priv_data_size = sizeof(VAAPIEncodeVP8Context), + + .sequence_params_size = sizeof(VAEncSequenceParameterBufferVP8), + .init_sequence_params = &vaapi_encode_vp8_init_sequence_params, + + .picture_params_size = sizeof(VAEncPictureParameterBufferVP8), + .init_picture_params = &vaapi_encode_vp8_init_picture_params, + + .write_extra_buffer = &vaapi_encode_vp8_write_quant_table, +}; + +static av_cold int vaapi_encode_vp8_init(AVCodecContext *avctx) +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + + if (avctx->max_b_frames > 0) { + av_log(avctx, AV_LOG_ERROR, "B-frames are not supported.\n"); + return AVERROR_PATCHWELCOME; + } + + ctx->codec = &vaapi_encode_type_vp8; + + ctx->va_profile = VAProfileVP8Version0_3; + ctx->va_entrypoint = VAEntrypointEncSlice; + ctx->va_rt_format = VA_RT_FORMAT_YUV420; + + if (avctx->flags & AV_CODEC_FLAG_QSCALE) { + ctx->va_rc_mode = VA_RC_CQP; + } else if (avctx->bit_rate > 0) { + if (avctx->rc_max_rate == avctx->bit_rate) + ctx->va_rc_mode = VA_RC_CBR; + else + ctx->va_rc_mode = VA_RC_VBR; + } else { + ctx->va_rc_mode = VA_RC_CQP; + } + + // Packed headers are not currently supported. + ctx->va_packed_headers = 0; + + ctx->surface_width = FFALIGN(avctx->width, 16); + ctx->surface_height = FFALIGN(avctx->height, 16); + + return ff_vaapi_encode_init(avctx); +} + +#define OFFSET(x) (offsetof(VAAPIEncodeContext, codec_options_data) + \ + offsetof(VAAPIEncodeVP8Options, x)) +#define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM) +static const AVOption vaapi_encode_vp8_options[] = { + { "loop_filter_level", "Loop filter level", + OFFSET(loop_filter_level), AV_OPT_TYPE_INT, { .i64 = 16 }, 0, 63, FLAGS }, + { "loop_filter_sharpness", "Loop filter sharpness", + OFFSET(loop_filter_sharpness), AV_OPT_TYPE_INT, { .i64 = 4 }, 0, 15, FLAGS }, + { NULL }, +}; + +static const AVCodecDefault vaapi_encode_vp8_defaults[] = { + { "b", "0" }, + { "bf", "0" }, + { "g", "120" }, + { "global_quality", "40" }, + { NULL }, +}; + +static const AVClass vaapi_encode_vp8_class = { + .class_name = "vp8_vaapi", + .item_name = av_default_item_name, + .option = vaapi_encode_vp8_options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_vp8_vaapi_encoder = { + .name = "vp8_vaapi", + .long_name = NULL_IF_CONFIG_SMALL("VP8 (VAAPI)"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_VP8, + .priv_data_size = (sizeof(VAAPIEncodeContext) + + sizeof(VAAPIEncodeVP8Options)), + .init = &vaapi_encode_vp8_init, + .encode2 = &ff_vaapi_encode2, + .close = &ff_vaapi_encode_close, + .priv_class = &vaapi_encode_vp8_class, + .capabilities = AV_CODEC_CAP_DELAY, + .defaults = vaapi_encode_vp8_defaults, + .pix_fmts = (const enum AVPixelFormat[]) { + AV_PIX_FMT_VAAPI, + AV_PIX_FMT_NONE, + }, +}; diff --git a/libavcodec/version.h b/libavcodec/version.h index 271bc9d6b0cbe..2ade539c60996 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 32 +#define LIBAVCODEC_VERSION_MINOR 33 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ From 708e84cda1bdbffb92847f3d6ccf6fbeb26d9948 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 29 Jan 2017 19:45:59 +0000 Subject: [PATCH 0835/3374] mov: Avoid memcmp of uninitialised data The string codec name need not be as long as the value we are comparing it to, so memcmp may make decisions derived from uninitialised data that valgrind then complains about (though the overall result of the function will always be the same). Use strncmp instead, which will stop at the first zero byte and therefore not encounter this issue. --- libavformat/mov.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 37afe79df029a..9afd0202ca981 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1455,11 +1455,11 @@ static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb, av_dict_set(&st->metadata, "encoder", codec_name, 0); /* codec_tag YV12 triggers an UV swap in rawdec.c */ - if (!memcmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) + if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) st->codecpar->codec_tag = MKTAG('I', '4', '2', '0'); /* Flash Media Server uses tag H.263 with Sorenson Spark */ if (st->codecpar->codec_tag == MKTAG('H','2','6','3') && - !memcmp(codec_name, "Sorenson H263", 13)) + !strncmp(codec_name, "Sorenson H263", 13)) st->codecpar->codec_id = AV_CODEC_ID_FLV1; st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */ From 612cc0712836af2f025b0c68b11da29b9f259d5a Mon Sep 17 00:00:00 2001 From: Andreas Cadhalpun Date: Tue, 31 Jan 2017 01:59:38 +0100 Subject: [PATCH 0836/3374] pgssubdec: reset rle_data_len/rle_remaining_len on allocation error The code relies on their validity and otherwise can try to access a NULL object->rle pointer, causing segmentation faults. Signed-off-by: Andreas Cadhalpun Signed-off-by: Diego Biurrun --- libavcodec/pgssubdec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/pgssubdec.c b/libavcodec/pgssubdec.c index 886685b4b5de8..a6a43ae32ba72 100644 --- a/libavcodec/pgssubdec.c +++ b/libavcodec/pgssubdec.c @@ -297,8 +297,11 @@ static int parse_object_segment(AVCodecContext *avctx, av_fast_malloc(&object->rle, &object->rle_buffer_size, rle_bitmap_len); - if (!object->rle) + if (!object->rle) { + object->rle_data_len = 0; + object->rle_remaining_len = 0; return AVERROR(ENOMEM); + } memcpy(object->rle, buf, buf_size); object->rle_data_len = buf_size; From ab87af41636b081dd3562423999351b5444fa09e Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 25 Jan 2017 19:11:24 +0100 Subject: [PATCH 0837/3374] configure: Add proper weak dependency of avformat on network --- configure | 1 + 1 file changed, 1 insertion(+) diff --git a/configure b/configure index 3904b41e36a34..a2223022cb022 100755 --- a/configure +++ b/configure @@ -2484,6 +2484,7 @@ avcodec_select="null_bsf" avdevice_deps="avformat avcodec avutil" avfilter_deps="avutil" avformat_deps="avcodec avutil" +avformat_suggest="network" avresample_deps="avutil" swscale_deps="avutil" From d4c2103bd30ff6ceea70c3696ae88a7d2ea72493 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 30 Jan 2017 20:24:38 +0100 Subject: [PATCH 0838/3374] golomb: Convert to the new bitstream reader --- libavcodec/aic.c | 2 +- libavcodec/cavs.c | 2 +- libavcodec/cavsdec.c | 2 +- libavcodec/dirac.c | 2 +- libavcodec/ffv1dec.c | 3 +- libavcodec/ffv1enc.c | 2 +- libavcodec/fic.c | 3 +- libavcodec/flacdec.c | 2 +- libavcodec/flacenc.c | 2 +- libavcodec/golomb.h | 190 +++++------- libavcodec/golomb_legacy.h | 573 +++++++++++++++++++++++++++++++++++++ libavcodec/h264_cavlc.c | 2 +- libavcodec/h264_parse.c | 2 +- libavcodec/h264_parser.c | 2 +- libavcodec/h264_ps.c | 3 +- libavcodec/h264_refs.c | 2 +- libavcodec/h264_sei.c | 2 +- libavcodec/h264_slice.c | 2 +- libavcodec/h264dec.c | 2 +- libavcodec/hevc_parser.c | 2 +- libavcodec/hevc_ps.c | 2 +- libavcodec/hevc_ps_enc.c | 2 +- libavcodec/hevc_sei.c | 2 +- libavcodec/hevcdec.c | 2 +- libavcodec/jpeglsdec.c | 2 +- libavcodec/jpeglsenc.c | 2 +- libavcodec/loco.c | 2 +- libavcodec/ralf.c | 2 +- libavcodec/rv30.c | 2 +- libavcodec/rv34.c | 2 +- libavcodec/rv40.c | 2 +- libavcodec/shorten.c | 2 +- libavcodec/svq3.c | 3 +- libavcodec/tests/golomb.c | 22 +- libavformat/hevc.c | 2 +- 35 files changed, 693 insertions(+), 160 deletions(-) create mode 100644 libavcodec/golomb_legacy.h diff --git a/libavcodec/aic.c b/libavcodec/aic.c index 2c9b6f80985ab..405ebf12d54b0 100644 --- a/libavcodec/aic.c +++ b/libavcodec/aic.c @@ -26,7 +26,7 @@ #include "bytestream.h" #include "internal.h" #include "get_bits.h" -#include "golomb.h" +#include "golomb_legacy.h" #include "idctdsp.h" #include "thread.h" #include "unary_legacy.h" diff --git a/libavcodec/cavs.c b/libavcodec/cavs.c index cf66629ffd99f..bf1a59a6f0f69 100644 --- a/libavcodec/cavs.c +++ b/libavcodec/cavs.c @@ -27,7 +27,7 @@ #include "avcodec.h" #include "get_bits.h" -#include "golomb.h" +#include "golomb_legacy.h" #include "h264chroma.h" #include "idctdsp.h" #include "internal.h" diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c index 1c4f276373f2c..5a28fc04eda75 100644 --- a/libavcodec/cavsdec.c +++ b/libavcodec/cavsdec.c @@ -27,7 +27,7 @@ #include "avcodec.h" #include "get_bits.h" -#include "golomb.h" +#include "golomb_legacy.h" #include "cavs.h" #include "internal.h" #include "mpeg12data.h" diff --git a/libavcodec/dirac.c b/libavcodec/dirac.c index 142af205792ac..cce9439d44f6a 100644 --- a/libavcodec/dirac.c +++ b/libavcodec/dirac.c @@ -29,7 +29,7 @@ #include "avcodec.h" #include "dirac.h" -#include "golomb.h" +#include "golomb_legacy.h" #include "internal.h" #include "mpeg12data.h" diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index d3169ec7c52ae..2ebd6864a1cf6 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -31,12 +31,13 @@ #include "libavutil/opt.h" #include "libavutil/imgutils.h" #include "libavutil/timer.h" + #include "avcodec.h" +#include "golomb_legacy.h" #include "internal.h" #include "get_bits.h" #include "put_bits.h" #include "rangecoder.h" -#include "golomb.h" #include "mathops.h" #include "ffv1.h" diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c index 0eeccfffb4f06..adf70d8a6b2f8 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -33,10 +33,10 @@ #include "libavutil/imgutils.h" #include "avcodec.h" +#include "golomb_legacy.h" #include "internal.h" #include "put_bits.h" #include "rangecoder.h" -#include "golomb.h" #include "mathops.h" #include "ffv1.h" diff --git a/libavcodec/fic.c b/libavcodec/fic.c index b1286ebe65362..180410491654e 100644 --- a/libavcodec/fic.c +++ b/libavcodec/fic.c @@ -22,10 +22,11 @@ */ #include "libavutil/common.h" + #include "avcodec.h" +#include "golomb_legacy.h" #include "internal.h" #include "get_bits.h" -#include "golomb.h" typedef struct FICThreadContext { DECLARE_ALIGNED(16, int16_t, block)[64]; diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c index 7af71f3c0c0de..78be2adab3baa 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -37,7 +37,7 @@ #include "internal.h" #include "get_bits.h" #include "bytestream.h" -#include "golomb.h" +#include "golomb_legacy.h" #include "flac.h" #include "flacdata.h" #include "flacdsp.h" diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c index 67f899f712cb4..0c1e6b7673a97 100644 --- a/libavcodec/flacenc.c +++ b/libavcodec/flacenc.c @@ -26,7 +26,7 @@ #include "avcodec.h" #include "bswapdsp.h" -#include "golomb.h" +#include "golomb_legacy.h" #include "internal.h" #include "lpc.h" #include "flac.h" diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h index 9fafbcda70b71..648f9243fc4a6 100644 --- a/libavcodec/golomb.h +++ b/libavcodec/golomb.h @@ -32,7 +32,7 @@ #include -#include "get_bits.h" +#include "bitstream.h" #include "put_bits.h" #define INVALID_VLC 0x80000000 @@ -50,26 +50,22 @@ extern const uint8_t ff_interleaved_dirac_golomb_vlc_code[256]; /** * read unsigned exp golomb code. */ -static inline int get_ue_golomb(GetBitContext *gb) +static inline int get_ue_golomb(BitstreamContext *bc) { unsigned int buf; - OPEN_READER(re, gb); - UPDATE_CACHE(re, gb); - buf = GET_CACHE(re, gb); + buf = bitstream_peek(bc, 32); if (buf >= (1 << 27)) { buf >>= 32 - 9; - LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]); - CLOSE_READER(re, gb); + bitstream_skip(bc, ff_golomb_vlc_len[buf]); return ff_ue_golomb_vlc_code[buf]; } else { int log = 2 * av_log2(buf) - 31; buf >>= log; buf--; - LAST_SKIP_BITS(re, gb, 32 - log); - CLOSE_READER(re, gb); + bitstream_skip(bc, 32 - log); return buf; } @@ -78,48 +74,42 @@ static inline int get_ue_golomb(GetBitContext *gb) /** * Read an unsigned Exp-Golomb code in the range 0 to UINT32_MAX-1. */ -static inline unsigned get_ue_golomb_long(GetBitContext *gb) +static inline unsigned get_ue_golomb_long(BitstreamContext *bc) { unsigned buf, log; - buf = show_bits_long(gb, 32); + buf = bitstream_peek(bc, 32); log = 31 - av_log2(buf); - skip_bits_long(gb, log); + bitstream_skip(bc, log); - return get_bits_long(gb, log + 1) - 1; + return bitstream_read(bc, log + 1) - 1; } /** * read unsigned exp golomb code, constraint to a max of 31. * the return value is undefined if the stored value exceeds 31. */ -static inline int get_ue_golomb_31(GetBitContext *gb) +static inline int get_ue_golomb_31(BitstreamContext *bc) { unsigned int buf; - OPEN_READER(re, gb); - UPDATE_CACHE(re, gb); - buf = GET_CACHE(re, gb); + buf = bitstream_peek(bc, 32); buf >>= 32 - 9; - LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]); - CLOSE_READER(re, gb); + bitstream_skip(bc, ff_golomb_vlc_len[buf]); return ff_ue_golomb_vlc_code[buf]; } -static inline unsigned get_interleaved_ue_golomb(GetBitContext *gb) +static inline unsigned get_interleaved_ue_golomb(BitstreamContext *bc) { uint32_t buf; - OPEN_READER(re, gb); - UPDATE_CACHE(re, gb); - buf = GET_CACHE(re, gb); + buf = bitstream_peek(bc, 32); if (buf & 0xAA800000) { buf >>= 32 - 8; - LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]); - CLOSE_READER(re, gb); + bitstream_skip(bc, ff_interleaved_golomb_vlc_len[buf]); return ff_interleaved_ue_golomb_vlc_code[buf]; } else { @@ -127,8 +117,7 @@ static inline unsigned get_interleaved_ue_golomb(GetBitContext *gb) do { buf >>= 32 - 8; - LAST_SKIP_BITS(re, gb, - FFMIN(ff_interleaved_golomb_vlc_len[buf], 8)); + bitstream_skip(bc, FFMIN(ff_interleaved_golomb_vlc_len[buf], 8)); if (ff_interleaved_golomb_vlc_len[buf] != 9) { ret <<= (ff_interleaved_golomb_vlc_len[buf] - 1) >> 1; @@ -136,11 +125,9 @@ static inline unsigned get_interleaved_ue_golomb(GetBitContext *gb) break; } ret = (ret << 4) | ff_interleaved_dirac_golomb_vlc_code[buf]; - UPDATE_CACHE(re, gb); - buf = GET_CACHE(re, gb); - } while (BITS_AVAILABLE(re, gb)); + buf = bitstream_peek(bc, 32); + } while (bitstream_bits_left(bc) > 0); - CLOSE_READER(re, gb); return ret - 1; } } @@ -148,54 +135,50 @@ static inline unsigned get_interleaved_ue_golomb(GetBitContext *gb) /** * read unsigned truncated exp golomb code. */ -static inline int get_te0_golomb(GetBitContext *gb, int range) +static inline int get_te0_golomb(BitstreamContext *bc, int range) { assert(range >= 1); if (range == 1) return 0; else if (range == 2) - return get_bits1(gb) ^ 1; + return bitstream_read_bit(bc) ^ 1; else - return get_ue_golomb(gb); + return get_ue_golomb(bc); } /** * read unsigned truncated exp golomb code. */ -static inline int get_te_golomb(GetBitContext *gb, int range) +static inline int get_te_golomb(BitstreamContext *bc, int range) { assert(range >= 1); if (range == 2) - return get_bits1(gb) ^ 1; + return bitstream_read_bit(bc) ^ 1; else - return get_ue_golomb(gb); + return get_ue_golomb(bc); } /** * read signed exp golomb code. */ -static inline int get_se_golomb(GetBitContext *gb) +static inline int get_se_golomb(BitstreamContext *bc) { unsigned int buf; - OPEN_READER(re, gb); - UPDATE_CACHE(re, gb); - buf = GET_CACHE(re, gb); + buf = bitstream_peek(bc, 32); if (buf >= (1 << 27)) { buf >>= 32 - 9; - LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]); - CLOSE_READER(re, gb); + bitstream_skip(bc, ff_golomb_vlc_len[buf]); return ff_se_golomb_vlc_code[buf]; } else { int log = 2 * av_log2(buf) - 31; buf >>= log; - LAST_SKIP_BITS(re, gb, 32 - log); - CLOSE_READER(re, gb); + bitstream_skip(bc, 32 - log); if (buf & 1) buf = -(buf >> 1); @@ -206,9 +189,9 @@ static inline int get_se_golomb(GetBitContext *gb) } } -static inline int get_se_golomb_long(GetBitContext *gb) +static inline int get_se_golomb_long(BitstreamContext *bc) { - unsigned int buf = get_ue_golomb_long(gb); + unsigned int buf = get_ue_golomb_long(bc); if (buf & 1) buf = (buf + 1) >> 1; @@ -218,25 +201,21 @@ static inline int get_se_golomb_long(GetBitContext *gb) return buf; } -static inline int get_interleaved_se_golomb(GetBitContext *gb) +static inline int get_interleaved_se_golomb(BitstreamContext *bc) { unsigned int buf; - OPEN_READER(re, gb); - UPDATE_CACHE(re, gb); - buf = GET_CACHE(re, gb); + buf = bitstream_peek(bc, 32); if (buf & 0xAA800000) { buf >>= 32 - 8; - LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]); - CLOSE_READER(re, gb); + bitstream_skip(bc, ff_interleaved_golomb_vlc_len[buf]); return ff_interleaved_se_golomb_vlc_code[buf]; } else { int log; - LAST_SKIP_BITS(re, gb, 8); - UPDATE_CACHE(re, gb); - buf |= 1 | (GET_CACHE(re, gb) >> 8); + bitstream_skip(bc, 8); + buf |= 1 | bitstream_peek(bc, 24); if ((buf & 0xAAAAAAAA) == 0) return INVALID_VLC; @@ -244,25 +223,20 @@ static inline int get_interleaved_se_golomb(GetBitContext *gb) for (log = 31; (buf & 0x80000000) == 0; log--) buf = (buf << 2) - ((buf << log) >> (log - 1)) + (buf >> 30); - LAST_SKIP_BITS(re, gb, 63 - 2 * log - 8); - CLOSE_READER(re, gb); + bitstream_skip(bc, 63 - 2 * log - 8); return (signed) (((((buf << log) >> log) - 1) ^ -(buf & 0x1)) + 1) >> 1; } } -static inline int dirac_get_se_golomb(GetBitContext *gb) +static inline int dirac_get_se_golomb(BitstreamContext *bc) { - uint32_t ret = get_interleaved_ue_golomb(gb); + uint32_t ret = get_interleaved_ue_golomb(bc); if (ret) { uint32_t buf; - OPEN_READER(re, gb); - UPDATE_CACHE(re, gb); - buf = SHOW_SBITS(re, gb, 1); - LAST_SKIP_BITS(re, gb, 1); + buf = bitstream_read_signed(bc, 1); ret = (ret ^ buf) - buf; - CLOSE_READER(re, gb); } return ret; @@ -271,33 +245,25 @@ static inline int dirac_get_se_golomb(GetBitContext *gb) /** * read unsigned golomb rice code (ffv1). */ -static inline int get_ur_golomb(GetBitContext *gb, int k, int limit, +static inline int get_ur_golomb(BitstreamContext *bc, int k, int limit, int esc_len) { unsigned int buf; int log; - OPEN_READER(re, gb); - UPDATE_CACHE(re, gb); - buf = GET_CACHE(re, gb); + buf = bitstream_peek(bc, 32); log = av_log2(buf); if (log > 31 - limit) { buf >>= log - k; buf += (30 - log) << k; - LAST_SKIP_BITS(re, gb, 32 + k - log); - CLOSE_READER(re, gb); + bitstream_skip(bc, 32 + k - log); return buf; } else { - LAST_SKIP_BITS(re, gb, limit); - UPDATE_CACHE(re, gb); - - buf = SHOW_UBITS(re, gb, esc_len); - - LAST_SKIP_BITS(re, gb, esc_len); - CLOSE_READER(re, gb); + bitstream_skip(bc, limit); + buf = bitstream_read(bc, esc_len); return buf + limit - 1; } @@ -306,48 +272,38 @@ static inline int get_ur_golomb(GetBitContext *gb, int k, int limit, /** * read unsigned golomb rice code (jpegls). */ -static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, +static inline int get_ur_golomb_jpegls(BitstreamContext *bc, int k, int limit, int esc_len) { unsigned int buf; int log; - OPEN_READER(re, gb); - UPDATE_CACHE(re, gb); - buf = GET_CACHE(re, gb); + buf = bitstream_peek(bc, 32); log = av_log2(buf); - if (log - k >= 32 - MIN_CACHE_BITS + (MIN_CACHE_BITS == 32) && - 32 - log < limit) { + if (log - k >= 1 && 32 - log < limit) { buf >>= log - k; buf += (30 - log) << k; - LAST_SKIP_BITS(re, gb, 32 + k - log); - CLOSE_READER(re, gb); + bitstream_skip(bc, 32 + k - log); return buf; } else { int i; - for (i = 0; i < limit && SHOW_UBITS(re, gb, 1) == 0 && BITS_AVAILABLE(re, gb); i++) { - LAST_SKIP_BITS(re, gb, 1); - UPDATE_CACHE(re, gb); - } - SKIP_BITS(re, gb, 1); + for (i = 0; i < limit && bitstream_peek(bc, 1) == 0 && bitstream_bits_left(bc) > 0; i++) + bitstream_skip(bc, 1); + bitstream_skip(bc, 1); if (i < limit - 1) { if (k) { - buf = SHOW_UBITS(re, gb, k); - LAST_SKIP_BITS(re, gb, k); + buf = bitstream_read(bc, k); } else { buf = 0; } - CLOSE_READER(re, gb); return buf + (i << k); } else if (i == limit - 1) { - buf = SHOW_UBITS(re, gb, esc_len); - LAST_SKIP_BITS(re, gb, esc_len); - CLOSE_READER(re, gb); + buf = bitstream_read(bc, esc_len); return buf + 1; } else @@ -358,10 +314,10 @@ static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, /** * read signed golomb rice code (ffv1). */ -static inline int get_sr_golomb(GetBitContext *gb, int k, int limit, +static inline int get_sr_golomb(BitstreamContext *bc, int k, int limit, int esc_len) { - int v = get_ur_golomb(gb, k, limit, esc_len); + int v = get_ur_golomb(bc, k, limit, esc_len); v++; if (v & 1) @@ -375,27 +331,27 @@ static inline int get_sr_golomb(GetBitContext *gb, int k, int limit, /** * read signed golomb rice code (flac). */ -static inline int get_sr_golomb_flac(GetBitContext *gb, int k, int limit, +static inline int get_sr_golomb_flac(BitstreamContext *bc, int k, int limit, int esc_len) { - int v = get_ur_golomb_jpegls(gb, k, limit, esc_len); + int v = get_ur_golomb_jpegls(bc, k, limit, esc_len); return (v >> 1) ^ -(v & 1); } /** * read unsigned golomb rice code (shorten). */ -static inline unsigned int get_ur_golomb_shorten(GetBitContext *gb, int k) +static inline unsigned int get_ur_golomb_shorten(BitstreamContext *bc, int k) { - return get_ur_golomb_jpegls(gb, k, INT_MAX, 0); + return get_ur_golomb_jpegls(bc, k, INT_MAX, 0); } /** * read signed golomb rice code (shorten). */ -static inline int get_sr_golomb_shorten(GetBitContext *gb, int k) +static inline int get_sr_golomb_shorten(BitstreamContext *bc, int k) { - int uvar = get_ur_golomb_jpegls(gb, k + 1, INT_MAX, 0); + int uvar = get_ur_golomb_jpegls(bc, k + 1, INT_MAX, 0); if (uvar & 1) return ~(uvar >> 1); else @@ -404,13 +360,13 @@ static inline int get_sr_golomb_shorten(GetBitContext *gb, int k) #ifdef TRACE -static inline int get_ue(GetBitContext *s, const char *file, const char *func, +static inline int get_ue(BitstreamContext *s, const char *file, const char *func, int line) { - int show = show_bits(s, 24); - int pos = get_bits_count(s); + int show = bitstream_peek(s, 24); + int pos = bitstream_tell(s); int i = get_ue_golomb(s); - int len = get_bits_count(s) - pos; + int len = bitstream_tell(s) - pos; int bits = show >> (24 - len); av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d ue @%5d in %s %s:%d\n", @@ -419,13 +375,13 @@ static inline int get_ue(GetBitContext *s, const char *file, const char *func, return i; } -static inline int get_se(GetBitContext *s, const char *file, const char *func, +static inline int get_se(BitstreamContext *s, const char *file, const char *func, int line) { - int show = show_bits(s, 24); - int pos = get_bits_count(s); + int show = bitstream_peek(s, 24); + int pos = bitstream_tell(s); int i = get_se_golomb(s); - int len = get_bits_count(s) - pos; + int len = bitstream_tell(s) - pos; int bits = show >> (24 - len); av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d se @%5d in %s %s:%d\n", @@ -434,13 +390,13 @@ static inline int get_se(GetBitContext *s, const char *file, const char *func, return i; } -static inline int get_te(GetBitContext *s, int r, char *file, const char *func, +static inline int get_te(BitstreamContext *s, int r, char *file, const char *func, int line) { - int show = show_bits(s, 24); - int pos = get_bits_count(s); + int show = bitstream_peek(s, 24); + int pos = bitstream_tell(s); int i = get_te0_golomb(s, r); - int len = get_bits_count(s) - pos; + int len = bitstream_tell(s) - pos; int bits = show >> (24 - len); av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d te @%5d in %s %s:%d\n", diff --git a/libavcodec/golomb_legacy.h b/libavcodec/golomb_legacy.h new file mode 100644 index 0000000000000..9fafbcda70b71 --- /dev/null +++ b/libavcodec/golomb_legacy.h @@ -0,0 +1,573 @@ +/* + * exp golomb vlc stuff + * Copyright (c) 2003 Michael Niedermayer + * Copyright (c) 2004 Alex Beregszaszi + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @brief + * exp golomb vlc stuff + * @author Michael Niedermayer and Alex Beregszaszi + */ + +#ifndef AVCODEC_GOLOMB_H +#define AVCODEC_GOLOMB_H + +#include + +#include "get_bits.h" +#include "put_bits.h" + +#define INVALID_VLC 0x80000000 + +extern const uint8_t ff_golomb_vlc_len[512]; +extern const uint8_t ff_ue_golomb_vlc_code[512]; +extern const int8_t ff_se_golomb_vlc_code[512]; +extern const uint8_t ff_ue_golomb_len[256]; + +extern const uint8_t ff_interleaved_golomb_vlc_len[256]; +extern const uint8_t ff_interleaved_ue_golomb_vlc_code[256]; +extern const int8_t ff_interleaved_se_golomb_vlc_code[256]; +extern const uint8_t ff_interleaved_dirac_golomb_vlc_code[256]; + +/** + * read unsigned exp golomb code. + */ +static inline int get_ue_golomb(GetBitContext *gb) +{ + unsigned int buf; + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf = GET_CACHE(re, gb); + + if (buf >= (1 << 27)) { + buf >>= 32 - 9; + LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]); + CLOSE_READER(re, gb); + + return ff_ue_golomb_vlc_code[buf]; + } else { + int log = 2 * av_log2(buf) - 31; + buf >>= log; + buf--; + LAST_SKIP_BITS(re, gb, 32 - log); + CLOSE_READER(re, gb); + + return buf; + } +} + +/** + * Read an unsigned Exp-Golomb code in the range 0 to UINT32_MAX-1. + */ +static inline unsigned get_ue_golomb_long(GetBitContext *gb) +{ + unsigned buf, log; + + buf = show_bits_long(gb, 32); + log = 31 - av_log2(buf); + skip_bits_long(gb, log); + + return get_bits_long(gb, log + 1) - 1; +} + +/** + * read unsigned exp golomb code, constraint to a max of 31. + * the return value is undefined if the stored value exceeds 31. + */ +static inline int get_ue_golomb_31(GetBitContext *gb) +{ + unsigned int buf; + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf = GET_CACHE(re, gb); + + buf >>= 32 - 9; + LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]); + CLOSE_READER(re, gb); + + return ff_ue_golomb_vlc_code[buf]; +} + +static inline unsigned get_interleaved_ue_golomb(GetBitContext *gb) +{ + uint32_t buf; + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf = GET_CACHE(re, gb); + + if (buf & 0xAA800000) { + buf >>= 32 - 8; + LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]); + CLOSE_READER(re, gb); + + return ff_interleaved_ue_golomb_vlc_code[buf]; + } else { + unsigned ret = 1; + + do { + buf >>= 32 - 8; + LAST_SKIP_BITS(re, gb, + FFMIN(ff_interleaved_golomb_vlc_len[buf], 8)); + + if (ff_interleaved_golomb_vlc_len[buf] != 9) { + ret <<= (ff_interleaved_golomb_vlc_len[buf] - 1) >> 1; + ret |= ff_interleaved_dirac_golomb_vlc_code[buf]; + break; + } + ret = (ret << 4) | ff_interleaved_dirac_golomb_vlc_code[buf]; + UPDATE_CACHE(re, gb); + buf = GET_CACHE(re, gb); + } while (BITS_AVAILABLE(re, gb)); + + CLOSE_READER(re, gb); + return ret - 1; + } +} + +/** + * read unsigned truncated exp golomb code. + */ +static inline int get_te0_golomb(GetBitContext *gb, int range) +{ + assert(range >= 1); + + if (range == 1) + return 0; + else if (range == 2) + return get_bits1(gb) ^ 1; + else + return get_ue_golomb(gb); +} + +/** + * read unsigned truncated exp golomb code. + */ +static inline int get_te_golomb(GetBitContext *gb, int range) +{ + assert(range >= 1); + + if (range == 2) + return get_bits1(gb) ^ 1; + else + return get_ue_golomb(gb); +} + +/** + * read signed exp golomb code. + */ +static inline int get_se_golomb(GetBitContext *gb) +{ + unsigned int buf; + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf = GET_CACHE(re, gb); + + if (buf >= (1 << 27)) { + buf >>= 32 - 9; + LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]); + CLOSE_READER(re, gb); + + return ff_se_golomb_vlc_code[buf]; + } else { + int log = 2 * av_log2(buf) - 31; + buf >>= log; + + LAST_SKIP_BITS(re, gb, 32 - log); + CLOSE_READER(re, gb); + + if (buf & 1) + buf = -(buf >> 1); + else + buf = (buf >> 1); + + return buf; + } +} + +static inline int get_se_golomb_long(GetBitContext *gb) +{ + unsigned int buf = get_ue_golomb_long(gb); + + if (buf & 1) + buf = (buf + 1) >> 1; + else + buf = -(buf >> 1); + + return buf; +} + +static inline int get_interleaved_se_golomb(GetBitContext *gb) +{ + unsigned int buf; + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf = GET_CACHE(re, gb); + + if (buf & 0xAA800000) { + buf >>= 32 - 8; + LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]); + CLOSE_READER(re, gb); + + return ff_interleaved_se_golomb_vlc_code[buf]; + } else { + int log; + LAST_SKIP_BITS(re, gb, 8); + UPDATE_CACHE(re, gb); + buf |= 1 | (GET_CACHE(re, gb) >> 8); + + if ((buf & 0xAAAAAAAA) == 0) + return INVALID_VLC; + + for (log = 31; (buf & 0x80000000) == 0; log--) + buf = (buf << 2) - ((buf << log) >> (log - 1)) + (buf >> 30); + + LAST_SKIP_BITS(re, gb, 63 - 2 * log - 8); + CLOSE_READER(re, gb); + + return (signed) (((((buf << log) >> log) - 1) ^ -(buf & 0x1)) + 1) >> 1; + } +} + +static inline int dirac_get_se_golomb(GetBitContext *gb) +{ + uint32_t ret = get_interleaved_ue_golomb(gb); + + if (ret) { + uint32_t buf; + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf = SHOW_SBITS(re, gb, 1); + LAST_SKIP_BITS(re, gb, 1); + ret = (ret ^ buf) - buf; + CLOSE_READER(re, gb); + } + + return ret; +} + +/** + * read unsigned golomb rice code (ffv1). + */ +static inline int get_ur_golomb(GetBitContext *gb, int k, int limit, + int esc_len) +{ + unsigned int buf; + int log; + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf = GET_CACHE(re, gb); + + log = av_log2(buf); + + if (log > 31 - limit) { + buf >>= log - k; + buf += (30 - log) << k; + LAST_SKIP_BITS(re, gb, 32 + k - log); + CLOSE_READER(re, gb); + + return buf; + } else { + LAST_SKIP_BITS(re, gb, limit); + UPDATE_CACHE(re, gb); + + buf = SHOW_UBITS(re, gb, esc_len); + + LAST_SKIP_BITS(re, gb, esc_len); + CLOSE_READER(re, gb); + + return buf + limit - 1; + } +} + +/** + * read unsigned golomb rice code (jpegls). + */ +static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, + int esc_len) +{ + unsigned int buf; + int log; + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf = GET_CACHE(re, gb); + + log = av_log2(buf); + + if (log - k >= 32 - MIN_CACHE_BITS + (MIN_CACHE_BITS == 32) && + 32 - log < limit) { + buf >>= log - k; + buf += (30 - log) << k; + LAST_SKIP_BITS(re, gb, 32 + k - log); + CLOSE_READER(re, gb); + + return buf; + } else { + int i; + for (i = 0; i < limit && SHOW_UBITS(re, gb, 1) == 0 && BITS_AVAILABLE(re, gb); i++) { + LAST_SKIP_BITS(re, gb, 1); + UPDATE_CACHE(re, gb); + } + SKIP_BITS(re, gb, 1); + + if (i < limit - 1) { + if (k) { + buf = SHOW_UBITS(re, gb, k); + LAST_SKIP_BITS(re, gb, k); + } else { + buf = 0; + } + + CLOSE_READER(re, gb); + return buf + (i << k); + } else if (i == limit - 1) { + buf = SHOW_UBITS(re, gb, esc_len); + LAST_SKIP_BITS(re, gb, esc_len); + CLOSE_READER(re, gb); + + return buf + 1; + } else + return -1; + } +} + +/** + * read signed golomb rice code (ffv1). + */ +static inline int get_sr_golomb(GetBitContext *gb, int k, int limit, + int esc_len) +{ + int v = get_ur_golomb(gb, k, limit, esc_len); + + v++; + if (v & 1) + return v >> 1; + else + return -(v >> 1); + +// return (v>>1) ^ -(v&1); +} + +/** + * read signed golomb rice code (flac). + */ +static inline int get_sr_golomb_flac(GetBitContext *gb, int k, int limit, + int esc_len) +{ + int v = get_ur_golomb_jpegls(gb, k, limit, esc_len); + return (v >> 1) ^ -(v & 1); +} + +/** + * read unsigned golomb rice code (shorten). + */ +static inline unsigned int get_ur_golomb_shorten(GetBitContext *gb, int k) +{ + return get_ur_golomb_jpegls(gb, k, INT_MAX, 0); +} + +/** + * read signed golomb rice code (shorten). + */ +static inline int get_sr_golomb_shorten(GetBitContext *gb, int k) +{ + int uvar = get_ur_golomb_jpegls(gb, k + 1, INT_MAX, 0); + if (uvar & 1) + return ~(uvar >> 1); + else + return uvar >> 1; +} + +#ifdef TRACE + +static inline int get_ue(GetBitContext *s, const char *file, const char *func, + int line) +{ + int show = show_bits(s, 24); + int pos = get_bits_count(s); + int i = get_ue_golomb(s); + int len = get_bits_count(s) - pos; + int bits = show >> (24 - len); + + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d ue @%5d in %s %s:%d\n", + bits, len, i, pos, file, func, line); + + return i; +} + +static inline int get_se(GetBitContext *s, const char *file, const char *func, + int line) +{ + int show = show_bits(s, 24); + int pos = get_bits_count(s); + int i = get_se_golomb(s); + int len = get_bits_count(s) - pos; + int bits = show >> (24 - len); + + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d se @%5d in %s %s:%d\n", + bits, len, i, pos, file, func, line); + + return i; +} + +static inline int get_te(GetBitContext *s, int r, char *file, const char *func, + int line) +{ + int show = show_bits(s, 24); + int pos = get_bits_count(s); + int i = get_te0_golomb(s, r); + int len = get_bits_count(s) - pos; + int bits = show >> (24 - len); + + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d te @%5d in %s %s:%d\n", + bits, len, i, pos, file, func, line); + + return i; +} + +#define get_ue_golomb(a) get_ue(a, __FILE__, __func__, __LINE__) +#define get_se_golomb(a) get_se(a, __FILE__, __func__, __LINE__) +#define get_te_golomb(a, r) get_te(a, r, __FILE__, __func__, __LINE__) +#define get_te0_golomb(a, r) get_te(a, r, __FILE__, __func__, __LINE__) + +#endif /* TRACE */ + +/** + * write unsigned exp golomb code. + */ +static inline void set_ue_golomb(PutBitContext *pb, int i) +{ + assert(i >= 0); + + if (i < 256) + put_bits(pb, ff_ue_golomb_len[i], i + 1); + else { + int e = av_log2(i + 1); + put_bits(pb, 2 * e + 1, i + 1); + } +} + +/** + * write truncated unsigned exp golomb code. + */ +static inline void set_te_golomb(PutBitContext *pb, int i, int range) +{ + assert(range >= 1); + assert(i <= range); + + if (range == 2) + put_bits(pb, 1, i ^ 1); + else + set_ue_golomb(pb, i); +} + +/** + * write signed exp golomb code. 16 bits at most. + */ +static inline void set_se_golomb(PutBitContext *pb, int i) +{ + i = 2 * i - 1; + if (i < 0) + i ^= -1; //FIXME check if gcc does the right thing + set_ue_golomb(pb, i); +} + +/** + * write unsigned golomb rice code (ffv1). + */ +static inline void set_ur_golomb(PutBitContext *pb, int i, int k, int limit, + int esc_len) +{ + int e; + + assert(i >= 0); + + e = i >> k; + if (e < limit) + put_bits(pb, e + k + 1, (1 << k) + (i & ((1 << k) - 1))); + else + put_bits(pb, limit + esc_len, i - limit + 1); +} + +/** + * write unsigned golomb rice code (jpegls). + */ +static inline void set_ur_golomb_jpegls(PutBitContext *pb, int i, int k, + int limit, int esc_len) +{ + int e; + + assert(i >= 0); + + e = (i >> k) + 1; + if (e < limit) { + while (e > 31) { + put_bits(pb, 31, 0); + e -= 31; + } + put_bits(pb, e, 1); + if (k) + put_sbits(pb, k, i); + } else { + while (limit > 31) { + put_bits(pb, 31, 0); + limit -= 31; + } + put_bits(pb, limit, 1); + put_bits(pb, esc_len, i - 1); + } +} + +/** + * write signed golomb rice code (ffv1). + */ +static inline void set_sr_golomb(PutBitContext *pb, int i, int k, int limit, + int esc_len) +{ + int v; + + v = -2 * i - 1; + v ^= (v >> 31); + + set_ur_golomb(pb, v, k, limit, esc_len); +} + +/** + * write signed golomb rice code (flac). + */ +static inline void set_sr_golomb_flac(PutBitContext *pb, int i, int k, + int limit, int esc_len) +{ + int v; + + v = -2 * i - 1; + v ^= (v >> 31); + + set_ur_golomb_jpegls(pb, v, k, limit, esc_len); +} + +#endif /* AVCODEC_GOLOMB_H */ diff --git a/libavcodec/h264_cavlc.c b/libavcodec/h264_cavlc.c index 4fa2de01844ae..9b950ede20a04 100644 --- a/libavcodec/h264_cavlc.c +++ b/libavcodec/h264_cavlc.c @@ -32,7 +32,7 @@ #include "h264dec.h" #include "h264_mvpred.h" #include "h264data.h" -#include "golomb.h" +#include "golomb_legacy.h" #include "mpegutils.h" #include diff --git a/libavcodec/h264_parse.c b/libavcodec/h264_parse.c index d694558ecc53a..cde46fa9eb580 100644 --- a/libavcodec/h264_parse.c +++ b/libavcodec/h264_parse.c @@ -18,7 +18,7 @@ #include "bytestream.h" #include "get_bits.h" -#include "golomb.h" +#include "golomb_legacy.h" #include "h264.h" #include "h264dec.h" #include "h264_parse.h" diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c index b4da123e943d6..6de37c0b55db2 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -36,7 +36,7 @@ #include "avcodec.h" #include "get_bits.h" -#include "golomb.h" +#include "golomb_legacy.h" #include "h264.h" #include "h264_sei.h" #include "h264_ps.h" diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c index 7ee3876c8bdad..b3a0e8a7ed4fe 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -28,12 +28,13 @@ #include #include "libavutil/imgutils.h" + +#include "golomb_legacy.h" #include "internal.h" #include "mathops.h" #include "avcodec.h" #include "h264data.h" #include "h264_ps.h" -#include "golomb.h" #define MAX_LOG2_MAX_FRAME_NUM (12 + 4) #define MIN_LOG2_MAX_FRAME_NUM 4 diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c index 3c55998424f0b..b4dc49cc41452 100644 --- a/libavcodec/h264_refs.c +++ b/libavcodec/h264_refs.c @@ -27,11 +27,11 @@ #include +#include "golomb_legacy.h" #include "internal.h" #include "avcodec.h" #include "h264.h" #include "h264dec.h" -#include "golomb.h" #include "mpegutils.h" #include diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c index 7eef3ee9627d4..4bf001ae07420 100644 --- a/libavcodec/h264_sei.c +++ b/libavcodec/h264_sei.c @@ -27,7 +27,7 @@ #include "avcodec.h" #include "get_bits.h" -#include "golomb.h" +#include "golomb_legacy.h" #include "h264_ps.h" #include "h264_sei.h" #include "internal.h" diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 3749d1f2caceb..f1f5fc05f9c00 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -34,6 +34,7 @@ #include "cabac.h" #include "cabac_functions.h" #include "error_resilience.h" +#include "golomb_legacy.h" #include "avcodec.h" #include "h264.h" #include "h264dec.h" @@ -41,7 +42,6 @@ #include "h264chroma.h" #include "h264_mvpred.h" #include "h264_ps.h" -#include "golomb.h" #include "mathops.h" #include "mpegutils.h" #include "rectangle.h" diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 834c60c38c7e3..5137039188bc2 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -36,6 +36,7 @@ #include "cabac_functions.h" #include "error_resilience.h" #include "avcodec.h" +#include "golomb_legacy.h" #include "h264.h" #include "h264dec.h" #include "h2645_parse.h" @@ -43,7 +44,6 @@ #include "h264chroma.h" #include "h264_mvpred.h" #include "h264_ps.h" -#include "golomb.h" #include "mathops.h" #include "me_cmp.h" #include "mpegutils.h" diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c index 74a0257073d13..5129e3a9c1e46 100644 --- a/libavcodec/hevc_parser.c +++ b/libavcodec/hevc_parser.c @@ -22,7 +22,7 @@ #include "libavutil/common.h" -#include "golomb.h" +#include "golomb_legacy.h" #include "hevc.h" #include "hevcdec.h" #include "h2645_parse.h" diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index 4a5a47e20e50e..3c98e4ce443a2 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -25,7 +25,7 @@ #include "libavutil/imgutils.h" -#include "golomb.h" +#include "golomb_legacy.h" #include "hevc_data.h" #include "hevc_ps.h" diff --git a/libavcodec/hevc_ps_enc.c b/libavcodec/hevc_ps_enc.c index 4864e6ebfc6fa..1fb93b3020791 100644 --- a/libavcodec/hevc_ps_enc.c +++ b/libavcodec/hevc_ps_enc.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "golomb.h" +#include "golomb_legacy.h" #include "hevc_ps.h" #include "put_bits.h" diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c index 8c913f93a7494..1f8554ad5fe52 100644 --- a/libavcodec/hevc_sei.c +++ b/libavcodec/hevc_sei.c @@ -22,7 +22,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "golomb.h" +#include "golomb_legacy.h" #include "hevcdec.h" enum HEVC_SEI_TYPE { diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index dcb2453a20a79..e24ce1e3c092f 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -35,7 +35,7 @@ #include "bswapdsp.h" #include "bytestream.h" #include "cabac_functions.h" -#include "golomb.h" +#include "golomb_legacy.h" #include "hevc.h" #include "hevc_data.h" #include "hevcdec.h" diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c index 9f8ccecec6c27..8d1e7631133c4 100644 --- a/libavcodec/jpeglsdec.c +++ b/libavcodec/jpeglsdec.c @@ -27,7 +27,7 @@ #include "avcodec.h" #include "get_bits.h" -#include "golomb.h" +#include "golomb_legacy.h" #include "internal.h" #include "mathops.h" #include "mjpeg.h" diff --git a/libavcodec/jpeglsenc.c b/libavcodec/jpeglsenc.c index cb9b71e4cd70c..fb3c69f2f988c 100644 --- a/libavcodec/jpeglsenc.c +++ b/libavcodec/jpeglsenc.c @@ -27,7 +27,7 @@ #include "avcodec.h" #include "get_bits.h" -#include "golomb.h" +#include "golomb_legacy.h" #include "internal.h" #include "mathops.h" #include "mjpeg.h" diff --git a/libavcodec/loco.c b/libavcodec/loco.c index f25ef61f37346..8624ea86ad50e 100644 --- a/libavcodec/loco.c +++ b/libavcodec/loco.c @@ -26,7 +26,7 @@ #include "avcodec.h" #include "get_bits.h" -#include "golomb.h" +#include "golomb_legacy.h" #include "internal.h" #include "mathops.h" diff --git a/libavcodec/ralf.c b/libavcodec/ralf.c index 9812837570ca5..6bc0f3fa0d397 100644 --- a/libavcodec/ralf.c +++ b/libavcodec/ralf.c @@ -30,7 +30,7 @@ #include "libavutil/channel_layout.h" #include "avcodec.h" #include "get_bits.h" -#include "golomb.h" +#include "golomb_legacy.h" #include "internal.h" #include "unary_legacy.h" #include "ralfdata.h" diff --git a/libavcodec/rv30.c b/libavcodec/rv30.c index 7218fa36dce4f..77e875bac9c3a 100644 --- a/libavcodec/rv30.c +++ b/libavcodec/rv30.c @@ -25,9 +25,9 @@ */ #include "avcodec.h" +#include "golomb_legacy.h" #include "mpegutils.h" #include "mpegvideo.h" -#include "golomb.h" #include "rv34.h" #include "rv30data.h" diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c index 4220195a52de0..9fb0760ccbdc4 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -28,9 +28,9 @@ #include "avcodec.h" #include "error_resilience.h" +#include "golomb_legacy.h" #include "mpegutils.h" #include "mpegvideo.h" -#include "golomb.h" #include "internal.h" #include "mathops.h" #include "mpeg_er.h" diff --git a/libavcodec/rv40.c b/libavcodec/rv40.c index 0da13124d6da3..d46a44a5dd73d 100644 --- a/libavcodec/rv40.c +++ b/libavcodec/rv40.c @@ -27,9 +27,9 @@ #include "libavutil/imgutils.h" #include "avcodec.h" +#include "golomb_legacy.h" #include "mpegutils.h" #include "mpegvideo.h" -#include "golomb.h" #include "rv34.h" #include "rv40vlc2.h" diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c index 00d166177996c..82fa2ab94317e 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -29,7 +29,7 @@ #include "avcodec.h" #include "bytestream.h" #include "get_bits.h" -#include "golomb.h" +#include "golomb_legacy.h" #include "internal.h" #define MAX_CHANNELS 8 diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index 51657372ae8cf..8bbd331de3fbf 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -43,12 +43,13 @@ #include #include "libavutil/attributes.h" + +#include "golomb_legacy.h" #include "internal.h" #include "avcodec.h" #include "mpegutils.h" #include "h264dec.h" #include "h264data.h" -#include "golomb.h" #include "hpeldsp.h" #include "mathops.h" #include "rectangle.h" diff --git a/libavcodec/tests/golomb.c b/libavcodec/tests/golomb.c index 7587402e2483f..d8fff71ca3cf3 100644 --- a/libavcodec/tests/golomb.c +++ b/libavcodec/tests/golomb.c @@ -21,7 +21,7 @@ #include "libavutil/mem.h" -#include "libavcodec/get_bits.h" +#include "libavcodec/bitstream.h" #include "libavcodec/put_bits.h" #include "libavcodec/golomb.h" @@ -33,7 +33,7 @@ int main(void) int i, ret = 0; uint8_t *temp; PutBitContext pb; - GetBitContext gb; + BitstreamContext bc; temp = av_malloc(SIZE); if (!temp) @@ -44,11 +44,11 @@ int main(void) set_ue_golomb(&pb, i); flush_put_bits(&pb); - init_get_bits(&gb, temp, 8 * SIZE); + bitstream_init8(&bc, temp, SIZE); for (i = 0; i < COUNT; i++) { - int j, s = show_bits(&gb, 25); + int j, s = bitstream_peek(&bc, 25); - j = get_ue_golomb(&gb); + j = get_ue_golomb(&bc); if (j != i) { fprintf(stderr, "get_ue_golomb: expected %d, got %d. bits: %7x\n", i, j, s); @@ -62,11 +62,11 @@ int main(void) set_ue_golomb(&pb, EXTEND(i)); flush_put_bits(&pb); - init_get_bits(&gb, temp, 8 * SIZE); + bitstream_init8(&bc, temp, SIZE); for (i = 0; i < COUNT; i++) { - int j, s = show_bits_long(&gb, 32); + int j, s = bitstream_peek(&bc, 32); - j = get_ue_golomb_long(&gb); + j = get_ue_golomb_long(&bc); if (j != EXTEND(i)) { fprintf(stderr, "get_ue_golomb_long: expected %d, got %d. " "bits: %8x\n", EXTEND(i), j, s); @@ -79,11 +79,11 @@ int main(void) set_se_golomb(&pb, i - COUNT / 2); flush_put_bits(&pb); - init_get_bits(&gb, temp, 8 * SIZE); + bitstream_init8(&bc, temp, SIZE); for (i = 0; i < COUNT; i++) { - int j, s = show_bits(&gb, 25); + int j, s = bitstream_peek(&bc, 25); - j = get_se_golomb(&gb); + j = get_se_golomb(&bc); if (j != i - COUNT / 2) { fprintf(stderr, "get_se_golomb: expected %d, got %d. bits: %7x\n", i - COUNT / 2, j, s); diff --git a/libavformat/hevc.c b/libavformat/hevc.c index 62eefc6d29061..057f6517ffe7e 100644 --- a/libavformat/hevc.c +++ b/libavformat/hevc.c @@ -20,7 +20,7 @@ #include "libavcodec/avcodec.h" #include "libavcodec/get_bits.h" -#include "libavcodec/golomb.h" +#include "libavcodec/golomb_legacy.h" #include "libavcodec/hevc.h" #include "libavutil/intreadwrite.h" #include "avc.h" From 0c89ff82e9ddc68ec92316d786cd8ddc7b6c2b8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 23 Apr 2016 15:19:08 +0200 Subject: [PATCH 0839/3374] aic: Convert to the new bitstream reader --- libavcodec/aic.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/libavcodec/aic.c b/libavcodec/aic.c index 405ebf12d54b0..368b3bcf23a64 100644 --- a/libavcodec/aic.c +++ b/libavcodec/aic.c @@ -23,13 +23,13 @@ #include #include "avcodec.h" +#include "bitstream.h" #include "bytestream.h" +#include "golomb.h" #include "internal.h" -#include "get_bits.h" -#include "golomb_legacy.h" #include "idctdsp.h" #include "thread.h" -#include "unary_legacy.h" +#include "unary.h" #define AIC_HDR_SIZE 24 #define AIC_BAND_COEFFS (64 + 32 + 192 + 96) @@ -191,14 +191,14 @@ static int aic_decode_header(AICContext *ctx, const uint8_t *src, int size) #define GET_CODE(val, type, add_bits) \ do { \ if (type) \ - val = get_ue_golomb(gb); \ + val = get_ue_golomb(bc); \ else \ - val = get_unary(gb, 1, 31); \ + val = get_unary(bc, 1, 31); \ if (add_bits) \ - val = (val << add_bits) + get_bits(gb, add_bits); \ + val = (val << add_bits) + bitstream_read(bc, add_bits); \ } while (0) -static int aic_decode_coeffs(GetBitContext *gb, int16_t *dst, +static int aic_decode_coeffs(BitstreamContext *bc, int16_t *dst, int band, int slice_width, int force_chroma) { int has_skips, coeff_type, coeff_bits, skip_type, skip_bits; @@ -206,13 +206,13 @@ static int aic_decode_coeffs(GetBitContext *gb, int16_t *dst, const uint8_t *scan = aic_scan[band | force_chroma]; int mb, idx, val; - has_skips = get_bits1(gb); - coeff_type = get_bits1(gb); - coeff_bits = get_bits(gb, 3); + has_skips = bitstream_read_bit(bc); + coeff_type = bitstream_read_bit(bc); + coeff_bits = bitstream_read(bc, 3); if (has_skips) { - skip_type = get_bits1(gb); - skip_bits = get_bits(gb, 3); + skip_type = bitstream_read_bit(bc); + skip_bits = bitstream_read(bc, 3); for (mb = 0; mb < slice_width; mb++) { idx = -1; @@ -303,7 +303,7 @@ static void unquant_block(int16_t *block, int q) static int aic_decode_slice(AICContext *ctx, int mb_x, int mb_y, const uint8_t *src, int src_size) { - GetBitContext gb; + BitstreamContext bc; int ret, i, mb, blk; int slice_width = FFMIN(ctx->slice_width, ctx->mb_width - mb_x); uint8_t *Y, *C[2]; @@ -318,12 +318,12 @@ static int aic_decode_slice(AICContext *ctx, int mb_x, int mb_y, for (i = 0; i < 2; i++) C[i] = ctx->frame->data[i + 1] + mb_x * 8 + mb_y * 8 * ctx->frame->linesize[i + 1]; - init_get_bits(&gb, src, src_size * 8); + bitstream_init8(&bc, src, src_size); memset(ctx->slice_data, 0, sizeof(*ctx->slice_data) * slice_width * AIC_BAND_COEFFS); for (i = 0; i < NUM_BANDS; i++) - if ((ret = aic_decode_coeffs(&gb, ctx->data_ptr[i], + if ((ret = aic_decode_coeffs(&bc, ctx->data_ptr[i], i, slice_width, !ctx->interlaced)) < 0) return ret; From ffc00df0a61b656b3c2ba199c9d153b7787caefa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 19 Mar 2016 12:39:03 +0100 Subject: [PATCH 0840/3374] cavs: Convert to the new bitstream reader --- libavcodec/cavs.c | 8 +- libavcodec/cavs.h | 4 +- libavcodec/cavsdec.c | 178 +++++++++++++++++++++---------------------- 3 files changed, 95 insertions(+), 95 deletions(-) diff --git a/libavcodec/cavs.c b/libavcodec/cavs.c index bf1a59a6f0f69..6959f54404635 100644 --- a/libavcodec/cavs.c +++ b/libavcodec/cavs.c @@ -26,8 +26,8 @@ */ #include "avcodec.h" -#include "get_bits.h" -#include "golomb_legacy.h" +#include "bitstream.h" +#include "golomb.h" #include "h264chroma.h" #include "idctdsp.h" #include "internal.h" @@ -603,8 +603,8 @@ void ff_cavs_mv(AVSContext *h, enum cavs_mv_loc nP, enum cavs_mv_loc nC, mv_pred_median(h, mvP, mvA, mvB, mvC); if (mode < MV_PRED_PSKIP) { - mvP->x += get_se_golomb(&h->gb); - mvP->y += get_se_golomb(&h->gb); + mvP->x += get_se_golomb(&h->bc); + mvP->y += get_se_golomb(&h->bc); } set_mvs(mvP, size); } diff --git a/libavcodec/cavs.h b/libavcodec/cavs.h index e8729d50cdfe6..cb549f161ec3c 100644 --- a/libavcodec/cavs.h +++ b/libavcodec/cavs.h @@ -22,11 +22,11 @@ #ifndef AVCODEC_CAVS_H #define AVCODEC_CAVS_H +#include "bitstream.h" #include "cavsdsp.h" #include "blockdsp.h" #include "h264chroma.h" #include "idctdsp.h" -#include "get_bits.h" #include "videodsp.h" #define SLICE_MAX_START_CODE 0x000001af @@ -167,7 +167,7 @@ typedef struct AVSContext { IDCTDSPContext idsp; VideoDSPContext vdsp; CAVSDSPContext cdsp; - GetBitContext gb; + BitstreamContext bc; AVSFrame cur; ///< currently decoded frame AVSFrame DPB[2]; ///< reference frames int dist[2]; ///< temporal distances from current frame to ref frames diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c index 5a28fc04eda75..7f584ac1c0ddc 100644 --- a/libavcodec/cavsdec.c +++ b/libavcodec/cavsdec.c @@ -26,9 +26,9 @@ */ #include "avcodec.h" -#include "get_bits.h" -#include "golomb_legacy.h" +#include "bitstream.h" #include "cavs.h" +#include "golomb.h" #include "internal.h" #include "mpeg12data.h" @@ -506,13 +506,13 @@ static inline void mv_pred_sym(AVSContext *h, cavs_vector *src, ****************************************************************************/ /** kth-order exponential golomb code */ -static inline int get_ue_code(GetBitContext *gb, int order) +static inline int get_ue_code(BitstreamContext *bc, int order) { if (order) { - int ret = get_ue_golomb(gb) << order; - return ret + get_bits(gb, order); + int ret = get_ue_golomb(bc) << order; + return ret + bitstream_read(bc, order); } - return get_ue_golomb(gb); + return get_ue_golomb(bc); } static inline int dequant(AVSContext *h, int16_t *level_buf, uint8_t *run_buf, @@ -545,7 +545,7 @@ static inline int dequant(AVSContext *h, int16_t *level_buf, uint8_t *run_buf, * @param dst location of sample block * @param stride line stride in frame buffer */ -static int decode_residual_block(AVSContext *h, GetBitContext *gb, +static int decode_residual_block(AVSContext *h, BitstreamContext *bc, const struct dec_2dvlc *r, int esc_golomb_order, int qp, uint8_t *dst, ptrdiff_t stride) { @@ -555,10 +555,10 @@ static int decode_residual_block(AVSContext *h, GetBitContext *gb, int16_t *block = h->block; for (i = 0;i < 65; i++) { - level_code = get_ue_code(gb, r->golomb_order); + level_code = get_ue_code(bc, r->golomb_order); if (level_code >= ESCAPE_CODE) { run = ((level_code - ESCAPE_CODE) >> 1) + 1; - esc_code = get_ue_code(gb, esc_golomb_order); + esc_code = get_ue_code(bc, esc_golomb_order); level = esc_code + (run > r->max_run ? 1 : r->level_add[run]); while (level > r->inc_limit) r++; @@ -588,10 +588,10 @@ static int decode_residual_block(AVSContext *h, GetBitContext *gb, static inline void decode_residual_chroma(AVSContext *h) { if (h->cbp & (1 << 4)) - decode_residual_block(h, &h->gb, chroma_dec, 0, + decode_residual_block(h, &h->bc, chroma_dec, 0, cavs_chroma_qp[h->qp], h->cu, h->c_stride); if (h->cbp & (1 << 5)) - decode_residual_block(h, &h->gb, chroma_dec, 0, + decode_residual_block(h, &h->bc, chroma_dec, 0, cavs_chroma_qp[h->qp], h->cv, h->c_stride); } @@ -600,7 +600,7 @@ static inline int decode_residual_inter(AVSContext *h) int block; /* get coded block pattern */ - int cbp = get_ue_golomb(&h->gb); + int cbp = get_ue_golomb(&h->bc); if (cbp > 63 || cbp < 0) { av_log(h->avctx, AV_LOG_ERROR, "illegal inter cbp %d\n", cbp); return AVERROR_INVALIDDATA; @@ -609,10 +609,10 @@ static inline int decode_residual_inter(AVSContext *h) /* get quantizer */ if (h->cbp && !h->qp_fixed) - h->qp = (h->qp + get_se_golomb(&h->gb)) & 63; + h->qp = (h->qp + get_se_golomb(&h->bc)) & 63; for (block = 0; block < 4; block++) if (h->cbp & (1 << block)) - decode_residual_block(h, &h->gb, inter_dec, 0, h->qp, + decode_residual_block(h, &h->bc, inter_dec, 0, h->qp, h->cy + h->luma_scan[block], h->l_stride); decode_residual_chroma(h); @@ -637,7 +637,7 @@ static inline void set_mv_intra(AVSContext *h) static int decode_mb_i(AVSContext *h, int cbp_code) { - GetBitContext *gb = &h->gb; + BitstreamContext *bc = &h->bc; unsigned pred_mode_uv; int block; uint8_t top[18]; @@ -656,13 +656,13 @@ static int decode_mb_i(AVSContext *h, int cbp_code) predpred = FFMIN(nA, nB); if (predpred == NOT_AVAIL) // if either is not available predpred = INTRA_L_LP; - if (!get_bits1(gb)) { - int rem_mode = get_bits(gb, 2); + if (!bitstream_read_bit(bc)) { + int rem_mode = bitstream_read(bc, 2); predpred = rem_mode + (rem_mode >= predpred); } h->pred_mode_Y[pos] = predpred; } - pred_mode_uv = get_ue_golomb(gb); + pred_mode_uv = get_ue_golomb(bc); if (pred_mode_uv > 6) { av_log(h->avctx, AV_LOG_ERROR, "illegal intra chroma pred mode\n"); return AVERROR_INVALIDDATA; @@ -671,14 +671,14 @@ static int decode_mb_i(AVSContext *h, int cbp_code) /* get coded block pattern */ if (h->cur.f->pict_type == AV_PICTURE_TYPE_I) - cbp_code = get_ue_golomb(gb); + cbp_code = get_ue_golomb(bc); if (cbp_code > 63 || cbp_code < 0) { av_log(h->avctx, AV_LOG_ERROR, "illegal intra cbp\n"); return AVERROR_INVALIDDATA; } h->cbp = cbp_tab[cbp_code][0]; if (h->cbp && !h->qp_fixed) - h->qp = (h->qp + get_se_golomb(gb)) & 63; //qp_delta + h->qp = (h->qp + get_se_golomb(bc)) & 63; // qp_delta /* luma intra prediction interleaved with residual decode/transform/add */ for (block = 0; block < 4; block++) { @@ -687,7 +687,7 @@ static int decode_mb_i(AVSContext *h, int cbp_code) h->intra_pred_l[h->pred_mode_Y[scan3x3[block]]] (d, top, left, h->l_stride); if (h->cbp & (1<qp, d, h->l_stride); + decode_residual_block(h, bc, intra_dec, 1, h->qp, d, h->l_stride); } /* chroma intra prediction */ @@ -716,7 +716,7 @@ static inline void set_intra_mode_default(AVSContext *h) static void decode_mb_p(AVSContext *h, enum cavs_mb mb_type) { - GetBitContext *gb = &h->gb; + BitstreamContext *bc = &h->bc; int ref[4]; ff_cavs_init_mb(h); @@ -725,26 +725,26 @@ static void decode_mb_p(AVSContext *h, enum cavs_mb mb_type) ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_PSKIP, BLK_16X16, 0); break; case P_16X16: - ref[0] = h->ref_flag ? 0 : get_bits1(gb); + ref[0] = h->ref_flag ? 0 : bitstream_read_bit(bc); ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_MEDIAN, BLK_16X16, ref[0]); break; case P_16X8: - ref[0] = h->ref_flag ? 0 : get_bits1(gb); - ref[2] = h->ref_flag ? 0 : get_bits1(gb); + ref[0] = h->ref_flag ? 0 : bitstream_read_bit(bc); + ref[2] = h->ref_flag ? 0 : bitstream_read_bit(bc); ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_TOP, BLK_16X8, ref[0]); ff_cavs_mv(h, MV_FWD_X2, MV_FWD_A1, MV_PRED_LEFT, BLK_16X8, ref[2]); break; case P_8X16: - ref[0] = h->ref_flag ? 0 : get_bits1(gb); - ref[1] = h->ref_flag ? 0 : get_bits1(gb); + ref[0] = h->ref_flag ? 0 : bitstream_read_bit(bc); + ref[1] = h->ref_flag ? 0 : bitstream_read_bit(bc); ff_cavs_mv(h, MV_FWD_X0, MV_FWD_B3, MV_PRED_LEFT, BLK_8X16, ref[0]); ff_cavs_mv(h, MV_FWD_X1, MV_FWD_C2, MV_PRED_TOPRIGHT, BLK_8X16, ref[1]); break; case P_8X8: - ref[0] = h->ref_flag ? 0 : get_bits1(gb); - ref[1] = h->ref_flag ? 0 : get_bits1(gb); - ref[2] = h->ref_flag ? 0 : get_bits1(gb); - ref[3] = h->ref_flag ? 0 : get_bits1(gb); + ref[0] = h->ref_flag ? 0 : bitstream_read_bit(bc); + ref[1] = h->ref_flag ? 0 : bitstream_read_bit(bc); + ref[2] = h->ref_flag ? 0 : bitstream_read_bit(bc); + ref[3] = h->ref_flag ? 0 : bitstream_read_bit(bc); ff_cavs_mv(h, MV_FWD_X0, MV_FWD_B3, MV_PRED_MEDIAN, BLK_8X8, ref[0]); ff_cavs_mv(h, MV_FWD_X1, MV_FWD_C2, MV_PRED_MEDIAN, BLK_8X8, ref[1]); ff_cavs_mv(h, MV_FWD_X2, MV_FWD_X1, MV_PRED_MEDIAN, BLK_8X8, ref[2]); @@ -797,7 +797,7 @@ static void decode_mb_b(AVSContext *h, enum cavs_mb mb_type) break; case B_8X8: for (block = 0; block < 4; block++) - sub_type[block] = get_bits(&h->gb, 2); + sub_type[block] = bitstream_read(&h->bc, 2); for (block = 0; block < 4; block++) { switch (sub_type[block]) { case B_SUB_DIRECT: @@ -874,7 +874,7 @@ static void decode_mb_b(AVSContext *h, enum cavs_mb mb_type) * ****************************************************************************/ -static inline int decode_slice_header(AVSContext *h, GetBitContext *gb) +static inline int decode_slice_header(AVSContext *h, BitstreamContext *bc) { if (h->stc > 0xAF) av_log(h->avctx, AV_LOG_ERROR, "unexpected start code 0x%02x\n", h->stc); @@ -884,13 +884,13 @@ static inline int decode_slice_header(AVSContext *h, GetBitContext *gb) /* mark top macroblocks as unavailable */ h->flags &= ~(B_AVAIL | C_AVAIL); if ((h->mby == 0) && (!h->qp_fixed)) { - h->qp_fixed = get_bits1(gb); - h->qp = get_bits(gb, 6); + h->qp_fixed = bitstream_read_bit(bc); + h->qp = bitstream_read(bc, 6); } /* inter frame or second slice can have weighting params */ if ((h->cur.f->pict_type != AV_PICTURE_TYPE_I) || (!h->pic_structure && h->mby >= h->mb_width / 2)) - if (get_bits1(gb)) { //slice_weighting_flag + if (bitstream_read_bit(bc)) { // slice_weighting_flag av_log(h->avctx, AV_LOG_ERROR, "weighted prediction not yet supported\n"); } @@ -899,21 +899,21 @@ static inline int decode_slice_header(AVSContext *h, GetBitContext *gb) static inline int check_for_slice(AVSContext *h) { - GetBitContext *gb = &h->gb; + BitstreamContext *bc = &h->bc; int align; if (h->mbx) return 0; - align = (-get_bits_count(gb)) & 7; + align = (-bitstream_tell(bc)) & 7; /* check for stuffing byte */ - if (!align && (show_bits(gb, 8) == 0x80)) + if (!align && (bitstream_peek(bc, 8) == 0x80)) align = 8; - if ((show_bits_long(gb, 24 + align) & 0xFFFFFF) == 0x000001) { - skip_bits_long(gb, 24 + align); - h->stc = get_bits(gb, 8); + if ((bitstream_peek(bc, 24 + align) & 0xFFFFFF) == 0x000001) { + bitstream_skip(bc, 24 + align); + h->stc = bitstream_read(bc, 8); if (h->stc >= h->mb_height) return 0; - decode_slice_header(h, gb); + decode_slice_header(h, bc); return 1; } return 0; @@ -938,9 +938,9 @@ static int decode_pic(AVSContext *h) av_frame_unref(h->cur.f); - skip_bits(&h->gb, 16);//bbv_dwlay + bitstream_skip(&h->bc, 16); // bbv_dwlay if (h->stc == PIC_PB_START_CODE) { - h->cur.f->pict_type = get_bits(&h->gb, 2) + AV_PICTURE_TYPE_I; + h->cur.f->pict_type = bitstream_read(&h->bc, 2) + AV_PICTURE_TYPE_I; if (h->cur.f->pict_type > AV_PICTURE_TYPE_B) { av_log(h->avctx, AV_LOG_ERROR, "illegal picture type\n"); return AVERROR_INVALIDDATA; @@ -951,17 +951,17 @@ static int decode_pic(AVSContext *h) return AVERROR_INVALIDDATA; } else { h->cur.f->pict_type = AV_PICTURE_TYPE_I; - if (get_bits1(&h->gb)) - skip_bits(&h->gb, 24);//time_code + if (bitstream_read_bit(&h->bc)) + bitstream_skip(&h->bc, 24); // time_code /* old sample clips were all progressive and no low_delay, bump stream revision if detected otherwise */ - if (h->low_delay || !(show_bits(&h->gb, 9) & 1)) + if (h->low_delay || !(bitstream_peek(&h->bc, 9) & 1)) h->stream_revision = 1; /* similarly test top_field_first and repeat_first_field */ - else if (show_bits(&h->gb, 11) & 3) + else if (bitstream_peek(&h->bc, 11) & 3) h->stream_revision = 1; if (h->stream_revision > 0) - skip_bits(&h->gb, 1); //marker_bit + bitstream_skip(&h->bc, 1); // marker_bit } ret = ff_get_buffer(h->avctx, h->cur.f, h->cur.f->pict_type == AV_PICTURE_TYPE_B ? @@ -977,7 +977,7 @@ static int decode_pic(AVSContext *h) } ff_cavs_init_pic(h); - h->cur.poc = get_bits(&h->gb, 8) * 2; + h->cur.poc = bitstream_read(&h->bc, 8) * 2; /* get temporal distances and MV scaling factors */ if (h->cur.f->pict_type != AV_PICTURE_TYPE_B) { @@ -996,31 +996,31 @@ static int decode_pic(AVSContext *h) } if (h->low_delay) - get_ue_golomb(&h->gb); //bbv_check_times - h->progressive = get_bits1(&h->gb); + get_ue_golomb(&h->bc); // bbv_check_times + h->progressive = bitstream_read_bit(&h->bc); h->pic_structure = 1; if (!h->progressive) - h->pic_structure = get_bits1(&h->gb); + h->pic_structure = bitstream_read_bit(&h->bc); if (!h->pic_structure && h->stc == PIC_PB_START_CODE) - skip_bits1(&h->gb); //advanced_pred_mode_disable - skip_bits1(&h->gb); //top_field_first - skip_bits1(&h->gb); //repeat_first_field - h->qp_fixed = get_bits1(&h->gb); - h->qp = get_bits(&h->gb, 6); + bitstream_skip(&h->bc, 1); // advanced_pred_mode_disable + bitstream_skip(&h->bc, 1); // top_field_first + bitstream_skip(&h->bc, 1); // repeat_first_field + h->qp_fixed = bitstream_read_bit(&h->bc); + h->qp = bitstream_read(&h->bc, 6); if (h->cur.f->pict_type == AV_PICTURE_TYPE_I) { if (!h->progressive && !h->pic_structure) - skip_bits1(&h->gb);//what is this? - skip_bits(&h->gb, 4); //reserved bits + bitstream_skip(&h->bc, 1); // what is this? + bitstream_skip(&h->bc, 4); // reserved bits } else { if (!(h->cur.f->pict_type == AV_PICTURE_TYPE_B && h->pic_structure == 1)) - h->ref_flag = get_bits1(&h->gb); - skip_bits(&h->gb, 4); //reserved bits - h->skip_mode_flag = get_bits1(&h->gb); + h->ref_flag = bitstream_read_bit(&h->bc); + bitstream_skip(&h->bc, 4); // reserved bits + h->skip_mode_flag = bitstream_read_bit(&h->bc); } - h->loop_filter_disable = get_bits1(&h->gb); - if (!h->loop_filter_disable && get_bits1(&h->gb)) { - h->alpha_offset = get_se_golomb(&h->gb); - h->beta_offset = get_se_golomb(&h->gb); + h->loop_filter_disable = bitstream_read_bit(&h->bc); + if (!h->loop_filter_disable && bitstream_read_bit(&h->bc)) { + h->alpha_offset = get_se_golomb(&h->bc); + h->beta_offset = get_se_golomb(&h->bc); } else { h->alpha_offset = h->beta_offset = 0; } @@ -1034,11 +1034,11 @@ static int decode_pic(AVSContext *h) if (check_for_slice(h)) skip_count = -1; if (h->skip_mode_flag && (skip_count < 0)) - skip_count = get_ue_golomb(&h->gb); + skip_count = get_ue_golomb(&h->bc); if (h->skip_mode_flag && skip_count--) { decode_mb_p(h, P_SKIP); } else { - mb_type = get_ue_golomb(&h->gb) + P_SKIP + h->skip_mode_flag; + mb_type = get_ue_golomb(&h->bc) + P_SKIP + h->skip_mode_flag; if (mb_type > P_8X8) decode_mb_i(h, mb_type - P_8X8 - 1); else @@ -1050,11 +1050,11 @@ static int decode_pic(AVSContext *h) if (check_for_slice(h)) skip_count = -1; if (h->skip_mode_flag && (skip_count < 0)) - skip_count = get_ue_golomb(&h->gb); + skip_count = get_ue_golomb(&h->bc); if (h->skip_mode_flag && skip_count--) { decode_mb_b(h, B_SKIP); } else { - mb_type = get_ue_golomb(&h->gb) + B_SKIP + h->skip_mode_flag; + mb_type = get_ue_golomb(&h->bc) + B_SKIP + h->skip_mode_flag; if (mb_type > B_8X8) decode_mb_i(h, mb_type - B_8X8 - 1); else @@ -1081,12 +1081,12 @@ static int decode_seq_header(AVSContext *h) int frame_rate_code; int width, height; - h->profile = get_bits(&h->gb, 8); - h->level = get_bits(&h->gb, 8); - skip_bits1(&h->gb); //progressive sequence + h->profile = bitstream_read(&h->bc, 8); + h->level = bitstream_read(&h->bc, 8); + bitstream_skip(&h->bc, 1); // progressive sequence - width = get_bits(&h->gb, 14); - height = get_bits(&h->gb, 14); + width = bitstream_read(&h->bc, 14); + height = bitstream_read(&h->bc, 14); if ((h->width || h->height) && (h->width != width || h->height != height)) { avpriv_report_missing_feature(h->avctx, "Width/height changing in CAVS"); @@ -1095,14 +1095,14 @@ static int decode_seq_header(AVSContext *h) h->width = width; h->height = height; - skip_bits(&h->gb, 2); //chroma format - skip_bits(&h->gb, 3); //sample_precision - h->aspect_ratio = get_bits(&h->gb, 4); - frame_rate_code = get_bits(&h->gb, 4); - skip_bits(&h->gb, 18); //bit_rate_lower - skip_bits1(&h->gb); //marker_bit - skip_bits(&h->gb, 12); //bit_rate_upper - h->low_delay = get_bits1(&h->gb); + bitstream_skip(&h->bc, 2); // chroma format + bitstream_skip(&h->bc, 3); // sample_precision + h->aspect_ratio = bitstream_read(&h->bc, 4); + frame_rate_code = bitstream_read(&h->bc, 4); + bitstream_skip(&h->bc, 18); // bit_rate_lower + bitstream_skip(&h->bc, 1); // marker_bit + bitstream_skip(&h->bc, 12); // bit_rate_upper + h->low_delay = bitstream_read_bit(&h->bc); h->mb_width = (h->width + 15) >> 4; h->mb_height = (h->height + 15) >> 4; h->avctx->framerate = ff_mpeg12_frame_rate_tab[frame_rate_code]; @@ -1147,7 +1147,7 @@ static int cavs_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, input_size = (buf_end - buf_ptr) * 8; switch (stc) { case CAVS_START_CODE: - init_get_bits(&h->gb, buf_ptr, input_size); + bitstream_init(&h->bc, buf_ptr, input_size); decode_seq_header(h); break; case PIC_I_START_CODE: @@ -1160,7 +1160,7 @@ static int cavs_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, *got_frame = 0; if (!h->got_keyframe) break; - init_get_bits(&h->gb, buf_ptr, input_size); + bitstream_init(&h->bc, buf_ptr, input_size); h->stc = stc; if (decode_pic(h)) break; @@ -1184,8 +1184,8 @@ static int cavs_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, break; default: if (stc <= SLICE_MAX_START_CODE) { - init_get_bits(&h->gb, buf_ptr, input_size); - decode_slice_header(h, &h->gb); + bitstream_init(&h->bc, buf_ptr, input_size); + decode_slice_header(h, &h->bc); } break; } From 6b1f559f9a0667390259374c738132ad9475fd39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 19 Mar 2016 15:39:03 +0100 Subject: [PATCH 0841/3374] dirac: Convert to the new bitstream reader --- libavcodec/dirac.c | 89 +++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 44 deletions(-) diff --git a/libavcodec/dirac.c b/libavcodec/dirac.c index cce9439d44f6a..5faf0a384d95e 100644 --- a/libavcodec/dirac.c +++ b/libavcodec/dirac.c @@ -28,8 +28,9 @@ #include "libavutil/imgutils.h" #include "avcodec.h" +#include "bitstream.h" #include "dirac.h" -#include "golomb_legacy.h" +#include "golomb.h" #include "internal.h" #include "mpeg12data.h" @@ -138,7 +139,7 @@ static const enum AVPixelFormat dirac_pix_fmt[2][3] = { /* [DIRAC_STD] 10.3 Parse Source Parameters. * source_parameters(base_video_format) */ -static int parse_source_parameters(AVDiracSeqHeader *dsh, GetBitContext *gb, +static int parse_source_parameters(AVDiracSeqHeader *dsh, BitstreamContext *bc, void *log_ctx) { AVRational frame_rate = { 0, 0 }; @@ -147,17 +148,17 @@ static int parse_source_parameters(AVDiracSeqHeader *dsh, GetBitContext *gb, /* [DIRAC_STD] 10.3.2 Frame size. frame_size(video_params) */ /* [DIRAC_STD] custom_dimensions_flag */ - if (get_bits1(gb)) { - dsh->width = get_interleaved_ue_golomb(gb); /* [DIRAC_STD] FRAME_WIDTH */ - dsh->height = get_interleaved_ue_golomb(gb); /* [DIRAC_STD] FRAME_HEIGHT */ + if (bitstream_read_bit(bc)) { + dsh->width = get_interleaved_ue_golomb(bc); /* [DIRAC_STD] FRAME_WIDTH */ + dsh->height = get_interleaved_ue_golomb(bc); /* [DIRAC_STD] FRAME_HEIGHT */ } /* [DIRAC_STD] 10.3.3 Chroma Sampling Format. * chroma_sampling_format(video_params) */ /* [DIRAC_STD] custom_chroma_format_flag */ - if (get_bits1(gb)) + if (bitstream_read_bit(bc)) /* [DIRAC_STD] CHROMA_FORMAT_INDEX */ - dsh->chroma_format = get_interleaved_ue_golomb(gb); + dsh->chroma_format = get_interleaved_ue_golomb(bc); if (dsh->chroma_format > 2) { if (log_ctx) av_log(log_ctx, AV_LOG_ERROR, "Unknown chroma format %d\n", @@ -167,24 +168,24 @@ static int parse_source_parameters(AVDiracSeqHeader *dsh, GetBitContext *gb, /* [DIRAC_STD] 10.3.4 Scan Format. scan_format(video_params) */ /* [DIRAC_STD] custom_scan_format_flag */ - if (get_bits1(gb)) + if (bitstream_read_bit(bc)) /* [DIRAC_STD] SOURCE_SAMPLING */ - dsh->interlaced = get_interleaved_ue_golomb(gb); + dsh->interlaced = get_interleaved_ue_golomb(bc); if (dsh->interlaced > 1) return AVERROR_INVALIDDATA; /* [DIRAC_STD] 10.3.5 Frame Rate. frame_rate(video_params) */ - if (get_bits1(gb)) { /* [DIRAC_STD] custom_frame_rate_flag */ - dsh->frame_rate_index = get_interleaved_ue_golomb(gb); + if (bitstream_read_bit(bc)) { /* [DIRAC_STD] custom_frame_rate_flag */ + dsh->frame_rate_index = get_interleaved_ue_golomb(bc); if (dsh->frame_rate_index > 10) return AVERROR_INVALIDDATA; if (!dsh->frame_rate_index) { /* [DIRAC_STD] FRAME_RATE_NUMER */ - frame_rate.num = get_interleaved_ue_golomb(gb); + frame_rate.num = get_interleaved_ue_golomb(bc); /* [DIRAC_STD] FRAME_RATE_DENOM */ - frame_rate.den = get_interleaved_ue_golomb(gb); + frame_rate.den = get_interleaved_ue_golomb(bc); } } /* [DIRAC_STD] preset_frame_rate(video_params, index) */ @@ -199,16 +200,16 @@ static int parse_source_parameters(AVDiracSeqHeader *dsh, GetBitContext *gb, /* [DIRAC_STD] 10.3.6 Pixel Aspect Ratio. * pixel_aspect_ratio(video_params) */ - if (get_bits1(gb)) { /* [DIRAC_STD] custom_pixel_aspect_ratio_flag */ + if (bitstream_read_bit(bc)) { /* [DIRAC_STD] custom_pixel_aspect_ratio_flag */ /* [DIRAC_STD] index */ - dsh->aspect_ratio_index = get_interleaved_ue_golomb(gb); + dsh->aspect_ratio_index = get_interleaved_ue_golomb(bc); if (dsh->aspect_ratio_index > 6) return AVERROR_INVALIDDATA; if (!dsh->aspect_ratio_index) { - dsh->sample_aspect_ratio.num = get_interleaved_ue_golomb(gb); - dsh->sample_aspect_ratio.den = get_interleaved_ue_golomb(gb); + dsh->sample_aspect_ratio.num = get_interleaved_ue_golomb(bc); + dsh->sample_aspect_ratio.den = get_interleaved_ue_golomb(bc); } } /* [DIRAC_STD] Take value from Table 10.4 Available preset pixel @@ -218,33 +219,33 @@ static int parse_source_parameters(AVDiracSeqHeader *dsh, GetBitContext *gb, dirac_preset_aspect_ratios[dsh->aspect_ratio_index - 1]; /* [DIRAC_STD] 10.3.7 Clean area. clean_area(video_params) */ - if (get_bits1(gb)) { /* [DIRAC_STD] custom_clean_area_flag */ + if (bitstream_read_bit(bc)) { /* [DIRAC_STD] custom_clean_area_flag */ /* [DIRAC_STD] CLEAN_WIDTH */ - dsh->clean_width = get_interleaved_ue_golomb(gb); + dsh->clean_width = get_interleaved_ue_golomb(bc); /* [DIRAC_STD] CLEAN_HEIGHT */ - dsh->clean_height = get_interleaved_ue_golomb(gb); + dsh->clean_height = get_interleaved_ue_golomb(bc); /* [DIRAC_STD] CLEAN_LEFT_OFFSET */ - dsh->clean_left_offset = get_interleaved_ue_golomb(gb); + dsh->clean_left_offset = get_interleaved_ue_golomb(bc); /* [DIRAC_STD] CLEAN_RIGHT_OFFSET */ - dsh->clean_right_offset = get_interleaved_ue_golomb(gb); + dsh->clean_right_offset = get_interleaved_ue_golomb(bc); } /* [DIRAC_STD] 10.3.8 Signal range. signal_range(video_params) * WARNING: Some adaptation seems to be done using the * AVCOL_RANGE_MPEG/JPEG values */ - if (get_bits1(gb)) { /* [DIRAC_STD] custom_signal_range_flag */ + if (bitstream_read_bit(bc)) { /* [DIRAC_STD] custom_signal_range_flag */ /* [DIRAC_STD] index */ - dsh->pixel_range_index = get_interleaved_ue_golomb(gb); + dsh->pixel_range_index = get_interleaved_ue_golomb(bc); if (dsh->pixel_range_index > 4) return AVERROR_INVALIDDATA; // This assumes either fullrange or MPEG levels only if (!dsh->pixel_range_index) { - luma_offset = get_interleaved_ue_golomb(gb); - luma_depth = av_log2(get_interleaved_ue_golomb(gb)) + 1; - get_interleaved_ue_golomb(gb); /* chroma offset */ - get_interleaved_ue_golomb(gb); /* chroma excursion */ + luma_offset = get_interleaved_ue_golomb(bc); + luma_depth = av_log2(get_interleaved_ue_golomb(bc)) + 1; + get_interleaved_ue_golomb(bc); /* chroma offset */ + get_interleaved_ue_golomb(bc); /* chroma excursion */ dsh->color_range = luma_offset ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; } @@ -263,9 +264,9 @@ static int parse_source_parameters(AVDiracSeqHeader *dsh, GetBitContext *gb, dsh->pix_fmt = dirac_pix_fmt[!luma_offset][dsh->chroma_format]; /* [DIRAC_STD] 10.3.9 Colour specification. colour_spec(video_params) */ - if (get_bits1(gb)) { /* [DIRAC_STD] custom_colour_spec_flag */ + if (bitstream_read_bit(bc)) { /* [DIRAC_STD] custom_colour_spec_flag */ /* [DIRAC_STD] index */ - idx = dsh->color_spec_index = get_interleaved_ue_golomb(gb); + idx = dsh->color_spec_index = get_interleaved_ue_golomb(bc); if (dsh->color_spec_index > 4) return AVERROR_INVALIDDATA; @@ -276,21 +277,21 @@ static int parse_source_parameters(AVDiracSeqHeader *dsh, GetBitContext *gb, if (!dsh->color_spec_index) { /* [DIRAC_STD] 10.3.9.1 Colour primaries */ - if (get_bits1(gb)) { - idx = get_interleaved_ue_golomb(gb); + if (bitstream_read_bit(bc)) { + idx = get_interleaved_ue_golomb(bc); if (idx < 3) dsh->color_primaries = dirac_primaries[idx]; } /* [DIRAC_STD] 10.3.9.2 Colour matrix */ - if (get_bits1(gb)) { - idx = get_interleaved_ue_golomb(gb); + if (bitstream_read_bit(bc)) { + idx = get_interleaved_ue_golomb(bc); if (!idx) dsh->colorspace = AVCOL_SPC_BT709; else if (idx == 1) dsh->colorspace = AVCOL_SPC_BT470BG; } /* [DIRAC_STD] 10.3.9.3 Transfer function */ - if (get_bits1(gb) && !get_interleaved_ue_golomb(gb)) + if (bitstream_read_bit(bc) && !get_interleaved_ue_golomb(bc)) dsh->color_trc = AVCOL_TRC_BT709; } } else { @@ -309,7 +310,7 @@ int av_dirac_parse_sequence_header(AVDiracSeqHeader **pdsh, void *log_ctx) { AVDiracSeqHeader *dsh; - GetBitContext gb; + BitstreamContext bc; unsigned version_major; unsigned video_format, picture_coding_mode; int ret; @@ -318,18 +319,18 @@ int av_dirac_parse_sequence_header(AVDiracSeqHeader **pdsh, if (!dsh) return AVERROR(ENOMEM); - ret = init_get_bits8(&gb, buf, buf_size); + ret = bitstream_init8(&bc, buf, buf_size); if (ret < 0) goto fail; /* [DIRAC_SPEC] 10.1 Parse Parameters. parse_parameters() */ - version_major = get_interleaved_ue_golomb(&gb); - get_interleaved_ue_golomb(&gb); /* version_minor */ - dsh->profile = get_interleaved_ue_golomb(&gb); - dsh->level = get_interleaved_ue_golomb(&gb); + version_major = get_interleaved_ue_golomb(&bc); + get_interleaved_ue_golomb(&bc); /* version_minor */ + dsh->profile = get_interleaved_ue_golomb(&bc); + dsh->level = get_interleaved_ue_golomb(&bc); /* [DIRAC_SPEC] sequence_header() -> base_video_format as defined in * 10.2 Base Video Format, table 10.1 Dirac predefined video formats */ - video_format = get_interleaved_ue_golomb(&gb); + video_format = get_interleaved_ue_golomb(&bc); if (log_ctx) { if (version_major < 2) @@ -360,13 +361,13 @@ int av_dirac_parse_sequence_header(AVDiracSeqHeader **pdsh, /* [DIRAC_STD] 10.3 Source Parameters * Override the defaults. */ - ret = parse_source_parameters(dsh, &gb, log_ctx); + ret = parse_source_parameters(dsh, &bc, log_ctx); if (ret < 0) goto fail; /* [DIRAC_STD] picture_coding_mode shall be 0 for fields and 1 for frames * currently only used to signal field coding */ - picture_coding_mode = get_interleaved_ue_golomb(&gb); + picture_coding_mode = get_interleaved_ue_golomb(&bc); if (picture_coding_mode != 0) { if (log_ctx) { av_log(log_ctx, AV_LOG_ERROR, "Unsupported picture coding mode %d", From 0f94de8a092b1a9f1fe45f830c0f134699c16de1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 19 Mar 2016 17:40:55 +0100 Subject: [PATCH 0842/3374] fic: Convert to the new bitstream reader --- libavcodec/fic.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libavcodec/fic.c b/libavcodec/fic.c index 180410491654e..a038af6e60353 100644 --- a/libavcodec/fic.c +++ b/libavcodec/fic.c @@ -24,9 +24,9 @@ #include "libavutil/common.h" #include "avcodec.h" -#include "golomb_legacy.h" +#include "bitstream.h" +#include "golomb.h" #include "internal.h" -#include "get_bits.h" typedef struct FICThreadContext { DECLARE_ALIGNED(16, int16_t, block)[64]; @@ -129,13 +129,13 @@ static void fic_idct_put(uint8_t *dst, int stride, int16_t *block) ptr += 8; } } -static int fic_decode_block(FICContext *ctx, GetBitContext *gb, +static int fic_decode_block(FICContext *ctx, BitstreamContext *bc, uint8_t *dst, int stride, int16_t *block) { int i, num_coeff; /* Is it a skip block? */ - if (get_bits1(gb)) { + if (bitstream_read_bit(bc)) { /* This is a P-frame. */ ctx->frame->key_frame = 0; ctx->frame->pict_type = AV_PICTURE_TYPE_P; @@ -145,12 +145,12 @@ static int fic_decode_block(FICContext *ctx, GetBitContext *gb, memset(block, 0, sizeof(*block) * 64); - num_coeff = get_bits(gb, 7); + num_coeff = bitstream_read(bc, 7); if (num_coeff > 64) return AVERROR_INVALIDDATA; for (i = 0; i < num_coeff; i++) - block[ff_zigzag_direct[i]] = get_se_golomb(gb) * + block[ff_zigzag_direct[i]] = get_se_golomb(bc) * ctx->qmat[ff_zigzag_direct[i]]; fic_idct_put(dst, stride, block); @@ -162,14 +162,14 @@ static int fic_decode_slice(AVCodecContext *avctx, void *tdata) { FICContext *ctx = avctx->priv_data; FICThreadContext *tctx = tdata; - GetBitContext gb; + BitstreamContext bc; uint8_t *src = tctx->src; int slice_h = tctx->slice_h; int src_size = tctx->src_size; int y_off = tctx->y_off; int x, y, p; - init_get_bits(&gb, src, src_size * 8); + bitstream_init8(&bc, src, src_size); for (p = 0; p < 3; p++) { int stride = ctx->frame->linesize[p]; @@ -179,7 +179,7 @@ static int fic_decode_slice(AVCodecContext *avctx, void *tdata) for (x = 0; x < (ctx->aligned_width >> !!p); x += 8) { int ret; - if ((ret = fic_decode_block(ctx, &gb, dst + x, stride, tctx->block)) != 0) + if ((ret = fic_decode_block(ctx, &bc, dst + x, stride, tctx->block)) != 0) return ret; } From d85b37a955317f176f3443a40859a21c15d7c3bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Mon, 21 Mar 2016 20:23:36 +0100 Subject: [PATCH 0843/3374] loco: Convert to the new bitstream reader --- libavcodec/loco.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libavcodec/loco.c b/libavcodec/loco.c index 8624ea86ad50e..fa4c5edb4097a 100644 --- a/libavcodec/loco.c +++ b/libavcodec/loco.c @@ -25,8 +25,8 @@ */ #include "avcodec.h" -#include "get_bits.h" -#include "golomb_legacy.h" +#include "bitstream.h" +#include "golomb.h" #include "internal.h" #include "mathops.h" @@ -50,7 +50,7 @@ typedef struct LOCOContext { } LOCOContext; typedef struct RICEContext { - GetBitContext gb; + BitstreamContext bc; int save, run, run2; /* internal rice decoder state */ int sum, count; /* sum and count for getting rice parameter */ int lossy; @@ -88,11 +88,11 @@ static inline int loco_get_rice(RICEContext *r) loco_update_rice_param(r, 0); return 0; } - v = get_ur_golomb_jpegls(&r->gb, loco_get_rice_param(r), INT_MAX, 0); + v = get_ur_golomb_jpegls(&r->bc, loco_get_rice_param(r), INT_MAX, 0); loco_update_rice_param(r, (v + 1) >> 1); if (!v) { if (r->save >= 0) { - r->run = get_ur_golomb_jpegls(&r->gb, 2, INT_MAX, 0); + r->run = get_ur_golomb_jpegls(&r->bc, 2, INT_MAX, 0); if (r->run > 1) r->save += r->run + 1; else @@ -132,7 +132,7 @@ static int loco_decode_plane(LOCOContext *l, uint8_t *data, int width, int heigh int val; int i, j; - init_get_bits(&rc.gb, buf, buf_size*8); + bitstream_init8(&rc.bc, buf, buf_size); rc.save = 0; rc.run = 0; rc.run2 = 0; @@ -162,7 +162,7 @@ static int loco_decode_plane(LOCOContext *l, uint8_t *data, int width, int heigh data += stride; } - return (get_bits_count(&rc.gb) + 7) >> 3; + return (bitstream_tell(&rc.bc) + 7) >> 3; } static int decode_frame(AVCodecContext *avctx, From 5a6da49dd0c078b7d20e130ab74f326abc4678a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Tue, 22 Mar 2016 10:26:03 +0100 Subject: [PATCH 0844/3374] ralf: Convert to the new bitstream reader --- libavcodec/ralf.c | 68 ++++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/libavcodec/ralf.c b/libavcodec/ralf.c index 6bc0f3fa0d397..1003b10c11d7f 100644 --- a/libavcodec/ralf.c +++ b/libavcodec/ralf.c @@ -28,11 +28,13 @@ #include "libavutil/attributes.h" #include "libavutil/channel_layout.h" + #include "avcodec.h" -#include "get_bits.h" -#include "golomb_legacy.h" +#include "bitstream.h" +#include "golomb.h" #include "internal.h" -#include "unary_legacy.h" +#include "unary.h" +#include "vlc.h" #include "ralfdata.h" #define FILTER_NONE 0 @@ -210,21 +212,21 @@ static av_cold int decode_init(AVCodecContext *avctx) return 0; } -static inline int extend_code(GetBitContext *gb, int val, int range, int bits) +static inline int extend_code(BitstreamContext *bc, int val, int range, int bits) { if (val == 0) { - val = -range - get_ue_golomb(gb); + val = -range - get_ue_golomb(bc); } else if (val == range * 2) { - val = range + get_ue_golomb(gb); + val = range + get_ue_golomb(bc); } else { val -= range; } if (bits) - val = (val << bits) | get_bits(gb, bits); + val = (val << bits) | bitstream_read(bc, bits); return val; } -static int decode_channel(RALFContext *ctx, GetBitContext *gb, int ch, +static int decode_channel(RALFContext *ctx, BitstreamContext *bc, int ch, int length, int mode, int bits) { int i, t; @@ -233,19 +235,19 @@ static int decode_channel(RALFContext *ctx, GetBitContext *gb, int ch, VLC *code_vlc; int range, range2, add_bits; int *dst = ctx->channel_data[ch]; - ctx->filter_params = get_vlc2(gb, set->filter_params.table, 9, 2); + ctx->filter_params = bitstream_read_vlc(bc, set->filter_params.table, 9, 2); ctx->filter_bits = (ctx->filter_params - 2) >> 6; ctx->filter_length = ctx->filter_params - (ctx->filter_bits << 6) - 1; if (ctx->filter_params == FILTER_RAW) { for (i = 0; i < length; i++) - dst[i] = get_bits(gb, bits); + dst[i] = bitstream_read(bc, bits); ctx->bias[ch] = 0; return 0; } - ctx->bias[ch] = get_vlc2(gb, set->bias.table, 9, 2); - ctx->bias[ch] = extend_code(gb, ctx->bias[ch], 127, 4); + ctx->bias[ch] = bitstream_read_vlc(bc, set->bias.table, 9, 2); + ctx->bias[ch] = extend_code(bc, ctx->bias[ch], 127, 4); if (ctx->filter_params == FILTER_NONE) { memset(dst, 0, sizeof(*dst) * length); @@ -259,8 +261,8 @@ static int decode_channel(RALFContext *ctx, GetBitContext *gb, int ch, add_bits = ctx->filter_bits; for (i = 0; i < ctx->filter_length; i++) { - t = get_vlc2(gb, vlc[cmode].table, vlc[cmode].bits, 2); - t = extend_code(gb, t, 21, add_bits); + t = bitstream_read_vlc(bc, vlc[cmode].table, vlc[cmode].bits, 2); + t = extend_code(bc, t, 21, add_bits); if (!cmode) coeff -= 12 << add_bits; coeff = t - coeff; @@ -279,7 +281,7 @@ static int decode_channel(RALFContext *ctx, GetBitContext *gb, int ch, } } - code_params = get_vlc2(gb, set->coding_mode.table, set->coding_mode.bits, 2); + code_params = bitstream_read_vlc(bc, set->coding_mode.table, set->coding_mode.bits, 2); if (code_params >= 15) { add_bits = av_clip((code_params / 5 - 3) / 2, 0, 10); if (add_bits > 9 && (code_params % 5) != 2) @@ -297,14 +299,14 @@ static int decode_channel(RALFContext *ctx, GetBitContext *gb, int ch, for (i = 0; i < length; i += 2) { int code1, code2; - t = get_vlc2(gb, code_vlc->table, code_vlc->bits, 2); + t = bitstream_read_vlc(bc, code_vlc->table, code_vlc->bits, 2); code1 = t / range2; code2 = t % range2; - dst[i] = extend_code(gb, code1, range, 0) << add_bits; - dst[i + 1] = extend_code(gb, code2, range, 0) << add_bits; + dst[i] = extend_code(bc, code1, range, 0) << add_bits; + dst[i + 1] = extend_code(bc, code2, range, 0) << add_bits; if (add_bits) { - dst[i] |= get_bits(gb, add_bits); - dst[i + 1] |= get_bits(gb, add_bits); + dst[i] |= bitstream_read(bc, add_bits); + dst[i + 1] |= bitstream_read(bc, add_bits); } } @@ -335,7 +337,7 @@ static void apply_lpc(RALFContext *ctx, int ch, int length, int bits) } } -static int decode_block(AVCodecContext *avctx, GetBitContext *gb, +static int decode_block(AVCodecContext *avctx, BitstreamContext *bc, int16_t *dst0, int16_t *dst1) { RALFContext *ctx = avctx->priv_data; @@ -344,7 +346,7 @@ static int decode_block(AVCodecContext *avctx, GetBitContext *gb, int *ch0, *ch1; int i, t, t2; - len = 12 - get_unary(gb, 0, 6); + len = 12 - get_unary(bc, 0, 6); if (len <= 7) len ^= 1; // codes for length = 6 and 7 are swapped len = 1 << len; @@ -356,7 +358,7 @@ static int decode_block(AVCodecContext *avctx, GetBitContext *gb, } if (avctx->channels > 1) - dmode = get_bits(gb, 2) + 1; + dmode = bitstream_read(bc, 2) + 1; else dmode = 0; @@ -366,13 +368,13 @@ static int decode_block(AVCodecContext *avctx, GetBitContext *gb, bits[1] = (mode[1] == 2) ? 17 : 16; for (ch = 0; ch < avctx->channels; ch++) { - if ((ret = decode_channel(ctx, gb, ch, len, mode[ch], bits[ch])) < 0) + if ((ret = decode_channel(ctx, bc, ch, len, mode[ch], bits[ch])) < 0) return ret; if (ctx->filter_params > 1 && ctx->filter_params != FILTER_RAW) { ctx->filter_bits += 3; apply_lpc(ctx, ch, len, bits[ch]); } - if (get_bits_left(gb) < 0) + if (bitstream_bits_left(bc) < 0) return AVERROR_INVALIDDATA; } ch0 = ctx->channel_data[0]; @@ -426,7 +428,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, int16_t *samples0; int16_t *samples1; int ret; - GetBitContext gb; + BitstreamContext bc; int table_size, table_bytes, i; const uint8_t *src, *block_pointer; int src_size; @@ -478,12 +480,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, av_log(avctx, AV_LOG_ERROR, "short packets are short!\n"); return AVERROR_INVALIDDATA; } - init_get_bits(&gb, src + 2, table_size); + bitstream_init(&bc, src + 2, table_size); ctx->num_blocks = 0; - while (get_bits_left(&gb) > 0) { - ctx->block_size[ctx->num_blocks] = get_bits(&gb, 15); - if (get_bits1(&gb)) { - ctx->block_pts[ctx->num_blocks] = get_bits(&gb, 9); + while (bitstream_bits_left(&bc) > 0) { + ctx->block_size[ctx->num_blocks] = bitstream_read(&bc, 15); + if (bitstream_read_bit(&bc)) { + ctx->block_pts[ctx->num_blocks] = bitstream_read(&bc, 9); } else { ctx->block_pts[ctx->num_blocks] = 0; } @@ -498,8 +500,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, av_log(avctx, AV_LOG_ERROR, "I'm pedaling backwards\n"); break; } - init_get_bits(&gb, block_pointer, ctx->block_size[i] * 8); - if (decode_block(avctx, &gb, samples0 + ctx->sample_offset, + bitstream_init8(&bc, block_pointer, ctx->block_size[i]); + if (decode_block(avctx, &bc, samples0 + ctx->sample_offset, samples1 + ctx->sample_offset) < 0) { av_log(avctx, AV_LOG_ERROR, "Sir, I got carsick in your office. Not decoding the rest of packet.\n"); break; From 2b94ed12de7b6b7f444ed67e1a7068141af3d4ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Tue, 22 Mar 2016 16:09:39 +0100 Subject: [PATCH 0845/3374] shorten: Convert to the new bitstream reader --- libavcodec/shorten.c | 49 ++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c index 82fa2ab94317e..e040b9cfedab2 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -26,10 +26,11 @@ */ #include + #include "avcodec.h" +#include "bitstream.h" #include "bytestream.h" -#include "get_bits.h" -#include "golomb_legacy.h" +#include "golomb.h" #include "internal.h" #define MAX_CHANNELS 8 @@ -79,7 +80,7 @@ static const uint8_t is_audio_command[10] = { 1, 1, 1, 1, 0, 0, 0, 1, 1, 0 }; typedef struct ShortenContext { AVCodecContext *avctx; - GetBitContext gb; + BitstreamContext bc; int min_framesize, max_framesize; unsigned channels; @@ -154,8 +155,8 @@ static int allocate_buffers(ShortenContext *s) static inline unsigned int get_uint(ShortenContext *s, int k) { if (s->version != 0) - k = get_ur_golomb_shorten(&s->gb, ULONGSIZE); - return get_ur_golomb_shorten(&s->gb, k); + k = get_ur_golomb_shorten(&s->bc, ULONGSIZE); + return get_ur_golomb_shorten(&s->bc, k); } static void fix_bitshift(ShortenContext *s, int32_t *buffer) @@ -280,7 +281,7 @@ static int decode_subframe_lpc(ShortenContext *s, int command, int channel, if (command == FN_QLPC) { /* read/validate prediction order */ - pred_order = get_ur_golomb_shorten(&s->gb, LPCQSIZE); + pred_order = get_ur_golomb_shorten(&s->bc, LPCQSIZE); if (pred_order > s->nwrap) { av_log(s->avctx, AV_LOG_ERROR, "invalid pred_order %d\n", pred_order); @@ -288,7 +289,7 @@ static int decode_subframe_lpc(ShortenContext *s, int command, int channel, } /* read LPC coefficients */ for (i = 0; i < pred_order; i++) - s->coeffs[i] = get_sr_golomb_shorten(&s->gb, LPCQUANT); + s->coeffs[i] = get_sr_golomb_shorten(&s->bc, LPCQUANT); coeffs = s->coeffs; qshift = LPCQUANT; @@ -315,7 +316,7 @@ static int decode_subframe_lpc(ShortenContext *s, int command, int channel, sum = init_sum; for (j = 0; j < pred_order; j++) sum += coeffs[j] * s->decoded[channel][i - j - 1]; - s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + + s->decoded[channel][i] = get_sr_golomb_shorten(&s->bc, residual_size) + (sum >> qshift); } @@ -332,7 +333,7 @@ static int read_header(ShortenContext *s) int i, ret; int maxnlpc = 0; /* shorten signature */ - if (get_bits_long(&s->gb, 32) != AV_RB32("ajkg")) { + if (bitstream_read(&s->bc, 32) != AV_RB32("ajkg")) { av_log(s->avctx, AV_LOG_ERROR, "missing shorten magic 'ajkg'\n"); return AVERROR_INVALIDDATA; } @@ -340,7 +341,7 @@ static int read_header(ShortenContext *s) s->lpcqoffset = 0; s->blocksize = DEFAULT_BLOCK_SIZE; s->nmean = -1; - s->version = get_bits(&s->gb, 8); + s->version = bitstream_read(&s->bc, 8); s->internal_ftype = get_uint(s, TYPESIZE); s->channels = get_uint(s, CHANSIZE); @@ -374,7 +375,7 @@ static int read_header(ShortenContext *s) skip_bytes = get_uint(s, NSKIPSIZE); for (i = 0; i < skip_bytes; i++) - skip_bits(&s->gb, 8); + bitstream_skip(&s->bc, 8); } s->nwrap = FFMAX(NWRAP, maxnlpc); @@ -387,13 +388,13 @@ static int read_header(ShortenContext *s) if (s->version > 1) s->lpcqoffset = V2LPCQOFFSET; - if (get_ur_golomb_shorten(&s->gb, FNSIZE) != FN_VERBATIM) { + if (get_ur_golomb_shorten(&s->bc, FNSIZE) != FN_VERBATIM) { av_log(s->avctx, AV_LOG_ERROR, "missing verbatim section at beginning of stream\n"); return AVERROR_INVALIDDATA; } - s->header_size = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE); + s->header_size = get_ur_golomb_shorten(&s->bc, VERBATIM_CKSIZE_SIZE); if (s->header_size >= OUT_BUFFER_SIZE || s->header_size < CANONICAL_HEADER_SIZE) { av_log(s->avctx, AV_LOG_ERROR, "header is wrong size: %d\n", @@ -402,7 +403,7 @@ static int read_header(ShortenContext *s) } for (i = 0; i < s->header_size; i++) - s->header[i] = (char)get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE); + s->header[i] = (char)get_ur_golomb_shorten(&s->bc, VERBATIM_BYTE_SIZE); if ((ret = decode_wave_header(s->avctx, s->header, s->header_size)) < 0) return ret; @@ -464,8 +465,8 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, } } /* init and position bitstream reader */ - init_get_bits(&s->gb, buf, buf_size * 8); - skip_bits(&s->gb, s->bitindex); + bitstream_init8(&s->bc, buf, buf_size); + bitstream_skip(&s->bc, s->bitindex); /* process header or next subblock */ if (!s->got_header) { @@ -486,12 +487,12 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, unsigned cmd; int len; - if (get_bits_left(&s->gb) < 3 + FNSIZE) { + if (bitstream_bits_left(&s->bc) < 3 + FNSIZE) { *got_frame_ptr = 0; break; } - cmd = get_ur_golomb_shorten(&s->gb, FNSIZE); + cmd = get_ur_golomb_shorten(&s->bc, FNSIZE); if (cmd > FN_VERBATIM) { av_log(avctx, AV_LOG_ERROR, "unknown shorten function %d\n", cmd); @@ -503,12 +504,12 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, /* process non-audio command */ switch (cmd) { case FN_VERBATIM: - len = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE); + len = get_ur_golomb_shorten(&s->bc, VERBATIM_CKSIZE_SIZE); while (len--) - get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE); + get_ur_golomb_shorten(&s->bc, VERBATIM_BYTE_SIZE); break; case FN_BITSHIFT: - s->bitshift = get_ur_golomb_shorten(&s->gb, BITSHIFTSIZE); + s->bitshift = get_ur_golomb_shorten(&s->bc, BITSHIFTSIZE); if (s->bitshift < 0) return AVERROR_INVALIDDATA; break; @@ -543,7 +544,7 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, /* get Rice code for residual decoding */ if (cmd != FN_ZERO) { - residual_size = get_ur_golomb_shorten(&s->gb, ENERGYSIZE); + residual_size = get_ur_golomb_shorten(&s->bc, ENERGYSIZE); /* This is a hack as version 0 differed in the definition * of get_sr_golomb_shorten(). */ if (s->version == 0) @@ -616,8 +617,8 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, *got_frame_ptr = 0; finish_frame: - s->bitindex = get_bits_count(&s->gb) - 8 * (get_bits_count(&s->gb) / 8); - i = get_bits_count(&s->gb) / 8; + s->bitindex = bitstream_tell(&s->bc) - 8 * (bitstream_tell(&s->bc) / 8); + i = bitstream_tell(&s->bc) / 8; if (i > buf_size) { av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", i - buf_size); s->bitstream_size = 0; From 2d72219554adb09bc3ba044ac3e579a84550067b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sun, 10 Apr 2016 11:44:20 +0200 Subject: [PATCH 0846/3374] h261dec: Convert to the new bitstream reader --- libavcodec/h261dec.c | 92 +++++++++++++++++++++--------------------- libavcodec/mpegvideo.h | 3 ++ libavformat/h261dec.c | 11 ++--- 3 files changed, 56 insertions(+), 50 deletions(-) diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c index 9a323ec7d127c..b08598ec996b6 100644 --- a/libavcodec/h261dec.c +++ b/libavcodec/h261dec.c @@ -26,12 +26,14 @@ */ #include "avcodec.h" +#include "bitstream.h" #include "mpeg_er.h" #include "mpegutils.h" #include "mpegvideo.h" #include "h263.h" #include "h261.h" #include "internal.h" +#include "vlc.h" #define H261_MBA_VLC_BITS 9 #define H261_MTYPE_VLC_BITS 6 @@ -103,18 +105,18 @@ static int h261_decode_gob_header(H261Context *h) if (!h->gob_start_code_skipped) { /* Check for GOB Start Code */ - val = show_bits(&s->gb, 15); + val = bitstream_peek(&s->bc, 15); if (val) return -1; /* We have a GBSC */ - skip_bits(&s->gb, 16); + bitstream_skip(&s->bc, 16); } h->gob_start_code_skipped = 0; - h->gob_number = get_bits(&s->gb, 4); /* GN */ - s->qscale = get_bits(&s->gb, 5); /* GQUANT */ + h->gob_number = bitstream_read(&s->bc, 4); /* GN */ + s->qscale = bitstream_read(&s->bc, 5); /* GQUANT */ /* Check if gob_number is valid */ if (s->mb_height == 18) { // CIF @@ -127,8 +129,8 @@ static int h261_decode_gob_header(H261Context *h) } /* GEI */ - while (get_bits1(&s->gb) != 0) - skip_bits(&s->gb, 8); + while (bitstream_read_bit(&s->bc) != 0) + bitstream_skip(&s->bc, 8); if (s->qscale == 0) { av_log(s->avctx, AV_LOG_ERROR, "qscale has forbidden 0 value\n"); @@ -160,27 +162,27 @@ static int h261_resync(H261Context *h) if (ret >= 0) return 0; } else { - if (show_bits(&s->gb, 15) == 0) { + if (bitstream_peek(&s->bc, 15) == 0) { ret = h261_decode_gob_header(h); if (ret >= 0) return 0; } // OK, it is not where it is supposed to be ... - s->gb = s->last_resync_gb; - align_get_bits(&s->gb); - left = get_bits_left(&s->gb); + s->bc = s->last_resync_bc; + bitstream_align(&s->bc); + left = bitstream_bits_left(&s->bc); for (; left > 15 + 1 + 4 + 5; left -= 8) { - if (show_bits(&s->gb, 15) == 0) { - GetBitContext bak = s->gb; + if (bitstream_peek(&s->bc, 15) == 0) { + BitstreamContext bak = s->bc; ret = h261_decode_gob_header(h); if (ret >= 0) return 0; - s->gb = bak; + s->bc = bak; } - skip_bits(&s->gb, 8); + bitstream_skip(&s->bc, 8); } } @@ -228,9 +230,9 @@ static const int mvmap[17] = { 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16 }; -static int decode_mv_component(GetBitContext *gb, int v) +static int decode_mv_component(BitstreamContext *bc, int v) { - int mv_diff = get_vlc2(gb, h261_mv_vlc.table, H261_MV_VLC_BITS, 2); + int mv_diff = bitstream_read_vlc(bc, h261_mv_vlc.table, H261_MV_VLC_BITS, 2); /* check if mv_diff is valid */ if (mv_diff < 0) @@ -238,7 +240,7 @@ static int decode_mv_component(GetBitContext *gb, int v) mv_diff = mvmap[mv_diff]; - if (mv_diff && !get_bits1(gb)) + if (mv_diff && !bitstream_read_bit(bc)) mv_diff = -mv_diff; v += mv_diff; @@ -270,7 +272,7 @@ static int h261_decode_block(H261Context *h, int16_t *block, int n, int coded) scan_table = s->intra_scantable.permutated; if (s->mb_intra) { /* DC coef */ - level = get_bits(&s->gb, 8); + level = bitstream_read(&s->bc, 8); // 0 (00000000b) and -128 (10000000b) are FORBIDDEN if ((level & 0x7F) == 0) { av_log(s->avctx, AV_LOG_ERROR, "illegal dc %d at %d %d\n", @@ -288,10 +290,10 @@ static int h261_decode_block(H261Context *h, int16_t *block, int n, int coded) // EOB Not possible for first level when cbp is available (that's why the table is different) // 0 1 1s // * * 0* - int check = show_bits(&s->gb, 2); + int check = bitstream_peek(&s->bc, 2); i = 0; if (check & 0x2) { - skip_bits(&s->gb, 2); + bitstream_skip(&s->bc, 2); block[0] = (check & 0x1) ? -1 : 1; i = 1; } @@ -303,7 +305,7 @@ static int h261_decode_block(H261Context *h, int16_t *block, int n, int coded) return 0; } for (;;) { - code = get_vlc2(&s->gb, rl->vlc.table, TCOEFF_VLC_BITS, 2); + code = bitstream_read_vlc(&s->bc, rl->vlc.table, TCOEFF_VLC_BITS, 2); if (code < 0) { av_log(s->avctx, AV_LOG_ERROR, "illegal ac vlc code at %dx%d\n", s->mb_x, s->mb_y); @@ -314,14 +316,14 @@ static int h261_decode_block(H261Context *h, int16_t *block, int n, int coded) /* The remaining combinations of (run, level) are encoded with a * 20-bit word consisting of 6 bits escape, 6 bits run and 8 bits * level. */ - run = get_bits(&s->gb, 6); - level = get_sbits(&s->gb, 8); + run = bitstream_read(&s->bc, 6); + level = bitstream_read_signed(&s->bc, 8); } else if (code == 0) { break; } else { run = rl->table_run[code]; level = rl->table_level[code]; - if (get_bits1(&s->gb)) + if (bitstream_read_bit(&s->bc)) level = -level; } i += run; @@ -346,8 +348,8 @@ static int h261_decode_mb(H261Context *h) cbp = 63; // Read mba do { - h->mba_diff = get_vlc2(&s->gb, h261_mba_vlc.table, - H261_MBA_VLC_BITS, 2); + h->mba_diff = bitstream_read_vlc(&s->bc, h261_mba_vlc.table, + H261_MBA_VLC_BITS, 2); /* Check for slice end */ /* NOTE: GOB can be empty (no MB data) or exist only of MBA_stuffing */ @@ -358,7 +360,7 @@ static int h261_decode_mb(H261Context *h) } while (h->mba_diff == MBA_STUFFING); // stuffing if (h->mba_diff < 0) { - if (get_bits_left(&s->gb) <= 7) + if (bitstream_bits_left(&s->bc) <= 7) return SLICE_END; av_log(s->avctx, AV_LOG_ERROR, "illegal mba at %d %d\n", s->mb_x, s->mb_y); @@ -378,7 +380,7 @@ static int h261_decode_mb(H261Context *h) ff_update_block_index(s); // Read mtype - h->mtype = get_vlc2(&s->gb, h261_mtype_vlc.table, H261_MTYPE_VLC_BITS, 2); + h->mtype = bitstream_read_vlc(&s->bc, h261_mtype_vlc.table, H261_MTYPE_VLC_BITS, 2); if (h->mtype < 0 || h->mtype >= FF_ARRAY_ELEMS(ff_h261_mtype_map)) { av_log(s->avctx, AV_LOG_ERROR, "Invalid mtype index %d\n", h->mtype); @@ -388,7 +390,7 @@ static int h261_decode_mb(H261Context *h) // Read mquant if (IS_QUANT(h->mtype)) - ff_set_qscale(s, get_bits(&s->gb, 5)); + ff_set_qscale(s, bitstream_read(&s->bc, 5)); s->mb_intra = IS_INTRA4x4(h->mtype); @@ -408,8 +410,8 @@ static int h261_decode_mb(H261Context *h) h->current_mv_y = 0; } - h->current_mv_x = decode_mv_component(&s->gb, h->current_mv_x); - h->current_mv_y = decode_mv_component(&s->gb, h->current_mv_y); + h->current_mv_x = decode_mv_component(&s->bc, h->current_mv_x); + h->current_mv_y = decode_mv_component(&s->bc, h->current_mv_y); } else { h->current_mv_x = 0; h->current_mv_y = 0; @@ -417,7 +419,7 @@ static int h261_decode_mb(H261Context *h) // Read cbp if (HAS_CBP(h->mtype)) - cbp = get_vlc2(&s->gb, h261_cbp_vlc.table, H261_CBP_VLC_BITS, 2) + 1; + cbp = bitstream_read_vlc(&s->bc, h261_cbp_vlc.table, H261_CBP_VLC_BITS, 2) + 1; if (s->mb_intra) { s->current_picture.mb_type[xy] = MB_TYPE_INTRA; @@ -460,8 +462,8 @@ static int h261_decode_picture_header(H261Context *h) int format, i; uint32_t startcode = 0; - for (i = get_bits_left(&s->gb); i > 24; i -= 1) { - startcode = ((startcode << 1) | get_bits(&s->gb, 1)) & 0x000FFFFF; + for (i = bitstream_bits_left(&s->bc); i > 24; i -= 1) { + startcode = ((startcode << 1) | bitstream_read(&s->bc, 1)) & 0x000FFFFF; if (startcode == 0x10) break; @@ -473,7 +475,7 @@ static int h261_decode_picture_header(H261Context *h) } /* temporal reference */ - i = get_bits(&s->gb, 5); /* picture timestamp */ + i = bitstream_read(&s->bc, 5); /* picture timestamp */ if (i < (s->picture_number & 31)) i += 32; s->picture_number = (s->picture_number & ~31) + i; @@ -481,11 +483,11 @@ static int h261_decode_picture_header(H261Context *h) s->avctx->framerate = (AVRational) { 30000, 1001 }; /* PTYPE starts here */ - skip_bits1(&s->gb); /* split screen off */ - skip_bits1(&s->gb); /* camera off */ - skip_bits1(&s->gb); /* freeze picture release off */ + bitstream_skip(&s->bc, 1); /* split screen off */ + bitstream_skip(&s->bc, 1); /* camera off */ + bitstream_skip(&s->bc, 1); /* freeze picture release off */ - format = get_bits1(&s->gb); + format = bitstream_read_bit(&s->bc); // only 2 formats possible if (format == 0) { // QCIF @@ -502,12 +504,12 @@ static int h261_decode_picture_header(H261Context *h) s->mb_num = s->mb_width * s->mb_height; - skip_bits1(&s->gb); /* still image mode off */ - skip_bits1(&s->gb); /* Reserved */ + bitstream_skip(&s->bc, 1); /* still image mode off */ + bitstream_skip(&s->bc, 1); /* Reserved */ /* PEI */ - while (get_bits1(&s->gb) != 0) - skip_bits(&s->gb, 8); + while (bitstream_read_bit(&s->bc) != 0) + bitstream_skip(&s->bc, 8); /* H.261 has no I-frames, but if we pass AV_PICTURE_TYPE_I for the first * frame, the codec crashes if it does not contain all I-blocks @@ -552,7 +554,7 @@ static int h261_decode_gob(H261Context *h) */ static int get_consumed_bytes(MpegEncContext *s, int buf_size) { - int pos = get_bits_count(&s->gb) >> 3; + int pos = bitstream_tell(&s->bc) >> 3; if (pos == 0) pos = 1; // avoid infinite loops (i doubt that is needed but ...) if (pos + 10 > buf_size) @@ -577,7 +579,7 @@ static int h261_decode_frame(AVCodecContext *avctx, void *data, h->gob_start_code_skipped = 0; retry: - init_get_bits(&s->gb, buf, buf_size * 8); + bitstream_init8(&s->bc, buf, buf_size); if (!s->context_initialized) // we need the IDCT permutation for reading a custom matrix diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index f096b8a0fa8fb..5d8c31ce02add 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -31,6 +31,7 @@ #include #include "avcodec.h" +#include "bitstream.h" #include "blockdsp.h" #include "error_resilience.h" #include "fdctdsp.h" @@ -344,6 +345,7 @@ typedef struct MpegEncContext { int resync_mb_x; ///< x position of last resync marker int resync_mb_y; ///< y position of last resync marker GetBitContext last_resync_gb; ///< used to search for the next resync marker + BitstreamContext last_resync_bc; ///< used to search for the next resync marker int mb_num_left; ///< number of MBs left in this video packet (for partitioned Slices only) int next_p_frame_damaged; ///< set if the next p frame is damaged, to avoid showing trashed B-frames @@ -428,6 +430,7 @@ typedef struct MpegEncContext { /* decompression specific */ GetBitContext gb; + BitstreamContext bc; /* MPEG-1 specific */ int gop_picture_number; ///< index of the first picture of a GOP based on fake_pic_num & MPEG-1 specific diff --git a/libavformat/h261dec.c b/libavformat/h261dec.c index 4a5805020f4ca..d8a2cecc77263 100644 --- a/libavformat/h261dec.c +++ b/libavformat/h261dec.c @@ -19,7 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "libavcodec/get_bits.h" +#include "libavcodec/bitstream.h" + #include "avformat.h" #include "rawdec.h" @@ -31,16 +32,16 @@ static int h261_probe(AVProbeData *p) int invalid_psc=0; int next_gn=0; int src_fmt=0; - GetBitContext gb; + BitstreamContext bc; - init_get_bits(&gb, p->buf, p->buf_size*8); + bitstream_init(&bc, p->buf, p->buf_size * 8); for(i=0; ibuf_size*8; i++){ if ((code & 0x01ff0000) || !(code & 0xff00)) { - code = (code<<8) + get_bits(&gb, 8); + code = (code << 8) + bitstream_read(&bc, 8); i += 7; } else - code = (code<<1) + get_bits1(&gb); + code = (code << 1) + bitstream_read_bit(&bc); if ((code & 0xffff0000) == 0x10000) { int gn= (code>>12)&0xf; if(!gn) From ab2539bd374fe7ddbc6e2f058b62645cd5076192 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Sat, 19 Mar 2016 17:32:04 +0100 Subject: [PATCH 0847/3374] ffv1: Convert to the new bitstream reader --- libavcodec/ffv1.h | 4 ++-- libavcodec/ffv1dec.c | 24 ++++++++++++------------ libavcodec/ffv1enc.c | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/libavcodec/ffv1.h b/libavcodec/ffv1.h index 34370fa143b7e..7e0465abaa793 100644 --- a/libavcodec/ffv1.h +++ b/libavcodec/ffv1.h @@ -26,7 +26,7 @@ #include #include "avcodec.h" -#include "get_bits.h" +#include "bitstream.h" #include "put_bits.h" #include "rangecoder.h" @@ -70,7 +70,7 @@ typedef struct FFV1Context { AVClass *class; AVCodecContext *avctx; RangeCoder c; - GetBitContext gb; + BitstreamContext bc; PutBitContext pb; uint64_t rc_stat[256][2]; uint64_t (*rc_stat2[MAX_QUANT_TABLES])[32][2]; diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index 2ebd6864a1cf6..07e66b9dbbea4 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -33,9 +33,9 @@ #include "libavutil/timer.h" #include "avcodec.h" -#include "golomb_legacy.h" +#include "bitstream.h" +#include "golomb.h" #include "internal.h" -#include "get_bits.h" #include "put_bits.h" #include "rangecoder.h" #include "mathops.h" @@ -66,7 +66,7 @@ static av_noinline int get_symbol(RangeCoder *c, uint8_t *state, int is_signed) return get_symbol_inline(c, state, is_signed); } -static inline int get_vlc_symbol(GetBitContext *gb, VlcState *const state, +static inline int get_vlc_symbol(BitstreamContext *bc, VlcState *const state, int bits) { int k, i, v, ret; @@ -80,7 +80,7 @@ static inline int get_vlc_symbol(GetBitContext *gb, VlcState *const state, assert(k <= 8); - v = get_sr_golomb(gb, k, 12, bits); + v = get_sr_golomb(bc, k, 12, bits); ff_dlog(NULL, "v:%d bias:%d error:%d drift:%d count:%d k:%d", v, state->bias, state->error_sum, state->drift, state->count, k); @@ -124,13 +124,13 @@ static av_always_inline void decode_line(FFV1Context *s, int w, if (run_mode) { if (run_count == 0 && run_mode == 1) { - if (get_bits1(&s->gb)) { + if (bitstream_read_bit(&s->bc)) { run_count = 1 << ff_log2_run[run_index]; if (x + run_count <= w) run_index++; } else { if (ff_log2_run[run_index]) - run_count = get_bits(&s->gb, ff_log2_run[run_index]); + run_count = bitstream_read(&s->bc, ff_log2_run[run_index]); else run_count = 0; if (run_index) @@ -142,17 +142,17 @@ static av_always_inline void decode_line(FFV1Context *s, int w, if (run_count < 0) { run_mode = 0; run_count = 0; - diff = get_vlc_symbol(&s->gb, &p->vlc_state[context], + diff = get_vlc_symbol(&s->bc, &p->vlc_state[context], bits); if (diff >= 0) diff++; } else diff = 0; } else - diff = get_vlc_symbol(&s->gb, &p->vlc_state[context], bits); + diff = get_vlc_symbol(&s->bc, &p->vlc_state[context], bits); ff_dlog(s->avctx, "count:%d index:%d, mode:%d, x:%d pos:%d\n", - run_count, run_index, run_mode, x, get_bits_count(&s->gb)); + run_count, run_index, run_mode, x, bitstream_tell(&s->bc)); } if (sign) @@ -364,9 +364,9 @@ static int decode_slice(AVCodecContext *c, void *arg) if (f->version == 3 && f->minor_version > 1 || f->version > 3) get_rac(&fs->c, (uint8_t[]) { 129 }); fs->ac_byte_count = f->version > 2 || (!x && !y) ? fs->c.bytestream - fs->c.bytestream_start - 1 : 0; - init_get_bits(&fs->gb, fs->c.bytestream_start + fs->ac_byte_count, - (fs->c.bytestream_end - fs->c.bytestream_start - - fs->ac_byte_count) * 8); + bitstream_init8(&fs->bc, fs->c.bytestream_start + fs->ac_byte_count, + (fs->c.bytestream_end - fs->c.bytestream_start - + fs->ac_byte_count)); } av_assert1(width && height); diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c index adf70d8a6b2f8..c5088bb545f55 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -33,7 +33,7 @@ #include "libavutil/imgutils.h" #include "avcodec.h" -#include "golomb_legacy.h" +#include "golomb.h" #include "internal.h" #include "put_bits.h" #include "rangecoder.h" From b420a27e74750b60d2e064236afb10be06a38ace Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 30 Jan 2017 21:35:42 +0100 Subject: [PATCH 0848/3374] avconv: allow -b to be used with streamcopy In this mode it tells the muxer about the bitrate of the input stream. --- avconv.c | 3 +++ avconv.h | 5 +++++ avconv_opt.c | 11 +++++++++++ doc/avconv.texi | 7 +++++++ 4 files changed, 26 insertions(+) diff --git a/avconv.c b/avconv.c index fe606250feb8a..94b6da2a8ba18 100644 --- a/avconv.c +++ b/avconv.c @@ -1852,6 +1852,9 @@ static int init_output_stream_streamcopy(OutputStream *ost) ost->st->time_base = ist->st->time_base; + if (ost->bitrate_override) + par_dst->bit_rate = ost->bitrate_override; + if (ist->st->nb_side_data) { ost->st->side_data = av_realloc_array(NULL, ist->st->nb_side_data, sizeof(*ist->st->side_data)); diff --git a/avconv.h b/avconv.h index 6360f76c0bb5d..3c3f0ef659558 100644 --- a/avconv.h +++ b/avconv.h @@ -162,6 +162,8 @@ typedef struct OptionsContext { int nb_sample_fmts; SpecifierOpt *qscale; int nb_qscale; + SpecifierOpt *bitrates; + int nb_bitrates; SpecifierOpt *forced_key_frames; int nb_forced_key_frames; SpecifierOpt *force_fps; @@ -382,6 +384,9 @@ typedef struct OutputStream { int forced_kf_index; char *forced_keyframes; + // the bitrate to send to the muxer for streamcopy + int bitrate_override; + char *logfile_prefix; FILE *logfile; diff --git a/avconv_opt.c b/avconv_opt.c index 8b43f0f4e2bb3..e078a0b89ddae 100644 --- a/avconv_opt.c +++ b/avconv_opt.c @@ -952,6 +952,7 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e const char *bsfs = NULL; char *next, *codec_tag = NULL; double qscale = -1; + int bitrate = 0; if (!st) { av_log(NULL, AV_LOG_FATAL, "Could not alloc stream.\n"); @@ -1091,6 +1092,14 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e ost->enc_ctx->global_quality = FF_QP2LAMBDA * qscale; } + MATCH_PER_STREAM_OPT(bitrates, i, bitrate, oc, st); + if (bitrate > 0) { + if (ost->stream_copy) + ost->bitrate_override = bitrate; + else + ost->enc_ctx->bit_rate = bitrate; + } + ost->max_muxing_queue_size = 128; MATCH_PER_STREAM_OPT(max_muxing_queue_size, i, ost->max_muxing_queue_size, oc, st); ost->max_muxing_queue_size *= sizeof(AVPacket); @@ -2570,6 +2579,8 @@ const OptionDef options[] = { { "qscale", HAS_ARG | OPT_EXPERT | OPT_DOUBLE | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(qscale) }, "use fixed quality scale (VBR)", "q" }, + { "b", HAS_ARG | OPT_INT | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(bitrates) }, + "set stream bitrate in bits/second", "bitrate" }, { "filter", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filters) }, "set stream filterchain", "filter_list" }, { "filter_script", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filter_scripts) }, diff --git a/doc/avconv.texi b/doc/avconv.texi index 002dba3184485..6f1fbc79b2ff7 100644 --- a/doc/avconv.texi +++ b/doc/avconv.texi @@ -354,6 +354,13 @@ Stop writing to the stream after @var{framecount} frames. Use fixed quality scale (VBR). The meaning of @var{q} is codec-dependent. +@item -b[:@var{stream_specifier}] @var{bitrate} (@emph{output,per-stream}) +Set the stream bitrate in bits per second. When transcoding, this tells the +encoder to use the specified bitrate for the encoded stream. + +For streamcopy, this provides a hint to the muxer about the bitrate of the input +stream. + @item -filter[:@var{stream_specifier}] @var{filter_graph} (@emph{output,per-stream}) @var{filter_graph} is a description of the filter graph to apply to the stream. Use @code{-filters} to show all the available filters From fd9212f2edfe9b107c3c08ba2df5fd2cba5ab9e3 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 3 Jul 2016 10:09:36 +0200 Subject: [PATCH 0849/3374] Mark some arrays that never change as const. --- configure | 2 +- libavcodec/aaccoder.c | 4 ++-- libavcodec/aacenc.c | 4 ++-- libavcodec/aacenc.h | 4 ++-- libavcodec/aic.c | 2 +- libavcodec/amrnbdata.h | 4 ++-- libavcodec/amrwbdata.h | 4 ++-- libavcodec/atrac3plus.c | 38 ++++++++++++++++----------------- libavcodec/dfa.c | 2 +- libavcodec/g722dec.c | 6 +++--- libavcodec/h263data.c | 4 ++-- libavcodec/h263data.h | 4 ++-- libavcodec/indeo3.c | 4 ++-- libavcodec/indeo4data.h | 2 +- libavcodec/mpeg4videodec.c | 2 +- libavcodec/on2avc.c | 4 ++-- libavcodec/on2avcdata.c | 20 ++++++++--------- libavcodec/on2avcdata.h | 20 ++++++++--------- libavcodec/opus_silk.c | 6 +++--- libavcodec/qsvdec_h2645.c | 4 ++-- libavcodec/qsvenc_hevc.c | 4 ++-- libavcodec/sipr.c | 2 +- libavcodec/sipr16k.c | 2 +- libavcodec/sipr16kdata.h | 2 +- libavcodec/siprdata.h | 2 +- libavcodec/tscc2data.h | 6 +++--- libavcodec/vaapi_encode.c | 2 +- libavcodec/vaapi_encode_mjpeg.c | 2 +- libavcodec/vp8.c | 8 +++---- libavcodec/vp9block.c | 4 ++-- libavcodec/vp9data.c | 4 ++-- libavcodec/vp9data.h | 4 ++-- libavcodec/x86/fdct.c | 4 ++-- libavcodec/x86/mlpdsp.c | 16 +++++++------- libavcodec/x86/videodsp_init.c | 12 +++++------ libavfilter/af_volume.c | 2 +- libavfilter/vf_drawtext.c | 2 +- libavfilter/vf_libopencv.c | 4 ++-- libavfilter/vf_overlay.c | 2 +- libavformat/hls.c | 4 ++-- libavformat/id3v2.c | 2 +- libavformat/id3v2.h | 2 +- libavformat/mov_chan.c | 2 +- libavformat/movenc.c | 2 +- libavformat/mxfdec.c | 2 +- libavresample/audio_mix.c | 2 +- libavutil/hwcontext.c | 2 +- libavutil/hwcontext_vaapi.c | 2 +- libavutil/parseutils.c | 2 +- libavutil/pixdesc.c | 10 ++++----- libavutil/stereo3d.c | 2 +- 51 files changed, 129 insertions(+), 129 deletions(-) diff --git a/configure b/configure index a2223022cb022..64c077465d2fd 100755 --- a/configure +++ b/configure @@ -5414,7 +5414,7 @@ print_enabled_components(){ struct_name=$2 name=$3 shift 3 - echo "static const $struct_name *$name[] = {" > $TMPH + echo "static const $struct_name * const $name[] = {" > $TMPH for c in $*; do enabled $c && printf " &ff_%s,\n" $c >> $TMPH done diff --git a/libavcodec/aaccoder.c b/libavcodec/aaccoder.c index ee89148ef4c0e..a654844cd08df 100644 --- a/libavcodec/aaccoder.c +++ b/libavcodec/aaccoder.c @@ -53,7 +53,7 @@ static const uint8_t run_value_bits_short[16] = { 3, 3, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 9 }; -static const uint8_t *run_value_bits[2] = { +static const uint8_t * const run_value_bits[2] = { run_value_bits_long, run_value_bits_short }; @@ -1112,7 +1112,7 @@ static void search_for_ms(AACEncContext *s, ChannelElement *cpe, } } -AACCoefficientsEncoder ff_aac_coders[] = { +const AACCoefficientsEncoder ff_aac_coders[] = { { search_for_quantizers_faac, encode_window_bands_info, diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c index c247c5b39028b..9b0e99b28d0bd 100644 --- a/libavcodec/aacenc.c +++ b/libavcodec/aacenc.c @@ -98,7 +98,7 @@ static const uint8_t swb_size_1024_8[] = { 32, 36, 36, 40, 44, 48, 52, 56, 60, 64, 80 }; -static const uint8_t *swb_size_1024[] = { +static const uint8_t * const swb_size_1024[] = { swb_size_1024_96, swb_size_1024_96, swb_size_1024_64, swb_size_1024_48, swb_size_1024_48, swb_size_1024_32, swb_size_1024_24, swb_size_1024_24, swb_size_1024_16, @@ -125,7 +125,7 @@ static const uint8_t swb_size_128_8[] = { 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 16, 20, 20 }; -static const uint8_t *swb_size_128[] = { +static const uint8_t * const swb_size_128[] = { /* the last entry on the following row is swb_size_128_64 but is a duplicate of swb_size_128_96 */ swb_size_128_96, swb_size_128_96, swb_size_128_96, diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h index dec445ce346dc..f77b2002e4bea 100644 --- a/libavcodec/aacenc.h +++ b/libavcodec/aacenc.h @@ -46,7 +46,7 @@ typedef struct AACCoefficientsEncoder { void (*search_for_ms)(struct AACEncContext *s, ChannelElement *cpe, const float lambda); } AACCoefficientsEncoder; -extern AACCoefficientsEncoder ff_aac_coders[]; +extern const AACCoefficientsEncoder ff_aac_coders[]; /** * AAC encoder context @@ -67,7 +67,7 @@ typedef struct AACEncContext { ChannelElement *cpe; ///< channel elements FFPsyContext psy; struct FFPsyPreprocessContext* psypp; - AACCoefficientsEncoder *coder; + const AACCoefficientsEncoder *coder; int cur_channel; int last_frame; float lambda; diff --git a/libavcodec/aic.c b/libavcodec/aic.c index 368b3bcf23a64..ed0be44629e7f 100644 --- a/libavcodec/aic.c +++ b/libavcodec/aic.c @@ -133,7 +133,7 @@ static const uint8_t aic_c_ext_scan[192] = { 177, 184, 176, 169, 162, 161, 168, 160, }; -static const uint8_t *aic_scan[NUM_BANDS] = { +static const uint8_t * const aic_scan[NUM_BANDS] = { aic_y_scan, aic_c_scan, aic_y_ext_scan, aic_c_ext_scan }; diff --git a/libavcodec/amrnbdata.h b/libavcodec/amrnbdata.h index b7d1b8960898d..4eaeb0e3559c3 100644 --- a/libavcodec/amrnbdata.h +++ b/libavcodec/amrnbdata.h @@ -1655,10 +1655,10 @@ static const float ir_filter_medium[AMR_SUBFRAME_SIZE] = { 0.016998, 0.023804, -0.041779, 0.025696, 0.019989, }; -static const float *ir_filters_lookup[2] = { +static const float * const ir_filters_lookup[2] = { ir_filter_strong, ir_filter_medium }; -static const float *ir_filters_lookup_MODE_7k95[2] = { +static const float * const ir_filters_lookup_MODE_7k95[2] = { ir_filter_strong_MODE_7k95, ir_filter_medium }; diff --git a/libavcodec/amrwbdata.h b/libavcodec/amrwbdata.h index c0078b3c6e5d9..19f5a311bea90 100644 --- a/libavcodec/amrwbdata.h +++ b/libavcodec/amrwbdata.h @@ -673,7 +673,7 @@ static const uint16_t order_MODE_23k85[] = { }; /** Reordering array addresses for each mode */ -static const uint16_t* amr_bit_orderings_by_mode[] = { +static const uint16_t * const amr_bit_orderings_by_mode[] = { order_MODE_6k60, order_MODE_8k85, order_MODE_12k65, @@ -1805,7 +1805,7 @@ static const float ir_filter_mid[64] = { -7.501221e-02, 2.920532e-02, 1.660156e-02, 7.751465e-02 }; -static const float *ir_filters_lookup[2] = { +static const float * const ir_filters_lookup[2] = { ir_filter_str, ir_filter_mid }; diff --git a/libavcodec/atrac3plus.c b/libavcodec/atrac3plus.c index 2731a80725b7e..e3c2504178ac2 100644 --- a/libavcodec/atrac3plus.c +++ b/libavcodec/atrac3plus.c @@ -82,52 +82,52 @@ av_cold void ff_atrac3p_init_vlcs(AVCodec *codec) { int i, wl_vlc_offs, ct_vlc_offs, sf_vlc_offs, tab_offset; - static int wl_nb_bits[4] = { 2, 3, 5, 5 }; - static int wl_nb_codes[4] = { 3, 5, 8, 8 }; - static const uint8_t *wl_bits[4] = { + static const int wl_nb_bits[4] = { 2, 3, 5, 5 }; + static const int wl_nb_codes[4] = { 3, 5, 8, 8 }; + static const uint8_t * const wl_bits[4] = { atrac3p_wl_huff_bits1, atrac3p_wl_huff_bits2, atrac3p_wl_huff_bits3, atrac3p_wl_huff_bits4 }; - static const uint8_t *wl_codes[4] = { + static const uint8_t * const wl_codes[4] = { atrac3p_wl_huff_code1, atrac3p_wl_huff_code2, atrac3p_wl_huff_code3, atrac3p_wl_huff_code4 }; - static const uint8_t *wl_xlats[4] = { + static const uint8_t * const wl_xlats[4] = { atrac3p_wl_huff_xlat1, atrac3p_wl_huff_xlat2, NULL, NULL }; - static int ct_nb_bits[4] = { 3, 4, 4, 4 }; - static int ct_nb_codes[4] = { 4, 8, 8, 8 }; - static const uint8_t *ct_bits[4] = { + static const int ct_nb_bits[4] = { 3, 4, 4, 4 }; + static const int ct_nb_codes[4] = { 4, 8, 8, 8 }; + static const uint8_t * const ct_bits[4] = { atrac3p_ct_huff_bits1, atrac3p_ct_huff_bits2, atrac3p_ct_huff_bits2, atrac3p_ct_huff_bits3 }; - static const uint8_t *ct_codes[4] = { + static const uint8_t * const ct_codes[4] = { atrac3p_ct_huff_code1, atrac3p_ct_huff_code2, atrac3p_ct_huff_code2, atrac3p_ct_huff_code3 }; - static const uint8_t *ct_xlats[4] = { + static const uint8_t * const ct_xlats[4] = { NULL, NULL, atrac3p_ct_huff_xlat1, NULL }; - static int sf_nb_bits[8] = { 9, 9, 9, 9, 6, 6, 7, 7 }; - static int sf_nb_codes[8] = { 64, 64, 64, 64, 16, 16, 16, 16 }; - static const uint8_t *sf_bits[8] = { + static const int sf_nb_bits[8] = { 9, 9, 9, 9, 6, 6, 7, 7 }; + static const int sf_nb_codes[8] = { 64, 64, 64, 64, 16, 16, 16, 16 }; + static const uint8_t * const sf_bits[8] = { atrac3p_sf_huff_bits1, atrac3p_sf_huff_bits1, atrac3p_sf_huff_bits2, atrac3p_sf_huff_bits3, atrac3p_sf_huff_bits4, atrac3p_sf_huff_bits4, atrac3p_sf_huff_bits5, atrac3p_sf_huff_bits6 }; - static const uint16_t *sf_codes[8] = { + static const uint16_t * const sf_codes[8] = { atrac3p_sf_huff_code1, atrac3p_sf_huff_code1, atrac3p_sf_huff_code2, atrac3p_sf_huff_code3, atrac3p_sf_huff_code4, atrac3p_sf_huff_code4, atrac3p_sf_huff_code5, atrac3p_sf_huff_code6 }; - static const uint8_t *sf_xlats[8] = { + static const uint8_t * const sf_xlats[8] = { atrac3p_sf_huff_xlat1, atrac3p_sf_huff_xlat2, NULL, NULL, atrac3p_sf_huff_xlat4, atrac3p_sf_huff_xlat5, NULL, NULL }; - static const uint8_t *gain_cbs[11] = { + static const uint8_t * const gain_cbs[11] = { atrac3p_huff_gain_npoints1_cb, atrac3p_huff_gain_npoints1_cb, atrac3p_huff_gain_lev1_cb, atrac3p_huff_gain_lev2_cb, atrac3p_huff_gain_lev3_cb, atrac3p_huff_gain_lev4_cb, @@ -135,7 +135,7 @@ av_cold void ff_atrac3p_init_vlcs(AVCodec *codec) atrac3p_huff_gain_loc4_cb, atrac3p_huff_gain_loc2_cb, atrac3p_huff_gain_loc5_cb }; - static const uint8_t *gain_xlats[11] = { + static const uint8_t * const gain_xlats[11] = { NULL, atrac3p_huff_gain_npoints2_xlat, atrac3p_huff_gain_lev1_xlat, atrac3p_huff_gain_lev2_xlat, atrac3p_huff_gain_lev3_xlat, atrac3p_huff_gain_lev4_xlat, atrac3p_huff_gain_loc3_xlat, @@ -143,13 +143,13 @@ av_cold void ff_atrac3p_init_vlcs(AVCodec *codec) atrac3p_huff_gain_loc2_xlat, atrac3p_huff_gain_loc5_xlat }; - static const uint8_t *tone_cbs[7] = { + static const uint8_t * const tone_cbs[7] = { atrac3p_huff_tonebands_cb, atrac3p_huff_numwavs1_cb, atrac3p_huff_numwavs2_cb, atrac3p_huff_wav_ampsf1_cb, atrac3p_huff_wav_ampsf2_cb, atrac3p_huff_wav_ampsf3_cb, atrac3p_huff_freq_cb }; - static const uint8_t *tone_xlats[7] = { + static const uint8_t * const tone_xlats[7] = { NULL, NULL, atrac3p_huff_numwavs2_xlat, atrac3p_huff_wav_ampsf1_xlat, atrac3p_huff_wav_ampsf2_xlat, atrac3p_huff_wav_ampsf3_xlat, atrac3p_huff_freq_xlat diff --git a/libavcodec/dfa.c b/libavcodec/dfa.c index 8021193894795..2654118fad0c7 100644 --- a/libavcodec/dfa.c +++ b/libavcodec/dfa.c @@ -322,7 +322,7 @@ static const chunk_decoder decoder[8] = { decode_tdlt, decode_dsw1, decode_blck, decode_dds1, }; -static const char* chunk_name[8] = { +static const char * const chunk_name[8] = { "COPY", "TSW1", "BDLT", "WDLT", "TDLT", "DSW1", "BLCK", "DDS1" }; diff --git a/libavcodec/g722dec.c b/libavcodec/g722dec.c index bfd4b420b2591..f9605c99c588f 100644 --- a/libavcodec/g722dec.c +++ b/libavcodec/g722dec.c @@ -80,9 +80,9 @@ static const int16_t low_inv_quant5[32] = { 587, 473, 370, 276, 190, 110, 35, -35 }; -static const int16_t *low_inv_quants[3] = { ff_g722_low_inv_quant6, - low_inv_quant5, - ff_g722_low_inv_quant4 }; +static const int16_t * const low_inv_quants[3] = { ff_g722_low_inv_quant6, + low_inv_quant5, + ff_g722_low_inv_quant4 }; static int g722_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) diff --git a/libavcodec/h263data.c b/libavcodec/h263data.c index b7f4f20e42644..0e368a3ac7d4a 100644 --- a/libavcodec/h263data.c +++ b/libavcodec/h263data.c @@ -264,11 +264,11 @@ const uint8_t ff_h263_chroma_qscale_table[32] = { 0, 1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15 }; -uint16_t ff_mba_max[6] = { +const uint16_t ff_mba_max[6] = { 47, 98, 395, 1583, 6335, 9215 }; -uint8_t ff_mba_length[7] = { +const uint8_t ff_mba_length[7] = { 6, 7, 9, 11, 13, 14, 14 }; diff --git a/libavcodec/h263data.h b/libavcodec/h263data.h index a431d58f12cd0..2c494b32cc41d 100644 --- a/libavcodec/h263data.h +++ b/libavcodec/h263data.h @@ -71,7 +71,7 @@ extern const uint8_t ff_modified_quant_tab[2][32]; extern const uint8_t ff_h263_chroma_qscale_table[32]; -extern uint16_t ff_mba_max[6]; -extern uint8_t ff_mba_length[7]; +extern const uint16_t ff_mba_max[6]; +extern const uint8_t ff_mba_length[7]; #endif /* AVCODEC_H263DATA_H */ diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c index 1b5b6505d67dc..37d85e1abc230 100644 --- a/libavcodec/indeo3.c +++ b/libavcodec/indeo3.c @@ -118,8 +118,8 @@ static uint8_t requant_tab[8][128]; */ static av_cold void build_requant_tab(void) { - static int8_t offsets[8] = { 1, 1, 2, -3, -3, 3, 4, 4 }; - static int8_t deltas [8] = { 0, 1, 0, 4, 4, 1, 0, 1 }; + static const int8_t offsets[8] = { 1, 1, 2, -3, -3, 3, 4, 4 }; + static const int8_t deltas [8] = { 0, 1, 0, 4, 4, 1, 0, 1 }; int i, j, step; diff --git a/libavcodec/indeo4data.h b/libavcodec/indeo4data.h index be7c41356b5db..35ff404e183bb 100644 --- a/libavcodec/indeo4data.h +++ b/libavcodec/indeo4data.h @@ -60,7 +60,7 @@ static const uint8_t ivi4_horizontal_scan_4x4[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; -static const uint8_t *scan_index_to_tab[15] = { +static const uint8_t * const scan_index_to_tab[15] = { // for 8x8 transforms ff_zigzag_direct, ivi4_alternate_scan_8x8, diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index e16d482f9cd07..8891ec1bb7912 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -1274,7 +1274,7 @@ static int mpeg4_decode_mb(MpegEncContext *s, int16_t block[6][64]) Mpeg4DecContext *ctx = (Mpeg4DecContext *)s; int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant; int16_t *mot_val; - static int8_t quant_tab[4] = { -1, -2, 1, 2 }; + static const int8_t quant_tab[4] = { -1, -2, 1, 2 }; const int xy = s->mb_x + s->mb_y * s->mb_stride; assert(s->h263_pred); diff --git a/libavcodec/on2avc.c b/libavcodec/on2avc.c index 1b81980f7dd70..39ae1178f1bff 100644 --- a/libavcodec/on2avc.c +++ b/libavcodec/on2avc.c @@ -320,7 +320,7 @@ static void zero_head_and_tail(float *src, int len, int order0, int order1) } static void pretwiddle(float *src, float *dst, int dst_len, int tab_step, - int step, int order0, int order1, const double **tabs) + int step, int order0, int order1, const double * const *tabs) { float *src2, *out; const double *tab; @@ -348,7 +348,7 @@ static void pretwiddle(float *src, float *dst, int dst_len, int tab_step, static void twiddle(float *src1, float *src2, int src2_len, const double *tab, int tab_len, int step, - int order0, int order1, const double **tabs) + int order0, int order1, const double * const *tabs) { int steps; int mask; diff --git a/libavcodec/on2avcdata.c b/libavcodec/on2avcdata.c index d039f23509cc7..93543ad17c171 100644 --- a/libavcodec/on2avcdata.c +++ b/libavcodec/on2avcdata.c @@ -7641,11 +7641,11 @@ static const double tabs_4_10[4 * 2][10] = { -0.099339873, -0.041293536, 0.31028851, 0.17727433, -0.92756648 } }; -const double *ff_on2avc_tabs_4_10_1[4] = { +const double * const ff_on2avc_tabs_4_10_1[4] = { tabs_4_10[0], tabs_4_10[1], tabs_4_10[2], tabs_4_10[3] }; -const double *ff_on2avc_tabs_4_10_2[4] = { +const double * const ff_on2avc_tabs_4_10_2[4] = { tabs_4_10[4], tabs_4_10[5], tabs_4_10[6], tabs_4_10[7] }; @@ -7724,12 +7724,12 @@ static const double tabs_9_20[9 * 2][20] = { 0.22783, 0.058894795, -0.61350902, 0.69559873, -0.27013783, } }; -const double* ff_on2avc_tabs_9_20_1[9] = { +const double * const ff_on2avc_tabs_9_20_1[9] = { tabs_9_20[0], tabs_9_20[1], tabs_9_20[2], tabs_9_20[3], tabs_9_20[4], tabs_9_20[5], tabs_9_20[6], tabs_9_20[7], tabs_9_20[8] }; -const double* ff_on2avc_tabs_9_20_2[9] = { +const double * const ff_on2avc_tabs_9_20_2[9] = { tabs_9_20[ 9], tabs_9_20[10], tabs_9_20[11], tabs_9_20[12], tabs_9_20[13], tabs_9_20[14], tabs_9_20[15], tabs_9_20[16], tabs_9_20[17] }; @@ -7927,7 +7927,7 @@ static const double tabs_19_40[19 * 2][40] = { 0.019871848, -0.11989559, 0.036659135, 0.26632201, -0.3057397, -0.23220335, 0.68741352, -0.54024027, } }; -const double* ff_on2avc_tabs_19_40_1[19] = { +const double * const ff_on2avc_tabs_19_40_1[19] = { tabs_19_40[ 0], tabs_19_40[ 1], tabs_19_40[ 2], tabs_19_40[ 3], tabs_19_40[ 4], tabs_19_40[ 5], tabs_19_40[ 6], tabs_19_40[ 7], tabs_19_40[ 8], tabs_19_40[ 9], tabs_19_40[10], tabs_19_40[11], @@ -7935,7 +7935,7 @@ const double* ff_on2avc_tabs_19_40_1[19] = { tabs_19_40[16], tabs_19_40[17], tabs_19_40[18], }; -const double* ff_on2avc_tabs_19_40_2[19] = { +const double * const ff_on2avc_tabs_19_40_2[19] = { tabs_19_40[19], tabs_19_40[20], tabs_19_40[21], tabs_19_40[22], tabs_19_40[23], tabs_19_40[24], tabs_19_40[25], tabs_19_40[26], tabs_19_40[27], tabs_19_40[28], tabs_19_40[29], tabs_19_40[30], @@ -8826,7 +8826,7 @@ static const double tabs_20_84[20 * 4][84] = { 0.51434408, -0.41486443, 0.27672635, -0.10432054, }, }; -const double* ff_on2avc_tabs_20_84_1[20] = { +const double * const ff_on2avc_tabs_20_84_1[20] = { tabs_20_84[ 0], tabs_20_84[ 1], tabs_20_84[ 2], tabs_20_84[ 3], tabs_20_84[ 4], tabs_20_84[ 5], tabs_20_84[ 6], tabs_20_84[ 7], tabs_20_84[ 8], tabs_20_84[ 9], tabs_20_84[10], tabs_20_84[11], @@ -8834,7 +8834,7 @@ const double* ff_on2avc_tabs_20_84_1[20] = { tabs_20_84[16], tabs_20_84[17], tabs_20_84[18], tabs_20_84[19] }; -const double* ff_on2avc_tabs_20_84_2[20] = { +const double * const ff_on2avc_tabs_20_84_2[20] = { tabs_20_84[20], tabs_20_84[21], tabs_20_84[22], tabs_20_84[23], tabs_20_84[24], tabs_20_84[25], tabs_20_84[26], tabs_20_84[27], tabs_20_84[28], tabs_20_84[29], tabs_20_84[30], tabs_20_84[31], @@ -8842,7 +8842,7 @@ const double* ff_on2avc_tabs_20_84_2[20] = { tabs_20_84[36], tabs_20_84[37], tabs_20_84[38], tabs_20_84[39] }; -const double* ff_on2avc_tabs_20_84_3[20] = { +const double * const ff_on2avc_tabs_20_84_3[20] = { tabs_20_84[40], tabs_20_84[41], tabs_20_84[42], tabs_20_84[43], tabs_20_84[44], tabs_20_84[45], tabs_20_84[46], tabs_20_84[47], tabs_20_84[48], tabs_20_84[49], tabs_20_84[50], tabs_20_84[51], @@ -8850,7 +8850,7 @@ const double* ff_on2avc_tabs_20_84_3[20] = { tabs_20_84[56], tabs_20_84[57], tabs_20_84[58], tabs_20_84[59] }; -const double* ff_on2avc_tabs_20_84_4[20] = { +const double * const ff_on2avc_tabs_20_84_4[20] = { tabs_20_84[60], tabs_20_84[61], tabs_20_84[62], tabs_20_84[63], tabs_20_84[64], tabs_20_84[65], tabs_20_84[66], tabs_20_84[67], tabs_20_84[68], tabs_20_84[69], tabs_20_84[70], tabs_20_84[71], diff --git a/libavcodec/on2avcdata.h b/libavcodec/on2avcdata.h index 39d29110ec1b4..ff66ccacd360b 100644 --- a/libavcodec/on2avcdata.h +++ b/libavcodec/on2avcdata.h @@ -64,16 +64,16 @@ extern const double ff_on2avc_tab_84_1[]; extern const double ff_on2avc_tab_84_2[]; extern const double ff_on2avc_tab_84_3[]; extern const double ff_on2avc_tab_84_4[]; -extern const double* ff_on2avc_tabs_4_10_1[4]; -extern const double* ff_on2avc_tabs_4_10_2[4]; -extern const double* ff_on2avc_tabs_9_20_1[9]; -extern const double* ff_on2avc_tabs_9_20_2[9]; -extern const double* ff_on2avc_tabs_19_40_1[19]; -extern const double* ff_on2avc_tabs_19_40_2[19]; -extern const double* ff_on2avc_tabs_20_84_1[20]; -extern const double* ff_on2avc_tabs_20_84_2[20]; -extern const double* ff_on2avc_tabs_20_84_3[20]; -extern const double* ff_on2avc_tabs_20_84_4[20]; +extern const double * const ff_on2avc_tabs_4_10_1[4]; +extern const double * const ff_on2avc_tabs_4_10_2[4]; +extern const double * const ff_on2avc_tabs_9_20_1[9]; +extern const double * const ff_on2avc_tabs_9_20_2[9]; +extern const double * const ff_on2avc_tabs_19_40_1[19]; +extern const double * const ff_on2avc_tabs_19_40_2[19]; +extern const double * const ff_on2avc_tabs_20_84_1[20]; +extern const double * const ff_on2avc_tabs_20_84_2[20]; +extern const double * const ff_on2avc_tabs_20_84_3[20]; +extern const double * const ff_on2avc_tabs_20_84_4[20]; extern const float ff_on2avc_ctab_1[2048]; extern const float ff_on2avc_ctab_2[2048]; extern const float ff_on2avc_ctab_3[2048]; diff --git a/libavcodec/opus_silk.c b/libavcodec/opus_silk.c index 5db1b26c6f807..e5d1a9923d7c0 100644 --- a/libavcodec/opus_silk.c +++ b/libavcodec/opus_silk.c @@ -1323,7 +1323,7 @@ static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc, if (lag_absolute) { /* primary lag is coded absolute */ int highbits, lowbits; - static const uint16_t *model[] = { + static const uint16_t * const model[] = { silk_model_pitch_lowbits_nb, silk_model_pitch_lowbits_mb, silk_model_pitch_lowbits_wb }; @@ -1357,11 +1357,11 @@ static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc, ltpfilter = opus_rc_getsymbol(rc, silk_model_ltp_filter); for (i = 0; i < s->subframes; i++) { int index, j; - static const uint16_t *filter_sel[] = { + static const uint16_t * const filter_sel[] = { silk_model_ltp_filter0_sel, silk_model_ltp_filter1_sel, silk_model_ltp_filter2_sel }; - static const int8_t (*filter_taps[])[5] = { + static const int8_t (* const filter_taps[])[5] = { silk_ltp_filter0_taps, silk_ltp_filter1_taps, silk_ltp_filter2_taps }; index = opus_rc_getsymbol(rc, filter_sel[ltpfilter]); diff --git a/libavcodec/qsvdec_h2645.c b/libavcodec/qsvdec_h2645.c index 6624fbecc77f3..a2a6cc3c47464 100644 --- a/libavcodec/qsvdec_h2645.c +++ b/libavcodec/qsvdec_h2645.c @@ -84,8 +84,8 @@ static av_cold int qsv_decode_init(AVCodecContext *avctx) int ret; if (avctx->codec_id == AV_CODEC_ID_HEVC && s->load_plugin != LOAD_PLUGIN_NONE) { - static const char *uid_hevcdec_sw = "15dd936825ad475ea34e35f3f54217a6"; - static const char *uid_hevcdec_hw = "33a61c0b4c27454ca8d85dde757c6f8e"; + static const char * const uid_hevcdec_sw = "15dd936825ad475ea34e35f3f54217a6"; + static const char * const uid_hevcdec_hw = "33a61c0b4c27454ca8d85dde757c6f8e"; if (s->qsv.load_plugins[0]) { av_log(avctx, AV_LOG_WARNING, diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c index c51309f9c68ec..27ff0c6feb7df 100644 --- a/libavcodec/qsvenc_hevc.c +++ b/libavcodec/qsvenc_hevc.c @@ -161,8 +161,8 @@ static av_cold int qsv_enc_init(AVCodecContext *avctx) int ret; if (q->load_plugin != LOAD_PLUGIN_NONE) { - static const char *uid_hevcenc_sw = "2fca99749fdb49aeb121a5b63ef568f7"; - static const char *uid_hevcenc_hw = "6fadc791a0c2eb479ab6dcd5ea9da347"; + static const char * const uid_hevcenc_sw = "2fca99749fdb49aeb121a5b63ef568f7"; + static const char * const uid_hevcenc_hw = "6fadc791a0c2eb479ab6dcd5ea9da347"; if (q->qsv.load_plugins[0]) { av_log(avctx, AV_LOG_WARNING, diff --git a/libavcodec/sipr.c b/libavcodec/sipr.c index cf29d3bba7cc1..5d2bdbdcba1ae 100644 --- a/libavcodec/sipr.c +++ b/libavcodec/sipr.c @@ -139,7 +139,7 @@ const float ff_pow_0_5[] = { 1.0/(1 << 13), 1.0/(1 << 14), 1.0/(1 << 15), 1.0/(1 << 16) }; -static void dequant(float *out, const int *idx, const float *cbs[]) +static void dequant(float *out, const int *idx, const float * const cbs[]) { int i; int stride = 2; diff --git a/libavcodec/sipr16k.c b/libavcodec/sipr16k.c index f7fcb34315034..6a0ef8d98c24b 100644 --- a/libavcodec/sipr16k.c +++ b/libavcodec/sipr16k.c @@ -51,7 +51,7 @@ static void lsf2lsp(const float *lsf, double *lsp) lsp[i] = cosf(lsf[i]); } -static void dequant(float *out, const int *idx, const float *cbs[]) +static void dequant(float *out, const int *idx, const float * const cbs[]) { int i; diff --git a/libavcodec/sipr16kdata.h b/libavcodec/sipr16kdata.h index ec60c29b51e29..7677a69a1897d 100644 --- a/libavcodec/sipr16kdata.h +++ b/libavcodec/sipr16kdata.h @@ -525,7 +525,7 @@ static const float lsf_cb5_16k[128][4] = { { 0.124405, 0.009943, -0.148477, -0.205184} }; -static const float *lsf_codebooks_16k[] = { +static const float * const lsf_codebooks_16k[] = { lsf_cb1_16k[0], lsf_cb2_16k[0], lsf_cb3_16k[0], lsf_cb4_16k[0], lsf_cb5_16k[0] }; diff --git a/libavcodec/siprdata.h b/libavcodec/siprdata.h index 92037a4a87fb2..2644d59d57674 100644 --- a/libavcodec/siprdata.h +++ b/libavcodec/siprdata.h @@ -206,7 +206,7 @@ static const float lsf_cb5[32][2] = { { 0.150514, 0.034366}, { 0.186092, -0.069272} }; -static const float *lsf_codebooks[] = { +static const float * const lsf_codebooks[] = { lsf_cb1[0], lsf_cb2[0], lsf_cb3[0], lsf_cb4[0], lsf_cb5[0] }; diff --git a/libavcodec/tscc2data.h b/libavcodec/tscc2data.h index ac0a898177e44..bcadc094a2ee3 100644 --- a/libavcodec/tscc2data.h +++ b/libavcodec/tscc2data.h @@ -903,14 +903,14 @@ static const int tscc2_ac_vlc_sizes[NUM_VLC_SETS] = { 172, 169, 165, 162, 131, 132, 130, 125, 121, 114, 110, 101, 96 }; -static const uint16_t *tscc2_ac_vlc_syms[NUM_VLC_SETS] = { +static const uint16_t * const tscc2_ac_vlc_syms[NUM_VLC_SETS] = { ac_vlc_desc0_syms, ac_vlc_desc1_syms, ac_vlc_desc2_syms, ac_vlc_desc3_syms, ac_vlc_desc4_syms, ac_vlc_desc5_syms, ac_vlc_desc6_syms, ac_vlc_desc7_syms, ac_vlc_desc8_syms, ac_vlc_desc9_syms, ac_vlc_descA_syms, ac_vlc_descB_syms, ac_vlc_descC_syms, }; -static const uint16_t *tscc2_ac_vlc_codes[NUM_VLC_SETS] = { +static const uint16_t * const tscc2_ac_vlc_codes[NUM_VLC_SETS] = { ac_vlc_desc0_codes, ac_vlc_desc1_codes, ac_vlc_desc2_codes, ac_vlc_desc3_codes, ac_vlc_desc4_codes, ac_vlc_desc5_codes, ac_vlc_desc6_codes, ac_vlc_desc7_codes, ac_vlc_desc8_codes, @@ -918,7 +918,7 @@ static const uint16_t *tscc2_ac_vlc_codes[NUM_VLC_SETS] = { ac_vlc_descC_codes, }; -static const uint8_t *tscc2_ac_vlc_bits[NUM_VLC_SETS] = { +static const uint8_t * const tscc2_ac_vlc_bits[NUM_VLC_SETS] = { ac_vlc_desc0_bits, ac_vlc_desc1_bits, ac_vlc_desc2_bits, ac_vlc_desc3_bits, ac_vlc_desc4_bits, ac_vlc_desc5_bits, ac_vlc_desc6_bits, ac_vlc_desc7_bits, ac_vlc_desc8_bits, ac_vlc_desc9_bits, ac_vlc_descA_bits, ac_vlc_descB_bits, diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index 8238952543fcb..c02b633b4679d 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -27,7 +27,7 @@ #include "vaapi_encode.h" #include "avcodec.h" -static const char *picture_type_name[] = { "IDR", "I", "P", "B" }; +static const char * const picture_type_name[] = { "IDR", "I", "P", "B" }; static int vaapi_encode_make_packed_header(AVCodecContext *avctx, VAAPIEncodePicture *pic, diff --git a/libavcodec/vaapi_encode_mjpeg.c b/libavcodec/vaapi_encode_mjpeg.c index 78d5e789f1b33..b96715146dde4 100644 --- a/libavcodec/vaapi_encode_mjpeg.c +++ b/libavcodec/vaapi_encode_mjpeg.c @@ -361,7 +361,7 @@ static av_cold int vaapi_encode_mjpeg_configure(AVCodecContext *avctx) return 0; } -static VAAPIEncodeType vaapi_encode_type_mjpeg = { +static const VAAPIEncodeType vaapi_encode_type_mjpeg = { .priv_data_size = sizeof(VAAPIEncodeMJPEGContext), .configure = &vaapi_encode_mjpeg_configure, diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index bf1b03e9f77ef..43580a3a813e0 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -1166,10 +1166,10 @@ void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y, uint8_t *segment, uint8_t *ref, int layout, int is_vp7) { VP56RangeCoder *c = &s->c; - static const char *vp7_feature_name[] = { "q-index", - "lf-delta", - "partial-golden-update", - "blit-pitch" }; + static const char * const vp7_feature_name[] = { "q-index", + "lf-delta", + "partial-golden-update", + "blit-pitch" }; if (is_vp7) { int i; *segment = 0; diff --git a/libavcodec/vp9block.c b/libavcodec/vp9block.c index 194d619ce2277..35c9c27c5386f 100644 --- a/libavcodec/vp9block.c +++ b/libavcodec/vp9block.c @@ -842,8 +842,8 @@ static int decode_coeffs(AVCodecContext *avctx) int uvstep1d = 1 << b->uvtx, uvstep = 1 << (b->uvtx * 2), ret; int16_t (*qmul)[2] = s->segmentation.feat[b->seg_id].qmul; int tx = 4 * s->lossless + b->tx; - const int16_t **yscans = ff_vp9_scans[tx]; - const int16_t (**ynbs)[2] = ff_vp9_scans_nb[tx]; + const int16_t * const *yscans = ff_vp9_scans[tx]; + const int16_t (* const * ynbs)[2] = ff_vp9_scans_nb[tx]; const int16_t *uvscan = ff_vp9_scans[b->uvtx][DCT_DCT]; const int16_t (*uvnb)[2] = ff_vp9_scans_nb[b->uvtx][DCT_DCT]; uint8_t *a = &s->above_y_nnz_ctx[col * 2]; diff --git a/libavcodec/vp9data.c b/libavcodec/vp9data.c index 374fa8bb8cedd..2b678781b81ce 100644 --- a/libavcodec/vp9data.c +++ b/libavcodec/vp9data.c @@ -483,7 +483,7 @@ const int16_t ff_vp9_default_scan_32x32[1024] = { 924, 925, 956, 926, 957, 988, 927, 958, 989, 1020, 959, 990, 1021, 991, 1022, 1023, }; -const int16_t *ff_vp9_scans[5][4] = { +const int16_t * const ff_vp9_scans[5][4] = { { ff_vp9_default_scan_4x4, ff_vp9_col_scan_4x4, ff_vp9_row_scan_4x4, ff_vp9_default_scan_4x4 @@ -1040,7 +1040,7 @@ const int16_t ff_vp9_default_scan_32x32_nb[1024][2] = { { 990, 959 }, { 1021, 990 }, { 1022, 991 }, { 0, 0 }, }; -const int16_t (*ff_vp9_scans_nb[5][4])[2] = { +const int16_t (* const ff_vp9_scans_nb[5][4])[2] = { { ff_vp9_default_scan_4x4_nb, ff_vp9_col_scan_4x4_nb, ff_vp9_row_scan_4x4_nb, ff_vp9_default_scan_4x4_nb diff --git a/libavcodec/vp9data.h b/libavcodec/vp9data.h index a52cc0a353177..f9ad9119d17ac 100644 --- a/libavcodec/vp9data.h +++ b/libavcodec/vp9data.h @@ -48,7 +48,7 @@ extern const int16_t ff_vp9_default_scan_16x16[256]; extern const int16_t ff_vp9_col_scan_16x16[256]; extern const int16_t ff_vp9_row_scan_16x16[256]; extern const int16_t ff_vp9_default_scan_32x32[1024]; -extern const int16_t *ff_vp9_scans[5][4]; +extern const int16_t * const ff_vp9_scans[5][4]; extern const int16_t ff_vp9_default_scan_4x4_nb[16][2]; extern const int16_t ff_vp9_col_scan_4x4_nb[16][2]; extern const int16_t ff_vp9_row_scan_4x4_nb[16][2]; @@ -59,7 +59,7 @@ extern const int16_t ff_vp9_default_scan_16x16_nb[256][2]; extern const int16_t ff_vp9_col_scan_16x16_nb[256][2]; extern const int16_t ff_vp9_row_scan_16x16_nb[256][2]; extern const int16_t ff_vp9_default_scan_32x32_nb[1024][2]; -extern const int16_t (*ff_vp9_scans_nb[5][4])[2]; +extern const int16_t (* const ff_vp9_scans_nb[5][4])[2]; extern const uint8_t ff_vp9_model_pareto8[256][8]; extern const ProbContext ff_vp9_default_probs; extern const uint8_t ff_vp9_default_coef_probs[4][2][2][6][6][3]; diff --git a/libavcodec/x86/fdct.c b/libavcodec/x86/fdct.c index 6528b57361f77..e01509eaef0c7 100644 --- a/libavcodec/x86/fdct.c +++ b/libavcodec/x86/fdct.c @@ -70,7 +70,7 @@ DECLARE_ALIGNED(16, static const int16_t, fdct_one_corr)[8] = { X8(1) }; DECLARE_ALIGNED(8, static const int32_t, fdct_r_row)[2] = {RND_FRW_ROW, RND_FRW_ROW }; -static struct +static const struct { DECLARE_ALIGNED(16, const int32_t, fdct_r_row_sse2)[4]; } fdct_r_row_sse2 = @@ -153,7 +153,7 @@ DECLARE_ALIGNED(8, static const int16_t, tab_frw_01234567)[] = { // forward_dct 29692, -12299, 26722, -31521, }; -static struct +static const struct { DECLARE_ALIGNED(16, const int16_t, tab_frw_01234567_sse2)[256]; } tab_frw_01234567_sse2 = diff --git a/libavcodec/x86/mlpdsp.c b/libavcodec/x86/mlpdsp.c index 72fc637764dcb..157ba7c9079c6 100644 --- a/libavcodec/x86/mlpdsp.c +++ b/libavcodec/x86/mlpdsp.c @@ -45,14 +45,14 @@ extern char ff_mlp_iirorder_2; extern char ff_mlp_iirorder_1; extern char ff_mlp_iirorder_0; -static const void *firtable[9] = { &ff_mlp_firorder_0, &ff_mlp_firorder_1, - &ff_mlp_firorder_2, &ff_mlp_firorder_3, - &ff_mlp_firorder_4, &ff_mlp_firorder_5, - &ff_mlp_firorder_6, &ff_mlp_firorder_7, - &ff_mlp_firorder_8 }; -static const void *iirtable[5] = { &ff_mlp_iirorder_0, &ff_mlp_iirorder_1, - &ff_mlp_iirorder_2, &ff_mlp_iirorder_3, - &ff_mlp_iirorder_4 }; +static const void * const firtable[9] = { &ff_mlp_firorder_0, &ff_mlp_firorder_1, + &ff_mlp_firorder_2, &ff_mlp_firorder_3, + &ff_mlp_firorder_4, &ff_mlp_firorder_5, + &ff_mlp_firorder_6, &ff_mlp_firorder_7, + &ff_mlp_firorder_8 }; +static const void * const iirtable[5] = { &ff_mlp_iirorder_0, &ff_mlp_iirorder_1, + &ff_mlp_iirorder_2, &ff_mlp_iirorder_3, + &ff_mlp_iirorder_4 }; #if ARCH_X86_64 diff --git a/libavcodec/x86/videodsp_init.c b/libavcodec/x86/videodsp_init.c index 8ee837096aef2..d5bfe010f77e6 100644 --- a/libavcodec/x86/videodsp_init.c +++ b/libavcodec/x86/videodsp_init.c @@ -59,7 +59,7 @@ extern emu_edge_vfix_func ff_emu_edge_vfix20_mmx; extern emu_edge_vfix_func ff_emu_edge_vfix21_mmx; extern emu_edge_vfix_func ff_emu_edge_vfix22_mmx; #if ARCH_X86_32 -static emu_edge_vfix_func *vfixtbl_mmx[22] = { +static emu_edge_vfix_func * const vfixtbl_mmx[22] = { &ff_emu_edge_vfix1_mmx, &ff_emu_edge_vfix2_mmx, &ff_emu_edge_vfix3_mmx, &ff_emu_edge_vfix4_mmx, &ff_emu_edge_vfix5_mmx, &ff_emu_edge_vfix6_mmx, &ff_emu_edge_vfix7_mmx, &ff_emu_edge_vfix8_mmx, &ff_emu_edge_vfix9_mmx, @@ -78,7 +78,7 @@ extern emu_edge_vfix_func ff_emu_edge_vfix19_sse; extern emu_edge_vfix_func ff_emu_edge_vfix20_sse; extern emu_edge_vfix_func ff_emu_edge_vfix21_sse; extern emu_edge_vfix_func ff_emu_edge_vfix22_sse; -static emu_edge_vfix_func *vfixtbl_sse[22] = { +static emu_edge_vfix_func * const vfixtbl_sse[22] = { ff_emu_edge_vfix1_mmx, ff_emu_edge_vfix2_mmx, ff_emu_edge_vfix3_mmx, ff_emu_edge_vfix4_mmx, ff_emu_edge_vfix5_mmx, ff_emu_edge_vfix6_mmx, ff_emu_edge_vfix7_mmx, ff_emu_edge_vfix8_mmx, ff_emu_edge_vfix9_mmx, @@ -107,7 +107,7 @@ extern emu_edge_hfix_func ff_emu_edge_hfix18_mmx; extern emu_edge_hfix_func ff_emu_edge_hfix20_mmx; extern emu_edge_hfix_func ff_emu_edge_hfix22_mmx; #if ARCH_X86_32 -static emu_edge_hfix_func *hfixtbl_mmx[11] = { +static emu_edge_hfix_func * const hfixtbl_mmx[11] = { ff_emu_edge_hfix2_mmx, ff_emu_edge_hfix4_mmx, ff_emu_edge_hfix6_mmx, ff_emu_edge_hfix8_mmx, ff_emu_edge_hfix10_mmx, ff_emu_edge_hfix12_mmx, ff_emu_edge_hfix14_mmx, ff_emu_edge_hfix16_mmx, ff_emu_edge_hfix18_mmx, @@ -119,7 +119,7 @@ extern emu_edge_hfix_func ff_emu_edge_hfix16_sse2; extern emu_edge_hfix_func ff_emu_edge_hfix18_sse2; extern emu_edge_hfix_func ff_emu_edge_hfix20_sse2; extern emu_edge_hfix_func ff_emu_edge_hfix22_sse2; -static emu_edge_hfix_func *hfixtbl_sse2[11] = { +static emu_edge_hfix_func * const hfixtbl_sse2[11] = { ff_emu_edge_hfix2_mmx, ff_emu_edge_hfix4_mmx, ff_emu_edge_hfix6_mmx, ff_emu_edge_hfix8_mmx, ff_emu_edge_hfix10_mmx, ff_emu_edge_hfix12_mmx, ff_emu_edge_hfix14_mmx, ff_emu_edge_hfix16_sse2, ff_emu_edge_hfix18_sse2, @@ -133,9 +133,9 @@ static av_always_inline void emulated_edge_mc(uint8_t *dst, const uint8_t *src, x86_reg block_w, x86_reg block_h, x86_reg src_x, x86_reg src_y, x86_reg w, x86_reg h, - emu_edge_vfix_func **vfix_tbl, + emu_edge_vfix_func * const *vfix_tbl, emu_edge_vvar_func *v_extend_var, - emu_edge_hfix_func **hfix_tbl, + emu_edge_hfix_func * const *hfix_tbl, emu_edge_hvar_func *h_extend_var) { x86_reg start_y, start_x, end_y, end_x, src_y_add = 0, p; diff --git a/libavfilter/af_volume.c b/libavfilter/af_volume.c index 11d85a17eb541..0ec42b031e1eb 100644 --- a/libavfilter/af_volume.c +++ b/libavfilter/af_volume.c @@ -38,7 +38,7 @@ #include "internal.h" #include "af_volume.h" -static const char *precision_str[] = { +static const char * const precision_str[] = { "fixed", "float", "double" }; diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index d119251712386..5668c8e8e0b23 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -219,7 +219,7 @@ static const AVClass drawtext_class = { #define FT_ERRORDEF(e, v, s) { (e), (s) }, #define FT_ERROR_END_LIST { 0, NULL } }; -static struct ft_error { +static const struct ft_error { int err; const char *err_msg; } ft_errors[] = diff --git a/libavfilter/vf_libopencv.c b/libavfilter/vf_libopencv.c index 50d02f84a8aa5..5a97e4bfb697b 100644 --- a/libavfilter/vf_libopencv.c +++ b/libavfilter/vf_libopencv.c @@ -321,7 +321,7 @@ typedef struct OCVFilterEntry { void (*end_frame_filter)(AVFilterContext *ctx, IplImage *inimg, IplImage *outimg); } OCVFilterEntry; -static OCVFilterEntry ocv_filter_entries[] = { +static const OCVFilterEntry ocv_filter_entries[] = { { "dilate", sizeof(DilateContext), dilate_init, dilate_uninit, dilate_end_frame_filter }, { "erode", sizeof(DilateContext), dilate_init, dilate_uninit, erode_end_frame_filter }, { "smooth", sizeof(SmoothContext), smooth_init, NULL, smooth_end_frame_filter }, @@ -333,7 +333,7 @@ static av_cold int init(AVFilterContext *ctx) int i; for (i = 0; i < FF_ARRAY_ELEMS(ocv_filter_entries); i++) { - OCVFilterEntry *entry = &ocv_filter_entries[i]; + const OCVFilterEntry *entry = &ocv_filter_entries[i]; if (!strcmp(s->name, entry->name)) { s->init = entry->init; s->uninit = entry->uninit; diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c index 2fa791d00126f..fb30993260a09 100644 --- a/libavfilter/vf_overlay.c +++ b/libavfilter/vf_overlay.c @@ -66,7 +66,7 @@ enum EOFAction { EOF_ACTION_PASS }; -static const char *eof_action_str[] = { +static const char * const eof_action_str[] = { "repeat", "endall", "pass" }; diff --git a/libavformat/hls.c b/libavformat/hls.c index 3b8e28038da5f..c9da4e30ecf59 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -477,8 +477,8 @@ static int read_data(void *opaque, uint8_t *buf, int buf_size) static int save_avio_options(AVFormatContext *s) { HLSContext *c = s->priv_data; - static const char *opts[] = { "headers", "user_agent", NULL }; - const char **opt = opts; + static const char * const opts[] = { "headers", "user_agent", NULL }; + const char * const *opt = opts; uint8_t *buf; int ret = 0; diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index 3f43b4aa8be15..643891c08202f 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -86,7 +86,7 @@ const char ff_id3v2_3_tags[][4] = { { 0 }, }; -const char *ff_id3v2_picture_types[21] = { +const char * const ff_id3v2_picture_types[21] = { "Other", "32x32 pixels 'file icon'", "Other file icon", diff --git a/libavformat/id3v2.h b/libavformat/id3v2.h index 7cb4296f111fa..2d65a4dcb4202 100644 --- a/libavformat/id3v2.h +++ b/libavformat/id3v2.h @@ -158,6 +158,6 @@ extern const char ff_id3v2_3_tags[][4]; extern const CodecMime ff_id3v2_mime_tags[]; -extern const char *ff_id3v2_picture_types[21]; +extern const char * const ff_id3v2_picture_types[21]; #endif /* AVFORMAT_ID3V2_H */ diff --git a/libavformat/mov_chan.c b/libavformat/mov_chan.c index 1b05cdff4e25f..42decb1e816c2 100644 --- a/libavformat/mov_chan.c +++ b/libavformat/mov_chan.c @@ -344,7 +344,7 @@ static const struct MovChannelLayoutMap mov_ch_layout_map_9ch[] = { { 0, 0 }, }; -static const struct MovChannelLayoutMap *mov_ch_layout_map[] = { +static const struct MovChannelLayoutMap * const mov_ch_layout_map[] = { mov_ch_layout_map_misc, mov_ch_layout_map_1ch, mov_ch_layout_map_2ch, diff --git a/libavformat/movenc.c b/libavformat/movenc.c index ac76dedca40fc..440370e2592ce 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -3529,7 +3529,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) if (par->codec_id == AV_CODEC_ID_AMR_NB) { /* We must find out how many AMR blocks there are in one packet */ - static uint16_t packed_size[16] = + static const uint16_t packed_size[16] = {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 1}; int len = 0; diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 1c7c280188842..cf4931e7318d6 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -981,7 +981,7 @@ static const MXFCodecUL mxf_data_essence_container_uls[] = { { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x09,0x0d,0x01,0x03,0x01,0x02,0x0e,0x00,0x00 }, 16, AV_CODEC_ID_NONE }, }; -static const char* mxf_data_essence_descriptor[] = { +static const char * const mxf_data_essence_descriptor[] = { "vbi_vanc_smpte_436M", }; diff --git a/libavresample/audio_mix.c b/libavresample/audio_mix.c index 8ff82a2b94a22..89ecc6ba71c72 100644 --- a/libavresample/audio_mix.c +++ b/libavresample/audio_mix.c @@ -28,7 +28,7 @@ #include "audio_data.h" #include "audio_mix.h" -static const char *coeff_type_names[] = { "q8", "q15", "flt" }; +static const char * const coeff_type_names[] = { "q8", "q15", "flt" }; struct AudioMix { AVAudioResampleContext *avr; diff --git a/libavutil/hwcontext.c b/libavutil/hwcontext.c index 83f733e9f95f8..608da6872761f 100644 --- a/libavutil/hwcontext.c +++ b/libavutil/hwcontext.c @@ -28,7 +28,7 @@ #include "pixdesc.h" #include "pixfmt.h" -static const HWContextType *hw_table[] = { +static const HWContextType * const hw_table[] = { #if CONFIG_CUDA &ff_hwcontext_type_cuda, #endif diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index b2e212c1fe518..f8719aaf0adb4 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -84,7 +84,7 @@ typedef struct VAAPIMapping { } // The map fourcc <-> pix_fmt isn't bijective because of the annoying U/V // plane swap cases. The frame handling below tries to hide these. -static struct { +static const struct { unsigned int fourcc; unsigned int rt_format; enum AVPixelFormat pix_fmt; diff --git a/libavutil/parseutils.c b/libavutil/parseutils.c index f4248114b5715..d9d5839f67c6e 100644 --- a/libavutil/parseutils.c +++ b/libavutil/parseutils.c @@ -152,7 +152,7 @@ typedef struct ColorEntry { uint8_t rgb_color[3]; ///< RGB values for the color } ColorEntry; -static ColorEntry color_table[] = { +static const ColorEntry color_table[] = { { "AliceBlue", { 0xF0, 0xF8, 0xFF } }, { "AntiqueWhite", { 0xFA, 0xEB, 0xD7 } }, { "Aqua", { 0x00, 0xFF, 0xFF } }, diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index 2f1adf5d8dda5..d69eeea9de7bd 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -1764,13 +1764,13 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { FF_ENABLE_DEPRECATION_WARNINGS #endif -static const char *color_range_names[] = { +static const char * const color_range_names[] = { [AVCOL_RANGE_UNSPECIFIED] = "unknown", [AVCOL_RANGE_MPEG] = "tv", [AVCOL_RANGE_JPEG] = "pc", }; -static const char *color_primaries_names[] = { +static const char * const color_primaries_names[] = { [AVCOL_PRI_RESERVED0] = "reserved", [AVCOL_PRI_BT709] = "bt709", [AVCOL_PRI_UNSPECIFIED] = "unknown", @@ -1787,7 +1787,7 @@ static const char *color_primaries_names[] = { [AVCOL_PRI_JEDEC_P22] = "jedec-p22", }; -static const char *color_transfer_names[] = { +static const char * const color_transfer_names[] = { [AVCOL_TRC_RESERVED0] = "reserved", [AVCOL_TRC_BT709] = "bt709", [AVCOL_TRC_UNSPECIFIED] = "unknown", @@ -1809,7 +1809,7 @@ static const char *color_transfer_names[] = { [AVCOL_TRC_ARIB_STD_B67] = "arib-std-b67", }; -static const char *color_space_names[] = { +static const char * const color_space_names[] = { [AVCOL_SPC_RGB] = "gbr", [AVCOL_SPC_BT709] = "bt709", [AVCOL_SPC_UNSPECIFIED] = "unknown", @@ -1824,7 +1824,7 @@ static const char *color_space_names[] = { [AVCOL_SPC_SMPTE2085] = "smpte2085", }; -static const char *chroma_location_names[] = { +static const char * const chroma_location_names[] = { [AVCHROMA_LOC_UNSPECIFIED] = "unspecified", [AVCHROMA_LOC_LEFT] = "left", [AVCHROMA_LOC_CENTER] = "center", diff --git a/libavutil/stereo3d.c b/libavutil/stereo3d.c index 0d72609cd0754..5dc902e909451 100644 --- a/libavutil/stereo3d.c +++ b/libavutil/stereo3d.c @@ -43,7 +43,7 @@ AVStereo3D *av_stereo3d_create_side_data(AVFrame *frame) return (AVStereo3D *)side_data->data; } -static const char *stereo3d_type_names[] = { +static const char * const stereo3d_type_names[] = { [AV_STEREO3D_2D] = "2D", [AV_STEREO3D_SIDEBYSIDE] = "side by side", [AV_STEREO3D_TOPBOTTOM] = "top and bottom", From 3ad825793a43253154bed05827f27425fc0757df Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 16 Jan 2017 16:42:17 +0100 Subject: [PATCH 0850/3374] hwcontext_cuda: implement frames_get_constraints Copied and modified from hwcontext_qsv.c. Signed-off-by: Anton Khirnov --- libavutil/hwcontext_cuda.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/libavutil/hwcontext_cuda.c b/libavutil/hwcontext_cuda.c index 260783426a7f6..fc9b8b429859b 100644 --- a/libavutil/hwcontext_cuda.c +++ b/libavutil/hwcontext_cuda.c @@ -37,6 +37,31 @@ static const enum AVPixelFormat supported_formats[] = { AV_PIX_FMT_YUV444P16, }; +static int cuda_frames_get_constraints(AVHWDeviceContext *ctx, + const void *hwconfig, + AVHWFramesConstraints *constraints) +{ + int i; + + constraints->valid_sw_formats = av_malloc_array(FF_ARRAY_ELEMS(supported_formats) + 1, + sizeof(*constraints->valid_sw_formats)); + if (!constraints->valid_sw_formats) + return AVERROR(ENOMEM); + + for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) + constraints->valid_sw_formats[i] = supported_formats[i]; + constraints->valid_sw_formats[FF_ARRAY_ELEMS(supported_formats)] = AV_PIX_FMT_NONE; + + constraints->valid_hw_formats = av_malloc_array(2, sizeof(*constraints->valid_hw_formats)); + if (!constraints->valid_hw_formats) + return AVERROR(ENOMEM); + + constraints->valid_hw_formats[0] = AV_PIX_FMT_CUDA; + constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE; + + return 0; +} + static void cuda_buffer_free(void *opaque, uint8_t *data) { AVHWFramesContext *ctx = opaque; @@ -326,6 +351,7 @@ const HWContextType ff_hwcontext_type_cuda = { .frames_priv_size = sizeof(CUDAFramesContext), .device_create = cuda_device_create, + .frames_get_constraints = cuda_frames_get_constraints, .frames_init = cuda_frames_init, .frames_get_buffer = cuda_get_buffer, .transfer_get_formats = cuda_transfer_get_formats, From 577326d430593a25456393a75212b95d1cd94131 Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 16 Jan 2017 17:32:18 +0100 Subject: [PATCH 0851/3374] lavc: deprecate refcounted_frames field No deprecation guards, because the old decode API (for which this field is needed) doesn't have any either. This field should be removed together with the old decode calls. Signed-off-by: Anton Khirnov --- doc/APIchanges | 6 ++++++ libavcodec/avcodec.h | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index c8c2a219f63d7..c161618d92f0f 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,12 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-02-01 - xxxxxxx - lavc - avcodec.h + Deprecate AVCodecContext.refcounted_frames. This was useful for deprecated + API only (avcodec_decode_video2/avcodec_decode_audio4). The new decode APIs + (avcodec_send_packet/avcodec_receive_frame) always work with reference + counted frames. + 2016-xx-xx - xxxxxxx - lavc 57.31.0 - avcodec.h Add AVCodecContext.apply_cropping to control whether cropping is handled by libavcodec or the caller. diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 18721561d54c8..8d8fa594aa280 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -2327,7 +2327,7 @@ typedef struct AVCodecContext { * - encoding: unused * - decoding: set by the caller before avcodec_open2(). */ - int refcounted_frames; + attribute_deprecated int refcounted_frames; /* - encoding parameters */ float qcompress; ///< amount of qscale change between easy & hard scenes (0.0-1.0) From b3825723dceffc64240da7b0e562bd1fd024da26 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 20 Jan 2017 15:29:57 +0100 Subject: [PATCH 0852/3374] configure: Merge compiler/libc/os hacks sections --- configure | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/configure b/configure index 64c077465d2fd..79898184c2ec1 100755 --- a/configure +++ b/configure @@ -4115,26 +4115,25 @@ test -n "$libc_type" && enable libc_$libc_type probe_libc host_ test -n "$host_libc_type" && enable host_libc_$host_libc_type +# hacks for compiler/libc/os combinations + case $libc_type in bionic) add_compat strtod.o strtod=avpriv_strtod ;; + glibc) + if enabled tms470; then + CPPFLAGS="-I${source_path}/compat/tms470 ${CPPFLAGS}" + add_cppflags -D__USER_LABEL_PREFIX__= + add_cppflags -D__builtin_memset=memset + add_cppflags -D__gnuc_va_list=va_list -D_VA_LIST_DEFINED + add_cflags -pds=48 # incompatible redefinition of macro + elif enabled ccc; then + add_ldflags -Wl,-z,now # calls to libots crash without this + fi + ;; esac -# hacks for compiler/libc/os combinations - -if enabled_all tms470 libc_glibc; then - CPPFLAGS="-I${source_path}/compat/tms470 ${CPPFLAGS}" - add_cppflags -D__USER_LABEL_PREFIX__= - add_cppflags -D__builtin_memset=memset - add_cppflags -D__gnuc_va_list=va_list -D_VA_LIST_DEFINED - add_cflags -pds=48 # incompatible redefinition of macro -fi - -if enabled_all ccc libc_glibc; then - add_ldflags -Wl,-z,now # calls to libots crash without this -fi - check_compile_assert flt_lim "float.h limits.h" "DBL_MAX == (double)DBL_MAX" || add_cppflags '-I\$(SRC_PATH)/compat/float' From 24d5680bbc01fc124709d522d348572ad4672563 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 20 Jan 2017 15:30:36 +0100 Subject: [PATCH 0853/3374] configure: Simplify inline asm check with appropriate helper function --- configure | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/configure b/configure index 79898184c2ec1..4a8d04d21073a 100755 --- a/configure +++ b/configure @@ -4183,9 +4183,7 @@ EOF sym=$($nm $TMPO | awk '/ff_extern/{ print substr($0, match($0, /[^ \t]*ff_extern/)) }') extern_prefix=${sym%%ff_extern*} -check_cc < Date: Mon, 23 Jan 2017 17:59:56 +0100 Subject: [PATCH 0854/3374] configure: Add proper weak dependency of drawtext filter on libfontconfig --- configure | 1 + 1 file changed, 1 insertion(+) diff --git a/configure b/configure index 4a8d04d21073a..e3f1a91235b87 100755 --- a/configure +++ b/configure @@ -2453,6 +2453,7 @@ deinterlace_qsv_filter_deps="libmfx" deinterlace_vaapi_filter_deps="vaapi" delogo_filter_deps="gpl" drawtext_filter_deps="libfreetype" +drawtext_filter_suggest="libfontconfig" frei0r_filter_deps="frei0r dlopen" frei0r_filter_extralibs='$ldl' frei0r_src_filter_deps="frei0r dlopen" From acfa7a2178f08fd81b66279959cd55ec3ae237e2 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 23 Jan 2017 13:17:24 +0100 Subject: [PATCH 0855/3374] configure: Drop weak dependencies on external libraries for webm muxer Weak dependencies on external libraries do not obviate having to explicitly enable these libraries, so the weak dependency does not simplify the configure command line nor have any real effect. --- configure | 1 - 1 file changed, 1 deletion(-) diff --git a/configure b/configure index e3f1a91235b87..d77eb3d0bbb46 100755 --- a/configure +++ b/configure @@ -2376,7 +2376,6 @@ w64_demuxer_select="wav_demuxer" wav_demuxer_select="riffdec" wav_muxer_select="riffenc" webm_muxer_select="iso_media riffenc" -webm_muxer_suggest="libopus_encoder libvorbis_encoder libvpx_vp8_encoder libvpx_vp9_encoder" wtv_demuxer_select="mpegts_demuxer riffdec" xmv_demuxer_select="riffdec" xwma_demuxer_select="riffdec" From c29da01ac95ea2c8c5c4b3a312a33aaaa8fb7068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Thu, 17 Mar 2016 14:21:24 +0100 Subject: [PATCH 0856/3374] svq3: Convert to the new bitstream reader --- libavcodec/svq3.c | 132 +++++++++++++++++++++++----------------------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index 8bbd331de3fbf..20c8f89e76e15 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -44,7 +44,8 @@ #include "libavutil/attributes.h" -#include "golomb_legacy.h" +#include "bitstream.h" +#include "golomb.h" #include "internal.h" #include "avcodec.h" #include "mpegutils.h" @@ -92,8 +93,8 @@ typedef struct SVQ3Context { SVQ3Frame *cur_pic; SVQ3Frame *next_pic; SVQ3Frame *last_pic; - GetBitContext gb; - GetBitContext gb_slice; + BitstreamContext bc; + BitstreamContext bc_slice; uint8_t *slice_buf; int slice_size; int halfpel_flag; @@ -292,7 +293,7 @@ static void svq3_add_idct_c(uint8_t *dst, int16_t *block, memset(block, 0, 16 * sizeof(int16_t)); } -static inline int svq3_decode_block(GetBitContext *gb, int16_t *block, +static inline int svq3_decode_block(BitstreamContext *bc, int16_t *block, int index, const int type) { static const uint8_t *const scan_patterns[4] = { @@ -305,7 +306,7 @@ static inline int svq3_decode_block(GetBitContext *gb, int16_t *block, const uint8_t *const scan = scan_patterns[type]; for (limit = (16 >> intra); index < 16; index = limit, limit += 8) { - for (; (vlc = get_interleaved_ue_golomb(gb)) != 0; index++) { + for (; (vlc = get_interleaved_ue_golomb(bc)) != 0; index++) { int sign = (vlc & 1) ? 0 : -1; vlc = vlc + 1 >> 1; @@ -542,8 +543,8 @@ static inline int svq3_mc_dir(SVQ3Context *s, int size, int mode, if (mode == PREDICT_MODE) { dx = dy = 0; } else { - dy = get_interleaved_se_golomb(&s->gb_slice); - dx = get_interleaved_se_golomb(&s->gb_slice); + dy = get_interleaved_se_golomb(&s->bc_slice); + dx = get_interleaved_se_golomb(&s->bc_slice); if (dx == INVALID_VLC || dy == INVALID_VLC) { av_log(s->avctx, AV_LOG_ERROR, "invalid MV vlc\n"); @@ -744,10 +745,10 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) mb_type = MB_TYPE_16x16; } } else if (mb_type < 8) { /* INTER */ - if (s->thirdpel_flag && s->halfpel_flag == !get_bits1(&s->gb_slice)) + if (s->thirdpel_flag && s->halfpel_flag == !bitstream_read_bit(&s->bc_slice)) mode = THIRDPEL_MODE; else if (s->halfpel_flag && - s->thirdpel_flag == !get_bits1(&s->gb_slice)) + s->thirdpel_flag == !bitstream_read_bit(&s->bc_slice)) mode = HALFPEL_MODE; else mode = FULLPEL_MODE; @@ -849,7 +850,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) /* decode prediction codes for luma blocks */ for (i = 0; i < 16; i += 2) { - vlc = get_interleaved_ue_golomb(&s->gb_slice); + vlc = get_interleaved_ue_golomb(&s->bc_slice); if (vlc >= 25) { av_log(s->avctx, AV_LOG_ERROR, @@ -927,7 +928,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) if (!IS_INTRA16x16(mb_type) && (!IS_SKIP(mb_type) || s->pict_type == AV_PICTURE_TYPE_B)) { - if ((vlc = get_interleaved_ue_golomb(&s->gb_slice)) >= 48) { + if ((vlc = get_interleaved_ue_golomb(&s->bc_slice)) >= 48) { av_log(s->avctx, AV_LOG_ERROR, "cbp_vlc=%"PRIu32"\n", vlc); return -1; } @@ -937,7 +938,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) } if (IS_INTRA16x16(mb_type) || (s->pict_type != AV_PICTURE_TYPE_I && s->adaptive_quant && cbp)) { - s->qscale += get_interleaved_se_golomb(&s->gb_slice); + s->qscale += get_interleaved_se_golomb(&s->bc_slice); if (s->qscale > 31u) { av_log(s->avctx, AV_LOG_ERROR, "qscale:%d\n", s->qscale); @@ -947,7 +948,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) if (IS_INTRA16x16(mb_type)) { AV_ZERO128(s->mb_luma_dc[0] + 0); AV_ZERO128(s->mb_luma_dc[0] + 8); - if (svq3_decode_block(&s->gb_slice, s->mb_luma_dc[0], 0, 1)) { + if (svq3_decode_block(&s->bc_slice, s->mb_luma_dc[0], 0, 1)) { av_log(s->avctx, AV_LOG_ERROR, "error while decoding intra luma dc\n"); return -1; @@ -966,7 +967,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) : (4 * i + j); s->non_zero_count_cache[scan8[k]] = 1; - if (svq3_decode_block(&s->gb_slice, &s->mb[16 * k], index, type)) { + if (svq3_decode_block(&s->bc_slice, &s->mb[16 * k], index, type)) { av_log(s->avctx, AV_LOG_ERROR, "error while decoding block\n"); return -1; @@ -976,7 +977,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) if ((cbp & 0x30)) { for (i = 1; i < 3; ++i) - if (svq3_decode_block(&s->gb_slice, &s->mb[16 * 16 * i], 0, 3)) { + if (svq3_decode_block(&s->bc_slice, &s->mb[16 * 16 * i], 0, 3)) { av_log(s->avctx, AV_LOG_ERROR, "error while decoding chroma dc block\n"); return -1; @@ -988,7 +989,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) k = 16 * i + j; s->non_zero_count_cache[scan8[k]] = 1; - if (svq3_decode_block(&s->gb_slice, &s->mb[16 * k], 1, 1)) { + if (svq3_decode_block(&s->bc_slice, &s->mb[16 * k], 1, 1)) { av_log(s->avctx, AV_LOG_ERROR, "error while decoding chroma ac block\n"); return -1; @@ -1016,7 +1017,7 @@ static int svq3_decode_slice_header(AVCodecContext *avctx) int i, header; unsigned slice_id; - header = get_bits(&s->gb, 8); + header = bitstream_read(&s->bc, 8); if (((header & 0x9F) != 1 && (header & 0x9F) != 2) || (header & 0x60) == 0) { /* TODO: what? */ @@ -1026,36 +1027,35 @@ static int svq3_decode_slice_header(AVCodecContext *avctx) int slice_bits, slice_bytes, slice_length; int length = header >> 5 & 3; - slice_length = show_bits(&s->gb, 8 * length); + slice_length = bitstream_peek(&s->bc, 8 * length); slice_bits = slice_length * 8; slice_bytes = slice_length + length - 1; - if (slice_bytes > get_bits_left(&s->gb)) { + if (slice_bytes > bitstream_bits_left(&s->bc)) { av_log(avctx, AV_LOG_ERROR, "slice after bitstream end\n"); return -1; } - skip_bits(&s->gb, 8); + bitstream_skip(&s->bc, 8); av_fast_malloc(&s->slice_buf, &s->slice_size, slice_bytes + AV_INPUT_BUFFER_PADDING_SIZE); if (!s->slice_buf) return AVERROR(ENOMEM); - memcpy(s->slice_buf, s->gb.buffer + s->gb.index / 8, slice_bytes); - - init_get_bits(&s->gb_slice, s->slice_buf, slice_bits); + memcpy(s->slice_buf, s->bc.buffer + bitstream_tell(&s->bc) / 8, slice_bytes); if (s->watermark_key) { - uint32_t header = AV_RL32(&s->gb_slice.buffer[1]); - AV_WL32(&s->gb_slice.buffer[1], header ^ s->watermark_key); + uint32_t header = AV_RL32(&s->bc_slice.buffer[1]); + AV_WL32(&s->bc_slice.buffer[1], header ^ s->watermark_key); } if (length > 0) { memcpy(s->slice_buf, &s->slice_buf[slice_length], length - 1); } - skip_bits_long(&s->gb, slice_bytes * 8); + bitstream_skip(&s->bc, slice_bytes * 8); + bitstream_init(&s->bc_slice, s->slice_buf, slice_bits); } - if ((slice_id = get_interleaved_ue_golomb(&s->gb_slice)) >= 3) { + if ((slice_id = get_interleaved_ue_golomb(&s->bc_slice)) >= 3) { av_log(s->avctx, AV_LOG_ERROR, "illegal slice type %u \n", slice_id); return -1; } @@ -1064,26 +1064,26 @@ static int svq3_decode_slice_header(AVCodecContext *avctx) if ((header & 0x9F) == 2) { i = (s->mb_num < 64) ? 6 : (1 + av_log2(s->mb_num - 1)); - get_bits(&s->gb_slice, i); + bitstream_read(&s->bc_slice, i); } else { - skip_bits1(&s->gb_slice); + bitstream_skip(&s->bc_slice, 1); } - s->slice_num = get_bits(&s->gb_slice, 8); - s->qscale = get_bits(&s->gb_slice, 5); - s->adaptive_quant = get_bits1(&s->gb_slice); + s->slice_num = bitstream_read(&s->bc_slice, 8); + s->qscale = bitstream_read(&s->bc_slice, 5); + s->adaptive_quant = bitstream_read_bit(&s->bc_slice); /* unknown fields */ - skip_bits1(&s->gb_slice); + bitstream_skip(&s->bc_slice, 1); if (s->unknown_flag) - skip_bits1(&s->gb_slice); + bitstream_skip(&s->bc_slice, 1); - skip_bits1(&s->gb_slice); - skip_bits(&s->gb_slice, 2); + bitstream_skip(&s->bc_slice, 1); + bitstream_skip(&s->bc_slice, 2); - while (get_bits1(&s->gb_slice)) - skip_bits(&s->gb_slice, 8); + while (bitstream_read_bit(&s->bc_slice)) + bitstream_skip(&s->bc_slice, 8); /* reset intra predictors and invalidate motion vector references */ if (s->mb_x > 0) { @@ -1172,16 +1172,16 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) /* if a match was found, parse the extra data */ if (marker_found) { - GetBitContext gb; + BitstreamContext bc; int frame_size_code; size = AV_RB32(&extradata[4]); if (size > extradata_end - extradata - 8) return AVERROR_INVALIDDATA; - init_get_bits(&gb, extradata + 8, size * 8); + bitstream_init8(&bc, extradata + 8, size); /* 'frame size code' and optional 'width, height' */ - frame_size_code = get_bits(&gb, 3); + frame_size_code = bitstream_read(&bc, 3); switch (frame_size_code) { case 0: avctx->width = 160; @@ -1212,41 +1212,41 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) avctx->height = 240; break; case 7: - avctx->width = get_bits(&gb, 12); - avctx->height = get_bits(&gb, 12); + avctx->width = bitstream_read(&bc, 12); + avctx->height = bitstream_read(&bc, 12); break; } - s->halfpel_flag = get_bits1(&gb); - s->thirdpel_flag = get_bits1(&gb); + s->halfpel_flag = bitstream_read_bit(&bc); + s->thirdpel_flag = bitstream_read_bit(&bc); /* unknown fields */ - skip_bits1(&gb); - skip_bits1(&gb); - skip_bits1(&gb); - skip_bits1(&gb); + bitstream_skip(&bc, 1); + bitstream_skip(&bc, 1); + bitstream_skip(&bc, 1); + bitstream_skip(&bc, 1); - s->low_delay = get_bits1(&gb); + s->low_delay = bitstream_read_bit(&bc); /* unknown field */ - skip_bits1(&gb); + bitstream_skip(&bc, 1); - while (get_bits1(&gb)) - skip_bits(&gb, 8); + while (bitstream_read_bit(&bc)) + bitstream_skip(&bc, 8); - s->unknown_flag = get_bits1(&gb); + s->unknown_flag = bitstream_read_bit(&bc); avctx->has_b_frames = !s->low_delay; if (s->unknown_flag) { #if CONFIG_ZLIB - unsigned watermark_width = get_interleaved_ue_golomb(&gb); - unsigned watermark_height = get_interleaved_ue_golomb(&gb); - int u1 = get_interleaved_ue_golomb(&gb); - int u2 = get_bits(&gb, 8); - int u3 = get_bits(&gb, 2); - int u4 = get_interleaved_ue_golomb(&gb); + unsigned watermark_width = get_interleaved_ue_golomb(&bc); + unsigned watermark_height = get_interleaved_ue_golomb(&bc); + int u1 = get_interleaved_ue_golomb(&bc); + int u2 = bitstream_read(&bc, 8); + int u3 = bitstream_read(&bc, 2); + int u4 = get_interleaved_ue_golomb(&bc); unsigned long buf_len = watermark_width * watermark_height * 4; - int offset = get_bits_count(&gb) + 7 >> 3; + int offset = bitstream_tell(&bc) + 7 >> 3; uint8_t *buf; if (watermark_height > 0 && @@ -1388,7 +1388,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, return 0; } - ret = init_get_bits(&s->gb, buf, 8 * buf_size); + ret = bitstream_init8(&s->bc, buf, buf_size); if (ret < 0) return ret; @@ -1501,9 +1501,9 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, unsigned mb_type; s->mb_xy = s->mb_x + s->mb_y * s->mb_stride; - if ((get_bits_left(&s->gb_slice)) <= 7) { - if (((get_bits_count(&s->gb_slice) & 7) == 0 || - show_bits(&s->gb_slice, get_bits_left(&s->gb_slice) & 7) == 0)) { + if ((bitstream_bits_left(&s->bc_slice)) <= 7) { + if (((bitstream_tell(&s->bc_slice) & 7) == 0 || + bitstream_peek(&s->bc_slice, bitstream_bits_left(&s->bc_slice) & 7) == 0)) { if (svq3_decode_slice_header(avctx)) return -1; @@ -1511,7 +1511,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, /* TODO: support s->mb_skip_run */ } - mb_type = get_interleaved_ue_golomb(&s->gb_slice); + mb_type = get_interleaved_ue_golomb(&s->bc_slice); if (s->pict_type == AV_PICTURE_TYPE_I) mb_type += 8; From a97563c889fefd81ad6b3758471434d8c2e2e550 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 22 Jan 2017 16:05:25 +0100 Subject: [PATCH 0857/3374] configure: Simplify libxcb check --- configure | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/configure b/configure index d77eb3d0bbb46..070edcae1e33b 100755 --- a/configure +++ b/configure @@ -2401,6 +2401,7 @@ sndio_outdev_deps="sndio" v4l2_indev_deps_any="linux_videodev2_h sys_videoio_h" vfwcap_indev_deps="vfw32 vfwcap_defines" xcbgrab_indev_deps="libxcb" +xcbgrab_indev_suggest="libxcb_shm libxcb_xfixes" # protocols ffrtmpcrypt_protocol_deps="!librtmp_protocol" @@ -4783,22 +4784,11 @@ if enabled libcdio; then fi if enabled libxcb; then - check_pkg_config xcb-shape xcb/shape.h xcb_shape_rectangles || { - enabled libxcb && die "ERROR: libxcb not found"; - } && enable libxcb - + require_pkg_config xcb-shape xcb/shape.h xcb_shape_rectangles disabled libxcb_shm || - check_pkg_config xcb-shm xcb/shm.h xcb_shm_attach || { - enabled libxcb_shm && die "ERROR: libxcb_shm not found"; - } && check_header sys/shm.h && enable libxcb_shm - + require_pkg_config xcb-shm xcb/shm.h xcb_shm_attach disabled libxcb_xfixes || - check_pkg_config xcb-xfixes xcb/xfixes.h xcb_xfixes_get_cursor_image || { - enabled libxcb_xfixes && die "ERROR: libxcb_xfixes not found"; - } && enable libxcb_xfixes - - add_cflags "$xcb_shape_cflags $xcb_shm_cflags $xcb_xfixes_cflags" - add_extralibs "$xcb_shape_extralibs $xcb_shm_extralibs $xcb_xfixes_extralibs" + require_pkg_config xcb-xfixes xcb/xfixes.h xcb_xfixes_get_cursor_image fi enabled dxva2 && From aba7fdcc8baaed35e804c7882b70a848a0e566c7 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 22 Jan 2017 16:04:09 +0100 Subject: [PATCH 0858/3374] configure: Add require_header() convenience function Simplifies checking for external library headers and aborting if the external library support was requested, but is not available. --- configure | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/configure b/configure index 070edcae1e33b..30f053954bccf 100755 --- a/configure +++ b/configure @@ -1117,6 +1117,13 @@ require(){ check_lib $name "$headers" $func "$@" || die "ERROR: $name_version not found" } +require_header(){ + log require "$@" + header="$1" + shift + check_header "$header" "$@" || die "ERROR: $header not found" +} + require_pkg_config(){ log require_pkg_config "$@" pkg_version="$1" @@ -4636,10 +4643,10 @@ for func in $MATH_FUNCS; do done # these are off by default, so fail if requested and not available -enabled avisynth && { check_header avisynth/avisynth_c.h || die "ERROR: avisynth/avisynth_c.h header not found"; } +enabled avisynth && require_header avisynth/avisynth_c.h enabled avxsynth && require avxsynth "avxsynth/avxsynth_c.h dlfcn.h" dlopen -ldl enabled cuda && require cuda cuda.h cuInit -lcuda -enabled frei0r && { check_header frei0r.h || die "ERROR: frei0r.h header not found"; } +enabled frei0r && require_header frei0r.h enabled gnutls && require_pkg_config gnutls gnutls/gnutls.h gnutls_global_init enabled libbs2b && require_pkg_config libbs2b bs2b.h bs2b_open enabled libdc1394 && require_pkg_config libdc1394-2 dc1394/dc1394.h dc1394_new @@ -4717,7 +4724,7 @@ enabled mmal && { check_lib mmal interface/mmal/mmal.h mmal_port_co enabled omx_rpi && { check_header OMX_Core.h || { ! enabled cross_compile && add_cflags -isystem/opt/vc/include/IL && check_header OMX_Core.h ; } || die "ERROR: OpenMAX IL headers not found"; } -enabled omx && { check_header OMX_Core.h || die "ERROR: OpenMAX IL headers not found"; } +enabled omx && require_header OMX_Core.h enabled openssl && { { check_pkg_config openssl openssl/ssl.h OPENSSL_init_ssl || check_pkg_config openssl openssl/ssl.h SSL_library_init; } && { add_cflags $openssl_cflags && add_extralibs $openssl_extralibs; } || @@ -4729,7 +4736,7 @@ enabled openssl && { { check_pkg_config openssl openssl/ssl.h OPENSSL_ enabled gnutls && check_lib gmp gmp.h mpz_export -lgmp if enabled nvenc; then - check_header nvEncodeAPI.h || die "ERROR: nvEncodeAPI.h not found." + require_header nvEncodeAPI.h check_cpp_condition nvEncodeAPI.h "NVENCAPI_MAJOR_VERSION >= 6" || die "ERROR: NVENC API version 5 or older is not supported" fi From bcaedef1189a3531aa4dfb020627eb0133ffa89c Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 22 Jan 2017 16:15:38 +0100 Subject: [PATCH 0859/3374] configure: Add require_cpp_condition() convenience function Simplifies checking for conditions in external library headers and aborting if said conditions are not met. --- configure | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/configure b/configure index 30f053954bccf..555dc8861ea27 100755 --- a/configure +++ b/configure @@ -1124,6 +1124,14 @@ require_header(){ check_header "$header" "$@" || die "ERROR: $header not found" } +require_cpp_condition(){ + log require "$@" + header="$1" + condition="$2" + shift 2 + check_cpp_condition "$header" "$condition" "$@" || die "ERROR: $condition not satisfied" +} + require_pkg_config(){ log require_pkg_config "$@" pkg_version="$1" @@ -4705,13 +4713,11 @@ enabled libvpx && require_pkg_config "vpx >= 1.3.0" vpx/vpx_codec.h v enabled libwavpack && require libwavpack wavpack/wavpack.h WavpackOpenFileOutput -lwavpack enabled libwebp && require_pkg_config libwebp webp/encode.h WebPGetEncoderVersion enabled libx264 && require_pkg_config x264 "stdint.h x264.h" x264_encoder_encode && - { check_cpp_condition x264.h "X264_BUILD >= 118" || - die "ERROR: libx264 version must be >= 0.118."; } && + require_cpp_condition x264.h "X264_BUILD >= 118" && { check_cpp_condition x264.h "X264_MPEG2" && enable libx262; } enabled libx265 && require_pkg_config x265 x265.h x265_api_get && - { check_cpp_condition x265.h "X265_BUILD >= 57" || - die "ERROR: libx265 version must be >= 57."; } + require_cpp_condition x265.h "X265_BUILD >= 57" enabled libxavs && require libxavs "stdint.h xavs.h" xavs_encoder_encode -lxavs enabled libxvid && require libxvid xvid.h xvid_global -lxvidcore enabled mmal && { check_lib mmal interface/mmal/mmal.h mmal_port_connect -lmmal_core -lmmal_util -lmmal_vc_client -lbcm_host || @@ -4737,8 +4743,7 @@ enabled gnutls && check_lib gmp gmp.h mpz_export -lgmp if enabled nvenc; then require_header nvEncodeAPI.h - check_cpp_condition nvEncodeAPI.h "NVENCAPI_MAJOR_VERSION >= 6" || - die "ERROR: NVENC API version 5 or older is not supported" + require_cpp_condition nvEncodeAPI.h "NVENCAPI_MAJOR_VERSION >= 6" fi if check_pkg_config sdl SDL_events.h SDL_PollEvent; then From a1a143adb0fd11c474221431417cff25db7d920f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 31 Jan 2017 15:47:00 +0200 Subject: [PATCH 0860/3374] rtmp: Rename packet types to closer match the spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also rename comments and log messages accordingly, and add clarifying comments for some hardcoded values. The previous names were taken from older, reverse engineered references. These names match the official public rtmp specification, and matches the names used by wirecast in annotating captured streams. These names also avoid hardcoding the roles of server and client, since the handling of them is irrelevant of whether we act as server or client. The RTMP_PT_PING type maps to RTMP_PT_USER_CONTROL. The SERVER_BW and CLIENT_BW types are a bit more intertwined; RTMP_PT_SERVER_BW maps to RTMP_PT_WINDOW_ACK_SIZE and RTMP_PT_CLIENT_BW maps to RTMP_PT_SET_PEER_BW. Signed-off-by: Martin Storsjö --- libavformat/rtmppkt.c | 14 ++++----- libavformat/rtmppkt.h | 6 ++-- libavformat/rtmpproto.c | 66 ++++++++++++++++++++--------------------- 3 files changed, 43 insertions(+), 43 deletions(-) diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c index 1cb30786794ec..0bb06143b5fe4 100644 --- a/libavformat/rtmppkt.c +++ b/libavformat/rtmppkt.c @@ -527,9 +527,9 @@ static const char* rtmp_packet_type(int type) switch (type) { case RTMP_PT_CHUNK_SIZE: return "chunk size"; case RTMP_PT_BYTES_READ: return "bytes read"; - case RTMP_PT_PING: return "ping"; - case RTMP_PT_SERVER_BW: return "server bandwidth"; - case RTMP_PT_CLIENT_BW: return "client bandwidth"; + case RTMP_PT_USER_CONTROL: return "user control"; + case RTMP_PT_WINDOW_ACK_SIZE: return "window acknowledgement size"; + case RTMP_PT_SET_PEER_BW: return "set peer bandwidth"; case RTMP_PT_AUDIO: return "audio packet"; case RTMP_PT_VIDEO: return "video packet"; case RTMP_PT_FLEX_STREAM: return "Flex shared stream"; @@ -627,10 +627,10 @@ void ff_rtmp_packet_dump(void *ctx, RTMPPacket *p) break; src += sz; } - } else if (p->type == RTMP_PT_SERVER_BW){ - av_log(ctx, AV_LOG_DEBUG, "Server BW = %d\n", AV_RB32(p->data)); - } else if (p->type == RTMP_PT_CLIENT_BW){ - av_log(ctx, AV_LOG_DEBUG, "Client BW = %d\n", AV_RB32(p->data)); + } else if (p->type == RTMP_PT_WINDOW_ACK_SIZE) { + av_log(ctx, AV_LOG_DEBUG, "Window acknowledgement size = %d\n", AV_RB32(p->data)); + } else if (p->type == RTMP_PT_SET_PEER_BW) { + av_log(ctx, AV_LOG_DEBUG, "Set Peer BW = %d\n", AV_RB32(p->data)); } else if (p->type != RTMP_PT_AUDIO && p->type != RTMP_PT_VIDEO && p->type != RTMP_PT_METADATA) { int i; for (i = 0; i < p->size; i++) diff --git a/libavformat/rtmppkt.h b/libavformat/rtmppkt.h index 149c153cad780..eccd299b248b3 100644 --- a/libavformat/rtmppkt.h +++ b/libavformat/rtmppkt.h @@ -47,9 +47,9 @@ enum RTMPChannel { typedef enum RTMPPacketType { RTMP_PT_CHUNK_SIZE = 1, ///< chunk size change RTMP_PT_BYTES_READ = 3, ///< number of bytes read - RTMP_PT_PING, ///< ping - RTMP_PT_SERVER_BW, ///< server bandwidth - RTMP_PT_CLIENT_BW, ///< client bandwidth + RTMP_PT_USER_CONTROL, ///< user control + RTMP_PT_WINDOW_ACK_SIZE, ///< window acknowledgement size + RTMP_PT_SET_PEER_BW, ///< peer bandwidth RTMP_PT_AUDIO = 8, ///< audio packet RTMP_PT_VIDEO, ///< video packet RTMP_PT_FLEX_STREAM = 15, ///< Flex shared stream diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 49a40dd66ab82..d0a36139ccc1a 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -453,7 +453,7 @@ static int read_connect(URLContext *s, RTMPContext *rt) // Send Window Acknowledgement Size (as defined in specification) if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, - RTMP_PT_SERVER_BW, 0, 4)) < 0) + RTMP_PT_WINDOW_ACK_SIZE, 0, 4)) < 0) return ret; p = pkt.data; bytestream_put_be32(&p, rt->server_bw); @@ -463,9 +463,9 @@ static int read_connect(URLContext *s, RTMPContext *rt) ff_rtmp_packet_destroy(&pkt); if (ret < 0) return ret; - // Send Peer Bandwidth + // Set Peer Bandwidth if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, - RTMP_PT_CLIENT_BW, 0, 5)) < 0) + RTMP_PT_SET_PEER_BW, 0, 5)) < 0) return ret; p = pkt.data; bytestream_put_be32(&p, rt->server_bw); @@ -477,14 +477,14 @@ static int read_connect(URLContext *s, RTMPContext *rt) if (ret < 0) return ret; - // Ping request + // User control if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, - RTMP_PT_PING, 0, 6)) < 0) + RTMP_PT_USER_CONTROL, 0, 6)) < 0) return ret; p = pkt.data; bytestream_put_be16(&p, 0); // 0 -> Stream Begin - bytestream_put_be32(&p, 0); + bytestream_put_be32(&p, 0); // Stream 0 ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size, &rt->prev_pkt[1], &rt->nb_prev_pkt[1]); ff_rtmp_packet_destroy(&pkt); @@ -710,12 +710,12 @@ static int gen_buffer_time(URLContext *s, RTMPContext *rt) uint8_t *p; int ret; - if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING, + if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_USER_CONTROL, 1, 10)) < 0) return ret; p = pkt.data; - bytestream_put_be16(&p, 3); + bytestream_put_be16(&p, 3); // SetBuffer Length bytestream_put_be32(&p, rt->stream_id); bytestream_put_be32(&p, rt->client_buffer_time); @@ -842,12 +842,12 @@ static int gen_pong(URLContext *s, RTMPContext *rt, RTMPPacket *ppkt) return AVERROR_INVALIDDATA; } - if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING, + if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL,RTMP_PT_USER_CONTROL, ppkt->timestamp + 1, 6)) < 0) return ret; p = pkt.data; - bytestream_put_be16(&p, 7); + bytestream_put_be16(&p, 7); // PingResponse bytestream_put_be32(&p, AV_RB32(ppkt->data+2)); return rtmp_send_packet(rt, &pkt, 0); @@ -863,7 +863,7 @@ static int gen_swf_verification(URLContext *s, RTMPContext *rt) int ret; av_log(s, AV_LOG_DEBUG, "Sending SWF verification...\n"); - if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING, + if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_USER_CONTROL, 0, 44)) < 0) return ret; @@ -875,15 +875,15 @@ static int gen_swf_verification(URLContext *s, RTMPContext *rt) } /** - * Generate server bandwidth message and send it to the server. + * Generate window acknowledgement size message and send it to the server. */ -static int gen_server_bw(URLContext *s, RTMPContext *rt) +static int gen_window_ack_size(URLContext *s, RTMPContext *rt) { RTMPPacket pkt; uint8_t *p; int ret; - if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_SERVER_BW, + if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_WINDOW_ACK_SIZE, 0, 4)) < 0) return ret; @@ -1520,19 +1520,19 @@ static int handle_chunk_size(URLContext *s, RTMPPacket *pkt) return 0; } -static int handle_ping(URLContext *s, RTMPPacket *pkt) +static int handle_user_control(URLContext *s, RTMPPacket *pkt) { RTMPContext *rt = s->priv_data; int t, ret; if (pkt->size < 2) { - av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n", + av_log(s, AV_LOG_ERROR, "Too short user control packet (%d)\n", pkt->size); return AVERROR_INVALIDDATA; } t = AV_RB16(pkt->data); - if (t == 6) { + if (t == 6) { // PingRequest if ((ret = gen_pong(s, rt, pkt)) < 0) return ret; } else if (t == 26) { @@ -1547,48 +1547,48 @@ static int handle_ping(URLContext *s, RTMPPacket *pkt) return 0; } -static int handle_client_bw(URLContext *s, RTMPPacket *pkt) +static int handle_set_peer_bw(URLContext *s, RTMPPacket *pkt) { RTMPContext *rt = s->priv_data; if (pkt->size < 4) { av_log(s, AV_LOG_ERROR, - "Client bandwidth report packet is less than 4 bytes long (%d)\n", + "Peer bandwidth packet is less than 4 bytes long (%d)\n", pkt->size); return AVERROR_INVALIDDATA; } rt->client_report_size = AV_RB32(pkt->data); if (rt->client_report_size <= 0) { - av_log(s, AV_LOG_ERROR, "Incorrect client bandwidth %d\n", + av_log(s, AV_LOG_ERROR, "Incorrect peer bandwidth %d\n", rt->client_report_size); return AVERROR_INVALIDDATA; } - av_log(s, AV_LOG_DEBUG, "Client bandwidth = %d\n", rt->client_report_size); + av_log(s, AV_LOG_DEBUG, "Peer bandwidth = %d\n", rt->client_report_size); rt->client_report_size >>= 1; return 0; } -static int handle_server_bw(URLContext *s, RTMPPacket *pkt) +static int handle_window_ack_size(URLContext *s, RTMPPacket *pkt) { RTMPContext *rt = s->priv_data; if (pkt->size < 4) { av_log(s, AV_LOG_ERROR, - "Too short server bandwidth report packet (%d)\n", + "Too short window acknowledgement size packet (%d)\n", pkt->size); return AVERROR_INVALIDDATA; } rt->server_bw = AV_RB32(pkt->data); if (rt->server_bw <= 0) { - av_log(s, AV_LOG_ERROR, "Incorrect server bandwidth %d\n", + av_log(s, AV_LOG_ERROR, "Incorrect window acknowledgement size %d\n", rt->server_bw); return AVERROR_INVALIDDATA; } - av_log(s, AV_LOG_DEBUG, "Server bandwidth = %d\n", rt->server_bw); + av_log(s, AV_LOG_DEBUG, "Window acknowledgement size = %d\n", rt->server_bw); return 0; } @@ -1825,7 +1825,7 @@ static int write_begin(URLContext *s) // Send Stream Begin 1 if ((ret = ff_rtmp_packet_create(&spkt, RTMP_NETWORK_CHANNEL, - RTMP_PT_PING, 0, 6)) < 0) { + RTMP_PT_USER_CONTROL, 0, 6)) < 0) { av_log(s, AV_LOG_ERROR, "Unable to create response packet\n"); return ret; } @@ -2053,7 +2053,7 @@ static int handle_invoke_result(URLContext *s, RTMPPacket *pkt) if ((ret = gen_fcpublish_stream(s, rt)) < 0) goto fail; } else { - if ((ret = gen_server_bw(s, rt)) < 0) + if ((ret = gen_window_ack_size(s, rt)) < 0) goto fail; } @@ -2302,16 +2302,16 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt) if ((ret = handle_chunk_size(s, pkt)) < 0) return ret; break; - case RTMP_PT_PING: - if ((ret = handle_ping(s, pkt)) < 0) + case RTMP_PT_USER_CONTROL: + if ((ret = handle_user_control(s, pkt)) < 0) return ret; break; - case RTMP_PT_CLIENT_BW: - if ((ret = handle_client_bw(s, pkt)) < 0) + case RTMP_PT_SET_PEER_BW: + if ((ret = handle_set_peer_bw(s, pkt)) < 0) return ret; break; - case RTMP_PT_SERVER_BW: - if ((ret = handle_server_bw(s, pkt)) < 0) + case RTMP_PT_WINDOW_ACK_SIZE: + if ((ret = handle_window_ack_size(s, pkt)) < 0) return ret; break; case RTMP_PT_INVOKE: From 15a92e0c402c830b607f905d6bf203b6cfb4fa8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 31 Jan 2017 16:15:56 +0200 Subject: [PATCH 0861/3374] rtmp: Correctly handle the Window Acknowledgement Size packets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This swaps which field is set when the Window Acknowledgement Size and Set Peer BW packets are received, renames the fields in order to clarify their role further and adds verbose comments explaining their respective roles and how well the code currently does what it is supposed to. The Set Peer BW packet tells the receiver of the packet (which can be either client or server) that it should not send more data if it already has sent more data than the specified number of bytes, without receiving acknowledgement for them. Actually checking this limit is currently not implemented. In order to be able to check that properly, one can send the Window Acknowledgement Size packet, which tells the receiver of the packet that it needs to send Acknowledgement packets (RTMP_PT_BYTES_READ) at least after receiving a given number of bytes since the last Acknowledgement. Therefore, when we receive a Window Acknowledgement Size packet, this sets the maximum number of bytes we can receive without sending an Acknowledgement; therefore when handling this packet we should set the receive_report_size field (previously client_report_size). Signed-off-by: Martin Storsjö --- libavformat/rtmpproto.c | 47 +++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index d0a36139ccc1a..8e036961a6da7 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -93,7 +93,7 @@ typedef struct RTMPContext { int flv_off; ///< number of bytes read from current buffer int flv_nb_packets; ///< number of flv packets published RTMPPacket out_pkt; ///< rtmp packet, created from flv a/v or metadata (for output) - uint32_t client_report_size; ///< number of bytes after which client should report to server + uint32_t receive_report_size; ///< number of bytes after which we should report the number of received bytes to the peer uint32_t bytes_read; ///< number of bytes read from server uint32_t last_bytes_read; ///< number of bytes read last reported to server uint32_t last_timestamp; ///< last timestamp received in a packet @@ -114,7 +114,7 @@ typedef struct RTMPContext { char swfverification[42]; ///< hash of the SWF verification char* pageurl; ///< url of the web page char* subscribe; ///< name of live stream to subscribe - int server_bw; ///< server bandwidth + int max_sent_unacked; ///< max unacked sent bytes int client_buffer_time; ///< client buffer time in ms int flush_interval; ///< number of packets flushed in the same request (RTMPT only) int encrypted; ///< use an encrypted connection (RTMPE only) @@ -456,7 +456,9 @@ static int read_connect(URLContext *s, RTMPContext *rt) RTMP_PT_WINDOW_ACK_SIZE, 0, 4)) < 0) return ret; p = pkt.data; - bytestream_put_be32(&p, rt->server_bw); + // Inform the peer about how often we want acknowledgements about what + // we send. (We don't check for the acknowledgements currently.) + bytestream_put_be32(&p, rt->max_sent_unacked); pkt.size = p - pkt.data; ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size, &rt->prev_pkt[1], &rt->nb_prev_pkt[1]); @@ -468,7 +470,9 @@ static int read_connect(URLContext *s, RTMPContext *rt) RTMP_PT_SET_PEER_BW, 0, 5)) < 0) return ret; p = pkt.data; - bytestream_put_be32(&p, rt->server_bw); + // Tell the peer to only send this many bytes unless it gets acknowledgements. + // This could be any arbitrary value we want here. + bytestream_put_be32(&p, rt->max_sent_unacked); bytestream_put_byte(&p, 2); // dynamic pkt.size = p - pkt.data; ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size, @@ -888,7 +892,7 @@ static int gen_window_ack_size(URLContext *s, RTMPContext *rt) return ret; p = pkt.data; - bytestream_put_be32(&p, rt->server_bw); + bytestream_put_be32(&p, rt->max_sent_unacked); return rtmp_send_packet(rt, &pkt, 0); } @@ -1558,15 +1562,18 @@ static int handle_set_peer_bw(URLContext *s, RTMPPacket *pkt) return AVERROR_INVALIDDATA; } - rt->client_report_size = AV_RB32(pkt->data); - if (rt->client_report_size <= 0) { - av_log(s, AV_LOG_ERROR, "Incorrect peer bandwidth %d\n", - rt->client_report_size); + // We currently don't check how much the peer has acknowledged of + // what we have sent. To do that properly, we should call + // gen_window_ack_size here, to tell the peer that we want an + // acknowledgement with (at least) that interval. + rt->max_sent_unacked = AV_RB32(pkt->data); + if (rt->max_sent_unacked <= 0) { + av_log(s, AV_LOG_ERROR, "Incorrect set peer bandwidth %d\n", + rt->max_sent_unacked); return AVERROR_INVALIDDATA; } - av_log(s, AV_LOG_DEBUG, "Peer bandwidth = %d\n", rt->client_report_size); - rt->client_report_size >>= 1; + av_log(s, AV_LOG_DEBUG, "Max sent, unacked = %d\n", rt->max_sent_unacked); return 0; } @@ -1582,13 +1589,17 @@ static int handle_window_ack_size(URLContext *s, RTMPPacket *pkt) return AVERROR_INVALIDDATA; } - rt->server_bw = AV_RB32(pkt->data); - if (rt->server_bw <= 0) { + rt->receive_report_size = AV_RB32(pkt->data); + if (rt->receive_report_size <= 0) { av_log(s, AV_LOG_ERROR, "Incorrect window acknowledgement size %d\n", - rt->server_bw); + rt->receive_report_size); return AVERROR_INVALIDDATA; } - av_log(s, AV_LOG_DEBUG, "Window acknowledgement size = %d\n", rt->server_bw); + av_log(s, AV_LOG_DEBUG, "Window acknowledgement size = %d\n", rt->receive_report_size); + // Send an Acknowledgement packet after receiving half the maximum + // size, to make sure the peer can keep on sending without waiting + // for acknowledgements. + rt->receive_report_size >>= 1; return 0; } @@ -2416,7 +2427,7 @@ static int get_packet(URLContext *s, int for_header) rt->last_timestamp = rpkt.timestamp; rt->bytes_read += ret; - if (rt->bytes_read - rt->last_bytes_read > rt->client_report_size) { + if (rt->bytes_read - rt->last_bytes_read > rt->receive_report_size) { av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n"); if ((ret = gen_bytes_read(s, rt, rpkt.timestamp + 1)) < 0) return ret; @@ -2765,13 +2776,13 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) } } - rt->client_report_size = 1048576; + rt->receive_report_size = 1048576; rt->bytes_read = 0; rt->has_audio = 0; rt->has_video = 0; rt->received_metadata = 0; rt->last_bytes_read = 0; - rt->server_bw = 2500000; + rt->max_sent_unacked = 2500000; rt->duration = 0; av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n", From 740b0bf03b4bb8b0a0e964750817ac0363a33c55 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 31 Jan 2017 15:46:50 +0100 Subject: [PATCH 0862/3374] build: Ignore generated .version files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f6d97b05f5379..1a08fd15c59c5 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ *.so.* *.swp *.ver +*.version /.config /.version /avconv From 7abdd026df6a9a52d07d8174505b33cc89db7bf6 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 1 Feb 2017 13:27:30 +0100 Subject: [PATCH 0863/3374] asm: Consistently uppercase SECTION markers --- libavcodec/x86/dnxhdenc.asm | 2 +- libavcodec/x86/hevc_idct.asm | 2 +- libavcodec/x86/vc1dsp.asm | 2 +- libavutil/x86/x86inc.asm | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/x86/dnxhdenc.asm b/libavcodec/x86/dnxhdenc.asm index d39b07b9f4582..091f322358505 100644 --- a/libavcodec/x86/dnxhdenc.asm +++ b/libavcodec/x86/dnxhdenc.asm @@ -22,7 +22,7 @@ %include "libavutil/x86/x86util.asm" -section .text +SECTION .text ; void get_pixels_8x4_sym_sse2(int16_t *block, const uint8_t *pixels, ; ptrdiff_t line_size) diff --git a/libavcodec/x86/hevc_idct.asm b/libavcodec/x86/hevc_idct.asm index f397cc1097b62..a36fa53c2d109 100644 --- a/libavcodec/x86/hevc_idct.asm +++ b/libavcodec/x86/hevc_idct.asm @@ -234,7 +234,7 @@ times 4 dw 78, -82 times 4 dw 85, -88 times 4 dw 90, -90 -section .text +SECTION .text ; void ff_hevc_idctHxW_dc_{8,10}_(int16_t *coeffs) ; %1 = HxW diff --git a/libavcodec/x86/vc1dsp.asm b/libavcodec/x86/vc1dsp.asm index adf08d7d84355..b9a770ee08873 100644 --- a/libavcodec/x86/vc1dsp.asm +++ b/libavcodec/x86/vc1dsp.asm @@ -24,7 +24,7 @@ cextern pw_4 cextern pw_5 -section .text +SECTION .text ; dst_low, dst_high (src), zero ; zero-extends one vector from 8 to 16 bits diff --git a/libavutil/x86/x86inc.asm b/libavutil/x86/x86inc.asm index 7941af304a73d..e04dbfedf343e 100644 --- a/libavutil/x86/x86inc.asm +++ b/libavutil/x86/x86inc.asm @@ -87,7 +87,7 @@ ; keep supporting OS/2. %macro SECTION_RODATA 0-1 16 %ifidn __OUTPUT_FORMAT__,aout - section .text + SECTION .text %else SECTION .rodata align=%1 %endif From 8e67039c6312ba520945f2c01b7b14df056d5ed1 Mon Sep 17 00:00:00 2001 From: John Stebbins Date: Thu, 12 Jan 2017 13:36:26 -0700 Subject: [PATCH 0864/3374] asfdec: Use the ASF stream count when iterating The AVFormat stream count can be larger due external factors, such as an id3 tag appended. Avoid an out of bound read. Signed-off-by: Luca Barbato --- libavformat/asfdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index 1c50ad627c3b4..d602af87934f7 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -1485,7 +1485,7 @@ static int asf_read_packet(AVFormatContext *s, AVPacket *pkt) asf->return_subpayload = 0; return 0; } - for (i = 0; i < s->nb_streams; i++) { + for (i = 0; i < asf->nb_streams; i++) { ASFPacket *asf_pkt = &asf->asf_st[i]->pkt; if (asf_pkt && !asf_pkt->size_left && asf_pkt->data_size) { if (asf->asf_st[i]->span > 1 && From 3bc5b28d5a191864c54bba60646933a63da31656 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 4 Feb 2017 22:16:09 +0200 Subject: [PATCH 0865/3374] arm: vp9itxfm: Avoid .irp when it doesn't save any lines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes it more readable. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index 5abe435be9e99..49b993ffe3552 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -690,21 +690,21 @@ function \txfm\()16_1d_4x16_pass1_neon @ for the first slice of the second pass (where it is the @ last 4x4 block). add r0, r0, #8 -.irp i, 20, 24, 28 - vst1.16 {d\i}, [r0,:64]! -.endr + vst1.16 {d20}, [r0,:64]! + vst1.16 {d24}, [r0,:64]! + vst1.16 {d28}, [r0,:64]! add r0, r0, #8 -.irp i, 21, 25, 29 - vst1.16 {d\i}, [r0,:64]! -.endr + vst1.16 {d21}, [r0,:64]! + vst1.16 {d25}, [r0,:64]! + vst1.16 {d29}, [r0,:64]! add r0, r0, #8 -.irp i, 22, 26, 30 - vst1.16 {d\i}, [r0,:64]! -.endr + vst1.16 {d22}, [r0,:64]! + vst1.16 {d26}, [r0,:64]! + vst1.16 {d30}, [r0,:64]! add r0, r0, #8 -.irp i, 23, 27, 31 - vst1.16 {d\i}, [r0,:64]! -.endr + vst1.16 {d23}, [r0,:64]! + vst1.16 {d27}, [r0,:64]! + vst1.16 {d31}, [r0,:64]! vmov d28, d16 vmov d29, d17 vmov d30, d18 From 58d87e0f49bcbbc6f426328f53b657bae7430cd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 1 Dec 2016 11:10:19 +0200 Subject: [PATCH 0866/3374] aarch64: vp9itxfm: Restructure the idct32 store macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids concatenation, which can't be used if the whole macro is wrapped within another macro. This is also arguably more readable. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 80 +++++++++++++++--------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index 7ce6df0a6de21..c14c5f9ded550 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -935,23 +935,23 @@ function idct32_1d_8x32_pass1_neon .macro store_rev a, b // There's no rev128 instruction, but we reverse each 64 bit // half, and then flip them using an ext with 8 bytes offset. - rev64 v1.8h, v\b\().8h - st1 {v\a\().8h}, [x0], #16 - rev64 v0.8h, v\a\().8h + rev64 v1.8h, \b + st1 {\a}, [x0], #16 + rev64 v0.8h, \a ext v1.16b, v1.16b, v1.16b, #8 - st1 {v\b\().8h}, [x0], #16 + st1 {\b}, [x0], #16 ext v0.16b, v0.16b, v0.16b, #8 st1 {v1.8h}, [x0], #16 st1 {v0.8h}, [x0], #16 .endm - store_rev 16, 24 - store_rev 17, 25 - store_rev 18, 26 - store_rev 19, 27 - store_rev 20, 28 - store_rev 21, 29 - store_rev 22, 30 - store_rev 23, 31 + store_rev v16.8h, v24.8h + store_rev v17.8h, v25.8h + store_rev v18.8h, v26.8h + store_rev v19.8h, v27.8h + store_rev v20.8h, v28.8h + store_rev v21.8h, v29.8h + store_rev v22.8h, v30.8h + store_rev v23.8h, v31.8h sub x0, x0, #512 .purgem store_rev @@ -977,14 +977,14 @@ function idct32_1d_8x32_pass1_neon // subtracted from the output. .macro store_rev a, b ld1 {v4.8h}, [x0] - rev64 v1.8h, v\b\().8h - add v4.8h, v4.8h, v\a\().8h - rev64 v0.8h, v\a\().8h + rev64 v1.8h, \b + add v4.8h, v4.8h, \a + rev64 v0.8h, \a st1 {v4.8h}, [x0], #16 ext v1.16b, v1.16b, v1.16b, #8 ld1 {v5.8h}, [x0] ext v0.16b, v0.16b, v0.16b, #8 - add v5.8h, v5.8h, v\b\().8h + add v5.8h, v5.8h, \b st1 {v5.8h}, [x0], #16 ld1 {v6.8h}, [x0] sub v6.8h, v6.8h, v1.8h @@ -994,14 +994,14 @@ function idct32_1d_8x32_pass1_neon st1 {v7.8h}, [x0], #16 .endm - store_rev 31, 23 - store_rev 30, 22 - store_rev 29, 21 - store_rev 28, 20 - store_rev 27, 19 - store_rev 26, 18 - store_rev 25, 17 - store_rev 24, 16 + store_rev v31.8h, v23.8h + store_rev v30.8h, v22.8h + store_rev v29.8h, v21.8h + store_rev v28.8h, v20.8h + store_rev v27.8h, v19.8h + store_rev v26.8h, v18.8h + store_rev v25.8h, v17.8h + store_rev v24.8h, v16.8h .purgem store_rev ret endfunc @@ -1047,21 +1047,21 @@ function idct32_1d_8x32_pass2_neon .if \neg == 0 ld1 {v4.8h}, [x2], x9 ld1 {v5.8h}, [x2], x9 - add v4.8h, v4.8h, v\a\().8h + add v4.8h, v4.8h, \a ld1 {v6.8h}, [x2], x9 - add v5.8h, v5.8h, v\b\().8h + add v5.8h, v5.8h, \b ld1 {v7.8h}, [x2], x9 - add v6.8h, v6.8h, v\c\().8h - add v7.8h, v7.8h, v\d\().8h + add v6.8h, v6.8h, \c + add v7.8h, v7.8h, \d .else ld1 {v4.8h}, [x2], x7 ld1 {v5.8h}, [x2], x7 - sub v4.8h, v4.8h, v\a\().8h + sub v4.8h, v4.8h, \a ld1 {v6.8h}, [x2], x7 - sub v5.8h, v5.8h, v\b\().8h + sub v5.8h, v5.8h, \b ld1 {v7.8h}, [x2], x7 - sub v6.8h, v6.8h, v\c\().8h - sub v7.8h, v7.8h, v\d\().8h + sub v6.8h, v6.8h, \c + sub v7.8h, v7.8h, \d .endif ld1 {v0.8b}, [x0], x1 ld1 {v1.8b}, [x0], x1 @@ -1085,15 +1085,15 @@ function idct32_1d_8x32_pass2_neon st1 {v6.8b}, [x0], x1 st1 {v7.8b}, [x0], x1 .endm - load_acc_store 31, 30, 29, 28 - load_acc_store 27, 26, 25, 24 - load_acc_store 23, 22, 21, 20 - load_acc_store 19, 18, 17, 16 + load_acc_store v31.8h, v30.8h, v29.8h, v28.8h + load_acc_store v27.8h, v26.8h, v25.8h, v24.8h + load_acc_store v23.8h, v22.8h, v21.8h, v20.8h + load_acc_store v19.8h, v18.8h, v17.8h, v16.8h sub x2, x2, x9 - load_acc_store 16, 17, 18, 19, 1 - load_acc_store 20, 21, 22, 23, 1 - load_acc_store 24, 25, 26, 27, 1 - load_acc_store 28, 29, 30, 31, 1 + load_acc_store v16.8h, v17.8h, v18.8h, v19.8h, 1 + load_acc_store v20.8h, v21.8h, v22.8h, v23.8h, 1 + load_acc_store v24.8h, v25.8h, v26.8h, v27.8h, 1 + load_acc_store v28.8h, v29.8h, v30.8h, v31.8h, 1 .purgem load_acc_store ret endfunc From f7ec7f546f0021d28da284b024416b916b61c974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Fri, 15 Apr 2016 10:46:06 +0200 Subject: [PATCH 0867/3374] wma: Convert to the new bitstream reader --- libavcodec/wma.c | 41 +++--- libavcodec/wma.h | 8 +- libavcodec/wmadec.c | 64 ++++----- libavcodec/wmalosslessdec.c | 188 +++++++++++++------------- libavcodec/wmaprodec.c | 207 ++++++++++++++-------------- libavcodec/wmavoice.c | 262 ++++++++++++++++++------------------ 6 files changed, 387 insertions(+), 383 deletions(-) diff --git a/libavcodec/wma.c b/libavcodec/wma.c index 4067dff11aa5c..697b41b0aaaca 100644 --- a/libavcodec/wma.c +++ b/libavcodec/wma.c @@ -22,6 +22,7 @@ #include "libavutil/attributes.h" #include "avcodec.h" +#include "bitstream.h" #include "internal.h" #include "sinewin.h" #include "wma.h" @@ -382,30 +383,30 @@ int ff_wma_end(AVCodecContext *avctx) /** * Decode an uncompressed coefficient. - * @param gb GetBitContext + * @param bc BitstreamContext * @return the decoded coefficient */ -unsigned int ff_wma_get_large_val(GetBitContext *gb) +unsigned int ff_wma_get_large_val(BitstreamContext *bc) { /** consumes up to 34 bits */ int n_bits = 8; /** decode length */ - if (get_bits1(gb)) { + if (bitstream_read_bit(bc)) { n_bits += 8; - if (get_bits1(gb)) { + if (bitstream_read_bit(bc)) { n_bits += 8; - if (get_bits1(gb)) + if (bitstream_read_bit(bc)) n_bits += 7; } } - return get_bits_long(gb, n_bits); + return bitstream_read(bc, n_bits); } /** * Decode run level compressed coefficients. * @param avctx codec context - * @param gb bitstream reader context - * @param vlc vlc table for get_vlc2 + * @param bc bitstream reader context + * @param vlc VLC table for bitstream_read_vlc * @param level_table level codes * @param run_table run codes * @param version 0 for wma1,2 1 for wmapro @@ -417,7 +418,7 @@ unsigned int ff_wma_get_large_val(GetBitContext *gb) * @param coef_nb_bits number of bits for escaped level codes * @return 0 on success, -1 otherwise */ -int ff_wma_run_level_decode(AVCodecContext *avctx, GetBitContext *gb, +int ff_wma_run_level_decode(AVCodecContext *avctx, BitstreamContext *bc, VLC *vlc, const float *level_table, const uint16_t *run_table, int version, WMACoef *ptr, int offset, int num_coefs, @@ -429,11 +430,11 @@ int ff_wma_run_level_decode(AVCodecContext *avctx, GetBitContext *gb, uint32_t *iptr = (uint32_t *) ptr; const unsigned int coef_mask = block_len - 1; for (; offset < num_coefs; offset++) { - code = get_vlc2(gb, vlc->table, VLCBITS, VLCMAX); + code = bitstream_read_vlc(bc, vlc->table, VLCBITS, VLCMAX); if (code > 1) { /** normal code */ offset += run_table[code]; - sign = get_bits1(gb) - 1; + sign = bitstream_read_bit(bc) - 1; iptr[offset & coef_mask] = ilvl[code] ^ sign << 31; } else if (code == 1) { /** EOB */ @@ -441,26 +442,26 @@ int ff_wma_run_level_decode(AVCodecContext *avctx, GetBitContext *gb, } else { /** escape */ if (!version) { - level = get_bits(gb, coef_nb_bits); + level = bitstream_read(bc, coef_nb_bits); /** NOTE: this is rather suboptimal. reading * block_len_bits would be better */ - offset += get_bits(gb, frame_len_bits); + offset += bitstream_read(bc, frame_len_bits); } else { - level = ff_wma_get_large_val(gb); + level = ff_wma_get_large_val(bc); /** escape decode */ - if (get_bits1(gb)) { - if (get_bits1(gb)) { - if (get_bits1(gb)) { + if (bitstream_read_bit(bc)) { + if (bitstream_read_bit(bc)) { + if (bitstream_read_bit(bc)) { av_log(avctx, AV_LOG_ERROR, "broken escape sequence\n"); return -1; } else - offset += get_bits(gb, frame_len_bits) + 4; + offset += bitstream_read(bc, frame_len_bits) + 4; } else - offset += get_bits(gb, 2) + 1; + offset += bitstream_read(bc, 2) + 1; } } - sign = get_bits1(gb) - 1; + sign = bitstream_read_bit(bc) - 1; ptr[offset & coef_mask] = (level ^ sign) - sign; } } diff --git a/libavcodec/wma.h b/libavcodec/wma.h index c954d71e289ac..6d14fc66c6d3b 100644 --- a/libavcodec/wma.h +++ b/libavcodec/wma.h @@ -25,8 +25,8 @@ #include "libavutil/float_dsp.h" #include "avcodec.h" +#include "bitstream.h" #include "fft.h" -#include "get_bits.h" #include "put_bits.h" /* size of blocks */ @@ -66,7 +66,7 @@ typedef struct CoefVLCTable { typedef struct WMACodecContext { AVCodecContext *avctx; - GetBitContext gb; + BitstreamContext bc; PutBitContext pb; int version; ///< 1 = 0x160 (WMAV1), 2 = 0x161 (WMAV2) int use_bit_reservoir; @@ -147,8 +147,8 @@ extern const uint8_t ff_aac_scalefactor_bits[121]; int ff_wma_init(AVCodecContext *avctx, int flags2); int ff_wma_total_gain_to_bits(int total_gain); int ff_wma_end(AVCodecContext *avctx); -unsigned int ff_wma_get_large_val(GetBitContext *gb); -int ff_wma_run_level_decode(AVCodecContext *avctx, GetBitContext *gb, +unsigned int ff_wma_get_large_val(BitstreamContext *bc); +int ff_wma_run_level_decode(AVCodecContext *avctx, BitstreamContext *bc, VLC *vlc, const float *level_table, const uint16_t *run_table, int version, WMACoef *ptr, int offset, int num_coefs, diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c index 50c77dd100cd7..fcbac931f9113 100644 --- a/libavcodec/wmadec.c +++ b/libavcodec/wmadec.c @@ -36,6 +36,7 @@ #include "libavutil/attributes.h" #include "avcodec.h" +#include "bitstream.h" #include "internal.h" #include "wma.h" @@ -209,9 +210,9 @@ static void decode_exp_lsp(WMACodecContext *s, int ch) for (i = 0; i < NB_LSP_COEFS; i++) { if (i == 0 || i >= 8) - val = get_bits(&s->gb, 3); + val = bitstream_read(&s->bc, 3); else - val = get_bits(&s->gb, 4); + val = bitstream_read(&s->bc, 4); lsp_coefs[i] = ff_wma_lsp_codebook[i][val]; } @@ -318,7 +319,7 @@ static int decode_exp_vlc(WMACodecContext *s, int ch) q_end = q + s->block_len; max_scale = 0; if (s->version == 1) { - last_exp = get_bits(&s->gb, 5) + 10; + last_exp = bitstream_read(&s->bc, 5) + 10; v = ptab[last_exp]; iv = iptab[last_exp]; max_scale = v; @@ -333,7 +334,7 @@ static int decode_exp_vlc(WMACodecContext *s, int ch) last_exp = 36; while (q < q_end) { - code = get_vlc2(&s->gb, s->exp_vlc.table, EXPVLCBITS, EXPMAX); + code = bitstream_read_vlc(&s->bc, s->exp_vlc.table, EXPVLCBITS, EXPMAX); if (code < 0) { av_log(s->avctx, AV_LOG_ERROR, "Exponent vlc invalid\n"); return -1; @@ -436,7 +437,7 @@ static int wma_decode_block(WMACodecContext *s) if (s->reset_block_lengths) { s->reset_block_lengths = 0; - v = get_bits(&s->gb, n); + v = bitstream_read(&s->bc, n); if (v >= s->nb_block_sizes) { av_log(s->avctx, AV_LOG_ERROR, "prev_block_len_bits %d out of range\n", @@ -444,7 +445,7 @@ static int wma_decode_block(WMACodecContext *s) return -1; } s->prev_block_len_bits = s->frame_len_bits - v; - v = get_bits(&s->gb, n); + v = bitstream_read(&s->bc, n); if (v >= s->nb_block_sizes) { av_log(s->avctx, AV_LOG_ERROR, "block_len_bits %d out of range\n", @@ -457,7 +458,7 @@ static int wma_decode_block(WMACodecContext *s) s->prev_block_len_bits = s->block_len_bits; s->block_len_bits = s->next_block_len_bits; } - v = get_bits(&s->gb, n); + v = bitstream_read(&s->bc, n); if (v >= s->nb_block_sizes) { av_log(s->avctx, AV_LOG_ERROR, "next_block_len_bits %d out of range\n", @@ -480,10 +481,10 @@ static int wma_decode_block(WMACodecContext *s) } if (s->avctx->channels == 2) - s->ms_stereo = get_bits1(&s->gb); + s->ms_stereo = bitstream_read_bit(&s->bc); v = 0; for (ch = 0; ch < s->avctx->channels; ch++) { - a = get_bits1(&s->gb); + a = bitstream_read_bit(&s->bc); s->channel_coded[ch] = a; v |= a; } @@ -499,7 +500,7 @@ static int wma_decode_block(WMACodecContext *s) * coef escape coding */ total_gain = 1; for (;;) { - a = get_bits(&s->gb, 7); + a = bitstream_read(&s->bc, 7); total_gain += a; if (a != 127) break; @@ -519,7 +520,7 @@ static int wma_decode_block(WMACodecContext *s) int i, n, a; n = s->exponent_high_sizes[bsize]; for (i = 0; i < n; i++) { - a = get_bits1(&s->gb); + a = bitstream_read_bit(&s->bc); s->high_band_coded[ch][i] = a; /* if noise coding, the coefficients are not transmitted */ if (a) @@ -536,10 +537,11 @@ static int wma_decode_block(WMACodecContext *s) for (i = 0; i < n; i++) { if (s->high_band_coded[ch][i]) { if (val == (int) 0x80000000) { - val = get_bits(&s->gb, 7) - 19; + val = bitstream_read(&s->bc, 7) - 19; } else { - code = get_vlc2(&s->gb, s->hgain_vlc.table, - HGAINVLCBITS, HGAINMAX); + code = bitstream_read_vlc(&s->bc, + s->hgain_vlc.table, + HGAINVLCBITS, HGAINMAX); if (code < 0) { av_log(s->avctx, AV_LOG_ERROR, "hgain vlc invalid\n"); @@ -555,7 +557,7 @@ static int wma_decode_block(WMACodecContext *s) } /* exponents can be reused in short blocks. */ - if ((s->block_len_bits == s->frame_len_bits) || get_bits1(&s->gb)) { + if ((s->block_len_bits == s->frame_len_bits) || bitstream_read_bit(&s->bc)) { for (ch = 0; ch < s->avctx->channels; ch++) { if (s->channel_coded[ch]) { if (s->use_exp_vlc) { @@ -579,13 +581,13 @@ static int wma_decode_block(WMACodecContext *s) * there is potentially less energy there */ tindex = (ch == 1 && s->ms_stereo); memset(ptr, 0, s->block_len * sizeof(WMACoef)); - ff_wma_run_level_decode(s->avctx, &s->gb, &s->coef_vlc[tindex], + ff_wma_run_level_decode(s->avctx, &s->bc, &s->coef_vlc[tindex], s->level_table[tindex], s->run_table[tindex], 0, ptr, 0, nb_coefs[ch], s->block_len, s->frame_len_bits, coef_nb_bits); } if (s->version == 1 && s->avctx->channels >= 2) - align_get_bits(&s->gb); + bitstream_align(&s->bc); } /* normalize */ @@ -810,12 +812,12 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, } buf_size = avctx->block_align; - init_get_bits(&s->gb, buf, buf_size * 8); + bitstream_init8(&s->bc, buf, buf_size); if (s->use_bit_reservoir) { /* read super frame header */ - skip_bits(&s->gb, 4); /* super frame index */ - nb_frames = get_bits(&s->gb, 4) - (s->last_superframe_len <= 0); + bitstream_skip(&s->bc, 4); /* super frame index */ + nb_frames = bitstream_read(&s->bc, 4) - (s->last_superframe_len <= 0); } else nb_frames = 1; @@ -829,11 +831,11 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, samples_offset = 0; if (s->use_bit_reservoir) { - bit_offset = get_bits(&s->gb, s->byte_offset_bits + 3); - if (bit_offset > get_bits_left(&s->gb)) { + bit_offset = bitstream_read(&s->bc, s->byte_offset_bits + 3); + if (bit_offset > bitstream_bits_left(&s->bc)) { av_log(avctx, AV_LOG_ERROR, "Invalid last frame bit offset %d > buf size %d (%d)\n", - bit_offset, get_bits_left(&s->gb), buf_size); + bit_offset, bitstream_bits_left(&s->bc), buf_size); goto fail; } @@ -845,19 +847,19 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, q = s->last_superframe + s->last_superframe_len; len = bit_offset; while (len > 7) { - *q++ = (get_bits) (&s->gb, 8); + *q++ = bitstream_read(&s->bc, 8); len -= 8; } if (len > 0) - *q++ = (get_bits) (&s->gb, len) << (8 - len); + *q++ = bitstream_read(&s->bc, len) << (8 - len); memset(q, 0, AV_INPUT_BUFFER_PADDING_SIZE); /* XXX: bit_offset bits into last frame */ - init_get_bits(&s->gb, s->last_superframe, - s->last_superframe_len * 8 + bit_offset); + bitstream_init(&s->bc, s->last_superframe, + s->last_superframe_len * 8 + bit_offset); /* skip unused bits */ if (s->last_bitoffset > 0) - skip_bits(&s->gb, s->last_bitoffset); + bitstream_skip(&s->bc, s->last_bitoffset); /* this frame is stored in the last superframe and in the * current one */ if (wma_decode_frame(s, samples, samples_offset) < 0) @@ -870,10 +872,10 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, pos = bit_offset + 4 + 4 + s->byte_offset_bits + 3; if (pos >= MAX_CODED_SUPERFRAME_SIZE * 8 || pos > buf_size * 8) return AVERROR_INVALIDDATA; - init_get_bits(&s->gb, buf + (pos >> 3), (buf_size - (pos >> 3)) * 8); + bitstream_init8(&s->bc, buf + (pos >> 3), buf_size - (pos >> 3)); len = pos & 7; if (len > 0) - skip_bits(&s->gb, len); + bitstream_skip(&s->bc, len); s->reset_block_lengths = 1; for (i = 0; i < nb_frames; i++) { @@ -883,7 +885,7 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, } /* we copy the end of the frame in the last frame buffer */ - pos = get_bits_count(&s->gb) + + pos = bitstream_tell(&s->bc) + ((bit_offset + 4 + 4 + s->byte_offset_bits + 3) & ~7); s->last_bitoffset = pos & 7; pos >>= 3; diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c index 231a74d24f86e..b8299874d37f6 100644 --- a/libavcodec/wmalosslessdec.c +++ b/libavcodec/wmalosslessdec.c @@ -28,8 +28,8 @@ #include "libavutil/avassert.h" #include "avcodec.h" +#include "bitstream.h" #include "internal.h" -#include "get_bits.h" #include "put_bits.h" #include "wma.h" #include "wma_common.h" @@ -87,7 +87,7 @@ typedef struct WmallDecodeCtx { uint16_t min_samples_per_subframe; /* packet decode state */ - GetBitContext pgb; ///< bitstream reader context for the packet + BitstreamContext pbc; ///< bitstream reader context for the packet int next_packet_start; ///< start offset of the next WMA packet in the demuxer packet uint8_t packet_offset; ///< offset to the frame in the packet uint8_t packet_sequence_number; ///< current packet number @@ -99,7 +99,7 @@ typedef struct WmallDecodeCtx { /* frame decode state */ uint32_t frame_num; ///< current frame number (not used for decoding) - GetBitContext gb; ///< bitstream reader context + BitstreamContext bc; ///< bitstream reader context int buf_bit_size; ///< buffer size in bits int16_t *samples_16[WMALL_MAX_CHANNELS]; ///< current sample buffer pointer (16-bit) int32_t *samples_32[WMALL_MAX_CHANNELS]; ///< current sample buffer pointer (24-bit) @@ -286,7 +286,7 @@ static int decode_subframe_length(WmallDecodeCtx *s, int offset) return s->min_samples_per_subframe; len = av_log2(s->max_num_subframes - 1) + 1; - frame_len_ratio = get_bits(&s->gb, len); + frame_len_ratio = bitstream_read(&s->bc, len); subframe_len = s->min_samples_per_subframe * (frame_len_ratio + 1); /* sanity check the length */ @@ -332,7 +332,7 @@ static int decode_tilehdr(WmallDecodeCtx *s) for (c = 0; c < s->num_channels; c++) s->channel[c].num_subframes = 0; - tile_aligned = get_bits1(&s->gb); + tile_aligned = bitstream_read_bit(&s->bc); if (s->max_num_subframes == 1 || tile_aligned) fixed_channel_layout = 1; @@ -347,7 +347,7 @@ static int decode_tilehdr(WmallDecodeCtx *s) (min_channel_len == s->samples_per_frame - s->min_samples_per_subframe)) { contains_subframe[c] = in_use = 1; } else { - if (get_bits1(&s->gb)) + if (bitstream_read_bit(&s->bc)) contains_subframe[c] = in_use = 1; } } else @@ -407,32 +407,32 @@ static int decode_tilehdr(WmallDecodeCtx *s) static void decode_ac_filter(WmallDecodeCtx *s) { int i; - s->acfilter_order = get_bits(&s->gb, 4) + 1; - s->acfilter_scaling = get_bits(&s->gb, 4); + s->acfilter_order = bitstream_read(&s->bc, 4) + 1; + s->acfilter_scaling = bitstream_read(&s->bc, 4); for (i = 0; i < s->acfilter_order; i++) - s->acfilter_coeffs[i] = get_bitsz(&s->gb, s->acfilter_scaling) + 1; + s->acfilter_coeffs[i] = bitstream_read(&s->bc, s->acfilter_scaling) + 1; } static void decode_mclms(WmallDecodeCtx *s) { - s->mclms_order = (get_bits(&s->gb, 4) + 1) * 2; - s->mclms_scaling = get_bits(&s->gb, 4); - if (get_bits1(&s->gb)) { + s->mclms_order = (bitstream_read(&s->bc, 4) + 1) * 2; + s->mclms_scaling = bitstream_read(&s->bc, 4); + if (bitstream_read_bit(&s->bc)) { int i, send_coef_bits; int cbits = av_log2(s->mclms_scaling + 1); if (1 << cbits < s->mclms_scaling + 1) cbits++; - send_coef_bits = get_bitsz(&s->gb, cbits) + 2; + send_coef_bits = bitstream_read(&s->bc, cbits) + 2; for (i = 0; i < s->mclms_order * s->num_channels * s->num_channels; i++) - s->mclms_coeffs[i] = get_bits(&s->gb, send_coef_bits); + s->mclms_coeffs[i] = bitstream_read(&s->bc, send_coef_bits); for (i = 0; i < s->num_channels; i++) { int c; for (c = 0; c < i; c++) - s->mclms_coeffs_cur[i * s->num_channels + c] = get_bits(&s->gb, send_coef_bits); + s->mclms_coeffs_cur[i * s->num_channels + c] = bitstream_read(&s->bc, send_coef_bits); } } } @@ -440,12 +440,12 @@ static void decode_mclms(WmallDecodeCtx *s) static int decode_cdlms(WmallDecodeCtx *s) { int c, i; - int cdlms_send_coef = get_bits1(&s->gb); + int cdlms_send_coef = bitstream_read_bit(&s->bc); for (c = 0; c < s->num_channels; c++) { - s->cdlms_ttl[c] = get_bits(&s->gb, 3) + 1; + s->cdlms_ttl[c] = bitstream_read(&s->bc, 3) + 1; for (i = 0; i < s->cdlms_ttl[c]; i++) { - s->cdlms[c][i].order = (get_bits(&s->gb, 7) + 1) * 8; + s->cdlms[c][i].order = (bitstream_read(&s->bc, 7) + 1) * 8; if (s->cdlms[c][i].order > MAX_ORDER) { av_log(s->avctx, AV_LOG_ERROR, "Order[%d][%d] %d > max (%d), not supported\n", @@ -456,7 +456,7 @@ static int decode_cdlms(WmallDecodeCtx *s) } for (i = 0; i < s->cdlms_ttl[c]; i++) - s->cdlms[c][i].scaling = get_bits(&s->gb, 4); + s->cdlms[c][i].scaling = bitstream_read(&s->bc, 4); if (cdlms_send_coef) { for (i = 0; i < s->cdlms_ttl[c]; i++) { @@ -464,18 +464,18 @@ static int decode_cdlms(WmallDecodeCtx *s) cbits = av_log2(s->cdlms[c][i].order); if ((1 << cbits) < s->cdlms[c][i].order) cbits++; - s->cdlms[c][i].coefsend = get_bits(&s->gb, cbits) + 1; + s->cdlms[c][i].coefsend = bitstream_read(&s->bc, cbits) + 1; cbits = av_log2(s->cdlms[c][i].scaling + 1); if ((1 << cbits) < s->cdlms[c][i].scaling + 1) cbits++; - s->cdlms[c][i].bitsend = get_bitsz(&s->gb, cbits) + 2; + s->cdlms[c][i].bitsend = bitstream_read(&s->bc, cbits) + 2; shift_l = 32 - s->cdlms[c][i].bitsend; shift_r = 32 - s->cdlms[c][i].scaling - 2; for (j = 0; j < s->cdlms[c][i].coefsend; j++) s->cdlms[c][i].coefs[j] = - (get_bits(&s->gb, s->cdlms[c][i].bitsend) << shift_l) >> shift_r; + (bitstream_read(&s->bc, s->cdlms[c][i].bitsend) << shift_l) >> shift_r; } } } @@ -487,9 +487,9 @@ static int decode_channel_residues(WmallDecodeCtx *s, int ch, int tile_size) { int i = 0; unsigned int ave_mean; - s->transient[ch] = get_bits1(&s->gb); + s->transient[ch] = bitstream_read_bit(&s->bc); if (s->transient[ch]) { - s->transient_pos[ch] = get_bits(&s->gb, av_log2(tile_size)); + s->transient_pos[ch] = bitstream_read(&s->bc, av_log2(tile_size)); if (s->transient_pos[ch]) s->transient[ch] = 0; s->channel[ch].transient_counter = @@ -498,33 +498,33 @@ static int decode_channel_residues(WmallDecodeCtx *s, int ch, int tile_size) s->transient[ch] = 1; if (s->seekable_tile) { - ave_mean = get_bits(&s->gb, s->bits_per_sample); + ave_mean = bitstream_read(&s->bc, s->bits_per_sample); s->ave_sum[ch] = ave_mean << (s->movave_scaling + 1); } if (s->seekable_tile) { if (s->do_inter_ch_decorr) - s->channel_residues[ch][0] = get_sbits(&s->gb, s->bits_per_sample + 1); + s->channel_residues[ch][0] = bitstream_read_signed(&s->bc, s->bits_per_sample + 1); else - s->channel_residues[ch][0] = get_sbits(&s->gb, s->bits_per_sample); + s->channel_residues[ch][0] = bitstream_read_signed(&s->bc, s->bits_per_sample); i++; } for (; i < tile_size; i++) { int quo = 0, rem, rem_bits, residue; - while(get_bits1(&s->gb)) { + while (bitstream_read_bit(&s->bc)) { quo++; - if (get_bits_left(&s->gb) <= 0) + if (bitstream_bits_left(&s->bc) <= 0) return -1; } if (quo >= 32) - quo += get_bits_long(&s->gb, get_bits(&s->gb, 5) + 1); + quo += bitstream_read(&s->bc, bitstream_read(&s->bc, 5) + 1); ave_mean = (s->ave_sum[ch] + (1 << s->movave_scaling)) >> (s->movave_scaling + 1); if (ave_mean <= 1) residue = quo; else { rem_bits = av_ceil_log2(ave_mean); - rem = rem_bits ? get_bits_long(&s->gb, rem_bits) : 0; + rem = rem_bits ? bitstream_read(&s->bc, rem_bits) : 0; residue = (quo << rem_bits) + rem; } @@ -545,13 +545,13 @@ static int decode_channel_residues(WmallDecodeCtx *s, int ch, int tile_size) static void decode_lpc(WmallDecodeCtx *s) { int ch, i, cbits; - s->lpc_order = get_bits(&s->gb, 5) + 1; - s->lpc_scaling = get_bits(&s->gb, 4); - s->lpc_intbits = get_bits(&s->gb, 3) + 1; + s->lpc_order = bitstream_read(&s->bc, 5) + 1; + s->lpc_scaling = bitstream_read(&s->bc, 4); + s->lpc_intbits = bitstream_read(&s->bc, 3) + 1; cbits = s->lpc_scaling + s->lpc_intbits; for (ch = 0; ch < s->num_channels; ch++) for (i = 0; i < s->lpc_order; i++) - s->lpc_coefs[ch][i] = get_sbits(&s->gb, cbits); + s->lpc_coefs[ch][i] = bitstream_read_signed(&s->bc, cbits); } static void clear_codec_buffers(WmallDecodeCtx *s) @@ -846,7 +846,7 @@ static int decode_subframe(WmallDecodeCtx *s) int total_samples = s->samples_per_frame * s->num_channels; int i, j, rawpcm_tile, padding_zeroes, res; - s->subframe_offset = get_bits_count(&s->gb); + s->subframe_offset = bitstream_tell(&s->bc); /* reset channel context and find the next block offset and size == the next block of the channel with the smallest number of @@ -883,18 +883,18 @@ static int decode_subframe(WmallDecodeCtx *s) s->parsed_all_subframes = 1; - s->seekable_tile = get_bits1(&s->gb); + s->seekable_tile = bitstream_read_bit(&s->bc); if (s->seekable_tile) { clear_codec_buffers(s); - s->do_arith_coding = get_bits1(&s->gb); + s->do_arith_coding = bitstream_read_bit(&s->bc); if (s->do_arith_coding) { avpriv_request_sample(s->avctx, "Arithmetic coding"); return AVERROR_PATCHWELCOME; } - s->do_ac_filter = get_bits1(&s->gb); - s->do_inter_ch_decorr = get_bits1(&s->gb); - s->do_mclms = get_bits1(&s->gb); + s->do_ac_filter = bitstream_read_bit(&s->bc); + s->do_inter_ch_decorr = bitstream_read_bit(&s->bc); + s->do_mclms = bitstream_read_bit(&s->bc); if (s->do_ac_filter) decode_ac_filter(s); @@ -904,8 +904,8 @@ static int decode_subframe(WmallDecodeCtx *s) if ((res = decode_cdlms(s)) < 0) return res; - s->movave_scaling = get_bits(&s->gb, 3); - s->quant_stepsize = get_bits(&s->gb, 8) + 1; + s->movave_scaling = bitstream_read(&s->bc, 3); + s->quant_stepsize = bitstream_read(&s->bc, 8) + 1; reset_codec(s); } else if (!s->cdlms[0][0].order) { @@ -915,18 +915,18 @@ static int decode_subframe(WmallDecodeCtx *s) return -1; } - rawpcm_tile = get_bits1(&s->gb); + rawpcm_tile = bitstream_read_bit(&s->bc); for (i = 0; i < s->num_channels; i++) s->is_channel_coded[i] = 1; if (!rawpcm_tile) { for (i = 0; i < s->num_channels; i++) - s->is_channel_coded[i] = get_bits1(&s->gb); + s->is_channel_coded[i] = bitstream_read_bit(&s->bc); if (s->bV3RTM) { // LPC - s->do_lpc = get_bits1(&s->gb); + s->do_lpc = bitstream_read_bit(&s->bc); if (s->do_lpc) { decode_lpc(s); avpriv_request_sample(s->avctx, "Expect wrong output since " @@ -937,8 +937,8 @@ static int decode_subframe(WmallDecodeCtx *s) } - if (get_bits1(&s->gb)) - padding_zeroes = get_bits(&s->gb, 5); + if (bitstream_read_bit(&s->bc)) + padding_zeroes = bitstream_read(&s->bc, 5); else padding_zeroes = 0; @@ -951,10 +951,10 @@ static int decode_subframe(WmallDecodeCtx *s) } ff_dlog(s->avctx, "RAWPCM %d bits per sample. " "total %d bits, remain=%d\n", bits, - bits * s->num_channels * subframe_len, get_bits_count(&s->gb)); + bits * s->num_channels * subframe_len, bitstream_tell(&s->bc)); for (i = 0; i < s->num_channels; i++) for (j = 0; j < subframe_len; j++) - s->channel_coeffs[i][j] = get_sbits(&s->gb, bits); + s->channel_coeffs[i][j] = bitstream_read_signed(&s->bc, bits); } else { for (i = 0; i < s->num_channels; i++) if (s->is_channel_coded[i]) { @@ -1015,7 +1015,7 @@ static int decode_subframe(WmallDecodeCtx *s) */ static int decode_frame(WmallDecodeCtx *s) { - GetBitContext* gb = &s->gb; + BitstreamContext *bc = &s->bc; int more_frames = 0, len = 0, i, ret; s->frame->nb_samples = s->samples_per_frame; @@ -1033,7 +1033,7 @@ static int decode_frame(WmallDecodeCtx *s) /* get frame length */ if (s->len_prefix) - len = get_bits(gb, s->log2_frame_size); + len = bitstream_read(bc, s->log2_frame_size); /* decode tile information */ if (decode_tilehdr(s)) { @@ -1043,22 +1043,22 @@ static int decode_frame(WmallDecodeCtx *s) /* read drc info */ if (s->dynamic_range_compression) - s->drc_gain = get_bits(gb, 8); + s->drc_gain = bitstream_read(bc, 8); /* no idea what these are for, might be the number of samples that need to be skipped at the beginning or end of a stream */ - if (get_bits1(gb)) { + if (bitstream_read_bit(bc)) { int av_unused skip; /* usually true for the first frame */ - if (get_bits1(gb)) { - skip = get_bits(gb, av_log2(s->samples_per_frame * 2)); + if (bitstream_read_bit(bc)) { + skip = bitstream_read(bc, av_log2(s->samples_per_frame * 2)); ff_dlog(s->avctx, "start skip: %i\n", skip); } /* sometimes true for the last frame */ - if (get_bits1(gb)) { - skip = get_bits(gb, av_log2(s->samples_per_frame * 2)); + if (bitstream_read_bit(bc)) { + skip = bitstream_read(bc, av_log2(s->samples_per_frame * 2)); ff_dlog(s->avctx, "end skip: %i\n", skip); } @@ -1085,22 +1085,22 @@ static int decode_frame(WmallDecodeCtx *s) s->skip_frame = 0; if (s->len_prefix) { - if (len != (get_bits_count(gb) - s->frame_offset) + 2) { + if (len != (bitstream_tell(bc) - s->frame_offset) + 2) { /* FIXME: not sure if this is always an error */ av_log(s->avctx, AV_LOG_ERROR, "frame[%"PRIu32"] would have to skip %i bits\n", s->frame_num, - len - (get_bits_count(gb) - s->frame_offset) - 1); + len - (bitstream_tell(bc) - s->frame_offset) - 1); s->packet_loss = 1; return 0; } /* skip the rest of the frame data */ - skip_bits_long(gb, len - (get_bits_count(gb) - s->frame_offset) - 1); + bitstream_skip(bc, len - (bitstream_tell(bc) - s->frame_offset) - 1); } /* decode trailer bit */ - more_frames = get_bits1(gb); + more_frames = bitstream_read_bit(bc); ++s->frame_num; return more_frames; } @@ -1108,22 +1108,22 @@ static int decode_frame(WmallDecodeCtx *s) /** * @brief Calculate remaining input buffer length. * @param s codec context - * @param gb bitstream reader context + * @param bc bitstream reader context * @return remaining size in bits */ -static int remaining_bits(WmallDecodeCtx *s, GetBitContext *gb) +static int remaining_bits(WmallDecodeCtx *s, BitstreamContext *bc) { - return s->buf_bit_size - get_bits_count(gb); + return s->buf_bit_size - bitstream_tell(bc); } /** * @brief Fill the bit reservoir with a (partial) frame. * @param s codec context - * @param gb bitstream reader context + * @param bc bitstream reader context * @param len length of the partial frame * @param append decides whether to reset the buffer or not */ -static void save_bits(WmallDecodeCtx *s, GetBitContext* gb, int len, +static void save_bits(WmallDecodeCtx *s, BitstreamContext *bc, int len, int append) { int buflen; @@ -1134,7 +1134,7 @@ static void save_bits(WmallDecodeCtx *s, GetBitContext* gb, int len, and skipped later so that a fast byte copy is possible */ if (!append) { - s->frame_offset = get_bits_count(gb) & 7; + s->frame_offset = bitstream_tell(bc) & 7; s->num_saved_bits = s->frame_offset; init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE); } @@ -1149,29 +1149,29 @@ static void save_bits(WmallDecodeCtx *s, GetBitContext* gb, int len, s->num_saved_bits += len; if (!append) { - avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), + avpriv_copy_bits(&s->pb, bc->buffer + (bitstream_tell(bc) >> 3), s->num_saved_bits); } else { - int align = 8 - (get_bits_count(gb) & 7); + int align = 8 - (bitstream_tell(bc) & 7); align = FFMIN(align, len); - put_bits(&s->pb, align, get_bits(gb, align)); + put_bits(&s->pb, align, bitstream_read(bc, align)); len -= align; - avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), len); + avpriv_copy_bits(&s->pb, bc->buffer + (bitstream_tell(bc) >> 3), len); } - skip_bits_long(gb, len); + bitstream_skip(bc, len); tmp = s->pb; flush_put_bits(&tmp); - init_get_bits(&s->gb, s->frame_data, s->num_saved_bits); - skip_bits(&s->gb, s->frame_offset); + bitstream_init(&s->bc, s->frame_data, s->num_saved_bits); + bitstream_skip(&s->bc, s->frame_offset); } static int decode_packet(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket* avpkt) { WmallDecodeCtx *s = avctx->priv_data; - GetBitContext* gb = &s->pgb; + BitstreamContext *bc = &s->pbc; const uint8_t* buf = avpkt->data; int buf_size = avpkt->size; int num_bits_prev_frame, packet_sequence_number, spliced_packet; @@ -1190,15 +1190,15 @@ static int decode_packet(AVCodecContext *avctx, void *data, int *got_frame_ptr, s->buf_bit_size = buf_size << 3; /* parse packet header */ - init_get_bits(gb, buf, s->buf_bit_size); - packet_sequence_number = get_bits(gb, 4); - skip_bits(gb, 1); // Skip seekable_frame_in_packet, currently unused - spliced_packet = get_bits1(gb); + bitstream_init(bc, buf, s->buf_bit_size); + packet_sequence_number = bitstream_read(bc, 4); + bitstream_skip(bc, 1); // Skip seekable_frame_in_packet, currently ununused + spliced_packet = bitstream_read_bit(bc); if (spliced_packet) avpriv_request_sample(avctx, "Bitstream splicing"); /* get number of bits that need to be added to the previous frame */ - num_bits_prev_frame = get_bits(gb, s->log2_frame_size); + num_bits_prev_frame = bitstream_read(bc, s->log2_frame_size); /* check for packet loss */ if (!s->packet_loss && @@ -1211,7 +1211,7 @@ static int decode_packet(AVCodecContext *avctx, void *data, int *got_frame_ptr, s->packet_sequence_number = packet_sequence_number; if (num_bits_prev_frame > 0) { - int remaining_packet_bits = s->buf_bit_size - get_bits_count(gb); + int remaining_packet_bits = s->buf_bit_size - bitstream_tell(bc); if (num_bits_prev_frame >= remaining_packet_bits) { num_bits_prev_frame = remaining_packet_bits; s->packet_done = 1; @@ -1219,7 +1219,7 @@ static int decode_packet(AVCodecContext *avctx, void *data, int *got_frame_ptr, /* Append the previous frame data to the remaining data from the * previous packet to create a full frame. */ - save_bits(s, gb, num_bits_prev_frame, 1); + save_bits(s, bc, num_bits_prev_frame, 1); /* decode the cross packet frame if it is valid */ if (num_bits_prev_frame < remaining_packet_bits && !s->packet_loss) @@ -1241,16 +1241,16 @@ static int decode_packet(AVCodecContext *avctx, void *data, int *got_frame_ptr, int frame_size; s->buf_bit_size = (avpkt->size - s->next_packet_start) << 3; - init_get_bits(gb, avpkt->data, s->buf_bit_size); - skip_bits(gb, s->packet_offset); + bitstream_init(bc, avpkt->data, s->buf_bit_size); + bitstream_skip(bc, s->packet_offset); - if (s->len_prefix && remaining_bits(s, gb) > s->log2_frame_size && - (frame_size = show_bits(gb, s->log2_frame_size)) && - frame_size <= remaining_bits(s, gb)) { - save_bits(s, gb, frame_size, 0); + if (s->len_prefix && remaining_bits(s, bc) > s->log2_frame_size && + (frame_size = bitstream_peek(bc, s->log2_frame_size)) && + frame_size <= remaining_bits(s, bc)) { + save_bits(s, bc, frame_size, 0); s->packet_done = !decode_frame(s); } else if (!s->len_prefix - && s->num_saved_bits > get_bits_count(&s->gb)) { + && s->num_saved_bits > bitstream_tell(&s->bc)) { /* when the frames do not have a length prefix, we don't know the * compressed length of the individual frames however, we know what * part of a new packet belongs to the previous frame therefore we @@ -1264,18 +1264,18 @@ static int decode_packet(AVCodecContext *avctx, void *data, int *got_frame_ptr, } if (s->packet_done && !s->packet_loss && - remaining_bits(s, gb) > 0) { + remaining_bits(s, bc) > 0) { /* save the rest of the data so that it can be decoded * with the next packet */ - save_bits(s, gb, remaining_bits(s, gb), 0); + save_bits(s, bc, remaining_bits(s, bc), 0); } *got_frame_ptr = s->frame->nb_samples > 0; av_frame_move_ref(data, s->frame); - s->packet_offset = get_bits_count(gb) & 7; + s->packet_offset = bitstream_tell(bc) & 7; - return (s->packet_loss) ? AVERROR_INVALIDDATA : get_bits_count(gb) >> 3; + return (s->packet_loss) ? AVERROR_INVALIDDATA : bitstream_tell(bc) >> 3; } static void flush(AVCodecContext *avctx) diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index 08b41f446fe80..4eaeed610ee24 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -91,9 +91,10 @@ #include "libavutil/float_dsp.h" #include "libavutil/intfloat.h" #include "libavutil/intreadwrite.h" + #include "avcodec.h" +#include "bitstream.h" #include "internal.h" -#include "get_bits.h" #include "put_bits.h" #include "wmaprodata.h" #include "sinewin.h" @@ -197,7 +198,7 @@ typedef struct WMAProDecodeCtx { int16_t subwoofer_cutoffs[WMAPRO_BLOCK_SIZES]; ///< subwoofer cutoff values /* packet decode state */ - GetBitContext pgb; ///< bitstream reader context for the packet + BitstreamContext pbc; ///< bitstream reader context for the packet int next_packet_start; ///< start offset of the next wma packet in the demuxer packet uint8_t packet_offset; ///< frame offset in the packet uint8_t packet_sequence_number; ///< current packet number @@ -209,7 +210,7 @@ typedef struct WMAProDecodeCtx { /* frame decode state */ uint32_t frame_num; ///< current frame number (not used for decoding) - GetBitContext gb; ///< bitstream reader context + BitstreamContext bc; ///< bitstream reader context int buf_bit_size; ///< buffer size in bits uint8_t drc_gain; ///< gain for the DRC tool int8_t skip_frame; ///< skip output step @@ -495,10 +496,11 @@ static int decode_subframe_length(WMAProDecodeCtx *s, int offset) /** 1 bit indicates if the subframe is of maximum length */ if (s->max_subframe_len_bit) { - if (get_bits1(&s->gb)) - frame_len_shift = 1 + get_bits(&s->gb, s->subframe_len_bits-1); + if (bitstream_read_bit(&s->bc)) + frame_len_shift = 1 + bitstream_read(&s->bc, + s->subframe_len_bits - 1); } else - frame_len_shift = get_bits(&s->gb, s->subframe_len_bits); + frame_len_shift = bitstream_read(&s->bc, s->subframe_len_bits); subframe_len = s->samples_per_frame >> frame_len_shift; @@ -551,7 +553,7 @@ static int decode_tilehdr(WMAProDecodeCtx *s) for (c = 0; c < s->avctx->channels; c++) s->channel[c].num_subframes = 0; - if (s->max_num_subframes == 1 || get_bits1(&s->gb)) + if (s->max_num_subframes == 1 || bitstream_read_bit(&s->bc)) fixed_channel_layout = 1; /** loop until the frame data is split between the subframes */ @@ -565,7 +567,7 @@ static int decode_tilehdr(WMAProDecodeCtx *s) (min_channel_len == s->samples_per_frame - s->min_samples_per_subframe)) contains_subframe[c] = 1; else - contains_subframe[c] = get_bits1(&s->gb); + contains_subframe[c] = bitstream_read_bit(&s->bc); } else contains_subframe[c] = 0; } @@ -633,11 +635,11 @@ static void decode_decorrelation_matrix(WMAProDecodeCtx *s, s->avctx->channels * sizeof(*chgroup->decorrelation_matrix)); for (i = 0; i < chgroup->num_channels * (chgroup->num_channels - 1) >> 1; i++) - rotation_offset[i] = get_bits(&s->gb, 6); + rotation_offset[i] = bitstream_read(&s->bc, 6); for (i = 0; i < chgroup->num_channels; i++) chgroup->decorrelation_matrix[chgroup->num_channels * i + i] = - get_bits1(&s->gb) ? 1.0 : -1.0; + bitstream_read_bit(&s->bc) ? 1.0 : -1.0; for (i = 1; i < chgroup->num_channels; i++) { int x; @@ -686,7 +688,7 @@ static int decode_channel_transform(WMAProDecodeCtx* s) if (s->avctx->channels > 1) { int remaining_channels = s->channels_for_cur_subframe; - if (get_bits1(&s->gb)) { + if (bitstream_read_bit(&s->bc)) { avpriv_request_sample(s->avctx, "Channel transform bit"); return AVERROR_PATCHWELCOME; @@ -704,7 +706,7 @@ static int decode_channel_transform(WMAProDecodeCtx* s) for (i = 0; i < s->channels_for_cur_subframe; i++) { int channel_idx = s->channel_indexes_for_cur_subframe[i]; if (!s->channel[channel_idx].grouped - && get_bits1(&s->gb)) { + && bitstream_read_bit(&s->bc)) { ++chgroup->num_channels; s->channel[channel_idx].grouped = 1; *channel_data++ = s->channel[channel_idx].coeffs; @@ -722,8 +724,8 @@ static int decode_channel_transform(WMAProDecodeCtx* s) /** decode transform type */ if (chgroup->num_channels == 2) { - if (get_bits1(&s->gb)) { - if (get_bits1(&s->gb)) { + if (bitstream_read_bit(&s->bc)) { + if (bitstream_read_bit(&s->bc)) { avpriv_request_sample(s->avctx, "Unknown channel transform type"); return AVERROR_PATCHWELCOME; @@ -744,9 +746,9 @@ static int decode_channel_transform(WMAProDecodeCtx* s) } } } else if (chgroup->num_channels > 2) { - if (get_bits1(&s->gb)) { + if (bitstream_read_bit(&s->bc)) { chgroup->transform = 1; - if (get_bits1(&s->gb)) { + if (bitstream_read_bit(&s->bc)) { decode_decorrelation_matrix(s, chgroup); } else { /** FIXME: more than 6 coupled channels not supported */ @@ -765,11 +767,11 @@ static int decode_channel_transform(WMAProDecodeCtx* s) /** decode transform on / off */ if (chgroup->transform) { - if (!get_bits1(&s->gb)) { + if (!bitstream_read_bit(&s->bc)) { int i; /** transform can be enabled for individual bands */ for (i = 0; i < s->num_bands; i++) { - chgroup->transform_band[i] = get_bits1(&s->gb); + chgroup->transform_band[i] = bitstream_read_bit(&s->bc); } } else { memset(chgroup->transform_band, 1, s->num_bands); @@ -809,7 +811,7 @@ static int decode_coeffs(WMAProDecodeCtx *s, int c) ff_dlog(s->avctx, "decode coefficients for channel %i\n", c); - vlctable = get_bits1(&s->gb); + vlctable = bitstream_read_bit(&s->bc); vlc = &coef_vlc[vlctable]; if (vlctable) { @@ -828,19 +830,19 @@ static int decode_coeffs(WMAProDecodeCtx *s, int c) int i; unsigned int idx; - idx = get_vlc2(&s->gb, vec4_vlc.table, VLCBITS, VEC4MAXDEPTH); + idx = bitstream_read_vlc(&s->bc, vec4_vlc.table, VLCBITS, VEC4MAXDEPTH); if (idx == HUFF_VEC4_SIZE - 1) { for (i = 0; i < 4; i += 2) { - idx = get_vlc2(&s->gb, vec2_vlc.table, VLCBITS, VEC2MAXDEPTH); + idx = bitstream_read_vlc(&s->bc, vec2_vlc.table, VLCBITS, VEC2MAXDEPTH); if (idx == HUFF_VEC2_SIZE - 1) { uint32_t v0, v1; - v0 = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH); + v0 = bitstream_read_vlc(&s->bc, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH); if (v0 == HUFF_VEC1_SIZE - 1) - v0 += ff_wma_get_large_val(&s->gb); - v1 = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH); + v0 += ff_wma_get_large_val(&s->bc); + v1 = bitstream_read_vlc(&s->bc, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH); if (v1 == HUFF_VEC1_SIZE - 1) - v1 += ff_wma_get_large_val(&s->gb); + v1 += ff_wma_get_large_val(&s->bc); vals[i ] = av_float2int(v0); vals[i+1] = av_float2int(v1); } else { @@ -858,7 +860,7 @@ static int decode_coeffs(WMAProDecodeCtx *s, int c) /** decode sign */ for (i = 0; i < 4; i++) { if (vals[i]) { - uint32_t sign = get_bits1(&s->gb) - 1; + uint32_t sign = bitstream_read_bit(&s->bc) - 1; AV_WN32A(&ci->coeffs[cur_coeff], vals[i] ^ sign << 31); num_zeros = 0; } else { @@ -875,7 +877,7 @@ static int decode_coeffs(WMAProDecodeCtx *s, int c) if (cur_coeff < s->subframe_len) { memset(&ci->coeffs[cur_coeff], 0, sizeof(*ci->coeffs) * (s->subframe_len - cur_coeff)); - if (ff_wma_run_level_decode(s->avctx, &s->gb, vlc, + if (ff_wma_run_level_decode(s->avctx, &s->bc, vlc, level, run, 1, ci->coeffs, cur_coeff, s->subframe_len, s->subframe_len, s->esc_len, 0)) @@ -918,15 +920,14 @@ static int decode_scale_factors(WMAProDecodeCtx* s) s->channel[c].saved_scale_factors[s->channel[c].scale_factor_idx][*sf_offsets++]; } - if (!s->channel[c].cur_subframe || get_bits1(&s->gb)) { - + if (!s->channel[c].cur_subframe || bitstream_read_bit(&s->bc)) { if (!s->channel[c].reuse_sf) { int val; /** decode DPCM coded scale factors */ - s->channel[c].scale_factor_step = get_bits(&s->gb, 2) + 1; + s->channel[c].scale_factor_step = bitstream_read(&s->bc, 2) + 1; val = 45 / s->channel[c].scale_factor_step; for (sf = s->channel[c].scale_factors; sf < sf_end; sf++) { - val += get_vlc2(&s->gb, sf_vlc.table, SCALEVLCBITS, SCALEMAXDEPTH) - 60; + val += bitstream_read_vlc(&s->bc, sf_vlc.table, SCALEVLCBITS, SCALEMAXDEPTH) - 60; *sf = val; } } else { @@ -938,10 +939,10 @@ static int decode_scale_factors(WMAProDecodeCtx* s) int val; int sign; - idx = get_vlc2(&s->gb, sf_rl_vlc.table, VLCBITS, SCALERLMAXDEPTH); + idx = bitstream_read_vlc(&s->bc, sf_rl_vlc.table, VLCBITS, SCALERLMAXDEPTH); if (!idx) { - uint32_t code = get_bits(&s->gb, 14); + uint32_t code = bitstream_read(&s->bc, 14); val = code >> 6; sign = (code & 1) - 1; skip = (code & 0x3f) >> 1; @@ -950,7 +951,7 @@ static int decode_scale_factors(WMAProDecodeCtx* s) } else { skip = scale_rl_run[idx]; val = scale_rl_level[idx]; - sign = get_bits1(&s->gb)-1; + sign = bitstream_read_bit(&s->bc)-1; } i += skip; @@ -1077,7 +1078,7 @@ static int decode_subframe(WMAProDecodeCtx *s) int transmit_coeffs = 0; int cur_subwoofer_cutoff; - s->subframe_offset = get_bits_count(&s->gb); + s->subframe_offset = bitstream_tell(&s->bc); /** reset channel context and find the next block offset and size == the next block of the channel with the smallest number of @@ -1141,25 +1142,25 @@ static int decode_subframe(WMAProDecodeCtx *s) s->esc_len = av_log2(s->subframe_len - 1) + 1; /** skip extended header if any */ - if (get_bits1(&s->gb)) { + if (bitstream_read_bit(&s->bc)) { int num_fill_bits; - if (!(num_fill_bits = get_bits(&s->gb, 2))) { - int len = get_bits(&s->gb, 4); - num_fill_bits = get_bitsz(&s->gb, len) + 1; + if (!(num_fill_bits = bitstream_read(&s->bc, 2))) { + int len = bitstream_read(&s->bc, 4); + num_fill_bits = bitstream_read(&s->bc, len) + 1; } if (num_fill_bits >= 0) { - if (get_bits_count(&s->gb) + num_fill_bits > s->num_saved_bits) { + if (bitstream_tell(&s->bc) + num_fill_bits > s->num_saved_bits) { av_log(s->avctx, AV_LOG_ERROR, "invalid number of fill bits\n"); return AVERROR_INVALIDDATA; } - skip_bits_long(&s->gb, num_fill_bits); + bitstream_skip(&s->bc, num_fill_bits); } } /** no idea for what the following bit is used */ - if (get_bits1(&s->gb)) { + if (bitstream_read_bit(&s->bc)) { avpriv_request_sample(s->avctx, "Reserved bit"); return AVERROR_PATCHWELCOME; } @@ -1171,7 +1172,7 @@ static int decode_subframe(WMAProDecodeCtx *s) for (i = 0; i < s->channels_for_cur_subframe; i++) { int c = s->channel_indexes_for_cur_subframe[i]; - if ((s->channel[c].transmit_coefs = get_bits1(&s->gb))) + if ((s->channel[c].transmit_coefs = bitstream_read_bit(&s->bc))) transmit_coeffs = 1; } @@ -1180,11 +1181,11 @@ static int decode_subframe(WMAProDecodeCtx *s) int quant_step = 90 * s->bits_per_sample >> 4; /** decode number of vector coded coefficients */ - if ((s->transmit_num_vec_coeffs = get_bits1(&s->gb))) { + if ((s->transmit_num_vec_coeffs = bitstream_read_bit(&s->bc))) { int num_bits = av_log2((s->subframe_len + 3)/4) + 1; for (i = 0; i < s->channels_for_cur_subframe; i++) { int c = s->channel_indexes_for_cur_subframe[i]; - int num_vec_coeffs = get_bits(&s->gb, num_bits) << 2; + int num_vec_coeffs = bitstream_read(&s->bc, num_bits) << 2; if (num_vec_coeffs + offset > FF_ARRAY_ELEMS(s->channel[c].out)) { av_log(s->avctx, AV_LOG_ERROR, "num_vec_coeffs %d is too large\n", num_vec_coeffs); return AVERROR_INVALIDDATA; @@ -1198,13 +1199,13 @@ static int decode_subframe(WMAProDecodeCtx *s) } } /** decode quantization step */ - step = get_sbits(&s->gb, 6); + step = bitstream_read_signed(&s->bc, 6); quant_step += step; if (step == -32 || step == 31) { const int sign = (step == 31) - 1; int quant = 0; - while (get_bits_count(&s->gb) + 5 < s->num_saved_bits && - (step = get_bits(&s->gb, 5)) == 31) { + while (bitstream_tell(&s->bc) + 5 < s->num_saved_bits && + (step = bitstream_read(&s->bc, 5)) == 31) { quant += 31; } quant_step += ((quant + step) ^ sign) - sign; @@ -1218,13 +1219,13 @@ static int decode_subframe(WMAProDecodeCtx *s) if (s->channels_for_cur_subframe == 1) { s->channel[s->channel_indexes_for_cur_subframe[0]].quant_step = quant_step; } else { - int modifier_len = get_bits(&s->gb, 3); + int modifier_len = bitstream_read(&s->bc, 3); for (i = 0; i < s->channels_for_cur_subframe; i++) { int c = s->channel_indexes_for_cur_subframe[i]; s->channel[c].quant_step = quant_step; - if (get_bits1(&s->gb)) { + if (bitstream_read_bit(&s->bc)) { if (modifier_len) { - s->channel[c].quant_step += get_bits(&s->gb, modifier_len) + 1; + s->channel[c].quant_step += bitstream_read(&s->bc, modifier_len) + 1; } else ++s->channel[c].quant_step; } @@ -1237,13 +1238,13 @@ static int decode_subframe(WMAProDecodeCtx *s) } ff_dlog(s->avctx, "BITSTREAM: subframe header length was %i\n", - get_bits_count(&s->gb) - s->subframe_offset); + bitstream_tell(&s->bc) - s->subframe_offset); /** parse coefficients */ for (i = 0; i < s->channels_for_cur_subframe; i++) { int c = s->channel_indexes_for_cur_subframe[i]; if (s->channel[c].transmit_coefs && - get_bits_count(&s->gb) < s->num_saved_bits) { + bitstream_tell(&s->bc) < s->num_saved_bits) { decode_coeffs(s, c); } else memset(s->channel[c].coeffs, 0, @@ -1251,7 +1252,7 @@ static int decode_subframe(WMAProDecodeCtx *s) } ff_dlog(s->avctx, "BITSTREAM: subframe length was %i\n", - get_bits_count(&s->gb) - s->subframe_offset); + bitstream_tell(&s->bc) - s->subframe_offset); if (transmit_coeffs) { FFTContext *mdct = &s->mdct_ctx[av_log2(subframe_len) - WMAPRO_BLOCK_MIN_BITS]; @@ -1309,14 +1310,14 @@ static int decode_subframe(WMAProDecodeCtx *s) static int decode_frame(WMAProDecodeCtx *s, AVFrame *frame, int *got_frame_ptr) { AVCodecContext *avctx = s->avctx; - GetBitContext* gb = &s->gb; + BitstreamContext *bc = &s->bc; int more_frames = 0; int len = 0; int i, ret; /** get frame length */ if (s->len_prefix) - len = get_bits(gb, s->log2_frame_size); + len = bitstream_read(bc, s->log2_frame_size); ff_dlog(s->avctx, "decoding frame with length %x\n", len); @@ -1327,40 +1328,40 @@ static int decode_frame(WMAProDecodeCtx *s, AVFrame *frame, int *got_frame_ptr) } /** read postproc transform */ - if (s->avctx->channels > 1 && get_bits1(gb)) { - if (get_bits1(gb)) { + if (s->avctx->channels > 1 && bitstream_read_bit(bc)) { + if (bitstream_read_bit(bc)) { for (i = 0; i < avctx->channels * avctx->channels; i++) - skip_bits(gb, 4); + bitstream_skip(bc, 4); } } /** read drc info */ if (s->dynamic_range_compression) { - s->drc_gain = get_bits(gb, 8); + s->drc_gain = bitstream_read(bc, 8); ff_dlog(s->avctx, "drc_gain %i\n", s->drc_gain); } /** no idea what these are for, might be the number of samples that need to be skipped at the beginning or end of a stream */ - if (get_bits1(gb)) { + if (bitstream_read_bit(bc)) { int av_unused skip; /** usually true for the first frame */ - if (get_bits1(gb)) { - skip = get_bits(gb, av_log2(s->samples_per_frame * 2)); + if (bitstream_read_bit(bc)) { + skip = bitstream_read(bc, av_log2(s->samples_per_frame * 2)); ff_dlog(s->avctx, "start skip: %i\n", skip); } /** sometimes true for the last frame */ - if (get_bits1(gb)) { - skip = get_bits(gb, av_log2(s->samples_per_frame * 2)); + if (bitstream_read_bit(bc)) { + skip = bitstream_read(bc, av_log2(s->samples_per_frame * 2)); ff_dlog(s->avctx, "end skip: %i\n", skip); } } ff_dlog(s->avctx, "BITSTREAM: frame header length was %i\n", - get_bits_count(gb) - s->frame_offset); + bitstream_tell(bc) - s->frame_offset); /** reset subframe states */ s->parsed_all_subframes = 0; @@ -1407,25 +1408,25 @@ static int decode_frame(WMAProDecodeCtx *s, AVFrame *frame, int *got_frame_ptr) } if (s->len_prefix) { - if (len != (get_bits_count(gb) - s->frame_offset) + 2) { + if (len != (bitstream_tell(bc) - s->frame_offset) + 2) { /** FIXME: not sure if this is always an error */ av_log(s->avctx, AV_LOG_ERROR, "frame[%"PRIu32"] would have to skip %i bits\n", s->frame_num, - len - (get_bits_count(gb) - s->frame_offset) - 1); + len - (bitstream_tell(bc) - s->frame_offset) - 1); s->packet_loss = 1; return 0; } /** skip the rest of the frame data */ - skip_bits_long(gb, len - (get_bits_count(gb) - s->frame_offset) - 1); + bitstream_skip(bc, len - (bitstream_tell(bc) - s->frame_offset) - 1); } else { - while (get_bits_count(gb) < s->num_saved_bits && get_bits1(gb) == 0) { + while (bitstream_tell(bc) < s->num_saved_bits && bitstream_read_bit(bc) == 0) { } } /** decode trailer bit */ - more_frames = get_bits1(gb); + more_frames = bitstream_read_bit(bc); ++s->frame_num; return more_frames; @@ -1434,22 +1435,22 @@ static int decode_frame(WMAProDecodeCtx *s, AVFrame *frame, int *got_frame_ptr) /** *@brief Calculate remaining input buffer length. *@param s codec context - *@param gb bitstream reader context + *@param bc bitstream reader context *@return remaining size in bits */ -static int remaining_bits(WMAProDecodeCtx *s, GetBitContext *gb) +static int remaining_bits(WMAProDecodeCtx *s, BitstreamContext *bc) { - return s->buf_bit_size - get_bits_count(gb); + return s->buf_bit_size - bitstream_tell(bc); } /** *@brief Fill the bit reservoir with a (partial) frame. *@param s codec context - *@param gb bitstream reader context + *@param bc bitstream reader context *@param len length of the partial frame *@param append decides whether to reset the buffer or not */ -static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len, +static void save_bits(WMAProDecodeCtx *s, BitstreamContext *bc, int len, int append) { int buflen; @@ -1459,7 +1460,7 @@ static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len, and skipped later so that a fast byte copy is possible */ if (!append) { - s->frame_offset = get_bits_count(gb) & 7; + s->frame_offset = bitstream_tell(bc) & 7; s->num_saved_bits = s->frame_offset; init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE); } @@ -1482,24 +1483,24 @@ static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len, s->num_saved_bits += len; if (!append) { - avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), - s->num_saved_bits); + avpriv_copy_bits(&s->pb, bc->buffer + (bitstream_tell(bc) >> 3), + s->num_saved_bits); } else { - int align = 8 - (get_bits_count(gb) & 7); + int align = 8 - (bitstream_tell(bc) & 7); align = FFMIN(align, len); - put_bits(&s->pb, align, get_bits(gb, align)); + put_bits(&s->pb, align, bitstream_read(bc, align)); len -= align; - avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), len); + avpriv_copy_bits(&s->pb, bc->buffer + (bitstream_tell(bc) >> 3), len); } - skip_bits_long(gb, len); + bitstream_skip(bc, len); { PutBitContext tmp = s->pb; flush_put_bits(&tmp); } - init_get_bits(&s->gb, s->frame_data, s->num_saved_bits); - skip_bits(&s->gb, s->frame_offset); + bitstream_init(&s->bc, s->frame_data, s->num_saved_bits); + bitstream_skip(&s->bc, s->frame_offset); } /** @@ -1513,7 +1514,7 @@ static int decode_packet(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket* avpkt) { WMAProDecodeCtx *s = avctx->priv_data; - GetBitContext* gb = &s->pgb; + BitstreamContext *bc = &s->pbc; const uint8_t* buf = avpkt->data; int buf_size = avpkt->size; int num_bits_prev_frame; @@ -1536,12 +1537,12 @@ static int decode_packet(AVCodecContext *avctx, void *data, s->buf_bit_size = buf_size << 3; /** parse packet header */ - init_get_bits(gb, buf, s->buf_bit_size); - packet_sequence_number = get_bits(gb, 4); - skip_bits(gb, 2); + bitstream_init(bc, buf, s->buf_bit_size); + packet_sequence_number = bitstream_read(bc, 4); + bitstream_skip(bc, 2); /** get number of bits that need to be added to the previous frame */ - num_bits_prev_frame = get_bits(gb, s->log2_frame_size); + num_bits_prev_frame = bitstream_read(bc, s->log2_frame_size); ff_dlog(avctx, "packet[%d]: nbpf %x\n", avctx->frame_number, num_bits_prev_frame); @@ -1556,7 +1557,7 @@ static int decode_packet(AVCodecContext *avctx, void *data, s->packet_sequence_number = packet_sequence_number; if (num_bits_prev_frame > 0) { - int remaining_packet_bits = s->buf_bit_size - get_bits_count(gb); + int remaining_packet_bits = s->buf_bit_size - bitstream_tell(bc); if (num_bits_prev_frame >= remaining_packet_bits) { num_bits_prev_frame = remaining_packet_bits; s->packet_done = 1; @@ -1564,7 +1565,7 @@ static int decode_packet(AVCodecContext *avctx, void *data, /** append the previous frame data to the remaining data from the previous packet to create a full frame */ - save_bits(s, gb, num_bits_prev_frame, 1); + save_bits(s, bc, num_bits_prev_frame, 1); ff_dlog(avctx, "accumulated %x bits of frame data\n", s->num_saved_bits - s->frame_offset); @@ -1587,15 +1588,15 @@ static int decode_packet(AVCodecContext *avctx, void *data, } else { int frame_size; s->buf_bit_size = (avpkt->size - s->next_packet_start) << 3; - init_get_bits(gb, avpkt->data, s->buf_bit_size); - skip_bits(gb, s->packet_offset); - if (s->len_prefix && remaining_bits(s, gb) > s->log2_frame_size && - (frame_size = show_bits(gb, s->log2_frame_size)) && - frame_size <= remaining_bits(s, gb)) { - save_bits(s, gb, frame_size, 0); + bitstream_init(bc, avpkt->data, s->buf_bit_size); + bitstream_skip(bc, s->packet_offset); + if (s->len_prefix && remaining_bits(s, bc) > s->log2_frame_size && + (frame_size = bitstream_peek(bc, s->log2_frame_size)) && + frame_size <= remaining_bits(s, bc)) { + save_bits(s, bc, frame_size, 0); s->packet_done = !decode_frame(s, data, got_frame_ptr); } else if (!s->len_prefix - && s->num_saved_bits > get_bits_count(&s->gb)) { + && s->num_saved_bits > bitstream_tell(&s->bc)) { /** when the frames do not have a length prefix, we don't know the compressed length of the individual frames however, we know what part of a new packet belongs to the @@ -1609,17 +1610,17 @@ static int decode_packet(AVCodecContext *avctx, void *data, } if (s->packet_done && !s->packet_loss && - remaining_bits(s, gb) > 0) { + remaining_bits(s, bc) > 0) { /** save the rest of the data so that it can be decoded with the next packet */ - save_bits(s, gb, remaining_bits(s, gb), 0); + save_bits(s, bc, remaining_bits(s, bc), 0); } - s->packet_offset = get_bits_count(gb) & 7; + s->packet_offset = bitstream_tell(bc) & 7; if (s->packet_loss) return AVERROR_INVALIDDATA; - return get_bits_count(gb) >> 3; + return bitstream_tell(bc) >> 3; } /** diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c index 19c06f44726f6..cf9884108c115 100644 --- a/libavcodec/wmavoice.c +++ b/libavcodec/wmavoice.c @@ -25,16 +25,15 @@ * @author Ronald S. Bultje */ -#define UNCHECKED_BITSTREAM_READER 1 - #include #include "libavutil/channel_layout.h" #include "libavutil/float_dsp.h" #include "libavutil/mem.h" + #include "avcodec.h" +#include "bitstream.h" #include "internal.h" -#include "get_bits.h" #include "put_bits.h" #include "wmavoice_data.h" #include "celp_filters.h" @@ -136,7 +135,7 @@ typedef struct WMAVoiceContext { * @name Global values specified in the stream header / extradata or used all over. * @{ */ - GetBitContext gb; ///< packet bitreader. During decoder init, + BitstreamContext bc; ///< packet bitreader. During decoder init, ///< it contains the extradata from the ///< demuxer. During decoding, it contains ///< packet data. @@ -296,20 +295,20 @@ typedef struct WMAVoiceContext { /** * Set up the variable bit mode (VBM) tree from container extradata. - * @param gb bit I/O context. - * The bit context (s->gb) should be loaded with byte 23-46 of the + * @param bc bit I/O context. + * The bit context (s->bc) should be loaded with byte 23-46 of the * container extradata (i.e. the ones containing the VBM tree). * @param vbm_tree pointer to array to which the decoded VBM tree will be * written. * @return 0 on success, <0 on error. */ -static av_cold int decode_vbmtree(GetBitContext *gb, int8_t vbm_tree[25]) +static av_cold int decode_vbmtree(BitstreamContext *bc, int8_t vbm_tree[25]) { int cntr[8] = { 0 }, n, res; memset(vbm_tree, 0xff, sizeof(vbm_tree[0]) * 25); for (n = 0; n < 17; n++) { - res = get_bits(gb, 3); + res = bitstream_read(bc, 3); if (cntr[res] > 3) // should be >= 3 + (res == 7)) return -1; vbm_tree[res * 3 + cntr[res]++] = n; @@ -401,8 +400,8 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx) for (n = 0; n < s->lsps; n++) s->prev_lsps[n] = M_PI * (n + 1.0) / (s->lsps + 1.0); - init_get_bits(&s->gb, ctx->extradata + 22, (ctx->extradata_size - 22) << 3); - if (decode_vbmtree(&s->gb, s->vbm_tree) < 0) { + bitstream_init8(&s->bc, ctx->extradata + 22, ctx->extradata_size - 22); + if (decode_vbmtree(&s->bc, s->vbm_tree) < 0) { av_log(ctx, AV_LOG_ERROR, "Invalid VBM tree; broken extradata?\n"); return AVERROR_INVALIDDATA; } @@ -857,7 +856,7 @@ static void dequant_lsps(double *lsps, int num, /** * Parse 10 independently-coded LSPs. */ -static void dequant_lsp10i(GetBitContext *gb, double *lsps) +static void dequant_lsp10i(BitstreamContext *bc, double *lsps) { static const uint16_t vec_sizes[4] = { 256, 64, 32, 32 }; static const double mul_lsf[4] = { @@ -870,10 +869,10 @@ static void dequant_lsp10i(GetBitContext *gb, double *lsps) }; uint16_t v[4]; - v[0] = get_bits(gb, 8); - v[1] = get_bits(gb, 6); - v[2] = get_bits(gb, 5); - v[3] = get_bits(gb, 5); + v[0] = bitstream_read(bc, 8); + v[1] = bitstream_read(bc, 6); + v[2] = bitstream_read(bc, 5); + v[3] = bitstream_read(bc, 5); dequant_lsps(lsps, 10, v, vec_sizes, 4, wmavoice_dq_lsp10i, mul_lsf, base_lsf); @@ -883,7 +882,7 @@ static void dequant_lsp10i(GetBitContext *gb, double *lsps) * Parse 10 independently-coded LSPs, and then derive the tables to * generate LSPs for the other frames from them (residual coding). */ -static void dequant_lsp10r(GetBitContext *gb, +static void dequant_lsp10r(BitstreamContext *bc, double *i_lsps, const double *old, double *a1, double *a2, int q_mode) { @@ -899,12 +898,12 @@ static void dequant_lsp10r(GetBitContext *gb, uint16_t interpol, v[3]; int n; - dequant_lsp10i(gb, i_lsps); + dequant_lsp10i(bc, i_lsps); - interpol = get_bits(gb, 5); - v[0] = get_bits(gb, 7); - v[1] = get_bits(gb, 6); - v[2] = get_bits(gb, 6); + interpol = bitstream_read(bc, 5); + v[0] = bitstream_read(bc, 7); + v[1] = bitstream_read(bc, 6); + v[2] = bitstream_read(bc, 6); for (n = 0; n < 10; n++) { double delta = old[n] - i_lsps[n]; @@ -919,7 +918,7 @@ static void dequant_lsp10r(GetBitContext *gb, /** * Parse 16 independently-coded LSPs. */ -static void dequant_lsp16i(GetBitContext *gb, double *lsps) +static void dequant_lsp16i(BitstreamContext *bc, double *lsps) { static const uint16_t vec_sizes[5] = { 256, 64, 128, 64, 128 }; static const double mul_lsf[5] = { @@ -934,11 +933,11 @@ static void dequant_lsp16i(GetBitContext *gb, double *lsps) }; uint16_t v[5]; - v[0] = get_bits(gb, 8); - v[1] = get_bits(gb, 6); - v[2] = get_bits(gb, 7); - v[3] = get_bits(gb, 6); - v[4] = get_bits(gb, 7); + v[0] = bitstream_read(bc, 8); + v[1] = bitstream_read(bc, 6); + v[2] = bitstream_read(bc, 7); + v[3] = bitstream_read(bc, 6); + v[4] = bitstream_read(bc, 7); dequant_lsps( lsps, 5, v, vec_sizes, 2, wmavoice_dq_lsp16i1, mul_lsf, base_lsf); @@ -952,7 +951,7 @@ static void dequant_lsp16i(GetBitContext *gb, double *lsps) * Parse 16 independently-coded LSPs, and then derive the tables to * generate LSPs for the other frames from them (residual coding). */ -static void dequant_lsp16r(GetBitContext *gb, +static void dequant_lsp16r(BitstreamContext *bc, double *i_lsps, const double *old, double *a1, double *a2, int q_mode) { @@ -968,12 +967,12 @@ static void dequant_lsp16r(GetBitContext *gb, uint16_t interpol, v[3]; int n; - dequant_lsp16i(gb, i_lsps); + dequant_lsp16i(bc, i_lsps); - interpol = get_bits(gb, 5); - v[0] = get_bits(gb, 7); - v[1] = get_bits(gb, 7); - v[2] = get_bits(gb, 7); + interpol = bitstream_read(bc, 5); + v[0] = bitstream_read(bc, 7); + v[1] = bitstream_read(bc, 7); + v[2] = bitstream_read(bc, 7); for (n = 0; n < 16; n++) { double delta = old[n] - i_lsps[n]; @@ -999,10 +998,10 @@ static void dequant_lsp16r(GetBitContext *gb, * Parse the offset of the first pitch-adaptive window pulses, and * the distribution of pulses between the two blocks in this frame. * @param s WMA Voice decoding context private data - * @param gb bit I/O context + * @param bc bit I/O context * @param pitch pitch for each block in this frame */ -static void aw_parse_coords(WMAVoiceContext *s, GetBitContext *gb, +static void aw_parse_coords(WMAVoiceContext *s, BitstreamContext *bc, const int *pitch) { static const int16_t start_offset[94] = { @@ -1019,9 +1018,9 @@ static void aw_parse_coords(WMAVoiceContext *s, GetBitContext *gb, /* position of pulse */ s->aw_idx_is_ext = 0; - if ((bits = get_bits(gb, 6)) >= 54) { + if ((bits = bitstream_read(bc, 6)) >= 54) { s->aw_idx_is_ext = 1; - bits += (bits - 54) * 3 + get_bits(gb, 2); + bits += (bits - 54) * 3 + bitstream_read(bc, 2); } /* for a repeated pulse at pulse_off with a pitch_lag of pitch[], count @@ -1049,12 +1048,12 @@ static void aw_parse_coords(WMAVoiceContext *s, GetBitContext *gb, /** * Apply second set of pitch-adaptive window pulses. * @param s WMA Voice decoding context private data - * @param gb bit I/O context + * @param bc bit I/O context * @param block_idx block index in frame [0, 1] * @param fcb structure containing fixed codebook vector info * @return -1 on error, 0 otherwise */ -static int aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb, +static int aw_pulse_set2(WMAVoiceContext *s, BitstreamContext *bc, int block_idx, AMRFixed *fcb) { uint16_t use_mask_mem[9]; // only 5 are used, rest is padding @@ -1108,7 +1107,7 @@ static int aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb, } /* find the 'aidx'th offset that is not excluded */ - aidx = get_bits(gb, s->aw_n_pulses[0] > 0 ? 5 - 2 * block_idx : 4); + aidx = bitstream_read(bc, s->aw_n_pulses[0] > 0 ? 5 - 2 * block_idx : 4); for (n = 0; n <= aidx; pulse_start++) { for (idx = pulse_start; idx < 0; idx += fcb->pitch_lag) ; if (idx >= MAX_FRAMESIZE / 2) { // find from zero @@ -1128,7 +1127,7 @@ static int aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb, } fcb->x[fcb->n] = start_off; - fcb->y[fcb->n] = get_bits1(gb) ? -1.0 : 1.0; + fcb->y[fcb->n] = bitstream_read_bit(bc) ? -1.0 : 1.0; fcb->n++; /* set offset for next block, relative to start of that block */ @@ -1140,14 +1139,14 @@ static int aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb, /** * Apply first set of pitch-adaptive window pulses. * @param s WMA Voice decoding context private data - * @param gb bit I/O context + * @param bc bit I/O context * @param block_idx block index in frame [0, 1] * @param fcb storage location for fixed codebook pulse info */ -static void aw_pulse_set1(WMAVoiceContext *s, GetBitContext *gb, +static void aw_pulse_set1(WMAVoiceContext *s, BitstreamContext *bc, int block_idx, AMRFixed *fcb) { - int val = get_bits(gb, 12 - 2 * (s->aw_idx_is_ext && !block_idx)); + int val = bitstream_read(bc, 12 - 2 * (s->aw_idx_is_ext && !block_idx)); float v; if (s->aw_n_pulses[block_idx] > 0) { @@ -1241,7 +1240,7 @@ static int pRNG(int frame_cntr, int block_num, int block_size) * Parse hardcoded signal for a single block. * @note see #synth_block(). */ -static void synth_block_hardcoded(WMAVoiceContext *s, GetBitContext *gb, +static void synth_block_hardcoded(WMAVoiceContext *s, BitstreamContext *bc, int block_idx, int size, const struct frame_type_desc *frame_desc, float *excitation) @@ -1256,8 +1255,8 @@ static void synth_block_hardcoded(WMAVoiceContext *s, GetBitContext *gb, r_idx = pRNG(s->frame_cntr, block_idx, size); gain = s->silence_gain; } else /* FCB_TYPE_HARDCODED */ { - r_idx = get_bits(gb, 8); - gain = wmavoice_gain_universal[get_bits(gb, 6)]; + r_idx = bitstream_read(bc, 8); + gain = wmavoice_gain_universal[bitstream_read(bc, 6)]; } /* Clear gain prediction parameters */ @@ -1272,7 +1271,7 @@ static void synth_block_hardcoded(WMAVoiceContext *s, GetBitContext *gb, * Parse FCB/ACB signal for a single block. * @note see #synth_block(). */ -static void synth_block_fcb_acb(WMAVoiceContext *s, GetBitContext *gb, +static void synth_block_fcb_acb(WMAVoiceContext *s, BitstreamContext *bc, int block_idx, int size, int block_pitch_sh2, const struct frame_type_desc *frame_desc, @@ -1296,8 +1295,8 @@ static void synth_block_fcb_acb(WMAVoiceContext *s, GetBitContext *gb, /* For the other frame types, this is where we apply the innovation * (fixed) codebook pulses of the speech signal. */ if (frame_desc->fcb_type == FCB_TYPE_AW_PULSES) { - aw_pulse_set1(s, gb, block_idx, &fcb); - if (aw_pulse_set2(s, gb, block_idx, &fcb)) { + aw_pulse_set1(s, bc, block_idx, &fcb); + if (aw_pulse_set2(s, bc, block_idx, &fcb)) { /* Conceal the block with silence and return. * Skip the correct amount of bits to read the next * block from the correct offset. */ @@ -1306,7 +1305,7 @@ static void synth_block_fcb_acb(WMAVoiceContext *s, GetBitContext *gb, for (n = 0; n < size; n++) excitation[n] = wmavoice_std_codebook[r_idx + n] * s->silence_gain; - skip_bits(gb, 7 + 1); + bitstream_skip(bc, 7 + 1); return; } } else /* FCB_TYPE_EXC_PULSES */ { @@ -1319,12 +1318,12 @@ static void synth_block_fcb_acb(WMAVoiceContext *s, GetBitContext *gb, float sign; int pos1, pos2; - sign = get_bits1(gb) ? 1.0 : -1.0; - pos1 = get_bits(gb, offset_nbits); + sign = bitstream_read_bit(bc) ? 1.0 : -1.0; + pos1 = bitstream_read(bc, offset_nbits); fcb.x[fcb.n] = n + 5 * pos1; fcb.y[fcb.n++] = sign; if (n < frame_desc->dbl_pulses) { - pos2 = get_bits(gb, offset_nbits); + pos2 = bitstream_read(bc, offset_nbits); fcb.x[fcb.n] = n + 5 * pos2; fcb.y[fcb.n++] = (pos1 < pos2) ? -sign : sign; } @@ -1334,7 +1333,7 @@ static void synth_block_fcb_acb(WMAVoiceContext *s, GetBitContext *gb, /* Calculate gain for adaptive & fixed codebook signal. * see ff_amr_set_fixed_gain(). */ - idx = get_bits(gb, 7); + idx = bitstream_read(bc, 7); fcb_gain = expf(avpriv_scalarproduct_float_c(s->gain_pred_err, gain_coeff, 6) - 5.2409161640 + wmavoice_gain_codebook_fcb[idx]); @@ -1396,7 +1395,7 @@ static void synth_block_fcb_acb(WMAVoiceContext *s, GetBitContext *gb, * @note we assume enough bits are available, caller should check. * * @param s WMA Voice decoding context private data - * @param gb bit I/O context + * @param bc bit I/O context * @param block_idx index of the to-be-read block * @param size amount of samples to be read in this block * @param block_pitch_sh2 pitch for this block << 2 @@ -1407,7 +1406,7 @@ static void synth_block_fcb_acb(WMAVoiceContext *s, GetBitContext *gb, * @param synth target memory for the speech synthesis filter output * @return 0 on success, <0 on error. */ -static void synth_block(WMAVoiceContext *s, GetBitContext *gb, +static void synth_block(WMAVoiceContext *s, BitstreamContext *bc, int block_idx, int size, int block_pitch_sh2, const double *lsps, const double *prev_lsps, @@ -1420,9 +1419,9 @@ static void synth_block(WMAVoiceContext *s, GetBitContext *gb, int n; if (frame_desc->acb_type == ACB_TYPE_NONE) - synth_block_hardcoded(s, gb, block_idx, size, frame_desc, excitation); + synth_block_hardcoded(s, bc, block_idx, size, frame_desc, excitation); else - synth_block_fcb_acb(s, gb, block_idx, size, block_pitch_sh2, + synth_block_fcb_acb(s, bc, block_idx, size, block_pitch_sh2, frame_desc, excitation); /* convert interpolated LSPs to LPCs */ @@ -1440,7 +1439,7 @@ static void synth_block(WMAVoiceContext *s, GetBitContext *gb, * @note we assume enough bits are available, caller should check. * * @param ctx WMA Voice decoder context - * @param gb bit I/O context (s->gb or one for cross-packet superframes) + * @param bc bit I/O context (s->bc or one for cross-packet superframes) * @param frame_idx Frame number within superframe [0-2] * @param samples pointer to output sample buffer, has space for at least 160 * samples @@ -1450,8 +1449,8 @@ static void synth_block(WMAVoiceContext *s, GetBitContext *gb, * @param synth target buffer for synthesized speech data * @return 0 on success, <0 on error. */ -static int synth_frame(AVCodecContext *ctx, GetBitContext *gb, int frame_idx, - float *samples, +static int synth_frame(AVCodecContext *ctx, BitstreamContext *bc, + int frame_idx, float *samples, const double *lsps, const double *prev_lsps, float *excitation, float *synth) { @@ -1460,7 +1459,7 @@ static int synth_frame(AVCodecContext *ctx, GetBitContext *gb, int frame_idx, int pitch[MAX_BLOCKS], last_block_pitch; /* Parse frame type ("frame header"), see frame_descs */ - int bd_idx = s->vbm_tree[get_vlc2(gb, frame_type_vlc.table, 6, 3)], block_nsamples; + int bd_idx = s->vbm_tree[bitstream_read_vlc(bc, frame_type_vlc.table, 6, 3)], block_nsamples; if (bd_idx < 0) { av_log(ctx, AV_LOG_ERROR, @@ -1478,7 +1477,7 @@ static int synth_frame(AVCodecContext *ctx, GetBitContext *gb, int frame_idx, * incrementing/decrementing prev_frame_pitch to cur_pitch_val. */ n_blocks_x2 = frame_descs[bd_idx].n_blocks << 1; log_n_blocks_x2 = frame_descs[bd_idx].log_n_blocks + 1; - cur_pitch_val = s->min_pitch_val + get_bits(gb, s->pitch_nbits); + cur_pitch_val = s->min_pitch_val + bitstream_read(bc, s->pitch_nbits); cur_pitch_val = FFMIN(cur_pitch_val, s->max_pitch_val - 1); if (s->last_acb_type == ACB_TYPE_NONE || 20 * abs(cur_pitch_val - s->last_pitch_val) > @@ -1502,10 +1501,10 @@ static int synth_frame(AVCodecContext *ctx, GetBitContext *gb, int frame_idx, /* Global gain (if silence) and pitch-adaptive window coordinates */ switch (frame_descs[bd_idx].fcb_type) { case FCB_TYPE_SILENCE: - s->silence_gain = wmavoice_gain_silence[get_bits(gb, 8)]; + s->silence_gain = wmavoice_gain_silence[bitstream_read(bc, 8)]; break; case FCB_TYPE_AW_PULSES: - aw_parse_coords(s, gb, pitch); + aw_parse_coords(s, bc, pitch); break; } @@ -1526,10 +1525,10 @@ static int synth_frame(AVCodecContext *ctx, GetBitContext *gb, int frame_idx, t3 = s->block_conv_table[3] - s->block_conv_table[2] + 1; if (n == 0) { - block_pitch = get_bits(gb, s->block_pitch_nbits); + block_pitch = bitstream_read(bc, s->block_pitch_nbits); } else block_pitch = last_block_pitch - s->block_delta_pitch_hrange + - get_bits(gb, s->block_delta_pitch_nbits); + bitstream_read(bc, s->block_delta_pitch_nbits); /* Convert last_ so that any next delta is within _range */ last_block_pitch = av_clip(block_pitch, s->block_delta_pitch_hrange, @@ -1567,7 +1566,7 @@ static int synth_frame(AVCodecContext *ctx, GetBitContext *gb, int frame_idx, break; } - synth_block(s, gb, n, block_nsamples, bl_pitch_sh2, + synth_block(s, bc, n, block_nsamples, bl_pitch_sh2, lsps, prev_lsps, &frame_descs[bd_idx], &excitation[n * block_nsamples], &synth[n * block_nsamples]); @@ -1658,32 +1657,32 @@ static void stabilize_lsps(double *lsps, int num) /** * Test if there's enough bits to read 1 superframe. * - * @param orig_gb bit I/O context used for reading. This function + * @param orig_bc bit I/O context used for reading. This function * does not modify the state of the bitreader; it * only uses it to copy the current stream position * @param s WMA Voice decoding context private data * @return < 0 on error, 1 on not enough bits or 0 if OK. */ -static int check_bits_for_superframe(GetBitContext *orig_gb, +static int check_bits_for_superframe(BitstreamContext *orig_bc, WMAVoiceContext *s) { - GetBitContext s_gb, *gb = &s_gb; + BitstreamContext s_bc, *bc = &s_bc; int n, need_bits, bd_idx; const struct frame_type_desc *frame_desc; /* initialize a copy */ - *gb = *orig_gb; + *bc = *orig_bc; /* superframe header */ - if (get_bits_left(gb) < 14) + if (bitstream_bits_left(bc) < 14) return 1; - if (!get_bits1(gb)) + if (!bitstream_read_bit(bc)) return AVERROR(ENOSYS); // WMAPro-in-WMAVoice superframe - if (get_bits1(gb)) skip_bits(gb, 12); // number of samples in superframe + if (bitstream_read_bit(bc)) bitstream_skip(bc, 12); // number of samples in superframe if (s->has_residual_lsps) { // residual LSPs (for all frames) - if (get_bits_left(gb) < s->sframe_lsp_bitsize) + if (bitstream_bits_left(bc) < s->sframe_lsp_bitsize) return 1; - skip_bits_long(gb, s->sframe_lsp_bitsize); + bitstream_skip(bc, s->sframe_lsp_bitsize); } /* frames */ @@ -1691,24 +1690,25 @@ static int check_bits_for_superframe(GetBitContext *orig_gb, int aw_idx_is_ext = 0; if (!s->has_residual_lsps) { // independent LSPs (per-frame) - if (get_bits_left(gb) < s->frame_lsp_bitsize) return 1; - skip_bits_long(gb, s->frame_lsp_bitsize); + if (bitstream_bits_left(bc) < s->frame_lsp_bitsize) + return 1; + bitstream_skip(bc, s->frame_lsp_bitsize); } - bd_idx = s->vbm_tree[get_vlc2(gb, frame_type_vlc.table, 6, 3)]; + bd_idx = s->vbm_tree[bitstream_read_vlc(bc, frame_type_vlc.table, 6, 3)]; if (bd_idx < 0) return AVERROR_INVALIDDATA; // invalid frame type VLC code frame_desc = &frame_descs[bd_idx]; if (frame_desc->acb_type == ACB_TYPE_ASYMMETRIC) { - if (get_bits_left(gb) < s->pitch_nbits) + if (bitstream_bits_left(bc) < s->pitch_nbits) return 1; - skip_bits_long(gb, s->pitch_nbits); + bitstream_skip(bc, s->pitch_nbits); } if (frame_desc->fcb_type == FCB_TYPE_SILENCE) { - skip_bits(gb, 8); + bitstream_skip(bc, 8); } else if (frame_desc->fcb_type == FCB_TYPE_AW_PULSES) { - int tmp = get_bits(gb, 6); + int tmp = bitstream_read(bc, 6); if (tmp >= 0x36) { - skip_bits(gb, 2); + bitstream_skip(bc, 2); aw_idx_is_ext = 1; } } @@ -1722,9 +1722,9 @@ static int check_bits_for_superframe(GetBitContext *orig_gb, } else need_bits = 0; need_bits += frame_desc->frame_size; - if (get_bits_left(gb) < need_bits) + if (bitstream_bits_left(bc) < need_bits) return 1; - skip_bits_long(gb, need_bits); + bitstream_skip(bc, need_bits); } return 0; @@ -1733,7 +1733,7 @@ static int check_bits_for_superframe(GetBitContext *orig_gb, /** * Synthesize output samples for a single superframe. If we have any data * cached in s->sframe_cache, that will be used instead of whatever is loaded - * in s->gb. + * in s->bc. * * WMA Voice superframes contain 3 frames, each containing 160 audio samples, * to give a total of 480 samples per frame. See #synth_frame() for frame @@ -1751,7 +1751,7 @@ static int synth_superframe(AVCodecContext *ctx, AVFrame *frame, int *got_frame_ptr) { WMAVoiceContext *s = ctx->priv_data; - GetBitContext *gb = &s->gb, s_gb; + BitstreamContext *bc = &s->bc, s_bc; int n, res, n_samples = 480; double lsps[MAX_FRAMES][MAX_LSPS]; const double *mean_lsf = s->lsps == 16 ? @@ -1766,12 +1766,12 @@ static int synth_superframe(AVCodecContext *ctx, AVFrame *frame, s->history_nsamples * sizeof(*excitation)); if (s->sframe_cache_size > 0) { - gb = &s_gb; - init_get_bits(gb, s->sframe_cache, s->sframe_cache_size); + bc = &s_bc; + bitstream_init(bc, s->sframe_cache, s->sframe_cache_size); s->sframe_cache_size = 0; } - if ((res = check_bits_for_superframe(gb, s)) == 1) { + if ((res = check_bits_for_superframe(bc, s)) == 1) { *got_frame_ptr = 0; return 1; } else if (res < 0) @@ -1781,14 +1781,14 @@ static int synth_superframe(AVCodecContext *ctx, AVFrame *frame, * speech samples (the actual codec) and WMAVoice music samples, which * are really WMAPro-in-WMAVoice-superframes. I've never seen those in * the wild yet. */ - if (!get_bits1(gb)) { + if (!bitstream_read_bit(bc)) { avpriv_request_sample(ctx, "WMAPro-in-WMAVoice"); return AVERROR_PATCHWELCOME; } /* (optional) nr. of samples in superframe; always <= 480 and >= 0 */ - if (get_bits1(gb)) { - if ((n_samples = get_bits(gb, 12)) > 480) { + if (bitstream_read_bit(bc)) { + if ((n_samples = bitstream_read(bc, 12)) > 480) { av_log(ctx, AV_LOG_ERROR, "Superframe encodes >480 samples (%d), not allowed\n", n_samples); @@ -1803,9 +1803,9 @@ static int synth_superframe(AVCodecContext *ctx, AVFrame *frame, prev_lsps[n] = s->prev_lsps[n] - mean_lsf[n]; if (s->lsps == 10) { - dequant_lsp10r(gb, lsps[2], prev_lsps, a1, a2, s->lsp_q_mode); + dequant_lsp10r(bc, lsps[2], prev_lsps, a1, a2, s->lsp_q_mode); } else /* s->lsps == 16 */ - dequant_lsp16r(gb, lsps[2], prev_lsps, a1, a2, s->lsp_q_mode); + dequant_lsp16r(bc, lsps[2], prev_lsps, a1, a2, s->lsp_q_mode); for (n = 0; n < s->lsps; n++) { lsps[0][n] = mean_lsf[n] + (a1[n] - a2[n * 2]); @@ -1831,16 +1831,16 @@ static int synth_superframe(AVCodecContext *ctx, AVFrame *frame, int m; if (s->lsps == 10) { - dequant_lsp10i(gb, lsps[n]); + dequant_lsp10i(bc, lsps[n]); } else /* s->lsps == 16 */ - dequant_lsp16i(gb, lsps[n]); + dequant_lsp16i(bc, lsps[n]); for (m = 0; m < s->lsps; m++) lsps[n][m] += mean_lsf[m]; stabilize_lsps(lsps[n], s->lsps); } - if ((res = synth_frame(ctx, gb, n, + if ((res = synth_frame(ctx, bc, n, &samples[n * MAX_FRAMESIZE], lsps[n], n == 0 ? s->prev_lsps : lsps[n - 1], &excitation[s->history_nsamples + n * MAX_FRAMESIZE], @@ -1853,9 +1853,9 @@ static int synth_superframe(AVCodecContext *ctx, AVFrame *frame, /* Statistics? FIXME - we don't check for length, a slight overrun * will be caught by internal buffer padding, and anything else * will be skipped, not read. */ - if (get_bits1(gb)) { - res = get_bits(gb, 4); - skip_bits(gb, 10 * (res + 1)); + if (bitstream_read_bit(bc)) { + res = bitstream_read(bc, 4); + bitstream_skip(bc, 10 * (res + 1)); } *got_frame_ptr = 1; @@ -1883,31 +1883,31 @@ static int synth_superframe(AVCodecContext *ctx, AVFrame *frame, */ static int parse_packet_header(WMAVoiceContext *s) { - GetBitContext *gb = &s->gb; + BitstreamContext *bc = &s->bc; unsigned int res; - if (get_bits_left(gb) < 11) + if (bitstream_bits_left(bc) < 11) return 1; - skip_bits(gb, 4); // packet sequence number - s->has_residual_lsps = get_bits1(gb); + bitstream_skip(bc, 4); // packet sequence number + s->has_residual_lsps = bitstream_read_bit(bc); do { - res = get_bits(gb, 6); // number of superframes per packet - // (minus first one if there is spillover) - if (get_bits_left(gb) < 6 * (res == 0x3F) + s->spillover_bitsize) + res = bitstream_read(bc, 6); // number of superframes per packet + // (minus first one if there is spillover) + if (bitstream_bits_left(bc) < 6 * (res == 0x3F) + s->spillover_bitsize) return 1; } while (res == 0x3F); - s->spillover_nbits = get_bits(gb, s->spillover_bitsize); + s->spillover_nbits = bitstream_read(bc, s->spillover_bitsize); return 0; } /** - * Copy (unaligned) bits from gb/data/size to pb. + * Copy (unaligned) bits from bc/data/size to pb. * * @param pb target buffer to copy bits into * @param data source buffer to copy bits from * @param size size of the source data, in bytes - * @param gb bit I/O context specifying the current position in the source. + * @param bc bit I/O context specifying the current position in the source. * data. This function might use this to align the bit position to * a whole-byte boundary before calling #avpriv_copy_bits() on aligned * source data @@ -1918,18 +1918,18 @@ static int parse_packet_header(WMAVoiceContext *s) */ static void copy_bits(PutBitContext *pb, const uint8_t *data, int size, - GetBitContext *gb, int nbits) + BitstreamContext *bc, int nbits) { int rmn_bytes, rmn_bits; - rmn_bits = rmn_bytes = get_bits_left(gb); + rmn_bits = rmn_bytes = bitstream_bits_left(bc); if (rmn_bits < nbits) return; if (nbits > pb->size_in_bits - put_bits_count(pb)) return; rmn_bits &= 7; rmn_bytes >>= 3; if ((rmn_bits = FFMIN(rmn_bits, nbits)) > 0) - put_bits(pb, rmn_bits, get_bits(gb, rmn_bits)); + put_bits(pb, rmn_bits, bitstream_read(bc, rmn_bits)); avpriv_copy_bits(pb, data + size - rmn_bytes, FFMIN(nbits - rmn_bits, rmn_bytes << 3)); } @@ -1949,7 +1949,7 @@ static int wmavoice_decode_packet(AVCodecContext *ctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { WMAVoiceContext *s = ctx->priv_data; - GetBitContext *gb = &s->gb; + BitstreamContext *bc = &s->bc; int size, res, pos; /* Packets are sometimes a multiple of ctx->block_align, with a packet @@ -1962,7 +1962,7 @@ static int wmavoice_decode_packet(AVCodecContext *ctx, void *data, *got_frame_ptr = 0; return 0; } - init_get_bits(&s->gb, avpkt->data, size << 3); + bitstream_init8(&s->bc, avpkt->data, size); /* size == ctx->block_align is used to indicate whether we are dealing with * a new packet or a packet of which we already read the packet header @@ -1976,8 +1976,8 @@ static int wmavoice_decode_packet(AVCodecContext *ctx, void *data, * continuing to parse new superframes in the current packet. */ if (s->spillover_nbits > 0) { if (s->sframe_cache_size > 0) { - int cnt = get_bits_count(gb); - copy_bits(&s->pb, avpkt->data, size, gb, s->spillover_nbits); + int cnt = bitstream_tell(bc); + copy_bits(&s->pb, avpkt->data, size, bc, s->spillover_nbits); flush_put_bits(&s->pb); s->sframe_cache_size += s->spillover_nbits; if ((res = synth_superframe(ctx, data, got_frame_ptr)) == 0 && @@ -1986,33 +1986,33 @@ static int wmavoice_decode_packet(AVCodecContext *ctx, void *data, s->skip_bits_next = cnt & 7; return cnt >> 3; } else - skip_bits_long (gb, s->spillover_nbits - cnt + - get_bits_count(gb)); // resync + bitstream_skip (bc, s->spillover_nbits - cnt + + bitstream_tell(bc)); // resync } else - skip_bits_long(gb, s->spillover_nbits); // resync + bitstream_skip(bc, s->spillover_nbits); // resync } } else if (s->skip_bits_next) - skip_bits(gb, s->skip_bits_next); + bitstream_skip(bc, s->skip_bits_next); /* Try parsing superframes in current packet */ s->sframe_cache_size = 0; s->skip_bits_next = 0; - pos = get_bits_left(gb); + pos = bitstream_bits_left(bc); if ((res = synth_superframe(ctx, data, got_frame_ptr)) < 0) { return res; } else if (*got_frame_ptr) { - int cnt = get_bits_count(gb); + int cnt = bitstream_tell(bc); s->skip_bits_next = cnt & 7; return cnt >> 3; } else if ((s->sframe_cache_size = pos) > 0) { /* rewind bit reader to start of last (incomplete) superframe... */ - init_get_bits(gb, avpkt->data, size << 3); - skip_bits_long(gb, (size << 3) - pos); - assert(get_bits_left(gb) == pos); + bitstream_init8(bc, avpkt->data, size); + bitstream_skip(bc, (size << 3) - pos); + assert(bitstream_bits_left(bc) == pos); /* ...and cache it for spillover in next packet */ init_put_bits(&s->pb, s->sframe_cache, SFRAME_CACHE_MAXSIZE); - copy_bits(&s->pb, avpkt->data, size, gb, s->sframe_cache_size); + copy_bits(&s->pb, avpkt->data, size, bc, s->sframe_cache_size); // FIXME bad - just copy bytes as whole and add use the // skip_bits_next field } From 0ce3761c781f2c2de40a5a8a99563878804f47cc Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 3 Feb 2017 10:15:40 +0100 Subject: [PATCH 0868/3374] configure: Add stdlib.h #include to CPPFLAGS check helper functions This ensures that added CPPFLAGS are validated against libc headers. --- configure | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 555dc8861ea27..32ab7329e3979 100755 --- a/configure +++ b/configure @@ -872,7 +872,7 @@ check_code(){ check_cppflags(){ log check_cppflags "$@" check_cpp "$@" <; EOF } @@ -1166,7 +1166,7 @@ check_host_cpp(){ check_host_cppflags(){ log check_host_cppflags "$@" check_host_cpp "$@" <; EOF } From 71a49fe25f2e4468fbbadbebef8d073b1b3cc1a5 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 20 Jan 2017 15:29:07 +0100 Subject: [PATCH 0869/3374] configure: Use cppflags check helper functions where appropriate --- configure | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/configure b/configure index 32ab7329e3979..c2580a3650c2d 100755 --- a/configure +++ b/configure @@ -3774,18 +3774,12 @@ add_cppflags -D_ISOC99_SOURCE # some compilers silently accept -std=c11, so we also need to check that the # version macro is defined properly -if test_cflags_cpp -std=c11 "__STDC_VERSION__ >= 201112L"; then - add_cflags -std=c11 -else +check_cpp_condition stdlib.h "__STDC_VERSION__ >= 201112L" -std=c11 && + add_cflags -std=c11 || check_cflags -std=c99 -fi -check_cc -D_FILE_OFFSET_BITS=64 < -EOF -check_cc -D_LARGEFILE_SOURCE < -EOF +check_cppflags -D_FILE_OFFSET_BITS=64 +check_cppflags -D_LARGEFILE_SOURCE add_host_cppflags -D_ISOC99_SOURCE check_host_cflags -std=c99 From a25dac976a4478331e4db86d44c3db4456c93eff Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 6 Jun 2016 13:20:17 +0200 Subject: [PATCH 0870/3374] Use bitstream_init8() where appropriate --- libavcodec/4xm.c | 6 +++--- libavcodec/adxdec.c | 2 +- libavcodec/asvdec.c | 2 +- libavcodec/atrac1.c | 2 +- libavcodec/atrac3.c | 10 +++++----- libavcodec/avs.c | 2 +- libavcodec/cdxl.c | 4 ++-- libavcodec/cljrdec.c | 2 +- libavcodec/dss_sp.c | 2 +- libavcodec/dvbsubdec.c | 4 ++-- libavcodec/eatgq.c | 2 +- libavcodec/eatgv.c | 2 +- libavcodec/escape124.c | 2 +- libavcodec/escape130.c | 2 +- libavcodec/faxcompr.c | 2 +- libavcodec/flashsv.c | 2 +- libavcodec/fraps.c | 2 +- libavcodec/g2meet.c | 4 ++-- libavcodec/g722dec.c | 2 +- libavcodec/g723_1dec.c | 2 +- libavcodec/g726.c | 2 +- libavcodec/gsmdec.c | 2 +- libavcodec/hq_hqa.c | 8 ++++---- libavcodec/imc.c | 2 +- libavcodec/indeo2.c | 2 +- libavcodec/indeo3.c | 2 +- libavcodec/interplayvideo.c | 2 +- libavcodec/ivi.c | 2 +- libavcodec/jvdec.c | 2 +- libavcodec/lagarith.c | 2 +- libavcodec/metasound.c | 2 +- libavcodec/mimic.c | 2 +- libavcodec/mlp_parser.c | 2 +- libavcodec/mlpdec.c | 4 ++-- libavcodec/motionpixels.c | 2 +- libavcodec/mpc7.c | 2 +- libavcodec/mpc8.c | 2 +- libavcodec/msgsmdec.c | 2 +- libavcodec/nellymoserdec.c | 4 ++-- libavcodec/pcx.c | 2 +- libavcodec/qcelpdec.c | 2 +- libavcodec/qdm2.c | 12 ++++++------ libavcodec/ra144dec.c | 2 +- libavcodec/ra288.c | 2 +- libavcodec/smacker.c | 6 +++--- libavcodec/svq1dec.c | 4 ++-- libavcodec/tiertexseqv.c | 6 +++--- libavcodec/truemotion2.c | 6 +++--- libavcodec/truespeech.c | 2 +- libavcodec/tscc2.c | 2 +- libavcodec/tta.c | 4 ++-- libavcodec/twinvqdec.c | 2 +- libavcodec/utvideodec.c | 2 +- libavcodec/vble.c | 2 +- libavcodec/webp.c | 4 ++-- libavcodec/wnv1.c | 2 +- libavcodec/xan.c | 2 +- libavcodec/xsubdec.c | 2 +- libavformat/h261dec.c | 2 +- libavformat/mov.c | 2 +- libavformat/movenc.c | 4 ++-- libavformat/mpegts.c | 2 +- libavformat/oggparseflac.c | 2 +- libavformat/oggparsetheora.c | 2 +- libavformat/rdt.c | 2 +- libavformat/rtpdec_latm.c | 2 +- libavformat/rtpdec_mpeg4.c | 2 +- libavformat/rtpdec_qt.c | 2 +- libavformat/rtpenc_h263_rfc2190.c | 2 +- 69 files changed, 98 insertions(+), 98 deletions(-) diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index ee9d0205d5a82..28f839165e645 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -454,7 +454,7 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length) bitstream_size / 4); memset((uint8_t*)f->bitstream_buffer + bitstream_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); - bitstream_init(&f->bc, f->bitstream_buffer, 8 * bitstream_size); + bitstream_init8(&f->bc, f->bitstream_buffer, bitstream_size); wordstream_offset = extra + bitstream_size; bytestream_offset = extra + bitstream_size + wordstream_size; @@ -765,7 +765,7 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length) return AVERROR_INVALIDDATA; } - bitstream_init(&f->bc, buf + 4, 8 * bitstream_size); + bitstream_init8(&f->bc, buf + 4, bitstream_size); prestream_size = length + buf - prestream; @@ -777,7 +777,7 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length) prestream_size / 4); memset((uint8_t*)f->bitstream_buffer + prestream_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); - bitstream_init(&f->pre_bc, f->bitstream_buffer, 8 * prestream_size); + bitstream_init8(&f->pre_bc, f->bitstream_buffer, prestream_size); f->last_dc = 0 * 128 * 8 * 8; diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index a3344ae695872..86aaade846a71 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -76,7 +76,7 @@ static int adx_decode(ADXContext *c, int16_t *out, int offset, if (scale & 0x8000) return -1; - bitstream_init(&bc, in + 2, (BLOCK_SIZE - 2) * 8); + bitstream_init8(&bc, in + 2, BLOCK_SIZE - 2); out += offset; s1 = prev->s1; s2 = prev->s2; diff --git a/libavcodec/asvdec.c b/libavcodec/asvdec.c index cbda63d3b0c75..bd87512d131c8 100644 --- a/libavcodec/asvdec.c +++ b/libavcodec/asvdec.c @@ -232,7 +232,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, a->bitstream_buffer[i] = ff_reverse[buf[i]]; } - bitstream_init(&a->bc, a->bitstream_buffer, buf_size * 8); + bitstream_init8(&a->bc, a->bitstream_buffer, buf_size); for (mb_y = 0; mb_y < a->mb_height2; mb_y++) { for (mb_x = 0; mb_x < a->mb_width2; mb_x++) { diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c index 60be85358889f..52d43e2c946aa 100644 --- a/libavcodec/atrac1.c +++ b/libavcodec/atrac1.c @@ -297,7 +297,7 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data, for (ch = 0; ch < avctx->channels; ch++) { AT1SUCtx* su = &q->SUs[ch]; - bitstream_init(&bc, &buf[212 * ch], 212 * 8); + bitstream_init8(&bc, &buf[212 * ch], 212); /* parse block_size_mode, 1st byte */ ret = at1_parse_bsm(&bc, su->log2_block_count); diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index be32a0ec864d8..2a703ca46ef0d 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -645,7 +645,7 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *databuf, if (q->coding_mode == JOINT_STEREO) { /* channel coupling mode */ /* decode Sound Unit 1 */ - bitstream_init(&q->bc, databuf, avctx->block_align * 8); + bitstream_init8(&q->bc, databuf, avctx->block_align); ret = decode_channel_sound_unit(q, &q->bc, q->units, out_samples[0], 0, JOINT_STEREO); @@ -674,7 +674,7 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *databuf, /* set the bitstream reader at the start of the second Sound Unit*/ - bitstream_init(&q->bc, ptr1, (avctx->block_align - i) * 8); + bitstream_init8(&q->bc, ptr1, avctx->block_align - i); /* Fill the Weighting coeffs delay buffer */ memmove(q->weighting_delay, &q->weighting_delay[2], @@ -705,9 +705,9 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *databuf, /* Decode the channel sound units. */ for (i = 0; i < avctx->channels; i++) { /* Set the bitstream reader at the start of a channel sound unit. */ - bitstream_init(&q->bc, - databuf + i * avctx->block_align / avctx->channels, - avctx->block_align * 8 / avctx->channels); + bitstream_init8(&q->bc, + databuf + i * avctx->block_align / avctx->channels, + avctx->block_align / avctx->channels); ret = decode_channel_sound_unit(q, &q->bc, &q->units[i], out_samples[i], i, q->coding_mode); diff --git a/libavcodec/avs.c b/libavcodec/avs.c index bea01a265621a..959f570b389e6 100644 --- a/libavcodec/avs.c +++ b/libavcodec/avs.c @@ -125,7 +125,7 @@ avs_decode_frame(AVCodecContext * avctx, int map_size = ((318 / vect_w + 7) / 8) * (198 / vect_h); if (buf_end - table < map_size) return AVERROR_INVALIDDATA; - bitstream_init(&change_map, table, map_size * 8); + bitstream_init8(&change_map, table, map_size); table += map_size; } diff --git a/libavcodec/cdxl.c b/libavcodec/cdxl.c index 4c0410dd212eb..e7cb79caf0c28 100644 --- a/libavcodec/cdxl.c +++ b/libavcodec/cdxl.c @@ -73,7 +73,7 @@ static void bitplanar2chunky(CDXLVideoContext *c, int linesize, uint8_t *out) BitstreamContext bc; int x, y, plane; - bitstream_init(&bc, c->video, c->video_size * 8); + bitstream_init8(&bc, c->video, c->video_size); for (plane = 0; plane < c->bpp; plane++) { for (y = 0; y < c->avctx->height; y++) { for (x = 0; x < c->avctx->width; x++) @@ -88,7 +88,7 @@ static void bitline2chunky(CDXLVideoContext *c, int linesize, uint8_t *out) BitstreamContext bc; int x, y, plane; - bitstream_init(&bc, c->video, c->video_size * 8); + bitstream_init8(&bc, c->video, c->video_size); for (y = 0; y < c->avctx->height; y++) { for (plane = 0; plane < c->bpp; plane++) { for (x = 0; x < c->avctx->width; x++) diff --git a/libavcodec/cljrdec.c b/libavcodec/cljrdec.c index 833707b0999f1..d17212e157653 100644 --- a/libavcodec/cljrdec.c +++ b/libavcodec/cljrdec.c @@ -56,7 +56,7 @@ static int decode_frame(AVCodecContext *avctx, p->pict_type = AV_PICTURE_TYPE_I; p->key_frame = 1; - bitstream_init(&bc, buf, buf_size * 8); + bitstream_init8(&bc, buf, buf_size); for (y = 0; y < avctx->height; y++) { uint8_t *luma = &p->data[0][y * p->linesize[0]]; diff --git a/libavcodec/dss_sp.c b/libavcodec/dss_sp.c index 44d98d8cf99d9..4fe784c055fb7 100644 --- a/libavcodec/dss_sp.c +++ b/libavcodec/dss_sp.c @@ -315,7 +315,7 @@ static void dss_sp_unpack_coeffs(DssSpContext *p, const uint8_t *src) p->bits[i + 1] = src[i]; } - bitstream_init(&bc, p->bits, DSS_SP_FRAME_SIZE * 8); + bitstream_init8(&bc, p->bits, DSS_SP_FRAME_SIZE); for (i = 0; i < 2; i++) fparam->filter_idx[i] = bitstream_read(&bc, 5); diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c index 2b9760fb35c8f..6530847dff1ad 100644 --- a/libavcodec/dvbsubdec.c +++ b/libavcodec/dvbsubdec.c @@ -336,7 +336,7 @@ static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, int run_length; int pixels_read = 0; - bitstream_init(&bc, *srcbuf, buf_size << 3); + bitstream_init8(&bc, *srcbuf, buf_size); while (bitstream_tell(&bc) < buf_size << 3 && pixels_read < dbuf_len) { bits = bitstream_read(&bc, 2); @@ -441,7 +441,7 @@ static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, int run_length; int pixels_read = 0; - bitstream_init(&bc, *srcbuf, buf_size << 3); + bitstream_init8(&bc, *srcbuf, buf_size); while (bitstream_tell(&bc) < buf_size << 3 && pixels_read < dbuf_len) { bits = bitstream_read(&bc, 4); diff --git a/libavcodec/eatgq.c b/libavcodec/eatgq.c index 9abedcc7838f6..190f4c89553bd 100644 --- a/libavcodec/eatgq.c +++ b/libavcodec/eatgq.c @@ -157,7 +157,7 @@ static void tgq_decode_mb(TgqContext *s, AVFrame *frame, int mb_y, int mb_x) mode = bytestream2_get_byte(&s->gb); if (mode > 12) { BitstreamContext bc; - bitstream_init(&bc, s->gb.buffer, FFMIN(s->gb.buffer_end - s->gb.buffer, mode) * 8); + bitstream_init8(&bc, s->gb.buffer, FFMIN(s->gb.buffer_end - s->gb.buffer, mode)); for (i = 0; i < 6; i++) tgq_decode_block(s, s->block[i], &bc); tgq_idct_put_mb(s, s->block, frame, mb_x, mb_y); diff --git a/libavcodec/eatgv.c b/libavcodec/eatgv.c index 549b5b6d3ca41..3894f2beccd8c 100644 --- a/libavcodec/eatgv.c +++ b/libavcodec/eatgv.c @@ -207,7 +207,7 @@ static int tgv_decode_inter(TgvContext *s, AVFrame *frame, buf += num_blocks_raw * 16; /* read compressed blocks */ - bitstream_init(&bc, buf, (buf_end - buf) << 3); + bitstream_init8(&bc, buf, buf_end - buf); for (i = 0; i < num_blocks_packed; i++) { int tmp[4]; for (j = 0; j < 4; j++) diff --git a/libavcodec/escape124.c b/libavcodec/escape124.c index 879f00a73cd0a..86a63a434e39b 100644 --- a/libavcodec/escape124.c +++ b/libavcodec/escape124.c @@ -217,7 +217,7 @@ static int escape124_decode_frame(AVCodecContext *avctx, unsigned old_stride, new_stride; int ret; - bitstream_init(&bc, buf, buf_size * 8); + bitstream_init8(&bc, buf, buf_size); // This call also guards the potential depth reads for the // codebook unpacking. diff --git a/libavcodec/escape130.c b/libavcodec/escape130.c index 544f36d1ac056..0f2fcae395b5c 100644 --- a/libavcodec/escape130.c +++ b/libavcodec/escape130.c @@ -216,7 +216,7 @@ static int escape130_decode_frame(AVCodecContext *avctx, void *data, if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) return ret; - bitstream_init(&bc, buf + 16, (buf_size - 16) * 8); + bitstream_init8(&bc, buf + 16, buf_size - 16); new_y = s->new_y; new_cb = s->new_u; diff --git a/libavcodec/faxcompr.c b/libavcodec/faxcompr.c index 8a9010d40c08c..9eb4e379999c0 100644 --- a/libavcodec/faxcompr.c +++ b/libavcodec/faxcompr.c @@ -289,7 +289,7 @@ int ff_ccitt_unpack(AVCodecContext *avctx, const uint8_t *src, int srcsize, ref[0] = avctx->width; ref[1] = 0; ref[2] = 0; - bitstream_init(&bc, src, srcsize * 8); + bitstream_init8(&bc, src, srcsize); for (j = 0; j < height; j++) { runend = runs + runsize; if (compr == TIFF_G4) { diff --git a/libavcodec/flashsv.c b/libavcodec/flashsv.c index 20fa7bc1aff3d..252caab25e0be 100644 --- a/libavcodec/flashsv.c +++ b/libavcodec/flashsv.c @@ -268,7 +268,7 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, if (buf_size < 4) return -1; - bitstream_init(&bc, avpkt->data, buf_size * 8); + bitstream_init8(&bc, avpkt->data, buf_size); /* start to parse the bitstream */ s->block_width = 16 * (bitstream_read(&bc, 4) + 1); diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c index 22379911330e1..fd1dcb7b4a7b8 100644 --- a/libavcodec/fraps.c +++ b/libavcodec/fraps.c @@ -111,7 +111,7 @@ static int fraps2_decode_plane(FrapsContext *s, uint8_t *dst, int stride, int w, s->bdsp.bswap_buf((uint32_t *) s->tmpbuf, (const uint32_t *) src, size >> 2); - bitstream_init(&bc, s->tmpbuf, size * 8); + bitstream_init8(&bc, s->tmpbuf, size); for (j = 0; j < h; j++) { for (i = 0; i < w*step; i += step) { dst[i] = bitstream_read_vlc(&bc, vlc.table, VLC_BITS, 3); diff --git a/libavcodec/g2meet.c b/libavcodec/g2meet.c index 4a7f5a3666988..511ea534b8830 100644 --- a/libavcodec/g2meet.c +++ b/libavcodec/g2meet.c @@ -298,7 +298,7 @@ static int jpg_decode_data(JPGContext *c, int width, int height, return ret; jpg_unescape(src, src_size, c->buf, &unesc_size); memset(c->buf + unesc_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); - bitstream_init(&bc, c->buf, unesc_size * 8); + bitstream_init8(&bc, c->buf, unesc_size); width = FFALIGN(width, 16); mb_w = width >> 4; @@ -1015,7 +1015,7 @@ static void kempf_restore_buf(const uint8_t *src, int len, int i, j, nb, col; int align_width = FFALIGN(width, 16); - bitstream_init(&bc, src, len * 8); + bitstream_init8(&bc, src, len); if (npal <= 2) nb = 1; else if (npal <= 4) nb = 2; diff --git a/libavcodec/g722dec.c b/libavcodec/g722dec.c index f9605c99c588f..07af0a082a5cb 100644 --- a/libavcodec/g722dec.c +++ b/libavcodec/g722dec.c @@ -103,7 +103,7 @@ static int g722_decode_frame(AVCodecContext *avctx, void *data, } out_buf = (int16_t *)frame->data[0]; - bitstream_init(&bc, avpkt->data, avpkt->size * 8); + bitstream_init8(&bc, avpkt->data, avpkt->size); for (j = 0; j < avpkt->size; j++) { int ilow, ihigh, rlow, rhigh, dhigh; diff --git a/libavcodec/g723_1dec.c b/libavcodec/g723_1dec.c index 2ea3bbffa51c7..0cb5ba70c533b 100644 --- a/libavcodec/g723_1dec.c +++ b/libavcodec/g723_1dec.c @@ -72,7 +72,7 @@ static int unpack_bitstream(G723_1_Context *p, const uint8_t *buf, int ad_cb_len; int temp, info_bits, i; - bitstream_init(&bc, buf, buf_size * 8); + bitstream_init8(&bc, buf, buf_size); /* Extract frame type and rate info */ info_bits = bitstream_read(&bc, 2); diff --git a/libavcodec/g726.c b/libavcodec/g726.c index 007cdb63ccdea..dab038f50ce85 100644 --- a/libavcodec/g726.c +++ b/libavcodec/g726.c @@ -443,7 +443,7 @@ static int g726_decode_frame(AVCodecContext *avctx, void *data, } samples = (int16_t *)frame->data[0]; - bitstream_init(&bc, buf, buf_size * 8); + bitstream_init8(&bc, buf, buf_size); while (out_samples--) *samples++ = g726_decode(c, bitstream_read(&bc, c->code_size)); diff --git a/libavcodec/gsmdec.c b/libavcodec/gsmdec.c index d727cf9ccf364..0205fafad0239 100644 --- a/libavcodec/gsmdec.c +++ b/libavcodec/gsmdec.c @@ -88,7 +88,7 @@ static int gsm_decode_frame(AVCodecContext *avctx, void *data, switch (avctx->codec_id) { case AV_CODEC_ID_GSM: - bitstream_init(&bc, buf, buf_size * 8); + bitstream_init8(&bc, buf, buf_size); if (bitstream_read(&bc, 4) != 0xd) av_log(avctx, AV_LOG_WARNING, "Missing GSM magic!\n"); res = gsm_decode_block(avctx, samples, &bc, GSM_13000); diff --git a/libavcodec/hq_hqa.c b/libavcodec/hq_hqa.c index 0d03e593f39e6..2afe8531beeb7 100644 --- a/libavcodec/hq_hqa.c +++ b/libavcodec/hq_hqa.c @@ -160,8 +160,8 @@ static int hq_decode_frame(HQContext *ctx, AVFrame *pic, "Invalid slice size %zu.\n", data_size); break; } - bitstream_init(&bc, src + slice_off[slice], - (slice_off[slice + 1] - slice_off[slice]) * 8); + bitstream_init8(&bc, src + slice_off[slice], + slice_off[slice + 1] - slice_off[slice]); for (i = 0; i < (next_off - start_off) * profile->tab_w; i++) { ret = hq_decode_mb(ctx, pic, &bc, perm[0] * 16, perm[1] * 16); @@ -285,8 +285,8 @@ static int hqa_decode_frame(HQContext *ctx, AVFrame *pic, size_t data_size) "Invalid slice size %zu.\n", data_size); break; } - bitstream_init(&bc, src + slice_off[slice], - (slice_off[slice + 1] - slice_off[slice]) * 8); + bitstream_init8(&bc, src + slice_off[slice], + slice_off[slice + 1] - slice_off[slice]); ret = hqa_decode_slice(ctx, pic, &bc, quant, slice, width, height); if (ret < 0) diff --git a/libavcodec/imc.c b/libavcodec/imc.c index 01ab0125f2cca..145b2d56fc865 100644 --- a/libavcodec/imc.c +++ b/libavcodec/imc.c @@ -1016,7 +1016,7 @@ static int imc_decode_frame(AVCodecContext *avctx, void *data, q->bdsp.bswap16_buf(buf16, (const uint16_t *) buf, IMC_BLOCK_SIZE / 2); - bitstream_init(&q->bc, (const uint8_t*)buf16, IMC_BLOCK_SIZE * 8); + bitstream_init8(&q->bc, (const uint8_t *)buf16, IMC_BLOCK_SIZE); buf += IMC_BLOCK_SIZE; diff --git a/libavcodec/indeo2.c b/libavcodec/indeo2.c index de2a9bb2f1293..811056dbfc365 100644 --- a/libavcodec/indeo2.c +++ b/libavcodec/indeo2.c @@ -171,7 +171,7 @@ static int ir2_decode_frame(AVCodecContext *avctx, buf[i] = ff_reverse[buf[i]]; #endif - bitstream_init(&s->bc, buf + start, (buf_size - start) * 8); + bitstream_init8(&s->bc, buf + start, buf_size - start); ltab = buf[0x22] & 3; ctab = buf[0x22] >> 2; diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c index 37d85e1abc230..22a072dea37b2 100644 --- a/libavcodec/indeo3.c +++ b/libavcodec/indeo3.c @@ -857,7 +857,7 @@ static int decode_plane(Indeo3DecodeContext *ctx, AVCodecContext *avctx, ctx->mc_vectors = num_vectors ? data : 0; /* init the bitreader */ - bitstream_init(&ctx->bc, &data[num_vectors * 2], (data_size - num_vectors * 2) << 3); + bitstream_init8(&ctx->bc, &data[num_vectors * 2], data_size - num_vectors * 2); ctx->skip_bits = 0; ctx->need_resync = 0; diff --git a/libavcodec/interplayvideo.c b/libavcodec/interplayvideo.c index fab9f2724c99f..f5593d347a232 100644 --- a/libavcodec/interplayvideo.c +++ b/libavcodec/interplayvideo.c @@ -898,7 +898,7 @@ static void ipvideo_decode_opcodes(IpvideoContext *s, AVFrame *frame) s->upper_motion_limit_offset = (s->avctx->height - 8) * frame->linesize[0] + (s->avctx->width - 8) * (1 + s->is_16bpp); - bitstream_init(&bc, s->decoding_map, s->decoding_map_size * 8); + bitstream_init8(&bc, s->decoding_map, s->decoding_map_size); for (y = 0; y < s->avctx->height; y += 8) { for (x = 0; x < s->avctx->width; x += 8) { opcode = bitstream_read(&bc, 4); diff --git a/libavcodec/ivi.c b/libavcodec/ivi.c index a83773443ccfc..2ff4824c92db5 100644 --- a/libavcodec/ivi.c +++ b/libavcodec/ivi.c @@ -1029,7 +1029,7 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, int buf_size = avpkt->size; int result, p, b; - bitstream_init(&ctx->bc, buf, buf_size * 8); + bitstream_init8(&ctx->bc, buf, buf_size); ctx->frame_data = buf; ctx->frame_size = buf_size; diff --git a/libavcodec/jvdec.c b/libavcodec/jvdec.c index 37a2770063eeb..5f5a825cd703e 100644 --- a/libavcodec/jvdec.c +++ b/libavcodec/jvdec.c @@ -164,7 +164,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (video_type == 0 || video_type == 1) { BitstreamContext bc; - bitstream_init(&bc, buf, 8 * FFMIN(video_size, buf_end - buf)); + bitstream_init8(&bc, buf, FFMIN(video_size, buf_end - buf)); for (j = 0; j < avctx->height; j += 8) for (i = 0; i < avctx->width; i += 8) diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c index d9667b7afced7..95e6aba25153b 100644 --- a/libavcodec/lagarith.c +++ b/libavcodec/lagarith.c @@ -436,7 +436,7 @@ static int lag_decode_arith_plane(LagarithContext *l, uint8_t *dst, offset += 4; } - bitstream_init(&bc, src + offset, src_size * 8); + bitstream_init8(&bc, src + offset, src_size); if (lag_read_prob_header(&rac, &bc) < 0) return -1; diff --git a/libavcodec/metasound.c b/libavcodec/metasound.c index ac6d9cd1c068e..4cd9051dbdd94 100644 --- a/libavcodec/metasound.c +++ b/libavcodec/metasound.c @@ -172,7 +172,7 @@ static int metasound_read_bitstream(AVCodecContext *avctx, TwinVQContext *tctx, BitstreamContext bc; int i, j, k; - bitstream_init(&bc, buf, buf_size * 8); + bitstream_init8(&bc, buf, buf_size); for (tctx->cur_frame = 0; tctx->cur_frame < tctx->frames_per_packet; tctx->cur_frame++) { diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c index 34d2587cfe66e..1ec27b292668f 100644 --- a/libavcodec/mimic.c +++ b/libavcodec/mimic.c @@ -426,7 +426,7 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data, ctx->bbdsp.bswap_buf(ctx->swap_buf, (const uint32_t *) (buf + MIMIC_HEADER_SIZE), swap_buf_size >> 2); - bitstream_init(&ctx->bc, ctx->swap_buf, swap_buf_size << 3); + bitstream_init8(&ctx->bc, ctx->swap_buf, swap_buf_size); res = decode(ctx, quality, num_coeffs, !is_pframe); ff_thread_report_progress(&ctx->frames[ctx->cur_index], INT_MAX, 0); diff --git a/libavcodec/mlp_parser.c b/libavcodec/mlp_parser.c index 45764e83f218c..e9ba840200a67 100644 --- a/libavcodec/mlp_parser.c +++ b/libavcodec/mlp_parser.c @@ -332,7 +332,7 @@ static int mlp_parse(AVCodecParserContext *s, BitstreamContext bc; MLPHeaderInfo mh; - bitstream_init(&bc, buf + 4, (buf_size - 4) << 3); + bitstream_init8(&bc, buf + 4, buf_size - 4); if (ff_mlp_read_major_sync(avctx, &mh, &bc) < 0) goto lost_sync; diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c index 40889161f81a4..a606213f97a73 100644 --- a/libavcodec/mlpdec.c +++ b/libavcodec/mlpdec.c @@ -1095,7 +1095,7 @@ static int read_access_unit(AVCodecContext *avctx, void* data, if (length < 4 || length > buf_size) return AVERROR_INVALIDDATA; - bitstream_init(&bc, (buf + 4), (length - 4) * 8); + bitstream_init8(&bc, buf + 4, length - 4); m->is_major_sync_unit = 0; if (bitstream_peek(&bc, 31) == (0xf8726fba >> 1)) { @@ -1175,7 +1175,7 @@ static int read_access_unit(AVCodecContext *avctx, void* data, for (substr = 0; substr <= m->max_decoded_substream; substr++) { SubStream *s = &m->substream[substr]; - bitstream_init(&bc, buf, substream_data_len[substr] * 8); + bitstream_init8(&bc, buf, substream_data_len[substr]); m->matrix_changed = 0; memset(m->filter_changed, 0, sizeof(m->filter_changed)); diff --git a/libavcodec/motionpixels.c b/libavcodec/motionpixels.c index 333f18fdb25c1..da4c141db6d7e 100644 --- a/libavcodec/motionpixels.c +++ b/libavcodec/motionpixels.c @@ -285,7 +285,7 @@ static int mp_decode_frame(AVCodecContext *avctx, if (buf_size & 3) memcpy(mp->bswapbuf + (buf_size & ~3), buf + (buf_size & ~3), buf_size & 3); memset(mp->bswapbuf + buf_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); - bitstream_init(&bc, mp->bswapbuf, buf_size * 8); + bitstream_init8(&bc, mp->bswapbuf, buf_size); memset(mp->changes_map, 0, avctx->width * avctx->height); for (i = !(avctx->extradata[1] & 2); i < 2; ++i) { diff --git a/libavcodec/mpc7.c b/libavcodec/mpc7.c index 5d749106de345..66a6162ec5d5f 100644 --- a/libavcodec/mpc7.c +++ b/libavcodec/mpc7.c @@ -238,7 +238,7 @@ static int mpc7_decode_frame(AVCodecContext * avctx, void *data, return AVERROR(ENOMEM); c->bdsp.bswap_buf((uint32_t *) c->bits, (const uint32_t *) buf, buf_size >> 2); - bitstream_init(&bc, c->bits, buf_size * 8); + bitstream_init8(&bc, c->bits, buf_size); bitstream_skip(&bc, skip); /* read subband indexes */ diff --git a/libavcodec/mpc8.c b/libavcodec/mpc8.c index cf621afb12569..f55fd5782400b 100644 --- a/libavcodec/mpc8.c +++ b/libavcodec/mpc8.c @@ -259,7 +259,7 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data, memset(c->Q, 0, sizeof(c->Q)); c->last_bits_used = 0; } - bitstream_init(bc, buf, buf_size * 8); + bitstream_init8(bc, buf, buf_size); bitstream_skip(bc, c->last_bits_used & 7); if(keyframe) diff --git a/libavcodec/msgsmdec.c b/libavcodec/msgsmdec.c index c26efa9fae04a..01ea95f43b4d1 100644 --- a/libavcodec/msgsmdec.c +++ b/libavcodec/msgsmdec.c @@ -32,7 +32,7 @@ int ff_msgsm_decode_block(AVCodecContext *avctx, int16_t *samples, { int res; BitstreamContext bc; - bitstream_init(&bc, buf, GSM_MS_BLOCK_SIZE * 8); + bitstream_init8(&bc, buf, GSM_MS_BLOCK_SIZE); res = gsm_decode_block(avctx, samples, &bc, mode); if (res < 0) return res; diff --git a/libavcodec/nellymoserdec.c b/libavcodec/nellymoserdec.c index 390872c89aef4..8d9af5fff6437 100644 --- a/libavcodec/nellymoserdec.c +++ b/libavcodec/nellymoserdec.c @@ -67,7 +67,7 @@ static void nelly_decode_block(NellyMoserDecodeContext *s, int bits[NELLY_BUF_LEN]; unsigned char v; - bitstream_init(&s->bc, block, NELLY_BLOCK_LEN * 8); + bitstream_init8(&s->bc, block, NELLY_BLOCK_LEN); bptr = buf; pptr = pows; @@ -88,7 +88,7 @@ static void nelly_decode_block(NellyMoserDecodeContext *s, for (i = 0; i < 2; i++) { aptr = audio + i * NELLY_BUF_LEN; - bitstream_init(&s->bc, block, NELLY_BLOCK_LEN * 8); + bitstream_init8(&s->bc, block, NELLY_BLOCK_LEN); bitstream_skip(&s->bc, NELLY_HEADER_BITS + i * NELLY_DETAIL_BITS); for (j = 0; j < NELLY_FILL_LEN; j++) { diff --git a/libavcodec/pcx.c b/libavcodec/pcx.c index ece885e6e01c5..f4a6a9196f50a 100644 --- a/libavcodec/pcx.c +++ b/libavcodec/pcx.c @@ -183,7 +183,7 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, BitstreamContext s; for (y = 0; y < h; y++) { - bitstream_init(&s, scanline, bytes_per_scanline << 3); + bitstream_init8(&s, scanline, bytes_per_scanline); pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed); diff --git a/libavcodec/qcelpdec.c b/libavcodec/qcelpdec.c index 9d5e13a117d3e..83be57a427580 100644 --- a/libavcodec/qcelpdec.c +++ b/libavcodec/qcelpdec.c @@ -719,7 +719,7 @@ static int qcelp_decode_frame(AVCodecContext *avctx, void *data, qcelp_unpacking_bitmaps_lengths[q->bitrate]; uint8_t *unpacked_data = (uint8_t *)&q->frame; - bitstream_init(&q->bc, buf, 8 * buf_size); + bitstream_init8(&q->bc, buf, buf_size); memset(&q->frame, 0, sizeof(QCELPFrame)); diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c index 781999aa101cb..00c952d51a279 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -1105,7 +1105,7 @@ static void process_subpacket_9(QDM2Context *q, QDM2SubPNode *node) BitstreamContext bc; int i, j, k, n, ch, run, level, diff; - bitstream_init(&bc, node->packet->data, node->packet->size * 8); + bitstream_init8(&bc, node->packet->data, node->packet->size); n = coeff_per_sb_for_avg[q->coeff_per_sb_select][QDM2_SB_USED(q->sub_sampling) - 1] + 1; @@ -1142,7 +1142,7 @@ static void process_subpacket_10(QDM2Context *q, QDM2SubPNode *node) BitstreamContext bc; if (node) { - bitstream_init(&bc, node->packet->data, node->packet->size * 8); + bitstream_init8(&bc, node->packet->data, node->packet->size); init_tone_level_dequantization(q, &bc); fill_tone_level_array(q, 1); } else { @@ -1252,7 +1252,7 @@ static void qdm2_decode_super_block(QDM2Context *q) average_quantized_coeffs(q); // average elements in quantized_coeffs[max_ch][10][8] - bitstream_init(&bc, q->compressed_data, q->compressed_size * 8); + bitstream_init8(&bc, q->compressed_data, q->compressed_size); qdm2_decode_sub_packet_header(&bc, &header); if (header.type < 2 || header.type >= 8) { @@ -1264,7 +1264,7 @@ static void qdm2_decode_super_block(QDM2Context *q) q->superblocktype_2_3 = (header.type == 2 || header.type == 3); packet_bytes = (q->compressed_size - bitstream_tell(&bc) / 8); - bitstream_init(&bc, header.data, header.size * 8); + bitstream_init8(&bc, header.data, header.size); if (header.type == 2 || header.type == 4 || header.type == 5) { int csum = 257 * bitstream_read(&bc, 8); @@ -1300,7 +1300,7 @@ static void qdm2_decode_super_block(QDM2Context *q) q->sub_packet_list_A[i - 1].next = &q->sub_packet_list_A[i]; /* seek to next block */ - bitstream_init(&bc, header.data, header.size * 8); + bitstream_init8(&bc, header.data, header.size); bitstream_skip(&bc, next_index * 8); if (next_index >= header.size) @@ -1495,7 +1495,7 @@ static void qdm2_decode_fft_packets(QDM2Context *q) return; /* decode FFT tones */ - bitstream_init(&bc, packet->data, packet->size * 8); + bitstream_init8(&bc, packet->data, packet->size); if (packet->type >= 32 && packet->type < 48 && !fft_subpackets[packet->type - 16]) unknown_flag = 1; diff --git a/libavcodec/ra144dec.c b/libavcodec/ra144dec.c index 35ee697731572..05165bf2e4a02 100644 --- a/libavcodec/ra144dec.c +++ b/libavcodec/ra144dec.c @@ -92,7 +92,7 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *data, } samples = (int16_t *)frame->data[0]; - bitstream_init(&bc, buf, FRAMESIZE * 8); + bitstream_init8(&bc, buf, FRAMESIZE); for (i = 0; i < LPC_ORDER; i++) lpc_refl[i] = ff_lpc_refl_cb[i][bitstream_read(&bc, sizes[i])]; diff --git a/libavcodec/ra288.c b/libavcodec/ra288.c index bc3fe29dc1491..c457d0c710214 100644 --- a/libavcodec/ra288.c +++ b/libavcodec/ra288.c @@ -198,7 +198,7 @@ static int ra288_decode_frame(AVCodecContext * avctx, void *data, } out = (float *)frame->data[0]; - bitstream_init(&bc, buf, avctx->block_align * 8); + bitstream_init8(&bc, buf, avctx->block_align); for (i=0; i < RA288_BLOCKS_PER_FRAME; i++) { float gain = amptable[bitstream_read(&bc, 3)]; diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c index 027728e387be2..2abf7c1c5af4f 100644 --- a/libavcodec/smacker.c +++ b/libavcodec/smacker.c @@ -302,7 +302,7 @@ static int decode_header_trees(SmackVContext *smk) { full_size = AV_RL32(smk->avctx->extradata + 8); type_size = AV_RL32(smk->avctx->extradata + 12); - bitstream_init(&bc, smk->avctx->extradata + 16, (smk->avctx->extradata_size - 16) * 8); + bitstream_init8(&bc, smk->avctx->extradata + 16, smk->avctx->extradata_size - 16); if (!bitstream_read_bit(&bc)) { av_log(smk->avctx, AV_LOG_INFO, "Skipping MMAP tree\n"); @@ -417,7 +417,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, last_reset(smk->mclr_tbl, smk->mclr_last); last_reset(smk->full_tbl, smk->full_last); last_reset(smk->type_tbl, smk->type_last); - bitstream_init(&bc, avpkt->data + 769, (avpkt->size - 769) * 8); + bitstream_init8(&bc, avpkt->data + 769, avpkt->size - 769); blk = 0; bw = avctx->width >> 2; @@ -618,7 +618,7 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, unp_size = AV_RL32(buf); - bitstream_init(&bc, buf + 4, (buf_size - 4) * 8); + bitstream_init8(&bc, buf + 4, buf_size - 4); if (!bitstream_read_bit(&bc)) { av_log(avctx, AV_LOG_INFO, "Sound: no data\n"); diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c index 2ab0f238bbb67..bce04e807da4c 100644 --- a/libavcodec/svq1dec.c +++ b/libavcodec/svq1dec.c @@ -616,7 +616,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, svq1_pmv *pmv; /* initialize bit buffer */ - bitstream_init(&s->bc, buf, buf_size * 8); + bitstream_init8(&s->bc, buf, buf_size); /* decode frame header */ s->frame_code = bitstream_read(&s->bc, 22); @@ -647,7 +647,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, for (i = 0; i < 4; i++) src[i] = ((src[i] << 16) | (src[i] >> 16)) ^ src[7 - i]; - bitstream_init(&s->bc, buf, buf_size * 8); + bitstream_init8(&s->bc, buf, buf_size); bitstream_skip(&s->bc, 22); } diff --git a/libavcodec/tiertexseqv.c b/libavcodec/tiertexseqv.c index d95226678b1e7..e24d4018c94a1 100644 --- a/libavcodec/tiertexseqv.c +++ b/libavcodec/tiertexseqv.c @@ -45,7 +45,7 @@ static const unsigned char *seq_unpack_rle_block(const unsigned char *src, int code_table[64]; /* get the rle codes */ - bitstream_init(&bc, src, (src_end - src) * 8); + bitstream_init8(&bc, src, src_end - src); for (i = 0, sz = 0; i < 64 && sz < dst_size; i++) { if (bitstream_bits_left(&bc) < 4) return NULL; @@ -113,7 +113,7 @@ static const unsigned char *seq_decode_op1(SeqVideoContext *seq, return NULL; color_table = src; src += len; - bitstream_init(&bc, src, bits * 8 * 8); + bitstream_init8(&bc, src, bits * 8); src += bits * 8; for (b = 0; b < 8; b++) { for (i = 0; i < 8; i++) @@ -188,7 +188,7 @@ static int seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int if (flags & 2) { if (data_end - data < 128) return AVERROR_INVALIDDATA; - bitstream_init(&bc, data, 128 * 8); + bitstream_init8(&bc, data, 128); data += 128; for (y = 0; y < 128; y += 8) for (x = 0; x < 256; x += 8) { diff --git a/libavcodec/truemotion2.c b/libavcodec/truemotion2.c index 99884be4bbe9b..333451cb7c91c 100644 --- a/libavcodec/truemotion2.c +++ b/libavcodec/truemotion2.c @@ -306,7 +306,7 @@ static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, i pos = bytestream2_tell(&gb); if (skip <= pos) return AVERROR_INVALIDDATA; - bitstream_init(&ctx->bc, buf + pos, (skip - pos) * 8); + bitstream_init8(&ctx->bc, buf + pos, skip - pos); if ((ret = tm2_read_deltas(ctx, stream_id)) < 0) return ret; bytestream2_skip(&gb, ((bitstream_tell(&ctx->bc) + 31) >> 5) << 2); @@ -323,7 +323,7 @@ static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, i pos = bytestream2_tell(&gb); if (skip <= pos) return AVERROR_INVALIDDATA; - bitstream_init(&ctx->bc, buf + pos, (skip - pos) * 8); + bitstream_init8(&ctx->bc, buf + pos, skip - pos); if ((ret = tm2_build_huff_table(ctx, &codes)) < 0) return ret; bytestream2_skip(&gb, ((bitstream_tell(&ctx->bc) + 31) >> 5) << 2); @@ -342,7 +342,7 @@ static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, i pos = bytestream2_tell(&gb); if (skip <= pos) return AVERROR_INVALIDDATA; - bitstream_init(&ctx->bc, buf + pos, (skip - pos) * 8); + bitstream_init8(&ctx->bc, buf + pos, skip - pos); for (i = 0; i < toks; i++) { if (bitstream_bits_left(&ctx->bc) <= 0) { av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of tokens: %i\n", toks); diff --git a/libavcodec/truespeech.c b/libavcodec/truespeech.c index 48e2126ba6473..6b9afaedda296 100644 --- a/libavcodec/truespeech.c +++ b/libavcodec/truespeech.c @@ -82,7 +82,7 @@ static void truespeech_read_frame(TSContext *dec, const uint8_t *input) BitstreamContext bc; dec->bdsp.bswap_buf((uint32_t *) dec->buffer, (const uint32_t *) input, 8); - bitstream_init(&bc, dec->buffer, 32 * 8); + bitstream_init8(&bc, dec->buffer, 32); dec->vector[7] = ts_codebook[7][bitstream_read(&bc, 3)]; dec->vector[6] = ts_codebook[6][bitstream_read(&bc, 3)]; diff --git a/libavcodec/tscc2.c b/libavcodec/tscc2.c index d86428afc6f8a..6081c72c301c8 100644 --- a/libavcodec/tscc2.c +++ b/libavcodec/tscc2.c @@ -195,7 +195,7 @@ static int tscc2_decode_slice(TSCC2Context *c, int mb_y, int i, mb_x, q, ret; int off; - bitstream_init(&c->bc, buf, buf_size * 8); + bitstream_init8(&c->bc, buf, buf_size); for (mb_x = 0; mb_x < c->mb_width; mb_x++) { q = c->slice_quants[mb_x + c->mb_width * mb_y]; diff --git a/libavcodec/tta.c b/libavcodec/tta.c index 7fe11f5830140..db5e094a2ea95 100644 --- a/libavcodec/tta.c +++ b/libavcodec/tta.c @@ -197,7 +197,7 @@ static av_cold int tta_decode_init(AVCodecContext * avctx) if (avctx->extradata_size < 30) return -1; - bitstream_init(&s->bc, avctx->extradata, avctx->extradata_size * 8); + bitstream_init8(&s->bc, avctx->extradata, avctx->extradata_size); if (bitstream_peek(&s->bc, 32) == AV_RL32("TTA1")) { if (avctx->err_recognition & AV_EF_CRCCHECK) { s->crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE); @@ -315,7 +315,7 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - bitstream_init(&s->bc, buf, buf_size * 8); + bitstream_init8(&s->bc, buf, buf_size); /* get output buffer */ frame->nb_samples = framelen; diff --git a/libavcodec/twinvqdec.c b/libavcodec/twinvqdec.c index 6355ad4ed2926..8981d95408961 100644 --- a/libavcodec/twinvqdec.c +++ b/libavcodec/twinvqdec.c @@ -259,7 +259,7 @@ static int twinvq_read_bitstream(AVCodecContext *avctx, TwinVQContext *tctx, BitstreamContext bc; int i, j, k; - bitstream_init(&bc, buf, buf_size * 8); + bitstream_init8(&bc, buf, buf_size); bitstream_skip(&bc, bitstream_read(&bc, 8)); bits->window_type = bitstream_read(&bc, TWINVQ_WINDOW_TYPE_BITS); diff --git a/libavcodec/utvideodec.c b/libavcodec/utvideodec.c index 29de815d4e0cb..1f5b02f560484 100644 --- a/libavcodec/utvideodec.c +++ b/libavcodec/utvideodec.c @@ -147,7 +147,7 @@ static int decode_plane(UtvideoContext *c, int plane_no, c->bdsp.bswap_buf((uint32_t *) c->slice_bits, (uint32_t *) c->slice_bits, (slice_data_end - slice_data_start + 3) >> 2); - bitstream_init(&bc, c->slice_bits, slice_size * 8); + bitstream_init8(&bc, c->slice_bits, slice_size); prev = 0x80; for (j = sstart; j < send; j++) { diff --git a/libavcodec/vble.c b/libavcodec/vble.c index fef10903ddeb1..75db27ff09e28 100644 --- a/libavcodec/vble.c +++ b/libavcodec/vble.c @@ -140,7 +140,7 @@ static int vble_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (version != 1) av_log(avctx, AV_LOG_WARNING, "Unsupported VBLE Version: %d\n", version); - bitstream_init(&bc, src + 4, (avpkt->size - 4) * 8); + bitstream_init8(&bc, src + 4, avpkt->size - 4); /* Unpack */ if (vble_unpack(ctx, &bc) < 0) { diff --git a/libavcodec/webp.c b/libavcodec/webp.c index a6ab52bf83721..4548e5fb3b860 100644 --- a/libavcodec/webp.c +++ b/libavcodec/webp.c @@ -1039,7 +1039,7 @@ static int apply_color_indexing_transform(WebPContext *s) for (y = 0; y < img->frame->height; y++) { p = GET_PIXEL(img->frame, 0, y); memcpy(line, p, img->frame->linesize[0]); - bitstream_init(&bc_g, line, img->frame->linesize[0] * 8); + bitstream_init8(&bc_g, line, img->frame->linesize[0]); bitstream_skip(&bc_g, 16); i = 0; for (x = 0; x < img->frame->width; x++) { @@ -1083,7 +1083,7 @@ static int vp8_lossless_decode_frame(AVCodecContext *avctx, AVFrame *p, avctx->pix_fmt = AV_PIX_FMT_ARGB; } - ret = bitstream_init(&s->bc, data_start, data_size * 8); + ret = bitstream_init8(&s->bc, data_start, data_size); if (ret < 0) return ret; diff --git a/libavcodec/wnv1.c b/libavcodec/wnv1.c index 80d66ae96cbea..e973f7ecc5314 100644 --- a/libavcodec/wnv1.c +++ b/libavcodec/wnv1.c @@ -90,7 +90,7 @@ static int decode_frame(AVCodecContext *avctx, for (i = 8; i < buf_size; i++) rbuf[i] = ff_reverse[buf[i]]; - bitstream_init(&l->bc, rbuf + 8, (buf_size - 8) * 8); + bitstream_init8(&l->bc, rbuf + 8, buf_size - 8); if (buf[2] >> 4 == 6) l->shift = 2; diff --git a/libavcodec/xan.c b/libavcodec/xan.c index 33149e5ff7e32..5bb4f161e446b 100644 --- a/libavcodec/xan.c +++ b/libavcodec/xan.c @@ -129,7 +129,7 @@ static int xan_huffman_decode(unsigned char *dest, int dest_len, if (ptr_len < 0) return AVERROR_INVALIDDATA; - bitstream_init(&bc, ptr, ptr_len * 8); + bitstream_init8(&bc, ptr, ptr_len); while (val != 0x16) { unsigned idx = val - 0x17 + bitstream_read_bit(&bc) * byte; diff --git a/libavcodec/xsubdec.c b/libavcodec/xsubdec.c index a07f94ce7379d..635067c0c8f8d 100644 --- a/libavcodec/xsubdec.c +++ b/libavcodec/xsubdec.c @@ -147,7 +147,7 @@ FF_ENABLE_DEPRECATION_WARNINGS #endif // process RLE-compressed data - bitstream_init(&bc, buf, (buf_end - buf) * 8); + bitstream_init8(&bc, buf, buf_end - buf); bitmap = sub->rects[0]->data[0]; for (y = 0; y < h; y++) { // interlaced: do odd lines diff --git a/libavformat/h261dec.c b/libavformat/h261dec.c index d8a2cecc77263..54202945ca406 100644 --- a/libavformat/h261dec.c +++ b/libavformat/h261dec.c @@ -34,7 +34,7 @@ static int h261_probe(AVProbeData *p) int src_fmt=0; BitstreamContext bc; - bitstream_init(&bc, p->buf, p->buf_size * 8); + bitstream_init8(&bc, p->buf, p->buf_size); for(i=0; ibuf_size*8; i++){ if ((code & 0x01ff0000) || !(code & 0xff00)) { diff --git a/libavformat/mov.c b/libavformat/mov.c index 9afd0202ca981..2810960e878d7 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -2138,7 +2138,7 @@ static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom) return ret; } - bitstream_init(&bc, buf, 8 * num_bytes); + bitstream_init8(&bc, buf, num_bytes); for (i = 0; i < entries && !pb->eof_reached; i++) { sc->sample_sizes[i] = bitstream_read(&bc, field_size); diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 440370e2592ce..840190dbfa906 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -252,7 +252,7 @@ static int mov_write_ac3_tag(AVIOContext *pb, MOVTrack *track) avio_wb32(pb, 11); ffio_wfourcc(pb, "dac3"); - bitstream_init(&bc, track->vos_data + 4, (track->vos_len - 4) * 8); + bitstream_init8(&bc, track->vos_data + 4, track->vos_len - 4); fscod = bitstream_read(&bc, 2); frmsizecod = bitstream_read(&bc, 6); bsid = bitstream_read(&bc, 5); @@ -470,7 +470,7 @@ static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf) if (size <= 0) continue; unescaped_size = vc1_unescape_buffer(start + 4, size, unescaped); - bitstream_init(&bc, unescaped, 8 * unescaped_size); + bitstream_init8(&bc, unescaped, unescaped_size); if (AV_RB32(start) == VC1_CODE_SEQHDR) { int profile = bitstream_read(&bc, 2); if (profile != PROFILE_ADVANCED) { diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 50244041119c5..dc9339fa3ecec 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -742,7 +742,7 @@ static int read_sl_header(PESContext *pes, SLConfigDescr *sl, int padding_flag = 0, padding_bits = 0, inst_bitrate_flag = 0; int dts_flag = -1, cts_flag = -1; int64_t dts = AV_NOPTS_VALUE, cts = AV_NOPTS_VALUE; - bitstream_init(&bc, buf, buf_size * 8); + bitstream_init8(&bc, buf, buf_size); if (sl->use_au_start) au_start_flag = bitstream_read_bit(&bc); diff --git a/libavformat/oggparseflac.c b/libavformat/oggparseflac.c index 90b1495c51be3..0946a3b7cff3a 100644 --- a/libavformat/oggparseflac.c +++ b/libavformat/oggparseflac.c @@ -41,7 +41,7 @@ flac_header (AVFormatContext * s, int idx) if (os->buf[os->pstart] == 0xff) return 0; - bitstream_init(&bc, os->buf + os->pstart, os->psize * 8); + bitstream_init8(&bc, os->buf + os->pstart, os->psize); bitstream_skip(&bc, 1); /* metadata_last */ mdt = bitstream_read(&bc, 7); diff --git a/libavformat/oggparsetheora.c b/libavformat/oggparsetheora.c index da47a0cd899d3..d9992fab9cd8b 100644 --- a/libavformat/oggparsetheora.c +++ b/libavformat/oggparsetheora.c @@ -63,7 +63,7 @@ static int theora_header(AVFormatContext *s, int idx) BitstreamContext bc; AVRational timebase; - bitstream_init(&bc, os->buf + os->pstart, os->psize * 8); + bitstream_init8(&bc, os->buf + os->pstart, os->psize); /* 0x80"theora" */ bitstream_skip(&bc, 7 * 8); diff --git a/libavformat/rdt.c b/libavformat/rdt.c index da5ff59c22a5d..825e4f1355209 100644 --- a/libavformat/rdt.c +++ b/libavformat/rdt.c @@ -262,7 +262,7 @@ ff_rdt_parse_header(const uint8_t *buf, int len, * [2] http://www.wireshark.org/docs/dfref/r/rdt.html and * http://anonsvn.wireshark.org/viewvc/trunk/epan/dissectors/packet-rdt.c */ - bitstream_init(&bc, buf, len << 3); + bitstream_init8(&bc, buf, len); len_included = bitstream_read_bit(&bc); need_reliable = bitstream_read_bit(&bc); set_id = bitstream_read(&bc, 5); diff --git a/libavformat/rtpdec_latm.c b/libavformat/rtpdec_latm.c index bb826269b0b2a..9893aeba9bae2 100644 --- a/libavformat/rtpdec_latm.c +++ b/libavformat/rtpdec_latm.c @@ -103,7 +103,7 @@ static int parse_fmtp_config(AVStream *st, const char *value) if (!config) return AVERROR(ENOMEM); ff_hex_to_data(config, value); - bitstream_init(&bc, config, len * 8); + bitstream_init8(&bc, config, len); audio_mux_version = bitstream_read(&bc, 1); same_time_framing = bitstream_read(&bc, 1); bitstream_skip(&bc, 6); /* num_sub_frames */ diff --git a/libavformat/rtpdec_mpeg4.c b/libavformat/rtpdec_mpeg4.c index b3cd6c94041d3..2a7e54aabc738 100644 --- a/libavformat/rtpdec_mpeg4.c +++ b/libavformat/rtpdec_mpeg4.c @@ -136,7 +136,7 @@ static int rtp_parse_mp4_au(PayloadContext *data, const uint8_t *buf, int len) if (len < data->au_headers_length_bytes) return AVERROR_INVALIDDATA; - bitstream_init(&bctx, buf, data->au_headers_length_bytes * 8); + bitstream_init8(&bctx, buf, data->au_headers_length_bytes); /* XXX: Wrong if optional additional sections are present (cts, dts etc...) */ au_header_size = data->sizelength + data->indexlength; diff --git a/libavformat/rtpdec_qt.c b/libavformat/rtpdec_qt.c index 2c0f8188b6551..e6c586fe500b3 100644 --- a/libavformat/rtpdec_qt.c +++ b/libavformat/rtpdec_qt.c @@ -72,7 +72,7 @@ static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt, * The RTP payload is described in: * http://developer.apple.com/quicktime/icefloe/dispatch026.html */ - bitstream_init(&bc, buf, len << 3); + bitstream_init8(&bc, buf, len); ffio_init_context(&pb, buf, len, 0, NULL, NULL, NULL, NULL); if (len < 4) diff --git a/libavformat/rtpenc_h263_rfc2190.c b/libavformat/rtpenc_h263_rfc2190.c index 750a52bcd861f..3b3479aeb28fc 100644 --- a/libavformat/rtpenc_h263_rfc2190.c +++ b/libavformat/rtpenc_h263_rfc2190.c @@ -112,7 +112,7 @@ void ff_rtp_send_h263_rfc2190(AVFormatContext *s1, const uint8_t *buf, int size, s->timestamp = s->cur_timestamp; - bitstream_init(&bc, buf, size * 8); + bitstream_init8(&bc, buf, size); if (bitstream_read(&bc, 22) == 0x20) { /* Picture Start Code */ info.tr = bitstream_read(&bc, 8); bitstream_skip(&bc, 2); /* PTYPE start, H.261 disambiguation */ From 9127ac5ebc941d5e54828a91e5072c876be8ec42 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 23 Jan 2017 11:57:14 +0100 Subject: [PATCH 0871/3374] configure: Add name parameter to require_pkg_config() helper function This allows distinguishing between the internal variable name for external libraries and the pkg-config package name. Having both names available avoids special-casing outside the helper function when the two identifiers do not match. --- configure | 53 ++++++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/configure b/configure index c2580a3650c2d..376ac148c82de 100755 --- a/configure +++ b/configure @@ -1134,8 +1134,11 @@ require_cpp_condition(){ require_pkg_config(){ log require_pkg_config "$@" + name="$1" + shift pkg_version="$1" pkg="${1%% *}" + test "$name" = "" && name=$pkg check_pkg_config "$@" || die "ERROR: $pkg_version not found" add_cflags $(get_safe "${pkg}_cflags") add_extralibs $(get_safe "${pkg}_extralibs") @@ -4513,7 +4516,7 @@ case "$custom_allocator" in require libjemalloc jemalloc/jemalloc.h malloc -ljemalloc ;; tcmalloc) - require_pkg_config libtcmalloc gperftools/tcmalloc.h tc_malloc + require_pkg_config "" libtcmalloc gperftools/tcmalloc.h tc_malloc malloc_prefix=tc_ ;; esac @@ -4649,41 +4652,41 @@ enabled avisynth && require_header avisynth/avisynth_c.h enabled avxsynth && require avxsynth "avxsynth/avxsynth_c.h dlfcn.h" dlopen -ldl enabled cuda && require cuda cuda.h cuInit -lcuda enabled frei0r && require_header frei0r.h -enabled gnutls && require_pkg_config gnutls gnutls/gnutls.h gnutls_global_init -enabled libbs2b && require_pkg_config libbs2b bs2b.h bs2b_open -enabled libdc1394 && require_pkg_config libdc1394-2 dc1394/dc1394.h dc1394_new +enabled gnutls && require_pkg_config "" gnutls gnutls/gnutls.h gnutls_global_init +enabled libbs2b && require_pkg_config "" libbs2b bs2b.h bs2b_open +enabled libdc1394 && require_pkg_config libdc1394 libdc1394-2 dc1394/dc1394.h dc1394_new enabled libdcadec && require libdcadec libdcadec/dca_context.h dcadec_context_create -ldcadec enabled libfaac && require libfaac "stdint.h faac.h" faacEncGetVersion -lfaac -enabled libfdk_aac && require_pkg_config fdk-aac "fdk-aac/aacenc_lib.h" aacEncOpen -enabled libfontconfig && require_pkg_config fontconfig "fontconfig/fontconfig.h" FcInit -enabled libfreetype && require_pkg_config freetype2 "ft2build.h FT_FREETYPE_H" FT_Init_FreeType +enabled libfdk_aac && require_pkg_config libfdk_aac fdk-aac "fdk-aac/aacenc_lib.h" aacEncOpen +enabled libfontconfig && require_pkg_config libfontconfig fontconfig "fontconfig/fontconfig.h" FcInit +enabled libfreetype && require_pkg_config libfreetype freetype2 "ft2build.h FT_FREETYPE_H" FT_Init_FreeType enabled libgsm && { for gsm_hdr in "gsm.h" "gsm/gsm.h"; do check_lib libgsm "${gsm_hdr}" gsm_create -lgsm && break; done || die "ERROR: libgsm not found"; } -enabled libhdcd && require_pkg_config libhdcd "hdcd/hdcd_simple.h" hdcd_new +enabled libhdcd && require_pkg_config "" libhdcd "hdcd/hdcd_simple.h" hdcd_new enabled libilbc && require libilbc ilbc.h WebRtcIlbcfix_InitDecode -lilbc -enabled libkvazaar && require_pkg_config "kvazaar >= 0.8.1" kvazaar.h kvz_api_get -enabled libmfx && require_pkg_config libmfx "mfx/mfxvideo.h" MFXInit +enabled libkvazaar && require_pkg_config libkvazaar "kvazaar >= 0.8.1" kvazaar.h kvz_api_get +enabled libmfx && require_pkg_config "" libmfx "mfx/mfxvideo.h" MFXInit enabled libmp3lame && require "libmp3lame >= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame enabled libnpp && require libnpp npp.h nppGetLibVersion -lnppi -lnppc enabled libopencore_amrnb && require libopencore_amrnb opencore-amrnb/interf_dec.h Decoder_Interface_init -lopencore-amrnb enabled libopencore_amrwb && require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb -enabled libopencv && require_pkg_config opencv opencv/cv.h cvCreateImageHeader -enabled libopenh264 && require_pkg_config openh264 wels/codec_api.h WelsGetCodecVersion +enabled libopencv && require_pkg_config libopencv opencv opencv/cv.h cvCreateImageHeader +enabled libopenh264 && require_pkg_config libopenh264 openh264 wels/codec_api.h WelsGetCodecVersion enabled libopenjpeg && { check_lib libopenjpeg openjpeg.h opj_version -lopenjpeg -DOPJ_STATIC || - require_pkg_config libopenjpeg1 openjpeg.h opj_version -DOPJ_STATIC; } -enabled libopus && require_pkg_config opus opus_multistream.h opus_multistream_decoder_create -enabled libpulse && require_pkg_config libpulse-simple pulse/simple.h pa_simple_new -enabled librtmp && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket -enabled libschroedinger && require_pkg_config schroedinger-1.0 schroedinger/schro.h schro_init + require_pkg_config libopenjpeg libopenjpeg1 openjpeg.h opj_version -DOPJ_STATIC; } +enabled libopus && require_pkg_config libopus opus opus_multistream.h opus_multistream_decoder_create +enabled libpulse && require_pkg_config libpulse libpulse-simple pulse/simple.h pa_simple_new +enabled librtmp && require_pkg_config "" librtmp librtmp/rtmp.h RTMP_Socket +enabled libschroedinger && require_pkg_config libschroedinger schroedinger-1.0 schroedinger/schro.h schro_init enabled libsnappy && require libsnappy snappy-c.h snappy_compress -lsnappy -enabled libspeex && require_pkg_config speex speex/speex.h speex_decoder_init -lspeex +enabled libspeex && require_pkg_config libspeex speex speex/speex.h speex_decoder_init -lspeex enabled libtheora && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg enabled libtwolame && require libtwolame twolame.h twolame_init -ltwolame enabled libvo_aacenc && require libvo_aacenc vo-aacenc/voAAC.h voGetAACEncAPI -lvo-aacenc enabled libvo_amrwbenc && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc enabled libvorbis && require libvorbis vorbis/vorbisenc.h vorbis_info_init -lvorbisenc -lvorbis -logg -enabled libvpx && require_pkg_config "vpx >= 1.3.0" vpx/vpx_codec.h vpx_codec_version && { +enabled libvpx && require_pkg_config libvpx "vpx >= 1.3.0" vpx/vpx_codec.h vpx_codec_version && { enabled libvpx_vp8_decoder && { check_pkg_config vpx "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_vp8_dx || disable libvpx_vp8_decoder; @@ -4705,12 +4708,12 @@ enabled libvpx && require_pkg_config "vpx >= 1.3.0" vpx/vpx_codec.h v fi } enabled libwavpack && require libwavpack wavpack/wavpack.h WavpackOpenFileOutput -lwavpack -enabled libwebp && require_pkg_config libwebp webp/encode.h WebPGetEncoderVersion -enabled libx264 && require_pkg_config x264 "stdint.h x264.h" x264_encoder_encode && +enabled libwebp && require_pkg_config "" libwebp webp/encode.h WebPGetEncoderVersion +enabled libx264 && require_pkg_config libx264 x264 "stdint.h x264.h" x264_encoder_encode && require_cpp_condition x264.h "X264_BUILD >= 118" && { check_cpp_condition x264.h "X264_MPEG2" && enable libx262; } -enabled libx265 && require_pkg_config x265 x265.h x265_api_get && +enabled libx265 && require_pkg_config libx265 x265 x265.h x265_api_get && require_cpp_condition x265.h "X265_BUILD >= 57" enabled libxavs && require libxavs "stdint.h xavs.h" xavs_encoder_encode -lxavs enabled libxvid && require libxvid xvid.h xvid_global -lxvidcore @@ -4790,11 +4793,11 @@ if enabled libcdio; then fi if enabled libxcb; then - require_pkg_config xcb-shape xcb/shape.h xcb_shape_rectangles + require_pkg_config libxcb xcb-shape xcb/shape.h xcb_shape_rectangles disabled libxcb_shm || - require_pkg_config xcb-shm xcb/shm.h xcb_shm_attach + require_pkg_config libxcb_shm xcb-shm xcb/shm.h xcb_shm_attach disabled libxcb_xfixes || - require_pkg_config xcb-xfixes xcb/xfixes.h xcb_xfixes_get_cursor_image + require_pkg_config libxcb_xfixes xcb-xfixes xcb/xfixes.h xcb_xfixes_get_cursor_image fi enabled dxva2 && From dad7a9c7c0ae8ebc56f2e3a24e6fa4da5c2cd491 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 20 Jan 2017 17:17:16 +0100 Subject: [PATCH 0872/3374] configure: Rework dependency handling for conflicting components This makes the feature more visible and obvious. --- configure | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/configure b/configure index 376ac148c82de..7d39acab377a7 100755 --- a/configure +++ b/configure @@ -620,19 +620,21 @@ do_check_deps(){ eval dep_all="\$${cfg}_deps" eval dep_any="\$${cfg}_deps_any" + eval dep_con="\$${cfg}_conflict" eval dep_sel="\$${cfg}_select" eval dep_sgs="\$${cfg}_suggest" eval dep_ifa="\$${cfg}_if" eval dep_ifn="\$${cfg}_if_any" - pushvar cfg dep_all dep_any dep_sel dep_sgs dep_ifa dep_ifn - do_check_deps $dep_all $dep_any $dep_sel $dep_sgs $dep_ifa $dep_ifn - popvar cfg dep_all dep_any dep_sel dep_sgs dep_ifa dep_ifn + pushvar cfg dep_all dep_any dep_con dep_sel dep_sgs dep_ifa dep_ifn + check_deps $dep_all $dep_any $dep_con $dep_sel $dep_sgs $dep_ifa $dep_ifn + popvar cfg dep_all dep_any dep_con dep_sel dep_sgs dep_ifa dep_ifn [ -n "$dep_ifa" ] && { enabled_all $dep_ifa && enable_weak $cfg; } [ -n "$dep_ifn" ] && { enabled_any $dep_ifn && enable_weak $cfg; } enabled_all $dep_all || disable $cfg enabled_any $dep_any || disable $cfg + disabled_all $dep_con || disable $cfg disabled_any $dep_sel && disable $cfg if enabled $cfg; then @@ -1922,7 +1924,8 @@ simd_align_32_if_any="avx" # system capabilities symver_if_any="symver_asm_label symver_gnu_asm" -valgrind_backtrace_deps="!optimizations valgrind_valgrind_h" +valgrind_backtrace_conflict="optimizations" +valgrind_backtrace_deps="valgrind_valgrind_h" # threading support atomics_gcc_if="sync_val_compare_and_swap" @@ -2422,10 +2425,10 @@ xcbgrab_indev_deps="libxcb" xcbgrab_indev_suggest="libxcb_shm libxcb_xfixes" # protocols -ffrtmpcrypt_protocol_deps="!librtmp_protocol" +ffrtmpcrypt_protocol_conflict="librtmp_protocol" ffrtmpcrypt_protocol_deps_any="gmp openssl" ffrtmpcrypt_protocol_select="tcp_protocol" -ffrtmphttp_protocol_deps="!librtmp_protocol" +ffrtmphttp_protocol_conflict="librtmp_protocol" ffrtmphttp_protocol_select="http_protocol" gopher_protocol_select="network" http_protocol_select="tcp_protocol" @@ -2439,10 +2442,10 @@ librtmpt_protocol_deps="librtmp" librtmpte_protocol_deps="librtmp" mmsh_protocol_select="http_protocol" mmst_protocol_select="network" -rtmp_protocol_deps="!librtmp_protocol" +rtmp_protocol_conflict="librtmp_protocol" rtmp_protocol_select="tcp_protocol" rtmpe_protocol_select="ffrtmpcrypt_protocol" -rtmps_protocol_deps="!librtmp_protocol" +rtmps_protocol_conflict="librtmp_protocol" rtmps_protocol_select="tls_protocol" rtmpt_protocol_select="ffrtmphttp_protocol" rtmpte_protocol_select="ffrtmpcrypt_protocol ffrtmphttp_protocol" @@ -2454,7 +2457,8 @@ srtp_protocol_select="rtp_protocol srtp" tcp_protocol_select="network" tls_gnutls_protocol_deps="gnutls" tls_gnutls_protocol_select="tcp_protocol" -tls_openssl_protocol_deps="openssl !tls_gnutls_protocol" +tls_openssl_protocol_conflict="tls_gnutls_protocol" +tls_openssl_protocol_deps="openssl" tls_openssl_protocol_select="tcp_protocol" tls_protocol_deps_any="tls_gnutls_protocol tls_openssl_protocol" udp_protocol_select="network" From 57ec83e4246b21c2f0c068b9151d806737d4497f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 7 Feb 2017 00:25:19 +0200 Subject: [PATCH 0873/3374] omx: Use the EOS flag to handle flushing at the end MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids having to count the number of frames sent to the codec and the number of output packets received; instead just wait until the encoder returns a buffer with the EOS flag set. Signed-off-by: Martin Storsjö --- libavcodec/omx.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/libavcodec/omx.c b/libavcodec/omx.c index 05c874323c1df..f43e92ae88c15 100644 --- a/libavcodec/omx.c +++ b/libavcodec/omx.c @@ -220,7 +220,7 @@ typedef struct OMXCodecContext { int mutex_cond_inited; - int num_in_frames, num_out_frames; + int eos_sent, got_eos; uint8_t *output_buf; int output_buf_size; @@ -791,17 +791,35 @@ static int omx_encode_frame(AVCodecContext *avctx, AVPacket *pkt, av_log(avctx, AV_LOG_ERROR, "OMX_EmptyThisBuffer failed: %x\n", err); return AVERROR_UNKNOWN; } - s->num_in_frames++; + } else if (!s->eos_sent) { + buffer = get_buffer(&s->input_mutex, &s->input_cond, + &s->num_free_in_buffers, s->free_in_buffers, 1); + + buffer->nFilledLen = 0; + buffer->nFlags = OMX_BUFFERFLAG_EOS; + buffer->pAppPrivate = buffer->pOutputPortPrivate = NULL; + err = OMX_EmptyThisBuffer(s->handle, buffer); + if (err != OMX_ErrorNone) { + append_buffer(&s->input_mutex, &s->input_cond, &s->num_free_in_buffers, s->free_in_buffers, buffer); + av_log(avctx, AV_LOG_ERROR, "OMX_EmptyThisBuffer failed: %x\n", err); + return AVERROR_UNKNOWN; + } + s->eos_sent = 1; } - while (!*got_packet && ret == 0) { - // Only wait for output if flushing and not all frames have been output + while (!*got_packet && ret == 0 && !s->got_eos) { + // If not flushing, just poll the queue if there's finished packets. + // If flushing, do a blocking wait until we either get a completed + // packet, or get EOS. buffer = get_buffer(&s->output_mutex, &s->output_cond, &s->num_done_out_buffers, s->done_out_buffers, - !frame && s->num_out_frames < s->num_in_frames); + !frame); if (!buffer) break; + if (buffer->nFlags & OMX_BUFFERFLAG_EOS) + s->got_eos = 1; + if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG && avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) { if ((ret = av_reallocp(&avctx->extradata, avctx->extradata_size + buffer->nFilledLen + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) { avctx->extradata_size = 0; @@ -811,8 +829,6 @@ static int omx_encode_frame(AVCodecContext *avctx, AVPacket *pkt, avctx->extradata_size += buffer->nFilledLen; memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); } else { - if (buffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) - s->num_out_frames++; if (!(buffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) || !pkt->data) { // If the output packet isn't preallocated, just concatenate everything in our // own buffer From c546147db07d16a76c2fb698d2e8a3057f393475 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 8 Feb 2017 18:06:34 +0100 Subject: [PATCH 0874/3374] configure: Correctly recurse in do_check_deps() Fixes all sorts of configuration problems introducec by dad7a9c7c0ae on non-Linux or non-vanilla configs. Also removes a line made redundant in that commit. --- configure | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/configure b/configure index 7d39acab377a7..9ebc3bf8948fb 100755 --- a/configure +++ b/configure @@ -612,7 +612,6 @@ is_in(){ do_check_deps(){ for cfg; do - cfg="${cfg#!}" enabled ${cfg}_checking && die "Circular dependency for $cfg." disabled ${cfg}_checking && continue enable ${cfg}_checking @@ -627,7 +626,7 @@ do_check_deps(){ eval dep_ifn="\$${cfg}_if_any" pushvar cfg dep_all dep_any dep_con dep_sel dep_sgs dep_ifa dep_ifn - check_deps $dep_all $dep_any $dep_con $dep_sel $dep_sgs $dep_ifa $dep_ifn + do_check_deps $dep_all $dep_any $dep_con $dep_sel $dep_sgs $dep_ifa $dep_ifn popvar cfg dep_all dep_any dep_con dep_sel dep_sgs dep_ifa dep_ifn [ -n "$dep_ifa" ] && { enabled_all $dep_ifa && enable_weak $cfg; } From 0331c3f5e8cb6e6b53fab7893e91d1be1bfa979c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 23 Nov 2016 10:56:12 +0200 Subject: [PATCH 0875/3374] arm: vp9itxfm: Make the larger core transforms standalone functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. This reduces the code size of libavcodec/arm/vp9itxfm_neon.o from 15324 to 12388 bytes. This gives a small slowdown of a couple tens of cycles, up to around 150 cycles for the full case of the largest transform, but makes it more feasible to add more optimized versions of these transforms. Before: Cortex A7 A8 A9 A53 vp9_inv_dct_dct_16x16_sub4_add_neon: 2063.4 1516.0 1719.5 1245.1 vp9_inv_dct_dct_16x16_sub16_add_neon: 3279.3 2454.5 2525.2 1982.3 vp9_inv_dct_dct_32x32_sub4_add_neon: 10750.0 7955.4 8525.6 6754.2 vp9_inv_dct_dct_32x32_sub32_add_neon: 18574.0 17108.4 14216.7 12010.2 After: vp9_inv_dct_dct_16x16_sub4_add_neon: 2060.8 1608.5 1735.7 1262.0 vp9_inv_dct_dct_16x16_sub16_add_neon: 3211.2 2443.5 2546.1 1999.5 vp9_inv_dct_dct_32x32_sub4_add_neon: 10682.0 8043.8 8581.3 6810.1 vp9_inv_dct_dct_32x32_sub32_add_neon: 18522.4 17277.4 14286.7 12087.9 Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 43 ++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index 49b993ffe3552..fd53a20a7368e 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -534,7 +534,7 @@ function idct16x16_dc_add_neon endfunc .ltorg -.macro idct16 +function idct16 mbutterfly0 d16, d24, d16, d24, d4, d6, q2, q3 @ d16 = t0a, d24 = t1a mbutterfly d20, d28, d0[1], d0[2], q2, q3 @ d20 = t2a, d28 = t3a mbutterfly d18, d30, d0[3], d1[0], q2, q3 @ d18 = t4a, d30 = t7a @@ -580,9 +580,10 @@ endfunc vmov d4, d21 @ d4 = t10a butterfly d20, d27, d6, d27 @ d20 = out[4], d27 = out[11] butterfly d21, d26, d26, d4 @ d21 = out[5], d26 = out[10] -.endm + bx lr +endfunc -.macro iadst16 +function iadst16 movrel r12, iadst16_coeffs vld1.16 {q0-q1}, [r12,:128] @@ -653,7 +654,8 @@ endfunc vmov d16, d2 vmov d30, d4 -.endm + bx lr +endfunc .macro itxfm16_1d_funcs txfm @ Read a vertical 4x16 slice out of a 16x16 matrix, do a transform on it, @@ -662,6 +664,8 @@ endfunc @ r1 = slice offset @ r2 = src function \txfm\()16_1d_4x16_pass1_neon + push {lr} + mov r12, #32 vmov.s16 q2, #0 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 @@ -669,7 +673,7 @@ function \txfm\()16_1d_4x16_pass1_neon vst1.16 {d4}, [r2,:64], r12 .endr - \txfm\()16 + bl \txfm\()16 @ Do four 4x4 transposes. Originally, d16-d31 contain the @ 16 rows. Afterwards, d16-d19, d20-d23, d24-d27, d28-d31 @@ -682,7 +686,7 @@ function \txfm\()16_1d_4x16_pass1_neon .irp i, 16, 20, 24, 28, 17, 21, 25, 29, 18, 22, 26, 30, 19, 23, 27, 31 vst1.16 {d\i}, [r0,:64]! .endr - bx lr + pop {pc} 1: @ Special case: For the last input column (r1 == 12), @ which would be stored as the last row in the temp buffer, @@ -709,7 +713,7 @@ function \txfm\()16_1d_4x16_pass1_neon vmov d29, d17 vmov d30, d18 vmov d31, d19 - bx lr + pop {pc} endfunc @ Read a vertical 4x16 slice out of a 16x16 matrix, do a transform on it, @@ -719,6 +723,7 @@ endfunc @ r2 = src (temp buffer) @ r3 = slice offset function \txfm\()16_1d_4x16_pass2_neon + push {lr} mov r12, #32 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 vld1.16 {d\i}, [r2,:64], r12 @@ -732,7 +737,7 @@ function \txfm\()16_1d_4x16_pass2_neon add r3, r0, r1 lsl r1, r1, #1 - \txfm\()16 + bl \txfm\()16 .macro load_add_store coef0, coef1, coef2, coef3 vrshr.s16 \coef0, \coef0, #6 @@ -773,7 +778,7 @@ function \txfm\()16_1d_4x16_pass2_neon load_add_store q12, q13, q14, q15 .purgem load_add_store - bx lr + pop {pc} endfunc .endm @@ -908,7 +913,7 @@ function idct32x32_dc_add_neon bx lr endfunc -.macro idct32_odd +function idct32_odd movrel r12, idct_coeffs add r12, r12, #32 vld1.16 {q0-q1}, [r12,:128] @@ -967,7 +972,8 @@ endfunc mbutterfly0 d26, d21, d26, d21, d4, d6, q2, q3 @ d26 = t26a, d21 = t21a mbutterfly0 d25, d22, d25, d22, d4, d6, q2, q3 @ d25 = t25, d22 = t22 mbutterfly0 d24, d23, d24, d23, d4, d6, q2, q3 @ d24 = t24a, d23 = t23a -.endm + bx lr +endfunc @ Do an 32-point IDCT of a 4x32 slice out of a 32x32 matrix. @ We don't have register space to do a single pass IDCT of 4x32 though, @@ -979,6 +985,8 @@ endfunc @ r1 = unused @ r2 = src function idct32_1d_4x32_pass1_neon + push {lr} + movrel r12, idct_coeffs vld1.16 {q0-q1}, [r12,:128] @@ -992,7 +1000,7 @@ function idct32_1d_4x32_pass1_neon vst1.16 {d4}, [r2,:64], r12 .endr - idct16 + bl idct16 @ Do four 4x4 transposes. Originally, d16-d31 contain the @ 16 rows. Afterwards, d16-d19, d20-d23, d24-d27, d28-d31 @@ -1028,7 +1036,7 @@ function idct32_1d_4x32_pass1_neon vst1.16 {d4}, [r2,:64], r12 .endr - idct32_odd + bl idct32_odd transpose16_q_4x_4x4 q15, q14, q13, q12, q11, q10, q9, q8, d31, d30, d29, d28, d27, d26, d25, d24, d23, d22, d21, d20, d19, d18, d17, d16 @@ -1054,7 +1062,7 @@ function idct32_1d_4x32_pass1_neon store_rev 29, 25, 21, 17 store_rev 28, 24, 20, 16 .purgem store_rev - bx lr + pop {pc} endfunc .ltorg @@ -1065,6 +1073,7 @@ endfunc @ r1 = dst stride @ r2 = src (temp buffer) function idct32_1d_4x32_pass2_neon + push {lr} movrel r12, idct_coeffs vld1.16 {q0-q1}, [r12,:128] @@ -1075,7 +1084,7 @@ function idct32_1d_4x32_pass2_neon .endr sub r2, r2, r12, lsl #4 - idct16 + bl idct16 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vst1.16 {d\i}, [r2,:64], r12 @@ -1091,7 +1100,7 @@ function idct32_1d_4x32_pass2_neon sub r2, r2, r12, lsl #4 sub r2, r2, #64 - idct32_odd + bl idct32_odd mov r12, #128 .macro load_acc_store a, b, c, d, neg=0 @@ -1139,7 +1148,7 @@ function idct32_1d_4x32_pass2_neon load_acc_store 24, 25, 26, 27, 1 load_acc_store 28, 29, 30, 31, 1 .purgem load_acc_store - bx lr + pop {pc} endfunc const min_eob_idct_idct_32, align=4 From 115476018d2c97df7e9b4445fe8f6cc7420ab91f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 23 Nov 2016 14:03:05 +0200 Subject: [PATCH 0876/3374] aarch64: vp9itxfm: Make the larger core transforms standalone functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. This reduces the code size of libavcodec/aarch64/vp9itxfm_neon.o from 19496 to 14740 bytes. This gives a small slowdown of a couple of tens of cycles, but makes it more feasible to add more optimized versions of these transforms. Before: vp9_inv_dct_dct_16x16_sub4_add_neon: 1036.7 vp9_inv_dct_dct_16x16_sub16_add_neon: 1372.2 vp9_inv_dct_dct_32x32_sub4_add_neon: 5180.0 vp9_inv_dct_dct_32x32_sub32_add_neon: 8095.7 After: vp9_inv_dct_dct_16x16_sub4_add_neon: 1051.0 vp9_inv_dct_dct_16x16_sub16_add_neon: 1390.1 vp9_inv_dct_dct_32x32_sub4_add_neon: 5199.9 vp9_inv_dct_dct_32x32_sub32_add_neon: 8125.8 Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 42 ++++++++++++++++++------------ 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index c14c5f9ded550..729860ca1f799 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -463,7 +463,7 @@ function idct16x16_dc_add_neon ret endfunc -.macro idct16 +function idct16 dmbutterfly0 v16, v24, v16, v24, v2, v3, v4, v5, v6, v7 // v16 = t0a, v24 = t1a dmbutterfly v20, v28, v0.h[1], v0.h[2], v2, v3, v4, v5 // v20 = t2a, v28 = t3a dmbutterfly v18, v30, v0.h[3], v0.h[4], v2, v3, v4, v5 // v18 = t4a, v30 = t7a @@ -506,9 +506,10 @@ endfunc butterfly_8h v19, v28, v5, v28 // v19 = out[3], v28 = out[12] butterfly_8h v20, v27, v6, v27 // v20 = out[4], v27 = out[11] butterfly_8h v21, v26, v26, v3 // v21 = out[5], v26 = out[10] -.endm + ret +endfunc -.macro iadst16 +function iadst16 ld1 {v0.8h,v1.8h}, [x11] dmbutterfly_l v6, v7, v4, v5, v31, v16, v0.h[1], v0.h[0] // v6,v7 = t1, v4,v5 = t0 @@ -577,7 +578,8 @@ endfunc mov v16.16b, v2.16b mov v30.16b, v4.16b -.endm + ret +endfunc // Helper macros; we can't use these expressions directly within // e.g. .irp due to the extra concatenation \(). Therefore wrap @@ -604,12 +606,14 @@ endfunc // x9 = input stride .macro itxfm16_1d_funcs txfm function \txfm\()16_1d_8x16_pass1_neon + mov x14, x30 + movi v2.8h, #0 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 load_clear \i, x2, x9 .endr - \txfm\()16 + bl \txfm\()16 // Do two 8x8 transposes. Originally, v16-v31 contain the // 16 rows. Afterwards, v16-v23 and v24-v31 contain the two @@ -623,7 +627,7 @@ function \txfm\()16_1d_8x16_pass1_neon .irp i, 16, 24, 17, 25, 18, 26, 19, 27, 20, 28, 21, 29, 22, 30, 23, 31 store \i, x0, #16 .endr - ret + br x14 1: // Special case: For the last input column (x1 == 8), // which would be stored as the last row in the temp buffer, @@ -642,7 +646,7 @@ function \txfm\()16_1d_8x16_pass1_neon mov v29.16b, v21.16b mov v30.16b, v22.16b mov v31.16b, v23.16b - ret + br x14 endfunc // Read a vertical 8x16 slice out of a 16x16 matrix, do a transform on it, @@ -653,6 +657,7 @@ endfunc // x3 = slice offset // x9 = temp buffer stride function \txfm\()16_1d_8x16_pass2_neon + mov x14, x30 .irp i, 16, 17, 18, 19, 20, 21, 22, 23 load \i, x2, x9 .endr @@ -664,7 +669,7 @@ function \txfm\()16_1d_8x16_pass2_neon add x3, x0, x1 lsl x1, x1, #1 - \txfm\()16 + bl \txfm\()16 .macro load_add_store coef0, coef1, coef2, coef3, coef4, coef5, coef6, coef7, tmp1, tmp2 srshr \coef0, \coef0, #6 @@ -714,7 +719,7 @@ function \txfm\()16_1d_8x16_pass2_neon load_add_store v24.8h, v25.8h, v26.8h, v27.8h, v28.8h, v29.8h, v30.8h, v31.8h, v16.8b, v17.8b .purgem load_add_store - ret + br x14 endfunc .endm @@ -843,7 +848,7 @@ function idct32x32_dc_add_neon ret endfunc -.macro idct32_odd +function idct32_odd ld1 {v0.8h,v1.8h}, [x11] dmbutterfly v16, v31, v0.h[0], v0.h[1], v4, v5, v6, v7 // v16 = t16a, v31 = t31a @@ -898,7 +903,8 @@ endfunc dmbutterfly0 v26, v21, v26, v21, v2, v3, v4, v5, v6, v7 // v26 = t26a, v21 = t21a dmbutterfly0 v25, v22, v25, v22, v2, v3, v4, v5, v6, v7 // v25 = t25, v22 = t22 dmbutterfly0 v24, v23, v24, v23, v2, v3, v4, v5, v6, v7 // v24 = t24a, v23 = t23a -.endm + ret +endfunc // Do an 32-point IDCT of a 8x32 slice out of a 32x32 matrix. // The 32-point IDCT can be decomposed into two 16-point IDCTs; @@ -912,6 +918,7 @@ endfunc // x10 = idct_coeffs // x11 = idct_coeffs + 32 function idct32_1d_8x32_pass1_neon + mov x14, x30 ld1 {v0.8h,v1.8h}, [x10] movi v4.8h, #0 @@ -922,7 +929,7 @@ function idct32_1d_8x32_pass1_neon st1 {v4.8h}, [x2], x9 .endr - idct16 + bl idct16 // Do two 8x8 transposes. Originally, v16-v31 contain the // 16 rows. Afterwards, v16-v23 and v24-v31 contain the @@ -967,7 +974,7 @@ function idct32_1d_8x32_pass1_neon st1 {v4.8h}, [x2], x9 .endr - idct32_odd + bl idct32_odd transpose_8x8H v31, v30, v29, v28, v27, v26, v25, v24, v2, v3 transpose_8x8H v23, v22, v21, v20, v19, v18, v17, v16, v2, v3 @@ -1003,7 +1010,7 @@ function idct32_1d_8x32_pass1_neon store_rev v25.8h, v17.8h store_rev v24.8h, v16.8h .purgem store_rev - ret + br x14 endfunc // This is mostly the same as 8x32_pass1, but without the transpose, @@ -1017,6 +1024,7 @@ endfunc // x10 = idct_coeffs // x11 = idct_coeffs + 32 function idct32_1d_8x32_pass2_neon + mov x14, x30 ld1 {v0.8h,v1.8h}, [x10] // v16 = IN(0), v17 = IN(2) ... v31 = IN(30) @@ -1025,7 +1033,7 @@ function idct32_1d_8x32_pass2_neon .endr sub x2, x2, x9, lsl #4 - idct16 + bl idct16 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 st1 {v\i\().8h}, [x2], x9 @@ -1041,7 +1049,7 @@ function idct32_1d_8x32_pass2_neon sub x2, x2, x9, lsl #4 sub x2, x2, #64 - idct32_odd + bl idct32_odd .macro load_acc_store a, b, c, d, neg=0 .if \neg == 0 @@ -1095,7 +1103,7 @@ function idct32_1d_8x32_pass2_neon load_acc_store v24.8h, v25.8h, v26.8h, v27.8h, 1 load_acc_store v28.8h, v29.8h, v30.8h, v31.8h, 1 .purgem load_acc_store - ret + br x14 endfunc const min_eob_idct_idct_32, align=4 From 47b3c2c18d1897f3c753ba0cec4b2d7aa24526af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 5 Feb 2017 22:55:20 +0200 Subject: [PATCH 0877/3374] arm: vp9itxfm: Move the load_add_store macro out from the itxfm16 pass2 function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows reusing the macro for a separate implementation of the pass2 function. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 72 +++++++++++++++++----------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index fd53a20a7368e..b3188bc7118d5 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -657,6 +657,42 @@ function iadst16 bx lr endfunc +.macro load_add_store coef0, coef1, coef2, coef3 + vrshr.s16 \coef0, \coef0, #6 + vrshr.s16 \coef1, \coef1, #6 + + vld1.32 {d4[]}, [r0,:32], r1 + vld1.32 {d4[1]}, [r3,:32], r1 + vrshr.s16 \coef2, \coef2, #6 + vrshr.s16 \coef3, \coef3, #6 + vld1.32 {d5[]}, [r0,:32], r1 + vld1.32 {d5[1]}, [r3,:32], r1 + vaddw.u8 \coef0, \coef0, d4 + vld1.32 {d6[]}, [r0,:32], r1 + vld1.32 {d6[1]}, [r3,:32], r1 + vaddw.u8 \coef1, \coef1, d5 + vld1.32 {d7[]}, [r0,:32], r1 + vld1.32 {d7[1]}, [r3,:32], r1 + + vqmovun.s16 d4, \coef0 + vqmovun.s16 d5, \coef1 + sub r0, r0, r1, lsl #2 + sub r3, r3, r1, lsl #2 + vaddw.u8 \coef2, \coef2, d6 + vaddw.u8 \coef3, \coef3, d7 + vst1.32 {d4[0]}, [r0,:32], r1 + vst1.32 {d4[1]}, [r3,:32], r1 + vqmovun.s16 d6, \coef2 + vst1.32 {d5[0]}, [r0,:32], r1 + vst1.32 {d5[1]}, [r3,:32], r1 + vqmovun.s16 d7, \coef3 + + vst1.32 {d6[0]}, [r0,:32], r1 + vst1.32 {d6[1]}, [r3,:32], r1 + vst1.32 {d7[0]}, [r0,:32], r1 + vst1.32 {d7[1]}, [r3,:32], r1 +.endm + .macro itxfm16_1d_funcs txfm @ Read a vertical 4x16 slice out of a 16x16 matrix, do a transform on it, @ transpose into a horizontal 16x4 slice and store. @@ -739,44 +775,8 @@ function \txfm\()16_1d_4x16_pass2_neon lsl r1, r1, #1 bl \txfm\()16 -.macro load_add_store coef0, coef1, coef2, coef3 - vrshr.s16 \coef0, \coef0, #6 - vrshr.s16 \coef1, \coef1, #6 - - vld1.32 {d4[]}, [r0,:32], r1 - vld1.32 {d4[1]}, [r3,:32], r1 - vrshr.s16 \coef2, \coef2, #6 - vrshr.s16 \coef3, \coef3, #6 - vld1.32 {d5[]}, [r0,:32], r1 - vld1.32 {d5[1]}, [r3,:32], r1 - vaddw.u8 \coef0, \coef0, d4 - vld1.32 {d6[]}, [r0,:32], r1 - vld1.32 {d6[1]}, [r3,:32], r1 - vaddw.u8 \coef1, \coef1, d5 - vld1.32 {d7[]}, [r0,:32], r1 - vld1.32 {d7[1]}, [r3,:32], r1 - - vqmovun.s16 d4, \coef0 - vqmovun.s16 d5, \coef1 - sub r0, r0, r1, lsl #2 - sub r3, r3, r1, lsl #2 - vaddw.u8 \coef2, \coef2, d6 - vaddw.u8 \coef3, \coef3, d7 - vst1.32 {d4[0]}, [r0,:32], r1 - vst1.32 {d4[1]}, [r3,:32], r1 - vqmovun.s16 d6, \coef2 - vst1.32 {d5[0]}, [r0,:32], r1 - vst1.32 {d5[1]}, [r3,:32], r1 - vqmovun.s16 d7, \coef3 - - vst1.32 {d6[0]}, [r0,:32], r1 - vst1.32 {d6[1]}, [r3,:32], r1 - vst1.32 {d7[0]}, [r0,:32], r1 - vst1.32 {d7[1]}, [r3,:32], r1 -.endm load_add_store q8, q9, q10, q11 load_add_store q12, q13, q14, q15 -.purgem load_add_store pop {pc} endfunc From 79d332ebbde8c0a3e9da094dcfd10abd33ba7378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 5 Feb 2017 22:53:55 +0200 Subject: [PATCH 0878/3374] aarch64: vp9itxfm: Move the load_add_store macro out from the itxfm16 pass2 function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows reusing the macro for a separate implementation of the pass2 function. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 90 +++++++++++++++--------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index 729860ca1f799..b6cadfb66bd1f 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -598,6 +598,51 @@ endfunc st1 {v2.8h}, [\src], \inc .endm +.macro load_add_store coef0, coef1, coef2, coef3, coef4, coef5, coef6, coef7, tmp1, tmp2 + srshr \coef0, \coef0, #6 + ld1 {v2.8b}, [x0], x1 + srshr \coef1, \coef1, #6 + ld1 {v3.8b}, [x3], x1 + srshr \coef2, \coef2, #6 + ld1 {v4.8b}, [x0], x1 + srshr \coef3, \coef3, #6 + uaddw \coef0, \coef0, v2.8b + ld1 {v5.8b}, [x3], x1 + uaddw \coef1, \coef1, v3.8b + srshr \coef4, \coef4, #6 + ld1 {v6.8b}, [x0], x1 + srshr \coef5, \coef5, #6 + ld1 {v7.8b}, [x3], x1 + sqxtun v2.8b, \coef0 + srshr \coef6, \coef6, #6 + sqxtun v3.8b, \coef1 + srshr \coef7, \coef7, #6 + uaddw \coef2, \coef2, v4.8b + ld1 {\tmp1}, [x0], x1 + uaddw \coef3, \coef3, v5.8b + ld1 {\tmp2}, [x3], x1 + sqxtun v4.8b, \coef2 + sub x0, x0, x1, lsl #2 + sub x3, x3, x1, lsl #2 + sqxtun v5.8b, \coef3 + uaddw \coef4, \coef4, v6.8b + st1 {v2.8b}, [x0], x1 + uaddw \coef5, \coef5, v7.8b + st1 {v3.8b}, [x3], x1 + sqxtun v6.8b, \coef4 + st1 {v4.8b}, [x0], x1 + sqxtun v7.8b, \coef5 + st1 {v5.8b}, [x3], x1 + uaddw \coef6, \coef6, \tmp1 + st1 {v6.8b}, [x0], x1 + uaddw \coef7, \coef7, \tmp2 + st1 {v7.8b}, [x3], x1 + sqxtun \tmp1, \coef6 + sqxtun \tmp2, \coef7 + st1 {\tmp1}, [x0], x1 + st1 {\tmp2}, [x3], x1 +.endm + // Read a vertical 8x16 slice out of a 16x16 matrix, do a transform on it, // transpose into a horizontal 16x8 slice and store. // x0 = dst (temp buffer) @@ -671,53 +716,8 @@ function \txfm\()16_1d_8x16_pass2_neon lsl x1, x1, #1 bl \txfm\()16 -.macro load_add_store coef0, coef1, coef2, coef3, coef4, coef5, coef6, coef7, tmp1, tmp2 - srshr \coef0, \coef0, #6 - ld1 {v2.8b}, [x0], x1 - srshr \coef1, \coef1, #6 - ld1 {v3.8b}, [x3], x1 - srshr \coef2, \coef2, #6 - ld1 {v4.8b}, [x0], x1 - srshr \coef3, \coef3, #6 - uaddw \coef0, \coef0, v2.8b - ld1 {v5.8b}, [x3], x1 - uaddw \coef1, \coef1, v3.8b - srshr \coef4, \coef4, #6 - ld1 {v6.8b}, [x0], x1 - srshr \coef5, \coef5, #6 - ld1 {v7.8b}, [x3], x1 - sqxtun v2.8b, \coef0 - srshr \coef6, \coef6, #6 - sqxtun v3.8b, \coef1 - srshr \coef7, \coef7, #6 - uaddw \coef2, \coef2, v4.8b - ld1 {\tmp1}, [x0], x1 - uaddw \coef3, \coef3, v5.8b - ld1 {\tmp2}, [x3], x1 - sqxtun v4.8b, \coef2 - sub x0, x0, x1, lsl #2 - sub x3, x3, x1, lsl #2 - sqxtun v5.8b, \coef3 - uaddw \coef4, \coef4, v6.8b - st1 {v2.8b}, [x0], x1 - uaddw \coef5, \coef5, v7.8b - st1 {v3.8b}, [x3], x1 - sqxtun v6.8b, \coef4 - st1 {v4.8b}, [x0], x1 - sqxtun v7.8b, \coef5 - st1 {v5.8b}, [x3], x1 - uaddw \coef6, \coef6, \tmp1 - st1 {v6.8b}, [x0], x1 - uaddw \coef7, \coef7, \tmp2 - st1 {v7.8b}, [x3], x1 - sqxtun \tmp1, \coef6 - sqxtun \tmp2, \coef7 - st1 {\tmp1}, [x0], x1 - st1 {\tmp2}, [x3], x1 -.endm load_add_store v16.8h, v17.8h, v18.8h, v19.8h, v20.8h, v21.8h, v22.8h, v23.8h, v16.8b, v17.8b load_add_store v24.8h, v25.8h, v26.8h, v27.8h, v28.8h, v29.8h, v30.8h, v31.8h, v16.8b, v17.8b -.purgem load_add_store br x14 endfunc From 5eb5aec475aabc884d083566f902876ecbc072cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 22 Nov 2016 11:07:38 +0200 Subject: [PATCH 0879/3374] arm: vp9itxfm: Do a simpler half/quarter idct16/idct32 when possible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. This avoids loading and calculating coefficients that we know will be zero, and avoids filling the temp buffer with zeros in places where we know the second pass won't read. This gives a pretty substantial speedup for the smaller subpartitions. The code size increases from 12388 bytes to 19784 bytes. The idct16/32_end macros are moved above the individual functions; the instructions themselves are unchanged, but since new functions are added at the same place where the code is moved from, the diff looks rather messy. Before: Cortex A7 A8 A9 A53 vp9_inv_dct_dct_16x16_sub1_add_neon: 273.0 189.5 212.0 235.8 vp9_inv_dct_dct_16x16_sub2_add_neon: 2102.1 1521.7 1736.2 1265.8 vp9_inv_dct_dct_16x16_sub4_add_neon: 2104.5 1533.0 1736.6 1265.5 vp9_inv_dct_dct_16x16_sub8_add_neon: 2484.8 1828.7 2014.4 1506.5 vp9_inv_dct_dct_16x16_sub12_add_neon: 2851.2 2117.8 2294.8 1753.2 vp9_inv_dct_dct_16x16_sub16_add_neon: 3239.4 2408.3 2543.5 1994.9 vp9_inv_dct_dct_32x32_sub1_add_neon: 758.3 456.7 864.5 553.9 vp9_inv_dct_dct_32x32_sub2_add_neon: 10776.7 7949.8 8567.7 6819.7 vp9_inv_dct_dct_32x32_sub4_add_neon: 10865.6 8131.5 8589.6 6816.3 vp9_inv_dct_dct_32x32_sub8_add_neon: 12053.9 9271.3 9387.7 7564.0 vp9_inv_dct_dct_32x32_sub12_add_neon: 13328.3 10463.2 10217.0 8321.3 vp9_inv_dct_dct_32x32_sub16_add_neon: 14176.4 11509.5 11018.7 9062.3 vp9_inv_dct_dct_32x32_sub20_add_neon: 15301.5 12999.9 11855.1 9828.2 vp9_inv_dct_dct_32x32_sub24_add_neon: 16482.7 14931.5 12650.1 10575.0 vp9_inv_dct_dct_32x32_sub28_add_neon: 17589.5 15811.9 13482.8 11333.4 vp9_inv_dct_dct_32x32_sub32_add_neon: 18696.2 17049.2 14355.6 12089.7 After: vp9_inv_dct_dct_16x16_sub1_add_neon: 273.0 189.5 211.7 235.8 vp9_inv_dct_dct_16x16_sub2_add_neon: 1203.5 998.2 1035.3 763.0 vp9_inv_dct_dct_16x16_sub4_add_neon: 1203.5 998.1 1035.5 760.8 vp9_inv_dct_dct_16x16_sub8_add_neon: 1926.1 1610.6 1722.1 1271.7 vp9_inv_dct_dct_16x16_sub12_add_neon: 2873.2 2129.7 2285.1 1757.3 vp9_inv_dct_dct_16x16_sub16_add_neon: 3221.4 2520.3 2557.6 2002.1 vp9_inv_dct_dct_32x32_sub1_add_neon: 753.0 457.5 866.6 554.6 vp9_inv_dct_dct_32x32_sub2_add_neon: 7554.6 5652.4 6048.4 4920.2 vp9_inv_dct_dct_32x32_sub4_add_neon: 7549.9 5685.0 6046.9 4925.7 vp9_inv_dct_dct_32x32_sub8_add_neon: 8336.9 6704.5 6604.0 5478.0 vp9_inv_dct_dct_32x32_sub12_add_neon: 10914.0 9777.2 9240.4 7416.9 vp9_inv_dct_dct_32x32_sub16_add_neon: 11859.2 11223.3 9966.3 8095.1 vp9_inv_dct_dct_32x32_sub20_add_neon: 15237.1 13029.4 11838.3 9829.4 vp9_inv_dct_dct_32x32_sub24_add_neon: 16293.2 14379.8 12644.9 10572.0 vp9_inv_dct_dct_32x32_sub28_add_neon: 17424.3 15734.7 13473.0 11326.9 vp9_inv_dct_dct_32x32_sub32_add_neon: 18531.3 17457.0 14298.6 12080.0 Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 591 ++++++++++++++++++++++++++++++--- 1 file changed, 537 insertions(+), 54 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index b3188bc7118d5..167d5178e43b9 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -74,6 +74,14 @@ endconst vrshrn.s32 \out2, \tmpq4, #14 .endm +@ Same as mbutterfly0 above, but treating the input in in2 as zero, +@ writing the same output into both out1 and out2. +.macro mbutterfly0_h out1, out2, in1, in2, tmpd1, tmpd2, tmpq3, tmpq4 + vmull.s16 \tmpq3, \in1, d0[0] + vrshrn.s32 \out1, \tmpq3, #14 + vrshrn.s32 \out2, \tmpq3, #14 +.endm + @ out1,out2 = ((in1 + in2) * d0[0] + (1 << 13)) >> 14 @ out3,out4 = ((in1 - in2) * d0[0] + (1 << 13)) >> 14 @ Same as mbutterfly0, but with input being 2 q registers, output @@ -137,6 +145,23 @@ endconst vrshrn.s32 \inout2, \tmp2, #14 .endm +@ Same as mbutterfly above, but treating the input in inout2 as zero +.macro mbutterfly_h1 inout1, inout2, coef1, coef2, tmp1, tmp2 + vmull.s16 \tmp1, \inout1, \coef1 + vmull.s16 \tmp2, \inout1, \coef2 + vrshrn.s32 \inout1, \tmp1, #14 + vrshrn.s32 \inout2, \tmp2, #14 +.endm + +@ Same as mbutterfly above, but treating the input in inout1 as zero +.macro mbutterfly_h2 inout1, inout2, coef1, coef2, tmp1, tmp2 + vmull.s16 \tmp1, \inout2, \coef2 + vmull.s16 \tmp2, \inout2, \coef1 + vneg.s32 \tmp1, \tmp1 + vrshrn.s32 \inout2, \tmp2, #14 + vrshrn.s32 \inout1, \tmp1, #14 +.endm + @ inout1,inout2 = (inout1,inout2 * coef1 - inout3,inout4 * coef2 + (1 << 13)) >> 14 @ inout3,inout4 = (inout1,inout2 * coef2 + inout3,inout4 * coef1 + (1 << 13)) >> 14 @ inout are 4 d registers, tmp are 4 q registers @@ -534,6 +559,33 @@ function idct16x16_dc_add_neon endfunc .ltorg +.macro idct16_end + butterfly d18, d7, d4, d7 @ d18 = t0a, d7 = t7a + butterfly d19, d22, d5, d22 @ d19 = t1a, d22 = t6 + butterfly d4, d26, d20, d26 @ d4 = t2a, d26 = t5 + butterfly d5, d6, d28, d6 @ d5 = t3a, d6 = t4 + butterfly d20, d28, d16, d24 @ d20 = t8a, d28 = t11a + butterfly d24, d21, d23, d21 @ d24 = t9, d21 = t10 + butterfly d23, d27, d25, d27 @ d23 = t14, d27 = t13 + butterfly d25, d29, d29, d17 @ d25 = t15a, d29 = t12a + + mbutterfly0 d27, d21, d27, d21, d16, d30, q8, q15 @ d27 = t13a, d21 = t10a + mbutterfly0 d29, d28, d29, d28, d16, d30, q8, q15 @ d29 = t12, d28 = t11 + + vswp d27, d29 @ d27 = t12, d29 = t13a + vswp d28, d27 @ d28 = t12, d27 = t11 + butterfly d16, d31, d18, d25 @ d16 = out[0], d31 = out[15] + butterfly d17, d30, d19, d23 @ d17 = out[1], d30 = out[14] + butterfly_r d25, d22, d22, d24 @ d25 = out[9], d22 = out[6] + butterfly d23, d24, d7, d20 @ d23 = out[7], d24 = out[8] + butterfly d18, d29, d4, d29 @ d18 = out[2], d29 = out[13] + butterfly d19, d28, d5, d28 @ d19 = out[3], d28 = out[12] + vmov d4, d21 @ d4 = t10a + butterfly d20, d27, d6, d27 @ d20 = out[4], d27 = out[11] + butterfly d21, d26, d26, d4 @ d21 = out[5], d26 = out[10] + bx lr +.endm + function idct16 mbutterfly0 d16, d24, d16, d24, d4, d6, q2, q3 @ d16 = t0a, d24 = t1a mbutterfly d20, d28, d0[1], d0[2], q2, q3 @ d20 = t2a, d28 = t3a @@ -556,31 +608,63 @@ function idct16 mbutterfly0 d22, d26, d22, d26, d18, d30, q9, q15 @ d22 = t6a, d26 = t5a mbutterfly d23, d25, d0[1], d0[2], q9, q15 @ d23 = t9a, d25 = t14a mbutterfly d27, d21, d0[1], d0[2], q9, q15, neg=1 @ d27 = t13a, d21 = t10a + idct16_end +endfunc - butterfly d18, d7, d4, d7 @ d18 = t0a, d7 = t7a - butterfly d19, d22, d5, d22 @ d19 = t1a, d22 = t6 - butterfly d4, d26, d20, d26 @ d4 = t2a, d26 = t5 - butterfly d5, d6, d28, d6 @ d5 = t3a, d6 = t4 - butterfly d20, d28, d16, d24 @ d20 = t8a, d28 = t11a - butterfly d24, d21, d23, d21 @ d24 = t9, d21 = t10 - butterfly d23, d27, d25, d27 @ d23 = t14, d27 = t13 - butterfly d25, d29, d29, d17 @ d25 = t15a, d29 = t12a +function idct16_half + mbutterfly0_h d16, d24, d16, d24, d4, d6, q2, q3 @ d16 = t0a, d24 = t1a + mbutterfly_h1 d20, d28, d0[1], d0[2], q2, q3 @ d20 = t2a, d28 = t3a + mbutterfly_h1 d18, d30, d0[3], d1[0], q2, q3 @ d18 = t4a, d30 = t7a + mbutterfly_h2 d26, d22, d1[1], d1[2], q2, q3 @ d26 = t5a, d22 = t6a + mbutterfly_h1 d17, d31, d1[3], d2[0], q2, q3 @ d17 = t8a, d31 = t15a + mbutterfly_h2 d25, d23, d2[1], d2[2], q2, q3 @ d25 = t9a, d23 = t14a + mbutterfly_h1 d21, d27, d2[3], d3[0], q2, q3 @ d21 = t10a, d27 = t13a + mbutterfly_h2 d29, d19, d3[1], d3[2], q2, q3 @ d29 = t11a, d19 = t12a - mbutterfly0 d27, d21, d27, d21, d16, d30, q8, q15 @ d27 = t13a, d21 = t10a - mbutterfly0 d29, d28, d29, d28, d16, d30, q8, q15 @ d29 = t12, d28 = t11 + butterfly d4, d28, d16, d28 @ d4 = t0, d28 = t3 + butterfly d5, d20, d24, d20 @ d5 = t1, d20 = t2 + butterfly d6, d26, d18, d26 @ d6 = t4, d26 = t5 + butterfly d7, d22, d30, d22 @ d7 = t7, d22 = t6 + butterfly d16, d25, d17, d25 @ d16 = t8, d25 = t9 + butterfly d24, d21, d29, d21 @ d24 = t11, d21 = t10 + butterfly d17, d27, d19, d27 @ d17 = t12, d27 = t13 + butterfly d29, d23, d31, d23 @ d29 = t15, d23 = t14 - vswp d27, d29 @ d27 = t12, d29 = t13a - vswp d28, d27 @ d28 = t12, d27 = t11 - butterfly d16, d31, d18, d25 @ d16 = out[0], d31 = out[15] - butterfly d17, d30, d19, d23 @ d17 = out[1], d30 = out[14] - butterfly_r d25, d22, d22, d24 @ d25 = out[9], d22 = out[6] - butterfly d23, d24, d7, d20 @ d23 = out[7], d24 = out[8] - butterfly d18, d29, d4, d29 @ d18 = out[2], d29 = out[13] - butterfly d19, d28, d5, d28 @ d19 = out[3], d28 = out[12] - vmov d4, d21 @ d4 = t10a - butterfly d20, d27, d6, d27 @ d20 = out[4], d27 = out[11] - butterfly d21, d26, d26, d4 @ d21 = out[5], d26 = out[10] - bx lr + mbutterfly0 d22, d26, d22, d26, d18, d30, q9, q15 @ d22 = t6a, d26 = t5a + mbutterfly d23, d25, d0[1], d0[2], q9, q15 @ d23 = t9a, d25 = t14a + mbutterfly d27, d21, d0[1], d0[2], q9, q15, neg=1 @ d27 = t13a, d21 = t10a + idct16_end +endfunc + +function idct16_quarter + vmull.s16 q12, d19, d3[2] + vmull.s16 q2, d17, d1[3] + vmull.s16 q3, d18, d1[0] + vmull.s16 q15, d18, d0[3] + vneg.s32 q12, q12 + vmull.s16 q14, d17, d2[0] + vmull.s16 q13, d19, d3[1] + vmull.s16 q11, d16, d0[0] + vrshrn.s32 d24, q12, #14 + vrshrn.s32 d16, q2, #14 + vrshrn.s32 d7, q3, #14 + vrshrn.s32 d6, q15, #14 + vrshrn.s32 d29, q14, #14 + vrshrn.s32 d17, q13, #14 + vrshrn.s32 d28, q11, #14 + + mbutterfly_l q10, q11, d17, d24, d0[1], d0[2] + mbutterfly_l q9, q15, d29, d16, d0[1], d0[2] + vneg.s32 q11, q11 + vrshrn.s32 d27, q10, #14 + vrshrn.s32 d21, q11, #14 + vrshrn.s32 d23, q9, #14 + vrshrn.s32 d25, q15, #14 + vmov d4, d28 + vmov d5, d28 + mbutterfly0 d22, d26, d7, d6, d18, d30, q9, q15 + vmov d20, d28 + idct16_end endfunc function iadst16 @@ -819,6 +903,13 @@ A and r7, sp, #15 vld1.16 {q0-q1}, [r12,:128] .endif +.ifc \txfm1\()_\txfm2,idct_idct + cmp r3, #10 + ble idct16x16_quarter_add_neon + cmp r3, #38 + ble idct16x16_half_add_neon +.endif + .irp i, 0, 4, 8, 12 add r0, sp, #(\i*32) .ifc \txfm1\()_\txfm2,idct_idct @@ -877,6 +968,169 @@ itxfm_func16x16 idct, iadst itxfm_func16x16 iadst, iadst .ltorg +function idct16_1d_4x16_pass1_quarter_neon + push {lr} + mov r12, #32 + vmov.s16 q2, #0 +.irp i, 16, 17, 18, 19 + vld1.16 {d\i}, [r2,:64] + vst1.16 {d4}, [r2,:64], r12 +.endr + + bl idct16_quarter + + @ Do four 4x4 transposes. Originally, d16-d31 contain the + @ 16 rows. Afterwards, d16-d19, d20-d23, d24-d27, d28-d31 + @ contain the transposed 4x4 blocks. + transpose16_q_4x_4x4 q8, q9, q10, q11, q12, q13, q14, q15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31 + + @ Store the transposed 4x4 blocks horizontally. + @ The first 4x4 block is kept in registers for the second pass, + @ store the rest in the temp buffer. + add r0, r0, #8 + vst1.16 {d20}, [r0,:64]! + vst1.16 {d24}, [r0,:64]! + vst1.16 {d28}, [r0,:64]! + add r0, r0, #8 + vst1.16 {d21}, [r0,:64]! + vst1.16 {d25}, [r0,:64]! + vst1.16 {d29}, [r0,:64]! + add r0, r0, #8 + vst1.16 {d22}, [r0,:64]! + vst1.16 {d26}, [r0,:64]! + vst1.16 {d30}, [r0,:64]! + add r0, r0, #8 + vst1.16 {d23}, [r0,:64]! + vst1.16 {d27}, [r0,:64]! + vst1.16 {d31}, [r0,:64]! + pop {pc} +endfunc + +function idct16_1d_4x16_pass2_quarter_neon + push {lr} + @ Only load the top 4 lines, and only do it for the later slices. + @ For the first slice, d16-d19 is kept in registers from the first pass. + cmp r3, #0 + beq 1f + mov r12, #32 +.irp i, 16, 17, 18, 19 + vld1.16 {d\i}, [r2,:64], r12 +.endr +1: + + add r3, r0, r1 + lsl r1, r1, #1 + bl idct16_quarter + + load_add_store q8, q9, q10, q11 + load_add_store q12, q13, q14, q15 + + pop {pc} +endfunc + +function idct16_1d_4x16_pass1_half_neon + push {lr} + mov r12, #32 + vmov.s16 q2, #0 +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + vld1.16 {d\i}, [r2,:64] + vst1.16 {d4}, [r2,:64], r12 +.endr + + bl idct16_half + + @ Do four 4x4 transposes. Originally, d16-d31 contain the + @ 16 rows. Afterwards, d16-d19, d20-d23, d24-d27, d28-d31 + @ contain the transposed 4x4 blocks. + transpose16_q_4x_4x4 q8, q9, q10, q11, q12, q13, q14, q15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31 + + @ Store the transposed 4x4 blocks horizontally. + cmp r1, #4 + beq 1f +.irp i, 16, 20, 24, 28, 17, 21, 25, 29, 18, 22, 26, 30, 19, 23, 27, 31 + vst1.16 {d\i}, [r0,:64]! +.endr + pop {pc} +1: + @ Special case: For the second input column (r1 == 4), + @ which would be stored as the second row in the temp buffer, + @ don't store the first 4x4 block, but keep it in registers + @ for the first slice of the second pass (where it is the + @ second 4x4 block). + add r0, r0, #8 + vst1.16 {d20}, [r0,:64]! + vst1.16 {d24}, [r0,:64]! + vst1.16 {d28}, [r0,:64]! + add r0, r0, #8 + vst1.16 {d21}, [r0,:64]! + vst1.16 {d25}, [r0,:64]! + vst1.16 {d29}, [r0,:64]! + add r0, r0, #8 + vst1.16 {d22}, [r0,:64]! + vst1.16 {d26}, [r0,:64]! + vst1.16 {d30}, [r0,:64]! + add r0, r0, #8 + vst1.16 {d23}, [r0,:64]! + vst1.16 {d27}, [r0,:64]! + vst1.16 {d31}, [r0,:64]! + vmov d20, d16 + vmov d21, d17 + vmov d22, d18 + vmov d23, d19 + pop {pc} +endfunc + +function idct16_1d_4x16_pass2_half_neon + push {lr} + mov r12, #32 + cmp r3, #0 +.irp i, 16, 17, 18, 19 + vld1.16 {d\i}, [r2,:64], r12 +.endr + beq 1f +.irp i, 20, 21, 22, 23 + vld1.16 {d\i}, [r2,:64], r12 +.endr +1: + + add r3, r0, r1 + lsl r1, r1, #1 + bl idct16_half + + load_add_store q8, q9, q10, q11 + load_add_store q12, q13, q14, q15 + + pop {pc} +endfunc +.purgem load_add_store + +.macro idct16_partial size +function idct16x16_\size\()_add_neon + add r0, sp, #(0*32) + mov r1, #0 + add r2, r6, #(0*2) + bl idct16_1d_4x16_pass1_\size\()_neon +.ifc \size,half + add r0, sp, #(4*32) + mov r1, #4 + add r2, r6, #(4*2) + bl idct16_1d_4x16_pass1_\size\()_neon +.endif +.irp i, 0, 4, 8, 12 + add r0, r4, #(\i) + mov r1, r5 + add r2, sp, #(\i*2) + mov r3, #\i + bl idct16_1d_4x16_pass2_\size\()_neon +.endr + + add sp, sp, r7 + pop {r4-r8,pc} +endfunc +.endm + +idct16_partial quarter +idct16_partial half function idct32x32_dc_add_neon movrel r12, idct_coeffs @@ -913,6 +1167,38 @@ function idct32x32_dc_add_neon bx lr endfunc +.macro idct32_end + butterfly d16, d5, d4, d5 @ d16 = t16a, d5 = t19a + butterfly d17, d20, d23, d20 @ d17 = t17, d20 = t18 + butterfly d18, d6, d7, d6 @ d18 = t23a, d6 = t20a + butterfly d19, d21, d22, d21 @ d19 = t22, d21 = t21 + butterfly d4, d28, d28, d30 @ d4 = t24a, d28 = t27a + butterfly d23, d26, d25, d26 @ d23 = t25, d26 = t26 + butterfly d7, d29, d29, d31 @ d7 = t31a, d29 = t28a + butterfly d22, d27, d24, d27 @ d22 = t30, d27 = t29 + + mbutterfly d27, d20, d0[1], d0[2], q12, q15 @ d27 = t18a, d20 = t29a + mbutterfly d29, d5, d0[1], d0[2], q12, q15 @ d29 = t19, d5 = t28 + mbutterfly d28, d6, d0[1], d0[2], q12, q15, neg=1 @ d28 = t27, d6 = t20 + mbutterfly d26, d21, d0[1], d0[2], q12, q15, neg=1 @ d26 = t26a, d21 = t21a + + butterfly d31, d24, d7, d4 @ d31 = t31, d24 = t24 + butterfly d30, d25, d22, d23 @ d30 = t30a, d25 = t25a + butterfly_r d23, d16, d16, d18 @ d23 = t23, d16 = t16 + butterfly_r d22, d17, d17, d19 @ d22 = t22a, d17 = t17a + butterfly d18, d21, d27, d21 @ d18 = t18, d21 = t21 + butterfly_r d27, d28, d5, d28 @ d27 = t27a, d28 = t28a + butterfly d4, d26, d20, d26 @ d4 = t29, d26 = t26 + butterfly d19, d20, d29, d6 @ d19 = t19a, d20 = t20 + vmov d29, d4 @ d29 = t29 + + mbutterfly0 d27, d20, d27, d20, d4, d6, q2, q3 @ d27 = t27, d20 = t20 + mbutterfly0 d26, d21, d26, d21, d4, d6, q2, q3 @ d26 = t26a, d21 = t21a + mbutterfly0 d25, d22, d25, d22, d4, d6, q2, q3 @ d25 = t25, d22 = t22 + mbutterfly0 d24, d23, d24, d23, d4, d6, q2, q3 @ d24 = t24a, d23 = t23a + bx lr +.endm + function idct32_odd movrel r12, idct_coeffs add r12, r12, #32 @@ -943,38 +1229,91 @@ function idct32_odd mbutterfly d27, d20, d0[3], d1[0], q8, q9, neg=1 @ d27 = t29a, d20 = t18a mbutterfly d21, d26, d1[1], d1[2], q8, q9 @ d21 = t21a, d26 = t26a mbutterfly d25, d22, d1[1], d1[2], q8, q9, neg=1 @ d25 = t25a, d22 = t22a + idct32_end +endfunc - butterfly d16, d5, d4, d5 @ d16 = t16a, d5 = t19a - butterfly d17, d20, d23, d20 @ d17 = t17, d20 = t18 - butterfly d18, d6, d7, d6 @ d18 = t23a, d6 = t20a - butterfly d19, d21, d22, d21 @ d19 = t22, d21 = t21 - butterfly d4, d28, d28, d30 @ d4 = t24a, d28 = t27a - butterfly d23, d26, d25, d26 @ d23 = t25, d26 = t26 - butterfly d7, d29, d29, d31 @ d7 = t31a, d29 = t28a - butterfly d22, d27, d24, d27 @ d22 = t30, d27 = t29 +function idct32_odd_half + movrel r12, idct_coeffs + add r12, r12, #32 + vld1.16 {q0-q1}, [r12,:128] - mbutterfly d27, d20, d0[1], d0[2], q12, q15 @ d27 = t18a, d20 = t29a - mbutterfly d29, d5, d0[1], d0[2], q12, q15 @ d29 = t19, d5 = t28 - mbutterfly d28, d6, d0[1], d0[2], q12, q15, neg=1 @ d28 = t27, d6 = t20 - mbutterfly d26, d21, d0[1], d0[2], q12, q15, neg=1 @ d26 = t26a, d21 = t21a + mbutterfly_h1 d16, d31, d0[0], d0[1], q2, q3 @ d16 = t16a, d31 = t31a + mbutterfly_h2 d24, d23, d0[2], d0[3], q2, q3 @ d24 = t17a, d23 = t30a + mbutterfly_h1 d20, d27, d1[0], d1[1], q2, q3 @ d20 = t18a, d27 = t29a + mbutterfly_h2 d28, d19, d1[2], d1[3], q2, q3 @ d28 = t19a, d19 = t28a + mbutterfly_h1 d18, d29, d2[0], d2[1], q2, q3 @ d18 = t20a, d29 = t27a + mbutterfly_h2 d26, d21, d2[2], d2[3], q2, q3 @ d26 = t21a, d21 = t26a + mbutterfly_h1 d22, d25, d3[0], d3[1], q2, q3 @ d22 = t22a, d25 = t25a + mbutterfly_h2 d30, d17, d3[2], d3[3], q2, q3 @ d30 = t23a, d17 = t24a - butterfly d31, d24, d7, d4 @ d31 = t31, d24 = t24 - butterfly d30, d25, d22, d23 @ d30 = t30a, d25 = t25a - butterfly_r d23, d16, d16, d18 @ d23 = t23, d16 = t16 - butterfly_r d22, d17, d17, d19 @ d22 = t22a, d17 = t17a - butterfly d18, d21, d27, d21 @ d18 = t18, d21 = t21 - butterfly_r d27, d28, d5, d28 @ d27 = t27a, d28 = t28a - butterfly d4, d26, d20, d26 @ d4 = t29, d26 = t26 - butterfly d19, d20, d29, d6 @ d19 = t19a, d20 = t20 - vmov d29, d4 @ d29 = t29 + sub r12, r12, #32 + vld1.16 {q0}, [r12,:128] - mbutterfly0 d27, d20, d27, d20, d4, d6, q2, q3 @ d27 = t27, d20 = t20 - mbutterfly0 d26, d21, d26, d21, d4, d6, q2, q3 @ d26 = t26a, d21 = t21a - mbutterfly0 d25, d22, d25, d22, d4, d6, q2, q3 @ d25 = t25, d22 = t22 - mbutterfly0 d24, d23, d24, d23, d4, d6, q2, q3 @ d24 = t24a, d23 = t23a - bx lr + butterfly d4, d24, d16, d24 @ d4 = t16, d24 = t17 + butterfly d5, d20, d28, d20 @ d5 = t19, d20 = t18 + butterfly d6, d26, d18, d26 @ d6 = t20, d26 = t21 + butterfly d7, d22, d30, d22 @ d7 = t23, d22 = t22 + butterfly d28, d25, d17, d25 @ d28 = t24, d25 = t25 + butterfly d30, d21, d29, d21 @ d30 = t27, d21 = t26 + butterfly d29, d23, d31, d23 @ d29 = t31, d23 = t30 + butterfly d31, d27, d19, d27 @ d31 = t28, d27 = t29 + + mbutterfly d23, d24, d0[3], d1[0], q8, q9 @ d23 = t17a, d24 = t30a + mbutterfly d27, d20, d0[3], d1[0], q8, q9, neg=1 @ d27 = t29a, d20 = t18a + mbutterfly d21, d26, d1[1], d1[2], q8, q9 @ d21 = t21a, d26 = t26a + mbutterfly d25, d22, d1[1], d1[2], q8, q9, neg=1 @ d25 = t25a, d22 = t22a + + idct32_end endfunc +function idct32_odd_quarter + movrel r12, idct_coeffs + add r12, r12, #32 + vld1.16 {q0-q1}, [r12,:128] + + vmull.s16 q2, d16, d0[0] + vmull.s16 q14, d19, d1[3] + vmull.s16 q15, d16, d0[1] + vmull.s16 q11, d17, d3[2] + vmull.s16 q3, d17, d3[3] + vmull.s16 q13, d19, d1[2] + vmull.s16 q10, d18, d2[0] + vmull.s16 q12, d18, d2[1] + + sub r12, r12, #32 + vld1.16 {q0}, [r12,:128] + + vneg.s32 q14, q14 + vneg.s32 q3, q3 + + vrshrn.s32 d4, q2, #14 + vrshrn.s32 d5, q14, #14 + vrshrn.s32 d29, q15, #14 + vrshrn.s32 d28, q11, #14 + vrshrn.s32 d7, q3, #14 + vrshrn.s32 d31, q13, #14 + vrshrn.s32 d6, q10, #14 + vrshrn.s32 d30, q12, #14 + + mbutterfly_l q8, q9, d29, d4, d0[3], d1[0] + mbutterfly_l q13, q10, d31, d5, d0[3], d1[0] + vrshrn.s32 d23, q8, #14 + vrshrn.s32 d24, q9, #14 + vneg.s32 q10, q10 + vrshrn.s32 d27, q13, #14 + vrshrn.s32 d20, q10, #14 + mbutterfly_l q8, q9, d30, d6, d1[1], d1[2] + vrshrn.s32 d21, q8, #14 + vrshrn.s32 d26, q9, #14 + mbutterfly_l q8, q9, d28, d7, d1[1], d1[2] + vrshrn.s32 d25, q8, #14 + vneg.s32 q9, q9 + vrshrn.s32 d22, q9, #14 + + idct32_end +endfunc + +.macro idct32_funcs suffix @ Do an 32-point IDCT of a 4x32 slice out of a 32x32 matrix. @ We don't have register space to do a single pass IDCT of 4x32 though, @ but the 32-point IDCT can be decomposed into two 16-point IDCTs; @@ -984,7 +1323,7 @@ endfunc @ r0 = dst (temp buffer) @ r1 = unused @ r2 = src -function idct32_1d_4x32_pass1_neon +function idct32_1d_4x32_pass1\suffix\()_neon push {lr} movrel r12, idct_coeffs @@ -995,12 +1334,26 @@ function idct32_1d_4x32_pass1_neon vmov.s16 d4, #0 @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vld1.16 {d\i}, [r2,:64] vst1.16 {d4}, [r2,:64], r12 .endr +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + vld1.16 {d\i}, [r2,:64] + vst1.16 {d4}, [r2,:64], r12 +.endr +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + vld1.16 {d\i}, [r2,:64] + vst1.16 {d4}, [r2,:64], r12 +.endr +.endif - bl idct16 + bl idct16\suffix @ Do four 4x4 transposes. Originally, d16-d31 contain the @ 16 rows. Afterwards, d16-d19, d20-d23, d24-d27, d28-d31 @@ -1026,17 +1379,39 @@ function idct32_1d_4x32_pass1_neon @ Move r2 back to the start of the input, and move @ to the first odd row +.ifb \suffix sub r2, r2, r12, lsl #4 +.endif +.ifc \suffix,_quarter + sub r2, r2, r12, lsl #2 +.endif +.ifc \suffix,_half + sub r2, r2, r12, lsl #3 +.endif add r2, r2, #64 vmov.s16 d4, #0 @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vld1.16 {d\i}, [r2,:64] vst1.16 {d4}, [r2,:64], r12 .endr +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + vld1.16 {d\i}, [r2,:64] + vst1.16 {d4}, [r2,:64], r12 +.endr +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + vld1.16 {d\i}, [r2,:64] + vst1.16 {d4}, [r2,:64], r12 +.endr +.endif - bl idct32_odd + bl idct32_odd\suffix transpose16_q_4x_4x4 q15, q14, q13, q12, q11, q10, q9, q8, d31, d30, d29, d28, d27, d26, d25, d24, d23, d22, d21, d20, d19, d18, d17, d16 @@ -1072,19 +1447,33 @@ endfunc @ r0 = dst @ r1 = dst stride @ r2 = src (temp buffer) -function idct32_1d_4x32_pass2_neon +function idct32_1d_4x32_pass2\suffix\()_neon push {lr} movrel r12, idct_coeffs vld1.16 {q0-q1}, [r12,:128] mov r12, #128 @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vld1.16 {d\i}, [r2,:64], r12 .endr sub r2, r2, r12, lsl #4 +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + vld1.16 {d\i}, [r2,:64], r12 +.endr + sub r2, r2, r12, lsl #2 +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + vld1.16 {d\i}, [r2,:64], r12 +.endr + sub r2, r2, r12, lsl #3 +.endif - bl idct16 + bl idct16\suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vst1.16 {d\i}, [r2,:64], r12 @@ -1094,13 +1483,27 @@ function idct32_1d_4x32_pass2_neon add r2, r2, #64 @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vld1.16 {d\i}, [r2,:64], r12 .endr sub r2, r2, r12, lsl #4 +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + vld1.16 {d\i}, [r2,:64], r12 +.endr + sub r2, r2, r12, lsl #2 +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + vld1.16 {d\i}, [r2,:64], r12 +.endr + sub r2, r2, r12, lsl #3 +.endif sub r2, r2, #64 - bl idct32_odd + bl idct32_odd\suffix mov r12, #128 .macro load_acc_store a, b, c, d, neg=0 @@ -1150,6 +1553,11 @@ function idct32_1d_4x32_pass2_neon .purgem load_acc_store pop {pc} endfunc +.endm + +idct32_funcs +idct32_funcs _quarter +idct32_funcs _half const min_eob_idct_idct_32, align=4 .short 0, 9, 34, 70, 135, 240, 336, 448 @@ -1173,6 +1581,11 @@ A and r7, sp, #15 mov r5, r1 mov r6, r2 + cmp r3, #34 + ble idct32x32_quarter_add_neon + cmp r3, #135 + ble idct32x32_half_add_neon + .irp i, 0, 4, 8, 12, 16, 20, 24, 28 add r0, sp, #(\i*64) .if \i > 0 @@ -1209,3 +1622,73 @@ A and r7, sp, #15 vpop {q4-q7} pop {r4-r8,pc} endfunc + +function idct32x32_quarter_add_neon +.irp i, 0, 4 + add r0, sp, #(\i*64) +.if \i == 4 + cmp r3, #9 + ble 1f +.endif + add r2, r6, #(\i*2) + bl idct32_1d_4x32_pass1_quarter_neon +.endr + b 3f + +1: + @ Write zeros to the temp buffer for pass 2 + vmov.i16 q14, #0 + vmov.i16 q15, #0 +.rept 8 + vst1.16 {q14-q15}, [r0,:128]! +.endr +3: +.irp i, 0, 4, 8, 12, 16, 20, 24, 28 + add r0, r4, #(\i) + mov r1, r5 + add r2, sp, #(\i*2) + bl idct32_1d_4x32_pass2_quarter_neon +.endr + + add sp, sp, r7 + vpop {q4-q7} + pop {r4-r8,pc} +endfunc + +function idct32x32_half_add_neon +.irp i, 0, 4, 8, 12 + add r0, sp, #(\i*64) +.if \i > 0 + ldrh_post r1, r8, #2 + cmp r3, r1 + it le + movle r1, #(16 - \i)/2 + ble 1f +.endif + add r2, r6, #(\i*2) + bl idct32_1d_4x32_pass1_half_neon +.endr + b 3f + +1: + @ Write zeros to the temp buffer for pass 2 + vmov.i16 q14, #0 + vmov.i16 q15, #0 +2: + subs r1, r1, #1 +.rept 4 + vst1.16 {q14-q15}, [r0,:128]! +.endr + bne 2b +3: +.irp i, 0, 4, 8, 12, 16, 20, 24, 28 + add r0, r4, #(\i) + mov r1, r5 + add r2, sp, #(\i*2) + bl idct32_1d_4x32_pass2_half_neon +.endr + + add sp, sp, r7 + vpop {q4-q7} + pop {r4-r8,pc} +endfunc From a63da4511d0fee66695ff4afd264ba1dbf1e812d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 22 Nov 2016 22:58:35 +0200 Subject: [PATCH 0880/3374] aarch64: vp9itxfm: Do separate functions for half/quarter idct16 and idct32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. This avoids loading and calculating coefficients that we know will be zero, and avoids filling the temp buffer with zeros in places where we know the second pass won't read. This gives a pretty substantial speedup for the smaller subpartitions. The code size increases from 14740 bytes to 24292 bytes. The idct16/32_end macros are moved above the individual functions; the instructions themselves are unchanged, but since new functions are added at the same place where the code is moved from, the diff looks rather messy. Before: vp9_inv_dct_dct_16x16_sub1_add_neon: 236.7 vp9_inv_dct_dct_16x16_sub2_add_neon: 1051.0 vp9_inv_dct_dct_16x16_sub4_add_neon: 1051.0 vp9_inv_dct_dct_16x16_sub8_add_neon: 1051.0 vp9_inv_dct_dct_16x16_sub12_add_neon: 1387.4 vp9_inv_dct_dct_16x16_sub16_add_neon: 1387.6 vp9_inv_dct_dct_32x32_sub1_add_neon: 554.1 vp9_inv_dct_dct_32x32_sub2_add_neon: 5198.5 vp9_inv_dct_dct_32x32_sub4_add_neon: 5198.6 vp9_inv_dct_dct_32x32_sub8_add_neon: 5196.3 vp9_inv_dct_dct_32x32_sub12_add_neon: 6183.4 vp9_inv_dct_dct_32x32_sub16_add_neon: 6174.3 vp9_inv_dct_dct_32x32_sub20_add_neon: 7151.4 vp9_inv_dct_dct_32x32_sub24_add_neon: 7145.3 vp9_inv_dct_dct_32x32_sub28_add_neon: 8119.3 vp9_inv_dct_dct_32x32_sub32_add_neon: 8118.7 After: vp9_inv_dct_dct_16x16_sub1_add_neon: 236.7 vp9_inv_dct_dct_16x16_sub2_add_neon: 640.8 vp9_inv_dct_dct_16x16_sub4_add_neon: 639.0 vp9_inv_dct_dct_16x16_sub8_add_neon: 842.0 vp9_inv_dct_dct_16x16_sub12_add_neon: 1388.3 vp9_inv_dct_dct_16x16_sub16_add_neon: 1389.3 vp9_inv_dct_dct_32x32_sub1_add_neon: 554.1 vp9_inv_dct_dct_32x32_sub2_add_neon: 3685.5 vp9_inv_dct_dct_32x32_sub4_add_neon: 3685.1 vp9_inv_dct_dct_32x32_sub8_add_neon: 3684.4 vp9_inv_dct_dct_32x32_sub12_add_neon: 5312.2 vp9_inv_dct_dct_32x32_sub16_add_neon: 5315.4 vp9_inv_dct_dct_32x32_sub20_add_neon: 7154.9 vp9_inv_dct_dct_32x32_sub24_add_neon: 7154.5 vp9_inv_dct_dct_32x32_sub28_add_neon: 8126.6 vp9_inv_dct_dct_32x32_sub32_add_neon: 8127.2 Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 525 +++++++++++++++++++++++++---- 1 file changed, 466 insertions(+), 59 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index b6cadfb66bd1f..c954d1a5e108d 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -75,6 +75,17 @@ endconst .endif .endm +// Same as dmbutterfly0 above, but treating the input in in2 as zero, +// writing the same output into both out1 and out2. +.macro dmbutterfly0_h out1, out2, in1, in2, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6 + smull \tmp1\().4s, \in1\().4h, v0.h[0] + smull2 \tmp2\().4s, \in1\().8h, v0.h[0] + rshrn \out1\().4h, \tmp1\().4s, #14 + rshrn2 \out1\().8h, \tmp2\().4s, #14 + rshrn \out2\().4h, \tmp1\().4s, #14 + rshrn2 \out2\().8h, \tmp2\().4s, #14 +.endm + // out1,out2 = in1 * coef1 - in2 * coef2 // out3,out4 = in1 * coef2 + in2 * coef1 // out are 4 x .4s registers, in are 2 x .8h registers @@ -104,6 +115,43 @@ endconst rshrn2 \inout2\().8h, \tmp4\().4s, #14 .endm +// Same as dmbutterfly above, but treating the input in inout2 as zero +.macro dmbutterfly_h1 inout1, inout2, coef1, coef2, tmp1, tmp2, tmp3, tmp4 + smull \tmp1\().4s, \inout1\().4h, \coef1 + smull2 \tmp2\().4s, \inout1\().8h, \coef1 + smull \tmp3\().4s, \inout1\().4h, \coef2 + smull2 \tmp4\().4s, \inout1\().8h, \coef2 + rshrn \inout1\().4h, \tmp1\().4s, #14 + rshrn2 \inout1\().8h, \tmp2\().4s, #14 + rshrn \inout2\().4h, \tmp3\().4s, #14 + rshrn2 \inout2\().8h, \tmp4\().4s, #14 +.endm + +// Same as dmbutterfly above, but treating the input in inout1 as zero +.macro dmbutterfly_h2 inout1, inout2, coef1, coef2, tmp1, tmp2, tmp3, tmp4 + smull \tmp1\().4s, \inout2\().4h, \coef2 + smull2 \tmp2\().4s, \inout2\().8h, \coef2 + smull \tmp3\().4s, \inout2\().4h, \coef1 + smull2 \tmp4\().4s, \inout2\().8h, \coef1 + neg \tmp1\().4s, \tmp1\().4s + neg \tmp2\().4s, \tmp2\().4s + rshrn \inout2\().4h, \tmp3\().4s, #14 + rshrn2 \inout2\().8h, \tmp4\().4s, #14 + rshrn \inout1\().4h, \tmp1\().4s, #14 + rshrn2 \inout1\().8h, \tmp2\().4s, #14 +.endm + +.macro dsmull_h out1, out2, in, coef + smull \out1\().4s, \in\().4h, \coef + smull2 \out2\().4s, \in\().8h, \coef +.endm + +.macro drshrn_h out, in1, in2, shift + rshrn \out\().4h, \in1\().4s, \shift + rshrn2 \out\().8h, \in2\().4s, \shift +.endm + + // out1 = in1 + in2 // out2 = in1 - in2 .macro butterfly_8h out1, out2, in1, in2 @@ -463,6 +511,30 @@ function idct16x16_dc_add_neon ret endfunc +.macro idct16_end + butterfly_8h v18, v7, v4, v7 // v18 = t0a, v7 = t7a + butterfly_8h v19, v22, v5, v22 // v19 = t1a, v22 = t6 + butterfly_8h v4, v26, v20, v26 // v4 = t2a, v26 = t5 + butterfly_8h v5, v6, v28, v6 // v5 = t3a, v6 = t4 + butterfly_8h v20, v28, v16, v24 // v20 = t8a, v28 = t11a + butterfly_8h v24, v21, v23, v21 // v24 = t9, v21 = t10 + butterfly_8h v23, v27, v25, v27 // v23 = t14, v27 = t13 + butterfly_8h v25, v29, v29, v17 // v25 = t15a, v29 = t12a + + dmbutterfly0 v2, v3, v27, v21, v2, v3, v16, v17, v30, v31 // v2 = t13a, v3 = t10a + dmbutterfly0 v28, v27, v29, v28, v21, v29, v16, v17, v30, v31 // v28 = t12, v27 = t11 + + butterfly_8h v16, v31, v18, v25 // v16 = out[0], v31 = out[15] + butterfly_8h v17, v30, v19, v23 // v17 = out[1], v30 = out[14] + butterfly_8h_r v25, v22, v22, v24 // v25 = out[9], v22 = out[6] + butterfly_8h v23, v24, v7, v20 // v23 = out[7], v24 = out[8] + butterfly_8h v18, v29, v4, v2 // v18 = out[2], v29 = out[13] + butterfly_8h v19, v28, v5, v28 // v19 = out[3], v28 = out[12] + butterfly_8h v20, v27, v6, v27 // v20 = out[4], v27 = out[11] + butterfly_8h v21, v26, v26, v3 // v21 = out[5], v26 = out[10] + ret +.endm + function idct16 dmbutterfly0 v16, v24, v16, v24, v2, v3, v4, v5, v6, v7 // v16 = t0a, v24 = t1a dmbutterfly v20, v28, v0.h[1], v0.h[2], v2, v3, v4, v5 // v20 = t2a, v28 = t3a @@ -485,28 +557,65 @@ function idct16 dmbutterfly0 v22, v26, v22, v26, v2, v3, v18, v19, v30, v31 // v22 = t6a, v26 = t5a dmbutterfly v23, v25, v0.h[1], v0.h[2], v18, v19, v30, v31 // v23 = t9a, v25 = t14a dmbutterfly v27, v21, v0.h[1], v0.h[2], v18, v19, v30, v31, neg=1 // v27 = t13a, v21 = t10a + idct16_end +endfunc - butterfly_8h v18, v7, v4, v7 // v18 = t0a, v7 = t7a - butterfly_8h v19, v22, v5, v22 // v19 = t1a, v22 = t6 - butterfly_8h v4, v26, v20, v26 // v4 = t2a, v26 = t5 - butterfly_8h v5, v6, v28, v6 // v5 = t3a, v6 = t4 - butterfly_8h v20, v28, v16, v24 // v20 = t8a, v28 = t11a - butterfly_8h v24, v21, v23, v21 // v24 = t9, v21 = t10 - butterfly_8h v23, v27, v25, v27 // v23 = t14, v27 = t13 - butterfly_8h v25, v29, v29, v17 // v25 = t15a, v29 = t12a +function idct16_half + dmbutterfly0_h v16, v24, v16, v24, v2, v3, v4, v5, v6, v7 // v16 = t0a, v24 = t1a + dmbutterfly_h1 v20, v28, v0.h[1], v0.h[2], v2, v3, v4, v5 // v20 = t2a, v28 = t3a + dmbutterfly_h1 v18, v30, v0.h[3], v0.h[4], v2, v3, v4, v5 // v18 = t4a, v30 = t7a + dmbutterfly_h2 v26, v22, v0.h[5], v0.h[6], v2, v3, v4, v5 // v26 = t5a, v22 = t6a + dmbutterfly_h1 v17, v31, v0.h[7], v1.h[0], v2, v3, v4, v5 // v17 = t8a, v31 = t15a + dmbutterfly_h2 v25, v23, v1.h[1], v1.h[2], v2, v3, v4, v5 // v25 = t9a, v23 = t14a + dmbutterfly_h1 v21, v27, v1.h[3], v1.h[4], v2, v3, v4, v5 // v21 = t10a, v27 = t13a + dmbutterfly_h2 v29, v19, v1.h[5], v1.h[6], v2, v3, v4, v5 // v29 = t11a, v19 = t12a - dmbutterfly0 v2, v3, v27, v21, v2, v3, v16, v17, v30, v31 // v2 = t13a, v3 = t10a - dmbutterfly0 v28, v27, v29, v28, v21, v29, v16, v17, v30, v31 // v28 = t12, v27 = t11 + butterfly_8h v4, v28, v16, v28 // v4 = t0, v28 = t3 + butterfly_8h v5, v20, v24, v20 // v5 = t1, v20 = t2 + butterfly_8h v6, v26, v18, v26 // v6 = t4, v26 = t5 + butterfly_8h v7, v22, v30, v22 // v7 = t7, v22 = t6 + butterfly_8h v16, v25, v17, v25 // v16 = t8, v25 = t9 + butterfly_8h v24, v21, v29, v21 // v24 = t11, v21 = t10 + butterfly_8h v17, v27, v19, v27 // v17 = t12, v27 = t13 + butterfly_8h v29, v23, v31, v23 // v29 = t15, v23 = t14 - butterfly_8h v16, v31, v18, v25 // v16 = out[0], v31 = out[15] - butterfly_8h v17, v30, v19, v23 // v17 = out[1], v30 = out[14] - butterfly_8h_r v25, v22, v22, v24 // v25 = out[9], v22 = out[6] - butterfly_8h v23, v24, v7, v20 // v23 = out[7], v24 = out[8] - butterfly_8h v18, v29, v4, v2 // v18 = out[2], v29 = out[13] - butterfly_8h v19, v28, v5, v28 // v19 = out[3], v28 = out[12] - butterfly_8h v20, v27, v6, v27 // v20 = out[4], v27 = out[11] - butterfly_8h v21, v26, v26, v3 // v21 = out[5], v26 = out[10] - ret + dmbutterfly0 v22, v26, v22, v26, v2, v3, v18, v19, v30, v31 // v22 = t6a, v26 = t5a + dmbutterfly v23, v25, v0.h[1], v0.h[2], v18, v19, v30, v31 // v23 = t9a, v25 = t14a + dmbutterfly v27, v21, v0.h[1], v0.h[2], v18, v19, v30, v31, neg=1 // v27 = t13a, v21 = t10a + idct16_end +endfunc + +function idct16_quarter + dsmull_h v24, v25, v19, v1.h[6] + dsmull_h v4, v5, v17, v0.h[7] + dsmull_h v7, v6, v18, v0.h[4] + dsmull_h v30, v31, v18, v0.h[3] + neg v24.4s, v24.4s + neg v25.4s, v25.4s + dsmull_h v29, v28, v17, v1.h[0] + dsmull_h v26, v27, v19, v1.h[5] + dsmull_h v22, v23, v16, v0.h[0] + drshrn_h v24, v24, v25, #14 + drshrn_h v16, v4, v5, #14 + drshrn_h v7, v7, v6, #14 + drshrn_h v6, v30, v31, #14 + drshrn_h v29, v29, v28, #14 + drshrn_h v17, v26, v27, #14 + drshrn_h v28, v22, v23, #14 + + dmbutterfly_l v20, v21, v22, v23, v17, v24, v0.h[1], v0.h[2] + dmbutterfly_l v18, v19, v30, v31, v29, v16, v0.h[1], v0.h[2] + neg v22.4s, v22.4s + neg v23.4s, v23.4s + drshrn_h v27, v20, v21, #14 + drshrn_h v21, v22, v23, #14 + drshrn_h v23, v18, v19, #14 + drshrn_h v25, v30, v31, #14 + mov v4.16b, v28.16b + mov v5.16b, v28.16b + dmbutterfly0 v22, v26, v7, v6, v18, v19, v30, v31 + mov v20.16b, v28.16b + idct16_end endfunc function iadst16 @@ -756,6 +865,13 @@ function ff_vp9_\txfm1\()_\txfm2\()_16x16_add_neon, export=1 .endif mov x9, #32 +.ifc \txfm1\()_\txfm2,idct_idct + cmp w3, #10 + b.le idct16x16_quarter_add_neon + cmp w3, #38 + b.le idct16x16_half_add_neon +.endif + .irp i, 0, 8 add x0, sp, #(\i*32) .ifc \txfm1\()_\txfm2,idct_idct @@ -812,6 +928,116 @@ itxfm_func16x16 iadst, idct itxfm_func16x16 idct, iadst itxfm_func16x16 iadst, iadst +function idct16_1d_8x16_pass1_quarter_neon + mov x14, x30 + movi v2.8h, #0 +.irp i, 16, 17, 18, 19 + load_clear \i, x2, x9 +.endr + + bl idct16_quarter + + // Do two 8x8 transposes. Originally, v16-v31 contain the + // 16 rows. Afterwards, v16-v23 and v24-v31 contain the two + // transposed 8x8 blocks. + transpose_8x8H v16, v17, v18, v19, v20, v21, v22, v23, v2, v3 + transpose_8x8H v24, v25, v26, v27, v28, v29, v30, v31, v2, v3 + + // Store the transposed 8x8 blocks horizontally. + // The first 8x8 block is kept in registers for the second pass, + // store the rest in the temp buffer. + // Since only a 4x4 part of the input was nonzero, this means that + // only 4 rows are nonzero after transposing, and the second pass + // only reads the topmost 4 rows. Therefore only store the topmost + // 4 rows. + add x0, x0, #16 +.irp i, 24, 25, 26, 27 + store \i, x0, x9 +.endr + br x14 +endfunc + +function idct16_1d_8x16_pass2_quarter_neon + mov x14, x30 + cbz x3, 1f +.irp i, 16, 17, 18, 19 + load \i, x2, x9 +.endr +1: + + add x3, x0, x1 + lsl x1, x1, #1 + bl idct16_quarter + + load_add_store v16.8h, v17.8h, v18.8h, v19.8h, v20.8h, v21.8h, v22.8h, v23.8h, v16.8b, v17.8b + load_add_store v24.8h, v25.8h, v26.8h, v27.8h, v28.8h, v29.8h, v30.8h, v31.8h, v16.8b, v17.8b + + br x14 +endfunc + +function idct16_1d_8x16_pass1_half_neon + mov x14, x30 + movi v2.8h, #0 +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + load_clear \i, x2, x9 +.endr + + bl idct16_half + + // Do two 8x8 transposes. Originally, v16-v31 contain the + // 16 rows. Afterwards, v16-v23 and v24-v31 contain the two + // transposed 8x8 blocks. + transpose_8x8H v16, v17, v18, v19, v20, v21, v22, v23, v2, v3 + transpose_8x8H v24, v25, v26, v27, v28, v29, v30, v31, v2, v3 + + // Store the transposed 8x8 blocks horizontally. + // The first 8x8 block is kept in registers for the second pass, + // store the rest in the temp buffer. + add x0, x0, #16 +.irp i, 24, 25, 26, 27, 28, 29, 30, 31 + store \i, x0, x9 +.endr + br x14 +endfunc + +function idct16_1d_8x16_pass2_half_neon + mov x14, x30 + cbz x3, 1f +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + load \i, x2, x9 +.endr +1: + + add x3, x0, x1 + lsl x1, x1, #1 + bl idct16_half + + load_add_store v16.8h, v17.8h, v18.8h, v19.8h, v20.8h, v21.8h, v22.8h, v23.8h, v16.8b, v17.8b + load_add_store v24.8h, v25.8h, v26.8h, v27.8h, v28.8h, v29.8h, v30.8h, v31.8h, v16.8b, v17.8b + + br x14 +endfunc + +.macro idct16_partial size +function idct16x16_\size\()_add_neon + add x0, sp, #(0*32) + add x2, x6, #(0*2) + bl idct16_1d_8x16_pass1_\size\()_neon +.irp i, 0, 8 + add x0, x4, #(\i) + mov x1, x5 + add x2, sp, #(\i*2) + mov x3, #\i + bl idct16_1d_8x16_pass2_\size\()_neon +.endr + + add sp, sp, #512 + br x15 +endfunc +.endm + +idct16_partial quarter +idct16_partial half function idct32x32_dc_add_neon movrel x4, idct_coeffs @@ -848,6 +1074,37 @@ function idct32x32_dc_add_neon ret endfunc +.macro idct32_end + butterfly_8h v16, v5, v4, v5 // v16 = t16a, v5 = t19a + butterfly_8h v17, v20, v23, v20 // v17 = t17, v20 = t18 + butterfly_8h v18, v6, v7, v6 // v18 = t23a, v6 = t20a + butterfly_8h v19, v21, v22, v21 // v19 = t22, v21 = t21 + butterfly_8h v4, v28, v28, v30 // v4 = t24a, v28 = t27a + butterfly_8h v23, v26, v25, v26 // v23 = t25, v26 = t26 + butterfly_8h v7, v3, v29, v31 // v7 = t31a, v3 = t28a + butterfly_8h v22, v27, v24, v27 // v22 = t30, v27 = t29 + + dmbutterfly v27, v20, v0.h[1], v0.h[2], v24, v25, v30, v31 // v27 = t18a, v20 = t29a + dmbutterfly v3, v5, v0.h[1], v0.h[2], v24, v25, v30, v31 // v3 = t19, v5 = t28 + dmbutterfly v28, v6, v0.h[1], v0.h[2], v24, v25, v30, v31, neg=1 // v28 = t27, v6 = t20 + dmbutterfly v26, v21, v0.h[1], v0.h[2], v24, v25, v30, v31, neg=1 // v26 = t26a, v21 = t21a + + butterfly_8h v31, v24, v7, v4 // v31 = t31, v24 = t24 + butterfly_8h v30, v25, v22, v23 // v30 = t30a, v25 = t25a + butterfly_8h_r v23, v16, v16, v18 // v23 = t23, v16 = t16 + butterfly_8h_r v22, v17, v17, v19 // v22 = t22a, v17 = t17a + butterfly_8h v18, v21, v27, v21 // v18 = t18, v21 = t21 + butterfly_8h_r v27, v28, v5, v28 // v27 = t27a, v28 = t28a + butterfly_8h v29, v26, v20, v26 // v29 = t29, v26 = t26 + butterfly_8h v19, v20, v3, v6 // v19 = t19a, v20 = t20 + + dmbutterfly0 v27, v20, v27, v20, v2, v3, v4, v5, v6, v7 // v27 = t27, v20 = t20 + dmbutterfly0 v26, v21, v26, v21, v2, v3, v4, v5, v6, v7 // v26 = t26a, v21 = t21a + dmbutterfly0 v25, v22, v25, v22, v2, v3, v4, v5, v6, v7 // v25 = t25, v22 = t22 + dmbutterfly0 v24, v23, v24, v23, v2, v3, v4, v5, v6, v7 // v24 = t24a, v23 = t23a + ret +.endm + function idct32_odd ld1 {v0.8h,v1.8h}, [x11] @@ -875,37 +1132,88 @@ function idct32_odd dmbutterfly v27, v20, v0.h[3], v0.h[4], v16, v17, v18, v19, neg=1 // v27 = t29a, v20 = t18a dmbutterfly v21, v26, v0.h[5], v0.h[6], v16, v17, v18, v19 // v21 = t21a, v26 = t26a dmbutterfly v25, v22, v0.h[5], v0.h[6], v16, v17, v18, v19, neg=1 // v25 = t25a, v22 = t22a + idct32_end +endfunc - butterfly_8h v16, v5, v4, v5 // v16 = t16a, v5 = t19a - butterfly_8h v17, v20, v23, v20 // v17 = t17, v20 = t18 - butterfly_8h v18, v6, v7, v6 // v18 = t23a, v6 = t20a - butterfly_8h v19, v21, v22, v21 // v19 = t22, v21 = t21 - butterfly_8h v4, v28, v28, v30 // v4 = t24a, v28 = t27a - butterfly_8h v23, v26, v25, v26 // v23 = t25, v26 = t26 - butterfly_8h v7, v3, v29, v31 // v7 = t31a, v3 = t28a - butterfly_8h v22, v27, v24, v27 // v22 = t30, v27 = t29 +function idct32_odd_half + ld1 {v0.8h,v1.8h}, [x11] - dmbutterfly v27, v20, v0.h[1], v0.h[2], v24, v25, v30, v31 // v27 = t18a, v20 = t29a - dmbutterfly v3, v5, v0.h[1], v0.h[2], v24, v25, v30, v31 // v3 = t19, v5 = t28 - dmbutterfly v28, v6, v0.h[1], v0.h[2], v24, v25, v30, v31, neg=1 // v28 = t27, v6 = t20 - dmbutterfly v26, v21, v0.h[1], v0.h[2], v24, v25, v30, v31, neg=1 // v26 = t26a, v21 = t21a + dmbutterfly_h1 v16, v31, v0.h[0], v0.h[1], v4, v5, v6, v7 // v16 = t16a, v31 = t31a + dmbutterfly_h2 v24, v23, v0.h[2], v0.h[3], v4, v5, v6, v7 // v24 = t17a, v23 = t30a + dmbutterfly_h1 v20, v27, v0.h[4], v0.h[5], v4, v5, v6, v7 // v20 = t18a, v27 = t29a + dmbutterfly_h2 v28, v19, v0.h[6], v0.h[7], v4, v5, v6, v7 // v28 = t19a, v19 = t28a + dmbutterfly_h1 v18, v29, v1.h[0], v1.h[1], v4, v5, v6, v7 // v18 = t20a, v29 = t27a + dmbutterfly_h2 v26, v21, v1.h[2], v1.h[3], v4, v5, v6, v7 // v26 = t21a, v21 = t26a + dmbutterfly_h1 v22, v25, v1.h[4], v1.h[5], v4, v5, v6, v7 // v22 = t22a, v25 = t25a + dmbutterfly_h2 v30, v17, v1.h[6], v1.h[7], v4, v5, v6, v7 // v30 = t23a, v17 = t24a - butterfly_8h v31, v24, v7, v4 // v31 = t31, v24 = t24 - butterfly_8h v30, v25, v22, v23 // v30 = t30a, v25 = t25a - butterfly_8h_r v23, v16, v16, v18 // v23 = t23, v16 = t16 - butterfly_8h_r v22, v17, v17, v19 // v22 = t22a, v17 = t17a - butterfly_8h v18, v21, v27, v21 // v18 = t18, v21 = t21 - butterfly_8h_r v27, v28, v5, v28 // v27 = t27a, v28 = t28a - butterfly_8h v29, v26, v20, v26 // v29 = t29, v26 = t26 - butterfly_8h v19, v20, v3, v6 // v19 = t19a, v20 = t20 + ld1 {v0.8h}, [x10] - dmbutterfly0 v27, v20, v27, v20, v2, v3, v4, v5, v6, v7 // v27 = t27, v20 = t20 - dmbutterfly0 v26, v21, v26, v21, v2, v3, v4, v5, v6, v7 // v26 = t26a, v21 = t21a - dmbutterfly0 v25, v22, v25, v22, v2, v3, v4, v5, v6, v7 // v25 = t25, v22 = t22 - dmbutterfly0 v24, v23, v24, v23, v2, v3, v4, v5, v6, v7 // v24 = t24a, v23 = t23a - ret + butterfly_8h v4, v24, v16, v24 // v4 = t16, v24 = t17 + butterfly_8h v5, v20, v28, v20 // v5 = t19, v20 = t18 + butterfly_8h v6, v26, v18, v26 // v6 = t20, v26 = t21 + butterfly_8h v7, v22, v30, v22 // v7 = t23, v22 = t22 + butterfly_8h v28, v25, v17, v25 // v28 = t24, v25 = t25 + butterfly_8h v30, v21, v29, v21 // v30 = t27, v21 = t26 + butterfly_8h v29, v23, v31, v23 // v29 = t31, v23 = t30 + butterfly_8h v31, v27, v19, v27 // v31 = t28, v27 = t29 + + dmbutterfly v23, v24, v0.h[3], v0.h[4], v16, v17, v18, v19 // v23 = t17a, v24 = t30a + dmbutterfly v27, v20, v0.h[3], v0.h[4], v16, v17, v18, v19, neg=1 // v27 = t29a, v20 = t18a + dmbutterfly v21, v26, v0.h[5], v0.h[6], v16, v17, v18, v19 // v21 = t21a, v26 = t26a + dmbutterfly v25, v22, v0.h[5], v0.h[6], v16, v17, v18, v19, neg=1 // v25 = t25a, v22 = t22a + idct32_end endfunc +function idct32_odd_quarter + ld1 {v0.8h,v1.8h}, [x11] + + dsmull_h v4, v5, v16, v0.h[0] + dsmull_h v28, v29, v19, v0.h[7] + dsmull_h v30, v31, v16, v0.h[1] + dsmull_h v22, v23, v17, v1.h[6] + dsmull_h v7, v6, v17, v1.h[7] + dsmull_h v26, v27, v19, v0.h[6] + dsmull_h v20, v21, v18, v1.h[0] + dsmull_h v24, v25, v18, v1.h[1] + + ld1 {v0.8h}, [x10] + + neg v28.4s, v28.4s + neg v29.4s, v29.4s + neg v7.4s, v7.4s + neg v6.4s, v6.4s + + drshrn_h v4, v4, v5, #14 + drshrn_h v5, v28, v29, #14 + drshrn_h v29, v30, v31, #14 + drshrn_h v28, v22, v23, #14 + drshrn_h v7, v7, v6, #14 + drshrn_h v31, v26, v27, #14 + drshrn_h v6, v20, v21, #14 + drshrn_h v30, v24, v25, #14 + + dmbutterfly_l v16, v17, v18, v19, v29, v4, v0.h[3], v0.h[4] + dmbutterfly_l v27, v26, v20, v21, v31, v5, v0.h[3], v0.h[4] + drshrn_h v23, v16, v17, #14 + drshrn_h v24, v18, v19, #14 + neg v20.4s, v20.4s + neg v21.4s, v21.4s + drshrn_h v27, v27, v26, #14 + drshrn_h v20, v20, v21, #14 + dmbutterfly_l v16, v17, v18, v19, v30, v6, v0.h[5], v0.h[6] + drshrn_h v21, v16, v17, #14 + drshrn_h v26, v18, v19, #14 + dmbutterfly_l v16, v17, v18, v19, v28, v7, v0.h[5], v0.h[6] + drshrn_h v25, v16, v17, #14 + neg v18.4s, v18.4s + neg v19.4s, v19.4s + drshrn_h v22, v18, v19, #14 + + idct32_end +endfunc + +.macro idct32_funcs suffix // Do an 32-point IDCT of a 8x32 slice out of a 32x32 matrix. // The 32-point IDCT can be decomposed into two 16-point IDCTs; // a normal IDCT16 with every other input component (the even ones, with @@ -917,19 +1225,30 @@ endfunc // x9 = double input stride // x10 = idct_coeffs // x11 = idct_coeffs + 32 -function idct32_1d_8x32_pass1_neon +function idct32_1d_8x32_pass1\suffix\()_neon mov x14, x30 ld1 {v0.8h,v1.8h}, [x10] - movi v4.8h, #0 + movi v2.8h, #0 // v16 = IN(0), v17 = IN(2) ... v31 = IN(30) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 - ld1 {v\i\().8h}, [x2] - st1 {v4.8h}, [x2], x9 + load_clear \i, x2, x9 .endr +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + load_clear \i, x2, x9 +.endr +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + load_clear \i, x2, x9 +.endr +.endif - bl idct16 + bl idct16\suffix // Do two 8x8 transposes. Originally, v16-v31 contain the // 16 rows. Afterwards, v16-v23 and v24-v31 contain the @@ -964,17 +1283,36 @@ function idct32_1d_8x32_pass1_neon // Move x2 back to the start of the input, and move // to the first odd row +.ifb \suffix sub x2, x2, x9, lsl #4 +.endif +.ifc \suffix,_quarter + sub x2, x2, x9, lsl #2 +.endif +.ifc \suffix,_half + sub x2, x2, x9, lsl #3 +.endif add x2, x2, #64 - movi v4.8h, #0 + movi v2.8h, #0 // v16 = IN(1), v17 = IN(3) ... v31 = IN(31) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 - ld1 {v\i\().8h}, [x2] - st1 {v4.8h}, [x2], x9 + load_clear \i, x2, x9 +.endr +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + load_clear \i, x2, x9 +.endr +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + load_clear \i, x2, x9 .endr +.endif - bl idct32_odd + bl idct32_odd\suffix transpose_8x8H v31, v30, v29, v28, v27, v26, v25, v24, v2, v3 transpose_8x8H v23, v22, v21, v20, v19, v18, v17, v16, v2, v3 @@ -1023,33 +1361,61 @@ endfunc // x9 = double temp buffer stride // x10 = idct_coeffs // x11 = idct_coeffs + 32 -function idct32_1d_8x32_pass2_neon +function idct32_1d_8x32_pass2\suffix\()_neon mov x14, x30 ld1 {v0.8h,v1.8h}, [x10] // v16 = IN(0), v17 = IN(2) ... v31 = IN(30) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 - ld1 {v\i\().8h}, [x2], x9 + load \i, x2, x9 .endr sub x2, x2, x9, lsl #4 +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + load \i, x2, x9 +.endr + sub x2, x2, x9, lsl #2 +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + load \i, x2, x9 +.endr + sub x2, x2, x9, lsl #3 +.endif - bl idct16 + bl idct16\suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 - st1 {v\i\().8h}, [x2], x9 + store \i, x2, x9 .endr sub x2, x2, x9, lsl #4 add x2, x2, #64 // v16 = IN(1), v17 = IN(3) ... v31 = IN(31) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 - ld1 {v\i\().8h}, [x2], x9 + load \i, x2, x9 .endr sub x2, x2, x9, lsl #4 +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + load \i, x2, x9 +.endr + sub x2, x2, x9, lsl #2 +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + load \i, x2, x9 +.endr + sub x2, x2, x9, lsl #3 +.endif sub x2, x2, #64 - bl idct32_odd + bl idct32_odd\suffix .macro load_acc_store a, b, c, d, neg=0 .if \neg == 0 @@ -1105,6 +1471,11 @@ function idct32_1d_8x32_pass2_neon .purgem load_acc_store br x14 endfunc +.endm + +idct32_funcs +idct32_funcs _quarter +idct32_funcs _half const min_eob_idct_idct_32, align=4 .short 0, 34, 135, 336 @@ -1135,6 +1506,11 @@ function ff_vp9_idct_idct_32x32_add_neon, export=1 mov x9, #128 neg x7, x9 + cmp w3, #34 + b.le idct32x32_quarter_add_neon + cmp w3, #135 + b.le idct32x32_half_add_neon + .irp i, 0, 8, 16, 24 add x0, sp, #(\i*64) .if \i > 0 @@ -1177,3 +1553,34 @@ function ff_vp9_idct_idct_32x32_add_neon, export=1 br x15 endfunc + +.macro idct32_partial size +function idct32x32_\size\()_add_neon + add x0, sp, #(0*64) + add x2, x6, #(0*2) + bl idct32_1d_8x32_pass1_\size\()_neon +.ifc \size,half + add x0, sp, #(8*64) + add x2, x6, #(8*2) + bl idct32_1d_8x32_pass1_\size\()_neon +.endif +.irp i, 0, 8, 16, 24 + add x0, x4, #(\i) + mov x1, x5 + add x2, sp, #(\i*2) + bl idct32_1d_8x32_pass2_\size\()_neon +.endr + + add sp, sp, #2048 + + ldp d8, d9, [sp], 0x10 + ldp d10, d11, [sp], 0x10 + ldp d12, d13, [sp], 0x10 + ldp d14, d15, [sp], 0x10 + + br x15 +endfunc +.endm + +idct32_partial quarter +idct32_partial half From 3933b86bb93aca47f29fbd493075b0f110c1e3f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 3 Jan 2017 16:38:56 +0200 Subject: [PATCH 0881/3374] arm: vp9itxfm: Share instructions for loading idct coeffs in the 8x8 function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index 167d5178e43b9..3d0b0fab2e173 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -412,13 +412,12 @@ function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_neon, export=1 .ifc \txfm1\()_\txfm2,idct_idct movrel r12, idct_coeffs vpush {q4-q5} - vld1.16 {q0}, [r12,:128] .else movrel r12, iadst8_coeffs vld1.16 {q1}, [r12,:128]! vpush {q4-q7} - vld1.16 {q0}, [r12,:128] .endif + vld1.16 {q0}, [r12,:128] vmov.i16 q2, #0 vmov.i16 q3, #0 From 4da4b2b87f08a1331650c7e36eb7d4029a160776 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 3 Jan 2017 16:39:41 +0200 Subject: [PATCH 0882/3374] aarch64: vp9itxfm: Share instructions for loading idct coeffs in the 8x8 function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index c954d1a5e108d..a9c7626e65e2f 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -379,12 +379,11 @@ function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_neon, export=1 // idct, so those always need to be loaded. .ifc \txfm1\()_\txfm2,idct_idct movrel x4, idct_coeffs - ld1 {v0.8h}, [x4] .else movrel x4, iadst8_coeffs ld1 {v1.8h}, [x4], #16 - ld1 {v0.8h}, [x4] .endif + ld1 {v0.8h}, [x4] movi v2.16b, #0 movi v3.16b, #0 From ed8d293306e12c9b79022d37d39f48825ce7f2fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 3 Jan 2017 14:55:46 +0200 Subject: [PATCH 0883/3374] aarch64: vp9itxfm: Use a single lane ld1 instead of ld1r where possible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ld1r is a leftover from the arm version, where this trick is beneficial on some cores. Use a single-lane load where we don't need the semantics of ld1r. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index a9c7626e65e2f..e7b88364f16f7 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -255,7 +255,7 @@ function ff_vp9_\txfm1\()_\txfm2\()_4x4_add_neon, export=1 cmp w3, #1 b.ne 1f // DC-only for idct/idct - ld1r {v2.4h}, [x2] + ld1 {v2.h}[0], [x2] smull v2.4s, v2.4h, v0.h[0] rshrn v2.4h, v2.4s, #14 smull v2.4s, v2.4h, v0.h[0] @@ -287,8 +287,8 @@ function ff_vp9_\txfm1\()_\txfm2\()_4x4_add_neon, export=1 \txfm2\()4 v4, v5, v6, v7 2: - ld1r {v0.2s}, [x0], x1 - ld1r {v1.2s}, [x0], x1 + ld1 {v0.s}[0], [x0], x1 + ld1 {v1.s}[0], [x0], x1 .ifnc \txfm1,iwht srshr v4.4h, v4.4h, #4 srshr v5.4h, v5.4h, #4 @@ -297,8 +297,8 @@ function ff_vp9_\txfm1\()_\txfm2\()_4x4_add_neon, export=1 .endif uaddw v4.8h, v4.8h, v0.8b uaddw v5.8h, v5.8h, v1.8b - ld1r {v2.2s}, [x0], x1 - ld1r {v3.2s}, [x0], x1 + ld1 {v2.s}[0], [x0], x1 + ld1 {v3.s}[0], [x0], x1 sqxtun v0.8b, v4.8h sqxtun v1.8b, v5.8h sub x0, x0, x1, lsl #2 @@ -394,7 +394,7 @@ function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_neon, export=1 cmp w3, #1 b.ne 1f // DC-only for idct/idct - ld1r {v2.4h}, [x2] + ld1 {v2.h}[0], [x2] smull v2.4s, v2.4h, v0.h[0] rshrn v2.4h, v2.4s, #14 smull v2.4s, v2.4h, v0.h[0] @@ -485,7 +485,7 @@ function idct16x16_dc_add_neon movi v1.4h, #0 - ld1r {v2.4h}, [x2] + ld1 {v2.h}[0], [x2] smull v2.4s, v2.4h, v0.h[0] rshrn v2.4h, v2.4s, #14 smull v2.4s, v2.4h, v0.h[0] @@ -1044,7 +1044,7 @@ function idct32x32_dc_add_neon movi v1.4h, #0 - ld1r {v2.4h}, [x2] + ld1 {v2.h}[0], [x2] smull v2.4s, v2.4h, v0.h[0] rshrn v2.4h, v2.4s, #14 smull v2.4s, v2.4h, v0.h[0] From 3dd7827258ddaa2e51085d0c677d6f3b1be3572f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 3 Jan 2017 16:46:17 +0200 Subject: [PATCH 0884/3374] aarch64: vp9itxfm: Use the right lane sizes in 8x8 for improved readability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index e7b88364f16f7..7582081bd8865 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -385,10 +385,10 @@ function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_neon, export=1 .endif ld1 {v0.8h}, [x4] - movi v2.16b, #0 - movi v3.16b, #0 - movi v4.16b, #0 - movi v5.16b, #0 + movi v2.8h, #0 + movi v3.8h, #0 + movi v4.8h, #0 + movi v5.8h, #0 .ifc \txfm1\()_\txfm2,idct_idct cmp w3, #1 @@ -411,11 +411,11 @@ function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_neon, export=1 b 2f .endif 1: - ld1 {v16.16b,v17.16b,v18.16b,v19.16b}, [x2], #64 - ld1 {v20.16b,v21.16b,v22.16b,v23.16b}, [x2], #64 + ld1 {v16.8h,v17.8h,v18.8h,v19.8h}, [x2], #64 + ld1 {v20.8h,v21.8h,v22.8h,v23.8h}, [x2], #64 sub x2, x2, #128 - st1 {v2.16b,v3.16b,v4.16b,v5.16b}, [x2], #64 - st1 {v2.16b,v3.16b,v4.16b,v5.16b}, [x2], #64 + st1 {v2.8h,v3.8h,v4.8h,v5.8h}, [x2], #64 + st1 {v2.8h,v3.8h,v4.8h,v5.8h}, [x2], #64 \txfm1\()8 From 8476eb0d3ab1f7a52317b23346646389c08fb57a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 3 Jan 2017 23:11:51 +0200 Subject: [PATCH 0885/3374] aarch64: vp9itxfm: Update a comment to refer to a register with a different name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index 7582081bd8865..81027202f8ef1 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -41,8 +41,8 @@ const iadst16_coeffs, align=4 .short 11003, 12140, 8423, 14053, 5520, 15426, 2404, 16207 endconst -// out1 = ((in1 + in2) * d0[0] + (1 << 13)) >> 14 -// out2 = ((in1 - in2) * d0[0] + (1 << 13)) >> 14 +// out1 = ((in1 + in2) * v0[0] + (1 << 13)) >> 14 +// out2 = ((in1 - in2) * v0[0] + (1 << 13)) >> 14 // in/out are .8h registers; this can do with 4 temp registers, but is // more efficient if 6 temp registers are available. .macro dmbutterfly0 out1, out2, in1, in2, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, neg=0 From 0c0b87f12d48d4e7f0d3d13f9345e828a3a5ea32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 3 Jan 2017 16:11:56 +0200 Subject: [PATCH 0886/3374] aarch64: vp9itxfm: Fix incorrect vertical alignment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index 81027202f8ef1..a199e9c6030f9 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -225,7 +225,7 @@ endconst add v21.4s, v17.4s, v19.4s rshrn \c0\().4h, v20.4s, #14 add v16.4s, v16.4s, v17.4s - rshrn \c1\().4h, v21.4s, #14 + rshrn \c1\().4h, v21.4s, #14 sub v16.4s, v16.4s, v19.4s rshrn \c2\().4h, v18.4s, #14 rshrn \c3\().4h, v16.4s, #14 @@ -1313,8 +1313,8 @@ function idct32_1d_8x32_pass1\suffix\()_neon bl idct32_odd\suffix - transpose_8x8H v31, v30, v29, v28, v27, v26, v25, v24, v2, v3 - transpose_8x8H v23, v22, v21, v20, v19, v18, v17, v16, v2, v3 + transpose_8x8H v31, v30, v29, v28, v27, v26, v25, v24, v2, v3 + transpose_8x8H v23, v22, v21, v20, v19, v18, v17, v16, v2, v3 // Store the registers a, b horizontally, // adding into the output first, and the mirrored, From 77c23704c769168e4210956314775a1931f6aa0b Mon Sep 17 00:00:00 2001 From: Derek Buitenhuis Date: Wed, 8 Feb 2017 14:42:16 +0000 Subject: [PATCH 0887/3374] avcodec: Mark some codecs with threadsafe init as such Signed-off-by: Derek Buitenhuis Signed-off-by: Luca Barbato --- libavcodec/aasc.c | 1 + libavcodec/aic.c | 1 + libavcodec/anm.c | 1 + libavcodec/ansi.c | 1 + libavcodec/aura.c | 1 + libavcodec/avs.c | 1 + libavcodec/bethsoftvideo.c | 1 + libavcodec/bfi.c | 1 + libavcodec/bmvvideo.c | 1 + libavcodec/c93.c | 1 + libavcodec/cllc.c | 1 + libavcodec/cyuv.c | 2 ++ libavcodec/fraps.c | 1 + libavcodec/lcldec.c | 2 ++ libavcodec/pngdec.c | 1 + libavcodec/r210dec.c | 2 ++ libavcodec/utvideodec.c | 1 + libavcodec/vble.c | 1 + libavcodec/zerocodec.c | 1 + 19 files changed, 22 insertions(+) diff --git a/libavcodec/aasc.c b/libavcodec/aasc.c index e65ea397b8a59..c4800f0906c2d 100644 --- a/libavcodec/aasc.c +++ b/libavcodec/aasc.c @@ -119,4 +119,5 @@ AVCodec ff_aasc_decoder = { .close = aasc_decode_end, .decode = aasc_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/aic.c b/libavcodec/aic.c index ed0be44629e7f..de9d7de91bee5 100644 --- a/libavcodec/aic.c +++ b/libavcodec/aic.c @@ -488,4 +488,5 @@ AVCodec ff_aic_decoder = { .decode = aic_decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, .init_thread_copy = ONLY_IF_THREADS_ENABLED(aic_decode_init), + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/anm.c b/libavcodec/anm.c index b70d220c9a27c..af8d843f6f5e8 100644 --- a/libavcodec/anm.c +++ b/libavcodec/anm.c @@ -199,4 +199,5 @@ AVCodec ff_anm_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/ansi.c b/libavcodec/ansi.c index 65e2e16faef9e..0bdbdbe071b05 100644 --- a/libavcodec/ansi.c +++ b/libavcodec/ansi.c @@ -451,4 +451,5 @@ AVCodec ff_ansi_decoder = { .close = decode_close, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/aura.c b/libavcodec/aura.c index a1ef6f8d10b8c..6a03f8f572f32 100644 --- a/libavcodec/aura.c +++ b/libavcodec/aura.c @@ -107,4 +107,5 @@ AVCodec ff_aura2_decoder = { .init = aura_decode_init, .decode = aura_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/avs.c b/libavcodec/avs.c index 959f570b389e6..edd91efbbd973 100644 --- a/libavcodec/avs.c +++ b/libavcodec/avs.c @@ -186,4 +186,5 @@ AVCodec ff_avs_decoder = { .decode = avs_decode_frame, .close = avs_decode_end, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/bethsoftvideo.c b/libavcodec/bethsoftvideo.c index 11e2cfaab2720..61f098bc0925d 100644 --- a/libavcodec/bethsoftvideo.c +++ b/libavcodec/bethsoftvideo.c @@ -164,4 +164,5 @@ AVCodec ff_bethsoftvid_decoder = { .close = bethsoftvid_decode_end, .decode = bethsoftvid_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/bfi.c b/libavcodec/bfi.c index 8335e9d12596e..0ce73b1754feb 100644 --- a/libavcodec/bfi.c +++ b/libavcodec/bfi.c @@ -181,4 +181,5 @@ AVCodec ff_bfi_decoder = { .close = bfi_decode_close, .decode = bfi_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/bmvvideo.c b/libavcodec/bmvvideo.c index 4fb42f0f5c2fd..698bc56871b01 100644 --- a/libavcodec/bmvvideo.c +++ b/libavcodec/bmvvideo.c @@ -289,4 +289,5 @@ AVCodec ff_bmv_video_decoder = { .init = decode_init, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/c93.c b/libavcodec/c93.c index 18df9586d0a9a..e75148328ed5f 100644 --- a/libavcodec/c93.c +++ b/libavcodec/c93.c @@ -261,4 +261,5 @@ AVCodec ff_c93_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/cllc.c b/libavcodec/cllc.c index bac2b730e1b90..3c476f71f0014 100644 --- a/libavcodec/cllc.c +++ b/libavcodec/cllc.c @@ -488,4 +488,5 @@ AVCodec ff_cllc_decoder = { .decode = cllc_decode_frame, .close = cllc_decode_close, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/cyuv.c b/libavcodec/cyuv.c index 86f7aacb654af..2c4f98d3f9fe9 100644 --- a/libavcodec/cyuv.c +++ b/libavcodec/cyuv.c @@ -173,6 +173,7 @@ AVCodec ff_aura_decoder = { .init = cyuv_decode_init, .decode = cyuv_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif @@ -186,5 +187,6 @@ AVCodec ff_cyuv_decoder = { .init = cyuv_decode_init, .decode = cyuv_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c index fd1dcb7b4a7b8..4620ec10db6f8 100644 --- a/libavcodec/fraps.c +++ b/libavcodec/fraps.c @@ -383,4 +383,5 @@ AVCodec ff_fraps_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c index ba608f908d72e..dffc20a811948 100644 --- a/libavcodec/lcldec.c +++ b/libavcodec/lcldec.c @@ -617,6 +617,7 @@ AVCodec ff_mszh_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif @@ -631,5 +632,6 @@ AVCodec ff_zlib_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index d59409764d442..927248f2e3464 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -708,4 +708,5 @@ AVCodec ff_png_decoder = { .close = png_dec_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1 /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/r210dec.c b/libavcodec/r210dec.c index f168fd3bfd120..cfe548465d59e 100644 --- a/libavcodec/r210dec.c +++ b/libavcodec/r210dec.c @@ -90,6 +90,7 @@ AVCodec ff_r210_decoder = { .init = decode_init, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif #if CONFIG_R10K_DECODER @@ -101,5 +102,6 @@ AVCodec ff_r10k_decoder = { .init = decode_init, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; #endif diff --git a/libavcodec/utvideodec.c b/libavcodec/utvideodec.c index 1f5b02f560484..381b4f74035f5 100644 --- a/libavcodec/utvideodec.c +++ b/libavcodec/utvideodec.c @@ -564,4 +564,5 @@ AVCodec ff_utvideo_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/vble.c b/libavcodec/vble.c index 75db27ff09e28..c3451cb9ed517 100644 --- a/libavcodec/vble.c +++ b/libavcodec/vble.c @@ -208,4 +208,5 @@ AVCodec ff_vble_decoder = { .close = vble_decode_close, .decode = vble_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/zerocodec.c b/libavcodec/zerocodec.c index 1419e84a3415a..4448e85f4b5eb 100644 --- a/libavcodec/zerocodec.c +++ b/libavcodec/zerocodec.c @@ -151,4 +151,5 @@ AVCodec ff_zerocodec_decoder = { .decode = zerocodec_decode_frame, .close = zerocodec_decode_close, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; From a52976c0feab6e86138983c248bd01fa45cdda69 Mon Sep 17 00:00:00 2001 From: Timo Rothenpieler Date: Mon, 6 Feb 2017 18:04:39 -0800 Subject: [PATCH 0888/3374] nvenc: make gpu indices independent of supported capabilities Do not allocate a CUDA context for every available gpu. Signed-off-by: Luca Barbato --- libavcodec/nvenc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index fe7b7f40f0d78..90b9d1a62aadd 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -359,6 +359,9 @@ static int nvenc_check_device(AVCodecContext *avctx, int idx) if (((major << 4) | minor) < NVENC_CAP) goto fail; + if (ctx->device != idx && ctx->device != ANY_DEVICE) + return -1; + ret = nvel->cu_ctx_create(&ctx->cu_context_internal, 0, cu_device); if (ret != CUDA_SUCCESS) goto fail; @@ -377,7 +380,7 @@ static int nvenc_check_device(AVCodecContext *avctx, int idx) av_log(avctx, loglevel, "supports NVENC\n"); - if (ctx->device == cu_device || ctx->device == ANY_DEVICE) + if (ctx->device == idx || ctx->device == ANY_DEVICE) return 0; fail3: From bc2589763042dc2384b724b203ec778f35bcebad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 10 Feb 2017 09:20:39 +0200 Subject: [PATCH 0889/3374] utvideodec: Add a missing include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was missing from 77c23704c76, fixing building. Signed-off-by: Martin Storsjö --- libavcodec/utvideodec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/utvideodec.c b/libavcodec/utvideodec.c index 381b4f74035f5..808e3be0676d5 100644 --- a/libavcodec/utvideodec.c +++ b/libavcodec/utvideodec.c @@ -33,6 +33,7 @@ #include "bitstream.h" #include "bswapdsp.h" #include "bytestream.h" +#include "internal.h" #include "thread.h" #include "utvideo.h" From b6093e8c72a80710f086c678ab0730cf30953b5c Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Thu, 9 Feb 2017 23:27:41 +0100 Subject: [PATCH 0890/3374] hlsenc: Correctly write down all 16 bytes in hex Signed-off-by: Luca Barbato --- libavformat/hlsenc.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 05c9adb959ff8..7aef02b80549d 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -102,11 +102,12 @@ static void free_encryption(AVFormatContext *s) av_freep(&hls->key_basename); } -static int dict_set_bin(AVDictionary **dict, const char *key, uint8_t *buf) +static int dict_set_bin(AVDictionary **dict, const char *key, + uint8_t *buf, size_t len) { char hex[33]; - ff_data_to_hex(hex, buf, sizeof(buf), 0); + ff_data_to_hex(hex, buf, len, 0); hex[32] = '\0'; return av_dict_set(dict, key, hex, 0); @@ -136,7 +137,7 @@ static int setup_encryption(AVFormatContext *s) return AVERROR(EINVAL); } - if ((ret = dict_set_bin(&hls->enc_opts, "key", hls->key)) < 0) + if ((ret = dict_set_bin(&hls->enc_opts, "key", hls->key, hls->key_len)) < 0) return ret; k = hls->key; } else { @@ -145,7 +146,7 @@ static int setup_encryption(AVFormatContext *s) return ret; } - if ((ret = dict_set_bin(&hls->enc_opts, "key", buf)) < 0) + if ((ret = dict_set_bin(&hls->enc_opts, "key", buf, sizeof(buf))) < 0) return ret; k = buf; } @@ -158,7 +159,7 @@ static int setup_encryption(AVFormatContext *s) return AVERROR(EINVAL); } - if ((ret = dict_set_bin(&hls->enc_opts, "iv", hls->iv)) < 0) + if ((ret = dict_set_bin(&hls->enc_opts, "iv", hls->iv, hls->iv_len)) < 0) return ret; } From ce6d72d10776b03c6780d4aa676414ce002285d4 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Tue, 7 Feb 2017 10:01:41 -0500 Subject: [PATCH 0891/3374] imgutils: Document av_image_get_buffer_size() --- libavutil/imgutils.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libavutil/imgutils.h b/libavutil/imgutils.h index 67063a2947072..fafabc48caf7d 100644 --- a/libavutil/imgutils.h +++ b/libavutil/imgutils.h @@ -169,7 +169,11 @@ int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4], * Return the size in bytes of the amount of data required to store an * image with the given parameters. * - * @param[in] align the assumed linesize alignment + * @param pix_fmt the pixel format of the image + * @param width the width of the image in pixels + * @param height the height of the image in pixels + * @param align the assumed linesize alignment + * @return the buffer size in bytes, a negative error code in case of failure */ int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align); From 53ea595eec984e3109310e8bb7ff4b5786d91057 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Fri, 3 Feb 2017 13:05:27 +0100 Subject: [PATCH 0892/3374] mov: Rework stsc index validation In order to avoid potential integer overflow change the comparison and make sure to use the same unsigned type for both elements. --- libavformat/isom.h | 2 +- libavformat/mov.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libavformat/isom.h b/libavformat/isom.h index 85b876106ff5d..8cc5ab744df83 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -111,7 +111,7 @@ typedef struct MOVStreamContext { MOVStts *ctts_data; unsigned int stsc_count; MOVStsc *stsc_data; - int stsc_index; + unsigned int stsc_index; int stsc_sample; unsigned int stps_count; unsigned *stps_data; ///< partial sync sample for mpeg-2 open gop diff --git a/libavformat/mov.c b/libavformat/mov.c index 2810960e878d7..11bcff035c89b 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1983,13 +1983,13 @@ static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; } -static inline int mov_stsc_index_valid(int index, int count) +static inline int mov_stsc_index_valid(unsigned int index, unsigned int count) { - return index + 1 < count; + return index < count - 1; } /* Compute the samples value for the stsc entry at the given index. */ -static inline int mov_get_stsc_samples(MOVStreamContext *sc, int index) +static inline int mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index) { int chunk_count; @@ -3982,7 +3982,7 @@ static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, { MOVStreamContext *sc = st->priv_data; int sample, time_sample; - int i; + unsigned int i; sample = av_index_search_timestamp(st, timestamp, flags); av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample); From 5e0c2158fbc774f87d3ce4b7b950ba4d42c4a7b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 17 Dec 2016 00:55:41 +0200 Subject: [PATCH 0893/3374] aarch64: vp9mc: Simplify the extmla macro parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fold the field lengths into the macro. This makes the macro invocations much more readable, when the lines are shorter. This also makes it easier to use only half the registers within the macro. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9mc_neon.S | 50 ++++++++++++++++----------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/libavcodec/aarch64/vp9mc_neon.S b/libavcodec/aarch64/vp9mc_neon.S index c1f1876fce5b9..99f1809270938 100644 --- a/libavcodec/aarch64/vp9mc_neon.S +++ b/libavcodec/aarch64/vp9mc_neon.S @@ -193,41 +193,41 @@ endfunc // for size >= 16), and multiply-accumulate into dst1 and dst3 (or // dst1-dst2 and dst3-dst4 for size >= 16) .macro extmla dst1, dst2, dst3, dst4, src1, src2, src3, src4, src5, src6, offset, size - ext v20.16b, \src1, \src2, #(2*\offset) - ext v22.16b, \src4, \src5, #(2*\offset) + ext v20.16b, \src1\().16b, \src2\().16b, #(2*\offset) + ext v22.16b, \src4\().16b, \src5\().16b, #(2*\offset) .if \size >= 16 - mla \dst1, v20.8h, v0.h[\offset] - ext v21.16b, \src2, \src3, #(2*\offset) - mla \dst3, v22.8h, v0.h[\offset] - ext v23.16b, \src5, \src6, #(2*\offset) - mla \dst2, v21.8h, v0.h[\offset] - mla \dst4, v23.8h, v0.h[\offset] + mla \dst1\().8h, v20.8h, v0.h[\offset] + ext v21.16b, \src2\().16b, \src3\().16b, #(2*\offset) + mla \dst3\().8h, v22.8h, v0.h[\offset] + ext v23.16b, \src5\().16b, \src6\().16b, #(2*\offset) + mla \dst2\().8h, v21.8h, v0.h[\offset] + mla \dst4\().8h, v23.8h, v0.h[\offset] .else - mla \dst1, v20.8h, v0.h[\offset] - mla \dst3, v22.8h, v0.h[\offset] + mla \dst1\().8h, v20.8h, v0.h[\offset] + mla \dst3\().8h, v22.8h, v0.h[\offset] .endif .endm // The same as above, but don't accumulate straight into the // destination, but use a temp register and accumulate with saturation. .macro extmulqadd dst1, dst2, dst3, dst4, src1, src2, src3, src4, src5, src6, offset, size - ext v20.16b, \src1, \src2, #(2*\offset) - ext v22.16b, \src4, \src5, #(2*\offset) + ext v20.16b, \src1\().16b, \src2\().16b, #(2*\offset) + ext v22.16b, \src4\().16b, \src5\().16b, #(2*\offset) .if \size >= 16 mul v20.8h, v20.8h, v0.h[\offset] - ext v21.16b, \src2, \src3, #(2*\offset) + ext v21.16b, \src2\().16b, \src3\().16b, #(2*\offset) mul v22.8h, v22.8h, v0.h[\offset] - ext v23.16b, \src5, \src6, #(2*\offset) + ext v23.16b, \src5\().16b, \src6\().16b, #(2*\offset) mul v21.8h, v21.8h, v0.h[\offset] mul v23.8h, v23.8h, v0.h[\offset] .else mul v20.8h, v20.8h, v0.h[\offset] mul v22.8h, v22.8h, v0.h[\offset] .endif - sqadd \dst1, \dst1, v20.8h - sqadd \dst3, \dst3, v22.8h + sqadd \dst1\().8h, \dst1\().8h, v20.8h + sqadd \dst3\().8h, \dst3\().8h, v22.8h .if \size >= 16 - sqadd \dst2, \dst2, v21.8h - sqadd \dst4, \dst4, v23.8h + sqadd \dst2\().8h, \dst2\().8h, v21.8h + sqadd \dst4\().8h, \dst4\().8h, v23.8h .endif .endm @@ -292,13 +292,13 @@ function \type\()_8tap_\size\()h_\idx1\idx2 mul v2.8h, v5.8h, v0.h[0] mul v25.8h, v17.8h, v0.h[0] .endif - extmla v1.8h, v2.8h, v24.8h, v25.8h, v4.16b, v5.16b, v6.16b, v16.16b, v17.16b, v18.16b, 1, \size - extmla v1.8h, v2.8h, v24.8h, v25.8h, v4.16b, v5.16b, v6.16b, v16.16b, v17.16b, v18.16b, 2, \size - extmla v1.8h, v2.8h, v24.8h, v25.8h, v4.16b, v5.16b, v6.16b, v16.16b, v17.16b, v18.16b, \idx1, \size - extmla v1.8h, v2.8h, v24.8h, v25.8h, v4.16b, v5.16b, v6.16b, v16.16b, v17.16b, v18.16b, 5, \size - extmla v1.8h, v2.8h, v24.8h, v25.8h, v4.16b, v5.16b, v6.16b, v16.16b, v17.16b, v18.16b, 6, \size - extmla v1.8h, v2.8h, v24.8h, v25.8h, v4.16b, v5.16b, v6.16b, v16.16b, v17.16b, v18.16b, 7, \size - extmulqadd v1.8h, v2.8h, v24.8h, v25.8h, v4.16b, v5.16b, v6.16b, v16.16b, v17.16b, v18.16b, \idx2, \size + extmla v1, v2, v24, v25, v4, v5, v6, v16, v17, v18, 1, \size + extmla v1, v2, v24, v25, v4, v5, v6, v16, v17, v18, 2, \size + extmla v1, v2, v24, v25, v4, v5, v6, v16, v17, v18, \idx1, \size + extmla v1, v2, v24, v25, v4, v5, v6, v16, v17, v18, 5, \size + extmla v1, v2, v24, v25, v4, v5, v6, v16, v17, v18, 6, \size + extmla v1, v2, v24, v25, v4, v5, v6, v16, v17, v18, 7, \size + extmulqadd v1, v2, v24, v25, v4, v5, v6, v16, v17, v18, \idx2, \size // Round, shift and saturate sqrshrun v1.8b, v1.8h, #7 From fea92a4b57d1c328b1de226a5f213a629ee63754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 17 Dec 2016 13:09:50 +0200 Subject: [PATCH 0894/3374] arm: vp9mc: Calculate less unused data in the 4 pixel wide horizontal filter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before: Cortex A7 A8 A9 A53 vp9_put_8tap_smooth_4h_neon: 378.1 273.2 340.7 229.5 After: vp9_put_8tap_smooth_4h_neon: 352.1 222.2 290.5 229.5 Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9mc_neon.S | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/libavcodec/arm/vp9mc_neon.S b/libavcodec/arm/vp9mc_neon.S index a5413a3c9f5ce..8d43ff19c31ad 100644 --- a/libavcodec/arm/vp9mc_neon.S +++ b/libavcodec/arm/vp9mc_neon.S @@ -209,7 +209,7 @@ endfunc @ Extract a vector from src1-src2 and src4-src5 (src1-src3 and src4-src6 @ for size >= 16), and multiply-accumulate into dst1 and dst3 (or @ dst1-dst2 and dst3-dst4 for size >= 16) -.macro extmla dst1, dst2, dst3, dst4, src1, src2, src3, src4, src5, src6, offset, size +.macro extmla dst1, dst2, dst3, dst4, dst1d, dst3d, src1, src2, src3, src4, src5, src6, offset, size vext.8 q14, \src1, \src2, #(2*\offset) vext.8 q15, \src4, \src5, #(2*\offset) .if \size >= 16 @@ -219,14 +219,17 @@ endfunc vext.8 q6, \src5, \src6, #(2*\offset) vmla_lane \dst2, q5, \offset vmla_lane \dst4, q6, \offset -.else +.elseif \size == 8 vmla_lane \dst1, q14, \offset vmla_lane \dst3, q15, \offset +.else + vmla_lane \dst1d, d28, \offset + vmla_lane \dst3d, d30, \offset .endif .endm @ The same as above, but don't accumulate straight into the @ destination, but use a temp register and accumulate with saturation. -.macro extmulqadd dst1, dst2, dst3, dst4, src1, src2, src3, src4, src5, src6, offset, size +.macro extmulqadd dst1, dst2, dst3, dst4, dst1d, dst3d, src1, src2, src3, src4, src5, src6, offset, size vext.8 q14, \src1, \src2, #(2*\offset) vext.8 q15, \src4, \src5, #(2*\offset) .if \size >= 16 @@ -236,16 +239,24 @@ endfunc vext.8 q6, \src5, \src6, #(2*\offset) vmul_lane q5, q5, \offset vmul_lane q6, q6, \offset -.else +.elseif \size == 8 vmul_lane q14, q14, \offset vmul_lane q15, q15, \offset +.else + vmul_lane d28, d28, \offset + vmul_lane d30, d30, \offset .endif +.if \size == 4 + vqadd.s16 \dst1d, \dst1d, d28 + vqadd.s16 \dst3d, \dst3d, d30 +.else vqadd.s16 \dst1, \dst1, q14 vqadd.s16 \dst3, \dst3, q15 .if \size >= 16 vqadd.s16 \dst2, \dst2, q5 vqadd.s16 \dst4, \dst4, q6 .endif +.endif .endm @@ -309,13 +320,13 @@ function \type\()_8tap_\size\()h_\idx1\idx2 vmul.s16 q2, q9, d0[0] vmul.s16 q4, q12, d0[0] .endif - extmla q1, q2, q3, q4, q8, q9, q10, q11, q12, q13, 1, \size - extmla q1, q2, q3, q4, q8, q9, q10, q11, q12, q13, 2, \size - extmla q1, q2, q3, q4, q8, q9, q10, q11, q12, q13, \idx1, \size - extmla q1, q2, q3, q4, q8, q9, q10, q11, q12, q13, 5, \size - extmla q1, q2, q3, q4, q8, q9, q10, q11, q12, q13, 6, \size - extmla q1, q2, q3, q4, q8, q9, q10, q11, q12, q13, 7, \size - extmulqadd q1, q2, q3, q4, q8, q9, q10, q11, q12, q13, \idx2, \size + extmla q1, q2, q3, q4, d2, d6, q8, q9, q10, q11, q12, q13, 1, \size + extmla q1, q2, q3, q4, d2, d6, q8, q9, q10, q11, q12, q13, 2, \size + extmla q1, q2, q3, q4, d2, d6, q8, q9, q10, q11, q12, q13, \idx1, \size + extmla q1, q2, q3, q4, d2, d6, q8, q9, q10, q11, q12, q13, 5, \size + extmla q1, q2, q3, q4, d2, d6, q8, q9, q10, q11, q12, q13, 6, \size + extmla q1, q2, q3, q4, d2, d6, q8, q9, q10, q11, q12, q13, 7, \size + extmulqadd q1, q2, q3, q4, d2, d6, q8, q9, q10, q11, q12, q13, \idx2, \size @ Round, shift and saturate vqrshrun.s16 d2, q1, #7 From 388e0d2515bc6bbc9d0c9af1d230bd16cf945fe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 17 Dec 2016 13:14:38 +0200 Subject: [PATCH 0895/3374] aarch64: vp9mc: Calculate less unused data in the 4 pixel wide horizontal filter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No measured speedup on a Cortex A53, but other cores might benefit. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9mc_neon.S | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/libavcodec/aarch64/vp9mc_neon.S b/libavcodec/aarch64/vp9mc_neon.S index 99f1809270938..95ed26c2325ed 100644 --- a/libavcodec/aarch64/vp9mc_neon.S +++ b/libavcodec/aarch64/vp9mc_neon.S @@ -202,9 +202,12 @@ endfunc ext v23.16b, \src5\().16b, \src6\().16b, #(2*\offset) mla \dst2\().8h, v21.8h, v0.h[\offset] mla \dst4\().8h, v23.8h, v0.h[\offset] -.else +.elseif \size == 8 mla \dst1\().8h, v20.8h, v0.h[\offset] mla \dst3\().8h, v22.8h, v0.h[\offset] +.else + mla \dst1\().4h, v20.4h, v0.h[\offset] + mla \dst3\().4h, v22.4h, v0.h[\offset] .endif .endm // The same as above, but don't accumulate straight into the @@ -219,16 +222,24 @@ endfunc ext v23.16b, \src5\().16b, \src6\().16b, #(2*\offset) mul v21.8h, v21.8h, v0.h[\offset] mul v23.8h, v23.8h, v0.h[\offset] -.else +.elseif \size == 8 mul v20.8h, v20.8h, v0.h[\offset] mul v22.8h, v22.8h, v0.h[\offset] +.else + mul v20.4h, v20.4h, v0.h[\offset] + mul v22.4h, v22.4h, v0.h[\offset] .endif +.if \size == 4 + sqadd \dst1\().4h, \dst1\().4h, v20.4h + sqadd \dst3\().4h, \dst3\().4h, v22.4h +.else sqadd \dst1\().8h, \dst1\().8h, v20.8h sqadd \dst3\().8h, \dst3\().8h, v22.8h .if \size >= 16 sqadd \dst2\().8h, \dst2\().8h, v21.8h sqadd \dst4\().8h, \dst4\().8h, v23.8h .endif +.endif .endm From a76bf8cf1277ef6feb1580b578f5e6ca327e713c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 4 Jan 2017 13:08:51 +0200 Subject: [PATCH 0896/3374] arm: vp9itxfm: Optimize 16x16 and 32x32 idct dc by unrolling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. Before: Cortex A7 A8 A9 A53 vp9_inv_dct_dct_16x16_sub1_add_neon: 273.0 189.5 211.7 235.8 vp9_inv_dct_dct_32x32_sub1_add_neon: 752.0 459.2 862.2 553.9 After: vp9_inv_dct_dct_16x16_sub1_add_neon: 226.5 145.0 225.1 171.8 vp9_inv_dct_dct_32x32_sub1_add_neon: 721.2 415.7 727.6 475.0 Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 54 ++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index 3d0b0fab2e173..8dc4bbfa5529e 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -542,16 +542,23 @@ function idct16x16_dc_add_neon vrshr.s16 q8, q8, #6 + mov r3, r0 mov r12, #16 1: @ Loop to add the constant from q8 into all 16x16 outputs - vld1.8 {q3}, [r0,:128] - vaddw.u8 q10, q8, d6 - vaddw.u8 q11, q8, d7 - vqmovun.s16 d6, q10 - vqmovun.s16 d7, q11 - vst1.8 {q3}, [r0,:128], r1 - subs r12, r12, #1 + subs r12, r12, #2 + vld1.8 {q2}, [r0,:128], r1 + vaddw.u8 q10, q8, d4 + vld1.8 {q3}, [r0,:128], r1 + vaddw.u8 q11, q8, d5 + vaddw.u8 q12, q8, d6 + vaddw.u8 q13, q8, d7 + vqmovun.s16 d4, q10 + vqmovun.s16 d5, q11 + vqmovun.s16 d6, q12 + vst1.8 {q2}, [r3,:128], r1 + vqmovun.s16 d7, q13 + vst1.8 {q3}, [r3,:128], r1 bne 1b bx lr @@ -1147,20 +1154,31 @@ function idct32x32_dc_add_neon vrshr.s16 q8, q8, #6 + mov r3, r0 mov r12, #32 1: @ Loop to add the constant from q8 into all 32x32 outputs - vld1.8 {q2-q3}, [r0,:128] - vaddw.u8 q10, q8, d4 - vaddw.u8 q11, q8, d5 - vaddw.u8 q12, q8, d6 - vaddw.u8 q13, q8, d7 - vqmovun.s16 d4, q10 - vqmovun.s16 d5, q11 - vqmovun.s16 d6, q12 - vqmovun.s16 d7, q13 - vst1.8 {q2-q3}, [r0,:128], r1 - subs r12, r12, #1 + subs r12, r12, #2 + vld1.8 {q0-q1}, [r0,:128], r1 + vaddw.u8 q9, q8, d0 + vaddw.u8 q10, q8, d1 + vld1.8 {q2-q3}, [r0,:128], r1 + vaddw.u8 q11, q8, d2 + vaddw.u8 q12, q8, d3 + vaddw.u8 q13, q8, d4 + vaddw.u8 q14, q8, d5 + vaddw.u8 q15, q8, d6 + vqmovun.s16 d0, q9 + vaddw.u8 q9, q8, d7 + vqmovun.s16 d1, q10 + vqmovun.s16 d2, q11 + vqmovun.s16 d3, q12 + vqmovun.s16 d4, q13 + vqmovun.s16 d5, q14 + vst1.8 {q0-q1}, [r3,:128], r1 + vqmovun.s16 d6, q15 + vqmovun.s16 d7, q9 + vst1.8 {q2-q3}, [r3,:128], r1 bne 1b bx lr From 3fcf788fbbccc4130868e7abe58a88990290f7c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 4 Jan 2017 12:57:56 +0200 Subject: [PATCH 0897/3374] aarch64: vp9itxfm: Optimize 16x16 and 32x32 idct dc by unrolling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. Before: Cortex A53 vp9_inv_dct_dct_16x16_sub1_add_neon: 235.3 vp9_inv_dct_dct_32x32_sub1_add_neon: 555.1 After: vp9_inv_dct_dct_16x16_sub1_add_neon: 180.2 vp9_inv_dct_dct_32x32_sub1_add_neon: 475.3 Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 54 ++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index a199e9c6030f9..d35f103a79968 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -495,16 +495,23 @@ function idct16x16_dc_add_neon srshr v2.8h, v2.8h, #6 + mov x3, x0 mov x4, #16 1: // Loop to add the constant from v2 into all 16x16 outputs - ld1 {v3.16b}, [x0] - uaddw v4.8h, v2.8h, v3.8b - uaddw2 v5.8h, v2.8h, v3.16b - sqxtun v4.8b, v4.8h - sqxtun2 v4.16b, v5.8h - st1 {v4.16b}, [x0], x1 - subs x4, x4, #1 + subs x4, x4, #2 + ld1 {v3.16b}, [x0], x1 + ld1 {v4.16b}, [x0], x1 + uaddw v16.8h, v2.8h, v3.8b + uaddw2 v17.8h, v2.8h, v3.16b + uaddw v18.8h, v2.8h, v4.8b + uaddw2 v19.8h, v2.8h, v4.16b + sqxtun v3.8b, v16.8h + sqxtun2 v3.16b, v17.8h + sqxtun v4.8b, v18.8h + sqxtun2 v4.16b, v19.8h + st1 {v3.16b}, [x3], x1 + st1 {v4.16b}, [x3], x1 b.ne 1b ret @@ -1054,20 +1061,31 @@ function idct32x32_dc_add_neon srshr v0.8h, v2.8h, #6 + mov x3, x0 mov x4, #32 1: // Loop to add the constant v0 into all 32x32 outputs - ld1 {v1.16b,v2.16b}, [x0] - uaddw v3.8h, v0.8h, v1.8b - uaddw2 v4.8h, v0.8h, v1.16b - uaddw v5.8h, v0.8h, v2.8b - uaddw2 v6.8h, v0.8h, v2.16b - sqxtun v3.8b, v3.8h - sqxtun2 v3.16b, v4.8h - sqxtun v4.8b, v5.8h - sqxtun2 v4.16b, v6.8h - st1 {v3.16b,v4.16b}, [x0], x1 - subs x4, x4, #1 + subs x4, x4, #2 + ld1 {v1.16b,v2.16b}, [x0], x1 + uaddw v16.8h, v0.8h, v1.8b + uaddw2 v17.8h, v0.8h, v1.16b + ld1 {v3.16b,v4.16b}, [x0], x1 + uaddw v18.8h, v0.8h, v2.8b + uaddw2 v19.8h, v0.8h, v2.16b + uaddw v20.8h, v0.8h, v3.8b + uaddw2 v21.8h, v0.8h, v3.16b + uaddw v22.8h, v0.8h, v4.8b + uaddw2 v23.8h, v0.8h, v4.16b + sqxtun v1.8b, v16.8h + sqxtun2 v1.16b, v17.8h + sqxtun v2.8b, v18.8h + sqxtun2 v2.16b, v19.8h + sqxtun v3.8b, v20.8h + sqxtun2 v3.16b, v21.8h + st1 {v1.16b,v2.16b}, [x3], x1 + sqxtun v4.8b, v22.8h + sqxtun2 v4.16b, v23.8h + st1 {v3.16b,v4.16b}, [x3], x1 b.ne 1b ret From e1f9de86f454861b69b199ad801adc2ec6c3b220 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 12 Jan 2017 16:52:33 +0200 Subject: [PATCH 0898/3374] arm/aarch64: vp9lpf: Calculate !hev directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously we first calculated hev, and then negated it. Since we were able to schedule the negation in the middle of another calculation, we don't see any gain in all cases. Before: Cortex A7 A8 A9 A53 A53/AArch64 vp9_loop_filter_v_4_8_neon: 147.0 129.0 115.8 89.0 88.7 vp9_loop_filter_v_8_8_neon: 242.0 198.5 174.7 140.0 136.7 vp9_loop_filter_v_16_8_neon: 500.0 419.5 382.7 293.0 275.7 vp9_loop_filter_v_16_16_neon: 971.2 825.5 731.5 579.0 453.0 After: vp9_loop_filter_v_4_8_neon: 143.0 127.7 114.8 88.0 87.7 vp9_loop_filter_v_8_8_neon: 241.0 197.2 173.7 140.0 136.7 vp9_loop_filter_v_16_8_neon: 497.0 419.5 379.7 293.0 275.7 vp9_loop_filter_v_16_16_neon: 965.2 818.7 731.4 579.0 452.0 Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9lpf_neon.S | 5 ++--- libavcodec/arm/vp9lpf_neon.S | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/libavcodec/aarch64/vp9lpf_neon.S b/libavcodec/aarch64/vp9lpf_neon.S index e9c7d9edc8029..3b8e6ebc99bea 100644 --- a/libavcodec/aarch64/vp9lpf_neon.S +++ b/libavcodec/aarch64/vp9lpf_neon.S @@ -292,7 +292,7 @@ .if \mix != 0 sxtl v1.8h, v1.8b .endif - cmhi v5\sz, v5\sz, v3\sz // hev + cmhs v5\sz, v3\sz, v5\sz // !hev .if \wd == 8 // If a 4/8 or 8/4 mix is used, clear the relevant half of v6 .if \mix != 0 @@ -306,11 +306,10 @@ .elseif \wd == 8 bic v4\sz, v4\sz, v6\sz // fm && !flat8in .endif - mvn v5\sz, v5\sz // !hev + and v5\sz, v5\sz, v4\sz // !hev && fm && !flat8in .if \wd == 16 and v7\sz, v7\sz, v6\sz // flat8out && flat8in && fm .endif - and v5\sz, v5\sz, v4\sz // !hev && fm && !flat8in mul_sz \tmp3\().8h, \tmp4\().8h, \tmp3\().8h, \tmp4\().8h, \tmp5\().8h, \tmp5\().8h, \sz // 3 * (q0 - p0) bic \tmp1\sz, \tmp1\sz, v5\sz // if (!hev) av_clip_int8 = 0 diff --git a/libavcodec/arm/vp9lpf_neon.S b/libavcodec/arm/vp9lpf_neon.S index fbf2901f75052..c57c0e9c31e19 100644 --- a/libavcodec/arm/vp9lpf_neon.S +++ b/libavcodec/arm/vp9lpf_neon.S @@ -141,7 +141,7 @@ .if \wd == 8 vcle.u8 d6, d6, d0 @ flat8in .endif - vcgt.u8 d5, d5, d3 @ hev + vcle.u8 d5, d5, d3 @ !hev .if \wd == 8 vand d6, d6, d4 @ flat8in && fm .endif @@ -151,11 +151,10 @@ .elseif \wd == 8 vbic d4, d4, d6 @ fm && !flat8in .endif - vmvn d5, d5 @ !hev + vand d5, d5, d4 @ !hev && fm && !flat8in .if \wd == 16 vand d7, d7, d6 @ flat8out && flat8in && fm .endif - vand d5, d5, d4 @ !hev && fm && !flat8in vmul.s16 \tmpq2, \tmpq2, \tmpq3 @ 3 * (q0 - p0) vbic \tmp1, \tmp1, d5 @ if (!hev) av_clip_int8 = 0 From 435cd7bc99671bf561193421a50ac6e9d63c4266 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 13 Jan 2017 23:42:28 +0200 Subject: [PATCH 0899/3374] arm: vp9lpf: Use orrs instead of orr+cmp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9lpf_neon.S | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/libavcodec/arm/vp9lpf_neon.S b/libavcodec/arm/vp9lpf_neon.S index c57c0e9c31e19..c2f1c954274b1 100644 --- a/libavcodec/arm/vp9lpf_neon.S +++ b/libavcodec/arm/vp9lpf_neon.S @@ -78,8 +78,7 @@ vdup.u8 d3, r3 @ H vmov r2, r3, d4 - orr r2, r2, r3 - cmp r2, #0 + orrs r2, r2, r3 @ If no pixels need filtering, just exit as soon as possible beq 9f @@ -192,8 +191,7 @@ .if \wd >= 8 vmov r2, r3, d6 - orr r2, r2, r3 - cmp r2, #0 + orrs r2, r2, r3 @ If no pixels need flat8in, jump to flat8out @ (or to a writeout of the inner 4 pixels, for wd=8) beq 6f @@ -248,14 +246,12 @@ 6: vorr d2, d6, d7 vmov r2, r3, d2 - orr r2, r2, r3 - cmp r2, #0 + orrs r2, r2, r3 @ If no pixels needed flat8in nor flat8out, jump to a @ writeout of the inner 4 pixels beq 7f vmov r2, r3, d7 - orr r2, r2, r3 - cmp r2, #0 + orrs r2, r2, r3 @ If no pixels need flat8out, jump to a writeout of the inner 6 pixels beq 8f From 99684f3ae752fc8bfb44a2dd1482f8d7a3d8536d Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 13 Jan 2017 11:53:51 +0100 Subject: [PATCH 0900/3374] avio: add a destructor for AVIOContext Before this commit, AVIOContext is to be freed with a plain av_free(), which prevents us from adding any deeper structure to it. --- doc/APIchanges | 3 +++ libavformat/avio.h | 8 ++++++++ libavformat/aviobuf.c | 17 ++++++++++++++--- libavformat/version.h | 4 ++-- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index c161618d92f0f..8c7d279fec89e 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-xx-xx - xxxxxxx - lavf 57.11.0 - avio.h + Add avio_context_free(). From now on it must be used for freeing AVIOContext. + 2017-02-01 - xxxxxxx - lavc - avcodec.h Deprecate AVCodecContext.refcounted_frames. This was useful for deprecated API only (avcodec_decode_video2/avcodec_decode_audio4). The new decode APIs diff --git a/libavformat/avio.h b/libavformat/avio.h index 7bf7985c5e04a..e65135ed9988a 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -219,6 +219,14 @@ AVIOContext *avio_alloc_context( int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), int64_t (*seek)(void *opaque, int64_t offset, int whence)); +/** + * Free the supplied IO context and everything associated with it. + * + * @param s Double pointer to the IO context. This function will write NULL + * into s. + */ +void avio_context_free(AVIOContext **s); + void avio_w8(AVIOContext *s, int b); void avio_write(AVIOContext *s, const unsigned char *buf, int size); void avio_wl64(AVIOContext *s, uint64_t val); diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index 6d83a9661b34f..31476d3f6d584 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -165,6 +165,11 @@ AVIOContext *avio_alloc_context( return s; } +void avio_context_free(AVIOContext **ps) +{ + av_freep(ps); +} + static void flush_buffer(AVIOContext *s) { if (s->buf_ptr > s->buffer) { @@ -1007,7 +1012,9 @@ int avio_close(AVIOContext *s) av_freep(&internal->protocols); av_freep(&s->opaque); av_freep(&s->buffer); - av_free(s); + + avio_context_free(&s); + return ffurl_close(h); } @@ -1186,7 +1193,9 @@ int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer) *pbuffer = d->buffer; size = d->size; av_free(d); - av_free(s); + + avio_context_free(&s); + return size - padding; } @@ -1229,6 +1238,8 @@ int ffio_close_null_buf(AVIOContext *s) size = d->size; av_free(d); - av_free(s); + + avio_context_free(&s); + return size; } diff --git a/libavformat/version.h b/libavformat/version.h index 65d5754630daf..92f3407909678 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -30,8 +30,8 @@ #include "libavutil/version.h" #define LIBAVFORMAT_VERSION_MAJOR 57 -#define LIBAVFORMAT_VERSION_MINOR 10 -#define LIBAVFORMAT_VERSION_MICRO 3 +#define LIBAVFORMAT_VERSION_MINOR 11 +#define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ From 6f554521afdf7ab4edbfaa9536660a1dca946b19 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 13 Jan 2017 12:04:16 +0100 Subject: [PATCH 0901/3374] Use the new AVIOContext destructor. --- avprobe.c | 2 +- libavformat/avidec.c | 4 ++-- libavformat/flac_picture.c | 4 ++-- libavformat/hdsenc.c | 4 ++-- libavformat/mpjpegdec.c | 2 +- libavformat/rdt.c | 2 +- libavformat/segment.c | 10 +++++----- libavformat/smoothstreamingenc.c | 4 ++-- libavformat/swfdec.c | 4 +++- libavformat/tests/movenc.c | 2 +- libavformat/wtv.c | 2 +- 11 files changed, 21 insertions(+), 19 deletions(-) diff --git a/avprobe.c b/avprobe.c index a24e6440eb613..613e090be6e8b 100644 --- a/avprobe.c +++ b/avprobe.c @@ -1178,7 +1178,7 @@ int main(int argc, char **argv) ret = probe_file(input_filename); probe_footer(); avio_flush(probe_out); - av_freep(&probe_out); + avio_context_free(&probe_out); av_freep(&buffer); uninit_opts(); avformat_network_deinit(); diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 0439c9c94cc95..701cccb6b0ad1 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -901,7 +901,7 @@ static int read_gab2_sub(AVStream *st, AVPacket *pkt) return 1; error: - av_freep(&pb); + avio_context_free(&pb); } return 0; } @@ -1576,7 +1576,7 @@ static int avi_read_close(AVFormatContext *s) AVIStream *ast = st->priv_data; if (ast) { if (ast->sub_ctx) { - av_freep(&ast->sub_ctx->pb); + avio_context_free(&ast->sub_ctx->pb); avformat_close_input(&ast->sub_ctx); } av_free(ast->sub_buffer); diff --git a/libavformat/flac_picture.c b/libavformat/flac_picture.c index 1381a28b8064f..fd0bb0291fd0f 100644 --- a/libavformat/flac_picture.c +++ b/libavformat/flac_picture.c @@ -139,14 +139,14 @@ int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size) if (desc) av_dict_set(&st->metadata, "title", desc, AV_DICT_DONT_STRDUP_VAL); - av_freep(&pb); + avio_context_free(&pb); return 0; fail: av_buffer_unref(&data); av_freep(&desc); - av_freep(&pb); + avio_context_free(&pb); return ret; } diff --git a/libavformat/hdsenc.c b/libavformat/hdsenc.c index e32c36503e5cd..a608e7eb0f793 100644 --- a/libavformat/hdsenc.c +++ b/libavformat/hdsenc.c @@ -143,8 +143,8 @@ static void hds_free(AVFormatContext *s) ff_format_io_close(s, &os->out); if (os->ctx && os->ctx_inited) av_write_trailer(os->ctx); - if (os->ctx && os->ctx->pb) - av_free(os->ctx->pb); + if (os->ctx) + avio_context_free(&os->ctx->pb); if (os->ctx) avformat_free_context(os->ctx); av_free(os->metadata); diff --git a/libavformat/mpjpegdec.c b/libavformat/mpjpegdec.c index 886bdfcbef443..844aa87da8ff1 100644 --- a/libavformat/mpjpegdec.c +++ b/libavformat/mpjpegdec.c @@ -102,7 +102,7 @@ static int mpjpeg_read_probe(AVProbeData *p) } } - av_free(pb); + avio_context_free(&pb); return ret; } diff --git a/libavformat/rdt.c b/libavformat/rdt.c index 825e4f1355209..0adfa2534f64b 100644 --- a/libavformat/rdt.c +++ b/libavformat/rdt.c @@ -324,7 +324,7 @@ rdt_parse_packet (AVFormatContext *ctx, PayloadContext *rdt, AVStream *st, st, rdt->rmst[st->index], pkt); if (rdt->audio_pkt_cnt == 0 && st->codecpar->codec_id == AV_CODEC_ID_AAC) - av_freep(&rdt->rmctx->pb); + avio_context_free(&rdt->rmctx->pb); } pkt->stream_index = st->index; pkt->pts = *timestamp; diff --git a/libavformat/segment.c b/libavformat/segment.c index fd68a9f753d7d..7d23afc0131a4 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -184,10 +184,10 @@ static int open_null_ctx(AVIOContext **ctx) return 0; } -static void close_null_ctx(AVIOContext *pb) +static void close_null_ctx(AVIOContext **pb) { - av_free(pb->buffer); - av_free(pb); + av_free((*pb)->buffer); + avio_context_free(pb); } static void seg_free_context(SegmentContext *seg) @@ -259,7 +259,7 @@ static int seg_write_header(AVFormatContext *s) } if (!seg->write_header_trailer) { - close_null_ctx(oc->pb); + close_null_ctx(&oc->pb); if ((ret = s->io_open(s, &oc->pb, oc->filename, AVIO_FLAG_WRITE, NULL)) < 0) goto fail; } @@ -353,7 +353,7 @@ static int seg_write_trailer(struct AVFormatContext *s) if ((ret = open_null_ctx(&oc->pb)) < 0) goto fail; ret = av_write_trailer(oc); - close_null_ctx(oc->pb); + close_null_ctx(&oc->pb); } else { ret = segment_end(oc, 1); } diff --git a/libavformat/smoothstreamingenc.c b/libavformat/smoothstreamingenc.c index 065ecc2ee4618..997b9e636cc2b 100644 --- a/libavformat/smoothstreamingenc.c +++ b/libavformat/smoothstreamingenc.c @@ -187,8 +187,8 @@ static void ism_free(AVFormatContext *s) os->out = os->out2 = os->tail_out = NULL; if (os->ctx && os->ctx_inited) av_write_trailer(os->ctx); - if (os->ctx && os->ctx->pb) - av_free(os->ctx->pb); + if (os->ctx) + avio_context_free(&os->ctx->pb); if (os->ctx) avformat_free_context(os->ctx); av_free(os->private_str); diff --git a/libavformat/swfdec.c b/libavformat/swfdec.c index 7bb67de8d8fe4..984fedffcf974 100644 --- a/libavformat/swfdec.c +++ b/libavformat/swfdec.c @@ -310,7 +310,9 @@ static av_cold int swf_read_close(AVFormatContext *avctx) inflateEnd(&s->zstream); av_freep(&s->zbuf_in); av_freep(&s->zbuf_out); - av_freep(&s->zpb); + + avio_context_free(&s->zpb); + return 0; } #endif diff --git a/libavformat/tests/movenc.c b/libavformat/tests/movenc.c index 05432eb488d93..583a8d9ca4336 100644 --- a/libavformat/tests/movenc.c +++ b/libavformat/tests/movenc.c @@ -338,7 +338,7 @@ static void signal_init_ts(void) static void finish(void) { av_write_trailer(ctx); - av_free(ctx->pb); + avio_context_free(&ctx->pb); avformat_free_context(ctx); ctx = NULL; } diff --git a/libavformat/wtv.c b/libavformat/wtv.c index 2cab4e5bd05e0..794dd4bb71b68 100644 --- a/libavformat/wtv.c +++ b/libavformat/wtv.c @@ -313,7 +313,7 @@ static void wtvfile_close(AVIOContext *pb) av_free(wf->sectors); av_free(wf); av_free(pb->buffer); - av_free(pb); + avio_context_free(&pb); } /* From 5c8a5765dc5f4e29afb85b95be393c30f45412a8 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 1 Feb 2017 10:38:42 +0100 Subject: [PATCH 0902/3374] scale_npp: explicitly set the output frames context for passthrough mode This is no longer done automatically for filters marked as hwframe-aware. --- libavfilter/vf_scale_npp.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libavfilter/vf_scale_npp.c b/libavfilter/vf_scale_npp.c index 0e636a997d01f..be1f81f8ad67e 100644 --- a/libavfilter/vf_scale_npp.c +++ b/libavfilter/vf_scale_npp.c @@ -336,9 +336,11 @@ static int init_processing_chain(AVFilterContext *ctx, int in_width, int in_heig last_stage = i; } - if (last_stage < 0) - return 0; - ctx->outputs[0]->hw_frames_ctx = av_buffer_ref(s->stages[last_stage].frames_ctx); + if (last_stage >= 0) + ctx->outputs[0]->hw_frames_ctx = av_buffer_ref(s->stages[last_stage].frames_ctx); + else + ctx->outputs[0]->hw_frames_ctx = av_buffer_ref(ctx->inputs[0]->hw_frames_ctx); + if (!ctx->outputs[0]->hw_frames_ctx) return AVERROR(ENOMEM); From e6bff23f1e11aefb16a2b5d6ee72bf7469c5a66e Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 8 Feb 2017 09:32:17 +0100 Subject: [PATCH 0903/3374] cpu: add a function for querying maximum required data alignment --- doc/APIchanges | 3 +++ libavutil/cpu.c | 13 +++++++++++++ libavutil/cpu.h | 13 +++++++++++++ libavutil/version.h | 2 +- 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index 8c7d279fec89e..be34c92d3f725 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-02-xx - xxxxxxx - lavu 55.31.0 - cpu.h + Add av_cpu_max_align() for querying maximum required data alignment. + 2016-xx-xx - xxxxxxx - lavf 57.11.0 - avio.h Add avio_context_free(). From now on it must be used for freeing AVIOContext. diff --git a/libavutil/cpu.c b/libavutil/cpu.c index 0109c9e8d1a26..5aef6af217c98 100644 --- a/libavutil/cpu.c +++ b/libavutil/cpu.c @@ -16,6 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include #include @@ -180,3 +181,15 @@ int av_cpu_count(void) return nb_cpus; } + +size_t av_cpu_max_align(void) +{ + int flags = av_get_cpu_flags(); + + if (flags & AV_CPU_FLAG_AVX) + return 32; + if (flags & (AV_CPU_FLAG_ALTIVEC | AV_CPU_FLAG_SSE | AV_CPU_FLAG_NEON)) + return 16; + + return 8; +} diff --git a/libavutil/cpu.h b/libavutil/cpu.h index c205ee16f6631..4dcde27dbecd4 100644 --- a/libavutil/cpu.h +++ b/libavutil/cpu.h @@ -21,6 +21,8 @@ #ifndef AVUTIL_CPU_H #define AVUTIL_CPU_H +#include + #include "version.h" #define AV_CPU_FLAG_FORCE 0x80000000 /* force usage of selected flags (OR) */ @@ -88,4 +90,15 @@ int av_parse_cpu_flags(const char *s); */ int av_cpu_count(void); +/** + * Get the maximum data alignment that may be required by Libav. + * + * Note that this is affected by the build configuration and the CPU flags mask, + * so e.g. if the CPU supports AVX, but libavutil has been built with + * --disable-avx or the AV_CPU_FLAG_AVX flag has been disabled through + * av_set_cpu_flags_mask(), then this function will behave as if AVX is not + * present. + */ +size_t av_cpu_max_align(void); + #endif /* AVUTIL_CPU_H */ diff --git a/libavutil/version.h b/libavutil/version.h index 7856a0acc3f9f..0fcd19a1eb2b7 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -54,7 +54,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 30 +#define LIBAVUTIL_VERSION_MINOR 31 #define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From f44ec22e095c5ba00ffeadd891655c456e3dd014 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 8 Feb 2017 09:34:58 +0100 Subject: [PATCH 0904/3374] lavc: use av_cpu_max_align() instead of hardcoding alignment requirements --- libavcodec/utils.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 2978109a23d41..06a5784046763 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -179,17 +179,10 @@ int ff_side_data_update_matrix_encoding(AVFrame *frame, return 0; } -#if HAVE_SIMD_ALIGN_32 -# define STRIDE_ALIGN 32 -#elif HAVE_SIMD_ALIGN_16 -# define STRIDE_ALIGN 16 -#else -# define STRIDE_ALIGN 8 -#endif - void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int linesize_align[AV_NUM_DATA_POINTERS]) { + size_t max_align = av_cpu_max_align(); int i; int w_align = 1; int h_align = 1; @@ -282,7 +275,7 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, *height += 2; for (i = 0; i < 4; i++) - linesize_align[i] = STRIDE_ALIGN; + linesize_align[i] = max_align; } void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height) From 4de220d2e3751c459f8739a08ac6ca52e63eba30 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 8 Feb 2017 09:46:04 +0100 Subject: [PATCH 0905/3374] frame: allow align=0 (meaning automatic) for av_frame_get_buffer() This will avoid every caller from hardcoding some specific alignment, which may break in the future with new instruction sets. --- doc/APIchanges | 4 ++++ libavutil/frame.c | 4 ++++ libavutil/frame.h | 4 +++- libavutil/version.h | 2 +- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index be34c92d3f725..9b9f46ef49348 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,10 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-02-xx - xxxxxxx - lavu 55.31.1 - frame.h + Allow passing the value of 0 (meaning "automatic") as the required alignment + to av_frame_get_buffer(). + 2017-02-xx - xxxxxxx - lavu 55.31.0 - cpu.h Add av_cpu_max_align() for querying maximum required data alignment. diff --git a/libavutil/frame.c b/libavutil/frame.c index aafaa57d8b556..aa5820c0e95ce 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -19,6 +19,7 @@ #include "channel_layout.h" #include "buffer.h" #include "common.h" +#include "cpu.h" #include "dict.h" #include "frame.h" #include "imgutils.h" @@ -103,6 +104,9 @@ static int get_video_buffer(AVFrame *frame, int align) if (ret < 0) return ret; + if (align <= 0) + align = av_cpu_max_align(); + for (i = 0; i < 4 && frame->linesize[i]; i++) frame->linesize[i] = FFALIGN(frame->linesize[i], align); } diff --git a/libavutil/frame.h b/libavutil/frame.h index c718f7bd62cc9..4f63fb024911b 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -475,7 +475,9 @@ void av_frame_move_ref(AVFrame *dst, AVFrame *src); * cases. * * @param frame frame in which to store the new buffers. - * @param align required buffer size alignment + * @param align Required buffer size alignment. If equal to 0, alignment will be + * chosen automatically for the current CPU. It is highly + * recommended to pass 0 here unless you know what you are doing. * * @return 0 on success, a negative AVERROR on error. */ diff --git a/libavutil/version.h b/libavutil/version.h index 0fcd19a1eb2b7..0768f9fe9996c 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -55,7 +55,7 @@ #define LIBAVUTIL_VERSION_MAJOR 55 #define LIBAVUTIL_VERSION_MINOR 31 -#define LIBAVUTIL_VERSION_MICRO 0 +#define LIBAVUTIL_VERSION_MICRO 1 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ LIBAVUTIL_VERSION_MINOR, \ From 04f3bd349651694f30feeb8c4ed9bc58106fca54 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 2 Feb 2017 11:27:54 +0100 Subject: [PATCH 0906/3374] AVFrame: add an opaque_ref field This is an extended version of the AVFrame.opaque field, which can be used to attach arbitrary user information to an AVFrame. The usefulness of the opaque field is rather limited, because it can store only up to 32 bits of information (or 64 bit on 64 bit systems). It's not possible to set this field to a memory allocation, because there is no way to deallocate it correctly. The opaque_ref field circumvents this by letting the user set an AVBuffer, which makes the user data refcounted. Signed-off-by: Anton Khirnov --- doc/APIchanges | 3 +++ libavutil/frame.c | 9 +++++++++ libavutil/frame.h | 11 +++++++++++ libavutil/version.h | 4 ++-- 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 9b9f46ef49348..e7a0b14038bd2 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-02-11 - xxxxxxx - lavu 55.32.0 - frame.h + Add AVFrame.opaque_ref. + 2017-02-xx - xxxxxxx - lavu 55.31.1 - frame.h Allow passing the value of 0 (meaning "automatic") as the required alignment to av_frame_get_buffer(). diff --git a/libavutil/frame.c b/libavutil/frame.c index aa5820c0e95ce..9cd5f9ab37cb5 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -317,6 +317,8 @@ void av_frame_unref(AVFrame *frame) av_buffer_unref(&frame->hw_frames_ctx); + av_buffer_unref(&frame->opaque_ref); + get_frame_defaults(frame); } @@ -440,6 +442,13 @@ FF_ENABLE_DEPRECATION_WARNINGS av_dict_copy(&sd_dst->metadata, sd_src->metadata, 0); } + av_buffer_unref(&dst->opaque_ref); + if (src->opaque_ref) { + dst->opaque_ref = av_buffer_ref(src->opaque_ref); + if (!dst->opaque_ref) + return AVERROR(ENOMEM); + } + return 0; } diff --git a/libavutil/frame.h b/libavutil/frame.h index 4f63fb024911b..f9ffb5bbbf852 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -395,6 +395,17 @@ typedef struct AVFrame { /** * @} */ + + /** + * AVBufferRef for free use by the API user. Libav will never check the + * contents of the buffer ref. Libav calls av_buffer_unref() on it when + * the frame is unreferenced. av_frame_copy_props() calls create a new + * reference with av_buffer_ref() for the target frame's opaque_ref field. + * + * This is unrelated to the opaque field, although it serves a similar + * purpose. + */ + AVBufferRef *opaque_ref; } AVFrame; /** diff --git a/libavutil/version.h b/libavutil/version.h index 0768f9fe9996c..5dbc57cc1b475 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -54,8 +54,8 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 31 -#define LIBAVUTIL_VERSION_MICRO 1 +#define LIBAVUTIL_VERSION_MINOR 32 +#define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ LIBAVUTIL_VERSION_MINOR, \ From c2f97f050870897575570708ac48c5c15e6a0dd8 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 10 Feb 2017 12:17:24 +0100 Subject: [PATCH 0907/3374] hwcontext_dxva2: support D3D9Ex D3D9Ex uses different driver paths. This helps with "headless" configurations when no user logs in. Plain D3D9 device creation will fail if no user is logged in, while it works with D3D9Ex. Signed-off-by: Anton Khirnov --- libavutil/hwcontext_dxva2.c | 117 +++++++++++++++++++++++++++--------- 1 file changed, 87 insertions(+), 30 deletions(-) diff --git a/libavutil/hwcontext_dxva2.c b/libavutil/hwcontext_dxva2.c index ccf03c8e9ff9b..3790bed4b748a 100644 --- a/libavutil/hwcontext_dxva2.c +++ b/libavutil/hwcontext_dxva2.c @@ -38,8 +38,22 @@ #include "pixfmt.h" typedef IDirect3D9* WINAPI pDirect3DCreate9(UINT); +typedef HRESULT WINAPI pDirect3DCreate9Ex(UINT, IDirect3D9Ex **); typedef HRESULT WINAPI pCreateDeviceManager9(UINT *, IDirect3DDeviceManager9 **); +#define FF_D3DCREATE_FLAGS (D3DCREATE_SOFTWARE_VERTEXPROCESSING | \ + D3DCREATE_MULTITHREADED | \ + D3DCREATE_FPU_PRESERVE) + +static const D3DPRESENT_PARAMETERS dxva2_present_params = { + .Windowed = TRUE, + .BackBufferWidth = 640, + .BackBufferHeight = 480, + .BackBufferCount = 0, + .SwapEffect = D3DSWAPEFFECT_DISCARD, + .Flags = D3DPRESENTFLAG_VIDEO, +}; + typedef struct DXVA2Mapping { uint32_t palette_dummy[256]; } DXVA2Mapping; @@ -411,19 +425,83 @@ static void dxva2_device_free(AVHWDeviceContext *ctx) av_freep(&ctx->user_opaque); } +static int dxva2_device_create9(AVHWDeviceContext *ctx, UINT adapter) +{ + DXVA2DevicePriv *priv = ctx->user_opaque; + D3DPRESENT_PARAMETERS d3dpp = dxva2_present_params; + D3DDISPLAYMODE d3ddm; + HRESULT hr; + pDirect3DCreate9 *createD3D = (pDirect3DCreate9 *)GetProcAddress(priv->d3dlib, "Direct3DCreate9"); + if (!createD3D) { + av_log(ctx, AV_LOG_ERROR, "Failed to locate Direct3DCreate9\n"); + return AVERROR_UNKNOWN; + } + + priv->d3d9 = createD3D(D3D_SDK_VERSION); + if (!priv->d3d9) { + av_log(ctx, AV_LOG_ERROR, "Failed to create IDirect3D object\n"); + return AVERROR_UNKNOWN; + } + + IDirect3D9_GetAdapterDisplayMode(priv->d3d9, adapter, &d3ddm); + + d3dpp.BackBufferFormat = d3ddm.Format; + + hr = IDirect3D9_CreateDevice(priv->d3d9, adapter, D3DDEVTYPE_HAL, GetShellWindow(), + FF_D3DCREATE_FLAGS, + &d3dpp, &priv->d3d9device); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Failed to create Direct3D device\n"); + return AVERROR_UNKNOWN; + } + + return 0; +} + +static int dxva2_device_create9ex(AVHWDeviceContext *ctx, UINT adapter) +{ + DXVA2DevicePriv *priv = ctx->user_opaque; + D3DPRESENT_PARAMETERS d3dpp = dxva2_present_params; + D3DDISPLAYMODEEX modeex = {0}; + IDirect3D9Ex *d3d9ex = NULL; + IDirect3DDevice9Ex *exdev = NULL; + HRESULT hr; + pDirect3DCreate9Ex *createD3DEx = (pDirect3DCreate9Ex *)GetProcAddress(priv->d3dlib, "Direct3DCreate9Ex"); + if (!createD3DEx) + return AVERROR(ENOSYS); + + hr = createD3DEx(D3D_SDK_VERSION, &d3d9ex); + if (FAILED(hr)) + return AVERROR_UNKNOWN; + + IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, adapter, &modeex, NULL); + + d3dpp.BackBufferFormat = modeex.Format; + + hr = IDirect3D9Ex_CreateDeviceEx(d3d9ex, adapter, D3DDEVTYPE_HAL, GetShellWindow(), + FF_D3DCREATE_FLAGS, + &d3dpp, NULL, &exdev); + if (FAILED(hr)) { + IDirect3D9Ex_Release(d3d9ex); + return AVERROR_UNKNOWN; + } + + av_log(ctx, AV_LOG_VERBOSE, "Using D3D9Ex device.\n"); + priv->d3d9 = (IDirect3D9 *)d3d9ex; + priv->d3d9device = (IDirect3DDevice9 *)exdev; + return 0; +} + static int dxva2_device_create(AVHWDeviceContext *ctx, const char *device, AVDictionary *opts, int flags) { AVDXVA2DeviceContext *hwctx = ctx->hwctx; DXVA2DevicePriv *priv; - - pDirect3DCreate9 *createD3D = NULL; pCreateDeviceManager9 *createDeviceManager = NULL; - D3DPRESENT_PARAMETERS d3dpp = {0}; - D3DDISPLAYMODE d3ddm; unsigned resetToken = 0; UINT adapter = D3DADAPTER_DEFAULT; HRESULT hr; + int err; if (device) adapter = atoi(device); @@ -448,11 +526,6 @@ static int dxva2_device_create(AVHWDeviceContext *ctx, const char *device, return AVERROR_UNKNOWN; } - createD3D = (pDirect3DCreate9 *)GetProcAddress(priv->d3dlib, "Direct3DCreate9"); - if (!createD3D) { - av_log(ctx, AV_LOG_ERROR, "Failed to locate Direct3DCreate9\n"); - return AVERROR_UNKNOWN; - } createDeviceManager = (pCreateDeviceManager9 *)GetProcAddress(priv->dxva2lib, "DXVA2CreateDirect3DDeviceManager9"); if (!createDeviceManager) { @@ -460,27 +533,11 @@ static int dxva2_device_create(AVHWDeviceContext *ctx, const char *device, return AVERROR_UNKNOWN; } - priv->d3d9 = createD3D(D3D_SDK_VERSION); - if (!priv->d3d9) { - av_log(ctx, AV_LOG_ERROR, "Failed to create IDirect3D object\n"); - return AVERROR_UNKNOWN; - } - - IDirect3D9_GetAdapterDisplayMode(priv->d3d9, adapter, &d3ddm); - d3dpp.Windowed = TRUE; - d3dpp.BackBufferWidth = 640; - d3dpp.BackBufferHeight = 480; - d3dpp.BackBufferCount = 0; - d3dpp.BackBufferFormat = d3ddm.Format; - d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; - d3dpp.Flags = D3DPRESENTFLAG_VIDEO; - - hr = IDirect3D9_CreateDevice(priv->d3d9, adapter, D3DDEVTYPE_HAL, GetShellWindow(), - D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE, - &d3dpp, &priv->d3d9device); - if (FAILED(hr)) { - av_log(ctx, AV_LOG_ERROR, "Failed to create Direct3D device\n"); - return AVERROR_UNKNOWN; + if (dxva2_device_create9ex(ctx, adapter) < 0) { + // Retry with "classic" d3d9 + err = dxva2_device_create9(ctx, adapter); + if (err < 0) + return err; } hr = createDeviceManager(&resetToken, &hwctx->devmgr); From 0ee78020cd41d81eec651acd7fc65906207796f3 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Fri, 10 Feb 2017 19:31:34 +0000 Subject: [PATCH 0908/3374] configure: Move up the avbuild directory creation The early check for inconsistent in-source vs out-of-source build cannot generate a config.log otherwise. Signed-off-by: Luca Barbato --- configure | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 9ebc3bf8948fb..69f5863582646 100755 --- a/configure +++ b/configure @@ -2622,6 +2622,8 @@ target_path='$(CURDIR)' DEPCMD='$(DEP$(1)) $(DEP$(1)FLAGS) $($(1)DEP_FLAGS) $< | sed -e "/^\#.*/d" -e "s,^[[:space:]]*$(*F)\\.o,$(@D)/$(*F).o," > $(@:.o=.d)' DEPFLAGS='-MM' +mkdir -p avbuild + # find source path if test -f configure; then source_path=. @@ -2839,7 +2841,6 @@ disable_components(){ map 'disable_components $v' $LIBRARY_LIST -mkdir -p avbuild echo "# $0 $LIBAV_CONFIGURATION" > $logfile set >> $logfile From ba30b74686f0cb6c9dd465ac4820059c48bf9d08 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sat, 11 Feb 2017 15:40:20 +0100 Subject: [PATCH 0909/3374] aac: Validate the sbr sample rate before using the value Avoid a floating point exception. Bug-Id: 1027 CC: libav-stable@libav.org --- libavcodec/aacsbr.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/libavcodec/aacsbr.c b/libavcodec/aacsbr.c index fc08079194938..99f7b0829c4bd 100644 --- a/libavcodec/aacsbr.c +++ b/libavcodec/aacsbr.c @@ -327,16 +327,6 @@ static int sbr_make_f_master(AACContext *ac, SpectralBandReplication *sbr, const int8_t *sbr_offset_ptr; int16_t stop_dk[13]; - if (sbr->sample_rate < 32000) { - temp = 3000; - } else if (sbr->sample_rate < 64000) { - temp = 4000; - } else - temp = 5000; - - start_min = ((temp << 7) + (sbr->sample_rate >> 1)) / sbr->sample_rate; - stop_min = ((temp << 8) + (sbr->sample_rate >> 1)) / sbr->sample_rate; - switch (sbr->sample_rate) { case 16000: sbr_offset_ptr = sbr_offset[0]; @@ -362,6 +352,16 @@ static int sbr_make_f_master(AACContext *ac, SpectralBandReplication *sbr, return -1; } + if (sbr->sample_rate < 32000) { + temp = 3000; + } else if (sbr->sample_rate < 64000) { + temp = 4000; + } else + temp = 5000; + + start_min = ((temp << 7) + (sbr->sample_rate >> 1)) / sbr->sample_rate; + stop_min = ((temp << 8) + (sbr->sample_rate >> 1)) / sbr->sample_rate; + sbr->k[0] = start_min + sbr_offset_ptr[spectrum->bs_start_freq]; if (spectrum->bs_stop_freq < 14) { From 9c2d36fcaf8748b9baa9aba9264abefce711d67b Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 11 Apr 2016 19:18:50 +0200 Subject: [PATCH 0910/3374] dv: Convert to the new bitstream reader --- libavcodec/bitstream.h | 28 +++++++++++++ libavcodec/dvdec.c | 94 ++++++++++++++++++------------------------ 2 files changed, 69 insertions(+), 53 deletions(-) diff --git a/libavcodec/bitstream.h b/libavcodec/bitstream.h index 996e32e83b91a..894a13e348e30 100644 --- a/libavcodec/bitstream.h +++ b/libavcodec/bitstream.h @@ -384,4 +384,32 @@ static inline int bitstream_apply_sign(BitstreamContext *bc, int val) return (val ^ sign) - sign; } +/* Unwind the cache so a refill_32 can fill it again. */ +static inline void bitstream_unwind(BitstreamContext *bc) +{ + int unwind = 4; + int unwind_bits = unwind * 8; + + if (bc->bits_left < unwind_bits) + return; + + bc->bits >>= unwind_bits; + bc->bits <<= unwind_bits; + bc->bits_left -= unwind_bits; + bc->ptr -= unwind; +} + +/* Unget up to 32 bits. */ +static inline void bitstream_unget(BitstreamContext *bc, uint64_t value, + size_t amount) +{ + size_t cache_size = sizeof(bc->bits) * 8; + + if (bc->bits_left + amount > cache_size) + bitstream_unwind(bc); + + bc->bits = (bc->bits >> amount) | (value << (cache_size - amount)); + bc->bits_left += amount; +} + #endif /* AVCODEC_BITSTREAM_H */ diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c index dc37a5efddd2b..a2f0171a1c71a 100644 --- a/libavcodec/dvdec.c +++ b/libavcodec/dvdec.c @@ -40,9 +40,9 @@ #include "libavutil/pixdesc.h" #include "avcodec.h" +#include "bitstream.h" #include "dv.h" #include "dvdata.h" -#include "get_bits.h" #include "idctdsp.h" #include "internal.h" #include "put_bits.h" @@ -80,51 +80,34 @@ static av_cold int dvvideo_decode_init(AVCodecContext *avctx) } /* decode AC coefficients */ -static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, int16_t *block) +static void dv_decode_ac(BitstreamContext *bc, BlockInfo *mb, int16_t *block) { - int last_index = gb->size_in_bits; const uint8_t *scan_table = mb->scan_table; const uint32_t *factor_table = mb->factor_table; int pos = mb->pos; int partial_bit_count = mb->partial_bit_count; - int level, run, vlc_len, index; - - OPEN_READER_NOSIZE(re, gb); - UPDATE_CACHE(re, gb); + int level, run; /* if we must parse a partial VLC, we do it here */ if (partial_bit_count > 0) { - re_cache = re_cache >> partial_bit_count | - mb->partial_bit_buffer; - re_index -= partial_bit_count; + bitstream_unget(bc, mb->partial_bit_buffer, partial_bit_count); mb->partial_bit_count = 0; } /* get the AC coefficients until last_index is reached */ for (;;) { - ff_dlog(NULL, "%2d: bits=%04x index=%u\n", pos, SHOW_UBITS(re, gb, 16), - re_index); - /* our own optimized GET_RL_VLC */ - index = NEG_USR32(re_cache, TEX_VLC_BITS); - vlc_len = ff_dv_rl_vlc[index].len; - if (vlc_len < 0) { - index = NEG_USR32((unsigned) re_cache << TEX_VLC_BITS, -vlc_len) + - ff_dv_rl_vlc[index].level; - vlc_len = TEX_VLC_BITS - vlc_len; - } - level = ff_dv_rl_vlc[index].level; - run = ff_dv_rl_vlc[index].run; - - /* gotta check if we're still within gb boundaries */ - if (re_index + vlc_len > last_index) { - /* should be < 16 bits otherwise a codeword could have been parsed */ - mb->partial_bit_count = last_index - re_index; - mb->partial_bit_buffer = re_cache & ~(-1u >> mb->partial_bit_count); - re_index = last_index; + BitstreamContext tmp = *bc; + + ff_dlog(NULL, "%2d: bits=%04x index=%d\n", + pos, bitstream_peek(bc, 16), bitstream_tell(bc)); + + BITSTREAM_RL_VLC(level, run, bc, ff_dv_rl_vlc, TEX_VLC_BITS, 2); + + if (bitstream_bits_left(bc) < 0) { + mb->partial_bit_count = bitstream_bits_left(&tmp); + mb->partial_bit_buffer = bitstream_peek(&tmp, mb->partial_bit_count); break; } - re_index += vlc_len; - ff_dlog(NULL, "run=%d level=%d\n", run, level); pos += run; if (pos >= 64) @@ -133,22 +116,22 @@ static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, int16_t *block) level = (level * factor_table[pos] + (1 << (dv_iweight_bits - 1))) >> dv_iweight_bits; block[scan_table[pos]] = level; - - UPDATE_CACHE(re, gb); } - CLOSE_READER(re, gb); mb->pos = pos; } -static inline void bit_copy(PutBitContext *pb, GetBitContext *gb) +static inline void bit_copy(PutBitContext *pb, BitstreamContext *bc) { - int bits_left = get_bits_left(gb); - while (bits_left >= MIN_CACHE_BITS) { - put_bits(pb, MIN_CACHE_BITS, get_bits(gb, MIN_CACHE_BITS)); - bits_left -= MIN_CACHE_BITS; + int bits_left = bitstream_bits_left(bc); + + while (bits_left >= 32) { + int read = bitstream_read(bc, 32); + put_bits32(pb, read); + bits_left -= 32; } + if (bits_left > 0) - put_bits(pb, bits_left, get_bits(gb, bits_left)); + put_bits(pb, bits_left, bitstream_read(bc, bits_left)); } /* mb_x and mb_y are in units of 8 pixels */ @@ -164,13 +147,14 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg) uint8_t *y_ptr; const uint8_t *buf_ptr; PutBitContext pb, vs_pb; - GetBitContext gb; + BitstreamContext bc; BlockInfo mb_data[5 * DV_MAX_BPM], *mb, *mb1; LOCAL_ALIGNED_16(int16_t, sblock, [5 * DV_MAX_BPM], [64]); LOCAL_ALIGNED_16(uint8_t, mb_bit_buffer, [80 + AV_INPUT_BUFFER_PADDING_SIZE]); /* allow some slack */ LOCAL_ALIGNED_16(uint8_t, vs_bit_buffer, [80 * 5 + AV_INPUT_BUFFER_PADDING_SIZE]); /* allow some slack */ const int log2_blocksize = 3; int is_field_mode[5]; + int mb_bits; assert((((int) mb_bit_buffer) & 7) == 0); assert((((int) vs_bit_buffer) & 7) == 0); @@ -192,12 +176,12 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg) is_field_mode[mb_index] = 0; for (j = 0; j < s->sys->bpm; j++) { last_index = s->sys->block_sizes[j]; - init_get_bits(&gb, buf_ptr, last_index); + bitstream_init(&bc, buf_ptr, last_index); /* get the DC */ - dc = get_sbits(&gb, 9); - dct_mode = get_bits1(&gb); - class1 = get_bits(&gb, 2); + dc = bitstream_read_signed(&bc, 9); + dct_mode = bitstream_read_bit(&bc); + class1 = bitstream_read(&bc, 2); if (DV_PROFILE_IS_HD(s->sys)) { mb->idct_put = s->idct_put[0]; mb->scan_table = s->dv_zigzag[0]; @@ -223,12 +207,12 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg) mb->partial_bit_count = 0; ff_dlog(avctx, "MB block: %d, %d ", mb_index, j); - dv_decode_ac(&gb, mb, block); + dv_decode_ac(&bc, mb, block); /* write the remaining bits in a new buffer only if the * block is finished */ if (mb->pos >= 64) - bit_copy(&pb, &gb); + bit_copy(&pb, &bc); block += 64; mb++; @@ -238,12 +222,15 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg) ff_dlog(avctx, "***pass 2 size=%d MB#=%d\n", put_bits_count(&pb), mb_index); block = block1; mb = mb1; - init_get_bits(&gb, mb_bit_buffer, put_bits_count(&pb)); + + mb_bits = put_bits_count(&pb); put_bits32(&pb, 0); // padding must be zeroed flush_put_bits(&pb); + bitstream_init(&bc, mb_bit_buffer, mb_bits); + for (j = 0; j < s->sys->bpm; j++, block += 64, mb++) { - if (mb->pos < 64 && get_bits_left(&gb) > 0) { - dv_decode_ac(&gb, mb, block); + if (mb->pos < 64 && bitstream_bits_left(&bc) > 0) { + dv_decode_ac(&bc, mb, block); /* if still not finished, no need to parse other blocks */ if (mb->pos < 64) break; @@ -252,21 +239,22 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg) /* all blocks are finished, so the extra bytes can be used at * the video segment level */ if (j >= s->sys->bpm) - bit_copy(&vs_pb, &gb); + bit_copy(&vs_pb, &bc); } /* we need a pass over the whole video segment */ ff_dlog(avctx, "***pass 3 size=%d\n", put_bits_count(&vs_pb)); block = &sblock[0][0]; mb = mb_data; - init_get_bits(&gb, vs_bit_buffer, put_bits_count(&vs_pb)); + mb_bits = put_bits_count(&vs_pb); put_bits32(&vs_pb, 0); // padding must be zeroed flush_put_bits(&vs_pb); + bitstream_init(&bc, vs_bit_buffer, mb_bits); for (mb_index = 0; mb_index < 5; mb_index++) { for (j = 0; j < s->sys->bpm; j++) { if (mb->pos < 64) { ff_dlog(avctx, "start %d:%d\n", mb_index, j); - dv_decode_ac(&gb, mb, block); + dv_decode_ac(&bc, mb, block); } if (mb->pos >= 64 && mb->pos < 127) av_log(avctx, AV_LOG_ERROR, From e18c39005ad1dbb178b336f691da1de91afd434e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 10 Jan 2017 16:49:13 +0200 Subject: [PATCH 0911/3374] arm: vp9lpf: Interleave the start of flat8in into the calculation above MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds lots of extra .ifs, but speeds it up by a couple cycles, by avoiding stalls. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9lpf_neon.S | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libavcodec/arm/vp9lpf_neon.S b/libavcodec/arm/vp9lpf_neon.S index c2f1c954274b1..1e161e0c63da7 100644 --- a/libavcodec/arm/vp9lpf_neon.S +++ b/libavcodec/arm/vp9lpf_neon.S @@ -182,16 +182,20 @@ vmovl.u8 q0, d22 @ p1 vmovl.u8 q1, d25 @ q1 +.if \wd >= 8 + vmov r2, r3, d6 +.endif vaddw.s8 q0, q0, \tmp3 @ p1 + f vsubw.s8 q1, q1, \tmp3 @ q1 - f +.if \wd >= 8 + orrs r2, r2, r3 +.endif vqmovun.s16 d0, q0 @ out p1 vqmovun.s16 d2, q1 @ out q1 vbit d22, d0, d5 @ if (!hev && fm && !flat8in) vbit d25, d2, d5 .if \wd >= 8 - vmov r2, r3, d6 - orrs r2, r2, r3 @ If no pixels need flat8in, jump to flat8out @ (or to a writeout of the inner 4 pixels, for wd=8) beq 6f From b0806088d3b27044145b20421da8d39089ae0c6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 10 Jan 2017 22:08:50 +0200 Subject: [PATCH 0912/3374] aarch64: vp9lpf: Interleave the start of flat8in into the calculation above MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds lots of extra .ifs, but speeds it up by a couple cycles, by avoiding stalls. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9lpf_neon.S | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/libavcodec/aarch64/vp9lpf_neon.S b/libavcodec/aarch64/vp9lpf_neon.S index 3b8e6ebc99bea..2b8a4783837b2 100644 --- a/libavcodec/aarch64/vp9lpf_neon.S +++ b/libavcodec/aarch64/vp9lpf_neon.S @@ -338,20 +338,28 @@ uxtl_sz v0.8h, v1.8h, v22, \sz // p1 uxtl_sz v2.8h, v3.8h, v25, \sz // q1 +.if \wd >= 8 + mov x5, v6.d[0] +.ifc \sz, .16b + mov x6, v6.d[1] +.endif +.endif saddw_sz v0.8h, v1.8h, v0.8h, v1.8h, \tmp3, \sz // p1 + f ssubw_sz v2.8h, v3.8h, v2.8h, v3.8h, \tmp3, \sz // q1 - f sqxtun_sz v0, v0.8h, v1.8h, \sz // out p1 sqxtun_sz v2, v2.8h, v3.8h, \sz // out q1 +.if \wd >= 8 +.ifc \sz, .16b + adds x5, x5, x6 +.endif +.endif bit v22\sz, v0\sz, v5\sz // if (!hev && fm && !flat8in) bit v25\sz, v2\sz, v5\sz // If no pixels need flat8in, jump to flat8out // (or to a writeout of the inner 4 pixels, for wd=8) .if \wd >= 8 - mov x5, v6.d[0] .ifc \sz, .16b - mov x6, v6.d[1] - adds x5, x5, x6 b.eq 6f .else cbz x5, 6f From 07b5136c481d394992c7e951967df0cfbb346c0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 11 Jan 2017 11:58:02 +0200 Subject: [PATCH 0913/3374] aarch64: vp9lpf: Fix broken indentation/vertical alignment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9lpf_neon.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/aarch64/vp9lpf_neon.S b/libavcodec/aarch64/vp9lpf_neon.S index 2b8a4783837b2..5fafc7ad5c9b8 100644 --- a/libavcodec/aarch64/vp9lpf_neon.S +++ b/libavcodec/aarch64/vp9lpf_neon.S @@ -417,7 +417,7 @@ mov x5, v2.d[0] .ifc \sz, .16b mov x6, v2.d[1] - adds x5, x5, x6 + adds x5, x5, x6 b.ne 1f .else cbnz x5, 1f @@ -430,7 +430,7 @@ mov x5, v7.d[0] .ifc \sz, .16b mov x6, v7.d[1] - adds x5, x5, x6 + adds x5, x5, x6 b.ne 1f .else cbnz x5, 1f From 44f2eda39ff55c69d4d739fb12a42a10b7ce581c Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sat, 11 Feb 2017 15:13:04 +0000 Subject: [PATCH 0914/3374] lavc: Add device context field to AVCodecContext For use by codec implementations which can allocate frames internally. --- doc/APIchanges | 3 +++ libavcodec/avcodec.h | 25 ++++++++++++++++++++++++- libavcodec/utils.c | 1 + libavcodec/version.h | 2 +- 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index e7a0b14038bd2..a919ffb2bf302 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-xx-xx - xxxxxxx - lavc 57.34.0 - avcodec.h + Add AVCodecContext.hw_device_ctx. + 2017-02-11 - xxxxxxx - lavu 55.32.0 - frame.h Add AVFrame.opaque_ref. diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 8d8fa594aa280..b7bf85a041d37 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3093,7 +3093,8 @@ typedef struct AVCodecContext { /** * A reference to the AVHWFramesContext describing the input (for encoding) * or output (decoding) frames. The reference is set by the caller and - * afterwards owned (and freed) by libavcodec. + * afterwards owned (and freed) by libavcodec - it should never be read by + * the caller after being set. * * - decoding: This field should be set by the caller from the get_format() * callback. The previous reference (if any) will always be @@ -3139,6 +3140,28 @@ typedef struct AVCodecContext { * (with the display dimensions being determined by the crop_* fields). */ int apply_cropping; + + /** + * A reference to the AVHWDeviceContext describing the device which will + * be used by a hardware encoder/decoder. The reference is set by the + * caller and afterwards owned (and freed) by libavcodec. + * + * This should be used if either the codec device does not require + * hardware frames or any that are used are to be allocated internally by + * libavcodec. If the user wishes to supply any of the frames used as + * encoder input or decoder output then hw_frames_ctx should be used + * instead. When hw_frames_ctx is set in get_format() for a decoder, this + * field will be ignored while decoding the associated stream segment, but + * may again be used on a following one after another get_format() call. + * + * For both encoders and decoders this field should be set before + * avcodec_open2() is called and must not be written to thereafter. + * + * Note that some decoders may require this field to be set initially in + * order to support hw_frames_ctx at all - in that case, all frames + * contexts used must be created on the same device. + */ + AVBufferRef *hw_device_ctx; } AVCodecContext; /** diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 06a5784046763..ea4d5fa3129ee 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -794,6 +794,7 @@ av_cold int avcodec_close(AVCodecContext *avctx) avctx->nb_coded_side_data = 0; av_buffer_unref(&avctx->hw_frames_ctx); + av_buffer_unref(&avctx->hw_device_ctx); if (avctx->priv_data && avctx->codec && avctx->codec->priv_class) av_opt_free(avctx->priv_data); diff --git a/libavcodec/version.h b/libavcodec/version.h index 2ade539c60996..a6eda6a691197 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 33 +#define LIBAVCODEC_VERSION_MINOR 34 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ From 5dd9a4b88b287bf8c93520afda7becb1ad0d1894 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sat, 11 Feb 2017 15:13:12 +0000 Subject: [PATCH 0915/3374] vaapi: Implement device-only setup In this case, the user only supplies a device and the frame context is allocated internally by lavc. --- libavcodec/vaapi_decode.c | 129 ++++++++++++++++++++++++++++++++------ libavcodec/vaapi_decode.h | 3 + 2 files changed, 114 insertions(+), 18 deletions(-) diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c index 42f03ab1414cf..0db79d401db99 100644 --- a/libavcodec/vaapi_decode.c +++ b/libavcodec/vaapi_decode.c @@ -18,6 +18,7 @@ #include "libavutil/avassert.h" #include "libavutil/common.h" +#include "libavutil/pixdesc.h" #include "avcodec.h" #include "internal.h" @@ -280,6 +281,7 @@ static int vaapi_decode_make_config(AVCodecContext *avctx) const AVCodecDescriptor *codec_desc; VAProfile profile, *profile_list = NULL; int profile_count, exact_match, alt_profile; + const AVPixFmtDescriptor *sw_desc, *desc; // Allowing a profile mismatch can be useful because streams may // over-declare their required capabilities - in particular, many @@ -373,7 +375,9 @@ static int vaapi_decode_make_config(AVCodecContext *avctx) goto fail; } - hwconfig = av_hwdevice_hwconfig_alloc(ctx->frames->device_ref); + hwconfig = av_hwdevice_hwconfig_alloc(avctx->hw_device_ctx ? + avctx->hw_device_ctx : + ctx->frames->device_ref); if (!hwconfig) { err = AVERROR(ENOMEM); goto fail; @@ -381,24 +385,77 @@ static int vaapi_decode_make_config(AVCodecContext *avctx) hwconfig->config_id = ctx->va_config; constraints = - av_hwdevice_get_hwframe_constraints(ctx->frames->device_ref, + av_hwdevice_get_hwframe_constraints(avctx->hw_device_ctx ? + avctx->hw_device_ctx : + ctx->frames->device_ref, hwconfig); if (!constraints) { - // Ignore. - } else { - if (avctx->coded_width < constraints->min_width || - avctx->coded_height < constraints->min_height || - avctx->coded_width > constraints->max_width || - avctx->coded_height > constraints->max_height) { - av_log(avctx, AV_LOG_ERROR, "Hardware does not support image " - "size %dx%d (constraints: width %d-%d height %d-%d).\n", - avctx->coded_width, avctx->coded_height, - constraints->min_width, constraints->max_width, - constraints->min_height, constraints->max_height); - err = AVERROR(EINVAL); - goto fail; + err = AVERROR(ENOMEM); + goto fail; + } + + if (avctx->coded_width < constraints->min_width || + avctx->coded_height < constraints->min_height || + avctx->coded_width > constraints->max_width || + avctx->coded_height > constraints->max_height) { + av_log(avctx, AV_LOG_ERROR, "Hardware does not support image " + "size %dx%d (constraints: width %d-%d height %d-%d).\n", + avctx->coded_width, avctx->coded_height, + constraints->min_width, constraints->max_width, + constraints->min_height, constraints->max_height); + err = AVERROR(EINVAL); + goto fail; + } + if (!constraints->valid_sw_formats || + constraints->valid_sw_formats[0] == AV_PIX_FMT_NONE) { + av_log(avctx, AV_LOG_ERROR, "Hardware does not offer any " + "usable surface formats.\n"); + err = AVERROR(EINVAL); + goto fail; + } + + // Find the first format in the list which matches the expected + // bit depth and subsampling. If none are found (this can happen + // when 10-bit streams are decoded to 8-bit surfaces, for example) + // then just take the first format on the list. + ctx->surface_format = constraints->valid_sw_formats[0]; + sw_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt); + for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) { + desc = av_pix_fmt_desc_get(constraints->valid_sw_formats[i]); + if (desc->nb_components != sw_desc->nb_components || + desc->log2_chroma_w != sw_desc->log2_chroma_w || + desc->log2_chroma_h != sw_desc->log2_chroma_h) + continue; + for (j = 0; j < desc->nb_components; j++) { + if (desc->comp[j].depth != sw_desc->comp[j].depth) + break; } + if (j < desc->nb_components) + continue; + ctx->surface_format = constraints->valid_sw_formats[i]; + break; + } + + // Start with at least four surfaces. + ctx->surface_count = 4; + // Add per-codec number of surfaces used for storing reference frames. + switch (avctx->codec_id) { + case AV_CODEC_ID_H264: + case AV_CODEC_ID_HEVC: + ctx->surface_count += 16; + break; + case AV_CODEC_ID_VP9: + ctx->surface_count += 8; + break; + case AV_CODEC_ID_VP8: + ctx->surface_count += 3; + break; + default: + ctx->surface_count += 2; } + // Add an additional surface per thread is frame threading is enabled. + if (avctx->active_thread_type & FF_THREAD_FRAME) + ctx->surface_count += avctx->thread_count; av_hwframe_constraints_free(&constraints); av_freep(&hwconfig); @@ -461,13 +518,24 @@ int ff_vaapi_decode_init(AVCodecContext *avctx) ctx->frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data; ctx->hwfc = ctx->frames->hwctx; - ctx->device = ctx->frames->device_ctx; ctx->hwctx = ctx->device->hwctx; + } else if (avctx->hw_device_ctx) { + ctx->device = (AVHWDeviceContext*)avctx->hw_device_ctx->data; + ctx->hwctx = ctx->device->hwctx; + + if (ctx->device->type != AV_HWDEVICE_TYPE_VAAPI) { + av_log(avctx, AV_LOG_ERROR, "Device supplied for VAAPI " + "decoding must be a VAAPI device (not %d).\n", + ctx->device->type); + err = AVERROR(EINVAL); + goto fail; + } + } else { - av_log(avctx, AV_LOG_ERROR, "A hardware frames context is " - "required for VAAPI decoding.\n"); + av_log(avctx, AV_LOG_ERROR, "A hardware device or frames context " + "is required for VAAPI decoding.\n"); err = AVERROR(EINVAL); goto fail; } @@ -486,6 +554,31 @@ int ff_vaapi_decode_init(AVCodecContext *avctx) if (err) goto fail; + if (!avctx->hw_frames_ctx) { + avctx->hw_frames_ctx = av_hwframe_ctx_alloc(avctx->hw_device_ctx); + if (!avctx->hw_frames_ctx) { + err = AVERROR(ENOMEM); + goto fail; + } + ctx->frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data; + + ctx->frames->format = AV_PIX_FMT_VAAPI; + ctx->frames->width = avctx->coded_width; + ctx->frames->height = avctx->coded_height; + + ctx->frames->sw_format = ctx->surface_format; + ctx->frames->initial_pool_size = ctx->surface_count; + + err = av_hwframe_ctx_init(avctx->hw_frames_ctx); + if (err < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to initialise internal " + "frames context: %d.\n", err); + goto fail; + } + + ctx->hwfc = ctx->frames->hwctx; + } + vas = vaCreateContext(ctx->hwctx->display, ctx->va_config, avctx->coded_width, avctx->coded_height, VA_PROGRESSIVE, diff --git a/libavcodec/vaapi_decode.h b/libavcodec/vaapi_decode.h index 08b212d0302fc..0ff400e34c154 100644 --- a/libavcodec/vaapi_decode.h +++ b/libavcodec/vaapi_decode.h @@ -69,6 +69,9 @@ typedef struct VAAPIDecodeContext { AVHWFramesContext *frames; AVVAAPIFramesContext *hwfc; + + enum AVPixelFormat surface_format; + int surface_count; } VAAPIDecodeContext; From e791b915c774408fbc0ec9e7270b021899e08ccc Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Mon, 30 Jan 2017 19:11:28 +0000 Subject: [PATCH 0916/3374] hwcontext_vaapi: Try to support the VDPAU wrapper The driver is somewhat bitrotten (not updated for years) but is still usable for decoding with this change. To support it, this adds a new driver quirk to indicate no support at all for surface attributes. Based on a patch by wm4 . --- libavutil/hwcontext_vaapi.c | 79 +++++++++++++++++++++---------------- libavutil/hwcontext_vaapi.h | 7 ++++ 2 files changed, 52 insertions(+), 34 deletions(-) diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index f8719aaf0adb4..23bce76605025 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -153,7 +153,8 @@ static int vaapi_frames_get_constraints(AVHWDeviceContext *hwdev, unsigned int fourcc; int err, i, j, attr_count, pix_fmt_count; - if (config) { + if (config && + !(hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES)) { attr_count = 0; vas = vaQuerySurfaceAttributes(hwctx->display, config->config_id, 0, &attr_count); @@ -271,6 +272,11 @@ static const struct { "ubit", AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE, }, + { + "VDPAU wrapper", + "Splitted-Desktop Systems VDPAU backend for VA-API", + AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES, + }, }; static int vaapi_device_init(AVHWDeviceContext *hwdev) @@ -449,43 +455,48 @@ static int vaapi_frames_init(AVHWFramesContext *hwfc) } if (!hwfc->pool) { - int need_memory_type = !(hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE); - int need_pixel_format = 1; - for (i = 0; i < avfc->nb_attributes; i++) { - if (ctx->attributes[i].type == VASurfaceAttribMemoryType) - need_memory_type = 0; - if (ctx->attributes[i].type == VASurfaceAttribPixelFormat) - need_pixel_format = 0; - } - ctx->nb_attributes = - avfc->nb_attributes + need_memory_type + need_pixel_format; + if (!(hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES)) { + int need_memory_type = !(hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE); + int need_pixel_format = 1; + for (i = 0; i < avfc->nb_attributes; i++) { + if (ctx->attributes[i].type == VASurfaceAttribMemoryType) + need_memory_type = 0; + if (ctx->attributes[i].type == VASurfaceAttribPixelFormat) + need_pixel_format = 0; + } + ctx->nb_attributes = + avfc->nb_attributes + need_memory_type + need_pixel_format; - ctx->attributes = av_malloc(ctx->nb_attributes * + ctx->attributes = av_malloc(ctx->nb_attributes * sizeof(*ctx->attributes)); - if (!ctx->attributes) { - err = AVERROR(ENOMEM); - goto fail; - } + if (!ctx->attributes) { + err = AVERROR(ENOMEM); + goto fail; + } - for (i = 0; i < avfc->nb_attributes; i++) - ctx->attributes[i] = avfc->attributes[i]; - if (need_memory_type) { - ctx->attributes[i++] = (VASurfaceAttrib) { - .type = VASurfaceAttribMemoryType, - .flags = VA_SURFACE_ATTRIB_SETTABLE, - .value.type = VAGenericValueTypeInteger, - .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA, - }; - } - if (need_pixel_format) { - ctx->attributes[i++] = (VASurfaceAttrib) { - .type = VASurfaceAttribPixelFormat, - .flags = VA_SURFACE_ATTRIB_SETTABLE, - .value.type = VAGenericValueTypeInteger, - .value.value.i = fourcc, - }; + for (i = 0; i < avfc->nb_attributes; i++) + ctx->attributes[i] = avfc->attributes[i]; + if (need_memory_type) { + ctx->attributes[i++] = (VASurfaceAttrib) { + .type = VASurfaceAttribMemoryType, + .flags = VA_SURFACE_ATTRIB_SETTABLE, + .value.type = VAGenericValueTypeInteger, + .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA, + }; + } + if (need_pixel_format) { + ctx->attributes[i++] = (VASurfaceAttrib) { + .type = VASurfaceAttribPixelFormat, + .flags = VA_SURFACE_ATTRIB_SETTABLE, + .value.type = VAGenericValueTypeInteger, + .value.value.i = fourcc, + }; + } + av_assert0(i == ctx->nb_attributes); + } else { + ctx->attributes = NULL; + ctx->nb_attributes = 0; } - av_assert0(i == ctx->nb_attributes); ctx->rt_format = rt_format; diff --git a/libavutil/hwcontext_vaapi.h b/libavutil/hwcontext_vaapi.h index 9f1e78a4146bb..529d26e07a18a 100644 --- a/libavutil/hwcontext_vaapi.h +++ b/libavutil/hwcontext_vaapi.h @@ -51,6 +51,13 @@ enum { * so the surface allocation code will not try to use it. */ AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE = (1 << 2), + + /** + * The driver does not support surface attributes at all. + * The surface allocation code will never pass them to surface allocation, + * and the results of the vaQuerySurfaceAttributes() call will be faked. + */ + AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES = (1 << 3), }; /** From b446f0e98f85e2e931b476e52b319f1c49244660 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sat, 11 Feb 2017 21:44:08 +0000 Subject: [PATCH 0917/3374] mov: Do not try to parse multiple stsd for the same track Bug-Id: 1017 CC: libav-stable@libav.org Signed-off-by: Luca Barbato --- libavformat/mov.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libavformat/mov.c b/libavformat/mov.c index 11bcff035c89b..5c9f85c738da6 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1911,6 +1911,12 @@ static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom) avio_rb24(pb); /* flags */ entries = avio_rb32(pb); + if (sc->extradata) { + av_log(c->fc, AV_LOG_ERROR, + "Duplicate stsd found in this track.\n"); + return AVERROR_INVALIDDATA; + } + /* Prepare space for hosting multiple extradata. */ sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata)); if (!sc->extradata) From 871b4f3654636ed64560e86b9faa33828d195ceb Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 11 Feb 2017 11:47:34 +0100 Subject: [PATCH 0918/3374] configure: Check for xcb as well as xcb-shape before enabling libxcb Newer versions of libxcb have xcb-foo pkg-config files that do not declare their xcb dependency so that required linker flags will not be generated. --- configure | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/configure b/configure index 69f5863582646..b8cbe175e82cb 100755 --- a/configure +++ b/configure @@ -1752,8 +1752,9 @@ CONFIG_EXTRA=" iso_media ividsp jpegtables - libx262 lgplv3 + libx262 + libxcb_shape lpc lzf me_cmp @@ -2420,7 +2421,7 @@ sndio_indev_deps="sndio" sndio_outdev_deps="sndio" v4l2_indev_deps_any="linux_videodev2_h sys_videoio_h" vfwcap_indev_deps="vfw32 vfwcap_defines" -xcbgrab_indev_deps="libxcb" +xcbgrab_indev_deps="libxcb libxcb_shape" xcbgrab_indev_suggest="libxcb_shm libxcb_xfixes" # protocols @@ -4797,7 +4798,8 @@ if enabled libcdio; then fi if enabled libxcb; then - require_pkg_config libxcb xcb-shape xcb/shape.h xcb_shape_rectangles + require_pkg_config libxcb xcb xcb/xcb.h xcb_connect + require_pkg_config libxcb_shape xcb-shape xcb/shape.h xcb_shape_rectangles disabled libxcb_shm || require_pkg_config libxcb_shm xcb-shm xcb/shm.h xcb_shm_attach disabled libxcb_xfixes || From 0539d84d985e811e5989ef27c13f7e2dda0f9b89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Wed, 8 Feb 2017 12:51:37 +0100 Subject: [PATCH 0919/3374] asfdec: Account for different Format Data sizes Some muxers may use the BMP_HEADER Format Data size instead of the ASF-specific one. Bug-Id: 1020 CC: libav-stable@libav.org Signed-off-by: Diego Biurrun --- libavformat/asfdec.c | 12 +++++++----- libavformat/avidec.c | 2 +- libavformat/riff.h | 3 ++- libavformat/riffdec.c | 6 ++++-- libavformat/wtv.c | 2 +- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index d602af87934f7..34730b20aa882 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -691,20 +691,22 @@ static int asf_read_properties(AVFormatContext *s, const GUIDParseTable *g) static int parse_video_info(AVIOContext *pb, AVStream *st) { - uint16_t size; + uint16_t size_asf; // ASF-specific Format Data size + uint32_t size_bmp; // BMP_HEADER-specific Format Data size unsigned int tag; st->codecpar->width = avio_rl32(pb); st->codecpar->height = avio_rl32(pb); avio_skip(pb, 1); // skip reserved flags - size = avio_rl16(pb); // size of the Format Data - tag = ff_get_bmp_header(pb, st); + size_asf = avio_rl16(pb); + tag = ff_get_bmp_header(pb, st, &size_bmp); st->codecpar->codec_tag = tag; st->codecpar->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag); + size_bmp = FFMAX(size_asf, size_bmp); - if (size > BMP_HEADER_SIZE) { + if (size_bmp > BMP_HEADER_SIZE) { int ret; - st->codecpar->extradata_size = size - BMP_HEADER_SIZE; + st->codecpar->extradata_size = size_bmp - BMP_HEADER_SIZE; if (!(st->codecpar->extradata = av_malloc(st->codecpar->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE))) { st->codecpar->extradata_size = 0; diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 701cccb6b0ad1..870066eb25ce8 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -613,7 +613,7 @@ static int avi_read_header(AVFormatContext *s) avio_skip(pb, size); break; } - tag1 = ff_get_bmp_header(pb, st); + tag1 = ff_get_bmp_header(pb, st, NULL); if (tag1 == MKTAG('D', 'X', 'S', 'B') || tag1 == MKTAG('D', 'X', 'S', 'A')) { diff --git a/libavformat/riff.h b/libavformat/riff.h index a45c7f301c6d9..e5f4645c12509 100644 --- a/libavformat/riff.h +++ b/libavformat/riff.h @@ -41,9 +41,10 @@ void ff_end_tag(AVIOContext *pb, int64_t start); /** * Read BITMAPINFOHEADER structure and set AVStream codec width, height and * bits_per_encoded_sample fields. Does not read extradata. + * Writes the size of the BMP file to *size. * @return codec tag */ -int ff_get_bmp_header(AVIOContext *pb, AVStream *st); +int ff_get_bmp_header(AVIOContext *pb, AVStream *st, uint32_t *size); void ff_put_bmp_header(AVIOContext *pb, AVCodecParameters *par, const AVCodecTag *tags, int for_asf); int ff_put_wav_header(AVFormatContext *s, AVIOContext *pb, AVCodecParameters *par); diff --git a/libavformat/riffdec.c b/libavformat/riffdec.c index 81248355e3b1b..db83b3205ac5e 100644 --- a/libavformat/riffdec.c +++ b/libavformat/riffdec.c @@ -180,10 +180,12 @@ enum AVCodecID ff_wav_codec_get_id(unsigned int tag, int bps) return id; } -int ff_get_bmp_header(AVIOContext *pb, AVStream *st) +int ff_get_bmp_header(AVIOContext *pb, AVStream *st, uint32_t *size) { int tag1; - avio_rl32(pb); /* size */ + uint32_t size_ = avio_rl32(pb); + if (size) + *size = size_; st->codecpar->width = avio_rl32(pb); st->codecpar->height = (int32_t)avio_rl32(pb); avio_rl16(pb); /* planes */ diff --git a/libavformat/wtv.c b/libavformat/wtv.c index 794dd4bb71b68..d750cef6472db 100644 --- a/libavformat/wtv.c +++ b/libavformat/wtv.c @@ -586,7 +586,7 @@ static int parse_videoinfoheader2(AVFormatContext *s, AVStream *st) AVIOContext *pb = wtv->pb; avio_skip(pb, 72); // picture aspect ratio is unreliable - ff_get_bmp_header(pb, st); + ff_get_bmp_header(pb, st, NULL); return 72 + 40; } From 030de53e9cc225dc767458aedcc87efd457b4f3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 15 Feb 2017 11:06:17 +0200 Subject: [PATCH 0920/3374] libopenh264dec: Let the framework use the h264_mp4toannexb bitstream filter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids a lot of boilerplate code within the decoder wrapper itself. Signed-off-by: Martin Storsjö --- libavcodec/libopenh264dec.c | 144 +++++++----------------------------- 1 file changed, 25 insertions(+), 119 deletions(-) diff --git a/libavcodec/libopenh264dec.c b/libavcodec/libopenh264dec.c index cc18f240a6e32..d65d63914c640 100644 --- a/libavcodec/libopenh264dec.c +++ b/libavcodec/libopenh264dec.c @@ -35,28 +35,15 @@ typedef struct SVCContext { ISVCDecoder *decoder; - AVBSFContext *bsf; - AVFifoBuffer *packet_fifo; - AVPacket pkt_filtered; } SVCContext; static av_cold int svc_decode_close(AVCodecContext *avctx) { SVCContext *s = avctx->priv_data; - AVPacket pkt; if (s->decoder) WelsDestroyDecoder(s->decoder); - while (s->packet_fifo && av_fifo_size(s->packet_fifo) >= sizeof(pkt)) { - av_fifo_generic_read(s->packet_fifo, &pkt, sizeof(pkt), NULL); - av_packet_unref(&pkt); - } - - av_bsf_free(&s->bsf); - av_packet_unref(&s->pkt_filtered); - av_fifo_free(s->packet_fifo); - return 0; } @@ -71,10 +58,6 @@ static av_cold int svc_decode_init(AVCodecContext *avctx) if ((err = ff_libopenh264_check_version(avctx)) < 0) return err; - s->packet_fifo = av_fifo_alloc(sizeof(AVPacket)); - if (!s->packet_fifo) - return AVERROR(ENOMEM); - if (WelsCreateDecoder(&s->decoder)) { av_log(avctx, AV_LOG_ERROR, "Unable to create decoder\n"); return AVERROR_UNKNOWN; @@ -103,38 +86,6 @@ static av_cold int svc_decode_init(AVCodecContext *avctx) return 0; } -static int init_bsf(AVCodecContext *avctx) -{ - SVCContext *s = avctx->priv_data; - const AVBitStreamFilter *filter; - int ret; - - if (s->bsf) - return 0; - - // If the input stream already is annex b, this BSF only passes the - // packets through unchanged. - filter = av_bsf_get_by_name("h264_mp4toannexb"); - if (!filter) - return AVERROR_BUG; - - ret = av_bsf_alloc(filter, &s->bsf); - if (ret < 0) - return ret; - - ret = avcodec_parameters_from_context(s->bsf->par_in, avctx); - if (ret < 0) - return ret; - - s->bsf->time_base_in = avctx->time_base; - - ret = av_bsf_init(s->bsf); - if (ret < 0) - return ret; - - return ret; -} - static int svc_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { @@ -143,85 +94,39 @@ static int svc_decode_frame(AVCodecContext *avctx, void *data, uint8_t* ptrs[3]; int linesize[3]; AVFrame *avframe = data; - int ret; DECODING_STATE state; - if ((ret = init_bsf(avctx)) < 0) - return ret; - - if (avpkt->size) { - AVPacket input_ref = { 0 }; - if (av_fifo_space(s->packet_fifo) < sizeof(input_ref)) { - ret = av_fifo_realloc2(s->packet_fifo, - av_fifo_size(s->packet_fifo) + sizeof(input_ref)); - if (ret < 0) - return ret; - } - - ret = av_packet_ref(&input_ref, avpkt); - if (ret < 0) - return ret; - av_fifo_generic_write(s->packet_fifo, &input_ref, sizeof(input_ref), NULL); + state = (*s->decoder)->DecodeFrame2(s->decoder, avpkt->data, avpkt->size, ptrs, &info); + if (state != dsErrorFree) { + av_log(avctx, AV_LOG_ERROR, "DecodeFrame2 failed\n"); + return AVERROR_UNKNOWN; + } + if (info.iBufferStatus != 1) { + av_log(avctx, AV_LOG_DEBUG, "No frame produced\n"); + return avpkt->size; } - while (!*got_frame) { - /* prepare the input data -- convert to Annex B if needed */ - if (s->pkt_filtered.size <= 0) { - AVPacket input_ref; - - /* no more data */ - if (av_fifo_size(s->packet_fifo) < sizeof(AVPacket)) - return avpkt->size ? avpkt->size : 0; - - av_packet_unref(&s->pkt_filtered); - - av_fifo_generic_read(s->packet_fifo, &input_ref, sizeof(input_ref), NULL); - ret = av_bsf_send_packet(s->bsf, &input_ref); - if (ret < 0) { - av_packet_unref(&input_ref); - return ret; - } - - ret = av_bsf_receive_packet(s->bsf, &s->pkt_filtered); - if (ret < 0) - av_packet_move_ref(&s->pkt_filtered, &input_ref); - else - av_packet_unref(&input_ref); - } - - state = (*s->decoder)->DecodeFrame2(s->decoder, s->pkt_filtered.data, s->pkt_filtered.size, ptrs, &info); - s->pkt_filtered.size = 0; - if (state != dsErrorFree) { - av_log(avctx, AV_LOG_ERROR, "DecodeFrame2 failed\n"); - return AVERROR_UNKNOWN; - } - if (info.iBufferStatus != 1) { - av_log(avctx, AV_LOG_DEBUG, "No frame produced\n"); - continue; - } - - ff_set_dimensions(avctx, info.UsrData.sSystemBuffer.iWidth, info.UsrData.sSystemBuffer.iHeight); - // The decoder doesn't (currently) support decoding into a user - // provided buffer, so do a copy instead. - if (ff_get_buffer(avctx, avframe, 0) < 0) { - av_log(avctx, AV_LOG_ERROR, "Unable to allocate buffer\n"); - return AVERROR(ENOMEM); - } - - linesize[0] = info.UsrData.sSystemBuffer.iStride[0]; - linesize[1] = linesize[2] = info.UsrData.sSystemBuffer.iStride[1]; - av_image_copy(avframe->data, avframe->linesize, (const uint8_t **) ptrs, linesize, avctx->pix_fmt, avctx->width, avctx->height); - - avframe->pts = s->pkt_filtered.pts; - avframe->pkt_dts = s->pkt_filtered.dts; + ff_set_dimensions(avctx, info.UsrData.sSystemBuffer.iWidth, info.UsrData.sSystemBuffer.iHeight); + // The decoder doesn't (currently) support decoding into a user + // provided buffer, so do a copy instead. + if (ff_get_buffer(avctx, avframe, 0) < 0) { + av_log(avctx, AV_LOG_ERROR, "Unable to allocate buffer\n"); + return AVERROR(ENOMEM); + } + + linesize[0] = info.UsrData.sSystemBuffer.iStride[0]; + linesize[1] = linesize[2] = info.UsrData.sSystemBuffer.iStride[1]; + av_image_copy(avframe->data, avframe->linesize, (const uint8_t **) ptrs, linesize, avctx->pix_fmt, avctx->width, avctx->height); + + avframe->pts = avpkt->pts; + avframe->pkt_dts = avpkt->dts; #if FF_API_PKT_PTS FF_DISABLE_DEPRECATION_WARNINGS - avframe->pkt_pts = s->pkt_filtered.pts; + avframe->pkt_pts = avpkt->pts; FF_ENABLE_DEPRECATION_WARNINGS #endif - *got_frame = 1; - } + *got_frame = 1; return avpkt->size; } @@ -239,4 +144,5 @@ AVCodec ff_libopenh264_decoder = { .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1, .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS | FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, + .bsfs = "h264_mp4toannexb", }; From 82989bd98c7f4e87f59af2147b645b8fd8f31c53 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 12 Feb 2017 23:47:58 +0000 Subject: [PATCH 0921/3374] avconv: Move rescale to stream timebase before monotonisation If the stream timebase is coarser than the muxing timebase then the monotonisation process may fail because adding one to the timestamp need not actually produce a different timestamp after the rescale. --- avconv.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/avconv.c b/avconv.c index 94b6da2a8ba18..5c36761c1d14e 100644 --- a/avconv.c +++ b/avconv.c @@ -326,6 +326,8 @@ static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost) } } + av_packet_rescale_ts(pkt, ost->mux_timebase, ost->st->time_base); + if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS) && ost->last_mux_dts != AV_NOPTS_VALUE && pkt->dts < ost->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT)) { @@ -349,7 +351,6 @@ static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost) ost->packets_written++; pkt->stream_index = ost->index; - av_packet_rescale_ts(pkt, ost->mux_timebase, ost->st->time_base); ret = av_interleaved_write_frame(s, pkt); if (ret < 0) { @@ -1006,7 +1007,7 @@ FF_ENABLE_DEPRECATION_WARNINGS vid = 1; } /* compute min output value */ - pts = (double)ost->last_mux_dts * av_q2d(ost->mux_timebase); + pts = (double)ost->last_mux_dts * av_q2d(ost->st->time_base); if ((pts < ti1) && (pts > 0)) ti1 = pts; } From 8847eeaa141898850381400000fb2b8a7adc7100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 16 Feb 2017 09:18:25 +0200 Subject: [PATCH 0922/3374] aarch64: Add parentheses around the offset parameter in movrel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes building with clang for linux with PIC enabled. Signed-off-by: Martin Storsjö --- libavutil/aarch64/asm.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavutil/aarch64/asm.S b/libavutil/aarch64/asm.S index 0fc649ad0e782..86d36cd57fe2e 100644 --- a/libavutil/aarch64/asm.S +++ b/libavutil/aarch64/asm.S @@ -83,8 +83,8 @@ ELF .size \name, . - \name add \rd, \rd, \val+(\offset)@PAGEOFF .endif #elif CONFIG_PIC - adrp \rd, \val+\offset - add \rd, \rd, :lo12:\val+\offset + adrp \rd, \val+(\offset) + add \rd, \rd, :lo12:\val+(\offset) #else ldr \rd, =\val+\offset #endif From d00a0d8e84fef1b9124bfaf71cc17df79ca464a6 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 11 Feb 2017 16:51:25 +0100 Subject: [PATCH 0923/3374] configure: Handle SDL version check through pkg-config --- configure | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/configure b/configure index b8cbe175e82cb..4635b73b08f3e 100755 --- a/configure +++ b/configure @@ -4748,9 +4748,7 @@ if enabled nvenc; then require_cpp_condition nvEncodeAPI.h "NVENCAPI_MAJOR_VERSION >= 6" fi -if check_pkg_config sdl SDL_events.h SDL_PollEvent; then - check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) >= 0x010201" $sdl_cflags && - check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) < 0x010300" $sdl_cflags && +if check_pkg_config "sdl >= 1.2.1 sdl < 1.3.0" SDL_events.h SDL_PollEvent; then enable sdl fi From 8f5de34c8fb18fa1416e77d2cb998773a49ddb3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 16 Feb 2017 12:23:20 +0200 Subject: [PATCH 0924/3374] vf_fade: Make sure to not miss the last lines of a frame MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When slice_h is rounded up due to chroma subsampling, there's a risk that jobnr * slice_h exceeds frame->height. Prior to a638e9184d63, this wasn't an issue for the last slice of a frame, since slice_end was set to frame->height for the last slice. a638e9184d63 tried to fix the case where other slices than the last one would exceed frame->height (which can happen where the number of slices/threads is very large compared to the frame height). However, the fix in a638e9184d63 instead broke other cases, where slice_h * nb_threads < frame->height. Therefore, make sure the last slice always ends at frame->height. CC: libav-stable@libav.org Signed-off-by: Martin Storsjö --- libavfilter/vf_fade.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c index eb6d82a894623..fd8c6ef4c825f 100644 --- a/libavfilter/vf_fade.c +++ b/libavfilter/vf_fade.c @@ -123,7 +123,8 @@ static int filter_slice_chroma(AVFilterContext *ctx, void *arg, int jobnr, AVFrame *frame = arg; int slice_h = FFALIGN(frame->height / nb_jobs, 1 << s->vsub); int slice_start = jobnr * slice_h; - int slice_end = FFMIN((jobnr + 1) * slice_h, frame->height); + int slice_end = (jobnr == nb_jobs - 1) ? frame->height : + FFMIN((jobnr + 1) * slice_h, frame->height); int i, j, plane; for (plane = 1; plane < 3; plane++) { From 17aeee5832b9188b570c3d3de4197e4cdc54c634 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Thu, 16 Feb 2017 00:02:29 +0000 Subject: [PATCH 0925/3374] vaapi_encode: Discard output buffer if picture submission fails Previously this was leaking, though it actually hit an assert making sure that the buffer had already been cleared when freeing the picture. --- libavcodec/vaapi_encode.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index c02b633b4679d..411d8790919dc 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -428,6 +428,8 @@ static int vaapi_encode_issue(AVCodecContext *avctx, fail_at_end: av_freep(&pic->codec_picture_params); av_frame_free(&pic->recon_image); + av_buffer_unref(&pic->output_buffer_ref); + pic->output_buffer = VA_INVALID_ID; return err; } From 2d518aec4c781316092be65893b47922c8f71b67 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Thu, 9 Feb 2017 19:26:11 +0000 Subject: [PATCH 0926/3374] vf_deinterlace_vaapi: Create filter buffer after context The Intel proprietary VAAPI driver enforces the restriction that a buffer must be created inside an existing context, so just ensure this is always true. --- libavfilter/vf_deinterlace_vaapi.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libavfilter/vf_deinterlace_vaapi.c b/libavfilter/vf_deinterlace_vaapi.c index 022baa11fc26b..ab2a43291454f 100644 --- a/libavfilter/vf_deinterlace_vaapi.c +++ b/libavfilter/vf_deinterlace_vaapi.c @@ -278,10 +278,6 @@ static int deint_vaapi_config_output(AVFilterLink *outlink) goto fail; } - err = deint_vaapi_build_filter_params(avctx); - if (err < 0) - goto fail; - ctx->output_frames_ref = av_hwframe_ctx_alloc(ctx->device_ref); if (!ctx->output_frames_ref) { av_log(avctx, AV_LOG_ERROR, "Failed to create HW frame context " @@ -319,9 +315,14 @@ static int deint_vaapi_config_output(AVFilterLink *outlink) if (vas != VA_STATUS_SUCCESS) { av_log(avctx, AV_LOG_ERROR, "Failed to create processing pipeline " "context: %d (%s).\n", vas, vaErrorStr(vas)); - return AVERROR(EIO); + err = AVERROR(EIO); + goto fail; } + err = deint_vaapi_build_filter_params(avctx); + if (err < 0) + goto fail; + outlink->w = ctx->output_width; outlink->h = ctx->output_height; From 7cb9296db872c4221453e5411f242ebcfca62664 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Fri, 17 Feb 2017 23:14:19 +0000 Subject: [PATCH 0927/3374] webp: Fix alpha decoding This was broken by 4e528206bc4d968706401206cf54471739250ec7 - the webp decoder was assuming that it could set the output pixfmt of the vp8 decoder directly, but after that change it no longer could because ff_get_format() was used instead. This adds an internal get_format() callback to webp use of the vp8 decoder to override the pixfmt appropriately. --- libavcodec/webp.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/libavcodec/webp.c b/libavcodec/webp.c index 4548e5fb3b860..18d68e914020e 100644 --- a/libavcodec/webp.c +++ b/libavcodec/webp.c @@ -1288,6 +1288,16 @@ static int vp8_lossy_decode_alpha(AVCodecContext *avctx, AVFrame *p, return 0; } +static enum AVPixelFormat webp_get_format(AVCodecContext *avctx, + const enum AVPixelFormat *formats) +{ + WebPContext *s = avctx->priv_data; + if (s->has_alpha) + return AV_PIX_FMT_YUVA420P; + else + return AV_PIX_FMT_YUV420P; +} + static int vp8_lossy_decode_frame(AVCodecContext *avctx, AVFrame *p, int *got_frame, uint8_t *data_start, unsigned int data_size) @@ -1299,8 +1309,7 @@ static int vp8_lossy_decode_frame(AVCodecContext *avctx, AVFrame *p, if (!s->initialized) { ff_vp8_decode_init(avctx); s->initialized = 1; - if (s->has_alpha) - avctx->pix_fmt = AV_PIX_FMT_YUVA420P; + avctx->get_format = webp_get_format; } s->lossless = 0; From 42cf7f91f1e9dabf494ff469d8f67ac8b33b0f63 Mon Sep 17 00:00:00 2001 From: John Stebbins Date: Wed, 11 Jan 2017 12:17:06 -0700 Subject: [PATCH 0928/3374] dv: Don't return EIO upon EOF --- libavformat/dv.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libavformat/dv.c b/libavformat/dv.c index d4e51807d7e46..748b5e8926e21 100644 --- a/libavformat/dv.c +++ b/libavformat/dv.c @@ -484,11 +484,14 @@ static int dv_read_packet(AVFormatContext *s, AVPacket *pkt) size = avpriv_dv_get_packet(c->dv_demux, pkt); if (size < 0) { + int ret; + if (!c->dv_demux->sys) return AVERROR(EIO); size = c->dv_demux->sys->frame_size; - if (avio_read(s->pb, c->buf, size) <= 0) - return AVERROR(EIO); + ret = avio_read(s->pb, c->buf, size); + if (ret <= 0) + return ret; size = avpriv_dv_produce_packet(c->dv_demux, pkt, c->buf, size); } From 00b160af117b782292619c98effce6c8273792e5 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 17 Feb 2017 12:40:40 +0100 Subject: [PATCH 0929/3374] nvenc: Fix nvec vs. nvenc typo --- libavcodec/nvenc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 90b9d1a62aadd..30da83a08ca24 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -479,7 +479,7 @@ typedef struct GUIDTuple { #define PRESET(name, ...) PRESET_ALIAS(name, name, __VA_ARGS__) -static int nvec_map_preset(NVENCContext *ctx) +static int nvenc_map_preset(NVENCContext *ctx) { GUIDTuple presets[] = { PRESET(DEFAULT), @@ -882,7 +882,7 @@ static int nvenc_setup_encoder(AVCodecContext *avctx) ctx->params.encodeConfig = &ctx->config; - nvec_map_preset(ctx); + nvenc_map_preset(ctx); preset_cfg.version = NV_ENC_PRESET_CONFIG_VER; preset_cfg.presetCfg.version = NV_ENC_CONFIG_VER; From 54e39b102e29adcc2f59f1eca85be5f86c89454b Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 16 Feb 2017 17:37:25 +0100 Subject: [PATCH 0930/3374] configure: Explicitly spell out first require_pkg_config() parameter This is less confusing than encountering "" in the argument list. --- configure | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/configure b/configure index 4635b73b08f3e..287b1e5d41a81 100755 --- a/configure +++ b/configure @@ -1139,7 +1139,6 @@ require_pkg_config(){ shift pkg_version="$1" pkg="${1%% *}" - test "$name" = "" && name=$pkg check_pkg_config "$@" || die "ERROR: $pkg_version not found" add_cflags $(get_safe "${pkg}_cflags") add_extralibs $(get_safe "${pkg}_extralibs") @@ -4521,7 +4520,7 @@ case "$custom_allocator" in require libjemalloc jemalloc/jemalloc.h malloc -ljemalloc ;; tcmalloc) - require_pkg_config "" libtcmalloc gperftools/tcmalloc.h tc_malloc + require_pkg_config libtcmalloc libtcmalloc gperftools/tcmalloc.h tc_malloc malloc_prefix=tc_ ;; esac @@ -4657,8 +4656,8 @@ enabled avisynth && require_header avisynth/avisynth_c.h enabled avxsynth && require avxsynth "avxsynth/avxsynth_c.h dlfcn.h" dlopen -ldl enabled cuda && require cuda cuda.h cuInit -lcuda enabled frei0r && require_header frei0r.h -enabled gnutls && require_pkg_config "" gnutls gnutls/gnutls.h gnutls_global_init -enabled libbs2b && require_pkg_config "" libbs2b bs2b.h bs2b_open +enabled gnutls && require_pkg_config gnutls gnutls gnutls/gnutls.h gnutls_global_init +enabled libbs2b && require_pkg_config libbs2b libbs2b bs2b.h bs2b_open enabled libdc1394 && require_pkg_config libdc1394 libdc1394-2 dc1394/dc1394.h dc1394_new enabled libdcadec && require libdcadec libdcadec/dca_context.h dcadec_context_create -ldcadec enabled libfaac && require libfaac "stdint.h faac.h" faacEncGetVersion -lfaac @@ -4668,10 +4667,10 @@ enabled libfreetype && require_pkg_config libfreetype freetype2 "ft2build. enabled libgsm && { for gsm_hdr in "gsm.h" "gsm/gsm.h"; do check_lib libgsm "${gsm_hdr}" gsm_create -lgsm && break; done || die "ERROR: libgsm not found"; } -enabled libhdcd && require_pkg_config "" libhdcd "hdcd/hdcd_simple.h" hdcd_new +enabled libhdcd && require_pkg_config libhdcd libhdcd "hdcd/hdcd_simple.h" hdcd_new enabled libilbc && require libilbc ilbc.h WebRtcIlbcfix_InitDecode -lilbc enabled libkvazaar && require_pkg_config libkvazaar "kvazaar >= 0.8.1" kvazaar.h kvz_api_get -enabled libmfx && require_pkg_config "" libmfx "mfx/mfxvideo.h" MFXInit +enabled libmfx && require_pkg_config libmfx libmfx "mfx/mfxvideo.h" MFXInit enabled libmp3lame && require "libmp3lame >= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame enabled libnpp && require libnpp npp.h nppGetLibVersion -lnppi -lnppc enabled libopencore_amrnb && require libopencore_amrnb opencore-amrnb/interf_dec.h Decoder_Interface_init -lopencore-amrnb @@ -4682,7 +4681,7 @@ enabled libopenjpeg && { check_lib libopenjpeg openjpeg.h opj_version -lop require_pkg_config libopenjpeg libopenjpeg1 openjpeg.h opj_version -DOPJ_STATIC; } enabled libopus && require_pkg_config libopus opus opus_multistream.h opus_multistream_decoder_create enabled libpulse && require_pkg_config libpulse libpulse-simple pulse/simple.h pa_simple_new -enabled librtmp && require_pkg_config "" librtmp librtmp/rtmp.h RTMP_Socket +enabled librtmp && require_pkg_config librtmp librtmp librtmp/rtmp.h RTMP_Socket enabled libschroedinger && require_pkg_config libschroedinger schroedinger-1.0 schroedinger/schro.h schro_init enabled libsnappy && require libsnappy snappy-c.h snappy_compress -lsnappy enabled libspeex && require_pkg_config libspeex speex speex/speex.h speex_decoder_init -lspeex @@ -4713,7 +4712,7 @@ enabled libvpx && require_pkg_config libvpx "vpx >= 1.3.0" vpx/vpx_co fi } enabled libwavpack && require libwavpack wavpack/wavpack.h WavpackOpenFileOutput -lwavpack -enabled libwebp && require_pkg_config "" libwebp webp/encode.h WebPGetEncoderVersion +enabled libwebp && require_pkg_config libwebp libwebp webp/encode.h WebPGetEncoderVersion enabled libx264 && require_pkg_config libx264 x264 "stdint.h x264.h" x264_encoder_encode && require_cpp_condition x264.h "X264_BUILD >= 118" && { check_cpp_condition x264.h "X264_MPEG2" && From 7208e5b5d638d4b9c2784036b4fc5728f32233c7 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 11 Feb 2017 13:09:27 +0100 Subject: [PATCH 0931/3374] configure: Restructure the way check_pkg_config() operates Have check_pkg_config() enable variables and set cflags and extralibs instead of relegating that task to require_pkg_config. This simplifies require_pkg_config(), is consistent with what other helper functions like check_lib() do and allows getting rid of some manual variable setting in places where check_pkg_config() is used. --- configure | 70 ++++++++++++++++++++++--------------------------------- 1 file changed, 28 insertions(+), 42 deletions(-) diff --git a/configure b/configure index 287b1e5d41a81..24e9fc337fa31 100755 --- a/configure +++ b/configure @@ -1020,17 +1020,20 @@ check_lib(){ check_pkg_config(){ log check_pkg_config "$@" - pkg_version="$1" - pkg="${1%% *}" - headers="$2" - funcs="$3" - shift 3 + name="$1" + pkg_version="$2" + pkg="${2%% *}" + headers="$3" + funcs="$4" + shift 4 + disable $name check_cmd $pkg_config --exists --print-errors $pkg_version || return pkg_cflags=$($pkg_config --cflags $pkg_config_flags $pkg) pkg_libs=$($pkg_config --libs $pkg_config_flags $pkg) check_func_headers "$headers" "$funcs" $pkg_cflags $pkg_libs "$@" && - set_safe "${pkg}_cflags" $pkg_cflags && - set_safe "${pkg}_extralibs" $pkg_libs + enable $name && + add_cflags "$pkg_cflags" && + add_extralibs "$pkg_libs" } check_exec(){ @@ -1135,13 +1138,8 @@ require_cpp_condition(){ require_pkg_config(){ log require_pkg_config "$@" - name="$1" - shift - pkg_version="$1" - pkg="${1%% *}" + pkg_version="$2" check_pkg_config "$@" || die "ERROR: $pkg_version not found" - add_cflags $(get_safe "${pkg}_cflags") - add_extralibs $(get_safe "${pkg}_extralibs") } hostcc_e(){ @@ -4690,27 +4688,18 @@ enabled libtwolame && require libtwolame twolame.h twolame_init -ltwolame enabled libvo_aacenc && require libvo_aacenc vo-aacenc/voAAC.h voGetAACEncAPI -lvo-aacenc enabled libvo_amrwbenc && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc enabled libvorbis && require libvorbis vorbis/vorbisenc.h vorbis_info_init -lvorbisenc -lvorbis -logg -enabled libvpx && require_pkg_config libvpx "vpx >= 1.3.0" vpx/vpx_codec.h vpx_codec_version && { - enabled libvpx_vp8_decoder && { - check_pkg_config vpx "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_vp8_dx || - disable libvpx_vp8_decoder; - } - enabled libvpx_vp8_encoder && { - check_pkg_config vpx "vpx/vpx_encoder.h vpx/vp8cx.h" vpx_codec_vp8_cx || - disable libvpx_vp8_encoder; - } - enabled libvpx_vp9_decoder && { - check_pkg_config vpx "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_vp9_dx || - disable libvpx_vp9_decoder; - } - enabled libvpx_vp9_encoder && { - check_pkg_config vpx "vpx/vpx_encoder.h vpx/vp8cx.h" vpx_codec_vp9_cx || - disable libvpx_vp9_encoder; - } - if disabled_all libvpx_vp8_decoder libvpx_vp9_decoder libvpx_vp8_encoder libvpx_vp9_encoder; then - die "libvpx enabled but no supported decoders found" - fi -} +enabled libvpx && require_pkg_config libvpx "vpx >= 1.3.0" vpx/vpx_codec.h vpx_codec_version && + { enabled libvpx_vp8_decoder && + check_pkg_config libvpx_vp8_decoder vpx "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_vp8_dx + enabled libvpx_vp8_encoder && + check_pkg_config libvpx_vp8_encoder vpx "vpx/vpx_encoder.h vpx/vp8cx.h" vpx_codec_vp8_cx + enabled libvpx_vp9_decoder && + check_pkg_config libvpx_vp9_decoder vpx "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_vp9_dx + enabled libvpx_vp9_encoder && + check_pkg_config libvpx_vp9_encoder vpx "vpx/vpx_encoder.h vpx/vp8cx.h" vpx_codec_vp9_cx + disabled_all libvpx_vp8_decoder libvpx_vp9_decoder libvpx_vp8_encoder libvpx_vp9_encoder && + die "libvpx enabled but no supported decoders/encoders found" + } enabled libwavpack && require libwavpack wavpack/wavpack.h WavpackOpenFileOutput -lwavpack enabled libwebp && require_pkg_config libwebp libwebp webp/encode.h WebPGetEncoderVersion enabled libx264 && require_pkg_config libx264 x264 "stdint.h x264.h" x264_encoder_encode && @@ -4732,9 +4721,8 @@ enabled omx_rpi && { check_header OMX_Core.h || { ! enabled cross_compile && add_cflags -isystem/opt/vc/include/IL && check_header OMX_Core.h ; } || die "ERROR: OpenMAX IL headers not found"; } enabled omx && require_header OMX_Core.h -enabled openssl && { { check_pkg_config openssl openssl/ssl.h OPENSSL_init_ssl || - check_pkg_config openssl openssl/ssl.h SSL_library_init; } && { - add_cflags $openssl_cflags && add_extralibs $openssl_extralibs; } || +enabled openssl && { { check_pkg_config openssl openssl openssl/ssl.h OPENSSL_init_ssl || + check_pkg_config openssl openssl openssl/ssl.h SSL_library_init; } || check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto || check_lib openssl openssl/ssl.h SSL_library_init -lssl32 -leay32 || check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 || @@ -4747,9 +4735,7 @@ if enabled nvenc; then require_cpp_condition nvEncodeAPI.h "NVENCAPI_MAJOR_VERSION >= 6" fi -if check_pkg_config "sdl >= 1.2.1 sdl < 1.3.0" SDL_events.h SDL_PollEvent; then - enable sdl -fi +check_pkg_config sdl "sdl >= 1.2.1 sdl < 1.3.0" SDL_events.h SDL_PollEvent ! disabled pod2man && check_cmd pod2man --help && enable pod2man || disable pod2man ! disabled texi2html && check_cmd texi2html -version && enable texi2html || disable texi2html @@ -4798,9 +4784,9 @@ if enabled libxcb; then require_pkg_config libxcb xcb xcb/xcb.h xcb_connect require_pkg_config libxcb_shape xcb-shape xcb/shape.h xcb_shape_rectangles disabled libxcb_shm || - require_pkg_config libxcb_shm xcb-shm xcb/shm.h xcb_shm_attach + check_pkg_config libxcb_shm xcb-shm xcb/shm.h xcb_shm_attach disabled libxcb_xfixes || - require_pkg_config libxcb_xfixes xcb-xfixes xcb/xfixes.h xcb_xfixes_get_cursor_image + check_pkg_config libxcb_xfixes xcb-xfixes xcb/xfixes.h xcb_xfixes_get_cursor_image fi enabled dxva2 && From 533339bdcc3b39bbd708c723b3cd0b5898350f0f Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 6 Feb 2017 20:07:02 +0100 Subject: [PATCH 0932/3374] build: Drop leftover reference to old EXAMPLES logic --- Makefile | 2 +- doc/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 98eb3ab1d95f9..b14b29d76aafe 100644 --- a/Makefile +++ b/Makefile @@ -131,7 +131,7 @@ avbuild/.config: $(CONFIGURABLE_COMPONENTS) @-printf '\nWARNING: $(?) newer than config.h, rerun configure\n\n' @-tput sgr0 2>/dev/null -SUBDIR_VARS := CLEANFILES EXAMPLES FFLIBS HOSTPROGS TESTPROGS TOOLS \ +SUBDIR_VARS := CLEANFILES FFLIBS HOSTPROGS TESTPROGS TOOLS \ HEADERS ARCH_HEADERS BUILT_HEADERS SKIPHEADERS \ ARMV5TE-OBJS ARMV6-OBJS ARMV8-OBJS VFP-OBJS NEON-OBJS \ ALTIVEC-OBJS VSX-OBJS MMX-OBJS YASM-OBJS \ diff --git a/doc/Makefile b/doc/Makefile index bda815307c035..bd5c2e4b7ff08 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -73,7 +73,7 @@ $(DOCS) doc/doxy/html: | doc/ $(DOC_EXAMPLES:%$(EXESUF)=%.o): | doc/examples OBJDIRS += doc/examples -DOXY_INPUT = $(addprefix $(SRC_PATH)/, $(INSTHEADERS) $(DOC_EXAMPLES:%$(EXESUF)=%.c) $(LIB_EXAMPLES:%$(EXESUF)=%.c)) +DOXY_INPUT = $(addprefix $(SRC_PATH)/, $(INSTHEADERS) $(DOC_EXAMPLES:%$(EXESUF)=%.c)) DOXY_TEMPLATES = doxy_stylesheet.css footer.html header.html DOXY_TEMPLATES := $(addprefix $(SRC_PATH)/doc/doxy/, $(DOXY_TEMPLATES)) From db4903eb4875bed6c5b8a4259cdd7bc1768dfdf6 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 14 Feb 2017 12:57:13 +0100 Subject: [PATCH 0933/3374] build: Avoid duplication in examples lists --- doc/Makefile | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/doc/Makefile b/doc/Makefile index bd5c2e4b7ff08..365ac5d9130c1 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -25,16 +25,9 @@ DOC_EXAMPLES-$(CONFIG_METADATA_EXAMPLE) += metadata DOC_EXAMPLES-$(CONFIG_OUTPUT_EXAMPLE) += output DOC_EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE) += qsvdec DOC_EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac -ALL_DOC_EXAMPLES = decode_audio \ - decode_video \ - encode_audio \ - encode_video \ - filter_audio \ - metadata output \ - transcode_aac \ DOC_EXAMPLES := $(DOC_EXAMPLES-yes:%=doc/examples/%$(EXESUF)) -ALL_DOC_EXAMPLES := $(ALL_DOC_EXAMPLES:%=doc/examples/%$(EXESUF)) +ALL_DOC_EXAMPLES := $(DOC_EXAMPLES) $(DOC_EXAMPLES-:%=doc/examples/%$(EXESUF)) PROGS += $(DOC_EXAMPLES) all: $(DOCS) From acb0dea27efff4b35796015b96570b59fd517078 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 15 Feb 2017 13:31:52 +0100 Subject: [PATCH 0934/3374] build: Split logic for building examples off into a separate Makefile --- Makefile | 4 ++-- doc/Makefile | 23 ++--------------------- doc/examples/Makefile | 26 ++++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 23 deletions(-) create mode 100644 doc/examples/Makefile diff --git a/Makefile b/Makefile index b14b29d76aafe..c96e07916d276 100644 --- a/Makefile +++ b/Makefile @@ -154,6 +154,7 @@ endef $(foreach D,$(FFLIBS),$(eval $(call DOSUBDIR,lib$(D)))) include $(SRC_PATH)/doc/Makefile +include $(SRC_PATH)/doc/examples/Makefile define DOPROG OBJS-$(1) += $(1).o $(OBJS-$(1)-yes) @@ -239,5 +240,4 @@ $(sort $(OBJDIRS)): # so this saves some time on slow systems. .SUFFIXES: -.PHONY: all all-yes alltools check *clean config examples install* -.PHONY: testprogs uninstall* +.PHONY: all all-yes alltools check *clean config install* testprogs uninstall* diff --git a/doc/Makefile b/doc/Makefile index 365ac5d9130c1..381eca9c01b47 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -16,27 +16,11 @@ DOCS-$(CONFIG_POD2MAN) += $(MANPAGES) $(PODPAGES) DOCS-$(CONFIG_TEXI2HTML) += $(HTMLPAGES) DOCS = $(DOCS-yes) -DOC_EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE) += decode_audio -DOC_EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE) += decode_video -DOC_EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE) += encode_audio -DOC_EXAMPLES-$(CONFIG_ENCODE_VIDEO_EXAMPLE) += encode_video -DOC_EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE) += filter_audio -DOC_EXAMPLES-$(CONFIG_METADATA_EXAMPLE) += metadata -DOC_EXAMPLES-$(CONFIG_OUTPUT_EXAMPLE) += output -DOC_EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE) += qsvdec -DOC_EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac - -DOC_EXAMPLES := $(DOC_EXAMPLES-yes:%=doc/examples/%$(EXESUF)) -ALL_DOC_EXAMPLES := $(DOC_EXAMPLES) $(DOC_EXAMPLES-:%=doc/examples/%$(EXESUF)) -PROGS += $(DOC_EXAMPLES) - all: $(DOCS) apidoc: doc/doxy/html documentation: $(DOCS) -examples: $(DOC_EXAMPLES) - TEXIDEP = awk '/^@include/ { printf "$@: $(@D)/%s\n", $$2 }' <$< >$(@:%=%.d) GENTEXI = format codec @@ -63,10 +47,8 @@ doc/%.1: doc/%.pod $(M)pod2man --section=1 --center=" " --release=" " $< > $@ $(DOCS) doc/doxy/html: | doc/ -$(DOC_EXAMPLES:%$(EXESUF)=%.o): | doc/examples -OBJDIRS += doc/examples -DOXY_INPUT = $(addprefix $(SRC_PATH)/, $(INSTHEADERS) $(DOC_EXAMPLES:%$(EXESUF)=%.c)) +DOXY_INPUT = $(addprefix $(SRC_PATH)/, $(INSTHEADERS)) DOXY_TEMPLATES = doxy_stylesheet.css footer.html header.html DOXY_TEMPLATES := $(addprefix $(SRC_PATH)/doc/doxy/, $(DOXY_TEMPLATES)) @@ -93,8 +75,7 @@ uninstall-man: $(RM) $(addprefix "$(MANDIR)/man1/",$(ALLMANPAGES)) clean:: - $(RM) $(ALL_DOC_EXAMPLES) - $(RM) $(CLEANSUFFIXES:%=doc/%) $(CLEANSUFFIXES:%=doc/examples/%) + $(RM) $(CLEANSUFFIXES:%=doc/%) $(RM) doc/*.html doc/*.pod doc/*.1 doc/avoptions_*.texi $(RM) -r doc/doxy/html diff --git a/doc/examples/Makefile b/doc/examples/Makefile new file mode 100644 index 0000000000000..b24ca28aff527 --- /dev/null +++ b/doc/examples/Makefile @@ -0,0 +1,26 @@ +DOC_EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE) += decode_audio +DOC_EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE) += decode_video +DOC_EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE) += encode_audio +DOC_EXAMPLES-$(CONFIG_ENCODE_VIDEO_EXAMPLE) += encode_video +DOC_EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE) += filter_audio +DOC_EXAMPLES-$(CONFIG_METADATA_EXAMPLE) += metadata +DOC_EXAMPLES-$(CONFIG_OUTPUT_EXAMPLE) += output +DOC_EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE) += qsvdec +DOC_EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac + +DOC_EXAMPLES := $(DOC_EXAMPLES-yes:%=doc/examples/%$(EXESUF)) +ALL_DOC_EXAMPLES := $(DOC_EXAMPLES) $(DOC_EXAMPLES-:%=doc/examples/%$(EXESUF)) +PROGS += $(DOC_EXAMPLES) + +examples: $(DOC_EXAMPLES) + +$(DOC_EXAMPLES:%$(EXESUF)=%.o): | doc/examples +OBJDIRS += doc/examples + +DOXY_INPUT += $(addprefix $(SRC_PATH)/, $(DOC_EXAMPLES:%$(EXESUF)=%.c)) + +clean:: + $(RM) $(ALL_DOC_EXAMPLES) + $(RM) $(CLEANSUFFIXES:%=doc/examples/%) + +.PHONY: examples From ab566cc96bc0c31b34d944214bc06cec8ae8b640 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 14 Feb 2017 13:15:25 +0100 Subject: [PATCH 0935/3374] build: Separate logic for building examples from that for building avtools --- Makefile | 2 +- doc/examples/Makefile | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c96e07916d276..2932e6e04c317 100644 --- a/Makefile +++ b/Makefile @@ -165,7 +165,7 @@ $(1)$(EXESUF): FF_EXTRALIBS += $(EXTRALIBS-$(1)) -include $$(OBJS-$(1):.o=.d) endef -$(foreach P,$(PROGS),$(eval $(call DOPROG,$(P:$(EXESUF)=)))) +$(foreach P,$(AVPROGS-yes),$(eval $(call DOPROG,$(P)))) $(PROGS): %$(EXESUF): %.o $(FF_DEP_LIBS) $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $(OBJS-$*) $(FF_EXTRALIBS) diff --git a/doc/examples/Makefile b/doc/examples/Makefile index b24ca28aff527..c42c68fd5459c 100644 --- a/doc/examples/Makefile +++ b/doc/examples/Makefile @@ -12,6 +12,9 @@ DOC_EXAMPLES := $(DOC_EXAMPLES-yes:%=doc/examples/%$(EXESUF)) ALL_DOC_EXAMPLES := $(DOC_EXAMPLES) $(DOC_EXAMPLES-:%=doc/examples/%$(EXESUF)) PROGS += $(DOC_EXAMPLES) +$(foreach P,$(DOC_EXAMPLES),$(eval OBJS-$(P:%$(EXESUF)=%) = $(P:%$(EXESUF)=%).o)) +$(DOC_EXAMPLES): %$(EXESUF): %.o + examples: $(DOC_EXAMPLES) $(DOC_EXAMPLES:%$(EXESUF)=%.o): | doc/examples @@ -23,4 +26,6 @@ clean:: $(RM) $(ALL_DOC_EXAMPLES) $(RM) $(CLEANSUFFIXES:%=doc/examples/%) +-include $(wildcard $(DOC_EXAMPLES:%$(EXESUF)=%.d)) + .PHONY: examples From c95169f0ec68bdeeabc5fde8aa4076f406242524 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 4 Jan 2017 15:09:29 +0100 Subject: [PATCH 0936/3374] build: Move cli tool sources to a separate subdirectory This unclutters the top-level directory and groups related files together. --- Makefile | 54 ++-------------------- avtools/Makefile | 52 +++++++++++++++++++++ avconv.c => avtools/avconv.c | 0 avconv.h => avtools/avconv.h | 0 avconv_dxva2.c => avtools/avconv_dxva2.c | 0 avconv_filter.c => avtools/avconv_filter.c | 0 avconv_opt.c => avtools/avconv_opt.c | 0 avconv_qsv.c => avtools/avconv_qsv.c | 0 avconv_vaapi.c => avtools/avconv_vaapi.c | 0 avconv_vda.c => avtools/avconv_vda.c | 0 avconv_vdpau.c => avtools/avconv_vdpau.c | 0 avplay.c => avtools/avplay.c | 0 avprobe.c => avtools/avprobe.c | 0 cmdutils.c => avtools/cmdutils.c | 0 cmdutils.h => avtools/cmdutils.h | 0 15 files changed, 56 insertions(+), 50 deletions(-) create mode 100644 avtools/Makefile rename avconv.c => avtools/avconv.c (100%) rename avconv.h => avtools/avconv.h (100%) rename avconv_dxva2.c => avtools/avconv_dxva2.c (100%) rename avconv_filter.c => avtools/avconv_filter.c (100%) rename avconv_opt.c => avtools/avconv_opt.c (100%) rename avconv_qsv.c => avtools/avconv_qsv.c (100%) rename avconv_vaapi.c => avtools/avconv_vaapi.c (100%) rename avconv_vda.c => avtools/avconv_vda.c (100%) rename avconv_vdpau.c => avtools/avconv_vdpau.c (100%) rename avplay.c => avtools/avplay.c (100%) rename avprobe.c => avtools/avprobe.c (100%) rename cmdutils.c => avtools/cmdutils.c (100%) rename cmdutils.h => avtools/cmdutils.h (100%) diff --git a/Makefile b/Makefile index 2932e6e04c317..a3cd0846e1433 100644 --- a/Makefile +++ b/Makefile @@ -69,25 +69,6 @@ COMPILE_HOSTC = $(call COMPILE,HOSTCC) %.c %.h %.pc %.ver %.version: TAG = GEN -AVPROGS-$(CONFIG_AVCONV) += avconv -AVPROGS-$(CONFIG_AVPLAY) += avplay -AVPROGS-$(CONFIG_AVPROBE) += avprobe - -AVPROGS := $(AVPROGS-yes:%=%$(EXESUF)) -PROGS += $(AVPROGS) - -AVBASENAMES = avconv avplay avprobe -ALLAVPROGS = $(AVBASENAMES:%=%$(EXESUF)) - -$(foreach prog,$(AVBASENAMES),$(eval OBJS-$(prog) += cmdutils.o)) - -OBJS-avconv += avconv_opt.o avconv_filter.o -OBJS-avconv-$(CONFIG_LIBMFX) += avconv_qsv.o -OBJS-avconv-$(CONFIG_VAAPI) += avconv_vaapi.o -OBJS-avconv-$(CONFIG_VDA) += avconv_vda.o -OBJS-avconv-$(HAVE_DXVA2_LIB) += avconv_dxva2.o -OBJS-avconv-$(HAVE_VDPAU_X11) += avconv_vdpau.o - TESTTOOLS = audiogen videogen rotozoom tiny_psnr base64 HOSTPROGS := $(TESTTOOLS:%=tests/%) doc/print_options @@ -115,8 +96,6 @@ FF_EXTRALIBS := $(FFEXTRALIBS) FF_DEP_LIBS := $(DEP_LIBS) FF_STATIC_DEP_LIBS := $(STATIC_DEP_LIBS) -all: $(AVPROGS) - $(TOOLS): %$(EXESUF): %.o $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(EXTRALIBS) $(ELIBS) @@ -153,21 +132,11 @@ endef $(foreach D,$(FFLIBS),$(eval $(call DOSUBDIR,lib$(D)))) +include $(SRC_PATH)/avtools/Makefile include $(SRC_PATH)/doc/Makefile include $(SRC_PATH)/doc/examples/Makefile -define DOPROG -OBJS-$(1) += $(1).o $(OBJS-$(1)-yes) -$(1)$(EXESUF): $$(OBJS-$(1)) -$$(OBJS-$(1)): CFLAGS += $(CFLAGS-$(1)) -$(1)$(EXESUF): LDFLAGS += $(LDFLAGS-$(1)) -$(1)$(EXESUF): FF_EXTRALIBS += $(EXTRALIBS-$(1)) --include $$(OBJS-$(1):.o=.d) -endef - -$(foreach P,$(AVPROGS-yes),$(eval $(call DOPROG,$(P)))) - -$(PROGS): %$(EXESUF): %.o $(FF_DEP_LIBS) +$(PROGS): %$(EXESUF): $(FF_DEP_LIBS) $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $(OBJS-$*) $(FF_EXTRALIBS) VERSION_SH = $(SRC_PATH)/avbuild/version.sh @@ -176,7 +145,7 @@ GIT_LOG = $(SRC_PATH)/.git/logs/HEAD .version: $(wildcard $(GIT_LOG)) $(VERSION_SH) avbuild/config.mak .version: M=@ -cmdutils.o libavutil/utils.o: avversion.h +libavutil/utils.o: avversion.h avversion.h .version: $(M)$(VERSION_SH) $(SRC_PATH) avversion.h $(EXTRA_VERSION) $(Q)touch .version @@ -184,35 +153,20 @@ avversion.h .version: # force version.sh to run whenever version might have changed -include .version -ifdef AVPROGS -install: install-progs install-data -endif - install: install-libs install-headers install-libs: install-libs-yes -install-progs-yes: -install-progs-$(CONFIG_SHARED): install-libs - -install-progs: install-progs-yes $(AVPROGS) - $(Q)mkdir -p "$(BINDIR)" - $(INSTALL) -c -m 755 $(AVPROGS) "$(BINDIR)" - install-data: $(DATA_FILES) $(Q)mkdir -p "$(DATADIR)" $(INSTALL) -m 644 $(DATA_FILES) "$(DATADIR)" -uninstall: uninstall-libs uninstall-headers uninstall-progs uninstall-data - -uninstall-progs: - $(RM) $(addprefix "$(BINDIR)/", $(ALLAVPROGS)) +uninstall: uninstall-libs uninstall-headers uninstall-data uninstall-data: $(RM) -r "$(DATADIR)" clean:: - $(RM) $(ALLAVPROGS) $(RM) $(CLEANSUFFIXES) $(RM) -rf coverage.info lcov diff --git a/avtools/Makefile b/avtools/Makefile new file mode 100644 index 0000000000000..d6d609f54414b --- /dev/null +++ b/avtools/Makefile @@ -0,0 +1,52 @@ +AVPROGS-$(CONFIG_AVCONV) += avconv +AVPROGS-$(CONFIG_AVPLAY) += avplay +AVPROGS-$(CONFIG_AVPROBE) += avprobe + +AVPROGS := $(AVPROGS-yes:%=%$(EXESUF)) +PROGS += $(AVPROGS) + +AVBASENAMES = avconv avplay avprobe +ALLAVPROGS = $(AVBASENAMES:%=%$(EXESUF)) + +OBJS-avconv += avtools/avconv_opt.o avtools/avconv_filter.o +OBJS-avconv-$(CONFIG_LIBMFX) += avtools/avconv_qsv.o +OBJS-avconv-$(CONFIG_VAAPI) += avtools/avconv_vaapi.o +OBJS-avconv-$(CONFIG_VDA) += avtools/avconv_vda.o +OBJS-avconv-$(HAVE_DXVA2_LIB) += avtools/avconv_dxva2.o +OBJS-avconv-$(HAVE_VDPAU_X11) += avtools/avconv_vdpau.o + +define DOAVTOOL +OBJS-$(1) += avtools/cmdutils.o avtools/$(1).o $(OBJS-$(1)-yes) +$(1)$(EXESUF): $$(OBJS-$(1)) +$$(OBJS-$(1)): | avtools +$$(OBJS-$(1)): CFLAGS += $(CFLAGS-$(1)) +$(1)$(EXESUF): LDFLAGS += $(LDFLAGS-$(1)) +$(1)$(EXESUF): FF_EXTRALIBS += $(EXTRALIBS-$(1)) +-include $$(OBJS-$(1):.o=.d) +endef + +$(foreach P,$(AVPROGS-yes),$(eval $(call DOAVTOOL,$(P)))) + +all: $(AVPROGS) + +avtools/cmdutils.o: avversion.h | avtools +OBJDIRS += avtools + +ifdef AVPROGS +install: install-progs install-data +endif + +install-progs-yes: +install-progs-$(CONFIG_SHARED): install-libs + +install-progs: install-progs-yes $(AVPROGS) + $(Q)mkdir -p "$(BINDIR)" + $(INSTALL) -c -m 755 $(AVPROGS) "$(BINDIR)" + +uninstall: uninstall-progs + +uninstall-progs: + $(RM) $(addprefix "$(BINDIR)/", $(ALLAVPROGS)) + +clean:: + $(RM) $(ALLAVPROGS) $(CLEANSUFFIXES:%=avtools/%) diff --git a/avconv.c b/avtools/avconv.c similarity index 100% rename from avconv.c rename to avtools/avconv.c diff --git a/avconv.h b/avtools/avconv.h similarity index 100% rename from avconv.h rename to avtools/avconv.h diff --git a/avconv_dxva2.c b/avtools/avconv_dxva2.c similarity index 100% rename from avconv_dxva2.c rename to avtools/avconv_dxva2.c diff --git a/avconv_filter.c b/avtools/avconv_filter.c similarity index 100% rename from avconv_filter.c rename to avtools/avconv_filter.c diff --git a/avconv_opt.c b/avtools/avconv_opt.c similarity index 100% rename from avconv_opt.c rename to avtools/avconv_opt.c diff --git a/avconv_qsv.c b/avtools/avconv_qsv.c similarity index 100% rename from avconv_qsv.c rename to avtools/avconv_qsv.c diff --git a/avconv_vaapi.c b/avtools/avconv_vaapi.c similarity index 100% rename from avconv_vaapi.c rename to avtools/avconv_vaapi.c diff --git a/avconv_vda.c b/avtools/avconv_vda.c similarity index 100% rename from avconv_vda.c rename to avtools/avconv_vda.c diff --git a/avconv_vdpau.c b/avtools/avconv_vdpau.c similarity index 100% rename from avconv_vdpau.c rename to avtools/avconv_vdpau.c diff --git a/avplay.c b/avtools/avplay.c similarity index 100% rename from avplay.c rename to avtools/avplay.c diff --git a/avprobe.c b/avtools/avprobe.c similarity index 100% rename from avprobe.c rename to avtools/avprobe.c diff --git a/cmdutils.c b/avtools/cmdutils.c similarity index 100% rename from cmdutils.c rename to avtools/cmdutils.c diff --git a/cmdutils.h b/avtools/cmdutils.h similarity index 100% rename from cmdutils.h rename to avtools/cmdutils.h From 5d3953a5dcfd5f71391b7f34908517eb6f7e5146 Mon Sep 17 00:00:00 2001 From: John Stebbins Date: Wed, 15 Feb 2017 15:22:40 -0700 Subject: [PATCH 0937/3374] matroskaenc: factor ts_offset into block timecode computation ts_offset was added to cluster timecode, but then effectively subtracted back off the block timecode When setting initial_padding for an audio stream, the timestamps are written incorrectly to the mkv file. cluster timecode gets written as pts0 + ts_offset which is correct, but then block timecode gets written as pts - cluster timecode which expanded is pts - (pts0 + ts_offset). Adding cluster and block tc back together: cluster + block = (pts0 + ts_offset) + (pts - (pts0 + ts_offset)) = pts But the result should be pts + ts_offset since demux will subtract the CodecDelay element from pts and set initial_padding to CodecDelay. This patch gives the correct result. --- libavformat/matroskaenc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index e951a0fb679cd..2fe6e0ed4991b 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -1461,6 +1461,7 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb, uint8_t *data = NULL; int offset = 0, size = pkt->size; int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts; + ts += mkv->tracks[pkt->stream_index].ts_offset; av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, " "pts %" PRId64 ", dts %" PRId64 ", duration %" PRId64 ", flags %d\n", From 156bc0193bd47d3f4b3adaa93be0e206e12686ab Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Fri, 17 Feb 2017 23:13:14 +0000 Subject: [PATCH 0938/3374] fate: Add webp alpha test --- tests/fate/image.mak | 11 +++++++++-- tests/ref/fate/{webp => webp-yuv420p} | 0 tests/ref/fate/webp-yuva420p | 2 ++ 3 files changed, 11 insertions(+), 2 deletions(-) rename tests/ref/fate/{webp => webp-yuv420p} (100%) create mode 100644 tests/ref/fate/webp-yuva420p diff --git a/tests/fate/image.mak b/tests/fate/image.mak index 83fa71a199f76..7d970312d4d58 100644 --- a/tests/fate/image.mak +++ b/tests/fate/image.mak @@ -223,8 +223,15 @@ FATE_TIFF-$(call DEMDEC, IMAGE2, TIFF) += $(FATE_TIFF) FATE_SAMPLES_AVCONV += $(FATE_TIFF-yes) fate-tiff: $(FATE_TIFF-yes) -FATE_SAMPLES_AVCONV-$(call DEMDEC, IMAGE2, WEBP) += fate-webp -fate-webp: CMD = framecrc -i $(TARGET_SAMPLES)/webp/image_small.webp +FATE_WEBP += fate-webp-yuv420p +fate-webp-yuv420p: CMD = framecrc -i $(TARGET_SAMPLES)/webp/image_small.webp + +FATE_WEBP += fate-webp-yuva420p +fate-webp-yuva420p: CMD = framecrc -i $(TARGET_SAMPLES)/webp/1_webp_a.webp + +FATE_WEBP-$(call DEMDEC, IMAGE2, WEBP) += $(FATE_WEBP) +FATE_SAMPLES_AVCONV += $(FATE_WEBP-yes) +fate-webp: $(FATE_WEBP-yes) FATE_XBM += fate-xbm10 fate-xbm10: CMD = framecrc -i $(TARGET_SAMPLES)/xbm/xl.xbm diff --git a/tests/ref/fate/webp b/tests/ref/fate/webp-yuv420p similarity index 100% rename from tests/ref/fate/webp rename to tests/ref/fate/webp-yuv420p diff --git a/tests/ref/fate/webp-yuva420p b/tests/ref/fate/webp-yuva420p new file mode 100644 index 0000000000000..3350edf2d744e --- /dev/null +++ b/tests/ref/fate/webp-yuva420p @@ -0,0 +1,2 @@ +#tb 0: 1/25 +0, 0, 0, 1, 301200, 0x12b071a0 From fec3456ce188e895a2082fc1fb298570fc29ad29 Mon Sep 17 00:00:00 2001 From: John Stebbins Date: Tue, 21 Feb 2017 16:47:20 -0700 Subject: [PATCH 0939/3374] fate: Update fate-lavf-mkv after commit 5d3953a5dc --- tests/ref/lavf/mkv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ref/lavf/mkv b/tests/ref/lavf/mkv index db0aba0125744..04c5f3cac2b68 100644 --- a/tests/ref/lavf/mkv +++ b/tests/ref/lavf/mkv @@ -1,3 +1,3 @@ -76d400179dfd6143f50ea4d19fe8ed99 *./tests/data/lavf/lavf.mkv +dad336329ef85127f97e9d12a3b57a59 *./tests/data/lavf/lavf.mkv 320383 ./tests/data/lavf/lavf.mkv -./tests/data/lavf/lavf.mkv CRC=0x36193cda +./tests/data/lavf/lavf.mkv CRC=0x63ed3cda From 04d2afa93b6c6f320ac45dd99ce1226f3c3d5ac8 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Wed, 22 Feb 2017 09:55:45 +0100 Subject: [PATCH 0940/3374] mkv: Update the seek test to match 5d3953a5dc --- tests/ref/seek/lavf-mkv | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/ref/seek/lavf-mkv b/tests/ref/seek/lavf-mkv index 530c8dfe4d599..8267a2a255c94 100644 --- a/tests/ref/seek/lavf-mkv +++ b/tests/ref/seek/lavf-mkv @@ -1,53 +1,53 @@ -ret: 0 st: 1 flags:1 dts:-0.011000 pts:-0.011000 pos: 633 size: 208 +ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 633 size: 208 ret: 0 st:-1 flags:0 ts:-1.000000 -ret: 0 st: 1 flags:1 dts:-0.011000 pts:-0.011000 pos: 633 size: 208 +ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 849 size: 27837 ret: 0 st:-1 flags:1 ts: 1.894167 ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292271 size: 27834 ret: 0 st: 0 flags:0 ts: 0.788000 ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292271 size: 27834 ret: 0 st: 0 flags:1 ts:-0.317000 -ret: 0 st: 1 flags:1 dts:-0.011000 pts:-0.011000 pos: 633 size: 208 +ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 849 size: 27837 ret: 0 st: 1 flags:0 ts: 2.577000 ret:-EOF ret: 0 st: 1 flags:1 ts: 1.471000 -ret: 0 st: 1 flags:1 dts: 0.982000 pts: 0.982000 pos: 320112 size: 209 +ret: 0 st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 320112 size: 209 ret: 0 st:-1 flags:0 ts: 0.365002 ret: 0 st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 146824 size: 27925 ret: 0 st:-1 flags:1 ts:-0.740831 -ret: 0 st: 1 flags:1 dts:-0.011000 pts:-0.011000 pos: 633 size: 208 +ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 849 size: 27837 ret: 0 st: 0 flags:0 ts: 2.153000 ret:-EOF ret: 0 st: 0 flags:1 ts: 1.048000 ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292271 size: 27834 ret: 0 st: 1 flags:0 ts:-0.058000 -ret: 0 st: 1 flags:1 dts:-0.011000 pts:-0.011000 pos: 633 size: 208 +ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 633 size: 208 ret: 0 st: 1 flags:1 ts: 2.836000 -ret: 0 st: 1 flags:1 dts: 0.982000 pts: 0.982000 pos: 320112 size: 209 +ret: 0 st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 320112 size: 209 ret: 0 st:-1 flags:0 ts: 1.730004 ret:-EOF ret: 0 st:-1 flags:1 ts: 0.624171 ret: 0 st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 146824 size: 27925 ret: 0 st: 0 flags:0 ts:-0.482000 -ret: 0 st: 1 flags:1 dts:-0.011000 pts:-0.011000 pos: 633 size: 208 +ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 849 size: 27837 ret: 0 st: 0 flags:1 ts: 2.413000 ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292271 size: 27834 ret: 0 st: 1 flags:0 ts: 1.307000 ret:-EOF ret: 0 st: 1 flags:1 ts: 0.201000 -ret: 0 st: 1 flags:1 dts:-0.011000 pts:-0.011000 pos: 633 size: 208 +ret: 0 st: 1 flags:1 dts: 0.183000 pts: 0.183000 pos: 72204 size: 209 ret: 0 st:-1 flags:0 ts:-0.904994 -ret: 0 st: 1 flags:1 dts:-0.011000 pts:-0.011000 pos: 633 size: 208 +ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 849 size: 27837 ret: 0 st:-1 flags:1 ts: 1.989173 ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292271 size: 27834 ret: 0 st: 0 flags:0 ts: 0.883000 ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292271 size: 27834 ret: 0 st: 0 flags:1 ts:-0.222000 -ret: 0 st: 1 flags:1 dts:-0.011000 pts:-0.011000 pos: 633 size: 208 +ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 849 size: 27837 ret: 0 st: 1 flags:0 ts: 2.672000 ret:-EOF ret: 0 st: 1 flags:1 ts: 1.566000 -ret: 0 st: 1 flags:1 dts: 0.982000 pts: 0.982000 pos: 320112 size: 209 +ret: 0 st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 320112 size: 209 ret: 0 st:-1 flags:0 ts: 0.460008 ret: 0 st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 146824 size: 27925 ret: 0 st:-1 flags:1 ts:-0.645825 -ret: 0 st: 1 flags:1 dts:-0.011000 pts:-0.011000 pos: 633 size: 208 +ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 849 size: 27837 From ed6a891c364f8b0850b557d9578b8920cc15a937 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 22 Feb 2017 11:39:21 +0100 Subject: [PATCH 0941/3374] Place attribute_deprecated in the right position for struct declarations libavcodec/vaapi.h:58:1: warning: attribute 'deprecated' is ignored, place it after "struct" to apply attribute to type declaration [-Wignored-attributes] --- libavcodec/vaapi.h | 3 +-- libavcodec/xvmc.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/libavcodec/vaapi.h b/libavcodec/vaapi.h index ceb7904bea886..391368c85f058 100644 --- a/libavcodec/vaapi.h +++ b/libavcodec/vaapi.h @@ -55,8 +55,7 @@ * * Deprecated: use AVCodecContext.hw_frames_ctx instead. */ -attribute_deprecated -struct vaapi_context { +struct attribute_deprecated vaapi_context { /** * Window system dependent data * diff --git a/libavcodec/xvmc.h b/libavcodec/xvmc.h index 950ed1827646d..91027b9c2f15b 100644 --- a/libavcodec/xvmc.h +++ b/libavcodec/xvmc.h @@ -45,7 +45,7 @@ #define AV_XVMC_ID 0x1DC711C0 /**< special value to ensure that regular pixel routines haven't corrupted the struct the number is 1337 speak for the letters IDCT MCo (motion compensation) */ -attribute_deprecated struct xvmc_pix_fmt { +struct attribute_deprecated xvmc_pix_fmt { /** The field contains the special constant value AV_XVMC_ID. It is used as a test that the application correctly uses the API, and that there is no corruption caused by pixel routines. From c582cb8537367721bb399a5d01b652c20142b756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 14 Jan 2017 20:49:19 +0200 Subject: [PATCH 0942/3374] arm/aarch64: vp9lpf: Keep the comparison to E within 8 bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The theoretical maximum value of E is 193, so we can just saturate the addition to 255. Before: Cortex A7 A8 A9 A53 A53/AArch64 vp9_loop_filter_v_4_8_neon: 143.0 127.7 114.8 88.0 87.7 vp9_loop_filter_v_8_8_neon: 241.0 197.2 173.7 140.0 136.7 vp9_loop_filter_v_16_8_neon: 497.0 419.5 379.7 293.0 275.7 vp9_loop_filter_v_16_16_neon: 965.2 818.7 731.4 579.0 452.0 After: vp9_loop_filter_v_4_8_neon: 136.0 125.7 112.6 84.0 83.0 vp9_loop_filter_v_8_8_neon: 234.0 195.5 171.5 136.0 133.7 vp9_loop_filter_v_16_8_neon: 490.0 417.5 377.7 289.0 271.0 vp9_loop_filter_v_16_16_neon: 951.2 814.7 732.3 571.0 446.7 Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9lpf_neon.S | 40 +++++++------------------------- libavcodec/arm/vp9lpf_neon.S | 11 ++++----- 2 files changed, 14 insertions(+), 37 deletions(-) diff --git a/libavcodec/aarch64/vp9lpf_neon.S b/libavcodec/aarch64/vp9lpf_neon.S index 5fafc7ad5c9b8..48cac4cac6634 100644 --- a/libavcodec/aarch64/vp9lpf_neon.S +++ b/libavcodec/aarch64/vp9lpf_neon.S @@ -51,13 +51,6 @@ // see the arm version instead. -.macro uabdl_sz dst1, dst2, in1, in2, sz - uabdl \dst1, \in1\().8b, \in2\().8b -.ifc \sz, .16b - uabdl2 \dst2, \in1\().16b, \in2\().16b -.endif -.endm - .macro add_sz dst1, dst2, in1, in2, in3, in4, sz add \dst1, \in1, \in3 .ifc \sz, .16b @@ -86,20 +79,6 @@ .endif .endm -.macro cmhs_sz dst1, dst2, in1, in2, in3, in4, sz - cmhs \dst1, \in1, \in3 -.ifc \sz, .16b - cmhs \dst2, \in2, \in4 -.endif -.endm - -.macro xtn_sz dst, in1, in2, sz - xtn \dst\().8b, \in1 -.ifc \sz, .16b - xtn2 \dst\().16b, \in2 -.endif -.endm - .macro usubl_sz dst1, dst2, in1, in2, sz usubl \dst1, \in1\().8b, \in2\().8b .ifc \sz, .16b @@ -179,20 +158,20 @@ // tmpq2 == tmp3 + tmp4, etc. .macro loop_filter wd, sz, mix, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8 .if \mix == 0 - dup v0.8h, w2 // E - dup v1.8h, w2 // E + dup v0\sz, w2 // E dup v2\sz, w3 // I dup v3\sz, w4 // H .else - dup v0.8h, w2 // E + dup v0.8b, w2 // E dup v2.8b, w3 // I dup v3.8b, w4 // H + lsr w5, w2, #8 lsr w6, w3, #8 lsr w7, w4, #8 - ushr v1.8h, v0.8h, #8 // E + dup v1.8b, w5 // E dup v4.8b, w6 // I - bic v0.8h, #255, lsl 8 // E dup v5.8b, w7 // H + trn1 v0.2d, v0.2d, v1.2d trn1 v2.2d, v2.2d, v4.2d trn1 v3.2d, v3.2d, v5.2d .endif @@ -206,16 +185,15 @@ umax v4\sz, v4\sz, v5\sz umax v5\sz, v6\sz, v7\sz umax \tmp1\sz, \tmp1\sz, \tmp2\sz - uabdl_sz v6.8h, v7.8h, v23, v24, \sz // abs(p0 - q0) + uabd v6\sz, v23\sz, v24\sz // abs(p0 - q0) umax v4\sz, v4\sz, v5\sz - add_sz v6.8h, v7.8h, v6.8h, v7.8h, v6.8h, v7.8h, \sz // abs(p0 - q0) * 2 + uqadd v6\sz, v6\sz, v6\sz // abs(p0 - q0) * 2 uabd v5\sz, v22\sz, v25\sz // abs(p1 - q1) umax v4\sz, v4\sz, \tmp1\sz // max(abs(p3 - p2), ..., abs(q2 - q3)) ushr v5\sz, v5\sz, #1 cmhs v4\sz, v2\sz, v4\sz // max(abs()) <= I - uaddw_sz v6.8h, v7.8h, v6.8h, v7.8h, v5, \sz // abs(p0 - q0) * 2 + abs(p1 - q1) >> 1 - cmhs_sz v6.8h, v7.8h, v0.8h, v1.8h, v6.8h, v7.8h, \sz - xtn_sz v5, v6.8h, v7.8h, \sz + uqadd v6\sz, v6\sz, v5\sz // abs(p0 - q0) * 2 + abs(p1 - q1) >> 1 + cmhs v5\sz, v0\sz, v6\sz and v4\sz, v4\sz, v5\sz // fm // If no pixels need filtering, just exit as soon as possible diff --git a/libavcodec/arm/vp9lpf_neon.S b/libavcodec/arm/vp9lpf_neon.S index 1e161e0c63da7..e31c807cc01c4 100644 --- a/libavcodec/arm/vp9lpf_neon.S +++ b/libavcodec/arm/vp9lpf_neon.S @@ -51,7 +51,7 @@ @ and d28-d31 as temp registers, or d8-d15. @ tmp1,tmp2 = tmpq1, tmp3,tmp4 = tmpq2, tmp5,tmp6 = tmpq3, tmp7,tmp8 = tmpq4 .macro loop_filter wd, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmpq1, tmpq2, tmpq3, tmpq4 - vdup.u16 q0, r2 @ E + vdup.u8 d0, r2 @ E vdup.u8 d2, r3 @ I ldr r3, [sp] @@ -64,16 +64,15 @@ vmax.u8 d4, d4, d5 vmax.u8 d5, d6, d7 vmax.u8 \tmp1, \tmp1, \tmp2 - vabdl.u8 q3, d23, d24 @ abs(p0 - q0) + vabd.u8 d6, d23, d24 @ abs(p0 - q0) vmax.u8 d4, d4, d5 - vadd.u16 q3, q3, q3 @ abs(p0 - q0) * 2 + vqadd.u8 d6, d6, d6 @ abs(p0 - q0) * 2 vabd.u8 d5, d22, d25 @ abs(p1 - q1) vmax.u8 d4, d4, \tmp1 @ max(abs(p3 - p2), ..., abs(q2 - q3)) vshr.u8 d5, d5, #1 vcle.u8 d4, d4, d2 @ max(abs()) <= I - vaddw.u8 q3, q3, d5 @ abs(p0 - q0) * 2 + abs(p1 - q1) >> 1 - vcle.u16 q3, q3, q0 - vmovn.u16 d5, q3 + vqadd.u8 d6, d6, d5 @ abs(p0 - q0) * 2 + abs(p1 - q1) >> 1 + vcle.u8 d5, d6, d0 vand d4, d4, d5 @ fm vdup.u8 d3, r3 @ H From 3bf9c48320f25f3d5557485b0202f22ae60748b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 23 Feb 2017 23:33:58 +0200 Subject: [PATCH 0943/3374] aarch64: vp9lpf: Use dup+rev16+uzp1 instead of dup+lsr+dup+trn1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is one cycle faster in total, and three instructions fewer. Before: vp9_loop_filter_mix2_v_44_16_neon: 123.2 After: vp9_loop_filter_mix2_v_44_16_neon: 122.2 Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9lpf_neon.S | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/libavcodec/aarch64/vp9lpf_neon.S b/libavcodec/aarch64/vp9lpf_neon.S index 48cac4cac6634..e9c497096bd60 100644 --- a/libavcodec/aarch64/vp9lpf_neon.S +++ b/libavcodec/aarch64/vp9lpf_neon.S @@ -162,18 +162,15 @@ dup v2\sz, w3 // I dup v3\sz, w4 // H .else - dup v0.8b, w2 // E - dup v2.8b, w3 // I - dup v3.8b, w4 // H - lsr w5, w2, #8 - lsr w6, w3, #8 - lsr w7, w4, #8 - dup v1.8b, w5 // E - dup v4.8b, w6 // I - dup v5.8b, w7 // H - trn1 v0.2d, v0.2d, v1.2d - trn1 v2.2d, v2.2d, v4.2d - trn1 v3.2d, v3.2d, v5.2d + dup v0.8h, w2 // E + dup v2.8h, w3 // I + dup v3.8h, w4 // H + rev16 v1.16b, v0.16b // E + rev16 v4.16b, v2.16b // I + rev16 v5.16b, v3.16b // H + uzp1 v0.16b, v0.16b, v1.16b + uzp1 v2.16b, v2.16b, v4.16b + uzp1 v3.16b, v3.16b, v5.16b .endif uabd v4\sz, v20\sz, v21\sz // abs(p3 - p2) From 575e31e931e4178e9f1e24407503c9b4ec0ef9ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 14 Jan 2017 13:22:30 +0200 Subject: [PATCH 0944/3374] arm: vp9lpf: Implement the mix2_44 function with one single filter pass MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For this case, with 8 inputs but only changing 4 of them, we can fit all 16 input pixels into a q register, and still have enough temporary registers for doing the loop filter. The wd=8 filters would require too many temporary registers for processing all 16 pixels at once though. Before: Cortex A7 A8 A9 A53 vp9_loop_filter_mix2_v_44_16_neon: 289.7 256.2 237.5 181.2 After: vp9_loop_filter_mix2_v_44_16_neon: 221.2 150.5 177.7 138.0 Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9dsp_init_arm.c | 7 +- libavcodec/arm/vp9lpf_neon.S | 191 +++++++++++++++++++++++++++++++ 2 files changed, 195 insertions(+), 3 deletions(-) diff --git a/libavcodec/arm/vp9dsp_init_arm.c b/libavcodec/arm/vp9dsp_init_arm.c index e99d931674376..1ede1708e7f99 100644 --- a/libavcodec/arm/vp9dsp_init_arm.c +++ b/libavcodec/arm/vp9dsp_init_arm.c @@ -194,6 +194,8 @@ define_loop_filters(8, 8); define_loop_filters(16, 8); define_loop_filters(16, 16); +define_loop_filters(44, 16); + #define lf_mix_fn(dir, wd1, wd2, stridea) \ static void loop_filter_##dir##_##wd1##wd2##_16_neon(uint8_t *dst, \ ptrdiff_t stride, \ @@ -207,7 +209,6 @@ static void loop_filter_##dir##_##wd1##wd2##_16_neon(uint8_t *dst, lf_mix_fn(h, wd1, wd2, stride) \ lf_mix_fn(v, wd1, wd2, sizeof(uint8_t)) -lf_mix_fns(4, 4) lf_mix_fns(4, 8) lf_mix_fns(8, 4) lf_mix_fns(8, 8) @@ -227,8 +228,8 @@ static av_cold void vp9dsp_loopfilter_init_arm(VP9DSPContext *dsp) dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_neon; dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_neon; - dsp->loop_filter_mix2[0][0][0] = loop_filter_h_44_16_neon; - dsp->loop_filter_mix2[0][0][1] = loop_filter_v_44_16_neon; + dsp->loop_filter_mix2[0][0][0] = ff_vp9_loop_filter_h_44_16_neon; + dsp->loop_filter_mix2[0][0][1] = ff_vp9_loop_filter_v_44_16_neon; dsp->loop_filter_mix2[0][1][0] = loop_filter_h_48_16_neon; dsp->loop_filter_mix2[0][1][1] = loop_filter_v_48_16_neon; dsp->loop_filter_mix2[1][0][0] = loop_filter_h_84_16_neon; diff --git a/libavcodec/arm/vp9lpf_neon.S b/libavcodec/arm/vp9lpf_neon.S index e31c807cc01c4..12984a900c0a4 100644 --- a/libavcodec/arm/vp9lpf_neon.S +++ b/libavcodec/arm/vp9lpf_neon.S @@ -44,6 +44,109 @@ vtrn.8 \r2, \r3 .endm +@ The input to and output from this macro is in the registers q8-q15, +@ and q0-q7 are used as scratch registers. +@ p3 = q8, p0 = q11, q0 = q12, q3 = q15 +.macro loop_filter_q + vdup.u8 d0, r2 @ E + lsr r2, r2, #8 + vdup.u8 d2, r3 @ I + lsr r3, r3, #8 + vdup.u8 d1, r2 @ E + vdup.u8 d3, r3 @ I + + vabd.u8 q2, q8, q9 @ abs(p3 - p2) + vabd.u8 q3, q9, q10 @ abs(p2 - p1) + vabd.u8 q4, q10, q11 @ abs(p1 - p0) + vabd.u8 q5, q12, q13 @ abs(q0 - q1) + vabd.u8 q6, q13, q14 @ abs(q1 - q2) + vabd.u8 q7, q14, q15 @ abs(q2 - q3) + vmax.u8 q2, q2, q3 + vmax.u8 q3, q4, q5 + vmax.u8 q4, q6, q7 + vabd.u8 q5, q11, q12 @ abs(p0 - q0) + vmax.u8 q2, q2, q3 + vqadd.u8 q5, q5, q5 @ abs(p0 - q0) * 2 + vabd.u8 q7, q10, q13 @ abs(p1 - q1) + vmax.u8 q2, q2, q4 @ max(abs(p3 - p2), ..., abs(q2 - q3)) + vshr.u8 q7, q7, #1 + vcle.u8 q2, q2, q1 @ max(abs()) <= I + vqadd.u8 q5, q5, q7 @ abs(p0 - q0) * 2 + abs(p1 - q1) >> 1 + vcle.u8 q5, q5, q0 + vand q2, q2, q5 @ fm + + vshrn.u16 d10, q2, #4 + vmov r2, r3, d10 + orrs r2, r2, r3 + @ If no pixels need filtering, just exit as soon as possible + beq 9f + + @ Calculate the normal inner loop filter for 2 or 4 pixels + ldr r3, [sp, #64] + vabd.u8 q3, q10, q11 @ abs(p1 - p0) + vabd.u8 q4, q13, q12 @ abs(q1 - q0) + + vsubl.u8 q5, d20, d26 @ p1 - q1 + vsubl.u8 q6, d21, d27 @ p1 - q1 + vmax.u8 q3, q3, q4 @ max(abs(p1 - p0), abs(q1 - q0)) + vqmovn.s16 d10, q5 @ av_clip_int8p(p1 - q1) + vqmovn.s16 d11, q6 @ av_clip_int8p(p1 - q1) + vdup.u8 d8, r3 @ H + lsr r3, r3, #8 + vdup.u8 d9, r3 @ H + vsubl.u8 q6, d24, d22 @ q0 - p0 + vsubl.u8 q7, d25, d23 @ q0 - p0 + vcle.u8 q3, q3, q4 @ hev + vmov.s16 q0, #3 + vand q3, q3, q2 @ !hev && fm && !flat8in + + vmul.s16 q6, q6, q0 @ 3 * (q0 - p0) + vmul.s16 q7, q7, q0 @ 3 * (q0 - p0) + vbic q5, q5, q3 @ if (!hev) av_clip_int8 = 0 + vaddw.s8 q6, q6, d10 @ 3 * (q0 - p0) [+ av_clip_int8(p1 - q1)] + vaddw.s8 q7, q7, d11 @ 3 * (q0 - p0) [+ av_clip_int8(p1 - q1)] + vmov.s8 q5, #4 + vqmovn.s16 d12, q6 + vqmovn.s16 d13, q7 @ av_clip_int8(3 * (q0 - p0) [+ av_clip_int8(p1 - q1)], BIT_DEPTH - 1) = f + vmov.s8 q0, #3 + + vqadd.s8 q5, q6, q5 @ FFMIN(f + 4, 127) + vqadd.s8 q0, q6, q0 @ FFMIN(f + 3, 127) + vmovl.u8 q6, d22 @ p0 + vmovl.u8 q7, d23 @ p0 + vshr.s8 q5, q5, #3 @ f1 + vshr.s8 q0, q0, #3 @ f2 + + vaddw.s8 q6, q6, d0 @ p0 + f2 + vaddw.s8 q7, q7, d1 @ p0 + f2 + vqmovun.s16 d0, q6 @ out p0 + vmovl.u8 q6, d24 @ q0 + vqmovun.s16 d1, q7 @ out p0 + vmovl.u8 q7, d25 @ q0 + vsubw.s8 q6, q6, d10 @ q0 - f1 + vsubw.s8 q7, q7, d11 @ q0 - f1 + vqmovun.s16 d12, q6 @ out q0 + vqmovun.s16 d13, q7 @ out q0 + vrshr.s8 q5, q5, #1 @ f = (f1 + 1) >> 1 + vbit q11, q0, q2 @ if (fm && !flat8in) + vbit q12, q6, q2 + + vmovl.u8 q0, d20 @ p1 + vmovl.u8 q2, d21 @ p1 + vmovl.u8 q6, d26 @ q1 + vmovl.u8 q7, d27 @ q1 + vaddw.s8 q0, q0, d10 @ p1 + f + vaddw.s8 q2, q2, d11 @ p1 + f + vsubw.s8 q6, q6, d10 @ q1 - f + vsubw.s8 q7, q7, d11 @ q1 - f + vqmovun.s16 d0, q0 @ out p1 + vqmovun.s16 d1, q2 @ out p1 + vqmovun.s16 d12, q6 @ out q1 + vqmovun.s16 d13, q7 @ out q1 + vbit q10, q0, q3 @ if (!hev && fm && !flat8in) + vbit q13, q6, q3 +.endm + @ The input to and output from this macro is in the registers d16-d31, @ and d0-d7 are used as scratch registers. @ p7 = d16 .. p3 = d20, p0 = d23, q0 = d24, q3 = d27, q7 = d31 @@ -455,6 +558,94 @@ function ff_vp9_loop_filter_h_4_8_neon, export=1 bx lr endfunc +function ff_vp9_loop_filter_v_44_16_neon, export=1 + vpush {q4-q7} + sub r12, r0, r1, lsl #2 + vld1.8 {q8}, [r12,:128], r1 @ p3 + vld1.8 {q12}, [r0, :128], r1 @ q0 + vld1.8 {q9}, [r12,:128], r1 @ p2 + vld1.8 {q13}, [r0, :128], r1 @ q1 + vld1.8 {q10}, [r12,:128], r1 @ p1 + vld1.8 {q14}, [r0, :128], r1 @ q2 + vld1.8 {q11}, [r12,:128], r1 @ p0 + vld1.8 {q15}, [r0, :128], r1 @ q3 + sub r0, r0, r1, lsl #2 + sub r12, r12, r1, lsl #1 + + loop_filter_q + + vst1.8 {q10}, [r12,:128], r1 + vst1.8 {q12}, [r0, :128], r1 + vst1.8 {q11}, [r12,:128], r1 + vst1.8 {q13}, [r0, :128], r1 +9: + vpop {q4-q7} + bx lr +endfunc + +function ff_vp9_loop_filter_h_44_16_neon, export=1 + vpush {q4-q7} + sub r12, r0, #4 + add r0, r12, r1, lsl #2 + vld1.8 {d16}, [r12], r1 + vld1.8 {d24}, [r0], r1 + vld1.8 {d18}, [r12], r1 + vld1.8 {d26}, [r0], r1 + vld1.8 {d20}, [r12], r1 + vld1.8 {d28}, [r0], r1 + vld1.8 {d22}, [r12], r1 + vld1.8 {d30}, [r0], r1 + mov r12, r0 + add r0, r0, r1, lsl #2 + vld1.8 {d17}, [r12], r1 + vld1.8 {d25}, [r0], r1 + vld1.8 {d19}, [r12], r1 + vld1.8 {d27}, [r0], r1 + vld1.8 {d21}, [r12], r1 + vld1.8 {d29}, [r0], r1 + vld1.8 {d23}, [r12], r1 + vld1.8 {d31}, [r0], r1 + + @ Transpose the 16x8 pixels, as two 8x8 parts + transpose_8x8 q8, q9, q10, q11, q12, q13, q14, q15 + + loop_filter_q + + sub r12, r0, r1, lsl #4 + add r0, r12, r1, lsl #3 + @ Move r0/r12 forward by 2 pixels; we don't need to rewrite the + @ outermost 2 pixels since they aren't changed. + add r12, r12, #2 + add r0, r0, #2 + + @ We only will write the mid 4 pixels back; after the loop filter, + @ these are in q10, q11, q12, q13, ordered as rows (16x4 pixels). + @ We need to transpose them to columns, done with a 4x4 transpose + @ (which in practice is four 4x4 transposes of the 4x4 blocks of + @ the 16x4 pixels; into 4x16 pixels). + transpose_4x4 q10, q11, q12, q13 + + vst1.32 {d20[0]}, [r12], r1 + vst1.32 {d21[0]}, [r0], r1 + vst1.32 {d22[0]}, [r12], r1 + vst1.32 {d23[0]}, [r0], r1 + vst1.32 {d24[0]}, [r12], r1 + vst1.32 {d25[0]}, [r0], r1 + vst1.32 {d26[0]}, [r12], r1 + vst1.32 {d27[0]}, [r0], r1 + vst1.32 {d20[1]}, [r12], r1 + vst1.32 {d21[1]}, [r0], r1 + vst1.32 {d22[1]}, [r12], r1 + vst1.32 {d23[1]}, [r0], r1 + vst1.32 {d24[1]}, [r12], r1 + vst1.32 {d25[1]}, [r0], r1 + vst1.32 {d26[1]}, [r12], r1 + vst1.32 {d27[1]}, [r0], r1 +9: + vpop {q4-q7} + bx lr +endfunc + function ff_vp9_loop_filter_v_8_8_neon, export=1 sub r12, r0, r1, lsl #2 vld1.8 {d20}, [r12,:64], r1 @ p3 From 402546a17233a8815307df9e14ff88cd70424537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 2 Jan 2017 22:50:38 +0200 Subject: [PATCH 0945/3374] arm: vp9itxfm: Avoid reloading the idct32 coefficients MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The idct32x32 function actually pushed q4-q7 onto the stack even though it didn't clobber them; there are plenty of registers that can be used to allow keeping all the idct coefficients in registers without having to reload different subsets of them at different stages in the transform. Since the idct16 core transform avoids clobbering q4-q7 (but clobbers q2-q3 instead, to avoid needing to back up and restore q4-q7 at all in the idct16 function), and the lanewise vmul needs a register in the q0-q3 range, we move the stored coefficients from q2-q3 into q4-q5 while doing idct16. While keeping these coefficients in registers, we still can skip pushing q7. Before: Cortex A7 A8 A9 A53 vp9_inv_dct_dct_32x32_sub32_add_neon: 18553.8 17182.7 14303.3 12089.7 After: vp9_inv_dct_dct_32x32_sub32_add_neon: 18470.3 16717.7 14173.6 11860.8 Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 246 ++++++++++++++++----------------- 1 file changed, 120 insertions(+), 126 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index 8dc4bbfa5529e..bed502eba2007 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -1185,58 +1185,51 @@ function idct32x32_dc_add_neon endfunc .macro idct32_end - butterfly d16, d5, d4, d5 @ d16 = t16a, d5 = t19a + butterfly d16, d9, d8, d9 @ d16 = t16a, d9 = t19a butterfly d17, d20, d23, d20 @ d17 = t17, d20 = t18 - butterfly d18, d6, d7, d6 @ d18 = t23a, d6 = t20a + butterfly d18, d10, d11, d10 @ d18 = t23a, d10 = t20a butterfly d19, d21, d22, d21 @ d19 = t22, d21 = t21 - butterfly d4, d28, d28, d30 @ d4 = t24a, d28 = t27a + butterfly d8, d28, d28, d30 @ d8 = t24a, d28 = t27a butterfly d23, d26, d25, d26 @ d23 = t25, d26 = t26 - butterfly d7, d29, d29, d31 @ d7 = t31a, d29 = t28a + butterfly d11, d29, d29, d31 @ d11 = t31a, d29 = t28a butterfly d22, d27, d24, d27 @ d22 = t30, d27 = t29 mbutterfly d27, d20, d0[1], d0[2], q12, q15 @ d27 = t18a, d20 = t29a - mbutterfly d29, d5, d0[1], d0[2], q12, q15 @ d29 = t19, d5 = t28 - mbutterfly d28, d6, d0[1], d0[2], q12, q15, neg=1 @ d28 = t27, d6 = t20 + mbutterfly d29, d9, d0[1], d0[2], q12, q15 @ d29 = t19, d9 = t28 + mbutterfly d28, d10, d0[1], d0[2], q12, q15, neg=1 @ d28 = t27, d10 = t20 mbutterfly d26, d21, d0[1], d0[2], q12, q15, neg=1 @ d26 = t26a, d21 = t21a - butterfly d31, d24, d7, d4 @ d31 = t31, d24 = t24 + butterfly d31, d24, d11, d8 @ d31 = t31, d24 = t24 butterfly d30, d25, d22, d23 @ d30 = t30a, d25 = t25a butterfly_r d23, d16, d16, d18 @ d23 = t23, d16 = t16 butterfly_r d22, d17, d17, d19 @ d22 = t22a, d17 = t17a butterfly d18, d21, d27, d21 @ d18 = t18, d21 = t21 - butterfly_r d27, d28, d5, d28 @ d27 = t27a, d28 = t28a - butterfly d4, d26, d20, d26 @ d4 = t29, d26 = t26 - butterfly d19, d20, d29, d6 @ d19 = t19a, d20 = t20 - vmov d29, d4 @ d29 = t29 - - mbutterfly0 d27, d20, d27, d20, d4, d6, q2, q3 @ d27 = t27, d20 = t20 - mbutterfly0 d26, d21, d26, d21, d4, d6, q2, q3 @ d26 = t26a, d21 = t21a - mbutterfly0 d25, d22, d25, d22, d4, d6, q2, q3 @ d25 = t25, d22 = t22 - mbutterfly0 d24, d23, d24, d23, d4, d6, q2, q3 @ d24 = t24a, d23 = t23a + butterfly_r d27, d28, d9, d28 @ d27 = t27a, d28 = t28a + butterfly d8, d26, d20, d26 @ d8 = t29, d26 = t26 + butterfly d19, d20, d29, d10 @ d19 = t19a, d20 = t20 + vmov d29, d8 @ d29 = t29 + + mbutterfly0 d27, d20, d27, d20, d8, d10, q4, q5 @ d27 = t27, d20 = t20 + mbutterfly0 d26, d21, d26, d21, d8, d10, q4, q5 @ d26 = t26a, d21 = t21a + mbutterfly0 d25, d22, d25, d22, d8, d10, q4, q5 @ d25 = t25, d22 = t22 + mbutterfly0 d24, d23, d24, d23, d8, d10, q4, q5 @ d24 = t24a, d23 = t23a bx lr .endm function idct32_odd - movrel r12, idct_coeffs - add r12, r12, #32 - vld1.16 {q0-q1}, [r12,:128] - - mbutterfly d16, d31, d0[0], d0[1], q2, q3 @ d16 = t16a, d31 = t31a - mbutterfly d24, d23, d0[2], d0[3], q2, q3 @ d24 = t17a, d23 = t30a - mbutterfly d20, d27, d1[0], d1[1], q2, q3 @ d20 = t18a, d27 = t29a - mbutterfly d28, d19, d1[2], d1[3], q2, q3 @ d28 = t19a, d19 = t28a - mbutterfly d18, d29, d2[0], d2[1], q2, q3 @ d18 = t20a, d29 = t27a - mbutterfly d26, d21, d2[2], d2[3], q2, q3 @ d26 = t21a, d21 = t26a - mbutterfly d22, d25, d3[0], d3[1], q2, q3 @ d22 = t22a, d25 = t25a - mbutterfly d30, d17, d3[2], d3[3], q2, q3 @ d30 = t23a, d17 = t24a - - sub r12, r12, #32 - vld1.16 {q0}, [r12,:128] - - butterfly d4, d24, d16, d24 @ d4 = t16, d24 = t17 - butterfly d5, d20, d28, d20 @ d5 = t19, d20 = t18 - butterfly d6, d26, d18, d26 @ d6 = t20, d26 = t21 - butterfly d7, d22, d30, d22 @ d7 = t23, d22 = t22 + mbutterfly d16, d31, d4[0], d4[1], q4, q5 @ d16 = t16a, d31 = t31a + mbutterfly d24, d23, d4[2], d4[3], q4, q5 @ d24 = t17a, d23 = t30a + mbutterfly d20, d27, d5[0], d5[1], q4, q5 @ d20 = t18a, d27 = t29a + mbutterfly d28, d19, d5[2], d5[3], q4, q5 @ d28 = t19a, d19 = t28a + mbutterfly d18, d29, d6[0], d6[1], q4, q5 @ d18 = t20a, d29 = t27a + mbutterfly d26, d21, d6[2], d6[3], q4, q5 @ d26 = t21a, d21 = t26a + mbutterfly d22, d25, d7[0], d7[1], q4, q5 @ d22 = t22a, d25 = t25a + mbutterfly d30, d17, d7[2], d7[3], q4, q5 @ d30 = t23a, d17 = t24a + + butterfly d8, d24, d16, d24 @ d8 = t16, d24 = t17 + butterfly d9, d20, d28, d20 @ d9 = t19, d20 = t18 + butterfly d10, d26, d18, d26 @ d10 = t20, d26 = t21 + butterfly d11, d22, d30, d22 @ d11 = t23, d22 = t22 butterfly d28, d25, d17, d25 @ d28 = t24, d25 = t25 butterfly d30, d21, d29, d21 @ d30 = t27, d21 = t26 butterfly d29, d23, d31, d23 @ d29 = t31, d23 = t30 @@ -1250,26 +1243,19 @@ function idct32_odd endfunc function idct32_odd_half - movrel r12, idct_coeffs - add r12, r12, #32 - vld1.16 {q0-q1}, [r12,:128] - - mbutterfly_h1 d16, d31, d0[0], d0[1], q2, q3 @ d16 = t16a, d31 = t31a - mbutterfly_h2 d24, d23, d0[2], d0[3], q2, q3 @ d24 = t17a, d23 = t30a - mbutterfly_h1 d20, d27, d1[0], d1[1], q2, q3 @ d20 = t18a, d27 = t29a - mbutterfly_h2 d28, d19, d1[2], d1[3], q2, q3 @ d28 = t19a, d19 = t28a - mbutterfly_h1 d18, d29, d2[0], d2[1], q2, q3 @ d18 = t20a, d29 = t27a - mbutterfly_h2 d26, d21, d2[2], d2[3], q2, q3 @ d26 = t21a, d21 = t26a - mbutterfly_h1 d22, d25, d3[0], d3[1], q2, q3 @ d22 = t22a, d25 = t25a - mbutterfly_h2 d30, d17, d3[2], d3[3], q2, q3 @ d30 = t23a, d17 = t24a - - sub r12, r12, #32 - vld1.16 {q0}, [r12,:128] - - butterfly d4, d24, d16, d24 @ d4 = t16, d24 = t17 - butterfly d5, d20, d28, d20 @ d5 = t19, d20 = t18 - butterfly d6, d26, d18, d26 @ d6 = t20, d26 = t21 - butterfly d7, d22, d30, d22 @ d7 = t23, d22 = t22 + mbutterfly_h1 d16, d31, d4[0], d4[1], q4, q5 @ d16 = t16a, d31 = t31a + mbutterfly_h2 d24, d23, d4[2], d4[3], q4, q5 @ d24 = t17a, d23 = t30a + mbutterfly_h1 d20, d27, d5[0], d5[1], q4, q5 @ d20 = t18a, d27 = t29a + mbutterfly_h2 d28, d19, d5[2], d5[3], q4, q5 @ d28 = t19a, d19 = t28a + mbutterfly_h1 d18, d29, d6[0], d6[1], q4, q5 @ d18 = t20a, d29 = t27a + mbutterfly_h2 d26, d21, d6[2], d6[3], q4, q5 @ d26 = t21a, d21 = t26a + mbutterfly_h1 d22, d25, d7[0], d7[1], q4, q5 @ d22 = t22a, d25 = t25a + mbutterfly_h2 d30, d17, d7[2], d7[3], q4, q5 @ d30 = t23a, d17 = t24a + + butterfly d8, d24, d16, d24 @ d8 = t16, d24 = t17 + butterfly d9, d20, d28, d20 @ d9 = t19, d20 = t18 + butterfly d10, d26, d18, d26 @ d10 = t20, d26 = t21 + butterfly d11, d22, d30, d22 @ d11 = t23, d22 = t22 butterfly d28, d25, d17, d25 @ d28 = t24, d25 = t25 butterfly d30, d21, d29, d21 @ d30 = t27, d21 = t26 butterfly d29, d23, d31, d23 @ d29 = t31, d23 = t30 @@ -1284,45 +1270,38 @@ function idct32_odd_half endfunc function idct32_odd_quarter - movrel r12, idct_coeffs - add r12, r12, #32 - vld1.16 {q0-q1}, [r12,:128] - - vmull.s16 q2, d16, d0[0] - vmull.s16 q14, d19, d1[3] - vmull.s16 q15, d16, d0[1] - vmull.s16 q11, d17, d3[2] - vmull.s16 q3, d17, d3[3] - vmull.s16 q13, d19, d1[2] - vmull.s16 q10, d18, d2[0] - vmull.s16 q12, d18, d2[1] - - sub r12, r12, #32 - vld1.16 {q0}, [r12,:128] + vmull.s16 q4, d16, d4[0] + vmull.s16 q14, d19, d5[3] + vmull.s16 q15, d16, d4[1] + vmull.s16 q11, d17, d7[2] + vmull.s16 q5, d17, d7[3] + vmull.s16 q13, d19, d5[2] + vmull.s16 q10, d18, d6[0] + vmull.s16 q12, d18, d6[1] vneg.s32 q14, q14 - vneg.s32 q3, q3 + vneg.s32 q5, q5 - vrshrn.s32 d4, q2, #14 - vrshrn.s32 d5, q14, #14 + vrshrn.s32 d8, q4, #14 + vrshrn.s32 d9, q14, #14 vrshrn.s32 d29, q15, #14 vrshrn.s32 d28, q11, #14 - vrshrn.s32 d7, q3, #14 + vrshrn.s32 d11, q5, #14 vrshrn.s32 d31, q13, #14 - vrshrn.s32 d6, q10, #14 + vrshrn.s32 d10, q10, #14 vrshrn.s32 d30, q12, #14 - mbutterfly_l q8, q9, d29, d4, d0[3], d1[0] - mbutterfly_l q13, q10, d31, d5, d0[3], d1[0] + mbutterfly_l q8, q9, d29, d8, d0[3], d1[0] + mbutterfly_l q13, q10, d31, d9, d0[3], d1[0] vrshrn.s32 d23, q8, #14 vrshrn.s32 d24, q9, #14 vneg.s32 q10, q10 vrshrn.s32 d27, q13, #14 vrshrn.s32 d20, q10, #14 - mbutterfly_l q8, q9, d30, d6, d1[1], d1[2] + mbutterfly_l q8, q9, d30, d10, d1[1], d1[2] vrshrn.s32 d21, q8, #14 vrshrn.s32 d26, q9, #14 - mbutterfly_l q8, q9, d28, d7, d1[1], d1[2] + mbutterfly_l q8, q9, d28, d11, d1[1], d1[2] vrshrn.s32 d25, q8, #14 vneg.s32 q9, q9 vrshrn.s32 d22, q9, #14 @@ -1343,8 +1322,11 @@ endfunc function idct32_1d_4x32_pass1\suffix\()_neon push {lr} - movrel r12, idct_coeffs - vld1.16 {q0-q1}, [r12,:128] + @ idct16 clobbers q2-q3 (since it doesn't clobber q4-q7 at all + @ when doing the normal 16x16 idct), so move the idct32_odd coeffs + @ to q4-q5 + vmov q4, q2 + vmov q5, q3 @ Double stride of the input, since we only read every other line mov r12, #128 @@ -1372,6 +1354,11 @@ function idct32_1d_4x32_pass1\suffix\()_neon bl idct16\suffix + @ Move the idct32_odd coeffs back into q2-q3 for idct32_odd; + @ the constants for a vmul with a lane must be in q0-q3. + vmov q2, q4 + vmov q3, q5 + @ Do four 4x4 transposes. Originally, d16-d31 contain the @ 16 rows. Afterwards, d16-d19, d20-d23, d24-d27, d28-d31 @ contain the transposed 4x4 blocks. @@ -1407,24 +1394,24 @@ function idct32_1d_4x32_pass1\suffix\()_neon .endif add r2, r2, #64 - vmov.s16 d4, #0 + vmov.s16 d8, #0 @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31) .ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vld1.16 {d\i}, [r2,:64] - vst1.16 {d4}, [r2,:64], r12 + vst1.16 {d8}, [r2,:64], r12 .endr .endif .ifc \suffix,_quarter .irp i, 16, 17, 18, 19 vld1.16 {d\i}, [r2,:64] - vst1.16 {d4}, [r2,:64], r12 + vst1.16 {d8}, [r2,:64], r12 .endr .endif .ifc \suffix,_half .irp i, 16, 17, 18, 19, 20, 21, 22, 23 vld1.16 {d\i}, [r2,:64] - vst1.16 {d4}, [r2,:64], r12 + vst1.16 {d8}, [r2,:64], r12 .endr .endif @@ -1437,15 +1424,15 @@ function idct32_1d_4x32_pass1\suffix\()_neon @ from the output. .macro store_rev a, b, c, d .irp i, \a, \b, \c, \d - vld1.16 {d4}, [r0,:64] - vadd.s16 d4, d4, d\i - vst1.16 {d4}, [r0,:64]! + vld1.16 {d8}, [r0,:64] + vadd.s16 d8, d8, d\i + vst1.16 {d8}, [r0,:64]! vrev64.16 d\i, d\i .endr .irp i, \d, \c, \b, \a - vld1.16 {d4}, [r0,:64] - vsub.s16 d4, d4, d\i - vst1.16 {d4}, [r0,:64]! + vld1.16 {d8}, [r0,:64] + vsub.s16 d8, d8, d\i + vst1.16 {d8}, [r0,:64]! .endr .endm @@ -1466,8 +1453,8 @@ endfunc @ r2 = src (temp buffer) function idct32_1d_4x32_pass2\suffix\()_neon push {lr} - movrel r12, idct_coeffs - vld1.16 {q0-q1}, [r12,:128] + vmov q4, q2 + vmov q5, q3 mov r12, #128 @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30) @@ -1492,6 +1479,9 @@ function idct32_1d_4x32_pass2\suffix\()_neon bl idct16\suffix + vmov q2, q4 + vmov q3, q5 + .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vst1.16 {d\i}, [r2,:64], r12 .endr @@ -1524,38 +1514,38 @@ function idct32_1d_4x32_pass2\suffix\()_neon mov r12, #128 .macro load_acc_store a, b, c, d, neg=0 - vld1.16 {d4}, [r2,:64], r12 - vld1.16 {d5}, [r2,:64], r12 + vld1.16 {d8}, [r2,:64], r12 + vld1.16 {d9}, [r2,:64], r12 .if \neg == 0 - vadd.s16 d4, d4, d\a - vld1.16 {d6}, [r2,:64], r12 - vadd.s16 d5, d5, d\b - vld1.16 {d7}, [r2,:64], r12 - vadd.s16 d6, d6, d\c - vadd.s16 d7, d7, d\d + vadd.s16 d8, d8, d\a + vld1.16 {d10}, [r2,:64], r12 + vadd.s16 d9, d9, d\b + vld1.16 {d11}, [r2,:64], r12 + vadd.s16 d10, d10, d\c + vadd.s16 d11, d11, d\d .else - vsub.s16 d4, d4, d\a - vld1.16 {d6}, [r2,:64], r12 - vsub.s16 d5, d5, d\b - vld1.16 {d7}, [r2,:64], r12 - vsub.s16 d6, d6, d\c - vsub.s16 d7, d7, d\d + vsub.s16 d8, d8, d\a + vld1.16 {d10}, [r2,:64], r12 + vsub.s16 d9, d9, d\b + vld1.16 {d11}, [r2,:64], r12 + vsub.s16 d10, d10, d\c + vsub.s16 d11, d11, d\d .endif - vld1.32 {d2[]}, [r0,:32], r1 - vld1.32 {d2[1]}, [r0,:32], r1 - vrshr.s16 q2, q2, #6 - vld1.32 {d3[]}, [r0,:32], r1 - vrshr.s16 q3, q3, #6 - vld1.32 {d3[1]}, [r0,:32], r1 + vld1.32 {d12[]}, [r0,:32], r1 + vld1.32 {d12[1]}, [r0,:32], r1 + vrshr.s16 q4, q4, #6 + vld1.32 {d13[]}, [r0,:32], r1 + vrshr.s16 q5, q5, #6 + vld1.32 {d13[1]}, [r0,:32], r1 sub r0, r0, r1, lsl #2 - vaddw.u8 q2, q2, d2 - vaddw.u8 q3, q3, d3 - vqmovun.s16 d4, q2 - vqmovun.s16 d5, q3 - vst1.32 {d4[0]}, [r0,:32], r1 - vst1.32 {d4[1]}, [r0,:32], r1 - vst1.32 {d5[0]}, [r0,:32], r1 - vst1.32 {d5[1]}, [r0,:32], r1 + vaddw.u8 q4, q4, d12 + vaddw.u8 q5, q5, d13 + vqmovun.s16 d8, q4 + vqmovun.s16 d9, q5 + vst1.32 {d8[0]}, [r0,:32], r1 + vst1.32 {d8[1]}, [r0,:32], r1 + vst1.32 {d9[0]}, [r0,:32], r1 + vst1.32 {d9[1]}, [r0,:32], r1 .endm load_acc_store 31, 30, 29, 28 load_acc_store 27, 26, 25, 24 @@ -1584,7 +1574,7 @@ function ff_vp9_idct_idct_32x32_add_neon, export=1 cmp r3, #1 beq idct32x32_dc_add_neon push {r4-r8,lr} - vpush {q4-q7} + vpush {q4-q6} movrel r8, min_eob_idct_idct_32 + 2 @ Align the stack, allocate a temp buffer @@ -1598,6 +1588,10 @@ A and r7, sp, #15 mov r5, r1 mov r6, r2 + movrel r12, idct_coeffs + vld1.16 {q0-q1}, [r12,:128]! + vld1.16 {q2-q3}, [r12,:128] + cmp r3, #34 ble idct32x32_quarter_add_neon cmp r3, #135 @@ -1636,7 +1630,7 @@ A and r7, sp, #15 .endr add sp, sp, r7 - vpop {q4-q7} + vpop {q4-q6} pop {r4-r8,pc} endfunc @@ -1668,7 +1662,7 @@ function idct32x32_quarter_add_neon .endr add sp, sp, r7 - vpop {q4-q7} + vpop {q4-q6} pop {r4-r8,pc} endfunc @@ -1706,6 +1700,6 @@ function idct32x32_half_add_neon .endr add sp, sp, r7 - vpop {q4-q7} + vpop {q4-q6} pop {r4-r8,pc} endfunc From 65aa002d54433154a6924dc13e498bec98451ad0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 2 Jan 2017 22:08:41 +0200 Subject: [PATCH 0946/3374] aarch64: vp9itxfm: Avoid reloading the idct32 coefficients MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The idct32x32 function actually pushed d8-d15 onto the stack even though it didn't clobber them; there are plenty of registers that can be used to allow keeping all the idct coefficients in registers without having to reload different subsets of them at different stages in the transform. After this, we still can skip pushing d12-d15. Before: vp9_inv_dct_dct_32x32_sub32_add_neon: 8128.3 After: vp9_inv_dct_dct_32x32_sub32_add_neon: 8053.3 Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 110 +++++++++++------------------ 1 file changed, 43 insertions(+), 67 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index d35f103a79968..b6c2575236831 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -1123,18 +1123,14 @@ endfunc .endm function idct32_odd - ld1 {v0.8h,v1.8h}, [x11] - - dmbutterfly v16, v31, v0.h[0], v0.h[1], v4, v5, v6, v7 // v16 = t16a, v31 = t31a - dmbutterfly v24, v23, v0.h[2], v0.h[3], v4, v5, v6, v7 // v24 = t17a, v23 = t30a - dmbutterfly v20, v27, v0.h[4], v0.h[5], v4, v5, v6, v7 // v20 = t18a, v27 = t29a - dmbutterfly v28, v19, v0.h[6], v0.h[7], v4, v5, v6, v7 // v28 = t19a, v19 = t28a - dmbutterfly v18, v29, v1.h[0], v1.h[1], v4, v5, v6, v7 // v18 = t20a, v29 = t27a - dmbutterfly v26, v21, v1.h[2], v1.h[3], v4, v5, v6, v7 // v26 = t21a, v21 = t26a - dmbutterfly v22, v25, v1.h[4], v1.h[5], v4, v5, v6, v7 // v22 = t22a, v25 = t25a - dmbutterfly v30, v17, v1.h[6], v1.h[7], v4, v5, v6, v7 // v30 = t23a, v17 = t24a - - ld1 {v0.8h}, [x10] + dmbutterfly v16, v31, v8.h[0], v8.h[1], v4, v5, v6, v7 // v16 = t16a, v31 = t31a + dmbutterfly v24, v23, v8.h[2], v8.h[3], v4, v5, v6, v7 // v24 = t17a, v23 = t30a + dmbutterfly v20, v27, v8.h[4], v8.h[5], v4, v5, v6, v7 // v20 = t18a, v27 = t29a + dmbutterfly v28, v19, v8.h[6], v8.h[7], v4, v5, v6, v7 // v28 = t19a, v19 = t28a + dmbutterfly v18, v29, v9.h[0], v9.h[1], v4, v5, v6, v7 // v18 = t20a, v29 = t27a + dmbutterfly v26, v21, v9.h[2], v9.h[3], v4, v5, v6, v7 // v26 = t21a, v21 = t26a + dmbutterfly v22, v25, v9.h[4], v9.h[5], v4, v5, v6, v7 // v22 = t22a, v25 = t25a + dmbutterfly v30, v17, v9.h[6], v9.h[7], v4, v5, v6, v7 // v30 = t23a, v17 = t24a butterfly_8h v4, v24, v16, v24 // v4 = t16, v24 = t17 butterfly_8h v5, v20, v28, v20 // v5 = t19, v20 = t18 @@ -1153,18 +1149,14 @@ function idct32_odd endfunc function idct32_odd_half - ld1 {v0.8h,v1.8h}, [x11] - - dmbutterfly_h1 v16, v31, v0.h[0], v0.h[1], v4, v5, v6, v7 // v16 = t16a, v31 = t31a - dmbutterfly_h2 v24, v23, v0.h[2], v0.h[3], v4, v5, v6, v7 // v24 = t17a, v23 = t30a - dmbutterfly_h1 v20, v27, v0.h[4], v0.h[5], v4, v5, v6, v7 // v20 = t18a, v27 = t29a - dmbutterfly_h2 v28, v19, v0.h[6], v0.h[7], v4, v5, v6, v7 // v28 = t19a, v19 = t28a - dmbutterfly_h1 v18, v29, v1.h[0], v1.h[1], v4, v5, v6, v7 // v18 = t20a, v29 = t27a - dmbutterfly_h2 v26, v21, v1.h[2], v1.h[3], v4, v5, v6, v7 // v26 = t21a, v21 = t26a - dmbutterfly_h1 v22, v25, v1.h[4], v1.h[5], v4, v5, v6, v7 // v22 = t22a, v25 = t25a - dmbutterfly_h2 v30, v17, v1.h[6], v1.h[7], v4, v5, v6, v7 // v30 = t23a, v17 = t24a - - ld1 {v0.8h}, [x10] + dmbutterfly_h1 v16, v31, v8.h[0], v8.h[1], v4, v5, v6, v7 // v16 = t16a, v31 = t31a + dmbutterfly_h2 v24, v23, v8.h[2], v8.h[3], v4, v5, v6, v7 // v24 = t17a, v23 = t30a + dmbutterfly_h1 v20, v27, v8.h[4], v8.h[5], v4, v5, v6, v7 // v20 = t18a, v27 = t29a + dmbutterfly_h2 v28, v19, v8.h[6], v8.h[7], v4, v5, v6, v7 // v28 = t19a, v19 = t28a + dmbutterfly_h1 v18, v29, v9.h[0], v9.h[1], v4, v5, v6, v7 // v18 = t20a, v29 = t27a + dmbutterfly_h2 v26, v21, v9.h[2], v9.h[3], v4, v5, v6, v7 // v26 = t21a, v21 = t26a + dmbutterfly_h1 v22, v25, v9.h[4], v9.h[5], v4, v5, v6, v7 // v22 = t22a, v25 = t25a + dmbutterfly_h2 v30, v17, v9.h[6], v9.h[7], v4, v5, v6, v7 // v30 = t23a, v17 = t24a butterfly_8h v4, v24, v16, v24 // v4 = t16, v24 = t17 butterfly_8h v5, v20, v28, v20 // v5 = t19, v20 = t18 @@ -1183,18 +1175,14 @@ function idct32_odd_half endfunc function idct32_odd_quarter - ld1 {v0.8h,v1.8h}, [x11] - - dsmull_h v4, v5, v16, v0.h[0] - dsmull_h v28, v29, v19, v0.h[7] - dsmull_h v30, v31, v16, v0.h[1] - dsmull_h v22, v23, v17, v1.h[6] - dsmull_h v7, v6, v17, v1.h[7] - dsmull_h v26, v27, v19, v0.h[6] - dsmull_h v20, v21, v18, v1.h[0] - dsmull_h v24, v25, v18, v1.h[1] - - ld1 {v0.8h}, [x10] + dsmull_h v4, v5, v16, v8.h[0] + dsmull_h v28, v29, v19, v8.h[7] + dsmull_h v30, v31, v16, v8.h[1] + dsmull_h v22, v23, v17, v9.h[6] + dsmull_h v7, v6, v17, v9.h[7] + dsmull_h v26, v27, v19, v8.h[6] + dsmull_h v20, v21, v18, v9.h[0] + dsmull_h v24, v25, v18, v9.h[1] neg v28.4s, v28.4s neg v29.4s, v29.4s @@ -1240,12 +1228,8 @@ endfunc // x1 = unused // x2 = src // x9 = double input stride -// x10 = idct_coeffs -// x11 = idct_coeffs + 32 function idct32_1d_8x32_pass1\suffix\()_neon mov x14, x30 - ld1 {v0.8h,v1.8h}, [x10] - movi v2.8h, #0 // v16 = IN(0), v17 = IN(2) ... v31 = IN(30) @@ -1278,14 +1262,14 @@ function idct32_1d_8x32_pass1\suffix\()_neon .macro store_rev a, b // There's no rev128 instruction, but we reverse each 64 bit // half, and then flip them using an ext with 8 bytes offset. - rev64 v1.8h, \b + rev64 v3.8h, \b st1 {\a}, [x0], #16 - rev64 v0.8h, \a - ext v1.16b, v1.16b, v1.16b, #8 + rev64 v2.8h, \a + ext v3.16b, v3.16b, v3.16b, #8 st1 {\b}, [x0], #16 - ext v0.16b, v0.16b, v0.16b, #8 - st1 {v1.8h}, [x0], #16 - st1 {v0.8h}, [x0], #16 + ext v2.16b, v2.16b, v2.16b, #8 + st1 {v3.8h}, [x0], #16 + st1 {v2.8h}, [x0], #16 .endm store_rev v16.8h, v24.8h store_rev v17.8h, v25.8h @@ -1339,20 +1323,20 @@ function idct32_1d_8x32_pass1\suffix\()_neon // subtracted from the output. .macro store_rev a, b ld1 {v4.8h}, [x0] - rev64 v1.8h, \b + rev64 v3.8h, \b add v4.8h, v4.8h, \a - rev64 v0.8h, \a + rev64 v2.8h, \a st1 {v4.8h}, [x0], #16 - ext v1.16b, v1.16b, v1.16b, #8 + ext v3.16b, v3.16b, v3.16b, #8 ld1 {v5.8h}, [x0] - ext v0.16b, v0.16b, v0.16b, #8 + ext v2.16b, v2.16b, v2.16b, #8 add v5.8h, v5.8h, \b st1 {v5.8h}, [x0], #16 ld1 {v6.8h}, [x0] - sub v6.8h, v6.8h, v1.8h + sub v6.8h, v6.8h, v3.8h st1 {v6.8h}, [x0], #16 ld1 {v7.8h}, [x0] - sub v7.8h, v7.8h, v0.8h + sub v7.8h, v7.8h, v2.8h st1 {v7.8h}, [x0], #16 .endm @@ -1376,12 +1360,8 @@ endfunc // x2 = src (temp buffer) // x7 = negative double temp buffer stride // x9 = double temp buffer stride -// x10 = idct_coeffs -// x11 = idct_coeffs + 32 function idct32_1d_8x32_pass2\suffix\()_neon mov x14, x30 - ld1 {v0.8h,v1.8h}, [x10] - // v16 = IN(0), v17 = IN(2) ... v31 = IN(30) .ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 @@ -1454,15 +1434,15 @@ function idct32_1d_8x32_pass2\suffix\()_neon sub v6.8h, v6.8h, \c sub v7.8h, v7.8h, \d .endif - ld1 {v0.8b}, [x0], x1 - ld1 {v1.8b}, [x0], x1 + ld1 {v10.8b}, [x0], x1 + ld1 {v11.8b}, [x0], x1 srshr v4.8h, v4.8h, #6 ld1 {v2.8b}, [x0], x1 srshr v5.8h, v5.8h, #6 - uaddw v4.8h, v4.8h, v0.8b + uaddw v4.8h, v4.8h, v10.8b ld1 {v3.8b}, [x0], x1 srshr v6.8h, v6.8h, #6 - uaddw v5.8h, v5.8h, v1.8b + uaddw v5.8h, v5.8h, v11.8b srshr v7.8h, v7.8h, #6 sub x0, x0, x1, lsl #2 uaddw v6.8h, v6.8h, v2.8b @@ -1503,13 +1483,10 @@ function ff_vp9_idct_idct_32x32_add_neon, export=1 b.eq idct32x32_dc_add_neon movrel x10, idct_coeffs - add x11, x10, #32 movrel x12, min_eob_idct_idct_32, 2 mov x15, x30 - stp d14, d15, [sp, #-0x10]! - stp d12, d13, [sp, #-0x10]! stp d10, d11, [sp, #-0x10]! stp d8, d9, [sp, #-0x10]! @@ -1523,6 +1500,9 @@ function ff_vp9_idct_idct_32x32_add_neon, export=1 mov x9, #128 neg x7, x9 + ld1 {v0.8h,v1.8h}, [x10], #32 + ld1 {v8.8h,v9.8h}, [x10] + cmp w3, #34 b.le idct32x32_quarter_add_neon cmp w3, #135 @@ -1565,8 +1545,6 @@ function ff_vp9_idct_idct_32x32_add_neon, export=1 ldp d8, d9, [sp], 0x10 ldp d10, d11, [sp], 0x10 - ldp d12, d13, [sp], 0x10 - ldp d14, d15, [sp], 0x10 br x15 endfunc @@ -1592,8 +1570,6 @@ function idct32x32_\size\()_add_neon ldp d8, d9, [sp], 0x10 ldp d10, d11, [sp], 0x10 - ldp d12, d13, [sp], 0x10 - ldp d14, d15, [sp], 0x10 br x15 endfunc From de06bdfe6c8abd8266d5c6f5c68e4df0060b61fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 31 Dec 2016 14:05:44 +0200 Subject: [PATCH 0947/3374] arm: vp9itxfm: Reorder the idct coefficients for better pairing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All elements are used pairwise, except for the first one. Previously, the 16th element was unused. Move the unused element to the second slot, to make the later element pairs not split across registers. This simplifies loading only parts of the coefficients, reducing the difference to the 16 bpp version. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 124 ++++++++++++++++----------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index bed502eba2007..1d4d6a79101b8 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -22,7 +22,7 @@ #include "neon.S" const itxfm4_coeffs, align=4 - .short 11585, 6270, 15137, 0 + .short 11585, 0, 6270, 15137 iadst4_coeffs: .short 5283, 15212, 9929, 13377 endconst @@ -30,8 +30,8 @@ endconst const iadst8_coeffs, align=4 .short 16305, 1606, 14449, 7723, 10394, 12665, 4756, 15679 idct_coeffs: - .short 11585, 6270, 15137, 3196, 16069, 13623, 9102, 1606 - .short 16305, 12665, 10394, 7723, 14449, 15679, 4756, 0 + .short 11585, 0, 6270, 15137, 3196, 16069, 13623, 9102 + .short 1606, 16305, 12665, 10394, 7723, 14449, 15679, 4756 .short 804, 16364, 12140, 11003, 7005, 14811, 15426, 5520 .short 3981, 15893, 14053, 8423, 9760, 13160, 16207, 2404 endconst @@ -224,14 +224,14 @@ endconst .endm .macro idct4 c0, c1, c2, c3 - vmull.s16 q13, \c1, d0[2] - vmull.s16 q11, \c1, d0[1] + vmull.s16 q13, \c1, d0[3] + vmull.s16 q11, \c1, d0[2] vadd.i16 d16, \c0, \c2 vsub.i16 d17, \c0, \c2 - vmlal.s16 q13, \c3, d0[1] + vmlal.s16 q13, \c3, d0[2] vmull.s16 q9, d16, d0[0] vmull.s16 q10, d17, d0[0] - vmlsl.s16 q11, \c3, d0[2] + vmlsl.s16 q11, \c3, d0[3] vrshrn.s32 d26, q13, #14 vrshrn.s32 d18, q9, #14 vrshrn.s32 d20, q10, #14 @@ -350,9 +350,9 @@ itxfm_func4x4 iwht, iwht .macro idct8 dmbutterfly0 d16, d17, d24, d25, q8, q12, q2, q4, d4, d5, d8, d9, q3, q2, q5, q4 @ q8 = t0a, q12 = t1a - dmbutterfly d20, d21, d28, d29, d0[1], d0[2], q2, q3, q4, q5 @ q10 = t2a, q14 = t3a - dmbutterfly d18, d19, d30, d31, d0[3], d1[0], q2, q3, q4, q5 @ q9 = t4a, q15 = t7a - dmbutterfly d26, d27, d22, d23, d1[1], d1[2], q2, q3, q4, q5 @ q13 = t5a, q11 = t6a + dmbutterfly d20, d21, d28, d29, d0[2], d0[3], q2, q3, q4, q5 @ q10 = t2a, q14 = t3a + dmbutterfly d18, d19, d30, d31, d1[0], d1[1], q2, q3, q4, q5 @ q9 = t4a, q15 = t7a + dmbutterfly d26, d27, d22, d23, d1[2], d1[3], q2, q3, q4, q5 @ q13 = t5a, q11 = t6a butterfly q2, q14, q8, q14 @ q2 = t0, q14 = t3 butterfly q3, q10, q12, q10 @ q3 = t1, q10 = t2 @@ -386,8 +386,8 @@ itxfm_func4x4 iwht, iwht vneg.s16 q15, q15 @ q15 = out[7] butterfly q8, q9, q11, q9 @ q8 = out[0], q9 = t2 - dmbutterfly_l q10, q11, q5, q7, d4, d5, d6, d7, d0[1], d0[2] @ q10,q11 = t5a, q5,q7 = t4a - dmbutterfly_l q2, q3, q13, q14, d12, d13, d8, d9, d0[2], d0[1] @ q2,q3 = t6a, q13,q14 = t7a + dmbutterfly_l q10, q11, q5, q7, d4, d5, d6, d7, d0[2], d0[3] @ q10,q11 = t5a, q5,q7 = t4a + dmbutterfly_l q2, q3, q13, q14, d12, d13, d8, d9, d0[3], d0[2] @ q2,q3 = t6a, q13,q14 = t7a dbutterfly_n d28, d29, d8, d9, q10, q11, q13, q14, q4, q6, q10, q11 @ q14 = out[6], q4 = t7 @@ -594,13 +594,13 @@ endfunc function idct16 mbutterfly0 d16, d24, d16, d24, d4, d6, q2, q3 @ d16 = t0a, d24 = t1a - mbutterfly d20, d28, d0[1], d0[2], q2, q3 @ d20 = t2a, d28 = t3a - mbutterfly d18, d30, d0[3], d1[0], q2, q3 @ d18 = t4a, d30 = t7a - mbutterfly d26, d22, d1[1], d1[2], q2, q3 @ d26 = t5a, d22 = t6a - mbutterfly d17, d31, d1[3], d2[0], q2, q3 @ d17 = t8a, d31 = t15a - mbutterfly d25, d23, d2[1], d2[2], q2, q3 @ d25 = t9a, d23 = t14a - mbutterfly d21, d27, d2[3], d3[0], q2, q3 @ d21 = t10a, d27 = t13a - mbutterfly d29, d19, d3[1], d3[2], q2, q3 @ d29 = t11a, d19 = t12a + mbutterfly d20, d28, d0[2], d0[3], q2, q3 @ d20 = t2a, d28 = t3a + mbutterfly d18, d30, d1[0], d1[1], q2, q3 @ d18 = t4a, d30 = t7a + mbutterfly d26, d22, d1[2], d1[3], q2, q3 @ d26 = t5a, d22 = t6a + mbutterfly d17, d31, d2[0], d2[1], q2, q3 @ d17 = t8a, d31 = t15a + mbutterfly d25, d23, d2[2], d2[3], q2, q3 @ d25 = t9a, d23 = t14a + mbutterfly d21, d27, d3[0], d3[1], q2, q3 @ d21 = t10a, d27 = t13a + mbutterfly d29, d19, d3[2], d3[3], q2, q3 @ d29 = t11a, d19 = t12a butterfly d4, d28, d16, d28 @ d4 = t0, d28 = t3 butterfly d5, d20, d24, d20 @ d5 = t1, d20 = t2 @@ -612,20 +612,20 @@ function idct16 butterfly d29, d23, d31, d23 @ d29 = t15, d23 = t14 mbutterfly0 d22, d26, d22, d26, d18, d30, q9, q15 @ d22 = t6a, d26 = t5a - mbutterfly d23, d25, d0[1], d0[2], q9, q15 @ d23 = t9a, d25 = t14a - mbutterfly d27, d21, d0[1], d0[2], q9, q15, neg=1 @ d27 = t13a, d21 = t10a + mbutterfly d23, d25, d0[2], d0[3], q9, q15 @ d23 = t9a, d25 = t14a + mbutterfly d27, d21, d0[2], d0[3], q9, q15, neg=1 @ d27 = t13a, d21 = t10a idct16_end endfunc function idct16_half mbutterfly0_h d16, d24, d16, d24, d4, d6, q2, q3 @ d16 = t0a, d24 = t1a - mbutterfly_h1 d20, d28, d0[1], d0[2], q2, q3 @ d20 = t2a, d28 = t3a - mbutterfly_h1 d18, d30, d0[3], d1[0], q2, q3 @ d18 = t4a, d30 = t7a - mbutterfly_h2 d26, d22, d1[1], d1[2], q2, q3 @ d26 = t5a, d22 = t6a - mbutterfly_h1 d17, d31, d1[3], d2[0], q2, q3 @ d17 = t8a, d31 = t15a - mbutterfly_h2 d25, d23, d2[1], d2[2], q2, q3 @ d25 = t9a, d23 = t14a - mbutterfly_h1 d21, d27, d2[3], d3[0], q2, q3 @ d21 = t10a, d27 = t13a - mbutterfly_h2 d29, d19, d3[1], d3[2], q2, q3 @ d29 = t11a, d19 = t12a + mbutterfly_h1 d20, d28, d0[2], d0[3], q2, q3 @ d20 = t2a, d28 = t3a + mbutterfly_h1 d18, d30, d1[0], d1[1], q2, q3 @ d18 = t4a, d30 = t7a + mbutterfly_h2 d26, d22, d1[2], d1[3], q2, q3 @ d26 = t5a, d22 = t6a + mbutterfly_h1 d17, d31, d2[0], d2[1], q2, q3 @ d17 = t8a, d31 = t15a + mbutterfly_h2 d25, d23, d2[2], d2[3], q2, q3 @ d25 = t9a, d23 = t14a + mbutterfly_h1 d21, d27, d3[0], d3[1], q2, q3 @ d21 = t10a, d27 = t13a + mbutterfly_h2 d29, d19, d3[2], d3[3], q2, q3 @ d29 = t11a, d19 = t12a butterfly d4, d28, d16, d28 @ d4 = t0, d28 = t3 butterfly d5, d20, d24, d20 @ d5 = t1, d20 = t2 @@ -637,19 +637,19 @@ function idct16_half butterfly d29, d23, d31, d23 @ d29 = t15, d23 = t14 mbutterfly0 d22, d26, d22, d26, d18, d30, q9, q15 @ d22 = t6a, d26 = t5a - mbutterfly d23, d25, d0[1], d0[2], q9, q15 @ d23 = t9a, d25 = t14a - mbutterfly d27, d21, d0[1], d0[2], q9, q15, neg=1 @ d27 = t13a, d21 = t10a + mbutterfly d23, d25, d0[2], d0[3], q9, q15 @ d23 = t9a, d25 = t14a + mbutterfly d27, d21, d0[2], d0[3], q9, q15, neg=1 @ d27 = t13a, d21 = t10a idct16_end endfunc function idct16_quarter - vmull.s16 q12, d19, d3[2] - vmull.s16 q2, d17, d1[3] - vmull.s16 q3, d18, d1[0] - vmull.s16 q15, d18, d0[3] + vmull.s16 q12, d19, d3[3] + vmull.s16 q2, d17, d2[0] + vmull.s16 q3, d18, d1[1] + vmull.s16 q15, d18, d1[0] vneg.s32 q12, q12 - vmull.s16 q14, d17, d2[0] - vmull.s16 q13, d19, d3[1] + vmull.s16 q14, d17, d2[1] + vmull.s16 q13, d19, d3[2] vmull.s16 q11, d16, d0[0] vrshrn.s32 d24, q12, #14 vrshrn.s32 d16, q2, #14 @@ -659,8 +659,8 @@ function idct16_quarter vrshrn.s32 d17, q13, #14 vrshrn.s32 d28, q11, #14 - mbutterfly_l q10, q11, d17, d24, d0[1], d0[2] - mbutterfly_l q9, q15, d29, d16, d0[1], d0[2] + mbutterfly_l q10, q11, d17, d24, d0[2], d0[3] + mbutterfly_l q9, q15, d29, d16, d0[2], d0[3] vneg.s32 q11, q11 vrshrn.s32 d27, q10, #14 vrshrn.s32 d21, q11, #14 @@ -697,16 +697,16 @@ function iadst16 movrel r12, idct_coeffs vld1.16 {q0}, [r12,:128] butterfly_n d22, d30, q3, q5, q6, q5 @ d22 = t7a, d30 = t15a - mbutterfly_l q7, q6, d23, d24, d0[3], d1[0] @ q7 = t9, q6 = t8 + mbutterfly_l q7, q6, d23, d24, d1[0], d1[1] @ q7 = t9, q6 = t8 butterfly_n d25, d17, q2, q4, q3, q4 @ d25 = t6a, d17 = t14a - mbutterfly_l q2, q3, d28, d19, d1[0], d0[3] @ q2 = t12, q3 = t13 + mbutterfly_l q2, q3, d28, d19, d1[1], d1[0] @ q2 = t12, q3 = t13 butterfly_n d23, d19, q6, q2, q4, q2 @ d23 = t8a, d19 = t12a - mbutterfly_l q5, q4, d21, d26, d1[1], d1[2] @ q5 = t11, q4 = t10 + mbutterfly_l q5, q4, d21, d26, d1[2], d1[3] @ q5 = t11, q4 = t10 butterfly_r d4, d27, d16, d27 @ d4 = t4, d27 = t0 butterfly_n d24, d28, q7, q3, q6, q3 @ d24 = t9a, d28 = t13a - mbutterfly_l q6, q7, d30, d17, d1[2], d1[1] @ q6 = t14, q7 = t15 + mbutterfly_l q6, q7, d30, d17, d1[3], d1[2] @ q6 = t14, q7 = t15 butterfly_r d5, d20, d31, d20 @ d5 = t5, d20 = t1 butterfly_n d21, d17, q4, q6, q3, q6 @ d21 = t10a, d17 = t14a butterfly_n d26, d30, q5, q7, q4, q7 @ d26 = t11a, d30 = t15a @@ -714,15 +714,15 @@ function iadst16 butterfly_r d6, d25, d18, d25 @ d6 = t6, d25 = t2 butterfly_r d7, d22, d29, d22 @ d7 = t7, d22 = t3 - mbutterfly_l q5, q4, d19, d28, d0[1], d0[2] @ q5 = t13, q4 = t12 - mbutterfly_l q6, q7, d30, d17, d0[2], d0[1] @ q6 = t14, q7 = t15 + mbutterfly_l q5, q4, d19, d28, d0[2], d0[3] @ q5 = t13, q4 = t12 + mbutterfly_l q6, q7, d30, d17, d0[3], d0[2] @ q6 = t14, q7 = t15 butterfly_n d18, d30, q4, q6, q8, q6 @ d18 = out[2], d30 = t14a butterfly_n d29, d17, q5, q7, q6, q7 @ d29 = -out[13], d17 = t15a vneg.s16 d29, d29 @ d29 = out[13] - mbutterfly_l q5, q4, d4, d5, d0[1], d0[2] @ q5 = t5a, q4 = t4a - mbutterfly_l q6, q7, d7, d6, d0[2], d0[1] @ q6 = t6a, q7 = t7a + mbutterfly_l q5, q4, d4, d5, d0[2], d0[3] @ q5 = t5a, q4 = t4a + mbutterfly_l q6, q7, d7, d6, d0[3], d0[2] @ q6 = t6a, q7 = t7a butterfly d2, d6, d27, d25 @ d2 = out[0], d6 = t2a butterfly d3, d7, d23, d21 @ d3 =-out[1], d7 = t10 @@ -1194,10 +1194,10 @@ endfunc butterfly d11, d29, d29, d31 @ d11 = t31a, d29 = t28a butterfly d22, d27, d24, d27 @ d22 = t30, d27 = t29 - mbutterfly d27, d20, d0[1], d0[2], q12, q15 @ d27 = t18a, d20 = t29a - mbutterfly d29, d9, d0[1], d0[2], q12, q15 @ d29 = t19, d9 = t28 - mbutterfly d28, d10, d0[1], d0[2], q12, q15, neg=1 @ d28 = t27, d10 = t20 - mbutterfly d26, d21, d0[1], d0[2], q12, q15, neg=1 @ d26 = t26a, d21 = t21a + mbutterfly d27, d20, d0[2], d0[3], q12, q15 @ d27 = t18a, d20 = t29a + mbutterfly d29, d9, d0[2], d0[3], q12, q15 @ d29 = t19, d5 = t28 + mbutterfly d28, d10, d0[2], d0[3], q12, q15, neg=1 @ d28 = t27, d6 = t20 + mbutterfly d26, d21, d0[2], d0[3], q12, q15, neg=1 @ d26 = t26a, d21 = t21a butterfly d31, d24, d11, d8 @ d31 = t31, d24 = t24 butterfly d30, d25, d22, d23 @ d30 = t30a, d25 = t25a @@ -1235,10 +1235,10 @@ function idct32_odd butterfly d29, d23, d31, d23 @ d29 = t31, d23 = t30 butterfly d31, d27, d19, d27 @ d31 = t28, d27 = t29 - mbutterfly d23, d24, d0[3], d1[0], q8, q9 @ d23 = t17a, d24 = t30a - mbutterfly d27, d20, d0[3], d1[0], q8, q9, neg=1 @ d27 = t29a, d20 = t18a - mbutterfly d21, d26, d1[1], d1[2], q8, q9 @ d21 = t21a, d26 = t26a - mbutterfly d25, d22, d1[1], d1[2], q8, q9, neg=1 @ d25 = t25a, d22 = t22a + mbutterfly d23, d24, d1[0], d1[1], q8, q9 @ d23 = t17a, d24 = t30a + mbutterfly d27, d20, d1[0], d1[1], q8, q9, neg=1 @ d27 = t29a, d20 = t18a + mbutterfly d21, d26, d1[2], d1[3], q8, q9 @ d21 = t21a, d26 = t26a + mbutterfly d25, d22, d1[2], d1[3], q8, q9, neg=1 @ d25 = t25a, d22 = t22a idct32_end endfunc @@ -1261,10 +1261,10 @@ function idct32_odd_half butterfly d29, d23, d31, d23 @ d29 = t31, d23 = t30 butterfly d31, d27, d19, d27 @ d31 = t28, d27 = t29 - mbutterfly d23, d24, d0[3], d1[0], q8, q9 @ d23 = t17a, d24 = t30a - mbutterfly d27, d20, d0[3], d1[0], q8, q9, neg=1 @ d27 = t29a, d20 = t18a - mbutterfly d21, d26, d1[1], d1[2], q8, q9 @ d21 = t21a, d26 = t26a - mbutterfly d25, d22, d1[1], d1[2], q8, q9, neg=1 @ d25 = t25a, d22 = t22a + mbutterfly d23, d24, d1[0], d1[1], q8, q9 @ d23 = t17a, d24 = t30a + mbutterfly d27, d20, d1[0], d1[1], q8, q9, neg=1 @ d27 = t29a, d20 = t18a + mbutterfly d21, d26, d1[2], d1[3], q8, q9 @ d21 = t21a, d26 = t26a + mbutterfly d25, d22, d1[2], d1[3], q8, q9, neg=1 @ d25 = t25a, d22 = t22a idct32_end endfunc @@ -1291,17 +1291,17 @@ function idct32_odd_quarter vrshrn.s32 d10, q10, #14 vrshrn.s32 d30, q12, #14 - mbutterfly_l q8, q9, d29, d8, d0[3], d1[0] - mbutterfly_l q13, q10, d31, d9, d0[3], d1[0] + mbutterfly_l q8, q9, d29, d8, d1[0], d1[1] + mbutterfly_l q13, q10, d31, d9, d1[0], d1[1] vrshrn.s32 d23, q8, #14 vrshrn.s32 d24, q9, #14 vneg.s32 q10, q10 vrshrn.s32 d27, q13, #14 vrshrn.s32 d20, q10, #14 - mbutterfly_l q8, q9, d30, d10, d1[1], d1[2] + mbutterfly_l q8, q9, d30, d10, d1[2], d1[3] vrshrn.s32 d21, q8, #14 vrshrn.s32 d26, q9, #14 - mbutterfly_l q8, q9, d28, d11, d1[1], d1[2] + mbutterfly_l q8, q9, d28, d11, d1[2], d1[3] vrshrn.s32 d25, q8, #14 vneg.s32 q9, q9 vrshrn.s32 d22, q9, #14 From 09eb88a12e008d10a3f7a6be75d18ad98b368e68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 31 Dec 2016 14:18:31 +0200 Subject: [PATCH 0948/3374] aarch64: vp9itxfm: Reorder the idct coefficients for better pairing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All elements are used pairwise, except for the first one. Previously, the 16th element was unused. Move the unused element to the second slot, to make the later element pairs not split across registers. This simplifies loading only parts of the coefficients, reducing the difference to the 16 bpp version. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 124 ++++++++++++++--------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index b6c2575236831..d4fc2163aa30b 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -22,7 +22,7 @@ #include "neon.S" const itxfm4_coeffs, align=4 - .short 11585, 6270, 15137, 0 + .short 11585, 0, 6270, 15137 iadst4_coeffs: .short 5283, 15212, 9929, 13377 endconst @@ -30,8 +30,8 @@ endconst const iadst8_coeffs, align=4 .short 16305, 1606, 14449, 7723, 10394, 12665, 4756, 15679 idct_coeffs: - .short 11585, 6270, 15137, 3196, 16069, 13623, 9102, 1606 - .short 16305, 12665, 10394, 7723, 14449, 15679, 4756, 0 + .short 11585, 0, 6270, 15137, 3196, 16069, 13623, 9102 + .short 1606, 16305, 12665, 10394, 7723, 14449, 15679, 4756 .short 804, 16364, 12140, 11003, 7005, 14811, 15426, 5520 .short 3981, 15893, 14053, 8423, 9760, 13160, 16207, 2404 endconst @@ -192,14 +192,14 @@ endconst .endm .macro idct4 c0, c1, c2, c3 - smull v22.4s, \c1\().4h, v0.h[2] - smull v20.4s, \c1\().4h, v0.h[1] + smull v22.4s, \c1\().4h, v0.h[3] + smull v20.4s, \c1\().4h, v0.h[2] add v16.4h, \c0\().4h, \c2\().4h sub v17.4h, \c0\().4h, \c2\().4h - smlal v22.4s, \c3\().4h, v0.h[1] + smlal v22.4s, \c3\().4h, v0.h[2] smull v18.4s, v16.4h, v0.h[0] smull v19.4s, v17.4h, v0.h[0] - smlsl v20.4s, \c3\().4h, v0.h[2] + smlsl v20.4s, \c3\().4h, v0.h[3] rshrn v22.4h, v22.4s, #14 rshrn v18.4h, v18.4s, #14 rshrn v19.4h, v19.4s, #14 @@ -326,9 +326,9 @@ itxfm_func4x4 iwht, iwht .macro idct8 dmbutterfly0 v16, v20, v16, v20, v2, v3, v4, v5, v6, v7 // v16 = t0a, v20 = t1a - dmbutterfly v18, v22, v0.h[1], v0.h[2], v2, v3, v4, v5 // v18 = t2a, v22 = t3a - dmbutterfly v17, v23, v0.h[3], v0.h[4], v2, v3, v4, v5 // v17 = t4a, v23 = t7a - dmbutterfly v21, v19, v0.h[5], v0.h[6], v2, v3, v4, v5 // v21 = t5a, v19 = t6a + dmbutterfly v18, v22, v0.h[2], v0.h[3], v2, v3, v4, v5 // v18 = t2a, v22 = t3a + dmbutterfly v17, v23, v0.h[4], v0.h[5], v2, v3, v4, v5 // v17 = t4a, v23 = t7a + dmbutterfly v21, v19, v0.h[6], v0.h[7], v2, v3, v4, v5 // v21 = t5a, v19 = t6a butterfly_8h v24, v25, v16, v22 // v24 = t0, v25 = t3 butterfly_8h v28, v29, v17, v21 // v28 = t4, v29 = t5a @@ -361,8 +361,8 @@ itxfm_func4x4 iwht, iwht dmbutterfly0 v19, v20, v6, v7, v24, v26, v27, v28, v29, v30 // v19 = -out[3], v20 = out[4] neg v19.8h, v19.8h // v19 = out[3] - dmbutterfly_l v26, v27, v28, v29, v5, v3, v0.h[1], v0.h[2] // v26,v27 = t5a, v28,v29 = t4a - dmbutterfly_l v2, v3, v4, v5, v31, v25, v0.h[2], v0.h[1] // v2,v3 = t6a, v4,v5 = t7a + dmbutterfly_l v26, v27, v28, v29, v5, v3, v0.h[2], v0.h[3] // v26,v27 = t5a, v28,v29 = t4a + dmbutterfly_l v2, v3, v4, v5, v31, v25, v0.h[3], v0.h[2] // v2,v3 = t6a, v4,v5 = t7a dbutterfly_n v17, v30, v28, v29, v2, v3, v6, v7, v24, v25 // v17 = -out[1], v30 = t6 dbutterfly_n v22, v31, v26, v27, v4, v5, v6, v7, v24, v25 // v22 = out[6], v31 = t7 @@ -543,13 +543,13 @@ endfunc function idct16 dmbutterfly0 v16, v24, v16, v24, v2, v3, v4, v5, v6, v7 // v16 = t0a, v24 = t1a - dmbutterfly v20, v28, v0.h[1], v0.h[2], v2, v3, v4, v5 // v20 = t2a, v28 = t3a - dmbutterfly v18, v30, v0.h[3], v0.h[4], v2, v3, v4, v5 // v18 = t4a, v30 = t7a - dmbutterfly v26, v22, v0.h[5], v0.h[6], v2, v3, v4, v5 // v26 = t5a, v22 = t6a - dmbutterfly v17, v31, v0.h[7], v1.h[0], v2, v3, v4, v5 // v17 = t8a, v31 = t15a - dmbutterfly v25, v23, v1.h[1], v1.h[2], v2, v3, v4, v5 // v25 = t9a, v23 = t14a - dmbutterfly v21, v27, v1.h[3], v1.h[4], v2, v3, v4, v5 // v21 = t10a, v27 = t13a - dmbutterfly v29, v19, v1.h[5], v1.h[6], v2, v3, v4, v5 // v29 = t11a, v19 = t12a + dmbutterfly v20, v28, v0.h[2], v0.h[3], v2, v3, v4, v5 // v20 = t2a, v28 = t3a + dmbutterfly v18, v30, v0.h[4], v0.h[5], v2, v3, v4, v5 // v18 = t4a, v30 = t7a + dmbutterfly v26, v22, v0.h[6], v0.h[7], v2, v3, v4, v5 // v26 = t5a, v22 = t6a + dmbutterfly v17, v31, v1.h[0], v1.h[1], v2, v3, v4, v5 // v17 = t8a, v31 = t15a + dmbutterfly v25, v23, v1.h[2], v1.h[3], v2, v3, v4, v5 // v25 = t9a, v23 = t14a + dmbutterfly v21, v27, v1.h[4], v1.h[5], v2, v3, v4, v5 // v21 = t10a, v27 = t13a + dmbutterfly v29, v19, v1.h[6], v1.h[7], v2, v3, v4, v5 // v29 = t11a, v19 = t12a butterfly_8h v4, v28, v16, v28 // v4 = t0, v28 = t3 butterfly_8h v5, v20, v24, v20 // v5 = t1, v20 = t2 @@ -561,20 +561,20 @@ function idct16 butterfly_8h v29, v23, v31, v23 // v29 = t15, v23 = t14 dmbutterfly0 v22, v26, v22, v26, v2, v3, v18, v19, v30, v31 // v22 = t6a, v26 = t5a - dmbutterfly v23, v25, v0.h[1], v0.h[2], v18, v19, v30, v31 // v23 = t9a, v25 = t14a - dmbutterfly v27, v21, v0.h[1], v0.h[2], v18, v19, v30, v31, neg=1 // v27 = t13a, v21 = t10a + dmbutterfly v23, v25, v0.h[2], v0.h[3], v18, v19, v30, v31 // v23 = t9a, v25 = t14a + dmbutterfly v27, v21, v0.h[2], v0.h[3], v18, v19, v30, v31, neg=1 // v27 = t13a, v21 = t10a idct16_end endfunc function idct16_half dmbutterfly0_h v16, v24, v16, v24, v2, v3, v4, v5, v6, v7 // v16 = t0a, v24 = t1a - dmbutterfly_h1 v20, v28, v0.h[1], v0.h[2], v2, v3, v4, v5 // v20 = t2a, v28 = t3a - dmbutterfly_h1 v18, v30, v0.h[3], v0.h[4], v2, v3, v4, v5 // v18 = t4a, v30 = t7a - dmbutterfly_h2 v26, v22, v0.h[5], v0.h[6], v2, v3, v4, v5 // v26 = t5a, v22 = t6a - dmbutterfly_h1 v17, v31, v0.h[7], v1.h[0], v2, v3, v4, v5 // v17 = t8a, v31 = t15a - dmbutterfly_h2 v25, v23, v1.h[1], v1.h[2], v2, v3, v4, v5 // v25 = t9a, v23 = t14a - dmbutterfly_h1 v21, v27, v1.h[3], v1.h[4], v2, v3, v4, v5 // v21 = t10a, v27 = t13a - dmbutterfly_h2 v29, v19, v1.h[5], v1.h[6], v2, v3, v4, v5 // v29 = t11a, v19 = t12a + dmbutterfly_h1 v20, v28, v0.h[2], v0.h[3], v2, v3, v4, v5 // v20 = t2a, v28 = t3a + dmbutterfly_h1 v18, v30, v0.h[4], v0.h[5], v2, v3, v4, v5 // v18 = t4a, v30 = t7a + dmbutterfly_h2 v26, v22, v0.h[6], v0.h[7], v2, v3, v4, v5 // v26 = t5a, v22 = t6a + dmbutterfly_h1 v17, v31, v1.h[0], v1.h[1], v2, v3, v4, v5 // v17 = t8a, v31 = t15a + dmbutterfly_h2 v25, v23, v1.h[2], v1.h[3], v2, v3, v4, v5 // v25 = t9a, v23 = t14a + dmbutterfly_h1 v21, v27, v1.h[4], v1.h[5], v2, v3, v4, v5 // v21 = t10a, v27 = t13a + dmbutterfly_h2 v29, v19, v1.h[6], v1.h[7], v2, v3, v4, v5 // v29 = t11a, v19 = t12a butterfly_8h v4, v28, v16, v28 // v4 = t0, v28 = t3 butterfly_8h v5, v20, v24, v20 // v5 = t1, v20 = t2 @@ -586,20 +586,20 @@ function idct16_half butterfly_8h v29, v23, v31, v23 // v29 = t15, v23 = t14 dmbutterfly0 v22, v26, v22, v26, v2, v3, v18, v19, v30, v31 // v22 = t6a, v26 = t5a - dmbutterfly v23, v25, v0.h[1], v0.h[2], v18, v19, v30, v31 // v23 = t9a, v25 = t14a - dmbutterfly v27, v21, v0.h[1], v0.h[2], v18, v19, v30, v31, neg=1 // v27 = t13a, v21 = t10a + dmbutterfly v23, v25, v0.h[2], v0.h[3], v18, v19, v30, v31 // v23 = t9a, v25 = t14a + dmbutterfly v27, v21, v0.h[2], v0.h[3], v18, v19, v30, v31, neg=1 // v27 = t13a, v21 = t10a idct16_end endfunc function idct16_quarter - dsmull_h v24, v25, v19, v1.h[6] - dsmull_h v4, v5, v17, v0.h[7] - dsmull_h v7, v6, v18, v0.h[4] - dsmull_h v30, v31, v18, v0.h[3] + dsmull_h v24, v25, v19, v1.h[7] + dsmull_h v4, v5, v17, v1.h[0] + dsmull_h v7, v6, v18, v0.h[5] + dsmull_h v30, v31, v18, v0.h[4] neg v24.4s, v24.4s neg v25.4s, v25.4s - dsmull_h v29, v28, v17, v1.h[0] - dsmull_h v26, v27, v19, v1.h[5] + dsmull_h v29, v28, v17, v1.h[1] + dsmull_h v26, v27, v19, v1.h[6] dsmull_h v22, v23, v16, v0.h[0] drshrn_h v24, v24, v25, #14 drshrn_h v16, v4, v5, #14 @@ -609,8 +609,8 @@ function idct16_quarter drshrn_h v17, v26, v27, #14 drshrn_h v28, v22, v23, #14 - dmbutterfly_l v20, v21, v22, v23, v17, v24, v0.h[1], v0.h[2] - dmbutterfly_l v18, v19, v30, v31, v29, v16, v0.h[1], v0.h[2] + dmbutterfly_l v20, v21, v22, v23, v17, v24, v0.h[2], v0.h[3] + dmbutterfly_l v18, v19, v30, v31, v29, v16, v0.h[2], v0.h[3] neg v22.4s, v22.4s neg v23.4s, v23.4s drshrn_h v27, v20, v21, #14 @@ -646,16 +646,16 @@ function iadst16 dmbutterfly_l v10, v11, v8, v9, v17, v30, v1.h[7], v1.h[6] // v10,v11 = t15, v8,v9 = t14 ld1 {v0.8h}, [x10] dbutterfly_n v22, v30, v6, v7, v10, v11, v12, v13, v10, v11 // v22 = t7a, v30 = t15a - dmbutterfly_l v14, v15, v12, v13, v23, v24, v0.h[3], v0.h[4] // v14,v15 = t9, v12,v13 = t8 + dmbutterfly_l v14, v15, v12, v13, v23, v24, v0.h[4], v0.h[5] // v14,v15 = t9, v12,v13 = t8 dbutterfly_n v25, v17, v4, v5, v8, v9, v6, v7, v8, v9 // v25 = t6a, v17 = t14a - dmbutterfly_l v4, v5, v6, v7, v28, v19, v0.h[4], v0.h[3] // v4,v5 = t12, v6,v7 = t13 + dmbutterfly_l v4, v5, v6, v7, v28, v19, v0.h[5], v0.h[4] // v4,v5 = t12, v6,v7 = t13 dbutterfly_n v23, v19, v12, v13, v4, v5, v8, v9, v4, v5 // v23 = t8a, v19 = t12a - dmbutterfly_l v10, v11, v8, v9, v21, v26, v0.h[5], v0.h[6] // v10,v11 = t11, v8,v9 = t10 + dmbutterfly_l v10, v11, v8, v9, v21, v26, v0.h[6], v0.h[7] // v10,v11 = t11, v8,v9 = t10 butterfly_8h_r v4, v27, v16, v27 // v4 = t4, v27 = t0 dbutterfly_n v24, v28, v14, v15, v6, v7, v12, v13, v6, v7 // v24 = t9a, v28 = t13a - dmbutterfly_l v12, v13, v14, v15, v30, v17, v0.h[6], v0.h[5] // v12,v13 = t14, v14,v15 = t15 + dmbutterfly_l v12, v13, v14, v15, v30, v17, v0.h[7], v0.h[6] // v12,v13 = t14, v14,v15 = t15 butterfly_8h_r v5, v20, v31, v20 // v5 = t5, v20 = t1 dbutterfly_n v21, v17, v8, v9, v12, v13, v6, v7, v12, v13 // v21 = t10a, v17 = t14a dbutterfly_n v26, v30, v10, v11, v14, v15, v8, v9, v14, v15 // v26 = t11a, v30 = t15a @@ -663,15 +663,15 @@ function iadst16 butterfly_8h_r v6, v25, v18, v25 // v6 = t6, v25 = t2 butterfly_8h_r v7, v22, v29, v22 // v7 = t7, v22 = t3 - dmbutterfly_l v10, v11, v8, v9, v19, v28, v0.h[1], v0.h[2] // v10,v11 = t13, v8,v9 = t12 - dmbutterfly_l v12, v13, v14, v15, v30, v17, v0.h[2], v0.h[1] // v12,v13 = t14, v14,v15 = t15 + dmbutterfly_l v10, v11, v8, v9, v19, v28, v0.h[2], v0.h[3] // v10,v11 = t13, v8,v9 = t12 + dmbutterfly_l v12, v13, v14, v15, v30, v17, v0.h[3], v0.h[2] // v12,v13 = t14, v14,v15 = t15 dbutterfly_n v18, v30, v8, v9, v12, v13, v16, v17, v12, v13 // v18 = out[2], v30 = t14a dbutterfly_n v29, v17, v10, v11, v14, v15, v12, v13, v14, v15 // v29 = -out[13], v17 = t15a neg v29.8h, v29.8h // v29 = out[13] - dmbutterfly_l v10, v11, v8, v9, v4, v5, v0.h[1], v0.h[2] // v10,v11 = t5a, v8,v9 = t4a - dmbutterfly_l v12, v13, v14, v15, v7, v6, v0.h[2], v0.h[1] // v12,v13 = t6a, v14,v15 = t7a + dmbutterfly_l v10, v11, v8, v9, v4, v5, v0.h[2], v0.h[3] // v10,v11 = t5a, v8,v9 = t4a + dmbutterfly_l v12, v13, v14, v15, v7, v6, v0.h[3], v0.h[2] // v12,v13 = t6a, v14,v15 = t7a butterfly_8h v2, v6, v27, v25 // v2 = out[0], v6 = t2a butterfly_8h v3, v7, v23, v21 // v3 =-out[1], v7 = t10 @@ -1101,10 +1101,10 @@ endfunc butterfly_8h v7, v3, v29, v31 // v7 = t31a, v3 = t28a butterfly_8h v22, v27, v24, v27 // v22 = t30, v27 = t29 - dmbutterfly v27, v20, v0.h[1], v0.h[2], v24, v25, v30, v31 // v27 = t18a, v20 = t29a - dmbutterfly v3, v5, v0.h[1], v0.h[2], v24, v25, v30, v31 // v3 = t19, v5 = t28 - dmbutterfly v28, v6, v0.h[1], v0.h[2], v24, v25, v30, v31, neg=1 // v28 = t27, v6 = t20 - dmbutterfly v26, v21, v0.h[1], v0.h[2], v24, v25, v30, v31, neg=1 // v26 = t26a, v21 = t21a + dmbutterfly v27, v20, v0.h[2], v0.h[3], v24, v25, v30, v31 // v27 = t18a, v20 = t29a + dmbutterfly v3, v5, v0.h[2], v0.h[3], v24, v25, v30, v31 // v3 = t19, v5 = t28 + dmbutterfly v28, v6, v0.h[2], v0.h[3], v24, v25, v30, v31, neg=1 // v28 = t27, v6 = t20 + dmbutterfly v26, v21, v0.h[2], v0.h[3], v24, v25, v30, v31, neg=1 // v26 = t26a, v21 = t21a butterfly_8h v31, v24, v7, v4 // v31 = t31, v24 = t24 butterfly_8h v30, v25, v22, v23 // v30 = t30a, v25 = t25a @@ -1141,10 +1141,10 @@ function idct32_odd butterfly_8h v29, v23, v31, v23 // v29 = t31, v23 = t30 butterfly_8h v31, v27, v19, v27 // v31 = t28, v27 = t29 - dmbutterfly v23, v24, v0.h[3], v0.h[4], v16, v17, v18, v19 // v23 = t17a, v24 = t30a - dmbutterfly v27, v20, v0.h[3], v0.h[4], v16, v17, v18, v19, neg=1 // v27 = t29a, v20 = t18a - dmbutterfly v21, v26, v0.h[5], v0.h[6], v16, v17, v18, v19 // v21 = t21a, v26 = t26a - dmbutterfly v25, v22, v0.h[5], v0.h[6], v16, v17, v18, v19, neg=1 // v25 = t25a, v22 = t22a + dmbutterfly v23, v24, v0.h[4], v0.h[5], v16, v17, v18, v19 // v23 = t17a, v24 = t30a + dmbutterfly v27, v20, v0.h[4], v0.h[5], v16, v17, v18, v19, neg=1 // v27 = t29a, v20 = t18a + dmbutterfly v21, v26, v0.h[6], v0.h[7], v16, v17, v18, v19 // v21 = t21a, v26 = t26a + dmbutterfly v25, v22, v0.h[6], v0.h[7], v16, v17, v18, v19, neg=1 // v25 = t25a, v22 = t22a idct32_end endfunc @@ -1167,10 +1167,10 @@ function idct32_odd_half butterfly_8h v29, v23, v31, v23 // v29 = t31, v23 = t30 butterfly_8h v31, v27, v19, v27 // v31 = t28, v27 = t29 - dmbutterfly v23, v24, v0.h[3], v0.h[4], v16, v17, v18, v19 // v23 = t17a, v24 = t30a - dmbutterfly v27, v20, v0.h[3], v0.h[4], v16, v17, v18, v19, neg=1 // v27 = t29a, v20 = t18a - dmbutterfly v21, v26, v0.h[5], v0.h[6], v16, v17, v18, v19 // v21 = t21a, v26 = t26a - dmbutterfly v25, v22, v0.h[5], v0.h[6], v16, v17, v18, v19, neg=1 // v25 = t25a, v22 = t22a + dmbutterfly v23, v24, v0.h[4], v0.h[5], v16, v17, v18, v19 // v23 = t17a, v24 = t30a + dmbutterfly v27, v20, v0.h[4], v0.h[5], v16, v17, v18, v19, neg=1 // v27 = t29a, v20 = t18a + dmbutterfly v21, v26, v0.h[6], v0.h[7], v16, v17, v18, v19 // v21 = t21a, v26 = t26a + dmbutterfly v25, v22, v0.h[6], v0.h[7], v16, v17, v18, v19, neg=1 // v25 = t25a, v22 = t22a idct32_end endfunc @@ -1198,18 +1198,18 @@ function idct32_odd_quarter drshrn_h v6, v20, v21, #14 drshrn_h v30, v24, v25, #14 - dmbutterfly_l v16, v17, v18, v19, v29, v4, v0.h[3], v0.h[4] - dmbutterfly_l v27, v26, v20, v21, v31, v5, v0.h[3], v0.h[4] + dmbutterfly_l v16, v17, v18, v19, v29, v4, v0.h[4], v0.h[5] + dmbutterfly_l v27, v26, v20, v21, v31, v5, v0.h[4], v0.h[5] drshrn_h v23, v16, v17, #14 drshrn_h v24, v18, v19, #14 neg v20.4s, v20.4s neg v21.4s, v21.4s drshrn_h v27, v27, v26, #14 drshrn_h v20, v20, v21, #14 - dmbutterfly_l v16, v17, v18, v19, v30, v6, v0.h[5], v0.h[6] + dmbutterfly_l v16, v17, v18, v19, v30, v6, v0.h[6], v0.h[7] drshrn_h v21, v16, v17, #14 drshrn_h v26, v18, v19, #14 - dmbutterfly_l v16, v17, v18, v19, v28, v7, v0.h[5], v0.h[6] + dmbutterfly_l v16, v17, v18, v19, v28, v7, v0.h[6], v0.h[7] drshrn_h v25, v16, v17, #14 neg v18.4s, v18.4s neg v19.4s, v19.4s From 08074c092d8c97d71c5986e5325e97ffc956119d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 31 Dec 2016 22:27:13 +0200 Subject: [PATCH 0949/3374] arm: vp9itxfm: Reorder iadst16 coeffs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matches the order they are in the 16 bpp version. There they are in this order, to make sure we access them in the same order they are declared, easing loading only half of the coefficients at a time. This makes the 8 bpp version match the 16 bpp version better. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index 1d4d6a79101b8..a612b25f4f65c 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -37,8 +37,8 @@ idct_coeffs: endconst const iadst16_coeffs, align=4 - .short 16364, 804, 15893, 3981, 14811, 7005, 13160, 9760 - .short 11003, 12140, 8423, 14053, 5520, 15426, 2404, 16207 + .short 16364, 804, 15893, 3981, 11003, 12140, 8423, 14053 + .short 14811, 7005, 13160, 9760, 5520, 15426, 2404, 16207 endconst @ Do four 4x4 transposes, using q registers for the subtransposes that don't @@ -678,19 +678,19 @@ function iadst16 vld1.16 {q0-q1}, [r12,:128] mbutterfly_l q3, q2, d31, d16, d0[1], d0[0] @ q3 = t1, q2 = t0 - mbutterfly_l q5, q4, d23, d24, d2[1], d2[0] @ q5 = t9, q4 = t8 + mbutterfly_l q5, q4, d23, d24, d1[1], d1[0] @ q5 = t9, q4 = t8 butterfly_n d31, d24, q3, q5, q6, q5 @ d31 = t1a, d24 = t9a mbutterfly_l q7, q6, d29, d18, d0[3], d0[2] @ q7 = t3, q6 = t2 butterfly_n d16, d23, q2, q4, q3, q4 @ d16 = t0a, d23 = t8a - mbutterfly_l q3, q2, d21, d26, d2[3], d2[2] @ q3 = t11, q2 = t10 + mbutterfly_l q3, q2, d21, d26, d1[3], d1[2] @ q3 = t11, q2 = t10 butterfly_n d29, d26, q7, q3, q4, q3 @ d29 = t3a, d26 = t11a - mbutterfly_l q5, q4, d27, d20, d1[1], d1[0] @ q5 = t5, q4 = t4 + mbutterfly_l q5, q4, d27, d20, d2[1], d2[0] @ q5 = t5, q4 = t4 butterfly_n d18, d21, q6, q2, q3, q2 @ d18 = t2a, d21 = t10a mbutterfly_l q7, q6, d19, d28, d3[1], d3[0] @ q7 = t13, q6 = t12 butterfly_n d20, d28, q5, q7, q2, q7 @ d20 = t5a, d28 = t13a - mbutterfly_l q3, q2, d25, d22, d1[3], d1[2] @ q3 = t7, q2 = t6 + mbutterfly_l q3, q2, d25, d22, d2[3], d2[2] @ q3 = t7, q2 = t6 butterfly_n d27, d19, q4, q6, q5, q6 @ d27 = t4a, d19 = t12a mbutterfly_l q5, q4, d17, d30, d3[3], d3[2] @ q5 = t15, q4 = t14 From b8f66c0838b4c645227f23a35b4d54373da4c60a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 31 Dec 2016 22:27:13 +0200 Subject: [PATCH 0950/3374] aarch64: vp9itxfm: Reorder iadst16 coeffs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matches the order they are in the 16 bpp version. There they are in this order, to make sure we access them in the same order they are declared, easing loading only half of the coefficients at a time. This makes the 8 bpp version match the 16 bpp version better. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index d4fc2163aa30b..93dc736f01fed 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -37,8 +37,8 @@ idct_coeffs: endconst const iadst16_coeffs, align=4 - .short 16364, 804, 15893, 3981, 14811, 7005, 13160, 9760 - .short 11003, 12140, 8423, 14053, 5520, 15426, 2404, 16207 + .short 16364, 804, 15893, 3981, 11003, 12140, 8423, 14053 + .short 14811, 7005, 13160, 9760, 5520, 15426, 2404, 16207 endconst // out1 = ((in1 + in2) * v0[0] + (1 << 13)) >> 14 @@ -628,19 +628,19 @@ function iadst16 ld1 {v0.8h,v1.8h}, [x11] dmbutterfly_l v6, v7, v4, v5, v31, v16, v0.h[1], v0.h[0] // v6,v7 = t1, v4,v5 = t0 - dmbutterfly_l v10, v11, v8, v9, v23, v24, v1.h[1], v1.h[0] // v10,v11 = t9, v8,v9 = t8 + dmbutterfly_l v10, v11, v8, v9, v23, v24, v0.h[5], v0.h[4] // v10,v11 = t9, v8,v9 = t8 dbutterfly_n v31, v24, v6, v7, v10, v11, v12, v13, v10, v11 // v31 = t1a, v24 = t9a dmbutterfly_l v14, v15, v12, v13, v29, v18, v0.h[3], v0.h[2] // v14,v15 = t3, v12,v13 = t2 dbutterfly_n v16, v23, v4, v5, v8, v9, v6, v7, v8, v9 // v16 = t0a, v23 = t8a - dmbutterfly_l v6, v7, v4, v5, v21, v26, v1.h[3], v1.h[2] // v6,v7 = t11, v4,v5 = t10 + dmbutterfly_l v6, v7, v4, v5, v21, v26, v0.h[7], v0.h[6] // v6,v7 = t11, v4,v5 = t10 dbutterfly_n v29, v26, v14, v15, v6, v7, v8, v9, v6, v7 // v29 = t3a, v26 = t11a - dmbutterfly_l v10, v11, v8, v9, v27, v20, v0.h[5], v0.h[4] // v10,v11 = t5, v8,v9 = t4 + dmbutterfly_l v10, v11, v8, v9, v27, v20, v1.h[1], v1.h[0] // v10,v11 = t5, v8,v9 = t4 dbutterfly_n v18, v21, v12, v13, v4, v5, v6, v7, v4, v5 // v18 = t2a, v21 = t10a dmbutterfly_l v14, v15, v12, v13, v19, v28, v1.h[5], v1.h[4] // v14,v15 = t13, v12,v13 = t12 dbutterfly_n v20, v28, v10, v11, v14, v15, v4, v5, v14, v15 // v20 = t5a, v28 = t13a - dmbutterfly_l v6, v7, v4, v5, v25, v22, v0.h[7], v0.h[6] // v6,v7 = t7, v4,v5 = t6 + dmbutterfly_l v6, v7, v4, v5, v25, v22, v1.h[3], v1.h[2] // v6,v7 = t7, v4,v5 = t6 dbutterfly_n v27, v19, v8, v9, v12, v13, v10, v11, v12, v13 // v27 = t4a, v19 = t12a dmbutterfly_l v10, v11, v8, v9, v17, v30, v1.h[7], v1.h[6] // v10,v11 = t15, v8,v9 = t14 From 8e4d4efc67e154fdffd65964a7cfeef740320827 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 6 Apr 2013 12:48:32 +0200 Subject: [PATCH 0951/3374] fate: Add another SVQ3 test to increase coverage --- tests/fate/qt.mak | 10 ++++++++-- tests/ref/fate/{svq3 => svq3-1} | 0 tests/ref/fate/svq3-2 | 20 ++++++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) rename tests/ref/fate/{svq3 => svq3-1} (100%) create mode 100644 tests/ref/fate/svq3-2 diff --git a/tests/fate/qt.mak b/tests/fate/qt.mak index 97537f93efe58..761db8d234eba 100644 --- a/tests/fate/qt.mak +++ b/tests/fate/qt.mak @@ -49,5 +49,11 @@ fate-svq1: CMD = framecrc -i $(TARGET_SAMPLES)/svq1/marymary-shackles.mov -an -t FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, SVQ1) += fate-svq1-headerswap fate-svq1-headerswap: CMD = framecrc -i $(TARGET_SAMPLES)/svq1/ct_ending_cut.mov -frames 4 -FATE_SAMPLES_AVCONV-$(call ALLYES, MOV_DEMUXER SVQ3_DECODER ZLIB) += fate-svq3 -fate-svq3: CMD = framecrc -i $(TARGET_SAMPLES)/svq3/Vertical400kbit.sorenson3.mov -t 6 -an +FATE_SVQ3 += fate-svq3-1 +fate-svq3-1: CMD = framecrc -i $(TARGET_SAMPLES)/svq3/Vertical400kbit.sorenson3.mov -t 6 -an + +FATE_SVQ3 += fate-svq3-2 +fate-svq3-2: CMD = framecrc -i $(TARGET_SAMPLES)/svq3/svq3_decoding_regression.mov -an + +FATE_SAMPLES_AVCONV-$(call ALLYES, MOV_DEMUXER SVQ3_DECODER ZLIB) += $(FATE_SVQ3) +fate-svq3: $(FATE_SVQ3) diff --git a/tests/ref/fate/svq3 b/tests/ref/fate/svq3-1 similarity index 100% rename from tests/ref/fate/svq3 rename to tests/ref/fate/svq3-1 diff --git a/tests/ref/fate/svq3-2 b/tests/ref/fate/svq3-2 new file mode 100644 index 0000000000000..7e69b31b01c07 --- /dev/null +++ b/tests/ref/fate/svq3-2 @@ -0,0 +1,20 @@ +#tb 0: 1/19200 +0, -20000, -20000, 0, 185280, 0x061c0d85 +0, -19200, -19200, 0, 185280, 0x427ef9a7 +0, -18400, -18400, 0, 185280, 0x8f495d37 +0, -17600, -17600, 0, 185280, 0x5bfd0e5b +0, -16800, -16800, 0, 185280, 0x60d12d25 +0, -16000, -16000, 0, 185280, 0x25aaa51b +0, -15200, -15200, 0, 185280, 0x9cf58bf0 +0, -14400, -14400, 0, 185280, 0xd9bd03ea +0, -13600, -13600, 0, 185280, 0xd18be732 +0, -12800, -12800, 0, 185280, 0x92763708 +0, -12000, -12000, 0, 185280, 0x94b5784a +0, -11200, -11200, 0, 185280, 0x32b184c9 +0, -10400, -10400, 0, 185280, 0xe316fec3 +0, -9600, -9600, 0, 185280, 0x6344ec88 +0, -8800, -8800, 0, 185280, 0xe0aa6de4 +0, -8000, -8000, 0, 185280, 0x6cfc8687 +0, -7200, -7200, 0, 185280, 0x26ddc189 +0, -6400, -6400, 0, 185280, 0x5a0c1b38 +0, -5600, -5600, 0, 185280, 0x79a88cb9 From 248dc5c1646dcdd96fe79761105c4ae889e711fd Mon Sep 17 00:00:00 2001 From: John Stebbins Date: Thu, 23 Feb 2017 14:22:56 -0700 Subject: [PATCH 0952/3374] h264dec: fix dropped initial SEI recovery point --- libavcodec/h264dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 5137039188bc2..6d7aa7b53ca4f 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -452,7 +452,6 @@ void ff_h264_flush_change(H264Context *h) if (h->cur_pic_ptr) h->cur_pic_ptr->reference = 0; h->first_field = 0; - ff_h264_sei_uninit(&h->sei); h->recovery_frame = -1; h->frame_recovered = 0; } @@ -466,6 +465,7 @@ static void flush_dpb(AVCodecContext *avctx) memset(h->delayed_pic, 0, sizeof(h->delayed_pic)); ff_h264_flush_change(h); + ff_h264_sei_uninit(&h->sei); for (i = 0; i < H264_MAX_PICTURE_COUNT; i++) ff_h264_unref_picture(h, &h->DPB[i]); From cd7a2e1502f174c725c0de82711d2c7649057574 Mon Sep 17 00:00:00 2001 From: John Stebbins Date: Thu, 23 Feb 2017 16:47:58 -0700 Subject: [PATCH 0953/3374] asfdec: fix reading files larger than 2GB avio_skip returns file position and overflows int --- libavformat/asfdec.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index 34730b20aa882..9e1f8f6b62aec 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -976,7 +976,8 @@ static int asf_read_simple_index(AVFormatContext *s, const GUIDParseTable *g) uint64_t interval; // index entry time interval in 100 ns units, usually it's 1s uint32_t pkt_num, nb_entries; int32_t prev_pkt_num = -1; - int i, ret; + int i; + int64_t offset; uint64_t size = avio_rl64(pb); // simple index objects should be ordered by stream number, this loop tries to find @@ -998,10 +999,10 @@ static int asf_read_simple_index(AVFormatContext *s, const GUIDParseTable *g) nb_entries = avio_rl32(pb); for (i = 0; i < nb_entries; i++) { pkt_num = avio_rl32(pb); - ret = avio_skip(pb, 2); - if (ret < 0) { + offset = avio_skip(pb, 2); + if (offset < 0) { av_log(s, AV_LOG_ERROR, "Skipping failed in asf_read_simple_index.\n"); - return ret; + return offset; } if (prev_pkt_num != pkt_num) { av_add_index_entry(st, asf->first_packet_offset + asf->packet_size * From 3f258f5ee05c9da05f61447b802ae3e39629f44b Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 10 Feb 2017 20:24:26 -0300 Subject: [PATCH 0954/3374] apetag: fix flag value to signal footer presence According to the spec[1], a value of 0 means the footer is present and a value of 1 means it's absent, the exact opposite of header presence flag where 1 means present and 0 absent. The reason for this is compatibility with APEv1 tags, where there's no header, footer presence was mandatory for all files, and the flags field was a zeroed reserved field. [1] http://wiki.hydrogenaud.io/index.php?title=Ape_Tags_Flags Signed-off-by: James Almer CC: libav-stable@libav.org Signed-off-by: Anton Khirnov --- libavformat/apetag.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libavformat/apetag.c b/libavformat/apetag.c index 05430dd9bcc3f..93a4fb3430578 100644 --- a/libavformat/apetag.c +++ b/libavformat/apetag.c @@ -32,7 +32,7 @@ #define APE_TAG_VERSION 2000 #define APE_TAG_FOOTER_BYTES 32 #define APE_TAG_FLAG_CONTAINS_HEADER (1 << 31) -#define APE_TAG_FLAG_CONTAINS_FOOTER (1 << 30) +#define APE_TAG_FLAG_LACKS_FOOTER (1 << 30) #define APE_TAG_FLAG_IS_HEADER (1 << 29) #define APE_TAG_FLAG_IS_BINARY (1 << 1) @@ -194,8 +194,7 @@ int ff_ape_write_tag(AVFormatContext *s) avio_wl32(s->pb, 0); // reserve space for tag count // flags - avio_wl32(s->pb, APE_TAG_FLAG_CONTAINS_HEADER | APE_TAG_FLAG_CONTAINS_FOOTER | - APE_TAG_FLAG_IS_HEADER); + avio_wl32(s->pb, APE_TAG_FLAG_CONTAINS_HEADER | APE_TAG_FLAG_IS_HEADER); ffio_fill(s->pb, 0, 8); // reserved while ((e = av_dict_get(s->metadata, "", e, AV_DICT_IGNORE_SUFFIX))) { @@ -217,7 +216,7 @@ int ff_ape_write_tag(AVFormatContext *s) avio_wl32(s->pb, count); // tag count // flags - avio_wl32(s->pb, APE_TAG_FLAG_CONTAINS_HEADER | APE_TAG_FLAG_CONTAINS_FOOTER); + avio_wl32(s->pb, APE_TAG_FLAG_CONTAINS_HEADER); ffio_fill(s->pb, 0, 8); // reserved // update values in the header From b2788fe9347c02b1355574f3d28d60bfe1250ea7 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 1 Feb 2017 11:50:38 +0100 Subject: [PATCH 0955/3374] svq3: fix the slice size check Currently it incorrectly compares bits with bytes. Also, move the check right before where it's relevant, so that the correct number of remaining bits is used. CC: libav-stable@libav.org --- libavcodec/svq3.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index 20c8f89e76e15..667d3906a1fed 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -1031,17 +1031,16 @@ static int svq3_decode_slice_header(AVCodecContext *avctx) slice_bits = slice_length * 8; slice_bytes = slice_length + length - 1; - if (slice_bytes > bitstream_bits_left(&s->bc)) { - av_log(avctx, AV_LOG_ERROR, "slice after bitstream end\n"); - return -1; - } - bitstream_skip(&s->bc, 8); av_fast_malloc(&s->slice_buf, &s->slice_size, slice_bytes + AV_INPUT_BUFFER_PADDING_SIZE); if (!s->slice_buf) return AVERROR(ENOMEM); + if (slice_bytes * 8 > bitstream_bits_left(&s->bc)) { + av_log(avctx, AV_LOG_ERROR, "slice after bitstream end\n"); + return AVERROR_INVALIDDATA; + } memcpy(s->slice_buf, s->bc.buffer + bitstream_tell(&s->bc) / 8, slice_bytes); if (s->watermark_key) { From 4cc0227040adb9efc63be6a5765e3214f5c6f662 Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 10 Feb 2017 20:24:27 -0300 Subject: [PATCH 0956/3374] apetag: account for header size if present when returning the start position The size field in the header/footer accounts for the entire APE tag structure except the 32 bytes from header, for compatibility with APEv1. Signed-off-by: James Almer CC: libav-stable@libav.org Signed-off-by: Anton Khirnov --- libavformat/apetag.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libavformat/apetag.c b/libavformat/apetag.c index 93a4fb3430578..a7cf8530f1a0b 100644 --- a/libavformat/apetag.c +++ b/libavformat/apetag.c @@ -31,6 +31,7 @@ #define APE_TAG_VERSION 2000 #define APE_TAG_FOOTER_BYTES 32 +#define APE_TAG_HEADER_BYTES 32 #define APE_TAG_FLAG_CONTAINS_HEADER (1 << 31) #define APE_TAG_FLAG_LACKS_FOOTER (1 << 30) #define APE_TAG_FLAG_IS_HEADER (1 << 29) @@ -154,7 +155,6 @@ int64_t ff_ape_parse_tag(AVFormatContext *s) av_log(s, AV_LOG_ERROR, "Invalid tag size %"PRIu32".\n", tag_bytes); return 0; } - tag_start = file_size - tag_bytes - APE_TAG_FOOTER_BYTES; fields = avio_rl32(pb); /* number of fields */ if (fields > 65536) { @@ -170,6 +170,11 @@ int64_t ff_ape_parse_tag(AVFormatContext *s) avio_seek(pb, file_size - tag_bytes, SEEK_SET); + if (val & APE_TAG_FLAG_CONTAINS_HEADER) + tag_bytes += APE_TAG_HEADER_BYTES; + + tag_start = file_size - tag_bytes; + for (i=0; i Date: Tue, 14 Feb 2017 20:51:06 +0100 Subject: [PATCH 0957/3374] lavc: make sure not to return EAGAIN from codecs This error is treated specially by the API. CC: libav-stable@libav.org --- libavcodec/aacdec.c | 6 +++--- libavcodec/nvenc.c | 8 +++++--- libavcodec/qsv.c | 8 +++++--- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index 22ebcdc570569..4ba346ac48710 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -3228,7 +3228,7 @@ static int read_audio_mux_element(struct LATMContext *latmctx, } else if (!latmctx->aac_ctx.avctx->extradata) { av_log(latmctx->aac_ctx.avctx, AV_LOG_DEBUG, "no decoder config found\n"); - return AVERROR(EAGAIN); + return 1; } if (latmctx->audio_mux_version_A == 0) { int mux_slot_length_bytes = read_payload_length_info(latmctx, gb); @@ -3265,8 +3265,8 @@ static int latm_decode_frame(AVCodecContext *avctx, void *out, if (muxlength > avpkt->size) return AVERROR_INVALIDDATA; - if ((err = read_audio_mux_element(latmctx, &gb)) < 0) - return err; + if ((err = read_audio_mux_element(latmctx, &gb))) + return (err < 0) ? err : avpkt->size; if (!latmctx->initialized) { if (!avctx->extradata) { diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 30da83a08ca24..ffa8a0a2d8d8f 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -123,12 +123,14 @@ static const struct { { NV_ENC_ERR_OUT_OF_MEMORY, AVERROR(ENOMEM), "out of memory" }, { NV_ENC_ERR_ENCODER_NOT_INITIALIZED, AVERROR(EINVAL), "encoder not initialized" }, { NV_ENC_ERR_UNSUPPORTED_PARAM, AVERROR(ENOSYS), "unsupported param" }, - { NV_ENC_ERR_LOCK_BUSY, AVERROR(EAGAIN), "lock busy" }, + { NV_ENC_ERR_LOCK_BUSY, AVERROR(EBUSY), "lock busy" }, { NV_ENC_ERR_NOT_ENOUGH_BUFFER, AVERROR(ENOBUFS), "not enough buffer" }, { NV_ENC_ERR_INVALID_VERSION, AVERROR(EINVAL), "invalid version" }, { NV_ENC_ERR_MAP_FAILED, AVERROR(EIO), "map failed" }, - { NV_ENC_ERR_NEED_MORE_INPUT, AVERROR(EAGAIN), "need more input" }, - { NV_ENC_ERR_ENCODER_BUSY, AVERROR(EAGAIN), "encoder busy" }, + /* this is error should always be treated specially, so this "mapping" + * is for completeness only */ + { NV_ENC_ERR_NEED_MORE_INPUT, AVERROR_UNKNOWN, "need more input" }, + { NV_ENC_ERR_ENCODER_BUSY, AVERROR(EBUSY), "encoder busy" }, { NV_ENC_ERR_EVENT_NOT_REGISTERD, AVERROR(EBADF), "event not registered" }, { NV_ENC_ERR_GENERIC, AVERROR_UNKNOWN, "generic error" }, { NV_ENC_ERR_INCOMPATIBLE_CLIENT_KEY, AVERROR(EINVAL), "incompatible client key" }, diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index ab48bb0dfb84b..735e1536f8406 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -94,15 +94,17 @@ static const struct { { MFX_ERR_LOCK_MEMORY, AVERROR(EIO), "failed to lock the memory block" }, { MFX_ERR_NOT_INITIALIZED, AVERROR_BUG, "not initialized" }, { MFX_ERR_NOT_FOUND, AVERROR(ENOSYS), "specified object was not found" }, - { MFX_ERR_MORE_DATA, AVERROR(EAGAIN), "expect more data at input" }, - { MFX_ERR_MORE_SURFACE, AVERROR(EAGAIN), "expect more surface at output" }, + /* the following 3 errors should always be handled explicitly, so those "mappings" + * are for completeness only */ + { MFX_ERR_MORE_DATA, AVERROR_UNKNOWN, "expect more data at input" }, + { MFX_ERR_MORE_SURFACE, AVERROR_UNKNOWN, "expect more surface at output" }, + { MFX_ERR_MORE_BITSTREAM, AVERROR_UNKNOWN, "expect more bitstream at output" }, { MFX_ERR_ABORTED, AVERROR_UNKNOWN, "operation aborted" }, { MFX_ERR_DEVICE_LOST, AVERROR(EIO), "device lost" }, { MFX_ERR_INCOMPATIBLE_VIDEO_PARAM, AVERROR(EINVAL), "incompatible video parameters" }, { MFX_ERR_INVALID_VIDEO_PARAM, AVERROR(EINVAL), "invalid video parameters" }, { MFX_ERR_UNDEFINED_BEHAVIOR, AVERROR_BUG, "undefined behavior" }, { MFX_ERR_DEVICE_FAILED, AVERROR(EIO), "device failed" }, - { MFX_ERR_MORE_BITSTREAM, AVERROR(EAGAIN), "expect more bitstream at output" }, { MFX_ERR_INCOMPATIBLE_AUDIO_PARAM, AVERROR(EINVAL), "incompatible audio parameters" }, { MFX_ERR_INVALID_AUDIO_PARAM, AVERROR(EINVAL), "invalid audio parameters" }, From da8093f712d625db7ce4a2526fb52994e01921ec Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 25 Feb 2017 17:19:48 +0100 Subject: [PATCH 0958/3374] fate: Use bitexact optimizations in the svq3-2 test This fixes the test with mmxext disabled because the current reference frame hashes correspond to the non-bitexact mmxext optimizations. --- tests/fate/qt.mak | 2 +- tests/ref/fate/svq3-2 | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/fate/qt.mak b/tests/fate/qt.mak index 761db8d234eba..b51168fbeae18 100644 --- a/tests/fate/qt.mak +++ b/tests/fate/qt.mak @@ -53,7 +53,7 @@ FATE_SVQ3 += fate-svq3-1 fate-svq3-1: CMD = framecrc -i $(TARGET_SAMPLES)/svq3/Vertical400kbit.sorenson3.mov -t 6 -an FATE_SVQ3 += fate-svq3-2 -fate-svq3-2: CMD = framecrc -i $(TARGET_SAMPLES)/svq3/svq3_decoding_regression.mov -an +fate-svq3-2: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/svq3/svq3_decoding_regression.mov -an FATE_SAMPLES_AVCONV-$(call ALLYES, MOV_DEMUXER SVQ3_DECODER ZLIB) += $(FATE_SVQ3) fate-svq3: $(FATE_SVQ3) diff --git a/tests/ref/fate/svq3-2 b/tests/ref/fate/svq3-2 index 7e69b31b01c07..575e472a18451 100644 --- a/tests/ref/fate/svq3-2 +++ b/tests/ref/fate/svq3-2 @@ -1,20 +1,20 @@ #tb 0: 1/19200 0, -20000, -20000, 0, 185280, 0x061c0d85 0, -19200, -19200, 0, 185280, 0x427ef9a7 -0, -18400, -18400, 0, 185280, 0x8f495d37 +0, -18400, -18400, 0, 185280, 0x64c74d6a 0, -17600, -17600, 0, 185280, 0x5bfd0e5b -0, -16800, -16800, 0, 185280, 0x60d12d25 +0, -16800, -16800, 0, 185280, 0x9da221c6 0, -16000, -16000, 0, 185280, 0x25aaa51b -0, -15200, -15200, 0, 185280, 0x9cf58bf0 +0, -15200, -15200, 0, 185280, 0x26848298 0, -14400, -14400, 0, 185280, 0xd9bd03ea -0, -13600, -13600, 0, 185280, 0xd18be732 +0, -13600, -13600, 0, 185280, 0xe1a7e39f 0, -12800, -12800, 0, 185280, 0x92763708 -0, -12000, -12000, 0, 185280, 0x94b5784a +0, -12000, -12000, 0, 185280, 0x76137106 0, -11200, -11200, 0, 185280, 0x32b184c9 -0, -10400, -10400, 0, 185280, 0xe316fec3 +0, -10400, -10400, 0, 185280, 0xe5d6ec11 0, -9600, -9600, 0, 185280, 0x6344ec88 -0, -8800, -8800, 0, 185280, 0xe0aa6de4 +0, -8800, -8800, 0, 185280, 0xa8875cb9 0, -8000, -8000, 0, 185280, 0x6cfc8687 -0, -7200, -7200, 0, 185280, 0x26ddc189 +0, -7200, -7200, 0, 185280, 0xcbc5bb85 0, -6400, -6400, 0, 185280, 0x5a0c1b38 -0, -5600, -5600, 0, 185280, 0x79a88cb9 +0, -5600, -5600, 0, 185280, 0x887a7fb2 From 4141a5a240fba44b4b4a1c488c279d7dd8a11ec7 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 18 Oct 2012 10:15:07 +0200 Subject: [PATCH 0959/3374] Use modern avconv syntax for codec selection in documentation and tests --- doc/encoders.texi | 2 +- doc/faq.texi | 8 ++++---- doc/filters.texi | 4 ++-- tests/fate-run.sh | 4 ++-- tests/fate/demux.mak | 34 +++++++++++++++++----------------- tests/fate/h264.mak | 2 +- tests/fate/microsoft.mak | 2 +- tests/fate/mp3.mak | 14 +++++++------- tests/fate/mpc.mak | 4 ++-- tests/fate/utvideo.mak | 2 +- tests/fate/video.mak | 4 ++-- tests/fate/vqf.mak | 2 +- tests/lavf-regression.sh | 28 ++++++++++++++-------------- 13 files changed, 55 insertions(+), 55 deletions(-) diff --git a/doc/encoders.texi b/doc/encoders.texi index bc5b33660e8c2..41b839812727a 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -38,7 +38,7 @@ always faster, just that one or the other may be better suited to a particular system. The floating-point encoder will generally produce better quality audio for a given bitrate. The @var{ac3_fixed} encoder is not the default codec for any of the output formats, so it must be specified explicitly -using the option @code{-acodec ac3_fixed} in order to use it. +using the option @code{-c:a ac3_fixed} in order to use it. @subsection AC-3 Metadata diff --git a/doc/faq.texi b/doc/faq.texi index b400124f69415..f3d55bde95a3f 100644 --- a/doc/faq.texi +++ b/doc/faq.texi @@ -234,7 +234,7 @@ mkfifo intermediate2.mpg avconv -i input1.avi -y intermediate1.mpg < /dev/null & avconv -i input2.avi -y intermediate2.mpg < /dev/null & cat intermediate1.mpg intermediate2.mpg |\ -avconv -f mpeg -i - -c:v mpeg4 -acodec libmp3lame output.avi +avconv -f mpeg -i - -c:v mpeg4 -c:a libmp3lame output.avi @end example Similarly, the yuv4mpegpipe format, and the raw video, raw audio codecs also @@ -253,13 +253,13 @@ mkfifo temp2.a mkfifo temp2.v mkfifo all.a mkfifo all.v -avconv -i input1.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp1.a < /dev/null & -avconv -i input2.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp2.a < /dev/null & +avconv -i input1.flv -vn -f u16le -c:a pcm_s16le -ac 2 -ar 44100 - > temp1.a < /dev/null & +avconv -i input2.flv -vn -f u16le -c:a pcm_s16le -ac 2 -ar 44100 - > temp2.a < /dev/null & avconv -i input1.flv -an -f yuv4mpegpipe - > temp1.v < /dev/null & @{ avconv -i input2.flv -an -f yuv4mpegpipe - < /dev/null | tail -n +2 > temp2.v ; @} & cat temp1.a temp2.a > all.a & cat temp1.v temp2.v > all.v & -avconv -f u16le -acodec pcm_s16le -ac 2 -ar 44100 -i all.a \ +avconv -f u16le -c:a pcm_s16le -ac 2 -ar 44100 -i all.a \ -f yuv4mpegpipe -i all.v \ -y output.flv rm temp[12].[av] all.[av] diff --git a/doc/filters.texi b/doc/filters.texi index 954765f08ed56..947fd7915c04a 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -661,10 +661,10 @@ avconv -i HDCD16.flac -af hdcd OUT24.flac When using the filter with WAV, note that the default encoding for WAV is 16-bit, so the resulting 20-bit stream will be truncated back to 16-bit. Use something -like @command{-acodec pcm_s24le} after the filter to get 24-bit PCM output. +like @command{-c:a pcm_s24le} after the filter to get 24-bit PCM output. @example avconv -i HDCD16.wav -af hdcd OUT16.wav -avconv -i HDCD16.wav -af hdcd -acodec pcm_s24le OUT24.wav +avconv -i HDCD16.wav -af hdcd -c:a pcm_s24le OUT24.wav @end example The filter accepts the following options: diff --git a/tests/fate-run.sh b/tests/fate-run.sh index 623fd635a02f2..43fcee02abf15 100755 --- a/tests/fate-run.sh +++ b/tests/fate-run.sh @@ -164,8 +164,8 @@ video_filter(){ label=${test#filter-} raw_src="${target_path}/tests/vsynth1/%02d.pgm" printf '%-20s' $label - avconv $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src \ - $FLAGS $ENC_OPTS -vf "$filters" -vcodec rawvideo -frames:v 5 $* -f nut md5: + avconv $DEC_OPTS -f image2 -c:v pgmyuv -i $raw_src \ + $FLAGS $ENC_OPTS -vf "$filters" -c:v rawvideo -frames:v 5 $* -f nut md5: } pixfmts(){ diff --git a/tests/fate/demux.mak b/tests/fate/demux.mak index d529341a5da0e..44c4d6efa45b6 100644 --- a/tests/fate/demux.mak +++ b/tests/fate/demux.mak @@ -1,26 +1,26 @@ FATE_SAMPLES_AVCONV-$(call DEMDEC, AAC, AAC) += fate-adts-demux -fate-adts-demux: CMD = crc -i $(TARGET_SAMPLES)/aac/ct_faac-adts.aac -acodec copy +fate-adts-demux: CMD = crc -i $(TARGET_SAMPLES)/aac/ct_faac-adts.aac -c:a copy FATE_SAMPLES_AVCONV-$(CONFIG_AEA_DEMUXER) += fate-aea-demux -fate-aea-demux: CMD = crc -i $(TARGET_SAMPLES)/aea/chirp.aea -acodec copy +fate-aea-demux: CMD = crc -i $(TARGET_SAMPLES)/aea/chirp.aea -c:a copy FATE_SAMPLES_AVCONV-$(CONFIG_BINK_DEMUXER) += fate-bink-demux -fate-bink-demux: CMD = crc -i $(TARGET_SAMPLES)/bink/Snd0a7d9b58.dee -vn -acodec copy +fate-bink-demux: CMD = crc -i $(TARGET_SAMPLES)/bink/Snd0a7d9b58.dee -vn -c:a copy FATE_SAMPLES_AVCONV-$(CONFIG_CAF_DEMUXER) += fate-caf fate-caf: CMD = crc -i $(TARGET_SAMPLES)/caf/caf-pcm16.caf -c copy FATE_SAMPLES_AVCONV-$(CONFIG_CDXL_DEMUXER) += fate-cdxl-demux -fate-cdxl-demux: CMD = framecrc -i $(TARGET_SAMPLES)/cdxl/mirage.cdxl -vcodec copy -acodec copy +fate-cdxl-demux: CMD = framecrc -i $(TARGET_SAMPLES)/cdxl/mirage.cdxl -c copy FATE_SAMPLES_AVCONV-$(CONFIG_DAUD_DEMUXER) += fate-d-cinema-demux -fate-d-cinema-demux: CMD = framecrc -i $(TARGET_SAMPLES)/d-cinema/THX_Science_FLT_1920-partial.302 -acodec copy +fate-d-cinema-demux: CMD = framecrc -i $(TARGET_SAMPLES)/d-cinema/THX_Science_FLT_1920-partial.302 -c:a copy FATE_SAMPLES_AVCONV-$(call ALLYES, IV8_DEMUXER MPEG4VIDEO_PARSER) += fate-iv8-demux -fate-iv8-demux: CMD = framecrc -i $(TARGET_SAMPLES)/iv8/zzz-partial.mpg -vcodec copy +fate-iv8-demux: CMD = framecrc -i $(TARGET_SAMPLES)/iv8/zzz-partial.mpg -c:v copy FATE_SAMPLES_AVCONV-$(call ALLYES, LMLM4_DEMUXER MPEG4VIDEO_PARSER) += fate-lmlm4-demux -fate-lmlm4-demux: CMD = framecrc -i $(TARGET_SAMPLES)/lmlm4/LMLM4_CIFat30fps.divx -t 3 -acodec copy -vcodec copy +fate-lmlm4-demux: CMD = framecrc -i $(TARGET_SAMPLES)/lmlm4/LMLM4_CIFat30fps.divx -t 3 -c copy FATE_SAMPLES_AVCONV-$(CONFIG_XA_DEMUXER) += fate-maxis-xa fate-maxis-xa: CMD = framecrc -i $(TARGET_SAMPLES)/maxis-xa/SC2KBUG.XA -frames:a 30 -c:a copy @@ -29,28 +29,28 @@ FATE_SAMPLES_AVCONV-$(CONFIG_MTV_DEMUXER) += fate-mtv fate-mtv: CMD = framecrc -i $(TARGET_SAMPLES)/mtv/comedian_auto-partial.mtv -c copy FATE_SAMPLES_AVCONV-$(call DEMDEC, MXF, MPEG4) += fate-mxf-demux -fate-mxf-demux: CMD = framecrc -i $(TARGET_SAMPLES)/mxf/C0023S01.mxf -acodec copy -vcodec copy +fate-mxf-demux: CMD = framecrc -i $(TARGET_SAMPLES)/mxf/C0023S01.mxf -c copy FATE_SAMPLES_AVCONV-$(call ALLYES, NC_DEMUXER MPEG4VIDEO_PARSER) += fate-nc-demux -fate-nc-demux: CMD = framecrc -i $(TARGET_SAMPLES)/nc-camera/nc-sample-partial -vcodec copy +fate-nc-demux: CMD = framecrc -i $(TARGET_SAMPLES)/nc-camera/nc-sample-partial -c:v copy FATE_SAMPLES_AVCONV-$(CONFIG_NSV_DEMUXER) += fate-nsv-demux -fate-nsv-demux: CMD = framecrc -i $(TARGET_SAMPLES)/nsv/witchblade-51kbps.nsv -t 6 -vcodec copy -acodec copy +fate-nsv-demux: CMD = framecrc -i $(TARGET_SAMPLES)/nsv/witchblade-51kbps.nsv -t 6 -c copy FATE_SAMPLES_AVCONV-$(CONFIG_OMA_DEMUXER) += fate-oma-demux -fate-oma-demux: CMD = crc -i $(TARGET_SAMPLES)/oma/01-Untitled-partial.oma -acodec copy +fate-oma-demux: CMD = crc -i $(TARGET_SAMPLES)/oma/01-Untitled-partial.oma -c:a copy FATE_SAMPLES_AVCONV-$(CONFIG_STR_DEMUXER) += fate-psx-str-demux fate-psx-str-demux: CMD = framecrc -i $(TARGET_SAMPLES)/psx-str/descent-partial.str -c copy FATE_SAMPLES_AVCONV-$(CONFIG_PVA_DEMUXER) += fate-pva-demux -fate-pva-demux: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/pva/PVA_test-partial.pva -t 0.6 -acodec copy -vn +fate-pva-demux: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/pva/PVA_test-partial.pva -t 0.6 -c:a copy -vn FATE_SAMPLES_AVCONV-$(CONFIG_QCP_DEMUXER) += fate-qcp-demux -fate-qcp-demux: CMD = crc -i $(TARGET_SAMPLES)/qcp/0036580847.QCP -acodec copy +fate-qcp-demux: CMD = crc -i $(TARGET_SAMPLES)/qcp/0036580847.QCP -c:a copy FATE_SAMPLES_AVCONV-$(CONFIG_R3D_DEMUXER) += fate-redcode-demux -fate-redcode-demux: CMD = framecrc -i $(TARGET_SAMPLES)/r3d/4MB-sample.r3d -vcodec copy -acodec copy +fate-redcode-demux: CMD = framecrc -i $(TARGET_SAMPLES)/r3d/4MB-sample.r3d -c copy FATE_SAMPLES_AVCONV-$(CONFIG_SIFF_DEMUXER) += fate-siff-demux fate-siff-demux: CMD = framecrc -i $(TARGET_SAMPLES)/SIFF/INTRO_B.VB -c copy @@ -62,10 +62,10 @@ FATE_SAMPLES_AVCONV-$(CONFIG_WSAUD_DEMUXER) += fate-westwood-aud fate-westwood-aud: CMD = framecrc -i $(TARGET_SAMPLES)/westwood-aud/excellent.aud -c copy FATE_SAMPLES_AVCONV-$(call ALLYES, WTV_DEMUXER MPEGVIDEO_PARSER) += fate-wtv-demux -fate-wtv-demux: CMD = framecrc -i $(TARGET_SAMPLES)/wtv/law-and-order-partial.wtv -vcodec copy -acodec copy +fate-wtv-demux: CMD = framecrc -i $(TARGET_SAMPLES)/wtv/law-and-order-partial.wtv -c copy FATE_SAMPLES_AVCONV-$(CONFIG_XMV_DEMUXER) += fate-xmv-demux -fate-xmv-demux: CMD = framecrc -i $(TARGET_SAMPLES)/xmv/logos1p.fmv -vcodec copy -acodec copy +fate-xmv-demux: CMD = framecrc -i $(TARGET_SAMPLES)/xmv/logos1p.fmv -c copy FATE_SAMPLES_AVCONV-$(CONFIG_XWMA_DEMUXER) += fate-xwma-demux -fate-xwma-demux: CMD = crc -i $(TARGET_SAMPLES)/xwma/ergon.xwma -acodec copy +fate-xwma-demux: CMD = crc -i $(TARGET_SAMPLES)/xwma/ergon.xwma -c:a copy diff --git a/tests/fate/h264.mak b/tests/fate/h264.mak index 3d6fde7bdb732..bdc390d4793f9 100644 --- a/tests/fate/h264.mak +++ b/tests/fate/h264.mak @@ -386,7 +386,7 @@ fate-h264-conformance-sva_fm1_e: CMD = framecrc -i $(TARGET_SAM fate-h264-conformance-sva_nl1_b: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/SVA_NL1_B.264 fate-h264-conformance-sva_nl2_e: CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/SVA_NL2_E.264 -fate-h264-bsf-mp4toannexb: CMD = md5 -i $(TARGET_SAMPLES)/h264/interlaced_crop.mp4 -vcodec copy -bsf h264_mp4toannexb -f h264 +fate-h264-bsf-mp4toannexb: CMD = md5 -i $(TARGET_SAMPLES)/h264/interlaced_crop.mp4 -c:v copy -bsf h264_mp4toannexb -f h264 fate-h264-crop-to-container: CMD = framemd5 -i $(TARGET_SAMPLES)/h264/crop-to-container-dims-canon.mov fate-h264-direct-bff: CMD = framecrc -i $(TARGET_SAMPLES)/h264/direct-bff.mkv fate-h264-extradata-reload: CMD = framemd5 -i $(TARGET_SAMPLES)/h264/extradata-reload-multi-stsd.mov diff --git a/tests/fate/microsoft.mak b/tests/fate/microsoft.mak index de53f00d33af3..5b32c7fd742d2 100644 --- a/tests/fate/microsoft.mak +++ b/tests/fate/microsoft.mak @@ -39,7 +39,7 @@ FATE_WMV8_DRM += fate-wmv8-drm fate-wmv8-drm: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(TARGET_SAMPLES)/wmv8/wmv_drm.wmv -an -frames:v 129 FATE_WMV8_DRM += fate-wmv8-drm-nodec -fate-wmv8-drm-nodec: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(TARGET_SAMPLES)/wmv8/wmv_drm.wmv -acodec copy -vcodec copy +fate-wmv8-drm-nodec: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(TARGET_SAMPLES)/wmv8/wmv_drm.wmv -c copy FATE_SAMPLES_AVCONV-$(call DEMDEC, ASF, WMV3) += $(FATE_WMV8_DRM) fate-wmv8_drm: $(FATE_WMV8_DRM) diff --git a/tests/fate/mp3.mak b/tests/fate/mp3.mak index 78832cb9f2482..3af3135071530 100644 --- a/tests/fate/mp3.mak +++ b/tests/fate/mp3.mak @@ -1,29 +1,29 @@ FATE_MP3 += fate-mp3-float-conf-compl -fate-mp3-float-conf-compl: CMD = avconv -acodec mp3float -i $(TARGET_SAMPLES)/mp3-conformance/compl.bit -f f32le - +fate-mp3-float-conf-compl: CMD = avconv -c:a mp3float -i $(TARGET_SAMPLES)/mp3-conformance/compl.bit -f f32le - fate-mp3-float-conf-compl: REF = $(SAMPLES)/mp3-conformance/compl.f32 FATE_MP3 += fate-mp3-float-conf-he_32khz -fate-mp3-float-conf-he_32khz: CMD = avconv -acodec mp3float -i $(TARGET_SAMPLES)/mp3-conformance/he_32khz.bit -af atrim=end_sample=171648 -f f32le - +fate-mp3-float-conf-he_32khz: CMD = avconv -c:a mp3float -i $(TARGET_SAMPLES)/mp3-conformance/he_32khz.bit -af atrim=end_sample=171648 -f f32le - fate-mp3-float-conf-he_32khz: REF = $(SAMPLES)/mp3-conformance/he_32khz.f32 FATE_MP3 += fate-mp3-float-conf-he_44khz -fate-mp3-float-conf-he_44khz: CMD = avconv -acodec mp3float -i $(TARGET_SAMPLES)/mp3-conformance/he_44khz.bit -af atrim=end_sample=471168 -f f32le - +fate-mp3-float-conf-he_44khz: CMD = avconv -c:a mp3float -i $(TARGET_SAMPLES)/mp3-conformance/he_44khz.bit -af atrim=end_sample=471168 -f f32le - fate-mp3-float-conf-he_44khz: REF = $(SAMPLES)/mp3-conformance/he_44khz.f32 FATE_MP3 += fate-mp3-float-conf-he_48khz -fate-mp3-float-conf-he_48khz: CMD = avconv -acodec mp3float -i $(TARGET_SAMPLES)/mp3-conformance/he_48khz.bit -af atrim=end_sample=171648 -f f32le - +fate-mp3-float-conf-he_48khz: CMD = avconv -c:a mp3float -i $(TARGET_SAMPLES)/mp3-conformance/he_48khz.bit -af atrim=end_sample=171648 -f f32le - fate-mp3-float-conf-he_48khz: REF = $(SAMPLES)/mp3-conformance/he_48khz.f32 FATE_MP3 += fate-mp3-float-conf-hecommon -fate-mp3-float-conf-hecommon: CMD = avconv -acodec mp3float -i $(TARGET_SAMPLES)/mp3-conformance/hecommon.bit -af atrim=end_sample=33408 -f f32le - +fate-mp3-float-conf-hecommon: CMD = avconv -c:a mp3float -i $(TARGET_SAMPLES)/mp3-conformance/hecommon.bit -af atrim=end_sample=33408 -f f32le - fate-mp3-float-conf-hecommon: REF = $(SAMPLES)/mp3-conformance/hecommon.f32 FATE_MP3 += fate-mp3-float-conf-si -fate-mp3-float-conf-si: CMD = avconv -acodec mp3float -i $(TARGET_SAMPLES)/mp3-conformance/si.bit -af atrim=end_sample=134784 -f f32le - +fate-mp3-float-conf-si: CMD = avconv -c:a mp3float -i $(TARGET_SAMPLES)/mp3-conformance/si.bit -af atrim=end_sample=134784 -f f32le - fate-mp3-float-conf-si: REF = $(SAMPLES)/mp3-conformance/si.f32 FATE_MP3 += fate-mp3-float-conf-si_block -fate-mp3-float-conf-si_block: CMD = avconv -acodec mp3float -i $(TARGET_SAMPLES)/mp3-conformance/si_block.bit -af atrim=end_sample=72576 -f f32le - +fate-mp3-float-conf-si_block: CMD = avconv -c:a mp3float -i $(TARGET_SAMPLES)/mp3-conformance/si_block.bit -af atrim=end_sample=72576 -f f32le - fate-mp3-float-conf-si_block: REF = $(SAMPLES)/mp3-conformance/si_block.f32 FATE_MP3 += fate-mp3-float-extra_overread diff --git a/tests/fate/mpc.mak b/tests/fate/mpc.mak index 4a012737d2083..294dffeabf96a 100644 --- a/tests/fate/mpc.mak +++ b/tests/fate/mpc.mak @@ -1,8 +1,8 @@ FATE_MPC-$(CONFIG_MPC_DEMUXER) += fate-mpc7-demux -fate-mpc7-demux: CMD = crc -i $(TARGET_SAMPLES)/musepack/inside-mp7.mpc -acodec copy +fate-mpc7-demux: CMD = crc -i $(TARGET_SAMPLES)/musepack/inside-mp7.mpc -c:a copy FATE_MPC-$(CONFIG_MPC8_DEMUXER) += fate-mpc8-demux -fate-mpc8-demux: CMD = crc -i $(TARGET_SAMPLES)/musepack/inside-mp8.mpc -acodec copy +fate-mpc8-demux: CMD = crc -i $(TARGET_SAMPLES)/musepack/inside-mp8.mpc -c:a copy FATE_MPC-$(call DEMDEC, MPC, MPC7) += fate-musepack7 fate-musepack7: CMD = pcm -i $(TARGET_SAMPLES)/musepack/inside-mp7.mpc diff --git a/tests/fate/utvideo.mak b/tests/fate/utvideo.mak index 4c0c6bf460142..cbd7ad117bf6e 100644 --- a/tests/fate/utvideo.mak +++ b/tests/fate/utvideo.mak @@ -28,7 +28,7 @@ fate-utvideo_yuv422_median: CMD = framecrc -i $(TARGET_SAMPLES)/utvideo/utvideo_ FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, UTVIDEO) += $(FATE_UTVIDEO) fate-utvideo: $(FATE_UTVIDEO) -fate-utvideoenc%: CMD = framemd5 -f image2 -vcodec pgmyuv -i $(TARGET_PATH)/tests/vsynth1/%02d.pgm -vcodec utvideo -slices 1 -f avi -sws_flags +accurate_rnd+bitexact ${OPTS} +fate-utvideoenc%: CMD = framemd5 -f image2 -c:v pgmyuv -i $(TARGET_PATH)/tests/vsynth1/%02d.pgm -c:v utvideo -slices 1 -f avi -sws_flags +accurate_rnd+bitexact ${OPTS} FATE_UTVIDEOENC += fate-utvideoenc_rgba_left fate-utvideoenc_rgba_left: OPTS = -pix_fmt rgba -pred left diff --git a/tests/fate/video.mak b/tests/fate/video.mak index bd5d3ca3b2a89..fd15e83c39f5f 100644 --- a/tests/fate/video.mak +++ b/tests/fate/video.mak @@ -140,7 +140,7 @@ FATE_SAMPLES_AVCONV-$(call DEMDEC, IDCIN, IDCIN) += fate-id-cin-video fate-id-cin-video: CMD = framecrc -i $(TARGET_SAMPLES)/idcin/idlog-2MB.cin -pix_fmt rgb24 FATE_SAMPLES_AVCONV-$(call ENCDEC, ROQ PGMYUV, ROQ IMAGE2) += fate-idroq-video-encode -fate-idroq-video-encode: CMD = md5 -f image2 -vcodec pgmyuv -i $(TARGET_SAMPLES)/ffmpeg-synthetic/vsynth1/%02d.pgm -sws_flags +bitexact -vf pad=512:512:80:112 -f roq -t 0.2 +fate-idroq-video-encode: CMD = md5 -f image2 -c:v pgmyuv -i $(TARGET_SAMPLES)/ffmpeg-synthetic/vsynth1/%02d.pgm -sws_flags +bitexact -vf pad=512:512:80:112 -f roq -t 0.2 FATE_HAP += fate-hap1 fate-hap1: CMD = framecrc -i $(TARGET_SAMPLES)/hap/hap1.mov @@ -308,7 +308,7 @@ fate-v410dec: CMD = framecrc -i $(TARGET_SAMPLES)/v410/lenav410.mov -pix_fmt yuv FATE_SAMPLES_AVCONV-$(call ENCDEC, V410 PGMYUV, AVI IMAGE2) += fate-v410enc fate-v410enc: $(VREF) -fate-v410enc: CMD = md5 -f image2 -vcodec pgmyuv -i $(TARGET_PATH)/tests/vsynth1/%02d.pgm -fflags +bitexact -vcodec v410 -f avi +fate-v410enc: CMD = md5 -f image2 -c:v pgmyuv -i $(TARGET_PATH)/tests/vsynth1/%02d.pgm -fflags +bitexact -c:v v410 -f avi FATE_SAMPLES_AVCONV-$(call DEMDEC, SIFF, VB) += fate-vb fate-vb: CMD = framecrc -i $(TARGET_SAMPLES)/SIFF/INTRO_B.VB -t 3 -pix_fmt rgb24 -an diff --git a/tests/fate/vqf.mak b/tests/fate/vqf.mak index 355bab09083a1..89dbcb1a8873f 100644 --- a/tests/fate/vqf.mak +++ b/tests/fate/vqf.mak @@ -4,4 +4,4 @@ fate-twinvq: CMP = oneoff fate-twinvq: REF = $(SAMPLES)/vqf/achterba.pcm FATE_SAMPLES_AVCONV-$(CONFIG_VQF_DEMUXER) += fate-vqf-demux -fate-vqf-demux: CMD = md5 -i $(TARGET_SAMPLES)/vqf/achterba.vqf -acodec copy -f framecrc +fate-vqf-demux: CMD = md5 -i $(TARGET_SAMPLES)/vqf/achterba.vqf -c:a copy -f framecrc diff --git a/tests/lavf-regression.sh b/tests/lavf-regression.sh index 3c18b2f051bba..fd4f5548d0a0b 100755 --- a/tests/lavf-regression.sh +++ b/tests/lavf-regression.sh @@ -14,14 +14,14 @@ eval do_$test=y do_lavf() { file=${outfile}lavf.$1 - do_avconv $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $DEC_OPTS -ar 44100 -f s16le $2 -i $pcm_src $ENC_OPTS -b:a 64k -t 1 -qscale:v 10 $3 + do_avconv $file $DEC_OPTS -f image2 -c:v pgmyuv -i $raw_src $DEC_OPTS -ar 44100 -f s16le $2 -i $pcm_src $ENC_OPTS -b:a 64k -t 1 -qscale:v 10 $3 do_avconv_crc $file $DEC_OPTS -i $target_path/$file $4 } do_streamed_images() { file=${outfile}${1}pipe.$1 - do_avconv $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src -f image2pipe $ENC_OPTS -t 1 -qscale 10 + do_avconv $file $DEC_OPTS -f image2 -c:v pgmyuv -i $raw_src -f image2pipe $ENC_OPTS -t 1 -qscale 10 do_avconv_crc $file $DEC_OPTS -f image2pipe -i $target_path/$file } @@ -30,7 +30,7 @@ do_image_formats() outfile="$datadir/images/$1/" mkdir -p "$outfile" file=${outfile}%02d.$1 - run_avconv $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $2 $ENC_OPTS $3 -frames 12 -y -qscale 10 $target_path/$file + run_avconv $DEC_OPTS -f image2 -c:v pgmyuv -i $raw_src $2 $ENC_OPTS $3 -frames 12 -y -qscale 10 $target_path/$file do_md5sum ${outfile}02.$1 do_avconv_crc $file $DEC_OPTS $3 -i $target_path/$file echo $(wc -c ${outfile}02.$1) @@ -44,16 +44,16 @@ do_audio_only() } if [ -n "$do_avi" ] ; then -do_lavf avi "" "-acodec mp2 -ar 44100" +do_lavf avi "" "-c:a mp2 -ar 44100" fi if [ -n "$do_asf" ] ; then -do_lavf asf "" "-acodec mp2 -ar 44100" "-r 25" +do_lavf asf "" "-c:a mp2 -ar 44100" "-r 25" fi if [ -n "$do_rm" ] ; then file=${outfile}lavf.rm -do_avconv $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $DEC_OPTS -ar 44100 -f s16le -i $pcm_src $ENC_OPTS -t 1 -qscale 10 -acodec ac3_fixed -b:a 64k +do_avconv $file $DEC_OPTS -f image2 -c:v pgmyuv -i $raw_src $DEC_OPTS -ar 44100 -f s16le -i $pcm_src $ENC_OPTS -t 1 -qscale 10 -c:a ac3_fixed -b:a 64k # broken #do_avconv_crc $file -i $target_path/$file fi @@ -67,7 +67,7 @@ do_lavf mxf "-ar 48000" "-bf 2 -timecode_frame_start 264363" fi if [ -n "$do_mxf_d10" ]; then -do_lavf mxf_d10 "-ar 48000 -ac 2" "-r 25 -vf scale=720:576,pad=720:608:0:32 -vcodec mpeg2video -g 0 -flags +ildct+low_delay -dc 10 -non_linear_quant 1 -intra_vlc 1 -qscale 1 -ps 1 -qmin 1 -rc_max_vbv_use 1 -rc_min_vbv_use 1 -pix_fmt yuv422p -minrate 30000k -maxrate 30000k -b 30000k -bufsize 1200000 -top 1 -rc_init_occupancy 1200000 -qmax 12 -f mxf_d10" +do_lavf mxf_d10 "-ar 48000 -ac 2" "-r 25 -vf scale=720:576,pad=720:608:0:32 -c:v mpeg2video -g 0 -flags +ildct+low_delay -dc 10 -non_linear_quant 1 -intra_vlc 1 -qscale 1 -ps 1 -qmin 1 -rc_max_vbv_use 1 -rc_min_vbv_use 1 -pix_fmt yuv422p -minrate 30000k -maxrate 30000k -b 30000k -bufsize 1200000 -top 1 -rc_init_occupancy 1200000 -qmax 12 -f mxf_d10" fi if [ -n "$do_ts" ] ; then @@ -83,7 +83,7 @@ do_lavf flv "" "-an" fi if [ -n "$do_mov" ] ; then -do_lavf mov "" "-acodec pcm_alaw -c:v mpeg4" +do_lavf mov "" "-c:a pcm_alaw -c:v mpeg4" fi if [ -n "$do_dv_fmt" ] ; then @@ -95,7 +95,7 @@ do_lavf gxf "-ar 48000" "-r 25 -s pal -ac 1" fi if [ -n "$do_nut" ] ; then -do_lavf nut "" "-acodec mp2 -ar 44100" +do_lavf nut "" "-c:a mp2 -ar 44100" fi if [ -n "$do_mkv" ] ; then @@ -106,7 +106,7 @@ fi # streamed images # mjpeg #file=${outfile}lavf.mjpeg -#do_avconv $file -t 1 -qscale 10 -f image2 -vcodec pgmyuv -i $raw_src +#do_avconv $file -t 1 -qscale 10 -f image2 -c:v pgmyuv -i $raw_src #do_avconv_crc $file -i $target_path/$file if [ -n "$do_pbmpipe" ] ; then @@ -123,13 +123,13 @@ fi if [ -n "$do_gif" ] ; then file=${outfile}lavf.gif -do_avconv $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $ENC_OPTS -t 1 -qscale 10 -pix_fmt rgb24 +do_avconv $file $DEC_OPTS -f image2 -c:v pgmyuv -i $raw_src $ENC_OPTS -t 1 -qscale 10 -pix_fmt rgb24 do_avconv_crc $file $DEC_OPTS -i $target_path/$file -pix_fmt rgb24 fi if [ -n "$do_yuv4mpeg" ] ; then file=${outfile}lavf.y4m -do_avconv $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $ENC_OPTS -t 1 -qscale 10 +do_avconv $file $DEC_OPTS -f image2 -c:v pgmyuv -i $raw_src $ENC_OPTS -t 1 -qscale 10 #do_avconv_crc $file -i $target_path/$file fi @@ -218,7 +218,7 @@ do_audio_only voc fi if [ -n "$do_voc_s16" ] ; then -do_audio_only s16.voc "-ac 2" "-acodec pcm_s16le" +do_audio_only s16.voc "-ac 2" "-c:a pcm_s16le" fi if [ -n "$do_ogg" ] ; then @@ -243,7 +243,7 @@ conversions="yuv420p yuv422p yuv444p yuyv422 yuv410p yuv411p yuvj420p \ monob yuv440p yuvj440p" for pix_fmt in $conversions ; do file=${outfile}${pix_fmt}.yuv - run_avconv $DEC_OPTS -r 1 -f image2 -vcodec pgmyuv -i $raw_src \ + run_avconv $DEC_OPTS -r 1 -f image2 -c:v pgmyuv -i $raw_src \ $ENC_OPTS -f rawvideo -t 1 -s 352x288 -pix_fmt $pix_fmt $target_path/$raw_dst do_avconv $file $DEC_OPTS -f rawvideo -s 352x288 -pix_fmt $pix_fmt -i $target_path/$raw_dst \ $ENC_OPTS -f rawvideo -s 352x288 -pix_fmt yuv444p From 150e99d694f33ab9ad678834964909aa315d14a1 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 20 Feb 2017 00:04:59 +0100 Subject: [PATCH 0960/3374] rtsp: Factor out packet reading --- libavformat/rtsp.c | 66 ++++++++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 7e5985719e900..e75670867a0a8 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -2043,6 +2043,44 @@ static int pick_stream(AVFormatContext *s, RTSPStream **rtsp_st, return AVERROR(EAGAIN); } +static int read_packet(AVFormatContext *s, + RTSPStream **rtsp_st, RTSPStream *first_queue_st, + int64_t wait_end) +{ + RTSPState *rt = s->priv_data; + int len; + + switch(rt->lower_transport) { + default: +#if CONFIG_RTSP_DEMUXER + case RTSP_LOWER_TRANSPORT_TCP: + len = ff_rtsp_tcp_read_packet(s, rtsp_st, rt->recvbuf, RECVBUF_SIZE); + break; +#endif + case RTSP_LOWER_TRANSPORT_UDP: + case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: + len = udp_read_packet(s, rtsp_st, rt->recvbuf, RECVBUF_SIZE, wait_end); + if (len > 0 && (*rtsp_st)->transport_priv && rt->transport == RTSP_TRANSPORT_RTP) + ff_rtp_check_and_send_back_rr((*rtsp_st)->transport_priv, (*rtsp_st)->rtp_handle, NULL, len); + break; + case RTSP_LOWER_TRANSPORT_CUSTOM: + if (first_queue_st && rt->transport == RTSP_TRANSPORT_RTP && + wait_end && wait_end < av_gettime_relative()) + len = AVERROR(EAGAIN); + else + len = ffio_read_partial(s->pb, rt->recvbuf, RECVBUF_SIZE); + len = pick_stream(s, rtsp_st, rt->recvbuf, len); + if (len > 0 && (*rtsp_st)->transport_priv && rt->transport == RTSP_TRANSPORT_RTP) + ff_rtp_check_and_send_back_rr((*rtsp_st)->transport_priv, NULL, s->pb, len); + break; + } + + if (len == 0) + return AVERROR_EOF; + + return len; +} + int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt) { RTSPState *rt = s->priv_data; @@ -2107,30 +2145,7 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR(ENOMEM); } - switch(rt->lower_transport) { - default: -#if CONFIG_RTSP_DEMUXER - case RTSP_LOWER_TRANSPORT_TCP: - len = ff_rtsp_tcp_read_packet(s, &rtsp_st, rt->recvbuf, RECVBUF_SIZE); - break; -#endif - case RTSP_LOWER_TRANSPORT_UDP: - case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: - len = udp_read_packet(s, &rtsp_st, rt->recvbuf, RECVBUF_SIZE, wait_end); - if (len > 0 && rtsp_st->transport_priv && rt->transport == RTSP_TRANSPORT_RTP) - ff_rtp_check_and_send_back_rr(rtsp_st->transport_priv, rtsp_st->rtp_handle, NULL, len); - break; - case RTSP_LOWER_TRANSPORT_CUSTOM: - if (first_queue_st && rt->transport == RTSP_TRANSPORT_RTP && - wait_end && wait_end < av_gettime_relative()) - len = AVERROR(EAGAIN); - else - len = ffio_read_partial(s->pb, rt->recvbuf, RECVBUF_SIZE); - len = pick_stream(s, &rtsp_st, rt->recvbuf, len); - if (len > 0 && rtsp_st->transport_priv && rt->transport == RTSP_TRANSPORT_RTP) - ff_rtp_check_and_send_back_rr(rtsp_st->transport_priv, NULL, s->pb, len); - break; - } + len = read_packet(s, &rtsp_st, first_queue_st, wait_end); if (len == AVERROR(EAGAIN) && first_queue_st && rt->transport == RTSP_TRANSPORT_RTP) { av_log(s, AV_LOG_WARNING, @@ -2141,8 +2156,7 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt) } if (len < 0) return len; - if (len == 0) - return AVERROR_EOF; + if (rt->transport == RTSP_TRANSPORT_RDT) { ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len); } else if (rt->transport == RTSP_TRANSPORT_RTP) { From b9b82151a1aaa8bbf389853a6142c4e101d80b86 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 20 Feb 2017 00:50:34 +0100 Subject: [PATCH 0961/3374] rtsp: Move the pollfd setup out of the for loop --- libavformat/rtsp.c | 56 +++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index e75670867a0a8..e4cbae43a291e 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -1920,39 +1920,39 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, struct pollfd *p = rt->p; int *fds = NULL, fdsnum, fdsidx; + if (rt->rtsp_hd) { + tcp_fd = ffurl_get_file_handle(rt->rtsp_hd); + p[max_p].fd = tcp_fd; + p[max_p++].events = POLLIN; + } else { + tcp_fd = -1; + } + for (i = 0; i < rt->nb_rtsp_streams; i++) { + rtsp_st = rt->rtsp_streams[i]; + if (rtsp_st->rtp_handle) { + if (ret = ffurl_get_multi_file_handle(rtsp_st->rtp_handle, + &fds, &fdsnum)) { + av_log(s, AV_LOG_ERROR, "Unable to recover rtp ports\n"); + return ret; + } + if (fdsnum != 2) { + av_log(s, AV_LOG_ERROR, + "Number of fds %d not supported\n", fdsnum); + return AVERROR_INVALIDDATA; + } + for (fdsidx = 0; fdsidx < fdsnum; fdsidx++) { + p[max_p].fd = fds[fdsidx]; + p[max_p++].events = POLLIN; + } + av_free(fds); + } + } + for (;;) { if (ff_check_interrupt(&s->interrupt_callback)) return AVERROR_EXIT; if (wait_end && wait_end - av_gettime_relative() < 0) return AVERROR(EAGAIN); - max_p = 0; - if (rt->rtsp_hd) { - tcp_fd = ffurl_get_file_handle(rt->rtsp_hd); - p[max_p].fd = tcp_fd; - p[max_p++].events = POLLIN; - } else { - tcp_fd = -1; - } - for (i = 0; i < rt->nb_rtsp_streams; i++) { - rtsp_st = rt->rtsp_streams[i]; - if (rtsp_st->rtp_handle) { - if (ret = ffurl_get_multi_file_handle(rtsp_st->rtp_handle, - &fds, &fdsnum)) { - av_log(s, AV_LOG_ERROR, "Unable to recover rtp ports\n"); - return ret; - } - if (fdsnum != 2) { - av_log(s, AV_LOG_ERROR, - "Number of fds %d not supported\n", fdsnum); - return AVERROR_INVALIDDATA; - } - for (fdsidx = 0; fdsidx < fdsnum; fdsidx++) { - p[max_p].fd = fds[fdsidx]; - p[max_p++].events = POLLIN; - } - av_free(fds); - } - } n = poll(p, max_p, POLL_TIMEOUT_MS); if (n > 0) { int j = 1 - (tcp_fd == -1); From 5263f464db5f2df74ddf712f6d1221b24475fa8e Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 20 Feb 2017 02:11:58 +0100 Subject: [PATCH 0962/3374] rtsp: Lazily allocate the pollfd array And use av_malloc_array. --- libavformat/rtsp.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index e4cbae43a291e..4ff12c63dd617 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -662,7 +662,6 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1, int ff_sdp_parse(AVFormatContext *s, const char *content) { - RTSPState *rt = s->priv_data; const char *p; int letter, i; /* Some SDP lines, particularly for Realmedia or ASF RTSP streams, @@ -709,8 +708,6 @@ int ff_sdp_parse(AVFormatContext *s, const char *content) av_free(s1->default_exclude_source_addrs[i]); av_freep(&s1->default_exclude_source_addrs); - rt->p = av_malloc(sizeof(struct pollfd)*2*(rt->nb_rtsp_streams+1)); - if (!rt->p) return AVERROR(ENOMEM); return 0; } #endif /* CONFIG_RTPDEC */ @@ -1920,6 +1917,12 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, struct pollfd *p = rt->p; int *fds = NULL, fdsnum, fdsidx; + if (!p) { + p = rt->p = av_malloc_array(2 * (rt->nb_rtsp_streams + 1), sizeof(struct pollfd)); + if (!p) + return AVERROR(ENOMEM); + } + if (rt->rtsp_hd) { tcp_fd = ffurl_get_file_handle(rt->rtsp_hd); p[max_p].fd = tcp_fd; From c483398bb7ef66f61ed2dcb09f3d6160683da0eb Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 22 Feb 2017 14:18:47 +0100 Subject: [PATCH 0963/3374] build: Drop DOC_ prefix from EXAMPLES-related variables --- doc/examples/Makefile | 46 +++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/doc/examples/Makefile b/doc/examples/Makefile index c42c68fd5459c..40c9557fbc2fb 100644 --- a/doc/examples/Makefile +++ b/doc/examples/Makefile @@ -1,31 +1,31 @@ -DOC_EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE) += decode_audio -DOC_EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE) += decode_video -DOC_EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE) += encode_audio -DOC_EXAMPLES-$(CONFIG_ENCODE_VIDEO_EXAMPLE) += encode_video -DOC_EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE) += filter_audio -DOC_EXAMPLES-$(CONFIG_METADATA_EXAMPLE) += metadata -DOC_EXAMPLES-$(CONFIG_OUTPUT_EXAMPLE) += output -DOC_EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE) += qsvdec -DOC_EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac - -DOC_EXAMPLES := $(DOC_EXAMPLES-yes:%=doc/examples/%$(EXESUF)) -ALL_DOC_EXAMPLES := $(DOC_EXAMPLES) $(DOC_EXAMPLES-:%=doc/examples/%$(EXESUF)) -PROGS += $(DOC_EXAMPLES) - -$(foreach P,$(DOC_EXAMPLES),$(eval OBJS-$(P:%$(EXESUF)=%) = $(P:%$(EXESUF)=%).o)) -$(DOC_EXAMPLES): %$(EXESUF): %.o - -examples: $(DOC_EXAMPLES) - -$(DOC_EXAMPLES:%$(EXESUF)=%.o): | doc/examples +EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE) += decode_audio +EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE) += decode_video +EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE) += encode_audio +EXAMPLES-$(CONFIG_ENCODE_VIDEO_EXAMPLE) += encode_video +EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE) += filter_audio +EXAMPLES-$(CONFIG_METADATA_EXAMPLE) += metadata +EXAMPLES-$(CONFIG_OUTPUT_EXAMPLE) += output +EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE) += qsvdec +EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac + +EXAMPLES := $(EXAMPLES-yes:%=doc/examples/%$(EXESUF)) +ALL_EXAMPLES := $(EXAMPLES) $(EXAMPLES-:%=doc/examples/%$(EXESUF)) +PROGS += $(EXAMPLES) + +$(foreach P,$(EXAMPLES),$(eval OBJS-$(P:%$(EXESUF)=%) = $(P:%$(EXESUF)=%).o)) +$(EXAMPLES): %$(EXESUF): %.o + +examples: $(EXAMPLES) + +$(EXAMPLES:%$(EXESUF)=%.o): | doc/examples OBJDIRS += doc/examples -DOXY_INPUT += $(addprefix $(SRC_PATH)/, $(DOC_EXAMPLES:%$(EXESUF)=%.c)) +DOXY_INPUT += $(addprefix $(SRC_PATH)/, $(EXAMPLES:%$(EXESUF)=%.c)) clean:: - $(RM) $(ALL_DOC_EXAMPLES) + $(RM) $(ALL_EXAMPLES) $(RM) $(CLEANSUFFIXES:%=doc/examples/%) --include $(wildcard $(DOC_EXAMPLES:%$(EXESUF)=%.d)) +-include $(wildcard $(EXAMPLES:%$(EXESUF)=%.d)) .PHONY: examples From 698ac8f9cabd053f2c19346a77b92f8eae4218fc Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 15 Oct 2012 15:38:29 +0200 Subject: [PATCH 0964/3374] fate: Make null comparison method more useful This allows dropping /dev/null as reference value when no output is generated. --- tests/fate-run.sh | 2 +- tests/fate/libavcodec.mak | 4 +--- tests/fate/libavutil.mak | 13 ++++++------- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/tests/fate-run.sh b/tests/fate-run.sh index 43fcee02abf15..21111403a60f2 100755 --- a/tests/fate-run.sh +++ b/tests/fate-run.sh @@ -203,7 +203,7 @@ if [ $err -gt 128 ]; then test "${sig}" = "${sig%[!A-Za-z]*}" || unset sig fi -if test -e "$ref" || test $cmp = "oneline" ; then +if test -e "$ref" || test $cmp = "oneline" || test $cmp = "null" ; then case $cmp in diff) diff -u -b "$ref" "$outfile" >$cmpfile ;; oneoff) oneoff "$ref" "$outfile" >$cmpfile ;; diff --git a/tests/fate/libavcodec.mak b/tests/fate/libavcodec.mak index d656acefb773d..0bbe57223f06c 100644 --- a/tests/fate/libavcodec.mak +++ b/tests/fate/libavcodec.mak @@ -1,13 +1,12 @@ FATE_LIBAVCODEC-$(CONFIG_GOLOMB) += fate-golomb fate-golomb: libavcodec/tests/golomb$(EXESUF) fate-golomb: CMD = run libavcodec/tests/golomb -fate-golomb: REF = /dev/null +fate-golomb: CMP = null FATE_LIBAVCODEC-$(CONFIG_IDCTDSP) += fate-idct8x8 fate-idct8x8: libavcodec/tests/dct$(EXESUF) fate-idct8x8: CMD = run libavcodec/tests/dct -i fate-idct8x8: CMP = null -fate-idct8x8: REF = /dev/null FATE_LIBAVCODEC-$(CONFIG_IIRFILTER) += fate-iirfilter fate-iirfilter: libavcodec/tests/iirfilter$(EXESUF) @@ -17,7 +16,6 @@ FATE_LIBAVCODEC-$(CONFIG_RANGECODER) += fate-rangecoder fate-rangecoder: libavcodec/tests/rangecoder$(EXESUF) fate-rangecoder: CMD = run libavcodec/tests/rangecoder fate-rangecoder: CMP = null -fate-rangecoder: REF = /dev/null FATE-$(CONFIG_AVCODEC) += $(FATE_LIBAVCODEC-yes) fate-libavcodec: $(FATE_LIBAVCODEC-yes) diff --git a/tests/fate/libavutil.mak b/tests/fate/libavutil.mak index 8b174113701a6..e0a669310be96 100644 --- a/tests/fate/libavutil.mak +++ b/tests/fate/libavutil.mak @@ -1,12 +1,12 @@ FATE_LIBAVUTIL += fate-adler32 fate-adler32: libavutil/tests/adler32$(EXESUF) fate-adler32: CMD = run libavutil/tests/adler32 -fate-adler32: REF = /dev/null +fate-adler32: CMP = null FATE_LIBAVUTIL += fate-aes fate-aes: libavutil/tests/aes$(EXESUF) fate-aes: CMD = run libavutil/tests/aes -fate-aes: REF = /dev/null +fate-aes: CMP = null FATE_LIBAVUTIL += fate-avstring fate-avstring: libavutil/tests/avstring$(EXESUF) @@ -23,12 +23,12 @@ fate-blowfish: CMD = run libavutil/tests/blowfish FATE_LIBAVUTIL += fate-cpu fate-cpu: libavutil/tests/cpu$(EXESUF) fate-cpu: CMD = run libavutil/tests/cpu $(CPUFLAGS:%=-c%) $(THREADS:%=-t%) -fate-cpu: REF = /dev/null +fate-cpu: CMP = null FATE_LIBAVUTIL-$(HAVE_THREADS) += fate-cpu_init fate-cpu_init: libavutil/tests/cpu_init$(EXESUF) fate-cpu_init: CMD = run libavutil/tests/cpu_init -fate-cpu_init: REF = /dev/null +fate-cpu_init: CMP = null FATE_LIBAVUTIL += fate-crc fate-crc: libavutil/tests/crc$(EXESUF) @@ -37,7 +37,7 @@ fate-crc: CMD = run libavutil/tests/crc FATE_LIBAVUTIL += fate-des fate-des: libavutil/tests/des$(EXESUF) fate-des: CMD = run libavutil/tests/des -fate-des: REF = /dev/null +fate-des: CMP = null FATE_LIBAVUTIL += fate-eval fate-eval: libavutil/tests/eval$(EXESUF) @@ -51,7 +51,6 @@ FATE_LIBAVUTIL += fate-float-dsp fate-float-dsp: libavutil/tests/float_dsp$(EXESUF) fate-float-dsp: CMD = run libavutil/tests/float_dsp fate-float-dsp: CMP = null -fate-float-dsp: REF = /dev/null FATE_LIBAVUTIL += fate-hmac fate-hmac: libavutil/tests/hmac$(EXESUF) @@ -72,7 +71,7 @@ fate-sha: CMD = run libavutil/tests/sha FATE_LIBAVUTIL += fate-tree fate-tree: libavutil/tests/tree$(EXESUF) fate-tree: CMD = run libavutil/tests/tree -fate-tree: REF = /dev/null +fate-tree: CMP = null FATE_LIBAVUTIL += fate-xtea fate-xtea: libavutil/tests/xtea$(EXESUF) From d8f36a6aa33e9f904fa47caa0329ddaac391cd7d Mon Sep 17 00:00:00 2001 From: Ben Chang Date: Fri, 24 Feb 2017 14:39:21 -0800 Subject: [PATCH 0965/3374] nvenc: Fix the preset mapping list The map is a sparse array and does not need a empty element to terminate it. The empty element is stored after the last one inserted in the list, overwriting whichever element was next with zeros. Bug-Id: 1029 Signed-off-by: Luca Barbato --- libavcodec/nvenc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index ffa8a0a2d8d8f..fcd496b93f1d5 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -495,8 +495,7 @@ static int nvenc_map_preset(NVENCContext *ctx) PRESET(LOSSLESS_HP, NVENC_LOSSLESS), PRESET_ALIAS(SLOW, HQ, NVENC_TWO_PASSES), PRESET_ALIAS(MEDIUM, HQ, NVENC_ONE_PASS), - PRESET_ALIAS(FAST, HP, NVENC_ONE_PASS), - { { 0 } } + PRESET_ALIAS(FAST, HP, NVENC_ONE_PASS) }; GUIDTuple *t = &presets[ctx->preset]; From 79331df362fb05a0d04ca9489c87e5b80077a3f4 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 20 Feb 2017 02:16:28 +0100 Subject: [PATCH 0966/3374] rtsp: Lazily set up the pollfd array once --- libavformat/rtsp.c | 53 +++++++++++++++++++++++----------------------- libavformat/rtsp.h | 1 + 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 4ff12c63dd617..141477bbbfee4 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -1913,7 +1913,6 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, RTSPState *rt = s->priv_data; RTSPStream *rtsp_st; int n, i, ret, tcp_fd, timeout_cnt = 0; - int max_p = 0; struct pollfd *p = rt->p; int *fds = NULL, fdsnum, fdsidx; @@ -1921,33 +1920,33 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, p = rt->p = av_malloc_array(2 * (rt->nb_rtsp_streams + 1), sizeof(struct pollfd)); if (!p) return AVERROR(ENOMEM); - } - if (rt->rtsp_hd) { - tcp_fd = ffurl_get_file_handle(rt->rtsp_hd); - p[max_p].fd = tcp_fd; - p[max_p++].events = POLLIN; - } else { - tcp_fd = -1; - } - for (i = 0; i < rt->nb_rtsp_streams; i++) { - rtsp_st = rt->rtsp_streams[i]; - if (rtsp_st->rtp_handle) { - if (ret = ffurl_get_multi_file_handle(rtsp_st->rtp_handle, - &fds, &fdsnum)) { - av_log(s, AV_LOG_ERROR, "Unable to recover rtp ports\n"); - return ret; - } - if (fdsnum != 2) { - av_log(s, AV_LOG_ERROR, - "Number of fds %d not supported\n", fdsnum); - return AVERROR_INVALIDDATA; - } - for (fdsidx = 0; fdsidx < fdsnum; fdsidx++) { - p[max_p].fd = fds[fdsidx]; - p[max_p++].events = POLLIN; + if (rt->rtsp_hd) { + tcp_fd = ffurl_get_file_handle(rt->rtsp_hd); + p[rt->max_p].fd = tcp_fd; + p[rt->max_p++].events = POLLIN; + } else { + tcp_fd = -1; + } + for (i = 0; i < rt->nb_rtsp_streams; i++) { + rtsp_st = rt->rtsp_streams[i]; + if (rtsp_st->rtp_handle) { + if (ret = ffurl_get_multi_file_handle(rtsp_st->rtp_handle, + &fds, &fdsnum)) { + av_log(s, AV_LOG_ERROR, "Unable to recover rtp ports\n"); + return ret; + } + if (fdsnum != 2) { + av_log(s, AV_LOG_ERROR, + "Number of fds %d not supported\n", fdsnum); + return AVERROR_INVALIDDATA; + } + for (fdsidx = 0; fdsidx < fdsnum; fdsidx++) { + p[rt->max_p].fd = fds[fdsidx]; + p[rt->max_p++].events = POLLIN; + } + av_free(fds); } - av_free(fds); } } @@ -1956,7 +1955,7 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, return AVERROR_EXIT; if (wait_end && wait_end - av_gettime_relative() < 0) return AVERROR(EAGAIN); - n = poll(p, max_p, POLL_TIMEOUT_MS); + n = poll(p, rt->max_p, POLL_TIMEOUT_MS); if (n > 0) { int j = 1 - (tcp_fd == -1); timeout_cnt = 0; diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h index ff5b53207eb68..9dfbc5367f9f7 100644 --- a/libavformat/rtsp.h +++ b/libavformat/rtsp.h @@ -352,6 +352,7 @@ typedef struct RTSPState { * Polling array for udp */ struct pollfd *p; + int max_p; /** * Whether the server supports the GET_PARAMETER method. From e1a6d63c7eeff2f0ec8173546357bfaa9deecea4 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 18 Oct 2012 12:34:23 +0200 Subject: [PATCH 0967/3374] fate: Rename WMV8_DRM decoder tests to WMV3_DRM The codec used in those files is WMV3/WMV9, not WMV2/WMV8. --- tests/fate/microsoft.mak | 12 ++++++------ tests/ref/fate/{wmv8-drm => wmv3-drm-dec} | 0 tests/ref/fate/{wmv8-drm-nodec => wmv3-drm-nodec} | 0 3 files changed, 6 insertions(+), 6 deletions(-) rename tests/ref/fate/{wmv8-drm => wmv3-drm-dec} (100%) rename tests/ref/fate/{wmv8-drm-nodec => wmv3-drm-nodec} (100%) diff --git a/tests/fate/microsoft.mak b/tests/fate/microsoft.mak index 5b32c7fd742d2..5c0133d8fd84a 100644 --- a/tests/fate/microsoft.mak +++ b/tests/fate/microsoft.mak @@ -34,15 +34,15 @@ fate-msvideo1: $(FATE_MSVIDEO1) FATE_SAMPLES_AVCONV-$(call DEMDEC, ASF, MTS2) += fate-mts2 fate-mts2: CMD = framecrc -i $(TARGET_SAMPLES)/mts2/ScreenCapture.xesc -FATE_WMV8_DRM += fate-wmv8-drm +FATE_WMV3_DRM += fate-wmv3-drm-dec # discard last packet to avoid fails due to overread of VC-1 decoder -fate-wmv8-drm: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(TARGET_SAMPLES)/wmv8/wmv_drm.wmv -an -frames:v 129 +fate-wmv3-drm-dec: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(TARGET_SAMPLES)/wmv3/wmv_drm.wmv -an -frames:v 129 -FATE_WMV8_DRM += fate-wmv8-drm-nodec -fate-wmv8-drm-nodec: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(TARGET_SAMPLES)/wmv8/wmv_drm.wmv -c copy +FATE_WMV3_DRM += fate-wmv3-drm-nodec +fate-wmv3-drm-nodec: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(TARGET_SAMPLES)/wmv3/wmv_drm.wmv -c copy -FATE_SAMPLES_AVCONV-$(call DEMDEC, ASF, WMV3) += $(FATE_WMV8_DRM) -fate-wmv8_drm: $(FATE_WMV8_DRM) +FATE_SAMPLES_AVCONV-$(call DEMDEC, ASF, WMV3) += $(FATE_WMV3_DRM) +fate-wmv3-drm: $(FATE_WMV3_DRM) FATE_SAMPLES_AVCONV-$(call DEMDEC, ASF, WMV2) += fate-wmv8-intrax8 fate-wmv8-intrax8: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/wmv8/wmv8_x8intra.wmv -an diff --git a/tests/ref/fate/wmv8-drm b/tests/ref/fate/wmv3-drm-dec similarity index 100% rename from tests/ref/fate/wmv8-drm rename to tests/ref/fate/wmv3-drm-dec diff --git a/tests/ref/fate/wmv8-drm-nodec b/tests/ref/fate/wmv3-drm-nodec similarity index 100% rename from tests/ref/fate/wmv8-drm-nodec rename to tests/ref/fate/wmv3-drm-nodec From 21cca00dfeaec08ca93cf94ed33f4311cf1d8c84 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 24 Feb 2017 14:00:24 +0100 Subject: [PATCH 0968/3374] build: Explicitly disable external libraries when not explicitly enabled Leaving those variables in an undefined state allows them getting implicitly enabled when they are declared as weak dependencies of other components. In that case, the library check is not run and required linker flags are not added, resulting in a failing build. Fixes linking when enabling libfreetype without libfontconfig. --- configure | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 24e9fc337fa31..eb7b6c75f8d10 100755 --- a/configure +++ b/configure @@ -1296,7 +1296,6 @@ EXTERNAL_LIBRARY_LIST=" $EXTERNAL_LIBRARY_VERSION3_LIST avisynth avxsynth - bzlib frei0r gnutls libbs2b @@ -1327,6 +1326,10 @@ EXTERNAL_LIBRARY_LIST=" libxcb libxcb_shm libxcb_xfixes +" + +SYSTEM_LIBRARY_LIST=" + bzlib zlib " @@ -1388,6 +1391,7 @@ CONFIG_LIST=" $LIBRARY_LIST $PROGRAM_LIST $SUBSYSTEM_LIST + $SYSTEM_LIBRARY_LIST neon_clobber_test pic pod2man @@ -2574,6 +2578,9 @@ enable valgrind_backtrace # By default, enable only those hwaccels that have no external dependencies. enable d3d11va dxva2 vda vdpau +# Avoid external, non-system, libraries getting enabled by dependency resolution +disable $EXTERNAL_LIBRARY_LIST + # build settings SHFLAGS='-shared -Wl,-soname,$$(@F)' LIBPREF="lib" From d7b2bb5391bf55e8f9421bff7feb4c1fddfac4bf Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 15 Feb 2017 11:34:52 -0500 Subject: [PATCH 0969/3374] h264_sei: Check actual presence of picture timing SEI message Signed-off-by: Michael Niedermayer Signed-off-by: Vittorio Giovara --- libavcodec/h264_parser.c | 4 ++-- libavcodec/h264_sei.c | 3 +++ libavcodec/h264_sei.h | 1 + libavcodec/h264_slice.c | 5 +++-- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c index 6de37c0b55db2..22153bd4e0207 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -402,7 +402,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: @@ -433,7 +433,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 4bf001ae07420..17f89cec61606 100644 --- a/libavcodec/h264_sei.c +++ b/libavcodec/h264_sei.c @@ -44,6 +44,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; @@ -109,6 +110,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 58f5ecc5a9fe4..8815aa3899ff0 100644 --- a/libavcodec/h264_sei.h +++ b/libavcodec/h264_sei.h @@ -50,6 +50,7 @@ typedef enum { } SEI_PicStructType; typedef struct H264SEIPictureTiming { + int present; SEI_PicStructType pic_struct; /** diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index f1f5fc05f9c00..427cbe618c8eb 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1004,7 +1004,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: @@ -1049,7 +1049,8 @@ 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 (cur->f->interlaced_frame || sps->pic_struct_present_flag) { + if (cur->f->interlaced_frame || + (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 || From d154bdd3d053128c908a994bb26e14bbc17f0e53 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 24 Jan 2017 13:57:52 +0100 Subject: [PATCH 0970/3374] configure: Simplify dlopen check --- configure | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/configure b/configure index eb7b6c75f8d10..85ce5f581f89c 100755 --- a/configure +++ b/configure @@ -1612,7 +1612,6 @@ SYSTEM_FUNCS=" CommandLineToArgvW CoTaskMemFree CryptGenRandom - dlopen fcntl flt_lim fork @@ -2222,10 +2221,8 @@ wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel" wmv3_vdpau_hwaccel_select="vc1_vdpau_hwaccel" # hardware-accelerated codecs -nvenc_deps_any="dlopen LoadLibrary" -nvenc_extralibs='$ldl' -omx_deps="dlopen pthreads" -omx_extralibs='$ldl' +nvenc_deps_any="libdl LoadLibrary" +omx_deps="libdl pthreads" omx_rpi_select="omx" qsvdec_select="qsv" qsvenc_select="qsv" @@ -2284,7 +2281,7 @@ mjpeg2jpeg_bsf_select="jpegtables" # external libraries avisynth_deps="LoadLibrary" -avxsynth_deps="dlopen" +avxsynth_deps="libdl" avisynth_demuxer_deps_any="avisynth avxsynth" avisynth_demuxer_select="riffdec" libdcadec_decoder_deps="libdcadec" @@ -2477,10 +2474,8 @@ deinterlace_vaapi_filter_deps="vaapi" delogo_filter_deps="gpl" drawtext_filter_deps="libfreetype" drawtext_filter_suggest="libfontconfig" -frei0r_filter_deps="frei0r dlopen" -frei0r_filter_extralibs='$ldl' -frei0r_src_filter_deps="frei0r dlopen" -frei0r_src_filter_extralibs='$ldl' +frei0r_filter_deps="frei0r libdl" +frei0r_src_filter_deps="frei0r libdl" hdcd_filter_deps="libhdcd" hqdn3d_filter_deps="gpl" interlace_filter_deps="gpl" @@ -4469,12 +4464,6 @@ check_code cc arm_neon.h "int16x8_t test = vdupq_n_s16(0)" && enable intrinsics_ check_ldflags -Wl,--as-needed -if check_func dlopen; then - ldl= -elif check_func dlopen -ldl; then - ldl=-ldl -fi - if ! disabled network; then check_func getaddrinfo $network_extralibs check_func inet_aton $network_extralibs @@ -4646,6 +4635,9 @@ enabled pthreads && disabled zlib || check_lib zlib zlib.h zlibVersion -lz disabled bzlib || check_lib bzlib bzlib.h BZ2_bzlibVersion -lbz2 +# On some systems dynamic loading requires no extra linker flags +check_lib libdl dlfcn.h dlopen || check_lib libdl dlfcn.h dlopen -ldl + check_lib libm math.h sin -lm && LIBM="-lm" atan2f_args=2 @@ -4658,7 +4650,7 @@ done # these are off by default, so fail if requested and not available enabled avisynth && require_header avisynth/avisynth_c.h -enabled avxsynth && require avxsynth "avxsynth/avxsynth_c.h dlfcn.h" dlopen -ldl +enabled avxsynth && require_header avxsynth/avxsynth_c.h enabled cuda && require cuda cuda.h cuInit -lcuda enabled frei0r && require_header frei0r.h enabled gnutls && require_pkg_config gnutls gnutls gnutls/gnutls.h gnutls_global_init From b27be563a88544bf0e151321f073493817048f86 Mon Sep 17 00:00:00 2001 From: Timo Rothenpieler Date: Mon, 27 Feb 2017 23:57:42 +0100 Subject: [PATCH 0971/3374] compat/cuda: fix ulong size on cygwin --- compat/cuda/dynlink_cuviddec.h | 26 ++++++++++++++++---------- compat/cuda/dynlink_nvcuvid.h | 4 ++-- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/compat/cuda/dynlink_cuviddec.h b/compat/cuda/dynlink_cuviddec.h index 9ff274161e69f..4d237643a1e4c 100644 --- a/compat/cuda/dynlink_cuviddec.h +++ b/compat/cuda/dynlink_cuviddec.h @@ -45,6 +45,12 @@ extern "C" { #endif /* __cplusplus */ +#if defined(__CYGWIN__) +typedef unsigned int tcu_ulong; +#else +typedef unsigned long tcu_ulong; +#endif + typedef void *CUvideodecoder; typedef struct _CUcontextlock_st *CUvideoctxlock; @@ -125,14 +131,14 @@ typedef enum cudaVideoCreateFlags_enum { */ typedef struct _CUVIDDECODECREATEINFO { - unsigned long ulWidth; /**< Coded Sequence Width */ - unsigned long ulHeight; /**< Coded Sequence Height */ - unsigned long ulNumDecodeSurfaces; /**< Maximum number of internal decode surfaces */ + tcu_ulong ulWidth; /**< Coded Sequence Width */ + tcu_ulong ulHeight; /**< Coded Sequence Height */ + tcu_ulong ulNumDecodeSurfaces; /**< Maximum number of internal decode surfaces */ cudaVideoCodec CodecType; /**< cudaVideoCodec_XXX */ cudaVideoChromaFormat ChromaFormat; /**< cudaVideoChromaFormat_XXX (only 4:2:0 is currently supported) */ - unsigned long ulCreationFlags; /**< Decoder creation flags (cudaVideoCreateFlags_XXX) */ - unsigned long bitDepthMinus8; - unsigned long Reserved1[4]; /**< Reserved for future use - set to zero */ + tcu_ulong ulCreationFlags; /**< Decoder creation flags (cudaVideoCreateFlags_XXX) */ + tcu_ulong bitDepthMinus8; + tcu_ulong Reserved1[4]; /**< Reserved for future use - set to zero */ /** * area of the frame that should be displayed */ @@ -145,9 +151,9 @@ typedef struct _CUVIDDECODECREATEINFO cudaVideoSurfaceFormat OutputFormat; /**< cudaVideoSurfaceFormat_XXX */ cudaVideoDeinterlaceMode DeinterlaceMode; /**< cudaVideoDeinterlaceMode_XXX */ - unsigned long ulTargetWidth; /**< Post-processed Output Width (Should be aligned to 2) */ - unsigned long ulTargetHeight; /**< Post-processed Output Height (Should be aligbed to 2) */ - unsigned long ulNumOutputSurfaces; /**< Maximum number of output surfaces simultaneously mapped */ + tcu_ulong ulTargetWidth; /**< Post-processed Output Width (Should be aligned to 2) */ + tcu_ulong ulTargetHeight; /**< Post-processed Output Height (Should be aligbed to 2) */ + tcu_ulong ulNumOutputSurfaces; /**< Maximum number of output surfaces simultaneously mapped */ CUvideoctxlock vidLock; /**< If non-NULL, context lock used for synchronizing ownership of the cuda context */ /** * target rectangle in the output frame (for aspect ratio conversion) @@ -159,7 +165,7 @@ typedef struct _CUVIDDECODECREATEINFO short right; short bottom; } target_rect; - unsigned long Reserved2[5]; /**< Reserved for future use - set to zero */ + tcu_ulong Reserved2[5]; /**< Reserved for future use - set to zero */ } CUVIDDECODECREATEINFO; /*! diff --git a/compat/cuda/dynlink_nvcuvid.h b/compat/cuda/dynlink_nvcuvid.h index 6c197e078746b..53e0a7b400cb6 100644 --- a/compat/cuda/dynlink_nvcuvid.h +++ b/compat/cuda/dynlink_nvcuvid.h @@ -173,8 +173,8 @@ typedef enum { */ typedef struct _CUVIDSOURCEDATAPACKET { - unsigned long flags; /**< Combination of CUVID_PKT_XXX flags */ - unsigned long payload_size; /**< number of bytes in the payload (may be zero if EOS flag is set) */ + tcu_ulong flags; /**< Combination of CUVID_PKT_XXX flags */ + tcu_ulong payload_size; /**< number of bytes in the payload (may be zero if EOS flag is set) */ const unsigned char *payload; /**< Pointer to packet payload data (may be NULL if EOS flag is set) */ CUvideotimestamp timestamp; /**< Presentation timestamp (10MHz clock), only valid if CUVID_PKT_TIMESTAMP flag is set */ } CUVIDSOURCEDATAPACKET; From a549243b89da7df5504253b9679b777834014b7f Mon Sep 17 00:00:00 2001 From: Ganapathy Raman Kasi Date: Fri, 24 Feb 2017 01:42:27 +0000 Subject: [PATCH 0972/3374] avcodec/nvenc: remove qmin and qmax constraints for vbr qmin and qmax are not necessary for nvenc vbr. Enforcing this constraint, doesn't allow user to use vbr 2 pass mode without explicity setting the qmin and qmax options Signed-off-by: Timo Rothenpieler --- libavcodec/nvenc.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index ba2647b10acd8..fbd42f41389d9 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -589,16 +589,6 @@ static void nvenc_override_rate_control(AVCodecContext *avctx) } set_constqp(avctx); return; - case NV_ENC_PARAMS_RC_2_PASS_VBR: - case NV_ENC_PARAMS_RC_VBR: - if (avctx->qmin < 0 && avctx->qmax < 0) { - av_log(avctx, AV_LOG_WARNING, - "The variable bitrate rate-control requires " - "the 'qmin' and/or 'qmax' option set.\n"); - set_vbr(avctx); - return; - } - /* fall through */ case NV_ENC_PARAMS_RC_VBR_MINQP: if (avctx->qmin < 0) { av_log(avctx, AV_LOG_WARNING, @@ -607,6 +597,9 @@ static void nvenc_override_rate_control(AVCodecContext *avctx) set_vbr(avctx); return; } + /* fall through */ + case NV_ENC_PARAMS_RC_2_PASS_VBR: + case NV_ENC_PARAMS_RC_VBR: set_vbr(avctx); break; case NV_ENC_PARAMS_RC_CBR: From 5f44a4a0a97e802479e6ce689d719e5277267f22 Mon Sep 17 00:00:00 2001 From: Konda Raju Date: Tue, 28 Feb 2017 11:09:12 +0530 Subject: [PATCH 0973/3374] avcodec/nvenc: add initial QP value options Signed-off-by: Timo Rothenpieler --- libavcodec/nvenc.c | 33 +++++++++++++++++++++++++-------- libavcodec/nvenc.h | 3 +++ libavcodec/nvenc_h264.c | 3 +++ libavcodec/nvenc_hevc.c | 3 +++ libavcodec/version.h | 2 +- 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index fbd42f41389d9..d9fef525dd334 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -547,16 +547,33 @@ static av_cold void set_vbr(AVCodecContext *avctx) } rc->enableInitialRCQP = 1; - rc->initialRCQP.qpInterP = qp_inter_p; - if (avctx->i_quant_factor != 0.0 && avctx->b_quant_factor != 0.0) { - rc->initialRCQP.qpIntra = av_clip( - qp_inter_p * fabs(avctx->i_quant_factor) + avctx->i_quant_offset + 0.5, 0, 51); - rc->initialRCQP.qpInterB = av_clip( - qp_inter_p * fabs(avctx->b_quant_factor) + avctx->b_quant_offset + 0.5, 0, 51); + if (ctx->init_qp_p < 0) { + rc->initialRCQP.qpInterP = qp_inter_p; } else { - rc->initialRCQP.qpIntra = qp_inter_p; - rc->initialRCQP.qpInterB = qp_inter_p; + rc->initialRCQP.qpInterP = ctx->init_qp_p; + } + + if (ctx->init_qp_i < 0) { + if (avctx->i_quant_factor != 0.0 && avctx->b_quant_factor != 0.0) { + rc->initialRCQP.qpIntra = av_clip( + rc->initialRCQP.qpInterP * fabs(avctx->i_quant_factor) + avctx->i_quant_offset + 0.5, 0, 51); + } else { + rc->initialRCQP.qpIntra = rc->initialRCQP.qpInterP; + } + } else { + rc->initialRCQP.qpIntra = ctx->init_qp_i; + } + + if (ctx->init_qp_b < 0) { + if (avctx->i_quant_factor != 0.0 && avctx->b_quant_factor != 0.0) { + rc->initialRCQP.qpInterB = av_clip( + rc->initialRCQP.qpInterP * fabs(avctx->b_quant_factor) + avctx->b_quant_offset + 0.5, 0, 51); + } else { + rc->initialRCQP.qpInterB = rc->initialRCQP.qpInterP; + } + } else { + rc->initialRCQP.qpInterB = ctx->init_qp_b; } } diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h index ab48cf759afdb..cfca2efcc5647 100644 --- a/libavcodec/nvenc.h +++ b/libavcodec/nvenc.h @@ -155,6 +155,9 @@ typedef struct NvencContext int quality; int aud; int bluray_compat; + int init_qp_p; + int init_qp_b; + int init_qp_i; } NvencContext; int ff_nvenc_encode_init(AVCodecContext *avctx); diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c index 3f71204afbc42..b7d4004fd36c9 100644 --- a/libavcodec/nvenc_h264.c +++ b/libavcodec/nvenc_h264.c @@ -109,6 +109,9 @@ static const AVOption options[] = { OFFSET(quality), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 51, VE }, { "aud", "Use access unit delimiters", OFFSET(aud), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, { "bluray-compat", "Bluray compatibility workarounds", OFFSET(bluray_compat),AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, + { "init_qpP", "Initial QP value for P frame", OFFSET(init_qp_p), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE }, + { "init_qpB", "Initial QP value for B frame", OFFSET(init_qp_b), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE }, + { "init_qpI", "Initial QP value for I frame", OFFSET(init_qp_i), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE }, { NULL } }; diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c index 1c97fb0e45a23..2804d7df5aef5 100644 --- a/libavcodec/nvenc_hevc.c +++ b/libavcodec/nvenc_hevc.c @@ -106,6 +106,9 @@ static const AVOption options[] = { OFFSET(quality), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 51, VE }, { "aud", "Use access unit delimiters", OFFSET(aud), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, { "bluray-compat", "Bluray compatibility workarounds", OFFSET(bluray_compat),AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, + { "init_qpP", "Initial QP value for P frame", OFFSET(init_qp_p), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE }, + { "init_qpB", "Initial QP value for B frame", OFFSET(init_qp_b), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE }, + { "init_qpI", "Initial QP value for I frame", OFFSET(init_qp_i), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE }, { NULL } }; diff --git a/libavcodec/version.h b/libavcodec/version.h index 6fdc7764af355..c027e6c3cb97a 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 81 -#define LIBAVCODEC_VERSION_MICRO 100 +#define LIBAVCODEC_VERSION_MICRO 101 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From a2ca9e11ff7166cbbc0314d152702a201f6a14fb Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Wed, 1 Mar 2017 13:42:43 +0100 Subject: [PATCH 0974/3374] Makefile: Clean compat/atomics/pthread subdirectory. --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index ddc7f0c5b8f72..72c959393818c 100644 --- a/Makefile +++ b/Makefile @@ -180,6 +180,7 @@ clean:: $(RM) $(CLEANSUFFIXES) $(RM) $(CLEANSUFFIXES:%=tools/%) $(RM) $(CLEANSUFFIXES:%=compat/msvcrt/%) + $(RM) $(CLEANSUFFIXES:%=compat/atomics/pthread/%) $(RM) $(CLEANSUFFIXES:%=compat/%) $(RM) -r coverage-html $(RM) -rf coverage.info coverage.info.in lcov From 2c00b373024054e0779ef67fc54b763d624db3e8 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 27 Feb 2017 04:12:09 +0100 Subject: [PATCH 0975/3374] avcodec/avpacket: Check metadata key in av_packet_unpack_dictionary() Fixes timeout Fixes: 501/clusterfuzz-testcase-5672752870588416 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/avpacket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index 8e028a2a6c464..60269aa63db8e 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -508,7 +508,7 @@ int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **di const uint8_t *key = data; const uint8_t *val = data + strlen(key) + 1; - if (val >= end) + if (val >= end || !*key) return AVERROR_INVALIDDATA; ret = av_dict_set(dict, key, val, 0); From 4bd3f1ce3e68a9348e97ec07a247048ea72ed808 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 28 Feb 2017 03:13:24 +0100 Subject: [PATCH 0976/3374] avcodec/h264_direct: Fix runtime error: left shift of negative value -14 Fixes: 682/clusterfuzz-testcase-4799120021651456 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/h264_direct.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c index 107c905db126c..cbb84665b3b90 100644 --- a/libavcodec/h264_direct.c +++ b/libavcodec/h264_direct.c @@ -614,7 +614,7 @@ static void pred_temp_direct_motion(const H264Context *const h, H264SliceContext { const int16_t *mv_col = l1mv[x8 * 3 + y8 * b4_stride]; - int my_col = (mv_col[1] << y_shift) / 2; + int my_col = (mv_col[1] * (1 << y_shift)) / 2; int mx = (scale * mv_col[0] + 128) >> 8; int my = (scale * my_col + 128) >> 8; fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, From 7b5ff7d57355dc608f0fd86e3ab32a2fda65e752 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 28 Feb 2017 03:55:02 +0100 Subject: [PATCH 0977/3374] avcodec/vp8: Check for bitsteam end in decode_mb_row_no_filter() Fixes timeout with 686/clusterfuzz-testcase-5853946876788736 this shortcuts (i.e. speeds up) the error and return-to-user when decoding a truncated frame Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Previous version reviewed by: "Ronald S. Bultje" Signed-off-by: Michael Niedermayer --- libavcodec/vp8.c | 20 ++++++++++++++------ libavcodec/vp8.h | 2 +- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index c1c3eb707244b..cc158528ef61b 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -2275,7 +2275,7 @@ static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame, #define update_pos(td, mb_y, mb_x) while(0) #endif -static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, +static av_always_inline int decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr, int is_vp7) { VP8Context *s = avctx->priv_data; @@ -2291,6 +2291,10 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void curframe->tf.f->data[1] + 8 * mb_y * s->uvlinesize, curframe->tf.f->data[2] + 8 * mb_y * s->uvlinesize }; + + if (c->end <= c->buffer && c->bits >= 0) + return AVERROR_INVALIDDATA; + if (mb_y == 0) prev_td = td; else @@ -2394,18 +2398,19 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void update_pos(td, mb_y, mb_x); } } + return 0; } -static void vp7_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, +static int vp7_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr) { - decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 1); + return decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 1); } -static void vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, +static int vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr) { - decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 0); + return decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 0); } static av_always_inline void filter_mb_row(AVCodecContext *avctx, void *tdata, @@ -2488,13 +2493,16 @@ int vp78_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, int jobnr, VP8ThreadData *next_td = NULL, *prev_td = NULL; VP8Frame *curframe = s->curframe; int mb_y, num_jobs = s->num_jobs; + int ret; td->thread_nr = threadnr; for (mb_y = jobnr; mb_y < s->mb_height; mb_y += num_jobs) { if (mb_y >= s->mb_height) break; td->thread_mb_pos = mb_y << 16; - s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr); + ret = s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr); + if (ret < 0) + return ret; if (s->deblock_filter) s->filter_mb_row(avctx, tdata, jobnr, threadnr); update_pos(td, mb_y, INT_MAX & 0xFFFF); diff --git a/libavcodec/vp8.h b/libavcodec/vp8.h index 374e1388e217d..6218fe0567045 100644 --- a/libavcodec/vp8.h +++ b/libavcodec/vp8.h @@ -275,7 +275,7 @@ typedef struct VP8Context { */ int mb_layout; - void (*decode_mb_row_no_filter)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr); + int (*decode_mb_row_no_filter)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr); void (*filter_mb_row)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr); int vp7; From 70ebc05bce51215cd0857194d6cabf1e4d1440fb Mon Sep 17 00:00:00 2001 From: Rick Kern Date: Wed, 1 Mar 2017 10:39:13 -0500 Subject: [PATCH 0978/3374] lavc/videotoolboxenc: fix symbol linking Removes explicit reference to symbols and fixes dereferencing issue. Signed-off-by: Rick Kern --- libavcodec/videotoolboxenc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c index fe64250f29ead..005f5d63257f4 100644 --- a/libavcodec/videotoolboxenc.c +++ b/libavcodec/videotoolboxenc.c @@ -74,11 +74,11 @@ static struct{ #define GET_SYM(symbol, defaultVal) \ do{ \ - CFStringRef cfstr = dlsym(RTLD_DEFAULT, #symbol); \ + CFStringRef cfstr = *(CFStringRef*)dlsym(RTLD_DEFAULT, #symbol); \ if(!cfstr) \ compat_keys.symbol = CFSTR(defaultVal); \ else \ - compat_keys.symbol = symbol; \ + compat_keys.symbol = cfstr; \ }while(0) static pthread_once_t once_ctrl = PTHREAD_ONCE_INIT; From 3250d4b39ccf70a9517a708fb6738070ebe83d6a Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 28 Feb 2017 13:36:29 +0100 Subject: [PATCH 0979/3374] avformat/oggdec: remove unused parameter of ogg_restore() Signed-off-by: Michael Niedermayer --- libavformat/oggdec.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c index e1ef21337c820..64a88261e3fe2 100644 --- a/libavformat/oggdec.c +++ b/libavformat/oggdec.c @@ -61,7 +61,7 @@ static const struct ogg_codec * const ogg_codecs[] = { static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts); static int ogg_new_stream(AVFormatContext *s, uint32_t serial); -static int ogg_restore(AVFormatContext *s, int discard); +static int ogg_restore(AVFormatContext *s); //FIXME We could avoid some structure duplication static int ogg_save(AVFormatContext *s) @@ -95,12 +95,12 @@ static int ogg_save(AVFormatContext *s) ogg->state = ost; if (ret < 0) - ogg_restore(s, 0); + ogg_restore(s); return ret; } -static int ogg_restore(AVFormatContext *s, int discard) +static int ogg_restore(AVFormatContext *s) { struct ogg *ogg = s->priv_data; AVIOContext *bc = s->pb; @@ -112,8 +112,6 @@ static int ogg_restore(AVFormatContext *s, int discard) ogg->state = ost->next; - if (!discard) { - for (i = 0; i < ogg->nstreams; i++) av_freep(&ogg->streams[i].buf); @@ -128,7 +126,6 @@ static int ogg_restore(AVFormatContext *s, int discard) } else memcpy(ogg->streams, ost->streams, ost->nstreams * sizeof(*ogg->streams)); - } av_free(ost); @@ -631,7 +628,7 @@ static int ogg_get_length(AVFormatContext *s) } } - ogg_restore(s, 0); + ogg_restore(s); ret = ogg_save(s); if (ret < 0) @@ -654,7 +651,7 @@ static int ogg_get_length(AVFormatContext *s) streams_left--; } } - ogg_restore (s, 0); + ogg_restore (s); return 0; } From fb6fa48fce3a09a30403326973f03f0343c6e24a Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 28 Feb 2017 15:16:23 +0100 Subject: [PATCH 0980/3374] avformat/oggdec: Factor free_stream out Signed-off-by: Michael Niedermayer --- libavformat/oggdec.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c index 64a88261e3fe2..98cd0f55c7ffa 100644 --- a/libavformat/oggdec.c +++ b/libavformat/oggdec.c @@ -63,6 +63,21 @@ static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts); static int ogg_new_stream(AVFormatContext *s, uint32_t serial); static int ogg_restore(AVFormatContext *s); +static void free_stream(AVFormatContext *s, int i) +{ + struct ogg *ogg = s->priv_data; + struct ogg_stream *stream = &ogg->streams[i]; + + av_freep(&stream->buf); + if (stream->codec && + stream->codec->cleanup) { + stream->codec->cleanup(s, i); + } + + av_freep(&stream->private); + av_freep(&stream->new_metadata); +} + //FIXME We could avoid some structure duplication static int ogg_save(AVFormatContext *s) { @@ -662,13 +677,7 @@ static int ogg_read_close(AVFormatContext *s) int i; for (i = 0; i < ogg->nstreams; i++) { - av_freep(&ogg->streams[i].buf); - if (ogg->streams[i].codec && - ogg->streams[i].codec->cleanup) { - ogg->streams[i].codec->cleanup(s, i); - } - av_freep(&ogg->streams[i].private); - av_freep(&ogg->streams[i].new_metadata); + free_stream(s, i); } ogg->nstreams = 0; From e46ab997506e8aa84344c29553ebacca7993904c Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 28 Feb 2017 15:16:54 +0100 Subject: [PATCH 0981/3374] avformat/oggdec: fix leak in ogg_restore() Fixes: asan_bug_leak Found-by: Thomas Guilbert Signed-off-by: Michael Niedermayer --- libavformat/oggdec.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c index 98cd0f55c7ffa..edeae2ba83c66 100644 --- a/libavformat/oggdec.c +++ b/libavformat/oggdec.c @@ -127,8 +127,12 @@ static int ogg_restore(AVFormatContext *s) ogg->state = ost->next; - for (i = 0; i < ogg->nstreams; i++) + for (i = 0; i < ogg->nstreams; i++) { av_freep(&ogg->streams[i].buf); + if (i >= ost->nstreams || !ost->streams[i].private) { + free_stream(s, i); + } + } avio_seek(bc, ost->pos, SEEK_SET); ogg->page_pos = -1; From 04c99c8042c8bfae817c722d90aa0f1a40db861e Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 28 Feb 2017 22:07:36 +0100 Subject: [PATCH 0982/3374] avcodec/h264idct_template: Fix several runtime error: signed integer overflow Fixes: 689/clusterfuzz-testcase-6029352737177600 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/h264idct_template.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libavcodec/h264idct_template.c b/libavcodec/h264idct_template.c index 9c5a43ce4fc49..c62716090cd6e 100644 --- a/libavcodec/h264idct_template.c +++ b/libavcodec/h264idct_template.c @@ -261,15 +261,15 @@ void FUNCC(ff_h264_luma_dc_dequant_idct)(int16_t *_output, int16_t *_input, int for(i=0; i<4; i++){ const int offset= x_offset[i]; - const int z0= temp[4*0+i] + temp[4*2+i]; - const int z1= temp[4*0+i] - temp[4*2+i]; - const int z2= temp[4*1+i] - temp[4*3+i]; - const int z3= temp[4*1+i] + temp[4*3+i]; - - output[stride* 0+offset]= ((((z0 + z3)*qmul + 128 ) >> 8)); - output[stride* 1+offset]= ((((z1 + z2)*qmul + 128 ) >> 8)); - output[stride* 4+offset]= ((((z1 - z2)*qmul + 128 ) >> 8)); - output[stride* 5+offset]= ((((z0 - z3)*qmul + 128 ) >> 8)); + const SUINT z0= temp[4*0+i] + temp[4*2+i]; + const SUINT z1= temp[4*0+i] - temp[4*2+i]; + const SUINT z2= temp[4*1+i] - temp[4*3+i]; + const SUINT z3= temp[4*1+i] + temp[4*3+i]; + + output[stride* 0+offset]= (int)((z0 + z3)*qmul + 128 ) >> 8; + output[stride* 1+offset]= (int)((z1 + z2)*qmul + 128 ) >> 8; + output[stride* 4+offset]= (int)((z1 - z2)*qmul + 128 ) >> 8; + output[stride* 5+offset]= (int)((z0 - z3)*qmul + 128 ) >> 8; } #undef stride } From 12c3e120fe8f8d6881001eade390d8a5c185783d Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 28 Feb 2017 22:07:37 +0100 Subject: [PATCH 0983/3374] avcodec/ituh263dec: Use 0xffff as error code in h263p_decode_umotion() This matches ff_h263_decode_motion() both functions error codes are interpreted by the same common code Fixes: 690/clusterfuzz-testcase-4744944981901312 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/ituh263dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c index e39338870f0ea..edb68861ac639 100644 --- a/libavcodec/ituh263dec.c +++ b/libavcodec/ituh263dec.c @@ -305,7 +305,7 @@ static int h263p_decode_umotion(MpegEncContext * s, int pred) code += get_bits1(&s->gb); if (code >= 32768) { avpriv_request_sample(s->avctx, "Huge DMV"); - return AVERROR_INVALIDDATA; + return 0xffff; } } sign = code & 1; From f8060ab927f89db8844b1a0e0709159662e6167b Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 28 Feb 2017 22:07:38 +0100 Subject: [PATCH 0984/3374] avcodec/wavpack: Check value before shift in wp_exp2() Fixes undefined shift, all callers should be changed to check the value they use with wp_exp2() or its return value. Fixes: 692/clusterfuzz-testcase-5757381516460032 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/wavpack.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/wavpack.h b/libavcodec/wavpack.h index a1b46d5bd74d0..0196574aab3c5 100644 --- a/libavcodec/wavpack.h +++ b/libavcodec/wavpack.h @@ -171,6 +171,8 @@ static av_always_inline int wp_exp2(int16_t val) res = wp_exp2_table[val & 0xFF] | 0x100; val >>= 8; + if (val > 31) + return INT_MIN; res = (val > 9) ? (res << (val - 9)) : (res >> (9 - val)); return neg ? -res : res; } From 4bed06637729ab000b79250c67d53078300e37c4 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 1 Mar 2017 04:28:23 +0100 Subject: [PATCH 0985/3374] avcodec/vp56: Clear dimensions in case of failure in the middle of a resolution change Similar code is used elsewhere in vp56 to force a more complete reinit in the future. Fixes null pointer dereference Fixes: 707/clusterfuzz-testcase-4717453097566208 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/vp56.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c index a9a1a0c1d5818..5ea365375b4d4 100644 --- a/libavcodec/vp56.c +++ b/libavcodec/vp56.c @@ -572,13 +572,18 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } ret = ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF); - if (ret < 0) + if (ret < 0) { + if (res == VP56_SIZE_CHANGE) + ff_set_dimensions(avctx, 0, 0); return ret; + } if (avctx->pix_fmt == AV_PIX_FMT_YUVA420P) { av_frame_unref(s->alpha_context->frames[VP56_FRAME_CURRENT]); if ((ret = av_frame_ref(s->alpha_context->frames[VP56_FRAME_CURRENT], p)) < 0) { av_frame_unref(p); + if (res == VP56_SIZE_CHANGE) + ff_set_dimensions(avctx, 0, 0); return ret; } } From 3733039610d76231e404ebf089f0ff2b9d8e5490 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Thu, 2 Mar 2017 09:29:10 +0100 Subject: [PATCH 0986/3374] lavf/flacdec: Return maximum score if the streaminfo header is valid. --- libavformat/flacdec.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c index 66baba5922511..fee46fcfe6a80 100644 --- a/libavformat/flacdec.c +++ b/libavformat/flacdec.c @@ -233,7 +233,14 @@ static int flac_probe(AVProbeData *p) return raw_flac_probe(p); if (p->buf_size < 4 || memcmp(p->buf, "fLaC", 4)) return 0; - return AVPROBE_SCORE_EXTENSION; + if ( p->buf[4] & 0x7f != FLAC_METADATA_TYPE_STREAMINFO + || AV_RB24(p->buf + 5) != FLAC_STREAMINFO_SIZE + || AV_RB16(p->buf + 8) < 16 + || AV_RB16(p->buf + 8) > AV_RB16(p->buf + 10) + || !(AV_RB24(p->buf + 18) >> 4) + || AV_RB24(p->buf + 18) >> 4 > 655350) + return AVPROBE_SCORE_EXTENSION; + return AVPROBE_SCORE_MAX; } static av_unused int64_t flac_read_timestamp(AVFormatContext *s, int stream_index, From 554bc4eea8aa71d5c017289a036b49313882f7e6 Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 13 Feb 2017 11:40:22 +0100 Subject: [PATCH 0987/3374] avcodec, avutil, avformat: remove AVOption requirement for some fields Allow all struct fields to be accessed directly, as long as they're public. Before this change, many fields were "public", but could be accessed via AVOption only. This meant they were effectively not public, but were present for documentation purposes, which was incredibly confusing at best. --- doc/APIchanges | 5 +++++ libavcodec/avcodec.h | 25 +++++---------------- libavcodec/version.h | 2 +- libavformat/avformat.h | 50 ++++++++++++++++++++++-------------------- libavformat/version.h | 2 +- libavutil/frame.h | 32 +++------------------------ libavutil/version.h | 2 +- 7 files changed, 42 insertions(+), 76 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index d739895aa4207..cd5f926b15bc7 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,11 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-03-02 - xxxxxxx - lavu 55.47.101, lavc 57.81.102, lavf 57.66.103 + Remove requirement to use AVOption or accessors to access certain fields + in AVFrame, AVCodecContext, and AVFormatContext that were previously + documented as "no direct access" allowed. + 2017-02-13 - xxxxxxx - lavc 57.80.100 - avcodec.h Add AVCodecContext.hw_device_ctx. diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 925a8c72771cb..298b9146e27ff 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1680,7 +1680,7 @@ enum AVFieldOrder { * New fields can be added to the end with minor version bumps. * Removal, reordering and changes to existing fields require a major * version bump. - * Please use AVOptions (av_opt* / av_set/get*()) to access these fields from user + * You can use AVOptions (av_opt* / av_set/get*()) to access these fields from user * applications. * The name string for AVOptions options matches the associated command line * parameter name and can be found in libavcodec/options_table.h @@ -2951,8 +2951,8 @@ typedef struct AVCodecContext { #define FF_DEBUG_MMCO 0x00000800 #define FF_DEBUG_BUGS 0x00001000 #if FF_API_DEBUG_MV -#define FF_DEBUG_VIS_QP 0x00002000 ///< only access through AVOptions from outside libavcodec -#define FF_DEBUG_VIS_MB_TYPE 0x00004000 ///< only access through AVOptions from outside libavcodec +#define FF_DEBUG_VIS_QP 0x00002000 +#define FF_DEBUG_VIS_MB_TYPE 0x00004000 #endif #define FF_DEBUG_BUFFERS 0x00008000 #define FF_DEBUG_THREADS 0x00010000 @@ -2962,7 +2962,6 @@ typedef struct AVCodecContext { #if FF_API_DEBUG_MV /** * debug - * Code outside libavcodec should access this field using AVOptions * - encoding: Set by user. * - decoding: Set by user. */ @@ -3097,8 +3096,6 @@ typedef struct AVCodecContext { * low resolution decoding, 1-> 1/2 size, 2->1/4 size * - encoding: unused * - decoding: Set by user. - * Code outside libavcodec should access this field using: - * av_codec_{get,set}_lowres(avctx) */ int lowres; #endif @@ -3399,8 +3396,6 @@ typedef struct AVCodecContext { /** * Timebase in which pkt_dts/pts and AVPacket.dts/pts are. - * Code outside libavcodec should access this field using: - * av_codec_{get,set}_pkt_timebase(avctx) * - encoding unused. * - decoding set by user. */ @@ -3408,8 +3403,6 @@ typedef struct AVCodecContext { /** * AVCodecDescriptor - * Code outside libavcodec should access this field using: - * av_codec_{get,set}_codec_descriptor(avctx) * - encoding: unused. * - decoding: set by libavcodec. */ @@ -3420,8 +3413,6 @@ typedef struct AVCodecContext { * low resolution decoding, 1-> 1/2 size, 2->1/4 size * - encoding: unused * - decoding: Set by user. - * Code outside libavcodec should access this field using: - * av_codec_{get,set}_lowres(avctx) */ int lowres; #endif @@ -3462,7 +3453,6 @@ typedef struct AVCodecContext { * However for formats that do not use pre-multiplied alpha * there might be serious artefacts (though e.g. libswscale currently * assumes pre-multiplied alpha anyway). - * Code outside libavcodec should access this field using AVOptions * * - decoding: set by user * - encoding: unused @@ -3479,7 +3469,6 @@ typedef struct AVCodecContext { #if !FF_API_DEBUG_MV /** * debug motion vectors - * Code outside libavcodec should access this field using AVOptions * - encoding: Set by user. * - decoding: Set by user. */ @@ -3491,7 +3480,6 @@ typedef struct AVCodecContext { /** * custom intra quantization matrix - * Code outside libavcodec should access this field using av_codec_g/set_chroma_intra_matrix() * - encoding: Set by user, can be NULL. * - decoding: unused. */ @@ -3500,8 +3488,6 @@ typedef struct AVCodecContext { /** * dump format separator. * can be ", " or "\n " or anything else - * Code outside libavcodec should access this field using AVOptions - * (NO direct access). * - encoding: Set by user. * - decoding: Set by user. */ @@ -3511,13 +3497,12 @@ typedef struct AVCodecContext { * ',' separated list of allowed decoders. * If NULL then all are allowed * - encoding: unused - * - decoding: set by user through AVOPtions (NO direct access) + * - decoding: set by user */ char *codec_whitelist; /* * Properties of the stream that gets decoded - * To be accessed through av_codec_get_properties() (NO direct access) * - encoding: unused * - decoding: set by libavcodec */ @@ -3668,7 +3653,7 @@ typedef struct AVCodec { const int *supported_samplerates; ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0 const enum AVSampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1 const uint64_t *channel_layouts; ///< array of support channel layouts, or NULL if unknown. array is terminated by 0 - uint8_t max_lowres; ///< maximum value for lowres supported by the decoder, no direct access, use av_codec_get_max_lowres() + uint8_t max_lowres; ///< maximum value for lowres supported by the decoder const AVClass *priv_class; ///< AVClass for the private context const AVProfile *profiles; ///< array of recognized profiles, or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN} diff --git a/libavcodec/version.h b/libavcodec/version.h index c027e6c3cb97a..3b4c2531466a2 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 81 -#define LIBAVCODEC_VERSION_MICRO 101 +#define LIBAVCODEC_VERSION_MICRO 102 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavformat/avformat.h b/libavformat/avformat.h index ebb0e05c04282..64180bca9e32a 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1649,7 +1649,7 @@ typedef struct AVFormatContext { /** * Audio preload in microseconds. * Note, not all formats support this and unpredictable things may happen if it is used when not supported. - * - encoding: Set by user via AVOptions (NO direct access) + * - encoding: Set by user * - decoding: unused */ int audio_preload; @@ -1657,7 +1657,7 @@ typedef struct AVFormatContext { /** * Max chunk time in microseconds. * Note, not all formats support this and unpredictable things may happen if it is used when not supported. - * - encoding: Set by user via AVOptions (NO direct access) + * - encoding: Set by user * - decoding: unused */ int max_chunk_duration; @@ -1665,7 +1665,7 @@ typedef struct AVFormatContext { /** * Max chunk size in bytes * Note, not all formats support this and unpredictable things may happen if it is used when not supported. - * - encoding: Set by user via AVOptions (NO direct access) + * - encoding: Set by user * - decoding: unused */ int max_chunk_size; @@ -1674,14 +1674,14 @@ typedef struct AVFormatContext { * forces the use of wallclock timestamps as pts/dts of packets * This has undefined results in the presence of B frames. * - encoding: unused - * - decoding: Set by user via AVOptions (NO direct access) + * - decoding: Set by user */ int use_wallclock_as_timestamps; /** * avio flags, used to force AVIO_FLAG_DIRECT. * - encoding: unused - * - decoding: Set by user via AVOptions (NO direct access) + * - decoding: Set by user */ int avio_flags; @@ -1689,34 +1689,34 @@ typedef struct AVFormatContext { * The duration field can be estimated through various ways, and this field can be used * to know how the duration was estimated. * - encoding: unused - * - decoding: Read by user via AVOptions (NO direct access) + * - decoding: Read by user */ enum AVDurationEstimationMethod duration_estimation_method; /** * Skip initial bytes when opening stream * - encoding: unused - * - decoding: Set by user via AVOptions (NO direct access) + * - decoding: Set by user */ int64_t skip_initial_bytes; /** * Correct single timestamp overflows * - encoding: unused - * - decoding: Set by user via AVOptions (NO direct access) + * - decoding: Set by user */ unsigned int correct_ts_overflow; /** * Force seeking to any (also non key) frames. * - encoding: unused - * - decoding: Set by user via AVOptions (NO direct access) + * - decoding: Set by user */ int seek2any; /** * Flush the I/O context after each packet. - * - encoding: Set by user via AVOptions (NO direct access) + * - encoding: Set by user * - decoding: unused */ int flush_packets; @@ -1726,14 +1726,14 @@ typedef struct AVFormatContext { * The maximal score is AVPROBE_SCORE_MAX, its set when the demuxer probes * the format. * - encoding: unused - * - decoding: set by avformat, read by user via av_format_get_probe_score() (NO direct access) + * - decoding: set by avformat, read by user */ int probe_score; /** * number of bytes to read maximally to identify format. * - encoding: unused - * - decoding: set by user through AVOPtions (NO direct access) + * - decoding: set by user */ int format_probesize; @@ -1741,7 +1741,7 @@ typedef struct AVFormatContext { * ',' separated list of allowed decoders. * If NULL then all are allowed * - encoding: unused - * - decoding: set by user through AVOptions (NO direct access) + * - decoding: set by user */ char *codec_whitelist; @@ -1749,7 +1749,7 @@ typedef struct AVFormatContext { * ',' separated list of allowed demuxers. * If NULL then all are allowed * - encoding: unused - * - decoding: set by user through AVOptions (NO direct access) + * - decoding: set by user */ char *format_whitelist; @@ -1771,7 +1771,7 @@ typedef struct AVFormatContext { * Forced video codec. * This allows forcing a specific decoder, even when there are multiple with * the same codec_id. - * Demuxing: Set by user via av_format_set_video_codec (NO direct access). + * Demuxing: Set by user */ AVCodec *video_codec; @@ -1779,7 +1779,7 @@ typedef struct AVFormatContext { * Forced audio codec. * This allows forcing a specific decoder, even when there are multiple with * the same codec_id. - * Demuxing: Set by user via av_format_set_audio_codec (NO direct access). + * Demuxing: Set by user */ AVCodec *audio_codec; @@ -1787,7 +1787,7 @@ typedef struct AVFormatContext { * Forced subtitle codec. * This allows forcing a specific decoder, even when there are multiple with * the same codec_id. - * Demuxing: Set by user via av_format_set_subtitle_codec (NO direct access). + * Demuxing: Set by user */ AVCodec *subtitle_codec; @@ -1795,7 +1795,7 @@ typedef struct AVFormatContext { * Forced data codec. * This allows forcing a specific decoder, even when there are multiple with * the same codec_id. - * Demuxing: Set by user via av_format_set_data_codec (NO direct access). + * Demuxing: Set by user */ AVCodec *data_codec; @@ -1819,15 +1819,13 @@ typedef struct AVFormatContext { /** * Output timestamp offset, in microseconds. - * Muxing: set by user via AVOptions (NO direct access) + * Muxing: set by user */ int64_t output_ts_offset; /** * dump format separator. * can be ", " or "\n " or anything else - * Code outside libavformat should access this field using AVOptions - * (NO direct access). * - muxing: Set by user. * - demuxing: Set by user. */ @@ -1864,7 +1862,7 @@ typedef struct AVFormatContext { /** * ',' separated list of allowed protocols. * - encoding: unused - * - decoding: set by user through AVOptions (NO direct access) + * - decoding: set by user */ char *protocol_whitelist; @@ -1899,18 +1897,22 @@ typedef struct AVFormatContext { /** * ',' separated list of disallowed protocols. * - encoding: unused - * - decoding: set by user through AVOptions (NO direct access) + * - decoding: set by user */ char *protocol_blacklist; /** * The maximum number of streams. * - encoding: unused - * - decoding: set by user through AVOptions (NO direct access) + * - decoding: set by user */ int max_streams; } AVFormatContext; +/** + * Accessors for some AVFormatContext fields. These used to be provided for ABI + * compatibility, and do not need to be used anymore. + */ int av_format_get_probe_score(const AVFormatContext *s); AVCodec * av_format_get_video_codec(const AVFormatContext *s); void av_format_set_video_codec(AVFormatContext *s, AVCodec *c); diff --git a/libavformat/version.h b/libavformat/version.h index 7368743236248..cd505242efee0 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -33,7 +33,7 @@ // Also please add any ticket numbers that you believe might be affected here #define LIBAVFORMAT_VERSION_MAJOR 57 #define LIBAVFORMAT_VERSION_MINOR 66 -#define LIBAVFORMAT_VERSION_MICRO 102 +#define LIBAVFORMAT_VERSION_MICRO 103 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ diff --git a/libavutil/frame.h b/libavutil/frame.h index 2b1dc2fee3ff1..7cb78a1a443a5 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -179,9 +179,6 @@ typedef struct AVFrameSideData { * * sizeof(AVFrame) is not a part of the public ABI, so new fields may be added * to the end with a minor bump. - * Similarly fields that are marked as to be only accessed by - * av_opt_ptr() can be reordered. This allows 2 forks to add fields - * without breaking compatibility with each other. * * Fields can be accessed through AVOptions, the name string used, matches the * C structure field name for fields accessible through AVOptions. The AVClass @@ -420,8 +417,6 @@ typedef struct AVFrame { /** * MPEG vs JPEG YUV range. - * It must be accessed using av_frame_get_color_range() and - * av_frame_set_color_range(). * - encoding: Set by user * - decoding: Set by libavcodec */ @@ -433,8 +428,6 @@ typedef struct AVFrame { /** * YUV colorspace type. - * It must be accessed using av_frame_get_colorspace() and - * av_frame_set_colorspace(). * - encoding: Set by user * - decoding: Set by libavcodec */ @@ -444,8 +437,6 @@ typedef struct AVFrame { /** * frame timestamp estimated using various heuristics, in stream time base - * Code outside libavutil should access this field using: - * av_frame_get_best_effort_timestamp(frame) * - encoding: unused * - decoding: set by libavcodec, read by user. */ @@ -453,8 +444,6 @@ typedef struct AVFrame { /** * reordered pos from the last AVPacket that has been input into the decoder - * Code outside libavutil should access this field using: - * av_frame_get_pkt_pos(frame) * - encoding: unused * - decoding: Read by user. */ @@ -463,8 +452,6 @@ typedef struct AVFrame { /** * duration of the corresponding packet, expressed in * AVStream->time_base units, 0 if unknown. - * Code outside libavutil should access this field using: - * av_frame_get_pkt_duration(frame) * - encoding: unused * - decoding: Read by user. */ @@ -472,8 +459,6 @@ typedef struct AVFrame { /** * metadata. - * Code outside libavutil should access this field using: - * av_frame_get_metadata(frame) * - encoding: Set by user. * - decoding: Set by libavcodec. */ @@ -483,8 +468,6 @@ typedef struct AVFrame { * decode error flags of the frame, set to a combination of * FF_DECODE_ERROR_xxx flags if the decoder produced a frame, but there * were errors during the decoding. - * Code outside libavutil should access this field using: - * av_frame_get_decode_error_flags(frame) * - encoding: unused * - decoding: set by libavcodec, read by user. */ @@ -494,8 +477,6 @@ typedef struct AVFrame { /** * number of audio channels, only used for audio. - * Code outside libavutil should access this field using: - * av_frame_get_channels(frame) * - encoding: unused * - decoding: Read by user. */ @@ -503,8 +484,7 @@ typedef struct AVFrame { /** * size of the corresponding packet containing the compressed - * frame. It must be accessed using av_frame_get_pkt_size() and - * av_frame_set_pkt_size(). + * frame. * It is set to a negative value if unknown. * - encoding: unused * - decoding: set by libavcodec, read by user. @@ -514,13 +494,11 @@ typedef struct AVFrame { #if FF_API_FRAME_QP /** * QP table - * Not to be accessed directly from outside libavutil */ attribute_deprecated int8_t *qscale_table; /** * QP store stride - * Not to be accessed directly from outside libavutil */ attribute_deprecated int qstride; @@ -528,9 +506,6 @@ typedef struct AVFrame { attribute_deprecated int qscale_type; - /** - * Not to be accessed directly from outside libavutil - */ AVBufferRef *qp_table_buf; #endif /** @@ -552,9 +527,8 @@ typedef struct AVFrame { } AVFrame; /** - * Accessors for some AVFrame fields. - * The position of these field in the structure is not part of the ABI, - * they should not be accessed directly outside libavutil. + * Accessors for some AVFrame fields. These used to be provided for ABI + * compatibility, and do not need to be used anymore. */ int64_t av_frame_get_best_effort_timestamp(const AVFrame *frame); void av_frame_set_best_effort_timestamp(AVFrame *frame, int64_t val); diff --git a/libavutil/version.h b/libavutil/version.h index a8b00bfc64bc3..3cf9d7ff157d1 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -80,7 +80,7 @@ #define LIBAVUTIL_VERSION_MAJOR 55 #define LIBAVUTIL_VERSION_MINOR 47 -#define LIBAVUTIL_VERSION_MICRO 100 +#define LIBAVUTIL_VERSION_MICRO 101 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ LIBAVUTIL_VERSION_MINOR, \ From 227f6e1e8d4bd23734db9769bb52cc9896e253b5 Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 13 Feb 2017 11:50:54 +0100 Subject: [PATCH 0988/3374] avformat: fix AVStream private fields marker Public fields were added after the private fields (negating the entire point of this). New private fields go into AVStreamInternal anyway. The new marker was set by guessing which fields are supposed to be private and wshich not. recommended_encoder_configuration is accessed by ffserver_config.c directly, and is supposed to use the public API. ffmpeg.c accesses AVStream.cur_dts, even though it's a private field, but that seems to be an older error. --- libavformat/avformat.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 64180bca9e32a..4c1b18e0028e8 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1005,7 +1005,9 @@ typedef struct AVStream { * All fields below this line are not part of the public API. They * may not be used outside of libavformat and can be changed and * removed at will. - * New public fields should be added right above. + * Internal note: be aware that physically removing these fields + * will break ABI. Replace removed fields with dummy fields, and + * add new fields to AVStreamInternal. ***************************************************************** */ @@ -1201,6 +1203,12 @@ typedef struct AVStream { */ int inject_global_side_data; + /***************************************************************** + * All fields above this line are not part of the public API. + * Fields below are part of the public API and ABI again. + ***************************************************************** + */ + /** * String containing paris of key and values describing recommended encoder configuration. * Paris are separated by ','. From ade7c1a2326e2bb9be5e60a48b9968eb1d16bfaf Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 24 Feb 2017 10:17:34 +0100 Subject: [PATCH 0989/3374] avcodec/videotoolbox: allow not setting the kCVPixelBufferPixelFormatTypeKey If AVVideotoolboxContext.cv_pix_fmt_type is set to 0, don't set the kCVPixelBufferPixelFormatTypeKey value on the VT decoder. This makes VT output its native format, which can be much faster on some hardware iterations (if the native format does not match with the requested format, it will be converted, which is slow). The default is still forcing nv12. --- doc/APIchanges | 4 ++++ libavcodec/version.h | 2 +- libavcodec/videotoolbox.c | 3 ++- libavcodec/videotoolbox.h | 3 ++- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index cd5f926b15bc7..6922ea5268f65 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,10 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-03-02 - xxxxxxx - lavc 57.81.104 - videotoolbox.h + AVVideotoolboxContext.cv_pix_fmt_type can now be set to 0 to output the + native decoder format. (The default value is not changed.) + 2017-03-02 - xxxxxxx - lavu 55.47.101, lavc 57.81.102, lavf 57.66.103 Remove requirement to use AVOption or accessors to access certain fields in AVFrame, AVCodecContext, and AVFormatContext that were previously diff --git a/libavcodec/version.h b/libavcodec/version.h index 3b4c2531466a2..5d8b22cb29a96 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 81 -#define LIBAVCODEC_VERSION_MICRO 102 +#define LIBAVCODEC_VERSION_MICRO 103 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavcodec/videotoolbox.c b/libavcodec/videotoolbox.c index 1288aa5087386..2ebe60fb5c0d0 100644 --- a/libavcodec/videotoolbox.c +++ b/libavcodec/videotoolbox.c @@ -472,7 +472,8 @@ static CFDictionaryRef videotoolbox_buffer_attributes_create(int width, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDictionarySetValue(buffer_attributes, kCVPixelBufferPixelFormatTypeKey, cv_pix_fmt); + if (pix_fmt) + CFDictionarySetValue(buffer_attributes, kCVPixelBufferPixelFormatTypeKey, cv_pix_fmt); CFDictionarySetValue(buffer_attributes, kCVPixelBufferIOSurfacePropertiesKey, io_surface_properties); CFDictionarySetValue(buffer_attributes, kCVPixelBufferWidthKey, w); CFDictionarySetValue(buffer_attributes, kCVPixelBufferHeightKey, h); diff --git a/libavcodec/videotoolbox.h b/libavcodec/videotoolbox.h index a48638e2b224f..af2db0d580932 100644 --- a/libavcodec/videotoolbox.h +++ b/libavcodec/videotoolbox.h @@ -58,7 +58,8 @@ typedef struct AVVideotoolboxContext { /** * CVPixelBuffer Format Type that Videotoolbox will use for decoded frames. - * set by the caller. + * set by the caller. If this is set to 0, then no specific format is + * requested from the decoder, and its native format is output. */ OSType cv_pix_fmt_type; From f07492e7fb6601948649ea09a25a493b3da0b75b Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 24 Feb 2017 10:48:13 +0100 Subject: [PATCH 0990/3374] avcodec/videotoolbox: set kCVPixelBufferIOSurfaceOpenGLTextureCompatibilityKey Makes sure the output can be mapped as OpenGL texture. This is what at least video players normally want. --- libavcodec/videotoolbox.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/videotoolbox.c b/libavcodec/videotoolbox.c index 2ebe60fb5c0d0..824f2d8e683f6 100644 --- a/libavcodec/videotoolbox.c +++ b/libavcodec/videotoolbox.c @@ -477,6 +477,7 @@ static CFDictionaryRef videotoolbox_buffer_attributes_create(int width, CFDictionarySetValue(buffer_attributes, kCVPixelBufferIOSurfacePropertiesKey, io_surface_properties); CFDictionarySetValue(buffer_attributes, kCVPixelBufferWidthKey, w); CFDictionarySetValue(buffer_attributes, kCVPixelBufferHeightKey, h); + CFDictionarySetValue(buffer_attributes, kCVPixelBufferIOSurfaceOpenGLTextureCompatibilityKey, kCFBooleanTrue); CFRelease(io_surface_properties); CFRelease(cv_pix_fmt); From 2b8151c80690a71db2cf8009855b4ae1a6abdd4c Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Fri, 25 Nov 2016 12:36:05 +0000 Subject: [PATCH 0991/3374] hwcontext_vaapi: Don't abort on failing to allocate from a fixed-size pool Cherry-picked from Libav d30719e62de68975cbc7ffd318df03a183037563. Signed-off-by: wm4 --- libavutil/hwcontext_vaapi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index 6176bdc880c81..da15f891300b0 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -397,6 +397,10 @@ static AVBufferRef *vaapi_pool_alloc(void *opaque, int size) VAStatus vas; AVBufferRef *ref; + if (hwfc->initial_pool_size > 0 && + avfc->nb_surfaces >= hwfc->initial_pool_size) + return NULL; + vas = vaCreateSurfaces(hwctx->display, ctx->rt_format, hwfc->width, hwfc->height, &surface_id, 1, From a63496cc882428aefafc85d2f60e0908b020bffe Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Thu, 2 Mar 2017 11:21:48 +0100 Subject: [PATCH 0992/3374] avcodec: add ClearVideo decoder Only I-frames are decoded for now. Signed-off-by: Paul B Mahol --- Changelog | 1 + doc/general.texi | 1 + libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/avcodec.h | 1 + libavcodec/clearvideo.c | 387 ++++++++++++++++++++++++++++++++++++++++ libavcodec/codec_desc.c | 7 + libavcodec/version.h | 4 +- libavformat/riff.c | 1 + libavformat/rm.c | 1 + 10 files changed, 403 insertions(+), 2 deletions(-) create mode 100644 libavcodec/clearvideo.c diff --git a/Changelog b/Changelog index beb3486524aed..13628ca28b5d7 100644 --- a/Changelog +++ b/Changelog @@ -25,6 +25,7 @@ version : - FM Screen Capture Codec decoder - native Opus encoder - ScreenPressor decoder +- incomplete ClearVideo decoder version 3.2: - libopenmpt demuxer diff --git a/doc/general.texi b/doc/general.texi index 626590ca7660f..30450c0cefa84 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -342,6 +342,7 @@ library: @item iLBC @tab X @tab X @item Interplay MVE @tab @tab X @tab Format used in various Interplay computer games. +@item Iterated Systems ClearVideo @tab @tab X @item IV8 @tab @tab X @tab A format generated by IndigoVision 8000 video server. @item IVF (On2) @tab X @tab X diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 1bea44ad9134d..65ccbade8ef29 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -228,6 +228,7 @@ OBJS-$(CONFIG_CDXL_DECODER) += cdxl.o OBJS-$(CONFIG_CFHD_DECODER) += cfhd.o cfhddata.o OBJS-$(CONFIG_CINEPAK_DECODER) += cinepak.o OBJS-$(CONFIG_CINEPAK_ENCODER) += cinepakenc.o elbg.o +OBJS-$(CONFIG_CLEARVIDEO_DECODER) += clearvideo.o OBJS-$(CONFIG_CLJR_DECODER) += cljrdec.o OBJS-$(CONFIG_CLJR_ENCODER) += cljrenc.o OBJS-$(CONFIG_CLLC_DECODER) += cllc.o canopus.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index eee322b2b8c07..a265ce5728da3 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -157,6 +157,7 @@ void avcodec_register_all(void) REGISTER_DECODER(CDXL, cdxl); REGISTER_DECODER(CFHD, cfhd); REGISTER_ENCDEC (CINEPAK, cinepak); + REGISTER_DECODER(CLEARVIDEO, clearvideo); REGISTER_ENCDEC (CLJR, cljr); REGISTER_DECODER(CLLC, cllc); REGISTER_ENCDEC (COMFORTNOISE, comfortnoise); diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 298b9146e27ff..af054f3194fdc 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -416,6 +416,7 @@ enum AVCodecID { AV_CODEC_ID_SPEEDHQ, AV_CODEC_ID_FMVC, AV_CODEC_ID_SCPR, + AV_CODEC_ID_CLEARVIDEO, /* various PCM "codecs" */ AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs diff --git a/libavcodec/clearvideo.c b/libavcodec/clearvideo.c new file mode 100644 index 0000000000000..91f37e1b62a7f --- /dev/null +++ b/libavcodec/clearvideo.c @@ -0,0 +1,387 @@ +/* + * ClearVideo decoder + * Copyright (c) 2012 Konstantin Shishkov + * + * 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 + */ + +/** + * @file + * ClearVideo decoder + */ + +#include "avcodec.h" +#include "idctdsp.h" +#include "internal.h" +#include "get_bits.h" +#include "bytestream.h" + +#define NUM_DC_CODES 127 +#define NUM_AC_CODES 103 + +static const uint8_t clv_dc_codes[NUM_DC_CODES] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x13, 0x14, 0x07, 0x0B, + 0x0C, 0x08, 0x08, 0x09, 0x04, 0x06, 0x07, 0x05, + 0x04, 0x05, 0x04, 0x06, 0x05, 0x06, 0x07, 0x05, + 0x06, 0x07, 0x06, 0x07, 0x08, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x07, 0x08, 0x09, 0x07, 0x08, + 0x06, 0x07, 0x08, 0x06, 0x04, 0x05, 0x02, 0x01, + 0x03, 0x06, 0x07, 0x07, 0x09, 0x0A, 0x0B, 0x09, + 0x0A, 0x0B, 0x0A, 0x0B, 0x0C, 0x0D, 0x0C, 0x09, + 0x0D, 0x0A, 0x0B, 0x08, 0x09, 0x0A, 0x0B, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x06, 0x07, 0x06, 0x08, + 0x07, 0x09, 0x0A, 0x0B, 0x09, 0x0A, 0x0B, 0x0C, + 0x14, 0x0D, 0x0D, 0x0E, 0x0F, 0x15, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, + 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, +}; + +static const uint8_t clv_dc_bits[NUM_DC_CODES] = { + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 21, 22, 22, 19, 20, + 20, 19, 18, 18, 15, 17, 17, 16, + 14, 15, 12, 13, 14, 14, 14, 12, + 12, 12, 11, 11, 11, 10, 10, 10, + 10, 10, 10, 9, 9, 9, 8, 8, + 7, 7, 7, 6, 5, 5, 3, 1, + 3, 5, 5, 6, 7, 7, 7, 8, + 8, 8, 9, 9, 9, 9, 10, 11, + 10, 11, 11, 12, 12, 12, 12, 13, + 14, 14, 14, 14, 15, 15, 16, 17, + 16, 17, 18, 18, 19, 19, 19, 19, + 21, 19, 20, 19, 19, 21, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, +}; + +static const uint16_t clv_ac_syms[NUM_AC_CODES] = { + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, + 0x0009, 0x000A, 0x000B, 0x000C, 0x0011, 0x0012, 0x0013, 0x0014, + 0x0015, 0x0016, 0x0021, 0x0022, 0x0023, 0x0024, 0x0031, 0x0032, + 0x0033, 0x0041, 0x0042, 0x0043, 0x0051, 0x0052, 0x0053, 0x0061, + 0x0062, 0x0063, 0x0071, 0x0072, 0x0081, 0x0082, 0x0091, 0x0092, + 0x00A1, 0x00A2, 0x00B1, 0x00C1, 0x00D1, 0x00E1, 0x00F1, 0x0101, + 0x0111, 0x0121, 0x0131, 0x0141, 0x0151, 0x0161, 0x0171, 0x0181, + 0x0191, 0x01A1, 0x1001, 0x1002, 0x1003, 0x1011, 0x1012, 0x1021, + 0x1031, 0x1041, 0x1051, 0x1061, 0x1071, 0x1081, 0x1091, 0x10A1, + 0x10B1, 0x10C1, 0x10D1, 0x10E1, 0x10F1, 0x1101, 0x1111, 0x1121, + 0x1131, 0x1141, 0x1151, 0x1161, 0x1171, 0x1181, 0x1191, 0x11A1, + 0x11B1, 0x11C1, 0x11D1, 0x11E1, 0x11F1, 0x1201, 0x1211, 0x1221, + 0x1231, 0x1241, 0x1251, 0x1261, 0x1271, 0x1281, 0x1BFF, +}; + +static const uint8_t clv_ac_codes[NUM_AC_CODES] = { + 0x02, 0x0F, 0x15, 0x17, 0x1F, 0x25, 0x24, 0x21, + 0x20, 0x07, 0x06, 0x20, 0x06, 0x14, 0x1E, 0x0F, + 0x21, 0x50, 0x0E, 0x1D, 0x0E, 0x51, 0x0D, 0x23, + 0x0D, 0x0C, 0x22, 0x52, 0x0B, 0x0C, 0x53, 0x13, + 0x0B, 0x54, 0x12, 0x0A, 0x11, 0x09, 0x10, 0x08, + 0x16, 0x55, 0x15, 0x14, 0x1C, 0x1B, 0x21, 0x20, + 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x22, 0x23, + 0x56, 0x57, 0x07, 0x19, 0x05, 0x0F, 0x04, 0x0E, + 0x0D, 0x0C, 0x13, 0x12, 0x11, 0x10, 0x1A, 0x19, + 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x18, 0x17, + 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x07, 0x06, + 0x05, 0x04, 0x24, 0x25, 0x26, 0x27, 0x58, 0x59, + 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x03, +}; + +static const uint8_t clv_ac_bits[NUM_AC_CODES] = { + 2, 4, 6, 7, 8, 9, 9, 10, + 10, 11, 11, 11, 3, 6, 8, 10, + 11, 12, 4, 8, 10, 12, 5, 9, + 10, 5, 9, 12, 5, 10, 12, 6, + 10, 12, 6, 10, 6, 10, 6, 10, + 7, 12, 7, 7, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9, 11, 11, + 12, 12, 4, 9, 11, 6, 11, 6, + 6, 6, 7, 7, 7, 7, 8, 8, + 8, 8, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9, 10, 10, + 10, 10, 11, 11, 11, 11, 12, 12, + 12, 12, 12, 12, 12, 12, 7, +}; + +typedef struct CLVContext { + AVCodecContext *avctx; + IDCTDSPContext idsp; + AVFrame *pic; + GetBitContext gb; + int mb_width, mb_height; + VLC dc_vlc, ac_vlc; + int luma_dc_quant, chroma_dc_quant, ac_quant; + DECLARE_ALIGNED(16, int16_t, block)[64]; + int top_dc[3], left_dc[4]; +} CLVContext; + +static inline int decode_block(CLVContext *ctx, int16_t *blk, int has_ac, + int ac_quant) +{ + GetBitContext *gb = &ctx->gb; + int idx = 1, last = 0, val, skip; + + memset(blk, 0, sizeof(*blk) * 64); + blk[0] = get_vlc2(gb, ctx->dc_vlc.table, 9, 3); + if (blk[0] < 0) + return AVERROR_INVALIDDATA; + blk[0] -= 63; + + if (!has_ac) + return 0; + + while (idx < 64 && !last) { + val = get_vlc2(gb, ctx->ac_vlc.table, 9, 2); + if (val < 0) + return AVERROR_INVALIDDATA; + if (val != 0x1BFF) { + last = val >> 12; + skip = (val >> 4) & 0xFF; + val &= 0xF; + if (get_bits1(gb)) + val = -val; + } else { + last = get_bits1(gb); + skip = get_bits(gb, 6); + val = get_sbits(gb, 8); + } + if (val) { + int aval = FFABS(val), sign = val < 0; + val = ac_quant * (2 * aval + 1); + if (!(ac_quant & 1)) + val--; + if (sign) + val = -val; + } + idx += skip; + if (idx >= 64) + return AVERROR_INVALIDDATA; + blk[ff_zigzag_direct[idx++]] = val; + } + + return (idx <= 64 && last) ? 0 : -1; +} + +#define DCT_TEMPLATE(blk, step, bias, shift, dshift, OP) \ + const int t0 = OP( 2841 * blk[1 * step] + 565 * blk[7 * step]); \ + const int t1 = OP( 565 * blk[1 * step] - 2841 * blk[7 * step]); \ + const int t2 = OP( 1609 * blk[5 * step] + 2408 * blk[3 * step]); \ + const int t3 = OP( 2408 * blk[5 * step] - 1609 * blk[3 * step]); \ + const int t4 = OP( 1108 * blk[2 * step] - 2676 * blk[6 * step]); \ + const int t5 = OP( 2676 * blk[2 * step] + 1108 * blk[6 * step]); \ + const int t6 = ((blk[0 * step] + blk[4 * step]) << dshift) + bias; \ + const int t7 = ((blk[0 * step] - blk[4 * step]) << dshift) + bias; \ + const int t8 = t0 + t2; \ + const int t9 = t0 - t2; \ + const int tA = 181 * (t9 + (t1 - t3)) + 0x80 >> 8; \ + const int tB = 181 * (t9 - (t1 - t3)) + 0x80 >> 8; \ + const int tC = t1 + t3; \ + \ + blk[0 * step] = (t6 + t5 + t8) >> shift; \ + blk[1 * step] = (t7 + t4 + tA) >> shift; \ + blk[2 * step] = (t7 - t4 + tB) >> shift; \ + blk[3 * step] = (t6 - t5 + tC) >> shift; \ + blk[4 * step] = (t6 - t5 - tC) >> shift; \ + blk[5 * step] = (t7 - t4 - tB) >> shift; \ + blk[6 * step] = (t7 + t4 - tA) >> shift; \ + blk[7 * step] = (t6 + t5 - t8) >> shift; \ + +#define ROP(x) x +#define COP(x) (((x) + 4) >> 3) + +static void clv_dct(int16_t *block) +{ + int i; + int16_t *ptr; + + ptr = block; + for (i = 0; i < 8; i++) { + DCT_TEMPLATE(ptr, 1, 0x80, 8, 11, ROP); + ptr += 8; + } + + ptr = block; + for (i = 0; i < 8; i++) { + DCT_TEMPLATE(ptr, 8, 0x2000, 14, 8, COP); + ptr++; + } +} + +static int decode_mb(CLVContext *c, int x, int y) +{ + int i; + int has_ac[6]; + int off; + + for (i = 0; i < 6; i++) + has_ac[i] = get_bits1(&c->gb); + + off = x * 16 + y * 16 * c->pic->linesize[0]; + for (i = 0; i < 4; i++) { + if (decode_block(c, c->block, has_ac[i], c->ac_quant) < 0) + return AVERROR_INVALIDDATA; + if (!x && !(i & 1)) { + c->block[0] += c->top_dc[0]; + c->top_dc[0] = c->block[0]; + } else { + c->block[0] += c->left_dc[(i & 2) >> 1]; + } + c->left_dc[(i & 2) >> 1] = c->block[0]; + c->block[0] *= c->luma_dc_quant; + clv_dct(c->block); + if (i == 2) + off += c->pic->linesize[0] * 8; + c->idsp.put_pixels_clamped(c->block, c->pic->data[0] + off + (i & 1) * 8, + c->pic->linesize[0]); + } + + off = x * 8 + y * 8 * c->pic->linesize[1]; + for (i = 1; i < 3; i++) { + if (decode_block(c, c->block, has_ac[i + 3], c->ac_quant) < 0) + return AVERROR_INVALIDDATA; + if (!x) { + c->block[0] += c->top_dc[i]; + c->top_dc[i] = c->block[0]; + } else { + c->block[0] += c->left_dc[i + 1]; + } + c->left_dc[i + 1] = c->block[0]; + c->block[0] *= c->chroma_dc_quant; + clv_dct(c->block); + c->idsp.put_pixels_clamped(c->block, c->pic->data[i] + off, + c->pic->linesize[i]); + } + + return 0; +} + +static int clv_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame, AVPacket *avpkt) +{ + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + CLVContext *c = avctx->priv_data; + GetByteContext gb; + uint32_t frame_type; + int i, j; + int ret; + + bytestream2_init(&gb, buf, buf_size); + if (avctx->codec_tag == MKTAG('C','L','V','1')) { + int skip = bytestream2_get_byte(&gb); + bytestream2_skip(&gb, (skip + 1) * 8); + } + + frame_type = bytestream2_get_byte(&gb); + if ((ret = ff_reget_buffer(avctx, c->pic)) < 0) + return ret; + + c->pic->key_frame = frame_type & 0x20 ? 1 : 0; + c->pic->pict_type = frame_type & 0x20 ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; + + if (frame_type & 0x2) { + bytestream2_get_be32(&gb); // frame size; + c->ac_quant = bytestream2_get_byte(&gb); + c->luma_dc_quant = 32; + c->chroma_dc_quant = 32; + + if ((ret = init_get_bits8(&c->gb, buf + bytestream2_tell(&gb), + (buf_size - bytestream2_tell(&gb)))) < 0) + return ret; + + for (i = 0; i < 3; i++) + c->top_dc[i] = 32; + for (i = 0; i < 4; i++) + c->left_dc[i] = 32; + + for (j = 0; j < c->mb_height; j++) { + for (i = 0; i < c->mb_width; i++) { + ret |= decode_mb(c, i, j); + } + } + } else { + } + + if ((ret = av_frame_ref(data, c->pic)) < 0) + return ret; + + *got_frame = 1; + + return ret < 0 ? ret : buf_size; +} + +static av_cold int clv_decode_init(AVCodecContext *avctx) +{ + CLVContext * const c = avctx->priv_data; + int ret; + + c->avctx = avctx; + + avctx->pix_fmt = AV_PIX_FMT_YUV420P; + + c->pic = av_frame_alloc(); + if (!c->pic) + return AVERROR(ENOMEM); + + c->mb_width = FFALIGN(avctx->width, 16) >> 4; + c->mb_height = FFALIGN(avctx->height, 16) >> 4; + + ff_idctdsp_init(&c->idsp, avctx); + ret = init_vlc(&c->dc_vlc, 9, NUM_DC_CODES, + clv_dc_bits, 1, 1, + clv_dc_codes, 1, 1, 0); + if (ret) { + av_log(avctx, AV_LOG_ERROR, "Error initialising DC VLC\n"); + return ret; + } + ret = ff_init_vlc_sparse(&c->ac_vlc, 9, NUM_AC_CODES, + clv_ac_bits, 1, 1, + clv_ac_codes, 1, 1, + clv_ac_syms, 2, 2, 0); + if (ret) { + av_log(avctx, AV_LOG_ERROR, "Error initialising AC VLC\n"); + return ret; + } + + return 0; +} + +static av_cold int clv_decode_end(AVCodecContext *avctx) +{ + CLVContext * const c = avctx->priv_data; + + av_frame_free(&c->pic); + + ff_free_vlc(&c->dc_vlc); + ff_free_vlc(&c->ac_vlc); + + return 0; +} + +AVCodec ff_clearvideo_decoder = { + .name = "clearvideo", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_CLEARVIDEO, + .priv_data_size = sizeof(CLVContext), + .init = clv_decode_init, + .close = clv_decode_end, + .decode = clv_decode_frame, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("Iterated Systems ClearVideo"), +}; diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 42935d756026d..06bcfc3cce31d 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -1367,6 +1367,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("ScreenPressor"), .props = AV_CODEC_PROP_LOSSLESS | AV_CODEC_PROP_LOSSY, }, + { + .id = AV_CODEC_ID_CLEARVIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "clearvideo", + .long_name = NULL_IF_CONFIG_SMALL("Iterated Systems ClearVideo"), + .props = AV_CODEC_PROP_LOSSY, + }, /* image codecs */ { diff --git a/libavcodec/version.h b/libavcodec/version.h index 5d8b22cb29a96..7647ad2e189e6 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 81 -#define LIBAVCODEC_VERSION_MICRO 103 +#define LIBAVCODEC_VERSION_MINOR 82 +#define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavformat/riff.c b/libavformat/riff.c index e38c63632f5ca..e3fb953622e92 100644 --- a/libavformat/riff.c +++ b/libavformat/riff.c @@ -450,6 +450,7 @@ const AVCodecTag ff_codec_bmp_tags[] = { { AV_CODEC_ID_SPEEDHQ, MKTAG('S', 'H', 'Q', '9') }, { AV_CODEC_ID_FMVC, MKTAG('F', 'M', 'V', 'C') }, { AV_CODEC_ID_SCPR, MKTAG('S', 'C', 'P', 'R') }, + { AV_CODEC_ID_CLEARVIDEO, MKTAG('U', 'C', 'O', 'D') }, { AV_CODEC_ID_NONE, 0 } }; diff --git a/libavformat/rm.c b/libavformat/rm.c index 0591a1735ad3c..52c7ccc1e8e80 100644 --- a/libavformat/rm.c +++ b/libavformat/rm.c @@ -43,5 +43,6 @@ const AVCodecTag ff_rm_codec_tags[] = { { AV_CODEC_ID_AAC, MKTAG('r','a','a','c') }, { AV_CODEC_ID_AAC, MKTAG('r','a','c','p') }, { AV_CODEC_ID_RALF, MKTAG('L','S','D',':') }, + { AV_CODEC_ID_CLEARVIDEO, MKTAG('C','L','V','1') }, { AV_CODEC_ID_NONE }, }; From d1bfd19ad196b33d6fde07dbb9060946368ec2c1 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Thu, 2 Mar 2017 18:05:58 +0100 Subject: [PATCH 0993/3374] doc: Link to "Resampler Options" in the aresample documentation. --- doc/filters.texi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/filters.texi b/doc/filters.texi index 3b444c7667b87..b5265d929773d 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -1413,7 +1413,9 @@ The filter accepts the syntax [@var{sample_rate}:]@var{resampler_options}, where @var{sample_rate} expresses a sample rate and @var{resampler_options} is a list of @var{key}=@var{value} pairs, separated by ":". See the -ffmpeg-resampler manual for the complete list of supported options. +@ref{Resampler Options,,the "Resampler Options" section in the +ffmpeg-resampler(1) manual,ffmpeg-resampler} +for the complete list of supported options. @subsection Examples From 46082c2b3f2158ca3a69b7cd2b105cc763e9c3e7 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Wed, 1 Mar 2017 23:45:10 +0100 Subject: [PATCH 0994/3374] lavc/sheervideo: Fix Y prediction for interlaced frames with transparency. Based on 260de8a2 by Paul B Mahol. Fixes ticket #6210. --- libavcodec/sheervideo.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/sheervideo.c b/libavcodec/sheervideo.c index e8f008b7e4a59..9d2da7ffb4872 100644 --- a/libavcodec/sheervideo.c +++ b/libavcodec/sheervideo.c @@ -2185,7 +2185,7 @@ static void decode_aybri(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) dst_v[x] = get_bits(gb, 8); } } else { - int pred[4] = { 125, 125, -128, -128 }; + int pred[4] = { 125, s->alt ? 125 : -146, -128, -128 }; for (x = 0; x < avctx->width; x++) { int a, y, u, v; @@ -2263,7 +2263,7 @@ static void decode_aybr(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb) dst_v[x] = get_bits(gb, 8); } } else { - int pred[4] = { 125, 125, -128, -128 }; + int pred[4] = { 125, s->alt ? 125 : -146, -128, -128 }; for (x = 0; x < avctx->width; x++) { int a, y, u, v; @@ -2959,6 +2959,7 @@ static int decode_frame(AVCodecContext *avctx, } break; case MKTAG('A', 'Y', 'B', 'R'): + s->alt = 1; case MKTAG('A', 'Y', 'b', 'R'): avctx->pix_fmt = AV_PIX_FMT_YUVA444P; s->decode_frame = decode_aybr; @@ -2968,6 +2969,7 @@ static int decode_frame(AVCodecContext *avctx, } break; case MKTAG('A', 'y', 'B', 'R'): + s->alt = 1; case MKTAG('A', 'y', 'b', 'R'): avctx->pix_fmt = AV_PIX_FMT_YUVA444P; s->decode_frame = decode_aybri; From 4b72d5cd6f9341dcafdbc1b9030166aa987b8304 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 1 Mar 2017 16:32:09 +0100 Subject: [PATCH 0995/3374] avcodec/mjpegdec: Fix runtime error: left shift of negative value -511 Fixes: 693/clusterfuzz-testcase-6109776066904064 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/mjpegdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 69469c5229cce..2b5adfc61be99 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -1157,7 +1157,7 @@ static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, if (s->interlaced && s->bottom_field) ptr16 += linesize >> 1; pred &= mask; - *ptr16= pred + (dc << point_transform); + *ptr16= pred + ((unsigned)dc << point_transform); } if (++x == h) { x = 0; From 3b0b35150df4a9da75105662d145603151de6714 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 1 Mar 2017 16:35:58 +0100 Subject: [PATCH 0996/3374] avcodec/mpegaudiodec_template: Fix runtime error: signed integer overflow: 2053224902 + 2053224902 cannot be represented in type 'int' Fixes: 696/clusterfuzz-testcase-5853632270434304 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/mpegaudiodec_template.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/mpegaudiodec_template.c b/libavcodec/mpegaudiodec_template.c index a389318a2a958..a3729a9e297e2 100644 --- a/libavcodec/mpegaudiodec_template.c +++ b/libavcodec/mpegaudiodec_template.c @@ -457,7 +457,7 @@ static av_cold int decode_init(AVCodecContext * avctx) /* 12 points IMDCT. We compute it "by hand" by factorizing obvious cases. */ -static void imdct12(INTFLOAT *out, INTFLOAT *in) +static void imdct12(INTFLOAT *out, SUINTFLOAT *in) { SUINTFLOAT in0, in1, in2, in3, in4, in5, t1, t2; From 6191198c216e0ca38d6e65270d2f1b054584a0a9 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 1 Mar 2017 17:56:23 +0100 Subject: [PATCH 0997/3374] avcodec/interplayvideo: Fix timeout from lack of bitstream end check Fixes: 697/clusterfuzz-testcase-6111250582863872 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/interplayvideo.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/interplayvideo.c b/libavcodec/interplayvideo.c index 8d2f3ab48c856..df3314d4b70a7 100644 --- a/libavcodec/interplayvideo.c +++ b/libavcodec/interplayvideo.c @@ -928,6 +928,8 @@ static void ipvideo_decode_opcodes(IpvideoContext *s, AVFrame *frame) init_get_bits(&gb, s->decoding_map, s->decoding_map_size * 8); for (y = 0; y < s->avctx->height; y += 8) { for (x = 0; x < s->avctx->width; x += 8) { + if (get_bits_left(&gb) < 4) + return; opcode = get_bits(&gb, 4); ff_tlog(s->avctx, From 55196e5d10af7c295352bb9a2d7565efe07ce46b Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 1 Mar 2017 13:02:11 +0100 Subject: [PATCH 0998/3374] Revert "avutil/frame: Disallow zero sized frame side data" Found a case where we use size==0, the other related commits remain needed, and should be sufficient to fix the original issue This reverts commit 7e4f32f4e4b93c95dcc872cb844c5548e69f352e. Signed-off-by: Michael Niedermayer --- libavutil/frame.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/libavutil/frame.c b/libavutil/frame.c index 69ee240758743..8811dcdcfec40 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -668,8 +668,6 @@ AVFrameSideData *av_frame_new_side_data(AVFrame *frame, enum AVFrameSideDataType type, int size) { - if (size <= 0) - return NULL; return frame_new_side_data(frame, type, av_buffer_alloc(size)); } From 9ae762da7e256aa4d3b645c614fcd1959e1cbb8d Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Wed, 1 Mar 2017 23:40:35 +0100 Subject: [PATCH 0999/3374] lavf/matroska: Support codec ID V_FFV1 for demuxing. Fixes ticket #6206. --- libavformat/matroska.c | 1 + libavformat/matroskaenc.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libavformat/matroska.c b/libavformat/matroska.c index fda96fb01439a..7905fd1ff7473 100644 --- a/libavformat/matroska.c +++ b/libavformat/matroska.c @@ -77,6 +77,7 @@ const CodecTags ff_mkv_codec_tags[]={ {"S_HDMV/TEXTST" , AV_CODEC_ID_HDMV_TEXT_SUBTITLE}, {"V_DIRAC" , AV_CODEC_ID_DIRAC}, + {"V_FFV1" , AV_CODEC_ID_FFV1}, {"V_MJPEG" , AV_CODEC_ID_MJPEG}, {"V_MPEG1" , AV_CODEC_ID_MPEG1VIDEO}, {"V_MPEG2" , AV_CODEC_ID_MPEG2VIDEO}, diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 7cb88935fb037..1622b44e5ecc8 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -1138,7 +1138,7 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, // if none are found, use AVI codes if (par->codec_id != AV_CODEC_ID_RAWVIDEO || par->codec_tag) { for (j = 0; ff_mkv_codec_tags[j].id != AV_CODEC_ID_NONE; j++) { - if (ff_mkv_codec_tags[j].id == par->codec_id) { + if (ff_mkv_codec_tags[j].id == par->codec_id && par->codec_id != AV_CODEC_ID_FFV1) { put_ebml_string(pb, MATROSKA_ID_CODECID, ff_mkv_codec_tags[j].str); native_id = 1; break; From 33580a8625c77591919b6155a48da04dccc8d398 Mon Sep 17 00:00:00 2001 From: wm4 Date: Wed, 8 Feb 2017 09:53:26 +0100 Subject: [PATCH 1000/3374] 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 --- ffmpeg.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index 38395e7598234..5adec2b2907d7 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; } From 4ee5aed122ba7d289c1686eca6eba161d5d62304 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 27 May 2016 12:04:29 +0200 Subject: [PATCH 1001/3374] 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 --- 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 5adec2b2907d7..983e2fb486d65 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(&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:video " "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, &ost->mux_timebase), + av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &ost->mux_timebase)); } frame_size = pkt.size; @@ -1862,7 +1864,7 @@ static void flush_encoders(void) av_packet_unref(&pkt); continue; } - av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base); + av_packet_rescale_ts(&pkt, enc->time_base, ost->mux_timebase); pkt_size = pkt.size; output_packet(of, &pkt, ost); if (ost->enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO && vstats_filename) { @@ -1897,7 +1899,7 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p OutputFile *of = output_files[ost->file_index]; InputFile *f = input_files [ist->file_index]; int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time; - int64_t ost_tb_start_time = av_rescale_q(start_time, AV_TIME_BASE_Q, ost->st->time_base); + int64_t ost_tb_start_time = av_rescale_q(start_time, AV_TIME_BASE_Q, ost->mux_timebase); AVPicture pict; AVPacket opkt; @@ -1938,14 +1940,14 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p ost->sync_opts++; if (pkt->pts != AV_NOPTS_VALUE) - opkt.pts = av_rescale_q(pkt->pts, ist->st->time_base, ost->st->time_base) - ost_tb_start_time; + opkt.pts = av_rescale_q(pkt->pts, ist->st->time_base, ost->mux_timebase) - ost_tb_start_time; else opkt.pts = AV_NOPTS_VALUE; if (pkt->dts == AV_NOPTS_VALUE) - opkt.dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q, ost->st->time_base); + opkt.dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q, ost->mux_timebase); else - opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->st->time_base); + opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->mux_timebase); opkt.dts -= ost_tb_start_time; if (ost->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && pkt->dts != AV_NOPTS_VALUE) { @@ -1954,10 +1956,11 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p duration = ist->dec_ctx->frame_size; opkt.dts = opkt.pts = av_rescale_delta(ist->st->time_base, pkt->dts, (AVRational){1, ist->dec_ctx->sample_rate}, duration, &ist->filter_in_rescale_delta_last, - ost->st->time_base) - ost_tb_start_time; + ost->mux_timebase) - ost_tb_start_time; } - opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->st->time_base); + opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->mux_timebase); + opkt.flags = pkt->flags; // FIXME remove the following 2 lines they shall be replaced by the bitstream filters if ( ost->st->codecpar->codec_id != AV_CODEC_ID_H264 @@ -2822,6 +2825,10 @@ static int check_init_output_file(OutputFile *of, int file_index) for (i = 0; i < of->ctx->nb_streams; i++) { OutputStream *ost = output_streams[of->ost_index + i]; + /* try to improve muxing time_base (only possible if nothing has been written yet) */ + if (!av_fifo_size(ost->muxing_queue)) + ost->mux_timebase = ost->st->time_base; + while (av_fifo_size(ost->muxing_queue)) { AVPacket pkt; av_fifo_generic_read(ost->muxing_queue, &pkt, sizeof(pkt), NULL); @@ -2981,6 +2988,8 @@ static int init_output_stream_streamcopy(OutputStream *ost) break; } + ost->mux_timebase = ist->st->time_base; + return 0; } @@ -3236,7 +3245,7 @@ static int init_output_stream_encode(OutputStream *ost) } break; case AVMEDIA_TYPE_SUBTITLE: - enc_ctx->time_base = (AVRational){1, 1000}; + enc_ctx->time_base = AV_TIME_BASE_Q; if (!enc_ctx->width) { enc_ctx->width = input_streams[ost->source_index]->st->codecpar->width; enc_ctx->height = input_streams[ost->source_index]->st->codecpar->height; @@ -3249,6 +3258,8 @@ static int init_output_stream_encode(OutputStream *ost) break; } + ost->mux_timebase = enc_ctx->time_base; + return 0; } diff --git a/ffmpeg.h b/ffmpeg.h index 458bb8a3dc280..ca35ccc260fc4 100644 --- a/ffmpeg.h +++ b/ffmpeg.h @@ -446,6 +446,8 @@ typedef struct OutputStream { int64_t first_pts; /* dts of the last packet sent to the muxer */ int64_t last_mux_dts; + // the timebase of the packets sent to the muxer + AVRational mux_timebase; int nb_bitstream_filters; uint8_t *bsf_extradata_updated; diff --git a/tests/ref/fate/binsub-movtextenc b/tests/ref/fate/binsub-movtextenc index 6efe2c015a0bd..22ee85a2f8fa6 100644 --- a/tests/ref/fate/binsub-movtextenc +++ b/tests/ref/fate/binsub-movtextenc @@ -1 +1 @@ -ef264064c522389d0cf267c4d6235561 +af6a8f38d7c11d9af7823cc44554d2ad diff --git a/tests/ref/fate/sub2video b/tests/ref/fate/sub2video index ace6d38538d2c..4e034a5e91db6 100644 --- a/tests/ref/fate/sub2video +++ b/tests/ref/fate/sub2video @@ -4,13 +4,13 @@ #codec_id 0: rawvideo #dimensions 0: 720x480 #sar 0: 0/1 -#tb 1: 1/1000 +#tb 1: 1/1000000 #media_type 1: subtitle #codec_id 1: dvd_subtitle 0, 0, 0, 1, 518400, 0x83c27b82 0, 1, 1, 1, 518400, 0x4051c7f9 0, 2, 2, 1, 518400, 0xfb00e17e -1, 499, 499, 4960, 1015, 0x19e092d2, F=0x0 +1, 499000, 499000, 4960000, 1015, 0x19e092d2, F=0x0 0, 3, 3, 1, 518400, 0x192abb74 0, 4, 4, 1, 518400, 0x4669a88b 0, 5, 5, 1, 518400, 0xaababe00 @@ -58,129 +58,129 @@ 0, 47, 47, 1, 518400, 0xde69683f 0, 48, 48, 1, 518400, 0x7df08fba 0, 49, 49, 1, 518400, 0xbab197ea -1, 15355, 15355, 4733, 2094, 0x3c171425, F=0x0 +1, 15355000, 15355000, 4733000, 2094, 0x3c171425, F=0x0 0, 77, 77, 1, 518400, 0x902285d9 0, 100, 100, 1, 518400, 0xbab197ea -1, 48797, 48797, 2560, 2480, 0x7c0edf21, F=0x0 +1, 48797000, 48797000, 2560000, 2480, 0x7c0edf21, F=0x0 0, 244, 244, 1, 518400, 0x7a11c812 0, 257, 257, 1, 518400, 0xbab197ea -1, 51433, 51433, 2366, 3059, 0xc95b8a05, F=0x0 +1, 51433000, 51433000, 2366000, 3059, 0xc95b8a05, F=0x0 0, 258, 258, 1, 518400, 0x34cdddee 0, 269, 269, 1, 518400, 0xbab197ea -1, 53910, 53910, 2696, 2095, 0x61bb15ed, F=0x0 +1, 53910000, 53910000, 2696000, 2095, 0x61bb15ed, F=0x0 0, 270, 270, 1, 518400, 0x4db4ce51 0, 283, 283, 1, 518400, 0xbab197ea -1, 56663, 56663, 1262, 1013, 0xc9ae89b7, F=0x0 +1, 56663000, 56663000, 1262000, 1013, 0xc9ae89b7, F=0x0 0, 284, 284, 1, 518400, 0xe6bc0ea9 0, 290, 290, 1, 518400, 0xbab197ea -1, 58014, 58014, 1661, 969, 0xe01878f0, F=0x0 +1, 58014000, 58014000, 1661000, 969, 0xe01878f0, F=0x0 0, 291, 291, 1, 518400, 0xa8643af7 0, 298, 298, 1, 518400, 0xbab197ea -1, 67724, 67724, 1365, 844, 0xe7db4fc1, F=0x0 +1, 67724000, 67724000, 1365000, 844, 0xe7db4fc1, F=0x0 0, 339, 339, 1, 518400, 0xb1885c67 0, 345, 345, 1, 518400, 0xbab197ea -1, 69175, 69175, 1558, 802, 0xf48531ba, F=0x0 +1, 69175000, 69175000, 1558000, 802, 0xf48531ba, F=0x0 0, 346, 346, 1, 518400, 0x378e3fd0 0, 354, 354, 1, 518400, 0xbab197ea -1, 70819, 70819, 1865, 1709, 0xb4d5a1bd, F=0x0 +1, 70819000, 70819000, 1865000, 1709, 0xb4d5a1bd, F=0x0 0, 355, 355, 1, 518400, 0xa3782469 0, 363, 363, 1, 518400, 0xbab197ea -1, 72762, 72762, 1968, 2438, 0x99d7bc82, F=0x0 +1, 72762000, 72762000, 1968000, 2438, 0x99d7bc82, F=0x0 0, 364, 364, 1, 518400, 0xba23a0d5 0, 374, 374, 1, 518400, 0xbab197ea -1, 74806, 74806, 1831, 2116, 0x96514097, F=0x0 +1, 74806000, 74806000, 1831000, 2116, 0x96514097, F=0x0 0, 375, 375, 1, 518400, 0x129de2f8 0, 383, 383, 1, 518400, 0xbab197ea -1, 76716, 76716, 1262, 1822, 0xefccc72e, F=0x0 +1, 76716000, 76716000, 1262000, 1822, 0xefccc72e, F=0x0 0, 384, 384, 1, 518400, 0x19772f0f 0, 390, 390, 1, 518400, 0xbab197ea -1, 78051, 78051, 1524, 987, 0x7b927a27, F=0x0 +1, 78051000, 78051000, 1524000, 987, 0x7b927a27, F=0x0 0, 391, 391, 1, 518400, 0x56f54e73 0, 398, 398, 1, 518400, 0xbab197ea -1, 79644, 79644, 2662, 2956, 0x190778f7, F=0x0 +1, 79644000, 79644000, 2662000, 2956, 0x190778f7, F=0x0 0, 399, 399, 1, 518400, 0x300b5247 -1, 82380, 82380, 2764, 3094, 0xc021b7d3, F=0x0 +1, 82380000, 82380000, 2764000, 3094, 0xc021b7d3, F=0x0 0, 412, 412, 1, 518400, 0xbab197ea 0, 413, 413, 1, 518400, 0x6fd028fa 0, 426, 426, 1, 518400, 0xbab197ea -1, 85225, 85225, 2366, 2585, 0x74d0048f, F=0x0 +1, 85225000, 85225000, 2366000, 2585, 0x74d0048f, F=0x0 0, 427, 427, 1, 518400, 0x01f80e9d 0, 438, 438, 1, 518400, 0xbab197ea -1, 87652, 87652, 1831, 634, 0x8832fda1, F=0x0 +1, 87652000, 87652000, 1831000, 634, 0x8832fda1, F=0x0 0, 439, 439, 1, 518400, 0xb48d90c0 0, 447, 447, 1, 518400, 0xbab197ea -1, 91531, 91531, 2332, 2080, 0x97a1146f, F=0x0 +1, 91531000, 91531000, 2332000, 2080, 0x97a1146f, F=0x0 0, 458, 458, 1, 518400, 0xcb5a0173 0, 469, 469, 1, 518400, 0xbab197ea -1, 95510, 95510, 3299, 2964, 0x8b8f6684, F=0x0 +1, 95510000, 95510000, 3299000, 2964, 0x8b8f6684, F=0x0 0, 478, 478, 1, 518400, 0xb8a323e4 0, 494, 494, 1, 518400, 0xbab197ea -1, 98872, 98872, 2161, 1875, 0x9002ef71, F=0x0 +1, 98872000, 98872000, 2161000, 1875, 0x9002ef71, F=0x0 0, 495, 495, 1, 518400, 0xc43518ba 0, 505, 505, 1, 518400, 0xbab197ea -1, 101124, 101124, 4096, 3872, 0x20c6ed9c, F=0x0 +1, 101124000, 101124000, 4096000, 3872, 0x20c6ed9c, F=0x0 0, 506, 506, 1, 518400, 0x04e38692 0, 526, 526, 1, 518400, 0xbab197ea -1, 105303, 105303, 2730, 3094, 0xf203a663, F=0x0 +1, 105303000, 105303000, 2730000, 3094, 0xf203a663, F=0x0 0, 527, 527, 1, 518400, 0x856b0ee5 0, 540, 540, 1, 518400, 0xbab197ea -1, 108106, 108106, 2059, 2404, 0x41a7b429, F=0x0 +1, 108106000, 108106000, 2059000, 2404, 0x41a7b429, F=0x0 0, 541, 541, 1, 518400, 0x3e5beee2 0, 551, 551, 1, 518400, 0xbab197ea -1, 141556, 141556, 1661, 1088, 0xde20aa20, F=0x0 +1, 141556000, 141556000, 1661000, 1088, 0xde20aa20, F=0x0 0, 708, 708, 1, 518400, 0xb8bc1365 0, 716, 716, 1, 518400, 0xbab197ea 0, 817, 817, 1, 518400, 0x83efa32d -1, 163445, 163445, 1331, 339, 0x8bd186ef, F=0x0 +1, 163445000, 163445000, 1331000, 339, 0x8bd186ef, F=0x0 0, 824, 824, 1, 518400, 0xbab197ea 0, 840, 840, 1, 518400, 0x03ea0e90 -1, 168049, 168049, 1900, 1312, 0x0bf20e8d, F=0x0 +1, 168049000, 168049000, 1900000, 1312, 0x0bf20e8d, F=0x0 0, 850, 850, 1, 518400, 0xbab197ea -1, 170035, 170035, 1524, 1279, 0xb6c2dafe, F=0x0 +1, 170035000, 170035000, 1524000, 1279, 0xb6c2dafe, F=0x0 0, 851, 851, 1, 518400, 0x8780239e 0, 858, 858, 1, 518400, 0xbab197ea 0, 861, 861, 1, 518400, 0x6eb72347 -1, 172203, 172203, 1695, 1826, 0x9a1ac769, F=0x0 +1, 172203000, 172203000, 1695000, 1826, 0x9a1ac769, F=0x0 0, 869, 869, 1, 518400, 0xbab197ea -1, 173947, 173947, 1934, 1474, 0xa9b03cdc, F=0x0 +1, 173947000, 173947000, 1934000, 1474, 0xa9b03cdc, F=0x0 0, 870, 870, 1, 518400, 0x9c4a3a3d 0, 879, 879, 1, 518400, 0xbab197ea -1, 175957, 175957, 1763, 1019, 0x20409355, F=0x0 +1, 175957000, 175957000, 1763000, 1019, 0x20409355, F=0x0 0, 880, 880, 1, 518400, 0xc9ebfa89 0, 889, 889, 1, 518400, 0xbab197ea 0, 946, 946, 1, 518400, 0xbaf801ef -1, 189295, 189295, 1968, 1596, 0x408c726e, F=0x0 +1, 189295000, 189295000, 1968000, 1596, 0x408c726e, F=0x0 0, 956, 956, 1, 518400, 0xbab197ea -1, 191356, 191356, 1228, 1517, 0xae8c5c2b, F=0x0 +1, 191356000, 191356000, 1228000, 1517, 0xae8c5c2b, F=0x0 0, 957, 957, 1, 518400, 0x59f4e72f 0, 963, 963, 1, 518400, 0xbab197ea -1, 192640, 192640, 1763, 2506, 0xa458d6d4, F=0x0 +1, 192640000, 192640000, 1763000, 2506, 0xa458d6d4, F=0x0 0, 964, 964, 1, 518400, 0x9d5b9d69 0, 972, 972, 1, 518400, 0xbab197ea -1, 195193, 195193, 1092, 1074, 0x397ba9a8, F=0x0 +1, 195193000, 195193000, 1092000, 1074, 0x397ba9a8, F=0x0 0, 976, 976, 1, 518400, 0x923d1ce7 0, 981, 981, 1, 518400, 0xbab197ea -1, 196361, 196361, 1524, 1715, 0x695ca41e, F=0x0 +1, 196361000, 196361000, 1524000, 1715, 0x695ca41e, F=0x0 0, 982, 982, 1, 518400, 0x6e652cd2 0, 989, 989, 1, 518400, 0xbab197ea -1, 197946, 197946, 1160, 789, 0xc63a189e, F=0x0 +1, 197946000, 197946000, 1160000, 789, 0xc63a189e, F=0x0 0, 990, 990, 1, 518400, 0x25113966 0, 996, 996, 1, 518400, 0xbab197ea -1, 199230, 199230, 1627, 1846, 0xeea8c599, F=0x0 +1, 199230000, 199230000, 1627000, 1846, 0xeea8c599, F=0x0 0, 997, 997, 1, 518400, 0x2dc83609 0, 1004, 1004, 1, 518400, 0xbab197ea -1, 200924, 200924, 1763, 922, 0xd4a87222, F=0x0 +1, 200924000, 200924000, 1763000, 922, 0xd4a87222, F=0x0 0, 1005, 1005, 1, 518400, 0x90483bc6 0, 1013, 1013, 1, 518400, 0xbab197ea 0, 1053, 1053, 1, 518400, 0x3de86ab7 -1, 210600, 210600, 1831, 665, 0x55580135, F=0x0 +1, 210600000, 210600000, 1831000, 665, 0x55580135, F=0x0 0, 1062, 1062, 1, 518400, 0xbab197ea -1, 214771, 214771, 1558, 1216, 0x50d1f6c5, F=0x0 +1, 214771000, 214771000, 1558000, 1216, 0x50d1f6c5, F=0x0 0, 1074, 1074, 1, 518400, 0x8c320e68 0, 1082, 1082, 1, 518400, 0xbab197ea 0, 1128, 1128, 1, 518400, 0x81e977b2 -1, 225640, 225640, 2127, 2133, 0x670c11a5, F=0x0 +1, 225640000, 225640000, 2127000, 2133, 0x670c11a5, F=0x0 0, 1139, 1139, 1, 518400, 0xbab197ea -1, 227834, 227834, 1262, 1264, 0xc1d9fc57, F=0x0 +1, 227834000, 227834000, 1262000, 1264, 0xc1d9fc57, F=0x0 0, 1140, 1140, 1, 518400, 0xb046dd30 0, 1145, 1145, 1, 518400, 0xbab197ea From af1761f7b5b1b72197dc40934953b775c2d951cc Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 27 May 2016 12:14:33 +0200 Subject: [PATCH 1002/3374] 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 --- ffmpeg.c | 338 +++++++++++------- ffmpeg.h | 17 +- ffmpeg_cuvid.c | 1 - ffmpeg_filter.c | 48 +-- ffmpeg_opt.c | 44 --- ffmpeg_qsv.c | 82 ----- .../exr-rgb-scanline-pxr24-half-uint32-13x9 | 2 +- .../exr-rgba-scanline-float-half-b44-12x8-l1 | 2 +- .../exr-rgba-scanline-float-half-b44-12x8-l2 | 2 +- .../exr-rgba-scanline-float-half-b44-13x9-l1 | 2 +- .../exr-rgba-scanline-float-half-b44-13x9-l2 | 2 +- .../exr-rgba-scanline-float-half-b44a-12x8-l1 | 2 +- .../exr-rgba-scanline-float-half-b44a-12x8-l2 | 2 +- .../exr-rgba-scanline-float-half-b44a-13x9-l1 | 2 +- .../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 983e2fb486d65..88f68342edf6c 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 (!ost->initialized) { + FilterGraph *fg = ost->filter->graph; + char error[1024]; + + av_log(NULL, AV_LOG_WARNING, + "Finishing stream %d:%d without any data written to it.\n", + ost->file_index, ost->st->index); + + if (ost->filter && !fg->graph) { + int x; + for (x = 0; x < fg->nb_inputs; x++) { + InputFilter *ifilter = fg->inputs[x]; + if (ifilter->format < 0) { + AVCodecParameters *par = ifilter->ist->st->codecpar; + // We never got any input. Set a fake format, which will + // come from libavformat. + ifilter->format = par->format; + ifilter->sample_rate = par->sample_rate; + ifilter->channels = par->channels; + ifilter->channel_layout = par->channel_layout; + ifilter->width = par->width; + ifilter->height = par->height; + ifilter->sample_aspect_ratio = par->sample_aspect_ratio; + } + } + + if (!ifilter_has_all_input_formats(fg)) + continue; + + ret = configure_filtergraph(fg); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error configuring filter graph\n"); + exit_program(1); + } + + finish_output_stream(ost); + } + + 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 (enc->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <= 1) continue; #if FF_API_LAVF_FMT_RAWPICTURE @@ -2044,6 +2112,102 @@ static void check_decode_result(InputStream *ist, int *got_output, int ret) } } +// Filters can be configured only if the formats of all inputs are known. +static int ifilter_has_all_input_formats(FilterGraph *fg) +{ + int i; + for (i = 0; i < fg->nb_inputs; i++) { + if (fg->inputs[i]->format < 0 && (fg->inputs[i]->type == AVMEDIA_TYPE_AUDIO || + fg->inputs[i]->type == AVMEDIA_TYPE_VIDEO)) + return 0; + } + return 1; +} + +static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame) +{ + FilterGraph *fg = ifilter->graph; + int need_reinit, ret, i; + + /* determine if the parameters for this input changed */ + need_reinit = ifilter->format != frame->format; + if (!!ifilter->hw_frames_ctx != !!frame->hw_frames_ctx || + (ifilter->hw_frames_ctx && ifilter->hw_frames_ctx->data != frame->hw_frames_ctx->data)) + need_reinit = 1; + + switch (ifilter->ist->st->codecpar->codec_type) { + case AVMEDIA_TYPE_AUDIO: + need_reinit |= ifilter->sample_rate != frame->sample_rate || + ifilter->channels != frame->channels || + ifilter->channel_layout != frame->channel_layout; + break; + case AVMEDIA_TYPE_VIDEO: + need_reinit |= ifilter->width != frame->width || + ifilter->height != frame->height; + break; + } + + if (need_reinit) { + ret = ifilter_parameters_from_frame(ifilter, frame); + if (ret < 0) + return ret; + } + + /* (re)init the graph if possible, otherwise buffer the frame and return */ + if (need_reinit || !fg->graph) { + for (i = 0; i < fg->nb_inputs; i++) { + if (!ifilter_has_all_input_formats(fg)) { + AVFrame *tmp = av_frame_clone(frame); + if (!tmp) + return AVERROR(ENOMEM); + av_frame_unref(frame); + + if (!av_fifo_space(ifilter->frame_queue)) { + ret = av_fifo_realloc2(ifilter->frame_queue, 2 * av_fifo_size(ifilter->frame_queue)); + if (ret < 0) + return ret; + } + av_fifo_generic_write(ifilter->frame_queue, &tmp, sizeof(tmp), NULL); + return 0; + } + } + + ret = reap_filters(1); + if (ret < 0 && ret != AVERROR_EOF) { + char errbuf[128]; + av_strerror(ret, errbuf, sizeof(errbuf)); + + av_log(NULL, AV_LOG_ERROR, "Error while filtering: %s\n", errbuf); + return ret; + } + + ret = configure_filtergraph(fg); + if (ret < 0) { + 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); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error while filtering\n"); + return ret; + } + + 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 @@ -2085,8 +2249,7 @@ static int send_frame_to_filters(InputStream *ist, AVFrame *decoded_frame) break; } else f = decoded_frame; - ret = av_buffersrc_add_frame_flags(ist->filters[i]->filter, f, - AV_BUFFERSRC_FLAG_PUSH); + ret = ifilter_send_frame(ist->filters[i], f); if (ret == AVERROR_EOF) ret = 0; /* ignore */ if (ret < 0) { @@ -2102,7 +2265,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) { AVFrame *decoded_frame; AVCodecContext *avctx = ist->dec_ctx; - int i, ret, err = 0, resample_changed; + int ret, err = 0; AVRational decoded_frame_tb; if (!ist->decoded_frame && !(ist->decoded_frame = av_frame_alloc())) @@ -2138,59 +2301,6 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) avctx->sample_rate; #endif - resample_changed = ist->resample_sample_fmt != decoded_frame->format || - ist->resample_channels != avctx->channels || - ist->resample_channel_layout != decoded_frame->channel_layout || - ist->resample_sample_rate != decoded_frame->sample_rate; - if (resample_changed) { - char layout1[64], layout2[64]; - - if (!guess_input_channel_layout(ist)) { - av_log(NULL, AV_LOG_FATAL, "Unable to find default channel " - "layout for Input Stream #%d.%d\n", ist->file_index, - ist->st->index); - exit_program(1); - } - decoded_frame->channel_layout = avctx->channel_layout; - - av_get_channel_layout_string(layout1, sizeof(layout1), ist->resample_channels, - ist->resample_channel_layout); - av_get_channel_layout_string(layout2, sizeof(layout2), avctx->channels, - decoded_frame->channel_layout); - - av_log(NULL, AV_LOG_INFO, - "Input stream #%d:%d frame changed from rate:%d fmt:%s ch:%d chl:%s to rate:%d fmt:%s ch:%d chl:%s\n", - ist->file_index, ist->st->index, - ist->resample_sample_rate, av_get_sample_fmt_name(ist->resample_sample_fmt), - ist->resample_channels, layout1, - decoded_frame->sample_rate, av_get_sample_fmt_name(decoded_frame->format), - avctx->channels, layout2); - - ist->resample_sample_fmt = decoded_frame->format; - ist->resample_sample_rate = decoded_frame->sample_rate; - ist->resample_channel_layout = decoded_frame->channel_layout; - ist->resample_channels = avctx->channels; - - for (i = 0; i < ist->nb_filters; i++) { - err = ifilter_parameters_from_frame(ist->filters[i], decoded_frame); - if (err < 0) { - av_log(NULL, AV_LOG_ERROR, - "Error reconfiguring input stream %d:%d filter %d\n", - ist->file_index, ist->st->index, i); - goto fail; - } - } - - for (i = 0; i < nb_filtergraphs; i++) - if (ist_in_filtergraph(filtergraphs[i], ist)) { - FilterGraph *fg = filtergraphs[i]; - if (configure_filtergraph(fg) < 0) { - av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n"); - exit_program(1); - } - } - } - if (decoded_frame->pts != AV_NOPTS_VALUE) { decoded_frame_tb = ist->st->time_base; } else if (pkt && pkt->pts != AV_NOPTS_VALUE) { @@ -2206,9 +2316,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) (AVRational){1, avctx->sample_rate}); ist->nb_samples = decoded_frame->nb_samples; err = send_frame_to_filters(ist, decoded_frame); - decoded_frame->pts = AV_NOPTS_VALUE; -fail: av_frame_unref(ist->filter_frame); av_frame_unref(decoded_frame); return err < 0 ? err : ret; @@ -2217,7 +2325,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int eof) { AVFrame *decoded_frame; - int i, ret = 0, err = 0, resample_changed; + int i, ret = 0, err = 0; int64_t best_effort_timestamp; int64_t dts = AV_NOPTS_VALUE; AVPacket avpkt; @@ -2332,39 +2440,6 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int eo if (ist->st->sample_aspect_ratio.num) decoded_frame->sample_aspect_ratio = ist->st->sample_aspect_ratio; - resample_changed = ist->resample_width != decoded_frame->width || - ist->resample_height != decoded_frame->height || - ist->resample_pix_fmt != decoded_frame->format; - if (resample_changed) { - av_log(NULL, AV_LOG_INFO, - "Input stream #%d:%d frame changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s\n", - ist->file_index, ist->st->index, - ist->resample_width, ist->resample_height, av_get_pix_fmt_name(ist->resample_pix_fmt), - decoded_frame->width, decoded_frame->height, av_get_pix_fmt_name(decoded_frame->format)); - - ist->resample_width = decoded_frame->width; - ist->resample_height = decoded_frame->height; - ist->resample_pix_fmt = decoded_frame->format; - - for (i = 0; i < ist->nb_filters; i++) { - err = ifilter_parameters_from_frame(ist->filters[i], decoded_frame); - if (err < 0) { - av_log(NULL, AV_LOG_ERROR, - "Error reconfiguring input stream %d:%d filter %d\n", - ist->file_index, ist->st->index, i); - goto fail; - } - } - - for (i = 0; i < nb_filtergraphs; i++) { - if (ist_in_filtergraph(filtergraphs[i], ist) && ist->reinit_filters && - configure_filtergraph(filtergraphs[i]) < 0) { - av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n"); - exit_program(1); - } - } - } - err = send_frame_to_filters(ist, decoded_frame); fail: @@ -2434,11 +2509,18 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output) static int send_filter_eof(InputStream *ist) { - int i, ret; + int i, j, ret; for (i = 0; i < ist->nb_filters; i++) { - ret = av_buffersrc_add_frame(ist->filters[i]->filter, NULL); - if (ret < 0) - return ret; + 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); + } } return 0; } @@ -2544,6 +2626,9 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo break; } + if (got_output) + ist->got_output = 1; + if (!got_output) break; @@ -2721,17 +2806,9 @@ static int get_buffer(AVCodecContext *s, AVFrame *frame, int flags) static int init_input_stream(int ist_index, char *error, int error_len) { - int i, ret; + int ret; InputStream *ist = input_streams[ist_index]; - for (i = 0; i < ist->nb_filters; i++) { - ret = ifilter_parameters_from_decoder(ist->filters[i], ist->dec_ctx); - if (ret < 0) { - av_log(NULL, AV_LOG_FATAL, "Error initializing filter input\n"); - return ret; - } - } - if (ist->decoding_needed) { AVCodec *codec = ist->dec; if (!codec) { @@ -3125,17 +3202,6 @@ static int init_output_stream_encode(OutputStream *ost) ost->st->disposition = AV_DISPOSITION_DEFAULT; } - if ((enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO || - enc_ctx->codec_type == AVMEDIA_TYPE_AUDIO) && - filtergraph_is_simple(ost->filter->graph)) { - FilterGraph *fg = ost->filter->graph; - - if (configure_filtergraph(fg)) { - av_log(NULL, AV_LOG_FATAL, "Error opening filters!\n"); - exit_program(1); - } - } - if (enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO) { if (!ost->frame_rate.num) ost->frame_rate = av_buffersink_get_frame_rate(ost->filter->filter); @@ -3475,10 +3541,6 @@ static int transcode_init(void) ost = output_streams[i]; if (!ost->stream_copy) { -#if CONFIG_LIBMFX - if (qsv_transcode_init(ost)) - exit_program(1); -#endif #if CONFIG_CUVID if (cuvid_transcode_init(ost)) @@ -3499,6 +3561,10 @@ static int transcode_init(void) /* open each encoder */ for (i = 0; i < nb_output_streams; i++) { + // skip streams fed from filtergraphs until we have a frame for them + if (output_streams[i]->filter) + continue; + ret = init_output_stream(output_streams[i], error, sizeof(error)); if (ret < 0) goto dump_format; @@ -3669,6 +3735,9 @@ static OutputStream *choose_output(void) if (ost->st->cur_dts == AV_NOPTS_VALUE) av_log(NULL, AV_LOG_DEBUG, "cur_dts is invalid (this is harmless if it occurs once at the start per stream)\n"); + if (!ost->initialized && !ost->inputs_done) + return ost; + if (!ost->finished && opts < opts_min) { opts_min = opts; ost_min = ost->unavailable ? NULL : ost; @@ -4326,7 +4395,7 @@ static int transcode_from_filter(FilterGraph *graph, InputStream **best_ist) static int transcode_step(void) { OutputStream *ost; - InputStream *ist; + InputStream *ist = NULL; int ret; ost = choose_output(); @@ -4340,11 +4409,34 @@ static int transcode_step(void) return AVERROR_EOF; } - if (ost->filter) { + if (ost->filter && !ost->filter->graph->graph) { + if (ifilter_has_all_input_formats(ost->filter->graph)) { + ret = configure_filtergraph(ost->filter->graph); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error reinitializing filters!\n"); + return ret; + } + } + } + + if (ost->filter && ost->filter->graph->graph) { if ((ret = transcode_from_filter(ost->filter->graph, &ist)) < 0) return ret; if (!ist) return 0; + } else if (ost->filter) { + int i; + for (i = 0; i < ost->filter->graph->nb_inputs; i++) { + InputFilter *ifilter = ost->filter->graph->inputs[i]; + if (!ifilter->ist->got_output && !input_files[ifilter->ist->file_index]->eof_reached) { + ist = ifilter->ist; + break; + } + } + if (!ist) { + ost->inputs_done = 1; + return 0; + } } else { av_assert0(ost->source_index >= 0); ist = input_streams[ost->source_index]; diff --git a/ffmpeg.h b/ffmpeg.h index ca35ccc260fc4..56e35ebb9cf1c 100644 --- a/ffmpeg.h +++ b/ffmpeg.h @@ -233,6 +233,9 @@ typedef struct InputFilter { struct InputStream *ist; struct FilterGraph *graph; uint8_t *name; + enum AVMediaType type; // AVMEDIA_TYPE_SUBTITLE for sub2video + + AVFifoBuffer *frame_queue; // parameters configured for this input int format; @@ -321,14 +324,6 @@ typedef struct InputStream { int guess_layout_max; int autorotate; - int resample_height; - int resample_width; - int resample_pix_fmt; - - int resample_sample_fmt; - int resample_sample_rate; - int resample_channels; - uint64_t resample_channel_layout; int fix_sub_duration; struct { /* previous decoded subtitle and related variables */ @@ -379,6 +374,8 @@ typedef struct InputStream { int64_t *dts_buffer; int nb_dts_buffer; + + int got_output; } InputStream; typedef struct InputFile { @@ -507,6 +504,8 @@ typedef struct OutputStream { // parameters are set in the AVStream. int initialized; + int inputs_done; + const char *attachment_filename; int copy_initial_nonkeyframes; int copy_prior_start; @@ -636,7 +635,6 @@ int init_simple_filtergraph(InputStream *ist, OutputStream *ost); int init_complex_filtergraph(FilterGraph *fg); int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame); -int ifilter_parameters_from_decoder(InputFilter *ifilter, const AVCodecContext *avctx); int ffmpeg_parse_options(int argc, char **argv); @@ -645,7 +643,6 @@ int dxva2_init(AVCodecContext *s); int vda_init(AVCodecContext *s); int videotoolbox_init(AVCodecContext *s); int qsv_init(AVCodecContext *s); -int qsv_transcode_init(OutputStream *ost); int vaapi_decode_init(AVCodecContext *avctx); int vaapi_device_init(const char *device); int cuvid_init(AVCodecContext *s); diff --git a/ffmpeg_cuvid.c b/ffmpeg_cuvid.c index baf6eee9f8c46..46540795d454c 100644 --- a/ffmpeg_cuvid.c +++ b/ffmpeg_cuvid.c @@ -125,7 +125,6 @@ int cuvid_transcode_init(OutputStream *ost) } ist->hwaccel_ctx = ctx; - ist->resample_pix_fmt = AV_PIX_FMT_CUDA; ist->hwaccel_uninit = cuvid_uninit; /* This is a bit hacky, av_hwframe_ctx_init is called by the cuvid decoder diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c index f13f52304514b..8490f4a455570 100644 --- a/ffmpeg_filter.c +++ b/ffmpeg_filter.c @@ -217,6 +217,10 @@ int init_simple_filtergraph(InputStream *ist, OutputStream *ost) fg->inputs[0]->graph = fg; fg->inputs[0]->format = -1; + fg->inputs[0]->frame_queue = av_fifo_alloc(8 * sizeof(AVFrame*)); + if (!fg->inputs[0]->frame_queue) + exit_program(1); + GROW_ARRAY(ist->filters, ist->nb_filters); ist->filters[ist->nb_filters - 1] = fg->inputs[0]; @@ -295,6 +299,11 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in) fg->inputs[fg->nb_inputs - 1]->ist = ist; 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]->frame_queue = av_fifo_alloc(8 * sizeof(AVFrame*)); + if (!fg->inputs[fg->nb_inputs - 1]->frame_queue) + exit_program(1); GROW_ARRAY(ist->filters, ist->nb_filters); ist->filters[ist->nb_filters - 1] = fg->inputs[fg->nb_inputs - 1]; @@ -691,12 +700,15 @@ static int sub2video_prepare(InputStream *ist, InputFilter *ifilter) } av_log(avf, AV_LOG_INFO, "sub2video: using %dx%d canvas\n", w, h); } - ist->sub2video.w = ist->resample_width = ifilter->width = w; - ist->sub2video.h = ist->resample_height = ifilter->height = h; + ist->sub2video.w = ifilter->width = w; + ist->sub2video.h = ifilter->height = h; + + ifilter->width = ist->dec_ctx->width ? ist->dec_ctx->width : ist->sub2video.w; + ifilter->height = ist->dec_ctx->height ? ist->dec_ctx->height : ist->sub2video.h; /* rectangles are AV_PIX_FMT_PAL8, but we have no guarantee that the palettes for all rectangles are identical or compatible */ - ist->resample_pix_fmt = ifilter->format = AV_PIX_FMT_RGB32; + ifilter->format = AV_PIX_FMT_RGB32; ist->sub2video.frame = av_frame_alloc(); if (!ist->sub2video.frame) @@ -1133,36 +1145,6 @@ int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame) return 0; } -int ifilter_parameters_from_decoder(InputFilter *ifilter, const AVCodecContext *avctx) -{ - av_buffer_unref(&ifilter->hw_frames_ctx); - - if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) - ifilter->format = avctx->pix_fmt; - else - ifilter->format = avctx->sample_fmt; - - ifilter->width = avctx->width; - ifilter->height = avctx->height; - if (ifilter->ist && ifilter->ist->st && ifilter->ist->st->sample_aspect_ratio.num) - ifilter->sample_aspect_ratio = ifilter->ist->st->sample_aspect_ratio; - else - ifilter->sample_aspect_ratio = avctx->sample_aspect_ratio; - - ifilter->sample_rate = avctx->sample_rate; - ifilter->channels = avctx->channels; - ifilter->channel_layout = avctx->channel_layout; - - if (ifilter->ist && ifilter->ist->hw_frames_ctx) { - ifilter->format = ifilter->ist->resample_pix_fmt; - ifilter->hw_frames_ctx = av_buffer_ref(ifilter->ist->hw_frames_ctx); - if (!ifilter->hw_frames_ctx) - return AVERROR(ENOMEM); - } - - return 0; -} - int ist_in_filtergraph(FilterGraph *fg, InputStream *ist) { int i; diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c index 6a47d32b53147..e2c0176e140c7 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -736,10 +736,6 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) // avformat_find_stream_info() doesn't set this for us anymore. ist->dec_ctx->framerate = st->avg_frame_rate; - ist->resample_height = ist->dec_ctx->height; - ist->resample_width = ist->dec_ctx->width; - ist->resample_pix_fmt = ist->dec_ctx->pix_fmt; - MATCH_PER_STREAM_OPT(frame_rates, str, framerate, ic, st); if (framerate && av_parse_video_rate(&ist->framerate, framerate) < 0) { @@ -804,12 +800,6 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) ist->guess_layout_max = INT_MAX; MATCH_PER_STREAM_OPT(guess_layout_max, i, ist->guess_layout_max, ic, st); guess_input_channel_layout(ist); - - ist->resample_sample_fmt = ist->dec_ctx->sample_fmt; - ist->resample_sample_rate = ist->dec_ctx->sample_rate; - ist->resample_channels = ist->dec_ctx->channels; - ist->resample_channel_layout = ist->dec_ctx->channel_layout; - break; case AVMEDIA_TYPE_DATA: case AVMEDIA_TYPE_SUBTITLE: { @@ -2021,33 +2011,6 @@ static int init_complex_filters(void) return 0; } -static int configure_complex_filters(void) -{ - int i, j, ret = 0; - - for (i = 0; i < nb_filtergraphs; i++) { - FilterGraph *fg = filtergraphs[i]; - - if (filtergraph_is_simple(fg)) - continue; - - for (j = 0; j < fg->nb_inputs; j++) { - ret = ifilter_parameters_from_decoder(fg->inputs[j], - fg->inputs[j]->ist->dec_ctx); - if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, - "Error initializing filtergraph %d input %d\n", i, j); - return ret; - } - } - - ret = configure_filtergraph(filtergraphs[i]); - if (ret < 0) - return ret; - } - return 0; -} - static int open_output_file(OptionsContext *o, const char *filename) { AVFormatContext *oc; @@ -3291,13 +3254,6 @@ int ffmpeg_parse_options(int argc, char **argv) goto fail; } - /* configure the complex filtergraphs */ - ret = configure_complex_filters(); - if (ret < 0) { - av_log(NULL, AV_LOG_FATAL, "Error configuring complex filters.\n"); - goto fail; - } - fail: uninit_parse_context(&octx); if (ret < 0) { diff --git a/ffmpeg_qsv.c b/ffmpeg_qsv.c index 86824b60f20d0..74427500291a5 100644 --- a/ffmpeg_qsv.c +++ b/ffmpeg_qsv.c @@ -107,85 +107,3 @@ int qsv_init(AVCodecContext *s) return 0; } - -int qsv_transcode_init(OutputStream *ost) -{ - InputStream *ist; - const enum AVPixelFormat *pix_fmt; - - int err, i; - AVBufferRef *encode_frames_ref = NULL; - AVHWFramesContext *encode_frames; - AVQSVFramesContext *qsv_frames; - - /* check if the encoder supports QSV */ - if (!ost->enc->pix_fmts) - return 0; - for (pix_fmt = ost->enc->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++) - if (*pix_fmt == AV_PIX_FMT_QSV) - break; - if (*pix_fmt == AV_PIX_FMT_NONE) - return 0; - - if (strcmp(ost->avfilter, "null") || ost->source_index < 0) - return 0; - - /* check if the decoder supports QSV and the output only goes to this stream */ - ist = input_streams[ost->source_index]; - if (ist->hwaccel_id != HWACCEL_QSV || !ist->dec || !ist->dec->pix_fmts) - return 0; - for (pix_fmt = ist->dec->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++) - if (*pix_fmt == AV_PIX_FMT_QSV) - break; - if (*pix_fmt == AV_PIX_FMT_NONE) - return 0; - - for (i = 0; i < nb_output_streams; i++) - if (output_streams[i] != ost && - output_streams[i]->source_index == ost->source_index) - return 0; - - av_log(NULL, AV_LOG_VERBOSE, "Setting up QSV transcoding\n"); - - if (!hw_device_ctx) { - err = qsv_device_init(ist); - if (err < 0) - goto fail; - } - - // This creates a dummy hw_frames_ctx for the encoder to be - // suitably initialised. It only contains one real frame, so - // hopefully doesn't waste too much memory. - - encode_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx); - if (!encode_frames_ref) { - err = AVERROR(ENOMEM); - goto fail; - } - encode_frames = (AVHWFramesContext*)encode_frames_ref->data; - qsv_frames = encode_frames->hwctx; - - encode_frames->width = FFALIGN(ist->resample_width, 32); - encode_frames->height = FFALIGN(ist->resample_height, 32); - encode_frames->format = AV_PIX_FMT_QSV; - encode_frames->sw_format = AV_PIX_FMT_NV12; - encode_frames->initial_pool_size = 1; - - qsv_frames->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; - - err = av_hwframe_ctx_init(encode_frames_ref); - if (err < 0) - goto fail; - - ist->dec_ctx->pix_fmt = AV_PIX_FMT_QSV; - ist->resample_pix_fmt = AV_PIX_FMT_QSV; - - ost->enc_ctx->pix_fmt = AV_PIX_FMT_QSV; - ost->enc_ctx->hw_frames_ctx = encode_frames_ref; - - return 0; - -fail: - av_buffer_unref(&encode_frames_ref); - return err; -} diff --git a/tests/ref/fate/exr-rgb-scanline-pxr24-half-uint32-13x9 b/tests/ref/fate/exr-rgb-scanline-pxr24-half-uint32-13x9 index 4a54c336e3685..e2aa9efb9f0a9 100644 --- a/tests/ref/fate/exr-rgb-scanline-pxr24-half-uint32-13x9 +++ b/tests/ref/fate/exr-rgb-scanline-pxr24-half-uint32-13x9 @@ -2,5 +2,5 @@ #media_type 0: video #codec_id 0: rawvideo #dimensions 0: 13x9 -#sar 0: 0/1 +#sar 0: 9/10 0, 0, 0, 1, 936, 0x7b44246e diff --git a/tests/ref/fate/exr-rgba-scanline-float-half-b44-12x8-l1 b/tests/ref/fate/exr-rgba-scanline-float-half-b44-12x8-l1 index c84d388fff6c8..cd25f618f416d 100644 --- a/tests/ref/fate/exr-rgba-scanline-float-half-b44-12x8-l1 +++ b/tests/ref/fate/exr-rgba-scanline-float-half-b44-12x8-l1 @@ -2,5 +2,5 @@ #media_type 0: video #codec_id 0: rawvideo #dimensions 0: 12x8 -#sar 0: 0/1 +#sar 0: 9/10 0, 0, 0, 1, 768, 0x1de5c7f1 diff --git a/tests/ref/fate/exr-rgba-scanline-float-half-b44-12x8-l2 b/tests/ref/fate/exr-rgba-scanline-float-half-b44-12x8-l2 index 1dd42d9175b52..ecfba85e83dc3 100644 --- a/tests/ref/fate/exr-rgba-scanline-float-half-b44-12x8-l2 +++ b/tests/ref/fate/exr-rgba-scanline-float-half-b44-12x8-l2 @@ -2,5 +2,5 @@ #media_type 0: video #codec_id 0: rawvideo #dimensions 0: 12x8 -#sar 0: 0/1 +#sar 0: 9/10 0, 0, 0, 1, 768, 0xe08ca6d3 diff --git a/tests/ref/fate/exr-rgba-scanline-float-half-b44-13x9-l1 b/tests/ref/fate/exr-rgba-scanline-float-half-b44-13x9-l1 index 595c721d5096a..3e82e2aaa43f4 100644 --- a/tests/ref/fate/exr-rgba-scanline-float-half-b44-13x9-l1 +++ b/tests/ref/fate/exr-rgba-scanline-float-half-b44-13x9-l1 @@ -2,5 +2,5 @@ #media_type 0: video #codec_id 0: rawvideo #dimensions 0: 13x9 -#sar 0: 0/1 +#sar 0: 9/10 0, 0, 0, 1, 936, 0xdcb42186 diff --git a/tests/ref/fate/exr-rgba-scanline-float-half-b44-13x9-l2 b/tests/ref/fate/exr-rgba-scanline-float-half-b44-13x9-l2 index 079d1d877f7d5..f237d17d3f446 100644 --- a/tests/ref/fate/exr-rgba-scanline-float-half-b44-13x9-l2 +++ b/tests/ref/fate/exr-rgba-scanline-float-half-b44-13x9-l2 @@ -2,5 +2,5 @@ #media_type 0: video #codec_id 0: rawvideo #dimensions 0: 13x9 -#sar 0: 0/1 +#sar 0: 9/10 0, 0, 0, 1, 936, 0x7f710bf5 diff --git a/tests/ref/fate/exr-rgba-scanline-float-half-b44a-12x8-l1 b/tests/ref/fate/exr-rgba-scanline-float-half-b44a-12x8-l1 index 6d202af80845d..43313e37126d4 100644 --- a/tests/ref/fate/exr-rgba-scanline-float-half-b44a-12x8-l1 +++ b/tests/ref/fate/exr-rgba-scanline-float-half-b44a-12x8-l1 @@ -2,5 +2,5 @@ #media_type 0: video #codec_id 0: rawvideo #dimensions 0: 12x8 -#sar 0: 0/1 +#sar 0: 9/10 0, 0, 0, 1, 768, 0xe200c160 diff --git a/tests/ref/fate/exr-rgba-scanline-float-half-b44a-12x8-l2 b/tests/ref/fate/exr-rgba-scanline-float-half-b44a-12x8-l2 index 1dd42d9175b52..ecfba85e83dc3 100644 --- a/tests/ref/fate/exr-rgba-scanline-float-half-b44a-12x8-l2 +++ b/tests/ref/fate/exr-rgba-scanline-float-half-b44a-12x8-l2 @@ -2,5 +2,5 @@ #media_type 0: video #codec_id 0: rawvideo #dimensions 0: 12x8 -#sar 0: 0/1 +#sar 0: 9/10 0, 0, 0, 1, 768, 0xe08ca6d3 diff --git a/tests/ref/fate/exr-rgba-scanline-float-half-b44a-13x9-l1 b/tests/ref/fate/exr-rgba-scanline-float-half-b44a-13x9-l1 index 9fcf3093683e8..e43c31ebd54b6 100644 --- a/tests/ref/fate/exr-rgba-scanline-float-half-b44a-13x9-l1 +++ b/tests/ref/fate/exr-rgba-scanline-float-half-b44a-13x9-l1 @@ -2,5 +2,5 @@ #media_type 0: video #codec_id 0: rawvideo #dimensions 0: 13x9 -#sar 0: 0/1 +#sar 0: 9/10 0, 0, 0, 1, 936, 0x911718ac diff --git a/tests/ref/fate/exr-rgba-scanline-float-half-b44a-13x9-l2 b/tests/ref/fate/exr-rgba-scanline-float-half-b44a-13x9-l2 index 079d1d877f7d5..f237d17d3f446 100644 --- a/tests/ref/fate/exr-rgba-scanline-float-half-b44a-13x9-l2 +++ b/tests/ref/fate/exr-rgba-scanline-float-half-b44a-13x9-l2 @@ -2,5 +2,5 @@ #media_type 0: video #codec_id 0: rawvideo #dimensions 0: 13x9 -#sar 0: 0/1 +#sar 0: 9/10 0, 0, 0, 1, 936, 0x7f710bf5 diff --git a/tests/ref/fate/vp8-size-change b/tests/ref/fate/vp8-size-change index 741b6d65fb317..5105bc6f55685 100644 --- a/tests/ref/fate/vp8-size-change +++ b/tests/ref/fate/vp8-size-change @@ -4,36 +4,36 @@ #tb 0: 1/30 #media_type 0: video #codec_id 0: rawvideo -#dimensions 0: 1920x1080 +#dimensions 0: 160x90 #sar 0: 1/1 #stream#, dts, pts, duration, size, hash -0, 0, 0, 1, 3110400, 7dde8cd136ab4b04a95d9856b941697e -0, 1, 1, 1, 3110400, aa885f78cb6374b5bfcc66a4fc57026f -0, 2, 2, 1, 3110400, b69b7b56f549a3f9b0a603940bac85ed -0, 3, 3, 1, 3110400, 20e2e0f0c89c58828b6a3b10d9e175e5 -0, 4, 4, 1, 3110400, 483997936e7d6bb849e64d50426ec689 -0, 5, 5, 1, 3110400, c85ef97a853ff594e2bfdf0a0a581dcc -0, 6, 6, 1, 3110400, c5e7b9ff4c25391793446da788cb83a9 -0, 7, 7, 1, 3110400, 63f93e89d24162e2f6328edbc6716b33 -0, 8, 8, 1, 3110400, 0e346ab4831ce8c69001153c72b7b827 -0, 9, 9, 1, 3110400, c526c21511d8bec2659d3d43d93734f2 -0, 10, 10, 1, 3110400, e95d01d5f9fb81a98bd34305c7ab30f8 -0, 11, 11, 1, 3110400, 177e75e7516e8746d31b43ea9d39e6b1 -0, 12, 12, 1, 3110400, 489d2bc0da93f118dc9a2697275697a7 -0, 13, 13, 1, 3110400, a2dc00d627350ff1ab302bcbad5ca5ac -0, 14, 14, 1, 3110400, 20ce143831b0189f763ee5bee9c51188 -0, 15, 15, 1, 3110400, 7822fd908bd81b521c23fa4a639caf9e -0, 16, 16, 1, 3110400, dabc4febbe09734126ac6f5a5180ba8c -0, 17, 17, 1, 3110400, ef88f0d6667feefac1471b065208e1c8 -0, 18, 18, 1, 3110400, 7c7fc665a6fd9e19af9358bbdc162a51 -0, 19, 19, 1, 3110400, f2bcf32f734f99506bdd0a0376badf82 -0, 20, 20, 1, 3110400, 06809c2d277fd3b3918ebb4b65c27661 -0, 21, 21, 1, 3110400, e403e9e86fa5d519f65c565b3add84b5 -0, 22, 22, 1, 3110400, d2b876730e12245cacb578307794349a -0, 23, 23, 1, 3110400, dfdfd8cb626a96138f6a2c1953dcf5ec -0, 24, 24, 1, 3110400, 0ac58c28575b804d9e63395653c3aef2 -0, 25, 25, 1, 3110400, 641f2a78e338c733ef159bd36ec7966f -0, 26, 26, 1, 3110400, 9402d455fa5bd556b85f479c42c3a4d2 -0, 27, 27, 1, 3110400, 0044d42b4048bc93112aa59789dbdc2d -0, 28, 28, 1, 3110400, 5d9e5c5ba35f6f452e5f31ccff9e819c -0, 29, 29, 1, 3110400, 307a55a94739b4cfdf41f7da7e5c0135 +0, 0, 0, 1, 21600, 5abd6c163522c7e882f7e9c369293bf9 +0, 1, 1, 1, 21600, 5c11d8cc9cc9102d0ef5afd1dc64aff1 +0, 2, 2, 1, 21600, cbeffa9ea9d682af77d3fd0fdf12c8c1 +0, 3, 3, 1, 21600, ea7cec515fcf8ccbc932d9e9b472cdc7 +0, 4, 4, 1, 21600, 23038b711dbac95ce710657b1fef5901 +0, 5, 5, 1, 21600, e0d6fb46bb5c0d939ee33af82b887668 +0, 6, 6, 1, 21600, 694518f14d3a2bd3c319bc0b098c78bb +0, 7, 7, 1, 21600, c1c7394bd4236afbc773af52ef7a10ea +0, 8, 8, 1, 21600, 4d8d3b2c9a637f963521585ea879357b +0, 9, 9, 1, 21600, b4444dc3cbf1b6cdd8047d3dcd497ffd +0, 10, 10, 1, 21600, 65e5d667ec9ceb636e21357f032ce800 +0, 11, 11, 1, 21600, fd9a4c67598051074387b640df7edaa9 +0, 12, 12, 1, 21600, 0e54e22d90f6296ae6989c83846272cd +0, 13, 13, 1, 21600, db4b1727450243b202bfec5ed6c73ae0 +0, 14, 14, 1, 21600, ab37a84be075ca42cc7351ff9fb1cb47 +0, 15, 15, 1, 21600, ae4d2d297e646bd8e05e76b457d9b576 +0, 16, 16, 1, 21600, e7cfd580e3c3d7c3f2f5136d1e548595 +0, 17, 17, 1, 21600, cbec09314a0b7ad53f4893eb474e1c65 +0, 18, 18, 1, 21600, e1fa89cd63c37496bc86f18694324d88 +0, 19, 19, 1, 21600, e9655b151253950313810228278ca104 +0, 20, 20, 1, 21600, 69ba31c0eff7bc93f4180173d8e64c60 +0, 21, 21, 1, 21600, 368a1f6a1172d7d56f695153b234a330 +0, 22, 22, 1, 21600, 6c298b196e16c64f7c2f407ba1242937 +0, 23, 23, 1, 21600, bf54474112ed5592c4d890e3313881a0 +0, 24, 24, 1, 21600, 945d49abedb0606b6a009c8b5d8face3 +0, 25, 25, 1, 21600, dd6ebef7b6f24619910de811918d3437 +0, 26, 26, 1, 21600, 7952346fc0f1eff3914e0d7646b3cf28 +0, 27, 27, 1, 21600, 26bd0d6b21e8a2df17af8d1446fba745 +0, 28, 28, 1, 21600, b0d91600416716d81c1f73ac141a0b62 +0, 29, 29, 1, 21600, 08f16698beb9cc15f7115961bd69e995 diff --git a/tests/ref/lavf/ffm b/tests/ref/lavf/ffm index 54c56034aa0fe..d9fa8d52cbcf5 100644 --- a/tests/ref/lavf/ffm +++ b/tests/ref/lavf/ffm @@ -1,3 +1,3 @@ -a0e9616f0d9a8c1029f3220b1b9175f4 *./tests/data/lavf/lavf.ffm +ca2a450cd0d1e299514a345923b4c82a *./tests/data/lavf/lavf.ffm 376832 ./tests/data/lavf/lavf.ffm ./tests/data/lavf/lavf.ffm CRC=0x000e23ae diff --git a/tests/ref/lavf/mxf b/tests/ref/lavf/mxf index e1c0c79b0555f..103ef010b70c5 100644 --- a/tests/ref/lavf/mxf +++ b/tests/ref/lavf/mxf @@ -1,9 +1,9 @@ -f9b570c7b4fbbc2b71f2236b32e7cbb6 *./tests/data/lavf/lavf.mxf +c61e677b4facc407ca82b1d7c6298484 *./tests/data/lavf/lavf.mxf 525369 ./tests/data/lavf/lavf.mxf ./tests/data/lavf/lavf.mxf CRC=0xdbfff6f1 -8f6a9a6b409f0f5a0bf003f8dea26314 *./tests/data/lavf/lavf.mxf +1ae017b5879992431614b1c7ab3b48c5 *./tests/data/lavf/lavf.mxf 560697 ./tests/data/lavf/lavf.mxf ./tests/data/lavf/lavf.mxf CRC=0x11a6178e -10ac0f158fc0af356439b818de7601e3 *./tests/data/lavf/lavf.mxf +27fac91dce279630a04b94b93518a9d8 *./tests/data/lavf/lavf.mxf 525369 ./tests/data/lavf/lavf.mxf ./tests/data/lavf/lavf.mxf CRC=0xdbfff6f1 From 97614a68e474062b46f6fae92bf34976f3436c6a Mon Sep 17 00:00:00 2001 From: wm4 Date: Wed, 8 Feb 2017 12:55:58 +0100 Subject: [PATCH 1003/3374] 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 --- ffmpeg_filter.c | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c index 8490f4a455570..f21a8c85f8fbb 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", From cb884f8d7e3b55cddf8a4568bddb1e5f5f86b811 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 27 Jun 2016 18:59:23 +0200 Subject: [PATCH 1004/3374] 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 --- ffmpeg.c | 11 ----------- ffmpeg_filter.c | 11 +++++++++++ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index 88f68342edf6c..f52d3e2f0ffdf 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 f21a8c85f8fbb..4d9a4e2eb814f 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; } From 76e13bdeaabc7ec49322b3a118dc4805153e0401 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 27 Jun 2016 19:03:42 +0200 Subject: [PATCH 1005/3374] 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 --- 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 23b48d1e2bb1e..39d846f8fccbf 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 f52d3e2f0ffdf..275894dbf5748 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 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output) 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 56e35ebb9cf1c..5d20d453eb805 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 4d9a4e2eb814f..816c906c7e712 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; } From 736f4af4fea44d15c5d08558d3fe6f1a0fc98173 Mon Sep 17 00:00:00 2001 From: Timo Rothenpieler Date: Thu, 9 Feb 2017 21:33:51 +0100 Subject: [PATCH 1006/3374] ffmpeg_cuvid: adapt for recent filter graph initialization changes --- 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 275894dbf5748..6e57524558eae 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 5d20d453eb805..59f6cb36596c7 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 46540795d454c..3ff3b40f17d0e 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->hw_frames_ctx = av_hwframe_ctx_alloc(device_ref); - if (!ctx->hw_frames_ctx) { - av_log(NULL, AV_LOG_ERROR, "av_hwframe_ctx_alloc failed\n"); - ret = AVERROR(ENOMEM); - goto error; - } - av_buffer_unref(&device_ref); + frames_ctx = (AVHWFramesContext*)ist->hw_frames_ctx->data; - ist->hw_frames_ctx = av_buffer_ref(ctx->hw_frames_ctx); - if (!ist->hw_frames_ctx) { - av_log(NULL, AV_LOG_ERROR, "av_buffer_ref failed\n"); - ret = AVERROR(ENOMEM); - goto error; - } + frames_ctx->format = AV_PIX_FMT_CUDA; + frames_ctx->sw_format = avctx->sw_pix_fmt; + frames_ctx->width = avctx->width; + frames_ctx->height = avctx->height; - ist->hwaccel_ctx = ctx; - ist->hwaccel_uninit = cuvid_uninit; + av_log(avctx, AV_LOG_DEBUG, "Initializing CUDA frames context: sw_format = %s, width = %d, height = %d\n", + av_get_pix_fmt_name(frames_ctx->sw_format), frames_ctx->width, frames_ctx->height); - /* This is a bit hacky, av_hwframe_ctx_init is called by the cuvid decoder - * once it has probed the necessary format information. But as filters/nvenc - * need to know the format/sw_format, set them here so they are happy. - * This is fine as long as CUVID doesn't add another supported pix_fmt. - */ - hwframe_ctx = (AVHWFramesContext*)ctx->hw_frames_ctx->data; - hwframe_ctx->format = AV_PIX_FMT_CUDA; - hwframe_ctx->sw_format = ist->st->codecpar->format == AV_PIX_FMT_YUV420P10 ? AV_PIX_FMT_P010 : AV_PIX_FMT_NV12; + ret = av_hwframe_ctx_init(ist->hw_frames_ctx); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Error initializing a CUDA frame pool\n"); + return ret; } - return 0; - -error: - av_freep(&ctx); - av_buffer_unref(&device_ref); - return ret; - -cancel: - if (ist->hwaccel_id == HWACCEL_CUVID) { - av_log(NULL, AV_LOG_ERROR, "CUVID hwaccel requested, but impossible to achieve.\n"); - return AVERROR(EINVAL); - } + ist->hwaccel_uninit = cuvid_uninit; return 0; } From 7dd44cde2abb156710f26a08b6cd6c8dd9a9793d Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 2 Mar 2017 16:01:01 +0100 Subject: [PATCH 1007/3374] 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. --- 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 6e57524558eae..db7e8cd0c6723 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 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int eo 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 59f6cb36596c7..06a125112480c 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 816c906c7e712..da2a46d3b714b 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; } From 16abc10b0997c76cbb0c0ebedc49f6bc21452f9d Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 2 Mar 2017 19:14:58 +0100 Subject: [PATCH 1008/3374] 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. --- ffmpeg_filter.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c index da2a46d3b714b..7f249c2960260 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) From 6d93e7d1a3e607d001141784e66cc73ba1f061c6 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Fri, 3 Mar 2017 12:17:46 +0100 Subject: [PATCH 1009/3374] avcodec/scpr: fix top left prediction for special case when x is 0 for keyframes Signed-off-by: Paul B Mahol --- libavcodec/scpr.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/libavcodec/scpr.c b/libavcodec/scpr.c index 031ce5152a9c6..1fc0593dbb6e5 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; From 13332504c98918447159da2a1a34e377dca360e2 Mon Sep 17 00:00:00 2001 From: Takayuki 'January June' Suwa Date: Fri, 3 Mar 2017 15:17:37 +0900 Subject: [PATCH 1010/3374] omx: Add support for specifying H.264 profile [v5'] This adds "-profile[:v] profile_name"-style option. Signed-off-by: Michael Niedermayer --- libavcodec/omx.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/libavcodec/omx.c b/libavcodec/omx.c index 16df50e456736..19b4f33836b68 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 } }; From d8094a303ba36344015a44d629bafc6d7094b4ac Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 15 Dec 2016 21:08:48 +0100 Subject: [PATCH 1011/3374] avcodec/vp3: Do not return random positive values but the buf size Signed-off-by: Michael Niedermayer --- libavcodec/vp3.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index fa749be0b758b..86e5852e32935 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, From e2b7ae4b198c1dc001b3b28476608eaf4daf726c Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 3 Mar 2017 00:25:54 -0300 Subject: [PATCH 1012/3374] 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 --- libavutil/md5.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/libavutil/md5.c b/libavutil/md5.c index 8c36aa80c44ef..d3698dcb1d41a 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); From a43389547c51b857451cd47d0a1484382c78af37 Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 3 Mar 2017 00:27:52 -0300 Subject: [PATCH 1013/3374] 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 --- libavutil/md5.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/libavutil/md5.c b/libavutil/md5.c index d3698dcb1d41a..1069ef1efe0f0 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; From 68ee800a9dd9808d6b5c8b52963cd19cfdd4753e Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 3 Mar 2017 13:49:14 -0300 Subject: [PATCH 1014/3374] doc/encoders: mention valid values for compression_level when using FLAC encoder Found-by: Miles Signed-off-by: James Almer --- doc/encoders.texi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/encoders.texi b/doc/encoders.texi index 430f9f801e16c..594c612b5ae3d 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. From 4507f29e4a6a4363e0179c02bdb78d55e4d9a12c Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Sat, 4 Mar 2017 09:27:56 +0800 Subject: [PATCH 1015/3374] avformat/hlsenc: move the segment files handler close to before temp flags process fix ticket: #6204 Signed-off-by: Steven Liu --- libavformat/hlsenc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 9cf621125c7e6..b8122f1a37adb 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); } From 2ce4f28431623cdde4aa496fd10430f6c7bdef63 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 2 Mar 2017 03:02:06 +0100 Subject: [PATCH 1016/3374] 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 --- 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 5ea365375b4d4..0010408847a85 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 34d48228fdd4e..e5c5bea96331f 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; }; From eb41956636fc264fe2077b78ef00591d83bbbace Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 2 Mar 2017 03:02:07 +0100 Subject: [PATCH 1017/3374] 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 --- libavcodec/mpeg4videodec.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index 9f9374d550a68..568263ecdf97c 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) { From d23727e0420b9f77f0d4cb28b43819b402f702e5 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 3 Mar 2017 04:39:04 +0100 Subject: [PATCH 1018/3374] avcodec/adxdec: Fix runtime error: left shift of negative value -1 Fixes: 705/clusterfuzz-testcase-5129572590813184 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/adxdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index 32cc0f005a436..178ea99dcfc8f 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -81,7 +81,7 @@ static int adx_decode(ADXContext *c, int16_t *out, int offset, s2 = prev->s2; for (i = 0; i < BLOCK_SAMPLES; i++) { d = get_sbits(&gb, 4); - s0 = ((d << COEFF_BITS) * scale + c->coeff[0] * s1 + c->coeff[1] * s2) >> COEFF_BITS; + s0 = ((d * (1 << COEFF_BITS)) * scale + c->coeff[0] * s1 + c->coeff[1] * s2) >> COEFF_BITS; s2 = s1; s1 = av_clip_int16(s0); *out++ = s1; From ab998f4c7faf90d0e46b6ead38a1df1f6a31e2eb Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 3 Mar 2017 04:39:06 +0100 Subject: [PATCH 1019/3374] avcodec/h264_mvpred: Fix multiple runtime error: left shift of negative value Fixes: 710/clusterfuzz-testcase-5091051431788544 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/h264_mvpred.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/h264_mvpred.h b/libavcodec/h264_mvpred.h index 24f250d794560..339cf623d5a43 100644 --- a/libavcodec/h264_mvpred.h +++ b/libavcodec/h264_mvpred.h @@ -248,7 +248,7 @@ static av_always_inline void pred_8x16_motion(const H264Context *const h, if (IS_INTERLACED(type)) { \ refn >>= 1; \ AV_COPY32(mvbuf[idx], mvn); \ - mvbuf[idx][1] <<= 1; \ + mvbuf[idx][1] *= 2; \ mvn = mvbuf[idx]; \ } \ } \ From d757ddbaab8f03b3664788e620314b70ac791319 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 3 Mar 2017 04:39:05 +0100 Subject: [PATCH 1020/3374] avcodec/mpeg12dec: Fix runtime error: left shift of negative value -13 Fixes: 709/clusterfuzz-testcase-4789836449841152 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/mpeg12dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c index d44ddb20fae3b..27db14c35ef81 100644 --- a/libavcodec/mpeg12dec.c +++ b/libavcodec/mpeg12dec.c @@ -497,7 +497,7 @@ static inline int mpeg2_decode_block_intra(MpegEncContext *s, dc = s->last_dc[component]; dc += diff; s->last_dc[component] = dc; - block[0] = dc << (3 - s->intra_dc_precision); + block[0] = dc * (1 << (3 - s->intra_dc_precision)); ff_tlog(s->avctx, "dc=%d\n", block[0]); mismatch = block[0] ^ 1; i = 0; From fab13bbbcdf92da165f1a6be94fbb8f87fac639a Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 3 Mar 2017 20:12:20 +0100 Subject: [PATCH 1021/3374] avcodec/mpeg4videodec: Fix runtime error: signed integer overflow: 134527392 * 16 cannot be represented in type 'int' This checks the sprite delta intermediates for overflow Fixes: 716/clusterfuzz-testcase-4890287480504320 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/mpeg4videodec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index 568263ecdf97c..128469d7552ef 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -389,7 +389,10 @@ static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *g 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) { + llabs(s->sprite_offset[0][i] + s->sprite_delta[i][0] * (w+16LL) + s->sprite_delta[i][1] * (h+16LL)) >= INT_MAX || + llabs(s->sprite_delta[i][0] * (w+16LL)) >= INT_MAX || + llabs(s->sprite_delta[i][1] * (w+16LL)) >= INT_MAX + ) { avpriv_request_sample(s->avctx, "Overflow on sprite points"); goto overflow; } From d03d38616278bf209e6c860d8f9f564cbc6c1780 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 3 Mar 2017 20:12:21 +0100 Subject: [PATCH 1022/3374] avcodec/wavpack: Check bitrate_acc for overflow Fixes: undefined behavior in 717/clusterfuzz-testcase-5434924129583104 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/wavpack.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index ebcdd96508e0a..bf538a9b87d2a 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -99,11 +99,13 @@ static av_always_inline int get_tail(GetBitContext *gb, int k) return res; } -static void update_error_limit(WavpackFrameContext *ctx) +static int update_error_limit(WavpackFrameContext *ctx) { int i, br[2], sl[2]; for (i = 0; i <= ctx->stereo_in; i++) { + if (ctx->ch[i].bitrate_acc > UINT_MAX - ctx->ch[i].bitrate_delta) + return AVERROR_INVALIDDATA; ctx->ch[i].bitrate_acc += ctx->ch[i].bitrate_delta; br[i] = ctx->ch[i].bitrate_acc >> 16; sl[i] = LEVEL_DECAY(ctx->ch[i].slow_level); @@ -131,6 +133,8 @@ static void update_error_limit(WavpackFrameContext *ctx) ctx->ch[i].error_limit = wp_exp2(br[i]); } } + + return 0; } static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, @@ -200,8 +204,10 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, ctx->zero = !ctx->one; } - if (ctx->hybrid && !channel) - update_error_limit(ctx); + if (ctx->hybrid && !channel) { + if (update_error_limit(ctx) < 0) + goto error; + } if (!t) { base = 0; From 29638d4db90d5e3fc107c1beb40808f53cc7acaa Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 3 Mar 2017 20:12:22 +0100 Subject: [PATCH 1023/3374] avcodec/dcadsp: Fix 2 runtime error: signed integer overflow: -1958094138 - 1078906344 cannot be represented in type 'int' Fixes: 722/clusterfuzz-testcase-5711268868521984 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/dcadsp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/dcadsp.c b/libavcodec/dcadsp.c index 1503d00886c7b..4f1e933cfbe21 100644 --- a/libavcodec/dcadsp.c +++ b/libavcodec/dcadsp.c @@ -347,7 +347,7 @@ static void dmix_scale_inv_c(int32_t *dst, int scale_inv, ptrdiff_t len) dst[i] = mul16(dst[i], scale_inv); } -static void filter0(int32_t *dst, const int32_t *src, int32_t coeff, ptrdiff_t len) +static void filter0(SUINT32 *dst, const int32_t *src, int32_t coeff, ptrdiff_t len) { int i; @@ -355,7 +355,7 @@ static void filter0(int32_t *dst, const int32_t *src, int32_t coeff, ptrdiff_t l dst[i] -= mul22(src[i], coeff); } -static void filter1(int32_t *dst, const int32_t *src, int32_t coeff, ptrdiff_t len) +static void filter1(SUINT32 *dst, const int32_t *src, int32_t coeff, ptrdiff_t len) { int i; From ba150051322c02e24c004bd5309468886e1e5ab6 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 4 Mar 2017 04:55:15 +0100 Subject: [PATCH 1024/3374] avcodec/wavpack: Fix runtime error: left shift of negative value -2 Fixes: 723/clusterfuzz-testcase-6471394663596032 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/wavpack.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index bf538a9b87d2a..a4ba07fc834d7 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -745,13 +745,13 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, } for (i = 0; i < weights; i++) { t = (int8_t)bytestream2_get_byte(&gb); - s->decorr[s->terms - i - 1].weightA = t << 3; + s->decorr[s->terms - i - 1].weightA = t * (1 << 3); if (s->decorr[s->terms - i - 1].weightA > 0) s->decorr[s->terms - i - 1].weightA += (s->decorr[s->terms - i - 1].weightA + 64) >> 7; if (s->stereo_in) { t = (int8_t)bytestream2_get_byte(&gb); - s->decorr[s->terms - i - 1].weightB = t << 3; + s->decorr[s->terms - i - 1].weightB = t * (1 << 3); if (s->decorr[s->terms - i - 1].weightB > 0) s->decorr[s->terms - i - 1].weightB += (s->decorr[s->terms - i - 1].weightB + 64) >> 7; From 1638d956a35c240e4f9ad2d8711dce06bd32838a Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Wed, 1 Mar 2017 23:22:40 +0100 Subject: [PATCH 1025/3374] lavf/matroska: Support QDMC. --- libavformat/matroska.c | 1 + libavformat/matroskaenc.c | 1 + 2 files changed, 2 insertions(+) diff --git a/libavformat/matroska.c b/libavformat/matroska.c index 7905fd1ff7473..6af667c36b006 100644 --- a/libavformat/matroska.c +++ b/libavformat/matroska.c @@ -48,6 +48,7 @@ const CodecTags ff_mkv_codec_tags[]={ {"A_PCM/INT/LIT" , AV_CODEC_ID_PCM_S24LE}, {"A_PCM/INT/LIT" , AV_CODEC_ID_PCM_S32LE}, {"A_PCM/INT/LIT" , AV_CODEC_ID_PCM_U8}, + {"A_QUICKTIME/QDMC" , AV_CODEC_ID_QDMC}, {"A_QUICKTIME/QDM2" , AV_CODEC_ID_QDM2}, {"A_REAL/14_4" , AV_CODEC_ID_RA_144}, {"A_REAL/28_8" , AV_CODEC_ID_RA_288}, diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 1622b44e5ecc8..1605f0cafe3de 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -2528,6 +2528,7 @@ static const AVCodecTag additional_audio_tags[] = { { AV_CODEC_ID_PCM_S16BE, 0xFFFFFFFF }, { AV_CODEC_ID_PCM_S24BE, 0xFFFFFFFF }, { AV_CODEC_ID_PCM_S32BE, 0xFFFFFFFF }, + { AV_CODEC_ID_QDMC, 0xFFFFFFFF }, { AV_CODEC_ID_QDM2, 0xFFFFFFFF }, { AV_CODEC_ID_RA_144, 0xFFFFFFFF }, { AV_CODEC_ID_RA_288, 0xFFFFFFFF }, From 035e932d7c039030bd8142bf2f99cbbd1d3e92cf Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 5 Mar 2017 16:34:32 +0100 Subject: [PATCH 1026/3374] avformat/vivo: fix logic error in checking version in probe Signed-off-by: Paul B Mahol --- libavformat/vivo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/vivo.c b/libavformat/vivo.c index a9effd5835b2d..c9e9c37f37dfb 100644 --- a/libavformat/vivo.c +++ b/libavformat/vivo.c @@ -63,7 +63,7 @@ static int vivo_probe(AVProbeData *p) return 0; buf += 15; - if (*buf < '0' && *buf > '2') + if (*buf < '0' || *buf > '2') return 0; return AVPROBE_SCORE_MAX; From 3267e1703b32e83bce1329676fd007cc66a592c7 Mon Sep 17 00:00:00 2001 From: wang-bin Date: Fri, 3 Mar 2017 18:10:54 +0800 Subject: [PATCH 1027/3374] avcodec/videotoolbox: set kCVPixelBufferOpenGLESCompatibilityKey for iOS kCVPixelBufferIOSurfaceOpenGLTextureCompatibilityKey is not available in iOS --- libavcodec/videotoolbox.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/videotoolbox.c b/libavcodec/videotoolbox.c index 824f2d8e683f6..9199b020556bd 100644 --- a/libavcodec/videotoolbox.c +++ b/libavcodec/videotoolbox.c @@ -31,6 +31,7 @@ #include "bytestream.h" #include "h264dec.h" #include "mpegvideo.h" +#include #ifndef kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder # define kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder CFSTR("RequireHardwareAcceleratedVideoDecoder") @@ -477,7 +478,11 @@ static CFDictionaryRef videotoolbox_buffer_attributes_create(int width, CFDictionarySetValue(buffer_attributes, kCVPixelBufferIOSurfacePropertiesKey, io_surface_properties); CFDictionarySetValue(buffer_attributes, kCVPixelBufferWidthKey, w); CFDictionarySetValue(buffer_attributes, kCVPixelBufferHeightKey, h); +#if TARGET_OS_IPHONE + CFDictionarySetValue(buffer_attributes, kCVPixelBufferOpenGLESCompatibilityKey, kCFBooleanTrue); +#else CFDictionarySetValue(buffer_attributes, kCVPixelBufferIOSurfaceOpenGLTextureCompatibilityKey, kCFBooleanTrue); +#endif CFRelease(io_surface_properties); CFRelease(cv_pix_fmt); From a755b725ec1d657609c8bd726ce37e7cf193d03f Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 2 Mar 2017 10:37:26 +0100 Subject: [PATCH 1028/3374] avcodec: consider an error during decoder draining as EOF There is no reason that draining couldn't return an error or two. But some decoders don't handle this very well, and might always return an error. This can lead to API users getting into an infinite loop and burning CPU, because no progress is made and EOF is never returned. In fact, ffmpeg.c contains a hack against such a case. It is made unnecessary with this commit, and removed with the next one. (This particular error case seems to have been fixed since the hack was added, though.) This might lose frames if decoding returns errors during draining. --- libavcodec/utils.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 1156e430794f8..db3adb18d4516 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -2807,12 +2807,12 @@ static int do_decode(AVCodecContext *avctx, AVPacket *pkt) if (ret == AVERROR(EAGAIN)) ret = pkt->size; - if (ret < 0) - return ret; - if (avctx->internal->draining && !got_frame) avctx->internal->draining_done = 1; + if (ret < 0) + return ret; + if (ret >= pkt->size) { av_packet_unref(avctx->internal->buffer_pkt); } else { From 808ab2fd0ba26ecb70655ec990748b16f30017bf Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 2 Mar 2017 10:38:44 +0100 Subject: [PATCH 1029/3374] ffmpeg: remove unnecessary hack for decoders which refuse to drain Now the previous commit takes care of this instead. --- ffmpeg.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index db7e8cd0c6723..79c91ffc1e615 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -2652,12 +2652,6 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo ist->file_index, ist->st->index, av_err2str(ret)); if (exit_on_error) exit_program(1); - // Decoding might not terminate if we're draining the decoder, and - // the decoder keeps returning an error. - // This should probably be considered a libavcodec issue. - // Sample: fate-vsynth1-dnxhd-720p-hr-lb - if (!pkt) - eof_reached = 1; break; } From ef86488696a84ae98028e4e199d51b10e331399d Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 2 Mar 2017 11:00:40 +0100 Subject: [PATCH 1030/3374] avformat/flvdec: remove meaningless warning Ever since the codecpar changes, this has been always printed when opening a flv file. This is because the codecpar changes made all streams to be added lazily as read_packet is called. --- libavformat/flvdec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 520a3a0034afb..3959a3665a39c 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -1033,7 +1033,6 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) } if (i == s->nb_streams) { static const enum AVMediaType stream_types[] = {AVMEDIA_TYPE_VIDEO, AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_SUBTITLE}; - av_log(s, AV_LOG_WARNING, "%s stream discovered after head already parsed\n", av_get_media_type_string(stream_types[stream_type])); st = create_stream(s, stream_types[stream_type]); if (!st) return AVERROR(ENOMEM); From a9f9b7f5c70e80245983e67b8ed23212d9637645 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 4 Mar 2017 19:19:31 +0100 Subject: [PATCH 1031/3374] avcodec/movtextdec: Call mov_text_cleanup() on close Fixes memleak Fixes: 548/clusterfuzz-testcase-5511470875934720 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/movtextdec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c index 81fd1d6deb41c..6de15004fc5b6 100644 --- a/libavcodec/movtextdec.c +++ b/libavcodec/movtextdec.c @@ -521,6 +521,7 @@ static int mov_text_decode_close(AVCodecContext *avctx) { MovTextContext *m = avctx->priv_data; mov_text_cleanup_ftab(m); + mov_text_cleanup(m); return 0; } From 835d9f299cf6b3704989a7b3eccfa1c2ec6866d9 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 5 Mar 2017 03:14:27 +0100 Subject: [PATCH 1032/3374] avcodec/x86/cavsdsp: Put MMX code under mmx check Without this the FPU state becomes trashed and causes mysterious fate failures with cpuflags=0 Signed-off-by: Michael Niedermayer --- libavcodec/x86/cavsdsp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavcodec/x86/cavsdsp.c b/libavcodec/x86/cavsdsp.c index 4b20e655a75f5..e57d8be76af8d 100644 --- a/libavcodec/x86/cavsdsp.c +++ b/libavcodec/x86/cavsdsp.c @@ -565,7 +565,9 @@ av_cold void ff_cavsdsp_init_x86(CAVSDSPContext *c, AVCodecContext *avctx) { av_unused int cpu_flags = av_get_cpu_flags(); - cavsdsp_init_mmx(c, avctx); + if (X86_MMX(cpu_flags)) + cavsdsp_init_mmx(c, avctx); + #if HAVE_AMD3DNOW_INLINE if (INLINE_AMD3DNOW(cpu_flags)) cavsdsp_init_3dnow(c, avctx); From 8aa4f3bb4f772404ff43a3c8c9d5faaadafbdfdd Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 4 Mar 2017 01:30:54 +0100 Subject: [PATCH 1033/3374] avcodec/proresdec2: Do not discard frames with bad slices The code previously completely discarded frames that had any error in a slice Signed-off-by: Michael Niedermayer --- libavcodec/proresdec2.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c index a3a1ebdecb97d..ff46bcfde0d72 100644 --- a/libavcodec/proresdec2.c +++ b/libavcodec/proresdec2.c @@ -614,14 +614,19 @@ static int decode_picture(AVCodecContext *avctx) { ProresContext *ctx = avctx->priv_data; int i; + int error = 0; avctx->execute2(avctx, decode_slice_thread, NULL, NULL, ctx->slice_count); for (i = 0; i < ctx->slice_count; i++) - if (ctx->slices[i].ret < 0) - return ctx->slices[i].ret; + error += ctx->slices[i].ret < 0; - return 0; + if (error) + av_frame_set_decode_error_flags(ctx->frame, FF_DECODE_ERROR_INVALID_BITSTREAM); + if (error < ctx->slice_count) + return 0; + + return ctx->slices[0].ret; } static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, From 734d760e2fb2621040edef3536b5935e7bc45351 Mon Sep 17 00:00:00 2001 From: Kagami Hiiragi Date: Thu, 2 Mar 2017 21:19:09 +0300 Subject: [PATCH 1034/3374] lavc/libvpxenc: add -row-mt option Signed-off-by: James Zern --- libavcodec/libvpxenc.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c index de0d0b6bcbb6a..7c567a0d1d13d 100644 --- a/libavcodec/libvpxenc.c +++ b/libavcodec/libvpxenc.c @@ -108,6 +108,7 @@ typedef struct VPxEncoderContext { int noise_sensitivity; int vpx_cs; float level; + int row_mt; } VPxContext; /** String mappings for enum vp8e_enc_control_id */ @@ -139,6 +140,9 @@ static const char *const ctlidstr[] = { [VP9E_SET_TARGET_LEVEL] = "VP9E_SET_TARGET_LEVEL", [VP9E_GET_LEVEL] = "VP9E_GET_LEVEL", #endif +#ifdef VPX_CTRL_VP9E_SET_ROW_MT + [VP9E_SET_ROW_MT] = "VP9E_SET_ROW_MT", +#endif #endif }; @@ -719,6 +723,10 @@ FF_ENABLE_DEPRECATION_WARNINGS #endif #if VPX_ENCODER_ABI_VERSION >= 12 codecctl_int(avctx, VP9E_SET_TARGET_LEVEL, ctx->level < 0 ? 255 : lrint(ctx->level * 10)); +#endif +#ifdef VPX_CTRL_VP9E_SET_ROW_MT + if (ctx->row_mt >= 0) + codecctl_int(avctx, VP9E_SET_ROW_MT, ctx->row_mt); #endif } #endif @@ -1131,6 +1139,9 @@ static const AVOption vp9_options[] = { { "cyclic", "Cyclic Refresh Aq", 0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 0, VE, "aq_mode" }, #if VPX_ENCODER_ABI_VERSION >= 12 {"level", "Specify level", OFFSET(level), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 6.2, VE}, +#endif +#ifdef VPX_CTRL_VP9E_SET_ROW_MT + {"row-mt", "Row based multi-threading", OFFSET(row_mt), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, #endif LEGACY_OPTIONS { NULL } From b6eaa3928e198554a3934dd5ad6eac4d16f27df2 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Tue, 21 Feb 2017 10:48:37 -0800 Subject: [PATCH 1035/3374] avcodec/h264, videotoolbox: fix crash after VT decoder fails The way videotoolbox hooks in as a hwaccel is pretty hacky. The VT decode API is not invoked until end_frame(), so alloc_frame() returns a dummy frame with a 1-byte buffer. When end_frame() is eventually called, the dummy buffer is replaced with the actual decoded data from VTDecompressionSessionDecodeFrame(). When the VT decoder fails, the frame returned to the h264 decoder from alloc_frame() remains invalid and should not be used. Before 9747219958060d8c4f697df62e7f172c2a77e6c7, it was accidentally being returned all the way up to the API user. After that commit, the dummy frame was unref'd so the user received an error. However, since that commit, VT hwaccel failures started causing random segfaults in the h264 decoder. This happened more often on iOS where the VT implementation is more likely to throw errors on bitstream anomolies. A recent report of this issue can be see in http://ffmpeg.org/pipermail/libav-user/2016-November/009831.html The issue here is that the dummy frame is still referenced internally by the h264 decoder, as part of the reflist and cur_pic_ptr. Deallocating the frame causes assertions like this one to trip later on during decoding: Assertion h->cur_pic_ptr->f->buf[0] failed at src/libavcodec/h264_slice.c:1340 With this commit, we leave the dummy 1-byte frame intact, but avoid returning it to the user. This reverts commit 9747219958060d8c4f697df62e7f172c2a77e6c7. Signed-off-by: wm4 --- libavcodec/h264_refs.c | 3 +-- libavcodec/h264dec.c | 7 ++++++- libavcodec/version.h | 2 +- libavcodec/videotoolbox.c | 2 -- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c index 97bf588b512c1..ad296753c3bd9 100644 --- a/libavcodec/h264_refs.c +++ b/libavcodec/h264_refs.c @@ -571,8 +571,7 @@ void ff_h264_remove_all_refs(H264Context *h) if (h->short_ref_count && !h->last_pic_for_ec.f->data[0]) { ff_h264_unref_picture(h, &h->last_pic_for_ec); - if (h->short_ref[0]->f->buf[0]) - ff_h264_ref_picture(h, &h->last_pic_for_ec, h->short_ref[0]); + ff_h264_ref_picture(h, &h->last_pic_for_ec, h->short_ref[0]); } for (i = 0; i < h->short_ref_count; i++) { diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 41c0964392a47..35598ea7cd759 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -850,7 +850,12 @@ static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp) AVFrame *src = srcp->f; const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(src->format); int i; - int ret = av_frame_ref(dst, src); + int ret; + + if (src->format == AV_PIX_FMT_VIDEOTOOLBOX && src->buf[0]->size == 1) + return AVERROR_EXTERNAL; + + ret = av_frame_ref(dst, src); if (ret < 0) return ret; diff --git a/libavcodec/version.h b/libavcodec/version.h index 7647ad2e189e6..cd9ed87225f1d 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 82 -#define LIBAVCODEC_VERSION_MICRO 100 +#define LIBAVCODEC_VERSION_MICRO 101 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavcodec/videotoolbox.c b/libavcodec/videotoolbox.c index 9199b020556bd..67adad53ed8bb 100644 --- a/libavcodec/videotoolbox.c +++ b/libavcodec/videotoolbox.c @@ -352,8 +352,6 @@ static int videotoolbox_common_end_frame(AVCodecContext *avctx, AVFrame *frame) AVVideotoolboxContext *videotoolbox = avctx->hwaccel_context; VTContext *vtctx = avctx->internal->hwaccel_priv_data; - av_buffer_unref(&frame->buf[0]); - if (!videotoolbox->session || !vtctx->bitstream) return AVERROR_INVALIDDATA; From a6b1180e390925c0ceb78fd223fd18f8c1e39c94 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Tue, 7 Mar 2017 13:57:34 +0100 Subject: [PATCH 1036/3374] avcodec/pixlet: fix architecture-dependent code and values The constants used in the decoder used floating point precision, and this caused different values to be generated on different architectures. So, eradicate floating point numbers and use fixed point (32.32) arithmetics everywhere, replacing constants with precomputed integer values. Signed-off-by: Vittorio Giovara Signed-off-by: Paul B Mahol --- libavcodec/pixlet.c | 57 ++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/libavcodec/pixlet.c b/libavcodec/pixlet.c index bb7f94c65f245..1d4734d397deb 100644 --- a/libavcodec/pixlet.c +++ b/libavcodec/pixlet.c @@ -55,7 +55,7 @@ typedef struct PixletContext { int16_t *filter[2]; int16_t *prediction; - float scaling[4][2][NB_LEVELS]; + int64_t scaling[4][2][NB_LEVELS]; SubBand band[4][NB_LEVELS * 3 + 1]; } PixletContext; @@ -360,11 +360,11 @@ static void lowpass_prediction(int16_t *dst, int16_t *pred, int width, int heigh } } -static void filter(int16_t *dest, int16_t *tmp, unsigned size, float SCALE) +static void filterfn(int16_t *dest, int16_t *tmp, unsigned size, int64_t scale) { int16_t *low, *high, *ll, *lh, *hl, *hh; int hsize, i, j; - float value; + int64_t value; hsize = size >> 1; low = tmp + 4; @@ -385,33 +385,33 @@ static void filter(int16_t *dest, int16_t *tmp, unsigned size, float SCALE) } for (i = 0; i < hsize; i++) { - value = low [i+1] * -0.07576144003329376f + - low [i ] * 0.8586296626673486f + - low [i-1] * -0.07576144003329376f + - high[i ] * 0.3535533905932737f + - high[i-1] * 0.3535533905932737f; - dest[i * 2] = av_clipf(value * SCALE, INT16_MIN, INT16_MAX); + value = (int64_t) low [i + 1] * -INT64_C(325392907) + + (int64_t) low [i + 0] * INT64_C(3687786320) + + (int64_t) low [i - 1] * -INT64_C(325392907) + + (int64_t) high[i + 0] * INT64_C(1518500249) + + (int64_t) high[i - 1] * INT64_C(1518500249); + dest[i * 2] = av_clip_int16(((value >> 32) * scale) >> 32); } for (i = 0; i < hsize; i++) { - value = low [i+2] * -0.01515228715813062f + - low [i+1] * 0.3687056777514043f + - low [i ] * 0.3687056777514043f + - low [i-1] * -0.01515228715813062f + - high[i+1] * 0.07071067811865475f + - high[i ] * -0.8485281374238569f + - high[i-1] * 0.07071067811865475f; - dest[i * 2 + 1] = av_clipf(value * SCALE, INT16_MIN, INT16_MAX); + value = (int64_t) low [i + 2] * -INT64_C(65078576) + + (int64_t) low [i + 1] * INT64_C(1583578880) + + (int64_t) low [i + 0] * INT64_C(1583578880) + + (int64_t) low [i - 1] * -INT64_C(65078576) + + (int64_t) high[i + 1] * INT64_C(303700064) + + (int64_t) high[i + 0] * -INT64_C(3644400640) + + (int64_t) high[i - 1] * INT64_C(303700064); + dest[i * 2 + 1] = av_clip_int16(((value >> 32) * scale) >> 32); } } static void reconstruction(AVCodecContext *avctx, int16_t *dest, unsigned width, unsigned height, ptrdiff_t stride, int nb_levels, - float *scaling_H, float *scaling_V) + int64_t *scaling_H, int64_t *scaling_V) { PixletContext *ctx = avctx->priv_data; unsigned scaled_width, scaled_height; - float scale_H, scale_V; + int64_t scale_H, scale_V; int16_t *ptr, *tmp; int i, j, k; @@ -427,7 +427,7 @@ static void reconstruction(AVCodecContext *avctx, ptr = dest; for (j = 0; j < scaled_height; j++) { - filter(ptr, ctx->filter[1], scaled_width, scale_V); + filterfn(ptr, ctx->filter[1], scaled_width, scale_V); ptr += stride; } @@ -438,7 +438,7 @@ static void reconstruction(AVCodecContext *avctx, ptr += stride; } - filter(tmp, ctx->filter[1], scaled_height, scale_H); + filterfn(tmp, ctx->filter[1], scaled_height, scale_H); ptr = dest + j; for (k = 0; k < scaled_height; k++) { @@ -449,19 +449,22 @@ static void reconstruction(AVCodecContext *avctx, } } -#define SQR(a) ((a) * (a)) - static void postprocess_luma(AVFrame *frame, int w, int h, int depth) { uint16_t *dsty = (uint16_t *)frame->data[0]; int16_t *srcy = (int16_t *)frame->data[0]; ptrdiff_t stridey = frame->linesize[0] / 2; - const float factor = 1.0f / ((1 << depth) - 1); int i, j; for (j = 0; j < h; j++) { for (i = 0; i < w; i++) { - dsty[i] = SQR(FFMAX(srcy[i], 0) * factor) * 65535; + if (srcy[i] <= 0) + dsty[i] = 0; + else if (srcy[i] > ((1 << depth) - 1)) + dsty[i] = 65535; + else + dsty[i] = ((int64_t) srcy[i] * srcy[i] * 65535) / + ((1 << depth) - 1) / ((1 << depth) - 1); } dsty += stridey; srcy += stridey; @@ -507,8 +510,8 @@ static int decode_plane(AVCodecContext *avctx, int plane, AVPacket *avpkt, AVFra if (!h || !v) return AVERROR_INVALIDDATA; - ctx->scaling[plane][H][i] = 1000000.0f / h; - ctx->scaling[plane][V][i] = 1000000.0f / v; + ctx->scaling[plane][H][i] = (1000000ULL << 32) / h; + ctx->scaling[plane][V][i] = (1000000ULL << 32) / v; } bytestream2_skip(&ctx->gb, 4); From e85e8408802dc3a474e6a610867df8e57c768339 Mon Sep 17 00:00:00 2001 From: Muhammad Faiz Date: Tue, 7 Mar 2017 15:51:12 +0700 Subject: [PATCH 1037/3374] avcodec/allcodecs: make avcodec_register_all thread safe use ff_thread_once Suggested-by: wm4 Signed-off-by: Muhammad Faiz --- libavcodec/allcodecs.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index a265ce5728da3..074efd463f6f5 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -25,6 +25,7 @@ */ #include "config.h" +#include "libavutil/thread.h" #include "avcodec.h" #include "version.h" @@ -58,14 +59,8 @@ av_register_codec_parser(&ff_##x##_parser); \ } -void avcodec_register_all(void) +static void register_all(void) { - static int initialized; - - if (initialized) - return; - initialized = 1; - /* hardware accelerators */ REGISTER_HWACCEL(H263_VAAPI, h263_vaapi); REGISTER_HWACCEL(H263_VIDEOTOOLBOX, h263_videotoolbox); @@ -718,3 +713,10 @@ void avcodec_register_all(void) REGISTER_PARSER(VP9, vp9); REGISTER_PARSER(XMA, xma); } + +void avcodec_register_all(void) +{ + static AVOnce control = AV_ONCE_INIT; + + ff_thread_once(&control, register_all); +} From 49635f0a46365f361ce665356bb41e199176021b Mon Sep 17 00:00:00 2001 From: Muhammad Faiz Date: Tue, 7 Mar 2017 15:53:27 +0700 Subject: [PATCH 1038/3374] avfilter/allformats: make av_register_all thread safe use ff_thread_once Suggested-by: wm4 Signed-off-by: Muhammad Faiz --- libavformat/allformats.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/libavformat/allformats.c b/libavformat/allformats.c index 35869e3cf0688..132e58b8b9351 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/thread.h" #include "avformat.h" #include "rtp.h" #include "rdt.h" @@ -41,13 +42,8 @@ #define REGISTER_MUXDEMUX(X, x) REGISTER_MUXER(X, x); REGISTER_DEMUXER(X, x) -void av_register_all(void) +static void register_all(void) { - static int initialized; - - if (initialized) - return; - avcodec_register_all(); /* (de)muxers */ @@ -383,6 +379,11 @@ void av_register_all(void) REGISTER_DEMUXER (LIBMODPLUG, libmodplug); REGISTER_MUXDEMUX(LIBNUT, libnut); REGISTER_DEMUXER (LIBOPENMPT, libopenmpt); +} + +void av_register_all(void) +{ + AVOnce control = AV_ONCE_INIT; - initialized = 1; + ff_thread_once(&control, register_all); } From af7010ad0557fe66d35886581eecebf02e92637c Mon Sep 17 00:00:00 2001 From: Muhammad Faiz Date: Tue, 7 Mar 2017 15:54:44 +0700 Subject: [PATCH 1039/3374] avfilter/allfilters: make avfilter_register_all thread safe use ff_thread_once Suggested-by: wm4 Signed-off-by: Muhammad Faiz --- libavfilter/allfilters.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 15a74c4eeddbb..df1af8de232be 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/thread.h" #include "avfilter.h" #include "config.h" #include "opencl_allkernels.h" @@ -37,14 +38,8 @@ avfilter_register(&ff_##x); \ } -void avfilter_register_all(void) +static void register_all(void) { - static int initialized; - - if (initialized) - return; - initialized = 1; - REGISTER_FILTER(ABENCH, abench, af); REGISTER_FILTER(ACOMPRESSOR, acompressor, af); REGISTER_FILTER(ACROSSFADE, acrossfade, af); @@ -380,3 +375,10 @@ void avfilter_register_all(void) REGISTER_FILTER_UNCONDITIONAL(vf_fifo); ff_opencl_register_filter_kernel_code_all(); } + +void avfilter_register_all(void) +{ + AVOnce control = AV_ONCE_INIT; + + ff_thread_once(&control, register_all); +} From 776f289c0fe82c4e3418a7c504ae3247eb10ffd7 Mon Sep 17 00:00:00 2001 From: Muhammad Faiz Date: Tue, 7 Mar 2017 15:55:38 +0700 Subject: [PATCH 1040/3374] avdevice/alldevices: make avdevice_register_all thread safe use ff_thread_once Suggested-by: wm4 Signed-off-by: Muhammad Faiz --- libavdevice/alldevices.c | 16 +++++++++------- libavdevice/avdevice.h | 1 - 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/libavdevice/alldevices.c b/libavdevice/alldevices.c index a761be4f9c3a0..75f4ae0428a12 100644 --- a/libavdevice/alldevices.c +++ b/libavdevice/alldevices.c @@ -19,6 +19,7 @@ */ #include "config.h" +#include "libavutil/thread.h" #include "avdevice.h" #define REGISTER_OUTDEV(X, x) \ @@ -37,14 +38,8 @@ #define REGISTER_INOUTDEV(X, x) REGISTER_OUTDEV(X, x); REGISTER_INDEV(X, x) -void avdevice_register_all(void) +static void register_all(void) { - static int initialized; - - if (initialized) - return; - initialized = 1; - /* devices */ REGISTER_INOUTDEV(ALSA, alsa); REGISTER_INDEV (AVFOUNDATION, avfoundation); @@ -76,3 +71,10 @@ void avdevice_register_all(void) REGISTER_INDEV (LIBCDIO, libcdio); REGISTER_INDEV (LIBDC1394, libdc1394); } + +void avdevice_register_all(void) +{ + AVOnce control = AV_ONCE_INIT; + + ff_thread_once(&control, register_all); +} diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h index 6153f2cd46dbc..84f374a6f8111 100644 --- a/libavdevice/avdevice.h +++ b/libavdevice/avdevice.h @@ -67,7 +67,6 @@ const char *avdevice_license(void); /** * Initialize libavdevice and register all the input and output devices. - * @warning This function is not thread safe. */ void avdevice_register_all(void); From 1b7ffddb3a999f37443c58232b112534c0abcf28 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Fri, 10 Feb 2017 15:26:55 -0500 Subject: [PATCH 1041/3374] spherical: Add tiled equirectangular type and projection-specific properties Signed-off-by: Vittorio Giovara --- doc/APIchanges | 5 ++ ffprobe.c | 19 +++++-- libavformat/dump.c | 15 +++++- libavutil/spherical.c | 18 +++++++ libavutil/spherical.h | 74 ++++++++++++++++++++++++++ libavutil/version.h | 4 +- tests/ref/fate/matroska-spherical-mono | 2 +- tests/ref/fate/mov-spherical-mono | 2 +- 8 files changed, 129 insertions(+), 10 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 6922ea5268f65..dc36a6bea7c82 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,11 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-02-10 - xxxxxxx - lavu 55.48.100 / 55.33.0 - spherical.h + Add AV_SPHERICAL_EQUIRECTANGULAR_TILE, av_spherical_tile_bounds(), + and projection-specific properties (bound_left, bound_top, bound_right, + bound_bottom, padding) to AVSphericalMapping. + 2017-03-02 - xxxxxxx - lavc 57.81.104 - videotoolbox.h AVVideotoolboxContext.cv_pix_fmt_type can now be set to 0 to output the native decoder format. (The default value is not changed.) diff --git a/ffprobe.c b/ffprobe.c index 046f080792ba1..c85c3a104b316 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -1762,6 +1762,7 @@ static inline int show_tags(WriterContext *w, AVDictionary *tags, int section_id } static void print_pkt_side_data(WriterContext *w, + AVCodecParameters *par, const AVPacketSideData *side_data, int nb_side_data, SectionID id_data_list, @@ -1788,9 +1789,19 @@ static void print_pkt_side_data(WriterContext *w, const AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data; if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR) print_str("projection", "equirectangular"); - else if (spherical->projection == AV_SPHERICAL_CUBEMAP) + else if (spherical->projection == AV_SPHERICAL_CUBEMAP) { print_str("projection", "cubemap"); - else + print_int("padding", spherical->padding); + } else if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE) { + size_t l, t, r, b; + av_spherical_tile_bounds(spherical, par->width, par->height, + &l, &t, &r, &b); + print_str("projection", "tiled equirectangular"); + print_int("bound_left", l); + print_int("bound_top", t); + print_int("bound_right", r); + print_int("bound_bottom", b); + } else print_str("projection", "unknown"); print_int("yaw", (double) spherical->yaw / (1 << 16)); @@ -1843,7 +1854,7 @@ static void show_packet(WriterContext *w, InputFile *ifile, AVPacket *pkt, int p av_dict_free(&dict); } - print_pkt_side_data(w, pkt->side_data, pkt->side_data_elems, + print_pkt_side_data(w, st->codecpar, pkt->side_data, pkt->side_data_elems, SECTION_ID_PACKET_SIDE_DATA_LIST, SECTION_ID_PACKET_SIDE_DATA); } @@ -2404,7 +2415,7 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id ret = show_tags(w, stream->metadata, in_program ? SECTION_ID_PROGRAM_STREAM_TAGS : SECTION_ID_STREAM_TAGS); if (stream->nb_side_data) { - print_pkt_side_data(w, stream->side_data, stream->nb_side_data, + print_pkt_side_data(w, stream->codecpar, stream->side_data, stream->nb_side_data, SECTION_ID_STREAM_SIDE_DATA_LIST, SECTION_ID_STREAM_SIDE_DATA); } diff --git a/libavformat/dump.c b/libavformat/dump.c index d9aa3afe58c59..505d572301743 100644 --- a/libavformat/dump.c +++ b/libavformat/dump.c @@ -343,7 +343,7 @@ static void dump_mastering_display_metadata(void *ctx, AVPacketSideData* sd) { av_q2d(metadata->min_luminance), av_q2d(metadata->max_luminance)); } -static void dump_spherical(void *ctx, AVPacketSideData *sd) +static void dump_spherical(void *ctx, AVCodecParameters *par, AVPacketSideData *sd) { AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data; double yaw, pitch, roll; @@ -357,6 +357,8 @@ static void dump_spherical(void *ctx, AVPacketSideData *sd) av_log(ctx, AV_LOG_INFO, "equirectangular "); else if (spherical->projection == AV_SPHERICAL_CUBEMAP) av_log(ctx, AV_LOG_INFO, "cubemap "); + else if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE) + av_log(ctx, AV_LOG_INFO, "tiled equirectangular "); else { av_log(ctx, AV_LOG_WARNING, "unknown"); return; @@ -366,6 +368,15 @@ static void dump_spherical(void *ctx, AVPacketSideData *sd) pitch = ((double)spherical->pitch) / (1 << 16); roll = ((double)spherical->roll) / (1 << 16); av_log(ctx, AV_LOG_INFO, "(%f/%f/%f) ", yaw, pitch, roll); + + if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE) { + size_t l, t, r, b; + av_spherical_tile_bounds(spherical, par->width, par->height, + &l, &t, &r, &b); + av_log(ctx, AV_LOG_INFO, "[%zu, %zu, %zu, %zu] ", l, t, r, b); + } else if (spherical->projection == AV_SPHERICAL_CUBEMAP) { + av_log(ctx, AV_LOG_INFO, "[pad %zu] ", spherical->padding); + } } static void dump_sidedata(void *ctx, AVStream *st, const char *indent) @@ -421,7 +432,7 @@ static void dump_sidedata(void *ctx, AVStream *st, const char *indent) break; case AV_PKT_DATA_SPHERICAL: av_log(ctx, AV_LOG_INFO, "spherical: "); - dump_spherical(ctx, &sd); + dump_spherical(ctx, st->codecpar, &sd); break; default: av_log(ctx, AV_LOG_INFO, diff --git a/libavutil/spherical.c b/libavutil/spherical.c index 816452cbd6f2e..0ca2dd367a769 100644 --- a/libavutil/spherical.c +++ b/libavutil/spherical.c @@ -32,3 +32,21 @@ AVSphericalMapping *av_spherical_alloc(size_t *size) return spherical; } + +void av_spherical_tile_bounds(AVSphericalMapping *map, + size_t width, size_t height, + size_t *left, size_t *top, + size_t *right, size_t *bottom) +{ + /* conversion from 0.32 coordinates to pixels */ + uint64_t orig_width = (uint64_t) width * UINT32_MAX / + (UINT32_MAX - map->bound_right - map->bound_left); + uint64_t orig_height = (uint64_t) height * UINT32_MAX / + (UINT32_MAX - map->bound_bottom - map->bound_top); + + /* add a (UINT32_MAX - 1) to round up integer division */ + *left = (orig_width * map->bound_left + UINT32_MAX - 1) / UINT32_MAX; + *top = (orig_height * map->bound_top + UINT32_MAX - 1) / UINT32_MAX; + *right = orig_width - width - *left; + *bottom = orig_height - height - *top; +} diff --git a/libavutil/spherical.h b/libavutil/spherical.h index eeda62523103d..db9bdc0be5f0c 100644 --- a/libavutil/spherical.h +++ b/libavutil/spherical.h @@ -63,6 +63,13 @@ enum AVSphericalProjection { * to the back. */ AV_SPHERICAL_CUBEMAP, + + /** + * Video represents a portion of a sphere mapped on a flat surface + * using equirectangular projection. The @ref bounding fields indicate + * the position of the current video in a larger surface. + */ + AV_SPHERICAL_EQUIRECTANGULAR_TILE, }; /** @@ -122,6 +129,57 @@ typedef struct AVSphericalMapping { /** * @} */ + + /** + * @name Bounding rectangle + * @anchor bounding + * @{ + * These fields indicate the location of the current tile, and where + * it should be mapped relative to the original surface. They are + * exported as 0.32 fixed point, and can be converted to classic + * pixel values with av_spherical_bounds(). + * + * @code{.unparsed} + * +----------------+----------+ + * | |bound_top | + * | +--------+ | + * | bound_left |tile | | + * +<---------->| |<--->+bound_right + * | +--------+ | + * | | | + * | bound_bottom| | + * +----------------+----------+ + * @endcode + * + * If needed, the original video surface dimensions can be derived + * by adding the current stream or frame size to the related bounds, + * like in the following example: + * + * @code{c} + * original_width = tile->width + bound_left + bound_right; + * original_height = tile->height + bound_top + bound_bottom; + * @endcode + * + * @note These values are valid only for the tiled equirectangular + * projection type (@ref AV_SPHERICAL_EQUIRECTANGULAR_TILE), + * and should be ignored in all other cases. + */ + size_t bound_left; ///< Distance from the left edge + size_t bound_top; ///< Distance from the top edge + size_t bound_right; ///< Distance from the right edge + size_t bound_bottom; ///< Distance from the bottom edge + /** + * @} + */ + + /** + * Number of pixels to pad from the edge of each cube face. + * + * @note This value is valid for only for the cubemap projection type + * (@ref AV_SPHERICAL_CUBEMAP), and should be ignored in all other + * cases. + */ + size_t padding; } AVSphericalMapping; /** @@ -132,6 +190,22 @@ typedef struct AVSphericalMapping { */ AVSphericalMapping *av_spherical_alloc(size_t *size); +/** + * Convert the @ref bounding fields from an AVSphericalVideo + * from 0.32 fixed point to pixels. + * + * @param map The AVSphericalVideo map to read bound values from. + * @param width Width of the current frame or stream. + * @param height Height of the current frame or stream. + * @param left Pixels from the left edge. + * @param top Pixels from the top edge. + * @param right Pixels from the right edge. + * @param bottom Pixels from the bottom edge. + */ +void av_spherical_tile_bounds(AVSphericalMapping *map, + size_t width, size_t height, + size_t *left, size_t *top, + size_t *right, size_t *bottom); /** * @} * @} diff --git a/libavutil/version.h b/libavutil/version.h index 3cf9d7ff157d1..4d5a40513076d 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,8 +79,8 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 47 -#define LIBAVUTIL_VERSION_MICRO 101 +#define LIBAVUTIL_VERSION_MINOR 48 +#define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ LIBAVUTIL_VERSION_MINOR, \ diff --git a/tests/ref/fate/matroska-spherical-mono b/tests/ref/fate/matroska-spherical-mono index 9f4b4f8e17237..8048aff0dc885 100644 --- a/tests/ref/fate/matroska-spherical-mono +++ b/tests/ref/fate/matroska-spherical-mono @@ -7,7 +7,7 @@ inverted=0 [/SIDE_DATA] [SIDE_DATA] side_data_type=Spherical Mapping -side_data_size=16 +side_data_size=56 projection=equirectangular yaw=45 pitch=30 diff --git a/tests/ref/fate/mov-spherical-mono b/tests/ref/fate/mov-spherical-mono index 9f4b4f8e17237..8048aff0dc885 100644 --- a/tests/ref/fate/mov-spherical-mono +++ b/tests/ref/fate/mov-spherical-mono @@ -7,7 +7,7 @@ inverted=0 [/SIDE_DATA] [SIDE_DATA] side_data_type=Spherical Mapping -side_data_size=16 +side_data_size=56 projection=equirectangular yaw=45 pitch=30 From 022b4ea5837bb79b9fe32bf707c3117be8e6d730 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Fri, 10 Feb 2017 15:36:56 -0500 Subject: [PATCH 1042/3374] mov: Export bounds and padding from spherical metadata Update the fate test as needed. --- libavformat/mov.c | 28 +++++++++++++++++++++++++++- tests/ref/fate/mov-spherical-mono | 6 +++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 2a7cbfe14283e..cc098cd97787e 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -4637,6 +4637,8 @@ static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom) MOVStreamContext *sc; int size; int32_t yaw, pitch, roll; + size_t l = 0, t = 0, r = 0, b = 0; + size_t padding = 0; uint32_t tag; enum AVSphericalProjection projection; @@ -4698,9 +4700,26 @@ static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom) switch (tag) { case MKTAG('c','b','m','p'): projection = AV_SPHERICAL_CUBEMAP; + padding = avio_rb32(pb); break; case MKTAG('e','q','u','i'): - projection = AV_SPHERICAL_EQUIRECTANGULAR; + t = avio_rb32(pb); + b = avio_rb32(pb); + l = avio_rb32(pb); + r = avio_rb32(pb); + + if (b >= UINT_MAX - t || r >= UINT_MAX - l) { + av_log(c->fc, AV_LOG_ERROR, + "Invalid bounding rectangle coordinates %"SIZE_SPECIFIER"," + "%"SIZE_SPECIFIER",%"SIZE_SPECIFIER",%"SIZE_SPECIFIER"\n", + l, t, r, b); + return AVERROR_INVALIDDATA; + } + + if (l || t || r || b) + projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE; + else + projection = AV_SPHERICAL_EQUIRECTANGULAR; break; default: av_log(c->fc, AV_LOG_ERROR, "Unknown projection type\n"); @@ -4717,6 +4736,13 @@ static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom) sc->spherical->pitch = pitch; sc->spherical->roll = roll; + sc->spherical->padding = padding; + + sc->spherical->bound_left = l; + sc->spherical->bound_top = t; + sc->spherical->bound_right = r; + sc->spherical->bound_bottom = b; + return 0; } diff --git a/tests/ref/fate/mov-spherical-mono b/tests/ref/fate/mov-spherical-mono index 8048aff0dc885..a70d879f0e464 100644 --- a/tests/ref/fate/mov-spherical-mono +++ b/tests/ref/fate/mov-spherical-mono @@ -8,7 +8,11 @@ inverted=0 [SIDE_DATA] side_data_type=Spherical Mapping side_data_size=56 -projection=equirectangular +projection=tiled equirectangular +bound_left=148 +bound_top=73 +bound_right=147 +bound_bottom=72 yaw=45 pitch=30 roll=15 From bde96422686fdb4bf754e9d03c0c535572b02f30 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Fri, 10 Feb 2017 16:02:22 -0500 Subject: [PATCH 1043/3374] mkv: Export bounds and padding from spherical metadata Update the fate test as needed. --- libavformat/matroskadec.c | 64 ++++++++++++++++++++++++-- tests/ref/fate/matroska-spherical-mono | 6 ++- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 11265fb229361..fdc3f268aa618 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -1913,16 +1913,67 @@ static int mkv_parse_video_projection(AVStream *st, const MatroskaTrack *track) AVSphericalMapping *spherical; enum AVSphericalProjection projection; size_t spherical_size; + size_t l = 0, t = 0, r = 0, b = 0; + size_t padding = 0; int ret; + GetByteContext gb; + + bytestream2_init(&gb, track->video.projection.private.data, + track->video.projection.private.size); + + if (bytestream2_get_byte(&gb) != 0) { + av_log(NULL, AV_LOG_WARNING, "Unknown spherical metadata\n"); + return 0; + } + + bytestream2_skip(&gb, 3); // flags switch (track->video.projection.type) { case MATROSKA_VIDEO_PROJECTION_TYPE_EQUIRECTANGULAR: - projection = AV_SPHERICAL_EQUIRECTANGULAR; + if (track->video.projection.private.size == 0) + projection = AV_SPHERICAL_EQUIRECTANGULAR; + else if (track->video.projection.private.size == 20) { + t = bytestream2_get_be32(&gb); + b = bytestream2_get_be32(&gb); + l = bytestream2_get_be32(&gb); + r = bytestream2_get_be32(&gb); + + if (b >= UINT_MAX - t || r >= UINT_MAX - l) { + av_log(NULL, AV_LOG_ERROR, + "Invalid bounding rectangle coordinates " + "%"SIZE_SPECIFIER",%"SIZE_SPECIFIER"," + "%"SIZE_SPECIFIER",%"SIZE_SPECIFIER"\n", + l, t, r, b); + return AVERROR_INVALIDDATA; + } + + if (l || t || r || b) + projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE; + else + projection = AV_SPHERICAL_EQUIRECTANGULAR; + } else { + av_log(NULL, AV_LOG_ERROR, "Unknown spherical metadata\n"); + return AVERROR_INVALIDDATA; + } break; case MATROSKA_VIDEO_PROJECTION_TYPE_CUBEMAP: - if (track->video.projection.private.size < 4) + if (track->video.projection.private.size < 4) { + av_log(NULL, AV_LOG_ERROR, "Missing projection private properties\n"); + return AVERROR_INVALIDDATA; + } else if (track->video.projection.private.size == 12) { + uint32_t layout = bytestream2_get_be32(&gb); + if (layout == 0) { + projection = AV_SPHERICAL_CUBEMAP; + } else { + av_log(NULL, AV_LOG_WARNING, + "Unknown spherical cubemap layout %"PRIu32"\n", layout); + return 0; + } + padding = bytestream2_get_be32(&gb); + } else { + av_log(NULL, AV_LOG_ERROR, "Unknown spherical metadata\n"); return AVERROR_INVALIDDATA; - projection = AV_SPHERICAL_CUBEMAP; + } break; default: return 0; @@ -1937,6 +1988,13 @@ static int mkv_parse_video_projection(AVStream *st, const MatroskaTrack *track) spherical->pitch = (int32_t)(track->video.projection.pitch * (1 << 16)); spherical->roll = (int32_t)(track->video.projection.roll * (1 << 16)); + spherical->padding = padding; + + spherical->bound_left = l; + spherical->bound_top = t; + spherical->bound_right = r; + spherical->bound_bottom = b; + ret = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL, (uint8_t *)spherical, spherical_size); if (ret < 0) { diff --git a/tests/ref/fate/matroska-spherical-mono b/tests/ref/fate/matroska-spherical-mono index 8048aff0dc885..a70d879f0e464 100644 --- a/tests/ref/fate/matroska-spherical-mono +++ b/tests/ref/fate/matroska-spherical-mono @@ -8,7 +8,11 @@ inverted=0 [SIDE_DATA] side_data_type=Spherical Mapping side_data_size=56 -projection=equirectangular +projection=tiled equirectangular +bound_left=148 +bound_top=73 +bound_right=147 +bound_bottom=72 yaw=45 pitch=30 roll=15 From 5098a6f6275a57f122cd8f03e7ffbe5dd090b8e0 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 7 Mar 2017 00:53:52 +0100 Subject: [PATCH 1044/3374] avcodec/vp8: remove redundant check Reviewed-by: Paul B Mahol Signed-off-by: Michael Niedermayer --- libavcodec/vp8.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index cc158528ef61b..fb17ff114d275 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -2497,8 +2497,6 @@ int vp78_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, int jobnr, td->thread_nr = threadnr; for (mb_y = jobnr; mb_y < s->mb_height; mb_y += num_jobs) { - if (mb_y >= s->mb_height) - break; td->thread_mb_pos = mb_y << 16; ret = s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr); if (ret < 0) From 55d7371fe0c44c025eb0e75215e0685870f31874 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 7 Mar 2017 19:09:38 +0100 Subject: [PATCH 1045/3374] avcodec/vp568: Check that there is enough data for ff_vp56_init_range_decoder() Fixes: timeout in 730/clusterfuzz-testcase-5265113739165696 (part 1 of 2) Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Reviewed-by: BBB Signed-off-by: Michael Niedermayer --- libavcodec/vp5.c | 5 ++++- libavcodec/vp56.h | 2 +- libavcodec/vp56rac.c | 5 ++++- libavcodec/vp6.c | 15 +++++++++++---- libavcodec/vp8.c | 21 ++++++++++++++------- libavcodec/vp9.c | 9 +++++++-- 6 files changed, 41 insertions(+), 16 deletions(-) diff --git a/libavcodec/vp5.c b/libavcodec/vp5.c index 54db620bde69f..b5f06a09403c5 100644 --- a/libavcodec/vp5.c +++ b/libavcodec/vp5.c @@ -38,8 +38,11 @@ static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size) { VP56RangeCoder *c = &s->c; int rows, cols; + int ret; - ff_vp56_init_range_decoder(&s->c, buf, buf_size); + ret = ff_vp56_init_range_decoder(&s->c, buf, buf_size); + if (ret < 0) + return ret; s->frames[VP56_FRAME_CURRENT]->key_frame = !vp56_rac_get(c); vp56_rac_get(c); ff_vp56_init_dequant(s, vp56_rac_gets(c, 6)); diff --git a/libavcodec/vp56.h b/libavcodec/vp56.h index e5c5bea96331f..c049399df8ffa 100644 --- a/libavcodec/vp56.h +++ b/libavcodec/vp56.h @@ -224,7 +224,7 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, */ extern const uint8_t ff_vp56_norm_shift[256]; -void ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size); +int ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size); static av_always_inline unsigned int vp56_rac_renorm(VP56RangeCoder *c) { diff --git a/libavcodec/vp56rac.c b/libavcodec/vp56rac.c index 6061b7ee72c8a..e70302bf856da 100644 --- a/libavcodec/vp56rac.c +++ b/libavcodec/vp56rac.c @@ -37,11 +37,14 @@ const uint8_t ff_vp56_norm_shift[256]= { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, }; -void ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size) +int ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size) { c->high = 255; c->bits = -16; c->buffer = buf; c->end = buf + buf_size; + if (buf_size < 1) + return AVERROR_INVALIDDATA; c->code_word = bytestream_get_be24(&c->buffer); + return 0; } diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c index 662126ca70725..f0e60a3822ae6 100644 --- a/libavcodec/vp6.c +++ b/libavcodec/vp6.c @@ -52,6 +52,7 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size) int sub_version; int rows, cols; int res = 0; + int ret; int separated_coeff = buf[0] & 1; s->frames[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80); @@ -93,7 +94,7 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size) s->avctx->coded_width = 16 * cols; s->avctx->coded_height = 16 * rows; } else { - int ret = ff_set_dimensions(s->avctx, 16 * cols, 16 * rows); + ret = ff_set_dimensions(s->avctx, 16 * cols, 16 * rows); if (ret < 0) return ret; @@ -105,7 +106,9 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size) res = VP56_SIZE_CHANGE; } - ff_vp56_init_range_decoder(c, buf+6, buf_size-6); + ret = ff_vp56_init_range_decoder(c, buf+6, buf_size-6); + if (ret < 0) + return ret; vp56_rac_gets(c, 2); parse_filter_info = s->filter_header; @@ -122,7 +125,9 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size) buf += 2; buf_size -= 2; } - ff_vp56_init_range_decoder(c, buf+1, buf_size-1); + ret = ff_vp56_init_range_decoder(c, buf+1, buf_size-1); + if (ret < 0) + return ret; s->golden_frame = vp56_rac_get(c); if (s->filter_header) { @@ -165,7 +170,9 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size) s->parse_coeff = vp6_parse_coeff_huffman; init_get_bits(&s->gb, buf, buf_size<<3); } else { - ff_vp56_init_range_decoder(&s->cc, buf, buf_size); + ret = ff_vp56_init_range_decoder(&s->cc, buf, buf_size); + if (ret < 0) + return ret; s->ccp = &s->cc; } } else { diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index fb17ff114d275..a3d057d62e529 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -261,6 +261,7 @@ static int setup_partitions(VP8Context *s, const uint8_t *buf, int buf_size) { const uint8_t *sizes = buf; int i; + int ret; s->num_coeff_partitions = 1 << vp8_rac_get_uint(&s->c, 2); @@ -274,13 +275,13 @@ static int setup_partitions(VP8Context *s, const uint8_t *buf, int buf_size) if (buf_size - size < 0) return -1; - ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, size); + ret = ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, size); + if (ret < 0) + return ret; buf += size; buf_size -= size; } - ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, buf_size); - - return 0; + return ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, buf_size); } static void vp7_get_quants(VP8Context *s) @@ -518,7 +519,9 @@ static int vp7_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si memcpy(s->put_pixels_tab, s->vp8dsp.put_vp8_epel_pixels_tab, sizeof(s->put_pixels_tab)); - ff_vp56_init_range_decoder(c, buf, part1_size); + ret = ff_vp56_init_range_decoder(c, buf, part1_size); + if (ret < 0) + return ret; buf += part1_size; buf_size -= part1_size; @@ -570,7 +573,9 @@ static int vp7_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si s->lf_delta.enabled = 0; s->num_coeff_partitions = 1; - ff_vp56_init_range_decoder(&s->coeff_partition[0], buf, buf_size); + ret = ff_vp56_init_range_decoder(&s->coeff_partition[0], buf, buf_size); + if (ret < 0) + return ret; if (!s->macroblocks_base || /* first frame */ width != s->avctx->width || height != s->avctx->height || @@ -699,7 +704,9 @@ static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si memset(&s->lf_delta, 0, sizeof(s->lf_delta)); } - ff_vp56_init_range_decoder(c, buf, header_size); + ret = ff_vp56_init_range_decoder(c, buf, header_size); + if (ret < 0) + return ret; buf += header_size; buf_size -= header_size; diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 09365f833ab61..a41f3a3961523 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -852,7 +852,10 @@ static int decode_frame_header(AVCodecContext *ctx, av_log(ctx, AV_LOG_ERROR, "Invalid compressed header size\n"); return AVERROR_INVALIDDATA; } - ff_vp56_init_range_decoder(&s->c, data2, size2); + res = ff_vp56_init_range_decoder(&s->c, data2, size2); + if (res < 0) + return res; + if (vp56_rac_get_prob_branchy(&s->c, 128)) { // marker bit av_log(ctx, AV_LOG_ERROR, "Marker bit was set\n"); return AVERROR_INVALIDDATA; @@ -4153,7 +4156,9 @@ FF_ENABLE_DEPRECATION_WARNINGS ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); return AVERROR_INVALIDDATA; } - ff_vp56_init_range_decoder(&s->c_b[tile_col], data, tile_size); + res = ff_vp56_init_range_decoder(&s->c_b[tile_col], data, tile_size); + if (res < 0) + return res; if (vp56_rac_get_prob_branchy(&s->c_b[tile_col], 128)) { // marker bit ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); return AVERROR_INVALIDDATA; From 1afd246960202917e244c844c534e9c1e3c323f5 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 7 Mar 2017 19:09:39 +0100 Subject: [PATCH 1046/3374] avcodec/vp8: Check for the bitstream end per MB in decode_mb_row_no_filter() Fixes: timeout in 730/clusterfuzz-testcase-5265113739165696 (part 2 of 2) Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Reviewed-by: BBB Signed-off-by: Michael Niedermayer --- libavcodec/vp8.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index a3d057d62e529..6759b310f01aa 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -2330,6 +2330,8 @@ static av_always_inline int decode_mb_row_no_filter(AVCodecContext *avctx, void s->mv_max.x = ((s->mb_width - 1) << 6) + MARGIN; for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) { + if (c->end <= c->buffer && c->bits >= 0) + return AVERROR_INVALIDDATA; // Wait for previous thread to read mb_x+2, and reach mb_y-1. if (prev_td != td) { if (threadnr != 0) { From ac8c72f8f1f758ae7606db42eac83d04418aec48 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Tue, 7 Mar 2017 17:29:52 -0500 Subject: [PATCH 1047/3374] mov: Fix checking layout and loading padding for cubemaps --- libavformat/mov.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index cc098cd97787e..d5c3949050223 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -4635,7 +4635,7 @@ static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; MOVStreamContext *sc; - int size; + int size, layout; int32_t yaw, pitch, roll; size_t l = 0, t = 0, r = 0, b = 0; size_t padding = 0; @@ -4699,6 +4699,12 @@ static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom) avio_skip(pb, 4); /* version + flags */ switch (tag) { case MKTAG('c','b','m','p'): + layout = avio_rb32(pb); + if (layout) { + av_log(c->fc, AV_LOG_WARNING, + "Unsupported cubemap layout %d\n", layout); + return 0; + } projection = AV_SPHERICAL_CUBEMAP; padding = avio_rb32(pb); break; From 9ae3506696badc226a4e73a35009de17aeee14ce Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Tue, 7 Mar 2017 17:34:32 -0500 Subject: [PATCH 1048/3374] matroskadec: cosmetics: Rearrange checks for projection-depedendent properties --- libavformat/matroskadec.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index fdc3f268aa618..fdb23ab05e8b2 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -1930,9 +1930,7 @@ static int mkv_parse_video_projection(AVStream *st, const MatroskaTrack *track) switch (track->video.projection.type) { case MATROSKA_VIDEO_PROJECTION_TYPE_EQUIRECTANGULAR: - if (track->video.projection.private.size == 0) - projection = AV_SPHERICAL_EQUIRECTANGULAR; - else if (track->video.projection.private.size == 20) { + if (track->video.projection.private.size == 20) { t = bytestream2_get_be32(&gb); b = bytestream2_get_be32(&gb); l = bytestream2_get_be32(&gb); @@ -1946,15 +1944,15 @@ static int mkv_parse_video_projection(AVStream *st, const MatroskaTrack *track) l, t, r, b); return AVERROR_INVALIDDATA; } - - if (l || t || r || b) - projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE; - else - projection = AV_SPHERICAL_EQUIRECTANGULAR; - } else { + } else if (track->video.projection.private.size != 0) { av_log(NULL, AV_LOG_ERROR, "Unknown spherical metadata\n"); return AVERROR_INVALIDDATA; } + + if (l || t || r || b) + projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE; + else + projection = AV_SPHERICAL_EQUIRECTANGULAR; break; case MATROSKA_VIDEO_PROJECTION_TYPE_CUBEMAP: if (track->video.projection.private.size < 4) { @@ -1962,13 +1960,12 @@ static int mkv_parse_video_projection(AVStream *st, const MatroskaTrack *track) return AVERROR_INVALIDDATA; } else if (track->video.projection.private.size == 12) { uint32_t layout = bytestream2_get_be32(&gb); - if (layout == 0) { - projection = AV_SPHERICAL_CUBEMAP; - } else { + if (layout) { av_log(NULL, AV_LOG_WARNING, "Unknown spherical cubemap layout %"PRIu32"\n", layout); return 0; } + projection = AV_SPHERICAL_CUBEMAP; padding = bytestream2_get_be32(&gb); } else { av_log(NULL, AV_LOG_ERROR, "Unknown spherical metadata\n"); From 587226ad45948dfd360c4c2cb14341f1dfdfe351 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Wed, 8 Mar 2017 00:25:33 +0100 Subject: [PATCH 1049/3374] lavc/libx265: Add gray10 and gray12 encoding support. --- libavcodec/libx265.c | 5 +++++ libavcodec/version.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c index f9b287eb6609b..784b51c52d40e 100644 --- a/libavcodec/libx265.c +++ b/libavcodec/libx265.c @@ -167,6 +167,8 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) ctx->params->internalCsp = X265_CSP_I444; break; case AV_PIX_FMT_GRAY8: + case AV_PIX_FMT_GRAY10: + case AV_PIX_FMT_GRAY12: if (ctx->api->api_build_number < 85) { av_log(avctx, AV_LOG_ERROR, "libx265 version is %d, must be at least 85 for gray encoding.\n", @@ -350,6 +352,7 @@ static const enum AVPixelFormat x265_csp_ten[] = { AV_PIX_FMT_YUV444P10, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GRAY8, + AV_PIX_FMT_GRAY10, AV_PIX_FMT_NONE }; @@ -367,6 +370,8 @@ static const enum AVPixelFormat x265_csp_twelve[] = { AV_PIX_FMT_YUV444P12, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GRAY8, + AV_PIX_FMT_GRAY10, + AV_PIX_FMT_GRAY12, AV_PIX_FMT_NONE }; diff --git a/libavcodec/version.h b/libavcodec/version.h index cd9ed87225f1d..b00e011959ecb 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 82 -#define LIBAVCODEC_VERSION_MICRO 101 +#define LIBAVCODEC_VERSION_MICRO 102 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From a9c20598b505ac2314843cc0855fdd3e6460322c Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Tue, 7 Mar 2017 09:28:00 +0100 Subject: [PATCH 1050/3374] lsws/input: Do not define unused functions. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes warnings like the following: libswscale/input.c:951:13: warning: ‘planar_rgb14be_to_a’ defined but not used --- libswscale/input.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/libswscale/input.c b/libswscale/input.c index 8b5f348168c67..f32f896f35bae 100644 --- a/libswscale/input.c +++ b/libswscale/input.c @@ -948,17 +948,24 @@ static void planar_rgb##nbits##endian_name##_to_y(uint8_t *dst, const uint8_t *s { \ planar_rgb16_to_y(dst, src, w, nbits, endian, rgb2yuv); \ } \ -static void planar_rgb##nbits##endian_name##_to_a(uint8_t *dst, const uint8_t *src[4], \ - int w, int32_t *rgb2yuv) \ -{ \ - planar_rgb16_to_a(dst, src, w, nbits, endian, rgb2yuv); \ -} \ static void planar_rgb##nbits##endian_name##_to_uv(uint8_t *dstU, uint8_t *dstV, \ const uint8_t *src[4], int w, int32_t *rgb2yuv) \ { \ planar_rgb16_to_uv(dstU, dstV, src, w, nbits, endian, rgb2yuv); \ } \ +#define rgb9plus_planar_transparency_funcs(nbits) \ +static void planar_rgb##nbits##le_to_a(uint8_t *dst, const uint8_t *src[4], \ + int w, int32_t *rgb2yuv) \ +{ \ + planar_rgb16_to_a(dst, src, w, nbits, 0, rgb2yuv); \ +} \ +static void planar_rgb##nbits##be_to_a(uint8_t *dst, const uint8_t *src[4], \ + int w, int32_t *rgb2yuv) \ +{ \ + planar_rgb16_to_a(dst, src, w, nbits, 1, rgb2yuv); \ +} + #define rgb9plus_planar_funcs(nbits) \ rgb9plus_planar_funcs_endian(nbits, le, 0) \ rgb9plus_planar_funcs_endian(nbits, be, 1) @@ -969,6 +976,10 @@ rgb9plus_planar_funcs(12) rgb9plus_planar_funcs(14) rgb9plus_planar_funcs(16) +rgb9plus_planar_transparency_funcs(10) +rgb9plus_planar_transparency_funcs(12) +rgb9plus_planar_transparency_funcs(16) + av_cold void ff_sws_init_input_funcs(SwsContext *c) { enum AVPixelFormat srcFormat = c->srcFormat; From 851f4255e0e2001f73c393db48b3eb3bd2a8b96e Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Sun, 26 Feb 2017 11:18:25 +0100 Subject: [PATCH 1051/3374] lsws/slice: Move a misplaced const. Fixes a gcc warning: libswscale/slice.c:178:56: warning: assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers] --- libswscale/slice.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libswscale/slice.c b/libswscale/slice.c index e14456f75f3ef..db4fa874ffccc 100644 --- a/libswscale/slice.c +++ b/libswscale/slice.c @@ -158,7 +158,7 @@ int ff_init_slice_from_src(SwsSlice * s, uint8_t *src[4], int stride[4], int src chrY + chrH, lumY + lumH}; - const uint8_t *src_[4] = {src[0] + (relative ? 0 : start[0]) * stride[0], + uint8_t *const src_[4] = {src[0] + (relative ? 0 : start[0]) * stride[0], src[1] + (relative ? 0 : start[1]) * stride[1], src[2] + (relative ? 0 : start[2]) * stride[2], src[3] + (relative ? 0 : start[3]) * stride[3]}; From dbc932e745fe4dc9ffbe48d0332a95cbbaa2b228 Mon Sep 17 00:00:00 2001 From: James Almer Date: Tue, 7 Mar 2017 00:23:07 -0300 Subject: [PATCH 1052/3374] Revert "lavu/atomic: add support for the new memory model aware gcc built-ins" This reverts commit faa9d2982969c999ab0e443a226eff116f7f8e4b. This change became superfluous when support for C11 atomics was introduced. Reverting it will make the removal of this implementation in an upcoming merge conflict free. Reviewed-by: wm4 Signed-off-by: James Almer --- configure | 4 +--- libavutil/atomic_gcc.h | 17 ----------------- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/configure b/configure index 0199fec5c0ab9..6350942ef979a 100755 --- a/configure +++ b/configure @@ -1821,7 +1821,6 @@ ARCH_FEATURES=" BUILTIN_LIST=" atomic_cas_ptr - atomic_compare_exchange machine_rw_barrier MemoryBarrier mm_empty @@ -2322,7 +2321,7 @@ symver_if_any="symver_asm_label symver_gnu_asm" valgrind_backtrace_deps="!optimizations valgrind_valgrind_h" # threading support -atomics_gcc_if_any="sync_val_compare_and_swap atomic_compare_exchange" +atomics_gcc_if="sync_val_compare_and_swap" atomics_suncc_if="atomic_cas_ptr machine_rw_barrier" atomics_win32_if="MemoryBarrier" atomics_native_if_any="$ATOMICS_LIST" @@ -5533,7 +5532,6 @@ if ! disabled network; then fi check_builtin atomic_cas_ptr atomic.h "void **ptr; void *oldval, *newval; atomic_cas_ptr(ptr, oldval, newval)" -check_builtin atomic_compare_exchange "" "int *ptr, *oldval; int newval; __atomic_compare_exchange_n(ptr, oldval, newval, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)" check_builtin machine_rw_barrier mbarrier.h "__machine_rw_barrier()" check_builtin MemoryBarrier windows.h "MemoryBarrier()" check_builtin sarestart signal.h "SA_RESTART" diff --git a/libavutil/atomic_gcc.h b/libavutil/atomic_gcc.h index 5f9fc49ba0849..2bb43c3cea0e8 100644 --- a/libavutil/atomic_gcc.h +++ b/libavutil/atomic_gcc.h @@ -28,40 +28,27 @@ #define avpriv_atomic_int_get atomic_int_get_gcc static inline int atomic_int_get_gcc(volatile int *ptr) { -#if HAVE_ATOMIC_COMPARE_EXCHANGE - return __atomic_load_n(ptr, __ATOMIC_SEQ_CST); -#else __sync_synchronize(); return *ptr; -#endif } #define avpriv_atomic_int_set atomic_int_set_gcc static inline void atomic_int_set_gcc(volatile int *ptr, int val) { -#if HAVE_ATOMIC_COMPARE_EXCHANGE - __atomic_store_n(ptr, val, __ATOMIC_SEQ_CST); -#else *ptr = val; __sync_synchronize(); -#endif } #define avpriv_atomic_int_add_and_fetch atomic_int_add_and_fetch_gcc static inline int atomic_int_add_and_fetch_gcc(volatile int *ptr, int inc) { -#if HAVE_ATOMIC_COMPARE_EXCHANGE - return __atomic_add_fetch(ptr, inc, __ATOMIC_SEQ_CST); -#else return __sync_add_and_fetch(ptr, inc); -#endif } #define avpriv_atomic_ptr_cas atomic_ptr_cas_gcc static inline void *atomic_ptr_cas_gcc(void * volatile *ptr, void *oldval, void *newval) { -#if HAVE_SYNC_VAL_COMPARE_AND_SWAP #ifdef __ARMCC_VERSION // armcc will throw an error if ptr is not an integer type volatile uintptr_t *tmp = (volatile uintptr_t*)ptr; @@ -69,10 +56,6 @@ static inline void *atomic_ptr_cas_gcc(void * volatile *ptr, #else return __sync_val_compare_and_swap(ptr, oldval, newval); #endif -#else - __atomic_compare_exchange_n(ptr, &oldval, newval, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); - return oldval; -#endif } #endif /* AVUTIL_ATOMIC_GCC_H */ From 61926b6c3e560283ef6c015d6d85c32716942833 Mon Sep 17 00:00:00 2001 From: Muhammad Faiz Date: Wed, 1 Mar 2017 22:18:36 +0700 Subject: [PATCH 1053/3374] swresample/resample: use uniform normalization this gives better frequency response update swresample fate and other fates that depend on resampling Signed-off-by: Muhammad Faiz --- libswresample/resample.c | 14 +- tests/fate/libswresample.mak | 276 +++++++++++++++++------------------ tests/ref/acodec/roqaudio | 2 +- tests/ref/acodec/s302m | 6 +- tests/ref/lavf/dv_fmt | 8 +- tests/ref/lavf/gxf | 8 +- tests/ref/lavf/mxf | 12 +- 7 files changed, 163 insertions(+), 163 deletions(-) diff --git a/libswresample/resample.c b/libswresample/resample.c index 8e2f76901a33a..b0d14d1e95676 100644 --- a/libswresample/resample.c +++ b/libswresample/resample.c @@ -149,6 +149,7 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap double *tab = av_malloc_array(tap_count+1, sizeof(*tab)); double *sin_lut = av_malloc_array(ph_nb, sizeof(*sin_lut)); const int center= (tap_count-1)/2; + double norm = 0; int ret = AVERROR(ENOMEM); if (!tab || !sin_lut) @@ -160,10 +161,9 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap if (factor == 1.0) { for (ph = 0; ph < ph_nb; ph++) - sin_lut[ph] = sin(M_PI * ph / phase_count); + sin_lut[ph] = sin(M_PI * ph / phase_count) * (center & 1 ? 1 : -1); } for(ph = 0; ph < ph_nb; ph++) { - double norm = 0; s = sin_lut[ph]; for(i=0;i<=tap_count;i++) { x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor; @@ -194,7 +194,7 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap tab[i] = y; s = -s; - if (i < tap_count) + if (!ph && i < tap_count) norm += y; } @@ -211,7 +211,7 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap else { for (i = 1; i <= tap_count; i++) ((int16_t*)filter)[(phase_count-ph) * alloc + tap_count-i] = - av_clip_int16(lrintf(tab[i] * scale / (norm - tab[0] + tab[tap_count]))); + av_clip_int16(lrintf(tab[i] * scale / norm)); } break; case AV_SAMPLE_FMT_S32P: @@ -225,7 +225,7 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap else { for (i = 1; i <= tap_count; i++) ((int32_t*)filter)[(phase_count-ph) * alloc + tap_count-i] = - av_clipl_int32(llrint(tab[i] * scale / (norm - tab[0] + tab[tap_count]))); + av_clipl_int32(llrint(tab[i] * scale / norm)); } break; case AV_SAMPLE_FMT_FLTP: @@ -238,7 +238,7 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap } else { for (i = 1; i <= tap_count; i++) - ((float*)filter)[(phase_count-ph) * alloc + tap_count-i] = tab[i] * scale / (norm - tab[0] + tab[tap_count]); + ((float*)filter)[(phase_count-ph) * alloc + tap_count-i] = tab[i] * scale / norm; } break; case AV_SAMPLE_FMT_DBLP: @@ -251,7 +251,7 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap } else { for (i = 1; i <= tap_count; i++) - ((double*)filter)[(phase_count-ph) * alloc + tap_count-i] = tab[i] * scale / (norm - tab[0] + tab[tap_count]); + ((double*)filter)[(phase_count-ph) * alloc + tap_count-i] = tab[i] * scale / norm; } break; } diff --git a/tests/fate/libswresample.mak b/tests/fate/libswresample.mak index cc50693410bb3..f2967cdd2b9be 100644 --- a/tests/fate/libswresample.mak +++ b/tests/fate/libswresample.mak @@ -26,34 +26,34 @@ endef #you can use this if you need to update it! #make -k `make fate-list | grep swr` | egrep 'TEST|stddev' | tr '\n' '@' | sed 's#TEST *\([^@]*\)@stddev: *\([0-9.]*\)[^b@]*bytes: *\([0-9]*\) */ *\([0-9]*\)@#fate-\1: CMP_TARGET = \2@fate-\1: SIZE_TOLERANCE = \3 - \4@@#g' | tr '@' '\n' -fate-swr-resample-dblp-2626-44100: CMP_TARGET = 1352.68 +fate-swr-resample-dblp-2626-44100: CMP_TARGET = 1352.69 fate-swr-resample-dblp-2626-44100: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample-dblp-2626-48000: CMP_TARGET = 1352.65 +fate-swr-resample-dblp-2626-48000: CMP_TARGET = 1352.66 fate-swr-resample-dblp-2626-48000: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample-dblp-2626-8000: CMP_TARGET = 1353.08 +fate-swr-resample-dblp-2626-8000: CMP_TARGET = 1353.09 fate-swr-resample-dblp-2626-8000: SIZE_TOLERANCE = 31512 - 20482 -fate-swr-resample-dblp-2626-96000: CMP_TARGET = 1352.67 +fate-swr-resample-dblp-2626-96000: CMP_TARGET = 1352.68 fate-swr-resample-dblp-2626-96000: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample-dblp-44100-2626: CMP_TARGET = 185.82 fate-swr-resample-dblp-44100-2626: SIZE_TOLERANCE = 529200 - 20490 -fate-swr-resample-dblp-44100-48000: CMP_TARGET = 9.70 +fate-swr-resample-dblp-44100-48000: CMP_TARGET = 9.69 fate-swr-resample-dblp-44100-48000: SIZE_TOLERANCE = 529200 - 20482 fate-swr-resample-dblp-44100-8000: CMP_TARGET = 75.45 fate-swr-resample-dblp-44100-8000: SIZE_TOLERANCE = 529200 - 20486 -fate-swr-resample-dblp-44100-96000: CMP_TARGET = 11.47 +fate-swr-resample-dblp-44100-96000: CMP_TARGET = 11.46 fate-swr-resample-dblp-44100-96000: SIZE_TOLERANCE = 529200 - 20482 fate-swr-resample-dblp-48000-2626: CMP_TARGET = 456.51 fate-swr-resample-dblp-48000-2626: SIZE_TOLERANCE = 576000 - 20510 -fate-swr-resample-dblp-48000-44100: CMP_TARGET = 1.02 +fate-swr-resample-dblp-48000-44100: CMP_TARGET = 1.00 fate-swr-resample-dblp-48000-44100: SIZE_TOLERANCE = 576000 - 20480 fate-swr-resample-dblp-48000-8000: CMP_TARGET = 62.38 @@ -77,43 +77,43 @@ fate-swr-resample-dblp-8000-96000: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample-dblp-96000-2626: CMP_TARGET = 675.08 fate-swr-resample-dblp-96000-2626: SIZE_TOLERANCE = 1152000 - 20474 -fate-swr-resample-dblp-96000-44100: CMP_TARGET = 1.45 +fate-swr-resample-dblp-96000-44100: CMP_TARGET = 1.44 fate-swr-resample-dblp-96000-44100: SIZE_TOLERANCE = 1152000 - 20480 -fate-swr-resample-dblp-96000-48000: CMP_TARGET = 1.00 +fate-swr-resample-dblp-96000-48000: CMP_TARGET = 0.99 fate-swr-resample-dblp-96000-48000: SIZE_TOLERANCE = 1152000 - 20480 fate-swr-resample-dblp-96000-8000: CMP_TARGET = 58.57 fate-swr-resample-dblp-96000-8000: SIZE_TOLERANCE = 1152000 - 20496 -fate-swr-resample-fltp-2626-44100: CMP_TARGET = 1352.68 +fate-swr-resample-fltp-2626-44100: CMP_TARGET = 1352.69 fate-swr-resample-fltp-2626-44100: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample-fltp-2626-48000: CMP_TARGET = 1352.65 +fate-swr-resample-fltp-2626-48000: CMP_TARGET = 1352.66 fate-swr-resample-fltp-2626-48000: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample-fltp-2626-8000: CMP_TARGET = 1353.08 +fate-swr-resample-fltp-2626-8000: CMP_TARGET = 1353.09 fate-swr-resample-fltp-2626-8000: SIZE_TOLERANCE = 31512 - 20482 -fate-swr-resample-fltp-2626-96000: CMP_TARGET = 1352.67 +fate-swr-resample-fltp-2626-96000: CMP_TARGET = 1352.68 fate-swr-resample-fltp-2626-96000: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample-fltp-44100-2626: CMP_TARGET = 185.82 fate-swr-resample-fltp-44100-2626: SIZE_TOLERANCE = 529200 - 20490 -fate-swr-resample-fltp-44100-48000: CMP_TARGET = 9.70 +fate-swr-resample-fltp-44100-48000: CMP_TARGET = 9.69 fate-swr-resample-fltp-44100-48000: SIZE_TOLERANCE = 529200 - 20482 fate-swr-resample-fltp-44100-8000: CMP_TARGET = 75.45 fate-swr-resample-fltp-44100-8000: SIZE_TOLERANCE = 529200 - 20486 -fate-swr-resample-fltp-44100-96000: CMP_TARGET = 11.47 +fate-swr-resample-fltp-44100-96000: CMP_TARGET = 11.46 fate-swr-resample-fltp-44100-96000: SIZE_TOLERANCE = 529200 - 20482 fate-swr-resample-fltp-48000-2626: CMP_TARGET = 456.51 fate-swr-resample-fltp-48000-2626: SIZE_TOLERANCE = 576000 - 20510 -fate-swr-resample-fltp-48000-44100: CMP_TARGET = 1.02 +fate-swr-resample-fltp-48000-44100: CMP_TARGET = 1.00 fate-swr-resample-fltp-48000-44100: SIZE_TOLERANCE = 576000 - 20480 fate-swr-resample-fltp-48000-8000: CMP_TARGET = 62.38 @@ -137,25 +137,25 @@ fate-swr-resample-fltp-8000-96000: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample-fltp-96000-2626: CMP_TARGET = 675.08 fate-swr-resample-fltp-96000-2626: SIZE_TOLERANCE = 1152000 - 20474 -fate-swr-resample-fltp-96000-44100: CMP_TARGET = 1.45 +fate-swr-resample-fltp-96000-44100: CMP_TARGET = 1.44 fate-swr-resample-fltp-96000-44100: SIZE_TOLERANCE = 1152000 - 20480 -fate-swr-resample-fltp-96000-48000: CMP_TARGET = 1.00 +fate-swr-resample-fltp-96000-48000: CMP_TARGET = 0.99 fate-swr-resample-fltp-96000-48000: SIZE_TOLERANCE = 1152000 - 20480 fate-swr-resample-fltp-96000-8000: CMP_TARGET = 58.57 fate-swr-resample-fltp-96000-8000: SIZE_TOLERANCE = 1152000 - 20496 -fate-swr-resample-s16p-2626-44100: CMP_TARGET = 1393.01 +fate-swr-resample-s16p-2626-44100: CMP_TARGET = 1393.02 fate-swr-resample-s16p-2626-44100: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample-s16p-2626-48000: CMP_TARGET = 1392.99 +fate-swr-resample-s16p-2626-48000: CMP_TARGET = 1393.01 fate-swr-resample-s16p-2626-48000: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample-s16p-2626-8000: CMP_TARGET = 1393.90 +fate-swr-resample-s16p-2626-8000: CMP_TARGET = 1393.91 fate-swr-resample-s16p-2626-8000: SIZE_TOLERANCE = 31512 - 20482 -fate-swr-resample-s16p-2626-96000: CMP_TARGET = 1393.08 +fate-swr-resample-s16p-2626-96000: CMP_TARGET = 1393.09 fate-swr-resample-s16p-2626-96000: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample-s16p-44100-2626: CMP_TARGET = 185.84 @@ -173,19 +173,19 @@ fate-swr-resample-s16p-44100-96000: SIZE_TOLERANCE = 529200 - 20482 fate-swr-resample-s16p-48000-2626: CMP_TARGET = 456.55 fate-swr-resample-s16p-48000-2626: SIZE_TOLERANCE = 576000 - 20510 -fate-swr-resample-s16p-48000-44100: CMP_TARGET = 1.22 +fate-swr-resample-s16p-48000-44100: CMP_TARGET = 1.20 fate-swr-resample-s16p-48000-44100: SIZE_TOLERANCE = 576000 - 20480 fate-swr-resample-s16p-48000-8000: CMP_TARGET = 62.41 fate-swr-resample-s16p-48000-8000: SIZE_TOLERANCE = 576000 - 20484 -fate-swr-resample-s16p-48000-96000: CMP_TARGET = 0.50 +fate-swr-resample-s16p-48000-96000: CMP_TARGET = 0.73 fate-swr-resample-s16p-48000-96000: SIZE_TOLERANCE = 576000 - 20480 fate-swr-resample-s16p-8000-2626: CMP_TARGET = 2506.02 fate-swr-resample-s16p-8000-2626: SIZE_TOLERANCE = 96000 - 20486 -fate-swr-resample-s16p-8000-44100: CMP_TARGET = 15.12 +fate-swr-resample-s16p-8000-44100: CMP_TARGET = 15.13 fate-swr-resample-s16p-8000-44100: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample-s16p-8000-48000: CMP_TARGET = 14.69 @@ -194,46 +194,46 @@ fate-swr-resample-s16p-8000-48000: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample-s16p-8000-96000: CMP_TARGET = 13.83 fate-swr-resample-s16p-8000-96000: SIZE_TOLERANCE = 96000 - 20480 -fate-swr-resample-s16p-96000-2626: CMP_TARGET = 675.14 +fate-swr-resample-s16p-96000-2626: CMP_TARGET = 675.15 fate-swr-resample-s16p-96000-2626: SIZE_TOLERANCE = 1152000 - 20474 fate-swr-resample-s16p-96000-44100: CMP_TARGET = 1.62 fate-swr-resample-s16p-96000-44100: SIZE_TOLERANCE = 1152000 - 20480 -fate-swr-resample-s16p-96000-48000: CMP_TARGET = 1.03 +fate-swr-resample-s16p-96000-48000: CMP_TARGET = 1.12 fate-swr-resample-s16p-96000-48000: SIZE_TOLERANCE = 1152000 - 20480 fate-swr-resample-s16p-96000-8000: CMP_TARGET = 58.60 fate-swr-resample-s16p-96000-8000: SIZE_TOLERANCE = 1152000 - 20496 -fate-swr-resample-s32p-2626-44100: CMP_TARGET = 1393.01 +fate-swr-resample-s32p-2626-44100: CMP_TARGET = 1393.02 fate-swr-resample-s32p-2626-44100: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample-s32p-2626-48000: CMP_TARGET = 1392.99 +fate-swr-resample-s32p-2626-48000: CMP_TARGET = 1393.01 fate-swr-resample-s32p-2626-48000: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample-s32p-2626-8000: CMP_TARGET = 1393.89 +fate-swr-resample-s32p-2626-8000: CMP_TARGET = 1393.90 fate-swr-resample-s32p-2626-8000: SIZE_TOLERANCE = 31512 - 20482 -fate-swr-resample-s32p-2626-96000: CMP_TARGET = 1393.00 +fate-swr-resample-s32p-2626-96000: CMP_TARGET = 1393.01 fate-swr-resample-s32p-2626-96000: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample-s32p-44100-2626: CMP_TARGET = 185.82 fate-swr-resample-s32p-44100-2626: SIZE_TOLERANCE = 529200 - 20490 -fate-swr-resample-s32p-44100-48000: CMP_TARGET = 9.70 +fate-swr-resample-s32p-44100-48000: CMP_TARGET = 9.69 fate-swr-resample-s32p-44100-48000: SIZE_TOLERANCE = 529200 - 20482 fate-swr-resample-s32p-44100-8000: CMP_TARGET = 75.45 fate-swr-resample-s32p-44100-8000: SIZE_TOLERANCE = 529200 - 20486 -fate-swr-resample-s32p-44100-96000: CMP_TARGET = 11.47 +fate-swr-resample-s32p-44100-96000: CMP_TARGET = 11.46 fate-swr-resample-s32p-44100-96000: SIZE_TOLERANCE = 529200 - 20482 fate-swr-resample-s32p-48000-2626: CMP_TARGET = 456.51 fate-swr-resample-s32p-48000-2626: SIZE_TOLERANCE = 576000 - 20510 -fate-swr-resample-s32p-48000-44100: CMP_TARGET = 1.02 +fate-swr-resample-s32p-48000-44100: CMP_TARGET = 1.00 fate-swr-resample-s32p-48000-44100: SIZE_TOLERANCE = 576000 - 20480 fate-swr-resample-s32p-48000-8000: CMP_TARGET = 62.38 @@ -257,10 +257,10 @@ fate-swr-resample-s32p-8000-96000: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample-s32p-96000-2626: CMP_TARGET = 675.08 fate-swr-resample-s32p-96000-2626: SIZE_TOLERANCE = 1152000 - 20474 -fate-swr-resample-s32p-96000-44100: CMP_TARGET = 1.45 +fate-swr-resample-s32p-96000-44100: CMP_TARGET = 1.44 fate-swr-resample-s32p-96000-44100: SIZE_TOLERANCE = 1152000 - 20480 -fate-swr-resample-s32p-96000-48000: CMP_TARGET = 1.00 +fate-swr-resample-s32p-96000-48000: CMP_TARGET = 0.99 fate-swr-resample-s32p-96000-48000: SIZE_TOLERANCE = 1152000 - 20480 fate-swr-resample-s32p-96000-8000: CMP_TARGET = 58.57 @@ -290,10 +290,10 @@ fate-swr-resample_lin-s16p-44100-8000: SIZE_TOLERANCE = 529200 - 20486 fate-swr-resample_lin-s16p-44100-48000: CMP_TARGET = 9.66 fate-swr-resample_lin-s16p-44100-48000: SIZE_TOLERANCE = 529200 - 20482 -fate-swr-resample_lin-s16p-48000-8000: CMP_TARGET = 62.39 +fate-swr-resample_lin-s16p-48000-8000: CMP_TARGET = 62.38 fate-swr-resample_lin-s16p-48000-8000: SIZE_TOLERANCE = 576000 - 20484 -fate-swr-resample_lin-s16p-48000-44100: CMP_TARGET = 0.68 +fate-swr-resample_lin-s16p-48000-44100: CMP_TARGET = 0.65 fate-swr-resample_lin-s16p-48000-44100: SIZE_TOLERANCE = 576000 - 20480 fate-swr-resample_lin-fltp-8000-44100: CMP_TARGET = 14.59 @@ -305,13 +305,13 @@ fate-swr-resample_lin-fltp-8000-48000: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample_lin-fltp-44100-8000: CMP_TARGET = 75.38 fate-swr-resample_lin-fltp-44100-8000: SIZE_TOLERANCE = 529200 - 20486 -fate-swr-resample_lin-fltp-44100-48000: CMP_TARGET = 9.65 +fate-swr-resample_lin-fltp-44100-48000: CMP_TARGET = 9.64 fate-swr-resample_lin-fltp-44100-48000: SIZE_TOLERANCE = 529200 - 20482 fate-swr-resample_lin-fltp-48000-8000: CMP_TARGET = 62.36 fate-swr-resample_lin-fltp-48000-8000: SIZE_TOLERANCE = 576000 - 20484 -fate-swr-resample_lin-fltp-48000-44100: CMP_TARGET = 0.26 +fate-swr-resample_lin-fltp-48000-44100: CMP_TARGET = 0.23 fate-swr-resample_lin-fltp-48000-44100: SIZE_TOLERANCE = 576000 - 20480 fate-swr-resample_lin-dblp-8000-44100: CMP_TARGET = 14.59 @@ -323,13 +323,13 @@ fate-swr-resample_lin-dblp-8000-48000: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample_lin-dblp-44100-8000: CMP_TARGET = 75.38 fate-swr-resample_lin-dblp-44100-8000: SIZE_TOLERANCE = 529200 - 20486 -fate-swr-resample_lin-dblp-44100-48000: CMP_TARGET = 9.65 +fate-swr-resample_lin-dblp-44100-48000: CMP_TARGET = 9.64 fate-swr-resample_lin-dblp-44100-48000: SIZE_TOLERANCE = 529200 - 20482 fate-swr-resample_lin-dblp-48000-8000: CMP_TARGET = 62.36 fate-swr-resample_lin-dblp-48000-8000: SIZE_TOLERANCE = 576000 - 20484 -fate-swr-resample_lin-dblp-48000-44100: CMP_TARGET = 0.26 +fate-swr-resample_lin-dblp-48000-44100: CMP_TARGET = 0.23 fate-swr-resample_lin-dblp-48000-44100: SIZE_TOLERANCE = 576000 - 20480 define ARESAMPLE_NN @@ -343,13 +343,13 @@ fate-swr-resample_nn-$(3)-$(1)-$(2): FUZZ = 0.1 fate-swr-resample_nn-$(3)-$(1)-$(2): REF = tests/data/asynth-$(1)-1.wav endef -fate-swr-resample_nn-fltp-44100-8000: CMP_TARGET = 590.98 +fate-swr-resample_nn-fltp-44100-8000: CMP_TARGET = 591.03 fate-swr-resample_nn-fltp-44100-8000: SIZE_TOLERANCE = 529200 - 20486 fate-swr-resample_nn-fltp-8000-44100: CMP_TARGET = 3163.32 fate-swr-resample_nn-fltp-8000-44100: SIZE_TOLERANCE = 96000 - 20480 -fate-swr-resample_nn-s16p-44100-8000: CMP_TARGET = 590.97 +fate-swr-resample_nn-s16p-44100-8000: CMP_TARGET = 590.98 fate-swr-resample_nn-s16p-44100-8000: SIZE_TOLERANCE = 529200 - 20486 fate-swr-resample_nn-s16p-8000-44100: CMP_TARGET = 3163.39 @@ -362,20 +362,20 @@ fate-swr-resample_async-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/dat fate-swr-resample_async-$(3)-$(1)-$(2): CMP = stddev fate-swr-resample_async-$(3)-$(1)-$(2): CMP_UNIT = $(5) -fate-swr-resample_async-$(3)-$(1)-$(2): FUZZ = 0.1 +fate-swr-resample_async-$(3)-$(1)-$(2): FUZZ = 0.01 fate-swr-resample_async-$(3)-$(1)-$(2): REF = tests/data/asynth-$(1)-1.wav endef -fate-swr-resample_async-fltp-44100-8000: CMP_TARGET = 4020.62 +fate-swr-resample_async-fltp-44100-8000: CMP_TARGET = 4020.60 fate-swr-resample_async-fltp-44100-8000: SIZE_TOLERANCE = 529200 - 20310 -fate-swr-resample_async-fltp-8000-44100: CMP_TARGET = 11186.69 +fate-swr-resample_async-fltp-8000-44100: CMP_TARGET = 11186.66 fate-swr-resample_async-fltp-8000-44100: SIZE_TOLERANCE = 96000 - 20344 -fate-swr-resample_async-s16p-44100-8000: CMP_TARGET = 4020.73 +fate-swr-resample_async-s16p-44100-8000: CMP_TARGET = 4020.71 fate-swr-resample_async-s16p-44100-8000: SIZE_TOLERANCE = 529200 - 20310 -fate-swr-resample_async-s16p-8000-44100: CMP_TARGET = 11187.01 +fate-swr-resample_async-s16p-8000-44100: CMP_TARGET = 11186.94 fate-swr-resample_async-s16p-8000-44100: SIZE_TOLERANCE = 96000 - 20344 define ARESAMPLE_EXACT @@ -389,22 +389,22 @@ fate-swr-resample_exact-$(3)-$(1)-$(2): FUZZ = 0.1 fate-swr-resample_exact-$(3)-$(1)-$(2): REF = tests/data/asynth-$(1)-1.wav endef -fate-swr-resample_exact-dblp-2626-44100: CMP_TARGET = 1352.68 +fate-swr-resample_exact-dblp-2626-44100: CMP_TARGET = 1352.69 fate-swr-resample_exact-dblp-2626-44100: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample_exact-dblp-2626-48000: CMP_TARGET = 1352.65 +fate-swr-resample_exact-dblp-2626-48000: CMP_TARGET = 1352.66 fate-swr-resample_exact-dblp-2626-48000: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample_exact-dblp-2626-8000: CMP_TARGET = 1353.08 +fate-swr-resample_exact-dblp-2626-8000: CMP_TARGET = 1353.09 fate-swr-resample_exact-dblp-2626-8000: SIZE_TOLERANCE = 31512 - 20482 -fate-swr-resample_exact-dblp-2626-96000: CMP_TARGET = 1352.67 +fate-swr-resample_exact-dblp-2626-96000: CMP_TARGET = 1352.68 fate-swr-resample_exact-dblp-2626-96000: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample_exact-dblp-44100-2626: CMP_TARGET = 185.82 fate-swr-resample_exact-dblp-44100-2626: SIZE_TOLERANCE = 529200 - 20490 -fate-swr-resample_exact-dblp-44100-48000: CMP_TARGET = 9.65 +fate-swr-resample_exact-dblp-44100-48000: CMP_TARGET = 9.64 fate-swr-resample_exact-dblp-44100-48000: SIZE_TOLERANCE = 529200 - 20482 fate-swr-resample_exact-dblp-44100-8000: CMP_TARGET = 75.38 @@ -416,7 +416,7 @@ fate-swr-resample_exact-dblp-44100-96000: SIZE_TOLERANCE = 529200 - 20482 fate-swr-resample_exact-dblp-48000-2626: CMP_TARGET = 456.51 fate-swr-resample_exact-dblp-48000-2626: SIZE_TOLERANCE = 576000 - 20510 -fate-swr-resample_exact-dblp-48000-44100: CMP_TARGET = 0.26 +fate-swr-resample_exact-dblp-48000-44100: CMP_TARGET = 0.23 fate-swr-resample_exact-dblp-48000-44100: SIZE_TOLERANCE = 576000 - 20480 fate-swr-resample_exact-dblp-48000-8000: CMP_TARGET = 62.36 @@ -440,31 +440,31 @@ fate-swr-resample_exact-dblp-8000-96000: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample_exact-dblp-96000-2626: CMP_TARGET = 675.08 fate-swr-resample_exact-dblp-96000-2626: SIZE_TOLERANCE = 1152000 - 20474 -fate-swr-resample_exact-dblp-96000-44100: CMP_TARGET = 1.26 +fate-swr-resample_exact-dblp-96000-44100: CMP_TARGET = 1.23 fate-swr-resample_exact-dblp-96000-44100: SIZE_TOLERANCE = 1152000 - 20480 -fate-swr-resample_exact-dblp-96000-48000: CMP_TARGET = 1.00 +fate-swr-resample_exact-dblp-96000-48000: CMP_TARGET = 0.99 fate-swr-resample_exact-dblp-96000-48000: SIZE_TOLERANCE = 1152000 - 20480 fate-swr-resample_exact-dblp-96000-8000: CMP_TARGET = 58.52 fate-swr-resample_exact-dblp-96000-8000: SIZE_TOLERANCE = 1152000 - 20496 -fate-swr-resample_exact-fltp-2626-44100: CMP_TARGET = 1352.68 +fate-swr-resample_exact-fltp-2626-44100: CMP_TARGET = 1352.69 fate-swr-resample_exact-fltp-2626-44100: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample_exact-fltp-2626-48000: CMP_TARGET = 1352.65 +fate-swr-resample_exact-fltp-2626-48000: CMP_TARGET = 1352.66 fate-swr-resample_exact-fltp-2626-48000: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample_exact-fltp-2626-8000: CMP_TARGET = 1353.08 +fate-swr-resample_exact-fltp-2626-8000: CMP_TARGET = 1353.09 fate-swr-resample_exact-fltp-2626-8000: SIZE_TOLERANCE = 31512 - 20482 -fate-swr-resample_exact-fltp-2626-96000: CMP_TARGET = 1352.67 +fate-swr-resample_exact-fltp-2626-96000: CMP_TARGET = 1352.68 fate-swr-resample_exact-fltp-2626-96000: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample_exact-fltp-44100-2626: CMP_TARGET = 185.82 fate-swr-resample_exact-fltp-44100-2626: SIZE_TOLERANCE = 529200 - 20490 -fate-swr-resample_exact-fltp-44100-48000: CMP_TARGET = 9.65 +fate-swr-resample_exact-fltp-44100-48000: CMP_TARGET = 9.64 fate-swr-resample_exact-fltp-44100-48000: SIZE_TOLERANCE = 529200 - 20482 fate-swr-resample_exact-fltp-44100-8000: CMP_TARGET = 75.38 @@ -476,7 +476,7 @@ fate-swr-resample_exact-fltp-44100-96000: SIZE_TOLERANCE = 529200 - 20482 fate-swr-resample_exact-fltp-48000-2626: CMP_TARGET = 456.51 fate-swr-resample_exact-fltp-48000-2626: SIZE_TOLERANCE = 576000 - 20510 -fate-swr-resample_exact-fltp-48000-44100: CMP_TARGET = 0.26 +fate-swr-resample_exact-fltp-48000-44100: CMP_TARGET = 0.23 fate-swr-resample_exact-fltp-48000-44100: SIZE_TOLERANCE = 576000 - 20480 fate-swr-resample_exact-fltp-48000-8000: CMP_TARGET = 62.36 @@ -500,31 +500,31 @@ fate-swr-resample_exact-fltp-8000-96000: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample_exact-fltp-96000-2626: CMP_TARGET = 675.08 fate-swr-resample_exact-fltp-96000-2626: SIZE_TOLERANCE = 1152000 - 20474 -fate-swr-resample_exact-fltp-96000-44100: CMP_TARGET = 1.26 +fate-swr-resample_exact-fltp-96000-44100: CMP_TARGET = 1.23 fate-swr-resample_exact-fltp-96000-44100: SIZE_TOLERANCE = 1152000 - 20480 -fate-swr-resample_exact-fltp-96000-48000: CMP_TARGET = 1.00 +fate-swr-resample_exact-fltp-96000-48000: CMP_TARGET = 0.99 fate-swr-resample_exact-fltp-96000-48000: SIZE_TOLERANCE = 1152000 - 20480 fate-swr-resample_exact-fltp-96000-8000: CMP_TARGET = 58.52 fate-swr-resample_exact-fltp-96000-8000: SIZE_TOLERANCE = 1152000 - 20496 -fate-swr-resample_exact-s16p-2626-44100: CMP_TARGET = 1393.01 +fate-swr-resample_exact-s16p-2626-44100: CMP_TARGET = 1393.02 fate-swr-resample_exact-s16p-2626-44100: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample_exact-s16p-2626-48000: CMP_TARGET = 1392.99 +fate-swr-resample_exact-s16p-2626-48000: CMP_TARGET = 1393.01 fate-swr-resample_exact-s16p-2626-48000: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample_exact-s16p-2626-8000: CMP_TARGET = 1393.90 +fate-swr-resample_exact-s16p-2626-8000: CMP_TARGET = 1393.91 fate-swr-resample_exact-s16p-2626-8000: SIZE_TOLERANCE = 31512 - 20482 -fate-swr-resample_exact-s16p-2626-96000: CMP_TARGET = 1393.08 +fate-swr-resample_exact-s16p-2626-96000: CMP_TARGET = 1393.09 fate-swr-resample_exact-s16p-2626-96000: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample_exact-s16p-44100-2626: CMP_TARGET = 185.84 fate-swr-resample_exact-s16p-44100-2626: SIZE_TOLERANCE = 529200 - 20490 -fate-swr-resample_exact-s16p-44100-48000: CMP_TARGET = 9.67 +fate-swr-resample_exact-s16p-44100-48000: CMP_TARGET = 9.66 fate-swr-resample_exact-s16p-44100-48000: SIZE_TOLERANCE = 529200 - 20482 fate-swr-resample_exact-s16p-44100-8000: CMP_TARGET = 75.43 @@ -536,13 +536,13 @@ fate-swr-resample_exact-s16p-44100-96000: SIZE_TOLERANCE = 529200 - 20482 fate-swr-resample_exact-s16p-48000-2626: CMP_TARGET = 456.55 fate-swr-resample_exact-s16p-48000-2626: SIZE_TOLERANCE = 576000 - 20510 -fate-swr-resample_exact-s16p-48000-44100: CMP_TARGET = 0.72 +fate-swr-resample_exact-s16p-48000-44100: CMP_TARGET = 0.68 fate-swr-resample_exact-s16p-48000-44100: SIZE_TOLERANCE = 576000 - 20480 fate-swr-resample_exact-s16p-48000-8000: CMP_TARGET = 62.39 fate-swr-resample_exact-s16p-48000-8000: SIZE_TOLERANCE = 576000 - 20484 -fate-swr-resample_exact-s16p-48000-96000: CMP_TARGET = 0.50 +fate-swr-resample_exact-s16p-48000-96000: CMP_TARGET = 0.73 fate-swr-resample_exact-s16p-48000-96000: SIZE_TOLERANCE = 576000 - 20480 fate-swr-resample_exact-s16p-8000-2626: CMP_TARGET = 2506.02 @@ -557,34 +557,34 @@ fate-swr-resample_exact-s16p-8000-48000: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample_exact-s16p-8000-96000: CMP_TARGET = 13.65 fate-swr-resample_exact-s16p-8000-96000: SIZE_TOLERANCE = 96000 - 20480 -fate-swr-resample_exact-s16p-96000-2626: CMP_TARGET = 675.14 +fate-swr-resample_exact-s16p-96000-2626: CMP_TARGET = 675.15 fate-swr-resample_exact-s16p-96000-2626: SIZE_TOLERANCE = 1152000 - 20474 -fate-swr-resample_exact-s16p-96000-44100: CMP_TARGET = 1.45 +fate-swr-resample_exact-s16p-96000-44100: CMP_TARGET = 1.44 fate-swr-resample_exact-s16p-96000-44100: SIZE_TOLERANCE = 1152000 - 20480 -fate-swr-resample_exact-s16p-96000-48000: CMP_TARGET = 1.03 +fate-swr-resample_exact-s16p-96000-48000: CMP_TARGET = 1.12 fate-swr-resample_exact-s16p-96000-48000: SIZE_TOLERANCE = 1152000 - 20480 fate-swr-resample_exact-s16p-96000-8000: CMP_TARGET = 58.56 fate-swr-resample_exact-s16p-96000-8000: SIZE_TOLERANCE = 1152000 - 20496 -fate-swr-resample_exact-s32p-2626-44100: CMP_TARGET = 1393.01 +fate-swr-resample_exact-s32p-2626-44100: CMP_TARGET = 1393.02 fate-swr-resample_exact-s32p-2626-44100: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample_exact-s32p-2626-48000: CMP_TARGET = 1392.99 +fate-swr-resample_exact-s32p-2626-48000: CMP_TARGET = 1393.01 fate-swr-resample_exact-s32p-2626-48000: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample_exact-s32p-2626-8000: CMP_TARGET = 1393.89 +fate-swr-resample_exact-s32p-2626-8000: CMP_TARGET = 1393.90 fate-swr-resample_exact-s32p-2626-8000: SIZE_TOLERANCE = 31512 - 20482 -fate-swr-resample_exact-s32p-2626-96000: CMP_TARGET = 1393.00 +fate-swr-resample_exact-s32p-2626-96000: CMP_TARGET = 1393.01 fate-swr-resample_exact-s32p-2626-96000: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample_exact-s32p-44100-2626: CMP_TARGET = 185.82 fate-swr-resample_exact-s32p-44100-2626: SIZE_TOLERANCE = 529200 - 20490 -fate-swr-resample_exact-s32p-44100-48000: CMP_TARGET = 9.65 +fate-swr-resample_exact-s32p-44100-48000: CMP_TARGET = 9.64 fate-swr-resample_exact-s32p-44100-48000: SIZE_TOLERANCE = 529200 - 20482 fate-swr-resample_exact-s32p-44100-8000: CMP_TARGET = 75.38 @@ -596,7 +596,7 @@ fate-swr-resample_exact-s32p-44100-96000: SIZE_TOLERANCE = 529200 - 20482 fate-swr-resample_exact-s32p-48000-2626: CMP_TARGET = 456.51 fate-swr-resample_exact-s32p-48000-2626: SIZE_TOLERANCE = 576000 - 20510 -fate-swr-resample_exact-s32p-48000-44100: CMP_TARGET = 0.26 +fate-swr-resample_exact-s32p-48000-44100: CMP_TARGET = 0.23 fate-swr-resample_exact-s32p-48000-44100: SIZE_TOLERANCE = 576000 - 20480 fate-swr-resample_exact-s32p-48000-8000: CMP_TARGET = 62.36 @@ -620,10 +620,10 @@ fate-swr-resample_exact-s32p-8000-96000: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample_exact-s32p-96000-2626: CMP_TARGET = 675.08 fate-swr-resample_exact-s32p-96000-2626: SIZE_TOLERANCE = 1152000 - 20474 -fate-swr-resample_exact-s32p-96000-44100: CMP_TARGET = 1.26 +fate-swr-resample_exact-s32p-96000-44100: CMP_TARGET = 1.23 fate-swr-resample_exact-s32p-96000-44100: SIZE_TOLERANCE = 1152000 - 20480 -fate-swr-resample_exact-s32p-96000-48000: CMP_TARGET = 1.00 +fate-swr-resample_exact-s32p-96000-48000: CMP_TARGET = 0.99 fate-swr-resample_exact-s32p-96000-48000: SIZE_TOLERANCE = 1152000 - 20480 fate-swr-resample_exact-s32p-96000-8000: CMP_TARGET = 58.52 @@ -640,76 +640,76 @@ fate-swr-resample_exact_async-$(3)-$(1)-$(2): FUZZ = 0.1 fate-swr-resample_exact_async-$(3)-$(1)-$(2): REF = tests/data/asynth-$(1)-1.wav endef -fate-swr-resample_exact_async-dblp-44100-48000: CMP_TARGET = 7791.55 +fate-swr-resample_exact_async-dblp-44100-48000: CMP_TARGET = 7791.50 fate-swr-resample_exact_async-dblp-44100-48000: SIZE_TOLERANCE = 529200 - 20300 -fate-swr-resample_exact_async-dblp-44100-8000: CMP_TARGET = 4022.89 +fate-swr-resample_exact_async-dblp-44100-8000: CMP_TARGET = 4022.87 fate-swr-resample_exact_async-dblp-44100-8000: SIZE_TOLERANCE = 529200 - 20310 -fate-swr-resample_exact_async-dblp-48000-44100: CMP_TARGET = 1923.99 +fate-swr-resample_exact_async-dblp-48000-44100: CMP_TARGET = 1923.97 fate-swr-resample_exact_async-dblp-48000-44100: SIZE_TOLERANCE = 576000 - 20298 -fate-swr-resample_exact_async-dblp-48000-8000: CMP_TARGET = 2592.02 +fate-swr-resample_exact_async-dblp-48000-8000: CMP_TARGET = 2592.00 fate-swr-resample_exact_async-dblp-48000-8000: SIZE_TOLERANCE = 576000 - 20304 -fate-swr-resample_exact_async-dblp-8000-44100: CMP_TARGET = 11187.37 +fate-swr-resample_exact_async-dblp-8000-44100: CMP_TARGET = 11187.24 fate-swr-resample_exact_async-dblp-8000-44100: SIZE_TOLERANCE = 96000 - 20344 -fate-swr-resample_exact_async-dblp-8000-48000: CMP_TARGET = 11326.82 +fate-swr-resample_exact_async-dblp-8000-48000: CMP_TARGET = 11326.80 fate-swr-resample_exact_async-dblp-8000-48000: SIZE_TOLERANCE = 96000 - 20344 -fate-swr-resample_exact_async-fltp-44100-48000: CMP_TARGET = 7791.55 +fate-swr-resample_exact_async-fltp-44100-48000: CMP_TARGET = 7791.50 fate-swr-resample_exact_async-fltp-44100-48000: SIZE_TOLERANCE = 529200 - 20300 -fate-swr-resample_exact_async-fltp-44100-8000: CMP_TARGET = 4022.89 +fate-swr-resample_exact_async-fltp-44100-8000: CMP_TARGET = 4022.87 fate-swr-resample_exact_async-fltp-44100-8000: SIZE_TOLERANCE = 529200 - 20310 -fate-swr-resample_exact_async-fltp-48000-44100: CMP_TARGET = 1923.98 +fate-swr-resample_exact_async-fltp-48000-44100: CMP_TARGET = 1923.97 fate-swr-resample_exact_async-fltp-48000-44100: SIZE_TOLERANCE = 576000 - 20298 -fate-swr-resample_exact_async-fltp-48000-8000: CMP_TARGET = 2592.02 +fate-swr-resample_exact_async-fltp-48000-8000: CMP_TARGET = 2592.00 fate-swr-resample_exact_async-fltp-48000-8000: SIZE_TOLERANCE = 576000 - 20304 -fate-swr-resample_exact_async-fltp-8000-44100: CMP_TARGET = 11187.37 +fate-swr-resample_exact_async-fltp-8000-44100: CMP_TARGET = 11187.24 fate-swr-resample_exact_async-fltp-8000-44100: SIZE_TOLERANCE = 96000 - 20344 -fate-swr-resample_exact_async-fltp-8000-48000: CMP_TARGET = 11326.82 +fate-swr-resample_exact_async-fltp-8000-48000: CMP_TARGET = 11326.80 fate-swr-resample_exact_async-fltp-8000-48000: SIZE_TOLERANCE = 96000 - 20344 -fate-swr-resample_exact_async-s16p-44100-48000: CMP_TARGET = 7791.56 +fate-swr-resample_exact_async-s16p-44100-48000: CMP_TARGET = 7791.50 fate-swr-resample_exact_async-s16p-44100-48000: SIZE_TOLERANCE = 529200 - 20300 -fate-swr-resample_exact_async-s16p-44100-8000: CMP_TARGET = 4023.06 +fate-swr-resample_exact_async-s16p-44100-8000: CMP_TARGET = 4023.05 fate-swr-resample_exact_async-s16p-44100-8000: SIZE_TOLERANCE = 529200 - 20310 -fate-swr-resample_exact_async-s16p-48000-44100: CMP_TARGET = 1923.98 +fate-swr-resample_exact_async-s16p-48000-44100: CMP_TARGET = 1923.96 fate-swr-resample_exact_async-s16p-48000-44100: SIZE_TOLERANCE = 576000 - 20298 fate-swr-resample_exact_async-s16p-48000-8000: CMP_TARGET = 2592.15 fate-swr-resample_exact_async-s16p-48000-8000: SIZE_TOLERANCE = 576000 - 20304 -fate-swr-resample_exact_async-s16p-8000-44100: CMP_TARGET = 11187.62 +fate-swr-resample_exact_async-s16p-8000-44100: CMP_TARGET = 11187.58 fate-swr-resample_exact_async-s16p-8000-44100: SIZE_TOLERANCE = 96000 - 20344 -fate-swr-resample_exact_async-s16p-8000-48000: CMP_TARGET = 11327.50 +fate-swr-resample_exact_async-s16p-8000-48000: CMP_TARGET = 11327.48 fate-swr-resample_exact_async-s16p-8000-48000: SIZE_TOLERANCE = 96000 - 20344 -fate-swr-resample_exact_async-s32p-44100-48000: CMP_TARGET = 7791.55 +fate-swr-resample_exact_async-s32p-44100-48000: CMP_TARGET = 7791.50 fate-swr-resample_exact_async-s32p-44100-48000: SIZE_TOLERANCE = 529200 - 20300 -fate-swr-resample_exact_async-s32p-44100-8000: CMP_TARGET = 4022.89 +fate-swr-resample_exact_async-s32p-44100-8000: CMP_TARGET = 4022.87 fate-swr-resample_exact_async-s32p-44100-8000: SIZE_TOLERANCE = 529200 - 20310 -fate-swr-resample_exact_async-s32p-48000-44100: CMP_TARGET = 1923.98 +fate-swr-resample_exact_async-s32p-48000-44100: CMP_TARGET = 1923.97 fate-swr-resample_exact_async-s32p-48000-44100: SIZE_TOLERANCE = 576000 - 20298 -fate-swr-resample_exact_async-s32p-48000-8000: CMP_TARGET = 2592.02 +fate-swr-resample_exact_async-s32p-48000-8000: CMP_TARGET = 2592.00 fate-swr-resample_exact_async-s32p-48000-8000: SIZE_TOLERANCE = 576000 - 20304 -fate-swr-resample_exact_async-s32p-8000-44100: CMP_TARGET = 11187.37 +fate-swr-resample_exact_async-s32p-8000-44100: CMP_TARGET = 11187.24 fate-swr-resample_exact_async-s32p-8000-44100: SIZE_TOLERANCE = 96000 - 20344 -fate-swr-resample_exact_async-s32p-8000-48000: CMP_TARGET = 11326.82 +fate-swr-resample_exact_async-s32p-8000-48000: CMP_TARGET = 11326.80 fate-swr-resample_exact_async-s32p-8000-48000: SIZE_TOLERANCE = 96000 - 20344 define ARESAMPLE_EXACT_LIN @@ -723,13 +723,13 @@ fate-swr-resample_exact_lin-$(3)-$(1)-$(2): FUZZ = 0.1 fate-swr-resample_exact_lin-$(3)-$(1)-$(2): REF = tests/data/asynth-$(1)-1.wav endef -fate-swr-resample_exact_lin-dblp-44100-48000: CMP_TARGET = 9.65 +fate-swr-resample_exact_lin-dblp-44100-48000: CMP_TARGET = 9.64 fate-swr-resample_exact_lin-dblp-44100-48000: SIZE_TOLERANCE = 529200 - 20482 fate-swr-resample_exact_lin-dblp-44100-8000: CMP_TARGET = 75.38 fate-swr-resample_exact_lin-dblp-44100-8000: SIZE_TOLERANCE = 529200 - 20486 -fate-swr-resample_exact_lin-dblp-48000-44100: CMP_TARGET = 0.26 +fate-swr-resample_exact_lin-dblp-48000-44100: CMP_TARGET = 0.23 fate-swr-resample_exact_lin-dblp-48000-44100: SIZE_TOLERANCE = 576000 - 20480 fate-swr-resample_exact_lin-dblp-48000-8000: CMP_TARGET = 62.36 @@ -741,13 +741,13 @@ fate-swr-resample_exact_lin-dblp-8000-44100: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample_exact_lin-dblp-8000-48000: CMP_TARGET = 14.50 fate-swr-resample_exact_lin-dblp-8000-48000: SIZE_TOLERANCE = 96000 - 20480 -fate-swr-resample_exact_lin-fltp-44100-48000: CMP_TARGET = 9.65 +fate-swr-resample_exact_lin-fltp-44100-48000: CMP_TARGET = 9.64 fate-swr-resample_exact_lin-fltp-44100-48000: SIZE_TOLERANCE = 529200 - 20482 fate-swr-resample_exact_lin-fltp-44100-8000: CMP_TARGET = 75.38 fate-swr-resample_exact_lin-fltp-44100-8000: SIZE_TOLERANCE = 529200 - 20486 -fate-swr-resample_exact_lin-fltp-48000-44100: CMP_TARGET = 0.26 +fate-swr-resample_exact_lin-fltp-48000-44100: CMP_TARGET = 0.23 fate-swr-resample_exact_lin-fltp-48000-44100: SIZE_TOLERANCE = 576000 - 20480 fate-swr-resample_exact_lin-fltp-48000-8000: CMP_TARGET = 62.36 @@ -759,13 +759,13 @@ fate-swr-resample_exact_lin-fltp-8000-44100: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample_exact_lin-fltp-8000-48000: CMP_TARGET = 14.50 fate-swr-resample_exact_lin-fltp-8000-48000: SIZE_TOLERANCE = 96000 - 20480 -fate-swr-resample_exact_lin-s16p-44100-48000: CMP_TARGET = 9.67 +fate-swr-resample_exact_lin-s16p-44100-48000: CMP_TARGET = 9.66 fate-swr-resample_exact_lin-s16p-44100-48000: SIZE_TOLERANCE = 529200 - 20482 fate-swr-resample_exact_lin-s16p-44100-8000: CMP_TARGET = 75.43 fate-swr-resample_exact_lin-s16p-44100-8000: SIZE_TOLERANCE = 529200 - 20486 -fate-swr-resample_exact_lin-s16p-48000-44100: CMP_TARGET = 0.72 +fate-swr-resample_exact_lin-s16p-48000-44100: CMP_TARGET = 0.68 fate-swr-resample_exact_lin-s16p-48000-44100: SIZE_TOLERANCE = 576000 - 20480 fate-swr-resample_exact_lin-s16p-48000-8000: CMP_TARGET = 62.39 @@ -777,13 +777,13 @@ fate-swr-resample_exact_lin-s16p-8000-44100: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample_exact_lin-s16p-8000-48000: CMP_TARGET = 14.54 fate-swr-resample_exact_lin-s16p-8000-48000: SIZE_TOLERANCE = 96000 - 20480 -fate-swr-resample_exact_lin-s32p-44100-48000: CMP_TARGET = 9.65 +fate-swr-resample_exact_lin-s32p-44100-48000: CMP_TARGET = 9.64 fate-swr-resample_exact_lin-s32p-44100-48000: SIZE_TOLERANCE = 529200 - 20482 fate-swr-resample_exact_lin-s32p-44100-8000: CMP_TARGET = 75.38 fate-swr-resample_exact_lin-s32p-44100-8000: SIZE_TOLERANCE = 529200 - 20486 -fate-swr-resample_exact_lin-s32p-48000-44100: CMP_TARGET = 0.26 +fate-swr-resample_exact_lin-s32p-48000-44100: CMP_TARGET = 0.23 fate-swr-resample_exact_lin-s32p-48000-44100: SIZE_TOLERANCE = 576000 - 20480 fate-swr-resample_exact_lin-s32p-48000-8000: CMP_TARGET = 62.36 @@ -806,76 +806,76 @@ fate-swr-resample_exact_lin_async-$(3)-$(1)-$(2): FUZZ = 0.1 fate-swr-resample_exact_lin_async-$(3)-$(1)-$(2): REF = tests/data/asynth-$(1)-1.wav endef -fate-swr-resample_exact_lin_async-dblp-44100-48000: CMP_TARGET = 7791.78 +fate-swr-resample_exact_lin_async-dblp-44100-48000: CMP_TARGET = 7791.72 fate-swr-resample_exact_lin_async-dblp-44100-48000: SIZE_TOLERANCE = 529200 - 20300 -fate-swr-resample_exact_lin_async-dblp-44100-8000: CMP_TARGET = 4023.03 +fate-swr-resample_exact_lin_async-dblp-44100-8000: CMP_TARGET = 4023.01 fate-swr-resample_exact_lin_async-dblp-44100-8000: SIZE_TOLERANCE = 529200 - 20310 -fate-swr-resample_exact_lin_async-dblp-48000-44100: CMP_TARGET = 1923.80 +fate-swr-resample_exact_lin_async-dblp-48000-44100: CMP_TARGET = 1923.79 fate-swr-resample_exact_lin_async-dblp-48000-44100: SIZE_TOLERANCE = 576000 - 20298 -fate-swr-resample_exact_lin_async-dblp-48000-8000: CMP_TARGET = 2591.73 +fate-swr-resample_exact_lin_async-dblp-48000-8000: CMP_TARGET = 2591.72 fate-swr-resample_exact_lin_async-dblp-48000-8000: SIZE_TOLERANCE = 576000 - 20304 -fate-swr-resample_exact_lin_async-dblp-8000-44100: CMP_TARGET = 11187.37 +fate-swr-resample_exact_lin_async-dblp-8000-44100: CMP_TARGET = 11187.25 fate-swr-resample_exact_lin_async-dblp-8000-44100: SIZE_TOLERANCE = 96000 - 20344 -fate-swr-resample_exact_lin_async-dblp-8000-48000: CMP_TARGET = 11326.82 +fate-swr-resample_exact_lin_async-dblp-8000-48000: CMP_TARGET = 11326.80 fate-swr-resample_exact_lin_async-dblp-8000-48000: SIZE_TOLERANCE = 96000 - 20344 -fate-swr-resample_exact_lin_async-fltp-44100-48000: CMP_TARGET = 7791.78 +fate-swr-resample_exact_lin_async-fltp-44100-48000: CMP_TARGET = 7791.72 fate-swr-resample_exact_lin_async-fltp-44100-48000: SIZE_TOLERANCE = 529200 - 20300 -fate-swr-resample_exact_lin_async-fltp-44100-8000: CMP_TARGET = 4023.03 +fate-swr-resample_exact_lin_async-fltp-44100-8000: CMP_TARGET = 4023.01 fate-swr-resample_exact_lin_async-fltp-44100-8000: SIZE_TOLERANCE = 529200 - 20310 -fate-swr-resample_exact_lin_async-fltp-48000-44100: CMP_TARGET = 1923.81 +fate-swr-resample_exact_lin_async-fltp-48000-44100: CMP_TARGET = 1923.79 fate-swr-resample_exact_lin_async-fltp-48000-44100: SIZE_TOLERANCE = 576000 - 20298 -fate-swr-resample_exact_lin_async-fltp-48000-8000: CMP_TARGET = 2591.73 +fate-swr-resample_exact_lin_async-fltp-48000-8000: CMP_TARGET = 2591.72 fate-swr-resample_exact_lin_async-fltp-48000-8000: SIZE_TOLERANCE = 576000 - 20304 -fate-swr-resample_exact_lin_async-fltp-8000-44100: CMP_TARGET = 11187.37 +fate-swr-resample_exact_lin_async-fltp-8000-44100: CMP_TARGET = 11187.25 fate-swr-resample_exact_lin_async-fltp-8000-44100: SIZE_TOLERANCE = 96000 - 20344 -fate-swr-resample_exact_lin_async-fltp-8000-48000: CMP_TARGET = 11326.82 +fate-swr-resample_exact_lin_async-fltp-8000-48000: CMP_TARGET = 11326.80 fate-swr-resample_exact_lin_async-fltp-8000-48000: SIZE_TOLERANCE = 96000 - 20344 -fate-swr-resample_exact_lin_async-s16p-44100-48000: CMP_TARGET = 7791.78 +fate-swr-resample_exact_lin_async-s16p-44100-48000: CMP_TARGET = 7791.72 fate-swr-resample_exact_lin_async-s16p-44100-48000: SIZE_TOLERANCE = 529200 - 20300 -fate-swr-resample_exact_lin_async-s16p-44100-8000: CMP_TARGET = 4023.20 +fate-swr-resample_exact_lin_async-s16p-44100-8000: CMP_TARGET = 4023.19 fate-swr-resample_exact_lin_async-s16p-44100-8000: SIZE_TOLERANCE = 529200 - 20310 -fate-swr-resample_exact_lin_async-s16p-48000-44100: CMP_TARGET = 1923.81 +fate-swr-resample_exact_lin_async-s16p-48000-44100: CMP_TARGET = 1923.79 fate-swr-resample_exact_lin_async-s16p-48000-44100: SIZE_TOLERANCE = 576000 - 20298 -fate-swr-resample_exact_lin_async-s16p-48000-8000: CMP_TARGET = 2591.86 +fate-swr-resample_exact_lin_async-s16p-48000-8000: CMP_TARGET = 2591.85 fate-swr-resample_exact_lin_async-s16p-48000-8000: SIZE_TOLERANCE = 576000 - 20304 -fate-swr-resample_exact_lin_async-s16p-8000-44100: CMP_TARGET = 11187.62 +fate-swr-resample_exact_lin_async-s16p-8000-44100: CMP_TARGET = 11187.57 fate-swr-resample_exact_lin_async-s16p-8000-44100: SIZE_TOLERANCE = 96000 - 20344 -fate-swr-resample_exact_lin_async-s16p-8000-48000: CMP_TARGET = 11327.49 +fate-swr-resample_exact_lin_async-s16p-8000-48000: CMP_TARGET = 11327.48 fate-swr-resample_exact_lin_async-s16p-8000-48000: SIZE_TOLERANCE = 96000 - 20344 -fate-swr-resample_exact_lin_async-s32p-44100-48000: CMP_TARGET = 7791.78 +fate-swr-resample_exact_lin_async-s32p-44100-48000: CMP_TARGET = 7791.72 fate-swr-resample_exact_lin_async-s32p-44100-48000: SIZE_TOLERANCE = 529200 - 20300 -fate-swr-resample_exact_lin_async-s32p-44100-8000: CMP_TARGET = 4023.03 +fate-swr-resample_exact_lin_async-s32p-44100-8000: CMP_TARGET = 4023.01 fate-swr-resample_exact_lin_async-s32p-44100-8000: SIZE_TOLERANCE = 529200 - 20310 -fate-swr-resample_exact_lin_async-s32p-48000-44100: CMP_TARGET = 1923.81 +fate-swr-resample_exact_lin_async-s32p-48000-44100: CMP_TARGET = 1923.79 fate-swr-resample_exact_lin_async-s32p-48000-44100: SIZE_TOLERANCE = 576000 - 20298 -fate-swr-resample_exact_lin_async-s32p-48000-8000: CMP_TARGET = 2591.73 +fate-swr-resample_exact_lin_async-s32p-48000-8000: CMP_TARGET = 2591.72 fate-swr-resample_exact_lin_async-s32p-48000-8000: SIZE_TOLERANCE = 576000 - 20304 -fate-swr-resample_exact_lin_async-s32p-8000-44100: CMP_TARGET = 11187.37 +fate-swr-resample_exact_lin_async-s32p-8000-44100: CMP_TARGET = 11187.25 fate-swr-resample_exact_lin_async-s32p-8000-44100: SIZE_TOLERANCE = 96000 - 20344 -fate-swr-resample_exact_lin_async-s32p-8000-48000: CMP_TARGET = 11326.82 +fate-swr-resample_exact_lin_async-s32p-8000-48000: CMP_TARGET = 11326.80 fate-swr-resample_exact_lin_async-s32p-8000-48000: SIZE_TOLERANCE = 96000 - 20344 $(call CROSS_TEST,$(SAMPLERATES),ARESAMPLE,s16p,s16le,s16) diff --git a/tests/ref/acodec/roqaudio b/tests/ref/acodec/roqaudio index 61cb27a38a041..f513a03975e03 100644 --- a/tests/ref/acodec/roqaudio +++ b/tests/ref/acodec/roqaudio @@ -1,4 +1,4 @@ 75859976d7098588aeaebbc5551484a9 *tests/data/fate/acodec-roqaudio.roq 265992 tests/data/fate/acodec-roqaudio.roq -73d5aaaab9488e63f1cf6fc324c7a9a2 *tests/data/fate/acodec-roqaudio.out.wav +2057ed235e9d4e727e13bf57f3891093 *tests/data/fate/acodec-roqaudio.out.wav stddev: 4481.70 PSNR: 23.30 MAXDIFF:46250 bytes: 1058400/ 1058400 diff --git a/tests/ref/acodec/s302m b/tests/ref/acodec/s302m index 5eca9e3a6bc64..7e41abb61f258 100644 --- a/tests/ref/acodec/s302m +++ b/tests/ref/acodec/s302m @@ -1,4 +1,4 @@ -f6908214498489799b50e332ac42ebf3 *tests/data/fate/acodec-s302m.mpegts +a69563c4c5db97d1b313c2fd7a193dd4 *tests/data/fate/acodec-s302m.mpegts 1589164 tests/data/fate/acodec-s302m.mpegts -f9b6528eee1aea04640ee83400c78689 *tests/data/fate/acodec-s302m.out.wav -stddev: 986.97 PSNR: 36.44 MAXDIFF:18642 bytes: 1058400/ 1056708 +2c033ed1d9029ed03e08c1d01dcefd99 *tests/data/fate/acodec-s302m.out.wav +stddev: 986.98 PSNR: 36.44 MAXDIFF:18642 bytes: 1058400/ 1056708 diff --git a/tests/ref/lavf/dv_fmt b/tests/ref/lavf/dv_fmt index b152c84ca826f..c8e4b115f5e1e 100644 --- a/tests/ref/lavf/dv_fmt +++ b/tests/ref/lavf/dv_fmt @@ -1,9 +1,9 @@ -11be3e5caa2892236b3475c3f7807b76 *./tests/data/lavf/lavf.dv +3bcb02ee889b8b2da19cae79d0f1c27d *./tests/data/lavf/lavf.dv 3600000 ./tests/data/lavf/lavf.dv -./tests/data/lavf/lavf.dv CRC=0x0b2cd3ec -e9949bc767924e1e7d28856029fee024 *./tests/data/lavf/lavf.dv +./tests/data/lavf/lavf.dv CRC=0x5a36cc70 +f827583ae54e590d753c37709738fd54 *./tests/data/lavf/lavf.dv 3480000 ./tests/data/lavf/lavf.dv -./tests/data/lavf/lavf.dv CRC=0xfab17c4a +./tests/data/lavf/lavf.dv CRC=0x8f8074be 87d3b20f656235671383a7eaa2f66330 *./tests/data/lavf/lavf.dv 3600000 ./tests/data/lavf/lavf.dv ./tests/data/lavf/lavf.dv CRC=0xf3e6873c diff --git a/tests/ref/lavf/gxf b/tests/ref/lavf/gxf index d356f20811365..9b9831be3e1e4 100644 --- a/tests/ref/lavf/gxf +++ b/tests/ref/lavf/gxf @@ -1,9 +1,9 @@ -7993da95d8bfe04832e27892c163e562 *./tests/data/lavf/lavf.gxf +1b384e20293a84b274739c147e2b290a *./tests/data/lavf/lavf.gxf 795876 ./tests/data/lavf/lavf.gxf -./tests/data/lavf/lavf.gxf CRC=0xda7cebbc -9e873074b5c3ef1d80d233a38e7de156 *./tests/data/lavf/lavf.gxf +./tests/data/lavf/lavf.gxf CRC=0x55b3ec1d +411f109b5867e5cb81bc876d3cc5702b *./tests/data/lavf/lavf.gxf 794656 ./tests/data/lavf/lavf.gxf -./tests/data/lavf/lavf.gxf CRC=0x7f0c9089 +./tests/data/lavf/lavf.gxf CRC=0x0d7e90ea 0638c4d073ac224608baaba16732b68f *./tests/data/lavf/lavf.gxf 795876 ./tests/data/lavf/lavf.gxf ./tests/data/lavf/lavf.gxf CRC=0x5ade0285 diff --git a/tests/ref/lavf/mxf b/tests/ref/lavf/mxf index 103ef010b70c5..aea9c0246c9ca 100644 --- a/tests/ref/lavf/mxf +++ b/tests/ref/lavf/mxf @@ -1,9 +1,9 @@ -c61e677b4facc407ca82b1d7c6298484 *./tests/data/lavf/lavf.mxf +2fd59c174dfb213d35e86dea63c0fb13 *./tests/data/lavf/lavf.mxf 525369 ./tests/data/lavf/lavf.mxf -./tests/data/lavf/lavf.mxf CRC=0xdbfff6f1 -1ae017b5879992431614b1c7ab3b48c5 *./tests/data/lavf/lavf.mxf +./tests/data/lavf/lavf.mxf CRC=0x9fd3f752 +edb3b610c301362d7b4c12f06f8d2782 *./tests/data/lavf/lavf.mxf 560697 ./tests/data/lavf/lavf.mxf -./tests/data/lavf/lavf.mxf CRC=0x11a6178e -27fac91dce279630a04b94b93518a9d8 *./tests/data/lavf/lavf.mxf +./tests/data/lavf/lavf.mxf CRC=0xc51717ef +a6ba421f38ee5ec46e181225c632fee4 *./tests/data/lavf/lavf.mxf 525369 ./tests/data/lavf/lavf.mxf -./tests/data/lavf/lavf.mxf CRC=0xdbfff6f1 +./tests/data/lavf/lavf.mxf CRC=0x9fd3f752 From a50ccbd240a958c32078352021b677c5476d734e Mon Sep 17 00:00:00 2001 From: Thomas Turner Date: Tue, 7 Mar 2017 16:36:15 -0800 Subject: [PATCH 1054/3374] avutil/tests/lfg.c: added proper normality test The Chen-Shapiro(CS) test was used to test normality for Lagged Fibonacci PRNG. Normality Hypothesis Test: The null hypothesis formally tests if the population the sample represents is normally-distributed. For CS, when the normality hypothesis is True, the distribution of QH will have a mean close to 1. Information on CS can be found here: http://www.stata-journal.com/sjpdf.html?articlenum=st0264 http://www.originlab.com/doc/Origin-Help/NormalityTest-Algorithm Signed-off-by: Thomas Turner Signed-off-by: Michael Niedermayer --- libavutil/tests/lfg.c | 164 ++++++- tests/fate/libavutil.mak | 4 + tests/ref/fate/lfg | 1007 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 1153 insertions(+), 22 deletions(-) create mode 100644 tests/ref/fate/lfg diff --git a/libavutil/tests/lfg.c b/libavutil/tests/lfg.c index 1425e026b404f..9e908d2a9086f 100644 --- a/libavutil/tests/lfg.c +++ b/libavutil/tests/lfg.c @@ -20,6 +20,85 @@ #include "libavutil/timer.h" #include "libavutil/lfg.h" +static const double Z_TABLE[31][10] = { + {0.5000, 0.5040, 0.5080, 0.5120, 0.5160, 0.5199, 0.5239, 0.5279, 0.5319, 0.5359}, + {0.5398, 0.5438, 0.5478, 0.5517, 0.5557, 0.5596, 0.5636, 0.5675, 0.5714, 0.5753}, + {0.5793, 0.5832, 0.5871, 0.5910, 0.5948, 0.5987, 0.6026, 0.6064, 0.6103, 0.6141}, + {0.6179, 0.6217, 0.6255, 0.6293, 0.6331, 0.6368, 0.6406, 0.6443, 0.6480, 0.6517}, + {0.6554, 0.6591, 0.6628, 0.6664, 0.6700, 0.6736, 0.6772, 0.6808, 0.6844, 0.6879}, + {0.6915, 0.6950, 0.6985, 0.7019, 0.7054, 0.7088, 0.7123, 0.7157, 0.7190, 0.7224}, + {0.7257, 0.7291, 0.7324, 0.7357, 0.7389, 0.7422, 0.7454, 0.7486, 0.7517, 0.7549}, + {0.7580, 0.7611, 0.7642, 0.7673, 0.7704, 0.7734, 0.7764, 0.7794, 0.7823, 0.7852}, + {0.7881, 0.7910, 0.7939, 0.7967, 0.7995, 0.8023, 0.8051, 0.8078, 0.8106, 0.8133}, + {0.8159, 0.8186, 0.8212, 0.8238, 0.8264, 0.8289, 0.8315, 0.8340, 0.8365, 0.8389}, + {0.8413, 0.8438, 0.8461, 0.8485, 0.8508, 0.8531, 0.8554, 0.8577, 0.8599, 0.8621}, + {0.8643, 0.8665, 0.8686, 0.8708, 0.8729, 0.8749, 0.8770, 0.8790, 0.8810, 0.8830}, + {0.8849, 0.8869, 0.8888, 0.8907, 0.8925, 0.8944, 0.8962, 0.8980, 0.8997, 0.9015}, + {0.9032, 0.9049, 0.9066, 0.9082, 0.9099, 0.9115, 0.9131, 0.9147, 0.9162, 0.9177}, + {0.9192, 0.9207, 0.9222, 0.9236, 0.9251, 0.9265, 0.9279, 0.9292, 0.9306, 0.9319}, + {0.9332, 0.9345, 0.9357, 0.9370, 0.9382, 0.9394, 0.9406, 0.9418, 0.9429, 0.9441}, + {0.9452, 0.9463, 0.9474, 0.9484, 0.9495, 0.9505, 0.9515, 0.9525, 0.9535, 0.9545}, + {0.9554, 0.9564, 0.9573, 0.9582, 0.9591, 0.9599, 0.9608, 0.9616, 0.9625, 0.9633}, + {0.9641, 0.9649, 0.9656, 0.9664, 0.9671, 0.9678, 0.9686, 0.9693, 0.9699, 0.9706}, + {0.9713, 0.9719, 0.9726, 0.9732, 0.9738, 0.9744, 0.9750, 0.9756, 0.9761, 0.9767}, + {0.9772, 0.9778, 0.9783, 0.9788, 0.9793, 0.9798, 0.9803, 0.9808, 0.9812, 0.9817}, + {0.9821, 0.9826, 0.9830, 0.9834, 0.9838, 0.9842, 0.9846, 0.9850, 0.9854, 0.9857}, + {0.9861, 0.9864, 0.9868, 0.9871, 0.9875, 0.9878, 0.9881, 0.9884, 0.9887, 0.9890}, + {0.9893, 0.9896, 0.9898, 0.9901, 0.9904, 0.9906, 0.9909, 0.9911, 0.9913, 0.9916}, + {0.9918, 0.9920, 0.9922, 0.9925, 0.9927, 0.9929, 0.9931, 0.9932, 0.9934, 0.9936}, + {0.9938, 0.9940, 0.9941, 0.9943, 0.9945, 0.9946, 0.9948, 0.9949, 0.9951, 0.9952}, + {0.9953, 0.9955, 0.9956, 0.9957, 0.9959, 0.9960, 0.9961, 0.9962, 0.9963, 0.9964}, + {0.9965, 0.9966, 0.9967, 0.9968, 0.9969, 0.9970, 0.9971, 0.9972, 0.9973, 0.9974}, + {0.9974, 0.9975, 0.9976, 0.9977, 0.9977, 0.9978, 0.9979, 0.9979, 0.9980, 0.9981}, + {0.9981, 0.9982, 0.9982, 0.9983, 0.9984, 0.9984, 0.9985, 0.9985, 0.9986, 0.9986}, + {0.9987, 0.9987, 0.9987, 0.9988, 0.9988, 0.9989, 0.9989, 0.9989, 0.9990, 0.9990} }; + +// Inverse cumulative distribution function +static double inv_cdf(double u) +{ + const double a[4] = { 2.50662823884, + -18.61500062529, + 41.39119773534, + -25.44106049637}; + + const double b[4] = {-8.47351093090, + 23.08336743743, + -21.06224101826, + 3.13082909833}; + + const double c[9] = {0.3374754822726147, + 0.9761690190917186, + 0.1607979714918209, + 0.0276438810333863, + 0.0038405729373609, + 0.0003951896511919, + 0.0000321767881768, + 0.0000002888167364, + 0.0000003960315187}; + + double r; + double x = u - 0.5; + + // Beasley-Springer + if (fabs(x) < 0.42) { + + double y = x * x; + r = x * (((a[3]*y+a[2])*y+a[1])*y+a[0]) / + ((((b[3]*y+b[2])*y+b[1])*y+b[0])*y+1.0); + } + else {// Moro + r = u; + if (x > 0.0) + r = 1.0 - u; + r = log(-log(r)); + r = c[0] + r*(c[1]+r*(c[2]+r*(c[3]+r*(c[4]+r*(c[5]+r*(c[6]+ + r*(c[7]+r*c[8]))))))); + if (x < 0.0) + r = -r; + } + + return r; +} int main(void) { int x = 0; @@ -41,34 +120,75 @@ int main(void) { double mean = 1000; double stddev = 53; - double samp_mean = 0.0, samp_stddev = 0.0; - double samp0, samp1; + double samp_mean = 0.0, samp_stddev = 0.0, QH = 0; + double Z, p_value = -1, tot_samp = 1000; + double *PRN_arr = av_malloc_array(tot_samp, sizeof(double)); - av_lfg_init(&state, 42); + if (!PRN_arr) { + fprintf(stderr, "failed to allocate memory!\n"); + return 1; + } - for (i = 0; i < 1000; i += 2) { + av_lfg_init(&state, 42); + for (i = 0; i < tot_samp; i += 2) { double bmg_out[2]; av_bmg_get(&state, bmg_out); - samp0 = bmg_out[0] * stddev + mean; - samp1 = bmg_out[1] * stddev + mean; - samp_mean += samp0 + samp1; - samp_stddev += samp0 * samp0 + samp1 * samp1; - av_log(NULL, AV_LOG_INFO, - "%f\n%f\n", - samp0, - samp1); + PRN_arr[i ] = bmg_out[0] * stddev + mean; + PRN_arr[i+1] = bmg_out[1] * stddev + mean; + samp_mean += PRN_arr[i] + PRN_arr[i+1]; + samp_stddev += PRN_arr[i] * PRN_arr[i] + PRN_arr[i+1] * PRN_arr[i+1]; + printf("PRN%d : %f\n" + "PRN%d : %f\n", + i, PRN_arr[i], i+1, PRN_arr[i+1]); } - /* TODO: add proper normality test */ - samp_mean /= 1000; - samp_stddev /= 999; - samp_stddev -= (1000.0/999.0)*samp_mean*samp_mean; + samp_mean /= tot_samp; + samp_stddev /= (tot_samp - 1); + samp_stddev -= (tot_samp * 1.0 / (tot_samp - 1))*samp_mean*samp_mean; samp_stddev = sqrt(samp_stddev); - av_log(NULL, AV_LOG_INFO, "sample mean : %f\n" - "true mean : %f\n" - "sample stddev: %f\n" - "true stddev : %f\n", - samp_mean, mean, samp_stddev, stddev); - } + Z = (mean - samp_mean) / (stddev / sqrt(tot_samp)); + { + int x, y, a, b, flag = 0; + + if (Z < 0.0) { + flag = !flag; + Z = Z * -1.0; + } + + a = (int)(Z * 100); + b = ((int)Z * 100); + x = Z * 10; + y = (b > 0) ? a % b : a; + y = y % 10; + if (x > 30 || y > 9) { + av_log(NULL, AV_LOG_INFO, "error: out of bounds! tried to access" + "Z_TABLE[%d][%d]\n", x, y); + goto SKIP; + } + p_value = flag ? 1 - Z_TABLE[x][y] : Z_TABLE[x][y]; + } +SKIP: for (i = 0; i < tot_samp; ++i) { + + if ( i < (tot_samp - 1)) { + double H_diff; + H_diff = inv_cdf((i + 2.0 - (3.0/8.0)) / (tot_samp + (1.0/4.0))); + H_diff -= inv_cdf((i + 1.0 - (3.0/8.0)) / (tot_samp + (1.0/4.0))); + + QH += ((PRN_arr[i + 1] - PRN_arr[i]) / H_diff); + } + } + QH = 1.0 - QH / ((tot_samp - 1.0) * samp_stddev); + + printf("sample mean : %f\n" + "true mean : %f\n" + "sample stddev: %f\n" + "true stddev : %f\n" + "z-score : %f\n" + "p-value : %f\n" + "QH[normality]: %f\n", + samp_mean, mean, samp_stddev, stddev, Z, p_value, QH); + + av_freep(&PRN_arr); + } return 0; } diff --git a/tests/fate/libavutil.mak b/tests/fate/libavutil.mak index a7bf739dff11e..2e3830ed881d9 100644 --- a/tests/fate/libavutil.mak +++ b/tests/fate/libavutil.mak @@ -101,6 +101,10 @@ FATE_LIBAVUTIL += fate-imgutils fate-imgutils: libavutil/tests/imgutils$(EXESUF) fate-imgutils: CMD = run libavutil/tests/imgutils +FATE_LIBAVUTIL += fate-lfg +fate-lfg: libavutil/tests/lfg$(EXESUF) +fate-lfg: CMD = run libavutil/tests/lfg + FATE_LIBAVUTIL += fate-md5 fate-md5: libavutil/tests/md5$(EXESUF) fate-md5: CMD = run libavutil/tests/md5 diff --git a/tests/ref/fate/lfg b/tests/ref/fate/lfg new file mode 100644 index 0000000000000..2d00f4d8a20ff --- /dev/null +++ b/tests/ref/fate/lfg @@ -0,0 +1,1007 @@ +PRN0 : 993.985459 +PRN1 : 1033.987435 +PRN2 : 1047.662570 +PRN3 : 1063.912250 +PRN4 : 991.171781 +PRN5 : 981.734708 +PRN6 : 970.361179 +PRN7 : 998.599410 +PRN8 : 1001.562108 +PRN9 : 1094.675286 +PRN10 : 1026.730733 +PRN11 : 1001.794662 +PRN12 : 1063.992962 +PRN13 : 1003.176291 +PRN14 : 975.451418 +PRN15 : 963.164272 +PRN16 : 1035.042964 +PRN17 : 936.289221 +PRN18 : 1031.696061 +PRN19 : 1033.960882 +PRN20 : 970.449088 +PRN21 : 910.742009 +PRN22 : 1062.832837 +PRN23 : 972.315035 +PRN24 : 1094.553302 +PRN25 : 1004.366061 +PRN26 : 1067.940967 +PRN27 : 954.763340 +PRN28 : 923.089263 +PRN29 : 1053.286222 +PRN30 : 1012.639887 +PRN31 : 948.568149 +PRN32 : 1027.339362 +PRN33 : 953.080426 +PRN34 : 1035.425106 +PRN35 : 966.976740 +PRN36 : 1064.841657 +PRN37 : 904.714740 +PRN38 : 1054.112231 +PRN39 : 986.084454 +PRN40 : 964.995134 +PRN41 : 1064.898415 +PRN42 : 1049.385860 +PRN43 : 946.010664 +PRN44 : 914.563520 +PRN45 : 1054.057798 +PRN46 : 921.007266 +PRN47 : 1055.600575 +PRN48 : 984.003285 +PRN49 : 1064.479044 +PRN50 : 989.128936 +PRN51 : 972.772486 +PRN52 : 1028.824527 +PRN53 : 948.999392 +PRN54 : 926.982512 +PRN55 : 1028.107269 +PRN56 : 1018.971292 +PRN57 : 979.049159 +PRN58 : 1078.652930 +PRN59 : 1059.268785 +PRN60 : 966.062302 +PRN61 : 952.298249 +PRN62 : 965.484659 +PRN63 : 957.131298 +PRN64 : 1101.631483 +PRN65 : 991.328207 +PRN66 : 947.868071 +PRN67 : 977.329736 +PRN68 : 1039.860026 +PRN69 : 1005.357641 +PRN70 : 926.524754 +PRN71 : 1065.337110 +PRN72 : 1016.266500 +PRN73 : 1005.771115 +PRN74 : 1013.342260 +PRN75 : 1016.421157 +PRN76 : 918.857846 +PRN77 : 1084.126406 +PRN78 : 1013.273197 +PRN79 : 1009.859699 +PRN80 : 953.978276 +PRN81 : 966.195381 +PRN82 : 966.041526 +PRN83 : 1034.313935 +PRN84 : 1028.006502 +PRN85 : 988.667994 +PRN86 : 951.447243 +PRN87 : 950.197401 +PRN88 : 1004.492867 +PRN89 : 1018.726549 +PRN90 : 1002.135383 +PRN91 : 1015.553223 +PRN92 : 968.825638 +PRN93 : 909.251629 +PRN94 : 927.430200 +PRN95 : 1026.839173 +PRN96 : 1001.209732 +PRN97 : 903.997372 +PRN98 : 1029.582853 +PRN99 : 998.221588 +PRN100 : 874.533368 +PRN101 : 1008.158727 +PRN102 : 1064.130097 +PRN103 : 1020.425429 +PRN104 : 914.904591 +PRN105 : 1050.711960 +PRN106 : 1019.491585 +PRN107 : 968.062305 +PRN108 : 946.755388 +PRN109 : 1012.508705 +PRN110 : 997.922624 +PRN111 : 962.447265 +PRN112 : 1065.410496 +PRN113 : 1059.470790 +PRN114 : 1036.427789 +PRN115 : 963.516351 +PRN116 : 970.000982 +PRN117 : 978.030226 +PRN118 : 1041.883687 +PRN119 : 924.311759 +PRN120 : 987.574757 +PRN121 : 1020.188441 +PRN122 : 979.109616 +PRN123 : 1076.652961 +PRN124 : 905.994009 +PRN125 : 999.425282 +PRN126 : 1012.521111 +PRN127 : 893.443447 +PRN128 : 978.578327 +PRN129 : 1068.476732 +PRN130 : 960.687195 +PRN131 : 954.211448 +PRN132 : 1031.587651 +PRN133 : 1069.561334 +PRN134 : 948.293168 +PRN135 : 999.185195 +PRN136 : 967.284970 +PRN137 : 1004.112868 +PRN138 : 989.683149 +PRN139 : 1008.154639 +PRN140 : 1043.953748 +PRN141 : 1082.131379 +PRN142 : 1006.528611 +PRN143 : 942.893040 +PRN144 : 1120.072970 +PRN145 : 908.369273 +PRN146 : 1039.338207 +PRN147 : 1011.429056 +PRN148 : 1058.020374 +PRN149 : 1007.346274 +PRN150 : 916.830032 +PRN151 : 1000.237008 +PRN152 : 977.470622 +PRN153 : 985.066693 +PRN154 : 1020.675449 +PRN155 : 1026.074199 +PRN156 : 1087.961390 +PRN157 : 993.836698 +PRN158 : 1008.510268 +PRN159 : 1013.336576 +PRN160 : 1022.611211 +PRN161 : 996.211550 +PRN162 : 1025.772152 +PRN163 : 1058.268017 +PRN164 : 911.997787 +PRN165 : 1052.556722 +PRN166 : 998.536098 +PRN167 : 915.837410 +PRN168 : 979.313138 +PRN169 : 1045.691152 +PRN170 : 1018.832329 +PRN171 : 1086.959291 +PRN172 : 1065.875576 +PRN173 : 1018.341432 +PRN174 : 1101.511906 +PRN175 : 1130.164468 +PRN176 : 1043.232574 +PRN177 : 1086.907863 +PRN178 : 1025.378136 +PRN179 : 999.601323 +PRN180 : 1036.776794 +PRN181 : 988.653272 +PRN182 : 973.274518 +PRN183 : 1000.807655 +PRN184 : 1057.386211 +PRN185 : 960.735035 +PRN186 : 904.872645 +PRN187 : 889.117280 +PRN188 : 983.809186 +PRN189 : 912.874411 +PRN190 : 975.589269 +PRN191 : 948.421999 +PRN192 : 947.657566 +PRN193 : 950.000738 +PRN194 : 962.922561 +PRN195 : 1026.301488 +PRN196 : 1029.353812 +PRN197 : 1047.303674 +PRN198 : 1028.695557 +PRN199 : 1070.200632 +PRN200 : 947.575145 +PRN201 : 876.904616 +PRN202 : 1017.701430 +PRN203 : 1049.267498 +PRN204 : 958.139948 +PRN205 : 967.417379 +PRN206 : 968.274143 +PRN207 : 1000.864388 +PRN208 : 1066.802181 +PRN209 : 1014.463051 +PRN210 : 1026.799870 +PRN211 : 1018.450824 +PRN212 : 988.633963 +PRN213 : 904.749119 +PRN214 : 937.323052 +PRN215 : 1037.391158 +PRN216 : 1026.099281 +PRN217 : 907.667691 +PRN218 : 1010.454766 +PRN219 : 1019.473463 +PRN220 : 1005.177530 +PRN221 : 997.361757 +PRN222 : 954.628248 +PRN223 : 1061.917463 +PRN224 : 1039.311045 +PRN225 : 983.843948 +PRN226 : 968.679422 +PRN227 : 970.518863 +PRN228 : 963.038929 +PRN229 : 1086.210292 +PRN230 : 1022.961948 +PRN231 : 964.149961 +PRN232 : 949.462428 +PRN233 : 959.221279 +PRN234 : 987.151293 +PRN235 : 959.017697 +PRN236 : 996.893693 +PRN237 : 965.063094 +PRN238 : 1000.468116 +PRN239 : 1004.755878 +PRN240 : 995.674256 +PRN241 : 996.723454 +PRN242 : 966.714381 +PRN243 : 992.601460 +PRN244 : 1041.656776 +PRN245 : 1061.690153 +PRN246 : 1103.650456 +PRN247 : 1055.668922 +PRN248 : 1052.582092 +PRN249 : 953.461917 +PRN250 : 1006.433285 +PRN251 : 955.606772 +PRN252 : 1039.688043 +PRN253 : 1088.653591 +PRN254 : 942.093968 +PRN255 : 1031.071161 +PRN256 : 946.110148 +PRN257 : 932.761874 +PRN258 : 1052.693974 +PRN259 : 1008.479381 +PRN260 : 1063.720881 +PRN261 : 992.478541 +PRN262 : 915.981089 +PRN263 : 992.027282 +PRN264 : 1024.266535 +PRN265 : 919.165065 +PRN266 : 1010.516440 +PRN267 : 997.213969 +PRN268 : 1021.925225 +PRN269 : 978.883278 +PRN270 : 981.515166 +PRN271 : 980.281886 +PRN272 : 1053.161093 +PRN273 : 912.521231 +PRN274 : 953.132131 +PRN275 : 1004.643842 +PRN276 : 1058.794186 +PRN277 : 984.215138 +PRN278 : 1042.304270 +PRN279 : 972.388973 +PRN280 : 1033.185530 +PRN281 : 969.133442 +PRN282 : 1027.169707 +PRN283 : 1061.483306 +PRN284 : 960.680868 +PRN285 : 1001.272929 +PRN286 : 1017.813674 +PRN287 : 983.331085 +PRN288 : 932.052156 +PRN289 : 1004.348693 +PRN290 : 1086.961051 +PRN291 : 1038.181141 +PRN292 : 1050.191404 +PRN293 : 997.767778 +PRN294 : 1080.797673 +PRN295 : 976.782991 +PRN296 : 1031.633723 +PRN297 : 1011.128806 +PRN298 : 1008.380640 +PRN299 : 1087.552272 +PRN300 : 962.484066 +PRN301 : 942.301619 +PRN302 : 983.039469 +PRN303 : 962.689056 +PRN304 : 947.296230 +PRN305 : 1070.666154 +PRN306 : 1032.115321 +PRN307 : 1021.567324 +PRN308 : 953.506490 +PRN309 : 1002.026680 +PRN310 : 1008.181860 +PRN311 : 1025.392684 +PRN312 : 968.955019 +PRN313 : 1049.458891 +PRN314 : 957.676990 +PRN315 : 1035.683512 +PRN316 : 1112.131175 +PRN317 : 1055.138933 +PRN318 : 1078.236814 +PRN319 : 1125.693872 +PRN320 : 1022.131166 +PRN321 : 1116.997957 +PRN322 : 1089.131000 +PRN323 : 1077.159289 +PRN324 : 945.536432 +PRN325 : 1075.404651 +PRN326 : 946.487332 +PRN327 : 1024.258871 +PRN328 : 1031.225842 +PRN329 : 1016.780255 +PRN330 : 1103.910936 +PRN331 : 1000.846691 +PRN332 : 984.532087 +PRN333 : 1005.306673 +PRN334 : 1113.067840 +PRN335 : 964.786705 +PRN336 : 1031.129909 +PRN337 : 1102.032227 +PRN338 : 1032.427500 +PRN339 : 915.287948 +PRN340 : 1069.521468 +PRN341 : 1037.884311 +PRN342 : 1022.783172 +PRN343 : 1010.113843 +PRN344 : 936.663822 +PRN345 : 967.568134 +PRN346 : 998.248532 +PRN347 : 970.595103 +PRN348 : 1059.133013 +PRN349 : 1002.450372 +PRN350 : 1041.569244 +PRN351 : 1071.151467 +PRN352 : 1074.430879 +PRN353 : 1024.192522 +PRN354 : 1027.316098 +PRN355 : 903.837437 +PRN356 : 1025.087981 +PRN357 : 1078.239201 +PRN358 : 947.160744 +PRN359 : 943.791880 +PRN360 : 982.419379 +PRN361 : 1015.326413 +PRN362 : 930.457683 +PRN363 : 1056.989164 +PRN364 : 1048.214411 +PRN365 : 1011.714309 +PRN366 : 973.561885 +PRN367 : 938.897489 +PRN368 : 898.131351 +PRN369 : 1089.422229 +PRN370 : 1000.737285 +PRN371 : 943.187609 +PRN372 : 980.631385 +PRN373 : 1026.612456 +PRN374 : 914.530023 +PRN375 : 989.137431 +PRN376 : 936.013065 +PRN377 : 1037.484721 +PRN378 : 1005.741041 +PRN379 : 1079.121866 +PRN380 : 1055.031055 +PRN381 : 967.647139 +PRN382 : 1073.874913 +PRN383 : 987.676314 +PRN384 : 1064.291410 +PRN385 : 1036.029393 +PRN386 : 1021.885249 +PRN387 : 971.958380 +PRN388 : 1060.807076 +PRN389 : 944.558349 +PRN390 : 936.791120 +PRN391 : 986.203862 +PRN392 : 934.815474 +PRN393 : 950.177863 +PRN394 : 1053.566520 +PRN395 : 955.717211 +PRN396 : 914.562496 +PRN397 : 1021.237741 +PRN398 : 985.669335 +PRN399 : 1049.267052 +PRN400 : 1096.201981 +PRN401 : 871.290446 +PRN402 : 1056.942788 +PRN403 : 991.680777 +PRN404 : 987.094995 +PRN405 : 1030.857572 +PRN406 : 1014.738174 +PRN407 : 1122.789424 +PRN408 : 1057.378717 +PRN409 : 852.638284 +PRN410 : 979.034993 +PRN411 : 1050.776805 +PRN412 : 1013.760119 +PRN413 : 1013.442288 +PRN414 : 1056.335907 +PRN415 : 1003.833582 +PRN416 : 952.287368 +PRN417 : 983.410711 +PRN418 : 981.610215 +PRN419 : 955.751367 +PRN420 : 1026.024405 +PRN421 : 913.215405 +PRN422 : 1039.587952 +PRN423 : 934.420327 +PRN424 : 1048.085188 +PRN425 : 1069.984971 +PRN426 : 1022.569605 +PRN427 : 994.967729 +PRN428 : 978.231174 +PRN429 : 1091.191368 +PRN430 : 1110.565525 +PRN431 : 993.099640 +PRN432 : 943.356916 +PRN433 : 1008.520337 +PRN434 : 1039.057948 +PRN435 : 995.518711 +PRN436 : 923.381630 +PRN437 : 1008.525954 +PRN438 : 1074.725786 +PRN439 : 973.831465 +PRN440 : 992.850511 +PRN441 : 915.574772 +PRN442 : 935.268901 +PRN443 : 1030.668761 +PRN444 : 1006.389624 +PRN445 : 1070.532520 +PRN446 : 1044.161059 +PRN447 : 1009.868970 +PRN448 : 995.488179 +PRN449 : 1003.676963 +PRN450 : 1036.281447 +PRN451 : 1034.663850 +PRN452 : 1016.940948 +PRN453 : 1041.761449 +PRN454 : 1036.179308 +PRN455 : 927.147021 +PRN456 : 1015.267516 +PRN457 : 1025.120602 +PRN458 : 1003.012895 +PRN459 : 1017.405398 +PRN460 : 1084.152015 +PRN461 : 938.100545 +PRN462 : 982.848682 +PRN463 : 971.208439 +PRN464 : 1024.169902 +PRN465 : 984.026162 +PRN466 : 885.734952 +PRN467 : 970.662665 +PRN468 : 966.626383 +PRN469 : 970.630895 +PRN470 : 1065.729526 +PRN471 : 1087.725051 +PRN472 : 934.663676 +PRN473 : 982.326660 +PRN474 : 1028.573796 +PRN475 : 1042.602736 +PRN476 : 919.644128 +PRN477 : 1117.592528 +PRN478 : 973.727786 +PRN479 : 1017.035309 +PRN480 : 985.948508 +PRN481 : 993.332284 +PRN482 : 913.783006 +PRN483 : 1036.292614 +PRN484 : 944.347075 +PRN485 : 993.774520 +PRN486 : 1004.501737 +PRN487 : 975.074516 +PRN488 : 960.381723 +PRN489 : 1032.461979 +PRN490 : 965.849830 +PRN491 : 959.343865 +PRN492 : 998.303510 +PRN493 : 1098.972429 +PRN494 : 978.774732 +PRN495 : 923.587406 +PRN496 : 934.194464 +PRN497 : 1019.233725 +PRN498 : 998.978470 +PRN499 : 969.151090 +PRN500 : 1008.850844 +PRN501 : 1002.711126 +PRN502 : 991.872449 +PRN503 : 948.998513 +PRN504 : 985.482935 +PRN505 : 1064.356664 +PRN506 : 920.085989 +PRN507 : 957.924976 +PRN508 : 1059.586657 +PRN509 : 948.912499 +PRN510 : 969.734926 +PRN511 : 991.121045 +PRN512 : 980.425651 +PRN513 : 1002.105883 +PRN514 : 1044.420229 +PRN515 : 1050.108383 +PRN516 : 1055.666511 +PRN517 : 1050.562993 +PRN518 : 918.954103 +PRN519 : 1031.398881 +PRN520 : 1015.533157 +PRN521 : 982.110348 +PRN522 : 911.625140 +PRN523 : 908.261708 +PRN524 : 892.515101 +PRN525 : 999.272597 +PRN526 : 1063.535795 +PRN527 : 1001.036057 +PRN528 : 1054.891358 +PRN529 : 970.513392 +PRN530 : 1009.957719 +PRN531 : 994.077721 +PRN532 : 1094.151066 +PRN533 : 987.039498 +PRN534 : 973.811047 +PRN535 : 959.839155 +PRN536 : 961.322994 +PRN537 : 1051.549887 +PRN538 : 931.006138 +PRN539 : 1090.452240 +PRN540 : 967.033966 +PRN541 : 991.451211 +PRN542 : 1042.788825 +PRN543 : 1075.910278 +PRN544 : 1009.225010 +PRN545 : 1005.631562 +PRN546 : 972.521547 +PRN547 : 1001.788406 +PRN548 : 1026.096292 +PRN549 : 943.517653 +PRN550 : 1043.297977 +PRN551 : 1068.734900 +PRN552 : 971.528905 +PRN553 : 1101.736300 +PRN554 : 1064.997347 +PRN555 : 1036.258822 +PRN556 : 921.038528 +PRN557 : 1009.332591 +PRN558 : 908.767369 +PRN559 : 950.432316 +PRN560 : 1025.848851 +PRN561 : 1026.275418 +PRN562 : 1027.138158 +PRN563 : 891.008164 +PRN564 : 966.635315 +PRN565 : 1105.694983 +PRN566 : 901.168653 +PRN567 : 1005.085680 +PRN568 : 986.376781 +PRN569 : 1021.988728 +PRN570 : 1032.032304 +PRN571 : 1066.922843 +PRN572 : 978.165759 +PRN573 : 985.471003 +PRN574 : 1018.542739 +PRN575 : 1104.217604 +PRN576 : 993.366411 +PRN577 : 908.428162 +PRN578 : 1030.181215 +PRN579 : 959.654949 +PRN580 : 1001.943741 +PRN581 : 1024.829762 +PRN582 : 912.207242 +PRN583 : 1016.092124 +PRN584 : 944.519752 +PRN585 : 1115.606496 +PRN586 : 884.228571 +PRN587 : 1080.684296 +PRN588 : 1000.544389 +PRN589 : 1018.277531 +PRN590 : 1069.476533 +PRN591 : 972.380515 +PRN592 : 979.162973 +PRN593 : 1040.650719 +PRN594 : 962.376923 +PRN595 : 929.303273 +PRN596 : 977.208942 +PRN597 : 1009.877287 +PRN598 : 946.361825 +PRN599 : 937.358872 +PRN600 : 1045.706701 +PRN601 : 1001.353164 +PRN602 : 1071.691606 +PRN603 : 1020.971714 +PRN604 : 957.623404 +PRN605 : 970.896382 +PRN606 : 941.442249 +PRN607 : 945.406684 +PRN608 : 980.972425 +PRN609 : 969.174424 +PRN610 : 1031.894081 +PRN611 : 1029.095046 +PRN612 : 957.535746 +PRN613 : 943.186463 +PRN614 : 955.065383 +PRN615 : 988.925782 +PRN616 : 969.603025 +PRN617 : 976.321914 +PRN618 : 1081.982260 +PRN619 : 1021.381110 +PRN620 : 978.594813 +PRN621 : 991.522599 +PRN622 : 1056.221346 +PRN623 : 1005.261003 +PRN624 : 938.437253 +PRN625 : 1005.952092 +PRN626 : 1034.131845 +PRN627 : 1026.000397 +PRN628 : 1056.506798 +PRN629 : 1007.883782 +PRN630 : 948.805620 +PRN631 : 926.033432 +PRN632 : 929.683971 +PRN633 : 1084.549770 +PRN634 : 939.995126 +PRN635 : 1017.329087 +PRN636 : 929.734793 +PRN637 : 968.947835 +PRN638 : 992.543787 +PRN639 : 1051.439605 +PRN640 : 962.215123 +PRN641 : 934.669279 +PRN642 : 873.191979 +PRN643 : 978.156276 +PRN644 : 1036.169440 +PRN645 : 1009.123122 +PRN646 : 1042.696787 +PRN647 : 1004.992474 +PRN648 : 985.307029 +PRN649 : 914.993369 +PRN650 : 883.268853 +PRN651 : 978.492871 +PRN652 : 1037.468856 +PRN653 : 903.697832 +PRN654 : 1016.299145 +PRN655 : 1032.662729 +PRN656 : 971.860043 +PRN657 : 876.217640 +PRN658 : 1076.128497 +PRN659 : 967.662496 +PRN660 : 1118.152109 +PRN661 : 959.402400 +PRN662 : 931.127652 +PRN663 : 963.395502 +PRN664 : 985.039373 +PRN665 : 1130.966014 +PRN666 : 1015.222803 +PRN667 : 979.416557 +PRN668 : 1044.451714 +PRN669 : 1013.521435 +PRN670 : 986.434595 +PRN671 : 1081.668437 +PRN672 : 1118.515896 +PRN673 : 989.972971 +PRN674 : 966.293542 +PRN675 : 960.277413 +PRN676 : 1000.049668 +PRN677 : 1082.002407 +PRN678 : 993.898160 +PRN679 : 1026.534251 +PRN680 : 962.202086 +PRN681 : 1004.697585 +PRN682 : 945.449849 +PRN683 : 1036.296061 +PRN684 : 1025.414145 +PRN685 : 1063.165272 +PRN686 : 993.281842 +PRN687 : 1024.850451 +PRN688 : 978.756895 +PRN689 : 1000.348903 +PRN690 : 886.538615 +PRN691 : 1044.053091 +PRN692 : 1011.514352 +PRN693 : 977.162158 +PRN694 : 1040.123413 +PRN695 : 1049.348768 +PRN696 : 1070.281599 +PRN697 : 994.095158 +PRN698 : 998.311277 +PRN699 : 996.305247 +PRN700 : 926.604115 +PRN701 : 1000.046728 +PRN702 : 992.973540 +PRN703 : 1001.014210 +PRN704 : 950.900234 +PRN705 : 1074.602127 +PRN706 : 987.731174 +PRN707 : 946.971275 +PRN708 : 1027.578158 +PRN709 : 1024.011220 +PRN710 : 959.145194 +PRN711 : 1006.423937 +PRN712 : 981.213721 +PRN713 : 1044.065461 +PRN714 : 979.223485 +PRN715 : 1008.857033 +PRN716 : 1043.892450 +PRN717 : 1060.529980 +PRN718 : 933.250802 +PRN719 : 1061.461152 +PRN720 : 961.259637 +PRN721 : 1058.283064 +PRN722 : 1011.319119 +PRN723 : 996.167947 +PRN724 : 1037.665974 +PRN725 : 865.574895 +PRN726 : 1002.911144 +PRN727 : 978.886205 +PRN728 : 1002.302369 +PRN729 : 945.213366 +PRN730 : 1049.330526 +PRN731 : 1011.089995 +PRN732 : 911.273000 +PRN733 : 1030.796132 +PRN734 : 1101.699446 +PRN735 : 868.524288 +PRN736 : 951.807712 +PRN737 : 997.957367 +PRN738 : 953.791979 +PRN739 : 954.430760 +PRN740 : 993.834055 +PRN741 : 1021.300808 +PRN742 : 891.272906 +PRN743 : 879.577939 +PRN744 : 1093.176950 +PRN745 : 961.198091 +PRN746 : 976.086349 +PRN747 : 900.514535 +PRN748 : 911.711376 +PRN749 : 975.997454 +PRN750 : 1007.292432 +PRN751 : 1023.266464 +PRN752 : 1066.723102 +PRN753 : 1060.468262 +PRN754 : 1115.673922 +PRN755 : 1041.290534 +PRN756 : 912.248040 +PRN757 : 1034.518587 +PRN758 : 967.154895 +PRN759 : 1043.478493 +PRN760 : 1026.025257 +PRN761 : 997.795632 +PRN762 : 948.207823 +PRN763 : 970.366980 +PRN764 : 973.390941 +PRN765 : 1008.249734 +PRN766 : 965.810614 +PRN767 : 1034.368743 +PRN768 : 969.130435 +PRN769 : 939.525153 +PRN770 : 939.346863 +PRN771 : 1098.433434 +PRN772 : 973.913623 +PRN773 : 994.629391 +PRN774 : 1019.029751 +PRN775 : 999.068601 +PRN776 : 952.374565 +PRN777 : 1005.413476 +PRN778 : 1008.606450 +PRN779 : 949.586928 +PRN780 : 984.336007 +PRN781 : 966.334220 +PRN782 : 952.353697 +PRN783 : 1081.685083 +PRN784 : 1148.865924 +PRN785 : 1043.881782 +PRN786 : 950.747262 +PRN787 : 1013.342099 +PRN788 : 1021.841738 +PRN789 : 943.202183 +PRN790 : 1018.658753 +PRN791 : 1039.519748 +PRN792 : 1066.745417 +PRN793 : 991.922297 +PRN794 : 989.993508 +PRN795 : 935.256770 +PRN796 : 1049.355101 +PRN797 : 984.271969 +PRN798 : 1046.060384 +PRN799 : 1044.170052 +PRN800 : 920.720627 +PRN801 : 938.453295 +PRN802 : 980.425711 +PRN803 : 974.857425 +PRN804 : 1016.266917 +PRN805 : 1039.658764 +PRN806 : 925.171481 +PRN807 : 982.577139 +PRN808 : 997.552114 +PRN809 : 1063.108389 +PRN810 : 927.965656 +PRN811 : 1049.828313 +PRN812 : 1012.506665 +PRN813 : 962.613627 +PRN814 : 915.580235 +PRN815 : 1003.806599 +PRN816 : 1086.454522 +PRN817 : 968.915000 +PRN818 : 1008.546559 +PRN819 : 856.499306 +PRN820 : 960.536031 +PRN821 : 1025.778766 +PRN822 : 1071.326673 +PRN823 : 993.205599 +PRN824 : 1052.750624 +PRN825 : 1040.987166 +PRN826 : 1034.039072 +PRN827 : 963.048804 +PRN828 : 970.510949 +PRN829 : 1049.829816 +PRN830 : 934.945358 +PRN831 : 980.925084 +PRN832 : 1037.321718 +PRN833 : 1031.532551 +PRN834 : 1049.045828 +PRN835 : 1086.751941 +PRN836 : 1036.770670 +PRN837 : 1032.479988 +PRN838 : 957.264581 +PRN839 : 982.586134 +PRN840 : 1002.144549 +PRN841 : 856.221346 +PRN842 : 1077.732261 +PRN843 : 1023.844204 +PRN844 : 1049.015013 +PRN845 : 1109.868706 +PRN846 : 1032.030843 +PRN847 : 994.431051 +PRN848 : 999.263384 +PRN849 : 1052.311112 +PRN850 : 955.831734 +PRN851 : 958.864423 +PRN852 : 1016.728795 +PRN853 : 1004.874796 +PRN854 : 1004.259084 +PRN855 : 963.819718 +PRN856 : 949.755330 +PRN857 : 987.900168 +PRN858 : 995.226017 +PRN859 : 1098.708859 +PRN860 : 1009.514337 +PRN861 : 948.777253 +PRN862 : 982.680500 +PRN863 : 996.028285 +PRN864 : 1029.124415 +PRN865 : 942.101818 +PRN866 : 1034.222040 +PRN867 : 949.348550 +PRN868 : 965.963597 +PRN869 : 995.021503 +PRN870 : 889.653326 +PRN871 : 951.899055 +PRN872 : 1038.667756 +PRN873 : 1088.885329 +PRN874 : 979.471141 +PRN875 : 1027.647348 +PRN876 : 1054.157446 +PRN877 : 1003.472116 +PRN878 : 914.016815 +PRN879 : 1034.862598 +PRN880 : 936.253104 +PRN881 : 962.254857 +PRN882 : 1042.166034 +PRN883 : 934.618156 +PRN884 : 939.923222 +PRN885 : 998.649324 +PRN886 : 986.753492 +PRN887 : 1095.450118 +PRN888 : 982.660119 +PRN889 : 947.149665 +PRN890 : 893.930985 +PRN891 : 956.589953 +PRN892 : 1067.312301 +PRN893 : 952.406240 +PRN894 : 986.728920 +PRN895 : 1030.999219 +PRN896 : 993.306628 +PRN897 : 972.230094 +PRN898 : 993.227094 +PRN899 : 1008.926188 +PRN900 : 976.391192 +PRN901 : 952.545561 +PRN902 : 1011.157462 +PRN903 : 1056.357455 +PRN904 : 1027.929510 +PRN905 : 986.749151 +PRN906 : 963.462803 +PRN907 : 988.772926 +PRN908 : 1031.930882 +PRN909 : 981.130300 +PRN910 : 1073.463235 +PRN911 : 1081.696380 +PRN912 : 1020.678551 +PRN913 : 906.544270 +PRN914 : 1097.495849 +PRN915 : 1113.146380 +PRN916 : 1058.443029 +PRN917 : 902.487848 +PRN918 : 1009.914281 +PRN919 : 1057.100054 +PRN920 : 940.428079 +PRN921 : 941.473058 +PRN922 : 905.716759 +PRN923 : 997.789107 +PRN924 : 962.306176 +PRN925 : 1072.504216 +PRN926 : 946.554822 +PRN927 : 972.932223 +PRN928 : 1024.961360 +PRN929 : 1080.513692 +PRN930 : 1047.137658 +PRN931 : 1012.824933 +PRN932 : 976.404512 +PRN933 : 895.604509 +PRN934 : 1114.446905 +PRN935 : 1051.342533 +PRN936 : 1027.204609 +PRN937 : 917.811842 +PRN938 : 882.306487 +PRN939 : 1010.444766 +PRN940 : 978.686109 +PRN941 : 1020.585581 +PRN942 : 989.944335 +PRN943 : 1010.484323 +PRN944 : 936.727744 +PRN945 : 1038.631446 +PRN946 : 1012.530572 +PRN947 : 961.577357 +PRN948 : 988.253770 +PRN949 : 1054.353206 +PRN950 : 964.120426 +PRN951 : 943.486864 +PRN952 : 1052.650937 +PRN953 : 980.334313 +PRN954 : 1137.186817 +PRN955 : 1125.255968 +PRN956 : 964.830093 +PRN957 : 930.646626 +PRN958 : 1043.519941 +PRN959 : 1088.829938 +PRN960 : 1024.017051 +PRN961 : 1065.574266 +PRN962 : 1008.740833 +PRN963 : 972.421950 +PRN964 : 1082.991316 +PRN965 : 963.163028 +PRN966 : 1040.184197 +PRN967 : 865.234238 +PRN968 : 1026.703665 +PRN969 : 991.758625 +PRN970 : 1091.021716 +PRN971 : 1079.872892 +PRN972 : 1042.401875 +PRN973 : 1085.624604 +PRN974 : 1055.314437 +PRN975 : 1138.344149 +PRN976 : 906.958400 +PRN977 : 954.641162 +PRN978 : 1014.840472 +PRN979 : 991.906864 +PRN980 : 947.716713 +PRN981 : 1075.346169 +PRN982 : 913.043943 +PRN983 : 1006.107228 +PRN984 : 940.937691 +PRN985 : 925.827770 +PRN986 : 870.001279 +PRN987 : 1093.348026 +PRN988 : 990.938631 +PRN989 : 1067.552107 +PRN990 : 936.441162 +PRN991 : 956.066787 +PRN992 : 1001.705214 +PRN993 : 1007.198453 +PRN994 : 956.883661 +PRN995 : 1033.645356 +PRN996 : 1036.395999 +PRN997 : 954.941658 +PRN998 : 1015.720547 +PRN999 : 1023.147999 +sample mean : 1000.303825 +true mean : 1000.000000 +sample stddev: 53.233584 +true stddev : 53.000000 +z-score : 0.181279 +p-value : 0.428600 +QH[normality]: 1.015347 From 1d0bad421ceb5c0040819a0c9f8e66a7bf4a5fd2 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 8 Mar 2017 11:29:40 +0100 Subject: [PATCH 1055/3374] avutil/tests/lfg: Remove debugging start/stop timer Fixes code with qemu ARM Signed-off-by: Michael Niedermayer --- libavutil/tests/lfg.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/libavutil/tests/lfg.c b/libavutil/tests/lfg.c index 9e908d2a9086f..bf127e30316cc 100644 --- a/libavutil/tests/lfg.c +++ b/libavutil/tests/lfg.c @@ -104,15 +104,12 @@ int main(void) int x = 0; int i, j; AVLFG state; - av_lfg_init(&state, 0xdeadbeef); for (j = 0; j < 10000; j++) { - START_TIMER for (i = 0; i < 624; i++) { //av_log(NULL, AV_LOG_ERROR, "%X\n", av_lfg_get(&state)); x += av_lfg_get(&state); } - STOP_TIMER("624 calls of av_lfg_get"); } av_log(NULL, AV_LOG_ERROR, "final value:%X\n", x); From fe57bf7cd6ac8ffd8bcc398d50150cab1e55f84c Mon Sep 17 00:00:00 2001 From: Muhammad Faiz Date: Wed, 8 Mar 2017 21:51:02 +0700 Subject: [PATCH 1056/3374] fate/swresample: fix FUZZ typo unintentionally changed to 0.01 at '61926b6c3e560283ef6c015d6d85c32716942833' Signed-off-by: Muhammad Faiz --- tests/fate/libswresample.mak | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fate/libswresample.mak b/tests/fate/libswresample.mak index f2967cdd2b9be..d07d0270ef8ae 100644 --- a/tests/fate/libswresample.mak +++ b/tests/fate/libswresample.mak @@ -362,7 +362,7 @@ fate-swr-resample_async-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/dat fate-swr-resample_async-$(3)-$(1)-$(2): CMP = stddev fate-swr-resample_async-$(3)-$(1)-$(2): CMP_UNIT = $(5) -fate-swr-resample_async-$(3)-$(1)-$(2): FUZZ = 0.01 +fate-swr-resample_async-$(3)-$(1)-$(2): FUZZ = 0.1 fate-swr-resample_async-$(3)-$(1)-$(2): REF = tests/data/asynth-$(1)-1.wav endef From 01a33b835f7a9e135eb8c7b7dd98c8b89f15dea1 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 6 Mar 2017 21:33:18 +0100 Subject: [PATCH 1057/3374] avcodec/pictordec: Fix runtime error: left shift of 64 by 25 places cannot be represented in type 'int' Fixes: 724/clusterfuzz-testcase-6738249571631104 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/pictordec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/pictordec.c b/libavcodec/pictordec.c index a09ee379c0237..2dbc040b5ca11 100644 --- a/libavcodec/pictordec.c +++ b/libavcodec/pictordec.c @@ -57,7 +57,7 @@ static void picmemset_8bpp(PicContext *s, AVFrame *frame, int value, int run, } } -static void picmemset(PicContext *s, AVFrame *frame, int value, int run, +static void picmemset(PicContext *s, AVFrame *frame, unsigned value, int run, int *x, int *y, int *plane, int bits_per_plane) { uint8_t *d; From 3016e919d4e1d90da98af19ce2a9d4979506eaf3 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 6 Mar 2017 21:52:36 +0100 Subject: [PATCH 1058/3374] avcodec/wavpack: Fix runtime error: left shift of negative value -5 Fixes: 729/clusterfuzz-testcase-5154831595470848 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/wavpack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index a4ba07fc834d7..943e46a25cae9 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -273,7 +273,7 @@ static inline int wv_get_value_integer(WavpackFrameContext *s, uint32_t *crc, unsigned bit; if (s->extra_bits) { - S <<= s->extra_bits; + S *= 1 << s->extra_bits; if (s->got_extra_bits && get_bits_left(&s->gb_extra_bits) >= s->extra_bits) { From 53a5cea478616d2caa1c07aa58b6b911bd80c285 Mon Sep 17 00:00:00 2001 From: Muhammad Faiz Date: Wed, 8 Mar 2017 22:21:34 +0700 Subject: [PATCH 1059/3374] swresample/resample: do not allow odd filter_length except filter_length == 1 odd filter_length gives worse frequency response, even when compared with shorter filter_length also makes build_filter simpler Reviewed-by: Michael Niedermayer Signed-off-by: Muhammad Faiz --- libswresample/resample.c | 56 +++++++++----------------- tests/fate/libswresample.mak | 76 ++++++++++++++++++------------------ 2 files changed, 56 insertions(+), 76 deletions(-) diff --git a/libswresample/resample.c b/libswresample/resample.c index b0d14d1e95676..8f3428f512b79 100644 --- a/libswresample/resample.c +++ b/libswresample/resample.c @@ -155,6 +155,8 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap if (!tab || !sin_lut) goto fail; + av_assert0(tap_count == 1 || tap_count % 2 == 0); + /* if upsampling, only need to interpolate, no filter */ if (factor > 1.0) factor = 1.0; @@ -165,7 +167,7 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap } for(ph = 0; ph < ph_nb; ph++) { s = sin_lut[ph]; - for(i=0;i<=tap_count;i++) { + for(i=0;i 1) + filter_length = FFALIGN(filter_length, 2); if (exact_rational) { int phase_count_exact, phase_count_exact_den; @@ -320,7 +300,7 @@ static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_r } if (!c || c->phase_count != phase_count || c->linear!=linear || c->factor != factor - || c->filter_length != FFMAX((int)ceil(filter_size/factor), 1) || c->format != format + || c->filter_length != filter_length || c->format != format || c->filter_type != filter_type || c->kaiser_beta != kaiser_beta) { c = av_mallocz(sizeof(*c)); if (!c) @@ -354,7 +334,7 @@ static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_r c->phase_count = phase_count; c->linear = linear; c->factor = factor; - c->filter_length = FFMAX((int)ceil(filter_size/factor), 1); + c->filter_length = filter_length; c->filter_alloc = FFALIGN(c->filter_length, 8); c->filter_bank = av_calloc(c->filter_alloc, (phase_count+1)*c->felem_size); c->filter_type = filter_type; diff --git a/tests/fate/libswresample.mak b/tests/fate/libswresample.mak index d07d0270ef8ae..78dbde74083f9 100644 --- a/tests/fate/libswresample.mak +++ b/tests/fate/libswresample.mak @@ -26,16 +26,16 @@ endef #you can use this if you need to update it! #make -k `make fate-list | grep swr` | egrep 'TEST|stddev' | tr '\n' '@' | sed 's#TEST *\([^@]*\)@stddev: *\([0-9.]*\)[^b@]*bytes: *\([0-9]*\) */ *\([0-9]*\)@#fate-\1: CMP_TARGET = \2@fate-\1: SIZE_TOLERANCE = \3 - \4@@#g' | tr '@' '\n' -fate-swr-resample-dblp-2626-44100: CMP_TARGET = 1352.69 +fate-swr-resample-dblp-2626-44100: CMP_TARGET = 1352.67 fate-swr-resample-dblp-2626-44100: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample-dblp-2626-48000: CMP_TARGET = 1352.66 fate-swr-resample-dblp-2626-48000: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample-dblp-2626-8000: CMP_TARGET = 1353.09 +fate-swr-resample-dblp-2626-8000: CMP_TARGET = 1352.56 fate-swr-resample-dblp-2626-8000: SIZE_TOLERANCE = 31512 - 20482 -fate-swr-resample-dblp-2626-96000: CMP_TARGET = 1352.68 +fate-swr-resample-dblp-2626-96000: CMP_TARGET = 1352.67 fate-swr-resample-dblp-2626-96000: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample-dblp-44100-2626: CMP_TARGET = 185.82 @@ -62,7 +62,7 @@ fate-swr-resample-dblp-48000-8000: SIZE_TOLERANCE = 576000 - 20484 fate-swr-resample-dblp-48000-96000: CMP_TARGET = 0.47 fate-swr-resample-dblp-48000-96000: SIZE_TOLERANCE = 576000 - 20480 -fate-swr-resample-dblp-8000-2626: CMP_TARGET = 2506.02 +fate-swr-resample-dblp-8000-2626: CMP_TARGET = 2503.33 fate-swr-resample-dblp-8000-2626: SIZE_TOLERANCE = 96000 - 20486 fate-swr-resample-dblp-8000-44100: CMP_TARGET = 15.09 @@ -74,7 +74,7 @@ fate-swr-resample-dblp-8000-48000: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample-dblp-8000-96000: CMP_TARGET = 13.81 fate-swr-resample-dblp-8000-96000: SIZE_TOLERANCE = 96000 - 20480 -fate-swr-resample-dblp-96000-2626: CMP_TARGET = 675.08 +fate-swr-resample-dblp-96000-2626: CMP_TARGET = 675.07 fate-swr-resample-dblp-96000-2626: SIZE_TOLERANCE = 1152000 - 20474 fate-swr-resample-dblp-96000-44100: CMP_TARGET = 1.44 @@ -86,16 +86,16 @@ fate-swr-resample-dblp-96000-48000: SIZE_TOLERANCE = 1152000 - 20480 fate-swr-resample-dblp-96000-8000: CMP_TARGET = 58.57 fate-swr-resample-dblp-96000-8000: SIZE_TOLERANCE = 1152000 - 20496 -fate-swr-resample-fltp-2626-44100: CMP_TARGET = 1352.69 +fate-swr-resample-fltp-2626-44100: CMP_TARGET = 1352.67 fate-swr-resample-fltp-2626-44100: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample-fltp-2626-48000: CMP_TARGET = 1352.66 fate-swr-resample-fltp-2626-48000: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample-fltp-2626-8000: CMP_TARGET = 1353.09 +fate-swr-resample-fltp-2626-8000: CMP_TARGET = 1352.56 fate-swr-resample-fltp-2626-8000: SIZE_TOLERANCE = 31512 - 20482 -fate-swr-resample-fltp-2626-96000: CMP_TARGET = 1352.68 +fate-swr-resample-fltp-2626-96000: CMP_TARGET = 1352.67 fate-swr-resample-fltp-2626-96000: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample-fltp-44100-2626: CMP_TARGET = 185.82 @@ -122,7 +122,7 @@ fate-swr-resample-fltp-48000-8000: SIZE_TOLERANCE = 576000 - 20484 fate-swr-resample-fltp-48000-96000: CMP_TARGET = 0.47 fate-swr-resample-fltp-48000-96000: SIZE_TOLERANCE = 576000 - 20480 -fate-swr-resample-fltp-8000-2626: CMP_TARGET = 2506.02 +fate-swr-resample-fltp-8000-2626: CMP_TARGET = 2503.33 fate-swr-resample-fltp-8000-2626: SIZE_TOLERANCE = 96000 - 20486 fate-swr-resample-fltp-8000-44100: CMP_TARGET = 15.09 @@ -134,7 +134,7 @@ fate-swr-resample-fltp-8000-48000: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample-fltp-8000-96000: CMP_TARGET = 13.81 fate-swr-resample-fltp-8000-96000: SIZE_TOLERANCE = 96000 - 20480 -fate-swr-resample-fltp-96000-2626: CMP_TARGET = 675.08 +fate-swr-resample-fltp-96000-2626: CMP_TARGET = 675.07 fate-swr-resample-fltp-96000-2626: SIZE_TOLERANCE = 1152000 - 20474 fate-swr-resample-fltp-96000-44100: CMP_TARGET = 1.44 @@ -146,16 +146,16 @@ fate-swr-resample-fltp-96000-48000: SIZE_TOLERANCE = 1152000 - 20480 fate-swr-resample-fltp-96000-8000: CMP_TARGET = 58.57 fate-swr-resample-fltp-96000-8000: SIZE_TOLERANCE = 1152000 - 20496 -fate-swr-resample-s16p-2626-44100: CMP_TARGET = 1393.02 +fate-swr-resample-s16p-2626-44100: CMP_TARGET = 1392.98 fate-swr-resample-s16p-2626-44100: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample-s16p-2626-48000: CMP_TARGET = 1393.01 fate-swr-resample-s16p-2626-48000: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample-s16p-2626-8000: CMP_TARGET = 1393.91 +fate-swr-resample-s16p-2626-8000: CMP_TARGET = 1393.36 fate-swr-resample-s16p-2626-8000: SIZE_TOLERANCE = 31512 - 20482 -fate-swr-resample-s16p-2626-96000: CMP_TARGET = 1393.09 +fate-swr-resample-s16p-2626-96000: CMP_TARGET = 1393.07 fate-swr-resample-s16p-2626-96000: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample-s16p-44100-2626: CMP_TARGET = 185.84 @@ -182,7 +182,7 @@ fate-swr-resample-s16p-48000-8000: SIZE_TOLERANCE = 576000 - 20484 fate-swr-resample-s16p-48000-96000: CMP_TARGET = 0.73 fate-swr-resample-s16p-48000-96000: SIZE_TOLERANCE = 576000 - 20480 -fate-swr-resample-s16p-8000-2626: CMP_TARGET = 2506.02 +fate-swr-resample-s16p-8000-2626: CMP_TARGET = 2503.32 fate-swr-resample-s16p-8000-2626: SIZE_TOLERANCE = 96000 - 20486 fate-swr-resample-s16p-8000-44100: CMP_TARGET = 15.13 @@ -206,16 +206,16 @@ fate-swr-resample-s16p-96000-48000: SIZE_TOLERANCE = 1152000 - 20480 fate-swr-resample-s16p-96000-8000: CMP_TARGET = 58.60 fate-swr-resample-s16p-96000-8000: SIZE_TOLERANCE = 1152000 - 20496 -fate-swr-resample-s32p-2626-44100: CMP_TARGET = 1393.02 +fate-swr-resample-s32p-2626-44100: CMP_TARGET = 1392.99 fate-swr-resample-s32p-2626-44100: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample-s32p-2626-48000: CMP_TARGET = 1393.01 fate-swr-resample-s32p-2626-48000: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample-s32p-2626-8000: CMP_TARGET = 1393.90 +fate-swr-resample-s32p-2626-8000: CMP_TARGET = 1393.36 fate-swr-resample-s32p-2626-8000: SIZE_TOLERANCE = 31512 - 20482 -fate-swr-resample-s32p-2626-96000: CMP_TARGET = 1393.01 +fate-swr-resample-s32p-2626-96000: CMP_TARGET = 1393.00 fate-swr-resample-s32p-2626-96000: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample-s32p-44100-2626: CMP_TARGET = 185.82 @@ -242,7 +242,7 @@ fate-swr-resample-s32p-48000-8000: SIZE_TOLERANCE = 576000 - 20484 fate-swr-resample-s32p-48000-96000: CMP_TARGET = 0.47 fate-swr-resample-s32p-48000-96000: SIZE_TOLERANCE = 576000 - 20480 -fate-swr-resample-s32p-8000-2626: CMP_TARGET = 2506.02 +fate-swr-resample-s32p-8000-2626: CMP_TARGET = 2503.33 fate-swr-resample-s32p-8000-2626: SIZE_TOLERANCE = 96000 - 20486 fate-swr-resample-s32p-8000-44100: CMP_TARGET = 15.09 @@ -254,7 +254,7 @@ fate-swr-resample-s32p-8000-48000: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample-s32p-8000-96000: CMP_TARGET = 13.81 fate-swr-resample-s32p-8000-96000: SIZE_TOLERANCE = 96000 - 20480 -fate-swr-resample-s32p-96000-2626: CMP_TARGET = 675.08 +fate-swr-resample-s32p-96000-2626: CMP_TARGET = 675.07 fate-swr-resample-s32p-96000-2626: SIZE_TOLERANCE = 1152000 - 20474 fate-swr-resample-s32p-96000-44100: CMP_TARGET = 1.44 @@ -389,16 +389,16 @@ fate-swr-resample_exact-$(3)-$(1)-$(2): FUZZ = 0.1 fate-swr-resample_exact-$(3)-$(1)-$(2): REF = tests/data/asynth-$(1)-1.wav endef -fate-swr-resample_exact-dblp-2626-44100: CMP_TARGET = 1352.69 +fate-swr-resample_exact-dblp-2626-44100: CMP_TARGET = 1352.67 fate-swr-resample_exact-dblp-2626-44100: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample_exact-dblp-2626-48000: CMP_TARGET = 1352.66 fate-swr-resample_exact-dblp-2626-48000: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample_exact-dblp-2626-8000: CMP_TARGET = 1353.09 +fate-swr-resample_exact-dblp-2626-8000: CMP_TARGET = 1352.56 fate-swr-resample_exact-dblp-2626-8000: SIZE_TOLERANCE = 31512 - 20482 -fate-swr-resample_exact-dblp-2626-96000: CMP_TARGET = 1352.68 +fate-swr-resample_exact-dblp-2626-96000: CMP_TARGET = 1352.67 fate-swr-resample_exact-dblp-2626-96000: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample_exact-dblp-44100-2626: CMP_TARGET = 185.82 @@ -425,7 +425,7 @@ fate-swr-resample_exact-dblp-48000-8000: SIZE_TOLERANCE = 576000 - 20484 fate-swr-resample_exact-dblp-48000-96000: CMP_TARGET = 0.47 fate-swr-resample_exact-dblp-48000-96000: SIZE_TOLERANCE = 576000 - 20480 -fate-swr-resample_exact-dblp-8000-2626: CMP_TARGET = 2506.02 +fate-swr-resample_exact-dblp-8000-2626: CMP_TARGET = 2503.33 fate-swr-resample_exact-dblp-8000-2626: SIZE_TOLERANCE = 96000 - 20486 fate-swr-resample_exact-dblp-8000-44100: CMP_TARGET = 14.59 @@ -437,7 +437,7 @@ fate-swr-resample_exact-dblp-8000-48000: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample_exact-dblp-8000-96000: CMP_TARGET = 13.62 fate-swr-resample_exact-dblp-8000-96000: SIZE_TOLERANCE = 96000 - 20480 -fate-swr-resample_exact-dblp-96000-2626: CMP_TARGET = 675.08 +fate-swr-resample_exact-dblp-96000-2626: CMP_TARGET = 675.07 fate-swr-resample_exact-dblp-96000-2626: SIZE_TOLERANCE = 1152000 - 20474 fate-swr-resample_exact-dblp-96000-44100: CMP_TARGET = 1.23 @@ -449,16 +449,16 @@ fate-swr-resample_exact-dblp-96000-48000: SIZE_TOLERANCE = 1152000 - 20480 fate-swr-resample_exact-dblp-96000-8000: CMP_TARGET = 58.52 fate-swr-resample_exact-dblp-96000-8000: SIZE_TOLERANCE = 1152000 - 20496 -fate-swr-resample_exact-fltp-2626-44100: CMP_TARGET = 1352.69 +fate-swr-resample_exact-fltp-2626-44100: CMP_TARGET = 1352.67 fate-swr-resample_exact-fltp-2626-44100: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample_exact-fltp-2626-48000: CMP_TARGET = 1352.66 fate-swr-resample_exact-fltp-2626-48000: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample_exact-fltp-2626-8000: CMP_TARGET = 1353.09 +fate-swr-resample_exact-fltp-2626-8000: CMP_TARGET = 1352.56 fate-swr-resample_exact-fltp-2626-8000: SIZE_TOLERANCE = 31512 - 20482 -fate-swr-resample_exact-fltp-2626-96000: CMP_TARGET = 1352.68 +fate-swr-resample_exact-fltp-2626-96000: CMP_TARGET = 1352.67 fate-swr-resample_exact-fltp-2626-96000: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample_exact-fltp-44100-2626: CMP_TARGET = 185.82 @@ -485,7 +485,7 @@ fate-swr-resample_exact-fltp-48000-8000: SIZE_TOLERANCE = 576000 - 20484 fate-swr-resample_exact-fltp-48000-96000: CMP_TARGET = 0.47 fate-swr-resample_exact-fltp-48000-96000: SIZE_TOLERANCE = 576000 - 20480 -fate-swr-resample_exact-fltp-8000-2626: CMP_TARGET = 2506.02 +fate-swr-resample_exact-fltp-8000-2626: CMP_TARGET = 2503.33 fate-swr-resample_exact-fltp-8000-2626: SIZE_TOLERANCE = 96000 - 20486 fate-swr-resample_exact-fltp-8000-44100: CMP_TARGET = 14.59 @@ -497,7 +497,7 @@ fate-swr-resample_exact-fltp-8000-48000: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample_exact-fltp-8000-96000: CMP_TARGET = 13.62 fate-swr-resample_exact-fltp-8000-96000: SIZE_TOLERANCE = 96000 - 20480 -fate-swr-resample_exact-fltp-96000-2626: CMP_TARGET = 675.08 +fate-swr-resample_exact-fltp-96000-2626: CMP_TARGET = 675.07 fate-swr-resample_exact-fltp-96000-2626: SIZE_TOLERANCE = 1152000 - 20474 fate-swr-resample_exact-fltp-96000-44100: CMP_TARGET = 1.23 @@ -509,16 +509,16 @@ fate-swr-resample_exact-fltp-96000-48000: SIZE_TOLERANCE = 1152000 - 20480 fate-swr-resample_exact-fltp-96000-8000: CMP_TARGET = 58.52 fate-swr-resample_exact-fltp-96000-8000: SIZE_TOLERANCE = 1152000 - 20496 -fate-swr-resample_exact-s16p-2626-44100: CMP_TARGET = 1393.02 +fate-swr-resample_exact-s16p-2626-44100: CMP_TARGET = 1392.98 fate-swr-resample_exact-s16p-2626-44100: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample_exact-s16p-2626-48000: CMP_TARGET = 1393.01 fate-swr-resample_exact-s16p-2626-48000: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample_exact-s16p-2626-8000: CMP_TARGET = 1393.91 +fate-swr-resample_exact-s16p-2626-8000: CMP_TARGET = 1393.36 fate-swr-resample_exact-s16p-2626-8000: SIZE_TOLERANCE = 31512 - 20482 -fate-swr-resample_exact-s16p-2626-96000: CMP_TARGET = 1393.09 +fate-swr-resample_exact-s16p-2626-96000: CMP_TARGET = 1393.07 fate-swr-resample_exact-s16p-2626-96000: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample_exact-s16p-44100-2626: CMP_TARGET = 185.84 @@ -545,7 +545,7 @@ fate-swr-resample_exact-s16p-48000-8000: SIZE_TOLERANCE = 576000 - 20484 fate-swr-resample_exact-s16p-48000-96000: CMP_TARGET = 0.73 fate-swr-resample_exact-s16p-48000-96000: SIZE_TOLERANCE = 576000 - 20480 -fate-swr-resample_exact-s16p-8000-2626: CMP_TARGET = 2506.02 +fate-swr-resample_exact-s16p-8000-2626: CMP_TARGET = 2503.32 fate-swr-resample_exact-s16p-8000-2626: SIZE_TOLERANCE = 96000 - 20486 fate-swr-resample_exact-s16p-8000-44100: CMP_TARGET = 14.63 @@ -569,16 +569,16 @@ fate-swr-resample_exact-s16p-96000-48000: SIZE_TOLERANCE = 1152000 - 20480 fate-swr-resample_exact-s16p-96000-8000: CMP_TARGET = 58.56 fate-swr-resample_exact-s16p-96000-8000: SIZE_TOLERANCE = 1152000 - 20496 -fate-swr-resample_exact-s32p-2626-44100: CMP_TARGET = 1393.02 +fate-swr-resample_exact-s32p-2626-44100: CMP_TARGET = 1392.99 fate-swr-resample_exact-s32p-2626-44100: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample_exact-s32p-2626-48000: CMP_TARGET = 1393.01 fate-swr-resample_exact-s32p-2626-48000: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample_exact-s32p-2626-8000: CMP_TARGET = 1393.90 +fate-swr-resample_exact-s32p-2626-8000: CMP_TARGET = 1393.36 fate-swr-resample_exact-s32p-2626-8000: SIZE_TOLERANCE = 31512 - 20482 -fate-swr-resample_exact-s32p-2626-96000: CMP_TARGET = 1393.01 +fate-swr-resample_exact-s32p-2626-96000: CMP_TARGET = 1393.00 fate-swr-resample_exact-s32p-2626-96000: SIZE_TOLERANCE = 31512 - 20480 fate-swr-resample_exact-s32p-44100-2626: CMP_TARGET = 185.82 @@ -605,7 +605,7 @@ fate-swr-resample_exact-s32p-48000-8000: SIZE_TOLERANCE = 576000 - 20484 fate-swr-resample_exact-s32p-48000-96000: CMP_TARGET = 0.47 fate-swr-resample_exact-s32p-48000-96000: SIZE_TOLERANCE = 576000 - 20480 -fate-swr-resample_exact-s32p-8000-2626: CMP_TARGET = 2506.02 +fate-swr-resample_exact-s32p-8000-2626: CMP_TARGET = 2503.33 fate-swr-resample_exact-s32p-8000-2626: SIZE_TOLERANCE = 96000 - 20486 fate-swr-resample_exact-s32p-8000-44100: CMP_TARGET = 14.59 @@ -617,7 +617,7 @@ fate-swr-resample_exact-s32p-8000-48000: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample_exact-s32p-8000-96000: CMP_TARGET = 13.62 fate-swr-resample_exact-s32p-8000-96000: SIZE_TOLERANCE = 96000 - 20480 -fate-swr-resample_exact-s32p-96000-2626: CMP_TARGET = 675.08 +fate-swr-resample_exact-s32p-96000-2626: CMP_TARGET = 675.07 fate-swr-resample_exact-s32p-96000-2626: SIZE_TOLERANCE = 1152000 - 20474 fate-swr-resample_exact-s32p-96000-44100: CMP_TARGET = 1.23 From fcfc78cbabb6b454aa9e39ad32ae7a766dcf33d8 Mon Sep 17 00:00:00 2001 From: wm4 Date: Wed, 8 Mar 2017 12:36:05 +0100 Subject: [PATCH 1060/3374] aacdec: do not mutate input packet metadata Apparently the demuxer outputs the wrong padding for HE-AAC (based on the raw sample rate, or so). aacdec contains a hack to adjust the muxer padding accordingly before it's used to trim the decoder output. This modified the packet side data, which in combination with the old decoding API would change the packet the user passed to the decoder. This is clearly not allowed, and it breaks running some gapless fate tests with "-fflags +keepside" applied (without keepside, the packet metadata is typically newly allocated, essentially making a copy and not modifying the user's input packet). This should probably be fixed in the demuxer (and consequently also the muxer), but for now only fix the immediate problem. Regression since 946ed78f5f8 (2012). --- libavcodec/aacdec_template.c | 8 ++------ libavcodec/internal.h | 2 ++ libavcodec/utils.c | 4 +++- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libavcodec/aacdec_template.c b/libavcodec/aacdec_template.c index 4367e74cf76db..98a3240597970 100644 --- a/libavcodec/aacdec_template.c +++ b/libavcodec/aacdec_template.c @@ -3095,12 +3095,8 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, ac->oc[1].status = OC_LOCKED; } - if (multiplier) { - int side_size; - const uint8_t *side = av_packet_get_side_data(avpkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size); - if (side && side_size>=4) - AV_WL32(side, 2*AV_RL32(side)); - } + if (multiplier) + avctx->internal->skip_samples_multiplier = 2; if (!ac->frame->data[0] && samples) { av_log(avctx, AV_LOG_ERROR, "no frame data found\n"); diff --git a/libavcodec/internal.h b/libavcodec/internal.h index c92dba472a0c8..e3286d2a58df1 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -174,6 +174,8 @@ typedef struct AVCodecInternal { AVFrame *buffer_frame; int draining_done; int showed_multi_packet_warning; + + int skip_samples_multiplier; } AVCodecInternal; struct AVCodecDefault { diff --git a/libavcodec/utils.c b/libavcodec/utils.c index db3adb18d4516..3c8a9cc13e056 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -1305,6 +1305,8 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code goto free_and_end; } + avctx->internal->skip_samples_multiplier = 1; + if (codec->priv_data_size > 0) { if (!avctx->priv_data) { avctx->priv_data = av_mallocz(codec->priv_data_size); @@ -2387,7 +2389,7 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, side= av_packet_get_side_data(avctx->internal->pkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size); if(side && side_size>=10) { - avctx->internal->skip_samples = AV_RL32(side); + avctx->internal->skip_samples = AV_RL32(side) * avctx->internal->skip_samples_multiplier; discard_padding = AV_RL32(side + 4); av_log(avctx, AV_LOG_DEBUG, "skip %d / discard %d samples due to side data\n", avctx->internal->skip_samples, (int)discard_padding); From f5da453b068f55d335ca403d2e2b4dd2ac3d4331 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 9 Mar 2017 15:43:00 +0100 Subject: [PATCH 1061/3374] concatdec: pass AVFormatContext flags to sub demuxer --- libavformat/concatdec.c | 1 + tests/ref/fate/concat-demuxer-simple2-lavf-ts | 192 ++++++++++++------ 2 files changed, 129 insertions(+), 64 deletions(-) diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c index 5cc239a1b6522..8649916ff22a6 100644 --- a/libavformat/concatdec.c +++ b/libavformat/concatdec.c @@ -322,6 +322,7 @@ static int open_file(AVFormatContext *avf, unsigned fileno) if (!cat->avf) return AVERROR(ENOMEM); + cat->avf->flags |= avf->flags; cat->avf->interrupt_callback = avf->interrupt_callback; if ((ret = ff_copy_whiteblacklists(cat->avf, avf)) < 0) diff --git a/tests/ref/fate/concat-demuxer-simple2-lavf-ts b/tests/ref/fate/concat-demuxer-simple2-lavf-ts index 4cb9f5ca7a0f1..880f9b7e03f42 100644 --- a/tests/ref/fate/concat-demuxer-simple2-lavf-ts +++ b/tests/ref/fate/concat-demuxer-simple2-lavf-ts @@ -1,12 +1,21 @@ -video|1|982|0.010911|-2618|-0.029089|3600|0.040000|N/A|N/A|24815|564|K_ -video|1|4582|0.050911|982|0.010911|3600|0.040000|N/A|N/A|16443|27072|__ -video|1|8182|0.090911|4582|0.050911|3600|0.040000|N/A|N/A|14522|44932|__ -video|1|11782|0.130911|8182|0.090911|3600|0.040000|N/A|N/A|12636|60536|__ -video|1|15382|0.170911|11782|0.130911|3600|0.040000|N/A|N/A|13407|74260|__ -video|1|18982|0.210911|15382|0.170911|3600|0.040000|N/A|N/A|13106|88924|__ -video|1|22582|0.250911|18982|0.210911|3600|0.040000|N/A|N/A|12769|102836|__ -video|1|26182|0.290911|22582|0.250911|3600|0.040000|N/A|N/A|12037|116748|__ -audio|0|0|0.000000|0|0.000000|2351|0.026122|N/A|N/A|222|159988|K_ +video|1|982|0.010911|-2618|-0.029089|3600|0.040000|N/A|N/A|24801|564|K_MPEGTS Stream ID|1 + +video|1|4582|0.050911|982|0.010911|3600|0.040000|N/A|N/A|16429|27072|__MPEGTS Stream ID|1 + +video|1|8182|0.090911|4582|0.050911|3600|0.040000|N/A|N/A|14508|44932|__MPEGTS Stream ID|1 + +video|1|11782|0.130911|8182|0.090911|3600|0.040000|N/A|N/A|12622|60536|__MPEGTS Stream ID|1 + +video|1|15382|0.170911|11782|0.130911|3600|0.040000|N/A|N/A|13393|74260|__MPEGTS Stream ID|1 + +video|1|18982|0.210911|15382|0.170911|3600|0.040000|N/A|N/A|13092|88924|__MPEGTS Stream ID|1 + +video|1|22582|0.250911|18982|0.210911|3600|0.040000|N/A|N/A|12755|102836|__MPEGTS Stream ID|1 + +video|1|26182|0.290911|22582|0.250911|3600|0.040000|N/A|N/A|12023|116748|__MPEGTS Stream ID|1 + +audio|0|0|0.000000|0|0.000000|2351|0.026122|N/A|N/A|208|159988|K_MPEGTS Stream ID|1 + audio|0|2351|0.026122|2351|0.026122|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|4702|0.052244|4702|0.052244|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|7053|0.078367|7053|0.078367|2351|0.026122|N/A|N/A|209|N/A|K_ @@ -20,17 +29,28 @@ audio|0|23510|0.261222|23510|0.261222|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|25861|0.287344|25861|0.287344|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|28212|0.313467|28212|0.313467|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|30563|0.339589|30563|0.339589|2351|0.026122|N/A|N/A|209|N/A|K_ -video|1|29782|0.330911|26182|0.290911|3600|0.040000|N/A|N/A|14112|130096|__ -video|1|33382|0.370911|29782|0.330911|3600|0.040000|N/A|N/A|13343|145324|__ -video|1|36982|0.410911|33382|0.370911|3600|0.040000|N/A|N/A|12149|162996|__ -video|1|40582|0.450911|36982|0.410911|3600|0.040000|N/A|N/A|12296|176344|__ -video|1|44182|0.490911|40582|0.450911|3600|0.040000|N/A|N/A|24800|189692|K_ -video|1|47782|0.530911|44182|0.490911|3600|0.040000|N/A|N/A|17454|216388|__ -video|1|51382|0.570911|47782|0.530911|3600|0.040000|N/A|N/A|15033|235000|__ -video|1|54982|0.610911|51382|0.570911|3600|0.040000|N/A|N/A|13463|251356|__ -video|1|58582|0.650911|54982|0.610911|3600|0.040000|N/A|N/A|12412|266020|__ -video|1|62182|0.690911|58582|0.650911|3600|0.040000|N/A|N/A|13469|279744|__ -audio|0|32915|0.365722|32915|0.365722|2351|0.026122|N/A|N/A|223|322608|K_ +video|1|29782|0.330911|26182|0.290911|3600|0.040000|N/A|N/A|14098|130096|__MPEGTS Stream ID|1 + +video|1|33382|0.370911|29782|0.330911|3600|0.040000|N/A|N/A|13329|145324|__MPEGTS Stream ID|1 + +video|1|36982|0.410911|33382|0.370911|3600|0.040000|N/A|N/A|12135|162996|__MPEGTS Stream ID|1 + +video|1|40582|0.450911|36982|0.410911|3600|0.040000|N/A|N/A|12282|176344|__MPEGTS Stream ID|1 + +video|1|44182|0.490911|40582|0.450911|3600|0.040000|N/A|N/A|24786|189692|K_MPEGTS Stream ID|1 + +video|1|47782|0.530911|44182|0.490911|3600|0.040000|N/A|N/A|17440|216388|__MPEGTS Stream ID|1 + +video|1|51382|0.570911|47782|0.530911|3600|0.040000|N/A|N/A|15019|235000|__MPEGTS Stream ID|1 + +video|1|54982|0.610911|51382|0.570911|3600|0.040000|N/A|N/A|13449|251356|__MPEGTS Stream ID|1 + +video|1|58582|0.650911|54982|0.610911|3600|0.040000|N/A|N/A|12398|266020|__MPEGTS Stream ID|1 + +video|1|62182|0.690911|58582|0.650911|3600|0.040000|N/A|N/A|13455|279744|__MPEGTS Stream ID|1 + +audio|0|32915|0.365722|32915|0.365722|2351|0.026122|N/A|N/A|209|322608|K_MPEGTS Stream ID|1 + audio|0|35266|0.391844|35266|0.391844|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|37617|0.417967|37617|0.417967|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|39968|0.444089|39968|0.444089|2351|0.026122|N/A|N/A|209|N/A|K_ @@ -44,12 +64,18 @@ audio|0|56425|0.626944|56425|0.626944|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|58776|0.653067|58776|0.653067|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|61127|0.679189|61127|0.679189|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|63478|0.705311|63478|0.705311|2351|0.026122|N/A|N/A|209|N/A|K_ -video|1|65782|0.730911|62182|0.690911|3600|0.040000|N/A|N/A|13850|294408|__ -video|1|69382|0.770911|65782|0.730911|3600|0.040000|N/A|N/A|12177|309448|__ -video|1|72982|0.810911|69382|0.770911|3600|0.040000|N/A|N/A|12706|325992|__ -video|1|76582|0.850911|72982|0.810911|3600|0.040000|N/A|N/A|10838|339528|__ -video|1|80182|0.890911|76582|0.850911|3600|0.040000|N/A|N/A|11300|351372|__ -audio|0|65829|0.731433|65829|0.731433|2351|0.026122|N/A|N/A|223|404576|K_ +video|1|65782|0.730911|62182|0.690911|3600|0.040000|N/A|N/A|13836|294408|__MPEGTS Stream ID|1 + +video|1|69382|0.770911|65782|0.730911|3600|0.040000|N/A|N/A|12163|309448|__MPEGTS Stream ID|1 + +video|1|72982|0.810911|69382|0.770911|3600|0.040000|N/A|N/A|12692|325992|__MPEGTS Stream ID|1 + +video|1|76582|0.850911|72982|0.810911|3600|0.040000|N/A|N/A|10824|339528|__MPEGTS Stream ID|1 + +video|1|80182|0.890911|76582|0.850911|3600|0.040000|N/A|N/A|11286|351372|__MPEGTS Stream ID|1 + +audio|0|65829|0.731433|65829|0.731433|2351|0.026122|N/A|N/A|209|404576|K_MPEGTS Stream ID|1 + audio|0|68180|0.757556|68180|0.757556|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|70531|0.783678|70531|0.783678|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|72882|0.809800|72882|0.809800|2351|0.026122|N/A|N/A|209|N/A|K_ @@ -60,17 +86,27 @@ audio|0|82286|0.914289|82286|0.914289|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|84637|0.940411|84637|0.940411|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|86988|0.966533|86988|0.966533|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|89339|0.992656|89339|0.992656|2351|0.026122|N/A|N/A|209|N/A|K_ -video|1|83782|0.930911|80182|0.890911|3600|0.040000|N/A|N/A|12692|363592|__ +video|1|83782|0.930911|80182|0.890911|3600|0.040000|N/A|N/A|12678|363592|__MPEGTS Stream ID|1 + video|1|87382|0.970911|83782|0.930911|3600|0.040000|N/A|N/A|24711|377880|K_ -video|1|91964|1.021822|88364|0.981822|3600|0.040000|N/A|N/A|24815|564|K_ -video|1|95564|1.061822|91964|1.021822|3600|0.040000|N/A|N/A|16443|27072|__ -video|1|99164|1.101822|95564|1.061822|3600|0.040000|N/A|N/A|14522|44932|__ -video|1|102764|1.141822|99164|1.101822|3600|0.040000|N/A|N/A|12636|60536|__ -video|1|106364|1.181822|102764|1.141822|3600|0.040000|N/A|N/A|13407|74260|__ -video|1|109964|1.221822|106364|1.181822|3600|0.040000|N/A|N/A|13106|88924|__ -video|1|113564|1.261822|109964|1.221822|3600|0.040000|N/A|N/A|12769|102836|__ -video|1|117164|1.301822|113564|1.261822|3600|0.040000|N/A|N/A|12037|116748|__ -audio|0|90982|1.010911|90982|1.010911|2351|0.026122|N/A|N/A|222|159988|K_ +video|1|91964|1.021822|88364|0.981822|3600|0.040000|N/A|N/A|24801|564|K_MPEGTS Stream ID|1 + +video|1|95564|1.061822|91964|1.021822|3600|0.040000|N/A|N/A|16429|27072|__MPEGTS Stream ID|1 + +video|1|99164|1.101822|95564|1.061822|3600|0.040000|N/A|N/A|14508|44932|__MPEGTS Stream ID|1 + +video|1|102764|1.141822|99164|1.101822|3600|0.040000|N/A|N/A|12622|60536|__MPEGTS Stream ID|1 + +video|1|106364|1.181822|102764|1.141822|3600|0.040000|N/A|N/A|13393|74260|__MPEGTS Stream ID|1 + +video|1|109964|1.221822|106364|1.181822|3600|0.040000|N/A|N/A|13092|88924|__MPEGTS Stream ID|1 + +video|1|113564|1.261822|109964|1.221822|3600|0.040000|N/A|N/A|12755|102836|__MPEGTS Stream ID|1 + +video|1|117164|1.301822|113564|1.261822|3600|0.040000|N/A|N/A|12023|116748|__MPEGTS Stream ID|1 + +audio|0|90982|1.010911|90982|1.010911|2351|0.026122|N/A|N/A|208|159988|K_MPEGTS Stream ID|1 + audio|0|93333|1.037033|93333|1.037033|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|95684|1.063156|95684|1.063156|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|98035|1.089278|98035|1.089278|2351|0.026122|N/A|N/A|209|N/A|K_ @@ -84,17 +120,28 @@ audio|0|114492|1.272133|114492|1.272133|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|116843|1.298256|116843|1.298256|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|119194|1.324378|119194|1.324378|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|121545|1.350500|121545|1.350500|2351|0.026122|N/A|N/A|209|N/A|K_ -video|1|120764|1.341822|117164|1.301822|3600|0.040000|N/A|N/A|14112|130096|__ -video|1|124364|1.381822|120764|1.341822|3600|0.040000|N/A|N/A|13343|145324|__ -video|1|127964|1.421822|124364|1.381822|3600|0.040000|N/A|N/A|12149|162996|__ -video|1|131564|1.461822|127964|1.421822|3600|0.040000|N/A|N/A|12296|176344|__ -video|1|135164|1.501822|131564|1.461822|3600|0.040000|N/A|N/A|24800|189692|K_ -video|1|138764|1.541822|135164|1.501822|3600|0.040000|N/A|N/A|17454|216388|__ -video|1|142364|1.581822|138764|1.541822|3600|0.040000|N/A|N/A|15033|235000|__ -video|1|145964|1.621822|142364|1.581822|3600|0.040000|N/A|N/A|13463|251356|__ -video|1|149564|1.661822|145964|1.621822|3600|0.040000|N/A|N/A|12412|266020|__ -video|1|153164|1.701822|149564|1.661822|3600|0.040000|N/A|N/A|13469|279744|__ -audio|0|123897|1.376633|123897|1.376633|2351|0.026122|N/A|N/A|223|322608|K_ +video|1|120764|1.341822|117164|1.301822|3600|0.040000|N/A|N/A|14098|130096|__MPEGTS Stream ID|1 + +video|1|124364|1.381822|120764|1.341822|3600|0.040000|N/A|N/A|13329|145324|__MPEGTS Stream ID|1 + +video|1|127964|1.421822|124364|1.381822|3600|0.040000|N/A|N/A|12135|162996|__MPEGTS Stream ID|1 + +video|1|131564|1.461822|127964|1.421822|3600|0.040000|N/A|N/A|12282|176344|__MPEGTS Stream ID|1 + +video|1|135164|1.501822|131564|1.461822|3600|0.040000|N/A|N/A|24786|189692|K_MPEGTS Stream ID|1 + +video|1|138764|1.541822|135164|1.501822|3600|0.040000|N/A|N/A|17440|216388|__MPEGTS Stream ID|1 + +video|1|142364|1.581822|138764|1.541822|3600|0.040000|N/A|N/A|15019|235000|__MPEGTS Stream ID|1 + +video|1|145964|1.621822|142364|1.581822|3600|0.040000|N/A|N/A|13449|251356|__MPEGTS Stream ID|1 + +video|1|149564|1.661822|145964|1.621822|3600|0.040000|N/A|N/A|12398|266020|__MPEGTS Stream ID|1 + +video|1|153164|1.701822|149564|1.661822|3600|0.040000|N/A|N/A|13455|279744|__MPEGTS Stream ID|1 + +audio|0|123897|1.376633|123897|1.376633|2351|0.026122|N/A|N/A|209|322608|K_MPEGTS Stream ID|1 + audio|0|126248|1.402756|126248|1.402756|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|128599|1.428878|128599|1.428878|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|130950|1.455000|130950|1.455000|2351|0.026122|N/A|N/A|209|N/A|K_ @@ -108,12 +155,18 @@ audio|0|147407|1.637856|147407|1.637856|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|149758|1.663978|149758|1.663978|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|152109|1.690100|152109|1.690100|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|154460|1.716222|154460|1.716222|2351|0.026122|N/A|N/A|209|N/A|K_ -video|1|156764|1.741822|153164|1.701822|3600|0.040000|N/A|N/A|13850|294408|__ -video|1|160364|1.781822|156764|1.741822|3600|0.040000|N/A|N/A|12177|309448|__ -video|1|163964|1.821822|160364|1.781822|3600|0.040000|N/A|N/A|12706|325992|__ -video|1|167564|1.861822|163964|1.821822|3600|0.040000|N/A|N/A|10838|339528|__ -video|1|171164|1.901822|167564|1.861822|3600|0.040000|N/A|N/A|11300|351372|__ -audio|0|156811|1.742344|156811|1.742344|2351|0.026122|N/A|N/A|223|404576|K_ +video|1|156764|1.741822|153164|1.701822|3600|0.040000|N/A|N/A|13836|294408|__MPEGTS Stream ID|1 + +video|1|160364|1.781822|156764|1.741822|3600|0.040000|N/A|N/A|12163|309448|__MPEGTS Stream ID|1 + +video|1|163964|1.821822|160364|1.781822|3600|0.040000|N/A|N/A|12692|325992|__MPEGTS Stream ID|1 + +video|1|167564|1.861822|163964|1.821822|3600|0.040000|N/A|N/A|10824|339528|__MPEGTS Stream ID|1 + +video|1|171164|1.901822|167564|1.861822|3600|0.040000|N/A|N/A|11286|351372|__MPEGTS Stream ID|1 + +audio|0|156811|1.742344|156811|1.742344|2351|0.026122|N/A|N/A|209|404576|K_MPEGTS Stream ID|1 + audio|0|159162|1.768467|159162|1.768467|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|161513|1.794589|161513|1.794589|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|163864|1.820711|163864|1.820711|2351|0.026122|N/A|N/A|209|N/A|K_ @@ -124,12 +177,17 @@ audio|0|173268|1.925200|173268|1.925200|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|175619|1.951322|175619|1.951322|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|177970|1.977444|177970|1.977444|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|180321|2.003567|180321|2.003567|2351|0.026122|N/A|N/A|209|N/A|K_ -video|1|174764|1.941822|171164|1.901822|3600|0.040000|N/A|N/A|12692|363592|__ +video|1|174764|1.941822|171164|1.901822|3600|0.040000|N/A|N/A|12678|363592|__MPEGTS Stream ID|1 + video|1|178364|1.981822|174764|1.941822|3600|0.040000|N/A|N/A|24711|377880|K_ -video|1|139582|1.550911|135982|1.510911|3600|0.040000|N/A|N/A|12706|325992|__ -video|1|143182|1.590911|139582|1.550911|3600|0.040000|N/A|N/A|10838|339528|__ -video|1|146782|1.630911|143182|1.590911|3600|0.040000|N/A|N/A|11300|351372|__ -audio|0|132429|1.471433|132429|1.471433|2351|0.026122|N/A|N/A|223|404576|K_ +video|1|139582|1.550911|135982|1.510911|3600|0.040000|N/A|N/A|12692|325992|__MPEGTS Stream ID|1 + +video|1|143182|1.590911|139582|1.550911|3600|0.040000|N/A|N/A|10824|339528|__MPEGTS Stream ID|1 + +video|1|146782|1.630911|143182|1.590911|3600|0.040000|N/A|N/A|11286|351372|__MPEGTS Stream ID|1 + +audio|0|132429|1.471433|132429|1.471433|2351|0.026122|N/A|N/A|209|404576|K_MPEGTS Stream ID|1 + audio|0|134780|1.497556|134780|1.497556|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|137131|1.523678|137131|1.523678|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|139482|1.549800|139482|1.549800|2351|0.026122|N/A|N/A|209|N/A|K_ @@ -140,12 +198,18 @@ audio|0|148886|1.654289|148886|1.654289|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|151237|1.680411|151237|1.680411|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|153588|1.706533|153588|1.706533|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|155939|1.732656|155939|1.732656|2351|0.026122|N/A|N/A|209|N/A|K_ -video|1|150382|1.670911|146782|1.630911|3600|0.040000|N/A|N/A|12692|363592|__ +video|1|150382|1.670911|146782|1.630911|3600|0.040000|N/A|N/A|12678|363592|__MPEGTS Stream ID|1 + video|1|153982|1.710911|150382|1.670911|3600|0.040000|N/A|N/A|24711|377880|K_ -video|1|161182|1.790911|157582|1.750911|3600|0.040000|N/A|N/A|12149|162996|__ -video|1|164782|1.830911|161182|1.790911|3600|0.040000|N/A|N/A|12296|176344|__ -video|1|168382|1.870911|164782|1.830911|3600|0.040000|N/A|N/A|24800|189692|K_ -video|1|171982|1.910911|168382|1.870911|3600|0.040000|N/A|N/A|17454|216388|__ -video|1|175582|1.950911|171982|1.910911|3600|0.040000|N/A|N/A|15033|235000|__ +video|1|161182|1.790911|157582|1.750911|3600|0.040000|N/A|N/A|12135|162996|__MPEGTS Stream ID|1 + +video|1|164782|1.830911|161182|1.790911|3600|0.040000|N/A|N/A|12282|176344|__MPEGTS Stream ID|1 + +video|1|168382|1.870911|164782|1.830911|3600|0.040000|N/A|N/A|24786|189692|K_MPEGTS Stream ID|1 + +video|1|171982|1.910911|168382|1.870911|3600|0.040000|N/A|N/A|17440|216388|__MPEGTS Stream ID|1 + +video|1|175582|1.950911|171982|1.910911|3600|0.040000|N/A|N/A|15019|235000|__MPEGTS Stream ID|1 + 0|mp2|unknown|audio|1/44100|[3][0][0][0]|0x0003|s16p|44100|1|mono|0|N/A|0/0|0/0|1/90000|0|0.000000|N/A|N/A|64000|N/A|N/A|N/A|N/A|89|0|0|0|0|0|0|0|0|0|0|0|0 1|mpeg2video|4|video|1/25|[2][0][0][0]|0x0002|352|288|0|0|1|1:1|11:9|yuv420p|8|tv|unknown|unknown|unknown|left|progressive|N/A|1|N/A|25/1|25/1|1/90000|N/A|N/A|N/A|N/A|N/A|N/A|N/A|N/A|N/A|60|0|0|0|0|0|0|0|0|0|0|0|0 From 597c6b789efb8d3eec200eb4f38a3d8da591deec Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 9 Mar 2017 15:43:08 +0100 Subject: [PATCH 1062/3374] hls: pass AVFormatContext flags to sub demuxer --- libavformat/hls.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/hls.c b/libavformat/hls.c index 3ae3c7cc5c033..c65a9f9e87b03 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -1761,6 +1761,7 @@ static int hls_read_header(AVFormatContext *s) } pls->ctx->pb = &pls->pb; pls->ctx->io_open = nested_io_open; + pls->ctx->flags |= s->flags; if ((ret = ff_copy_whiteblacklists(pls->ctx, s)) < 0) goto fail; From f940492bb241d1cf27175f40e580c51c20d6ebc3 Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 6 Mar 2017 11:34:20 +0100 Subject: [PATCH 1063/3374] avcodec: clarify some decoding/encoding API details Make it clear that there is no timing-dependent behavior. In particular, there is no state in which both input and output are denied, and where you have to wait for a while yourself to make progress (apparently some hardware decoders like to do this). Avoid wording that makes references to time. It shouldn't be mistaken for some kind of asynchronous API (like POSIX read() can return EAGAIN if there is no new input yet). It's a state machine, so try to use appropriate terms. Signed-off-by: Diego Biurrun Merges Libav commit 8a60bba0ae. --- libavcodec/avcodec.h | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index af054f3194fdc..30ac2360e0969 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -112,6 +112,12 @@ * are filled. This situation is handled transparently if you follow the steps * outlined above. * + * In theory, sending input can result in EAGAIN - this should happen only if + * not all output was received. You can use this to structure alternative decode + * or encode loops other than the one suggested above. For example, you could + * try sending new input on each iteration, and try to receive output if that + * returns EAGAIN. + * * End of stream situations. These require "flushing" (aka draining) the codec, * as the codec might buffer multiple frames or packets internally for * performance or out of necessity (consider B-frames). @@ -146,7 +152,8 @@ * Unlike with the old video decoding API, multiple frames might result from * a packet. For audio, splitting the input packet into frames by partially * decoding packets becomes transparent to the API user. You never need to - * feed an AVPacket to the API twice. + * feed an AVPacket to the API twice (unless it is rejected with EAGAIN - then + * no data was read from the packet). * Additionally, sending a flush/draining packet is required only once. * - avcodec_encode_video2()/avcodec_encode_audio2(): * Use avcodec_send_frame() to feed input to the encoder, then use @@ -159,7 +166,22 @@ * and will result in undefined behavior. * * Some codecs might require using the new API; using the old API will return - * an error when calling it. + * an error when calling it. All codecs support the new API. + * + * A codec is not allowed to return EAGAIN for both sending and receiving. This + * would be an invalid state, which could put the codec user into an endless + * loop. The API has no concept of time either: it cannot happen that trying to + * do avcodec_send_packet() results in EAGAIN, but a repeated call 1 second + * later accepts the packet (with no other receive/flush API calls involved). + * The API is a strict state machine, and the passage of time is not supposed + * to influence it. Some timing-dependent behavior might still be deemed + * acceptable in certain cases. But it must never result in both send/receive + * returning EAGAIN at the same time at any point. It must also absolutely be + * avoided that the current state is "unstable" and can "flip-flop" between + * the send/receive APIs allowing progress. For example, it's not allowed that + * the codec randomly decides that it actually wants to consume a packet now + * instead of returning a frame, after it just returned EAGAIN on an + * avcodec_send_packet() call. * @} */ @@ -4914,8 +4936,10 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, * a flush packet. * * @return 0 on success, otherwise negative error code: - * AVERROR(EAGAIN): input is not accepted right now - the packet must be - * resent after trying to read output + * AVERROR(EAGAIN): input is not accepted in the current state - user + * must read output with avcodec_receive_frame() (once + * all output is read, the packet should be resent, and + * the call will not fail with EAGAIN). * AVERROR_EOF: the decoder has been flushed, and no new packets can * be sent to it (also returned if more than 1 flush * packet is sent) @@ -4936,7 +4960,7 @@ int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt); * * @return * 0: success, a frame was returned - * AVERROR(EAGAIN): output is not available right now - user must try + * AVERROR(EAGAIN): output is not available in this state - user must try * to send new input * AVERROR_EOF: the decoder has been fully flushed, and there will be * no more output frames @@ -4969,8 +4993,10 @@ int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame); * avctx->frame_size for all frames except the last. * The final frame may be smaller than avctx->frame_size. * @return 0 on success, otherwise negative error code: - * AVERROR(EAGAIN): input is not accepted right now - the frame must be - * resent after trying to read output packets + * AVERROR(EAGAIN): input is not accepted in the current state - user + * must read output with avcodec_receive_packet() (once + * all output is read, the packet should be resent, and + * the call will not fail with EAGAIN). * AVERROR_EOF: the encoder has been flushed, and no new frames can * be sent to it * AVERROR(EINVAL): codec not opened, refcounted_frames not set, it is a @@ -4988,8 +5014,8 @@ int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame); * encoder. Note that the function will always call * av_frame_unref(frame) before doing anything else. * @return 0 on success, otherwise negative error code: - * AVERROR(EAGAIN): output is not available right now - user must try - * to send input + * AVERROR(EAGAIN): output is not available in the current state - user + * must try to send input * AVERROR_EOF: the encoder has been fully flushed, and there will be * no more output packets * AVERROR(EINVAL): codec not opened, or it is an encoder From 58eb0f57f6702d57b6f97ec5010657bb2c076eff Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 8 Mar 2017 16:12:32 -0300 Subject: [PATCH 1064/3374] avformat/matroskaenc: add support for Spherical Video elements Reviewed-by: Vittorio Giovara Signed-off-by: James Almer --- libavformat/matroskaenc.c | 79 +++++++++++++++++++++++++++++++++++++++ libavformat/version.h | 2 +- 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 1605f0cafe3de..df77313675e06 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -918,6 +918,82 @@ static int mkv_write_video_color(AVIOContext *pb, AVCodecParameters *par, AVStre return 0; } +static int mkv_write_video_projection(AVFormatContext *s, AVIOContext *pb, AVStream *st) +{ + int side_data_size = 0; + const AVSphericalMapping *spherical = + (const AVSphericalMapping*) av_stream_get_side_data(st, AV_PKT_DATA_SPHERICAL, + &side_data_size); + + if (side_data_size) { + AVIOContext *dyn_cp; + uint8_t *projection_ptr; + int ret, projection_size; + + ret = avio_open_dyn_buf(&dyn_cp); + if (ret < 0) + return ret; + + switch (spherical->projection) { + case AV_SPHERICAL_EQUIRECTANGULAR: + put_ebml_uint(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONTYPE, + MATROSKA_VIDEO_PROJECTION_TYPE_EQUIRECTANGULAR); + break; + case AV_SPHERICAL_EQUIRECTANGULAR_TILE: + { + AVIOContext b; + uint8_t private[20]; + ffio_init_context(&b, private, sizeof(private), + 1, NULL, NULL, NULL, NULL); + put_ebml_uint(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONTYPE, + MATROSKA_VIDEO_PROJECTION_TYPE_EQUIRECTANGULAR); + avio_wb32(&b, 0); // version + flags + avio_wb32(&b, spherical->bound_top); + avio_wb32(&b, spherical->bound_bottom); + avio_wb32(&b, spherical->bound_left); + avio_wb32(&b, spherical->bound_right); + put_ebml_binary(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONPRIVATE, private, sizeof(private)); + break; + } + case AV_SPHERICAL_CUBEMAP: + { + AVIOContext b; + uint8_t private[12]; + ffio_init_context(&b, private, sizeof(private), + 1, NULL, NULL, NULL, NULL); + put_ebml_uint(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONTYPE, + MATROSKA_VIDEO_PROJECTION_TYPE_CUBEMAP); + avio_wb32(&b, 0); // version + flags + avio_wb32(&b, 0); // layout + avio_wb32(&b, spherical->padding); + put_ebml_binary(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONPRIVATE, private, sizeof(private)); + break; + } + default: + av_log(s, AV_LOG_WARNING, "Unknown projection type\n"); + goto end; + } + + if (spherical->yaw) + put_ebml_float(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONPOSEYAW, (double)spherical->yaw / (1 << 16)); + if (spherical->pitch) + put_ebml_float(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONPOSEPITCH, (double)spherical->pitch / (1 << 16)); + if (spherical->roll) + put_ebml_float(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONPOSEROLL, (double)spherical->roll / (1 << 16)); + +end: + projection_size = avio_close_dyn_buf(dyn_cp, &projection_ptr); + if (projection_size) { + ebml_master projection = start_ebml_master(pb, MATROSKA_ID_VIDEOPROJECTION, projection_size); + avio_write(pb, projection_ptr, projection_size); + end_ebml_master(pb, projection); + } + av_freep(&projection_ptr); + } + + return 0; +} + static void mkv_write_field_order(AVIOContext *pb, int mode, enum AVFieldOrder field_order) { @@ -1266,6 +1342,9 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, put_ebml_binary(pb, MATROSKA_ID_VIDEOCOLORSPACE, &color_space, sizeof(color_space)); } ret = mkv_write_video_color(pb, par, st); + if (ret < 0) + return ret; + ret = mkv_write_video_projection(s, pb, st); if (ret < 0) return ret; end_ebml_master(pb, subinfo); diff --git a/libavformat/version.h b/libavformat/version.h index cd505242efee0..dc689d45fbff1 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -33,7 +33,7 @@ // Also please add any ticket numbers that you believe might be affected here #define LIBAVFORMAT_VERSION_MAJOR 57 #define LIBAVFORMAT_VERSION_MINOR 66 -#define LIBAVFORMAT_VERSION_MICRO 103 +#define LIBAVFORMAT_VERSION_MICRO 104 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ From 5cd3cd5b6872eda1775aa2ddb34fc23ca03c6c85 Mon Sep 17 00:00:00 2001 From: Timo Rothenpieler Date: Sun, 5 Mar 2017 15:32:36 +0100 Subject: [PATCH 1065/3374] avcodec/cuvid: add support for cropping/resizing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Overhauled version, original patch by Miroslav Slugeň . --- libavcodec/cuvid.c | 85 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 66 insertions(+), 19 deletions(-) diff --git a/libavcodec/cuvid.c b/libavcodec/cuvid.c index c0b4a37734b25..916d7e9987ebb 100644 --- a/libavcodec/cuvid.c +++ b/libavcodec/cuvid.c @@ -43,6 +43,20 @@ typedef struct CuvidContext char *cu_gpu; int nb_surfaces; int drop_second_field; + char *crop_expr; + char *resize_expr; + + struct { + int left; + int top; + int right; + int bottom; + } crop; + + struct { + int width; + int height; + } resize; AVBufferRef *hwdevice; AVBufferRef *hwframe; @@ -107,17 +121,46 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form CUVIDDECODECREATEINFO cuinfo; int surface_fmt; + int old_width = avctx->width; + int old_height = avctx->height; + enum AVPixelFormat pix_fmts[3] = { AV_PIX_FMT_CUDA, AV_PIX_FMT_NONE, // Will be updated below AV_PIX_FMT_NONE }; av_log(avctx, AV_LOG_TRACE, "pfnSequenceCallback, progressive_sequence=%d\n", format->progressive_sequence); + memset(&cuinfo, 0, sizeof(cuinfo)); + ctx->internal_error = 0; + avctx->coded_width = cuinfo.ulWidth = format->coded_width; + avctx->coded_height = cuinfo.ulHeight = format->coded_height; + + // apply cropping + cuinfo.display_area.left = format->display_area.left + ctx->crop.left; + cuinfo.display_area.top = format->display_area.top + ctx->crop.top; + cuinfo.display_area.right = format->display_area.right - ctx->crop.right; + cuinfo.display_area.bottom = format->display_area.bottom - ctx->crop.bottom; + // width and height need to be set before calling ff_get_format - avctx->width = format->display_area.right; - avctx->height = format->display_area.bottom; + if (ctx->resize_expr) { + avctx->width = ctx->resize.width; + avctx->height = ctx->resize.height; + } else { + avctx->width = cuinfo.display_area.right - cuinfo.display_area.left; + avctx->height = cuinfo.display_area.bottom - cuinfo.display_area.top; + } + + // target width/height need to be multiples of two + cuinfo.ulTargetWidth = avctx->width = (avctx->width + 1) & ~1; + cuinfo.ulTargetHeight = avctx->height = (avctx->height + 1) & ~1; + + // aspect ratio conversion, 1:1, depends on scaled resolution + cuinfo.target_rect.left = 0; + cuinfo.target_rect.top = 0; + cuinfo.target_rect.right = cuinfo.ulTargetWidth; + cuinfo.target_rect.bottom = cuinfo.ulTargetHeight; switch (format->bit_depth_luma_minus8) { case 0: // 8-bit @@ -195,6 +238,8 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form if (ctx->cudecoder && avctx->coded_width == format->coded_width && avctx->coded_height == format->coded_height + && avctx->width == old_width + && avctx->height == old_height && ctx->chroma_format == format->chroma_format && ctx->codec_type == format->codec) return 1; @@ -228,13 +273,8 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form return 0; } - avctx->coded_width = format->coded_width; - avctx->coded_height = format->coded_height; - ctx->chroma_format = format->chroma_format; - memset(&cuinfo, 0, sizeof(cuinfo)); - cuinfo.CodecType = ctx->codec_type = format->codec; cuinfo.ChromaFormat = format->chroma_format; @@ -252,16 +292,6 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form return 0; } - cuinfo.ulWidth = avctx->coded_width; - cuinfo.ulHeight = avctx->coded_height; - cuinfo.ulTargetWidth = cuinfo.ulWidth; - cuinfo.ulTargetHeight = cuinfo.ulHeight; - - cuinfo.target_rect.left = 0; - cuinfo.target_rect.top = 0; - cuinfo.target_rect.right = cuinfo.ulWidth; - cuinfo.target_rect.bottom = cuinfo.ulHeight; - cuinfo.ulNumDecodeSurfaces = ctx->nb_surfaces; cuinfo.ulNumOutputSurfaces = 1; cuinfo.ulCreationFlags = cudaVideoCreate_PreferCUVID; @@ -486,7 +516,7 @@ static int cuvid_output_frame(AVCodecContext *avctx, AVFrame *frame) if (ret < 0) goto error; - offset += avctx->coded_height; + offset += avctx->height; } } else if (avctx->pix_fmt == AV_PIX_FMT_NV12 || avctx->pix_fmt == AV_PIX_FMT_P010 || @@ -502,7 +532,7 @@ static int cuvid_output_frame(AVCodecContext *avctx, AVFrame *frame) tmp_frame->hw_frames_ctx = av_buffer_ref(ctx->hwframe); tmp_frame->data[0] = (uint8_t*)mapped_frame; tmp_frame->linesize[0] = pitch; - tmp_frame->data[1] = (uint8_t*)(mapped_frame + avctx->coded_height * pitch); + tmp_frame->data[1] = (uint8_t*)(mapped_frame + avctx->height * pitch); tmp_frame->linesize[1] = pitch; tmp_frame->width = avctx->width; tmp_frame->height = avctx->height; @@ -708,6 +738,21 @@ static av_cold int cuvid_decode_init(AVCodecContext *avctx) } avctx->pix_fmt = ret; + if (ctx->resize_expr && sscanf(ctx->resize_expr, "%dx%d", + &ctx->resize.width, &ctx->resize.height) != 2) { + av_log(avctx, AV_LOG_ERROR, "Invalid resize expressions\n"); + ret = AVERROR(EINVAL); + goto error; + } + + if (ctx->crop_expr && sscanf(ctx->crop_expr, "%dx%dx%dx%d", + &ctx->crop.top, &ctx->crop.bottom, + &ctx->crop.left, &ctx->crop.right) != 4) { + av_log(avctx, AV_LOG_ERROR, "Invalid cropping expressions\n"); + ret = AVERROR(EINVAL); + goto error; + } + ret = cuvid_load_functions(&ctx->cvdl); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Failed loading nvcuvid.\n"); @@ -953,6 +998,8 @@ static const AVOption options[] = { { "gpu", "GPU to be used for decoding", OFFSET(cu_gpu), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VD }, { "surfaces", "Maximum surfaces to be used for decoding", OFFSET(nb_surfaces), AV_OPT_TYPE_INT, { .i64 = 25 }, 0, INT_MAX, VD }, { "drop_second_field", "Drop second field when deinterlacing", OFFSET(drop_second_field), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD }, + { "crop", "Crop (top)x(bottom)x(left)x(right)", OFFSET(crop_expr), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VD }, + { "resize", "Resize (width)x(height)", OFFSET(resize_expr), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VD }, { NULL } }; From 58dd25f8adb151a59971daa94d352d3226d2dbb6 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 8 Mar 2017 21:25:13 +0100 Subject: [PATCH 1066/3374] avcodec/mpegaudiodec_template: Check for negative e Fixes: undefined shift Fixes: 631/clusterfuzz-testcase-6725491035734016 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/mpegaudiodec_template.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/mpegaudiodec_template.c b/libavcodec/mpegaudiodec_template.c index a3729a9e297e2..88f62727cbd5e 100644 --- a/libavcodec/mpegaudiodec_template.c +++ b/libavcodec/mpegaudiodec_template.c @@ -251,7 +251,7 @@ static inline int l3_unscale(int value, int exponent) if(e < 1) av_log(NULL, AV_LOG_WARNING, "l3_unscale: e is %d\n", e); #endif - if (e > 31) + if (e > (SUINT)31) return 0; m = (m + (1 << (e - 1))) >> e; From 800d02abe041deacab5585bf41c1bc2ae5f4b922 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 8 Mar 2017 21:41:34 +0100 Subject: [PATCH 1067/3374] avcodec/mjpegdec: Fix runtime error: left shift of negative value -127 Fixes: 733/clusterfuzz-testcase-4682158096515072 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/mjpegdec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 2b5adfc61be99..4e78e1e3ae2d8 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -1196,13 +1196,13 @@ static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); pred &= mask; - *ptr = pred + (dc << point_transform); + *ptr = pred + ((unsigned)dc << point_transform); }else{ ptr16 = (uint16_t*)(s->picture_ptr->data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x)); //FIXME optimize this crap PREDICT(pred, ptr16[-linesize-1], ptr16[-linesize], ptr16[-1], predictor); pred &= mask; - *ptr16= pred + (dc << point_transform); + *ptr16= pred + ((unsigned)dc << point_transform); } if (++x == h) { From 222c9f031de3315af62be6d7a99c71105e516088 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 8 Mar 2017 21:53:15 +0100 Subject: [PATCH 1068/3374] avcodec/h264_mvpred: Fix runtime error: left shift of negative value -1 Fixes: 734/clusterfuzz-testcase-4821293192970240 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/h264_mvpred.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/h264_mvpred.h b/libavcodec/h264_mvpred.h index 339cf623d5a43..bf395e3fe296f 100644 --- a/libavcodec/h264_mvpred.h +++ b/libavcodec/h264_mvpred.h @@ -68,7 +68,7 @@ static av_always_inline int fetch_diagonal_mv(const H264Context *h, H264SliceCon } if (MB_FIELD(sl) && !IS_INTERLACED(sl->left_type[0])) { // left shift will turn LIST_NOT_USED into PART_NOT_AVAILABLE, but that's OK. - SET_DIAG_MV(/ 2, << 1, sl->left_mb_xy[i >= 36], ((i >> 2)) & 3); + SET_DIAG_MV(/ 2, *2, sl->left_mb_xy[i >= 36], ((i >> 2)) & 3); } } #undef SET_DIAG_MV From e2a4f1a9eb2c1ef3feed4a4f04db7629f2b61084 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 8 Mar 2017 22:25:08 +0100 Subject: [PATCH 1069/3374] avcodec/mpeg4videodec: Fix runtime error: signed integer overflow: -135088512 * 16 cannot be represented in type 'int' Fixes: 736/clusterfuzz-testcase-5580263943831552 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/mpeg4videodec.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index 128469d7552ef..791a07bbbb7db 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -387,11 +387,21 @@ static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *g } for (i = 0; i < 2; i++) { + int64_t sd[2] = { + s->sprite_delta[i][0] - a * (1LL<<16), + s->sprite_delta[i][1] - a * (1LL<<16) + }; + 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 || llabs(s->sprite_delta[i][0] * (w+16LL)) >= INT_MAX || - llabs(s->sprite_delta[i][1] * (w+16LL)) >= INT_MAX + llabs(s->sprite_delta[i][1] * (w+16LL)) >= INT_MAX || + llabs(sd[0]) >= INT_MAX || + llabs(sd[1]) >= INT_MAX || + llabs(s->sprite_offset[0][i] + sd[0] * (w+16LL)) >= INT_MAX || + llabs(s->sprite_offset[0][i] + sd[1] * (h+16LL)) >= INT_MAX || + llabs(s->sprite_offset[0][i] + sd[0] * (w+16LL) + sd[1] * (h+16LL)) >= INT_MAX ) { avpriv_request_sample(s->avctx, "Overflow on sprite points"); goto overflow; From bac9c03ed9328c63aba46e280ba408431b53fcb4 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 8 Mar 2017 22:54:10 +0100 Subject: [PATCH 1070/3374] avcodec/movtextdec: run mov_text_cleanup() before overwriting pointers Fixes: memleak Fixes: 741/clusterfuzz-testcase-586996200452915 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/movtextdec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c index 6de15004fc5b6..fb5085c3e8222 100644 --- a/libavcodec/movtextdec.c +++ b/libavcodec/movtextdec.c @@ -459,6 +459,8 @@ static int mov_text_decode_frame(AVCodecContext *avctx, end = ptr + FFMIN(2 + text_length, avpkt->size); ptr += 2; + mov_text_cleanup(m); + tsmb_size = 0; m->tracksize = 2 + text_length; m->style_entries = 0; From 9bbc73ae9fdedc8789b2b6be65279e9a0ecd7090 Mon Sep 17 00:00:00 2001 From: Thomas Guilbert Date: Fri, 10 Mar 2017 00:15:39 +0100 Subject: [PATCH 1071/3374] avcodec/vp8: Fix hang with slice threads Fixes: 447860.webm Reviewed-by: "Ronald S. Bultje" Signed-off-by: Michael Niedermayer --- libavcodec/vp8.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index 6759b310f01aa..068223920e40c 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -2508,8 +2508,10 @@ int vp78_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, int jobnr, for (mb_y = jobnr; mb_y < s->mb_height; mb_y += num_jobs) { td->thread_mb_pos = mb_y << 16; ret = s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr); - if (ret < 0) + if (ret < 0) { + update_pos(td, s->mb_height, INT_MAX & 0xFFFF); return ret; + } if (s->deblock_filter) s->filter_mb_row(avctx, tdata, jobnr, threadnr); update_pos(td, mb_y, INT_MAX & 0xFFFF); From 195784ec95266c69c111f1e977fd4cf4815c6d8d Mon Sep 17 00:00:00 2001 From: Aaron Boxer Date: Thu, 9 Mar 2017 23:01:48 -0500 Subject: [PATCH 1072/3374] libavcodec/libopenjpegenc: enable lossless option, remove layer option, and improve defaults 1. limit to single layer, as there is no current support for setting distortion/quality of multiple layers 2. encoder mode should be kept at default setting (0) 3. remove fixed_alloc parameter from context : seldom if ever used, and no way of properly configuring at the moment 4. add irreversible setting, to allow for lossless encoding. Set to OpenJPEG default (enabled) 5. set numresolution max to 33, which is the maximum number of allowed resolutions according the J2K spec Signed-off-by: Michael Bradshaw --- libavcodec/libopenjpegenc.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/libavcodec/libopenjpegenc.c b/libavcodec/libopenjpegenc.c index 1b7e1684af9b2..4a12729ecbf5f 100644 --- a/libavcodec/libopenjpegenc.c +++ b/libavcodec/libopenjpegenc.c @@ -64,9 +64,8 @@ typedef struct LibOpenJPEGContext { int prog_order; int cinema_mode; int numresolution; - int numlayers; + int irreversible; int disto_alloc; - int fixed_alloc; int fixed_quality; } LibOpenJPEGContext; @@ -358,13 +357,12 @@ static av_cold int libopenjpeg_encode_init(AVCodecContext *avctx) ctx->numresolution --; } - ctx->enc_params.mode = !!avctx->global_quality; ctx->enc_params.prog_order = ctx->prog_order; ctx->enc_params.numresolution = ctx->numresolution; + ctx->enc_params.irreversible = ctx->irreversible; ctx->enc_params.cp_disto_alloc = ctx->disto_alloc; - ctx->enc_params.cp_fixed_alloc = ctx->fixed_alloc; ctx->enc_params.cp_fixed_quality = ctx->fixed_quality; - ctx->enc_params.tcp_numlayers = ctx->numlayers; + ctx->enc_params.tcp_numlayers = 1; ctx->enc_params.tcp_rates[0] = FFMAX(avctx->compression_level, 0) * 2; if (ctx->cinema_mode > 0) { @@ -838,11 +836,10 @@ static const AVOption options[] = { { "rpcl", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OPJ(RPCL) }, 0, 0, VE, "prog_order" }, { "pcrl", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OPJ(PCRL) }, 0, 0, VE, "prog_order" }, { "cprl", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OPJ(CPRL) }, 0, 0, VE, "prog_order" }, - { "numresolution", NULL, OFFSET(numresolution), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, - { "numlayers", NULL, OFFSET(numlayers), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 10, VE }, - { "disto_alloc", NULL, OFFSET(disto_alloc), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE }, - { "fixed_alloc", NULL, OFFSET(fixed_alloc), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, - { "fixed_quality", NULL, OFFSET(fixed_quality), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, + { "numresolution", NULL, OFFSET(numresolution), AV_OPT_TYPE_INT, { .i64 = 6 }, 0, 33, VE }, + { "irreversible", NULL, OFFSET(irreversible), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, + { "disto_alloc", NULL, OFFSET(disto_alloc), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE }, + { "fixed_quality", NULL, OFFSET(fixed_quality), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, { NULL }, }; From dc0b9b218c1970d79908523657fff65a16613ca2 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 9 Mar 2017 13:54:24 +0100 Subject: [PATCH 1073/3374] avcodec/h264_ps: Forward errors from decode_scaling_list() Signed-off-by: Michael Niedermayer --- libavcodec/h264_ps.c | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c index f384ef23c308f..c330efddcb80f 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -247,7 +247,7 @@ static inline int decode_vui_parameters(GetBitContext *gb, AVCodecContext *avctx return 0; } -static void decode_scaling_list(GetBitContext *gb, uint8_t *factors, int size, +static int decode_scaling_list(GetBitContext *gb, uint8_t *factors, int size, const uint8_t *jvt_list, const uint8_t *fallback_list) { @@ -261,7 +261,7 @@ static void decode_scaling_list(GetBitContext *gb, uint8_t *factors, int size, int v = get_se_golomb(gb); if (v < -128 || v > 127) { av_log(NULL, AV_LOG_ERROR, "delta scale %d is invalid\n", v); - v = -last; + return AVERROR_INVALIDDATA; } next = (last + v) & 0xff; } @@ -271,6 +271,7 @@ static void decode_scaling_list(GetBitContext *gb, uint8_t *factors, int size, } last = factors[scan[i]] = next ? next : last; } + return 0; } /* returns non zero if the provided SPS scaling matrix has been filled */ @@ -288,23 +289,24 @@ static int decode_scaling_matrices(GetBitContext *gb, const SPS *sps, }; int ret = 0; if (get_bits1(gb)) { - ret = is_sps; - decode_scaling_list(gb, scaling_matrix4[0], 16, default_scaling4[0], fallback[0]); // Intra, Y - decode_scaling_list(gb, scaling_matrix4[1], 16, default_scaling4[0], scaling_matrix4[0]); // Intra, Cr - decode_scaling_list(gb, scaling_matrix4[2], 16, default_scaling4[0], scaling_matrix4[1]); // Intra, Cb - decode_scaling_list(gb, scaling_matrix4[3], 16, default_scaling4[1], fallback[1]); // Inter, Y - decode_scaling_list(gb, scaling_matrix4[4], 16, default_scaling4[1], scaling_matrix4[3]); // Inter, Cr - decode_scaling_list(gb, scaling_matrix4[5], 16, default_scaling4[1], scaling_matrix4[4]); // Inter, Cb + ret |= decode_scaling_list(gb, scaling_matrix4[0], 16, default_scaling4[0], fallback[0]); // Intra, Y + ret |= decode_scaling_list(gb, scaling_matrix4[1], 16, default_scaling4[0], scaling_matrix4[0]); // Intra, Cr + ret |= decode_scaling_list(gb, scaling_matrix4[2], 16, default_scaling4[0], scaling_matrix4[1]); // Intra, Cb + ret |= decode_scaling_list(gb, scaling_matrix4[3], 16, default_scaling4[1], fallback[1]); // Inter, Y + ret |= decode_scaling_list(gb, scaling_matrix4[4], 16, default_scaling4[1], scaling_matrix4[3]); // Inter, Cr + ret |= decode_scaling_list(gb, scaling_matrix4[5], 16, default_scaling4[1], scaling_matrix4[4]); // Inter, Cb if (is_sps || pps->transform_8x8_mode) { - decode_scaling_list(gb, scaling_matrix8[0], 64, default_scaling8[0], fallback[2]); // Intra, Y - decode_scaling_list(gb, scaling_matrix8[3], 64, default_scaling8[1], fallback[3]); // Inter, Y + ret |= decode_scaling_list(gb, scaling_matrix8[0], 64, default_scaling8[0], fallback[2]); // Intra, Y + ret |= decode_scaling_list(gb, scaling_matrix8[3], 64, default_scaling8[1], fallback[3]); // Inter, Y if (sps->chroma_format_idc == 3) { - decode_scaling_list(gb, scaling_matrix8[1], 64, default_scaling8[0], scaling_matrix8[0]); // Intra, Cr - decode_scaling_list(gb, scaling_matrix8[4], 64, default_scaling8[1], scaling_matrix8[3]); // Inter, Cr - decode_scaling_list(gb, scaling_matrix8[2], 64, default_scaling8[0], scaling_matrix8[1]); // Intra, Cb - decode_scaling_list(gb, scaling_matrix8[5], 64, default_scaling8[1], scaling_matrix8[4]); // Inter, Cb + ret |= decode_scaling_list(gb, scaling_matrix8[1], 64, default_scaling8[0], scaling_matrix8[0]); // Intra, Cr + ret |= decode_scaling_list(gb, scaling_matrix8[4], 64, default_scaling8[1], scaling_matrix8[3]); // Inter, Cr + ret |= decode_scaling_list(gb, scaling_matrix8[2], 64, default_scaling8[0], scaling_matrix8[1]); // Intra, Cb + ret |= decode_scaling_list(gb, scaling_matrix8[5], 64, default_scaling8[1], scaling_matrix8[4]); // Inter, Cb } } + if (!ret) + ret = is_sps; } return ret; @@ -335,6 +337,7 @@ int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx, unsigned int sps_id; int i, log2_max_frame_num_minus4; SPS *sps; + int ret; sps_buf = av_buffer_allocz(sizeof(*sps)); if (!sps_buf) @@ -413,8 +416,11 @@ int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx, goto fail; } sps->transform_bypass = get_bits1(gb); - sps->scaling_matrix_present |= decode_scaling_matrices(gb, sps, NULL, 1, - sps->scaling_matrix4, sps->scaling_matrix8); + ret = decode_scaling_matrices(gb, sps, NULL, 1, + sps->scaling_matrix4, sps->scaling_matrix8); + if (ret < 0) + goto fail; + sps->scaling_matrix_present |= ret; } else { sps->chroma_format_idc = 1; sps->bit_depth_luma = 8; @@ -846,8 +852,10 @@ int ff_h264_decode_picture_parameter_set(GetBitContext *gb, AVCodecContext *avct bits_left = bit_length - get_bits_count(gb); if (bits_left > 0 && more_rbsp_data_in_pps(sps, avctx)) { pps->transform_8x8_mode = get_bits1(gb); - decode_scaling_matrices(gb, sps, pps, 0, + ret = decode_scaling_matrices(gb, sps, pps, 0, pps->scaling_matrix4, pps->scaling_matrix8); + if (ret < 0) + goto fail; // second_chroma_qp_index_offset pps->chroma_qp_index_offset[1] = get_se_golomb(gb); if (pps->chroma_qp_index_offset[1] < -12 || pps->chroma_qp_index_offset[1] > 12) { From 6e913f212907048d7009cf2f15551781c69b9985 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 9 Mar 2017 17:55:32 +0100 Subject: [PATCH 1074/3374] avcodec/vp56: Reset have_undamaged_frame on resolution changes Fixes: timeout in 758/clusterfuzz-testcase-4720832028868608 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/vp56.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c index 0010408847a85..9d4162bb963db 100644 --- a/libavcodec/vp56.c +++ b/libavcodec/vp56.c @@ -507,6 +507,8 @@ static int vp56_size_changed(VP56Context *s) s->plane_height[0] = s->plane_height[3] = avctx->coded_height; s->plane_height[1] = s->plane_height[2] = avctx->coded_height/2; + s->have_undamaged_frame = 0; + for (i=0; i<4; i++) s->stride[i] = s->flip * s->frames[VP56_FRAME_CURRENT]->linesize[i]; From 51e3501993e3296727678c95bfcffe5b85525a12 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Sat, 11 Mar 2017 11:12:23 +0800 Subject: [PATCH 1075/3374] ffprobe: add AVCodecContext help message into ffprobe because the ffprobe can use AVCodecContext parameters Signed-off-by: Steven Liu --- ffprobe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ffprobe.c b/ffprobe.c index c85c3a104b316..b104390990d2f 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -3004,6 +3004,7 @@ void show_help_default(const char *opt, const char *arg) printf("\n"); show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM); + show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM); } /** From 114bbb0b74edd4c962095513117806c82ec06b61 Mon Sep 17 00:00:00 2001 From: Moritz Barsnick Date: Thu, 9 Mar 2017 10:23:28 +0100 Subject: [PATCH 1076/3374] libavfilter/avf_showwaves: make sqrt and cbrt scale option values available to showwavespic by name The 'sqrt' and 'cbrt' scalers were added in commit 80262d8c86e94ff9a4bb3a9e3c2d734e04ccb399, but their symbolic option values only made available to the showwaves filter, not showwavespic, despite the scalers working properly by their numerical option values. Signed-off-by: Moritz Barsnick --- doc/filters.texi | 18 +++++++++++++++++- libavfilter/avf_showwaves.c | 2 ++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/doc/filters.texi b/doc/filters.texi index b5265d929773d..192a81a075743 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -17897,7 +17897,23 @@ Set if channels should be drawn separately or overlap. Default value is 0. Set colors separated by '|' which are going to be used for drawing of each channel. @item scale -Set amplitude scale. Can be linear @code{lin} or logarithmic @code{log}. +Set amplitude scale. + +Available values are: +@table @samp +@item lin +Linear. + +@item log +Logarithmic. + +@item sqrt +Square root. + +@item cbrt +Cubic root. +@end table + Default is linear. @end table diff --git a/libavfilter/avf_showwaves.c b/libavfilter/avf_showwaves.c index 05aa9955612a4..aadc5c1c2a07a 100644 --- a/libavfilter/avf_showwaves.c +++ b/libavfilter/avf_showwaves.c @@ -676,6 +676,8 @@ static const AVOption showwavespic_options[] = { { "scale", "set amplitude scale", OFFSET(scale), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, SCALE_NB-1, FLAGS, .unit="scale" }, { "lin", "linear", 0, AV_OPT_TYPE_CONST, {.i64=SCALE_LIN}, .flags=FLAGS, .unit="scale"}, { "log", "logarithmic", 0, AV_OPT_TYPE_CONST, {.i64=SCALE_LOG}, .flags=FLAGS, .unit="scale"}, + { "sqrt", "square root", 0, AV_OPT_TYPE_CONST, {.i64=SCALE_SQRT}, .flags=FLAGS, .unit="scale"}, + { "cbrt", "cubic root", 0, AV_OPT_TYPE_CONST, {.i64=SCALE_CBRT}, .flags=FLAGS, .unit="scale"}, { NULL } }; From 31e41350d283febda7e91b92555854ca270e075e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 4 Feb 2017 22:16:09 +0200 Subject: [PATCH 1077/3374] arm: vp9itxfm: Avoid .irp when it doesn't save any lines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes it more readable. This is cherrypicked from libav commit 3bc5b28d5a191864c54bba60646933a63da31656. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index 25f6ddeb0e391..93816d25fc39b 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -690,21 +690,21 @@ function \txfm\()16_1d_4x16_pass1_neon @ for the first slice of the second pass (where it is the @ last 4x4 block). add r0, r0, #8 -.irp i, 20, 24, 28 - vst1.16 {d\i}, [r0,:64]! -.endr + vst1.16 {d20}, [r0,:64]! + vst1.16 {d24}, [r0,:64]! + vst1.16 {d28}, [r0,:64]! add r0, r0, #8 -.irp i, 21, 25, 29 - vst1.16 {d\i}, [r0,:64]! -.endr + vst1.16 {d21}, [r0,:64]! + vst1.16 {d25}, [r0,:64]! + vst1.16 {d29}, [r0,:64]! add r0, r0, #8 -.irp i, 22, 26, 30 - vst1.16 {d\i}, [r0,:64]! -.endr + vst1.16 {d22}, [r0,:64]! + vst1.16 {d26}, [r0,:64]! + vst1.16 {d30}, [r0,:64]! add r0, r0, #8 -.irp i, 23, 27, 31 - vst1.16 {d\i}, [r0,:64]! -.endr + vst1.16 {d23}, [r0,:64]! + vst1.16 {d27}, [r0,:64]! + vst1.16 {d31}, [r0,:64]! vmov d28, d16 vmov d29, d17 vmov d30, d18 From 52c7366c83aba4dc92ceedecbee592d629c98e29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 1 Dec 2016 11:10:19 +0200 Subject: [PATCH 1078/3374] aarch64: vp9itxfm: Restructure the idct32 store macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids concatenation, which can't be used if the whole macro is wrapped within another macro. This is also arguably more readable. This is cherrypicked from libav commit 58d87e0f49bcbbc6f426328f53b657bae7430cd2. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 80 +++++++++++++++--------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index 82f1f41579ab1..74279636c74a4 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -935,23 +935,23 @@ function idct32_1d_8x32_pass1_neon .macro store_rev a, b // There's no rev128 instruction, but we reverse each 64 bit // half, and then flip them using an ext with 8 bytes offset. - rev64 v1.8h, v\b\().8h - st1 {v\a\().8h}, [x0], #16 - rev64 v0.8h, v\a\().8h + rev64 v1.8h, \b + st1 {\a}, [x0], #16 + rev64 v0.8h, \a ext v1.16b, v1.16b, v1.16b, #8 - st1 {v\b\().8h}, [x0], #16 + st1 {\b}, [x0], #16 ext v0.16b, v0.16b, v0.16b, #8 st1 {v1.8h}, [x0], #16 st1 {v0.8h}, [x0], #16 .endm - store_rev 16, 24 - store_rev 17, 25 - store_rev 18, 26 - store_rev 19, 27 - store_rev 20, 28 - store_rev 21, 29 - store_rev 22, 30 - store_rev 23, 31 + store_rev v16.8h, v24.8h + store_rev v17.8h, v25.8h + store_rev v18.8h, v26.8h + store_rev v19.8h, v27.8h + store_rev v20.8h, v28.8h + store_rev v21.8h, v29.8h + store_rev v22.8h, v30.8h + store_rev v23.8h, v31.8h sub x0, x0, #512 .purgem store_rev @@ -977,14 +977,14 @@ function idct32_1d_8x32_pass1_neon // subtracted from the output. .macro store_rev a, b ld1 {v4.8h}, [x0] - rev64 v1.8h, v\b\().8h - add v4.8h, v4.8h, v\a\().8h - rev64 v0.8h, v\a\().8h + rev64 v1.8h, \b + add v4.8h, v4.8h, \a + rev64 v0.8h, \a st1 {v4.8h}, [x0], #16 ext v1.16b, v1.16b, v1.16b, #8 ld1 {v5.8h}, [x0] ext v0.16b, v0.16b, v0.16b, #8 - add v5.8h, v5.8h, v\b\().8h + add v5.8h, v5.8h, \b st1 {v5.8h}, [x0], #16 ld1 {v6.8h}, [x0] sub v6.8h, v6.8h, v1.8h @@ -994,14 +994,14 @@ function idct32_1d_8x32_pass1_neon st1 {v7.8h}, [x0], #16 .endm - store_rev 31, 23 - store_rev 30, 22 - store_rev 29, 21 - store_rev 28, 20 - store_rev 27, 19 - store_rev 26, 18 - store_rev 25, 17 - store_rev 24, 16 + store_rev v31.8h, v23.8h + store_rev v30.8h, v22.8h + store_rev v29.8h, v21.8h + store_rev v28.8h, v20.8h + store_rev v27.8h, v19.8h + store_rev v26.8h, v18.8h + store_rev v25.8h, v17.8h + store_rev v24.8h, v16.8h .purgem store_rev ret endfunc @@ -1047,21 +1047,21 @@ function idct32_1d_8x32_pass2_neon .if \neg == 0 ld1 {v4.8h}, [x2], x9 ld1 {v5.8h}, [x2], x9 - add v4.8h, v4.8h, v\a\().8h + add v4.8h, v4.8h, \a ld1 {v6.8h}, [x2], x9 - add v5.8h, v5.8h, v\b\().8h + add v5.8h, v5.8h, \b ld1 {v7.8h}, [x2], x9 - add v6.8h, v6.8h, v\c\().8h - add v7.8h, v7.8h, v\d\().8h + add v6.8h, v6.8h, \c + add v7.8h, v7.8h, \d .else ld1 {v4.8h}, [x2], x7 ld1 {v5.8h}, [x2], x7 - sub v4.8h, v4.8h, v\a\().8h + sub v4.8h, v4.8h, \a ld1 {v6.8h}, [x2], x7 - sub v5.8h, v5.8h, v\b\().8h + sub v5.8h, v5.8h, \b ld1 {v7.8h}, [x2], x7 - sub v6.8h, v6.8h, v\c\().8h - sub v7.8h, v7.8h, v\d\().8h + sub v6.8h, v6.8h, \c + sub v7.8h, v7.8h, \d .endif ld1 {v0.8b}, [x0], x1 ld1 {v1.8b}, [x0], x1 @@ -1085,15 +1085,15 @@ function idct32_1d_8x32_pass2_neon st1 {v6.8b}, [x0], x1 st1 {v7.8b}, [x0], x1 .endm - load_acc_store 31, 30, 29, 28 - load_acc_store 27, 26, 25, 24 - load_acc_store 23, 22, 21, 20 - load_acc_store 19, 18, 17, 16 + load_acc_store v31.8h, v30.8h, v29.8h, v28.8h + load_acc_store v27.8h, v26.8h, v25.8h, v24.8h + load_acc_store v23.8h, v22.8h, v21.8h, v20.8h + load_acc_store v19.8h, v18.8h, v17.8h, v16.8h sub x2, x2, x9 - load_acc_store 16, 17, 18, 19, 1 - load_acc_store 20, 21, 22, 23, 1 - load_acc_store 24, 25, 26, 27, 1 - load_acc_store 28, 29, 30, 31, 1 + load_acc_store v16.8h, v17.8h, v18.8h, v19.8h, 1 + load_acc_store v20.8h, v21.8h, v22.8h, v23.8h, 1 + load_acc_store v24.8h, v25.8h, v26.8h, v27.8h, 1 + load_acc_store v28.8h, v29.8h, v30.8h, v31.8h, 1 .purgem load_acc_store ret endfunc From f8fcee0daf42d16581ec581bd5ff6373c3a76103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 23 Nov 2016 10:56:12 +0200 Subject: [PATCH 1079/3374] arm: vp9itxfm: Make the larger core transforms standalone functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. This reduces the code size of libavcodec/arm/vp9itxfm_neon.o from 15324 to 12388 bytes. This gives a small slowdown of a couple tens of cycles, up to around 150 cycles for the full case of the largest transform, but makes it more feasible to add more optimized versions of these transforms. Before: Cortex A7 A8 A9 A53 vp9_inv_dct_dct_16x16_sub4_add_neon: 2063.4 1516.0 1719.5 1245.1 vp9_inv_dct_dct_16x16_sub16_add_neon: 3279.3 2454.5 2525.2 1982.3 vp9_inv_dct_dct_32x32_sub4_add_neon: 10750.0 7955.4 8525.6 6754.2 vp9_inv_dct_dct_32x32_sub32_add_neon: 18574.0 17108.4 14216.7 12010.2 After: vp9_inv_dct_dct_16x16_sub4_add_neon: 2060.8 1608.5 1735.7 1262.0 vp9_inv_dct_dct_16x16_sub16_add_neon: 3211.2 2443.5 2546.1 1999.5 vp9_inv_dct_dct_32x32_sub4_add_neon: 10682.0 8043.8 8581.3 6810.1 vp9_inv_dct_dct_32x32_sub32_add_neon: 18522.4 17277.4 14286.7 12087.9 This is cherrypicked from libav commit 0331c3f5e8cb6e6b53fab7893e91d1be1bfa979c. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 43 ++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index 93816d25fc39b..328bb01f027ab 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -534,7 +534,7 @@ function idct16x16_dc_add_neon endfunc .ltorg -.macro idct16 +function idct16 mbutterfly0 d16, d24, d16, d24, d4, d6, q2, q3 @ d16 = t0a, d24 = t1a mbutterfly d20, d28, d0[1], d0[2], q2, q3 @ d20 = t2a, d28 = t3a mbutterfly d18, d30, d0[3], d1[0], q2, q3 @ d18 = t4a, d30 = t7a @@ -580,9 +580,10 @@ endfunc vmov d4, d21 @ d4 = t10a butterfly d20, d27, d6, d27 @ d20 = out[4], d27 = out[11] butterfly d21, d26, d26, d4 @ d21 = out[5], d26 = out[10] -.endm + bx lr +endfunc -.macro iadst16 +function iadst16 movrel r12, iadst16_coeffs vld1.16 {q0-q1}, [r12,:128] @@ -653,7 +654,8 @@ endfunc vmov d16, d2 vmov d30, d4 -.endm + bx lr +endfunc .macro itxfm16_1d_funcs txfm @ Read a vertical 4x16 slice out of a 16x16 matrix, do a transform on it, @@ -662,6 +664,8 @@ endfunc @ r1 = slice offset @ r2 = src function \txfm\()16_1d_4x16_pass1_neon + push {lr} + mov r12, #32 vmov.s16 q2, #0 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 @@ -669,7 +673,7 @@ function \txfm\()16_1d_4x16_pass1_neon vst1.16 {d4}, [r2,:64], r12 .endr - \txfm\()16 + bl \txfm\()16 @ Do four 4x4 transposes. Originally, d16-d31 contain the @ 16 rows. Afterwards, d16-d19, d20-d23, d24-d27, d28-d31 @@ -682,7 +686,7 @@ function \txfm\()16_1d_4x16_pass1_neon .irp i, 16, 20, 24, 28, 17, 21, 25, 29, 18, 22, 26, 30, 19, 23, 27, 31 vst1.16 {d\i}, [r0,:64]! .endr - bx lr + pop {pc} 1: @ Special case: For the last input column (r1 == 12), @ which would be stored as the last row in the temp buffer, @@ -709,7 +713,7 @@ function \txfm\()16_1d_4x16_pass1_neon vmov d29, d17 vmov d30, d18 vmov d31, d19 - bx lr + pop {pc} endfunc @ Read a vertical 4x16 slice out of a 16x16 matrix, do a transform on it, @@ -719,6 +723,7 @@ endfunc @ r2 = src (temp buffer) @ r3 = slice offset function \txfm\()16_1d_4x16_pass2_neon + push {lr} mov r12, #32 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 vld1.16 {d\i}, [r2,:64], r12 @@ -732,7 +737,7 @@ function \txfm\()16_1d_4x16_pass2_neon add r3, r0, r1 lsl r1, r1, #1 - \txfm\()16 + bl \txfm\()16 .macro load_add_store coef0, coef1, coef2, coef3 vrshr.s16 \coef0, \coef0, #6 @@ -773,7 +778,7 @@ function \txfm\()16_1d_4x16_pass2_neon load_add_store q12, q13, q14, q15 .purgem load_add_store - bx lr + pop {pc} endfunc .endm @@ -908,7 +913,7 @@ function idct32x32_dc_add_neon bx lr endfunc -.macro idct32_odd +function idct32_odd movrel r12, idct_coeffs add r12, r12, #32 vld1.16 {q0-q1}, [r12,:128] @@ -967,7 +972,8 @@ endfunc mbutterfly0 d26, d21, d26, d21, d4, d6, q2, q3 @ d26 = t26a, d21 = t21a mbutterfly0 d25, d22, d25, d22, d4, d6, q2, q3 @ d25 = t25, d22 = t22 mbutterfly0 d24, d23, d24, d23, d4, d6, q2, q3 @ d24 = t24a, d23 = t23a -.endm + bx lr +endfunc @ Do an 32-point IDCT of a 4x32 slice out of a 32x32 matrix. @ We don't have register space to do a single pass IDCT of 4x32 though, @@ -979,6 +985,8 @@ endfunc @ r1 = unused @ r2 = src function idct32_1d_4x32_pass1_neon + push {lr} + movrel r12, idct_coeffs vld1.16 {q0-q1}, [r12,:128] @@ -992,7 +1000,7 @@ function idct32_1d_4x32_pass1_neon vst1.16 {d4}, [r2,:64], r12 .endr - idct16 + bl idct16 @ Do four 4x4 transposes. Originally, d16-d31 contain the @ 16 rows. Afterwards, d16-d19, d20-d23, d24-d27, d28-d31 @@ -1028,7 +1036,7 @@ function idct32_1d_4x32_pass1_neon vst1.16 {d4}, [r2,:64], r12 .endr - idct32_odd + bl idct32_odd transpose16_q_4x_4x4 q15, q14, q13, q12, q11, q10, q9, q8, d31, d30, d29, d28, d27, d26, d25, d24, d23, d22, d21, d20, d19, d18, d17, d16 @@ -1054,7 +1062,7 @@ function idct32_1d_4x32_pass1_neon store_rev 29, 25, 21, 17 store_rev 28, 24, 20, 16 .purgem store_rev - bx lr + pop {pc} endfunc .ltorg @@ -1065,6 +1073,7 @@ endfunc @ r1 = dst stride @ r2 = src (temp buffer) function idct32_1d_4x32_pass2_neon + push {lr} movrel r12, idct_coeffs vld1.16 {q0-q1}, [r12,:128] @@ -1075,7 +1084,7 @@ function idct32_1d_4x32_pass2_neon .endr sub r2, r2, r12, lsl #4 - idct16 + bl idct16 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vst1.16 {d\i}, [r2,:64], r12 @@ -1091,7 +1100,7 @@ function idct32_1d_4x32_pass2_neon sub r2, r2, r12, lsl #4 sub r2, r2, #64 - idct32_odd + bl idct32_odd mov r12, #128 .macro load_acc_store a, b, c, d, neg=0 @@ -1139,7 +1148,7 @@ function idct32_1d_4x32_pass2_neon load_acc_store 24, 25, 26, 27, 1 load_acc_store 28, 29, 30, 31, 1 .purgem load_acc_store - bx lr + pop {pc} endfunc const min_eob_idct_idct_32, align=4 From dc47bf3872fde18f6aea33f015a95b70e24dff19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 23 Nov 2016 14:03:05 +0200 Subject: [PATCH 1080/3374] aarch64: vp9itxfm: Make the larger core transforms standalone functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. This reduces the code size of libavcodec/aarch64/vp9itxfm_neon.o from 19496 to 14740 bytes. This gives a small slowdown of a couple of tens of cycles, but makes it more feasible to add more optimized versions of these transforms. Before: vp9_inv_dct_dct_16x16_sub4_add_neon: 1036.7 vp9_inv_dct_dct_16x16_sub16_add_neon: 1372.2 vp9_inv_dct_dct_32x32_sub4_add_neon: 5180.0 vp9_inv_dct_dct_32x32_sub32_add_neon: 8095.7 After: vp9_inv_dct_dct_16x16_sub4_add_neon: 1051.0 vp9_inv_dct_dct_16x16_sub16_add_neon: 1390.1 vp9_inv_dct_dct_32x32_sub4_add_neon: 5199.9 vp9_inv_dct_dct_32x32_sub32_add_neon: 8125.8 This is cherrypicked from libav commit 115476018d2c97df7e9b4445fe8f6cc7420ab91f. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 42 ++++++++++++++++++------------ 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index 74279636c74a4..a37b4597e0038 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -463,7 +463,7 @@ function idct16x16_dc_add_neon ret endfunc -.macro idct16 +function idct16 dmbutterfly0 v16, v24, v16, v24, v2, v3, v4, v5, v6, v7 // v16 = t0a, v24 = t1a dmbutterfly v20, v28, v0.h[1], v0.h[2], v2, v3, v4, v5 // v20 = t2a, v28 = t3a dmbutterfly v18, v30, v0.h[3], v0.h[4], v2, v3, v4, v5 // v18 = t4a, v30 = t7a @@ -506,9 +506,10 @@ endfunc butterfly_8h v19, v28, v5, v28 // v19 = out[3], v28 = out[12] butterfly_8h v20, v27, v6, v27 // v20 = out[4], v27 = out[11] butterfly_8h v21, v26, v26, v3 // v21 = out[5], v26 = out[10] -.endm + ret +endfunc -.macro iadst16 +function iadst16 ld1 {v0.8h,v1.8h}, [x11] dmbutterfly_l v6, v7, v4, v5, v31, v16, v0.h[1], v0.h[0] // v6,v7 = t1, v4,v5 = t0 @@ -577,7 +578,8 @@ endfunc mov v16.16b, v2.16b mov v30.16b, v4.16b -.endm + ret +endfunc // Helper macros; we can't use these expressions directly within // e.g. .irp due to the extra concatenation \(). Therefore wrap @@ -604,12 +606,14 @@ endfunc // x9 = input stride .macro itxfm16_1d_funcs txfm function \txfm\()16_1d_8x16_pass1_neon + mov x14, x30 + movi v2.8h, #0 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 load_clear \i, x2, x9 .endr - \txfm\()16 + bl \txfm\()16 // Do two 8x8 transposes. Originally, v16-v31 contain the // 16 rows. Afterwards, v16-v23 and v24-v31 contain the two @@ -623,7 +627,7 @@ function \txfm\()16_1d_8x16_pass1_neon .irp i, 16, 24, 17, 25, 18, 26, 19, 27, 20, 28, 21, 29, 22, 30, 23, 31 store \i, x0, #16 .endr - ret + br x14 1: // Special case: For the last input column (x1 == 8), // which would be stored as the last row in the temp buffer, @@ -642,7 +646,7 @@ function \txfm\()16_1d_8x16_pass1_neon mov v29.16b, v21.16b mov v30.16b, v22.16b mov v31.16b, v23.16b - ret + br x14 endfunc // Read a vertical 8x16 slice out of a 16x16 matrix, do a transform on it, @@ -653,6 +657,7 @@ endfunc // x3 = slice offset // x9 = temp buffer stride function \txfm\()16_1d_8x16_pass2_neon + mov x14, x30 .irp i, 16, 17, 18, 19, 20, 21, 22, 23 load \i, x2, x9 .endr @@ -664,7 +669,7 @@ function \txfm\()16_1d_8x16_pass2_neon add x3, x0, x1 lsl x1, x1, #1 - \txfm\()16 + bl \txfm\()16 .macro load_add_store coef0, coef1, coef2, coef3, coef4, coef5, coef6, coef7, tmp1, tmp2 srshr \coef0, \coef0, #6 @@ -714,7 +719,7 @@ function \txfm\()16_1d_8x16_pass2_neon load_add_store v24.8h, v25.8h, v26.8h, v27.8h, v28.8h, v29.8h, v30.8h, v31.8h, v16.8b, v17.8b .purgem load_add_store - ret + br x14 endfunc .endm @@ -843,7 +848,7 @@ function idct32x32_dc_add_neon ret endfunc -.macro idct32_odd +function idct32_odd ld1 {v0.8h,v1.8h}, [x11] dmbutterfly v16, v31, v0.h[0], v0.h[1], v4, v5, v6, v7 // v16 = t16a, v31 = t31a @@ -898,7 +903,8 @@ endfunc dmbutterfly0 v26, v21, v26, v21, v2, v3, v4, v5, v6, v7 // v26 = t26a, v21 = t21a dmbutterfly0 v25, v22, v25, v22, v2, v3, v4, v5, v6, v7 // v25 = t25, v22 = t22 dmbutterfly0 v24, v23, v24, v23, v2, v3, v4, v5, v6, v7 // v24 = t24a, v23 = t23a -.endm + ret +endfunc // Do an 32-point IDCT of a 8x32 slice out of a 32x32 matrix. // The 32-point IDCT can be decomposed into two 16-point IDCTs; @@ -912,6 +918,7 @@ endfunc // x10 = idct_coeffs // x11 = idct_coeffs + 32 function idct32_1d_8x32_pass1_neon + mov x14, x30 ld1 {v0.8h,v1.8h}, [x10] movi v4.8h, #0 @@ -922,7 +929,7 @@ function idct32_1d_8x32_pass1_neon st1 {v4.8h}, [x2], x9 .endr - idct16 + bl idct16 // Do two 8x8 transposes. Originally, v16-v31 contain the // 16 rows. Afterwards, v16-v23 and v24-v31 contain the @@ -967,7 +974,7 @@ function idct32_1d_8x32_pass1_neon st1 {v4.8h}, [x2], x9 .endr - idct32_odd + bl idct32_odd transpose_8x8H v31, v30, v29, v28, v27, v26, v25, v24, v2, v3 transpose_8x8H v23, v22, v21, v20, v19, v18, v17, v16, v2, v3 @@ -1003,7 +1010,7 @@ function idct32_1d_8x32_pass1_neon store_rev v25.8h, v17.8h store_rev v24.8h, v16.8h .purgem store_rev - ret + br x14 endfunc // This is mostly the same as 8x32_pass1, but without the transpose, @@ -1017,6 +1024,7 @@ endfunc // x10 = idct_coeffs // x11 = idct_coeffs + 32 function idct32_1d_8x32_pass2_neon + mov x14, x30 ld1 {v0.8h,v1.8h}, [x10] // v16 = IN(0), v17 = IN(2) ... v31 = IN(30) @@ -1025,7 +1033,7 @@ function idct32_1d_8x32_pass2_neon .endr sub x2, x2, x9, lsl #4 - idct16 + bl idct16 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 st1 {v\i\().8h}, [x2], x9 @@ -1041,7 +1049,7 @@ function idct32_1d_8x32_pass2_neon sub x2, x2, x9, lsl #4 sub x2, x2, #64 - idct32_odd + bl idct32_odd .macro load_acc_store a, b, c, d, neg=0 .if \neg == 0 @@ -1095,7 +1103,7 @@ function idct32_1d_8x32_pass2_neon load_acc_store v24.8h, v25.8h, v26.8h, v27.8h, 1 load_acc_store v28.8h, v29.8h, v30.8h, v31.8h, 1 .purgem load_acc_store - ret + br x14 endfunc const min_eob_idct_idct_32, align=4 From 3bd9b39108076e1fca8cd26970cb946fce66523a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 5 Feb 2017 22:55:20 +0200 Subject: [PATCH 1081/3374] arm: vp9itxfm: Move the load_add_store macro out from the itxfm16 pass2 function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows reusing the macro for a separate implementation of the pass2 function. This is cherrypicked from libav commit 47b3c2c18d1897f3c753ba0cec4b2d7aa24526af. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 72 +++++++++++++++++----------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index 328bb01f027ab..682a82e4cc0aa 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -657,6 +657,42 @@ function iadst16 bx lr endfunc +.macro load_add_store coef0, coef1, coef2, coef3 + vrshr.s16 \coef0, \coef0, #6 + vrshr.s16 \coef1, \coef1, #6 + + vld1.32 {d4[]}, [r0,:32], r1 + vld1.32 {d4[1]}, [r3,:32], r1 + vrshr.s16 \coef2, \coef2, #6 + vrshr.s16 \coef3, \coef3, #6 + vld1.32 {d5[]}, [r0,:32], r1 + vld1.32 {d5[1]}, [r3,:32], r1 + vaddw.u8 \coef0, \coef0, d4 + vld1.32 {d6[]}, [r0,:32], r1 + vld1.32 {d6[1]}, [r3,:32], r1 + vaddw.u8 \coef1, \coef1, d5 + vld1.32 {d7[]}, [r0,:32], r1 + vld1.32 {d7[1]}, [r3,:32], r1 + + vqmovun.s16 d4, \coef0 + vqmovun.s16 d5, \coef1 + sub r0, r0, r1, lsl #2 + sub r3, r3, r1, lsl #2 + vaddw.u8 \coef2, \coef2, d6 + vaddw.u8 \coef3, \coef3, d7 + vst1.32 {d4[0]}, [r0,:32], r1 + vst1.32 {d4[1]}, [r3,:32], r1 + vqmovun.s16 d6, \coef2 + vst1.32 {d5[0]}, [r0,:32], r1 + vst1.32 {d5[1]}, [r3,:32], r1 + vqmovun.s16 d7, \coef3 + + vst1.32 {d6[0]}, [r0,:32], r1 + vst1.32 {d6[1]}, [r3,:32], r1 + vst1.32 {d7[0]}, [r0,:32], r1 + vst1.32 {d7[1]}, [r3,:32], r1 +.endm + .macro itxfm16_1d_funcs txfm @ Read a vertical 4x16 slice out of a 16x16 matrix, do a transform on it, @ transpose into a horizontal 16x4 slice and store. @@ -739,44 +775,8 @@ function \txfm\()16_1d_4x16_pass2_neon lsl r1, r1, #1 bl \txfm\()16 -.macro load_add_store coef0, coef1, coef2, coef3 - vrshr.s16 \coef0, \coef0, #6 - vrshr.s16 \coef1, \coef1, #6 - - vld1.32 {d4[]}, [r0,:32], r1 - vld1.32 {d4[1]}, [r3,:32], r1 - vrshr.s16 \coef2, \coef2, #6 - vrshr.s16 \coef3, \coef3, #6 - vld1.32 {d5[]}, [r0,:32], r1 - vld1.32 {d5[1]}, [r3,:32], r1 - vaddw.u8 \coef0, \coef0, d4 - vld1.32 {d6[]}, [r0,:32], r1 - vld1.32 {d6[1]}, [r3,:32], r1 - vaddw.u8 \coef1, \coef1, d5 - vld1.32 {d7[]}, [r0,:32], r1 - vld1.32 {d7[1]}, [r3,:32], r1 - - vqmovun.s16 d4, \coef0 - vqmovun.s16 d5, \coef1 - sub r0, r0, r1, lsl #2 - sub r3, r3, r1, lsl #2 - vaddw.u8 \coef2, \coef2, d6 - vaddw.u8 \coef3, \coef3, d7 - vst1.32 {d4[0]}, [r0,:32], r1 - vst1.32 {d4[1]}, [r3,:32], r1 - vqmovun.s16 d6, \coef2 - vst1.32 {d5[0]}, [r0,:32], r1 - vst1.32 {d5[1]}, [r3,:32], r1 - vqmovun.s16 d7, \coef3 - - vst1.32 {d6[0]}, [r0,:32], r1 - vst1.32 {d6[1]}, [r3,:32], r1 - vst1.32 {d7[0]}, [r0,:32], r1 - vst1.32 {d7[1]}, [r3,:32], r1 -.endm load_add_store q8, q9, q10, q11 load_add_store q12, q13, q14, q15 -.purgem load_add_store pop {pc} endfunc From a681c793a30386d01d273ce86b3368311cffb511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 5 Feb 2017 22:53:55 +0200 Subject: [PATCH 1082/3374] aarch64: vp9itxfm: Move the load_add_store macro out from the itxfm16 pass2 function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows reusing the macro for a separate implementation of the pass2 function. This is cherrypicked from libav commit 79d332ebbde8c0a3e9da094dcfd10abd33ba7378. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 90 +++++++++++++++--------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index a37b4597e0038..e45d385870cea 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -598,6 +598,51 @@ endfunc st1 {v2.8h}, [\src], \inc .endm +.macro load_add_store coef0, coef1, coef2, coef3, coef4, coef5, coef6, coef7, tmp1, tmp2 + srshr \coef0, \coef0, #6 + ld1 {v2.8b}, [x0], x1 + srshr \coef1, \coef1, #6 + ld1 {v3.8b}, [x3], x1 + srshr \coef2, \coef2, #6 + ld1 {v4.8b}, [x0], x1 + srshr \coef3, \coef3, #6 + uaddw \coef0, \coef0, v2.8b + ld1 {v5.8b}, [x3], x1 + uaddw \coef1, \coef1, v3.8b + srshr \coef4, \coef4, #6 + ld1 {v6.8b}, [x0], x1 + srshr \coef5, \coef5, #6 + ld1 {v7.8b}, [x3], x1 + sqxtun v2.8b, \coef0 + srshr \coef6, \coef6, #6 + sqxtun v3.8b, \coef1 + srshr \coef7, \coef7, #6 + uaddw \coef2, \coef2, v4.8b + ld1 {\tmp1}, [x0], x1 + uaddw \coef3, \coef3, v5.8b + ld1 {\tmp2}, [x3], x1 + sqxtun v4.8b, \coef2 + sub x0, x0, x1, lsl #2 + sub x3, x3, x1, lsl #2 + sqxtun v5.8b, \coef3 + uaddw \coef4, \coef4, v6.8b + st1 {v2.8b}, [x0], x1 + uaddw \coef5, \coef5, v7.8b + st1 {v3.8b}, [x3], x1 + sqxtun v6.8b, \coef4 + st1 {v4.8b}, [x0], x1 + sqxtun v7.8b, \coef5 + st1 {v5.8b}, [x3], x1 + uaddw \coef6, \coef6, \tmp1 + st1 {v6.8b}, [x0], x1 + uaddw \coef7, \coef7, \tmp2 + st1 {v7.8b}, [x3], x1 + sqxtun \tmp1, \coef6 + sqxtun \tmp2, \coef7 + st1 {\tmp1}, [x0], x1 + st1 {\tmp2}, [x3], x1 +.endm + // Read a vertical 8x16 slice out of a 16x16 matrix, do a transform on it, // transpose into a horizontal 16x8 slice and store. // x0 = dst (temp buffer) @@ -671,53 +716,8 @@ function \txfm\()16_1d_8x16_pass2_neon lsl x1, x1, #1 bl \txfm\()16 -.macro load_add_store coef0, coef1, coef2, coef3, coef4, coef5, coef6, coef7, tmp1, tmp2 - srshr \coef0, \coef0, #6 - ld1 {v2.8b}, [x0], x1 - srshr \coef1, \coef1, #6 - ld1 {v3.8b}, [x3], x1 - srshr \coef2, \coef2, #6 - ld1 {v4.8b}, [x0], x1 - srshr \coef3, \coef3, #6 - uaddw \coef0, \coef0, v2.8b - ld1 {v5.8b}, [x3], x1 - uaddw \coef1, \coef1, v3.8b - srshr \coef4, \coef4, #6 - ld1 {v6.8b}, [x0], x1 - srshr \coef5, \coef5, #6 - ld1 {v7.8b}, [x3], x1 - sqxtun v2.8b, \coef0 - srshr \coef6, \coef6, #6 - sqxtun v3.8b, \coef1 - srshr \coef7, \coef7, #6 - uaddw \coef2, \coef2, v4.8b - ld1 {\tmp1}, [x0], x1 - uaddw \coef3, \coef3, v5.8b - ld1 {\tmp2}, [x3], x1 - sqxtun v4.8b, \coef2 - sub x0, x0, x1, lsl #2 - sub x3, x3, x1, lsl #2 - sqxtun v5.8b, \coef3 - uaddw \coef4, \coef4, v6.8b - st1 {v2.8b}, [x0], x1 - uaddw \coef5, \coef5, v7.8b - st1 {v3.8b}, [x3], x1 - sqxtun v6.8b, \coef4 - st1 {v4.8b}, [x0], x1 - sqxtun v7.8b, \coef5 - st1 {v5.8b}, [x3], x1 - uaddw \coef6, \coef6, \tmp1 - st1 {v6.8b}, [x0], x1 - uaddw \coef7, \coef7, \tmp2 - st1 {v7.8b}, [x3], x1 - sqxtun \tmp1, \coef6 - sqxtun \tmp2, \coef7 - st1 {\tmp1}, [x0], x1 - st1 {\tmp2}, [x3], x1 -.endm load_add_store v16.8h, v17.8h, v18.8h, v19.8h, v20.8h, v21.8h, v22.8h, v23.8h, v16.8b, v17.8b load_add_store v24.8h, v25.8h, v26.8h, v27.8h, v28.8h, v29.8h, v30.8h, v31.8h, v16.8b, v17.8b -.purgem load_add_store br x14 endfunc From 824589556cb7c4bfafb8a0190e71a10c628f5339 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 22 Nov 2016 11:07:38 +0200 Subject: [PATCH 1083/3374] arm: vp9itxfm: Do a simpler half/quarter idct16/idct32 when possible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. This avoids loading and calculating coefficients that we know will be zero, and avoids filling the temp buffer with zeros in places where we know the second pass won't read. This gives a pretty substantial speedup for the smaller subpartitions. The code size increases from 12388 bytes to 19784 bytes. The idct16/32_end macros are moved above the individual functions; the instructions themselves are unchanged, but since new functions are added at the same place where the code is moved from, the diff looks rather messy. Before: Cortex A7 A8 A9 A53 vp9_inv_dct_dct_16x16_sub1_add_neon: 273.0 189.5 212.0 235.8 vp9_inv_dct_dct_16x16_sub2_add_neon: 2102.1 1521.7 1736.2 1265.8 vp9_inv_dct_dct_16x16_sub4_add_neon: 2104.5 1533.0 1736.6 1265.5 vp9_inv_dct_dct_16x16_sub8_add_neon: 2484.8 1828.7 2014.4 1506.5 vp9_inv_dct_dct_16x16_sub12_add_neon: 2851.2 2117.8 2294.8 1753.2 vp9_inv_dct_dct_16x16_sub16_add_neon: 3239.4 2408.3 2543.5 1994.9 vp9_inv_dct_dct_32x32_sub1_add_neon: 758.3 456.7 864.5 553.9 vp9_inv_dct_dct_32x32_sub2_add_neon: 10776.7 7949.8 8567.7 6819.7 vp9_inv_dct_dct_32x32_sub4_add_neon: 10865.6 8131.5 8589.6 6816.3 vp9_inv_dct_dct_32x32_sub8_add_neon: 12053.9 9271.3 9387.7 7564.0 vp9_inv_dct_dct_32x32_sub12_add_neon: 13328.3 10463.2 10217.0 8321.3 vp9_inv_dct_dct_32x32_sub16_add_neon: 14176.4 11509.5 11018.7 9062.3 vp9_inv_dct_dct_32x32_sub20_add_neon: 15301.5 12999.9 11855.1 9828.2 vp9_inv_dct_dct_32x32_sub24_add_neon: 16482.7 14931.5 12650.1 10575.0 vp9_inv_dct_dct_32x32_sub28_add_neon: 17589.5 15811.9 13482.8 11333.4 vp9_inv_dct_dct_32x32_sub32_add_neon: 18696.2 17049.2 14355.6 12089.7 After: vp9_inv_dct_dct_16x16_sub1_add_neon: 273.0 189.5 211.7 235.8 vp9_inv_dct_dct_16x16_sub2_add_neon: 1203.5 998.2 1035.3 763.0 vp9_inv_dct_dct_16x16_sub4_add_neon: 1203.5 998.1 1035.5 760.8 vp9_inv_dct_dct_16x16_sub8_add_neon: 1926.1 1610.6 1722.1 1271.7 vp9_inv_dct_dct_16x16_sub12_add_neon: 2873.2 2129.7 2285.1 1757.3 vp9_inv_dct_dct_16x16_sub16_add_neon: 3221.4 2520.3 2557.6 2002.1 vp9_inv_dct_dct_32x32_sub1_add_neon: 753.0 457.5 866.6 554.6 vp9_inv_dct_dct_32x32_sub2_add_neon: 7554.6 5652.4 6048.4 4920.2 vp9_inv_dct_dct_32x32_sub4_add_neon: 7549.9 5685.0 6046.9 4925.7 vp9_inv_dct_dct_32x32_sub8_add_neon: 8336.9 6704.5 6604.0 5478.0 vp9_inv_dct_dct_32x32_sub12_add_neon: 10914.0 9777.2 9240.4 7416.9 vp9_inv_dct_dct_32x32_sub16_add_neon: 11859.2 11223.3 9966.3 8095.1 vp9_inv_dct_dct_32x32_sub20_add_neon: 15237.1 13029.4 11838.3 9829.4 vp9_inv_dct_dct_32x32_sub24_add_neon: 16293.2 14379.8 12644.9 10572.0 vp9_inv_dct_dct_32x32_sub28_add_neon: 17424.3 15734.7 13473.0 11326.9 vp9_inv_dct_dct_32x32_sub32_add_neon: 18531.3 17457.0 14298.6 12080.0 This is cherrypicked from libav commit 5eb5aec475aabc884d083566f902876ecbc072cb. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 591 ++++++++++++++++++++++++++++++--- 1 file changed, 537 insertions(+), 54 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index 682a82e4cc0aa..33a7af1109fe0 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -74,6 +74,14 @@ endconst vrshrn.s32 \out2, \tmpq4, #14 .endm +@ Same as mbutterfly0 above, but treating the input in in2 as zero, +@ writing the same output into both out1 and out2. +.macro mbutterfly0_h out1, out2, in1, in2, tmpd1, tmpd2, tmpq3, tmpq4 + vmull.s16 \tmpq3, \in1, d0[0] + vrshrn.s32 \out1, \tmpq3, #14 + vrshrn.s32 \out2, \tmpq3, #14 +.endm + @ out1,out2 = ((in1 + in2) * d0[0] + (1 << 13)) >> 14 @ out3,out4 = ((in1 - in2) * d0[0] + (1 << 13)) >> 14 @ Same as mbutterfly0, but with input being 2 q registers, output @@ -137,6 +145,23 @@ endconst vrshrn.s32 \inout2, \tmp2, #14 .endm +@ Same as mbutterfly above, but treating the input in inout2 as zero +.macro mbutterfly_h1 inout1, inout2, coef1, coef2, tmp1, tmp2 + vmull.s16 \tmp1, \inout1, \coef1 + vmull.s16 \tmp2, \inout1, \coef2 + vrshrn.s32 \inout1, \tmp1, #14 + vrshrn.s32 \inout2, \tmp2, #14 +.endm + +@ Same as mbutterfly above, but treating the input in inout1 as zero +.macro mbutterfly_h2 inout1, inout2, coef1, coef2, tmp1, tmp2 + vmull.s16 \tmp1, \inout2, \coef2 + vmull.s16 \tmp2, \inout2, \coef1 + vneg.s32 \tmp1, \tmp1 + vrshrn.s32 \inout2, \tmp2, #14 + vrshrn.s32 \inout1, \tmp1, #14 +.endm + @ inout1,inout2 = (inout1,inout2 * coef1 - inout3,inout4 * coef2 + (1 << 13)) >> 14 @ inout3,inout4 = (inout1,inout2 * coef2 + inout3,inout4 * coef1 + (1 << 13)) >> 14 @ inout are 4 d registers, tmp are 4 q registers @@ -534,6 +559,33 @@ function idct16x16_dc_add_neon endfunc .ltorg +.macro idct16_end + butterfly d18, d7, d4, d7 @ d18 = t0a, d7 = t7a + butterfly d19, d22, d5, d22 @ d19 = t1a, d22 = t6 + butterfly d4, d26, d20, d26 @ d4 = t2a, d26 = t5 + butterfly d5, d6, d28, d6 @ d5 = t3a, d6 = t4 + butterfly d20, d28, d16, d24 @ d20 = t8a, d28 = t11a + butterfly d24, d21, d23, d21 @ d24 = t9, d21 = t10 + butterfly d23, d27, d25, d27 @ d23 = t14, d27 = t13 + butterfly d25, d29, d29, d17 @ d25 = t15a, d29 = t12a + + mbutterfly0 d27, d21, d27, d21, d16, d30, q8, q15 @ d27 = t13a, d21 = t10a + mbutterfly0 d29, d28, d29, d28, d16, d30, q8, q15 @ d29 = t12, d28 = t11 + + vswp d27, d29 @ d27 = t12, d29 = t13a + vswp d28, d27 @ d28 = t12, d27 = t11 + butterfly d16, d31, d18, d25 @ d16 = out[0], d31 = out[15] + butterfly d17, d30, d19, d23 @ d17 = out[1], d30 = out[14] + butterfly_r d25, d22, d22, d24 @ d25 = out[9], d22 = out[6] + butterfly d23, d24, d7, d20 @ d23 = out[7], d24 = out[8] + butterfly d18, d29, d4, d29 @ d18 = out[2], d29 = out[13] + butterfly d19, d28, d5, d28 @ d19 = out[3], d28 = out[12] + vmov d4, d21 @ d4 = t10a + butterfly d20, d27, d6, d27 @ d20 = out[4], d27 = out[11] + butterfly d21, d26, d26, d4 @ d21 = out[5], d26 = out[10] + bx lr +.endm + function idct16 mbutterfly0 d16, d24, d16, d24, d4, d6, q2, q3 @ d16 = t0a, d24 = t1a mbutterfly d20, d28, d0[1], d0[2], q2, q3 @ d20 = t2a, d28 = t3a @@ -556,31 +608,63 @@ function idct16 mbutterfly0 d22, d26, d22, d26, d18, d30, q9, q15 @ d22 = t6a, d26 = t5a mbutterfly d23, d25, d0[1], d0[2], q9, q15 @ d23 = t9a, d25 = t14a mbutterfly d27, d21, d0[1], d0[2], q9, q15, neg=1 @ d27 = t13a, d21 = t10a + idct16_end +endfunc - butterfly d18, d7, d4, d7 @ d18 = t0a, d7 = t7a - butterfly d19, d22, d5, d22 @ d19 = t1a, d22 = t6 - butterfly d4, d26, d20, d26 @ d4 = t2a, d26 = t5 - butterfly d5, d6, d28, d6 @ d5 = t3a, d6 = t4 - butterfly d20, d28, d16, d24 @ d20 = t8a, d28 = t11a - butterfly d24, d21, d23, d21 @ d24 = t9, d21 = t10 - butterfly d23, d27, d25, d27 @ d23 = t14, d27 = t13 - butterfly d25, d29, d29, d17 @ d25 = t15a, d29 = t12a +function idct16_half + mbutterfly0_h d16, d24, d16, d24, d4, d6, q2, q3 @ d16 = t0a, d24 = t1a + mbutterfly_h1 d20, d28, d0[1], d0[2], q2, q3 @ d20 = t2a, d28 = t3a + mbutterfly_h1 d18, d30, d0[3], d1[0], q2, q3 @ d18 = t4a, d30 = t7a + mbutterfly_h2 d26, d22, d1[1], d1[2], q2, q3 @ d26 = t5a, d22 = t6a + mbutterfly_h1 d17, d31, d1[3], d2[0], q2, q3 @ d17 = t8a, d31 = t15a + mbutterfly_h2 d25, d23, d2[1], d2[2], q2, q3 @ d25 = t9a, d23 = t14a + mbutterfly_h1 d21, d27, d2[3], d3[0], q2, q3 @ d21 = t10a, d27 = t13a + mbutterfly_h2 d29, d19, d3[1], d3[2], q2, q3 @ d29 = t11a, d19 = t12a - mbutterfly0 d27, d21, d27, d21, d16, d30, q8, q15 @ d27 = t13a, d21 = t10a - mbutterfly0 d29, d28, d29, d28, d16, d30, q8, q15 @ d29 = t12, d28 = t11 + butterfly d4, d28, d16, d28 @ d4 = t0, d28 = t3 + butterfly d5, d20, d24, d20 @ d5 = t1, d20 = t2 + butterfly d6, d26, d18, d26 @ d6 = t4, d26 = t5 + butterfly d7, d22, d30, d22 @ d7 = t7, d22 = t6 + butterfly d16, d25, d17, d25 @ d16 = t8, d25 = t9 + butterfly d24, d21, d29, d21 @ d24 = t11, d21 = t10 + butterfly d17, d27, d19, d27 @ d17 = t12, d27 = t13 + butterfly d29, d23, d31, d23 @ d29 = t15, d23 = t14 - vswp d27, d29 @ d27 = t12, d29 = t13a - vswp d28, d27 @ d28 = t12, d27 = t11 - butterfly d16, d31, d18, d25 @ d16 = out[0], d31 = out[15] - butterfly d17, d30, d19, d23 @ d17 = out[1], d30 = out[14] - butterfly_r d25, d22, d22, d24 @ d25 = out[9], d22 = out[6] - butterfly d23, d24, d7, d20 @ d23 = out[7], d24 = out[8] - butterfly d18, d29, d4, d29 @ d18 = out[2], d29 = out[13] - butterfly d19, d28, d5, d28 @ d19 = out[3], d28 = out[12] - vmov d4, d21 @ d4 = t10a - butterfly d20, d27, d6, d27 @ d20 = out[4], d27 = out[11] - butterfly d21, d26, d26, d4 @ d21 = out[5], d26 = out[10] - bx lr + mbutterfly0 d22, d26, d22, d26, d18, d30, q9, q15 @ d22 = t6a, d26 = t5a + mbutterfly d23, d25, d0[1], d0[2], q9, q15 @ d23 = t9a, d25 = t14a + mbutterfly d27, d21, d0[1], d0[2], q9, q15, neg=1 @ d27 = t13a, d21 = t10a + idct16_end +endfunc + +function idct16_quarter + vmull.s16 q12, d19, d3[2] + vmull.s16 q2, d17, d1[3] + vmull.s16 q3, d18, d1[0] + vmull.s16 q15, d18, d0[3] + vneg.s32 q12, q12 + vmull.s16 q14, d17, d2[0] + vmull.s16 q13, d19, d3[1] + vmull.s16 q11, d16, d0[0] + vrshrn.s32 d24, q12, #14 + vrshrn.s32 d16, q2, #14 + vrshrn.s32 d7, q3, #14 + vrshrn.s32 d6, q15, #14 + vrshrn.s32 d29, q14, #14 + vrshrn.s32 d17, q13, #14 + vrshrn.s32 d28, q11, #14 + + mbutterfly_l q10, q11, d17, d24, d0[1], d0[2] + mbutterfly_l q9, q15, d29, d16, d0[1], d0[2] + vneg.s32 q11, q11 + vrshrn.s32 d27, q10, #14 + vrshrn.s32 d21, q11, #14 + vrshrn.s32 d23, q9, #14 + vrshrn.s32 d25, q15, #14 + vmov d4, d28 + vmov d5, d28 + mbutterfly0 d22, d26, d7, d6, d18, d30, q9, q15 + vmov d20, d28 + idct16_end endfunc function iadst16 @@ -819,6 +903,13 @@ A and r7, sp, #15 vld1.16 {q0-q1}, [r12,:128] .endif +.ifc \txfm1\()_\txfm2,idct_idct + cmp r3, #10 + ble idct16x16_quarter_add_neon + cmp r3, #38 + ble idct16x16_half_add_neon +.endif + .irp i, 0, 4, 8, 12 add r0, sp, #(\i*32) .ifc \txfm1\()_\txfm2,idct_idct @@ -877,6 +968,169 @@ itxfm_func16x16 idct, iadst itxfm_func16x16 iadst, iadst .ltorg +function idct16_1d_4x16_pass1_quarter_neon + push {lr} + mov r12, #32 + vmov.s16 q2, #0 +.irp i, 16, 17, 18, 19 + vld1.16 {d\i}, [r2,:64] + vst1.16 {d4}, [r2,:64], r12 +.endr + + bl idct16_quarter + + @ Do four 4x4 transposes. Originally, d16-d31 contain the + @ 16 rows. Afterwards, d16-d19, d20-d23, d24-d27, d28-d31 + @ contain the transposed 4x4 blocks. + transpose16_q_4x_4x4 q8, q9, q10, q11, q12, q13, q14, q15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31 + + @ Store the transposed 4x4 blocks horizontally. + @ The first 4x4 block is kept in registers for the second pass, + @ store the rest in the temp buffer. + add r0, r0, #8 + vst1.16 {d20}, [r0,:64]! + vst1.16 {d24}, [r0,:64]! + vst1.16 {d28}, [r0,:64]! + add r0, r0, #8 + vst1.16 {d21}, [r0,:64]! + vst1.16 {d25}, [r0,:64]! + vst1.16 {d29}, [r0,:64]! + add r0, r0, #8 + vst1.16 {d22}, [r0,:64]! + vst1.16 {d26}, [r0,:64]! + vst1.16 {d30}, [r0,:64]! + add r0, r0, #8 + vst1.16 {d23}, [r0,:64]! + vst1.16 {d27}, [r0,:64]! + vst1.16 {d31}, [r0,:64]! + pop {pc} +endfunc + +function idct16_1d_4x16_pass2_quarter_neon + push {lr} + @ Only load the top 4 lines, and only do it for the later slices. + @ For the first slice, d16-d19 is kept in registers from the first pass. + cmp r3, #0 + beq 1f + mov r12, #32 +.irp i, 16, 17, 18, 19 + vld1.16 {d\i}, [r2,:64], r12 +.endr +1: + + add r3, r0, r1 + lsl r1, r1, #1 + bl idct16_quarter + + load_add_store q8, q9, q10, q11 + load_add_store q12, q13, q14, q15 + + pop {pc} +endfunc + +function idct16_1d_4x16_pass1_half_neon + push {lr} + mov r12, #32 + vmov.s16 q2, #0 +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + vld1.16 {d\i}, [r2,:64] + vst1.16 {d4}, [r2,:64], r12 +.endr + + bl idct16_half + + @ Do four 4x4 transposes. Originally, d16-d31 contain the + @ 16 rows. Afterwards, d16-d19, d20-d23, d24-d27, d28-d31 + @ contain the transposed 4x4 blocks. + transpose16_q_4x_4x4 q8, q9, q10, q11, q12, q13, q14, q15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31 + + @ Store the transposed 4x4 blocks horizontally. + cmp r1, #4 + beq 1f +.irp i, 16, 20, 24, 28, 17, 21, 25, 29, 18, 22, 26, 30, 19, 23, 27, 31 + vst1.16 {d\i}, [r0,:64]! +.endr + pop {pc} +1: + @ Special case: For the second input column (r1 == 4), + @ which would be stored as the second row in the temp buffer, + @ don't store the first 4x4 block, but keep it in registers + @ for the first slice of the second pass (where it is the + @ second 4x4 block). + add r0, r0, #8 + vst1.16 {d20}, [r0,:64]! + vst1.16 {d24}, [r0,:64]! + vst1.16 {d28}, [r0,:64]! + add r0, r0, #8 + vst1.16 {d21}, [r0,:64]! + vst1.16 {d25}, [r0,:64]! + vst1.16 {d29}, [r0,:64]! + add r0, r0, #8 + vst1.16 {d22}, [r0,:64]! + vst1.16 {d26}, [r0,:64]! + vst1.16 {d30}, [r0,:64]! + add r0, r0, #8 + vst1.16 {d23}, [r0,:64]! + vst1.16 {d27}, [r0,:64]! + vst1.16 {d31}, [r0,:64]! + vmov d20, d16 + vmov d21, d17 + vmov d22, d18 + vmov d23, d19 + pop {pc} +endfunc + +function idct16_1d_4x16_pass2_half_neon + push {lr} + mov r12, #32 + cmp r3, #0 +.irp i, 16, 17, 18, 19 + vld1.16 {d\i}, [r2,:64], r12 +.endr + beq 1f +.irp i, 20, 21, 22, 23 + vld1.16 {d\i}, [r2,:64], r12 +.endr +1: + + add r3, r0, r1 + lsl r1, r1, #1 + bl idct16_half + + load_add_store q8, q9, q10, q11 + load_add_store q12, q13, q14, q15 + + pop {pc} +endfunc +.purgem load_add_store + +.macro idct16_partial size +function idct16x16_\size\()_add_neon + add r0, sp, #(0*32) + mov r1, #0 + add r2, r6, #(0*2) + bl idct16_1d_4x16_pass1_\size\()_neon +.ifc \size,half + add r0, sp, #(4*32) + mov r1, #4 + add r2, r6, #(4*2) + bl idct16_1d_4x16_pass1_\size\()_neon +.endif +.irp i, 0, 4, 8, 12 + add r0, r4, #(\i) + mov r1, r5 + add r2, sp, #(\i*2) + mov r3, #\i + bl idct16_1d_4x16_pass2_\size\()_neon +.endr + + add sp, sp, r7 + pop {r4-r8,pc} +endfunc +.endm + +idct16_partial quarter +idct16_partial half function idct32x32_dc_add_neon movrel r12, idct_coeffs @@ -913,6 +1167,38 @@ function idct32x32_dc_add_neon bx lr endfunc +.macro idct32_end + butterfly d16, d5, d4, d5 @ d16 = t16a, d5 = t19a + butterfly d17, d20, d23, d20 @ d17 = t17, d20 = t18 + butterfly d18, d6, d7, d6 @ d18 = t23a, d6 = t20a + butterfly d19, d21, d22, d21 @ d19 = t22, d21 = t21 + butterfly d4, d28, d28, d30 @ d4 = t24a, d28 = t27a + butterfly d23, d26, d25, d26 @ d23 = t25, d26 = t26 + butterfly d7, d29, d29, d31 @ d7 = t31a, d29 = t28a + butterfly d22, d27, d24, d27 @ d22 = t30, d27 = t29 + + mbutterfly d27, d20, d0[1], d0[2], q12, q15 @ d27 = t18a, d20 = t29a + mbutterfly d29, d5, d0[1], d0[2], q12, q15 @ d29 = t19, d5 = t28 + mbutterfly d28, d6, d0[1], d0[2], q12, q15, neg=1 @ d28 = t27, d6 = t20 + mbutterfly d26, d21, d0[1], d0[2], q12, q15, neg=1 @ d26 = t26a, d21 = t21a + + butterfly d31, d24, d7, d4 @ d31 = t31, d24 = t24 + butterfly d30, d25, d22, d23 @ d30 = t30a, d25 = t25a + butterfly_r d23, d16, d16, d18 @ d23 = t23, d16 = t16 + butterfly_r d22, d17, d17, d19 @ d22 = t22a, d17 = t17a + butterfly d18, d21, d27, d21 @ d18 = t18, d21 = t21 + butterfly_r d27, d28, d5, d28 @ d27 = t27a, d28 = t28a + butterfly d4, d26, d20, d26 @ d4 = t29, d26 = t26 + butterfly d19, d20, d29, d6 @ d19 = t19a, d20 = t20 + vmov d29, d4 @ d29 = t29 + + mbutterfly0 d27, d20, d27, d20, d4, d6, q2, q3 @ d27 = t27, d20 = t20 + mbutterfly0 d26, d21, d26, d21, d4, d6, q2, q3 @ d26 = t26a, d21 = t21a + mbutterfly0 d25, d22, d25, d22, d4, d6, q2, q3 @ d25 = t25, d22 = t22 + mbutterfly0 d24, d23, d24, d23, d4, d6, q2, q3 @ d24 = t24a, d23 = t23a + bx lr +.endm + function idct32_odd movrel r12, idct_coeffs add r12, r12, #32 @@ -943,38 +1229,91 @@ function idct32_odd mbutterfly d27, d20, d0[3], d1[0], q8, q9, neg=1 @ d27 = t29a, d20 = t18a mbutterfly d21, d26, d1[1], d1[2], q8, q9 @ d21 = t21a, d26 = t26a mbutterfly d25, d22, d1[1], d1[2], q8, q9, neg=1 @ d25 = t25a, d22 = t22a + idct32_end +endfunc - butterfly d16, d5, d4, d5 @ d16 = t16a, d5 = t19a - butterfly d17, d20, d23, d20 @ d17 = t17, d20 = t18 - butterfly d18, d6, d7, d6 @ d18 = t23a, d6 = t20a - butterfly d19, d21, d22, d21 @ d19 = t22, d21 = t21 - butterfly d4, d28, d28, d30 @ d4 = t24a, d28 = t27a - butterfly d23, d26, d25, d26 @ d23 = t25, d26 = t26 - butterfly d7, d29, d29, d31 @ d7 = t31a, d29 = t28a - butterfly d22, d27, d24, d27 @ d22 = t30, d27 = t29 +function idct32_odd_half + movrel r12, idct_coeffs + add r12, r12, #32 + vld1.16 {q0-q1}, [r12,:128] - mbutterfly d27, d20, d0[1], d0[2], q12, q15 @ d27 = t18a, d20 = t29a - mbutterfly d29, d5, d0[1], d0[2], q12, q15 @ d29 = t19, d5 = t28 - mbutterfly d28, d6, d0[1], d0[2], q12, q15, neg=1 @ d28 = t27, d6 = t20 - mbutterfly d26, d21, d0[1], d0[2], q12, q15, neg=1 @ d26 = t26a, d21 = t21a + mbutterfly_h1 d16, d31, d0[0], d0[1], q2, q3 @ d16 = t16a, d31 = t31a + mbutterfly_h2 d24, d23, d0[2], d0[3], q2, q3 @ d24 = t17a, d23 = t30a + mbutterfly_h1 d20, d27, d1[0], d1[1], q2, q3 @ d20 = t18a, d27 = t29a + mbutterfly_h2 d28, d19, d1[2], d1[3], q2, q3 @ d28 = t19a, d19 = t28a + mbutterfly_h1 d18, d29, d2[0], d2[1], q2, q3 @ d18 = t20a, d29 = t27a + mbutterfly_h2 d26, d21, d2[2], d2[3], q2, q3 @ d26 = t21a, d21 = t26a + mbutterfly_h1 d22, d25, d3[0], d3[1], q2, q3 @ d22 = t22a, d25 = t25a + mbutterfly_h2 d30, d17, d3[2], d3[3], q2, q3 @ d30 = t23a, d17 = t24a - butterfly d31, d24, d7, d4 @ d31 = t31, d24 = t24 - butterfly d30, d25, d22, d23 @ d30 = t30a, d25 = t25a - butterfly_r d23, d16, d16, d18 @ d23 = t23, d16 = t16 - butterfly_r d22, d17, d17, d19 @ d22 = t22a, d17 = t17a - butterfly d18, d21, d27, d21 @ d18 = t18, d21 = t21 - butterfly_r d27, d28, d5, d28 @ d27 = t27a, d28 = t28a - butterfly d4, d26, d20, d26 @ d4 = t29, d26 = t26 - butterfly d19, d20, d29, d6 @ d19 = t19a, d20 = t20 - vmov d29, d4 @ d29 = t29 + sub r12, r12, #32 + vld1.16 {q0}, [r12,:128] - mbutterfly0 d27, d20, d27, d20, d4, d6, q2, q3 @ d27 = t27, d20 = t20 - mbutterfly0 d26, d21, d26, d21, d4, d6, q2, q3 @ d26 = t26a, d21 = t21a - mbutterfly0 d25, d22, d25, d22, d4, d6, q2, q3 @ d25 = t25, d22 = t22 - mbutterfly0 d24, d23, d24, d23, d4, d6, q2, q3 @ d24 = t24a, d23 = t23a - bx lr + butterfly d4, d24, d16, d24 @ d4 = t16, d24 = t17 + butterfly d5, d20, d28, d20 @ d5 = t19, d20 = t18 + butterfly d6, d26, d18, d26 @ d6 = t20, d26 = t21 + butterfly d7, d22, d30, d22 @ d7 = t23, d22 = t22 + butterfly d28, d25, d17, d25 @ d28 = t24, d25 = t25 + butterfly d30, d21, d29, d21 @ d30 = t27, d21 = t26 + butterfly d29, d23, d31, d23 @ d29 = t31, d23 = t30 + butterfly d31, d27, d19, d27 @ d31 = t28, d27 = t29 + + mbutterfly d23, d24, d0[3], d1[0], q8, q9 @ d23 = t17a, d24 = t30a + mbutterfly d27, d20, d0[3], d1[0], q8, q9, neg=1 @ d27 = t29a, d20 = t18a + mbutterfly d21, d26, d1[1], d1[2], q8, q9 @ d21 = t21a, d26 = t26a + mbutterfly d25, d22, d1[1], d1[2], q8, q9, neg=1 @ d25 = t25a, d22 = t22a + + idct32_end endfunc +function idct32_odd_quarter + movrel r12, idct_coeffs + add r12, r12, #32 + vld1.16 {q0-q1}, [r12,:128] + + vmull.s16 q2, d16, d0[0] + vmull.s16 q14, d19, d1[3] + vmull.s16 q15, d16, d0[1] + vmull.s16 q11, d17, d3[2] + vmull.s16 q3, d17, d3[3] + vmull.s16 q13, d19, d1[2] + vmull.s16 q10, d18, d2[0] + vmull.s16 q12, d18, d2[1] + + sub r12, r12, #32 + vld1.16 {q0}, [r12,:128] + + vneg.s32 q14, q14 + vneg.s32 q3, q3 + + vrshrn.s32 d4, q2, #14 + vrshrn.s32 d5, q14, #14 + vrshrn.s32 d29, q15, #14 + vrshrn.s32 d28, q11, #14 + vrshrn.s32 d7, q3, #14 + vrshrn.s32 d31, q13, #14 + vrshrn.s32 d6, q10, #14 + vrshrn.s32 d30, q12, #14 + + mbutterfly_l q8, q9, d29, d4, d0[3], d1[0] + mbutterfly_l q13, q10, d31, d5, d0[3], d1[0] + vrshrn.s32 d23, q8, #14 + vrshrn.s32 d24, q9, #14 + vneg.s32 q10, q10 + vrshrn.s32 d27, q13, #14 + vrshrn.s32 d20, q10, #14 + mbutterfly_l q8, q9, d30, d6, d1[1], d1[2] + vrshrn.s32 d21, q8, #14 + vrshrn.s32 d26, q9, #14 + mbutterfly_l q8, q9, d28, d7, d1[1], d1[2] + vrshrn.s32 d25, q8, #14 + vneg.s32 q9, q9 + vrshrn.s32 d22, q9, #14 + + idct32_end +endfunc + +.macro idct32_funcs suffix @ Do an 32-point IDCT of a 4x32 slice out of a 32x32 matrix. @ We don't have register space to do a single pass IDCT of 4x32 though, @ but the 32-point IDCT can be decomposed into two 16-point IDCTs; @@ -984,7 +1323,7 @@ endfunc @ r0 = dst (temp buffer) @ r1 = unused @ r2 = src -function idct32_1d_4x32_pass1_neon +function idct32_1d_4x32_pass1\suffix\()_neon push {lr} movrel r12, idct_coeffs @@ -995,12 +1334,26 @@ function idct32_1d_4x32_pass1_neon vmov.s16 d4, #0 @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vld1.16 {d\i}, [r2,:64] vst1.16 {d4}, [r2,:64], r12 .endr +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + vld1.16 {d\i}, [r2,:64] + vst1.16 {d4}, [r2,:64], r12 +.endr +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + vld1.16 {d\i}, [r2,:64] + vst1.16 {d4}, [r2,:64], r12 +.endr +.endif - bl idct16 + bl idct16\suffix @ Do four 4x4 transposes. Originally, d16-d31 contain the @ 16 rows. Afterwards, d16-d19, d20-d23, d24-d27, d28-d31 @@ -1026,17 +1379,39 @@ function idct32_1d_4x32_pass1_neon @ Move r2 back to the start of the input, and move @ to the first odd row +.ifb \suffix sub r2, r2, r12, lsl #4 +.endif +.ifc \suffix,_quarter + sub r2, r2, r12, lsl #2 +.endif +.ifc \suffix,_half + sub r2, r2, r12, lsl #3 +.endif add r2, r2, #64 vmov.s16 d4, #0 @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vld1.16 {d\i}, [r2,:64] vst1.16 {d4}, [r2,:64], r12 .endr +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + vld1.16 {d\i}, [r2,:64] + vst1.16 {d4}, [r2,:64], r12 +.endr +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + vld1.16 {d\i}, [r2,:64] + vst1.16 {d4}, [r2,:64], r12 +.endr +.endif - bl idct32_odd + bl idct32_odd\suffix transpose16_q_4x_4x4 q15, q14, q13, q12, q11, q10, q9, q8, d31, d30, d29, d28, d27, d26, d25, d24, d23, d22, d21, d20, d19, d18, d17, d16 @@ -1072,19 +1447,33 @@ endfunc @ r0 = dst @ r1 = dst stride @ r2 = src (temp buffer) -function idct32_1d_4x32_pass2_neon +function idct32_1d_4x32_pass2\suffix\()_neon push {lr} movrel r12, idct_coeffs vld1.16 {q0-q1}, [r12,:128] mov r12, #128 @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vld1.16 {d\i}, [r2,:64], r12 .endr sub r2, r2, r12, lsl #4 +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + vld1.16 {d\i}, [r2,:64], r12 +.endr + sub r2, r2, r12, lsl #2 +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + vld1.16 {d\i}, [r2,:64], r12 +.endr + sub r2, r2, r12, lsl #3 +.endif - bl idct16 + bl idct16\suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vst1.16 {d\i}, [r2,:64], r12 @@ -1094,13 +1483,27 @@ function idct32_1d_4x32_pass2_neon add r2, r2, #64 @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vld1.16 {d\i}, [r2,:64], r12 .endr sub r2, r2, r12, lsl #4 +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + vld1.16 {d\i}, [r2,:64], r12 +.endr + sub r2, r2, r12, lsl #2 +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + vld1.16 {d\i}, [r2,:64], r12 +.endr + sub r2, r2, r12, lsl #3 +.endif sub r2, r2, #64 - bl idct32_odd + bl idct32_odd\suffix mov r12, #128 .macro load_acc_store a, b, c, d, neg=0 @@ -1150,6 +1553,11 @@ function idct32_1d_4x32_pass2_neon .purgem load_acc_store pop {pc} endfunc +.endm + +idct32_funcs +idct32_funcs _quarter +idct32_funcs _half const min_eob_idct_idct_32, align=4 .short 0, 9, 34, 70, 135, 240, 336, 448 @@ -1173,6 +1581,11 @@ A and r7, sp, #15 mov r5, r1 mov r6, r2 + cmp r3, #34 + ble idct32x32_quarter_add_neon + cmp r3, #135 + ble idct32x32_half_add_neon + .irp i, 0, 4, 8, 12, 16, 20, 24, 28 add r0, sp, #(\i*64) .if \i > 0 @@ -1209,3 +1622,73 @@ A and r7, sp, #15 vpop {q4-q7} pop {r4-r8,pc} endfunc + +function idct32x32_quarter_add_neon +.irp i, 0, 4 + add r0, sp, #(\i*64) +.if \i == 4 + cmp r3, #9 + ble 1f +.endif + add r2, r6, #(\i*2) + bl idct32_1d_4x32_pass1_quarter_neon +.endr + b 3f + +1: + @ Write zeros to the temp buffer for pass 2 + vmov.i16 q14, #0 + vmov.i16 q15, #0 +.rept 8 + vst1.16 {q14-q15}, [r0,:128]! +.endr +3: +.irp i, 0, 4, 8, 12, 16, 20, 24, 28 + add r0, r4, #(\i) + mov r1, r5 + add r2, sp, #(\i*2) + bl idct32_1d_4x32_pass2_quarter_neon +.endr + + add sp, sp, r7 + vpop {q4-q7} + pop {r4-r8,pc} +endfunc + +function idct32x32_half_add_neon +.irp i, 0, 4, 8, 12 + add r0, sp, #(\i*64) +.if \i > 0 + ldrh_post r1, r8, #2 + cmp r3, r1 + it le + movle r1, #(16 - \i)/2 + ble 1f +.endif + add r2, r6, #(\i*2) + bl idct32_1d_4x32_pass1_half_neon +.endr + b 3f + +1: + @ Write zeros to the temp buffer for pass 2 + vmov.i16 q14, #0 + vmov.i16 q15, #0 +2: + subs r1, r1, #1 +.rept 4 + vst1.16 {q14-q15}, [r0,:128]! +.endr + bne 2b +3: +.irp i, 0, 4, 8, 12, 16, 20, 24, 28 + add r0, r4, #(\i) + mov r1, r5 + add r2, sp, #(\i*2) + bl idct32_1d_4x32_pass2_half_neon +.endr + + add sp, sp, r7 + vpop {q4-q7} + pop {r4-r8,pc} +endfunc From 9532a7d4d060f2a2741225a76945daed52dbc478 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 22 Nov 2016 22:58:35 +0200 Subject: [PATCH 1084/3374] aarch64: vp9itxfm: Do separate functions for half/quarter idct16 and idct32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. This avoids loading and calculating coefficients that we know will be zero, and avoids filling the temp buffer with zeros in places where we know the second pass won't read. This gives a pretty substantial speedup for the smaller subpartitions. The code size increases from 14740 bytes to 24292 bytes. The idct16/32_end macros are moved above the individual functions; the instructions themselves are unchanged, but since new functions are added at the same place where the code is moved from, the diff looks rather messy. Before: vp9_inv_dct_dct_16x16_sub1_add_neon: 236.7 vp9_inv_dct_dct_16x16_sub2_add_neon: 1051.0 vp9_inv_dct_dct_16x16_sub4_add_neon: 1051.0 vp9_inv_dct_dct_16x16_sub8_add_neon: 1051.0 vp9_inv_dct_dct_16x16_sub12_add_neon: 1387.4 vp9_inv_dct_dct_16x16_sub16_add_neon: 1387.6 vp9_inv_dct_dct_32x32_sub1_add_neon: 554.1 vp9_inv_dct_dct_32x32_sub2_add_neon: 5198.5 vp9_inv_dct_dct_32x32_sub4_add_neon: 5198.6 vp9_inv_dct_dct_32x32_sub8_add_neon: 5196.3 vp9_inv_dct_dct_32x32_sub12_add_neon: 6183.4 vp9_inv_dct_dct_32x32_sub16_add_neon: 6174.3 vp9_inv_dct_dct_32x32_sub20_add_neon: 7151.4 vp9_inv_dct_dct_32x32_sub24_add_neon: 7145.3 vp9_inv_dct_dct_32x32_sub28_add_neon: 8119.3 vp9_inv_dct_dct_32x32_sub32_add_neon: 8118.7 After: vp9_inv_dct_dct_16x16_sub1_add_neon: 236.7 vp9_inv_dct_dct_16x16_sub2_add_neon: 640.8 vp9_inv_dct_dct_16x16_sub4_add_neon: 639.0 vp9_inv_dct_dct_16x16_sub8_add_neon: 842.0 vp9_inv_dct_dct_16x16_sub12_add_neon: 1388.3 vp9_inv_dct_dct_16x16_sub16_add_neon: 1389.3 vp9_inv_dct_dct_32x32_sub1_add_neon: 554.1 vp9_inv_dct_dct_32x32_sub2_add_neon: 3685.5 vp9_inv_dct_dct_32x32_sub4_add_neon: 3685.1 vp9_inv_dct_dct_32x32_sub8_add_neon: 3684.4 vp9_inv_dct_dct_32x32_sub12_add_neon: 5312.2 vp9_inv_dct_dct_32x32_sub16_add_neon: 5315.4 vp9_inv_dct_dct_32x32_sub20_add_neon: 7154.9 vp9_inv_dct_dct_32x32_sub24_add_neon: 7154.5 vp9_inv_dct_dct_32x32_sub28_add_neon: 8126.6 vp9_inv_dct_dct_32x32_sub32_add_neon: 8127.2 This is cherrypicked from libav commit a63da4511d0fee66695ff4afd264ba1dbf1e812d. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 525 +++++++++++++++++++++++++---- 1 file changed, 466 insertions(+), 59 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index e45d385870cea..3eb999a9cf02c 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -75,6 +75,17 @@ endconst .endif .endm +// Same as dmbutterfly0 above, but treating the input in in2 as zero, +// writing the same output into both out1 and out2. +.macro dmbutterfly0_h out1, out2, in1, in2, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6 + smull \tmp1\().4s, \in1\().4h, v0.h[0] + smull2 \tmp2\().4s, \in1\().8h, v0.h[0] + rshrn \out1\().4h, \tmp1\().4s, #14 + rshrn2 \out1\().8h, \tmp2\().4s, #14 + rshrn \out2\().4h, \tmp1\().4s, #14 + rshrn2 \out2\().8h, \tmp2\().4s, #14 +.endm + // out1,out2 = in1 * coef1 - in2 * coef2 // out3,out4 = in1 * coef2 + in2 * coef1 // out are 4 x .4s registers, in are 2 x .8h registers @@ -104,6 +115,43 @@ endconst rshrn2 \inout2\().8h, \tmp4\().4s, #14 .endm +// Same as dmbutterfly above, but treating the input in inout2 as zero +.macro dmbutterfly_h1 inout1, inout2, coef1, coef2, tmp1, tmp2, tmp3, tmp4 + smull \tmp1\().4s, \inout1\().4h, \coef1 + smull2 \tmp2\().4s, \inout1\().8h, \coef1 + smull \tmp3\().4s, \inout1\().4h, \coef2 + smull2 \tmp4\().4s, \inout1\().8h, \coef2 + rshrn \inout1\().4h, \tmp1\().4s, #14 + rshrn2 \inout1\().8h, \tmp2\().4s, #14 + rshrn \inout2\().4h, \tmp3\().4s, #14 + rshrn2 \inout2\().8h, \tmp4\().4s, #14 +.endm + +// Same as dmbutterfly above, but treating the input in inout1 as zero +.macro dmbutterfly_h2 inout1, inout2, coef1, coef2, tmp1, tmp2, tmp3, tmp4 + smull \tmp1\().4s, \inout2\().4h, \coef2 + smull2 \tmp2\().4s, \inout2\().8h, \coef2 + smull \tmp3\().4s, \inout2\().4h, \coef1 + smull2 \tmp4\().4s, \inout2\().8h, \coef1 + neg \tmp1\().4s, \tmp1\().4s + neg \tmp2\().4s, \tmp2\().4s + rshrn \inout2\().4h, \tmp3\().4s, #14 + rshrn2 \inout2\().8h, \tmp4\().4s, #14 + rshrn \inout1\().4h, \tmp1\().4s, #14 + rshrn2 \inout1\().8h, \tmp2\().4s, #14 +.endm + +.macro dsmull_h out1, out2, in, coef + smull \out1\().4s, \in\().4h, \coef + smull2 \out2\().4s, \in\().8h, \coef +.endm + +.macro drshrn_h out, in1, in2, shift + rshrn \out\().4h, \in1\().4s, \shift + rshrn2 \out\().8h, \in2\().4s, \shift +.endm + + // out1 = in1 + in2 // out2 = in1 - in2 .macro butterfly_8h out1, out2, in1, in2 @@ -463,6 +511,30 @@ function idct16x16_dc_add_neon ret endfunc +.macro idct16_end + butterfly_8h v18, v7, v4, v7 // v18 = t0a, v7 = t7a + butterfly_8h v19, v22, v5, v22 // v19 = t1a, v22 = t6 + butterfly_8h v4, v26, v20, v26 // v4 = t2a, v26 = t5 + butterfly_8h v5, v6, v28, v6 // v5 = t3a, v6 = t4 + butterfly_8h v20, v28, v16, v24 // v20 = t8a, v28 = t11a + butterfly_8h v24, v21, v23, v21 // v24 = t9, v21 = t10 + butterfly_8h v23, v27, v25, v27 // v23 = t14, v27 = t13 + butterfly_8h v25, v29, v29, v17 // v25 = t15a, v29 = t12a + + dmbutterfly0 v2, v3, v27, v21, v2, v3, v16, v17, v30, v31 // v2 = t13a, v3 = t10a + dmbutterfly0 v28, v27, v29, v28, v21, v29, v16, v17, v30, v31 // v28 = t12, v27 = t11 + + butterfly_8h v16, v31, v18, v25 // v16 = out[0], v31 = out[15] + butterfly_8h v17, v30, v19, v23 // v17 = out[1], v30 = out[14] + butterfly_8h_r v25, v22, v22, v24 // v25 = out[9], v22 = out[6] + butterfly_8h v23, v24, v7, v20 // v23 = out[7], v24 = out[8] + butterfly_8h v18, v29, v4, v2 // v18 = out[2], v29 = out[13] + butterfly_8h v19, v28, v5, v28 // v19 = out[3], v28 = out[12] + butterfly_8h v20, v27, v6, v27 // v20 = out[4], v27 = out[11] + butterfly_8h v21, v26, v26, v3 // v21 = out[5], v26 = out[10] + ret +.endm + function idct16 dmbutterfly0 v16, v24, v16, v24, v2, v3, v4, v5, v6, v7 // v16 = t0a, v24 = t1a dmbutterfly v20, v28, v0.h[1], v0.h[2], v2, v3, v4, v5 // v20 = t2a, v28 = t3a @@ -485,28 +557,65 @@ function idct16 dmbutterfly0 v22, v26, v22, v26, v2, v3, v18, v19, v30, v31 // v22 = t6a, v26 = t5a dmbutterfly v23, v25, v0.h[1], v0.h[2], v18, v19, v30, v31 // v23 = t9a, v25 = t14a dmbutterfly v27, v21, v0.h[1], v0.h[2], v18, v19, v30, v31, neg=1 // v27 = t13a, v21 = t10a + idct16_end +endfunc - butterfly_8h v18, v7, v4, v7 // v18 = t0a, v7 = t7a - butterfly_8h v19, v22, v5, v22 // v19 = t1a, v22 = t6 - butterfly_8h v4, v26, v20, v26 // v4 = t2a, v26 = t5 - butterfly_8h v5, v6, v28, v6 // v5 = t3a, v6 = t4 - butterfly_8h v20, v28, v16, v24 // v20 = t8a, v28 = t11a - butterfly_8h v24, v21, v23, v21 // v24 = t9, v21 = t10 - butterfly_8h v23, v27, v25, v27 // v23 = t14, v27 = t13 - butterfly_8h v25, v29, v29, v17 // v25 = t15a, v29 = t12a +function idct16_half + dmbutterfly0_h v16, v24, v16, v24, v2, v3, v4, v5, v6, v7 // v16 = t0a, v24 = t1a + dmbutterfly_h1 v20, v28, v0.h[1], v0.h[2], v2, v3, v4, v5 // v20 = t2a, v28 = t3a + dmbutterfly_h1 v18, v30, v0.h[3], v0.h[4], v2, v3, v4, v5 // v18 = t4a, v30 = t7a + dmbutterfly_h2 v26, v22, v0.h[5], v0.h[6], v2, v3, v4, v5 // v26 = t5a, v22 = t6a + dmbutterfly_h1 v17, v31, v0.h[7], v1.h[0], v2, v3, v4, v5 // v17 = t8a, v31 = t15a + dmbutterfly_h2 v25, v23, v1.h[1], v1.h[2], v2, v3, v4, v5 // v25 = t9a, v23 = t14a + dmbutterfly_h1 v21, v27, v1.h[3], v1.h[4], v2, v3, v4, v5 // v21 = t10a, v27 = t13a + dmbutterfly_h2 v29, v19, v1.h[5], v1.h[6], v2, v3, v4, v5 // v29 = t11a, v19 = t12a - dmbutterfly0 v2, v3, v27, v21, v2, v3, v16, v17, v30, v31 // v2 = t13a, v3 = t10a - dmbutterfly0 v28, v27, v29, v28, v21, v29, v16, v17, v30, v31 // v28 = t12, v27 = t11 + butterfly_8h v4, v28, v16, v28 // v4 = t0, v28 = t3 + butterfly_8h v5, v20, v24, v20 // v5 = t1, v20 = t2 + butterfly_8h v6, v26, v18, v26 // v6 = t4, v26 = t5 + butterfly_8h v7, v22, v30, v22 // v7 = t7, v22 = t6 + butterfly_8h v16, v25, v17, v25 // v16 = t8, v25 = t9 + butterfly_8h v24, v21, v29, v21 // v24 = t11, v21 = t10 + butterfly_8h v17, v27, v19, v27 // v17 = t12, v27 = t13 + butterfly_8h v29, v23, v31, v23 // v29 = t15, v23 = t14 - butterfly_8h v16, v31, v18, v25 // v16 = out[0], v31 = out[15] - butterfly_8h v17, v30, v19, v23 // v17 = out[1], v30 = out[14] - butterfly_8h_r v25, v22, v22, v24 // v25 = out[9], v22 = out[6] - butterfly_8h v23, v24, v7, v20 // v23 = out[7], v24 = out[8] - butterfly_8h v18, v29, v4, v2 // v18 = out[2], v29 = out[13] - butterfly_8h v19, v28, v5, v28 // v19 = out[3], v28 = out[12] - butterfly_8h v20, v27, v6, v27 // v20 = out[4], v27 = out[11] - butterfly_8h v21, v26, v26, v3 // v21 = out[5], v26 = out[10] - ret + dmbutterfly0 v22, v26, v22, v26, v2, v3, v18, v19, v30, v31 // v22 = t6a, v26 = t5a + dmbutterfly v23, v25, v0.h[1], v0.h[2], v18, v19, v30, v31 // v23 = t9a, v25 = t14a + dmbutterfly v27, v21, v0.h[1], v0.h[2], v18, v19, v30, v31, neg=1 // v27 = t13a, v21 = t10a + idct16_end +endfunc + +function idct16_quarter + dsmull_h v24, v25, v19, v1.h[6] + dsmull_h v4, v5, v17, v0.h[7] + dsmull_h v7, v6, v18, v0.h[4] + dsmull_h v30, v31, v18, v0.h[3] + neg v24.4s, v24.4s + neg v25.4s, v25.4s + dsmull_h v29, v28, v17, v1.h[0] + dsmull_h v26, v27, v19, v1.h[5] + dsmull_h v22, v23, v16, v0.h[0] + drshrn_h v24, v24, v25, #14 + drshrn_h v16, v4, v5, #14 + drshrn_h v7, v7, v6, #14 + drshrn_h v6, v30, v31, #14 + drshrn_h v29, v29, v28, #14 + drshrn_h v17, v26, v27, #14 + drshrn_h v28, v22, v23, #14 + + dmbutterfly_l v20, v21, v22, v23, v17, v24, v0.h[1], v0.h[2] + dmbutterfly_l v18, v19, v30, v31, v29, v16, v0.h[1], v0.h[2] + neg v22.4s, v22.4s + neg v23.4s, v23.4s + drshrn_h v27, v20, v21, #14 + drshrn_h v21, v22, v23, #14 + drshrn_h v23, v18, v19, #14 + drshrn_h v25, v30, v31, #14 + mov v4.16b, v28.16b + mov v5.16b, v28.16b + dmbutterfly0 v22, v26, v7, v6, v18, v19, v30, v31 + mov v20.16b, v28.16b + idct16_end endfunc function iadst16 @@ -756,6 +865,13 @@ function ff_vp9_\txfm1\()_\txfm2\()_16x16_add_neon, export=1 .endif mov x9, #32 +.ifc \txfm1\()_\txfm2,idct_idct + cmp w3, #10 + b.le idct16x16_quarter_add_neon + cmp w3, #38 + b.le idct16x16_half_add_neon +.endif + .irp i, 0, 8 add x0, sp, #(\i*32) .ifc \txfm1\()_\txfm2,idct_idct @@ -812,6 +928,116 @@ itxfm_func16x16 iadst, idct itxfm_func16x16 idct, iadst itxfm_func16x16 iadst, iadst +function idct16_1d_8x16_pass1_quarter_neon + mov x14, x30 + movi v2.8h, #0 +.irp i, 16, 17, 18, 19 + load_clear \i, x2, x9 +.endr + + bl idct16_quarter + + // Do two 8x8 transposes. Originally, v16-v31 contain the + // 16 rows. Afterwards, v16-v23 and v24-v31 contain the two + // transposed 8x8 blocks. + transpose_8x8H v16, v17, v18, v19, v20, v21, v22, v23, v2, v3 + transpose_8x8H v24, v25, v26, v27, v28, v29, v30, v31, v2, v3 + + // Store the transposed 8x8 blocks horizontally. + // The first 8x8 block is kept in registers for the second pass, + // store the rest in the temp buffer. + // Since only a 4x4 part of the input was nonzero, this means that + // only 4 rows are nonzero after transposing, and the second pass + // only reads the topmost 4 rows. Therefore only store the topmost + // 4 rows. + add x0, x0, #16 +.irp i, 24, 25, 26, 27 + store \i, x0, x9 +.endr + br x14 +endfunc + +function idct16_1d_8x16_pass2_quarter_neon + mov x14, x30 + cbz x3, 1f +.irp i, 16, 17, 18, 19 + load \i, x2, x9 +.endr +1: + + add x3, x0, x1 + lsl x1, x1, #1 + bl idct16_quarter + + load_add_store v16.8h, v17.8h, v18.8h, v19.8h, v20.8h, v21.8h, v22.8h, v23.8h, v16.8b, v17.8b + load_add_store v24.8h, v25.8h, v26.8h, v27.8h, v28.8h, v29.8h, v30.8h, v31.8h, v16.8b, v17.8b + + br x14 +endfunc + +function idct16_1d_8x16_pass1_half_neon + mov x14, x30 + movi v2.8h, #0 +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + load_clear \i, x2, x9 +.endr + + bl idct16_half + + // Do two 8x8 transposes. Originally, v16-v31 contain the + // 16 rows. Afterwards, v16-v23 and v24-v31 contain the two + // transposed 8x8 blocks. + transpose_8x8H v16, v17, v18, v19, v20, v21, v22, v23, v2, v3 + transpose_8x8H v24, v25, v26, v27, v28, v29, v30, v31, v2, v3 + + // Store the transposed 8x8 blocks horizontally. + // The first 8x8 block is kept in registers for the second pass, + // store the rest in the temp buffer. + add x0, x0, #16 +.irp i, 24, 25, 26, 27, 28, 29, 30, 31 + store \i, x0, x9 +.endr + br x14 +endfunc + +function idct16_1d_8x16_pass2_half_neon + mov x14, x30 + cbz x3, 1f +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + load \i, x2, x9 +.endr +1: + + add x3, x0, x1 + lsl x1, x1, #1 + bl idct16_half + + load_add_store v16.8h, v17.8h, v18.8h, v19.8h, v20.8h, v21.8h, v22.8h, v23.8h, v16.8b, v17.8b + load_add_store v24.8h, v25.8h, v26.8h, v27.8h, v28.8h, v29.8h, v30.8h, v31.8h, v16.8b, v17.8b + + br x14 +endfunc + +.macro idct16_partial size +function idct16x16_\size\()_add_neon + add x0, sp, #(0*32) + add x2, x6, #(0*2) + bl idct16_1d_8x16_pass1_\size\()_neon +.irp i, 0, 8 + add x0, x4, #(\i) + mov x1, x5 + add x2, sp, #(\i*2) + mov x3, #\i + bl idct16_1d_8x16_pass2_\size\()_neon +.endr + + add sp, sp, #512 + br x15 +endfunc +.endm + +idct16_partial quarter +idct16_partial half function idct32x32_dc_add_neon movrel x4, idct_coeffs @@ -848,6 +1074,37 @@ function idct32x32_dc_add_neon ret endfunc +.macro idct32_end + butterfly_8h v16, v5, v4, v5 // v16 = t16a, v5 = t19a + butterfly_8h v17, v20, v23, v20 // v17 = t17, v20 = t18 + butterfly_8h v18, v6, v7, v6 // v18 = t23a, v6 = t20a + butterfly_8h v19, v21, v22, v21 // v19 = t22, v21 = t21 + butterfly_8h v4, v28, v28, v30 // v4 = t24a, v28 = t27a + butterfly_8h v23, v26, v25, v26 // v23 = t25, v26 = t26 + butterfly_8h v7, v3, v29, v31 // v7 = t31a, v3 = t28a + butterfly_8h v22, v27, v24, v27 // v22 = t30, v27 = t29 + + dmbutterfly v27, v20, v0.h[1], v0.h[2], v24, v25, v30, v31 // v27 = t18a, v20 = t29a + dmbutterfly v3, v5, v0.h[1], v0.h[2], v24, v25, v30, v31 // v3 = t19, v5 = t28 + dmbutterfly v28, v6, v0.h[1], v0.h[2], v24, v25, v30, v31, neg=1 // v28 = t27, v6 = t20 + dmbutterfly v26, v21, v0.h[1], v0.h[2], v24, v25, v30, v31, neg=1 // v26 = t26a, v21 = t21a + + butterfly_8h v31, v24, v7, v4 // v31 = t31, v24 = t24 + butterfly_8h v30, v25, v22, v23 // v30 = t30a, v25 = t25a + butterfly_8h_r v23, v16, v16, v18 // v23 = t23, v16 = t16 + butterfly_8h_r v22, v17, v17, v19 // v22 = t22a, v17 = t17a + butterfly_8h v18, v21, v27, v21 // v18 = t18, v21 = t21 + butterfly_8h_r v27, v28, v5, v28 // v27 = t27a, v28 = t28a + butterfly_8h v29, v26, v20, v26 // v29 = t29, v26 = t26 + butterfly_8h v19, v20, v3, v6 // v19 = t19a, v20 = t20 + + dmbutterfly0 v27, v20, v27, v20, v2, v3, v4, v5, v6, v7 // v27 = t27, v20 = t20 + dmbutterfly0 v26, v21, v26, v21, v2, v3, v4, v5, v6, v7 // v26 = t26a, v21 = t21a + dmbutterfly0 v25, v22, v25, v22, v2, v3, v4, v5, v6, v7 // v25 = t25, v22 = t22 + dmbutterfly0 v24, v23, v24, v23, v2, v3, v4, v5, v6, v7 // v24 = t24a, v23 = t23a + ret +.endm + function idct32_odd ld1 {v0.8h,v1.8h}, [x11] @@ -875,37 +1132,88 @@ function idct32_odd dmbutterfly v27, v20, v0.h[3], v0.h[4], v16, v17, v18, v19, neg=1 // v27 = t29a, v20 = t18a dmbutterfly v21, v26, v0.h[5], v0.h[6], v16, v17, v18, v19 // v21 = t21a, v26 = t26a dmbutterfly v25, v22, v0.h[5], v0.h[6], v16, v17, v18, v19, neg=1 // v25 = t25a, v22 = t22a + idct32_end +endfunc - butterfly_8h v16, v5, v4, v5 // v16 = t16a, v5 = t19a - butterfly_8h v17, v20, v23, v20 // v17 = t17, v20 = t18 - butterfly_8h v18, v6, v7, v6 // v18 = t23a, v6 = t20a - butterfly_8h v19, v21, v22, v21 // v19 = t22, v21 = t21 - butterfly_8h v4, v28, v28, v30 // v4 = t24a, v28 = t27a - butterfly_8h v23, v26, v25, v26 // v23 = t25, v26 = t26 - butterfly_8h v7, v3, v29, v31 // v7 = t31a, v3 = t28a - butterfly_8h v22, v27, v24, v27 // v22 = t30, v27 = t29 +function idct32_odd_half + ld1 {v0.8h,v1.8h}, [x11] - dmbutterfly v27, v20, v0.h[1], v0.h[2], v24, v25, v30, v31 // v27 = t18a, v20 = t29a - dmbutterfly v3, v5, v0.h[1], v0.h[2], v24, v25, v30, v31 // v3 = t19, v5 = t28 - dmbutterfly v28, v6, v0.h[1], v0.h[2], v24, v25, v30, v31, neg=1 // v28 = t27, v6 = t20 - dmbutterfly v26, v21, v0.h[1], v0.h[2], v24, v25, v30, v31, neg=1 // v26 = t26a, v21 = t21a + dmbutterfly_h1 v16, v31, v0.h[0], v0.h[1], v4, v5, v6, v7 // v16 = t16a, v31 = t31a + dmbutterfly_h2 v24, v23, v0.h[2], v0.h[3], v4, v5, v6, v7 // v24 = t17a, v23 = t30a + dmbutterfly_h1 v20, v27, v0.h[4], v0.h[5], v4, v5, v6, v7 // v20 = t18a, v27 = t29a + dmbutterfly_h2 v28, v19, v0.h[6], v0.h[7], v4, v5, v6, v7 // v28 = t19a, v19 = t28a + dmbutterfly_h1 v18, v29, v1.h[0], v1.h[1], v4, v5, v6, v7 // v18 = t20a, v29 = t27a + dmbutterfly_h2 v26, v21, v1.h[2], v1.h[3], v4, v5, v6, v7 // v26 = t21a, v21 = t26a + dmbutterfly_h1 v22, v25, v1.h[4], v1.h[5], v4, v5, v6, v7 // v22 = t22a, v25 = t25a + dmbutterfly_h2 v30, v17, v1.h[6], v1.h[7], v4, v5, v6, v7 // v30 = t23a, v17 = t24a - butterfly_8h v31, v24, v7, v4 // v31 = t31, v24 = t24 - butterfly_8h v30, v25, v22, v23 // v30 = t30a, v25 = t25a - butterfly_8h_r v23, v16, v16, v18 // v23 = t23, v16 = t16 - butterfly_8h_r v22, v17, v17, v19 // v22 = t22a, v17 = t17a - butterfly_8h v18, v21, v27, v21 // v18 = t18, v21 = t21 - butterfly_8h_r v27, v28, v5, v28 // v27 = t27a, v28 = t28a - butterfly_8h v29, v26, v20, v26 // v29 = t29, v26 = t26 - butterfly_8h v19, v20, v3, v6 // v19 = t19a, v20 = t20 + ld1 {v0.8h}, [x10] - dmbutterfly0 v27, v20, v27, v20, v2, v3, v4, v5, v6, v7 // v27 = t27, v20 = t20 - dmbutterfly0 v26, v21, v26, v21, v2, v3, v4, v5, v6, v7 // v26 = t26a, v21 = t21a - dmbutterfly0 v25, v22, v25, v22, v2, v3, v4, v5, v6, v7 // v25 = t25, v22 = t22 - dmbutterfly0 v24, v23, v24, v23, v2, v3, v4, v5, v6, v7 // v24 = t24a, v23 = t23a - ret + butterfly_8h v4, v24, v16, v24 // v4 = t16, v24 = t17 + butterfly_8h v5, v20, v28, v20 // v5 = t19, v20 = t18 + butterfly_8h v6, v26, v18, v26 // v6 = t20, v26 = t21 + butterfly_8h v7, v22, v30, v22 // v7 = t23, v22 = t22 + butterfly_8h v28, v25, v17, v25 // v28 = t24, v25 = t25 + butterfly_8h v30, v21, v29, v21 // v30 = t27, v21 = t26 + butterfly_8h v29, v23, v31, v23 // v29 = t31, v23 = t30 + butterfly_8h v31, v27, v19, v27 // v31 = t28, v27 = t29 + + dmbutterfly v23, v24, v0.h[3], v0.h[4], v16, v17, v18, v19 // v23 = t17a, v24 = t30a + dmbutterfly v27, v20, v0.h[3], v0.h[4], v16, v17, v18, v19, neg=1 // v27 = t29a, v20 = t18a + dmbutterfly v21, v26, v0.h[5], v0.h[6], v16, v17, v18, v19 // v21 = t21a, v26 = t26a + dmbutterfly v25, v22, v0.h[5], v0.h[6], v16, v17, v18, v19, neg=1 // v25 = t25a, v22 = t22a + idct32_end endfunc +function idct32_odd_quarter + ld1 {v0.8h,v1.8h}, [x11] + + dsmull_h v4, v5, v16, v0.h[0] + dsmull_h v28, v29, v19, v0.h[7] + dsmull_h v30, v31, v16, v0.h[1] + dsmull_h v22, v23, v17, v1.h[6] + dsmull_h v7, v6, v17, v1.h[7] + dsmull_h v26, v27, v19, v0.h[6] + dsmull_h v20, v21, v18, v1.h[0] + dsmull_h v24, v25, v18, v1.h[1] + + ld1 {v0.8h}, [x10] + + neg v28.4s, v28.4s + neg v29.4s, v29.4s + neg v7.4s, v7.4s + neg v6.4s, v6.4s + + drshrn_h v4, v4, v5, #14 + drshrn_h v5, v28, v29, #14 + drshrn_h v29, v30, v31, #14 + drshrn_h v28, v22, v23, #14 + drshrn_h v7, v7, v6, #14 + drshrn_h v31, v26, v27, #14 + drshrn_h v6, v20, v21, #14 + drshrn_h v30, v24, v25, #14 + + dmbutterfly_l v16, v17, v18, v19, v29, v4, v0.h[3], v0.h[4] + dmbutterfly_l v27, v26, v20, v21, v31, v5, v0.h[3], v0.h[4] + drshrn_h v23, v16, v17, #14 + drshrn_h v24, v18, v19, #14 + neg v20.4s, v20.4s + neg v21.4s, v21.4s + drshrn_h v27, v27, v26, #14 + drshrn_h v20, v20, v21, #14 + dmbutterfly_l v16, v17, v18, v19, v30, v6, v0.h[5], v0.h[6] + drshrn_h v21, v16, v17, #14 + drshrn_h v26, v18, v19, #14 + dmbutterfly_l v16, v17, v18, v19, v28, v7, v0.h[5], v0.h[6] + drshrn_h v25, v16, v17, #14 + neg v18.4s, v18.4s + neg v19.4s, v19.4s + drshrn_h v22, v18, v19, #14 + + idct32_end +endfunc + +.macro idct32_funcs suffix // Do an 32-point IDCT of a 8x32 slice out of a 32x32 matrix. // The 32-point IDCT can be decomposed into two 16-point IDCTs; // a normal IDCT16 with every other input component (the even ones, with @@ -917,19 +1225,30 @@ endfunc // x9 = double input stride // x10 = idct_coeffs // x11 = idct_coeffs + 32 -function idct32_1d_8x32_pass1_neon +function idct32_1d_8x32_pass1\suffix\()_neon mov x14, x30 ld1 {v0.8h,v1.8h}, [x10] - movi v4.8h, #0 + movi v2.8h, #0 // v16 = IN(0), v17 = IN(2) ... v31 = IN(30) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 - ld1 {v\i\().8h}, [x2] - st1 {v4.8h}, [x2], x9 + load_clear \i, x2, x9 .endr +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + load_clear \i, x2, x9 +.endr +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + load_clear \i, x2, x9 +.endr +.endif - bl idct16 + bl idct16\suffix // Do two 8x8 transposes. Originally, v16-v31 contain the // 16 rows. Afterwards, v16-v23 and v24-v31 contain the @@ -964,17 +1283,36 @@ function idct32_1d_8x32_pass1_neon // Move x2 back to the start of the input, and move // to the first odd row +.ifb \suffix sub x2, x2, x9, lsl #4 +.endif +.ifc \suffix,_quarter + sub x2, x2, x9, lsl #2 +.endif +.ifc \suffix,_half + sub x2, x2, x9, lsl #3 +.endif add x2, x2, #64 - movi v4.8h, #0 + movi v2.8h, #0 // v16 = IN(1), v17 = IN(3) ... v31 = IN(31) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 - ld1 {v\i\().8h}, [x2] - st1 {v4.8h}, [x2], x9 + load_clear \i, x2, x9 +.endr +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + load_clear \i, x2, x9 +.endr +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + load_clear \i, x2, x9 .endr +.endif - bl idct32_odd + bl idct32_odd\suffix transpose_8x8H v31, v30, v29, v28, v27, v26, v25, v24, v2, v3 transpose_8x8H v23, v22, v21, v20, v19, v18, v17, v16, v2, v3 @@ -1023,33 +1361,61 @@ endfunc // x9 = double temp buffer stride // x10 = idct_coeffs // x11 = idct_coeffs + 32 -function idct32_1d_8x32_pass2_neon +function idct32_1d_8x32_pass2\suffix\()_neon mov x14, x30 ld1 {v0.8h,v1.8h}, [x10] // v16 = IN(0), v17 = IN(2) ... v31 = IN(30) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 - ld1 {v\i\().8h}, [x2], x9 + load \i, x2, x9 .endr sub x2, x2, x9, lsl #4 +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + load \i, x2, x9 +.endr + sub x2, x2, x9, lsl #2 +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + load \i, x2, x9 +.endr + sub x2, x2, x9, lsl #3 +.endif - bl idct16 + bl idct16\suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 - st1 {v\i\().8h}, [x2], x9 + store \i, x2, x9 .endr sub x2, x2, x9, lsl #4 add x2, x2, #64 // v16 = IN(1), v17 = IN(3) ... v31 = IN(31) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 - ld1 {v\i\().8h}, [x2], x9 + load \i, x2, x9 .endr sub x2, x2, x9, lsl #4 +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + load \i, x2, x9 +.endr + sub x2, x2, x9, lsl #2 +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + load \i, x2, x9 +.endr + sub x2, x2, x9, lsl #3 +.endif sub x2, x2, #64 - bl idct32_odd + bl idct32_odd\suffix .macro load_acc_store a, b, c, d, neg=0 .if \neg == 0 @@ -1105,6 +1471,11 @@ function idct32_1d_8x32_pass2_neon .purgem load_acc_store br x14 endfunc +.endm + +idct32_funcs +idct32_funcs _quarter +idct32_funcs _half const min_eob_idct_idct_32, align=4 .short 0, 34, 135, 336 @@ -1135,6 +1506,11 @@ function ff_vp9_idct_idct_32x32_add_neon, export=1 mov x9, #128 neg x7, x9 + cmp w3, #34 + b.le idct32x32_quarter_add_neon + cmp w3, #135 + b.le idct32x32_half_add_neon + .irp i, 0, 8, 16, 24 add x0, sp, #(\i*64) .if \i > 0 @@ -1177,3 +1553,34 @@ function ff_vp9_idct_idct_32x32_add_neon, export=1 br x15 endfunc + +.macro idct32_partial size +function idct32x32_\size\()_add_neon + add x0, sp, #(0*64) + add x2, x6, #(0*2) + bl idct32_1d_8x32_pass1_\size\()_neon +.ifc \size,half + add x0, sp, #(8*64) + add x2, x6, #(8*2) + bl idct32_1d_8x32_pass1_\size\()_neon +.endif +.irp i, 0, 8, 16, 24 + add x0, x4, #(\i) + mov x1, x5 + add x2, sp, #(\i*2) + bl idct32_1d_8x32_pass2_\size\()_neon +.endr + + add sp, sp, #2048 + + ldp d8, d9, [sp], 0x10 + ldp d10, d11, [sp], 0x10 + ldp d12, d13, [sp], 0x10 + ldp d14, d15, [sp], 0x10 + + br x15 +endfunc +.endm + +idct32_partial quarter +idct32_partial half From 1d8ab576a7e40ea6209dd753929f26dcb37e1444 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 3 Jan 2017 16:38:56 +0200 Subject: [PATCH 1085/3374] arm: vp9itxfm: Share instructions for loading idct coeffs in the 8x8 function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is cherrypicked from libav commit 3933b86bb93aca47f29fbd493075b0f110c1e3f5. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index 33a7af1109fe0..78fdae661f3d0 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -412,13 +412,12 @@ function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_neon, export=1 .ifc \txfm1\()_\txfm2,idct_idct movrel r12, idct_coeffs vpush {q4-q5} - vld1.16 {q0}, [r12,:128] .else movrel r12, iadst8_coeffs vld1.16 {q1}, [r12,:128]! vpush {q4-q7} - vld1.16 {q0}, [r12,:128] .endif + vld1.16 {q0}, [r12,:128] vmov.i16 q2, #0 vmov.i16 q3, #0 From 3006e5253afc6a0ee001916806aae80f157d7043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 3 Jan 2017 16:39:41 +0200 Subject: [PATCH 1086/3374] aarch64: vp9itxfm: Share instructions for loading idct coeffs in the 8x8 function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is cherrypicked from libav commit 4da4b2b87f08a1331650c7e36eb7d4029a160776. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index 3eb999a9cf02c..df178d216b46d 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -379,12 +379,11 @@ function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_neon, export=1 // idct, so those always need to be loaded. .ifc \txfm1\()_\txfm2,idct_idct movrel x4, idct_coeffs - ld1 {v0.8h}, [x4] .else movrel x4, iadst8_coeffs ld1 {v1.8h}, [x4], #16 - ld1 {v0.8h}, [x4] .endif + ld1 {v0.8h}, [x4] movi v2.16b, #0 movi v3.16b, #0 From 19a0f9529ccdb48696f0caa251fe36b1d30df739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 3 Jan 2017 14:55:46 +0200 Subject: [PATCH 1087/3374] aarch64: vp9itxfm: Use a single lane ld1 instead of ld1r where possible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ld1r is a leftover from the arm version, where this trick is beneficial on some cores. Use a single-lane load where we don't need the semantics of ld1r. This is cherrypicked from libav commit ed8d293306e12c9b79022d37d39f48825ce7f2fa. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index df178d216b46d..e42cc2d821b88 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -255,7 +255,7 @@ function ff_vp9_\txfm1\()_\txfm2\()_4x4_add_neon, export=1 cmp w3, #1 b.ne 1f // DC-only for idct/idct - ld1r {v2.4h}, [x2] + ld1 {v2.h}[0], [x2] smull v2.4s, v2.4h, v0.h[0] rshrn v2.4h, v2.4s, #14 smull v2.4s, v2.4h, v0.h[0] @@ -287,8 +287,8 @@ function ff_vp9_\txfm1\()_\txfm2\()_4x4_add_neon, export=1 \txfm2\()4 v4, v5, v6, v7 2: - ld1r {v0.2s}, [x0], x1 - ld1r {v1.2s}, [x0], x1 + ld1 {v0.s}[0], [x0], x1 + ld1 {v1.s}[0], [x0], x1 .ifnc \txfm1,iwht srshr v4.4h, v4.4h, #4 srshr v5.4h, v5.4h, #4 @@ -297,8 +297,8 @@ function ff_vp9_\txfm1\()_\txfm2\()_4x4_add_neon, export=1 .endif uaddw v4.8h, v4.8h, v0.8b uaddw v5.8h, v5.8h, v1.8b - ld1r {v2.2s}, [x0], x1 - ld1r {v3.2s}, [x0], x1 + ld1 {v2.s}[0], [x0], x1 + ld1 {v3.s}[0], [x0], x1 sqxtun v0.8b, v4.8h sqxtun v1.8b, v5.8h sub x0, x0, x1, lsl #2 @@ -394,7 +394,7 @@ function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_neon, export=1 cmp w3, #1 b.ne 1f // DC-only for idct/idct - ld1r {v2.4h}, [x2] + ld1 {v2.h}[0], [x2] smull v2.4s, v2.4h, v0.h[0] rshrn v2.4h, v2.4s, #14 smull v2.4s, v2.4h, v0.h[0] @@ -485,7 +485,7 @@ function idct16x16_dc_add_neon movi v1.4h, #0 - ld1r {v2.4h}, [x2] + ld1 {v2.h}[0], [x2] smull v2.4s, v2.4h, v0.h[0] rshrn v2.4h, v2.4s, #14 smull v2.4s, v2.4h, v0.h[0] @@ -1044,7 +1044,7 @@ function idct32x32_dc_add_neon movi v1.4h, #0 - ld1r {v2.4h}, [x2] + ld1 {v2.h}[0], [x2] smull v2.4s, v2.4h, v0.h[0] rshrn v2.4h, v2.4s, #14 smull v2.4s, v2.4h, v0.h[0] From 6752318c737663f0ac019de3acd63e3cea706864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 3 Jan 2017 16:46:17 +0200 Subject: [PATCH 1088/3374] aarch64: vp9itxfm: Use the right lane sizes in 8x8 for improved readability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is cherrypicked from libav commit 3dd7827258ddaa2e51085d0c677d6f3b1be3572f. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index e42cc2d821b88..3b347496cecad 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -385,10 +385,10 @@ function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_neon, export=1 .endif ld1 {v0.8h}, [x4] - movi v2.16b, #0 - movi v3.16b, #0 - movi v4.16b, #0 - movi v5.16b, #0 + movi v2.8h, #0 + movi v3.8h, #0 + movi v4.8h, #0 + movi v5.8h, #0 .ifc \txfm1\()_\txfm2,idct_idct cmp w3, #1 @@ -411,11 +411,11 @@ function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_neon, export=1 b 2f .endif 1: - ld1 {v16.16b,v17.16b,v18.16b,v19.16b}, [x2], #64 - ld1 {v20.16b,v21.16b,v22.16b,v23.16b}, [x2], #64 + ld1 {v16.8h,v17.8h,v18.8h,v19.8h}, [x2], #64 + ld1 {v20.8h,v21.8h,v22.8h,v23.8h}, [x2], #64 sub x2, x2, #128 - st1 {v2.16b,v3.16b,v4.16b,v5.16b}, [x2], #64 - st1 {v2.16b,v3.16b,v4.16b,v5.16b}, [x2], #64 + st1 {v2.8h,v3.8h,v4.8h,v5.8h}, [x2], #64 + st1 {v2.8h,v3.8h,v4.8h,v5.8h}, [x2], #64 \txfm1\()8 From d0fbf7f34e7243f6a4cbde9925f34d924e6d93f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 3 Jan 2017 23:11:51 +0200 Subject: [PATCH 1089/3374] aarch64: vp9itxfm: Update a comment to refer to a register with a different name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is cherrypicked from libav commit 8476eb0d3ab1f7a52317b23346646389c08fb57a. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index 3b347496cecad..5219d6e18c26b 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -41,8 +41,8 @@ const iadst16_coeffs, align=4 .short 11003, 12140, 8423, 14053, 5520, 15426, 2404, 16207 endconst -// out1 = ((in1 + in2) * d0[0] + (1 << 13)) >> 14 -// out2 = ((in1 - in2) * d0[0] + (1 << 13)) >> 14 +// out1 = ((in1 + in2) * v0[0] + (1 << 13)) >> 14 +// out2 = ((in1 - in2) * v0[0] + (1 << 13)) >> 14 // in/out are .8h registers; this can do with 4 temp registers, but is // more efficient if 6 temp registers are available. .macro dmbutterfly0 out1, out2, in1, in2, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, neg=0 From 16ef000799b227d0226b7a678d28c34ff1d09410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 3 Jan 2017 16:11:56 +0200 Subject: [PATCH 1090/3374] aarch64: vp9itxfm: Fix incorrect vertical alignment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is cherrypicked from libav commit 0c0b87f12d48d4e7f0d3d13f9345e828a3a5ea32. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index 5219d6e18c26b..6bb097b47124c 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -225,7 +225,7 @@ endconst add v21.4s, v17.4s, v19.4s rshrn \c0\().4h, v20.4s, #14 add v16.4s, v16.4s, v17.4s - rshrn \c1\().4h, v21.4s, #14 + rshrn \c1\().4h, v21.4s, #14 sub v16.4s, v16.4s, v19.4s rshrn \c2\().4h, v18.4s, #14 rshrn \c3\().4h, v16.4s, #14 @@ -1313,8 +1313,8 @@ function idct32_1d_8x32_pass1\suffix\()_neon bl idct32_odd\suffix - transpose_8x8H v31, v30, v29, v28, v27, v26, v25, v24, v2, v3 - transpose_8x8H v23, v22, v21, v20, v19, v18, v17, v16, v2, v3 + transpose_8x8H v31, v30, v29, v28, v27, v26, v25, v24, v2, v3 + transpose_8x8H v23, v22, v21, v20, v19, v18, v17, v16, v2, v3 // Store the registers a, b horizontally, // adding into the output first, and the mirrored, From ac6cb8ae5b1c56c4a3fceb635c60d05e447c4365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 17 Dec 2016 00:55:41 +0200 Subject: [PATCH 1091/3374] aarch64: vp9mc: Simplify the extmla macro parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fold the field lengths into the macro. This makes the macro invocations much more readable, when the lines are shorter. This also makes it easier to use only half the registers within the macro. This is cherrypicked from libav commit 5e0c2158fbc774f87d3ce4b7b950ba4d42c4a7b8. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9mc_neon.S | 50 ++++++++++++++++----------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/libavcodec/aarch64/vp9mc_neon.S b/libavcodec/aarch64/vp9mc_neon.S index 80d1d238d687f..94039114bd0de 100644 --- a/libavcodec/aarch64/vp9mc_neon.S +++ b/libavcodec/aarch64/vp9mc_neon.S @@ -193,41 +193,41 @@ endfunc // for size >= 16), and multiply-accumulate into dst1 and dst3 (or // dst1-dst2 and dst3-dst4 for size >= 16) .macro extmla dst1, dst2, dst3, dst4, src1, src2, src3, src4, src5, src6, offset, size - ext v20.16b, \src1, \src2, #(2*\offset) - ext v22.16b, \src4, \src5, #(2*\offset) + ext v20.16b, \src1\().16b, \src2\().16b, #(2*\offset) + ext v22.16b, \src4\().16b, \src5\().16b, #(2*\offset) .if \size >= 16 - mla \dst1, v20.8h, v0.h[\offset] - ext v21.16b, \src2, \src3, #(2*\offset) - mla \dst3, v22.8h, v0.h[\offset] - ext v23.16b, \src5, \src6, #(2*\offset) - mla \dst2, v21.8h, v0.h[\offset] - mla \dst4, v23.8h, v0.h[\offset] + mla \dst1\().8h, v20.8h, v0.h[\offset] + ext v21.16b, \src2\().16b, \src3\().16b, #(2*\offset) + mla \dst3\().8h, v22.8h, v0.h[\offset] + ext v23.16b, \src5\().16b, \src6\().16b, #(2*\offset) + mla \dst2\().8h, v21.8h, v0.h[\offset] + mla \dst4\().8h, v23.8h, v0.h[\offset] .else - mla \dst1, v20.8h, v0.h[\offset] - mla \dst3, v22.8h, v0.h[\offset] + mla \dst1\().8h, v20.8h, v0.h[\offset] + mla \dst3\().8h, v22.8h, v0.h[\offset] .endif .endm // The same as above, but don't accumulate straight into the // destination, but use a temp register and accumulate with saturation. .macro extmulqadd dst1, dst2, dst3, dst4, src1, src2, src3, src4, src5, src6, offset, size - ext v20.16b, \src1, \src2, #(2*\offset) - ext v22.16b, \src4, \src5, #(2*\offset) + ext v20.16b, \src1\().16b, \src2\().16b, #(2*\offset) + ext v22.16b, \src4\().16b, \src5\().16b, #(2*\offset) .if \size >= 16 mul v20.8h, v20.8h, v0.h[\offset] - ext v21.16b, \src2, \src3, #(2*\offset) + ext v21.16b, \src2\().16b, \src3\().16b, #(2*\offset) mul v22.8h, v22.8h, v0.h[\offset] - ext v23.16b, \src5, \src6, #(2*\offset) + ext v23.16b, \src5\().16b, \src6\().16b, #(2*\offset) mul v21.8h, v21.8h, v0.h[\offset] mul v23.8h, v23.8h, v0.h[\offset] .else mul v20.8h, v20.8h, v0.h[\offset] mul v22.8h, v22.8h, v0.h[\offset] .endif - sqadd \dst1, \dst1, v20.8h - sqadd \dst3, \dst3, v22.8h + sqadd \dst1\().8h, \dst1\().8h, v20.8h + sqadd \dst3\().8h, \dst3\().8h, v22.8h .if \size >= 16 - sqadd \dst2, \dst2, v21.8h - sqadd \dst4, \dst4, v23.8h + sqadd \dst2\().8h, \dst2\().8h, v21.8h + sqadd \dst4\().8h, \dst4\().8h, v23.8h .endif .endm @@ -291,13 +291,13 @@ function \type\()_8tap_\size\()h_\idx1\idx2 mul v2.8h, v5.8h, v0.h[0] mul v25.8h, v17.8h, v0.h[0] .endif - extmla v1.8h, v2.8h, v24.8h, v25.8h, v4.16b, v5.16b, v6.16b, v16.16b, v17.16b, v18.16b, 1, \size - extmla v1.8h, v2.8h, v24.8h, v25.8h, v4.16b, v5.16b, v6.16b, v16.16b, v17.16b, v18.16b, 2, \size - extmla v1.8h, v2.8h, v24.8h, v25.8h, v4.16b, v5.16b, v6.16b, v16.16b, v17.16b, v18.16b, \idx1, \size - extmla v1.8h, v2.8h, v24.8h, v25.8h, v4.16b, v5.16b, v6.16b, v16.16b, v17.16b, v18.16b, 5, \size - extmla v1.8h, v2.8h, v24.8h, v25.8h, v4.16b, v5.16b, v6.16b, v16.16b, v17.16b, v18.16b, 6, \size - extmla v1.8h, v2.8h, v24.8h, v25.8h, v4.16b, v5.16b, v6.16b, v16.16b, v17.16b, v18.16b, 7, \size - extmulqadd v1.8h, v2.8h, v24.8h, v25.8h, v4.16b, v5.16b, v6.16b, v16.16b, v17.16b, v18.16b, \idx2, \size + extmla v1, v2, v24, v25, v4, v5, v6, v16, v17, v18, 1, \size + extmla v1, v2, v24, v25, v4, v5, v6, v16, v17, v18, 2, \size + extmla v1, v2, v24, v25, v4, v5, v6, v16, v17, v18, \idx1, \size + extmla v1, v2, v24, v25, v4, v5, v6, v16, v17, v18, 5, \size + extmla v1, v2, v24, v25, v4, v5, v6, v16, v17, v18, 6, \size + extmla v1, v2, v24, v25, v4, v5, v6, v16, v17, v18, 7, \size + extmulqadd v1, v2, v24, v25, v4, v5, v6, v16, v17, v18, \idx2, \size // Round, shift and saturate sqrshrun v1.8b, v1.8h, #7 From bff07715904cc02f04eb5c5e171b431eb00f0c3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 17 Dec 2016 13:09:50 +0200 Subject: [PATCH 1092/3374] arm: vp9mc: Calculate less unused data in the 4 pixel wide horizontal filter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before: Cortex A7 A8 A9 A53 vp9_put_8tap_smooth_4h_neon: 378.1 273.2 340.7 229.5 After: vp9_put_8tap_smooth_4h_neon: 352.1 222.2 290.5 229.5 This is cherrypicked from libav commit fea92a4b57d1c328b1de226a5f213a629ee63754. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9mc_neon.S | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/libavcodec/arm/vp9mc_neon.S b/libavcodec/arm/vp9mc_neon.S index 83235ff23f21c..bd8cda7c308f6 100644 --- a/libavcodec/arm/vp9mc_neon.S +++ b/libavcodec/arm/vp9mc_neon.S @@ -209,7 +209,7 @@ endfunc @ Extract a vector from src1-src2 and src4-src5 (src1-src3 and src4-src6 @ for size >= 16), and multiply-accumulate into dst1 and dst3 (or @ dst1-dst2 and dst3-dst4 for size >= 16) -.macro extmla dst1, dst2, dst3, dst4, src1, src2, src3, src4, src5, src6, offset, size +.macro extmla dst1, dst2, dst3, dst4, dst1d, dst3d, src1, src2, src3, src4, src5, src6, offset, size vext.8 q14, \src1, \src2, #(2*\offset) vext.8 q15, \src4, \src5, #(2*\offset) .if \size >= 16 @@ -219,14 +219,17 @@ endfunc vext.8 q6, \src5, \src6, #(2*\offset) vmla_lane \dst2, q5, \offset vmla_lane \dst4, q6, \offset -.else +.elseif \size == 8 vmla_lane \dst1, q14, \offset vmla_lane \dst3, q15, \offset +.else + vmla_lane \dst1d, d28, \offset + vmla_lane \dst3d, d30, \offset .endif .endm @ The same as above, but don't accumulate straight into the @ destination, but use a temp register and accumulate with saturation. -.macro extmulqadd dst1, dst2, dst3, dst4, src1, src2, src3, src4, src5, src6, offset, size +.macro extmulqadd dst1, dst2, dst3, dst4, dst1d, dst3d, src1, src2, src3, src4, src5, src6, offset, size vext.8 q14, \src1, \src2, #(2*\offset) vext.8 q15, \src4, \src5, #(2*\offset) .if \size >= 16 @@ -236,16 +239,24 @@ endfunc vext.8 q6, \src5, \src6, #(2*\offset) vmul_lane q5, q5, \offset vmul_lane q6, q6, \offset -.else +.elseif \size == 8 vmul_lane q14, q14, \offset vmul_lane q15, q15, \offset +.else + vmul_lane d28, d28, \offset + vmul_lane d30, d30, \offset .endif +.if \size == 4 + vqadd.s16 \dst1d, \dst1d, d28 + vqadd.s16 \dst3d, \dst3d, d30 +.else vqadd.s16 \dst1, \dst1, q14 vqadd.s16 \dst3, \dst3, q15 .if \size >= 16 vqadd.s16 \dst2, \dst2, q5 vqadd.s16 \dst4, \dst4, q6 .endif +.endif .endm @@ -308,13 +319,13 @@ function \type\()_8tap_\size\()h_\idx1\idx2 vmul.s16 q2, q9, d0[0] vmul.s16 q4, q12, d0[0] .endif - extmla q1, q2, q3, q4, q8, q9, q10, q11, q12, q13, 1, \size - extmla q1, q2, q3, q4, q8, q9, q10, q11, q12, q13, 2, \size - extmla q1, q2, q3, q4, q8, q9, q10, q11, q12, q13, \idx1, \size - extmla q1, q2, q3, q4, q8, q9, q10, q11, q12, q13, 5, \size - extmla q1, q2, q3, q4, q8, q9, q10, q11, q12, q13, 6, \size - extmla q1, q2, q3, q4, q8, q9, q10, q11, q12, q13, 7, \size - extmulqadd q1, q2, q3, q4, q8, q9, q10, q11, q12, q13, \idx2, \size + extmla q1, q2, q3, q4, d2, d6, q8, q9, q10, q11, q12, q13, 1, \size + extmla q1, q2, q3, q4, d2, d6, q8, q9, q10, q11, q12, q13, 2, \size + extmla q1, q2, q3, q4, d2, d6, q8, q9, q10, q11, q12, q13, \idx1, \size + extmla q1, q2, q3, q4, d2, d6, q8, q9, q10, q11, q12, q13, 5, \size + extmla q1, q2, q3, q4, d2, d6, q8, q9, q10, q11, q12, q13, 6, \size + extmla q1, q2, q3, q4, d2, d6, q8, q9, q10, q11, q12, q13, 7, \size + extmulqadd q1, q2, q3, q4, d2, d6, q8, q9, q10, q11, q12, q13, \idx2, \size @ Round, shift and saturate vqrshrun.s16 d2, q1, #7 From 045e33ae3fee74e39b1321dddf727eacb1ecf541 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 17 Dec 2016 13:14:38 +0200 Subject: [PATCH 1093/3374] aarch64: vp9mc: Calculate less unused data in the 4 pixel wide horizontal filter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No measured speedup on a Cortex A53, but other cores might benefit. This is cherrypicked from libav commit 388e0d2515bc6bbc9d0c9af1d230bd16cf945fe7. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9mc_neon.S | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/libavcodec/aarch64/vp9mc_neon.S b/libavcodec/aarch64/vp9mc_neon.S index 94039114bd0de..82a0f53133728 100644 --- a/libavcodec/aarch64/vp9mc_neon.S +++ b/libavcodec/aarch64/vp9mc_neon.S @@ -202,9 +202,12 @@ endfunc ext v23.16b, \src5\().16b, \src6\().16b, #(2*\offset) mla \dst2\().8h, v21.8h, v0.h[\offset] mla \dst4\().8h, v23.8h, v0.h[\offset] -.else +.elseif \size == 8 mla \dst1\().8h, v20.8h, v0.h[\offset] mla \dst3\().8h, v22.8h, v0.h[\offset] +.else + mla \dst1\().4h, v20.4h, v0.h[\offset] + mla \dst3\().4h, v22.4h, v0.h[\offset] .endif .endm // The same as above, but don't accumulate straight into the @@ -219,16 +222,24 @@ endfunc ext v23.16b, \src5\().16b, \src6\().16b, #(2*\offset) mul v21.8h, v21.8h, v0.h[\offset] mul v23.8h, v23.8h, v0.h[\offset] -.else +.elseif \size == 8 mul v20.8h, v20.8h, v0.h[\offset] mul v22.8h, v22.8h, v0.h[\offset] +.else + mul v20.4h, v20.4h, v0.h[\offset] + mul v22.4h, v22.4h, v0.h[\offset] .endif +.if \size == 4 + sqadd \dst1\().4h, \dst1\().4h, v20.4h + sqadd \dst3\().4h, \dst3\().4h, v22.4h +.else sqadd \dst1\().8h, \dst1\().8h, v20.8h sqadd \dst3\().8h, \dst3\().8h, v22.8h .if \size >= 16 sqadd \dst2\().8h, \dst2\().8h, v21.8h sqadd \dst4\().8h, \dst4\().8h, v23.8h .endif +.endif .endm From 758302e4bc14e93989e7feb1135ec3f807c3310d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 4 Jan 2017 13:08:51 +0200 Subject: [PATCH 1094/3374] arm: vp9itxfm: Optimize 16x16 and 32x32 idct dc by unrolling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. Before: Cortex A7 A8 A9 A53 vp9_inv_dct_dct_16x16_sub1_add_neon: 273.0 189.5 211.7 235.8 vp9_inv_dct_dct_32x32_sub1_add_neon: 752.0 459.2 862.2 553.9 After: vp9_inv_dct_dct_16x16_sub1_add_neon: 226.5 145.0 225.1 171.8 vp9_inv_dct_dct_32x32_sub1_add_neon: 721.2 415.7 727.6 475.0 This is cherrypicked from libav commit a76bf8cf1277ef6feb1580b578f5e6ca327e713c. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 54 ++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index 78fdae661f3d0..dee2f058efead 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -542,16 +542,23 @@ function idct16x16_dc_add_neon vrshr.s16 q8, q8, #6 + mov r3, r0 mov r12, #16 1: @ Loop to add the constant from q8 into all 16x16 outputs - vld1.8 {q3}, [r0,:128] - vaddw.u8 q10, q8, d6 - vaddw.u8 q11, q8, d7 - vqmovun.s16 d6, q10 - vqmovun.s16 d7, q11 - vst1.8 {q3}, [r0,:128], r1 - subs r12, r12, #1 + subs r12, r12, #2 + vld1.8 {q2}, [r0,:128], r1 + vaddw.u8 q10, q8, d4 + vld1.8 {q3}, [r0,:128], r1 + vaddw.u8 q11, q8, d5 + vaddw.u8 q12, q8, d6 + vaddw.u8 q13, q8, d7 + vqmovun.s16 d4, q10 + vqmovun.s16 d5, q11 + vqmovun.s16 d6, q12 + vst1.8 {q2}, [r3,:128], r1 + vqmovun.s16 d7, q13 + vst1.8 {q3}, [r3,:128], r1 bne 1b bx lr @@ -1147,20 +1154,31 @@ function idct32x32_dc_add_neon vrshr.s16 q8, q8, #6 + mov r3, r0 mov r12, #32 1: @ Loop to add the constant from q8 into all 32x32 outputs - vld1.8 {q2-q3}, [r0,:128] - vaddw.u8 q10, q8, d4 - vaddw.u8 q11, q8, d5 - vaddw.u8 q12, q8, d6 - vaddw.u8 q13, q8, d7 - vqmovun.s16 d4, q10 - vqmovun.s16 d5, q11 - vqmovun.s16 d6, q12 - vqmovun.s16 d7, q13 - vst1.8 {q2-q3}, [r0,:128], r1 - subs r12, r12, #1 + subs r12, r12, #2 + vld1.8 {q0-q1}, [r0,:128], r1 + vaddw.u8 q9, q8, d0 + vaddw.u8 q10, q8, d1 + vld1.8 {q2-q3}, [r0,:128], r1 + vaddw.u8 q11, q8, d2 + vaddw.u8 q12, q8, d3 + vaddw.u8 q13, q8, d4 + vaddw.u8 q14, q8, d5 + vaddw.u8 q15, q8, d6 + vqmovun.s16 d0, q9 + vaddw.u8 q9, q8, d7 + vqmovun.s16 d1, q10 + vqmovun.s16 d2, q11 + vqmovun.s16 d3, q12 + vqmovun.s16 d4, q13 + vqmovun.s16 d5, q14 + vst1.8 {q0-q1}, [r3,:128], r1 + vqmovun.s16 d6, q15 + vqmovun.s16 d7, q9 + vst1.8 {q2-q3}, [r3,:128], r1 bne 1b bx lr From 148cc0bb890839bc2a9cda514c5e71acc39eb374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 4 Jan 2017 12:57:56 +0200 Subject: [PATCH 1095/3374] aarch64: vp9itxfm: Optimize 16x16 and 32x32 idct dc by unrolling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. Before: Cortex A53 vp9_inv_dct_dct_16x16_sub1_add_neon: 235.3 vp9_inv_dct_dct_32x32_sub1_add_neon: 555.1 After: vp9_inv_dct_dct_16x16_sub1_add_neon: 180.2 vp9_inv_dct_dct_32x32_sub1_add_neon: 475.3 This is cherrypicked from libav commit 3fcf788fbbccc4130868e7abe58a88990290f7c1. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 54 ++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index 6bb097b47124c..be65eb791930c 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -495,16 +495,23 @@ function idct16x16_dc_add_neon srshr v2.8h, v2.8h, #6 + mov x3, x0 mov x4, #16 1: // Loop to add the constant from v2 into all 16x16 outputs - ld1 {v3.16b}, [x0] - uaddw v4.8h, v2.8h, v3.8b - uaddw2 v5.8h, v2.8h, v3.16b - sqxtun v4.8b, v4.8h - sqxtun2 v4.16b, v5.8h - st1 {v4.16b}, [x0], x1 - subs x4, x4, #1 + subs x4, x4, #2 + ld1 {v3.16b}, [x0], x1 + ld1 {v4.16b}, [x0], x1 + uaddw v16.8h, v2.8h, v3.8b + uaddw2 v17.8h, v2.8h, v3.16b + uaddw v18.8h, v2.8h, v4.8b + uaddw2 v19.8h, v2.8h, v4.16b + sqxtun v3.8b, v16.8h + sqxtun2 v3.16b, v17.8h + sqxtun v4.8b, v18.8h + sqxtun2 v4.16b, v19.8h + st1 {v3.16b}, [x3], x1 + st1 {v4.16b}, [x3], x1 b.ne 1b ret @@ -1054,20 +1061,31 @@ function idct32x32_dc_add_neon srshr v0.8h, v2.8h, #6 + mov x3, x0 mov x4, #32 1: // Loop to add the constant v0 into all 32x32 outputs - ld1 {v1.16b,v2.16b}, [x0] - uaddw v3.8h, v0.8h, v1.8b - uaddw2 v4.8h, v0.8h, v1.16b - uaddw v5.8h, v0.8h, v2.8b - uaddw2 v6.8h, v0.8h, v2.16b - sqxtun v3.8b, v3.8h - sqxtun2 v3.16b, v4.8h - sqxtun v4.8b, v5.8h - sqxtun2 v4.16b, v6.8h - st1 {v3.16b,v4.16b}, [x0], x1 - subs x4, x4, #1 + subs x4, x4, #2 + ld1 {v1.16b,v2.16b}, [x0], x1 + uaddw v16.8h, v0.8h, v1.8b + uaddw2 v17.8h, v0.8h, v1.16b + ld1 {v3.16b,v4.16b}, [x0], x1 + uaddw v18.8h, v0.8h, v2.8b + uaddw2 v19.8h, v0.8h, v2.16b + uaddw v20.8h, v0.8h, v3.8b + uaddw2 v21.8h, v0.8h, v3.16b + uaddw v22.8h, v0.8h, v4.8b + uaddw2 v23.8h, v0.8h, v4.16b + sqxtun v1.8b, v16.8h + sqxtun2 v1.16b, v17.8h + sqxtun v2.8b, v18.8h + sqxtun2 v2.16b, v19.8h + sqxtun v3.8b, v20.8h + sqxtun2 v3.16b, v21.8h + st1 {v1.16b,v2.16b}, [x3], x1 + sqxtun v4.8b, v22.8h + sqxtun2 v4.16b, v23.8h + st1 {v3.16b,v4.16b}, [x3], x1 b.ne 1b ret From f0ecbb13cf1cf706a1350dad657219dc7b3c131e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 12 Jan 2017 16:52:33 +0200 Subject: [PATCH 1096/3374] arm/aarch64: vp9lpf: Calculate !hev directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously we first calculated hev, and then negated it. Since we were able to schedule the negation in the middle of another calculation, we don't see any gain in all cases. Before: Cortex A7 A8 A9 A53 A53/AArch64 vp9_loop_filter_v_4_8_neon: 147.0 129.0 115.8 89.0 88.7 vp9_loop_filter_v_8_8_neon: 242.0 198.5 174.7 140.0 136.7 vp9_loop_filter_v_16_8_neon: 500.0 419.5 382.7 293.0 275.7 vp9_loop_filter_v_16_16_neon: 971.2 825.5 731.5 579.0 453.0 After: vp9_loop_filter_v_4_8_neon: 143.0 127.7 114.8 88.0 87.7 vp9_loop_filter_v_8_8_neon: 241.0 197.2 173.7 140.0 136.7 vp9_loop_filter_v_16_8_neon: 497.0 419.5 379.7 293.0 275.7 vp9_loop_filter_v_16_16_neon: 965.2 818.7 731.4 579.0 452.0 This is cherrypicked from libav commit e1f9de86f454861b69b199ad801adc2ec6c3b220. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9lpf_neon.S | 5 ++--- libavcodec/arm/vp9lpf_neon.S | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/libavcodec/aarch64/vp9lpf_neon.S b/libavcodec/aarch64/vp9lpf_neon.S index 55e1964c47866..7fe2c88f9ea0d 100644 --- a/libavcodec/aarch64/vp9lpf_neon.S +++ b/libavcodec/aarch64/vp9lpf_neon.S @@ -292,7 +292,7 @@ .if \mix != 0 sxtl v1.8h, v1.8b .endif - cmhi v5\sz, v5\sz, v3\sz // hev + cmhs v5\sz, v3\sz, v5\sz // !hev .if \wd == 8 // If a 4/8 or 8/4 mix is used, clear the relevant half of v6 .if \mix != 0 @@ -306,11 +306,10 @@ .elseif \wd == 8 bic v4\sz, v4\sz, v6\sz // fm && !flat8in .endif - mvn v5\sz, v5\sz // !hev + and v5\sz, v5\sz, v4\sz // !hev && fm && !flat8in .if \wd == 16 and v7\sz, v7\sz, v6\sz // flat8out && flat8in && fm .endif - and v5\sz, v5\sz, v4\sz // !hev && fm && !flat8in mul_sz \tmp3\().8h, \tmp4\().8h, \tmp3\().8h, \tmp4\().8h, \tmp5\().8h, \tmp5\().8h, \sz // 3 * (q0 - p0) bic \tmp1\sz, \tmp1\sz, v5\sz // if (!hev) av_clip_int8 = 0 diff --git a/libavcodec/arm/vp9lpf_neon.S b/libavcodec/arm/vp9lpf_neon.S index e96f4db7c9f53..2761956c0cbb9 100644 --- a/libavcodec/arm/vp9lpf_neon.S +++ b/libavcodec/arm/vp9lpf_neon.S @@ -141,7 +141,7 @@ .if \wd == 8 vcle.u8 d6, d6, d0 @ flat8in .endif - vcgt.u8 d5, d5, d3 @ hev + vcle.u8 d5, d5, d3 @ !hev .if \wd == 8 vand d6, d6, d4 @ flat8in && fm .endif @@ -151,11 +151,10 @@ .elseif \wd == 8 vbic d4, d4, d6 @ fm && !flat8in .endif - vmvn d5, d5 @ !hev + vand d5, d5, d4 @ !hev && fm && !flat8in .if \wd == 16 vand d7, d7, d6 @ flat8out && flat8in && fm .endif - vand d5, d5, d4 @ !hev && fm && !flat8in vmul.s16 \tmpq2, \tmpq2, \tmpq3 @ 3 * (q0 - p0) vbic \tmp1, \tmp1, d5 @ if (!hev) av_clip_int8 = 0 From 92ab8374b1051dd632c3ccc326b6cb1d564f293f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 13 Jan 2017 23:42:28 +0200 Subject: [PATCH 1097/3374] arm: vp9lpf: Use orrs instead of orr+cmp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is cherrypicked from libav commit 435cd7bc99671bf561193421a50ac6e9d63c4266. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9lpf_neon.S | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/libavcodec/arm/vp9lpf_neon.S b/libavcodec/arm/vp9lpf_neon.S index 2761956c0cbb9..3d289e5d08cae 100644 --- a/libavcodec/arm/vp9lpf_neon.S +++ b/libavcodec/arm/vp9lpf_neon.S @@ -78,8 +78,7 @@ vdup.u8 d3, r3 @ H vmov r2, r3, d4 - orr r2, r2, r3 - cmp r2, #0 + orrs r2, r2, r3 @ If no pixels need filtering, just exit as soon as possible beq 9f @@ -192,8 +191,7 @@ .if \wd >= 8 vmov r2, r3, d6 - orr r2, r2, r3 - cmp r2, #0 + orrs r2, r2, r3 @ If no pixels need flat8in, jump to flat8out @ (or to a writeout of the inner 4 pixels, for wd=8) beq 6f @@ -248,14 +246,12 @@ 6: vorr d2, d6, d7 vmov r2, r3, d2 - orr r2, r2, r3 - cmp r2, #0 + orrs r2, r2, r3 @ If no pixels needed flat8in nor flat8out, jump to a @ writeout of the inner 4 pixels beq 7f vmov r2, r3, d7 - orr r2, r2, r3 - cmp r2, #0 + orrs r2, r2, r3 @ If no pixels need flat8out, jump to a writeout of the inner 6 pixels beq 8f From 83399cf569c9f78e0c72e21aa67184c222bb2d59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 10 Jan 2017 16:49:13 +0200 Subject: [PATCH 1098/3374] arm: vp9lpf: Interleave the start of flat8in into the calculation above MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds lots of extra .ifs, but speeds it up by a couple cycles, by avoiding stalls. This is cherrypicked from libav commit e18c39005ad1dbb178b336f691da1de91afd434e. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9lpf_neon.S | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libavcodec/arm/vp9lpf_neon.S b/libavcodec/arm/vp9lpf_neon.S index 3d289e5d08cae..b90c53630acf4 100644 --- a/libavcodec/arm/vp9lpf_neon.S +++ b/libavcodec/arm/vp9lpf_neon.S @@ -182,16 +182,20 @@ vmovl.u8 q0, d22 @ p1 vmovl.u8 q1, d25 @ q1 +.if \wd >= 8 + vmov r2, r3, d6 +.endif vaddw.s8 q0, q0, \tmp3 @ p1 + f vsubw.s8 q1, q1, \tmp3 @ q1 - f +.if \wd >= 8 + orrs r2, r2, r3 +.endif vqmovun.s16 d0, q0 @ out p1 vqmovun.s16 d2, q1 @ out q1 vbit d22, d0, d5 @ if (!hev && fm && !flat8in) vbit d25, d2, d5 .if \wd >= 8 - vmov r2, r3, d6 - orrs r2, r2, r3 @ If no pixels need flat8in, jump to flat8out @ (or to a writeout of the inner 4 pixels, for wd=8) beq 6f From 9f3a8863648ed19ea69ca5ddfcfa3c80e0df15b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 10 Jan 2017 22:08:50 +0200 Subject: [PATCH 1099/3374] aarch64: vp9lpf: Interleave the start of flat8in into the calculation above MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds lots of extra .ifs, but speeds it up by a couple cycles, by avoiding stalls. This is cherrypicked from libav commit b0806088d3b27044145b20421da8d39089ae0c6a. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9lpf_neon.S | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/libavcodec/aarch64/vp9lpf_neon.S b/libavcodec/aarch64/vp9lpf_neon.S index 7fe2c88f9ea0d..cd3e26c95775c 100644 --- a/libavcodec/aarch64/vp9lpf_neon.S +++ b/libavcodec/aarch64/vp9lpf_neon.S @@ -338,20 +338,28 @@ uxtl_sz v0.8h, v1.8h, v22, \sz // p1 uxtl_sz v2.8h, v3.8h, v25, \sz // q1 +.if \wd >= 8 + mov x5, v6.d[0] +.ifc \sz, .16b + mov x6, v6.d[1] +.endif +.endif saddw_sz v0.8h, v1.8h, v0.8h, v1.8h, \tmp3, \sz // p1 + f ssubw_sz v2.8h, v3.8h, v2.8h, v3.8h, \tmp3, \sz // q1 - f sqxtun_sz v0, v0.8h, v1.8h, \sz // out p1 sqxtun_sz v2, v2.8h, v3.8h, \sz // out q1 +.if \wd >= 8 +.ifc \sz, .16b + adds x5, x5, x6 +.endif +.endif bit v22\sz, v0\sz, v5\sz // if (!hev && fm && !flat8in) bit v25\sz, v2\sz, v5\sz // If no pixels need flat8in, jump to flat8out // (or to a writeout of the inner 4 pixels, for wd=8) .if \wd >= 8 - mov x5, v6.d[0] .ifc \sz, .16b - mov x6, v6.d[1] - adds x5, x5, x6 b.eq 6f .else cbz x5, 6f From c8d6eec85d6a87c9075c87d5eb75af47c964fff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 11 Jan 2017 11:58:02 +0200 Subject: [PATCH 1100/3374] aarch64: vp9lpf: Fix broken indentation/vertical alignment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is cherrypicked from libav commit 07b5136c481d394992c7e951967df0cfbb346c0b. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9lpf_neon.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/aarch64/vp9lpf_neon.S b/libavcodec/aarch64/vp9lpf_neon.S index cd3e26c95775c..ebfd9bebe3639 100644 --- a/libavcodec/aarch64/vp9lpf_neon.S +++ b/libavcodec/aarch64/vp9lpf_neon.S @@ -417,7 +417,7 @@ mov x5, v2.d[0] .ifc \sz, .16b mov x6, v2.d[1] - adds x5, x5, x6 + adds x5, x5, x6 b.ne 1f .else cbnz x5, 1f @@ -430,7 +430,7 @@ mov x5, v7.d[0] .ifc \sz, .16b mov x6, v7.d[1] - adds x5, x5, x6 + adds x5, x5, x6 b.ne 1f .else cbnz x5, 1f From dda45c087b2c09ba9e485c51ff9c8f2aaca709a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 16 Feb 2017 09:18:25 +0200 Subject: [PATCH 1101/3374] aarch64: Add parentheses around the offset parameter in movrel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes building with clang for linux with PIC enabled. This is cherrypicked from libav commit 8847eeaa141898850381400000fb2b8a7adc7100. Signed-off-by: Martin Storsjö --- libavutil/aarch64/asm.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavutil/aarch64/asm.S b/libavutil/aarch64/asm.S index 523b8c5b4c059..42897294280b1 100644 --- a/libavutil/aarch64/asm.S +++ b/libavutil/aarch64/asm.S @@ -83,8 +83,8 @@ ELF .size \name, . - \name add \rd, \rd, \val+(\offset)@PAGEOFF .endif #elif CONFIG_PIC - adrp \rd, \val+\offset - add \rd, \rd, :lo12:\val+\offset + adrp \rd, \val+(\offset) + add \rd, \rd, :lo12:\val+(\offset) #else ldr \rd, =\val+\offset #endif From 3fbbad29847c79f422128ad88f174c53a5f6c449 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 14 Jan 2017 20:49:19 +0200 Subject: [PATCH 1102/3374] arm/aarch64: vp9lpf: Keep the comparison to E within 8 bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The theoretical maximum value of E is 193, so we can just saturate the addition to 255. Before: Cortex A7 A8 A9 A53 A53/AArch64 vp9_loop_filter_v_4_8_neon: 143.0 127.7 114.8 88.0 87.7 vp9_loop_filter_v_8_8_neon: 241.0 197.2 173.7 140.0 136.7 vp9_loop_filter_v_16_8_neon: 497.0 419.5 379.7 293.0 275.7 vp9_loop_filter_v_16_16_neon: 965.2 818.7 731.4 579.0 452.0 After: vp9_loop_filter_v_4_8_neon: 136.0 125.7 112.6 84.0 83.0 vp9_loop_filter_v_8_8_neon: 234.0 195.5 171.5 136.0 133.7 vp9_loop_filter_v_16_8_neon: 490.0 417.5 377.7 289.0 271.0 vp9_loop_filter_v_16_16_neon: 951.2 814.7 732.3 571.0 446.7 This is cherrypicked from libav commit c582cb8537367721bb399a5d01b652c20142b756. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9lpf_neon.S | 40 +++++++------------------------- libavcodec/arm/vp9lpf_neon.S | 11 ++++----- 2 files changed, 14 insertions(+), 37 deletions(-) diff --git a/libavcodec/aarch64/vp9lpf_neon.S b/libavcodec/aarch64/vp9lpf_neon.S index ebfd9bebe3639..a9eea7f951a64 100644 --- a/libavcodec/aarch64/vp9lpf_neon.S +++ b/libavcodec/aarch64/vp9lpf_neon.S @@ -51,13 +51,6 @@ // see the arm version instead. -.macro uabdl_sz dst1, dst2, in1, in2, sz - uabdl \dst1, \in1\().8b, \in2\().8b -.ifc \sz, .16b - uabdl2 \dst2, \in1\().16b, \in2\().16b -.endif -.endm - .macro add_sz dst1, dst2, in1, in2, in3, in4, sz add \dst1, \in1, \in3 .ifc \sz, .16b @@ -86,20 +79,6 @@ .endif .endm -.macro cmhs_sz dst1, dst2, in1, in2, in3, in4, sz - cmhs \dst1, \in1, \in3 -.ifc \sz, .16b - cmhs \dst2, \in2, \in4 -.endif -.endm - -.macro xtn_sz dst, in1, in2, sz - xtn \dst\().8b, \in1 -.ifc \sz, .16b - xtn2 \dst\().16b, \in2 -.endif -.endm - .macro usubl_sz dst1, dst2, in1, in2, sz usubl \dst1, \in1\().8b, \in2\().8b .ifc \sz, .16b @@ -179,20 +158,20 @@ // tmpq2 == tmp3 + tmp4, etc. .macro loop_filter wd, sz, mix, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8 .if \mix == 0 - dup v0.8h, w2 // E - dup v1.8h, w2 // E + dup v0\sz, w2 // E dup v2\sz, w3 // I dup v3\sz, w4 // H .else - dup v0.8h, w2 // E + dup v0.8b, w2 // E dup v2.8b, w3 // I dup v3.8b, w4 // H + lsr w5, w2, #8 lsr w6, w3, #8 lsr w7, w4, #8 - ushr v1.8h, v0.8h, #8 // E + dup v1.8b, w5 // E dup v4.8b, w6 // I - bic v0.8h, #255, lsl 8 // E dup v5.8b, w7 // H + trn1 v0.2d, v0.2d, v1.2d trn1 v2.2d, v2.2d, v4.2d trn1 v3.2d, v3.2d, v5.2d .endif @@ -206,16 +185,15 @@ umax v4\sz, v4\sz, v5\sz umax v5\sz, v6\sz, v7\sz umax \tmp1\sz, \tmp1\sz, \tmp2\sz - uabdl_sz v6.8h, v7.8h, v23, v24, \sz // abs(p0 - q0) + uabd v6\sz, v23\sz, v24\sz // abs(p0 - q0) umax v4\sz, v4\sz, v5\sz - add_sz v6.8h, v7.8h, v6.8h, v7.8h, v6.8h, v7.8h, \sz // abs(p0 - q0) * 2 + uqadd v6\sz, v6\sz, v6\sz // abs(p0 - q0) * 2 uabd v5\sz, v22\sz, v25\sz // abs(p1 - q1) umax v4\sz, v4\sz, \tmp1\sz // max(abs(p3 - p2), ..., abs(q2 - q3)) ushr v5\sz, v5\sz, #1 cmhs v4\sz, v2\sz, v4\sz // max(abs()) <= I - uaddw_sz v6.8h, v7.8h, v6.8h, v7.8h, v5, \sz // abs(p0 - q0) * 2 + abs(p1 - q1) >> 1 - cmhs_sz v6.8h, v7.8h, v0.8h, v1.8h, v6.8h, v7.8h, \sz - xtn_sz v5, v6.8h, v7.8h, \sz + uqadd v6\sz, v6\sz, v5\sz // abs(p0 - q0) * 2 + abs(p1 - q1) >> 1 + cmhs v5\sz, v0\sz, v6\sz and v4\sz, v4\sz, v5\sz // fm // If no pixels need filtering, just exit as soon as possible diff --git a/libavcodec/arm/vp9lpf_neon.S b/libavcodec/arm/vp9lpf_neon.S index b90c53630acf4..2d91092ee097f 100644 --- a/libavcodec/arm/vp9lpf_neon.S +++ b/libavcodec/arm/vp9lpf_neon.S @@ -51,7 +51,7 @@ @ and d28-d31 as temp registers, or d8-d15. @ tmp1,tmp2 = tmpq1, tmp3,tmp4 = tmpq2, tmp5,tmp6 = tmpq3, tmp7,tmp8 = tmpq4 .macro loop_filter wd, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmpq1, tmpq2, tmpq3, tmpq4 - vdup.u16 q0, r2 @ E + vdup.u8 d0, r2 @ E vdup.u8 d2, r3 @ I ldr r3, [sp] @@ -64,16 +64,15 @@ vmax.u8 d4, d4, d5 vmax.u8 d5, d6, d7 vmax.u8 \tmp1, \tmp1, \tmp2 - vabdl.u8 q3, d23, d24 @ abs(p0 - q0) + vabd.u8 d6, d23, d24 @ abs(p0 - q0) vmax.u8 d4, d4, d5 - vadd.u16 q3, q3, q3 @ abs(p0 - q0) * 2 + vqadd.u8 d6, d6, d6 @ abs(p0 - q0) * 2 vabd.u8 d5, d22, d25 @ abs(p1 - q1) vmax.u8 d4, d4, \tmp1 @ max(abs(p3 - p2), ..., abs(q2 - q3)) vshr.u8 d5, d5, #1 vcle.u8 d4, d4, d2 @ max(abs()) <= I - vaddw.u8 q3, q3, d5 @ abs(p0 - q0) * 2 + abs(p1 - q1) >> 1 - vcle.u16 q3, q3, q0 - vmovn.u16 d5, q3 + vqadd.u8 d6, d6, d5 @ abs(p0 - q0) * 2 + abs(p1 - q1) >> 1 + vcle.u8 d5, d6, d0 vand d4, d4, d5 @ fm vdup.u8 d3, r3 @ H From f32690a298badbf2df66319e9b38236ad3d3e321 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 23 Feb 2017 23:33:58 +0200 Subject: [PATCH 1103/3374] aarch64: vp9lpf: Use dup+rev16+uzp1 instead of dup+lsr+dup+trn1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is one cycle faster in total, and three instructions fewer. Before: vp9_loop_filter_mix2_v_44_16_neon: 123.2 After: vp9_loop_filter_mix2_v_44_16_neon: 122.2 This is cherrypicked from libav commit 3bf9c48320f25f3d5557485b0202f22ae60748b0. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9lpf_neon.S | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/libavcodec/aarch64/vp9lpf_neon.S b/libavcodec/aarch64/vp9lpf_neon.S index a9eea7f951a64..0878763020a5d 100644 --- a/libavcodec/aarch64/vp9lpf_neon.S +++ b/libavcodec/aarch64/vp9lpf_neon.S @@ -162,18 +162,15 @@ dup v2\sz, w3 // I dup v3\sz, w4 // H .else - dup v0.8b, w2 // E - dup v2.8b, w3 // I - dup v3.8b, w4 // H - lsr w5, w2, #8 - lsr w6, w3, #8 - lsr w7, w4, #8 - dup v1.8b, w5 // E - dup v4.8b, w6 // I - dup v5.8b, w7 // H - trn1 v0.2d, v0.2d, v1.2d - trn1 v2.2d, v2.2d, v4.2d - trn1 v3.2d, v3.2d, v5.2d + dup v0.8h, w2 // E + dup v2.8h, w3 // I + dup v3.8h, w4 // H + rev16 v1.16b, v0.16b // E + rev16 v4.16b, v2.16b // I + rev16 v5.16b, v3.16b // H + uzp1 v0.16b, v0.16b, v1.16b + uzp1 v2.16b, v2.16b, v4.16b + uzp1 v3.16b, v3.16b, v5.16b .endif uabd v4\sz, v20\sz, v21\sz // abs(p3 - p2) From a88db8b9a016fe47997029e3653cdac4777994b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 14 Jan 2017 13:22:30 +0200 Subject: [PATCH 1104/3374] arm: vp9lpf: Implement the mix2_44 function with one single filter pass MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For this case, with 8 inputs but only changing 4 of them, we can fit all 16 input pixels into a q register, and still have enough temporary registers for doing the loop filter. The wd=8 filters would require too many temporary registers for processing all 16 pixels at once though. Before: Cortex A7 A8 A9 A53 vp9_loop_filter_mix2_v_44_16_neon: 289.7 256.2 237.5 181.2 After: vp9_loop_filter_mix2_v_44_16_neon: 221.2 150.5 177.7 138.0 This is cherrypicked from libav commit 575e31e931e4178e9f1e24407503c9b4ec0ef9ba. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9dsp_init_arm.c | 7 +- libavcodec/arm/vp9lpf_neon.S | 191 +++++++++++++++++++++++++++++++ 2 files changed, 195 insertions(+), 3 deletions(-) diff --git a/libavcodec/arm/vp9dsp_init_arm.c b/libavcodec/arm/vp9dsp_init_arm.c index f7b539e7e2f8d..4c57fd6ba05b5 100644 --- a/libavcodec/arm/vp9dsp_init_arm.c +++ b/libavcodec/arm/vp9dsp_init_arm.c @@ -195,6 +195,8 @@ define_loop_filters(8, 8); define_loop_filters(16, 8); define_loop_filters(16, 16); +define_loop_filters(44, 16); + #define lf_mix_fn(dir, wd1, wd2, stridea) \ static void loop_filter_##dir##_##wd1##wd2##_16_neon(uint8_t *dst, \ ptrdiff_t stride, \ @@ -208,7 +210,6 @@ static void loop_filter_##dir##_##wd1##wd2##_16_neon(uint8_t *dst, lf_mix_fn(h, wd1, wd2, stride) \ lf_mix_fn(v, wd1, wd2, sizeof(uint8_t)) -lf_mix_fns(4, 4) lf_mix_fns(4, 8) lf_mix_fns(8, 4) lf_mix_fns(8, 8) @@ -228,8 +229,8 @@ static av_cold void vp9dsp_loopfilter_init_arm(VP9DSPContext *dsp) dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_neon; dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_neon; - dsp->loop_filter_mix2[0][0][0] = loop_filter_h_44_16_neon; - dsp->loop_filter_mix2[0][0][1] = loop_filter_v_44_16_neon; + dsp->loop_filter_mix2[0][0][0] = ff_vp9_loop_filter_h_44_16_neon; + dsp->loop_filter_mix2[0][0][1] = ff_vp9_loop_filter_v_44_16_neon; dsp->loop_filter_mix2[0][1][0] = loop_filter_h_48_16_neon; dsp->loop_filter_mix2[0][1][1] = loop_filter_v_48_16_neon; dsp->loop_filter_mix2[1][0][0] = loop_filter_h_84_16_neon; diff --git a/libavcodec/arm/vp9lpf_neon.S b/libavcodec/arm/vp9lpf_neon.S index 2d91092ee097f..8d44d58f32e8b 100644 --- a/libavcodec/arm/vp9lpf_neon.S +++ b/libavcodec/arm/vp9lpf_neon.S @@ -44,6 +44,109 @@ vtrn.8 \r2, \r3 .endm +@ The input to and output from this macro is in the registers q8-q15, +@ and q0-q7 are used as scratch registers. +@ p3 = q8, p0 = q11, q0 = q12, q3 = q15 +.macro loop_filter_q + vdup.u8 d0, r2 @ E + lsr r2, r2, #8 + vdup.u8 d2, r3 @ I + lsr r3, r3, #8 + vdup.u8 d1, r2 @ E + vdup.u8 d3, r3 @ I + + vabd.u8 q2, q8, q9 @ abs(p3 - p2) + vabd.u8 q3, q9, q10 @ abs(p2 - p1) + vabd.u8 q4, q10, q11 @ abs(p1 - p0) + vabd.u8 q5, q12, q13 @ abs(q0 - q1) + vabd.u8 q6, q13, q14 @ abs(q1 - q2) + vabd.u8 q7, q14, q15 @ abs(q2 - q3) + vmax.u8 q2, q2, q3 + vmax.u8 q3, q4, q5 + vmax.u8 q4, q6, q7 + vabd.u8 q5, q11, q12 @ abs(p0 - q0) + vmax.u8 q2, q2, q3 + vqadd.u8 q5, q5, q5 @ abs(p0 - q0) * 2 + vabd.u8 q7, q10, q13 @ abs(p1 - q1) + vmax.u8 q2, q2, q4 @ max(abs(p3 - p2), ..., abs(q2 - q3)) + vshr.u8 q7, q7, #1 + vcle.u8 q2, q2, q1 @ max(abs()) <= I + vqadd.u8 q5, q5, q7 @ abs(p0 - q0) * 2 + abs(p1 - q1) >> 1 + vcle.u8 q5, q5, q0 + vand q2, q2, q5 @ fm + + vshrn.u16 d10, q2, #4 + vmov r2, r3, d10 + orrs r2, r2, r3 + @ If no pixels need filtering, just exit as soon as possible + beq 9f + + @ Calculate the normal inner loop filter for 2 or 4 pixels + ldr r3, [sp, #64] + vabd.u8 q3, q10, q11 @ abs(p1 - p0) + vabd.u8 q4, q13, q12 @ abs(q1 - q0) + + vsubl.u8 q5, d20, d26 @ p1 - q1 + vsubl.u8 q6, d21, d27 @ p1 - q1 + vmax.u8 q3, q3, q4 @ max(abs(p1 - p0), abs(q1 - q0)) + vqmovn.s16 d10, q5 @ av_clip_int8p(p1 - q1) + vqmovn.s16 d11, q6 @ av_clip_int8p(p1 - q1) + vdup.u8 d8, r3 @ H + lsr r3, r3, #8 + vdup.u8 d9, r3 @ H + vsubl.u8 q6, d24, d22 @ q0 - p0 + vsubl.u8 q7, d25, d23 @ q0 - p0 + vcle.u8 q3, q3, q4 @ hev + vmov.s16 q0, #3 + vand q3, q3, q2 @ !hev && fm && !flat8in + + vmul.s16 q6, q6, q0 @ 3 * (q0 - p0) + vmul.s16 q7, q7, q0 @ 3 * (q0 - p0) + vbic q5, q5, q3 @ if (!hev) av_clip_int8 = 0 + vaddw.s8 q6, q6, d10 @ 3 * (q0 - p0) [+ av_clip_int8(p1 - q1)] + vaddw.s8 q7, q7, d11 @ 3 * (q0 - p0) [+ av_clip_int8(p1 - q1)] + vmov.s8 q5, #4 + vqmovn.s16 d12, q6 + vqmovn.s16 d13, q7 @ av_clip_int8(3 * (q0 - p0) [+ av_clip_int8(p1 - q1)], BIT_DEPTH - 1) = f + vmov.s8 q0, #3 + + vqadd.s8 q5, q6, q5 @ FFMIN(f + 4, 127) + vqadd.s8 q0, q6, q0 @ FFMIN(f + 3, 127) + vmovl.u8 q6, d22 @ p0 + vmovl.u8 q7, d23 @ p0 + vshr.s8 q5, q5, #3 @ f1 + vshr.s8 q0, q0, #3 @ f2 + + vaddw.s8 q6, q6, d0 @ p0 + f2 + vaddw.s8 q7, q7, d1 @ p0 + f2 + vqmovun.s16 d0, q6 @ out p0 + vmovl.u8 q6, d24 @ q0 + vqmovun.s16 d1, q7 @ out p0 + vmovl.u8 q7, d25 @ q0 + vsubw.s8 q6, q6, d10 @ q0 - f1 + vsubw.s8 q7, q7, d11 @ q0 - f1 + vqmovun.s16 d12, q6 @ out q0 + vqmovun.s16 d13, q7 @ out q0 + vrshr.s8 q5, q5, #1 @ f = (f1 + 1) >> 1 + vbit q11, q0, q2 @ if (fm && !flat8in) + vbit q12, q6, q2 + + vmovl.u8 q0, d20 @ p1 + vmovl.u8 q2, d21 @ p1 + vmovl.u8 q6, d26 @ q1 + vmovl.u8 q7, d27 @ q1 + vaddw.s8 q0, q0, d10 @ p1 + f + vaddw.s8 q2, q2, d11 @ p1 + f + vsubw.s8 q6, q6, d10 @ q1 - f + vsubw.s8 q7, q7, d11 @ q1 - f + vqmovun.s16 d0, q0 @ out p1 + vqmovun.s16 d1, q2 @ out p1 + vqmovun.s16 d12, q6 @ out q1 + vqmovun.s16 d13, q7 @ out q1 + vbit q10, q0, q3 @ if (!hev && fm && !flat8in) + vbit q13, q6, q3 +.endm + @ The input to and output from this macro is in the registers d16-d31, @ and d0-d7 are used as scratch registers. @ p7 = d16 .. p3 = d20, p0 = d23, q0 = d24, q3 = d27, q7 = d31 @@ -455,6 +558,94 @@ function ff_vp9_loop_filter_h_4_8_neon, export=1 bx lr endfunc +function ff_vp9_loop_filter_v_44_16_neon, export=1 + vpush {q4-q7} + sub r12, r0, r1, lsl #2 + vld1.8 {q8}, [r12,:128], r1 @ p3 + vld1.8 {q12}, [r0, :128], r1 @ q0 + vld1.8 {q9}, [r12,:128], r1 @ p2 + vld1.8 {q13}, [r0, :128], r1 @ q1 + vld1.8 {q10}, [r12,:128], r1 @ p1 + vld1.8 {q14}, [r0, :128], r1 @ q2 + vld1.8 {q11}, [r12,:128], r1 @ p0 + vld1.8 {q15}, [r0, :128], r1 @ q3 + sub r0, r0, r1, lsl #2 + sub r12, r12, r1, lsl #1 + + loop_filter_q + + vst1.8 {q10}, [r12,:128], r1 + vst1.8 {q12}, [r0, :128], r1 + vst1.8 {q11}, [r12,:128], r1 + vst1.8 {q13}, [r0, :128], r1 +9: + vpop {q4-q7} + bx lr +endfunc + +function ff_vp9_loop_filter_h_44_16_neon, export=1 + vpush {q4-q7} + sub r12, r0, #4 + add r0, r12, r1, lsl #2 + vld1.8 {d16}, [r12], r1 + vld1.8 {d24}, [r0], r1 + vld1.8 {d18}, [r12], r1 + vld1.8 {d26}, [r0], r1 + vld1.8 {d20}, [r12], r1 + vld1.8 {d28}, [r0], r1 + vld1.8 {d22}, [r12], r1 + vld1.8 {d30}, [r0], r1 + mov r12, r0 + add r0, r0, r1, lsl #2 + vld1.8 {d17}, [r12], r1 + vld1.8 {d25}, [r0], r1 + vld1.8 {d19}, [r12], r1 + vld1.8 {d27}, [r0], r1 + vld1.8 {d21}, [r12], r1 + vld1.8 {d29}, [r0], r1 + vld1.8 {d23}, [r12], r1 + vld1.8 {d31}, [r0], r1 + + @ Transpose the 16x8 pixels, as two 8x8 parts + transpose_8x8 q8, q9, q10, q11, q12, q13, q14, q15 + + loop_filter_q + + sub r12, r0, r1, lsl #4 + add r0, r12, r1, lsl #3 + @ Move r0/r12 forward by 2 pixels; we don't need to rewrite the + @ outermost 2 pixels since they aren't changed. + add r12, r12, #2 + add r0, r0, #2 + + @ We only will write the mid 4 pixels back; after the loop filter, + @ these are in q10, q11, q12, q13, ordered as rows (16x4 pixels). + @ We need to transpose them to columns, done with a 4x4 transpose + @ (which in practice is four 4x4 transposes of the 4x4 blocks of + @ the 16x4 pixels; into 4x16 pixels). + transpose_4x4 q10, q11, q12, q13 + + vst1.32 {d20[0]}, [r12], r1 + vst1.32 {d21[0]}, [r0], r1 + vst1.32 {d22[0]}, [r12], r1 + vst1.32 {d23[0]}, [r0], r1 + vst1.32 {d24[0]}, [r12], r1 + vst1.32 {d25[0]}, [r0], r1 + vst1.32 {d26[0]}, [r12], r1 + vst1.32 {d27[0]}, [r0], r1 + vst1.32 {d20[1]}, [r12], r1 + vst1.32 {d21[1]}, [r0], r1 + vst1.32 {d22[1]}, [r12], r1 + vst1.32 {d23[1]}, [r0], r1 + vst1.32 {d24[1]}, [r12], r1 + vst1.32 {d25[1]}, [r0], r1 + vst1.32 {d26[1]}, [r12], r1 + vst1.32 {d27[1]}, [r0], r1 +9: + vpop {q4-q7} + bx lr +endfunc + function ff_vp9_loop_filter_v_8_8_neon, export=1 sub r12, r0, r1, lsl #2 vld1.8 {d20}, [r12,:64], r1 @ p3 From 600f4c9b03b8d39b986a00dd9dafa61be7d86a72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 2 Jan 2017 22:50:38 +0200 Subject: [PATCH 1105/3374] arm: vp9itxfm: Avoid reloading the idct32 coefficients MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The idct32x32 function actually pushed q4-q7 onto the stack even though it didn't clobber them; there are plenty of registers that can be used to allow keeping all the idct coefficients in registers without having to reload different subsets of them at different stages in the transform. Since the idct16 core transform avoids clobbering q4-q7 (but clobbers q2-q3 instead, to avoid needing to back up and restore q4-q7 at all in the idct16 function), and the lanewise vmul needs a register in the q0-q3 range, we move the stored coefficients from q2-q3 into q4-q5 while doing idct16. While keeping these coefficients in registers, we still can skip pushing q7. Before: Cortex A7 A8 A9 A53 vp9_inv_dct_dct_32x32_sub32_add_neon: 18553.8 17182.7 14303.3 12089.7 After: vp9_inv_dct_dct_32x32_sub32_add_neon: 18470.3 16717.7 14173.6 11860.8 This is cherrypicked from libav commit 402546a17233a8815307df9e14ff88cd70424537. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 246 ++++++++++++++++----------------- 1 file changed, 120 insertions(+), 126 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index dee2f058efead..9385b0153a1a5 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -1185,58 +1185,51 @@ function idct32x32_dc_add_neon endfunc .macro idct32_end - butterfly d16, d5, d4, d5 @ d16 = t16a, d5 = t19a + butterfly d16, d9, d8, d9 @ d16 = t16a, d9 = t19a butterfly d17, d20, d23, d20 @ d17 = t17, d20 = t18 - butterfly d18, d6, d7, d6 @ d18 = t23a, d6 = t20a + butterfly d18, d10, d11, d10 @ d18 = t23a, d10 = t20a butterfly d19, d21, d22, d21 @ d19 = t22, d21 = t21 - butterfly d4, d28, d28, d30 @ d4 = t24a, d28 = t27a + butterfly d8, d28, d28, d30 @ d8 = t24a, d28 = t27a butterfly d23, d26, d25, d26 @ d23 = t25, d26 = t26 - butterfly d7, d29, d29, d31 @ d7 = t31a, d29 = t28a + butterfly d11, d29, d29, d31 @ d11 = t31a, d29 = t28a butterfly d22, d27, d24, d27 @ d22 = t30, d27 = t29 mbutterfly d27, d20, d0[1], d0[2], q12, q15 @ d27 = t18a, d20 = t29a - mbutterfly d29, d5, d0[1], d0[2], q12, q15 @ d29 = t19, d5 = t28 - mbutterfly d28, d6, d0[1], d0[2], q12, q15, neg=1 @ d28 = t27, d6 = t20 + mbutterfly d29, d9, d0[1], d0[2], q12, q15 @ d29 = t19, d9 = t28 + mbutterfly d28, d10, d0[1], d0[2], q12, q15, neg=1 @ d28 = t27, d10 = t20 mbutterfly d26, d21, d0[1], d0[2], q12, q15, neg=1 @ d26 = t26a, d21 = t21a - butterfly d31, d24, d7, d4 @ d31 = t31, d24 = t24 + butterfly d31, d24, d11, d8 @ d31 = t31, d24 = t24 butterfly d30, d25, d22, d23 @ d30 = t30a, d25 = t25a butterfly_r d23, d16, d16, d18 @ d23 = t23, d16 = t16 butterfly_r d22, d17, d17, d19 @ d22 = t22a, d17 = t17a butterfly d18, d21, d27, d21 @ d18 = t18, d21 = t21 - butterfly_r d27, d28, d5, d28 @ d27 = t27a, d28 = t28a - butterfly d4, d26, d20, d26 @ d4 = t29, d26 = t26 - butterfly d19, d20, d29, d6 @ d19 = t19a, d20 = t20 - vmov d29, d4 @ d29 = t29 - - mbutterfly0 d27, d20, d27, d20, d4, d6, q2, q3 @ d27 = t27, d20 = t20 - mbutterfly0 d26, d21, d26, d21, d4, d6, q2, q3 @ d26 = t26a, d21 = t21a - mbutterfly0 d25, d22, d25, d22, d4, d6, q2, q3 @ d25 = t25, d22 = t22 - mbutterfly0 d24, d23, d24, d23, d4, d6, q2, q3 @ d24 = t24a, d23 = t23a + butterfly_r d27, d28, d9, d28 @ d27 = t27a, d28 = t28a + butterfly d8, d26, d20, d26 @ d8 = t29, d26 = t26 + butterfly d19, d20, d29, d10 @ d19 = t19a, d20 = t20 + vmov d29, d8 @ d29 = t29 + + mbutterfly0 d27, d20, d27, d20, d8, d10, q4, q5 @ d27 = t27, d20 = t20 + mbutterfly0 d26, d21, d26, d21, d8, d10, q4, q5 @ d26 = t26a, d21 = t21a + mbutterfly0 d25, d22, d25, d22, d8, d10, q4, q5 @ d25 = t25, d22 = t22 + mbutterfly0 d24, d23, d24, d23, d8, d10, q4, q5 @ d24 = t24a, d23 = t23a bx lr .endm function idct32_odd - movrel r12, idct_coeffs - add r12, r12, #32 - vld1.16 {q0-q1}, [r12,:128] - - mbutterfly d16, d31, d0[0], d0[1], q2, q3 @ d16 = t16a, d31 = t31a - mbutterfly d24, d23, d0[2], d0[3], q2, q3 @ d24 = t17a, d23 = t30a - mbutterfly d20, d27, d1[0], d1[1], q2, q3 @ d20 = t18a, d27 = t29a - mbutterfly d28, d19, d1[2], d1[3], q2, q3 @ d28 = t19a, d19 = t28a - mbutterfly d18, d29, d2[0], d2[1], q2, q3 @ d18 = t20a, d29 = t27a - mbutterfly d26, d21, d2[2], d2[3], q2, q3 @ d26 = t21a, d21 = t26a - mbutterfly d22, d25, d3[0], d3[1], q2, q3 @ d22 = t22a, d25 = t25a - mbutterfly d30, d17, d3[2], d3[3], q2, q3 @ d30 = t23a, d17 = t24a - - sub r12, r12, #32 - vld1.16 {q0}, [r12,:128] - - butterfly d4, d24, d16, d24 @ d4 = t16, d24 = t17 - butterfly d5, d20, d28, d20 @ d5 = t19, d20 = t18 - butterfly d6, d26, d18, d26 @ d6 = t20, d26 = t21 - butterfly d7, d22, d30, d22 @ d7 = t23, d22 = t22 + mbutterfly d16, d31, d4[0], d4[1], q4, q5 @ d16 = t16a, d31 = t31a + mbutterfly d24, d23, d4[2], d4[3], q4, q5 @ d24 = t17a, d23 = t30a + mbutterfly d20, d27, d5[0], d5[1], q4, q5 @ d20 = t18a, d27 = t29a + mbutterfly d28, d19, d5[2], d5[3], q4, q5 @ d28 = t19a, d19 = t28a + mbutterfly d18, d29, d6[0], d6[1], q4, q5 @ d18 = t20a, d29 = t27a + mbutterfly d26, d21, d6[2], d6[3], q4, q5 @ d26 = t21a, d21 = t26a + mbutterfly d22, d25, d7[0], d7[1], q4, q5 @ d22 = t22a, d25 = t25a + mbutterfly d30, d17, d7[2], d7[3], q4, q5 @ d30 = t23a, d17 = t24a + + butterfly d8, d24, d16, d24 @ d8 = t16, d24 = t17 + butterfly d9, d20, d28, d20 @ d9 = t19, d20 = t18 + butterfly d10, d26, d18, d26 @ d10 = t20, d26 = t21 + butterfly d11, d22, d30, d22 @ d11 = t23, d22 = t22 butterfly d28, d25, d17, d25 @ d28 = t24, d25 = t25 butterfly d30, d21, d29, d21 @ d30 = t27, d21 = t26 butterfly d29, d23, d31, d23 @ d29 = t31, d23 = t30 @@ -1250,26 +1243,19 @@ function idct32_odd endfunc function idct32_odd_half - movrel r12, idct_coeffs - add r12, r12, #32 - vld1.16 {q0-q1}, [r12,:128] - - mbutterfly_h1 d16, d31, d0[0], d0[1], q2, q3 @ d16 = t16a, d31 = t31a - mbutterfly_h2 d24, d23, d0[2], d0[3], q2, q3 @ d24 = t17a, d23 = t30a - mbutterfly_h1 d20, d27, d1[0], d1[1], q2, q3 @ d20 = t18a, d27 = t29a - mbutterfly_h2 d28, d19, d1[2], d1[3], q2, q3 @ d28 = t19a, d19 = t28a - mbutterfly_h1 d18, d29, d2[0], d2[1], q2, q3 @ d18 = t20a, d29 = t27a - mbutterfly_h2 d26, d21, d2[2], d2[3], q2, q3 @ d26 = t21a, d21 = t26a - mbutterfly_h1 d22, d25, d3[0], d3[1], q2, q3 @ d22 = t22a, d25 = t25a - mbutterfly_h2 d30, d17, d3[2], d3[3], q2, q3 @ d30 = t23a, d17 = t24a - - sub r12, r12, #32 - vld1.16 {q0}, [r12,:128] - - butterfly d4, d24, d16, d24 @ d4 = t16, d24 = t17 - butterfly d5, d20, d28, d20 @ d5 = t19, d20 = t18 - butterfly d6, d26, d18, d26 @ d6 = t20, d26 = t21 - butterfly d7, d22, d30, d22 @ d7 = t23, d22 = t22 + mbutterfly_h1 d16, d31, d4[0], d4[1], q4, q5 @ d16 = t16a, d31 = t31a + mbutterfly_h2 d24, d23, d4[2], d4[3], q4, q5 @ d24 = t17a, d23 = t30a + mbutterfly_h1 d20, d27, d5[0], d5[1], q4, q5 @ d20 = t18a, d27 = t29a + mbutterfly_h2 d28, d19, d5[2], d5[3], q4, q5 @ d28 = t19a, d19 = t28a + mbutterfly_h1 d18, d29, d6[0], d6[1], q4, q5 @ d18 = t20a, d29 = t27a + mbutterfly_h2 d26, d21, d6[2], d6[3], q4, q5 @ d26 = t21a, d21 = t26a + mbutterfly_h1 d22, d25, d7[0], d7[1], q4, q5 @ d22 = t22a, d25 = t25a + mbutterfly_h2 d30, d17, d7[2], d7[3], q4, q5 @ d30 = t23a, d17 = t24a + + butterfly d8, d24, d16, d24 @ d8 = t16, d24 = t17 + butterfly d9, d20, d28, d20 @ d9 = t19, d20 = t18 + butterfly d10, d26, d18, d26 @ d10 = t20, d26 = t21 + butterfly d11, d22, d30, d22 @ d11 = t23, d22 = t22 butterfly d28, d25, d17, d25 @ d28 = t24, d25 = t25 butterfly d30, d21, d29, d21 @ d30 = t27, d21 = t26 butterfly d29, d23, d31, d23 @ d29 = t31, d23 = t30 @@ -1284,45 +1270,38 @@ function idct32_odd_half endfunc function idct32_odd_quarter - movrel r12, idct_coeffs - add r12, r12, #32 - vld1.16 {q0-q1}, [r12,:128] - - vmull.s16 q2, d16, d0[0] - vmull.s16 q14, d19, d1[3] - vmull.s16 q15, d16, d0[1] - vmull.s16 q11, d17, d3[2] - vmull.s16 q3, d17, d3[3] - vmull.s16 q13, d19, d1[2] - vmull.s16 q10, d18, d2[0] - vmull.s16 q12, d18, d2[1] - - sub r12, r12, #32 - vld1.16 {q0}, [r12,:128] + vmull.s16 q4, d16, d4[0] + vmull.s16 q14, d19, d5[3] + vmull.s16 q15, d16, d4[1] + vmull.s16 q11, d17, d7[2] + vmull.s16 q5, d17, d7[3] + vmull.s16 q13, d19, d5[2] + vmull.s16 q10, d18, d6[0] + vmull.s16 q12, d18, d6[1] vneg.s32 q14, q14 - vneg.s32 q3, q3 + vneg.s32 q5, q5 - vrshrn.s32 d4, q2, #14 - vrshrn.s32 d5, q14, #14 + vrshrn.s32 d8, q4, #14 + vrshrn.s32 d9, q14, #14 vrshrn.s32 d29, q15, #14 vrshrn.s32 d28, q11, #14 - vrshrn.s32 d7, q3, #14 + vrshrn.s32 d11, q5, #14 vrshrn.s32 d31, q13, #14 - vrshrn.s32 d6, q10, #14 + vrshrn.s32 d10, q10, #14 vrshrn.s32 d30, q12, #14 - mbutterfly_l q8, q9, d29, d4, d0[3], d1[0] - mbutterfly_l q13, q10, d31, d5, d0[3], d1[0] + mbutterfly_l q8, q9, d29, d8, d0[3], d1[0] + mbutterfly_l q13, q10, d31, d9, d0[3], d1[0] vrshrn.s32 d23, q8, #14 vrshrn.s32 d24, q9, #14 vneg.s32 q10, q10 vrshrn.s32 d27, q13, #14 vrshrn.s32 d20, q10, #14 - mbutterfly_l q8, q9, d30, d6, d1[1], d1[2] + mbutterfly_l q8, q9, d30, d10, d1[1], d1[2] vrshrn.s32 d21, q8, #14 vrshrn.s32 d26, q9, #14 - mbutterfly_l q8, q9, d28, d7, d1[1], d1[2] + mbutterfly_l q8, q9, d28, d11, d1[1], d1[2] vrshrn.s32 d25, q8, #14 vneg.s32 q9, q9 vrshrn.s32 d22, q9, #14 @@ -1343,8 +1322,11 @@ endfunc function idct32_1d_4x32_pass1\suffix\()_neon push {lr} - movrel r12, idct_coeffs - vld1.16 {q0-q1}, [r12,:128] + @ idct16 clobbers q2-q3 (since it doesn't clobber q4-q7 at all + @ when doing the normal 16x16 idct), so move the idct32_odd coeffs + @ to q4-q5 + vmov q4, q2 + vmov q5, q3 @ Double stride of the input, since we only read every other line mov r12, #128 @@ -1372,6 +1354,11 @@ function idct32_1d_4x32_pass1\suffix\()_neon bl idct16\suffix + @ Move the idct32_odd coeffs back into q2-q3 for idct32_odd; + @ the constants for a vmul with a lane must be in q0-q3. + vmov q2, q4 + vmov q3, q5 + @ Do four 4x4 transposes. Originally, d16-d31 contain the @ 16 rows. Afterwards, d16-d19, d20-d23, d24-d27, d28-d31 @ contain the transposed 4x4 blocks. @@ -1407,24 +1394,24 @@ function idct32_1d_4x32_pass1\suffix\()_neon .endif add r2, r2, #64 - vmov.s16 d4, #0 + vmov.s16 d8, #0 @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31) .ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vld1.16 {d\i}, [r2,:64] - vst1.16 {d4}, [r2,:64], r12 + vst1.16 {d8}, [r2,:64], r12 .endr .endif .ifc \suffix,_quarter .irp i, 16, 17, 18, 19 vld1.16 {d\i}, [r2,:64] - vst1.16 {d4}, [r2,:64], r12 + vst1.16 {d8}, [r2,:64], r12 .endr .endif .ifc \suffix,_half .irp i, 16, 17, 18, 19, 20, 21, 22, 23 vld1.16 {d\i}, [r2,:64] - vst1.16 {d4}, [r2,:64], r12 + vst1.16 {d8}, [r2,:64], r12 .endr .endif @@ -1437,15 +1424,15 @@ function idct32_1d_4x32_pass1\suffix\()_neon @ from the output. .macro store_rev a, b, c, d .irp i, \a, \b, \c, \d - vld1.16 {d4}, [r0,:64] - vadd.s16 d4, d4, d\i - vst1.16 {d4}, [r0,:64]! + vld1.16 {d8}, [r0,:64] + vadd.s16 d8, d8, d\i + vst1.16 {d8}, [r0,:64]! vrev64.16 d\i, d\i .endr .irp i, \d, \c, \b, \a - vld1.16 {d4}, [r0,:64] - vsub.s16 d4, d4, d\i - vst1.16 {d4}, [r0,:64]! + vld1.16 {d8}, [r0,:64] + vsub.s16 d8, d8, d\i + vst1.16 {d8}, [r0,:64]! .endr .endm @@ -1466,8 +1453,8 @@ endfunc @ r2 = src (temp buffer) function idct32_1d_4x32_pass2\suffix\()_neon push {lr} - movrel r12, idct_coeffs - vld1.16 {q0-q1}, [r12,:128] + vmov q4, q2 + vmov q5, q3 mov r12, #128 @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30) @@ -1492,6 +1479,9 @@ function idct32_1d_4x32_pass2\suffix\()_neon bl idct16\suffix + vmov q2, q4 + vmov q3, q5 + .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vst1.16 {d\i}, [r2,:64], r12 .endr @@ -1524,38 +1514,38 @@ function idct32_1d_4x32_pass2\suffix\()_neon mov r12, #128 .macro load_acc_store a, b, c, d, neg=0 - vld1.16 {d4}, [r2,:64], r12 - vld1.16 {d5}, [r2,:64], r12 + vld1.16 {d8}, [r2,:64], r12 + vld1.16 {d9}, [r2,:64], r12 .if \neg == 0 - vadd.s16 d4, d4, d\a - vld1.16 {d6}, [r2,:64], r12 - vadd.s16 d5, d5, d\b - vld1.16 {d7}, [r2,:64], r12 - vadd.s16 d6, d6, d\c - vadd.s16 d7, d7, d\d + vadd.s16 d8, d8, d\a + vld1.16 {d10}, [r2,:64], r12 + vadd.s16 d9, d9, d\b + vld1.16 {d11}, [r2,:64], r12 + vadd.s16 d10, d10, d\c + vadd.s16 d11, d11, d\d .else - vsub.s16 d4, d4, d\a - vld1.16 {d6}, [r2,:64], r12 - vsub.s16 d5, d5, d\b - vld1.16 {d7}, [r2,:64], r12 - vsub.s16 d6, d6, d\c - vsub.s16 d7, d7, d\d + vsub.s16 d8, d8, d\a + vld1.16 {d10}, [r2,:64], r12 + vsub.s16 d9, d9, d\b + vld1.16 {d11}, [r2,:64], r12 + vsub.s16 d10, d10, d\c + vsub.s16 d11, d11, d\d .endif - vld1.32 {d2[]}, [r0,:32], r1 - vld1.32 {d2[1]}, [r0,:32], r1 - vrshr.s16 q2, q2, #6 - vld1.32 {d3[]}, [r0,:32], r1 - vrshr.s16 q3, q3, #6 - vld1.32 {d3[1]}, [r0,:32], r1 + vld1.32 {d12[]}, [r0,:32], r1 + vld1.32 {d12[1]}, [r0,:32], r1 + vrshr.s16 q4, q4, #6 + vld1.32 {d13[]}, [r0,:32], r1 + vrshr.s16 q5, q5, #6 + vld1.32 {d13[1]}, [r0,:32], r1 sub r0, r0, r1, lsl #2 - vaddw.u8 q2, q2, d2 - vaddw.u8 q3, q3, d3 - vqmovun.s16 d4, q2 - vqmovun.s16 d5, q3 - vst1.32 {d4[0]}, [r0,:32], r1 - vst1.32 {d4[1]}, [r0,:32], r1 - vst1.32 {d5[0]}, [r0,:32], r1 - vst1.32 {d5[1]}, [r0,:32], r1 + vaddw.u8 q4, q4, d12 + vaddw.u8 q5, q5, d13 + vqmovun.s16 d8, q4 + vqmovun.s16 d9, q5 + vst1.32 {d8[0]}, [r0,:32], r1 + vst1.32 {d8[1]}, [r0,:32], r1 + vst1.32 {d9[0]}, [r0,:32], r1 + vst1.32 {d9[1]}, [r0,:32], r1 .endm load_acc_store 31, 30, 29, 28 load_acc_store 27, 26, 25, 24 @@ -1584,7 +1574,7 @@ function ff_vp9_idct_idct_32x32_add_neon, export=1 cmp r3, #1 beq idct32x32_dc_add_neon push {r4-r8,lr} - vpush {q4-q7} + vpush {q4-q6} movrel r8, min_eob_idct_idct_32 + 2 @ Align the stack, allocate a temp buffer @@ -1598,6 +1588,10 @@ A and r7, sp, #15 mov r5, r1 mov r6, r2 + movrel r12, idct_coeffs + vld1.16 {q0-q1}, [r12,:128]! + vld1.16 {q2-q3}, [r12,:128] + cmp r3, #34 ble idct32x32_quarter_add_neon cmp r3, #135 @@ -1636,7 +1630,7 @@ A and r7, sp, #15 .endr add sp, sp, r7 - vpop {q4-q7} + vpop {q4-q6} pop {r4-r8,pc} endfunc @@ -1668,7 +1662,7 @@ function idct32x32_quarter_add_neon .endr add sp, sp, r7 - vpop {q4-q7} + vpop {q4-q6} pop {r4-r8,pc} endfunc @@ -1706,6 +1700,6 @@ function idct32x32_half_add_neon .endr add sp, sp, r7 - vpop {q4-q7} + vpop {q4-q6} pop {r4-r8,pc} endfunc From 2905657b902fea8718434f0d29056cf4e7434307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 2 Jan 2017 22:08:41 +0200 Subject: [PATCH 1106/3374] aarch64: vp9itxfm: Avoid reloading the idct32 coefficients MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The idct32x32 function actually pushed d8-d15 onto the stack even though it didn't clobber them; there are plenty of registers that can be used to allow keeping all the idct coefficients in registers without having to reload different subsets of them at different stages in the transform. After this, we still can skip pushing d12-d15. Before: vp9_inv_dct_dct_32x32_sub32_add_neon: 8128.3 After: vp9_inv_dct_dct_32x32_sub32_add_neon: 8053.3 This is cherrypicked from libav commit 65aa002d54433154a6924dc13e498bec98451ad0. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 110 +++++++++++------------------ 1 file changed, 43 insertions(+), 67 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index be65eb791930c..dd9fde15d7493 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -1123,18 +1123,14 @@ endfunc .endm function idct32_odd - ld1 {v0.8h,v1.8h}, [x11] - - dmbutterfly v16, v31, v0.h[0], v0.h[1], v4, v5, v6, v7 // v16 = t16a, v31 = t31a - dmbutterfly v24, v23, v0.h[2], v0.h[3], v4, v5, v6, v7 // v24 = t17a, v23 = t30a - dmbutterfly v20, v27, v0.h[4], v0.h[5], v4, v5, v6, v7 // v20 = t18a, v27 = t29a - dmbutterfly v28, v19, v0.h[6], v0.h[7], v4, v5, v6, v7 // v28 = t19a, v19 = t28a - dmbutterfly v18, v29, v1.h[0], v1.h[1], v4, v5, v6, v7 // v18 = t20a, v29 = t27a - dmbutterfly v26, v21, v1.h[2], v1.h[3], v4, v5, v6, v7 // v26 = t21a, v21 = t26a - dmbutterfly v22, v25, v1.h[4], v1.h[5], v4, v5, v6, v7 // v22 = t22a, v25 = t25a - dmbutterfly v30, v17, v1.h[6], v1.h[7], v4, v5, v6, v7 // v30 = t23a, v17 = t24a - - ld1 {v0.8h}, [x10] + dmbutterfly v16, v31, v8.h[0], v8.h[1], v4, v5, v6, v7 // v16 = t16a, v31 = t31a + dmbutterfly v24, v23, v8.h[2], v8.h[3], v4, v5, v6, v7 // v24 = t17a, v23 = t30a + dmbutterfly v20, v27, v8.h[4], v8.h[5], v4, v5, v6, v7 // v20 = t18a, v27 = t29a + dmbutterfly v28, v19, v8.h[6], v8.h[7], v4, v5, v6, v7 // v28 = t19a, v19 = t28a + dmbutterfly v18, v29, v9.h[0], v9.h[1], v4, v5, v6, v7 // v18 = t20a, v29 = t27a + dmbutterfly v26, v21, v9.h[2], v9.h[3], v4, v5, v6, v7 // v26 = t21a, v21 = t26a + dmbutterfly v22, v25, v9.h[4], v9.h[5], v4, v5, v6, v7 // v22 = t22a, v25 = t25a + dmbutterfly v30, v17, v9.h[6], v9.h[7], v4, v5, v6, v7 // v30 = t23a, v17 = t24a butterfly_8h v4, v24, v16, v24 // v4 = t16, v24 = t17 butterfly_8h v5, v20, v28, v20 // v5 = t19, v20 = t18 @@ -1153,18 +1149,14 @@ function idct32_odd endfunc function idct32_odd_half - ld1 {v0.8h,v1.8h}, [x11] - - dmbutterfly_h1 v16, v31, v0.h[0], v0.h[1], v4, v5, v6, v7 // v16 = t16a, v31 = t31a - dmbutterfly_h2 v24, v23, v0.h[2], v0.h[3], v4, v5, v6, v7 // v24 = t17a, v23 = t30a - dmbutterfly_h1 v20, v27, v0.h[4], v0.h[5], v4, v5, v6, v7 // v20 = t18a, v27 = t29a - dmbutterfly_h2 v28, v19, v0.h[6], v0.h[7], v4, v5, v6, v7 // v28 = t19a, v19 = t28a - dmbutterfly_h1 v18, v29, v1.h[0], v1.h[1], v4, v5, v6, v7 // v18 = t20a, v29 = t27a - dmbutterfly_h2 v26, v21, v1.h[2], v1.h[3], v4, v5, v6, v7 // v26 = t21a, v21 = t26a - dmbutterfly_h1 v22, v25, v1.h[4], v1.h[5], v4, v5, v6, v7 // v22 = t22a, v25 = t25a - dmbutterfly_h2 v30, v17, v1.h[6], v1.h[7], v4, v5, v6, v7 // v30 = t23a, v17 = t24a - - ld1 {v0.8h}, [x10] + dmbutterfly_h1 v16, v31, v8.h[0], v8.h[1], v4, v5, v6, v7 // v16 = t16a, v31 = t31a + dmbutterfly_h2 v24, v23, v8.h[2], v8.h[3], v4, v5, v6, v7 // v24 = t17a, v23 = t30a + dmbutterfly_h1 v20, v27, v8.h[4], v8.h[5], v4, v5, v6, v7 // v20 = t18a, v27 = t29a + dmbutterfly_h2 v28, v19, v8.h[6], v8.h[7], v4, v5, v6, v7 // v28 = t19a, v19 = t28a + dmbutterfly_h1 v18, v29, v9.h[0], v9.h[1], v4, v5, v6, v7 // v18 = t20a, v29 = t27a + dmbutterfly_h2 v26, v21, v9.h[2], v9.h[3], v4, v5, v6, v7 // v26 = t21a, v21 = t26a + dmbutterfly_h1 v22, v25, v9.h[4], v9.h[5], v4, v5, v6, v7 // v22 = t22a, v25 = t25a + dmbutterfly_h2 v30, v17, v9.h[6], v9.h[7], v4, v5, v6, v7 // v30 = t23a, v17 = t24a butterfly_8h v4, v24, v16, v24 // v4 = t16, v24 = t17 butterfly_8h v5, v20, v28, v20 // v5 = t19, v20 = t18 @@ -1183,18 +1175,14 @@ function idct32_odd_half endfunc function idct32_odd_quarter - ld1 {v0.8h,v1.8h}, [x11] - - dsmull_h v4, v5, v16, v0.h[0] - dsmull_h v28, v29, v19, v0.h[7] - dsmull_h v30, v31, v16, v0.h[1] - dsmull_h v22, v23, v17, v1.h[6] - dsmull_h v7, v6, v17, v1.h[7] - dsmull_h v26, v27, v19, v0.h[6] - dsmull_h v20, v21, v18, v1.h[0] - dsmull_h v24, v25, v18, v1.h[1] - - ld1 {v0.8h}, [x10] + dsmull_h v4, v5, v16, v8.h[0] + dsmull_h v28, v29, v19, v8.h[7] + dsmull_h v30, v31, v16, v8.h[1] + dsmull_h v22, v23, v17, v9.h[6] + dsmull_h v7, v6, v17, v9.h[7] + dsmull_h v26, v27, v19, v8.h[6] + dsmull_h v20, v21, v18, v9.h[0] + dsmull_h v24, v25, v18, v9.h[1] neg v28.4s, v28.4s neg v29.4s, v29.4s @@ -1240,12 +1228,8 @@ endfunc // x1 = unused // x2 = src // x9 = double input stride -// x10 = idct_coeffs -// x11 = idct_coeffs + 32 function idct32_1d_8x32_pass1\suffix\()_neon mov x14, x30 - ld1 {v0.8h,v1.8h}, [x10] - movi v2.8h, #0 // v16 = IN(0), v17 = IN(2) ... v31 = IN(30) @@ -1278,14 +1262,14 @@ function idct32_1d_8x32_pass1\suffix\()_neon .macro store_rev a, b // There's no rev128 instruction, but we reverse each 64 bit // half, and then flip them using an ext with 8 bytes offset. - rev64 v1.8h, \b + rev64 v3.8h, \b st1 {\a}, [x0], #16 - rev64 v0.8h, \a - ext v1.16b, v1.16b, v1.16b, #8 + rev64 v2.8h, \a + ext v3.16b, v3.16b, v3.16b, #8 st1 {\b}, [x0], #16 - ext v0.16b, v0.16b, v0.16b, #8 - st1 {v1.8h}, [x0], #16 - st1 {v0.8h}, [x0], #16 + ext v2.16b, v2.16b, v2.16b, #8 + st1 {v3.8h}, [x0], #16 + st1 {v2.8h}, [x0], #16 .endm store_rev v16.8h, v24.8h store_rev v17.8h, v25.8h @@ -1339,20 +1323,20 @@ function idct32_1d_8x32_pass1\suffix\()_neon // subtracted from the output. .macro store_rev a, b ld1 {v4.8h}, [x0] - rev64 v1.8h, \b + rev64 v3.8h, \b add v4.8h, v4.8h, \a - rev64 v0.8h, \a + rev64 v2.8h, \a st1 {v4.8h}, [x0], #16 - ext v1.16b, v1.16b, v1.16b, #8 + ext v3.16b, v3.16b, v3.16b, #8 ld1 {v5.8h}, [x0] - ext v0.16b, v0.16b, v0.16b, #8 + ext v2.16b, v2.16b, v2.16b, #8 add v5.8h, v5.8h, \b st1 {v5.8h}, [x0], #16 ld1 {v6.8h}, [x0] - sub v6.8h, v6.8h, v1.8h + sub v6.8h, v6.8h, v3.8h st1 {v6.8h}, [x0], #16 ld1 {v7.8h}, [x0] - sub v7.8h, v7.8h, v0.8h + sub v7.8h, v7.8h, v2.8h st1 {v7.8h}, [x0], #16 .endm @@ -1376,12 +1360,8 @@ endfunc // x2 = src (temp buffer) // x7 = negative double temp buffer stride // x9 = double temp buffer stride -// x10 = idct_coeffs -// x11 = idct_coeffs + 32 function idct32_1d_8x32_pass2\suffix\()_neon mov x14, x30 - ld1 {v0.8h,v1.8h}, [x10] - // v16 = IN(0), v17 = IN(2) ... v31 = IN(30) .ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 @@ -1454,15 +1434,15 @@ function idct32_1d_8x32_pass2\suffix\()_neon sub v6.8h, v6.8h, \c sub v7.8h, v7.8h, \d .endif - ld1 {v0.8b}, [x0], x1 - ld1 {v1.8b}, [x0], x1 + ld1 {v10.8b}, [x0], x1 + ld1 {v11.8b}, [x0], x1 srshr v4.8h, v4.8h, #6 ld1 {v2.8b}, [x0], x1 srshr v5.8h, v5.8h, #6 - uaddw v4.8h, v4.8h, v0.8b + uaddw v4.8h, v4.8h, v10.8b ld1 {v3.8b}, [x0], x1 srshr v6.8h, v6.8h, #6 - uaddw v5.8h, v5.8h, v1.8b + uaddw v5.8h, v5.8h, v11.8b srshr v7.8h, v7.8h, #6 sub x0, x0, x1, lsl #2 uaddw v6.8h, v6.8h, v2.8b @@ -1503,13 +1483,10 @@ function ff_vp9_idct_idct_32x32_add_neon, export=1 b.eq idct32x32_dc_add_neon movrel x10, idct_coeffs - add x11, x10, #32 movrel x12, min_eob_idct_idct_32, 2 mov x15, x30 - stp d14, d15, [sp, #-0x10]! - stp d12, d13, [sp, #-0x10]! stp d10, d11, [sp, #-0x10]! stp d8, d9, [sp, #-0x10]! @@ -1523,6 +1500,9 @@ function ff_vp9_idct_idct_32x32_add_neon, export=1 mov x9, #128 neg x7, x9 + ld1 {v0.8h,v1.8h}, [x10], #32 + ld1 {v8.8h,v9.8h}, [x10] + cmp w3, #34 b.le idct32x32_quarter_add_neon cmp w3, #135 @@ -1565,8 +1545,6 @@ function ff_vp9_idct_idct_32x32_add_neon, export=1 ldp d8, d9, [sp], 0x10 ldp d10, d11, [sp], 0x10 - ldp d12, d13, [sp], 0x10 - ldp d14, d15, [sp], 0x10 br x15 endfunc @@ -1592,8 +1570,6 @@ function idct32x32_\size\()_add_neon ldp d8, d9, [sp], 0x10 ldp d10, d11, [sp], 0x10 - ldp d12, d13, [sp], 0x10 - ldp d14, d15, [sp], 0x10 br x15 endfunc From 4f693b56bdcfda37b4f2c48b39dcf12439c149c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 31 Dec 2016 14:05:44 +0200 Subject: [PATCH 1107/3374] arm: vp9itxfm: Reorder the idct coefficients for better pairing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All elements are used pairwise, except for the first one. Previously, the 16th element was unused. Move the unused element to the second slot, to make the later element pairs not split across registers. This simplifies loading only parts of the coefficients, reducing the difference to the 16 bpp version. This is cherrypicked from libav commit de06bdfe6c8abd8266d5c6f5c68e4df0060b61fc. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 124 ++++++++++++++++----------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index 9385b0153a1a5..05e31e62406db 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -22,7 +22,7 @@ #include "neon.S" const itxfm4_coeffs, align=4 - .short 11585, 6270, 15137, 0 + .short 11585, 0, 6270, 15137 iadst4_coeffs: .short 5283, 15212, 9929, 13377 endconst @@ -30,8 +30,8 @@ endconst const iadst8_coeffs, align=4 .short 16305, 1606, 14449, 7723, 10394, 12665, 4756, 15679 idct_coeffs: - .short 11585, 6270, 15137, 3196, 16069, 13623, 9102, 1606 - .short 16305, 12665, 10394, 7723, 14449, 15679, 4756, 0 + .short 11585, 0, 6270, 15137, 3196, 16069, 13623, 9102 + .short 1606, 16305, 12665, 10394, 7723, 14449, 15679, 4756 .short 804, 16364, 12140, 11003, 7005, 14811, 15426, 5520 .short 3981, 15893, 14053, 8423, 9760, 13160, 16207, 2404 endconst @@ -224,14 +224,14 @@ endconst .endm .macro idct4 c0, c1, c2, c3 - vmull.s16 q13, \c1, d0[2] - vmull.s16 q11, \c1, d0[1] + vmull.s16 q13, \c1, d0[3] + vmull.s16 q11, \c1, d0[2] vadd.i16 d16, \c0, \c2 vsub.i16 d17, \c0, \c2 - vmlal.s16 q13, \c3, d0[1] + vmlal.s16 q13, \c3, d0[2] vmull.s16 q9, d16, d0[0] vmull.s16 q10, d17, d0[0] - vmlsl.s16 q11, \c3, d0[2] + vmlsl.s16 q11, \c3, d0[3] vrshrn.s32 d26, q13, #14 vrshrn.s32 d18, q9, #14 vrshrn.s32 d20, q10, #14 @@ -350,9 +350,9 @@ itxfm_func4x4 iwht, iwht .macro idct8 dmbutterfly0 d16, d17, d24, d25, q8, q12, q2, q4, d4, d5, d8, d9, q3, q2, q5, q4 @ q8 = t0a, q12 = t1a - dmbutterfly d20, d21, d28, d29, d0[1], d0[2], q2, q3, q4, q5 @ q10 = t2a, q14 = t3a - dmbutterfly d18, d19, d30, d31, d0[3], d1[0], q2, q3, q4, q5 @ q9 = t4a, q15 = t7a - dmbutterfly d26, d27, d22, d23, d1[1], d1[2], q2, q3, q4, q5 @ q13 = t5a, q11 = t6a + dmbutterfly d20, d21, d28, d29, d0[2], d0[3], q2, q3, q4, q5 @ q10 = t2a, q14 = t3a + dmbutterfly d18, d19, d30, d31, d1[0], d1[1], q2, q3, q4, q5 @ q9 = t4a, q15 = t7a + dmbutterfly d26, d27, d22, d23, d1[2], d1[3], q2, q3, q4, q5 @ q13 = t5a, q11 = t6a butterfly q2, q14, q8, q14 @ q2 = t0, q14 = t3 butterfly q3, q10, q12, q10 @ q3 = t1, q10 = t2 @@ -386,8 +386,8 @@ itxfm_func4x4 iwht, iwht vneg.s16 q15, q15 @ q15 = out[7] butterfly q8, q9, q11, q9 @ q8 = out[0], q9 = t2 - dmbutterfly_l q10, q11, q5, q7, d4, d5, d6, d7, d0[1], d0[2] @ q10,q11 = t5a, q5,q7 = t4a - dmbutterfly_l q2, q3, q13, q14, d12, d13, d8, d9, d0[2], d0[1] @ q2,q3 = t6a, q13,q14 = t7a + dmbutterfly_l q10, q11, q5, q7, d4, d5, d6, d7, d0[2], d0[3] @ q10,q11 = t5a, q5,q7 = t4a + dmbutterfly_l q2, q3, q13, q14, d12, d13, d8, d9, d0[3], d0[2] @ q2,q3 = t6a, q13,q14 = t7a dbutterfly_n d28, d29, d8, d9, q10, q11, q13, q14, q4, q6, q10, q11 @ q14 = out[6], q4 = t7 @@ -594,13 +594,13 @@ endfunc function idct16 mbutterfly0 d16, d24, d16, d24, d4, d6, q2, q3 @ d16 = t0a, d24 = t1a - mbutterfly d20, d28, d0[1], d0[2], q2, q3 @ d20 = t2a, d28 = t3a - mbutterfly d18, d30, d0[3], d1[0], q2, q3 @ d18 = t4a, d30 = t7a - mbutterfly d26, d22, d1[1], d1[2], q2, q3 @ d26 = t5a, d22 = t6a - mbutterfly d17, d31, d1[3], d2[0], q2, q3 @ d17 = t8a, d31 = t15a - mbutterfly d25, d23, d2[1], d2[2], q2, q3 @ d25 = t9a, d23 = t14a - mbutterfly d21, d27, d2[3], d3[0], q2, q3 @ d21 = t10a, d27 = t13a - mbutterfly d29, d19, d3[1], d3[2], q2, q3 @ d29 = t11a, d19 = t12a + mbutterfly d20, d28, d0[2], d0[3], q2, q3 @ d20 = t2a, d28 = t3a + mbutterfly d18, d30, d1[0], d1[1], q2, q3 @ d18 = t4a, d30 = t7a + mbutterfly d26, d22, d1[2], d1[3], q2, q3 @ d26 = t5a, d22 = t6a + mbutterfly d17, d31, d2[0], d2[1], q2, q3 @ d17 = t8a, d31 = t15a + mbutterfly d25, d23, d2[2], d2[3], q2, q3 @ d25 = t9a, d23 = t14a + mbutterfly d21, d27, d3[0], d3[1], q2, q3 @ d21 = t10a, d27 = t13a + mbutterfly d29, d19, d3[2], d3[3], q2, q3 @ d29 = t11a, d19 = t12a butterfly d4, d28, d16, d28 @ d4 = t0, d28 = t3 butterfly d5, d20, d24, d20 @ d5 = t1, d20 = t2 @@ -612,20 +612,20 @@ function idct16 butterfly d29, d23, d31, d23 @ d29 = t15, d23 = t14 mbutterfly0 d22, d26, d22, d26, d18, d30, q9, q15 @ d22 = t6a, d26 = t5a - mbutterfly d23, d25, d0[1], d0[2], q9, q15 @ d23 = t9a, d25 = t14a - mbutterfly d27, d21, d0[1], d0[2], q9, q15, neg=1 @ d27 = t13a, d21 = t10a + mbutterfly d23, d25, d0[2], d0[3], q9, q15 @ d23 = t9a, d25 = t14a + mbutterfly d27, d21, d0[2], d0[3], q9, q15, neg=1 @ d27 = t13a, d21 = t10a idct16_end endfunc function idct16_half mbutterfly0_h d16, d24, d16, d24, d4, d6, q2, q3 @ d16 = t0a, d24 = t1a - mbutterfly_h1 d20, d28, d0[1], d0[2], q2, q3 @ d20 = t2a, d28 = t3a - mbutterfly_h1 d18, d30, d0[3], d1[0], q2, q3 @ d18 = t4a, d30 = t7a - mbutterfly_h2 d26, d22, d1[1], d1[2], q2, q3 @ d26 = t5a, d22 = t6a - mbutterfly_h1 d17, d31, d1[3], d2[0], q2, q3 @ d17 = t8a, d31 = t15a - mbutterfly_h2 d25, d23, d2[1], d2[2], q2, q3 @ d25 = t9a, d23 = t14a - mbutterfly_h1 d21, d27, d2[3], d3[0], q2, q3 @ d21 = t10a, d27 = t13a - mbutterfly_h2 d29, d19, d3[1], d3[2], q2, q3 @ d29 = t11a, d19 = t12a + mbutterfly_h1 d20, d28, d0[2], d0[3], q2, q3 @ d20 = t2a, d28 = t3a + mbutterfly_h1 d18, d30, d1[0], d1[1], q2, q3 @ d18 = t4a, d30 = t7a + mbutterfly_h2 d26, d22, d1[2], d1[3], q2, q3 @ d26 = t5a, d22 = t6a + mbutterfly_h1 d17, d31, d2[0], d2[1], q2, q3 @ d17 = t8a, d31 = t15a + mbutterfly_h2 d25, d23, d2[2], d2[3], q2, q3 @ d25 = t9a, d23 = t14a + mbutterfly_h1 d21, d27, d3[0], d3[1], q2, q3 @ d21 = t10a, d27 = t13a + mbutterfly_h2 d29, d19, d3[2], d3[3], q2, q3 @ d29 = t11a, d19 = t12a butterfly d4, d28, d16, d28 @ d4 = t0, d28 = t3 butterfly d5, d20, d24, d20 @ d5 = t1, d20 = t2 @@ -637,19 +637,19 @@ function idct16_half butterfly d29, d23, d31, d23 @ d29 = t15, d23 = t14 mbutterfly0 d22, d26, d22, d26, d18, d30, q9, q15 @ d22 = t6a, d26 = t5a - mbutterfly d23, d25, d0[1], d0[2], q9, q15 @ d23 = t9a, d25 = t14a - mbutterfly d27, d21, d0[1], d0[2], q9, q15, neg=1 @ d27 = t13a, d21 = t10a + mbutterfly d23, d25, d0[2], d0[3], q9, q15 @ d23 = t9a, d25 = t14a + mbutterfly d27, d21, d0[2], d0[3], q9, q15, neg=1 @ d27 = t13a, d21 = t10a idct16_end endfunc function idct16_quarter - vmull.s16 q12, d19, d3[2] - vmull.s16 q2, d17, d1[3] - vmull.s16 q3, d18, d1[0] - vmull.s16 q15, d18, d0[3] + vmull.s16 q12, d19, d3[3] + vmull.s16 q2, d17, d2[0] + vmull.s16 q3, d18, d1[1] + vmull.s16 q15, d18, d1[0] vneg.s32 q12, q12 - vmull.s16 q14, d17, d2[0] - vmull.s16 q13, d19, d3[1] + vmull.s16 q14, d17, d2[1] + vmull.s16 q13, d19, d3[2] vmull.s16 q11, d16, d0[0] vrshrn.s32 d24, q12, #14 vrshrn.s32 d16, q2, #14 @@ -659,8 +659,8 @@ function idct16_quarter vrshrn.s32 d17, q13, #14 vrshrn.s32 d28, q11, #14 - mbutterfly_l q10, q11, d17, d24, d0[1], d0[2] - mbutterfly_l q9, q15, d29, d16, d0[1], d0[2] + mbutterfly_l q10, q11, d17, d24, d0[2], d0[3] + mbutterfly_l q9, q15, d29, d16, d0[2], d0[3] vneg.s32 q11, q11 vrshrn.s32 d27, q10, #14 vrshrn.s32 d21, q11, #14 @@ -697,16 +697,16 @@ function iadst16 movrel r12, idct_coeffs vld1.16 {q0}, [r12,:128] butterfly_n d22, d30, q3, q5, q6, q5 @ d22 = t7a, d30 = t15a - mbutterfly_l q7, q6, d23, d24, d0[3], d1[0] @ q7 = t9, q6 = t8 + mbutterfly_l q7, q6, d23, d24, d1[0], d1[1] @ q7 = t9, q6 = t8 butterfly_n d25, d17, q2, q4, q3, q4 @ d25 = t6a, d17 = t14a - mbutterfly_l q2, q3, d28, d19, d1[0], d0[3] @ q2 = t12, q3 = t13 + mbutterfly_l q2, q3, d28, d19, d1[1], d1[0] @ q2 = t12, q3 = t13 butterfly_n d23, d19, q6, q2, q4, q2 @ d23 = t8a, d19 = t12a - mbutterfly_l q5, q4, d21, d26, d1[1], d1[2] @ q5 = t11, q4 = t10 + mbutterfly_l q5, q4, d21, d26, d1[2], d1[3] @ q5 = t11, q4 = t10 butterfly_r d4, d27, d16, d27 @ d4 = t4, d27 = t0 butterfly_n d24, d28, q7, q3, q6, q3 @ d24 = t9a, d28 = t13a - mbutterfly_l q6, q7, d30, d17, d1[2], d1[1] @ q6 = t14, q7 = t15 + mbutterfly_l q6, q7, d30, d17, d1[3], d1[2] @ q6 = t14, q7 = t15 butterfly_r d5, d20, d31, d20 @ d5 = t5, d20 = t1 butterfly_n d21, d17, q4, q6, q3, q6 @ d21 = t10a, d17 = t14a butterfly_n d26, d30, q5, q7, q4, q7 @ d26 = t11a, d30 = t15a @@ -714,15 +714,15 @@ function iadst16 butterfly_r d6, d25, d18, d25 @ d6 = t6, d25 = t2 butterfly_r d7, d22, d29, d22 @ d7 = t7, d22 = t3 - mbutterfly_l q5, q4, d19, d28, d0[1], d0[2] @ q5 = t13, q4 = t12 - mbutterfly_l q6, q7, d30, d17, d0[2], d0[1] @ q6 = t14, q7 = t15 + mbutterfly_l q5, q4, d19, d28, d0[2], d0[3] @ q5 = t13, q4 = t12 + mbutterfly_l q6, q7, d30, d17, d0[3], d0[2] @ q6 = t14, q7 = t15 butterfly_n d18, d30, q4, q6, q8, q6 @ d18 = out[2], d30 = t14a butterfly_n d29, d17, q5, q7, q6, q7 @ d29 = -out[13], d17 = t15a vneg.s16 d29, d29 @ d29 = out[13] - mbutterfly_l q5, q4, d4, d5, d0[1], d0[2] @ q5 = t5a, q4 = t4a - mbutterfly_l q6, q7, d7, d6, d0[2], d0[1] @ q6 = t6a, q7 = t7a + mbutterfly_l q5, q4, d4, d5, d0[2], d0[3] @ q5 = t5a, q4 = t4a + mbutterfly_l q6, q7, d7, d6, d0[3], d0[2] @ q6 = t6a, q7 = t7a butterfly d2, d6, d27, d25 @ d2 = out[0], d6 = t2a butterfly d3, d7, d23, d21 @ d3 =-out[1], d7 = t10 @@ -1194,10 +1194,10 @@ endfunc butterfly d11, d29, d29, d31 @ d11 = t31a, d29 = t28a butterfly d22, d27, d24, d27 @ d22 = t30, d27 = t29 - mbutterfly d27, d20, d0[1], d0[2], q12, q15 @ d27 = t18a, d20 = t29a - mbutterfly d29, d9, d0[1], d0[2], q12, q15 @ d29 = t19, d9 = t28 - mbutterfly d28, d10, d0[1], d0[2], q12, q15, neg=1 @ d28 = t27, d10 = t20 - mbutterfly d26, d21, d0[1], d0[2], q12, q15, neg=1 @ d26 = t26a, d21 = t21a + mbutterfly d27, d20, d0[2], d0[3], q12, q15 @ d27 = t18a, d20 = t29a + mbutterfly d29, d9, d0[2], d0[3], q12, q15 @ d29 = t19, d5 = t28 + mbutterfly d28, d10, d0[2], d0[3], q12, q15, neg=1 @ d28 = t27, d6 = t20 + mbutterfly d26, d21, d0[2], d0[3], q12, q15, neg=1 @ d26 = t26a, d21 = t21a butterfly d31, d24, d11, d8 @ d31 = t31, d24 = t24 butterfly d30, d25, d22, d23 @ d30 = t30a, d25 = t25a @@ -1235,10 +1235,10 @@ function idct32_odd butterfly d29, d23, d31, d23 @ d29 = t31, d23 = t30 butterfly d31, d27, d19, d27 @ d31 = t28, d27 = t29 - mbutterfly d23, d24, d0[3], d1[0], q8, q9 @ d23 = t17a, d24 = t30a - mbutterfly d27, d20, d0[3], d1[0], q8, q9, neg=1 @ d27 = t29a, d20 = t18a - mbutterfly d21, d26, d1[1], d1[2], q8, q9 @ d21 = t21a, d26 = t26a - mbutterfly d25, d22, d1[1], d1[2], q8, q9, neg=1 @ d25 = t25a, d22 = t22a + mbutterfly d23, d24, d1[0], d1[1], q8, q9 @ d23 = t17a, d24 = t30a + mbutterfly d27, d20, d1[0], d1[1], q8, q9, neg=1 @ d27 = t29a, d20 = t18a + mbutterfly d21, d26, d1[2], d1[3], q8, q9 @ d21 = t21a, d26 = t26a + mbutterfly d25, d22, d1[2], d1[3], q8, q9, neg=1 @ d25 = t25a, d22 = t22a idct32_end endfunc @@ -1261,10 +1261,10 @@ function idct32_odd_half butterfly d29, d23, d31, d23 @ d29 = t31, d23 = t30 butterfly d31, d27, d19, d27 @ d31 = t28, d27 = t29 - mbutterfly d23, d24, d0[3], d1[0], q8, q9 @ d23 = t17a, d24 = t30a - mbutterfly d27, d20, d0[3], d1[0], q8, q9, neg=1 @ d27 = t29a, d20 = t18a - mbutterfly d21, d26, d1[1], d1[2], q8, q9 @ d21 = t21a, d26 = t26a - mbutterfly d25, d22, d1[1], d1[2], q8, q9, neg=1 @ d25 = t25a, d22 = t22a + mbutterfly d23, d24, d1[0], d1[1], q8, q9 @ d23 = t17a, d24 = t30a + mbutterfly d27, d20, d1[0], d1[1], q8, q9, neg=1 @ d27 = t29a, d20 = t18a + mbutterfly d21, d26, d1[2], d1[3], q8, q9 @ d21 = t21a, d26 = t26a + mbutterfly d25, d22, d1[2], d1[3], q8, q9, neg=1 @ d25 = t25a, d22 = t22a idct32_end endfunc @@ -1291,17 +1291,17 @@ function idct32_odd_quarter vrshrn.s32 d10, q10, #14 vrshrn.s32 d30, q12, #14 - mbutterfly_l q8, q9, d29, d8, d0[3], d1[0] - mbutterfly_l q13, q10, d31, d9, d0[3], d1[0] + mbutterfly_l q8, q9, d29, d8, d1[0], d1[1] + mbutterfly_l q13, q10, d31, d9, d1[0], d1[1] vrshrn.s32 d23, q8, #14 vrshrn.s32 d24, q9, #14 vneg.s32 q10, q10 vrshrn.s32 d27, q13, #14 vrshrn.s32 d20, q10, #14 - mbutterfly_l q8, q9, d30, d10, d1[1], d1[2] + mbutterfly_l q8, q9, d30, d10, d1[2], d1[3] vrshrn.s32 d21, q8, #14 vrshrn.s32 d26, q9, #14 - mbutterfly_l q8, q9, d28, d11, d1[1], d1[2] + mbutterfly_l q8, q9, d28, d11, d1[2], d1[3] vrshrn.s32 d25, q8, #14 vneg.s32 q9, q9 vrshrn.s32 d22, q9, #14 From f952273019984da5e7bfa1298e1cdb0683049296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 31 Dec 2016 14:18:31 +0200 Subject: [PATCH 1108/3374] aarch64: vp9itxfm: Reorder the idct coefficients for better pairing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All elements are used pairwise, except for the first one. Previously, the 16th element was unused. Move the unused element to the second slot, to make the later element pairs not split across registers. This simplifies loading only parts of the coefficients, reducing the difference to the 16 bpp version. This is cherrypicked from libav commit 09eb88a12e008d10a3f7a6be75d18ad98b368e68. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 124 ++++++++++++++--------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index dd9fde15d7493..31c6e3c610621 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -22,7 +22,7 @@ #include "neon.S" const itxfm4_coeffs, align=4 - .short 11585, 6270, 15137, 0 + .short 11585, 0, 6270, 15137 iadst4_coeffs: .short 5283, 15212, 9929, 13377 endconst @@ -30,8 +30,8 @@ endconst const iadst8_coeffs, align=4 .short 16305, 1606, 14449, 7723, 10394, 12665, 4756, 15679 idct_coeffs: - .short 11585, 6270, 15137, 3196, 16069, 13623, 9102, 1606 - .short 16305, 12665, 10394, 7723, 14449, 15679, 4756, 0 + .short 11585, 0, 6270, 15137, 3196, 16069, 13623, 9102 + .short 1606, 16305, 12665, 10394, 7723, 14449, 15679, 4756 .short 804, 16364, 12140, 11003, 7005, 14811, 15426, 5520 .short 3981, 15893, 14053, 8423, 9760, 13160, 16207, 2404 endconst @@ -192,14 +192,14 @@ endconst .endm .macro idct4 c0, c1, c2, c3 - smull v22.4s, \c1\().4h, v0.h[2] - smull v20.4s, \c1\().4h, v0.h[1] + smull v22.4s, \c1\().4h, v0.h[3] + smull v20.4s, \c1\().4h, v0.h[2] add v16.4h, \c0\().4h, \c2\().4h sub v17.4h, \c0\().4h, \c2\().4h - smlal v22.4s, \c3\().4h, v0.h[1] + smlal v22.4s, \c3\().4h, v0.h[2] smull v18.4s, v16.4h, v0.h[0] smull v19.4s, v17.4h, v0.h[0] - smlsl v20.4s, \c3\().4h, v0.h[2] + smlsl v20.4s, \c3\().4h, v0.h[3] rshrn v22.4h, v22.4s, #14 rshrn v18.4h, v18.4s, #14 rshrn v19.4h, v19.4s, #14 @@ -326,9 +326,9 @@ itxfm_func4x4 iwht, iwht .macro idct8 dmbutterfly0 v16, v20, v16, v20, v2, v3, v4, v5, v6, v7 // v16 = t0a, v20 = t1a - dmbutterfly v18, v22, v0.h[1], v0.h[2], v2, v3, v4, v5 // v18 = t2a, v22 = t3a - dmbutterfly v17, v23, v0.h[3], v0.h[4], v2, v3, v4, v5 // v17 = t4a, v23 = t7a - dmbutterfly v21, v19, v0.h[5], v0.h[6], v2, v3, v4, v5 // v21 = t5a, v19 = t6a + dmbutterfly v18, v22, v0.h[2], v0.h[3], v2, v3, v4, v5 // v18 = t2a, v22 = t3a + dmbutterfly v17, v23, v0.h[4], v0.h[5], v2, v3, v4, v5 // v17 = t4a, v23 = t7a + dmbutterfly v21, v19, v0.h[6], v0.h[7], v2, v3, v4, v5 // v21 = t5a, v19 = t6a butterfly_8h v24, v25, v16, v22 // v24 = t0, v25 = t3 butterfly_8h v28, v29, v17, v21 // v28 = t4, v29 = t5a @@ -361,8 +361,8 @@ itxfm_func4x4 iwht, iwht dmbutterfly0 v19, v20, v6, v7, v24, v26, v27, v28, v29, v30 // v19 = -out[3], v20 = out[4] neg v19.8h, v19.8h // v19 = out[3] - dmbutterfly_l v26, v27, v28, v29, v5, v3, v0.h[1], v0.h[2] // v26,v27 = t5a, v28,v29 = t4a - dmbutterfly_l v2, v3, v4, v5, v31, v25, v0.h[2], v0.h[1] // v2,v3 = t6a, v4,v5 = t7a + dmbutterfly_l v26, v27, v28, v29, v5, v3, v0.h[2], v0.h[3] // v26,v27 = t5a, v28,v29 = t4a + dmbutterfly_l v2, v3, v4, v5, v31, v25, v0.h[3], v0.h[2] // v2,v3 = t6a, v4,v5 = t7a dbutterfly_n v17, v30, v28, v29, v2, v3, v6, v7, v24, v25 // v17 = -out[1], v30 = t6 dbutterfly_n v22, v31, v26, v27, v4, v5, v6, v7, v24, v25 // v22 = out[6], v31 = t7 @@ -543,13 +543,13 @@ endfunc function idct16 dmbutterfly0 v16, v24, v16, v24, v2, v3, v4, v5, v6, v7 // v16 = t0a, v24 = t1a - dmbutterfly v20, v28, v0.h[1], v0.h[2], v2, v3, v4, v5 // v20 = t2a, v28 = t3a - dmbutterfly v18, v30, v0.h[3], v0.h[4], v2, v3, v4, v5 // v18 = t4a, v30 = t7a - dmbutterfly v26, v22, v0.h[5], v0.h[6], v2, v3, v4, v5 // v26 = t5a, v22 = t6a - dmbutterfly v17, v31, v0.h[7], v1.h[0], v2, v3, v4, v5 // v17 = t8a, v31 = t15a - dmbutterfly v25, v23, v1.h[1], v1.h[2], v2, v3, v4, v5 // v25 = t9a, v23 = t14a - dmbutterfly v21, v27, v1.h[3], v1.h[4], v2, v3, v4, v5 // v21 = t10a, v27 = t13a - dmbutterfly v29, v19, v1.h[5], v1.h[6], v2, v3, v4, v5 // v29 = t11a, v19 = t12a + dmbutterfly v20, v28, v0.h[2], v0.h[3], v2, v3, v4, v5 // v20 = t2a, v28 = t3a + dmbutterfly v18, v30, v0.h[4], v0.h[5], v2, v3, v4, v5 // v18 = t4a, v30 = t7a + dmbutterfly v26, v22, v0.h[6], v0.h[7], v2, v3, v4, v5 // v26 = t5a, v22 = t6a + dmbutterfly v17, v31, v1.h[0], v1.h[1], v2, v3, v4, v5 // v17 = t8a, v31 = t15a + dmbutterfly v25, v23, v1.h[2], v1.h[3], v2, v3, v4, v5 // v25 = t9a, v23 = t14a + dmbutterfly v21, v27, v1.h[4], v1.h[5], v2, v3, v4, v5 // v21 = t10a, v27 = t13a + dmbutterfly v29, v19, v1.h[6], v1.h[7], v2, v3, v4, v5 // v29 = t11a, v19 = t12a butterfly_8h v4, v28, v16, v28 // v4 = t0, v28 = t3 butterfly_8h v5, v20, v24, v20 // v5 = t1, v20 = t2 @@ -561,20 +561,20 @@ function idct16 butterfly_8h v29, v23, v31, v23 // v29 = t15, v23 = t14 dmbutterfly0 v22, v26, v22, v26, v2, v3, v18, v19, v30, v31 // v22 = t6a, v26 = t5a - dmbutterfly v23, v25, v0.h[1], v0.h[2], v18, v19, v30, v31 // v23 = t9a, v25 = t14a - dmbutterfly v27, v21, v0.h[1], v0.h[2], v18, v19, v30, v31, neg=1 // v27 = t13a, v21 = t10a + dmbutterfly v23, v25, v0.h[2], v0.h[3], v18, v19, v30, v31 // v23 = t9a, v25 = t14a + dmbutterfly v27, v21, v0.h[2], v0.h[3], v18, v19, v30, v31, neg=1 // v27 = t13a, v21 = t10a idct16_end endfunc function idct16_half dmbutterfly0_h v16, v24, v16, v24, v2, v3, v4, v5, v6, v7 // v16 = t0a, v24 = t1a - dmbutterfly_h1 v20, v28, v0.h[1], v0.h[2], v2, v3, v4, v5 // v20 = t2a, v28 = t3a - dmbutterfly_h1 v18, v30, v0.h[3], v0.h[4], v2, v3, v4, v5 // v18 = t4a, v30 = t7a - dmbutterfly_h2 v26, v22, v0.h[5], v0.h[6], v2, v3, v4, v5 // v26 = t5a, v22 = t6a - dmbutterfly_h1 v17, v31, v0.h[7], v1.h[0], v2, v3, v4, v5 // v17 = t8a, v31 = t15a - dmbutterfly_h2 v25, v23, v1.h[1], v1.h[2], v2, v3, v4, v5 // v25 = t9a, v23 = t14a - dmbutterfly_h1 v21, v27, v1.h[3], v1.h[4], v2, v3, v4, v5 // v21 = t10a, v27 = t13a - dmbutterfly_h2 v29, v19, v1.h[5], v1.h[6], v2, v3, v4, v5 // v29 = t11a, v19 = t12a + dmbutterfly_h1 v20, v28, v0.h[2], v0.h[3], v2, v3, v4, v5 // v20 = t2a, v28 = t3a + dmbutterfly_h1 v18, v30, v0.h[4], v0.h[5], v2, v3, v4, v5 // v18 = t4a, v30 = t7a + dmbutterfly_h2 v26, v22, v0.h[6], v0.h[7], v2, v3, v4, v5 // v26 = t5a, v22 = t6a + dmbutterfly_h1 v17, v31, v1.h[0], v1.h[1], v2, v3, v4, v5 // v17 = t8a, v31 = t15a + dmbutterfly_h2 v25, v23, v1.h[2], v1.h[3], v2, v3, v4, v5 // v25 = t9a, v23 = t14a + dmbutterfly_h1 v21, v27, v1.h[4], v1.h[5], v2, v3, v4, v5 // v21 = t10a, v27 = t13a + dmbutterfly_h2 v29, v19, v1.h[6], v1.h[7], v2, v3, v4, v5 // v29 = t11a, v19 = t12a butterfly_8h v4, v28, v16, v28 // v4 = t0, v28 = t3 butterfly_8h v5, v20, v24, v20 // v5 = t1, v20 = t2 @@ -586,20 +586,20 @@ function idct16_half butterfly_8h v29, v23, v31, v23 // v29 = t15, v23 = t14 dmbutterfly0 v22, v26, v22, v26, v2, v3, v18, v19, v30, v31 // v22 = t6a, v26 = t5a - dmbutterfly v23, v25, v0.h[1], v0.h[2], v18, v19, v30, v31 // v23 = t9a, v25 = t14a - dmbutterfly v27, v21, v0.h[1], v0.h[2], v18, v19, v30, v31, neg=1 // v27 = t13a, v21 = t10a + dmbutterfly v23, v25, v0.h[2], v0.h[3], v18, v19, v30, v31 // v23 = t9a, v25 = t14a + dmbutterfly v27, v21, v0.h[2], v0.h[3], v18, v19, v30, v31, neg=1 // v27 = t13a, v21 = t10a idct16_end endfunc function idct16_quarter - dsmull_h v24, v25, v19, v1.h[6] - dsmull_h v4, v5, v17, v0.h[7] - dsmull_h v7, v6, v18, v0.h[4] - dsmull_h v30, v31, v18, v0.h[3] + dsmull_h v24, v25, v19, v1.h[7] + dsmull_h v4, v5, v17, v1.h[0] + dsmull_h v7, v6, v18, v0.h[5] + dsmull_h v30, v31, v18, v0.h[4] neg v24.4s, v24.4s neg v25.4s, v25.4s - dsmull_h v29, v28, v17, v1.h[0] - dsmull_h v26, v27, v19, v1.h[5] + dsmull_h v29, v28, v17, v1.h[1] + dsmull_h v26, v27, v19, v1.h[6] dsmull_h v22, v23, v16, v0.h[0] drshrn_h v24, v24, v25, #14 drshrn_h v16, v4, v5, #14 @@ -609,8 +609,8 @@ function idct16_quarter drshrn_h v17, v26, v27, #14 drshrn_h v28, v22, v23, #14 - dmbutterfly_l v20, v21, v22, v23, v17, v24, v0.h[1], v0.h[2] - dmbutterfly_l v18, v19, v30, v31, v29, v16, v0.h[1], v0.h[2] + dmbutterfly_l v20, v21, v22, v23, v17, v24, v0.h[2], v0.h[3] + dmbutterfly_l v18, v19, v30, v31, v29, v16, v0.h[2], v0.h[3] neg v22.4s, v22.4s neg v23.4s, v23.4s drshrn_h v27, v20, v21, #14 @@ -646,16 +646,16 @@ function iadst16 dmbutterfly_l v10, v11, v8, v9, v17, v30, v1.h[7], v1.h[6] // v10,v11 = t15, v8,v9 = t14 ld1 {v0.8h}, [x10] dbutterfly_n v22, v30, v6, v7, v10, v11, v12, v13, v10, v11 // v22 = t7a, v30 = t15a - dmbutterfly_l v14, v15, v12, v13, v23, v24, v0.h[3], v0.h[4] // v14,v15 = t9, v12,v13 = t8 + dmbutterfly_l v14, v15, v12, v13, v23, v24, v0.h[4], v0.h[5] // v14,v15 = t9, v12,v13 = t8 dbutterfly_n v25, v17, v4, v5, v8, v9, v6, v7, v8, v9 // v25 = t6a, v17 = t14a - dmbutterfly_l v4, v5, v6, v7, v28, v19, v0.h[4], v0.h[3] // v4,v5 = t12, v6,v7 = t13 + dmbutterfly_l v4, v5, v6, v7, v28, v19, v0.h[5], v0.h[4] // v4,v5 = t12, v6,v7 = t13 dbutterfly_n v23, v19, v12, v13, v4, v5, v8, v9, v4, v5 // v23 = t8a, v19 = t12a - dmbutterfly_l v10, v11, v8, v9, v21, v26, v0.h[5], v0.h[6] // v10,v11 = t11, v8,v9 = t10 + dmbutterfly_l v10, v11, v8, v9, v21, v26, v0.h[6], v0.h[7] // v10,v11 = t11, v8,v9 = t10 butterfly_8h_r v4, v27, v16, v27 // v4 = t4, v27 = t0 dbutterfly_n v24, v28, v14, v15, v6, v7, v12, v13, v6, v7 // v24 = t9a, v28 = t13a - dmbutterfly_l v12, v13, v14, v15, v30, v17, v0.h[6], v0.h[5] // v12,v13 = t14, v14,v15 = t15 + dmbutterfly_l v12, v13, v14, v15, v30, v17, v0.h[7], v0.h[6] // v12,v13 = t14, v14,v15 = t15 butterfly_8h_r v5, v20, v31, v20 // v5 = t5, v20 = t1 dbutterfly_n v21, v17, v8, v9, v12, v13, v6, v7, v12, v13 // v21 = t10a, v17 = t14a dbutterfly_n v26, v30, v10, v11, v14, v15, v8, v9, v14, v15 // v26 = t11a, v30 = t15a @@ -663,15 +663,15 @@ function iadst16 butterfly_8h_r v6, v25, v18, v25 // v6 = t6, v25 = t2 butterfly_8h_r v7, v22, v29, v22 // v7 = t7, v22 = t3 - dmbutterfly_l v10, v11, v8, v9, v19, v28, v0.h[1], v0.h[2] // v10,v11 = t13, v8,v9 = t12 - dmbutterfly_l v12, v13, v14, v15, v30, v17, v0.h[2], v0.h[1] // v12,v13 = t14, v14,v15 = t15 + dmbutterfly_l v10, v11, v8, v9, v19, v28, v0.h[2], v0.h[3] // v10,v11 = t13, v8,v9 = t12 + dmbutterfly_l v12, v13, v14, v15, v30, v17, v0.h[3], v0.h[2] // v12,v13 = t14, v14,v15 = t15 dbutterfly_n v18, v30, v8, v9, v12, v13, v16, v17, v12, v13 // v18 = out[2], v30 = t14a dbutterfly_n v29, v17, v10, v11, v14, v15, v12, v13, v14, v15 // v29 = -out[13], v17 = t15a neg v29.8h, v29.8h // v29 = out[13] - dmbutterfly_l v10, v11, v8, v9, v4, v5, v0.h[1], v0.h[2] // v10,v11 = t5a, v8,v9 = t4a - dmbutterfly_l v12, v13, v14, v15, v7, v6, v0.h[2], v0.h[1] // v12,v13 = t6a, v14,v15 = t7a + dmbutterfly_l v10, v11, v8, v9, v4, v5, v0.h[2], v0.h[3] // v10,v11 = t5a, v8,v9 = t4a + dmbutterfly_l v12, v13, v14, v15, v7, v6, v0.h[3], v0.h[2] // v12,v13 = t6a, v14,v15 = t7a butterfly_8h v2, v6, v27, v25 // v2 = out[0], v6 = t2a butterfly_8h v3, v7, v23, v21 // v3 =-out[1], v7 = t10 @@ -1101,10 +1101,10 @@ endfunc butterfly_8h v7, v3, v29, v31 // v7 = t31a, v3 = t28a butterfly_8h v22, v27, v24, v27 // v22 = t30, v27 = t29 - dmbutterfly v27, v20, v0.h[1], v0.h[2], v24, v25, v30, v31 // v27 = t18a, v20 = t29a - dmbutterfly v3, v5, v0.h[1], v0.h[2], v24, v25, v30, v31 // v3 = t19, v5 = t28 - dmbutterfly v28, v6, v0.h[1], v0.h[2], v24, v25, v30, v31, neg=1 // v28 = t27, v6 = t20 - dmbutterfly v26, v21, v0.h[1], v0.h[2], v24, v25, v30, v31, neg=1 // v26 = t26a, v21 = t21a + dmbutterfly v27, v20, v0.h[2], v0.h[3], v24, v25, v30, v31 // v27 = t18a, v20 = t29a + dmbutterfly v3, v5, v0.h[2], v0.h[3], v24, v25, v30, v31 // v3 = t19, v5 = t28 + dmbutterfly v28, v6, v0.h[2], v0.h[3], v24, v25, v30, v31, neg=1 // v28 = t27, v6 = t20 + dmbutterfly v26, v21, v0.h[2], v0.h[3], v24, v25, v30, v31, neg=1 // v26 = t26a, v21 = t21a butterfly_8h v31, v24, v7, v4 // v31 = t31, v24 = t24 butterfly_8h v30, v25, v22, v23 // v30 = t30a, v25 = t25a @@ -1141,10 +1141,10 @@ function idct32_odd butterfly_8h v29, v23, v31, v23 // v29 = t31, v23 = t30 butterfly_8h v31, v27, v19, v27 // v31 = t28, v27 = t29 - dmbutterfly v23, v24, v0.h[3], v0.h[4], v16, v17, v18, v19 // v23 = t17a, v24 = t30a - dmbutterfly v27, v20, v0.h[3], v0.h[4], v16, v17, v18, v19, neg=1 // v27 = t29a, v20 = t18a - dmbutterfly v21, v26, v0.h[5], v0.h[6], v16, v17, v18, v19 // v21 = t21a, v26 = t26a - dmbutterfly v25, v22, v0.h[5], v0.h[6], v16, v17, v18, v19, neg=1 // v25 = t25a, v22 = t22a + dmbutterfly v23, v24, v0.h[4], v0.h[5], v16, v17, v18, v19 // v23 = t17a, v24 = t30a + dmbutterfly v27, v20, v0.h[4], v0.h[5], v16, v17, v18, v19, neg=1 // v27 = t29a, v20 = t18a + dmbutterfly v21, v26, v0.h[6], v0.h[7], v16, v17, v18, v19 // v21 = t21a, v26 = t26a + dmbutterfly v25, v22, v0.h[6], v0.h[7], v16, v17, v18, v19, neg=1 // v25 = t25a, v22 = t22a idct32_end endfunc @@ -1167,10 +1167,10 @@ function idct32_odd_half butterfly_8h v29, v23, v31, v23 // v29 = t31, v23 = t30 butterfly_8h v31, v27, v19, v27 // v31 = t28, v27 = t29 - dmbutterfly v23, v24, v0.h[3], v0.h[4], v16, v17, v18, v19 // v23 = t17a, v24 = t30a - dmbutterfly v27, v20, v0.h[3], v0.h[4], v16, v17, v18, v19, neg=1 // v27 = t29a, v20 = t18a - dmbutterfly v21, v26, v0.h[5], v0.h[6], v16, v17, v18, v19 // v21 = t21a, v26 = t26a - dmbutterfly v25, v22, v0.h[5], v0.h[6], v16, v17, v18, v19, neg=1 // v25 = t25a, v22 = t22a + dmbutterfly v23, v24, v0.h[4], v0.h[5], v16, v17, v18, v19 // v23 = t17a, v24 = t30a + dmbutterfly v27, v20, v0.h[4], v0.h[5], v16, v17, v18, v19, neg=1 // v27 = t29a, v20 = t18a + dmbutterfly v21, v26, v0.h[6], v0.h[7], v16, v17, v18, v19 // v21 = t21a, v26 = t26a + dmbutterfly v25, v22, v0.h[6], v0.h[7], v16, v17, v18, v19, neg=1 // v25 = t25a, v22 = t22a idct32_end endfunc @@ -1198,18 +1198,18 @@ function idct32_odd_quarter drshrn_h v6, v20, v21, #14 drshrn_h v30, v24, v25, #14 - dmbutterfly_l v16, v17, v18, v19, v29, v4, v0.h[3], v0.h[4] - dmbutterfly_l v27, v26, v20, v21, v31, v5, v0.h[3], v0.h[4] + dmbutterfly_l v16, v17, v18, v19, v29, v4, v0.h[4], v0.h[5] + dmbutterfly_l v27, v26, v20, v21, v31, v5, v0.h[4], v0.h[5] drshrn_h v23, v16, v17, #14 drshrn_h v24, v18, v19, #14 neg v20.4s, v20.4s neg v21.4s, v21.4s drshrn_h v27, v27, v26, #14 drshrn_h v20, v20, v21, #14 - dmbutterfly_l v16, v17, v18, v19, v30, v6, v0.h[5], v0.h[6] + dmbutterfly_l v16, v17, v18, v19, v30, v6, v0.h[6], v0.h[7] drshrn_h v21, v16, v17, #14 drshrn_h v26, v18, v19, #14 - dmbutterfly_l v16, v17, v18, v19, v28, v7, v0.h[5], v0.h[6] + dmbutterfly_l v16, v17, v18, v19, v28, v7, v0.h[6], v0.h[7] drshrn_h v25, v16, v17, #14 neg v18.4s, v18.4s neg v19.4s, v19.4s From b2e20d89844b51c3d9565b293606d1433bd67f25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 31 Dec 2016 22:27:13 +0200 Subject: [PATCH 1109/3374] arm: vp9itxfm: Reorder iadst16 coeffs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matches the order they are in the 16 bpp version. There they are in this order, to make sure we access them in the same order they are declared, easing loading only half of the coefficients at a time. This makes the 8 bpp version match the 16 bpp version better. This is cherrypicked from libav commit 08074c092d8c97d71c5986e5325e97ffc956119d. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index 05e31e62406db..ebbbda9248674 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -37,8 +37,8 @@ idct_coeffs: endconst const iadst16_coeffs, align=4 - .short 16364, 804, 15893, 3981, 14811, 7005, 13160, 9760 - .short 11003, 12140, 8423, 14053, 5520, 15426, 2404, 16207 + .short 16364, 804, 15893, 3981, 11003, 12140, 8423, 14053 + .short 14811, 7005, 13160, 9760, 5520, 15426, 2404, 16207 endconst @ Do four 4x4 transposes, using q registers for the subtransposes that don't @@ -678,19 +678,19 @@ function iadst16 vld1.16 {q0-q1}, [r12,:128] mbutterfly_l q3, q2, d31, d16, d0[1], d0[0] @ q3 = t1, q2 = t0 - mbutterfly_l q5, q4, d23, d24, d2[1], d2[0] @ q5 = t9, q4 = t8 + mbutterfly_l q5, q4, d23, d24, d1[1], d1[0] @ q5 = t9, q4 = t8 butterfly_n d31, d24, q3, q5, q6, q5 @ d31 = t1a, d24 = t9a mbutterfly_l q7, q6, d29, d18, d0[3], d0[2] @ q7 = t3, q6 = t2 butterfly_n d16, d23, q2, q4, q3, q4 @ d16 = t0a, d23 = t8a - mbutterfly_l q3, q2, d21, d26, d2[3], d2[2] @ q3 = t11, q2 = t10 + mbutterfly_l q3, q2, d21, d26, d1[3], d1[2] @ q3 = t11, q2 = t10 butterfly_n d29, d26, q7, q3, q4, q3 @ d29 = t3a, d26 = t11a - mbutterfly_l q5, q4, d27, d20, d1[1], d1[0] @ q5 = t5, q4 = t4 + mbutterfly_l q5, q4, d27, d20, d2[1], d2[0] @ q5 = t5, q4 = t4 butterfly_n d18, d21, q6, q2, q3, q2 @ d18 = t2a, d21 = t10a mbutterfly_l q7, q6, d19, d28, d3[1], d3[0] @ q7 = t13, q6 = t12 butterfly_n d20, d28, q5, q7, q2, q7 @ d20 = t5a, d28 = t13a - mbutterfly_l q3, q2, d25, d22, d1[3], d1[2] @ q3 = t7, q2 = t6 + mbutterfly_l q3, q2, d25, d22, d2[3], d2[2] @ q3 = t7, q2 = t6 butterfly_n d27, d19, q4, q6, q5, q6 @ d27 = t4a, d19 = t12a mbutterfly_l q5, q4, d17, d30, d3[3], d3[2] @ q5 = t15, q4 = t14 From 26ee83acc4ebd765529b666c7f050243b7677d76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 31 Dec 2016 22:27:13 +0200 Subject: [PATCH 1110/3374] aarch64: vp9itxfm: Reorder iadst16 coeffs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matches the order they are in the 16 bpp version. There they are in this order, to make sure we access them in the same order they are declared, easing loading only half of the coefficients at a time. This makes the 8 bpp version match the 16 bpp version better. This is cherrypicked from libav commit b8f66c0838b4c645227f23a35b4d54373da4c60a. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index 31c6e3c610621..2c3c002d54c9c 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -37,8 +37,8 @@ idct_coeffs: endconst const iadst16_coeffs, align=4 - .short 16364, 804, 15893, 3981, 14811, 7005, 13160, 9760 - .short 11003, 12140, 8423, 14053, 5520, 15426, 2404, 16207 + .short 16364, 804, 15893, 3981, 11003, 12140, 8423, 14053 + .short 14811, 7005, 13160, 9760, 5520, 15426, 2404, 16207 endconst // out1 = ((in1 + in2) * v0[0] + (1 << 13)) >> 14 @@ -628,19 +628,19 @@ function iadst16 ld1 {v0.8h,v1.8h}, [x11] dmbutterfly_l v6, v7, v4, v5, v31, v16, v0.h[1], v0.h[0] // v6,v7 = t1, v4,v5 = t0 - dmbutterfly_l v10, v11, v8, v9, v23, v24, v1.h[1], v1.h[0] // v10,v11 = t9, v8,v9 = t8 + dmbutterfly_l v10, v11, v8, v9, v23, v24, v0.h[5], v0.h[4] // v10,v11 = t9, v8,v9 = t8 dbutterfly_n v31, v24, v6, v7, v10, v11, v12, v13, v10, v11 // v31 = t1a, v24 = t9a dmbutterfly_l v14, v15, v12, v13, v29, v18, v0.h[3], v0.h[2] // v14,v15 = t3, v12,v13 = t2 dbutterfly_n v16, v23, v4, v5, v8, v9, v6, v7, v8, v9 // v16 = t0a, v23 = t8a - dmbutterfly_l v6, v7, v4, v5, v21, v26, v1.h[3], v1.h[2] // v6,v7 = t11, v4,v5 = t10 + dmbutterfly_l v6, v7, v4, v5, v21, v26, v0.h[7], v0.h[6] // v6,v7 = t11, v4,v5 = t10 dbutterfly_n v29, v26, v14, v15, v6, v7, v8, v9, v6, v7 // v29 = t3a, v26 = t11a - dmbutterfly_l v10, v11, v8, v9, v27, v20, v0.h[5], v0.h[4] // v10,v11 = t5, v8,v9 = t4 + dmbutterfly_l v10, v11, v8, v9, v27, v20, v1.h[1], v1.h[0] // v10,v11 = t5, v8,v9 = t4 dbutterfly_n v18, v21, v12, v13, v4, v5, v6, v7, v4, v5 // v18 = t2a, v21 = t10a dmbutterfly_l v14, v15, v12, v13, v19, v28, v1.h[5], v1.h[4] // v14,v15 = t13, v12,v13 = t12 dbutterfly_n v20, v28, v10, v11, v14, v15, v4, v5, v14, v15 // v20 = t5a, v28 = t13a - dmbutterfly_l v6, v7, v4, v5, v25, v22, v0.h[7], v0.h[6] // v6,v7 = t7, v4,v5 = t6 + dmbutterfly_l v6, v7, v4, v5, v25, v22, v1.h[3], v1.h[2] // v6,v7 = t7, v4,v5 = t6 dbutterfly_n v27, v19, v8, v9, v12, v13, v10, v11, v12, v13 // v27 = t4a, v19 = t12a dmbutterfly_l v10, v11, v8, v9, v17, v30, v1.h[7], v1.h[6] // v10,v11 = t15, v8,v9 = t14 From 70a9407b509fbefb60a215bc4ad00e54eb4e64ab Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Sat, 11 Mar 2017 21:11:38 +0800 Subject: [PATCH 1111/3374] doc/muxers: move hls_flags temp_file to after SECOND LEVEL hls example the temp_file hls_flags describe text offset is wrong, now move it after example Signed-off-by: Steven Liu --- doc/muxers.texi | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index 30c08ad028479..fa89e6cfa9085 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -656,11 +656,6 @@ Makes it possible to use segment duration (calculated in microseconds) as %%t i expression besides date/time values when use_localtime is on. To get fixed width numbers with trailing zeroes, %%0xt format is available where x is the required width. -@item temp_file -Write segment data to filename.tmp and rename to filename only once the segment is complete. A webserver -serving up segments can be configured to reject requests to *.tmp to prevent access to in-progress segments -before they have been added to the m3u8 playlist. - @example ffmpeg -i sample.mpeg \ -f hls -hls_time 3 -hls_list_size 5 \ @@ -670,6 +665,10 @@ ffmpeg -i sample.mpeg \ This will produce segments like this: @file{segment_20170102194334_0003_00122200_0000003000000.ts}, @file{segment_20170102194334_0004_00120072_0000003000000.ts} etc. +@item temp_file +Write segment data to filename.tmp and rename to filename only once the segment is complete. A webserver +serving up segments can be configured to reject requests to *.tmp to prevent access to in-progress segments +before they have been added to the m3u8 playlist. @end table From 89c0fda5f43d8a3d3a1c538ff8d72e6737bc7d8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Sobala?= Date: Fri, 3 Mar 2017 09:38:28 +0100 Subject: [PATCH 1112/3374] lavf/dashenc: update bitrates on dash_write_trailer Provides a way to change bandwidth parameter inside DASH manifest after a non-CBR H.264 encoding. Caller now is able to compute the bitrate by itself, after all packets have been written, and then set that value in AVFormatContext->streams->codecpar->bit_rate before calling av_write_trailer. As a result that value will be set in DASH manifest. Signed-off-by: Michael Niedermayer --- libavformat/dashenc.c | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index fa56505f8fc9a..1f31968ab99d0 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -561,6 +561,30 @@ static int write_manifest(AVFormatContext *s, int final) return 0; } +static int set_bitrate(AVFormatContext *s) +{ + DASHContext *c = s->priv_data; + int i; + + for (i = 0; i < s->nb_streams; i++) { + OutputStream *os = &c->streams[i]; + + os->bit_rate = s->streams[i]->codecpar->bit_rate; + if (os->bit_rate) { + snprintf(os->bandwidth_str, sizeof(os->bandwidth_str), + " bandwidth=\"%d\"", os->bit_rate); + } else { + int level = s->strict_std_compliance >= FF_COMPLIANCE_STRICT ? + AV_LOG_ERROR : AV_LOG_WARNING; + av_log(s, level, "No bit rate set for stream %d\n", i); + if (s->strict_std_compliance >= FF_COMPLIANCE_STRICT) + return AVERROR(EINVAL); + } + } + + return 0; +} + static int dash_init(AVFormatContext *s) { DASHContext *c = s->priv_data; @@ -597,6 +621,10 @@ static int dash_init(AVFormatContext *s) if (!c->streams) return AVERROR(ENOMEM); + ret = set_bitrate(s); + if (ret < 0) + return ret; + for (i = 0; i < s->nb_streams; i++) { OutputStream *os = &c->streams[i]; AVFormatContext *ctx; @@ -604,18 +632,6 @@ static int dash_init(AVFormatContext *s) AVDictionary *opts = NULL; char filename[1024]; - os->bit_rate = s->streams[i]->codecpar->bit_rate; - if (os->bit_rate) { - snprintf(os->bandwidth_str, sizeof(os->bandwidth_str), - " bandwidth=\"%d\"", os->bit_rate); - } else { - int level = s->strict_std_compliance >= FF_COMPLIANCE_STRICT ? - AV_LOG_ERROR : AV_LOG_WARNING; - av_log(s, level, "No bit rate set for stream %d\n", i); - if (s->strict_std_compliance >= FF_COMPLIANCE_STRICT) - return AVERROR(EINVAL); - } - ctx = avformat_alloc_context(); if (!ctx) return AVERROR(ENOMEM); @@ -981,6 +997,8 @@ static int dash_write_trailer(AVFormatContext *s) { DASHContext *c = s->priv_data; + set_bitrate(s); + if (s->nb_streams > 0) { OutputStream *os = &c->streams[0]; // If no segments have been written so far, try to do a crude From 0bab78f7e729a76ea7a8cbec7f1de033c52494e8 Mon Sep 17 00:00:00 2001 From: Muhammad Faiz Date: Sat, 11 Mar 2017 07:54:30 +0700 Subject: [PATCH 1113/3374] avfilter/af_firequalizer: add av_restrict on convolution func slightly improved speed Reviewed-by: wm4 Signed-off-by: Muhammad Faiz --- libavfilter/af_firequalizer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavfilter/af_firequalizer.c b/libavfilter/af_firequalizer.c index 5c6fd542ae517..4243d66bd632e 100644 --- a/libavfilter/af_firequalizer.c +++ b/libavfilter/af_firequalizer.c @@ -197,8 +197,8 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_samplerates(ctx, formats); } -static void fast_convolute(FIREqualizerContext *s, const float *kernel_buf, float *conv_buf, - OverlapIndex *idx, float *data, int nsamples) +static void fast_convolute(FIREqualizerContext *av_restrict s, const float *av_restrict kernel_buf, float *av_restrict conv_buf, + OverlapIndex *av_restrict idx, float *av_restrict data, int nsamples) { if (nsamples <= s->nsamples_max) { float *buf = conv_buf + idx->buf_idx * s->rdft_len; @@ -235,8 +235,8 @@ static void fast_convolute(FIREqualizerContext *s, const float *kernel_buf, floa } } -static void fast_convolute2(FIREqualizerContext *s, const float *kernel_buf, FFTComplex *conv_buf, - OverlapIndex *idx, float *data0, float *data1, int nsamples) +static void fast_convolute2(FIREqualizerContext *av_restrict s, const float *av_restrict kernel_buf, FFTComplex *av_restrict conv_buf, + OverlapIndex *av_restrict idx, float *av_restrict data0, float *av_restrict data1, int nsamples) { if (nsamples <= s->nsamples_max) { FFTComplex *buf = conv_buf + idx->buf_idx * s->rdft_len; From 47cc9c1d77f5362e1ba8cee604cb0853d3576b0b Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 11 Mar 2017 03:25:41 +0100 Subject: [PATCH 1114/3374] avcodec/wavpack: Fix runtime error: signed integer overflow: -2147483648 + -83886075 cannot be represented in type 'int' Fixes: 761/clusterfuzz-testcase-5442222252097536 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/wavpack.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/wavpack.h b/libavcodec/wavpack.h index 0196574aab3c5..445d593c3bb6a 100644 --- a/libavcodec/wavpack.h +++ b/libavcodec/wavpack.h @@ -99,8 +99,8 @@ typedef struct WvChannel { // macros for manipulating median values #define GET_MED(n) ((c->median[n] >> 4) + 1) -#define DEC_MED(n) c->median[n] -= ((c->median[n] + (128 >> (n)) - 2) / (128 >> (n))) * 2 -#define INC_MED(n) c->median[n] += ((c->median[n] + (128 >> (n)) ) / (128 >> (n))) * 5 +#define DEC_MED(n) c->median[n] -= ((c->median[n] + (128 >> (n)) - 2) / (128 >> (n))) * 2U +#define INC_MED(n) c->median[n] += ((c->median[n] + (128 >> (n)) ) / (128 >> (n))) * 5U // macros for applying weight #define UPDATE_WEIGHT_CLIP(weight, delta, samples, in) \ From f4c2302ee24d8a6a31226acca48fe9caed597a8c Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 11 Mar 2017 03:38:01 +0100 Subject: [PATCH 1115/3374] avcodec/dca_xll: Fix runtime error: signed integer overflow: 1762028192 + 698372290 cannot be represented in type 'int' Fixes: 762/clusterfuzz-testcase-5927683747741696 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/dca_xll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/dca_xll.c b/libavcodec/dca_xll.c index 6cebda35e4bf5..b7331e04b9415 100644 --- a/libavcodec/dca_xll.c +++ b/libavcodec/dca_xll.c @@ -658,7 +658,7 @@ static void chs_filter_band_data(DCAXllDecoder *s, DCAXllChSet *c, int band) // Inverse fixed coefficient prediction for (j = 0; j < b->fixed_pred_order[i]; j++) for (k = 1; k < nsamples; k++) - buf[k] += buf[k - 1]; + buf[k] += (unsigned)buf[k - 1]; } } From 44e2105189ac66637f34c764febc349238250b1d Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 11 Mar 2017 03:55:39 +0100 Subject: [PATCH 1116/3374] avcodec/amrwbdec: Fix runtime error: left shift of negative value -1 Fixes: 763/clusterfuzz-testcase-6007567320875008 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/amrwbdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c index 999bfb99dc401..57aed874cc467 100644 --- a/libavcodec/amrwbdec.c +++ b/libavcodec/amrwbdec.c @@ -262,7 +262,7 @@ static void decode_pitch_lag_high(int *lag_int, int *lag_frac, int pitch_index, *lag_frac = pitch_index - (*lag_int << 2) + 136; } else if (pitch_index < 440) { *lag_int = (pitch_index + 257 - 376) >> 1; - *lag_frac = (pitch_index - (*lag_int << 1) + 256 - 376) << 1; + *lag_frac = (pitch_index - (*lag_int << 1) + 256 - 376) * 2; /* the actual resolution is 1/2 but expressed as 1/4 */ } else { *lag_int = pitch_index - 280; From ce010655a6b82d49bd8df179d73bcb5802a273c1 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 8 Mar 2017 21:35:51 +0100 Subject: [PATCH 1117/3374] avcodec/dca_xll: Fix runtime error: signed integer overflow: 2147286116 + 6298923 cannot be represented in type 'int' Fixes: 732/clusterfuzz-testcase-4872990070145024 See: [FFmpeg-devel] [PATCH 2/6] avcodec/dca_xll: Fix runtime error: signed integer overflow: 2147286116 + 6298923 cannot be represented in type 'int' Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/dca_xll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/dca_xll.c b/libavcodec/dca_xll.c index b7331e04b9415..38a1999fc80bc 100644 --- a/libavcodec/dca_xll.c +++ b/libavcodec/dca_xll.c @@ -1312,7 +1312,7 @@ static int combine_residual_frame(DCAXllDecoder *s, DCAXllChSet *c) } else { // No downmix scaling for (n = 0; n < nsamples; n++) - dst[n] += (src[n] + round) >> shift; + dst[n] += (unsigned)((src[n] + round) >> shift); } } From 807d5dcde9d83dca48f8dfc5c98bbc2be6fdc61c Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 12 Mar 2017 12:34:55 +0100 Subject: [PATCH 1118/3374] avcodec/scpr: use correct linesize for prev frame Signed-off-by: Paul B Mahol --- libavcodec/scpr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/scpr.c b/libavcodec/scpr.c index 1fc0593dbb6e5..465926af19f3f 100644 --- a/libavcodec/scpr.c +++ b/libavcodec/scpr.c @@ -656,7 +656,7 @@ static int decompress_p(AVCodecContext *avctx, if (by >= avctx->height) return AVERROR_INVALIDDATA; - clr = prev[by * linesize + bx]; + clr = prev[by * plinesize + bx]; dst[by * linesize + bx] = clr; bx++; if (bx >= x * 16 + sx2 || bx >= avctx->width) { From 807a3b30d29128773ca433dac530d440638bbbf3 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 26 Mar 2016 12:39:58 +0100 Subject: [PATCH 1119/3374] lavfi: add a QSV scaling filter This merges libav commit ac7bfd69678f3966e38debdb27f4bde94dc0345c, which was previously skipped. (cherry picked from commit ac7bfd69678f3966e38debdb27f4bde94dc0345c) Signed-off-by: Mark Thompson --- Changelog | 1 + configure | 1 + doc/libav-merge.txt | 1 - libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/version.h | 2 +- libavfilter/vf_scale_qsv.c | 635 +++++++++++++++++++++++++++++++++++++ 7 files changed, 640 insertions(+), 2 deletions(-) create mode 100644 libavfilter/vf_scale_qsv.c diff --git a/Changelog b/Changelog index 13628ca28b5d7..ac9998ec4fe62 100644 --- a/Changelog +++ b/Changelog @@ -26,6 +26,7 @@ version : - native Opus encoder - ScreenPressor decoder - incomplete ClearVideo decoder +- Intel QSV video scaling filter version 3.2: - libopenmpt demuxer diff --git a/configure b/configure index 707b98011a02d..dc18bfa43e3f8 100755 --- a/configure +++ b/configure @@ -3127,6 +3127,7 @@ rubberband_filter_deps="librubberband" sab_filter_deps="gpl swscale" scale2ref_filter_deps="swscale" scale_filter_deps="swscale" +scale_qsv_filter_deps="libmfx" select_filter_select="pixelutils" showcqt_filter_deps="avcodec avformat swscale" showcqt_filter_select="fft" diff --git a/doc/libav-merge.txt b/doc/libav-merge.txt index 39d846f8fccbf..50eb34fd7c706 100644 --- a/doc/libav-merge.txt +++ b/doc/libav-merge.txt @@ -94,7 +94,6 @@ Stuff that didn't reach the codebase: - a853388d2 hevc: change the stride of the MC buffer to be in bytes instead of elements - 0cef06df0 checkasm: add HEVC MC tests - e7078e842 hevcdsp: add x86 SIMD for MC -- QSV scaling filter (62c58c5) Collateral damage that needs work locally: ------------------------------------------ diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 0ba1c74a26586..4d1180babbec6 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -261,6 +261,7 @@ OBJS-$(CONFIG_ROTATE_FILTER) += vf_rotate.o OBJS-$(CONFIG_SAB_FILTER) += vf_sab.o OBJS-$(CONFIG_SCALE_FILTER) += vf_scale.o scale.o OBJS-$(CONFIG_SCALE_NPP_FILTER) += vf_scale_npp.o scale.o +OBJS-$(CONFIG_SCALE_QSV_FILTER) += vf_scale_qsv.o OBJS-$(CONFIG_SCALE_VAAPI_FILTER) += vf_scale_vaapi.o scale.o OBJS-$(CONFIG_SCALE2REF_FILTER) += vf_scale.o scale.o OBJS-$(CONFIG_SELECT_FILTER) += f_select.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index df1af8de232be..6aa482d910be8 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -271,6 +271,7 @@ static void register_all(void) REGISTER_FILTER(SAB, sab, vf); REGISTER_FILTER(SCALE, scale, vf); REGISTER_FILTER(SCALE_NPP, scale_npp, vf); + REGISTER_FILTER(SCALE_QSV, scale_qsv, vf); REGISTER_FILTER(SCALE_VAAPI, scale_vaapi, vf); REGISTER_FILTER(SCALE2REF, scale2ref, vf); REGISTER_FILTER(SELECT, select, vf); diff --git a/libavfilter/version.h b/libavfilter/version.h index 11db8d5513704..878711d9070e0 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 6 -#define LIBAVFILTER_VERSION_MINOR 74 +#define LIBAVFILTER_VERSION_MINOR 75 #define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vf_scale_qsv.c b/libavfilter/vf_scale_qsv.c new file mode 100644 index 0000000000000..88fca8b46128a --- /dev/null +++ b/libavfilter/vf_scale_qsv.c @@ -0,0 +1,635 @@ +/* + * 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 + */ + +/** + * @file + * scale video filter - QSV + */ + +#include + +#include +#include + +#include "libavutil/avstring.h" +#include "libavutil/common.h" +#include "libavutil/eval.h" +#include "libavutil/hwcontext.h" +#include "libavutil/hwcontext_qsv.h" +#include "libavutil/internal.h" +#include "libavutil/mathematics.h" +#include "libavutil/opt.h" +#include "libavutil/pixdesc.h" +#include "libavutil/time.h" + +#include "avfilter.h" +#include "formats.h" +#include "internal.h" +#include "video.h" + +static const char *const var_names[] = { + "PI", + "PHI", + "E", + "in_w", "iw", + "in_h", "ih", + "out_w", "ow", + "out_h", "oh", + "a", "dar", + "sar", + NULL +}; + +enum var_name { + VAR_PI, + VAR_PHI, + VAR_E, + VAR_IN_W, VAR_IW, + VAR_IN_H, VAR_IH, + VAR_OUT_W, VAR_OW, + VAR_OUT_H, VAR_OH, + VAR_A, VAR_DAR, + VAR_SAR, + VARS_NB +}; + +typedef struct QSVScaleContext { + const AVClass *class; + + AVBufferRef *out_frames_ref; + /* a clone of the main session, used internally for scaling */ + mfxSession session; + + mfxMemId *mem_ids_in; + int nb_mem_ids_in; + + mfxMemId *mem_ids_out; + int nb_mem_ids_out; + + mfxFrameSurface1 **surface_ptrs_in; + int nb_surface_ptrs_in; + + mfxFrameSurface1 **surface_ptrs_out; + int nb_surface_ptrs_out; + + mfxExtOpaqueSurfaceAlloc opaque_alloc; + mfxExtBuffer *ext_buffers[1]; + + int shift_width, shift_height; + + /** + * New dimensions. Special values are: + * 0 = original width/height + * -1 = keep original aspect + */ + int w, h; + + /** + * Output sw format. AV_PIX_FMT_NONE for no conversion. + */ + enum AVPixelFormat format; + + char *w_expr; ///< width expression string + char *h_expr; ///< height expression string + char *format_str; +} QSVScaleContext; + +static int qsvscale_init(AVFilterContext *ctx) +{ + QSVScaleContext *s = ctx->priv; + + if (!strcmp(s->format_str, "same")) { + s->format = AV_PIX_FMT_NONE; + } else { + s->format = av_get_pix_fmt(s->format_str); + if (s->format == AV_PIX_FMT_NONE) { + av_log(ctx, AV_LOG_ERROR, "Unrecognized pixel format: %s\n", s->format_str); + return AVERROR(EINVAL); + } + } + + return 0; +} + +static void qsvscale_uninit(AVFilterContext *ctx) +{ + QSVScaleContext *s = ctx->priv; + + if (s->session) { + MFXClose(s->session); + s->session = NULL; + } + av_buffer_unref(&s->out_frames_ref); + + av_freep(&s->mem_ids_in); + av_freep(&s->mem_ids_out); + s->nb_mem_ids_in = 0; + s->nb_mem_ids_out = 0; + + av_freep(&s->surface_ptrs_in); + av_freep(&s->surface_ptrs_out); + s->nb_surface_ptrs_in = 0; + s->nb_surface_ptrs_out = 0; +} + +static int qsvscale_query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pixel_formats[] = { + AV_PIX_FMT_QSV, AV_PIX_FMT_NONE, + }; + AVFilterFormats *pix_fmts = ff_make_format_list(pixel_formats); + int ret; + + if ((ret = ff_set_common_formats(ctx, pix_fmts)) < 0) + return ret; + + return 0; +} + +static int init_out_pool(AVFilterContext *ctx, + int out_width, int out_height) +{ + QSVScaleContext *s = ctx->priv; + + AVHWFramesContext *in_frames_ctx; + AVHWFramesContext *out_frames_ctx; + AVQSVFramesContext *in_frames_hwctx; + AVQSVFramesContext *out_frames_hwctx; + enum AVPixelFormat in_format; + enum AVPixelFormat out_format; + int i, ret; + + /* check that we have a hw context */ + if (!ctx->inputs[0]->hw_frames_ctx) { + av_log(ctx, AV_LOG_ERROR, "No hw context provided on input\n"); + return AVERROR(EINVAL); + } + in_frames_ctx = (AVHWFramesContext*)ctx->inputs[0]->hw_frames_ctx->data; + in_frames_hwctx = in_frames_ctx->hwctx; + + in_format = in_frames_ctx->sw_format; + out_format = (s->format == AV_PIX_FMT_NONE) ? in_format : s->format; + + s->out_frames_ref = av_hwframe_ctx_alloc(in_frames_ctx->device_ref); + if (!s->out_frames_ref) + return AVERROR(ENOMEM); + out_frames_ctx = (AVHWFramesContext*)s->out_frames_ref->data; + out_frames_hwctx = out_frames_ctx->hwctx; + + out_frames_ctx->format = AV_PIX_FMT_QSV; + out_frames_ctx->width = FFALIGN(out_width, 32); + out_frames_ctx->height = FFALIGN(out_height, 32); + out_frames_ctx->sw_format = out_format; + out_frames_ctx->initial_pool_size = 32; + + out_frames_hwctx->frame_type = in_frames_hwctx->frame_type; + + ret = av_hwframe_ctx_init(s->out_frames_ref); + if (ret < 0) + return ret; + + for (i = 0; i < out_frames_hwctx->nb_surfaces; i++) { + mfxFrameInfo *info = &out_frames_hwctx->surfaces[i].Info; + info->CropW = out_width; + info->CropH = out_height; + } + + return 0; +} + +static mfxStatus frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req, + mfxFrameAllocResponse *resp) +{ + AVFilterContext *ctx = pthis; + QSVScaleContext *s = ctx->priv; + + if (!(req->Type & MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET) || + !(req->Type & (MFX_MEMTYPE_FROM_VPPIN | MFX_MEMTYPE_FROM_VPPOUT)) || + !(req->Type & MFX_MEMTYPE_EXTERNAL_FRAME)) + return MFX_ERR_UNSUPPORTED; + + if (req->Type & MFX_MEMTYPE_FROM_VPPIN) { + resp->mids = s->mem_ids_in; + resp->NumFrameActual = s->nb_mem_ids_in; + } else { + resp->mids = s->mem_ids_out; + resp->NumFrameActual = s->nb_mem_ids_out; + } + + return MFX_ERR_NONE; +} + +static mfxStatus frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp) +{ + return MFX_ERR_NONE; +} + +static mfxStatus frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) +{ + return MFX_ERR_UNSUPPORTED; +} + +static mfxStatus frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) +{ + return MFX_ERR_UNSUPPORTED; +} + +static mfxStatus frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl) +{ + *hdl = mid; + return MFX_ERR_NONE; +} + +static const mfxHandleType handle_types[] = { + MFX_HANDLE_VA_DISPLAY, + MFX_HANDLE_D3D9_DEVICE_MANAGER, + MFX_HANDLE_D3D11_DEVICE, +}; + +static int init_out_session(AVFilterContext *ctx) +{ + + QSVScaleContext *s = ctx->priv; + AVHWFramesContext *in_frames_ctx = (AVHWFramesContext*)ctx->inputs[0]->hw_frames_ctx->data; + AVHWFramesContext *out_frames_ctx = (AVHWFramesContext*)s->out_frames_ref->data; + AVQSVFramesContext *in_frames_hwctx = in_frames_ctx->hwctx; + AVQSVFramesContext *out_frames_hwctx = out_frames_ctx->hwctx; + AVQSVDeviceContext *device_hwctx = in_frames_ctx->device_ctx->hwctx; + + int opaque = !!(in_frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME); + + mfxHDL handle = NULL; + mfxHandleType handle_type; + mfxVersion ver; + mfxIMPL impl; + mfxVideoParam par; + mfxStatus err; + int i; + + /* extract the properties of the "master" session given to us */ + err = MFXQueryIMPL(device_hwctx->session, &impl); + if (err == MFX_ERR_NONE) + err = MFXQueryVersion(device_hwctx->session, &ver); + if (err != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error querying the session attributes\n"); + return AVERROR_UNKNOWN; + } + + for (i = 0; i < FF_ARRAY_ELEMS(handle_types); i++) { + err = MFXVideoCORE_GetHandle(device_hwctx->session, handle_types[i], &handle); + if (err == MFX_ERR_NONE) { + handle_type = handle_types[i]; + break; + } + } + + /* create a "slave" session with those same properties, to be used for + * actual scaling */ + err = MFXInit(impl, &ver, &s->session); + if (err != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error initializing a session for scaling\n"); + return AVERROR_UNKNOWN; + } + + if (handle) { + err = MFXVideoCORE_SetHandle(s->session, handle_type, handle); + if (err != MFX_ERR_NONE) + return AVERROR_UNKNOWN; + } + + memset(&par, 0, sizeof(par)); + + if (opaque) { + s->surface_ptrs_in = av_mallocz_array(in_frames_hwctx->nb_surfaces, + sizeof(*s->surface_ptrs_in)); + if (!s->surface_ptrs_in) + return AVERROR(ENOMEM); + for (i = 0; i < in_frames_hwctx->nb_surfaces; i++) + s->surface_ptrs_in[i] = in_frames_hwctx->surfaces + i; + s->nb_surface_ptrs_in = in_frames_hwctx->nb_surfaces; + + s->surface_ptrs_out = av_mallocz_array(out_frames_hwctx->nb_surfaces, + sizeof(*s->surface_ptrs_out)); + if (!s->surface_ptrs_out) + return AVERROR(ENOMEM); + for (i = 0; i < out_frames_hwctx->nb_surfaces; i++) + s->surface_ptrs_out[i] = out_frames_hwctx->surfaces + i; + s->nb_surface_ptrs_out = out_frames_hwctx->nb_surfaces; + + s->opaque_alloc.In.Surfaces = s->surface_ptrs_in; + s->opaque_alloc.In.NumSurface = s->nb_surface_ptrs_in; + s->opaque_alloc.In.Type = in_frames_hwctx->frame_type; + + s->opaque_alloc.Out.Surfaces = s->surface_ptrs_out; + s->opaque_alloc.Out.NumSurface = s->nb_surface_ptrs_out; + s->opaque_alloc.Out.Type = out_frames_hwctx->frame_type; + + s->opaque_alloc.Header.BufferId = MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION; + s->opaque_alloc.Header.BufferSz = sizeof(s->opaque_alloc); + + s->ext_buffers[0] = (mfxExtBuffer*)&s->opaque_alloc; + + par.ExtParam = s->ext_buffers; + par.NumExtParam = FF_ARRAY_ELEMS(s->ext_buffers); + + par.IOPattern = MFX_IOPATTERN_IN_OPAQUE_MEMORY | MFX_IOPATTERN_OUT_OPAQUE_MEMORY; + } else { + mfxFrameAllocator frame_allocator = { + .pthis = ctx, + .Alloc = frame_alloc, + .Lock = frame_lock, + .Unlock = frame_unlock, + .GetHDL = frame_get_hdl, + .Free = frame_free, + }; + + s->mem_ids_in = av_mallocz_array(in_frames_hwctx->nb_surfaces, + sizeof(*s->mem_ids_in)); + if (!s->mem_ids_in) + return AVERROR(ENOMEM); + for (i = 0; i < in_frames_hwctx->nb_surfaces; i++) + s->mem_ids_in[i] = in_frames_hwctx->surfaces[i].Data.MemId; + s->nb_mem_ids_in = in_frames_hwctx->nb_surfaces; + + s->mem_ids_out = av_mallocz_array(out_frames_hwctx->nb_surfaces, + sizeof(*s->mem_ids_out)); + if (!s->mem_ids_out) + return AVERROR(ENOMEM); + for (i = 0; i < out_frames_hwctx->nb_surfaces; i++) + s->mem_ids_out[i] = out_frames_hwctx->surfaces[i].Data.MemId; + s->nb_mem_ids_out = out_frames_hwctx->nb_surfaces; + + err = MFXVideoCORE_SetFrameAllocator(s->session, &frame_allocator); + if (err != MFX_ERR_NONE) + return AVERROR_UNKNOWN; + + par.IOPattern = MFX_IOPATTERN_IN_VIDEO_MEMORY | MFX_IOPATTERN_OUT_VIDEO_MEMORY; + } + + par.AsyncDepth = 1; // TODO async + + par.vpp.In = in_frames_hwctx->surfaces[0].Info; + par.vpp.Out = out_frames_hwctx->surfaces[0].Info; + + /* Apparently VPP requires the frame rate to be set to some value, otherwise + * init will fail (probably for the framerate conversion filter). Since we + * are only doing scaling here, we just invent an arbitrary + * value */ + par.vpp.In.FrameRateExtN = 25; + par.vpp.In.FrameRateExtD = 1; + par.vpp.Out.FrameRateExtN = 25; + par.vpp.Out.FrameRateExtD = 1; + + err = MFXVideoVPP_Init(s->session, &par); + if (err != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error opening the VPP for scaling\n"); + return AVERROR_UNKNOWN; + } + + return 0; +} + +static int init_scale_session(AVFilterContext *ctx, int in_width, int in_height, + int out_width, int out_height) +{ + QSVScaleContext *s = ctx->priv; + + int ret; + + qsvscale_uninit(ctx); + + ret = init_out_pool(ctx, out_width, out_height); + if (ret < 0) + return ret; + + ret = init_out_session(ctx); + if (ret < 0) + return ret; + + av_buffer_unref(&ctx->outputs[0]->hw_frames_ctx); + ctx->outputs[0]->hw_frames_ctx = av_buffer_ref(s->out_frames_ref); + if (!ctx->outputs[0]->hw_frames_ctx) + return AVERROR(ENOMEM); + + return 0; +} + +static int qsvscale_config_props(AVFilterLink *outlink) +{ + AVFilterContext *ctx = outlink->src; + AVFilterLink *inlink = outlink->src->inputs[0]; + QSVScaleContext *s = ctx->priv; + int64_t w, h; + double var_values[VARS_NB], res; + char *expr; + int ret; + + var_values[VAR_PI] = M_PI; + var_values[VAR_PHI] = M_PHI; + var_values[VAR_E] = M_E; + var_values[VAR_IN_W] = var_values[VAR_IW] = inlink->w; + var_values[VAR_IN_H] = var_values[VAR_IH] = inlink->h; + var_values[VAR_OUT_W] = var_values[VAR_OW] = NAN; + var_values[VAR_OUT_H] = var_values[VAR_OH] = NAN; + var_values[VAR_A] = (double) inlink->w / inlink->h; + var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ? + (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1; + var_values[VAR_DAR] = var_values[VAR_A] * var_values[VAR_SAR]; + + /* evaluate width and height */ + av_expr_parse_and_eval(&res, (expr = s->w_expr), + var_names, var_values, + NULL, NULL, NULL, NULL, NULL, 0, ctx); + s->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res; + if ((ret = av_expr_parse_and_eval(&res, (expr = s->h_expr), + var_names, var_values, + NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) + goto fail; + s->h = var_values[VAR_OUT_H] = var_values[VAR_OH] = res; + /* evaluate again the width, as it may depend on the output height */ + if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr), + var_names, var_values, + NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) + goto fail; + s->w = res; + + w = s->w; + h = s->h; + + /* sanity check params */ + if (w < -1 || h < -1) { + av_log(ctx, AV_LOG_ERROR, "Size values less than -1 are not acceptable.\n"); + return AVERROR(EINVAL); + } + if (w == -1 && h == -1) + s->w = s->h = 0; + + if (!(w = s->w)) + w = inlink->w; + if (!(h = s->h)) + h = inlink->h; + if (w == -1) + w = av_rescale(h, inlink->w, inlink->h); + if (h == -1) + h = av_rescale(w, inlink->h, inlink->w); + + if (w > INT_MAX || h > INT_MAX || + (h * inlink->w) > INT_MAX || + (w * inlink->h) > INT_MAX) + av_log(ctx, AV_LOG_ERROR, "Rescaled value for width or height is too big.\n"); + + outlink->w = w; + outlink->h = h; + + ret = init_scale_session(ctx, inlink->w, inlink->h, w, h); + if (ret < 0) + return ret; + + av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d -> w:%d h:%d\n", + inlink->w, inlink->h, outlink->w, outlink->h); + + if (inlink->sample_aspect_ratio.num) + outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h*inlink->w, + outlink->w*inlink->h}, + inlink->sample_aspect_ratio); + else + outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; + + return 0; + +fail: + av_log(NULL, AV_LOG_ERROR, + "Error when evaluating the expression '%s'\n", expr); + return ret; +} + +static int qsvscale_filter_frame(AVFilterLink *link, AVFrame *in) +{ + AVFilterContext *ctx = link->dst; + QSVScaleContext *s = ctx->priv; + AVFilterLink *outlink = ctx->outputs[0]; + + mfxSyncPoint sync = NULL; + mfxStatus err; + + AVFrame *out = NULL; + int ret = 0; + + out = av_frame_alloc(); + if (!out) { + ret = AVERROR(ENOMEM); + goto fail; + } + + ret = av_hwframe_get_buffer(s->out_frames_ref, out, 0); + if (ret < 0) + goto fail; + + do { + err = MFXVideoVPP_RunFrameVPPAsync(s->session, + (mfxFrameSurface1*)in->data[3], + (mfxFrameSurface1*)out->data[3], + NULL, &sync); + if (err == MFX_WRN_DEVICE_BUSY) + av_usleep(1); + } while (err == MFX_WRN_DEVICE_BUSY); + + if (err < 0 || !sync) { + av_log(ctx, AV_LOG_ERROR, "Error during scaling\n"); + ret = AVERROR_UNKNOWN; + goto fail; + } + + do { + err = MFXVideoCORE_SyncOperation(s->session, sync, 1000); + } while (err == MFX_WRN_IN_EXECUTION); + if (err < 0) { + av_log(ctx, AV_LOG_ERROR, "Error synchronizing the operation: %d\n", err); + ret = AVERROR_UNKNOWN; + goto fail; + } + + ret = av_frame_copy_props(out, in); + if (ret < 0) + goto fail; + + out->width = outlink->w; + out->height = outlink->h; + + av_reduce(&out->sample_aspect_ratio.num, &out->sample_aspect_ratio.den, + (int64_t)in->sample_aspect_ratio.num * outlink->h * link->w, + (int64_t)in->sample_aspect_ratio.den * outlink->w * link->h, + INT_MAX); + + av_frame_free(&in); + return ff_filter_frame(outlink, out); +fail: + av_frame_free(&in); + av_frame_free(&out); + return ret; +} + +#define OFFSET(x) offsetof(QSVScaleContext, x) +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM +static const AVOption options[] = { + { "w", "Output video width", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str = "iw" }, .flags = FLAGS }, + { "h", "Output video height", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str = "ih" }, .flags = FLAGS }, + { "format", "Output pixel format", OFFSET(format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS }, + + { NULL }, +}; + +static const AVClass qsvscale_class = { + .class_name = "qsvscale", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +static const AVFilterPad qsvscale_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .filter_frame = qsvscale_filter_frame, + }, + { NULL } +}; + +static const AVFilterPad qsvscale_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = qsvscale_config_props, + }, + { NULL } +}; + +AVFilter ff_vf_scale_qsv = { + .name = "scale_qsv", + .description = NULL_IF_CONFIG_SMALL("QuickSync video scaling and format conversion"), + + .init = qsvscale_init, + .uninit = qsvscale_uninit, + .query_formats = qsvscale_query_formats, + + .priv_size = sizeof(QSVScaleContext), + .priv_class = &qsvscale_class, + + .inputs = qsvscale_inputs, + .outputs = qsvscale_outputs, +}; From 5dab7b91adf65eb35d4ae0e76fbd988d55b0d764 Mon Sep 17 00:00:00 2001 From: Paras Chadha Date: Sun, 12 Mar 2017 02:31:23 +0530 Subject: [PATCH 1120/3374] avcodec: add XPM decoder and demuxer Signed-off-by: Paras Chadha --- Changelog | 1 + doc/general.texi | 2 + libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/avcodec.h | 1 + libavcodec/codec_desc.c | 7 + libavcodec/version.h | 4 +- libavcodec/xpmdec.c | 425 +++++++++++++++++++++++++++++++++++++++ libavformat/Makefile | 1 + libavformat/allformats.c | 1 + libavformat/img2.c | 1 + libavformat/img2dec.c | 10 + 12 files changed, 453 insertions(+), 2 deletions(-) create mode 100644 libavcodec/xpmdec.c diff --git a/Changelog b/Changelog index 8cefcb520203f..b9d1a3cac1c64 100644 --- a/Changelog +++ b/Changelog @@ -27,6 +27,7 @@ version : - ScreenPressor decoder - incomplete ClearVideo decoder - Intel QSV video scaling and deinterlacing filters +- XPM decoder version 3.2: - libopenmpt demuxer diff --git a/doc/general.texi b/doc/general.texi index 30450c0cefa84..80eaace678789 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -609,6 +609,8 @@ following image formats are supported: @tab X BitMap image format @item XFace @tab X @tab X @tab X-Face image format +@item XPM @tab @tab X + @tab X PixMap image format @item XWD @tab X @tab X @tab X Window Dump image format @end multitable diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 65ccbade8ef29..b8d7a005ea9c7 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -650,6 +650,7 @@ OBJS-$(CONFIG_XFACE_ENCODER) += xfaceenc.o xface.o OBJS-$(CONFIG_XL_DECODER) += xl.o OBJS-$(CONFIG_XMA1_DECODER) += wmaprodec.o wma.o wma_common.o OBJS-$(CONFIG_XMA2_DECODER) += wmaprodec.o wma.o wma_common.o +OBJS-$(CONFIG_XPM_DECODER) += xpmdec.o OBJS-$(CONFIG_XSUB_DECODER) += xsubdec.o OBJS-$(CONFIG_XSUB_ENCODER) += xsubenc.o OBJS-$(CONFIG_XWD_DECODER) += xwddec.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 074efd463f6f5..b7d03ad60188d 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -378,6 +378,7 @@ static void register_all(void) REGISTER_ENCDEC (XBM, xbm); REGISTER_ENCDEC (XFACE, xface); REGISTER_DECODER(XL, xl); + REGISTER_DECODER(XPM, xpm); REGISTER_ENCDEC (XWD, xwd); REGISTER_ENCDEC (Y41P, y41p); REGISTER_DECODER(YLC, ylc); diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 30ac2360e0969..e32f57983c32e 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -439,6 +439,7 @@ enum AVCodecID { AV_CODEC_ID_FMVC, AV_CODEC_ID_SCPR, AV_CODEC_ID_CLEARVIDEO, + AV_CODEC_ID_XPM, /* various PCM "codecs" */ AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 06bcfc3cce31d..88cfddb4f359b 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -1590,6 +1590,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("XBM (X BitMap) image"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, + { + .id = AV_CODEC_ID_XPM, + .type = AVMEDIA_TYPE_VIDEO, + .name = "xpm", + .long_name = NULL_IF_CONFIG_SMALL("XPM (X PixMap) image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, { .id = AV_CODEC_ID_XWD, .type = AVMEDIA_TYPE_VIDEO, diff --git a/libavcodec/version.h b/libavcodec/version.h index b00e011959ecb..3ed5a718d4d91 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 82 -#define LIBAVCODEC_VERSION_MICRO 102 +#define LIBAVCODEC_VERSION_MINOR 83 +#define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavcodec/xpmdec.c b/libavcodec/xpmdec.c new file mode 100644 index 0000000000000..3f01a8f002ee2 --- /dev/null +++ b/libavcodec/xpmdec.c @@ -0,0 +1,425 @@ +/* + * XPM image format + * + * Copyright (c) 2012 Paul B Mahol + * Copyright (c) 2017 Paras Chadha + * + * 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 "libavutil/parseutils.h" +#include "libavutil/avstring.h" +#include "avcodec.h" +#include "internal.h" + +typedef struct XPMContext { + uint32_t *pixels; + int pixels_size; +} XPMDecContext; + +typedef struct ColorEntry { + const char *name; ///< a string representing the name of the color + uint32_t rgb_color; ///< RGB values for the color +} ColorEntry; + +static int color_table_compare(const void *lhs, const void *rhs) +{ + return av_strcasecmp(lhs, ((const ColorEntry *)rhs)->name); +} + +static const ColorEntry color_table[] = { + { "AliceBlue", 0xFFF0F8FF }, + { "AntiqueWhite", 0xFFFAEBD7 }, + { "Aqua", 0xFF00FFFF }, + { "Aquamarine", 0xFF7FFFD4 }, + { "Azure", 0xFFF0FFFF }, + { "Beige", 0xFFF5F5DC }, + { "Bisque", 0xFFFFE4C4 }, + { "Black", 0xFF000000 }, + { "BlanchedAlmond", 0xFFFFEBCD }, + { "Blue", 0xFF0000FF }, + { "BlueViolet", 0xFF8A2BE2 }, + { "Brown", 0xFFA52A2A }, + { "BurlyWood", 0xFFDEB887 }, + { "CadetBlue", 0xFF5F9EA0 }, + { "Chartreuse", 0xFF7FFF00 }, + { "Chocolate", 0xFFD2691E }, + { "Coral", 0xFFFF7F50 }, + { "CornflowerBlue", 0xFF6495ED }, + { "Cornsilk", 0xFFFFF8DC }, + { "Crimson", 0xFFDC143C }, + { "Cyan", 0xFF00FFFF }, + { "DarkBlue", 0xFF00008B }, + { "DarkCyan", 0xFF008B8B }, + { "DarkGoldenRod", 0xFFB8860B }, + { "DarkGray", 0xFFA9A9A9 }, + { "DarkGreen", 0xFF006400 }, + { "DarkKhaki", 0xFFBDB76B }, + { "DarkMagenta", 0xFF8B008B }, + { "DarkOliveGreen", 0xFF556B2F }, + { "Darkorange", 0xFFFF8C00 }, + { "DarkOrchid", 0xFF9932CC }, + { "DarkRed", 0xFF8B0000 }, + { "DarkSalmon", 0xFFE9967A }, + { "DarkSeaGreen", 0xFF8FBC8F }, + { "DarkSlateBlue", 0xFF483D8B }, + { "DarkSlateGray", 0xFF2F4F4F }, + { "DarkTurquoise", 0xFF00CED1 }, + { "DarkViolet", 0xFF9400D3 }, + { "DeepPink", 0xFFFF1493 }, + { "DeepSkyBlue", 0xFF00BFFF }, + { "DimGray", 0xFF696969 }, + { "DodgerBlue", 0xFF1E90FF }, + { "FireBrick", 0xFFB22222 }, + { "FloralWhite", 0xFFFFFAF0 }, + { "ForestGreen", 0xFF228B22 }, + { "Fuchsia", 0xFFFF00FF }, + { "Gainsboro", 0xFFDCDCDC }, + { "GhostWhite", 0xFFF8F8FF }, + { "Gold", 0xFFFFD700 }, + { "GoldenRod", 0xFFDAA520 }, + { "Gray", 0xFF808080 }, + { "Green", 0xFF008000 }, + { "GreenYellow", 0xFFADFF2F }, + { "HoneyDew", 0xFFF0FFF0 }, + { "HotPink", 0xFFFF69B4 }, + { "IndianRed", 0xFFCD5C5C }, + { "Indigo", 0xFF4B0082 }, + { "Ivory", 0xFFFFFFF0 }, + { "Khaki", 0xFFF0E68C }, + { "Lavender", 0xFFE6E6FA }, + { "LavenderBlush", 0xFFFFF0F5 }, + { "LawnGreen", 0xFF7CFC00 }, + { "LemonChiffon", 0xFFFFFACD }, + { "LightBlue", 0xFFADD8E6 }, + { "LightCoral", 0xFFF08080 }, + { "LightCyan", 0xFFE0FFFF }, + { "LightGoldenRodYellow", 0xFFFAFAD2 }, + { "LightGreen", 0xFF90EE90 }, + { "LightGrey", 0xFFD3D3D3 }, + { "LightPink", 0xFFFFB6C1 }, + { "LightSalmon", 0xFFFFA07A }, + { "LightSeaGreen", 0xFF20B2AA }, + { "LightSkyBlue", 0xFF87CEFA }, + { "LightSlateGray", 0xFF778899 }, + { "LightSteelBlue", 0xFFB0C4DE }, + { "LightYellow", 0xFFFFFFE0 }, + { "Lime", 0xFF00FF00 }, + { "LimeGreen", 0xFF32CD32 }, + { "Linen", 0xFFFAF0E6 }, + { "Magenta", 0xFFFF00FF }, + { "Maroon", 0xFF800000 }, + { "MediumAquaMarine", 0xFF66CDAA }, + { "MediumBlue", 0xFF0000CD }, + { "MediumOrchid", 0xFFBA55D3 }, + { "MediumPurple", 0xFF9370D8 }, + { "MediumSeaGreen", 0xFF3CB371 }, + { "MediumSlateBlue", 0xFF7B68EE }, + { "MediumSpringGreen", 0xFF00FA9A }, + { "MediumTurquoise", 0xFF48D1CC }, + { "MediumVioletRed", 0xFFC71585 }, + { "MidnightBlue", 0xFF191970 }, + { "MintCream", 0xFFF5FFFA }, + { "MistyRose", 0xFFFFE4E1 }, + { "Moccasin", 0xFFFFE4B5 }, + { "NavajoWhite", 0xFFFFDEAD }, + { "Navy", 0xFF000080 }, + { "None", 0x00000000 }, + { "OldLace", 0xFFFDF5E6 }, + { "Olive", 0xFF808000 }, + { "OliveDrab", 0xFF6B8E23 }, + { "Orange", 0xFFFFA500 }, + { "OrangeRed", 0xFFFF4500 }, + { "Orchid", 0xFFDA70D6 }, + { "PaleGoldenRod", 0xFFEEE8AA }, + { "PaleGreen", 0xFF98FB98 }, + { "PaleTurquoise", 0xFFAFEEEE }, + { "PaleVioletRed", 0xFFD87093 }, + { "PapayaWhip", 0xFFFFEFD5 }, + { "PeachPuff", 0xFFFFDAB9 }, + { "Peru", 0xFFCD853F }, + { "Pink", 0xFFFFC0CB }, + { "Plum", 0xFFDDA0DD }, + { "PowderBlue", 0xFFB0E0E6 }, + { "Purple", 0xFF800080 }, + { "Red", 0xFFFF0000 }, + { "RosyBrown", 0xFFBC8F8F }, + { "RoyalBlue", 0xFF4169E1 }, + { "SaddleBrown", 0xFF8B4513 }, + { "Salmon", 0xFFFA8072 }, + { "SandyBrown", 0xFFF4A460 }, + { "SeaGreen", 0xFF2E8B57 }, + { "SeaShell", 0xFFFFF5EE }, + { "Sienna", 0xFFA0522D }, + { "Silver", 0xFFC0C0C0 }, + { "SkyBlue", 0xFF87CEEB }, + { "SlateBlue", 0xFF6A5ACD }, + { "SlateGray", 0xFF708090 }, + { "Snow", 0xFFFFFAFA }, + { "SpringGreen", 0xFF00FF7F }, + { "SteelBlue", 0xFF4682B4 }, + { "Tan", 0xFFD2B48C }, + { "Teal", 0xFF008080 }, + { "Thistle", 0xFFD8BFD8 }, + { "Tomato", 0xFFFF6347 }, + { "Turquoise", 0xFF40E0D0 }, + { "Violet", 0xFFEE82EE }, + { "Wheat", 0xFFF5DEB3 }, + { "White", 0xFFFFFFFF }, + { "WhiteSmoke", 0xFFF5F5F5 }, + { "Yellow", 0xFFFFFF00 }, + { "YellowGreen", 0xFF9ACD32 } +}; + +static int convert(uint8_t x) +{ + if (x >= 'a') { + x -= 87; + } else if (x >= 'A') { + x -= 55; + } else { + x -= '0'; + } + return x; +} + +/* +** functions same as strcspn but ignores characters in reject if they are inside a C style comment... +** @param string, reject - same as that of strcspn +** @return length till any character in reject does not occur in string +*/ +static size_t mod_strcspn(const char *string, const char *reject) +{ + int i, j; + + for (i = 0; string && string[i]; i++) { + if (string[i] == '/' && string[i+1] == '*') { + i += 2; + while ( string && string[i] && (string[i] != '*' || string[i+1] != '/') ) + i++; + i++; + } else if (string[i] == '/' && string[i+1] == '/') { + i += 2; + while ( string && string[i] && string[i] != '\n' ) + i++; + } else { + for (j = 0; reject && reject[j]; j++) { + if (string[i] == reject[j]) + break; + } + if (reject && reject[j]) + break; + } + } + return i; +} + +static uint32_t hexstring_to_rgba(const char *p, int len) +{ + uint32_t ret = 0xFF000000; + const ColorEntry *entry; + char color_name[100]; + + if (*p == '#') { + p++; + len--; + if (len == 3) { + ret |= (convert(p[2]) << 4) | + (convert(p[1]) << 12) | + (convert(p[0]) << 20); + } else if (len == 4) { + ret = (convert(p[3]) << 4) | + (convert(p[2]) << 12) | + (convert(p[1]) << 20) | + (convert(p[0]) << 28); + } else if (len == 6) { + ret |= convert(p[5]) | + (convert(p[4]) << 4) | + (convert(p[3]) << 8) | + (convert(p[2]) << 12) | + (convert(p[1]) << 16) | + (convert(p[0]) << 20); + } else if (len == 8) { + ret = convert(p[7]) | + (convert(p[6]) << 4) | + (convert(p[5]) << 8) | + (convert(p[4]) << 12) | + (convert(p[3]) << 16) | + (convert(p[2]) << 20) | + (convert(p[1]) << 24) | + (convert(p[0]) << 28); + } + } else { + strncpy(color_name, p, len); + color_name[len] = '\0'; + + entry = bsearch(color_name, + color_table, + FF_ARRAY_ELEMS(color_table), + sizeof(ColorEntry), + color_table_compare); + + if (!entry) + return ret; + + ret = entry->rgb_color; + } + return ret; +} + +static int ascii2index(const uint8_t *cpixel, int cpp) +{ + const uint8_t *p = cpixel; + int n = 0, m = 1, i; + + for (i = 0; i < cpp; i++) { + if (*p < ' ' || *p > '~') + return AVERROR_INVALIDDATA; + n += (*p++ - ' ') * m; + m *= 95; + } + return n; +} + +static int xpm_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame, AVPacket *avpkt) +{ + XPMDecContext *x = avctx->priv_data; + AVFrame *p=data; + const uint8_t *end, *ptr = avpkt->data; + int ncolors, cpp, ret, i, j; + int64_t size; + uint32_t *dst; + + avctx->pix_fmt = AV_PIX_FMT_BGRA; + + end = avpkt->data + avpkt->size; + if (memcmp(ptr, "/* XPM */", 9)) { + av_log(avctx, AV_LOG_ERROR, "missing signature\n"); + return AVERROR_INVALIDDATA; + } + + ptr += mod_strcspn(ptr, "\""); + if (sscanf(ptr, "\"%u %u %u %u\",", + &avctx->width, &avctx->height, &ncolors, &cpp) != 4) { + av_log(avctx, AV_LOG_ERROR, "missing image parameters\n"); + return AVERROR_INVALIDDATA; + } + + if ((ret = ff_set_dimensions(avctx, avctx->width, avctx->height)) < 0) + return ret; + + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) + return ret; + + if (ncolors <= 0) { + av_log(avctx, AV_LOG_ERROR, "invalid number of colors: %d\n", ncolors); + return AVERROR_INVALIDDATA; + } + + if (cpp <= 0) { + av_log(avctx, AV_LOG_ERROR, "invalid number of chars per pixel: %d\n", cpp); + return AVERROR_INVALIDDATA; + } + + size = 1; + j = 1; + for (i = 0; i < cpp; i++) { + size += j * 94; + j *= 95; + } + size *= 4; + + if (size < 0) { + av_log(avctx, AV_LOG_ERROR, "unsupported number of chars per pixel: %d\n", cpp); + return AVERROR(ENOMEM); + } + + av_fast_padded_malloc(&x->pixels, &x->pixels_size, size); + if (!x->pixels) + return AVERROR(ENOMEM); + + ptr += mod_strcspn(ptr, ",") + 1; + for (i = 0; i < ncolors; i++) { + const uint8_t *index; + int len; + + ptr += mod_strcspn(ptr, "\"") + 1; + if (ptr + cpp > end) + return AVERROR_INVALIDDATA; + index = ptr; + ptr += cpp; + + ptr = strstr(ptr, "c "); + if (ptr) { + ptr += 2; + } else { + return AVERROR_INVALIDDATA; + } + + len = strcspn(ptr, "\" "); + + if ((ret = ascii2index(index, cpp)) < 0) + return ret; + + x->pixels[ret] = hexstring_to_rgba(ptr, len); + ptr += mod_strcspn(ptr, ",") + 1; + } + + for (i = 0; i < avctx->height; i++) { + dst = (uint32_t *)(p->data[0] + i * p->linesize[0]); + ptr += mod_strcspn(ptr, "\"") + 1; + + for (j = 0; j < avctx->width; j++) { + if (ptr + cpp > end) + return AVERROR_INVALIDDATA; + + if ((ret = ascii2index(ptr, cpp)) < 0) + return ret; + + *dst++ = x->pixels[ret]; + ptr += cpp; + } + ptr += mod_strcspn(ptr, ",") + 1; + } + + p->key_frame = 1; + p->pict_type = AV_PICTURE_TYPE_I; + + *got_frame = 1; + + return avpkt->size; +} + +static av_cold int xpm_decode_close(AVCodecContext *avctx) +{ + XPMDecContext *x = avctx->priv_data; + av_freep(&x->pixels); + + return 0; +} + +AVCodec ff_xpm_decoder = { + .name = "xpm", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_XPM, + .priv_data_size = sizeof(XPMDecContext), + .close = xpm_decode_close, + .decode = xpm_decode_frame, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("XPM (X PixMap) image") +}; diff --git a/libavformat/Makefile b/libavformat/Makefile index fc2d76067b344..f56ef165322f4 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -241,6 +241,7 @@ OBJS-$(CONFIG_IMAGE_SGI_PIPE_DEMUXER) += img2dec.o img2.o OBJS-$(CONFIG_IMAGE_SUNRAST_PIPE_DEMUXER) += img2dec.o img2.o OBJS-$(CONFIG_IMAGE_TIFF_PIPE_DEMUXER) += img2dec.o img2.o OBJS-$(CONFIG_IMAGE_WEBP_PIPE_DEMUXER) += img2dec.o img2.o +OBJS-$(CONFIG_IMAGE_XPM_PIPE_DEMUXER) += img2dec.o img2.o OBJS-$(CONFIG_INGENIENT_DEMUXER) += ingenientdec.o rawdec.o OBJS-$(CONFIG_IPMOVIE_DEMUXER) += ipmovie.o OBJS-$(CONFIG_IRCAM_DEMUXER) += ircamdec.o ircam.o pcm.o diff --git a/libavformat/allformats.c b/libavformat/allformats.c index 132e58b8b9351..09e62c3cfc994 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -372,6 +372,7 @@ static void register_all(void) REGISTER_DEMUXER (IMAGE_SUNRAST_PIPE, image_sunrast_pipe); REGISTER_DEMUXER (IMAGE_TIFF_PIPE, image_tiff_pipe); REGISTER_DEMUXER (IMAGE_WEBP_PIPE, image_webp_pipe); + REGISTER_DEMUXER (IMAGE_XPM_PIPE, image_xpm_pipe); /* external libraries */ REGISTER_MUXER (CHROMAPRINT, chromaprint); diff --git a/libavformat/img2.c b/libavformat/img2.c index f9f53ff558def..29df4f04e2744 100644 --- a/libavformat/img2.c +++ b/libavformat/img2.c @@ -75,6 +75,7 @@ const IdStrMap ff_img_tags[] = { { AV_CODEC_ID_V210X, "yuv10" }, { AV_CODEC_ID_WEBP, "webp" }, { AV_CODEC_ID_XBM, "xbm" }, + { AV_CODEC_ID_XPM, "xpm" }, { AV_CODEC_ID_XFACE, "xface" }, { AV_CODEC_ID_XWD, "xwd" }, { AV_CODEC_ID_NONE, NULL } diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c index c3c2cf3640bb6..b454071168714 100644 --- a/libavformat/img2dec.c +++ b/libavformat/img2dec.c @@ -943,6 +943,15 @@ static int pam_probe(AVProbeData *p) return pnm_magic_check(p, 7) ? pnm_probe(p) : 0; } +static int xpm_probe(AVProbeData *p) +{ + const uint8_t *b = p->buf; + + if (AV_RB64(b) == 0x2f2a2058504d202a && *(b+8) == '/') + return AVPROBE_SCORE_MAX - 1; + return 0; +} + #define IMAGEAUTO_DEMUXER(imgname, codecid)\ static const AVClass imgname ## _class = {\ .class_name = AV_STRINGIFY(imgname) " demuxer",\ @@ -983,3 +992,4 @@ IMAGEAUTO_DEMUXER(sgi, AV_CODEC_ID_SGI) IMAGEAUTO_DEMUXER(sunrast, AV_CODEC_ID_SUNRAST) IMAGEAUTO_DEMUXER(tiff, AV_CODEC_ID_TIFF) IMAGEAUTO_DEMUXER(webp, AV_CODEC_ID_WEBP) +IMAGEAUTO_DEMUXER(xpm, AV_CODEC_ID_XPM) From eda78c8b7f8a0e4728344f97700960f022eee6d2 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 12 Mar 2017 12:48:01 +0100 Subject: [PATCH 1121/3374] avcodec/xpmdec: make convert function more picky about its input Signed-off-by: Paul B Mahol --- libavcodec/xpmdec.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libavcodec/xpmdec.c b/libavcodec/xpmdec.c index 3f01a8f002ee2..8d5bc76ab2860 100644 --- a/libavcodec/xpmdec.c +++ b/libavcodec/xpmdec.c @@ -185,15 +185,16 @@ static const ColorEntry color_table[] = { { "YellowGreen", 0xFF9ACD32 } }; -static int convert(uint8_t x) +static unsigned convert(uint8_t x) { - if (x >= 'a') { + if (x >= 'a' && x <= 'f') x -= 87; - } else if (x >= 'A') { + else if (x >= 'A' && x <= 'F') x -= 55; - } else { + else if (x >= '0' && x <= '9') x -= '0'; - } + else + x = 0; return x; } From 404d2b977fde6018affef80255f2f0578be5dace Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 12 Mar 2017 14:49:26 +0100 Subject: [PATCH 1122/3374] avcodec/codec_desc: add mime type for X-PixMap Signed-off-by: Paul B Mahol --- libavcodec/codec_desc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 88cfddb4f359b..75a69c501fcaf 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -1596,6 +1596,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .name = "xpm", .long_name = NULL_IF_CONFIG_SMALL("XPM (X PixMap) image"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + .mime_types= MT("image/x-xpixmap"), }, { .id = AV_CODEC_ID_XWD, From 01b069c1b81f68373f4401a611f1b8a4ad552895 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 12 Mar 2017 14:50:33 +0100 Subject: [PATCH 1123/3374] avcodec/codec_desc: add mime type for X-BitMap Signed-off-by: Paul B Mahol --- libavcodec/codec_desc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 75a69c501fcaf..c0418e4880f57 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -1589,6 +1589,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .name = "xbm", .long_name = NULL_IF_CONFIG_SMALL("XBM (X BitMap) image"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + .mime_types= MT("image/x-xbitmap"), }, { .id = AV_CODEC_ID_XPM, From e73325b971b37dd4741c49541c74cde0739dab8c Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 12 Mar 2017 15:07:02 +0100 Subject: [PATCH 1124/3374] avcodec/xpmdec: skip everything before signature Signed-off-by: Paul B Mahol --- libavcodec/xpmdec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/xpmdec.c b/libavcodec/xpmdec.c index 8d5bc76ab2860..6cd7bde4ec729 100644 --- a/libavcodec/xpmdec.c +++ b/libavcodec/xpmdec.c @@ -309,7 +309,10 @@ static int xpm_decode_frame(AVCodecContext *avctx, void *data, avctx->pix_fmt = AV_PIX_FMT_BGRA; end = avpkt->data + avpkt->size; - if (memcmp(ptr, "/* XPM */", 9)) { + while (memcmp(ptr, "/* XPM */\n", 10) && ptr < end - 10) + ptr++; + + if (ptr >= end) { av_log(avctx, AV_LOG_ERROR, "missing signature\n"); return AVERROR_INVALIDDATA; } From 88deeb3eba00271e9fb82177860c743fc564e8c0 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 11 Mar 2017 20:24:53 -0300 Subject: [PATCH 1125/3374] tests/api-seek: make the crc array uint32_t Reviewed-by: Michael Niedermayer Signed-off-by: James Almer --- tests/api/api-seek-test.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tests/api/api-seek-test.c b/tests/api/api-seek-test.c index cc3287b28f9e1..6ef3b91933b79 100644 --- a/tests/api/api-seek-test.c +++ b/tests/api/api-seek-test.c @@ -30,17 +30,17 @@ #include "libavutil/imgutils.h" int64_t *pts_array; -int64_t *crc_array; +uint32_t *crc_array; int size_of_array; int number_of_elements; -static int add_crc_to_array(int64_t crc, int64_t pts) +static int add_crc_to_array(uint32_t crc, int64_t pts) { if (size_of_array <= number_of_elements) { if (size_of_array == 0) size_of_array = 10; size_of_array *= 2; - crc_array = av_realloc(crc_array, size_of_array * sizeof(int64_t)); + crc_array = av_realloc(crc_array, size_of_array * sizeof(uint32_t)); pts_array = av_realloc(pts_array, size_of_array * sizeof(int64_t)); if ((crc_array == NULL) || (pts_array == NULL)) { av_log(NULL, AV_LOG_ERROR, "Can't allocate array to store crcs\n"); @@ -53,13 +53,13 @@ static int add_crc_to_array(int64_t crc, int64_t pts) return 0; } -static int compare_crc_in_array(int64_t crc, int64_t pts) +static int compare_crc_in_array(uint32_t crc, int64_t pts) { int i; for (i = 0; i < number_of_elements; i++) { if (pts_array[i] == pts) { if (crc_array[i] == crc) { - printf("Comparing 0x%08lx %"PRId64" %d is OK\n", crc, pts, i); + printf("Comparing 0x%08"PRIx32" %"PRId64" %d is OK\n", crc, pts, i); return 0; } else { @@ -81,7 +81,7 @@ static int compute_crc_of_packets(AVFormatContext *fmt_ctx, int video_stream, int end_of_stream = 0; int byte_buffer_size; uint8_t *byte_buffer; - int64_t crc; + uint32_t crc; AVPacket pkt; byte_buffer_size = av_image_get_buffer_size(ctx->pix_fmt, ctx->width, ctx->height, 16); @@ -132,7 +132,7 @@ static int compute_crc_of_packets(AVFormatContext *fmt_ctx, int video_stream, if ((!no_seeking) && (fr->pts > ts_end)) break; crc = av_adler32_update(0, (const uint8_t*)byte_buffer, number_of_written_bytes); - printf("%10"PRId64", 0x%08lx\n", fr->pts, crc); + printf("%10"PRId64", 0x%08"PRIx32"\n", fr->pts, crc); if (no_seeking) { if (add_crc_to_array(crc, fr->pts) < 0) return -1; @@ -185,7 +185,8 @@ static int seek_test(const char *input_filename, const char *start, const char * size_of_array = 0; number_of_elements = 0; - crc_array = pts_array = NULL; + crc_array = NULL; + pts_array = NULL; result = avformat_open_input(&fmt_ctx, input_filename, NULL, NULL); if (result < 0) { From bdd07d7796e939e920842eb7280e1bce488fb95d Mon Sep 17 00:00:00 2001 From: James Almer Date: Sun, 12 Mar 2017 10:36:44 -0300 Subject: [PATCH 1126/3374] test/api-seek: clean up properly on failure Also propagate better error values. Reviewed-by: Michael Niedermayer Signed-off-by: James Almer --- tests/api/api-seek-test.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/tests/api/api-seek-test.c b/tests/api/api-seek-test.c index 6ef3b91933b79..e4276eb9c8330 100644 --- a/tests/api/api-seek-test.c +++ b/tests/api/api-seek-test.c @@ -197,19 +197,22 @@ static int seek_test(const char *input_filename, const char *start, const char * result = avformat_find_stream_info(fmt_ctx, NULL); if (result < 0) { av_log(NULL, AV_LOG_ERROR, "Can't get stream info\n"); - return result; + goto end; } start_ts = read_seek_range(start); end_ts = read_seek_range(end); - if ((start_ts < 0) || (end_ts < 0)) - return -1; + if ((start_ts < 0) || (end_ts < 0)) { + result = -1; + goto end; + } //TODO: add ability to work with audio format video_stream = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0); if (video_stream < 0) { av_log(NULL, AV_LOG_ERROR, "Can't find video stream in input file\n"); - return -1; + result = video_stream; + goto end; } origin_par = fmt_ctx->streams[video_stream]->codecpar; @@ -217,52 +220,56 @@ static int seek_test(const char *input_filename, const char *start, const char * codec = avcodec_find_decoder(origin_par->codec_id); if (!codec) { av_log(NULL, AV_LOG_ERROR, "Can't find decoder\n"); - return -1; + result = AVERROR_DECODER_NOT_FOUND; + goto end; } ctx = avcodec_alloc_context3(codec); if (!ctx) { av_log(NULL, AV_LOG_ERROR, "Can't allocate decoder context\n"); - return AVERROR(ENOMEM); + result = AVERROR(ENOMEM); + goto end; } result = avcodec_parameters_to_context(ctx, origin_par); if (result) { av_log(NULL, AV_LOG_ERROR, "Can't copy decoder context\n"); - return result; + goto end; } result = avcodec_open2(ctx, codec, NULL); if (result < 0) { av_log(ctx, AV_LOG_ERROR, "Can't open decoder\n"); - return result; + goto end; } fr = av_frame_alloc(); if (!fr) { av_log(NULL, AV_LOG_ERROR, "Can't allocate frame\n"); - return AVERROR(ENOMEM); + result = AVERROR(ENOMEM); + goto end; } result = compute_crc_of_packets(fmt_ctx, video_stream, ctx, fr, 0, 0, 1); if (result != 0) - return -1; + goto end; for (i = start_ts; i < end_ts; i += 100) { for (j = i + 100; j < end_ts; j += 100) { result = compute_crc_of_packets(fmt_ctx, video_stream, ctx, fr, i, j, 0); if (result != 0) - return -1; + break; } } +end: av_freep(&crc_array); av_freep(&pts_array); av_frame_free(&fr); avcodec_close(ctx); avformat_close_input(&fmt_ctx); avcodec_free_context(&ctx); - return 0; + return result; } int main(int argc, char **argv) From ff17c76e92cd9a9072a8771cad73c96cd620040b Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 11 Mar 2017 20:29:40 -0300 Subject: [PATCH 1127/3374] tests/api-seek: fix memory leak on realloc() failure Reviewed-by: Michael Niedermayer Signed-off-by: James Almer --- tests/api/api-seek-test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/api/api-seek-test.c b/tests/api/api-seek-test.c index e4276eb9c8330..4fd1e6ea04561 100644 --- a/tests/api/api-seek-test.c +++ b/tests/api/api-seek-test.c @@ -40,8 +40,8 @@ static int add_crc_to_array(uint32_t crc, int64_t pts) if (size_of_array == 0) size_of_array = 10; size_of_array *= 2; - crc_array = av_realloc(crc_array, size_of_array * sizeof(uint32_t)); - pts_array = av_realloc(pts_array, size_of_array * sizeof(int64_t)); + crc_array = av_realloc_f(crc_array, size_of_array, sizeof(uint32_t)); + pts_array = av_realloc_f(pts_array, size_of_array, sizeof(int64_t)); if ((crc_array == NULL) || (pts_array == NULL)) { av_log(NULL, AV_LOG_ERROR, "Can't allocate array to store crcs\n"); return AVERROR(ENOMEM); From bf238a6a3ca92de686e0e103135c1336f33f685b Mon Sep 17 00:00:00 2001 From: Jun Zhao Date: Fri, 3 Mar 2017 09:25:53 +0800 Subject: [PATCH 1128/3374] vf_hwupload: Add missing return value check Add missing return value checks to suppress build warning and remove noop ff_formats_unref() calling. Note: most filters using ff_formats_ref() didn't have a suitable error handling, it's a potential memory leak issue. Signed-off-by: Jun Zhao Signed-off-by: Mark Thompson --- libavfilter/vf_hwupload.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/libavfilter/vf_hwupload.c b/libavfilter/vf_hwupload.c index 08af2dd49fe6a..f54ce9faa760a 100644 --- a/libavfilter/vf_hwupload.c +++ b/libavfilter/vf_hwupload.c @@ -74,17 +74,15 @@ static int hwupload_query_formats(AVFilterContext *avctx) if (input_pix_fmts) { for (i = 0; input_pix_fmts[i] != AV_PIX_FMT_NONE; i++) { err = ff_add_format(&input_formats, input_pix_fmts[i]); - if (err < 0) { - ff_formats_unref(&input_formats); + if (err < 0) goto fail; - } } } - ff_formats_ref(input_formats, &avctx->inputs[0]->out_formats); - - ff_formats_ref(ff_make_format_list(output_pix_fmts), - &avctx->outputs[0]->in_formats); + if ((err = ff_formats_ref(input_formats, &avctx->inputs[0]->out_formats)) < 0 || + (err = ff_formats_ref(ff_make_format_list(output_pix_fmts), + &avctx->outputs[0]->in_formats)) < 0) + goto fail; av_hwframe_constraints_free(&constraints); return 0; From 6c7a0876fefdd3c919afcabf493492cb4946ca6a Mon Sep 17 00:00:00 2001 From: Muhammad Faiz Date: Sun, 12 Mar 2017 00:24:21 +0700 Subject: [PATCH 1129/3374] swresample/swresample: do not reset tsf on swr_alloc_set_opts so tsf option in aresample will have effect previously tsf/internal_sample_format had no effect fate is updated s32p previously used fltp internally dblp previously used fltp/dblp internally Reviewed-by: Michael Niedermayer Signed-off-by: Muhammad Faiz --- libswresample/swresample.c | 3 -- tests/fate/libswresample.mak | 80 ++++++++++++++++++------------------ 2 files changed, 40 insertions(+), 43 deletions(-) diff --git a/libswresample/swresample.c b/libswresample/swresample.c index dea61391ac036..f2e66005eb076 100644 --- a/libswresample/swresample.c +++ b/libswresample/swresample.c @@ -84,9 +84,6 @@ struct SwrContext *swr_alloc_set_opts(struct SwrContext *s, if (av_opt_set_int(s, "isr", in_sample_rate, 0) < 0) goto fail; - if (av_opt_set_int(s, "tsf", AV_SAMPLE_FMT_NONE, 0) < 0) - goto fail; - if (av_opt_set_int(s, "ich", av_get_channel_layout_nb_channels(s-> user_in_ch_layout), 0) < 0) goto fail; diff --git a/tests/fate/libswresample.mak b/tests/fate/libswresample.mak index 78dbde74083f9..d9e0fa9c03143 100644 --- a/tests/fate/libswresample.mak +++ b/tests/fate/libswresample.mak @@ -218,28 +218,28 @@ fate-swr-resample-s32p-2626-8000: SIZE_TOLERANCE = 31512 - 20482 fate-swr-resample-s32p-2626-96000: CMP_TARGET = 1393.00 fate-swr-resample-s32p-2626-96000: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample-s32p-44100-2626: CMP_TARGET = 185.82 +fate-swr-resample-s32p-44100-2626: CMP_TARGET = 185.81 fate-swr-resample-s32p-44100-2626: SIZE_TOLERANCE = 529200 - 20490 -fate-swr-resample-s32p-44100-48000: CMP_TARGET = 9.69 +fate-swr-resample-s32p-44100-48000: CMP_TARGET = 9.70 fate-swr-resample-s32p-44100-48000: SIZE_TOLERANCE = 529200 - 20482 fate-swr-resample-s32p-44100-8000: CMP_TARGET = 75.45 fate-swr-resample-s32p-44100-8000: SIZE_TOLERANCE = 529200 - 20486 -fate-swr-resample-s32p-44100-96000: CMP_TARGET = 11.46 +fate-swr-resample-s32p-44100-96000: CMP_TARGET = 11.47 fate-swr-resample-s32p-44100-96000: SIZE_TOLERANCE = 529200 - 20482 -fate-swr-resample-s32p-48000-2626: CMP_TARGET = 456.51 +fate-swr-resample-s32p-48000-2626: CMP_TARGET = 456.49 fate-swr-resample-s32p-48000-2626: SIZE_TOLERANCE = 576000 - 20510 -fate-swr-resample-s32p-48000-44100: CMP_TARGET = 1.00 +fate-swr-resample-s32p-48000-44100: CMP_TARGET = 1.12 fate-swr-resample-s32p-48000-44100: SIZE_TOLERANCE = 576000 - 20480 -fate-swr-resample-s32p-48000-8000: CMP_TARGET = 62.38 +fate-swr-resample-s32p-48000-8000: CMP_TARGET = 62.37 fate-swr-resample-s32p-48000-8000: SIZE_TOLERANCE = 576000 - 20484 -fate-swr-resample-s32p-48000-96000: CMP_TARGET = 0.47 +fate-swr-resample-s32p-48000-96000: CMP_TARGET = 0.85 fate-swr-resample-s32p-48000-96000: SIZE_TOLERANCE = 576000 - 20480 fate-swr-resample-s32p-8000-2626: CMP_TARGET = 2503.33 @@ -248,22 +248,22 @@ fate-swr-resample-s32p-8000-2626: SIZE_TOLERANCE = 96000 - 20486 fate-swr-resample-s32p-8000-44100: CMP_TARGET = 15.09 fate-swr-resample-s32p-8000-44100: SIZE_TOLERANCE = 96000 - 20480 -fate-swr-resample-s32p-8000-48000: CMP_TARGET = 14.69 +fate-swr-resample-s32p-8000-48000: CMP_TARGET = 14.68 fate-swr-resample-s32p-8000-48000: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample-s32p-8000-96000: CMP_TARGET = 13.81 fate-swr-resample-s32p-8000-96000: SIZE_TOLERANCE = 96000 - 20480 -fate-swr-resample-s32p-96000-2626: CMP_TARGET = 675.07 +fate-swr-resample-s32p-96000-2626: CMP_TARGET = 675.05 fate-swr-resample-s32p-96000-2626: SIZE_TOLERANCE = 1152000 - 20474 -fate-swr-resample-s32p-96000-44100: CMP_TARGET = 1.44 +fate-swr-resample-s32p-96000-44100: CMP_TARGET = 1.54 fate-swr-resample-s32p-96000-44100: SIZE_TOLERANCE = 1152000 - 20480 -fate-swr-resample-s32p-96000-48000: CMP_TARGET = 0.99 +fate-swr-resample-s32p-96000-48000: CMP_TARGET = 1.21 fate-swr-resample-s32p-96000-48000: SIZE_TOLERANCE = 1152000 - 20480 -fate-swr-resample-s32p-96000-8000: CMP_TARGET = 58.57 +fate-swr-resample-s32p-96000-8000: CMP_TARGET = 58.59 fate-swr-resample-s32p-96000-8000: SIZE_TOLERANCE = 1152000 - 20496 @@ -440,7 +440,7 @@ fate-swr-resample_exact-dblp-8000-96000: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample_exact-dblp-96000-2626: CMP_TARGET = 675.07 fate-swr-resample_exact-dblp-96000-2626: SIZE_TOLERANCE = 1152000 - 20474 -fate-swr-resample_exact-dblp-96000-44100: CMP_TARGET = 1.23 +fate-swr-resample_exact-dblp-96000-44100: CMP_TARGET = 1.24 fate-swr-resample_exact-dblp-96000-44100: SIZE_TOLERANCE = 1152000 - 20480 fate-swr-resample_exact-dblp-96000-48000: CMP_TARGET = 0.99 @@ -581,52 +581,52 @@ fate-swr-resample_exact-s32p-2626-8000: SIZE_TOLERANCE = 31512 - 20482 fate-swr-resample_exact-s32p-2626-96000: CMP_TARGET = 1393.00 fate-swr-resample_exact-s32p-2626-96000: SIZE_TOLERANCE = 31512 - 20480 -fate-swr-resample_exact-s32p-44100-2626: CMP_TARGET = 185.82 +fate-swr-resample_exact-s32p-44100-2626: CMP_TARGET = 185.81 fate-swr-resample_exact-s32p-44100-2626: SIZE_TOLERANCE = 529200 - 20490 -fate-swr-resample_exact-s32p-44100-48000: CMP_TARGET = 9.64 +fate-swr-resample_exact-s32p-44100-48000: CMP_TARGET = 9.66 fate-swr-resample_exact-s32p-44100-48000: SIZE_TOLERANCE = 529200 - 20482 -fate-swr-resample_exact-s32p-44100-8000: CMP_TARGET = 75.38 +fate-swr-resample_exact-s32p-44100-8000: CMP_TARGET = 75.37 fate-swr-resample_exact-s32p-44100-8000: SIZE_TOLERANCE = 529200 - 20486 -fate-swr-resample_exact-s32p-44100-96000: CMP_TARGET = 11.45 +fate-swr-resample_exact-s32p-44100-96000: CMP_TARGET = 11.46 fate-swr-resample_exact-s32p-44100-96000: SIZE_TOLERANCE = 529200 - 20482 -fate-swr-resample_exact-s32p-48000-2626: CMP_TARGET = 456.51 +fate-swr-resample_exact-s32p-48000-2626: CMP_TARGET = 456.49 fate-swr-resample_exact-s32p-48000-2626: SIZE_TOLERANCE = 576000 - 20510 -fate-swr-resample_exact-s32p-48000-44100: CMP_TARGET = 0.23 +fate-swr-resample_exact-s32p-48000-44100: CMP_TARGET = 0.74 fate-swr-resample_exact-s32p-48000-44100: SIZE_TOLERANCE = 576000 - 20480 -fate-swr-resample_exact-s32p-48000-8000: CMP_TARGET = 62.36 +fate-swr-resample_exact-s32p-48000-8000: CMP_TARGET = 62.35 fate-swr-resample_exact-s32p-48000-8000: SIZE_TOLERANCE = 576000 - 20484 -fate-swr-resample_exact-s32p-48000-96000: CMP_TARGET = 0.47 +fate-swr-resample_exact-s32p-48000-96000: CMP_TARGET = 0.85 fate-swr-resample_exact-s32p-48000-96000: SIZE_TOLERANCE = 576000 - 20480 fate-swr-resample_exact-s32p-8000-2626: CMP_TARGET = 2503.33 fate-swr-resample_exact-s32p-8000-2626: SIZE_TOLERANCE = 96000 - 20486 -fate-swr-resample_exact-s32p-8000-44100: CMP_TARGET = 14.59 +fate-swr-resample_exact-s32p-8000-44100: CMP_TARGET = 14.61 fate-swr-resample_exact-s32p-8000-44100: SIZE_TOLERANCE = 96000 - 20480 -fate-swr-resample_exact-s32p-8000-48000: CMP_TARGET = 14.50 +fate-swr-resample_exact-s32p-8000-48000: CMP_TARGET = 14.52 fate-swr-resample_exact-s32p-8000-48000: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample_exact-s32p-8000-96000: CMP_TARGET = 13.62 fate-swr-resample_exact-s32p-8000-96000: SIZE_TOLERANCE = 96000 - 20480 -fate-swr-resample_exact-s32p-96000-2626: CMP_TARGET = 675.07 +fate-swr-resample_exact-s32p-96000-2626: CMP_TARGET = 675.05 fate-swr-resample_exact-s32p-96000-2626: SIZE_TOLERANCE = 1152000 - 20474 -fate-swr-resample_exact-s32p-96000-44100: CMP_TARGET = 1.23 +fate-swr-resample_exact-s32p-96000-44100: CMP_TARGET = 1.41 fate-swr-resample_exact-s32p-96000-44100: SIZE_TOLERANCE = 1152000 - 20480 -fate-swr-resample_exact-s32p-96000-48000: CMP_TARGET = 0.99 +fate-swr-resample_exact-s32p-96000-48000: CMP_TARGET = 1.21 fate-swr-resample_exact-s32p-96000-48000: SIZE_TOLERANCE = 1152000 - 20480 -fate-swr-resample_exact-s32p-96000-8000: CMP_TARGET = 58.52 +fate-swr-resample_exact-s32p-96000-8000: CMP_TARGET = 58.54 fate-swr-resample_exact-s32p-96000-8000: SIZE_TOLERANCE = 1152000 - 20496 define ARESAMPLE_EXACT_ASYNC @@ -700,7 +700,7 @@ fate-swr-resample_exact_async-s32p-44100-48000: SIZE_TOLERANCE = 529200 - 20300 fate-swr-resample_exact_async-s32p-44100-8000: CMP_TARGET = 4022.87 fate-swr-resample_exact_async-s32p-44100-8000: SIZE_TOLERANCE = 529200 - 20310 -fate-swr-resample_exact_async-s32p-48000-44100: CMP_TARGET = 1923.97 +fate-swr-resample_exact_async-s32p-48000-44100: CMP_TARGET = 1923.96 fate-swr-resample_exact_async-s32p-48000-44100: SIZE_TOLERANCE = 576000 - 20298 fate-swr-resample_exact_async-s32p-48000-8000: CMP_TARGET = 2592.00 @@ -709,7 +709,7 @@ fate-swr-resample_exact_async-s32p-48000-8000: SIZE_TOLERANCE = 576000 - 20304 fate-swr-resample_exact_async-s32p-8000-44100: CMP_TARGET = 11187.24 fate-swr-resample_exact_async-s32p-8000-44100: SIZE_TOLERANCE = 96000 - 20344 -fate-swr-resample_exact_async-s32p-8000-48000: CMP_TARGET = 11326.80 +fate-swr-resample_exact_async-s32p-8000-48000: CMP_TARGET = 11326.79 fate-swr-resample_exact_async-s32p-8000-48000: SIZE_TOLERANCE = 96000 - 20344 define ARESAMPLE_EXACT_LIN @@ -777,22 +777,22 @@ fate-swr-resample_exact_lin-s16p-8000-44100: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample_exact_lin-s16p-8000-48000: CMP_TARGET = 14.54 fate-swr-resample_exact_lin-s16p-8000-48000: SIZE_TOLERANCE = 96000 - 20480 -fate-swr-resample_exact_lin-s32p-44100-48000: CMP_TARGET = 9.64 +fate-swr-resample_exact_lin-s32p-44100-48000: CMP_TARGET = 9.66 fate-swr-resample_exact_lin-s32p-44100-48000: SIZE_TOLERANCE = 529200 - 20482 -fate-swr-resample_exact_lin-s32p-44100-8000: CMP_TARGET = 75.38 +fate-swr-resample_exact_lin-s32p-44100-8000: CMP_TARGET = 75.37 fate-swr-resample_exact_lin-s32p-44100-8000: SIZE_TOLERANCE = 529200 - 20486 -fate-swr-resample_exact_lin-s32p-48000-44100: CMP_TARGET = 0.23 +fate-swr-resample_exact_lin-s32p-48000-44100: CMP_TARGET = 0.74 fate-swr-resample_exact_lin-s32p-48000-44100: SIZE_TOLERANCE = 576000 - 20480 -fate-swr-resample_exact_lin-s32p-48000-8000: CMP_TARGET = 62.36 +fate-swr-resample_exact_lin-s32p-48000-8000: CMP_TARGET = 62.35 fate-swr-resample_exact_lin-s32p-48000-8000: SIZE_TOLERANCE = 576000 - 20484 -fate-swr-resample_exact_lin-s32p-8000-44100: CMP_TARGET = 14.59 +fate-swr-resample_exact_lin-s32p-8000-44100: CMP_TARGET = 14.61 fate-swr-resample_exact_lin-s32p-8000-44100: SIZE_TOLERANCE = 96000 - 20480 -fate-swr-resample_exact_lin-s32p-8000-48000: CMP_TARGET = 14.50 +fate-swr-resample_exact_lin-s32p-8000-48000: CMP_TARGET = 14.52 fate-swr-resample_exact_lin-s32p-8000-48000: SIZE_TOLERANCE = 96000 - 20480 define ARESAMPLE_EXACT_LIN_ASYNC @@ -818,7 +818,7 @@ fate-swr-resample_exact_lin_async-dblp-48000-44100: SIZE_TOLERANCE = 576000 - 20 fate-swr-resample_exact_lin_async-dblp-48000-8000: CMP_TARGET = 2591.72 fate-swr-resample_exact_lin_async-dblp-48000-8000: SIZE_TOLERANCE = 576000 - 20304 -fate-swr-resample_exact_lin_async-dblp-8000-44100: CMP_TARGET = 11187.25 +fate-swr-resample_exact_lin_async-dblp-8000-44100: CMP_TARGET = 11187.24 fate-swr-resample_exact_lin_async-dblp-8000-44100: SIZE_TOLERANCE = 96000 - 20344 fate-swr-resample_exact_lin_async-dblp-8000-48000: CMP_TARGET = 11326.80 @@ -863,19 +863,19 @@ fate-swr-resample_exact_lin_async-s16p-8000-48000: SIZE_TOLERANCE = 96000 - 2034 fate-swr-resample_exact_lin_async-s32p-44100-48000: CMP_TARGET = 7791.72 fate-swr-resample_exact_lin_async-s32p-44100-48000: SIZE_TOLERANCE = 529200 - 20300 -fate-swr-resample_exact_lin_async-s32p-44100-8000: CMP_TARGET = 4023.01 +fate-swr-resample_exact_lin_async-s32p-44100-8000: CMP_TARGET = 4023.02 fate-swr-resample_exact_lin_async-s32p-44100-8000: SIZE_TOLERANCE = 529200 - 20310 -fate-swr-resample_exact_lin_async-s32p-48000-44100: CMP_TARGET = 1923.79 +fate-swr-resample_exact_lin_async-s32p-48000-44100: CMP_TARGET = 1923.77 fate-swr-resample_exact_lin_async-s32p-48000-44100: SIZE_TOLERANCE = 576000 - 20298 -fate-swr-resample_exact_lin_async-s32p-48000-8000: CMP_TARGET = 2591.72 +fate-swr-resample_exact_lin_async-s32p-48000-8000: CMP_TARGET = 2591.71 fate-swr-resample_exact_lin_async-s32p-48000-8000: SIZE_TOLERANCE = 576000 - 20304 fate-swr-resample_exact_lin_async-s32p-8000-44100: CMP_TARGET = 11187.25 fate-swr-resample_exact_lin_async-s32p-8000-44100: SIZE_TOLERANCE = 96000 - 20344 -fate-swr-resample_exact_lin_async-s32p-8000-48000: CMP_TARGET = 11326.80 +fate-swr-resample_exact_lin_async-s32p-8000-48000: CMP_TARGET = 11326.81 fate-swr-resample_exact_lin_async-s32p-8000-48000: SIZE_TOLERANCE = 96000 - 20344 $(call CROSS_TEST,$(SAMPLERATES),ARESAMPLE,s16p,s16le,s16) From 7133ab435abb3e7ae1a7e6d9570343d07d0b0d87 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 12 Mar 2017 22:37:53 +0100 Subject: [PATCH 1130/3374] avcodec/xpmdec: improve comment for one function and also fix 2 identation issues Signed-off-by: Paul B Mahol --- libavcodec/xpmdec.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/libavcodec/xpmdec.c b/libavcodec/xpmdec.c index 6cd7bde4ec729..ad6de3d05c5fa 100644 --- a/libavcodec/xpmdec.c +++ b/libavcodec/xpmdec.c @@ -28,11 +28,11 @@ typedef struct XPMContext { uint32_t *pixels; - int pixels_size; + int pixels_size; } XPMDecContext; typedef struct ColorEntry { - const char *name; ///< a string representing the name of the color + const char *name; ///< a string representing the name of the color uint32_t rgb_color; ///< RGB values for the color } ColorEntry; @@ -199,10 +199,8 @@ static unsigned convert(uint8_t x) } /* -** functions same as strcspn but ignores characters in reject if they are inside a C style comment... -** @param string, reject - same as that of strcspn -** @return length till any character in reject does not occur in string -*/ + * Function same as strcspn but ignores characters if they are inside a C style comments + */ static size_t mod_strcspn(const char *string, const char *reject) { int i, j; From 9d7e71a233e33a3f1bf9a2b5a69f22dfa3613610 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 12 Mar 2017 22:42:05 +0100 Subject: [PATCH 1131/3374] avcodec/xpmdec: rename convert to hex_char_to_number Signed-off-by: Paul B Mahol --- libavcodec/xpmdec.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/libavcodec/xpmdec.c b/libavcodec/xpmdec.c index ad6de3d05c5fa..7edb04c7616c1 100644 --- a/libavcodec/xpmdec.c +++ b/libavcodec/xpmdec.c @@ -185,7 +185,7 @@ static const ColorEntry color_table[] = { { "YellowGreen", 0xFF9ACD32 } }; -static unsigned convert(uint8_t x) +static unsigned hex_char_to_number(uint8_t x) { if (x >= 'a' && x <= 'f') x -= 87; @@ -237,30 +237,30 @@ static uint32_t hexstring_to_rgba(const char *p, int len) p++; len--; if (len == 3) { - ret |= (convert(p[2]) << 4) | - (convert(p[1]) << 12) | - (convert(p[0]) << 20); + ret |= (hex_char_to_number(p[2]) << 4) | + (hex_char_to_number(p[1]) << 12) | + (hex_char_to_number(p[0]) << 20); } else if (len == 4) { - ret = (convert(p[3]) << 4) | - (convert(p[2]) << 12) | - (convert(p[1]) << 20) | - (convert(p[0]) << 28); + ret = (hex_char_to_number(p[3]) << 4) | + (hex_char_to_number(p[2]) << 12) | + (hex_char_to_number(p[1]) << 20) | + (hex_char_to_number(p[0]) << 28); } else if (len == 6) { - ret |= convert(p[5]) | - (convert(p[4]) << 4) | - (convert(p[3]) << 8) | - (convert(p[2]) << 12) | - (convert(p[1]) << 16) | - (convert(p[0]) << 20); + ret |= hex_char_to_number(p[5]) | + (hex_char_to_number(p[4]) << 4) | + (hex_char_to_number(p[3]) << 8) | + (hex_char_to_number(p[2]) << 12) | + (hex_char_to_number(p[1]) << 16) | + (hex_char_to_number(p[0]) << 20); } else if (len == 8) { - ret = convert(p[7]) | - (convert(p[6]) << 4) | - (convert(p[5]) << 8) | - (convert(p[4]) << 12) | - (convert(p[3]) << 16) | - (convert(p[2]) << 20) | - (convert(p[1]) << 24) | - (convert(p[0]) << 28); + ret = hex_char_to_number(p[7]) | + (hex_char_to_number(p[6]) << 4) | + (hex_char_to_number(p[5]) << 8) | + (hex_char_to_number(p[4]) << 12) | + (hex_char_to_number(p[3]) << 16) | + (hex_char_to_number(p[2]) << 20) | + (hex_char_to_number(p[1]) << 24) | + (hex_char_to_number(p[0]) << 28); } } else { strncpy(color_name, p, len); From fbc1f323dbda521a693737fd9d98ce1640e9a3de Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 12 Mar 2017 22:43:49 +0100 Subject: [PATCH 1132/3374] avcodec/xpmdec: rename yet another function Signed-off-by: Paul B Mahol --- libavcodec/xpmdec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/xpmdec.c b/libavcodec/xpmdec.c index 7edb04c7616c1..25ef992a1ccb5 100644 --- a/libavcodec/xpmdec.c +++ b/libavcodec/xpmdec.c @@ -227,7 +227,7 @@ static size_t mod_strcspn(const char *string, const char *reject) return i; } -static uint32_t hexstring_to_rgba(const char *p, int len) +static uint32_t color_string_to_rgba(const char *p, int len) { uint32_t ret = 0xFF000000; const ColorEntry *entry; @@ -378,7 +378,7 @@ static int xpm_decode_frame(AVCodecContext *avctx, void *data, if ((ret = ascii2index(index, cpp)) < 0) return ret; - x->pixels[ret] = hexstring_to_rgba(ptr, len); + x->pixels[ret] = color_string_to_rgba(ptr, len); ptr += mod_strcspn(ptr, ",") + 1; } From 2b790b1c9e3bf8f4fbc56fc3a071f2015b58de21 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 12 Mar 2017 22:51:00 +0100 Subject: [PATCH 1133/3374] avcodec/xpmdec: do not allow number of colors to be higher than allocated Signed-off-by: Paul B Mahol --- libavcodec/xpmdec.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/libavcodec/xpmdec.c b/libavcodec/xpmdec.c index 25ef992a1ccb5..592f81ac3c4f8 100644 --- a/libavcodec/xpmdec.c +++ b/libavcodec/xpmdec.c @@ -328,29 +328,22 @@ static int xpm_decode_frame(AVCodecContext *avctx, void *data, if ((ret = ff_get_buffer(avctx, p, 0)) < 0) return ret; - if (ncolors <= 0) { - av_log(avctx, AV_LOG_ERROR, "invalid number of colors: %d\n", ncolors); + if (cpp <= 0 || cpp >= 5) { + av_log(avctx, AV_LOG_ERROR, "unsupported/invalid number of chars per pixel: %d\n", cpp); return AVERROR_INVALIDDATA; } - if (cpp <= 0) { - av_log(avctx, AV_LOG_ERROR, "invalid number of chars per pixel: %d\n", cpp); + size = 1; + for (i = 0; i < cpp; i++) + size *= 94; + + if (ncolors <= 0 || ncolors > size) { + av_log(avctx, AV_LOG_ERROR, "invalid number of colors: %d\n", ncolors); return AVERROR_INVALIDDATA; } - size = 1; - j = 1; - for (i = 0; i < cpp; i++) { - size += j * 94; - j *= 95; - } size *= 4; - if (size < 0) { - av_log(avctx, AV_LOG_ERROR, "unsupported number of chars per pixel: %d\n", cpp); - return AVERROR(ENOMEM); - } - av_fast_padded_malloc(&x->pixels, &x->pixels_size, size); if (!x->pixels) return AVERROR(ENOMEM); From dd0090eb211219377bf43a034749d8e6524015eb Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 12 Mar 2017 22:56:58 +0100 Subject: [PATCH 1134/3374] avcodec/xpmdec: fix colors values which are different for X11 Signed-off-by: Paul B Mahol --- libavcodec/xpmdec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/xpmdec.c b/libavcodec/xpmdec.c index 592f81ac3c4f8..b9b2551ec16c0 100644 --- a/libavcodec/xpmdec.c +++ b/libavcodec/xpmdec.c @@ -92,8 +92,8 @@ static const ColorEntry color_table[] = { { "GhostWhite", 0xFFF8F8FF }, { "Gold", 0xFFFFD700 }, { "GoldenRod", 0xFFDAA520 }, - { "Gray", 0xFF808080 }, - { "Green", 0xFF008000 }, + { "Gray", 0xFFBEBEBE }, + { "Green", 0xFF00FF00 }, { "GreenYellow", 0xFFADFF2F }, { "HoneyDew", 0xFFF0FFF0 }, { "HotPink", 0xFFFF69B4 }, @@ -122,7 +122,7 @@ static const ColorEntry color_table[] = { { "LimeGreen", 0xFF32CD32 }, { "Linen", 0xFFFAF0E6 }, { "Magenta", 0xFFFF00FF }, - { "Maroon", 0xFF800000 }, + { "Maroon", 0xFFB03060 }, { "MediumAquaMarine", 0xFF66CDAA }, { "MediumBlue", 0xFF0000CD }, { "MediumOrchid", 0xFFBA55D3 }, @@ -155,7 +155,7 @@ static const ColorEntry color_table[] = { { "Pink", 0xFFFFC0CB }, { "Plum", 0xFFDDA0DD }, { "PowderBlue", 0xFFB0E0E6 }, - { "Purple", 0xFF800080 }, + { "Purple", 0xFFA020F0 }, { "Red", 0xFFFF0000 }, { "RosyBrown", 0xFFBC8F8F }, { "RoyalBlue", 0xFF4169E1 }, From 58f0bbc1eafbe21197bc53ad263005093182a7f2 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 12 Mar 2017 22:58:49 +0100 Subject: [PATCH 1135/3374] avcodec/xpmdec: avoid "magic" numbers in function hex_char_to_number() Signed-off-by: Paul B Mahol --- libavcodec/xpmdec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/xpmdec.c b/libavcodec/xpmdec.c index b9b2551ec16c0..605a09d05a081 100644 --- a/libavcodec/xpmdec.c +++ b/libavcodec/xpmdec.c @@ -188,9 +188,9 @@ static const ColorEntry color_table[] = { static unsigned hex_char_to_number(uint8_t x) { if (x >= 'a' && x <= 'f') - x -= 87; + x -= 'a' - 10; else if (x >= 'A' && x <= 'F') - x -= 55; + x -= 'A' - 10; else if (x >= '0' && x <= '9') x -= '0'; else From a720b854b0d3f0fae2b1eac644dd39e5821cacb1 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 12 Mar 2017 03:04:04 +0100 Subject: [PATCH 1136/3374] avcodec/mpeg12dec: Fix runtime error: left shift of negative value -1 Fixes: 764/clusterfuzz-testcase-6273034652483584 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/mpeg12dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c index 27db14c35ef81..e49167f89eb3a 100644 --- a/libavcodec/mpeg12dec.c +++ b/libavcodec/mpeg12dec.c @@ -994,7 +994,7 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64]) cbp = get_vlc2(&s->gb, ff_mb_pat_vlc.table, MB_PAT_VLC_BITS, 1); if (mb_block_count > 6) { - cbp <<= mb_block_count - 6; + cbp *= 1 << mb_block_count - 6; cbp |= get_bits(&s->gb, mb_block_count - 6); s->bdsp.clear_blocks(s->block[6]); } From a66c6e28b543804f50df1c6083a204219b6b1daa Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 12 Mar 2017 03:04:05 +0100 Subject: [PATCH 1137/3374] avcodec/rv34: Fix runtime error: signed integer overflow: 36880 * 66288 cannot be represented in type 'int' Fixes: 768/clusterfuzz-testcase-4807444305805312 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/rv34.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c index be49804ebd5c6..d2d676a86d09f 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -1636,7 +1636,7 @@ static AVRational update_sar(int old_w, int old_h, AVRational sar, int new_w, in if (!sar.num) sar = (AVRational){1, 1}; - sar = av_mul_q(sar, (AVRational){new_h * old_w, new_w * old_h}); + sar = av_mul_q(sar, av_mul_q((AVRational){new_h, new_w}, (AVRational){old_w, old_h})); return sar; } From 967feea5ebb744dce97ab327d33502b43fca0c7f Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 12 Mar 2017 03:04:06 +0100 Subject: [PATCH 1138/3374] avcodec/vp6: clear dimensions on failed resolution change in vp6_parse_header() Fixes: 807/clusterfuzz-testcase-6470061042696192 Fixes null pointer dereference Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/vp6.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c index f0e60a3822ae6..4afd67b3a47f1 100644 --- a/libavcodec/vp6.c +++ b/libavcodec/vp6.c @@ -108,7 +108,7 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size) ret = ff_vp56_init_range_decoder(c, buf+6, buf_size-6); if (ret < 0) - return ret; + goto fail; vp56_rac_gets(c, 2); parse_filter_info = s->filter_header; @@ -162,9 +162,8 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size) buf += coeff_offset; buf_size -= coeff_offset; if (buf_size < 0) { - if (s->frames[VP56_FRAME_CURRENT]->key_frame) - ff_set_dimensions(s->avctx, 0, 0); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } if (s->use_huffman) { s->parse_coeff = vp6_parse_coeff_huffman; @@ -172,7 +171,7 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size) } else { ret = ff_vp56_init_range_decoder(&s->cc, buf, buf_size); if (ret < 0) - return ret; + goto fail; s->ccp = &s->cc; } } else { @@ -180,6 +179,10 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size) } return res; +fail: + if (res == VP56_SIZE_CHANGE) + ff_set_dimensions(s->avctx, 0, 0); + return ret; } static void vp6_coeff_order_table_init(VP56Context *s) From 33e997d992ccd4e93b57fa7dfb478fc6a67ce4ac Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Mon, 13 Mar 2017 11:58:34 +0800 Subject: [PATCH 1139/3374] avformat/hlsenc: second_levels flags process function extract the SECOND_LEVEL* flags process and name is too long extract all of them output to funtions, make code clear Signed-off-by: Steven Liu --- libavformat/hlsenc.c | 239 ++++++++++++++++++++++++------------------- 1 file changed, 136 insertions(+), 103 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index b8122f1a37adb..5df25146a7e80 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -470,17 +470,9 @@ static HLSSegment *find_segment_by_filename(HLSSegment *segment, const char *fil return (HLSSegment *) NULL; } -/* Create a new segment and append it to the segment list */ -static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, - int64_t pos, int64_t size) +static int sls_flags_filename_process(struct AVFormatContext *s, HLSContext *hls, HLSSegment *en, double duration, + int64_t pos, int64_t size) { - HLSSegment *en = av_malloc(sizeof(*en)); - const char *filename; - int ret; - - if (!en) - return AVERROR(ENOMEM); - if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) && strlen(hls->current_segment_final_filename_fmt)) { av_strlcpy(hls->avf->filename, hls->current_segment_final_filename_fmt, sizeof(hls->avf->filename)); @@ -521,7 +513,127 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double av_free(filename); } } + return 0; +} + +static int sls_flag_check_duration_size_index(HLSContext *hls) +{ + int ret = 0; + + 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"); + 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"); + 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"); + ret = AVERROR(EINVAL); + } + + return ret; +} + +static int sls_flag_check_duration_size(HLSContext *hls) +{ + const char *proto = avio_find_protocol_name(hls->basename); + int segment_renaming_ok = proto && !strcmp(proto, "file"); + int ret = 0; + + if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) && !segment_renaming_ok) { + av_log(hls, AV_LOG_ERROR, + "second_level_segment_duration hls_flag works only with file protocol segment names\n"); + ret = AVERROR(EINVAL); + } + if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) && !segment_renaming_ok) { + av_log(hls, AV_LOG_ERROR, + "second_level_segment_size hls_flag works only with file protocol segment names\n"); + ret = AVERROR(EINVAL); + } + + return ret; +} + +static void sls_flag_file_rename(HLSContext *hls, char *old_filename) { + if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) && + strlen(hls->current_segment_final_filename_fmt)) { + ff_rename(old_filename, hls->avf->filename, hls); + } +} + +static int sls_flag_use_localtime_filename(AVFormatContext *oc, HLSContext *c) +{ + if (c->flags & HLS_SECOND_LEVEL_SEGMENT_INDEX) { + char * filename = av_strdup(oc->filename); // %%d will be %d after strftime + if (!filename) + return AVERROR(ENOMEM); + if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename), +#if FF_API_HLS_WRAP + filename, 'd', c->wrap ? c->sequence % c->wrap : c->sequence) < 1) { +#else + filename, 'd', c->sequence) < 1) { +#endif + av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', " + "you can try to remove second_level_segment_index flag\n", + filename); + av_free(filename); + return AVERROR(EINVAL); + } + av_free(filename); + } + if (c->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) { + av_strlcpy(c->current_segment_final_filename_fmt, oc->filename, + sizeof(c->current_segment_final_filename_fmt)); + if (c->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) { + char * filename = av_strdup(oc->filename); // %%s will be %s after strftime + if (!filename) + return AVERROR(ENOMEM); + if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename), filename, 's', 0) < 1) { + av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', " + "you can try to remove second_level_segment_size flag\n", + filename); + av_free(filename); + return AVERROR(EINVAL); + } + av_free(filename); + } + if (c->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) { + char * filename = av_strdup(oc->filename); // %%t will be %t after strftime + if (!filename) + return AVERROR(ENOMEM); + if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename), filename, 't', 0) < 1) { + av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', " + "you can try to remove second_level_segment_time flag\n", + filename); + av_free(filename); + return AVERROR(EINVAL); + } + av_free(filename); + } + } + return 0; +} + +/* Create a new segment and append it to the segment list */ +static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, + int64_t pos, int64_t size) +{ + HLSSegment *en = av_malloc(sizeof(*en)); + const char *filename; + int ret; + if (!en) + return AVERROR(ENOMEM); + + ret = sls_flags_filename_process(s, hls, en, duration, pos, size); + if (ret < 0) { + return ret; + } filename = av_basename(hls->avf->filename); @@ -870,57 +982,12 @@ static int hls_start(AVFormatContext *s) av_log(oc, AV_LOG_ERROR, "Could not get segment filename with use_localtime\n"); return AVERROR(EINVAL); } - if (c->flags & HLS_SECOND_LEVEL_SEGMENT_INDEX) { - char * filename = av_strdup(oc->filename); // %%d will be %d after strftime - if (!filename) - return AVERROR(ENOMEM); - if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename), -#if FF_API_HLS_WRAP - filename, 'd', c->wrap ? c->sequence % c->wrap : c->sequence) < 1) { -#else - filename, 'd', c->sequence) < 1) { -#endif - av_log(c, AV_LOG_ERROR, - "Invalid second level segment filename template '%s', " - "you can try to remove second_level_segment_index flag\n", - filename); - av_free(filename); - return AVERROR(EINVAL); - } - av_free(filename); - } - if (c->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) { - av_strlcpy(c->current_segment_final_filename_fmt, oc->filename, - sizeof(c->current_segment_final_filename_fmt)); - if (c->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) { - char * filename = av_strdup(oc->filename); // %%s will be %s after strftime - if (!filename) - return AVERROR(ENOMEM); - if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename), filename, 's', 0) < 1) { - av_log(c, AV_LOG_ERROR, - "Invalid second level segment filename template '%s', " - "you can try to remove second_level_segment_size flag\n", - filename); - av_free(filename); - return AVERROR(EINVAL); - } - av_free(filename); - } - if (c->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) { - char * filename = av_strdup(oc->filename); // %%t will be %t after strftime - if (!filename) - return AVERROR(ENOMEM); - if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename), filename, 't', 0) < 1) { - av_log(c, AV_LOG_ERROR, - "Invalid second level segment filename template '%s', " - "you can try to remove second_level_segment_time flag\n", - filename); - av_free(filename); - return AVERROR(EINVAL); - } - av_free(filename); - } + + err = sls_flag_use_localtime_filename(oc, c); + if (err < 0) { + return AVERROR(ENOMEM); } + if (c->use_localtime_mkdir) { const char *dir; char *fn_copy = av_strdup(oc->filename); @@ -1043,7 +1110,8 @@ static int hls_write_header(AVFormatContext *s) int basename_size; int vtt_basename_size; - if (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH || hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_FORMATTED_DATETIME) { + if ((hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH) || + (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_FORMATTED_DATETIME)) { time_t t = time(NULL); // we will need it in either case if (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH) { hls->start_sequence = (int64_t)t; @@ -1138,38 +1206,13 @@ static int hls_write_header(AVFormatContext *s) } } if (!hls->use_localtime) { - 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"); - ret = AVERROR(EINVAL); - goto fail; - } - 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"); - ret = AVERROR(EINVAL); + ret = sls_flag_check_duration_size_index(hls); + if (ret < 0) { goto fail; } - 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"); - ret = AVERROR(EINVAL); - goto fail; - } } else { - const char *proto = avio_find_protocol_name(hls->basename); - int segment_renaming_ok = proto && !strcmp(proto, "file"); - - if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) && !segment_renaming_ok) { - av_log(hls, AV_LOG_ERROR, - "second_level_segment_duration hls_flag works only with file protocol segment names\n"); - ret = AVERROR(EINVAL); - goto fail; - } - if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) && !segment_renaming_ok) { - av_log(hls, AV_LOG_ERROR, - "second_level_segment_size hls_flag works only with file protocol segment names\n"); - ret = AVERROR(EINVAL); + ret = sls_flag_check_duration_size(hls); + if (ret < 0) { goto fail; } } @@ -1355,10 +1398,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) } else if (hls->max_seg_size > 0) { if (hls->start_pos >= hls->max_seg_size) { hls->sequence++; - if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) && - strlen(hls->current_segment_final_filename_fmt)) { - ff_rename(old_filename, hls->avf->filename, hls); - } + sls_flag_file_rename(hls, old_filename); ret = hls_start(s); hls->start_pos = 0; /* When split segment by byte, the duration is short than hls_time, @@ -1367,11 +1407,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) } hls->number++; } else { - if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) && - strlen(hls->current_segment_final_filename_fmt)) { - ff_rename(old_filename, hls->avf->filename, hls); - } - + sls_flag_file_rename(hls, old_filename); ret = hls_start(s); } @@ -1416,10 +1452,7 @@ static int hls_write_trailer(struct AVFormatContext *s) hls_append_segment(s, hls, hls->duration + hls->dpp, hls->start_pos, hls->size); } - if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) && - strlen(hls->current_segment_final_filename_fmt)) { - ff_rename(old_filename, hls->avf->filename, hls); - } + sls_flag_file_rename(hls, old_filename); if (vtt_oc) { if (vtt_oc->pb) From 62c8dc46429bd75a27142c142f8c50139d8a0702 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 12 Mar 2017 18:59:05 +0100 Subject: [PATCH 1140/3374] avfilter/vf_lut3d: actually skip lines when encountering DOMAIN_ string Signed-off-by: Paul B Mahol --- libavfilter/vf_lut3d.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavfilter/vf_lut3d.c b/libavfilter/vf_lut3d.c index b136cda21d43d..7a294b07610f3 100644 --- a/libavfilter/vf_lut3d.c +++ b/libavfilter/vf_lut3d.c @@ -320,6 +320,7 @@ static int parse_cube(AVFilterContext *ctx, FILE *f) struct rgbvec *vec = &lut3d->lut[i][j][k]; do { +try_again: NEXT_LINE(0); if (!strncmp(line, "DOMAIN_", 7)) { float *vals = NULL; @@ -330,7 +331,7 @@ static int parse_cube(AVFilterContext *ctx, FILE *f) sscanf(line + 11, "%f %f %f", vals, vals + 1, vals + 2); av_log(ctx, AV_LOG_DEBUG, "min: %f %f %f | max: %f %f %f\n", min[0], min[1], min[2], max[0], max[1], max[2]); - continue; + goto try_again; } } while (skip_line(line)); if (sscanf(line, "%f %f %f", &vec->r, &vec->g, &vec->b) != 3) From fbfbd97be25c4da0562ef61e2f27192d1ec4d276 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 12 Mar 2017 23:13:26 +0100 Subject: [PATCH 1141/3374] avcodec/xpmdec: there are XPM files with dos line endings Signed-off-by: Paul B Mahol --- libavcodec/xpmdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/xpmdec.c b/libavcodec/xpmdec.c index 605a09d05a081..3c025a6bc5baa 100644 --- a/libavcodec/xpmdec.c +++ b/libavcodec/xpmdec.c @@ -307,7 +307,7 @@ static int xpm_decode_frame(AVCodecContext *avctx, void *data, avctx->pix_fmt = AV_PIX_FMT_BGRA; end = avpkt->data + avpkt->size; - while (memcmp(ptr, "/* XPM */\n", 10) && ptr < end - 10) + while (memcmp(ptr, "/* XPM */", 9) && ptr < end - 9) ptr++; if (ptr >= end) { From a557ae8d52ce1cfaf3be5cdb13728b7b2b9512b9 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 10 Mar 2017 15:24:52 +0100 Subject: [PATCH 1142/3374] avcodec/h264_direct: Fix runtime error: signed integer overflow: 2147483647 - -14133 cannot be represented in type 'int' Fixes: 755/clusterfuzz-testcase-5369072516595712 See: [FFmpeg-devel] [PATCH 1/2] avcodec/h264_direct: Fix runtime error: signed integer overflow: 2147483647 - -14133 cannot be represented in type 'int' Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/h264_direct.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c index cbb84665b3b90..66e54479d1165 100644 --- a/libavcodec/h264_direct.c +++ b/libavcodec/h264_direct.c @@ -39,7 +39,12 @@ static int get_scale_factor(H264SliceContext *sl, int poc, int poc1, int i) { int poc0 = sl->ref_list[0][i].poc; - int td = av_clip_int8(poc1 - poc0); + int64_t pocdiff = poc1 - (int64_t)poc0; + int td = av_clip_int8(pocdiff); + + if (pocdiff != (int)pocdiff) + avpriv_request_sample(sl->h264->avctx, "pocdiff overflow\n"); + if (td == 0 || sl->ref_list[0][i].parent->long_ref) { return 256; } else { From 1467143a6ebf08a16ec0b833ae462f88345828bd Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 12 Mar 2017 23:45:54 +0100 Subject: [PATCH 1143/3374] avcodec/wavpack: Fix runtime error: shift exponent 137 is too large for 32-bit type 'int' Fixes: 808/clusterfuzz-testcase-4715513349406720 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/wavpack.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/wavpack.h b/libavcodec/wavpack.h index 445d593c3bb6a..c949390f51684 100644 --- a/libavcodec/wavpack.h +++ b/libavcodec/wavpack.h @@ -171,7 +171,7 @@ static av_always_inline int wp_exp2(int16_t val) res = wp_exp2_table[val & 0xFF] | 0x100; val >>= 8; - if (val > 31) + if (val > 31U) return INT_MIN; res = (val > 9) ? (res << (val - 9)) : (res >> (9 - val)); return neg ? -res : res; From acdacb108d98e42bb631de0d3859958662aa2019 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 13 Mar 2017 00:18:04 +0100 Subject: [PATCH 1144/3374] avcodec/targa: Skip hflip on blank images Fixes: timeout with 810/clusterfuzz-testcase-5249282825256960 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/targa.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/libavcodec/targa.c b/libavcodec/targa.c index 215c0f51f6661..93e0ef7905db8 100644 --- a/libavcodec/targa.c +++ b/libavcodec/targa.c @@ -265,32 +265,33 @@ static int decode_frame(AVCodecContext *avctx, line = advance_line(dst, line, stride, &y, h, interleave); } while (line); } - } - if (flags & TGA_RIGHTTOLEFT) { // right-to-left, needs horizontal flip - int x; - for (y = 0; y < h; y++) { - void *line = &p->data[0][y * p->linesize[0]]; - for (x = 0; x < w >> 1; x++) { - switch (bpp) { - case 32: - FFSWAP(uint32_t, ((uint32_t *)line)[x], ((uint32_t *)line)[w - x - 1]); - break; - case 24: - FFSWAP(uint8_t, ((uint8_t *)line)[3 * x ], ((uint8_t *)line)[3 * w - 3 * x - 3]); - FFSWAP(uint8_t, ((uint8_t *)line)[3 * x + 1], ((uint8_t *)line)[3 * w - 3 * x - 2]); - FFSWAP(uint8_t, ((uint8_t *)line)[3 * x + 2], ((uint8_t *)line)[3 * w - 3 * x - 1]); - break; - case 16: - FFSWAP(uint16_t, ((uint16_t *)line)[x], ((uint16_t *)line)[w - x - 1]); - break; - case 8: - FFSWAP(uint8_t, ((uint8_t *)line)[x], ((uint8_t *)line)[w - x - 1]); + if (flags & TGA_RIGHTTOLEFT) { // right-to-left, needs horizontal flip + int x; + for (y = 0; y < h; y++) { + void *line = &p->data[0][y * p->linesize[0]]; + for (x = 0; x < w >> 1; x++) { + switch (bpp) { + case 32: + FFSWAP(uint32_t, ((uint32_t *)line)[x], ((uint32_t *)line)[w - x - 1]); + break; + case 24: + FFSWAP(uint8_t, ((uint8_t *)line)[3 * x ], ((uint8_t *)line)[3 * w - 3 * x - 3]); + FFSWAP(uint8_t, ((uint8_t *)line)[3 * x + 1], ((uint8_t *)line)[3 * w - 3 * x - 2]); + FFSWAP(uint8_t, ((uint8_t *)line)[3 * x + 2], ((uint8_t *)line)[3 * w - 3 * x - 1]); + break; + case 16: + FFSWAP(uint16_t, ((uint16_t *)line)[x], ((uint16_t *)line)[w - x - 1]); + break; + case 8: + FFSWAP(uint8_t, ((uint8_t *)line)[x], ((uint8_t *)line)[w - x - 1]); + } } } } } + *got_frame = 1; return avpkt->size; From 7cebc5a9ccba0de7bddf7900ae85652ebc66141c Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 13 Mar 2017 02:51:15 +0100 Subject: [PATCH 1145/3374] avcodec/wavpack: Fix runtime error: shift exponent 32 is too large for 32-bit type 'int' Fixes: 822/clusterfuzz-testcase-4873433189974016 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/wavpack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index 943e46a25cae9..bc94b27c04071 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -846,7 +846,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, continue; } bytestream2_get_buffer(&gb, val, 4); - if (val[0] > 32) { + if (val[0] > 31) { av_log(avctx, AV_LOG_ERROR, "Invalid INT32INFO, extra_bits = %d (> 32)\n", val[0]); continue; From d3ce067e7687203cf4a0a475ffd4b733b7c3b4f4 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Tue, 14 Mar 2017 10:16:00 +0800 Subject: [PATCH 1146/3374] avformat/hlsenc: fix ticket 6231 check if the hls_flags is byterange_mode and check if should close fd Signed-off-by: Steven Liu --- libavformat/hlsenc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 5df25146a7e80..e2c021b754b03 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -1362,6 +1362,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) end_pts, AV_TIME_BASE_Q) >= 0) { int64_t new_start_pos; char *old_filename = av_strdup(hls->avf->filename); + int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0); if (!old_filename) { return AVERROR(ENOMEM); @@ -1372,9 +1373,11 @@ 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 (!byterange_mode) { + 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)) From 4e3cc4bdd8acedbcc703607ed0efbb64bb5c3cc4 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Tue, 14 Mar 2017 18:11:20 +0800 Subject: [PATCH 1147/3374] avformat/flvenc: flx flvflags no_metadata bug When use flvflags no_metadata , the FLV header will be cover by write tailer This commit fix the bug Signed-off-by: Steven Liu --- libavformat/flvenc.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c index d7506c56fbe99..899b07ea7bef8 100644 --- a/libavformat/flvenc.c +++ b/libavformat/flvenc.c @@ -848,20 +848,22 @@ static int flv_write_trailer(AVFormatContext *s) avio_seek(pb, flv->datasize_offset, SEEK_SET); put_amf_double(pb, flv->datasize); } - if (!(flv->flags & FLV_NO_DURATION_FILESIZE)) { - /* update information */ - if (avio_seek(pb, flv->duration_offset, SEEK_SET) < 0) { - av_log(s, AV_LOG_WARNING, "Failed to update header with correct duration.\n"); - } else { - put_amf_double(pb, flv->duration / (double)1000); - } - if (avio_seek(pb, flv->filesize_offset, SEEK_SET) < 0) { - av_log(s, AV_LOG_WARNING, "Failed to update header with correct filesize.\n"); - } else { - put_amf_double(pb, file_size); + if (!(flv->flags & FLV_NO_METADATA)) { + if (!(flv->flags & FLV_NO_DURATION_FILESIZE)) { + /* update information */ + if (avio_seek(pb, flv->duration_offset, SEEK_SET) < 0) { + av_log(s, AV_LOG_WARNING, "Failed to update header with correct duration.\n"); + } else { + put_amf_double(pb, flv->duration / (double)1000); + } + if (avio_seek(pb, flv->filesize_offset, SEEK_SET) < 0) { + av_log(s, AV_LOG_WARNING, "Failed to update header with correct filesize.\n"); + } else { + put_amf_double(pb, file_size); + } } } - avio_seek(pb, file_size, SEEK_SET); + return 0; } From b2206475b45950954c3af38dc09722c7b217611d Mon Sep 17 00:00:00 2001 From: Katherine Nagels Date: Mon, 13 Mar 2017 11:57:11 +1300 Subject: [PATCH 1148/3374] doc/filters: Add colourspace values for colormatrix filter Reviewed-by: Michael Niedermayer Signed-off-by: Kieran Kunhya --- doc/filters.texi | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 192a81a075743..950ff817c5a6c 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -5260,15 +5260,24 @@ The accepted values are: @item bt709 BT.709 +@item fcc +FCC + @item bt601 BT.601 +@item bt470 +BT.470 + +@item bt470bg +BT.470BG + +@item smpte170m +SMPTE-170M + @item smpte240m SMPTE-240M -@item fcc -FCC - @item bt2020 BT.2020 @end table From 0728d9a281068add5898a8b51cd9c6f3b973ea31 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 13 Mar 2017 20:45:07 +0100 Subject: [PATCH 1149/3374] avcodec/pictordec: Fix runtime error: left shift of 805306368 by 2 places cannot be represented in type 'int' Fixes: 823/clusterfuzz-testcase-6727060074528768 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/pictordec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/pictordec.c b/libavcodec/pictordec.c index 2dbc040b5ca11..8b075bfd0cdab 100644 --- a/libavcodec/pictordec.c +++ b/libavcodec/pictordec.c @@ -62,7 +62,7 @@ static void picmemset(PicContext *s, AVFrame *frame, unsigned value, int run, { uint8_t *d; int shift = *plane * bits_per_plane; - int mask = ((1 << bits_per_plane) - 1) << shift; + unsigned mask = ((1 << bits_per_plane) - 1) << shift; value <<= shift; while (run > 0) { From 108b02e5471c1dae248200db694aba9b7b8555a8 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 13 Mar 2017 20:45:08 +0100 Subject: [PATCH 1150/3374] avcodec/tiff: Check for multiple geo key directories Fixes memleak Fixes: 826/clusterfuzz-testcase-5316921379520512 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/tiff.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index efbd9791a54b0..456da5142b9a8 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -1045,6 +1045,10 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) ADD_METADATA(count, "ModelTiepointTag", NULL); break; case TIFF_GEO_KEY_DIRECTORY: + if (s->geotag_count) { + avpriv_request_sample(s->avctx, "Multiple geo key directories\n"); + return AVERROR_INVALIDDATA; + } ADD_METADATA(1, "GeoTIFF_Version", NULL); ADD_METADATA(2, "GeoTIFF_Key_Revision", "."); s->geotag_count = ff_tget_short(&s->gb, s->le); From 8ebed703f153e979edb2156754c8bdac4d5d6266 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 13 Mar 2017 20:45:09 +0100 Subject: [PATCH 1151/3374] avcodec/mpegaudiodec_template: Make l3_unscale() work with e=0 Fixes undefined behavior Fixes: 830/clusterfuzz-testcase-6253175327686656 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/mpegaudiodec_template.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/mpegaudiodec_template.c b/libavcodec/mpegaudiodec_template.c index 88f62727cbd5e..a5ac5817f34b5 100644 --- a/libavcodec/mpegaudiodec_template.c +++ b/libavcodec/mpegaudiodec_template.c @@ -253,7 +253,7 @@ static inline int l3_unscale(int value, int exponent) #endif if (e > (SUINT)31) return 0; - m = (m + (1 << (e - 1))) >> e; + m = (m + ((1U << e)>>1)) >> e; return m; } From 6693d57e99d9bde450b145024f025e5c5349c3a0 Mon Sep 17 00:00:00 2001 From: Alexander Strasser Date: Sat, 11 Mar 2017 12:02:32 +0100 Subject: [PATCH 1152/3374] lavf/avio: Remove unnecessary escaping of ' in string literals Signed-off-by: Alexander Strasser --- libavformat/avio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/avio.c b/libavformat/avio.c index 62233a633c7bf..9020aa91e44e9 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -179,12 +179,12 @@ int ffurl_connect(URLContext *uc, AVDictionary **options) (uc->protocol_blacklist && !strcmp(uc->protocol_blacklist, e->value))); if (uc->protocol_whitelist && av_match_list(uc->prot->name, uc->protocol_whitelist, ',') <= 0) { - av_log(uc, AV_LOG_ERROR, "Protocol not on whitelist \'%s\'!\n", uc->protocol_whitelist); + av_log(uc, AV_LOG_ERROR, "Protocol not on whitelist '%s'!\n", uc->protocol_whitelist); return AVERROR(EINVAL); } if (uc->protocol_blacklist && av_match_list(uc->prot->name, uc->protocol_blacklist, ',') > 0) { - av_log(uc, AV_LOG_ERROR, "Protocol blacklisted \'%s\'!\n", uc->protocol_blacklist); + av_log(uc, AV_LOG_ERROR, "Protocol blacklisted '%s'!\n", uc->protocol_blacklist); return AVERROR(EINVAL); } From a70d5e25936424112ecbeb1c304100e68bce0faa Mon Sep 17 00:00:00 2001 From: Alexander Strasser Date: Sat, 11 Mar 2017 15:43:39 +0100 Subject: [PATCH 1153/3374] lavf/avio: Be more explicit in logging white/black list matches The current form of the messages indicating matches in the white or black lists seems to be a bit too much relying on context. Make the messages more explicit. Signed-off-by: Alexander Strasser --- libavformat/avio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/avio.c b/libavformat/avio.c index 9020aa91e44e9..1e79c9dd5c33f 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -179,12 +179,12 @@ int ffurl_connect(URLContext *uc, AVDictionary **options) (uc->protocol_blacklist && !strcmp(uc->protocol_blacklist, e->value))); if (uc->protocol_whitelist && av_match_list(uc->prot->name, uc->protocol_whitelist, ',') <= 0) { - av_log(uc, AV_LOG_ERROR, "Protocol not on whitelist '%s'!\n", uc->protocol_whitelist); + av_log(uc, AV_LOG_ERROR, "Protocol '%s' not on whitelist '%s'!\n", uc->prot->name, uc->protocol_whitelist); return AVERROR(EINVAL); } if (uc->protocol_blacklist && av_match_list(uc->prot->name, uc->protocol_blacklist, ',') > 0) { - av_log(uc, AV_LOG_ERROR, "Protocol blacklisted '%s'!\n", uc->protocol_blacklist); + av_log(uc, AV_LOG_ERROR, "Protocol '%s' on blacklist '%s'!\n", uc->prot->name, uc->protocol_blacklist); return AVERROR(EINVAL); } From 55eab1733b9e730ceac33edce9aab56c17ea87b2 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 9 Mar 2017 15:43:30 +0100 Subject: [PATCH 1154/3374] ffmpeg, ffprobe: don't "merge" side data into packet data by default Preparation for potentially disabling merged side data by default in the libs. Do this in particular because it affects fate tests. The changed tests either reflect added packet side data, or the changed packet size due to merged side data removal reducing the packet size. --- ffmpeg_opt.c | 2 + ffprobe.c | 8 +++ libavformat/tests/seek.c | 2 + tests/ref/fate/gaplessenc-itunes-to-ipod-aac | 4 +- tests/ref/fate/gaplessenc-pcm-to-mov-aac | 4 +- tests/ref/fate/gaplessinfo-itunes1 | 4 +- tests/ref/fate/gaplessinfo-itunes2 | 4 +- tests/ref/fate/mov-aac-2048-priming | 3 +- tests/ref/seek/cache-pipe | 10 ++-- tests/ref/seek/extra-mp3 | 18 +++---- tests/ref/seek/lavf-ts | 54 ++++++++++---------- tests/ref/seek/mkv-codec-delay | 14 ++--- 12 files changed, 70 insertions(+), 57 deletions(-) diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c index e2c0176e140c7..fc885dfac3c0c 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -927,6 +927,7 @@ static int open_input_file(OptionsContext *o, const char *filename) print_error(filename, AVERROR(ENOMEM)); exit_program(1); } + ic->flags |= AVFMT_FLAG_KEEP_SIDE_DATA; if (o->nb_audio_sample_rate) { av_dict_set_int(&o->g->format_opts, "sample_rate", o->audio_sample_rate[o->nb_audio_sample_rate - 1].u.i, 0); } @@ -1912,6 +1913,7 @@ static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const ch int i, err; AVFormatContext *ic = avformat_alloc_context(); + ic->flags |= AVFMT_FLAG_KEEP_SIDE_DATA; ic->interrupt_callback = int_cb; err = avformat_open_input(&ic, filename, NULL, NULL); if (err < 0) diff --git a/ffprobe.c b/ffprobe.c index b104390990d2f..17dc73294fe44 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -2575,6 +2575,14 @@ static int open_input_file(InputFile *ifile, const char *filename) AVDictionary **opts; int scan_all_pmts_set = 0; + fmt_ctx = avformat_alloc_context(); + if (!fmt_ctx) { + print_error(filename, AVERROR(ENOMEM)); + exit_program(1); + } + + fmt_ctx->flags |= AVFMT_FLAG_KEEP_SIDE_DATA; + if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) { av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE); scan_all_pmts_set = 1; diff --git a/libavformat/tests/seek.c b/libavformat/tests/seek.c index 7ed56ba4ef980..5cf3a123e33fb 100644 --- a/libavformat/tests/seek.c +++ b/libavformat/tests/seek.c @@ -67,6 +67,8 @@ int main(int argc, char **argv) int frame_count = 1; int duration = 4; + ic->flags |= AVFMT_FLAG_KEEP_SIDE_DATA; + for(i=2; i Date: Wed, 15 Mar 2017 07:37:11 +0800 Subject: [PATCH 1155/3374] avformat/hlsenc: fix duration wrong when no pkt duration when cannot get pkt duration, hlsenc segments duration will be set to 0, this patch can fix it. Signed-off-by: Steven Liu --- libavformat/hlsenc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index e2c021b754b03..e6c378df2e70b 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -1354,7 +1354,12 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) * st->time_base.num / st->time_base.den; hls->dpp = (double)(pkt->duration) * st->time_base.num / st->time_base.den; } else { - hls->duration += (double)(pkt->duration) * st->time_base.num / st->time_base.den; + if (pkt->duration) { + hls->duration += (double)(pkt->duration) * st->time_base.num / st->time_base.den; + } else { + av_log(s, AV_LOG_WARNING, "pkt->duration = 0, maybe the hls segment duration will not precise\n"); + hls->duration = (double)(pkt->pts - hls->end_pts) * st->time_base.num / st->time_base.den; + } } } From 1ade4d87bae8db3f2073c18eb322382ad7827bb9 Mon Sep 17 00:00:00 2001 From: Matthieu Bouron Date: Mon, 6 Feb 2017 17:14:57 +0100 Subject: [PATCH 1156/3374] lavc/h264dec: use OFFSET macro --- libavcodec/h264dec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 35598ea7cd759..9042169338dc3 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -1077,8 +1077,8 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data, #define OFFSET(x) offsetof(H264Context, x) #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM static const AVOption h264_options[] = { - {"is_avc", "is avc", offsetof(H264Context, is_avc), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, 0}, - {"nal_length_size", "nal_length_size", offsetof(H264Context, nal_length_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 4, 0}, + { "is_avc", "is avc", OFFSET(is_avc), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, 0 }, + { "nal_length_size", "nal_length_size", OFFSET(nal_length_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 4, 0 }, { "enable_er", "Enable error resilience on damaged frames (unsafe)", OFFSET(enable_er), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VD }, { NULL }, }; From 0052f3f527c4558d32b4f710063acb096493d99c Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Tue, 14 Mar 2017 22:53:43 +0800 Subject: [PATCH 1157/3374] avcodec/videotoolboxenc: add rc_max_bitrate control into videotoolbox add kVTCompressionPropertyKey_DataRateLimits support by rc_max_bitrate Reviewed-by: Rick Kern Signed-off-by: Steven Liu --- libavcodec/videotoolboxenc.c | 47 ++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c index 005f5d63257f4..4b8718c9aaf20 100644 --- a/libavcodec/videotoolboxenc.c +++ b/libavcodec/videotoolboxenc.c @@ -898,7 +898,14 @@ static int vtenc_create_encoder(AVCodecContext *avctx, { VTEncContext *vtctx = avctx->priv_data; SInt32 bit_rate = avctx->bit_rate; + SInt32 max_rate = avctx->rc_max_rate; CFNumberRef bit_rate_num; + CFNumberRef bytes_per_second; + CFNumberRef one_second; + CFArrayRef data_rate_limits; + int64_t bytes_per_second_value = 0; + int64_t one_second_value = 0; + void *nums[2]; int status = VTCompressionSessionCreate(kCFAllocatorDefault, avctx->width, @@ -938,6 +945,46 @@ static int vtenc_create_encoder(AVCodecContext *avctx, return AVERROR_EXTERNAL; } + bytes_per_second_value = max_rate >> 3; + bytes_per_second = CFNumberCreate(kCFAllocatorDefault, + kCFNumberSInt64Type, + &bytes_per_second_value); + if (!bytes_per_second) { + return AVERROR(ENOMEM); + } + one_second_value = 1; + one_second = CFNumberCreate(kCFAllocatorDefault, + kCFNumberSInt64Type, + &one_second_value); + if (!one_second) { + CFRelease(bytes_per_second); + return AVERROR(ENOMEM); + } + nums[0] = bytes_per_second; + nums[1] = one_second; + data_rate_limits = CFArrayCreate(kCFAllocatorDefault, + nums, + 2, + &kCFTypeArrayCallBacks); + + if (!data_rate_limits) { + CFRelease(bytes_per_second); + CFRelease(one_second); + return AVERROR(ENOMEM); + } + status = VTSessionSetProperty(vtctx->session, + kVTCompressionPropertyKey_DataRateLimits, + data_rate_limits); + + CFRelease(bytes_per_second); + CFRelease(one_second); + CFRelease(data_rate_limits); + + if (status) { + av_log(avctx, AV_LOG_ERROR, "Error setting max bitrate property: %d\n", status); + return AVERROR_EXTERNAL; + } + if (profile_level) { status = VTSessionSetProperty(vtctx->session, kVTCompressionPropertyKey_ProfileLevel, From 2f6661c940161e97c7d5a2275e398264b171e001 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 15 Mar 2017 22:23:00 +0100 Subject: [PATCH 1158/3374] doc: remove remaining legacy x11grab references --- doc/indevs.texi | 8 -------- 1 file changed, 8 deletions(-) diff --git a/doc/indevs.texi b/doc/indevs.texi index 54f270b0dce55..27cc3d5dc37f1 100644 --- a/doc/indevs.texi +++ b/doc/indevs.texi @@ -1305,9 +1305,6 @@ To enable this input device during configuration you need libxcb installed on your system. It will be automatically detected during configuration. -Alternatively, the configure option @option{--enable-x11grab} exists -for legacy Xlib users. - This device allows one to capture a region of an X11 display. The filename passed as input has the syntax: @@ -1395,11 +1392,6 @@ ffmpeg -f x11grab -follow_mouse centered -show_region 1 -framerate 25 -video_siz @item video_size Set the video frame size. Default value is @code{vga}. -@item use_shm -Use the MIT-SHM extension for shared memory. Default value is @code{1}. -It may be necessary to disable it for remote displays (legacy x11grab -only). - @item grab_x @item grab_y Set the grabbing region coordinates. They are expressed as offset from From b409d8d4a276490cd67255fd4230ea0954bd8c50 Mon Sep 17 00:00:00 2001 From: Ricardo Constantino Date: Wed, 15 Mar 2017 22:47:58 +0000 Subject: [PATCH 1159/3374] configure: libnpp is always nonfree, even with LGPL libnpp was erroneously grouped up with libfdk-aac and openssl to check if --enable-nonfree wasn't passed only with --enable-gpl in 9f28db47accb31bfec40a56dd2dc19ffd366a6be. The latter two are compatible with LGPL, libnpp is not. Signed-off-by: James Almer --- configure | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure b/configure index e72ee297def8d..ecf67d5910049 100755 --- a/configure +++ b/configure @@ -5173,7 +5173,8 @@ die_license_disabled_gpl() { map "die_license_disabled gpl" $EXTERNAL_LIBRARY_GPL_LIST $EXTERNAL_LIBRARY_GPLV3_LIST map "die_license_disabled version3" $EXTERNAL_LIBRARY_VERSION3_LIST $EXTERNAL_LIBRARY_GPLV3_LIST -enabled gpl && map "die_license_disabled_gpl nonfree" $EXTERNAL_LIBRARY_NONFREE_LIST $HWACCEL_LIBRARY_NONFREE_LIST +enabled gpl && map "die_license_disabled_gpl nonfree" $EXTERNAL_LIBRARY_NONFREE_LIST +map "die_license_disabled nonfree" $HWACCEL_LIBRARY_NONFREE_LIST enabled version3 && { enabled gpl && enable gplv3 || enable lgplv3; } From 45198477de19ccb00729b7eec07d81494f0353e0 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 13 Mar 2017 02:25:42 +0100 Subject: [PATCH 1160/3374] avcodec/simple_idct_template: Fix several integer overflows Benchmarks with START_TIMER indicate that the code is faster with unsigned, (that is with the patch), there was quite some fluctuation in the numbers so this may be just random Fixes: 811/clusterfuzz-testcase-6465493076541440 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/simple_idct_template.c | 36 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/libavcodec/simple_idct_template.c b/libavcodec/simple_idct_template.c index f5744e0a3946f..c669767761557 100644 --- a/libavcodec/simple_idct_template.c +++ b/libavcodec/simple_idct_template.c @@ -112,7 +112,7 @@ static inline void FUNC(idctRowCondDC_extrashift)(int16_t *row, int extra_shift) static inline void FUNC(idctRowCondDC)(int16_t *row, int extra_shift) #endif { - int a0, a1, a2, a3, b0, b1, b2, b3; + SUINT a0, a1, a2, a3, b0, b1, b2, b3; #if HAVE_FAST_64BIT #define ROW0_MASK (0xffffLL << 48 * HAVE_BIGENDIAN) @@ -187,14 +187,14 @@ static inline void FUNC(idctRowCondDC)(int16_t *row, int extra_shift) MAC(b3, -W1, row[7]); } - row[0] = (a0 + b0) >> (ROW_SHIFT + extra_shift); - row[7] = (a0 - b0) >> (ROW_SHIFT + extra_shift); - row[1] = (a1 + b1) >> (ROW_SHIFT + extra_shift); - row[6] = (a1 - b1) >> (ROW_SHIFT + extra_shift); - row[2] = (a2 + b2) >> (ROW_SHIFT + extra_shift); - row[5] = (a2 - b2) >> (ROW_SHIFT + extra_shift); - row[3] = (a3 + b3) >> (ROW_SHIFT + extra_shift); - row[4] = (a3 - b3) >> (ROW_SHIFT + extra_shift); + row[0] = (int)(a0 + b0) >> (ROW_SHIFT + extra_shift); + row[7] = (int)(a0 - b0) >> (ROW_SHIFT + extra_shift); + row[1] = (int)(a1 + b1) >> (ROW_SHIFT + extra_shift); + row[6] = (int)(a1 - b1) >> (ROW_SHIFT + extra_shift); + row[2] = (int)(a2 + b2) >> (ROW_SHIFT + extra_shift); + row[5] = (int)(a2 - b2) >> (ROW_SHIFT + extra_shift); + row[3] = (int)(a3 + b3) >> (ROW_SHIFT + extra_shift); + row[4] = (int)(a3 - b3) >> (ROW_SHIFT + extra_shift); } #define IDCT_COLS do { \ @@ -253,25 +253,25 @@ static inline void FUNC(idctSparseCol_extrashift)(int16_t *col) static inline void FUNC(idctSparseColPut)(pixel *dest, int line_size, int16_t *col) { - int a0, a1, a2, a3, b0, b1, b2, b3; + SUINT a0, a1, a2, a3, b0, b1, b2, b3; IDCT_COLS; - dest[0] = av_clip_pixel((a0 + b0) >> COL_SHIFT); + dest[0] = av_clip_pixel((int)(a0 + b0) >> COL_SHIFT); dest += line_size; - dest[0] = av_clip_pixel((a1 + b1) >> COL_SHIFT); + dest[0] = av_clip_pixel((int)(a1 + b1) >> COL_SHIFT); dest += line_size; - dest[0] = av_clip_pixel((a2 + b2) >> COL_SHIFT); + dest[0] = av_clip_pixel((int)(a2 + b2) >> COL_SHIFT); dest += line_size; - dest[0] = av_clip_pixel((a3 + b3) >> COL_SHIFT); + dest[0] = av_clip_pixel((int)(a3 + b3) >> COL_SHIFT); dest += line_size; - dest[0] = av_clip_pixel((a3 - b3) >> COL_SHIFT); + dest[0] = av_clip_pixel((int)(a3 - b3) >> COL_SHIFT); dest += line_size; - dest[0] = av_clip_pixel((a2 - b2) >> COL_SHIFT); + dest[0] = av_clip_pixel((int)(a2 - b2) >> COL_SHIFT); dest += line_size; - dest[0] = av_clip_pixel((a1 - b1) >> COL_SHIFT); + dest[0] = av_clip_pixel((int)(a1 - b1) >> COL_SHIFT); dest += line_size; - dest[0] = av_clip_pixel((a0 - b0) >> COL_SHIFT); + dest[0] = av_clip_pixel((int)(a0 - b0) >> COL_SHIFT); } static inline void FUNC(idctSparseColAdd)(pixel *dest, int line_size, From 58e9c7f4a2fdce4bc5531a618c142f27117c5145 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 14 Mar 2017 01:17:53 +0100 Subject: [PATCH 1161/3374] avcodec/wavpack: Fix multiple integer overflows Fixes: 839/clusterfuzz-testcase-4871084446842880 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/wavpack.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index bc94b27c04071..3d0b01f257c95 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -268,7 +268,7 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, } static inline int wv_get_value_integer(WavpackFrameContext *s, uint32_t *crc, - int S) + unsigned S) { unsigned bit; @@ -415,11 +415,11 @@ static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb, if (t > 0) { if (t > 8) { if (t & 1) { - A = 2 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]; - B = 2 * s->decorr[i].samplesB[0] - s->decorr[i].samplesB[1]; + A = 2U * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]; + B = 2U * s->decorr[i].samplesB[0] - s->decorr[i].samplesB[1]; } else { - A = (3 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]) >> 1; - B = (3 * s->decorr[i].samplesB[0] - s->decorr[i].samplesB[1]) >> 1; + A = (int)(3U * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]) >> 1; + B = (int)(3U * s->decorr[i].samplesB[0] - s->decorr[i].samplesB[1]) >> 1; } s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0]; s->decorr[i].samplesB[1] = s->decorr[i].samplesB[0]; @@ -488,7 +488,7 @@ static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb, pos = (pos + 1) & 7; if (s->joint) - L += (R -= (L >> 1)); + L += (unsigned)(R -= (unsigned)(L >> 1)); crc = (crc * 3 + L) * 3 + R; if (type == AV_SAMPLE_FMT_FLTP) { From cfa10e11be4c17fdff0c77cba7c0b3d6ea99acea Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 14 Mar 2017 01:34:14 +0100 Subject: [PATCH 1162/3374] avcodec/tiff: Check palette shift Fixes multiple runtime error: shift exponent 792 is too large for 32-bit type 'unsigned int' Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/tiff.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index 456da5142b9a8..0be7be75280b5 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -996,6 +996,11 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) bytestream2_skip(&pal_gb[2], count / 3 * off * 2); off = (type_sizes[type] - 1) << 3; + if (off > 31U) { + av_log(s->avctx, AV_LOG_ERROR, "palette shift %d is out of range\n", off); + return AVERROR_INVALIDDATA; + } + for (i = 0; i < count / 3; i++) { uint32_t p = 0xFF000000; p |= (ff_tget(&pal_gb[0], type, s->le) >> off) << 16; From 911417f0b34e611bf084319c5b5a4e4e630da940 Mon Sep 17 00:00:00 2001 From: Rostislav Pehlivanov Date: Mon, 6 Mar 2017 02:46:49 +0000 Subject: [PATCH 1163/3374] ffmpeg: don't use resample_lavr_opts That pointer isn't used by absolutely anything. Signed-off-by: Rostislav Pehlivanov Reviewed-by: Michael Niedermayer --- ffmpeg_filter.c | 1 - 1 file changed, 1 deletion(-) diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c index 6cf4204e2f8ec..5cc640d75dbc0 100644 --- a/ffmpeg_filter.c +++ b/ffmpeg_filter.c @@ -1020,7 +1020,6 @@ int configure_filtergraph(FilterGraph *fg) } if (strlen(args)) args[strlen(args) - 1] = '\0'; - fg->graph->resample_lavr_opts = av_strdup(args); e = av_dict_get(ost->encoder_opts, "threads", NULL, 0); if (e) From 4c8e528d19a37d796a9808908e5b5cb0ce039fb2 Mon Sep 17 00:00:00 2001 From: Matthieu Bouron Date: Fri, 27 Jan 2017 11:55:48 +0000 Subject: [PATCH 1164/3374] lavc/aarch64: add ff_simple_idct{,_add,_put}_neon functions --- libavcodec/aarch64/Makefile | 2 + libavcodec/aarch64/idct.h | 28 ++ libavcodec/aarch64/idctdsp_init_aarch64.c | 41 +++ libavcodec/aarch64/simple_idct_neon.S | 362 ++++++++++++++++++++++ libavcodec/idctdsp.c | 2 + libavcodec/idctdsp.h | 2 + 6 files changed, 437 insertions(+) create mode 100644 libavcodec/aarch64/idct.h create mode 100644 libavcodec/aarch64/idctdsp_init_aarch64.c create mode 100644 libavcodec/aarch64/simple_idct_neon.S diff --git a/libavcodec/aarch64/Makefile b/libavcodec/aarch64/Makefile index 37666b42cbcbb..104bc678024fe 100644 --- a/libavcodec/aarch64/Makefile +++ b/libavcodec/aarch64/Makefile @@ -36,6 +36,8 @@ NEON-OBJS-$(CONFIG_H264PRED) += aarch64/h264pred_neon.o NEON-OBJS-$(CONFIG_H264QPEL) += aarch64/h264qpel_neon.o \ aarch64/hpeldsp_neon.o NEON-OBJS-$(CONFIG_HPELDSP) += aarch64/hpeldsp_neon.o +NEON-OBJS-$(CONFIG_IDCTDSP) += aarch64/idctdsp_init_aarch64.o \ + aarch64/simple_idct_neon.o NEON-OBJS-$(CONFIG_MDCT) += aarch64/mdct_neon.o NEON-OBJS-$(CONFIG_MPEGAUDIODSP) += aarch64/mpegaudiodsp_neon.o diff --git a/libavcodec/aarch64/idct.h b/libavcodec/aarch64/idct.h new file mode 100644 index 0000000000000..05699c2286914 --- /dev/null +++ b/libavcodec/aarch64/idct.h @@ -0,0 +1,28 @@ +/* + * 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 + */ + +#ifndef AVCODEC_AARCH64_IDCT_H +#define AVCODEC_AARCH64_IDCT_H + +#include + +void ff_simple_idct_neon(int16_t *data); +void ff_simple_idct_put_neon(uint8_t *dest, int line_size, int16_t *data); +void ff_simple_idct_add_neon(uint8_t *dest, int line_size, int16_t *data); + +#endif /* AVCODEC_AARCH64_IDCT_H */ diff --git a/libavcodec/aarch64/idctdsp_init_aarch64.c b/libavcodec/aarch64/idctdsp_init_aarch64.c new file mode 100644 index 0000000000000..0406e6083041e --- /dev/null +++ b/libavcodec/aarch64/idctdsp_init_aarch64.c @@ -0,0 +1,41 @@ +/* + * ARM-NEON-optimized IDCT functions + * Copyright (c) 2008 Mans Rullgard + * Copyright (c) 2017 Matthieu Bouron + * + * 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 "libavutil/attributes.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/idctdsp.h" +#include "idct.h" + +av_cold void ff_idctdsp_init_aarch64(IDCTDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth) +{ + if (!avctx->lowres && !high_bit_depth) { + if (avctx->idct_algo == FF_IDCT_AUTO || + avctx->idct_algo == FF_IDCT_SIMPLEAUTO || + avctx->idct_algo == FF_IDCT_SIMPLENEON) { + c->idct_put = ff_simple_idct_put_neon; + c->idct_add = ff_simple_idct_add_neon; + c->idct = ff_simple_idct_neon; + c->perm_type = FF_IDCT_PERM_PARTTRANS; + } + } +} diff --git a/libavcodec/aarch64/simple_idct_neon.S b/libavcodec/aarch64/simple_idct_neon.S new file mode 100644 index 0000000000000..52273420f9f7f --- /dev/null +++ b/libavcodec/aarch64/simple_idct_neon.S @@ -0,0 +1,362 @@ +/* + * ARM NEON IDCT + * + * Copyright (c) 2008 Mans Rullgard + * Copyright (c) 2017 Matthieu Bouron + * + * Based on Simple IDCT + * Copyright (c) 2001 Michael Niedermayer + * + * 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 "libavutil/aarch64/asm.S" + +#define Z1 22725 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +#define Z2 21407 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +#define Z3 19266 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +#define Z4 16383 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +#define Z5 12873 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +#define Z6 8867 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +#define Z7 4520 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +#define Z4c ((1<<(COL_SHIFT-1))/Z4) +#define ROW_SHIFT 11 +#define COL_SHIFT 20 + +#define z1 v0.H[0] +#define z2 v0.H[1] +#define z3 v0.H[2] +#define z4 v0.H[3] +#define z5 v0.H[4] +#define z6 v0.H[5] +#define z7 v0.H[6] +#define z4c v0.H[7] + +const idct_coeff_neon, align=4 + .short Z1, Z2, Z3, Z4, Z5, Z6, Z7, Z4c +endconst + +.macro idct_start data + prfm pldl1keep, [\data] + mov x10, x30 + movrel x3, idct_coeff_neon + ld1 {v0.2D}, [x3] +.endm + +.macro idct_end + br x10 +.endm + +.macro smull1 a b c + smull \a, \b, \c +.endm + +.macro smlal1 a b c + smlal \a, \b, \c +.endm + +.macro smlsl1 a b c + smlsl \a, \b, \c +.endm + +.macro idct_col4_top y1 y2 y3 y4 i l + smull\i v7.4S, \y3\().\l, z2 + smull\i v16.4S, \y3\().\l, z6 + smull\i v17.4S, \y2\().\l, z1 + add v19.4S, v23.4S, v7.4S + smull\i v18.4S, \y2\().\l, z3 + add v20.4S, v23.4S, v16.4S + smull\i v5.4S, \y2\().\l, z5 + sub v21.4S, v23.4S, v16.4S + smull\i v6.4S, \y2\().\l, z7 + sub v22.4S, v23.4S, v7.4S + + smlal\i v17.4S, \y4\().\l, z3 + smlsl\i v18.4S, \y4\().\l, z7 + smlsl\i v5.4S, \y4\().\l, z1 + smlsl\i v6.4S, \y4\().\l, z5 +.endm + +.macro idct_row4_neon y1 y2 y3 y4 pass + ld1 {\y1\().2D-\y2\().2D}, [x2], #32 + movi v23.4S, #1<<2, lsl #8 + orr v5.16B, \y1\().16B, \y2\().16B + ld1 {\y3\().2D, \y4\().2D}, [x2], #32 + orr v6.16B, \y3\().16B, \y4\().16B + orr v5.16B, v5.16B, v6.16B + mov x3, v5.D[1] + smlal v23.4S, \y1\().4H, z4 + + idct_col4_top \y1 \y2 \y3 \y4 1 4H + + cmp x3, #0 + beq \pass\()f + + smull2 v7.4S, \y1\().8H, z4 + smlal2 v17.4S, \y2\().8H, z5 + smlsl2 v18.4S, \y2\().8H, z1 + smull2 v16.4S, \y3\().8H, z2 + smlal2 v5.4S, \y2\().8H, z7 + add v19.4S, v19.4S, v7.4S + sub v20.4S, v20.4S, v7.4S + sub v21.4S, v21.4S, v7.4S + add v22.4S, v22.4S, v7.4S + smlal2 v6.4S, \y2\().8H, z3 + smull2 v7.4S, \y3\().8H, z6 + smlal2 v17.4S, \y4\().8H, z7 + smlsl2 v18.4S, \y4\().8H, z5 + smlal2 v5.4S, \y4\().8H, z3 + smlsl2 v6.4S, \y4\().8H, z1 + add v19.4S, v19.4S, v7.4S + sub v20.4S, v20.4S, v16.4S + add v21.4S, v21.4S, v16.4S + sub v22.4S, v22.4S, v7.4S + +\pass: add \y3\().4S, v19.4S, v17.4S + add \y4\().4S, v20.4S, v18.4S + shrn \y1\().4H, \y3\().4S, #ROW_SHIFT + shrn \y2\().4H, \y4\().4S, #ROW_SHIFT + add v7.4S, v21.4S, v5.4S + add v16.4S, v22.4S, v6.4S + shrn \y3\().4H, v7.4S, #ROW_SHIFT + shrn \y4\().4H, v16.4S, #ROW_SHIFT + sub v22.4S, v22.4S, v6.4S + sub v19.4S, v19.4S, v17.4S + sub v21.4S, v21.4S, v5.4S + shrn2 \y1\().8H, v22.4S, #ROW_SHIFT + sub v20.4S, v20.4S, v18.4S + shrn2 \y2\().8H, v21.4S, #ROW_SHIFT + shrn2 \y3\().8H, v20.4S, #ROW_SHIFT + shrn2 \y4\().8H, v19.4S, #ROW_SHIFT + + trn1 v16.8H, \y1\().8H, \y2\().8H + trn2 v17.8H, \y1\().8H, \y2\().8H + trn1 v18.8H, \y3\().8H, \y4\().8H + trn2 v19.8H, \y3\().8H, \y4\().8H + trn1 \y1\().4S, v16.4S, v18.4S + trn1 \y2\().4S, v17.4S, v19.4S + trn2 \y3\().4S, v16.4S, v18.4S + trn2 \y4\().4S, v17.4S, v19.4S +.endm + +.macro declare_idct_col4_neon i l +function idct_col4_neon\i + dup v23.4H, z4c +.if \i == 1 + add v23.4H, v23.4H, v24.4H +.else + mov v5.D[0], v24.D[1] + add v23.4H, v23.4H, v5.4H +.endif + smull v23.4S, v23.4H, z4 + + idct_col4_top v24 v25 v26 v27 \i \l + + mov x4, v28.D[\i - 1] + mov x5, v29.D[\i - 1] + cmp x4, #0 + beq 1f + + smull\i v7.4S, v28.\l, z4 + add v19.4S, v19.4S, v7.4S + sub v20.4S, v20.4S, v7.4S + sub v21.4S, v21.4S, v7.4S + add v22.4S, v22.4S, v7.4S + +1: mov x4, v30.D[\i - 1] + cmp x5, #0 + beq 2f + + smlal\i v17.4S, v29.\l, z5 + smlsl\i v18.4S, v29.\l, z1 + smlal\i v5.4S, v29.\l, z7 + smlal\i v6.4S, v29.\l, z3 + +2: mov x5, v31.D[\i - 1] + cmp x4, #0 + beq 3f + + smull\i v7.4S, v30.\l, z6 + smull\i v16.4S, v30.\l, z2 + add v19.4S, v19.4S, v7.4S + sub v22.4S, v22.4S, v7.4S + sub v20.4S, v20.4S, v16.4S + add v21.4S, v21.4S, v16.4S + +3: cmp x5, #0 + beq 4f + + smlal\i v17.4S, v31.\l, z7 + smlsl\i v18.4S, v31.\l, z5 + smlal\i v5.4S, v31.\l, z3 + smlsl\i v6.4S, v31.\l, z1 + +4: addhn v7.4H, v19.4S, v17.4S + addhn2 v7.8H, v20.4S, v18.4S + subhn v18.4H, v20.4S, v18.4S + subhn2 v18.8H, v19.4S, v17.4S + + addhn v16.4H, v21.4S, v5.4S + addhn2 v16.8H, v22.4S, v6.4S + subhn v17.4H, v22.4S, v6.4S + subhn2 v17.8H, v21.4S, v5.4S + + ret +endfunc +.endm + +declare_idct_col4_neon 1 4H +declare_idct_col4_neon 2 8H + +function ff_simple_idct_put_neon, export=1 + idct_start x2 + + idct_row4_neon v24 v25 v26 v27 1 + idct_row4_neon v28 v29 v30 v31 2 + bl idct_col4_neon1 + + sqshrun v1.8B, v7.8H, #COL_SHIFT-16 + sqshrun2 v1.16B, v16.8H, #COL_SHIFT-16 + sqshrun v3.8B, v17.8H, #COL_SHIFT-16 + sqshrun2 v3.16B, v18.8H, #COL_SHIFT-16 + + bl idct_col4_neon2 + + sqshrun v2.8B, v7.8H, #COL_SHIFT-16 + sqshrun2 v2.16B, v16.8H, #COL_SHIFT-16 + sqshrun v4.8B, v17.8H, #COL_SHIFT-16 + sqshrun2 v4.16B, v18.8H, #COL_SHIFT-16 + + zip1 v16.4S, v1.4S, v2.4S + zip2 v17.4S, v1.4S, v2.4S + + st1 {v16.D}[0], [x0], x1 + st1 {v16.D}[1], [x0], x1 + + zip1 v18.4S, v3.4S, v4.4S + zip2 v19.4S, v3.4S, v4.4S + + st1 {v17.D}[0], [x0], x1 + st1 {v17.D}[1], [x0], x1 + st1 {v18.D}[0], [x0], x1 + st1 {v18.D}[1], [x0], x1 + st1 {v19.D}[0], [x0], x1 + st1 {v19.D}[1], [x0], x1 + + idct_end +endfunc + +function ff_simple_idct_add_neon, export=1 + idct_start x2 + + idct_row4_neon v24 v25 v26 v27 1 + idct_row4_neon v28 v29 v30 v31 2 + bl idct_col4_neon1 + + sshr v1.8H, V7.8H, #COL_SHIFT-16 + sshr v2.8H, v16.8H, #COL_SHIFT-16 + sshr v3.8H, v17.8H, #COL_SHIFT-16 + sshr v4.8H, v18.8H, #COL_SHIFT-16 + + bl idct_col4_neon2 + + sshr v7.8H, V7.8H, #COL_SHIFT-16 + sshr v16.8H, v16.8H, #COL_SHIFT-16 + sshr v17.8H, v17.8H, #COL_SHIFT-16 + sshr v18.8H, v18.8H, #COL_SHIFT-16 + + mov x9, x0 + ld1 {v19.D}[0], [x0], x1 + zip1 v23.2D, v1.2D, v7.2D + zip2 v24.2D, v1.2D, v7.2D + ld1 {v19.D}[1], [x0], x1 + zip1 v25.2D, v2.2D, v16.2D + zip2 v26.2D, v2.2D, v16.2D + ld1 {v20.D}[0], [x0], x1 + zip1 v27.2D, v3.2D, v17.2D + zip2 v28.2D, v3.2D, v17.2D + ld1 {v20.D}[1], [x0], x1 + zip1 v29.2D, v4.2D, v18.2D + zip2 v30.2D, v4.2D, v18.2D + ld1 {v21.D}[0], [x0], x1 + uaddw v23.8H, v23.8H, v19.8B + uaddw2 v24.8H, v24.8H, v19.16B + ld1 {v21.D}[1], [x0], x1 + sqxtun v23.8B, v23.8H + sqxtun2 v23.16B, v24.8H + ld1 {v22.D}[0], [x0], x1 + uaddw v24.8H, v25.8H, v20.8B + uaddw2 v25.8H, v26.8H, v20.16B + ld1 {v22.D}[1], [x0], x1 + sqxtun v24.8B, v24.8H + sqxtun2 v24.16B, v25.8H + st1 {v23.D}[0], [x9], x1 + uaddw v25.8H, v27.8H, v21.8B + uaddw2 v26.8H, v28.8H, v21.16B + st1 {v23.D}[1], [x9], x1 + sqxtun v25.8B, v25.8H + sqxtun2 v25.16B, v26.8H + st1 {v24.D}[0], [x9], x1 + uaddw v26.8H, v29.8H, v22.8B + uaddw2 v27.8H, v30.8H, v22.16B + st1 {v24.D}[1], [x9], x1 + sqxtun v26.8B, v26.8H + sqxtun2 v26.16B, v27.8H + st1 {v25.D}[0], [x9], x1 + st1 {v25.D}[1], [x9], x1 + st1 {v26.D}[0], [x9], x1 + st1 {v26.D}[1], [x9], x1 + + idct_end +endfunc + +function ff_simple_idct_neon, export=1 + idct_start x0 + + mov x2, x0 + idct_row4_neon v24 v25 v26 v27 1 + idct_row4_neon v28 v29 v30 v31 2 + add x2, x2, #-128 + bl idct_col4_neon1 + + sshr v1.8H, v7.8H, #COL_SHIFT-16 + sshr v2.8H, v16.8H, #COL_SHIFT-16 + sshr v3.8H, v17.8H, #COL_SHIFT-16 + sshr v4.8H, v18.8H, #COL_SHIFT-16 + + bl idct_col4_neon2 + + sshr v7.8H, v7.8H, #COL_SHIFT-16 + sshr v16.8H, v16.8H, #COL_SHIFT-16 + sshr v17.8H, v17.8H, #COL_SHIFT-16 + sshr v18.8H, v18.8H, #COL_SHIFT-16 + + zip1 v23.2D, v1.2D, v7.2D + zip2 v24.2D, v1.2D, v7.2D + st1 {v23.2D,V24.2D}, [x2], #32 + zip1 v25.2D, v2.2D, v16.2D + zip2 v26.2D, v2.2D, v16.2D + st1 {v25.2D,V26.2D}, [x2], #32 + zip1 v27.2D, v3.2D, v17.2D + zip2 v28.2D, v3.2D, v17.2D + st1 {v27.2D,V28.2D}, [x2], #32 + zip1 v29.2D, v4.2D, v18.2D + zip2 v30.2D, v4.2D, v18.2D + st1 {v29.2D,V30.2D}, [x2], #32 + + idct_end +endfunc diff --git a/libavcodec/idctdsp.c b/libavcodec/idctdsp.c index 63e9b5216b0b1..37f4640f0d889 100644 --- a/libavcodec/idctdsp.c +++ b/libavcodec/idctdsp.c @@ -297,6 +297,8 @@ av_cold void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx) if (CONFIG_MPEG4_DECODER && avctx->idct_algo == FF_IDCT_XVID) ff_xvid_idct_init(c, avctx); + if (ARCH_AARCH64) + ff_idctdsp_init_aarch64(c, avctx, high_bit_depth); if (ARCH_ALPHA) ff_idctdsp_init_alpha(c, avctx, high_bit_depth); if (ARCH_ARM) diff --git a/libavcodec/idctdsp.h b/libavcodec/idctdsp.h index b180a6762a7ef..e449be310f56e 100644 --- a/libavcodec/idctdsp.h +++ b/libavcodec/idctdsp.h @@ -100,6 +100,8 @@ extern void (*ff_add_pixels_clamped)(const int16_t *block, uint8_t *pixels, ptrd void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx); +void ff_idctdsp_init_aarch64(IDCTDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth); void ff_idctdsp_init_alpha(IDCTDSPContext *c, AVCodecContext *avctx, unsigned high_bit_depth); void ff_idctdsp_init_arm(IDCTDSPContext *c, AVCodecContext *avctx, From 0c6105dde0c42bc64c93e7e7fbf286869c0bffa2 Mon Sep 17 00:00:00 2001 From: Matthieu Bouron Date: Thu, 16 Feb 2017 12:34:53 +0000 Subject: [PATCH 1165/3374] lavc/tests/dct/aarch64: add ff_simple_idct_neon test --- libavcodec/tests/aarch64/dct.c | 30 ++++++++++++++++++++++++++++++ libavcodec/tests/dct.c | 4 +++- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 libavcodec/tests/aarch64/dct.c diff --git a/libavcodec/tests/aarch64/dct.c b/libavcodec/tests/aarch64/dct.c new file mode 100644 index 0000000000000..032a9638f6287 --- /dev/null +++ b/libavcodec/tests/aarch64/dct.c @@ -0,0 +1,30 @@ +/* + * 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 "config.h" + +#include "libavcodec/aarch64/idct.h" + +static const struct algo fdct_tab_arch[] = { + { 0 } +}; + +static const struct algo idct_tab_arch[] = { + { "SIMPLE-NEON", ff_simple_idct_neon, FF_IDCT_PERM_PARTTRANS, AV_CPU_FLAG_NEON }, + { 0 } +}; diff --git a/libavcodec/tests/dct.c b/libavcodec/tests/dct.c index 5303fdff8fd0d..4f0e0d958eb80 100644 --- a/libavcodec/tests/dct.c +++ b/libavcodec/tests/dct.c @@ -94,7 +94,9 @@ static const struct algo idct_tab[] = { #endif /* CONFIG_MPEG4_DECODER */ }; -#if ARCH_ARM +#if ARCH_AARCH64 +#include "aarch64/dct.c" +#elif ARCH_ARM #include "arm/dct.c" #elif ARCH_PPC #include "ppc/dct.c" From bbc8f3d20e09ab238e345a02ed983434d2efe633 Mon Sep 17 00:00:00 2001 From: Alexis Ballier Date: Sat, 11 Mar 2017 20:18:54 +0100 Subject: [PATCH 1166/3374] lavf/vf_framerate: Fix frame leak when increasing framerate. Signed-off-by: Michael Niedermayer --- libavfilter/vf_framerate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_framerate.c b/libavfilter/vf_framerate.c index 237a4873b3562..b4a74f7f7df71 100644 --- a/libavfilter/vf_framerate.c +++ b/libavfilter/vf_framerate.c @@ -526,7 +526,7 @@ static av_cold void uninit(AVFilterContext *ctx) FrameRateContext *s = ctx->priv; int i; - for (i = s->frst + 1; i < s->last; i++) { + for (i = s->frst; i < s->last; i++) { if (s->srce[i] && (s->srce[i] != s->srce[i + 1])) av_frame_free(&s->srce[i]); } From 21bed3c981d17b1b5dcb1eb995075bb9ec850563 Mon Sep 17 00:00:00 2001 From: Alexis Ballier Date: Sat, 11 Mar 2017 20:18:55 +0100 Subject: [PATCH 1167/3374] fate: Add vf_framerate test. Signed-off-by: Michael Niedermayer --- tests/fate/filter-video.mak | 4 ++++ tests/ref/fate/filter-framerate-down | 6 ++++++ tests/ref/fate/filter-framerate-up | 15 +++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 tests/ref/fate/filter-framerate-down create mode 100644 tests/ref/fate/filter-framerate-up diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak index c57c9c7d1808e..97c5e6c547ce2 100644 --- a/tests/fate/filter-video.mak +++ b/tests/fate/filter-video.mak @@ -78,6 +78,10 @@ fate-filter-lavd-scalenorm: tests/data/filtergraphs/scalenorm fate-filter-lavd-scalenorm: CMD = framecrc -f lavfi -graph_file $(TARGET_PATH)/tests/data/filtergraphs/scalenorm -i dummy +FATE_FILTER-$(call ALLYES FRAMERATE_FILTER TESTSRC2_FILTER) += fate-filter-framerate-up fate-filter-framerate-down +fate-filter-framerate-up: CMD = framecrc -lavfi testsrc2=r=2:d=10,framerate=fps=10 -t 1 +fate-filter-framerate-down: CMD = framecrc -lavfi testsrc2=r=2:d=10,framerate=fps=1 -t 1 + FATE_FILTER_VSYNTH-$(CONFIG_BOXBLUR_FILTER) += fate-filter-boxblur fate-filter-boxblur: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf boxblur=2:1 diff --git a/tests/ref/fate/filter-framerate-down b/tests/ref/fate/filter-framerate-down new file mode 100644 index 0000000000000..4eab7aab85f94 --- /dev/null +++ b/tests/ref/fate/filter-framerate-down @@ -0,0 +1,6 @@ +#tb 0: 1/1 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 320x240 +#sar 0: 1/1 +0, 0, 0, 1, 115200, 0x3744b3ed diff --git a/tests/ref/fate/filter-framerate-up b/tests/ref/fate/filter-framerate-up new file mode 100644 index 0000000000000..b2af9cb879df5 --- /dev/null +++ b/tests/ref/fate/filter-framerate-up @@ -0,0 +1,15 @@ +#tb 0: 1/10 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 320x240 +#sar 0: 1/1 +0, 0, 0, 1, 115200, 0x3744b3ed +0, 1, 1, 1, 115200, 0xc44bdc65 +0, 2, 2, 1, 115200, 0xa17f0d74 +0, 3, 3, 1, 115200, 0xb0c83274 +0, 4, 4, 1, 115200, 0x232d6368 +0, 5, 5, 1, 115200, 0x6e318ba0 +0, 6, 6, 1, 115200, 0x247e846e +0, 7, 7, 1, 115200, 0x89e27599 +0, 8, 8, 1, 115200, 0x31c5704e +0, 9, 9, 1, 115200, 0x97e45fec From 2898bc522da6adebda5cbbd9036defe22e3b9bcf Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 15 Mar 2017 02:58:16 +0100 Subject: [PATCH 1168/3374] avcodec/h264idct_template: fix multiple runtime error: signed integer overflow Fixes: 857/clusterfuzz-testcase-5319093760557056 Benchmark changes from 335->333 (so if its not a random fluctuation then it would be faster) Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/h264idct_template.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavcodec/h264idct_template.c b/libavcodec/h264idct_template.c index c62716090cd6e..229a9ac36bcf2 100644 --- a/libavcodec/h264idct_template.c +++ b/libavcodec/h264idct_template.c @@ -304,7 +304,7 @@ void FUNCC(ff_h264_chroma422_dc_dequant_idct)(int16_t *_block, int qmul){ void FUNCC(ff_h264_chroma_dc_dequant_idct)(int16_t *_block, int qmul){ const int stride= 16*2; const int xStride= 16; - int a,b,c,d,e; + SUINT a,b,c,d,e; dctcoef *block = (dctcoef*)_block; a= block[stride*0 + xStride*0]; @@ -317,8 +317,8 @@ void FUNCC(ff_h264_chroma_dc_dequant_idct)(int16_t *_block, int qmul){ b= c-d; c= c+d; - block[stride*0 + xStride*0]= ((a+c)*qmul) >> 7; - block[stride*0 + xStride*1]= ((e+b)*qmul) >> 7; - block[stride*1 + xStride*0]= ((a-c)*qmul) >> 7; - block[stride*1 + xStride*1]= ((e-b)*qmul) >> 7; + block[stride*0 + xStride*0]= (int)((a+c)*qmul) >> 7; + block[stride*0 + xStride*1]= (int)((e+b)*qmul) >> 7; + block[stride*1 + xStride*0]= (int)((a-c)*qmul) >> 7; + block[stride*1 + xStride*1]= (int)((e-b)*qmul) >> 7; } From a3a408259912e6d9337837c5d63c4b826778530f Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 15 Mar 2017 03:48:59 +0100 Subject: [PATCH 1169/3374] avcodec/h264_cabac: Fix runtime error: negation of -2147483648 cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself Fixes: 858/clusterfuzz-testcase-5168477042114560 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/h264_cabac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c index 17a4bdadd692d..a1a16daafa90d 100644 --- a/libavcodec/h264_cabac.c +++ b/libavcodec/h264_cabac.c @@ -1725,7 +1725,7 @@ decode_cabac_residual_internal(const H264Context *h, H264SliceContext *sl, ((type*)block)[j] = (get_cabac_bypass_sign( CC, -qmul[j]) + 32) >> 6; \ } \ } else { \ - int coeff_abs = 2; \ + unsigned coeff_abs = 2; \ ctx = coeff_abs_levelgt1_ctx[is_dc && chroma422][node_ctx] + abs_level_m1_ctx_base; \ node_ctx = coeff_abs_level_transition[1][node_ctx]; \ \ From 1f7eb216b085cfd4f18f328182cabe3f89093edd Mon Sep 17 00:00:00 2001 From: Muhammad Faiz Date: Mon, 13 Mar 2017 20:33:03 +0700 Subject: [PATCH 1170/3374] swresample/options: enable linear_interp and exact_rational by default better quality without speedloss Signed-off-by: Muhammad Faiz --- doc/resampler.texi | 5 +- libswresample/options.c | 4 +- tests/fate/libswresample.mak | 189 +++++++++++++++++++++++++++++++++-- tests/ref/acodec/s302m | 6 +- tests/ref/lavf/dv_fmt | 8 +- tests/ref/lavf/gxf | 8 +- tests/ref/lavf/mxf | 12 +-- 7 files changed, 201 insertions(+), 31 deletions(-) diff --git a/doc/resampler.texi b/doc/resampler.texi index d72677c9159b5..5ed3f4377a2ae 100644 --- a/doc/resampler.texi +++ b/doc/resampler.texi @@ -132,12 +132,13 @@ For swr only, set resampling phase shift, default value is 10, and must be in the interval [0,30]. @item linear_interp -Use linear interpolation if set to 1, default value is 0. +Use linear interpolation when enabled (the default). Disable it if you want +to preserve speed instead of quality when exact_rational fails. @item exact_rational For swr only, when enabled, try to use exact phase_count based on input and output sample rate. However, if it is larger than @code{1 << phase_shift}, -the phase_count will be @code{1 << phase_shift} as fallback. Default is disabled. +the phase_count will be @code{1 << phase_shift} as fallback. Default is enabled. @item cutoff Set cutoff frequency (swr: 6dB point; soxr: 0dB point) ratio; must be a float diff --git a/libswresample/options.c b/libswresample/options.c index 4abf5e05189a8..00d4f7c1c9016 100644 --- a/libswresample/options.c +++ b/libswresample/options.c @@ -84,8 +84,8 @@ static const AVOption options[]={ {"filter_size" , "set swr resampling filter size", OFFSET(filter_size) , AV_OPT_TYPE_INT , {.i64=32 }, 0 , INT_MAX , PARAM }, {"phase_shift" , "set swr resampling phase shift", OFFSET(phase_shift) , AV_OPT_TYPE_INT , {.i64=10 }, 0 , 24 , PARAM }, -{"linear_interp" , "enable linear interpolation" , OFFSET(linear_interp) , AV_OPT_TYPE_BOOL , {.i64=0 }, 0 , 1 , PARAM }, -{"exact_rational" , "enable exact rational" , OFFSET(exact_rational) , AV_OPT_TYPE_BOOL , {.i64=0 }, 0 , 1 , PARAM }, +{"linear_interp" , "enable linear interpolation" , OFFSET(linear_interp) , AV_OPT_TYPE_BOOL , {.i64=1 }, 0 , 1 , PARAM }, +{"exact_rational" , "enable exact rational" , OFFSET(exact_rational) , AV_OPT_TYPE_BOOL , {.i64=1 }, 0 , 1 , PARAM }, {"cutoff" , "set cutoff frequency ratio" , OFFSET(cutoff) , AV_OPT_TYPE_DOUBLE,{.dbl=0. }, 0 , 1 , PARAM }, /* duplicate option in order to work with avconv */ diff --git a/tests/fate/libswresample.mak b/tests/fate/libswresample.mak index d9e0fa9c03143..4681a5c72c434 100644 --- a/tests/fate/libswresample.mak +++ b/tests/fate/libswresample.mak @@ -11,10 +11,11 @@ SAMPLERATES_LITE = 8000 44100 48000 SAMPLERATES_NN = 8000 44100 +#note that the default is ARESAMPLE_EXACT_LIN define ARESAMPLE FATE_SWR_RESAMPLE += fate-swr-resample-$(3)-$(1)-$(2) fate-swr-resample-$(3)-$(1)-$(2): tests/data/asynth-$(1)-1.wav -fate-swr-resample-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-$(1)-1.wav -af atrim=end_sample=10240,aresample=$(2):internal_sample_fmt=$(3),aformat=$(3),aresample=$(1):internal_sample_fmt=$(3) -f wav -acodec pcm_s16le - +fate-swr-resample-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-$(1)-1.wav -af atrim=end_sample=10240,aresample=$(2):internal_sample_fmt=$(3):exact_rational=0:linear_interp=0,aformat=$(3),aresample=$(1):internal_sample_fmt=$(3):exact_rational=0:linear_interp=0 -f wav -acodec pcm_s16le - fate-swr-resample-$(3)-$(1)-$(2): CMP = stddev fate-swr-resample-$(3)-$(1)-$(2): CMP_UNIT = $(5) @@ -270,7 +271,7 @@ fate-swr-resample-s32p-96000-8000: SIZE_TOLERANCE = 1152000 - 20496 define ARESAMPLE_LIN FATE_SWR_RESAMPLE += fate-swr-resample_lin-$(3)-$(1)-$(2) fate-swr-resample_lin-$(3)-$(1)-$(2): tests/data/asynth-$(1)-1.wav -fate-swr-resample_lin-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-$(1)-1.wav -af atrim=end_sample=10240,aresample=$(2):linear_interp=1:internal_sample_fmt=$(3),aformat=$(3),aresample=$(1):linear_interp=1:internal_sample_fmt=$(3) -f wav -acodec pcm_s16le - +fate-swr-resample_lin-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-$(1)-1.wav -af atrim=end_sample=10240,aresample=$(2):linear_interp=1:exact_rational=0:internal_sample_fmt=$(3),aformat=$(3),aresample=$(1):linear_interp=1:exact_rational=0:internal_sample_fmt=$(3) -f wav -acodec pcm_s16le - fate-swr-resample_lin-$(3)-$(1)-$(2): CMP = stddev fate-swr-resample_lin-$(3)-$(1)-$(2): CMP_UNIT = $(5) @@ -335,7 +336,7 @@ fate-swr-resample_lin-dblp-48000-44100: SIZE_TOLERANCE = 576000 - 20480 define ARESAMPLE_NN FATE_SWR_RESAMPLE += fate-swr-resample_nn-$(3)-$(1)-$(2) fate-swr-resample_nn-$(3)-$(1)-$(2): tests/data/asynth-$(1)-1.wav -fate-swr-resample_nn-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-$(1)-1.wav -af atrim=end_sample=10240,aresample=$(2):filter_size=1:phase_shift=0:internal_sample_fmt=$(3),aformat=$(3),aresample=$(1):internal_sample_fmt=$(3) -f wav -acodec pcm_s16le - +fate-swr-resample_nn-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-$(1)-1.wav -af atrim=end_sample=10240,aresample=$(2):filter_size=1:phase_shift=0:linear_interp=0:internal_sample_fmt=$(3),aformat=$(3),aresample=$(1):linear_interp=0:exact_rational=0:internal_sample_fmt=$(3) -f wav -acodec pcm_s16le - fate-swr-resample_nn-$(3)-$(1)-$(2): CMP = stddev fate-swr-resample_nn-$(3)-$(1)-$(2): CMP_UNIT = $(5) @@ -358,7 +359,7 @@ fate-swr-resample_nn-s16p-8000-44100: SIZE_TOLERANCE = 96000 - 20480 define ARESAMPLE_ASYNC FATE_SWR_RESAMPLE += fate-swr-resample_async-$(3)-$(1)-$(2) fate-swr-resample_async-$(3)-$(1)-$(2): tests/data/asynth-$(1)-1.wav -fate-swr-resample_async-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-$(1)-1.wav -af atrim=end_sample=10240,asetpts=PTS+random\(0\)*200-100,aresample=$(2):async=50:min_hard_comp=0.100000:first_pts=0:internal_sample_fmt=$(3),aformat=$(3),aresample=$(1):internal_sample_fmt=$(3) -f wav -acodec pcm_s16le - +fate-swr-resample_async-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-$(1)-1.wav -af atrim=end_sample=10240,asetpts=PTS+random\(0\)*200-100,aresample=$(2):async=50:min_hard_comp=0.100000:first_pts=0:linear_interp=0:exact_rational=0:internal_sample_fmt=$(3),aformat=$(3),aresample=$(1):linear_interp=0:exact_rational=0:internal_sample_fmt=$(3) -f wav -acodec pcm_s16le - fate-swr-resample_async-$(3)-$(1)-$(2): CMP = stddev fate-swr-resample_async-$(3)-$(1)-$(2): CMP_UNIT = $(5) @@ -381,7 +382,7 @@ fate-swr-resample_async-s16p-8000-44100: SIZE_TOLERANCE = 96000 - 20344 define ARESAMPLE_EXACT FATE_SWR_RESAMPLE += fate-swr-resample_exact-$(3)-$(1)-$(2) fate-swr-resample_exact-$(3)-$(1)-$(2): tests/data/asynth-$(1)-1.wav -fate-swr-resample_exact-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-$(1)-1.wav -af atrim=end_sample=10240,aresample=$(2):internal_sample_fmt=$(3):exact_rational=on,aformat=$(3),aresample=$(1):internal_sample_fmt=$(3):exact_rational=on -f wav -acodec pcm_s16le - +fate-swr-resample_exact-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-$(1)-1.wav -af atrim=end_sample=10240,aresample=$(2):internal_sample_fmt=$(3):exact_rational=on:linear_interp=0,aformat=$(3),aresample=$(1):internal_sample_fmt=$(3):exact_rational=on:linear_interp=0 -f wav -acodec pcm_s16le - fate-swr-resample_exact-$(3)-$(1)-$(2): CMP = stddev fate-swr-resample_exact-$(3)-$(1)-$(2): CMP_UNIT = $(5) @@ -632,7 +633,7 @@ fate-swr-resample_exact-s32p-96000-8000: SIZE_TOLERANCE = 1152000 - 20496 define ARESAMPLE_EXACT_ASYNC FATE_SWR_RESAMPLE += fate-swr-resample_exact_async-$(3)-$(1)-$(2) fate-swr-resample_exact_async-$(3)-$(1)-$(2): tests/data/asynth-$(1)-1.wav -fate-swr-resample_exact_async-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-$(1)-1.wav -af atrim=end_sample=10240,asetpts=PTS+random\(0\)*200-100,aresample=$(2):async=50:min_hard_comp=0.100000:first_pts=0:internal_sample_fmt=$(3):exact_rational=on,aformat=$(3),aresample=$(1):internal_sample_fmt=$(3):exact_rational=on -f wav -acodec pcm_s16le - +fate-swr-resample_exact_async-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-$(1)-1.wav -af atrim=end_sample=10240,asetpts=PTS+random\(0\)*200-100,aresample=$(2):async=50:min_hard_comp=0.100000:first_pts=0:internal_sample_fmt=$(3):exact_rational=on:linear_interp=0,aformat=$(3),aresample=$(1):internal_sample_fmt=$(3):exact_rational=on:linear_interp=0 -f wav -acodec pcm_s16le - fate-swr-resample_exact_async-$(3)-$(1)-$(2): CMP = stddev fate-swr-resample_exact_async-$(3)-$(1)-$(2): CMP_UNIT = $(5) @@ -795,6 +796,174 @@ fate-swr-resample_exact_lin-s32p-8000-44100: SIZE_TOLERANCE = 96000 - 20480 fate-swr-resample_exact_lin-s32p-8000-48000: CMP_TARGET = 14.52 fate-swr-resample_exact_lin-s32p-8000-48000: SIZE_TOLERANCE = 96000 - 20480 +fate-swr-resample_exact_lin-dblp-2626-44100: CMP_TARGET = 1352.60 +fate-swr-resample_exact_lin-dblp-2626-44100: SIZE_TOLERANCE = 31512 - 20480 + +fate-swr-resample_exact_lin-dblp-2626-48000: CMP_TARGET = 1352.62 +fate-swr-resample_exact_lin-dblp-2626-48000: SIZE_TOLERANCE = 31512 - 20480 + +fate-swr-resample_exact_lin-dblp-2626-8000: CMP_TARGET = 1352.49 +fate-swr-resample_exact_lin-dblp-2626-8000: SIZE_TOLERANCE = 31512 - 20480 + +fate-swr-resample_exact_lin-dblp-2626-96000: CMP_TARGET = 1352.62 +fate-swr-resample_exact_lin-dblp-2626-96000: SIZE_TOLERANCE = 31512 - 20480 + +fate-swr-resample_exact_lin-dblp-44100-2626: CMP_TARGET = 185.49 +fate-swr-resample_exact_lin-dblp-44100-2626: SIZE_TOLERANCE = 529200 - 20490 + +fate-swr-resample_exact_lin-dblp-44100-96000: CMP_TARGET = 11.45 +fate-swr-resample_exact_lin-dblp-44100-96000: SIZE_TOLERANCE = 529200 - 20482 + +fate-swr-resample_exact_lin-dblp-48000-2626: CMP_TARGET = 456.50 +fate-swr-resample_exact_lin-dblp-48000-2626: SIZE_TOLERANCE = 576000 - 20510 + +fate-swr-resample_exact_lin-dblp-48000-96000: CMP_TARGET = 0.47 +fate-swr-resample_exact_lin-dblp-48000-96000: SIZE_TOLERANCE = 576000 - 20480 + +fate-swr-resample_exact_lin-dblp-8000-2626: CMP_TARGET = 2503.28 +fate-swr-resample_exact_lin-dblp-8000-2626: SIZE_TOLERANCE = 96000 - 20480 + +fate-swr-resample_exact_lin-dblp-8000-96000: CMP_TARGET = 13.62 +fate-swr-resample_exact_lin-dblp-8000-96000: SIZE_TOLERANCE = 96000 - 20480 + +fate-swr-resample_exact_lin-dblp-96000-2626: CMP_TARGET = 675.02 +fate-swr-resample_exact_lin-dblp-96000-2626: SIZE_TOLERANCE = 1152000 - 20474 + +fate-swr-resample_exact_lin-dblp-96000-44100: CMP_TARGET = 1.24 +fate-swr-resample_exact_lin-dblp-96000-44100: SIZE_TOLERANCE = 1152000 - 20480 + +fate-swr-resample_exact_lin-dblp-96000-48000: CMP_TARGET = 0.99 +fate-swr-resample_exact_lin-dblp-96000-48000: SIZE_TOLERANCE = 1152000 - 20480 + +fate-swr-resample_exact_lin-dblp-96000-8000: CMP_TARGET = 58.52 +fate-swr-resample_exact_lin-dblp-96000-8000: SIZE_TOLERANCE = 1152000 - 20496 + +fate-swr-resample_exact_lin-fltp-2626-44100: CMP_TARGET = 1352.60 +fate-swr-resample_exact_lin-fltp-2626-44100: SIZE_TOLERANCE = 31512 - 20480 + +fate-swr-resample_exact_lin-fltp-2626-48000: CMP_TARGET = 1352.62 +fate-swr-resample_exact_lin-fltp-2626-48000: SIZE_TOLERANCE = 31512 - 20480 + +fate-swr-resample_exact_lin-fltp-2626-8000: CMP_TARGET = 1352.49 +fate-swr-resample_exact_lin-fltp-2626-8000: SIZE_TOLERANCE = 31512 - 20480 + +fate-swr-resample_exact_lin-fltp-2626-96000: CMP_TARGET = 1352.62 +fate-swr-resample_exact_lin-fltp-2626-96000: SIZE_TOLERANCE = 31512 - 20480 + +fate-swr-resample_exact_lin-fltp-44100-2626: CMP_TARGET = 185.49 +fate-swr-resample_exact_lin-fltp-44100-2626: SIZE_TOLERANCE = 529200 - 20490 + +fate-swr-resample_exact_lin-fltp-44100-96000: CMP_TARGET = 11.45 +fate-swr-resample_exact_lin-fltp-44100-96000: SIZE_TOLERANCE = 529200 - 20482 + +fate-swr-resample_exact_lin-fltp-48000-2626: CMP_TARGET = 456.50 +fate-swr-resample_exact_lin-fltp-48000-2626: SIZE_TOLERANCE = 576000 - 20510 + +fate-swr-resample_exact_lin-fltp-48000-96000: CMP_TARGET = 0.47 +fate-swr-resample_exact_lin-fltp-48000-96000: SIZE_TOLERANCE = 576000 - 20480 + +fate-swr-resample_exact_lin-fltp-8000-2626: CMP_TARGET = 2503.28 +fate-swr-resample_exact_lin-fltp-8000-2626: SIZE_TOLERANCE = 96000 - 20480 + +fate-swr-resample_exact_lin-fltp-8000-96000: CMP_TARGET = 13.62 +fate-swr-resample_exact_lin-fltp-8000-96000: SIZE_TOLERANCE = 96000 - 20480 + +fate-swr-resample_exact_lin-fltp-96000-2626: CMP_TARGET = 675.02 +fate-swr-resample_exact_lin-fltp-96000-2626: SIZE_TOLERANCE = 1152000 - 20474 + +fate-swr-resample_exact_lin-fltp-96000-44100: CMP_TARGET = 1.23 +fate-swr-resample_exact_lin-fltp-96000-44100: SIZE_TOLERANCE = 1152000 - 20480 + +fate-swr-resample_exact_lin-fltp-96000-48000: CMP_TARGET = 0.99 +fate-swr-resample_exact_lin-fltp-96000-48000: SIZE_TOLERANCE = 1152000 - 20480 + +fate-swr-resample_exact_lin-fltp-96000-8000: CMP_TARGET = 58.52 +fate-swr-resample_exact_lin-fltp-96000-8000: SIZE_TOLERANCE = 1152000 - 20496 + +fate-swr-resample_exact_lin-s16p-2626-44100: CMP_TARGET = 1392.93 +fate-swr-resample_exact_lin-s16p-2626-44100: SIZE_TOLERANCE = 31512 - 20480 + +fate-swr-resample_exact_lin-s16p-2626-48000: CMP_TARGET = 1392.97 +fate-swr-resample_exact_lin-s16p-2626-48000: SIZE_TOLERANCE = 31512 - 20480 + +fate-swr-resample_exact_lin-s16p-2626-8000: CMP_TARGET = 1393.28 +fate-swr-resample_exact_lin-s16p-2626-8000: SIZE_TOLERANCE = 31512 - 20480 + +fate-swr-resample_exact_lin-s16p-2626-96000: CMP_TARGET = 1393.04 +fate-swr-resample_exact_lin-s16p-2626-96000: SIZE_TOLERANCE = 31512 - 20480 + +fate-swr-resample_exact_lin-s16p-44100-2626: CMP_TARGET = 185.51 +fate-swr-resample_exact_lin-s16p-44100-2626: SIZE_TOLERANCE = 529200 - 20490 + +fate-swr-resample_exact_lin-s16p-44100-96000: CMP_TARGET = 11.46 +fate-swr-resample_exact_lin-s16p-44100-96000: SIZE_TOLERANCE = 529200 - 20482 + +fate-swr-resample_exact_lin-s16p-48000-2626: CMP_TARGET = 456.56 +fate-swr-resample_exact_lin-s16p-48000-2626: SIZE_TOLERANCE = 576000 - 20510 + +fate-swr-resample_exact_lin-s16p-48000-96000: CMP_TARGET = 0.73 +fate-swr-resample_exact_lin-s16p-48000-96000: SIZE_TOLERANCE = 576000 - 20480 + +fate-swr-resample_exact_lin-s16p-8000-2626: CMP_TARGET = 2503.28 +fate-swr-resample_exact_lin-s16p-8000-2626: SIZE_TOLERANCE = 96000 - 20480 + +fate-swr-resample_exact_lin-s16p-8000-96000: CMP_TARGET = 13.65 +fate-swr-resample_exact_lin-s16p-8000-96000: SIZE_TOLERANCE = 96000 - 20480 + +fate-swr-resample_exact_lin-s16p-96000-2626: CMP_TARGET = 675.07 +fate-swr-resample_exact_lin-s16p-96000-2626: SIZE_TOLERANCE = 1152000 - 20474 + +fate-swr-resample_exact_lin-s16p-96000-44100: CMP_TARGET = 1.44 +fate-swr-resample_exact_lin-s16p-96000-44100: SIZE_TOLERANCE = 1152000 - 20480 + +fate-swr-resample_exact_lin-s16p-96000-48000: CMP_TARGET = 1.12 +fate-swr-resample_exact_lin-s16p-96000-48000: SIZE_TOLERANCE = 1152000 - 20480 + +fate-swr-resample_exact_lin-s16p-96000-8000: CMP_TARGET = 58.56 +fate-swr-resample_exact_lin-s16p-96000-8000: SIZE_TOLERANCE = 1152000 - 20496 + +fate-swr-resample_exact_lin-s32p-2626-44100: CMP_TARGET = 1392.95 +fate-swr-resample_exact_lin-s32p-2626-44100: SIZE_TOLERANCE = 31512 - 20480 + +fate-swr-resample_exact_lin-s32p-2626-48000: CMP_TARGET = 1392.98 +fate-swr-resample_exact_lin-s32p-2626-48000: SIZE_TOLERANCE = 31512 - 20480 + +fate-swr-resample_exact_lin-s32p-2626-8000: CMP_TARGET = 1393.29 +fate-swr-resample_exact_lin-s32p-2626-8000: SIZE_TOLERANCE = 31512 - 20480 + +fate-swr-resample_exact_lin-s32p-2626-96000: CMP_TARGET = 1392.96 +fate-swr-resample_exact_lin-s32p-2626-96000: SIZE_TOLERANCE = 31512 - 20480 + +fate-swr-resample_exact_lin-s32p-44100-2626: CMP_TARGET = 185.48 +fate-swr-resample_exact_lin-s32p-44100-2626: SIZE_TOLERANCE = 529200 - 20490 + +fate-swr-resample_exact_lin-s32p-44100-96000: CMP_TARGET = 11.46 +fate-swr-resample_exact_lin-s32p-44100-96000: SIZE_TOLERANCE = 529200 - 20482 + +fate-swr-resample_exact_lin-s32p-48000-2626: CMP_TARGET = 456.48 +fate-swr-resample_exact_lin-s32p-48000-2626: SIZE_TOLERANCE = 576000 - 20510 + +fate-swr-resample_exact_lin-s32p-48000-96000: CMP_TARGET = 0.85 +fate-swr-resample_exact_lin-s32p-48000-96000: SIZE_TOLERANCE = 576000 - 20480 + +fate-swr-resample_exact_lin-s32p-8000-2626: CMP_TARGET = 2503.28 +fate-swr-resample_exact_lin-s32p-8000-2626: SIZE_TOLERANCE = 96000 - 20480 + +fate-swr-resample_exact_lin-s32p-8000-96000: CMP_TARGET = 13.62 +fate-swr-resample_exact_lin-s32p-8000-96000: SIZE_TOLERANCE = 96000 - 20480 + +fate-swr-resample_exact_lin-s32p-96000-2626: CMP_TARGET = 675.00 +fate-swr-resample_exact_lin-s32p-96000-2626: SIZE_TOLERANCE = 1152000 - 20474 + +fate-swr-resample_exact_lin-s32p-96000-44100: CMP_TARGET = 1.41 +fate-swr-resample_exact_lin-s32p-96000-44100: SIZE_TOLERANCE = 1152000 - 20480 + +fate-swr-resample_exact_lin-s32p-96000-48000: CMP_TARGET = 1.21 +fate-swr-resample_exact_lin-s32p-96000-48000: SIZE_TOLERANCE = 1152000 - 20480 + +fate-swr-resample_exact_lin-s32p-96000-8000: CMP_TARGET = 58.54 +fate-swr-resample_exact_lin-s32p-96000-8000: SIZE_TOLERANCE = 1152000 - 20496 + define ARESAMPLE_EXACT_LIN_ASYNC FATE_SWR_RESAMPLE += fate-swr-resample_exact_lin_async-$(3)-$(1)-$(2) fate-swr-resample_exact_lin_async-$(3)-$(1)-$(2): tests/data/asynth-$(1)-1.wav @@ -903,10 +1072,10 @@ $(call CROSS_TEST,$(SAMPLERATES_LITE),ARESAMPLE_EXACT_ASYNC,s32p,s32le,s16) $(call CROSS_TEST,$(SAMPLERATES_LITE),ARESAMPLE_EXACT_ASYNC,fltp,f32le,s16) $(call CROSS_TEST,$(SAMPLERATES_LITE),ARESAMPLE_EXACT_ASYNC,dblp,f64le,s16) -$(call CROSS_TEST,$(SAMPLERATES_LITE),ARESAMPLE_EXACT_LIN,s16p,s16le,s16) -$(call CROSS_TEST,$(SAMPLERATES_LITE),ARESAMPLE_EXACT_LIN,s32p,s32le,s16) -$(call CROSS_TEST,$(SAMPLERATES_LITE),ARESAMPLE_EXACT_LIN,fltp,f32le,s16) -$(call CROSS_TEST,$(SAMPLERATES_LITE),ARESAMPLE_EXACT_LIN,dblp,f64le,s16) +$(call CROSS_TEST,$(SAMPLERATES),ARESAMPLE_EXACT_LIN,s16p,s16le,s16) +$(call CROSS_TEST,$(SAMPLERATES),ARESAMPLE_EXACT_LIN,s32p,s32le,s16) +$(call CROSS_TEST,$(SAMPLERATES),ARESAMPLE_EXACT_LIN,fltp,f32le,s16) +$(call CROSS_TEST,$(SAMPLERATES),ARESAMPLE_EXACT_LIN,dblp,f64le,s16) $(call CROSS_TEST,$(SAMPLERATES_LITE),ARESAMPLE_EXACT_LIN_ASYNC,s16p,s16le,s16) $(call CROSS_TEST,$(SAMPLERATES_LITE),ARESAMPLE_EXACT_LIN_ASYNC,s32p,s32le,s16) diff --git a/tests/ref/acodec/s302m b/tests/ref/acodec/s302m index 7e41abb61f258..63e39edef91ec 100644 --- a/tests/ref/acodec/s302m +++ b/tests/ref/acodec/s302m @@ -1,4 +1,4 @@ -a69563c4c5db97d1b313c2fd7a193dd4 *tests/data/fate/acodec-s302m.mpegts +165d022ab86306d069797acff0c1e295 *tests/data/fate/acodec-s302m.mpegts 1589164 tests/data/fate/acodec-s302m.mpegts -2c033ed1d9029ed03e08c1d01dcefd99 *tests/data/fate/acodec-s302m.out.wav -stddev: 986.98 PSNR: 36.44 MAXDIFF:18642 bytes: 1058400/ 1056708 +31f25a0020fd9017de9c3c608316854b *tests/data/fate/acodec-s302m.out.wav +stddev: 986.94 PSNR: 36.44 MAXDIFF:18571 bytes: 1058400/ 1056708 diff --git a/tests/ref/lavf/dv_fmt b/tests/ref/lavf/dv_fmt index c8e4b115f5e1e..dac43b68a1d33 100644 --- a/tests/ref/lavf/dv_fmt +++ b/tests/ref/lavf/dv_fmt @@ -1,9 +1,9 @@ -3bcb02ee889b8b2da19cae79d0f1c27d *./tests/data/lavf/lavf.dv +5a622e1ae4fd16bec59cd514380d7882 *./tests/data/lavf/lavf.dv 3600000 ./tests/data/lavf/lavf.dv -./tests/data/lavf/lavf.dv CRC=0x5a36cc70 -f827583ae54e590d753c37709738fd54 *./tests/data/lavf/lavf.dv +./tests/data/lavf/lavf.dv CRC=0x0a6edbd8 +155e8fd4ea1196edd56ae9ff09edcf85 *./tests/data/lavf/lavf.dv 3480000 ./tests/data/lavf/lavf.dv -./tests/data/lavf/lavf.dv CRC=0x8f8074be +./tests/data/lavf/lavf.dv CRC=0x3e5583fa 87d3b20f656235671383a7eaa2f66330 *./tests/data/lavf/lavf.dv 3600000 ./tests/data/lavf/lavf.dv ./tests/data/lavf/lavf.dv CRC=0xf3e6873c diff --git a/tests/ref/lavf/gxf b/tests/ref/lavf/gxf index 9b9831be3e1e4..4dd463cd2a5dc 100644 --- a/tests/ref/lavf/gxf +++ b/tests/ref/lavf/gxf @@ -1,9 +1,9 @@ -1b384e20293a84b274739c147e2b290a *./tests/data/lavf/lavf.gxf +6ef34e8bedf699cd1601022c4a0a4910 *./tests/data/lavf/lavf.gxf 795876 ./tests/data/lavf/lavf.gxf -./tests/data/lavf/lavf.gxf CRC=0x55b3ec1d -411f109b5867e5cb81bc876d3cc5702b *./tests/data/lavf/lavf.gxf +./tests/data/lavf/lavf.gxf CRC=0x1dbfef76 +7780c428dde2c93a9ff04794f7168440 *./tests/data/lavf/lavf.gxf 794656 ./tests/data/lavf/lavf.gxf -./tests/data/lavf/lavf.gxf CRC=0x0d7e90ea +./tests/data/lavf/lavf.gxf CRC=0xdcd39443 0638c4d073ac224608baaba16732b68f *./tests/data/lavf/lavf.gxf 795876 ./tests/data/lavf/lavf.gxf ./tests/data/lavf/lavf.gxf CRC=0x5ade0285 diff --git a/tests/ref/lavf/mxf b/tests/ref/lavf/mxf index aea9c0246c9ca..48fe95a235661 100644 --- a/tests/ref/lavf/mxf +++ b/tests/ref/lavf/mxf @@ -1,9 +1,9 @@ -2fd59c174dfb213d35e86dea63c0fb13 *./tests/data/lavf/lavf.mxf +eaac3125ac1a61fe5f968c7af83fa71e *./tests/data/lavf/lavf.mxf 525369 ./tests/data/lavf/lavf.mxf -./tests/data/lavf/lavf.mxf CRC=0x9fd3f752 -edb3b610c301362d7b4c12f06f8d2782 *./tests/data/lavf/lavf.mxf +./tests/data/lavf/lavf.mxf CRC=0x8dddfaab +1562530330b13e9e70f522fe20265632 *./tests/data/lavf/lavf.mxf 560697 ./tests/data/lavf/lavf.mxf -./tests/data/lavf/lavf.mxf CRC=0xc51717ef -a6ba421f38ee5ec46e181225c632fee4 *./tests/data/lavf/lavf.mxf +./tests/data/lavf/lavf.mxf CRC=0xf21b1b48 +e07858715997313ae66a1cdd6fde5f66 *./tests/data/lavf/lavf.mxf 525369 ./tests/data/lavf/lavf.mxf -./tests/data/lavf/lavf.mxf CRC=0x9fd3f752 +./tests/data/lavf/lavf.mxf CRC=0x8dddfaab From e7282674a505d548746a4734cbe902a9f242eb6b Mon Sep 17 00:00:00 2001 From: Lou Logan Date: Wed, 15 Mar 2017 18:45:12 -0800 Subject: [PATCH 1171/3374] lavf/mpegtsenc: clarify pcr_period unit of measurement pcr_period is in milliseconds. Signed-off-by: Lou Logan --- libavformat/mpegtsenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 0f394c5fe0e9e..3250dde311edf 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -1945,7 +1945,7 @@ static const AVOption options[] = { { "omit_video_pes_length", "Omit the PES packet length for video packets", offsetof(MpegTSWrite, omit_video_pes_length), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM }, - { "pcr_period", "PCR retransmission time", + { "pcr_period", "PCR retransmission time in milliseconds", offsetof(MpegTSWrite, pcr_period), AV_OPT_TYPE_INT, { .i64 = PCR_RETRANS_TIME }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, { "pat_period", "PAT/PMT retransmission time limit in seconds", From b573e3f4845bd1cd004df70dd0b7cf2c4c73a5f9 Mon Sep 17 00:00:00 2001 From: wang-bin Date: Fri, 10 Mar 2017 04:02:13 +0000 Subject: [PATCH 1172/3374] configure: clang -Oz for small size build to reduce size further --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 0333210b46e8c..48a53f144b522 100755 --- a/configure +++ b/configure @@ -4054,7 +4054,7 @@ probe_cc(){ _ident=$($_cc --version 2>/dev/null | head -n1) _depflags='-MMD -MF $(@:.o=.d) -MT $@' _cflags_speed='-O3' - _cflags_size='-Os' + _cflags_size='-Oz' elif $_cc -V 2>&1 | grep -q Sun; then _type=suncc _ident=$($_cc -V 2>&1 | head -n1 | cut -d' ' -f 2-) From 396be0da59fa5071392288a840a1761d10fecd6b Mon Sep 17 00:00:00 2001 From: Lou Logan Date: Wed, 15 Mar 2017 19:51:01 -0800 Subject: [PATCH 1173/3374] doc/muxers: cleanup mpegts section Add missing options. List correct variable types. Re-order options and markup flag options properly. Add more texinfo markup. Signed-off-by: Lou Logan --- doc/muxers.texi | 140 ++++++++++++++++++++++++++++-------------------- 1 file changed, 81 insertions(+), 59 deletions(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index fa89e6cfa9085..166c929369261 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -1091,69 +1091,35 @@ This muxer implements ISO 13818-1 and part of ETSI EN 300 468. The recognized metadata settings in mpegts muxer are @code{service_provider} and @code{service_name}. If they are not set the default for -@code{service_provider} is "FFmpeg" and the default for -@code{service_name} is "Service01". +@code{service_provider} is @samp{FFmpeg} and the default for +@code{service_name} is @samp{Service01}. @subsection Options The muxer options are: @table @option -@item mpegts_original_network_id @var{number} -Set the original_network_id (default 0x0001). This is unique identifier -of a network in DVB. Its main use is in the unique identification of a -service through the path Original_Network_ID, Transport_Stream_ID. -@item mpegts_transport_stream_id @var{number} -Set the transport_stream_id (default 0x0001). This identifies a -transponder in DVB. -@item mpegts_service_id @var{number} -Set the service_id (default 0x0001) also known as program in DVB. -@item mpegts_service_type @var{number} -Set the program service_type (default @var{digital_tv}), see below -a list of pre defined values. -@item mpegts_pmt_start_pid @var{number} -Set the first PID for PMT (default 0x1000, max 0x1f00). -@item mpegts_start_pid @var{number} -Set the first PID for data packets (default 0x0100, max 0x0f00). -@item mpegts_m2ts_mode @var{number} -Enable m2ts mode if set to 1. Default value is -1 which disables m2ts mode. -@item muxrate @var{number} -Set a constant muxrate (default VBR). -@item pcr_period @var{numer} -Override the default PCR retransmission time (default 20ms), ignored -if variable muxrate is selected. -@item pat_period @var{number} -Maximal time in seconds between PAT/PMT tables. -@item sdt_period @var{number} -Maximal time in seconds between SDT tables. -@item pes_payload_size @var{number} -Set minimum PES packet payload in bytes. -@item mpegts_flags @var{flags} -Set flags (see below). -@item mpegts_copyts @var{number} -Preserve original timestamps, if value is set to 1. Default value is -1, which -results in shifting timestamps so that they start from 0. -@item tables_version @var{number} -Set PAT, PMT and SDT version (default 0, valid values are from 0 to 31, inclusively). -This option allows updating stream structure so that standard consumer may -detect the change. To do so, reopen output AVFormatContext (in case of API -usage) or restart ffmpeg instance, cyclically changing tables_version value: -@example -ffmpeg -i source1.ts -codec copy -f mpegts -tables_version 0 udp://1.1.1.1:1111 -ffmpeg -i source2.ts -codec copy -f mpegts -tables_version 1 udp://1.1.1.1:1111 -... -ffmpeg -i source3.ts -codec copy -f mpegts -tables_version 31 udp://1.1.1.1:1111 -ffmpeg -i source1.ts -codec copy -f mpegts -tables_version 0 udp://1.1.1.1:1111 -ffmpeg -i source2.ts -codec copy -f mpegts -tables_version 1 udp://1.1.1.1:1111 -... -@end example -@end table - -Option @option{mpegts_service_type} accepts the following values: - -@table @option +@item mpegts_transport_stream_id @var{integer} +Set the @samp{transport_stream_id}. This identifies a transponder in DVB. +Default is @code{0x0001}. + +@item mpegts_original_network_id @var{integer} +Set the @samp{original_network_id}. This is unique identifier of a +network in DVB. Its main use is in the unique identification of a service +through the path @samp{Original_Network_ID, Transport_Stream_ID}. Default +is @code{0x0001}. + +@item mpegts_service_id @var{integer} +Set the @samp{service_id}, also known as program in DVB. Default is +@code{0x0001}. + +@item mpegts_service_type @var{integer} +Set the program @samp{service_type}. Default is @code{digital_tv}. +Accepts the following options: +@table @samp @item hex_value -Any hexdecimal value between 0x01 to 0xff as defined in ETSI 300 468. +Any hexdecimal value between @code{0x01} to @code{0xff} as defined in +ETSI 300 468. @item digital_tv Digital TV service. @item digital_radio @@ -1170,9 +1136,26 @@ Advanced Codec Digital SDTV service. Advanced Codec Digital HDTV service. @end table -Option @option{mpegts_flags} may take a set of such flags: +@item mpegts_pmt_start_pid @var{integer} +Set the first PID for PMT. Default is @code{0x1000}. Max is @code{0x1f00}. -@table @option +@item mpegts_start_pid @var{integer} +Set the first PID for data packets. Default is @code{0x0100}. Max is +@code{0x0f00}. + +@item mpegts_m2ts_mode @var{boolean} +Enable m2ts mode if set to @code{1}. Default value is @code{-1} which +disables m2ts mode. + +@item muxrate @var{integer} +Set a constant muxrate. Default is VBR. + +@item pes_payload_size @var{integer} +Set minimum PES packet payload in bytes. Default is @code{2930}. + +@item mpegts_flags @var{flags} +Set mpegts flags. Accepts the following options: +@table @samp @item resend_headers Reemit PAT/PMT before writing the next packet. @item latm @@ -1185,6 +1168,45 @@ Conform to System B (DVB) instead of System A (ATSC). Mark the initial packet of each stream as discontinuity. @end table +@item resend_headers @var{integer} +Reemit PAT/PMT before writing the next packet. This option is deprecated: +use @option{mpegts_flags} instead. + +@item mpegts_copyts @var{boolean} +Preserve original timestamps, if value is set to @code{1}. Default value +is @code{-1}, which results in shifting timestamps so that they start from 0. + +@item omit_video_pes_length @var{boolean} +Omit the PES packet length for video packets. Default is @code{1} (true). + +@item pcr_period @var{integer} +Override the default PCR retransmission time in milliseconds. Ignored if +variable muxrate is selected. Default is @code{20}. + +@item pat_period @var{double} +Maximum time in seconds between PAT/PMT tables. + +@item sdt_period @var{double} +Maximum time in seconds between SDT tables. + +@item tables_version @var{integer} +Set PAT, PMT and SDT version (default @code{0}, valid values are from 0 to 31, inclusively). +This option allows updating stream structure so that standard consumer may +detect the change. To do so, reopen output @code{AVFormatContext} (in case of API +usage) or restart @command{ffmpeg} instance, cyclically changing +@option{tables_version} value: + +@example +ffmpeg -i source1.ts -codec copy -f mpegts -tables_version 0 udp://1.1.1.1:1111 +ffmpeg -i source2.ts -codec copy -f mpegts -tables_version 1 udp://1.1.1.1:1111 +... +ffmpeg -i source3.ts -codec copy -f mpegts -tables_version 31 udp://1.1.1.1:1111 +ffmpeg -i source1.ts -codec copy -f mpegts -tables_version 0 udp://1.1.1.1:1111 +ffmpeg -i source2.ts -codec copy -f mpegts -tables_version 1 udp://1.1.1.1:1111 +... +@end example +@end table + @subsection Example @example @@ -1196,7 +1218,7 @@ ffmpeg -i file.mpg -c copy \ -mpegts_start_pid 0x150 \ -metadata service_provider="Some provider" \ -metadata service_name="Some Channel" \ - -y out.ts + out.ts @end example @section mxf, mxf_d10 From 0d34dbc27277d65e58a675d91d810903a3e21fac Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Sun, 26 Feb 2017 11:58:49 +0100 Subject: [PATCH 1174/3374] lavc/avpacket: Make pkt parameter of av_packet_get_side_data() const. Reflects the actual code and silences a gcc warning: libavcodec/utils.c:2102:36: warning: passing argument 1 of 'av_packet_get_side_data' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers] --- libavcodec/avcodec.h | 2 +- libavcodec/avpacket.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index e32f57983c32e..1923c9648df0a 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -4572,7 +4572,7 @@ int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type, * @param size pointer for side information size to store (optional) * @return pointer to data if present or NULL otherwise */ -uint8_t* av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type, +uint8_t* av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, int *size); int av_packet_merge_side_data(AVPacket *pkt); diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index 60269aa63db8e..3ea2511dea816 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -336,7 +336,7 @@ uint8_t *av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, return data; } -uint8_t *av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type, +uint8_t *av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, int *size) { int i; From 5dd7ea9f569b92c1e3de10eff46b80f3dfa63a1d Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Sun, 26 Feb 2017 12:34:41 +0100 Subject: [PATCH 1175/3374] lavc/internal: Constify AVPacket* in AVCodecInternal. Fixes a gcc warning: libavcodec/utils.c:2244:26: warning: assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers] --- libavcodec/internal.h | 2 +- libavcodec/utils.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/internal.h b/libavcodec/internal.h index d6e620a9832d2..6e93eeb1a91f9 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -141,7 +141,7 @@ typedef struct AVCodecInternal { * Current packet as passed into the decoder, to avoid having to pass the * packet into every function. */ - AVPacket *pkt; + const AVPacket *pkt; /** * temporary buffer used for encoders to store their bitstream diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 4d1b63222f30a..d41ea572f5e35 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -745,7 +745,7 @@ int avcodec_default_get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags } } -static int add_metadata_from_side_data(AVPacket *avpkt, AVFrame *frame) +static int add_metadata_from_side_data(const AVPacket *avpkt, AVFrame *frame) { int size; const uint8_t *side_metadata; @@ -759,7 +759,7 @@ static int add_metadata_from_side_data(AVPacket *avpkt, AVFrame *frame) int ff_init_buffer_info(AVCodecContext *avctx, AVFrame *frame) { - AVPacket *pkt = avctx->internal->pkt; + const AVPacket *pkt = avctx->internal->pkt; int i; static const struct { enum AVPacketSideDataType packet; From 1cd58e915436ea84eb861327f3897ef54058ee42 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Thu, 16 Mar 2017 21:19:48 +0100 Subject: [PATCH 1176/3374] lavu/spherical: Make AVSphericalMapping pointer parameter const. Reflects the actual code and silences a gcc warning: ffprobe.c:1797:42: warning: passing argument 1 of 'av_spherical_tile_bounds' discards 'const' qualifier from pointer target type --- libavutil/spherical.c | 2 +- libavutil/spherical.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libavutil/spherical.c b/libavutil/spherical.c index 0ca2dd367a769..f0b622128a57e 100644 --- a/libavutil/spherical.c +++ b/libavutil/spherical.c @@ -33,7 +33,7 @@ AVSphericalMapping *av_spherical_alloc(size_t *size) return spherical; } -void av_spherical_tile_bounds(AVSphericalMapping *map, +void av_spherical_tile_bounds(const AVSphericalMapping *map, size_t width, size_t height, size_t *left, size_t *top, size_t *right, size_t *bottom) diff --git a/libavutil/spherical.h b/libavutil/spherical.h index db9bdc0be5f0c..f4e0d60966b2b 100644 --- a/libavutil/spherical.h +++ b/libavutil/spherical.h @@ -202,7 +202,7 @@ AVSphericalMapping *av_spherical_alloc(size_t *size); * @param right Pixels from the right edge. * @param bottom Pixels from the bottom edge. */ -void av_spherical_tile_bounds(AVSphericalMapping *map, +void av_spherical_tile_bounds(const AVSphericalMapping *map, size_t width, size_t height, size_t *left, size_t *top, size_t *right, size_t *bottom); From b4b8ca24f62473528949fe047085eb084364124b Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 7 Mar 2017 09:56:42 +0100 Subject: [PATCH 1177/3374] avcodec: fix uninitialized variable read This cna happen if the user tries to call the new decode API for subtitles. Fixes CID 1402071. --- libavcodec/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/utils.c b/libavcodec/utils.c index d41ea572f5e35..6f7b2e7af705e 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -2787,7 +2787,7 @@ void avsubtitle_free(AVSubtitle *sub) static int do_decode(AVCodecContext *avctx, AVPacket *pkt) { - int got_frame; + int got_frame = 0; int ret; av_assert0(!avctx->internal->buffer_frame->buf[0]); From 3ba7b47d5cb494a0559beb61156eceb17fabf91f Mon Sep 17 00:00:00 2001 From: Muhammad Faiz Date: Fri, 17 Mar 2017 07:46:20 +0700 Subject: [PATCH 1178/3374] swresample/resample: do not assert compensation_distance on rebuild_filter when set_compensation is called with zero sample_delta, compensation does not happen (because dst_incr == ideal_dst_incr) but compensation_distance is set regression since 01ebb57c03abde89bca7bdbc552917efcb8f551d Found-by: wm4 Reviewed-by: wm4 Signed-off-by: Muhammad Faiz --- libswresample/resample.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libswresample/resample.c b/libswresample/resample.c index 8f3428f512b79..144b2324628d9 100644 --- a/libswresample/resample.c +++ b/libswresample/resample.c @@ -388,7 +388,7 @@ static int rebuild_filter_bank_with_compensation(ResampleContext *c) if (phase_count == c->phase_count) return 0; - av_assert0(!c->frac && !c->dst_incr_mod && !c->compensation_distance); + av_assert0(!c->frac && !c->dst_incr_mod); new_filter_bank = av_calloc(c->filter_alloc, (phase_count + 1) * c->felem_size); if (!new_filter_bank) From 2db5ab73d43a8c22616e686ab12f94223910c761 Mon Sep 17 00:00:00 2001 From: Konda Raju Date: Fri, 17 Mar 2017 09:42:25 +0530 Subject: [PATCH 1179/3374] avcodec/nvenc: allow different const-qps for I, P and B frames Signed-off-by: Timo Rothenpieler --- libavcodec/nvenc.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index d9fef525dd334..dd9ebc1756431 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -507,9 +507,26 @@ static av_cold void set_constqp(AVCodecContext *avctx) NV_ENC_RC_PARAMS *rc = &ctx->encode_config.rcParams; rc->rateControlMode = NV_ENC_PARAMS_RC_CONSTQP; - rc->constQP.qpInterB = avctx->global_quality; - rc->constQP.qpInterP = avctx->global_quality; - rc->constQP.qpIntra = avctx->global_quality; + + if (ctx->init_qp_p >= 0) { + rc->constQP.qpInterP = ctx->init_qp_p; + if (ctx->init_qp_i >= 0 && ctx->init_qp_b >= 0) { + rc->constQP.qpIntra = ctx->init_qp_i; + rc->constQP.qpInterB = ctx->init_qp_b; + } else if (avctx->i_quant_factor != 0.0 && avctx->b_quant_factor != 0.0) { + rc->constQP.qpIntra = av_clip( + rc->constQP.qpInterP * fabs(avctx->i_quant_factor) + avctx->i_quant_offset + 0.5, 0, 51); + rc->constQP.qpInterB = av_clip( + rc->constQP.qpInterP * fabs(avctx->b_quant_factor) + avctx->b_quant_offset + 0.5, 0, 51); + } else { + rc->constQP.qpIntra = rc->constQP.qpInterP; + rc->constQP.qpInterB = rc->constQP.qpInterP; + } + } else if (avctx->global_quality > 0) { + rc->constQP.qpInterP = avctx->global_quality; + rc->constQP.qpInterB = avctx->global_quality; + rc->constQP.qpIntra = avctx->global_quality; + } avctx->qmin = -1; avctx->qmax = -1; @@ -598,12 +615,6 @@ static void nvenc_override_rate_control(AVCodecContext *avctx) switch (ctx->rc) { case NV_ENC_PARAMS_RC_CONSTQP: - if (avctx->global_quality <= 0) { - av_log(avctx, AV_LOG_WARNING, - "The constant quality rate-control requires " - "the 'global_quality' option set.\n"); - return; - } set_constqp(avctx); return; case NV_ENC_PARAMS_RC_VBR_MINQP: From 8db301deadfcf113fb274881e65afcbe3e1bd645 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 1 Oct 2016 11:47:23 +0200 Subject: [PATCH 1180/3374] ffmpeg: set the encoding framerate when the output is CFR (cherry picked from Libav commit d10102d23c9467d4eb84f58e0cd12be284b982f6) Signed-off-by: Tobias Rapp --- ffmpeg.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ffmpeg.c b/ffmpeg.c index 63fc1bc5f4c49..dbfb14bfca5a2 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -3314,6 +3314,8 @@ static int init_output_stream_encode(OutputStream *ost) enc_ctx->bits_per_raw_sample = FFMIN(dec_ctx->bits_per_raw_sample, av_pix_fmt_desc_get(enc_ctx->pix_fmt)->comp[0].depth); + enc_ctx->framerate = ost->frame_rate; + ost->st->avg_frame_rate = ost->frame_rate; if (!dec_ctx || From 205b8fd078e50aa3f7f401646dbb73de1bb35a10 Mon Sep 17 00:00:00 2001 From: Tobias Rapp Date: Mon, 6 Mar 2017 08:53:28 +0100 Subject: [PATCH 1181/3374] avcodec: estimate output bitrate for uncompressed video codecs Allows to get a more realistic total bitrate (and estimated file size) in avi_write_header. Previously a static default value of 200k was assumed. Adds an internal helper function for bitrate guessing. Signed-off-by: Tobias Rapp Reviewed-by: Michael Niedermayer --- libavcodec/internal.h | 6 ++++++ libavcodec/r210enc.c | 15 +++++++++++++++ libavcodec/rawenc.c | 2 ++ libavcodec/utils.c | 21 +++++++++++++++++++++ libavcodec/v210enc.c | 3 +++ libavcodec/v308enc.c | 3 +++ libavcodec/v408enc.c | 2 ++ libavcodec/v410enc.c | 3 +++ libavcodec/y41penc.c | 1 + tests/ref/fate/v410enc | 2 +- tests/ref/vsynth/vsynth1-bpp1 | 2 +- tests/ref/vsynth/vsynth1-bpp15 | 2 +- tests/ref/vsynth/vsynth1-r210 | 2 +- tests/ref/vsynth/vsynth1-rgb | 2 +- tests/ref/vsynth/vsynth1-v210 | 2 +- tests/ref/vsynth/vsynth1-v210-10 | 2 +- tests/ref/vsynth/vsynth1-v308 | 2 +- tests/ref/vsynth/vsynth1-v408 | 2 +- tests/ref/vsynth/vsynth1-y41p | 2 +- tests/ref/vsynth/vsynth1-yuv | 2 +- tests/ref/vsynth/vsynth2-bpp1 | 2 +- tests/ref/vsynth/vsynth2-bpp15 | 2 +- tests/ref/vsynth/vsynth2-r210 | 2 +- tests/ref/vsynth/vsynth2-rgb | 2 +- tests/ref/vsynth/vsynth2-v210 | 2 +- tests/ref/vsynth/vsynth2-v210-10 | 2 +- tests/ref/vsynth/vsynth2-v308 | 2 +- tests/ref/vsynth/vsynth2-v408 | 2 +- tests/ref/vsynth/vsynth2-y41p | 2 +- tests/ref/vsynth/vsynth2-yuv | 2 +- tests/ref/vsynth/vsynth3-bpp1 | 2 +- tests/ref/vsynth/vsynth3-bpp15 | 2 +- tests/ref/vsynth/vsynth3-r210 | 2 +- tests/ref/vsynth/vsynth3-rgb | 2 +- tests/ref/vsynth/vsynth3-v210 | 2 +- tests/ref/vsynth/vsynth3-v210-10 | 2 +- tests/ref/vsynth/vsynth3-v308 | 2 +- tests/ref/vsynth/vsynth3-v408 | 2 +- tests/ref/vsynth/vsynth3-yuv | 2 +- tests/ref/vsynth/vsynth_lena-bpp1 | 2 +- tests/ref/vsynth/vsynth_lena-bpp15 | 2 +- tests/ref/vsynth/vsynth_lena-r210 | 2 +- tests/ref/vsynth/vsynth_lena-rgb | 2 +- tests/ref/vsynth/vsynth_lena-v210 | 2 +- tests/ref/vsynth/vsynth_lena-v210-10 | 2 +- tests/ref/vsynth/vsynth_lena-v308 | 2 +- tests/ref/vsynth/vsynth_lena-v408 | 2 +- tests/ref/vsynth/vsynth_lena-y41p | 2 +- tests/ref/vsynth/vsynth_lena-yuv | 2 +- 49 files changed, 96 insertions(+), 40 deletions(-) diff --git a/libavcodec/internal.h b/libavcodec/internal.h index 6e93eeb1a91f9..e5f132a673040 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -363,4 +363,10 @@ int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, i int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, void **data, size_t *sei_size); +/** + * Get an estimated video bitrate based on frame size, frame rate and coded + * bits per pixel. + */ +int64_t ff_guess_coded_bitrate(AVCodecContext *avctx); + #endif /* AVCODEC_INTERNAL_H */ diff --git a/libavcodec/r210enc.c b/libavcodec/r210enc.c index 65b3c069fcb3e..a55e5434f317f 100644 --- a/libavcodec/r210enc.c +++ b/libavcodec/r210enc.c @@ -24,6 +24,18 @@ #include "internal.h" #include "bytestream.h" +static av_cold int encode_init(AVCodecContext *avctx) +{ + int aligned_width = FFALIGN(avctx->width, + avctx->codec_id == AV_CODEC_ID_R10K ? 1 : 64); + + avctx->bits_per_coded_sample = 32; + if (avctx->width > 0) + avctx->bit_rate = ff_guess_coded_bitrate(avctx) * aligned_width / avctx->width; + + return 0; +} + static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pic, int *got_packet) { @@ -73,6 +85,7 @@ AVCodec ff_r210_encoder = { .long_name = NULL_IF_CONFIG_SMALL("Uncompressed RGB 10-bit"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_R210, + .init = encode_init, .encode2 = encode_frame, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB48, AV_PIX_FMT_NONE }, .capabilities = AV_CODEC_CAP_INTRA_ONLY, @@ -84,6 +97,7 @@ AVCodec ff_r10k_encoder = { .long_name = NULL_IF_CONFIG_SMALL("AJA Kona 10-bit RGB Codec"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_R10K, + .init = encode_init, .encode2 = encode_frame, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB48, AV_PIX_FMT_NONE }, .capabilities = AV_CODEC_CAP_INTRA_ONLY, @@ -95,6 +109,7 @@ AVCodec ff_avrp_encoder = { .long_name = NULL_IF_CONFIG_SMALL("Avid 1:1 10-bit RGB Packer"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_AVRP, + .init = encode_init, .encode2 = encode_frame, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB48, AV_PIX_FMT_NONE }, .capabilities = AV_CODEC_CAP_INTRA_ONLY, diff --git a/libavcodec/rawenc.c b/libavcodec/rawenc.c index a2d5ccc0a6855..d181b74570d6e 100644 --- a/libavcodec/rawenc.c +++ b/libavcodec/rawenc.c @@ -44,6 +44,8 @@ FF_ENABLE_DEPRECATION_WARNINGS avctx->bits_per_coded_sample = av_get_bits_per_pixel(desc); if(!avctx->codec_tag) avctx->codec_tag = avcodec_pix_fmt_to_codec_tag(avctx->pix_fmt); + avctx->bit_rate = ff_guess_coded_bitrate(avctx); + return 0; } diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 6f7b2e7af705e..63a6349703c4e 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -4343,3 +4343,24 @@ int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, return 0; } + +int64_t ff_guess_coded_bitrate(AVCodecContext *avctx) +{ + AVRational framerate = avctx->framerate; + int bits_per_coded_sample = avctx->bits_per_coded_sample; + int64_t bitrate; + + if (!(framerate.num && framerate.den)) + framerate = av_inv_q(avctx->time_base); + if (!(framerate.num && framerate.den)) + return 0; + + if (!bits_per_coded_sample) { + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); + bits_per_coded_sample = av_get_bits_per_pixel(desc); + } + bitrate = (int64_t)bits_per_coded_sample * avctx->width * avctx->height * + framerate.num / framerate.den; + + return bitrate; +} diff --git a/libavcodec/v210enc.c b/libavcodec/v210enc.c index d3a8e26bc1bab..a6afbbfc41965 100644 --- a/libavcodec/v210enc.c +++ b/libavcodec/v210enc.c @@ -110,6 +110,9 @@ FF_ENABLE_DEPRECATION_WARNINGS ff_v210enc_init(s); + avctx->bits_per_coded_sample = 20; + avctx->bit_rate = ff_guess_coded_bitrate(avctx) * 16 / 15; + return 0; } diff --git a/libavcodec/v308enc.c b/libavcodec/v308enc.c index b60a72cee6a97..e88f1f464814e 100644 --- a/libavcodec/v308enc.c +++ b/libavcodec/v308enc.c @@ -31,6 +31,9 @@ static av_cold int v308_encode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } + avctx->bits_per_coded_sample = 24; + avctx->bit_rate = ff_guess_coded_bitrate(avctx); + return 0; } diff --git a/libavcodec/v408enc.c b/libavcodec/v408enc.c index f37f360b73f6d..e12965b7ad680 100644 --- a/libavcodec/v408enc.c +++ b/libavcodec/v408enc.c @@ -26,6 +26,8 @@ static av_cold int v408_encode_init(AVCodecContext *avctx) { + avctx->bits_per_coded_sample = 32; + avctx->bit_rate = ff_guess_coded_bitrate(avctx); return 0; } diff --git a/libavcodec/v410enc.c b/libavcodec/v410enc.c index f35ff7596397c..5e2450279fb52 100644 --- a/libavcodec/v410enc.c +++ b/libavcodec/v410enc.c @@ -32,6 +32,9 @@ static av_cold int v410_encode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } + avctx->bits_per_coded_sample = 32; + avctx->bit_rate = ff_guess_coded_bitrate(avctx); + return 0; } diff --git a/libavcodec/y41penc.c b/libavcodec/y41penc.c index 94acc343fb590..ca94a3c171a56 100644 --- a/libavcodec/y41penc.c +++ b/libavcodec/y41penc.c @@ -31,6 +31,7 @@ static av_cold int y41p_encode_init(AVCodecContext *avctx) } avctx->bits_per_coded_sample = 12; + avctx->bit_rate = ff_guess_coded_bitrate(avctx); return 0; } diff --git a/tests/ref/fate/v410enc b/tests/ref/fate/v410enc index b2c728e9b24db..139da7b8755e7 100644 --- a/tests/ref/fate/v410enc +++ b/tests/ref/fate/v410enc @@ -1 +1 @@ -f7cf1b743c18f74d047ce8d6ea05d3d9 +5fd2d9a7b3311f5c19dbdd647bb9eae6 diff --git a/tests/ref/vsynth/vsynth1-bpp1 b/tests/ref/vsynth/vsynth1-bpp1 index af1fb0ecd4ce4..b647ba0a1404e 100644 --- a/tests/ref/vsynth/vsynth1-bpp1 +++ b/tests/ref/vsynth/vsynth1-bpp1 @@ -1,4 +1,4 @@ -a0b35707a9aa7144e3e1c70c1d01f4ce *tests/data/fate/vsynth1-bpp1.avi +1c78e77c971b1ce31f229c6fc23d0902 *tests/data/fate/vsynth1-bpp1.avi 640460 tests/data/fate/vsynth1-bpp1.avi cd1e1448d9895561347ceb66d0add34d *tests/data/fate/vsynth1-bpp1.out.rawvideo stddev: 84.48 PSNR: 9.60 MAXDIFF: 218 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth1-bpp15 b/tests/ref/vsynth/vsynth1-bpp15 index 855383810eb53..d687b963d69f5 100644 --- a/tests/ref/vsynth/vsynth1-bpp15 +++ b/tests/ref/vsynth/vsynth1-bpp15 @@ -1,4 +1,4 @@ -dc37d1db0429f44000a03a60862751cd *tests/data/fate/vsynth1-bpp15.avi +6147f5f235657fa9ced6ec6146be6ff0 *tests/data/fate/vsynth1-bpp15.avi 10144452 tests/data/fate/vsynth1-bpp15.avi 3aee2d6e82a9507d7f01844c04d2b57b *tests/data/fate/vsynth1-bpp15.out.rawvideo stddev: 38.44 PSNR: 16.43 MAXDIFF: 159 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth1-r210 b/tests/ref/vsynth/vsynth1-r210 index e25b1de6d2689..825e1d4789685 100644 --- a/tests/ref/vsynth/vsynth1-r210 +++ b/tests/ref/vsynth/vsynth1-r210 @@ -1,4 +1,4 @@ -fd2bb8b3d3e47f5ea7769443324ee0ae *tests/data/fate/vsynth1-r210.avi +1ea72f280b110ed65fc535c3438d27f9 *tests/data/fate/vsynth1-r210.avi 22125252 tests/data/fate/vsynth1-r210.avi ecaafa9eec11b5e1453a63ed6d194eed *tests/data/fate/vsynth1-r210.out.rawvideo stddev: 3.23 PSNR: 37.94 MAXDIFF: 48 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth1-rgb b/tests/ref/vsynth/vsynth1-rgb index 0a3947c7ebcc3..6d9629b5e9bec 100644 --- a/tests/ref/vsynth/vsynth1-rgb +++ b/tests/ref/vsynth/vsynth1-rgb @@ -1,4 +1,4 @@ -c8a4b8648436e73ced7fe32f6f65a1b3 *tests/data/fate/vsynth1-rgb.avi +9d2bd1fa569a803c41b5dc5dd03f088e *tests/data/fate/vsynth1-rgb.avi 15213252 tests/data/fate/vsynth1-rgb.avi 93695a27c24a61105076ca7b1f010bbd *tests/data/fate/vsynth1-rgb.out.rawvideo stddev: 3.42 PSNR: 37.44 MAXDIFF: 48 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth1-v210 b/tests/ref/vsynth/vsynth1-v210 index 388e8b66886c1..1b69da4e9f1aa 100644 --- a/tests/ref/vsynth/vsynth1-v210 +++ b/tests/ref/vsynth/vsynth1-v210 @@ -1,4 +1,4 @@ -0712d60b3a00cf2d5a7e39aa21e2547a *tests/data/fate/vsynth1-v210.avi +767471c71d60daf46ca3a758771c4f8e *tests/data/fate/vsynth1-v210.avi 14752452 tests/data/fate/vsynth1-v210.avi 2ba7f4ca302f3c4147860b9dfb12b6e4 *tests/data/fate/vsynth1-v210.out.rawvideo stddev: 1.84 PSNR: 42.81 MAXDIFF: 29 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth1-v210-10 b/tests/ref/vsynth/vsynth1-v210-10 index 4621b9d69adc2..f459cfa8e18c1 100644 --- a/tests/ref/vsynth/vsynth1-v210-10 +++ b/tests/ref/vsynth/vsynth1-v210-10 @@ -1,4 +1,4 @@ -230bbd31c82d4fbb92d5ea2ac591ded5 *tests/data/fate/vsynth1-v210-10.avi +9269ce2a5294a4c9a8346328d06b23af *tests/data/fate/vsynth1-v210-10.avi 14752452 tests/data/fate/vsynth1-v210-10.avi 50973792d3f1abe04a51ee0121f077f2 *tests/data/fate/vsynth1-v210-10.out.rawvideo stddev: 1.85 PSNR: 42.78 MAXDIFF: 29 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth1-v308 b/tests/ref/vsynth/vsynth1-v308 index 9eb29110065c5..162624e28658c 100644 --- a/tests/ref/vsynth/vsynth1-v308 +++ b/tests/ref/vsynth/vsynth1-v308 @@ -1,4 +1,4 @@ -58ea26d3060f9d47cf95056ed9361c90 *tests/data/fate/vsynth1-v308.avi +5d868b73c554a9a2422d6c8a18ce9c02 *tests/data/fate/vsynth1-v308.avi 15213252 tests/data/fate/vsynth1-v308.avi 10fb42f1abf40a289c3edafc0390482c *tests/data/fate/vsynth1-v308.out.rawvideo stddev: 2.67 PSNR: 39.60 MAXDIFF: 43 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth1-v408 b/tests/ref/vsynth/vsynth1-v408 index bf16cbd489a80..5d5f816fc09d7 100644 --- a/tests/ref/vsynth/vsynth1-v408 +++ b/tests/ref/vsynth/vsynth1-v408 @@ -1,4 +1,4 @@ -4ac68e91ac25bc422abb3febe86a4acd *tests/data/fate/vsynth1-v408.avi +4e977bec707cda2b09edb717805cb960 *tests/data/fate/vsynth1-v408.avi 20282052 tests/data/fate/vsynth1-v408.avi c5ccac874dbf808e9088bc3107860042 *tests/data/fate/vsynth1-v408.out.rawvideo stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth1-y41p b/tests/ref/vsynth/vsynth1-y41p index cb4c001f0975c..84e790b4a0f3a 100644 --- a/tests/ref/vsynth/vsynth1-y41p +++ b/tests/ref/vsynth/vsynth1-y41p @@ -1,4 +1,4 @@ -862ffddd90c82163d2505031e5bbcd9a *tests/data/fate/vsynth1-y41p.avi +7355fc7614e1ba50d364fc13af5fc3e1 *tests/data/fate/vsynth1-y41p.avi 7610052 tests/data/fate/vsynth1-y41p.avi 3aef1d83732a3f9835ee2523a11c95c1 *tests/data/fate/vsynth1-y41p.out.rawvideo stddev: 5.98 PSNR: 32.59 MAXDIFF: 87 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth1-yuv b/tests/ref/vsynth/vsynth1-yuv index 8498d68e6acab..9f73c6fc26fac 100644 --- a/tests/ref/vsynth/vsynth1-yuv +++ b/tests/ref/vsynth/vsynth1-yuv @@ -1,4 +1,4 @@ -2b930d809c19e8d50eb4c92474085c27 *tests/data/fate/vsynth1-yuv.avi +795ce63f1fe371b98822b1cb385b062f *tests/data/fate/vsynth1-yuv.avi 7610052 tests/data/fate/vsynth1-yuv.avi c5ccac874dbf808e9088bc3107860042 *tests/data/fate/vsynth1-yuv.out.rawvideo stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-bpp1 b/tests/ref/vsynth/vsynth2-bpp1 index 4005755662fab..3b512e9a6ab66 100644 --- a/tests/ref/vsynth/vsynth2-bpp1 +++ b/tests/ref/vsynth/vsynth2-bpp1 @@ -1,4 +1,4 @@ -a0330430d7dbd76cbd6d099b778397e8 *tests/data/fate/vsynth2-bpp1.avi +22664dc7e6cefc580b1456502c46eb10 *tests/data/fate/vsynth2-bpp1.avi 640460 tests/data/fate/vsynth2-bpp1.avi f0dfc0e87e5d96bce29a5944b1bd7471 *tests/data/fate/vsynth2-bpp1.out.rawvideo stddev: 68.98 PSNR: 11.36 MAXDIFF: 218 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-bpp15 b/tests/ref/vsynth/vsynth2-bpp15 index 153b21e55548d..9236c25b950ce 100644 --- a/tests/ref/vsynth/vsynth2-bpp15 +++ b/tests/ref/vsynth/vsynth2-bpp15 @@ -1,4 +1,4 @@ -4bf0992de6b40389a35cd744f76bb213 *tests/data/fate/vsynth2-bpp15.avi +1760b76ddf1df0092333434f1a97407b *tests/data/fate/vsynth2-bpp15.avi 10144452 tests/data/fate/vsynth2-bpp15.avi 9a40133384e3f22c960d70c8cfe51781 *tests/data/fate/vsynth2-bpp15.out.rawvideo stddev: 33.97 PSNR: 17.51 MAXDIFF: 154 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-r210 b/tests/ref/vsynth/vsynth2-r210 index 3e19ef840d88d..dc5ff1849c233 100644 --- a/tests/ref/vsynth/vsynth2-r210 +++ b/tests/ref/vsynth/vsynth2-r210 @@ -1,4 +1,4 @@ -50e82830a941457a3cade01394e34dd0 *tests/data/fate/vsynth2-r210.avi +2f928096d892ce0239832afc369e117c *tests/data/fate/vsynth2-r210.avi 22125252 tests/data/fate/vsynth2-r210.avi 2ade5f6167d7a4a1589e168ddbbc35d0 *tests/data/fate/vsynth2-r210.out.rawvideo stddev: 1.17 PSNR: 46.71 MAXDIFF: 15 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-rgb b/tests/ref/vsynth/vsynth2-rgb index 93fe634b9ebc4..6d44b2548956e 100644 --- a/tests/ref/vsynth/vsynth2-rgb +++ b/tests/ref/vsynth/vsynth2-rgb @@ -1,4 +1,4 @@ -707159e45a20b22d383e71d3e5960753 *tests/data/fate/vsynth2-rgb.avi +3f8f04636aa027d1fc8245b08c7a8414 *tests/data/fate/vsynth2-rgb.avi 15213252 tests/data/fate/vsynth2-rgb.avi 32fae3e665407bb4317b3f90fedb903c *tests/data/fate/vsynth2-rgb.out.rawvideo stddev: 1.54 PSNR: 44.37 MAXDIFF: 17 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-v210 b/tests/ref/vsynth/vsynth2-v210 index cc72bb222002b..3bd4598b406b3 100644 --- a/tests/ref/vsynth/vsynth2-v210 +++ b/tests/ref/vsynth/vsynth2-v210 @@ -1,4 +1,4 @@ -211a901d7e6327cc7a48a80250acf4f8 *tests/data/fate/vsynth2-v210.avi +7a4f5840860ae0bec0c354025b488118 *tests/data/fate/vsynth2-v210.avi 14752452 tests/data/fate/vsynth2-v210.avi 99e367a50da75c2c187230889bee8e2e *tests/data/fate/vsynth2-v210.out.rawvideo stddev: 0.40 PSNR: 56.06 MAXDIFF: 9 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-v210-10 b/tests/ref/vsynth/vsynth2-v210-10 index db38b2f598b2f..4e973aa2a46fd 100644 --- a/tests/ref/vsynth/vsynth2-v210-10 +++ b/tests/ref/vsynth/vsynth2-v210-10 @@ -1,4 +1,4 @@ -02a5d983deb4bc91bb273c2b26c3100f *tests/data/fate/vsynth2-v210-10.avi +d078cb3cbbbc022ed7c5c448026b050a *tests/data/fate/vsynth2-v210-10.avi 14752452 tests/data/fate/vsynth2-v210-10.avi 8bb1c449e1a2a94fd0d98841c04246bb *tests/data/fate/vsynth2-v210-10.out.rawvideo stddev: 0.39 PSNR: 56.17 MAXDIFF: 9 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-v308 b/tests/ref/vsynth/vsynth2-v308 index f1fee2d7d4992..cc36d8a3a1025 100644 --- a/tests/ref/vsynth/vsynth2-v308 +++ b/tests/ref/vsynth/vsynth2-v308 @@ -1,4 +1,4 @@ -a07c9e12508dec90a414a4a6119c5ae4 *tests/data/fate/vsynth2-v308.avi +866fb5095976d62279c402023526d7a9 *tests/data/fate/vsynth2-v308.avi 15213252 tests/data/fate/vsynth2-v308.avi 8394327c14ef0b6fbaae3b69fcc5572a *tests/data/fate/vsynth2-v308.out.rawvideo stddev: 0.50 PSNR: 54.10 MAXDIFF: 13 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-v408 b/tests/ref/vsynth/vsynth2-v408 index 808135ff2d8a9..688e4e469a794 100644 --- a/tests/ref/vsynth/vsynth2-v408 +++ b/tests/ref/vsynth/vsynth2-v408 @@ -1,4 +1,4 @@ -01612752a44782cd99bf6399875d313c *tests/data/fate/vsynth2-v408.avi +a9b25bf6f9559cdbe795913cc69d5c0f *tests/data/fate/vsynth2-v408.avi 20282052 tests/data/fate/vsynth2-v408.avi 36d7ca943916e1743cefa609eba0205c *tests/data/fate/vsynth2-v408.out.rawvideo stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-y41p b/tests/ref/vsynth/vsynth2-y41p index e40a0f3359a48..164a84581efaa 100644 --- a/tests/ref/vsynth/vsynth2-y41p +++ b/tests/ref/vsynth/vsynth2-y41p @@ -1,4 +1,4 @@ -34425303a27433cfa2cf077258c21c68 *tests/data/fate/vsynth2-y41p.avi +4eda6db518001a8f2bbb2ec4b414b05a *tests/data/fate/vsynth2-y41p.avi 7610052 tests/data/fate/vsynth2-y41p.avi 7c760febffcf1c2e43e494f38b010af1 *tests/data/fate/vsynth2-y41p.out.rawvideo stddev: 1.32 PSNR: 45.72 MAXDIFF: 34 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-yuv b/tests/ref/vsynth/vsynth2-yuv index 08c9593c8e4c1..71999680246f0 100644 --- a/tests/ref/vsynth/vsynth2-yuv +++ b/tests/ref/vsynth/vsynth2-yuv @@ -1,4 +1,4 @@ -3d7ecff63ce4863a3d299ff82d910d78 *tests/data/fate/vsynth2-yuv.avi +5eda550fac21e8913cbb2c88e4f0791a *tests/data/fate/vsynth2-yuv.avi 7610052 tests/data/fate/vsynth2-yuv.avi 36d7ca943916e1743cefa609eba0205c *tests/data/fate/vsynth2-yuv.out.rawvideo stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth3-bpp1 b/tests/ref/vsynth/vsynth3-bpp1 index 3c8c47ac86ded..639a2b15dedd6 100644 --- a/tests/ref/vsynth/vsynth3-bpp1 +++ b/tests/ref/vsynth/vsynth3-bpp1 @@ -1,4 +1,4 @@ -4c8777a88a9e52b99d5a345acffcbf06 *tests/data/fate/vsynth3-bpp1.avi +7eafab02a501b3b0ac9f854cd334f47a *tests/data/fate/vsynth3-bpp1.avi 20460 tests/data/fate/vsynth3-bpp1.avi 52ae74ef7910e5b603c12288d425b9ae *tests/data/fate/vsynth3-bpp1.out.rawvideo stddev: 84.76 PSNR: 9.57 MAXDIFF: 232 bytes: 86700/ 86700 diff --git a/tests/ref/vsynth/vsynth3-bpp15 b/tests/ref/vsynth/vsynth3-bpp15 index fff803721c8dc..fe67e1a980dc1 100644 --- a/tests/ref/vsynth/vsynth3-bpp15 +++ b/tests/ref/vsynth/vsynth3-bpp15 @@ -1,4 +1,4 @@ -9ac236c12757cbf9ee6f95c24a374524 *tests/data/fate/vsynth3-bpp15.avi +ad67910bcee1f3fe49ba7312499a3b16 *tests/data/fate/vsynth3-bpp15.avi 122452 tests/data/fate/vsynth3-bpp15.avi 85ac2fa98252ae907b97a7a561ca676f *tests/data/fate/vsynth3-bpp15.out.rawvideo stddev: 37.76 PSNR: 16.59 MAXDIFF: 156 bytes: 86700/ 86700 diff --git a/tests/ref/vsynth/vsynth3-r210 b/tests/ref/vsynth/vsynth3-r210 index cdbdb283bc414..75c424cf28665 100644 --- a/tests/ref/vsynth/vsynth3-r210 +++ b/tests/ref/vsynth/vsynth3-r210 @@ -1,4 +1,4 @@ -40b93804d521e2b7c82a3060dec81221 *tests/data/fate/vsynth3-r210.avi +229e700e0fab4e81481e99a70e00bec9 *tests/data/fate/vsynth3-r210.avi 442052 tests/data/fate/vsynth3-r210.avi e1d882babc8754f7418aa91ce48f7ab0 *tests/data/fate/vsynth3-r210.out.rawvideo stddev: 3.48 PSNR: 37.28 MAXDIFF: 42 bytes: 86700/ 86700 diff --git a/tests/ref/vsynth/vsynth3-rgb b/tests/ref/vsynth/vsynth3-rgb index f67d28580255f..1a882ce1041e3 100644 --- a/tests/ref/vsynth/vsynth3-rgb +++ b/tests/ref/vsynth/vsynth3-rgb @@ -1,4 +1,4 @@ -000bd5f3251bfd6a2a2b590b2d16fe0b *tests/data/fate/vsynth3-rgb.avi +3e2909a69865eb88df72916c38d265de *tests/data/fate/vsynth3-rgb.avi 183652 tests/data/fate/vsynth3-rgb.avi 693aff10c094f8bd31693f74cf79d2b2 *tests/data/fate/vsynth3-rgb.out.rawvideo stddev: 3.67 PSNR: 36.82 MAXDIFF: 43 bytes: 86700/ 86700 diff --git a/tests/ref/vsynth/vsynth3-v210 b/tests/ref/vsynth/vsynth3-v210 index 658f90c31ebd3..f5282eee4b9cf 100644 --- a/tests/ref/vsynth/vsynth3-v210 +++ b/tests/ref/vsynth/vsynth3-v210 @@ -1,4 +1,4 @@ -df0ae6cafc1aedbf17176eb44a732e4d *tests/data/fate/vsynth3-v210.avi +6824f941ed079952cdf22cc9cdfaa35d *tests/data/fate/vsynth3-v210.avi 224452 tests/data/fate/vsynth3-v210.avi 198ffb24c06927d8aaac5e59d81a0934 *tests/data/fate/vsynth3-v210.out.rawvideo stddev: 2.11 PSNR: 41.61 MAXDIFF: 27 bytes: 86700/ 86700 diff --git a/tests/ref/vsynth/vsynth3-v210-10 b/tests/ref/vsynth/vsynth3-v210-10 index 1a664afdcc295..46fe24dc7ed9e 100644 --- a/tests/ref/vsynth/vsynth3-v210-10 +++ b/tests/ref/vsynth/vsynth3-v210-10 @@ -1,4 +1,4 @@ -b68ad16e3bfd78556b816ec1a676445c *tests/data/fate/vsynth3-v210-10.avi +83eef7004f81a2f9529941ed27554509 *tests/data/fate/vsynth3-v210-10.avi 224452 tests/data/fate/vsynth3-v210-10.avi 0cf7cf68724fa5146b1667e4fa08b0e1 *tests/data/fate/vsynth3-v210-10.out.rawvideo stddev: 2.12 PSNR: 41.58 MAXDIFF: 26 bytes: 86700/ 86700 diff --git a/tests/ref/vsynth/vsynth3-v308 b/tests/ref/vsynth/vsynth3-v308 index 347d4755dc876..b823c7bad4c6f 100644 --- a/tests/ref/vsynth/vsynth3-v308 +++ b/tests/ref/vsynth/vsynth3-v308 @@ -1,4 +1,4 @@ -073e24cc00a27436e97e0b242d4fd077 *tests/data/fate/vsynth3-v308.avi +e1259287375d05431ee718e50eb7f37b *tests/data/fate/vsynth3-v308.avi 180252 tests/data/fate/vsynth3-v308.avi 02a85ec07377df6b483281038f8882ee *tests/data/fate/vsynth3-v308.out.rawvideo stddev: 3.06 PSNR: 38.40 MAXDIFF: 40 bytes: 86700/ 86700 diff --git a/tests/ref/vsynth/vsynth3-v408 b/tests/ref/vsynth/vsynth3-v408 index 2da09e1825561..b64f7d8e1ae8c 100644 --- a/tests/ref/vsynth/vsynth3-v408 +++ b/tests/ref/vsynth/vsynth3-v408 @@ -1,4 +1,4 @@ -e74a1abf73b9df90f5103d901b37185f *tests/data/fate/vsynth3-v408.avi +c75fc69c19c6c578ec95c3972f4af339 *tests/data/fate/vsynth3-v408.avi 238052 tests/data/fate/vsynth3-v408.avi a038ad7c3c09f776304ef7accdea9c74 *tests/data/fate/vsynth3-v408.out.rawvideo stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 86700/ 86700 diff --git a/tests/ref/vsynth/vsynth3-yuv b/tests/ref/vsynth/vsynth3-yuv index aa2cf2fad2b7e..ceeb1059c6484 100644 --- a/tests/ref/vsynth/vsynth3-yuv +++ b/tests/ref/vsynth/vsynth3-yuv @@ -1,4 +1,4 @@ -080401647f4b08df4fb44a253c914cc0 *tests/data/fate/vsynth3-yuv.avi +7935fee60d3eb567baf312900616dec0 *tests/data/fate/vsynth3-yuv.avi 93552 tests/data/fate/vsynth3-yuv.avi a038ad7c3c09f776304ef7accdea9c74 *tests/data/fate/vsynth3-yuv.out.rawvideo stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 86700/ 86700 diff --git a/tests/ref/vsynth/vsynth_lena-bpp1 b/tests/ref/vsynth/vsynth_lena-bpp1 index 348998926836e..a3772551ba9f0 100644 --- a/tests/ref/vsynth/vsynth_lena-bpp1 +++ b/tests/ref/vsynth/vsynth_lena-bpp1 @@ -1,4 +1,4 @@ -32673399a8442e397a608839eb3e95cb *tests/data/fate/vsynth_lena-bpp1.avi +8dc90696dabf220a8f4413af20e93073 *tests/data/fate/vsynth_lena-bpp1.avi 640460 tests/data/fate/vsynth_lena-bpp1.avi 6183ba861d4e48d4aaefc514fde270e5 *tests/data/fate/vsynth_lena-bpp1.out.rawvideo stddev: 83.28 PSNR: 9.72 MAXDIFF: 215 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth_lena-bpp15 b/tests/ref/vsynth/vsynth_lena-bpp15 index 96dbf6d493267..65bff0bfd01c3 100644 --- a/tests/ref/vsynth/vsynth_lena-bpp15 +++ b/tests/ref/vsynth/vsynth_lena-bpp15 @@ -1,4 +1,4 @@ -b1b2dd35bcb3d5c20651ffe0da55cb46 *tests/data/fate/vsynth_lena-bpp15.avi +64516ba947d531db2bccc2ecc338b7be *tests/data/fate/vsynth_lena-bpp15.avi 10144452 tests/data/fate/vsynth_lena-bpp15.avi ccf6fc507e938e8cc5c2a97b644de51c *tests/data/fate/vsynth_lena-bpp15.out.rawvideo stddev: 32.84 PSNR: 17.80 MAXDIFF: 92 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth_lena-r210 b/tests/ref/vsynth/vsynth_lena-r210 index 3ed30ff5061db..8fd1a666afcf0 100644 --- a/tests/ref/vsynth/vsynth_lena-r210 +++ b/tests/ref/vsynth/vsynth_lena-r210 @@ -1,4 +1,4 @@ -e5f96a1d0fe5c519f6cb954838e105bc *tests/data/fate/vsynth_lena-r210.avi +94874a48987fd401494f4d7ca8e1273b *tests/data/fate/vsynth_lena-r210.avi 22125252 tests/data/fate/vsynth_lena-r210.avi 6ea4fcd93fc83defc8770e85b64b60bb *tests/data/fate/vsynth_lena-r210.out.rawvideo stddev: 0.70 PSNR: 51.12 MAXDIFF: 12 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth_lena-rgb b/tests/ref/vsynth/vsynth_lena-rgb index 9706ffba83cc8..f3d232e76c84c 100644 --- a/tests/ref/vsynth/vsynth_lena-rgb +++ b/tests/ref/vsynth/vsynth_lena-rgb @@ -1,4 +1,4 @@ -f083e812216195c1e9454b5fac681c92 *tests/data/fate/vsynth_lena-rgb.avi +6ffbbd6939b3fe9f5dcf036ee46aad2d *tests/data/fate/vsynth_lena-rgb.avi 15213252 tests/data/fate/vsynth_lena-rgb.avi 98d0e2854731472c5bf13d8638502d0a *tests/data/fate/vsynth_lena-rgb.out.rawvideo stddev: 1.26 PSNR: 46.10 MAXDIFF: 13 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth_lena-v210 b/tests/ref/vsynth/vsynth_lena-v210 index ef5020b3f30d8..549bf43fe132e 100644 --- a/tests/ref/vsynth/vsynth_lena-v210 +++ b/tests/ref/vsynth/vsynth_lena-v210 @@ -1,4 +1,4 @@ -20af8b986704b9713cd75d3e6e41efa4 *tests/data/fate/vsynth_lena-v210.avi +0e0db58fa269cffbfb15f81277fa2828 *tests/data/fate/vsynth_lena-v210.avi 14752452 tests/data/fate/vsynth_lena-v210.avi 7ba6e411e43c6b57c95c49d6848f41e6 *tests/data/fate/vsynth_lena-v210.out.rawvideo stddev: 0.34 PSNR: 57.41 MAXDIFF: 6 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth_lena-v210-10 b/tests/ref/vsynth/vsynth_lena-v210-10 index 1e5732bd55018..9541b57d7f199 100644 --- a/tests/ref/vsynth/vsynth_lena-v210-10 +++ b/tests/ref/vsynth/vsynth_lena-v210-10 @@ -1,4 +1,4 @@ -a3913b719397fae870c1d9bc35053259 *tests/data/fate/vsynth_lena-v210-10.avi +0d638c575c7784c2d445f7f7e3b889bc *tests/data/fate/vsynth_lena-v210-10.avi 14752452 tests/data/fate/vsynth_lena-v210-10.avi a627fb50c8276200fd71383977d87ca3 *tests/data/fate/vsynth_lena-v210-10.out.rawvideo stddev: 0.34 PSNR: 57.43 MAXDIFF: 6 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth_lena-v308 b/tests/ref/vsynth/vsynth_lena-v308 index 6de15b5aa49d3..81766df82fc65 100644 --- a/tests/ref/vsynth/vsynth_lena-v308 +++ b/tests/ref/vsynth/vsynth_lena-v308 @@ -1,4 +1,4 @@ -5bff4d7763e624272835e056c9faf4c2 *tests/data/fate/vsynth_lena-v308.avi +eabb002088244fa802b67aea78271641 *tests/data/fate/vsynth_lena-v308.avi 15213252 tests/data/fate/vsynth_lena-v308.avi d43cb310c130c69214332d74f6ee5f9a *tests/data/fate/vsynth_lena-v308.out.rawvideo stddev: 0.41 PSNR: 55.80 MAXDIFF: 7 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth_lena-v408 b/tests/ref/vsynth/vsynth_lena-v408 index ba19e28d2ee5d..2c67dcdac852b 100644 --- a/tests/ref/vsynth/vsynth_lena-v408 +++ b/tests/ref/vsynth/vsynth_lena-v408 @@ -1,4 +1,4 @@ -e2a1c097a78f1a5c8ad1bccc4077844b *tests/data/fate/vsynth_lena-v408.avi +ba166cd36099177b3942b16cd2c200fc *tests/data/fate/vsynth_lena-v408.avi 20282052 tests/data/fate/vsynth_lena-v408.avi dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth_lena-v408.out.rawvideo stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth_lena-y41p b/tests/ref/vsynth/vsynth_lena-y41p index 9cc09573b0a88..325d752073103 100644 --- a/tests/ref/vsynth/vsynth_lena-y41p +++ b/tests/ref/vsynth/vsynth_lena-y41p @@ -1,4 +1,4 @@ -3b958734c653d265cd42e31d6a22230f *tests/data/fate/vsynth_lena-y41p.avi +159548ec0881286674e4a1bd75b89f9e *tests/data/fate/vsynth_lena-y41p.avi 7610052 tests/data/fate/vsynth_lena-y41p.avi d27a84ccdac09055724d122e03fea82a *tests/data/fate/vsynth_lena-y41p.out.rawvideo stddev: 1.07 PSNR: 47.54 MAXDIFF: 21 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth_lena-yuv b/tests/ref/vsynth/vsynth_lena-yuv index bc27dcf6ae175..645ef8bb8d2e1 100644 --- a/tests/ref/vsynth/vsynth_lena-yuv +++ b/tests/ref/vsynth/vsynth_lena-yuv @@ -1,4 +1,4 @@ -0d061b0b7bedcd59e5c90a99f58ceeae *tests/data/fate/vsynth_lena-yuv.avi +2f4102cd4375383c0a3b6114a502996f *tests/data/fate/vsynth_lena-yuv.avi 7610052 tests/data/fate/vsynth_lena-yuv.avi dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth_lena-yuv.out.rawvideo stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200 From 21a8e751ad6abb2d423afa3041da92f8f7741997 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Tue, 7 Mar 2017 19:15:28 -0500 Subject: [PATCH 1182/3374] fate: Do not report side data size This field is of little value, and interferes with testing side data, since sizes can be different on multiple architectures. Signed-off-by: Vittorio Giovara --- ffprobe.c | 2 - .../ref/fate/concat-demuxer-extended-lavf-mxf | 2 +- .../fate/concat-demuxer-extended-lavf-mxf_d10 | 2 +- .../ref/fate/concat-demuxer-simple1-lavf-mxf | 42 +++--- .../fate/concat-demuxer-simple1-lavf-mxf_d10 | 20 +-- tests/ref/fate/concat-demuxer-simple2-lavf-ts | 128 +++++++++--------- tests/ref/fate/matroska-spherical-mono | 2 - tests/ref/fate/mov-displaymatrix | 1 - tests/ref/fate/mov-spherical-mono | 2 - tests/ref/fate/mov-zombie | 2 +- 10 files changed, 98 insertions(+), 105 deletions(-) diff --git a/ffprobe.c b/ffprobe.c index 17dc73294fe44..4a7ec0ad3111c 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -1777,7 +1777,6 @@ static void print_pkt_side_data(WriterContext *w, writer_print_section_header(w, SECTION_ID_STREAM_SIDE_DATA); print_str("side_data_type", name ? name : "unknown"); - print_int("side_data_size", sd->size); if (sd->type == AV_PKT_DATA_DISPLAYMATRIX && sd->size >= 9*4) { writer_print_integers(w, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1); print_int("rotation", av_display_rotation_get((int32_t *)sd->data)); @@ -1970,7 +1969,6 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream, writer_print_section_header(w, SECTION_ID_FRAME_SIDE_DATA); name = av_frame_side_data_name(sd->type); print_str("side_data_type", name ? name : "unknown"); - print_int("side_data_size", sd->size); if (sd->type == AV_FRAME_DATA_DISPLAYMATRIX && sd->size >= 9*4) { writer_print_integers(w, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1); print_int("rotation", av_display_rotation_get((int32_t *)sd->data)); diff --git a/tests/ref/fate/concat-demuxer-extended-lavf-mxf b/tests/ref/fate/concat-demuxer-extended-lavf-mxf index f6b1010bea91e..c47f14faa1572 100644 --- a/tests/ref/fate/concat-demuxer-extended-lavf-mxf +++ b/tests/ref/fate/concat-demuxer-extended-lavf-mxf @@ -1 +1 @@ -32fe9ae5b89c7802c804ac51f62d89cb *tests/data/fate/concat-demuxer-extended-lavf-mxf.ffprobe +7e53f4c5cb0c9afda2771c9f0c697d9c *tests/data/fate/concat-demuxer-extended-lavf-mxf.ffprobe diff --git a/tests/ref/fate/concat-demuxer-extended-lavf-mxf_d10 b/tests/ref/fate/concat-demuxer-extended-lavf-mxf_d10 index 6d84589fbdbc6..75d386e3c1795 100644 --- a/tests/ref/fate/concat-demuxer-extended-lavf-mxf_d10 +++ b/tests/ref/fate/concat-demuxer-extended-lavf-mxf_d10 @@ -1 +1 @@ -0724a00f35550e4ae1e87240a5c95050 *tests/data/fate/concat-demuxer-extended-lavf-mxf_d10.ffprobe +44810fc2eeee0072d9d7011b0d2afe59 *tests/data/fate/concat-demuxer-extended-lavf-mxf_d10.ffprobe diff --git a/tests/ref/fate/concat-demuxer-simple1-lavf-mxf b/tests/ref/fate/concat-demuxer-simple1-lavf-mxf index d71acbe7b1b3e..1174a1e183124 100644 --- a/tests/ref/fate/concat-demuxer-simple1-lavf-mxf +++ b/tests/ref/fate/concat-demuxer-simple1-lavf-mxf @@ -79,46 +79,46 @@ audio|1|53760|1.120000|53760|1.120000|1920|0.040000|N/A|N/A|3840|501248|K_ video|0|28|1.120000|28|1.120000|1|0.040000|N/A|N/A|13350|505856|__ audio|1|55680|1.160000|55680|1.160000|1920|0.040000|N/A|N/A|3840|519680|K_ video|0|25|1.000000|24|0.960000|1|0.040000|N/A|N/A|24801|6144|K_|1 -Strings Metadata|8 +Strings Metadata audio|1|48000|1.000000|48000|1.000000|1920|0.040000|N/A|N/A|3840|31232|K_|1 -Strings Metadata|8 +Strings Metadata video|0|28|1.120000|25|1.000000|1|0.040000|N/A|N/A|16743|35840|__|1 -Strings Metadata|8 +Strings Metadata audio|1|49920|1.040000|49920|1.040000|1920|0.040000|N/A|N/A|3840|52736|K_|1 -Strings Metadata|8 +Strings Metadata video|0|26|1.040000|26|1.040000|1|0.040000|N/A|N/A|13812|57344|__|1 -Strings Metadata|8 +Strings Metadata audio|1|51840|1.080000|51840|1.080000|1920|0.040000|N/A|N/A|3840|71680|K_|1 -Strings Metadata|8 +Strings Metadata video|0|27|1.080000|27|1.080000|1|0.040000|N/A|N/A|13607|76288|__|1 -Strings Metadata|8 +Strings Metadata audio|1|53760|1.120000|53760|1.120000|1920|0.040000|N/A|N/A|3840|90112|K_|1 -Strings Metadata|8 +Strings Metadata video|0|31|1.240000|28|1.120000|1|0.040000|N/A|N/A|16158|94720|__|1 -Strings Metadata|8 +Strings Metadata audio|1|55680|1.160000|55680|1.160000|1920|0.040000|N/A|N/A|3840|111104|K_|1 -Strings Metadata|8 +Strings Metadata video|0|29|1.160000|29|1.160000|1|0.040000|N/A|N/A|13943|115712|__|1 -Strings Metadata|8 +Strings Metadata audio|1|57600|1.200000|57600|1.200000|1920|0.040000|N/A|N/A|3840|130048|K_|1 -Strings Metadata|8 +Strings Metadata video|0|30|1.200000|30|1.200000|1|0.040000|N/A|N/A|11223|134656|__|1 -Strings Metadata|8 +Strings Metadata audio|1|59520|1.240000|59520|1.240000|1920|0.040000|N/A|N/A|3840|145920|K_|1 -Strings Metadata|8 +Strings Metadata video|0|34|1.360000|31|1.240000|1|0.040000|N/A|N/A|20298|150528|__|1 -Strings Metadata|8 +Strings Metadata audio|1|61440|1.280000|61440|1.280000|1920|0.040000|N/A|N/A|3840|171008|K_|1 -Strings Metadata|8 +Strings Metadata video|0|32|1.280000|32|1.280000|1|0.040000|N/A|N/A|13341|175616|__|1 -Strings Metadata|8 +Strings Metadata audio|1|63360|1.320000|63360|1.320000|1920|0.040000|N/A|N/A|3840|189440|K_|1 -Strings Metadata|8 +Strings Metadata video|0|33|1.320000|33|1.320000|1|0.040000|N/A|N/A|12362|194048|__|1 -Strings Metadata|8 +Strings Metadata audio|1|65280|1.360000|65280|1.360000|1920|0.040000|N/A|N/A|3840|206848|K_|1 -Strings Metadata|8 +Strings Metadata video|0|37|1.480000|34|1.360000|1|0.040000|N/A|N/A|24786|211456|K_|1 -Strings Metadata|8 +Strings Metadata 0|mpeg2video|4|video|1/25|[0][0][0][0]|0x0000|352|288|0|0|1|1:1|11:9|yuv420p|8|tv|unknown|unknown|unknown|left|progressive|N/A|1|N/A|25/1|25/1|1/25|N/A|N/A|N/A|N/A|N/A|N/A|N/A|N/A|N/A|51|0|0|0|0|0|0|0|0|0|0|0|0|0x060A2B340101010501010D001300000000000000000000000000000000000001 1|pcm_s16le|unknown|audio|1/48000|[0][0][0][0]|0x0000|s16|48000|1|unknown|16|N/A|0/0|0/0|1/48000|0|0.000000|N/A|N/A|768000|N/A|N/A|N/A|N/A|50|0|0|0|0|0|0|0|0|0|0|0|0|0x060A2B340101010501010D001300000000000000000000000000000000000001 diff --git a/tests/ref/fate/concat-demuxer-simple1-lavf-mxf_d10 b/tests/ref/fate/concat-demuxer-simple1-lavf-mxf_d10 index 4c78bb2ab907c..bd0e5e2a747db 100644 --- a/tests/ref/fate/concat-demuxer-simple1-lavf-mxf_d10 +++ b/tests/ref/fate/concat-demuxer-simple1-lavf-mxf_d10 @@ -59,24 +59,24 @@ audio|1|53760|1.120000|53760|1.120000|1920|0.040000|N/A|N/A|7680|5055488|K_ video|0|29|1.160000|29|1.160000|1|0.040000|N/A|N/A|150000|5117952|K_ audio|1|55680|1.160000|55680|1.160000|1920|0.040000|N/A|N/A|7680|5268480|K_ video|0|30|1.200000|30|1.200000|1|0.040000|N/A|N/A|150000|1071104|K_|1 -Strings Metadata|8 +Strings Metadata audio|1|57600|1.200000|57600|1.200000|1920|0.040000|N/A|N/A|7680|1221632|K_|1 -Strings Metadata|8 +Strings Metadata video|0|31|1.240000|31|1.240000|1|0.040000|N/A|N/A|150000|1284096|K_|1 -Strings Metadata|8 +Strings Metadata audio|1|59520|1.240000|59520|1.240000|1920|0.040000|N/A|N/A|7680|1434624|K_|1 -Strings Metadata|8 +Strings Metadata video|0|32|1.280000|32|1.280000|1|0.040000|N/A|N/A|150000|1497088|K_|1 -Strings Metadata|8 +Strings Metadata audio|1|61440|1.280000|61440|1.280000|1920|0.040000|N/A|N/A|7680|1647616|K_|1 -Strings Metadata|8 +Strings Metadata video|0|33|1.320000|33|1.320000|1|0.040000|N/A|N/A|150000|1710080|K_|1 -Strings Metadata|8 +Strings Metadata audio|1|63360|1.320000|63360|1.320000|1920|0.040000|N/A|N/A|7680|1860608|K_|1 -Strings Metadata|8 +Strings Metadata video|0|34|1.360000|34|1.360000|1|0.040000|N/A|N/A|150000|1923072|K_|1 -Strings Metadata|8 +Strings Metadata audio|1|65280|1.360000|65280|1.360000|1920|0.040000|N/A|N/A|7680|2073600|K_|1 -Strings Metadata|8 +Strings Metadata 0|mpeg2video|0|video|1/25|[0][0][0][0]|0x0000|720|608|0|0|0|1:1|45:38|yuv422p|5|tv|unknown|unknown|unknown|topleft|tt|N/A|1|N/A|25/1|25/1|1/25|0|0.000000|N/A|N/A|30000000|N/A|N/A|N/A|N/A|35|0|0|0|0|0|0|0|0|0|0|0|0|0x060A2B340101010501010D001300000000000000000000000000000000000001 1|pcm_s16le|unknown|audio|1/48000|[0][0][0][0]|0x0000|s16|48000|2|unknown|16|N/A|0/0|0/0|1/48000|0|0.000000|N/A|N/A|1536000|N/A|N/A|N/A|N/A|35|0|0|0|0|0|0|0|0|0|0|0|0|0x060A2B340101010501010D001300000000000000000000000000000000000001 diff --git a/tests/ref/fate/concat-demuxer-simple2-lavf-ts b/tests/ref/fate/concat-demuxer-simple2-lavf-ts index 880f9b7e03f42..e5cf18bbcee34 100644 --- a/tests/ref/fate/concat-demuxer-simple2-lavf-ts +++ b/tests/ref/fate/concat-demuxer-simple2-lavf-ts @@ -1,20 +1,20 @@ -video|1|982|0.010911|-2618|-0.029089|3600|0.040000|N/A|N/A|24801|564|K_MPEGTS Stream ID|1 +video|1|982|0.010911|-2618|-0.029089|3600|0.040000|N/A|N/A|24801|564|K_MPEGTS Stream ID -video|1|4582|0.050911|982|0.010911|3600|0.040000|N/A|N/A|16429|27072|__MPEGTS Stream ID|1 +video|1|4582|0.050911|982|0.010911|3600|0.040000|N/A|N/A|16429|27072|__MPEGTS Stream ID -video|1|8182|0.090911|4582|0.050911|3600|0.040000|N/A|N/A|14508|44932|__MPEGTS Stream ID|1 +video|1|8182|0.090911|4582|0.050911|3600|0.040000|N/A|N/A|14508|44932|__MPEGTS Stream ID -video|1|11782|0.130911|8182|0.090911|3600|0.040000|N/A|N/A|12622|60536|__MPEGTS Stream ID|1 +video|1|11782|0.130911|8182|0.090911|3600|0.040000|N/A|N/A|12622|60536|__MPEGTS Stream ID -video|1|15382|0.170911|11782|0.130911|3600|0.040000|N/A|N/A|13393|74260|__MPEGTS Stream ID|1 +video|1|15382|0.170911|11782|0.130911|3600|0.040000|N/A|N/A|13393|74260|__MPEGTS Stream ID -video|1|18982|0.210911|15382|0.170911|3600|0.040000|N/A|N/A|13092|88924|__MPEGTS Stream ID|1 +video|1|18982|0.210911|15382|0.170911|3600|0.040000|N/A|N/A|13092|88924|__MPEGTS Stream ID -video|1|22582|0.250911|18982|0.210911|3600|0.040000|N/A|N/A|12755|102836|__MPEGTS Stream ID|1 +video|1|22582|0.250911|18982|0.210911|3600|0.040000|N/A|N/A|12755|102836|__MPEGTS Stream ID -video|1|26182|0.290911|22582|0.250911|3600|0.040000|N/A|N/A|12023|116748|__MPEGTS Stream ID|1 +video|1|26182|0.290911|22582|0.250911|3600|0.040000|N/A|N/A|12023|116748|__MPEGTS Stream ID -audio|0|0|0.000000|0|0.000000|2351|0.026122|N/A|N/A|208|159988|K_MPEGTS Stream ID|1 +audio|0|0|0.000000|0|0.000000|2351|0.026122|N/A|N/A|208|159988|K_MPEGTS Stream ID audio|0|2351|0.026122|2351|0.026122|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|4702|0.052244|4702|0.052244|2351|0.026122|N/A|N/A|209|N/A|K_ @@ -29,27 +29,27 @@ audio|0|23510|0.261222|23510|0.261222|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|25861|0.287344|25861|0.287344|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|28212|0.313467|28212|0.313467|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|30563|0.339589|30563|0.339589|2351|0.026122|N/A|N/A|209|N/A|K_ -video|1|29782|0.330911|26182|0.290911|3600|0.040000|N/A|N/A|14098|130096|__MPEGTS Stream ID|1 +video|1|29782|0.330911|26182|0.290911|3600|0.040000|N/A|N/A|14098|130096|__MPEGTS Stream ID -video|1|33382|0.370911|29782|0.330911|3600|0.040000|N/A|N/A|13329|145324|__MPEGTS Stream ID|1 +video|1|33382|0.370911|29782|0.330911|3600|0.040000|N/A|N/A|13329|145324|__MPEGTS Stream ID -video|1|36982|0.410911|33382|0.370911|3600|0.040000|N/A|N/A|12135|162996|__MPEGTS Stream ID|1 +video|1|36982|0.410911|33382|0.370911|3600|0.040000|N/A|N/A|12135|162996|__MPEGTS Stream ID -video|1|40582|0.450911|36982|0.410911|3600|0.040000|N/A|N/A|12282|176344|__MPEGTS Stream ID|1 +video|1|40582|0.450911|36982|0.410911|3600|0.040000|N/A|N/A|12282|176344|__MPEGTS Stream ID -video|1|44182|0.490911|40582|0.450911|3600|0.040000|N/A|N/A|24786|189692|K_MPEGTS Stream ID|1 +video|1|44182|0.490911|40582|0.450911|3600|0.040000|N/A|N/A|24786|189692|K_MPEGTS Stream ID -video|1|47782|0.530911|44182|0.490911|3600|0.040000|N/A|N/A|17440|216388|__MPEGTS Stream ID|1 +video|1|47782|0.530911|44182|0.490911|3600|0.040000|N/A|N/A|17440|216388|__MPEGTS Stream ID -video|1|51382|0.570911|47782|0.530911|3600|0.040000|N/A|N/A|15019|235000|__MPEGTS Stream ID|1 +video|1|51382|0.570911|47782|0.530911|3600|0.040000|N/A|N/A|15019|235000|__MPEGTS Stream ID -video|1|54982|0.610911|51382|0.570911|3600|0.040000|N/A|N/A|13449|251356|__MPEGTS Stream ID|1 +video|1|54982|0.610911|51382|0.570911|3600|0.040000|N/A|N/A|13449|251356|__MPEGTS Stream ID -video|1|58582|0.650911|54982|0.610911|3600|0.040000|N/A|N/A|12398|266020|__MPEGTS Stream ID|1 +video|1|58582|0.650911|54982|0.610911|3600|0.040000|N/A|N/A|12398|266020|__MPEGTS Stream ID -video|1|62182|0.690911|58582|0.650911|3600|0.040000|N/A|N/A|13455|279744|__MPEGTS Stream ID|1 +video|1|62182|0.690911|58582|0.650911|3600|0.040000|N/A|N/A|13455|279744|__MPEGTS Stream ID -audio|0|32915|0.365722|32915|0.365722|2351|0.026122|N/A|N/A|209|322608|K_MPEGTS Stream ID|1 +audio|0|32915|0.365722|32915|0.365722|2351|0.026122|N/A|N/A|209|322608|K_MPEGTS Stream ID audio|0|35266|0.391844|35266|0.391844|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|37617|0.417967|37617|0.417967|2351|0.026122|N/A|N/A|209|N/A|K_ @@ -64,17 +64,17 @@ audio|0|56425|0.626944|56425|0.626944|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|58776|0.653067|58776|0.653067|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|61127|0.679189|61127|0.679189|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|63478|0.705311|63478|0.705311|2351|0.026122|N/A|N/A|209|N/A|K_ -video|1|65782|0.730911|62182|0.690911|3600|0.040000|N/A|N/A|13836|294408|__MPEGTS Stream ID|1 +video|1|65782|0.730911|62182|0.690911|3600|0.040000|N/A|N/A|13836|294408|__MPEGTS Stream ID -video|1|69382|0.770911|65782|0.730911|3600|0.040000|N/A|N/A|12163|309448|__MPEGTS Stream ID|1 +video|1|69382|0.770911|65782|0.730911|3600|0.040000|N/A|N/A|12163|309448|__MPEGTS Stream ID -video|1|72982|0.810911|69382|0.770911|3600|0.040000|N/A|N/A|12692|325992|__MPEGTS Stream ID|1 +video|1|72982|0.810911|69382|0.770911|3600|0.040000|N/A|N/A|12692|325992|__MPEGTS Stream ID -video|1|76582|0.850911|72982|0.810911|3600|0.040000|N/A|N/A|10824|339528|__MPEGTS Stream ID|1 +video|1|76582|0.850911|72982|0.810911|3600|0.040000|N/A|N/A|10824|339528|__MPEGTS Stream ID -video|1|80182|0.890911|76582|0.850911|3600|0.040000|N/A|N/A|11286|351372|__MPEGTS Stream ID|1 +video|1|80182|0.890911|76582|0.850911|3600|0.040000|N/A|N/A|11286|351372|__MPEGTS Stream ID -audio|0|65829|0.731433|65829|0.731433|2351|0.026122|N/A|N/A|209|404576|K_MPEGTS Stream ID|1 +audio|0|65829|0.731433|65829|0.731433|2351|0.026122|N/A|N/A|209|404576|K_MPEGTS Stream ID audio|0|68180|0.757556|68180|0.757556|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|70531|0.783678|70531|0.783678|2351|0.026122|N/A|N/A|209|N/A|K_ @@ -86,26 +86,26 @@ audio|0|82286|0.914289|82286|0.914289|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|84637|0.940411|84637|0.940411|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|86988|0.966533|86988|0.966533|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|89339|0.992656|89339|0.992656|2351|0.026122|N/A|N/A|209|N/A|K_ -video|1|83782|0.930911|80182|0.890911|3600|0.040000|N/A|N/A|12678|363592|__MPEGTS Stream ID|1 +video|1|83782|0.930911|80182|0.890911|3600|0.040000|N/A|N/A|12678|363592|__MPEGTS Stream ID video|1|87382|0.970911|83782|0.930911|3600|0.040000|N/A|N/A|24711|377880|K_ -video|1|91964|1.021822|88364|0.981822|3600|0.040000|N/A|N/A|24801|564|K_MPEGTS Stream ID|1 +video|1|91964|1.021822|88364|0.981822|3600|0.040000|N/A|N/A|24801|564|K_MPEGTS Stream ID -video|1|95564|1.061822|91964|1.021822|3600|0.040000|N/A|N/A|16429|27072|__MPEGTS Stream ID|1 +video|1|95564|1.061822|91964|1.021822|3600|0.040000|N/A|N/A|16429|27072|__MPEGTS Stream ID -video|1|99164|1.101822|95564|1.061822|3600|0.040000|N/A|N/A|14508|44932|__MPEGTS Stream ID|1 +video|1|99164|1.101822|95564|1.061822|3600|0.040000|N/A|N/A|14508|44932|__MPEGTS Stream ID -video|1|102764|1.141822|99164|1.101822|3600|0.040000|N/A|N/A|12622|60536|__MPEGTS Stream ID|1 +video|1|102764|1.141822|99164|1.101822|3600|0.040000|N/A|N/A|12622|60536|__MPEGTS Stream ID -video|1|106364|1.181822|102764|1.141822|3600|0.040000|N/A|N/A|13393|74260|__MPEGTS Stream ID|1 +video|1|106364|1.181822|102764|1.141822|3600|0.040000|N/A|N/A|13393|74260|__MPEGTS Stream ID -video|1|109964|1.221822|106364|1.181822|3600|0.040000|N/A|N/A|13092|88924|__MPEGTS Stream ID|1 +video|1|109964|1.221822|106364|1.181822|3600|0.040000|N/A|N/A|13092|88924|__MPEGTS Stream ID -video|1|113564|1.261822|109964|1.221822|3600|0.040000|N/A|N/A|12755|102836|__MPEGTS Stream ID|1 +video|1|113564|1.261822|109964|1.221822|3600|0.040000|N/A|N/A|12755|102836|__MPEGTS Stream ID -video|1|117164|1.301822|113564|1.261822|3600|0.040000|N/A|N/A|12023|116748|__MPEGTS Stream ID|1 +video|1|117164|1.301822|113564|1.261822|3600|0.040000|N/A|N/A|12023|116748|__MPEGTS Stream ID -audio|0|90982|1.010911|90982|1.010911|2351|0.026122|N/A|N/A|208|159988|K_MPEGTS Stream ID|1 +audio|0|90982|1.010911|90982|1.010911|2351|0.026122|N/A|N/A|208|159988|K_MPEGTS Stream ID audio|0|93333|1.037033|93333|1.037033|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|95684|1.063156|95684|1.063156|2351|0.026122|N/A|N/A|209|N/A|K_ @@ -120,27 +120,27 @@ audio|0|114492|1.272133|114492|1.272133|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|116843|1.298256|116843|1.298256|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|119194|1.324378|119194|1.324378|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|121545|1.350500|121545|1.350500|2351|0.026122|N/A|N/A|209|N/A|K_ -video|1|120764|1.341822|117164|1.301822|3600|0.040000|N/A|N/A|14098|130096|__MPEGTS Stream ID|1 +video|1|120764|1.341822|117164|1.301822|3600|0.040000|N/A|N/A|14098|130096|__MPEGTS Stream ID -video|1|124364|1.381822|120764|1.341822|3600|0.040000|N/A|N/A|13329|145324|__MPEGTS Stream ID|1 +video|1|124364|1.381822|120764|1.341822|3600|0.040000|N/A|N/A|13329|145324|__MPEGTS Stream ID -video|1|127964|1.421822|124364|1.381822|3600|0.040000|N/A|N/A|12135|162996|__MPEGTS Stream ID|1 +video|1|127964|1.421822|124364|1.381822|3600|0.040000|N/A|N/A|12135|162996|__MPEGTS Stream ID -video|1|131564|1.461822|127964|1.421822|3600|0.040000|N/A|N/A|12282|176344|__MPEGTS Stream ID|1 +video|1|131564|1.461822|127964|1.421822|3600|0.040000|N/A|N/A|12282|176344|__MPEGTS Stream ID -video|1|135164|1.501822|131564|1.461822|3600|0.040000|N/A|N/A|24786|189692|K_MPEGTS Stream ID|1 +video|1|135164|1.501822|131564|1.461822|3600|0.040000|N/A|N/A|24786|189692|K_MPEGTS Stream ID -video|1|138764|1.541822|135164|1.501822|3600|0.040000|N/A|N/A|17440|216388|__MPEGTS Stream ID|1 +video|1|138764|1.541822|135164|1.501822|3600|0.040000|N/A|N/A|17440|216388|__MPEGTS Stream ID -video|1|142364|1.581822|138764|1.541822|3600|0.040000|N/A|N/A|15019|235000|__MPEGTS Stream ID|1 +video|1|142364|1.581822|138764|1.541822|3600|0.040000|N/A|N/A|15019|235000|__MPEGTS Stream ID -video|1|145964|1.621822|142364|1.581822|3600|0.040000|N/A|N/A|13449|251356|__MPEGTS Stream ID|1 +video|1|145964|1.621822|142364|1.581822|3600|0.040000|N/A|N/A|13449|251356|__MPEGTS Stream ID -video|1|149564|1.661822|145964|1.621822|3600|0.040000|N/A|N/A|12398|266020|__MPEGTS Stream ID|1 +video|1|149564|1.661822|145964|1.621822|3600|0.040000|N/A|N/A|12398|266020|__MPEGTS Stream ID -video|1|153164|1.701822|149564|1.661822|3600|0.040000|N/A|N/A|13455|279744|__MPEGTS Stream ID|1 +video|1|153164|1.701822|149564|1.661822|3600|0.040000|N/A|N/A|13455|279744|__MPEGTS Stream ID -audio|0|123897|1.376633|123897|1.376633|2351|0.026122|N/A|N/A|209|322608|K_MPEGTS Stream ID|1 +audio|0|123897|1.376633|123897|1.376633|2351|0.026122|N/A|N/A|209|322608|K_MPEGTS Stream ID audio|0|126248|1.402756|126248|1.402756|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|128599|1.428878|128599|1.428878|2351|0.026122|N/A|N/A|209|N/A|K_ @@ -155,17 +155,17 @@ audio|0|147407|1.637856|147407|1.637856|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|149758|1.663978|149758|1.663978|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|152109|1.690100|152109|1.690100|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|154460|1.716222|154460|1.716222|2351|0.026122|N/A|N/A|209|N/A|K_ -video|1|156764|1.741822|153164|1.701822|3600|0.040000|N/A|N/A|13836|294408|__MPEGTS Stream ID|1 +video|1|156764|1.741822|153164|1.701822|3600|0.040000|N/A|N/A|13836|294408|__MPEGTS Stream ID -video|1|160364|1.781822|156764|1.741822|3600|0.040000|N/A|N/A|12163|309448|__MPEGTS Stream ID|1 +video|1|160364|1.781822|156764|1.741822|3600|0.040000|N/A|N/A|12163|309448|__MPEGTS Stream ID -video|1|163964|1.821822|160364|1.781822|3600|0.040000|N/A|N/A|12692|325992|__MPEGTS Stream ID|1 +video|1|163964|1.821822|160364|1.781822|3600|0.040000|N/A|N/A|12692|325992|__MPEGTS Stream ID -video|1|167564|1.861822|163964|1.821822|3600|0.040000|N/A|N/A|10824|339528|__MPEGTS Stream ID|1 +video|1|167564|1.861822|163964|1.821822|3600|0.040000|N/A|N/A|10824|339528|__MPEGTS Stream ID -video|1|171164|1.901822|167564|1.861822|3600|0.040000|N/A|N/A|11286|351372|__MPEGTS Stream ID|1 +video|1|171164|1.901822|167564|1.861822|3600|0.040000|N/A|N/A|11286|351372|__MPEGTS Stream ID -audio|0|156811|1.742344|156811|1.742344|2351|0.026122|N/A|N/A|209|404576|K_MPEGTS Stream ID|1 +audio|0|156811|1.742344|156811|1.742344|2351|0.026122|N/A|N/A|209|404576|K_MPEGTS Stream ID audio|0|159162|1.768467|159162|1.768467|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|161513|1.794589|161513|1.794589|2351|0.026122|N/A|N/A|209|N/A|K_ @@ -177,16 +177,16 @@ audio|0|173268|1.925200|173268|1.925200|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|175619|1.951322|175619|1.951322|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|177970|1.977444|177970|1.977444|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|180321|2.003567|180321|2.003567|2351|0.026122|N/A|N/A|209|N/A|K_ -video|1|174764|1.941822|171164|1.901822|3600|0.040000|N/A|N/A|12678|363592|__MPEGTS Stream ID|1 +video|1|174764|1.941822|171164|1.901822|3600|0.040000|N/A|N/A|12678|363592|__MPEGTS Stream ID video|1|178364|1.981822|174764|1.941822|3600|0.040000|N/A|N/A|24711|377880|K_ -video|1|139582|1.550911|135982|1.510911|3600|0.040000|N/A|N/A|12692|325992|__MPEGTS Stream ID|1 +video|1|139582|1.550911|135982|1.510911|3600|0.040000|N/A|N/A|12692|325992|__MPEGTS Stream ID -video|1|143182|1.590911|139582|1.550911|3600|0.040000|N/A|N/A|10824|339528|__MPEGTS Stream ID|1 +video|1|143182|1.590911|139582|1.550911|3600|0.040000|N/A|N/A|10824|339528|__MPEGTS Stream ID -video|1|146782|1.630911|143182|1.590911|3600|0.040000|N/A|N/A|11286|351372|__MPEGTS Stream ID|1 +video|1|146782|1.630911|143182|1.590911|3600|0.040000|N/A|N/A|11286|351372|__MPEGTS Stream ID -audio|0|132429|1.471433|132429|1.471433|2351|0.026122|N/A|N/A|209|404576|K_MPEGTS Stream ID|1 +audio|0|132429|1.471433|132429|1.471433|2351|0.026122|N/A|N/A|209|404576|K_MPEGTS Stream ID audio|0|134780|1.497556|134780|1.497556|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|137131|1.523678|137131|1.523678|2351|0.026122|N/A|N/A|209|N/A|K_ @@ -198,18 +198,18 @@ audio|0|148886|1.654289|148886|1.654289|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|151237|1.680411|151237|1.680411|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|153588|1.706533|153588|1.706533|2351|0.026122|N/A|N/A|209|N/A|K_ audio|0|155939|1.732656|155939|1.732656|2351|0.026122|N/A|N/A|209|N/A|K_ -video|1|150382|1.670911|146782|1.630911|3600|0.040000|N/A|N/A|12678|363592|__MPEGTS Stream ID|1 +video|1|150382|1.670911|146782|1.630911|3600|0.040000|N/A|N/A|12678|363592|__MPEGTS Stream ID video|1|153982|1.710911|150382|1.670911|3600|0.040000|N/A|N/A|24711|377880|K_ -video|1|161182|1.790911|157582|1.750911|3600|0.040000|N/A|N/A|12135|162996|__MPEGTS Stream ID|1 +video|1|161182|1.790911|157582|1.750911|3600|0.040000|N/A|N/A|12135|162996|__MPEGTS Stream ID -video|1|164782|1.830911|161182|1.790911|3600|0.040000|N/A|N/A|12282|176344|__MPEGTS Stream ID|1 +video|1|164782|1.830911|161182|1.790911|3600|0.040000|N/A|N/A|12282|176344|__MPEGTS Stream ID -video|1|168382|1.870911|164782|1.830911|3600|0.040000|N/A|N/A|24786|189692|K_MPEGTS Stream ID|1 +video|1|168382|1.870911|164782|1.830911|3600|0.040000|N/A|N/A|24786|189692|K_MPEGTS Stream ID -video|1|171982|1.910911|168382|1.870911|3600|0.040000|N/A|N/A|17440|216388|__MPEGTS Stream ID|1 +video|1|171982|1.910911|168382|1.870911|3600|0.040000|N/A|N/A|17440|216388|__MPEGTS Stream ID -video|1|175582|1.950911|171982|1.910911|3600|0.040000|N/A|N/A|15019|235000|__MPEGTS Stream ID|1 +video|1|175582|1.950911|171982|1.910911|3600|0.040000|N/A|N/A|15019|235000|__MPEGTS Stream ID 0|mp2|unknown|audio|1/44100|[3][0][0][0]|0x0003|s16p|44100|1|mono|0|N/A|0/0|0/0|1/90000|0|0.000000|N/A|N/A|64000|N/A|N/A|N/A|N/A|89|0|0|0|0|0|0|0|0|0|0|0|0 1|mpeg2video|4|video|1/25|[2][0][0][0]|0x0002|352|288|0|0|1|1:1|11:9|yuv420p|8|tv|unknown|unknown|unknown|left|progressive|N/A|1|N/A|25/1|25/1|1/90000|N/A|N/A|N/A|N/A|N/A|N/A|N/A|N/A|N/A|60|0|0|0|0|0|0|0|0|0|0|0|0 diff --git a/tests/ref/fate/matroska-spherical-mono b/tests/ref/fate/matroska-spherical-mono index a70d879f0e464..bd57d94514b4b 100644 --- a/tests/ref/fate/matroska-spherical-mono +++ b/tests/ref/fate/matroska-spherical-mono @@ -1,13 +1,11 @@ [STREAM] [SIDE_DATA] side_data_type=Stereo 3D -side_data_size=8 type=2D inverted=0 [/SIDE_DATA] [SIDE_DATA] side_data_type=Spherical Mapping -side_data_size=56 projection=tiled equirectangular bound_left=148 bound_top=73 diff --git a/tests/ref/fate/mov-displaymatrix b/tests/ref/fate/mov-displaymatrix index 86139fc969487..ac09e2ac04a81 100644 --- a/tests/ref/fate/mov-displaymatrix +++ b/tests/ref/fate/mov-displaymatrix @@ -1,7 +1,6 @@ [STREAM] [SIDE_DATA] side_data_type=Display Matrix -side_data_size=36 displaymatrix= 00000000: 0 131072 0 00000001: -65536 0 0 diff --git a/tests/ref/fate/mov-spherical-mono b/tests/ref/fate/mov-spherical-mono index a70d879f0e464..bd57d94514b4b 100644 --- a/tests/ref/fate/mov-spherical-mono +++ b/tests/ref/fate/mov-spherical-mono @@ -1,13 +1,11 @@ [STREAM] [SIDE_DATA] side_data_type=Stereo 3D -side_data_size=8 type=2D inverted=0 [/SIDE_DATA] [SIDE_DATA] side_data_type=Spherical Mapping -side_data_size=56 projection=tiled equirectangular bound_left=148 bound_top=73 diff --git a/tests/ref/fate/mov-zombie b/tests/ref/fate/mov-zombie index 42e3a6f29e230..522417dce7176 100644 --- a/tests/ref/fate/mov-zombie +++ b/tests/ref/fate/mov-zombie @@ -130,4 +130,4 @@ frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=188623|pkt_pts_time=2. packet|codec_type=video|stream_index=0|pts=197632|pts_time=2.195911|dts=191625|dts_time=2.129167|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=580|pos=101820|flags=__ frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=191626|pkt_pts_time=2.129178|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=191626|best_effort_timestamp_time=2.129178|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=99180|pkt_size=1666|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=63|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 stream|index=0|codec_name=h264|profile=77|codec_type=video|codec_time_base=212521/12744000|codec_tag_string=avc1|codec_tag=0x31637661|width=160|height=240|coded_width=160|coded_height=240|has_b_frames=0|sample_aspect_ratio=2:1|display_aspect_ratio=4:3|pix_fmt=yuv420p|level=12|color_range=tv|color_space=smpte170m|color_transfer=bt709|color_primaries=smpte170m|chroma_location=topleft|field_order=unknown|timecode=N/A|refs=2|is_avc=true|nal_length_size=4|id=N/A|r_frame_rate=30000/1001|avg_frame_rate=6372000/212521|time_base=1/90000|start_pts=0|start_time=0.000000|duration_ts=2125200|duration=23.613333|bit_rate=333874|max_bit_rate=N/A|bits_per_raw_sample=8|nb_frames=708|nb_read_frames=65|nb_read_packets=66|disposition:default=1|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|tag:rotate=0|tag:creation_time=2008-05-12T20:59:27.000000Z|tag:language=eng|tag:handler_name=Apple Alias Data Handler|tag:encoder=H.264 -side_data|side_data_type=Display Matrix|side_data_size=36|displaymatrix=\n00000000: 131072 0 0\n00000001: 0 65536 0\n00000002: 0 0 1073741824\n|rotation=0 +side_data|side_data_type=Display Matrix|displaymatrix=\n00000000: 131072 0 0\n00000001: 0 65536 0\n00000002: 0 0 1073741824\n|rotation=0 From f20bcec4c2b1c2a57ed89e5be1ac2e0db1bc62b4 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Thu, 16 Mar 2017 17:20:47 -0400 Subject: [PATCH 1183/3374] spherical: Change types of bounding and pad to uint32_t These values are defined to be 32bit in the specification, so it makes more sense to store them as fixed width. Based on a patch by Micahel Niedermayer . Signed-off-by: Vittorio Giovara --- libavformat/dump.c | 2 +- libavformat/matroskadec.c | 7 +++---- libavformat/mov.c | 8 +++----- libavutil/spherical.h | 10 +++++----- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/libavformat/dump.c b/libavformat/dump.c index 505d572301743..3e6218303d47e 100644 --- a/libavformat/dump.c +++ b/libavformat/dump.c @@ -375,7 +375,7 @@ static void dump_spherical(void *ctx, AVCodecParameters *par, AVPacketSideData * &l, &t, &r, &b); av_log(ctx, AV_LOG_INFO, "[%zu, %zu, %zu, %zu] ", l, t, r, b); } else if (spherical->projection == AV_SPHERICAL_CUBEMAP) { - av_log(ctx, AV_LOG_INFO, "[pad %zu] ", spherical->padding); + av_log(ctx, AV_LOG_INFO, "[pad %"PRIu32"] ", spherical->padding); } } diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index fdb23ab05e8b2..bad034b77050a 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -1913,8 +1913,8 @@ static int mkv_parse_video_projection(AVStream *st, const MatroskaTrack *track) AVSphericalMapping *spherical; enum AVSphericalProjection projection; size_t spherical_size; - size_t l = 0, t = 0, r = 0, b = 0; - size_t padding = 0; + uint32_t l = 0, t = 0, r = 0, b = 0; + uint32_t padding = 0; int ret; GetByteContext gb; @@ -1939,8 +1939,7 @@ static int mkv_parse_video_projection(AVStream *st, const MatroskaTrack *track) if (b >= UINT_MAX - t || r >= UINT_MAX - l) { av_log(NULL, AV_LOG_ERROR, "Invalid bounding rectangle coordinates " - "%"SIZE_SPECIFIER",%"SIZE_SPECIFIER"," - "%"SIZE_SPECIFIER",%"SIZE_SPECIFIER"\n", + "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b); return AVERROR_INVALIDDATA; } diff --git a/libavformat/mov.c b/libavformat/mov.c index d5c3949050223..5e7be495632bd 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -4637,9 +4637,8 @@ static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom) MOVStreamContext *sc; int size, layout; int32_t yaw, pitch, roll; - size_t l = 0, t = 0, r = 0, b = 0; - size_t padding = 0; - uint32_t tag; + uint32_t l = 0, t = 0, r = 0, b = 0; + uint32_t tag, padding = 0; enum AVSphericalProjection projection; if (c->fc->nb_streams < 1) @@ -4717,8 +4716,7 @@ static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (b >= UINT_MAX - t || r >= UINT_MAX - l) { av_log(c->fc, AV_LOG_ERROR, "Invalid bounding rectangle coordinates %"SIZE_SPECIFIER"," - "%"SIZE_SPECIFIER",%"SIZE_SPECIFIER",%"SIZE_SPECIFIER"\n", - l, t, r, b); + "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b); return AVERROR_INVALIDDATA; } diff --git a/libavutil/spherical.h b/libavutil/spherical.h index f4e0d60966b2b..a7952875af76e 100644 --- a/libavutil/spherical.h +++ b/libavutil/spherical.h @@ -164,10 +164,10 @@ typedef struct AVSphericalMapping { * projection type (@ref AV_SPHERICAL_EQUIRECTANGULAR_TILE), * and should be ignored in all other cases. */ - size_t bound_left; ///< Distance from the left edge - size_t bound_top; ///< Distance from the top edge - size_t bound_right; ///< Distance from the right edge - size_t bound_bottom; ///< Distance from the bottom edge + uint32_t bound_left; ///< Distance from the left edge + uint32_t bound_top; ///< Distance from the top edge + uint32_t bound_right; ///< Distance from the right edge + uint32_t bound_bottom; ///< Distance from the bottom edge /** * @} */ @@ -179,7 +179,7 @@ typedef struct AVSphericalMapping { * (@ref AV_SPHERICAL_CUBEMAP), and should be ignored in all other * cases. */ - size_t padding; + uint32_t padding; } AVSphericalMapping; /** From 95a72aed764aa8a08c56ba0e8cf5153f5b769222 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Fri, 17 Mar 2017 15:29:51 -0400 Subject: [PATCH 1184/3374] mov: Drop extra format specifier in error message --- libavformat/mov.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 5e7be495632bd..f7dd2502c5a68 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -4715,7 +4715,7 @@ static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (b >= UINT_MAX - t || r >= UINT_MAX - l) { av_log(c->fc, AV_LOG_ERROR, - "Invalid bounding rectangle coordinates %"SIZE_SPECIFIER"," + "Invalid bounding rectangle coordinates " "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b); return AVERROR_INVALIDDATA; } From 9e6b269fea260a4f4cd15d1c0f77b21addee342a Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Thu, 16 Mar 2017 22:31:44 +0100 Subject: [PATCH 1185/3374] lavc/avcodec: Constify AVBitStreamFilter* in AVBitStreamFilterContext struct. Fixes a gcc warning: libavcodec/bitstream_filter.c:71:20: warning: assignment discards 'const' qualifier from pointer target type --- libavcodec/avcodec.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 1923c9648df0a..8774718abbd89 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -5764,7 +5764,7 @@ int av_get_audio_frame_duration2(AVCodecParameters *par, int frame_bytes); #if FF_API_OLD_BSF typedef struct AVBitStreamFilterContext { void *priv_data; - struct AVBitStreamFilter *filter; + const struct AVBitStreamFilter *filter; AVCodecParserContext *parser; struct AVBitStreamFilterContext *next; /** From c52638cca255737eb060dcdedf5be4414e622e82 Mon Sep 17 00:00:00 2001 From: Muhammad Faiz Date: Thu, 16 Mar 2017 12:35:11 +0700 Subject: [PATCH 1186/3374] swresample/swresample: do not use s32p internally by default when resampling use fltp when doing s32 -> s32 resampling because s32p has no simd optimization benchmark: old 17.913s new 7.584s (use fma3) Reviewed-by: wm4 Signed-off-by: Muhammad Faiz --- libswresample/swresample.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libswresample/swresample.c b/libswresample/swresample.c index f2e66005eb076..74c96dce605e4 100644 --- a/libswresample/swresample.c +++ b/libswresample/swresample.c @@ -223,6 +223,8 @@ av_cold int swr_init(struct SwrContext *s){ }else if( av_get_planar_sample_fmt(s-> in_sample_fmt) == AV_SAMPLE_FMT_S32P && av_get_planar_sample_fmt(s->out_sample_fmt) == AV_SAMPLE_FMT_S32P && !s->rematrix + && s->out_sample_rate == s->in_sample_rate + && !(s->flags & SWR_FLAG_RESAMPLE) && s->engine != SWR_ENGINE_SOXR){ s->int_sample_fmt= AV_SAMPLE_FMT_S32P; }else if(av_get_bytes_per_sample(s->in_sample_fmt) <= 4){ From 3796fb2692f87d0000fc0aa4572ac025a6469c2b Mon Sep 17 00:00:00 2001 From: Rostislav Pehlivanov Date: Mon, 6 Mar 2017 02:46:50 +0000 Subject: [PATCH 1187/3374] lavfi: deprecate AVFilterGraph->resample_lavr_opts Not used by anything at all since we don't auto insert lavr filters. Reviewed-by: wm4 Signed-off-by: Rostislav Pehlivanov --- doc/APIchanges | 4 ++++ libavfilter/avfilter.h | 4 +++- libavfilter/avfiltergraph.c | 2 ++ libavfilter/version.h | 5 ++++- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index dc36a6bea7c82..d5cee9b703d92 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,10 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-03-18 - xxxxxxx - lavfi 6.77.100 - avfilter.h + Deprecate AVFilterGraph.resample_lavr_opts + It's never been used by avfilter nor passed to anything. + 2017-02-10 - xxxxxxx - lavu 55.48.100 / 55.33.0 - spherical.h Add AV_SPHERICAL_EQUIRECTANGULAR_TILE, av_spherical_tile_bounds(), and projection-specific properties (bound_left, bound_top, bound_right, diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index b56615c98edf2..ac6dca4fc087e 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -841,7 +841,9 @@ typedef struct AVFilterGraph { unsigned nb_filters; char *scale_sws_opts; ///< sws options to use for the auto-inserted scale filters - char *resample_lavr_opts; ///< libavresample options to use for the auto-inserted resample filters +#if FF_API_LAVR_OPTS + attribute_deprecated char *resample_lavr_opts; ///< libavresample options to use for the auto-inserted resample filters +#endif /** * Type of multithreading allowed for filters in this graph. A combination diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 534c6701a843b..75bd516896842 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -128,7 +128,9 @@ void avfilter_graph_free(AVFilterGraph **graph) av_freep(&(*graph)->scale_sws_opts); av_freep(&(*graph)->aresample_swr_opts); +#if FF_API_LAVR_OPTS av_freep(&(*graph)->resample_lavr_opts); +#endif av_freep(&(*graph)->filters); av_freep(&(*graph)->internal); av_freep(graph); diff --git a/libavfilter/version.h b/libavfilter/version.h index e67f34b611a04..c2684bfe94367 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 6 -#define LIBAVFILTER_VERSION_MINOR 76 +#define LIBAVFILTER_VERSION_MINOR 77 #define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ @@ -67,5 +67,8 @@ #ifndef FF_API_NOCONST_GET_NAME #define FF_API_NOCONST_GET_NAME (LIBAVFILTER_VERSION_MAJOR < 7) #endif +#ifndef FF_API_LAVR_OPTS +#define FF_API_LAVR_OPTS (LIBAVFILTER_VERSION_MAJOR < 7) +#endif #endif /* AVFILTER_VERSION_H */ From 824d4062a172bd435fea7cbf8d6b55583c73e70e Mon Sep 17 00:00:00 2001 From: James Almer Date: Tue, 7 Mar 2017 00:04:46 -0300 Subject: [PATCH 1188/3374] compat/atomics/gcc: use __typeof__ instead of typeof The typeof keyword is apparently not available when using the -std=c99 option. Fixes the use of C11 atomic functions with old GCC. Reviewed-by: Muhammad Faiz Signed-off-by: James Almer --- compat/atomics/gcc/stdatomic.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compat/atomics/gcc/stdatomic.h b/compat/atomics/gcc/stdatomic.h index 41caddec5c56c..2b64687437b93 100644 --- a/compat/atomics/gcc/stdatomic.h +++ b/compat/atomics/gcc/stdatomic.h @@ -100,8 +100,8 @@ do { \ #define atomic_exchange(object, desired) \ ({ \ - typeof(object) _obj = (object); \ - typeof(*object) _old; \ + __typeof__(object) _obj = (object); \ + __typeof__(*object) _old; \ do \ _old = atomic_load(_obj); \ while (!__sync_bool_compare_and_swap(_obj, _old, (desired))); \ @@ -113,8 +113,8 @@ do { \ #define atomic_compare_exchange_strong(object, expected, desired) \ ({ \ - typeof(object) _exp = (expected); \ - typeof(*object) _old = *_exp; \ + __typeof__(object) _exp = (expected); \ + __typeof__(*object) _old = *_exp; \ *_exp = __sync_val_compare_and_swap((object), _old, (desired)); \ *_exp == _old; \ }) From 1e1513d01aa8296d55efab95143e65ccbb152c5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sat, 18 Mar 2017 23:48:22 +0100 Subject: [PATCH 1189/3374] lavu/mathematics: document so-called "cruft" --- libavutil/mathematics.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavutil/mathematics.c b/libavutil/mathematics.c index 20ff37f5e9d76..f378bc73b3833 100644 --- a/libavutil/mathematics.c +++ b/libavutil/mathematics.c @@ -117,6 +117,7 @@ int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd) return t1; } #else + /* reference code doing (a*b + r) / c, requires libavutil/integer.h */ AVInteger ai; ai = av_mul_i(av_int2i(a), av_int2i(b)); ai = av_add_i(ai, av_int2i(r)); From ea8efc959449573dd7fd29940240bdc1d671817d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sat, 18 Mar 2017 23:49:20 +0100 Subject: [PATCH 1190/3374] lavu/mathematics: split closing bracket out of ifdefery --- libavutil/mathematics.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libavutil/mathematics.c b/libavutil/mathematics.c index f378bc73b3833..1bf044cdf114f 100644 --- a/libavutil/mathematics.c +++ b/libavutil/mathematics.c @@ -115,7 +115,6 @@ int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd) if (t1 > INT64_MAX) return INT64_MIN; return t1; - } #else /* reference code doing (a*b + r) / c, requires libavutil/integer.h */ AVInteger ai; @@ -123,8 +122,8 @@ int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd) ai = av_add_i(ai, av_int2i(r)); return av_i2int(av_div_i(ai, av_int2i(c))); - } #endif + } } int64_t av_rescale(int64_t a, int64_t b, int64_t c) From de1308429ae649c899b74365f0dc72847676ba75 Mon Sep 17 00:00:00 2001 From: Muhammad Faiz Date: Thu, 16 Mar 2017 11:33:16 +0700 Subject: [PATCH 1191/3374] swresample/x86/resample: extend resample_double to support avx and fma3 benchmark: sse2 10.670s avx 8.763s fma3 8.380s Signed-off-by: Muhammad Faiz --- libswresample/x86/resample.asm | 15 ++++++++++++--- libswresample/x86/resample_init.c | 10 ++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/libswresample/x86/resample.asm b/libswresample/x86/resample.asm index 4163df1aa1a07..7107cf9d42a12 100644 --- a/libswresample/x86/resample.asm +++ b/libswresample/x86/resample.asm @@ -203,7 +203,7 @@ cglobal resample_common_%1, 1, 7, 2, ctx, phase_count, dst, frac, \ ; horizontal sum & store %if mmsize == 32 vextractf128 xm1, m0, 0x1 - addps xm0, xm1 + addp%4 xm0, xm1 %endif movhlps xm1, xm0 %ifidn %1, float @@ -489,8 +489,8 @@ cglobal resample_linear_%1, 1, 7, 5, ctx, min_filter_length_x4, filter2, \ %if mmsize == 32 vextractf128 xm1, m0, 0x1 vextractf128 xm3, m2, 0x1 - addps xm0, xm1 - addps xm2, xm3 + addp%4 xm0, xm1 + addp%4 xm2, xm3 %endif cvtsi2s%4 xm1, fracd subp%4 xm2, xm0 @@ -608,3 +608,12 @@ RESAMPLE_FNS int16, 2, 1 INIT_XMM sse2 RESAMPLE_FNS double, 8, 3, d, pdbl_1 + +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +RESAMPLE_FNS double, 8, 3, d, pdbl_1 +%endif +%if HAVE_FMA3_EXTERNAL +INIT_YMM fma3 +RESAMPLE_FNS double, 8, 3, d, pdbl_1 +%endif diff --git a/libswresample/x86/resample_init.c b/libswresample/x86/resample_init.c index e515762b98978..c6b2a36060dc3 100644 --- a/libswresample/x86/resample_init.c +++ b/libswresample/x86/resample_init.c @@ -42,6 +42,8 @@ RESAMPLE_FUNCS(float, avx); RESAMPLE_FUNCS(float, fma3); RESAMPLE_FUNCS(float, fma4); RESAMPLE_FUNCS(double, sse2); +RESAMPLE_FUNCS(double, avx); +RESAMPLE_FUNCS(double, fma3); av_cold void swri_resample_dsp_x86_init(ResampleContext *c) { @@ -85,6 +87,14 @@ av_cold void swri_resample_dsp_x86_init(ResampleContext *c) c->dsp.resample_linear = ff_resample_linear_double_sse2; c->dsp.resample_common = ff_resample_common_double_sse2; } + if (EXTERNAL_AVX_FAST(mm_flags)) { + c->dsp.resample_linear = ff_resample_linear_double_avx; + c->dsp.resample_common = ff_resample_common_double_avx; + } + if (EXTERNAL_FMA3_FAST(mm_flags)) { + c->dsp.resample_linear = ff_resample_linear_double_fma3; + c->dsp.resample_common = ff_resample_common_double_fma3; + } break; } } From b7a565fe71d16747209bd66955a54c9b54abc5dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 26 Feb 2017 14:02:35 +0200 Subject: [PATCH 1192/3374] arm: vp9itxfm: Template the quarter/half idct32 function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reduces the number of lines and reduces the duplication. Also simplify the eob check for the half case. If we are in the half case, we know we at least will need to do the first three slices, we only need to check eob for the fourth one, so we can hardcode the value to check against instead of loading from the min_eob array. Since at most one slice can be skipped in the first pass, we can unroll the loop for filling zeros completely, as it was done for the quarter case before. This allows skipping loading the min_eob pointer when using the quarter/half cases. This is cherrypicked from libav commit 98ee855ae0cc118bd1d20921d6bdb14731832462. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_neon.S | 57 ++++++++++++---------------------- 1 file changed, 20 insertions(+), 37 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index ebbbda9248674..adc9896db4c94 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -1575,7 +1575,6 @@ function ff_vp9_idct_idct_32x32_add_neon, export=1 beq idct32x32_dc_add_neon push {r4-r8,lr} vpush {q4-q6} - movrel r8, min_eob_idct_idct_32 + 2 @ Align the stack, allocate a temp buffer T mov r7, sp @@ -1597,6 +1596,8 @@ A and r7, sp, #15 cmp r3, #135 ble idct32x32_half_add_neon + movrel r8, min_eob_idct_idct_32 + 2 + .irp i, 0, 4, 8, 12, 16, 20, 24, 28 add r0, sp, #(\i*64) .if \i > 0 @@ -1634,72 +1635,54 @@ A and r7, sp, #15 pop {r4-r8,pc} endfunc -function idct32x32_quarter_add_neon +.macro idct32_partial size +function idct32x32_\size\()_add_neon .irp i, 0, 4 add r0, sp, #(\i*64) +.ifc \size,quarter .if \i == 4 cmp r3, #9 ble 1f +.endif .endif add r2, r6, #(\i*2) - bl idct32_1d_4x32_pass1_quarter_neon -.endr - b 3f - -1: - @ Write zeros to the temp buffer for pass 2 - vmov.i16 q14, #0 - vmov.i16 q15, #0 -.rept 8 - vst1.16 {q14-q15}, [r0,:128]! -.endr -3: -.irp i, 0, 4, 8, 12, 16, 20, 24, 28 - add r0, r4, #(\i) - mov r1, r5 - add r2, sp, #(\i*2) - bl idct32_1d_4x32_pass2_quarter_neon + bl idct32_1d_4x32_pass1_\size\()_neon .endr - add sp, sp, r7 - vpop {q4-q6} - pop {r4-r8,pc} -endfunc - -function idct32x32_half_add_neon -.irp i, 0, 4, 8, 12 +.ifc \size,half +.irp i, 8, 12 add r0, sp, #(\i*64) -.if \i > 0 - ldrh_post r1, r8, #2 - cmp r3, r1 - it le - movle r1, #(16 - \i)/2 +.if \i == 12 + cmp r3, #70 ble 1f .endif add r2, r6, #(\i*2) - bl idct32_1d_4x32_pass1_half_neon + bl idct32_1d_4x32_pass1_\size\()_neon .endr +.endif b 3f 1: @ Write zeros to the temp buffer for pass 2 vmov.i16 q14, #0 vmov.i16 q15, #0 -2: - subs r1, r1, #1 -.rept 4 +.rept 8 vst1.16 {q14-q15}, [r0,:128]! .endr - bne 2b + 3: .irp i, 0, 4, 8, 12, 16, 20, 24, 28 add r0, r4, #(\i) mov r1, r5 add r2, sp, #(\i*2) - bl idct32_1d_4x32_pass2_half_neon + bl idct32_1d_4x32_pass2_\size\()_neon .endr add sp, sp, r7 vpop {q4-q6} pop {r4-r8,pc} endfunc +.endm + +idct32_partial quarter +idct32_partial half From 70317b25aa35c0907720e4d2b7686408588c07aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 26 Feb 2017 22:13:10 +0200 Subject: [PATCH 1193/3374] arm/aarch64: vp9itxfm: Skip loading the min_eob pointer when it won't be used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the half/quarter cases where we don't use the min_eob array, defer loading the pointer until we know it will be needed. This is cherrypicked from libav commit 3a0d5e206d24d41d87a25ba16a79b2ea04c39d4c. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 3 ++- libavcodec/arm/vp9itxfm_neon.S | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index 2c3c002d54c9c..3e5da0880c7f2 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -1483,7 +1483,6 @@ function ff_vp9_idct_idct_32x32_add_neon, export=1 b.eq idct32x32_dc_add_neon movrel x10, idct_coeffs - movrel x12, min_eob_idct_idct_32, 2 mov x15, x30 @@ -1508,6 +1507,8 @@ function ff_vp9_idct_idct_32x32_add_neon, export=1 cmp w3, #135 b.le idct32x32_half_add_neon + movrel x12, min_eob_idct_idct_32, 2 + .irp i, 0, 8, 16, 24 add x0, sp, #(\i*64) .if \i > 0 diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index adc9896db4c94..6d4d765c28571 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -889,8 +889,6 @@ function ff_vp9_\txfm1\()_\txfm2\()_16x16_add_neon, export=1 push {r4-r8,lr} .ifnc \txfm1\()_\txfm2,idct_idct vpush {q4-q7} -.else - movrel r8, min_eob_idct_idct_16 + 2 .endif @ Align the stack, allocate a temp buffer @@ -914,6 +912,8 @@ A and r7, sp, #15 ble idct16x16_quarter_add_neon cmp r3, #38 ble idct16x16_half_add_neon + + movrel r8, min_eob_idct_idct_16 + 2 .endif .irp i, 0, 4, 8, 12 From 21c89f3a26bb1331381b90e653277585447cfbb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 9 Jan 2017 00:04:19 +0200 Subject: [PATCH 1194/3374] arm/aarch64: vp9: Fix vertical alignment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Align the second/third operands as they usually are. Due to the wildly varying sizes of the written out operands in aarch64 assembly, the column alignment is usually not as clear as in arm assembly. This is cherrypicked from libav commit 7995ebfad12002033c73feed422a1cfc62081e8f. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_neon.S | 36 +++++++++++++++--------------- libavcodec/arm/vp9itxfm_neon.S | 14 ++++++------ libavcodec/arm/vp9lpf_neon.S | 2 +- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S index 3e5da0880c7f2..b12890f0db366 100644 --- a/libavcodec/aarch64/vp9itxfm_neon.S +++ b/libavcodec/aarch64/vp9itxfm_neon.S @@ -380,7 +380,7 @@ function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_neon, export=1 .ifc \txfm1\()_\txfm2,idct_idct movrel x4, idct_coeffs .else - movrel x4, iadst8_coeffs + movrel x4, iadst8_coeffs ld1 {v1.8h}, [x4], #16 .endif ld1 {v0.8h}, [x4] @@ -480,23 +480,23 @@ itxfm_func8x8 iadst, iadst function idct16x16_dc_add_neon - movrel x4, idct_coeffs + movrel x4, idct_coeffs ld1 {v0.4h}, [x4] - movi v1.4h, #0 + movi v1.4h, #0 ld1 {v2.h}[0], [x2] - smull v2.4s, v2.4h, v0.h[0] - rshrn v2.4h, v2.4s, #14 - smull v2.4s, v2.4h, v0.h[0] - rshrn v2.4h, v2.4s, #14 + smull v2.4s, v2.4h, v0.h[0] + rshrn v2.4h, v2.4s, #14 + smull v2.4s, v2.4h, v0.h[0] + rshrn v2.4h, v2.4s, #14 dup v2.8h, v2.h[0] st1 {v1.h}[0], [x2] - srshr v2.8h, v2.8h, #6 + srshr v2.8h, v2.8h, #6 - mov x3, x0 - mov x4, #16 + mov x3, x0 + mov x4, #16 1: // Loop to add the constant from v2 into all 16x16 outputs subs x4, x4, #2 @@ -869,7 +869,7 @@ function ff_vp9_\txfm1\()_\txfm2\()_16x16_add_neon, export=1 .ifc \txfm1,idct ld1 {v0.8h,v1.8h}, [x10] .endif - mov x9, #32 + mov x9, #32 .ifc \txfm1\()_\txfm2,idct_idct cmp w3, #10 @@ -1046,10 +1046,10 @@ idct16_partial quarter idct16_partial half function idct32x32_dc_add_neon - movrel x4, idct_coeffs + movrel x4, idct_coeffs ld1 {v0.4h}, [x4] - movi v1.4h, #0 + movi v1.4h, #0 ld1 {v2.h}[0], [x2] smull v2.4s, v2.4h, v0.h[0] @@ -1059,10 +1059,10 @@ function idct32x32_dc_add_neon dup v2.8h, v2.h[0] st1 {v1.h}[0], [x2] - srshr v0.8h, v2.8h, #6 + srshr v0.8h, v2.8h, #6 - mov x3, x0 - mov x4, #32 + mov x3, x0 + mov x4, #32 1: // Loop to add the constant v0 into all 32x32 outputs subs x4, x4, #2 @@ -1230,7 +1230,7 @@ endfunc // x9 = double input stride function idct32_1d_8x32_pass1\suffix\()_neon mov x14, x30 - movi v2.8h, #0 + movi v2.8h, #0 // v16 = IN(0), v17 = IN(2) ... v31 = IN(30) .ifb \suffix @@ -1295,7 +1295,7 @@ function idct32_1d_8x32_pass1\suffix\()_neon .endif add x2, x2, #64 - movi v2.8h, #0 + movi v2.8h, #0 // v16 = IN(1), v17 = IN(3) ... v31 = IN(31) .ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 diff --git a/libavcodec/arm/vp9itxfm_neon.S b/libavcodec/arm/vp9itxfm_neon.S index 6d4d765c28571..6c09922caee88 100644 --- a/libavcodec/arm/vp9itxfm_neon.S +++ b/libavcodec/arm/vp9itxfm_neon.S @@ -530,7 +530,7 @@ function idct16x16_dc_add_neon movrel r12, idct_coeffs vld1.16 {d0}, [r12,:64] - vmov.i16 q2, #0 + vmov.i16 q2, #0 vld1.16 {d16[]}, [r2,:16] vmull.s16 q8, d16, d0[0] @@ -793,7 +793,7 @@ function \txfm\()16_1d_4x16_pass1_neon push {lr} mov r12, #32 - vmov.s16 q2, #0 + vmov.s16 q2, #0 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vld1.16 {d\i}, [r2,:64] vst1.16 {d4}, [r2,:64], r12 @@ -1142,7 +1142,7 @@ function idct32x32_dc_add_neon movrel r12, idct_coeffs vld1.16 {d0}, [r12,:64] - vmov.i16 q2, #0 + vmov.i16 q2, #0 vld1.16 {d16[]}, [r2,:16] vmull.s16 q8, d16, d0[0] @@ -1330,7 +1330,7 @@ function idct32_1d_4x32_pass1\suffix\()_neon @ Double stride of the input, since we only read every other line mov r12, #128 - vmov.s16 d4, #0 + vmov.s16 d4, #0 @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30) .ifb \suffix @@ -1394,7 +1394,7 @@ function idct32_1d_4x32_pass1\suffix\()_neon .endif add r2, r2, #64 - vmov.s16 d8, #0 + vmov.s16 d8, #0 @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31) .ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 @@ -1533,9 +1533,9 @@ function idct32_1d_4x32_pass2\suffix\()_neon .endif vld1.32 {d12[]}, [r0,:32], r1 vld1.32 {d12[1]}, [r0,:32], r1 - vrshr.s16 q4, q4, #6 + vrshr.s16 q4, q4, #6 vld1.32 {d13[]}, [r0,:32], r1 - vrshr.s16 q5, q5, #6 + vrshr.s16 q5, q5, #6 vld1.32 {d13[1]}, [r0,:32], r1 sub r0, r0, r1, lsl #2 vaddw.u8 q4, q4, d12 diff --git a/libavcodec/arm/vp9lpf_neon.S b/libavcodec/arm/vp9lpf_neon.S index 8d44d58f32e8b..4b3608064a5d8 100644 --- a/libavcodec/arm/vp9lpf_neon.S +++ b/libavcodec/arm/vp9lpf_neon.S @@ -828,7 +828,7 @@ function ff_vp9_loop_filter_v_16_16_neon, export=1 endfunc function vp9_loop_filter_h_16_neon - sub r12, r0, #8 + sub r12, r0, #8 vld1.8 {d16}, [r12,:64], r1 vld1.8 {d24}, [r0, :64], r1 vld1.8 {d17}, [r12,:64], r1 From b46d37e93ab1d38281ce2cc54b70de2c422d06e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 24 Feb 2017 17:36:05 +0200 Subject: [PATCH 1195/3374] arm: vp9itxfm16: Use the right lane size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes the code slightly clearer, but doesn't make any functional difference. Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_16bpp_neon.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_16bpp_neon.S b/libavcodec/arm/vp9itxfm_16bpp_neon.S index e6e94407e2215..a92f3234dda00 100644 --- a/libavcodec/arm/vp9itxfm_16bpp_neon.S +++ b/libavcodec/arm/vp9itxfm_16bpp_neon.S @@ -1082,8 +1082,8 @@ A and r7, sp, #15 .ifc \txfm1\()_\txfm2,idct_idct b 3f 1: - vmov.i16 q14, #0 - vmov.i16 q15, #0 + vmov.i32 q14, #0 + vmov.i32 q15, #0 2: subs r1, r1, #1 @ Unroll for 2 lines From c1619318e540a214c730c6a300ebee0a4f450ba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 25 Feb 2017 00:07:22 +0200 Subject: [PATCH 1196/3374] arm: vp9itxfm16: Fix vertical alignment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_16bpp_neon.S | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_16bpp_neon.S b/libavcodec/arm/vp9itxfm_16bpp_neon.S index a92f3234dda00..9c02ed99dcfdb 100644 --- a/libavcodec/arm/vp9itxfm_16bpp_neon.S +++ b/libavcodec/arm/vp9itxfm_16bpp_neon.S @@ -1395,25 +1395,25 @@ function idct32_1d_2x32_pass2_neon vld1.32 {d4}, [r2,:64], r12 vld1.32 {d5}, [r2,:64], r12 .if \neg == 0 - vadd.s32 d4, d4, d\a + vadd.s32 d4, d4, d\a vld1.32 {d6}, [r2,:64], r12 - vadd.s32 d5, d5, d\b + vadd.s32 d5, d5, d\b vld1.32 {d7}, [r2,:64], r12 - vadd.s32 d6, d6, d\c - vadd.s32 d7, d7, d\d + vadd.s32 d6, d6, d\c + vadd.s32 d7, d7, d\d .else - vsub.s32 d4, d4, d\a + vsub.s32 d4, d4, d\a vld1.32 {d6}, [r2,:64], r12 - vsub.s32 d5, d5, d\b + vsub.s32 d5, d5, d\b vld1.32 {d7}, [r2,:64], r12 - vsub.s32 d6, d6, d\c - vsub.s32 d7, d7, d\d + vsub.s32 d6, d6, d\c + vsub.s32 d7, d7, d\d .endif vld1.32 {d2[]}, [r0,:32], r1 vld1.32 {d2[1]}, [r0,:32], r1 - vrshr.s32 q2, q2, #6 + vrshr.s32 q2, q2, #6 vld1.32 {d3[]}, [r0,:32], r1 - vrshr.s32 q3, q3, #6 + vrshr.s32 q3, q3, #6 vld1.32 {d3[1]}, [r0,:32], r1 sub r0, r0, r1, lsl #2 vaddw.u16 q2, q2, d2 From 32e273c111d8700dde895b80741622afc285ad3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 25 Feb 2017 00:20:25 +0200 Subject: [PATCH 1197/3374] arm: vp9itxfm16: Avoid reloading the idct32 coefficients MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keep the idct32 coefficients in narrow form in q6-q7, and idct16 coefficients in lengthened 32 bit form in q0-q3. Avoid clobbering q0-q3 in the pass1 function, and squeeze the idct16 coefficients into q0-q1 in the pass2 function to avoid reloading them. The idct16 coefficients are clobbered and reloaded within idct32_odd though, since that turns out to be faster than narrowing them and swapping them into q6-q7. Before: Cortex A7 A8 A9 A53 vp9_inv_dct_dct_32x32_sub4_add_10_neon: 22653.8 18268.4 19598.0 14079.0 vp9_inv_dct_dct_32x32_sub32_add_10_neon: 37699.0 38665.2 32542.3 24472.2 After: vp9_inv_dct_dct_32x32_sub4_add_10_neon: 22270.8 18159.3 19531.0 13865.0 vp9_inv_dct_dct_32x32_sub32_add_10_neon: 37523.3 37731.6 32181.7 24071.2 Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_16bpp_neon.S | 128 +++++++++++++++------------ 1 file changed, 69 insertions(+), 59 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_16bpp_neon.S b/libavcodec/arm/vp9itxfm_16bpp_neon.S index 9c02ed99dcfdb..29d95ca22843c 100644 --- a/libavcodec/arm/vp9itxfm_16bpp_neon.S +++ b/libavcodec/arm/vp9itxfm_16bpp_neon.S @@ -1195,12 +1195,12 @@ endfunc .macro idct32_odd movrel r12, idct_coeffs - add r12, r12, #32 - vld1.16 {q0-q1}, [r12,:128] - vmovl.s16 q2, d2 - vmovl.s16 q3, d3 - vmovl.s16 q1, d1 - vmovl.s16 q0, d0 + + @ Overwrite the idct16 coeffs with the stored ones for idct32 + vmovl.s16 q0, d12 + vmovl.s16 q1, d13 + vmovl.s16 q2, d14 + vmovl.s16 q3, d15 mbutterfly d16, d31, d0[0], d0[1], q4, q5 @ d16 = t16a, d31 = t31a mbutterfly d24, d23, d1[0], d1[1], q4, q5 @ d24 = t17a, d23 = t30a @@ -1211,15 +1211,19 @@ endfunc mbutterfly d22, d25, d6[0], d6[1], q4, q5 @ d22 = t22a, d25 = t25a mbutterfly d30, d17, d7[0], d7[1], q4, q5 @ d30 = t23a, d17 = t24a - sub r12, r12, #32 - vld1.16 {q0}, [r12,:128] + @ Reload the idct16 coefficients. We could swap the coefficients between + @ q0-q3 and q6-q7 by narrowing/lengthening, but that's slower than just + @ loading and lengthening. + vld1.16 {q0-q1}, [r12,:128] + + butterfly d8, d24, d16, d24 @ d8 = t16, d24 = t17 + butterfly d9, d20, d28, d20 @ d9 = t19, d20 = t18 + butterfly d10, d26, d18, d26 @ d10 = t20, d26 = t21 + butterfly d11, d22, d30, d22 @ d11 = t23, d22 = t22 + vmovl.s16 q2, d2 + vmovl.s16 q3, d3 vmovl.s16 q1, d1 vmovl.s16 q0, d0 - - butterfly d4, d24, d16, d24 @ d4 = t16, d24 = t17 - butterfly d5, d20, d28, d20 @ d5 = t19, d20 = t18 - butterfly d6, d26, d18, d26 @ d6 = t20, d26 = t21 - butterfly d7, d22, d30, d22 @ d7 = t23, d22 = t22 butterfly d28, d25, d17, d25 @ d28 = t24, d25 = t25 butterfly d30, d21, d29, d21 @ d30 = t27, d21 = t26 butterfly d29, d23, d31, d23 @ d29 = t31, d23 = t30 @@ -1230,34 +1234,34 @@ endfunc mbutterfly d21, d26, d3[0], d3[1], q8, q9 @ d21 = t21a, d26 = t26a mbutterfly d25, d22, d3[0], d3[1], q8, q9, neg=1 @ d25 = t25a, d22 = t22a - butterfly d16, d5, d4, d5 @ d16 = t16a, d5 = t19a + butterfly d16, d9, d8, d9 @ d16 = t16a, d9 = t19a butterfly d17, d20, d23, d20 @ d17 = t17, d20 = t18 - butterfly d18, d6, d7, d6 @ d18 = t23a, d6 = t20a + butterfly d18, d10, d11, d10 @ d18 = t23a, d10 = t20a butterfly d19, d21, d22, d21 @ d19 = t22, d21 = t21 - butterfly d4, d28, d28, d30 @ d4 = t24a, d28 = t27a + butterfly d8, d28, d28, d30 @ d8 = t24a, d28 = t27a butterfly d23, d26, d25, d26 @ d23 = t25, d26 = t26 - butterfly d7, d29, d29, d31 @ d7 = t31a, d29 = t28a + butterfly d11, d29, d29, d31 @ d11 = t31a, d29 = t28a butterfly d22, d27, d24, d27 @ d22 = t30, d27 = t29 mbutterfly d27, d20, d1[0], d1[1], q12, q15 @ d27 = t18a, d20 = t29a - mbutterfly d29, d5, d1[0], d1[1], q12, q15 @ d29 = t19, d5 = t28 - mbutterfly d28, d6, d1[0], d1[1], q12, q15, neg=1 @ d28 = t27, d6 = t20 + mbutterfly d29, d9, d1[0], d1[1], q12, q15 @ d29 = t19, d9 = t28 + mbutterfly d28, d10, d1[0], d1[1], q12, q15, neg=1 @ d28 = t27, d10 = t20 mbutterfly d26, d21, d1[0], d1[1], q12, q15, neg=1 @ d26 = t26a, d21 = t21a - butterfly d31, d24, d7, d4 @ d31 = t31, d24 = t24 + butterfly d31, d24, d11, d8 @ d31 = t31, d24 = t24 butterfly d30, d25, d22, d23 @ d30 = t30a, d25 = t25a butterfly_r d23, d16, d16, d18 @ d23 = t23, d16 = t16 butterfly_r d22, d17, d17, d19 @ d22 = t22a, d17 = t17a butterfly d18, d21, d27, d21 @ d18 = t18, d21 = t21 - butterfly_r d27, d28, d5, d28 @ d27 = t27a, d28 = t28a - butterfly d4, d26, d20, d26 @ d4 = t29, d26 = t26 - butterfly d19, d20, d29, d6 @ d19 = t19a, d20 = t20 - vmov d29, d4 @ d29 = t29 - - mbutterfly0 d27, d20, d27, d20, d4, d6, q2, q3 @ d27 = t27, d20 = t20 - mbutterfly0 d26, d21, d26, d21, d4, d6, q2, q3 @ d26 = t26a, d21 = t21a - mbutterfly0 d25, d22, d25, d22, d4, d6, q2, q3 @ d25 = t25, d22 = t22 - mbutterfly0 d24, d23, d24, d23, d4, d6, q2, q3 @ d24 = t24a, d23 = t23a + butterfly_r d27, d28, d9, d28 @ d27 = t27a, d28 = t28a + butterfly d8, d26, d20, d26 @ d8 = t29, d26 = t26 + butterfly d19, d20, d29, d10 @ d19 = t19a, d20 = t20 + vmov d29, d8 @ d29 = t29 + + mbutterfly0 d27, d20, d27, d20, d8, d10, q4, q5 @ d27 = t27, d20 = t20 + mbutterfly0 d26, d21, d26, d21, d8, d10, q4, q5 @ d26 = t26a, d21 = t21a + mbutterfly0 d25, d22, d25, d22, d8, d10, q4, q5 @ d25 = t25, d22 = t22 + mbutterfly0 d24, d23, d24, d23, d8, d10, q4, q5 @ d24 = t24a, d23 = t23a .endm @ Do an 32-point IDCT of a 2x32 slice out of a 32x32 matrix. @@ -1270,13 +1274,6 @@ endfunc @ r1 = unused @ r2 = src function idct32_1d_2x32_pass1_neon - movrel r12, idct_coeffs - vld1.16 {q0-q1}, [r12,:128] - vmovl.s16 q2, d2 - vmovl.s16 q3, d3 - vmovl.s16 q1, d1 - vmovl.s16 q0, d0 - @ Double stride of the input, since we only read every other line mov r12, #256 vmov.s32 d8, #0 @@ -1315,11 +1312,11 @@ function idct32_1d_2x32_pass1_neon sub r2, r2, r12, lsl #4 add r2, r2, #128 - vmov.s32 d4, #0 + vmov.s32 d8, #0 @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31) .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vld1.16 {d\i}, [r2,:64] - vst1.16 {d4}, [r2,:64], r12 + vst1.16 {d8}, [r2,:64], r12 .endr idct32_odd @@ -1331,15 +1328,15 @@ function idct32_1d_2x32_pass1_neon @ from the output. .macro store_rev a, b, c, d, e, f, g, h .irp i, \a, \b, \c, \d, \e, \f, \g, \h - vld1.32 {d4}, [r0,:64] - vadd.s32 d4, d4, d\i - vst1.32 {d4}, [r0,:64]! + vld1.32 {d8}, [r0,:64] + vadd.s32 d8, d8, d\i + vst1.32 {d8}, [r0,:64]! vrev64.32 d\i, d\i .endr .irp i, \h, \g, \f, \e, \d, \c, \b, \a - vld1.32 {d4}, [r0,:64] - vsub.s32 d4, d4, d\i - vst1.32 {d4}, [r0,:64]! + vld1.32 {d8}, [r0,:64] + vsub.s32 d8, d8, d\i + vst1.32 {d8}, [r0,:64]! .endr .endm @@ -1357,13 +1354,6 @@ endfunc @ r1 = dst stride @ r2 = src (temp buffer) function idct32_1d_2x32_pass2_neon - movrel r12, idct_coeffs - vld1.16 {q0-q1}, [r12,:128] - vmovl.s16 q2, d2 - vmovl.s16 q3, d3 - vmovl.s16 q1, d1 - vmovl.s16 q0, d0 - mov r12, #256 @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30) .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 @@ -1389,6 +1379,13 @@ function idct32_1d_2x32_pass2_neon idct32_odd + @ Narrow the ict16 coefficients in q0-q3 into q0-q1, to + @ allow clobbering q2-q3 below. + vmovn.s32 d0, q0 + vmovn.s32 d1, q1 + vmovn.s32 d2, q2 + vmovn.s32 d3, q3 + mov r12, #256 vdup.s16 q4, r9 .macro load_acc_store a, b, c, d, neg=0 @@ -1409,15 +1406,15 @@ function idct32_1d_2x32_pass2_neon vsub.s32 d6, d6, d\c vsub.s32 d7, d7, d\d .endif - vld1.32 {d2[]}, [r0,:32], r1 - vld1.32 {d2[1]}, [r0,:32], r1 + vld1.32 {d10[]}, [r0,:32], r1 + vld1.32 {d10[1]}, [r0,:32], r1 vrshr.s32 q2, q2, #6 - vld1.32 {d3[]}, [r0,:32], r1 + vld1.32 {d11[]}, [r0,:32], r1 vrshr.s32 q3, q3, #6 - vld1.32 {d3[1]}, [r0,:32], r1 + vld1.32 {d11[1]}, [r0,:32], r1 sub r0, r0, r1, lsl #2 - vaddw.u16 q2, q2, d2 - vaddw.u16 q3, q3, d3 + vaddw.u16 q2, q2, d10 + vaddw.u16 q3, q3, d11 vqmovun.s32 d4, q2 vqmovun.s32 d5, q3 vmin.u16 q2, q2, q4 @@ -1437,6 +1434,11 @@ function idct32_1d_2x32_pass2_neon load_acc_store 24, 25, 26, 27, 1 load_acc_store 28, 29, 30, 31, 1 .purgem load_acc_store + @ Lengthen the idct16 coeffs back into 32 bit form + vmovl.s16 q2, d2 + vmovl.s16 q3, d3 + vmovl.s16 q1, d1 + vmovl.s16 q0, d0 bx lr endfunc @@ -1447,7 +1449,7 @@ endconst function vp9_idct_idct_32x32_add_16_neon cmp r3, #1 beq idct32x32_dc_add_neon - vpush {q4-q5} + vpush {q4-q7} movrel r8, min_eob_idct_idct_32 + 2 @ Align the stack, allocate a temp buffer @@ -1461,6 +1463,14 @@ A and r7, sp, #15 mov r5, r1 mov r6, r2 + movrel r12, idct_coeffs + vld1.16 {q0-q1}, [r12,:128]! + vld1.16 {q6-q7}, [r12,:128] + vmovl.s16 q2, d2 + vmovl.s16 q3, d3 + vmovl.s16 q1, d1 + vmovl.s16 q0, d0 + .irp i, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 add r0, sp, #(\i*128) .if \i > 0 @@ -1498,7 +1508,7 @@ A and r7, sp, #15 .endr add sp, sp, r7 - vpop {q4-q5} + vpop {q4-q7} pop {r4-r9,pc} endfunc From 25ced1eb1c6cf23099a0fa07ba503b4581713561 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 26 Feb 2017 00:24:50 +0200 Subject: [PATCH 1198/3374] aarch64: vp9itxfm16: Fix a typo in a comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_16bpp_neon.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/aarch64/vp9itxfm_16bpp_neon.S b/libavcodec/aarch64/vp9itxfm_16bpp_neon.S index f53e94ac0c485..f80604f95435c 100644 --- a/libavcodec/aarch64/vp9itxfm_16bpp_neon.S +++ b/libavcodec/aarch64/vp9itxfm_16bpp_neon.S @@ -872,7 +872,7 @@ function \txfm\()16_1d_4x16_pass1_neon transpose_4x4s v24, v25, v26, v27, v4, v5, v6, v7 transpose_4x4s v28, v29, v30, v31, v4, v5, v6, v7 - // Store the transposed 8x8 blocks horizontally. + // Store the transposed 4x4 blocks horizontally. cmp x1, #12 b.eq 1f .irp i, 16, 20, 24, 28, 17, 21, 25, 29, 18, 22, 26, 30, 19, 23, 27, 31 From d613251622d6807fd685452770612a743d7f20a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 26 Feb 2017 00:28:12 +0200 Subject: [PATCH 1199/3374] aarch64: vp9itxfm16: Avoid .irp when it doesn't save any lines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes the code a bit more readable. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_16bpp_neon.S | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_16bpp_neon.S b/libavcodec/aarch64/vp9itxfm_16bpp_neon.S index f80604f95435c..86ea29ec10717 100644 --- a/libavcodec/aarch64/vp9itxfm_16bpp_neon.S +++ b/libavcodec/aarch64/vp9itxfm_16bpp_neon.S @@ -886,21 +886,21 @@ function \txfm\()16_1d_4x16_pass1_neon // for the first slice of the second pass (where it is the // last 4x4 block). add x0, x0, #16 -.irp i, 20, 24, 28 - store \i, x0, #16 -.endr + st1 {v20.4s}, [x0], #16 + st1 {v24.4s}, [x0], #16 + st1 {v28.4s}, [x0], #16 add x0, x0, #16 -.irp i, 21, 25, 29 - store \i, x0, #16 -.endr + st1 {v21.4s}, [x0], #16 + st1 {v25.4s}, [x0], #16 + st1 {v29.4s}, [x0], #16 add x0, x0, #16 -.irp i, 22, 26, 30 - store \i, x0, #16 -.endr + st1 {v22.4s}, [x0], #16 + st1 {v26.4s}, [x0], #16 + st1 {v30.4s}, [x0], #16 add x0, x0, #16 -.irp i, 23, 27, 31 - store \i, x0, #16 -.endr + st1 {v23.4s}, [x0], #16 + st1 {v27.4s}, [x0], #16 + st1 {v31.4s}, [x0], #16 mov v28.16b, v16.16b mov v29.16b, v17.16b From b76533f105cc01f6fb64199309fab84ba22da725 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 26 Feb 2017 13:43:10 +0200 Subject: [PATCH 1200/3374] aarch64: vp9itxfm16: Restructure the idct32 store macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids concatenation, which can't be used if the whole macro is wrapped within another macro. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_16bpp_neon.S | 90 ++++++++++++------------ 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_16bpp_neon.S b/libavcodec/aarch64/vp9itxfm_16bpp_neon.S index 86ea29ec10717..a97c1b6d4cec4 100644 --- a/libavcodec/aarch64/vp9itxfm_16bpp_neon.S +++ b/libavcodec/aarch64/vp9itxfm_16bpp_neon.S @@ -1244,27 +1244,27 @@ function idct32_1d_4x32_pass1_neon .macro store_rev a, b, c, d // There's no rev128 instruction, but we reverse each 64 bit // half, and then flip them using an ext with 8 bytes offset. - rev64 v7.4s, v\d\().4s - st1 {v\a\().4s}, [x0], #16 + rev64 v7.4s, \d + st1 {\a}, [x0], #16 ext v7.16b, v7.16b, v7.16b, #8 - st1 {v\b\().4s}, [x0], #16 - rev64 v6.4s, v\c\().4s - st1 {v\c\().4s}, [x0], #16 + st1 {\b}, [x0], #16 + rev64 v6.4s, \c + st1 {\c}, [x0], #16 ext v6.16b, v6.16b, v6.16b, #8 - st1 {v\d\().4s}, [x0], #16 - rev64 v5.4s, v\b\().4s + st1 {\d}, [x0], #16 + rev64 v5.4s, \b st1 {v7.4s}, [x0], #16 ext v5.16b, v5.16b, v5.16b, #8 st1 {v6.4s}, [x0], #16 - rev64 v4.4s, v\a\().4s + rev64 v4.4s, \a st1 {v5.4s}, [x0], #16 ext v4.16b, v4.16b, v4.16b, #8 st1 {v4.4s}, [x0], #16 .endm - store_rev 16, 20, 24, 28 - store_rev 17, 21, 25, 29 - store_rev 18, 22, 26, 30 - store_rev 19, 23, 27, 31 + store_rev v16.4s, v20.4s, v24.4s, v28.4s + store_rev v17.4s, v21.4s, v25.4s, v29.4s + store_rev v18.4s, v22.4s, v26.4s, v30.4s + store_rev v19.4s, v23.4s, v27.4s, v31.4s sub x0, x0, #512 .purgem store_rev @@ -1290,27 +1290,27 @@ function idct32_1d_4x32_pass1_neon // Store the registers a, b, c, d horizontally, // adding into the output first, and the mirrored, // subtracted from the output. -.macro store_rev a, b, c, d +.macro store_rev a, b, c, d, a16b, b16b ld1 {v4.4s}, [x0] - rev64 v9.4s, v\d\().4s - add v4.4s, v4.4s, v\a\().4s + rev64 v9.4s, \d + add v4.4s, v4.4s, \a st1 {v4.4s}, [x0], #16 - rev64 v8.4s, v\c\().4s + rev64 v8.4s, \c ld1 {v4.4s}, [x0] ext v9.16b, v9.16b, v9.16b, #8 - add v4.4s, v4.4s, v\b\().4s + add v4.4s, v4.4s, \b st1 {v4.4s}, [x0], #16 ext v8.16b, v8.16b, v8.16b, #8 ld1 {v4.4s}, [x0] - rev64 v\b\().4s, v\b\().4s - add v4.4s, v4.4s, v\c\().4s + rev64 \b, \b + add v4.4s, v4.4s, \c st1 {v4.4s}, [x0], #16 - rev64 v\a\().4s, v\a\().4s + rev64 \a, \a ld1 {v4.4s}, [x0] - ext v\b\().16b, v\b\().16b, v\b\().16b, #8 - add v4.4s, v4.4s, v\d\().4s + ext \b16b, \b16b, \b16b, #8 + add v4.4s, v4.4s, \d st1 {v4.4s}, [x0], #16 - ext v\a\().16b, v\a\().16b, v\a\().16b, #8 + ext \a16b, \a16b, \a16b, #8 ld1 {v4.4s}, [x0] sub v4.4s, v4.4s, v9.4s st1 {v4.4s}, [x0], #16 @@ -1318,17 +1318,17 @@ function idct32_1d_4x32_pass1_neon sub v4.4s, v4.4s, v8.4s st1 {v4.4s}, [x0], #16 ld1 {v4.4s}, [x0] - sub v4.4s, v4.4s, v\b\().4s + sub v4.4s, v4.4s, \b st1 {v4.4s}, [x0], #16 ld1 {v4.4s}, [x0] - sub v4.4s, v4.4s, v\a\().4s + sub v4.4s, v4.4s, \a st1 {v4.4s}, [x0], #16 .endm - store_rev 31, 27, 23, 19 - store_rev 30, 26, 22, 18 - store_rev 29, 25, 21, 17 - store_rev 28, 24, 20, 16 + store_rev v31.4s, v27.4s, v23.4s, v19.4s, v31.16b, v27.16b + store_rev v30.4s, v26.4s, v22.4s, v18.4s, v30.16b, v26.16b + store_rev v29.4s, v25.4s, v21.4s, v17.4s, v29.16b, v25.16b + store_rev v28.4s, v24.4s, v20.4s, v16.4s, v28.16b, v24.16b .purgem store_rev ret endfunc @@ -1370,21 +1370,21 @@ function idct32_1d_4x32_pass2_neon .if \neg == 0 ld1 {v4.4s}, [x2], x9 ld1 {v5.4s}, [x2], x9 - add v4.4s, v4.4s, v\a\().4s + add v4.4s, v4.4s, \a ld1 {v6.4s}, [x2], x9 - add v5.4s, v5.4s, v\b\().4s + add v5.4s, v5.4s, \b ld1 {v7.4s}, [x2], x9 - add v6.4s, v6.4s, v\c\().4s - add v7.4s, v7.4s, v\d\().4s + add v6.4s, v6.4s, \c + add v7.4s, v7.4s, \d .else ld1 {v4.4s}, [x2], x7 ld1 {v5.4s}, [x2], x7 - sub v4.4s, v4.4s, v\a\().4s + sub v4.4s, v4.4s, \a ld1 {v6.4s}, [x2], x7 - sub v5.4s, v5.4s, v\b\().4s + sub v5.4s, v5.4s, \b ld1 {v7.4s}, [x2], x7 - sub v6.4s, v6.4s, v\c\().4s - sub v7.4s, v7.4s, v\d\().4s + sub v6.4s, v6.4s, \c + sub v7.4s, v7.4s, \d .endif ld1 {v8.4h}, [x0], x1 ld1 {v8.d}[1], [x0], x1 @@ -1410,15 +1410,15 @@ function idct32_1d_4x32_pass2_neon st1 {v5.4h}, [x0], x1 st1 {v5.d}[1], [x0], x1 .endm - load_acc_store 31, 30, 29, 28 - load_acc_store 27, 26, 25, 24 - load_acc_store 23, 22, 21, 20 - load_acc_store 19, 18, 17, 16 + load_acc_store v31.4s, v30.4s, v29.4s, v28.4s + load_acc_store v27.4s, v26.4s, v25.4s, v24.4s + load_acc_store v23.4s, v22.4s, v21.4s, v20.4s + load_acc_store v19.4s, v18.4s, v17.4s, v16.4s sub x2, x2, x9 - load_acc_store 16, 17, 18, 19, 1 - load_acc_store 20, 21, 22, 23, 1 - load_acc_store 24, 25, 26, 27, 1 - load_acc_store 28, 29, 30, 31, 1 + load_acc_store v16.4s, v17.4s, v18.4s, v19.4s, 1 + load_acc_store v20.4s, v21.4s, v22.4s, v23.4s, 1 + load_acc_store v24.4s, v25.4s, v26.4s, v27.4s, 1 + load_acc_store v28.4s, v29.4s, v30.4s, v31.4s, 1 .purgem load_acc_store ret endfunc From 0ea603203d1a46ea36cbaa3fb53d6fc69f5367ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 24 Feb 2017 16:02:23 +0200 Subject: [PATCH 1201/3374] arm: vp9itxfm16: Make the larger core transforms standalone functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. This reduces the code size of libavcodec/arm/vp9itxfm_16bpp_neon.o from 17500 to 14516 bytes. This gives a small slowdown of a couple tens of cycles, up to around 150 cycles for the full case of the largest transform, but makes it more feasible to add more optimized versions of these transforms. Before: Cortex A7 A8 A9 A53 vp9_inv_dct_dct_16x16_sub4_add_10_neon: 4237.4 3561.5 3971.8 2525.3 vp9_inv_dct_dct_16x16_sub16_add_10_neon: 6371.9 5452.0 5779.3 3910.5 vp9_inv_dct_dct_32x32_sub4_add_10_neon: 22068.8 17867.5 19555.2 13871.6 vp9_inv_dct_dct_32x32_sub32_add_10_neon: 37268.9 38684.2 32314.2 23969.0 After: vp9_inv_dct_dct_16x16_sub4_add_10_neon: 4375.1 3571.9 4283.8 2567.2 vp9_inv_dct_dct_16x16_sub16_add_10_neon: 6415.6 5578.9 5844.6 3948.3 vp9_inv_dct_dct_32x32_sub4_add_10_neon: 22653.7 18079.7 19603.7 13905.3 vp9_inv_dct_dct_32x32_sub32_add_10_neon: 37593.2 38862.2 32235.8 24070.9 Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_16bpp_neon.S | 43 +++++++++++++++++----------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_16bpp_neon.S b/libavcodec/arm/vp9itxfm_16bpp_neon.S index 29d95ca22843c..8350153f73165 100644 --- a/libavcodec/arm/vp9itxfm_16bpp_neon.S +++ b/libavcodec/arm/vp9itxfm_16bpp_neon.S @@ -807,7 +807,7 @@ function idct16x16_dc_add_neon endfunc .ltorg -.macro idct16 +function idct16 mbutterfly0 d16, d24, d16, d24, d8, d10, q4, q5 @ d16 = t0a, d24 = t1a mbutterfly d20, d28, d1[0], d1[1], q4, q5 @ d20 = t2a, d28 = t3a mbutterfly d18, d30, d2[0], d2[1], q4, q5 @ d18 = t4a, d30 = t7a @@ -853,9 +853,10 @@ endfunc vmov d8, d21 @ d8 = t10a butterfly d20, d27, d10, d27 @ d20 = out[4], d27 = out[11] butterfly d21, d26, d26, d8 @ d21 = out[5], d26 = out[10] -.endm + bx lr +endfunc -.macro iadst16 +function iadst16 movrel r12, iadst16_coeffs vld1.16 {q0}, [r12,:128]! vmovl.s16 q1, d1 @@ -933,7 +934,8 @@ endfunc vmov d16, d2 vmov d30, d4 -.endm + bx lr +endfunc .macro itxfm16_1d_funcs txfm @ Read a vertical 2x16 slice out of a 16x16 matrix, do a transform on it, @@ -941,6 +943,8 @@ endfunc @ r0 = dst (temp buffer) @ r2 = src function \txfm\()16_1d_2x16_pass1_neon + push {lr} + mov r12, #64 vmov.s32 q4, #0 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 @@ -948,7 +952,7 @@ function \txfm\()16_1d_2x16_pass1_neon vst1.32 {d8}, [r2,:64], r12 .endr - \txfm\()16 + bl \txfm\()16 @ Do eight 2x2 transposes. Originally, d16-d31 contain the @ 16 rows. Afterwards, d16-d17, d18-d19 etc contain the eight @@ -959,7 +963,7 @@ function \txfm\()16_1d_2x16_pass1_neon .irp i, 16, 18, 20, 22, 24, 26, 28, 30, 17, 19, 21, 23, 25, 27, 29, 31 vst1.32 {d\i}, [r0,:64]! .endr - bx lr + pop {pc} endfunc @ Read a vertical 2x16 slice out of a 16x16 matrix, do a transform on it, @@ -968,6 +972,8 @@ endfunc @ r1 = dst stride @ r2 = src (temp buffer) function \txfm\()16_1d_2x16_pass2_neon + push {lr} + mov r12, #64 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vld1.16 {d\i}, [r2,:64], r12 @@ -975,7 +981,7 @@ function \txfm\()16_1d_2x16_pass2_neon add r3, r0, r1 lsl r1, r1, #1 - \txfm\()16 + bl \txfm\()16 .macro load_add_store coef0, coef1, coef2, coef3 vrshr.s32 \coef0, \coef0, #6 @@ -1019,7 +1025,7 @@ function \txfm\()16_1d_2x16_pass2_neon load_add_store q12, q13, q14, q15 .purgem load_add_store - bx lr + pop {pc} endfunc .endm @@ -1193,7 +1199,7 @@ function idct32x32_dc_add_neon pop {r4-r9,pc} endfunc -.macro idct32_odd +function idct32_odd movrel r12, idct_coeffs @ Overwrite the idct16 coeffs with the stored ones for idct32 @@ -1262,7 +1268,8 @@ endfunc mbutterfly0 d26, d21, d26, d21, d8, d10, q4, q5 @ d26 = t26a, d21 = t21a mbutterfly0 d25, d22, d25, d22, d8, d10, q4, q5 @ d25 = t25, d22 = t22 mbutterfly0 d24, d23, d24, d23, d8, d10, q4, q5 @ d24 = t24a, d23 = t23a -.endm + bx lr +endfunc @ Do an 32-point IDCT of a 2x32 slice out of a 32x32 matrix. @ We don't have register space to do a single pass IDCT of 2x32 though, @@ -1274,6 +1281,8 @@ endfunc @ r1 = unused @ r2 = src function idct32_1d_2x32_pass1_neon + push {lr} + @ Double stride of the input, since we only read every other line mov r12, #256 vmov.s32 d8, #0 @@ -1284,7 +1293,7 @@ function idct32_1d_2x32_pass1_neon vst1.32 {d8}, [r2,:64], r12 .endr - idct16 + bl idct16 @ Do eight 2x2 transposes. Originally, d16-d31 contain the @ 16 rows. Afterwards, d16-d17, d18-d19 etc contain the eight @@ -1319,7 +1328,7 @@ function idct32_1d_2x32_pass1_neon vst1.16 {d8}, [r2,:64], r12 .endr - idct32_odd + bl idct32_odd transpose32_8x_2x2 d31, d30, d29, d28, d27, d26, d25, d24, d23, d22, d21, d20, d19, d18, d17, d16 @@ -1343,7 +1352,7 @@ function idct32_1d_2x32_pass1_neon store_rev 31, 29, 27, 25, 23, 21, 19, 17 store_rev 30, 28, 26, 24, 22, 20, 18, 16 .purgem store_rev - bx lr + pop {pc} endfunc .ltorg @@ -1354,6 +1363,8 @@ endfunc @ r1 = dst stride @ r2 = src (temp buffer) function idct32_1d_2x32_pass2_neon + push {lr} + mov r12, #256 @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30) .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 @@ -1361,7 +1372,7 @@ function idct32_1d_2x32_pass2_neon .endr sub r2, r2, r12, lsl #4 - idct16 + bl idct16 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vst1.32 {d\i}, [r2,:64], r12 @@ -1377,7 +1388,7 @@ function idct32_1d_2x32_pass2_neon sub r2, r2, r12, lsl #4 sub r2, r2, #128 - idct32_odd + bl idct32_odd @ Narrow the ict16 coefficients in q0-q3 into q0-q1, to @ allow clobbering q2-q3 below. @@ -1439,7 +1450,7 @@ function idct32_1d_2x32_pass2_neon vmovl.s16 q3, d3 vmovl.s16 q1, d1 vmovl.s16 q0, d0 - bx lr + pop {pc} endfunc const min_eob_idct_idct_32, align=4 From 0f2705e66b1f7f9ae900667c400e46fa0e4f15a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 24 Feb 2017 16:10:25 +0200 Subject: [PATCH 1202/3374] aarch64: vp9itxfm16: Make the larger core transforms standalone functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. This reduces the code size of libavcodec/aarch64/vp9itxfm_16bpp_neon.o from 26288 to 21512 bytes. This gives a small slowdown of a couple of tens of cycles, but makes it more feasible to add more optimized versions of these transforms. Before: vp9_inv_dct_dct_16x16_sub4_add_10_neon: 1887.4 vp9_inv_dct_dct_16x16_sub16_add_10_neon: 2801.5 vp9_inv_dct_dct_32x32_sub4_add_10_neon: 9691.4 vp9_inv_dct_dct_32x32_sub32_add_10_neon: 16154.9 After: vp9_inv_dct_dct_16x16_sub4_add_10_neon: 1899.5 vp9_inv_dct_dct_16x16_sub16_add_10_neon: 2827.2 vp9_inv_dct_dct_32x32_sub4_add_10_neon: 9714.7 vp9_inv_dct_dct_32x32_sub32_add_10_neon: 16175.9 Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_16bpp_neon.S | 45 +++++++++++++++--------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_16bpp_neon.S b/libavcodec/aarch64/vp9itxfm_16bpp_neon.S index a97c1b6d4cec4..de1da55c2e6a5 100644 --- a/libavcodec/aarch64/vp9itxfm_16bpp_neon.S +++ b/libavcodec/aarch64/vp9itxfm_16bpp_neon.S @@ -710,7 +710,7 @@ function idct16x16_dc_add_neon ret endfunc -.macro idct16 +function idct16 dmbutterfly0 v16, v24, v16, v24, v4, v5, v6, v7, v8, v9 // v16 = t0a, v24 = t1a dmbutterfly v20, v28, v0.s[2], v0.s[3], v4, v5, v6, v7 // v20 = t2a, v28 = t3a dmbutterfly v18, v30, v1.s[0], v1.s[1], v4, v5, v6, v7 // v18 = t4a, v30 = t7a @@ -753,9 +753,10 @@ endfunc butterfly_4s v19, v28, v5, v28 // v19 = out[3], v28 = out[12] butterfly_4s v20, v27, v6, v27 // v20 = out[4], v27 = out[11] butterfly_4s v21, v26, v26, v9 // v21 = out[5], v26 = out[10] -.endm + ret +endfunc -.macro iadst16 +function iadst16 ld1 {v0.8h,v1.8h}, [x11] sxtl v2.4s, v1.4h sxtl2 v3.4s, v1.8h @@ -830,7 +831,8 @@ endfunc mov v16.16b, v2.16b mov v30.16b, v4.16b -.endm + ret +endfunc // Helper macros; we can't use these expressions directly within // e.g. .irp due to the extra concatenation \(). Therefore wrap @@ -857,12 +859,14 @@ endfunc // x9 = input stride .macro itxfm16_1d_funcs txfm function \txfm\()16_1d_4x16_pass1_neon + mov x14, x30 + movi v4.4s, #0 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 load_clear \i, x2, x9 .endr - \txfm\()16 + bl \txfm\()16 // Do four 4x4 transposes. Originally, v16-v31 contain the // 16 rows. Afterwards, v16-v19, v20-v23, v24-v27 and v28-v31 @@ -878,7 +882,7 @@ function \txfm\()16_1d_4x16_pass1_neon .irp i, 16, 20, 24, 28, 17, 21, 25, 29, 18, 22, 26, 30, 19, 23, 27, 31 store \i, x0, #16 .endr - ret + br x14 1: // Special case: For the last input column (x1 == 12), // which would be stored as the last row in the temp buffer, @@ -906,7 +910,7 @@ function \txfm\()16_1d_4x16_pass1_neon mov v29.16b, v17.16b mov v30.16b, v18.16b mov v31.16b, v19.16b - ret + br x14 endfunc // Read a vertical 4x16 slice out of a 16x16 matrix, do a transform on it, @@ -917,6 +921,8 @@ endfunc // x3 = slice offset // x9 = temp buffer stride function \txfm\()16_1d_4x16_pass2_neon + mov x14, x30 + .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 load \i, x2, x9 .endr @@ -928,7 +934,7 @@ function \txfm\()16_1d_4x16_pass2_neon add x3, x0, x1 lsl x1, x1, #1 - \txfm\()16 + bl \txfm\()16 dup v8.8h, w13 .macro load_add_store coef0, coef1, coef2, coef3, coef4, coef5, coef6, coef7 @@ -983,7 +989,7 @@ function \txfm\()16_1d_4x16_pass2_neon load_add_store v24.4s, v25.4s, v26.4s, v27.4s, v28.4s, v29.4s, v30.4s, v31.4s .purgem load_add_store - ret + br x14 endfunc .endm @@ -1158,7 +1164,7 @@ function idct32x32_dc_add_neon ret endfunc -.macro idct32_odd +function idct32_odd dmbutterfly v16, v31, v10.s[0], v10.s[1], v4, v5, v6, v7 // v16 = t16a, v31 = t31a dmbutterfly v24, v23, v10.s[2], v10.s[3], v4, v5, v6, v7 // v24 = t17a, v23 = t30a dmbutterfly v20, v27, v11.s[0], v11.s[1], v4, v5, v6, v7 // v20 = t18a, v27 = t29a @@ -1209,7 +1215,8 @@ endfunc dmbutterfly0 v26, v21, v26, v21, v4, v5, v6, v7, v8, v9 // v26 = t26a, v21 = t21a dmbutterfly0 v25, v22, v25, v22, v4, v5, v6, v7, v8, v9 // v25 = t25, v22 = t22 dmbutterfly0 v24, v23, v24, v23, v4, v5, v6, v7, v8, v9 // v24 = t24a, v23 = t23a -.endm + ret +endfunc // Do an 32-point IDCT of a 4x32 slice out of a 32x32 matrix. // The 32-point IDCT can be decomposed into two 16-point IDCTs; @@ -1221,6 +1228,8 @@ endfunc // x2 = src // x9 = double input stride function idct32_1d_4x32_pass1_neon + mov x14, x30 + movi v4.4s, #0 // v16 = IN(0), v17 = IN(2) ... v31 = IN(30) @@ -1229,7 +1238,7 @@ function idct32_1d_4x32_pass1_neon st1 {v4.4s}, [x2], x9 .endr - idct16 + bl idct16 // Do four 4x4 transposes. Originally, v16-v31 contain the // 16 rows. Afterwards, v16-v19, v20-v23, v24-v27 and v28-v31 @@ -1280,7 +1289,7 @@ function idct32_1d_4x32_pass1_neon st1 {v4.4s}, [x2], x9 .endr - idct32_odd + bl idct32_odd transpose_4x4s v31, v30, v29, v28, v4, v5, v6, v7 transpose_4x4s v27, v26, v25, v24, v4, v5, v6, v7 @@ -1330,7 +1339,7 @@ function idct32_1d_4x32_pass1_neon store_rev v29.4s, v25.4s, v21.4s, v17.4s, v29.16b, v25.16b store_rev v28.4s, v24.4s, v20.4s, v16.4s, v28.16b, v24.16b .purgem store_rev - ret + br x14 endfunc // This is mostly the same as 4x32_pass1, but without the transpose, @@ -1342,13 +1351,15 @@ endfunc // x7 = negative double temp buffer stride // x9 = double temp buffer stride function idct32_1d_4x32_pass2_neon + mov x14, x30 + // v16 = IN(0), v17 = IN(2) ... v31 = IN(30) .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 ld1 {v\i\().4s}, [x2], x9 .endr sub x2, x2, x9, lsl #4 - idct16 + bl idct16 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 st1 {v\i\().4s}, [x2], x9 @@ -1364,7 +1375,7 @@ function idct32_1d_4x32_pass2_neon sub x2, x2, x9, lsl #4 sub x2, x2, #128 - idct32_odd + bl idct32_odd .macro load_acc_store a, b, c, d, neg=0 .if \neg == 0 @@ -1420,7 +1431,7 @@ function idct32_1d_4x32_pass2_neon load_acc_store v24.4s, v25.4s, v26.4s, v27.4s, 1 load_acc_store v28.4s, v29.4s, v30.4s, v31.4s, 1 .purgem load_acc_store - ret + br x14 endfunc const min_eob_idct_idct_32, align=4 From d564c9018f8a45c1f4c38f02844186545582531d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 24 Feb 2017 16:49:12 +0200 Subject: [PATCH 1203/3374] aarch64: vp9itxfm16: Move the load_add_store macro out from the itxfm16 pass2 function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows reusing the macro for a separate implementation of the pass2 function. Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_16bpp_neon.S | 98 ++++++++++++------------ 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_16bpp_neon.S b/libavcodec/aarch64/vp9itxfm_16bpp_neon.S index de1da55c2e6a5..f30fdd868987c 100644 --- a/libavcodec/aarch64/vp9itxfm_16bpp_neon.S +++ b/libavcodec/aarch64/vp9itxfm_16bpp_neon.S @@ -851,6 +851,55 @@ endfunc st1 {v4.4s}, [\src], \inc .endm +.macro load_add_store coef0, coef1, coef2, coef3, coef4, coef5, coef6, coef7 + srshr \coef0, \coef0, #6 + ld1 {v4.4h}, [x0], x1 + srshr \coef1, \coef1, #6 + ld1 {v4.d}[1], [x3], x1 + srshr \coef2, \coef2, #6 + ld1 {v5.4h}, [x0], x1 + srshr \coef3, \coef3, #6 + uaddw \coef0, \coef0, v4.4h + ld1 {v5.d}[1], [x3], x1 + srshr \coef4, \coef4, #6 + uaddw2 \coef1, \coef1, v4.8h + ld1 {v6.4h}, [x0], x1 + srshr \coef5, \coef5, #6 + uaddw \coef2, \coef2, v5.4h + ld1 {v6.d}[1], [x3], x1 + sqxtun v4.4h, \coef0 + srshr \coef6, \coef6, #6 + uaddw2 \coef3, \coef3, v5.8h + ld1 {v7.4h}, [x0], x1 + sqxtun2 v4.8h, \coef1 + srshr \coef7, \coef7, #6 + uaddw \coef4, \coef4, v6.4h + ld1 {v7.d}[1], [x3], x1 + umin v4.8h, v4.8h, v8.8h + sub x0, x0, x1, lsl #2 + sub x3, x3, x1, lsl #2 + sqxtun v5.4h, \coef2 + uaddw2 \coef5, \coef5, v6.8h + st1 {v4.4h}, [x0], x1 + sqxtun2 v5.8h, \coef3 + uaddw \coef6, \coef6, v7.4h + st1 {v4.d}[1], [x3], x1 + umin v5.8h, v5.8h, v8.8h + sqxtun v6.4h, \coef4 + uaddw2 \coef7, \coef7, v7.8h + st1 {v5.4h}, [x0], x1 + sqxtun2 v6.8h, \coef5 + st1 {v5.d}[1], [x3], x1 + umin v6.8h, v6.8h, v8.8h + sqxtun v7.4h, \coef6 + st1 {v6.4h}, [x0], x1 + sqxtun2 v7.8h, \coef7 + st1 {v6.d}[1], [x3], x1 + umin v7.8h, v7.8h, v8.8h + st1 {v7.4h}, [x0], x1 + st1 {v7.d}[1], [x3], x1 +.endm + // Read a vertical 4x16 slice out of a 16x16 matrix, do a transform on it, // transpose into a horizontal 16x4 slice and store. // x0 = dst (temp buffer) @@ -937,57 +986,8 @@ function \txfm\()16_1d_4x16_pass2_neon bl \txfm\()16 dup v8.8h, w13 -.macro load_add_store coef0, coef1, coef2, coef3, coef4, coef5, coef6, coef7 - srshr \coef0, \coef0, #6 - ld1 {v4.4h}, [x0], x1 - srshr \coef1, \coef1, #6 - ld1 {v4.d}[1], [x3], x1 - srshr \coef2, \coef2, #6 - ld1 {v5.4h}, [x0], x1 - srshr \coef3, \coef3, #6 - uaddw \coef0, \coef0, v4.4h - ld1 {v5.d}[1], [x3], x1 - srshr \coef4, \coef4, #6 - uaddw2 \coef1, \coef1, v4.8h - ld1 {v6.4h}, [x0], x1 - srshr \coef5, \coef5, #6 - uaddw \coef2, \coef2, v5.4h - ld1 {v6.d}[1], [x3], x1 - sqxtun v4.4h, \coef0 - srshr \coef6, \coef6, #6 - uaddw2 \coef3, \coef3, v5.8h - ld1 {v7.4h}, [x0], x1 - sqxtun2 v4.8h, \coef1 - srshr \coef7, \coef7, #6 - uaddw \coef4, \coef4, v6.4h - ld1 {v7.d}[1], [x3], x1 - umin v4.8h, v4.8h, v8.8h - sub x0, x0, x1, lsl #2 - sub x3, x3, x1, lsl #2 - sqxtun v5.4h, \coef2 - uaddw2 \coef5, \coef5, v6.8h - st1 {v4.4h}, [x0], x1 - sqxtun2 v5.8h, \coef3 - uaddw \coef6, \coef6, v7.4h - st1 {v4.d}[1], [x3], x1 - umin v5.8h, v5.8h, v8.8h - sqxtun v6.4h, \coef4 - uaddw2 \coef7, \coef7, v7.8h - st1 {v5.4h}, [x0], x1 - sqxtun2 v6.8h, \coef5 - st1 {v5.d}[1], [x3], x1 - umin v6.8h, v6.8h, v8.8h - sqxtun v7.4h, \coef6 - st1 {v6.4h}, [x0], x1 - sqxtun2 v7.8h, \coef7 - st1 {v6.d}[1], [x3], x1 - umin v7.8h, v7.8h, v8.8h - st1 {v7.4h}, [x0], x1 - st1 {v7.d}[1], [x3], x1 -.endm load_add_store v16.4s, v17.4s, v18.4s, v19.4s, v20.4s, v21.4s, v22.4s, v23.4s load_add_store v24.4s, v25.4s, v26.4s, v27.4s, v28.4s, v29.4s, v30.4s, v31.4s -.purgem load_add_store br x14 endfunc From eabc5abf949bb8cadafe33df73adacf87ee4c5e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 24 Feb 2017 17:39:00 +0200 Subject: [PATCH 1204/3374] arm: vp9itxfm16: Do a simpler half/quarter idct16/idct32 when possible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. This avoids loading and calculating coefficients that we know will be zero, and avoids filling the temp buffer with zeros in places where we know the second pass won't read. This gives a pretty substantial speedup for the smaller subpartitions. The code size increases from 14516 bytes to 22484 bytes. The idct16/32_end macros are moved above the individual functions; the instructions themselves are unchanged, but since new functions are added at the same place where the code is moved from, the diff looks rather messy. Before: Cortex A7 A8 A9 A53 vp9_inv_dct_dct_16x16_sub1_add_10_neon: 454.0 270.7 418.5 295.4 vp9_inv_dct_dct_16x16_sub2_add_10_neon: 3840.2 3244.8 3700.1 2337.9 vp9_inv_dct_dct_16x16_sub4_add_10_neon: 4212.5 3575.4 3996.9 2571.6 vp9_inv_dct_dct_16x16_sub8_add_10_neon: 5174.4 4270.5 4615.5 3031.9 vp9_inv_dct_dct_16x16_sub12_add_10_neon: 5676.0 4908.5 5226.5 3491.3 vp9_inv_dct_dct_16x16_sub16_add_10_neon: 6403.9 5589.0 5839.8 3948.5 vp9_inv_dct_dct_32x32_sub1_add_10_neon: 1710.7 944.7 1582.1 1045.4 vp9_inv_dct_dct_32x32_sub2_add_10_neon: 21040.7 16706.1 18687.7 13193.1 vp9_inv_dct_dct_32x32_sub4_add_10_neon: 22197.7 18282.7 19577.5 13918.6 vp9_inv_dct_dct_32x32_sub8_add_10_neon: 24511.5 20911.5 21472.5 15367.5 vp9_inv_dct_dct_32x32_sub12_add_10_neon: 26939.5 24264.3 23239.1 16830.3 vp9_inv_dct_dct_32x32_sub16_add_10_neon: 29419.5 26845.1 25020.6 18259.9 vp9_inv_dct_dct_32x32_sub20_add_10_neon: 31146.4 29633.5 26803.3 19721.7 vp9_inv_dct_dct_32x32_sub24_add_10_neon: 33376.3 32507.8 28642.4 21174.2 vp9_inv_dct_dct_32x32_sub28_add_10_neon: 35629.4 35439.6 30416.5 22625.7 vp9_inv_dct_dct_32x32_sub32_add_10_neon: 37269.9 37914.9 32271.9 24078.9 After: vp9_inv_dct_dct_16x16_sub1_add_10_neon: 454.0 276.0 418.5 295.1 vp9_inv_dct_dct_16x16_sub2_add_10_neon: 2336.2 1886.0 2251.0 1458.6 vp9_inv_dct_dct_16x16_sub4_add_10_neon: 2531.0 2054.7 2402.8 1591.1 vp9_inv_dct_dct_16x16_sub8_add_10_neon: 3848.6 3491.1 3845.7 2554.8 vp9_inv_dct_dct_16x16_sub12_add_10_neon: 5703.8 4831.6 5230.8 3493.4 vp9_inv_dct_dct_16x16_sub16_add_10_neon: 6399.5 5567.0 5832.4 3951.5 vp9_inv_dct_dct_32x32_sub1_add_10_neon: 1722.1 938.5 1577.3 1044.5 vp9_inv_dct_dct_32x32_sub2_add_10_neon: 15003.5 11576.8 13105.8 9602.2 vp9_inv_dct_dct_32x32_sub4_add_10_neon: 15768.5 12677.2 13726.0 10138.1 vp9_inv_dct_dct_32x32_sub8_add_10_neon: 17278.8 14825.4 14907.5 11185.7 vp9_inv_dct_dct_32x32_sub12_add_10_neon: 22335.7 21544.5 20379.5 15019.8 vp9_inv_dct_dct_32x32_sub16_add_10_neon: 24165.6 23881.7 21938.6 16308.2 vp9_inv_dct_dct_32x32_sub20_add_10_neon: 31082.2 30860.9 26835.3 19711.3 vp9_inv_dct_dct_32x32_sub24_add_10_neon: 33102.6 31922.8 28638.3 21161.0 vp9_inv_dct_dct_32x32_sub28_add_10_neon: 35104.9 34867.5 30411.7 22621.2 vp9_inv_dct_dct_32x32_sub32_add_10_neon: 37438.1 39103.4 32217.8 24067.6 Signed-off-by: Martin Storsjö --- libavcodec/arm/vp9itxfm_16bpp_neon.S | 529 ++++++++++++++++++++++++--- 1 file changed, 469 insertions(+), 60 deletions(-) diff --git a/libavcodec/arm/vp9itxfm_16bpp_neon.S b/libavcodec/arm/vp9itxfm_16bpp_neon.S index 8350153f73165..b4f615ebb81ce 100644 --- a/libavcodec/arm/vp9itxfm_16bpp_neon.S +++ b/libavcodec/arm/vp9itxfm_16bpp_neon.S @@ -82,6 +82,14 @@ endconst vrshrn.s64 \out2, \tmpq4, #14 .endm +@ Same as mbutterfly0 above, but treating the input in in2 as zero, +@ writing the same output into both out1 and out2. +.macro mbutterfly0_h out1, out2, in1, in2, tmpd1, tmpd2, tmpq3, tmpq4 + vmull.s32 \tmpq3, \in1, d0[0] + vrshrn.s64 \out1, \tmpq3, #14 + vrshrn.s64 \out2, \tmpq3, #14 +.endm + @ out1,out2 = ((in1 + in2) * d0[0] + (1 << 13)) >> 14 @ out3,out4 = ((in1 - in2) * d0[0] + (1 << 13)) >> 14 @ Same as mbutterfly0, but with input being 2 q registers, output @@ -148,6 +156,23 @@ endconst vrshrn.s64 \inout2, \tmp2, #14 .endm +@ Same as mbutterfly above, but treating the input in inout2 as zero +.macro mbutterfly_h1 inout1, inout2, coef1, coef2, tmp1, tmp2 + vmull.s32 \tmp1, \inout1, \coef1 + vmull.s32 \tmp2, \inout1, \coef2 + vrshrn.s64 \inout1, \tmp1, #14 + vrshrn.s64 \inout2, \tmp2, #14 +.endm + +@ Same as mbutterfly above, but treating the input in inout1 as zero +.macro mbutterfly_h2 inout1, inout2, coef1, coef2, tmp1, tmp2 + vmov.s64 \tmp1, #0 + vmull.s32 \tmp2, \inout2, \coef1 + vmlsl.s32 \tmp1, \inout2, \coef2 + vrshrn.s64 \inout2, \tmp2, #14 + vrshrn.s64 \inout1, \tmp1, #14 +.endm + @ inout1,inout2 = (inout1,inout2 * coef1 - inout3,inout4 * coef2 + (1 << 13)) >> 14 @ inout3,inout4 = (inout1,inout2 * coef2 + inout3,inout4 * coef1 + (1 << 13)) >> 14 @ inout are 4 d registers, tmp are 4 q registers @@ -807,6 +832,33 @@ function idct16x16_dc_add_neon endfunc .ltorg +.macro idct16_end + butterfly d18, d11, d8, d11 @ d18 = t0a, d11 = t7a + butterfly d19, d22, d9, d22 @ d19 = t1a, d22 = t6 + butterfly d8, d26, d20, d26 @ d8 = t2a, d26 = t5 + butterfly d9, d10, d28, d10 @ d9 = t3a, d10 = t4 + butterfly d20, d28, d16, d24 @ d20 = t8a, d28 = t11a + butterfly d24, d21, d23, d21 @ d24 = t9, d21 = t10 + butterfly d23, d27, d25, d27 @ d23 = t14, d27 = t13 + butterfly d25, d29, d29, d17 @ d25 = t15a, d29 = t12a + + mbutterfly0 d27, d21, d27, d21, d16, d30, q8, q15 @ d27 = t13a, d21 = t10a + mbutterfly0 d29, d28, d29, d28, d16, d30, q8, q15 @ d29 = t12, d28 = t11 + + vswp d27, d29 @ d27 = t12, d29 = t13a + vswp d28, d27 @ d28 = t12, d27 = t11 + butterfly d16, d31, d18, d25 @ d16 = out[0], d31 = out[15] + butterfly d17, d30, d19, d23 @ d17 = out[1], d30 = out[14] + butterfly_r d25, d22, d22, d24 @ d25 = out[9], d22 = out[6] + butterfly d23, d24, d11, d20 @ d23 = out[7], d24 = out[8] + butterfly d18, d29, d8, d29 @ d18 = out[2], d29 = out[13] + butterfly d19, d28, d9, d28 @ d19 = out[3], d28 = out[12] + vmov d8, d21 @ d8 = t10a + butterfly d20, d27, d10, d27 @ d20 = out[4], d27 = out[11] + butterfly d21, d26, d26, d8 @ d21 = out[5], d26 = out[10] + bx lr +.endm + function idct16 mbutterfly0 d16, d24, d16, d24, d8, d10, q4, q5 @ d16 = t0a, d24 = t1a mbutterfly d20, d28, d1[0], d1[1], q4, q5 @ d20 = t2a, d28 = t3a @@ -829,31 +881,62 @@ function idct16 mbutterfly0 d22, d26, d22, d26, d18, d30, q9, q15 @ d22 = t6a, d26 = t5a mbutterfly d23, d25, d1[0], d1[1], q9, q15 @ d23 = t9a, d25 = t14a mbutterfly d27, d21, d1[0], d1[1], q9, q15, neg=1 @ d27 = t13a, d21 = t10a + idct16_end +endfunc - butterfly d18, d11, d8, d11 @ d18 = t0a, d11 = t7a - butterfly d19, d22, d9, d22 @ d19 = t1a, d22 = t6 - butterfly d8, d26, d20, d26 @ d8 = t2a, d26 = t5 - butterfly d9, d10, d28, d10 @ d9 = t3a, d10 = t4 - butterfly d20, d28, d16, d24 @ d20 = t8a, d28 = t11a - butterfly d24, d21, d23, d21 @ d24 = t9, d21 = t10 - butterfly d23, d27, d25, d27 @ d23 = t14, d27 = t13 - butterfly d25, d29, d29, d17 @ d25 = t15a, d29 = t12a +function idct16_half + mbutterfly0_h d16, d24, d16, d24, d8, d10, q4, q5 @ d16 = t0a, d24 = t1a + mbutterfly_h1 d20, d28, d1[0], d1[1], q4, q5 @ d20 = t2a, d28 = t3a + mbutterfly_h1 d18, d30, d2[0], d2[1], q4, q5 @ d18 = t4a, d30 = t7a + mbutterfly_h2 d26, d22, d3[0], d3[1], q4, q5 @ d26 = t5a, d22 = t6a + mbutterfly_h1 d17, d31, d4[0], d4[1], q4, q5 @ d17 = t8a, d31 = t15a + mbutterfly_h2 d25, d23, d5[0], d5[1], q4, q5 @ d25 = t9a, d23 = t14a + mbutterfly_h1 d21, d27, d6[0], d6[1], q4, q5 @ d21 = t10a, d27 = t13a + mbutterfly_h2 d29, d19, d7[0], d7[1], q4, q5 @ d29 = t11a, d19 = t12a - mbutterfly0 d27, d21, d27, d21, d16, d30, q8, q15 @ d27 = t13a, d21 = t10a - mbutterfly0 d29, d28, d29, d28, d16, d30, q8, q15 @ d29 = t12, d28 = t11 + butterfly d8, d28, d16, d28 @ d8 = t0, d28 = t3 + butterfly d9, d20, d24, d20 @ d9 = t1, d20 = t2 + butterfly d10, d26, d18, d26 @ d10 = t4, d26 = t5 + butterfly d11, d22, d30, d22 @ d11 = t7, d22 = t6 + butterfly d16, d25, d17, d25 @ d16 = t8, d25 = t9 + butterfly d24, d21, d29, d21 @ d24 = t11, d21 = t10 + butterfly d17, d27, d19, d27 @ d17 = t12, d27 = t13 + butterfly d29, d23, d31, d23 @ d29 = t15, d23 = t14 - vswp d27, d29 @ d27 = t12, d29 = t13a - vswp d28, d27 @ d28 = t12, d27 = t11 - butterfly d16, d31, d18, d25 @ d16 = out[0], d31 = out[15] - butterfly d17, d30, d19, d23 @ d17 = out[1], d30 = out[14] - butterfly_r d25, d22, d22, d24 @ d25 = out[9], d22 = out[6] - butterfly d23, d24, d11, d20 @ d23 = out[7], d24 = out[8] - butterfly d18, d29, d8, d29 @ d18 = out[2], d29 = out[13] - butterfly d19, d28, d9, d28 @ d19 = out[3], d28 = out[12] - vmov d8, d21 @ d8 = t10a - butterfly d20, d27, d10, d27 @ d20 = out[4], d27 = out[11] - butterfly d21, d26, d26, d8 @ d21 = out[5], d26 = out[10] - bx lr + mbutterfly0 d22, d26, d22, d26, d18, d30, q9, q15 @ d22 = t6a, d26 = t5a + mbutterfly d23, d25, d1[0], d1[1], q9, q15 @ d23 = t9a, d25 = t14a + mbutterfly d27, d21, d1[0], d1[1], q9, q15, neg=1 @ d27 = t13a, d21 = t10a + idct16_end +endfunc + +function idct16_quarter + vmov.s64 q12, #0 + vmull.s32 q4, d17, d4[0] + vmull.s32 q5, d18, d2[1] + vmull.s32 q15, d18, d2[0] + vmlsl.s32 q12, d19, d7[1] + vmull.s32 q14, d17, d4[1] + vmull.s32 q13, d19, d7[0] + vmull.s32 q11, d16, d0[0] + vrshrn.s64 d16, q4, #14 + vrshrn.s64 d11, q5, #14 + vrshrn.s64 d10, q15, #14 + vrshrn.s64 d24, q12, #14 + vrshrn.s64 d29, q14, #14 + vrshrn.s64 d17, q13, #14 + vrshrn.s64 d28, q11, #14 + + mbutterfly_l q10, q11, d17, d24, d1[0], d1[1], neg=1 + mbutterfly_l q9, q15, d29, d16, d1[0], d1[1] + vrshrn.s64 d27, q10, #14 + vrshrn.s64 d21, q11, #14 + vrshrn.s64 d23, q9, #14 + vrshrn.s64 d25, q15, #14 + vmov d8, d28 + vmov d9, d28 + mbutterfly0 d22, d26, d11, d10, d18, d30, q9, q15 + vmov d20, d28 + idct16_end endfunc function iadst16 @@ -937,22 +1020,36 @@ function iadst16 bx lr endfunc -.macro itxfm16_1d_funcs txfm +.macro itxfm16_1d_funcs txfm, suffix @ Read a vertical 2x16 slice out of a 16x16 matrix, do a transform on it, @ transpose into a horizontal 16x2 slice and store. @ r0 = dst (temp buffer) @ r2 = src -function \txfm\()16_1d_2x16_pass1_neon +function \txfm\()16_1d_2x16_pass1\suffix\()_neon push {lr} mov r12, #64 vmov.s32 q4, #0 +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vld1.32 {d\i}, [r2,:64] vst1.32 {d8}, [r2,:64], r12 .endr +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + vld1.32 {d\i}, [r2,:64] + vst1.32 {d8}, [r2,:64], r12 +.endr +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + vld1.32 {d\i}, [r2,:64] + vst1.32 {d8}, [r2,:64], r12 +.endr +.endif - bl \txfm\()16 + bl \txfm\()16\suffix @ Do eight 2x2 transposes. Originally, d16-d31 contain the @ 16 rows. Afterwards, d16-d17, d18-d19 etc contain the eight @@ -971,17 +1068,29 @@ endfunc @ r0 = dst @ r1 = dst stride @ r2 = src (temp buffer) -function \txfm\()16_1d_2x16_pass2_neon +function \txfm\()16_1d_2x16_pass2\suffix\()_neon push {lr} mov r12, #64 +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vld1.16 {d\i}, [r2,:64], r12 .endr +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19, 20 + vld1.16 {d\i}, [r2,:64], r12 +.endr +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + vld1.16 {d\i}, [r2,:64], r12 +.endr +.endif add r3, r0, r1 lsl r1, r1, #1 - bl \txfm\()16 + bl \txfm\()16\suffix .macro load_add_store coef0, coef1, coef2, coef3 vrshr.s32 \coef0, \coef0, #6 @@ -1031,6 +1140,9 @@ endfunc itxfm16_1d_funcs idct itxfm16_1d_funcs iadst +itxfm16_1d_funcs idct, _quarter +itxfm16_1d_funcs idct, _half +.ltorg @ This is the minimum eob value for each subpartition, in increments of 2 const min_eob_idct_idct_16, align=4 @@ -1047,7 +1159,6 @@ function vp9_\txfm1\()_\txfm2\()_16x16_add_16_neon vpush {q4-q7} .else vpush {q4-q5} - movrel r8, min_eob_idct_idct_16 + 2 .endif @ Align the stack, allocate a temp buffer @@ -1070,6 +1181,15 @@ A and r7, sp, #15 vmovl.s16 q0, d0 .endif +.ifc \txfm1\()_\txfm2,idct_idct + cmp r3, #10 + ble idct16x16_quarter_add_16_neon + cmp r3, #38 + ble idct16x16_half_add_16_neon + + movrel r8, min_eob_idct_idct_16 + 2 +.endif + .irp i, 0, 2, 4, 6, 8, 10, 12, 14 add r0, sp, #(\i*64) .ifc \txfm1\()_\txfm2,idct_idct @@ -1145,6 +1265,61 @@ itxfm_func16x16 idct, iadst itxfm_func16x16 iadst, iadst .ltorg +.macro idct16_partial size +function idct16x16_\size\()_add_16_neon +.irp i, 0, 2 + add r0, sp, #(\i*64) +.ifc \size,quarter +.if \i == 2 + cmp r3, #3 + ble 1f +.endif +.endif + add r2, r6, #(\i*4) + bl idct16_1d_2x16_pass1_\size\()_neon +.endr + +.ifc \size,half +.irp i, 4, 6 + add r0, sp, #(\i*64) +.if \i == 6 + cmp r3, #22 + ble 1f +.endif + add r2, r6, #(\i*4) + bl idct16_1d_2x16_pass1_\size\()_neon +.endr +.endif + + b 3f +1: + vmov.i32 q14, #0 + vmov.i32 q15, #0 + + @ Unroll for 2 lines +.rept 2 + @ Fill one line with zeros + vst1.32 {q14-q15}, [r0,:128]! + vst1.32 {q14-q15}, [r0,:128]! +.endr + +3: + +.irp i, 0, 2, 4, 6, 8, 10, 12, 14 + add r0, r4, #(\i*2) + mov r1, r5 + add r2, sp, #(\i*4) + bl idct16_1d_2x16_pass2_\size\()_neon +.endr + + add sp, sp, r7 + vpop {q4-q5} + pop {r4-r9,pc} +endfunc +.endm + +idct16_partial quarter +idct16_partial half function idct32x32_dc_add_neon movrel r12, idct_coeffs @@ -1199,6 +1374,38 @@ function idct32x32_dc_add_neon pop {r4-r9,pc} endfunc +.macro idct32_end + butterfly d16, d9, d8, d9 @ d16 = t16a, d9 = t19a + butterfly d17, d20, d23, d20 @ d17 = t17, d20 = t18 + butterfly d18, d10, d11, d10 @ d18 = t23a, d10 = t20a + butterfly d19, d21, d22, d21 @ d19 = t22, d21 = t21 + butterfly d8, d28, d28, d30 @ d8 = t24a, d28 = t27a + butterfly d23, d26, d25, d26 @ d23 = t25, d26 = t26 + butterfly d11, d29, d29, d31 @ d11 = t31a, d29 = t28a + butterfly d22, d27, d24, d27 @ d22 = t30, d27 = t29 + + mbutterfly d27, d20, d1[0], d1[1], q12, q15 @ d27 = t18a, d20 = t29a + mbutterfly d29, d9, d1[0], d1[1], q12, q15 @ d29 = t19, d9 = t28 + mbutterfly d28, d10, d1[0], d1[1], q12, q15, neg=1 @ d28 = t27, d10 = t20 + mbutterfly d26, d21, d1[0], d1[1], q12, q15, neg=1 @ d26 = t26a, d21 = t21a + + butterfly d31, d24, d11, d8 @ d31 = t31, d24 = t24 + butterfly d30, d25, d22, d23 @ d30 = t30a, d25 = t25a + butterfly_r d23, d16, d16, d18 @ d23 = t23, d16 = t16 + butterfly_r d22, d17, d17, d19 @ d22 = t22a, d17 = t17a + butterfly d18, d21, d27, d21 @ d18 = t18, d21 = t21 + butterfly_r d27, d28, d9, d28 @ d27 = t27a, d28 = t28a + butterfly d8, d26, d20, d26 @ d8 = t29, d26 = t26 + butterfly d19, d20, d29, d10 @ d19 = t19a, d20 = t20 + vmov d29, d8 @ d29 = t29 + + mbutterfly0 d27, d20, d27, d20, d8, d10, q4, q5 @ d27 = t27, d20 = t20 + mbutterfly0 d26, d21, d26, d21, d8, d10, q4, q5 @ d26 = t26a, d21 = t21a + mbutterfly0 d25, d22, d25, d22, d8, d10, q4, q5 @ d25 = t25, d22 = t22 + mbutterfly0 d24, d23, d24, d23, d8, d10, q4, q5 @ d24 = t24a, d23 = t23a + bx lr +.endm + function idct32_odd movrel r12, idct_coeffs @@ -1239,38 +1446,102 @@ function idct32_odd mbutterfly d27, d20, d2[0], d2[1], q8, q9, neg=1 @ d27 = t29a, d20 = t18a mbutterfly d21, d26, d3[0], d3[1], q8, q9 @ d21 = t21a, d26 = t26a mbutterfly d25, d22, d3[0], d3[1], q8, q9, neg=1 @ d25 = t25a, d22 = t22a + idct32_end +endfunc - butterfly d16, d9, d8, d9 @ d16 = t16a, d9 = t19a - butterfly d17, d20, d23, d20 @ d17 = t17, d20 = t18 - butterfly d18, d10, d11, d10 @ d18 = t23a, d10 = t20a - butterfly d19, d21, d22, d21 @ d19 = t22, d21 = t21 - butterfly d8, d28, d28, d30 @ d8 = t24a, d28 = t27a - butterfly d23, d26, d25, d26 @ d23 = t25, d26 = t26 - butterfly d11, d29, d29, d31 @ d11 = t31a, d29 = t28a - butterfly d22, d27, d24, d27 @ d22 = t30, d27 = t29 +function idct32_odd_half + movrel r12, idct_coeffs - mbutterfly d27, d20, d1[0], d1[1], q12, q15 @ d27 = t18a, d20 = t29a - mbutterfly d29, d9, d1[0], d1[1], q12, q15 @ d29 = t19, d9 = t28 - mbutterfly d28, d10, d1[0], d1[1], q12, q15, neg=1 @ d28 = t27, d10 = t20 - mbutterfly d26, d21, d1[0], d1[1], q12, q15, neg=1 @ d26 = t26a, d21 = t21a + vmovl.s16 q0, d12 + vmovl.s16 q1, d13 + vmovl.s16 q2, d14 + vmovl.s16 q3, d15 - butterfly d31, d24, d11, d8 @ d31 = t31, d24 = t24 - butterfly d30, d25, d22, d23 @ d30 = t30a, d25 = t25a - butterfly_r d23, d16, d16, d18 @ d23 = t23, d16 = t16 - butterfly_r d22, d17, d17, d19 @ d22 = t22a, d17 = t17a - butterfly d18, d21, d27, d21 @ d18 = t18, d21 = t21 - butterfly_r d27, d28, d9, d28 @ d27 = t27a, d28 = t28a - butterfly d8, d26, d20, d26 @ d8 = t29, d26 = t26 - butterfly d19, d20, d29, d10 @ d19 = t19a, d20 = t20 - vmov d29, d8 @ d29 = t29 + mbutterfly_h1 d16, d31, d0[0], d0[1], q4, q5 @ d16 = t16a, d31 = t31a + mbutterfly_h2 d24, d23, d1[0], d1[1], q4, q5 @ d24 = t17a, d23 = t30a + mbutterfly_h1 d20, d27, d2[0], d2[1], q4, q5 @ d20 = t18a, d27 = t29a + mbutterfly_h2 d28, d19, d3[0], d3[1], q4, q5 @ d28 = t19a, d19 = t28a + mbutterfly_h1 d18, d29, d4[0], d4[1], q4, q5 @ d18 = t20a, d29 = t27a + mbutterfly_h2 d26, d21, d5[0], d5[1], q4, q5 @ d26 = t21a, d21 = t26a + mbutterfly_h1 d22, d25, d6[0], d6[1], q4, q5 @ d22 = t22a, d25 = t25a + mbutterfly_h2 d30, d17, d7[0], d7[1], q4, q5 @ d30 = t23a, d17 = t24a - mbutterfly0 d27, d20, d27, d20, d8, d10, q4, q5 @ d27 = t27, d20 = t20 - mbutterfly0 d26, d21, d26, d21, d8, d10, q4, q5 @ d26 = t26a, d21 = t21a - mbutterfly0 d25, d22, d25, d22, d8, d10, q4, q5 @ d25 = t25, d22 = t22 - mbutterfly0 d24, d23, d24, d23, d8, d10, q4, q5 @ d24 = t24a, d23 = t23a - bx lr + vld1.16 {q0-q1}, [r12,:128] + + butterfly d8, d24, d16, d24 @ d8 = t16, d24 = t17 + butterfly d9, d20, d28, d20 @ d9 = t19, d20 = t18 + butterfly d10, d26, d18, d26 @ d10 = t20, d26 = t21 + butterfly d11, d22, d30, d22 @ d11 = t23, d22 = t22 + vmovl.s16 q2, d2 + vmovl.s16 q3, d3 + vmovl.s16 q1, d1 + vmovl.s16 q0, d0 + butterfly d28, d25, d17, d25 @ d28 = t24, d25 = t25 + butterfly d30, d21, d29, d21 @ d30 = t27, d21 = t26 + butterfly d29, d23, d31, d23 @ d29 = t31, d23 = t30 + butterfly d31, d27, d19, d27 @ d31 = t28, d27 = t29 + + mbutterfly d23, d24, d2[0], d2[1], q8, q9 @ d23 = t17a, d24 = t30a + mbutterfly d27, d20, d2[0], d2[1], q8, q9, neg=1 @ d27 = t29a, d20 = t18a + mbutterfly d21, d26, d3[0], d3[1], q8, q9 @ d21 = t21a, d26 = t26a + mbutterfly d25, d22, d3[0], d3[1], q8, q9, neg=1 @ d25 = t25a, d22 = t22a + idct32_end +endfunc + +function idct32_odd_quarter + movrel r12, idct_coeffs + + vmovl.s16 q0, d12 + vmovl.s16 q1, d13 + vmovl.s16 q2, d14 + vmovl.s16 q3, d15 + + vmov.s64 q14, #0 + vmov.s64 q5, #0 + + vmull.s32 q4, d16, d0[0] + vmlsl.s32 q14, d19, d3[1] + vmull.s32 q15, d16, d0[1] + vmull.s32 q11, d17, d7[0] + vmlsl.s32 q5, d17, d7[1] + vmull.s32 q13, d19, d3[0] + vmull.s32 q10, d18, d4[0] + vmull.s32 q12, d18, d4[1] + + vld1.16 {q0-q1}, [r12,:128] + + vrshrn.s64 d8, q4, #14 + vrshrn.s64 d9, q14, #14 + vrshrn.s64 d29, q15, #14 + vrshrn.s64 d28, q11, #14 + + vmovl.s16 q2, d2 + vmovl.s16 q3, d3 + vmovl.s16 q1, d1 + vmovl.s16 q0, d0 + + vrshrn.s64 d11, q5, #14 + vrshrn.s64 d31, q13, #14 + vrshrn.s64 d10, q10, #14 + vrshrn.s64 d30, q12, #14 + + mbutterfly_l q8, q9, d29, d8, d2[0], d2[1] + mbutterfly_l q13, q10, d31, d9, d2[0], d2[1], neg=1 + vrshrn.s64 d23, q8, #14 + vrshrn.s64 d24, q9, #14 + vrshrn.s64 d27, q13, #14 + vrshrn.s64 d20, q10, #14 + mbutterfly_l q8, q9, d30, d10, d3[0], d3[1] + vrshrn.s64 d21, q8, #14 + vrshrn.s64 d26, q9, #14 + mbutterfly_l q8, q9, d28, d11, d3[0], d3[1], neg=1 + vrshrn.s64 d25, q8, #14 + vrshrn.s64 d22, q9, #14 + + idct32_end endfunc +.macro idct32_funcs suffix @ Do an 32-point IDCT of a 2x32 slice out of a 32x32 matrix. @ We don't have register space to do a single pass IDCT of 2x32 though, @ but the 32-point IDCT can be decomposed into two 16-point IDCTs; @@ -1280,7 +1551,7 @@ endfunc @ r0 = dst (temp buffer) @ r1 = unused @ r2 = src -function idct32_1d_2x32_pass1_neon +function idct32_1d_2x32_pass1\suffix\()_neon push {lr} @ Double stride of the input, since we only read every other line @@ -1288,12 +1559,26 @@ function idct32_1d_2x32_pass1_neon vmov.s32 d8, #0 @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vld1.32 {d\i}, [r2,:64] vst1.32 {d8}, [r2,:64], r12 .endr +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + vld1.32 {d\i}, [r2,:64] + vst1.32 {d8}, [r2,:64], r12 +.endr +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + vld1.32 {d\i}, [r2,:64] + vst1.32 {d8}, [r2,:64], r12 +.endr +.endif - bl idct16 + bl idct16\suffix @ Do eight 2x2 transposes. Originally, d16-d31 contain the @ 16 rows. Afterwards, d16-d17, d18-d19 etc contain the eight @@ -1318,17 +1603,39 @@ function idct32_1d_2x32_pass1_neon @ Move r2 back to the start of the input, and move @ to the first odd row +.ifb \suffix sub r2, r2, r12, lsl #4 +.endif +.ifc \suffix,_quarter + sub r2, r2, r12, lsl #2 +.endif +.ifc \suffix,_half + sub r2, r2, r12, lsl #3 +.endif add r2, r2, #128 vmov.s32 d8, #0 @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vld1.16 {d\i}, [r2,:64] vst1.16 {d8}, [r2,:64], r12 .endr +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + vld1.16 {d\i}, [r2,:64] + vst1.16 {d8}, [r2,:64], r12 +.endr +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + vld1.16 {d\i}, [r2,:64] + vst1.16 {d8}, [r2,:64], r12 +.endr +.endif - bl idct32_odd + bl idct32_odd\suffix transpose32_8x_2x2 d31, d30, d29, d28, d27, d26, d25, d24, d23, d22, d21, d20, d19, d18, d17, d16 @@ -1362,17 +1669,31 @@ endfunc @ r0 = dst @ r1 = dst stride @ r2 = src (temp buffer) -function idct32_1d_2x32_pass2_neon +function idct32_1d_2x32_pass2\suffix\()_neon push {lr} mov r12, #256 @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vld1.32 {d\i}, [r2,:64], r12 .endr sub r2, r2, r12, lsl #4 +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + vld1.32 {d\i}, [r2,:64], r12 +.endr + sub r2, r2, r12, lsl #2 +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + vld1.32 {d\i}, [r2,:64], r12 +.endr + sub r2, r2, r12, lsl #3 +.endif - bl idct16 + bl idct16\suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vst1.32 {d\i}, [r2,:64], r12 @@ -1382,13 +1703,27 @@ function idct32_1d_2x32_pass2_neon add r2, r2, #128 @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 vld1.32 {d\i}, [r2,:64], r12 .endr sub r2, r2, r12, lsl #4 +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + vld1.32 {d\i}, [r2,:64], r12 +.endr + sub r2, r2, r12, lsl #2 +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + vld1.32 {d\i}, [r2,:64], r12 +.endr + sub r2, r2, r12, lsl #3 +.endif sub r2, r2, #128 - bl idct32_odd + bl idct32_odd\suffix @ Narrow the ict16 coefficients in q0-q3 into q0-q1, to @ allow clobbering q2-q3 below. @@ -1452,6 +1787,11 @@ function idct32_1d_2x32_pass2_neon vmovl.s16 q0, d0 pop {pc} endfunc +.endm + +idct32_funcs +idct32_funcs _quarter +idct32_funcs _half const min_eob_idct_idct_32, align=4 .short 0, 3, 9, 21, 34, 51, 70, 98, 135, 176, 240, 258, 336, 357, 448, 472 @@ -1482,6 +1822,11 @@ A and r7, sp, #15 vmovl.s16 q1, d1 vmovl.s16 q0, d0 + cmp r3, #34 + ble idct32x32_quarter_add_16_neon + cmp r3, #135 + ble idct32x32_half_add_16_neon + .irp i, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 add r0, sp, #(\i*128) .if \i > 0 @@ -1534,3 +1879,67 @@ function ff_vp9_idct_idct_32x32_add_12_neon, export=1 movw r9, #0x0fff b vp9_idct_idct_32x32_add_16_neon endfunc + +.macro idct32_partial size, rows +function idct32x32_\size\()_add_16_neon +.irp i, 0, 2, 4, 6 + add r0, sp, #(\i*128) +.ifc \size,quarter +.if \i > 0 + ldrh_post r1, r8, #2 + cmp r3, r1 + it le + movle r1, #(\rows - \i)/2 + ble 1f +.endif +.endif + add r2, r6, #(\i*4) + bl idct32_1d_2x32_pass1_\size\()_neon +.endr +.ifc \size,half + add r8, r8, #8 +.irp i, 8, 10, 12, 14 + add r0, sp, #(\i*128) +.if \i > 8 + ldrh_post r1, r8, #2 + cmp r3, r1 + it le + movle r1, #(\rows - \i)/2 + ble 1f +.endif + add r2, r6, #(\i*4) + bl idct32_1d_2x32_pass1_\size\()_neon +.endr +.endif + b 3f + +1: + @ Write zeros to the temp buffer for pass 2 + vmov.i16 q14, #0 + vmov.i16 q15, #0 +2: + subs r1, r1, #1 +.rept 2 + @ Fill one line with zeros + vst1.16 {q14-q15}, [r0,:128]! + vst1.16 {q14-q15}, [r0,:128]! + vst1.16 {q14-q15}, [r0,:128]! + vst1.16 {q14-q15}, [r0,:128]! +.endr + bne 2b +3: +.irp i, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 + add r0, r4, #(\i*2) + mov r1, r5 + add r2, sp, #(\i*4) + bl idct32_1d_2x32_pass2_\size\()_neon +.endr + + add sp, sp, r7 + vpop {q4-q7} + pop {r4-r9,pc} +endfunc +.endm + +idct32_partial quarter, 8 +idct32_partial half, 16 From 61b8a9ea2930130a1fecf6c06a391a18d8b95d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 26 Feb 2017 00:38:48 +0200 Subject: [PATCH 1205/3374] aarch64: vp9itxfm16: Do a simpler half/quarter idct16/idct32 when possible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This work is sponsored by, and copyright, Google. This avoids loading and calculating coefficients that we know will be zero, and avoids filling the temp buffer with zeros in places where we know the second pass won't read. This gives a pretty substantial speedup for the smaller subpartitions. The code size increases from 21512 bytes to 31400 bytes. The idct16/32_end macros are moved above the individual functions; the instructions themselves are unchanged, but since new functions are added at the same place where the code is moved from, the diff looks rather messy. Before: vp9_inv_dct_dct_16x16_sub1_add_10_neon: 284.6 vp9_inv_dct_dct_16x16_sub2_add_10_neon: 1902.7 vp9_inv_dct_dct_16x16_sub4_add_10_neon: 1903.0 vp9_inv_dct_dct_16x16_sub8_add_10_neon: 2201.1 vp9_inv_dct_dct_16x16_sub12_add_10_neon: 2510.0 vp9_inv_dct_dct_16x16_sub16_add_10_neon: 2821.3 vp9_inv_dct_dct_32x32_sub1_add_10_neon: 1011.6 vp9_inv_dct_dct_32x32_sub2_add_10_neon: 9716.5 vp9_inv_dct_dct_32x32_sub4_add_10_neon: 9704.9 vp9_inv_dct_dct_32x32_sub8_add_10_neon: 10641.7 vp9_inv_dct_dct_32x32_sub12_add_10_neon: 11555.7 vp9_inv_dct_dct_32x32_sub16_add_10_neon: 12499.8 vp9_inv_dct_dct_32x32_sub20_add_10_neon: 13403.7 vp9_inv_dct_dct_32x32_sub24_add_10_neon: 14335.8 vp9_inv_dct_dct_32x32_sub28_add_10_neon: 15253.6 vp9_inv_dct_dct_32x32_sub32_add_10_neon: 16179.5 After: vp9_inv_dct_dct_16x16_sub1_add_10_neon: 282.8 vp9_inv_dct_dct_16x16_sub2_add_10_neon: 1142.4 vp9_inv_dct_dct_16x16_sub4_add_10_neon: 1139.0 vp9_inv_dct_dct_16x16_sub8_add_10_neon: 1772.9 vp9_inv_dct_dct_16x16_sub12_add_10_neon: 2515.2 vp9_inv_dct_dct_16x16_sub16_add_10_neon: 2823.5 vp9_inv_dct_dct_32x32_sub1_add_10_neon: 1012.7 vp9_inv_dct_dct_32x32_sub2_add_10_neon: 6944.4 vp9_inv_dct_dct_32x32_sub4_add_10_neon: 6944.2 vp9_inv_dct_dct_32x32_sub8_add_10_neon: 7609.8 vp9_inv_dct_dct_32x32_sub12_add_10_neon: 9953.4 vp9_inv_dct_dct_32x32_sub16_add_10_neon: 10770.1 vp9_inv_dct_dct_32x32_sub20_add_10_neon: 13418.8 vp9_inv_dct_dct_32x32_sub24_add_10_neon: 14330.7 vp9_inv_dct_dct_32x32_sub28_add_10_neon: 15257.1 vp9_inv_dct_dct_32x32_sub32_add_10_neon: 16190.6 Signed-off-by: Martin Storsjö --- libavcodec/aarch64/vp9itxfm_16bpp_neon.S | 605 ++++++++++++++++++++--- 1 file changed, 547 insertions(+), 58 deletions(-) diff --git a/libavcodec/aarch64/vp9itxfm_16bpp_neon.S b/libavcodec/aarch64/vp9itxfm_16bpp_neon.S index f30fdd868987c..0befe383df3e1 100644 --- a/libavcodec/aarch64/vp9itxfm_16bpp_neon.S +++ b/libavcodec/aarch64/vp9itxfm_16bpp_neon.S @@ -124,6 +124,17 @@ endconst .endif .endm +// Same as dmbutterfly0 above, but treating the input in in2 as zero, +// writing the same output into both out1 and out2. +.macro dmbutterfly0_h out1, out2, in1, in2, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6 + smull \tmp1\().2d, \in1\().2s, v0.s[0] + smull2 \tmp2\().2d, \in1\().4s, v0.s[0] + rshrn \out1\().2s, \tmp1\().2d, #14 + rshrn2 \out1\().4s, \tmp2\().2d, #14 + rshrn \out2\().2s, \tmp1\().2d, #14 + rshrn2 \out2\().4s, \tmp2\().2d, #14 +.endm + // out1,out2 = in1 * coef1 - in2 * coef2 // out3,out4 = in1 * coef2 + in2 * coef1 // out are 4 x .2d registers, in are 2 x .4s registers @@ -153,6 +164,43 @@ endconst rshrn2 \inout2\().4s, \tmp4\().2d, #14 .endm +// Same as dmbutterfly above, but treating the input in inout2 as zero +.macro dmbutterfly_h1 inout1, inout2, coef1, coef2, tmp1, tmp2, tmp3, tmp4 + smull \tmp1\().2d, \inout1\().2s, \coef1 + smull2 \tmp2\().2d, \inout1\().4s, \coef1 + smull \tmp3\().2d, \inout1\().2s, \coef2 + smull2 \tmp4\().2d, \inout1\().4s, \coef2 + rshrn \inout1\().2s, \tmp1\().2d, #14 + rshrn2 \inout1\().4s, \tmp2\().2d, #14 + rshrn \inout2\().2s, \tmp3\().2d, #14 + rshrn2 \inout2\().4s, \tmp4\().2d, #14 +.endm + +// Same as dmbutterfly above, but treating the input in inout1 as zero +.macro dmbutterfly_h2 inout1, inout2, coef1, coef2, tmp1, tmp2, tmp3, tmp4 + smull \tmp1\().2d, \inout2\().2s, \coef2 + smull2 \tmp2\().2d, \inout2\().4s, \coef2 + smull \tmp3\().2d, \inout2\().2s, \coef1 + smull2 \tmp4\().2d, \inout2\().4s, \coef1 + neg \tmp1\().2d, \tmp1\().2d + neg \tmp2\().2d, \tmp2\().2d + rshrn \inout2\().2s, \tmp3\().2d, #14 + rshrn2 \inout2\().4s, \tmp4\().2d, #14 + rshrn \inout1\().2s, \tmp1\().2d, #14 + rshrn2 \inout1\().4s, \tmp2\().2d, #14 +.endm + +.macro dsmull_h out1, out2, in, coef + smull \out1\().2d, \in\().2s, \coef + smull2 \out2\().2d, \in\().4s, \coef +.endm + +.macro drshrn_h out, in1, in2, shift + rshrn \out\().2s, \in1\().2d, \shift + rshrn2 \out\().4s, \in2\().2d, \shift +.endm + + // out1 = in1 + in2 // out2 = in1 - in2 .macro butterfly_4s out1, out2, in1, in2 @@ -710,6 +758,30 @@ function idct16x16_dc_add_neon ret endfunc +.macro idct16_end + butterfly_4s v18, v7, v4, v7 // v18 = t0a, v7 = t7a + butterfly_4s v19, v22, v5, v22 // v19 = t1a, v22 = t6 + butterfly_4s v4, v26, v20, v26 // v4 = t2a, v26 = t5 + butterfly_4s v5, v6, v28, v6 // v5 = t3a, v6 = t4 + butterfly_4s v20, v28, v16, v24 // v20 = t8a, v28 = t11a + butterfly_4s v24, v21, v23, v21 // v24 = t9, v21 = t10 + butterfly_4s v23, v27, v25, v27 // v23 = t14, v27 = t13 + butterfly_4s v25, v29, v29, v17 // v25 = t15a, v29 = t12a + + dmbutterfly0 v8, v9, v27, v21, v8, v9, v16, v17, v30, v31 // v8 = t13a, v9 = t10a + dmbutterfly0 v28, v27, v29, v28, v21, v29, v16, v17, v30, v31 // v28 = t12, v27 = t11 + + butterfly_4s v16, v31, v18, v25 // v16 = out[0], v31 = out[15] + butterfly_4s v17, v30, v19, v23 // v17 = out[1], v30 = out[14] + butterfly_4s_r v25, v22, v22, v24 // v25 = out[9], v22 = out[6] + butterfly_4s v23, v24, v7, v20 // v23 = out[7], v24 = out[8] + butterfly_4s v18, v29, v4, v8 // v18 = out[2], v29 = out[13] + butterfly_4s v19, v28, v5, v28 // v19 = out[3], v28 = out[12] + butterfly_4s v20, v27, v6, v27 // v20 = out[4], v27 = out[11] + butterfly_4s v21, v26, v26, v9 // v21 = out[5], v26 = out[10] + ret +.endm + function idct16 dmbutterfly0 v16, v24, v16, v24, v4, v5, v6, v7, v8, v9 // v16 = t0a, v24 = t1a dmbutterfly v20, v28, v0.s[2], v0.s[3], v4, v5, v6, v7 // v20 = t2a, v28 = t3a @@ -732,28 +804,65 @@ function idct16 dmbutterfly0 v22, v26, v22, v26, v8, v9, v18, v19, v30, v31 // v22 = t6a, v26 = t5a dmbutterfly v23, v25, v0.s[2], v0.s[3], v18, v19, v30, v31 // v23 = t9a, v25 = t14a dmbutterfly v27, v21, v0.s[2], v0.s[3], v18, v19, v30, v31, neg=1 // v27 = t13a, v21 = t10a + idct16_end +endfunc - butterfly_4s v18, v7, v4, v7 // v18 = t0a, v7 = t7a - butterfly_4s v19, v22, v5, v22 // v19 = t1a, v22 = t6 - butterfly_4s v4, v26, v20, v26 // v4 = t2a, v26 = t5 - butterfly_4s v5, v6, v28, v6 // v5 = t3a, v6 = t4 - butterfly_4s v20, v28, v16, v24 // v20 = t8a, v28 = t11a - butterfly_4s v24, v21, v23, v21 // v24 = t9, v21 = t10 - butterfly_4s v23, v27, v25, v27 // v23 = t14, v27 = t13 - butterfly_4s v25, v29, v29, v17 // v25 = t15a, v29 = t12a +function idct16_half + dmbutterfly0_h v16, v24, v16, v24, v4, v5, v6, v7, v8, v9 // v16 = t0a, v24 = t1a + dmbutterfly_h1 v20, v28, v0.s[2], v0.s[3], v4, v5, v6, v7 // v20 = t2a, v28 = t3a + dmbutterfly_h1 v18, v30, v1.s[0], v1.s[1], v4, v5, v6, v7 // v18 = t4a, v30 = t7a + dmbutterfly_h2 v26, v22, v1.s[2], v1.s[3], v4, v5, v6, v7 // v26 = t5a, v22 = t6a + dmbutterfly_h1 v17, v31, v2.s[0], v2.s[1], v4, v5, v6, v7 // v17 = t8a, v31 = t15a + dmbutterfly_h2 v25, v23, v2.s[2], v2.s[3], v4, v5, v6, v7 // v25 = t9a, v23 = t14a + dmbutterfly_h1 v21, v27, v3.s[0], v3.s[1], v4, v5, v6, v7 // v21 = t10a, v27 = t13a + dmbutterfly_h2 v29, v19, v3.s[2], v3.s[3], v4, v5, v6, v7 // v29 = t11a, v19 = t12a - dmbutterfly0 v8, v9, v27, v21, v8, v9, v16, v17, v30, v31 // v8 = t13a, v9 = t10a - dmbutterfly0 v28, v27, v29, v28, v21, v29, v16, v17, v30, v31 // v28 = t12, v27 = t11 + butterfly_4s v4, v28, v16, v28 // v4 = t0, v28 = t3 + butterfly_4s v5, v20, v24, v20 // v5 = t1, v20 = t2 + butterfly_4s v6, v26, v18, v26 // v6 = t4, v26 = t5 + butterfly_4s v7, v22, v30, v22 // v7 = t7, v22 = t6 + butterfly_4s v16, v25, v17, v25 // v16 = t8, v25 = t9 + butterfly_4s v24, v21, v29, v21 // v24 = t11, v21 = t10 + butterfly_4s v17, v27, v19, v27 // v17 = t12, v27 = t13 + butterfly_4s v29, v23, v31, v23 // v29 = t15, v23 = t14 - butterfly_4s v16, v31, v18, v25 // v16 = out[0], v31 = out[15] - butterfly_4s v17, v30, v19, v23 // v17 = out[1], v30 = out[14] - butterfly_4s_r v25, v22, v22, v24 // v25 = out[9], v22 = out[6] - butterfly_4s v23, v24, v7, v20 // v23 = out[7], v24 = out[8] - butterfly_4s v18, v29, v4, v8 // v18 = out[2], v29 = out[13] - butterfly_4s v19, v28, v5, v28 // v19 = out[3], v28 = out[12] - butterfly_4s v20, v27, v6, v27 // v20 = out[4], v27 = out[11] - butterfly_4s v21, v26, v26, v9 // v21 = out[5], v26 = out[10] - ret + dmbutterfly0 v22, v26, v22, v26, v8, v9, v18, v19, v30, v31 // v22 = t6a, v26 = t5a + dmbutterfly v23, v25, v0.s[2], v0.s[3], v18, v19, v30, v31 // v23 = t9a, v25 = t14a + dmbutterfly v27, v21, v0.s[2], v0.s[3], v18, v19, v30, v31, neg=1 // v27 = t13a, v21 = t10a + idct16_end +endfunc + +function idct16_quarter + dsmull_h v24, v25, v19, v3.s[3] + dsmull_h v4, v5, v17, v2.s[0] + dsmull_h v7, v6, v18, v1.s[1] + dsmull_h v30, v31, v18, v1.s[0] + neg v24.2d, v24.2d + neg v25.2d, v25.2d + dsmull_h v29, v28, v17, v2.s[1] + dsmull_h v26, v27, v19, v3.s[2] + dsmull_h v22, v23, v16, v0.s[0] + drshrn_h v24, v24, v25, #14 + drshrn_h v16, v4, v5, #14 + drshrn_h v7, v7, v6, #14 + drshrn_h v6, v30, v31, #14 + drshrn_h v29, v29, v28, #14 + drshrn_h v17, v26, v27, #14 + drshrn_h v28, v22, v23, #14 + + dmbutterfly_l v20, v21, v22, v23, v17, v24, v0.s[2], v0.s[3] + dmbutterfly_l v18, v19, v30, v31, v29, v16, v0.s[2], v0.s[3] + neg v22.2d, v22.2d + neg v23.2d, v23.2d + drshrn_h v27, v20, v21, #14 + drshrn_h v21, v22, v23, #14 + drshrn_h v23, v18, v19, #14 + drshrn_h v25, v30, v31, #14 + mov v4.16b, v28.16b + mov v5.16b, v28.16b + dmbutterfly0 v22, v26, v7, v6, v18, v19, v30, v31 + mov v20.16b, v28.16b + idct16_end endfunc function iadst16 @@ -1026,7 +1135,6 @@ function vp9_\txfm1\()_\txfm2\()_16x16_add_16_neon .ifnc \txfm1\()_\txfm2,idct_idct movrel x11, iadst16_coeffs .endif - movrel x12, min_eob_idct_idct_16, 2 .ifc \txfm1,idct ld1 {v0.8h,v1.8h}, [x10] sxtl v2.4s, v1.4h @@ -1036,6 +1144,15 @@ function vp9_\txfm1\()_\txfm2\()_16x16_add_16_neon .endif mov x9, #64 +.ifc \txfm1\()_\txfm2,idct_idct + cmp w3, #10 + b.le idct16x16_quarter_add_16_neon + cmp w3, #38 + b.le idct16x16_half_add_16_neon + + movrel x12, min_eob_idct_idct_16, 2 +.endif + .irp i, 0, 4, 8, 12 add x0, sp, #(\i*64) .ifc \txfm1\()_\txfm2,idct_idct @@ -1110,6 +1227,175 @@ itxfm_func16x16 iadst, idct itxfm_func16x16 idct, iadst itxfm_func16x16 iadst, iadst +function idct16_1d_4x16_pass1_quarter_neon + mov x14, x30 + + movi v4.4s, #0 +.irp i, 16, 17, 18, 19 + load_clear \i, x2, x9 +.endr + + bl idct16_quarter + + // Do four 4x4 transposes. Originally, v16-v31 contain the + // 16 rows. Afterwards, v16-v19, v20-v23, v24-v27 and v28-v31 + // contain the four transposed 4x4 blocks. + transpose_4x4s v16, v17, v18, v19, v4, v5, v6, v7 + transpose_4x4s v20, v21, v22, v23, v4, v5, v6, v7 + transpose_4x4s v24, v25, v26, v27, v4, v5, v6, v7 + transpose_4x4s v28, v29, v30, v31, v4, v5, v6, v7 + + // Store the transposed 4x4 blocks horizontally. + // The first 4x4 block is kept in registers for the second pass, + // store the rest in the temp buffer. + add x0, x0, #16 + st1 {v20.4s}, [x0], #16 + st1 {v24.4s}, [x0], #16 + st1 {v28.4s}, [x0], #16 + add x0, x0, #16 + st1 {v21.4s}, [x0], #16 + st1 {v25.4s}, [x0], #16 + st1 {v29.4s}, [x0], #16 + add x0, x0, #16 + st1 {v22.4s}, [x0], #16 + st1 {v26.4s}, [x0], #16 + st1 {v30.4s}, [x0], #16 + add x0, x0, #16 + st1 {v23.4s}, [x0], #16 + st1 {v27.4s}, [x0], #16 + st1 {v31.4s}, [x0], #16 + br x14 +endfunc + +function idct16_1d_4x16_pass2_quarter_neon + mov x14, x30 + + // Only load the top 4 lines, and only do it for the later slices. + // For the first slice, d16-d19 is kept in registers from the first pass. + cbz x3, 1f +.irp i, 16, 17, 18, 19 + load \i, x2, x9 +.endr +1: + + add x3, x0, x1 + lsl x1, x1, #1 + bl idct16_quarter + + dup v8.8h, w13 + load_add_store v16.4s, v17.4s, v18.4s, v19.4s, v20.4s, v21.4s, v22.4s, v23.4s + load_add_store v24.4s, v25.4s, v26.4s, v27.4s, v28.4s, v29.4s, v30.4s, v31.4s + + br x14 +endfunc + +function idct16_1d_4x16_pass1_half_neon + mov x14, x30 + + movi v4.4s, #0 +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + load_clear \i, x2, x9 +.endr + + bl idct16_half + + // Do four 4x4 transposes. Originally, v16-v31 contain the + // 16 rows. Afterwards, v16-v19, v20-v23, v24-v27 and v28-v31 + // contain the four transposed 4x4 blocks. + transpose_4x4s v16, v17, v18, v19, v4, v5, v6, v7 + transpose_4x4s v20, v21, v22, v23, v4, v5, v6, v7 + transpose_4x4s v24, v25, v26, v27, v4, v5, v6, v7 + transpose_4x4s v28, v29, v30, v31, v4, v5, v6, v7 + + // Store the transposed 4x4 blocks horizontally. + cmp x1, #4 + b.eq 1f +.irp i, 16, 20, 24, 28, 17, 21, 25, 29, 18, 22, 26, 30, 19, 23, 27, 31 + store \i, x0, #16 +.endr + br x14 +1: + // Special case: For the second input column (r1 == 4), + // which would be stored as the second row in the temp buffer, + // don't store the first 4x4 block, but keep it in registers + // for the first slice of the second pass (where it is the + // second 4x4 block). + add x0, x0, #16 + st1 {v20.4s}, [x0], #16 + st1 {v24.4s}, [x0], #16 + st1 {v28.4s}, [x0], #16 + add x0, x0, #16 + st1 {v21.4s}, [x0], #16 + st1 {v25.4s}, [x0], #16 + st1 {v29.4s}, [x0], #16 + add x0, x0, #16 + st1 {v22.4s}, [x0], #16 + st1 {v26.4s}, [x0], #16 + st1 {v30.4s}, [x0], #16 + add x0, x0, #16 + st1 {v23.4s}, [x0], #16 + st1 {v27.4s}, [x0], #16 + st1 {v31.4s}, [x0], #16 + + mov v20.16b, v16.16b + mov v21.16b, v17.16b + mov v22.16b, v18.16b + mov v23.16b, v19.16b + br x14 +endfunc + +function idct16_1d_4x16_pass2_half_neon + mov x14, x30 + +.irp i, 16, 17, 18, 19 + load \i, x2, x9 +.endr + cbz x3, 1f +.irp i, 20, 21, 22, 23 + load \i, x2, x9 +.endr +1: + + add x3, x0, x1 + lsl x1, x1, #1 + bl idct16_half + + dup v8.8h, w13 + load_add_store v16.4s, v17.4s, v18.4s, v19.4s, v20.4s, v21.4s, v22.4s, v23.4s + load_add_store v24.4s, v25.4s, v26.4s, v27.4s, v28.4s, v29.4s, v30.4s, v31.4s + + br x14 +endfunc + +.macro idct16_partial size +function idct16x16_\size\()_add_16_neon + add x0, sp, #(0*64) + mov x1, #0 + add x2, x6, #(0*4) + bl idct16_1d_4x16_pass1_\size\()_neon +.ifc \size,half + add x0, sp, #(4*64) + mov x1, #4 + add x2, x6, #(4*4) + bl idct16_1d_4x16_pass1_\size\()_neon +.endif + +.irp i, 0, 4, 8, 12 + add x0, x4, #(\i*2) + mov x1, x5 + add x2, sp, #(\i*4) + mov x3, #\i + bl idct16_1d_4x16_pass2_\size\()_neon +.endr + + add sp, sp, #1024 + ldp d8, d9, [sp], 0x10 + br x15 +endfunc +.endm + +idct16_partial quarter +idct16_partial half function idct32x32_dc_add_neon movrel x4, idct_coeffs @@ -1164,30 +1450,7 @@ function idct32x32_dc_add_neon ret endfunc -function idct32_odd - dmbutterfly v16, v31, v10.s[0], v10.s[1], v4, v5, v6, v7 // v16 = t16a, v31 = t31a - dmbutterfly v24, v23, v10.s[2], v10.s[3], v4, v5, v6, v7 // v24 = t17a, v23 = t30a - dmbutterfly v20, v27, v11.s[0], v11.s[1], v4, v5, v6, v7 // v20 = t18a, v27 = t29a - dmbutterfly v28, v19, v11.s[2], v11.s[3], v4, v5, v6, v7 // v28 = t19a, v19 = t28a - dmbutterfly v18, v29, v12.s[0], v12.s[1], v4, v5, v6, v7 // v18 = t20a, v29 = t27a - dmbutterfly v26, v21, v12.s[2], v12.s[3], v4, v5, v6, v7 // v26 = t21a, v21 = t26a - dmbutterfly v22, v25, v13.s[0], v13.s[1], v4, v5, v6, v7 // v22 = t22a, v25 = t25a - dmbutterfly v30, v17, v13.s[2], v13.s[3], v4, v5, v6, v7 // v30 = t23a, v17 = t24a - - butterfly_4s v4, v24, v16, v24 // v4 = t16, v24 = t17 - butterfly_4s v5, v20, v28, v20 // v5 = t19, v20 = t18 - butterfly_4s v6, v26, v18, v26 // v6 = t20, v26 = t21 - butterfly_4s v7, v22, v30, v22 // v7 = t23, v22 = t22 - butterfly_4s v28, v25, v17, v25 // v28 = t24, v25 = t25 - butterfly_4s v30, v21, v29, v21 // v30 = t27, v21 = t26 - butterfly_4s v29, v23, v31, v23 // v29 = t31, v23 = t30 - butterfly_4s v31, v27, v19, v27 // v31 = t28, v27 = t29 - - dmbutterfly v23, v24, v1.s[0], v1.s[1], v16, v17, v18, v19 // v23 = t17a, v24 = t30a - dmbutterfly v27, v20, v1.s[0], v1.s[1], v16, v17, v18, v19, neg=1 // v27 = t29a, v20 = t18a - dmbutterfly v21, v26, v1.s[2], v1.s[3], v16, v17, v18, v19 // v21 = t21a, v26 = t26a - dmbutterfly v25, v22, v1.s[2], v1.s[3], v16, v17, v18, v19, neg=1 // v25 = t25a, v22 = t22a - +.macro idct32_end butterfly_4s v16, v5, v4, v5 // v16 = t16a, v5 = t19a butterfly_4s v17, v20, v23, v20 // v17 = t17, v20 = t18 butterfly_4s v18, v6, v7, v6 // v18 = t23a, v6 = t20a @@ -1216,8 +1479,105 @@ function idct32_odd dmbutterfly0 v25, v22, v25, v22, v4, v5, v6, v7, v8, v9 // v25 = t25, v22 = t22 dmbutterfly0 v24, v23, v24, v23, v4, v5, v6, v7, v8, v9 // v24 = t24a, v23 = t23a ret +.endm + +function idct32_odd + dmbutterfly v16, v31, v10.s[0], v10.s[1], v4, v5, v6, v7 // v16 = t16a, v31 = t31a + dmbutterfly v24, v23, v10.s[2], v10.s[3], v4, v5, v6, v7 // v24 = t17a, v23 = t30a + dmbutterfly v20, v27, v11.s[0], v11.s[1], v4, v5, v6, v7 // v20 = t18a, v27 = t29a + dmbutterfly v28, v19, v11.s[2], v11.s[3], v4, v5, v6, v7 // v28 = t19a, v19 = t28a + dmbutterfly v18, v29, v12.s[0], v12.s[1], v4, v5, v6, v7 // v18 = t20a, v29 = t27a + dmbutterfly v26, v21, v12.s[2], v12.s[3], v4, v5, v6, v7 // v26 = t21a, v21 = t26a + dmbutterfly v22, v25, v13.s[0], v13.s[1], v4, v5, v6, v7 // v22 = t22a, v25 = t25a + dmbutterfly v30, v17, v13.s[2], v13.s[3], v4, v5, v6, v7 // v30 = t23a, v17 = t24a + + butterfly_4s v4, v24, v16, v24 // v4 = t16, v24 = t17 + butterfly_4s v5, v20, v28, v20 // v5 = t19, v20 = t18 + butterfly_4s v6, v26, v18, v26 // v6 = t20, v26 = t21 + butterfly_4s v7, v22, v30, v22 // v7 = t23, v22 = t22 + butterfly_4s v28, v25, v17, v25 // v28 = t24, v25 = t25 + butterfly_4s v30, v21, v29, v21 // v30 = t27, v21 = t26 + butterfly_4s v29, v23, v31, v23 // v29 = t31, v23 = t30 + butterfly_4s v31, v27, v19, v27 // v31 = t28, v27 = t29 + + dmbutterfly v23, v24, v1.s[0], v1.s[1], v16, v17, v18, v19 // v23 = t17a, v24 = t30a + dmbutterfly v27, v20, v1.s[0], v1.s[1], v16, v17, v18, v19, neg=1 // v27 = t29a, v20 = t18a + dmbutterfly v21, v26, v1.s[2], v1.s[3], v16, v17, v18, v19 // v21 = t21a, v26 = t26a + dmbutterfly v25, v22, v1.s[2], v1.s[3], v16, v17, v18, v19, neg=1 // v25 = t25a, v22 = t22a + idct32_end +endfunc + +function idct32_odd_half + dmbutterfly_h1 v16, v31, v10.s[0], v10.s[1], v4, v5, v6, v7 // v16 = t16a, v31 = t31a + dmbutterfly_h2 v24, v23, v10.s[2], v10.s[3], v4, v5, v6, v7 // v24 = t17a, v23 = t30a + dmbutterfly_h1 v20, v27, v11.s[0], v11.s[1], v4, v5, v6, v7 // v20 = t18a, v27 = t29a + dmbutterfly_h2 v28, v19, v11.s[2], v11.s[3], v4, v5, v6, v7 // v28 = t19a, v19 = t28a + dmbutterfly_h1 v18, v29, v12.s[0], v12.s[1], v4, v5, v6, v7 // v18 = t20a, v29 = t27a + dmbutterfly_h2 v26, v21, v12.s[2], v12.s[3], v4, v5, v6, v7 // v26 = t21a, v21 = t26a + dmbutterfly_h1 v22, v25, v13.s[0], v13.s[1], v4, v5, v6, v7 // v22 = t22a, v25 = t25a + dmbutterfly_h2 v30, v17, v13.s[2], v13.s[3], v4, v5, v6, v7 // v30 = t23a, v17 = t24a + + butterfly_4s v4, v24, v16, v24 // v4 = t16, v24 = t17 + butterfly_4s v5, v20, v28, v20 // v5 = t19, v20 = t18 + butterfly_4s v6, v26, v18, v26 // v6 = t20, v26 = t21 + butterfly_4s v7, v22, v30, v22 // v7 = t23, v22 = t22 + butterfly_4s v28, v25, v17, v25 // v28 = t24, v25 = t25 + butterfly_4s v30, v21, v29, v21 // v30 = t27, v21 = t26 + butterfly_4s v29, v23, v31, v23 // v29 = t31, v23 = t30 + butterfly_4s v31, v27, v19, v27 // v31 = t28, v27 = t29 + + dmbutterfly v23, v24, v1.s[0], v1.s[1], v16, v17, v18, v19 // v23 = t17a, v24 = t30a + dmbutterfly v27, v20, v1.s[0], v1.s[1], v16, v17, v18, v19, neg=1 // v27 = t29a, v20 = t18a + dmbutterfly v21, v26, v1.s[2], v1.s[3], v16, v17, v18, v19 // v21 = t21a, v26 = t26a + dmbutterfly v25, v22, v1.s[2], v1.s[3], v16, v17, v18, v19, neg=1 // v25 = t25a, v22 = t22a + idct32_end +endfunc + +function idct32_odd_quarter + dsmull_h v4, v5, v16, v10.s[0] + dsmull_h v28, v29, v19, v11.s[3] + dsmull_h v30, v31, v16, v10.s[1] + dsmull_h v22, v23, v17, v13.s[2] + dsmull_h v7, v6, v17, v13.s[3] + dsmull_h v26, v27, v19, v11.s[2] + dsmull_h v20, v21, v18, v12.s[0] + dsmull_h v24, v25, v18, v12.s[1] + + neg v28.2d, v28.2d + neg v29.2d, v29.2d + neg v7.2d, v7.2d + neg v6.2d, v6.2d + + drshrn_h v4, v4, v5, #14 + drshrn_h v5, v28, v29, #14 + drshrn_h v29, v30, v31, #14 + drshrn_h v28, v22, v23, #14 + drshrn_h v7, v7, v6, #14 + drshrn_h v31, v26, v27, #14 + drshrn_h v6, v20, v21, #14 + drshrn_h v30, v24, v25, #14 + + dmbutterfly_l v16, v17, v18, v19, v29, v4, v1.s[0], v1.s[1] + dmbutterfly_l v27, v26, v20, v21, v31, v5, v1.s[0], v1.s[1] + drshrn_h v23, v16, v17, #14 + drshrn_h v24, v18, v19, #14 + neg v20.2d, v20.2d + neg v21.2d, v21.2d + drshrn_h v27, v27, v26, #14 + drshrn_h v20, v20, v21, #14 + dmbutterfly_l v16, v17, v18, v19, v30, v6, v1.s[2], v1.s[3] + drshrn_h v21, v16, v17, #14 + drshrn_h v26, v18, v19, #14 + dmbutterfly_l v16, v17, v18, v19, v28, v7, v1.s[2], v1.s[3] + drshrn_h v25, v16, v17, #14 + neg v18.2d, v18.2d + neg v19.2d, v19.2d + drshrn_h v22, v18, v19, #14 + + idct32_end endfunc +.macro idct32_funcs suffix // Do an 32-point IDCT of a 4x32 slice out of a 32x32 matrix. // The 32-point IDCT can be decomposed into two 16-point IDCTs; // a normal IDCT16 with every other input component (the even ones, with @@ -1227,18 +1587,29 @@ endfunc // x1 = unused // x2 = src // x9 = double input stride -function idct32_1d_4x32_pass1_neon +function idct32_1d_4x32_pass1\suffix\()_neon mov x14, x30 movi v4.4s, #0 // v16 = IN(0), v17 = IN(2) ... v31 = IN(30) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 - ld1 {v\i\().4s}, [x2] - st1 {v4.4s}, [x2], x9 + load_clear \i, x2, x9 +.endr +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + load_clear \i, x2, x9 .endr +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + load_clear \i, x2, x9 +.endr +.endif - bl idct16 + bl idct16\suffix // Do four 4x4 transposes. Originally, v16-v31 contain the // 16 rows. Afterwards, v16-v19, v20-v23, v24-v27 and v28-v31 @@ -1279,17 +1650,36 @@ function idct32_1d_4x32_pass1_neon // Move x2 back to the start of the input, and move // to the first odd row +.ifb \suffix sub x2, x2, x9, lsl #4 +.endif +.ifc \suffix,_quarter + sub x2, x2, x9, lsl #2 +.endif +.ifc \suffix,_half + sub x2, x2, x9, lsl #3 +.endif add x2, x2, #128 movi v4.4s, #0 // v16 = IN(1), v17 = IN(3) ... v31 = IN(31) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 - ld1 {v\i\().4s}, [x2] - st1 {v4.4s}, [x2], x9 + load_clear \i, x2, x9 +.endr +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + load_clear \i, x2, x9 .endr +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + load_clear \i, x2, x9 +.endr +.endif - bl idct32_odd + bl idct32_odd\suffix transpose_4x4s v31, v30, v29, v28, v4, v5, v6, v7 transpose_4x4s v27, v26, v25, v24, v4, v5, v6, v7 @@ -1350,32 +1740,60 @@ endfunc // x2 = src (temp buffer) // x7 = negative double temp buffer stride // x9 = double temp buffer stride -function idct32_1d_4x32_pass2_neon +function idct32_1d_4x32_pass2\suffix\()_neon mov x14, x30 // v16 = IN(0), v17 = IN(2) ... v31 = IN(30) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 - ld1 {v\i\().4s}, [x2], x9 + load \i, x2, x9 .endr sub x2, x2, x9, lsl #4 +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + load \i, x2, x9 +.endr + sub x2, x2, x9, lsl #2 +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + load \i, x2, x9 +.endr + sub x2, x2, x9, lsl #3 +.endif - bl idct16 + bl idct16\suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 - st1 {v\i\().4s}, [x2], x9 + store \i, x2, x9 .endr sub x2, x2, x9, lsl #4 add x2, x2, #128 // v16 = IN(1), v17 = IN(3) ... v31 = IN(31) +.ifb \suffix .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 - ld1 {v\i\().4s}, [x2], x9 + load \i, x2, x9 .endr sub x2, x2, x9, lsl #4 +.endif +.ifc \suffix,_quarter +.irp i, 16, 17, 18, 19 + load \i, x2, x9 +.endr + sub x2, x2, x9, lsl #2 +.endif +.ifc \suffix,_half +.irp i, 16, 17, 18, 19, 20, 21, 22, 23 + load \i, x2, x9 +.endr + sub x2, x2, x9, lsl #3 +.endif sub x2, x2, #128 - bl idct32_odd + bl idct32_odd\suffix .macro load_acc_store a, b, c, d, neg=0 .if \neg == 0 @@ -1433,6 +1851,11 @@ function idct32_1d_4x32_pass2_neon .purgem load_acc_store br x14 endfunc +.endm + +idct32_funcs +idct32_funcs _quarter +idct32_funcs _half const min_eob_idct_idct_32, align=4 .short 0, 9, 34, 70, 135, 240, 336, 448 @@ -1443,7 +1866,6 @@ function vp9_idct_idct_32x32_add_16_neon b.eq idct32x32_dc_add_neon movrel x10, idct_coeffs - movrel x12, min_eob_idct_idct_32, 2 mov x15, x30 stp d8, d9, [sp, #-0x10]! @@ -1474,6 +1896,13 @@ function vp9_idct_idct_32x32_add_16_neon dup v15.8h, w13 + cmp w3, #34 + b.le idct32x32_quarter_add_16_neon + cmp w3, #135 + b.le idct32x32_half_add_16_neon + + movrel x12, min_eob_idct_idct_32, 2 + .irp i, 0, 4, 8, 12, 16, 20, 24, 28 add x0, sp, #(\i*128) .if \i > 0 @@ -1526,3 +1955,63 @@ function ff_vp9_idct_idct_32x32_add_12_neon, export=1 mov x13, #0x0fff b vp9_idct_idct_32x32_add_16_neon endfunc + +.macro idct32_partial size +function idct32x32_\size\()_add_16_neon +.irp i, 0, 4 + add x0, sp, #(\i*128) +.ifc \size,quarter +.if \i == 4 + cmp w3, #9 + b.le 1f +.endif +.endif + add x2, x6, #(\i*4) + bl idct32_1d_4x32_pass1_\size\()_neon +.endr + +.ifc \size,half +.irp i, 8, 12 + add x0, sp, #(\i*128) +.if \i == 12 + cmp w3, #70 + b.le 1f +.endif + add x2, x6, #(\i*4) + bl idct32_1d_4x32_pass1_\size\()_neon +.endr +.endif + b 3f + +1: + // Write zeros to the temp buffer for pass 2 + movi v16.4s, #0 + movi v17.4s, #0 + movi v18.4s, #0 + movi v19.4s, #0 + +.rept 4 + st1 {v16.4s-v19.4s}, [x0], #64 + st1 {v16.4s-v19.4s}, [x0], #64 +.endr + +3: +.irp i, 0, 4, 8, 12, 16, 20, 24, 28 + add x0, x4, #(\i*2) + mov x1, x5 + add x2, sp, #(\i*4) + bl idct32_1d_4x32_pass2_\size\()_neon +.endr + + add sp, sp, #4096 + ldp d14, d15, [sp], 0x10 + ldp d12, d13, [sp], 0x10 + ldp d10, d11, [sp], 0x10 + ldp d8, d9, [sp], 0x10 + + br x15 +endfunc +.endm + +idct32_partial quarter +idct32_partial half From 5d996b56499f00f80b02a41bab3d6b7349e36e9d Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 16 Mar 2017 02:00:17 +0100 Subject: [PATCH 1206/3374] avcodec/tiff: Check stripsize strippos for overflow Fixes: 861/clusterfuzz-testcase-5688284384591872 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/tiff.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index 0be7be75280b5..5a6573fb79f88 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -914,6 +914,11 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) break; case TIFF_STRIP_OFFS: if (count == 1) { + if (value > INT_MAX) { + av_log(s->avctx, AV_LOG_ERROR, + "strippos %u too large\n", value); + return AVERROR_INVALIDDATA; + } s->strippos = 0; s->stripoff = value; } else @@ -925,6 +930,11 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) break; case TIFF_STRIP_SIZE: if (count == 1) { + if (value > INT_MAX) { + av_log(s->avctx, AV_LOG_ERROR, + "stripsize %u too large\n", value); + return AVERROR_INVALIDDATA; + } s->stripsizesoff = 0; s->stripsize = value; s->strips = 1; From a84d610b372c63e8a48a9ed7c038a2954097512c Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 16 Mar 2017 03:02:50 +0100 Subject: [PATCH 1207/3374] avcodec/h264_direct: Fix runtime error: signed integer overflow: -9 - 2147483647 cannot be represented in type 'int' Fixes: 864/clusterfuzz-testcase-4774385942528000 See: [FFmpeg-devel] [PATCH 1/2] avcodec/h264_direct: Fix runtime error: signed integer overflow: 2147483647 - -14133 cannot be represented in type 'int' See: [FFmpeg-devel] [PATCH 2/2] avcodec/h264_direct: Fix runtime error: signed integer overflow: -9 - 2147483647 cannot be represented in type 'int' Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/h264_direct.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c index 66e54479d1165..4e7202b986d85 100644 --- a/libavcodec/h264_direct.c +++ b/libavcodec/h264_direct.c @@ -48,8 +48,13 @@ static int get_scale_factor(H264SliceContext *sl, if (td == 0 || sl->ref_list[0][i].parent->long_ref) { return 256; } else { - int tb = av_clip_int8(poc - poc0); + int64_t pocdiff0 = poc - (int64_t)poc0; + int tb = av_clip_int8(pocdiff0); int tx = (16384 + (FFABS(td) >> 1)) / td; + + if (pocdiff0 != (int)pocdiff0) + av_log(sl->h264->avctx, AV_LOG_DEBUG, "pocdiff0 overflow\n"); + return av_clip_intp2((tb * tx + 32) >> 6, 10); } } From 98da63b3f5f5a277c5c3a16860db9a9f6741e54c Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 16 Mar 2017 11:20:46 +0100 Subject: [PATCH 1208/3374] avcodec/vp56: Check avctx->error_concealment before enabling EC Fixes timeout with 847/clusterfuzz-testcase-5291877358108672 Fixes timeout with 850/clusterfuzz-testcase-5721296509861888 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/vp56.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c index 4751840943ecd..b69fe6c176d1c 100644 --- a/libavcodec/vp56.c +++ b/libavcodec/vp56.c @@ -712,7 +712,7 @@ static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *data, int ret = vp56_decode_mb(s, mb_row, mb_col, is_alpha); if (ret < 0) { damaged = 1; - if (!s->have_undamaged_frame) { + if (!s->have_undamaged_frame || !avctx->error_concealment) { s->discard_frame = 1; return AVERROR_INVALIDDATA; } From 656a17e126c08ac8ed71da99047f13cf3e6c2a7c Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 17 Mar 2017 03:25:17 +0100 Subject: [PATCH 1209/3374] avcodec/mjpegdec: Check quant_matrixes values for being non zero Signed-off-by: Michael Niedermayer --- libavcodec/mjpegdec.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 8bf2fdfcc1458..af12d5d71b2d6 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -188,6 +188,10 @@ int ff_mjpeg_decode_dqt(MJpegDecodeContext *s) /* read quant table */ for (i = 0; i < 64; i++) { s->quant_matrixes[index][i] = get_bits(&s->gb, pr ? 16 : 8); + if (s->quant_matrixes[index][i] == 0) { + av_log(s->avctx, AV_LOG_ERROR, "dqt: 0 quant value\n"); + return AVERROR_INVALIDDATA; + } } // XXX FIXME fine-tune, and perhaps add dc too From 23f3f92361a3db53e595de33cfd5440f53bee220 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 17 Mar 2017 03:25:18 +0100 Subject: [PATCH 1210/3374] avcodec/mjpegdec: quant_matrixes can be up to 65535, use uint16_t Fixes invalid shift Fixes: 870/clusterfuzz-testcase-5649105424482304 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/mjpegdec.c | 10 +++++----- libavcodec/mjpegdec.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index af12d5d71b2d6..f26e8a3f9ac05 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -686,7 +686,7 @@ static inline int mjpeg_decode_dc(MJpegDecodeContext *s, int dc_index) /* decode block and dequantize */ static int decode_block(MJpegDecodeContext *s, int16_t *block, int component, - int dc_index, int ac_index, int16_t *quant_matrix) + int dc_index, int ac_index, uint16_t *quant_matrix) { int code, i, j, level, val; @@ -736,7 +736,7 @@ static int decode_block(MJpegDecodeContext *s, int16_t *block, int component, static int decode_dc_progressive(MJpegDecodeContext *s, int16_t *block, int component, int dc_index, - int16_t *quant_matrix, int Al) + uint16_t *quant_matrix, int Al) { int val; s->bdsp.clear_block(block); @@ -754,7 +754,7 @@ static int decode_dc_progressive(MJpegDecodeContext *s, int16_t *block, /* decode block and dequantize - progressive JPEG version */ static int decode_block_progressive(MJpegDecodeContext *s, int16_t *block, uint8_t *last_nnz, int ac_index, - int16_t *quant_matrix, + uint16_t *quant_matrix, int ss, int se, int Al, int *EOBRUN) { int code, i, j, level, val, run; @@ -852,7 +852,7 @@ for (; ; i++) { \ /* decode block and dequantize - progressive JPEG refinement pass */ static int decode_block_refinement(MJpegDecodeContext *s, int16_t *block, uint8_t *last_nnz, - int ac_index, int16_t *quant_matrix, + int ac_index, uint16_t *quant_matrix, int ss, int se, int Al, int *EOBRUN) { int code, i = ss, j, sign, val, run; @@ -1383,7 +1383,7 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, int mb_x, mb_y; int EOBRUN = 0; int c = s->comp_index[0]; - int16_t *quant_matrix = s->quant_matrixes[s->quant_sindex[0]]; + uint16_t *quant_matrix = s->quant_matrixes[s->quant_sindex[0]]; av_assert0(ss>=0 && Ah>=0 && Al>=0); if (se < ss || se > 63) { diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h index fb811294a146f..024cedcb5ad69 100644 --- a/libavcodec/mjpegdec.h +++ b/libavcodec/mjpegdec.h @@ -50,7 +50,7 @@ typedef struct MJpegDecodeContext { int buffer_size; uint8_t *buffer; - int16_t quant_matrixes[4][64]; + uint16_t quant_matrixes[4][64]; VLC vlcs[3][4]; int qscale[4]; ///< quantizer scale calculated from quant_matrixes From 08e1376d81f380a22fc7d4c1f783e83364d4ceb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sun, 19 Mar 2017 14:48:32 +0100 Subject: [PATCH 1211/3374] fate: add fate-sws-pixdesc-query Test the pixel format querying within libswscale. --- libswscale/Makefile | 1 + libswscale/tests/.gitignore | 1 + libswscale/tests/pixdesc_query.c | 90 ++++ tests/Makefile | 1 + tests/fate/libswscale.mak | 7 + tests/ref/fate/sws-pixdesc-query | 806 +++++++++++++++++++++++++++++++ 6 files changed, 906 insertions(+) create mode 100644 libswscale/tests/pixdesc_query.c create mode 100644 tests/fate/libswscale.mak create mode 100644 tests/ref/fate/sws-pixdesc-query diff --git a/libswscale/Makefile b/libswscale/Makefile index 0272039a6c8e8..183167cced9b0 100644 --- a/libswscale/Makefile +++ b/libswscale/Makefile @@ -26,4 +26,5 @@ OBJS-$(CONFIG_SHARED) += log2_tab.o SLIBOBJS-$(HAVE_GNU_WINDRES) += swscaleres.o TESTPROGS = colorspace \ + pixdesc_query \ swscale \ diff --git a/libswscale/tests/.gitignore b/libswscale/tests/.gitignore index 0ac3691ecdd12..1a26f038c4588 100644 --- a/libswscale/tests/.gitignore +++ b/libswscale/tests/.gitignore @@ -1,2 +1,3 @@ /colorspace +/pixdesc_query /swscale diff --git a/libswscale/tests/pixdesc_query.c b/libswscale/tests/pixdesc_query.c new file mode 100644 index 0000000000000..bc49809d4b533 --- /dev/null +++ b/libswscale/tests/pixdesc_query.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2017 Clément Bœsch + * + * 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 "libswscale/swscale_internal.h" + +/* TODO: drop this wrapper when all the is*() becomes functions */ +#define DECLARE_WRAPPER(macro) \ +static int macro##_func(enum AVPixelFormat pix_fmt) \ +{ \ + return macro(pix_fmt); \ +} + +DECLARE_WRAPPER(is16BPS) +DECLARE_WRAPPER(isNBPS) +DECLARE_WRAPPER(isBE) +DECLARE_WRAPPER(isYUV) +DECLARE_WRAPPER(isPlanarYUV) +DECLARE_WRAPPER(isRGB) +DECLARE_WRAPPER(isGray) +DECLARE_WRAPPER(isRGBinInt) +DECLARE_WRAPPER(isBGRinInt) +DECLARE_WRAPPER(isRGBinBytes) +DECLARE_WRAPPER(isBGRinBytes) +DECLARE_WRAPPER(isBayer) +DECLARE_WRAPPER(isAnyRGB) +DECLARE_WRAPPER(isALPHA) +DECLARE_WRAPPER(isPacked) +DECLARE_WRAPPER(isPlanar) +DECLARE_WRAPPER(isPackedRGB) +DECLARE_WRAPPER(isPlanarRGB) +DECLARE_WRAPPER(usePal) + +static const struct { + const char *class; + int (*cond)(enum AVPixelFormat pix_fmt); +} query_tab[] = { + {"is16BPS", is16BPS_func}, + {"isNBPS", isNBPS_func}, + {"isBE", isBE_func}, + {"isYUV", isYUV_func}, + {"isPlanarYUV", isPlanarYUV_func}, + {"isRGB", isRGB_func}, + {"Gray", isGray_func}, + {"RGBinInt", isRGBinInt_func}, + {"BGRinInt", isBGRinInt_func}, + {"RGBinBytes", isRGBinBytes_func}, + {"BGRinBytes", isBGRinBytes_func}, + {"Bayer", isBayer_func}, + {"AnyRGB", isAnyRGB_func}, + {"ALPHA", isALPHA_func}, + {"Packed", isPacked_func}, + {"Planar", isPlanar_func}, + {"PackedRGB", isPackedRGB_func}, + {"PlanarRGB", isPlanarRGB_func}, + {"usePal", usePal_func}, +}; + +int main(void) +{ + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(query_tab); i++) { + const AVPixFmtDescriptor *pix_desc = NULL; + printf("%s:\n", query_tab[i].class); + while ((pix_desc = av_pix_fmt_desc_next(pix_desc))) { + enum AVPixelFormat pix_fmt = av_pix_fmt_desc_get_id(pix_desc); + if (query_tab[i].cond(pix_fmt)) + printf(" %s\n", pix_desc->name); + } + printf("\n"); + } + return 0; +} diff --git a/tests/Makefile b/tests/Makefile index 53d900bdba759..66d99106ff9a3 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -145,6 +145,7 @@ include $(SRC_PATH)/tests/fate/libavformat.mak include $(SRC_PATH)/tests/fate/libavresample.mak include $(SRC_PATH)/tests/fate/libavutil.mak include $(SRC_PATH)/tests/fate/libswresample.mak +include $(SRC_PATH)/tests/fate/libswscale.mak include $(SRC_PATH)/tests/fate/lossless-audio.mak include $(SRC_PATH)/tests/fate/lossless-video.mak include $(SRC_PATH)/tests/fate/matroska.mak diff --git a/tests/fate/libswscale.mak b/tests/fate/libswscale.mak new file mode 100644 index 0000000000000..e72fe590a81a8 --- /dev/null +++ b/tests/fate/libswscale.mak @@ -0,0 +1,7 @@ +FATE_LIBSWSCALE += fate-sws-pixdesc-query +fate-sws-pixdesc-query: libswscale/tests/pixdesc_query$(EXESUF) +fate-sws-pixdesc-query: CMD = run libswscale/tests/pixdesc_query + +FATE_LIBSWSCALE += $(FATE_LIBSWSCALE-yes) +FATE-$(CONFIG_SWSCALE) += $(FATE_LIBSWSCALE) +fate-libswscale: $(FATE_LIBSWSCALE) diff --git a/tests/ref/fate/sws-pixdesc-query b/tests/ref/fate/sws-pixdesc-query new file mode 100644 index 0000000000000..1f0584474b379 --- /dev/null +++ b/tests/ref/fate/sws-pixdesc-query @@ -0,0 +1,806 @@ +is16BPS: + gray16be + gray16le + rgb48be + rgb48le + yuv420p16le + yuv420p16be + yuv422p16le + yuv422p16be + yuv444p16le + yuv444p16be + bgr48be + bgr48le + gbrp16be + gbrp16le + yuva420p16be + yuva420p16le + yuva422p16be + yuva422p16le + yuva444p16be + yuva444p16le + rgba64be + rgba64le + bgra64be + bgra64le + ya16be + ya16le + gbrap16be + gbrap16le + ayuv64le + ayuv64be + p016le + p016be + +isNBPS: + yuv420p9be + yuv420p9le + yuv420p10be + yuv420p10le + yuv422p10be + yuv422p10le + yuv444p9be + yuv444p9le + yuv444p10be + yuv444p10le + yuv422p9be + yuv422p9le + gbrp9be + gbrp9le + gbrp10be + gbrp10le + yuva420p9be + yuva420p9le + yuva422p9be + yuva422p9le + yuva444p9be + yuva444p9le + yuva420p10be + yuva420p10le + yuva422p10be + yuva422p10le + yuva444p10be + yuva444p10le + xyz12le + xyz12be + nv20le + nv20be + yuv420p12be + yuv420p12le + yuv420p14be + yuv420p14le + yuv422p12be + yuv422p12le + yuv422p14be + yuv422p14le + yuv444p12be + yuv444p12le + yuv444p14be + yuv444p14le + gbrp12be + gbrp12le + gbrp14be + gbrp14le + yuv440p10le + yuv440p10be + yuv440p12le + yuv440p12be + p010le + p010be + gbrap12be + gbrap12le + gbrap10be + gbrap10le + gray12be + gray12le + gray10be + gray10le + +isBE: + gray16be + rgb48be + rgb565be + rgb555be + bgr565be + bgr555be + yuv420p16be + yuv422p16be + yuv444p16be + rgb444be + bgr444be + bgr48be + yuv420p9be + yuv420p10be + yuv422p10be + yuv444p9be + yuv444p10be + yuv422p9be + gbrp9be + gbrp10be + gbrp16be + yuva420p9be + yuva422p9be + yuva444p9be + yuva420p10be + yuva422p10be + yuva444p10be + yuva420p16be + yuva422p16be + yuva444p16be + xyz12be + nv20be + rgba64be + bgra64be + ya16be + gbrap16be + yuv420p12be + yuv420p14be + yuv422p12be + yuv422p14be + yuv444p12be + yuv444p14be + gbrp12be + gbrp14be + bayer_bggr16be + bayer_rggb16be + bayer_gbrg16be + bayer_grbg16be + yuv440p10be + yuv440p12be + ayuv64be + p010be + gbrap12be + gbrap10be + gray12be + gray10be + p016be + +isYUV: + yuv420p + yuyv422 + yuv422p + yuv444p + yuv410p + yuv411p + yuvj420p + yuvj422p + yuvj444p + uyvy422 + uyyvyy411 + nv12 + nv21 + yuv440p + yuvj440p + yuva420p + yuv420p16le + yuv420p16be + yuv422p16le + yuv422p16be + yuv444p16le + yuv444p16be + ya8 + yuv420p9be + yuv420p9le + yuv420p10be + yuv420p10le + yuv422p10be + yuv422p10le + yuv444p9be + yuv444p9le + yuv444p10be + yuv444p10le + yuv422p9be + yuv422p9le + yuva422p + yuva444p + yuva420p9be + yuva420p9le + yuva422p9be + yuva422p9le + yuva444p9be + yuva444p9le + yuva420p10be + yuva420p10le + yuva422p10be + yuva422p10le + yuva444p10be + yuva444p10le + yuva420p16be + yuva420p16le + yuva422p16be + yuva422p16le + yuva444p16be + yuva444p16le + xyz12le + xyz12be + nv16 + nv20le + nv20be + yvyu422 + ya16be + ya16le + yuv420p12be + yuv420p12le + yuv420p14be + yuv420p14le + yuv422p12be + yuv422p12le + yuv422p14be + yuv422p14le + yuv444p12be + yuv444p12le + yuv444p14be + yuv444p14le + yuvj411p + yuv440p10le + yuv440p10be + yuv440p12le + yuv440p12be + ayuv64le + ayuv64be + p010le + p010be + p016le + p016be + +isPlanarYUV: + yuv420p + yuv422p + yuv444p + yuv410p + yuv411p + yuvj420p + yuvj422p + yuvj444p + nv12 + nv21 + yuv440p + yuvj440p + yuva420p + yuv420p16le + yuv420p16be + yuv422p16le + yuv422p16be + yuv444p16le + yuv444p16be + yuv420p9be + yuv420p9le + yuv420p10be + yuv420p10le + yuv422p10be + yuv422p10le + yuv444p9be + yuv444p9le + yuv444p10be + yuv444p10le + yuv422p9be + yuv422p9le + yuva422p + yuva444p + yuva420p9be + yuva420p9le + yuva422p9be + yuva422p9le + yuva444p9be + yuva444p9le + yuva420p10be + yuva420p10le + yuva422p10be + yuva422p10le + yuva444p10be + yuva444p10le + yuva420p16be + yuva420p16le + yuva422p16be + yuva422p16le + yuva444p16be + yuva444p16le + nv16 + nv20le + nv20be + yuv420p12be + yuv420p12le + yuv420p14be + yuv420p14le + yuv422p12be + yuv422p12le + yuv422p14be + yuv422p14le + yuv444p12be + yuv444p12le + yuv444p14be + yuv444p14le + yuvj411p + yuv440p10le + yuv440p10be + yuv440p12le + yuv440p12be + p010le + p010be + p016le + p016be + +isRGB: + rgb24 + bgr24 + bgr8 + bgr4 + bgr4_byte + rgb8 + rgb4 + rgb4_byte + argb + rgba + abgr + bgra + rgb48be + rgb48le + rgb565be + rgb565le + rgb555be + rgb555le + bgr565be + bgr565le + bgr555be + bgr555le + rgb444le + rgb444be + bgr444le + bgr444be + bgr48be + bgr48le + gbrp + gbrp9be + gbrp9le + gbrp10be + gbrp10le + gbrp16be + gbrp16le + rgba64be + rgba64le + bgra64be + bgra64le + gbrap + gbrap16be + gbrap16le + 0rgb + rgb0 + 0bgr + bgr0 + gbrp12be + gbrp12le + gbrp14be + gbrp14le + bayer_bggr8 + bayer_rggb8 + bayer_gbrg8 + bayer_grbg8 + bayer_bggr16le + bayer_bggr16be + bayer_rggb16le + bayer_rggb16be + bayer_gbrg16le + bayer_gbrg16be + bayer_grbg16le + bayer_grbg16be + gbrap12be + gbrap12le + gbrap10be + gbrap10le + +Gray: + gray + gray16be + gray16le + ya8 + ya16be + ya16le + gray12be + gray12le + gray10be + gray10le + +RGBinInt: + rgb24 + monow + monob + rgb8 + rgb4 + rgb4_byte + abgr + bgra + rgb48be + rgb48le + rgb565be + rgb565le + rgb555be + rgb555le + rgb444le + rgb444be + rgba64be + rgba64le + +BGRinInt: + bgr24 + monow + monob + bgr8 + bgr4 + bgr4_byte + argb + rgba + bgr565be + bgr565le + bgr555be + bgr555le + bgr444le + bgr444be + bgr48be + bgr48le + bgra64be + bgra64le + +RGBinBytes: + rgb24 + argb + rgba + rgb48be + rgb48le + rgba64be + rgba64le + +BGRinBytes: + bgr24 + abgr + bgra + bgr48be + bgr48le + bgra64be + bgra64le + +Bayer: + bayer_bggr8 + bayer_rggb8 + bayer_gbrg8 + bayer_grbg8 + bayer_bggr16le + bayer_bggr16be + bayer_rggb16le + bayer_rggb16be + bayer_gbrg16le + bayer_gbrg16be + bayer_grbg16le + bayer_grbg16be + +AnyRGB: + rgb24 + bgr24 + monow + monob + bgr8 + bgr4 + bgr4_byte + rgb8 + rgb4 + rgb4_byte + argb + rgba + abgr + bgra + rgb48be + rgb48le + rgb565be + rgb565le + rgb555be + rgb555le + bgr565be + bgr565le + bgr555be + bgr555le + rgb444le + rgb444be + bgr444le + bgr444be + bgr48be + bgr48le + gbrp + gbrp9be + gbrp9le + gbrp10be + gbrp10le + gbrp16be + gbrp16le + rgba64be + rgba64le + bgra64be + bgra64le + gbrap + gbrap16be + gbrap16le + 0rgb + rgb0 + 0bgr + bgr0 + gbrp12be + gbrp12le + gbrp14be + gbrp14le + bayer_bggr8 + bayer_rggb8 + bayer_gbrg8 + bayer_grbg8 + bayer_bggr16le + bayer_bggr16be + bayer_rggb16le + bayer_rggb16be + bayer_gbrg16le + bayer_gbrg16be + bayer_grbg16le + bayer_grbg16be + gbrap12be + gbrap12le + gbrap10be + gbrap10le + +ALPHA: + pal8 + argb + rgba + abgr + bgra + yuva420p + ya8 + yuva422p + yuva444p + yuva420p9be + yuva420p9le + yuva422p9be + yuva422p9le + yuva444p9be + yuva444p9le + yuva420p10be + yuva420p10le + yuva422p10be + yuva422p10le + yuva444p10be + yuva444p10le + yuva420p16be + yuva420p16le + yuva422p16be + yuva422p16le + yuva444p16be + yuva444p16le + rgba64be + rgba64le + bgra64be + bgra64le + ya16be + ya16le + gbrap + gbrap16be + gbrap16le + ayuv64le + ayuv64be + gbrap12be + gbrap12le + gbrap10be + gbrap10le + +Packed: + yuyv422 + rgb24 + bgr24 + monow + monob + pal8 + uyvy422 + bgr8 + bgr4 + bgr4_byte + rgb8 + rgb4 + rgb4_byte + argb + rgba + abgr + bgra + rgb48be + rgb48le + rgb565be + rgb565le + rgb555be + rgb555le + bgr565be + bgr565le + bgr555be + bgr555le + rgb444le + rgb444be + bgr444le + bgr444be + ya8 + bgr48be + bgr48le + rgba64be + rgba64le + bgra64be + bgra64le + yvyu422 + ya16be + ya16le + ayuv64le + ayuv64be + +Planar: + yuv420p + yuv422p + yuv444p + yuv410p + yuv411p + yuvj420p + yuvj422p + yuvj444p + nv12 + nv21 + yuv440p + yuvj440p + yuva420p + yuv420p16le + yuv420p16be + yuv422p16le + yuv422p16be + yuv444p16le + yuv444p16be + yuv420p9be + yuv420p9le + yuv420p10be + yuv420p10le + yuv422p10be + yuv422p10le + yuv444p9be + yuv444p9le + yuv444p10be + yuv444p10le + yuv422p9be + yuv422p9le + gbrp + gbrp9be + gbrp9le + gbrp10be + gbrp10le + gbrp16be + gbrp16le + yuva422p + yuva444p + yuva420p9be + yuva420p9le + yuva422p9be + yuva422p9le + yuva444p9be + yuva444p9le + yuva420p10be + yuva420p10le + yuva422p10be + yuva422p10le + yuva444p10be + yuva444p10le + yuva420p16be + yuva420p16le + yuva422p16be + yuva422p16le + yuva444p16be + yuva444p16le + nv16 + nv20le + nv20be + gbrap + gbrap16be + gbrap16le + yuv420p12be + yuv420p12le + yuv420p14be + yuv420p14le + yuv422p12be + yuv422p12le + yuv422p14be + yuv422p14le + yuv444p12be + yuv444p12le + yuv444p14be + yuv444p14le + gbrp12be + gbrp12le + gbrp14be + gbrp14le + yuvj411p + yuv440p10le + yuv440p10be + yuv440p12le + yuv440p12be + p010le + p010be + gbrap12be + gbrap12le + gbrap10be + gbrap10le + p016le + p016be + +PackedRGB: + rgb24 + bgr24 + bgr8 + bgr4 + bgr4_byte + rgb8 + rgb4 + rgb4_byte + argb + rgba + abgr + bgra + rgb48be + rgb48le + rgb565be + rgb565le + rgb555be + rgb555le + bgr565be + bgr565le + bgr555be + bgr555le + rgb444le + rgb444be + bgr444le + bgr444be + bgr48be + bgr48le + rgba64be + rgba64le + bgra64be + bgra64le + 0rgb + rgb0 + 0bgr + bgr0 + bayer_bggr8 + bayer_rggb8 + bayer_gbrg8 + bayer_grbg8 + bayer_bggr16le + bayer_bggr16be + bayer_rggb16le + bayer_rggb16be + bayer_gbrg16le + bayer_gbrg16be + bayer_grbg16le + bayer_grbg16be + +PlanarRGB: + gbrp + gbrp9be + gbrp9le + gbrp10be + gbrp10le + gbrp16be + gbrp16le + gbrap + gbrap16be + gbrap16le + gbrp12be + gbrp12le + gbrp14be + gbrp14le + gbrap12be + gbrap12le + gbrap10be + gbrap10le + +usePal: + gray + pal8 + bgr8 + bgr4_byte + rgb8 + rgb4_byte + From f052b1b40f94dd89ce86330cffb8f6e4793ff203 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sun, 19 Mar 2017 14:57:29 +0100 Subject: [PATCH 1212/3374] swscale: use a function for isGray --- libswscale/swscale_internal.h | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index af82396b1c813..6bcb4640eea95 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -687,23 +687,16 @@ static av_always_inline int isRGB(enum AVPixelFormat pix_fmt) return (desc->flags & AV_PIX_FMT_FLAG_RGB); } -#if 0 // FIXME -#define isGray(x) \ - (!(av_pix_fmt_desc_get(x)->flags & AV_PIX_FMT_FLAG_PAL) && \ - av_pix_fmt_desc_get(x)->nb_components <= 2) -#else -#define isGray(x) \ - ((x) == AV_PIX_FMT_GRAY8 || \ - (x) == AV_PIX_FMT_YA8 || \ - (x) == AV_PIX_FMT_GRAY10BE || \ - (x) == AV_PIX_FMT_GRAY10LE || \ - (x) == AV_PIX_FMT_GRAY12BE || \ - (x) == AV_PIX_FMT_GRAY12LE || \ - (x) == AV_PIX_FMT_GRAY16BE || \ - (x) == AV_PIX_FMT_GRAY16LE || \ - (x) == AV_PIX_FMT_YA16BE || \ - (x) == AV_PIX_FMT_YA16LE) -#endif +static av_always_inline int isGray(enum AVPixelFormat pix_fmt) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + av_assert0(desc); + return !(desc->flags & AV_PIX_FMT_FLAG_PAL) && + !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL) && + desc->nb_components <= 2 && + pix_fmt != AV_PIX_FMT_MONOBLACK && + pix_fmt != AV_PIX_FMT_MONOWHITE; +} #define isRGBinInt(x) \ ( \ From 9c2436e1e78f92439836131555efe69bbacc056a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sun, 19 Mar 2017 22:34:31 +0100 Subject: [PATCH 1213/3374] lavu: add AV_PIX_FMT_FLAG_BAYER --- doc/APIchanges | 3 +++ libavutil/pixdesc.c | 26 +++++++++++++------------- libavutil/pixdesc.h | 5 +++++ libavutil/version.h | 2 +- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index d5cee9b703d92..cbf6f369798bd 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-03-xx - xxxxxxx - lavu 55.49.100 - pixdesc.h + Add AV_PIX_FMT_FLAG_BAYER pixel format flag. + 2017-03-18 - xxxxxxx - lavfi 6.77.100 - avfilter.h Deprecate AVFilterGraph.resample_lavr_opts It's never been used by avfilter nor passed to anything. diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index 3b9c45d035f5f..ad068df3c74b7 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -1915,62 +1915,62 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { [AV_PIX_FMT_BAYER_BGGR8] = { .name = "bayer_bggr8", BAYER8_DESC_COMMON - .flags = AV_PIX_FMT_FLAG_RGB, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, }, [AV_PIX_FMT_BAYER_BGGR16LE] = { .name = "bayer_bggr16le", BAYER16_DESC_COMMON - .flags = AV_PIX_FMT_FLAG_RGB, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, }, [AV_PIX_FMT_BAYER_BGGR16BE] = { .name = "bayer_bggr16be", BAYER16_DESC_COMMON - .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, }, [AV_PIX_FMT_BAYER_RGGB8] = { .name = "bayer_rggb8", BAYER8_DESC_COMMON - .flags = AV_PIX_FMT_FLAG_RGB, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, }, [AV_PIX_FMT_BAYER_RGGB16LE] = { .name = "bayer_rggb16le", BAYER16_DESC_COMMON - .flags = AV_PIX_FMT_FLAG_RGB, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, }, [AV_PIX_FMT_BAYER_RGGB16BE] = { .name = "bayer_rggb16be", BAYER16_DESC_COMMON - .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, }, [AV_PIX_FMT_BAYER_GBRG8] = { .name = "bayer_gbrg8", BAYER8_DESC_COMMON - .flags = AV_PIX_FMT_FLAG_RGB, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, }, [AV_PIX_FMT_BAYER_GBRG16LE] = { .name = "bayer_gbrg16le", BAYER16_DESC_COMMON - .flags = AV_PIX_FMT_FLAG_RGB, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, }, [AV_PIX_FMT_BAYER_GBRG16BE] = { .name = "bayer_gbrg16be", BAYER16_DESC_COMMON - .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, }, [AV_PIX_FMT_BAYER_GRBG8] = { .name = "bayer_grbg8", BAYER8_DESC_COMMON - .flags = AV_PIX_FMT_FLAG_RGB, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, }, [AV_PIX_FMT_BAYER_GRBG16LE] = { .name = "bayer_grbg16le", BAYER16_DESC_COMMON - .flags = AV_PIX_FMT_FLAG_RGB, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, }, [AV_PIX_FMT_BAYER_GRBG16BE] = { .name = "bayer_grbg16be", BAYER16_DESC_COMMON - .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, }, [AV_PIX_FMT_NV16] = { .name = "nv16", @@ -2415,7 +2415,7 @@ void ff_check_pixfmt_descriptors(void){ } else { av_assert0(8*c->step >= c->depth); } - if (!strncmp(d->name, "bayer_", 6)) + if (d->flags & AV_PIX_FMT_FLAG_BAYER) continue; av_read_image_line(tmp, (void*)data, linesize, d, 0, 0, j, 2, 0); av_assert0(tmp[0] == 0 && tmp[1] == 0); diff --git a/libavutil/pixdesc.h b/libavutil/pixdesc.h index a8ad588913cf1..c3a6f27f49e1f 100644 --- a/libavutil/pixdesc.h +++ b/libavutil/pixdesc.h @@ -172,6 +172,11 @@ typedef struct AVPixFmtDescriptor { */ #define AV_PIX_FMT_FLAG_ALPHA (1 << 7) +/** + * The pixel format is following a Bayer pattern + */ +#define AV_PIX_FMT_FLAG_BAYER (1 << 8) + /** * Return the number of bits per pixel used by the pixel format * described by pixdesc. Note that this is not the same as the number diff --git a/libavutil/version.h b/libavutil/version.h index 4d5a40513076d..25925b996dd3c 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 48 +#define LIBAVUTIL_VERSION_MINOR 49 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From c30875e8b2bd785ff02cbc828295f583ccc488c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sun, 19 Mar 2017 15:04:53 +0100 Subject: [PATCH 1214/3374] swscale: use a function for isBayer --- libswscale/swscale_internal.h | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index 6bcb4640eea95..34130740b17af 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -760,20 +760,12 @@ static av_always_inline int isGray(enum AVPixelFormat pix_fmt) || (x) == AV_PIX_FMT_BGR24 \ ) -#define isBayer(x) ( \ - (x)==AV_PIX_FMT_BAYER_BGGR8 \ - || (x)==AV_PIX_FMT_BAYER_BGGR16LE \ - || (x)==AV_PIX_FMT_BAYER_BGGR16BE \ - || (x)==AV_PIX_FMT_BAYER_RGGB8 \ - || (x)==AV_PIX_FMT_BAYER_RGGB16LE \ - || (x)==AV_PIX_FMT_BAYER_RGGB16BE \ - || (x)==AV_PIX_FMT_BAYER_GBRG8 \ - || (x)==AV_PIX_FMT_BAYER_GBRG16LE \ - || (x)==AV_PIX_FMT_BAYER_GBRG16BE \ - || (x)==AV_PIX_FMT_BAYER_GRBG8 \ - || (x)==AV_PIX_FMT_BAYER_GRBG16LE \ - || (x)==AV_PIX_FMT_BAYER_GRBG16BE \ - ) +static av_always_inline int isBayer(enum AVPixelFormat pix_fmt) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + av_assert0(desc); + return !!(desc->flags & AV_PIX_FMT_FLAG_BAYER); +} #define isAnyRGB(x) \ ( \ From 2b9a52bcca7d0b95c974a9addaad29e917dd3d40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sun, 19 Mar 2017 15:15:10 +0100 Subject: [PATCH 1215/3374] swscale: use a function for isAnyRGB --- libswscale/swscale_internal.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index 34130740b17af..b1fec421fead9 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -767,13 +767,13 @@ static av_always_inline int isBayer(enum AVPixelFormat pix_fmt) return !!(desc->flags & AV_PIX_FMT_FLAG_BAYER); } -#define isAnyRGB(x) \ - ( \ - isBayer(x) || \ - isRGBinInt(x) || \ - isBGRinInt(x) || \ - isRGB(x) \ - ) +static av_always_inline int isAnyRGB(enum AVPixelFormat pix_fmt) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + av_assert0(desc); + return (desc->flags & AV_PIX_FMT_FLAG_RGB) || + pix_fmt == AV_PIX_FMT_MONOBLACK || pix_fmt == AV_PIX_FMT_MONOWHITE; +} static av_always_inline int isALPHA(enum AVPixelFormat pix_fmt) { From ff6bc16c5ad94704615b2cc9cb7f238e61bbe12d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sun, 19 Mar 2017 15:28:19 +0100 Subject: [PATCH 1216/3374] swscale: use a (more correct) function for isPacked --- libswscale/swscale_internal.h | 21 +++------------------ tests/ref/fate/sws-pixdesc-query | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index b1fec421fead9..ea5df26a2734d 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -784,30 +784,15 @@ static av_always_inline int isALPHA(enum AVPixelFormat pix_fmt) return desc->flags & AV_PIX_FMT_FLAG_ALPHA; } -#if 1 -#define isPacked(x) ( \ - (x)==AV_PIX_FMT_PAL8 \ - || (x)==AV_PIX_FMT_YUYV422 \ - || (x)==AV_PIX_FMT_YVYU422 \ - || (x)==AV_PIX_FMT_UYVY422 \ - || (x)==AV_PIX_FMT_YA8 \ - || (x)==AV_PIX_FMT_YA16LE \ - || (x)==AV_PIX_FMT_YA16BE \ - || (x)==AV_PIX_FMT_AYUV64LE \ - || (x)==AV_PIX_FMT_AYUV64BE \ - || isRGBinInt(x) \ - || isBGRinInt(x) \ - ) -#else static av_always_inline int isPacked(enum AVPixelFormat pix_fmt) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); av_assert0(desc); - return ((desc->nb_components >= 2 && !(desc->flags & AV_PIX_FMT_FLAG_PLANAR)) || - pix_fmt == AV_PIX_FMT_PAL8); + return (desc->nb_components >= 2 && !(desc->flags & AV_PIX_FMT_FLAG_PLANAR)) || + pix_fmt == AV_PIX_FMT_PAL8 || + pix_fmt == AV_PIX_FMT_MONOBLACK || pix_fmt == AV_PIX_FMT_MONOWHITE; } -#endif static av_always_inline int isPlanar(enum AVPixelFormat pix_fmt) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); diff --git a/tests/ref/fate/sws-pixdesc-query b/tests/ref/fate/sws-pixdesc-query index 1f0584474b379..d23b4f5a11a29 100644 --- a/tests/ref/fate/sws-pixdesc-query +++ b/tests/ref/fate/sws-pixdesc-query @@ -594,6 +594,7 @@ Packed: monob pal8 uyvy422 + uyyvyy411 bgr8 bgr4 bgr4_byte @@ -621,6 +622,8 @@ Packed: ya8 bgr48be bgr48le + xyz12le + xyz12be rgba64be rgba64le bgra64be @@ -628,6 +631,22 @@ Packed: yvyu422 ya16be ya16le + 0rgb + rgb0 + 0bgr + bgr0 + bayer_bggr8 + bayer_rggb8 + bayer_gbrg8 + bayer_grbg8 + bayer_bggr16le + bayer_bggr16be + bayer_rggb16le + bayer_rggb16be + bayer_gbrg16le + bayer_gbrg16be + bayer_grbg16le + bayer_grbg16be ayuv64le ayuv64be From d6635daded80d68b0cda767a8a19af4b6a41701f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sun, 19 Mar 2017 23:36:29 +0100 Subject: [PATCH 1217/3374] swscale: remove unused is{RGB,BGR}inBytes --- libswscale/swscale_internal.h | 19 ------------------- libswscale/tests/pixdesc_query.c | 4 ---- tests/ref/fate/sws-pixdesc-query | 18 ------------------ 3 files changed, 41 deletions(-) diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index ea5df26a2734d..d5674227ed215 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -741,25 +741,6 @@ static av_always_inline int isGray(enum AVPixelFormat pix_fmt) (x) == AV_PIX_FMT_MONOWHITE \ ) -#define isRGBinBytes(x) ( \ - (x) == AV_PIX_FMT_RGB48BE \ - || (x) == AV_PIX_FMT_RGB48LE \ - || (x) == AV_PIX_FMT_RGBA64BE \ - || (x) == AV_PIX_FMT_RGBA64LE \ - || (x) == AV_PIX_FMT_RGBA \ - || (x) == AV_PIX_FMT_ARGB \ - || (x) == AV_PIX_FMT_RGB24 \ - ) -#define isBGRinBytes(x) ( \ - (x) == AV_PIX_FMT_BGR48BE \ - || (x) == AV_PIX_FMT_BGR48LE \ - || (x) == AV_PIX_FMT_BGRA64BE \ - || (x) == AV_PIX_FMT_BGRA64LE \ - || (x) == AV_PIX_FMT_BGRA \ - || (x) == AV_PIX_FMT_ABGR \ - || (x) == AV_PIX_FMT_BGR24 \ - ) - static av_always_inline int isBayer(enum AVPixelFormat pix_fmt) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); diff --git a/libswscale/tests/pixdesc_query.c b/libswscale/tests/pixdesc_query.c index bc49809d4b533..9591b04da69c5 100644 --- a/libswscale/tests/pixdesc_query.c +++ b/libswscale/tests/pixdesc_query.c @@ -36,8 +36,6 @@ DECLARE_WRAPPER(isRGB) DECLARE_WRAPPER(isGray) DECLARE_WRAPPER(isRGBinInt) DECLARE_WRAPPER(isBGRinInt) -DECLARE_WRAPPER(isRGBinBytes) -DECLARE_WRAPPER(isBGRinBytes) DECLARE_WRAPPER(isBayer) DECLARE_WRAPPER(isAnyRGB) DECLARE_WRAPPER(isALPHA) @@ -60,8 +58,6 @@ static const struct { {"Gray", isGray_func}, {"RGBinInt", isRGBinInt_func}, {"BGRinInt", isBGRinInt_func}, - {"RGBinBytes", isRGBinBytes_func}, - {"BGRinBytes", isBGRinBytes_func}, {"Bayer", isBayer_func}, {"AnyRGB", isAnyRGB_func}, {"ALPHA", isALPHA_func}, diff --git a/tests/ref/fate/sws-pixdesc-query b/tests/ref/fate/sws-pixdesc-query index d23b4f5a11a29..e262a0cabff41 100644 --- a/tests/ref/fate/sws-pixdesc-query +++ b/tests/ref/fate/sws-pixdesc-query @@ -440,24 +440,6 @@ BGRinInt: bgra64be bgra64le -RGBinBytes: - rgb24 - argb - rgba - rgb48be - rgb48le - rgba64be - rgba64le - -BGRinBytes: - bgr24 - abgr - bgra - bgr48be - bgr48le - bgra64be - bgra64le - Bayer: bayer_bggr8 bayer_rggb8 From e811f84a2ed05ed9ed22210d34969b989811da37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sun, 19 Mar 2017 23:42:10 +0100 Subject: [PATCH 1218/3374] swscale: cosmetics in is{RGB,BGR}inInt Reduce diff with Libav. --- libswscale/swscale_internal.h | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index d5674227ed215..1e1d5fa300709 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -698,9 +698,8 @@ static av_always_inline int isGray(enum AVPixelFormat pix_fmt) pix_fmt != AV_PIX_FMT_MONOWHITE; } -#define isRGBinInt(x) \ - ( \ - (x) == AV_PIX_FMT_RGB48BE || \ +#define isRGBinInt(x) \ + ((x) == AV_PIX_FMT_RGB48BE || \ (x) == AV_PIX_FMT_RGB48LE || \ (x) == AV_PIX_FMT_RGB32 || \ (x) == AV_PIX_FMT_RGB32_1 || \ @@ -717,11 +716,10 @@ static av_always_inline int isGray(enum AVPixelFormat pix_fmt) (x) == AV_PIX_FMT_RGBA64BE || \ (x) == AV_PIX_FMT_RGBA64LE || \ (x) == AV_PIX_FMT_MONOBLACK || \ - (x) == AV_PIX_FMT_MONOWHITE \ - ) -#define isBGRinInt(x) \ - ( \ - (x) == AV_PIX_FMT_BGR48BE || \ + (x) == AV_PIX_FMT_MONOWHITE) + +#define isBGRinInt(x) \ + ((x) == AV_PIX_FMT_BGR48BE || \ (x) == AV_PIX_FMT_BGR48LE || \ (x) == AV_PIX_FMT_BGR32 || \ (x) == AV_PIX_FMT_BGR32_1 || \ @@ -738,8 +736,7 @@ static av_always_inline int isGray(enum AVPixelFormat pix_fmt) (x) == AV_PIX_FMT_BGRA64BE || \ (x) == AV_PIX_FMT_BGRA64LE || \ (x) == AV_PIX_FMT_MONOBLACK || \ - (x) == AV_PIX_FMT_MONOWHITE \ - ) + (x) == AV_PIX_FMT_MONOWHITE) static av_always_inline int isBayer(enum AVPixelFormat pix_fmt) { From 5e5e7935523d51b36277a02f2d247132dc6db01c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Mon, 20 Mar 2017 08:10:54 +0100 Subject: [PATCH 1219/3374] doc/APIchanges: fill date & hash for AV_PIX_FMT_FLAG_BAYER --- doc/APIchanges | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index cbf6f369798bd..6e187670c065f 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,7 +15,7 @@ libavutil: 2015-08-28 API changes, most recent first: -2017-03-xx - xxxxxxx - lavu 55.49.100 - pixdesc.h +2017-03-20 - 9c2436e - lavu 55.49.100 - pixdesc.h Add AV_PIX_FMT_FLAG_BAYER pixel format flag. 2017-03-18 - xxxxxxx - lavfi 6.77.100 - avfilter.h From 64926292a68aca217a122c207baacd006e8187ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Mon, 20 Mar 2017 09:23:15 +0100 Subject: [PATCH 1220/3374] lavc/copy_block: style fix --- libavcodec/copy_block.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libavcodec/copy_block.h b/libavcodec/copy_block.h index 4d6ef262d1397..393d45578e78c 100644 --- a/libavcodec/copy_block.h +++ b/libavcodec/copy_block.h @@ -27,11 +27,10 @@ static inline void copy_block2(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride, int h) { int i; - for(i=0; i Date: Mon, 20 Mar 2017 10:45:18 +0100 Subject: [PATCH 1221/3374] configure: remove pod2man from the config list The configure has the --disable-manpages option for this purpose, and --disable-pod2man is currently ignored due to that. This is also consistent with the other documentation options. --- configure | 1 - 1 file changed, 1 deletion(-) diff --git a/configure b/configure index 9529d50b1fa0c..c6eba84423a68 100755 --- a/configure +++ b/configure @@ -1702,7 +1702,6 @@ CONFIG_LIST=" memory_poisoning neon_clobber_test pic - pod2man raise_major thumb valgrind_backtrace From f3cd2302a9c9724f57fda4afb5ad7a588fb8b304 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 22 Dec 2016 09:02:32 -0500 Subject: [PATCH 1222/3374] wmavoice: remove unused or write-only variables. --- libavcodec/wmavoice.c | 44 +++++++++++++++++-------------------------- 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c index c2390a92b6299..2ec4499981f52 100644 --- a/libavcodec/wmavoice.c +++ b/libavcodec/wmavoice.c @@ -104,26 +104,24 @@ static const struct frame_type_desc { uint8_t dbl_pulses; ///< how many pulse vectors have pulse pairs ///< (rather than just one single pulse) ///< only if #fcb_type == #FCB_TYPE_EXC_PULSES - uint16_t frame_size; ///< the amount of bits that make up the block - ///< data (per frame) } frame_descs[17] = { - { 1, 0, ACB_TYPE_NONE, FCB_TYPE_SILENCE, 0, 0 }, - { 2, 1, ACB_TYPE_NONE, FCB_TYPE_HARDCODED, 0, 28 }, - { 2, 1, ACB_TYPE_ASYMMETRIC, FCB_TYPE_AW_PULSES, 0, 46 }, - { 2, 1, ACB_TYPE_ASYMMETRIC, FCB_TYPE_EXC_PULSES, 2, 80 }, - { 2, 1, ACB_TYPE_ASYMMETRIC, FCB_TYPE_EXC_PULSES, 5, 104 }, - { 4, 2, ACB_TYPE_ASYMMETRIC, FCB_TYPE_EXC_PULSES, 0, 108 }, - { 4, 2, ACB_TYPE_ASYMMETRIC, FCB_TYPE_EXC_PULSES, 2, 132 }, - { 4, 2, ACB_TYPE_ASYMMETRIC, FCB_TYPE_EXC_PULSES, 5, 168 }, - { 2, 1, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 0, 64 }, - { 2, 1, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 2, 80 }, - { 2, 1, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 5, 104 }, - { 4, 2, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 0, 108 }, - { 4, 2, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 2, 132 }, - { 4, 2, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 5, 168 }, - { 8, 3, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 0, 176 }, - { 8, 3, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 2, 208 }, - { 8, 3, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 5, 256 } + { 1, 0, ACB_TYPE_NONE, FCB_TYPE_SILENCE, 0 }, + { 2, 1, ACB_TYPE_NONE, FCB_TYPE_HARDCODED, 0 }, + { 2, 1, ACB_TYPE_ASYMMETRIC, FCB_TYPE_AW_PULSES, 0 }, + { 2, 1, ACB_TYPE_ASYMMETRIC, FCB_TYPE_EXC_PULSES, 2 }, + { 2, 1, ACB_TYPE_ASYMMETRIC, FCB_TYPE_EXC_PULSES, 5 }, + { 4, 2, ACB_TYPE_ASYMMETRIC, FCB_TYPE_EXC_PULSES, 0 }, + { 4, 2, ACB_TYPE_ASYMMETRIC, FCB_TYPE_EXC_PULSES, 2 }, + { 4, 2, ACB_TYPE_ASYMMETRIC, FCB_TYPE_EXC_PULSES, 5 }, + { 2, 1, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 0 }, + { 2, 1, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 2 }, + { 2, 1, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 5 }, + { 4, 2, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 0 }, + { 4, 2, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 2 }, + { 4, 2, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 5 }, + { 8, 3, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 0 }, + { 8, 3, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 2 }, + { 8, 3, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 5 } }; /** @@ -160,10 +158,6 @@ typedef struct WMAVoiceContext { int lsp_q_mode; ///< defines quantizer defaults [0, 1] int lsp_def_mode; ///< defines different sets of LSP defaults ///< [0, 1] - int frame_lsp_bitsize; ///< size (in bits) of LSPs, when encoded - ///< per-frame (independent coding) - int sframe_lsp_bitsize; ///< size (in bits) of LSPs, when encoded - ///< per superframe (residual coding) int min_pitch_val; ///< base value for pitch parsing code int max_pitch_val; ///< max value + 1 for pitch parsing @@ -423,12 +417,8 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx) lsp16_flag = flags & 0x1000; if (lsp16_flag) { s->lsps = 16; - s->frame_lsp_bitsize = 34; - s->sframe_lsp_bitsize = 60; } else { s->lsps = 10; - s->frame_lsp_bitsize = 24; - s->sframe_lsp_bitsize = 48; } for (n = 0; n < s->lsps; n++) s->prev_lsps[n] = M_PI * (n + 1.0) / (s->lsps + 1.0); From 5eb4f95bef2f95c4e776c60613b2825064d02ba9 Mon Sep 17 00:00:00 2001 From: Mirage Abeysekara Date: Sun, 19 Mar 2017 01:20:53 +0530 Subject: [PATCH 1223/3374] h264pred: added AVX2 implementation for tm_vp8 16x16. checkasm --bench results with 5000 runs pred16x16_tm_vp8_c: 302.8 pred16x16_tm_vp8_mmx: 101.4 pred16x16_tm_vp8_mmxext: 95.5 pred16x16_tm_vp8_sse2: 95.1 pred16x16_tm_vp8_avx2: 38.2 Signed-off-by: Ronald S. Bultje --- libavcodec/x86/h264_intrapred.asm | 37 ++++++++++++++++++++++++++++ libavcodec/x86/h264_intrapred_init.c | 7 ++++++ 2 files changed, 44 insertions(+) diff --git a/libavcodec/x86/h264_intrapred.asm b/libavcodec/x86/h264_intrapred.asm index c88d91b49e59b..0f3b46287edb9 100644 --- a/libavcodec/x86/h264_intrapred.asm +++ b/libavcodec/x86/h264_intrapred.asm @@ -268,6 +268,43 @@ cglobal pred16x16_tm_vp8_8, 2,6,6 jg .loop REP_RET +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +cglobal pred16x16_tm_vp8_8, 2, 4, 5, dst, stride, stride3, iteration + sub dstq, strideq + pmovzxbw m0, [dstq] + vpbroadcastb xm1, [r0-1] + pmovzxbw m1, xm1 + psubw m0, m1 + mov iterationd, 4 + lea stride3q, [strideq*3] +.loop: + vpbroadcastb xm1, [dstq+strideq*1-1] + vpbroadcastb xm2, [dstq+strideq*2-1] + vpbroadcastb xm3, [dstq+stride3q-1] + vpbroadcastb xm4, [dstq+strideq*4-1] + pmovzxbw m1, xm1 + pmovzxbw m2, xm2 + pmovzxbw m3, xm3 + pmovzxbw m4, xm4 + paddw m1, m0 + paddw m2, m0 + paddw m3, m0 + paddw m4, m0 + vpackuswb m1, m1, m2 + vpackuswb m3, m3, m4 + vpermq m1, m1, q3120 + vpermq m3, m3, q3120 + movdqa [dstq+strideq*1], xm1 + vextracti128 [dstq+strideq*2], m1, 1 + movdqa [dstq+stride3q*1], xm3 + vextracti128 [dstq+strideq*4], m3, 1 + lea dstq, [dstq+strideq*4] + dec iterationd + jg .loop + REP_RET +%endif + ;----------------------------------------------------------------------------- ; void ff_pred16x16_plane_*_8(uint8_t *src, int stride) ;----------------------------------------------------------------------------- diff --git a/libavcodec/x86/h264_intrapred_init.c b/libavcodec/x86/h264_intrapred_init.c index 528b92e497859..bdd5125d688f2 100644 --- a/libavcodec/x86/h264_intrapred_init.c +++ b/libavcodec/x86/h264_intrapred_init.c @@ -127,6 +127,7 @@ PRED16x16(plane_svq3, 8, ssse3) PRED16x16(tm_vp8, 8, mmx) PRED16x16(tm_vp8, 8, mmxext) PRED16x16(tm_vp8, 8, sse2) +PRED16x16(tm_vp8, 8, avx2) PRED8x8(top_dc, 8, mmxext) PRED8x8(dc_rv40, 8, mmxext) @@ -323,6 +324,12 @@ av_cold void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, } } } + + if(EXTERNAL_AVX2(cpu_flags)){ + if (codec_id == AV_CODEC_ID_VP8) { + h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_tm_vp8_8_avx2; + } + } } else if (bit_depth == 10) { if (EXTERNAL_MMXEXT(cpu_flags)) { h->pred4x4[DC_PRED ] = ff_pred4x4_dc_10_mmxext; From 2f3d10a01ac5f613f80db8542bf3ecda1dd40d79 Mon Sep 17 00:00:00 2001 From: Ilia Date: Mon, 13 Mar 2017 05:06:26 +0700 Subject: [PATCH 1224/3374] avcodec/vp9: avx2 implementation of ipred_dl_16x16_16 vp9_diag_downleft_16x16_10bpp_c: 263.0 vp9_diag_downleft_16x16_10bpp_sse2: 44.7 vp9_diag_downleft_16x16_10bpp_ssse3: 32.5 vp9_diag_downleft_16x16_10bpp_avx: 31.9 vp9_diag_downleft_16x16_10bpp_avx2: 25.7 vp9_diag_downleft_16x16_12bpp_c: 264.7 vp9_diag_downleft_16x16_12bpp_sse2: 44.4 vp9_diag_downleft_16x16_12bpp_ssse3: 32.0 vp9_diag_downleft_16x16_12bpp_avx: 32.4 vp9_diag_downleft_16x16_12bpp_avx2: 25.5 Benchmarked with 10000 runs Signed-off-by: Ilia Signed-off-by: Ronald S. Bultje --- libavcodec/x86/vp9dsp_init_16bpp.c | 2 ++ libavcodec/x86/vp9intrapred_16bpp.asm | 39 +++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/libavcodec/x86/vp9dsp_init_16bpp.c b/libavcodec/x86/vp9dsp_init_16bpp.c index eb67499c96241..4576ff16922ca 100644 --- a/libavcodec/x86/vp9dsp_init_16bpp.c +++ b/libavcodec/x86/vp9dsp_init_16bpp.c @@ -51,6 +51,7 @@ decl_ipred_fns(h, 16, mmxext, sse2); decl_ipred_fns(dc, 16, mmxext, sse2); decl_ipred_fns(dc_top, 16, mmxext, sse2); decl_ipred_fns(dc_left, 16, mmxext, sse2); +decl_ipred_fn(dl, 16, 16, avx2); #define decl_ipred_dir_funcs(type) \ decl_ipred_fns(type, 16, sse2, sse2); \ @@ -133,6 +134,7 @@ av_cold void ff_vp9dsp_init_16bpp_x86(VP9DSPContext *dsp) init_fpel_func(2, 1, 32, avg, _16, avx2); init_fpel_func(1, 1, 64, avg, _16, avx2); init_fpel_func(0, 1, 128, avg, _16, avx2); + init_ipred_func(dl, DIAG_DOWN_LEFT, 16, 16, avx2); } #endif /* HAVE_YASM */ diff --git a/libavcodec/x86/vp9intrapred_16bpp.asm b/libavcodec/x86/vp9intrapred_16bpp.asm index c0ac16d3eba4f..212e4130e832b 100644 --- a/libavcodec/x86/vp9intrapred_16bpp.asm +++ b/libavcodec/x86/vp9intrapred_16bpp.asm @@ -847,6 +847,45 @@ DL_FUNCS INIT_XMM avx DL_FUNCS +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +cglobal vp9_ipred_dl_16x16_16, 2, 4, 5, dst, stride, l, a + movifnidn aq, amp + mova m0, [aq] ; abcdefghijklmnop + vpbroadcastw xm1, [aq+30] ; pppppppp + vperm2i128 m2, m0, m1, q0201 ; ijklmnoppppppppp + vpalignr m3, m2, m0, 2 ; bcdefghijklmnopp + vpalignr m4, m2, m0, 4 ; cdefghijklmnoppp + LOWPASS 0, 3, 4 ; BCDEFGHIJKLMNOPp + vperm2i128 m2, m0, m1, q0201 ; JKLMNOPppppppppp + DEFINE_ARGS dst, stride, stride3, cnt + mov cntd, 2 + lea stride3q, [strideq*3] +.loop: + mova [dstq+strideq*0], m0 + vpalignr m3, m2, m0, 2 + vpalignr m4, m2, m0, 4 + mova [dstq+strideq*1], m3 + mova [dstq+strideq*2], m4 + vpalignr m3, m2, m0, 6 + vpalignr m4, m2, m0, 8 + mova [dstq+stride3q ], m3 + lea dstq, [dstq+strideq*4] + mova [dstq+strideq*0], m4 + vpalignr m3, m2, m0, 10 + vpalignr m4, m2, m0, 12 + mova [dstq+strideq*1], m3 + mova [dstq+strideq*2], m4 + vpalignr m3, m2, m0, 14 + mova [dstq+stride3q ], m3 + lea dstq, [dstq+strideq*4] + mova m0, m2 + vperm2i128 m2, m2, m2, q0101 ; pppppppppppppppp + dec cntd + jg .loop + RET +%endif + %macro DR_FUNCS 1 ; stack_mem_for_32x32_32bit_function cglobal vp9_ipred_dr_4x4_16, 4, 4, 3, dst, stride, l, a movh m0, [lq] ; wxyz.... From 20c4fb2e010fff7e3f8acd36ad132c0140fec5fb Mon Sep 17 00:00:00 2001 From: Ricardo Constantino Date: Mon, 20 Mar 2017 14:10:34 +0000 Subject: [PATCH 1225/3374] configure: add stdint.h to x264 and xavs checks Regression from 4563a86f011b54977b390c72ec3901cace35f8da. Both need stdint.h included before the respective x264.h and xavs.h. Old require() used different, separate checks that didn't actually need stdint.h to work. require2()'s (now require) check_func_headers() does include stdint.h but only after the custom headers. For libxavs this would also be consequently fixed by libav's commit 20abcaa273a6e77d0a2e1a98c643c73562c6f8f2 which wasn't merged yet. --- configure | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index fc256b195375e..e1b7c6199d4b9 100755 --- a/configure +++ b/configure @@ -5848,7 +5848,7 @@ enabled libwebp && { enabled libwebp_encoder && require_pkg_config "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion enabled libwebp_anim_encoder && { use_pkg_config "libwebpmux >= 0.4.0" webp/mux.h WebPAnimEncoderOptionsInit || disable libwebp_anim_encoder; } } enabled libx264 && { use_pkg_config x264 "stdint.h x264.h" x264_encoder_encode || - { require libx264 x264.h x264_encoder_encode -lx264 && + { require libx264 "stdint.h x264.h" x264_encoder_encode -lx264 && warn "using libx264 without pkg-config"; } } && { check_cpp_condition x264.h "X264_BUILD >= 118" || die "ERROR: libx264 must be installed and version must be >= 0.118."; } && @@ -5857,7 +5857,7 @@ enabled libx264 && { use_pkg_config x264 "stdint.h x264.h" x264_encode enabled libx265 && require_pkg_config x265 x265.h x265_api_get && { check_cpp_condition x265.h "X265_BUILD >= 68" || die "ERROR: libx265 version must be >= 68."; } -enabled libxavs && require libxavs xavs.h xavs_encoder_encode -lxavs +enabled libxavs && require libxavs "stdint.h xavs.h" xavs_encoder_encode -lxavs enabled libxvid && require libxvid xvid.h xvid_global -lxvidcore enabled libzimg && require_pkg_config "zimg >= 2.3.0" zimg.h zimg_get_api_version enabled libzmq && require_pkg_config libzmq zmq.h zmq_ctx_new From ce818d90bdb28d8591e6b81e020d1e7f87536649 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Mon, 20 Mar 2017 15:05:01 +0100 Subject: [PATCH 1226/3374] avcodec/wmaprodec: reset offsets when error happens Fixes #6250. Signed-off-by: Paul B Mahol --- libavcodec/wmaprodec.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index 1ad1e2354136c..5b1fe40a422e3 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -1760,6 +1760,10 @@ static int xma_decode_packet(AVCodecContext *avctx, void *data, memcpy(&s->samples[s->current_stream * 2 + 1][s->offset[s->current_stream] * 512], s->frames[s->current_stream]->extended_data[1], 512 * 4); s->offset[s->current_stream]++; + } else if (ret < 0) { + memset(s->offset, 0, sizeof(s->offset)); + s->current_stream = 0; + return ret; } if (s->xma[s->current_stream].packet_done || From d839c4716cdcecf3b46d05d0aec8f460cdb4ce23 Mon Sep 17 00:00:00 2001 From: Matthieu Bouron Date: Wed, 15 Mar 2017 15:23:34 +0100 Subject: [PATCH 1227/3374] configure: error out if jni is enabled and cannot be found --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index e1b7c6199d4b9..3232b9fb46489 100755 --- a/configure +++ b/configure @@ -5751,7 +5751,7 @@ enabled frei0r && { check_header frei0r.h || die "ERROR: frei0r.h hea enabled gmp && require gmp gmp.h mpz_export -lgmp enabled gnutls && require_pkg_config gnutls gnutls/gnutls.h gnutls_global_init enabled jni && { [ $target_os = "android" ] && check_header jni.h && enabled pthreads && - check_lib "dlfcn.h" dlopen -ldl; } + check_lib "dlfcn.h" dlopen -ldl || die "ERROR: jni not found"; } enabled ladspa && { check_header ladspa.h || die "ERROR: ladspa.h header not found"; } enabled libiec61883 && require libiec61883 libiec61883/iec61883.h iec61883_cmp_connect -lraw1394 -lavc1394 -lrom1394 -liec61883 enabled libass && require_pkg_config libass ass/ass.h ass_library_init From b78243c504014c0ee1fb8a66a866d2583c0985fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Mon, 20 Mar 2017 19:01:25 +0100 Subject: [PATCH 1228/3374] lavc/arm: fix indent in blockdsp_init_neon --- libavcodec/arm/blockdsp_init_neon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/arm/blockdsp_init_neon.c b/libavcodec/arm/blockdsp_init_neon.c index 87c0d6d6eb856..0600bc6e50796 100644 --- a/libavcodec/arm/blockdsp_init_neon.c +++ b/libavcodec/arm/blockdsp_init_neon.c @@ -30,6 +30,6 @@ void ff_clear_blocks_neon(int16_t *blocks); av_cold void ff_blockdsp_init_neon(BlockDSPContext *c) { - c->clear_block = ff_clear_block_neon; - c->clear_blocks = ff_clear_blocks_neon; + c->clear_block = ff_clear_block_neon; + c->clear_blocks = ff_clear_blocks_neon; } From bbc3bde14f1402a68c64a28edc347464554589cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Mon, 20 Mar 2017 19:45:48 +0100 Subject: [PATCH 1229/3374] configure: fix crystalhd detection Regression since 4563a86f011b54977b390c72ec3901cace35f8da. See 20c4fb2e010fff7e3f8acd36ad132c0140fec5fb for more information. Tested-by: Michael Niedermayer --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 3232b9fb46489..d4cfe1accb176 100755 --- a/configure +++ b/configure @@ -5719,7 +5719,7 @@ disabled bzlib || check_lib bzlib.h BZ2_bzlibVersion -lbz2 || disable bzlib disabled lzma || check_lib lzma.h lzma_version_number -llzma || disable lzma check_lib math.h sin -lm && LIBM="-lm" -disabled crystalhd || check_lib libcrystalhd/libcrystalhd_if.h DtsCrystalHDVersion -lcrystalhd || disable crystalhd +disabled crystalhd || check_lib "stdint.h libcrystalhd/libcrystalhd_if.h" DtsCrystalHDVersion -lcrystalhd || disable crystalhd atan2f_args=2 copysign_args=2 From b7cc4eb3030b48ba21c0c5de960f89f0240cf091 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Mon, 20 Mar 2017 23:04:28 +0100 Subject: [PATCH 1230/3374] lavc/nvenc: misc cosmetics to reduce diff with Libav --- libavcodec/nvenc.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index dd9ebc1756431..0abada0ff02b3 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -48,8 +48,8 @@ const enum AVPixelFormat ff_nvenc_pix_fmts[] = { AV_PIX_FMT_NONE }; -#define IS_10BIT(pix_fmt) (pix_fmt == AV_PIX_FMT_P010 || \ - pix_fmt == AV_PIX_FMT_YUV444P16) +#define IS_10BIT(pix_fmt) (pix_fmt == AV_PIX_FMT_P010 || \ + pix_fmt == AV_PIX_FMT_YUV444P16) #define IS_YUV444(pix_fmt) (pix_fmt == AV_PIX_FMT_YUV444P || \ pix_fmt == AV_PIX_FMT_YUV444P16) @@ -103,7 +103,7 @@ static int nvenc_map_error(NVENCSTATUS err, const char **desc) } static int nvenc_print_error(void *log_ctx, NVENCSTATUS err, - const char *error_string) + const char *error_string) { const char *desc; int ret; @@ -114,7 +114,7 @@ static int nvenc_print_error(void *log_ctx, NVENCSTATUS err, static av_cold int nvenc_load_libraries(AVCodecContext *avctx) { - NvencContext *ctx = avctx->priv_data; + NvencContext *ctx = avctx->priv_data; NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs; NVENCSTATUS err; uint32_t nvenc_max_ver; @@ -176,7 +176,7 @@ static av_cold int nvenc_open_session(AVCodecContext *avctx) static int nvenc_check_codec_support(AVCodecContext *avctx) { - NvencContext *ctx = avctx->priv_data; + NvencContext *ctx = avctx->priv_data; NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &ctx->nvenc_dload_funcs.nvenc_funcs; int i, ret, count = 0; GUID *guids = NULL; @@ -386,7 +386,7 @@ static av_cold int nvenc_check_device(AVCodecContext *avctx, int idx) static av_cold int nvenc_setup_device(AVCodecContext *avctx) { - NvencContext *ctx = avctx->priv_data; + NvencContext *ctx = avctx->priv_data; NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs; switch (avctx->codec->id) { @@ -544,7 +544,7 @@ static av_cold void set_vbr(AVCodecContext *avctx) rc->minQP.qpInterB = avctx->qmin; rc->minQP.qpInterP = avctx->qmin; - rc->minQP.qpIntra = avctx->qmin; + rc->minQP.qpIntra = avctx->qmin; rc->maxQP.qpInterB = avctx->qmax; rc->maxQP.qpInterP = avctx->qmax; @@ -602,7 +602,7 @@ static av_cold void set_lossless(AVCodecContext *avctx) rc->rateControlMode = NV_ENC_PARAMS_RC_CONSTQP; rc->constQP.qpInterB = 0; rc->constQP.qpInterP = 0; - rc->constQP.qpIntra = 0; + rc->constQP.qpIntra = 0; avctx->qmin = -1; avctx->qmax = -1; @@ -883,18 +883,18 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx) hevc->outputPictureTimingSEI = 1; } - switch(ctx->profile) { + switch (ctx->profile) { case NV_ENC_HEVC_PROFILE_MAIN: cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN_GUID; - avctx->profile = FF_PROFILE_HEVC_MAIN; + avctx->profile = FF_PROFILE_HEVC_MAIN; break; case NV_ENC_HEVC_PROFILE_MAIN_10: cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN10_GUID; - avctx->profile = FF_PROFILE_HEVC_MAIN_10; + avctx->profile = FF_PROFILE_HEVC_MAIN_10; break; case NV_ENC_HEVC_PROFILE_REXT: cc->profileGUID = NV_ENC_HEVC_PROFILE_FREXT_GUID; - avctx->profile = FF_PROFILE_HEVC_REXT; + avctx->profile = FF_PROFILE_HEVC_REXT; break; } @@ -1299,7 +1299,7 @@ static NvencSurface *get_free_frame(NvencContext *ctx) { int i; - for (i = 0; i < ctx->nb_surfaces; ++i) { + for (i = 0; i < ctx->nb_surfaces; i++) { if (!ctx->surfaces[i].lockCount) { ctx->surfaces[i].lockCount = 1; return &ctx->surfaces[i]; From 5e3a418b6047acd848698c4bb4bf0c1b73526744 Mon Sep 17 00:00:00 2001 From: Gerion Entrup Date: Mon, 2 Jan 2017 02:08:57 +0100 Subject: [PATCH 1231/3374] add signature filter for MPEG7 video signature This filter does not implement all features of MPEG7. Missing features: - compression of signature files - work only on (cropped) parts of the video Signed-off-by: Michael Niedermayer --- Changelog | 1 + configure | 1 + doc/filters.texi | 89 ++++ libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/signature.h | 569 ++++++++++++++++++++++++ libavfilter/signature_lookup.c | 573 ++++++++++++++++++++++++ libavfilter/version.h | 2 +- libavfilter/vf_signature.c | 767 +++++++++++++++++++++++++++++++++ 9 files changed, 2003 insertions(+), 1 deletion(-) create mode 100644 libavfilter/signature.h create mode 100644 libavfilter/signature_lookup.c create mode 100644 libavfilter/vf_signature.c diff --git a/Changelog b/Changelog index bc434feeac758..5bcf8f180e799 100644 --- a/Changelog +++ b/Changelog @@ -30,6 +30,7 @@ version : - Support MOV with multiple sample description tables - XPM decoder - Removed the legacy X11 screen grabber, use XCB instead +- MPEG-7 Video Signature filter version 3.2: diff --git a/configure b/configure index d4cfe1accb176..a9ea6986d5816 100755 --- a/configure +++ b/configure @@ -3139,6 +3139,7 @@ showspectrum_filter_deps="avcodec" showspectrum_filter_select="fft" showspectrumpic_filter_deps="avcodec" showspectrumpic_filter_select="fft" +signature_filter_deps="gpl avcodec avformat" smartblur_filter_deps="gpl swscale" sofalizer_filter_deps="netcdf avcodec" sofalizer_filter_select="fft" diff --git a/doc/filters.texi b/doc/filters.texi index 950ff817c5a6c..b62952af3957d 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -12660,6 +12660,95 @@ saturation maximum: %@{metadata:lavfi.signalstats.SATMAX@} @end example @end itemize +@anchor{signature} +@section signature + +Calculates the MPEG-7 Video Signature. The filter can handle more than one +input. In this case the matching between the inputs can be calculated additionally. +The filter always passes through the first input. The signature of each stream can +be written into a file. + +It accepts the following options: + +@table @option +@item detectmode +Enable or disable the matching process. + +Available values are: + +@table @samp +@item off +Disable the calculation of a matching (default). +@item full +Calculate the matching for the whole video and output whether the whole video +matches or only parts. +@item fast +Calculate only until a matching is found or the video ends. Should be faster in +some cases. +@end table + +@item nb_inputs +Set the number of inputs. The option value must be a non negative integer. +Default value is 1. + +@item filename +Set the path to which the output is written. If there is more than one input, +the path must be a prototype, i.e. must contain %d or %0nd (where n is a positive +integer), that will be replaced with the input number. If no filename is +specified, no output will be written. This is the default. + +@item format +Choose the output format. + +Available values are: + +@table @samp +@item binary +Use the specified binary representation (default). +@item xml +Use the specified xml representation. +@end table + +@item th_d +Set threshold to detect one word as similar. The option value must be an integer +greater than zero. The default value is 9000. + +@item th_dc +Set threshold to detect all words as similar. The option value must be an integer +greater than zero. The default value is 60000. + +@item th_xh +Set threshold to detect frames as similar. The option value must be an integer +greater than zero. The default value is 116. + +@item th_di +Set the minimum length of a sequence in frames to recognize it as matching +sequence. The option value must be a non negative integer value. +The default value is 0. + +@item th_it +Set the minimum relation, that matching frames to all frames must have. +The option value must be a double value between 0 and 1. The default value is 0.5. +@end table + +@subsection Examples + +@itemize +@item +To calculate the signature of an input video and store it in signature.bin: +@example +ffmpeg -i input.mkv -vf signature=filename=signature.bin -map 0:v -f null - +@end example + +@item +To detect whether two videos match and store the signatures in XML format in +signature0.xml and signature1.xml: +@example +ffmpeg -i input1.mkv -i input2.mkv -filter_complex "[0:v][1:v] signature=nb_inputs=2:detectmode=full:format=xml:filename=signature%d.xml" -map :v -f null - +@end example + +@end itemize + @anchor{smartblur} @section smartblur diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 428251f71cb4e..a48ca0ab45328 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -280,6 +280,7 @@ OBJS-$(CONFIG_SHUFFLEFRAMES_FILTER) += vf_shuffleframes.o OBJS-$(CONFIG_SHUFFLEPLANES_FILTER) += vf_shuffleplanes.o OBJS-$(CONFIG_SIDEDATA_FILTER) += f_sidedata.o OBJS-$(CONFIG_SIGNALSTATS_FILTER) += vf_signalstats.o +OBJS-$(CONFIG_SIGNATURE_FILTER) += vf_signature.o OBJS-$(CONFIG_SMARTBLUR_FILTER) += vf_smartblur.o OBJS-$(CONFIG_SOBEL_FILTER) += vf_convolution.o OBJS-$(CONFIG_SPLIT_FILTER) += split.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 2bf34efc84446..93271fb2c4a8d 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -290,6 +290,7 @@ static void register_all(void) REGISTER_FILTER(SHUFFLEPLANES, shuffleplanes, vf); REGISTER_FILTER(SIDEDATA, sidedata, vf); REGISTER_FILTER(SIGNALSTATS, signalstats, vf); + REGISTER_FILTER(SIGNATURE, signature, vf); REGISTER_FILTER(SMARTBLUR, smartblur, vf); REGISTER_FILTER(SOBEL, sobel, vf); REGISTER_FILTER(SPLIT, split, vf); diff --git a/libavfilter/signature.h b/libavfilter/signature.h new file mode 100644 index 0000000000000..2659c8790e778 --- /dev/null +++ b/libavfilter/signature.h @@ -0,0 +1,569 @@ +/* + * Copyright (c) 2017 Gerion Entrup + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU 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. + */ + +/** + * @file + * MPEG-7 video signature calculation and lookup filter + */ + +#ifndef AVFILTER_SIGNATURE_H +#define AVFILTER_SIGNATURE_H + +#include +#include "libavutil/common.h" +#include "libavutil/opt.h" +#include "libavutil/timestamp.h" +#include "avfilter.h" +#include "internal.h" + +#define ELEMENT_COUNT 10 +#define SIGELEM_SIZE 380 +#define DIFFELEM_SIZE 348 /* SIGELEM_SIZE - elem_a1 - elem_a2 */ +#define COARSE_SIZE 90 + +enum lookup_mode { + MODE_OFF, + MODE_FULL, + MODE_FAST, + NB_LOOKUP_MODE +}; + +enum formats { + FORMAT_BINARY, + FORMAT_XML, + NB_FORMATS +}; + +typedef struct { + uint8_t x; + uint8_t y; +} Point; + +typedef struct { + Point up; + Point to; +} Block; + +typedef struct { + int av_elem; /* average element category */ + short left_count; /* count of blocks that will be added together */ + short block_count; /* count of blocks per element */ + short elem_count; + const Block* blocks; +} ElemCat; + +typedef struct FineSignature { + struct FineSignature* next; + struct FineSignature* prev; + uint64_t pts; + uint32_t index; /* needed for xmlexport */ + uint8_t confidence; + uint8_t words[5]; + uint8_t framesig[SIGELEM_SIZE/5]; +} FineSignature; + +typedef struct CoarseSignature { + uint8_t data[5][31]; /* 5 words with min. 243 bit */ + struct FineSignature* first; /* associated Finesignatures */ + struct FineSignature* last; + struct CoarseSignature* next; +} CoarseSignature; + +/* lookup types */ +typedef struct MatchingInfo { + double meandist; + double framerateratio; /* second/first */ + int score; + int offset; + int matchframes; /* number of matching frames */ + int whole; + struct FineSignature* first; + struct FineSignature* second; + struct MatchingInfo* next; +} MatchingInfo; + +typedef struct { + AVRational time_base; + /* needed for xml_export */ + int w; /* height */ + int h; /* width */ + + /* overflow protection */ + int divide; + + FineSignature* finesiglist; + FineSignature* curfinesig; + + CoarseSignature* coarsesiglist; + CoarseSignature* coarseend; /* needed for xml export */ + /* helpers to store the alternating signatures */ + CoarseSignature* curcoarsesig1; + CoarseSignature* curcoarsesig2; + + int coarsecount; /* counter from 0 to 89 */ + int midcoarse; /* whether it is a coarsesignature beginning from 45 + i * 90 */ + uint32_t lastindex; /* helper to store amount of frames */ + + int exported; /* boolean whether stream already exported */ +} StreamContext; + +typedef struct { + const AVClass *class; + /* input parameters */ + int mode; + int nb_inputs; + char *filename; + int format; + int thworddist; + int thcomposdist; + int thl1; + int thdi; + int thit; + /* end input parameters */ + + uint8_t l1distlut[243*242/2]; /* 243 + 242 + 241 ... */ + StreamContext* streamcontexts; +} SignatureContext; + + +static const Block elem_a1_data[] = { + {{ 0, 0},{ 7, 7}}, + {{ 8, 0},{15, 7}}, + {{ 0, 8},{ 7,15}}, + {{ 8, 8},{15,15}}, + {{16, 0},{23, 7}}, + {{24, 0},{31, 7}}, + {{16, 8},{23,15}}, + {{24, 8},{31,15}}, + {{ 0,16},{ 7,23}}, + {{ 8,16},{15,23}}, + {{ 0,24},{ 7,31}}, + {{ 8,24},{15,31}}, + {{16,16},{23,23}}, + {{24,16},{31,23}}, + {{16,24},{23,31}}, + {{24,24},{31,31}}, + {{ 0, 0},{15,15}}, + {{16, 0},{31,15}}, + {{ 0,16},{15,31}}, + {{16,16},{31,31}} +}; +static const ElemCat elem_a1 = { 1, 1, 1, 20, elem_a1_data }; + +static const Block elem_a2_data[] = { + {{ 2, 2},{ 9, 9}}, + {{12, 2},{19, 9}}, + {{22, 2},{29, 9}}, + {{ 2,12},{ 9,19}}, + {{12,12},{19,19}}, + {{22,12},{29,19}}, + {{ 2,22},{ 9,29}}, + {{12,22},{19,29}}, + {{22,22},{29,29}}, + {{ 9, 9},{22,22}}, + {{ 6, 6},{25,25}}, + {{ 3, 3},{28,28}} +}; +static const ElemCat elem_a2 = { 1, 1, 1, 12, elem_a2_data }; + +static const Block elem_d1_data[] = { + {{ 0, 0},{ 1, 3}},{{ 2, 0},{ 3, 3}}, + {{ 4, 0},{ 7, 1}},{{ 4, 2},{ 7, 3}}, + {{ 0, 6},{ 3, 7}},{{ 0, 4},{ 3, 5}}, + {{ 6, 4},{ 7, 7}},{{ 4, 4},{ 5, 7}}, + {{ 8, 0},{ 9, 3}},{{10, 0},{11, 3}}, + {{12, 0},{15, 1}},{{12, 2},{15, 3}}, + {{ 8, 6},{11, 7}},{{ 8, 4},{11, 5}}, + {{14, 4},{15, 7}},{{12, 4},{13, 7}}, + {{ 0, 8},{ 1,11}},{{ 2, 8},{ 3,11}}, + {{ 4, 8},{ 7, 9}},{{ 4,10},{ 7,11}}, + {{ 0,14},{ 3,15}},{{ 0,12},{ 3,13}}, + {{ 6,12},{ 7,15}},{{ 4,12},{ 5,15}}, + {{ 8, 8},{ 9,11}},{{10, 8},{11,11}}, + {{12, 8},{15, 9}},{{12,10},{15,11}}, + {{ 8,14},{11,15}},{{ 8,12},{11,13}}, + {{14,12},{15,15}},{{12,12},{13,15}}, + {{16, 0},{19, 1}},{{16, 2},{19, 3}}, + {{22, 0},{23, 3}},{{20, 0},{21, 3}}, + {{16, 4},{17, 7}},{{18, 4},{19, 7}}, + {{20, 6},{23, 7}},{{20, 4},{23, 5}}, + {{24, 0},{27, 1}},{{24, 2},{27, 3}}, + {{30, 0},{31, 3}},{{28, 0},{29, 3}}, + {{24, 4},{25, 7}},{{26, 4},{27, 7}}, + {{28, 6},{31, 7}},{{28, 4},{31, 5}}, + {{16, 8},{19, 9}},{{16,10},{19,11}}, + {{22, 8},{23,11}},{{20, 8},{21,11}}, + {{16,12},{17,15}},{{18,12},{19,15}}, + {{20,14},{23,15}},{{20,12},{23,13}}, + {{24, 8},{27, 9}},{{24,10},{27,11}}, + {{30, 8},{31,11}},{{28, 8},{29,11}}, + {{24,12},{25,15}},{{26,12},{27,15}}, + {{28,14},{31,15}},{{28,12},{31,13}}, + {{ 0,16},{ 3,17}},{{ 0,18},{ 3,19}}, + {{ 6,16},{ 7,19}},{{ 4,16},{ 5,19}}, + {{ 0,20},{ 1,23}},{{ 2,20},{ 3,23}}, + {{ 4,22},{ 7,23}},{{ 4,20},{ 7,21}}, + {{ 8,16},{11,17}},{{ 8,18},{11,19}}, + {{14,16},{15,19}},{{12,16},{13,19}}, + {{ 8,20},{ 9,23}},{{10,20},{11,23}}, + {{12,22},{15,23}},{{12,20},{15,21}}, + {{ 0,24},{ 3,25}},{{ 0,26},{ 3,27}}, + {{ 6,24},{ 7,27}},{{ 4,24},{ 5,27}}, + {{ 0,28},{ 1,31}},{{ 2,28},{ 3,31}}, + {{ 4,30},{ 7,31}},{{ 4,28},{ 7,29}}, + {{ 8,24},{11,25}},{{ 8,26},{11,27}}, + {{14,24},{15,27}},{{12,24},{13,27}}, + {{ 8,28},{ 9,31}},{{10,28},{11,31}}, + {{12,30},{15,31}},{{12,28},{15,29}}, + {{16,16},{17,19}},{{18,16},{19,19}}, + {{20,16},{23,17}},{{20,18},{23,19}}, + {{16,22},{19,23}},{{16,20},{19,21}}, + {{22,20},{23,23}},{{20,20},{21,23}}, + {{24,16},{25,19}},{{26,16},{27,19}}, + {{28,16},{31,17}},{{28,18},{31,19}}, + {{24,22},{27,23}},{{24,20},{27,21}}, + {{30,20},{31,23}},{{28,20},{29,23}}, + {{16,24},{17,27}},{{18,24},{19,27}}, + {{20,24},{23,25}},{{20,26},{23,27}}, + {{16,30},{19,31}},{{16,28},{19,29}}, + {{22,28},{23,31}},{{20,28},{21,31}}, + {{24,24},{25,27}},{{26,24},{27,27}}, + {{28,24},{31,25}},{{28,26},{31,27}}, + {{24,30},{27,31}},{{24,28},{27,29}}, + {{30,28},{31,31}},{{28,28},{29,31}}, + {{ 2, 2},{ 3, 5}},{{ 4, 2},{ 5, 5}}, + {{ 6, 2},{ 9, 3}},{{ 6, 4},{ 9, 5}}, + {{ 2, 8},{ 5, 9}},{{ 2, 6},{ 5, 7}}, + {{ 8, 6},{ 9, 9}},{{ 6, 6},{ 7, 9}}, + {{12, 2},{13, 5}},{{14, 2},{15, 5}}, + {{16, 2},{19, 3}},{{16, 4},{19, 5}}, + {{12, 8},{15, 9}},{{12, 6},{15, 7}}, + {{18, 6},{19, 9}},{{16, 6},{17, 9}}, + {{22, 2},{23, 5}},{{24, 2},{25, 5}}, + {{26, 2},{29, 3}},{{26, 4},{29, 5}}, + {{22, 8},{25, 9}},{{22, 6},{25, 7}}, + {{28, 6},{29, 9}},{{26, 6},{27, 9}}, + {{ 2,12},{ 3,15}},{{ 4,12},{ 5,15}}, + {{ 6,12},{ 9,13}},{{ 6,14},{ 9,15}}, + {{ 2,18},{ 5,19}},{{ 2,16},{ 5,17}}, + {{ 8,16},{ 9,19}},{{ 6,16},{ 7,19}}, + {{12,12},{15,13}},{{12,14},{15,15}}, + {{16,12},{19,13}},{{16,14},{19,15}}, + {{12,18},{15,19}},{{12,16},{15,17}}, + {{16,18},{19,19}},{{16,16},{19,17}}, + {{22,12},{23,15}},{{24,12},{25,15}}, + {{26,12},{29,13}},{{26,14},{29,15}}, + {{22,18},{25,19}},{{22,16},{25,17}}, + {{28,16},{29,19}},{{26,16},{27,19}}, + {{ 2,22},{ 3,25}},{{ 4,22},{ 5,25}}, + {{ 6,22},{ 9,23}},{{ 6,24},{ 9,25}}, + {{ 2,28},{ 5,29}},{{ 2,26},{ 5,27}}, + {{ 8,26},{ 9,29}},{{ 6,26},{ 7,29}}, + {{12,22},{13,25}},{{14,22},{15,25}}, + {{16,22},{19,23}},{{16,24},{19,25}}, + {{12,28},{15,29}},{{12,26},{15,27}}, + {{18,26},{19,29}},{{16,26},{17,29}}, + {{22,22},{23,25}},{{24,22},{25,25}}, + {{26,22},{29,23}},{{26,24},{29,25}}, + {{22,28},{25,29}},{{22,26},{25,27}}, + {{28,26},{29,29}},{{26,26},{27,29}}, + {{ 7, 7},{10, 8}},{{ 7, 9},{10,10}}, + {{11, 7},{12,10}},{{13, 7},{14,10}}, + {{ 7,11},{ 8,14}},{{ 9,11},{10,14}}, + {{11,11},{14,12}},{{11,13},{14,14}}, + {{17, 7},{20, 8}},{{17, 9},{20,10}}, + {{21, 7},{22,10}},{{23, 7},{24,10}}, + {{17,11},{18,14}},{{19,11},{20,14}}, + {{21,11},{24,12}},{{21,13},{24,14}}, + {{ 7,17},{10,18}},{{ 7,19},{10,20}}, + {{11,17},{12,20}},{{13,17},{14,20}}, + {{ 7,21},{ 8,24}},{{ 9,21},{10,24}}, + {{11,21},{14,22}},{{11,23},{14,24}}, + {{17,17},{20,18}},{{17,19},{20,20}}, + {{21,17},{22,20}},{{23,17},{24,20}}, + {{17,21},{18,24}},{{19,21},{20,24}}, + {{21,21},{24,22}},{{21,23},{24,24}} +}; +static const ElemCat elem_d1 = { 0, 1, 2, 116, elem_d1_data }; + +static const Block elem_d2_data[] = { + {{ 0, 0},{ 3, 3}},{{ 4, 4},{ 7, 7}},{{ 4, 0},{ 7, 3}},{{ 0, 4},{ 3, 7}}, + {{ 8, 0},{11, 3}},{{12, 4},{15, 7}},{{12, 0},{15, 3}},{{ 8, 4},{11, 7}}, + {{16, 0},{19, 3}},{{20, 4},{23, 7}},{{20, 0},{23, 3}},{{16, 4},{19, 7}}, + {{24, 0},{27, 3}},{{28, 4},{31, 7}},{{28, 0},{31, 3}},{{24, 4},{27, 7}}, + {{ 0, 8},{ 3,11}},{{ 4,12},{ 7,15}},{{ 4, 8},{ 7,11}},{{ 0,12},{ 3,15}}, + {{ 8, 8},{11,11}},{{12,12},{15,15}},{{12, 8},{15,11}},{{ 8,12},{11,15}}, + {{16, 8},{19,11}},{{20,12},{23,15}},{{20, 8},{23,11}},{{16,12},{19,15}}, + {{24, 8},{27,11}},{{28,12},{31,15}},{{28, 8},{31,11}},{{24,12},{27,15}}, + {{ 0,16},{ 3,19}},{{ 4,20},{ 7,23}},{{ 4,16},{ 7,19}},{{ 0,20},{ 3,23}}, + {{ 8,16},{11,19}},{{12,20},{15,23}},{{12,16},{15,19}},{{ 8,20},{11,23}}, + {{16,16},{19,19}},{{20,20},{23,23}},{{20,16},{23,19}},{{16,20},{19,23}}, + {{24,16},{27,19}},{{28,20},{31,23}},{{28,16},{31,19}},{{24,20},{27,23}}, + {{ 0,24},{ 3,27}},{{ 4,28},{ 7,31}},{{ 4,24},{ 7,27}},{{ 0,28},{ 3,31}}, + {{ 8,24},{11,27}},{{12,28},{15,31}},{{12,24},{15,27}},{{ 8,28},{11,31}}, + {{16,24},{19,27}},{{20,28},{23,31}},{{20,24},{23,27}},{{16,28},{19,31}}, + {{24,24},{27,27}},{{28,28},{31,31}},{{28,24},{31,27}},{{24,28},{27,31}}, + {{ 4, 4},{ 7, 7}},{{ 8, 8},{11,11}},{{ 8, 4},{11, 7}},{{ 4, 8},{ 7,11}}, + {{12, 4},{15, 7}},{{16, 8},{19,11}},{{16, 4},{19, 7}},{{12, 8},{15,11}}, + {{20, 4},{23, 7}},{{24, 8},{27,11}},{{24, 4},{27, 7}},{{20, 8},{23,11}}, + {{ 4,12},{ 7,15}},{{ 8,16},{11,19}},{{ 8,12},{11,15}},{{ 4,16},{ 7,19}}, + {{12,12},{15,15}},{{16,16},{19,19}},{{16,12},{19,15}},{{12,16},{15,19}}, + {{20,12},{23,15}},{{24,16},{27,19}},{{24,12},{27,15}},{{20,16},{23,19}}, + {{ 4,20},{ 7,23}},{{ 8,24},{11,27}},{{ 8,20},{11,23}},{{ 4,24},{ 7,27}}, + {{12,20},{15,23}},{{16,24},{19,27}},{{16,20},{19,23}},{{12,24},{15,27}}, + {{20,20},{23,23}},{{24,24},{27,27}},{{24,20},{27,23}},{{20,24},{23,27}} +}; +static const ElemCat elem_d2 = { 0, 2, 4, 25, elem_d2_data }; + +static const Block elem_d3_data[] = { + {{ 1, 1},{10,10}},{{11, 1},{20,10}}, + {{ 1, 1},{10,10}},{{21, 1},{30,10}}, + {{ 1, 1},{10,10}},{{ 1,11},{10,20}}, + {{ 1, 1},{10,10}},{{11,11},{20,20}}, + {{ 1, 1},{10,10}},{{21,11},{30,20}}, + {{ 1, 1},{10,10}},{{ 1,21},{10,30}}, + {{ 1, 1},{10,10}},{{11,21},{20,30}}, + {{ 1, 1},{10,10}},{{21,21},{30,30}}, + {{11, 1},{20,10}},{{21, 1},{30,10}}, + {{11, 1},{20,10}},{{ 1,11},{10,20}}, + {{11, 1},{20,10}},{{11,11},{20,20}}, + {{11, 1},{20,10}},{{21,11},{30,20}}, + {{11, 1},{20,10}},{{ 1,21},{10,30}}, + {{11, 1},{20,10}},{{11,21},{20,30}}, + {{11, 1},{20,10}},{{21,21},{30,30}}, + {{21, 1},{30,10}},{{ 1,11},{10,20}}, + {{21, 1},{30,10}},{{11,11},{20,20}}, + {{21, 1},{30,10}},{{21,11},{30,20}}, + {{21, 1},{30,10}},{{ 1,21},{10,30}}, + {{21, 1},{30,10}},{{11,21},{20,30}}, + {{21, 1},{30,10}},{{21,21},{30,30}}, + {{ 1,11},{10,20}},{{11,11},{20,20}}, + {{ 1,11},{10,20}},{{21,11},{30,20}}, + {{ 1,11},{10,20}},{{ 1,21},{10,30}}, + {{ 1,11},{10,20}},{{11,21},{20,30}}, + {{ 1,11},{10,20}},{{21,21},{30,30}}, + {{11,11},{20,20}},{{21,11},{30,20}}, + {{11,11},{20,20}},{{ 1,21},{10,30}}, + {{11,11},{20,20}},{{11,21},{20,30}}, + {{11,11},{20,20}},{{21,21},{30,30}}, + {{21,11},{30,20}},{{ 1,21},{10,30}}, + {{21,11},{30,20}},{{11,21},{20,30}}, + {{21,11},{30,20}},{{21,21},{30,30}}, + {{ 1,21},{10,30}},{{11,21},{20,30}}, + {{ 1,21},{10,30}},{{21,21},{30,30}}, + {{11,21},{20,30}},{{21,21},{30,30}} +}; +static const ElemCat elem_d3 = { 0, 1, 2, 36, elem_d3_data }; + +static const Block elem_d4_data[] = { + {{ 7,13},{12,18}},{{19,13},{24,18}}, + {{13, 7},{18,12}},{{13,19},{18,24}}, + {{ 7, 7},{12,12}},{{19,19},{24,24}}, + {{19, 7},{24,12}},{{ 7,19},{12,24}}, + {{13, 7},{18,12}},{{19,13},{24,18}}, + {{19,13},{24,18}},{{13,19},{18,24}}, + {{13,19},{18,24}},{{ 7,13},{12,18}}, + {{ 7,13},{12,18}},{{13, 7},{18,12}}, + {{ 7, 7},{12,12}},{{19, 7},{24,12}}, + {{19, 7},{24,12}},{{19,19},{24,24}}, + {{19,19},{24,24}},{{ 7,19},{12,24}}, + {{ 7,19},{12,24}},{{ 7, 7},{12,12}}, + {{13,13},{18,18}},{{13, 1},{18, 6}}, + {{13,13},{18,18}},{{25,13},{30,18}}, + {{13,13},{18,18}},{{13,25},{18,30}}, + {{13,13},{18,18}},{{ 1,13},{ 6,18}}, + {{13, 1},{18, 6}},{{13,25},{18,30}}, + {{ 1,13},{ 6,18}},{{25,13},{30,18}}, + {{ 7, 1},{12, 6}},{{19, 1},{24, 6}}, + {{ 7,25},{12,30}},{{19,25},{24,30}}, + {{ 1, 7},{ 6,12}},{{ 1,19},{ 6,24}}, + {{25, 7},{30,12}},{{25,19},{30,24}}, + {{ 7, 1},{12, 6}},{{ 1, 7},{ 6,12}}, + {{19, 1},{24, 6}},{{25, 7},{30,12}}, + {{25,19},{30,24}},{{19,25},{24,30}}, + {{ 1,19},{ 6,24}},{{ 7,25},{12,30}}, + {{ 1, 1},{ 6, 6}},{{25, 1},{30, 6}}, + {{25, 1},{30, 6}},{{25,25},{30,30}}, + {{25,25},{30,30}},{{ 1,25},{ 6,30}}, + {{ 1,25},{ 6,30}},{{ 1, 1},{ 6, 6}} +}; +static const ElemCat elem_d4 = { 0, 1, 2, 30, elem_d4_data }; + +static const Block elem_d5_data[] = { + {{ 1, 1},{10, 3}},{{ 1, 4},{ 3, 7}},{{ 8, 4},{10, 7}},{{ 1, 8},{10,10}},{{ 4, 4},{ 7, 7}}, + {{11, 1},{20, 3}},{{11, 4},{13, 7}},{{18, 4},{20, 7}},{{11, 8},{20,10}},{{14, 4},{17, 7}}, + {{21, 1},{30, 3}},{{21, 4},{23, 7}},{{28, 4},{30, 7}},{{21, 8},{30,10}},{{24, 4},{27, 7}}, + {{ 1,11},{10,13}},{{ 1,14},{ 3,17}},{{ 8,14},{10,17}},{{ 1,18},{10,20}},{{ 4,14},{ 7,17}}, + {{11,11},{20,13}},{{11,14},{13,17}},{{18,14},{20,17}},{{11,18},{20,20}},{{14,14},{17,17}}, + {{21,11},{30,13}},{{21,14},{23,17}},{{28,14},{30,17}},{{21,18},{30,20}},{{24,14},{27,17}}, + {{ 1,21},{10,23}},{{ 1,24},{ 3,27}},{{ 8,24},{10,27}},{{ 1,28},{10,30}},{{ 4,24},{ 7,27}}, + {{11,21},{20,23}},{{11,24},{13,27}},{{18,24},{20,27}},{{11,28},{20,30}},{{14,24},{17,27}}, + {{21,21},{30,23}},{{21,24},{23,27}},{{28,24},{30,27}},{{21,28},{30,30}},{{24,24},{27,27}}, + {{ 6, 6},{15, 8}},{{ 6, 9},{ 8,12}},{{13, 9},{15,12}},{{ 6,13},{15,15}},{{ 9, 9},{12,12}}, + {{16, 6},{25, 8}},{{16, 9},{18,12}},{{23, 9},{25,12}},{{16,13},{25,15}},{{19, 9},{22,12}}, + {{ 6,16},{15,18}},{{ 6,19},{ 8,22}},{{13,19},{15,22}},{{ 6,23},{15,25}},{{ 9,19},{12,22}}, + {{16,16},{25,18}},{{16,19},{18,22}},{{23,19},{25,22}},{{16,23},{25,25}},{{19,19},{22,22}}, + {{ 6, 1},{15, 3}},{{ 6, 4},{ 8, 7}},{{13, 4},{15, 7}},{{ 6, 8},{15,10}},{{ 9, 4},{12, 7}}, + {{16, 1},{25, 3}},{{16, 4},{18, 7}},{{23, 4},{25, 7}},{{16, 8},{25,10}},{{19, 4},{22, 7}}, + {{ 1, 6},{10, 8}},{{ 1, 9},{ 3,12}},{{ 8, 9},{10,12}},{{ 1,13},{10,15}},{{ 4, 9},{ 7,12}}, + {{11, 6},{20, 8}},{{11, 9},{13,12}},{{18, 9},{20,12}},{{11,13},{20,15}},{{14, 9},{17,12}}, + {{21, 6},{30, 8}},{{21, 9},{23,12}},{{28, 9},{30,12}},{{21,13},{30,15}},{{24, 9},{27,12}}, + {{ 6,11},{15,13}},{{ 6,14},{ 8,17}},{{13,14},{15,17}},{{ 6,18},{15,20}},{{ 9,14},{12,17}}, + {{16,11},{25,13}},{{16,14},{18,17}},{{23,14},{25,17}},{{16,18},{25,20}},{{19,14},{22,17}}, + {{ 1,16},{10,18}},{{ 1,19},{ 3,22}},{{ 8,19},{10,22}},{{ 1,23},{10,25}},{{ 4,19},{ 7,22}}, + {{11,16},{20,18}},{{11,19},{13,22}},{{18,19},{20,22}},{{11,23},{20,25}},{{14,19},{17,22}}, + {{21,16},{30,18}},{{21,19},{23,22}},{{28,19},{30,22}},{{21,23},{30,25}},{{24,19},{27,22}}, + {{ 6,21},{15,23}},{{ 6,24},{ 8,27}},{{13,24},{15,27}},{{ 6,28},{15,30}},{{ 9,24},{12,27}}, + {{16,21},{25,23}},{{16,24},{18,27}},{{23,24},{25,27}},{{16,28},{25,30}},{{19,24},{22,27}}, + {{ 2, 2},{14, 6}},{{ 2, 7},{ 6, 9}},{{10, 7},{14, 9}},{{ 2,10},{14,14}},{{ 7, 7},{ 9, 9}}, + {{ 7, 2},{19, 6}},{{ 7, 7},{11, 9}},{{15, 7},{19, 9}},{{ 7,10},{19,14}},{{12, 7},{14, 9}}, + {{12, 2},{24, 6}},{{12, 7},{16, 9}},{{20, 7},{24, 9}},{{12,10},{24,14}},{{17, 7},{19, 9}}, + {{17, 2},{29, 6}},{{17, 7},{21, 9}},{{25, 7},{29, 9}},{{17,10},{29,14}},{{22, 7},{24, 9}}, + {{ 2, 7},{14,11}},{{ 2,12},{ 6,14}},{{10,12},{14,14}},{{ 2,15},{14,19}},{{ 7,12},{ 9,14}}, + {{ 7, 7},{19,11}},{{ 7,12},{11,14}},{{15,12},{19,14}},{{ 7,15},{19,19}},{{12,12},{14,14}}, + {{12, 7},{24,11}},{{12,12},{16,14}},{{20,12},{24,14}},{{12,15},{24,19}},{{17,12},{19,14}}, + {{17, 7},{29,11}},{{17,12},{21,14}},{{25,12},{29,14}},{{17,15},{29,19}},{{22,12},{24,14}}, + {{ 2,12},{14,16}},{{ 2,17},{ 6,19}},{{10,17},{14,19}},{{ 2,20},{14,24}},{{ 7,17},{ 9,19}}, + {{ 7,12},{19,16}},{{ 7,17},{11,19}},{{15,17},{19,19}},{{ 7,20},{19,24}},{{12,17},{14,19}}, + {{12,12},{24,16}},{{12,17},{16,19}},{{20,17},{24,19}},{{12,20},{24,24}},{{17,17},{19,19}}, + {{17,12},{29,16}},{{17,17},{21,19}},{{25,17},{29,19}},{{17,20},{29,24}},{{22,17},{24,19}}, + {{ 2,17},{14,21}},{{ 2,22},{ 6,24}},{{10,22},{14,24}},{{ 2,25},{14,29}},{{ 7,22},{ 9,24}}, + {{ 7,17},{19,21}},{{ 7,22},{11,24}},{{15,22},{19,24}},{{ 7,25},{19,29}},{{12,22},{14,24}}, + {{12,17},{24,21}},{{12,22},{16,24}},{{20,22},{24,24}},{{12,25},{24,29}},{{17,22},{19,24}}, + {{17,17},{29,21}},{{17,22},{21,24}},{{25,22},{29,24}},{{17,25},{29,29}},{{22,22},{24,24}}, + {{ 8, 3},{13, 4}},{{ 8, 5},{ 9, 6}},{{12, 5},{13, 6}},{{ 8, 7},{13, 8}},{{10, 5},{11, 6}}, + {{13, 3},{18, 4}},{{13, 5},{14, 6}},{{17, 5},{18, 6}},{{13, 7},{18, 8}},{{15, 5},{16, 6}}, + {{18, 3},{23, 4}},{{18, 5},{19, 6}},{{22, 5},{23, 6}},{{18, 7},{23, 8}},{{20, 5},{21, 6}}, + {{ 3, 8},{ 8, 9}},{{ 3,10},{ 4,11}},{{ 7,10},{ 8,11}},{{ 3,12},{ 8,13}},{{ 5,10},{ 6,11}}, + {{ 8, 8},{13, 9}},{{ 8,10},{ 9,11}},{{12,10},{13,11}},{{ 8,12},{13,13}},{{10,10},{11,11}}, + {{13, 8},{18, 9}},{{13,10},{14,11}},{{17,10},{18,11}},{{13,12},{18,13}},{{15,10},{16,11}}, + {{18, 8},{23, 9}},{{18,10},{19,11}},{{22,10},{23,11}},{{18,12},{23,13}},{{20,10},{21,11}}, + {{23, 8},{28, 9}},{{23,10},{24,11}},{{27,10},{28,11}},{{23,12},{28,13}},{{25,10},{26,11}}, + {{ 3,13},{ 8,14}},{{ 3,15},{ 4,16}},{{ 7,15},{ 8,16}},{{ 3,17},{ 8,18}},{{ 5,15},{ 6,16}}, + {{ 8,13},{13,14}},{{ 8,15},{ 9,16}},{{12,15},{13,16}},{{ 8,17},{13,18}},{{10,15},{11,16}}, + {{13,13},{18,14}},{{13,15},{14,16}},{{17,15},{18,16}},{{13,17},{18,18}},{{15,15},{16,16}}, + {{18,13},{23,14}},{{18,15},{19,16}},{{22,15},{23,16}},{{18,17},{23,18}},{{20,15},{21,16}}, + {{23,13},{28,14}},{{23,15},{24,16}},{{27,15},{28,16}},{{23,17},{28,18}},{{25,15},{26,16}}, + {{ 3,18},{ 8,19}},{{ 3,20},{ 4,21}},{{ 7,20},{ 8,21}},{{ 3,22},{ 8,23}},{{ 5,20},{ 6,21}}, + {{ 8,18},{13,19}},{{ 8,20},{ 9,21}},{{12,20},{13,21}},{{ 8,22},{13,23}},{{10,20},{11,21}}, + {{13,18},{18,19}},{{13,20},{14,21}},{{17,20},{18,21}},{{13,22},{18,23}},{{15,20},{16,21}}, + {{18,18},{23,19}},{{18,20},{19,21}},{{22,20},{23,21}},{{18,22},{23,23}},{{20,20},{21,21}}, + {{23,18},{28,19}},{{23,20},{24,21}},{{27,20},{28,21}},{{23,22},{28,23}},{{25,20},{26,21}}, + {{ 8,23},{13,24}},{{ 8,25},{ 9,26}},{{12,25},{13,26}},{{ 8,27},{13,28}},{{10,25},{11,26}}, + {{13,23},{18,24}},{{13,25},{14,26}},{{17,25},{18,26}},{{13,27},{18,28}},{{15,25},{16,26}}, + {{18,23},{23,24}},{{18,25},{19,26}},{{22,25},{23,26}},{{18,27},{23,28}},{{20,25},{21,26}} +}; +static const ElemCat elem_d5 = { 0, 4, 5, 62, elem_d5_data }; + +static const Block elem_d6_data[] = { + {{ 3, 5},{12,10}},{{ 5, 3},{10,12}}, + {{11, 5},{20,10}},{{13, 3},{18,12}}, + {{19, 5},{28,10}},{{21, 3},{26,12}}, + {{ 3,13},{12,18}},{{ 5,11},{10,20}}, + {{11,13},{20,18}},{{13,11},{18,20}}, + {{19,13},{28,18}},{{21,11},{26,20}}, + {{ 3,21},{12,26}},{{ 5,19},{10,28}}, + {{11,21},{20,26}},{{13,19},{18,28}}, + {{19,21},{28,26}},{{21,19},{26,28}} +}; +static const ElemCat elem_d6 = { 0, 1, 2, 9, elem_d6_data }; + +static const Block elem_d7_data[] = { + {{ 0, 4},{ 3, 7}},{{ 8, 4},{11, 7}},{{ 4, 4},{ 7, 7}}, + {{ 4, 0},{ 7, 3}},{{ 4, 8},{ 7,11}},{{ 4, 4},{ 7, 7}}, + {{ 5, 4},{ 8, 7}},{{13, 4},{16, 7}},{{ 9, 4},{12, 7}}, + {{ 9, 0},{12, 3}},{{ 9, 8},{12,11}},{{ 9, 4},{12, 7}}, + {{10, 4},{13, 7}},{{18, 4},{21, 7}},{{14, 4},{17, 7}}, + {{14, 0},{17, 3}},{{14, 8},{17,11}},{{14, 4},{17, 7}}, + {{15, 4},{18, 7}},{{23, 4},{26, 7}},{{19, 4},{22, 7}}, + {{19, 0},{22, 3}},{{19, 8},{22,11}},{{19, 4},{22, 7}}, + {{20, 4},{23, 7}},{{28, 4},{31, 7}},{{24, 4},{27, 7}}, + {{24, 0},{27, 3}},{{24, 8},{27,11}},{{24, 4},{27, 7}}, + {{ 0, 9},{ 3,12}},{{ 8, 9},{11,12}},{{ 4, 9},{ 7,12}}, + {{ 4, 5},{ 7, 8}},{{ 4,13},{ 7,16}},{{ 4, 9},{ 7,12}}, + {{ 5, 9},{ 8,12}},{{13, 9},{16,12}},{{ 9, 9},{12,12}}, + {{ 9, 5},{12, 8}},{{ 9,13},{12,16}},{{ 9, 9},{12,12}}, + {{10, 9},{13,12}},{{18, 9},{21,12}},{{14, 9},{17,12}}, + {{14, 5},{17, 8}},{{14,13},{17,16}},{{14, 9},{17,12}}, + {{15, 9},{18,12}},{{23, 9},{26,12}},{{19, 9},{22,12}}, + {{19, 5},{22, 8}},{{19,13},{22,16}},{{19, 9},{22,12}}, + {{20, 9},{23,12}},{{28, 9},{31,12}},{{24, 9},{27,12}}, + {{24, 5},{27, 8}},{{24,13},{27,16}},{{24, 9},{27,12}}, + {{ 0,14},{ 3,17}},{{ 8,14},{11,17}},{{ 4,14},{ 7,17}}, + {{ 4,10},{ 7,13}},{{ 4,18},{ 7,21}},{{ 4,14},{ 7,17}}, + {{ 5,14},{ 8,17}},{{13,14},{16,17}},{{ 9,14},{12,17}}, + {{ 9,10},{12,13}},{{ 9,18},{12,21}},{{ 9,14},{12,17}}, + {{10,14},{13,17}},{{18,14},{21,17}},{{14,14},{17,17}}, + {{14,10},{17,13}},{{14,18},{17,21}},{{14,14},{17,17}}, + {{15,14},{18,17}},{{23,14},{26,17}},{{19,14},{22,17}}, + {{19,10},{22,13}},{{19,18},{22,21}},{{19,14},{22,17}}, + {{20,14},{23,17}},{{28,14},{31,17}},{{24,14},{27,17}}, + {{24,10},{27,13}},{{24,18},{27,21}},{{24,14},{27,17}}, + {{ 0,19},{ 3,22}},{{ 8,19},{11,22}},{{ 4,19},{ 7,22}}, + {{ 4,15},{ 7,18}},{{ 4,23},{ 7,26}},{{ 4,19},{ 7,22}}, + {{ 5,19},{ 8,22}},{{13,19},{16,22}},{{ 9,19},{12,22}}, + {{ 9,15},{12,18}},{{ 9,23},{12,26}},{{ 9,19},{12,22}}, + {{10,19},{13,22}},{{18,19},{21,22}},{{14,19},{17,22}}, + {{14,15},{17,18}},{{14,23},{17,26}},{{14,19},{17,22}}, + {{15,19},{18,22}},{{23,19},{26,22}},{{19,19},{22,22}}, + {{19,15},{22,18}},{{19,23},{22,26}},{{19,19},{22,22}}, + {{20,19},{23,22}},{{28,19},{31,22}},{{24,19},{27,22}}, + {{24,15},{27,18}},{{24,23},{27,26}},{{24,19},{27,22}}, + {{ 0,24},{ 3,27}},{{ 8,24},{11,27}},{{ 4,24},{ 7,27}}, + {{ 4,20},{ 7,23}},{{ 4,28},{ 7,31}},{{ 4,24},{ 7,27}}, + {{ 5,24},{ 8,27}},{{13,24},{16,27}},{{ 9,24},{12,27}}, + {{ 9,20},{12,23}},{{ 9,28},{12,31}},{{ 9,24},{12,27}}, + {{10,24},{13,27}},{{18,24},{21,27}},{{14,24},{17,27}}, + {{14,20},{17,23}},{{14,28},{17,31}},{{14,24},{17,27}}, + {{15,24},{18,27}},{{23,24},{26,27}},{{19,24},{22,27}}, + {{19,20},{22,23}},{{19,28},{22,31}},{{19,24},{22,27}}, + {{20,24},{23,27}},{{28,24},{31,27}},{{24,24},{27,27}}, + {{24,20},{27,23}},{{24,28},{27,31}},{{24,24},{27,27}} +}; +static const ElemCat elem_d7 = { 0, 2, 3, 50, elem_d7_data }; + +static const Block elem_d8_data[] = { + {{ 0, 0},{ 7, 3}},{{ 0, 4},{ 7, 7}}, + {{ 8, 0},{11, 7}},{{12, 0},{15, 7}}, + {{ 0, 8},{ 3,15}},{{ 4, 8},{ 7,15}}, + {{ 8, 8},{15,11}},{{ 8,12},{15,15}}, + {{16, 0},{19, 7}},{{20, 0},{23, 7}}, + {{24, 0},{31, 3}},{{24, 4},{31, 7}}, + {{16, 8},{23,11}},{{16,12},{23,15}}, + {{24, 8},{27,15}},{{28, 8},{31,15}}, + {{ 0,16},{ 3,23}},{{ 4,16},{ 7,23}}, + {{ 8,16},{15,19}},{{ 8,20},{15,23}}, + {{ 0,24},{ 7,27}},{{ 0,28},{ 7,31}}, + {{ 8,24},{11,31}},{{12,24},{15,31}}, + {{16,16},{23,19}},{{16,20},{23,23}}, + {{24,16},{27,23}},{{28,16},{31,23}}, + {{16,24},{19,31}},{{20,24},{23,31}}, + {{24,24},{31,27}},{{24,28},{31,31}}, + {{ 0, 0},{ 7,15}},{{ 8, 0},{15,15}}, + {{16, 0},{31, 7}},{{16, 8},{31,15}}, + {{ 0,16},{15,23}},{{ 0,24},{15,31}}, + {{16,16},{23,31}},{{24,16},{31,31}} +}; +static const ElemCat elem_d8 = { 0, 1, 2, 20, elem_d8_data }; + +static const ElemCat* elements[ELEMENT_COUNT] = { &elem_a1, &elem_a2, + &elem_d1, &elem_d2, &elem_d3, &elem_d4, + &elem_d5, &elem_d6, &elem_d7, &elem_d8 }; +#endif /* AVFILTER_SIGNATURE_H */ diff --git a/libavfilter/signature_lookup.c b/libavfilter/signature_lookup.c new file mode 100644 index 0000000000000..5bc2904409866 --- /dev/null +++ b/libavfilter/signature_lookup.c @@ -0,0 +1,573 @@ +/* + * Copyright (c) 2017 Gerion Entrup + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU 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. + */ + +/** + * @file + * MPEG-7 video signature calculation and lookup filter + */ + +#include "signature.h" + +#define HOUGH_MAX_OFFSET 90 +#define MAX_FRAMERATE 60 + +#define DIR_PREV 0 +#define DIR_NEXT 1 +#define DIR_PREV_END 2 +#define DIR_NEXT_END 3 + +#define STATUS_NULL 0 +#define STATUS_END_REACHED 1 +#define STATUS_BEGIN_REACHED 2 + +static void fill_l1distlut(uint8_t lut[]) +{ + int i, j, tmp_i, tmp_j,count; + uint8_t dist; + + for (i = 0, count = 0; i < 242; i++) { + for (j = i + 1; j < 243; j++, count++) { + /* ternary distance between i and j */ + dist = 0; + tmp_i = i; tmp_j = j; + do { + dist += FFABS((tmp_j % 3) - (tmp_i % 3)); + tmp_j /= 3; + tmp_i /= 3; + } while (tmp_i > 0 || tmp_j > 0); + lut[count] = dist; + } + } +} + +static unsigned int intersection_word(const uint8_t *first, const uint8_t *second) +{ + unsigned int val=0,i; + for (i = 0; i < 28; i += 4) { + val += av_popcount( (first[i] & second[i] ) << 24 | + (first[i+1] & second[i+1]) << 16 | + (first[i+2] & second[i+2]) << 8 | + (first[i+3] & second[i+3]) ); + } + val += av_popcount( (first[28] & second[28]) << 16 | + (first[29] & second[29]) << 8 | + (first[30] & second[30]) ); + return val; +} + +static unsigned int union_word(const uint8_t *first, const uint8_t *second) +{ + unsigned int val=0,i; + for (i = 0; i < 28; i += 4) { + val += av_popcount( (first[i] | second[i] ) << 24 | + (first[i+1] | second[i+1]) << 16 | + (first[i+2] | second[i+2]) << 8 | + (first[i+3] | second[i+3]) ); + } + val += av_popcount( (first[28] | second[28]) << 16 | + (first[29] | second[29]) << 8 | + (first[30] | second[30]) ); + return val; +} + +static unsigned int get_l1dist(AVFilterContext *ctx, SignatureContext *sc, const uint8_t *first, const uint8_t *second) +{ + unsigned int i; + unsigned int dist = 0; + uint8_t f, s; + + for (i = 0; i < SIGELEM_SIZE/5; i++) { + if (first[i] != second[i]) { + f = first[i]; + s = second[i]; + if (f > s) { + /* little variation of gauss sum formula */ + dist += sc->l1distlut[243*242/2 - (243-s)*(242-s)/2 + f - s - 1]; + } else { + dist += sc->l1distlut[243*242/2 - (243-f)*(242-f)/2 + s - f - 1]; + } + } + } + return dist; +} + +/** + * calculates the jaccard distance and evaluates a pair of coarse signatures as good + * @return 0 if pair is bad, 1 otherwise + */ +static int get_jaccarddist(SignatureContext *sc, CoarseSignature *first, CoarseSignature *second) +{ + int jaccarddist, i, composdist = 0, cwthcount = 0; + for (i = 0; i < 5; i++) { + if ((jaccarddist = intersection_word(first->data[i], second->data[i])) > 0) { + jaccarddist /= union_word(first->data[i], second->data[i]); + } + if (jaccarddist >= sc->thworddist) { + if (++cwthcount > 2) { + /* more than half (5/2) of distances are too wide */ + return 0; + } + } + composdist += jaccarddist; + if (composdist > sc->thcomposdist) { + return 0; + } + } + return 1; +} + +/** + * step through the coarsesignatures as long as a good candidate is found + * @return 0 if no candidate is found, 1 otherwise + */ +static int find_next_coarsecandidate(SignatureContext *sc, CoarseSignature *secondstart, CoarseSignature **first, CoarseSignature **second, int start) +{ + /* go one coarsesignature foreword */ + if (!start) { + if ((*second)->next) { + *second = (*second)->next; + } else if ((*first)->next) { + *second = secondstart; + *first = (*first)->next; + } else { + return 0; + } + } + + while (1) { + if (get_jaccarddist(sc, *first, *second)) + return 1; + + /* next signature */ + if ((*second)->next) { + *second = (*second)->next; + } else if ((*first)->next) { + *second = secondstart; + *first = (*first)->next; + } else { + return 0; + } + } +} + +/** + * compares framesignatures and sorts out signatures with a l1 distance above a given threshold. + * Then tries to find out offset and differences between framerates with a hough transformation + */ +static MatchingInfo* get_matching_parameters(AVFilterContext *ctx, SignatureContext *sc, FineSignature *first, FineSignature *second) +{ + FineSignature *f, *s; + size_t i, j, k, l, hmax = 0, score; + int framerate, offset, l1dist; + double m; + MatchingInfo *cands = NULL, *c = NULL; + + struct { + uint8_t size; + unsigned int dist; + FineSignature *a; + uint8_t b_pos[COARSE_SIZE]; + FineSignature *b[COARSE_SIZE]; + } pairs[COARSE_SIZE]; + + typedef struct { + int dist; + size_t score; + FineSignature *a; + FineSignature *b; + } hspace_elem; + + /* houghspace */ + hspace_elem** hspace = av_malloc_array(MAX_FRAMERATE, sizeof(hspace_elem *)); + + /* initialize houghspace */ + for (i = 0; i < MAX_FRAMERATE; i++) { + hspace[i] = av_malloc_array(2 * HOUGH_MAX_OFFSET + 1, sizeof(hspace_elem)); + for (j = 0; j < HOUGH_MAX_OFFSET; j++) { + hspace[i][j].score = 0; + hspace[i][j].dist = 99999; + } + } + + /* l1 distances */ + for (i = 0, f = first; i < COARSE_SIZE && f->next; i++, f = f->next) { + pairs[i].size = 0; + pairs[i].dist = 99999; + pairs[i].a = f; + for (j = 0, s = second; j < COARSE_SIZE && s->next; j++, s = s->next) { + /* l1 distance of finesignature */ + l1dist = get_l1dist(ctx, sc, f->framesig, s->framesig); + if (l1dist < sc->thl1) { + if (l1dist < pairs[i].dist) { + pairs[i].size = 1; + pairs[i].dist = l1dist; + pairs[i].b_pos[0] = j; + pairs[i].b[0] = s; + } else if (l1dist == pairs[i].dist) { + pairs[i].b[pairs[i].size] = s; + pairs[i].b_pos[pairs[i].size] = j; + pairs[i].size++; + } + } + } + } + /* last incomplete coarsesignature */ + if (f->next == NULL) { + for (; i < COARSE_SIZE; i++) { + pairs[i].size = 0; + pairs[i].dist = 99999; + } + } + + /* hough transformation */ + for (i = 0; i < COARSE_SIZE; i++) { + for (j = 0; j < pairs[i].size; j++) { + for (k = i + 1; k < COARSE_SIZE; k++) { + for (l = 0; l < pairs[k].size; l++) { + if (pairs[i].b[j] != pairs[k].b[l]) { + /* linear regression */ + m = (pairs[k].b_pos[l]-pairs[i].b_pos[j]) / (k-i); /* good value between 0.0 - 2.0 */ + framerate = (int) m*30 + 0.5; /* round up to 0 - 60 */ + if (framerate>0 && framerate <= MAX_FRAMERATE) { + offset = pairs[i].b_pos[j] - ((int) m*i + 0.5); /* only second part has to be rounded up */ + if (offset > -HOUGH_MAX_OFFSET && offset < HOUGH_MAX_OFFSET) { + if (pairs[i].dist < pairs[k].dist) { + if (pairs[i].dist < hspace[framerate-1][offset+HOUGH_MAX_OFFSET].dist) { + hspace[framerate-1][offset+HOUGH_MAX_OFFSET].dist = pairs[i].dist; + hspace[framerate-1][offset+HOUGH_MAX_OFFSET].a = pairs[i].a; + hspace[framerate-1][offset+HOUGH_MAX_OFFSET].b = pairs[i].b[j]; + } + } else { + if (pairs[k].dist < hspace[framerate-1][offset+HOUGH_MAX_OFFSET].dist) { + hspace[framerate-1][offset+HOUGH_MAX_OFFSET].dist = pairs[k].dist; + hspace[framerate-1][offset+HOUGH_MAX_OFFSET].a = pairs[k].a; + hspace[framerate-1][offset+HOUGH_MAX_OFFSET].b = pairs[k].b[l]; + } + } + + score = hspace[framerate-1][offset+HOUGH_MAX_OFFSET].score + 1; + if (score > hmax ) + hmax = score; + hspace[framerate-1][offset+HOUGH_MAX_OFFSET].score = score; + } + } + } + } + } + } + } + + if (hmax > 0) { + hmax = (int) (0.7*hmax); + for (i = 0; i < MAX_FRAMERATE; i++) { + for (j = 0; j < HOUGH_MAX_OFFSET; j++) { + if (hmax < hspace[i][j].score) { + if (c == NULL) { + c = av_malloc(sizeof(MatchingInfo)); + if (!c) + av_log(ctx, AV_LOG_FATAL, "Could not allocate memory"); + cands = c; + } else { + c->next = av_malloc(sizeof(MatchingInfo)); + if (!c->next) + av_log(ctx, AV_LOG_FATAL, "Could not allocate memory"); + c = c->next; + } + c->framerateratio = (i+1.0) / 30; + c->score = hspace[i][j].score; + c->offset = j-90; + c->first = hspace[i][j].a; + c->second = hspace[i][j].b; + c->next = NULL; + + /* not used */ + c->meandist = 0; + c->matchframes = 0; + c->whole = 0; + } + } + } + } + for (i = 0; i < MAX_FRAMERATE; i++) { + av_freep(&hspace[i]); + } + av_freep(&hspace); + return cands; +} + +static int iterate_frame(double frr, FineSignature **a, FineSignature **b, int fcount, int *bcount, int dir) +{ + int step; + + /* between 1 and 2, because frr is between 1 and 2 */ + step = ((int) 0.5 + fcount * frr) /* current frame */ + -((int) 0.5 + (fcount-1) * frr);/* last frame */ + + if (dir == DIR_NEXT) { + if (frr >= 1.0) { + if ((*a)->next) { + *a = (*a)->next; + } else { + return DIR_NEXT_END; + } + + if (step == 1) { + if ((*b)->next) { + *b = (*b)->next; + (*bcount)++; + } else { + return DIR_NEXT_END; + } + } else { + if ((*b)->next && (*b)->next->next) { + *b = (*b)->next->next; + (*bcount)++; + } else { + return DIR_NEXT_END; + } + } + } else { + if ((*b)->next) { + *b = (*b)->next; + (*bcount)++; + } else { + return DIR_NEXT_END; + } + + if (step == 1) { + if ((*a)->next) { + *a = (*a)->next; + } else { + return DIR_NEXT_END; + } + } else { + if ((*a)->next && (*a)->next->next) { + *a = (*a)->next->next; + } else { + return DIR_NEXT_END; + } + } + } + return DIR_NEXT; + } else { + if (frr >= 1.0) { + if ((*a)->prev) { + *a = (*a)->prev; + } else { + return DIR_PREV_END; + } + + if (step == 1) { + if ((*b)->prev) { + *b = (*b)->prev; + (*bcount)++; + } else { + return DIR_PREV_END; + } + } else { + if ((*b)->prev && (*b)->prev->prev) { + *b = (*b)->prev->prev; + (*bcount)++; + } else { + return DIR_PREV_END; + } + } + } else { + if ((*b)->prev) { + *b = (*b)->prev; + (*bcount)++; + } else { + return DIR_PREV_END; + } + + if (step == 1) { + if ((*a)->prev) { + *a = (*a)->prev; + } else { + return DIR_PREV_END; + } + } else { + if ((*a)->prev && (*a)->prev->prev) { + *a = (*a)->prev->prev; + } else { + return DIR_PREV_END; + } + } + } + return DIR_PREV; + } +} + +static MatchingInfo evaluate_parameters(AVFilterContext *ctx, SignatureContext *sc, MatchingInfo *infos, MatchingInfo bestmatch, int mode) +{ + int dist, distsum = 0, bcount = 1, dir = DIR_NEXT; + int fcount = 0, goodfcount = 0, gooda = 0, goodb = 0; + double meandist, minmeandist = bestmatch.meandist; + int tolerancecount = 0; + FineSignature *a, *b, *aprev, *bprev; + int status = STATUS_NULL; + + for (; infos != NULL; infos = infos->next) { + a = infos->first; + b = infos->second; + while (1) { + dist = get_l1dist(ctx, sc, a->framesig, b->framesig); + + if (dist > sc->thl1) { + if (a->confidence >= 1 || b->confidence >= 1) { + /* bad frame (because high different information) */ + tolerancecount++; + } + + if (tolerancecount > 2) { + a = aprev; + b = bprev; + if (dir == DIR_NEXT) { + /* turn around */ + a = infos->first; + b = infos->second; + dir = DIR_PREV; + } else { + break; + } + } + } else { + /* good frame */ + distsum += dist; + goodfcount++; + tolerancecount=0; + + aprev = a; + bprev = b; + + if (a->confidence < 1) gooda++; + if (b->confidence < 1) goodb++; + } + + fcount++; + + dir = iterate_frame(infos->framerateratio, &a, &b, fcount, &bcount, dir); + if (dir == DIR_NEXT_END) { + status = STATUS_END_REACHED; + a = infos->first; + b = infos->second; + dir = iterate_frame(infos->framerateratio, &a, &b, fcount, &bcount, DIR_PREV); + } + + if (dir == DIR_PREV_END) { + status |= STATUS_BEGIN_REACHED; + break; + } + + if (sc->thdi != 0 && bcount >= sc->thdi) { + break; /* enough frames found */ + } + } + + if (bcount < sc->thdi) + continue; /* matching sequence is too short */ + if ((double) goodfcount / (double) fcount < sc->thit) + continue; + if ((double) goodfcount*0.5 < FFMAX(gooda, goodb)) + continue; + + meandist = (double) goodfcount / (double) distsum; + + if (meandist < minmeandist || + status == STATUS_END_REACHED | STATUS_BEGIN_REACHED || + mode == MODE_FAST){ + minmeandist = meandist; + /* bestcandidate in this iteration */ + bestmatch.meandist = meandist; + bestmatch.matchframes = bcount; + bestmatch.framerateratio = infos->framerateratio; + bestmatch.score = infos->score; + bestmatch.offset = infos->offset; + bestmatch.first = infos->first; + bestmatch.second = infos->second; + bestmatch.whole = 0; /* will be set to true later */ + bestmatch.next = NULL; + } + + /* whole sequence is automatically best match */ + if (status == (STATUS_END_REACHED | STATUS_BEGIN_REACHED)) { + bestmatch.whole = 1; + break; + } + + /* first matching sequence is enough, finding the best one is not necessary */ + if (mode == MODE_FAST) { + break; + } + } + return bestmatch; +} + +static void sll_free(MatchingInfo *sll) +{ + void *tmp; + while (sll) { + tmp = sll; + sll = sll->next; + av_freep(&tmp); + } +} + +static MatchingInfo lookup_signatures(AVFilterContext *ctx, SignatureContext *sc, StreamContext *first, StreamContext *second, int mode) +{ + CoarseSignature *cs, *cs2; + MatchingInfo *infos; + MatchingInfo bestmatch; + MatchingInfo *i; + + cs = first->coarsesiglist; + cs2 = second->coarsesiglist; + + /* score of bestmatch is 0, if no match is found */ + bestmatch.score = 0; + bestmatch.meandist = 99999; + bestmatch.whole = 0; + + fill_l1distlut(sc->l1distlut); + + /* stage 1: coarsesignature matching */ + if (find_next_coarsecandidate(sc, second->coarsesiglist, &cs, &cs2, 1) == 0) + return bestmatch; /* no candidate found */ + do { + av_log(ctx, AV_LOG_DEBUG, "Stage 1: got coarsesignature pair. indices of first frame: %d and %d\n", cs->first->index, cs2->first->index); + /* stage 2: l1-distance and hough-transform */ + av_log(ctx, AV_LOG_DEBUG, "Stage 2: calculate matching parameters\n"); + infos = get_matching_parameters(ctx, sc, cs->first, cs2->first); + if (av_log_get_level() == AV_LOG_DEBUG) { + for (i = infos; i != NULL; i = i->next) { + av_log(ctx, AV_LOG_DEBUG, "Stage 2: matching pair at %d and %d, ratio %f, offset %d\n", i->first->index, i->second->index, i->framerateratio, i->offset); + } + } + /* stage 3: evaluation */ + av_log(ctx, AV_LOG_DEBUG, "Stage 3: evaluate\n"); + if (infos) { + bestmatch = evaluate_parameters(ctx, sc, infos, bestmatch, mode); + av_log(ctx, AV_LOG_DEBUG, "Stage 3: best matching pair at %d and %d, ratio %f, offset %d, score %d, %d frames matching\n", bestmatch.first->index, bestmatch.second->index, bestmatch.framerateratio, bestmatch.offset, bestmatch.score, bestmatch.matchframes); + sll_free(infos); + } + } while (find_next_coarsecandidate(sc, second->coarsesiglist, &cs, &cs2, 0) && !bestmatch.whole); + return bestmatch; + +} diff --git a/libavfilter/version.h b/libavfilter/version.h index c2684bfe94367..a61ca32712351 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 6 -#define LIBAVFILTER_VERSION_MINOR 77 +#define LIBAVFILTER_VERSION_MINOR 78 #define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vf_signature.c b/libavfilter/vf_signature.c new file mode 100644 index 0000000000000..57cb96b6c4185 --- /dev/null +++ b/libavfilter/vf_signature.c @@ -0,0 +1,767 @@ +/* + * Copyright (c) 2017 Gerion Entrup + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU 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. + */ + +/** + * @file + * MPEG-7 video signature calculation and lookup filter + * @see http://epubs.surrey.ac.uk/531590/1/MPEG-7%20Video%20Signature%20Author%27s%20Copy.pdf + */ + +#include +#include "libavcodec/put_bits.h" +#include "libavformat/avformat.h" +#include "libavutil/opt.h" +#include "libavutil/avstring.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/timestamp.h" +#include "avfilter.h" +#include "internal.h" +#include "signature.h" +#include "signature_lookup.c" + +#define OFFSET(x) offsetof(SignatureContext, x) +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM +#define BLOCK_LCM (int64_t) 476985600 + +static const AVOption signature_options[] = { + { "detectmode", "set the detectmode", + OFFSET(mode), AV_OPT_TYPE_INT, {.i64 = MODE_OFF}, 0, NB_LOOKUP_MODE-1, FLAGS, "mode" }, + { "off", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = MODE_OFF}, 0, 0, .flags = FLAGS, "mode" }, + { "full", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = MODE_FULL}, 0, 0, .flags = FLAGS, "mode" }, + { "fast", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = MODE_FAST}, 0, 0, .flags = FLAGS, "mode" }, + { "nb_inputs", "number of inputs", + OFFSET(nb_inputs), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, FLAGS }, + { "filename", "filename for output files", + OFFSET(filename), AV_OPT_TYPE_STRING, {.str = ""}, 0, NB_FORMATS-1, FLAGS }, + { "format", "set output format", + OFFSET(format), AV_OPT_TYPE_INT, {.i64 = FORMAT_BINARY}, 0, 1, FLAGS , "format" }, + { "binary", 0, 0, AV_OPT_TYPE_CONST, {.i64=FORMAT_BINARY}, 0, 0, FLAGS, "format" }, + { "xml", 0, 0, AV_OPT_TYPE_CONST, {.i64=FORMAT_XML}, 0, 0, FLAGS, "format" }, + { "th_d", "threshold to detect one word as similar", + OFFSET(thworddist), AV_OPT_TYPE_INT, {.i64 = 9000}, 1, INT_MAX, FLAGS }, + { "th_dc", "threshold to detect all words as similar", + OFFSET(thcomposdist), AV_OPT_TYPE_INT, {.i64 = 60000}, 1, INT_MAX, FLAGS }, + { "th_xh", "threshold to detect frames as similar", + OFFSET(thl1), AV_OPT_TYPE_INT, {.i64 = 116}, 1, INT_MAX, FLAGS }, + { "th_di", "minimum length of matching sequence in frames", + OFFSET(thdi), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS }, + { "th_it", "threshold for relation of good to all frames", + OFFSET(thit), AV_OPT_TYPE_DOUBLE, {.dbl = 0.5}, 0.0, 1.0, FLAGS }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(signature); + +static int query_formats(AVFilterContext *ctx) +{ + /* all formats with a seperate gray value */ + static const enum AVPixelFormat pix_fmts[] = { + AV_PIX_FMT_GRAY8, + AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, + AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUVJ420P, + AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, + AV_PIX_FMT_YUVJ440P, + AV_PIX_FMT_NV12, AV_PIX_FMT_NV21, + AV_PIX_FMT_NONE + }; + + return ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); +} + +static int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + SignatureContext *sic = ctx->priv; + StreamContext *sc = &(sic->streamcontexts[FF_INLINK_IDX(inlink)]); + + sc->time_base = inlink->time_base; + /* test for overflow */ + sc->divide = (((uint64_t) inlink->w/32) * (inlink->w/32 + 1) * (inlink->h/32 * inlink->h/32 + 1) > INT64_MAX / (BLOCK_LCM * 255)); + if (sc->divide) { + av_log(ctx, AV_LOG_WARNING, "Input dimension too high for precise calculation, numbers will be rounded.\n"); + } + sc->w = inlink->w; + sc->h = inlink->h; + return 0; +} + +static int get_block_size(const Block *b) +{ + return (b->to.y - b->up.y + 1) * (b->to.x - b->up.x + 1); +} + +static uint64_t get_block_sum(StreamContext *sc, uint64_t intpic[32][32], const Block *b) +{ + uint64_t sum = 0; + + int x0, y0, x1, y1; + + x0 = b->up.x; + y0 = b->up.y; + x1 = b->to.x; + y1 = b->to.y; + + if (x0-1 >= 0 && y0-1 >= 0) { + sum = intpic[y1][x1] + intpic[y0-1][x0-1] - intpic[y1][x0-1] - intpic[y0-1][x1]; + } else if (x0-1 >= 0) { + sum = intpic[y1][x1] - intpic[y1][x0-1]; + } else if (y0-1 >= 0) { + sum = intpic[y1][x1] - intpic[y0-1][x1]; + } else { + sum = intpic[y1][x1]; + } + return sum; +} + +static int cmp(const uint64_t *a, const uint64_t *b) +{ + return *a < *b ? -1 : ( *a > *b ? 1 : 0 ); +} + +/** + * sets the bit at position pos to 1 in data + */ +static void set_bit(uint8_t* data, size_t pos) +{ + uint8_t mask = 1 << 7-(pos%8); + data[pos/8] |= mask; +} + +static int filter_frame(AVFilterLink *inlink, AVFrame *picref) +{ + AVFilterContext *ctx = inlink->dst; + SignatureContext *sic = ctx->priv; + StreamContext *sc = &(sic->streamcontexts[FF_INLINK_IDX(inlink)]); + FineSignature* fs; + + static const uint8_t pot3[5] = { 3*3*3*3, 3*3*3, 3*3, 3, 1 }; + /* indexes of words : 210,217,219,274,334 44,175,233,270,273 57,70,103,237,269 100,285,295,337,354 101,102,111,275,296 + s2usw = sorted to unsorted wordvec: 44 is at index 5, 57 at index 10... + */ + static const unsigned int wordvec[25] = {44,57,70,100,101,102,103,111,175,210,217,219,233,237,269,270,273,274,275,285,295,296,334,337,354}; + static const uint8_t s2usw[25] = { 5,10,11, 15, 20, 21, 12, 22, 6, 0, 1, 2, 7, 13, 14, 8, 9, 3, 23, 16, 17, 24, 4, 18, 19}; + + uint8_t wordt2b[5] = { 0, 0, 0, 0, 0 }; /* word ternary to binary */ + uint64_t intpic[32][32]; + uint64_t rowcount; + uint8_t *p = picref->data[0]; + int inti, intj; + int *intjlut; + + uint64_t conflist[DIFFELEM_SIZE]; + int f = 0, g = 0, w = 0; + int32_t dh1 = 1, dh2 = 1, dw1 = 1, dw2 = 1, a, b; + int64_t denom; + int i, j, k, ternary; + uint64_t blocksum; + int blocksize; + int64_t th; /* threshold */ + int64_t sum; + + int64_t precfactor = (sc->divide) ? 65536 : BLOCK_LCM; + + /* initialize fs */ + if (sc->curfinesig) { + fs = av_mallocz(sizeof(FineSignature)); + if (!fs) + return AVERROR(ENOMEM); + sc->curfinesig->next = fs; + fs->prev = sc->curfinesig; + sc->curfinesig = fs; + } else { + fs = sc->curfinesig = sc->finesiglist; + sc->curcoarsesig1->first = fs; + } + + fs->pts = picref->pts; + fs->index = sc->lastindex++; + + memset(intpic, 0, sizeof(uint64_t)*32*32); + intjlut = av_malloc_array(inlink->w, sizeof(int)); + if (!intjlut) + return AVERROR(ENOMEM); + for (i = 0; i < inlink->w; i++) { + intjlut[i] = (i*32)/inlink->w; + } + + for (i = 0; i < inlink->h; i++) { + inti = (i*32)/inlink->h; + for (j = 0; j < inlink->w; j++) { + intj = intjlut[j]; + intpic[inti][intj] += p[j]; + } + p += picref->linesize[0]; + } + av_freep(&intjlut); + + /* The following calculates a summed area table (intpic) and brings the numbers + * in intpic to the same denominator. + * So you only have to handle the numinator in the following sections. + */ + dh1 = inlink->h / 32; + if (inlink->h % 32) + dh2 = dh1 + 1; + dw1 = inlink->w / 32; + if (inlink->w % 32) + dw2 = dw1 + 1; + denom = (sc->divide) ? dh1 * dh2 * dw1 * dw2 : 1; + + for (i = 0; i < 32; i++) { + rowcount = 0; + a = 1; + if (dh2 > 1) { + a = ((inlink->h*(i+1))%32 == 0) ? (inlink->h*(i+1))/32 - 1 : (inlink->h*(i+1))/32; + a -= ((inlink->h*i)%32 == 0) ? (inlink->h*i)/32 - 1 : (inlink->h*i)/32; + a = (a == dh1)? dh2 : dh1; + } + for (j = 0; j < 32; j++) { + b = 1; + if (dw2 > 1) { + b = ((inlink->w*(j+1))%32 == 0) ? (inlink->w*(j+1))/32 - 1 : (inlink->w*(j+1))/32; + b -= ((inlink->w*j)%32 == 0) ? (inlink->w*j)/32 - 1 : (inlink->w*j)/32; + b = (b == dw1)? dw2 : dw1; + } + rowcount += intpic[i][j] * a * b * precfactor / denom; + if (i > 0) { + intpic[i][j] = intpic[i-1][j] + rowcount; + } else { + intpic[i][j] = rowcount; + } + } + } + + denom = (sc->divide) ? 1 : dh1 * dh2 * dw1 * dw2; + + for (i = 0; i < ELEMENT_COUNT; i++) { + const ElemCat* elemcat = elements[i]; + int64_t* elemsignature; + uint64_t* sortsignature; + + elemsignature = av_malloc_array(elemcat->elem_count, sizeof(int64_t)); + if (!elemsignature) + return AVERROR(ENOMEM); + sortsignature = av_malloc_array(elemcat->elem_count, sizeof(int64_t)); + if (!sortsignature) + return AVERROR(ENOMEM); + + for (j = 0; j < elemcat->elem_count; j++) { + blocksum = 0; + blocksize = 0; + for (k = 0; k < elemcat->left_count; k++) { + blocksum += get_block_sum(sc, intpic, &elemcat->blocks[j*elemcat->block_count+k]); + blocksize += get_block_size(&elemcat->blocks[j*elemcat->block_count+k]); + } + sum = blocksum / blocksize; + if (elemcat->av_elem) { + sum -= 128 * precfactor * denom; + } else { + blocksum = 0; + blocksize = 0; + for (; k < elemcat->block_count; k++) { + blocksum += get_block_sum(sc, intpic, &elemcat->blocks[j*elemcat->block_count+k]); + blocksize += get_block_size(&elemcat->blocks[j*elemcat->block_count+k]); + } + sum -= blocksum / blocksize; + conflist[g++] = FFABS(sum * 8 / (precfactor * denom)); + } + + elemsignature[j] = sum; + sortsignature[j] = FFABS(sum); + } + + /* get threshold */ + qsort(sortsignature, elemcat->elem_count, sizeof(uint64_t), (void*) cmp); + th = sortsignature[(int) (elemcat->elem_count*0.333)]; + + /* ternarize */ + for (j = 0; j < elemcat->elem_count; j++) { + if (elemsignature[j] < -th) { + ternary = 0; + } else if (elemsignature[j] <= th) { + ternary = 1; + } else { + ternary = 2; + } + fs->framesig[f/5] += ternary * pot3[f%5]; + + if (f == wordvec[w]) { + fs->words[s2usw[w]/5] += ternary * pot3[wordt2b[s2usw[w]/5]++]; + if (w < 24) + w++; + } + f++; + } + av_freep(&elemsignature); + av_freep(&sortsignature); + } + + /* confidence */ + qsort(conflist, DIFFELEM_SIZE, sizeof(uint64_t), (void*) cmp); + fs->confidence = FFMIN(conflist[DIFFELEM_SIZE/2], 255); + + /* coarsesignature */ + if (sc->coarsecount == 0) { + if (sc->curcoarsesig2) { + sc->curcoarsesig1 = av_mallocz(sizeof(CoarseSignature)); + if (!sc->curcoarsesig1) + return AVERROR(ENOMEM); + sc->curcoarsesig1->first = fs; + sc->curcoarsesig2->next = sc->curcoarsesig1; + sc->coarseend = sc->curcoarsesig1; + } + } + if (sc->coarsecount == 45) { + sc->midcoarse = 1; + sc->curcoarsesig2 = av_mallocz(sizeof(CoarseSignature)); + if (!sc->curcoarsesig2) + return AVERROR(ENOMEM); + sc->curcoarsesig2->first = fs; + sc->curcoarsesig1->next = sc->curcoarsesig2; + sc->coarseend = sc->curcoarsesig2; + } + for (i = 0; i < 5; i++) { + set_bit(sc->curcoarsesig1->data[i], fs->words[i]); + } + /* assuming the actual frame is the last */ + sc->curcoarsesig1->last = fs; + if (sc->midcoarse) { + for (i = 0; i < 5; i++) { + set_bit(sc->curcoarsesig2->data[i], fs->words[i]); + } + sc->curcoarsesig2->last = fs; + } + + sc->coarsecount = (sc->coarsecount+1)%90; + + /* debug printing finesignature */ + if (av_log_get_level() == AV_LOG_DEBUG) { + av_log(ctx, AV_LOG_DEBUG, "input %d, confidence: %d\n", FF_INLINK_IDX(inlink), fs->confidence); + + av_log(ctx, AV_LOG_DEBUG, "words:"); + for (i = 0; i < 5; i++) { + av_log(ctx, AV_LOG_DEBUG, " %d:", fs->words[i] ); + av_log(ctx, AV_LOG_DEBUG, " %d", fs->words[i] / pot3[0] ); + for (j = 1; j < 5; j++) + av_log(ctx, AV_LOG_DEBUG, ",%d", fs->words[i] % pot3[j-1] / pot3[j] ); + av_log(ctx, AV_LOG_DEBUG, ";"); + } + av_log(ctx, AV_LOG_DEBUG, "\n"); + + av_log(ctx, AV_LOG_DEBUG, "framesignature:"); + for (i = 0; i < SIGELEM_SIZE/5; i++) { + av_log(ctx, AV_LOG_DEBUG, " %d", fs->framesig[i] / pot3[0] ); + for (j = 1; j < 5; j++) + av_log(ctx, AV_LOG_DEBUG, ",%d", fs->framesig[i] % pot3[j-1] / pot3[j] ); + } + av_log(ctx, AV_LOG_DEBUG, "\n"); + } + + if (FF_INLINK_IDX(inlink) == 0) + return ff_filter_frame(inlink->dst->outputs[0], picref); + return 1; +} + +static int xml_export(AVFilterContext *ctx, StreamContext *sc, const char* filename) +{ + FineSignature* fs; + CoarseSignature* cs; + int i, j; + FILE* f; + unsigned int pot3[5] = { 3*3*3*3, 3*3*3, 3*3, 3, 1 }; + + f = fopen(filename, "w"); + if (!f) { + int err = AVERROR(EINVAL); + char buf[128]; + av_strerror(err, buf, sizeof(buf)); + av_log(ctx, AV_LOG_ERROR, "cannot open xml file %s: %s\n", filename, buf); + return err; + } + + /* header */ + fprintf(f, "\n"); + fprintf(f, "\n"); + fprintf(f, " \n"); + fprintf(f, " \n"); + fprintf(f, " \n"); + fprintf(f, " \n"); + fprintf(f, " 0 0 \n"); + fprintf(f, " %d %d \n", sc->w - 1, sc->h - 1); + fprintf(f, " \n"); + fprintf(f, " 0\n"); + /* hoping num is 1, other values are vague */ + fprintf(f, " %d\n", sc->time_base.den / sc->time_base.num); + fprintf(f, " \n"); + fprintf(f, " 0\n"); + fprintf(f, " %" PRIu64 "\n", sc->coarseend->last->pts); + fprintf(f, " \n"); + + /* coarsesignatures */ + for (cs = sc->coarsesiglist; cs; cs = cs->next) { + fprintf(f, " \n"); + fprintf(f, " %" PRIu32 "\n", cs->first->index); + fprintf(f, " %" PRIu32 "\n", cs->last->index); + fprintf(f, " \n"); + fprintf(f, " %" PRIu64 "\n", cs->first->pts); + fprintf(f, " %" PRIu64 "\n", cs->last->pts); + fprintf(f, " \n"); + for (i = 0; i < 5; i++) { + fprintf(f, " "); + for (j = 0; j < 31; j++) { + uint8_t n = cs->data[i][j]; + if (j < 30) { + fprintf(f, "%d %d %d %d %d %d %d %d ", (n & 0x80) >> 7, + (n & 0x40) >> 6, + (n & 0x20) >> 5, + (n & 0x10) >> 4, + (n & 0x08) >> 3, + (n & 0x04) >> 2, + (n & 0x02) >> 1, + (n & 0x01)); + } else { + /* print only 3 bit in last byte */ + fprintf(f, "%d %d %d ", (n & 0x80) >> 7, + (n & 0x40) >> 6, + (n & 0x20) >> 5); + } + } + fprintf(f, "\n"); + } + fprintf(f, " \n"); + } + + /* finesignatures */ + for (fs = sc->finesiglist; fs; fs = fs->next) { + fprintf(f, " \n"); + fprintf(f, " %" PRIu64 "\n", fs->pts); + /* confidence */ + fprintf(f, " %d\n", fs->confidence); + /* words */ + fprintf(f, " "); + for (i = 0; i < 5; i++) { + fprintf(f, "%d ", fs->words[i]); + if (i < 4) { + fprintf(f, " "); + } + } + fprintf(f, "\n"); + /* framesignature */ + fprintf(f, " "); + for (i = 0; i< SIGELEM_SIZE/5; i++) { + if (i > 0) { + fprintf(f, " "); + } + fprintf(f, "%d ", fs->framesig[i] / pot3[0]); + for (j = 1; j < 5; j++) + fprintf(f, " %d ", fs->framesig[i] % pot3[j-1] / pot3[j] ); + } + fprintf(f, "\n"); + fprintf(f, " \n"); + } + fprintf(f, " \n"); + fprintf(f, " \n"); + fprintf(f, " \n"); + fprintf(f, "\n"); + + fclose(f); + return 0; +} + +static int binary_export(AVFilterContext *ctx, StreamContext *sc, const char* filename) +{ + FILE* f; + FineSignature* fs; + CoarseSignature* cs; + uint32_t numofsegments = (sc->lastindex + 44)/45; + int i, j; + PutBitContext buf; + /* buffer + header + coarsesignatures + finesignature */ + int len = (512 + 6 * 32 + 3*16 + 2 + + numofsegments * (4*32 + 1 + 5*243) + + sc->lastindex * (2 + 32 + 6*8 + 608)) / 8; + uint8_t* buffer = av_malloc_array(len, sizeof(uint8_t)); + if (!buffer) + return AVERROR(ENOMEM); + + f = fopen(filename, "wb"); + if (!f) { + int err = AVERROR(EINVAL); + char buf[128]; + av_strerror(err, buf, sizeof(buf)); + av_log(ctx, AV_LOG_ERROR, "cannot open file %s: %s\n", filename, buf); + return err; + } + init_put_bits(&buf, buffer, len); + + put_bits32(&buf, 1); /* NumOfSpatial Regions, only 1 supported */ + put_bits(&buf, 1, 1); /* SpatialLocationFlag, always the whole image */ + put_bits32(&buf, 0); /* PixelX,1 PixelY,1, 0,0 */ + put_bits(&buf, 16, sc->w-1 & 0xFFFF); /* PixelX,2 */ + put_bits(&buf, 16, sc->h-1 & 0xFFFF); /* PixelY,2 */ + put_bits32(&buf, 0); /* StartFrameOfSpatialRegion */ + put_bits32(&buf, sc->lastindex); /* NumOfFrames */ + /* hoping num is 1, other values are vague */ + /* den/num might be greater than 16 bit, so cutting it */ + put_bits(&buf, 16, 0xFFFF & (sc->time_base.den / sc->time_base.num)); /* MediaTimeUnit */ + put_bits(&buf, 1, 1); /* MediaTimeFlagOfSpatialRegion */ + put_bits32(&buf, 0); /* StartMediaTimeOfSpatialRegion */ + put_bits32(&buf, 0xFFFFFFFF & sc->coarseend->last->pts); /* EndMediaTimeOfSpatialRegion */ + put_bits32(&buf, numofsegments); /* NumOfSegments */ + /* coarsesignatures */ + for (cs = sc->coarsesiglist; cs; cs = cs->next) { + put_bits32(&buf, cs->first->index); /* StartFrameOfSegment */ + put_bits32(&buf, cs->last->index); /* EndFrameOfSegment */ + put_bits(&buf, 1, 1); /* MediaTimeFlagOfSegment */ + put_bits32(&buf, 0xFFFFFFFF & cs->first->pts); /* StartMediaTimeOfSegment */ + put_bits32(&buf, 0xFFFFFFFF & cs->last->pts); /* EndMediaTimeOfSegment */ + for (i = 0; i < 5; i++) { + /* put 243 bits ( = 7 * 32 + 19 = 8 * 28 + 19) into buffer */ + for (j = 0; j < 30; j++) { + put_bits(&buf, 8, cs->data[i][j]); + } + put_bits(&buf, 3, cs->data[i][30] >> 5); + } + } + /* finesignatures */ + put_bits(&buf, 1, 0); /* CompressionFlag, only 0 supported */ + for (fs = sc->finesiglist; fs; fs = fs->next) { + put_bits(&buf, 1, 1); /* MediaTimeFlagOfFrame */ + put_bits32(&buf, 0xFFFFFFFF & fs->pts); /* MediaTimeOfFrame */ + put_bits(&buf, 8, fs->confidence); /* FrameConfidence */ + for (i = 0; i < 5; i++) { + put_bits(&buf, 8, fs->words[i]); /* Words */ + } + /* framesignature */ + for (i = 0; i < SIGELEM_SIZE/5; i++) { + put_bits(&buf, 8, fs->framesig[i]); + } + } + + avpriv_align_put_bits(&buf); + flush_put_bits(&buf); + fwrite(buffer, 1, put_bits_count(&buf)/8, f); + fclose(f); + av_freep(&buffer); + return 0; +} + +static int export(AVFilterContext *ctx, StreamContext *sc, int input) +{ + SignatureContext* sic = ctx->priv; + char filename[1024]; + + if (sic->nb_inputs > 1) { + /* error already handled */ + av_assert0(av_get_frame_filename(filename, sizeof(filename), sic->filename, input) == 0); + } else { + strcpy(filename, sic->filename); + } + if (sic->format == FORMAT_XML) { + return xml_export(ctx, sc, filename); + } else { + return binary_export(ctx, sc, filename); + } +} + +static int request_frame(AVFilterLink *outlink) +{ + AVFilterContext *ctx = outlink->src; + SignatureContext *sic = ctx->priv; + StreamContext *sc, *sc2; + MatchingInfo match; + int i, j, ret; + int lookup = 1; /* indicates wheather EOF of all files is reached */ + + /* process all inputs */ + for (i = 0; i < sic->nb_inputs; i++){ + sc = &(sic->streamcontexts[i]); + + ret = ff_request_frame(ctx->inputs[i]); + + /* return if unexpected error occurs in input stream */ + if (ret < 0 && ret != AVERROR_EOF) + return ret; + + /* export signature at EOF */ + if (ret == AVERROR_EOF && !sc->exported) { + /* export if wanted */ + if (strlen(sic->filename) > 0) { + if (export(ctx, sc, i) < 0) + return ret; + } + sc->exported = 1; + } + lookup &= sc->exported; + } + + /* signature lookup */ + if (lookup && sic->mode != MODE_OFF) { + /* iterate over every pair */ + for (i = 0; i < sic->nb_inputs; i++) { + sc = &(sic->streamcontexts[i]); + for (j = i+1; j < sic->nb_inputs; j++) { + sc2 = &(sic->streamcontexts[j]); + match = lookup_signatures(ctx, sic, sc, sc2, sic->mode); + if (match.score != 0) { + av_log(ctx, AV_LOG_INFO, "matching of video %d at %f and %d at %f, %d frames matching\n", + i, ((double) match.first->pts * sc->time_base.num) / sc->time_base.den, + j, ((double) match.second->pts * sc2->time_base.num) / sc2->time_base.den, + match.matchframes); + if (match.whole) + av_log(ctx, AV_LOG_INFO, "whole video matching\n"); + } else { + av_log(ctx, AV_LOG_INFO, "no matching of video %d and %d\n", i, j); + } + } + } + } + + return ret; +} + +static av_cold int init(AVFilterContext *ctx) +{ + + SignatureContext *sic = ctx->priv; + StreamContext *sc; + int i, ret; + char tmp[1024]; + + sic->streamcontexts = av_mallocz(sic->nb_inputs * sizeof(StreamContext)); + if (!sic->streamcontexts) + return AVERROR(ENOMEM); + + for (i = 0; i < sic->nb_inputs; i++) { + AVFilterPad pad = { + .type = AVMEDIA_TYPE_VIDEO, + .name = av_asprintf("in%d", i), + .config_props = config_input, + .filter_frame = filter_frame, + }; + + if (!pad.name) + return AVERROR(ENOMEM); + + sc = &(sic->streamcontexts[i]); + + sc->lastindex = 0; + sc->finesiglist = av_mallocz(sizeof(FineSignature)); + if (!sc->finesiglist) + return AVERROR(ENOMEM); + sc->curfinesig = NULL; + + sc->coarsesiglist = av_mallocz(sizeof(CoarseSignature)); + if (!sc->coarsesiglist) + return AVERROR(ENOMEM); + sc->curcoarsesig1 = sc->coarsesiglist; + sc->coarseend = sc->coarsesiglist; + sc->coarsecount = 0; + sc->midcoarse = 0; + + if ((ret = ff_insert_inpad(ctx, i, &pad)) < 0) { + av_freep(&pad.name); + return ret; + } + } + + /* check filename */ + if (sic->nb_inputs > 1 && strlen(sic->filename) > 0 && av_get_frame_filename(tmp, sizeof(tmp), sic->filename, 0) == -1) { + av_log(ctx, AV_LOG_ERROR, "The filename must contain %%d or %%0nd, if you have more than one input.\n"); + return AVERROR(EINVAL); + } + + return 0; +} + + + +static av_cold void uninit(AVFilterContext *ctx) +{ + SignatureContext *sic = ctx->priv; + StreamContext *sc; + void* tmp; + FineSignature* finsig; + CoarseSignature* cousig; + int i; + + + /* free the lists */ + if (sic->streamcontexts != NULL) { + for (i = 0; i < sic->nb_inputs; i++) { + sc = &(sic->streamcontexts[i]); + finsig = sc->finesiglist; + cousig = sc->coarsesiglist; + + while (finsig) { + tmp = finsig; + finsig = finsig->next; + av_freep(&tmp); + } + sc->finesiglist = NULL; + + while (cousig) { + tmp = cousig; + cousig = cousig->next; + av_freep(&tmp); + } + sc->coarsesiglist = NULL; + } + av_freep(&sic->streamcontexts); + } +} + +static int config_output(AVFilterLink *outlink) +{ + AVFilterContext *ctx = outlink->src; + AVFilterLink *inlink = ctx->inputs[0]; + + outlink->time_base = inlink->time_base; + outlink->frame_rate = inlink->frame_rate; + outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; + outlink->w = inlink->w; + outlink->h = inlink->h; + + return 0; +} + +static const AVFilterPad signature_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .request_frame = request_frame, + .config_props = config_output, + }, + { NULL } +}; + +AVFilter ff_vf_signature = { + .name = "signature", + .description = NULL_IF_CONFIG_SMALL("Calculate the MPEG-7 video signature"), + .priv_size = sizeof(SignatureContext), + .priv_class = &signature_class, + .init = init, + .uninit = uninit, + .query_formats = query_formats, + .outputs = signature_outputs, + .inputs = NULL, + .flags = AVFILTER_FLAG_DYNAMIC_INPUTS, +}; From d682ae70b4b3a53fb73ec30281f9f4cfbc531edd Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 16 Mar 2017 04:52:55 +0100 Subject: [PATCH 1232/3374] avcodec, avformat: deprecate anything related to side data merging This patch deprecates anything that has to do with merging/splitting side data. Automatic side data merging (and splitting), as well as all API symbols involved in it, are removed completely. Two FF_API_ defines are dedicated to deprecating API symbols related to this: FF_API_MERGE_SD_API removes av_packet_split/merge_side_data in libavcodec, and FF_API_LAVF_KEEPSIDE_FLAG deprecates AVFMT_FLAG_KEEP_SIDE_DATA in libavformat. Since it was claimed that changing the default from merging side data to not doing it is an ABI change, there are two additional FF_API_ defines, which stop using the side data merging/splitting by default (and remove any code in avformat/avcodec doing this): FF_API_MERGE_SD in libavcodec, and FF_API_LAVF_MERGE_SD in libavformat. It is very much intended that FF_API_MERGE_SD and FF_API_LAVF_MERGE_SD are quickly defined to 0 in the next ABI bump, while the API symbols are retained for a longer time for the sake of compatibility. AVFMT_FLAG_KEEP_SIDE_DATA will (very much intentionally) do nothing for most of the time it will still be defined. Keep in mind that no code exists that actually tries to unset this flag for any reason, nor does such code need to exist. Code setting this flag explicitly will work as before. Thus it's ok for AVFMT_FLAG_KEEP_SIDE_DATA to do nothing once side data merging has been removed from libavformat. In order to avoid that anyone in the future does this incorrectly, here is a small guide how to update the internal code on bumps: - next ABI bump (probably soon): - define FF_API_LAVF_MERGE_SD to 0, and remove all code covered by it - define FF_API_MERGE_SD to 0, and remove all code covered by it - next API bump (typically two years in the future or so): - define FF_API_LAVF_KEEPSIDE_FLAG to 0, and remove all code covered by it - define FF_API_MERGE_SD_API to 0, and remove all code covered by it This forces anyone who actually wants packet side data to temporarily use deprecated API to get it all. If you ask me, this is batshit fucked up crazy, but it's how we roll. Making AVFMT_FLAG_KEEP_SIDE_DATA to be set by default was rejected as an ABI change, so I'm going all the way to get rid of this once and for all. Reviewed-by: James Almer Reviewed-by: Rostislav Pehlivanov Reviewed-by: Michael Niedermayer --- doc/APIchanges | 5 +++++ libavcodec/avcodec.h | 4 ++++ libavcodec/avpacket.c | 4 ++++ libavcodec/utils.c | 24 ++++++++++++++++++++++++ libavcodec/version.h | 9 ++++++++- libavformat/avformat.h | 4 +++- libavformat/mux.c | 12 ++++++++++++ libavformat/options_table.h | 2 ++ libavformat/utils.c | 4 ++++ libavformat/version.h | 8 +++++++- 10 files changed, 73 insertions(+), 3 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 436fb71acb812..aadf164254c61 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,11 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-03-21 - xxxxxxx - lavf 57.66.105, lavc 57.83.101 - avformat.h, avcodec.h + Deprecate AVFMT_FLAG_KEEP_SIDE_DATA. It will be ignored after the next major + bump, and libavformat will behave as if it were always set. + Deprecate av_packet_merge_side_data() and av_packet_split_side_data(). + 2016-03-20 - xxxxxxx - lavu 55.50.100 / 55.21.0 - imgutils.h Add av_image_copy_uc_from(), a version of av_image_copy() for copying from GPU mapped memory. diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index ea3cb4506b1c0..fbdf89216d6bb 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -4576,9 +4576,13 @@ int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t* av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, int *size); +#if FF_API_MERGE_SD_API +attribute_deprecated int av_packet_merge_side_data(AVPacket *pkt); +attribute_deprecated int av_packet_split_side_data(AVPacket *pkt); +#endif const char *av_packet_side_data_name(enum AVPacketSideDataType type); diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index 3ea2511dea816..8420d8b2581eb 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -379,6 +379,8 @@ const char *av_packet_side_data_name(enum AVPacketSideDataType type) return NULL; } +#if FF_API_MERGE_SD_API + #define FF_MERGE_MARKER 0x8c4d9d108e25e9feULL int av_packet_merge_side_data(AVPacket *pkt){ @@ -460,6 +462,8 @@ int av_packet_split_side_data(AVPacket *pkt){ return 0; } +#endif + uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size) { AVDictionaryEntry *t = NULL; diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 84c28c8396e01..9b055d2b3ebde 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -2263,7 +2263,11 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type & FF_THREAD_FRAME)) { +#if FF_API_MERGE_SD +FF_DISABLE_DEPRECATION_WARNINGS int did_split = av_packet_split_side_data(&tmp); +FF_ENABLE_DEPRECATION_WARNINGS +#endif ret = apply_param_change(avctx, &tmp); if (ret < 0) goto fail; @@ -2295,11 +2299,13 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi emms_c(); //needed to avoid an emms_c() call before every return; avctx->internal->pkt = NULL; +#if FF_API_MERGE_SD if (did_split) { av_packet_free_side_data(&tmp); if(ret == tmp.size) ret = avpkt->size; } +#endif if (picture->flags & AV_FRAME_FLAG_DISCARD) { *got_picture_ptr = 0; } @@ -2369,7 +2375,11 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, uint8_t discard_reason = 0; // copy to ensure we do not change avpkt AVPacket tmp = *avpkt; +#if FF_API_MERGE_SD +FF_DISABLE_DEPRECATION_WARNINGS int did_split = av_packet_split_side_data(&tmp); +FF_ENABLE_DEPRECATION_WARNINGS +#endif ret = apply_param_change(avctx, &tmp); if (ret < 0) goto fail; @@ -2481,11 +2491,13 @@ FF_ENABLE_DEPRECATION_WARNINGS } fail: avctx->internal->pkt = NULL; +#if FF_API_MERGE_SD if (did_split) { av_packet_free_side_data(&tmp); if(ret == tmp.size) ret = avpkt->size; } +#endif if (ret >= 0 && *got_frame_ptr) { if (!avctx->refcounted_frames) { @@ -2682,6 +2694,8 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size) { AVPacket pkt_recoded; AVPacket tmp = *avpkt; +#if FF_API_MERGE_SD +FF_DISABLE_DEPRECATION_WARNINGS int did_split = av_packet_split_side_data(&tmp); //apply_param_change(avctx, &tmp); @@ -2694,6 +2708,8 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, memset(tmp.data + tmp.size, 0, FFMIN(avpkt->size - tmp.size, AV_INPUT_BUFFER_PADDING_SIZE)); } +FF_ENABLE_DEPRECATION_WARNINGS +#endif pkt_recoded = tmp; ret = recode_subtitle(avctx, &pkt_recoded, &tmp); @@ -2753,11 +2769,13 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, avctx->internal->pkt = NULL; } +#if FF_API_MERGE_SD if (did_split) { av_packet_free_side_data(&tmp); if(ret == tmp.size) ret = avpkt->size; } +#endif if (*got_sub_ptr) avctx->frame_number++; @@ -2873,12 +2891,18 @@ int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacke if (avctx->codec->send_packet) { if (avpkt) { AVPacket tmp = *avpkt; +#if FF_API_MERGE_SD +FF_DISABLE_DEPRECATION_WARNINGS int did_split = av_packet_split_side_data(&tmp); +FF_ENABLE_DEPRECATION_WARNINGS +#endif ret = apply_param_change(avctx, &tmp); if (ret >= 0) ret = avctx->codec->send_packet(avctx, &tmp); +#if FF_API_MERGE_SD if (did_split) av_packet_free_side_data(&tmp); +#endif return ret; } else { return avctx->codec->send_packet(avctx, NULL); diff --git a/libavcodec/version.h b/libavcodec/version.h index 3ed5a718d4d91..ec8651f086e59 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 83 -#define LIBAVCODEC_VERSION_MICRO 100 +#define LIBAVCODEC_VERSION_MICRO 101 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ @@ -157,6 +157,9 @@ #ifndef FF_API_VAAPI_CONTEXT #define FF_API_VAAPI_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 58) #endif +#ifndef FF_API_MERGE_SD +#define FF_API_MERGE_SD (LIBAVCODEC_VERSION_MAJOR < 58) +#endif #ifndef FF_API_AVCTX_TIMEBASE #define FF_API_AVCTX_TIMEBASE (LIBAVCODEC_VERSION_MAJOR < 59) #endif @@ -229,5 +232,9 @@ #ifndef FF_API_STRUCT_VAAPI_CONTEXT #define FF_API_STRUCT_VAAPI_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 59) #endif +#ifndef FF_API_MERGE_SD_API +#define FF_API_MERGE_SD_API (LIBAVCODEC_VERSION_MAJOR < 59) +#endif + #endif /* AVCODEC_VERSION_H */ diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 4c1b18e0028e8..4ab217dc17691 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1468,7 +1468,9 @@ typedef struct AVFormatContext { #define AVFMT_FLAG_MP4A_LATM 0x8000 ///< Enable RTP MP4A-LATM payload #define AVFMT_FLAG_SORT_DTS 0x10000 ///< try to interleave outputted packets by dts (using this flag can slow demuxing down) #define AVFMT_FLAG_PRIV_OPT 0x20000 ///< Enable use of private options by delaying codec open (this could be made default once all code is converted) -#define AVFMT_FLAG_KEEP_SIDE_DATA 0x40000 ///< Don't merge side data but keep it separate. +#if FF_API_LAVF_KEEPSIDE_FLAG +#define AVFMT_FLAG_KEEP_SIDE_DATA 0x40000 ///< Don't merge side data but keep it separate. Deprecated, will be the default. +#endif #define AVFMT_FLAG_FAST_SEEK 0x80000 ///< Enable fast, but inaccurate seeks for some formats #define AVFMT_FLAG_SHORTEST 0x100000 ///< Stop muxing when the shortest stream stops. #define AVFMT_FLAG_AUTO_BSF 0x200000 ///< Wait for packet data before writing a header, and add bitstream filters as requested by the muxer diff --git a/libavformat/mux.c b/libavformat/mux.c index e500531789ecb..11b09f1b6ed74 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -752,7 +752,11 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) } } +#if FF_API_LAVF_MERGE_SD +FF_DISABLE_DEPRECATION_WARNINGS did_split = av_packet_split_side_data(pkt); +FF_ENABLE_DEPRECATION_WARNINGS +#endif if (!s->internal->header_written) { ret = s->internal->write_header_ret ? s->internal->write_header_ret : write_header_internal(s); @@ -777,8 +781,12 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) } fail: +#if FF_API_LAVF_MERGE_SD +FF_DISABLE_DEPRECATION_WARNINGS if (did_split) av_packet_merge_side_data(pkt); +FF_ENABLE_DEPRECATION_WARNINGS +#endif if (ret < 0) { pkt->pts = pts_backup; @@ -875,8 +883,12 @@ static int do_packet_auto_bsf(AVFormatContext *s, AVPacket *pkt) { } } +#if FF_API_LAVF_MERGE_SD +FF_DISABLE_DEPRECATION_WARNINGS if (st->internal->nb_bsfcs) av_packet_split_side_data(pkt); +FF_ENABLE_DEPRECATION_WARNINGS +#endif for (i = 0; i < st->internal->nb_bsfcs; i++) { AVBSFContext *ctx = st->internal->bsfcs[i]; diff --git a/libavformat/options_table.h b/libavformat/options_table.h index a537dda95eaca..0c1915d6d46ba 100644 --- a/libavformat/options_table.h +++ b/libavformat/options_table.h @@ -48,7 +48,9 @@ static const AVOption avformat_options[] = { {"igndts", "ignore dts", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_IGNDTS }, INT_MIN, INT_MAX, D, "fflags"}, {"discardcorrupt", "discard corrupted frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_DISCARD_CORRUPT }, INT_MIN, INT_MAX, D, "fflags"}, {"sortdts", "try to interleave outputted packets by dts", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_SORT_DTS }, INT_MIN, INT_MAX, D, "fflags"}, +#if FF_API_LAVF_KEEPSIDE_FLAG {"keepside", "don't merge side data", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_KEEP_SIDE_DATA }, INT_MIN, INT_MAX, D, "fflags"}, +#endif {"fastseek", "fast but inaccurate seeks", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_FAST_SEEK }, INT_MIN, INT_MAX, D, "fflags"}, {"latm", "enable RTP MP4A-LATM payload", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_MP4A_LATM }, INT_MIN, INT_MAX, E, "fflags"}, {"nobuffer", "reduce the latency introduced by optional buffering", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_NOBUFFER }, 0, INT_MAX, D, "fflags"}, diff --git a/libavformat/utils.c b/libavformat/utils.c index 37d7024465cb8..8227d1bbe18bb 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -1675,8 +1675,12 @@ FF_ENABLE_DEPRECATION_WARNINGS st->inject_global_side_data = 0; } +#if FF_API_LAVF_MERGE_SD +FF_DISABLE_DEPRECATION_WARNINGS if (!(s->flags & AVFMT_FLAG_KEEP_SIDE_DATA)) av_packet_merge_side_data(pkt); +FF_ENABLE_DEPRECATION_WARNINGS +#endif } av_opt_get_dict_val(s, "metadata", AV_OPT_SEARCH_CHILDREN, &metadata); diff --git a/libavformat/version.h b/libavformat/version.h index dc689d45fbff1..bfc42e3f15fe1 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -33,7 +33,7 @@ // Also please add any ticket numbers that you believe might be affected here #define LIBAVFORMAT_VERSION_MAJOR 57 #define LIBAVFORMAT_VERSION_MINOR 66 -#define LIBAVFORMAT_VERSION_MICRO 104 +#define LIBAVFORMAT_VERSION_MICRO 105 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ @@ -88,6 +88,12 @@ #ifndef FF_API_HLS_WRAP #define FF_API_HLS_WRAP (LIBAVFORMAT_VERSION_MAJOR < 58) #endif +#ifndef FF_API_LAVF_MERGE_SD +#define FF_API_LAVF_MERGE_SD (LIBAVFORMAT_VERSION_MAJOR < 58) +#endif +#ifndef FF_API_LAVF_KEEPSIDE_FLAG +#define FF_API_LAVF_KEEPSIDE_FLAG (LIBAVFORMAT_VERSION_MAJOR < 58) +#endif #ifndef FF_API_R_FRAME_RATE From 87c082c42602924cf1ef98880df99044416c9329 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 16 Mar 2017 05:18:59 +0100 Subject: [PATCH 1233/3374] ffmpeg: don't unnecessarily use a deprecated API function Since we've disabled side data merging in ffmpeg.c, this really changes nothing. --- ffmpeg.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index dbfb14bfca5a2..dcb7720241853 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -818,7 +818,6 @@ static void output_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost) if (ost->nb_bitstream_filters) { int idx; - av_packet_split_side_data(pkt); ret = av_bsf_send_packet(ost->bsf_ctx[0], pkt); if (ret < 0) goto finish; @@ -4247,8 +4246,6 @@ static int process_input(int file_index) /* add the stream-global side data to the first packet */ if (ist->nb_packets == 1) { - if (ist->st->nb_side_data) - av_packet_split_side_data(&pkt); for (i = 0; i < ist->st->nb_side_data; i++) { AVPacketSideData *src_sd = &ist->st->side_data[i]; uint8_t *dst_data; From 749262693247808e2db5a2eb29a11ad3cfec211c Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 18 Jul 2016 00:04:16 +0200 Subject: [PATCH 1234/3374] pthread_frame: use atomics for PerThreadContext.state Merges Libav commit 64a31b28. Signed-off-by: wm4 --- libavcodec/pthread_frame.c | 84 +++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 272587f53c375..bd250002a3af3 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -24,6 +24,7 @@ #include "config.h" +#include #include #include "avcodec.h" @@ -43,6 +44,25 @@ #include "libavutil/opt.h" #include "libavutil/thread.h" +enum { + ///< Set when the thread is awaiting a packet. + STATE_INPUT_READY, + ///< Set before the codec has called ff_thread_finish_setup(). + STATE_SETTING_UP, + /** + * Set when the codec calls get_buffer(). + * State is returned to STATE_SETTING_UP afterwards. + */ + STATE_GET_BUFFER, + /** + * Set when the codec calls get_format(). + * State is returned to STATE_SETTING_UP afterwards. + */ + STATE_GET_FORMAT, + ///< Set after the codec has called ff_thread_finish_setup(). + STATE_SETUP_FINISHED, +}; + /** * Context used by codec threads and stored in their AVCodecInternal thread_ctx. */ @@ -66,19 +86,7 @@ typedef struct PerThreadContext { int got_frame; ///< The output of got_picture_ptr from the last avcodec_decode_video() call. int result; ///< The result of the last codec decode/encode() call. - enum { - STATE_INPUT_READY, ///< Set when the thread is awaiting a packet. - STATE_SETTING_UP, ///< Set before the codec has called ff_thread_finish_setup(). - STATE_GET_BUFFER, /**< - * Set when the codec calls get_buffer(). - * State is returned to STATE_SETTING_UP afterwards. - */ - STATE_GET_FORMAT, /**< - * Set when the codec calls get_format(). - * State is returned to STATE_SETTING_UP afterwards. - */ - STATE_SETUP_FINISHED ///< Set after the codec has called ff_thread_finish_setup(). - } state; + atomic_int state; /** * Array of frames passed to ff_thread_release_buffer(). @@ -133,8 +141,8 @@ static attribute_align_arg void *frame_worker_thread(void *arg) pthread_mutex_lock(&p->mutex); while (1) { - while (p->state == STATE_INPUT_READY && !p->die) - pthread_cond_wait(&p->input_cond, &p->mutex); + while (atomic_load(&p->state) == STATE_INPUT_READY && !p->die) + pthread_cond_wait(&p->input_cond, &p->mutex); if (p->die) break; @@ -152,7 +160,8 @@ static attribute_align_arg void *frame_worker_thread(void *arg) av_frame_unref(p->frame); } - if (p->state == STATE_SETTING_UP) ff_thread_finish_setup(avctx); + if (atomic_load(&p->state) == STATE_SETTING_UP) + ff_thread_finish_setup(avctx); pthread_mutex_lock(&p->progress_mutex); #if 0 //BUFREF-FIXME @@ -162,7 +171,7 @@ static attribute_align_arg void *frame_worker_thread(void *arg) p->progress[i][1] = INT_MAX; } #endif - p->state = STATE_INPUT_READY; + atomic_store(&p->state, STATE_INPUT_READY); pthread_cond_broadcast(&p->progress_cond); pthread_cond_signal(&p->output_cond); @@ -323,9 +332,9 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt) if (prev_thread) { int err; - if (prev_thread->state == STATE_SETTING_UP) { + if (atomic_load(&prev_thread->state) == STATE_SETTING_UP) { pthread_mutex_lock(&prev_thread->progress_mutex); - while (prev_thread->state == STATE_SETTING_UP) + while (atomic_load(&prev_thread->state) == STATE_SETTING_UP) pthread_cond_wait(&prev_thread->progress_cond, &prev_thread->progress_mutex); pthread_mutex_unlock(&prev_thread->progress_mutex); } @@ -345,7 +354,7 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt) return ret; } - p->state = STATE_SETTING_UP; + atomic_store(&p->state, STATE_SETTING_UP); pthread_cond_signal(&p->input_cond); pthread_mutex_unlock(&p->mutex); @@ -358,13 +367,13 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt) if (!p->avctx->thread_safe_callbacks && ( p->avctx->get_format != avcodec_default_get_format || p->avctx->get_buffer2 != avcodec_default_get_buffer2)) { - while (p->state != STATE_SETUP_FINISHED && p->state != STATE_INPUT_READY) { + while (atomic_load(&p->state) != STATE_SETUP_FINISHED && atomic_load(&p->state) != STATE_INPUT_READY) { int call_done = 1; pthread_mutex_lock(&p->progress_mutex); - while (p->state == STATE_SETTING_UP) + while (atomic_load(&p->state) == STATE_SETTING_UP) pthread_cond_wait(&p->progress_cond, &p->progress_mutex); - switch (p->state) { + switch (atomic_load_explicit(&p->state, memory_order_acquire)) { case STATE_GET_BUFFER: p->result = ff_get_buffer(p->avctx, p->requested_frame, p->requested_flags); break; @@ -376,7 +385,7 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt) break; } if (call_done) { - p->state = STATE_SETTING_UP; + atomic_store(&p->state, STATE_SETTING_UP); pthread_cond_signal(&p->progress_cond); } pthread_mutex_unlock(&p->progress_mutex); @@ -431,9 +440,9 @@ int ff_thread_decode_frame(AVCodecContext *avctx, do { p = &fctx->threads[finished++]; - if (p->state != STATE_INPUT_READY) { + if (atomic_load(&p->state) != STATE_INPUT_READY) { pthread_mutex_lock(&p->progress_mutex); - while (p->state != STATE_INPUT_READY) + while (atomic_load_explicit(&p->state, memory_order_relaxed) != STATE_INPUT_READY) pthread_cond_wait(&p->output_cond, &p->progress_mutex); pthread_mutex_unlock(&p->progress_mutex); } @@ -516,11 +525,12 @@ void ff_thread_finish_setup(AVCodecContext *avctx) { if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return; pthread_mutex_lock(&p->progress_mutex); - if(p->state == STATE_SETUP_FINISHED){ + if(atomic_load(&p->state) == STATE_SETUP_FINISHED){ av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n"); } - p->state = STATE_SETUP_FINISHED; + atomic_store(&p->state, STATE_SETUP_FINISHED); + pthread_cond_broadcast(&p->progress_cond); pthread_mutex_unlock(&p->progress_mutex); } @@ -533,9 +543,9 @@ static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count for (i = 0; i < thread_count; i++) { PerThreadContext *p = &fctx->threads[i]; - if (p->state != STATE_INPUT_READY) { + if (atomic_load(&p->state) != STATE_INPUT_READY) { pthread_mutex_lock(&p->progress_mutex); - while (p->state != STATE_INPUT_READY) + while (atomic_load(&p->state) != STATE_INPUT_READY) pthread_cond_wait(&p->output_cond, &p->progress_mutex); pthread_mutex_unlock(&p->progress_mutex); } @@ -753,7 +763,7 @@ void ff_thread_flush(AVCodecContext *avctx) int ff_thread_can_start_frame(AVCodecContext *avctx) { PerThreadContext *p = avctx->internal->thread_ctx; - if ((avctx->active_thread_type&FF_THREAD_FRAME) && p->state != STATE_SETTING_UP && + if ((avctx->active_thread_type&FF_THREAD_FRAME) && atomic_load(&p->state) != STATE_SETTING_UP && (avctx->codec->update_thread_context || !THREAD_SAFE_CALLBACKS(avctx))) { return 0; } @@ -772,7 +782,7 @@ static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int if (!(avctx->active_thread_type & FF_THREAD_FRAME)) return ff_get_buffer(avctx, f->f, flags); - if (p->state != STATE_SETTING_UP && + if (atomic_load(&p->state) != STATE_SETTING_UP && (avctx->codec->update_thread_context || !THREAD_SAFE_CALLBACKS(avctx))) { av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n"); return -1; @@ -797,10 +807,10 @@ static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int pthread_mutex_lock(&p->progress_mutex); p->requested_frame = f->f; p->requested_flags = flags; - p->state = STATE_GET_BUFFER; + atomic_store_explicit(&p->state, STATE_GET_BUFFER, memory_order_release); pthread_cond_broadcast(&p->progress_cond); - while (p->state != STATE_SETTING_UP) + while (atomic_load(&p->state) != STATE_SETTING_UP) pthread_cond_wait(&p->progress_cond, &p->progress_mutex); err = p->result; @@ -825,16 +835,16 @@ enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixe if (!(avctx->active_thread_type & FF_THREAD_FRAME) || avctx->thread_safe_callbacks || avctx->get_format == avcodec_default_get_format) return ff_get_format(avctx, fmt); - if (p->state != STATE_SETTING_UP) { + if (atomic_load(&p->state) != STATE_SETTING_UP) { av_log(avctx, AV_LOG_ERROR, "get_format() cannot be called after ff_thread_finish_setup()\n"); return -1; } pthread_mutex_lock(&p->progress_mutex); p->available_formats = fmt; - p->state = STATE_GET_FORMAT; + atomic_store(&p->state, STATE_GET_FORMAT); pthread_cond_broadcast(&p->progress_cond); - while (p->state != STATE_SETTING_UP) + while (atomic_load(&p->state) != STATE_SETTING_UP) pthread_cond_wait(&p->progress_cond, &p->progress_mutex); res = p->result_format; From b6587421c7799f18038c7c802b62d034ede52f8f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 18 Jul 2016 00:04:16 +0200 Subject: [PATCH 1235/3374] pthread_frame: use atomics for frame progress Merges Libav commit 59c70227. Signed-off-by: wm4 --- libavcodec/pthread_frame.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index bd250002a3af3..2a5dfc67236b9 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -486,9 +486,11 @@ int ff_thread_decode_frame(AVCodecContext *avctx, void ff_thread_report_progress(ThreadFrame *f, int n, int field) { PerThreadContext *p; - volatile int *progress = f->progress ? (int*)f->progress->data : NULL; + atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL; - if (!progress || progress[field] >= n) return; + if (!progress || + atomic_load_explicit(&progress[field], memory_order_acquire) >= n) + return; p = f->owner->internal->thread_ctx; @@ -496,7 +498,9 @@ void ff_thread_report_progress(ThreadFrame *f, int n, int field) av_log(f->owner, AV_LOG_DEBUG, "%p finished %d field %d\n", progress, n, field); pthread_mutex_lock(&p->progress_mutex); - progress[field] = n; + + atomic_store(&progress[field], n); + pthread_cond_broadcast(&p->progress_cond); pthread_mutex_unlock(&p->progress_mutex); } @@ -504,9 +508,11 @@ void ff_thread_report_progress(ThreadFrame *f, int n, int field) void ff_thread_await_progress(ThreadFrame *f, int n, int field) { PerThreadContext *p; - volatile int *progress = f->progress ? (int*)f->progress->data : NULL; + atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL; - if (!progress || progress[field] >= n) return; + if (!progress || + atomic_load_explicit(&progress[field], memory_order_acquire) >= n) + return; p = f->owner->internal->thread_ctx; @@ -514,7 +520,7 @@ void ff_thread_await_progress(ThreadFrame *f, int n, int field) av_log(f->owner, AV_LOG_DEBUG, "thread awaiting %d field %d from %p\n", n, field, progress); pthread_mutex_lock(&p->progress_mutex); - while (progress[field] < n) + while (atomic_load_explicit(&progress[field], memory_order_relaxed) < n) pthread_cond_wait(&p->progress_cond, &p->progress_mutex); pthread_mutex_unlock(&p->progress_mutex); } @@ -789,14 +795,15 @@ static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int } if (avctx->internal->allocate_progress) { - int *progress; - f->progress = av_buffer_alloc(2 * sizeof(int)); + atomic_int *progress; + f->progress = av_buffer_alloc(2 * sizeof(*progress)); if (!f->progress) { return AVERROR(ENOMEM); } - progress = (int*)f->progress->data; + progress = (atomic_int*)f->progress->data; - progress[0] = progress[1] = -1; + atomic_store(&progress[0], -1); + atomic_store(&progress[1], -1); } pthread_mutex_lock(&p->parent->buffer_mutex); From 98f89d615b6490a5b93930c7bfa74c427dedf04e Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 7 Nov 2016 14:21:18 +0100 Subject: [PATCH 1236/3374] pthread_frame: properly propagate the hw frame context across frame threads Merges Libav commit 84f22568. Signed-off-by: wm4 --- libavcodec/pthread_frame.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 2a5dfc67236b9..18f89ee73de80 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -235,6 +235,17 @@ FF_ENABLE_DEPRECATION_WARNINGS dst->sample_fmt = src->sample_fmt; dst->channel_layout = src->channel_layout; dst->internal->hwaccel_priv_data = src->internal->hwaccel_priv_data; + + if (!!dst->hw_frames_ctx != !!src->hw_frames_ctx || + (dst->hw_frames_ctx && dst->hw_frames_ctx->data != src->hw_frames_ctx->data)) { + av_buffer_unref(&dst->hw_frames_ctx); + + if (src->hw_frames_ctx) { + dst->hw_frames_ctx = av_buffer_ref(src->hw_frames_ctx); + if (!dst->hw_frames_ctx) + return AVERROR(ENOMEM); + } + } } if (for_user) { From fb69a8e1f124ee89e924344bfb7934937abed642 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Thu, 3 Nov 2016 00:13:35 +0000 Subject: [PATCH 1237/3374] pthread_frame: Unreference hw_frames_ctx on per-thread codec contexts When decoding with threads enabled, the get_format callback will be called with one of the per-thread codec contexts rather than with the outer context. If a hwaccel is in use too, this will add a reference to the hardware frames context on that codec context, which will then propagate to all of the other per-thread contexts for decoding. Once the decoder finishes, however, the per-thread contexts are not freed normally, so these references leak. Merges Libav commit fd0fae60. Signed-off-by: wm4 --- libavcodec/pthread_frame.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 18f89ee73de80..b16c1b9928b4e 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -620,8 +620,11 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) av_freep(&p->avctx->slice_offset); } - if (p->avctx) + if (p->avctx) { av_freep(&p->avctx->internal); + av_buffer_unref(&p->avctx->hw_frames_ctx); + } + av_freep(&p->avctx); } From c358c62550e60a150c49f192d72631142a6eedd6 Mon Sep 17 00:00:00 2001 From: Wan-Teh Chang Date: Fri, 9 Dec 2016 09:54:47 -0800 Subject: [PATCH 1238/3374] pthread_frame: use better memory orders for frame progress This improves commit 59c70227405c214b29971e6272f3a3ff6fcce3d0. In ff_thread_report_progress(), the fast code path can load progress[field] with the relaxed memory order, and the slow code path can store progress[field] with the release memory order. These changes are mainly intended to avoid confusion when one inspects the source code. They are unlikely to have measurable performance improvement. ff_thread_report_progress() and ff_thread_await_progress() form a pair. ff_thread_await_progress() reads progress[field] with the acquire memory order (in the fast code path). Therefore, one expects to see ff_thread_report_progress() write progress[field] with the matching release memory order. In the fast code path in ff_thread_report_progress(), the atomic load of progress[field] doesn't need the acquire memory order because the calling thread is trying to make the data it just decoded visible to the other threads, rather than trying to read the data decoded by other threads. In ff_thread_get_buffer(), initialize progress[0] and progress[1] using atomic_init(). Signed-off-by: Wan-Teh Chang Signed-off-by: Anton Khirnov Merges Libav commit 343e2833. Signed-off-by: wm4 --- libavcodec/pthread_frame.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index b16c1b9928b4e..2919e9546bee6 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -500,7 +500,7 @@ void ff_thread_report_progress(ThreadFrame *f, int n, int field) atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL; if (!progress || - atomic_load_explicit(&progress[field], memory_order_acquire) >= n) + atomic_load_explicit(&progress[field], memory_order_relaxed) >= n) return; p = f->owner->internal->thread_ctx; @@ -510,7 +510,7 @@ void ff_thread_report_progress(ThreadFrame *f, int n, int field) pthread_mutex_lock(&p->progress_mutex); - atomic_store(&progress[field], n); + atomic_store_explicit(&progress[field], n, memory_order_release); pthread_cond_broadcast(&p->progress_cond); pthread_mutex_unlock(&p->progress_mutex); @@ -816,8 +816,8 @@ static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int } progress = (atomic_int*)f->progress->data; - atomic_store(&progress[0], -1); - atomic_store(&progress[1], -1); + atomic_init(&progress[0], -1); + atomic_init(&progress[1], -1); } pthread_mutex_lock(&p->parent->buffer_mutex); From 14bb15bfd56d6e907fabe4620206c1ee152b7a20 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 3 Dec 2016 15:21:40 +0100 Subject: [PATCH 1239/3374] pthread_frame: ensure the threads don't run simultaneously with hwaccel Merges Libav commit 8dfba25c. Signed-off-by: wm4 --- libavcodec/h263dec.c | 2 +- libavcodec/h264dec.c | 2 +- libavcodec/pthread_frame.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index c440537e8f9ba..077666470dec6 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -600,7 +600,7 @@ int ff_h263_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if ((ret = ff_mpv_frame_start(s, avctx)) < 0) return ret; - if (!s->divx_packed && !avctx->hwaccel) + if (!s->divx_packed) ff_thread_finish_setup(avctx); #if FF_API_CAP_VDPAU diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 9042169338dc3..585ce86f37339 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -681,7 +681,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size) } if (h->current_slice == 1) { - if (avctx->active_thread_type & FF_THREAD_FRAME && !h->avctx->hwaccel && + if (avctx->active_thread_type & FF_THREAD_FRAME && i >= nals_needed && !h->setup_finished && h->cur_pic_ptr) { ff_thread_finish_setup(avctx); h->setup_finished = 1; diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 2919e9546bee6..e3bfbab872d9e 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -103,6 +103,8 @@ typedef struct PerThreadContext { enum AVPixelFormat result_format; ///< get_format() result int die; ///< Set when the thread should exit. + + int hwaccel_serializing; } PerThreadContext; /** @@ -113,6 +115,11 @@ typedef struct FrameThreadContext { PerThreadContext *prev_thread; ///< The last thread submit_packet() was called on. pthread_mutex_t buffer_mutex; ///< Mutex used to protect get/release_buffer(). + /** + * This lock is used for ensuring threads run in serial when hwaccel + * is used. + */ + pthread_mutex_t hwaccel_mutex; int next_decoding; ///< The next context to submit a packet to. int next_finished; ///< The next context to return output from. @@ -149,6 +156,21 @@ static attribute_align_arg void *frame_worker_thread(void *arg) if (!codec->update_thread_context && THREAD_SAFE_CALLBACKS(avctx)) ff_thread_finish_setup(avctx); + /* If a decoder supports hwaccel, then it must call ff_get_format(). + * Since that call must happen before ff_thread_finish_setup(), the + * decoder is required to implement update_thread_context() and call + * ff_thread_finish_setup() manually. Therefore the above + * ff_thread_finish_setup() call did not happen and hwaccel_serializing + * cannot be true here. */ + av_assert0(!p->hwaccel_serializing); + + /* if the previous thread uses hwaccel then we take the lock to ensure + * the threads don't run concurrently */ + if (avctx->hwaccel) { + pthread_mutex_lock(&p->parent->hwaccel_mutex); + p->hwaccel_serializing = 1; + } + av_frame_unref(p->frame); p->got_frame = 0; p->result = codec->decode(avctx, p->frame, &p->got_frame, &p->avpkt); @@ -163,6 +185,11 @@ static attribute_align_arg void *frame_worker_thread(void *arg) if (atomic_load(&p->state) == STATE_SETTING_UP) ff_thread_finish_setup(avctx); + if (p->hwaccel_serializing) { + p->hwaccel_serializing = 0; + pthread_mutex_unlock(&p->parent->hwaccel_mutex); + } + pthread_mutex_lock(&p->progress_mutex); #if 0 //BUFREF-FIXME for (i = 0; i < MAX_BUFFERS; i++) @@ -541,6 +568,11 @@ void ff_thread_finish_setup(AVCodecContext *avctx) { if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return; + if (avctx->hwaccel && !p->hwaccel_serializing) { + pthread_mutex_lock(&p->parent->hwaccel_mutex); + p->hwaccel_serializing = 1; + } + pthread_mutex_lock(&p->progress_mutex); if(atomic_load(&p->state) == STATE_SETUP_FINISHED){ av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n"); @@ -630,6 +662,7 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) av_freep(&fctx->threads); pthread_mutex_destroy(&fctx->buffer_mutex); + pthread_mutex_destroy(&fctx->hwaccel_mutex); av_freep(&avctx->internal->thread_ctx); if (avctx->priv_data && avctx->codec && avctx->codec->priv_class) @@ -676,6 +709,7 @@ int ff_frame_thread_init(AVCodecContext *avctx) } pthread_mutex_init(&fctx->buffer_mutex, NULL); + pthread_mutex_init(&fctx->hwaccel_mutex, NULL); fctx->delaying = 1; for (i = 0; i < thread_count; i++) { From e0cd598bc4684654d63942e9ff4872c0b48a7dc2 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 24 Nov 2016 15:14:22 +0100 Subject: [PATCH 1240/3374] pthread_frame: do not run hwaccel decoding asynchronously unless it's safe Certain hardware decoding APIs are not guaranteed to be thread-safe, so having the user access decoded hardware surfaces while the decoder is running in another thread can cause failures (this is mainly known to happen with DXVA2). For such hwaccels, only allow the decoding thread to run while the user is inside a lavc decode call (avcodec_send_packet/receive_frame). Merges Libav commit d4a91e65. Signed-off-by: wm4 Tested-by: Michael Niedermayer --- libavcodec/avcodec.h | 5 ++++ libavcodec/hwaccel.h | 24 +++++++++++++++++ libavcodec/pthread_frame.c | 54 +++++++++++++++++++++++++++++++++----- libavcodec/vaapi_h264.c | 2 ++ libavcodec/vaapi_mpeg2.c | 2 ++ libavcodec/vaapi_mpeg4.c | 3 +++ libavcodec/vaapi_vc1.c | 3 +++ libavcodec/vdpau_h264.c | 2 ++ libavcodec/vdpau_hevc.c | 2 ++ libavcodec/vdpau_mpeg12.c | 3 +++ libavcodec/vdpau_mpeg4.c | 2 ++ libavcodec/vdpau_vc1.c | 3 +++ 12 files changed, 98 insertions(+), 7 deletions(-) create mode 100644 libavcodec/hwaccel.h diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index fbdf89216d6bb..f9ebd14a7eaa9 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3905,6 +3905,11 @@ typedef struct AVHWAccel { * AVCodecInternal.hwaccel_priv_data. */ int priv_data_size; + + /** + * Internal hwaccel capabilities. + */ + int caps_internal; } AVHWAccel; /** diff --git a/libavcodec/hwaccel.h b/libavcodec/hwaccel.h new file mode 100644 index 0000000000000..17af43707c233 --- /dev/null +++ b/libavcodec/hwaccel.h @@ -0,0 +1,24 @@ +/* + * This file is part of FFmpeg and was stolen from Libav. + * + * 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 + */ + +#ifndef AVCODEC_HWACCEL_H +#define AVCODEC_HWACCEL_H + +#define HWACCEL_CAP_ASYNC_SAFE (1 << 0) + +#endif /* AVCODEC_HWACCEL_H */ diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index e3bfbab872d9e..f959175db32f7 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -28,6 +28,7 @@ #include #include "avcodec.h" +#include "hwaccel.h" #include "internal.h" #include "pthread_internal.h" #include "thread.h" @@ -105,6 +106,7 @@ typedef struct PerThreadContext { int die; ///< Set when the thread should exit. int hwaccel_serializing; + int async_serializing; } PerThreadContext; /** @@ -120,6 +122,7 @@ typedef struct FrameThreadContext { * is used. */ pthread_mutex_t hwaccel_mutex; + pthread_mutex_t async_mutex; int next_decoding; ///< The next context to submit a packet to. int next_finished; ///< The next context to return output from. @@ -190,6 +193,11 @@ static attribute_align_arg void *frame_worker_thread(void *arg) pthread_mutex_unlock(&p->parent->hwaccel_mutex); } + if (p->async_serializing) { + p->async_serializing = 0; + pthread_mutex_unlock(&p->parent->async_mutex); + } + pthread_mutex_lock(&p->progress_mutex); #if 0 //BUFREF-FIXME for (i = 0; i < MAX_BUFFERS; i++) @@ -443,7 +451,11 @@ int ff_thread_decode_frame(AVCodecContext *avctx, FrameThreadContext *fctx = avctx->internal->thread_ctx; int finished = fctx->next_finished; PerThreadContext *p; - int err; + int err, ret; + + /* release the async lock, permitting blocked hwaccel threads to + * go forward while we are in this function */ + pthread_mutex_unlock(&fctx->async_mutex); /* * Submit a packet to the next decoding thread. @@ -451,9 +463,11 @@ int ff_thread_decode_frame(AVCodecContext *avctx, p = &fctx->threads[fctx->next_decoding]; err = update_context_from_user(p->avctx, avctx); - if (err) return err; + if (err) + goto finish; err = submit_packet(p, avpkt); - if (err) return err; + if (err) + goto finish; /* * If we're still receiving the initial packets, don't return a frame. @@ -464,8 +478,10 @@ int ff_thread_decode_frame(AVCodecContext *avctx, if (fctx->delaying) { *got_picture_ptr=0; - if (avpkt->size) - return avpkt->size; + if (avpkt->size) { + ret = avpkt->size; + goto finish; + } } /* @@ -515,10 +531,15 @@ int ff_thread_decode_frame(AVCodecContext *avctx, * Otherwise the error can get lost. */ if (!avpkt->size && !*got_picture_ptr) - return err; + goto finish; /* return the size of the consumed packet if no error occurred */ - return (p->result >= 0) ? avpkt->size : p->result; + ret = (p->result >= 0) ? avpkt->size : p->result; +finish: + pthread_mutex_lock(&fctx->async_mutex); + if (err < 0) + return err; + return ret; } void ff_thread_report_progress(ThreadFrame *f, int n, int field) @@ -573,6 +594,13 @@ void ff_thread_finish_setup(AVCodecContext *avctx) { p->hwaccel_serializing = 1; } + /* this assumes that no hwaccel calls happen before ff_thread_finish_setup() */ + if (avctx->hwaccel && + !(avctx->hwaccel->caps_internal & HWACCEL_CAP_ASYNC_SAFE)) { + p->async_serializing = 1; + pthread_mutex_lock(&p->parent->async_mutex); + } + pthread_mutex_lock(&p->progress_mutex); if(atomic_load(&p->state) == STATE_SETUP_FINISHED){ av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n"); @@ -589,6 +617,8 @@ static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count { int i; + pthread_mutex_unlock(&fctx->async_mutex); + for (i = 0; i < thread_count; i++) { PerThreadContext *p = &fctx->threads[i]; @@ -600,6 +630,8 @@ static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count } p->got_frame = 0; } + + pthread_mutex_lock(&fctx->async_mutex); } void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) @@ -663,6 +695,10 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) av_freep(&fctx->threads); pthread_mutex_destroy(&fctx->buffer_mutex); pthread_mutex_destroy(&fctx->hwaccel_mutex); + + pthread_mutex_unlock(&fctx->async_mutex); + pthread_mutex_destroy(&fctx->async_mutex); + av_freep(&avctx->internal->thread_ctx); if (avctx->priv_data && avctx->codec && avctx->codec->priv_class) @@ -710,6 +746,10 @@ int ff_frame_thread_init(AVCodecContext *avctx) pthread_mutex_init(&fctx->buffer_mutex, NULL); pthread_mutex_init(&fctx->hwaccel_mutex, NULL); + + pthread_mutex_init(&fctx->async_mutex, NULL); + pthread_mutex_lock(&fctx->async_mutex); + fctx->delaying = 1; for (i = 0; i < thread_count; i++) { diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c index 44e84625220a3..30e7026ccf049 100644 --- a/libavcodec/vaapi_h264.c +++ b/libavcodec/vaapi_h264.c @@ -22,6 +22,7 @@ #include "h264dec.h" #include "h264_ps.h" +#include "hwaccel.h" #include "vaapi_decode.h" /** @@ -399,4 +400,5 @@ AVHWAccel ff_h264_vaapi_hwaccel = { .init = &ff_vaapi_decode_init, .uninit = &ff_vaapi_decode_uninit, .priv_data_size = sizeof(VAAPIDecodeContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; diff --git a/libavcodec/vaapi_mpeg2.c b/libavcodec/vaapi_mpeg2.c index b2417ee83046f..0d197c9692883 100644 --- a/libavcodec/vaapi_mpeg2.c +++ b/libavcodec/vaapi_mpeg2.c @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "hwaccel.h" #include "mpegutils.h" #include "mpegvideo.h" #include "internal.h" @@ -183,4 +184,5 @@ AVHWAccel ff_mpeg2_vaapi_hwaccel = { .init = &ff_vaapi_decode_init, .uninit = &ff_vaapi_decode_uninit, .priv_data_size = sizeof(VAAPIDecodeContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; diff --git a/libavcodec/vaapi_mpeg4.c b/libavcodec/vaapi_mpeg4.c index b00f73dce1ce8..f8c5ddf209537 100644 --- a/libavcodec/vaapi_mpeg4.c +++ b/libavcodec/vaapi_mpeg4.c @@ -21,6 +21,7 @@ */ #include "h263.h" +#include "hwaccel.h" #include "internal.h" #include "mpeg4video.h" #include "mpegvideo.h" @@ -189,6 +190,7 @@ AVHWAccel ff_mpeg4_vaapi_hwaccel = { .init = &ff_vaapi_decode_init, .uninit = &ff_vaapi_decode_uninit, .priv_data_size = sizeof(VAAPIDecodeContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; #endif @@ -205,5 +207,6 @@ AVHWAccel ff_h263_vaapi_hwaccel = { .init = &ff_vaapi_decode_init, .uninit = &ff_vaapi_decode_uninit, .priv_data_size = sizeof(VAAPIDecodeContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; #endif diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c index a456149e6e4ce..30c9ed3c8b530 100644 --- a/libavcodec/vaapi_vc1.c +++ b/libavcodec/vaapi_vc1.c @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "hwaccel.h" #include "internal.h" #include "vaapi_decode.h" #include "vc1.h" @@ -399,6 +400,7 @@ AVHWAccel ff_wmv3_vaapi_hwaccel = { .init = &ff_vaapi_decode_init, .uninit = &ff_vaapi_decode_uninit, .priv_data_size = sizeof(VAAPIDecodeContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; #endif @@ -414,4 +416,5 @@ AVHWAccel ff_vc1_vaapi_hwaccel = { .init = &ff_vaapi_decode_init, .uninit = &ff_vaapi_decode_uninit, .priv_data_size = sizeof(VAAPIDecodeContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; diff --git a/libavcodec/vdpau_h264.c b/libavcodec/vdpau_h264.c index 7265af2890e53..be6ba71433348 100644 --- a/libavcodec/vdpau_h264.c +++ b/libavcodec/vdpau_h264.c @@ -27,6 +27,7 @@ #include "internal.h" #include "h264dec.h" #include "h264_ps.h" +#include "hwaccel.h" #include "mpegutils.h" #include "vdpau.h" #include "vdpau_internal.h" @@ -273,4 +274,5 @@ AVHWAccel ff_h264_vdpau_hwaccel = { .init = vdpau_h264_init, .uninit = ff_vdpau_common_uninit, .priv_data_size = sizeof(VDPAUContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; diff --git a/libavcodec/vdpau_hevc.c b/libavcodec/vdpau_hevc.c index ce2610f67f20e..ee93b3a5e8bd6 100644 --- a/libavcodec/vdpau_hevc.c +++ b/libavcodec/vdpau_hevc.c @@ -25,6 +25,7 @@ #include "avcodec.h" #include "internal.h" #include "hevc.h" +#include "hwaccel.h" #include "vdpau.h" #include "vdpau_internal.h" @@ -423,4 +424,5 @@ AVHWAccel ff_hevc_vdpau_hwaccel = { .init = vdpau_hevc_init, .uninit = ff_vdpau_common_uninit, .priv_data_size = sizeof(VDPAUContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; diff --git a/libavcodec/vdpau_mpeg12.c b/libavcodec/vdpau_mpeg12.c index 3ac2cb827defc..b657007ee7710 100644 --- a/libavcodec/vdpau_mpeg12.c +++ b/libavcodec/vdpau_mpeg12.c @@ -24,6 +24,7 @@ #include #include "avcodec.h" +#include "hwaccel.h" #include "mpegvideo.h" #include "vdpau.h" #include "vdpau_internal.h" @@ -114,6 +115,7 @@ AVHWAccel ff_mpeg1_vdpau_hwaccel = { .init = vdpau_mpeg1_init, .uninit = ff_vdpau_common_uninit, .priv_data_size = sizeof(VDPAUContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; #endif @@ -148,5 +150,6 @@ AVHWAccel ff_mpeg2_vdpau_hwaccel = { .init = vdpau_mpeg2_init, .uninit = ff_vdpau_common_uninit, .priv_data_size = sizeof(VDPAUContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; #endif diff --git a/libavcodec/vdpau_mpeg4.c b/libavcodec/vdpau_mpeg4.c index 46a00cb27cb99..bbdd843a449c7 100644 --- a/libavcodec/vdpau_mpeg4.c +++ b/libavcodec/vdpau_mpeg4.c @@ -24,6 +24,7 @@ #include #include "avcodec.h" +#include "hwaccel.h" #include "mpeg4video.h" #include "vdpau.h" #include "vdpau_internal.h" @@ -121,4 +122,5 @@ AVHWAccel ff_mpeg4_vdpau_hwaccel = { .init = vdpau_mpeg4_init, .uninit = ff_vdpau_common_uninit, .priv_data_size = sizeof(VDPAUContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; diff --git a/libavcodec/vdpau_vc1.c b/libavcodec/vdpau_vc1.c index ffd6505d13f47..665a2333f45a3 100644 --- a/libavcodec/vdpau_vc1.c +++ b/libavcodec/vdpau_vc1.c @@ -24,6 +24,7 @@ #include #include "avcodec.h" +#include "hwaccel.h" #include "vc1.h" #include "vdpau.h" #include "vdpau_internal.h" @@ -147,6 +148,7 @@ AVHWAccel ff_wmv3_vdpau_hwaccel = { .init = vdpau_vc1_init, .uninit = ff_vdpau_common_uninit, .priv_data_size = sizeof(VDPAUContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; #endif @@ -162,4 +164,5 @@ AVHWAccel ff_vc1_vdpau_hwaccel = { .init = vdpau_vc1_init, .uninit = ff_vdpau_common_uninit, .priv_data_size = sizeof(VDPAUContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; From 2e5c52896b0a07dee714267ab5beab7ad0ae5c90 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 18 Mar 2017 09:36:20 +0100 Subject: [PATCH 1241/3374] pthread_frame: remove some dead code Whatever it was supposed to do. --- libavcodec/pthread_frame.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index f959175db32f7..a52160145e593 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -199,13 +199,7 @@ static attribute_align_arg void *frame_worker_thread(void *arg) } pthread_mutex_lock(&p->progress_mutex); -#if 0 //BUFREF-FIXME - for (i = 0; i < MAX_BUFFERS; i++) - if (p->progress_used[i] && (p->got_frame || p->result<0 || avctx->codec_id != AV_CODEC_ID_H264)) { - p->progress[i][0] = INT_MAX; - p->progress[i][1] = INT_MAX; - } -#endif + atomic_store(&p->state, STATE_INPUT_READY); pthread_cond_broadcast(&p->progress_cond); From 66963d4b8d302611553e7928063c1cb2ff0efdff Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 18 Mar 2017 09:49:20 +0100 Subject: [PATCH 1242/3374] avcodec: remove warning against using frame threading with hwaccels libavcodec now automatically serializes decoding for hwaccels which are not thread-safe. This means API users, which rely on the libavcodec native software fallback mechanism, can now simply enable threading without running into problems. --- libavcodec/utils.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 9b055d2b3ebde..365ee260565c8 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -1076,11 +1076,6 @@ static int setup_hwaccel(AVCodecContext *avctx, AVHWAccel *hwa = find_hwaccel(avctx->codec_id, fmt); int ret = 0; - if (avctx->active_thread_type & FF_THREAD_FRAME) { - av_log(avctx, AV_LOG_WARNING, - "Hardware accelerated decoding with frame threading is known to be unstable and its use is discouraged.\n"); - } - if (!hwa) { av_log(avctx, AV_LOG_ERROR, "Could not find an AVHWAccel for the pixel format: %s", From 4b192ffdbe226461d8a07fd36d655ec13b2c7582 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Tue, 21 Mar 2017 08:03:49 +0100 Subject: [PATCH 1243/3374] ffmpeg: Initialize two stack variables. Avoids reading from uninitialized memory, regression since af1761f7 --- ffmpeg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index dcb7720241853..4e6fc375e6659 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -1434,7 +1434,7 @@ static int reap_filters(int flush) filter = ost->filter->filter; if (!ost->initialized) { - char error[1024]; + 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", @@ -1847,7 +1847,7 @@ static void flush_encoders(void) // Maybe we should just let encoding fail instead. if (!ost->initialized) { FilterGraph *fg = ost->filter->graph; - char error[1024]; + char error[1024] = ""; av_log(NULL, AV_LOG_WARNING, "Finishing stream %d:%d without any data written to it.\n", From b4da4307a91e477e98f62498590a5dafb9d08204 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 21 Mar 2017 11:46:43 +0100 Subject: [PATCH 1244/3374] avcodec/fmvc: small refactoring in decode_type1() Signed-off-by: Paul B Mahol --- libavcodec/fmvc.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/libavcodec/fmvc.c b/libavcodec/fmvc.c index 9c452da351d63..1f8b0c5c17ca3 100644 --- a/libavcodec/fmvc.c +++ b/libavcodec/fmvc.c @@ -380,18 +380,14 @@ static int decode_type1(GetByteContext *gb, PutByteContext *pb) bytestream2_put_byte(pb, bytestream2_get_byte(&gbc)); bytestream2_put_byte(pb, bytestream2_get_byte(&gbc)); bytestream2_put_byte(pb, bytestream2_get_byte(&gbc)); - do { - bytestream2_put_byte(pb, bytestream2_get_byte(&gbc)); - --len; - } while (len && bytestream2_get_bytes_left(&gbc) > 0); } else { bytestream2_put_le32(pb, bytestream2_get_le32(&gbc)); len--; - do { - bytestream2_put_byte(pb, bytestream2_get_byte(&gbc)); - len--; - } while (len && bytestream2_get_bytes_left(&gbc) > 0); } + do { + bytestream2_put_byte(pb, bytestream2_get_byte(&gbc)); + len--; + } while (len && bytestream2_get_bytes_left(&gbc) > 0); } return 0; From 6476bb84bca36b4af5427c5e733fd7b33a985700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Tue, 21 Mar 2017 12:34:50 +0100 Subject: [PATCH 1245/3374] lavc/hwaccel: fix header copyright It was done on a whim because of the FATE header check and was actually meant to be removed before pushing. Also, nobody in review spotted it. Reviewed-by: wm4 --- libavcodec/hwaccel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/hwaccel.h b/libavcodec/hwaccel.h index 17af43707c233..124fbbf1fdf61 100644 --- a/libavcodec/hwaccel.h +++ b/libavcodec/hwaccel.h @@ -1,5 +1,5 @@ /* - * This file is part of FFmpeg and was stolen from Libav. + * 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 From 4cca2f74f25331067cfb234328411bd114664871 Mon Sep 17 00:00:00 2001 From: Kieran Kunhya Date: Mon, 20 Mar 2017 19:40:29 +0000 Subject: [PATCH 1246/3374] vf_drawtext: Fix memory leak --- libavfilter/vf_drawtext.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index 0b9472508f047..bcbe2d9106908 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -709,7 +709,8 @@ static av_cold void uninit(AVFilterContext *ctx) av_expr_free(s->x_pexpr); av_expr_free(s->y_pexpr); - s->x_pexpr = s->y_pexpr = NULL; + av_expr_free(s->a_pexpr); + s->x_pexpr = s->y_pexpr = s->a_pexpr = NULL; av_freep(&s->positions); s->nb_positions = 0; @@ -752,7 +753,8 @@ static int config_input(AVFilterLink *inlink) av_expr_free(s->x_pexpr); av_expr_free(s->y_pexpr); - s->x_pexpr = s->y_pexpr = NULL; + av_expr_free(s->a_pexpr); + s->x_pexpr = s->y_pexpr = s->a_pexpr = NULL; if ((ret = av_expr_parse(&s->x_pexpr, s->x_expr, var_names, NULL, NULL, fun2_names, fun2, 0, ctx)) < 0 || From 2a8a8a2e98136c22f6e07ff669251afb8a033676 Mon Sep 17 00:00:00 2001 From: James Almer Date: Tue, 21 Mar 2017 12:02:35 -0300 Subject: [PATCH 1247/3374] swresample/resample: move resample_free() higher in the file Also make it more readable while at it. Signed-off-by: James Almer --- libswresample/resample.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/libswresample/resample.c b/libswresample/resample.c index 144b2324628d9..7b433d0110b44 100644 --- a/libswresample/resample.c +++ b/libswresample/resample.c @@ -276,6 +276,14 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap return ret; } +static void resample_free(ResampleContext **cc){ + ResampleContext *c = *cc; + if(!c) + return; + av_freep(&c->filter_bank); + av_freep(cc); +} + static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_rate, int filter_size, int phase_shift, int linear, double cutoff0, enum AVSampleFormat format, enum SwrFilterType filter_type, double kaiser_beta, double precision, int cheby, int exact_rational) @@ -371,13 +379,6 @@ static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_r return NULL; } -static void resample_free(ResampleContext **c){ - if(!*c) - return; - av_freep(&(*c)->filter_bank); - av_freep(c); -} - static int rebuild_filter_bank_with_compensation(ResampleContext *c) { uint8_t *new_filter_bank; From db7a05dab0652d4ec6d89394c9024d02f44494a7 Mon Sep 17 00:00:00 2001 From: James Almer Date: Tue, 21 Mar 2017 12:03:44 -0300 Subject: [PATCH 1248/3374] swresample/resample: free existing ResampleContext on reinit Fixes memleak. Reviewed-by: wm4 Reviewed-by: Michael Niedermayer Signed-off-by: James Almer --- libswresample/resample.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libswresample/resample.c b/libswresample/resample.c index 7b433d0110b44..39c242bf413d7 100644 --- a/libswresample/resample.c +++ b/libswresample/resample.c @@ -310,6 +310,7 @@ static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_r if (!c || c->phase_count != phase_count || c->linear!=linear || c->factor != factor || c->filter_length != filter_length || c->format != format || c->filter_type != filter_type || c->kaiser_beta != kaiser_beta) { + resample_free(&c); c = av_mallocz(sizeof(*c)); if (!c) return NULL; From 2c8a3aa985acc906ecab37357f2798da7cb9822d Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Mon, 20 Mar 2017 12:44:42 -0700 Subject: [PATCH 1249/3374] aacsbr: Turnoff in the event of over read. Aliased compressed AAC bytes are almost certainly not meaningful SBR data. In the wild this causes harsh artifacts switching HE-AAC streams that don't have SBR headers aligned with segment boundaries. Turning off SBR falls back to a default set of upsampling parameters that can function as a sort of error concealment. This is consistent with how the decoder handles other sorts of errors. --- libavcodec/aacsbr_template.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/aacsbr_template.c b/libavcodec/aacsbr_template.c index cf8621eee03d9..750131c64c4ad 100644 --- a/libavcodec/aacsbr_template.c +++ b/libavcodec/aacsbr_template.c @@ -1137,6 +1137,7 @@ int AAC_RENAME(ff_decode_sbr_extension)(AACContext *ac, SpectralBandReplication if (bytes_read > cnt) { av_log(ac->avctx, AV_LOG_ERROR, "Expected to read %d SBR bytes actually read %d.\n", cnt, bytes_read); + sbr_turnoff(sbr); } return cnt; } From b15818642b4e8c4ea61bf93bc6920e71a834a535 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 20 Mar 2017 01:55:39 +0100 Subject: [PATCH 1250/3374] avcodec/mpegaudiodec_template: Fix 2 runtime error: signed integer overflow Fixes: 873/clusterfuzz-testcase-5714546230558720 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/mpegaudiodec_template.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/mpegaudiodec_template.c b/libavcodec/mpegaudiodec_template.c index a5ac5817f34b5..6e94cf75f329a 100644 --- a/libavcodec/mpegaudiodec_template.c +++ b/libavcodec/mpegaudiodec_template.c @@ -1038,7 +1038,8 @@ static void compute_stereo(MPADecodeContext *s, GranuleDef *g0, GranuleDef *g1) { int i, j, k, l; int sf_max, sf, len, non_zero_found; - INTFLOAT (*is_tab)[16], *tab0, *tab1, tmp0, tmp1, v1, v2; + INTFLOAT (*is_tab)[16], *tab0, *tab1, v1, v2; + SUINTFLOAT tmp0, tmp1; int non_zero_found_short[3]; /* intensity stereo */ From 423375d4f06ae7103e575a31c23e62e3ba440845 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 20 Mar 2017 02:05:23 +0100 Subject: [PATCH 1251/3374] avcodec/wavpack: Check shift Fixes: runtime error: shift exponent 255 is too large for 32-bit type 'unsigned int' Fixes: 894/clusterfuzz-testcase-4841537823309824 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/wavpack.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index 3d0b01f257c95..2bda3599a8448 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -861,6 +861,12 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, s->and = 1; s->shift = val[3]; } + if (s->shift > 31) { + av_log(avctx, AV_LOG_ERROR, + "Invalid INT32INFO, shift = %d (> 31)\n", s->shift); + s->and = s->or = s->shift = 0; + continue; + } /* original WavPack decoder forces 32-bit lossy sound to be treated * as 24-bit one in order to have proper clipping */ if (s->hybrid && bpp == 4 && s->post_shift < 8 && s->shift > 8) { From d8962ffbd8aaf9485d06eec045b022ba9c39692b Mon Sep 17 00:00:00 2001 From: James Almer Date: Mon, 20 Mar 2017 19:39:49 -0300 Subject: [PATCH 1252/3374] avutil/x86util: don't use movss in VBROADCASTSS macro when src and dst args are the same Reviewed-by: Henrik Gramner Signed-off-by: James Almer --- libavutil/x86/x86util.asm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavutil/x86/x86util.asm b/libavutil/x86/x86util.asm index de7d2d11c108c..fe9a727e22280 100644 --- a/libavutil/x86/x86util.asm +++ b/libavutil/x86/x86util.asm @@ -833,7 +833,9 @@ %if cpuflag(avx) vbroadcastss %1, %2 %else ; sse +%ifnidn %1, %2 movss %1, %2 +%endif shufps %1, %1, 0 %endif %endmacro From 874eb012f75bc18bb6d79ad4bc0912afa21751f3 Mon Sep 17 00:00:00 2001 From: James Almer Date: Mon, 20 Mar 2017 22:53:00 -0300 Subject: [PATCH 1253/3374] avformat/apng: fix setting frame delay when max_fps is set to no limit Reviewed-by: Michael Niedermayer Signed-off-by: James Almer --- libavformat/apngdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/apngdec.c b/libavformat/apngdec.c index bb17896ee50ef..7a284e32c2355 100644 --- a/libavformat/apngdec.c +++ b/libavformat/apngdec.c @@ -269,7 +269,7 @@ static int decode_fctl_chunk(AVFormatContext *s, APNGDemuxContext *ctx, AVPacket /* default is hundredths of seconds */ if (!delay_den) delay_den = 100; - if (!delay_num || delay_den / delay_num > ctx->max_fps) { + if (!delay_num || (ctx->max_fps && delay_den / delay_num > ctx->max_fps)) { delay_num = 1; delay_den = ctx->default_fps; } From 7bfbb7229971a5220fed07bb931e6ff1030a319a Mon Sep 17 00:00:00 2001 From: James Almer Date: Mon, 20 Mar 2017 22:55:11 -0300 Subject: [PATCH 1254/3374] avformat/apng: set max_fps to no limit by default Should fix ticket #6252 Reviewed-by: Michael Niedermayer Signed-off-by: James Almer --- libavformat/apngdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/apngdec.c b/libavformat/apngdec.c index 7a284e32c2355..75dcf74a0ca7c 100644 --- a/libavformat/apngdec.c +++ b/libavformat/apngdec.c @@ -421,7 +421,7 @@ static const AVOption options[] = { { "ignore_loop", "ignore loop setting" , offsetof(APNGDemuxContext, ignore_loop), AV_OPT_TYPE_BOOL, { .i64 = 1 } , 0, 1 , AV_OPT_FLAG_DECODING_PARAM }, { "max_fps" , "maximum framerate (0 is no limit)" , offsetof(APNGDemuxContext, max_fps), - AV_OPT_TYPE_INT, { .i64 = DEFAULT_APNG_FPS }, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, + AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, { "default_fps", "default framerate (0 is as fast as possible)", offsetof(APNGDemuxContext, default_fps), AV_OPT_TYPE_INT, { .i64 = DEFAULT_APNG_FPS }, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, { NULL }, From 51546504133cbea93284aeda3e30e531fe2c1633 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Wed, 15 Mar 2017 01:00:57 +0100 Subject: [PATCH 1255/3374] avcodec/avcodec.h: clarify decoupled decode/encode API docs Reviewed-by: wm4 Signed-off-by: Marton Balint --- libavcodec/avcodec.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index f9ebd14a7eaa9..3e3c37278a45f 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -142,8 +142,9 @@ * * Not all codecs will follow a rigid and predictable dataflow; the only * guarantee is that an AVERROR(EAGAIN) return value on a send/receive call on - * one end implies that a receive/send call on the other end will succeed. In - * general, no codec will permit unlimited buffering of input or output. + * one end implies that a receive/send call on the other end will succeed, or + * at least will not fail with AVERROR(EAGAIN). In general, no codec will + * permit unlimited buffering of input or output. * * This API replaces the following legacy functions: * - avcodec_decode_video2() and avcodec_decode_audio4(): From 9365dfcbf665b83b2e60c5ec5e2abf1f0a49e2c3 Mon Sep 17 00:00:00 2001 From: Jun Zhao Date: Sun, 19 Mar 2017 15:44:46 +0800 Subject: [PATCH 1256/3374] hwcontext: fix comments for av_hwdevice_ctx_alloc() fix the wrong comments for av_hwdevice_ctx_alloc() Signed-off-by: Jun Zhao Signed-off-by: Mark Thompson --- libavutil/hwcontext.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h index 785da090b3fc4..f5bc077897252 100644 --- a/libavutil/hwcontext.h +++ b/libavutil/hwcontext.h @@ -223,10 +223,9 @@ typedef struct AVHWFramesContext { } AVHWFramesContext; /** - * Allocate an AVHWDeviceContext for a given pixel format. + * Allocate an AVHWDeviceContext for a given hardware type. * - * @param format a hwaccel pixel format (AV_PIX_FMT_FLAG_HWACCEL must be set - * on the corresponding format descriptor) + * @param type the type of the hardware device to allocate. * @return a reference to the newly created AVHWDeviceContext on success or NULL * on failure. */ From 607bffbed2872641b7f63127934f0398041fa55e Mon Sep 17 00:00:00 2001 From: Matthias Hunstock Date: Mon, 20 Mar 2017 00:16:36 +0100 Subject: [PATCH 1257/3374] avdevice/decklink: add format_code of display mode to list_format output Signed-off-by: Matthias Hunstock Signed-off-by: Marton Balint --- libavdevice/decklink_common.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp index 8b499c5640328..26c0776b020a8 100644 --- a/libavdevice/decklink_common.cpp +++ b/libavdevice/decklink_common.cpp @@ -33,6 +33,7 @@ extern "C" { #include "libavformat/avformat.h" #include "libavformat/internal.h" #include "libavutil/imgutils.h" +#include "libavutil/bswap.h" } #include "decklink_common.h" @@ -276,6 +277,7 @@ int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direct struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; IDeckLinkDisplayModeIterator *itermode; IDeckLinkDisplayMode *mode; + uint32_t format_code; int i=0; HRESULT res; @@ -297,13 +299,14 @@ int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direct return AVERROR(EIO); } - av_log(avctx, AV_LOG_INFO, "Supported formats for '%s':\n", + av_log(avctx, AV_LOG_INFO, "Supported formats for '%s':\n\tmode\tformat_code\tdescription", avctx->filename); while (itermode->Next(&mode) == S_OK) { BMDTimeValue tb_num, tb_den; mode->GetFrameRate(&tb_num, &tb_den); - av_log(avctx, AV_LOG_INFO, "\t%d\t%ldx%ld at %d/%d fps", - ++i,mode->GetWidth(), mode->GetHeight(), + format_code = av_bswap32(mode->GetDisplayMode()); + av_log(avctx, AV_LOG_INFO, "\n\t%d\t%.4s\t\t%ldx%ld at %d/%d fps", + ++i, (char*) &format_code, mode->GetWidth(), mode->GetHeight(), (int) tb_den, (int) tb_num); switch (mode->GetFieldDominance()) { case bmdLowerFieldFirst: @@ -311,9 +314,9 @@ int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direct case bmdUpperFieldFirst: av_log(avctx, AV_LOG_INFO, " (interlaced, upper field first)"); break; } - av_log(avctx, AV_LOG_INFO, "\n"); mode->Release(); } + av_log(avctx, AV_LOG_INFO, "\n"); itermode->Release(); From b3a2adaac6526428843a1fa74eb9f896e898a78a Mon Sep 17 00:00:00 2001 From: Matthias Hunstock Date: Mon, 20 Mar 2017 00:16:37 +0100 Subject: [PATCH 1258/3374] avdevice/decklink: new option 'format_code' to set video format by fourCC Signed-off-by: Matthias Hunstock Signed-off-by: Marton Balint --- doc/indevs.texi | 14 ++++++++++---- libavdevice/decklink_common.cpp | 16 ++++++++++++---- libavdevice/decklink_common_c.h | 1 + libavdevice/decklink_dec.cpp | 5 +++-- libavdevice/decklink_dec_c.c | 1 + libavdevice/version.h | 2 +- 6 files changed, 28 insertions(+), 11 deletions(-) diff --git a/doc/indevs.texi b/doc/indevs.texi index 27cc3d5dc37f1..51c304f3ecda2 100644 --- a/doc/indevs.texi +++ b/doc/indevs.texi @@ -233,6 +233,12 @@ Defaults to @option{false}. If set to @option{true}, print a list of supported formats and exit. Defaults to @option{false}. +@item format_code +This sets the input video format to the format given by the FourCC. To see +the supported values of your device(s) use @option{list_formats}. +Note that there is a FourCC @option{'pal '} that can also be used +as @option{pal} (3 letters). + @item bm_v210 If set to @samp{1}, video is captured in 10 bit v210 instead of uyvy422. Not all Blackmagic devices support this option. @@ -296,21 +302,21 @@ ffmpeg -f decklink -list_formats 1 -i 'Intensity Pro' @end example @item -Capture video clip at 1080i50 (format 11): +Capture video clip at 1080i50: @example -ffmpeg -f decklink -i 'Intensity Pro@@11' -acodec copy -vcodec copy output.avi +ffmpeg -format_code Hi50 -f decklink -i 'Intensity Pro' -acodec copy -vcodec copy output.avi @end example @item Capture video clip at 1080i50 10 bit: @example -ffmpeg -bm_v210 1 -f decklink -i 'UltraStudio Mini Recorder@@11' -acodec copy -vcodec copy output.avi +ffmpeg -bm_v210 1 -format_code Hi50 -f decklink -i 'UltraStudio Mini Recorder' -acodec copy -vcodec copy output.avi @end example @item Capture video clip at 1080i50 with 16 audio channels: @example -ffmpeg -channels 16 -f decklink -i 'UltraStudio Mini Recorder@@11' -acodec copy -vcodec copy output.avi +ffmpeg -channels 16 -format_code Hi50 -f decklink -i 'UltraStudio Mini Recorder' -acodec copy -vcodec copy output.avi @end example @end itemize diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp index 26c0776b020a8..f17c263c4bf49 100644 --- a/libavdevice/decklink_common.cpp +++ b/libavdevice/decklink_common.cpp @@ -33,6 +33,7 @@ extern "C" { #include "libavformat/avformat.h" #include "libavformat/internal.h" #include "libavutil/imgutils.h" +#include "libavutil/intreadwrite.h" #include "libavutil/bswap.h" } @@ -158,8 +159,8 @@ int ff_decklink_set_format(AVFormatContext *avctx, int i = 1; HRESULT res; - av_log(avctx, AV_LOG_DEBUG, "Trying to find mode for frame size %dx%d, frame timing %d/%d, field order %d, direction %d, mode number %d\n", - width, height, tb_num, tb_den, field_order, direction, num); + av_log(avctx, AV_LOG_DEBUG, "Trying to find mode for frame size %dx%d, frame timing %d/%d, field order %d, direction %d, mode number %d, format code %s\n", + width, height, tb_num, tb_den, field_order, direction, num, (cctx->format_code) ? cctx->format_code : "(unset)"); if (ctx->duplex_mode) { DECKLINK_BOOL duplex_supported = false; @@ -196,12 +197,17 @@ int ff_decklink_set_format(AVFormatContext *avctx, return AVERROR(EIO); } + char format_buf[] = " "; + if (cctx->format_code) + memcpy(format_buf, cctx->format_code, FFMIN(strlen(cctx->format_code), sizeof(format_buf))); + BMDDisplayMode target_mode = (BMDDisplayMode)AV_RB32(format_buf); AVRational target_tb = av_make_q(tb_num, tb_den); ctx->bmd_mode = bmdModeUnknown; while ((ctx->bmd_mode == bmdModeUnknown) && itermode->Next(&mode) == S_OK) { BMDTimeValue bmd_tb_num, bmd_tb_den; int bmd_width = mode->GetWidth(); int bmd_height = mode->GetHeight(); + BMDDisplayMode bmd_mode = mode->GetDisplayMode(); BMDFieldDominance bmd_field_dominance = mode->GetFieldDominance(); mode->GetFrameRate(&bmd_tb_num, &bmd_tb_den); @@ -210,8 +216,10 @@ int ff_decklink_set_format(AVFormatContext *avctx, if ((bmd_width == width && bmd_height == height && !av_cmp_q(mode_tb, target_tb) && - field_order_eq(field_order, bmd_field_dominance)) || i == num) { - ctx->bmd_mode = mode->GetDisplayMode(); + field_order_eq(field_order, bmd_field_dominance)) + || i == num + || target_mode == bmd_mode) { + ctx->bmd_mode = bmd_mode; ctx->bmd_width = bmd_width; ctx->bmd_height = bmd_height; ctx->bmd_tb_den = bmd_tb_den; diff --git a/libavdevice/decklink_common_c.h b/libavdevice/decklink_common_c.h index d5656317aece6..72c5f9a71be17 100644 --- a/libavdevice/decklink_common_c.h +++ b/libavdevice/decklink_common_c.h @@ -47,6 +47,7 @@ struct decklink_cctx { int audio_input; int video_input; int draw_bars; + char *format_code; }; #endif /* AVDEVICE_DECKLINK_COMMON_C_H */ diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index 7df841b806389..ffe65db0d074f 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -539,9 +539,10 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) goto error; } - if (mode_num > 0) { + if (mode_num > 0 || cctx->format_code) { if (ff_decklink_set_format(avctx, DIRECTION_IN, mode_num) < 0) { - av_log(avctx, AV_LOG_ERROR, "Could not set mode %d for %s\n", mode_num, fname); + av_log(avctx, AV_LOG_ERROR, "Could not set mode number %d or format code %s for %s\n", + mode_num, (cctx->format_code) ? cctx->format_code : "(unset)", fname); ret = AVERROR(EIO); goto error; } diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c index 31818d2397cea..5b26d1257c461 100644 --- a/libavdevice/decklink_dec_c.c +++ b/libavdevice/decklink_dec_c.c @@ -31,6 +31,7 @@ static const AVOption options[] = { { "list_devices", "list available devices" , OFFSET(list_devices), AV_OPT_TYPE_INT , { .i64 = 0 }, 0, 1, DEC }, { "list_formats", "list supported formats" , OFFSET(list_formats), AV_OPT_TYPE_INT , { .i64 = 0 }, 0, 1, DEC }, + { "format_code", "set format by fourcc" , OFFSET(format_code), AV_OPT_TYPE_STRING, { .str = NULL}, 0, 0, DEC }, { "bm_v210", "v210 10 bit per channel" , OFFSET(v210), AV_OPT_TYPE_INT , { .i64 = 0 }, 0, 1, DEC }, { "teletext_lines", "teletext lines bitmask", OFFSET(teletext_lines), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, 0x7ffffffffLL, DEC, "teletext_lines"}, { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0x7fff9fffeLL}, 0, 0, DEC, "teletext_lines"}, diff --git a/libavdevice/version.h b/libavdevice/version.h index a58cb0e91414e..74af12960458f 100644 --- a/libavdevice/version.h +++ b/libavdevice/version.h @@ -29,7 +29,7 @@ #define LIBAVDEVICE_VERSION_MAJOR 57 #define LIBAVDEVICE_VERSION_MINOR 3 -#define LIBAVDEVICE_VERSION_MICRO 100 +#define LIBAVDEVICE_VERSION_MICRO 101 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ LIBAVDEVICE_VERSION_MINOR, \ From aee046a895db972ce6ac49950dafbad99445191a Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 22 Mar 2017 00:14:56 -0300 Subject: [PATCH 1259/3374] x86/audiodsp: remove an unnecessary movss --- libavcodec/x86/audiodsp.asm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/x86/audiodsp.asm b/libavcodec/x86/audiodsp.asm index 8ef2a8c680343..a44e064a55311 100644 --- a/libavcodec/x86/audiodsp.asm +++ b/libavcodec/x86/audiodsp.asm @@ -140,7 +140,8 @@ cglobal vector_clipf, 3, 3, 6, dst, src, len, min, max VBROADCASTSS m0, minm VBROADCASTSS m1, maxm %elif WIN64 - VBROADCASTSS m0, m3 + SWAP 0, 3 + VBROADCASTSS m0, m0 VBROADCASTSS m1, maxm %else ; 64bit sysv VBROADCASTSS m0, m0 From 8ddadf56f621ddaeaa877e5739c03645ee7e57f8 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Wed, 22 Mar 2017 18:06:14 +0800 Subject: [PATCH 1260/3374] avformat/rtmpproto: change rtmp_open from url_open to url_open2 use the option set by user Reported-by: Lancelot Lai Signed-off-by: Steven Liu --- libavformat/rtmpproto.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 5d7ad795ed4c4..7b2bd81bd12be 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -2604,14 +2604,13 @@ static int inject_fake_duration_metadata(RTMPContext *rt) * and 'playpath' is a file name (the rest of the path, * may be prefixed with "mp4:") */ -static int rtmp_open(URLContext *s, const char *uri, int flags) +static int rtmp_open(URLContext *s, const char *uri, int flags, AVDictionary **opts) { RTMPContext *rt = s->priv_data; char proto[8], hostname[256], path[1024], auth[100], *fname; char *old_app, *qmark, *n, fname_buffer[1024]; uint8_t buf[2048]; int port; - AVDictionary *opts = NULL; int ret; if (rt->listen_timeout > 0) @@ -2648,7 +2647,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) } if (!strcmp(proto, "rtmpt") || !strcmp(proto, "rtmpts")) { if (!strcmp(proto, "rtmpts")) - av_dict_set(&opts, "ffrtmphttp_tls", "1", 1); + av_dict_set(opts, "ffrtmphttp_tls", "1", 1); /* open the http tunneling connection */ ff_url_join(buf, sizeof(buf), "ffrtmphttp", NULL, hostname, port, NULL); @@ -2659,7 +2658,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) ff_url_join(buf, sizeof(buf), "tls", NULL, hostname, port, NULL); } else if (!strcmp(proto, "rtmpe") || (!strcmp(proto, "rtmpte"))) { if (!strcmp(proto, "rtmpte")) - av_dict_set(&opts, "ffrtmpcrypt_tunneling", "1", 1); + av_dict_set(opts, "ffrtmpcrypt_tunneling", "1", 1); /* open the encrypted connection */ ff_url_join(buf, sizeof(buf), "ffrtmpcrypt", NULL, hostname, port, NULL); @@ -2678,7 +2677,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) reconnect: if ((ret = ffurl_open_whitelist(&rt->stream, buf, AVIO_FLAG_READ_WRITE, - &s->interrupt_callback, &opts, + &s->interrupt_callback, opts, s->protocol_whitelist, s->protocol_blacklist, s)) < 0) { av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf); goto fail; @@ -2896,7 +2895,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) return 0; fail: - av_dict_free(&opts); + av_dict_free(opts); rtmp_close(s); return ret; } @@ -3141,7 +3140,7 @@ static const AVClass flavor##_class = { \ \ const URLProtocol ff_##flavor##_protocol = { \ .name = #flavor, \ - .url_open = rtmp_open, \ + .url_open2 = rtmp_open, \ .url_read = rtmp_read, \ .url_read_seek = rtmp_seek, \ .url_read_pause = rtmp_pause, \ From ce10e4cb1f21d1ef65ab679f5beb88842f971357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 22 Mar 2017 11:42:42 +0100 Subject: [PATCH 1261/3374] doc/libav-merge: create a special "extra changes" section --- doc/libav-merge.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/libav-merge.txt b/doc/libav-merge.txt index e94a7497703bf..03b433fbf95e6 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 - VAAPI VP8 decode hwaccel (currently under review: http://ffmpeg.org/pipermail/ffmpeg-devel/2017-February/thread.html#207348) -- Switching examples to the new encode/decode API (see 67d28f4a0f) Collateral damage that needs work locally: ------------------------------------------ @@ -103,3 +102,9 @@ Collateral damage that needs work locally: - Merge proresdec2.c and proresdec_lgpl.c - Merge proresenc_anatoliy.c and proresenc_kostya.c - Remove ADVANCED_PARSER in libavcodec/hevc_parser.c + +Extra changes needed to be aligned with Libav: +---------------------------------------------- + +- Switching our examples to the new encode/decode API (see 67d28f4a0f) +- AC3 speed-up for our fixed version (see a9ba59591e) From 9dc57688c8e250a669c8f601b909eaf411199d94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 22 Mar 2017 11:46:13 +0100 Subject: [PATCH 1262/3374] lavc/mips: temporally disable ac3 downmix --- doc/libav-merge.txt | 1 + libavcodec/mips/ac3dsp_mips.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/libav-merge.txt b/doc/libav-merge.txt index 03b433fbf95e6..9f3c9c2a9ed66 100644 --- a/doc/libav-merge.txt +++ b/doc/libav-merge.txt @@ -102,6 +102,7 @@ Collateral damage that needs work locally: - Merge proresdec2.c and proresdec_lgpl.c - Merge proresenc_anatoliy.c and proresenc_kostya.c - Remove ADVANCED_PARSER in libavcodec/hevc_parser.c +- Fix MIPS AC3 downmix Extra changes needed to be aligned with Libav: ---------------------------------------------- diff --git a/libavcodec/mips/ac3dsp_mips.c b/libavcodec/mips/ac3dsp_mips.c index f9aaf15639a35..e5cee16081934 100644 --- a/libavcodec/mips/ac3dsp_mips.c +++ b/libavcodec/mips/ac3dsp_mips.c @@ -409,7 +409,7 @@ void ff_ac3dsp_init_mips(AC3DSPContext *c, int bit_exact) { #if HAVE_MIPSFPU #if !HAVE_MIPS32R6 && !HAVE_MIPS64R6 c->float_to_fixed24 = float_to_fixed24_mips; - c->downmix = ac3_downmix_mips; + //c->downmix = ac3_downmix_mips; #endif #endif From 0dbfed08d06a0d8f6da1bc0ff5ef06bf11e51302 Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 22 Mar 2017 10:27:46 -0300 Subject: [PATCH 1263/3374] fate: update ref file for apng-clock test --- tests/ref/fate/apng-clock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ref/fate/apng-clock b/tests/ref/fate/apng-clock index 54db0944b705f..c0480fd4e6c53 100644 --- a/tests/ref/fate/apng-clock +++ b/tests/ref/fate/apng-clock @@ -1,4 +1,4 @@ -#tb 0: 6667/100000 +#tb 0: 1/25 #media_type 0: video #codec_id 0: rawvideo #dimensions 0: 150x150 From c7904af057239104774244954d1f5a5a7b2a2d04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 22 Mar 2017 16:15:42 +0100 Subject: [PATCH 1264/3374] lavc/huffyuvdsp: remove unused ppc init prototype --- libavcodec/huffyuvdsp.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libavcodec/huffyuvdsp.h b/libavcodec/huffyuvdsp.h index 7680f2ec9c98a..f9af09e602961 100644 --- a/libavcodec/huffyuvdsp.h +++ b/libavcodec/huffyuvdsp.h @@ -47,7 +47,6 @@ typedef struct HuffYUVDSPContext { } HuffYUVDSPContext; void ff_huffyuvdsp_init(HuffYUVDSPContext *c, AVCodecContext *avctx); -void ff_huffyuvdsp_init_ppc(HuffYUVDSPContext *c, AVCodecContext *avctx); void ff_huffyuvdsp_init_x86(HuffYUVDSPContext *c, AVCodecContext *avctx); #endif /* AVCODEC_HUFFYUVDSP_H */ From af607b7e0787a8d3af418ed2a03c48669ba3397c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 22 Mar 2017 16:21:20 +0100 Subject: [PATCH 1265/3374] lavc/huffyuvdsp: only transmit the pix_fmt instead of the whole avctx Only the pixel format is required in that init function. This will also simplify the incoming merge. --- libavcodec/huffyuvdec.c | 2 +- libavcodec/huffyuvdsp.c | 4 ++-- libavcodec/huffyuvdsp.h | 6 +++--- libavcodec/x86/huffyuvdsp_init.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libavcodec/huffyuvdec.c b/libavcodec/huffyuvdec.c index c68eadd933587..5572b9819fe25 100644 --- a/libavcodec/huffyuvdec.c +++ b/libavcodec/huffyuvdec.c @@ -297,7 +297,7 @@ static av_cold int decode_init(AVCodecContext *avctx) if (ret < 0) return ret; - ff_huffyuvdsp_init(&s->hdsp, avctx); + ff_huffyuvdsp_init(&s->hdsp, avctx->pix_fmt); ff_llviddsp_init(&s->llviddsp); memset(s->vlc, 0, 4 * sizeof(VLC)); diff --git a/libavcodec/huffyuvdsp.c b/libavcodec/huffyuvdsp.c index e770923bb22d0..7b865fe40c5ef 100644 --- a/libavcodec/huffyuvdsp.c +++ b/libavcodec/huffyuvdsp.c @@ -80,12 +80,12 @@ static void add_hfyu_left_pred_bgr32_c(uint8_t *dst, const uint8_t *src, left[A] = a; } -av_cold void ff_huffyuvdsp_init(HuffYUVDSPContext *c, AVCodecContext *avctx) +av_cold void ff_huffyuvdsp_init(HuffYUVDSPContext *c, enum AVPixelFormat pix_fmt) { c->add_int16 = add_int16_c; c->add_hfyu_median_pred_int16 = add_hfyu_median_pred_int16_c; c->add_hfyu_left_pred_bgr32 = add_hfyu_left_pred_bgr32_c; if (ARCH_X86) - ff_huffyuvdsp_init_x86(c, avctx); + ff_huffyuvdsp_init_x86(c, pix_fmt); } diff --git a/libavcodec/huffyuvdsp.h b/libavcodec/huffyuvdsp.h index f9af09e602961..e5f5b05466761 100644 --- a/libavcodec/huffyuvdsp.h +++ b/libavcodec/huffyuvdsp.h @@ -20,8 +20,8 @@ #define AVCODEC_HUFFYUVDSP_H #include +#include "libavutil/pixfmt.h" #include "config.h" -#include "avcodec.h" #if HAVE_BIGENDIAN #define B 3 @@ -46,7 +46,7 @@ typedef struct HuffYUVDSPContext { intptr_t w, uint8_t *left); } HuffYUVDSPContext; -void ff_huffyuvdsp_init(HuffYUVDSPContext *c, AVCodecContext *avctx); -void ff_huffyuvdsp_init_x86(HuffYUVDSPContext *c, AVCodecContext *avctx); +void ff_huffyuvdsp_init(HuffYUVDSPContext *c, enum AVPixelFormat pix_fmt); +void ff_huffyuvdsp_init_x86(HuffYUVDSPContext *c, enum AVPixelFormat pix_fmt); #endif /* AVCODEC_HUFFYUVDSP_H */ diff --git a/libavcodec/x86/huffyuvdsp_init.c b/libavcodec/x86/huffyuvdsp_init.c index f72d759ef2e81..26cf6214d8fb0 100644 --- a/libavcodec/x86/huffyuvdsp_init.c +++ b/libavcodec/x86/huffyuvdsp_init.c @@ -34,10 +34,10 @@ void ff_add_hfyu_left_pred_bgr32_sse2(uint8_t *dst, const uint8_t *src, intptr_t w, uint8_t *left); void ff_add_hfyu_median_pred_int16_mmxext(uint16_t *dst, const uint16_t *top, const uint16_t *diff, unsigned mask, int w, int *left, int *left_top); -av_cold void ff_huffyuvdsp_init_x86(HuffYUVDSPContext *c, AVCodecContext *avctx) +av_cold void ff_huffyuvdsp_init_x86(HuffYUVDSPContext *c, enum AVPixelFormat pix_fmt) { int cpu_flags = av_get_cpu_flags(); - const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(avctx->pix_fmt); + const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(pix_fmt); if (ARCH_X86_32 && EXTERNAL_MMX(cpu_flags)) { c->add_hfyu_left_pred_bgr32 = ff_add_hfyu_left_pred_bgr32_mmx; From 67d8eabdbb29efb66c9d813635732c9d6aa5c437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 22 Mar 2017 17:31:15 +0100 Subject: [PATCH 1266/3374] lavu/buffer: drop USE_ATOMICS USE_ATOMICS is only set if there is no thread implementation enabled, in which case you can't expect any lock mechanism from FFmpeg. This is also conflicting with the incoming use of stdatomic. --- libavutil/buffer.c | 71 ------------------------------------- libavutil/buffer_internal.h | 2 -- libavutil/thread.h | 4 --- 3 files changed, 77 deletions(-) diff --git a/libavutil/buffer.c b/libavutil/buffer.c index 478e4880e5c60..33cb513cc9bb6 100644 --- a/libavutil/buffer.c +++ b/libavutil/buffer.c @@ -284,44 +284,6 @@ void av_buffer_pool_uninit(AVBufferPool **ppool) buffer_pool_free(pool); } -#if USE_ATOMICS -/* remove the whole buffer list from the pool and return it */ -static BufferPoolEntry *get_pool(AVBufferPool *pool) -{ - BufferPoolEntry *cur = *(void * volatile *)&pool->pool, *last = NULL; - - while (cur != last) { - last = cur; - cur = avpriv_atomic_ptr_cas((void * volatile *)&pool->pool, last, NULL); - if (!cur) - return NULL; - } - - return cur; -} - -static void add_to_pool(BufferPoolEntry *buf) -{ - AVBufferPool *pool; - BufferPoolEntry *cur, *end = buf; - - if (!buf) - return; - pool = buf->pool; - - while (end->next) - end = end->next; - - while (avpriv_atomic_ptr_cas((void * volatile *)&pool->pool, NULL, buf)) { - /* pool is not empty, retrieve it and append it to our list */ - cur = get_pool(pool); - end->next = cur; - while (end->next) - end = end->next; - } -} -#endif - static void pool_release_buffer(void *opaque, uint8_t *data) { BufferPoolEntry *buf = opaque; @@ -330,14 +292,10 @@ static void pool_release_buffer(void *opaque, uint8_t *data) if(CONFIG_MEMORY_POISONING) memset(buf->data, FF_MEMORY_POISON, pool->size); -#if USE_ATOMICS - add_to_pool(buf); -#else ff_mutex_lock(&pool->mutex); buf->next = pool->pool; pool->pool = buf; ff_mutex_unlock(&pool->mutex); -#endif if (!avpriv_atomic_int_add_and_fetch(&pool->refcount, -1)) buffer_pool_free(pool); @@ -369,11 +327,6 @@ static AVBufferRef *pool_alloc_buffer(AVBufferPool *pool) ret->buffer->opaque = buf; ret->buffer->free = pool_release_buffer; -#if USE_ATOMICS - avpriv_atomic_int_add_and_fetch(&pool->refcount, 1); - avpriv_atomic_int_add_and_fetch(&pool->nb_allocated, 1); -#endif - return ret; } @@ -382,29 +335,6 @@ AVBufferRef *av_buffer_pool_get(AVBufferPool *pool) AVBufferRef *ret; BufferPoolEntry *buf; -#if USE_ATOMICS - /* check whether the pool is empty */ - buf = get_pool(pool); - if (!buf && pool->refcount <= pool->nb_allocated) { - av_log(NULL, AV_LOG_DEBUG, "Pool race dectected, spining to avoid overallocation and eventual OOM\n"); - while (!buf && avpriv_atomic_int_get(&pool->refcount) <= avpriv_atomic_int_get(&pool->nb_allocated)) - buf = get_pool(pool); - } - - if (!buf) - return pool_alloc_buffer(pool); - - /* keep the first entry, return the rest of the list to the pool */ - add_to_pool(buf->next); - buf->next = NULL; - - ret = av_buffer_create(buf->data, pool->size, pool_release_buffer, - buf, 0); - if (!ret) { - add_to_pool(buf); - return NULL; - } -#else ff_mutex_lock(&pool->mutex); buf = pool->pool; if (buf) { @@ -418,7 +348,6 @@ AVBufferRef *av_buffer_pool_get(AVBufferPool *pool) ret = pool_alloc_buffer(pool); } ff_mutex_unlock(&pool->mutex); -#endif if (ret) avpriv_atomic_int_add_and_fetch(&pool->refcount, 1); diff --git a/libavutil/buffer_internal.h b/libavutil/buffer_internal.h index 29ce8a643c0a4..bbd40a04e47a7 100644 --- a/libavutil/buffer_internal.h +++ b/libavutil/buffer_internal.h @@ -87,8 +87,6 @@ struct AVBufferPool { */ volatile int refcount; - volatile int nb_allocated; - int size; void *opaque; AVBufferRef* (*alloc)(int size); diff --git a/libavutil/thread.h b/libavutil/thread.h index 32ddf40365afe..6e5744736becb 100644 --- a/libavutil/thread.h +++ b/libavutil/thread.h @@ -26,8 +26,6 @@ #if HAVE_PTHREADS || HAVE_W32THREADS || HAVE_OS2THREADS -#define USE_ATOMICS 0 - #if HAVE_PTHREADS #include @@ -146,8 +144,6 @@ static inline int strict_pthread_once(pthread_once_t *once_control, void (*init_ #else -#define USE_ATOMICS 1 - #define AVMutex char #define ff_mutex_init(mutex, attr) (0) From cb763a9ba849678cf5830ccb15e8df0d984cad27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 22 Mar 2017 18:16:58 +0100 Subject: [PATCH 1267/3374] lavc/bitstream: remove unused atomic.h include --- libavcodec/bitstream.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libavcodec/bitstream.c b/libavcodec/bitstream.c index c26650099f598..69deabe770108 100644 --- a/libavcodec/bitstream.c +++ b/libavcodec/bitstream.c @@ -28,7 +28,6 @@ * bitstream api. */ -#include "libavutil/atomic.h" #include "libavutil/avassert.h" #include "libavutil/qsort.h" #include "avcodec.h" From cf1c8a379e9fa1a7715b44e629365cc02a42e620 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 22 Mar 2017 18:17:44 +0100 Subject: [PATCH 1268/3374] lavc/bitstream_filter: remove unused atomic.h include --- libavcodec/bitstream_filter.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libavcodec/bitstream_filter.c b/libavcodec/bitstream_filter.c index 02878e3bf3e97..e9291aba192c7 100644 --- a/libavcodec/bitstream_filter.c +++ b/libavcodec/bitstream_filter.c @@ -21,7 +21,6 @@ #include #include "avcodec.h" -#include "libavutil/atomic.h" #include "libavutil/internal.h" #include "libavutil/mem.h" #include "libavutil/opt.h" From 38d7cc22f7782de2e7aca8eda2c2c2996f7f5700 Mon Sep 17 00:00:00 2001 From: Rostislav Pehlivanov Date: Wed, 22 Mar 2017 17:17:04 +0000 Subject: [PATCH 1269/3374] mdct15: fix left shift of a negative value Should fix Chromium issue 704064. Signed-off-by: Rostislav Pehlivanov --- libavcodec/mdct15.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/mdct15.c b/libavcodec/mdct15.c index a6bea2d46946e..e0382091ba941 100644 --- a/libavcodec/mdct15.c +++ b/libavcodec/mdct15.c @@ -88,7 +88,7 @@ static inline int init_pfa_reindex_tabs(MDCT15Context *s) for (j = 0; j < 15; j++) { const int q_pre = ((l_ptwo * j)/15 + i) >> b_ptwo; const int q_post = (((j*inv_1)/15) + (i*inv_2)) >> b_ptwo; - const int k_pre = 15*i + ((j - q_pre*15) << b_ptwo); + const int k_pre = 15*i + (j - q_pre*15)*(1 << b_ptwo); const int k_post = i*inv_2*15 + j*inv_1 - 15*q_post*l_ptwo; s->pfa_prereindex[i*15 + j] = k_pre; s->pfa_postreindex[k_post] = l_ptwo*j + i; From e28bd75f7cfd17169562d7c7f5a4a5386aba68e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 22 Mar 2017 18:23:17 +0100 Subject: [PATCH 1270/3374] lavc/hevc: use atomics for wpp_err --- libavcodec/hevc.c | 11 ++++++----- libavcodec/hevc.h | 4 +++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c index 0b4a719fe779f..0b007f16e5d2c 100644 --- a/libavcodec/hevc.c +++ b/libavcodec/hevc.c @@ -23,7 +23,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "libavutil/atomic.h" #include "libavutil/attributes.h" #include "libavutil/common.h" #include "libavutil/display.h" @@ -2406,7 +2405,7 @@ static int hls_decode_entry_wpp(AVCodecContext *avctxt, void *input_ctb_row, int ff_thread_await_progress2(s->avctx, ctb_row, thread, SHIFT_CTB_WPP); - if (avpriv_atomic_int_get(&s1->wpp_err)){ + if (atomic_load(&s1->wpp_err)) { ff_thread_report_progress2(s->avctx, ctb_row , thread, SHIFT_CTB_WPP); return 0; } @@ -2417,7 +2416,7 @@ static int hls_decode_entry_wpp(AVCodecContext *avctxt, void *input_ctb_row, int if (more_data < 0) { s->tab_slice_address[ctb_addr_rs] = -1; - avpriv_atomic_int_set(&s1->wpp_err, 1); + atomic_store(&s1->wpp_err, 1); ff_thread_report_progress2(s->avctx, ctb_row ,thread, SHIFT_CTB_WPP); return more_data; } @@ -2429,7 +2428,7 @@ static int hls_decode_entry_wpp(AVCodecContext *avctxt, void *input_ctb_row, int ff_hevc_hls_filters(s, x_ctb, y_ctb, ctb_size); if (!more_data && (x_ctb+ctb_size) < s->ps.sps->width && ctb_row != s->sh.num_entry_point_offsets) { - avpriv_atomic_int_set(&s1->wpp_err, 1); + atomic_store(&s1->wpp_err, 1); ff_thread_report_progress2(s->avctx, ctb_row ,thread, SHIFT_CTB_WPP); return 0; } @@ -2530,7 +2529,7 @@ static int hls_slice_data_wpp(HEVCContext *s, const H2645NAL *nal) s->sList[i]->HEVClc = s->HEVClcList[i]; } - avpriv_atomic_int_set(&s->wpp_err, 0); + atomic_store(&s->wpp_err, 0); ff_reset_entries(s->avctx); for (i = 0; i <= s->sh.num_entry_point_offsets; i++) { @@ -3340,6 +3339,8 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx) s->picture_struct = 0; s->eos = 1; + atomic_init(&s->wpp_err, 0); + if(avctx->active_thread_type & FF_THREAD_SLICE) s->threads_number = avctx->thread_count; else diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h index 6a3c7506c2a3e..ff9a6cbf6d72f 100644 --- a/libavcodec/hevc.h +++ b/libavcodec/hevc.h @@ -23,6 +23,8 @@ #ifndef AVCODEC_HEVC_H #define AVCODEC_HEVC_H +#include + #include "libavutil/buffer.h" #include "libavutil/md5.h" @@ -885,7 +887,7 @@ typedef struct HEVCContext { uint16_t seq_output; int enable_parallel_tiles; - int wpp_err; + atomic_int wpp_err; const uint8_t *data; From 6ff3da4f6a8e460d77bb65fed4267bf48f513fcf Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 22 Feb 2017 11:39:21 +0100 Subject: [PATCH 1271/3374] Place attribute_deprecated in the right position for struct declarations libavcodec/vaapi.h:58:1: warning: attribute 'deprecated' is ignored, place it after "struct" to apply attribute to type declaration [-Wignored-attributes] (cherry picked from commit ed6a891c364f8b0850b557d9578b8920cc15a937) Signed-off-by: Mark Thompson --- libavcodec/vaapi.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libavcodec/vaapi.h b/libavcodec/vaapi.h index e68912d93b564..bb28455329362 100644 --- a/libavcodec/vaapi.h +++ b/libavcodec/vaapi.h @@ -53,8 +53,7 @@ * * Deprecated: use AVCodecContext.hw_frames_ctx instead. */ -attribute_deprecated -struct vaapi_context { +struct attribute_deprecated vaapi_context { /** * Window system dependent data * From 81b7deab8296f8446a64e20b9fcaf8eba88b9e29 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sat, 11 Feb 2017 15:13:12 +0000 Subject: [PATCH 1272/3374] vaapi: Implement device-only setup In this case, the user only supplies a device and the frame context is allocated internally by lavc. (cherry picked from commit 5dd9a4b88b287bf8c93520afda7becb1ad0d1894) --- libavcodec/vaapi_decode.c | 129 ++++++++++++++++++++++++++++++++------ libavcodec/vaapi_decode.h | 3 + libavcodec/version.h | 2 +- 3 files changed, 115 insertions(+), 19 deletions(-) diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c index da9e4aeddef86..b63fb94fc110a 100644 --- a/libavcodec/vaapi_decode.c +++ b/libavcodec/vaapi_decode.c @@ -18,6 +18,7 @@ #include "libavutil/avassert.h" #include "libavutil/common.h" +#include "libavutil/pixdesc.h" #include "avcodec.h" #include "internal.h" @@ -283,6 +284,7 @@ static int vaapi_decode_make_config(AVCodecContext *avctx) const AVCodecDescriptor *codec_desc; VAProfile profile, *profile_list = NULL; int profile_count, exact_match, alt_profile; + const AVPixFmtDescriptor *sw_desc, *desc; // Allowing a profile mismatch can be useful because streams may // over-declare their required capabilities - in particular, many @@ -375,7 +377,9 @@ static int vaapi_decode_make_config(AVCodecContext *avctx) goto fail; } - hwconfig = av_hwdevice_hwconfig_alloc(ctx->frames->device_ref); + hwconfig = av_hwdevice_hwconfig_alloc(avctx->hw_device_ctx ? + avctx->hw_device_ctx : + ctx->frames->device_ref); if (!hwconfig) { err = AVERROR(ENOMEM); goto fail; @@ -383,24 +387,77 @@ static int vaapi_decode_make_config(AVCodecContext *avctx) hwconfig->config_id = ctx->va_config; constraints = - av_hwdevice_get_hwframe_constraints(ctx->frames->device_ref, + av_hwdevice_get_hwframe_constraints(avctx->hw_device_ctx ? + avctx->hw_device_ctx : + ctx->frames->device_ref, hwconfig); if (!constraints) { - // Ignore. - } else { - if (avctx->coded_width < constraints->min_width || - avctx->coded_height < constraints->min_height || - avctx->coded_width > constraints->max_width || - avctx->coded_height > constraints->max_height) { - av_log(avctx, AV_LOG_ERROR, "Hardware does not support image " - "size %dx%d (constraints: width %d-%d height %d-%d).\n", - avctx->coded_width, avctx->coded_height, - constraints->min_width, constraints->max_width, - constraints->min_height, constraints->max_height); - err = AVERROR(EINVAL); - goto fail; + err = AVERROR(ENOMEM); + goto fail; + } + + if (avctx->coded_width < constraints->min_width || + avctx->coded_height < constraints->min_height || + avctx->coded_width > constraints->max_width || + avctx->coded_height > constraints->max_height) { + av_log(avctx, AV_LOG_ERROR, "Hardware does not support image " + "size %dx%d (constraints: width %d-%d height %d-%d).\n", + avctx->coded_width, avctx->coded_height, + constraints->min_width, constraints->max_width, + constraints->min_height, constraints->max_height); + err = AVERROR(EINVAL); + goto fail; + } + if (!constraints->valid_sw_formats || + constraints->valid_sw_formats[0] == AV_PIX_FMT_NONE) { + av_log(avctx, AV_LOG_ERROR, "Hardware does not offer any " + "usable surface formats.\n"); + err = AVERROR(EINVAL); + goto fail; + } + + // Find the first format in the list which matches the expected + // bit depth and subsampling. If none are found (this can happen + // when 10-bit streams are decoded to 8-bit surfaces, for example) + // then just take the first format on the list. + ctx->surface_format = constraints->valid_sw_formats[0]; + sw_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt); + for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) { + desc = av_pix_fmt_desc_get(constraints->valid_sw_formats[i]); + if (desc->nb_components != sw_desc->nb_components || + desc->log2_chroma_w != sw_desc->log2_chroma_w || + desc->log2_chroma_h != sw_desc->log2_chroma_h) + continue; + for (j = 0; j < desc->nb_components; j++) { + if (desc->comp[j].depth != sw_desc->comp[j].depth) + break; } + if (j < desc->nb_components) + continue; + ctx->surface_format = constraints->valid_sw_formats[i]; + break; + } + + // Start with at least four surfaces. + ctx->surface_count = 4; + // Add per-codec number of surfaces used for storing reference frames. + switch (avctx->codec_id) { + case AV_CODEC_ID_H264: + case AV_CODEC_ID_HEVC: + ctx->surface_count += 16; + break; + case AV_CODEC_ID_VP9: + ctx->surface_count += 8; + break; + case AV_CODEC_ID_VP8: + ctx->surface_count += 3; + break; + default: + ctx->surface_count += 2; } + // Add an additional surface per thread is frame threading is enabled. + if (avctx->active_thread_type & FF_THREAD_FRAME) + ctx->surface_count += avctx->thread_count; av_hwframe_constraints_free(&constraints); av_freep(&hwconfig); @@ -463,13 +520,24 @@ int ff_vaapi_decode_init(AVCodecContext *avctx) ctx->frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data; ctx->hwfc = ctx->frames->hwctx; - ctx->device = ctx->frames->device_ctx; ctx->hwctx = ctx->device->hwctx; + } else if (avctx->hw_device_ctx) { + ctx->device = (AVHWDeviceContext*)avctx->hw_device_ctx->data; + ctx->hwctx = ctx->device->hwctx; + + if (ctx->device->type != AV_HWDEVICE_TYPE_VAAPI) { + av_log(avctx, AV_LOG_ERROR, "Device supplied for VAAPI " + "decoding must be a VAAPI device (not %d).\n", + ctx->device->type); + err = AVERROR(EINVAL); + goto fail; + } + } else { - av_log(avctx, AV_LOG_ERROR, "A hardware frames context is " - "required for VAAPI decoding.\n"); + av_log(avctx, AV_LOG_ERROR, "A hardware device or frames context " + "is required for VAAPI decoding.\n"); err = AVERROR(EINVAL); goto fail; } @@ -488,6 +556,31 @@ int ff_vaapi_decode_init(AVCodecContext *avctx) if (err) goto fail; + if (!avctx->hw_frames_ctx) { + avctx->hw_frames_ctx = av_hwframe_ctx_alloc(avctx->hw_device_ctx); + if (!avctx->hw_frames_ctx) { + err = AVERROR(ENOMEM); + goto fail; + } + ctx->frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data; + + ctx->frames->format = AV_PIX_FMT_VAAPI; + ctx->frames->width = avctx->coded_width; + ctx->frames->height = avctx->coded_height; + + ctx->frames->sw_format = ctx->surface_format; + ctx->frames->initial_pool_size = ctx->surface_count; + + err = av_hwframe_ctx_init(avctx->hw_frames_ctx); + if (err < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to initialise internal " + "frames context: %d.\n", err); + goto fail; + } + + ctx->hwfc = ctx->frames->hwctx; + } + vas = vaCreateContext(ctx->hwctx->display, ctx->va_config, avctx->coded_width, avctx->coded_height, VA_PROGRESSIVE, diff --git a/libavcodec/vaapi_decode.h b/libavcodec/vaapi_decode.h index 5ac3069ef360b..4fe414c504e05 100644 --- a/libavcodec/vaapi_decode.h +++ b/libavcodec/vaapi_decode.h @@ -69,6 +69,9 @@ typedef struct VAAPIDecodeContext { AVHWFramesContext *frames; AVVAAPIFramesContext *hwfc; + + enum AVPixelFormat surface_format; + int surface_count; } VAAPIDecodeContext; diff --git a/libavcodec/version.h b/libavcodec/version.h index ec8651f086e59..8d9dda76753fa 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 83 -#define LIBAVCODEC_VERSION_MICRO 101 +#define LIBAVCODEC_VERSION_MICRO 102 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From 14c1101518388f0f190c4737ea1b88d8b55b5281 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Tue, 21 Mar 2017 22:31:04 +0000 Subject: [PATCH 1273/3374] vaapi_hevc: Mark as async-safe --- libavcodec/vaapi_hevc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/vaapi_hevc.c b/libavcodec/vaapi_hevc.c index 2b0e8ff326f4c..34d32795b7a09 100644 --- a/libavcodec/vaapi_hevc.c +++ b/libavcodec/vaapi_hevc.c @@ -25,6 +25,7 @@ #include "avcodec.h" #include "hevc.h" +#include "hwaccel.h" #include "vaapi_decode.h" typedef struct VAAPIDecodePictureHEVC { @@ -434,4 +435,5 @@ AVHWAccel ff_hevc_vaapi_hwaccel = { .init = ff_vaapi_decode_init, .uninit = ff_vaapi_decode_uninit, .priv_data_size = sizeof(VAAPIDecodeContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; From 9560766a6164ed362e7f274242a024fe7b71d154 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Tue, 21 Mar 2017 22:31:21 +0000 Subject: [PATCH 1274/3374] vaapi_vp9: Mark as async-safe --- libavcodec/vaapi_vp9.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavcodec/vaapi_vp9.c b/libavcodec/vaapi_vp9.c index a656ffb13c7d2..7374465d49c92 100644 --- a/libavcodec/vaapi_vp9.c +++ b/libavcodec/vaapi_vp9.c @@ -21,6 +21,8 @@ */ #include "libavutil/pixdesc.h" + +#include "hwaccel.h" #include "vaapi_decode.h" #include "vp9.h" @@ -178,4 +180,5 @@ AVHWAccel ff_vp9_vaapi_hwaccel = { .init = ff_vaapi_decode_init, .uninit = ff_vaapi_decode_uninit, .priv_data_size = sizeof(VAAPIDecodeContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; From 30cadfe071ad353b60144d235a347a57ada7998c Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 22 Mar 2017 18:27:53 -0300 Subject: [PATCH 1275/3374] avcodec/lossless_videodsp: use ptrdiff_t for length parameters Signed-off-by: James Almer --- libavcodec/lossless_videodsp.c | 8 ++++---- libavcodec/lossless_videodsp.h | 11 +++++++---- libavcodec/ppc/lossless_videodsp_altivec.c | 2 +- libavcodec/x86/lossless_videodsp_init.c | 18 +++++++++--------- tests/checkasm/llviddsp.c | 2 +- 5 files changed, 22 insertions(+), 19 deletions(-) diff --git a/libavcodec/lossless_videodsp.c b/libavcodec/lossless_videodsp.c index 1de288b24641b..b5b96e612966d 100644 --- a/libavcodec/lossless_videodsp.c +++ b/libavcodec/lossless_videodsp.c @@ -25,7 +25,7 @@ #define pb_7f (~0UL / 255 * 0x7f) #define pb_80 (~0UL / 255 * 0x80) -static void add_bytes_c(uint8_t *dst, uint8_t *src, intptr_t w) +static void add_bytes_c(uint8_t *dst, uint8_t *src, ptrdiff_t w) { long i; @@ -39,7 +39,7 @@ static void add_bytes_c(uint8_t *dst, uint8_t *src, intptr_t w) } static void add_median_pred_c(uint8_t *dst, const uint8_t *src1, - const uint8_t *diff, intptr_t w, + const uint8_t *diff, ptrdiff_t w, int *left, int *left_top) { int i; @@ -58,7 +58,7 @@ static void add_median_pred_c(uint8_t *dst, const uint8_t *src1, *left_top = lt; } -static int add_left_pred_c(uint8_t *dst, const uint8_t *src, intptr_t w, +static int add_left_pred_c(uint8_t *dst, const uint8_t *src, ptrdiff_t w, int acc) { int i; @@ -79,7 +79,7 @@ static int add_left_pred_c(uint8_t *dst, const uint8_t *src, intptr_t w, return acc; } -static int add_left_pred_int16_c(uint16_t *dst, const uint16_t *src, unsigned mask, int w, unsigned acc){ +static int add_left_pred_int16_c(uint16_t *dst, const uint16_t *src, unsigned mask, ptrdiff_t w, unsigned acc){ int i; for(i=0; i +#include + #include "avcodec.h" #include "libavutil/cpu.h" typedef struct LLVidDSPContext { void (*add_bytes)(uint8_t *dst /* align 16 */, uint8_t *src /* align 16 */, - intptr_t w); + ptrdiff_t w); void (*add_median_pred)(uint8_t *dst, const uint8_t *top, - const uint8_t *diff, intptr_t w, + const uint8_t *diff, ptrdiff_t w, int *left, int *left_top); int (*add_left_pred)(uint8_t *dst, const uint8_t *src, - intptr_t w, int left); + ptrdiff_t w, int left); int (*add_left_pred_int16)(uint16_t *dst, const uint16_t *src, - unsigned mask, int w, unsigned left); + unsigned mask, ptrdiff_t w, unsigned left); } LLVidDSPContext; void ff_llviddsp_init(LLVidDSPContext *llviddsp); diff --git a/libavcodec/ppc/lossless_videodsp_altivec.c b/libavcodec/ppc/lossless_videodsp_altivec.c index c388dc33affd1..16dd99f8d7325 100644 --- a/libavcodec/ppc/lossless_videodsp_altivec.c +++ b/libavcodec/ppc/lossless_videodsp_altivec.c @@ -33,7 +33,7 @@ #include "libavcodec/lossless_videodsp.h" #if HAVE_ALTIVEC -static void add_bytes_altivec(uint8_t *dst, uint8_t *src, intptr_t w) +static void add_bytes_altivec(uint8_t *dst, uint8_t *src, ptrdiff_t w) { register int i; register vector unsigned char vdst, vsrc; diff --git a/libavcodec/x86/lossless_videodsp_init.c b/libavcodec/x86/lossless_videodsp_init.c index 8d583447dcadb..21bbd12bd2d91 100644 --- a/libavcodec/x86/lossless_videodsp_init.c +++ b/libavcodec/x86/lossless_videodsp_init.c @@ -23,27 +23,27 @@ #include "../lossless_videodsp.h" #include "libavutil/x86/cpu.h" -void ff_add_bytes_mmx(uint8_t *dst, uint8_t *src, intptr_t w); -void ff_add_bytes_sse2(uint8_t *dst, uint8_t *src, intptr_t w); +void ff_add_bytes_mmx(uint8_t *dst, uint8_t *src, ptrdiff_t w); +void ff_add_bytes_sse2(uint8_t *dst, uint8_t *src, ptrdiff_t w); void ff_add_median_pred_mmxext(uint8_t *dst, const uint8_t *top, - const uint8_t *diff, intptr_t w, + const uint8_t *diff, ptrdiff_t w, int *left, int *left_top); void ff_add_median_pred_sse2(uint8_t *dst, const uint8_t *top, - const uint8_t *diff, intptr_t w, + const uint8_t *diff, ptrdiff_t w, int *left, int *left_top); int ff_add_left_pred_ssse3(uint8_t *dst, const uint8_t *src, - intptr_t w, int left); + ptrdiff_t w, int left); int ff_add_left_pred_unaligned_ssse3(uint8_t *dst, const uint8_t *src, - intptr_t w, int left); + ptrdiff_t w, int left); -int ff_add_left_pred_int16_ssse3(uint16_t *dst, const uint16_t *src, unsigned mask, int w, unsigned acc); -int ff_add_left_pred_int16_sse4(uint16_t *dst, const uint16_t *src, unsigned mask, int w, unsigned acc); +int ff_add_left_pred_int16_ssse3(uint16_t *dst, const uint16_t *src, unsigned mask, ptrdiff_t w, unsigned acc); +int ff_add_left_pred_int16_sse4(uint16_t *dst, const uint16_t *src, unsigned mask, ptrdiff_t w, unsigned acc); #if HAVE_INLINE_ASM && HAVE_7REGS && ARCH_X86_32 static void add_median_pred_cmov(uint8_t *dst, const uint8_t *top, - const uint8_t *diff, intptr_t w, + const uint8_t *diff, ptrdiff_t w, int *left, int *left_top) { x86_reg w2 = -w; diff --git a/tests/checkasm/llviddsp.c b/tests/checkasm/llviddsp.c index e42873bd20783..b1f3b83b43b59 100644 --- a/tests/checkasm/llviddsp.c +++ b/tests/checkasm/llviddsp.c @@ -41,7 +41,7 @@ static void check_add_bytes(LLVidDSPContext c, int width) uint8_t *src1 = av_mallocz(width); uint8_t *dst0 = av_mallocz(width); uint8_t *dst1 = av_mallocz(width); - declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, uint8_t *src, int w); + declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, uint8_t *src, ptrdiff_t w); if (!src0 || !src1 || !dst0 || !dst1) fail(); From 156bd8278f4098426cffaa68efb161907e5c1869 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 4 Mar 2017 23:57:32 +0000 Subject: [PATCH 1276/3374] lavc: Add hwaccel_flags field to AVCodecContext This "reuses" the flags introduced for the av_vdpau_bind_context() API function, and makes them available to all hwaccels. This does not affect the current vdpau API, as av_vdpau_bind_context() should obviously override the AVCodecContext.hwaccel_flags flags for the sake of compatibility. Cherry-picked from Libav commit 16a163b5. Reviewed-by: Mark Thompson --- doc/APIchanges | 4 ++++ libavcodec/avcodec.h | 9 +++++++++ libavcodec/pthread_frame.c | 2 ++ libavcodec/version.h | 4 ++-- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index eccfb708995c5..a2dc60167d974 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,10 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-03-xx - xxxxxxx - lavc 57.85.100 - avcodec.h + Add AVCodecContext.hwaccel_flags field. This will control some hwaccels at + a later point. + 2017-03-21 - xxxxxxx - lavf 57.67.100 / 57.08.0 - avio.h Add AVIO_SEEKABLE_TIME flag. diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 3e3c37278a45f..b3479a72235f8 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3620,6 +3620,15 @@ typedef struct AVCodecContext { * contexts used must be created on the same device. */ AVBufferRef *hw_device_ctx; + + /** + * Bit set of AV_HWACCEL_FLAG_* flags, which affect hardware accelerated + * decoding (if active). + * - encoding: unused + * - decoding: Set by user (either before avcodec_open2(), or in the + * AVCodecContext.get_format callback) + */ + int hwaccel_flags; } AVCodecContext; AVRational av_codec_get_pkt_timebase (const AVCodecContext *avctx); diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index a52160145e593..6768402ed887f 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -275,6 +275,8 @@ FF_ENABLE_DEPRECATION_WARNINGS return AVERROR(ENOMEM); } } + + dst->hwaccel_flags = src->hwaccel_flags; } if (for_user) { diff --git a/libavcodec/version.h b/libavcodec/version.h index 8d9dda76753fa..32746d0f8fd76 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 83 -#define LIBAVCODEC_VERSION_MICRO 102 +#define LIBAVCODEC_VERSION_MINOR 85 +#define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From 7e4ba776a2240d40124d5540ea6b2118fa2fe26a Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 4 Mar 2017 23:57:33 +0000 Subject: [PATCH 1277/3374] lavc: vdpau: Add support for new hw_frames_ctx and hw_device_ctx API This supports retrieving the device from a provided hw_frames_ctx, and automatically creating a hw_frames_ctx if hw_device_ctx is set. The old API is not deprecated yet. The user can still use av_vdpau_bind_context() (with or without setting hw_frames_ctx), or use the API before that by allocating and setting hwaccel_context manually. Cherry-picked from Libav commit 1a7ddba5. (Adds missing APIchanges entry to the Libav version.) Reviewed-by: Mark Thompson --- doc/APIchanges | 5 ++ libavcodec/vdpau.c | 95 +++++++++++++++++++++++++++---------- libavcodec/vdpau_internal.h | 2 + libavcodec/version.h | 2 +- 4 files changed, 78 insertions(+), 26 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index a2dc60167d974..6aaa9adcebd75 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,11 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-03-xx - xxxxxxx - lavc 57.85.101 - avcodec.h + vdpau hardware accelerated decoding now supports the new hwaccel API, which + can create the decoder context and allocate hardware frame automatically. + See AVCodecContext.hw_device_ctx and AVCodecContext.hw_frames_ctx. + 2017-03-xx - xxxxxxx - lavc 57.85.100 - avcodec.h Add AVCodecContext.hwaccel_flags field. This will control some hwaccels at a later point. diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c index bbb9913f8b0f3..a232603c60f25 100644 --- a/libavcodec/vdpau.c +++ b/libavcodec/vdpau.c @@ -138,34 +138,75 @@ int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile, vdctx->width = UINT32_MAX; vdctx->height = UINT32_MAX; - if (!hwctx) { - vdctx->device = VDP_INVALID_HANDLE; - av_log(avctx, AV_LOG_WARNING, "hwaccel_context has not been setup by the user application, cannot initialize\n"); - return 0; - } + if (av_vdpau_get_surface_parameters(avctx, &type, &width, &height)) + return AVERROR(ENOSYS); - if (hwctx->context.decoder != VDP_INVALID_HANDLE) { - vdctx->decoder = hwctx->context.decoder; - vdctx->render = hwctx->context.render; - vdctx->device = VDP_INVALID_HANDLE; - return 0; /* Decoder created by user */ - } - hwctx->reset = 0; + if (hwctx) { + hwctx->reset = 0; - vdctx->device = hwctx->device; - vdctx->get_proc_address = hwctx->get_proc_address; + if (hwctx->context.decoder != VDP_INVALID_HANDLE) { + vdctx->decoder = hwctx->context.decoder; + vdctx->render = hwctx->context.render; + vdctx->device = VDP_INVALID_HANDLE; + return 0; /* Decoder created by user */ + } - if (hwctx->flags & AV_HWACCEL_FLAG_IGNORE_LEVEL) - level = 0; - else if (level < 0) - return AVERROR(ENOTSUP); + vdctx->device = hwctx->device; + vdctx->get_proc_address = hwctx->get_proc_address; + + if (hwctx->flags & AV_HWACCEL_FLAG_IGNORE_LEVEL) + level = 0; + + if (!(hwctx->flags & AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH) && + type != VDP_CHROMA_TYPE_420) + return AVERROR(ENOSYS); + } else { + AVHWFramesContext *frames_ctx = NULL; + AVVDPAUDeviceContext *dev_ctx; + + // We assume the hw_frames_ctx always survives until ff_vdpau_common_uninit + // is called. This holds true as the user is not allowed to touch + // hw_device_ctx, or hw_frames_ctx after get_format (and ff_get_format + // itself also uninits before unreffing hw_frames_ctx). + if (avctx->hw_frames_ctx) { + frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; + } else if (avctx->hw_device_ctx) { + int ret; + + avctx->hw_frames_ctx = av_hwframe_ctx_alloc(avctx->hw_device_ctx); + if (!avctx->hw_frames_ctx) + return AVERROR(ENOMEM); + + frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; + frames_ctx->format = AV_PIX_FMT_VDPAU; + frames_ctx->sw_format = avctx->sw_pix_fmt; + frames_ctx->width = avctx->coded_width; + frames_ctx->height = avctx->coded_height; + + ret = av_hwframe_ctx_init(avctx->hw_frames_ctx); + if (ret < 0) { + av_buffer_unref(&avctx->hw_frames_ctx); + return ret; + } + } - if (av_vdpau_get_surface_parameters(avctx, &type, &width, &height)) - return AVERROR(ENOSYS); + if (!frames_ctx) { + av_log(avctx, AV_LOG_ERROR, "A hardware frames context is " + "required for VDPAU decoding.\n"); + return AVERROR(EINVAL); + } - if (!(hwctx->flags & AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH) && - type != VDP_CHROMA_TYPE_420) - return AVERROR(ENOSYS); + dev_ctx = frames_ctx->device_ctx->hwctx; + + vdctx->device = dev_ctx->device; + vdctx->get_proc_address = dev_ctx->get_proc_address; + + if (avctx->hwaccel_flags & AV_HWACCEL_FLAG_IGNORE_LEVEL) + level = 0; + } + + if (level < 0) + return AVERROR(ENOTSUP); status = vdctx->get_proc_address(vdctx->device, VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES, @@ -263,7 +304,7 @@ static int ff_vdpau_common_reinit(AVCodecContext *avctx) if (vdctx->device == VDP_INVALID_HANDLE) return 0; /* Decoder created by user */ if (avctx->coded_width == vdctx->width && - avctx->coded_height == vdctx->height && !hwctx->reset) + avctx->coded_height == vdctx->height && (!hwctx || !hwctx->reset)) return 0; avctx->hwaccel->uninit(avctx); @@ -295,15 +336,17 @@ int ff_vdpau_common_end_frame(AVCodecContext *avctx, AVFrame *frame, #if FF_API_BUFS_VDPAU FF_DISABLE_DEPRECATION_WARNINGS + if (hwctx) { av_assert0(sizeof(hwctx->info) <= sizeof(pic_ctx->info)); memcpy(&hwctx->info, &pic_ctx->info, sizeof(hwctx->info)); hwctx->bitstream_buffers = pic_ctx->bitstream_buffers; hwctx->bitstream_buffers_used = pic_ctx->bitstream_buffers_used; hwctx->bitstream_buffers_allocated = pic_ctx->bitstream_buffers_allocated; + } FF_ENABLE_DEPRECATION_WARNINGS #endif - if (!hwctx->render && hwctx->render2) { + if (hwctx && !hwctx->render && hwctx->render2) { status = hwctx->render2(avctx, frame, (void *)&pic_ctx->info, pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers); } else @@ -315,9 +358,11 @@ FF_ENABLE_DEPRECATION_WARNINGS #if FF_API_BUFS_VDPAU FF_DISABLE_DEPRECATION_WARNINGS + if (hwctx) { hwctx->bitstream_buffers = NULL; hwctx->bitstream_buffers_used = 0; hwctx->bitstream_buffers_allocated = 0; + } FF_ENABLE_DEPRECATION_WARNINGS #endif diff --git a/libavcodec/vdpau_internal.h b/libavcodec/vdpau_internal.h index 77800af33fc1e..30d01af65d801 100644 --- a/libavcodec/vdpau_internal.h +++ b/libavcodec/vdpau_internal.h @@ -28,6 +28,8 @@ #include #include "libavutil/frame.h" +#include "libavutil/hwcontext.h" +#include "libavutil/hwcontext_vdpau.h" #include "avcodec.h" #include "vdpau.h" diff --git a/libavcodec/version.h b/libavcodec/version.h index 32746d0f8fd76..a545464bbc5cd 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 85 -#define LIBAVCODEC_VERSION_MICRO 100 +#define LIBAVCODEC_VERSION_MICRO 101 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From aff80aa4ecadd0a2aa8da839f289b815db2ef078 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Fri, 17 Feb 2017 12:00:40 +0100 Subject: [PATCH 1278/3374] hls: consistent use of user_agent This came up while debugging a problem with mpv: https://github.com/mpv-player/mpv/issues/4155 Signed-off-by: wm4 --- libavformat/hls.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index c65a9f9e87b03..bac53a43500fe 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -670,7 +670,7 @@ static int parse_playlist(HLSContext *c, const char *url, av_dict_set(&opts, "seekable", "0", 0); // broker prior HTTP options that should be consistent across requests - av_dict_set(&opts, "user-agent", c->user_agent, 0); + 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); av_dict_set(&opts, "http_proxy", c->http_proxy, 0); @@ -1084,7 +1084,7 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg) int is_http = 0; // broker prior HTTP options that should be consistent across requests - av_dict_set(&opts, "user-agent", c->user_agent, 0); + 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); av_dict_set(&opts, "http_proxy", c->http_proxy, 0); @@ -1623,7 +1623,7 @@ static int hls_read_header(AVFormatContext *s) if (u) { // get the previous user agent & set back to null if string size is zero - update_options(&c->user_agent, "user-agent", u); + update_options(&c->user_agent, "user_agent", u); // get the previous cookies & set back to null if string size is zero update_options(&c->cookies, "cookies", u); From 3182e19c1c29eef60208a67ad8ecad1d9a2d0694 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 21 Mar 2017 01:55:01 +0100 Subject: [PATCH 1279/3374] avcodec/tiff: Check geotag count for being non zero Fixes memleak Fixes: 874/clusterfuzz-testcase-5252796175613952 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/tiff.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index 5a6573fb79f88..3aaf63338d600 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -1071,7 +1071,8 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) s->geotag_count = count / 4 - 1; av_log(s->avctx, AV_LOG_WARNING, "GeoTIFF key directory buffer shorter than specified\n"); } - if (bytestream2_get_bytes_left(&s->gb) < s->geotag_count * sizeof(int16_t) * 4) { + if ( bytestream2_get_bytes_left(&s->gb) < s->geotag_count * sizeof(int16_t) * 4 + || s->geotag_count == 0) { s->geotag_count = 0; return -1; } From 0f34c0789f855f04dce518ffc93a01bb943ba1aa Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 21 Mar 2017 02:20:35 +0100 Subject: [PATCH 1280/3374] avcodec/pictordec: runtime error: left shift of 15 by 28 places cannot be represented in type 'int' Fixes: 898/clusterfuzz-testcase-6149765467209728 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/pictordec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/pictordec.c b/libavcodec/pictordec.c index 8b075bfd0cdab..b29a484534150 100644 --- a/libavcodec/pictordec.c +++ b/libavcodec/pictordec.c @@ -62,7 +62,7 @@ static void picmemset(PicContext *s, AVFrame *frame, unsigned value, int run, { uint8_t *d; int shift = *plane * bits_per_plane; - unsigned mask = ((1 << bits_per_plane) - 1) << shift; + unsigned mask = ((1U << bits_per_plane) - 1) << shift; value <<= shift; while (run > 0) { From 4f727fbc7330e726d003e2961fa676ddaf86f994 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 22 Mar 2017 00:17:05 +0100 Subject: [PATCH 1281/3374] avcodec/h264_ps: Fix runtime error: signed integer overflow: 2147483647 + 26 cannot be represented in type 'int' Fixes: 902/clusterfuzz-testcase-4561155144024064 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Reviewed-by: "Ronald S. Bultje" Signed-off-by: Michael Niedermayer --- libavcodec/h264_ps.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c index 65d164d81c673..b78ad251f5c1e 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -800,8 +800,8 @@ int ff_h264_decode_picture_parameter_set(GetBitContext *gb, AVCodecContext *avct pps->weighted_pred = get_bits1(gb); pps->weighted_bipred_idc = get_bits(gb, 2); - pps->init_qp = get_se_golomb(gb) + 26 + qp_bd_offset; - pps->init_qs = get_se_golomb(gb) + 26 + qp_bd_offset; + pps->init_qp = get_se_golomb(gb) + 26U + qp_bd_offset; + pps->init_qs = get_se_golomb(gb) + 26U + qp_bd_offset; pps->chroma_qp_index_offset[0] = get_se_golomb(gb); if (pps->chroma_qp_index_offset[0] < -12 || pps->chroma_qp_index_offset[0] > 12) { ret = AVERROR_INVALIDDATA; From 005da88c1ee231eddd9924ad8173aeeab6366165 Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 22 Mar 2017 15:27:30 -0300 Subject: [PATCH 1282/3374] avcodec/mediacodec: convert to stdatomic Reviewed-by: wm4 Signed-off-by: James Almer --- libavcodec/mediacodec.c | 5 ++--- libavcodec/mediacodecdec.c | 1 - libavcodec/mediacodecdec_common.c | 13 ++++++------- libavcodec/mediacodecdec_common.h | 5 +++-- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/libavcodec/mediacodec.c b/libavcodec/mediacodec.c index 4ad5921bc205a..610bb49a733ba 100644 --- a/libavcodec/mediacodec.c +++ b/libavcodec/mediacodec.c @@ -31,7 +31,6 @@ #include #include "libavcodec/avcodec.h" -#include "libavutil/atomic.h" #include "libavutil/mem.h" #include "ffjni.h" @@ -90,9 +89,9 @@ void av_mediacodec_default_free(AVCodecContext *avctx) int av_mediacodec_release_buffer(AVMediaCodecBuffer *buffer, int render) { MediaCodecDecContext *ctx = buffer->ctx; - int released = avpriv_atomic_int_add_and_fetch(&buffer->released, 1); + int released = atomic_fetch_add(&buffer->released, 1); - if (released == 1) { + if (!released) { return ff_AMediaCodec_releaseOutputBuffer(ctx->codec, buffer->index, render); } diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c index 2e645caafd92f..3ada3fa6985dc 100644 --- a/libavcodec/mediacodecdec.c +++ b/libavcodec/mediacodecdec.c @@ -29,7 +29,6 @@ #include "libavutil/opt.h" #include "libavutil/intreadwrite.h" #include "libavutil/pixfmt.h" -#include "libavutil/atomic.h" #include "avcodec.h" #include "h264_parse.h" diff --git a/libavcodec/mediacodecdec_common.c b/libavcodec/mediacodecdec_common.c index dfc7f5514a9a7..2ec25c581d34f 100644 --- a/libavcodec/mediacodecdec_common.c +++ b/libavcodec/mediacodecdec_common.c @@ -23,7 +23,6 @@ #include #include -#include "libavutil/atomic.h" #include "libavutil/common.h" #include "libavutil/mem.h" #include "libavutil/log.h" @@ -143,7 +142,7 @@ static enum AVPixelFormat mcdec_map_color_format(AVCodecContext *avctx, static void ff_mediacodec_dec_ref(MediaCodecDecContext *s) { - avpriv_atomic_int_add_and_fetch(&s->refcount, 1); + atomic_fetch_add(&s->refcount, 1); } static void ff_mediacodec_dec_unref(MediaCodecDecContext *s) @@ -151,7 +150,7 @@ static void ff_mediacodec_dec_unref(MediaCodecDecContext *s) if (!s) return; - if (!avpriv_atomic_int_add_and_fetch(&s->refcount, -1)) { + if (atomic_fetch_sub(&s->refcount, 1) == 1) { if (s->codec) { ff_AMediaCodec_delete(s->codec); s->codec = NULL; @@ -176,7 +175,7 @@ static void mediacodec_buffer_release(void *opaque, uint8_t *data) { AVMediaCodecBuffer *buffer = opaque; MediaCodecDecContext *ctx = buffer->ctx; - int released = avpriv_atomic_int_get(&buffer->released); + int released = atomic_load(&buffer->released); if (!released) { ff_AMediaCodec_releaseOutputBuffer(ctx->codec, buffer->index, 0); @@ -221,7 +220,7 @@ FF_ENABLE_DEPRECATION_WARNINGS goto fail; } - buffer->released = 0; + atomic_init(&buffer->released, 0); frame->buf[0] = av_buffer_create(NULL, 0, @@ -465,7 +464,7 @@ int ff_mediacodec_dec_init(AVCodecContext *avctx, MediaCodecDecContext *s, AV_PIX_FMT_NONE, }; - s->refcount = 1; + atomic_init(&s->refcount, 1); pix_fmt = ff_get_format(avctx, pix_fmts); if (pix_fmt == AV_PIX_FMT_MEDIACODEC) { @@ -725,7 +724,7 @@ int ff_mediacodec_dec_decode(AVCodecContext *avctx, MediaCodecDecContext *s, int ff_mediacodec_dec_flush(AVCodecContext *avctx, MediaCodecDecContext *s) { - if (!s->surface || avpriv_atomic_int_get(&s->refcount) == 1) { + if (!s->surface || atomic_load(&s->refcount) == 1) { int ret; /* No frames (holding a reference to the codec) are retained by the diff --git a/libavcodec/mediacodecdec_common.h b/libavcodec/mediacodecdec_common.h index c00c2e89f3b92..10f38277b54db 100644 --- a/libavcodec/mediacodecdec_common.h +++ b/libavcodec/mediacodecdec_common.h @@ -24,6 +24,7 @@ #define AVCODEC_MEDIACODECDEC_COMMON_H #include +#include #include #include "libavutil/frame.h" @@ -34,7 +35,7 @@ typedef struct MediaCodecDecContext { - volatile int refcount; + atomic_int refcount; char *codec_name; @@ -88,7 +89,7 @@ typedef struct MediaCodecBuffer { MediaCodecDecContext *ctx; ssize_t index; int64_t pts; - volatile int released; + atomic_int released; } MediaCodecBuffer; From 05510ec0677620ab2251f3985f288ad69cdb193b Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 22 Mar 2017 19:33:46 -0300 Subject: [PATCH 1283/3374] avcodec/videotoolboxenc: remove unused atomic header Signed-off-by: James Almer --- libavcodec/videotoolboxenc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c index 4b8718c9aaf20..f1c1670dd1877 100644 --- a/libavcodec/videotoolboxenc.c +++ b/libavcodec/videotoolboxenc.c @@ -26,7 +26,6 @@ #include "avcodec.h" #include "libavutil/opt.h" #include "libavutil/avassert.h" -#include "libavutil/atomic.h" #include "libavutil/avstring.h" #include "libavcodec/avcodec.h" #include "libavutil/pixdesc.h" From 7fb2a7afa174fcd31c7707d4c93c0afc33f060b7 Mon Sep 17 00:00:00 2001 From: Timo Rothenpieler Date: Thu, 23 Mar 2017 17:01:40 +0100 Subject: [PATCH 1284/3374] avcodec/nvenc: Deprecate usage of global_quality, introducing qp --- libavcodec/nvenc.c | 16 +++++++++++----- libavcodec/nvenc.h | 1 + libavcodec/nvenc_h264.c | 2 ++ libavcodec/nvenc_hevc.c | 2 ++ libavcodec/version.h | 2 +- 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 0abada0ff02b3..49f32228bcc07 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -522,10 +522,10 @@ static av_cold void set_constqp(AVCodecContext *avctx) rc->constQP.qpIntra = rc->constQP.qpInterP; rc->constQP.qpInterB = rc->constQP.qpInterP; } - } else if (avctx->global_quality > 0) { - rc->constQP.qpInterP = avctx->global_quality; - rc->constQP.qpInterB = avctx->global_quality; - rc->constQP.qpIntra = avctx->global_quality; + } else if (ctx->cqp >= 0) { + rc->constQP.qpInterP = ctx->cqp; + rc->constQP.qpInterB = ctx->cqp; + rc->constQP.qpIntra = ctx->cqp; } avctx->qmin = -1; @@ -664,6 +664,12 @@ static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx) { NvencContext *ctx = avctx->priv_data; + if (avctx->global_quality > 0) + av_log(avctx, AV_LOG_WARNING, "Using global_quality with nvenc is deprecated. Use qp instead.\n"); + + if (ctx->cqp < 0 && avctx->global_quality > 0) + ctx->cqp = avctx->global_quality; + if (avctx->bit_rate > 0) { ctx->encode_config.rcParams.averageBitRate = avctx->bit_rate; } else if (ctx->encode_config.rcParams.averageBitRate > 0) { @@ -688,7 +694,7 @@ static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx) } else { ctx->rc = NV_ENC_PARAMS_RC_CBR; } - } else if (avctx->global_quality > 0) { + } else if (ctx->cqp >= 0) { ctx->rc = NV_ENC_PARAMS_RC_CONSTQP; } else if (ctx->twopass) { ctx->rc = NV_ENC_PARAMS_RC_2_PASS_VBR; diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h index cfca2efcc5647..7dec5cc68517c 100644 --- a/libavcodec/nvenc.h +++ b/libavcodec/nvenc.h @@ -158,6 +158,7 @@ typedef struct NvencContext int init_qp_p; int init_qp_b; int init_qp_i; + int cqp; } NvencContext; int ff_nvenc_encode_init(AVCodecContext *avctx); diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c index b7d4004fd36c9..2c55b607893bf 100644 --- a/libavcodec/nvenc_h264.c +++ b/libavcodec/nvenc_h264.c @@ -112,6 +112,8 @@ static const AVOption options[] = { { "init_qpP", "Initial QP value for P frame", OFFSET(init_qp_p), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE }, { "init_qpB", "Initial QP value for B frame", OFFSET(init_qp_b), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE }, { "init_qpI", "Initial QP value for I frame", OFFSET(init_qp_i), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE }, + { "qp", "Constant quantization parameter rate control method", + OFFSET(cqp), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE }, { NULL } }; diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c index 2804d7df5aef5..c32ba4220bf77 100644 --- a/libavcodec/nvenc_hevc.c +++ b/libavcodec/nvenc_hevc.c @@ -109,6 +109,8 @@ static const AVOption options[] = { { "init_qpP", "Initial QP value for P frame", OFFSET(init_qp_p), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE }, { "init_qpB", "Initial QP value for B frame", OFFSET(init_qp_b), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE }, { "init_qpI", "Initial QP value for I frame", OFFSET(init_qp_i), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE }, + { "qp", "Constant quantization parameter rate control method", + OFFSET(cqp), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE }, { NULL } }; diff --git a/libavcodec/version.h b/libavcodec/version.h index a545464bbc5cd..5ca008fcb5d26 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 85 -#define LIBAVCODEC_VERSION_MICRO 101 +#define LIBAVCODEC_VERSION_MICRO 102 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From d84c2298e28cfe16161060f3b5eac02bca167a0e Mon Sep 17 00:00:00 2001 From: Timo Rothenpieler Date: Thu, 23 Mar 2017 17:10:25 +0100 Subject: [PATCH 1285/3374] avcodec/nvenc: apply quantization factors to cqp --- libavcodec/nvenc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 49f32228bcc07..cf054550c1312 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -523,9 +523,11 @@ static av_cold void set_constqp(AVCodecContext *avctx) rc->constQP.qpInterB = rc->constQP.qpInterP; } } else if (ctx->cqp >= 0) { - rc->constQP.qpInterP = ctx->cqp; - rc->constQP.qpInterB = ctx->cqp; - rc->constQP.qpIntra = ctx->cqp; + rc->constQP.qpInterP = rc->constQP.qpInterB = rc->constQP.qpIntra = ctx->cqp; + if (avctx->b_quant_factor != 0.0) + rc->constQP.qpInterB = av_clip(ctx->cqp * fabs(avctx->b_quant_factor) + avctx->b_quant_offset + 0.5, 0, 51); + if (avctx->i_quant_factor != 0.0) + rc->constQP.qpIntra = av_clip(ctx->cqp * fabs(avctx->i_quant_factor) + avctx->i_quant_offset + 0.5, 0, 51); } avctx->qmin = -1; From a1a80a6c9ce5309632a8b5c0241fa5ffcd09b5fc Mon Sep 17 00:00:00 2001 From: James Almer Date: Thu, 23 Mar 2017 14:26:44 -0300 Subject: [PATCH 1286/3374] avcodec/bytestream: check for AV_HAVE_BIGENDIAN instead of HAVE_BIGENDIAN No need to include config.h for HAVE_BIGENDIAN when libavutil/avconfig.h is already included. --- libavcodec/bytestream.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/bytestream.h b/libavcodec/bytestream.h index 7c05ea6cf541d..7be7fc22fc8e3 100644 --- a/libavcodec/bytestream.h +++ b/libavcodec/bytestream.h @@ -94,7 +94,7 @@ DEF(unsigned int, be24, 3, AV_RB24, AV_WB24) DEF(unsigned int, be16, 2, AV_RB16, AV_WB16) DEF(unsigned int, byte, 1, AV_RB8 , AV_WB8) -#if HAVE_BIGENDIAN +#if AV_HAVE_BIGENDIAN # define bytestream2_get_ne16 bytestream2_get_be16 # define bytestream2_get_ne24 bytestream2_get_be24 # define bytestream2_get_ne32 bytestream2_get_be32 From 5c6efaffd09de059aa5c7fb9d62bc2e53ba96baf Mon Sep 17 00:00:00 2001 From: James Almer Date: Thu, 23 Mar 2017 15:07:28 -0300 Subject: [PATCH 1287/3374] avcodec/hevc: add missing hevc.h header It was lost as part of a merge in 6397815be0bee10948387fcb90ead36ec2834ef7. --- libavcodec/hevc.h | 65 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 libavcodec/hevc.h diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h new file mode 100644 index 0000000000000..f71cd081ef484 --- /dev/null +++ b/libavcodec/hevc.h @@ -0,0 +1,65 @@ +/* + * HEVC shared code + * + * 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 + */ + +#ifndef AVCODEC_HEVC_H +#define AVCODEC_HEVC_H + +/** + * Table 7-3: NAL unit type codes + */ +enum HEVCNALUnitType { + HEVC_NAL_TRAIL_N = 0, + HEVC_NAL_TRAIL_R = 1, + HEVC_NAL_TSA_N = 2, + HEVC_NAL_TSA_R = 3, + HEVC_NAL_STSA_N = 4, + HEVC_NAL_STSA_R = 5, + HEVC_NAL_RADL_N = 6, + HEVC_NAL_RADL_R = 7, + HEVC_NAL_RASL_N = 8, + HEVC_NAL_RASL_R = 9, + HEVC_NAL_BLA_W_LP = 16, + HEVC_NAL_BLA_W_RADL = 17, + HEVC_NAL_BLA_N_LP = 18, + HEVC_NAL_IDR_W_RADL = 19, + HEVC_NAL_IDR_N_LP = 20, + HEVC_NAL_CRA_NUT = 21, + HEVC_NAL_VPS = 32, + HEVC_NAL_SPS = 33, + HEVC_NAL_PPS = 34, + HEVC_NAL_AUD = 35, + HEVC_NAL_EOS_NUT = 36, + HEVC_NAL_EOB_NUT = 37, + HEVC_NAL_FD_NUT = 38, + HEVC_NAL_SEI_PREFIX = 39, + HEVC_NAL_SEI_SUFFIX = 40, +}; + +/** + * 7.4.2.1 + */ +#define HEVC_MAX_SUB_LAYERS 7 +#define HEVC_MAX_VPS_COUNT 16 +#define HEVC_MAX_SPS_COUNT 32 +#define HEVC_MAX_PPS_COUNT 256 +#define HEVC_MAX_SHORT_TERM_RPS_COUNT 64 +#define HEVC_MAX_CU_SIZE 128 + +#endif /* AVCODEC_HEVC_H */ From 40fa9d416a2597b1f8a1b9096bfaf05ad367999c Mon Sep 17 00:00:00 2001 From: James Almer Date: Thu, 23 Mar 2017 19:34:00 -0300 Subject: [PATCH 1288/3374] Revert "Merge commit '8e2ea691351c5079cdab245ff7bfa5c0f3e3bfe4'" This reverts commit 1c193ac1f9cfe703d6a1c36795f309ba5d14bf6e, reversing changes made to 7ebc9f8df4035ecaa84ad4429480986e3e7597ae. Several FATE tests started failing after this merge, so it's reverted until it can be properly fixed. --- libavformat/internal.h | 9 --- libavformat/utils.c | 123 +++++------------------------------------ 2 files changed, 13 insertions(+), 119 deletions(-) diff --git a/libavformat/internal.h b/libavformat/internal.h index c856945ce9a0c..63a1724cfaa4f 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -178,15 +178,6 @@ struct AVStreamInternal { enum AVCodecID orig_codec_id; - /* the context for extracting extradata in find_stream_info() - * inited=1/bsf=NULL signals that extracting is not possible (codec not - * supported) */ - struct { - AVBSFContext *bsf; - AVPacket *pkt; - int inited; - } extract_extradata; - /** * Whether the internal avctx needs to be updated from codecpar (after a late change to codecpar) */ diff --git a/libavformat/utils.c b/libavformat/utils.c index e851251d66836..a059046a2c604 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -3370,104 +3370,6 @@ void ff_rfps_calculate(AVFormatContext *ic) } } -static int extract_extradata_init(AVStream *st) -{ - AVStreamInternal *i = st->internal; - const AVBitStreamFilter *f; - int ret; - - f = av_bsf_get_by_name("extract_extradata"); - if (!f) - goto finish; - - i->extract_extradata.pkt = av_packet_alloc(); - if (!i->extract_extradata.pkt) - return AVERROR(ENOMEM); - - ret = av_bsf_alloc(f, &i->extract_extradata.bsf); - if (ret < 0) - goto fail; - - ret = avcodec_parameters_copy(i->extract_extradata.bsf->par_in, - st->codecpar); - if (ret < 0) - goto fail; - - i->extract_extradata.bsf->time_base_in = st->time_base; - - /* if init fails here, we assume extracting extradata is just not - * supported for this codec, so we return success */ - ret = av_bsf_init(i->extract_extradata.bsf); - if (ret < 0) { - av_bsf_free(&i->extract_extradata.bsf); - ret = 0; - } - -finish: - i->extract_extradata.inited = 1; - - return 0; -fail: - av_bsf_free(&i->extract_extradata.bsf); - av_packet_free(&i->extract_extradata.pkt); - return ret; -} - -static int extract_extradata(AVStream *st, AVPacket *pkt) -{ - AVStreamInternal *i = st->internal; - AVPacket *pkt_ref; - int ret; - - if (!i->extract_extradata.inited) { - ret = extract_extradata_init(st); - if (ret < 0) - return ret; - } - - if (i->extract_extradata.inited && !i->extract_extradata.bsf) - return 0; - - pkt_ref = i->extract_extradata.pkt; - ret = av_packet_ref(pkt_ref, pkt); - if (ret < 0) - return ret; - - ret = av_bsf_send_packet(i->extract_extradata.bsf, pkt_ref); - if (ret < 0) { - av_packet_unref(pkt_ref); - return ret; - } - - while (ret >= 0 && !i->avctx->extradata) { - int extradata_size; - uint8_t *extradata; - - ret = av_bsf_receive_packet(i->extract_extradata.bsf, pkt_ref); - if (ret < 0) { - if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) - return ret; - continue; - } - - extradata = av_packet_get_side_data(pkt_ref, AV_PKT_DATA_NEW_EXTRADATA, - &extradata_size); - - if (extradata) { - i->avctx->extradata = av_mallocz(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); - if (!i->avctx->extradata) { - av_packet_unref(pkt_ref); - return AVERROR(ENOMEM); - } - memcpy(i->avctx->extradata, extradata, extradata_size); - i->avctx->extradata_size = extradata_size; - } - av_packet_unref(pkt_ref); - } - - return 0; -} - int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) { int i, count = 0, ret = 0, j; @@ -3627,10 +3529,8 @@ FF_ENABLE_DEPRECATION_WARNINGS if (count < fps_analyze_framecount) break; } - if (!st->codecpar->extradata && - !st->internal->avctx->extradata && - (!st->internal->extract_extradata.inited || - st->internal->extract_extradata.bsf)) + if (st->parser && st->parser->parser->split && + !st->internal->avctx->extradata) break; if (st->first_dts == AV_NOPTS_VALUE && !(ic->iformat->flags & AVFMT_NOTIMESTAMPS) && @@ -3780,10 +3680,17 @@ FF_ENABLE_DEPRECATION_WARNINGS if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) ff_rfps_add_frame(ic, st, pkt->dts); #endif - if (!st->internal->avctx->extradata) { - ret = extract_extradata(st, pkt); - if (ret < 0) - goto find_stream_info_err; + if (st->parser && st->parser->parser->split && !avctx->extradata) { + int i = st->parser->parser->split(avctx, pkt->data, pkt->size); + if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) { + avctx->extradata_size = i; + avctx->extradata = av_mallocz(avctx->extradata_size + + AV_INPUT_BUFFER_PADDING_SIZE); + if (!avctx->extradata) + return AVERROR(ENOMEM); + memcpy(avctx->extradata, pkt->data, + avctx->extradata_size); + } } /* If still no information, we try to open the codec and to @@ -4043,8 +3950,6 @@ FF_ENABLE_DEPRECATION_WARNINGS if (st->info) av_freep(&st->info->duration_error); av_freep(&ic->streams[i]->info); - av_bsf_free(&ic->streams[i]->internal->extract_extradata.bsf); - av_packet_free(&ic->streams[i]->internal->extract_extradata.pkt); } if (ic->pb) av_log(ic, AV_LOG_DEBUG, "After avformat_find_stream_info() pos: %"PRId64" bytes read:%"PRId64" seeks:%d frames:%d\n", @@ -4232,8 +4137,6 @@ static void free_stream(AVStream **pst) av_bsf_free(&st->internal->bsfcs[i]); av_freep(&st->internal->bsfcs); } - av_bsf_free(&st->internal->extract_extradata.bsf); - av_packet_free(&st->internal->extract_extradata.pkt); } av_freep(&st->internal); From 0f4abbd4ee1c5b34068cb48ceab3515641d6e0fb Mon Sep 17 00:00:00 2001 From: James Almer Date: Thu, 23 Mar 2017 19:49:09 -0300 Subject: [PATCH 1289/3374] doc/libav-merge: add a line about the extract_extradata commits --- doc/libav-merge.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/libav-merge.txt b/doc/libav-merge.txt index 4cb3e6e9ba284..d57b79a236933 100644 --- a/doc/libav-merge.txt +++ b/doc/libav-merge.txt @@ -96,6 +96,7 @@ Stuff that didn't reach the codebase: - e7078e842 hevcdsp: add x86 SIMD for MC - VAAPI VP8 decode hwaccel (currently under review: http://ffmpeg.org/pipermail/ffmpeg-devel/2017-February/thread.html#207348) - Removal of the custom atomic API (5cc0057f49, see http://ffmpeg.org/pipermail/ffmpeg-devel/2017-March/209003.html) +- Use the new bitstream filter for extracting extradata (see 8e2ea69135 and 096a8effa3) Collateral damage that needs work locally: ------------------------------------------ From bc7308aae82053ad371bed1e1dd3298f0c07ec35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Thu, 23 Mar 2017 22:51:15 +0100 Subject: [PATCH 1290/3374] sws: make is{RGB,BGR}inInt functions --- libswscale/swscale_internal.h | 82 ++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index 1e1d5fa300709..84d5bee5ff624 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -698,45 +698,49 @@ static av_always_inline int isGray(enum AVPixelFormat pix_fmt) pix_fmt != AV_PIX_FMT_MONOWHITE; } -#define isRGBinInt(x) \ - ((x) == AV_PIX_FMT_RGB48BE || \ - (x) == AV_PIX_FMT_RGB48LE || \ - (x) == AV_PIX_FMT_RGB32 || \ - (x) == AV_PIX_FMT_RGB32_1 || \ - (x) == AV_PIX_FMT_RGB24 || \ - (x) == AV_PIX_FMT_RGB565BE || \ - (x) == AV_PIX_FMT_RGB565LE || \ - (x) == AV_PIX_FMT_RGB555BE || \ - (x) == AV_PIX_FMT_RGB555LE || \ - (x) == AV_PIX_FMT_RGB444BE || \ - (x) == AV_PIX_FMT_RGB444LE || \ - (x) == AV_PIX_FMT_RGB8 || \ - (x) == AV_PIX_FMT_RGB4 || \ - (x) == AV_PIX_FMT_RGB4_BYTE || \ - (x) == AV_PIX_FMT_RGBA64BE || \ - (x) == AV_PIX_FMT_RGBA64LE || \ - (x) == AV_PIX_FMT_MONOBLACK || \ - (x) == AV_PIX_FMT_MONOWHITE) - -#define isBGRinInt(x) \ - ((x) == AV_PIX_FMT_BGR48BE || \ - (x) == AV_PIX_FMT_BGR48LE || \ - (x) == AV_PIX_FMT_BGR32 || \ - (x) == AV_PIX_FMT_BGR32_1 || \ - (x) == AV_PIX_FMT_BGR24 || \ - (x) == AV_PIX_FMT_BGR565BE || \ - (x) == AV_PIX_FMT_BGR565LE || \ - (x) == AV_PIX_FMT_BGR555BE || \ - (x) == AV_PIX_FMT_BGR555LE || \ - (x) == AV_PIX_FMT_BGR444BE || \ - (x) == AV_PIX_FMT_BGR444LE || \ - (x) == AV_PIX_FMT_BGR8 || \ - (x) == AV_PIX_FMT_BGR4 || \ - (x) == AV_PIX_FMT_BGR4_BYTE || \ - (x) == AV_PIX_FMT_BGRA64BE || \ - (x) == AV_PIX_FMT_BGRA64LE || \ - (x) == AV_PIX_FMT_MONOBLACK || \ - (x) == AV_PIX_FMT_MONOWHITE) +static av_always_inline int isRGBinInt(enum AVPixelFormat pix_fmt) +{ + return pix_fmt == AV_PIX_FMT_RGB48BE || + pix_fmt == AV_PIX_FMT_RGB48LE || + pix_fmt == AV_PIX_FMT_RGB32 || + pix_fmt == AV_PIX_FMT_RGB32_1 || + pix_fmt == AV_PIX_FMT_RGB24 || + pix_fmt == AV_PIX_FMT_RGB565BE || + pix_fmt == AV_PIX_FMT_RGB565LE || + pix_fmt == AV_PIX_FMT_RGB555BE || + pix_fmt == AV_PIX_FMT_RGB555LE || + pix_fmt == AV_PIX_FMT_RGB444BE || + pix_fmt == AV_PIX_FMT_RGB444LE || + pix_fmt == AV_PIX_FMT_RGB8 || + pix_fmt == AV_PIX_FMT_RGB4 || + pix_fmt == AV_PIX_FMT_RGB4_BYTE || + pix_fmt == AV_PIX_FMT_RGBA64BE || + pix_fmt == AV_PIX_FMT_RGBA64LE || + pix_fmt == AV_PIX_FMT_MONOBLACK || + pix_fmt == AV_PIX_FMT_MONOWHITE; +} + +static av_always_inline int isBGRinInt(enum AVPixelFormat pix_fmt) +{ + return pix_fmt == AV_PIX_FMT_BGR48BE || + pix_fmt == AV_PIX_FMT_BGR48LE || + pix_fmt == AV_PIX_FMT_BGR32 || + pix_fmt == AV_PIX_FMT_BGR32_1 || + pix_fmt == AV_PIX_FMT_BGR24 || + pix_fmt == AV_PIX_FMT_BGR565BE || + pix_fmt == AV_PIX_FMT_BGR565LE || + pix_fmt == AV_PIX_FMT_BGR555BE || + pix_fmt == AV_PIX_FMT_BGR555LE || + pix_fmt == AV_PIX_FMT_BGR444BE || + pix_fmt == AV_PIX_FMT_BGR444LE || + pix_fmt == AV_PIX_FMT_BGR8 || + pix_fmt == AV_PIX_FMT_BGR4 || + pix_fmt == AV_PIX_FMT_BGR4_BYTE || + pix_fmt == AV_PIX_FMT_BGRA64BE || + pix_fmt == AV_PIX_FMT_BGRA64LE || + pix_fmt == AV_PIX_FMT_MONOBLACK || + pix_fmt == AV_PIX_FMT_MONOWHITE; +} static av_always_inline int isBayer(enum AVPixelFormat pix_fmt) { From 99dd6fe62cb43ae26c854f61c58b8b6fc4f236e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Thu, 23 Mar 2017 22:46:28 +0100 Subject: [PATCH 1291/3374] sws/tests/pixdesc_query: remove func wrappers --- libswscale/tests/pixdesc_query.c | 59 +++++++++----------------------- 1 file changed, 17 insertions(+), 42 deletions(-) diff --git a/libswscale/tests/pixdesc_query.c b/libswscale/tests/pixdesc_query.c index 9591b04da69c5..a4aa8ac487ef5 100644 --- a/libswscale/tests/pixdesc_query.c +++ b/libswscale/tests/pixdesc_query.c @@ -20,52 +20,27 @@ #include "libswscale/swscale_internal.h" -/* TODO: drop this wrapper when all the is*() becomes functions */ -#define DECLARE_WRAPPER(macro) \ -static int macro##_func(enum AVPixelFormat pix_fmt) \ -{ \ - return macro(pix_fmt); \ -} - -DECLARE_WRAPPER(is16BPS) -DECLARE_WRAPPER(isNBPS) -DECLARE_WRAPPER(isBE) -DECLARE_WRAPPER(isYUV) -DECLARE_WRAPPER(isPlanarYUV) -DECLARE_WRAPPER(isRGB) -DECLARE_WRAPPER(isGray) -DECLARE_WRAPPER(isRGBinInt) -DECLARE_WRAPPER(isBGRinInt) -DECLARE_WRAPPER(isBayer) -DECLARE_WRAPPER(isAnyRGB) -DECLARE_WRAPPER(isALPHA) -DECLARE_WRAPPER(isPacked) -DECLARE_WRAPPER(isPlanar) -DECLARE_WRAPPER(isPackedRGB) -DECLARE_WRAPPER(isPlanarRGB) -DECLARE_WRAPPER(usePal) - static const struct { const char *class; int (*cond)(enum AVPixelFormat pix_fmt); } query_tab[] = { - {"is16BPS", is16BPS_func}, - {"isNBPS", isNBPS_func}, - {"isBE", isBE_func}, - {"isYUV", isYUV_func}, - {"isPlanarYUV", isPlanarYUV_func}, - {"isRGB", isRGB_func}, - {"Gray", isGray_func}, - {"RGBinInt", isRGBinInt_func}, - {"BGRinInt", isBGRinInt_func}, - {"Bayer", isBayer_func}, - {"AnyRGB", isAnyRGB_func}, - {"ALPHA", isALPHA_func}, - {"Packed", isPacked_func}, - {"Planar", isPlanar_func}, - {"PackedRGB", isPackedRGB_func}, - {"PlanarRGB", isPlanarRGB_func}, - {"usePal", usePal_func}, + {"is16BPS", is16BPS}, + {"isNBPS", isNBPS}, + {"isBE", isBE}, + {"isYUV", isYUV}, + {"isPlanarYUV", isPlanarYUV}, + {"isRGB", isRGB}, + {"Gray", isGray}, + {"RGBinInt", isRGBinInt}, + {"BGRinInt", isBGRinInt}, + {"Bayer", isBayer}, + {"AnyRGB", isAnyRGB}, + {"ALPHA", isALPHA}, + {"Packed", isPacked}, + {"Planar", isPlanar}, + {"PackedRGB", isPackedRGB}, + {"PlanarRGB", isPlanarRGB}, + {"usePal", usePal}, }; int main(void) From a44ab512e6b905460f13ddb12c47dd2dd9aba501 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Fri, 24 Mar 2017 11:17:51 +0100 Subject: [PATCH 1292/3374] lavu/pixfmt: fix redundant comment Mistake introduced in a1f6b1d9d816ad7e6a8f071b0efa2638bc80e65e. --- libavutil/pixfmt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index 0c406775ef1f0..a936ad34c5362 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -412,7 +412,7 @@ enum AVColorPrimaries { AVCOL_PRI_SMPTE428 = 10, ///< SMPTE ST 428-1 (CIE 1931 XYZ) AVCOL_PRI_SMPTEST428_1 = AVCOL_PRI_SMPTE428, AVCOL_PRI_SMPTE431 = 11, ///< SMPTE ST 431-2 (2011) / DCI P3 - AVCOL_PRI_SMPTE432 = 12, ///< SMPTE ST 432-1 D65 (2010) / P3 D65 / Display P3 + AVCOL_PRI_SMPTE432 = 12, ///< SMPTE ST 432-1 (2010) / P3 D65 / Display P3 AVCOL_PRI_NB ///< Not part of ABI }; From 40ac226014082682e504e8af613ed4169221ac36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Fri, 24 Mar 2017 11:45:23 +0100 Subject: [PATCH 1293/3374] lavc/x86/hevc: rename hevc_res_add to hevc_add_res This will simplify incoming merge. --- libavcodec/x86/Makefile | 4 ++-- libavcodec/x86/{hevc_res_add.asm => hevc_add_res.asm} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename libavcodec/x86/{hevc_res_add.asm => hevc_add_res.asm} (100%) diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile index 3a98a9624c3ef..0295a9f8f7e8e 100644 --- a/libavcodec/x86/Makefile +++ b/libavcodec/x86/Makefile @@ -150,10 +150,10 @@ YASM-OBJS-$(CONFIG_FLAC_DECODER) += x86/flacdsp.o ifdef CONFIG_GPL YASM-OBJS-$(CONFIG_FLAC_ENCODER) += x86/flac_dsp_gpl.o endif -YASM-OBJS-$(CONFIG_HEVC_DECODER) += x86/hevc_mc.o \ +YASM-OBJS-$(CONFIG_HEVC_DECODER) += x86/hevc_add_res.o \ x86/hevc_deblock.o \ x86/hevc_idct.o \ - x86/hevc_res_add.o \ + x86/hevc_mc.o \ x86/hevc_sao.o \ x86/hevc_sao_10bit.o YASM-OBJS-$(CONFIG_JPEG2000_DECODER) += x86/jpeg2000dsp.o diff --git a/libavcodec/x86/hevc_res_add.asm b/libavcodec/x86/hevc_add_res.asm similarity index 100% rename from libavcodec/x86/hevc_res_add.asm rename to libavcodec/x86/hevc_add_res.asm From ac42f080991ccef321f6f9a392e310aeb1379e1c Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 24 Mar 2017 11:23:33 -0300 Subject: [PATCH 1294/3374] x86/hevc_add_res: merge missing changes from 3d6535983282bea542dac2e568ae50da5796be34 Unrolling the loops triplicates the size of the assembled output while not generating any gain in performance. --- libavcodec/x86/hevc_add_res.asm | 70 +++++++++++++++++---------------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/libavcodec/x86/hevc_add_res.asm b/libavcodec/x86/hevc_add_res.asm index 1ea15df0bddc6..d97e4abddbc49 100644 --- a/libavcodec/x86/hevc_add_res.asm +++ b/libavcodec/x86/hevc_add_res.asm @@ -52,7 +52,7 @@ cextern pw_1023 INIT_MMX mmxext ; void ff_hevc_add_residual_4_8_mmxext(uint8_t *dst, int16_t *res, ptrdiff_t stride) -cglobal hevc_add_residual_4_8, 3, 4, 6 +cglobal hevc_add_residual_4_8, 3, 3, 6 ADD_RES_MMX_4_8 add r1, 16 lea r0, [r0+r2*2] @@ -145,30 +145,30 @@ cglobal hevc_add_residual_8_8, 3, 4, 8 RET ; void ff_hevc_add_residual_16_8_(uint8_t *dst, int16_t *res, ptrdiff_t stride) -cglobal hevc_add_residual_16_8, 3, 4, 7 +cglobal hevc_add_residual_16_8, 3, 5, 7 pxor m0, m0 lea r3, [r2*3] + mov r4d, 4 +.loop: ADD_RES_SSE_16_32_8 0, r0, r0+r2 ADD_RES_SSE_16_32_8 64, r0+r2*2, r0+r3 -%rep 3 add r1, 128 lea r0, [r0+r2*4] - ADD_RES_SSE_16_32_8 0, r0, r0+r2 - ADD_RES_SSE_16_32_8 64, r0+r2*2, r0+r3 -%endrep + dec r4d + jg .loop RET ; void ff_hevc_add_residual_32_8_(uint8_t *dst, int16_t *res, ptrdiff_t stride) -cglobal hevc_add_residual_32_8, 3, 4, 7 +cglobal hevc_add_residual_32_8, 3, 5, 7 pxor m0, m0 + mov r4d, 16 +.loop: ADD_RES_SSE_16_32_8 0, r0, r0+16 ADD_RES_SSE_16_32_8 64, r0+r2, r0+r2+16 -%rep 15 add r1, 128 lea r0, [r0+r2*2] - ADD_RES_SSE_16_32_8 0, r0, r0+16 - ADD_RES_SSE_16_32_8 64, r0+r2, r0+r2+16 -%endrep + dec r4d + jg .loop RET %endmacro @@ -180,17 +180,17 @@ TRANSFORM_ADD_8 %if HAVE_AVX2_EXTERNAL INIT_YMM avx2 ; void ff_hevc_add_residual_32_8_avx2(uint8_t *dst, int16_t *res, ptrdiff_t stride) -cglobal hevc_add_residual_32_8, 3, 4, 7 +cglobal hevc_add_residual_32_8, 3, 5, 7 pxor m0, m0 lea r3, [r2*3] + mov r4d, 8 +.loop: ADD_RES_SSE_16_32_8 0, r0, r0+r2 ADD_RES_SSE_16_32_8 128, r0+r2*2, r0+r3 -%rep 7 add r1, 256 lea r0, [r0+r2*4] - ADD_RES_SSE_16_32_8 0, r0, r0+r2 - ADD_RES_SSE_16_32_8 128, r0+r2*2, r0+r3 -%endrep + dec r4d + jg .loop RET %endif @@ -307,7 +307,7 @@ cglobal hevc_add_residual_32_8, 3, 4, 7 ; void ff_hevc_add_residual_<4|8|16|32>_10(pixel *dst, int16_t *block, ptrdiff_t stride) INIT_MMX mmxext -cglobal hevc_add_residual_4_10, 3, 4, 6 +cglobal hevc_add_residual_4_10, 3, 3, 6 pxor m2, m2 mova m3, [max_pixels_10] ADD_RES_MMX_4_10 r0, r2, r1 @@ -328,54 +328,58 @@ cglobal hevc_add_residual_8_10, 3, 4, 6 ADD_RES_SSE_8_10 r0, r2, r3, r1 RET -cglobal hevc_add_residual_16_10, 3, 4, 6 +cglobal hevc_add_residual_16_10, 3, 5, 6 pxor m4, m4 mova m5, [max_pixels_10] + mov r4d, 8 +.loop: ADD_RES_SSE_16_10 r0, r2, r1 -%rep 7 lea r0, [r0+r2*2] add r1, 64 - ADD_RES_SSE_16_10 r0, r2, r1 -%endrep + dec r4d + jg .loop RET -cglobal hevc_add_residual_32_10, 3, 4, 6 +cglobal hevc_add_residual_32_10, 3, 5, 6 pxor m4, m4 mova m5, [max_pixels_10] + mov r4d, 32 +.loop: ADD_RES_SSE_32_10 r0, r1 -%rep 31 lea r0, [r0+r2] add r1, 64 - ADD_RES_SSE_32_10 r0, r1 -%endrep + dec r4d + jg .loop RET %if HAVE_AVX2_EXTERNAL INIT_YMM avx2 -cglobal hevc_add_residual_16_10, 3, 4, 6 +cglobal hevc_add_residual_16_10, 3, 5, 6 pxor m4, m4 mova m5, [max_pixels_10] lea r3, [r2*3] + mov r4d, 4 +.loop: ADD_RES_AVX2_16_10 r0, r2, r3, r1 -%rep 3 lea r0, [r0+r2*4] add r1, 128 - ADD_RES_AVX2_16_10 r0, r2, r3, r1 -%endrep + dec r4d + jg .loop RET -cglobal hevc_add_residual_32_10, 3, 4, 6 +cglobal hevc_add_residual_32_10, 3, 5, 6 pxor m4, m4 mova m5, [max_pixels_10] + mov r4d, 16 +.loop: ADD_RES_AVX2_32_10 r0, r2, r1 -%rep 15 lea r0, [r0+r2*2] add r1, 128 - ADD_RES_AVX2_32_10 r0, r2, r1 -%endrep + dec r4d + jg .loop RET %endif ;HAVE_AVX2_EXTERNAL From e1940d2458353943e2fab6bdb87d2278077e22a5 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Mon, 20 Mar 2017 22:47:48 +0100 Subject: [PATCH 1295/3374] avcodec/dnxhd_parser: take into account compressed frame size and skip it Fixes #6214 and vsynth1-dnxhd-720p-hr-lb. Signed-off-by: Paul B Mahol --- libavcodec/dnxhd_parser.c | 65 ++++++++++++++++++++--- tests/ref/vsynth/vsynth1-dnxhd-720p-hr-lb | 4 +- 2 files changed, 60 insertions(+), 9 deletions(-) diff --git a/libavcodec/dnxhd_parser.c b/libavcodec/dnxhd_parser.c index 033b8ee7e119c..4f9bbceeeb551 100644 --- a/libavcodec/dnxhd_parser.c +++ b/libavcodec/dnxhd_parser.c @@ -31,8 +31,24 @@ typedef struct { ParseContext pc; int interlaced; int cur_field; /* first field is 0, second is 1 */ + int cur_byte; + int remaining; + int w, h; } DNXHDParserContext; +static int dnxhd_get_hr_frame_size(int cid, int w, int h) +{ + int result, i = ff_dnxhd_get_cid_table(cid); + + if (i < 0) + return i; + + result = ((h + 15) / 16) * ((w + 15) / 16) * ff_dnxhd_cid_table[i].packet_scale.num / ff_dnxhd_cid_table[i].packet_scale.den; + result = (result + 2048) / 4096 * 4096; + + return FFMAX(result, 8192); +} + static int dnxhd_find_frame_end(DNXHDParserContext *dctx, const uint8_t *buf, int buf_size) { @@ -51,30 +67,65 @@ static int dnxhd_find_frame_end(DNXHDParserContext *dctx, pic_found = 1; interlaced = (state&2)>>1; /* byte following the 5-byte header prefix */ cur_field = state&1; + dctx->cur_byte = 0; + dctx->remaining = 0; break; } } } - if (pic_found) { + if (pic_found && !dctx->remaining) { if (!buf_size) /* EOF considered as end of frame */ return 0; for (; i < buf_size; i++) { + dctx->cur_byte++; state = (state << 8) | buf[i]; - if (ff_dnxhd_check_header_prefix(state & 0xffffffffff00LL) != 0) { - if (!interlaced || dctx->cur_field) { + + if (dctx->cur_byte == 24) { + dctx->h = (state >> 32) & 0xFFFF; + } else if (dctx->cur_byte == 26) { + dctx->w = (state >> 32) & 0xFFFF; + } else if (dctx->cur_byte == 42) { + int cid = (state >> 32) & 0xFFFFFFFF; + + if (cid <= 0) + continue; + + dctx->remaining = avpriv_dnxhd_get_frame_size(cid); + if (dctx->remaining <= 0) { + dctx->remaining = dnxhd_get_hr_frame_size(cid, dctx->w, dctx->h); + if (dctx->remaining <= 0) + return dctx->remaining; + } + if (buf_size - i >= dctx->remaining && (!dctx->interlaced || dctx->cur_field)) { + int remaining = dctx->remaining; + pc->frame_start_found = 0; pc->state64 = -1; dctx->interlaced = interlaced; dctx->cur_field = 0; - return i - 5; + dctx->cur_byte = 0; + dctx->remaining = 0; + return remaining; } else { - /* continue, to get the second field */ - dctx->interlaced = interlaced = (state&2)>>1; - dctx->cur_field = cur_field = state&1; + dctx->remaining -= buf_size; } } } + } else if (pic_found) { + if (dctx->remaining > buf_size) { + dctx->remaining -= buf_size; + } else { + int remaining = dctx->remaining; + + pc->frame_start_found = 0; + pc->state64 = -1; + dctx->interlaced = interlaced; + dctx->cur_field = 0; + dctx->cur_byte = 0; + dctx->remaining = 0; + return remaining; + } } pc->frame_start_found = pic_found; pc->state64 = state; diff --git a/tests/ref/vsynth/vsynth1-dnxhd-720p-hr-lb b/tests/ref/vsynth/vsynth1-dnxhd-720p-hr-lb index 3490d4aeef246..27e593120a010 100644 --- a/tests/ref/vsynth/vsynth1-dnxhd-720p-hr-lb +++ b/tests/ref/vsynth/vsynth1-dnxhd-720p-hr-lb @@ -1,4 +1,4 @@ 08cbfe9b9f671cdb9dddc9307121d107 *tests/data/fate/vsynth1-dnxhd-720p-hr-lb.dnxhd 409600 tests/data/fate/vsynth1-dnxhd-720p-hr-lb.dnxhd -22eb87f0f8a50278355006fef70073a9 *tests/data/fate/vsynth1-dnxhd-720p-hr-lb.out.rawvideo -stddev: 7.49 PSNR: 30.63 MAXDIFF: 64 bytes: 7603200/ 608256 +77e510e3538313b1cbafb86ed248d2df *tests/data/fate/vsynth1-dnxhd-720p-hr-lb.out.rawvideo +stddev: 7.50 PSNR: 30.62 MAXDIFF: 64 bytes: 7603200/ 760320 From 824fe914fee7fb5dc8c8c14940e511cda089c36d Mon Sep 17 00:00:00 2001 From: Thomas Turner Date: Thu, 23 Mar 2017 22:48:28 -0700 Subject: [PATCH 1296/3374] avcodec/tests: added test for celp_math.c Signed-off-by: Thomas Turner Signed-off-by: Michael Niedermayer --- libavcodec/Makefile | 1 + libavcodec/tests/celp_math.c | 48 ++++++++++++++++++++++++++++++++++++ tests/fate/libavcodec.mak | 5 ++++ 3 files changed, 54 insertions(+) create mode 100644 libavcodec/tests/celp_math.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 89296cde8c6a5..05be516bbab00 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -1024,6 +1024,7 @@ SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h vdpau_internal.h SKIPHEADERS-$(CONFIG_VIDEOTOOLBOX) += videotoolbox.h vda_vt_internal.h TESTPROGS = avpacket \ + celp_math \ imgconvert \ jpeg2000dwt \ mathops \ diff --git a/libavcodec/tests/celp_math.c b/libavcodec/tests/celp_math.c new file mode 100644 index 0000000000000..4b1c1867b5e04 --- /dev/null +++ b/libavcodec/tests/celp_math.c @@ -0,0 +1,48 @@ +/* + * 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 "libavutil/libm.h" +#include "libavcodec/celp_math.c" + +int main(void) +{ + int i; + const float f1[3] = {0.0, 1.1, 2.2}; + const float f2[3] = {3.3, 4.4, 5.5}; + const int16_t i1[3] = {6, 7, 8}; + const int16_t i2[3] = {9, 10, 11}; + float diff, largest, absa, absb; + + float r = ff_dot_productf(f1, f2, FF_ARRAY_ELEMS(f1)); + int64_t d = ff_dot_product(i1, i2, FF_ARRAY_ELEMS(i1)); + +# define IsAlmostEqual(A, B, epsilon) \ + diff = fabsf(A - B); \ + absa = fabsf(A); \ + absb = fabsf(B); \ + largest = (absb > absa) ? absb : absa; \ + av_assert0(diff <= largest * epsilon); + + IsAlmostEqual(16.94f, r, 0.000001f); + av_assert0(212 == d); + + for (i = 1024; i >= 1; i/=2) + av_assert0(ff_log2_q15(i) == (1<<15)*((int)log2(i))+(1<<2)); + + return 0; +} diff --git a/tests/fate/libavcodec.mak b/tests/fate/libavcodec.mak index 32b0c1e6ab953..07417f0e6a030 100644 --- a/tests/fate/libavcodec.mak +++ b/tests/fate/libavcodec.mak @@ -8,6 +8,11 @@ fate-cabac: libavcodec/tests/cabac$(EXESUF) fate-cabac: CMD = run libavcodec/tests/cabac fate-cabac: REF = /dev/null +FATE_LIBAVCODEC-yes += fate-celp_math +fate-celp_math: libavcodec/tests/celp_math$(EXESUF) +fate-celp_math: CMD = run libavcodec/tests/celp_math +fate-celp_math: REF = /dev/null + FATE_LIBAVCODEC-$(CONFIG_GOLOMB) += fate-golomb fate-golomb: libavcodec/tests/golomb$(EXESUF) fate-golomb: CMD = run libavcodec/tests/golomb From d92ad42fb38a312c86b71b0e17fe860f0c881be4 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 24 Mar 2017 17:45:56 +0100 Subject: [PATCH 1297/3374] avcodec/tests/celp_math: Change IsAlmostEqual() to a function Fixes empty statement, found by ubitux Signed-off-by: Michael Niedermayer --- libavcodec/tests/celp_math.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/libavcodec/tests/celp_math.c b/libavcodec/tests/celp_math.c index 4b1c1867b5e04..669ea7036215a 100644 --- a/libavcodec/tests/celp_math.c +++ b/libavcodec/tests/celp_math.c @@ -19,6 +19,15 @@ #include "libavutil/libm.h" #include "libavcodec/celp_math.c" +static inline void IsAlmostEqual(float A, float B, float epsilon) +{ + float diff = fabsf(A - B); + float absa = fabsf(A); + float absb = fabsf(B); + float largest = (absb > absa) ? absb : absa; + av_assert0(diff <= largest * epsilon); +} + int main(void) { int i; @@ -26,18 +35,10 @@ int main(void) const float f2[3] = {3.3, 4.4, 5.5}; const int16_t i1[3] = {6, 7, 8}; const int16_t i2[3] = {9, 10, 11}; - float diff, largest, absa, absb; float r = ff_dot_productf(f1, f2, FF_ARRAY_ELEMS(f1)); int64_t d = ff_dot_product(i1, i2, FF_ARRAY_ELEMS(i1)); -# define IsAlmostEqual(A, B, epsilon) \ - diff = fabsf(A - B); \ - absa = fabsf(A); \ - absb = fabsf(B); \ - largest = (absb > absa) ? absb : absa; \ - av_assert0(diff <= largest * epsilon); - IsAlmostEqual(16.94f, r, 0.000001f); av_assert0(212 == d); From 66c1c9b2774968dc26017269ac175b356592f878 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Sun, 26 Feb 2017 11:03:50 +0100 Subject: [PATCH 1298/3374] lavc/xface: Reorder conditions to silence a gcc warning. libavcodec/xface.c:318:27: warning: assuming signed overflow does not occur when assuming that (X - c) > X is always false [-Wstrict-overflow] --- libavcodec/xface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/xface.c b/libavcodec/xface.c index 8c0cbfdb84af3..184c17417754b 100644 --- a/libavcodec/xface.c +++ b/libavcodec/xface.c @@ -315,9 +315,9 @@ void ff_xface_generate_face(uint8_t *dst, uint8_t * const src) for (l = i - 2; l <= i + 2; l++) { for (m = j - 2; m <= j; m++) { - if (l >= i && m == j) + if (l <= 0 || l >= i && m == j) continue; - if (l > 0 && l <= XFACE_WIDTH && m > 0) + if (l <= XFACE_WIDTH && m > 0) k = 2*k + src[l + m * XFACE_WIDTH]; } } From b68068eed20ec4eeae97fb10548c32e9ce75357c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Fri, 24 Mar 2017 22:28:02 +0100 Subject: [PATCH 1299/3374] fate: mask errors while constructing report files The first case was forgotten in 89790ba2bfc9d0dc5ad407c5724b6ee616ecde58. Note: build_only=yes is one of the case where hiding the errors makes sense. --- tests/fate.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fate.sh b/tests/fate.sh index 885ea17a1b6a0..bbdc7015a6971 100755 --- a/tests/fate.sh +++ b/tests/fate.sh @@ -86,7 +86,7 @@ report(){ date=$(date -u +%Y%m%d%H%M%S) echo "fate:1:${date}:${slot}:${version}:$1:$2:${branch}:${comment}" >report cat ${build}/config.fate >>report - cat ${build}/tests/data/fate/*.rep >>report || for i in ${build}/tests/data/fate/*.rep ; do cat "$i" >>report 2>/dev/null; done + cat ${build}/tests/data/fate/*.rep >>report 2>/dev/null || for i in ${build}/tests/data/fate/*.rep ; do cat "$i" >>report 2>/dev/null; done test -n "$fate_recv" && $tar report *.log | gzip | $fate_recv } From 36eae45510435378cfc498c6b68966492a58d03e Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 24 Mar 2017 22:11:22 -0300 Subject: [PATCH 1300/3374] fate/checkasm: use LOCAL_ALINGED_32 on hevc_add_res tests --- tests/checkasm/hevc_add_res.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/checkasm/hevc_add_res.c b/tests/checkasm/hevc_add_res.c index d2b5266aa58ed..ddb0584f86a5b 100644 --- a/tests/checkasm/hevc_add_res.c +++ b/tests/checkasm/hevc_add_res.c @@ -45,10 +45,10 @@ static void check_add_res(HEVCDSPContext h, int bit_depth) { int i; - LOCAL_ALIGNED(32, int16_t, res0, [32 * 32]); - LOCAL_ALIGNED(32, int16_t, res1, [32 * 32]); - LOCAL_ALIGNED(32, uint8_t, dst0, [32 * 32 * 2]); - LOCAL_ALIGNED(32, uint8_t, dst1, [32 * 32 * 2]); + LOCAL_ALIGNED_32(int16_t, res0, [32 * 32]); + LOCAL_ALIGNED_32(int16_t, res1, [32 * 32]); + LOCAL_ALIGNED_32(uint8_t, dst0, [32 * 32 * 2]); + LOCAL_ALIGNED_32(uint8_t, dst1, [32 * 32 * 2]); for (i = 2; i <= 5; i++) { int block_size = 1 << i; From 09ce5519f3b44873ac242e9a2f89db7d459de532 Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 24 Mar 2017 22:11:34 -0300 Subject: [PATCH 1301/3374] fate/checkasm: fix use of uninitialized memory on hevc_add_res tests --- tests/checkasm/hevc_add_res.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/checkasm/hevc_add_res.c b/tests/checkasm/hevc_add_res.c index ddb0584f86a5b..185656ae8c602 100644 --- a/tests/checkasm/hevc_add_res.c +++ b/tests/checkasm/hevc_add_res.c @@ -59,7 +59,7 @@ static void check_add_res(HEVCDSPContext h, int bit_depth) randomize_buffers(res0, size); randomize_buffers2(dst0, size); memcpy(res1, res0, sizeof(*res0) * size); - memcpy(dst1, dst0, size); + memcpy(dst1, dst0, sizeof(int16_t) * size); if (check_func(h.add_residual[i - 2], "add_res_%dx%d_%d", block_size, block_size, bit_depth)) { call_ref(dst0, res0, stride); From bd717340a28ef0fdb997584623236c4428a3bdae Mon Sep 17 00:00:00 2001 From: Timo Rothenpieler Date: Sat, 25 Mar 2017 22:31:22 +0100 Subject: [PATCH 1302/3374] configure: cuvid hwaccels need the corresponding decoder, not the other way around --- configure | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/configure b/configure index c1aeb6e252c1a..9cc7e7d4c159c 100755 --- a/configure +++ b/configure @@ -2604,6 +2604,7 @@ h263_videotoolbox_hwaccel_deps="videotoolbox" h263_videotoolbox_hwaccel_select="h263_decoder" h264_crystalhd_decoder_select="crystalhd h264_mp4toannexb_bsf h264_parser" h264_cuvid_hwaccel_deps="cuda cuvid" +h264_cuvid_hwaccel_select="h264_cuvid_decoder" h264_d3d11va_hwaccel_deps="d3d11va" h264_d3d11va_hwaccel_select="h264_decoder" h264_dxva2_hwaccel_deps="dxva2" @@ -2631,6 +2632,7 @@ h264_vdpau_hwaccel_select="h264_decoder" h264_videotoolbox_hwaccel_deps="videotoolbox" h264_videotoolbox_hwaccel_select="h264_decoder" hevc_cuvid_hwaccel_deps="cuda cuvid" +hevc_cuvid_hwaccel_select="hevc_cuvid_decoder" hevc_d3d11va_hwaccel_deps="d3d11va DXVA_PicParams_HEVC" hevc_d3d11va_hwaccel_select="hevc_decoder" hevc_mediacodec_decoder_deps="mediacodec" @@ -2644,11 +2646,13 @@ hevc_vaapi_hwaccel_select="hevc_decoder" hevc_vdpau_hwaccel_deps="vdpau VdpPictureInfoHEVC" hevc_vdpau_hwaccel_select="hevc_decoder" mjpeg_cuvid_hwaccel_deps="cuda cuvid" +mjpeg_cuvid_hwaccel_select="mjpeg_cuvid_decoder" mpeg_vdpau_decoder_deps="vdpau" mpeg_vdpau_decoder_select="mpeg2video_decoder" mpeg_xvmc_hwaccel_deps="xvmc" mpeg_xvmc_hwaccel_select="mpeg2video_decoder" mpeg1_cuvid_hwaccel_deps="cuda cuvid" +mpeg1_cuvid_hwaccel_select="mpeg1_cuvid_decoder" mpeg1_vdpau_decoder_deps="vdpau" mpeg1_vdpau_decoder_select="mpeg1video_decoder" mpeg1_vdpau_hwaccel_deps="vdpau" @@ -2659,6 +2663,7 @@ mpeg1_xvmc_hwaccel_deps="xvmc" mpeg1_xvmc_hwaccel_select="mpeg1video_decoder" mpeg2_crystalhd_decoder_select="crystalhd" mpeg2_cuvid_hwaccel_deps="cuda cuvid" +mpeg2_cuvid_hwaccel_select="mpeg2_cuvid_decoder" mpeg2_d3d11va_hwaccel_deps="d3d11va" mpeg2_d3d11va_hwaccel_select="mpeg2video_decoder" mpeg2_dxva2_hwaccel_deps="dxva2" @@ -2678,6 +2683,7 @@ mpeg2_xvmc_hwaccel_deps="xvmc" mpeg2_xvmc_hwaccel_select="mpeg2video_decoder" mpeg4_crystalhd_decoder_select="crystalhd" mpeg4_cuvid_hwaccel_deps="cuda cuvid" +mpeg4_cuvid_hwaccel_select="mpeg4_cuvid_decoder" mpeg4_mediacodec_decoder_deps="mediacodec" mpeg4_mediacodec_hwaccel_deps="mediacodec" mpeg4_mmal_decoder_deps="mmal" @@ -2695,6 +2701,7 @@ mpeg4_videotoolbox_hwaccel_select="mpeg4_decoder" msmpeg4_crystalhd_decoder_select="crystalhd" vc1_crystalhd_decoder_select="crystalhd" vc1_cuvid_hwaccel_deps="cuda cuvid" +vc1_cuvid_hwaccel_select="vc1_cuvid_decoder" vc1_d3d11va_hwaccel_deps="d3d11va" vc1_d3d11va_hwaccel_select="vc1_decoder" vc1_dxva2_hwaccel_deps="dxva2" @@ -2711,7 +2718,9 @@ vc1_vdpau_decoder_select="vc1_decoder" vc1_vdpau_hwaccel_deps="vdpau" vc1_vdpau_hwaccel_select="vc1_decoder" vp8_cuvid_hwaccel_deps="cuda cuvid" +vp8_cuvid_hwaccel_select="vp8_cuvid_decoder" vp9_cuvid_hwaccel_deps="cuda cuvid" +vp9_cuvid_hwaccel_select="vp9_cuvid_decoder" vp8_mediacodec_decoder_deps="mediacodec" vp8_mediacodec_hwaccel_deps="mediacodec" vp9_d3d11va_hwaccel_deps="d3d11va DXVA_PicParams_VP9" @@ -2743,7 +2752,7 @@ nvenc_deps="cuda" nvenc_deps_any="dlopen LoadLibrary" nvenc_encoder_deps="nvenc" h264_cuvid_decoder_deps="cuda cuvid" -h264_cuvid_decoder_select="h264_mp4toannexb_bsf h264_cuvid_hwaccel" +h264_cuvid_decoder_select="h264_mp4toannexb_bsf" h264_nvenc_encoder_deps="nvenc" h264_qsv_decoder_deps="libmfx" h264_qsv_decoder_select="h264_mp4toannexb_bsf h264_parser qsvdec h264_qsv_hwaccel" @@ -2753,7 +2762,7 @@ h264_vaapi_encoder_deps="VAEncPictureParameterBufferH264" h264_vaapi_encoder_select="vaapi_encode golomb" hevc_cuvid_decoder_deps="cuda cuvid" -hevc_cuvid_decoder_select="hevc_mp4toannexb_bsf hevc_cuvid_hwaccel" +hevc_cuvid_decoder_select="hevc_mp4toannexb_bsf" hevc_nvenc_encoder_deps="nvenc" hevc_qsv_decoder_deps="libmfx" hevc_qsv_decoder_select="hevc_mp4toannexb_bsf hevc_parser qsvdec hevc_qsv_hwaccel" @@ -2762,11 +2771,8 @@ hevc_qsv_encoder_select="qsvenc" hevc_vaapi_encoder_deps="VAEncPictureParameterBufferHEVC" hevc_vaapi_encoder_select="vaapi_encode golomb" mjpeg_cuvid_decoder_deps="cuda cuvid" -mjpeg_cuvid_decoder_select="mjpeg_cuvid_hwaccel" mpeg1_cuvid_decoder_deps="cuda cuvid" -mpeg1_cuvid_decoder_select="mpeg1_cuvid_hwaccel" mpeg2_cuvid_decoder_deps="cuda cuvid" -mpeg2_cuvid_decoder_select="mpeg2_cuvid_hwaccel" mpeg2_qsv_decoder_deps="libmfx" mpeg2_qsv_decoder_select="qsvdec mpeg2_qsv_hwaccel" mpeg2_qsv_encoder_deps="libmfx" @@ -2774,18 +2780,14 @@ mpeg2_qsv_encoder_select="qsvenc" mpeg2_vaapi_encoder_deps="VAEncPictureParameterBufferMPEG2" mpeg2_vaapi_encoder_select="vaapi_encode" mpeg4_cuvid_decoder_deps="cuda cuvid" -mpeg4_cuvid_decoder_select="mpeg4_cuvid_hwaccel" nvenc_h264_encoder_deps="nvenc" nvenc_hevc_encoder_deps="nvenc" vc1_cuvid_decoder_deps="cuda cuvid" -vc1_cuvid_decoder_select="vc1_cuvid_hwaccel" vp8_cuvid_decoder_deps="cuda cuvid" -vp8_cuvid_decoder_select="vp8_cuvid_hwaccel" vp8_vaapi_encoder_deps="VAEncPictureParameterBufferVP8" vp8_vaapi_encoder_select="vaapi_encode" vp9_cuvid_decoder_deps="cuda cuvid" -vp9_cuvid_decoder_select="vp9_cuvid_hwaccel" # parsers h264_parser_select="golomb h264dsp h264parse" From 2f05d18ee2c74e4c3619bf2ef6a64f686519f3c7 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 25 Mar 2017 21:34:52 -0300 Subject: [PATCH 1303/3374] ffmpeg: stop using deprecated codec flags Signed-off-by: James Almer --- ffmpeg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ffmpeg.c b/ffmpeg.c index 532db80e0b1e7..62e7d8222df88 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -1541,7 +1541,7 @@ static void print_final_stats(int64_t total_size) } extra_size += ost->enc_ctx->extradata_size; data_size += ost->data_size; - if ( (ost->enc_ctx->flags & (AV_CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2)) + if ( (ost->enc_ctx->flags & (AV_CODEC_FLAG_PASS1 | AV_CODEC_FLAG_PASS2)) != AV_CODEC_FLAG_PASS1) pass1_used = 0; } From f5c8d004c28d930d780c9164f7ed6005b88b9be5 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 25 Mar 2017 21:35:15 -0300 Subject: [PATCH 1304/3374] avcodec: stop using deprecated codec flags Signed-off-by: James Almer --- libavcodec/aaccoder.c | 8 ++++---- libavcodec/aaccoder_twoloop.h | 10 +++++----- libavcodec/aacenc.c | 2 +- libavcodec/aacpsy.c | 6 +++--- libavcodec/clearvideo.c | 2 +- libavcodec/pngenc.c | 4 ++-- libavcodec/psymodel.h | 2 +- libavcodec/snowenc.c | 4 ++-- libavcodec/xpmdec.c | 2 +- 9 files changed, 20 insertions(+), 20 deletions(-) diff --git a/libavcodec/aaccoder.c b/libavcodec/aaccoder.c index 9f3b4ed3895b1..abd0b9c636c17 100644 --- a/libavcodec/aaccoder.c +++ b/libavcodec/aaccoder.c @@ -557,13 +557,13 @@ static void search_for_pns(AACEncContext *s, AVCodecContext *avctx, SingleChanne const float pns_transient_energy_r = FFMIN(0.7f, lambda / 140.f); int refbits = avctx->bit_rate * 1024.0 / avctx->sample_rate - / ((avctx->flags & CODEC_FLAG_QSCALE) ? 2.0f : avctx->channels) + / ((avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : avctx->channels) * (lambda / 120.f); /** Keep this in sync with twoloop's cutoff selection */ float rate_bandwidth_multiplier = 1.5f; int prev = -1000, prev_sf = -1; - int frame_bit_rate = (avctx->flags & CODEC_FLAG_QSCALE) + int frame_bit_rate = (avctx->flags & AV_CODEC_FLAG_QSCALE) ? (refbits * rate_bandwidth_multiplier * avctx->sample_rate / 1024) : (avctx->bit_rate / avctx->channels); @@ -694,12 +694,12 @@ static void mark_pns(AACEncContext *s, AVCodecContext *avctx, SingleChannelEleme const float pns_transient_energy_r = FFMIN(0.7f, lambda / 140.f); int refbits = avctx->bit_rate * 1024.0 / avctx->sample_rate - / ((avctx->flags & CODEC_FLAG_QSCALE) ? 2.0f : avctx->channels) + / ((avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : avctx->channels) * (lambda / 120.f); /** Keep this in sync with twoloop's cutoff selection */ float rate_bandwidth_multiplier = 1.5f; - int frame_bit_rate = (avctx->flags & CODEC_FLAG_QSCALE) + int frame_bit_rate = (avctx->flags & AV_CODEC_FLAG_QSCALE) ? (refbits * rate_bandwidth_multiplier * avctx->sample_rate / 1024) : (avctx->bit_rate / avctx->channels); diff --git a/libavcodec/aaccoder_twoloop.h b/libavcodec/aaccoder_twoloop.h index f175c5f8b8846..8e1bc88a8538f 100644 --- a/libavcodec/aaccoder_twoloop.h +++ b/libavcodec/aaccoder_twoloop.h @@ -71,7 +71,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx, { int start = 0, i, w, w2, g, recomprd; int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate - / ((avctx->flags & CODEC_FLAG_QSCALE) ? 2.0f : avctx->channels) + / ((avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : avctx->channels) * (lambda / 120.f); int refbits = destbits; int toomanybits, toofewbits; @@ -136,7 +136,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx, * (lambda / (avctx->global_quality ? avctx->global_quality : 120)); } - if (avctx->flags & CODEC_FLAG_QSCALE) { + if (avctx->flags & AV_CODEC_FLAG_QSCALE) { /** * Constant Q-scale doesn't compensate MS coding on its own * No need to be overly precise, this only controls RD @@ -184,7 +184,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx, * AAC_CUTOFF_FROM_BITRATE is calibrated for effective bitrate. */ float rate_bandwidth_multiplier = 1.5f; - int frame_bit_rate = (avctx->flags & CODEC_FLAG_QSCALE) + int frame_bit_rate = (avctx->flags & AV_CODEC_FLAG_QSCALE) ? (refbits * rate_bandwidth_multiplier * avctx->sample_rate / 1024) : (avctx->bit_rate / avctx->channels); @@ -332,7 +332,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx, sce->coeffs + start, nzslope * cleanup_factor); energy2uplim *= de_psy_factor; - if (!(avctx->flags & CODEC_FLAG_QSCALE)) { + if (!(avctx->flags & AV_CODEC_FLAG_QSCALE)) { /** In ABR, we need to priorize less and let rate control do its thing */ energy2uplim = sqrtf(energy2uplim); } @@ -346,7 +346,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx, sce->coeffs + start, 2.0f); energy2uplim *= de_psy_factor; - if (!(avctx->flags & CODEC_FLAG_QSCALE)) { + if (!(avctx->flags & AV_CODEC_FLAG_QSCALE)) { /** In ABR, we need to priorize less and let rate control do its thing */ energy2uplim = sqrtf(energy2uplim); } diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c index 956e974cb2aba..11da260742b09 100644 --- a/libavcodec/aacenc.c +++ b/libavcodec/aacenc.c @@ -769,7 +769,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, start_ch += chans; } - if (avctx->flags & CODEC_FLAG_QSCALE) { + if (avctx->flags & AV_CODEC_FLAG_QSCALE) { /* When using a constant Q-scale, don't mess with lambda */ break; } diff --git a/libavcodec/aacpsy.c b/libavcodec/aacpsy.c index a5fec7374ee37..e32faaa908075 100644 --- a/libavcodec/aacpsy.c +++ b/libavcodec/aacpsy.c @@ -303,7 +303,7 @@ static av_cold int psy_3gpp_init(FFPsyContext *ctx) { float bark; int i, j, g, start; float prev, minscale, minath, minsnr, pe_min; - int chan_bitrate = ctx->avctx->bit_rate / ((ctx->avctx->flags & CODEC_FLAG_QSCALE) ? 2.0f : ctx->avctx->channels); + int chan_bitrate = ctx->avctx->bit_rate / ((ctx->avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : ctx->avctx->channels); const int bandwidth = ctx->cutoff ? ctx->cutoff : AAC_CUTOFF(ctx->avctx); const float num_bark = calc_bark((float)bandwidth); @@ -314,7 +314,7 @@ static av_cold int psy_3gpp_init(FFPsyContext *ctx) { pctx = (AacPsyContext*) ctx->model_priv_data; pctx->global_quality = (ctx->avctx->global_quality ? ctx->avctx->global_quality : 120) * 0.01f; - if (ctx->avctx->flags & CODEC_FLAG_QSCALE) { + if (ctx->avctx->flags & AV_CODEC_FLAG_QSCALE) { /* Use the target average bitrate to compute spread parameters */ chan_bitrate = (int)(chan_bitrate / 120.0 * (ctx->avctx->global_quality ? ctx->avctx->global_quality : 120)); } @@ -704,7 +704,7 @@ static void psy_3gpp_analyze_channel(FFPsyContext *ctx, int channel, /* 5.6.1.3.2 "Calculation of the desired perceptual entropy" */ ctx->ch[channel].entropy = pe; - if (ctx->avctx->flags & CODEC_FLAG_QSCALE) { + if (ctx->avctx->flags & AV_CODEC_FLAG_QSCALE) { /* (2.5 * 120) achieves almost transparent rate, and we want to give * ample room downwards, so we make that equivalent to QSCALE=2.4 */ diff --git a/libavcodec/clearvideo.c b/libavcodec/clearvideo.c index 91f37e1b62a7f..e2644e3090d11 100644 --- a/libavcodec/clearvideo.c +++ b/libavcodec/clearvideo.c @@ -382,6 +382,6 @@ AVCodec ff_clearvideo_decoder = { .init = clv_decode_init, .close = clv_decode_end, .decode = clv_decode_frame, - .capabilities = CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Iterated Systems ClearVideo"), }; diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c index f67a546f951d4..69b44954049a5 100644 --- a/libavcodec/pngenc.c +++ b/libavcodec/pngenc.c @@ -873,7 +873,7 @@ static int encode_apng(AVCodecContext *avctx, AVPacket *pkt, if (!pict) return AVERROR(EINVAL); - s->bytestream = s->extra_data = av_malloc(FF_MIN_BUFFER_SIZE); + s->bytestream = s->extra_data = av_malloc(AV_INPUT_BUFFER_MIN_SIZE); if (!s->extra_data) return AVERROR(ENOMEM); @@ -1167,7 +1167,7 @@ AVCodec ff_apng_encoder = { .init = png_enc_init, .close = png_enc_close, .encode2 = encode_apng, - .capabilities = CODEC_CAP_DELAY, + .capabilities = AV_CODEC_CAP_DELAY, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB48BE, AV_PIX_FMT_RGBA64BE, diff --git a/libavcodec/psymodel.h b/libavcodec/psymodel.h index 582f040c7a380..e5f917d495d0b 100644 --- a/libavcodec/psymodel.h +++ b/libavcodec/psymodel.h @@ -39,7 +39,7 @@ 22000, \ sample_rate / 2): (sample_rate / 2)) #define AAC_CUTOFF(s) ( \ - (s->flags & CODEC_FLAG_QSCALE) \ + (s->flags & AV_CODEC_FLAG_QSCALE) \ ? s->sample_rate / 2 \ : AAC_CUTOFF_FROM_BITRATE(s->bit_rate, s->channels, s->sample_rate) \ ) diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c index 5cc7997f5c9c4..ca55914d9e313 100644 --- a/libavcodec/snowenc.c +++ b/libavcodec/snowenc.c @@ -106,11 +106,11 @@ FF_ENABLE_DEPRECATION_WARNINGS if (!avctx->stats_out) return AVERROR(ENOMEM); } - if((avctx->flags&AV_CODEC_FLAG_PASS2) || !(avctx->flags&CODEC_FLAG_QSCALE)){ + if((avctx->flags&AV_CODEC_FLAG_PASS2) || !(avctx->flags&AV_CODEC_FLAG_QSCALE)){ if(ff_rate_control_init(&s->m) < 0) return -1; } - s->pass1_rc= !(avctx->flags & (AV_CODEC_FLAG_QSCALE|CODEC_FLAG_PASS2)); + s->pass1_rc= !(avctx->flags & (AV_CODEC_FLAG_QSCALE|AV_CODEC_FLAG_PASS2)); switch(avctx->pix_fmt){ case AV_PIX_FMT_YUV444P: diff --git a/libavcodec/xpmdec.c b/libavcodec/xpmdec.c index 3c025a6bc5baa..9112d4cb5e0b3 100644 --- a/libavcodec/xpmdec.c +++ b/libavcodec/xpmdec.c @@ -415,6 +415,6 @@ AVCodec ff_xpm_decoder = { .priv_data_size = sizeof(XPMDecContext), .close = xpm_decode_close, .decode = xpm_decode_frame, - .capabilities = CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("XPM (X PixMap) image") }; From 963cd953fbf6a57d8433043f3a3b341dd85c60f0 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 25 Mar 2017 21:35:52 -0300 Subject: [PATCH 1305/3374] avfilter: stop using deprecated codec flags Signed-off-by: James Almer --- libavfilter/vf_mcdeint.c | 2 +- libavfilter/vf_uspp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libavfilter/vf_mcdeint.c b/libavfilter/vf_mcdeint.c index 050a8341d9b54..d4f718cc95a3c 100644 --- a/libavfilter/vf_mcdeint.c +++ b/libavfilter/vf_mcdeint.c @@ -122,7 +122,7 @@ static int config_props(AVFilterLink *inlink) enc_ctx->gop_size = INT_MAX; enc_ctx->max_b_frames = 0; enc_ctx->pix_fmt = AV_PIX_FMT_YUV420P; - enc_ctx->flags = AV_CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY; + enc_ctx->flags = AV_CODEC_FLAG_QSCALE | AV_CODEC_FLAG_LOW_DELAY; enc_ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; enc_ctx->global_quality = 1; enc_ctx->me_cmp = enc_ctx->me_sub_cmp = FF_CMP_SAD; diff --git a/libavfilter/vf_uspp.c b/libavfilter/vf_uspp.c index 8a6d0fbb93935..ef493b860faf2 100644 --- a/libavfilter/vf_uspp.c +++ b/libavfilter/vf_uspp.c @@ -357,7 +357,7 @@ static int config_input(AVFilterLink *inlink) avctx_enc->gop_size = INT_MAX; avctx_enc->max_b_frames = 0; avctx_enc->pix_fmt = inlink->format; - avctx_enc->flags = AV_CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY; + avctx_enc->flags = AV_CODEC_FLAG_QSCALE | AV_CODEC_FLAG_LOW_DELAY; avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; avctx_enc->global_quality = 123; av_dict_set(&opts, "no_bitstream", "1", 0); From d054069c1540ff2c7fb8097b830ee852afad7021 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 25 Mar 2017 21:36:10 -0300 Subject: [PATCH 1306/3374] avformat/mov: stop using deprecated codec flags Signed-off-by: James Almer --- libavformat/mov.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 41bf21d8c35eb..2fce5a68352ae 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -873,7 +873,7 @@ static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom) uint32_t channel_layout_code = 0; GetBitContext gb; - buf = av_malloc(ddts_size + FF_INPUT_BUFFER_PADDING_SIZE); + buf = av_malloc(ddts_size + AV_INPUT_BUFFER_PADDING_SIZE); if (!buf) { return AVERROR(ENOMEM); } From ec996163c8dbacf39c1a3d490d0467299af9a0bd Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 24 Mar 2017 18:10:53 -0300 Subject: [PATCH 1307/3374] avcodec/extract_extradata_bsf: use the parsing code from mpegvideo_split() Changes to the parsing code originally committed to mpegvideo_parser.c in 73fb23dc5a5. Required by some samples, like PVA_test-partial.pva Reviewed-by: Michael Niedermayer Signed-off-by: James Almer --- libavcodec/extract_extradata_bsf.c | 46 ++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/libavcodec/extract_extradata_bsf.c b/libavcodec/extract_extradata_bsf.c index 0d11f86304852..d909ee6d17b86 100644 --- a/libavcodec/extract_extradata_bsf.c +++ b/libavcodec/extract_extradata_bsf.c @@ -170,19 +170,47 @@ static int extract_extradata_vc1(AVBSFContext *ctx, AVPacket *pkt, return 0; } -static int extract_extradata_mpeg124(AVBSFContext *ctx, AVPacket *pkt, +static int extract_extradata_mpeg12(AVBSFContext *ctx, AVPacket *pkt, uint8_t **data, int *size) { ExtractExtradataContext *s = ctx->priv_data; - int is_mpeg12 = ctx->par_in->codec_id == AV_CODEC_ID_MPEG1VIDEO || - ctx->par_in->codec_id == AV_CODEC_ID_MPEG2VIDEO; + uint32_t state = UINT32_MAX; + int i, found = 0; + + for (i = 0; i < pkt->size; i++) { + state = (state << 8) | pkt->data[i]; + if (state == 0x1B3) + found = 1; + else if (found && state != 0x1B5 && state < 0x200 && state >= 0x100) { + if (i > 3) { + *size = i - 3; + *data = av_malloc(*size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!*data) + return AVERROR(ENOMEM); + + memcpy(*data, pkt->data, *size); + + if (s->remove) { + pkt->data += *size; + pkt->size -= *size; + } + } + break; + } + } + return 0; +} + +static int extract_extradata_mpeg4(AVBSFContext *ctx, AVPacket *pkt, + uint8_t **data, int *size) +{ + ExtractExtradataContext *s = ctx->priv_data; uint32_t state = UINT32_MAX; int i; for (i = 0; i < pkt->size; i++) { state = (state << 8) | pkt->data[i]; - if ((is_mpeg12 && state != 0x1B3 && state != 0x1B5 && state < 0x200 && state >= 0x100) || - (!is_mpeg12 && (state == 0x1B3 || state == 0x1B6))) { + if ((state == 0x1B3 || state == 0x1B6)) { if (i > 3) { *size = i - 3; *data = av_malloc(*size + AV_INPUT_BUFFER_PADDING_SIZE); @@ -207,12 +235,12 @@ static const struct { int (*extract)(AVBSFContext *ctx, AVPacket *pkt, uint8_t **data, int *size); } extract_tab[] = { - { AV_CODEC_ID_CAVS, extract_extradata_mpeg124 }, + { AV_CODEC_ID_CAVS, extract_extradata_mpeg4 }, { AV_CODEC_ID_H264, extract_extradata_h2645 }, { AV_CODEC_ID_HEVC, extract_extradata_h2645 }, - { AV_CODEC_ID_MPEG1VIDEO, extract_extradata_mpeg124 }, - { AV_CODEC_ID_MPEG2VIDEO, extract_extradata_mpeg124 }, - { AV_CODEC_ID_MPEG4, extract_extradata_mpeg124 }, + { AV_CODEC_ID_MPEG1VIDEO, extract_extradata_mpeg12 }, + { AV_CODEC_ID_MPEG2VIDEO, extract_extradata_mpeg12 }, + { AV_CODEC_ID_MPEG4, extract_extradata_mpeg4 }, { AV_CODEC_ID_VC1, extract_extradata_vc1 }, }; From 173fdc4dea1351a8de5e04a324ad7f0fcb1563ea Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 24 Mar 2017 18:26:03 -0300 Subject: [PATCH 1308/3374] avcodec/extract_extradata_bsf: use the parsing code from vc1_split() It's a simplifaction of the same code, originally commited as b4b9a64bdb6. Reviewed-by: Michael Niedermayer Signed-off-by: James Almer --- libavcodec/extract_extradata_bsf.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/libavcodec/extract_extradata_bsf.c b/libavcodec/extract_extradata_bsf.c index d909ee6d17b86..447afb9f9a4f7 100644 --- a/libavcodec/extract_extradata_bsf.c +++ b/libavcodec/extract_extradata_bsf.c @@ -137,20 +137,16 @@ static int extract_extradata_vc1(AVBSFContext *ctx, AVPacket *pkt, uint8_t **data, int *size) { ExtractExtradataContext *s = ctx->priv_data; + const uint8_t *ptr = pkt->data, *end = pkt->data + pkt->size; uint32_t state = UINT32_MAX; int has_extradata = 0, extradata_size = 0; - int i; - for (i = 0; i < pkt->size; i++) { - state = (state << 8) | pkt->data[i]; - if (IS_MARKER(state)) { - if (state == VC1_CODE_SEQHDR || state == VC1_CODE_ENTRYPOINT) { - has_extradata = 1; - } else if (has_extradata) { - extradata_size = i - 3; - break; - } - } + while (ptr < end) { + ptr = avpriv_find_start_code(ptr, end, &state); + if (state == VC1_CODE_SEQHDR || state == VC1_CODE_ENTRYPOINT) { + has_extradata = 1; + } else if (has_extradata && IS_MARKER(state)) + extradata_size = ptr - 4 - pkt->data; } if (extradata_size) { From b53ac2a5283da595b5f5c7f685c5102dc3ed50ca Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 24 Mar 2017 18:27:37 -0300 Subject: [PATCH 1309/3374] avcodec/extract_extradata_bsf: use the parsing code from mpeg4video_split() It's a simplifaction of the same code, originally commited as 3b5ad8fbf77. Reviewed-by: Michael Niedermayer Signed-off-by: James Almer --- libavcodec/extract_extradata_bsf.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libavcodec/extract_extradata_bsf.c b/libavcodec/extract_extradata_bsf.c index 447afb9f9a4f7..e9b3791dc03a5 100644 --- a/libavcodec/extract_extradata_bsf.c +++ b/libavcodec/extract_extradata_bsf.c @@ -201,14 +201,14 @@ static int extract_extradata_mpeg4(AVBSFContext *ctx, AVPacket *pkt, uint8_t **data, int *size) { ExtractExtradataContext *s = ctx->priv_data; + const uint8_t *ptr = pkt->data, *end = pkt->data + pkt->size; uint32_t state = UINT32_MAX; - int i; - for (i = 0; i < pkt->size; i++) { - state = (state << 8) | pkt->data[i]; - if ((state == 0x1B3 || state == 0x1B6)) { - if (i > 3) { - *size = i - 3; + while (ptr < end) { + ptr = avpriv_find_start_code(ptr, end, &state); + if (state == 0x1B3 || state == 0x1B6) { + if (ptr - pkt->data > 4) { + *size = ptr - 4 - pkt->data; *data = av_malloc(*size + AV_INPUT_BUFFER_PADDING_SIZE); if (!*data) return AVERROR(ENOMEM); From a044f8df6aff511367ccd075614be00190c3c968 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 25 Mar 2017 13:50:51 -0300 Subject: [PATCH 1310/3374] ffprobe: support skip_samples packet side data information Reviewed-by: Rostislav Pehlivanov Signed-off-by: James Almer --- ffprobe.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ffprobe.c b/ffprobe.c index 4a7ec0ad3111c..ba27bce82384e 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -1806,6 +1806,11 @@ static void print_pkt_side_data(WriterContext *w, print_int("yaw", (double) spherical->yaw / (1 << 16)); print_int("pitch", (double) spherical->pitch / (1 << 16)); print_int("roll", (double) spherical->roll / (1 << 16)); + } else if (sd->type == AV_PKT_DATA_SKIP_SAMPLES && sd->size == 10) { + print_int("skip_samples", AV_RL32(sd->data)); + print_int("discard_padding", AV_RL32(sd->data + 4)); + print_int("skip_reason", AV_RL8(sd->data + 8)); + print_int("discard_reason", AV_RL8(sd->data + 9)); } writer_print_section_footer(w); } From 9dd1573423cad3ede50311fb9f5c3d8de16a1df4 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 26 Mar 2017 01:15:04 +0100 Subject: [PATCH 1311/3374] doc/bitstream_filters: Fix project name after merge Signed-off-by: Michael Niedermayer --- doc/bitstream_filters.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/bitstream_filters.texi b/doc/bitstream_filters.texi index d9d4a34779f22..947c31dae84e4 100644 --- a/doc/bitstream_filters.texi +++ b/doc/bitstream_filters.texi @@ -81,7 +81,7 @@ Extract the in-band extradata. Certain codecs allow the long-term headers (e.g. MPEG-2 sequence headers, or H.264/HEVC (VPS/)SPS/PPS) to be transmitted either "in-band" (i.e. as a part of the bitstream containing the coded frames) or "out of band" (e.g. on the -container level). This latter form is called "extradata" in Libav terminology. +container level). This latter form is called "extradata" in FFmpeg terminology. This bitstream filter detects the in-band headers and makes them available as extradata. From 73fb40dc879573a154811771cf7d5a732d969752 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 26 Mar 2017 01:38:34 +0100 Subject: [PATCH 1312/3374] avcodec/x86/idctdsp: Remove duplicate include Signed-off-by: Michael Niedermayer --- libavcodec/x86/idctdsp.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libavcodec/x86/idctdsp.h b/libavcodec/x86/idctdsp.h index e2e296ac8111e..0d0bdb5f578a3 100644 --- a/libavcodec/x86/idctdsp.h +++ b/libavcodec/x86/idctdsp.h @@ -21,7 +21,6 @@ #include #include -#include void ff_add_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, ptrdiff_t line_size); From 0ba22831e1fcc88c755190b08a9cfc235df3a9a9 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 24 Mar 2017 03:09:32 +0100 Subject: [PATCH 1313/3374] avcodec/h264idct_template: Fix multiple runtime error: signed integer overflow Fixes: 712/clusterfuzz-testcase-6647676227551232 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/h264idct_template.c | 56 +++++++++++++++++----------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/libavcodec/h264idct_template.c b/libavcodec/h264idct_template.c index 229a9ac36bcf2..e1ef68756c7de 100644 --- a/libavcodec/h264idct_template.c +++ b/libavcodec/h264idct_template.c @@ -107,34 +107,34 @@ void FUNCC(ff_h264_idct8_add)(uint8_t *_dst, int16_t *_block, int stride){ } for( i = 0; i < 8; i++ ) { - const int a0 = block[0+i*8] + block[4+i*8]; - const int a2 = block[0+i*8] - block[4+i*8]; - const int a4 = (block[2+i*8]>>1) - block[6+i*8]; - const int a6 = (block[6+i*8]>>1) + block[2+i*8]; - - const int b0 = a0 + a6; - const int b2 = a2 + a4; - const int b4 = a2 - a4; - const int b6 = a0 - a6; - - const int a1 = -block[3+i*8] + block[5+i*8] - block[7+i*8] - (block[7+i*8]>>1); - const int a3 = block[1+i*8] + block[7+i*8] - block[3+i*8] - (block[3+i*8]>>1); - const int a5 = -block[1+i*8] + block[7+i*8] + block[5+i*8] + (block[5+i*8]>>1); - const int a7 = block[3+i*8] + block[5+i*8] + block[1+i*8] + (block[1+i*8]>>1); - - const int b1 = (a7>>2) + a1; - const int b3 = a3 + (a5>>2); - const int b5 = (a3>>2) - a5; - const int b7 = a7 - (a1>>2); - - dst[i + 0*stride] = av_clip_pixel( dst[i + 0*stride] + ((b0 + b7) >> 6) ); - dst[i + 1*stride] = av_clip_pixel( dst[i + 1*stride] + ((b2 + b5) >> 6) ); - dst[i + 2*stride] = av_clip_pixel( dst[i + 2*stride] + ((b4 + b3) >> 6) ); - dst[i + 3*stride] = av_clip_pixel( dst[i + 3*stride] + ((b6 + b1) >> 6) ); - dst[i + 4*stride] = av_clip_pixel( dst[i + 4*stride] + ((b6 - b1) >> 6) ); - dst[i + 5*stride] = av_clip_pixel( dst[i + 5*stride] + ((b4 - b3) >> 6) ); - dst[i + 6*stride] = av_clip_pixel( dst[i + 6*stride] + ((b2 - b5) >> 6) ); - dst[i + 7*stride] = av_clip_pixel( dst[i + 7*stride] + ((b0 - b7) >> 6) ); + const unsigned a0 = block[0+i*8] + block[4+i*8]; + const unsigned a2 = block[0+i*8] - block[4+i*8]; + const unsigned a4 = (block[2+i*8]>>1) - block[6+i*8]; + const unsigned a6 = (block[6+i*8]>>1) + block[2+i*8]; + + const unsigned b0 = a0 + a6; + const unsigned b2 = a2 + a4; + const unsigned b4 = a2 - a4; + const unsigned b6 = a0 - a6; + + const int a1 = -(unsigned)block[3+i*8] + block[5+i*8] - block[7+i*8] - (block[7+i*8]>>1); + const int a3 = (unsigned)block[1+i*8] + block[7+i*8] - block[3+i*8] - (block[3+i*8]>>1); + const int a5 = -(unsigned)block[1+i*8] + block[7+i*8] + block[5+i*8] + (block[5+i*8]>>1); + const int a7 = (unsigned)block[3+i*8] + block[5+i*8] + block[1+i*8] + (block[1+i*8]>>1); + + const unsigned b1 = (a7>>2) + (unsigned)a1; + const unsigned b3 = (unsigned)a3 + (a5>>2); + const unsigned b5 = (a3>>2) - (unsigned)a5; + const unsigned b7 = (unsigned)a7 - (a1>>2); + + dst[i + 0*stride] = av_clip_pixel( dst[i + 0*stride] + ((int)(b0 + b7) >> 6) ); + dst[i + 1*stride] = av_clip_pixel( dst[i + 1*stride] + ((int)(b2 + b5) >> 6) ); + dst[i + 2*stride] = av_clip_pixel( dst[i + 2*stride] + ((int)(b4 + b3) >> 6) ); + dst[i + 3*stride] = av_clip_pixel( dst[i + 3*stride] + ((int)(b6 + b1) >> 6) ); + dst[i + 4*stride] = av_clip_pixel( dst[i + 4*stride] + ((int)(b6 - b1) >> 6) ); + dst[i + 5*stride] = av_clip_pixel( dst[i + 5*stride] + ((int)(b4 - b3) >> 6) ); + dst[i + 6*stride] = av_clip_pixel( dst[i + 6*stride] + ((int)(b2 - b5) >> 6) ); + dst[i + 7*stride] = av_clip_pixel( dst[i + 7*stride] + ((int)(b0 - b7) >> 6) ); } memset(block, 0, 64 * sizeof(dctcoef)); From eaf6f10f1b5c26cf5264654b48f8114ff949cbad Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 26 Mar 2017 20:34:47 +0200 Subject: [PATCH 1314/3374] avfilter/vf_signature: Replace uncommon spelling of seperate Signed-off-by: Michael Niedermayer --- libavfilter/vf_signature.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_signature.c b/libavfilter/vf_signature.c index 57cb96b6c4185..06b1b910d4d85 100644 --- a/libavfilter/vf_signature.c +++ b/libavfilter/vf_signature.c @@ -71,7 +71,7 @@ AVFILTER_DEFINE_CLASS(signature); static int query_formats(AVFilterContext *ctx) { - /* all formats with a seperate gray value */ + /* all formats with a separate gray value */ static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, From a94972b2b2e6b0370b69c664cacf4397c8bf33e9 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Wed, 22 Mar 2017 21:19:11 +0000 Subject: [PATCH 1315/3374] ffmpeg: Remove hw_device_ctx output filter reinit hack This was skipped in c17563c5d3c974a69709ebae0171534763b3051c because it depended on the filter setup merge, but was forgotten after that actually happened. Fixes hwaccel fate for stream size change tests. --- ffmpeg_filter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c index 5cc640d75dbc0..219e473f692be 100644 --- a/ffmpeg_filter.c +++ b/ffmpeg_filter.c @@ -460,7 +460,7 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, if (ret < 0) return ret; - if (!hw_device_ctx && (ofilter->width || ofilter->height)) { + if (ofilter->width || ofilter->height) { char args[255]; AVFilterContext *filter; AVDictionaryEntry *e = NULL; From d65b59550b4d7eb526bbd407df74f030fad5c00b Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 26 Mar 2017 21:17:54 +0200 Subject: [PATCH 1316/3374] avcodec/avcodec: Correct and make consistent AVERROR() in comments Reviewed-by: "Ronald S. Bultje" Signed-off-by: Michael Niedermayer --- libavcodec/avcodec.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index af327ff9ad2cc..4f3303366fe9c 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -153,7 +153,7 @@ * Unlike with the old video decoding API, multiple frames might result from * a packet. For audio, splitting the input packet into frames by partially * decoding packets becomes transparent to the API user. You never need to - * feed an AVPacket to the API twice (unless it is rejected with EAGAIN - then + * feed an AVPacket to the API twice (unless it is rejected with AVERROR(EAGAIN) - then * no data was read from the packet). * Additionally, sending a flush/draining packet is required only once. * - avcodec_encode_video2()/avcodec_encode_audio2(): @@ -169,10 +169,10 @@ * Some codecs might require using the new API; using the old API will return * an error when calling it. All codecs support the new API. * - * A codec is not allowed to return EAGAIN for both sending and receiving. This + * A codec is not allowed to return AVERROR(EAGAIN) for both sending and receiving. This * would be an invalid state, which could put the codec user into an endless * loop. The API has no concept of time either: it cannot happen that trying to - * do avcodec_send_packet() results in EAGAIN, but a repeated call 1 second + * do avcodec_send_packet() results in AVERROR(EAGAIN), but a repeated call 1 second * later accepts the packet (with no other receive/flush API calls involved). * The API is a strict state machine, and the passage of time is not supposed * to influence it. Some timing-dependent behavior might still be deemed @@ -181,7 +181,7 @@ * avoided that the current state is "unstable" and can "flip-flop" between * the send/receive APIs allowing progress. For example, it's not allowed that * the codec randomly decides that it actually wants to consume a packet now - * instead of returning a frame, after it just returned EAGAIN on an + * instead of returning a frame, after it just returned AVERROR(EAGAIN) on an * avcodec_send_packet() call. * @} */ From b12693facf991f343cdf310690f59f69143b256f Mon Sep 17 00:00:00 2001 From: Kyle Swanson Date: Sun, 26 Mar 2017 13:48:28 -0500 Subject: [PATCH 1317/3374] libavcodec/opusenc: use correct format specifiers Squelches the following compiler warnings: libavcodec/opusenc.c:1051:16: warning: format specifies type 'long' but the argument has type 'long long' [-Wformat] avctx->bit_rate/1000, clipped_rate/1000); ^~~~~~~~~~~~~~~~~~~~ libavcodec/opusenc.c:1051:38: warning: format specifies type 'long' but the argument has type 'long long' [-Wformat] avctx->bit_rate/1000, clipped_rate/1000); ^~~~~~~~~~~~~~~~~ --- libavcodec/opusenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/opusenc.c b/libavcodec/opusenc.c index 56368dbb914c7..cecc8f22ab3ba 100644 --- a/libavcodec/opusenc.c +++ b/libavcodec/opusenc.c @@ -1047,7 +1047,7 @@ static av_cold int opus_encode_init(AVCodecContext *avctx) avctx->bit_rate = coupled*(96000) + (s->channels - coupled*2)*(48000); } else if (avctx->bit_rate < 6000 || avctx->bit_rate > 255000 * s->channels) { int64_t clipped_rate = av_clip(avctx->bit_rate, 6000, 255000 * s->channels); - av_log(avctx, AV_LOG_ERROR, "Unsupported bitrate %li kbps, clipping to %li kbps\n", + av_log(avctx, AV_LOG_ERROR, "Unsupported bitrate %"PRId64" kbps, clipping to %"PRId64" kbps\n", avctx->bit_rate/1000, clipped_rate/1000); avctx->bit_rate = clipped_rate; } From ddef3d902f0e4cbd6be6b3e5df7ec158ce51488b Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 21 Mar 2017 08:02:58 +0100 Subject: [PATCH 1318/3374] avformat, ffmpeg: deprecate old rotation API The old "API" that signaled rotation as a metadata value has been replaced by DISPLAYMATRIX side data quite a while ago. There is no reason to make muxers/demuxers/API users support both. In addition, the metadata API is dangerous, as user tags could "leak" into it, creating unintended features or bugs. ffmpeg CLI has to be updated to use the new API. In particular, we must not allow to leak the "rotate" tag into the muxer. Some muxers will catch this properly (like mov), but others (like mkv) can add it as generic tag. Note applications, which use libavformat and assume the old rotate API, will interpret such "rotate" user tags as rotate metadata (which it is not), and incorrectly rotate the video. The ffmpeg/ffplay tools drop the use of the old API for muxing and demuxing, as all muxers/demuxers support the new API. This will mean that the tools will not mistakenly interpret per-track "rotate" user tags as rotate metadata. It will _not_ be treated as regression. Unfortunately, hacks have been added, that allow the user to override rotation by setting metadata explicitly, e.g. via -metadata:s:v:0 rotate=0 See references to trac #4560. fate-filter-meta-4560-rotate0 tests this. It's easier to adjust the hack for supporting it than arguing for its removal, so ffmpeg CLI now explicitly catches this case, and essentially replaces the "rotate" value with a display matrix side data. (It would be easier for both user and implementation to create an explicit option for rotation.) When the code under FF_API_OLD_ROTATE_API is disabled, one FATE reference file has to be updated (because "rotate" is not exported anymore). Tested-by: Michael Niedermayer Reviewed-by: Michael Niedermayer --- cmdutils.c | 10 +--------- doc/APIchanges | 8 ++++++++ ffmpeg.c | 41 ++++++++++++++++++++++++++++++++++++----- ffmpeg.h | 1 + ffmpeg_opt.c | 12 ++++++++---- libavformat/mov.c | 2 ++ libavformat/movenc.c | 4 ++++ libavformat/version.h | 5 ++++- 8 files changed, 64 insertions(+), 19 deletions(-) diff --git a/cmdutils.c b/cmdutils.c index 2373dbf841705..3d428f3eea8a9 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -2097,18 +2097,10 @@ void *grow_array(void *array, int elem_size, int *size, int new_size) double get_rotation(AVStream *st) { - AVDictionaryEntry *rotate_tag = av_dict_get(st->metadata, "rotate", NULL, 0); uint8_t* displaymatrix = av_stream_get_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, NULL); double theta = 0; - - if (rotate_tag && *rotate_tag->value && strcmp(rotate_tag->value, "0")) { - char *tail; - theta = av_strtod(rotate_tag->value, &tail); - if (*tail) - theta = 0; - } - if (displaymatrix && !theta) + if (displaymatrix) theta = -av_display_rotation_get((int32_t*) displaymatrix); theta -= 360*floor(theta/360 + 0.9/360); diff --git a/doc/APIchanges b/doc/APIchanges index 6aaa9adcebd75..2274543024b7c 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,14 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-03-xx - xxxxxxx - lavf 57.68.100 - avformat.h + Deprecate that demuxers export the stream rotation angle in AVStream.metadata + (via an entry named "rotate"). Use av_stream_get_side_data() with + AV_PKT_DATA_DISPLAYMATRIX instead, and read the rotation angle with + av_display_rotation_get(). The same is done for muxing. Instead of adding a + "rotate" entry to AVStream.metadata, AV_PKT_DATA_DISPLAYMATRIX side data has + to be added to the AVStream. + 2017-03-xx - xxxxxxx - lavc 57.85.101 - avcodec.h vdpau hardware accelerated decoding now supports the new hwaccel API, which can create the decoder context and allocate hardware frame automatically. diff --git a/ffmpeg.c b/ffmpeg.c index 62e7d8222df88..3aa1e7854da51 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -50,6 +50,7 @@ #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" #include "libavutil/dict.h" +#include "libavutil/display.h" #include "libavutil/mathematics.h" #include "libavutil/pixdesc.h" #include "libavutil/avstring.h" @@ -3067,9 +3068,6 @@ static int init_output_stream_streamcopy(OutputStream *ost) const AVPacketSideData *sd_src = &ist->st->side_data[i]; AVPacketSideData *sd_dst = &ost->st->side_data[ost->st->nb_side_data]; - if (ost->rotate_overridden && sd_src->type == AV_PKT_DATA_DISPLAYMATRIX) - continue; - sd_dst->data = av_malloc(sd_src->size); if (!sd_dst->data) return AVERROR(ENOMEM); @@ -3080,6 +3078,13 @@ static int init_output_stream_streamcopy(OutputStream *ost) } } + if (ost->rotate_overridden) { + uint8_t *sd = av_stream_new_side_data(ost->st, AV_PKT_DATA_DISPLAYMATRIX, + sizeof(int32_t) * 9); + if (sd) + av_display_rotation_set((int32_t *)sd, -ost->rotate_override_value); + } + ost->parser = av_parser_init(par_dst->codec_id); ost->parser_avctx = avcodec_alloc_context3(NULL); if (!ost->parser_avctx) @@ -3233,6 +3238,11 @@ static int init_output_stream_encode(OutputStream *ost) set_encoder_id(output_files[ost->file_index], ost); + // Muxers use AV_PKT_DATA_DISPLAYMATRIX to signal rotation. On the other + // hand, the legacy API makes demuxers set "rotate" metadata entries, + // which have to be filtered out to prevent leaking them to output files. + av_dict_set(&ost->st->metadata, "rotate", NULL, 0); + if (ist) { ost->st->disposition = ist->st->disposition; @@ -3470,6 +3480,26 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len) } } + /* + * Add global input side data. For now this is naive, and copies it + * from the input stream's global side data. All side data should + * really be funneled over AVFrame and libavfilter, then added back to + * packet side data, and then potentially using the first packet for + * global side data. + */ + if (ist) { + int i; + for (i = 0; i < ist->st->nb_side_data; i++) { + AVPacketSideData *sd = &ist->st->side_data[i]; + uint8_t *dst = av_stream_new_side_data(ost->st, sd->type, sd->size); + if (!dst) + return AVERROR(ENOMEM); + memcpy(dst, sd->data, sd->size); + if (ist->autorotate && sd->type == AV_PKT_DATA_DISPLAYMATRIX) + av_display_rotation_set((uint32_t *)dst, 0); + } + } + // copy timebase while removing common factors if (ost->st->time_base.num <= 0 || ost->st->time_base.den <= 0) ost->st->time_base = av_add_q(ost->enc_ctx->time_base, (AVRational){0, 1}); @@ -4266,9 +4296,10 @@ static int process_input(int file_index) AVPacketSideData *src_sd = &ist->st->side_data[i]; uint8_t *dst_data; - if (av_packet_get_side_data(&pkt, src_sd->type, NULL)) + if (src_sd->type == AV_PKT_DATA_DISPLAYMATRIX) continue; - if (ist->autorotate && src_sd->type == AV_PKT_DATA_DISPLAYMATRIX) + + if (av_packet_get_side_data(&pkt, src_sd->type, NULL)) continue; dst_data = av_packet_new_side_data(&pkt, src_sd->type, src_sd->size); diff --git a/ffmpeg.h b/ffmpeg.h index c3ed6ced784e8..4d0456c1fbe1e 100644 --- a/ffmpeg.h +++ b/ffmpeg.h @@ -475,6 +475,7 @@ typedef struct OutputStream { int force_fps; int top_field_first; int rotate_overridden; + double rotate_override_value; AVRational frame_aspect_ratio; diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c index fc885dfac3c0c..ffe1abdb38c0e 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -2549,8 +2549,6 @@ static int open_output_file(OptionsContext *o, const char *filename) av_dict_copy(&output_streams[i]->st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE); if (!output_streams[i]->stream_copy) { av_dict_set(&output_streams[i]->st->metadata, "encoder", NULL, 0); - if (ist->autorotate) - av_dict_set(&output_streams[i]->st->metadata, "rotate", NULL, 0); } } @@ -2640,9 +2638,15 @@ static int open_output_file(OptionsContext *o, const char *filename) for (j = 0; j < oc->nb_streams; j++) { ost = output_streams[nb_output_streams - oc->nb_streams + j]; if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) { - av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0); if (!strcmp(o->metadata[i].u.str, "rotate")) { - ost->rotate_overridden = 1; + char *tail; + double theta = av_strtod(val, &tail); + if (!*tail) { + ost->rotate_overridden = 1; + ost->rotate_override_value = theta; + } + } else { + av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0); } } else if (ret < 0) exit_program(1); diff --git a/libavformat/mov.c b/libavformat/mov.c index 2fce5a68352ae..4034ca5e046a5 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -4027,6 +4027,7 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) for (j = 0; j < 3; j++) sc->display_matrix[i * 3 + j] = res_display_matrix[i][j]; +#if FF_API_OLD_ROTATE_API rotate = av_display_rotation_get(sc->display_matrix); if (!isnan(rotate)) { char rotate_buf[64]; @@ -4036,6 +4037,7 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate); av_dict_set(&st->metadata, "rotate", rotate_buf, 0); } +#endif } // transform the display width/height according to the matrix diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 11b26708aec42..3b4e3b519c202 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -2496,19 +2496,23 @@ static int mov_write_tkhd_tag(AVIOContext *pb, MOVMuxContext *mov, avio_wb16(pb, 0); /* reserved */ /* Matrix structure */ +#if FF_API_OLD_ROTATE_API if (st && st->metadata) { AVDictionaryEntry *rot = av_dict_get(st->metadata, "rotate", NULL, 0); rotation = (rot && rot->value) ? atoi(rot->value) : 0; } +#endif if (display_matrix) { for (i = 0; i < 9; i++) avio_wb32(pb, display_matrix[i]); +#if FF_API_OLD_ROTATE_API } else if (rotation == 90) { write_matrix(pb, 0, 1, -1, 0, track->par->height, 0); } else if (rotation == 180) { write_matrix(pb, -1, 0, 0, -1, track->par->width, track->par->height); } else if (rotation == 270) { write_matrix(pb, 0, -1, 1, 0, 0, track->par->width); +#endif } else { write_matrix(pb, 1, 0, 0, 1, 0, 0); } diff --git a/libavformat/version.h b/libavformat/version.h index dd4c680803991..ba2b912908c54 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ // 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 57 -#define LIBAVFORMAT_VERSION_MINOR 67 +#define LIBAVFORMAT_VERSION_MINOR 68 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ @@ -94,6 +94,9 @@ #ifndef FF_API_LAVF_KEEPSIDE_FLAG #define FF_API_LAVF_KEEPSIDE_FLAG (LIBAVFORMAT_VERSION_MAJOR < 58) #endif +#ifndef FF_API_OLD_ROTATE_API +#define FF_API_OLD_ROTATE_API (LIBAVFORMAT_VERSION_MAJOR < 58) +#endif #ifndef FF_API_R_FRAME_RATE From 9e703ae30f911d4df3f80647266e65d3b2dcf30d Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 23 Mar 2017 13:18:16 +0100 Subject: [PATCH 1319/3374] pthread_frame: do not attempt to unlock a mutex on the wrong thread async_mutex has is used in a very strange but intentional way: it is locked by default, and unlocked only in regions that can be run concurrently. If the user was calling API functions to the same context from different threads (in a safe way), this could unintentionally unlock the mutex on a different thread than the previous lock operation. It's not allowed by the pthread API. Fix this by emulating a binary semaphore using a mutex and condition variable. (Posix semaphores are not available on all platforms.) Tested-by: Michael Niedermayer Reviewed-by: Michael Niedermayer --- libavcodec/pthread_frame.c | 41 ++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 6768402ed887f..6620a8d324462 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -123,6 +123,8 @@ typedef struct FrameThreadContext { */ pthread_mutex_t hwaccel_mutex; pthread_mutex_t async_mutex; + pthread_cond_t async_cond; + int async_lock; int next_decoding; ///< The next context to submit a packet to. int next_finished; ///< The next context to return output from. @@ -136,6 +138,24 @@ typedef struct FrameThreadContext { #define THREAD_SAFE_CALLBACKS(avctx) \ ((avctx)->thread_safe_callbacks || (avctx)->get_buffer2 == avcodec_default_get_buffer2) +static void async_lock(FrameThreadContext *fctx) +{ + pthread_mutex_lock(&fctx->async_mutex); + while (fctx->async_lock) + pthread_cond_wait(&fctx->async_cond, &fctx->async_mutex); + fctx->async_lock = 1; + pthread_mutex_unlock(&fctx->async_mutex); +} + +static void async_unlock(FrameThreadContext *fctx) +{ + pthread_mutex_lock(&fctx->async_mutex); + av_assert0(fctx->async_lock); + fctx->async_lock = 0; + pthread_cond_broadcast(&fctx->async_cond); + pthread_mutex_unlock(&fctx->async_mutex); +} + /** * Codec worker thread. * @@ -195,7 +215,8 @@ static attribute_align_arg void *frame_worker_thread(void *arg) if (p->async_serializing) { p->async_serializing = 0; - pthread_mutex_unlock(&p->parent->async_mutex); + + async_unlock(p->parent); } pthread_mutex_lock(&p->progress_mutex); @@ -451,7 +472,7 @@ int ff_thread_decode_frame(AVCodecContext *avctx, /* release the async lock, permitting blocked hwaccel threads to * go forward while we are in this function */ - pthread_mutex_unlock(&fctx->async_mutex); + async_unlock(fctx); /* * Submit a packet to the next decoding thread. @@ -532,7 +553,7 @@ int ff_thread_decode_frame(AVCodecContext *avctx, /* return the size of the consumed packet if no error occurred */ ret = (p->result >= 0) ? avpkt->size : p->result; finish: - pthread_mutex_lock(&fctx->async_mutex); + async_lock(fctx); if (err < 0) return err; return ret; @@ -594,7 +615,8 @@ void ff_thread_finish_setup(AVCodecContext *avctx) { if (avctx->hwaccel && !(avctx->hwaccel->caps_internal & HWACCEL_CAP_ASYNC_SAFE)) { p->async_serializing = 1; - pthread_mutex_lock(&p->parent->async_mutex); + + async_lock(p->parent); } pthread_mutex_lock(&p->progress_mutex); @@ -613,7 +635,7 @@ static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count { int i; - pthread_mutex_unlock(&fctx->async_mutex); + async_unlock(fctx); for (i = 0; i < thread_count; i++) { PerThreadContext *p = &fctx->threads[i]; @@ -627,7 +649,7 @@ static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count p->got_frame = 0; } - pthread_mutex_lock(&fctx->async_mutex); + async_lock(fctx); } void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) @@ -691,9 +713,8 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) av_freep(&fctx->threads); pthread_mutex_destroy(&fctx->buffer_mutex); pthread_mutex_destroy(&fctx->hwaccel_mutex); - - pthread_mutex_unlock(&fctx->async_mutex); pthread_mutex_destroy(&fctx->async_mutex); + pthread_cond_destroy(&fctx->async_cond); av_freep(&avctx->internal->thread_ctx); @@ -742,10 +763,10 @@ int ff_frame_thread_init(AVCodecContext *avctx) pthread_mutex_init(&fctx->buffer_mutex, NULL); pthread_mutex_init(&fctx->hwaccel_mutex, NULL); - pthread_mutex_init(&fctx->async_mutex, NULL); - pthread_mutex_lock(&fctx->async_mutex); + pthread_cond_init(&fctx->async_cond, NULL); + fctx->async_lock = 1; fctx->delaying = 1; for (i = 0; i < thread_count; i++) { From d7896e9b4228e5b7ffc7ef0d0f1cf145f518c819 Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 27 Mar 2017 13:06:56 +0200 Subject: [PATCH 1320/3374] pthread_frame: fix uninitialized variable read Could lead to random behavior. This possibly happened due to commit 32a5b631267. This should/could probably be simplified, but for no apply a minimal fix to quell the errors. Tested-by: Michael Niedermayer Reviewed-by: Michael Niedermayer --- libavcodec/pthread_frame.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 6620a8d324462..b618be0bf538e 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -468,7 +468,7 @@ int ff_thread_decode_frame(AVCodecContext *avctx, FrameThreadContext *fctx = avctx->internal->thread_ctx; int finished = fctx->next_finished; PerThreadContext *p; - int err, ret; + int err, ret = 0; /* release the async lock, permitting blocked hwaccel threads to * go forward while we are in this function */ From a8fe8d6b4a35c95aa94fccde5f001041278d197c Mon Sep 17 00:00:00 2001 From: Rostislav Pehlivanov Date: Mon, 6 Mar 2017 02:46:51 +0000 Subject: [PATCH 1321/3374] lavfi: remove af_asynts filter Long overdue for removal, af_aresample should be used instead. Signed-off-by: Rostislav Pehlivanov --- Changelog | 1 + configure | 2 - doc/filters.texi | 33 ---- libavfilter/Makefile | 1 - libavfilter/af_asyncts.c | 323 ------------------------------------ libavfilter/allfilters.c | 1 - libavfilter/version.h | 2 +- tests/fate/filter-audio.mak | 6 - 8 files changed, 2 insertions(+), 367 deletions(-) delete mode 100644 libavfilter/af_asyncts.c diff --git a/Changelog b/Changelog index 5bcf8f180e799..406a5afd27aee 100644 --- a/Changelog +++ b/Changelog @@ -2,6 +2,7 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. version : +- Removed asyncts filter (use af_aresample instead) - CrystalHD decoder moved to new decode API - add internal ebur128 library, remove external libebur128 dependency - Pro-MPEG CoP #3-R2 FEC protocol diff --git a/configure b/configure index 9cc7e7d4c159c..dc968bcfd836d 100755 --- a/configure +++ b/configure @@ -3076,7 +3076,6 @@ afftfilt_filter_select="fft" amovie_filter_deps="avcodec avformat" aresample_filter_deps="swresample" ass_filter_deps="libass" -asyncts_filter_deps="avresample" atempo_filter_deps="avcodec" atempo_filter_select="rdft" azmq_filter_deps="libzmq" @@ -6459,7 +6458,6 @@ enabled zlib && add_cppflags -DZLIB_CONST enabled afftfilt_filter && prepend avfilter_deps "avcodec" enabled amovie_filter && prepend avfilter_deps "avformat avcodec" enabled aresample_filter && prepend avfilter_deps "swresample" -enabled asyncts_filter && prepend avfilter_deps "avresample" enabled atempo_filter && prepend avfilter_deps "avcodec" enabled cover_rect_filter && prepend avfilter_deps "avformat avcodec" enabled ebur128_filter && enabled swresample && prepend avfilter_deps "swresample" diff --git a/doc/filters.texi b/doc/filters.texi index b62952af3957d..8e5e21f9eda97 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -1642,39 +1642,6 @@ Number of occasions (not the number of samples) that the signal attained either Overall bit depth of audio. Number of bits used for each sample. @end table -@section asyncts - -Synchronize audio data with timestamps by squeezing/stretching it and/or -dropping samples/adding silence when needed. - -This filter is not built by default, please use @ref{aresample} to do squeezing/stretching. - -It accepts the following parameters: -@table @option - -@item compensate -Enable stretching/squeezing the data to make it match the timestamps. Disabled -by default. When disabled, time gaps are covered with silence. - -@item min_delta -The minimum difference between timestamps and audio data (in seconds) to trigger -adding/dropping samples. The default value is 0.1. If you get an imperfect -sync with this filter, try setting this parameter to 0. - -@item max_comp -The maximum compensation in samples per second. Only relevant with compensate=1. -The default value is 500. - -@item first_pts -Assume that the first PTS should be this value. The time base is 1 / sample -rate. This allows for padding/trimming at the start of the stream. By default, -no assumption is made about the first frame's expected PTS, so no padding or -trimming is done. For example, this could be set to 0 to pad the beginning with -silence if an audio stream starts after the video stream or to trim any samples -with a negative PTS due to encoder delay. - -@end table - @section atempo Adjust audio tempo. diff --git a/libavfilter/Makefile b/libavfilter/Makefile index a48ca0ab45328..9c15ed62d2b69 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -67,7 +67,6 @@ OBJS-$(CONFIG_ASIDEDATA_FILTER) += f_sidedata.o OBJS-$(CONFIG_ASPLIT_FILTER) += split.o OBJS-$(CONFIG_ASTATS_FILTER) += af_astats.o OBJS-$(CONFIG_ASTREAMSELECT_FILTER) += f_streamselect.o -OBJS-$(CONFIG_ASYNCTS_FILTER) += af_asyncts.o OBJS-$(CONFIG_ATEMPO_FILTER) += af_atempo.o OBJS-$(CONFIG_ATRIM_FILTER) += trim.o OBJS-$(CONFIG_AZMQ_FILTER) += f_zmq.o diff --git a/libavfilter/af_asyncts.c b/libavfilter/af_asyncts.c deleted file mode 100644 index a33e0dd67e565..0000000000000 --- a/libavfilter/af_asyncts.c +++ /dev/null @@ -1,323 +0,0 @@ -/* - * 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 - -#include "libavresample/avresample.h" -#include "libavutil/attributes.h" -#include "libavutil/audio_fifo.h" -#include "libavutil/common.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "libavutil/samplefmt.h" - -#include "audio.h" -#include "avfilter.h" -#include "internal.h" - -typedef struct ASyncContext { - const AVClass *class; - - AVAudioResampleContext *avr; - int64_t pts; ///< timestamp in samples of the first sample in fifo - int min_delta; ///< pad/trim min threshold in samples - int first_frame; ///< 1 until filter_frame() has processed at least 1 frame with a pts != AV_NOPTS_VALUE - int64_t first_pts; ///< user-specified first expected pts, in samples - int comp; ///< current resample compensation - - /* options */ - int resample; - float min_delta_sec; - int max_comp; - - /* set by filter_frame() to signal an output frame to request_frame() */ - int got_output; -} ASyncContext; - -#define OFFSET(x) offsetof(ASyncContext, x) -#define A AV_OPT_FLAG_AUDIO_PARAM -#define F AV_OPT_FLAG_FILTERING_PARAM -static const AVOption asyncts_options[] = { - { "compensate", "Stretch/squeeze the data to make it match the timestamps", OFFSET(resample), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, A|F }, - { "min_delta", "Minimum difference between timestamps and audio data " - "(in seconds) to trigger padding/trimmin the data.", OFFSET(min_delta_sec), AV_OPT_TYPE_FLOAT, { .dbl = 0.1 }, 0, INT_MAX, A|F }, - { "max_comp", "Maximum compensation in samples per second.", OFFSET(max_comp), AV_OPT_TYPE_INT, { .i64 = 500 }, 0, INT_MAX, A|F }, - { "first_pts", "Assume the first pts should be this value.", OFFSET(first_pts), AV_OPT_TYPE_INT64, { .i64 = AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, A|F }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(asyncts); - -static av_cold int init(AVFilterContext *ctx) -{ - ASyncContext *s = ctx->priv; - - s->pts = AV_NOPTS_VALUE; - s->first_frame = 1; - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - ASyncContext *s = ctx->priv; - - if (s->avr) { - avresample_close(s->avr); - avresample_free(&s->avr); - } -} - -static int config_props(AVFilterLink *link) -{ - ASyncContext *s = link->src->priv; - int ret; - - s->min_delta = s->min_delta_sec * link->sample_rate; - link->time_base = (AVRational){1, link->sample_rate}; - - s->avr = avresample_alloc_context(); - if (!s->avr) - return AVERROR(ENOMEM); - - av_opt_set_int(s->avr, "in_channel_layout", link->channel_layout, 0); - av_opt_set_int(s->avr, "out_channel_layout", link->channel_layout, 0); - av_opt_set_int(s->avr, "in_sample_fmt", link->format, 0); - av_opt_set_int(s->avr, "out_sample_fmt", link->format, 0); - av_opt_set_int(s->avr, "in_sample_rate", link->sample_rate, 0); - av_opt_set_int(s->avr, "out_sample_rate", link->sample_rate, 0); - - if (s->resample) - av_opt_set_int(s->avr, "force_resampling", 1, 0); - - if ((ret = avresample_open(s->avr)) < 0) - return ret; - - return 0; -} - -/* get amount of data currently buffered, in samples */ -static int64_t get_delay(ASyncContext *s) -{ - return avresample_available(s->avr) + avresample_get_delay(s->avr); -} - -static void handle_trimming(AVFilterContext *ctx) -{ - ASyncContext *s = ctx->priv; - - if (s->pts < s->first_pts) { - int delta = FFMIN(s->first_pts - s->pts, avresample_available(s->avr)); - av_log(ctx, AV_LOG_VERBOSE, "Trimming %d samples from start\n", - delta); - avresample_read(s->avr, NULL, delta); - s->pts += delta; - } else if (s->first_frame) - s->pts = s->first_pts; -} - -static int request_frame(AVFilterLink *link) -{ - AVFilterContext *ctx = link->src; - ASyncContext *s = ctx->priv; - int ret = 0; - int nb_samples; - - s->got_output = 0; - ret = ff_request_frame(ctx->inputs[0]); - - /* flush the fifo */ - if (ret == AVERROR_EOF) { - if (s->first_pts != AV_NOPTS_VALUE) - handle_trimming(ctx); - - if (nb_samples = get_delay(s)) { - AVFrame *buf = ff_get_audio_buffer(link, nb_samples); - if (!buf) - return AVERROR(ENOMEM); - ret = avresample_convert(s->avr, buf->extended_data, - buf->linesize[0], nb_samples, NULL, 0, 0); - if (ret <= 0) { - av_frame_free(&buf); - return (ret < 0) ? ret : AVERROR_EOF; - } - - buf->pts = s->pts; - return ff_filter_frame(link, buf); - } - } - - return ret; -} - -static int write_to_fifo(ASyncContext *s, AVFrame *buf) -{ - int ret = avresample_convert(s->avr, NULL, 0, 0, buf->extended_data, - buf->linesize[0], buf->nb_samples); - av_frame_free(&buf); - return ret; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) -{ - AVFilterContext *ctx = inlink->dst; - ASyncContext *s = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - int nb_channels = av_get_channel_layout_nb_channels(buf->channel_layout); - int64_t pts = (buf->pts == AV_NOPTS_VALUE) ? buf->pts : - av_rescale_q(buf->pts, inlink->time_base, outlink->time_base); - int out_size, ret; - int64_t delta; - int64_t new_pts; - - /* buffer data until we get the next timestamp */ - if (s->pts == AV_NOPTS_VALUE || pts == AV_NOPTS_VALUE) { - if (pts != AV_NOPTS_VALUE) { - s->pts = pts - get_delay(s); - } - return write_to_fifo(s, buf); - } - - if (s->first_pts != AV_NOPTS_VALUE) { - handle_trimming(ctx); - if (!avresample_available(s->avr)) - return write_to_fifo(s, buf); - } - - /* when we have two timestamps, compute how many samples would we have - * to add/remove to get proper sync between data and timestamps */ - delta = pts - s->pts - get_delay(s); - out_size = avresample_available(s->avr); - - if (llabs(delta) > s->min_delta || - (s->first_frame && delta && s->first_pts != AV_NOPTS_VALUE)) { - av_log(ctx, AV_LOG_VERBOSE, "Discontinuity - %"PRId64" samples.\n", delta); - out_size = av_clipl_int32((int64_t)out_size + delta); - } else { - if (s->resample) { - // adjust the compensation if delta is non-zero - int delay = get_delay(s); - int comp = s->comp + av_clip(delta * inlink->sample_rate / delay, - -s->max_comp, s->max_comp); - if (comp != s->comp) { - av_log(ctx, AV_LOG_VERBOSE, "Compensating %d samples per second.\n", comp); - if (avresample_set_compensation(s->avr, comp, inlink->sample_rate) == 0) { - s->comp = comp; - } - } - } - // adjust PTS to avoid monotonicity errors with input PTS jitter - pts -= delta; - delta = 0; - } - - if (out_size > 0) { - AVFrame *buf_out = ff_get_audio_buffer(outlink, out_size); - if (!buf_out) { - ret = AVERROR(ENOMEM); - goto fail; - } - - if (s->first_frame && delta > 0) { - int planar = av_sample_fmt_is_planar(buf_out->format); - int planes = planar ? nb_channels : 1; - int block_size = av_get_bytes_per_sample(buf_out->format) * - (planar ? 1 : nb_channels); - - int ch; - - av_samples_set_silence(buf_out->extended_data, 0, delta, - nb_channels, buf->format); - - for (ch = 0; ch < planes; ch++) - buf_out->extended_data[ch] += delta * block_size; - - avresample_read(s->avr, buf_out->extended_data, out_size); - - for (ch = 0; ch < planes; ch++) - buf_out->extended_data[ch] -= delta * block_size; - } else { - avresample_read(s->avr, buf_out->extended_data, out_size); - - if (delta > 0) { - av_samples_set_silence(buf_out->extended_data, out_size - delta, - delta, nb_channels, buf->format); - } - } - buf_out->pts = s->pts; - ret = ff_filter_frame(outlink, buf_out); - if (ret < 0) - goto fail; - s->got_output = 1; - } else if (avresample_available(s->avr)) { - av_log(ctx, AV_LOG_WARNING, "Non-monotonous timestamps, dropping " - "whole buffer.\n"); - } - - /* drain any remaining buffered data */ - avresample_read(s->avr, NULL, avresample_available(s->avr)); - - new_pts = pts - avresample_get_delay(s->avr); - /* check for s->pts monotonicity */ - if (new_pts > s->pts) { - s->pts = new_pts; - ret = avresample_convert(s->avr, NULL, 0, 0, buf->extended_data, - buf->linesize[0], buf->nb_samples); - } else { - av_log(ctx, AV_LOG_WARNING, "Non-monotonous timestamps, dropping " - "whole buffer.\n"); - ret = 0; - } - - s->first_frame = 0; -fail: - av_frame_free(&buf); - - return ret; -} - -static const AVFilterPad avfilter_af_asyncts_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame - }, - { NULL } -}; - -static const AVFilterPad avfilter_af_asyncts_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .config_props = config_props, - .request_frame = request_frame - }, - { NULL } -}; - -AVFilter ff_af_asyncts = { - .name = "asyncts", - .description = NULL_IF_CONFIG_SMALL("Sync audio data to timestamps."), - .init = init, - .uninit = uninit, - .priv_size = sizeof(ASyncContext), - .priv_class = &asyncts_class, - .query_formats = ff_query_formats_all_layouts, - .inputs = avfilter_af_asyncts_inputs, - .outputs = avfilter_af_asyncts_outputs, -}; diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 93271fb2c4a8d..64b634e8f33c3 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -79,7 +79,6 @@ static void register_all(void) REGISTER_FILTER(ASPLIT, asplit, af); REGISTER_FILTER(ASTATS, astats, af); REGISTER_FILTER(ASTREAMSELECT, astreamselect, af); - REGISTER_FILTER(ASYNCTS, asyncts, af); REGISTER_FILTER(ATEMPO, atempo, af); REGISTER_FILTER(ATRIM, atrim, af); REGISTER_FILTER(AZMQ, azmq, af); diff --git a/libavfilter/version.h b/libavfilter/version.h index a61ca32712351..a798e911b0207 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -31,7 +31,7 @@ #define LIBAVFILTER_VERSION_MAJOR 6 #define LIBAVFILTER_VERSION_MINOR 78 -#define LIBAVFILTER_VERSION_MICRO 100 +#define LIBAVFILTER_VERSION_MICRO 101 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ LIBAVFILTER_VERSION_MINOR, \ diff --git a/tests/fate/filter-audio.mak b/tests/fate/filter-audio.mak index 0ec6758fb2aaa..5d15b31e0b245 100644 --- a/tests/fate/filter-audio.mak +++ b/tests/fate/filter-audio.mak @@ -187,12 +187,6 @@ $(FATE_AMIX): SRC1 = $(TARGET_PATH)/tests/data/asynth-44100-2-2.wav $(FATE_AMIX): CMP = oneoff $(FATE_AMIX): CMP_UNIT = f32 -FATE_AFILTER_SAMPLES-$(call FILTERDEMDECMUX, ASYNCTS, FLV, NELLYMOSER, PCM_S16LE) += fate-filter-asyncts -fate-filter-asyncts: SRC = $(TARGET_SAMPLES)/nellymoser/nellymoser-discont.flv -fate-filter-asyncts: CMD = pcm -analyzeduration 10000000 -i $(SRC) -af asyncts -fate-filter-asyncts: CMP = oneoff -fate-filter-asyncts: REF = $(SAMPLES)/nellymoser/nellymoser-discont-async-v3.pcm - FATE_AFILTER_SAMPLES-$(CONFIG_ARESAMPLE_FILTER) += fate-filter-aresample fate-filter-aresample: SRC = $(TARGET_SAMPLES)/nellymoser/nellymoser-discont.flv fate-filter-aresample: CMD = pcm -analyzeduration 10000000 -i $(SRC) -af aresample=min_comp=0.001:min_hard_comp=0.1:first_pts=0 From 487ca38e8bc416239f49b9b7768814fa7be82b5f Mon Sep 17 00:00:00 2001 From: Rostislav Pehlivanov Date: Mon, 27 Mar 2017 18:34:15 +0100 Subject: [PATCH 1322/3374] Changelog: reorder last entry Entries are organized in descending chronological order. Signed-off-by: Rostislav Pehlivanov --- Changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Changelog b/Changelog index 406a5afd27aee..ad53c9dd553e9 100644 --- a/Changelog +++ b/Changelog @@ -2,7 +2,6 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. version : -- Removed asyncts filter (use af_aresample instead) - CrystalHD decoder moved to new decode API - add internal ebur128 library, remove external libebur128 dependency - Pro-MPEG CoP #3-R2 FEC protocol @@ -32,6 +31,7 @@ version : - XPM decoder - Removed the legacy X11 screen grabber, use XCB instead - MPEG-7 Video Signature filter +- Removed asyncts filter (use af_aresample instead) version 3.2: From 1c9f4b507888ac94c7d9f7a6ac9edfe6880fa821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sat, 25 Mar 2017 12:10:13 +0100 Subject: [PATCH 1323/3374] lavc/vp9: split into vp9{block,data,mvs} This is following Libav layout to ease merges. --- libavcodec/Makefile | 5 +- libavcodec/aarch64/vp9dsp_init.h | 2 +- libavcodec/aarch64/vp9dsp_init_aarch64.c | 2 +- libavcodec/arm/vp9dsp_init.h | 2 +- libavcodec/arm/vp9dsp_init_arm.c | 2 +- libavcodec/mips/vp9_idct_msa.c | 2 +- libavcodec/mips/vp9_intra_msa.c | 2 +- libavcodec/mips/vp9_lpf_msa.c | 2 +- libavcodec/mips/vp9_mc_msa.c | 2 +- libavcodec/mips/vp9dsp_init_mips.c | 2 +- libavcodec/vp9.c | 3210 ++----------------- libavcodec/vp9.h | 280 ++ libavcodec/vp9block.c | 2059 ++++++++++++ libavcodec/vp9data.c | 2237 +++++++++++++ libavcodec/vp9data.h | 2287 +------------ libavcodec/vp9dsp.c | 2 +- libavcodec/vp9dsp.h | 137 - libavcodec/vp9dsp_template.c | 2 +- libavcodec/vp9mvs.c | 361 +++ libavcodec/vp9prob.c | 265 ++ libavcodec/x86/vp9dsp_init.c | 2 +- libavcodec/x86/vp9dsp_init.h | 2 +- libavcodec/x86/vp9dsp_init_16bpp.c | 2 +- libavcodec/x86/vp9dsp_init_16bpp_template.c | 2 +- tests/checkasm/vp9dsp.c | 4 +- 25 files changed, 5502 insertions(+), 5373 deletions(-) create mode 100644 libavcodec/vp9block.c create mode 100644 libavcodec/vp9data.c delete mode 100644 libavcodec/vp9dsp.h create mode 100644 libavcodec/vp9mvs.c create mode 100644 libavcodec/vp9prob.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 05be516bbab00..cf7ba258176aa 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -610,8 +610,9 @@ OBJS-$(CONFIG_VP8_DECODER) += vp8.o vp56rac.o OBJS-$(CONFIG_VP8_CUVID_DECODER) += cuvid.o OBJS-$(CONFIG_VP8_MEDIACODEC_DECODER) += mediacodecdec.o OBJS-$(CONFIG_VP8_VAAPI_ENCODER) += vaapi_encode_vp8.o -OBJS-$(CONFIG_VP9_DECODER) += vp9.o vp9dsp.o vp56rac.o vp9dsp_8bpp.o \ - vp9dsp_10bpp.o vp9dsp_12bpp.o +OBJS-$(CONFIG_VP9_DECODER) += vp9.o vp9data.o vp9dsp.o \ + vp9block.o vp9prob.o vp9mvs.o vp56rac.o \ + vp9dsp_8bpp.o vp9dsp_10bpp.o vp9dsp_12bpp.o OBJS-$(CONFIG_VP9_CUVID_DECODER) += cuvid.o OBJS-$(CONFIG_VP9_MEDIACODEC_DECODER) += mediacodecdec.o OBJS-$(CONFIG_VPLAYER_DECODER) += textdec.o ass.o diff --git a/libavcodec/aarch64/vp9dsp_init.h b/libavcodec/aarch64/vp9dsp_init.h index 9df1752c62789..e288fb482b9b2 100644 --- a/libavcodec/aarch64/vp9dsp_init.h +++ b/libavcodec/aarch64/vp9dsp_init.h @@ -21,7 +21,7 @@ #ifndef AVCODEC_AARCH64_VP9DSP_INIT_H #define AVCODEC_AARCH64_VP9DSP_INIT_H -#include "libavcodec/vp9dsp.h" +#include "libavcodec/vp9.h" void ff_vp9dsp_init_10bpp_aarch64(VP9DSPContext *dsp); void ff_vp9dsp_init_12bpp_aarch64(VP9DSPContext *dsp); diff --git a/libavcodec/aarch64/vp9dsp_init_aarch64.c b/libavcodec/aarch64/vp9dsp_init_aarch64.c index 91a82d822df77..e27c232b71c48 100644 --- a/libavcodec/aarch64/vp9dsp_init_aarch64.c +++ b/libavcodec/aarch64/vp9dsp_init_aarch64.c @@ -22,7 +22,7 @@ #include "libavutil/attributes.h" #include "libavutil/aarch64/cpu.h" -#include "libavcodec/vp9dsp.h" +#include "libavcodec/vp9.h" #include "vp9dsp_init.h" #define declare_fpel(type, sz) \ diff --git a/libavcodec/arm/vp9dsp_init.h b/libavcodec/arm/vp9dsp_init.h index 0dc1c2dc20940..0047a24bd8ba7 100644 --- a/libavcodec/arm/vp9dsp_init.h +++ b/libavcodec/arm/vp9dsp_init.h @@ -21,7 +21,7 @@ #ifndef AVCODEC_ARM_VP9DSP_INIT_H #define AVCODEC_ARM_VP9DSP_INIT_H -#include "libavcodec/vp9dsp.h" +#include "libavcodec/vp9.h" void ff_vp9dsp_init_10bpp_arm(VP9DSPContext *dsp); void ff_vp9dsp_init_12bpp_arm(VP9DSPContext *dsp); diff --git a/libavcodec/arm/vp9dsp_init_arm.c b/libavcodec/arm/vp9dsp_init_arm.c index 4c57fd6ba05b5..f9245c387986f 100644 --- a/libavcodec/arm/vp9dsp_init_arm.c +++ b/libavcodec/arm/vp9dsp_init_arm.c @@ -22,7 +22,7 @@ #include "libavutil/attributes.h" #include "libavutil/arm/cpu.h" -#include "libavcodec/vp9dsp.h" +#include "libavcodec/vp9.h" #include "vp9dsp_init.h" #define declare_fpel(type, sz) \ diff --git a/libavcodec/mips/vp9_idct_msa.c b/libavcodec/mips/vp9_idct_msa.c index 25ea16c72a060..e2b7b3cea8626 100644 --- a/libavcodec/mips/vp9_idct_msa.c +++ b/libavcodec/mips/vp9_idct_msa.c @@ -19,7 +19,7 @@ */ #include -#include "libavcodec/vp9dsp.h" +#include "libavcodec/vp9.h" #include "libavutil/mips/generic_macros_msa.h" #include "vp9dsp_mips.h" diff --git a/libavcodec/mips/vp9_intra_msa.c b/libavcodec/mips/vp9_intra_msa.c index 54cf0ae94f1ea..4097cf4c629d8 100644 --- a/libavcodec/mips/vp9_intra_msa.c +++ b/libavcodec/mips/vp9_intra_msa.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "libavcodec/vp9dsp.h" +#include "libavcodec/vp9.h" #include "libavutil/mips/generic_macros_msa.h" #include "vp9dsp_mips.h" diff --git a/libavcodec/mips/vp9_lpf_msa.c b/libavcodec/mips/vp9_lpf_msa.c index eef8afc4828e1..9164dcd10e7a5 100644 --- a/libavcodec/mips/vp9_lpf_msa.c +++ b/libavcodec/mips/vp9_lpf_msa.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "libavcodec/vp9dsp.h" +#include "libavcodec/vp9.h" #include "libavutil/mips/generic_macros_msa.h" #include "vp9dsp_mips.h" diff --git a/libavcodec/mips/vp9_mc_msa.c b/libavcodec/mips/vp9_mc_msa.c index 1671d973a4a0d..52207b6f23d5c 100644 --- a/libavcodec/mips/vp9_mc_msa.c +++ b/libavcodec/mips/vp9_mc_msa.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "libavcodec/vp9dsp.h" +#include "libavcodec/vp9.h" #include "libavutil/mips/generic_macros_msa.h" #include "vp9dsp_mips.h" diff --git a/libavcodec/mips/vp9dsp_init_mips.c b/libavcodec/mips/vp9dsp_init_mips.c index c8a48908af30e..3248baa3cc0c5 100644 --- a/libavcodec/mips/vp9dsp_init_mips.c +++ b/libavcodec/mips/vp9dsp_init_mips.c @@ -20,7 +20,7 @@ #include "config.h" #include "libavutil/common.h" -#include "libavcodec/vp9dsp.h" +#include "libavcodec/vp9.h" #include "vp9dsp_mips.h" #if HAVE_MSA diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index a41f3a3961523..16f4c0d0f41c7 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -30,150 +30,12 @@ #include "vp56.h" #include "vp9.h" #include "vp9data.h" -#include "vp9dsp.h" +#include "vp9.h" #include "libavutil/avassert.h" #include "libavutil/pixdesc.h" #define VP9_SYNCCODE 0x498342 -struct VP9Filter { - uint8_t level[8 * 8]; - uint8_t /* bit=col */ mask[2 /* 0=y, 1=uv */][2 /* 0=col, 1=row */] - [8 /* rows */][4 /* 0=16, 1=8, 2=4, 3=inner4 */]; -}; - -typedef struct VP9Block { - uint8_t seg_id, intra, comp, ref[2], mode[4], uvmode, skip; - enum FilterMode filter; - VP56mv mv[4 /* b_idx */][2 /* ref */]; - enum BlockSize bs; - enum TxfmMode tx, uvtx; - enum BlockLevel bl; - enum BlockPartition bp; -} VP9Block; - -typedef struct VP9Context { - VP9SharedContext s; - - VP9DSPContext dsp; - VideoDSPContext vdsp; - GetBitContext gb; - VP56RangeCoder c; - VP56RangeCoder *c_b; - unsigned c_b_size; - VP9Block *b_base, *b; - int pass; - int row, row7, col, col7; - uint8_t *dst[3]; - ptrdiff_t y_stride, uv_stride; - - uint8_t ss_h, ss_v; - uint8_t last_bpp, bpp_index, bytesperpixel; - uint8_t last_keyframe; - // sb_cols/rows, rows/cols and last_fmt are used for allocating all internal - // arrays, and are thus per-thread. w/h and gf_fmt are synced between threads - // and are therefore per-stream. pix_fmt represents the value in the header - // of the currently processed frame. - int w, h; - enum AVPixelFormat pix_fmt, last_fmt, gf_fmt; - unsigned sb_cols, sb_rows, rows, cols; - ThreadFrame next_refs[8]; - - struct { - uint8_t lim_lut[64]; - uint8_t mblim_lut[64]; - } filter_lut; - unsigned tile_row_start, tile_row_end, tile_col_start, tile_col_end; - struct { - prob_context p; - uint8_t coef[4][2][2][6][6][3]; - } prob_ctx[4]; - struct { - prob_context p; - uint8_t coef[4][2][2][6][6][11]; - } prob; - struct { - unsigned y_mode[4][10]; - unsigned uv_mode[10][10]; - unsigned filter[4][3]; - unsigned mv_mode[7][4]; - unsigned intra[4][2]; - unsigned comp[5][2]; - unsigned single_ref[5][2][2]; - unsigned comp_ref[5][2]; - unsigned tx32p[2][4]; - unsigned tx16p[2][3]; - unsigned tx8p[2][2]; - unsigned skip[3][2]; - unsigned mv_joint[4]; - struct { - unsigned sign[2]; - unsigned classes[11]; - unsigned class0[2]; - unsigned bits[10][2]; - unsigned class0_fp[2][4]; - unsigned fp[4]; - unsigned class0_hp[2]; - unsigned hp[2]; - } mv_comp[2]; - unsigned partition[4][4][4]; - unsigned coef[4][2][2][6][6][3]; - unsigned eob[4][2][2][6][6][2]; - } counts; - - // contextual (left/above) cache - DECLARE_ALIGNED(16, uint8_t, left_y_nnz_ctx)[16]; - DECLARE_ALIGNED(16, uint8_t, left_mode_ctx)[16]; - DECLARE_ALIGNED(16, VP56mv, left_mv_ctx)[16][2]; - DECLARE_ALIGNED(16, uint8_t, left_uv_nnz_ctx)[2][16]; - DECLARE_ALIGNED(8, uint8_t, left_partition_ctx)[8]; - DECLARE_ALIGNED(8, uint8_t, left_skip_ctx)[8]; - DECLARE_ALIGNED(8, uint8_t, left_txfm_ctx)[8]; - DECLARE_ALIGNED(8, uint8_t, left_segpred_ctx)[8]; - DECLARE_ALIGNED(8, uint8_t, left_intra_ctx)[8]; - DECLARE_ALIGNED(8, uint8_t, left_comp_ctx)[8]; - DECLARE_ALIGNED(8, uint8_t, left_ref_ctx)[8]; - DECLARE_ALIGNED(8, uint8_t, left_filter_ctx)[8]; - uint8_t *above_partition_ctx; - uint8_t *above_mode_ctx; - // FIXME maybe merge some of the below in a flags field? - uint8_t *above_y_nnz_ctx; - uint8_t *above_uv_nnz_ctx[2]; - uint8_t *above_skip_ctx; // 1bit - uint8_t *above_txfm_ctx; // 2bit - uint8_t *above_segpred_ctx; // 1bit - uint8_t *above_intra_ctx; // 1bit - uint8_t *above_comp_ctx; // 1bit - uint8_t *above_ref_ctx; // 2bit - uint8_t *above_filter_ctx; - VP56mv (*above_mv_ctx)[2]; - - // whole-frame cache - uint8_t *intra_pred_data[3]; - struct VP9Filter *lflvl; - DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[135 * 144 * 2]; - - // block reconstruction intermediates - int block_alloc_using_2pass; - int16_t *block_base, *block, *uvblock_base[2], *uvblock[2]; - uint8_t *eob_base, *uveob_base[2], *eob, *uveob[2]; - struct { int x, y; } min_mv, max_mv; - DECLARE_ALIGNED(32, uint8_t, tmp_y)[64 * 64 * 2]; - DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][64 * 64 * 2]; - uint16_t mvscale[3][2]; - uint8_t mvstep[3][2]; -} VP9Context; - -static const uint8_t bwh_tab[2][N_BS_SIZES][2] = { - { - { 16, 16 }, { 16, 8 }, { 8, 16 }, { 8, 8 }, { 8, 4 }, { 4, 8 }, - { 4, 4 }, { 4, 2 }, { 2, 4 }, { 2, 2 }, { 2, 1 }, { 1, 2 }, { 1, 1 }, - }, { - { 8, 8 }, { 8, 4 }, { 4, 8 }, { 4, 4 }, { 4, 2 }, { 2, 4 }, - { 2, 2 }, { 2, 1 }, { 1, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, - } -}; - static void vp9_unref_frame(AVCodecContext *ctx, VP9Frame *f) { ff_thread_release_buffer(ctx, &f->tf); @@ -736,10 +598,10 @@ static int decode_frame_header(AVCodecContext *ctx, quvac = av_clip_uintp2(qyac + s->s.h.uvac_qdelta, 8); qyac = av_clip_uintp2(qyac, 8); - s->s.h.segmentation.feat[i].qmul[0][0] = vp9_dc_qlookup[s->bpp_index][qydc]; - s->s.h.segmentation.feat[i].qmul[0][1] = vp9_ac_qlookup[s->bpp_index][qyac]; - s->s.h.segmentation.feat[i].qmul[1][0] = vp9_dc_qlookup[s->bpp_index][quvdc]; - s->s.h.segmentation.feat[i].qmul[1][1] = vp9_ac_qlookup[s->bpp_index][quvac]; + s->s.h.segmentation.feat[i].qmul[0][0] = ff_vp9_dc_qlookup[s->bpp_index][qydc]; + s->s.h.segmentation.feat[i].qmul[0][1] = ff_vp9_ac_qlookup[s->bpp_index][qyac]; + s->s.h.segmentation.feat[i].qmul[1][0] = ff_vp9_dc_qlookup[s->bpp_index][quvdc]; + s->s.h.segmentation.feat[i].qmul[1][1] = ff_vp9_ac_qlookup[s->bpp_index][quvac]; sh = s->s.h.filter.level >= 32; if (s->s.h.segmentation.enabled && s->s.h.segmentation.feat[i].lf_enabled) { @@ -828,19 +690,19 @@ static int decode_frame_header(AVCodecContext *ctx, if (s->s.h.keyframe || s->s.h.errorres || (s->s.h.intraonly && s->s.h.resetctx == 3)) { s->prob_ctx[0].p = s->prob_ctx[1].p = s->prob_ctx[2].p = - s->prob_ctx[3].p = vp9_default_probs; - memcpy(s->prob_ctx[0].coef, vp9_default_coef_probs, - sizeof(vp9_default_coef_probs)); - memcpy(s->prob_ctx[1].coef, vp9_default_coef_probs, - sizeof(vp9_default_coef_probs)); - memcpy(s->prob_ctx[2].coef, vp9_default_coef_probs, - sizeof(vp9_default_coef_probs)); - memcpy(s->prob_ctx[3].coef, vp9_default_coef_probs, - sizeof(vp9_default_coef_probs)); + s->prob_ctx[3].p = ff_vp9_default_probs; + memcpy(s->prob_ctx[0].coef, ff_vp9_default_coef_probs, + sizeof(ff_vp9_default_coef_probs)); + memcpy(s->prob_ctx[1].coef, ff_vp9_default_coef_probs, + sizeof(ff_vp9_default_coef_probs)); + memcpy(s->prob_ctx[2].coef, ff_vp9_default_coef_probs, + sizeof(ff_vp9_default_coef_probs)); + memcpy(s->prob_ctx[3].coef, ff_vp9_default_coef_probs, + sizeof(ff_vp9_default_coef_probs)); } else if (s->s.h.intraonly && s->s.h.resetctx == 2) { - s->prob_ctx[c].p = vp9_default_probs; - memcpy(s->prob_ctx[c].coef, vp9_default_coef_probs, - sizeof(vp9_default_coef_probs)); + s->prob_ctx[c].p = ff_vp9_default_probs; + memcpy(s->prob_ctx[c].coef, ff_vp9_default_coef_probs, + sizeof(ff_vp9_default_coef_probs)); } // next 16 bits is size of the rest of the header (arith-coded) @@ -1053,2612 +915,259 @@ static int decode_frame_header(AVCodecContext *ctx, return (data2 - data) + size2; } -static av_always_inline void clamp_mv(VP56mv *dst, const VP56mv *src, - VP9Context *s) -{ - dst->x = av_clip(src->x, s->min_mv.x, s->max_mv.x); - dst->y = av_clip(src->y, s->min_mv.y, s->max_mv.y); -} - -static void find_ref_mvs(VP9Context *s, - VP56mv *pmv, int ref, int z, int idx, int sb) +static void decode_sb(AVCodecContext *ctx, int row, int col, struct VP9Filter *lflvl, + ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl) { - static const int8_t mv_ref_blk_off[N_BS_SIZES][8][2] = { - [BS_64x64] = {{ 3, -1 }, { -1, 3 }, { 4, -1 }, { -1, 4 }, - { -1, -1 }, { 0, -1 }, { -1, 0 }, { 6, -1 }}, - [BS_64x32] = {{ 0, -1 }, { -1, 0 }, { 4, -1 }, { -1, 2 }, - { -1, -1 }, { 0, -3 }, { -3, 0 }, { 2, -1 }}, - [BS_32x64] = {{ -1, 0 }, { 0, -1 }, { -1, 4 }, { 2, -1 }, - { -1, -1 }, { -3, 0 }, { 0, -3 }, { -1, 2 }}, - [BS_32x32] = {{ 1, -1 }, { -1, 1 }, { 2, -1 }, { -1, 2 }, - { -1, -1 }, { 0, -3 }, { -3, 0 }, { -3, -3 }}, - [BS_32x16] = {{ 0, -1 }, { -1, 0 }, { 2, -1 }, { -1, -1 }, - { -1, 1 }, { 0, -3 }, { -3, 0 }, { -3, -3 }}, - [BS_16x32] = {{ -1, 0 }, { 0, -1 }, { -1, 2 }, { -1, -1 }, - { 1, -1 }, { -3, 0 }, { 0, -3 }, { -3, -3 }}, - [BS_16x16] = {{ 0, -1 }, { -1, 0 }, { 1, -1 }, { -1, 1 }, - { -1, -1 }, { 0, -3 }, { -3, 0 }, { -3, -3 }}, - [BS_16x8] = {{ 0, -1 }, { -1, 0 }, { 1, -1 }, { -1, -1 }, - { 0, -2 }, { -2, 0 }, { -2, -1 }, { -1, -2 }}, - [BS_8x16] = {{ -1, 0 }, { 0, -1 }, { -1, 1 }, { -1, -1 }, - { -2, 0 }, { 0, -2 }, { -1, -2 }, { -2, -1 }}, - [BS_8x8] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, - { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }}, - [BS_8x4] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, - { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }}, - [BS_4x8] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, - { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }}, - [BS_4x4] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, - { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }}, - }; - VP9Block *b = s->b; - int row = s->row, col = s->col, row7 = s->row7; - const int8_t (*p)[2] = mv_ref_blk_off[b->bs]; -#define INVALID_MV 0x80008000U - uint32_t mem = INVALID_MV, mem_sub8x8 = INVALID_MV; - int i; - -#define RETURN_DIRECT_MV(mv) \ - do { \ - uint32_t m = AV_RN32A(&mv); \ - if (!idx) { \ - AV_WN32A(pmv, m); \ - return; \ - } else if (mem == INVALID_MV) { \ - mem = m; \ - } else if (m != mem) { \ - AV_WN32A(pmv, m); \ - return; \ - } \ - } while (0) - - if (sb >= 0) { - if (sb == 2 || sb == 1) { - RETURN_DIRECT_MV(b->mv[0][z]); - } else if (sb == 3) { - RETURN_DIRECT_MV(b->mv[2][z]); - RETURN_DIRECT_MV(b->mv[1][z]); - RETURN_DIRECT_MV(b->mv[0][z]); - } + VP9Context *s = ctx->priv_data; + int c = ((s->above_partition_ctx[col] >> (3 - bl)) & 1) | + (((s->left_partition_ctx[row & 0x7] >> (3 - bl)) & 1) << 1); + const uint8_t *p = s->s.h.keyframe || s->s.h.intraonly ? ff_vp9_default_kf_partition_probs[bl][c] : + s->prob.p.partition[bl][c]; + enum BlockPartition bp; + ptrdiff_t hbs = 4 >> bl; + AVFrame *f = s->s.frames[CUR_FRAME].tf.f; + ptrdiff_t y_stride = f->linesize[0], uv_stride = f->linesize[1]; + int bytesperpixel = s->bytesperpixel; -#define RETURN_MV(mv) \ - do { \ - if (sb > 0) { \ - VP56mv tmp; \ - uint32_t m; \ - av_assert2(idx == 1); \ - av_assert2(mem != INVALID_MV); \ - if (mem_sub8x8 == INVALID_MV) { \ - clamp_mv(&tmp, &mv, s); \ - m = AV_RN32A(&tmp); \ - if (m != mem) { \ - AV_WN32A(pmv, m); \ - return; \ - } \ - mem_sub8x8 = AV_RN32A(&mv); \ - } else if (mem_sub8x8 != AV_RN32A(&mv)) { \ - clamp_mv(&tmp, &mv, s); \ - m = AV_RN32A(&tmp); \ - if (m != mem) { \ - AV_WN32A(pmv, m); \ - } else { \ - /* BUG I'm pretty sure this isn't the intention */ \ - AV_WN32A(pmv, 0); \ - } \ - return; \ - } \ - } else { \ - uint32_t m = AV_RN32A(&mv); \ - if (!idx) { \ - clamp_mv(pmv, &mv, s); \ - return; \ - } else if (mem == INVALID_MV) { \ - mem = m; \ - } else if (m != mem) { \ - clamp_mv(pmv, &mv, s); \ - return; \ - } \ - } \ - } while (0) - - if (row > 0) { - struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[(row - 1) * s->sb_cols * 8 + col]; - if (mv->ref[0] == ref) { - RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][0]); - } else if (mv->ref[1] == ref) { - RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][1]); + if (bl == BL_8X8) { + bp = vp8_rac_get_tree(&s->c, ff_vp9_partition_tree, p); + ff_vp9_decode_block(ctx, row, col, lflvl, yoff, uvoff, bl, bp); + } else if (col + hbs < s->cols) { // FIXME why not <=? + if (row + hbs < s->rows) { // FIXME why not <=? + bp = vp8_rac_get_tree(&s->c, ff_vp9_partition_tree, p); + switch (bp) { + case PARTITION_NONE: + ff_vp9_decode_block(ctx, row, col, lflvl, yoff, uvoff, bl, bp); + break; + case PARTITION_H: + ff_vp9_decode_block(ctx, row, col, lflvl, yoff, uvoff, bl, bp); + yoff += hbs * 8 * y_stride; + uvoff += hbs * 8 * uv_stride >> s->ss_v; + ff_vp9_decode_block(ctx, row + hbs, col, lflvl, yoff, uvoff, bl, bp); + break; + case PARTITION_V: + ff_vp9_decode_block(ctx, row, col, lflvl, yoff, uvoff, bl, bp); + yoff += hbs * 8 * bytesperpixel; + uvoff += hbs * 8 * bytesperpixel >> s->ss_h; + ff_vp9_decode_block(ctx, row, col + hbs, lflvl, yoff, uvoff, bl, bp); + break; + case PARTITION_SPLIT: + decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(ctx, row, col + hbs, lflvl, + yoff + 8 * hbs * bytesperpixel, + uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); + yoff += hbs * 8 * y_stride; + uvoff += hbs * 8 * uv_stride >> s->ss_v; + decode_sb(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(ctx, row + hbs, col + hbs, lflvl, + yoff + 8 * hbs * bytesperpixel, + uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); + break; + default: + av_assert0(0); } + } else if (vp56_rac_get_prob_branchy(&s->c, p[1])) { + bp = PARTITION_SPLIT; + decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(ctx, row, col + hbs, lflvl, + yoff + 8 * hbs * bytesperpixel, + uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); + } else { + bp = PARTITION_H; + ff_vp9_decode_block(ctx, row, col, lflvl, yoff, uvoff, bl, bp); } - if (col > s->tile_col_start) { - struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[row * s->sb_cols * 8 + col - 1]; - if (mv->ref[0] == ref) { - RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][0]); - } else if (mv->ref[1] == ref) { - RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][1]); - } + } else if (row + hbs < s->rows) { // FIXME why not <=? + if (vp56_rac_get_prob_branchy(&s->c, p[2])) { + bp = PARTITION_SPLIT; + decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1); + yoff += hbs * 8 * y_stride; + uvoff += hbs * 8 * uv_stride >> s->ss_v; + decode_sb(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); + } else { + bp = PARTITION_V; + ff_vp9_decode_block(ctx, row, col, lflvl, yoff, uvoff, bl, bp); } - i = 2; } else { - i = 0; + bp = PARTITION_SPLIT; + decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1); } + s->counts.partition[bl][c][bp]++; +} - // previously coded MVs in this neighbourhood, using same reference frame - for (; i < 8; i++) { - int c = p[i][0] + col, r = p[i][1] + row; - - if (c >= s->tile_col_start && c < s->cols && r >= 0 && r < s->rows) { - struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c]; +static void decode_sb_mem(AVCodecContext *ctx, int row, int col, struct VP9Filter *lflvl, + ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl) +{ + VP9Context *s = ctx->priv_data; + VP9Block *b = s->b; + ptrdiff_t hbs = 4 >> bl; + AVFrame *f = s->s.frames[CUR_FRAME].tf.f; + ptrdiff_t y_stride = f->linesize[0], uv_stride = f->linesize[1]; + int bytesperpixel = s->bytesperpixel; - if (mv->ref[0] == ref) { - RETURN_MV(mv->mv[0]); - } else if (mv->ref[1] == ref) { - RETURN_MV(mv->mv[1]); + if (bl == BL_8X8) { + av_assert2(b->bl == BL_8X8); + ff_vp9_decode_block(ctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp); + } else if (s->b->bl == bl) { + ff_vp9_decode_block(ctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp); + if (b->bp == PARTITION_H && row + hbs < s->rows) { + yoff += hbs * 8 * y_stride; + uvoff += hbs * 8 * uv_stride >> s->ss_v; + ff_vp9_decode_block(ctx, row + hbs, col, lflvl, yoff, uvoff, b->bl, b->bp); + } else if (b->bp == PARTITION_V && col + hbs < s->cols) { + yoff += hbs * 8 * bytesperpixel; + uvoff += hbs * 8 * bytesperpixel >> s->ss_h; + ff_vp9_decode_block(ctx, row, col + hbs, lflvl, yoff, uvoff, b->bl, b->bp); + } + } else { + decode_sb_mem(ctx, row, col, lflvl, yoff, uvoff, bl + 1); + if (col + hbs < s->cols) { // FIXME why not <=? + if (row + hbs < s->rows) { + decode_sb_mem(ctx, row, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel, + uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); + yoff += hbs * 8 * y_stride; + uvoff += hbs * 8 * uv_stride >> s->ss_v; + decode_sb_mem(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); + decode_sb_mem(ctx, row + hbs, col + hbs, lflvl, + yoff + 8 * hbs * bytesperpixel, + uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); + } else { + yoff += hbs * 8 * bytesperpixel; + uvoff += hbs * 8 * bytesperpixel >> s->ss_h; + decode_sb_mem(ctx, row, col + hbs, lflvl, yoff, uvoff, bl + 1); } + } else if (row + hbs < s->rows) { + yoff += hbs * 8 * y_stride; + uvoff += hbs * 8 * uv_stride >> s->ss_v; + decode_sb_mem(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); } } +} - // MV at this position in previous frame, using same reference frame - if (s->s.h.use_last_frame_mvs) { - struct VP9mvrefPair *mv = &s->s.frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col]; +static av_always_inline void filter_plane_cols(VP9Context *s, int col, int ss_h, int ss_v, + uint8_t *lvl, uint8_t (*mask)[4], + uint8_t *dst, ptrdiff_t ls) +{ + int y, x, bytesperpixel = s->bytesperpixel; - if (!s->s.frames[REF_FRAME_MVPAIR].uses_2pass) - ff_thread_await_progress(&s->s.frames[REF_FRAME_MVPAIR].tf, row >> 3, 0); - if (mv->ref[0] == ref) { - RETURN_MV(mv->mv[0]); - } else if (mv->ref[1] == ref) { - RETURN_MV(mv->mv[1]); - } - } + // filter edges between columns (e.g. block1 | block2) + for (y = 0; y < 8; y += 2 << ss_v, dst += 16 * ls, lvl += 16 << ss_v) { + uint8_t *ptr = dst, *l = lvl, *hmask1 = mask[y], *hmask2 = mask[y + 1 + ss_v]; + unsigned hm1 = hmask1[0] | hmask1[1] | hmask1[2], hm13 = hmask1[3]; + unsigned hm2 = hmask2[1] | hmask2[2], hm23 = hmask2[3]; + unsigned hm = hm1 | hm2 | hm13 | hm23; -#define RETURN_SCALE_MV(mv, scale) \ - do { \ - if (scale) { \ - VP56mv mv_temp = { -mv.x, -mv.y }; \ - RETURN_MV(mv_temp); \ - } else { \ - RETURN_MV(mv); \ - } \ - } while (0) - - // previously coded MVs in this neighbourhood, using different reference frame - for (i = 0; i < 8; i++) { - int c = p[i][0] + col, r = p[i][1] + row; + for (x = 1; hm & ~(x - 1); x <<= 1, ptr += 8 * bytesperpixel >> ss_h) { + if (col || x > 1) { + if (hm1 & x) { + int L = *l, H = L >> 4; + int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - if (c >= s->tile_col_start && c < s->cols && r >= 0 && r < s->rows) { - struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c]; + if (hmask1[0] & x) { + if (hmask2[0] & x) { + av_assert2(l[8 << ss_v] == L); + s->dsp.loop_filter_16[0](ptr, ls, E, I, H); + } else { + s->dsp.loop_filter_8[2][0](ptr, ls, E, I, H); + } + } else if (hm2 & x) { + L = l[8 << ss_v]; + H |= (L >> 4) << 8; + E |= s->filter_lut.mblim_lut[L] << 8; + I |= s->filter_lut.lim_lut[L] << 8; + s->dsp.loop_filter_mix2[!!(hmask1[1] & x)] + [!!(hmask2[1] & x)] + [0](ptr, ls, E, I, H); + } else { + s->dsp.loop_filter_8[!!(hmask1[1] & x)] + [0](ptr, ls, E, I, H); + } + } else if (hm2 & x) { + int L = l[8 << ss_v], H = L >> 4; + int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - if (mv->ref[0] != ref && mv->ref[0] >= 0) { - RETURN_SCALE_MV(mv->mv[0], s->s.h.signbias[mv->ref[0]] != s->s.h.signbias[ref]); - } - if (mv->ref[1] != ref && mv->ref[1] >= 0 && - // BUG - libvpx has this condition regardless of whether - // we used the first ref MV and pre-scaling - AV_RN32A(&mv->mv[0]) != AV_RN32A(&mv->mv[1])) { - RETURN_SCALE_MV(mv->mv[1], s->s.h.signbias[mv->ref[1]] != s->s.h.signbias[ref]); + s->dsp.loop_filter_8[!!(hmask2[1] & x)] + [0](ptr + 8 * ls, ls, E, I, H); + } } - } - } + if (ss_h) { + if (x & 0xAA) + l += 2; + } else { + if (hm13 & x) { + int L = *l, H = L >> 4; + int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - // MV at this position in previous frame, using different reference frame - if (s->s.h.use_last_frame_mvs) { - struct VP9mvrefPair *mv = &s->s.frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col]; + if (hm23 & x) { + L = l[8 << ss_v]; + H |= (L >> 4) << 8; + E |= s->filter_lut.mblim_lut[L] << 8; + I |= s->filter_lut.lim_lut[L] << 8; + s->dsp.loop_filter_mix2[0][0][0](ptr + 4 * bytesperpixel, ls, E, I, H); + } else { + s->dsp.loop_filter_8[0][0](ptr + 4 * bytesperpixel, ls, E, I, H); + } + } else if (hm23 & x) { + int L = l[8 << ss_v], H = L >> 4; + int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - // no need to await_progress, because we already did that above - if (mv->ref[0] != ref && mv->ref[0] >= 0) { - RETURN_SCALE_MV(mv->mv[0], s->s.h.signbias[mv->ref[0]] != s->s.h.signbias[ref]); - } - if (mv->ref[1] != ref && mv->ref[1] >= 0 && - // BUG - libvpx has this condition regardless of whether - // we used the first ref MV and pre-scaling - AV_RN32A(&mv->mv[0]) != AV_RN32A(&mv->mv[1])) { - RETURN_SCALE_MV(mv->mv[1], s->s.h.signbias[mv->ref[1]] != s->s.h.signbias[ref]); + s->dsp.loop_filter_8[0][0](ptr + 8 * ls + 4 * bytesperpixel, ls, E, I, H); + } + l++; + } } } - - AV_ZERO32(pmv); - clamp_mv(pmv, pmv, s); -#undef INVALID_MV -#undef RETURN_MV -#undef RETURN_SCALE_MV } -static av_always_inline int read_mv_component(VP9Context *s, int idx, int hp) +static av_always_inline void filter_plane_rows(VP9Context *s, int row, int ss_h, int ss_v, + uint8_t *lvl, uint8_t (*mask)[4], + uint8_t *dst, ptrdiff_t ls) { - int bit, sign = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].sign); - int n, c = vp8_rac_get_tree(&s->c, vp9_mv_class_tree, - s->prob.p.mv_comp[idx].classes); - - s->counts.mv_comp[idx].sign[sign]++; - s->counts.mv_comp[idx].classes[c]++; - if (c) { - int m; - - for (n = 0, m = 0; m < c; m++) { - bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].bits[m]); - n |= bit << m; - s->counts.mv_comp[idx].bits[m][bit]++; - } - n <<= 3; - bit = vp8_rac_get_tree(&s->c, vp9_mv_fp_tree, s->prob.p.mv_comp[idx].fp); - n |= bit << 1; - s->counts.mv_comp[idx].fp[bit]++; - if (hp) { - bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].hp); - s->counts.mv_comp[idx].hp[bit]++; - n |= bit; - } else { - n |= 1; - // bug in libvpx - we count for bw entropy purposes even if the - // bit wasn't coded - s->counts.mv_comp[idx].hp[1]++; - } - n += 8 << c; - } else { - n = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].class0); - s->counts.mv_comp[idx].class0[n]++; - bit = vp8_rac_get_tree(&s->c, vp9_mv_fp_tree, - s->prob.p.mv_comp[idx].class0_fp[n]); - s->counts.mv_comp[idx].class0_fp[n][bit]++; - n = (n << 3) | (bit << 1); - if (hp) { - bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].class0_hp); - s->counts.mv_comp[idx].class0_hp[bit]++; - n |= bit; - } else { - n |= 1; - // bug in libvpx - we count for bw entropy purposes even if the - // bit wasn't coded - s->counts.mv_comp[idx].class0_hp[1]++; - } - } + int y, x, bytesperpixel = s->bytesperpixel; - return sign ? -(n + 1) : (n + 1); -} + // block1 + // filter edges between rows (e.g. ------) + // block2 + for (y = 0; y < 8; y++, dst += 8 * ls >> ss_v) { + uint8_t *ptr = dst, *l = lvl, *vmask = mask[y]; + unsigned vm = vmask[0] | vmask[1] | vmask[2], vm3 = vmask[3]; -static void fill_mv(VP9Context *s, - VP56mv *mv, int mode, int sb) -{ - VP9Block *b = s->b; + for (x = 1; vm & ~(x - 1); x <<= (2 << ss_h), ptr += 16 * bytesperpixel, l += 2 << ss_h) { + if (row || y) { + if (vm & x) { + int L = *l, H = L >> 4; + int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - if (mode == ZEROMV) { - AV_ZERO64(mv); - } else { - int hp; - - // FIXME cache this value and reuse for other subblocks - find_ref_mvs(s, &mv[0], b->ref[0], 0, mode == NEARMV, - mode == NEWMV ? -1 : sb); - // FIXME maybe move this code into find_ref_mvs() - if ((mode == NEWMV || sb == -1) && - !(hp = s->s.h.highprecisionmvs && abs(mv[0].x) < 64 && abs(mv[0].y) < 64)) { - if (mv[0].y & 1) { - if (mv[0].y < 0) - mv[0].y++; - else - mv[0].y--; - } - if (mv[0].x & 1) { - if (mv[0].x < 0) - mv[0].x++; - else - mv[0].x--; - } - } - if (mode == NEWMV) { - enum MVJoint j = vp8_rac_get_tree(&s->c, vp9_mv_joint_tree, - s->prob.p.mv_joint); - - s->counts.mv_joint[j]++; - if (j >= MV_JOINT_V) - mv[0].y += read_mv_component(s, 0, hp); - if (j & 1) - mv[0].x += read_mv_component(s, 1, hp); - } + if (vmask[0] & x) { + if (vmask[0] & (x << (1 + ss_h))) { + av_assert2(l[1 + ss_h] == L); + s->dsp.loop_filter_16[1](ptr, ls, E, I, H); + } else { + s->dsp.loop_filter_8[2][1](ptr, ls, E, I, H); + } + } else if (vm & (x << (1 + ss_h))) { + L = l[1 + ss_h]; + H |= (L >> 4) << 8; + E |= s->filter_lut.mblim_lut[L] << 8; + I |= s->filter_lut.lim_lut[L] << 8; + s->dsp.loop_filter_mix2[!!(vmask[1] & x)] + [!!(vmask[1] & (x << (1 + ss_h)))] + [1](ptr, ls, E, I, H); + } else { + s->dsp.loop_filter_8[!!(vmask[1] & x)] + [1](ptr, ls, E, I, H); + } + } else if (vm & (x << (1 + ss_h))) { + int L = l[1 + ss_h], H = L >> 4; + int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - if (b->comp) { - // FIXME cache this value and reuse for other subblocks - find_ref_mvs(s, &mv[1], b->ref[1], 1, mode == NEARMV, - mode == NEWMV ? -1 : sb); - if ((mode == NEWMV || sb == -1) && - !(hp = s->s.h.highprecisionmvs && abs(mv[1].x) < 64 && abs(mv[1].y) < 64)) { - if (mv[1].y & 1) { - if (mv[1].y < 0) - mv[1].y++; - else - mv[1].y--; - } - if (mv[1].x & 1) { - if (mv[1].x < 0) - mv[1].x++; - else - mv[1].x--; + s->dsp.loop_filter_8[!!(vmask[1] & (x << (1 + ss_h)))] + [1](ptr + 8 * bytesperpixel, ls, E, I, H); } } - if (mode == NEWMV) { - enum MVJoint j = vp8_rac_get_tree(&s->c, vp9_mv_joint_tree, - s->prob.p.mv_joint); - - s->counts.mv_joint[j]++; - if (j >= MV_JOINT_V) - mv[1].y += read_mv_component(s, 0, hp); - if (j & 1) - mv[1].x += read_mv_component(s, 1, hp); - } - } - } -} - -static av_always_inline void setctx_2d(uint8_t *ptr, int w, int h, - ptrdiff_t stride, int v) -{ - switch (w) { - case 1: - do { - *ptr = v; - ptr += stride; - } while (--h); - break; - case 2: { - int v16 = v * 0x0101; - do { - AV_WN16A(ptr, v16); - ptr += stride; - } while (--h); - break; - } - case 4: { - uint32_t v32 = v * 0x01010101; - do { - AV_WN32A(ptr, v32); - ptr += stride; - } while (--h); - break; - } - case 8: { -#if HAVE_FAST_64BIT - uint64_t v64 = v * 0x0101010101010101ULL; - do { - AV_WN64A(ptr, v64); - ptr += stride; - } while (--h); -#else - uint32_t v32 = v * 0x01010101; - do { - AV_WN32A(ptr, v32); - AV_WN32A(ptr + 4, v32); - ptr += stride; - } while (--h); -#endif - break; - } - } -} - -static void decode_mode(AVCodecContext *ctx) -{ - static const uint8_t left_ctx[N_BS_SIZES] = { - 0x0, 0x8, 0x0, 0x8, 0xc, 0x8, 0xc, 0xe, 0xc, 0xe, 0xf, 0xe, 0xf - }; - static const uint8_t above_ctx[N_BS_SIZES] = { - 0x0, 0x0, 0x8, 0x8, 0x8, 0xc, 0xc, 0xc, 0xe, 0xe, 0xe, 0xf, 0xf - }; - static const uint8_t max_tx_for_bl_bp[N_BS_SIZES] = { - TX_32X32, TX_32X32, TX_32X32, TX_32X32, TX_16X16, TX_16X16, - TX_16X16, TX_8X8, TX_8X8, TX_8X8, TX_4X4, TX_4X4, TX_4X4 - }; - VP9Context *s = ctx->priv_data; - VP9Block *b = s->b; - int row = s->row, col = s->col, row7 = s->row7; - enum TxfmMode max_tx = max_tx_for_bl_bp[b->bs]; - int bw4 = bwh_tab[1][b->bs][0], w4 = FFMIN(s->cols - col, bw4); - int bh4 = bwh_tab[1][b->bs][1], h4 = FFMIN(s->rows - row, bh4), y; - int have_a = row > 0, have_l = col > s->tile_col_start; - int vref, filter_id; - - if (!s->s.h.segmentation.enabled) { - b->seg_id = 0; - } else if (s->s.h.keyframe || s->s.h.intraonly) { - b->seg_id = !s->s.h.segmentation.update_map ? 0 : - vp8_rac_get_tree(&s->c, vp9_segmentation_tree, s->s.h.segmentation.prob); - } else if (!s->s.h.segmentation.update_map || - (s->s.h.segmentation.temporal && - vp56_rac_get_prob_branchy(&s->c, - s->s.h.segmentation.pred_prob[s->above_segpred_ctx[col] + - s->left_segpred_ctx[row7]]))) { - if (!s->s.h.errorres && s->s.frames[REF_FRAME_SEGMAP].segmentation_map) { - int pred = 8, x; - uint8_t *refsegmap = s->s.frames[REF_FRAME_SEGMAP].segmentation_map; - - if (!s->s.frames[REF_FRAME_SEGMAP].uses_2pass) - ff_thread_await_progress(&s->s.frames[REF_FRAME_SEGMAP].tf, row >> 3, 0); - for (y = 0; y < h4; y++) { - int idx_base = (y + row) * 8 * s->sb_cols + col; - for (x = 0; x < w4; x++) - pred = FFMIN(pred, refsegmap[idx_base + x]); - } - av_assert1(pred < 8); - b->seg_id = pred; - } else { - b->seg_id = 0; - } - - memset(&s->above_segpred_ctx[col], 1, w4); - memset(&s->left_segpred_ctx[row7], 1, h4); - } else { - b->seg_id = vp8_rac_get_tree(&s->c, vp9_segmentation_tree, - s->s.h.segmentation.prob); - - memset(&s->above_segpred_ctx[col], 0, w4); - memset(&s->left_segpred_ctx[row7], 0, h4); - } - if (s->s.h.segmentation.enabled && - (s->s.h.segmentation.update_map || s->s.h.keyframe || s->s.h.intraonly)) { - setctx_2d(&s->s.frames[CUR_FRAME].segmentation_map[row * 8 * s->sb_cols + col], - bw4, bh4, 8 * s->sb_cols, b->seg_id); - } - - b->skip = s->s.h.segmentation.enabled && - s->s.h.segmentation.feat[b->seg_id].skip_enabled; - if (!b->skip) { - int c = s->left_skip_ctx[row7] + s->above_skip_ctx[col]; - b->skip = vp56_rac_get_prob(&s->c, s->prob.p.skip[c]); - s->counts.skip[c][b->skip]++; - } - - if (s->s.h.keyframe || s->s.h.intraonly) { - b->intra = 1; - } else if (s->s.h.segmentation.enabled && s->s.h.segmentation.feat[b->seg_id].ref_enabled) { - b->intra = !s->s.h.segmentation.feat[b->seg_id].ref_val; - } else { - int c, bit; - - if (have_a && have_l) { - c = s->above_intra_ctx[col] + s->left_intra_ctx[row7]; - c += (c == 2); - } else { - c = have_a ? 2 * s->above_intra_ctx[col] : - have_l ? 2 * s->left_intra_ctx[row7] : 0; - } - bit = vp56_rac_get_prob(&s->c, s->prob.p.intra[c]); - s->counts.intra[c][bit]++; - b->intra = !bit; - } - - if ((b->intra || !b->skip) && s->s.h.txfmmode == TX_SWITCHABLE) { - int c; - if (have_a) { - if (have_l) { - c = (s->above_skip_ctx[col] ? max_tx : - s->above_txfm_ctx[col]) + - (s->left_skip_ctx[row7] ? max_tx : - s->left_txfm_ctx[row7]) > max_tx; - } else { - c = s->above_skip_ctx[col] ? 1 : - (s->above_txfm_ctx[col] * 2 > max_tx); - } - } else if (have_l) { - c = s->left_skip_ctx[row7] ? 1 : - (s->left_txfm_ctx[row7] * 2 > max_tx); - } else { - c = 1; - } - switch (max_tx) { - case TX_32X32: - b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][0]); - if (b->tx) { - b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][1]); - if (b->tx == 2) - b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][2]); - } - s->counts.tx32p[c][b->tx]++; - break; - case TX_16X16: - b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx16p[c][0]); - if (b->tx) - b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx16p[c][1]); - s->counts.tx16p[c][b->tx]++; - break; - case TX_8X8: - b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx8p[c]); - s->counts.tx8p[c][b->tx]++; - break; - case TX_4X4: - b->tx = TX_4X4; - break; - } - } else { - b->tx = FFMIN(max_tx, s->s.h.txfmmode); - } - - if (s->s.h.keyframe || s->s.h.intraonly) { - uint8_t *a = &s->above_mode_ctx[col * 2]; - uint8_t *l = &s->left_mode_ctx[(row7) << 1]; - - b->comp = 0; - if (b->bs > BS_8x8) { - // FIXME the memory storage intermediates here aren't really - // necessary, they're just there to make the code slightly - // simpler for now - b->mode[0] = a[0] = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - vp9_default_kf_ymode_probs[a[0]][l[0]]); - if (b->bs != BS_8x4) { - b->mode[1] = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - vp9_default_kf_ymode_probs[a[1]][b->mode[0]]); - l[0] = a[1] = b->mode[1]; - } else { - l[0] = a[1] = b->mode[1] = b->mode[0]; - } - if (b->bs != BS_4x8) { - b->mode[2] = a[0] = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - vp9_default_kf_ymode_probs[a[0]][l[1]]); - if (b->bs != BS_8x4) { - b->mode[3] = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - vp9_default_kf_ymode_probs[a[1]][b->mode[2]]); - l[1] = a[1] = b->mode[3]; - } else { - l[1] = a[1] = b->mode[3] = b->mode[2]; - } - } else { - b->mode[2] = b->mode[0]; - l[1] = a[1] = b->mode[3] = b->mode[1]; - } - } else { - b->mode[0] = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - vp9_default_kf_ymode_probs[*a][*l]); - b->mode[3] = b->mode[2] = b->mode[1] = b->mode[0]; - // FIXME this can probably be optimized - memset(a, b->mode[0], bwh_tab[0][b->bs][0]); - memset(l, b->mode[0], bwh_tab[0][b->bs][1]); - } - b->uvmode = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - vp9_default_kf_uvmode_probs[b->mode[3]]); - } else if (b->intra) { - b->comp = 0; - if (b->bs > BS_8x8) { - b->mode[0] = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - s->prob.p.y_mode[0]); - s->counts.y_mode[0][b->mode[0]]++; - if (b->bs != BS_8x4) { - b->mode[1] = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - s->prob.p.y_mode[0]); - s->counts.y_mode[0][b->mode[1]]++; - } else { - b->mode[1] = b->mode[0]; - } - if (b->bs != BS_4x8) { - b->mode[2] = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - s->prob.p.y_mode[0]); - s->counts.y_mode[0][b->mode[2]]++; - if (b->bs != BS_8x4) { - b->mode[3] = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - s->prob.p.y_mode[0]); - s->counts.y_mode[0][b->mode[3]]++; - } else { - b->mode[3] = b->mode[2]; - } - } else { - b->mode[2] = b->mode[0]; - b->mode[3] = b->mode[1]; - } - } else { - static const uint8_t size_group[10] = { - 3, 3, 3, 3, 2, 2, 2, 1, 1, 1 - }; - int sz = size_group[b->bs]; - - b->mode[0] = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - s->prob.p.y_mode[sz]); - b->mode[1] = b->mode[2] = b->mode[3] = b->mode[0]; - s->counts.y_mode[sz][b->mode[3]]++; - } - b->uvmode = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - s->prob.p.uv_mode[b->mode[3]]); - s->counts.uv_mode[b->mode[3]][b->uvmode]++; - } else { - static const uint8_t inter_mode_ctx_lut[14][14] = { - { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, - { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, - { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, - { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, - { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, - { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, - { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, - { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, - { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, - { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, - { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 1, 3 }, - { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 1, 3 }, - { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 0, 3 }, - { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 4 }, - }; - - if (s->s.h.segmentation.enabled && s->s.h.segmentation.feat[b->seg_id].ref_enabled) { - av_assert2(s->s.h.segmentation.feat[b->seg_id].ref_val != 0); - b->comp = 0; - b->ref[0] = s->s.h.segmentation.feat[b->seg_id].ref_val - 1; - } else { - // read comp_pred flag - if (s->s.h.comppredmode != PRED_SWITCHABLE) { - b->comp = s->s.h.comppredmode == PRED_COMPREF; - } else { - int c; - - // FIXME add intra as ref=0xff (or -1) to make these easier? - if (have_a) { - if (have_l) { - if (s->above_comp_ctx[col] && s->left_comp_ctx[row7]) { - c = 4; - } else if (s->above_comp_ctx[col]) { - c = 2 + (s->left_intra_ctx[row7] || - s->left_ref_ctx[row7] == s->s.h.fixcompref); - } else if (s->left_comp_ctx[row7]) { - c = 2 + (s->above_intra_ctx[col] || - s->above_ref_ctx[col] == s->s.h.fixcompref); - } else { - c = (!s->above_intra_ctx[col] && - s->above_ref_ctx[col] == s->s.h.fixcompref) ^ - (!s->left_intra_ctx[row7] && - s->left_ref_ctx[row & 7] == s->s.h.fixcompref); - } - } else { - c = s->above_comp_ctx[col] ? 3 : - (!s->above_intra_ctx[col] && s->above_ref_ctx[col] == s->s.h.fixcompref); - } - } else if (have_l) { - c = s->left_comp_ctx[row7] ? 3 : - (!s->left_intra_ctx[row7] && s->left_ref_ctx[row7] == s->s.h.fixcompref); - } else { - c = 1; - } - b->comp = vp56_rac_get_prob(&s->c, s->prob.p.comp[c]); - s->counts.comp[c][b->comp]++; - } - - // read actual references - // FIXME probably cache a few variables here to prevent repetitive - // memory accesses below - if (b->comp) /* two references */ { - int fix_idx = s->s.h.signbias[s->s.h.fixcompref], var_idx = !fix_idx, c, bit; - - b->ref[fix_idx] = s->s.h.fixcompref; - // FIXME can this codeblob be replaced by some sort of LUT? - if (have_a) { - if (have_l) { - if (s->above_intra_ctx[col]) { - if (s->left_intra_ctx[row7]) { - c = 2; - } else { - c = 1 + 2 * (s->left_ref_ctx[row7] != s->s.h.varcompref[1]); - } - } else if (s->left_intra_ctx[row7]) { - c = 1 + 2 * (s->above_ref_ctx[col] != s->s.h.varcompref[1]); - } else { - int refl = s->left_ref_ctx[row7], refa = s->above_ref_ctx[col]; - - if (refl == refa && refa == s->s.h.varcompref[1]) { - c = 0; - } else if (!s->left_comp_ctx[row7] && !s->above_comp_ctx[col]) { - if ((refa == s->s.h.fixcompref && refl == s->s.h.varcompref[0]) || - (refl == s->s.h.fixcompref && refa == s->s.h.varcompref[0])) { - c = 4; - } else { - c = (refa == refl) ? 3 : 1; - } - } else if (!s->left_comp_ctx[row7]) { - if (refa == s->s.h.varcompref[1] && refl != s->s.h.varcompref[1]) { - c = 1; - } else { - c = (refl == s->s.h.varcompref[1] && - refa != s->s.h.varcompref[1]) ? 2 : 4; - } - } else if (!s->above_comp_ctx[col]) { - if (refl == s->s.h.varcompref[1] && refa != s->s.h.varcompref[1]) { - c = 1; - } else { - c = (refa == s->s.h.varcompref[1] && - refl != s->s.h.varcompref[1]) ? 2 : 4; - } - } else { - c = (refl == refa) ? 4 : 2; - } - } - } else { - if (s->above_intra_ctx[col]) { - c = 2; - } else if (s->above_comp_ctx[col]) { - c = 4 * (s->above_ref_ctx[col] != s->s.h.varcompref[1]); - } else { - c = 3 * (s->above_ref_ctx[col] != s->s.h.varcompref[1]); - } - } - } else if (have_l) { - if (s->left_intra_ctx[row7]) { - c = 2; - } else if (s->left_comp_ctx[row7]) { - c = 4 * (s->left_ref_ctx[row7] != s->s.h.varcompref[1]); - } else { - c = 3 * (s->left_ref_ctx[row7] != s->s.h.varcompref[1]); - } - } else { - c = 2; - } - bit = vp56_rac_get_prob(&s->c, s->prob.p.comp_ref[c]); - b->ref[var_idx] = s->s.h.varcompref[bit]; - s->counts.comp_ref[c][bit]++; - } else /* single reference */ { - int bit, c; - - if (have_a && !s->above_intra_ctx[col]) { - if (have_l && !s->left_intra_ctx[row7]) { - if (s->left_comp_ctx[row7]) { - if (s->above_comp_ctx[col]) { - c = 1 + (!s->s.h.fixcompref || !s->left_ref_ctx[row7] || - !s->above_ref_ctx[col]); - } else { - c = (3 * !s->above_ref_ctx[col]) + - (!s->s.h.fixcompref || !s->left_ref_ctx[row7]); - } - } else if (s->above_comp_ctx[col]) { - c = (3 * !s->left_ref_ctx[row7]) + - (!s->s.h.fixcompref || !s->above_ref_ctx[col]); - } else { - c = 2 * !s->left_ref_ctx[row7] + 2 * !s->above_ref_ctx[col]; - } - } else if (s->above_intra_ctx[col]) { - c = 2; - } else if (s->above_comp_ctx[col]) { - c = 1 + (!s->s.h.fixcompref || !s->above_ref_ctx[col]); - } else { - c = 4 * (!s->above_ref_ctx[col]); - } - } else if (have_l && !s->left_intra_ctx[row7]) { - if (s->left_intra_ctx[row7]) { - c = 2; - } else if (s->left_comp_ctx[row7]) { - c = 1 + (!s->s.h.fixcompref || !s->left_ref_ctx[row7]); - } else { - c = 4 * (!s->left_ref_ctx[row7]); - } - } else { - c = 2; - } - bit = vp56_rac_get_prob(&s->c, s->prob.p.single_ref[c][0]); - s->counts.single_ref[c][0][bit]++; - if (!bit) { - b->ref[0] = 0; - } else { - // FIXME can this codeblob be replaced by some sort of LUT? - if (have_a) { - if (have_l) { - if (s->left_intra_ctx[row7]) { - if (s->above_intra_ctx[col]) { - c = 2; - } else if (s->above_comp_ctx[col]) { - c = 1 + 2 * (s->s.h.fixcompref == 1 || - s->above_ref_ctx[col] == 1); - } else if (!s->above_ref_ctx[col]) { - c = 3; - } else { - c = 4 * (s->above_ref_ctx[col] == 1); - } - } else if (s->above_intra_ctx[col]) { - if (s->left_intra_ctx[row7]) { - c = 2; - } else if (s->left_comp_ctx[row7]) { - c = 1 + 2 * (s->s.h.fixcompref == 1 || - s->left_ref_ctx[row7] == 1); - } else if (!s->left_ref_ctx[row7]) { - c = 3; - } else { - c = 4 * (s->left_ref_ctx[row7] == 1); - } - } else if (s->above_comp_ctx[col]) { - if (s->left_comp_ctx[row7]) { - if (s->left_ref_ctx[row7] == s->above_ref_ctx[col]) { - c = 3 * (s->s.h.fixcompref == 1 || - s->left_ref_ctx[row7] == 1); - } else { - c = 2; - } - } else if (!s->left_ref_ctx[row7]) { - c = 1 + 2 * (s->s.h.fixcompref == 1 || - s->above_ref_ctx[col] == 1); - } else { - c = 3 * (s->left_ref_ctx[row7] == 1) + - (s->s.h.fixcompref == 1 || s->above_ref_ctx[col] == 1); - } - } else if (s->left_comp_ctx[row7]) { - if (!s->above_ref_ctx[col]) { - c = 1 + 2 * (s->s.h.fixcompref == 1 || - s->left_ref_ctx[row7] == 1); - } else { - c = 3 * (s->above_ref_ctx[col] == 1) + - (s->s.h.fixcompref == 1 || s->left_ref_ctx[row7] == 1); - } - } else if (!s->above_ref_ctx[col]) { - if (!s->left_ref_ctx[row7]) { - c = 3; - } else { - c = 4 * (s->left_ref_ctx[row7] == 1); - } - } else if (!s->left_ref_ctx[row7]) { - c = 4 * (s->above_ref_ctx[col] == 1); - } else { - c = 2 * (s->left_ref_ctx[row7] == 1) + - 2 * (s->above_ref_ctx[col] == 1); - } - } else { - if (s->above_intra_ctx[col] || - (!s->above_comp_ctx[col] && !s->above_ref_ctx[col])) { - c = 2; - } else if (s->above_comp_ctx[col]) { - c = 3 * (s->s.h.fixcompref == 1 || s->above_ref_ctx[col] == 1); - } else { - c = 4 * (s->above_ref_ctx[col] == 1); - } - } - } else if (have_l) { - if (s->left_intra_ctx[row7] || - (!s->left_comp_ctx[row7] && !s->left_ref_ctx[row7])) { - c = 2; - } else if (s->left_comp_ctx[row7]) { - c = 3 * (s->s.h.fixcompref == 1 || s->left_ref_ctx[row7] == 1); - } else { - c = 4 * (s->left_ref_ctx[row7] == 1); - } - } else { - c = 2; - } - bit = vp56_rac_get_prob(&s->c, s->prob.p.single_ref[c][1]); - s->counts.single_ref[c][1][bit]++; - b->ref[0] = 1 + bit; - } - } - } - - if (b->bs <= BS_8x8) { - if (s->s.h.segmentation.enabled && s->s.h.segmentation.feat[b->seg_id].skip_enabled) { - b->mode[0] = b->mode[1] = b->mode[2] = b->mode[3] = ZEROMV; - } else { - static const uint8_t off[10] = { - 3, 0, 0, 1, 0, 0, 0, 0, 0, 0 - }; - - // FIXME this needs to use the LUT tables from find_ref_mvs - // because not all are -1,0/0,-1 - int c = inter_mode_ctx_lut[s->above_mode_ctx[col + off[b->bs]]] - [s->left_mode_ctx[row7 + off[b->bs]]]; - - b->mode[0] = vp8_rac_get_tree(&s->c, vp9_inter_mode_tree, - s->prob.p.mv_mode[c]); - b->mode[1] = b->mode[2] = b->mode[3] = b->mode[0]; - s->counts.mv_mode[c][b->mode[0] - 10]++; - } - } - - if (s->s.h.filtermode == FILTER_SWITCHABLE) { - int c; - - if (have_a && s->above_mode_ctx[col] >= NEARESTMV) { - if (have_l && s->left_mode_ctx[row7] >= NEARESTMV) { - c = s->above_filter_ctx[col] == s->left_filter_ctx[row7] ? - s->left_filter_ctx[row7] : 3; - } else { - c = s->above_filter_ctx[col]; - } - } else if (have_l && s->left_mode_ctx[row7] >= NEARESTMV) { - c = s->left_filter_ctx[row7]; - } else { - c = 3; - } - - filter_id = vp8_rac_get_tree(&s->c, vp9_filter_tree, - s->prob.p.filter[c]); - s->counts.filter[c][filter_id]++; - b->filter = vp9_filter_lut[filter_id]; - } else { - b->filter = s->s.h.filtermode; - } - - if (b->bs > BS_8x8) { - int c = inter_mode_ctx_lut[s->above_mode_ctx[col]][s->left_mode_ctx[row7]]; - - b->mode[0] = vp8_rac_get_tree(&s->c, vp9_inter_mode_tree, - s->prob.p.mv_mode[c]); - s->counts.mv_mode[c][b->mode[0] - 10]++; - fill_mv(s, b->mv[0], b->mode[0], 0); - - if (b->bs != BS_8x4) { - b->mode[1] = vp8_rac_get_tree(&s->c, vp9_inter_mode_tree, - s->prob.p.mv_mode[c]); - s->counts.mv_mode[c][b->mode[1] - 10]++; - fill_mv(s, b->mv[1], b->mode[1], 1); - } else { - b->mode[1] = b->mode[0]; - AV_COPY32(&b->mv[1][0], &b->mv[0][0]); - AV_COPY32(&b->mv[1][1], &b->mv[0][1]); - } - - if (b->bs != BS_4x8) { - b->mode[2] = vp8_rac_get_tree(&s->c, vp9_inter_mode_tree, - s->prob.p.mv_mode[c]); - s->counts.mv_mode[c][b->mode[2] - 10]++; - fill_mv(s, b->mv[2], b->mode[2], 2); - - if (b->bs != BS_8x4) { - b->mode[3] = vp8_rac_get_tree(&s->c, vp9_inter_mode_tree, - s->prob.p.mv_mode[c]); - s->counts.mv_mode[c][b->mode[3] - 10]++; - fill_mv(s, b->mv[3], b->mode[3], 3); - } else { - b->mode[3] = b->mode[2]; - AV_COPY32(&b->mv[3][0], &b->mv[2][0]); - AV_COPY32(&b->mv[3][1], &b->mv[2][1]); - } - } else { - b->mode[2] = b->mode[0]; - AV_COPY32(&b->mv[2][0], &b->mv[0][0]); - AV_COPY32(&b->mv[2][1], &b->mv[0][1]); - b->mode[3] = b->mode[1]; - AV_COPY32(&b->mv[3][0], &b->mv[1][0]); - AV_COPY32(&b->mv[3][1], &b->mv[1][1]); - } - } else { - fill_mv(s, b->mv[0], b->mode[0], -1); - AV_COPY32(&b->mv[1][0], &b->mv[0][0]); - AV_COPY32(&b->mv[2][0], &b->mv[0][0]); - AV_COPY32(&b->mv[3][0], &b->mv[0][0]); - AV_COPY32(&b->mv[1][1], &b->mv[0][1]); - AV_COPY32(&b->mv[2][1], &b->mv[0][1]); - AV_COPY32(&b->mv[3][1], &b->mv[0][1]); - } - - vref = b->ref[b->comp ? s->s.h.signbias[s->s.h.varcompref[0]] : 0]; - } - -#if HAVE_FAST_64BIT -#define SPLAT_CTX(var, val, n) \ - switch (n) { \ - case 1: var = val; break; \ - case 2: AV_WN16A(&var, val * 0x0101); break; \ - case 4: AV_WN32A(&var, val * 0x01010101); break; \ - case 8: AV_WN64A(&var, val * 0x0101010101010101ULL); break; \ - case 16: { \ - uint64_t v64 = val * 0x0101010101010101ULL; \ - AV_WN64A( &var, v64); \ - AV_WN64A(&((uint8_t *) &var)[8], v64); \ - break; \ - } \ - } -#else -#define SPLAT_CTX(var, val, n) \ - switch (n) { \ - case 1: var = val; break; \ - case 2: AV_WN16A(&var, val * 0x0101); break; \ - case 4: AV_WN32A(&var, val * 0x01010101); break; \ - case 8: { \ - uint32_t v32 = val * 0x01010101; \ - AV_WN32A( &var, v32); \ - AV_WN32A(&((uint8_t *) &var)[4], v32); \ - break; \ - } \ - case 16: { \ - uint32_t v32 = val * 0x01010101; \ - AV_WN32A( &var, v32); \ - AV_WN32A(&((uint8_t *) &var)[4], v32); \ - AV_WN32A(&((uint8_t *) &var)[8], v32); \ - AV_WN32A(&((uint8_t *) &var)[12], v32); \ - break; \ - } \ - } -#endif - - switch (bwh_tab[1][b->bs][0]) { -#define SET_CTXS(dir, off, n) \ - do { \ - SPLAT_CTX(s->dir##_skip_ctx[off], b->skip, n); \ - SPLAT_CTX(s->dir##_txfm_ctx[off], b->tx, n); \ - SPLAT_CTX(s->dir##_partition_ctx[off], dir##_ctx[b->bs], n); \ - if (!s->s.h.keyframe && !s->s.h.intraonly) { \ - SPLAT_CTX(s->dir##_intra_ctx[off], b->intra, n); \ - SPLAT_CTX(s->dir##_comp_ctx[off], b->comp, n); \ - SPLAT_CTX(s->dir##_mode_ctx[off], b->mode[3], n); \ - if (!b->intra) { \ - SPLAT_CTX(s->dir##_ref_ctx[off], vref, n); \ - if (s->s.h.filtermode == FILTER_SWITCHABLE) { \ - SPLAT_CTX(s->dir##_filter_ctx[off], filter_id, n); \ - } \ - } \ - } \ - } while (0) - case 1: SET_CTXS(above, col, 1); break; - case 2: SET_CTXS(above, col, 2); break; - case 4: SET_CTXS(above, col, 4); break; - case 8: SET_CTXS(above, col, 8); break; - } - switch (bwh_tab[1][b->bs][1]) { - case 1: SET_CTXS(left, row7, 1); break; - case 2: SET_CTXS(left, row7, 2); break; - case 4: SET_CTXS(left, row7, 4); break; - case 8: SET_CTXS(left, row7, 8); break; - } -#undef SPLAT_CTX -#undef SET_CTXS - - if (!s->s.h.keyframe && !s->s.h.intraonly) { - if (b->bs > BS_8x8) { - int mv0 = AV_RN32A(&b->mv[3][0]), mv1 = AV_RN32A(&b->mv[3][1]); - - AV_COPY32(&s->left_mv_ctx[row7 * 2 + 0][0], &b->mv[1][0]); - AV_COPY32(&s->left_mv_ctx[row7 * 2 + 0][1], &b->mv[1][1]); - AV_WN32A(&s->left_mv_ctx[row7 * 2 + 1][0], mv0); - AV_WN32A(&s->left_mv_ctx[row7 * 2 + 1][1], mv1); - AV_COPY32(&s->above_mv_ctx[col * 2 + 0][0], &b->mv[2][0]); - AV_COPY32(&s->above_mv_ctx[col * 2 + 0][1], &b->mv[2][1]); - AV_WN32A(&s->above_mv_ctx[col * 2 + 1][0], mv0); - AV_WN32A(&s->above_mv_ctx[col * 2 + 1][1], mv1); - } else { - int n, mv0 = AV_RN32A(&b->mv[3][0]), mv1 = AV_RN32A(&b->mv[3][1]); - - for (n = 0; n < w4 * 2; n++) { - AV_WN32A(&s->above_mv_ctx[col * 2 + n][0], mv0); - AV_WN32A(&s->above_mv_ctx[col * 2 + n][1], mv1); - } - for (n = 0; n < h4 * 2; n++) { - AV_WN32A(&s->left_mv_ctx[row7 * 2 + n][0], mv0); - AV_WN32A(&s->left_mv_ctx[row7 * 2 + n][1], mv1); - } - } - } - - // FIXME kinda ugly - for (y = 0; y < h4; y++) { - int x, o = (row + y) * s->sb_cols * 8 + col; - struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[o]; - - if (b->intra) { - for (x = 0; x < w4; x++) { - mv[x].ref[0] = - mv[x].ref[1] = -1; - } - } else if (b->comp) { - for (x = 0; x < w4; x++) { - mv[x].ref[0] = b->ref[0]; - mv[x].ref[1] = b->ref[1]; - AV_COPY32(&mv[x].mv[0], &b->mv[3][0]); - AV_COPY32(&mv[x].mv[1], &b->mv[3][1]); - } - } else { - for (x = 0; x < w4; x++) { - mv[x].ref[0] = b->ref[0]; - mv[x].ref[1] = -1; - AV_COPY32(&mv[x].mv[0], &b->mv[3][0]); - } - } - } -} - -// FIXME merge cnt/eob arguments? -static av_always_inline int -decode_coeffs_b_generic(VP56RangeCoder *c, int16_t *coef, int n_coeffs, - int is_tx32x32, int is8bitsperpixel, int bpp, unsigned (*cnt)[6][3], - unsigned (*eob)[6][2], uint8_t (*p)[6][11], - int nnz, const int16_t *scan, const int16_t (*nb)[2], - const int16_t *band_counts, const int16_t *qmul) -{ - int i = 0, band = 0, band_left = band_counts[band]; - uint8_t *tp = p[0][nnz]; - uint8_t cache[1024]; - - do { - int val, rc; - - val = vp56_rac_get_prob_branchy(c, tp[0]); // eob - eob[band][nnz][val]++; - if (!val) - break; - - skip_eob: - if (!vp56_rac_get_prob_branchy(c, tp[1])) { // zero - cnt[band][nnz][0]++; - if (!--band_left) - band_left = band_counts[++band]; - cache[scan[i]] = 0; - nnz = (1 + cache[nb[i][0]] + cache[nb[i][1]]) >> 1; - tp = p[band][nnz]; - if (++i == n_coeffs) - break; //invalid input; blocks should end with EOB - goto skip_eob; - } - - rc = scan[i]; - if (!vp56_rac_get_prob_branchy(c, tp[2])) { // one - cnt[band][nnz][1]++; - val = 1; - cache[rc] = 1; - } else { - // fill in p[3-10] (model fill) - only once per frame for each pos - if (!tp[3]) - memcpy(&tp[3], vp9_model_pareto8[tp[2]], 8); - - cnt[band][nnz][2]++; - if (!vp56_rac_get_prob_branchy(c, tp[3])) { // 2, 3, 4 - if (!vp56_rac_get_prob_branchy(c, tp[4])) { - cache[rc] = val = 2; - } else { - val = 3 + vp56_rac_get_prob(c, tp[5]); - cache[rc] = 3; - } - } else if (!vp56_rac_get_prob_branchy(c, tp[6])) { // cat1/2 - cache[rc] = 4; - if (!vp56_rac_get_prob_branchy(c, tp[7])) { - val = 5 + vp56_rac_get_prob(c, 159); - } else { - val = 7 + (vp56_rac_get_prob(c, 165) << 1); - val += vp56_rac_get_prob(c, 145); - } - } else { // cat 3-6 - cache[rc] = 5; - if (!vp56_rac_get_prob_branchy(c, tp[8])) { - if (!vp56_rac_get_prob_branchy(c, tp[9])) { - val = 11 + (vp56_rac_get_prob(c, 173) << 2); - val += (vp56_rac_get_prob(c, 148) << 1); - val += vp56_rac_get_prob(c, 140); - } else { - val = 19 + (vp56_rac_get_prob(c, 176) << 3); - val += (vp56_rac_get_prob(c, 155) << 2); - val += (vp56_rac_get_prob(c, 140) << 1); - val += vp56_rac_get_prob(c, 135); - } - } else if (!vp56_rac_get_prob_branchy(c, tp[10])) { - val = 35 + (vp56_rac_get_prob(c, 180) << 4); - val += (vp56_rac_get_prob(c, 157) << 3); - val += (vp56_rac_get_prob(c, 141) << 2); - val += (vp56_rac_get_prob(c, 134) << 1); - val += vp56_rac_get_prob(c, 130); - } else { - val = 67; - if (!is8bitsperpixel) { - if (bpp == 12) { - val += vp56_rac_get_prob(c, 255) << 17; - val += vp56_rac_get_prob(c, 255) << 16; - } - val += (vp56_rac_get_prob(c, 255) << 15); - val += (vp56_rac_get_prob(c, 255) << 14); - } - val += (vp56_rac_get_prob(c, 254) << 13); - val += (vp56_rac_get_prob(c, 254) << 12); - val += (vp56_rac_get_prob(c, 254) << 11); - val += (vp56_rac_get_prob(c, 252) << 10); - val += (vp56_rac_get_prob(c, 249) << 9); - val += (vp56_rac_get_prob(c, 243) << 8); - val += (vp56_rac_get_prob(c, 230) << 7); - val += (vp56_rac_get_prob(c, 196) << 6); - val += (vp56_rac_get_prob(c, 177) << 5); - val += (vp56_rac_get_prob(c, 153) << 4); - val += (vp56_rac_get_prob(c, 140) << 3); - val += (vp56_rac_get_prob(c, 133) << 2); - val += (vp56_rac_get_prob(c, 130) << 1); - val += vp56_rac_get_prob(c, 129); - } - } - } -#define STORE_COEF(c, i, v) do { \ - if (is8bitsperpixel) { \ - c[i] = v; \ - } else { \ - AV_WN32A(&c[i * 2], v); \ - } \ -} while (0) - if (!--band_left) - band_left = band_counts[++band]; - if (is_tx32x32) - STORE_COEF(coef, rc, ((vp8_rac_get(c) ? -val : val) * qmul[!!i]) / 2); - else - STORE_COEF(coef, rc, (vp8_rac_get(c) ? -val : val) * qmul[!!i]); - nnz = (1 + cache[nb[i][0]] + cache[nb[i][1]]) >> 1; - tp = p[band][nnz]; - } while (++i < n_coeffs); - - return i; -} - -static int decode_coeffs_b_8bpp(VP9Context *s, int16_t *coef, int n_coeffs, - unsigned (*cnt)[6][3], unsigned (*eob)[6][2], - uint8_t (*p)[6][11], int nnz, const int16_t *scan, - const int16_t (*nb)[2], const int16_t *band_counts, - const int16_t *qmul) -{ - return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 0, 1, 8, cnt, eob, p, - nnz, scan, nb, band_counts, qmul); -} - -static int decode_coeffs_b32_8bpp(VP9Context *s, int16_t *coef, int n_coeffs, - unsigned (*cnt)[6][3], unsigned (*eob)[6][2], - uint8_t (*p)[6][11], int nnz, const int16_t *scan, - const int16_t (*nb)[2], const int16_t *band_counts, - const int16_t *qmul) -{ - return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 1, 1, 8, cnt, eob, p, - nnz, scan, nb, band_counts, qmul); -} - -static int decode_coeffs_b_16bpp(VP9Context *s, int16_t *coef, int n_coeffs, - unsigned (*cnt)[6][3], unsigned (*eob)[6][2], - uint8_t (*p)[6][11], int nnz, const int16_t *scan, - const int16_t (*nb)[2], const int16_t *band_counts, - const int16_t *qmul) -{ - return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 0, 0, s->s.h.bpp, cnt, eob, p, - nnz, scan, nb, band_counts, qmul); -} - -static int decode_coeffs_b32_16bpp(VP9Context *s, int16_t *coef, int n_coeffs, - unsigned (*cnt)[6][3], unsigned (*eob)[6][2], - uint8_t (*p)[6][11], int nnz, const int16_t *scan, - const int16_t (*nb)[2], const int16_t *band_counts, - const int16_t *qmul) -{ - return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 1, 0, s->s.h.bpp, cnt, eob, p, - nnz, scan, nb, band_counts, qmul); -} - -static av_always_inline int decode_coeffs(AVCodecContext *ctx, int is8bitsperpixel) -{ - VP9Context *s = ctx->priv_data; - VP9Block *b = s->b; - int row = s->row, col = s->col; - uint8_t (*p)[6][11] = s->prob.coef[b->tx][0 /* y */][!b->intra]; - unsigned (*c)[6][3] = s->counts.coef[b->tx][0 /* y */][!b->intra]; - unsigned (*e)[6][2] = s->counts.eob[b->tx][0 /* y */][!b->intra]; - int w4 = bwh_tab[1][b->bs][0] << 1, h4 = bwh_tab[1][b->bs][1] << 1; - int end_x = FFMIN(2 * (s->cols - col), w4); - int end_y = FFMIN(2 * (s->rows - row), h4); - int n, pl, x, y, res; - int16_t (*qmul)[2] = s->s.h.segmentation.feat[b->seg_id].qmul; - int tx = 4 * s->s.h.lossless + b->tx; - const int16_t * const *yscans = vp9_scans[tx]; - const int16_t (* const *ynbs)[2] = vp9_scans_nb[tx]; - const int16_t *uvscan = vp9_scans[b->uvtx][DCT_DCT]; - const int16_t (*uvnb)[2] = vp9_scans_nb[b->uvtx][DCT_DCT]; - uint8_t *a = &s->above_y_nnz_ctx[col * 2]; - uint8_t *l = &s->left_y_nnz_ctx[(row & 7) << 1]; - static const int16_t band_counts[4][8] = { - { 1, 2, 3, 4, 3, 16 - 13 }, - { 1, 2, 3, 4, 11, 64 - 21 }, - { 1, 2, 3, 4, 11, 256 - 21 }, - { 1, 2, 3, 4, 11, 1024 - 21 }, - }; - const int16_t *y_band_counts = band_counts[b->tx]; - const int16_t *uv_band_counts = band_counts[b->uvtx]; - int bytesperpixel = is8bitsperpixel ? 1 : 2; - int total_coeff = 0; - -#define MERGE(la, end, step, rd) \ - for (n = 0; n < end; n += step) \ - la[n] = !!rd(&la[n]) -#define MERGE_CTX(step, rd) \ - do { \ - MERGE(l, end_y, step, rd); \ - MERGE(a, end_x, step, rd); \ - } while (0) - -#define DECODE_Y_COEF_LOOP(step, mode_index, v) \ - for (n = 0, y = 0; y < end_y; y += step) { \ - for (x = 0; x < end_x; x += step, n += step * step) { \ - enum TxfmType txtp = vp9_intra_txfm_type[b->mode[mode_index]]; \ - res = (is8bitsperpixel ? decode_coeffs_b##v##_8bpp : decode_coeffs_b##v##_16bpp) \ - (s, s->block + 16 * n * bytesperpixel, 16 * step * step, \ - c, e, p, a[x] + l[y], yscans[txtp], \ - ynbs[txtp], y_band_counts, qmul[0]); \ - a[x] = l[y] = !!res; \ - total_coeff |= !!res; \ - if (step >= 4) { \ - AV_WN16A(&s->eob[n], res); \ - } else { \ - s->eob[n] = res; \ - } \ - } \ - } - -#define SPLAT(la, end, step, cond) \ - if (step == 2) { \ - for (n = 1; n < end; n += step) \ - la[n] = la[n - 1]; \ - } else if (step == 4) { \ - if (cond) { \ - for (n = 0; n < end; n += step) \ - AV_WN32A(&la[n], la[n] * 0x01010101); \ - } else { \ - for (n = 0; n < end; n += step) \ - memset(&la[n + 1], la[n], FFMIN(end - n - 1, 3)); \ - } \ - } else /* step == 8 */ { \ - if (cond) { \ - if (HAVE_FAST_64BIT) { \ - for (n = 0; n < end; n += step) \ - AV_WN64A(&la[n], la[n] * 0x0101010101010101ULL); \ - } else { \ - for (n = 0; n < end; n += step) { \ - uint32_t v32 = la[n] * 0x01010101; \ - AV_WN32A(&la[n], v32); \ - AV_WN32A(&la[n + 4], v32); \ - } \ - } \ - } else { \ - for (n = 0; n < end; n += step) \ - memset(&la[n + 1], la[n], FFMIN(end - n - 1, 7)); \ - } \ - } -#define SPLAT_CTX(step) \ - do { \ - SPLAT(a, end_x, step, end_x == w4); \ - SPLAT(l, end_y, step, end_y == h4); \ - } while (0) - - /* y tokens */ - switch (b->tx) { - case TX_4X4: - DECODE_Y_COEF_LOOP(1, b->bs > BS_8x8 ? n : 0,); - break; - case TX_8X8: - MERGE_CTX(2, AV_RN16A); - DECODE_Y_COEF_LOOP(2, 0,); - SPLAT_CTX(2); - break; - case TX_16X16: - MERGE_CTX(4, AV_RN32A); - DECODE_Y_COEF_LOOP(4, 0,); - SPLAT_CTX(4); - break; - case TX_32X32: - MERGE_CTX(8, AV_RN64A); - DECODE_Y_COEF_LOOP(8, 0, 32); - SPLAT_CTX(8); - break; - } - -#define DECODE_UV_COEF_LOOP(step, v) \ - for (n = 0, y = 0; y < end_y; y += step) { \ - for (x = 0; x < end_x; x += step, n += step * step) { \ - res = (is8bitsperpixel ? decode_coeffs_b##v##_8bpp : decode_coeffs_b##v##_16bpp) \ - (s, s->uvblock[pl] + 16 * n * bytesperpixel, \ - 16 * step * step, c, e, p, a[x] + l[y], \ - uvscan, uvnb, uv_band_counts, qmul[1]); \ - a[x] = l[y] = !!res; \ - total_coeff |= !!res; \ - if (step >= 4) { \ - AV_WN16A(&s->uveob[pl][n], res); \ - } else { \ - s->uveob[pl][n] = res; \ - } \ - } \ - } - - p = s->prob.coef[b->uvtx][1 /* uv */][!b->intra]; - c = s->counts.coef[b->uvtx][1 /* uv */][!b->intra]; - e = s->counts.eob[b->uvtx][1 /* uv */][!b->intra]; - w4 >>= s->ss_h; - end_x >>= s->ss_h; - h4 >>= s->ss_v; - end_y >>= s->ss_v; - for (pl = 0; pl < 2; pl++) { - a = &s->above_uv_nnz_ctx[pl][col << !s->ss_h]; - l = &s->left_uv_nnz_ctx[pl][(row & 7) << !s->ss_v]; - switch (b->uvtx) { - case TX_4X4: - DECODE_UV_COEF_LOOP(1,); - break; - case TX_8X8: - MERGE_CTX(2, AV_RN16A); - DECODE_UV_COEF_LOOP(2,); - SPLAT_CTX(2); - break; - case TX_16X16: - MERGE_CTX(4, AV_RN32A); - DECODE_UV_COEF_LOOP(4,); - SPLAT_CTX(4); - break; - case TX_32X32: - MERGE_CTX(8, AV_RN64A); - DECODE_UV_COEF_LOOP(8, 32); - SPLAT_CTX(8); - break; - } - } - - return total_coeff; -} - -static int decode_coeffs_8bpp(AVCodecContext *ctx) -{ - return decode_coeffs(ctx, 1); -} - -static int decode_coeffs_16bpp(AVCodecContext *ctx) -{ - return decode_coeffs(ctx, 0); -} - -static av_always_inline int check_intra_mode(VP9Context *s, int mode, uint8_t **a, - uint8_t *dst_edge, ptrdiff_t stride_edge, - uint8_t *dst_inner, ptrdiff_t stride_inner, - uint8_t *l, int col, int x, int w, - int row, int y, enum TxfmMode tx, - int p, int ss_h, int ss_v, int bytesperpixel) -{ - int have_top = row > 0 || y > 0; - int have_left = col > s->tile_col_start || x > 0; - int have_right = x < w - 1; - int bpp = s->s.h.bpp; - static const uint8_t mode_conv[10][2 /* have_left */][2 /* have_top */] = { - [VERT_PRED] = { { DC_127_PRED, VERT_PRED }, - { DC_127_PRED, VERT_PRED } }, - [HOR_PRED] = { { DC_129_PRED, DC_129_PRED }, - { HOR_PRED, HOR_PRED } }, - [DC_PRED] = { { DC_128_PRED, TOP_DC_PRED }, - { LEFT_DC_PRED, DC_PRED } }, - [DIAG_DOWN_LEFT_PRED] = { { DC_127_PRED, DIAG_DOWN_LEFT_PRED }, - { DC_127_PRED, DIAG_DOWN_LEFT_PRED } }, - [DIAG_DOWN_RIGHT_PRED] = { { DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED }, - { DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED } }, - [VERT_RIGHT_PRED] = { { VERT_RIGHT_PRED, VERT_RIGHT_PRED }, - { VERT_RIGHT_PRED, VERT_RIGHT_PRED } }, - [HOR_DOWN_PRED] = { { HOR_DOWN_PRED, HOR_DOWN_PRED }, - { HOR_DOWN_PRED, HOR_DOWN_PRED } }, - [VERT_LEFT_PRED] = { { DC_127_PRED, VERT_LEFT_PRED }, - { DC_127_PRED, VERT_LEFT_PRED } }, - [HOR_UP_PRED] = { { DC_129_PRED, DC_129_PRED }, - { HOR_UP_PRED, HOR_UP_PRED } }, - [TM_VP8_PRED] = { { DC_129_PRED, VERT_PRED }, - { HOR_PRED, TM_VP8_PRED } }, - }; - static const struct { - uint8_t needs_left:1; - uint8_t needs_top:1; - uint8_t needs_topleft:1; - uint8_t needs_topright:1; - uint8_t invert_left:1; - } edges[N_INTRA_PRED_MODES] = { - [VERT_PRED] = { .needs_top = 1 }, - [HOR_PRED] = { .needs_left = 1 }, - [DC_PRED] = { .needs_top = 1, .needs_left = 1 }, - [DIAG_DOWN_LEFT_PRED] = { .needs_top = 1, .needs_topright = 1 }, - [DIAG_DOWN_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 }, - [VERT_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 }, - [HOR_DOWN_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 }, - [VERT_LEFT_PRED] = { .needs_top = 1, .needs_topright = 1 }, - [HOR_UP_PRED] = { .needs_left = 1, .invert_left = 1 }, - [TM_VP8_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 }, - [LEFT_DC_PRED] = { .needs_left = 1 }, - [TOP_DC_PRED] = { .needs_top = 1 }, - [DC_128_PRED] = { 0 }, - [DC_127_PRED] = { 0 }, - [DC_129_PRED] = { 0 } - }; - - av_assert2(mode >= 0 && mode < 10); - mode = mode_conv[mode][have_left][have_top]; - if (edges[mode].needs_top) { - uint8_t *top, *topleft; - int n_px_need = 4 << tx, n_px_have = (((s->cols - col) << !ss_h) - x) * 4; - int n_px_need_tr = 0; - - if (tx == TX_4X4 && edges[mode].needs_topright && have_right) - n_px_need_tr = 4; - - // if top of sb64-row, use s->intra_pred_data[] instead of - // dst[-stride] for intra prediction (it contains pre- instead of - // post-loopfilter data) - if (have_top) { - top = !(row & 7) && !y ? - s->intra_pred_data[p] + (col * (8 >> ss_h) + x * 4) * bytesperpixel : - y == 0 ? &dst_edge[-stride_edge] : &dst_inner[-stride_inner]; - if (have_left) - topleft = !(row & 7) && !y ? - s->intra_pred_data[p] + (col * (8 >> ss_h) + x * 4) * bytesperpixel : - y == 0 || x == 0 ? &dst_edge[-stride_edge] : - &dst_inner[-stride_inner]; - } - - if (have_top && - (!edges[mode].needs_topleft || (have_left && top == topleft)) && - (tx != TX_4X4 || !edges[mode].needs_topright || have_right) && - n_px_need + n_px_need_tr <= n_px_have) { - *a = top; - } else { - if (have_top) { - if (n_px_need <= n_px_have) { - memcpy(*a, top, n_px_need * bytesperpixel); - } else { -#define memset_bpp(c, i1, v, i2, num) do { \ - if (bytesperpixel == 1) { \ - memset(&(c)[(i1)], (v)[(i2)], (num)); \ - } else { \ - int n, val = AV_RN16A(&(v)[(i2) * 2]); \ - for (n = 0; n < (num); n++) { \ - AV_WN16A(&(c)[((i1) + n) * 2], val); \ - } \ - } \ -} while (0) - memcpy(*a, top, n_px_have * bytesperpixel); - memset_bpp(*a, n_px_have, (*a), n_px_have - 1, n_px_need - n_px_have); - } - } else { -#define memset_val(c, val, num) do { \ - if (bytesperpixel == 1) { \ - memset((c), (val), (num)); \ - } else { \ - int n; \ - for (n = 0; n < (num); n++) { \ - AV_WN16A(&(c)[n * 2], (val)); \ - } \ - } \ -} while (0) - memset_val(*a, (128 << (bpp - 8)) - 1, n_px_need); - } - if (edges[mode].needs_topleft) { - if (have_left && have_top) { -#define assign_bpp(c, i1, v, i2) do { \ - if (bytesperpixel == 1) { \ - (c)[(i1)] = (v)[(i2)]; \ - } else { \ - AV_COPY16(&(c)[(i1) * 2], &(v)[(i2) * 2]); \ - } \ -} while (0) - assign_bpp(*a, -1, topleft, -1); - } else { -#define assign_val(c, i, v) do { \ - if (bytesperpixel == 1) { \ - (c)[(i)] = (v); \ - } else { \ - AV_WN16A(&(c)[(i) * 2], (v)); \ - } \ -} while (0) - assign_val((*a), -1, (128 << (bpp - 8)) + (have_top ? +1 : -1)); - } - } - if (tx == TX_4X4 && edges[mode].needs_topright) { - if (have_top && have_right && - n_px_need + n_px_need_tr <= n_px_have) { - memcpy(&(*a)[4 * bytesperpixel], &top[4 * bytesperpixel], 4 * bytesperpixel); - } else { - memset_bpp(*a, 4, *a, 3, 4); - } - } - } - } - if (edges[mode].needs_left) { - if (have_left) { - int n_px_need = 4 << tx, i, n_px_have = (((s->rows - row) << !ss_v) - y) * 4; - uint8_t *dst = x == 0 ? dst_edge : dst_inner; - ptrdiff_t stride = x == 0 ? stride_edge : stride_inner; - - if (edges[mode].invert_left) { - if (n_px_need <= n_px_have) { - for (i = 0; i < n_px_need; i++) - assign_bpp(l, i, &dst[i * stride], -1); - } else { - for (i = 0; i < n_px_have; i++) - assign_bpp(l, i, &dst[i * stride], -1); - memset_bpp(l, n_px_have, l, n_px_have - 1, n_px_need - n_px_have); - } - } else { - if (n_px_need <= n_px_have) { - for (i = 0; i < n_px_need; i++) - assign_bpp(l, n_px_need - 1 - i, &dst[i * stride], -1); - } else { - for (i = 0; i < n_px_have; i++) - assign_bpp(l, n_px_need - 1 - i, &dst[i * stride], -1); - memset_bpp(l, 0, l, n_px_need - n_px_have, n_px_need - n_px_have); - } - } - } else { - memset_val(l, (128 << (bpp - 8)) + 1, 4 << tx); - } - } - - return mode; -} - -static av_always_inline void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off, - ptrdiff_t uv_off, int bytesperpixel) -{ - VP9Context *s = ctx->priv_data; - VP9Block *b = s->b; - int row = s->row, col = s->col; - int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n; - int h4 = bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2); - int end_x = FFMIN(2 * (s->cols - col), w4); - int end_y = FFMIN(2 * (s->rows - row), h4); - int tx = 4 * s->s.h.lossless + b->tx, uvtx = b->uvtx + 4 * s->s.h.lossless; - int uvstep1d = 1 << b->uvtx, p; - uint8_t *dst = s->dst[0], *dst_r = s->s.frames[CUR_FRAME].tf.f->data[0] + y_off; - LOCAL_ALIGNED_32(uint8_t, a_buf, [96]); - LOCAL_ALIGNED_32(uint8_t, l, [64]); - - for (n = 0, y = 0; y < end_y; y += step1d) { - uint8_t *ptr = dst, *ptr_r = dst_r; - for (x = 0; x < end_x; x += step1d, ptr += 4 * step1d * bytesperpixel, - ptr_r += 4 * step1d * bytesperpixel, n += step) { - int mode = b->mode[b->bs > BS_8x8 && b->tx == TX_4X4 ? - y * 2 + x : 0]; - uint8_t *a = &a_buf[32]; - enum TxfmType txtp = vp9_intra_txfm_type[mode]; - int eob = b->skip ? 0 : b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n]; - - mode = check_intra_mode(s, mode, &a, ptr_r, - s->s.frames[CUR_FRAME].tf.f->linesize[0], - ptr, s->y_stride, l, - col, x, w4, row, y, b->tx, 0, 0, 0, bytesperpixel); - s->dsp.intra_pred[b->tx][mode](ptr, s->y_stride, l, a); - if (eob) - s->dsp.itxfm_add[tx][txtp](ptr, s->y_stride, - s->block + 16 * n * bytesperpixel, eob); - } - dst_r += 4 * step1d * s->s.frames[CUR_FRAME].tf.f->linesize[0]; - dst += 4 * step1d * s->y_stride; - } - - // U/V - w4 >>= s->ss_h; - end_x >>= s->ss_h; - end_y >>= s->ss_v; - step = 1 << (b->uvtx * 2); - for (p = 0; p < 2; p++) { - dst = s->dst[1 + p]; - dst_r = s->s.frames[CUR_FRAME].tf.f->data[1 + p] + uv_off; - for (n = 0, y = 0; y < end_y; y += uvstep1d) { - uint8_t *ptr = dst, *ptr_r = dst_r; - for (x = 0; x < end_x; x += uvstep1d, ptr += 4 * uvstep1d * bytesperpixel, - ptr_r += 4 * uvstep1d * bytesperpixel, n += step) { - int mode = b->uvmode; - uint8_t *a = &a_buf[32]; - int eob = b->skip ? 0 : b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n]; - - mode = check_intra_mode(s, mode, &a, ptr_r, - s->s.frames[CUR_FRAME].tf.f->linesize[1], - ptr, s->uv_stride, l, col, x, w4, row, y, - b->uvtx, p + 1, s->ss_h, s->ss_v, bytesperpixel); - s->dsp.intra_pred[b->uvtx][mode](ptr, s->uv_stride, l, a); - if (eob) - s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride, - s->uvblock[p] + 16 * n * bytesperpixel, eob); - } - dst_r += 4 * uvstep1d * s->s.frames[CUR_FRAME].tf.f->linesize[1]; - dst += 4 * uvstep1d * s->uv_stride; - } - } -} - -static void intra_recon_8bpp(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off) -{ - intra_recon(ctx, y_off, uv_off, 1); -} - -static void intra_recon_16bpp(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off) -{ - intra_recon(ctx, y_off, uv_off, 2); -} - -static av_always_inline void mc_luma_unscaled(VP9Context *s, vp9_mc_func (*mc)[2], - uint8_t *dst, ptrdiff_t dst_stride, - const uint8_t *ref, ptrdiff_t ref_stride, - ThreadFrame *ref_frame, - ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, - int bw, int bh, int w, int h, int bytesperpixel) -{ - int mx = mv->x, my = mv->y, th; - - y += my >> 3; - x += mx >> 3; - ref += y * ref_stride + x * bytesperpixel; - mx &= 7; - my &= 7; - // FIXME bilinear filter only needs 0/1 pixels, not 3/4 - // we use +7 because the last 7 pixels of each sbrow can be changed in - // the longest loopfilter of the next sbrow - th = (y + bh + 4 * !!my + 7) >> 6; - ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); - // The arm/aarch64 _hv filters read one more row than what actually is - // needed, so switch to emulated edge one pixel sooner vertically - // (!!my * 5) than horizontally (!!mx * 4). - if (x < !!mx * 3 || y < !!my * 3 || - x + !!mx * 4 > w - bw || y + !!my * 5 > h - bh) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, - ref - !!my * 3 * ref_stride - !!mx * 3 * bytesperpixel, - 160, ref_stride, - bw + !!mx * 7, bh + !!my * 7, - x - !!mx * 3, y - !!my * 3, w, h); - ref = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; - ref_stride = 160; - } - mc[!!mx][!!my](dst, dst_stride, ref, ref_stride, bh, mx << 1, my << 1); -} - -static av_always_inline void mc_chroma_unscaled(VP9Context *s, vp9_mc_func (*mc)[2], - uint8_t *dst_u, uint8_t *dst_v, - ptrdiff_t dst_stride, - const uint8_t *ref_u, ptrdiff_t src_stride_u, - const uint8_t *ref_v, ptrdiff_t src_stride_v, - ThreadFrame *ref_frame, - ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, - int bw, int bh, int w, int h, int bytesperpixel) -{ - int mx = mv->x * (1 << !s->ss_h), my = mv->y * (1 << !s->ss_v), th; - - y += my >> 4; - x += mx >> 4; - ref_u += y * src_stride_u + x * bytesperpixel; - ref_v += y * src_stride_v + x * bytesperpixel; - mx &= 15; - my &= 15; - // FIXME bilinear filter only needs 0/1 pixels, not 3/4 - // we use +7 because the last 7 pixels of each sbrow can be changed in - // the longest loopfilter of the next sbrow - th = (y + bh + 4 * !!my + 7) >> (6 - s->ss_v); - ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); - // The arm/aarch64 _hv filters read one more row than what actually is - // needed, so switch to emulated edge one pixel sooner vertically - // (!!my * 5) than horizontally (!!mx * 4). - if (x < !!mx * 3 || y < !!my * 3 || - x + !!mx * 4 > w - bw || y + !!my * 5 > h - bh) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, - ref_u - !!my * 3 * src_stride_u - !!mx * 3 * bytesperpixel, - 160, src_stride_u, - bw + !!mx * 7, bh + !!my * 7, - x - !!mx * 3, y - !!my * 3, w, h); - ref_u = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; - mc[!!mx][!!my](dst_u, dst_stride, ref_u, 160, bh, mx, my); - - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, - ref_v - !!my * 3 * src_stride_v - !!mx * 3 * bytesperpixel, - 160, src_stride_v, - bw + !!mx * 7, bh + !!my * 7, - x - !!mx * 3, y - !!my * 3, w, h); - ref_v = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; - mc[!!mx][!!my](dst_v, dst_stride, ref_v, 160, bh, mx, my); - } else { - mc[!!mx][!!my](dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my); - mc[!!mx][!!my](dst_v, dst_stride, ref_v, src_stride_v, bh, mx, my); - } -} - -#define mc_luma_dir(s, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ - px, py, pw, ph, bw, bh, w, h, i) \ - mc_luma_unscaled(s, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ - mv, bw, bh, w, h, bytesperpixel) -#define mc_chroma_dir(s, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ - row, col, mv, px, py, pw, ph, bw, bh, w, h, i) \ - mc_chroma_unscaled(s, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ - row, col, mv, bw, bh, w, h, bytesperpixel) -#define SCALED 0 -#define FN(x) x##_8bpp -#define BYTES_PER_PIXEL 1 -#include "vp9_mc_template.c" -#undef FN -#undef BYTES_PER_PIXEL -#define FN(x) x##_16bpp -#define BYTES_PER_PIXEL 2 -#include "vp9_mc_template.c" -#undef mc_luma_dir -#undef mc_chroma_dir -#undef FN -#undef BYTES_PER_PIXEL -#undef SCALED - -static av_always_inline void mc_luma_scaled(VP9Context *s, vp9_scaled_mc_func smc, - vp9_mc_func (*mc)[2], - uint8_t *dst, ptrdiff_t dst_stride, - const uint8_t *ref, ptrdiff_t ref_stride, - ThreadFrame *ref_frame, - ptrdiff_t y, ptrdiff_t x, const VP56mv *in_mv, - int px, int py, int pw, int ph, - int bw, int bh, int w, int h, int bytesperpixel, - const uint16_t *scale, const uint8_t *step) -{ - if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width && - s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) { - mc_luma_unscaled(s, mc, dst, dst_stride, ref, ref_stride, ref_frame, - y, x, in_mv, bw, bh, w, h, bytesperpixel); - } else { -#define scale_mv(n, dim) (((int64_t)(n) * scale[dim]) >> 14) - int mx, my; - int refbw_m1, refbh_m1; - int th; - VP56mv mv; - - mv.x = av_clip(in_mv->x, -(x + pw - px + 4) * 8, (s->cols * 8 - x + px + 3) * 8); - mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 8, (s->rows * 8 - y + py + 3) * 8); - // BUG libvpx seems to scale the two components separately. This introduces - // rounding errors but we have to reproduce them to be exactly compatible - // with the output from libvpx... - mx = scale_mv(mv.x * 2, 0) + scale_mv(x * 16, 0); - my = scale_mv(mv.y * 2, 1) + scale_mv(y * 16, 1); - - y = my >> 4; - x = mx >> 4; - ref += y * ref_stride + x * bytesperpixel; - mx &= 15; - my &= 15; - refbw_m1 = ((bw - 1) * step[0] + mx) >> 4; - refbh_m1 = ((bh - 1) * step[1] + my) >> 4; - // FIXME bilinear filter only needs 0/1 pixels, not 3/4 - // we use +7 because the last 7 pixels of each sbrow can be changed in - // the longest loopfilter of the next sbrow - th = (y + refbh_m1 + 4 + 7) >> 6; - ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); - // The arm/aarch64 _hv filters read one more row than what actually is - // needed, so switch to emulated edge one pixel sooner vertically - // (y + 5 >= h - refbh_m1) than horizontally (x + 4 >= w - refbw_m1). - if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 5 >= h - refbh_m1) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, - ref - 3 * ref_stride - 3 * bytesperpixel, - 288, ref_stride, - refbw_m1 + 8, refbh_m1 + 8, - x - 3, y - 3, w, h); - ref = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; - ref_stride = 288; - } - smc(dst, dst_stride, ref, ref_stride, bh, mx, my, step[0], step[1]); - } -} - -static av_always_inline void mc_chroma_scaled(VP9Context *s, vp9_scaled_mc_func smc, - vp9_mc_func (*mc)[2], - uint8_t *dst_u, uint8_t *dst_v, - ptrdiff_t dst_stride, - const uint8_t *ref_u, ptrdiff_t src_stride_u, - const uint8_t *ref_v, ptrdiff_t src_stride_v, - ThreadFrame *ref_frame, - ptrdiff_t y, ptrdiff_t x, const VP56mv *in_mv, - int px, int py, int pw, int ph, - int bw, int bh, int w, int h, int bytesperpixel, - const uint16_t *scale, const uint8_t *step) -{ - if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width && - s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) { - mc_chroma_unscaled(s, mc, dst_u, dst_v, dst_stride, ref_u, src_stride_u, - ref_v, src_stride_v, ref_frame, - y, x, in_mv, bw, bh, w, h, bytesperpixel); - } else { - int mx, my; - int refbw_m1, refbh_m1; - int th; - VP56mv mv; - - if (s->ss_h) { - // BUG https://code.google.com/p/webm/issues/detail?id=820 - mv.x = av_clip(in_mv->x, -(x + pw - px + 4) * 16, (s->cols * 4 - x + px + 3) * 16); - mx = scale_mv(mv.x, 0) + (scale_mv(x * 16, 0) & ~15) + (scale_mv(x * 32, 0) & 15); - } else { - mv.x = av_clip(in_mv->x, -(x + pw - px + 4) * 8, (s->cols * 8 - x + px + 3) * 8); - mx = scale_mv(mv.x * 2, 0) + scale_mv(x * 16, 0); - } - if (s->ss_v) { - // BUG https://code.google.com/p/webm/issues/detail?id=820 - mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 16, (s->rows * 4 - y + py + 3) * 16); - my = scale_mv(mv.y, 1) + (scale_mv(y * 16, 1) & ~15) + (scale_mv(y * 32, 1) & 15); - } else { - mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 8, (s->rows * 8 - y + py + 3) * 8); - my = scale_mv(mv.y * 2, 1) + scale_mv(y * 16, 1); - } -#undef scale_mv - y = my >> 4; - x = mx >> 4; - ref_u += y * src_stride_u + x * bytesperpixel; - ref_v += y * src_stride_v + x * bytesperpixel; - mx &= 15; - my &= 15; - refbw_m1 = ((bw - 1) * step[0] + mx) >> 4; - refbh_m1 = ((bh - 1) * step[1] + my) >> 4; - // FIXME bilinear filter only needs 0/1 pixels, not 3/4 - // we use +7 because the last 7 pixels of each sbrow can be changed in - // the longest loopfilter of the next sbrow - th = (y + refbh_m1 + 4 + 7) >> (6 - s->ss_v); - ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); - // The arm/aarch64 _hv filters read one more row than what actually is - // needed, so switch to emulated edge one pixel sooner vertically - // (y + 5 >= h - refbh_m1) than horizontally (x + 4 >= w - refbw_m1). - if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 5 >= h - refbh_m1) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, - ref_u - 3 * src_stride_u - 3 * bytesperpixel, - 288, src_stride_u, - refbw_m1 + 8, refbh_m1 + 8, - x - 3, y - 3, w, h); - ref_u = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; - smc(dst_u, dst_stride, ref_u, 288, bh, mx, my, step[0], step[1]); - - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, - ref_v - 3 * src_stride_v - 3 * bytesperpixel, - 288, src_stride_v, - refbw_m1 + 8, refbh_m1 + 8, - x - 3, y - 3, w, h); - ref_v = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; - smc(dst_v, dst_stride, ref_v, 288, bh, mx, my, step[0], step[1]); - } else { - smc(dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my, step[0], step[1]); - smc(dst_v, dst_stride, ref_v, src_stride_v, bh, mx, my, step[0], step[1]); - } - } -} - -#define mc_luma_dir(s, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ - px, py, pw, ph, bw, bh, w, h, i) \ - mc_luma_scaled(s, s->dsp.s##mc, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ - mv, px, py, pw, ph, bw, bh, w, h, bytesperpixel, \ - s->mvscale[b->ref[i]], s->mvstep[b->ref[i]]) -#define mc_chroma_dir(s, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ - row, col, mv, px, py, pw, ph, bw, bh, w, h, i) \ - mc_chroma_scaled(s, s->dsp.s##mc, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ - row, col, mv, px, py, pw, ph, bw, bh, w, h, bytesperpixel, \ - s->mvscale[b->ref[i]], s->mvstep[b->ref[i]]) -#define SCALED 1 -#define FN(x) x##_scaled_8bpp -#define BYTES_PER_PIXEL 1 -#include "vp9_mc_template.c" -#undef FN -#undef BYTES_PER_PIXEL -#define FN(x) x##_scaled_16bpp -#define BYTES_PER_PIXEL 2 -#include "vp9_mc_template.c" -#undef mc_luma_dir -#undef mc_chroma_dir -#undef FN -#undef BYTES_PER_PIXEL -#undef SCALED - -static av_always_inline void inter_recon(AVCodecContext *ctx, int bytesperpixel) -{ - VP9Context *s = ctx->priv_data; - VP9Block *b = s->b; - int row = s->row, col = s->col; - - if (s->mvscale[b->ref[0]][0] || (b->comp && s->mvscale[b->ref[1]][0])) { - if (bytesperpixel == 1) { - inter_pred_scaled_8bpp(ctx); - } else { - inter_pred_scaled_16bpp(ctx); - } - } else { - if (bytesperpixel == 1) { - inter_pred_8bpp(ctx); - } else { - inter_pred_16bpp(ctx); - } - } - if (!b->skip) { - /* mostly copied intra_recon() */ - - int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n; - int h4 = bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2); - int end_x = FFMIN(2 * (s->cols - col), w4); - int end_y = FFMIN(2 * (s->rows - row), h4); - int tx = 4 * s->s.h.lossless + b->tx, uvtx = b->uvtx + 4 * s->s.h.lossless; - int uvstep1d = 1 << b->uvtx, p; - uint8_t *dst = s->dst[0]; - - // y itxfm add - for (n = 0, y = 0; y < end_y; y += step1d) { - uint8_t *ptr = dst; - for (x = 0; x < end_x; x += step1d, - ptr += 4 * step1d * bytesperpixel, n += step) { - int eob = b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n]; - - if (eob) - s->dsp.itxfm_add[tx][DCT_DCT](ptr, s->y_stride, - s->block + 16 * n * bytesperpixel, eob); - } - dst += 4 * s->y_stride * step1d; - } - - // uv itxfm add - end_x >>= s->ss_h; - end_y >>= s->ss_v; - step = 1 << (b->uvtx * 2); - for (p = 0; p < 2; p++) { - dst = s->dst[p + 1]; - for (n = 0, y = 0; y < end_y; y += uvstep1d) { - uint8_t *ptr = dst; - for (x = 0; x < end_x; x += uvstep1d, - ptr += 4 * uvstep1d * bytesperpixel, n += step) { - int eob = b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n]; - - if (eob) - s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride, - s->uvblock[p] + 16 * n * bytesperpixel, eob); - } - dst += 4 * uvstep1d * s->uv_stride; - } - } - } -} - -static void inter_recon_8bpp(AVCodecContext *ctx) -{ - inter_recon(ctx, 1); -} - -static void inter_recon_16bpp(AVCodecContext *ctx) -{ - inter_recon(ctx, 2); -} - -static av_always_inline void mask_edges(uint8_t (*mask)[8][4], int ss_h, int ss_v, - int row_and_7, int col_and_7, - int w, int h, int col_end, int row_end, - enum TxfmMode tx, int skip_inter) -{ - static const unsigned wide_filter_col_mask[2] = { 0x11, 0x01 }; - static const unsigned wide_filter_row_mask[2] = { 0x03, 0x07 }; - - // FIXME I'm pretty sure all loops can be replaced by a single LUT if - // we make VP9Filter.mask uint64_t (i.e. row/col all single variable) - // and make the LUT 5-indexed (bl, bp, is_uv, tx and row/col), and then - // use row_and_7/col_and_7 as shifts (1*col_and_7+8*row_and_7) - - // the intended behaviour of the vp9 loopfilter is to work on 8-pixel - // edges. This means that for UV, we work on two subsampled blocks at - // a time, and we only use the topleft block's mode information to set - // things like block strength. Thus, for any block size smaller than - // 16x16, ignore the odd portion of the block. - if (tx == TX_4X4 && (ss_v | ss_h)) { - if (h == ss_v) { - if (row_and_7 & 1) - return; - if (!row_end) - h += 1; - } - if (w == ss_h) { - if (col_and_7 & 1) - return; - if (!col_end) - w += 1; - } - } - - if (tx == TX_4X4 && !skip_inter) { - int t = 1 << col_and_7, m_col = (t << w) - t, y; - // on 32-px edges, use the 8-px wide loopfilter; else, use 4-px wide - int m_row_8 = m_col & wide_filter_col_mask[ss_h], m_row_4 = m_col - m_row_8; - - for (y = row_and_7; y < h + row_and_7; y++) { - int col_mask_id = 2 - !(y & wide_filter_row_mask[ss_v]); - - mask[0][y][1] |= m_row_8; - mask[0][y][2] |= m_row_4; - // for odd lines, if the odd col is not being filtered, - // skip odd row also: - // .---. <-- a - // | | - // |___| <-- b - // ^ ^ - // c d - // - // if a/c are even row/col and b/d are odd, and d is skipped, - // e.g. right edge of size-66x66.webm, then skip b also (bug) - if ((ss_h & ss_v) && (col_end & 1) && (y & 1)) { - mask[1][y][col_mask_id] |= (t << (w - 1)) - t; - } else { - mask[1][y][col_mask_id] |= m_col; - } - if (!ss_h) - mask[0][y][3] |= m_col; - if (!ss_v) { - if (ss_h && (col_end & 1)) - mask[1][y][3] |= (t << (w - 1)) - t; - else - mask[1][y][3] |= m_col; - } - } - } else { - int y, t = 1 << col_and_7, m_col = (t << w) - t; - - if (!skip_inter) { - int mask_id = (tx == TX_8X8); - static const unsigned masks[4] = { 0xff, 0x55, 0x11, 0x01 }; - int l2 = tx + ss_h - 1, step1d; - int m_row = m_col & masks[l2]; - - // at odd UV col/row edges tx16/tx32 loopfilter edges, force - // 8wd loopfilter to prevent going off the visible edge. - if (ss_h && tx > TX_8X8 && (w ^ (w - 1)) == 1) { - int m_row_16 = ((t << (w - 1)) - t) & masks[l2]; - int m_row_8 = m_row - m_row_16; - - for (y = row_and_7; y < h + row_and_7; y++) { - mask[0][y][0] |= m_row_16; - mask[0][y][1] |= m_row_8; - } - } else { - for (y = row_and_7; y < h + row_and_7; y++) - mask[0][y][mask_id] |= m_row; - } - - l2 = tx + ss_v - 1; - step1d = 1 << l2; - if (ss_v && tx > TX_8X8 && (h ^ (h - 1)) == 1) { - for (y = row_and_7; y < h + row_and_7 - 1; y += step1d) - mask[1][y][0] |= m_col; - if (y - row_and_7 == h - 1) - mask[1][y][1] |= m_col; - } else { - for (y = row_and_7; y < h + row_and_7; y += step1d) - mask[1][y][mask_id] |= m_col; - } - } else if (tx != TX_4X4) { - int mask_id; - - mask_id = (tx == TX_8X8) || (h == ss_v); - mask[1][row_and_7][mask_id] |= m_col; - mask_id = (tx == TX_8X8) || (w == ss_h); - for (y = row_and_7; y < h + row_and_7; y++) - mask[0][y][mask_id] |= t; - } else { - int t8 = t & wide_filter_col_mask[ss_h], t4 = t - t8; - - for (y = row_and_7; y < h + row_and_7; y++) { - mask[0][y][2] |= t4; - mask[0][y][1] |= t8; - } - mask[1][row_and_7][2 - !(row_and_7 & wide_filter_row_mask[ss_v])] |= m_col; - } - } -} - -static void decode_b(AVCodecContext *ctx, int row, int col, - struct VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, - enum BlockLevel bl, enum BlockPartition bp) -{ - VP9Context *s = ctx->priv_data; - VP9Block *b = s->b; - enum BlockSize bs = bl * 3 + bp; - int bytesperpixel = s->bytesperpixel; - int w4 = bwh_tab[1][bs][0], h4 = bwh_tab[1][bs][1], lvl; - int emu[2]; - AVFrame *f = s->s.frames[CUR_FRAME].tf.f; - - s->row = row; - s->row7 = row & 7; - s->col = col; - s->col7 = col & 7; - s->min_mv.x = -(128 + col * 64); - s->min_mv.y = -(128 + row * 64); - s->max_mv.x = 128 + (s->cols - col - w4) * 64; - s->max_mv.y = 128 + (s->rows - row - h4) * 64; - if (s->pass < 2) { - b->bs = bs; - b->bl = bl; - b->bp = bp; - decode_mode(ctx); - b->uvtx = b->tx - ((s->ss_h && w4 * 2 == (1 << b->tx)) || - (s->ss_v && h4 * 2 == (1 << b->tx))); - - if (!b->skip) { - int has_coeffs; - - if (bytesperpixel == 1) { - has_coeffs = decode_coeffs_8bpp(ctx); - } else { - has_coeffs = decode_coeffs_16bpp(ctx); - } - if (!has_coeffs && b->bs <= BS_8x8 && !b->intra) { - b->skip = 1; - memset(&s->above_skip_ctx[col], 1, w4); - memset(&s->left_skip_ctx[s->row7], 1, h4); - } - } else { - int row7 = s->row7; - -#define SPLAT_ZERO_CTX(v, n) \ - switch (n) { \ - case 1: v = 0; break; \ - case 2: AV_ZERO16(&v); break; \ - case 4: AV_ZERO32(&v); break; \ - case 8: AV_ZERO64(&v); break; \ - case 16: AV_ZERO128(&v); break; \ - } -#define SPLAT_ZERO_YUV(dir, var, off, n, dir2) \ - do { \ - SPLAT_ZERO_CTX(s->dir##_y_##var[off * 2], n * 2); \ - if (s->ss_##dir2) { \ - SPLAT_ZERO_CTX(s->dir##_uv_##var[0][off], n); \ - SPLAT_ZERO_CTX(s->dir##_uv_##var[1][off], n); \ - } else { \ - SPLAT_ZERO_CTX(s->dir##_uv_##var[0][off * 2], n * 2); \ - SPLAT_ZERO_CTX(s->dir##_uv_##var[1][off * 2], n * 2); \ - } \ - } while (0) - - switch (w4) { - case 1: SPLAT_ZERO_YUV(above, nnz_ctx, col, 1, h); break; - case 2: SPLAT_ZERO_YUV(above, nnz_ctx, col, 2, h); break; - case 4: SPLAT_ZERO_YUV(above, nnz_ctx, col, 4, h); break; - case 8: SPLAT_ZERO_YUV(above, nnz_ctx, col, 8, h); break; - } - switch (h4) { - case 1: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 1, v); break; - case 2: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 2, v); break; - case 4: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 4, v); break; - case 8: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 8, v); break; - } - } - - if (s->pass == 1) { - s->b++; - s->block += w4 * h4 * 64 * bytesperpixel; - s->uvblock[0] += w4 * h4 * 64 * bytesperpixel >> (s->ss_h + s->ss_v); - s->uvblock[1] += w4 * h4 * 64 * bytesperpixel >> (s->ss_h + s->ss_v); - s->eob += 4 * w4 * h4; - s->uveob[0] += 4 * w4 * h4 >> (s->ss_h + s->ss_v); - s->uveob[1] += 4 * w4 * h4 >> (s->ss_h + s->ss_v); - - return; - } - } - - // emulated overhangs if the stride of the target buffer can't hold. This - // makes it possible to support emu-edge and so on even if we have large block - // overhangs - emu[0] = (col + w4) * 8 * bytesperpixel > f->linesize[0] || - (row + h4) > s->rows; - emu[1] = ((col + w4) * 8 >> s->ss_h) * bytesperpixel > f->linesize[1] || - (row + h4) > s->rows; - if (emu[0]) { - s->dst[0] = s->tmp_y; - s->y_stride = 128; - } else { - s->dst[0] = f->data[0] + yoff; - s->y_stride = f->linesize[0]; - } - if (emu[1]) { - s->dst[1] = s->tmp_uv[0]; - s->dst[2] = s->tmp_uv[1]; - s->uv_stride = 128; - } else { - s->dst[1] = f->data[1] + uvoff; - s->dst[2] = f->data[2] + uvoff; - s->uv_stride = f->linesize[1]; - } - if (b->intra) { - if (s->s.h.bpp > 8) { - intra_recon_16bpp(ctx, yoff, uvoff); - } else { - intra_recon_8bpp(ctx, yoff, uvoff); - } - } else { - if (s->s.h.bpp > 8) { - inter_recon_16bpp(ctx); - } else { - inter_recon_8bpp(ctx); - } - } - if (emu[0]) { - int w = FFMIN(s->cols - col, w4) * 8, h = FFMIN(s->rows - row, h4) * 8, n, o = 0; - - for (n = 0; o < w; n++) { - int bw = 64 >> n; - - av_assert2(n <= 4); - if (w & bw) { - s->dsp.mc[n][0][0][0][0](f->data[0] + yoff + o * bytesperpixel, f->linesize[0], - s->tmp_y + o * bytesperpixel, 128, h, 0, 0); - o += bw; - } - } - } - if (emu[1]) { - int w = FFMIN(s->cols - col, w4) * 8 >> s->ss_h; - int h = FFMIN(s->rows - row, h4) * 8 >> s->ss_v, n, o = 0; - - for (n = s->ss_h; o < w; n++) { - int bw = 64 >> n; - - av_assert2(n <= 4); - if (w & bw) { - s->dsp.mc[n][0][0][0][0](f->data[1] + uvoff + o * bytesperpixel, f->linesize[1], - s->tmp_uv[0] + o * bytesperpixel, 128, h, 0, 0); - s->dsp.mc[n][0][0][0][0](f->data[2] + uvoff + o * bytesperpixel, f->linesize[2], - s->tmp_uv[1] + o * bytesperpixel, 128, h, 0, 0); - o += bw; - } - } - } - - // pick filter level and find edges to apply filter to - if (s->s.h.filter.level && - (lvl = s->s.h.segmentation.feat[b->seg_id].lflvl[b->intra ? 0 : b->ref[0] + 1] - [b->mode[3] != ZEROMV]) > 0) { - int x_end = FFMIN(s->cols - col, w4), y_end = FFMIN(s->rows - row, h4); - int skip_inter = !b->intra && b->skip, col7 = s->col7, row7 = s->row7; - - setctx_2d(&lflvl->level[row7 * 8 + col7], w4, h4, 8, lvl); - mask_edges(lflvl->mask[0], 0, 0, row7, col7, x_end, y_end, 0, 0, b->tx, skip_inter); - if (s->ss_h || s->ss_v) - mask_edges(lflvl->mask[1], s->ss_h, s->ss_v, row7, col7, x_end, y_end, - s->cols & 1 && col + w4 >= s->cols ? s->cols & 7 : 0, - s->rows & 1 && row + h4 >= s->rows ? s->rows & 7 : 0, - b->uvtx, skip_inter); - - if (!s->filter_lut.lim_lut[lvl]) { - int sharp = s->s.h.filter.sharpness; - int limit = lvl; - - if (sharp > 0) { - limit >>= (sharp + 3) >> 2; - limit = FFMIN(limit, 9 - sharp); - } - limit = FFMAX(limit, 1); - - s->filter_lut.lim_lut[lvl] = limit; - s->filter_lut.mblim_lut[lvl] = 2 * (lvl + 2) + limit; - } - } - - if (s->pass == 2) { - s->b++; - s->block += w4 * h4 * 64 * bytesperpixel; - s->uvblock[0] += w4 * h4 * 64 * bytesperpixel >> (s->ss_v + s->ss_h); - s->uvblock[1] += w4 * h4 * 64 * bytesperpixel >> (s->ss_v + s->ss_h); - s->eob += 4 * w4 * h4; - s->uveob[0] += 4 * w4 * h4 >> (s->ss_v + s->ss_h); - s->uveob[1] += 4 * w4 * h4 >> (s->ss_v + s->ss_h); - } -} - -static void decode_sb(AVCodecContext *ctx, int row, int col, struct VP9Filter *lflvl, - ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl) -{ - VP9Context *s = ctx->priv_data; - int c = ((s->above_partition_ctx[col] >> (3 - bl)) & 1) | - (((s->left_partition_ctx[row & 0x7] >> (3 - bl)) & 1) << 1); - const uint8_t *p = s->s.h.keyframe || s->s.h.intraonly ? vp9_default_kf_partition_probs[bl][c] : - s->prob.p.partition[bl][c]; - enum BlockPartition bp; - ptrdiff_t hbs = 4 >> bl; - AVFrame *f = s->s.frames[CUR_FRAME].tf.f; - ptrdiff_t y_stride = f->linesize[0], uv_stride = f->linesize[1]; - int bytesperpixel = s->bytesperpixel; - - if (bl == BL_8X8) { - bp = vp8_rac_get_tree(&s->c, vp9_partition_tree, p); - decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp); - } else if (col + hbs < s->cols) { // FIXME why not <=? - if (row + hbs < s->rows) { // FIXME why not <=? - bp = vp8_rac_get_tree(&s->c, vp9_partition_tree, p); - switch (bp) { - case PARTITION_NONE: - decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp); - break; - case PARTITION_H: - decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp); - yoff += hbs * 8 * y_stride; - uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_b(ctx, row + hbs, col, lflvl, yoff, uvoff, bl, bp); - break; - case PARTITION_V: - decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp); - yoff += hbs * 8 * bytesperpixel; - uvoff += hbs * 8 * bytesperpixel >> s->ss_h; - decode_b(ctx, row, col + hbs, lflvl, yoff, uvoff, bl, bp); - break; - case PARTITION_SPLIT: - decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1); - decode_sb(ctx, row, col + hbs, lflvl, - yoff + 8 * hbs * bytesperpixel, - uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); - yoff += hbs * 8 * y_stride; - uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_sb(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); - decode_sb(ctx, row + hbs, col + hbs, lflvl, - yoff + 8 * hbs * bytesperpixel, - uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); - break; - default: - av_assert0(0); - } - } else if (vp56_rac_get_prob_branchy(&s->c, p[1])) { - bp = PARTITION_SPLIT; - decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1); - decode_sb(ctx, row, col + hbs, lflvl, - yoff + 8 * hbs * bytesperpixel, - uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); - } else { - bp = PARTITION_H; - decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp); - } - } else if (row + hbs < s->rows) { // FIXME why not <=? - if (vp56_rac_get_prob_branchy(&s->c, p[2])) { - bp = PARTITION_SPLIT; - decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1); - yoff += hbs * 8 * y_stride; - uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_sb(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); - } else { - bp = PARTITION_V; - decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp); - } - } else { - bp = PARTITION_SPLIT; - decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1); - } - s->counts.partition[bl][c][bp]++; -} - -static void decode_sb_mem(AVCodecContext *ctx, int row, int col, struct VP9Filter *lflvl, - ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl) -{ - VP9Context *s = ctx->priv_data; - VP9Block *b = s->b; - ptrdiff_t hbs = 4 >> bl; - AVFrame *f = s->s.frames[CUR_FRAME].tf.f; - ptrdiff_t y_stride = f->linesize[0], uv_stride = f->linesize[1]; - int bytesperpixel = s->bytesperpixel; - - if (bl == BL_8X8) { - av_assert2(b->bl == BL_8X8); - decode_b(ctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp); - } else if (s->b->bl == bl) { - decode_b(ctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp); - if (b->bp == PARTITION_H && row + hbs < s->rows) { - yoff += hbs * 8 * y_stride; - uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_b(ctx, row + hbs, col, lflvl, yoff, uvoff, b->bl, b->bp); - } else if (b->bp == PARTITION_V && col + hbs < s->cols) { - yoff += hbs * 8 * bytesperpixel; - uvoff += hbs * 8 * bytesperpixel >> s->ss_h; - decode_b(ctx, row, col + hbs, lflvl, yoff, uvoff, b->bl, b->bp); - } - } else { - decode_sb_mem(ctx, row, col, lflvl, yoff, uvoff, bl + 1); - if (col + hbs < s->cols) { // FIXME why not <=? - if (row + hbs < s->rows) { - decode_sb_mem(ctx, row, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel, - uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); - yoff += hbs * 8 * y_stride; - uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_sb_mem(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); - decode_sb_mem(ctx, row + hbs, col + hbs, lflvl, - yoff + 8 * hbs * bytesperpixel, - uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); - } else { - yoff += hbs * 8 * bytesperpixel; - uvoff += hbs * 8 * bytesperpixel >> s->ss_h; - decode_sb_mem(ctx, row, col + hbs, lflvl, yoff, uvoff, bl + 1); - } - } else if (row + hbs < s->rows) { - yoff += hbs * 8 * y_stride; - uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_sb_mem(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); - } - } -} - -static av_always_inline void filter_plane_cols(VP9Context *s, int col, int ss_h, int ss_v, - uint8_t *lvl, uint8_t (*mask)[4], - uint8_t *dst, ptrdiff_t ls) -{ - int y, x, bytesperpixel = s->bytesperpixel; - - // filter edges between columns (e.g. block1 | block2) - for (y = 0; y < 8; y += 2 << ss_v, dst += 16 * ls, lvl += 16 << ss_v) { - uint8_t *ptr = dst, *l = lvl, *hmask1 = mask[y], *hmask2 = mask[y + 1 + ss_v]; - unsigned hm1 = hmask1[0] | hmask1[1] | hmask1[2], hm13 = hmask1[3]; - unsigned hm2 = hmask2[1] | hmask2[2], hm23 = hmask2[3]; - unsigned hm = hm1 | hm2 | hm13 | hm23; - - for (x = 1; hm & ~(x - 1); x <<= 1, ptr += 8 * bytesperpixel >> ss_h) { - if (col || x > 1) { - if (hm1 & x) { - int L = *l, H = L >> 4; - int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - - if (hmask1[0] & x) { - if (hmask2[0] & x) { - av_assert2(l[8 << ss_v] == L); - s->dsp.loop_filter_16[0](ptr, ls, E, I, H); - } else { - s->dsp.loop_filter_8[2][0](ptr, ls, E, I, H); - } - } else if (hm2 & x) { - L = l[8 << ss_v]; - H |= (L >> 4) << 8; - E |= s->filter_lut.mblim_lut[L] << 8; - I |= s->filter_lut.lim_lut[L] << 8; - s->dsp.loop_filter_mix2[!!(hmask1[1] & x)] - [!!(hmask2[1] & x)] - [0](ptr, ls, E, I, H); - } else { - s->dsp.loop_filter_8[!!(hmask1[1] & x)] - [0](ptr, ls, E, I, H); - } - } else if (hm2 & x) { - int L = l[8 << ss_v], H = L >> 4; - int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - - s->dsp.loop_filter_8[!!(hmask2[1] & x)] - [0](ptr + 8 * ls, ls, E, I, H); - } - } - if (ss_h) { - if (x & 0xAA) - l += 2; - } else { - if (hm13 & x) { - int L = *l, H = L >> 4; - int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - - if (hm23 & x) { - L = l[8 << ss_v]; - H |= (L >> 4) << 8; - E |= s->filter_lut.mblim_lut[L] << 8; - I |= s->filter_lut.lim_lut[L] << 8; - s->dsp.loop_filter_mix2[0][0][0](ptr + 4 * bytesperpixel, ls, E, I, H); - } else { - s->dsp.loop_filter_8[0][0](ptr + 4 * bytesperpixel, ls, E, I, H); - } - } else if (hm23 & x) { - int L = l[8 << ss_v], H = L >> 4; - int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - - s->dsp.loop_filter_8[0][0](ptr + 8 * ls + 4 * bytesperpixel, ls, E, I, H); - } - l++; - } - } - } -} - -static av_always_inline void filter_plane_rows(VP9Context *s, int row, int ss_h, int ss_v, - uint8_t *lvl, uint8_t (*mask)[4], - uint8_t *dst, ptrdiff_t ls) -{ - int y, x, bytesperpixel = s->bytesperpixel; - - // block1 - // filter edges between rows (e.g. ------) - // block2 - for (y = 0; y < 8; y++, dst += 8 * ls >> ss_v) { - uint8_t *ptr = dst, *l = lvl, *vmask = mask[y]; - unsigned vm = vmask[0] | vmask[1] | vmask[2], vm3 = vmask[3]; - - for (x = 1; vm & ~(x - 1); x <<= (2 << ss_h), ptr += 16 * bytesperpixel, l += 2 << ss_h) { - if (row || y) { - if (vm & x) { - int L = *l, H = L >> 4; - int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - - if (vmask[0] & x) { - if (vmask[0] & (x << (1 + ss_h))) { - av_assert2(l[1 + ss_h] == L); - s->dsp.loop_filter_16[1](ptr, ls, E, I, H); - } else { - s->dsp.loop_filter_8[2][1](ptr, ls, E, I, H); - } - } else if (vm & (x << (1 + ss_h))) { - L = l[1 + ss_h]; - H |= (L >> 4) << 8; - E |= s->filter_lut.mblim_lut[L] << 8; - I |= s->filter_lut.lim_lut[L] << 8; - s->dsp.loop_filter_mix2[!!(vmask[1] & x)] - [!!(vmask[1] & (x << (1 + ss_h)))] - [1](ptr, ls, E, I, H); - } else { - s->dsp.loop_filter_8[!!(vmask[1] & x)] - [1](ptr, ls, E, I, H); - } - } else if (vm & (x << (1 + ss_h))) { - int L = l[1 + ss_h], H = L >> 4; - int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - - s->dsp.loop_filter_8[!!(vmask[1] & (x << (1 + ss_h)))] - [1](ptr + 8 * bytesperpixel, ls, E, I, H); - } - } - if (!ss_v) { - if (vm3 & x) { - int L = *l, H = L >> 4; - int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; + if (!ss_v) { + if (vm3 & x) { + int L = *l, H = L >> 4; + int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; if (vm3 & (x << (1 + ss_h))) { L = l[1 + ss_h]; @@ -3720,245 +1229,6 @@ static void set_tile_offset(int *start, int *end, int idx, int log2_n, int n) *end = FFMIN(sb_end, n) << 3; } -static av_always_inline void adapt_prob(uint8_t *p, unsigned ct0, unsigned ct1, - int max_count, int update_factor) -{ - unsigned ct = ct0 + ct1, p2, p1; - - if (!ct) - return; - - update_factor = FASTDIV(update_factor * FFMIN(ct, max_count), max_count); - p1 = *p; - p2 = ((((int64_t) ct0) << 8) + (ct >> 1)) / ct; - p2 = av_clip(p2, 1, 255); - - // (p1 * (256 - update_factor) + p2 * update_factor + 128) >> 8 - *p = p1 + (((p2 - p1) * update_factor + 128) >> 8); -} - -static void adapt_probs(VP9Context *s) -{ - int i, j, k, l, m; - prob_context *p = &s->prob_ctx[s->s.h.framectxid].p; - int uf = (s->s.h.keyframe || s->s.h.intraonly || !s->last_keyframe) ? 112 : 128; - - // coefficients - for (i = 0; i < 4; i++) - for (j = 0; j < 2; j++) - for (k = 0; k < 2; k++) - for (l = 0; l < 6; l++) - for (m = 0; m < 6; m++) { - uint8_t *pp = s->prob_ctx[s->s.h.framectxid].coef[i][j][k][l][m]; - unsigned *e = s->counts.eob[i][j][k][l][m]; - unsigned *c = s->counts.coef[i][j][k][l][m]; - - if (l == 0 && m >= 3) // dc only has 3 pt - break; - - adapt_prob(&pp[0], e[0], e[1], 24, uf); - adapt_prob(&pp[1], c[0], c[1] + c[2], 24, uf); - adapt_prob(&pp[2], c[1], c[2], 24, uf); - } - - if (s->s.h.keyframe || s->s.h.intraonly) { - memcpy(p->skip, s->prob.p.skip, sizeof(p->skip)); - memcpy(p->tx32p, s->prob.p.tx32p, sizeof(p->tx32p)); - memcpy(p->tx16p, s->prob.p.tx16p, sizeof(p->tx16p)); - memcpy(p->tx8p, s->prob.p.tx8p, sizeof(p->tx8p)); - return; - } - - // skip flag - for (i = 0; i < 3; i++) - adapt_prob(&p->skip[i], s->counts.skip[i][0], s->counts.skip[i][1], 20, 128); - - // intra/inter flag - for (i = 0; i < 4; i++) - adapt_prob(&p->intra[i], s->counts.intra[i][0], s->counts.intra[i][1], 20, 128); - - // comppred flag - if (s->s.h.comppredmode == PRED_SWITCHABLE) { - for (i = 0; i < 5; i++) - adapt_prob(&p->comp[i], s->counts.comp[i][0], s->counts.comp[i][1], 20, 128); - } - - // reference frames - if (s->s.h.comppredmode != PRED_SINGLEREF) { - for (i = 0; i < 5; i++) - adapt_prob(&p->comp_ref[i], s->counts.comp_ref[i][0], - s->counts.comp_ref[i][1], 20, 128); - } - - if (s->s.h.comppredmode != PRED_COMPREF) { - for (i = 0; i < 5; i++) { - uint8_t *pp = p->single_ref[i]; - unsigned (*c)[2] = s->counts.single_ref[i]; - - adapt_prob(&pp[0], c[0][0], c[0][1], 20, 128); - adapt_prob(&pp[1], c[1][0], c[1][1], 20, 128); - } - } - - // block partitioning - for (i = 0; i < 4; i++) - for (j = 0; j < 4; j++) { - uint8_t *pp = p->partition[i][j]; - unsigned *c = s->counts.partition[i][j]; - - adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); - adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); - adapt_prob(&pp[2], c[2], c[3], 20, 128); - } - - // tx size - if (s->s.h.txfmmode == TX_SWITCHABLE) { - for (i = 0; i < 2; i++) { - unsigned *c16 = s->counts.tx16p[i], *c32 = s->counts.tx32p[i]; - - adapt_prob(&p->tx8p[i], s->counts.tx8p[i][0], s->counts.tx8p[i][1], 20, 128); - adapt_prob(&p->tx16p[i][0], c16[0], c16[1] + c16[2], 20, 128); - adapt_prob(&p->tx16p[i][1], c16[1], c16[2], 20, 128); - adapt_prob(&p->tx32p[i][0], c32[0], c32[1] + c32[2] + c32[3], 20, 128); - adapt_prob(&p->tx32p[i][1], c32[1], c32[2] + c32[3], 20, 128); - adapt_prob(&p->tx32p[i][2], c32[2], c32[3], 20, 128); - } - } - - // interpolation filter - if (s->s.h.filtermode == FILTER_SWITCHABLE) { - for (i = 0; i < 4; i++) { - uint8_t *pp = p->filter[i]; - unsigned *c = s->counts.filter[i]; - - adapt_prob(&pp[0], c[0], c[1] + c[2], 20, 128); - adapt_prob(&pp[1], c[1], c[2], 20, 128); - } - } - - // inter modes - for (i = 0; i < 7; i++) { - uint8_t *pp = p->mv_mode[i]; - unsigned *c = s->counts.mv_mode[i]; - - adapt_prob(&pp[0], c[2], c[1] + c[0] + c[3], 20, 128); - adapt_prob(&pp[1], c[0], c[1] + c[3], 20, 128); - adapt_prob(&pp[2], c[1], c[3], 20, 128); - } - - // mv joints - { - uint8_t *pp = p->mv_joint; - unsigned *c = s->counts.mv_joint; - - adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); - adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); - adapt_prob(&pp[2], c[2], c[3], 20, 128); - } - - // mv components - for (i = 0; i < 2; i++) { - uint8_t *pp; - unsigned *c, (*c2)[2], sum; - - adapt_prob(&p->mv_comp[i].sign, s->counts.mv_comp[i].sign[0], - s->counts.mv_comp[i].sign[1], 20, 128); - - pp = p->mv_comp[i].classes; - c = s->counts.mv_comp[i].classes; - sum = c[1] + c[2] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9] + c[10]; - adapt_prob(&pp[0], c[0], sum, 20, 128); - sum -= c[1]; - adapt_prob(&pp[1], c[1], sum, 20, 128); - sum -= c[2] + c[3]; - adapt_prob(&pp[2], c[2] + c[3], sum, 20, 128); - adapt_prob(&pp[3], c[2], c[3], 20, 128); - sum -= c[4] + c[5]; - adapt_prob(&pp[4], c[4] + c[5], sum, 20, 128); - adapt_prob(&pp[5], c[4], c[5], 20, 128); - sum -= c[6]; - adapt_prob(&pp[6], c[6], sum, 20, 128); - adapt_prob(&pp[7], c[7] + c[8], c[9] + c[10], 20, 128); - adapt_prob(&pp[8], c[7], c[8], 20, 128); - adapt_prob(&pp[9], c[9], c[10], 20, 128); - - adapt_prob(&p->mv_comp[i].class0, s->counts.mv_comp[i].class0[0], - s->counts.mv_comp[i].class0[1], 20, 128); - pp = p->mv_comp[i].bits; - c2 = s->counts.mv_comp[i].bits; - for (j = 0; j < 10; j++) - adapt_prob(&pp[j], c2[j][0], c2[j][1], 20, 128); - - for (j = 0; j < 2; j++) { - pp = p->mv_comp[i].class0_fp[j]; - c = s->counts.mv_comp[i].class0_fp[j]; - adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); - adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); - adapt_prob(&pp[2], c[2], c[3], 20, 128); - } - pp = p->mv_comp[i].fp; - c = s->counts.mv_comp[i].fp; - adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); - adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); - adapt_prob(&pp[2], c[2], c[3], 20, 128); - - if (s->s.h.highprecisionmvs) { - adapt_prob(&p->mv_comp[i].class0_hp, s->counts.mv_comp[i].class0_hp[0], - s->counts.mv_comp[i].class0_hp[1], 20, 128); - adapt_prob(&p->mv_comp[i].hp, s->counts.mv_comp[i].hp[0], - s->counts.mv_comp[i].hp[1], 20, 128); - } - } - - // y intra modes - for (i = 0; i < 4; i++) { - uint8_t *pp = p->y_mode[i]; - unsigned *c = s->counts.y_mode[i], sum, s2; - - sum = c[0] + c[1] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9]; - adapt_prob(&pp[0], c[DC_PRED], sum, 20, 128); - sum -= c[TM_VP8_PRED]; - adapt_prob(&pp[1], c[TM_VP8_PRED], sum, 20, 128); - sum -= c[VERT_PRED]; - adapt_prob(&pp[2], c[VERT_PRED], sum, 20, 128); - s2 = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED]; - sum -= s2; - adapt_prob(&pp[3], s2, sum, 20, 128); - s2 -= c[HOR_PRED]; - adapt_prob(&pp[4], c[HOR_PRED], s2, 20, 128); - adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED], 20, 128); - sum -= c[DIAG_DOWN_LEFT_PRED]; - adapt_prob(&pp[6], c[DIAG_DOWN_LEFT_PRED], sum, 20, 128); - sum -= c[VERT_LEFT_PRED]; - adapt_prob(&pp[7], c[VERT_LEFT_PRED], sum, 20, 128); - adapt_prob(&pp[8], c[HOR_DOWN_PRED], c[HOR_UP_PRED], 20, 128); - } - - // uv intra modes - for (i = 0; i < 10; i++) { - uint8_t *pp = p->uv_mode[i]; - unsigned *c = s->counts.uv_mode[i], sum, s2; - - sum = c[0] + c[1] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9]; - adapt_prob(&pp[0], c[DC_PRED], sum, 20, 128); - sum -= c[TM_VP8_PRED]; - adapt_prob(&pp[1], c[TM_VP8_PRED], sum, 20, 128); - sum -= c[VERT_PRED]; - adapt_prob(&pp[2], c[VERT_PRED], sum, 20, 128); - s2 = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED]; - sum -= s2; - adapt_prob(&pp[3], s2, sum, 20, 128); - s2 -= c[HOR_PRED]; - adapt_prob(&pp[4], c[HOR_PRED], s2, 20, 128); - adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED], 20, 128); - sum -= c[DIAG_DOWN_LEFT_PRED]; - adapt_prob(&pp[6], c[DIAG_DOWN_LEFT_PRED], sum, 20, 128); - sum -= c[VERT_LEFT_PRED]; - adapt_prob(&pp[7], c[VERT_LEFT_PRED], sum, 20, 128); - adapt_prob(&pp[8], c[HOR_DOWN_PRED], c[HOR_UP_PRED], 20, 128); - } -} - static void free_buffers(VP9Context *s) { av_freep(&s->intra_pred_data[0]); @@ -4253,7 +1523,7 @@ FF_ENABLE_DEPRECATION_WARNINGS } if (s->pass < 2 && s->s.h.refreshctx && !s->s.h.parallelmode) { - adapt_probs(s); + ff_vp9_adapt_probs(s); ff_thread_finish_setup(ctx); } } while (s->pass++ == 1); diff --git a/libavcodec/vp9.h b/libavcodec/vp9.h index 89b1bd3e4c6de..0097385e1ca58 100644 --- a/libavcodec/vp9.h +++ b/libavcodec/vp9.h @@ -24,8 +24,13 @@ #ifndef AVCODEC_VP9_H #define AVCODEC_VP9_H +#include #include +#include "libavutil/buffer.h" +#include "libavutil/internal.h" + +#include "avcodec.h" #include "thread.h" #include "vp56.h" @@ -118,11 +123,143 @@ enum CompPredMode { PRED_SWITCHABLE, }; +enum MVJoint { + MV_JOINT_ZERO, + MV_JOINT_H, + MV_JOINT_V, + MV_JOINT_HV, +}; + +typedef struct ProbContext { + uint8_t y_mode[4][9]; + uint8_t uv_mode[10][9]; + uint8_t filter[4][2]; + uint8_t mv_mode[7][3]; + uint8_t intra[4]; + uint8_t comp[5]; + uint8_t single_ref[5][2]; + uint8_t comp_ref[5]; + uint8_t tx32p[2][3]; + uint8_t tx16p[2][2]; + uint8_t tx8p[2]; + uint8_t skip[3]; + uint8_t mv_joint[3]; + struct { + uint8_t sign; + uint8_t classes[10]; + uint8_t class0; + uint8_t bits[10]; + uint8_t class0_fp[2][3]; + uint8_t fp[3]; + uint8_t class0_hp; + uint8_t hp; + } mv_comp[2]; + uint8_t partition[4][4][3]; +} ProbContext; + +typedef void (*vp9_mc_func)(uint8_t *dst, ptrdiff_t dst_stride, + const uint8_t *ref, ptrdiff_t ref_stride, + int h, int mx, int my); +typedef void (*vp9_scaled_mc_func)(uint8_t *dst, ptrdiff_t dst_stride, + const uint8_t *ref, ptrdiff_t ref_stride, + int h, int mx, int my, int dx, int dy); + +typedef struct VP9DSPContext { + /* + * dimension 1: 0=4x4, 1=8x8, 2=16x16, 3=32x32 + * dimension 2: intra prediction modes + * + * dst/left/top is aligned by transform-size (i.e. 4, 8, 16 or 32 pixels) + * stride is aligned by 16 pixels + * top[-1] is top/left; top[4,7] is top-right for 4x4 + */ + // FIXME(rbultje) maybe replace left/top pointers with HAVE_TOP/ + // HAVE_LEFT/HAVE_TOPRIGHT flags instead, and then handle it in-place? + // also needs to fit in with what H.264/VP8/etc do + void (*intra_pred[N_TXFM_SIZES][N_INTRA_PRED_MODES])(uint8_t *dst, + ptrdiff_t stride, + const uint8_t *left, + const uint8_t *top); + + /* + * dimension 1: 0=4x4, 1=8x8, 2=16x16, 3=32x32, 4=lossless (3-4=dct only) + * dimension 2: 0=dct/dct, 1=dct/adst, 2=adst/dct, 3=adst/adst + * + * dst is aligned by transform-size (i.e. 4, 8, 16 or 32 pixels) + * stride is aligned by 16 pixels + * block is 16-byte aligned + * eob indicates the position (+1) of the last non-zero coefficient, + * in scan-order. This can be used to write faster versions, e.g. a + * dc-only 4x4/8x8/16x16/32x32, or a 4x4-only (eob<10) 8x8/16x16/32x32, + * etc. + */ + // FIXME also write idct_add_block() versions for whole (inter) pred + // blocks, so we can do 2 4x4s at once + void (*itxfm_add[N_TXFM_SIZES + 1][N_TXFM_TYPES])(uint8_t *dst, + ptrdiff_t stride, + int16_t *block, int eob); + + /* + * dimension 1: width of filter (0=4, 1=8, 2=16) + * dimension 2: 0=col-edge filter (h), 1=row-edge filter (v) + * + * dst/stride are aligned by 8 + */ + void (*loop_filter_8[3][2])(uint8_t *dst, ptrdiff_t stride, + int mb_lim, int lim, int hev_thr); + + /* + * dimension 1: 0=col-edge filter (h), 1=row-edge filter (v) + * + * The width of filter is assumed to be 16; dst/stride are aligned by 16 + */ + void (*loop_filter_16[2])(uint8_t *dst, ptrdiff_t stride, + int mb_lim, int lim, int hev_thr); + + /* + * dimension 1/2: width of filter (0=4, 1=8) for each filter half + * dimension 3: 0=col-edge filter (h), 1=row-edge filter (v) + * + * dst/stride are aligned by operation size + * this basically calls loop_filter[d1][d3][0](), followed by + * loop_filter[d2][d3][0]() on the next 8 pixels + * mb_lim/lim/hev_thr contain two values in the lowest two bytes of the + * integer. + */ + // FIXME perhaps a mix4 that operates on 32px (for AVX2) + void (*loop_filter_mix2[2][2][2])(uint8_t *dst, ptrdiff_t stride, + int mb_lim, int lim, int hev_thr); + + /* + * dimension 1: hsize (0: 64, 1: 32, 2: 16, 3: 8, 4: 4) + * dimension 2: filter type (0: smooth, 1: regular, 2: sharp, 3: bilin) + * dimension 3: averaging type (0: put, 1: avg) + * dimension 4: x subpel interpolation (0: none, 1: 8tap/bilin) + * dimension 5: y subpel interpolation (0: none, 1: 8tap/bilin) + * + * dst/stride are aligned by hsize + */ + vp9_mc_func mc[5][4][2][2][2]; + + /* + * for scalable MC, first 3 dimensions identical to above, the other two + * don't exist since it changes per stepsize. + */ + vp9_scaled_mc_func smc[5][4][2]; +} VP9DSPContext; + + struct VP9mvrefPair { VP56mv mv[2]; int8_t ref[2]; }; +struct VP9Filter { + uint8_t level[8 * 8]; + uint8_t /* bit=col */ mask[2 /* 0=y, 1=uv */][2 /* 0=col, 1=row */] + [8 /* rows */][4 /* 0=16, 1=8, 2=4, 3=inner4 */]; +}; + typedef struct VP9Frame { ThreadFrame tf; AVBufferRef *extradata; @@ -209,4 +346,147 @@ typedef struct VP9SharedContext { VP9Frame frames[3]; } VP9SharedContext; +typedef struct VP9Block { + uint8_t seg_id, intra, comp, ref[2], mode[4], uvmode, skip; + enum FilterMode filter; + VP56mv mv[4 /* b_idx */][2 /* ref */]; + enum BlockSize bs; + enum TxfmMode tx, uvtx; + enum BlockLevel bl; + enum BlockPartition bp; +} VP9Block; + +typedef struct VP9Context { + VP9SharedContext s; + + VP9DSPContext dsp; + VideoDSPContext vdsp; + GetBitContext gb; + VP56RangeCoder c; + VP56RangeCoder *c_b; + unsigned c_b_size; + VP9Block *b_base, *b; + int pass; + int row, row7, col, col7; + uint8_t *dst[3]; + ptrdiff_t y_stride, uv_stride; + + uint8_t ss_h, ss_v; + uint8_t last_bpp, bpp_index, bytesperpixel; + uint8_t last_keyframe; + // sb_cols/rows, rows/cols and last_fmt are used for allocating all internal + // arrays, and are thus per-thread. w/h and gf_fmt are synced between threads + // and are therefore per-stream. pix_fmt represents the value in the header + // of the currently processed frame. + int w, h; + enum AVPixelFormat pix_fmt, last_fmt, gf_fmt; + unsigned sb_cols, sb_rows, rows, cols; + ThreadFrame next_refs[8]; + + struct { + uint8_t lim_lut[64]; + uint8_t mblim_lut[64]; + } filter_lut; + unsigned tile_row_start, tile_row_end, tile_col_start, tile_col_end; + struct { + ProbContext p; + uint8_t coef[4][2][2][6][6][3]; + } prob_ctx[4]; + struct { + ProbContext p; + uint8_t coef[4][2][2][6][6][11]; + } prob; + struct { + unsigned y_mode[4][10]; + unsigned uv_mode[10][10]; + unsigned filter[4][3]; + unsigned mv_mode[7][4]; + unsigned intra[4][2]; + unsigned comp[5][2]; + unsigned single_ref[5][2][2]; + unsigned comp_ref[5][2]; + unsigned tx32p[2][4]; + unsigned tx16p[2][3]; + unsigned tx8p[2][2]; + unsigned skip[3][2]; + unsigned mv_joint[4]; + struct { + unsigned sign[2]; + unsigned classes[11]; + unsigned class0[2]; + unsigned bits[10][2]; + unsigned class0_fp[2][4]; + unsigned fp[4]; + unsigned class0_hp[2]; + unsigned hp[2]; + } mv_comp[2]; + unsigned partition[4][4][4]; + unsigned coef[4][2][2][6][6][3]; + unsigned eob[4][2][2][6][6][2]; + } counts; + + // contextual (left/above) cache + DECLARE_ALIGNED(16, uint8_t, left_y_nnz_ctx)[16]; + DECLARE_ALIGNED(16, uint8_t, left_mode_ctx)[16]; + DECLARE_ALIGNED(16, VP56mv, left_mv_ctx)[16][2]; + DECLARE_ALIGNED(16, uint8_t, left_uv_nnz_ctx)[2][16]; + DECLARE_ALIGNED(8, uint8_t, left_partition_ctx)[8]; + DECLARE_ALIGNED(8, uint8_t, left_skip_ctx)[8]; + DECLARE_ALIGNED(8, uint8_t, left_txfm_ctx)[8]; + DECLARE_ALIGNED(8, uint8_t, left_segpred_ctx)[8]; + DECLARE_ALIGNED(8, uint8_t, left_intra_ctx)[8]; + DECLARE_ALIGNED(8, uint8_t, left_comp_ctx)[8]; + DECLARE_ALIGNED(8, uint8_t, left_ref_ctx)[8]; + DECLARE_ALIGNED(8, uint8_t, left_filter_ctx)[8]; + uint8_t *above_partition_ctx; + uint8_t *above_mode_ctx; + // FIXME maybe merge some of the below in a flags field? + uint8_t *above_y_nnz_ctx; + uint8_t *above_uv_nnz_ctx[2]; + uint8_t *above_skip_ctx; // 1bit + uint8_t *above_txfm_ctx; // 2bit + uint8_t *above_segpred_ctx; // 1bit + uint8_t *above_intra_ctx; // 1bit + uint8_t *above_comp_ctx; // 1bit + uint8_t *above_ref_ctx; // 2bit + uint8_t *above_filter_ctx; + VP56mv (*above_mv_ctx)[2]; + + // whole-frame cache + uint8_t *intra_pred_data[3]; + struct VP9Filter *lflvl; + DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[135 * 144 * 2]; + + // block reconstruction intermediates + int block_alloc_using_2pass; + int16_t *block_base, *block, *uvblock_base[2], *uvblock[2]; + uint8_t *eob_base, *uveob_base[2], *eob, *uveob[2]; + struct { int x, y; } min_mv, max_mv; + DECLARE_ALIGNED(32, uint8_t, tmp_y)[64 * 64 * 2]; + DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][64 * 64 * 2]; + uint16_t mvscale[3][2]; + uint8_t mvstep[3][2]; +} VP9Context; + +extern const int16_t ff_vp9_subpel_filters[3][16][8]; + +void ff_vp9dsp_init(VP9DSPContext *dsp, int bpp, int bitexact); + +void ff_vp9dsp_init_8(VP9DSPContext *dsp); +void ff_vp9dsp_init_10(VP9DSPContext *dsp); +void ff_vp9dsp_init_12(VP9DSPContext *dsp); + +void ff_vp9dsp_init_aarch64(VP9DSPContext *dsp, int bpp); +void ff_vp9dsp_init_arm(VP9DSPContext *dsp, int bpp); +void ff_vp9dsp_init_x86(VP9DSPContext *dsp, int bpp, int bitexact); +void ff_vp9dsp_init_mips(VP9DSPContext *dsp, int bpp); + +void ff_vp9_fill_mv(VP9Context *s, VP56mv *mv, int mode, int sb); + +void ff_vp9_adapt_probs(VP9Context *s); + +void ff_vp9_decode_block(AVCodecContext *ctx, int row, int col, + struct VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, + enum BlockLevel bl, enum BlockPartition bp); + #endif /* AVCODEC_VP9_H */ diff --git a/libavcodec/vp9block.c b/libavcodec/vp9block.c new file mode 100644 index 0000000000000..dd135aadf426a --- /dev/null +++ b/libavcodec/vp9block.c @@ -0,0 +1,2059 @@ +/* + * VP9 compatible video decoder + * + * Copyright (C) 2013 Ronald S. Bultje + * Copyright (C) 2013 Clément Bœsch + * + * 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 "libavutil/avassert.h" + +#include "avcodec.h" +#include "internal.h" +#include "videodsp.h" +#include "vp56.h" +#include "vp9.h" +#include "vp9data.h" + +static const uint8_t bwh_tab[2][N_BS_SIZES][2] = { + { + { 16, 16 }, { 16, 8 }, { 8, 16 }, { 8, 8 }, { 8, 4 }, { 4, 8 }, + { 4, 4 }, { 4, 2 }, { 2, 4 }, { 2, 2 }, { 2, 1 }, { 1, 2 }, { 1, 1 }, + }, { + { 8, 8 }, { 8, 4 }, { 4, 8 }, { 4, 4 }, { 4, 2 }, { 2, 4 }, + { 2, 2 }, { 2, 1 }, { 1, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, + } +}; + +static av_always_inline void setctx_2d(uint8_t *ptr, int w, int h, + ptrdiff_t stride, int v) +{ + switch (w) { + case 1: + do { + *ptr = v; + ptr += stride; + } while (--h); + break; + case 2: { + int v16 = v * 0x0101; + do { + AV_WN16A(ptr, v16); + ptr += stride; + } while (--h); + break; + } + case 4: { + uint32_t v32 = v * 0x01010101; + do { + AV_WN32A(ptr, v32); + ptr += stride; + } while (--h); + break; + } + case 8: { +#if HAVE_FAST_64BIT + uint64_t v64 = v * 0x0101010101010101ULL; + do { + AV_WN64A(ptr, v64); + ptr += stride; + } while (--h); +#else + uint32_t v32 = v * 0x01010101; + do { + AV_WN32A(ptr, v32); + AV_WN32A(ptr + 4, v32); + ptr += stride; + } while (--h); +#endif + break; + } + } +} + +static void decode_mode(AVCodecContext *ctx) +{ + static const uint8_t left_ctx[N_BS_SIZES] = { + 0x0, 0x8, 0x0, 0x8, 0xc, 0x8, 0xc, 0xe, 0xc, 0xe, 0xf, 0xe, 0xf + }; + static const uint8_t above_ctx[N_BS_SIZES] = { + 0x0, 0x0, 0x8, 0x8, 0x8, 0xc, 0xc, 0xc, 0xe, 0xe, 0xe, 0xf, 0xf + }; + static const uint8_t max_tx_for_bl_bp[N_BS_SIZES] = { + TX_32X32, TX_32X32, TX_32X32, TX_32X32, TX_16X16, TX_16X16, + TX_16X16, TX_8X8, TX_8X8, TX_8X8, TX_4X4, TX_4X4, TX_4X4 + }; + VP9Context *s = ctx->priv_data; + VP9Block *b = s->b; + int row = s->row, col = s->col, row7 = s->row7; + enum TxfmMode max_tx = max_tx_for_bl_bp[b->bs]; + int bw4 = bwh_tab[1][b->bs][0], w4 = FFMIN(s->cols - col, bw4); + int bh4 = bwh_tab[1][b->bs][1], h4 = FFMIN(s->rows - row, bh4), y; + int have_a = row > 0, have_l = col > s->tile_col_start; + int vref, filter_id; + + if (!s->s.h.segmentation.enabled) { + b->seg_id = 0; + } else if (s->s.h.keyframe || s->s.h.intraonly) { + b->seg_id = !s->s.h.segmentation.update_map ? 0 : + vp8_rac_get_tree(&s->c, ff_vp9_segmentation_tree, s->s.h.segmentation.prob); + } else if (!s->s.h.segmentation.update_map || + (s->s.h.segmentation.temporal && + vp56_rac_get_prob_branchy(&s->c, + s->s.h.segmentation.pred_prob[s->above_segpred_ctx[col] + + s->left_segpred_ctx[row7]]))) { + if (!s->s.h.errorres && s->s.frames[REF_FRAME_SEGMAP].segmentation_map) { + int pred = 8, x; + uint8_t *refsegmap = s->s.frames[REF_FRAME_SEGMAP].segmentation_map; + + if (!s->s.frames[REF_FRAME_SEGMAP].uses_2pass) + ff_thread_await_progress(&s->s.frames[REF_FRAME_SEGMAP].tf, row >> 3, 0); + for (y = 0; y < h4; y++) { + int idx_base = (y + row) * 8 * s->sb_cols + col; + for (x = 0; x < w4; x++) + pred = FFMIN(pred, refsegmap[idx_base + x]); + } + av_assert1(pred < 8); + b->seg_id = pred; + } else { + b->seg_id = 0; + } + + memset(&s->above_segpred_ctx[col], 1, w4); + memset(&s->left_segpred_ctx[row7], 1, h4); + } else { + b->seg_id = vp8_rac_get_tree(&s->c, ff_vp9_segmentation_tree, + s->s.h.segmentation.prob); + + memset(&s->above_segpred_ctx[col], 0, w4); + memset(&s->left_segpred_ctx[row7], 0, h4); + } + if (s->s.h.segmentation.enabled && + (s->s.h.segmentation.update_map || s->s.h.keyframe || s->s.h.intraonly)) { + setctx_2d(&s->s.frames[CUR_FRAME].segmentation_map[row * 8 * s->sb_cols + col], + bw4, bh4, 8 * s->sb_cols, b->seg_id); + } + + b->skip = s->s.h.segmentation.enabled && + s->s.h.segmentation.feat[b->seg_id].skip_enabled; + if (!b->skip) { + int c = s->left_skip_ctx[row7] + s->above_skip_ctx[col]; + b->skip = vp56_rac_get_prob(&s->c, s->prob.p.skip[c]); + s->counts.skip[c][b->skip]++; + } + + if (s->s.h.keyframe || s->s.h.intraonly) { + b->intra = 1; + } else if (s->s.h.segmentation.enabled && s->s.h.segmentation.feat[b->seg_id].ref_enabled) { + b->intra = !s->s.h.segmentation.feat[b->seg_id].ref_val; + } else { + int c, bit; + + if (have_a && have_l) { + c = s->above_intra_ctx[col] + s->left_intra_ctx[row7]; + c += (c == 2); + } else { + c = have_a ? 2 * s->above_intra_ctx[col] : + have_l ? 2 * s->left_intra_ctx[row7] : 0; + } + bit = vp56_rac_get_prob(&s->c, s->prob.p.intra[c]); + s->counts.intra[c][bit]++; + b->intra = !bit; + } + + if ((b->intra || !b->skip) && s->s.h.txfmmode == TX_SWITCHABLE) { + int c; + if (have_a) { + if (have_l) { + c = (s->above_skip_ctx[col] ? max_tx : + s->above_txfm_ctx[col]) + + (s->left_skip_ctx[row7] ? max_tx : + s->left_txfm_ctx[row7]) > max_tx; + } else { + c = s->above_skip_ctx[col] ? 1 : + (s->above_txfm_ctx[col] * 2 > max_tx); + } + } else if (have_l) { + c = s->left_skip_ctx[row7] ? 1 : + (s->left_txfm_ctx[row7] * 2 > max_tx); + } else { + c = 1; + } + switch (max_tx) { + case TX_32X32: + b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][0]); + if (b->tx) { + b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][1]); + if (b->tx == 2) + b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][2]); + } + s->counts.tx32p[c][b->tx]++; + break; + case TX_16X16: + b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx16p[c][0]); + if (b->tx) + b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx16p[c][1]); + s->counts.tx16p[c][b->tx]++; + break; + case TX_8X8: + b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx8p[c]); + s->counts.tx8p[c][b->tx]++; + break; + case TX_4X4: + b->tx = TX_4X4; + break; + } + } else { + b->tx = FFMIN(max_tx, s->s.h.txfmmode); + } + + if (s->s.h.keyframe || s->s.h.intraonly) { + uint8_t *a = &s->above_mode_ctx[col * 2]; + uint8_t *l = &s->left_mode_ctx[(row7) << 1]; + + b->comp = 0; + if (b->bs > BS_8x8) { + // FIXME the memory storage intermediates here aren't really + // necessary, they're just there to make the code slightly + // simpler for now + b->mode[0] = a[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + ff_vp9_default_kf_ymode_probs[a[0]][l[0]]); + if (b->bs != BS_8x4) { + b->mode[1] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + ff_vp9_default_kf_ymode_probs[a[1]][b->mode[0]]); + l[0] = a[1] = b->mode[1]; + } else { + l[0] = a[1] = b->mode[1] = b->mode[0]; + } + if (b->bs != BS_4x8) { + b->mode[2] = a[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + ff_vp9_default_kf_ymode_probs[a[0]][l[1]]); + if (b->bs != BS_8x4) { + b->mode[3] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + ff_vp9_default_kf_ymode_probs[a[1]][b->mode[2]]); + l[1] = a[1] = b->mode[3]; + } else { + l[1] = a[1] = b->mode[3] = b->mode[2]; + } + } else { + b->mode[2] = b->mode[0]; + l[1] = a[1] = b->mode[3] = b->mode[1]; + } + } else { + b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + ff_vp9_default_kf_ymode_probs[*a][*l]); + b->mode[3] = b->mode[2] = b->mode[1] = b->mode[0]; + // FIXME this can probably be optimized + memset(a, b->mode[0], bwh_tab[0][b->bs][0]); + memset(l, b->mode[0], bwh_tab[0][b->bs][1]); + } + b->uvmode = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + ff_vp9_default_kf_uvmode_probs[b->mode[3]]); + } else if (b->intra) { + b->comp = 0; + if (b->bs > BS_8x8) { + b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + s->prob.p.y_mode[0]); + s->counts.y_mode[0][b->mode[0]]++; + if (b->bs != BS_8x4) { + b->mode[1] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + s->prob.p.y_mode[0]); + s->counts.y_mode[0][b->mode[1]]++; + } else { + b->mode[1] = b->mode[0]; + } + if (b->bs != BS_4x8) { + b->mode[2] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + s->prob.p.y_mode[0]); + s->counts.y_mode[0][b->mode[2]]++; + if (b->bs != BS_8x4) { + b->mode[3] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + s->prob.p.y_mode[0]); + s->counts.y_mode[0][b->mode[3]]++; + } else { + b->mode[3] = b->mode[2]; + } + } else { + b->mode[2] = b->mode[0]; + b->mode[3] = b->mode[1]; + } + } else { + static const uint8_t size_group[10] = { + 3, 3, 3, 3, 2, 2, 2, 1, 1, 1 + }; + int sz = size_group[b->bs]; + + b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + s->prob.p.y_mode[sz]); + b->mode[1] = b->mode[2] = b->mode[3] = b->mode[0]; + s->counts.y_mode[sz][b->mode[3]]++; + } + b->uvmode = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + s->prob.p.uv_mode[b->mode[3]]); + s->counts.uv_mode[b->mode[3]][b->uvmode]++; + } else { + static const uint8_t inter_mode_ctx_lut[14][14] = { + { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, + { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, + { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, + { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, + { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, + { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, + { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, + { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, + { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, + { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, + { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 1, 3 }, + { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 1, 3 }, + { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 0, 3 }, + { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 4 }, + }; + + if (s->s.h.segmentation.enabled && s->s.h.segmentation.feat[b->seg_id].ref_enabled) { + av_assert2(s->s.h.segmentation.feat[b->seg_id].ref_val != 0); + b->comp = 0; + b->ref[0] = s->s.h.segmentation.feat[b->seg_id].ref_val - 1; + } else { + // read comp_pred flag + if (s->s.h.comppredmode != PRED_SWITCHABLE) { + b->comp = s->s.h.comppredmode == PRED_COMPREF; + } else { + int c; + + // FIXME add intra as ref=0xff (or -1) to make these easier? + if (have_a) { + if (have_l) { + if (s->above_comp_ctx[col] && s->left_comp_ctx[row7]) { + c = 4; + } else if (s->above_comp_ctx[col]) { + c = 2 + (s->left_intra_ctx[row7] || + s->left_ref_ctx[row7] == s->s.h.fixcompref); + } else if (s->left_comp_ctx[row7]) { + c = 2 + (s->above_intra_ctx[col] || + s->above_ref_ctx[col] == s->s.h.fixcompref); + } else { + c = (!s->above_intra_ctx[col] && + s->above_ref_ctx[col] == s->s.h.fixcompref) ^ + (!s->left_intra_ctx[row7] && + s->left_ref_ctx[row & 7] == s->s.h.fixcompref); + } + } else { + c = s->above_comp_ctx[col] ? 3 : + (!s->above_intra_ctx[col] && s->above_ref_ctx[col] == s->s.h.fixcompref); + } + } else if (have_l) { + c = s->left_comp_ctx[row7] ? 3 : + (!s->left_intra_ctx[row7] && s->left_ref_ctx[row7] == s->s.h.fixcompref); + } else { + c = 1; + } + b->comp = vp56_rac_get_prob(&s->c, s->prob.p.comp[c]); + s->counts.comp[c][b->comp]++; + } + + // read actual references + // FIXME probably cache a few variables here to prevent repetitive + // memory accesses below + if (b->comp) /* two references */ { + int fix_idx = s->s.h.signbias[s->s.h.fixcompref], var_idx = !fix_idx, c, bit; + + b->ref[fix_idx] = s->s.h.fixcompref; + // FIXME can this codeblob be replaced by some sort of LUT? + if (have_a) { + if (have_l) { + if (s->above_intra_ctx[col]) { + if (s->left_intra_ctx[row7]) { + c = 2; + } else { + c = 1 + 2 * (s->left_ref_ctx[row7] != s->s.h.varcompref[1]); + } + } else if (s->left_intra_ctx[row7]) { + c = 1 + 2 * (s->above_ref_ctx[col] != s->s.h.varcompref[1]); + } else { + int refl = s->left_ref_ctx[row7], refa = s->above_ref_ctx[col]; + + if (refl == refa && refa == s->s.h.varcompref[1]) { + c = 0; + } else if (!s->left_comp_ctx[row7] && !s->above_comp_ctx[col]) { + if ((refa == s->s.h.fixcompref && refl == s->s.h.varcompref[0]) || + (refl == s->s.h.fixcompref && refa == s->s.h.varcompref[0])) { + c = 4; + } else { + c = (refa == refl) ? 3 : 1; + } + } else if (!s->left_comp_ctx[row7]) { + if (refa == s->s.h.varcompref[1] && refl != s->s.h.varcompref[1]) { + c = 1; + } else { + c = (refl == s->s.h.varcompref[1] && + refa != s->s.h.varcompref[1]) ? 2 : 4; + } + } else if (!s->above_comp_ctx[col]) { + if (refl == s->s.h.varcompref[1] && refa != s->s.h.varcompref[1]) { + c = 1; + } else { + c = (refa == s->s.h.varcompref[1] && + refl != s->s.h.varcompref[1]) ? 2 : 4; + } + } else { + c = (refl == refa) ? 4 : 2; + } + } + } else { + if (s->above_intra_ctx[col]) { + c = 2; + } else if (s->above_comp_ctx[col]) { + c = 4 * (s->above_ref_ctx[col] != s->s.h.varcompref[1]); + } else { + c = 3 * (s->above_ref_ctx[col] != s->s.h.varcompref[1]); + } + } + } else if (have_l) { + if (s->left_intra_ctx[row7]) { + c = 2; + } else if (s->left_comp_ctx[row7]) { + c = 4 * (s->left_ref_ctx[row7] != s->s.h.varcompref[1]); + } else { + c = 3 * (s->left_ref_ctx[row7] != s->s.h.varcompref[1]); + } + } else { + c = 2; + } + bit = vp56_rac_get_prob(&s->c, s->prob.p.comp_ref[c]); + b->ref[var_idx] = s->s.h.varcompref[bit]; + s->counts.comp_ref[c][bit]++; + } else /* single reference */ { + int bit, c; + + if (have_a && !s->above_intra_ctx[col]) { + if (have_l && !s->left_intra_ctx[row7]) { + if (s->left_comp_ctx[row7]) { + if (s->above_comp_ctx[col]) { + c = 1 + (!s->s.h.fixcompref || !s->left_ref_ctx[row7] || + !s->above_ref_ctx[col]); + } else { + c = (3 * !s->above_ref_ctx[col]) + + (!s->s.h.fixcompref || !s->left_ref_ctx[row7]); + } + } else if (s->above_comp_ctx[col]) { + c = (3 * !s->left_ref_ctx[row7]) + + (!s->s.h.fixcompref || !s->above_ref_ctx[col]); + } else { + c = 2 * !s->left_ref_ctx[row7] + 2 * !s->above_ref_ctx[col]; + } + } else if (s->above_intra_ctx[col]) { + c = 2; + } else if (s->above_comp_ctx[col]) { + c = 1 + (!s->s.h.fixcompref || !s->above_ref_ctx[col]); + } else { + c = 4 * (!s->above_ref_ctx[col]); + } + } else if (have_l && !s->left_intra_ctx[row7]) { + if (s->left_intra_ctx[row7]) { + c = 2; + } else if (s->left_comp_ctx[row7]) { + c = 1 + (!s->s.h.fixcompref || !s->left_ref_ctx[row7]); + } else { + c = 4 * (!s->left_ref_ctx[row7]); + } + } else { + c = 2; + } + bit = vp56_rac_get_prob(&s->c, s->prob.p.single_ref[c][0]); + s->counts.single_ref[c][0][bit]++; + if (!bit) { + b->ref[0] = 0; + } else { + // FIXME can this codeblob be replaced by some sort of LUT? + if (have_a) { + if (have_l) { + if (s->left_intra_ctx[row7]) { + if (s->above_intra_ctx[col]) { + c = 2; + } else if (s->above_comp_ctx[col]) { + c = 1 + 2 * (s->s.h.fixcompref == 1 || + s->above_ref_ctx[col] == 1); + } else if (!s->above_ref_ctx[col]) { + c = 3; + } else { + c = 4 * (s->above_ref_ctx[col] == 1); + } + } else if (s->above_intra_ctx[col]) { + if (s->left_intra_ctx[row7]) { + c = 2; + } else if (s->left_comp_ctx[row7]) { + c = 1 + 2 * (s->s.h.fixcompref == 1 || + s->left_ref_ctx[row7] == 1); + } else if (!s->left_ref_ctx[row7]) { + c = 3; + } else { + c = 4 * (s->left_ref_ctx[row7] == 1); + } + } else if (s->above_comp_ctx[col]) { + if (s->left_comp_ctx[row7]) { + if (s->left_ref_ctx[row7] == s->above_ref_ctx[col]) { + c = 3 * (s->s.h.fixcompref == 1 || + s->left_ref_ctx[row7] == 1); + } else { + c = 2; + } + } else if (!s->left_ref_ctx[row7]) { + c = 1 + 2 * (s->s.h.fixcompref == 1 || + s->above_ref_ctx[col] == 1); + } else { + c = 3 * (s->left_ref_ctx[row7] == 1) + + (s->s.h.fixcompref == 1 || s->above_ref_ctx[col] == 1); + } + } else if (s->left_comp_ctx[row7]) { + if (!s->above_ref_ctx[col]) { + c = 1 + 2 * (s->s.h.fixcompref == 1 || + s->left_ref_ctx[row7] == 1); + } else { + c = 3 * (s->above_ref_ctx[col] == 1) + + (s->s.h.fixcompref == 1 || s->left_ref_ctx[row7] == 1); + } + } else if (!s->above_ref_ctx[col]) { + if (!s->left_ref_ctx[row7]) { + c = 3; + } else { + c = 4 * (s->left_ref_ctx[row7] == 1); + } + } else if (!s->left_ref_ctx[row7]) { + c = 4 * (s->above_ref_ctx[col] == 1); + } else { + c = 2 * (s->left_ref_ctx[row7] == 1) + + 2 * (s->above_ref_ctx[col] == 1); + } + } else { + if (s->above_intra_ctx[col] || + (!s->above_comp_ctx[col] && !s->above_ref_ctx[col])) { + c = 2; + } else if (s->above_comp_ctx[col]) { + c = 3 * (s->s.h.fixcompref == 1 || s->above_ref_ctx[col] == 1); + } else { + c = 4 * (s->above_ref_ctx[col] == 1); + } + } + } else if (have_l) { + if (s->left_intra_ctx[row7] || + (!s->left_comp_ctx[row7] && !s->left_ref_ctx[row7])) { + c = 2; + } else if (s->left_comp_ctx[row7]) { + c = 3 * (s->s.h.fixcompref == 1 || s->left_ref_ctx[row7] == 1); + } else { + c = 4 * (s->left_ref_ctx[row7] == 1); + } + } else { + c = 2; + } + bit = vp56_rac_get_prob(&s->c, s->prob.p.single_ref[c][1]); + s->counts.single_ref[c][1][bit]++; + b->ref[0] = 1 + bit; + } + } + } + + if (b->bs <= BS_8x8) { + if (s->s.h.segmentation.enabled && s->s.h.segmentation.feat[b->seg_id].skip_enabled) { + b->mode[0] = b->mode[1] = b->mode[2] = b->mode[3] = ZEROMV; + } else { + static const uint8_t off[10] = { + 3, 0, 0, 1, 0, 0, 0, 0, 0, 0 + }; + + // FIXME this needs to use the LUT tables from find_ref_mvs + // because not all are -1,0/0,-1 + int c = inter_mode_ctx_lut[s->above_mode_ctx[col + off[b->bs]]] + [s->left_mode_ctx[row7 + off[b->bs]]]; + + b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree, + s->prob.p.mv_mode[c]); + b->mode[1] = b->mode[2] = b->mode[3] = b->mode[0]; + s->counts.mv_mode[c][b->mode[0] - 10]++; + } + } + + if (s->s.h.filtermode == FILTER_SWITCHABLE) { + int c; + + if (have_a && s->above_mode_ctx[col] >= NEARESTMV) { + if (have_l && s->left_mode_ctx[row7] >= NEARESTMV) { + c = s->above_filter_ctx[col] == s->left_filter_ctx[row7] ? + s->left_filter_ctx[row7] : 3; + } else { + c = s->above_filter_ctx[col]; + } + } else if (have_l && s->left_mode_ctx[row7] >= NEARESTMV) { + c = s->left_filter_ctx[row7]; + } else { + c = 3; + } + + filter_id = vp8_rac_get_tree(&s->c, ff_vp9_filter_tree, + s->prob.p.filter[c]); + s->counts.filter[c][filter_id]++; + b->filter = ff_vp9_filter_lut[filter_id]; + } else { + b->filter = s->s.h.filtermode; + } + + if (b->bs > BS_8x8) { + int c = inter_mode_ctx_lut[s->above_mode_ctx[col]][s->left_mode_ctx[row7]]; + + b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree, + s->prob.p.mv_mode[c]); + s->counts.mv_mode[c][b->mode[0] - 10]++; + ff_vp9_fill_mv(s, b->mv[0], b->mode[0], 0); + + if (b->bs != BS_8x4) { + b->mode[1] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree, + s->prob.p.mv_mode[c]); + s->counts.mv_mode[c][b->mode[1] - 10]++; + ff_vp9_fill_mv(s, b->mv[1], b->mode[1], 1); + } else { + b->mode[1] = b->mode[0]; + AV_COPY32(&b->mv[1][0], &b->mv[0][0]); + AV_COPY32(&b->mv[1][1], &b->mv[0][1]); + } + + if (b->bs != BS_4x8) { + b->mode[2] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree, + s->prob.p.mv_mode[c]); + s->counts.mv_mode[c][b->mode[2] - 10]++; + ff_vp9_fill_mv(s, b->mv[2], b->mode[2], 2); + + if (b->bs != BS_8x4) { + b->mode[3] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree, + s->prob.p.mv_mode[c]); + s->counts.mv_mode[c][b->mode[3] - 10]++; + ff_vp9_fill_mv(s, b->mv[3], b->mode[3], 3); + } else { + b->mode[3] = b->mode[2]; + AV_COPY32(&b->mv[3][0], &b->mv[2][0]); + AV_COPY32(&b->mv[3][1], &b->mv[2][1]); + } + } else { + b->mode[2] = b->mode[0]; + AV_COPY32(&b->mv[2][0], &b->mv[0][0]); + AV_COPY32(&b->mv[2][1], &b->mv[0][1]); + b->mode[3] = b->mode[1]; + AV_COPY32(&b->mv[3][0], &b->mv[1][0]); + AV_COPY32(&b->mv[3][1], &b->mv[1][1]); + } + } else { + ff_vp9_fill_mv(s, b->mv[0], b->mode[0], -1); + AV_COPY32(&b->mv[1][0], &b->mv[0][0]); + AV_COPY32(&b->mv[2][0], &b->mv[0][0]); + AV_COPY32(&b->mv[3][0], &b->mv[0][0]); + AV_COPY32(&b->mv[1][1], &b->mv[0][1]); + AV_COPY32(&b->mv[2][1], &b->mv[0][1]); + AV_COPY32(&b->mv[3][1], &b->mv[0][1]); + } + + vref = b->ref[b->comp ? s->s.h.signbias[s->s.h.varcompref[0]] : 0]; + } + +#if HAVE_FAST_64BIT +#define SPLAT_CTX(var, val, n) \ + switch (n) { \ + case 1: var = val; break; \ + case 2: AV_WN16A(&var, val * 0x0101); break; \ + case 4: AV_WN32A(&var, val * 0x01010101); break; \ + case 8: AV_WN64A(&var, val * 0x0101010101010101ULL); break; \ + case 16: { \ + uint64_t v64 = val * 0x0101010101010101ULL; \ + AV_WN64A( &var, v64); \ + AV_WN64A(&((uint8_t *) &var)[8], v64); \ + break; \ + } \ + } +#else +#define SPLAT_CTX(var, val, n) \ + switch (n) { \ + case 1: var = val; break; \ + case 2: AV_WN16A(&var, val * 0x0101); break; \ + case 4: AV_WN32A(&var, val * 0x01010101); break; \ + case 8: { \ + uint32_t v32 = val * 0x01010101; \ + AV_WN32A( &var, v32); \ + AV_WN32A(&((uint8_t *) &var)[4], v32); \ + break; \ + } \ + case 16: { \ + uint32_t v32 = val * 0x01010101; \ + AV_WN32A( &var, v32); \ + AV_WN32A(&((uint8_t *) &var)[4], v32); \ + AV_WN32A(&((uint8_t *) &var)[8], v32); \ + AV_WN32A(&((uint8_t *) &var)[12], v32); \ + break; \ + } \ + } +#endif + + switch (bwh_tab[1][b->bs][0]) { +#define SET_CTXS(dir, off, n) \ + do { \ + SPLAT_CTX(s->dir##_skip_ctx[off], b->skip, n); \ + SPLAT_CTX(s->dir##_txfm_ctx[off], b->tx, n); \ + SPLAT_CTX(s->dir##_partition_ctx[off], dir##_ctx[b->bs], n); \ + if (!s->s.h.keyframe && !s->s.h.intraonly) { \ + SPLAT_CTX(s->dir##_intra_ctx[off], b->intra, n); \ + SPLAT_CTX(s->dir##_comp_ctx[off], b->comp, n); \ + SPLAT_CTX(s->dir##_mode_ctx[off], b->mode[3], n); \ + if (!b->intra) { \ + SPLAT_CTX(s->dir##_ref_ctx[off], vref, n); \ + if (s->s.h.filtermode == FILTER_SWITCHABLE) { \ + SPLAT_CTX(s->dir##_filter_ctx[off], filter_id, n); \ + } \ + } \ + } \ + } while (0) + case 1: SET_CTXS(above, col, 1); break; + case 2: SET_CTXS(above, col, 2); break; + case 4: SET_CTXS(above, col, 4); break; + case 8: SET_CTXS(above, col, 8); break; + } + switch (bwh_tab[1][b->bs][1]) { + case 1: SET_CTXS(left, row7, 1); break; + case 2: SET_CTXS(left, row7, 2); break; + case 4: SET_CTXS(left, row7, 4); break; + case 8: SET_CTXS(left, row7, 8); break; + } +#undef SPLAT_CTX +#undef SET_CTXS + + if (!s->s.h.keyframe && !s->s.h.intraonly) { + if (b->bs > BS_8x8) { + int mv0 = AV_RN32A(&b->mv[3][0]), mv1 = AV_RN32A(&b->mv[3][1]); + + AV_COPY32(&s->left_mv_ctx[row7 * 2 + 0][0], &b->mv[1][0]); + AV_COPY32(&s->left_mv_ctx[row7 * 2 + 0][1], &b->mv[1][1]); + AV_WN32A(&s->left_mv_ctx[row7 * 2 + 1][0], mv0); + AV_WN32A(&s->left_mv_ctx[row7 * 2 + 1][1], mv1); + AV_COPY32(&s->above_mv_ctx[col * 2 + 0][0], &b->mv[2][0]); + AV_COPY32(&s->above_mv_ctx[col * 2 + 0][1], &b->mv[2][1]); + AV_WN32A(&s->above_mv_ctx[col * 2 + 1][0], mv0); + AV_WN32A(&s->above_mv_ctx[col * 2 + 1][1], mv1); + } else { + int n, mv0 = AV_RN32A(&b->mv[3][0]), mv1 = AV_RN32A(&b->mv[3][1]); + + for (n = 0; n < w4 * 2; n++) { + AV_WN32A(&s->above_mv_ctx[col * 2 + n][0], mv0); + AV_WN32A(&s->above_mv_ctx[col * 2 + n][1], mv1); + } + for (n = 0; n < h4 * 2; n++) { + AV_WN32A(&s->left_mv_ctx[row7 * 2 + n][0], mv0); + AV_WN32A(&s->left_mv_ctx[row7 * 2 + n][1], mv1); + } + } + } + + // FIXME kinda ugly + for (y = 0; y < h4; y++) { + int x, o = (row + y) * s->sb_cols * 8 + col; + struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[o]; + + if (b->intra) { + for (x = 0; x < w4; x++) { + mv[x].ref[0] = + mv[x].ref[1] = -1; + } + } else if (b->comp) { + for (x = 0; x < w4; x++) { + mv[x].ref[0] = b->ref[0]; + mv[x].ref[1] = b->ref[1]; + AV_COPY32(&mv[x].mv[0], &b->mv[3][0]); + AV_COPY32(&mv[x].mv[1], &b->mv[3][1]); + } + } else { + for (x = 0; x < w4; x++) { + mv[x].ref[0] = b->ref[0]; + mv[x].ref[1] = -1; + AV_COPY32(&mv[x].mv[0], &b->mv[3][0]); + } + } + } +} + +// FIXME merge cnt/eob arguments? +static av_always_inline int +decode_coeffs_b_generic(VP56RangeCoder *c, int16_t *coef, int n_coeffs, + int is_tx32x32, int is8bitsperpixel, int bpp, unsigned (*cnt)[6][3], + unsigned (*eob)[6][2], uint8_t (*p)[6][11], + int nnz, const int16_t *scan, const int16_t (*nb)[2], + const int16_t *band_counts, const int16_t *qmul) +{ + int i = 0, band = 0, band_left = band_counts[band]; + uint8_t *tp = p[0][nnz]; + uint8_t cache[1024]; + + do { + int val, rc; + + val = vp56_rac_get_prob_branchy(c, tp[0]); // eob + eob[band][nnz][val]++; + if (!val) + break; + + skip_eob: + if (!vp56_rac_get_prob_branchy(c, tp[1])) { // zero + cnt[band][nnz][0]++; + if (!--band_left) + band_left = band_counts[++band]; + cache[scan[i]] = 0; + nnz = (1 + cache[nb[i][0]] + cache[nb[i][1]]) >> 1; + tp = p[band][nnz]; + if (++i == n_coeffs) + break; //invalid input; blocks should end with EOB + goto skip_eob; + } + + rc = scan[i]; + if (!vp56_rac_get_prob_branchy(c, tp[2])) { // one + cnt[band][nnz][1]++; + val = 1; + cache[rc] = 1; + } else { + // fill in p[3-10] (model fill) - only once per frame for each pos + if (!tp[3]) + memcpy(&tp[3], ff_vp9_model_pareto8[tp[2]], 8); + + cnt[band][nnz][2]++; + if (!vp56_rac_get_prob_branchy(c, tp[3])) { // 2, 3, 4 + if (!vp56_rac_get_prob_branchy(c, tp[4])) { + cache[rc] = val = 2; + } else { + val = 3 + vp56_rac_get_prob(c, tp[5]); + cache[rc] = 3; + } + } else if (!vp56_rac_get_prob_branchy(c, tp[6])) { // cat1/2 + cache[rc] = 4; + if (!vp56_rac_get_prob_branchy(c, tp[7])) { + val = 5 + vp56_rac_get_prob(c, 159); + } else { + val = 7 + (vp56_rac_get_prob(c, 165) << 1); + val += vp56_rac_get_prob(c, 145); + } + } else { // cat 3-6 + cache[rc] = 5; + if (!vp56_rac_get_prob_branchy(c, tp[8])) { + if (!vp56_rac_get_prob_branchy(c, tp[9])) { + val = 11 + (vp56_rac_get_prob(c, 173) << 2); + val += (vp56_rac_get_prob(c, 148) << 1); + val += vp56_rac_get_prob(c, 140); + } else { + val = 19 + (vp56_rac_get_prob(c, 176) << 3); + val += (vp56_rac_get_prob(c, 155) << 2); + val += (vp56_rac_get_prob(c, 140) << 1); + val += vp56_rac_get_prob(c, 135); + } + } else if (!vp56_rac_get_prob_branchy(c, tp[10])) { + val = 35 + (vp56_rac_get_prob(c, 180) << 4); + val += (vp56_rac_get_prob(c, 157) << 3); + val += (vp56_rac_get_prob(c, 141) << 2); + val += (vp56_rac_get_prob(c, 134) << 1); + val += vp56_rac_get_prob(c, 130); + } else { + val = 67; + if (!is8bitsperpixel) { + if (bpp == 12) { + val += vp56_rac_get_prob(c, 255) << 17; + val += vp56_rac_get_prob(c, 255) << 16; + } + val += (vp56_rac_get_prob(c, 255) << 15); + val += (vp56_rac_get_prob(c, 255) << 14); + } + val += (vp56_rac_get_prob(c, 254) << 13); + val += (vp56_rac_get_prob(c, 254) << 12); + val += (vp56_rac_get_prob(c, 254) << 11); + val += (vp56_rac_get_prob(c, 252) << 10); + val += (vp56_rac_get_prob(c, 249) << 9); + val += (vp56_rac_get_prob(c, 243) << 8); + val += (vp56_rac_get_prob(c, 230) << 7); + val += (vp56_rac_get_prob(c, 196) << 6); + val += (vp56_rac_get_prob(c, 177) << 5); + val += (vp56_rac_get_prob(c, 153) << 4); + val += (vp56_rac_get_prob(c, 140) << 3); + val += (vp56_rac_get_prob(c, 133) << 2); + val += (vp56_rac_get_prob(c, 130) << 1); + val += vp56_rac_get_prob(c, 129); + } + } + } +#define STORE_COEF(c, i, v) do { \ + if (is8bitsperpixel) { \ + c[i] = v; \ + } else { \ + AV_WN32A(&c[i * 2], v); \ + } \ +} while (0) + if (!--band_left) + band_left = band_counts[++band]; + if (is_tx32x32) + STORE_COEF(coef, rc, ((vp8_rac_get(c) ? -val : val) * qmul[!!i]) / 2); + else + STORE_COEF(coef, rc, (vp8_rac_get(c) ? -val : val) * qmul[!!i]); + nnz = (1 + cache[nb[i][0]] + cache[nb[i][1]]) >> 1; + tp = p[band][nnz]; + } while (++i < n_coeffs); + + return i; +} + +static int decode_coeffs_b_8bpp(VP9Context *s, int16_t *coef, int n_coeffs, + unsigned (*cnt)[6][3], unsigned (*eob)[6][2], + uint8_t (*p)[6][11], int nnz, const int16_t *scan, + const int16_t (*nb)[2], const int16_t *band_counts, + const int16_t *qmul) +{ + return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 0, 1, 8, cnt, eob, p, + nnz, scan, nb, band_counts, qmul); +} + +static int decode_coeffs_b32_8bpp(VP9Context *s, int16_t *coef, int n_coeffs, + unsigned (*cnt)[6][3], unsigned (*eob)[6][2], + uint8_t (*p)[6][11], int nnz, const int16_t *scan, + const int16_t (*nb)[2], const int16_t *band_counts, + const int16_t *qmul) +{ + return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 1, 1, 8, cnt, eob, p, + nnz, scan, nb, band_counts, qmul); +} + +static int decode_coeffs_b_16bpp(VP9Context *s, int16_t *coef, int n_coeffs, + unsigned (*cnt)[6][3], unsigned (*eob)[6][2], + uint8_t (*p)[6][11], int nnz, const int16_t *scan, + const int16_t (*nb)[2], const int16_t *band_counts, + const int16_t *qmul) +{ + return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 0, 0, s->s.h.bpp, cnt, eob, p, + nnz, scan, nb, band_counts, qmul); +} + +static int decode_coeffs_b32_16bpp(VP9Context *s, int16_t *coef, int n_coeffs, + unsigned (*cnt)[6][3], unsigned (*eob)[6][2], + uint8_t (*p)[6][11], int nnz, const int16_t *scan, + const int16_t (*nb)[2], const int16_t *band_counts, + const int16_t *qmul) +{ + return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 1, 0, s->s.h.bpp, cnt, eob, p, + nnz, scan, nb, band_counts, qmul); +} + +static av_always_inline int decode_coeffs(AVCodecContext *ctx, int is8bitsperpixel) +{ + VP9Context *s = ctx->priv_data; + VP9Block *b = s->b; + int row = s->row, col = s->col; + uint8_t (*p)[6][11] = s->prob.coef[b->tx][0 /* y */][!b->intra]; + unsigned (*c)[6][3] = s->counts.coef[b->tx][0 /* y */][!b->intra]; + unsigned (*e)[6][2] = s->counts.eob[b->tx][0 /* y */][!b->intra]; + int w4 = bwh_tab[1][b->bs][0] << 1, h4 = bwh_tab[1][b->bs][1] << 1; + int end_x = FFMIN(2 * (s->cols - col), w4); + int end_y = FFMIN(2 * (s->rows - row), h4); + int n, pl, x, y, res; + int16_t (*qmul)[2] = s->s.h.segmentation.feat[b->seg_id].qmul; + int tx = 4 * s->s.h.lossless + b->tx; + const int16_t * const *yscans = ff_vp9_scans[tx]; + const int16_t (* const *ynbs)[2] = ff_vp9_scans_nb[tx]; + const int16_t *uvscan = ff_vp9_scans[b->uvtx][DCT_DCT]; + const int16_t (*uvnb)[2] = ff_vp9_scans_nb[b->uvtx][DCT_DCT]; + uint8_t *a = &s->above_y_nnz_ctx[col * 2]; + uint8_t *l = &s->left_y_nnz_ctx[(row & 7) << 1]; + static const int16_t band_counts[4][8] = { + { 1, 2, 3, 4, 3, 16 - 13 }, + { 1, 2, 3, 4, 11, 64 - 21 }, + { 1, 2, 3, 4, 11, 256 - 21 }, + { 1, 2, 3, 4, 11, 1024 - 21 }, + }; + const int16_t *y_band_counts = band_counts[b->tx]; + const int16_t *uv_band_counts = band_counts[b->uvtx]; + int bytesperpixel = is8bitsperpixel ? 1 : 2; + int total_coeff = 0; + +#define MERGE(la, end, step, rd) \ + for (n = 0; n < end; n += step) \ + la[n] = !!rd(&la[n]) +#define MERGE_CTX(step, rd) \ + do { \ + MERGE(l, end_y, step, rd); \ + MERGE(a, end_x, step, rd); \ + } while (0) + +#define DECODE_Y_COEF_LOOP(step, mode_index, v) \ + for (n = 0, y = 0; y < end_y; y += step) { \ + for (x = 0; x < end_x; x += step, n += step * step) { \ + enum TxfmType txtp = ff_vp9_intra_txfm_type[b->mode[mode_index]]; \ + res = (is8bitsperpixel ? decode_coeffs_b##v##_8bpp : decode_coeffs_b##v##_16bpp) \ + (s, s->block + 16 * n * bytesperpixel, 16 * step * step, \ + c, e, p, a[x] + l[y], yscans[txtp], \ + ynbs[txtp], y_band_counts, qmul[0]); \ + a[x] = l[y] = !!res; \ + total_coeff |= !!res; \ + if (step >= 4) { \ + AV_WN16A(&s->eob[n], res); \ + } else { \ + s->eob[n] = res; \ + } \ + } \ + } + +#define SPLAT(la, end, step, cond) \ + if (step == 2) { \ + for (n = 1; n < end; n += step) \ + la[n] = la[n - 1]; \ + } else if (step == 4) { \ + if (cond) { \ + for (n = 0; n < end; n += step) \ + AV_WN32A(&la[n], la[n] * 0x01010101); \ + } else { \ + for (n = 0; n < end; n += step) \ + memset(&la[n + 1], la[n], FFMIN(end - n - 1, 3)); \ + } \ + } else /* step == 8 */ { \ + if (cond) { \ + if (HAVE_FAST_64BIT) { \ + for (n = 0; n < end; n += step) \ + AV_WN64A(&la[n], la[n] * 0x0101010101010101ULL); \ + } else { \ + for (n = 0; n < end; n += step) { \ + uint32_t v32 = la[n] * 0x01010101; \ + AV_WN32A(&la[n], v32); \ + AV_WN32A(&la[n + 4], v32); \ + } \ + } \ + } else { \ + for (n = 0; n < end; n += step) \ + memset(&la[n + 1], la[n], FFMIN(end - n - 1, 7)); \ + } \ + } +#define SPLAT_CTX(step) \ + do { \ + SPLAT(a, end_x, step, end_x == w4); \ + SPLAT(l, end_y, step, end_y == h4); \ + } while (0) + + /* y tokens */ + switch (b->tx) { + case TX_4X4: + DECODE_Y_COEF_LOOP(1, b->bs > BS_8x8 ? n : 0,); + break; + case TX_8X8: + MERGE_CTX(2, AV_RN16A); + DECODE_Y_COEF_LOOP(2, 0,); + SPLAT_CTX(2); + break; + case TX_16X16: + MERGE_CTX(4, AV_RN32A); + DECODE_Y_COEF_LOOP(4, 0,); + SPLAT_CTX(4); + break; + case TX_32X32: + MERGE_CTX(8, AV_RN64A); + DECODE_Y_COEF_LOOP(8, 0, 32); + SPLAT_CTX(8); + break; + } + +#define DECODE_UV_COEF_LOOP(step, v) \ + for (n = 0, y = 0; y < end_y; y += step) { \ + for (x = 0; x < end_x; x += step, n += step * step) { \ + res = (is8bitsperpixel ? decode_coeffs_b##v##_8bpp : decode_coeffs_b##v##_16bpp) \ + (s, s->uvblock[pl] + 16 * n * bytesperpixel, \ + 16 * step * step, c, e, p, a[x] + l[y], \ + uvscan, uvnb, uv_band_counts, qmul[1]); \ + a[x] = l[y] = !!res; \ + total_coeff |= !!res; \ + if (step >= 4) { \ + AV_WN16A(&s->uveob[pl][n], res); \ + } else { \ + s->uveob[pl][n] = res; \ + } \ + } \ + } + + p = s->prob.coef[b->uvtx][1 /* uv */][!b->intra]; + c = s->counts.coef[b->uvtx][1 /* uv */][!b->intra]; + e = s->counts.eob[b->uvtx][1 /* uv */][!b->intra]; + w4 >>= s->ss_h; + end_x >>= s->ss_h; + h4 >>= s->ss_v; + end_y >>= s->ss_v; + for (pl = 0; pl < 2; pl++) { + a = &s->above_uv_nnz_ctx[pl][col << !s->ss_h]; + l = &s->left_uv_nnz_ctx[pl][(row & 7) << !s->ss_v]; + switch (b->uvtx) { + case TX_4X4: + DECODE_UV_COEF_LOOP(1,); + break; + case TX_8X8: + MERGE_CTX(2, AV_RN16A); + DECODE_UV_COEF_LOOP(2,); + SPLAT_CTX(2); + break; + case TX_16X16: + MERGE_CTX(4, AV_RN32A); + DECODE_UV_COEF_LOOP(4,); + SPLAT_CTX(4); + break; + case TX_32X32: + MERGE_CTX(8, AV_RN64A); + DECODE_UV_COEF_LOOP(8, 32); + SPLAT_CTX(8); + break; + } + } + + return total_coeff; +} + +static int decode_coeffs_8bpp(AVCodecContext *ctx) +{ + return decode_coeffs(ctx, 1); +} + +static int decode_coeffs_16bpp(AVCodecContext *ctx) +{ + return decode_coeffs(ctx, 0); +} + +static av_always_inline int check_intra_mode(VP9Context *s, int mode, uint8_t **a, + uint8_t *dst_edge, ptrdiff_t stride_edge, + uint8_t *dst_inner, ptrdiff_t stride_inner, + uint8_t *l, int col, int x, int w, + int row, int y, enum TxfmMode tx, + int p, int ss_h, int ss_v, int bytesperpixel) +{ + int have_top = row > 0 || y > 0; + int have_left = col > s->tile_col_start || x > 0; + int have_right = x < w - 1; + int bpp = s->s.h.bpp; + static const uint8_t mode_conv[10][2 /* have_left */][2 /* have_top */] = { + [VERT_PRED] = { { DC_127_PRED, VERT_PRED }, + { DC_127_PRED, VERT_PRED } }, + [HOR_PRED] = { { DC_129_PRED, DC_129_PRED }, + { HOR_PRED, HOR_PRED } }, + [DC_PRED] = { { DC_128_PRED, TOP_DC_PRED }, + { LEFT_DC_PRED, DC_PRED } }, + [DIAG_DOWN_LEFT_PRED] = { { DC_127_PRED, DIAG_DOWN_LEFT_PRED }, + { DC_127_PRED, DIAG_DOWN_LEFT_PRED } }, + [DIAG_DOWN_RIGHT_PRED] = { { DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED }, + { DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED } }, + [VERT_RIGHT_PRED] = { { VERT_RIGHT_PRED, VERT_RIGHT_PRED }, + { VERT_RIGHT_PRED, VERT_RIGHT_PRED } }, + [HOR_DOWN_PRED] = { { HOR_DOWN_PRED, HOR_DOWN_PRED }, + { HOR_DOWN_PRED, HOR_DOWN_PRED } }, + [VERT_LEFT_PRED] = { { DC_127_PRED, VERT_LEFT_PRED }, + { DC_127_PRED, VERT_LEFT_PRED } }, + [HOR_UP_PRED] = { { DC_129_PRED, DC_129_PRED }, + { HOR_UP_PRED, HOR_UP_PRED } }, + [TM_VP8_PRED] = { { DC_129_PRED, VERT_PRED }, + { HOR_PRED, TM_VP8_PRED } }, + }; + static const struct { + uint8_t needs_left:1; + uint8_t needs_top:1; + uint8_t needs_topleft:1; + uint8_t needs_topright:1; + uint8_t invert_left:1; + } edges[N_INTRA_PRED_MODES] = { + [VERT_PRED] = { .needs_top = 1 }, + [HOR_PRED] = { .needs_left = 1 }, + [DC_PRED] = { .needs_top = 1, .needs_left = 1 }, + [DIAG_DOWN_LEFT_PRED] = { .needs_top = 1, .needs_topright = 1 }, + [DIAG_DOWN_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 }, + [VERT_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 }, + [HOR_DOWN_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 }, + [VERT_LEFT_PRED] = { .needs_top = 1, .needs_topright = 1 }, + [HOR_UP_PRED] = { .needs_left = 1, .invert_left = 1 }, + [TM_VP8_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 }, + [LEFT_DC_PRED] = { .needs_left = 1 }, + [TOP_DC_PRED] = { .needs_top = 1 }, + [DC_128_PRED] = { 0 }, + [DC_127_PRED] = { 0 }, + [DC_129_PRED] = { 0 } + }; + + av_assert2(mode >= 0 && mode < 10); + mode = mode_conv[mode][have_left][have_top]; + if (edges[mode].needs_top) { + uint8_t *top, *topleft; + int n_px_need = 4 << tx, n_px_have = (((s->cols - col) << !ss_h) - x) * 4; + int n_px_need_tr = 0; + + if (tx == TX_4X4 && edges[mode].needs_topright && have_right) + n_px_need_tr = 4; + + // if top of sb64-row, use s->intra_pred_data[] instead of + // dst[-stride] for intra prediction (it contains pre- instead of + // post-loopfilter data) + if (have_top) { + top = !(row & 7) && !y ? + s->intra_pred_data[p] + (col * (8 >> ss_h) + x * 4) * bytesperpixel : + y == 0 ? &dst_edge[-stride_edge] : &dst_inner[-stride_inner]; + if (have_left) + topleft = !(row & 7) && !y ? + s->intra_pred_data[p] + (col * (8 >> ss_h) + x * 4) * bytesperpixel : + y == 0 || x == 0 ? &dst_edge[-stride_edge] : + &dst_inner[-stride_inner]; + } + + if (have_top && + (!edges[mode].needs_topleft || (have_left && top == topleft)) && + (tx != TX_4X4 || !edges[mode].needs_topright || have_right) && + n_px_need + n_px_need_tr <= n_px_have) { + *a = top; + } else { + if (have_top) { + if (n_px_need <= n_px_have) { + memcpy(*a, top, n_px_need * bytesperpixel); + } else { +#define memset_bpp(c, i1, v, i2, num) do { \ + if (bytesperpixel == 1) { \ + memset(&(c)[(i1)], (v)[(i2)], (num)); \ + } else { \ + int n, val = AV_RN16A(&(v)[(i2) * 2]); \ + for (n = 0; n < (num); n++) { \ + AV_WN16A(&(c)[((i1) + n) * 2], val); \ + } \ + } \ +} while (0) + memcpy(*a, top, n_px_have * bytesperpixel); + memset_bpp(*a, n_px_have, (*a), n_px_have - 1, n_px_need - n_px_have); + } + } else { +#define memset_val(c, val, num) do { \ + if (bytesperpixel == 1) { \ + memset((c), (val), (num)); \ + } else { \ + int n; \ + for (n = 0; n < (num); n++) { \ + AV_WN16A(&(c)[n * 2], (val)); \ + } \ + } \ +} while (0) + memset_val(*a, (128 << (bpp - 8)) - 1, n_px_need); + } + if (edges[mode].needs_topleft) { + if (have_left && have_top) { +#define assign_bpp(c, i1, v, i2) do { \ + if (bytesperpixel == 1) { \ + (c)[(i1)] = (v)[(i2)]; \ + } else { \ + AV_COPY16(&(c)[(i1) * 2], &(v)[(i2) * 2]); \ + } \ +} while (0) + assign_bpp(*a, -1, topleft, -1); + } else { +#define assign_val(c, i, v) do { \ + if (bytesperpixel == 1) { \ + (c)[(i)] = (v); \ + } else { \ + AV_WN16A(&(c)[(i) * 2], (v)); \ + } \ +} while (0) + assign_val((*a), -1, (128 << (bpp - 8)) + (have_top ? +1 : -1)); + } + } + if (tx == TX_4X4 && edges[mode].needs_topright) { + if (have_top && have_right && + n_px_need + n_px_need_tr <= n_px_have) { + memcpy(&(*a)[4 * bytesperpixel], &top[4 * bytesperpixel], 4 * bytesperpixel); + } else { + memset_bpp(*a, 4, *a, 3, 4); + } + } + } + } + if (edges[mode].needs_left) { + if (have_left) { + int n_px_need = 4 << tx, i, n_px_have = (((s->rows - row) << !ss_v) - y) * 4; + uint8_t *dst = x == 0 ? dst_edge : dst_inner; + ptrdiff_t stride = x == 0 ? stride_edge : stride_inner; + + if (edges[mode].invert_left) { + if (n_px_need <= n_px_have) { + for (i = 0; i < n_px_need; i++) + assign_bpp(l, i, &dst[i * stride], -1); + } else { + for (i = 0; i < n_px_have; i++) + assign_bpp(l, i, &dst[i * stride], -1); + memset_bpp(l, n_px_have, l, n_px_have - 1, n_px_need - n_px_have); + } + } else { + if (n_px_need <= n_px_have) { + for (i = 0; i < n_px_need; i++) + assign_bpp(l, n_px_need - 1 - i, &dst[i * stride], -1); + } else { + for (i = 0; i < n_px_have; i++) + assign_bpp(l, n_px_need - 1 - i, &dst[i * stride], -1); + memset_bpp(l, 0, l, n_px_need - n_px_have, n_px_need - n_px_have); + } + } + } else { + memset_val(l, (128 << (bpp - 8)) + 1, 4 << tx); + } + } + + return mode; +} + +static av_always_inline void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off, + ptrdiff_t uv_off, int bytesperpixel) +{ + VP9Context *s = ctx->priv_data; + VP9Block *b = s->b; + int row = s->row, col = s->col; + int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n; + int h4 = bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2); + int end_x = FFMIN(2 * (s->cols - col), w4); + int end_y = FFMIN(2 * (s->rows - row), h4); + int tx = 4 * s->s.h.lossless + b->tx, uvtx = b->uvtx + 4 * s->s.h.lossless; + int uvstep1d = 1 << b->uvtx, p; + uint8_t *dst = s->dst[0], *dst_r = s->s.frames[CUR_FRAME].tf.f->data[0] + y_off; + LOCAL_ALIGNED_32(uint8_t, a_buf, [96]); + LOCAL_ALIGNED_32(uint8_t, l, [64]); + + for (n = 0, y = 0; y < end_y; y += step1d) { + uint8_t *ptr = dst, *ptr_r = dst_r; + for (x = 0; x < end_x; x += step1d, ptr += 4 * step1d * bytesperpixel, + ptr_r += 4 * step1d * bytesperpixel, n += step) { + int mode = b->mode[b->bs > BS_8x8 && b->tx == TX_4X4 ? + y * 2 + x : 0]; + uint8_t *a = &a_buf[32]; + enum TxfmType txtp = ff_vp9_intra_txfm_type[mode]; + int eob = b->skip ? 0 : b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n]; + + mode = check_intra_mode(s, mode, &a, ptr_r, + s->s.frames[CUR_FRAME].tf.f->linesize[0], + ptr, s->y_stride, l, + col, x, w4, row, y, b->tx, 0, 0, 0, bytesperpixel); + s->dsp.intra_pred[b->tx][mode](ptr, s->y_stride, l, a); + if (eob) + s->dsp.itxfm_add[tx][txtp](ptr, s->y_stride, + s->block + 16 * n * bytesperpixel, eob); + } + dst_r += 4 * step1d * s->s.frames[CUR_FRAME].tf.f->linesize[0]; + dst += 4 * step1d * s->y_stride; + } + + // U/V + w4 >>= s->ss_h; + end_x >>= s->ss_h; + end_y >>= s->ss_v; + step = 1 << (b->uvtx * 2); + for (p = 0; p < 2; p++) { + dst = s->dst[1 + p]; + dst_r = s->s.frames[CUR_FRAME].tf.f->data[1 + p] + uv_off; + for (n = 0, y = 0; y < end_y; y += uvstep1d) { + uint8_t *ptr = dst, *ptr_r = dst_r; + for (x = 0; x < end_x; x += uvstep1d, ptr += 4 * uvstep1d * bytesperpixel, + ptr_r += 4 * uvstep1d * bytesperpixel, n += step) { + int mode = b->uvmode; + uint8_t *a = &a_buf[32]; + int eob = b->skip ? 0 : b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n]; + + mode = check_intra_mode(s, mode, &a, ptr_r, + s->s.frames[CUR_FRAME].tf.f->linesize[1], + ptr, s->uv_stride, l, col, x, w4, row, y, + b->uvtx, p + 1, s->ss_h, s->ss_v, bytesperpixel); + s->dsp.intra_pred[b->uvtx][mode](ptr, s->uv_stride, l, a); + if (eob) + s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride, + s->uvblock[p] + 16 * n * bytesperpixel, eob); + } + dst_r += 4 * uvstep1d * s->s.frames[CUR_FRAME].tf.f->linesize[1]; + dst += 4 * uvstep1d * s->uv_stride; + } + } +} + +static void intra_recon_8bpp(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off) +{ + intra_recon(ctx, y_off, uv_off, 1); +} + +static void intra_recon_16bpp(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off) +{ + intra_recon(ctx, y_off, uv_off, 2); +} + +static av_always_inline void mc_luma_unscaled(VP9Context *s, vp9_mc_func (*mc)[2], + uint8_t *dst, ptrdiff_t dst_stride, + const uint8_t *ref, ptrdiff_t ref_stride, + ThreadFrame *ref_frame, + ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, + int bw, int bh, int w, int h, int bytesperpixel) +{ + int mx = mv->x, my = mv->y, th; + + y += my >> 3; + x += mx >> 3; + ref += y * ref_stride + x * bytesperpixel; + mx &= 7; + my &= 7; + // FIXME bilinear filter only needs 0/1 pixels, not 3/4 + // we use +7 because the last 7 pixels of each sbrow can be changed in + // the longest loopfilter of the next sbrow + th = (y + bh + 4 * !!my + 7) >> 6; + ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); + // The arm/aarch64 _hv filters read one more row than what actually is + // needed, so switch to emulated edge one pixel sooner vertically + // (!!my * 5) than horizontally (!!mx * 4). + if (x < !!mx * 3 || y < !!my * 3 || + x + !!mx * 4 > w - bw || y + !!my * 5 > h - bh) { + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + ref - !!my * 3 * ref_stride - !!mx * 3 * bytesperpixel, + 160, ref_stride, + bw + !!mx * 7, bh + !!my * 7, + x - !!mx * 3, y - !!my * 3, w, h); + ref = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; + ref_stride = 160; + } + mc[!!mx][!!my](dst, dst_stride, ref, ref_stride, bh, mx << 1, my << 1); +} + +static av_always_inline void mc_chroma_unscaled(VP9Context *s, vp9_mc_func (*mc)[2], + uint8_t *dst_u, uint8_t *dst_v, + ptrdiff_t dst_stride, + const uint8_t *ref_u, ptrdiff_t src_stride_u, + const uint8_t *ref_v, ptrdiff_t src_stride_v, + ThreadFrame *ref_frame, + ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, + int bw, int bh, int w, int h, int bytesperpixel) +{ + int mx = mv->x * (1 << !s->ss_h), my = mv->y * (1 << !s->ss_v), th; + + y += my >> 4; + x += mx >> 4; + ref_u += y * src_stride_u + x * bytesperpixel; + ref_v += y * src_stride_v + x * bytesperpixel; + mx &= 15; + my &= 15; + // FIXME bilinear filter only needs 0/1 pixels, not 3/4 + // we use +7 because the last 7 pixels of each sbrow can be changed in + // the longest loopfilter of the next sbrow + th = (y + bh + 4 * !!my + 7) >> (6 - s->ss_v); + ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); + // The arm/aarch64 _hv filters read one more row than what actually is + // needed, so switch to emulated edge one pixel sooner vertically + // (!!my * 5) than horizontally (!!mx * 4). + if (x < !!mx * 3 || y < !!my * 3 || + x + !!mx * 4 > w - bw || y + !!my * 5 > h - bh) { + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + ref_u - !!my * 3 * src_stride_u - !!mx * 3 * bytesperpixel, + 160, src_stride_u, + bw + !!mx * 7, bh + !!my * 7, + x - !!mx * 3, y - !!my * 3, w, h); + ref_u = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; + mc[!!mx][!!my](dst_u, dst_stride, ref_u, 160, bh, mx, my); + + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + ref_v - !!my * 3 * src_stride_v - !!mx * 3 * bytesperpixel, + 160, src_stride_v, + bw + !!mx * 7, bh + !!my * 7, + x - !!mx * 3, y - !!my * 3, w, h); + ref_v = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; + mc[!!mx][!!my](dst_v, dst_stride, ref_v, 160, bh, mx, my); + } else { + mc[!!mx][!!my](dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my); + mc[!!mx][!!my](dst_v, dst_stride, ref_v, src_stride_v, bh, mx, my); + } +} + +#define mc_luma_dir(s, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ + px, py, pw, ph, bw, bh, w, h, i) \ + mc_luma_unscaled(s, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ + mv, bw, bh, w, h, bytesperpixel) +#define mc_chroma_dir(s, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ + row, col, mv, px, py, pw, ph, bw, bh, w, h, i) \ + mc_chroma_unscaled(s, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ + row, col, mv, bw, bh, w, h, bytesperpixel) +#define SCALED 0 +#define FN(x) x##_8bpp +#define BYTES_PER_PIXEL 1 +#include "vp9_mc_template.c" +#undef FN +#undef BYTES_PER_PIXEL +#define FN(x) x##_16bpp +#define BYTES_PER_PIXEL 2 +#include "vp9_mc_template.c" +#undef mc_luma_dir +#undef mc_chroma_dir +#undef FN +#undef BYTES_PER_PIXEL +#undef SCALED + +static av_always_inline void mc_luma_scaled(VP9Context *s, vp9_scaled_mc_func smc, + vp9_mc_func (*mc)[2], + uint8_t *dst, ptrdiff_t dst_stride, + const uint8_t *ref, ptrdiff_t ref_stride, + ThreadFrame *ref_frame, + ptrdiff_t y, ptrdiff_t x, const VP56mv *in_mv, + int px, int py, int pw, int ph, + int bw, int bh, int w, int h, int bytesperpixel, + const uint16_t *scale, const uint8_t *step) +{ + if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width && + s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) { + mc_luma_unscaled(s, mc, dst, dst_stride, ref, ref_stride, ref_frame, + y, x, in_mv, bw, bh, w, h, bytesperpixel); + } else { +#define scale_mv(n, dim) (((int64_t)(n) * scale[dim]) >> 14) + int mx, my; + int refbw_m1, refbh_m1; + int th; + VP56mv mv; + + mv.x = av_clip(in_mv->x, -(x + pw - px + 4) * 8, (s->cols * 8 - x + px + 3) * 8); + mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 8, (s->rows * 8 - y + py + 3) * 8); + // BUG libvpx seems to scale the two components separately. This introduces + // rounding errors but we have to reproduce them to be exactly compatible + // with the output from libvpx... + mx = scale_mv(mv.x * 2, 0) + scale_mv(x * 16, 0); + my = scale_mv(mv.y * 2, 1) + scale_mv(y * 16, 1); + + y = my >> 4; + x = mx >> 4; + ref += y * ref_stride + x * bytesperpixel; + mx &= 15; + my &= 15; + refbw_m1 = ((bw - 1) * step[0] + mx) >> 4; + refbh_m1 = ((bh - 1) * step[1] + my) >> 4; + // FIXME bilinear filter only needs 0/1 pixels, not 3/4 + // we use +7 because the last 7 pixels of each sbrow can be changed in + // the longest loopfilter of the next sbrow + th = (y + refbh_m1 + 4 + 7) >> 6; + ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); + // The arm/aarch64 _hv filters read one more row than what actually is + // needed, so switch to emulated edge one pixel sooner vertically + // (y + 5 >= h - refbh_m1) than horizontally (x + 4 >= w - refbw_m1). + if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 5 >= h - refbh_m1) { + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + ref - 3 * ref_stride - 3 * bytesperpixel, + 288, ref_stride, + refbw_m1 + 8, refbh_m1 + 8, + x - 3, y - 3, w, h); + ref = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; + ref_stride = 288; + } + smc(dst, dst_stride, ref, ref_stride, bh, mx, my, step[0], step[1]); + } +} + +static av_always_inline void mc_chroma_scaled(VP9Context *s, vp9_scaled_mc_func smc, + vp9_mc_func (*mc)[2], + uint8_t *dst_u, uint8_t *dst_v, + ptrdiff_t dst_stride, + const uint8_t *ref_u, ptrdiff_t src_stride_u, + const uint8_t *ref_v, ptrdiff_t src_stride_v, + ThreadFrame *ref_frame, + ptrdiff_t y, ptrdiff_t x, const VP56mv *in_mv, + int px, int py, int pw, int ph, + int bw, int bh, int w, int h, int bytesperpixel, + const uint16_t *scale, const uint8_t *step) +{ + if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width && + s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) { + mc_chroma_unscaled(s, mc, dst_u, dst_v, dst_stride, ref_u, src_stride_u, + ref_v, src_stride_v, ref_frame, + y, x, in_mv, bw, bh, w, h, bytesperpixel); + } else { + int mx, my; + int refbw_m1, refbh_m1; + int th; + VP56mv mv; + + if (s->ss_h) { + // BUG https://code.google.com/p/webm/issues/detail?id=820 + mv.x = av_clip(in_mv->x, -(x + pw - px + 4) * 16, (s->cols * 4 - x + px + 3) * 16); + mx = scale_mv(mv.x, 0) + (scale_mv(x * 16, 0) & ~15) + (scale_mv(x * 32, 0) & 15); + } else { + mv.x = av_clip(in_mv->x, -(x + pw - px + 4) * 8, (s->cols * 8 - x + px + 3) * 8); + mx = scale_mv(mv.x * 2, 0) + scale_mv(x * 16, 0); + } + if (s->ss_v) { + // BUG https://code.google.com/p/webm/issues/detail?id=820 + mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 16, (s->rows * 4 - y + py + 3) * 16); + my = scale_mv(mv.y, 1) + (scale_mv(y * 16, 1) & ~15) + (scale_mv(y * 32, 1) & 15); + } else { + mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 8, (s->rows * 8 - y + py + 3) * 8); + my = scale_mv(mv.y * 2, 1) + scale_mv(y * 16, 1); + } +#undef scale_mv + y = my >> 4; + x = mx >> 4; + ref_u += y * src_stride_u + x * bytesperpixel; + ref_v += y * src_stride_v + x * bytesperpixel; + mx &= 15; + my &= 15; + refbw_m1 = ((bw - 1) * step[0] + mx) >> 4; + refbh_m1 = ((bh - 1) * step[1] + my) >> 4; + // FIXME bilinear filter only needs 0/1 pixels, not 3/4 + // we use +7 because the last 7 pixels of each sbrow can be changed in + // the longest loopfilter of the next sbrow + th = (y + refbh_m1 + 4 + 7) >> (6 - s->ss_v); + ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); + // The arm/aarch64 _hv filters read one more row than what actually is + // needed, so switch to emulated edge one pixel sooner vertically + // (y + 5 >= h - refbh_m1) than horizontally (x + 4 >= w - refbw_m1). + if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 5 >= h - refbh_m1) { + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + ref_u - 3 * src_stride_u - 3 * bytesperpixel, + 288, src_stride_u, + refbw_m1 + 8, refbh_m1 + 8, + x - 3, y - 3, w, h); + ref_u = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; + smc(dst_u, dst_stride, ref_u, 288, bh, mx, my, step[0], step[1]); + + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + ref_v - 3 * src_stride_v - 3 * bytesperpixel, + 288, src_stride_v, + refbw_m1 + 8, refbh_m1 + 8, + x - 3, y - 3, w, h); + ref_v = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; + smc(dst_v, dst_stride, ref_v, 288, bh, mx, my, step[0], step[1]); + } else { + smc(dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my, step[0], step[1]); + smc(dst_v, dst_stride, ref_v, src_stride_v, bh, mx, my, step[0], step[1]); + } + } +} + +#define mc_luma_dir(s, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ + px, py, pw, ph, bw, bh, w, h, i) \ + mc_luma_scaled(s, s->dsp.s##mc, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ + mv, px, py, pw, ph, bw, bh, w, h, bytesperpixel, \ + s->mvscale[b->ref[i]], s->mvstep[b->ref[i]]) +#define mc_chroma_dir(s, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ + row, col, mv, px, py, pw, ph, bw, bh, w, h, i) \ + mc_chroma_scaled(s, s->dsp.s##mc, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ + row, col, mv, px, py, pw, ph, bw, bh, w, h, bytesperpixel, \ + s->mvscale[b->ref[i]], s->mvstep[b->ref[i]]) +#define SCALED 1 +#define FN(x) x##_scaled_8bpp +#define BYTES_PER_PIXEL 1 +#include "vp9_mc_template.c" +#undef FN +#undef BYTES_PER_PIXEL +#define FN(x) x##_scaled_16bpp +#define BYTES_PER_PIXEL 2 +#include "vp9_mc_template.c" +#undef mc_luma_dir +#undef mc_chroma_dir +#undef FN +#undef BYTES_PER_PIXEL +#undef SCALED + +static av_always_inline void inter_recon(AVCodecContext *ctx, int bytesperpixel) +{ + VP9Context *s = ctx->priv_data; + VP9Block *b = s->b; + int row = s->row, col = s->col; + + if (s->mvscale[b->ref[0]][0] || (b->comp && s->mvscale[b->ref[1]][0])) { + if (bytesperpixel == 1) { + inter_pred_scaled_8bpp(ctx); + } else { + inter_pred_scaled_16bpp(ctx); + } + } else { + if (bytesperpixel == 1) { + inter_pred_8bpp(ctx); + } else { + inter_pred_16bpp(ctx); + } + } + if (!b->skip) { + /* mostly copied intra_recon() */ + + int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n; + int h4 = bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2); + int end_x = FFMIN(2 * (s->cols - col), w4); + int end_y = FFMIN(2 * (s->rows - row), h4); + int tx = 4 * s->s.h.lossless + b->tx, uvtx = b->uvtx + 4 * s->s.h.lossless; + int uvstep1d = 1 << b->uvtx, p; + uint8_t *dst = s->dst[0]; + + // y itxfm add + for (n = 0, y = 0; y < end_y; y += step1d) { + uint8_t *ptr = dst; + for (x = 0; x < end_x; x += step1d, + ptr += 4 * step1d * bytesperpixel, n += step) { + int eob = b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n]; + + if (eob) + s->dsp.itxfm_add[tx][DCT_DCT](ptr, s->y_stride, + s->block + 16 * n * bytesperpixel, eob); + } + dst += 4 * s->y_stride * step1d; + } + + // uv itxfm add + end_x >>= s->ss_h; + end_y >>= s->ss_v; + step = 1 << (b->uvtx * 2); + for (p = 0; p < 2; p++) { + dst = s->dst[p + 1]; + for (n = 0, y = 0; y < end_y; y += uvstep1d) { + uint8_t *ptr = dst; + for (x = 0; x < end_x; x += uvstep1d, + ptr += 4 * uvstep1d * bytesperpixel, n += step) { + int eob = b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n]; + + if (eob) + s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride, + s->uvblock[p] + 16 * n * bytesperpixel, eob); + } + dst += 4 * uvstep1d * s->uv_stride; + } + } + } +} + +static void inter_recon_8bpp(AVCodecContext *ctx) +{ + inter_recon(ctx, 1); +} + +static void inter_recon_16bpp(AVCodecContext *ctx) +{ + inter_recon(ctx, 2); +} + +static av_always_inline void mask_edges(uint8_t (*mask)[8][4], int ss_h, int ss_v, + int row_and_7, int col_and_7, + int w, int h, int col_end, int row_end, + enum TxfmMode tx, int skip_inter) +{ + static const unsigned wide_filter_col_mask[2] = { 0x11, 0x01 }; + static const unsigned wide_filter_row_mask[2] = { 0x03, 0x07 }; + + // FIXME I'm pretty sure all loops can be replaced by a single LUT if + // we make VP9Filter.mask uint64_t (i.e. row/col all single variable) + // and make the LUT 5-indexed (bl, bp, is_uv, tx and row/col), and then + // use row_and_7/col_and_7 as shifts (1*col_and_7+8*row_and_7) + + // the intended behaviour of the vp9 loopfilter is to work on 8-pixel + // edges. This means that for UV, we work on two subsampled blocks at + // a time, and we only use the topleft block's mode information to set + // things like block strength. Thus, for any block size smaller than + // 16x16, ignore the odd portion of the block. + if (tx == TX_4X4 && (ss_v | ss_h)) { + if (h == ss_v) { + if (row_and_7 & 1) + return; + if (!row_end) + h += 1; + } + if (w == ss_h) { + if (col_and_7 & 1) + return; + if (!col_end) + w += 1; + } + } + + if (tx == TX_4X4 && !skip_inter) { + int t = 1 << col_and_7, m_col = (t << w) - t, y; + // on 32-px edges, use the 8-px wide loopfilter; else, use 4-px wide + int m_row_8 = m_col & wide_filter_col_mask[ss_h], m_row_4 = m_col - m_row_8; + + for (y = row_and_7; y < h + row_and_7; y++) { + int col_mask_id = 2 - !(y & wide_filter_row_mask[ss_v]); + + mask[0][y][1] |= m_row_8; + mask[0][y][2] |= m_row_4; + // for odd lines, if the odd col is not being filtered, + // skip odd row also: + // .---. <-- a + // | | + // |___| <-- b + // ^ ^ + // c d + // + // if a/c are even row/col and b/d are odd, and d is skipped, + // e.g. right edge of size-66x66.webm, then skip b also (bug) + if ((ss_h & ss_v) && (col_end & 1) && (y & 1)) { + mask[1][y][col_mask_id] |= (t << (w - 1)) - t; + } else { + mask[1][y][col_mask_id] |= m_col; + } + if (!ss_h) + mask[0][y][3] |= m_col; + if (!ss_v) { + if (ss_h && (col_end & 1)) + mask[1][y][3] |= (t << (w - 1)) - t; + else + mask[1][y][3] |= m_col; + } + } + } else { + int y, t = 1 << col_and_7, m_col = (t << w) - t; + + if (!skip_inter) { + int mask_id = (tx == TX_8X8); + static const unsigned masks[4] = { 0xff, 0x55, 0x11, 0x01 }; + int l2 = tx + ss_h - 1, step1d; + int m_row = m_col & masks[l2]; + + // at odd UV col/row edges tx16/tx32 loopfilter edges, force + // 8wd loopfilter to prevent going off the visible edge. + if (ss_h && tx > TX_8X8 && (w ^ (w - 1)) == 1) { + int m_row_16 = ((t << (w - 1)) - t) & masks[l2]; + int m_row_8 = m_row - m_row_16; + + for (y = row_and_7; y < h + row_and_7; y++) { + mask[0][y][0] |= m_row_16; + mask[0][y][1] |= m_row_8; + } + } else { + for (y = row_and_7; y < h + row_and_7; y++) + mask[0][y][mask_id] |= m_row; + } + + l2 = tx + ss_v - 1; + step1d = 1 << l2; + if (ss_v && tx > TX_8X8 && (h ^ (h - 1)) == 1) { + for (y = row_and_7; y < h + row_and_7 - 1; y += step1d) + mask[1][y][0] |= m_col; + if (y - row_and_7 == h - 1) + mask[1][y][1] |= m_col; + } else { + for (y = row_and_7; y < h + row_and_7; y += step1d) + mask[1][y][mask_id] |= m_col; + } + } else if (tx != TX_4X4) { + int mask_id; + + mask_id = (tx == TX_8X8) || (h == ss_v); + mask[1][row_and_7][mask_id] |= m_col; + mask_id = (tx == TX_8X8) || (w == ss_h); + for (y = row_and_7; y < h + row_and_7; y++) + mask[0][y][mask_id] |= t; + } else { + int t8 = t & wide_filter_col_mask[ss_h], t4 = t - t8; + + for (y = row_and_7; y < h + row_and_7; y++) { + mask[0][y][2] |= t4; + mask[0][y][1] |= t8; + } + mask[1][row_and_7][2 - !(row_and_7 & wide_filter_row_mask[ss_v])] |= m_col; + } + } +} + +void ff_vp9_decode_block(AVCodecContext *ctx, int row, int col, + struct VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, + enum BlockLevel bl, enum BlockPartition bp) +{ + VP9Context *s = ctx->priv_data; + VP9Block *b = s->b; + enum BlockSize bs = bl * 3 + bp; + int bytesperpixel = s->bytesperpixel; + int w4 = bwh_tab[1][bs][0], h4 = bwh_tab[1][bs][1], lvl; + int emu[2]; + AVFrame *f = s->s.frames[CUR_FRAME].tf.f; + + s->row = row; + s->row7 = row & 7; + s->col = col; + s->col7 = col & 7; + s->min_mv.x = -(128 + col * 64); + s->min_mv.y = -(128 + row * 64); + s->max_mv.x = 128 + (s->cols - col - w4) * 64; + s->max_mv.y = 128 + (s->rows - row - h4) * 64; + if (s->pass < 2) { + b->bs = bs; + b->bl = bl; + b->bp = bp; + decode_mode(ctx); + b->uvtx = b->tx - ((s->ss_h && w4 * 2 == (1 << b->tx)) || + (s->ss_v && h4 * 2 == (1 << b->tx))); + + if (!b->skip) { + int has_coeffs; + + if (bytesperpixel == 1) { + has_coeffs = decode_coeffs_8bpp(ctx); + } else { + has_coeffs = decode_coeffs_16bpp(ctx); + } + if (!has_coeffs && b->bs <= BS_8x8 && !b->intra) { + b->skip = 1; + memset(&s->above_skip_ctx[col], 1, w4); + memset(&s->left_skip_ctx[s->row7], 1, h4); + } + } else { + int row7 = s->row7; + +#define SPLAT_ZERO_CTX(v, n) \ + switch (n) { \ + case 1: v = 0; break; \ + case 2: AV_ZERO16(&v); break; \ + case 4: AV_ZERO32(&v); break; \ + case 8: AV_ZERO64(&v); break; \ + case 16: AV_ZERO128(&v); break; \ + } +#define SPLAT_ZERO_YUV(dir, var, off, n, dir2) \ + do { \ + SPLAT_ZERO_CTX(s->dir##_y_##var[off * 2], n * 2); \ + if (s->ss_##dir2) { \ + SPLAT_ZERO_CTX(s->dir##_uv_##var[0][off], n); \ + SPLAT_ZERO_CTX(s->dir##_uv_##var[1][off], n); \ + } else { \ + SPLAT_ZERO_CTX(s->dir##_uv_##var[0][off * 2], n * 2); \ + SPLAT_ZERO_CTX(s->dir##_uv_##var[1][off * 2], n * 2); \ + } \ + } while (0) + + switch (w4) { + case 1: SPLAT_ZERO_YUV(above, nnz_ctx, col, 1, h); break; + case 2: SPLAT_ZERO_YUV(above, nnz_ctx, col, 2, h); break; + case 4: SPLAT_ZERO_YUV(above, nnz_ctx, col, 4, h); break; + case 8: SPLAT_ZERO_YUV(above, nnz_ctx, col, 8, h); break; + } + switch (h4) { + case 1: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 1, v); break; + case 2: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 2, v); break; + case 4: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 4, v); break; + case 8: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 8, v); break; + } + } + + if (s->pass == 1) { + s->b++; + s->block += w4 * h4 * 64 * bytesperpixel; + s->uvblock[0] += w4 * h4 * 64 * bytesperpixel >> (s->ss_h + s->ss_v); + s->uvblock[1] += w4 * h4 * 64 * bytesperpixel >> (s->ss_h + s->ss_v); + s->eob += 4 * w4 * h4; + s->uveob[0] += 4 * w4 * h4 >> (s->ss_h + s->ss_v); + s->uveob[1] += 4 * w4 * h4 >> (s->ss_h + s->ss_v); + + return; + } + } + + // emulated overhangs if the stride of the target buffer can't hold. This + // makes it possible to support emu-edge and so on even if we have large block + // overhangs + emu[0] = (col + w4) * 8 * bytesperpixel > f->linesize[0] || + (row + h4) > s->rows; + emu[1] = ((col + w4) * 8 >> s->ss_h) * bytesperpixel > f->linesize[1] || + (row + h4) > s->rows; + if (emu[0]) { + s->dst[0] = s->tmp_y; + s->y_stride = 128; + } else { + s->dst[0] = f->data[0] + yoff; + s->y_stride = f->linesize[0]; + } + if (emu[1]) { + s->dst[1] = s->tmp_uv[0]; + s->dst[2] = s->tmp_uv[1]; + s->uv_stride = 128; + } else { + s->dst[1] = f->data[1] + uvoff; + s->dst[2] = f->data[2] + uvoff; + s->uv_stride = f->linesize[1]; + } + if (b->intra) { + if (s->s.h.bpp > 8) { + intra_recon_16bpp(ctx, yoff, uvoff); + } else { + intra_recon_8bpp(ctx, yoff, uvoff); + } + } else { + if (s->s.h.bpp > 8) { + inter_recon_16bpp(ctx); + } else { + inter_recon_8bpp(ctx); + } + } + if (emu[0]) { + int w = FFMIN(s->cols - col, w4) * 8, h = FFMIN(s->rows - row, h4) * 8, n, o = 0; + + for (n = 0; o < w; n++) { + int bw = 64 >> n; + + av_assert2(n <= 4); + if (w & bw) { + s->dsp.mc[n][0][0][0][0](f->data[0] + yoff + o * bytesperpixel, f->linesize[0], + s->tmp_y + o * bytesperpixel, 128, h, 0, 0); + o += bw; + } + } + } + if (emu[1]) { + int w = FFMIN(s->cols - col, w4) * 8 >> s->ss_h; + int h = FFMIN(s->rows - row, h4) * 8 >> s->ss_v, n, o = 0; + + for (n = s->ss_h; o < w; n++) { + int bw = 64 >> n; + + av_assert2(n <= 4); + if (w & bw) { + s->dsp.mc[n][0][0][0][0](f->data[1] + uvoff + o * bytesperpixel, f->linesize[1], + s->tmp_uv[0] + o * bytesperpixel, 128, h, 0, 0); + s->dsp.mc[n][0][0][0][0](f->data[2] + uvoff + o * bytesperpixel, f->linesize[2], + s->tmp_uv[1] + o * bytesperpixel, 128, h, 0, 0); + o += bw; + } + } + } + + // pick filter level and find edges to apply filter to + if (s->s.h.filter.level && + (lvl = s->s.h.segmentation.feat[b->seg_id].lflvl[b->intra ? 0 : b->ref[0] + 1] + [b->mode[3] != ZEROMV]) > 0) { + int x_end = FFMIN(s->cols - col, w4), y_end = FFMIN(s->rows - row, h4); + int skip_inter = !b->intra && b->skip, col7 = s->col7, row7 = s->row7; + + setctx_2d(&lflvl->level[row7 * 8 + col7], w4, h4, 8, lvl); + mask_edges(lflvl->mask[0], 0, 0, row7, col7, x_end, y_end, 0, 0, b->tx, skip_inter); + if (s->ss_h || s->ss_v) + mask_edges(lflvl->mask[1], s->ss_h, s->ss_v, row7, col7, x_end, y_end, + s->cols & 1 && col + w4 >= s->cols ? s->cols & 7 : 0, + s->rows & 1 && row + h4 >= s->rows ? s->rows & 7 : 0, + b->uvtx, skip_inter); + + if (!s->filter_lut.lim_lut[lvl]) { + int sharp = s->s.h.filter.sharpness; + int limit = lvl; + + if (sharp > 0) { + limit >>= (sharp + 3) >> 2; + limit = FFMIN(limit, 9 - sharp); + } + limit = FFMAX(limit, 1); + + s->filter_lut.lim_lut[lvl] = limit; + s->filter_lut.mblim_lut[lvl] = 2 * (lvl + 2) + limit; + } + } + + if (s->pass == 2) { + s->b++; + s->block += w4 * h4 * 64 * bytesperpixel; + s->uvblock[0] += w4 * h4 * 64 * bytesperpixel >> (s->ss_v + s->ss_h); + s->uvblock[1] += w4 * h4 * 64 * bytesperpixel >> (s->ss_v + s->ss_h); + s->eob += 4 * w4 * h4; + s->uveob[0] += 4 * w4 * h4 >> (s->ss_v + s->ss_h); + s->uveob[1] += 4 * w4 * h4 >> (s->ss_v + s->ss_h); + } +} diff --git a/libavcodec/vp9data.c b/libavcodec/vp9data.c new file mode 100644 index 0000000000000..f77e3398d9862 --- /dev/null +++ b/libavcodec/vp9data.c @@ -0,0 +1,2237 @@ +/* + * Copyright (C) 2013 Ronald S. Bultje + * Copyright (C) 2013 Clément Bœsch + * + * 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 "vp9.h" +#include "vp9data.h" + +const int8_t ff_vp9_partition_tree[3][2] = { + { -PARTITION_NONE, 1 }, // '0' + { -PARTITION_H, 2 }, // '10' + { -PARTITION_V, -PARTITION_SPLIT }, // '110', '111' +}; + +const uint8_t ff_vp9_default_kf_partition_probs[4][4][3] = { + { /* 64x64 -> 32x32 */ + { 174, 35, 49 } /* a/l both not split */, + { 68, 11, 27 } /* a split, l not split */, + { 57, 15, 9 } /* l split, a not split */, + { 12, 3, 3 } /* a/l both split */ + }, { /* 32x32 -> 16x16 */ + { 150, 40, 39 } /* a/l both not split */, + { 78, 12, 26 } /* a split, l not split */, + { 67, 33, 11 } /* l split, a not split */, + { 24, 7, 5 } /* a/l both split */, + }, { /* 16x16 -> 8x8 */ + { 149, 53, 53 } /* a/l both not split */, + { 94, 20, 48 } /* a split, l not split */, + { 83, 53, 24 } /* l split, a not split */, + { 52, 18, 18 } /* a/l both split */, + }, { /* 8x8 -> 4x4 */ + { 158, 97, 94 } /* a/l both not split */, + { 93, 24, 99 } /* a split, l not split */, + { 85, 119, 44 } /* l split, a not split */, + { 62, 59, 67 } /* a/l both split */, + }, +}; + +const int8_t ff_vp9_segmentation_tree[7][2] = { + { 1, 2 }, + { 3, 4 }, + { 5, 6 }, + { -0, -1 }, // '00x' + { -2, -3 }, // '01x' + { -4, -5 }, // '10x' + { -6, -7 }, // '11x' +}; + +const int8_t ff_vp9_intramode_tree[9][2] = { + { -DC_PRED, 1 }, // '0' + { -TM_VP8_PRED, 2 }, // '10' + { -VERT_PRED, 3 }, // '110' + { 4, 6 }, + { -HOR_PRED, 5 }, // '11100' + { -DIAG_DOWN_RIGHT_PRED, -VERT_RIGHT_PRED }, // '11101x' + { -DIAG_DOWN_LEFT_PRED, 7 }, // '11110' + { -VERT_LEFT_PRED, 8 }, // '111110' + { -HOR_DOWN_PRED, -HOR_UP_PRED }, // '111111x' +}; + +const uint8_t ff_vp9_default_kf_ymode_probs[10][10][9] = { + { /* above = v */ + { 43, 46, 168, 134, 107, 128, 69, 142, 92 } /* left = v */, + { 44, 29, 68, 159, 201, 177, 50, 57, 77 } /* left = h */, + { 63, 36, 126, 146, 123, 158, 60, 90, 96 } /* left = dc */, + { 58, 38, 76, 114, 97, 172, 78, 133, 92 } /* left = d45 */, + { 46, 41, 76, 140, 63, 184, 69, 112, 57 } /* left = d135 */, + { 38, 32, 85, 140, 46, 112, 54, 151, 133 } /* left = d117 */, + { 39, 27, 61, 131, 110, 175, 44, 75, 136 } /* left = d153 */, + { 47, 35, 80, 100, 74, 143, 64, 163, 74 } /* left = d63 */, + { 52, 30, 74, 113, 130, 175, 51, 64, 58 } /* left = d27 */, + { 36, 61, 116, 114, 128, 162, 80, 125, 82 } /* left = tm */ + }, { /* above = h */ + { 55, 44, 68, 166, 179, 192, 57, 57, 108 } /* left = v */, + { 42, 26, 11, 199, 241, 228, 23, 15, 85 } /* left = h */, + { 82, 26, 26, 171, 208, 204, 44, 32, 105 } /* left = dc */, + { 68, 42, 19, 131, 160, 199, 55, 52, 83 } /* left = d45 */, + { 58, 50, 25, 139, 115, 232, 39, 52, 118 } /* left = d135 */, + { 50, 35, 33, 153, 104, 162, 64, 59, 131 } /* left = d117 */, + { 44, 24, 16, 150, 177, 202, 33, 19, 156 } /* left = d153 */, + { 53, 49, 21, 110, 116, 168, 59, 80, 76 } /* left = d63 */, + { 55, 27, 12, 153, 203, 218, 26, 27, 49 } /* left = d27 */, + { 38, 72, 19, 168, 203, 212, 50, 50, 107 } /* left = tm */ + }, { /* above = dc */ + { 92, 45, 102, 136, 116, 180, 74, 90, 100 } /* left = v */, + { 73, 32, 19, 187, 222, 215, 46, 34, 100 } /* left = h */, + { 137, 30, 42, 148, 151, 207, 70, 52, 91 } /* left = dc */, + { 91, 30, 32, 116, 121, 186, 93, 86, 94 } /* left = d45 */, + { 72, 35, 36, 149, 68, 206, 68, 63, 105 } /* left = d135 */, + { 73, 31, 28, 138, 57, 124, 55, 122, 151 } /* left = d117 */, + { 67, 23, 21, 140, 126, 197, 40, 37, 171 } /* left = d153 */, + { 74, 32, 27, 107, 86, 160, 63, 134, 102 } /* left = d63 */, + { 86, 27, 28, 128, 154, 212, 45, 43, 53 } /* left = d27 */, + { 59, 67, 44, 140, 161, 202, 78, 67, 119 } /* left = tm */ + }, { /* above = d45 */ + { 59, 38, 83, 112, 103, 162, 98, 136, 90 } /* left = v */, + { 62, 30, 23, 158, 200, 207, 59, 57, 50 } /* left = h */, + { 103, 26, 36, 129, 132, 201, 83, 80, 93 } /* left = dc */, + { 67, 30, 29, 84, 86, 191, 102, 91, 59 } /* left = d45 */, + { 60, 32, 33, 112, 71, 220, 64, 89, 104 } /* left = d135 */, + { 53, 26, 34, 130, 56, 149, 84, 120, 103 } /* left = d117 */, + { 53, 21, 23, 133, 109, 210, 56, 77, 172 } /* left = d153 */, + { 61, 29, 29, 93, 97, 165, 83, 175, 162 } /* left = d63 */, + { 77, 19, 29, 112, 142, 228, 55, 66, 36 } /* left = d27 */, + { 47, 47, 43, 114, 137, 181, 100, 99, 95 } /* left = tm */ + }, { /* above = d135 */ + { 53, 40, 55, 139, 69, 183, 61, 80, 110 } /* left = v */, + { 40, 29, 19, 161, 180, 207, 43, 24, 91 } /* left = h */, + { 69, 23, 29, 128, 83, 199, 46, 44, 101 } /* left = dc */, + { 60, 34, 19, 105, 61, 198, 53, 64, 89 } /* left = d45 */, + { 52, 31, 22, 158, 40, 209, 58, 62, 89 } /* left = d135 */, + { 44, 31, 29, 147, 46, 158, 56, 102, 198 } /* left = d117 */, + { 35, 19, 12, 135, 87, 209, 41, 45, 167 } /* left = d153 */, + { 51, 38, 25, 113, 58, 164, 70, 93, 97 } /* left = d63 */, + { 55, 25, 21, 118, 95, 215, 38, 39, 66 } /* left = d27 */, + { 47, 54, 34, 146, 108, 203, 72, 103, 151 } /* left = tm */ + }, { /* above = d117 */ + { 46, 27, 80, 150, 55, 124, 55, 121, 135 } /* left = v */, + { 36, 23, 27, 165, 149, 166, 54, 64, 118 } /* left = h */, + { 64, 19, 37, 156, 66, 138, 49, 95, 133 } /* left = dc */, + { 53, 21, 36, 131, 63, 163, 60, 109, 81 } /* left = d45 */, + { 40, 26, 35, 154, 40, 185, 51, 97, 123 } /* left = d135 */, + { 35, 19, 34, 179, 19, 97, 48, 129, 124 } /* left = d117 */, + { 36, 20, 26, 136, 62, 164, 33, 77, 154 } /* left = d153 */, + { 45, 26, 28, 129, 45, 129, 49, 147, 123 } /* left = d63 */, + { 45, 18, 32, 130, 90, 157, 40, 79, 91 } /* left = d27 */, + { 38, 44, 51, 136, 74, 162, 57, 97, 121 } /* left = tm */ + }, { /* above = d153 */ + { 56, 39, 58, 133, 117, 173, 48, 53, 187 } /* left = v */, + { 35, 21, 12, 161, 212, 207, 20, 23, 145 } /* left = h */, + { 75, 17, 22, 136, 138, 185, 32, 34, 166 } /* left = dc */, + { 56, 29, 19, 117, 109, 181, 55, 68, 112 } /* left = d45 */, + { 47, 29, 17, 153, 64, 220, 59, 51, 114 } /* left = d135 */, + { 46, 16, 24, 136, 76, 147, 41, 64, 172 } /* left = d117 */, + { 34, 17, 11, 108, 152, 187, 13, 15, 209 } /* left = d153 */, + { 55, 30, 18, 122, 79, 179, 44, 88, 116 } /* left = d63 */, + { 51, 24, 14, 115, 133, 209, 32, 26, 104 } /* left = d27 */, + { 37, 49, 25, 129, 168, 164, 41, 54, 148 } /* left = tm */ + }, { /* above = d63 */ + { 48, 34, 86, 101, 92, 146, 78, 179, 134 } /* left = v */, + { 47, 22, 24, 138, 187, 178, 68, 69, 59 } /* left = h */, + { 78, 23, 39, 111, 117, 170, 74, 124, 94 } /* left = dc */, + { 56, 25, 33, 105, 112, 187, 95, 177, 129 } /* left = d45 */, + { 48, 31, 27, 114, 63, 183, 82, 116, 56 } /* left = d135 */, + { 43, 28, 37, 121, 63, 123, 61, 192, 169 } /* left = d117 */, + { 42, 17, 24, 109, 97, 177, 56, 76, 122 } /* left = d153 */, + { 46, 23, 32, 74, 86, 150, 67, 183, 88 } /* left = d63 */, + { 58, 18, 28, 105, 139, 182, 70, 92, 63 } /* left = d27 */, + { 36, 38, 48, 92, 122, 165, 88, 137, 91 } /* left = tm */ + }, { /* above = d27 */ + { 62, 44, 61, 123, 105, 189, 48, 57, 64 } /* left = v */, + { 47, 25, 17, 175, 222, 220, 24, 30, 86 } /* left = h */, + { 82, 22, 32, 127, 143, 213, 39, 41, 70 } /* left = dc */, + { 68, 36, 17, 106, 102, 206, 59, 74, 74 } /* left = d45 */, + { 57, 39, 23, 151, 68, 216, 55, 63, 58 } /* left = d135 */, + { 49, 30, 35, 141, 70, 168, 82, 40, 115 } /* left = d117 */, + { 51, 25, 15, 136, 129, 202, 38, 35, 139 } /* left = d153 */, + { 59, 39, 19, 114, 75, 180, 77, 104, 42 } /* left = d63 */, + { 68, 26, 16, 111, 141, 215, 29, 28, 28 } /* left = d27 */, + { 40, 61, 26, 126, 152, 206, 61, 59, 93 } /* left = tm */ + }, { /* above = tm */ + { 44, 78, 115, 132, 119, 173, 71, 112, 93 } /* left = v */, + { 39, 38, 21, 184, 227, 206, 42, 32, 64 } /* left = h */, + { 65, 70, 60, 155, 159, 199, 61, 60, 81 } /* left = dc */, + { 58, 47, 36, 124, 137, 193, 80, 82, 78 } /* left = d45 */, + { 49, 50, 35, 144, 95, 205, 63, 78, 59 } /* left = d135 */, + { 41, 53, 52, 148, 71, 142, 65, 128, 51 } /* left = d117 */, + { 40, 36, 28, 143, 143, 202, 40, 55, 137 } /* left = d153 */, + { 42, 44, 44, 104, 105, 164, 64, 130, 80 } /* left = d63 */, + { 52, 34, 29, 129, 183, 227, 42, 35, 43 } /* left = d27 */, + { 43, 81, 53, 140, 169, 204, 68, 84, 72 } /* left = tm */ + } +}; + +const uint8_t ff_vp9_default_kf_uvmode_probs[10][9] = { + { 118, 15, 123, 148, 131, 101, 44, 93, 131 } /* y = v */, + { 113, 12, 23, 188, 226, 142, 26, 32, 125 } /* y = h */, + { 144, 11, 54, 157, 195, 130, 46, 58, 108 } /* y = dc */, + { 120, 11, 50, 123, 163, 135, 64, 77, 103 } /* y = d45 */, + { 113, 9, 36, 155, 111, 157, 32, 44, 161 } /* y = d135 */, + { 116, 9, 55, 176, 76, 96, 37, 61, 149 } /* y = d117 */, + { 115, 9, 28, 141, 161, 167, 21, 25, 193 } /* y = d153 */, + { 116, 12, 64, 120, 140, 125, 49, 115, 121 } /* y = d63 */, + { 120, 12, 32, 145, 195, 142, 32, 38, 86 } /* y = d27 */, + { 102, 19, 66, 162, 182, 122, 35, 59, 128 } /* y = tm */ +}; + +const int8_t ff_vp9_inter_mode_tree[3][2] = { + { -ZEROMV, 1 }, // '0' + { -NEARESTMV, 2 }, // '10' + { -NEARMV, -NEWMV }, // '11x' +}; + +const int8_t ff_vp9_filter_tree[2][2] = { + { -0, 1 }, // '0' + { -1, -2 }, // '1x' +}; + +const enum FilterMode ff_vp9_filter_lut[3] = { + FILTER_8TAP_REGULAR, + FILTER_8TAP_SMOOTH, + FILTER_8TAP_SHARP, +}; + +const int16_t ff_vp9_dc_qlookup[3][256] = { + { + 4, 8, 8, 9, 10, 11, 12, 12, + 13, 14, 15, 16, 17, 18, 19, 19, + 20, 21, 22, 23, 24, 25, 26, 26, + 27, 28, 29, 30, 31, 32, 32, 33, + 34, 35, 36, 37, 38, 38, 39, 40, + 41, 42, 43, 43, 44, 45, 46, 47, + 48, 48, 49, 50, 51, 52, 53, 53, + 54, 55, 56, 57, 57, 58, 59, 60, + 61, 62, 62, 63, 64, 65, 66, 66, + 67, 68, 69, 70, 70, 71, 72, 73, + 74, 74, 75, 76, 77, 78, 78, 79, + 80, 81, 81, 82, 83, 84, 85, 85, + 87, 88, 90, 92, 93, 95, 96, 98, + 99, 101, 102, 104, 105, 107, 108, 110, + 111, 113, 114, 116, 117, 118, 120, 121, + 123, 125, 127, 129, 131, 134, 136, 138, + 140, 142, 144, 146, 148, 150, 152, 154, + 156, 158, 161, 164, 166, 169, 172, 174, + 177, 180, 182, 185, 187, 190, 192, 195, + 199, 202, 205, 208, 211, 214, 217, 220, + 223, 226, 230, 233, 237, 240, 243, 247, + 250, 253, 257, 261, 265, 269, 272, 276, + 280, 284, 288, 292, 296, 300, 304, 309, + 313, 317, 322, 326, 330, 335, 340, 344, + 349, 354, 359, 364, 369, 374, 379, 384, + 389, 395, 400, 406, 411, 417, 423, 429, + 435, 441, 447, 454, 461, 467, 475, 482, + 489, 497, 505, 513, 522, 530, 539, 549, + 559, 569, 579, 590, 602, 614, 626, 640, + 654, 668, 684, 700, 717, 736, 755, 775, + 796, 819, 843, 869, 896, 925, 955, 988, + 1022, 1058, 1098, 1139, 1184, 1232, 1282, 1336, + }, { + 4, 9, 10, 13, 15, 17, 20, 22, + 25, 28, 31, 34, 37, 40, 43, 47, + 50, 53, 57, 60, 64, 68, 71, 75, + 78, 82, 86, 90, 93, 97, 101, 105, + 109, 113, 116, 120, 124, 128, 132, 136, + 140, 143, 147, 151, 155, 159, 163, 166, + 170, 174, 178, 182, 185, 189, 193, 197, + 200, 204, 208, 212, 215, 219, 223, 226, + 230, 233, 237, 241, 244, 248, 251, 255, + 259, 262, 266, 269, 273, 276, 280, 283, + 287, 290, 293, 297, 300, 304, 307, 310, + 314, 317, 321, 324, 327, 331, 334, 337, + 343, 350, 356, 362, 369, 375, 381, 387, + 394, 400, 406, 412, 418, 424, 430, 436, + 442, 448, 454, 460, 466, 472, 478, 484, + 490, 499, 507, 516, 525, 533, 542, 550, + 559, 567, 576, 584, 592, 601, 609, 617, + 625, 634, 644, 655, 666, 676, 687, 698, + 708, 718, 729, 739, 749, 759, 770, 782, + 795, 807, 819, 831, 844, 856, 868, 880, + 891, 906, 920, 933, 947, 961, 975, 988, + 1001, 1015, 1030, 1045, 1061, 1076, 1090, 1105, + 1120, 1137, 1153, 1170, 1186, 1202, 1218, 1236, + 1253, 1271, 1288, 1306, 1323, 1342, 1361, 1379, + 1398, 1416, 1436, 1456, 1476, 1496, 1516, 1537, + 1559, 1580, 1601, 1624, 1647, 1670, 1692, 1717, + 1741, 1766, 1791, 1817, 1844, 1871, 1900, 1929, + 1958, 1990, 2021, 2054, 2088, 2123, 2159, 2197, + 2236, 2276, 2319, 2363, 2410, 2458, 2508, 2561, + 2616, 2675, 2737, 2802, 2871, 2944, 3020, 3102, + 3188, 3280, 3375, 3478, 3586, 3702, 3823, 3953, + 4089, 4236, 4394, 4559, 4737, 4929, 5130, 5347, + }, { + 4, 12, 18, 25, 33, 41, 50, 60, + 70, 80, 91, 103, 115, 127, 140, 153, + 166, 180, 194, 208, 222, 237, 251, 266, + 281, 296, 312, 327, 343, 358, 374, 390, + 405, 421, 437, 453, 469, 484, 500, 516, + 532, 548, 564, 580, 596, 611, 627, 643, + 659, 674, 690, 706, 721, 737, 752, 768, + 783, 798, 814, 829, 844, 859, 874, 889, + 904, 919, 934, 949, 964, 978, 993, 1008, + 1022, 1037, 1051, 1065, 1080, 1094, 1108, 1122, + 1136, 1151, 1165, 1179, 1192, 1206, 1220, 1234, + 1248, 1261, 1275, 1288, 1302, 1315, 1329, 1342, + 1368, 1393, 1419, 1444, 1469, 1494, 1519, 1544, + 1569, 1594, 1618, 1643, 1668, 1692, 1717, 1741, + 1765, 1789, 1814, 1838, 1862, 1885, 1909, 1933, + 1957, 1992, 2027, 2061, 2096, 2130, 2165, 2199, + 2233, 2267, 2300, 2334, 2367, 2400, 2434, 2467, + 2499, 2532, 2575, 2618, 2661, 2704, 2746, 2788, + 2830, 2872, 2913, 2954, 2995, 3036, 3076, 3127, + 3177, 3226, 3275, 3324, 3373, 3421, 3469, 3517, + 3565, 3621, 3677, 3733, 3788, 3843, 3897, 3951, + 4005, 4058, 4119, 4181, 4241, 4301, 4361, 4420, + 4479, 4546, 4612, 4677, 4742, 4807, 4871, 4942, + 5013, 5083, 5153, 5222, 5291, 5367, 5442, 5517, + 5591, 5665, 5745, 5825, 5905, 5984, 6063, 6149, + 6234, 6319, 6404, 6495, 6587, 6678, 6769, 6867, + 6966, 7064, 7163, 7269, 7376, 7483, 7599, 7715, + 7832, 7958, 8085, 8214, 8352, 8492, 8635, 8788, + 8945, 9104, 9275, 9450, 9639, 9832, 10031, 10245, + 10465, 10702, 10946, 11210, 11482, 11776, 12081, 12409, + 12750, 13118, 13501, 13913, 14343, 14807, 15290, 15812, + 16356, 16943, 17575, 18237, 18949, 19718, 20521, 21387, + } +}; + +const int16_t ff_vp9_ac_qlookup[3][256] = { + { + 4, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, + 104, 106, 108, 110, 112, 114, 116, 118, + 120, 122, 124, 126, 128, 130, 132, 134, + 136, 138, 140, 142, 144, 146, 148, 150, + 152, 155, 158, 161, 164, 167, 170, 173, + 176, 179, 182, 185, 188, 191, 194, 197, + 200, 203, 207, 211, 215, 219, 223, 227, + 231, 235, 239, 243, 247, 251, 255, 260, + 265, 270, 275, 280, 285, 290, 295, 300, + 305, 311, 317, 323, 329, 335, 341, 347, + 353, 359, 366, 373, 380, 387, 394, 401, + 408, 416, 424, 432, 440, 448, 456, 465, + 474, 483, 492, 501, 510, 520, 530, 540, + 550, 560, 571, 582, 593, 604, 615, 627, + 639, 651, 663, 676, 689, 702, 715, 729, + 743, 757, 771, 786, 801, 816, 832, 848, + 864, 881, 898, 915, 933, 951, 969, 988, + 1007, 1026, 1046, 1066, 1087, 1108, 1129, 1151, + 1173, 1196, 1219, 1243, 1267, 1292, 1317, 1343, + 1369, 1396, 1423, 1451, 1479, 1508, 1537, 1567, + 1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828, + }, { + 4, 9, 11, 13, 16, 18, 21, 24, + 27, 30, 33, 37, 40, 44, 48, 51, + 55, 59, 63, 67, 71, 75, 79, 83, + 88, 92, 96, 100, 105, 109, 114, 118, + 122, 127, 131, 136, 140, 145, 149, 154, + 158, 163, 168, 172, 177, 181, 186, 190, + 195, 199, 204, 208, 213, 217, 222, 226, + 231, 235, 240, 244, 249, 253, 258, 262, + 267, 271, 275, 280, 284, 289, 293, 297, + 302, 306, 311, 315, 319, 324, 328, 332, + 337, 341, 345, 349, 354, 358, 362, 367, + 371, 375, 379, 384, 388, 392, 396, 401, + 409, 417, 425, 433, 441, 449, 458, 466, + 474, 482, 490, 498, 506, 514, 523, 531, + 539, 547, 555, 563, 571, 579, 588, 596, + 604, 616, 628, 640, 652, 664, 676, 688, + 700, 713, 725, 737, 749, 761, 773, 785, + 797, 809, 825, 841, 857, 873, 889, 905, + 922, 938, 954, 970, 986, 1002, 1018, 1038, + 1058, 1078, 1098, 1118, 1138, 1158, 1178, 1198, + 1218, 1242, 1266, 1290, 1314, 1338, 1362, 1386, + 1411, 1435, 1463, 1491, 1519, 1547, 1575, 1603, + 1631, 1663, 1695, 1727, 1759, 1791, 1823, 1859, + 1895, 1931, 1967, 2003, 2039, 2079, 2119, 2159, + 2199, 2239, 2283, 2327, 2371, 2415, 2459, 2507, + 2555, 2603, 2651, 2703, 2755, 2807, 2859, 2915, + 2971, 3027, 3083, 3143, 3203, 3263, 3327, 3391, + 3455, 3523, 3591, 3659, 3731, 3803, 3876, 3952, + 4028, 4104, 4184, 4264, 4348, 4432, 4516, 4604, + 4692, 4784, 4876, 4972, 5068, 5168, 5268, 5372, + 5476, 5584, 5692, 5804, 5916, 6032, 6148, 6268, + 6388, 6512, 6640, 6768, 6900, 7036, 7172, 7312, + }, { + 4, 13, 19, 27, 35, 44, 54, 64, + 75, 87, 99, 112, 126, 139, 154, 168, + 183, 199, 214, 230, 247, 263, 280, 297, + 314, 331, 349, 366, 384, 402, 420, 438, + 456, 475, 493, 511, 530, 548, 567, 586, + 604, 623, 642, 660, 679, 698, 716, 735, + 753, 772, 791, 809, 828, 846, 865, 884, + 902, 920, 939, 957, 976, 994, 1012, 1030, + 1049, 1067, 1085, 1103, 1121, 1139, 1157, 1175, + 1193, 1211, 1229, 1246, 1264, 1282, 1299, 1317, + 1335, 1352, 1370, 1387, 1405, 1422, 1440, 1457, + 1474, 1491, 1509, 1526, 1543, 1560, 1577, 1595, + 1627, 1660, 1693, 1725, 1758, 1791, 1824, 1856, + 1889, 1922, 1954, 1987, 2020, 2052, 2085, 2118, + 2150, 2183, 2216, 2248, 2281, 2313, 2346, 2378, + 2411, 2459, 2508, 2556, 2605, 2653, 2701, 2750, + 2798, 2847, 2895, 2943, 2992, 3040, 3088, 3137, + 3185, 3234, 3298, 3362, 3426, 3491, 3555, 3619, + 3684, 3748, 3812, 3876, 3941, 4005, 4069, 4149, + 4230, 4310, 4390, 4470, 4550, 4631, 4711, 4791, + 4871, 4967, 5064, 5160, 5256, 5352, 5448, 5544, + 5641, 5737, 5849, 5961, 6073, 6185, 6297, 6410, + 6522, 6650, 6778, 6906, 7034, 7162, 7290, 7435, + 7579, 7723, 7867, 8011, 8155, 8315, 8475, 8635, + 8795, 8956, 9132, 9308, 9484, 9660, 9836, 10028, + 10220, 10412, 10604, 10812, 11020, 11228, 11437, 11661, + 11885, 12109, 12333, 12573, 12813, 13053, 13309, 13565, + 13821, 14093, 14365, 14637, 14925, 15213, 15502, 15806, + 16110, 16414, 16734, 17054, 17390, 17726, 18062, 18414, + 18766, 19134, 19502, 19886, 20270, 20670, 21070, 21486, + 21902, 22334, 22766, 23214, 23662, 24126, 24590, 25070, + 25551, 26047, 26559, 27071, 27599, 28143, 28687, 29247, + } +}; + +const enum TxfmType ff_vp9_intra_txfm_type[14] = { + [VERT_PRED] = ADST_DCT, + [HOR_PRED] = DCT_ADST, + [DC_PRED] = DCT_DCT, + [DIAG_DOWN_LEFT_PRED] = DCT_DCT, + [DIAG_DOWN_RIGHT_PRED] = ADST_ADST, + [VERT_RIGHT_PRED] = ADST_DCT, + [HOR_DOWN_PRED] = DCT_ADST, + [VERT_LEFT_PRED] = ADST_DCT, + [HOR_UP_PRED] = DCT_ADST, + [TM_VP8_PRED] = ADST_ADST, + [NEARESTMV] = DCT_DCT, + [NEARMV] = DCT_DCT, + [ZEROMV] = DCT_DCT, + [NEWMV] = DCT_DCT, +}; + +const int16_t ff_vp9_default_scan_4x4[16] = { + 0, 1, 4, 5, + 2, 8, 3, 6, + 12, 9, 7, 10, + 13, 11, 14, 15, +}; + +const int16_t ff_vp9_col_scan_4x4[16] = { + 0, 1, 2, 4, + 3, 5, 6, 8, + 7, 9, 10, 12, + 13, 11, 14, 15, +}; + +const int16_t ff_vp9_row_scan_4x4[16] = { + 0, 4, 1, 8, + 5, 12, 9, 2, + 6, 13, 3, 10, + 7, 14, 11, 15, +}; + +const int16_t ff_vp9_default_scan_8x8[64] = { + 0, 1, 8, 2, 9, 16, 10, 3, + 17, 24, 18, 11, 4, 25, 32, 19, + 12, 26, 5, 33, 20, 27, 40, 13, + 34, 6, 41, 28, 21, 35, 42, 48, + 14, 7, 36, 29, 43, 56, 49, 22, + 15, 37, 50, 44, 57, 30, 23, 51, + 45, 58, 38, 31, 52, 59, 39, 46, + 53, 60, 47, 54, 61, 55, 62, 63, +}; + +const int16_t ff_vp9_col_scan_8x8[64] = { + 0, 1, 2, 8, 3, 9, 4, 10, + 16, 5, 11, 17, 12, 18, 6, 24, + 19, 13, 25, 7, 26, 20, 32, 14, + 27, 21, 33, 28, 34, 15, 22, 35, + 40, 29, 41, 36, 23, 30, 42, 37, + 48, 43, 31, 44, 49, 38, 50, 56, + 45, 39, 51, 57, 52, 46, 58, 53, + 59, 47, 60, 54, 61, 55, 62, 63, +}; + +const int16_t ff_vp9_row_scan_8x8[64] = { + 0, 8, 16, 1, 9, 24, 2, 17, + 32, 10, 25, 3, 40, 18, 11, 33, + 26, 19, 4, 48, 41, 34, 12, 27, + 56, 20, 5, 42, 35, 13, 49, 28, + 6, 21, 43, 36, 14, 50, 29, 57, + 7, 44, 22, 37, 51, 15, 58, 30, + 23, 45, 52, 38, 59, 31, 46, 53, + 39, 60, 47, 61, 54, 62, 55, 63, +}; + +const int16_t ff_vp9_default_scan_16x16[256] = { + 0, 1, 16, 2, 17, 32, 3, 18, 33, 48, 4, 34, 19, 49, 20, 5, + 35, 64, 50, 36, 65, 21, 6, 51, 80, 66, 37, 22, 52, 7, 81, 67, + 38, 82, 53, 23, 96, 68, 8, 83, 97, 54, 39, 69, 112, 24, 98, 84, + 70, 55, 9, 40, 85, 99, 113, 128, 25, 114, 100, 71, 86, 56, 10, 41, + 115, 101, 129, 116, 72, 87, 26, 130, 144, 102, 57, 11, 42, 117, 131, 145, + 88, 103, 27, 73, 132, 118, 146, 58, 160, 12, 43, 133, 147, 104, 89, 119, + 161, 74, 148, 134, 28, 162, 59, 13, 176, 120, 149, 90, 135, 105, 163, 44, + 75, 177, 164, 29, 150, 121, 136, 178, 165, 14, 106, 60, 91, 151, 45, 179, + 192, 137, 166, 122, 76, 180, 152, 30, 61, 15, 107, 167, 181, 193, 92, 208, + 46, 138, 123, 153, 194, 77, 168, 182, 31, 195, 209, 183, 108, 139, 62, 154, + 47, 196, 93, 169, 210, 197, 224, 124, 184, 211, 78, 109, 170, 155, 63, 198, + 212, 185, 225, 240, 140, 94, 199, 125, 79, 213, 226, 171, 186, 156, 214, 200, + 110, 227, 141, 95, 241, 215, 228, 201, 126, 242, 187, 172, 157, 229, 111, 216, + 243, 142, 202, 230, 127, 217, 244, 173, 188, 231, 158, 203, 143, 245, 218, 232, + 189, 246, 159, 174, 233, 247, 219, 204, 175, 190, 248, 234, 205, 220, 249, 191, + 235, 221, 250, 206, 222, 251, 236, 207, 237, 223, 252, 238, 253, 239, 254, 255, +}; + +const int16_t ff_vp9_col_scan_16x16[256] = { + 0, 1, 2, 3, 16, 4, 17, 5, 18, 6, 19, 32, 20, 7, 33, 21, + 34, 8, 35, 22, 48, 36, 9, 49, 23, 50, 37, 10, 38, 51, 24, 64, + 52, 11, 65, 39, 25, 53, 66, 54, 40, 67, 12, 80, 26, 68, 55, 81, + 41, 69, 13, 27, 82, 56, 70, 83, 42, 14, 84, 96, 71, 28, 57, 85, + 97, 15, 72, 98, 43, 86, 58, 99, 29, 87, 100, 112, 73, 44, 101, 59, + 30, 113, 88, 114, 74, 128, 102, 45, 31, 115, 60, 103, 89, 116, 75, 129, + 117, 46, 104, 90, 61, 130, 118, 131, 132, 105, 76, 47, 119, 144, 91, 62, + 133, 106, 145, 120, 146, 134, 77, 147, 121, 92, 135, 148, 63, 107, 136, 122, + 93, 149, 160, 78, 150, 137, 108, 161, 162, 151, 123, 79, 138, 163, 152, 94, + 164, 109, 165, 153, 124, 139, 176, 166, 95, 177, 167, 110, 154, 178, 125, 179, + 140, 168, 155, 111, 180, 192, 181, 169, 141, 126, 182, 193, 194, 156, 183, 170, + 195, 127, 142, 196, 184, 208, 197, 157, 171, 143, 185, 198, 209, 199, 210, 172, + 158, 186, 211, 224, 212, 200, 240, 159, 213, 225, 187, 201, 173, 226, 214, 215, + 227, 202, 228, 188, 241, 216, 174, 229, 242, 203, 243, 217, 230, 175, 189, 244, + 231, 204, 218, 232, 245, 219, 246, 190, 233, 205, 191, 247, 234, 248, 220, 206, + 249, 235, 221, 207, 250, 236, 222, 251, 223, 237, 238, 252, 239, 253, 254, 255, +}; + +const int16_t ff_vp9_row_scan_16x16[256] = { + 0, 16, 32, 1, 48, 17, 64, 33, 2, 80, 18, 49, 96, 34, 3, 65, + 19, 112, 50, 81, 35, 4, 128, 66, 20, 97, 51, 82, 5, 144, 36, 67, + 113, 98, 21, 52, 160, 83, 129, 37, 68, 6, 114, 176, 99, 53, 22, 84, + 145, 38, 69, 130, 7, 115, 192, 100, 54, 23, 85, 161, 146, 131, 39, 70, + 208, 116, 8, 101, 177, 55, 86, 24, 162, 147, 132, 71, 224, 117, 40, 102, + 9, 148, 56, 87, 193, 163, 240, 133, 178, 25, 118, 72, 41, 103, 164, 10, + 149, 88, 134, 209, 179, 57, 119, 194, 26, 73, 165, 150, 104, 42, 135, 11, + 180, 120, 89, 225, 195, 58, 27, 210, 151, 181, 166, 74, 43, 105, 12, 136, + 90, 59, 241, 121, 28, 196, 167, 211, 152, 44, 182, 137, 75, 13, 226, 106, + 122, 60, 197, 91, 168, 29, 183, 153, 14, 76, 212, 138, 45, 107, 15, 198, + 92, 227, 169, 30, 123, 154, 61, 242, 184, 213, 139, 46, 77, 31, 108, 170, + 199, 185, 124, 228, 93, 155, 214, 62, 140, 243, 78, 47, 200, 109, 186, 171, + 201, 94, 63, 215, 229, 156, 79, 125, 141, 110, 216, 187, 172, 244, 202, 230, + 217, 95, 157, 126, 245, 111, 142, 231, 188, 127, 158, 218, 173, 232, 246, 233, + 203, 143, 247, 174, 189, 159, 219, 204, 248, 234, 249, 175, 190, 220, 205, 250, + 235, 191, 221, 251, 236, 206, 252, 222, 207, 237, 223, 253, 238, 254, 239, 255, +}; + +const int16_t ff_vp9_default_scan_32x32[1024] = { + 0, 1, 32, 2, 33, 64, 3, 34, 65, 4, 96, 35, 66, 5, 36, 97, 67, 128, 98, 68, 37, 6, 129, 99, 7, 160, 69, 38, 130, 100, 161, 131, + 39, 70, 8, 101, 162, 132, 192, 71, 40, 9, 102, 163, 133, 193, 72, 224, 103, 41, 164, 10, 194, 134, 165, 73, 104, 135, 225, 42, 195, 11, 256, 166, + 226, 196, 74, 105, 136, 43, 12, 167, 197, 227, 257, 75, 106, 137, 228, 44, 198, 168, 258, 288, 13, 229, 76, 107, 199, 138, 259, 169, 289, 45, 230, 260, + 200, 108, 14, 170, 139, 320, 290, 77, 231, 261, 46, 201, 140, 291, 109, 232, 321, 262, 171, 78, 292, 15, 322, 202, 263, 352, 172, 293, 233, 141, 323, 110, + 47, 203, 264, 234, 294, 353, 324, 16, 79, 204, 265, 295, 325, 173, 354, 142, 235, 384, 48, 296, 111, 266, 355, 326, 80, 17, 205, 236, 174, 356, 385, 327, + 143, 297, 267, 357, 386, 112, 49, 328, 298, 206, 416, 237, 358, 387, 81, 175, 18, 329, 359, 388, 299, 330, 389, 113, 417, 238, 360, 50, 207, 418, 390, 331, + 19, 448, 361, 82, 419, 391, 239, 51, 362, 420, 114, 449, 480, 421, 83, 363, 450, 422, 512, 451, 423, 115, 452, 481, 453, 482, 454, 544, 483, 455, 513, 484, + 514, 485, 515, 486, 545, 576, 487, 546, 547, 608, 577, 578, 579, 609, 610, 611, 20, 144, 268, 392, 516, 640, 21, 52, 145, 176, 269, 300, 393, 424, 517, 548, + 641, 672, 22, 53, 84, 146, 177, 208, 270, 301, 332, 394, 425, 456, 518, 549, 580, 642, 673, 704, 23, 54, 85, 116, 147, 178, 209, 240, 271, 302, 333, 364, + 395, 426, 457, 488, 519, 550, 581, 612, 643, 674, 705, 736, 55, 86, 117, 179, 210, 241, 303, 334, 365, 427, 458, 489, 551, 582, 613, 675, 706, 737, 87, 118, + 211, 242, 335, 366, 459, 490, 583, 614, 707, 738, 119, 243, 367, 491, 615, 739, 24, 148, 272, 396, 520, 644, 768, 25, 56, 149, 180, 273, 304, 397, 428, 521, + 552, 645, 676, 769, 800, 26, 57, 88, 150, 181, 212, 274, 305, 336, 398, 429, 460, 522, 553, 584, 646, 677, 708, 770, 801, 832, 27, 58, 89, 120, 151, 182, + 213, 244, 275, 306, 337, 368, 399, 430, 461, 492, 523, 554, 585, 616, 647, 678, 709, 740, 771, 802, 833, 864, 59, 90, 121, 183, 214, 245, 307, 338, 369, 431, + 462, 493, 555, 586, 617, 679, 710, 741, 803, 834, 865, 91, 122, 215, 246, 339, 370, 463, 494, 587, 618, 711, 742, 835, 866, 123, 247, 371, 495, 619, 743, 867, + 28, 152, 276, 400, 524, 648, 772, 896, 29, 60, 153, 184, 277, 308, 401, 432, 525, 556, 649, 680, 773, 804, 897, 928, 30, 61, 92, 154, 185, 216, 278, 309, + 340, 402, 433, 464, 526, 557, 588, 650, 681, 712, 774, 805, 836, 898, 929, 960, 31, 62, 93, 124, 155, 186, 217, 248, 279, 310, 341, 372, 403, 434, 465, 496, + 527, 558, 589, 620, 651, 682, 713, 744, 775, 806, 837, 868, 899, 930, 961, 992, 63, 94, 125, 187, 218, 249, 311, 342, 373, 435, 466, 497, 559, 590, 621, 683, + 714, 745, 807, 838, 869, 931, 962, 993, 95, 126, 219, 250, 343, 374, 467, 498, 591, 622, 715, 746, 839, 870, 963, 994, 127, 251, 375, 499, 623, 747, 871, 995, + 156, 280, 404, 528, 652, 776, 900, 157, 188, 281, 312, 405, 436, 529, 560, 653, 684, 777, 808, 901, 932, 158, 189, 220, 282, 313, 344, 406, 437, 468, 530, 561, + 592, 654, 685, 716, 778, 809, 840, 902, 933, 964, 159, 190, 221, 252, 283, 314, 345, 376, 407, 438, 469, 500, 531, 562, 593, 624, 655, 686, 717, 748, 779, 810, + 841, 872, 903, 934, 965, 996, 191, 222, 253, 315, 346, 377, 439, 470, 501, 563, 594, 625, 687, 718, 749, 811, 842, 873, 935, 966, 997, 223, 254, 347, 378, 471, + 502, 595, 626, 719, 750, 843, 874, 967, 998, 255, 379, 503, 627, 751, 875, 999, 284, 408, 532, 656, 780, 904, 285, 316, 409, 440, 533, 564, 657, 688, 781, 812, + 905, 936, 286, 317, 348, 410, 441, 472, 534, 565, 596, 658, 689, 720, 782, 813, 844, 906, 937, 968, 287, 318, 349, 380, 411, 442, 473, 504, 535, 566, 597, 628, + 659, 690, 721, 752, 783, 814, 845, 876, 907, 938, 969, 1000, 319, 350, 381, 443, 474, 505, 567, 598, 629, 691, 722, 753, 815, 846, 877, 939, 970, 1001, 351, 382, + 475, 506, 599, 630, 723, 754, 847, 878, 971, 1002, 383, 507, 631, 755, 879, 1003, 412, 536, 660, 784, 908, 413, 444, 537, 568, 661, 692, 785, 816, 909, 940, 414, + 445, 476, 538, 569, 600, 662, 693, 724, 786, 817, 848, 910, 941, 972, 415, 446, 477, 508, 539, 570, 601, 632, 663, 694, 725, 756, 787, 818, 849, 880, 911, 942, + 973, 1004, 447, 478, 509, 571, 602, 633, 695, 726, 757, 819, 850, 881, 943, 974, 1005, 479, 510, 603, 634, 727, 758, 851, 882, 975, 1006, 511, 635, 759, 883, 1007, + 540, 664, 788, 912, 541, 572, 665, 696, 789, 820, 913, 944, 542, 573, 604, 666, 697, 728, 790, 821, 852, 914, 945, 976, 543, 574, 605, 636, 667, 698, 729, 760, + 791, 822, 853, 884, 915, 946, 977, 1008, 575, 606, 637, 699, 730, 761, 823, 854, 885, 947, 978, 1009, 607, 638, 731, 762, 855, 886, 979, 1010, 639, 763, 887, 1011, + 668, 792, 916, 669, 700, 793, 824, 917, 948, 670, 701, 732, 794, 825, 856, 918, 949, 980, 671, 702, 733, 764, 795, 826, 857, 888, 919, 950, 981, 1012, 703, 734, + 765, 827, 858, 889, 951, 982, 1013, 735, 766, 859, 890, 983, 1014, 767, 891, 1015, 796, 920, 797, 828, 921, 952, 798, 829, 860, 922, 953, 984, 799, 830, 861, 892, + 923, 954, 985, 1016, 831, 862, 893, 955, 986, 1017, 863, 894, 987, 1018, 895, 1019, 924, 925, 956, 926, 957, 988, 927, 958, 989, 1020, 959, 990, 1021, 991, 1022, 1023, +}; + +const int16_t * const ff_vp9_scans[5][4] = { + { + ff_vp9_default_scan_4x4, ff_vp9_col_scan_4x4, + ff_vp9_row_scan_4x4, ff_vp9_default_scan_4x4 + }, { + ff_vp9_default_scan_8x8, ff_vp9_col_scan_8x8, + ff_vp9_row_scan_8x8, ff_vp9_default_scan_8x8 + }, { + ff_vp9_default_scan_16x16, ff_vp9_col_scan_16x16, + ff_vp9_row_scan_16x16, ff_vp9_default_scan_16x16 + }, { + ff_vp9_default_scan_32x32, ff_vp9_default_scan_32x32, + ff_vp9_default_scan_32x32, ff_vp9_default_scan_32x32 + }, { // lossless + ff_vp9_default_scan_4x4, ff_vp9_default_scan_4x4, + ff_vp9_default_scan_4x4, ff_vp9_default_scan_4x4 + } +}; + +const int16_t ff_vp9_default_scan_4x4_nb[16][2] = { + { 0, 0 }, { 0, 0 }, { 4, 1 }, { 1, 1 }, + { 4, 4 }, { 2, 2 }, { 5, 2 }, { 8, 8 }, + { 8, 5 }, { 6, 3 }, { 9, 6 }, { 12, 9 }, + { 10, 7 }, { 13, 10 }, { 14, 11 }, { 0, 0 }, +}; + +const int16_t ff_vp9_col_scan_4x4_nb[16][2] = { + { 0, 0 }, { 1, 1 }, { 0, 0 }, { 2, 2 }, + { 4, 4 }, { 5, 5 }, { 4, 4 }, { 6, 6 }, + { 8, 8 }, { 9, 9 }, { 8, 8 }, { 12, 12 }, + { 10, 10 }, { 13, 13 }, { 14, 14 }, { 0, 0 }, +}; + +const int16_t ff_vp9_row_scan_4x4_nb[16][2] = { + { 0, 0 }, { 0, 0 }, { 4, 4 }, { 1, 1 }, + { 8, 8 }, { 5, 5 }, { 1, 1 }, { 2, 2 }, + { 9, 9 }, { 2, 2 }, { 6, 6 }, { 3, 3 }, + { 10, 10 }, { 7, 7 }, { 11, 11 }, { 0, 0 }, +}; + +const int16_t ff_vp9_default_scan_8x8_nb[64][2] = { + { 0, 0 }, { 0, 0 }, { 1, 1 }, { 8, 1 }, + { 8, 8 }, { 9, 2 }, { 2, 2 }, { 16, 9 }, + { 16, 16 }, { 17, 10 }, { 10, 3 }, { 3, 3 }, + { 24, 17 }, { 24, 24 }, { 18, 11 }, { 11, 4 }, + { 25, 18 }, { 4, 4 }, { 32, 25 }, { 19, 12 }, + { 26, 19 }, { 32, 32 }, { 12, 5 }, { 33, 26 }, + { 5, 5 }, { 40, 33 }, { 27, 20 }, { 20, 13 }, + { 34, 27 }, { 41, 34 }, { 40, 40 }, { 13, 6 }, + { 6, 6 }, { 35, 28 }, { 28, 21 }, { 42, 35 }, + { 48, 48 }, { 48, 41 }, { 21, 14 }, { 14, 7 }, + { 36, 29 }, { 49, 42 }, { 43, 36 }, { 56, 49 }, + { 29, 22 }, { 22, 15 }, { 50, 43 }, { 44, 37 }, + { 57, 50 }, { 37, 30 }, { 30, 23 }, { 51, 44 }, + { 58, 51 }, { 38, 31 }, { 45, 38 }, { 52, 45 }, + { 59, 52 }, { 46, 39 }, { 53, 46 }, { 60, 53 }, + { 54, 47 }, { 61, 54 }, { 62, 55 }, { 0, 0 }, +}; + +const int16_t ff_vp9_col_scan_8x8_nb[64][2] = { + { 0, 0 }, { 1, 1 }, { 0, 0 }, { 2, 2 }, + { 8, 8 }, { 3, 3 }, { 9, 9 }, { 8, 8 }, + { 4, 4 }, { 10, 10 }, { 16, 16 }, { 11, 11 }, + { 17, 17 }, { 5, 5 }, { 16, 16 }, { 18, 18 }, + { 12, 12 }, { 24, 24 }, { 6, 6 }, { 25, 25 }, + { 19, 19 }, { 24, 24 }, { 13, 13 }, { 26, 26 }, + { 20, 20 }, { 32, 32 }, { 27, 27 }, { 33, 33 }, + { 14, 14 }, { 21, 21 }, { 34, 34 }, { 32, 32 }, + { 28, 28 }, { 40, 40 }, { 35, 35 }, { 22, 22 }, + { 29, 29 }, { 41, 41 }, { 36, 36 }, { 40, 40 }, + { 42, 42 }, { 30, 30 }, { 43, 43 }, { 48, 48 }, + { 37, 37 }, { 49, 49 }, { 48, 48 }, { 44, 44 }, + { 38, 38 }, { 50, 50 }, { 56, 56 }, { 51, 51 }, + { 45, 45 }, { 57, 57 }, { 52, 52 }, { 58, 58 }, + { 46, 46 }, { 59, 59 }, { 53, 53 }, { 60, 60 }, + { 54, 54 }, { 61, 61 }, { 62, 62 }, { 0, 0 }, +}; + +const int16_t ff_vp9_row_scan_8x8_nb[64][2] = { + { 0, 0 }, { 8, 8 }, { 0, 0 }, { 1, 1 }, + { 16, 16 }, { 1, 1 }, { 9, 9 }, { 24, 24 }, + { 2, 2 }, { 17, 17 }, { 2, 2 }, { 32, 32 }, + { 10, 10 }, { 3, 3 }, { 25, 25 }, { 18, 18 }, + { 11, 11 }, { 3, 3 }, { 40, 40 }, { 33, 33 }, + { 26, 26 }, { 4, 4 }, { 19, 19 }, { 48, 48 }, + { 12, 12 }, { 4, 4 }, { 34, 34 }, { 27, 27 }, + { 5, 5 }, { 41, 41 }, { 20, 20 }, { 5, 5 }, + { 13, 13 }, { 35, 35 }, { 28, 28 }, { 6, 6 }, + { 42, 42 }, { 21, 21 }, { 49, 49 }, { 6, 6 }, + { 36, 36 }, { 14, 14 }, { 29, 29 }, { 43, 43 }, + { 7, 7 }, { 50, 50 }, { 22, 22 }, { 15, 15 }, + { 37, 37 }, { 44, 44 }, { 30, 30 }, { 51, 51 }, + { 23, 23 }, { 38, 38 }, { 45, 45 }, { 31, 31 }, + { 52, 52 }, { 39, 39 }, { 53, 53 }, { 46, 46 }, + { 54, 54 }, { 47, 47 }, { 55, 55 }, { 0, 0 }, +}; + +const int16_t ff_vp9_default_scan_16x16_nb[256][2] = { + { 0, 0 }, { 0, 0 }, { 1, 1 }, { 16, 1 }, + { 16, 16 }, { 2, 2 }, { 17, 2 }, { 32, 17 }, + { 32, 32 }, { 3, 3 }, { 33, 18 }, { 18, 3 }, + { 48, 33 }, { 19, 4 }, { 4, 4 }, { 34, 19 }, + { 48, 48 }, { 49, 34 }, { 35, 20 }, { 64, 49 }, + { 20, 5 }, { 5, 5 }, { 50, 35 }, { 64, 64 }, + { 65, 50 }, { 36, 21 }, { 21, 6 }, { 51, 36 }, + { 6, 6 }, { 80, 65 }, { 66, 51 }, { 37, 22 }, + { 81, 66 }, { 52, 37 }, { 22, 7 }, { 80, 80 }, + { 67, 52 }, { 7, 7 }, { 82, 67 }, { 96, 81 }, + { 53, 38 }, { 38, 23 }, { 68, 53 }, { 96, 96 }, + { 23, 8 }, { 97, 82 }, { 83, 68 }, { 69, 54 }, + { 54, 39 }, { 8, 8 }, { 39, 24 }, { 84, 69 }, + { 98, 83 }, { 112, 97 }, { 112, 112 }, { 24, 9 }, + { 113, 98 }, { 99, 84 }, { 70, 55 }, { 85, 70 }, + { 55, 40 }, { 9, 9 }, { 40, 25 }, { 114, 99 }, + { 100, 85 }, { 128, 113 }, { 115, 100 }, { 71, 56 }, + { 86, 71 }, { 25, 10 }, { 129, 114 }, { 128, 128 }, + { 101, 86 }, { 56, 41 }, { 10, 10 }, { 41, 26 }, + { 116, 101 }, { 130, 115 }, { 144, 129 }, { 87, 72 }, + { 102, 87 }, { 26, 11 }, { 72, 57 }, { 131, 116 }, + { 117, 102 }, { 145, 130 }, { 57, 42 }, { 144, 144 }, + { 11, 11 }, { 42, 27 }, { 132, 117 }, { 146, 131 }, + { 103, 88 }, { 88, 73 }, { 118, 103 }, { 160, 145 }, + { 73, 58 }, { 147, 132 }, { 133, 118 }, { 27, 12 }, + { 161, 146 }, { 58, 43 }, { 12, 12 }, { 160, 160 }, + { 119, 104 }, { 148, 133 }, { 89, 74 }, { 134, 119 }, + { 104, 89 }, { 162, 147 }, { 43, 28 }, { 74, 59 }, + { 176, 161 }, { 163, 148 }, { 28, 13 }, { 149, 134 }, + { 120, 105 }, { 135, 120 }, { 177, 162 }, { 164, 149 }, + { 13, 13 }, { 105, 90 }, { 59, 44 }, { 90, 75 }, + { 150, 135 }, { 44, 29 }, { 178, 163 }, { 176, 176 }, + { 136, 121 }, { 165, 150 }, { 121, 106 }, { 75, 60 }, + { 179, 164 }, { 151, 136 }, { 29, 14 }, { 60, 45 }, + { 14, 14 }, { 106, 91 }, { 166, 151 }, { 180, 165 }, + { 192, 177 }, { 91, 76 }, { 192, 192 }, { 45, 30 }, + { 137, 122 }, { 122, 107 }, { 152, 137 }, { 193, 178 }, + { 76, 61 }, { 167, 152 }, { 181, 166 }, { 30, 15 }, + { 194, 179 }, { 208, 193 }, { 182, 167 }, { 107, 92 }, + { 138, 123 }, { 61, 46 }, { 153, 138 }, { 46, 31 }, + { 195, 180 }, { 92, 77 }, { 168, 153 }, { 209, 194 }, + { 196, 181 }, { 208, 208 }, { 123, 108 }, { 183, 168 }, + { 210, 195 }, { 77, 62 }, { 108, 93 }, { 169, 154 }, + { 154, 139 }, { 62, 47 }, { 197, 182 }, { 211, 196 }, + { 184, 169 }, { 224, 209 }, { 224, 224 }, { 139, 124 }, + { 93, 78 }, { 198, 183 }, { 124, 109 }, { 78, 63 }, + { 212, 197 }, { 225, 210 }, { 170, 155 }, { 185, 170 }, + { 155, 140 }, { 213, 198 }, { 199, 184 }, { 109, 94 }, + { 226, 211 }, { 140, 125 }, { 94, 79 }, { 240, 225 }, + { 214, 199 }, { 227, 212 }, { 200, 185 }, { 125, 110 }, + { 241, 226 }, { 186, 171 }, { 171, 156 }, { 156, 141 }, + { 228, 213 }, { 110, 95 }, { 215, 200 }, { 242, 227 }, + { 141, 126 }, { 201, 186 }, { 229, 214 }, { 126, 111 }, + { 216, 201 }, { 243, 228 }, { 172, 157 }, { 187, 172 }, + { 230, 215 }, { 157, 142 }, { 202, 187 }, { 142, 127 }, + { 244, 229 }, { 217, 202 }, { 231, 216 }, { 188, 173 }, + { 245, 230 }, { 158, 143 }, { 173, 158 }, { 232, 217 }, + { 246, 231 }, { 218, 203 }, { 203, 188 }, { 174, 159 }, + { 189, 174 }, { 247, 232 }, { 233, 218 }, { 204, 189 }, + { 219, 204 }, { 248, 233 }, { 190, 175 }, { 234, 219 }, + { 220, 205 }, { 249, 234 }, { 205, 190 }, { 221, 206 }, + { 250, 235 }, { 235, 220 }, { 206, 191 }, { 236, 221 }, + { 222, 207 }, { 251, 236 }, { 237, 222 }, { 252, 237 }, + { 238, 223 }, { 253, 238 }, { 254, 239 }, { 0, 0 }, +}; + +const int16_t ff_vp9_col_scan_16x16_nb[256][2] = { + { 0, 0 }, { 1, 1 }, { 2, 2 }, { 0, 0 }, + { 3, 3 }, { 16, 16 }, { 4, 4 }, { 17, 17 }, + { 5, 5 }, { 18, 18 }, { 16, 16 }, { 19, 19 }, + { 6, 6 }, { 32, 32 }, { 20, 20 }, { 33, 33 }, + { 7, 7 }, { 34, 34 }, { 21, 21 }, { 32, 32 }, + { 35, 35 }, { 8, 8 }, { 48, 48 }, { 22, 22 }, + { 49, 49 }, { 36, 36 }, { 9, 9 }, { 37, 37 }, + { 50, 50 }, { 23, 23 }, { 48, 48 }, { 51, 51 }, + { 10, 10 }, { 64, 64 }, { 38, 38 }, { 24, 24 }, + { 52, 52 }, { 65, 65 }, { 53, 53 }, { 39, 39 }, + { 66, 66 }, { 11, 11 }, { 64, 64 }, { 25, 25 }, + { 67, 67 }, { 54, 54 }, { 80, 80 }, { 40, 40 }, + { 68, 68 }, { 12, 12 }, { 26, 26 }, { 81, 81 }, + { 55, 55 }, { 69, 69 }, { 82, 82 }, { 41, 41 }, + { 13, 13 }, { 83, 83 }, { 80, 80 }, { 70, 70 }, + { 27, 27 }, { 56, 56 }, { 84, 84 }, { 96, 96 }, + { 14, 14 }, { 71, 71 }, { 97, 97 }, { 42, 42 }, + { 85, 85 }, { 57, 57 }, { 98, 98 }, { 28, 28 }, + { 86, 86 }, { 99, 99 }, { 96, 96 }, { 72, 72 }, + { 43, 43 }, { 100, 100 }, { 58, 58 }, { 29, 29 }, + { 112, 112 }, { 87, 87 }, { 113, 113 }, { 73, 73 }, + { 112, 112 }, { 101, 101 }, { 44, 44 }, { 30, 30 }, + { 114, 114 }, { 59, 59 }, { 102, 102 }, { 88, 88 }, + { 115, 115 }, { 74, 74 }, { 128, 128 }, { 116, 116 }, + { 45, 45 }, { 103, 103 }, { 89, 89 }, { 60, 60 }, + { 129, 129 }, { 117, 117 }, { 130, 130 }, { 131, 131 }, + { 104, 104 }, { 75, 75 }, { 46, 46 }, { 118, 118 }, + { 128, 128 }, { 90, 90 }, { 61, 61 }, { 132, 132 }, + { 105, 105 }, { 144, 144 }, { 119, 119 }, { 145, 145 }, + { 133, 133 }, { 76, 76 }, { 146, 146 }, { 120, 120 }, + { 91, 91 }, { 134, 134 }, { 147, 147 }, { 62, 62 }, + { 106, 106 }, { 135, 135 }, { 121, 121 }, { 92, 92 }, + { 148, 148 }, { 144, 144 }, { 77, 77 }, { 149, 149 }, + { 136, 136 }, { 107, 107 }, { 160, 160 }, { 161, 161 }, + { 150, 150 }, { 122, 122 }, { 78, 78 }, { 137, 137 }, + { 162, 162 }, { 151, 151 }, { 93, 93 }, { 163, 163 }, + { 108, 108 }, { 164, 164 }, { 152, 152 }, { 123, 123 }, + { 138, 138 }, { 160, 160 }, { 165, 165 }, { 94, 94 }, + { 176, 176 }, { 166, 166 }, { 109, 109 }, { 153, 153 }, + { 177, 177 }, { 124, 124 }, { 178, 178 }, { 139, 139 }, + { 167, 167 }, { 154, 154 }, { 110, 110 }, { 179, 179 }, + { 176, 176 }, { 180, 180 }, { 168, 168 }, { 140, 140 }, + { 125, 125 }, { 181, 181 }, { 192, 192 }, { 193, 193 }, + { 155, 155 }, { 182, 182 }, { 169, 169 }, { 194, 194 }, + { 126, 126 }, { 141, 141 }, { 195, 195 }, { 183, 183 }, + { 192, 192 }, { 196, 196 }, { 156, 156 }, { 170, 170 }, + { 142, 142 }, { 184, 184 }, { 197, 197 }, { 208, 208 }, + { 198, 198 }, { 209, 209 }, { 171, 171 }, { 157, 157 }, + { 185, 185 }, { 210, 210 }, { 208, 208 }, { 211, 211 }, + { 199, 199 }, { 224, 224 }, { 158, 158 }, { 212, 212 }, + { 224, 224 }, { 186, 186 }, { 200, 200 }, { 172, 172 }, + { 225, 225 }, { 213, 213 }, { 214, 214 }, { 226, 226 }, + { 201, 201 }, { 227, 227 }, { 187, 187 }, { 240, 240 }, + { 215, 215 }, { 173, 173 }, { 228, 228 }, { 241, 241 }, + { 202, 202 }, { 242, 242 }, { 216, 216 }, { 229, 229 }, + { 174, 174 }, { 188, 188 }, { 243, 243 }, { 230, 230 }, + { 203, 203 }, { 217, 217 }, { 231, 231 }, { 244, 244 }, + { 218, 218 }, { 245, 245 }, { 189, 189 }, { 232, 232 }, + { 204, 204 }, { 190, 190 }, { 246, 246 }, { 233, 233 }, + { 247, 247 }, { 219, 219 }, { 205, 205 }, { 248, 248 }, + { 234, 234 }, { 220, 220 }, { 206, 206 }, { 249, 249 }, + { 235, 235 }, { 221, 221 }, { 250, 250 }, { 222, 222 }, + { 236, 236 }, { 237, 237 }, { 251, 251 }, { 238, 238 }, + { 252, 252 }, { 253, 253 }, { 254, 254 }, { 0, 0 }, +}; + +const int16_t ff_vp9_row_scan_16x16_nb[256][2] = { + { 0, 0 }, { 16, 16 }, { 0, 0 }, { 32, 32 }, + { 1, 1 }, { 48, 48 }, { 17, 17 }, { 1, 1 }, + { 64, 64 }, { 2, 2 }, { 33, 33 }, { 80, 80 }, + { 18, 18 }, { 2, 2 }, { 49, 49 }, { 3, 3 }, + { 96, 96 }, { 34, 34 }, { 65, 65 }, { 19, 19 }, + { 3, 3 }, { 112, 112 }, { 50, 50 }, { 4, 4 }, + { 81, 81 }, { 35, 35 }, { 66, 66 }, { 4, 4 }, + { 128, 128 }, { 20, 20 }, { 51, 51 }, { 97, 97 }, + { 82, 82 }, { 5, 5 }, { 36, 36 }, { 144, 144 }, + { 67, 67 }, { 113, 113 }, { 21, 21 }, { 52, 52 }, + { 5, 5 }, { 98, 98 }, { 160, 160 }, { 83, 83 }, + { 37, 37 }, { 6, 6 }, { 68, 68 }, { 129, 129 }, + { 22, 22 }, { 53, 53 }, { 114, 114 }, { 6, 6 }, + { 99, 99 }, { 176, 176 }, { 84, 84 }, { 38, 38 }, + { 7, 7 }, { 69, 69 }, { 145, 145 }, { 130, 130 }, + { 115, 115 }, { 23, 23 }, { 54, 54 }, { 192, 192 }, + { 100, 100 }, { 7, 7 }, { 85, 85 }, { 161, 161 }, + { 39, 39 }, { 70, 70 }, { 8, 8 }, { 146, 146 }, + { 131, 131 }, { 116, 116 }, { 55, 55 }, { 208, 208 }, + { 101, 101 }, { 24, 24 }, { 86, 86 }, { 8, 8 }, + { 132, 132 }, { 40, 40 }, { 71, 71 }, { 177, 177 }, + { 147, 147 }, { 224, 224 }, { 117, 117 }, { 162, 162 }, + { 9, 9 }, { 102, 102 }, { 56, 56 }, { 25, 25 }, + { 87, 87 }, { 148, 148 }, { 9, 9 }, { 133, 133 }, + { 72, 72 }, { 118, 118 }, { 193, 193 }, { 163, 163 }, + { 41, 41 }, { 103, 103 }, { 178, 178 }, { 10, 10 }, + { 57, 57 }, { 149, 149 }, { 134, 134 }, { 88, 88 }, + { 26, 26 }, { 119, 119 }, { 10, 10 }, { 164, 164 }, + { 104, 104 }, { 73, 73 }, { 209, 209 }, { 179, 179 }, + { 42, 42 }, { 11, 11 }, { 194, 194 }, { 135, 135 }, + { 165, 165 }, { 150, 150 }, { 58, 58 }, { 27, 27 }, + { 89, 89 }, { 11, 11 }, { 120, 120 }, { 74, 74 }, + { 43, 43 }, { 225, 225 }, { 105, 105 }, { 12, 12 }, + { 180, 180 }, { 151, 151 }, { 195, 195 }, { 136, 136 }, + { 28, 28 }, { 166, 166 }, { 121, 121 }, { 59, 59 }, + { 12, 12 }, { 210, 210 }, { 90, 90 }, { 106, 106 }, + { 44, 44 }, { 181, 181 }, { 75, 75 }, { 152, 152 }, + { 13, 13 }, { 167, 167 }, { 137, 137 }, { 13, 13 }, + { 60, 60 }, { 196, 196 }, { 122, 122 }, { 29, 29 }, + { 91, 91 }, { 14, 14 }, { 182, 182 }, { 76, 76 }, + { 211, 211 }, { 153, 153 }, { 14, 14 }, { 107, 107 }, + { 138, 138 }, { 45, 45 }, { 226, 226 }, { 168, 168 }, + { 197, 197 }, { 123, 123 }, { 30, 30 }, { 61, 61 }, + { 15, 15 }, { 92, 92 }, { 154, 154 }, { 183, 183 }, + { 169, 169 }, { 108, 108 }, { 212, 212 }, { 77, 77 }, + { 139, 139 }, { 198, 198 }, { 46, 46 }, { 124, 124 }, + { 227, 227 }, { 62, 62 }, { 31, 31 }, { 184, 184 }, + { 93, 93 }, { 170, 170 }, { 155, 155 }, { 185, 185 }, + { 78, 78 }, { 47, 47 }, { 199, 199 }, { 213, 213 }, + { 140, 140 }, { 63, 63 }, { 109, 109 }, { 125, 125 }, + { 94, 94 }, { 200, 200 }, { 171, 171 }, { 156, 156 }, + { 228, 228 }, { 186, 186 }, { 214, 214 }, { 201, 201 }, + { 79, 79 }, { 141, 141 }, { 110, 110 }, { 229, 229 }, + { 95, 95 }, { 126, 126 }, { 215, 215 }, { 172, 172 }, + { 111, 111 }, { 142, 142 }, { 202, 202 }, { 157, 157 }, + { 216, 216 }, { 230, 230 }, { 217, 217 }, { 187, 187 }, + { 127, 127 }, { 231, 231 }, { 158, 158 }, { 173, 173 }, + { 143, 143 }, { 203, 203 }, { 188, 188 }, { 232, 232 }, + { 218, 218 }, { 233, 233 }, { 159, 159 }, { 174, 174 }, + { 204, 204 }, { 189, 189 }, { 234, 234 }, { 219, 219 }, + { 175, 175 }, { 205, 205 }, { 235, 235 }, { 220, 220 }, + { 190, 190 }, { 236, 236 }, { 206, 206 }, { 191, 191 }, + { 221, 221 }, { 207, 207 }, { 237, 237 }, { 222, 222 }, + { 238, 238 }, { 223, 223 }, { 239, 239 }, { 0, 0 }, +}; + +const int16_t ff_vp9_default_scan_32x32_nb[1024][2] = { + { 0, 0 }, { 0, 0 }, { 1, 1 }, { 32, 1 }, + { 32, 32 }, { 2, 2 }, { 33, 2 }, { 64, 33 }, + { 3, 3 }, { 64, 64 }, { 34, 3 }, { 65, 34 }, + { 4, 4 }, { 35, 4 }, { 96, 65 }, { 66, 35 }, + { 96, 96 }, { 97, 66 }, { 67, 36 }, { 36, 5 }, + { 5, 5 }, { 128, 97 }, { 98, 67 }, { 6, 6 }, + { 128, 128 }, { 68, 37 }, { 37, 6 }, { 129, 98 }, + { 99, 68 }, { 160, 129 }, { 130, 99 }, { 38, 7 }, + { 69, 38 }, { 7, 7 }, { 100, 69 }, { 161, 130 }, + { 131, 100 }, { 160, 160 }, { 70, 39 }, { 39, 8 }, + { 8, 8 }, { 101, 70 }, { 162, 131 }, { 132, 101 }, + { 192, 161 }, { 71, 40 }, { 192, 192 }, { 102, 71 }, + { 40, 9 }, { 163, 132 }, { 9, 9 }, { 193, 162 }, + { 133, 102 }, { 164, 133 }, { 72, 41 }, { 103, 72 }, + { 134, 103 }, { 224, 193 }, { 41, 10 }, { 194, 163 }, + { 10, 10 }, { 224, 224 }, { 165, 134 }, { 225, 194 }, + { 195, 164 }, { 73, 42 }, { 104, 73 }, { 135, 104 }, + { 42, 11 }, { 11, 11 }, { 166, 135 }, { 196, 165 }, + { 226, 195 }, { 256, 225 }, { 74, 43 }, { 105, 74 }, + { 136, 105 }, { 227, 196 }, { 43, 12 }, { 197, 166 }, + { 167, 136 }, { 257, 226 }, { 256, 256 }, { 12, 12 }, + { 228, 197 }, { 75, 44 }, { 106, 75 }, { 198, 167 }, + { 137, 106 }, { 258, 227 }, { 168, 137 }, { 288, 257 }, + { 44, 13 }, { 229, 198 }, { 259, 228 }, { 199, 168 }, + { 107, 76 }, { 13, 13 }, { 169, 138 }, { 138, 107 }, + { 288, 288 }, { 289, 258 }, { 76, 45 }, { 230, 199 }, + { 260, 229 }, { 45, 14 }, { 200, 169 }, { 139, 108 }, + { 290, 259 }, { 108, 77 }, { 231, 200 }, { 320, 289 }, + { 261, 230 }, { 170, 139 }, { 77, 46 }, { 291, 260 }, + { 14, 14 }, { 321, 290 }, { 201, 170 }, { 262, 231 }, + { 320, 320 }, { 171, 140 }, { 292, 261 }, { 232, 201 }, + { 140, 109 }, { 322, 291 }, { 109, 78 }, { 46, 15 }, + { 202, 171 }, { 263, 232 }, { 233, 202 }, { 293, 262 }, + { 352, 321 }, { 323, 292 }, { 15, 15 }, { 78, 47 }, + { 203, 172 }, { 264, 233 }, { 294, 263 }, { 324, 293 }, + { 172, 141 }, { 353, 322 }, { 141, 110 }, { 234, 203 }, + { 352, 352 }, { 47, 16 }, { 295, 264 }, { 110, 79 }, + { 265, 234 }, { 354, 323 }, { 325, 294 }, { 79, 48 }, + { 16, 16 }, { 204, 173 }, { 235, 204 }, { 173, 142 }, + { 355, 324 }, { 384, 353 }, { 326, 295 }, { 142, 111 }, + { 296, 265 }, { 266, 235 }, { 356, 325 }, { 385, 354 }, + { 111, 80 }, { 48, 17 }, { 327, 296 }, { 297, 266 }, + { 205, 174 }, { 384, 384 }, { 236, 205 }, { 357, 326 }, + { 386, 355 }, { 80, 49 }, { 174, 143 }, { 17, 17 }, + { 328, 297 }, { 358, 327 }, { 387, 356 }, { 298, 267 }, + { 329, 298 }, { 388, 357 }, { 112, 81 }, { 416, 385 }, + { 237, 206 }, { 359, 328 }, { 49, 18 }, { 206, 175 }, + { 417, 386 }, { 389, 358 }, { 330, 299 }, { 18, 18 }, + { 416, 416 }, { 360, 329 }, { 81, 50 }, { 418, 387 }, + { 390, 359 }, { 238, 207 }, { 50, 19 }, { 361, 330 }, + { 419, 388 }, { 113, 82 }, { 448, 417 }, { 448, 448 }, + { 420, 389 }, { 82, 51 }, { 362, 331 }, { 449, 418 }, + { 421, 390 }, { 480, 480 }, { 450, 419 }, { 422, 391 }, + { 114, 83 }, { 451, 420 }, { 480, 449 }, { 452, 421 }, + { 481, 450 }, { 453, 422 }, { 512, 512 }, { 482, 451 }, + { 454, 423 }, { 512, 481 }, { 483, 452 }, { 513, 482 }, + { 484, 453 }, { 514, 483 }, { 485, 454 }, { 544, 513 }, + { 544, 544 }, { 486, 455 }, { 545, 514 }, { 546, 515 }, + { 576, 576 }, { 576, 545 }, { 577, 546 }, { 578, 547 }, + { 608, 577 }, { 609, 578 }, { 610, 579 }, { 19, 19 }, + { 143, 112 }, { 267, 236 }, { 391, 360 }, { 515, 484 }, + { 608, 608 }, { 20, 20 }, { 51, 20 }, { 144, 113 }, + { 175, 144 }, { 268, 237 }, { 299, 268 }, { 392, 361 }, + { 423, 392 }, { 516, 485 }, { 547, 516 }, { 640, 609 }, + { 640, 640 }, { 21, 21 }, { 52, 21 }, { 83, 52 }, + { 145, 114 }, { 176, 145 }, { 207, 176 }, { 269, 238 }, + { 300, 269 }, { 331, 300 }, { 393, 362 }, { 424, 393 }, + { 455, 424 }, { 517, 486 }, { 548, 517 }, { 579, 548 }, + { 641, 610 }, { 672, 641 }, { 672, 672 }, { 22, 22 }, + { 53, 22 }, { 84, 53 }, { 115, 84 }, { 146, 115 }, + { 177, 146 }, { 208, 177 }, { 239, 208 }, { 270, 239 }, + { 301, 270 }, { 332, 301 }, { 363, 332 }, { 394, 363 }, + { 425, 394 }, { 456, 425 }, { 487, 456 }, { 518, 487 }, + { 549, 518 }, { 580, 549 }, { 611, 580 }, { 642, 611 }, + { 673, 642 }, { 704, 673 }, { 704, 704 }, { 54, 23 }, + { 85, 54 }, { 116, 85 }, { 178, 147 }, { 209, 178 }, + { 240, 209 }, { 302, 271 }, { 333, 302 }, { 364, 333 }, + { 426, 395 }, { 457, 426 }, { 488, 457 }, { 550, 519 }, + { 581, 550 }, { 612, 581 }, { 674, 643 }, { 705, 674 }, + { 736, 705 }, { 86, 55 }, { 117, 86 }, { 210, 179 }, + { 241, 210 }, { 334, 303 }, { 365, 334 }, { 458, 427 }, + { 489, 458 }, { 582, 551 }, { 613, 582 }, { 706, 675 }, + { 737, 706 }, { 118, 87 }, { 242, 211 }, { 366, 335 }, + { 490, 459 }, { 614, 583 }, { 738, 707 }, { 23, 23 }, + { 147, 116 }, { 271, 240 }, { 395, 364 }, { 519, 488 }, + { 643, 612 }, { 736, 736 }, { 24, 24 }, { 55, 24 }, + { 148, 117 }, { 179, 148 }, { 272, 241 }, { 303, 272 }, + { 396, 365 }, { 427, 396 }, { 520, 489 }, { 551, 520 }, + { 644, 613 }, { 675, 644 }, { 768, 737 }, { 768, 768 }, + { 25, 25 }, { 56, 25 }, { 87, 56 }, { 149, 118 }, + { 180, 149 }, { 211, 180 }, { 273, 242 }, { 304, 273 }, + { 335, 304 }, { 397, 366 }, { 428, 397 }, { 459, 428 }, + { 521, 490 }, { 552, 521 }, { 583, 552 }, { 645, 614 }, + { 676, 645 }, { 707, 676 }, { 769, 738 }, { 800, 769 }, + { 800, 800 }, { 26, 26 }, { 57, 26 }, { 88, 57 }, + { 119, 88 }, { 150, 119 }, { 181, 150 }, { 212, 181 }, + { 243, 212 }, { 274, 243 }, { 305, 274 }, { 336, 305 }, + { 367, 336 }, { 398, 367 }, { 429, 398 }, { 460, 429 }, + { 491, 460 }, { 522, 491 }, { 553, 522 }, { 584, 553 }, + { 615, 584 }, { 646, 615 }, { 677, 646 }, { 708, 677 }, + { 739, 708 }, { 770, 739 }, { 801, 770 }, { 832, 801 }, + { 832, 832 }, { 58, 27 }, { 89, 58 }, { 120, 89 }, + { 182, 151 }, { 213, 182 }, { 244, 213 }, { 306, 275 }, + { 337, 306 }, { 368, 337 }, { 430, 399 }, { 461, 430 }, + { 492, 461 }, { 554, 523 }, { 585, 554 }, { 616, 585 }, + { 678, 647 }, { 709, 678 }, { 740, 709 }, { 802, 771 }, + { 833, 802 }, { 864, 833 }, { 90, 59 }, { 121, 90 }, + { 214, 183 }, { 245, 214 }, { 338, 307 }, { 369, 338 }, + { 462, 431 }, { 493, 462 }, { 586, 555 }, { 617, 586 }, + { 710, 679 }, { 741, 710 }, { 834, 803 }, { 865, 834 }, + { 122, 91 }, { 246, 215 }, { 370, 339 }, { 494, 463 }, + { 618, 587 }, { 742, 711 }, { 866, 835 }, { 27, 27 }, + { 151, 120 }, { 275, 244 }, { 399, 368 }, { 523, 492 }, + { 647, 616 }, { 771, 740 }, { 864, 864 }, { 28, 28 }, + { 59, 28 }, { 152, 121 }, { 183, 152 }, { 276, 245 }, + { 307, 276 }, { 400, 369 }, { 431, 400 }, { 524, 493 }, + { 555, 524 }, { 648, 617 }, { 679, 648 }, { 772, 741 }, + { 803, 772 }, { 896, 865 }, { 896, 896 }, { 29, 29 }, + { 60, 29 }, { 91, 60 }, { 153, 122 }, { 184, 153 }, + { 215, 184 }, { 277, 246 }, { 308, 277 }, { 339, 308 }, + { 401, 370 }, { 432, 401 }, { 463, 432 }, { 525, 494 }, + { 556, 525 }, { 587, 556 }, { 649, 618 }, { 680, 649 }, + { 711, 680 }, { 773, 742 }, { 804, 773 }, { 835, 804 }, + { 897, 866 }, { 928, 897 }, { 928, 928 }, { 30, 30 }, + { 61, 30 }, { 92, 61 }, { 123, 92 }, { 154, 123 }, + { 185, 154 }, { 216, 185 }, { 247, 216 }, { 278, 247 }, + { 309, 278 }, { 340, 309 }, { 371, 340 }, { 402, 371 }, + { 433, 402 }, { 464, 433 }, { 495, 464 }, { 526, 495 }, + { 557, 526 }, { 588, 557 }, { 619, 588 }, { 650, 619 }, + { 681, 650 }, { 712, 681 }, { 743, 712 }, { 774, 743 }, + { 805, 774 }, { 836, 805 }, { 867, 836 }, { 898, 867 }, + { 929, 898 }, { 960, 929 }, { 960, 960 }, { 62, 31 }, + { 93, 62 }, { 124, 93 }, { 186, 155 }, { 217, 186 }, + { 248, 217 }, { 310, 279 }, { 341, 310 }, { 372, 341 }, + { 434, 403 }, { 465, 434 }, { 496, 465 }, { 558, 527 }, + { 589, 558 }, { 620, 589 }, { 682, 651 }, { 713, 682 }, + { 744, 713 }, { 806, 775 }, { 837, 806 }, { 868, 837 }, + { 930, 899 }, { 961, 930 }, { 992, 961 }, { 94, 63 }, + { 125, 94 }, { 218, 187 }, { 249, 218 }, { 342, 311 }, + { 373, 342 }, { 466, 435 }, { 497, 466 }, { 590, 559 }, + { 621, 590 }, { 714, 683 }, { 745, 714 }, { 838, 807 }, + { 869, 838 }, { 962, 931 }, { 993, 962 }, { 126, 95 }, + { 250, 219 }, { 374, 343 }, { 498, 467 }, { 622, 591 }, + { 746, 715 }, { 870, 839 }, { 994, 963 }, { 155, 124 }, + { 279, 248 }, { 403, 372 }, { 527, 496 }, { 651, 620 }, + { 775, 744 }, { 899, 868 }, { 156, 125 }, { 187, 156 }, + { 280, 249 }, { 311, 280 }, { 404, 373 }, { 435, 404 }, + { 528, 497 }, { 559, 528 }, { 652, 621 }, { 683, 652 }, + { 776, 745 }, { 807, 776 }, { 900, 869 }, { 931, 900 }, + { 157, 126 }, { 188, 157 }, { 219, 188 }, { 281, 250 }, + { 312, 281 }, { 343, 312 }, { 405, 374 }, { 436, 405 }, + { 467, 436 }, { 529, 498 }, { 560, 529 }, { 591, 560 }, + { 653, 622 }, { 684, 653 }, { 715, 684 }, { 777, 746 }, + { 808, 777 }, { 839, 808 }, { 901, 870 }, { 932, 901 }, + { 963, 932 }, { 158, 127 }, { 189, 158 }, { 220, 189 }, + { 251, 220 }, { 282, 251 }, { 313, 282 }, { 344, 313 }, + { 375, 344 }, { 406, 375 }, { 437, 406 }, { 468, 437 }, + { 499, 468 }, { 530, 499 }, { 561, 530 }, { 592, 561 }, + { 623, 592 }, { 654, 623 }, { 685, 654 }, { 716, 685 }, + { 747, 716 }, { 778, 747 }, { 809, 778 }, { 840, 809 }, + { 871, 840 }, { 902, 871 }, { 933, 902 }, { 964, 933 }, + { 995, 964 }, { 190, 159 }, { 221, 190 }, { 252, 221 }, + { 314, 283 }, { 345, 314 }, { 376, 345 }, { 438, 407 }, + { 469, 438 }, { 500, 469 }, { 562, 531 }, { 593, 562 }, + { 624, 593 }, { 686, 655 }, { 717, 686 }, { 748, 717 }, + { 810, 779 }, { 841, 810 }, { 872, 841 }, { 934, 903 }, + { 965, 934 }, { 996, 965 }, { 222, 191 }, { 253, 222 }, + { 346, 315 }, { 377, 346 }, { 470, 439 }, { 501, 470 }, + { 594, 563 }, { 625, 594 }, { 718, 687 }, { 749, 718 }, + { 842, 811 }, { 873, 842 }, { 966, 935 }, { 997, 966 }, + { 254, 223 }, { 378, 347 }, { 502, 471 }, { 626, 595 }, + { 750, 719 }, { 874, 843 }, { 998, 967 }, { 283, 252 }, + { 407, 376 }, { 531, 500 }, { 655, 624 }, { 779, 748 }, + { 903, 872 }, { 284, 253 }, { 315, 284 }, { 408, 377 }, + { 439, 408 }, { 532, 501 }, { 563, 532 }, { 656, 625 }, + { 687, 656 }, { 780, 749 }, { 811, 780 }, { 904, 873 }, + { 935, 904 }, { 285, 254 }, { 316, 285 }, { 347, 316 }, + { 409, 378 }, { 440, 409 }, { 471, 440 }, { 533, 502 }, + { 564, 533 }, { 595, 564 }, { 657, 626 }, { 688, 657 }, + { 719, 688 }, { 781, 750 }, { 812, 781 }, { 843, 812 }, + { 905, 874 }, { 936, 905 }, { 967, 936 }, { 286, 255 }, + { 317, 286 }, { 348, 317 }, { 379, 348 }, { 410, 379 }, + { 441, 410 }, { 472, 441 }, { 503, 472 }, { 534, 503 }, + { 565, 534 }, { 596, 565 }, { 627, 596 }, { 658, 627 }, + { 689, 658 }, { 720, 689 }, { 751, 720 }, { 782, 751 }, + { 813, 782 }, { 844, 813 }, { 875, 844 }, { 906, 875 }, + { 937, 906 }, { 968, 937 }, { 999, 968 }, { 318, 287 }, + { 349, 318 }, { 380, 349 }, { 442, 411 }, { 473, 442 }, + { 504, 473 }, { 566, 535 }, { 597, 566 }, { 628, 597 }, + { 690, 659 }, { 721, 690 }, { 752, 721 }, { 814, 783 }, + { 845, 814 }, { 876, 845 }, { 938, 907 }, { 969, 938 }, + { 1000, 969 }, { 350, 319 }, { 381, 350 }, { 474, 443 }, + { 505, 474 }, { 598, 567 }, { 629, 598 }, { 722, 691 }, + { 753, 722 }, { 846, 815 }, { 877, 846 }, { 970, 939 }, + { 1001, 970 }, { 382, 351 }, { 506, 475 }, { 630, 599 }, + { 754, 723 }, { 878, 847 }, { 1002, 971 }, { 411, 380 }, + { 535, 504 }, { 659, 628 }, { 783, 752 }, { 907, 876 }, + { 412, 381 }, { 443, 412 }, { 536, 505 }, { 567, 536 }, + { 660, 629 }, { 691, 660 }, { 784, 753 }, { 815, 784 }, + { 908, 877 }, { 939, 908 }, { 413, 382 }, { 444, 413 }, + { 475, 444 }, { 537, 506 }, { 568, 537 }, { 599, 568 }, + { 661, 630 }, { 692, 661 }, { 723, 692 }, { 785, 754 }, + { 816, 785 }, { 847, 816 }, { 909, 878 }, { 940, 909 }, + { 971, 940 }, { 414, 383 }, { 445, 414 }, { 476, 445 }, + { 507, 476 }, { 538, 507 }, { 569, 538 }, { 600, 569 }, + { 631, 600 }, { 662, 631 }, { 693, 662 }, { 724, 693 }, + { 755, 724 }, { 786, 755 }, { 817, 786 }, { 848, 817 }, + { 879, 848 }, { 910, 879 }, { 941, 910 }, { 972, 941 }, + { 1003, 972 }, { 446, 415 }, { 477, 446 }, { 508, 477 }, + { 570, 539 }, { 601, 570 }, { 632, 601 }, { 694, 663 }, + { 725, 694 }, { 756, 725 }, { 818, 787 }, { 849, 818 }, + { 880, 849 }, { 942, 911 }, { 973, 942 }, { 1004, 973 }, + { 478, 447 }, { 509, 478 }, { 602, 571 }, { 633, 602 }, + { 726, 695 }, { 757, 726 }, { 850, 819 }, { 881, 850 }, + { 974, 943 }, { 1005, 974 }, { 510, 479 }, { 634, 603 }, + { 758, 727 }, { 882, 851 }, { 1006, 975 }, { 539, 508 }, + { 663, 632 }, { 787, 756 }, { 911, 880 }, { 540, 509 }, + { 571, 540 }, { 664, 633 }, { 695, 664 }, { 788, 757 }, + { 819, 788 }, { 912, 881 }, { 943, 912 }, { 541, 510 }, + { 572, 541 }, { 603, 572 }, { 665, 634 }, { 696, 665 }, + { 727, 696 }, { 789, 758 }, { 820, 789 }, { 851, 820 }, + { 913, 882 }, { 944, 913 }, { 975, 944 }, { 542, 511 }, + { 573, 542 }, { 604, 573 }, { 635, 604 }, { 666, 635 }, + { 697, 666 }, { 728, 697 }, { 759, 728 }, { 790, 759 }, + { 821, 790 }, { 852, 821 }, { 883, 852 }, { 914, 883 }, + { 945, 914 }, { 976, 945 }, { 1007, 976 }, { 574, 543 }, + { 605, 574 }, { 636, 605 }, { 698, 667 }, { 729, 698 }, + { 760, 729 }, { 822, 791 }, { 853, 822 }, { 884, 853 }, + { 946, 915 }, { 977, 946 }, { 1008, 977 }, { 606, 575 }, + { 637, 606 }, { 730, 699 }, { 761, 730 }, { 854, 823 }, + { 885, 854 }, { 978, 947 }, { 1009, 978 }, { 638, 607 }, + { 762, 731 }, { 886, 855 }, { 1010, 979 }, { 667, 636 }, + { 791, 760 }, { 915, 884 }, { 668, 637 }, { 699, 668 }, + { 792, 761 }, { 823, 792 }, { 916, 885 }, { 947, 916 }, + { 669, 638 }, { 700, 669 }, { 731, 700 }, { 793, 762 }, + { 824, 793 }, { 855, 824 }, { 917, 886 }, { 948, 917 }, + { 979, 948 }, { 670, 639 }, { 701, 670 }, { 732, 701 }, + { 763, 732 }, { 794, 763 }, { 825, 794 }, { 856, 825 }, + { 887, 856 }, { 918, 887 }, { 949, 918 }, { 980, 949 }, + { 1011, 980 }, { 702, 671 }, { 733, 702 }, { 764, 733 }, + { 826, 795 }, { 857, 826 }, { 888, 857 }, { 950, 919 }, + { 981, 950 }, { 1012, 981 }, { 734, 703 }, { 765, 734 }, + { 858, 827 }, { 889, 858 }, { 982, 951 }, { 1013, 982 }, + { 766, 735 }, { 890, 859 }, { 1014, 983 }, { 795, 764 }, + { 919, 888 }, { 796, 765 }, { 827, 796 }, { 920, 889 }, + { 951, 920 }, { 797, 766 }, { 828, 797 }, { 859, 828 }, + { 921, 890 }, { 952, 921 }, { 983, 952 }, { 798, 767 }, + { 829, 798 }, { 860, 829 }, { 891, 860 }, { 922, 891 }, + { 953, 922 }, { 984, 953 }, { 1015, 984 }, { 830, 799 }, + { 861, 830 }, { 892, 861 }, { 954, 923 }, { 985, 954 }, + { 1016, 985 }, { 862, 831 }, { 893, 862 }, { 986, 955 }, + { 1017, 986 }, { 894, 863 }, { 1018, 987 }, { 923, 892 }, + { 924, 893 }, { 955, 924 }, { 925, 894 }, { 956, 925 }, + { 987, 956 }, { 926, 895 }, { 957, 926 }, { 988, 957 }, + { 1019, 988 }, { 958, 927 }, { 989, 958 }, { 1020, 989 }, + { 990, 959 }, { 1021, 990 }, { 1022, 991 }, { 0, 0 }, +}; + +const int16_t (* const ff_vp9_scans_nb[5][4])[2] = { + { + ff_vp9_default_scan_4x4_nb, ff_vp9_col_scan_4x4_nb, + ff_vp9_row_scan_4x4_nb, ff_vp9_default_scan_4x4_nb + }, { + ff_vp9_default_scan_8x8_nb, ff_vp9_col_scan_8x8_nb, + ff_vp9_row_scan_8x8_nb, ff_vp9_default_scan_8x8_nb + }, { + ff_vp9_default_scan_16x16_nb, ff_vp9_col_scan_16x16_nb, + ff_vp9_row_scan_16x16_nb, ff_vp9_default_scan_16x16_nb + }, { + ff_vp9_default_scan_32x32_nb, ff_vp9_default_scan_32x32_nb, + ff_vp9_default_scan_32x32_nb, ff_vp9_default_scan_32x32_nb + }, { // lossless + ff_vp9_default_scan_4x4_nb, ff_vp9_default_scan_4x4_nb, + ff_vp9_default_scan_4x4_nb, ff_vp9_default_scan_4x4_nb + } +}; + +const uint8_t ff_vp9_model_pareto8[256][8] = { + { 6, 86, 128, 11, 87, 42, 91, 52 }, + { 3, 86, 128, 6, 86, 23, 88, 29 }, + { 6, 86, 128, 11, 87, 42, 91, 52 }, + { 9, 86, 129, 17, 88, 61, 94, 76 }, + { 12, 86, 129, 22, 88, 77, 97, 93 }, + { 15, 87, 129, 28, 89, 93, 100, 110 }, + { 17, 87, 129, 33, 90, 105, 103, 123 }, + { 20, 88, 130, 38, 91, 118, 106, 136 }, + { 23, 88, 130, 43, 91, 128, 108, 146 }, + { 26, 89, 131, 48, 92, 139, 111, 156 }, + { 28, 89, 131, 53, 93, 147, 114, 163 }, + { 31, 90, 131, 58, 94, 156, 117, 171 }, + { 34, 90, 131, 62, 94, 163, 119, 177 }, + { 37, 90, 132, 66, 95, 171, 122, 184 }, + { 39, 90, 132, 70, 96, 177, 124, 189 }, + { 42, 91, 132, 75, 97, 183, 127, 194 }, + { 44, 91, 132, 79, 97, 188, 129, 198 }, + { 47, 92, 133, 83, 98, 193, 132, 202 }, + { 49, 92, 133, 86, 99, 197, 134, 205 }, + { 52, 93, 133, 90, 100, 201, 137, 208 }, + { 54, 93, 133, 94, 100, 204, 139, 211 }, + { 57, 94, 134, 98, 101, 208, 142, 214 }, + { 59, 94, 134, 101, 102, 211, 144, 216 }, + { 62, 94, 135, 105, 103, 214, 146, 218 }, + { 64, 94, 135, 108, 103, 216, 148, 220 }, + { 66, 95, 135, 111, 104, 219, 151, 222 }, + { 68, 95, 135, 114, 105, 221, 153, 223 }, + { 71, 96, 136, 117, 106, 224, 155, 225 }, + { 73, 96, 136, 120, 106, 225, 157, 226 }, + { 76, 97, 136, 123, 107, 227, 159, 228 }, + { 78, 97, 136, 126, 108, 229, 160, 229 }, + { 80, 98, 137, 129, 109, 231, 162, 231 }, + { 82, 98, 137, 131, 109, 232, 164, 232 }, + { 84, 98, 138, 134, 110, 234, 166, 233 }, + { 86, 98, 138, 137, 111, 235, 168, 234 }, + { 89, 99, 138, 140, 112, 236, 170, 235 }, + { 91, 99, 138, 142, 112, 237, 171, 235 }, + { 93, 100, 139, 145, 113, 238, 173, 236 }, + { 95, 100, 139, 147, 114, 239, 174, 237 }, + { 97, 101, 140, 149, 115, 240, 176, 238 }, + { 99, 101, 140, 151, 115, 241, 177, 238 }, + { 101, 102, 140, 154, 116, 242, 179, 239 }, + { 103, 102, 140, 156, 117, 242, 180, 239 }, + { 105, 103, 141, 158, 118, 243, 182, 240 }, + { 107, 103, 141, 160, 118, 243, 183, 240 }, + { 109, 104, 141, 162, 119, 244, 185, 241 }, + { 111, 104, 141, 164, 119, 244, 186, 241 }, + { 113, 104, 142, 166, 120, 245, 187, 242 }, + { 114, 104, 142, 168, 121, 245, 188, 242 }, + { 116, 105, 143, 170, 122, 246, 190, 243 }, + { 118, 105, 143, 171, 122, 246, 191, 243 }, + { 120, 106, 143, 173, 123, 247, 192, 244 }, + { 121, 106, 143, 175, 124, 247, 193, 244 }, + { 123, 107, 144, 177, 125, 248, 195, 244 }, + { 125, 107, 144, 178, 125, 248, 196, 244 }, + { 127, 108, 145, 180, 126, 249, 197, 245 }, + { 128, 108, 145, 181, 127, 249, 198, 245 }, + { 130, 109, 145, 183, 128, 249, 199, 245 }, + { 132, 109, 145, 184, 128, 249, 200, 245 }, + { 134, 110, 146, 186, 129, 250, 201, 246 }, + { 135, 110, 146, 187, 130, 250, 202, 246 }, + { 137, 111, 147, 189, 131, 251, 203, 246 }, + { 138, 111, 147, 190, 131, 251, 204, 246 }, + { 140, 112, 147, 192, 132, 251, 205, 247 }, + { 141, 112, 147, 193, 132, 251, 206, 247 }, + { 143, 113, 148, 194, 133, 251, 207, 247 }, + { 144, 113, 148, 195, 134, 251, 207, 247 }, + { 146, 114, 149, 197, 135, 252, 208, 248 }, + { 147, 114, 149, 198, 135, 252, 209, 248 }, + { 149, 115, 149, 199, 136, 252, 210, 248 }, + { 150, 115, 149, 200, 137, 252, 210, 248 }, + { 152, 115, 150, 201, 138, 252, 211, 248 }, + { 153, 115, 150, 202, 138, 252, 212, 248 }, + { 155, 116, 151, 204, 139, 253, 213, 249 }, + { 156, 116, 151, 205, 139, 253, 213, 249 }, + { 158, 117, 151, 206, 140, 253, 214, 249 }, + { 159, 117, 151, 207, 141, 253, 215, 249 }, + { 161, 118, 152, 208, 142, 253, 216, 249 }, + { 162, 118, 152, 209, 142, 253, 216, 249 }, + { 163, 119, 153, 210, 143, 253, 217, 249 }, + { 164, 119, 153, 211, 143, 253, 217, 249 }, + { 166, 120, 153, 212, 144, 254, 218, 250 }, + { 167, 120, 153, 212, 145, 254, 219, 250 }, + { 168, 121, 154, 213, 146, 254, 220, 250 }, + { 169, 121, 154, 214, 146, 254, 220, 250 }, + { 171, 122, 155, 215, 147, 254, 221, 250 }, + { 172, 122, 155, 216, 147, 254, 221, 250 }, + { 173, 123, 155, 217, 148, 254, 222, 250 }, + { 174, 123, 155, 217, 149, 254, 222, 250 }, + { 176, 124, 156, 218, 150, 254, 223, 250 }, + { 177, 124, 156, 219, 150, 254, 223, 250 }, + { 178, 125, 157, 220, 151, 254, 224, 251 }, + { 179, 125, 157, 220, 151, 254, 224, 251 }, + { 180, 126, 157, 221, 152, 254, 225, 251 }, + { 181, 126, 157, 221, 152, 254, 225, 251 }, + { 183, 127, 158, 222, 153, 254, 226, 251 }, + { 184, 127, 158, 223, 154, 254, 226, 251 }, + { 185, 128, 159, 224, 155, 255, 227, 251 }, + { 186, 128, 159, 224, 155, 255, 227, 251 }, + { 187, 129, 160, 225, 156, 255, 228, 251 }, + { 188, 130, 160, 225, 156, 255, 228, 251 }, + { 189, 131, 160, 226, 157, 255, 228, 251 }, + { 190, 131, 160, 226, 158, 255, 228, 251 }, + { 191, 132, 161, 227, 159, 255, 229, 251 }, + { 192, 132, 161, 227, 159, 255, 229, 251 }, + { 193, 133, 162, 228, 160, 255, 230, 252 }, + { 194, 133, 162, 229, 160, 255, 230, 252 }, + { 195, 134, 163, 230, 161, 255, 231, 252 }, + { 196, 134, 163, 230, 161, 255, 231, 252 }, + { 197, 135, 163, 231, 162, 255, 231, 252 }, + { 198, 135, 163, 231, 162, 255, 231, 252 }, + { 199, 136, 164, 232, 163, 255, 232, 252 }, + { 200, 136, 164, 232, 164, 255, 232, 252 }, + { 201, 137, 165, 233, 165, 255, 233, 252 }, + { 201, 137, 165, 233, 165, 255, 233, 252 }, + { 202, 138, 166, 233, 166, 255, 233, 252 }, + { 203, 138, 166, 233, 166, 255, 233, 252 }, + { 204, 139, 166, 234, 167, 255, 234, 252 }, + { 205, 139, 166, 234, 167, 255, 234, 252 }, + { 206, 140, 167, 235, 168, 255, 235, 252 }, + { 206, 140, 167, 235, 168, 255, 235, 252 }, + { 207, 141, 168, 236, 169, 255, 235, 252 }, + { 208, 141, 168, 236, 170, 255, 235, 252 }, + { 209, 142, 169, 237, 171, 255, 236, 252 }, + { 209, 143, 169, 237, 171, 255, 236, 252 }, + { 210, 144, 169, 237, 172, 255, 236, 252 }, + { 211, 144, 169, 237, 172, 255, 236, 252 }, + { 212, 145, 170, 238, 173, 255, 237, 252 }, + { 213, 145, 170, 238, 173, 255, 237, 252 }, + { 214, 146, 171, 239, 174, 255, 237, 253 }, + { 214, 146, 171, 239, 174, 255, 237, 253 }, + { 215, 147, 172, 240, 175, 255, 238, 253 }, + { 215, 147, 172, 240, 175, 255, 238, 253 }, + { 216, 148, 173, 240, 176, 255, 238, 253 }, + { 217, 148, 173, 240, 176, 255, 238, 253 }, + { 218, 149, 173, 241, 177, 255, 239, 253 }, + { 218, 149, 173, 241, 178, 255, 239, 253 }, + { 219, 150, 174, 241, 179, 255, 239, 253 }, + { 219, 151, 174, 241, 179, 255, 239, 253 }, + { 220, 152, 175, 242, 180, 255, 240, 253 }, + { 221, 152, 175, 242, 180, 255, 240, 253 }, + { 222, 153, 176, 242, 181, 255, 240, 253 }, + { 222, 153, 176, 242, 181, 255, 240, 253 }, + { 223, 154, 177, 243, 182, 255, 240, 253 }, + { 223, 154, 177, 243, 182, 255, 240, 253 }, + { 224, 155, 178, 244, 183, 255, 241, 253 }, + { 224, 155, 178, 244, 183, 255, 241, 253 }, + { 225, 156, 178, 244, 184, 255, 241, 253 }, + { 225, 157, 178, 244, 184, 255, 241, 253 }, + { 226, 158, 179, 244, 185, 255, 242, 253 }, + { 227, 158, 179, 244, 185, 255, 242, 253 }, + { 228, 159, 180, 245, 186, 255, 242, 253 }, + { 228, 159, 180, 245, 186, 255, 242, 253 }, + { 229, 160, 181, 245, 187, 255, 242, 253 }, + { 229, 160, 181, 245, 187, 255, 242, 253 }, + { 230, 161, 182, 246, 188, 255, 243, 253 }, + { 230, 162, 182, 246, 188, 255, 243, 253 }, + { 231, 163, 183, 246, 189, 255, 243, 253 }, + { 231, 163, 183, 246, 189, 255, 243, 253 }, + { 232, 164, 184, 247, 190, 255, 243, 253 }, + { 232, 164, 184, 247, 190, 255, 243, 253 }, + { 233, 165, 185, 247, 191, 255, 244, 253 }, + { 233, 165, 185, 247, 191, 255, 244, 253 }, + { 234, 166, 185, 247, 192, 255, 244, 253 }, + { 234, 167, 185, 247, 192, 255, 244, 253 }, + { 235, 168, 186, 248, 193, 255, 244, 253 }, + { 235, 168, 186, 248, 193, 255, 244, 253 }, + { 236, 169, 187, 248, 194, 255, 244, 253 }, + { 236, 169, 187, 248, 194, 255, 244, 253 }, + { 236, 170, 188, 248, 195, 255, 245, 253 }, + { 236, 170, 188, 248, 195, 255, 245, 253 }, + { 237, 171, 189, 249, 196, 255, 245, 254 }, + { 237, 172, 189, 249, 196, 255, 245, 254 }, + { 238, 173, 190, 249, 197, 255, 245, 254 }, + { 238, 173, 190, 249, 197, 255, 245, 254 }, + { 239, 174, 191, 249, 198, 255, 245, 254 }, + { 239, 174, 191, 249, 198, 255, 245, 254 }, + { 240, 175, 192, 249, 199, 255, 246, 254 }, + { 240, 176, 192, 249, 199, 255, 246, 254 }, + { 240, 177, 193, 250, 200, 255, 246, 254 }, + { 240, 177, 193, 250, 200, 255, 246, 254 }, + { 241, 178, 194, 250, 201, 255, 246, 254 }, + { 241, 178, 194, 250, 201, 255, 246, 254 }, + { 242, 179, 195, 250, 202, 255, 246, 254 }, + { 242, 180, 195, 250, 202, 255, 246, 254 }, + { 242, 181, 196, 250, 203, 255, 247, 254 }, + { 242, 181, 196, 250, 203, 255, 247, 254 }, + { 243, 182, 197, 251, 204, 255, 247, 254 }, + { 243, 183, 197, 251, 204, 255, 247, 254 }, + { 244, 184, 198, 251, 205, 255, 247, 254 }, + { 244, 184, 198, 251, 205, 255, 247, 254 }, + { 244, 185, 199, 251, 206, 255, 247, 254 }, + { 244, 185, 199, 251, 206, 255, 247, 254 }, + { 245, 186, 200, 251, 207, 255, 247, 254 }, + { 245, 187, 200, 251, 207, 255, 247, 254 }, + { 246, 188, 201, 252, 207, 255, 248, 254 }, + { 246, 188, 201, 252, 207, 255, 248, 254 }, + { 246, 189, 202, 252, 208, 255, 248, 254 }, + { 246, 190, 202, 252, 208, 255, 248, 254 }, + { 247, 191, 203, 252, 209, 255, 248, 254 }, + { 247, 191, 203, 252, 209, 255, 248, 254 }, + { 247, 192, 204, 252, 210, 255, 248, 254 }, + { 247, 193, 204, 252, 210, 255, 248, 254 }, + { 248, 194, 205, 252, 211, 255, 248, 254 }, + { 248, 194, 205, 252, 211, 255, 248, 254 }, + { 248, 195, 206, 252, 212, 255, 249, 254 }, + { 248, 196, 206, 252, 212, 255, 249, 254 }, + { 249, 197, 207, 253, 213, 255, 249, 254 }, + { 249, 197, 207, 253, 213, 255, 249, 254 }, + { 249, 198, 208, 253, 214, 255, 249, 254 }, + { 249, 199, 209, 253, 214, 255, 249, 254 }, + { 250, 200, 210, 253, 215, 255, 249, 254 }, + { 250, 200, 210, 253, 215, 255, 249, 254 }, + { 250, 201, 211, 253, 215, 255, 249, 254 }, + { 250, 202, 211, 253, 215, 255, 249, 254 }, + { 250, 203, 212, 253, 216, 255, 249, 254 }, + { 250, 203, 212, 253, 216, 255, 249, 254 }, + { 251, 204, 213, 253, 217, 255, 250, 254 }, + { 251, 205, 213, 253, 217, 255, 250, 254 }, + { 251, 206, 214, 254, 218, 255, 250, 254 }, + { 251, 206, 215, 254, 218, 255, 250, 254 }, + { 252, 207, 216, 254, 219, 255, 250, 254 }, + { 252, 208, 216, 254, 219, 255, 250, 254 }, + { 252, 209, 217, 254, 220, 255, 250, 254 }, + { 252, 210, 217, 254, 220, 255, 250, 254 }, + { 252, 211, 218, 254, 221, 255, 250, 254 }, + { 252, 212, 218, 254, 221, 255, 250, 254 }, + { 253, 213, 219, 254, 222, 255, 250, 254 }, + { 253, 213, 220, 254, 222, 255, 250, 254 }, + { 253, 214, 221, 254, 223, 255, 250, 254 }, + { 253, 215, 221, 254, 223, 255, 250, 254 }, + { 253, 216, 222, 254, 224, 255, 251, 254 }, + { 253, 217, 223, 254, 224, 255, 251, 254 }, + { 253, 218, 224, 254, 225, 255, 251, 254 }, + { 253, 219, 224, 254, 225, 255, 251, 254 }, + { 254, 220, 225, 254, 225, 255, 251, 254 }, + { 254, 221, 226, 254, 225, 255, 251, 254 }, + { 254, 222, 227, 255, 226, 255, 251, 254 }, + { 254, 223, 227, 255, 226, 255, 251, 254 }, + { 254, 224, 228, 255, 227, 255, 251, 254 }, + { 254, 225, 229, 255, 227, 255, 251, 254 }, + { 254, 226, 230, 255, 228, 255, 251, 254 }, + { 254, 227, 230, 255, 229, 255, 251, 254 }, + { 255, 228, 231, 255, 230, 255, 251, 254 }, + { 255, 229, 232, 255, 230, 255, 251, 254 }, + { 255, 230, 233, 255, 231, 255, 252, 254 }, + { 255, 231, 234, 255, 231, 255, 252, 254 }, + { 255, 232, 235, 255, 232, 255, 252, 254 }, + { 255, 233, 236, 255, 232, 255, 252, 254 }, + { 255, 235, 237, 255, 233, 255, 252, 254 }, + { 255, 236, 238, 255, 234, 255, 252, 254 }, + { 255, 238, 240, 255, 235, 255, 252, 255 }, + { 255, 239, 241, 255, 235, 255, 252, 254 }, + { 255, 241, 243, 255, 236, 255, 252, 254 }, + { 255, 243, 245, 255, 237, 255, 252, 254 }, + { 255, 246, 247, 255, 239, 255, 253, 255 }, +}; + +const ProbContext ff_vp9_default_probs = { + { /* y_mode */ + { 65, 32, 18, 144, 162, 194, 41, 51, 98 } /* bsize < 8x8 */, + { 132, 68, 18, 165, 217, 196, 45, 40, 78 } /* bsize < 16x16 */, + { 173, 80, 19, 176, 240, 193, 64, 35, 46 } /* bsize < 32x32 */, + { 221, 135, 38, 194, 248, 121, 96, 85, 29 } /* bsize >= 32x32 */ + }, { /* uv_mode */ + { 48, 12, 154, 155, 139, 90, 34, 117, 119 } /* y = v */, + { 67, 6, 25, 204, 243, 158, 13, 21, 96 } /* y = h */, + { 120, 7, 76, 176, 208, 126, 28, 54, 103 } /* y = dc */, + { 97, 5, 44, 131, 176, 139, 48, 68, 97 } /* y = d45 */, + { 83, 5, 42, 156, 111, 152, 26, 49, 152 } /* y = d135 */, + { 80, 5, 58, 178, 74, 83, 33, 62, 145 } /* y = d117 */, + { 86, 5, 32, 154, 192, 168, 14, 22, 163 } /* y = d153 */, + { 77, 7, 64, 116, 132, 122, 37, 126, 120 } /* y = d63 */, + { 85, 5, 32, 156, 216, 148, 19, 29, 73 } /* y = d27 */, + { 101, 21, 107, 181, 192, 103, 19, 67, 125 } /* y = tm */ + }, { /* filter */ + { 235, 162, }, + { 36, 255, }, + { 34, 3, }, + { 149, 144, }, + }, { /* mv_mode */ + { 2, 173, 34}, // 0 = both zero mv + { 7, 145, 85}, // 1 = one zero mv + one a predicted mv + { 7, 166, 63}, // 2 = two predicted mvs + { 7, 94, 66}, // 3 = one predicted/zero and one new mv + { 8, 64, 46}, // 4 = two new mvs + { 17, 81, 31}, // 5 = one intra neighbour + x + { 25, 29, 30}, // 6 = two intra neighbours + }, { /* intra */ + 9, 102, 187, 225 + }, { /* comp */ + 239, 183, 119, 96, 41 + }, { /* single_ref */ + { 33, 16 }, + { 77, 74 }, + { 142, 142 }, + { 172, 170 }, + { 238, 247 } + }, { /* comp_ref */ + 50, 126, 123, 221, 226 + }, { /* tx32p */ + { 3, 136, 37, }, + { 5, 52, 13, }, + }, { /* tx16p */ + { 20, 152, }, + { 15, 101, }, + }, { /* tx8p */ + 100, 66 + }, { /* skip */ + 192, 128, 64 + }, { /* mv_joint */ + 32, 64, 96 + }, { + { /* mv vertical component */ + 128, /* sign */ + { 224, 144, 192, 168, 192, 176, 192, 198, 198, 245 }, /* class */ + 216, /* class0 */ + { 136, 140, 148, 160, 176, 192, 224, 234, 234, 240}, /* bits */ + { /* class0_fp */ + { 128, 128, 64 }, + { 96, 112, 64 } + }, + { 64, 96, 64 }, /* fp */ + 160, /* class0_hp bit */ + 128, /* hp */ + }, { /* mv horizontal component */ + 128, /* sign */ + { 216, 128, 176, 160, 176, 176, 192, 198, 198, 208 }, /* class */ + 208, /* class0 */ + { 136, 140, 148, 160, 176, 192, 224, 234, 234, 240 }, /* bits */ + { /* class0_fp */ + { 128, 128, 64 }, + { 96, 112, 64 } + }, + { 64, 96, 64 }, /* fp */ + 160, /* class0_hp bit */ + 128, /* hp */ + } + }, { /* partition */ + { /* 64x64 -> 32x32 */ + { 222, 34, 30 } /* a/l both not split */, + { 72, 16, 44 } /* a split, l not split */, + { 58, 32, 12 } /* l split, a not split */, + { 10, 7, 6 } /* a/l both split */, + }, { /* 32x32 -> 16x16 */ + { 177, 58, 59 } /* a/l both not split */, + { 68, 26, 63 } /* a split, l not split */, + { 52, 79, 25 } /* l split, a not split */, + { 17, 14, 12 } /* a/l both split */, + }, { /* 16x16 -> 8x8 */ + { 174, 73, 87 } /* a/l both not split */, + { 92, 41, 83 } /* a split, l not split */, + { 82, 99, 50 } /* l split, a not split */, + { 53, 39, 39 } /* a/l both split */, + }, { /* 8x8 -> 4x4 */ + { 199, 122, 141 } /* a/l both not split */, + { 147, 63, 159 } /* a split, l not split */, + { 148, 133, 118 } /* l split, a not split */, + { 121, 104, 114 } /* a/l both split */, + } + }, +}; + +const uint8_t ff_vp9_default_coef_probs[4][2][2][6][6][3] = { + { /* tx = 4x4 */ + { /* block Type 0 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 195, 29, 183 }, + { 84, 49, 136 }, + { 8, 42, 71 } + }, { /* Coeff Band 1 */ + { 31, 107, 169 }, + { 35, 99, 159 }, + { 17, 82, 140 }, + { 8, 66, 114 }, + { 2, 44, 76 }, + { 1, 19, 32 } + }, { /* Coeff Band 2 */ + { 40, 132, 201 }, + { 29, 114, 187 }, + { 13, 91, 157 }, + { 7, 75, 127 }, + { 3, 58, 95 }, + { 1, 28, 47 } + }, { /* Coeff Band 3 */ + { 69, 142, 221 }, + { 42, 122, 201 }, + { 15, 91, 159 }, + { 6, 67, 121 }, + { 1, 42, 77 }, + { 1, 17, 31 } + }, { /* Coeff Band 4 */ + { 102, 148, 228 }, + { 67, 117, 204 }, + { 17, 82, 154 }, + { 6, 59, 114 }, + { 2, 39, 75 }, + { 1, 15, 29 } + }, { /* Coeff Band 5 */ + { 156, 57, 233 }, + { 119, 57, 212 }, + { 58, 48, 163 }, + { 29, 40, 124 }, + { 12, 30, 81 }, + { 3, 12, 31 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 191, 107, 226 }, + { 124, 117, 204 }, + { 25, 99, 155 } + }, { /* Coeff Band 1 */ + { 29, 148, 210 }, + { 37, 126, 194 }, + { 8, 93, 157 }, + { 2, 68, 118 }, + { 1, 39, 69 }, + { 1, 17, 33 } + }, { /* Coeff Band 2 */ + { 41, 151, 213 }, + { 27, 123, 193 }, + { 3, 82, 144 }, + { 1, 58, 105 }, + { 1, 32, 60 }, + { 1, 13, 26 } + }, { /* Coeff Band 3 */ + { 59, 159, 220 }, + { 23, 126, 198 }, + { 4, 88, 151 }, + { 1, 66, 114 }, + { 1, 38, 71 }, + { 1, 18, 34 } + }, { /* Coeff Band 4 */ + { 114, 136, 232 }, + { 51, 114, 207 }, + { 11, 83, 155 }, + { 3, 56, 105 }, + { 1, 33, 65 }, + { 1, 17, 34 } + }, { /* Coeff Band 5 */ + { 149, 65, 234 }, + { 121, 57, 215 }, + { 61, 49, 166 }, + { 28, 36, 114 }, + { 12, 25, 76 }, + { 3, 16, 42 } + } + } + }, { /* block Type 1 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 214, 49, 220 }, + { 132, 63, 188 }, + { 42, 65, 137 } + }, { /* Coeff Band 1 */ + { 85, 137, 221 }, + { 104, 131, 216 }, + { 49, 111, 192 }, + { 21, 87, 155 }, + { 2, 49, 87 }, + { 1, 16, 28 } + }, { /* Coeff Band 2 */ + { 89, 163, 230 }, + { 90, 137, 220 }, + { 29, 100, 183 }, + { 10, 70, 135 }, + { 2, 42, 81 }, + { 1, 17, 33 } + }, { /* Coeff Band 3 */ + { 108, 167, 237 }, + { 55, 133, 222 }, + { 15, 97, 179 }, + { 4, 72, 135 }, + { 1, 45, 85 }, + { 1, 19, 38 } + }, { /* Coeff Band 4 */ + { 124, 146, 240 }, + { 66, 124, 224 }, + { 17, 88, 175 }, + { 4, 58, 122 }, + { 1, 36, 75 }, + { 1, 18, 37 } + }, { /* Coeff Band 5 */ + { 141, 79, 241 }, + { 126, 70, 227 }, + { 66, 58, 182 }, + { 30, 44, 136 }, + { 12, 34, 96 }, + { 2, 20, 47 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 229, 99, 249 }, + { 143, 111, 235 }, + { 46, 109, 192 } + }, { /* Coeff Band 1 */ + { 82, 158, 236 }, + { 94, 146, 224 }, + { 25, 117, 191 }, + { 9, 87, 149 }, + { 3, 56, 99 }, + { 1, 33, 57 } + }, { /* Coeff Band 2 */ + { 83, 167, 237 }, + { 68, 145, 222 }, + { 10, 103, 177 }, + { 2, 72, 131 }, + { 1, 41, 79 }, + { 1, 20, 39 } + }, { /* Coeff Band 3 */ + { 99, 167, 239 }, + { 47, 141, 224 }, + { 10, 104, 178 }, + { 2, 73, 133 }, + { 1, 44, 85 }, + { 1, 22, 47 } + }, { /* Coeff Band 4 */ + { 127, 145, 243 }, + { 71, 129, 228 }, + { 17, 93, 177 }, + { 3, 61, 124 }, + { 1, 41, 84 }, + { 1, 21, 52 } + }, { /* Coeff Band 5 */ + { 157, 78, 244 }, + { 140, 72, 231 }, + { 69, 58, 184 }, + { 31, 44, 137 }, + { 14, 38, 105 }, + { 8, 23, 61 } + } + } + } + }, { /* tx = 8x8 */ + { /* block Type 0 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 125, 34, 187 }, + { 52, 41, 133 }, + { 6, 31, 56 } + }, { /* Coeff Band 1 */ + { 37, 109, 153 }, + { 51, 102, 147 }, + { 23, 87, 128 }, + { 8, 67, 101 }, + { 1, 41, 63 }, + { 1, 19, 29 } + }, { /* Coeff Band 2 */ + { 31, 154, 185 }, + { 17, 127, 175 }, + { 6, 96, 145 }, + { 2, 73, 114 }, + { 1, 51, 82 }, + { 1, 28, 45 } + }, { /* Coeff Band 3 */ + { 23, 163, 200 }, + { 10, 131, 185 }, + { 2, 93, 148 }, + { 1, 67, 111 }, + { 1, 41, 69 }, + { 1, 14, 24 } + }, { /* Coeff Band 4 */ + { 29, 176, 217 }, + { 12, 145, 201 }, + { 3, 101, 156 }, + { 1, 69, 111 }, + { 1, 39, 63 }, + { 1, 14, 23 } + }, { /* Coeff Band 5 */ + { 57, 192, 233 }, + { 25, 154, 215 }, + { 6, 109, 167 }, + { 3, 78, 118 }, + { 1, 48, 69 }, + { 1, 21, 29 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 202, 105, 245 }, + { 108, 106, 216 }, + { 18, 90, 144 } + }, { /* Coeff Band 1 */ + { 33, 172, 219 }, + { 64, 149, 206 }, + { 14, 117, 177 }, + { 5, 90, 141 }, + { 2, 61, 95 }, + { 1, 37, 57 } + }, { /* Coeff Band 2 */ + { 33, 179, 220 }, + { 11, 140, 198 }, + { 1, 89, 148 }, + { 1, 60, 104 }, + { 1, 33, 57 }, + { 1, 12, 21 } + }, { /* Coeff Band 3 */ + { 30, 181, 221 }, + { 8, 141, 198 }, + { 1, 87, 145 }, + { 1, 58, 100 }, + { 1, 31, 55 }, + { 1, 12, 20 } + }, { /* Coeff Band 4 */ + { 32, 186, 224 }, + { 7, 142, 198 }, + { 1, 86, 143 }, + { 1, 58, 100 }, + { 1, 31, 55 }, + { 1, 12, 22 } + }, { /* Coeff Band 5 */ + { 57, 192, 227 }, + { 20, 143, 204 }, + { 3, 96, 154 }, + { 1, 68, 112 }, + { 1, 42, 69 }, + { 1, 19, 32 } + } + } + }, { /* block Type 1 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 212, 35, 215 }, + { 113, 47, 169 }, + { 29, 48, 105 } + }, { /* Coeff Band 1 */ + { 74, 129, 203 }, + { 106, 120, 203 }, + { 49, 107, 178 }, + { 19, 84, 144 }, + { 4, 50, 84 }, + { 1, 15, 25 } + }, { /* Coeff Band 2 */ + { 71, 172, 217 }, + { 44, 141, 209 }, + { 15, 102, 173 }, + { 6, 76, 133 }, + { 2, 51, 89 }, + { 1, 24, 42 } + }, { /* Coeff Band 3 */ + { 64, 185, 231 }, + { 31, 148, 216 }, + { 8, 103, 175 }, + { 3, 74, 131 }, + { 1, 46, 81 }, + { 1, 18, 30 } + }, { /* Coeff Band 4 */ + { 65, 196, 235 }, + { 25, 157, 221 }, + { 5, 105, 174 }, + { 1, 67, 120 }, + { 1, 38, 69 }, + { 1, 15, 30 } + }, { /* Coeff Band 5 */ + { 65, 204, 238 }, + { 30, 156, 224 }, + { 7, 107, 177 }, + { 2, 70, 124 }, + { 1, 42, 73 }, + { 1, 18, 34 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 225, 86, 251 }, + { 144, 104, 235 }, + { 42, 99, 181 } + }, { /* Coeff Band 1 */ + { 85, 175, 239 }, + { 112, 165, 229 }, + { 29, 136, 200 }, + { 12, 103, 162 }, + { 6, 77, 123 }, + { 2, 53, 84 } + }, { /* Coeff Band 2 */ + { 75, 183, 239 }, + { 30, 155, 221 }, + { 3, 106, 171 }, + { 1, 74, 128 }, + { 1, 44, 76 }, + { 1, 17, 28 } + }, { /* Coeff Band 3 */ + { 73, 185, 240 }, + { 27, 159, 222 }, + { 2, 107, 172 }, + { 1, 75, 127 }, + { 1, 42, 73 }, + { 1, 17, 29 } + }, { /* Coeff Band 4 */ + { 62, 190, 238 }, + { 21, 159, 222 }, + { 2, 107, 172 }, + { 1, 72, 122 }, + { 1, 40, 71 }, + { 1, 18, 32 } + }, { /* Coeff Band 5 */ + { 61, 199, 240 }, + { 27, 161, 226 }, + { 4, 113, 180 }, + { 1, 76, 129 }, + { 1, 46, 80 }, + { 1, 23, 41 } + } + } + } + }, { /* tx = 16x16 */ + { /* block Type 0 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 7, 27, 153 }, + { 5, 30, 95 }, + { 1, 16, 30 } + }, { /* Coeff Band 1 */ + { 50, 75, 127 }, + { 57, 75, 124 }, + { 27, 67, 108 }, + { 10, 54, 86 }, + { 1, 33, 52 }, + { 1, 12, 18 } + }, { /* Coeff Band 2 */ + { 43, 125, 151 }, + { 26, 108, 148 }, + { 7, 83, 122 }, + { 2, 59, 89 }, + { 1, 38, 60 }, + { 1, 17, 27 } + }, { /* Coeff Band 3 */ + { 23, 144, 163 }, + { 13, 112, 154 }, + { 2, 75, 117 }, + { 1, 50, 81 }, + { 1, 31, 51 }, + { 1, 14, 23 } + }, { /* Coeff Band 4 */ + { 18, 162, 185 }, + { 6, 123, 171 }, + { 1, 78, 125 }, + { 1, 51, 86 }, + { 1, 31, 54 }, + { 1, 14, 23 } + }, { /* Coeff Band 5 */ + { 15, 199, 227 }, + { 3, 150, 204 }, + { 1, 91, 146 }, + { 1, 55, 95 }, + { 1, 30, 53 }, + { 1, 11, 20 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 19, 55, 240 }, + { 19, 59, 196 }, + { 3, 52, 105 } + }, { /* Coeff Band 1 */ + { 41, 166, 207 }, + { 104, 153, 199 }, + { 31, 123, 181 }, + { 14, 101, 152 }, + { 5, 72, 106 }, + { 1, 36, 52 } + }, { /* Coeff Band 2 */ + { 35, 176, 211 }, + { 12, 131, 190 }, + { 2, 88, 144 }, + { 1, 60, 101 }, + { 1, 36, 60 }, + { 1, 16, 28 } + }, { /* Coeff Band 3 */ + { 28, 183, 213 }, + { 8, 134, 191 }, + { 1, 86, 142 }, + { 1, 56, 96 }, + { 1, 30, 53 }, + { 1, 12, 20 } + }, { /* Coeff Band 4 */ + { 20, 190, 215 }, + { 4, 135, 192 }, + { 1, 84, 139 }, + { 1, 53, 91 }, + { 1, 28, 49 }, + { 1, 11, 20 } + }, { /* Coeff Band 5 */ + { 13, 196, 216 }, + { 2, 137, 192 }, + { 1, 86, 143 }, + { 1, 57, 99 }, + { 1, 32, 56 }, + { 1, 13, 24 } + } + } + }, { /* block Type 1 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 211, 29, 217 }, + { 96, 47, 156 }, + { 22, 43, 87 } + }, { /* Coeff Band 1 */ + { 78, 120, 193 }, + { 111, 116, 186 }, + { 46, 102, 164 }, + { 15, 80, 128 }, + { 2, 49, 76 }, + { 1, 18, 28 } + }, { /* Coeff Band 2 */ + { 71, 161, 203 }, + { 42, 132, 192 }, + { 10, 98, 150 }, + { 3, 69, 109 }, + { 1, 44, 70 }, + { 1, 18, 29 } + }, { /* Coeff Band 3 */ + { 57, 186, 211 }, + { 30, 140, 196 }, + { 4, 93, 146 }, + { 1, 62, 102 }, + { 1, 38, 65 }, + { 1, 16, 27 } + }, { /* Coeff Band 4 */ + { 47, 199, 217 }, + { 14, 145, 196 }, + { 1, 88, 142 }, + { 1, 57, 98 }, + { 1, 36, 62 }, + { 1, 15, 26 } + }, { /* Coeff Band 5 */ + { 26, 219, 229 }, + { 5, 155, 207 }, + { 1, 94, 151 }, + { 1, 60, 104 }, + { 1, 36, 62 }, + { 1, 16, 28 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 233, 29, 248 }, + { 146, 47, 220 }, + { 43, 52, 140 } + }, { /* Coeff Band 1 */ + { 100, 163, 232 }, + { 179, 161, 222 }, + { 63, 142, 204 }, + { 37, 113, 174 }, + { 26, 89, 137 }, + { 18, 68, 97 } + }, { /* Coeff Band 2 */ + { 85, 181, 230 }, + { 32, 146, 209 }, + { 7, 100, 164 }, + { 3, 71, 121 }, + { 1, 45, 77 }, + { 1, 18, 30 } + }, { /* Coeff Band 3 */ + { 65, 187, 230 }, + { 20, 148, 207 }, + { 2, 97, 159 }, + { 1, 68, 116 }, + { 1, 40, 70 }, + { 1, 14, 29 } + }, { /* Coeff Band 4 */ + { 40, 194, 227 }, + { 8, 147, 204 }, + { 1, 94, 155 }, + { 1, 65, 112 }, + { 1, 39, 66 }, + { 1, 14, 26 } + }, { /* Coeff Band 5 */ + { 16, 208, 228 }, + { 3, 151, 207 }, + { 1, 98, 160 }, + { 1, 67, 117 }, + { 1, 41, 74 }, + { 1, 17, 31 } + } + } + } + }, { /* tx = 32x32 */ + { /* block Type 0 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 17, 38, 140 }, + { 7, 34, 80 }, + { 1, 17, 29 } + }, { /* Coeff Band 1 */ + { 37, 75, 128 }, + { 41, 76, 128 }, + { 26, 66, 116 }, + { 12, 52, 94 }, + { 2, 32, 55 }, + { 1, 10, 16 } + }, { /* Coeff Band 2 */ + { 50, 127, 154 }, + { 37, 109, 152 }, + { 16, 82, 121 }, + { 5, 59, 85 }, + { 1, 35, 54 }, + { 1, 13, 20 } + }, { /* Coeff Band 3 */ + { 40, 142, 167 }, + { 17, 110, 157 }, + { 2, 71, 112 }, + { 1, 44, 72 }, + { 1, 27, 45 }, + { 1, 11, 17 } + }, { /* Coeff Band 4 */ + { 30, 175, 188 }, + { 9, 124, 169 }, + { 1, 74, 116 }, + { 1, 48, 78 }, + { 1, 30, 49 }, + { 1, 11, 18 } + }, { /* Coeff Band 5 */ + { 10, 222, 223 }, + { 2, 150, 194 }, + { 1, 83, 128 }, + { 1, 48, 79 }, + { 1, 27, 45 }, + { 1, 11, 17 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 36, 41, 235 }, + { 29, 36, 193 }, + { 10, 27, 111 } + }, { /* Coeff Band 1 */ + { 85, 165, 222 }, + { 177, 162, 215 }, + { 110, 135, 195 }, + { 57, 113, 168 }, + { 23, 83, 120 }, + { 10, 49, 61 } + }, { /* Coeff Band 2 */ + { 85, 190, 223 }, + { 36, 139, 200 }, + { 5, 90, 146 }, + { 1, 60, 103 }, + { 1, 38, 65 }, + { 1, 18, 30 } + }, { /* Coeff Band 3 */ + { 72, 202, 223 }, + { 23, 141, 199 }, + { 2, 86, 140 }, + { 1, 56, 97 }, + { 1, 36, 61 }, + { 1, 16, 27 } + }, { /* Coeff Band 4 */ + { 55, 218, 225 }, + { 13, 145, 200 }, + { 1, 86, 141 }, + { 1, 57, 99 }, + { 1, 35, 61 }, + { 1, 13, 22 } + }, { /* Coeff Band 5 */ + { 15, 235, 212 }, + { 1, 132, 184 }, + { 1, 84, 139 }, + { 1, 57, 97 }, + { 1, 34, 56 }, + { 1, 14, 23 } + } + } + }, { /* block Type 1 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 181, 21, 201 }, + { 61, 37, 123 }, + { 10, 38, 71 } + }, { /* Coeff Band 1 */ + { 47, 106, 172 }, + { 95, 104, 173 }, + { 42, 93, 159 }, + { 18, 77, 131 }, + { 4, 50, 81 }, + { 1, 17, 23 } + }, { /* Coeff Band 2 */ + { 62, 147, 199 }, + { 44, 130, 189 }, + { 28, 102, 154 }, + { 18, 75, 115 }, + { 2, 44, 65 }, + { 1, 12, 19 } + }, { /* Coeff Band 3 */ + { 55, 153, 210 }, + { 24, 130, 194 }, + { 3, 93, 146 }, + { 1, 61, 97 }, + { 1, 31, 50 }, + { 1, 10, 16 } + }, { /* Coeff Band 4 */ + { 49, 186, 223 }, + { 17, 148, 204 }, + { 1, 96, 142 }, + { 1, 53, 83 }, + { 1, 26, 44 }, + { 1, 11, 17 } + }, { /* Coeff Band 5 */ + { 13, 217, 212 }, + { 2, 136, 180 }, + { 1, 78, 124 }, + { 1, 50, 83 }, + { 1, 29, 49 }, + { 1, 14, 23 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 197, 13, 247 }, + { 82, 17, 222 }, + { 25, 17, 162 } + }, { /* Coeff Band 1 */ + { 126, 186, 247 }, + { 234, 191, 243 }, + { 176, 177, 234 }, + { 104, 158, 220 }, + { 66, 128, 186 }, + { 55, 90, 137 } + }, { /* Coeff Band 2 */ + { 111, 197, 242 }, + { 46, 158, 219 }, + { 9, 104, 171 }, + { 2, 65, 125 }, + { 1, 44, 80 }, + { 1, 17, 91 } + }, { /* Coeff Band 3 */ + { 104, 208, 245 }, + { 39, 168, 224 }, + { 3, 109, 162 }, + { 1, 79, 124 }, + { 1, 50, 102 }, + { 1, 43, 102 } + }, { /* Coeff Band 4 */ + { 84, 220, 246 }, + { 31, 177, 231 }, + { 2, 115, 180 }, + { 1, 79, 134 }, + { 1, 55, 77 }, + { 1, 60, 79 } + }, { /* Coeff Band 5 */ + { 43, 243, 240 }, + { 8, 180, 217 }, + { 1, 115, 166 }, + { 1, 84, 121 }, + { 1, 51, 67 }, + { 1, 16, 6 } + } + } + } + } +}; + +const int8_t ff_vp9_mv_joint_tree[3][2] = { + { -MV_JOINT_ZERO, 1 }, // '0' + { -MV_JOINT_H, 2 }, // '10' + { -MV_JOINT_V, -MV_JOINT_HV }, // '11x' +}; + +const int8_t ff_vp9_mv_class_tree[10][2] = { + { -0, 1 }, // '0' + { -1, 2 }, // '10' + { 3, 4 }, + { -2, -3 }, // '110x' + { 5, 6 }, + { -4, -5 }, // '1110x' + { -6, 7 }, // '11110' + { 8, 9 }, + { -7, -8 }, // '111110x' + { -9, -10 }, // '111111x' +}; + +const int8_t ff_vp9_mv_fp_tree[3][2] = { + { -0, 1 }, // '0' + { -1, 2 }, // '10' + { -2, -3 }, // '11x' +}; diff --git a/libavcodec/vp9data.h b/libavcodec/vp9data.h index cb12e7e94679c..084e8820f8427 100644 --- a/libavcodec/vp9data.h +++ b/libavcodec/vp9data.h @@ -26,2252 +26,45 @@ #include "vp9.h" -static const int8_t vp9_partition_tree[3][2] = { - { -PARTITION_NONE, 1 }, // '0' - { -PARTITION_H, 2 }, // '10' - { -PARTITION_V, -PARTITION_SPLIT }, // '110', '111' -}; - -static const uint8_t vp9_default_kf_partition_probs[4][4][3] = { - { /* 64x64 -> 32x32 */ - { 174, 35, 49 } /* a/l both not split */, - { 68, 11, 27 } /* a split, l not split */, - { 57, 15, 9 } /* l split, a not split */, - { 12, 3, 3 } /* a/l both split */ - }, { /* 32x32 -> 16x16 */ - { 150, 40, 39 } /* a/l both not split */, - { 78, 12, 26 } /* a split, l not split */, - { 67, 33, 11 } /* l split, a not split */, - { 24, 7, 5 } /* a/l both split */, - }, { /* 16x16 -> 8x8 */ - { 149, 53, 53 } /* a/l both not split */, - { 94, 20, 48 } /* a split, l not split */, - { 83, 53, 24 } /* l split, a not split */, - { 52, 18, 18 } /* a/l both split */, - }, { /* 8x8 -> 4x4 */ - { 158, 97, 94 } /* a/l both not split */, - { 93, 24, 99 } /* a split, l not split */, - { 85, 119, 44 } /* l split, a not split */, - { 62, 59, 67 } /* a/l both split */, - }, -}; - -static const int8_t vp9_segmentation_tree[7][2] = { - { 1, 2 }, - { 3, 4 }, - { 5, 6 }, - { -0, -1 }, // '00x' - { -2, -3 }, // '01x' - { -4, -5 }, // '10x' - { -6, -7 }, // '11x' -}; - -static const int8_t vp9_intramode_tree[9][2] = { - { -DC_PRED, 1 }, // '0' - { -TM_VP8_PRED, 2 }, // '10' - { -VERT_PRED, 3 }, // '110' - { 4, 6 }, - { -HOR_PRED, 5 }, // '11100' - { -DIAG_DOWN_RIGHT_PRED, -VERT_RIGHT_PRED }, // '11101x' - { -DIAG_DOWN_LEFT_PRED, 7 }, // '11110' - { -VERT_LEFT_PRED, 8 }, // '111110' - { -HOR_DOWN_PRED, -HOR_UP_PRED }, // '111111x' -}; - -static const uint8_t vp9_default_kf_ymode_probs[10][10][9] = { - { /* above = v */ - { 43, 46, 168, 134, 107, 128, 69, 142, 92 } /* left = v */, - { 44, 29, 68, 159, 201, 177, 50, 57, 77 } /* left = h */, - { 63, 36, 126, 146, 123, 158, 60, 90, 96 } /* left = dc */, - { 58, 38, 76, 114, 97, 172, 78, 133, 92 } /* left = d45 */, - { 46, 41, 76, 140, 63, 184, 69, 112, 57 } /* left = d135 */, - { 38, 32, 85, 140, 46, 112, 54, 151, 133 } /* left = d117 */, - { 39, 27, 61, 131, 110, 175, 44, 75, 136 } /* left = d153 */, - { 47, 35, 80, 100, 74, 143, 64, 163, 74 } /* left = d63 */, - { 52, 30, 74, 113, 130, 175, 51, 64, 58 } /* left = d27 */, - { 36, 61, 116, 114, 128, 162, 80, 125, 82 } /* left = tm */ - }, { /* above = h */ - { 55, 44, 68, 166, 179, 192, 57, 57, 108 } /* left = v */, - { 42, 26, 11, 199, 241, 228, 23, 15, 85 } /* left = h */, - { 82, 26, 26, 171, 208, 204, 44, 32, 105 } /* left = dc */, - { 68, 42, 19, 131, 160, 199, 55, 52, 83 } /* left = d45 */, - { 58, 50, 25, 139, 115, 232, 39, 52, 118 } /* left = d135 */, - { 50, 35, 33, 153, 104, 162, 64, 59, 131 } /* left = d117 */, - { 44, 24, 16, 150, 177, 202, 33, 19, 156 } /* left = d153 */, - { 53, 49, 21, 110, 116, 168, 59, 80, 76 } /* left = d63 */, - { 55, 27, 12, 153, 203, 218, 26, 27, 49 } /* left = d27 */, - { 38, 72, 19, 168, 203, 212, 50, 50, 107 } /* left = tm */ - }, { /* above = dc */ - { 92, 45, 102, 136, 116, 180, 74, 90, 100 } /* left = v */, - { 73, 32, 19, 187, 222, 215, 46, 34, 100 } /* left = h */, - { 137, 30, 42, 148, 151, 207, 70, 52, 91 } /* left = dc */, - { 91, 30, 32, 116, 121, 186, 93, 86, 94 } /* left = d45 */, - { 72, 35, 36, 149, 68, 206, 68, 63, 105 } /* left = d135 */, - { 73, 31, 28, 138, 57, 124, 55, 122, 151 } /* left = d117 */, - { 67, 23, 21, 140, 126, 197, 40, 37, 171 } /* left = d153 */, - { 74, 32, 27, 107, 86, 160, 63, 134, 102 } /* left = d63 */, - { 86, 27, 28, 128, 154, 212, 45, 43, 53 } /* left = d27 */, - { 59, 67, 44, 140, 161, 202, 78, 67, 119 } /* left = tm */ - }, { /* above = d45 */ - { 59, 38, 83, 112, 103, 162, 98, 136, 90 } /* left = v */, - { 62, 30, 23, 158, 200, 207, 59, 57, 50 } /* left = h */, - { 103, 26, 36, 129, 132, 201, 83, 80, 93 } /* left = dc */, - { 67, 30, 29, 84, 86, 191, 102, 91, 59 } /* left = d45 */, - { 60, 32, 33, 112, 71, 220, 64, 89, 104 } /* left = d135 */, - { 53, 26, 34, 130, 56, 149, 84, 120, 103 } /* left = d117 */, - { 53, 21, 23, 133, 109, 210, 56, 77, 172 } /* left = d153 */, - { 61, 29, 29, 93, 97, 165, 83, 175, 162 } /* left = d63 */, - { 77, 19, 29, 112, 142, 228, 55, 66, 36 } /* left = d27 */, - { 47, 47, 43, 114, 137, 181, 100, 99, 95 } /* left = tm */ - }, { /* above = d135 */ - { 53, 40, 55, 139, 69, 183, 61, 80, 110 } /* left = v */, - { 40, 29, 19, 161, 180, 207, 43, 24, 91 } /* left = h */, - { 69, 23, 29, 128, 83, 199, 46, 44, 101 } /* left = dc */, - { 60, 34, 19, 105, 61, 198, 53, 64, 89 } /* left = d45 */, - { 52, 31, 22, 158, 40, 209, 58, 62, 89 } /* left = d135 */, - { 44, 31, 29, 147, 46, 158, 56, 102, 198 } /* left = d117 */, - { 35, 19, 12, 135, 87, 209, 41, 45, 167 } /* left = d153 */, - { 51, 38, 25, 113, 58, 164, 70, 93, 97 } /* left = d63 */, - { 55, 25, 21, 118, 95, 215, 38, 39, 66 } /* left = d27 */, - { 47, 54, 34, 146, 108, 203, 72, 103, 151 } /* left = tm */ - }, { /* above = d117 */ - { 46, 27, 80, 150, 55, 124, 55, 121, 135 } /* left = v */, - { 36, 23, 27, 165, 149, 166, 54, 64, 118 } /* left = h */, - { 64, 19, 37, 156, 66, 138, 49, 95, 133 } /* left = dc */, - { 53, 21, 36, 131, 63, 163, 60, 109, 81 } /* left = d45 */, - { 40, 26, 35, 154, 40, 185, 51, 97, 123 } /* left = d135 */, - { 35, 19, 34, 179, 19, 97, 48, 129, 124 } /* left = d117 */, - { 36, 20, 26, 136, 62, 164, 33, 77, 154 } /* left = d153 */, - { 45, 26, 28, 129, 45, 129, 49, 147, 123 } /* left = d63 */, - { 45, 18, 32, 130, 90, 157, 40, 79, 91 } /* left = d27 */, - { 38, 44, 51, 136, 74, 162, 57, 97, 121 } /* left = tm */ - }, { /* above = d153 */ - { 56, 39, 58, 133, 117, 173, 48, 53, 187 } /* left = v */, - { 35, 21, 12, 161, 212, 207, 20, 23, 145 } /* left = h */, - { 75, 17, 22, 136, 138, 185, 32, 34, 166 } /* left = dc */, - { 56, 29, 19, 117, 109, 181, 55, 68, 112 } /* left = d45 */, - { 47, 29, 17, 153, 64, 220, 59, 51, 114 } /* left = d135 */, - { 46, 16, 24, 136, 76, 147, 41, 64, 172 } /* left = d117 */, - { 34, 17, 11, 108, 152, 187, 13, 15, 209 } /* left = d153 */, - { 55, 30, 18, 122, 79, 179, 44, 88, 116 } /* left = d63 */, - { 51, 24, 14, 115, 133, 209, 32, 26, 104 } /* left = d27 */, - { 37, 49, 25, 129, 168, 164, 41, 54, 148 } /* left = tm */ - }, { /* above = d63 */ - { 48, 34, 86, 101, 92, 146, 78, 179, 134 } /* left = v */, - { 47, 22, 24, 138, 187, 178, 68, 69, 59 } /* left = h */, - { 78, 23, 39, 111, 117, 170, 74, 124, 94 } /* left = dc */, - { 56, 25, 33, 105, 112, 187, 95, 177, 129 } /* left = d45 */, - { 48, 31, 27, 114, 63, 183, 82, 116, 56 } /* left = d135 */, - { 43, 28, 37, 121, 63, 123, 61, 192, 169 } /* left = d117 */, - { 42, 17, 24, 109, 97, 177, 56, 76, 122 } /* left = d153 */, - { 46, 23, 32, 74, 86, 150, 67, 183, 88 } /* left = d63 */, - { 58, 18, 28, 105, 139, 182, 70, 92, 63 } /* left = d27 */, - { 36, 38, 48, 92, 122, 165, 88, 137, 91 } /* left = tm */ - }, { /* above = d27 */ - { 62, 44, 61, 123, 105, 189, 48, 57, 64 } /* left = v */, - { 47, 25, 17, 175, 222, 220, 24, 30, 86 } /* left = h */, - { 82, 22, 32, 127, 143, 213, 39, 41, 70 } /* left = dc */, - { 68, 36, 17, 106, 102, 206, 59, 74, 74 } /* left = d45 */, - { 57, 39, 23, 151, 68, 216, 55, 63, 58 } /* left = d135 */, - { 49, 30, 35, 141, 70, 168, 82, 40, 115 } /* left = d117 */, - { 51, 25, 15, 136, 129, 202, 38, 35, 139 } /* left = d153 */, - { 59, 39, 19, 114, 75, 180, 77, 104, 42 } /* left = d63 */, - { 68, 26, 16, 111, 141, 215, 29, 28, 28 } /* left = d27 */, - { 40, 61, 26, 126, 152, 206, 61, 59, 93 } /* left = tm */ - }, { /* above = tm */ - { 44, 78, 115, 132, 119, 173, 71, 112, 93 } /* left = v */, - { 39, 38, 21, 184, 227, 206, 42, 32, 64 } /* left = h */, - { 65, 70, 60, 155, 159, 199, 61, 60, 81 } /* left = dc */, - { 58, 47, 36, 124, 137, 193, 80, 82, 78 } /* left = d45 */, - { 49, 50, 35, 144, 95, 205, 63, 78, 59 } /* left = d135 */, - { 41, 53, 52, 148, 71, 142, 65, 128, 51 } /* left = d117 */, - { 40, 36, 28, 143, 143, 202, 40, 55, 137 } /* left = d153 */, - { 42, 44, 44, 104, 105, 164, 64, 130, 80 } /* left = d63 */, - { 52, 34, 29, 129, 183, 227, 42, 35, 43 } /* left = d27 */, - { 43, 81, 53, 140, 169, 204, 68, 84, 72 } /* left = tm */ - } -}; - -static const uint8_t vp9_default_kf_uvmode_probs[10][9] = { - { 118, 15, 123, 148, 131, 101, 44, 93, 131 } /* y = v */, - { 113, 12, 23, 188, 226, 142, 26, 32, 125 } /* y = h */, - { 144, 11, 54, 157, 195, 130, 46, 58, 108 } /* y = dc */, - { 120, 11, 50, 123, 163, 135, 64, 77, 103 } /* y = d45 */, - { 113, 9, 36, 155, 111, 157, 32, 44, 161 } /* y = d135 */, - { 116, 9, 55, 176, 76, 96, 37, 61, 149 } /* y = d117 */, - { 115, 9, 28, 141, 161, 167, 21, 25, 193 } /* y = d153 */, - { 116, 12, 64, 120, 140, 125, 49, 115, 121 } /* y = d63 */, - { 120, 12, 32, 145, 195, 142, 32, 38, 86 } /* y = d27 */, - { 102, 19, 66, 162, 182, 122, 35, 59, 128 } /* y = tm */ -}; - -static const int8_t vp9_inter_mode_tree[3][2] = { - { -ZEROMV, 1 }, // '0' - { -NEARESTMV, 2 }, // '10' - { -NEARMV, -NEWMV }, // '11x' -}; - -static const int8_t vp9_filter_tree[2][2] = { - { -0, 1 }, // '0' - { -1, -2 }, // '1x' -}; - -static const enum FilterMode vp9_filter_lut[3] = { - FILTER_8TAP_REGULAR, - FILTER_8TAP_SMOOTH, - FILTER_8TAP_SHARP, -}; - -static const int16_t vp9_dc_qlookup[3][256] = { - { - 4, 8, 8, 9, 10, 11, 12, 12, - 13, 14, 15, 16, 17, 18, 19, 19, - 20, 21, 22, 23, 24, 25, 26, 26, - 27, 28, 29, 30, 31, 32, 32, 33, - 34, 35, 36, 37, 38, 38, 39, 40, - 41, 42, 43, 43, 44, 45, 46, 47, - 48, 48, 49, 50, 51, 52, 53, 53, - 54, 55, 56, 57, 57, 58, 59, 60, - 61, 62, 62, 63, 64, 65, 66, 66, - 67, 68, 69, 70, 70, 71, 72, 73, - 74, 74, 75, 76, 77, 78, 78, 79, - 80, 81, 81, 82, 83, 84, 85, 85, - 87, 88, 90, 92, 93, 95, 96, 98, - 99, 101, 102, 104, 105, 107, 108, 110, - 111, 113, 114, 116, 117, 118, 120, 121, - 123, 125, 127, 129, 131, 134, 136, 138, - 140, 142, 144, 146, 148, 150, 152, 154, - 156, 158, 161, 164, 166, 169, 172, 174, - 177, 180, 182, 185, 187, 190, 192, 195, - 199, 202, 205, 208, 211, 214, 217, 220, - 223, 226, 230, 233, 237, 240, 243, 247, - 250, 253, 257, 261, 265, 269, 272, 276, - 280, 284, 288, 292, 296, 300, 304, 309, - 313, 317, 322, 326, 330, 335, 340, 344, - 349, 354, 359, 364, 369, 374, 379, 384, - 389, 395, 400, 406, 411, 417, 423, 429, - 435, 441, 447, 454, 461, 467, 475, 482, - 489, 497, 505, 513, 522, 530, 539, 549, - 559, 569, 579, 590, 602, 614, 626, 640, - 654, 668, 684, 700, 717, 736, 755, 775, - 796, 819, 843, 869, 896, 925, 955, 988, - 1022, 1058, 1098, 1139, 1184, 1232, 1282, 1336, - }, { - 4, 9, 10, 13, 15, 17, 20, 22, - 25, 28, 31, 34, 37, 40, 43, 47, - 50, 53, 57, 60, 64, 68, 71, 75, - 78, 82, 86, 90, 93, 97, 101, 105, - 109, 113, 116, 120, 124, 128, 132, 136, - 140, 143, 147, 151, 155, 159, 163, 166, - 170, 174, 178, 182, 185, 189, 193, 197, - 200, 204, 208, 212, 215, 219, 223, 226, - 230, 233, 237, 241, 244, 248, 251, 255, - 259, 262, 266, 269, 273, 276, 280, 283, - 287, 290, 293, 297, 300, 304, 307, 310, - 314, 317, 321, 324, 327, 331, 334, 337, - 343, 350, 356, 362, 369, 375, 381, 387, - 394, 400, 406, 412, 418, 424, 430, 436, - 442, 448, 454, 460, 466, 472, 478, 484, - 490, 499, 507, 516, 525, 533, 542, 550, - 559, 567, 576, 584, 592, 601, 609, 617, - 625, 634, 644, 655, 666, 676, 687, 698, - 708, 718, 729, 739, 749, 759, 770, 782, - 795, 807, 819, 831, 844, 856, 868, 880, - 891, 906, 920, 933, 947, 961, 975, 988, - 1001, 1015, 1030, 1045, 1061, 1076, 1090, 1105, - 1120, 1137, 1153, 1170, 1186, 1202, 1218, 1236, - 1253, 1271, 1288, 1306, 1323, 1342, 1361, 1379, - 1398, 1416, 1436, 1456, 1476, 1496, 1516, 1537, - 1559, 1580, 1601, 1624, 1647, 1670, 1692, 1717, - 1741, 1766, 1791, 1817, 1844, 1871, 1900, 1929, - 1958, 1990, 2021, 2054, 2088, 2123, 2159, 2197, - 2236, 2276, 2319, 2363, 2410, 2458, 2508, 2561, - 2616, 2675, 2737, 2802, 2871, 2944, 3020, 3102, - 3188, 3280, 3375, 3478, 3586, 3702, 3823, 3953, - 4089, 4236, 4394, 4559, 4737, 4929, 5130, 5347, - }, { - 4, 12, 18, 25, 33, 41, 50, 60, - 70, 80, 91, 103, 115, 127, 140, 153, - 166, 180, 194, 208, 222, 237, 251, 266, - 281, 296, 312, 327, 343, 358, 374, 390, - 405, 421, 437, 453, 469, 484, 500, 516, - 532, 548, 564, 580, 596, 611, 627, 643, - 659, 674, 690, 706, 721, 737, 752, 768, - 783, 798, 814, 829, 844, 859, 874, 889, - 904, 919, 934, 949, 964, 978, 993, 1008, - 1022, 1037, 1051, 1065, 1080, 1094, 1108, 1122, - 1136, 1151, 1165, 1179, 1192, 1206, 1220, 1234, - 1248, 1261, 1275, 1288, 1302, 1315, 1329, 1342, - 1368, 1393, 1419, 1444, 1469, 1494, 1519, 1544, - 1569, 1594, 1618, 1643, 1668, 1692, 1717, 1741, - 1765, 1789, 1814, 1838, 1862, 1885, 1909, 1933, - 1957, 1992, 2027, 2061, 2096, 2130, 2165, 2199, - 2233, 2267, 2300, 2334, 2367, 2400, 2434, 2467, - 2499, 2532, 2575, 2618, 2661, 2704, 2746, 2788, - 2830, 2872, 2913, 2954, 2995, 3036, 3076, 3127, - 3177, 3226, 3275, 3324, 3373, 3421, 3469, 3517, - 3565, 3621, 3677, 3733, 3788, 3843, 3897, 3951, - 4005, 4058, 4119, 4181, 4241, 4301, 4361, 4420, - 4479, 4546, 4612, 4677, 4742, 4807, 4871, 4942, - 5013, 5083, 5153, 5222, 5291, 5367, 5442, 5517, - 5591, 5665, 5745, 5825, 5905, 5984, 6063, 6149, - 6234, 6319, 6404, 6495, 6587, 6678, 6769, 6867, - 6966, 7064, 7163, 7269, 7376, 7483, 7599, 7715, - 7832, 7958, 8085, 8214, 8352, 8492, 8635, 8788, - 8945, 9104, 9275, 9450, 9639, 9832, 10031, 10245, - 10465, 10702, 10946, 11210, 11482, 11776, 12081, 12409, - 12750, 13118, 13501, 13913, 14343, 14807, 15290, 15812, - 16356, 16943, 17575, 18237, 18949, 19718, 20521, 21387, - } -}; - -static const int16_t vp9_ac_qlookup[3][256] = { - { - 4, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, - 104, 106, 108, 110, 112, 114, 116, 118, - 120, 122, 124, 126, 128, 130, 132, 134, - 136, 138, 140, 142, 144, 146, 148, 150, - 152, 155, 158, 161, 164, 167, 170, 173, - 176, 179, 182, 185, 188, 191, 194, 197, - 200, 203, 207, 211, 215, 219, 223, 227, - 231, 235, 239, 243, 247, 251, 255, 260, - 265, 270, 275, 280, 285, 290, 295, 300, - 305, 311, 317, 323, 329, 335, 341, 347, - 353, 359, 366, 373, 380, 387, 394, 401, - 408, 416, 424, 432, 440, 448, 456, 465, - 474, 483, 492, 501, 510, 520, 530, 540, - 550, 560, 571, 582, 593, 604, 615, 627, - 639, 651, 663, 676, 689, 702, 715, 729, - 743, 757, 771, 786, 801, 816, 832, 848, - 864, 881, 898, 915, 933, 951, 969, 988, - 1007, 1026, 1046, 1066, 1087, 1108, 1129, 1151, - 1173, 1196, 1219, 1243, 1267, 1292, 1317, 1343, - 1369, 1396, 1423, 1451, 1479, 1508, 1537, 1567, - 1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828, - }, { - 4, 9, 11, 13, 16, 18, 21, 24, - 27, 30, 33, 37, 40, 44, 48, 51, - 55, 59, 63, 67, 71, 75, 79, 83, - 88, 92, 96, 100, 105, 109, 114, 118, - 122, 127, 131, 136, 140, 145, 149, 154, - 158, 163, 168, 172, 177, 181, 186, 190, - 195, 199, 204, 208, 213, 217, 222, 226, - 231, 235, 240, 244, 249, 253, 258, 262, - 267, 271, 275, 280, 284, 289, 293, 297, - 302, 306, 311, 315, 319, 324, 328, 332, - 337, 341, 345, 349, 354, 358, 362, 367, - 371, 375, 379, 384, 388, 392, 396, 401, - 409, 417, 425, 433, 441, 449, 458, 466, - 474, 482, 490, 498, 506, 514, 523, 531, - 539, 547, 555, 563, 571, 579, 588, 596, - 604, 616, 628, 640, 652, 664, 676, 688, - 700, 713, 725, 737, 749, 761, 773, 785, - 797, 809, 825, 841, 857, 873, 889, 905, - 922, 938, 954, 970, 986, 1002, 1018, 1038, - 1058, 1078, 1098, 1118, 1138, 1158, 1178, 1198, - 1218, 1242, 1266, 1290, 1314, 1338, 1362, 1386, - 1411, 1435, 1463, 1491, 1519, 1547, 1575, 1603, - 1631, 1663, 1695, 1727, 1759, 1791, 1823, 1859, - 1895, 1931, 1967, 2003, 2039, 2079, 2119, 2159, - 2199, 2239, 2283, 2327, 2371, 2415, 2459, 2507, - 2555, 2603, 2651, 2703, 2755, 2807, 2859, 2915, - 2971, 3027, 3083, 3143, 3203, 3263, 3327, 3391, - 3455, 3523, 3591, 3659, 3731, 3803, 3876, 3952, - 4028, 4104, 4184, 4264, 4348, 4432, 4516, 4604, - 4692, 4784, 4876, 4972, 5068, 5168, 5268, 5372, - 5476, 5584, 5692, 5804, 5916, 6032, 6148, 6268, - 6388, 6512, 6640, 6768, 6900, 7036, 7172, 7312, - }, { - 4, 13, 19, 27, 35, 44, 54, 64, - 75, 87, 99, 112, 126, 139, 154, 168, - 183, 199, 214, 230, 247, 263, 280, 297, - 314, 331, 349, 366, 384, 402, 420, 438, - 456, 475, 493, 511, 530, 548, 567, 586, - 604, 623, 642, 660, 679, 698, 716, 735, - 753, 772, 791, 809, 828, 846, 865, 884, - 902, 920, 939, 957, 976, 994, 1012, 1030, - 1049, 1067, 1085, 1103, 1121, 1139, 1157, 1175, - 1193, 1211, 1229, 1246, 1264, 1282, 1299, 1317, - 1335, 1352, 1370, 1387, 1405, 1422, 1440, 1457, - 1474, 1491, 1509, 1526, 1543, 1560, 1577, 1595, - 1627, 1660, 1693, 1725, 1758, 1791, 1824, 1856, - 1889, 1922, 1954, 1987, 2020, 2052, 2085, 2118, - 2150, 2183, 2216, 2248, 2281, 2313, 2346, 2378, - 2411, 2459, 2508, 2556, 2605, 2653, 2701, 2750, - 2798, 2847, 2895, 2943, 2992, 3040, 3088, 3137, - 3185, 3234, 3298, 3362, 3426, 3491, 3555, 3619, - 3684, 3748, 3812, 3876, 3941, 4005, 4069, 4149, - 4230, 4310, 4390, 4470, 4550, 4631, 4711, 4791, - 4871, 4967, 5064, 5160, 5256, 5352, 5448, 5544, - 5641, 5737, 5849, 5961, 6073, 6185, 6297, 6410, - 6522, 6650, 6778, 6906, 7034, 7162, 7290, 7435, - 7579, 7723, 7867, 8011, 8155, 8315, 8475, 8635, - 8795, 8956, 9132, 9308, 9484, 9660, 9836, 10028, - 10220, 10412, 10604, 10812, 11020, 11228, 11437, 11661, - 11885, 12109, 12333, 12573, 12813, 13053, 13309, 13565, - 13821, 14093, 14365, 14637, 14925, 15213, 15502, 15806, - 16110, 16414, 16734, 17054, 17390, 17726, 18062, 18414, - 18766, 19134, 19502, 19886, 20270, 20670, 21070, 21486, - 21902, 22334, 22766, 23214, 23662, 24126, 24590, 25070, - 25551, 26047, 26559, 27071, 27599, 28143, 28687, 29247, - } -}; - -static const enum TxfmType vp9_intra_txfm_type[14] = { - [VERT_PRED] = ADST_DCT, - [HOR_PRED] = DCT_ADST, - [DC_PRED] = DCT_DCT, - [DIAG_DOWN_LEFT_PRED] = DCT_DCT, - [DIAG_DOWN_RIGHT_PRED] = ADST_ADST, - [VERT_RIGHT_PRED] = ADST_DCT, - [HOR_DOWN_PRED] = DCT_ADST, - [VERT_LEFT_PRED] = ADST_DCT, - [HOR_UP_PRED] = DCT_ADST, - [TM_VP8_PRED] = ADST_ADST, - [NEARESTMV] = DCT_DCT, - [NEARMV] = DCT_DCT, - [ZEROMV] = DCT_DCT, - [NEWMV] = DCT_DCT, -}; - -static const int16_t vp9_default_scan_4x4[16] = { - 0, 1, 4, 5, - 2, 8, 3, 6, - 12, 9, 7, 10, - 13, 11, 14, 15, -}; - -static const int16_t vp9_col_scan_4x4[16] = { - 0, 1, 2, 4, - 3, 5, 6, 8, - 7, 9, 10, 12, - 13, 11, 14, 15, -}; - -static const int16_t vp9_row_scan_4x4[16] = { - 0, 4, 1, 8, - 5, 12, 9, 2, - 6, 13, 3, 10, - 7, 14, 11, 15, -}; - -static const int16_t vp9_default_scan_8x8[64] = { - 0, 1, 8, 2, 9, 16, 10, 3, - 17, 24, 18, 11, 4, 25, 32, 19, - 12, 26, 5, 33, 20, 27, 40, 13, - 34, 6, 41, 28, 21, 35, 42, 48, - 14, 7, 36, 29, 43, 56, 49, 22, - 15, 37, 50, 44, 57, 30, 23, 51, - 45, 58, 38, 31, 52, 59, 39, 46, - 53, 60, 47, 54, 61, 55, 62, 63, -}; - -static const int16_t vp9_col_scan_8x8[64] = { - 0, 1, 2, 8, 3, 9, 4, 10, - 16, 5, 11, 17, 12, 18, 6, 24, - 19, 13, 25, 7, 26, 20, 32, 14, - 27, 21, 33, 28, 34, 15, 22, 35, - 40, 29, 41, 36, 23, 30, 42, 37, - 48, 43, 31, 44, 49, 38, 50, 56, - 45, 39, 51, 57, 52, 46, 58, 53, - 59, 47, 60, 54, 61, 55, 62, 63, -}; - -static const int16_t vp9_row_scan_8x8[64] = { - 0, 8, 16, 1, 9, 24, 2, 17, - 32, 10, 25, 3, 40, 18, 11, 33, - 26, 19, 4, 48, 41, 34, 12, 27, - 56, 20, 5, 42, 35, 13, 49, 28, - 6, 21, 43, 36, 14, 50, 29, 57, - 7, 44, 22, 37, 51, 15, 58, 30, - 23, 45, 52, 38, 59, 31, 46, 53, - 39, 60, 47, 61, 54, 62, 55, 63, -}; - -static const int16_t vp9_default_scan_16x16[256] = { - 0, 1, 16, 2, 17, 32, 3, 18, 33, 48, 4, 34, 19, 49, 20, 5, - 35, 64, 50, 36, 65, 21, 6, 51, 80, 66, 37, 22, 52, 7, 81, 67, - 38, 82, 53, 23, 96, 68, 8, 83, 97, 54, 39, 69, 112, 24, 98, 84, - 70, 55, 9, 40, 85, 99, 113, 128, 25, 114, 100, 71, 86, 56, 10, 41, - 115, 101, 129, 116, 72, 87, 26, 130, 144, 102, 57, 11, 42, 117, 131, 145, - 88, 103, 27, 73, 132, 118, 146, 58, 160, 12, 43, 133, 147, 104, 89, 119, - 161, 74, 148, 134, 28, 162, 59, 13, 176, 120, 149, 90, 135, 105, 163, 44, - 75, 177, 164, 29, 150, 121, 136, 178, 165, 14, 106, 60, 91, 151, 45, 179, - 192, 137, 166, 122, 76, 180, 152, 30, 61, 15, 107, 167, 181, 193, 92, 208, - 46, 138, 123, 153, 194, 77, 168, 182, 31, 195, 209, 183, 108, 139, 62, 154, - 47, 196, 93, 169, 210, 197, 224, 124, 184, 211, 78, 109, 170, 155, 63, 198, - 212, 185, 225, 240, 140, 94, 199, 125, 79, 213, 226, 171, 186, 156, 214, 200, - 110, 227, 141, 95, 241, 215, 228, 201, 126, 242, 187, 172, 157, 229, 111, 216, - 243, 142, 202, 230, 127, 217, 244, 173, 188, 231, 158, 203, 143, 245, 218, 232, - 189, 246, 159, 174, 233, 247, 219, 204, 175, 190, 248, 234, 205, 220, 249, 191, - 235, 221, 250, 206, 222, 251, 236, 207, 237, 223, 252, 238, 253, 239, 254, 255, -}; - -static const int16_t vp9_col_scan_16x16[256] = { - 0, 1, 2, 3, 16, 4, 17, 5, 18, 6, 19, 32, 20, 7, 33, 21, - 34, 8, 35, 22, 48, 36, 9, 49, 23, 50, 37, 10, 38, 51, 24, 64, - 52, 11, 65, 39, 25, 53, 66, 54, 40, 67, 12, 80, 26, 68, 55, 81, - 41, 69, 13, 27, 82, 56, 70, 83, 42, 14, 84, 96, 71, 28, 57, 85, - 97, 15, 72, 98, 43, 86, 58, 99, 29, 87, 100, 112, 73, 44, 101, 59, - 30, 113, 88, 114, 74, 128, 102, 45, 31, 115, 60, 103, 89, 116, 75, 129, - 117, 46, 104, 90, 61, 130, 118, 131, 132, 105, 76, 47, 119, 144, 91, 62, - 133, 106, 145, 120, 146, 134, 77, 147, 121, 92, 135, 148, 63, 107, 136, 122, - 93, 149, 160, 78, 150, 137, 108, 161, 162, 151, 123, 79, 138, 163, 152, 94, - 164, 109, 165, 153, 124, 139, 176, 166, 95, 177, 167, 110, 154, 178, 125, 179, - 140, 168, 155, 111, 180, 192, 181, 169, 141, 126, 182, 193, 194, 156, 183, 170, - 195, 127, 142, 196, 184, 208, 197, 157, 171, 143, 185, 198, 209, 199, 210, 172, - 158, 186, 211, 224, 212, 200, 240, 159, 213, 225, 187, 201, 173, 226, 214, 215, - 227, 202, 228, 188, 241, 216, 174, 229, 242, 203, 243, 217, 230, 175, 189, 244, - 231, 204, 218, 232, 245, 219, 246, 190, 233, 205, 191, 247, 234, 248, 220, 206, - 249, 235, 221, 207, 250, 236, 222, 251, 223, 237, 238, 252, 239, 253, 254, 255, -}; - -static const int16_t vp9_row_scan_16x16[256] = { - 0, 16, 32, 1, 48, 17, 64, 33, 2, 80, 18, 49, 96, 34, 3, 65, - 19, 112, 50, 81, 35, 4, 128, 66, 20, 97, 51, 82, 5, 144, 36, 67, - 113, 98, 21, 52, 160, 83, 129, 37, 68, 6, 114, 176, 99, 53, 22, 84, - 145, 38, 69, 130, 7, 115, 192, 100, 54, 23, 85, 161, 146, 131, 39, 70, - 208, 116, 8, 101, 177, 55, 86, 24, 162, 147, 132, 71, 224, 117, 40, 102, - 9, 148, 56, 87, 193, 163, 240, 133, 178, 25, 118, 72, 41, 103, 164, 10, - 149, 88, 134, 209, 179, 57, 119, 194, 26, 73, 165, 150, 104, 42, 135, 11, - 180, 120, 89, 225, 195, 58, 27, 210, 151, 181, 166, 74, 43, 105, 12, 136, - 90, 59, 241, 121, 28, 196, 167, 211, 152, 44, 182, 137, 75, 13, 226, 106, - 122, 60, 197, 91, 168, 29, 183, 153, 14, 76, 212, 138, 45, 107, 15, 198, - 92, 227, 169, 30, 123, 154, 61, 242, 184, 213, 139, 46, 77, 31, 108, 170, - 199, 185, 124, 228, 93, 155, 214, 62, 140, 243, 78, 47, 200, 109, 186, 171, - 201, 94, 63, 215, 229, 156, 79, 125, 141, 110, 216, 187, 172, 244, 202, 230, - 217, 95, 157, 126, 245, 111, 142, 231, 188, 127, 158, 218, 173, 232, 246, 233, - 203, 143, 247, 174, 189, 159, 219, 204, 248, 234, 249, 175, 190, 220, 205, 250, - 235, 191, 221, 251, 236, 206, 252, 222, 207, 237, 223, 253, 238, 254, 239, 255, -}; - -static const int16_t vp9_default_scan_32x32[1024] = { - 0, 1, 32, 2, 33, 64, 3, 34, 65, 4, 96, 35, 66, 5, 36, 97, 67, 128, 98, 68, 37, 6, 129, 99, 7, 160, 69, 38, 130, 100, 161, 131, - 39, 70, 8, 101, 162, 132, 192, 71, 40, 9, 102, 163, 133, 193, 72, 224, 103, 41, 164, 10, 194, 134, 165, 73, 104, 135, 225, 42, 195, 11, 256, 166, - 226, 196, 74, 105, 136, 43, 12, 167, 197, 227, 257, 75, 106, 137, 228, 44, 198, 168, 258, 288, 13, 229, 76, 107, 199, 138, 259, 169, 289, 45, 230, 260, - 200, 108, 14, 170, 139, 320, 290, 77, 231, 261, 46, 201, 140, 291, 109, 232, 321, 262, 171, 78, 292, 15, 322, 202, 263, 352, 172, 293, 233, 141, 323, 110, - 47, 203, 264, 234, 294, 353, 324, 16, 79, 204, 265, 295, 325, 173, 354, 142, 235, 384, 48, 296, 111, 266, 355, 326, 80, 17, 205, 236, 174, 356, 385, 327, - 143, 297, 267, 357, 386, 112, 49, 328, 298, 206, 416, 237, 358, 387, 81, 175, 18, 329, 359, 388, 299, 330, 389, 113, 417, 238, 360, 50, 207, 418, 390, 331, - 19, 448, 361, 82, 419, 391, 239, 51, 362, 420, 114, 449, 480, 421, 83, 363, 450, 422, 512, 451, 423, 115, 452, 481, 453, 482, 454, 544, 483, 455, 513, 484, - 514, 485, 515, 486, 545, 576, 487, 546, 547, 608, 577, 578, 579, 609, 610, 611, 20, 144, 268, 392, 516, 640, 21, 52, 145, 176, 269, 300, 393, 424, 517, 548, - 641, 672, 22, 53, 84, 146, 177, 208, 270, 301, 332, 394, 425, 456, 518, 549, 580, 642, 673, 704, 23, 54, 85, 116, 147, 178, 209, 240, 271, 302, 333, 364, - 395, 426, 457, 488, 519, 550, 581, 612, 643, 674, 705, 736, 55, 86, 117, 179, 210, 241, 303, 334, 365, 427, 458, 489, 551, 582, 613, 675, 706, 737, 87, 118, - 211, 242, 335, 366, 459, 490, 583, 614, 707, 738, 119, 243, 367, 491, 615, 739, 24, 148, 272, 396, 520, 644, 768, 25, 56, 149, 180, 273, 304, 397, 428, 521, - 552, 645, 676, 769, 800, 26, 57, 88, 150, 181, 212, 274, 305, 336, 398, 429, 460, 522, 553, 584, 646, 677, 708, 770, 801, 832, 27, 58, 89, 120, 151, 182, - 213, 244, 275, 306, 337, 368, 399, 430, 461, 492, 523, 554, 585, 616, 647, 678, 709, 740, 771, 802, 833, 864, 59, 90, 121, 183, 214, 245, 307, 338, 369, 431, - 462, 493, 555, 586, 617, 679, 710, 741, 803, 834, 865, 91, 122, 215, 246, 339, 370, 463, 494, 587, 618, 711, 742, 835, 866, 123, 247, 371, 495, 619, 743, 867, - 28, 152, 276, 400, 524, 648, 772, 896, 29, 60, 153, 184, 277, 308, 401, 432, 525, 556, 649, 680, 773, 804, 897, 928, 30, 61, 92, 154, 185, 216, 278, 309, - 340, 402, 433, 464, 526, 557, 588, 650, 681, 712, 774, 805, 836, 898, 929, 960, 31, 62, 93, 124, 155, 186, 217, 248, 279, 310, 341, 372, 403, 434, 465, 496, - 527, 558, 589, 620, 651, 682, 713, 744, 775, 806, 837, 868, 899, 930, 961, 992, 63, 94, 125, 187, 218, 249, 311, 342, 373, 435, 466, 497, 559, 590, 621, 683, - 714, 745, 807, 838, 869, 931, 962, 993, 95, 126, 219, 250, 343, 374, 467, 498, 591, 622, 715, 746, 839, 870, 963, 994, 127, 251, 375, 499, 623, 747, 871, 995, - 156, 280, 404, 528, 652, 776, 900, 157, 188, 281, 312, 405, 436, 529, 560, 653, 684, 777, 808, 901, 932, 158, 189, 220, 282, 313, 344, 406, 437, 468, 530, 561, - 592, 654, 685, 716, 778, 809, 840, 902, 933, 964, 159, 190, 221, 252, 283, 314, 345, 376, 407, 438, 469, 500, 531, 562, 593, 624, 655, 686, 717, 748, 779, 810, - 841, 872, 903, 934, 965, 996, 191, 222, 253, 315, 346, 377, 439, 470, 501, 563, 594, 625, 687, 718, 749, 811, 842, 873, 935, 966, 997, 223, 254, 347, 378, 471, - 502, 595, 626, 719, 750, 843, 874, 967, 998, 255, 379, 503, 627, 751, 875, 999, 284, 408, 532, 656, 780, 904, 285, 316, 409, 440, 533, 564, 657, 688, 781, 812, - 905, 936, 286, 317, 348, 410, 441, 472, 534, 565, 596, 658, 689, 720, 782, 813, 844, 906, 937, 968, 287, 318, 349, 380, 411, 442, 473, 504, 535, 566, 597, 628, - 659, 690, 721, 752, 783, 814, 845, 876, 907, 938, 969, 1000, 319, 350, 381, 443, 474, 505, 567, 598, 629, 691, 722, 753, 815, 846, 877, 939, 970, 1001, 351, 382, - 475, 506, 599, 630, 723, 754, 847, 878, 971, 1002, 383, 507, 631, 755, 879, 1003, 412, 536, 660, 784, 908, 413, 444, 537, 568, 661, 692, 785, 816, 909, 940, 414, - 445, 476, 538, 569, 600, 662, 693, 724, 786, 817, 848, 910, 941, 972, 415, 446, 477, 508, 539, 570, 601, 632, 663, 694, 725, 756, 787, 818, 849, 880, 911, 942, - 973, 1004, 447, 478, 509, 571, 602, 633, 695, 726, 757, 819, 850, 881, 943, 974, 1005, 479, 510, 603, 634, 727, 758, 851, 882, 975, 1006, 511, 635, 759, 883, 1007, - 540, 664, 788, 912, 541, 572, 665, 696, 789, 820, 913, 944, 542, 573, 604, 666, 697, 728, 790, 821, 852, 914, 945, 976, 543, 574, 605, 636, 667, 698, 729, 760, - 791, 822, 853, 884, 915, 946, 977, 1008, 575, 606, 637, 699, 730, 761, 823, 854, 885, 947, 978, 1009, 607, 638, 731, 762, 855, 886, 979, 1010, 639, 763, 887, 1011, - 668, 792, 916, 669, 700, 793, 824, 917, 948, 670, 701, 732, 794, 825, 856, 918, 949, 980, 671, 702, 733, 764, 795, 826, 857, 888, 919, 950, 981, 1012, 703, 734, - 765, 827, 858, 889, 951, 982, 1013, 735, 766, 859, 890, 983, 1014, 767, 891, 1015, 796, 920, 797, 828, 921, 952, 798, 829, 860, 922, 953, 984, 799, 830, 861, 892, - 923, 954, 985, 1016, 831, 862, 893, 955, 986, 1017, 863, 894, 987, 1018, 895, 1019, 924, 925, 956, 926, 957, 988, 927, 958, 989, 1020, 959, 990, 1021, 991, 1022, 1023, -}; - -static const int16_t * const vp9_scans[5][4] = { - { - vp9_default_scan_4x4, vp9_col_scan_4x4, - vp9_row_scan_4x4, vp9_default_scan_4x4 - }, { - vp9_default_scan_8x8, vp9_col_scan_8x8, - vp9_row_scan_8x8, vp9_default_scan_8x8 - }, { - vp9_default_scan_16x16, vp9_col_scan_16x16, - vp9_row_scan_16x16, vp9_default_scan_16x16 - }, { - vp9_default_scan_32x32, vp9_default_scan_32x32, - vp9_default_scan_32x32, vp9_default_scan_32x32 - }, { // lossless - vp9_default_scan_4x4, vp9_default_scan_4x4, - vp9_default_scan_4x4, vp9_default_scan_4x4 - } -}; - -static const int16_t vp9_default_scan_4x4_nb[16][2] = { - { 0, 0 }, { 0, 0 }, { 4, 1 }, { 1, 1 }, - { 4, 4 }, { 2, 2 }, { 5, 2 }, { 8, 8 }, - { 8, 5 }, { 6, 3 }, { 9, 6 }, { 12, 9 }, - { 10, 7 }, { 13, 10 }, { 14, 11 }, { 0, 0 }, -}; - -static const int16_t vp9_col_scan_4x4_nb[16][2] = { - { 0, 0 }, { 1, 1 }, { 0, 0 }, { 2, 2 }, - { 4, 4 }, { 5, 5 }, { 4, 4 }, { 6, 6 }, - { 8, 8 }, { 9, 9 }, { 8, 8 }, { 12, 12 }, - { 10, 10 }, { 13, 13 }, { 14, 14 }, { 0, 0 }, -}; - -static const int16_t vp9_row_scan_4x4_nb[16][2] = { - { 0, 0 }, { 0, 0 }, { 4, 4 }, { 1, 1 }, - { 8, 8 }, { 5, 5 }, { 1, 1 }, { 2, 2 }, - { 9, 9 }, { 2, 2 }, { 6, 6 }, { 3, 3 }, - { 10, 10 }, { 7, 7 }, { 11, 11 }, { 0, 0 }, -}; - -static const int16_t vp9_default_scan_8x8_nb[64][2] = { - { 0, 0 }, { 0, 0 }, { 1, 1 }, { 8, 1 }, - { 8, 8 }, { 9, 2 }, { 2, 2 }, { 16, 9 }, - { 16, 16 }, { 17, 10 }, { 10, 3 }, { 3, 3 }, - { 24, 17 }, { 24, 24 }, { 18, 11 }, { 11, 4 }, - { 25, 18 }, { 4, 4 }, { 32, 25 }, { 19, 12 }, - { 26, 19 }, { 32, 32 }, { 12, 5 }, { 33, 26 }, - { 5, 5 }, { 40, 33 }, { 27, 20 }, { 20, 13 }, - { 34, 27 }, { 41, 34 }, { 40, 40 }, { 13, 6 }, - { 6, 6 }, { 35, 28 }, { 28, 21 }, { 42, 35 }, - { 48, 48 }, { 48, 41 }, { 21, 14 }, { 14, 7 }, - { 36, 29 }, { 49, 42 }, { 43, 36 }, { 56, 49 }, - { 29, 22 }, { 22, 15 }, { 50, 43 }, { 44, 37 }, - { 57, 50 }, { 37, 30 }, { 30, 23 }, { 51, 44 }, - { 58, 51 }, { 38, 31 }, { 45, 38 }, { 52, 45 }, - { 59, 52 }, { 46, 39 }, { 53, 46 }, { 60, 53 }, - { 54, 47 }, { 61, 54 }, { 62, 55 }, { 0, 0 }, -}; - -static const int16_t vp9_col_scan_8x8_nb[64][2] = { - { 0, 0 }, { 1, 1 }, { 0, 0 }, { 2, 2 }, - { 8, 8 }, { 3, 3 }, { 9, 9 }, { 8, 8 }, - { 4, 4 }, { 10, 10 }, { 16, 16 }, { 11, 11 }, - { 17, 17 }, { 5, 5 }, { 16, 16 }, { 18, 18 }, - { 12, 12 }, { 24, 24 }, { 6, 6 }, { 25, 25 }, - { 19, 19 }, { 24, 24 }, { 13, 13 }, { 26, 26 }, - { 20, 20 }, { 32, 32 }, { 27, 27 }, { 33, 33 }, - { 14, 14 }, { 21, 21 }, { 34, 34 }, { 32, 32 }, - { 28, 28 }, { 40, 40 }, { 35, 35 }, { 22, 22 }, - { 29, 29 }, { 41, 41 }, { 36, 36 }, { 40, 40 }, - { 42, 42 }, { 30, 30 }, { 43, 43 }, { 48, 48 }, - { 37, 37 }, { 49, 49 }, { 48, 48 }, { 44, 44 }, - { 38, 38 }, { 50, 50 }, { 56, 56 }, { 51, 51 }, - { 45, 45 }, { 57, 57 }, { 52, 52 }, { 58, 58 }, - { 46, 46 }, { 59, 59 }, { 53, 53 }, { 60, 60 }, - { 54, 54 }, { 61, 61 }, { 62, 62 }, { 0, 0 }, -}; - -static const int16_t vp9_row_scan_8x8_nb[64][2] = { - { 0, 0 }, { 8, 8 }, { 0, 0 }, { 1, 1 }, - { 16, 16 }, { 1, 1 }, { 9, 9 }, { 24, 24 }, - { 2, 2 }, { 17, 17 }, { 2, 2 }, { 32, 32 }, - { 10, 10 }, { 3, 3 }, { 25, 25 }, { 18, 18 }, - { 11, 11 }, { 3, 3 }, { 40, 40 }, { 33, 33 }, - { 26, 26 }, { 4, 4 }, { 19, 19 }, { 48, 48 }, - { 12, 12 }, { 4, 4 }, { 34, 34 }, { 27, 27 }, - { 5, 5 }, { 41, 41 }, { 20, 20 }, { 5, 5 }, - { 13, 13 }, { 35, 35 }, { 28, 28 }, { 6, 6 }, - { 42, 42 }, { 21, 21 }, { 49, 49 }, { 6, 6 }, - { 36, 36 }, { 14, 14 }, { 29, 29 }, { 43, 43 }, - { 7, 7 }, { 50, 50 }, { 22, 22 }, { 15, 15 }, - { 37, 37 }, { 44, 44 }, { 30, 30 }, { 51, 51 }, - { 23, 23 }, { 38, 38 }, { 45, 45 }, { 31, 31 }, - { 52, 52 }, { 39, 39 }, { 53, 53 }, { 46, 46 }, - { 54, 54 }, { 47, 47 }, { 55, 55 }, { 0, 0 }, -}; - -static const int16_t vp9_default_scan_16x16_nb[256][2] = { - { 0, 0 }, { 0, 0 }, { 1, 1 }, { 16, 1 }, - { 16, 16 }, { 2, 2 }, { 17, 2 }, { 32, 17 }, - { 32, 32 }, { 3, 3 }, { 33, 18 }, { 18, 3 }, - { 48, 33 }, { 19, 4 }, { 4, 4 }, { 34, 19 }, - { 48, 48 }, { 49, 34 }, { 35, 20 }, { 64, 49 }, - { 20, 5 }, { 5, 5 }, { 50, 35 }, { 64, 64 }, - { 65, 50 }, { 36, 21 }, { 21, 6 }, { 51, 36 }, - { 6, 6 }, { 80, 65 }, { 66, 51 }, { 37, 22 }, - { 81, 66 }, { 52, 37 }, { 22, 7 }, { 80, 80 }, - { 67, 52 }, { 7, 7 }, { 82, 67 }, { 96, 81 }, - { 53, 38 }, { 38, 23 }, { 68, 53 }, { 96, 96 }, - { 23, 8 }, { 97, 82 }, { 83, 68 }, { 69, 54 }, - { 54, 39 }, { 8, 8 }, { 39, 24 }, { 84, 69 }, - { 98, 83 }, { 112, 97 }, { 112, 112 }, { 24, 9 }, - { 113, 98 }, { 99, 84 }, { 70, 55 }, { 85, 70 }, - { 55, 40 }, { 9, 9 }, { 40, 25 }, { 114, 99 }, - { 100, 85 }, { 128, 113 }, { 115, 100 }, { 71, 56 }, - { 86, 71 }, { 25, 10 }, { 129, 114 }, { 128, 128 }, - { 101, 86 }, { 56, 41 }, { 10, 10 }, { 41, 26 }, - { 116, 101 }, { 130, 115 }, { 144, 129 }, { 87, 72 }, - { 102, 87 }, { 26, 11 }, { 72, 57 }, { 131, 116 }, - { 117, 102 }, { 145, 130 }, { 57, 42 }, { 144, 144 }, - { 11, 11 }, { 42, 27 }, { 132, 117 }, { 146, 131 }, - { 103, 88 }, { 88, 73 }, { 118, 103 }, { 160, 145 }, - { 73, 58 }, { 147, 132 }, { 133, 118 }, { 27, 12 }, - { 161, 146 }, { 58, 43 }, { 12, 12 }, { 160, 160 }, - { 119, 104 }, { 148, 133 }, { 89, 74 }, { 134, 119 }, - { 104, 89 }, { 162, 147 }, { 43, 28 }, { 74, 59 }, - { 176, 161 }, { 163, 148 }, { 28, 13 }, { 149, 134 }, - { 120, 105 }, { 135, 120 }, { 177, 162 }, { 164, 149 }, - { 13, 13 }, { 105, 90 }, { 59, 44 }, { 90, 75 }, - { 150, 135 }, { 44, 29 }, { 178, 163 }, { 176, 176 }, - { 136, 121 }, { 165, 150 }, { 121, 106 }, { 75, 60 }, - { 179, 164 }, { 151, 136 }, { 29, 14 }, { 60, 45 }, - { 14, 14 }, { 106, 91 }, { 166, 151 }, { 180, 165 }, - { 192, 177 }, { 91, 76 }, { 192, 192 }, { 45, 30 }, - { 137, 122 }, { 122, 107 }, { 152, 137 }, { 193, 178 }, - { 76, 61 }, { 167, 152 }, { 181, 166 }, { 30, 15 }, - { 194, 179 }, { 208, 193 }, { 182, 167 }, { 107, 92 }, - { 138, 123 }, { 61, 46 }, { 153, 138 }, { 46, 31 }, - { 195, 180 }, { 92, 77 }, { 168, 153 }, { 209, 194 }, - { 196, 181 }, { 208, 208 }, { 123, 108 }, { 183, 168 }, - { 210, 195 }, { 77, 62 }, { 108, 93 }, { 169, 154 }, - { 154, 139 }, { 62, 47 }, { 197, 182 }, { 211, 196 }, - { 184, 169 }, { 224, 209 }, { 224, 224 }, { 139, 124 }, - { 93, 78 }, { 198, 183 }, { 124, 109 }, { 78, 63 }, - { 212, 197 }, { 225, 210 }, { 170, 155 }, { 185, 170 }, - { 155, 140 }, { 213, 198 }, { 199, 184 }, { 109, 94 }, - { 226, 211 }, { 140, 125 }, { 94, 79 }, { 240, 225 }, - { 214, 199 }, { 227, 212 }, { 200, 185 }, { 125, 110 }, - { 241, 226 }, { 186, 171 }, { 171, 156 }, { 156, 141 }, - { 228, 213 }, { 110, 95 }, { 215, 200 }, { 242, 227 }, - { 141, 126 }, { 201, 186 }, { 229, 214 }, { 126, 111 }, - { 216, 201 }, { 243, 228 }, { 172, 157 }, { 187, 172 }, - { 230, 215 }, { 157, 142 }, { 202, 187 }, { 142, 127 }, - { 244, 229 }, { 217, 202 }, { 231, 216 }, { 188, 173 }, - { 245, 230 }, { 158, 143 }, { 173, 158 }, { 232, 217 }, - { 246, 231 }, { 218, 203 }, { 203, 188 }, { 174, 159 }, - { 189, 174 }, { 247, 232 }, { 233, 218 }, { 204, 189 }, - { 219, 204 }, { 248, 233 }, { 190, 175 }, { 234, 219 }, - { 220, 205 }, { 249, 234 }, { 205, 190 }, { 221, 206 }, - { 250, 235 }, { 235, 220 }, { 206, 191 }, { 236, 221 }, - { 222, 207 }, { 251, 236 }, { 237, 222 }, { 252, 237 }, - { 238, 223 }, { 253, 238 }, { 254, 239 }, { 0, 0 }, -}; - -static const int16_t vp9_col_scan_16x16_nb[256][2] = { - { 0, 0 }, { 1, 1 }, { 2, 2 }, { 0, 0 }, - { 3, 3 }, { 16, 16 }, { 4, 4 }, { 17, 17 }, - { 5, 5 }, { 18, 18 }, { 16, 16 }, { 19, 19 }, - { 6, 6 }, { 32, 32 }, { 20, 20 }, { 33, 33 }, - { 7, 7 }, { 34, 34 }, { 21, 21 }, { 32, 32 }, - { 35, 35 }, { 8, 8 }, { 48, 48 }, { 22, 22 }, - { 49, 49 }, { 36, 36 }, { 9, 9 }, { 37, 37 }, - { 50, 50 }, { 23, 23 }, { 48, 48 }, { 51, 51 }, - { 10, 10 }, { 64, 64 }, { 38, 38 }, { 24, 24 }, - { 52, 52 }, { 65, 65 }, { 53, 53 }, { 39, 39 }, - { 66, 66 }, { 11, 11 }, { 64, 64 }, { 25, 25 }, - { 67, 67 }, { 54, 54 }, { 80, 80 }, { 40, 40 }, - { 68, 68 }, { 12, 12 }, { 26, 26 }, { 81, 81 }, - { 55, 55 }, { 69, 69 }, { 82, 82 }, { 41, 41 }, - { 13, 13 }, { 83, 83 }, { 80, 80 }, { 70, 70 }, - { 27, 27 }, { 56, 56 }, { 84, 84 }, { 96, 96 }, - { 14, 14 }, { 71, 71 }, { 97, 97 }, { 42, 42 }, - { 85, 85 }, { 57, 57 }, { 98, 98 }, { 28, 28 }, - { 86, 86 }, { 99, 99 }, { 96, 96 }, { 72, 72 }, - { 43, 43 }, { 100, 100 }, { 58, 58 }, { 29, 29 }, - { 112, 112 }, { 87, 87 }, { 113, 113 }, { 73, 73 }, - { 112, 112 }, { 101, 101 }, { 44, 44 }, { 30, 30 }, - { 114, 114 }, { 59, 59 }, { 102, 102 }, { 88, 88 }, - { 115, 115 }, { 74, 74 }, { 128, 128 }, { 116, 116 }, - { 45, 45 }, { 103, 103 }, { 89, 89 }, { 60, 60 }, - { 129, 129 }, { 117, 117 }, { 130, 130 }, { 131, 131 }, - { 104, 104 }, { 75, 75 }, { 46, 46 }, { 118, 118 }, - { 128, 128 }, { 90, 90 }, { 61, 61 }, { 132, 132 }, - { 105, 105 }, { 144, 144 }, { 119, 119 }, { 145, 145 }, - { 133, 133 }, { 76, 76 }, { 146, 146 }, { 120, 120 }, - { 91, 91 }, { 134, 134 }, { 147, 147 }, { 62, 62 }, - { 106, 106 }, { 135, 135 }, { 121, 121 }, { 92, 92 }, - { 148, 148 }, { 144, 144 }, { 77, 77 }, { 149, 149 }, - { 136, 136 }, { 107, 107 }, { 160, 160 }, { 161, 161 }, - { 150, 150 }, { 122, 122 }, { 78, 78 }, { 137, 137 }, - { 162, 162 }, { 151, 151 }, { 93, 93 }, { 163, 163 }, - { 108, 108 }, { 164, 164 }, { 152, 152 }, { 123, 123 }, - { 138, 138 }, { 160, 160 }, { 165, 165 }, { 94, 94 }, - { 176, 176 }, { 166, 166 }, { 109, 109 }, { 153, 153 }, - { 177, 177 }, { 124, 124 }, { 178, 178 }, { 139, 139 }, - { 167, 167 }, { 154, 154 }, { 110, 110 }, { 179, 179 }, - { 176, 176 }, { 180, 180 }, { 168, 168 }, { 140, 140 }, - { 125, 125 }, { 181, 181 }, { 192, 192 }, { 193, 193 }, - { 155, 155 }, { 182, 182 }, { 169, 169 }, { 194, 194 }, - { 126, 126 }, { 141, 141 }, { 195, 195 }, { 183, 183 }, - { 192, 192 }, { 196, 196 }, { 156, 156 }, { 170, 170 }, - { 142, 142 }, { 184, 184 }, { 197, 197 }, { 208, 208 }, - { 198, 198 }, { 209, 209 }, { 171, 171 }, { 157, 157 }, - { 185, 185 }, { 210, 210 }, { 208, 208 }, { 211, 211 }, - { 199, 199 }, { 224, 224 }, { 158, 158 }, { 212, 212 }, - { 224, 224 }, { 186, 186 }, { 200, 200 }, { 172, 172 }, - { 225, 225 }, { 213, 213 }, { 214, 214 }, { 226, 226 }, - { 201, 201 }, { 227, 227 }, { 187, 187 }, { 240, 240 }, - { 215, 215 }, { 173, 173 }, { 228, 228 }, { 241, 241 }, - { 202, 202 }, { 242, 242 }, { 216, 216 }, { 229, 229 }, - { 174, 174 }, { 188, 188 }, { 243, 243 }, { 230, 230 }, - { 203, 203 }, { 217, 217 }, { 231, 231 }, { 244, 244 }, - { 218, 218 }, { 245, 245 }, { 189, 189 }, { 232, 232 }, - { 204, 204 }, { 190, 190 }, { 246, 246 }, { 233, 233 }, - { 247, 247 }, { 219, 219 }, { 205, 205 }, { 248, 248 }, - { 234, 234 }, { 220, 220 }, { 206, 206 }, { 249, 249 }, - { 235, 235 }, { 221, 221 }, { 250, 250 }, { 222, 222 }, - { 236, 236 }, { 237, 237 }, { 251, 251 }, { 238, 238 }, - { 252, 252 }, { 253, 253 }, { 254, 254 }, { 0, 0 }, -}; - -static const int16_t vp9_row_scan_16x16_nb[256][2] = { - { 0, 0 }, { 16, 16 }, { 0, 0 }, { 32, 32 }, - { 1, 1 }, { 48, 48 }, { 17, 17 }, { 1, 1 }, - { 64, 64 }, { 2, 2 }, { 33, 33 }, { 80, 80 }, - { 18, 18 }, { 2, 2 }, { 49, 49 }, { 3, 3 }, - { 96, 96 }, { 34, 34 }, { 65, 65 }, { 19, 19 }, - { 3, 3 }, { 112, 112 }, { 50, 50 }, { 4, 4 }, - { 81, 81 }, { 35, 35 }, { 66, 66 }, { 4, 4 }, - { 128, 128 }, { 20, 20 }, { 51, 51 }, { 97, 97 }, - { 82, 82 }, { 5, 5 }, { 36, 36 }, { 144, 144 }, - { 67, 67 }, { 113, 113 }, { 21, 21 }, { 52, 52 }, - { 5, 5 }, { 98, 98 }, { 160, 160 }, { 83, 83 }, - { 37, 37 }, { 6, 6 }, { 68, 68 }, { 129, 129 }, - { 22, 22 }, { 53, 53 }, { 114, 114 }, { 6, 6 }, - { 99, 99 }, { 176, 176 }, { 84, 84 }, { 38, 38 }, - { 7, 7 }, { 69, 69 }, { 145, 145 }, { 130, 130 }, - { 115, 115 }, { 23, 23 }, { 54, 54 }, { 192, 192 }, - { 100, 100 }, { 7, 7 }, { 85, 85 }, { 161, 161 }, - { 39, 39 }, { 70, 70 }, { 8, 8 }, { 146, 146 }, - { 131, 131 }, { 116, 116 }, { 55, 55 }, { 208, 208 }, - { 101, 101 }, { 24, 24 }, { 86, 86 }, { 8, 8 }, - { 132, 132 }, { 40, 40 }, { 71, 71 }, { 177, 177 }, - { 147, 147 }, { 224, 224 }, { 117, 117 }, { 162, 162 }, - { 9, 9 }, { 102, 102 }, { 56, 56 }, { 25, 25 }, - { 87, 87 }, { 148, 148 }, { 9, 9 }, { 133, 133 }, - { 72, 72 }, { 118, 118 }, { 193, 193 }, { 163, 163 }, - { 41, 41 }, { 103, 103 }, { 178, 178 }, { 10, 10 }, - { 57, 57 }, { 149, 149 }, { 134, 134 }, { 88, 88 }, - { 26, 26 }, { 119, 119 }, { 10, 10 }, { 164, 164 }, - { 104, 104 }, { 73, 73 }, { 209, 209 }, { 179, 179 }, - { 42, 42 }, { 11, 11 }, { 194, 194 }, { 135, 135 }, - { 165, 165 }, { 150, 150 }, { 58, 58 }, { 27, 27 }, - { 89, 89 }, { 11, 11 }, { 120, 120 }, { 74, 74 }, - { 43, 43 }, { 225, 225 }, { 105, 105 }, { 12, 12 }, - { 180, 180 }, { 151, 151 }, { 195, 195 }, { 136, 136 }, - { 28, 28 }, { 166, 166 }, { 121, 121 }, { 59, 59 }, - { 12, 12 }, { 210, 210 }, { 90, 90 }, { 106, 106 }, - { 44, 44 }, { 181, 181 }, { 75, 75 }, { 152, 152 }, - { 13, 13 }, { 167, 167 }, { 137, 137 }, { 13, 13 }, - { 60, 60 }, { 196, 196 }, { 122, 122 }, { 29, 29 }, - { 91, 91 }, { 14, 14 }, { 182, 182 }, { 76, 76 }, - { 211, 211 }, { 153, 153 }, { 14, 14 }, { 107, 107 }, - { 138, 138 }, { 45, 45 }, { 226, 226 }, { 168, 168 }, - { 197, 197 }, { 123, 123 }, { 30, 30 }, { 61, 61 }, - { 15, 15 }, { 92, 92 }, { 154, 154 }, { 183, 183 }, - { 169, 169 }, { 108, 108 }, { 212, 212 }, { 77, 77 }, - { 139, 139 }, { 198, 198 }, { 46, 46 }, { 124, 124 }, - { 227, 227 }, { 62, 62 }, { 31, 31 }, { 184, 184 }, - { 93, 93 }, { 170, 170 }, { 155, 155 }, { 185, 185 }, - { 78, 78 }, { 47, 47 }, { 199, 199 }, { 213, 213 }, - { 140, 140 }, { 63, 63 }, { 109, 109 }, { 125, 125 }, - { 94, 94 }, { 200, 200 }, { 171, 171 }, { 156, 156 }, - { 228, 228 }, { 186, 186 }, { 214, 214 }, { 201, 201 }, - { 79, 79 }, { 141, 141 }, { 110, 110 }, { 229, 229 }, - { 95, 95 }, { 126, 126 }, { 215, 215 }, { 172, 172 }, - { 111, 111 }, { 142, 142 }, { 202, 202 }, { 157, 157 }, - { 216, 216 }, { 230, 230 }, { 217, 217 }, { 187, 187 }, - { 127, 127 }, { 231, 231 }, { 158, 158 }, { 173, 173 }, - { 143, 143 }, { 203, 203 }, { 188, 188 }, { 232, 232 }, - { 218, 218 }, { 233, 233 }, { 159, 159 }, { 174, 174 }, - { 204, 204 }, { 189, 189 }, { 234, 234 }, { 219, 219 }, - { 175, 175 }, { 205, 205 }, { 235, 235 }, { 220, 220 }, - { 190, 190 }, { 236, 236 }, { 206, 206 }, { 191, 191 }, - { 221, 221 }, { 207, 207 }, { 237, 237 }, { 222, 222 }, - { 238, 238 }, { 223, 223 }, { 239, 239 }, { 0, 0 }, -}; - -static const int16_t vp9_default_scan_32x32_nb[1024][2] = { - { 0, 0 }, { 0, 0 }, { 1, 1 }, { 32, 1 }, - { 32, 32 }, { 2, 2 }, { 33, 2 }, { 64, 33 }, - { 3, 3 }, { 64, 64 }, { 34, 3 }, { 65, 34 }, - { 4, 4 }, { 35, 4 }, { 96, 65 }, { 66, 35 }, - { 96, 96 }, { 97, 66 }, { 67, 36 }, { 36, 5 }, - { 5, 5 }, { 128, 97 }, { 98, 67 }, { 6, 6 }, - { 128, 128 }, { 68, 37 }, { 37, 6 }, { 129, 98 }, - { 99, 68 }, { 160, 129 }, { 130, 99 }, { 38, 7 }, - { 69, 38 }, { 7, 7 }, { 100, 69 }, { 161, 130 }, - { 131, 100 }, { 160, 160 }, { 70, 39 }, { 39, 8 }, - { 8, 8 }, { 101, 70 }, { 162, 131 }, { 132, 101 }, - { 192, 161 }, { 71, 40 }, { 192, 192 }, { 102, 71 }, - { 40, 9 }, { 163, 132 }, { 9, 9 }, { 193, 162 }, - { 133, 102 }, { 164, 133 }, { 72, 41 }, { 103, 72 }, - { 134, 103 }, { 224, 193 }, { 41, 10 }, { 194, 163 }, - { 10, 10 }, { 224, 224 }, { 165, 134 }, { 225, 194 }, - { 195, 164 }, { 73, 42 }, { 104, 73 }, { 135, 104 }, - { 42, 11 }, { 11, 11 }, { 166, 135 }, { 196, 165 }, - { 226, 195 }, { 256, 225 }, { 74, 43 }, { 105, 74 }, - { 136, 105 }, { 227, 196 }, { 43, 12 }, { 197, 166 }, - { 167, 136 }, { 257, 226 }, { 256, 256 }, { 12, 12 }, - { 228, 197 }, { 75, 44 }, { 106, 75 }, { 198, 167 }, - { 137, 106 }, { 258, 227 }, { 168, 137 }, { 288, 257 }, - { 44, 13 }, { 229, 198 }, { 259, 228 }, { 199, 168 }, - { 107, 76 }, { 13, 13 }, { 169, 138 }, { 138, 107 }, - { 288, 288 }, { 289, 258 }, { 76, 45 }, { 230, 199 }, - { 260, 229 }, { 45, 14 }, { 200, 169 }, { 139, 108 }, - { 290, 259 }, { 108, 77 }, { 231, 200 }, { 320, 289 }, - { 261, 230 }, { 170, 139 }, { 77, 46 }, { 291, 260 }, - { 14, 14 }, { 321, 290 }, { 201, 170 }, { 262, 231 }, - { 320, 320 }, { 171, 140 }, { 292, 261 }, { 232, 201 }, - { 140, 109 }, { 322, 291 }, { 109, 78 }, { 46, 15 }, - { 202, 171 }, { 263, 232 }, { 233, 202 }, { 293, 262 }, - { 352, 321 }, { 323, 292 }, { 15, 15 }, { 78, 47 }, - { 203, 172 }, { 264, 233 }, { 294, 263 }, { 324, 293 }, - { 172, 141 }, { 353, 322 }, { 141, 110 }, { 234, 203 }, - { 352, 352 }, { 47, 16 }, { 295, 264 }, { 110, 79 }, - { 265, 234 }, { 354, 323 }, { 325, 294 }, { 79, 48 }, - { 16, 16 }, { 204, 173 }, { 235, 204 }, { 173, 142 }, - { 355, 324 }, { 384, 353 }, { 326, 295 }, { 142, 111 }, - { 296, 265 }, { 266, 235 }, { 356, 325 }, { 385, 354 }, - { 111, 80 }, { 48, 17 }, { 327, 296 }, { 297, 266 }, - { 205, 174 }, { 384, 384 }, { 236, 205 }, { 357, 326 }, - { 386, 355 }, { 80, 49 }, { 174, 143 }, { 17, 17 }, - { 328, 297 }, { 358, 327 }, { 387, 356 }, { 298, 267 }, - { 329, 298 }, { 388, 357 }, { 112, 81 }, { 416, 385 }, - { 237, 206 }, { 359, 328 }, { 49, 18 }, { 206, 175 }, - { 417, 386 }, { 389, 358 }, { 330, 299 }, { 18, 18 }, - { 416, 416 }, { 360, 329 }, { 81, 50 }, { 418, 387 }, - { 390, 359 }, { 238, 207 }, { 50, 19 }, { 361, 330 }, - { 419, 388 }, { 113, 82 }, { 448, 417 }, { 448, 448 }, - { 420, 389 }, { 82, 51 }, { 362, 331 }, { 449, 418 }, - { 421, 390 }, { 480, 480 }, { 450, 419 }, { 422, 391 }, - { 114, 83 }, { 451, 420 }, { 480, 449 }, { 452, 421 }, - { 481, 450 }, { 453, 422 }, { 512, 512 }, { 482, 451 }, - { 454, 423 }, { 512, 481 }, { 483, 452 }, { 513, 482 }, - { 484, 453 }, { 514, 483 }, { 485, 454 }, { 544, 513 }, - { 544, 544 }, { 486, 455 }, { 545, 514 }, { 546, 515 }, - { 576, 576 }, { 576, 545 }, { 577, 546 }, { 578, 547 }, - { 608, 577 }, { 609, 578 }, { 610, 579 }, { 19, 19 }, - { 143, 112 }, { 267, 236 }, { 391, 360 }, { 515, 484 }, - { 608, 608 }, { 20, 20 }, { 51, 20 }, { 144, 113 }, - { 175, 144 }, { 268, 237 }, { 299, 268 }, { 392, 361 }, - { 423, 392 }, { 516, 485 }, { 547, 516 }, { 640, 609 }, - { 640, 640 }, { 21, 21 }, { 52, 21 }, { 83, 52 }, - { 145, 114 }, { 176, 145 }, { 207, 176 }, { 269, 238 }, - { 300, 269 }, { 331, 300 }, { 393, 362 }, { 424, 393 }, - { 455, 424 }, { 517, 486 }, { 548, 517 }, { 579, 548 }, - { 641, 610 }, { 672, 641 }, { 672, 672 }, { 22, 22 }, - { 53, 22 }, { 84, 53 }, { 115, 84 }, { 146, 115 }, - { 177, 146 }, { 208, 177 }, { 239, 208 }, { 270, 239 }, - { 301, 270 }, { 332, 301 }, { 363, 332 }, { 394, 363 }, - { 425, 394 }, { 456, 425 }, { 487, 456 }, { 518, 487 }, - { 549, 518 }, { 580, 549 }, { 611, 580 }, { 642, 611 }, - { 673, 642 }, { 704, 673 }, { 704, 704 }, { 54, 23 }, - { 85, 54 }, { 116, 85 }, { 178, 147 }, { 209, 178 }, - { 240, 209 }, { 302, 271 }, { 333, 302 }, { 364, 333 }, - { 426, 395 }, { 457, 426 }, { 488, 457 }, { 550, 519 }, - { 581, 550 }, { 612, 581 }, { 674, 643 }, { 705, 674 }, - { 736, 705 }, { 86, 55 }, { 117, 86 }, { 210, 179 }, - { 241, 210 }, { 334, 303 }, { 365, 334 }, { 458, 427 }, - { 489, 458 }, { 582, 551 }, { 613, 582 }, { 706, 675 }, - { 737, 706 }, { 118, 87 }, { 242, 211 }, { 366, 335 }, - { 490, 459 }, { 614, 583 }, { 738, 707 }, { 23, 23 }, - { 147, 116 }, { 271, 240 }, { 395, 364 }, { 519, 488 }, - { 643, 612 }, { 736, 736 }, { 24, 24 }, { 55, 24 }, - { 148, 117 }, { 179, 148 }, { 272, 241 }, { 303, 272 }, - { 396, 365 }, { 427, 396 }, { 520, 489 }, { 551, 520 }, - { 644, 613 }, { 675, 644 }, { 768, 737 }, { 768, 768 }, - { 25, 25 }, { 56, 25 }, { 87, 56 }, { 149, 118 }, - { 180, 149 }, { 211, 180 }, { 273, 242 }, { 304, 273 }, - { 335, 304 }, { 397, 366 }, { 428, 397 }, { 459, 428 }, - { 521, 490 }, { 552, 521 }, { 583, 552 }, { 645, 614 }, - { 676, 645 }, { 707, 676 }, { 769, 738 }, { 800, 769 }, - { 800, 800 }, { 26, 26 }, { 57, 26 }, { 88, 57 }, - { 119, 88 }, { 150, 119 }, { 181, 150 }, { 212, 181 }, - { 243, 212 }, { 274, 243 }, { 305, 274 }, { 336, 305 }, - { 367, 336 }, { 398, 367 }, { 429, 398 }, { 460, 429 }, - { 491, 460 }, { 522, 491 }, { 553, 522 }, { 584, 553 }, - { 615, 584 }, { 646, 615 }, { 677, 646 }, { 708, 677 }, - { 739, 708 }, { 770, 739 }, { 801, 770 }, { 832, 801 }, - { 832, 832 }, { 58, 27 }, { 89, 58 }, { 120, 89 }, - { 182, 151 }, { 213, 182 }, { 244, 213 }, { 306, 275 }, - { 337, 306 }, { 368, 337 }, { 430, 399 }, { 461, 430 }, - { 492, 461 }, { 554, 523 }, { 585, 554 }, { 616, 585 }, - { 678, 647 }, { 709, 678 }, { 740, 709 }, { 802, 771 }, - { 833, 802 }, { 864, 833 }, { 90, 59 }, { 121, 90 }, - { 214, 183 }, { 245, 214 }, { 338, 307 }, { 369, 338 }, - { 462, 431 }, { 493, 462 }, { 586, 555 }, { 617, 586 }, - { 710, 679 }, { 741, 710 }, { 834, 803 }, { 865, 834 }, - { 122, 91 }, { 246, 215 }, { 370, 339 }, { 494, 463 }, - { 618, 587 }, { 742, 711 }, { 866, 835 }, { 27, 27 }, - { 151, 120 }, { 275, 244 }, { 399, 368 }, { 523, 492 }, - { 647, 616 }, { 771, 740 }, { 864, 864 }, { 28, 28 }, - { 59, 28 }, { 152, 121 }, { 183, 152 }, { 276, 245 }, - { 307, 276 }, { 400, 369 }, { 431, 400 }, { 524, 493 }, - { 555, 524 }, { 648, 617 }, { 679, 648 }, { 772, 741 }, - { 803, 772 }, { 896, 865 }, { 896, 896 }, { 29, 29 }, - { 60, 29 }, { 91, 60 }, { 153, 122 }, { 184, 153 }, - { 215, 184 }, { 277, 246 }, { 308, 277 }, { 339, 308 }, - { 401, 370 }, { 432, 401 }, { 463, 432 }, { 525, 494 }, - { 556, 525 }, { 587, 556 }, { 649, 618 }, { 680, 649 }, - { 711, 680 }, { 773, 742 }, { 804, 773 }, { 835, 804 }, - { 897, 866 }, { 928, 897 }, { 928, 928 }, { 30, 30 }, - { 61, 30 }, { 92, 61 }, { 123, 92 }, { 154, 123 }, - { 185, 154 }, { 216, 185 }, { 247, 216 }, { 278, 247 }, - { 309, 278 }, { 340, 309 }, { 371, 340 }, { 402, 371 }, - { 433, 402 }, { 464, 433 }, { 495, 464 }, { 526, 495 }, - { 557, 526 }, { 588, 557 }, { 619, 588 }, { 650, 619 }, - { 681, 650 }, { 712, 681 }, { 743, 712 }, { 774, 743 }, - { 805, 774 }, { 836, 805 }, { 867, 836 }, { 898, 867 }, - { 929, 898 }, { 960, 929 }, { 960, 960 }, { 62, 31 }, - { 93, 62 }, { 124, 93 }, { 186, 155 }, { 217, 186 }, - { 248, 217 }, { 310, 279 }, { 341, 310 }, { 372, 341 }, - { 434, 403 }, { 465, 434 }, { 496, 465 }, { 558, 527 }, - { 589, 558 }, { 620, 589 }, { 682, 651 }, { 713, 682 }, - { 744, 713 }, { 806, 775 }, { 837, 806 }, { 868, 837 }, - { 930, 899 }, { 961, 930 }, { 992, 961 }, { 94, 63 }, - { 125, 94 }, { 218, 187 }, { 249, 218 }, { 342, 311 }, - { 373, 342 }, { 466, 435 }, { 497, 466 }, { 590, 559 }, - { 621, 590 }, { 714, 683 }, { 745, 714 }, { 838, 807 }, - { 869, 838 }, { 962, 931 }, { 993, 962 }, { 126, 95 }, - { 250, 219 }, { 374, 343 }, { 498, 467 }, { 622, 591 }, - { 746, 715 }, { 870, 839 }, { 994, 963 }, { 155, 124 }, - { 279, 248 }, { 403, 372 }, { 527, 496 }, { 651, 620 }, - { 775, 744 }, { 899, 868 }, { 156, 125 }, { 187, 156 }, - { 280, 249 }, { 311, 280 }, { 404, 373 }, { 435, 404 }, - { 528, 497 }, { 559, 528 }, { 652, 621 }, { 683, 652 }, - { 776, 745 }, { 807, 776 }, { 900, 869 }, { 931, 900 }, - { 157, 126 }, { 188, 157 }, { 219, 188 }, { 281, 250 }, - { 312, 281 }, { 343, 312 }, { 405, 374 }, { 436, 405 }, - { 467, 436 }, { 529, 498 }, { 560, 529 }, { 591, 560 }, - { 653, 622 }, { 684, 653 }, { 715, 684 }, { 777, 746 }, - { 808, 777 }, { 839, 808 }, { 901, 870 }, { 932, 901 }, - { 963, 932 }, { 158, 127 }, { 189, 158 }, { 220, 189 }, - { 251, 220 }, { 282, 251 }, { 313, 282 }, { 344, 313 }, - { 375, 344 }, { 406, 375 }, { 437, 406 }, { 468, 437 }, - { 499, 468 }, { 530, 499 }, { 561, 530 }, { 592, 561 }, - { 623, 592 }, { 654, 623 }, { 685, 654 }, { 716, 685 }, - { 747, 716 }, { 778, 747 }, { 809, 778 }, { 840, 809 }, - { 871, 840 }, { 902, 871 }, { 933, 902 }, { 964, 933 }, - { 995, 964 }, { 190, 159 }, { 221, 190 }, { 252, 221 }, - { 314, 283 }, { 345, 314 }, { 376, 345 }, { 438, 407 }, - { 469, 438 }, { 500, 469 }, { 562, 531 }, { 593, 562 }, - { 624, 593 }, { 686, 655 }, { 717, 686 }, { 748, 717 }, - { 810, 779 }, { 841, 810 }, { 872, 841 }, { 934, 903 }, - { 965, 934 }, { 996, 965 }, { 222, 191 }, { 253, 222 }, - { 346, 315 }, { 377, 346 }, { 470, 439 }, { 501, 470 }, - { 594, 563 }, { 625, 594 }, { 718, 687 }, { 749, 718 }, - { 842, 811 }, { 873, 842 }, { 966, 935 }, { 997, 966 }, - { 254, 223 }, { 378, 347 }, { 502, 471 }, { 626, 595 }, - { 750, 719 }, { 874, 843 }, { 998, 967 }, { 283, 252 }, - { 407, 376 }, { 531, 500 }, { 655, 624 }, { 779, 748 }, - { 903, 872 }, { 284, 253 }, { 315, 284 }, { 408, 377 }, - { 439, 408 }, { 532, 501 }, { 563, 532 }, { 656, 625 }, - { 687, 656 }, { 780, 749 }, { 811, 780 }, { 904, 873 }, - { 935, 904 }, { 285, 254 }, { 316, 285 }, { 347, 316 }, - { 409, 378 }, { 440, 409 }, { 471, 440 }, { 533, 502 }, - { 564, 533 }, { 595, 564 }, { 657, 626 }, { 688, 657 }, - { 719, 688 }, { 781, 750 }, { 812, 781 }, { 843, 812 }, - { 905, 874 }, { 936, 905 }, { 967, 936 }, { 286, 255 }, - { 317, 286 }, { 348, 317 }, { 379, 348 }, { 410, 379 }, - { 441, 410 }, { 472, 441 }, { 503, 472 }, { 534, 503 }, - { 565, 534 }, { 596, 565 }, { 627, 596 }, { 658, 627 }, - { 689, 658 }, { 720, 689 }, { 751, 720 }, { 782, 751 }, - { 813, 782 }, { 844, 813 }, { 875, 844 }, { 906, 875 }, - { 937, 906 }, { 968, 937 }, { 999, 968 }, { 318, 287 }, - { 349, 318 }, { 380, 349 }, { 442, 411 }, { 473, 442 }, - { 504, 473 }, { 566, 535 }, { 597, 566 }, { 628, 597 }, - { 690, 659 }, { 721, 690 }, { 752, 721 }, { 814, 783 }, - { 845, 814 }, { 876, 845 }, { 938, 907 }, { 969, 938 }, - { 1000, 969 }, { 350, 319 }, { 381, 350 }, { 474, 443 }, - { 505, 474 }, { 598, 567 }, { 629, 598 }, { 722, 691 }, - { 753, 722 }, { 846, 815 }, { 877, 846 }, { 970, 939 }, - { 1001, 970 }, { 382, 351 }, { 506, 475 }, { 630, 599 }, - { 754, 723 }, { 878, 847 }, { 1002, 971 }, { 411, 380 }, - { 535, 504 }, { 659, 628 }, { 783, 752 }, { 907, 876 }, - { 412, 381 }, { 443, 412 }, { 536, 505 }, { 567, 536 }, - { 660, 629 }, { 691, 660 }, { 784, 753 }, { 815, 784 }, - { 908, 877 }, { 939, 908 }, { 413, 382 }, { 444, 413 }, - { 475, 444 }, { 537, 506 }, { 568, 537 }, { 599, 568 }, - { 661, 630 }, { 692, 661 }, { 723, 692 }, { 785, 754 }, - { 816, 785 }, { 847, 816 }, { 909, 878 }, { 940, 909 }, - { 971, 940 }, { 414, 383 }, { 445, 414 }, { 476, 445 }, - { 507, 476 }, { 538, 507 }, { 569, 538 }, { 600, 569 }, - { 631, 600 }, { 662, 631 }, { 693, 662 }, { 724, 693 }, - { 755, 724 }, { 786, 755 }, { 817, 786 }, { 848, 817 }, - { 879, 848 }, { 910, 879 }, { 941, 910 }, { 972, 941 }, - { 1003, 972 }, { 446, 415 }, { 477, 446 }, { 508, 477 }, - { 570, 539 }, { 601, 570 }, { 632, 601 }, { 694, 663 }, - { 725, 694 }, { 756, 725 }, { 818, 787 }, { 849, 818 }, - { 880, 849 }, { 942, 911 }, { 973, 942 }, { 1004, 973 }, - { 478, 447 }, { 509, 478 }, { 602, 571 }, { 633, 602 }, - { 726, 695 }, { 757, 726 }, { 850, 819 }, { 881, 850 }, - { 974, 943 }, { 1005, 974 }, { 510, 479 }, { 634, 603 }, - { 758, 727 }, { 882, 851 }, { 1006, 975 }, { 539, 508 }, - { 663, 632 }, { 787, 756 }, { 911, 880 }, { 540, 509 }, - { 571, 540 }, { 664, 633 }, { 695, 664 }, { 788, 757 }, - { 819, 788 }, { 912, 881 }, { 943, 912 }, { 541, 510 }, - { 572, 541 }, { 603, 572 }, { 665, 634 }, { 696, 665 }, - { 727, 696 }, { 789, 758 }, { 820, 789 }, { 851, 820 }, - { 913, 882 }, { 944, 913 }, { 975, 944 }, { 542, 511 }, - { 573, 542 }, { 604, 573 }, { 635, 604 }, { 666, 635 }, - { 697, 666 }, { 728, 697 }, { 759, 728 }, { 790, 759 }, - { 821, 790 }, { 852, 821 }, { 883, 852 }, { 914, 883 }, - { 945, 914 }, { 976, 945 }, { 1007, 976 }, { 574, 543 }, - { 605, 574 }, { 636, 605 }, { 698, 667 }, { 729, 698 }, - { 760, 729 }, { 822, 791 }, { 853, 822 }, { 884, 853 }, - { 946, 915 }, { 977, 946 }, { 1008, 977 }, { 606, 575 }, - { 637, 606 }, { 730, 699 }, { 761, 730 }, { 854, 823 }, - { 885, 854 }, { 978, 947 }, { 1009, 978 }, { 638, 607 }, - { 762, 731 }, { 886, 855 }, { 1010, 979 }, { 667, 636 }, - { 791, 760 }, { 915, 884 }, { 668, 637 }, { 699, 668 }, - { 792, 761 }, { 823, 792 }, { 916, 885 }, { 947, 916 }, - { 669, 638 }, { 700, 669 }, { 731, 700 }, { 793, 762 }, - { 824, 793 }, { 855, 824 }, { 917, 886 }, { 948, 917 }, - { 979, 948 }, { 670, 639 }, { 701, 670 }, { 732, 701 }, - { 763, 732 }, { 794, 763 }, { 825, 794 }, { 856, 825 }, - { 887, 856 }, { 918, 887 }, { 949, 918 }, { 980, 949 }, - { 1011, 980 }, { 702, 671 }, { 733, 702 }, { 764, 733 }, - { 826, 795 }, { 857, 826 }, { 888, 857 }, { 950, 919 }, - { 981, 950 }, { 1012, 981 }, { 734, 703 }, { 765, 734 }, - { 858, 827 }, { 889, 858 }, { 982, 951 }, { 1013, 982 }, - { 766, 735 }, { 890, 859 }, { 1014, 983 }, { 795, 764 }, - { 919, 888 }, { 796, 765 }, { 827, 796 }, { 920, 889 }, - { 951, 920 }, { 797, 766 }, { 828, 797 }, { 859, 828 }, - { 921, 890 }, { 952, 921 }, { 983, 952 }, { 798, 767 }, - { 829, 798 }, { 860, 829 }, { 891, 860 }, { 922, 891 }, - { 953, 922 }, { 984, 953 }, { 1015, 984 }, { 830, 799 }, - { 861, 830 }, { 892, 861 }, { 954, 923 }, { 985, 954 }, - { 1016, 985 }, { 862, 831 }, { 893, 862 }, { 986, 955 }, - { 1017, 986 }, { 894, 863 }, { 1018, 987 }, { 923, 892 }, - { 924, 893 }, { 955, 924 }, { 925, 894 }, { 956, 925 }, - { 987, 956 }, { 926, 895 }, { 957, 926 }, { 988, 957 }, - { 1019, 988 }, { 958, 927 }, { 989, 958 }, { 1020, 989 }, - { 990, 959 }, { 1021, 990 }, { 1022, 991 }, { 0, 0 }, -}; - -static const int16_t (* const vp9_scans_nb[5][4])[2] = { - { - vp9_default_scan_4x4_nb, vp9_col_scan_4x4_nb, - vp9_row_scan_4x4_nb, vp9_default_scan_4x4_nb - }, { - vp9_default_scan_8x8_nb, vp9_col_scan_8x8_nb, - vp9_row_scan_8x8_nb, vp9_default_scan_8x8_nb - }, { - vp9_default_scan_16x16_nb, vp9_col_scan_16x16_nb, - vp9_row_scan_16x16_nb, vp9_default_scan_16x16_nb - }, { - vp9_default_scan_32x32_nb, vp9_default_scan_32x32_nb, - vp9_default_scan_32x32_nb, vp9_default_scan_32x32_nb - }, { // lossless - vp9_default_scan_4x4_nb, vp9_default_scan_4x4_nb, - vp9_default_scan_4x4_nb, vp9_default_scan_4x4_nb - } -}; - -static const uint8_t vp9_model_pareto8[256][8] = { - { 6, 86, 128, 11, 87, 42, 91, 52 }, - { 3, 86, 128, 6, 86, 23, 88, 29 }, - { 6, 86, 128, 11, 87, 42, 91, 52 }, - { 9, 86, 129, 17, 88, 61, 94, 76 }, - { 12, 86, 129, 22, 88, 77, 97, 93 }, - { 15, 87, 129, 28, 89, 93, 100, 110 }, - { 17, 87, 129, 33, 90, 105, 103, 123 }, - { 20, 88, 130, 38, 91, 118, 106, 136 }, - { 23, 88, 130, 43, 91, 128, 108, 146 }, - { 26, 89, 131, 48, 92, 139, 111, 156 }, - { 28, 89, 131, 53, 93, 147, 114, 163 }, - { 31, 90, 131, 58, 94, 156, 117, 171 }, - { 34, 90, 131, 62, 94, 163, 119, 177 }, - { 37, 90, 132, 66, 95, 171, 122, 184 }, - { 39, 90, 132, 70, 96, 177, 124, 189 }, - { 42, 91, 132, 75, 97, 183, 127, 194 }, - { 44, 91, 132, 79, 97, 188, 129, 198 }, - { 47, 92, 133, 83, 98, 193, 132, 202 }, - { 49, 92, 133, 86, 99, 197, 134, 205 }, - { 52, 93, 133, 90, 100, 201, 137, 208 }, - { 54, 93, 133, 94, 100, 204, 139, 211 }, - { 57, 94, 134, 98, 101, 208, 142, 214 }, - { 59, 94, 134, 101, 102, 211, 144, 216 }, - { 62, 94, 135, 105, 103, 214, 146, 218 }, - { 64, 94, 135, 108, 103, 216, 148, 220 }, - { 66, 95, 135, 111, 104, 219, 151, 222 }, - { 68, 95, 135, 114, 105, 221, 153, 223 }, - { 71, 96, 136, 117, 106, 224, 155, 225 }, - { 73, 96, 136, 120, 106, 225, 157, 226 }, - { 76, 97, 136, 123, 107, 227, 159, 228 }, - { 78, 97, 136, 126, 108, 229, 160, 229 }, - { 80, 98, 137, 129, 109, 231, 162, 231 }, - { 82, 98, 137, 131, 109, 232, 164, 232 }, - { 84, 98, 138, 134, 110, 234, 166, 233 }, - { 86, 98, 138, 137, 111, 235, 168, 234 }, - { 89, 99, 138, 140, 112, 236, 170, 235 }, - { 91, 99, 138, 142, 112, 237, 171, 235 }, - { 93, 100, 139, 145, 113, 238, 173, 236 }, - { 95, 100, 139, 147, 114, 239, 174, 237 }, - { 97, 101, 140, 149, 115, 240, 176, 238 }, - { 99, 101, 140, 151, 115, 241, 177, 238 }, - { 101, 102, 140, 154, 116, 242, 179, 239 }, - { 103, 102, 140, 156, 117, 242, 180, 239 }, - { 105, 103, 141, 158, 118, 243, 182, 240 }, - { 107, 103, 141, 160, 118, 243, 183, 240 }, - { 109, 104, 141, 162, 119, 244, 185, 241 }, - { 111, 104, 141, 164, 119, 244, 186, 241 }, - { 113, 104, 142, 166, 120, 245, 187, 242 }, - { 114, 104, 142, 168, 121, 245, 188, 242 }, - { 116, 105, 143, 170, 122, 246, 190, 243 }, - { 118, 105, 143, 171, 122, 246, 191, 243 }, - { 120, 106, 143, 173, 123, 247, 192, 244 }, - { 121, 106, 143, 175, 124, 247, 193, 244 }, - { 123, 107, 144, 177, 125, 248, 195, 244 }, - { 125, 107, 144, 178, 125, 248, 196, 244 }, - { 127, 108, 145, 180, 126, 249, 197, 245 }, - { 128, 108, 145, 181, 127, 249, 198, 245 }, - { 130, 109, 145, 183, 128, 249, 199, 245 }, - { 132, 109, 145, 184, 128, 249, 200, 245 }, - { 134, 110, 146, 186, 129, 250, 201, 246 }, - { 135, 110, 146, 187, 130, 250, 202, 246 }, - { 137, 111, 147, 189, 131, 251, 203, 246 }, - { 138, 111, 147, 190, 131, 251, 204, 246 }, - { 140, 112, 147, 192, 132, 251, 205, 247 }, - { 141, 112, 147, 193, 132, 251, 206, 247 }, - { 143, 113, 148, 194, 133, 251, 207, 247 }, - { 144, 113, 148, 195, 134, 251, 207, 247 }, - { 146, 114, 149, 197, 135, 252, 208, 248 }, - { 147, 114, 149, 198, 135, 252, 209, 248 }, - { 149, 115, 149, 199, 136, 252, 210, 248 }, - { 150, 115, 149, 200, 137, 252, 210, 248 }, - { 152, 115, 150, 201, 138, 252, 211, 248 }, - { 153, 115, 150, 202, 138, 252, 212, 248 }, - { 155, 116, 151, 204, 139, 253, 213, 249 }, - { 156, 116, 151, 205, 139, 253, 213, 249 }, - { 158, 117, 151, 206, 140, 253, 214, 249 }, - { 159, 117, 151, 207, 141, 253, 215, 249 }, - { 161, 118, 152, 208, 142, 253, 216, 249 }, - { 162, 118, 152, 209, 142, 253, 216, 249 }, - { 163, 119, 153, 210, 143, 253, 217, 249 }, - { 164, 119, 153, 211, 143, 253, 217, 249 }, - { 166, 120, 153, 212, 144, 254, 218, 250 }, - { 167, 120, 153, 212, 145, 254, 219, 250 }, - { 168, 121, 154, 213, 146, 254, 220, 250 }, - { 169, 121, 154, 214, 146, 254, 220, 250 }, - { 171, 122, 155, 215, 147, 254, 221, 250 }, - { 172, 122, 155, 216, 147, 254, 221, 250 }, - { 173, 123, 155, 217, 148, 254, 222, 250 }, - { 174, 123, 155, 217, 149, 254, 222, 250 }, - { 176, 124, 156, 218, 150, 254, 223, 250 }, - { 177, 124, 156, 219, 150, 254, 223, 250 }, - { 178, 125, 157, 220, 151, 254, 224, 251 }, - { 179, 125, 157, 220, 151, 254, 224, 251 }, - { 180, 126, 157, 221, 152, 254, 225, 251 }, - { 181, 126, 157, 221, 152, 254, 225, 251 }, - { 183, 127, 158, 222, 153, 254, 226, 251 }, - { 184, 127, 158, 223, 154, 254, 226, 251 }, - { 185, 128, 159, 224, 155, 255, 227, 251 }, - { 186, 128, 159, 224, 155, 255, 227, 251 }, - { 187, 129, 160, 225, 156, 255, 228, 251 }, - { 188, 130, 160, 225, 156, 255, 228, 251 }, - { 189, 131, 160, 226, 157, 255, 228, 251 }, - { 190, 131, 160, 226, 158, 255, 228, 251 }, - { 191, 132, 161, 227, 159, 255, 229, 251 }, - { 192, 132, 161, 227, 159, 255, 229, 251 }, - { 193, 133, 162, 228, 160, 255, 230, 252 }, - { 194, 133, 162, 229, 160, 255, 230, 252 }, - { 195, 134, 163, 230, 161, 255, 231, 252 }, - { 196, 134, 163, 230, 161, 255, 231, 252 }, - { 197, 135, 163, 231, 162, 255, 231, 252 }, - { 198, 135, 163, 231, 162, 255, 231, 252 }, - { 199, 136, 164, 232, 163, 255, 232, 252 }, - { 200, 136, 164, 232, 164, 255, 232, 252 }, - { 201, 137, 165, 233, 165, 255, 233, 252 }, - { 201, 137, 165, 233, 165, 255, 233, 252 }, - { 202, 138, 166, 233, 166, 255, 233, 252 }, - { 203, 138, 166, 233, 166, 255, 233, 252 }, - { 204, 139, 166, 234, 167, 255, 234, 252 }, - { 205, 139, 166, 234, 167, 255, 234, 252 }, - { 206, 140, 167, 235, 168, 255, 235, 252 }, - { 206, 140, 167, 235, 168, 255, 235, 252 }, - { 207, 141, 168, 236, 169, 255, 235, 252 }, - { 208, 141, 168, 236, 170, 255, 235, 252 }, - { 209, 142, 169, 237, 171, 255, 236, 252 }, - { 209, 143, 169, 237, 171, 255, 236, 252 }, - { 210, 144, 169, 237, 172, 255, 236, 252 }, - { 211, 144, 169, 237, 172, 255, 236, 252 }, - { 212, 145, 170, 238, 173, 255, 237, 252 }, - { 213, 145, 170, 238, 173, 255, 237, 252 }, - { 214, 146, 171, 239, 174, 255, 237, 253 }, - { 214, 146, 171, 239, 174, 255, 237, 253 }, - { 215, 147, 172, 240, 175, 255, 238, 253 }, - { 215, 147, 172, 240, 175, 255, 238, 253 }, - { 216, 148, 173, 240, 176, 255, 238, 253 }, - { 217, 148, 173, 240, 176, 255, 238, 253 }, - { 218, 149, 173, 241, 177, 255, 239, 253 }, - { 218, 149, 173, 241, 178, 255, 239, 253 }, - { 219, 150, 174, 241, 179, 255, 239, 253 }, - { 219, 151, 174, 241, 179, 255, 239, 253 }, - { 220, 152, 175, 242, 180, 255, 240, 253 }, - { 221, 152, 175, 242, 180, 255, 240, 253 }, - { 222, 153, 176, 242, 181, 255, 240, 253 }, - { 222, 153, 176, 242, 181, 255, 240, 253 }, - { 223, 154, 177, 243, 182, 255, 240, 253 }, - { 223, 154, 177, 243, 182, 255, 240, 253 }, - { 224, 155, 178, 244, 183, 255, 241, 253 }, - { 224, 155, 178, 244, 183, 255, 241, 253 }, - { 225, 156, 178, 244, 184, 255, 241, 253 }, - { 225, 157, 178, 244, 184, 255, 241, 253 }, - { 226, 158, 179, 244, 185, 255, 242, 253 }, - { 227, 158, 179, 244, 185, 255, 242, 253 }, - { 228, 159, 180, 245, 186, 255, 242, 253 }, - { 228, 159, 180, 245, 186, 255, 242, 253 }, - { 229, 160, 181, 245, 187, 255, 242, 253 }, - { 229, 160, 181, 245, 187, 255, 242, 253 }, - { 230, 161, 182, 246, 188, 255, 243, 253 }, - { 230, 162, 182, 246, 188, 255, 243, 253 }, - { 231, 163, 183, 246, 189, 255, 243, 253 }, - { 231, 163, 183, 246, 189, 255, 243, 253 }, - { 232, 164, 184, 247, 190, 255, 243, 253 }, - { 232, 164, 184, 247, 190, 255, 243, 253 }, - { 233, 165, 185, 247, 191, 255, 244, 253 }, - { 233, 165, 185, 247, 191, 255, 244, 253 }, - { 234, 166, 185, 247, 192, 255, 244, 253 }, - { 234, 167, 185, 247, 192, 255, 244, 253 }, - { 235, 168, 186, 248, 193, 255, 244, 253 }, - { 235, 168, 186, 248, 193, 255, 244, 253 }, - { 236, 169, 187, 248, 194, 255, 244, 253 }, - { 236, 169, 187, 248, 194, 255, 244, 253 }, - { 236, 170, 188, 248, 195, 255, 245, 253 }, - { 236, 170, 188, 248, 195, 255, 245, 253 }, - { 237, 171, 189, 249, 196, 255, 245, 254 }, - { 237, 172, 189, 249, 196, 255, 245, 254 }, - { 238, 173, 190, 249, 197, 255, 245, 254 }, - { 238, 173, 190, 249, 197, 255, 245, 254 }, - { 239, 174, 191, 249, 198, 255, 245, 254 }, - { 239, 174, 191, 249, 198, 255, 245, 254 }, - { 240, 175, 192, 249, 199, 255, 246, 254 }, - { 240, 176, 192, 249, 199, 255, 246, 254 }, - { 240, 177, 193, 250, 200, 255, 246, 254 }, - { 240, 177, 193, 250, 200, 255, 246, 254 }, - { 241, 178, 194, 250, 201, 255, 246, 254 }, - { 241, 178, 194, 250, 201, 255, 246, 254 }, - { 242, 179, 195, 250, 202, 255, 246, 254 }, - { 242, 180, 195, 250, 202, 255, 246, 254 }, - { 242, 181, 196, 250, 203, 255, 247, 254 }, - { 242, 181, 196, 250, 203, 255, 247, 254 }, - { 243, 182, 197, 251, 204, 255, 247, 254 }, - { 243, 183, 197, 251, 204, 255, 247, 254 }, - { 244, 184, 198, 251, 205, 255, 247, 254 }, - { 244, 184, 198, 251, 205, 255, 247, 254 }, - { 244, 185, 199, 251, 206, 255, 247, 254 }, - { 244, 185, 199, 251, 206, 255, 247, 254 }, - { 245, 186, 200, 251, 207, 255, 247, 254 }, - { 245, 187, 200, 251, 207, 255, 247, 254 }, - { 246, 188, 201, 252, 207, 255, 248, 254 }, - { 246, 188, 201, 252, 207, 255, 248, 254 }, - { 246, 189, 202, 252, 208, 255, 248, 254 }, - { 246, 190, 202, 252, 208, 255, 248, 254 }, - { 247, 191, 203, 252, 209, 255, 248, 254 }, - { 247, 191, 203, 252, 209, 255, 248, 254 }, - { 247, 192, 204, 252, 210, 255, 248, 254 }, - { 247, 193, 204, 252, 210, 255, 248, 254 }, - { 248, 194, 205, 252, 211, 255, 248, 254 }, - { 248, 194, 205, 252, 211, 255, 248, 254 }, - { 248, 195, 206, 252, 212, 255, 249, 254 }, - { 248, 196, 206, 252, 212, 255, 249, 254 }, - { 249, 197, 207, 253, 213, 255, 249, 254 }, - { 249, 197, 207, 253, 213, 255, 249, 254 }, - { 249, 198, 208, 253, 214, 255, 249, 254 }, - { 249, 199, 209, 253, 214, 255, 249, 254 }, - { 250, 200, 210, 253, 215, 255, 249, 254 }, - { 250, 200, 210, 253, 215, 255, 249, 254 }, - { 250, 201, 211, 253, 215, 255, 249, 254 }, - { 250, 202, 211, 253, 215, 255, 249, 254 }, - { 250, 203, 212, 253, 216, 255, 249, 254 }, - { 250, 203, 212, 253, 216, 255, 249, 254 }, - { 251, 204, 213, 253, 217, 255, 250, 254 }, - { 251, 205, 213, 253, 217, 255, 250, 254 }, - { 251, 206, 214, 254, 218, 255, 250, 254 }, - { 251, 206, 215, 254, 218, 255, 250, 254 }, - { 252, 207, 216, 254, 219, 255, 250, 254 }, - { 252, 208, 216, 254, 219, 255, 250, 254 }, - { 252, 209, 217, 254, 220, 255, 250, 254 }, - { 252, 210, 217, 254, 220, 255, 250, 254 }, - { 252, 211, 218, 254, 221, 255, 250, 254 }, - { 252, 212, 218, 254, 221, 255, 250, 254 }, - { 253, 213, 219, 254, 222, 255, 250, 254 }, - { 253, 213, 220, 254, 222, 255, 250, 254 }, - { 253, 214, 221, 254, 223, 255, 250, 254 }, - { 253, 215, 221, 254, 223, 255, 250, 254 }, - { 253, 216, 222, 254, 224, 255, 251, 254 }, - { 253, 217, 223, 254, 224, 255, 251, 254 }, - { 253, 218, 224, 254, 225, 255, 251, 254 }, - { 253, 219, 224, 254, 225, 255, 251, 254 }, - { 254, 220, 225, 254, 225, 255, 251, 254 }, - { 254, 221, 226, 254, 225, 255, 251, 254 }, - { 254, 222, 227, 255, 226, 255, 251, 254 }, - { 254, 223, 227, 255, 226, 255, 251, 254 }, - { 254, 224, 228, 255, 227, 255, 251, 254 }, - { 254, 225, 229, 255, 227, 255, 251, 254 }, - { 254, 226, 230, 255, 228, 255, 251, 254 }, - { 254, 227, 230, 255, 229, 255, 251, 254 }, - { 255, 228, 231, 255, 230, 255, 251, 254 }, - { 255, 229, 232, 255, 230, 255, 251, 254 }, - { 255, 230, 233, 255, 231, 255, 252, 254 }, - { 255, 231, 234, 255, 231, 255, 252, 254 }, - { 255, 232, 235, 255, 232, 255, 252, 254 }, - { 255, 233, 236, 255, 232, 255, 252, 254 }, - { 255, 235, 237, 255, 233, 255, 252, 254 }, - { 255, 236, 238, 255, 234, 255, 252, 254 }, - { 255, 238, 240, 255, 235, 255, 252, 255 }, - { 255, 239, 241, 255, 235, 255, 252, 254 }, - { 255, 241, 243, 255, 236, 255, 252, 254 }, - { 255, 243, 245, 255, 237, 255, 252, 254 }, - { 255, 246, 247, 255, 239, 255, 253, 255 }, -}; - -typedef struct { - uint8_t y_mode[4][9]; - uint8_t uv_mode[10][9]; - uint8_t filter[4][2]; - uint8_t mv_mode[7][3]; - uint8_t intra[4]; - uint8_t comp[5]; - uint8_t single_ref[5][2]; - uint8_t comp_ref[5]; - uint8_t tx32p[2][3]; - uint8_t tx16p[2][2]; - uint8_t tx8p[2]; - uint8_t skip[3]; - uint8_t mv_joint[3]; - struct { - uint8_t sign; - uint8_t classes[10]; - uint8_t class0; - uint8_t bits[10]; - uint8_t class0_fp[2][3]; - uint8_t fp[3]; - uint8_t class0_hp; - uint8_t hp; - } mv_comp[2]; - uint8_t partition[4][4][3]; -} prob_context; - -static const prob_context vp9_default_probs = { - { /* y_mode */ - { 65, 32, 18, 144, 162, 194, 41, 51, 98 } /* bsize < 8x8 */, - { 132, 68, 18, 165, 217, 196, 45, 40, 78 } /* bsize < 16x16 */, - { 173, 80, 19, 176, 240, 193, 64, 35, 46 } /* bsize < 32x32 */, - { 221, 135, 38, 194, 248, 121, 96, 85, 29 } /* bsize >= 32x32 */ - }, { /* uv_mode */ - { 48, 12, 154, 155, 139, 90, 34, 117, 119 } /* y = v */, - { 67, 6, 25, 204, 243, 158, 13, 21, 96 } /* y = h */, - { 120, 7, 76, 176, 208, 126, 28, 54, 103 } /* y = dc */, - { 97, 5, 44, 131, 176, 139, 48, 68, 97 } /* y = d45 */, - { 83, 5, 42, 156, 111, 152, 26, 49, 152 } /* y = d135 */, - { 80, 5, 58, 178, 74, 83, 33, 62, 145 } /* y = d117 */, - { 86, 5, 32, 154, 192, 168, 14, 22, 163 } /* y = d153 */, - { 77, 7, 64, 116, 132, 122, 37, 126, 120 } /* y = d63 */, - { 85, 5, 32, 156, 216, 148, 19, 29, 73 } /* y = d27 */, - { 101, 21, 107, 181, 192, 103, 19, 67, 125 } /* y = tm */ - }, { /* filter */ - { 235, 162, }, - { 36, 255, }, - { 34, 3, }, - { 149, 144, }, - }, { /* mv_mode */ - { 2, 173, 34}, // 0 = both zero mv - { 7, 145, 85}, // 1 = one zero mv + one a predicted mv - { 7, 166, 63}, // 2 = two predicted mvs - { 7, 94, 66}, // 3 = one predicted/zero and one new mv - { 8, 64, 46}, // 4 = two new mvs - { 17, 81, 31}, // 5 = one intra neighbour + x - { 25, 29, 30}, // 6 = two intra neighbours - }, { /* intra */ - 9, 102, 187, 225 - }, { /* comp */ - 239, 183, 119, 96, 41 - }, { /* single_ref */ - { 33, 16 }, - { 77, 74 }, - { 142, 142 }, - { 172, 170 }, - { 238, 247 } - }, { /* comp_ref */ - 50, 126, 123, 221, 226 - }, { /* tx32p */ - { 3, 136, 37, }, - { 5, 52, 13, }, - }, { /* tx16p */ - { 20, 152, }, - { 15, 101, }, - }, { /* tx8p */ - 100, 66 - }, { /* skip */ - 192, 128, 64 - }, { /* mv_joint */ - 32, 64, 96 - }, { - { /* mv vertical component */ - 128, /* sign */ - { 224, 144, 192, 168, 192, 176, 192, 198, 198, 245 }, /* class */ - 216, /* class0 */ - { 136, 140, 148, 160, 176, 192, 224, 234, 234, 240}, /* bits */ - { /* class0_fp */ - { 128, 128, 64 }, - { 96, 112, 64 } - }, - { 64, 96, 64 }, /* fp */ - 160, /* class0_hp bit */ - 128, /* hp */ - }, { /* mv horizontal component */ - 128, /* sign */ - { 216, 128, 176, 160, 176, 176, 192, 198, 198, 208 }, /* class */ - 208, /* class0 */ - { 136, 140, 148, 160, 176, 192, 224, 234, 234, 240 }, /* bits */ - { /* class0_fp */ - { 128, 128, 64 }, - { 96, 112, 64 } - }, - { 64, 96, 64 }, /* fp */ - 160, /* class0_hp bit */ - 128, /* hp */ - } - }, { /* partition */ - { /* 64x64 -> 32x32 */ - { 222, 34, 30 } /* a/l both not split */, - { 72, 16, 44 } /* a split, l not split */, - { 58, 32, 12 } /* l split, a not split */, - { 10, 7, 6 } /* a/l both split */, - }, { /* 32x32 -> 16x16 */ - { 177, 58, 59 } /* a/l both not split */, - { 68, 26, 63 } /* a split, l not split */, - { 52, 79, 25 } /* l split, a not split */, - { 17, 14, 12 } /* a/l both split */, - }, { /* 16x16 -> 8x8 */ - { 174, 73, 87 } /* a/l both not split */, - { 92, 41, 83 } /* a split, l not split */, - { 82, 99, 50 } /* l split, a not split */, - { 53, 39, 39 } /* a/l both split */, - }, { /* 8x8 -> 4x4 */ - { 199, 122, 141 } /* a/l both not split */, - { 147, 63, 159 } /* a split, l not split */, - { 148, 133, 118 } /* l split, a not split */, - { 121, 104, 114 } /* a/l both split */, - } - }, -}; - -static const uint8_t vp9_default_coef_probs[4][2][2][6][6][3] = { - { /* tx = 4x4 */ - { /* block Type 0 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 195, 29, 183 }, - { 84, 49, 136 }, - { 8, 42, 71 } - }, { /* Coeff Band 1 */ - { 31, 107, 169 }, - { 35, 99, 159 }, - { 17, 82, 140 }, - { 8, 66, 114 }, - { 2, 44, 76 }, - { 1, 19, 32 } - }, { /* Coeff Band 2 */ - { 40, 132, 201 }, - { 29, 114, 187 }, - { 13, 91, 157 }, - { 7, 75, 127 }, - { 3, 58, 95 }, - { 1, 28, 47 } - }, { /* Coeff Band 3 */ - { 69, 142, 221 }, - { 42, 122, 201 }, - { 15, 91, 159 }, - { 6, 67, 121 }, - { 1, 42, 77 }, - { 1, 17, 31 } - }, { /* Coeff Band 4 */ - { 102, 148, 228 }, - { 67, 117, 204 }, - { 17, 82, 154 }, - { 6, 59, 114 }, - { 2, 39, 75 }, - { 1, 15, 29 } - }, { /* Coeff Band 5 */ - { 156, 57, 233 }, - { 119, 57, 212 }, - { 58, 48, 163 }, - { 29, 40, 124 }, - { 12, 30, 81 }, - { 3, 12, 31 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 191, 107, 226 }, - { 124, 117, 204 }, - { 25, 99, 155 } - }, { /* Coeff Band 1 */ - { 29, 148, 210 }, - { 37, 126, 194 }, - { 8, 93, 157 }, - { 2, 68, 118 }, - { 1, 39, 69 }, - { 1, 17, 33 } - }, { /* Coeff Band 2 */ - { 41, 151, 213 }, - { 27, 123, 193 }, - { 3, 82, 144 }, - { 1, 58, 105 }, - { 1, 32, 60 }, - { 1, 13, 26 } - }, { /* Coeff Band 3 */ - { 59, 159, 220 }, - { 23, 126, 198 }, - { 4, 88, 151 }, - { 1, 66, 114 }, - { 1, 38, 71 }, - { 1, 18, 34 } - }, { /* Coeff Band 4 */ - { 114, 136, 232 }, - { 51, 114, 207 }, - { 11, 83, 155 }, - { 3, 56, 105 }, - { 1, 33, 65 }, - { 1, 17, 34 } - }, { /* Coeff Band 5 */ - { 149, 65, 234 }, - { 121, 57, 215 }, - { 61, 49, 166 }, - { 28, 36, 114 }, - { 12, 25, 76 }, - { 3, 16, 42 } - } - } - }, { /* block Type 1 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 214, 49, 220 }, - { 132, 63, 188 }, - { 42, 65, 137 } - }, { /* Coeff Band 1 */ - { 85, 137, 221 }, - { 104, 131, 216 }, - { 49, 111, 192 }, - { 21, 87, 155 }, - { 2, 49, 87 }, - { 1, 16, 28 } - }, { /* Coeff Band 2 */ - { 89, 163, 230 }, - { 90, 137, 220 }, - { 29, 100, 183 }, - { 10, 70, 135 }, - { 2, 42, 81 }, - { 1, 17, 33 } - }, { /* Coeff Band 3 */ - { 108, 167, 237 }, - { 55, 133, 222 }, - { 15, 97, 179 }, - { 4, 72, 135 }, - { 1, 45, 85 }, - { 1, 19, 38 } - }, { /* Coeff Band 4 */ - { 124, 146, 240 }, - { 66, 124, 224 }, - { 17, 88, 175 }, - { 4, 58, 122 }, - { 1, 36, 75 }, - { 1, 18, 37 } - }, { /* Coeff Band 5 */ - { 141, 79, 241 }, - { 126, 70, 227 }, - { 66, 58, 182 }, - { 30, 44, 136 }, - { 12, 34, 96 }, - { 2, 20, 47 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 229, 99, 249 }, - { 143, 111, 235 }, - { 46, 109, 192 } - }, { /* Coeff Band 1 */ - { 82, 158, 236 }, - { 94, 146, 224 }, - { 25, 117, 191 }, - { 9, 87, 149 }, - { 3, 56, 99 }, - { 1, 33, 57 } - }, { /* Coeff Band 2 */ - { 83, 167, 237 }, - { 68, 145, 222 }, - { 10, 103, 177 }, - { 2, 72, 131 }, - { 1, 41, 79 }, - { 1, 20, 39 } - }, { /* Coeff Band 3 */ - { 99, 167, 239 }, - { 47, 141, 224 }, - { 10, 104, 178 }, - { 2, 73, 133 }, - { 1, 44, 85 }, - { 1, 22, 47 } - }, { /* Coeff Band 4 */ - { 127, 145, 243 }, - { 71, 129, 228 }, - { 17, 93, 177 }, - { 3, 61, 124 }, - { 1, 41, 84 }, - { 1, 21, 52 } - }, { /* Coeff Band 5 */ - { 157, 78, 244 }, - { 140, 72, 231 }, - { 69, 58, 184 }, - { 31, 44, 137 }, - { 14, 38, 105 }, - { 8, 23, 61 } - } - } - } - }, { /* tx = 8x8 */ - { /* block Type 0 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 125, 34, 187 }, - { 52, 41, 133 }, - { 6, 31, 56 } - }, { /* Coeff Band 1 */ - { 37, 109, 153 }, - { 51, 102, 147 }, - { 23, 87, 128 }, - { 8, 67, 101 }, - { 1, 41, 63 }, - { 1, 19, 29 } - }, { /* Coeff Band 2 */ - { 31, 154, 185 }, - { 17, 127, 175 }, - { 6, 96, 145 }, - { 2, 73, 114 }, - { 1, 51, 82 }, - { 1, 28, 45 } - }, { /* Coeff Band 3 */ - { 23, 163, 200 }, - { 10, 131, 185 }, - { 2, 93, 148 }, - { 1, 67, 111 }, - { 1, 41, 69 }, - { 1, 14, 24 } - }, { /* Coeff Band 4 */ - { 29, 176, 217 }, - { 12, 145, 201 }, - { 3, 101, 156 }, - { 1, 69, 111 }, - { 1, 39, 63 }, - { 1, 14, 23 } - }, { /* Coeff Band 5 */ - { 57, 192, 233 }, - { 25, 154, 215 }, - { 6, 109, 167 }, - { 3, 78, 118 }, - { 1, 48, 69 }, - { 1, 21, 29 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 202, 105, 245 }, - { 108, 106, 216 }, - { 18, 90, 144 } - }, { /* Coeff Band 1 */ - { 33, 172, 219 }, - { 64, 149, 206 }, - { 14, 117, 177 }, - { 5, 90, 141 }, - { 2, 61, 95 }, - { 1, 37, 57 } - }, { /* Coeff Band 2 */ - { 33, 179, 220 }, - { 11, 140, 198 }, - { 1, 89, 148 }, - { 1, 60, 104 }, - { 1, 33, 57 }, - { 1, 12, 21 } - }, { /* Coeff Band 3 */ - { 30, 181, 221 }, - { 8, 141, 198 }, - { 1, 87, 145 }, - { 1, 58, 100 }, - { 1, 31, 55 }, - { 1, 12, 20 } - }, { /* Coeff Band 4 */ - { 32, 186, 224 }, - { 7, 142, 198 }, - { 1, 86, 143 }, - { 1, 58, 100 }, - { 1, 31, 55 }, - { 1, 12, 22 } - }, { /* Coeff Band 5 */ - { 57, 192, 227 }, - { 20, 143, 204 }, - { 3, 96, 154 }, - { 1, 68, 112 }, - { 1, 42, 69 }, - { 1, 19, 32 } - } - } - }, { /* block Type 1 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 212, 35, 215 }, - { 113, 47, 169 }, - { 29, 48, 105 } - }, { /* Coeff Band 1 */ - { 74, 129, 203 }, - { 106, 120, 203 }, - { 49, 107, 178 }, - { 19, 84, 144 }, - { 4, 50, 84 }, - { 1, 15, 25 } - }, { /* Coeff Band 2 */ - { 71, 172, 217 }, - { 44, 141, 209 }, - { 15, 102, 173 }, - { 6, 76, 133 }, - { 2, 51, 89 }, - { 1, 24, 42 } - }, { /* Coeff Band 3 */ - { 64, 185, 231 }, - { 31, 148, 216 }, - { 8, 103, 175 }, - { 3, 74, 131 }, - { 1, 46, 81 }, - { 1, 18, 30 } - }, { /* Coeff Band 4 */ - { 65, 196, 235 }, - { 25, 157, 221 }, - { 5, 105, 174 }, - { 1, 67, 120 }, - { 1, 38, 69 }, - { 1, 15, 30 } - }, { /* Coeff Band 5 */ - { 65, 204, 238 }, - { 30, 156, 224 }, - { 7, 107, 177 }, - { 2, 70, 124 }, - { 1, 42, 73 }, - { 1, 18, 34 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 225, 86, 251 }, - { 144, 104, 235 }, - { 42, 99, 181 } - }, { /* Coeff Band 1 */ - { 85, 175, 239 }, - { 112, 165, 229 }, - { 29, 136, 200 }, - { 12, 103, 162 }, - { 6, 77, 123 }, - { 2, 53, 84 } - }, { /* Coeff Band 2 */ - { 75, 183, 239 }, - { 30, 155, 221 }, - { 3, 106, 171 }, - { 1, 74, 128 }, - { 1, 44, 76 }, - { 1, 17, 28 } - }, { /* Coeff Band 3 */ - { 73, 185, 240 }, - { 27, 159, 222 }, - { 2, 107, 172 }, - { 1, 75, 127 }, - { 1, 42, 73 }, - { 1, 17, 29 } - }, { /* Coeff Band 4 */ - { 62, 190, 238 }, - { 21, 159, 222 }, - { 2, 107, 172 }, - { 1, 72, 122 }, - { 1, 40, 71 }, - { 1, 18, 32 } - }, { /* Coeff Band 5 */ - { 61, 199, 240 }, - { 27, 161, 226 }, - { 4, 113, 180 }, - { 1, 76, 129 }, - { 1, 46, 80 }, - { 1, 23, 41 } - } - } - } - }, { /* tx = 16x16 */ - { /* block Type 0 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 7, 27, 153 }, - { 5, 30, 95 }, - { 1, 16, 30 } - }, { /* Coeff Band 1 */ - { 50, 75, 127 }, - { 57, 75, 124 }, - { 27, 67, 108 }, - { 10, 54, 86 }, - { 1, 33, 52 }, - { 1, 12, 18 } - }, { /* Coeff Band 2 */ - { 43, 125, 151 }, - { 26, 108, 148 }, - { 7, 83, 122 }, - { 2, 59, 89 }, - { 1, 38, 60 }, - { 1, 17, 27 } - }, { /* Coeff Band 3 */ - { 23, 144, 163 }, - { 13, 112, 154 }, - { 2, 75, 117 }, - { 1, 50, 81 }, - { 1, 31, 51 }, - { 1, 14, 23 } - }, { /* Coeff Band 4 */ - { 18, 162, 185 }, - { 6, 123, 171 }, - { 1, 78, 125 }, - { 1, 51, 86 }, - { 1, 31, 54 }, - { 1, 14, 23 } - }, { /* Coeff Band 5 */ - { 15, 199, 227 }, - { 3, 150, 204 }, - { 1, 91, 146 }, - { 1, 55, 95 }, - { 1, 30, 53 }, - { 1, 11, 20 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 19, 55, 240 }, - { 19, 59, 196 }, - { 3, 52, 105 } - }, { /* Coeff Band 1 */ - { 41, 166, 207 }, - { 104, 153, 199 }, - { 31, 123, 181 }, - { 14, 101, 152 }, - { 5, 72, 106 }, - { 1, 36, 52 } - }, { /* Coeff Band 2 */ - { 35, 176, 211 }, - { 12, 131, 190 }, - { 2, 88, 144 }, - { 1, 60, 101 }, - { 1, 36, 60 }, - { 1, 16, 28 } - }, { /* Coeff Band 3 */ - { 28, 183, 213 }, - { 8, 134, 191 }, - { 1, 86, 142 }, - { 1, 56, 96 }, - { 1, 30, 53 }, - { 1, 12, 20 } - }, { /* Coeff Band 4 */ - { 20, 190, 215 }, - { 4, 135, 192 }, - { 1, 84, 139 }, - { 1, 53, 91 }, - { 1, 28, 49 }, - { 1, 11, 20 } - }, { /* Coeff Band 5 */ - { 13, 196, 216 }, - { 2, 137, 192 }, - { 1, 86, 143 }, - { 1, 57, 99 }, - { 1, 32, 56 }, - { 1, 13, 24 } - } - } - }, { /* block Type 1 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 211, 29, 217 }, - { 96, 47, 156 }, - { 22, 43, 87 } - }, { /* Coeff Band 1 */ - { 78, 120, 193 }, - { 111, 116, 186 }, - { 46, 102, 164 }, - { 15, 80, 128 }, - { 2, 49, 76 }, - { 1, 18, 28 } - }, { /* Coeff Band 2 */ - { 71, 161, 203 }, - { 42, 132, 192 }, - { 10, 98, 150 }, - { 3, 69, 109 }, - { 1, 44, 70 }, - { 1, 18, 29 } - }, { /* Coeff Band 3 */ - { 57, 186, 211 }, - { 30, 140, 196 }, - { 4, 93, 146 }, - { 1, 62, 102 }, - { 1, 38, 65 }, - { 1, 16, 27 } - }, { /* Coeff Band 4 */ - { 47, 199, 217 }, - { 14, 145, 196 }, - { 1, 88, 142 }, - { 1, 57, 98 }, - { 1, 36, 62 }, - { 1, 15, 26 } - }, { /* Coeff Band 5 */ - { 26, 219, 229 }, - { 5, 155, 207 }, - { 1, 94, 151 }, - { 1, 60, 104 }, - { 1, 36, 62 }, - { 1, 16, 28 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 233, 29, 248 }, - { 146, 47, 220 }, - { 43, 52, 140 } - }, { /* Coeff Band 1 */ - { 100, 163, 232 }, - { 179, 161, 222 }, - { 63, 142, 204 }, - { 37, 113, 174 }, - { 26, 89, 137 }, - { 18, 68, 97 } - }, { /* Coeff Band 2 */ - { 85, 181, 230 }, - { 32, 146, 209 }, - { 7, 100, 164 }, - { 3, 71, 121 }, - { 1, 45, 77 }, - { 1, 18, 30 } - }, { /* Coeff Band 3 */ - { 65, 187, 230 }, - { 20, 148, 207 }, - { 2, 97, 159 }, - { 1, 68, 116 }, - { 1, 40, 70 }, - { 1, 14, 29 } - }, { /* Coeff Band 4 */ - { 40, 194, 227 }, - { 8, 147, 204 }, - { 1, 94, 155 }, - { 1, 65, 112 }, - { 1, 39, 66 }, - { 1, 14, 26 } - }, { /* Coeff Band 5 */ - { 16, 208, 228 }, - { 3, 151, 207 }, - { 1, 98, 160 }, - { 1, 67, 117 }, - { 1, 41, 74 }, - { 1, 17, 31 } - } - } - } - }, { /* tx = 32x32 */ - { /* block Type 0 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 17, 38, 140 }, - { 7, 34, 80 }, - { 1, 17, 29 } - }, { /* Coeff Band 1 */ - { 37, 75, 128 }, - { 41, 76, 128 }, - { 26, 66, 116 }, - { 12, 52, 94 }, - { 2, 32, 55 }, - { 1, 10, 16 } - }, { /* Coeff Band 2 */ - { 50, 127, 154 }, - { 37, 109, 152 }, - { 16, 82, 121 }, - { 5, 59, 85 }, - { 1, 35, 54 }, - { 1, 13, 20 } - }, { /* Coeff Band 3 */ - { 40, 142, 167 }, - { 17, 110, 157 }, - { 2, 71, 112 }, - { 1, 44, 72 }, - { 1, 27, 45 }, - { 1, 11, 17 } - }, { /* Coeff Band 4 */ - { 30, 175, 188 }, - { 9, 124, 169 }, - { 1, 74, 116 }, - { 1, 48, 78 }, - { 1, 30, 49 }, - { 1, 11, 18 } - }, { /* Coeff Band 5 */ - { 10, 222, 223 }, - { 2, 150, 194 }, - { 1, 83, 128 }, - { 1, 48, 79 }, - { 1, 27, 45 }, - { 1, 11, 17 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 36, 41, 235 }, - { 29, 36, 193 }, - { 10, 27, 111 } - }, { /* Coeff Band 1 */ - { 85, 165, 222 }, - { 177, 162, 215 }, - { 110, 135, 195 }, - { 57, 113, 168 }, - { 23, 83, 120 }, - { 10, 49, 61 } - }, { /* Coeff Band 2 */ - { 85, 190, 223 }, - { 36, 139, 200 }, - { 5, 90, 146 }, - { 1, 60, 103 }, - { 1, 38, 65 }, - { 1, 18, 30 } - }, { /* Coeff Band 3 */ - { 72, 202, 223 }, - { 23, 141, 199 }, - { 2, 86, 140 }, - { 1, 56, 97 }, - { 1, 36, 61 }, - { 1, 16, 27 } - }, { /* Coeff Band 4 */ - { 55, 218, 225 }, - { 13, 145, 200 }, - { 1, 86, 141 }, - { 1, 57, 99 }, - { 1, 35, 61 }, - { 1, 13, 22 } - }, { /* Coeff Band 5 */ - { 15, 235, 212 }, - { 1, 132, 184 }, - { 1, 84, 139 }, - { 1, 57, 97 }, - { 1, 34, 56 }, - { 1, 14, 23 } - } - } - }, { /* block Type 1 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 181, 21, 201 }, - { 61, 37, 123 }, - { 10, 38, 71 } - }, { /* Coeff Band 1 */ - { 47, 106, 172 }, - { 95, 104, 173 }, - { 42, 93, 159 }, - { 18, 77, 131 }, - { 4, 50, 81 }, - { 1, 17, 23 } - }, { /* Coeff Band 2 */ - { 62, 147, 199 }, - { 44, 130, 189 }, - { 28, 102, 154 }, - { 18, 75, 115 }, - { 2, 44, 65 }, - { 1, 12, 19 } - }, { /* Coeff Band 3 */ - { 55, 153, 210 }, - { 24, 130, 194 }, - { 3, 93, 146 }, - { 1, 61, 97 }, - { 1, 31, 50 }, - { 1, 10, 16 } - }, { /* Coeff Band 4 */ - { 49, 186, 223 }, - { 17, 148, 204 }, - { 1, 96, 142 }, - { 1, 53, 83 }, - { 1, 26, 44 }, - { 1, 11, 17 } - }, { /* Coeff Band 5 */ - { 13, 217, 212 }, - { 2, 136, 180 }, - { 1, 78, 124 }, - { 1, 50, 83 }, - { 1, 29, 49 }, - { 1, 14, 23 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 197, 13, 247 }, - { 82, 17, 222 }, - { 25, 17, 162 } - }, { /* Coeff Band 1 */ - { 126, 186, 247 }, - { 234, 191, 243 }, - { 176, 177, 234 }, - { 104, 158, 220 }, - { 66, 128, 186 }, - { 55, 90, 137 } - }, { /* Coeff Band 2 */ - { 111, 197, 242 }, - { 46, 158, 219 }, - { 9, 104, 171 }, - { 2, 65, 125 }, - { 1, 44, 80 }, - { 1, 17, 91 } - }, { /* Coeff Band 3 */ - { 104, 208, 245 }, - { 39, 168, 224 }, - { 3, 109, 162 }, - { 1, 79, 124 }, - { 1, 50, 102 }, - { 1, 43, 102 } - }, { /* Coeff Band 4 */ - { 84, 220, 246 }, - { 31, 177, 231 }, - { 2, 115, 180 }, - { 1, 79, 134 }, - { 1, 55, 77 }, - { 1, 60, 79 } - }, { /* Coeff Band 5 */ - { 43, 243, 240 }, - { 8, 180, 217 }, - { 1, 115, 166 }, - { 1, 84, 121 }, - { 1, 51, 67 }, - { 1, 16, 6 } - } - } - } - } -}; - -enum MVJoint { - MV_JOINT_ZERO, - MV_JOINT_H, - MV_JOINT_V, - MV_JOINT_HV, -}; - -static const int8_t vp9_mv_joint_tree[3][2] = { - { -MV_JOINT_ZERO, 1 }, // '0' - { -MV_JOINT_H, 2 }, // '10' - { -MV_JOINT_V, -MV_JOINT_HV }, // '11x' -}; - -static const int8_t vp9_mv_class_tree[10][2] = { - { -0, 1 }, // '0' - { -1, 2 }, // '10' - { 3, 4 }, - { -2, -3 }, // '110x' - { 5, 6 }, - { -4, -5 }, // '1110x' - { -6, 7 }, // '11110' - { 8, 9 }, - { -7, -8 }, // '111110x' - { -9, -10 }, // '111111x' -}; - -static const int8_t vp9_mv_fp_tree[3][2] = { - { -0, 1 }, // '0' - { -1, 2 }, // '10' - { -2, -3 }, // '11x' -}; +extern const int8_t ff_vp9_partition_tree[3][2]; +extern const uint8_t ff_vp9_default_kf_partition_probs[4][4][3]; +extern const int8_t ff_vp9_segmentation_tree[7][2]; +extern const int8_t ff_vp9_intramode_tree[9][2]; +extern const uint8_t ff_vp9_default_kf_ymode_probs[10][10][9]; +extern const uint8_t ff_vp9_default_kf_uvmode_probs[10][9]; +extern const int8_t ff_vp9_inter_mode_tree[3][2]; +extern const int8_t ff_vp9_filter_tree[2][2]; +extern const enum FilterMode ff_vp9_filter_lut[3]; +extern const int16_t ff_vp9_dc_qlookup[3][256]; +extern const int16_t ff_vp9_ac_qlookup[3][256]; +extern const enum TxfmType ff_vp9_intra_txfm_type[14]; +extern const int16_t ff_vp9_default_scan_4x4[16]; +extern const int16_t ff_vp9_col_scan_4x4[16]; +extern const int16_t ff_vp9_row_scan_4x4[16]; +extern const int16_t ff_vp9_default_scan_8x8[64]; +extern const int16_t ff_vp9_col_scan_8x8[64]; +extern const int16_t ff_vp9_row_scan_8x8[64]; +extern const int16_t ff_vp9_default_scan_16x16[256]; +extern const int16_t ff_vp9_col_scan_16x16[256]; +extern const int16_t ff_vp9_row_scan_16x16[256]; +extern const int16_t ff_vp9_default_scan_32x32[1024]; +extern const int16_t * const ff_vp9_scans[5][4]; +extern const int16_t ff_vp9_default_scan_4x4_nb[16][2]; +extern const int16_t ff_vp9_col_scan_4x4_nb[16][2]; +extern const int16_t ff_vp9_row_scan_4x4_nb[16][2]; +extern const int16_t ff_vp9_default_scan_8x8_nb[64][2]; +extern const int16_t ff_vp9_col_scan_8x8_nb[64][2]; +extern const int16_t ff_vp9_row_scan_8x8_nb[64][2]; +extern const int16_t ff_vp9_default_scan_16x16_nb[256][2]; +extern const int16_t ff_vp9_col_scan_16x16_nb[256][2]; +extern const int16_t ff_vp9_row_scan_16x16_nb[256][2]; +extern const int16_t ff_vp9_default_scan_32x32_nb[1024][2]; +extern const int16_t (* const ff_vp9_scans_nb[5][4])[2]; +extern const uint8_t ff_vp9_model_pareto8[256][8]; +extern const ProbContext ff_vp9_default_probs; +extern const uint8_t ff_vp9_default_coef_probs[4][2][2][6][6][3]; +extern const int8_t ff_vp9_mv_joint_tree[3][2]; +extern const int8_t ff_vp9_mv_class_tree[10][2]; +extern const int8_t ff_vp9_mv_fp_tree[3][2]; #endif /* AVCODEC_VP9DATA_H */ diff --git a/libavcodec/vp9dsp.c b/libavcodec/vp9dsp.c index f6d73f73cd4d1..cf9de4a0ff82f 100644 --- a/libavcodec/vp9dsp.c +++ b/libavcodec/vp9dsp.c @@ -23,7 +23,7 @@ #include "libavutil/avassert.h" #include "libavutil/common.h" -#include "vp9dsp.h" +#include "vp9.h" const DECLARE_ALIGNED(16, int16_t, ff_vp9_subpel_filters)[3][16][8] = { [FILTER_8TAP_REGULAR] = { diff --git a/libavcodec/vp9dsp.h b/libavcodec/vp9dsp.h deleted file mode 100644 index 0d24ae17f759b..0000000000000 --- a/libavcodec/vp9dsp.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * VP9 compatible video decoder - * - * Copyright (C) 2013 Ronald S. Bultje - * Copyright (C) 2013 Clément Bœsch - * - * 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 - */ - -#ifndef AVCODEC_VP9DSP_H -#define AVCODEC_VP9DSP_H - -#include -#include - -#include "vp9.h" - -typedef void (*vp9_mc_func)(uint8_t *dst, ptrdiff_t dst_stride, - const uint8_t *ref, ptrdiff_t ref_stride, - int h, int mx, int my); -typedef void (*vp9_scaled_mc_func)(uint8_t *dst, ptrdiff_t dst_stride, - const uint8_t *ref, ptrdiff_t ref_stride, - int h, int mx, int my, int dx, int dy); - -typedef struct VP9DSPContext { - /* - * dimension 1: 0=4x4, 1=8x8, 2=16x16, 3=32x32 - * dimension 2: intra prediction modes - * - * dst/left/top is aligned by transform-size (i.e. 4, 8, 16 or 32 pixels) - * stride is aligned by 16 pixels - * top[-1] is top/left; top[4,7] is top-right for 4x4 - */ - // FIXME(rbultje) maybe replace left/top pointers with HAVE_TOP/ - // HAVE_LEFT/HAVE_TOPRIGHT flags instead, and then handle it in-place? - // also needs to fit in with what H.264/VP8/etc do - void (*intra_pred[N_TXFM_SIZES][N_INTRA_PRED_MODES])(uint8_t *dst, - ptrdiff_t stride, - const uint8_t *left, - const uint8_t *top); - - /* - * dimension 1: 0=4x4, 1=8x8, 2=16x16, 3=32x32, 4=lossless (3-4=dct only) - * dimension 2: 0=dct/dct, 1=dct/adst, 2=adst/dct, 3=adst/adst - * - * dst is aligned by transform-size (i.e. 4, 8, 16 or 32 pixels) - * stride is aligned by 16 pixels - * block is 16-byte aligned - * eob indicates the position (+1) of the last non-zero coefficient, - * in scan-order. This can be used to write faster versions, e.g. a - * dc-only 4x4/8x8/16x16/32x32, or a 4x4-only (eob<10) 8x8/16x16/32x32, - * etc. - */ - // FIXME also write idct_add_block() versions for whole (inter) pred - // blocks, so we can do 2 4x4s at once - void (*itxfm_add[N_TXFM_SIZES + 1][N_TXFM_TYPES])(uint8_t *dst, - ptrdiff_t stride, - int16_t *block, int eob); - - /* - * dimension 1: width of filter (0=4, 1=8, 2=16) - * dimension 2: 0=col-edge filter (h), 1=row-edge filter (v) - * - * dst/stride are aligned by 8 - */ - void (*loop_filter_8[3][2])(uint8_t *dst, ptrdiff_t stride, - int mb_lim, int lim, int hev_thr); - - /* - * dimension 1: 0=col-edge filter (h), 1=row-edge filter (v) - * - * The width of filter is assumed to be 16; dst/stride are aligned by 16 - */ - void (*loop_filter_16[2])(uint8_t *dst, ptrdiff_t stride, - int mb_lim, int lim, int hev_thr); - - /* - * dimension 1/2: width of filter (0=4, 1=8) for each filter half - * dimension 3: 0=col-edge filter (h), 1=row-edge filter (v) - * - * dst/stride are aligned by operation size - * this basically calls loop_filter[d1][d3][0](), followed by - * loop_filter[d2][d3][0]() on the next 8 pixels - * mb_lim/lim/hev_thr contain two values in the lowest two bytes of the - * integer. - */ - // FIXME perhaps a mix4 that operates on 32px (for AVX2) - void (*loop_filter_mix2[2][2][2])(uint8_t *dst, ptrdiff_t stride, - int mb_lim, int lim, int hev_thr); - - /* - * dimension 1: hsize (0: 64, 1: 32, 2: 16, 3: 8, 4: 4) - * dimension 2: filter type (0: smooth, 1: regular, 2: sharp, 3: bilin) - * dimension 3: averaging type (0: put, 1: avg) - * dimension 4: x subpel interpolation (0: none, 1: 8tap/bilin) - * dimension 5: y subpel interpolation (0: none, 1: 8tap/bilin) - * - * dst/stride are aligned by hsize - */ - vp9_mc_func mc[5][4][2][2][2]; - - /* - * for scalable MC, first 3 dimensions identical to above, the other two - * don't exist since it changes per stepsize. - */ - vp9_scaled_mc_func smc[5][4][2]; -} VP9DSPContext; - - -extern const int16_t ff_vp9_subpel_filters[3][16][8]; - -void ff_vp9dsp_init(VP9DSPContext *dsp, int bpp, int bitexact); - -void ff_vp9dsp_init_8(VP9DSPContext *dsp); -void ff_vp9dsp_init_10(VP9DSPContext *dsp); -void ff_vp9dsp_init_12(VP9DSPContext *dsp); - -void ff_vp9dsp_init_aarch64(VP9DSPContext *dsp, int bpp); -void ff_vp9dsp_init_arm(VP9DSPContext *dsp, int bpp); -void ff_vp9dsp_init_x86(VP9DSPContext *dsp, int bpp, int bitexact); -void ff_vp9dsp_init_mips(VP9DSPContext *dsp, int bpp); - -#endif /* AVCODEC_VP9DSP_H */ diff --git a/libavcodec/vp9dsp_template.c b/libavcodec/vp9dsp_template.c index bb54561a60b33..01b08cd349a70 100644 --- a/libavcodec/vp9dsp_template.c +++ b/libavcodec/vp9dsp_template.c @@ -23,7 +23,7 @@ #include "libavutil/common.h" #include "bit_depth_template.c" -#include "vp9dsp.h" +#include "vp9.h" #if BIT_DEPTH != 12 diff --git a/libavcodec/vp9mvs.c b/libavcodec/vp9mvs.c new file mode 100644 index 0000000000000..d78096be540a2 --- /dev/null +++ b/libavcodec/vp9mvs.c @@ -0,0 +1,361 @@ +/* + * VP9 compatible video decoder + * + * Copyright (C) 2013 Ronald S. Bultje + * Copyright (C) 2013 Clément Bœsch + * + * 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 "internal.h" +#include "vp56.h" +#include "vp9.h" +#include "vp9data.h" + +static av_always_inline void clamp_mv(VP56mv *dst, const VP56mv *src, + VP9Context *s) +{ + dst->x = av_clip(src->x, s->min_mv.x, s->max_mv.x); + dst->y = av_clip(src->y, s->min_mv.y, s->max_mv.y); +} + +static void find_ref_mvs(VP9Context *s, + VP56mv *pmv, int ref, int z, int idx, int sb) +{ + static const int8_t mv_ref_blk_off[N_BS_SIZES][8][2] = { + [BS_64x64] = {{ 3, -1 }, { -1, 3 }, { 4, -1 }, { -1, 4 }, + { -1, -1 }, { 0, -1 }, { -1, 0 }, { 6, -1 }}, + [BS_64x32] = {{ 0, -1 }, { -1, 0 }, { 4, -1 }, { -1, 2 }, + { -1, -1 }, { 0, -3 }, { -3, 0 }, { 2, -1 }}, + [BS_32x64] = {{ -1, 0 }, { 0, -1 }, { -1, 4 }, { 2, -1 }, + { -1, -1 }, { -3, 0 }, { 0, -3 }, { -1, 2 }}, + [BS_32x32] = {{ 1, -1 }, { -1, 1 }, { 2, -1 }, { -1, 2 }, + { -1, -1 }, { 0, -3 }, { -3, 0 }, { -3, -3 }}, + [BS_32x16] = {{ 0, -1 }, { -1, 0 }, { 2, -1 }, { -1, -1 }, + { -1, 1 }, { 0, -3 }, { -3, 0 }, { -3, -3 }}, + [BS_16x32] = {{ -1, 0 }, { 0, -1 }, { -1, 2 }, { -1, -1 }, + { 1, -1 }, { -3, 0 }, { 0, -3 }, { -3, -3 }}, + [BS_16x16] = {{ 0, -1 }, { -1, 0 }, { 1, -1 }, { -1, 1 }, + { -1, -1 }, { 0, -3 }, { -3, 0 }, { -3, -3 }}, + [BS_16x8] = {{ 0, -1 }, { -1, 0 }, { 1, -1 }, { -1, -1 }, + { 0, -2 }, { -2, 0 }, { -2, -1 }, { -1, -2 }}, + [BS_8x16] = {{ -1, 0 }, { 0, -1 }, { -1, 1 }, { -1, -1 }, + { -2, 0 }, { 0, -2 }, { -1, -2 }, { -2, -1 }}, + [BS_8x8] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, + { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }}, + [BS_8x4] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, + { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }}, + [BS_4x8] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, + { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }}, + [BS_4x4] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, + { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }}, + }; + VP9Block *b = s->b; + int row = s->row, col = s->col, row7 = s->row7; + const int8_t (*p)[2] = mv_ref_blk_off[b->bs]; +#define INVALID_MV 0x80008000U + uint32_t mem = INVALID_MV, mem_sub8x8 = INVALID_MV; + int i; + +#define RETURN_DIRECT_MV(mv) \ + do { \ + uint32_t m = AV_RN32A(&mv); \ + if (!idx) { \ + AV_WN32A(pmv, m); \ + return; \ + } else if (mem == INVALID_MV) { \ + mem = m; \ + } else if (m != mem) { \ + AV_WN32A(pmv, m); \ + return; \ + } \ + } while (0) + + if (sb >= 0) { + if (sb == 2 || sb == 1) { + RETURN_DIRECT_MV(b->mv[0][z]); + } else if (sb == 3) { + RETURN_DIRECT_MV(b->mv[2][z]); + RETURN_DIRECT_MV(b->mv[1][z]); + RETURN_DIRECT_MV(b->mv[0][z]); + } + +#define RETURN_MV(mv) \ + do { \ + if (sb > 0) { \ + VP56mv tmp; \ + uint32_t m; \ + av_assert2(idx == 1); \ + av_assert2(mem != INVALID_MV); \ + if (mem_sub8x8 == INVALID_MV) { \ + clamp_mv(&tmp, &mv, s); \ + m = AV_RN32A(&tmp); \ + if (m != mem) { \ + AV_WN32A(pmv, m); \ + return; \ + } \ + mem_sub8x8 = AV_RN32A(&mv); \ + } else if (mem_sub8x8 != AV_RN32A(&mv)) { \ + clamp_mv(&tmp, &mv, s); \ + m = AV_RN32A(&tmp); \ + if (m != mem) { \ + AV_WN32A(pmv, m); \ + } else { \ + /* BUG I'm pretty sure this isn't the intention */ \ + AV_WN32A(pmv, 0); \ + } \ + return; \ + } \ + } else { \ + uint32_t m = AV_RN32A(&mv); \ + if (!idx) { \ + clamp_mv(pmv, &mv, s); \ + return; \ + } else if (mem == INVALID_MV) { \ + mem = m; \ + } else if (m != mem) { \ + clamp_mv(pmv, &mv, s); \ + return; \ + } \ + } \ + } while (0) + + if (row > 0) { + struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[(row - 1) * s->sb_cols * 8 + col]; + if (mv->ref[0] == ref) { + RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][0]); + } else if (mv->ref[1] == ref) { + RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][1]); + } + } + if (col > s->tile_col_start) { + struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[row * s->sb_cols * 8 + col - 1]; + if (mv->ref[0] == ref) { + RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][0]); + } else if (mv->ref[1] == ref) { + RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][1]); + } + } + i = 2; + } else { + i = 0; + } + + // previously coded MVs in this neighbourhood, using same reference frame + for (; i < 8; i++) { + int c = p[i][0] + col, r = p[i][1] + row; + + if (c >= s->tile_col_start && c < s->cols && r >= 0 && r < s->rows) { + struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c]; + + if (mv->ref[0] == ref) { + RETURN_MV(mv->mv[0]); + } else if (mv->ref[1] == ref) { + RETURN_MV(mv->mv[1]); + } + } + } + + // MV at this position in previous frame, using same reference frame + if (s->s.h.use_last_frame_mvs) { + struct VP9mvrefPair *mv = &s->s.frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col]; + + if (!s->s.frames[REF_FRAME_MVPAIR].uses_2pass) + ff_thread_await_progress(&s->s.frames[REF_FRAME_MVPAIR].tf, row >> 3, 0); + if (mv->ref[0] == ref) { + RETURN_MV(mv->mv[0]); + } else if (mv->ref[1] == ref) { + RETURN_MV(mv->mv[1]); + } + } + +#define RETURN_SCALE_MV(mv, scale) \ + do { \ + if (scale) { \ + VP56mv mv_temp = { -mv.x, -mv.y }; \ + RETURN_MV(mv_temp); \ + } else { \ + RETURN_MV(mv); \ + } \ + } while (0) + + // previously coded MVs in this neighbourhood, using different reference frame + for (i = 0; i < 8; i++) { + int c = p[i][0] + col, r = p[i][1] + row; + + if (c >= s->tile_col_start && c < s->cols && r >= 0 && r < s->rows) { + struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c]; + + if (mv->ref[0] != ref && mv->ref[0] >= 0) { + RETURN_SCALE_MV(mv->mv[0], s->s.h.signbias[mv->ref[0]] != s->s.h.signbias[ref]); + } + if (mv->ref[1] != ref && mv->ref[1] >= 0 && + // BUG - libvpx has this condition regardless of whether + // we used the first ref MV and pre-scaling + AV_RN32A(&mv->mv[0]) != AV_RN32A(&mv->mv[1])) { + RETURN_SCALE_MV(mv->mv[1], s->s.h.signbias[mv->ref[1]] != s->s.h.signbias[ref]); + } + } + } + + // MV at this position in previous frame, using different reference frame + if (s->s.h.use_last_frame_mvs) { + struct VP9mvrefPair *mv = &s->s.frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col]; + + // no need to await_progress, because we already did that above + if (mv->ref[0] != ref && mv->ref[0] >= 0) { + RETURN_SCALE_MV(mv->mv[0], s->s.h.signbias[mv->ref[0]] != s->s.h.signbias[ref]); + } + if (mv->ref[1] != ref && mv->ref[1] >= 0 && + // BUG - libvpx has this condition regardless of whether + // we used the first ref MV and pre-scaling + AV_RN32A(&mv->mv[0]) != AV_RN32A(&mv->mv[1])) { + RETURN_SCALE_MV(mv->mv[1], s->s.h.signbias[mv->ref[1]] != s->s.h.signbias[ref]); + } + } + + AV_ZERO32(pmv); + clamp_mv(pmv, pmv, s); +#undef INVALID_MV +#undef RETURN_MV +#undef RETURN_SCALE_MV +} + +static av_always_inline int read_mv_component(VP9Context *s, int idx, int hp) +{ + int bit, sign = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].sign); + int n, c = vp8_rac_get_tree(&s->c, ff_vp9_mv_class_tree, + s->prob.p.mv_comp[idx].classes); + + s->counts.mv_comp[idx].sign[sign]++; + s->counts.mv_comp[idx].classes[c]++; + if (c) { + int m; + + for (n = 0, m = 0; m < c; m++) { + bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].bits[m]); + n |= bit << m; + s->counts.mv_comp[idx].bits[m][bit]++; + } + n <<= 3; + bit = vp8_rac_get_tree(&s->c, ff_vp9_mv_fp_tree, s->prob.p.mv_comp[idx].fp); + n |= bit << 1; + s->counts.mv_comp[idx].fp[bit]++; + if (hp) { + bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].hp); + s->counts.mv_comp[idx].hp[bit]++; + n |= bit; + } else { + n |= 1; + // bug in libvpx - we count for bw entropy purposes even if the + // bit wasn't coded + s->counts.mv_comp[idx].hp[1]++; + } + n += 8 << c; + } else { + n = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].class0); + s->counts.mv_comp[idx].class0[n]++; + bit = vp8_rac_get_tree(&s->c, ff_vp9_mv_fp_tree, + s->prob.p.mv_comp[idx].class0_fp[n]); + s->counts.mv_comp[idx].class0_fp[n][bit]++; + n = (n << 3) | (bit << 1); + if (hp) { + bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].class0_hp); + s->counts.mv_comp[idx].class0_hp[bit]++; + n |= bit; + } else { + n |= 1; + // bug in libvpx - we count for bw entropy purposes even if the + // bit wasn't coded + s->counts.mv_comp[idx].class0_hp[1]++; + } + } + + return sign ? -(n + 1) : (n + 1); +} + +void ff_vp9_fill_mv(VP9Context *s, VP56mv *mv, int mode, int sb) +{ + VP9Block *b = s->b; + + if (mode == ZEROMV) { + AV_ZERO64(mv); + } else { + int hp; + + // FIXME cache this value and reuse for other subblocks + find_ref_mvs(s, &mv[0], b->ref[0], 0, mode == NEARMV, + mode == NEWMV ? -1 : sb); + // FIXME maybe move this code into find_ref_mvs() + if ((mode == NEWMV || sb == -1) && + !(hp = s->s.h.highprecisionmvs && abs(mv[0].x) < 64 && abs(mv[0].y) < 64)) { + if (mv[0].y & 1) { + if (mv[0].y < 0) + mv[0].y++; + else + mv[0].y--; + } + if (mv[0].x & 1) { + if (mv[0].x < 0) + mv[0].x++; + else + mv[0].x--; + } + } + if (mode == NEWMV) { + enum MVJoint j = vp8_rac_get_tree(&s->c, ff_vp9_mv_joint_tree, + s->prob.p.mv_joint); + + s->counts.mv_joint[j]++; + if (j >= MV_JOINT_V) + mv[0].y += read_mv_component(s, 0, hp); + if (j & 1) + mv[0].x += read_mv_component(s, 1, hp); + } + + if (b->comp) { + // FIXME cache this value and reuse for other subblocks + find_ref_mvs(s, &mv[1], b->ref[1], 1, mode == NEARMV, + mode == NEWMV ? -1 : sb); + if ((mode == NEWMV || sb == -1) && + !(hp = s->s.h.highprecisionmvs && abs(mv[1].x) < 64 && abs(mv[1].y) < 64)) { + if (mv[1].y & 1) { + if (mv[1].y < 0) + mv[1].y++; + else + mv[1].y--; + } + if (mv[1].x & 1) { + if (mv[1].x < 0) + mv[1].x++; + else + mv[1].x--; + } + } + if (mode == NEWMV) { + enum MVJoint j = vp8_rac_get_tree(&s->c, ff_vp9_mv_joint_tree, + s->prob.p.mv_joint); + + s->counts.mv_joint[j]++; + if (j >= MV_JOINT_V) + mv[1].y += read_mv_component(s, 0, hp); + if (j & 1) + mv[1].x += read_mv_component(s, 1, hp); + } + } + } +} diff --git a/libavcodec/vp9prob.c b/libavcodec/vp9prob.c new file mode 100644 index 0000000000000..948b87eb374a4 --- /dev/null +++ b/libavcodec/vp9prob.c @@ -0,0 +1,265 @@ +/* + * VP9 compatible video decoder + * + * Copyright (C) 2013 Ronald S. Bultje + * Copyright (C) 2013 Clément Bœsch + * + * 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 "vp56.h" +#include "vp9.h" +#include "vp9data.h" + +static av_always_inline void adapt_prob(uint8_t *p, unsigned ct0, unsigned ct1, + int max_count, int update_factor) +{ + unsigned ct = ct0 + ct1, p2, p1; + + if (!ct) + return; + + update_factor = FASTDIV(update_factor * FFMIN(ct, max_count), max_count); + p1 = *p; + p2 = ((((int64_t) ct0) << 8) + (ct >> 1)) / ct; + p2 = av_clip(p2, 1, 255); + + // (p1 * (256 - update_factor) + p2 * update_factor + 128) >> 8 + *p = p1 + (((p2 - p1) * update_factor + 128) >> 8); +} + +void ff_vp9_adapt_probs(VP9Context *s) +{ + int i, j, k, l, m; + ProbContext *p = &s->prob_ctx[s->s.h.framectxid].p; + int uf = (s->s.h.keyframe || s->s.h.intraonly || !s->last_keyframe) ? 112 : 128; + + // coefficients + for (i = 0; i < 4; i++) + for (j = 0; j < 2; j++) + for (k = 0; k < 2; k++) + for (l = 0; l < 6; l++) + for (m = 0; m < 6; m++) { + uint8_t *pp = s->prob_ctx[s->s.h.framectxid].coef[i][j][k][l][m]; + unsigned *e = s->counts.eob[i][j][k][l][m]; + unsigned *c = s->counts.coef[i][j][k][l][m]; + + if (l == 0 && m >= 3) // dc only has 3 pt + break; + + adapt_prob(&pp[0], e[0], e[1], 24, uf); + adapt_prob(&pp[1], c[0], c[1] + c[2], 24, uf); + adapt_prob(&pp[2], c[1], c[2], 24, uf); + } + + if (s->s.h.keyframe || s->s.h.intraonly) { + memcpy(p->skip, s->prob.p.skip, sizeof(p->skip)); + memcpy(p->tx32p, s->prob.p.tx32p, sizeof(p->tx32p)); + memcpy(p->tx16p, s->prob.p.tx16p, sizeof(p->tx16p)); + memcpy(p->tx8p, s->prob.p.tx8p, sizeof(p->tx8p)); + return; + } + + // skip flag + for (i = 0; i < 3; i++) + adapt_prob(&p->skip[i], s->counts.skip[i][0], s->counts.skip[i][1], 20, 128); + + // intra/inter flag + for (i = 0; i < 4; i++) + adapt_prob(&p->intra[i], s->counts.intra[i][0], s->counts.intra[i][1], 20, 128); + + // comppred flag + if (s->s.h.comppredmode == PRED_SWITCHABLE) { + for (i = 0; i < 5; i++) + adapt_prob(&p->comp[i], s->counts.comp[i][0], s->counts.comp[i][1], 20, 128); + } + + // reference frames + if (s->s.h.comppredmode != PRED_SINGLEREF) { + for (i = 0; i < 5; i++) + adapt_prob(&p->comp_ref[i], s->counts.comp_ref[i][0], + s->counts.comp_ref[i][1], 20, 128); + } + + if (s->s.h.comppredmode != PRED_COMPREF) { + for (i = 0; i < 5; i++) { + uint8_t *pp = p->single_ref[i]; + unsigned (*c)[2] = s->counts.single_ref[i]; + + adapt_prob(&pp[0], c[0][0], c[0][1], 20, 128); + adapt_prob(&pp[1], c[1][0], c[1][1], 20, 128); + } + } + + // block partitioning + for (i = 0; i < 4; i++) + for (j = 0; j < 4; j++) { + uint8_t *pp = p->partition[i][j]; + unsigned *c = s->counts.partition[i][j]; + + adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); + adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); + adapt_prob(&pp[2], c[2], c[3], 20, 128); + } + + // tx size + if (s->s.h.txfmmode == TX_SWITCHABLE) { + for (i = 0; i < 2; i++) { + unsigned *c16 = s->counts.tx16p[i], *c32 = s->counts.tx32p[i]; + + adapt_prob(&p->tx8p[i], s->counts.tx8p[i][0], s->counts.tx8p[i][1], 20, 128); + adapt_prob(&p->tx16p[i][0], c16[0], c16[1] + c16[2], 20, 128); + adapt_prob(&p->tx16p[i][1], c16[1], c16[2], 20, 128); + adapt_prob(&p->tx32p[i][0], c32[0], c32[1] + c32[2] + c32[3], 20, 128); + adapt_prob(&p->tx32p[i][1], c32[1], c32[2] + c32[3], 20, 128); + adapt_prob(&p->tx32p[i][2], c32[2], c32[3], 20, 128); + } + } + + // interpolation filter + if (s->s.h.filtermode == FILTER_SWITCHABLE) { + for (i = 0; i < 4; i++) { + uint8_t *pp = p->filter[i]; + unsigned *c = s->counts.filter[i]; + + adapt_prob(&pp[0], c[0], c[1] + c[2], 20, 128); + adapt_prob(&pp[1], c[1], c[2], 20, 128); + } + } + + // inter modes + for (i = 0; i < 7; i++) { + uint8_t *pp = p->mv_mode[i]; + unsigned *c = s->counts.mv_mode[i]; + + adapt_prob(&pp[0], c[2], c[1] + c[0] + c[3], 20, 128); + adapt_prob(&pp[1], c[0], c[1] + c[3], 20, 128); + adapt_prob(&pp[2], c[1], c[3], 20, 128); + } + + // mv joints + { + uint8_t *pp = p->mv_joint; + unsigned *c = s->counts.mv_joint; + + adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); + adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); + adapt_prob(&pp[2], c[2], c[3], 20, 128); + } + + // mv components + for (i = 0; i < 2; i++) { + uint8_t *pp; + unsigned *c, (*c2)[2], sum; + + adapt_prob(&p->mv_comp[i].sign, s->counts.mv_comp[i].sign[0], + s->counts.mv_comp[i].sign[1], 20, 128); + + pp = p->mv_comp[i].classes; + c = s->counts.mv_comp[i].classes; + sum = c[1] + c[2] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9] + c[10]; + adapt_prob(&pp[0], c[0], sum, 20, 128); + sum -= c[1]; + adapt_prob(&pp[1], c[1], sum, 20, 128); + sum -= c[2] + c[3]; + adapt_prob(&pp[2], c[2] + c[3], sum, 20, 128); + adapt_prob(&pp[3], c[2], c[3], 20, 128); + sum -= c[4] + c[5]; + adapt_prob(&pp[4], c[4] + c[5], sum, 20, 128); + adapt_prob(&pp[5], c[4], c[5], 20, 128); + sum -= c[6]; + adapt_prob(&pp[6], c[6], sum, 20, 128); + adapt_prob(&pp[7], c[7] + c[8], c[9] + c[10], 20, 128); + adapt_prob(&pp[8], c[7], c[8], 20, 128); + adapt_prob(&pp[9], c[9], c[10], 20, 128); + + adapt_prob(&p->mv_comp[i].class0, s->counts.mv_comp[i].class0[0], + s->counts.mv_comp[i].class0[1], 20, 128); + pp = p->mv_comp[i].bits; + c2 = s->counts.mv_comp[i].bits; + for (j = 0; j < 10; j++) + adapt_prob(&pp[j], c2[j][0], c2[j][1], 20, 128); + + for (j = 0; j < 2; j++) { + pp = p->mv_comp[i].class0_fp[j]; + c = s->counts.mv_comp[i].class0_fp[j]; + adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); + adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); + adapt_prob(&pp[2], c[2], c[3], 20, 128); + } + pp = p->mv_comp[i].fp; + c = s->counts.mv_comp[i].fp; + adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); + adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); + adapt_prob(&pp[2], c[2], c[3], 20, 128); + + if (s->s.h.highprecisionmvs) { + adapt_prob(&p->mv_comp[i].class0_hp, s->counts.mv_comp[i].class0_hp[0], + s->counts.mv_comp[i].class0_hp[1], 20, 128); + adapt_prob(&p->mv_comp[i].hp, s->counts.mv_comp[i].hp[0], + s->counts.mv_comp[i].hp[1], 20, 128); + } + } + + // y intra modes + for (i = 0; i < 4; i++) { + uint8_t *pp = p->y_mode[i]; + unsigned *c = s->counts.y_mode[i], sum, s2; + + sum = c[0] + c[1] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9]; + adapt_prob(&pp[0], c[DC_PRED], sum, 20, 128); + sum -= c[TM_VP8_PRED]; + adapt_prob(&pp[1], c[TM_VP8_PRED], sum, 20, 128); + sum -= c[VERT_PRED]; + adapt_prob(&pp[2], c[VERT_PRED], sum, 20, 128); + s2 = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED]; + sum -= s2; + adapt_prob(&pp[3], s2, sum, 20, 128); + s2 -= c[HOR_PRED]; + adapt_prob(&pp[4], c[HOR_PRED], s2, 20, 128); + adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED], 20, 128); + sum -= c[DIAG_DOWN_LEFT_PRED]; + adapt_prob(&pp[6], c[DIAG_DOWN_LEFT_PRED], sum, 20, 128); + sum -= c[VERT_LEFT_PRED]; + adapt_prob(&pp[7], c[VERT_LEFT_PRED], sum, 20, 128); + adapt_prob(&pp[8], c[HOR_DOWN_PRED], c[HOR_UP_PRED], 20, 128); + } + + // uv intra modes + for (i = 0; i < 10; i++) { + uint8_t *pp = p->uv_mode[i]; + unsigned *c = s->counts.uv_mode[i], sum, s2; + + sum = c[0] + c[1] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9]; + adapt_prob(&pp[0], c[DC_PRED], sum, 20, 128); + sum -= c[TM_VP8_PRED]; + adapt_prob(&pp[1], c[TM_VP8_PRED], sum, 20, 128); + sum -= c[VERT_PRED]; + adapt_prob(&pp[2], c[VERT_PRED], sum, 20, 128); + s2 = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED]; + sum -= s2; + adapt_prob(&pp[3], s2, sum, 20, 128); + s2 -= c[HOR_PRED]; + adapt_prob(&pp[4], c[HOR_PRED], s2, 20, 128); + adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED], 20, 128); + sum -= c[DIAG_DOWN_LEFT_PRED]; + adapt_prob(&pp[6], c[DIAG_DOWN_LEFT_PRED], sum, 20, 128); + sum -= c[VERT_LEFT_PRED]; + adapt_prob(&pp[7], c[VERT_LEFT_PRED], sum, 20, 128); + adapt_prob(&pp[8], c[HOR_DOWN_PRED], c[HOR_UP_PRED], 20, 128); + } +} diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c index 66363d46ad981..ae543771b0312 100644 --- a/libavcodec/x86/vp9dsp_init.c +++ b/libavcodec/x86/vp9dsp_init.c @@ -24,7 +24,7 @@ #include "libavutil/cpu.h" #include "libavutil/mem.h" #include "libavutil/x86/cpu.h" -#include "libavcodec/vp9dsp.h" +#include "libavcodec/vp9.h" #include "libavcodec/x86/vp9dsp_init.h" #if HAVE_YASM diff --git a/libavcodec/x86/vp9dsp_init.h b/libavcodec/x86/vp9dsp_init.h index e410cab3a12b6..016dc7f28358c 100644 --- a/libavcodec/x86/vp9dsp_init.h +++ b/libavcodec/x86/vp9dsp_init.h @@ -23,7 +23,7 @@ #ifndef AVCODEC_X86_VP9DSP_INIT_H #define AVCODEC_X86_VP9DSP_INIT_H -#include "libavcodec/vp9dsp.h" +#include "libavcodec/vp9.h" // hack to force-expand BPC #define cat(a, bpp, b) a##bpp##b diff --git a/libavcodec/x86/vp9dsp_init_16bpp.c b/libavcodec/x86/vp9dsp_init_16bpp.c index 4576ff16922ca..17aad50c60064 100644 --- a/libavcodec/x86/vp9dsp_init_16bpp.c +++ b/libavcodec/x86/vp9dsp_init_16bpp.c @@ -24,7 +24,7 @@ #include "libavutil/cpu.h" #include "libavutil/mem.h" #include "libavutil/x86/cpu.h" -#include "libavcodec/vp9dsp.h" +#include "libavcodec/vp9.h" #include "libavcodec/x86/vp9dsp_init.h" #if HAVE_YASM diff --git a/libavcodec/x86/vp9dsp_init_16bpp_template.c b/libavcodec/x86/vp9dsp_init_16bpp_template.c index 4840b2844e3a3..6f37e4b35a2d1 100644 --- a/libavcodec/x86/vp9dsp_init_16bpp_template.c +++ b/libavcodec/x86/vp9dsp_init_16bpp_template.c @@ -24,7 +24,7 @@ #include "libavutil/cpu.h" #include "libavutil/mem.h" #include "libavutil/x86/cpu.h" -#include "libavcodec/vp9dsp.h" +#include "libavcodec/vp9.h" #include "libavcodec/x86/vp9dsp_init.h" #if HAVE_YASM diff --git a/tests/checkasm/vp9dsp.c b/tests/checkasm/vp9dsp.c index 481730966bf17..a91577b94ed00 100644 --- a/tests/checkasm/vp9dsp.c +++ b/tests/checkasm/vp9dsp.c @@ -22,7 +22,7 @@ #include #include "checkasm.h" #include "libavcodec/vp9data.h" -#include "libavcodec/vp9dsp.h" +#include "libavcodec/vp9.h" #include "libavutil/common.h" #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" @@ -259,7 +259,7 @@ static int copy_subcoefs(int16_t *out, const int16_t *in, enum TxfmMode tx, // test int n; - const int16_t *scan = vp9_scans[tx][txtp]; + const int16_t *scan = ff_vp9_scans[tx][txtp]; int eob; for (n = 0; n < sz * sz; n++) { From 12c44d637382cb7364cdd6ac72f0ba5776f286e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sat, 25 Mar 2017 12:25:28 +0100 Subject: [PATCH 1324/3374] lavc/vp9: rename ctx to avctx This reduces diff with Libav. It also prevents a potential confusion between the private context and the AVCodecContext. --- libavcodec/vp9.c | 282 +++++++++++++++++------------------ libavcodec/vp9_mc_template.c | 4 +- libavcodec/vp9block.c | 66 ++++---- 3 files changed, 176 insertions(+), 176 deletions(-) diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 16f4c0d0f41c7..a075a625ee127 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -36,21 +36,21 @@ #define VP9_SYNCCODE 0x498342 -static void vp9_unref_frame(AVCodecContext *ctx, VP9Frame *f) +static void vp9_unref_frame(AVCodecContext *avctx, VP9Frame *f) { - ff_thread_release_buffer(ctx, &f->tf); + ff_thread_release_buffer(avctx, &f->tf); av_buffer_unref(&f->extradata); av_buffer_unref(&f->hwaccel_priv_buf); f->segmentation_map = NULL; f->hwaccel_picture_private = NULL; } -static int vp9_alloc_frame(AVCodecContext *ctx, VP9Frame *f) +static int vp9_alloc_frame(AVCodecContext *avctx, VP9Frame *f) { - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; int ret, sz; - if ((ret = ff_thread_get_buffer(ctx, &f->tf, AV_GET_BUFFER_FLAG_REF)) < 0) + if ((ret = ff_thread_get_buffer(avctx, &f->tf, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; sz = 64 * s->sb_cols * s->sb_rows; if (!(f->extradata = av_buffer_allocz(sz * (1 + sizeof(struct VP9mvrefPair))))) { @@ -60,8 +60,8 @@ static int vp9_alloc_frame(AVCodecContext *ctx, VP9Frame *f) f->segmentation_map = f->extradata->data; f->mv = (struct VP9mvrefPair *) (f->extradata->data + sz); - if (ctx->hwaccel) { - const AVHWAccel *hwaccel = ctx->hwaccel; + if (avctx->hwaccel) { + const AVHWAccel *hwaccel = avctx->hwaccel; av_assert0(!f->hwaccel_picture_private); if (hwaccel->frame_priv_data_size) { f->hwaccel_priv_buf = av_buffer_allocz(hwaccel->frame_priv_data_size); @@ -74,11 +74,11 @@ static int vp9_alloc_frame(AVCodecContext *ctx, VP9Frame *f) return 0; fail: - vp9_unref_frame(ctx, f); + vp9_unref_frame(avctx, f); return AVERROR(ENOMEM); } -static int vp9_ref_frame(AVCodecContext *ctx, VP9Frame *dst, VP9Frame *src) +static int vp9_ref_frame(AVCodecContext *avctx, VP9Frame *dst, VP9Frame *src) { int res; @@ -102,22 +102,22 @@ static int vp9_ref_frame(AVCodecContext *ctx, VP9Frame *dst, VP9Frame *src) return 0; fail: - vp9_unref_frame(ctx, dst); + vp9_unref_frame(avctx, dst); return AVERROR(ENOMEM); } -static int update_size(AVCodecContext *ctx, int w, int h) +static int update_size(AVCodecContext *avctx, int w, int h) { #define HWACCEL_MAX (CONFIG_VP9_DXVA2_HWACCEL + CONFIG_VP9_D3D11VA_HWACCEL + CONFIG_VP9_VAAPI_HWACCEL) enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmtp = pix_fmts; - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; uint8_t *p; int bytesperpixel = s->bytesperpixel, res, cols, rows; av_assert0(w > 0 && h > 0); if (!(s->pix_fmt == s->gf_fmt && w == s->w && h == s->h)) { - if ((res = ff_set_dimensions(ctx, w, h)) < 0) + if ((res = ff_set_dimensions(avctx, w, h)) < 0) return res; switch (s->pix_fmt) { @@ -143,11 +143,11 @@ static int update_size(AVCodecContext *ctx, int w, int h) *fmtp++ = s->pix_fmt; *fmtp = AV_PIX_FMT_NONE; - res = ff_thread_get_format(ctx, pix_fmts); + res = ff_thread_get_format(avctx, pix_fmts); if (res < 0) return res; - ctx->pix_fmt = res; + avctx->pix_fmt = res; s->gf_fmt = s->pix_fmt; s->w = w; s->h = h; @@ -197,7 +197,7 @@ static int update_size(AVCodecContext *ctx, int w, int h) av_freep(&s->block_base); if (s->s.h.bpp != s->last_bpp) { - ff_vp9dsp_init(&s->dsp, s->s.h.bpp, ctx->flags & AV_CODEC_FLAG_BITEXACT); + ff_vp9dsp_init(&s->dsp, s->s.h.bpp, avctx->flags & AV_CODEC_FLAG_BITEXACT); ff_videodsp_init(&s->vdsp, s->s.h.bpp); s->last_bpp = s->s.h.bpp; } @@ -205,9 +205,9 @@ static int update_size(AVCodecContext *ctx, int w, int h) return 0; } -static int update_block_buffers(AVCodecContext *ctx) +static int update_block_buffers(AVCodecContext *avctx) { - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; int chroma_blocks, chroma_eobs, bytesperpixel = s->bytesperpixel; if (s->b_base && s->block_base && s->block_alloc_using_2pass == s->s.frames[CUR_FRAME].uses_2pass) @@ -318,34 +318,34 @@ static int update_prob(VP56RangeCoder *c, int p) 255 - inv_recenter_nonneg(inv_map_table[d], 255 - p); } -static int read_colorspace_details(AVCodecContext *ctx) +static int read_colorspace_details(AVCodecContext *avctx) { static const enum AVColorSpace colorspaces[8] = { AVCOL_SPC_UNSPECIFIED, AVCOL_SPC_BT470BG, AVCOL_SPC_BT709, AVCOL_SPC_SMPTE170M, AVCOL_SPC_SMPTE240M, AVCOL_SPC_BT2020_NCL, AVCOL_SPC_RESERVED, AVCOL_SPC_RGB, }; - VP9Context *s = ctx->priv_data; - int bits = ctx->profile <= 1 ? 0 : 1 + get_bits1(&s->gb); // 0:8, 1:10, 2:12 + VP9Context *s = avctx->priv_data; + int bits = avctx->profile <= 1 ? 0 : 1 + get_bits1(&s->gb); // 0:8, 1:10, 2:12 s->bpp_index = bits; s->s.h.bpp = 8 + bits * 2; s->bytesperpixel = (7 + s->s.h.bpp) >> 3; - ctx->colorspace = colorspaces[get_bits(&s->gb, 3)]; - if (ctx->colorspace == AVCOL_SPC_RGB) { // RGB = profile 1 + avctx->colorspace = colorspaces[get_bits(&s->gb, 3)]; + if (avctx->colorspace == AVCOL_SPC_RGB) { // RGB = profile 1 static const enum AVPixelFormat pix_fmt_rgb[3] = { AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12 }; s->ss_h = s->ss_v = 0; - ctx->color_range = AVCOL_RANGE_JPEG; + avctx->color_range = AVCOL_RANGE_JPEG; s->pix_fmt = pix_fmt_rgb[bits]; - if (ctx->profile & 1) { + if (avctx->profile & 1) { if (get_bits1(&s->gb)) { - av_log(ctx, AV_LOG_ERROR, "Reserved bit set in RGB\n"); + av_log(avctx, AV_LOG_ERROR, "Reserved bit set in RGB\n"); return AVERROR_INVALIDDATA; } } else { - av_log(ctx, AV_LOG_ERROR, "RGB not supported in profile %d\n", - ctx->profile); + av_log(avctx, AV_LOG_ERROR, "RGB not supported in profile %d\n", + avctx->profile); return AVERROR_INVALIDDATA; } } else { @@ -357,18 +357,18 @@ static int read_colorspace_details(AVCodecContext *ctx) { { AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12 }, { AV_PIX_FMT_YUV440P12, AV_PIX_FMT_YUV420P12 } } }; - ctx->color_range = get_bits1(&s->gb) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; - if (ctx->profile & 1) { + avctx->color_range = get_bits1(&s->gb) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; + if (avctx->profile & 1) { s->ss_h = get_bits1(&s->gb); s->ss_v = get_bits1(&s->gb); s->pix_fmt = pix_fmt_for_ss[bits][s->ss_v][s->ss_h]; if (s->pix_fmt == AV_PIX_FMT_YUV420P) { - av_log(ctx, AV_LOG_ERROR, "YUV 4:2:0 not supported in profile %d\n", - ctx->profile); + av_log(avctx, AV_LOG_ERROR, "YUV 4:2:0 not supported in profile %d\n", + avctx->profile); return AVERROR_INVALIDDATA; } else if (get_bits1(&s->gb)) { - av_log(ctx, AV_LOG_ERROR, "Profile %d color details reserved bit set\n", - ctx->profile); + av_log(avctx, AV_LOG_ERROR, "Profile %d color details reserved bit set\n", + avctx->profile); return AVERROR_INVALIDDATA; } } else { @@ -380,31 +380,31 @@ static int read_colorspace_details(AVCodecContext *ctx) return 0; } -static int decode_frame_header(AVCodecContext *ctx, +static int decode_frame_header(AVCodecContext *avctx, const uint8_t *data, int size, int *ref) { - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; int c, i, j, k, l, m, n, w, h, max, size2, res, sharp; int last_invisible; const uint8_t *data2; /* general header */ if ((res = init_get_bits8(&s->gb, data, size)) < 0) { - av_log(ctx, AV_LOG_ERROR, "Failed to initialize bitstream reader\n"); + av_log(avctx, AV_LOG_ERROR, "Failed to initialize bitstream reader\n"); return res; } if (get_bits(&s->gb, 2) != 0x2) { // frame marker - av_log(ctx, AV_LOG_ERROR, "Invalid frame marker\n"); + av_log(avctx, AV_LOG_ERROR, "Invalid frame marker\n"); return AVERROR_INVALIDDATA; } - ctx->profile = get_bits1(&s->gb); - ctx->profile |= get_bits1(&s->gb) << 1; - if (ctx->profile == 3) ctx->profile += get_bits1(&s->gb); - if (ctx->profile > 3) { - av_log(ctx, AV_LOG_ERROR, "Profile %d is not yet supported\n", ctx->profile); + avctx->profile = get_bits1(&s->gb); + avctx->profile |= get_bits1(&s->gb) << 1; + if (avctx->profile == 3) avctx->profile += get_bits1(&s->gb); + if (avctx->profile > 3) { + av_log(avctx, AV_LOG_ERROR, "Profile %d is not yet supported\n", avctx->profile); return AVERROR_INVALIDDATA; } - s->s.h.profile = ctx->profile; + s->s.h.profile = avctx->profile; if (get_bits1(&s->gb)) { *ref = get_bits(&s->gb, 3); return 0; @@ -417,10 +417,10 @@ static int decode_frame_header(AVCodecContext *ctx, s->s.h.use_last_frame_mvs = !s->s.h.errorres && !last_invisible; if (s->s.h.keyframe) { if (get_bits_long(&s->gb, 24) != VP9_SYNCCODE) { // synccode - av_log(ctx, AV_LOG_ERROR, "Invalid sync code\n"); + av_log(avctx, AV_LOG_ERROR, "Invalid sync code\n"); return AVERROR_INVALIDDATA; } - if ((res = read_colorspace_details(ctx)) < 0) + if ((res = read_colorspace_details(avctx)) < 0) return res; // for profile 1, here follows the subsampling bits s->s.h.refreshrefmask = 0xff; @@ -433,11 +433,11 @@ static int decode_frame_header(AVCodecContext *ctx, s->s.h.resetctx = s->s.h.errorres ? 0 : get_bits(&s->gb, 2); if (s->s.h.intraonly) { if (get_bits_long(&s->gb, 24) != VP9_SYNCCODE) { // synccode - av_log(ctx, AV_LOG_ERROR, "Invalid sync code\n"); + av_log(avctx, AV_LOG_ERROR, "Invalid sync code\n"); return AVERROR_INVALIDDATA; } - if (ctx->profile >= 1) { - if ((res = read_colorspace_details(ctx)) < 0) + if (avctx->profile >= 1) { + if ((res = read_colorspace_details(avctx)) < 0) return res; } else { s->ss_h = s->ss_v = 1; @@ -445,8 +445,8 @@ static int decode_frame_header(AVCodecContext *ctx, s->bpp_index = 0; s->bytesperpixel = 1; s->pix_fmt = AV_PIX_FMT_YUV420P; - ctx->colorspace = AVCOL_SPC_BT470BG; - ctx->color_range = AVCOL_RANGE_JPEG; + avctx->colorspace = AVCOL_SPC_BT470BG; + avctx->color_range = AVCOL_RANGE_JPEG; } s->s.h.refreshrefmask = get_bits(&s->gb, 8); w = get_bits(&s->gb, 16) + 1; @@ -464,7 +464,7 @@ static int decode_frame_header(AVCodecContext *ctx, if (!s->s.refs[s->s.h.refidx[0]].f->buf[0] || !s->s.refs[s->s.h.refidx[1]].f->buf[0] || !s->s.refs[s->s.h.refidx[2]].f->buf[0]) { - av_log(ctx, AV_LOG_ERROR, "Not all references are available\n"); + av_log(avctx, AV_LOG_ERROR, "Not all references are available\n"); return AVERROR_INVALIDDATA; } if (get_bits1(&s->gb)) { @@ -552,7 +552,7 @@ static int decode_frame_header(AVCodecContext *ctx, s->s.h.lossless = s->s.h.yac_qi == 0 && s->s.h.ydc_qdelta == 0 && s->s.h.uvdc_qdelta == 0 && s->s.h.uvac_qdelta == 0; if (s->s.h.lossless) - ctx->properties |= FF_CODEC_PROPERTY_LOSSLESS; + avctx->properties |= FF_CODEC_PROPERTY_LOSSLESS; /* segmentation header info */ if ((s->s.h.segmentation.enabled = get_bits1(&s->gb))) { @@ -631,8 +631,8 @@ static int decode_frame_header(AVCodecContext *ctx, } /* tiling info */ - if ((res = update_size(ctx, w, h)) < 0) { - av_log(ctx, AV_LOG_ERROR, "Failed to initialize decoder for %dx%d @ %d\n", + if ((res = update_size(avctx, w, h)) < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to initialize decoder for %dx%d @ %d\n", w, h, s->pix_fmt); return res; } @@ -654,7 +654,7 @@ static int decode_frame_header(AVCodecContext *ctx, s->c_b = av_fast_realloc(s->c_b, &s->c_b_size, sizeof(VP56RangeCoder) * s->s.h.tiling.tile_cols); if (!s->c_b) { - av_log(ctx, AV_LOG_ERROR, "Ran out of memory during range coder init\n"); + av_log(avctx, AV_LOG_ERROR, "Ran out of memory during range coder init\n"); return AVERROR(ENOMEM); } } @@ -665,17 +665,17 @@ static int decode_frame_header(AVCodecContext *ctx, AVFrame *ref = s->s.refs[s->s.h.refidx[i]].f; int refw = ref->width, refh = ref->height; - if (ref->format != ctx->pix_fmt) { - av_log(ctx, AV_LOG_ERROR, + if (ref->format != avctx->pix_fmt) { + av_log(avctx, AV_LOG_ERROR, "Ref pixfmt (%s) did not match current frame (%s)", av_get_pix_fmt_name(ref->format), - av_get_pix_fmt_name(ctx->pix_fmt)); + av_get_pix_fmt_name(avctx->pix_fmt)); return AVERROR_INVALIDDATA; } else if (refw == w && refh == h) { s->mvscale[i][0] = s->mvscale[i][1] = 0; } else { if (w * 2 < refw || h * 2 < refh || w > 16 * refw || h > 16 * refh) { - av_log(ctx, AV_LOG_ERROR, + av_log(avctx, AV_LOG_ERROR, "Invalid ref frame dimensions %dx%d for frame size %dx%d\n", refw, refh, w, h); return AVERROR_INVALIDDATA; @@ -711,7 +711,7 @@ static int decode_frame_header(AVCodecContext *ctx, data2 = align_get_bits(&s->gb); if (size2 > size - (data2 - data)) { - av_log(ctx, AV_LOG_ERROR, "Invalid compressed header size\n"); + av_log(avctx, AV_LOG_ERROR, "Invalid compressed header size\n"); return AVERROR_INVALIDDATA; } res = ff_vp56_init_range_decoder(&s->c, data2, size2); @@ -719,7 +719,7 @@ static int decode_frame_header(AVCodecContext *ctx, return res; if (vp56_rac_get_prob_branchy(&s->c, 128)) { // marker bit - av_log(ctx, AV_LOG_ERROR, "Marker bit was set\n"); + av_log(avctx, AV_LOG_ERROR, "Marker bit was set\n"); return AVERROR_INVALIDDATA; } @@ -915,10 +915,10 @@ static int decode_frame_header(AVCodecContext *ctx, return (data2 - data) + size2; } -static void decode_sb(AVCodecContext *ctx, int row, int col, struct VP9Filter *lflvl, +static void decode_sb(AVCodecContext *avctx, int row, int col, struct VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl) { - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; int c = ((s->above_partition_ctx[col] >> (3 - bl)) & 1) | (((s->left_partition_ctx[row & 0x7] >> (3 - bl)) & 1) << 1); const uint8_t *p = s->s.h.keyframe || s->s.h.intraonly ? ff_vp9_default_kf_partition_probs[bl][c] : @@ -931,35 +931,35 @@ static void decode_sb(AVCodecContext *ctx, int row, int col, struct VP9Filter *l if (bl == BL_8X8) { bp = vp8_rac_get_tree(&s->c, ff_vp9_partition_tree, p); - ff_vp9_decode_block(ctx, row, col, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, bl, bp); } else if (col + hbs < s->cols) { // FIXME why not <=? if (row + hbs < s->rows) { // FIXME why not <=? bp = vp8_rac_get_tree(&s->c, ff_vp9_partition_tree, p); switch (bp) { case PARTITION_NONE: - ff_vp9_decode_block(ctx, row, col, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, bl, bp); break; case PARTITION_H: - ff_vp9_decode_block(ctx, row, col, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, bl, bp); yoff += hbs * 8 * y_stride; uvoff += hbs * 8 * uv_stride >> s->ss_v; - ff_vp9_decode_block(ctx, row + hbs, col, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(avctx, row + hbs, col, lflvl, yoff, uvoff, bl, bp); break; case PARTITION_V: - ff_vp9_decode_block(ctx, row, col, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, bl, bp); yoff += hbs * 8 * bytesperpixel; uvoff += hbs * 8 * bytesperpixel >> s->ss_h; - ff_vp9_decode_block(ctx, row, col + hbs, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(avctx, row, col + hbs, lflvl, yoff, uvoff, bl, bp); break; case PARTITION_SPLIT: - decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1); - decode_sb(ctx, row, col + hbs, lflvl, + decode_sb(avctx, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(avctx, row, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel, uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); yoff += hbs * 8 * y_stride; uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_sb(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); - decode_sb(ctx, row + hbs, col + hbs, lflvl, + decode_sb(avctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(avctx, row + hbs, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel, uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); break; @@ -968,36 +968,36 @@ static void decode_sb(AVCodecContext *ctx, int row, int col, struct VP9Filter *l } } else if (vp56_rac_get_prob_branchy(&s->c, p[1])) { bp = PARTITION_SPLIT; - decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1); - decode_sb(ctx, row, col + hbs, lflvl, + decode_sb(avctx, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(avctx, row, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel, uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); } else { bp = PARTITION_H; - ff_vp9_decode_block(ctx, row, col, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, bl, bp); } } else if (row + hbs < s->rows) { // FIXME why not <=? if (vp56_rac_get_prob_branchy(&s->c, p[2])) { bp = PARTITION_SPLIT; - decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(avctx, row, col, lflvl, yoff, uvoff, bl + 1); yoff += hbs * 8 * y_stride; uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_sb(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(avctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); } else { bp = PARTITION_V; - ff_vp9_decode_block(ctx, row, col, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, bl, bp); } } else { bp = PARTITION_SPLIT; - decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(avctx, row, col, lflvl, yoff, uvoff, bl + 1); } s->counts.partition[bl][c][bp]++; } -static void decode_sb_mem(AVCodecContext *ctx, int row, int col, struct VP9Filter *lflvl, +static void decode_sb_mem(AVCodecContext *avctx, int row, int col, struct VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl) { - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; VP9Block *b = s->b; ptrdiff_t hbs = 4 >> bl; AVFrame *f = s->s.frames[CUR_FRAME].tf.f; @@ -1006,39 +1006,39 @@ static void decode_sb_mem(AVCodecContext *ctx, int row, int col, struct VP9Filte if (bl == BL_8X8) { av_assert2(b->bl == BL_8X8); - ff_vp9_decode_block(ctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp); + ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp); } else if (s->b->bl == bl) { - ff_vp9_decode_block(ctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp); + ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp); if (b->bp == PARTITION_H && row + hbs < s->rows) { yoff += hbs * 8 * y_stride; uvoff += hbs * 8 * uv_stride >> s->ss_v; - ff_vp9_decode_block(ctx, row + hbs, col, lflvl, yoff, uvoff, b->bl, b->bp); + ff_vp9_decode_block(avctx, row + hbs, col, lflvl, yoff, uvoff, b->bl, b->bp); } else if (b->bp == PARTITION_V && col + hbs < s->cols) { yoff += hbs * 8 * bytesperpixel; uvoff += hbs * 8 * bytesperpixel >> s->ss_h; - ff_vp9_decode_block(ctx, row, col + hbs, lflvl, yoff, uvoff, b->bl, b->bp); + ff_vp9_decode_block(avctx, row, col + hbs, lflvl, yoff, uvoff, b->bl, b->bp); } } else { - decode_sb_mem(ctx, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb_mem(avctx, row, col, lflvl, yoff, uvoff, bl + 1); if (col + hbs < s->cols) { // FIXME why not <=? if (row + hbs < s->rows) { - decode_sb_mem(ctx, row, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel, + decode_sb_mem(avctx, row, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel, uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); yoff += hbs * 8 * y_stride; uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_sb_mem(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); - decode_sb_mem(ctx, row + hbs, col + hbs, lflvl, + decode_sb_mem(avctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); + decode_sb_mem(avctx, row + hbs, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel, uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); } else { yoff += hbs * 8 * bytesperpixel; uvoff += hbs * 8 * bytesperpixel >> s->ss_h; - decode_sb_mem(ctx, row, col + hbs, lflvl, yoff, uvoff, bl + 1); + decode_sb_mem(avctx, row, col + hbs, lflvl, yoff, uvoff, bl + 1); } } else if (row + hbs < s->rows) { yoff += hbs * 8 * y_stride; uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_sb_mem(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); + decode_sb_mem(avctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); } } } @@ -1195,10 +1195,10 @@ static av_always_inline void filter_plane_rows(VP9Context *s, int row, int ss_h, } } -static void loopfilter_sb(AVCodecContext *ctx, struct VP9Filter *lflvl, +static void loopfilter_sb(AVCodecContext *avctx, struct VP9Filter *lflvl, int row, int col, ptrdiff_t yoff, ptrdiff_t uvoff) { - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; AVFrame *f = s->s.frames[CUR_FRAME].tf.f; uint8_t *dst = f->data[0] + yoff; ptrdiff_t ls_y = f->linesize[0], ls_uv = f->linesize[1]; @@ -1236,22 +1236,22 @@ static void free_buffers(VP9Context *s) av_freep(&s->block_base); } -static av_cold int vp9_decode_free(AVCodecContext *ctx) +static av_cold int vp9_decode_free(AVCodecContext *avctx) { - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; int i; for (i = 0; i < 3; i++) { if (s->s.frames[i].tf.f->buf[0]) - vp9_unref_frame(ctx, &s->s.frames[i]); + vp9_unref_frame(avctx, &s->s.frames[i]); av_frame_free(&s->s.frames[i].tf.f); } for (i = 0; i < 8; i++) { if (s->s.refs[i].f->buf[0]) - ff_thread_release_buffer(ctx, &s->s.refs[i]); + ff_thread_release_buffer(avctx, &s->s.refs[i]); av_frame_free(&s->s.refs[i].f); if (s->next_refs[i].f->buf[0]) - ff_thread_release_buffer(ctx, &s->next_refs[i]); + ff_thread_release_buffer(avctx, &s->next_refs[i]); av_frame_free(&s->next_refs[i].f); } free_buffers(s); @@ -1262,12 +1262,12 @@ static av_cold int vp9_decode_free(AVCodecContext *ctx) } -static int vp9_decode_frame(AVCodecContext *ctx, void *frame, +static int vp9_decode_frame(AVCodecContext *avctx, void *frame, int *got_frame, AVPacket *pkt) { const uint8_t *data = pkt->data; int size = pkt->size; - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; int res, tile_row, tile_col, i, ref, row, col; int retain_segmap_ref = s->s.frames[REF_FRAME_SEGMAP].segmentation_map && (!s->s.h.segmentation.enabled || !s->s.h.segmentation.update_map); @@ -1275,11 +1275,11 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame, AVFrame *f; int bytesperpixel; - if ((res = decode_frame_header(ctx, data, size, &ref)) < 0) { + if ((res = decode_frame_header(avctx, data, size, &ref)) < 0) { return res; } else if (res == 0) { if (!s->s.refs[ref].f->buf[0]) { - av_log(ctx, AV_LOG_ERROR, "Requested reference %d not available\n", ref); + av_log(avctx, AV_LOG_ERROR, "Requested reference %d not available\n", ref); return AVERROR_INVALIDDATA; } if ((res = av_frame_ref(frame, s->s.refs[ref].f)) < 0) @@ -1293,7 +1293,7 @@ FF_ENABLE_DEPRECATION_WARNINGS ((AVFrame *)frame)->pkt_dts = pkt->dts; for (i = 0; i < 8; i++) { if (s->next_refs[i].f->buf[0]) - ff_thread_release_buffer(ctx, &s->next_refs[i]); + ff_thread_release_buffer(avctx, &s->next_refs[i]); if (s->s.refs[i].f->buf[0] && (res = ff_thread_ref_frame(&s->next_refs[i], &s->s.refs[i])) < 0) return res; @@ -1306,19 +1306,19 @@ FF_ENABLE_DEPRECATION_WARNINGS if (!retain_segmap_ref || s->s.h.keyframe || s->s.h.intraonly) { if (s->s.frames[REF_FRAME_SEGMAP].tf.f->buf[0]) - vp9_unref_frame(ctx, &s->s.frames[REF_FRAME_SEGMAP]); + vp9_unref_frame(avctx, &s->s.frames[REF_FRAME_SEGMAP]); if (!s->s.h.keyframe && !s->s.h.intraonly && !s->s.h.errorres && s->s.frames[CUR_FRAME].tf.f->buf[0] && - (res = vp9_ref_frame(ctx, &s->s.frames[REF_FRAME_SEGMAP], &s->s.frames[CUR_FRAME])) < 0) + (res = vp9_ref_frame(avctx, &s->s.frames[REF_FRAME_SEGMAP], &s->s.frames[CUR_FRAME])) < 0) return res; } if (s->s.frames[REF_FRAME_MVPAIR].tf.f->buf[0]) - vp9_unref_frame(ctx, &s->s.frames[REF_FRAME_MVPAIR]); + vp9_unref_frame(avctx, &s->s.frames[REF_FRAME_MVPAIR]); if (!s->s.h.intraonly && !s->s.h.keyframe && !s->s.h.errorres && s->s.frames[CUR_FRAME].tf.f->buf[0] && - (res = vp9_ref_frame(ctx, &s->s.frames[REF_FRAME_MVPAIR], &s->s.frames[CUR_FRAME])) < 0) + (res = vp9_ref_frame(avctx, &s->s.frames[REF_FRAME_MVPAIR], &s->s.frames[CUR_FRAME])) < 0) return res; if (s->s.frames[CUR_FRAME].tf.f->buf[0]) - vp9_unref_frame(ctx, &s->s.frames[CUR_FRAME]); - if ((res = vp9_alloc_frame(ctx, &s->s.frames[CUR_FRAME])) < 0) + vp9_unref_frame(avctx, &s->s.frames[CUR_FRAME]); + if ((res = vp9_alloc_frame(avctx, &s->s.frames[CUR_FRAME])) < 0) return res; f = s->s.frames[CUR_FRAME].tf.f; f->key_frame = s->s.h.keyframe; @@ -1329,13 +1329,13 @@ FF_ENABLE_DEPRECATION_WARNINGS if (s->s.frames[REF_FRAME_SEGMAP].tf.f->buf[0] && (s->s.frames[REF_FRAME_MVPAIR].tf.f->width != s->s.frames[CUR_FRAME].tf.f->width || s->s.frames[REF_FRAME_MVPAIR].tf.f->height != s->s.frames[CUR_FRAME].tf.f->height)) { - vp9_unref_frame(ctx, &s->s.frames[REF_FRAME_SEGMAP]); + vp9_unref_frame(avctx, &s->s.frames[REF_FRAME_SEGMAP]); } // ref frame setup for (i = 0; i < 8; i++) { if (s->next_refs[i].f->buf[0]) - ff_thread_release_buffer(ctx, &s->next_refs[i]); + ff_thread_release_buffer(avctx, &s->next_refs[i]); if (s->s.h.refreshrefmask & (1 << i)) { res = ff_thread_ref_frame(&s->next_refs[i], &s->s.frames[CUR_FRAME].tf); } else if (s->s.refs[i].f->buf[0]) { @@ -1345,14 +1345,14 @@ FF_ENABLE_DEPRECATION_WARNINGS return res; } - if (ctx->hwaccel) { - res = ctx->hwaccel->start_frame(ctx, NULL, 0); + if (avctx->hwaccel) { + res = avctx->hwaccel->start_frame(avctx, NULL, 0); if (res < 0) return res; - res = ctx->hwaccel->decode_slice(ctx, pkt->data, pkt->size); + res = avctx->hwaccel->decode_slice(avctx, pkt->data, pkt->size); if (res < 0) return res; - res = ctx->hwaccel->end_frame(ctx); + res = avctx->hwaccel->end_frame(avctx); if (res < 0) return res; goto finish; @@ -1372,9 +1372,9 @@ FF_ENABLE_DEPRECATION_WARNINGS memset(s->above_uv_nnz_ctx[1], 0, s->sb_cols * 16 >> s->ss_h); memset(s->above_segpred_ctx, 0, s->cols); s->pass = s->s.frames[CUR_FRAME].uses_2pass = - ctx->active_thread_type == FF_THREAD_FRAME && s->s.h.refreshctx && !s->s.h.parallelmode; - if ((res = update_block_buffers(ctx)) < 0) { - av_log(ctx, AV_LOG_ERROR, + avctx->active_thread_type == FF_THREAD_FRAME && s->s.h.refreshctx && !s->s.h.parallelmode; + if ((res = update_block_buffers(avctx)) < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to allocate block buffers\n"); return res; } @@ -1392,9 +1392,9 @@ FF_ENABLE_DEPRECATION_WARNINGS break; } s->prob_ctx[s->s.h.framectxid].p = s->prob.p; - ff_thread_finish_setup(ctx); + ff_thread_finish_setup(avctx); } else if (!s->s.h.refreshctx) { - ff_thread_finish_setup(ctx); + ff_thread_finish_setup(avctx); } do { @@ -1473,10 +1473,10 @@ FF_ENABLE_DEPRECATION_WARNINGS } if (s->pass == 2) { - decode_sb_mem(ctx, row, col, lflvl_ptr, + decode_sb_mem(avctx, row, col, lflvl_ptr, yoff2, uvoff2, BL_64X64); } else { - decode_sb(ctx, row, col, lflvl_ptr, + decode_sb(avctx, row, col, lflvl_ptr, yoff2, uvoff2, BL_64X64); } } @@ -1511,7 +1511,7 @@ FF_ENABLE_DEPRECATION_WARNINGS for (col = 0; col < s->cols; col += 8, yoff2 += 64 * bytesperpixel, uvoff2 += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) { - loopfilter_sb(ctx, lflvl_ptr, row, col, yoff2, uvoff2); + loopfilter_sb(avctx, lflvl_ptr, row, col, yoff2, uvoff2); } } @@ -1524,7 +1524,7 @@ FF_ENABLE_DEPRECATION_WARNINGS if (s->pass < 2 && s->s.h.refreshctx && !s->s.h.parallelmode) { ff_vp9_adapt_probs(s); - ff_thread_finish_setup(ctx); + ff_thread_finish_setup(avctx); } } while (s->pass++ == 1); ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); @@ -1533,7 +1533,7 @@ FF_ENABLE_DEPRECATION_WARNINGS // ref frame setup for (i = 0; i < 8; i++) { if (s->s.refs[i].f->buf[0]) - ff_thread_release_buffer(ctx, &s->s.refs[i]); + ff_thread_release_buffer(avctx, &s->s.refs[i]); if (s->next_refs[i].f->buf[0] && (res = ff_thread_ref_frame(&s->s.refs[i], &s->next_refs[i])) < 0) return res; @@ -1548,27 +1548,27 @@ FF_ENABLE_DEPRECATION_WARNINGS return pkt->size; } -static void vp9_decode_flush(AVCodecContext *ctx) +static void vp9_decode_flush(AVCodecContext *avctx) { - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; int i; for (i = 0; i < 3; i++) - vp9_unref_frame(ctx, &s->s.frames[i]); + vp9_unref_frame(avctx, &s->s.frames[i]); for (i = 0; i < 8; i++) - ff_thread_release_buffer(ctx, &s->s.refs[i]); + ff_thread_release_buffer(avctx, &s->s.refs[i]); } -static int init_frames(AVCodecContext *ctx) +static int init_frames(AVCodecContext *avctx) { - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; int i; for (i = 0; i < 3; i++) { s->s.frames[i].tf.f = av_frame_alloc(); if (!s->s.frames[i].tf.f) { - vp9_decode_free(ctx); - av_log(ctx, AV_LOG_ERROR, "Failed to allocate frame buffer %d\n", i); + vp9_decode_free(avctx); + av_log(avctx, AV_LOG_ERROR, "Failed to allocate frame buffer %d\n", i); return AVERROR(ENOMEM); } } @@ -1576,8 +1576,8 @@ static int init_frames(AVCodecContext *ctx) s->s.refs[i].f = av_frame_alloc(); s->next_refs[i].f = av_frame_alloc(); if (!s->s.refs[i].f || !s->next_refs[i].f) { - vp9_decode_free(ctx); - av_log(ctx, AV_LOG_ERROR, "Failed to allocate frame buffer %d\n", i); + vp9_decode_free(avctx); + av_log(avctx, AV_LOG_ERROR, "Failed to allocate frame buffer %d\n", i); return AVERROR(ENOMEM); } } @@ -1585,15 +1585,15 @@ static int init_frames(AVCodecContext *ctx) return 0; } -static av_cold int vp9_decode_init(AVCodecContext *ctx) +static av_cold int vp9_decode_init(AVCodecContext *avctx) { - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; - ctx->internal->allocate_progress = 1; + avctx->internal->allocate_progress = 1; s->last_bpp = 0; s->s.h.filter.sharpness = -1; - return init_frames(ctx); + return init_frames(avctx); } #if HAVE_THREADS diff --git a/libavcodec/vp9_mc_template.c b/libavcodec/vp9_mc_template.c index e7f226ca90e82..2d1e9bf8fbaf9 100644 --- a/libavcodec/vp9_mc_template.c +++ b/libavcodec/vp9_mc_template.c @@ -27,13 +27,13 @@ (VP56mv) { .x = ROUNDED_DIV(a.x + b.x + c.x + d.x, 4), \ .y = ROUNDED_DIV(a.y + b.y + c.y + d.y, 4) } -static void FN(inter_pred)(AVCodecContext *ctx) +static void FN(inter_pred)(AVCodecContext *avctx) { static const uint8_t bwlog_tab[2][N_BS_SIZES] = { { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 }, { 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4 }, }; - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; VP9Block *b = s->b; int row = s->row, col = s->col; ThreadFrame *tref1 = &s->s.refs[s->s.h.refidx[b->ref[0]]], *tref2; diff --git a/libavcodec/vp9block.c b/libavcodec/vp9block.c index dd135aadf426a..3d57913e5abd1 100644 --- a/libavcodec/vp9block.c +++ b/libavcodec/vp9block.c @@ -86,7 +86,7 @@ static av_always_inline void setctx_2d(uint8_t *ptr, int w, int h, } } -static void decode_mode(AVCodecContext *ctx) +static void decode_mode(AVCodecContext *avctx) { static const uint8_t left_ctx[N_BS_SIZES] = { 0x0, 0x8, 0x0, 0x8, 0xc, 0x8, 0xc, 0xe, 0xc, 0xe, 0xf, 0xe, 0xf @@ -98,7 +98,7 @@ static void decode_mode(AVCodecContext *ctx) TX_32X32, TX_32X32, TX_32X32, TX_32X32, TX_16X16, TX_16X16, TX_16X16, TX_8X8, TX_8X8, TX_8X8, TX_4X4, TX_4X4, TX_4X4 }; - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; VP9Block *b = s->b; int row = s->row, col = s->col, row7 = s->row7; enum TxfmMode max_tx = max_tx_for_bl_bp[b->bs]; @@ -955,9 +955,9 @@ static int decode_coeffs_b32_16bpp(VP9Context *s, int16_t *coef, int n_coeffs, nnz, scan, nb, band_counts, qmul); } -static av_always_inline int decode_coeffs(AVCodecContext *ctx, int is8bitsperpixel) +static av_always_inline int decode_coeffs(AVCodecContext *avctx, int is8bitsperpixel) { - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; VP9Block *b = s->b; int row = s->row, col = s->col; uint8_t (*p)[6][11] = s->prob.coef[b->tx][0 /* y */][!b->intra]; @@ -1122,14 +1122,14 @@ static av_always_inline int decode_coeffs(AVCodecContext *ctx, int is8bitsperpix return total_coeff; } -static int decode_coeffs_8bpp(AVCodecContext *ctx) +static int decode_coeffs_8bpp(AVCodecContext *avctx) { - return decode_coeffs(ctx, 1); + return decode_coeffs(avctx, 1); } -static int decode_coeffs_16bpp(AVCodecContext *ctx) +static int decode_coeffs_16bpp(AVCodecContext *avctx) { - return decode_coeffs(ctx, 0); + return decode_coeffs(avctx, 0); } static av_always_inline int check_intra_mode(VP9Context *s, int mode, uint8_t **a, @@ -1313,10 +1313,10 @@ static av_always_inline int check_intra_mode(VP9Context *s, int mode, uint8_t ** return mode; } -static av_always_inline void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off, +static av_always_inline void intra_recon(AVCodecContext *avctx, ptrdiff_t y_off, ptrdiff_t uv_off, int bytesperpixel) { - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; VP9Block *b = s->b; int row = s->row, col = s->col; int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n; @@ -1383,14 +1383,14 @@ static av_always_inline void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off, } } -static void intra_recon_8bpp(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off) +static void intra_recon_8bpp(AVCodecContext *avctx, ptrdiff_t y_off, ptrdiff_t uv_off) { - intra_recon(ctx, y_off, uv_off, 1); + intra_recon(avctx, y_off, uv_off, 1); } -static void intra_recon_16bpp(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off) +static void intra_recon_16bpp(AVCodecContext *avctx, ptrdiff_t y_off, ptrdiff_t uv_off) { - intra_recon(ctx, y_off, uv_off, 2); + intra_recon(avctx, y_off, uv_off, 2); } static av_always_inline void mc_luma_unscaled(VP9Context *s, vp9_mc_func (*mc)[2], @@ -1660,23 +1660,23 @@ static av_always_inline void mc_chroma_scaled(VP9Context *s, vp9_scaled_mc_func #undef BYTES_PER_PIXEL #undef SCALED -static av_always_inline void inter_recon(AVCodecContext *ctx, int bytesperpixel) +static av_always_inline void inter_recon(AVCodecContext *avctx, int bytesperpixel) { - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; VP9Block *b = s->b; int row = s->row, col = s->col; if (s->mvscale[b->ref[0]][0] || (b->comp && s->mvscale[b->ref[1]][0])) { if (bytesperpixel == 1) { - inter_pred_scaled_8bpp(ctx); + inter_pred_scaled_8bpp(avctx); } else { - inter_pred_scaled_16bpp(ctx); + inter_pred_scaled_16bpp(avctx); } } else { if (bytesperpixel == 1) { - inter_pred_8bpp(ctx); + inter_pred_8bpp(avctx); } else { - inter_pred_16bpp(ctx); + inter_pred_16bpp(avctx); } } if (!b->skip) { @@ -1726,14 +1726,14 @@ static av_always_inline void inter_recon(AVCodecContext *ctx, int bytesperpixel) } } -static void inter_recon_8bpp(AVCodecContext *ctx) +static void inter_recon_8bpp(AVCodecContext *avctx) { - inter_recon(ctx, 1); + inter_recon(avctx, 1); } -static void inter_recon_16bpp(AVCodecContext *ctx) +static void inter_recon_16bpp(AVCodecContext *avctx) { - inter_recon(ctx, 2); + inter_recon(avctx, 2); } static av_always_inline void mask_edges(uint8_t (*mask)[8][4], int ss_h, int ss_v, @@ -1858,11 +1858,11 @@ static av_always_inline void mask_edges(uint8_t (*mask)[8][4], int ss_h, int ss_ } } -void ff_vp9_decode_block(AVCodecContext *ctx, int row, int col, +void ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, struct VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl, enum BlockPartition bp) { - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; VP9Block *b = s->b; enum BlockSize bs = bl * 3 + bp; int bytesperpixel = s->bytesperpixel; @@ -1882,7 +1882,7 @@ void ff_vp9_decode_block(AVCodecContext *ctx, int row, int col, b->bs = bs; b->bl = bl; b->bp = bp; - decode_mode(ctx); + decode_mode(avctx); b->uvtx = b->tx - ((s->ss_h && w4 * 2 == (1 << b->tx)) || (s->ss_v && h4 * 2 == (1 << b->tx))); @@ -1890,9 +1890,9 @@ void ff_vp9_decode_block(AVCodecContext *ctx, int row, int col, int has_coeffs; if (bytesperpixel == 1) { - has_coeffs = decode_coeffs_8bpp(ctx); + has_coeffs = decode_coeffs_8bpp(avctx); } else { - has_coeffs = decode_coeffs_16bpp(ctx); + has_coeffs = decode_coeffs_16bpp(avctx); } if (!has_coeffs && b->bs <= BS_8x8 && !b->intra) { b->skip = 1; @@ -1974,15 +1974,15 @@ void ff_vp9_decode_block(AVCodecContext *ctx, int row, int col, } if (b->intra) { if (s->s.h.bpp > 8) { - intra_recon_16bpp(ctx, yoff, uvoff); + intra_recon_16bpp(avctx, yoff, uvoff); } else { - intra_recon_8bpp(ctx, yoff, uvoff); + intra_recon_8bpp(avctx, yoff, uvoff); } } else { if (s->s.h.bpp > 8) { - inter_recon_16bpp(ctx); + inter_recon_16bpp(avctx); } else { - inter_recon_8bpp(ctx); + inter_recon_8bpp(avctx); } } if (emu[0]) { From f4d95e0949fb7c483d0e5dc5addf049ce0e3fe6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sat, 25 Mar 2017 12:28:31 +0100 Subject: [PATCH 1325/3374] lavc/vp9: rename {ref,unref,alloc}_frame to frame_{ref,unref,alloc} For consistency with Libav. --- libavcodec/vp9.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index a075a625ee127..964053d9f244a 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -36,7 +36,7 @@ #define VP9_SYNCCODE 0x498342 -static void vp9_unref_frame(AVCodecContext *avctx, VP9Frame *f) +static void vp9_frame_unref(AVCodecContext *avctx, VP9Frame *f) { ff_thread_release_buffer(avctx, &f->tf); av_buffer_unref(&f->extradata); @@ -45,7 +45,7 @@ static void vp9_unref_frame(AVCodecContext *avctx, VP9Frame *f) f->hwaccel_picture_private = NULL; } -static int vp9_alloc_frame(AVCodecContext *avctx, VP9Frame *f) +static int vp9_frame_alloc(AVCodecContext *avctx, VP9Frame *f) { VP9Context *s = avctx->priv_data; int ret, sz; @@ -74,11 +74,11 @@ static int vp9_alloc_frame(AVCodecContext *avctx, VP9Frame *f) return 0; fail: - vp9_unref_frame(avctx, f); + vp9_frame_unref(avctx, f); return AVERROR(ENOMEM); } -static int vp9_ref_frame(AVCodecContext *avctx, VP9Frame *dst, VP9Frame *src) +static int vp9_frame_ref(AVCodecContext *avctx, VP9Frame *dst, VP9Frame *src) { int res; @@ -102,7 +102,7 @@ static int vp9_ref_frame(AVCodecContext *avctx, VP9Frame *dst, VP9Frame *src) return 0; fail: - vp9_unref_frame(avctx, dst); + vp9_frame_unref(avctx, dst); return AVERROR(ENOMEM); } @@ -1243,7 +1243,7 @@ static av_cold int vp9_decode_free(AVCodecContext *avctx) for (i = 0; i < 3; i++) { if (s->s.frames[i].tf.f->buf[0]) - vp9_unref_frame(avctx, &s->s.frames[i]); + vp9_frame_unref(avctx, &s->s.frames[i]); av_frame_free(&s->s.frames[i].tf.f); } for (i = 0; i < 8; i++) { @@ -1306,19 +1306,19 @@ FF_ENABLE_DEPRECATION_WARNINGS if (!retain_segmap_ref || s->s.h.keyframe || s->s.h.intraonly) { if (s->s.frames[REF_FRAME_SEGMAP].tf.f->buf[0]) - vp9_unref_frame(avctx, &s->s.frames[REF_FRAME_SEGMAP]); + vp9_frame_unref(avctx, &s->s.frames[REF_FRAME_SEGMAP]); if (!s->s.h.keyframe && !s->s.h.intraonly && !s->s.h.errorres && s->s.frames[CUR_FRAME].tf.f->buf[0] && - (res = vp9_ref_frame(avctx, &s->s.frames[REF_FRAME_SEGMAP], &s->s.frames[CUR_FRAME])) < 0) + (res = vp9_frame_ref(avctx, &s->s.frames[REF_FRAME_SEGMAP], &s->s.frames[CUR_FRAME])) < 0) return res; } if (s->s.frames[REF_FRAME_MVPAIR].tf.f->buf[0]) - vp9_unref_frame(avctx, &s->s.frames[REF_FRAME_MVPAIR]); + vp9_frame_unref(avctx, &s->s.frames[REF_FRAME_MVPAIR]); if (!s->s.h.intraonly && !s->s.h.keyframe && !s->s.h.errorres && s->s.frames[CUR_FRAME].tf.f->buf[0] && - (res = vp9_ref_frame(avctx, &s->s.frames[REF_FRAME_MVPAIR], &s->s.frames[CUR_FRAME])) < 0) + (res = vp9_frame_ref(avctx, &s->s.frames[REF_FRAME_MVPAIR], &s->s.frames[CUR_FRAME])) < 0) return res; if (s->s.frames[CUR_FRAME].tf.f->buf[0]) - vp9_unref_frame(avctx, &s->s.frames[CUR_FRAME]); - if ((res = vp9_alloc_frame(avctx, &s->s.frames[CUR_FRAME])) < 0) + vp9_frame_unref(avctx, &s->s.frames[CUR_FRAME]); + if ((res = vp9_frame_alloc(avctx, &s->s.frames[CUR_FRAME])) < 0) return res; f = s->s.frames[CUR_FRAME].tf.f; f->key_frame = s->s.h.keyframe; @@ -1329,7 +1329,7 @@ FF_ENABLE_DEPRECATION_WARNINGS if (s->s.frames[REF_FRAME_SEGMAP].tf.f->buf[0] && (s->s.frames[REF_FRAME_MVPAIR].tf.f->width != s->s.frames[CUR_FRAME].tf.f->width || s->s.frames[REF_FRAME_MVPAIR].tf.f->height != s->s.frames[CUR_FRAME].tf.f->height)) { - vp9_unref_frame(avctx, &s->s.frames[REF_FRAME_SEGMAP]); + vp9_frame_unref(avctx, &s->s.frames[REF_FRAME_SEGMAP]); } // ref frame setup @@ -1554,7 +1554,7 @@ static void vp9_decode_flush(AVCodecContext *avctx) int i; for (i = 0; i < 3; i++) - vp9_unref_frame(avctx, &s->s.frames[i]); + vp9_frame_unref(avctx, &s->s.frames[i]); for (i = 0; i < 8; i++) ff_thread_release_buffer(avctx, &s->s.refs[i]); } @@ -1609,9 +1609,9 @@ static int vp9_decode_update_thread_context(AVCodecContext *dst, const AVCodecCo for (i = 0; i < 3; i++) { if (s->s.frames[i].tf.f->buf[0]) - vp9_unref_frame(dst, &s->s.frames[i]); + vp9_frame_unref(dst, &s->s.frames[i]); if (ssrc->s.frames[i].tf.f->buf[0]) { - if ((res = vp9_ref_frame(dst, &s->s.frames[i], &ssrc->s.frames[i])) < 0) + if ((res = vp9_frame_ref(dst, &s->s.frames[i], &ssrc->s.frames[i])) < 0) return res; } } From 0f8ae9d7b29ddf7040ecaf6bb573c46afdb21cf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sat, 25 Mar 2017 12:32:45 +0100 Subject: [PATCH 1326/3374] lavc/vp9: split a few assignment out of ifs --- libavcodec/vp9.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 964053d9f244a..f2235a57f8a27 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -50,10 +50,13 @@ static int vp9_frame_alloc(AVCodecContext *avctx, VP9Frame *f) VP9Context *s = avctx->priv_data; int ret, sz; - if ((ret = ff_thread_get_buffer(avctx, &f->tf, AV_GET_BUFFER_FLAG_REF)) < 0) + ret = ff_thread_get_buffer(avctx, &f->tf, AV_GET_BUFFER_FLAG_REF); + if (ret < 0) return ret; + sz = 64 * s->sb_cols * s->sb_rows; - if (!(f->extradata = av_buffer_allocz(sz * (1 + sizeof(struct VP9mvrefPair))))) { + f->extradata = av_buffer_allocz(sz * (1 + sizeof(struct VP9mvrefPair))); + if (!f->extradata) { goto fail; } @@ -82,11 +85,13 @@ static int vp9_frame_ref(AVCodecContext *avctx, VP9Frame *dst, VP9Frame *src) { int res; - if ((res = ff_thread_ref_frame(&dst->tf, &src->tf)) < 0) { + res = ff_thread_ref_frame(&dst->tf, &src->tf); + if (res < 0) return res; - } else if (!(dst->extradata = av_buffer_ref(src->extradata))) { + + dst->extradata = av_buffer_ref(src->extradata); + if (!dst->extradata) goto fail; - } dst->segmentation_map = src->segmentation_map; dst->mv = src->mv; From ff8436ba7694fc466f9aadca9e386e1962e22904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sat, 25 Mar 2017 12:35:01 +0100 Subject: [PATCH 1327/3374] lavc/vp9: rename res to ret --- libavcodec/vp9.c | 132 +++++++++++++++++++++++------------------------ 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index f2235a57f8a27..3652655480894 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -83,11 +83,11 @@ static int vp9_frame_alloc(AVCodecContext *avctx, VP9Frame *f) static int vp9_frame_ref(AVCodecContext *avctx, VP9Frame *dst, VP9Frame *src) { - int res; + int ret; - res = ff_thread_ref_frame(&dst->tf, &src->tf); - if (res < 0) - return res; + ret = ff_thread_ref_frame(&dst->tf, &src->tf); + if (ret < 0) + return ret; dst->extradata = av_buffer_ref(src->extradata); if (!dst->extradata) @@ -117,13 +117,13 @@ static int update_size(AVCodecContext *avctx, int w, int h) enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmtp = pix_fmts; VP9Context *s = avctx->priv_data; uint8_t *p; - int bytesperpixel = s->bytesperpixel, res, cols, rows; + int bytesperpixel = s->bytesperpixel, ret, cols, rows; av_assert0(w > 0 && h > 0); if (!(s->pix_fmt == s->gf_fmt && w == s->w && h == s->h)) { - if ((res = ff_set_dimensions(avctx, w, h)) < 0) - return res; + if ((ret = ff_set_dimensions(avctx, w, h)) < 0) + return ret; switch (s->pix_fmt) { case AV_PIX_FMT_YUV420P: @@ -148,11 +148,11 @@ static int update_size(AVCodecContext *avctx, int w, int h) *fmtp++ = s->pix_fmt; *fmtp = AV_PIX_FMT_NONE; - res = ff_thread_get_format(avctx, pix_fmts); - if (res < 0) - return res; + ret = ff_thread_get_format(avctx, pix_fmts); + if (ret < 0) + return ret; - avctx->pix_fmt = res; + avctx->pix_fmt = ret; s->gf_fmt = s->pix_fmt; s->w = w; s->h = h; @@ -389,14 +389,14 @@ static int decode_frame_header(AVCodecContext *avctx, const uint8_t *data, int size, int *ref) { VP9Context *s = avctx->priv_data; - int c, i, j, k, l, m, n, w, h, max, size2, res, sharp; + int c, i, j, k, l, m, n, w, h, max, size2, ret, sharp; int last_invisible; const uint8_t *data2; /* general header */ - if ((res = init_get_bits8(&s->gb, data, size)) < 0) { + if ((ret = init_get_bits8(&s->gb, data, size)) < 0) { av_log(avctx, AV_LOG_ERROR, "Failed to initialize bitstream reader\n"); - return res; + return ret; } if (get_bits(&s->gb, 2) != 0x2) { // frame marker av_log(avctx, AV_LOG_ERROR, "Invalid frame marker\n"); @@ -425,8 +425,8 @@ static int decode_frame_header(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "Invalid sync code\n"); return AVERROR_INVALIDDATA; } - if ((res = read_colorspace_details(avctx)) < 0) - return res; + if ((ret = read_colorspace_details(avctx)) < 0) + return ret; // for profile 1, here follows the subsampling bits s->s.h.refreshrefmask = 0xff; w = get_bits(&s->gb, 16) + 1; @@ -442,8 +442,8 @@ static int decode_frame_header(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } if (avctx->profile >= 1) { - if ((res = read_colorspace_details(avctx)) < 0) - return res; + if ((ret = read_colorspace_details(avctx)) < 0) + return ret; } else { s->ss_h = s->ss_v = 1; s->s.h.bpp = 8; @@ -636,10 +636,10 @@ static int decode_frame_header(AVCodecContext *avctx, } /* tiling info */ - if ((res = update_size(avctx, w, h)) < 0) { + if ((ret = update_size(avctx, w, h)) < 0) { av_log(avctx, AV_LOG_ERROR, "Failed to initialize decoder for %dx%d @ %d\n", w, h, s->pix_fmt); - return res; + return ret; } for (s->s.h.tiling.log2_tile_cols = 0; s->sb_cols > (64 << s->s.h.tiling.log2_tile_cols); @@ -719,9 +719,9 @@ static int decode_frame_header(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "Invalid compressed header size\n"); return AVERROR_INVALIDDATA; } - res = ff_vp56_init_range_decoder(&s->c, data2, size2); - if (res < 0) - return res; + ret = ff_vp56_init_range_decoder(&s->c, data2, size2); + if (ret < 0) + return ret; if (vp56_rac_get_prob_branchy(&s->c, 128)) { // marker bit av_log(avctx, AV_LOG_ERROR, "Marker bit was set\n"); @@ -1273,22 +1273,22 @@ static int vp9_decode_frame(AVCodecContext *avctx, void *frame, const uint8_t *data = pkt->data; int size = pkt->size; VP9Context *s = avctx->priv_data; - int res, tile_row, tile_col, i, ref, row, col; + int ret, tile_row, tile_col, i, ref, row, col; int retain_segmap_ref = s->s.frames[REF_FRAME_SEGMAP].segmentation_map && (!s->s.h.segmentation.enabled || !s->s.h.segmentation.update_map); ptrdiff_t yoff, uvoff, ls_y, ls_uv; AVFrame *f; int bytesperpixel; - if ((res = decode_frame_header(avctx, data, size, &ref)) < 0) { - return res; - } else if (res == 0) { + if ((ret = decode_frame_header(avctx, data, size, &ref)) < 0) { + return ret; + } else if (ret == 0) { if (!s->s.refs[ref].f->buf[0]) { av_log(avctx, AV_LOG_ERROR, "Requested reference %d not available\n", ref); return AVERROR_INVALIDDATA; } - if ((res = av_frame_ref(frame, s->s.refs[ref].f)) < 0) - return res; + if ((ret = av_frame_ref(frame, s->s.refs[ref].f)) < 0) + return ret; ((AVFrame *)frame)->pts = pkt->pts; #if FF_API_PKT_PTS FF_DISABLE_DEPRECATION_WARNINGS @@ -1300,31 +1300,31 @@ FF_ENABLE_DEPRECATION_WARNINGS if (s->next_refs[i].f->buf[0]) ff_thread_release_buffer(avctx, &s->next_refs[i]); if (s->s.refs[i].f->buf[0] && - (res = ff_thread_ref_frame(&s->next_refs[i], &s->s.refs[i])) < 0) - return res; + (ret = ff_thread_ref_frame(&s->next_refs[i], &s->s.refs[i])) < 0) + return ret; } *got_frame = 1; return pkt->size; } - data += res; - size -= res; + data += ret; + size -= ret; if (!retain_segmap_ref || s->s.h.keyframe || s->s.h.intraonly) { if (s->s.frames[REF_FRAME_SEGMAP].tf.f->buf[0]) vp9_frame_unref(avctx, &s->s.frames[REF_FRAME_SEGMAP]); if (!s->s.h.keyframe && !s->s.h.intraonly && !s->s.h.errorres && s->s.frames[CUR_FRAME].tf.f->buf[0] && - (res = vp9_frame_ref(avctx, &s->s.frames[REF_FRAME_SEGMAP], &s->s.frames[CUR_FRAME])) < 0) - return res; + (ret = vp9_frame_ref(avctx, &s->s.frames[REF_FRAME_SEGMAP], &s->s.frames[CUR_FRAME])) < 0) + return ret; } if (s->s.frames[REF_FRAME_MVPAIR].tf.f->buf[0]) vp9_frame_unref(avctx, &s->s.frames[REF_FRAME_MVPAIR]); if (!s->s.h.intraonly && !s->s.h.keyframe && !s->s.h.errorres && s->s.frames[CUR_FRAME].tf.f->buf[0] && - (res = vp9_frame_ref(avctx, &s->s.frames[REF_FRAME_MVPAIR], &s->s.frames[CUR_FRAME])) < 0) - return res; + (ret = vp9_frame_ref(avctx, &s->s.frames[REF_FRAME_MVPAIR], &s->s.frames[CUR_FRAME])) < 0) + return ret; if (s->s.frames[CUR_FRAME].tf.f->buf[0]) vp9_frame_unref(avctx, &s->s.frames[CUR_FRAME]); - if ((res = vp9_frame_alloc(avctx, &s->s.frames[CUR_FRAME])) < 0) - return res; + if ((ret = vp9_frame_alloc(avctx, &s->s.frames[CUR_FRAME])) < 0) + return ret; f = s->s.frames[CUR_FRAME].tf.f; f->key_frame = s->s.h.keyframe; f->pict_type = (s->s.h.keyframe || s->s.h.intraonly) ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; @@ -1342,24 +1342,24 @@ FF_ENABLE_DEPRECATION_WARNINGS if (s->next_refs[i].f->buf[0]) ff_thread_release_buffer(avctx, &s->next_refs[i]); if (s->s.h.refreshrefmask & (1 << i)) { - res = ff_thread_ref_frame(&s->next_refs[i], &s->s.frames[CUR_FRAME].tf); + ret = ff_thread_ref_frame(&s->next_refs[i], &s->s.frames[CUR_FRAME].tf); } else if (s->s.refs[i].f->buf[0]) { - res = ff_thread_ref_frame(&s->next_refs[i], &s->s.refs[i]); + ret = ff_thread_ref_frame(&s->next_refs[i], &s->s.refs[i]); } - if (res < 0) - return res; + if (ret < 0) + return ret; } if (avctx->hwaccel) { - res = avctx->hwaccel->start_frame(avctx, NULL, 0); - if (res < 0) - return res; - res = avctx->hwaccel->decode_slice(avctx, pkt->data, pkt->size); - if (res < 0) - return res; - res = avctx->hwaccel->end_frame(avctx); - if (res < 0) - return res; + ret = avctx->hwaccel->start_frame(avctx, NULL, 0); + if (ret < 0) + return ret; + ret = avctx->hwaccel->decode_slice(avctx, pkt->data, pkt->size); + if (ret < 0) + return ret; + ret = avctx->hwaccel->end_frame(avctx); + if (ret < 0) + return ret; goto finish; } @@ -1378,10 +1378,10 @@ FF_ENABLE_DEPRECATION_WARNINGS memset(s->above_segpred_ctx, 0, s->cols); s->pass = s->s.frames[CUR_FRAME].uses_2pass = avctx->active_thread_type == FF_THREAD_FRAME && s->s.h.refreshctx && !s->s.h.parallelmode; - if ((res = update_block_buffers(avctx)) < 0) { + if ((ret = update_block_buffers(avctx)) < 0) { av_log(avctx, AV_LOG_ERROR, "Failed to allocate block buffers\n"); - return res; + return ret; } if (s->s.h.refreshctx && s->s.h.parallelmode) { int j, k, l, m; @@ -1431,9 +1431,9 @@ FF_ENABLE_DEPRECATION_WARNINGS ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); return AVERROR_INVALIDDATA; } - res = ff_vp56_init_range_decoder(&s->c_b[tile_col], data, tile_size); - if (res < 0) - return res; + ret = ff_vp56_init_range_decoder(&s->c_b[tile_col], data, tile_size); + if (ret < 0) + return ret; if (vp56_rac_get_prob_branchy(&s->c_b[tile_col], 128)) { // marker bit ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); return AVERROR_INVALIDDATA; @@ -1540,13 +1540,13 @@ FF_ENABLE_DEPRECATION_WARNINGS if (s->s.refs[i].f->buf[0]) ff_thread_release_buffer(avctx, &s->s.refs[i]); if (s->next_refs[i].f->buf[0] && - (res = ff_thread_ref_frame(&s->s.refs[i], &s->next_refs[i])) < 0) - return res; + (ret = ff_thread_ref_frame(&s->s.refs[i], &s->next_refs[i])) < 0) + return ret; } if (!s->s.h.invisible) { - if ((res = av_frame_ref(frame, s->s.frames[CUR_FRAME].tf.f)) < 0) - return res; + if ((ret = av_frame_ref(frame, s->s.frames[CUR_FRAME].tf.f)) < 0) + return ret; *got_frame = 1; } @@ -1609,23 +1609,23 @@ static av_cold int vp9_decode_init_thread_copy(AVCodecContext *avctx) static int vp9_decode_update_thread_context(AVCodecContext *dst, const AVCodecContext *src) { - int i, res; + int i, ret; VP9Context *s = dst->priv_data, *ssrc = src->priv_data; for (i = 0; i < 3; i++) { if (s->s.frames[i].tf.f->buf[0]) vp9_frame_unref(dst, &s->s.frames[i]); if (ssrc->s.frames[i].tf.f->buf[0]) { - if ((res = vp9_frame_ref(dst, &s->s.frames[i], &ssrc->s.frames[i])) < 0) - return res; + if ((ret = vp9_frame_ref(dst, &s->s.frames[i], &ssrc->s.frames[i])) < 0) + return ret; } } for (i = 0; i < 8; i++) { if (s->s.refs[i].f->buf[0]) ff_thread_release_buffer(dst, &s->s.refs[i]); if (ssrc->next_refs[i].f->buf[0]) { - if ((res = ff_thread_ref_frame(&s->s.refs[i], &ssrc->next_refs[i])) < 0) - return res; + if ((ret = ff_thread_ref_frame(&s->s.refs[i], &ssrc->next_refs[i])) < 0) + return ret; } } From 875f6955769bcb7caf083c1796ed6f3b2108c49e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sat, 25 Mar 2017 12:40:48 +0100 Subject: [PATCH 1328/3374] lavc/vp9: misc cosmetics Imported from Libav --- libavcodec/vp9.c | 60 ++++++------ libavcodec/vp9block.c | 198 ++++++++++++++++++++++----------------- libavcodec/vp9data.c | 94 +++++++++---------- libavcodec/vp9mvs.c | 213 +++++++++++++++++++++--------------------- libavcodec/vp9prob.c | 74 ++++++++------- 5 files changed, 337 insertions(+), 302 deletions(-) diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 3652655480894..c1c90ca65e047 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -252,7 +252,7 @@ static int update_block_buffers(AVCodecContext *avctx) return 0; } -// for some reason the sign bit is at the end, not the start, of a bit sequence +// The sign bit is at the end, not the start, of a bit sequence static av_always_inline int get_sbits_inv(GetBitContext *gb, int n) { int v = get_bits(gb, n); @@ -292,13 +292,13 @@ static int update_prob(VP56RangeCoder *c, int p) /* This code is trying to do a differential probability update. For a * current probability A in the range [1, 255], the difference to a new - * probability of any value can be expressed differentially as 1-A,255-A + * probability of any value can be expressed differentially as 1-A, 255-A * where some part of this (absolute range) exists both in positive as * well as the negative part, whereas another part only exists in one * half. We're trying to code this shared part differentially, i.e. * times two where the value of the lowest bit specifies the sign, and * the single part is then coded on top of this. This absolute difference - * then again has a value of [0,254], but a bigger value in this range + * then again has a value of [0, 254], but a bigger value in this range * indicates that we're further away from the original value A, so we * can code this as a VLC code, since higher values are increasingly * unlikely. The first 20 values in inv_map_table[] allow 'cheap, rough' @@ -414,12 +414,15 @@ static int decode_frame_header(AVCodecContext *avctx, *ref = get_bits(&s->gb, 3); return 0; } + s->last_keyframe = s->s.h.keyframe; - s->s.h.keyframe = !get_bits1(&s->gb); - last_invisible = s->s.h.invisible; - s->s.h.invisible = !get_bits1(&s->gb); - s->s.h.errorres = get_bits1(&s->gb); + s->s.h.keyframe = !get_bits1(&s->gb); + + last_invisible = s->s.h.invisible; + s->s.h.invisible = !get_bits1(&s->gb); + s->s.h.errorres = get_bits1(&s->gb); s->s.h.use_last_frame_mvs = !s->s.h.errorres && !last_invisible; + if (s->s.h.keyframe) { if (get_bits_long(&s->gb, 24) != VP9_SYNCCODE) { // synccode av_log(avctx, AV_LOG_ERROR, "Invalid sync code\n"); @@ -434,8 +437,8 @@ static int decode_frame_header(AVCodecContext *avctx, if (get_bits1(&s->gb)) // display size skip_bits(&s->gb, 32); } else { - s->s.h.intraonly = s->s.h.invisible ? get_bits1(&s->gb) : 0; - s->s.h.resetctx = s->s.h.errorres ? 0 : get_bits(&s->gb, 2); + s->s.h.intraonly = s->s.h.invisible ? get_bits1(&s->gb) : 0; + s->s.h.resetctx = s->s.h.errorres ? 0 : get_bits(&s->gb, 2); if (s->s.h.intraonly) { if (get_bits_long(&s->gb, 24) != VP9_SYNCCODE) { // synccode av_log(avctx, AV_LOG_ERROR, "Invalid sync code\n"); @@ -565,11 +568,10 @@ static int decode_frame_header(AVCodecContext *avctx, for (i = 0; i < 7; i++) s->s.h.segmentation.prob[i] = get_bits1(&s->gb) ? get_bits(&s->gb, 8) : 255; - if ((s->s.h.segmentation.temporal = get_bits1(&s->gb))) { + if ((s->s.h.segmentation.temporal = get_bits1(&s->gb))) for (i = 0; i < 3; i++) s->s.h.segmentation.pred_prob[i] = get_bits1(&s->gb) ? get_bits(&s->gb, 8) : 255; - } } if (get_bits1(&s->gb)) { @@ -734,9 +736,9 @@ static int decode_frame_header(AVCodecContext *avctx, } else { memset(&s->counts, 0, sizeof(s->counts)); } - // FIXME is it faster to not copy here, but do it down in the fw updates - // as explicit copies if the fw update is missing (and skip the copy upon - // fw update)? + /* FIXME is it faster to not copy here, but do it down in the fw updates + * as explicit copies if the fw update is missing (and skip the copy upon + * fw update)? */ s->prob.p = s->prob_ctx[c].p; // txfm updates @@ -777,11 +779,10 @@ static int decode_frame_header(AVCodecContext *avctx, if (m >= 3 && l == 0) // dc only has 3 pt break; for (n = 0; n < 3; n++) { - if (vp56_rac_get_prob_branchy(&s->c, 252)) { + if (vp56_rac_get_prob_branchy(&s->c, 252)) p[n] = update_prob(&s->c, r[n]); - } else { + else p[n] = r[n]; - } } p[3] = 0; } @@ -866,7 +867,8 @@ static int decode_frame_header(AVCodecContext *avctx, for (k = 0; k < 3; k++) if (vp56_rac_get_prob_branchy(&s->c, 252)) s->prob.p.partition[3 - i][j][k] = - update_prob(&s->c, s->prob.p.partition[3 - i][j][k]); + update_prob(&s->c, + s->prob.p.partition[3 - i][j][k]); // mv fields don't use the update_prob subexp model for some reason for (i = 0; i < 3; i++) @@ -875,7 +877,8 @@ static int decode_frame_header(AVCodecContext *avctx, for (i = 0; i < 2; i++) { if (vp56_rac_get_prob_branchy(&s->c, 252)) - s->prob.p.mv_comp[i].sign = (vp8_rac_get_uint(&s->c, 7) << 1) | 1; + s->prob.p.mv_comp[i].sign = + (vp8_rac_get_uint(&s->c, 7) << 1) | 1; for (j = 0; j < 10; j++) if (vp56_rac_get_prob_branchy(&s->c, 252)) @@ -883,7 +886,8 @@ static int decode_frame_header(AVCodecContext *avctx, (vp8_rac_get_uint(&s->c, 7) << 1) | 1; if (vp56_rac_get_prob_branchy(&s->c, 252)) - s->prob.p.mv_comp[i].class0 = (vp8_rac_get_uint(&s->c, 7) << 1) | 1; + s->prob.p.mv_comp[i].class0 = + (vp8_rac_get_uint(&s->c, 7) << 1) | 1; for (j = 0; j < 10; j++) if (vp56_rac_get_prob_branchy(&s->c, 252)) @@ -1210,11 +1214,11 @@ static void loopfilter_sb(AVCodecContext *avctx, struct VP9Filter *lflvl, uint8_t (*uv_masks)[8][4] = lflvl->mask[s->ss_h | s->ss_v]; int p; - // FIXME in how far can we interleave the v/h loopfilter calls? E.g. - // if you think of them as acting on a 8x8 block max, we can interleave - // each v/h within the single x loop, but that only works if we work on - // 8 pixel blocks, and we won't always do that (we want at least 16px - // to use SSE2 optimizations, perhaps 32 for AVX2) + /* FIXME: In how far can we interleave the v/h loopfilter calls? E.g. + * if you think of them as acting on a 8x8 block max, we can interleave + * each v/h within the single x loop, but that only works if we work on + * 8 pixel blocks, and we won't always do that (we want at least 16px + * to use SSE2 optimizations, perhaps 32 for AVX2) */ filter_plane_cols(s, col, 0, 0, lflvl->level, lflvl->mask[0][0], dst, ls_y); filter_plane_rows(s, row, 0, 0, lflvl->level, lflvl->mask[0][1], dst, ls_y); @@ -1485,14 +1489,12 @@ FF_ENABLE_DEPRECATION_WARNINGS yoff2, uvoff2, BL_64X64); } } - if (s->pass != 2) { + if (s->pass != 2) memcpy(&s->c_b[tile_col], &s->c, sizeof(s->c)); - } } - if (s->pass == 1) { + if (s->pass == 1) continue; - } // backup pre-loopfilter reconstruction data for intra // prediction of next row of sb64s diff --git a/libavcodec/vp9block.c b/libavcodec/vp9block.c index 3d57913e5abd1..70c701579969e 100644 --- a/libavcodec/vp9block.c +++ b/libavcodec/vp9block.c @@ -33,10 +33,10 @@ static const uint8_t bwh_tab[2][N_BS_SIZES][2] = { { { 16, 16 }, { 16, 8 }, { 8, 16 }, { 8, 8 }, { 8, 4 }, { 4, 8 }, - { 4, 4 }, { 4, 2 }, { 2, 4 }, { 2, 2 }, { 2, 1 }, { 1, 2 }, { 1, 1 }, + { 4, 4 }, { 4, 2 }, { 2, 4 }, { 2, 2 }, { 2, 1 }, { 1, 2 }, { 1, 1 }, }, { - { 8, 8 }, { 8, 4 }, { 4, 8 }, { 4, 4 }, { 4, 2 }, { 2, 4 }, - { 2, 2 }, { 2, 1 }, { 1, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, + { 8, 8 }, { 8, 4 }, { 4, 8 }, { 4, 4 }, { 4, 2 }, { 2, 4 }, + { 2, 2 }, { 2, 1 }, { 1, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, } }; @@ -96,7 +96,7 @@ static void decode_mode(AVCodecContext *avctx) }; static const uint8_t max_tx_for_bl_bp[N_BS_SIZES] = { TX_32X32, TX_32X32, TX_32X32, TX_32X32, TX_16X16, TX_16X16, - TX_16X16, TX_8X8, TX_8X8, TX_8X8, TX_4X4, TX_4X4, TX_4X4 + TX_16X16, TX_8X8, TX_8X8, TX_8X8, TX_4X4, TX_4X4, TX_4X4 }; VP9Context *s = avctx->priv_data; VP9Block *b = s->b; @@ -231,33 +231,45 @@ static void decode_mode(AVCodecContext *avctx) // FIXME the memory storage intermediates here aren't really // necessary, they're just there to make the code slightly // simpler for now - b->mode[0] = a[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, - ff_vp9_default_kf_ymode_probs[a[0]][l[0]]); + b->mode[0] = + a[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + ff_vp9_default_kf_ymode_probs[a[0]][l[0]]); if (b->bs != BS_8x4) { b->mode[1] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, - ff_vp9_default_kf_ymode_probs[a[1]][b->mode[0]]); - l[0] = a[1] = b->mode[1]; + ff_vp9_default_kf_ymode_probs[a[1]][b->mode[0]]); + l[0] = + a[1] = b->mode[1]; } else { - l[0] = a[1] = b->mode[1] = b->mode[0]; + l[0] = + a[1] = + b->mode[1] = b->mode[0]; } if (b->bs != BS_4x8) { - b->mode[2] = a[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, - ff_vp9_default_kf_ymode_probs[a[0]][l[1]]); + b->mode[2] = + a[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + ff_vp9_default_kf_ymode_probs[a[0]][l[1]]); if (b->bs != BS_8x4) { b->mode[3] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, - ff_vp9_default_kf_ymode_probs[a[1]][b->mode[2]]); - l[1] = a[1] = b->mode[3]; + ff_vp9_default_kf_ymode_probs[a[1]][b->mode[2]]); + l[1] = + a[1] = b->mode[3]; } else { - l[1] = a[1] = b->mode[3] = b->mode[2]; + l[1] = + a[1] = + b->mode[3] = b->mode[2]; } } else { b->mode[2] = b->mode[0]; - l[1] = a[1] = b->mode[3] = b->mode[1]; + l[1] = + a[1] = + b->mode[3] = b->mode[1]; } } else { b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, ff_vp9_default_kf_ymode_probs[*a][*l]); - b->mode[3] = b->mode[2] = b->mode[1] = b->mode[0]; + b->mode[3] = + b->mode[2] = + b->mode[1] = b->mode[0]; // FIXME this can probably be optimized memset(a, b->mode[0], bwh_tab[0][b->bs][0]); memset(l, b->mode[0], bwh_tab[0][b->bs][1]); @@ -300,7 +312,9 @@ static void decode_mode(AVCodecContext *avctx) b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, s->prob.p.y_mode[sz]); - b->mode[1] = b->mode[2] = b->mode[3] = b->mode[0]; + b->mode[1] = + b->mode[2] = + b->mode[3] = b->mode[0]; s->counts.y_mode[sz][b->mode[3]]++; } b->uvmode = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, @@ -349,8 +363,8 @@ static void decode_mode(AVCodecContext *avctx) } else { c = (!s->above_intra_ctx[col] && s->above_ref_ctx[col] == s->s.h.fixcompref) ^ - (!s->left_intra_ctx[row7] && - s->left_ref_ctx[row & 7] == s->s.h.fixcompref); + (!s->left_intra_ctx[row7] && + s->left_ref_ctx[row & 7] == s->s.h.fixcompref); } } else { c = s->above_comp_ctx[col] ? 3 : @@ -369,7 +383,7 @@ static void decode_mode(AVCodecContext *avctx) // read actual references // FIXME probably cache a few variables here to prevent repetitive // memory accesses below - if (b->comp) /* two references */ { + if (b->comp) { /* two references */ int fix_idx = s->s.h.signbias[s->s.h.fixcompref], var_idx = !fix_idx, c, bit; b->ref[fix_idx] = s->s.h.fixcompref; @@ -537,7 +551,7 @@ static void decode_mode(AVCodecContext *avctx) c = 4 * (s->above_ref_ctx[col] == 1); } else { c = 2 * (s->left_ref_ctx[row7] == 1) + - 2 * (s->above_ref_ctx[col] == 1); + 2 * (s->above_ref_ctx[col] == 1); } } else { if (s->above_intra_ctx[col] || @@ -570,7 +584,10 @@ static void decode_mode(AVCodecContext *avctx) if (b->bs <= BS_8x8) { if (s->s.h.segmentation.enabled && s->s.h.segmentation.feat[b->seg_id].skip_enabled) { - b->mode[0] = b->mode[1] = b->mode[2] = b->mode[3] = ZEROMV; + b->mode[0] = + b->mode[1] = + b->mode[2] = + b->mode[3] = ZEROMV; } else { static const uint8_t off[10] = { 3, 0, 0, 1, 0, 0, 0, 0, 0, 0 @@ -583,7 +600,9 @@ static void decode_mode(AVCodecContext *avctx) b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree, s->prob.p.mv_mode[c]); - b->mode[1] = b->mode[2] = b->mode[3] = b->mode[0]; + b->mode[1] = + b->mode[2] = + b->mode[3] = b->mode[0]; s->counts.mv_mode[c][b->mode[0] - 10]++; } } @@ -810,23 +829,23 @@ decode_coeffs_b_generic(VP56RangeCoder *c, int16_t *coef, int n_coeffs, if (!val) break; - skip_eob: +skip_eob: if (!vp56_rac_get_prob_branchy(c, tp[1])) { // zero cnt[band][nnz][0]++; if (!--band_left) band_left = band_counts[++band]; cache[scan[i]] = 0; - nnz = (1 + cache[nb[i][0]] + cache[nb[i][1]]) >> 1; - tp = p[band][nnz]; + nnz = (1 + cache[nb[i][0]] + cache[nb[i][1]]) >> 1; + tp = p[band][nnz]; if (++i == n_coeffs) - break; //invalid input; blocks should end with EOB + break; //invalid input; blocks should end with EOB goto skip_eob; } rc = scan[i]; if (!vp56_rac_get_prob_branchy(c, tp[2])) { // one cnt[band][nnz][1]++; - val = 1; + val = 1; cache[rc] = 1; } else { // fill in p[3-10] (model fill) - only once per frame for each pos @@ -838,16 +857,16 @@ decode_coeffs_b_generic(VP56RangeCoder *c, int16_t *coef, int n_coeffs, if (!vp56_rac_get_prob_branchy(c, tp[4])) { cache[rc] = val = 2; } else { - val = 3 + vp56_rac_get_prob(c, tp[5]); + val = 3 + vp56_rac_get_prob(c, tp[5]); cache[rc] = 3; } } else if (!vp56_rac_get_prob_branchy(c, tp[6])) { // cat1/2 cache[rc] = 4; if (!vp56_rac_get_prob_branchy(c, tp[7])) { - val = 5 + vp56_rac_get_prob(c, 159); + val = vp56_rac_get_prob(c, 159) + 5; } else { - val = 7 + (vp56_rac_get_prob(c, 165) << 1); - val += vp56_rac_get_prob(c, 145); + val = (vp56_rac_get_prob(c, 165) << 1) + 7; + val += vp56_rac_get_prob(c, 145); } } else { // cat 3-6 cache[rc] = 5; @@ -863,11 +882,11 @@ decode_coeffs_b_generic(VP56RangeCoder *c, int16_t *coef, int n_coeffs, val += vp56_rac_get_prob(c, 135); } } else if (!vp56_rac_get_prob_branchy(c, tp[10])) { - val = 35 + (vp56_rac_get_prob(c, 180) << 4); - val += (vp56_rac_get_prob(c, 157) << 3); - val += (vp56_rac_get_prob(c, 141) << 2); - val += (vp56_rac_get_prob(c, 134) << 1); - val += vp56_rac_get_prob(c, 130); + val = (vp56_rac_get_prob(c, 180) << 4) + 35; + val += (vp56_rac_get_prob(c, 157) << 3); + val += (vp56_rac_get_prob(c, 141) << 2); + val += (vp56_rac_get_prob(c, 134) << 1); + val += vp56_rac_get_prob(c, 130); } else { val = 67; if (!is8bitsperpixel) { @@ -878,20 +897,20 @@ decode_coeffs_b_generic(VP56RangeCoder *c, int16_t *coef, int n_coeffs, val += (vp56_rac_get_prob(c, 255) << 15); val += (vp56_rac_get_prob(c, 255) << 14); } - val += (vp56_rac_get_prob(c, 254) << 13); - val += (vp56_rac_get_prob(c, 254) << 12); - val += (vp56_rac_get_prob(c, 254) << 11); - val += (vp56_rac_get_prob(c, 252) << 10); - val += (vp56_rac_get_prob(c, 249) << 9); - val += (vp56_rac_get_prob(c, 243) << 8); - val += (vp56_rac_get_prob(c, 230) << 7); - val += (vp56_rac_get_prob(c, 196) << 6); - val += (vp56_rac_get_prob(c, 177) << 5); - val += (vp56_rac_get_prob(c, 153) << 4); - val += (vp56_rac_get_prob(c, 140) << 3); - val += (vp56_rac_get_prob(c, 133) << 2); - val += (vp56_rac_get_prob(c, 130) << 1); - val += vp56_rac_get_prob(c, 129); + val += (vp56_rac_get_prob(c, 254) << 13); + val += (vp56_rac_get_prob(c, 254) << 12); + val += (vp56_rac_get_prob(c, 254) << 11); + val += (vp56_rac_get_prob(c, 252) << 10); + val += (vp56_rac_get_prob(c, 249) << 9); + val += (vp56_rac_get_prob(c, 243) << 8); + val += (vp56_rac_get_prob(c, 230) << 7); + val += (vp56_rac_get_prob(c, 196) << 6); + val += (vp56_rac_get_prob(c, 177) << 5); + val += (vp56_rac_get_prob(c, 153) << 4); + val += (vp56_rac_get_prob(c, 140) << 3); + val += (vp56_rac_get_prob(c, 133) << 2); + val += (vp56_rac_get_prob(c, 130) << 1); + val += vp56_rac_get_prob(c, 129); } } } @@ -966,7 +985,7 @@ static av_always_inline int decode_coeffs(AVCodecContext *avctx, int is8bitsperp int w4 = bwh_tab[1][b->bs][0] << 1, h4 = bwh_tab[1][b->bs][1] << 1; int end_x = FFMIN(2 * (s->cols - col), w4); int end_y = FFMIN(2 * (s->rows - row), h4); - int n, pl, x, y, res; + int n, pl, x, y, ret; int16_t (*qmul)[2] = s->s.h.segmentation.feat[b->seg_id].qmul; int tx = 4 * s->s.h.lossless + b->tx; const int16_t * const *yscans = ff_vp9_scans[tx]; @@ -999,16 +1018,16 @@ static av_always_inline int decode_coeffs(AVCodecContext *avctx, int is8bitsperp for (n = 0, y = 0; y < end_y; y += step) { \ for (x = 0; x < end_x; x += step, n += step * step) { \ enum TxfmType txtp = ff_vp9_intra_txfm_type[b->mode[mode_index]]; \ - res = (is8bitsperpixel ? decode_coeffs_b##v##_8bpp : decode_coeffs_b##v##_16bpp) \ + ret = (is8bitsperpixel ? decode_coeffs_b##v##_8bpp : decode_coeffs_b##v##_16bpp) \ (s, s->block + 16 * n * bytesperpixel, 16 * step * step, \ c, e, p, a[x] + l[y], yscans[txtp], \ ynbs[txtp], y_band_counts, qmul[0]); \ - a[x] = l[y] = !!res; \ - total_coeff |= !!res; \ + a[x] = l[y] = !!ret; \ + total_coeff |= !!ret; \ if (step >= 4) { \ - AV_WN16A(&s->eob[n], res); \ + AV_WN16A(&s->eob[n], ret); \ } else { \ - s->eob[n] = res; \ + s->eob[n] = ret; \ } \ } \ } @@ -1073,16 +1092,16 @@ static av_always_inline int decode_coeffs(AVCodecContext *avctx, int is8bitsperp #define DECODE_UV_COEF_LOOP(step, v) \ for (n = 0, y = 0; y < end_y; y += step) { \ for (x = 0; x < end_x; x += step, n += step * step) { \ - res = (is8bitsperpixel ? decode_coeffs_b##v##_8bpp : decode_coeffs_b##v##_16bpp) \ + ret = (is8bitsperpixel ? decode_coeffs_b##v##_8bpp : decode_coeffs_b##v##_16bpp) \ (s, s->uvblock[pl] + 16 * n * bytesperpixel, \ 16 * step * step, c, e, p, a[x] + l[y], \ uvscan, uvnb, uv_band_counts, qmul[1]); \ - a[x] = l[y] = !!res; \ - total_coeff |= !!res; \ + a[x] = l[y] = !!ret; \ + total_coeff |= !!ret; \ if (step >= 4) { \ - AV_WN16A(&s->uveob[pl][n], res); \ + AV_WN16A(&s->uveob[pl][n], ret); \ } else { \ - s->uveob[pl][n] = res; \ + s->uveob[pl][n] = ret; \ } \ } \ } @@ -1144,26 +1163,26 @@ static av_always_inline int check_intra_mode(VP9Context *s, int mode, uint8_t ** int have_right = x < w - 1; int bpp = s->s.h.bpp; static const uint8_t mode_conv[10][2 /* have_left */][2 /* have_top */] = { - [VERT_PRED] = { { DC_127_PRED, VERT_PRED }, - { DC_127_PRED, VERT_PRED } }, - [HOR_PRED] = { { DC_129_PRED, DC_129_PRED }, - { HOR_PRED, HOR_PRED } }, - [DC_PRED] = { { DC_128_PRED, TOP_DC_PRED }, - { LEFT_DC_PRED, DC_PRED } }, - [DIAG_DOWN_LEFT_PRED] = { { DC_127_PRED, DIAG_DOWN_LEFT_PRED }, - { DC_127_PRED, DIAG_DOWN_LEFT_PRED } }, + [VERT_PRED] = { { DC_127_PRED, VERT_PRED }, + { DC_127_PRED, VERT_PRED } }, + [HOR_PRED] = { { DC_129_PRED, DC_129_PRED }, + { HOR_PRED, HOR_PRED } }, + [DC_PRED] = { { DC_128_PRED, TOP_DC_PRED }, + { LEFT_DC_PRED, DC_PRED } }, + [DIAG_DOWN_LEFT_PRED] = { { DC_127_PRED, DIAG_DOWN_LEFT_PRED }, + { DC_127_PRED, DIAG_DOWN_LEFT_PRED } }, [DIAG_DOWN_RIGHT_PRED] = { { DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED }, { DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED } }, - [VERT_RIGHT_PRED] = { { VERT_RIGHT_PRED, VERT_RIGHT_PRED }, - { VERT_RIGHT_PRED, VERT_RIGHT_PRED } }, - [HOR_DOWN_PRED] = { { HOR_DOWN_PRED, HOR_DOWN_PRED }, - { HOR_DOWN_PRED, HOR_DOWN_PRED } }, - [VERT_LEFT_PRED] = { { DC_127_PRED, VERT_LEFT_PRED }, - { DC_127_PRED, VERT_LEFT_PRED } }, - [HOR_UP_PRED] = { { DC_129_PRED, DC_129_PRED }, - { HOR_UP_PRED, HOR_UP_PRED } }, - [TM_VP8_PRED] = { { DC_129_PRED, VERT_PRED }, - { HOR_PRED, TM_VP8_PRED } }, + [VERT_RIGHT_PRED] = { { VERT_RIGHT_PRED, VERT_RIGHT_PRED }, + { VERT_RIGHT_PRED, VERT_RIGHT_PRED } }, + [HOR_DOWN_PRED] = { { HOR_DOWN_PRED, HOR_DOWN_PRED }, + { HOR_DOWN_PRED, HOR_DOWN_PRED } }, + [VERT_LEFT_PRED] = { { DC_127_PRED, VERT_LEFT_PRED }, + { DC_127_PRED, VERT_LEFT_PRED } }, + [HOR_UP_PRED] = { { DC_129_PRED, DC_129_PRED }, + { HOR_UP_PRED, HOR_UP_PRED } }, + [TM_VP8_PRED] = { { DC_129_PRED, VERT_PRED }, + { HOR_PRED, TM_VP8_PRED } }, }; static const struct { uint8_t needs_left:1; @@ -1176,12 +1195,16 @@ static av_always_inline int check_intra_mode(VP9Context *s, int mode, uint8_t ** [HOR_PRED] = { .needs_left = 1 }, [DC_PRED] = { .needs_top = 1, .needs_left = 1 }, [DIAG_DOWN_LEFT_PRED] = { .needs_top = 1, .needs_topright = 1 }, - [DIAG_DOWN_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 }, - [VERT_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 }, - [HOR_DOWN_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 }, + [DIAG_DOWN_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1, + .needs_topleft = 1 }, + [VERT_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1, + .needs_topleft = 1 }, + [HOR_DOWN_PRED] = { .needs_left = 1, .needs_top = 1, + .needs_topleft = 1 }, [VERT_LEFT_PRED] = { .needs_top = 1, .needs_topright = 1 }, [HOR_UP_PRED] = { .needs_left = 1, .invert_left = 1 }, - [TM_VP8_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 }, + [TM_VP8_PRED] = { .needs_left = 1, .needs_top = 1, + .needs_topleft = 1 }, [LEFT_DC_PRED] = { .needs_left = 1 }, [TOP_DC_PRED] = { .needs_top = 1 }, [DC_128_PRED] = { 0 }, @@ -1353,7 +1376,7 @@ static av_always_inline void intra_recon(AVCodecContext *avctx, ptrdiff_t y_off, } // U/V - w4 >>= s->ss_h; + w4 >>= s->ss_h; end_x >>= s->ss_h; end_y >>= s->ss_v; step = 1 << (b->uvtx * 2); @@ -1679,6 +1702,7 @@ static av_always_inline void inter_recon(AVCodecContext *avctx, int bytesperpixe inter_pred_16bpp(avctx); } } + if (!b->skip) { /* mostly copied intra_recon() */ @@ -1808,8 +1832,8 @@ static av_always_inline void mask_edges(uint8_t (*mask)[8][4], int ss_h, int ss_ if (!skip_inter) { int mask_id = (tx == TX_8X8); - static const unsigned masks[4] = { 0xff, 0x55, 0x11, 0x01 }; int l2 = tx + ss_h - 1, step1d; + static const unsigned masks[4] = { 0xff, 0x55, 0x11, 0x01 }; int m_row = m_col & masks[l2]; // at odd UV col/row edges tx16/tx32 loopfilter edges, force @@ -1874,10 +1898,12 @@ void ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, s->row7 = row & 7; s->col = col; s->col7 = col & 7; + s->min_mv.x = -(128 + col * 64); s->min_mv.y = -(128 + row * 64); s->max_mv.x = 128 + (s->cols - col - w4) * 64; s->max_mv.y = 128 + (s->rows - row - h4) * 64; + if (s->pass < 2) { b->bs = bs; b->bl = bl; diff --git a/libavcodec/vp9data.c b/libavcodec/vp9data.c index f77e3398d9862..4057c736963bf 100644 --- a/libavcodec/vp9data.c +++ b/libavcodec/vp9data.c @@ -23,9 +23,9 @@ #include "vp9data.h" const int8_t ff_vp9_partition_tree[3][2] = { - { -PARTITION_NONE, 1 }, // '0' - { -PARTITION_H, 2 }, // '10' - { -PARTITION_V, -PARTITION_SPLIT }, // '110', '111' + { -PARTITION_NONE, 1 }, // '0' + { -PARTITION_H, 2 }, // '10' + { -PARTITION_V, -PARTITION_SPLIT }, // '110', '111' }; const uint8_t ff_vp9_default_kf_partition_probs[4][4][3] = { @@ -54,24 +54,24 @@ const uint8_t ff_vp9_default_kf_partition_probs[4][4][3] = { const int8_t ff_vp9_segmentation_tree[7][2] = { { 1, 2 }, - { 3, 4 }, - { 5, 6 }, - { -0, -1 }, // '00x' - { -2, -3 }, // '01x' - { -4, -5 }, // '10x' - { -6, -7 }, // '11x' + { 3, 4 }, + { 5, 6 }, + { -0, -1 }, // '00x' + { -2, -3 }, // '01x' + { -4, -5 }, // '10x' + { -6, -7 }, // '11x' }; const int8_t ff_vp9_intramode_tree[9][2] = { - { -DC_PRED, 1 }, // '0' - { -TM_VP8_PRED, 2 }, // '10' - { -VERT_PRED, 3 }, // '110' - { 4, 6 }, - { -HOR_PRED, 5 }, // '11100' - { -DIAG_DOWN_RIGHT_PRED, -VERT_RIGHT_PRED }, // '11101x' - { -DIAG_DOWN_LEFT_PRED, 7 }, // '11110' - { -VERT_LEFT_PRED, 8 }, // '111110' - { -HOR_DOWN_PRED, -HOR_UP_PRED }, // '111111x' + { -DC_PRED, 1 }, // '0' + { -TM_VP8_PRED, 2 }, // '10' + { -VERT_PRED, 3 }, // '110' + { 4, 6 }, + { -HOR_PRED, 5 }, // '11100' + { -DIAG_DOWN_RIGHT_PRED, -VERT_RIGHT_PRED }, // '11101x' + { -DIAG_DOWN_LEFT_PRED, 7 }, // '11110' + { -VERT_LEFT_PRED, 8 }, // '111110' + { -HOR_DOWN_PRED, -HOR_UP_PRED }, // '111111x' }; const uint8_t ff_vp9_default_kf_ymode_probs[10][10][9] = { @@ -202,14 +202,14 @@ const uint8_t ff_vp9_default_kf_uvmode_probs[10][9] = { }; const int8_t ff_vp9_inter_mode_tree[3][2] = { - { -ZEROMV, 1 }, // '0' - { -NEARESTMV, 2 }, // '10' - { -NEARMV, -NEWMV }, // '11x' + { -ZEROMV, 1 }, // '0' + { -NEARESTMV, 2 }, // '10' + { -NEARMV, -NEWMV }, // '11x' }; const int8_t ff_vp9_filter_tree[2][2] = { - { -0, 1 }, // '0' - { -1, -2 }, // '1x' + { -0, 1 }, // '0' + { -1, -2 }, // '1x' }; const enum FilterMode ff_vp9_filter_lut[3] = { @@ -1445,13 +1445,13 @@ const ProbContext ff_vp9_default_probs = { { 34, 3, }, { 149, 144, }, }, { /* mv_mode */ - { 2, 173, 34}, // 0 = both zero mv - { 7, 145, 85}, // 1 = one zero mv + one a predicted mv - { 7, 166, 63}, // 2 = two predicted mvs - { 7, 94, 66}, // 3 = one predicted/zero and one new mv - { 8, 64, 46}, // 4 = two new mvs - { 17, 81, 31}, // 5 = one intra neighbour + x - { 25, 29, 30}, // 6 = two intra neighbours + { 2, 173, 34 }, // 0 = both zero mv + { 7, 145, 85 }, // 1 = one zero mv + one a predicted mv + { 7, 166, 63 }, // 2 = two predicted mvs + { 7, 94, 66 }, // 3 = one predicted/zero and one new mv + { 8, 64, 46 }, // 4 = two new mvs + { 17, 81, 31 }, // 5 = one intra neighbor + x + { 25, 29, 30 }, // 6 = two intra neighbors }, { /* intra */ 9, 102, 187, 225 }, { /* comp */ @@ -1481,7 +1481,7 @@ const ProbContext ff_vp9_default_probs = { 128, /* sign */ { 224, 144, 192, 168, 192, 176, 192, 198, 198, 245 }, /* class */ 216, /* class0 */ - { 136, 140, 148, 160, 176, 192, 224, 234, 234, 240}, /* bits */ + { 136, 140, 148, 160, 176, 192, 224, 234, 234, 240 }, /* bits */ { /* class0_fp */ { 128, 128, 64 }, { 96, 112, 64 } @@ -2212,26 +2212,26 @@ const uint8_t ff_vp9_default_coef_probs[4][2][2][6][6][3] = { }; const int8_t ff_vp9_mv_joint_tree[3][2] = { - { -MV_JOINT_ZERO, 1 }, // '0' - { -MV_JOINT_H, 2 }, // '10' - { -MV_JOINT_V, -MV_JOINT_HV }, // '11x' + { -MV_JOINT_ZERO, 1 }, // '0' + { -MV_JOINT_H, 2 }, // '10' + { -MV_JOINT_V, -MV_JOINT_HV }, // '11x' }; const int8_t ff_vp9_mv_class_tree[10][2] = { - { -0, 1 }, // '0' - { -1, 2 }, // '10' - { 3, 4 }, - { -2, -3 }, // '110x' - { 5, 6 }, - { -4, -5 }, // '1110x' - { -6, 7 }, // '11110' - { 8, 9 }, - { -7, -8 }, // '111110x' - { -9, -10 }, // '111111x' + { -0, 1 }, // '0' + { -1, 2 }, // '10' + { 3, 4 }, + { -2, -3 }, // '110x' + { 5, 6 }, + { -4, -5 }, // '1110x' + { -6, 7 }, // '11110' + { 8, 9 }, + { -7, -8 }, // '111110x' + { -9, -10 }, // '111111x' }; const int8_t ff_vp9_mv_fp_tree[3][2] = { - { -0, 1 }, // '0' - { -1, 2 }, // '10' - { -2, -3 }, // '11x' + { -0, 1 }, // '0' + { -1, 2 }, // '10' + { -2, -3 }, // '11x' }; diff --git a/libavcodec/vp9mvs.c b/libavcodec/vp9mvs.c index d78096be540a2..0de2ecfa231cc 100644 --- a/libavcodec/vp9mvs.c +++ b/libavcodec/vp9mvs.c @@ -37,32 +37,32 @@ static void find_ref_mvs(VP9Context *s, VP56mv *pmv, int ref, int z, int idx, int sb) { static const int8_t mv_ref_blk_off[N_BS_SIZES][8][2] = { - [BS_64x64] = {{ 3, -1 }, { -1, 3 }, { 4, -1 }, { -1, 4 }, - { -1, -1 }, { 0, -1 }, { -1, 0 }, { 6, -1 }}, - [BS_64x32] = {{ 0, -1 }, { -1, 0 }, { 4, -1 }, { -1, 2 }, - { -1, -1 }, { 0, -3 }, { -3, 0 }, { 2, -1 }}, - [BS_32x64] = {{ -1, 0 }, { 0, -1 }, { -1, 4 }, { 2, -1 }, - { -1, -1 }, { -3, 0 }, { 0, -3 }, { -1, 2 }}, - [BS_32x32] = {{ 1, -1 }, { -1, 1 }, { 2, -1 }, { -1, 2 }, - { -1, -1 }, { 0, -3 }, { -3, 0 }, { -3, -3 }}, - [BS_32x16] = {{ 0, -1 }, { -1, 0 }, { 2, -1 }, { -1, -1 }, - { -1, 1 }, { 0, -3 }, { -3, 0 }, { -3, -3 }}, - [BS_16x32] = {{ -1, 0 }, { 0, -1 }, { -1, 2 }, { -1, -1 }, - { 1, -1 }, { -3, 0 }, { 0, -3 }, { -3, -3 }}, - [BS_16x16] = {{ 0, -1 }, { -1, 0 }, { 1, -1 }, { -1, 1 }, - { -1, -1 }, { 0, -3 }, { -3, 0 }, { -3, -3 }}, - [BS_16x8] = {{ 0, -1 }, { -1, 0 }, { 1, -1 }, { -1, -1 }, - { 0, -2 }, { -2, 0 }, { -2, -1 }, { -1, -2 }}, - [BS_8x16] = {{ -1, 0 }, { 0, -1 }, { -1, 1 }, { -1, -1 }, - { -2, 0 }, { 0, -2 }, { -1, -2 }, { -2, -1 }}, - [BS_8x8] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, - { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }}, - [BS_8x4] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, - { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }}, - [BS_4x8] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, - { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }}, - [BS_4x4] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, - { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }}, + [BS_64x64] = { { 3, -1 }, { -1, 3 }, { 4, -1 }, { -1, 4 }, + { -1, -1 }, { 0, -1 }, { -1, 0 }, { 6, -1 } }, + [BS_64x32] = { { 0, -1 }, { -1, 0 }, { 4, -1 }, { -1, 2 }, + { -1, -1 }, { 0, -3 }, { -3, 0 }, { 2, -1 } }, + [BS_32x64] = { { -1, 0 }, { 0, -1 }, { -1, 4 }, { 2, -1 }, + { -1, -1 }, { -3, 0 }, { 0, -3 }, { -1, 2 } }, + [BS_32x32] = { { 1, -1 }, { -1, 1 }, { 2, -1 }, { -1, 2 }, + { -1, -1 }, { 0, -3 }, { -3, 0 }, { -3, -3 } }, + [BS_32x16] = { { 0, -1 }, { -1, 0 }, { 2, -1 }, { -1, -1 }, + { -1, 1 }, { 0, -3 }, { -3, 0 }, { -3, -3 } }, + [BS_16x32] = { { -1, 0 }, { 0, -1 }, { -1, 2 }, { -1, -1 }, + { 1, -1 }, { -3, 0 }, { 0, -3 }, { -3, -3 } }, + [BS_16x16] = { { 0, -1 }, { -1, 0 }, { 1, -1 }, { -1, 1 }, + { -1, -1 }, { 0, -3 }, { -3, 0 }, { -3, -3 } }, + [BS_16x8] = { { 0, -1 }, { -1, 0 }, { 1, -1 }, { -1, -1 }, + { 0, -2 }, { -2, 0 }, { -2, -1 }, { -1, -2 } }, + [BS_8x16] = { { -1, 0 }, { 0, -1 }, { -1, 1 }, { -1, -1 }, + { -2, 0 }, { 0, -2 }, { -1, -2 }, { -2, -1 } }, + [BS_8x8] = { { 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, + { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } }, + [BS_8x4] = { { 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, + { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } }, + [BS_4x8] = { { 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, + { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } }, + [BS_4x4] = { { 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, + { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } }, }; VP9Block *b = s->b; int row = s->row, col = s->col, row7 = s->row7; @@ -71,18 +71,18 @@ static void find_ref_mvs(VP9Context *s, uint32_t mem = INVALID_MV, mem_sub8x8 = INVALID_MV; int i; -#define RETURN_DIRECT_MV(mv) \ - do { \ - uint32_t m = AV_RN32A(&mv); \ - if (!idx) { \ - AV_WN32A(pmv, m); \ - return; \ - } else if (mem == INVALID_MV) { \ - mem = m; \ - } else if (m != mem) { \ - AV_WN32A(pmv, m); \ - return; \ - } \ +#define RETURN_DIRECT_MV(mv) \ + do { \ + uint32_t m = AV_RN32A(&mv); \ + if (!idx) { \ + AV_WN32A(pmv, m); \ + return; \ + } else if (mem == INVALID_MV) { \ + mem = m; \ + } else if (m != mem) { \ + AV_WN32A(pmv, m); \ + return; \ + } \ } while (0) if (sb >= 0) { @@ -94,79 +94,77 @@ static void find_ref_mvs(VP9Context *s, RETURN_DIRECT_MV(b->mv[0][z]); } -#define RETURN_MV(mv) \ - do { \ - if (sb > 0) { \ - VP56mv tmp; \ - uint32_t m; \ - av_assert2(idx == 1); \ - av_assert2(mem != INVALID_MV); \ - if (mem_sub8x8 == INVALID_MV) { \ - clamp_mv(&tmp, &mv, s); \ - m = AV_RN32A(&tmp); \ - if (m != mem) { \ - AV_WN32A(pmv, m); \ - return; \ - } \ - mem_sub8x8 = AV_RN32A(&mv); \ - } else if (mem_sub8x8 != AV_RN32A(&mv)) { \ - clamp_mv(&tmp, &mv, s); \ - m = AV_RN32A(&tmp); \ - if (m != mem) { \ - AV_WN32A(pmv, m); \ - } else { \ +#define RETURN_MV(mv) \ + do { \ + if (sb > 0) { \ + VP56mv tmp; \ + uint32_t m; \ + av_assert2(idx == 1); \ + av_assert2(mem != INVALID_MV); \ + if (mem_sub8x8 == INVALID_MV) { \ + clamp_mv(&tmp, &mv, s); \ + m = AV_RN32A(&tmp); \ + if (m != mem) { \ + AV_WN32A(pmv, m); \ + return; \ + } \ + mem_sub8x8 = AV_RN32A(&mv); \ + } else if (mem_sub8x8 != AV_RN32A(&mv)) { \ + clamp_mv(&tmp, &mv, s); \ + m = AV_RN32A(&tmp); \ + if (m != mem) { \ + AV_WN32A(pmv, m); \ + } else { \ /* BUG I'm pretty sure this isn't the intention */ \ - AV_WN32A(pmv, 0); \ - } \ - return; \ - } \ - } else { \ - uint32_t m = AV_RN32A(&mv); \ - if (!idx) { \ - clamp_mv(pmv, &mv, s); \ - return; \ - } else if (mem == INVALID_MV) { \ - mem = m; \ - } else if (m != mem) { \ - clamp_mv(pmv, &mv, s); \ - return; \ - } \ - } \ + AV_WN32A(pmv, 0); \ + } \ + return; \ + } \ + } else { \ + uint32_t m = AV_RN32A(&mv); \ + if (!idx) { \ + clamp_mv(pmv, &mv, s); \ + return; \ + } else if (mem == INVALID_MV) { \ + mem = m; \ + } else if (m != mem) { \ + clamp_mv(pmv, &mv, s); \ + return; \ + } \ + } \ } while (0) if (row > 0) { struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[(row - 1) * s->sb_cols * 8 + col]; - if (mv->ref[0] == ref) { + if (mv->ref[0] == ref) RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][0]); - } else if (mv->ref[1] == ref) { + else if (mv->ref[1] == ref) RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][1]); - } } if (col > s->tile_col_start) { struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[row * s->sb_cols * 8 + col - 1]; - if (mv->ref[0] == ref) { + if (mv->ref[0] == ref) RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][0]); - } else if (mv->ref[1] == ref) { + else if (mv->ref[1] == ref) RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][1]); - } } i = 2; } else { i = 0; } - // previously coded MVs in this neighbourhood, using same reference frame + // previously coded MVs in this neighborhood, using same reference frame for (; i < 8; i++) { int c = p[i][0] + col, r = p[i][1] + row; - if (c >= s->tile_col_start && c < s->cols && r >= 0 && r < s->rows) { + if (c >= s->tile_col_start && c < s->cols && + r >= 0 && r < s->rows) { struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c]; - if (mv->ref[0] == ref) { + if (mv->ref[0] == ref) RETURN_MV(mv->mv[0]); - } else if (mv->ref[1] == ref) { + else if (mv->ref[1] == ref) RETURN_MV(mv->mv[1]); - } } } @@ -176,33 +174,32 @@ static void find_ref_mvs(VP9Context *s, if (!s->s.frames[REF_FRAME_MVPAIR].uses_2pass) ff_thread_await_progress(&s->s.frames[REF_FRAME_MVPAIR].tf, row >> 3, 0); - if (mv->ref[0] == ref) { + if (mv->ref[0] == ref) RETURN_MV(mv->mv[0]); - } else if (mv->ref[1] == ref) { + else if (mv->ref[1] == ref) RETURN_MV(mv->mv[1]); - } } -#define RETURN_SCALE_MV(mv, scale) \ - do { \ - if (scale) { \ - VP56mv mv_temp = { -mv.x, -mv.y }; \ - RETURN_MV(mv_temp); \ - } else { \ - RETURN_MV(mv); \ - } \ +#define RETURN_SCALE_MV(mv, scale) \ + do { \ + if (scale) { \ + VP56mv mv_temp = { -mv.x, -mv.y }; \ + RETURN_MV(mv_temp); \ + } else { \ + RETURN_MV(mv); \ + } \ } while (0) - // previously coded MVs in this neighbourhood, using different reference frame + // previously coded MVs in this neighborhood, using different reference frame for (i = 0; i < 8; i++) { int c = p[i][0] + col, r = p[i][1] + row; if (c >= s->tile_col_start && c < s->cols && r >= 0 && r < s->rows) { struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c]; - if (mv->ref[0] != ref && mv->ref[0] >= 0) { - RETURN_SCALE_MV(mv->mv[0], s->s.h.signbias[mv->ref[0]] != s->s.h.signbias[ref]); - } + if (mv->ref[0] != ref && mv->ref[0] >= 0) + RETURN_SCALE_MV(mv->mv[0], + s->s.h.signbias[mv->ref[0]] != s->s.h.signbias[ref]); if (mv->ref[1] != ref && mv->ref[1] >= 0 && // BUG - libvpx has this condition regardless of whether // we used the first ref MV and pre-scaling @@ -217,9 +214,8 @@ static void find_ref_mvs(VP9Context *s, struct VP9mvrefPair *mv = &s->s.frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col]; // no need to await_progress, because we already did that above - if (mv->ref[0] != ref && mv->ref[0] >= 0) { + if (mv->ref[0] != ref && mv->ref[0] >= 0) RETURN_SCALE_MV(mv->mv[0], s->s.h.signbias[mv->ref[0]] != s->s.h.signbias[ref]); - } if (mv->ref[1] != ref && mv->ref[1] >= 0 && // BUG - libvpx has this condition regardless of whether // we used the first ref MV and pre-scaling @@ -252,8 +248,9 @@ static av_always_inline int read_mv_component(VP9Context *s, int idx, int hp) s->counts.mv_comp[idx].bits[m][bit]++; } n <<= 3; - bit = vp8_rac_get_tree(&s->c, ff_vp9_mv_fp_tree, s->prob.p.mv_comp[idx].fp); - n |= bit << 1; + bit = vp8_rac_get_tree(&s->c, ff_vp9_mv_fp_tree, + s->prob.p.mv_comp[idx].fp); + n |= bit << 1; s->counts.mv_comp[idx].fp[bit]++; if (hp) { bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].hp); @@ -302,7 +299,8 @@ void ff_vp9_fill_mv(VP9Context *s, VP56mv *mv, int mode, int sb) mode == NEWMV ? -1 : sb); // FIXME maybe move this code into find_ref_mvs() if ((mode == NEWMV || sb == -1) && - !(hp = s->s.h.highprecisionmvs && abs(mv[0].x) < 64 && abs(mv[0].y) < 64)) { + !(hp = s->s.h.highprecisionmvs && + abs(mv[0].x) < 64 && abs(mv[0].y) < 64)) { if (mv[0].y & 1) { if (mv[0].y < 0) mv[0].y++; @@ -332,7 +330,8 @@ void ff_vp9_fill_mv(VP9Context *s, VP56mv *mv, int mode, int sb) find_ref_mvs(s, &mv[1], b->ref[1], 1, mode == NEARMV, mode == NEWMV ? -1 : sb); if ((mode == NEWMV || sb == -1) && - !(hp = s->s.h.highprecisionmvs && abs(mv[1].x) < 64 && abs(mv[1].y) < 64)) { + !(hp = s->s.h.highprecisionmvs && + abs(mv[1].x) < 64 && abs(mv[1].y) < 64)) { if (mv[1].y & 1) { if (mv[1].y < 0) mv[1].y++; diff --git a/libavcodec/vp9prob.c b/libavcodec/vp9prob.c index 948b87eb374a4..b45d20d3d0e1b 100644 --- a/libavcodec/vp9prob.c +++ b/libavcodec/vp9prob.c @@ -76,33 +76,36 @@ void ff_vp9_adapt_probs(VP9Context *s) // skip flag for (i = 0; i < 3; i++) - adapt_prob(&p->skip[i], s->counts.skip[i][0], s->counts.skip[i][1], 20, 128); + adapt_prob(&p->skip[i], s->counts.skip[i][0], + s->counts.skip[i][1], 20, 128); // intra/inter flag for (i = 0; i < 4; i++) - adapt_prob(&p->intra[i], s->counts.intra[i][0], s->counts.intra[i][1], 20, 128); + adapt_prob(&p->intra[i], s->counts.intra[i][0], + s->counts.intra[i][1], 20, 128); // comppred flag if (s->s.h.comppredmode == PRED_SWITCHABLE) { - for (i = 0; i < 5; i++) - adapt_prob(&p->comp[i], s->counts.comp[i][0], s->counts.comp[i][1], 20, 128); + for (i = 0; i < 5; i++) + adapt_prob(&p->comp[i], s->counts.comp[i][0], + s->counts.comp[i][1], 20, 128); } // reference frames if (s->s.h.comppredmode != PRED_SINGLEREF) { - for (i = 0; i < 5; i++) - adapt_prob(&p->comp_ref[i], s->counts.comp_ref[i][0], - s->counts.comp_ref[i][1], 20, 128); + for (i = 0; i < 5; i++) + adapt_prob(&p->comp_ref[i], s->counts.comp_ref[i][0], + s->counts.comp_ref[i][1], 20, 128); } if (s->s.h.comppredmode != PRED_COMPREF) { - for (i = 0; i < 5; i++) { - uint8_t *pp = p->single_ref[i]; - unsigned (*c)[2] = s->counts.single_ref[i]; + for (i = 0; i < 5; i++) { + uint8_t *pp = p->single_ref[i]; + unsigned (*c)[2] = s->counts.single_ref[i]; - adapt_prob(&pp[0], c[0][0], c[0][1], 20, 128); - adapt_prob(&pp[1], c[1][0], c[1][1], 20, 128); - } + adapt_prob(&pp[0], c[0][0], c[0][1], 20, 128); + adapt_prob(&pp[1], c[1][0], c[1][1], 20, 128); + } } // block partitioning @@ -118,16 +121,17 @@ void ff_vp9_adapt_probs(VP9Context *s) // tx size if (s->s.h.txfmmode == TX_SWITCHABLE) { - for (i = 0; i < 2; i++) { - unsigned *c16 = s->counts.tx16p[i], *c32 = s->counts.tx32p[i]; - - adapt_prob(&p->tx8p[i], s->counts.tx8p[i][0], s->counts.tx8p[i][1], 20, 128); - adapt_prob(&p->tx16p[i][0], c16[0], c16[1] + c16[2], 20, 128); - adapt_prob(&p->tx16p[i][1], c16[1], c16[2], 20, 128); - adapt_prob(&p->tx32p[i][0], c32[0], c32[1] + c32[2] + c32[3], 20, 128); - adapt_prob(&p->tx32p[i][1], c32[1], c32[2] + c32[3], 20, 128); - adapt_prob(&p->tx32p[i][2], c32[2], c32[3], 20, 128); - } + for (i = 0; i < 2; i++) { + unsigned *c16 = s->counts.tx16p[i], *c32 = s->counts.tx32p[i]; + + adapt_prob(&p->tx8p[i], s->counts.tx8p[i][0], + s->counts.tx8p[i][1], 20, 128); + adapt_prob(&p->tx16p[i][0], c16[0], c16[1] + c16[2], 20, 128); + adapt_prob(&p->tx16p[i][1], c16[1], c16[2], 20, 128); + adapt_prob(&p->tx32p[i][0], c32[0], c32[1] + c32[2] + c32[3], 20, 128); + adapt_prob(&p->tx32p[i][1], c32[1], c32[2] + c32[3], 20, 128); + adapt_prob(&p->tx32p[i][2], c32[2], c32[3], 20, 128); + } } // interpolation filter @@ -169,9 +173,10 @@ void ff_vp9_adapt_probs(VP9Context *s) adapt_prob(&p->mv_comp[i].sign, s->counts.mv_comp[i].sign[0], s->counts.mv_comp[i].sign[1], 20, 128); - pp = p->mv_comp[i].classes; - c = s->counts.mv_comp[i].classes; - sum = c[1] + c[2] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9] + c[10]; + pp = p->mv_comp[i].classes; + c = s->counts.mv_comp[i].classes; + sum = c[1] + c[2] + c[3] + c[4] + c[5] + + c[6] + c[7] + c[8] + c[9] + c[10]; adapt_prob(&pp[0], c[0], sum, 20, 128); sum -= c[1]; adapt_prob(&pp[1], c[1], sum, 20, 128); @@ -196,19 +201,20 @@ void ff_vp9_adapt_probs(VP9Context *s) for (j = 0; j < 2; j++) { pp = p->mv_comp[i].class0_fp[j]; - c = s->counts.mv_comp[i].class0_fp[j]; + c = s->counts.mv_comp[i].class0_fp[j]; adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); adapt_prob(&pp[2], c[2], c[3], 20, 128); } pp = p->mv_comp[i].fp; - c = s->counts.mv_comp[i].fp; + c = s->counts.mv_comp[i].fp; adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); adapt_prob(&pp[2], c[2], c[3], 20, 128); if (s->s.h.highprecisionmvs) { - adapt_prob(&p->mv_comp[i].class0_hp, s->counts.mv_comp[i].class0_hp[0], + adapt_prob(&p->mv_comp[i].class0_hp, + s->counts.mv_comp[i].class0_hp[0], s->counts.mv_comp[i].class0_hp[1], 20, 128); adapt_prob(&p->mv_comp[i].hp, s->counts.mv_comp[i].hp[0], s->counts.mv_comp[i].hp[1], 20, 128); @@ -226,12 +232,13 @@ void ff_vp9_adapt_probs(VP9Context *s) adapt_prob(&pp[1], c[TM_VP8_PRED], sum, 20, 128); sum -= c[VERT_PRED]; adapt_prob(&pp[2], c[VERT_PRED], sum, 20, 128); - s2 = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED]; + s2 = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED]; sum -= s2; adapt_prob(&pp[3], s2, sum, 20, 128); s2 -= c[HOR_PRED]; adapt_prob(&pp[4], c[HOR_PRED], s2, 20, 128); - adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED], 20, 128); + adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED], + 20, 128); sum -= c[DIAG_DOWN_LEFT_PRED]; adapt_prob(&pp[6], c[DIAG_DOWN_LEFT_PRED], sum, 20, 128); sum -= c[VERT_LEFT_PRED]; @@ -250,12 +257,13 @@ void ff_vp9_adapt_probs(VP9Context *s) adapt_prob(&pp[1], c[TM_VP8_PRED], sum, 20, 128); sum -= c[VERT_PRED]; adapt_prob(&pp[2], c[VERT_PRED], sum, 20, 128); - s2 = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED]; + s2 = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED]; sum -= s2; adapt_prob(&pp[3], s2, sum, 20, 128); s2 -= c[HOR_PRED]; adapt_prob(&pp[4], c[HOR_PRED], s2, 20, 128); - adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED], 20, 128); + adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED], + 20, 128); sum -= c[DIAG_DOWN_LEFT_PRED]; adapt_prob(&pp[6], c[DIAG_DOWN_LEFT_PRED], sum, 20, 128); sum -= c[VERT_LEFT_PRED]; From 37814a21cb7dfbaca56b518b09eb0f85a0fe70fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sat, 25 Mar 2017 13:19:52 +0100 Subject: [PATCH 1329/3374] lavc/vp9: consistent use of typedef instead of struct --- libavcodec/vp9.c | 14 +++++++------- libavcodec/vp9.h | 15 +++++++-------- libavcodec/vp9block.c | 4 ++-- libavcodec/vp9mvs.c | 12 ++++++------ 4 files changed, 22 insertions(+), 23 deletions(-) diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index c1c90ca65e047..dc0cea19e6cd3 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -55,13 +55,13 @@ static int vp9_frame_alloc(AVCodecContext *avctx, VP9Frame *f) return ret; sz = 64 * s->sb_cols * s->sb_rows; - f->extradata = av_buffer_allocz(sz * (1 + sizeof(struct VP9mvrefPair))); + f->extradata = av_buffer_allocz(sz * (1 + sizeof(VP9mvrefPair))); if (!f->extradata) { goto fail; } f->segmentation_map = f->extradata->data; - f->mv = (struct VP9mvrefPair *) (f->extradata->data + sz); + f->mv = (VP9mvrefPair *) (f->extradata->data + sz); if (avctx->hwaccel) { const AVHWAccel *hwaccel = avctx->hwaccel; @@ -194,7 +194,7 @@ static int update_size(AVCodecContext *avctx, int w, int h) assign(s->above_comp_ctx, uint8_t *, 8); assign(s->above_ref_ctx, uint8_t *, 8); assign(s->above_filter_ctx, uint8_t *, 8); - assign(s->lflvl, struct VP9Filter *, 1); + assign(s->lflvl, VP9Filter *, 1); #undef assign // these will be re-allocated a little later @@ -924,7 +924,7 @@ static int decode_frame_header(AVCodecContext *avctx, return (data2 - data) + size2; } -static void decode_sb(AVCodecContext *avctx, int row, int col, struct VP9Filter *lflvl, +static void decode_sb(AVCodecContext *avctx, int row, int col, VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl) { VP9Context *s = avctx->priv_data; @@ -1003,7 +1003,7 @@ static void decode_sb(AVCodecContext *avctx, int row, int col, struct VP9Filter s->counts.partition[bl][c][bp]++; } -static void decode_sb_mem(AVCodecContext *avctx, int row, int col, struct VP9Filter *lflvl, +static void decode_sb_mem(AVCodecContext *avctx, int row, int col, VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl) { VP9Context *s = avctx->priv_data; @@ -1204,7 +1204,7 @@ static av_always_inline void filter_plane_rows(VP9Context *s, int row, int ss_h, } } -static void loopfilter_sb(AVCodecContext *avctx, struct VP9Filter *lflvl, +static void loopfilter_sb(AVCodecContext *avctx, VP9Filter *lflvl, int row, int col, ptrdiff_t yoff, ptrdiff_t uvoff) { VP9Context *s = avctx->priv_data; @@ -1449,7 +1449,7 @@ FF_ENABLE_DEPRECATION_WARNINGS for (row = s->tile_row_start; row < s->tile_row_end; row += 8, yoff += ls_y * 64, uvoff += ls_uv * 64 >> s->ss_v) { - struct VP9Filter *lflvl_ptr = s->lflvl; + VP9Filter *lflvl_ptr = s->lflvl; ptrdiff_t yoff2 = yoff, uvoff2 = uvoff; for (tile_col = 0; tile_col < s->s.h.tiling.tile_cols; tile_col++) { diff --git a/libavcodec/vp9.h b/libavcodec/vp9.h index 0097385e1ca58..ef277b1d1d4f1 100644 --- a/libavcodec/vp9.h +++ b/libavcodec/vp9.h @@ -248,23 +248,22 @@ typedef struct VP9DSPContext { vp9_scaled_mc_func smc[5][4][2]; } VP9DSPContext; - -struct VP9mvrefPair { +typedef struct VP9mvrefPair { VP56mv mv[2]; int8_t ref[2]; -}; +} VP9mvrefPair; -struct VP9Filter { +typedef struct VP9Filter { uint8_t level[8 * 8]; uint8_t /* bit=col */ mask[2 /* 0=y, 1=uv */][2 /* 0=col, 1=row */] [8 /* rows */][4 /* 0=16, 1=8, 2=4, 3=inner4 */]; -}; +} VP9Filter; typedef struct VP9Frame { ThreadFrame tf; AVBufferRef *extradata; uint8_t *segmentation_map; - struct VP9mvrefPair *mv; + VP9mvrefPair *mv; int uses_2pass; AVBufferRef *hwaccel_priv_buf; @@ -454,7 +453,7 @@ typedef struct VP9Context { // whole-frame cache uint8_t *intra_pred_data[3]; - struct VP9Filter *lflvl; + VP9Filter *lflvl; DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[135 * 144 * 2]; // block reconstruction intermediates @@ -486,7 +485,7 @@ void ff_vp9_fill_mv(VP9Context *s, VP56mv *mv, int mode, int sb); void ff_vp9_adapt_probs(VP9Context *s); void ff_vp9_decode_block(AVCodecContext *ctx, int row, int col, - struct VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, + VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl, enum BlockPartition bp); #endif /* AVCODEC_VP9_H */ diff --git a/libavcodec/vp9block.c b/libavcodec/vp9block.c index 70c701579969e..e5e117134df11 100644 --- a/libavcodec/vp9block.c +++ b/libavcodec/vp9block.c @@ -785,7 +785,7 @@ static void decode_mode(AVCodecContext *avctx) // FIXME kinda ugly for (y = 0; y < h4; y++) { int x, o = (row + y) * s->sb_cols * 8 + col; - struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[o]; + VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[o]; if (b->intra) { for (x = 0; x < w4; x++) { @@ -1883,7 +1883,7 @@ static av_always_inline void mask_edges(uint8_t (*mask)[8][4], int ss_h, int ss_ } void ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, - struct VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, + VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl, enum BlockPartition bp) { VP9Context *s = avctx->priv_data; diff --git a/libavcodec/vp9mvs.c b/libavcodec/vp9mvs.c index 0de2ecfa231cc..a66972bc8ba4c 100644 --- a/libavcodec/vp9mvs.c +++ b/libavcodec/vp9mvs.c @@ -135,14 +135,14 @@ static void find_ref_mvs(VP9Context *s, } while (0) if (row > 0) { - struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[(row - 1) * s->sb_cols * 8 + col]; + VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[(row - 1) * s->sb_cols * 8 + col]; if (mv->ref[0] == ref) RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][0]); else if (mv->ref[1] == ref) RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][1]); } if (col > s->tile_col_start) { - struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[row * s->sb_cols * 8 + col - 1]; + VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[row * s->sb_cols * 8 + col - 1]; if (mv->ref[0] == ref) RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][0]); else if (mv->ref[1] == ref) @@ -159,7 +159,7 @@ static void find_ref_mvs(VP9Context *s, if (c >= s->tile_col_start && c < s->cols && r >= 0 && r < s->rows) { - struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c]; + VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c]; if (mv->ref[0] == ref) RETURN_MV(mv->mv[0]); @@ -170,7 +170,7 @@ static void find_ref_mvs(VP9Context *s, // MV at this position in previous frame, using same reference frame if (s->s.h.use_last_frame_mvs) { - struct VP9mvrefPair *mv = &s->s.frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col]; + VP9mvrefPair *mv = &s->s.frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col]; if (!s->s.frames[REF_FRAME_MVPAIR].uses_2pass) ff_thread_await_progress(&s->s.frames[REF_FRAME_MVPAIR].tf, row >> 3, 0); @@ -195,7 +195,7 @@ static void find_ref_mvs(VP9Context *s, int c = p[i][0] + col, r = p[i][1] + row; if (c >= s->tile_col_start && c < s->cols && r >= 0 && r < s->rows) { - struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c]; + VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c]; if (mv->ref[0] != ref && mv->ref[0] >= 0) RETURN_SCALE_MV(mv->mv[0], @@ -211,7 +211,7 @@ static void find_ref_mvs(VP9Context *s, // MV at this position in previous frame, using different reference frame if (s->s.h.use_last_frame_mvs) { - struct VP9mvrefPair *mv = &s->s.frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col]; + VP9mvrefPair *mv = &s->s.frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col]; // no need to await_progress, because we already did that above if (mv->ref[0] != ref && mv->ref[0] >= 0) From e6ffdc9582a220ce77af348ec49b13eb887fe88f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sat, 25 Mar 2017 13:24:46 +0100 Subject: [PATCH 1330/3374] lavc/vp9: shuffle header declaration This reduces diff with Libav. --- libavcodec/vp9.h | 104 +++++++++++++++++++++++------------------------ 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/libavcodec/vp9.h b/libavcodec/vp9.h index ef277b1d1d4f1..a2067303000f4 100644 --- a/libavcodec/vp9.h +++ b/libavcodec/vp9.h @@ -34,37 +34,6 @@ #include "thread.h" #include "vp56.h" -enum BlockLevel { - BL_64X64, - BL_32X32, - BL_16X16, - BL_8X8, -}; - -enum BlockPartition { - PARTITION_NONE, // [ ] <-. - PARTITION_H, // [-] | - PARTITION_V, // [|] | - PARTITION_SPLIT, // [+] --' -}; - -enum BlockSize { - BS_64x64, - BS_64x32, - BS_32x64, - BS_32x32, - BS_32x16, - BS_16x32, - BS_16x16, - BS_16x8, - BS_8x16, - BS_8x8, - BS_8x4, - BS_4x8, - BS_4x4, - N_BS_SIZES, -}; - enum TxfmMode { TX_4X4, TX_8X8, @@ -102,13 +71,6 @@ enum IntraPredMode { N_INTRA_PRED_MODES }; -enum InterPredMode { - NEARESTMV = 10, - NEARMV = 11, - ZEROMV = 12, - NEWMV = 13, -}; - enum FilterMode { FILTER_8TAP_SMOOTH, FILTER_8TAP_REGULAR, @@ -117,10 +79,18 @@ enum FilterMode { FILTER_SWITCHABLE, }; -enum CompPredMode { - PRED_SINGLEREF, - PRED_COMPREF, - PRED_SWITCHABLE, +enum BlockPartition { + PARTITION_NONE, // [ ] <-. + PARTITION_H, // [-] | + PARTITION_V, // [|] | + PARTITION_SPLIT, // [+] --' +}; + +enum InterPredMode { + NEARESTMV = 10, + NEARMV = 11, + ZEROMV = 12, + NEWMV = 13, }; enum MVJoint { @@ -248,6 +218,12 @@ typedef struct VP9DSPContext { vp9_scaled_mc_func smc[5][4][2]; } VP9DSPContext; +enum CompPredMode { + PRED_SINGLEREF, + PRED_COMPREF, + PRED_SWITCHABLE, +}; + typedef struct VP9mvrefPair { VP56mv mv[2]; int8_t ref[2]; @@ -270,6 +246,40 @@ typedef struct VP9Frame { void *hwaccel_picture_private; } VP9Frame; +enum BlockLevel { + BL_64X64, + BL_32X32, + BL_16X16, + BL_8X8, +}; + +enum BlockSize { + BS_64x64, + BS_64x32, + BS_32x64, + BS_32x32, + BS_32x16, + BS_16x32, + BS_16x16, + BS_16x8, + BS_8x16, + BS_8x8, + BS_8x4, + BS_4x8, + BS_4x4, + N_BS_SIZES, +}; + +typedef struct VP9Block { + uint8_t seg_id, intra, comp, ref[2], mode[4], uvmode, skip; + enum FilterMode filter; + VP56mv mv[4 /* b_idx */][2 /* ref */]; + enum BlockSize bs; + enum TxfmMode tx, uvtx; + enum BlockLevel bl; + enum BlockPartition bp; +} VP9Block; + typedef struct VP9BitstreamHeader { // bitstream header uint8_t profile; @@ -345,16 +355,6 @@ typedef struct VP9SharedContext { VP9Frame frames[3]; } VP9SharedContext; -typedef struct VP9Block { - uint8_t seg_id, intra, comp, ref[2], mode[4], uvmode, skip; - enum FilterMode filter; - VP56mv mv[4 /* b_idx */][2 /* ref */]; - enum BlockSize bs; - enum TxfmMode tx, uvtx; - enum BlockLevel bl; - enum BlockPartition bp; -} VP9Block; - typedef struct VP9Context { VP9SharedContext s; From 5dd37c684736b3103430ffa94593726623ba3ff5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sat, 25 Mar 2017 13:33:07 +0100 Subject: [PATCH 1331/3374] lavc/vp9: clarify inv_recenter_nonneg Ends up identical to Libav. --- libavcodec/vp9.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index dc0cea19e6cd3..202b29e2eb541 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -261,7 +261,11 @@ static av_always_inline int get_sbits_inv(GetBitContext *gb, int n) static av_always_inline int inv_recenter_nonneg(int v, int m) { - return v > 2 * m ? v : v & 1 ? m - ((v + 1) >> 1) : m + (v >> 1); + if (v > 2 * m) + return v; + if (v & 1) + return m - ((v + 1) >> 1); + return m + (v >> 1); } // differential forward probability updates From b4189590a59159317f6316106e2f061e5c6df556 Mon Sep 17 00:00:00 2001 From: Aaron Colwell Date: Mon, 27 Mar 2017 08:00:12 -0700 Subject: [PATCH 1332/3374] movenc: Add support for writing st3d and sv3d boxes. Signed-off-by: James Almer --- libavformat/movenc.c | 99 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 3b4e3b519c202..112471d1ebd83 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -46,6 +46,7 @@ #include "libavutil/opt.h" #include "libavutil/dict.h" #include "libavutil/pixdesc.h" +#include "libavutil/stereo3d.h" #include "libavutil/timecode.h" #include "libavutil/color_utils.h" #include "hevc.h" @@ -1603,6 +1604,94 @@ static int mov_write_subtitle_tag(AVIOContext *pb, MOVTrack *track) return update_size(pb, pos); } +static int mov_write_st3d_tag(AVIOContext *pb, AVStereo3D *stereo_3d) +{ + int8_t stereo_mode; + + if (stereo_3d->flags != 0) { + av_log(pb, AV_LOG_WARNING, "Unsupported stereo_3d flags %x. st3d not written.\n", stereo_3d->flags); + return 0; + } + + switch (stereo_3d->type) { + case AV_STEREO3D_2D: + stereo_mode = 0; + break; + case AV_STEREO3D_TOPBOTTOM: + stereo_mode = 1; + break; + case AV_STEREO3D_SIDEBYSIDE: + stereo_mode = 2; + break; + default: + av_log(pb, AV_LOG_WARNING, "Unsupported stereo_3d type %s. st3d not written.\n", av_stereo3d_type_name(stereo_3d->type)); + return 0; + } + avio_wb32(pb, 13); /* size */ + ffio_wfourcc(pb, "st3d"); + avio_wb32(pb, 0); /* version = 0 & flags = 0 */ + avio_w8(pb, stereo_mode); + return 13; +} + +static int mov_write_sv3d_tag(AVFormatContext *s, AVIOContext *pb, AVSphericalMapping *spherical_mapping) +{ + int64_t sv3d_pos, svhd_pos, proj_pos; + const char* metadata_source = s->flags & AVFMT_FLAG_BITEXACT ? "Lavf" : LIBAVFORMAT_IDENT; + + if (spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR && + spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR_TILE && + spherical_mapping->projection != AV_SPHERICAL_CUBEMAP) { + av_log(pb, AV_LOG_WARNING, "Unsupported projection %d. sv3d not written.\n", spherical_mapping->projection); + return 0; + } + + sv3d_pos = avio_tell(pb); + avio_wb32(pb, 0); /* size */ + ffio_wfourcc(pb, "sv3d"); + + svhd_pos = avio_tell(pb); + avio_wb32(pb, 0); /* size */ + ffio_wfourcc(pb, "svhd"); + avio_wb32(pb, 0); /* version = 0 & flags = 0 */ + avio_put_str(pb, metadata_source); + update_size(pb, svhd_pos); + + proj_pos = avio_tell(pb); + avio_wb32(pb, 0); /* size */ + ffio_wfourcc(pb, "proj"); + + avio_wb32(pb, 24); /* size */ + ffio_wfourcc(pb, "prhd"); + avio_wb32(pb, 0); /* version = 0 & flags = 0 */ + avio_wb32(pb, spherical_mapping->yaw); + avio_wb32(pb, spherical_mapping->pitch); + avio_wb32(pb, spherical_mapping->roll); + + switch (spherical_mapping->projection) { + case AV_SPHERICAL_EQUIRECTANGULAR: + case AV_SPHERICAL_EQUIRECTANGULAR_TILE: + avio_wb32(pb, 28); /* size */ + ffio_wfourcc(pb, "equi"); + avio_wb32(pb, 0); /* version = 0 & flags = 0 */ + avio_wb32(pb, spherical_mapping->bound_top); + avio_wb32(pb, spherical_mapping->bound_bottom); + avio_wb32(pb, spherical_mapping->bound_left); + avio_wb32(pb, spherical_mapping->bound_right); + break; + case AV_SPHERICAL_CUBEMAP: + avio_wb32(pb, 20); /* size */ + ffio_wfourcc(pb, "cbmp"); + avio_wb32(pb, 0); /* version = 0 & flags = 0 */ + avio_wb32(pb, 0); /* layout */ + avio_wb32(pb, spherical_mapping->padding); /* padding */ + break; + } + update_size(pb, proj_pos); + + return update_size(pb, sv3d_pos); +} + static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track) { AVRational sar; @@ -1873,6 +1962,16 @@ static int mov_write_video_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *tr av_log(mov->fc, AV_LOG_WARNING, "Not writing 'colr' atom. Format is not MOV or MP4.\n"); } + if (mov->fc->strict_std_compliance <= FF_COMPLIANCE_EXPERIMENTAL) { + AVStereo3D* stereo_3d = (AVStereo3D*) av_stream_get_side_data(track->st, AV_PKT_DATA_STEREO3D, NULL); + AVSphericalMapping* spherical_mapping = (AVSphericalMapping*)av_stream_get_side_data(track->st, AV_PKT_DATA_SPHERICAL, NULL); + + if (stereo_3d) + mov_write_st3d_tag(pb, stereo_3d); + if (spherical_mapping) + mov_write_sv3d_tag(mov->fc, pb, spherical_mapping); + } + if (track->par->sample_aspect_ratio.den && track->par->sample_aspect_ratio.num) { mov_write_pasp_tag(pb, track); } From a715e5a276c03e0a3a47531d382106ec3390c756 Mon Sep 17 00:00:00 2001 From: James Almer Date: Mon, 27 Mar 2017 17:09:45 -0300 Subject: [PATCH 1333/3374] avformat/movenc: restrict st3d and sv3d mov atoms to MODE_MP4 --- libavformat/movenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 112471d1ebd83..0891e72ee7b11 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -1962,7 +1962,7 @@ static int mov_write_video_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *tr av_log(mov->fc, AV_LOG_WARNING, "Not writing 'colr' atom. Format is not MOV or MP4.\n"); } - if (mov->fc->strict_std_compliance <= FF_COMPLIANCE_EXPERIMENTAL) { + if (track->mode == MODE_MP4 && mov->fc->strict_std_compliance <= FF_COMPLIANCE_EXPERIMENTAL) { AVStereo3D* stereo_3d = (AVStereo3D*) av_stream_get_side_data(track->st, AV_PKT_DATA_STEREO3D, NULL); AVSphericalMapping* spherical_mapping = (AVSphericalMapping*)av_stream_get_side_data(track->st, AV_PKT_DATA_SPHERICAL, NULL); From 86dee47e397fe6bb0907adae8d4a54138a947646 Mon Sep 17 00:00:00 2001 From: James Almer Date: Mon, 27 Mar 2017 17:10:33 -0300 Subject: [PATCH 1334/3374] avformat/movenc: allow st3d and sv3d mov atoms to be written in strict unofficial mode They are unofficial extensions to the format for the time being, not an experimental feature. --- libavformat/movenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 0891e72ee7b11..a660645efea49 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -1962,7 +1962,7 @@ static int mov_write_video_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *tr av_log(mov->fc, AV_LOG_WARNING, "Not writing 'colr' atom. Format is not MOV or MP4.\n"); } - if (track->mode == MODE_MP4 && mov->fc->strict_std_compliance <= FF_COMPLIANCE_EXPERIMENTAL) { + if (track->mode == MODE_MP4 && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) { AVStereo3D* stereo_3d = (AVStereo3D*) av_stream_get_side_data(track->st, AV_PKT_DATA_STEREO3D, NULL); AVSphericalMapping* spherical_mapping = (AVSphericalMapping*)av_stream_get_side_data(track->st, AV_PKT_DATA_SPHERICAL, NULL); From bcd7153df382d0ff81453bc4044a954058c92841 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 31 May 2016 21:23:27 +0200 Subject: [PATCH 1335/3374] ffprobe: Support adding av_log output to frames adding demuxer and other logs should be easy This forces single threaded decoding for simplicity It also requires pthreads, this could be avoided either with some lockless tricks or simply by assuming av_log would never be called from another thread. Fixes Ticket5521 Previous version reviewed by Stefano Signed-off-by: Michael Niedermayer --- ffprobe.c | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 158 insertions(+), 1 deletion(-) diff --git a/ffprobe.c b/ffprobe.c index ba27bce82384e..17b4580a42965 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -51,6 +51,19 @@ #include "libpostproc/postprocess.h" #include "cmdutils.h" +#include "libavutil/thread.h" + +#if !HAVE_THREADS +# ifdef pthread_mutex_lock +# undef pthread_mutex_lock +# endif +# define pthread_mutex_lock(a) +# ifdef pthread_mutex_unlock +# undef pthread_mutex_unlock +# endif +# define pthread_mutex_unlock(a) +#endif + typedef struct InputStream { AVStream *st; @@ -86,6 +99,7 @@ static int do_show_library_versions = 0; static int do_show_pixel_formats = 0; static int do_show_pixel_format_flags = 0; static int do_show_pixel_format_components = 0; +static int do_show_log = 0; static int do_show_chapter_tags = 0; static int do_show_format_tags = 0; @@ -148,6 +162,8 @@ typedef enum { SECTION_ID_FRAME_TAGS, SECTION_ID_FRAME_SIDE_DATA_LIST, SECTION_ID_FRAME_SIDE_DATA, + SECTION_ID_FRAME_LOG, + SECTION_ID_FRAME_LOGS, SECTION_ID_LIBRARY_VERSION, SECTION_ID_LIBRARY_VERSIONS, SECTION_ID_PACKET, @@ -187,10 +203,12 @@ static struct section sections[] = { [SECTION_ID_FORMAT] = { SECTION_ID_FORMAT, "format", 0, { SECTION_ID_FORMAT_TAGS, -1 } }, [SECTION_ID_FORMAT_TAGS] = { SECTION_ID_FORMAT_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "format_tags" }, [SECTION_ID_FRAMES] = { SECTION_ID_FRAMES, "frames", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME, SECTION_ID_SUBTITLE, -1 } }, - [SECTION_ID_FRAME] = { SECTION_ID_FRAME, "frame", 0, { SECTION_ID_FRAME_TAGS, SECTION_ID_FRAME_SIDE_DATA_LIST, -1 } }, + [SECTION_ID_FRAME] = { SECTION_ID_FRAME, "frame", 0, { SECTION_ID_FRAME_TAGS, SECTION_ID_FRAME_SIDE_DATA_LIST, SECTION_ID_FRAME_LOGS, -1 } }, [SECTION_ID_FRAME_TAGS] = { SECTION_ID_FRAME_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "frame_tags" }, [SECTION_ID_FRAME_SIDE_DATA_LIST] ={ SECTION_ID_FRAME_SIDE_DATA_LIST, "side_data_list", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME_SIDE_DATA, -1 }, .element_name = "side_data", .unique_name = "frame_side_data_list" }, [SECTION_ID_FRAME_SIDE_DATA] = { SECTION_ID_FRAME_SIDE_DATA, "side_data", 0, { -1 } }, + [SECTION_ID_FRAME_LOGS] = { SECTION_ID_FRAME_LOGS, "logs", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME_LOG, -1 } }, + [SECTION_ID_FRAME_LOG] = { SECTION_ID_FRAME_LOG, "log", 0, { -1 }, }, [SECTION_ID_LIBRARY_VERSIONS] = { SECTION_ID_LIBRARY_VERSIONS, "library_versions", SECTION_FLAG_IS_ARRAY, { SECTION_ID_LIBRARY_VERSION, -1 } }, [SECTION_ID_LIBRARY_VERSION] = { SECTION_ID_LIBRARY_VERSION, "library_version", 0, { -1 } }, [SECTION_ID_PACKETS] = { SECTION_ID_PACKETS, "packets", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PACKET, -1} }, @@ -257,11 +275,79 @@ static uint64_t *nb_streams_packets; static uint64_t *nb_streams_frames; static int *selected_streams; +#if HAVE_THREADS +pthread_mutex_t log_mutex; +#endif +typedef struct LogBuffer { + char *context_name; + int log_level; + char *log_message; + AVClassCategory category; + char *parent_name; + AVClassCategory parent_category; +}LogBuffer; + +static LogBuffer *log_buffer; +static int log_buffer_size; + +static void log_callback(void *ptr, int level, const char *fmt, va_list vl) +{ + AVClass* avc = ptr ? *(AVClass **) ptr : NULL; + va_list vl2; + char line[1024]; + static int print_prefix = 1; + void *new_log_buffer; + + va_copy(vl2, vl); + av_log_default_callback(ptr, level, fmt, vl); + av_log_format_line(ptr, level, fmt, vl2, line, sizeof(line), &print_prefix); + va_end(vl2); + +#if HAVE_THREADS + pthread_mutex_lock(&log_mutex); + + new_log_buffer = av_realloc_array(log_buffer, log_buffer_size + 1, sizeof(*log_buffer)); + if (new_log_buffer) { + char *msg; + int i; + + log_buffer = new_log_buffer; + memset(&log_buffer[log_buffer_size], 0, sizeof(log_buffer[log_buffer_size])); + log_buffer[log_buffer_size].context_name= avc ? av_strdup(avc->item_name(ptr)) : NULL; + if (avc) { + if (avc->get_category) log_buffer[log_buffer_size].category = avc->get_category(ptr); + else log_buffer[log_buffer_size].category = avc->category; + } + log_buffer[log_buffer_size].log_level = level; + msg = log_buffer[log_buffer_size].log_message = av_strdup(line); + for (i=strlen(msg) - 1; i>=0 && msg[i] == '\n'; i--) { + msg[i] = 0; + } + if (avc && avc->parent_log_context_offset) { + AVClass** parent = *(AVClass ***) (((uint8_t *) ptr) + + avc->parent_log_context_offset); + if (parent && *parent) { + log_buffer[log_buffer_size].parent_name = av_strdup((*parent)->item_name(parent)); + log_buffer[log_buffer_size].parent_category = + (*parent)->get_category ? (*parent)->get_category(parent) :(*parent)->category; + } + } + log_buffer_size ++; + } + + pthread_mutex_unlock(&log_mutex); +#endif +} + static void ffprobe_cleanup(int ret) { int i; for (i = 0; i < FF_ARRAY_ELEMS(sections); i++) av_dict_free(&(sections[i].entries_to_show)); + +#if HAVE_THREADS + pthread_mutex_destroy(&log_mutex); +#endif } struct unit_value { @@ -1817,6 +1903,56 @@ static void print_pkt_side_data(WriterContext *w, writer_print_section_footer(w); } +static void clear_log(int need_lock) +{ + int i; + + if (need_lock) + pthread_mutex_lock(&log_mutex); + for (i=0; inb_side_data) { writer_print_section_header(w, SECTION_ID_FRAME_SIDE_DATA_LIST); for (i = 0; i < frame->nb_side_data; i++) { @@ -2003,6 +2141,7 @@ static av_always_inline int process_frame(WriterContext *w, AVSubtitle sub; int ret = 0, got_frame = 0; + clear_log(1); if (dec_ctx && dec_ctx->codec) { switch (par->codec_type) { case AVMEDIA_TYPE_VIDEO: @@ -2660,6 +2799,13 @@ static int open_input_file(InputFile *ifile, const char *filename) if (err < 0) exit(1); + if (do_show_log) { + // For loging it is needed to disable at least frame threads as otherwise + // the log information would need to be reordered and matches up to contexts and frames + // That is in fact possible but not trivial + av_dict_set(&codec_opts, "threads", "1", 0); + } + av_codec_set_pkt_timebase(ist->dec_ctx, stream->time_base); ist->dec_ctx->framerate = stream->avg_frame_rate; @@ -3245,6 +3391,9 @@ static const OptionDef real_options[] = { "show a particular entry from the format/container info", "entry" }, { "show_entries", HAS_ARG, {.func_arg = opt_show_entries}, "show a set of specified entries", "entry_list" }, +#if HAVE_THREADS + { "show_log", OPT_INT|HAS_ARG, {(void*)&do_show_log}, "show log" }, +#endif { "show_packets", 0, {(void*)&opt_show_packets}, "show packets info" }, { "show_programs", 0, {(void*)&opt_show_programs}, "show programs info" }, { "show_streams", 0, {(void*)&opt_show_streams}, "show streams info" }, @@ -3291,6 +3440,14 @@ int main(int argc, char **argv) init_dynload(); +#if HAVE_THREADS + ret = pthread_mutex_init(&log_mutex, NULL); + if (ret != 0) { + goto end; + } +#endif + av_log_set_callback(log_callback); + av_log_set_flags(AV_LOG_SKIP_REPEATED); register_exit(ffprobe_cleanup); From 52d9442a557e8137f261ba19defb08583f59d572 Mon Sep 17 00:00:00 2001 From: Dave Rice Date: Tue, 14 Mar 2017 12:59:43 -0400 Subject: [PATCH 1336/3374] ffprobe.xsd: add frame log data Signed-off-by: Michael Niedermayer --- doc/ffprobe.xsd | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/doc/ffprobe.xsd b/doc/ffprobe.xsd index f64656adf150b..6d929a1a32933 100644 --- a/doc/ffprobe.xsd +++ b/doc/ffprobe.xsd @@ -83,6 +83,7 @@ + @@ -121,6 +122,20 @@ + + + + + + + + + + + + + + From 3e0474ff39707ddbfb2361ad06c1acb45770183f Mon Sep 17 00:00:00 2001 From: Dave Rice Date: Tue, 14 Mar 2017 13:11:14 -0400 Subject: [PATCH 1337/3374] doc/ffprobe: add -show_log option Signed-off-by: Michael Niedermayer --- doc/ffprobe.texi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/ffprobe.texi b/doc/ffprobe.texi index 7514b2df73951..3572957c8a00b 100644 --- a/doc/ffprobe.texi +++ b/doc/ffprobe.texi @@ -208,6 +208,13 @@ multimedia stream. The information for each single frame is printed within a dedicated section with name "FRAME" or "SUBTITLE". +@item -show_log @var{loglevel} +Show logging information from the decoder about each frame according to +the value set in @var{loglevel}, (see @code{-loglevel}). This option requires @code{-show_frames}. + +The information for each log message is printed within a dedicated +section with name "LOG". + @item -show_streams Show information about each media stream contained in the input multimedia stream. From b613245c9715c34358522737bf0cf6a4f9392ca3 Mon Sep 17 00:00:00 2001 From: James Almer Date: Mon, 27 Mar 2017 20:37:29 -0300 Subject: [PATCH 1338/3374] ffprobe: free log buffer's parent_name during cleanup Fixes memleak. --- ffprobe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ffprobe.c b/ffprobe.c index 17b4580a42965..67c4ed40fae6d 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -1911,6 +1911,7 @@ static void clear_log(int need_lock) pthread_mutex_lock(&log_mutex); for (i=0; i Date: Tue, 28 Mar 2017 01:14:17 -0300 Subject: [PATCH 1339/3374] avcodec/extract_extradata_bsf: add missing break statement to extract_extradata_vc1 --- libavcodec/extract_extradata_bsf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavcodec/extract_extradata_bsf.c b/libavcodec/extract_extradata_bsf.c index e9b3791dc03a5..1e92f8ebdb918 100644 --- a/libavcodec/extract_extradata_bsf.c +++ b/libavcodec/extract_extradata_bsf.c @@ -145,8 +145,10 @@ static int extract_extradata_vc1(AVBSFContext *ctx, AVPacket *pkt, ptr = avpriv_find_start_code(ptr, end, &state); if (state == VC1_CODE_SEQHDR || state == VC1_CODE_ENTRYPOINT) { has_extradata = 1; - } else if (has_extradata && IS_MARKER(state)) + } else if (has_extradata && IS_MARKER(state)) { extradata_size = ptr - 4 - pkt->data; + break; + } } if (extradata_size) { From c0628919b8c5761d64b1169e8de7584544d15ebf Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Tue, 28 Mar 2017 16:51:28 +0800 Subject: [PATCH 1340/3374] avformat/flvdec: check FLVHeader PreviousTagSize0 refer to SPEC: Annex E. The FLV File Format said: E.3 TheFLVFileBody have a table: Field Type Comment PreviousTagSize0 UI32 Always 0 Reviewed-by: Bela Bodecs Reviewed-by: Hendrik Leppkes Signed-off-by: Steven Liu --- libavformat/flvdec.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index cdcfb9c5a085f..94c9e28334382 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -709,6 +709,7 @@ static int flv_read_header(AVFormatContext *s) int flags; FLVContext *flv = s->priv_data; int offset; + int pre_tag_size = 0; avio_skip(s->pb, 4); flags = avio_r8(s->pb); @@ -719,7 +720,16 @@ static int flv_read_header(AVFormatContext *s) offset = avio_rb32(s->pb); avio_seek(s->pb, offset, SEEK_SET); - avio_skip(s->pb, 4); + + /* Annex E. The FLV File Format + * E.3 TheFLVFileBody + * Field Type Comment + * PreviousTagSize0 UI32 Always 0 + * */ + pre_tag_size = avio_rb32(s->pb); + if (pre_tag_size) { + av_log(s, AV_LOG_WARNING, "Read FLV header error, input file is not a standard flv format, first PreviousTagSize0 always is 0\n"); + } s->start_time = 0; flv->sum_flv_tag_size = 0; From c3706bc255741faab426093c64fe16c2c879b3a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Tue, 28 Mar 2017 11:29:19 +0200 Subject: [PATCH 1341/3374] doc/examples/filtering_*: switch to codecpar --- doc/examples/filtering_audio.c | 9 +++++++-- doc/examples/filtering_video.c | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/doc/examples/filtering_audio.c b/doc/examples/filtering_audio.c index 6bb24a431dca8..c6a930ba8b620 100644 --- a/doc/examples/filtering_audio.c +++ b/doc/examples/filtering_audio.c @@ -69,7 +69,12 @@ static int open_input_file(const char *filename) return ret; } audio_stream_index = ret; - dec_ctx = fmt_ctx->streams[audio_stream_index]->codec; + + /* create decoding context */ + dec_ctx = avcodec_alloc_context3(dec); + if (!dec_ctx) + return AVERROR(ENOMEM); + avcodec_parameters_to_context(dec_ctx, fmt_ctx->streams[audio_stream_index]->codecpar); av_opt_set_int(dec_ctx, "refcounted_frames", 1, 0); /* init the audio decoder */ @@ -281,7 +286,7 @@ int main(int argc, char **argv) } end: avfilter_graph_free(&filter_graph); - avcodec_close(dec_ctx); + avcodec_free_context(&dec_ctx); avformat_close_input(&fmt_ctx); av_frame_free(&frame); av_frame_free(&filt_frame); diff --git a/doc/examples/filtering_video.c b/doc/examples/filtering_video.c index 3dabf13b1003b..15116d3881f87 100644 --- a/doc/examples/filtering_video.c +++ b/doc/examples/filtering_video.c @@ -72,7 +72,12 @@ static int open_input_file(const char *filename) return ret; } video_stream_index = ret; - dec_ctx = fmt_ctx->streams[video_stream_index]->codec; + + /* create decoding context */ + dec_ctx = avcodec_alloc_context3(dec); + if (!dec_ctx) + return AVERROR(ENOMEM); + avcodec_parameters_to_context(dec_ctx, fmt_ctx->streams[video_stream_index]->codecpar); av_opt_set_int(dec_ctx, "refcounted_frames", 1, 0); /* init the video decoder */ @@ -266,7 +271,7 @@ int main(int argc, char **argv) } end: avfilter_graph_free(&filter_graph); - avcodec_close(dec_ctx); + avcodec_free_context(&dec_ctx); avformat_close_input(&fmt_ctx); av_frame_free(&frame); av_frame_free(&filt_frame); From 7e3e0f87e6e911250855f03dd2fa8b4533a3e654 Mon Sep 17 00:00:00 2001 From: Matthieu Bouron Date: Tue, 28 Mar 2017 12:38:41 +0200 Subject: [PATCH 1342/3374] doc/examples/muxing: re-indent block --- doc/examples/muxing.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/examples/muxing.c b/doc/examples/muxing.c index 1df5912ca7934..e1a4770eb1228 100644 --- a/doc/examples/muxing.c +++ b/doc/examples/muxing.c @@ -335,15 +335,15 @@ static int write_audio_frame(AVFormatContext *oc, OutputStream *ost) if (ret < 0) exit(1); - /* convert to destination format */ - ret = swr_convert(ost->swr_ctx, - ost->frame->data, dst_nb_samples, - (const uint8_t **)frame->data, frame->nb_samples); - if (ret < 0) { - fprintf(stderr, "Error while converting\n"); - exit(1); - } - frame = ost->frame; + /* convert to destination format */ + ret = swr_convert(ost->swr_ctx, + ost->frame->data, dst_nb_samples, + (const uint8_t **)frame->data, frame->nb_samples); + if (ret < 0) { + fprintf(stderr, "Error while converting\n"); + exit(1); + } + frame = ost->frame; frame->pts = av_rescale_q(ost->samples_count, (AVRational){1, c->sample_rate}, c->time_base); ost->samples_count += dst_nb_samples; From 4a946aca7cf3c03d232953852405577e85f4da71 Mon Sep 17 00:00:00 2001 From: Matthieu Bouron Date: Tue, 28 Mar 2017 11:57:26 +0200 Subject: [PATCH 1343/3374] doc/examples/remuxing: switch to codecpar Also limits remuxing to audio, video and subtitle streams. --- doc/examples/remuxing.c | 42 ++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/doc/examples/remuxing.c b/doc/examples/remuxing.c index 65437d9abd51f..59594181a7090 100644 --- a/doc/examples/remuxing.c +++ b/doc/examples/remuxing.c @@ -50,6 +50,9 @@ int main(int argc, char **argv) AVPacket pkt; const char *in_filename, *out_filename; int ret, i; + int stream_index = 0; + int *stream_mapping = NULL; + int stream_mapping_size = 0; if (argc < 3) { printf("usage: %s input output\n" @@ -83,25 +86,42 @@ int main(int argc, char **argv) goto end; } + stream_mapping_size = ifmt_ctx->nb_streams; + stream_mapping = av_mallocz_array(stream_mapping_size, sizeof(*stream_mapping)); + if (!stream_mapping) { + ret = AVERROR(ENOMEM); + goto end; + } + ofmt = ofmt_ctx->oformat; for (i = 0; i < ifmt_ctx->nb_streams; i++) { + AVStream *out_stream; AVStream *in_stream = ifmt_ctx->streams[i]; - AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec); + AVCodecParameters *in_codecpar = in_stream->codecpar; + + if (in_codecpar->codec_type != AVMEDIA_TYPE_AUDIO && + in_codecpar->codec_type != AVMEDIA_TYPE_VIDEO && + in_codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) { + stream_mapping[i] = -1; + continue; + } + + stream_mapping[i] = stream_index++; + + out_stream = avformat_new_stream(ofmt_ctx, NULL); if (!out_stream) { fprintf(stderr, "Failed allocating output stream\n"); ret = AVERROR_UNKNOWN; goto end; } - ret = avcodec_copy_context(out_stream->codec, in_stream->codec); + ret = avcodec_parameters_copy(out_stream->codecpar, in_codecpar); if (ret < 0) { - fprintf(stderr, "Failed to copy context from input to output stream codec context\n"); + fprintf(stderr, "Failed to copy codec parameters\n"); goto end; } - out_stream->codec->codec_tag = 0; - if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) - out_stream->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; + out_stream->codecpar->codec_tag = 0; } av_dump_format(ofmt_ctx, 0, out_filename, 1); @@ -127,8 +147,14 @@ int main(int argc, char **argv) break; in_stream = ifmt_ctx->streams[pkt.stream_index]; - out_stream = ofmt_ctx->streams[pkt.stream_index]; + if (pkt.stream_index >= stream_mapping_size || + stream_mapping[pkt.stream_index] < 0) { + av_packet_unref(&pkt); + continue; + } + pkt.stream_index = stream_mapping[pkt.stream_index]; + out_stream = ofmt_ctx->streams[pkt.stream_index]; log_packet(ifmt_ctx, &pkt, "in"); /* copy packet */ @@ -156,6 +182,8 @@ int main(int argc, char **argv) avio_closep(&ofmt_ctx->pb); avformat_free_context(ofmt_ctx); + av_freep(&stream_mapping); + if (ret < 0 && ret != AVERROR_EOF) { fprintf(stderr, "Error occurred: %s\n", av_err2str(ret)); return 1; From 64b553998567141b05239dcf11ad4d24aeaead8e Mon Sep 17 00:00:00 2001 From: Matthieu Bouron Date: Tue, 28 Mar 2017 13:46:36 +0200 Subject: [PATCH 1344/3374] doc/examples/extract_mvs: switch to codecpar --- doc/examples/extract_mvs.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/doc/examples/extract_mvs.c b/doc/examples/extract_mvs.c index 975189c77d35e..8b22b40c116aa 100644 --- a/doc/examples/extract_mvs.c +++ b/doc/examples/extract_mvs.c @@ -69,8 +69,7 @@ static int decode_packet(int *got_frame, int cached) return decoded; } -static int open_codec_context(int *stream_idx, - AVFormatContext *fmt_ctx, enum AVMediaType type) +static int open_codec_context(AVFormatContext *fmt_ctx, enum AVMediaType type) { int ret; AVStream *st; @@ -78,24 +77,27 @@ static int open_codec_context(int *stream_idx, AVCodec *dec = NULL; AVDictionary *opts = NULL; - ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0); + ret = av_find_best_stream(fmt_ctx, type, -1, -1, &dec, 0); if (ret < 0) { fprintf(stderr, "Could not find %s stream in input file '%s'\n", av_get_media_type_string(type), src_filename); return ret; } else { - *stream_idx = ret; - st = fmt_ctx->streams[*stream_idx]; - - /* find decoder for the stream */ - dec_ctx = st->codec; - dec = avcodec_find_decoder(dec_ctx->codec_id); - if (!dec) { - fprintf(stderr, "Failed to find %s codec\n", - av_get_media_type_string(type)); + int stream_idx = ret; + st = fmt_ctx->streams[stream_idx]; + + dec_ctx = avcodec_alloc_context3(dec); + if (!dec_ctx) { + fprintf(stderr, "Failed to allocate codec\n"); return AVERROR(EINVAL); } + ret = avcodec_parameters_to_context(dec_ctx, st->codecpar); + if (ret < 0) { + fprintf(stderr, "Failed to copy codec parameters to codec context\n"); + return ret; + } + /* Init the video decoder */ av_dict_set(&opts, "flags2", "+export_mvs", 0); if ((ret = avcodec_open2(dec_ctx, dec, &opts)) < 0) { @@ -103,6 +105,10 @@ static int open_codec_context(int *stream_idx, av_get_media_type_string(type)); return ret; } + + video_stream_idx = stream_idx; + video_stream = fmt_ctx->streams[video_stream_idx]; + video_dec_ctx = dec_ctx; } return 0; @@ -130,10 +136,7 @@ int main(int argc, char **argv) exit(1); } - if (open_codec_context(&video_stream_idx, fmt_ctx, AVMEDIA_TYPE_VIDEO) >= 0) { - video_stream = fmt_ctx->streams[video_stream_idx]; - video_dec_ctx = video_stream->codec; - } + open_codec_context(fmt_ctx, AVMEDIA_TYPE_VIDEO); av_dump_format(fmt_ctx, 0, src_filename, 0); @@ -178,7 +181,7 @@ int main(int argc, char **argv) } while (got_frame); end: - avcodec_close(video_dec_ctx); + avcodec_free_context(&video_dec_ctx); avformat_close_input(&fmt_ctx); av_frame_free(&frame); return ret < 0; From 5ba8c3a0ed0e43e6418eabdf8af9549c9e806382 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 27 Mar 2017 11:24:43 -0400 Subject: [PATCH 1345/3374] dirac: make initialization of arithmetic coder tables threadsafe. --- libavcodec/dirac_arith.c | 15 ++++++++++----- libavcodec/dirac_arith.h | 1 + libavcodec/diracdec.c | 9 ++++++++- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/libavcodec/dirac_arith.c b/libavcodec/dirac_arith.c index bf913928b3247..7eb9bd60b2f17 100644 --- a/libavcodec/dirac_arith.c +++ b/libavcodec/dirac_arith.c @@ -83,6 +83,16 @@ const uint8_t ff_dirac_next_ctx[DIRAC_CTX_COUNT] = { int16_t ff_dirac_prob_branchless[256][2]; +av_cold void ff_dirac_init_arith_tables(void) +{ + int i; + + for (i = 0; i < 256; i++) { + ff_dirac_prob_branchless[i][0] = ff_dirac_prob[255-i]; + ff_dirac_prob_branchless[i][1] = -ff_dirac_prob[i]; + } +} + void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length) { int i; @@ -106,11 +116,6 @@ void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length) c->counter = -16; c->range = 0xffff; - for (i = 0; i < 256; i++) { - ff_dirac_prob_branchless[i][0] = ff_dirac_prob[255-i]; - ff_dirac_prob_branchless[i][1] = -ff_dirac_prob[i]; - } - for (i = 0; i < DIRAC_CTX_COUNT; i++) c->contexts[i] = 0x8000; } diff --git a/libavcodec/dirac_arith.h b/libavcodec/dirac_arith.h index 003430a48d11c..24a7ca390e704 100644 --- a/libavcodec/dirac_arith.h +++ b/libavcodec/dirac_arith.h @@ -190,6 +190,7 @@ static inline int dirac_get_arith_int(DiracArith *c, int follow_ctx, int data_ct return ret; } +void ff_dirac_init_arith_tables(void); void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length); #endif /* AVCODEC_DIRAC_ARITH_H */ diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c index e0604af103847..202ae94922785 100644 --- a/libavcodec/diracdec.c +++ b/libavcodec/diracdec.c @@ -26,6 +26,7 @@ * @author Marco Gerards , David Conrad, Jordi Ortiz */ +#include "libavutil/thread.h" #include "avcodec.h" #include "get_bits.h" #include "bytestream.h" @@ -379,10 +380,12 @@ static void free_sequence_buffers(DiracContext *s) av_freep(&s->mcscratch); } +static AVOnce dirac_arith_init = AV_ONCE_INIT; + static av_cold int dirac_decode_init(AVCodecContext *avctx) { DiracContext *s = avctx->priv_data; - int i; + int i, ret; s->avctx = avctx; s->frame_number = -1; @@ -404,6 +407,9 @@ static av_cold int dirac_decode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); } } + ret = ff_thread_once(&dirac_arith_init, ff_dirac_init_arith_tables); + if (ret != 0) + return AVERROR_UNKNOWN; return 0; } @@ -2299,5 +2305,6 @@ AVCodec ff_dirac_decoder = { .close = dirac_decode_end, .decode = dirac_decode_frame, .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, .flush = dirac_decode_flush, }; From 3b80f73b186dc24a39a95edc4243f785d1459273 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 27 Aug 2016 15:02:44 -0300 Subject: [PATCH 1346/3374] doc/examples/transcoding: convert to codecpar Reviewed-by: Matthieu Bouron Signed-off-by: James Almer --- doc/examples/transcoding.c | 96 ++++++++++++++++++++++++++------------ 1 file changed, 67 insertions(+), 29 deletions(-) diff --git a/doc/examples/transcoding.c b/doc/examples/transcoding.c index 8633362d46a44..476ec69afe6b9 100644 --- a/doc/examples/transcoding.c +++ b/doc/examples/transcoding.c @@ -45,6 +45,12 @@ typedef struct FilteringContext { } FilteringContext; static FilteringContext *filter_ctx; +typedef struct StreamContext { + AVCodecContext *dec_ctx; + AVCodecContext *enc_ctx; +} StreamContext; +static StreamContext *stream_ctx; + static int open_input_file(const char *filename) { int ret; @@ -61,22 +67,42 @@ static int open_input_file(const char *filename) return ret; } + stream_ctx = av_mallocz_array(ifmt_ctx->nb_streams, sizeof(*stream_ctx)); + if (!stream_ctx) + return AVERROR(ENOMEM); + for (i = 0; i < ifmt_ctx->nb_streams; i++) { - AVStream *stream; + AVStream *stream = ifmt_ctx->streams[i]; + AVCodec *dec = avcodec_find_decoder(stream->codecpar->codec_id); AVCodecContext *codec_ctx; - stream = ifmt_ctx->streams[i]; - codec_ctx = stream->codec; + if (!dec) { + av_log(NULL, AV_LOG_ERROR, "Failed to find decoder for stream #%u\n", i); + return AVERROR_DECODER_NOT_FOUND; + } + codec_ctx = avcodec_alloc_context3(dec); + if (!codec_ctx) { + av_log(NULL, AV_LOG_ERROR, "Failed to allocate the decoder context for stream #%u\n", i); + return AVERROR(ENOMEM); + } + ret = avcodec_parameters_to_context(codec_ctx, stream->codecpar); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Failed to copy decoder parameters to input decoder context " + "for stream #%u\n", i); + return ret; + } /* Reencode video & audio and remux subtitles etc. */ if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO || codec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) { + if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO) + codec_ctx->framerate = av_guess_frame_rate(ifmt_ctx, stream, NULL); /* Open decoder */ - ret = avcodec_open2(codec_ctx, - avcodec_find_decoder(codec_ctx->codec_id), NULL); + ret = avcodec_open2(codec_ctx, dec, NULL); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Failed to open decoder for stream #%u\n", i); return ret; } } + stream_ctx[i].dec_ctx = codec_ctx; } av_dump_format(ifmt_ctx, 0, filename, 0); @@ -108,8 +134,7 @@ static int open_output_file(const char *filename) } in_stream = ifmt_ctx->streams[i]; - dec_ctx = in_stream->codec; - enc_ctx = out_stream->codec; + dec_ctx = stream_ctx[i].dec_ctx; if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO || dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) { @@ -119,6 +144,11 @@ static int open_output_file(const char *filename) av_log(NULL, AV_LOG_FATAL, "Necessary encoder not found\n"); return AVERROR_INVALIDDATA; } + enc_ctx = avcodec_alloc_context3(encoder); + if (!enc_ctx) { + av_log(NULL, AV_LOG_FATAL, "Failed to allocate the encoder context\n"); + return AVERROR(ENOMEM); + } /* In this example, we transcode to same properties (picture size, * sample rate etc.). These properties can be changed for output @@ -133,7 +163,7 @@ static int open_output_file(const char *filename) else enc_ctx->pix_fmt = dec_ctx->pix_fmt; /* video time_base can be set to whatever is handy and supported by encoder */ - enc_ctx->time_base = dec_ctx->time_base; + enc_ctx->time_base = av_inv_q(dec_ctx->framerate); } else { enc_ctx->sample_rate = dec_ctx->sample_rate; enc_ctx->channel_layout = dec_ctx->channel_layout; @@ -149,22 +179,29 @@ static int open_output_file(const char *filename) av_log(NULL, AV_LOG_ERROR, "Cannot open video encoder for stream #%u\n", i); return ret; } + ret = avcodec_parameters_from_context(out_stream->codecpar, enc_ctx); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Failed to copy encoder parameters to output stream #%u\n", i); + return ret; + } + if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) + enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; + + out_stream->time_base = enc_ctx->time_base; + stream_ctx[i].enc_ctx = enc_ctx; } else if (dec_ctx->codec_type == AVMEDIA_TYPE_UNKNOWN) { av_log(NULL, AV_LOG_FATAL, "Elementary stream #%d is of unknown type, cannot proceed\n", i); return AVERROR_INVALIDDATA; } else { /* if this stream must be remuxed */ - ret = avcodec_copy_context(ofmt_ctx->streams[i]->codec, - ifmt_ctx->streams[i]->codec); + ret = avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Copying stream context failed\n"); + av_log(NULL, AV_LOG_ERROR, "Copying parameters for stream #%u failed\n", i); return ret; } + out_stream->time_base = in_stream->time_base; } - if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) - enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; - } av_dump_format(ofmt_ctx, 0, filename, 1); @@ -348,17 +385,17 @@ static int init_filters(void) filter_ctx[i].buffersrc_ctx = NULL; filter_ctx[i].buffersink_ctx = NULL; filter_ctx[i].filter_graph = NULL; - if (!(ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO - || ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)) + if (!(ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO + || ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)) continue; - if (ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) + if (ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) filter_spec = "null"; /* passthrough (dummy) filter for video */ else filter_spec = "anull"; /* passthrough (dummy) filter for audio */ - ret = init_filter(&filter_ctx[i], ifmt_ctx->streams[i]->codec, - ofmt_ctx->streams[i]->codec, filter_spec); + ret = init_filter(&filter_ctx[i], stream_ctx[i].dec_ctx, + stream_ctx[i].enc_ctx, filter_spec); if (ret) return ret; } @@ -370,7 +407,7 @@ static int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, in int got_frame_local; AVPacket enc_pkt; int (*enc_func)(AVCodecContext *, AVPacket *, const AVFrame *, int *) = - (ifmt_ctx->streams[stream_index]->codec->codec_type == + (ifmt_ctx->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) ? avcodec_encode_video2 : avcodec_encode_audio2; if (!got_frame) @@ -381,7 +418,7 @@ static int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, in enc_pkt.data = NULL; enc_pkt.size = 0; av_init_packet(&enc_pkt); - ret = enc_func(ofmt_ctx->streams[stream_index]->codec, &enc_pkt, + ret = enc_func(stream_ctx[stream_index].enc_ctx, &enc_pkt, filt_frame, got_frame); av_frame_free(&filt_frame); if (ret < 0) @@ -392,7 +429,7 @@ static int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, in /* prepare packet for muxing */ enc_pkt.stream_index = stream_index; av_packet_rescale_ts(&enc_pkt, - ofmt_ctx->streams[stream_index]->codec->time_base, + stream_ctx[stream_index].enc_ctx->time_base, ofmt_ctx->streams[stream_index]->time_base); av_log(NULL, AV_LOG_DEBUG, "Muxing frame\n"); @@ -450,7 +487,7 @@ static int flush_encoder(unsigned int stream_index) int ret; int got_frame; - if (!(ofmt_ctx->streams[stream_index]->codec->codec->capabilities & + if (!(stream_ctx[stream_index].enc_ctx->codec->capabilities & AV_CODEC_CAP_DELAY)) return 0; @@ -496,7 +533,7 @@ int main(int argc, char **argv) if ((ret = av_read_frame(ifmt_ctx, &packet)) < 0) break; stream_index = packet.stream_index; - type = ifmt_ctx->streams[packet.stream_index]->codec->codec_type; + type = ifmt_ctx->streams[packet.stream_index]->codecpar->codec_type; av_log(NULL, AV_LOG_DEBUG, "Demuxer gave frame of stream_index %u\n", stream_index); @@ -509,10 +546,10 @@ int main(int argc, char **argv) } av_packet_rescale_ts(&packet, ifmt_ctx->streams[stream_index]->time_base, - ifmt_ctx->streams[stream_index]->codec->time_base); + stream_ctx[stream_index].dec_ctx->time_base); dec_func = (type == AVMEDIA_TYPE_VIDEO) ? avcodec_decode_video2 : avcodec_decode_audio4; - ret = dec_func(ifmt_ctx->streams[stream_index]->codec, frame, + ret = dec_func(stream_ctx[stream_index].dec_ctx, frame, &got_frame, &packet); if (ret < 0) { av_frame_free(&frame); @@ -566,13 +603,14 @@ int main(int argc, char **argv) av_packet_unref(&packet); av_frame_free(&frame); for (i = 0; i < ifmt_ctx->nb_streams; i++) { - avcodec_close(ifmt_ctx->streams[i]->codec); - if (ofmt_ctx && ofmt_ctx->nb_streams > i && ofmt_ctx->streams[i] && ofmt_ctx->streams[i]->codec) - avcodec_close(ofmt_ctx->streams[i]->codec); + avcodec_free_context(&stream_ctx[i].dec_ctx); + if (ofmt_ctx && ofmt_ctx->nb_streams > i && ofmt_ctx->streams[i] && stream_ctx[i].enc_ctx) + avcodec_free_context(&stream_ctx[i].enc_ctx); if (filter_ctx && filter_ctx[i].filter_graph) avfilter_graph_free(&filter_ctx[i].filter_graph); } av_free(filter_ctx); + av_free(stream_ctx); avformat_close_input(&ifmt_ctx); if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE)) avio_closep(&ofmt_ctx->pb); From 7cfa98fd9460160d94c049bf72123e88d9c41a01 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sat, 25 Mar 2017 17:36:39 +0100 Subject: [PATCH 1347/3374] configure: use c++11 and fallback to c++0x for c++ files Needed for the C+11 atomics. Also change add_cxxflags to check_cxxflags. Reviewed-by: James Almer Signed-off-by: Marton Balint --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index dc968bcfd836d..a84b12656fb5c 100755 --- a/configure +++ b/configure @@ -4649,7 +4649,7 @@ fi add_cppflags -D_ISOC99_SOURCE add_cxxflags -D__STDC_CONSTANT_MACROS -add_cxxflags -std=c++98 +check_cxxflags -std=c++11 || check_cxxflags -std=c++0x # some compilers silently accept -std=c11, so we also need to check that the # version macro is defined properly From c395d230b12834752d28e81a74233daa816a26c2 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sat, 25 Mar 2017 17:42:17 +0100 Subject: [PATCH 1348/3374] avdevice/decklink_enc: convert to std::atomic Signed-off-by: Marton Balint --- libavdevice/decklink_enc.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libavdevice/decklink_enc.cpp b/libavdevice/decklink_enc.cpp index 8892d1972fb77..18ef9058e28c3 100644 --- a/libavdevice/decklink_enc.cpp +++ b/libavdevice/decklink_enc.cpp @@ -19,6 +19,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include +using std::atomic; + #include #include @@ -28,7 +31,6 @@ extern "C" { #include "libavformat/avformat.h" #include "libavformat/internal.h" #include "libavutil/imgutils.h" -#include "libavutil/atomic.h" } #include "decklink_common.h" @@ -60,10 +62,10 @@ class decklink_frame : public IDeckLinkVideoFrame virtual HRESULT STDMETHODCALLTYPE GetAncillaryData(IDeckLinkVideoFrameAncillary **ancillary) { return S_FALSE; } virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) { return E_NOINTERFACE; } - virtual ULONG STDMETHODCALLTYPE AddRef(void) { return avpriv_atomic_int_add_and_fetch(&_refs, 1); } + virtual ULONG STDMETHODCALLTYPE AddRef(void) { return ++_refs; } virtual ULONG STDMETHODCALLTYPE Release(void) { - int ret = avpriv_atomic_int_add_and_fetch(&_refs, -1); + int ret = --_refs; if (!ret) { av_frame_free(&_avframe); delete this; @@ -75,7 +77,7 @@ class decklink_frame : public IDeckLinkVideoFrame AVFrame *_avframe; private: - volatile int _refs; + std::atomic _refs; }; class decklink_output_callback : public IDeckLinkVideoOutputCallback From 77d2cb88741a9ac6ab6a3c53b32b01cec07b99b2 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sat, 25 Mar 2017 17:52:11 +0100 Subject: [PATCH 1349/3374] avdevice/decklink: deprecate @mode syntax in device name to specify mode Signed-off-by: Marton Balint --- libavdevice/decklink_common.cpp | 7 +++---- libavdevice/decklink_dec.cpp | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp index f17c263c4bf49..c9107c036a59c 100644 --- a/libavdevice/decklink_common.cpp +++ b/libavdevice/decklink_common.cpp @@ -286,7 +286,6 @@ int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direct IDeckLinkDisplayModeIterator *itermode; IDeckLinkDisplayMode *mode; uint32_t format_code; - int i=0; HRESULT res; if (direction == DIRECTION_IN) { @@ -307,14 +306,14 @@ int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direct return AVERROR(EIO); } - av_log(avctx, AV_LOG_INFO, "Supported formats for '%s':\n\tmode\tformat_code\tdescription", + av_log(avctx, AV_LOG_INFO, "Supported formats for '%s':\n\tformat_code\tdescription", avctx->filename); while (itermode->Next(&mode) == S_OK) { BMDTimeValue tb_num, tb_den; mode->GetFrameRate(&tb_num, &tb_den); format_code = av_bswap32(mode->GetDisplayMode()); - av_log(avctx, AV_LOG_INFO, "\n\t%d\t%.4s\t\t%ldx%ld at %d/%d fps", - ++i, (char*) &format_code, mode->GetWidth(), mode->GetHeight(), + av_log(avctx, AV_LOG_INFO, "\n\t%.4s\t\t%ldx%ld at %d/%d fps", + (char*) &format_code, mode->GetWidth(), mode->GetHeight(), (int) tb_den, (int) tb_num); switch (mode->GetFieldDominance()) { case bmdLowerFieldFirst: diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index ffe65db0d074f..8cc1bdf7c9dcc 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -516,6 +516,7 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) strcpy (fname, avctx->filename); tmp=strchr (fname, '@'); if (tmp != NULL) { + av_log(avctx, AV_LOG_WARNING, "The @mode syntax is deprecated and will be removed. Please use the -format_code option.\n"); mode_num = atoi (tmp+1); *tmp = 0; } From 473f0f75a16b4d37bdaa943f75e4ae249212c1ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Tue, 28 Mar 2017 18:00:02 +0200 Subject: [PATCH 1350/3374] lavfi: fix race when func rets holder is NULL If ret is NULL, a dummy common holder is created to hold *all* the parallel function returns, which gets written concurrently. This commit simplify the whole logic by simply not writing to that holder when not set. --- libavfilter/pthread.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/libavfilter/pthread.c b/libavfilter/pthread.c index ccb915eae56c8..c7a00210d6648 100644 --- a/libavfilter/pthread.c +++ b/libavfilter/pthread.c @@ -43,7 +43,6 @@ typedef struct ThreadContext { AVFilterContext *ctx; void *arg; int *rets; - int nb_rets; int nb_jobs; pthread_cond_t last_job_cond; @@ -60,10 +59,11 @@ static void* attribute_align_arg worker(void *v) int our_job = c->nb_jobs; int nb_threads = c->nb_threads; unsigned int last_execute = 0; - int self_id; + int ret, self_id; pthread_mutex_lock(&c->current_job_lock); self_id = c->current_job++; + for (;;) { while (our_job >= c->nb_jobs) { if (c->current_job == nb_threads + c->nb_jobs) @@ -81,7 +81,9 @@ static void* attribute_align_arg worker(void *v) } pthread_mutex_unlock(&c->current_job_lock); - c->rets[our_job % c->nb_rets] = c->func(c->ctx, c->arg, our_job, c->nb_jobs); + ret = c->func(c->ctx, c->arg, our_job, c->nb_jobs); + if (c->rets) + c->rets[our_job % c->nb_jobs] = ret; pthread_mutex_lock(&c->current_job_lock); our_job = c->current_job++; @@ -117,7 +119,6 @@ static int thread_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs) { ThreadContext *c = ctx->graph->internal->thread; - int dummy_ret; if (nb_jobs <= 0) return 0; @@ -129,13 +130,7 @@ static int thread_execute(AVFilterContext *ctx, avfilter_action_func *func, c->ctx = ctx; c->arg = arg; c->func = func; - if (ret) { - c->rets = ret; - c->nb_rets = nb_jobs; - } else { - c->rets = &dummy_ret; - c->nb_rets = 1; - } + c->rets = ret; c->current_execute++; pthread_cond_broadcast(&c->current_job_cond); From f8c019944d45f4ea9786f8690f8a64fd9398ebf3 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 27 Mar 2017 16:47:46 -0400 Subject: [PATCH 1351/3374] vp9: re-split the decoder/format/dsp interface header files. The advantage here is that the internal software decoder interface is not exposed to the DSP functions or the hardware accelerations. --- libavcodec/aarch64/vp9dsp_init.h | 2 +- libavcodec/aarch64/vp9dsp_init_aarch64.c | 2 +- libavcodec/arm/vp9dsp_init.h | 2 +- libavcodec/arm/vp9dsp_init_arm.c | 2 +- libavcodec/mips/vp9_idct_msa.c | 2 +- libavcodec/mips/vp9_intra_msa.c | 2 +- libavcodec/mips/vp9_lpf_msa.c | 2 +- libavcodec/mips/vp9_mc_msa.c | 2 +- libavcodec/mips/vp9dsp_init_mips.c | 2 +- libavcodec/vp9.c | 2 +- libavcodec/vp9.h | 277 -------------------- libavcodec/vp9block.c | 1 + libavcodec/vp9data.h | 2 +- libavcodec/vp9dec.h | 206 +++++++++++++++ libavcodec/vp9dsp.c | 2 +- libavcodec/vp9dsp.h | 136 ++++++++++ libavcodec/vp9dsp_template.c | 2 +- libavcodec/vp9mvs.c | 1 + libavcodec/vp9prob.c | 1 + libavcodec/x86/vp9dsp_init.c | 2 +- libavcodec/x86/vp9dsp_init.h | 2 +- libavcodec/x86/vp9dsp_init_16bpp.c | 2 +- libavcodec/x86/vp9dsp_init_16bpp_template.c | 2 +- 23 files changed, 362 insertions(+), 294 deletions(-) create mode 100644 libavcodec/vp9dec.h create mode 100644 libavcodec/vp9dsp.h diff --git a/libavcodec/aarch64/vp9dsp_init.h b/libavcodec/aarch64/vp9dsp_init.h index e288fb482b9b2..9df1752c62789 100644 --- a/libavcodec/aarch64/vp9dsp_init.h +++ b/libavcodec/aarch64/vp9dsp_init.h @@ -21,7 +21,7 @@ #ifndef AVCODEC_AARCH64_VP9DSP_INIT_H #define AVCODEC_AARCH64_VP9DSP_INIT_H -#include "libavcodec/vp9.h" +#include "libavcodec/vp9dsp.h" void ff_vp9dsp_init_10bpp_aarch64(VP9DSPContext *dsp); void ff_vp9dsp_init_12bpp_aarch64(VP9DSPContext *dsp); diff --git a/libavcodec/aarch64/vp9dsp_init_aarch64.c b/libavcodec/aarch64/vp9dsp_init_aarch64.c index e27c232b71c48..91a82d822df77 100644 --- a/libavcodec/aarch64/vp9dsp_init_aarch64.c +++ b/libavcodec/aarch64/vp9dsp_init_aarch64.c @@ -22,7 +22,7 @@ #include "libavutil/attributes.h" #include "libavutil/aarch64/cpu.h" -#include "libavcodec/vp9.h" +#include "libavcodec/vp9dsp.h" #include "vp9dsp_init.h" #define declare_fpel(type, sz) \ diff --git a/libavcodec/arm/vp9dsp_init.h b/libavcodec/arm/vp9dsp_init.h index 0047a24bd8ba7..0dc1c2dc20940 100644 --- a/libavcodec/arm/vp9dsp_init.h +++ b/libavcodec/arm/vp9dsp_init.h @@ -21,7 +21,7 @@ #ifndef AVCODEC_ARM_VP9DSP_INIT_H #define AVCODEC_ARM_VP9DSP_INIT_H -#include "libavcodec/vp9.h" +#include "libavcodec/vp9dsp.h" void ff_vp9dsp_init_10bpp_arm(VP9DSPContext *dsp); void ff_vp9dsp_init_12bpp_arm(VP9DSPContext *dsp); diff --git a/libavcodec/arm/vp9dsp_init_arm.c b/libavcodec/arm/vp9dsp_init_arm.c index f9245c387986f..4c57fd6ba05b5 100644 --- a/libavcodec/arm/vp9dsp_init_arm.c +++ b/libavcodec/arm/vp9dsp_init_arm.c @@ -22,7 +22,7 @@ #include "libavutil/attributes.h" #include "libavutil/arm/cpu.h" -#include "libavcodec/vp9.h" +#include "libavcodec/vp9dsp.h" #include "vp9dsp_init.h" #define declare_fpel(type, sz) \ diff --git a/libavcodec/mips/vp9_idct_msa.c b/libavcodec/mips/vp9_idct_msa.c index e2b7b3cea8626..25ea16c72a060 100644 --- a/libavcodec/mips/vp9_idct_msa.c +++ b/libavcodec/mips/vp9_idct_msa.c @@ -19,7 +19,7 @@ */ #include -#include "libavcodec/vp9.h" +#include "libavcodec/vp9dsp.h" #include "libavutil/mips/generic_macros_msa.h" #include "vp9dsp_mips.h" diff --git a/libavcodec/mips/vp9_intra_msa.c b/libavcodec/mips/vp9_intra_msa.c index 4097cf4c629d8..54cf0ae94f1ea 100644 --- a/libavcodec/mips/vp9_intra_msa.c +++ b/libavcodec/mips/vp9_intra_msa.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "libavcodec/vp9.h" +#include "libavcodec/vp9dsp.h" #include "libavutil/mips/generic_macros_msa.h" #include "vp9dsp_mips.h" diff --git a/libavcodec/mips/vp9_lpf_msa.c b/libavcodec/mips/vp9_lpf_msa.c index 9164dcd10e7a5..eef8afc4828e1 100644 --- a/libavcodec/mips/vp9_lpf_msa.c +++ b/libavcodec/mips/vp9_lpf_msa.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "libavcodec/vp9.h" +#include "libavcodec/vp9dsp.h" #include "libavutil/mips/generic_macros_msa.h" #include "vp9dsp_mips.h" diff --git a/libavcodec/mips/vp9_mc_msa.c b/libavcodec/mips/vp9_mc_msa.c index 52207b6f23d5c..1671d973a4a0d 100644 --- a/libavcodec/mips/vp9_mc_msa.c +++ b/libavcodec/mips/vp9_mc_msa.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "libavcodec/vp9.h" +#include "libavcodec/vp9dsp.h" #include "libavutil/mips/generic_macros_msa.h" #include "vp9dsp_mips.h" diff --git a/libavcodec/mips/vp9dsp_init_mips.c b/libavcodec/mips/vp9dsp_init_mips.c index 3248baa3cc0c5..c8a48908af30e 100644 --- a/libavcodec/mips/vp9dsp_init_mips.c +++ b/libavcodec/mips/vp9dsp_init_mips.c @@ -20,7 +20,7 @@ #include "config.h" #include "libavutil/common.h" -#include "libavcodec/vp9.h" +#include "libavcodec/vp9dsp.h" #include "vp9dsp_mips.h" #if HAVE_MSA diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 202b29e2eb541..01b6a1b48c63f 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -30,7 +30,7 @@ #include "vp56.h" #include "vp9.h" #include "vp9data.h" -#include "vp9.h" +#include "vp9dec.h" #include "libavutil/avassert.h" #include "libavutil/pixdesc.h" diff --git a/libavcodec/vp9.h b/libavcodec/vp9.h index a2067303000f4..6d2abaf24ec2a 100644 --- a/libavcodec/vp9.h +++ b/libavcodec/vp9.h @@ -27,9 +27,6 @@ #include #include -#include "libavutil/buffer.h" -#include "libavutil/internal.h" - #include "avcodec.h" #include "thread.h" #include "vp56.h" @@ -93,131 +90,6 @@ enum InterPredMode { NEWMV = 13, }; -enum MVJoint { - MV_JOINT_ZERO, - MV_JOINT_H, - MV_JOINT_V, - MV_JOINT_HV, -}; - -typedef struct ProbContext { - uint8_t y_mode[4][9]; - uint8_t uv_mode[10][9]; - uint8_t filter[4][2]; - uint8_t mv_mode[7][3]; - uint8_t intra[4]; - uint8_t comp[5]; - uint8_t single_ref[5][2]; - uint8_t comp_ref[5]; - uint8_t tx32p[2][3]; - uint8_t tx16p[2][2]; - uint8_t tx8p[2]; - uint8_t skip[3]; - uint8_t mv_joint[3]; - struct { - uint8_t sign; - uint8_t classes[10]; - uint8_t class0; - uint8_t bits[10]; - uint8_t class0_fp[2][3]; - uint8_t fp[3]; - uint8_t class0_hp; - uint8_t hp; - } mv_comp[2]; - uint8_t partition[4][4][3]; -} ProbContext; - -typedef void (*vp9_mc_func)(uint8_t *dst, ptrdiff_t dst_stride, - const uint8_t *ref, ptrdiff_t ref_stride, - int h, int mx, int my); -typedef void (*vp9_scaled_mc_func)(uint8_t *dst, ptrdiff_t dst_stride, - const uint8_t *ref, ptrdiff_t ref_stride, - int h, int mx, int my, int dx, int dy); - -typedef struct VP9DSPContext { - /* - * dimension 1: 0=4x4, 1=8x8, 2=16x16, 3=32x32 - * dimension 2: intra prediction modes - * - * dst/left/top is aligned by transform-size (i.e. 4, 8, 16 or 32 pixels) - * stride is aligned by 16 pixels - * top[-1] is top/left; top[4,7] is top-right for 4x4 - */ - // FIXME(rbultje) maybe replace left/top pointers with HAVE_TOP/ - // HAVE_LEFT/HAVE_TOPRIGHT flags instead, and then handle it in-place? - // also needs to fit in with what H.264/VP8/etc do - void (*intra_pred[N_TXFM_SIZES][N_INTRA_PRED_MODES])(uint8_t *dst, - ptrdiff_t stride, - const uint8_t *left, - const uint8_t *top); - - /* - * dimension 1: 0=4x4, 1=8x8, 2=16x16, 3=32x32, 4=lossless (3-4=dct only) - * dimension 2: 0=dct/dct, 1=dct/adst, 2=adst/dct, 3=adst/adst - * - * dst is aligned by transform-size (i.e. 4, 8, 16 or 32 pixels) - * stride is aligned by 16 pixels - * block is 16-byte aligned - * eob indicates the position (+1) of the last non-zero coefficient, - * in scan-order. This can be used to write faster versions, e.g. a - * dc-only 4x4/8x8/16x16/32x32, or a 4x4-only (eob<10) 8x8/16x16/32x32, - * etc. - */ - // FIXME also write idct_add_block() versions for whole (inter) pred - // blocks, so we can do 2 4x4s at once - void (*itxfm_add[N_TXFM_SIZES + 1][N_TXFM_TYPES])(uint8_t *dst, - ptrdiff_t stride, - int16_t *block, int eob); - - /* - * dimension 1: width of filter (0=4, 1=8, 2=16) - * dimension 2: 0=col-edge filter (h), 1=row-edge filter (v) - * - * dst/stride are aligned by 8 - */ - void (*loop_filter_8[3][2])(uint8_t *dst, ptrdiff_t stride, - int mb_lim, int lim, int hev_thr); - - /* - * dimension 1: 0=col-edge filter (h), 1=row-edge filter (v) - * - * The width of filter is assumed to be 16; dst/stride are aligned by 16 - */ - void (*loop_filter_16[2])(uint8_t *dst, ptrdiff_t stride, - int mb_lim, int lim, int hev_thr); - - /* - * dimension 1/2: width of filter (0=4, 1=8) for each filter half - * dimension 3: 0=col-edge filter (h), 1=row-edge filter (v) - * - * dst/stride are aligned by operation size - * this basically calls loop_filter[d1][d3][0](), followed by - * loop_filter[d2][d3][0]() on the next 8 pixels - * mb_lim/lim/hev_thr contain two values in the lowest two bytes of the - * integer. - */ - // FIXME perhaps a mix4 that operates on 32px (for AVX2) - void (*loop_filter_mix2[2][2][2])(uint8_t *dst, ptrdiff_t stride, - int mb_lim, int lim, int hev_thr); - - /* - * dimension 1: hsize (0: 64, 1: 32, 2: 16, 3: 8, 4: 4) - * dimension 2: filter type (0: smooth, 1: regular, 2: sharp, 3: bilin) - * dimension 3: averaging type (0: put, 1: avg) - * dimension 4: x subpel interpolation (0: none, 1: 8tap/bilin) - * dimension 5: y subpel interpolation (0: none, 1: 8tap/bilin) - * - * dst/stride are aligned by hsize - */ - vp9_mc_func mc[5][4][2][2][2]; - - /* - * for scalable MC, first 3 dimensions identical to above, the other two - * don't exist since it changes per stepsize. - */ - vp9_scaled_mc_func smc[5][4][2]; -} VP9DSPContext; - enum CompPredMode { PRED_SINGLEREF, PRED_COMPREF, @@ -229,12 +101,6 @@ typedef struct VP9mvrefPair { int8_t ref[2]; } VP9mvrefPair; -typedef struct VP9Filter { - uint8_t level[8 * 8]; - uint8_t /* bit=col */ mask[2 /* 0=y, 1=uv */][2 /* 0=col, 1=row */] - [8 /* rows */][4 /* 0=16, 1=8, 2=4, 3=inner4 */]; -} VP9Filter; - typedef struct VP9Frame { ThreadFrame tf; AVBufferRef *extradata; @@ -270,16 +136,6 @@ enum BlockSize { N_BS_SIZES, }; -typedef struct VP9Block { - uint8_t seg_id, intra, comp, ref[2], mode[4], uvmode, skip; - enum FilterMode filter; - VP56mv mv[4 /* b_idx */][2 /* ref */]; - enum BlockSize bs; - enum TxfmMode tx, uvtx; - enum BlockLevel bl; - enum BlockPartition bp; -} VP9Block; - typedef struct VP9BitstreamHeader { // bitstream header uint8_t profile; @@ -355,137 +211,4 @@ typedef struct VP9SharedContext { VP9Frame frames[3]; } VP9SharedContext; -typedef struct VP9Context { - VP9SharedContext s; - - VP9DSPContext dsp; - VideoDSPContext vdsp; - GetBitContext gb; - VP56RangeCoder c; - VP56RangeCoder *c_b; - unsigned c_b_size; - VP9Block *b_base, *b; - int pass; - int row, row7, col, col7; - uint8_t *dst[3]; - ptrdiff_t y_stride, uv_stride; - - uint8_t ss_h, ss_v; - uint8_t last_bpp, bpp_index, bytesperpixel; - uint8_t last_keyframe; - // sb_cols/rows, rows/cols and last_fmt are used for allocating all internal - // arrays, and are thus per-thread. w/h and gf_fmt are synced between threads - // and are therefore per-stream. pix_fmt represents the value in the header - // of the currently processed frame. - int w, h; - enum AVPixelFormat pix_fmt, last_fmt, gf_fmt; - unsigned sb_cols, sb_rows, rows, cols; - ThreadFrame next_refs[8]; - - struct { - uint8_t lim_lut[64]; - uint8_t mblim_lut[64]; - } filter_lut; - unsigned tile_row_start, tile_row_end, tile_col_start, tile_col_end; - struct { - ProbContext p; - uint8_t coef[4][2][2][6][6][3]; - } prob_ctx[4]; - struct { - ProbContext p; - uint8_t coef[4][2][2][6][6][11]; - } prob; - struct { - unsigned y_mode[4][10]; - unsigned uv_mode[10][10]; - unsigned filter[4][3]; - unsigned mv_mode[7][4]; - unsigned intra[4][2]; - unsigned comp[5][2]; - unsigned single_ref[5][2][2]; - unsigned comp_ref[5][2]; - unsigned tx32p[2][4]; - unsigned tx16p[2][3]; - unsigned tx8p[2][2]; - unsigned skip[3][2]; - unsigned mv_joint[4]; - struct { - unsigned sign[2]; - unsigned classes[11]; - unsigned class0[2]; - unsigned bits[10][2]; - unsigned class0_fp[2][4]; - unsigned fp[4]; - unsigned class0_hp[2]; - unsigned hp[2]; - } mv_comp[2]; - unsigned partition[4][4][4]; - unsigned coef[4][2][2][6][6][3]; - unsigned eob[4][2][2][6][6][2]; - } counts; - - // contextual (left/above) cache - DECLARE_ALIGNED(16, uint8_t, left_y_nnz_ctx)[16]; - DECLARE_ALIGNED(16, uint8_t, left_mode_ctx)[16]; - DECLARE_ALIGNED(16, VP56mv, left_mv_ctx)[16][2]; - DECLARE_ALIGNED(16, uint8_t, left_uv_nnz_ctx)[2][16]; - DECLARE_ALIGNED(8, uint8_t, left_partition_ctx)[8]; - DECLARE_ALIGNED(8, uint8_t, left_skip_ctx)[8]; - DECLARE_ALIGNED(8, uint8_t, left_txfm_ctx)[8]; - DECLARE_ALIGNED(8, uint8_t, left_segpred_ctx)[8]; - DECLARE_ALIGNED(8, uint8_t, left_intra_ctx)[8]; - DECLARE_ALIGNED(8, uint8_t, left_comp_ctx)[8]; - DECLARE_ALIGNED(8, uint8_t, left_ref_ctx)[8]; - DECLARE_ALIGNED(8, uint8_t, left_filter_ctx)[8]; - uint8_t *above_partition_ctx; - uint8_t *above_mode_ctx; - // FIXME maybe merge some of the below in a flags field? - uint8_t *above_y_nnz_ctx; - uint8_t *above_uv_nnz_ctx[2]; - uint8_t *above_skip_ctx; // 1bit - uint8_t *above_txfm_ctx; // 2bit - uint8_t *above_segpred_ctx; // 1bit - uint8_t *above_intra_ctx; // 1bit - uint8_t *above_comp_ctx; // 1bit - uint8_t *above_ref_ctx; // 2bit - uint8_t *above_filter_ctx; - VP56mv (*above_mv_ctx)[2]; - - // whole-frame cache - uint8_t *intra_pred_data[3]; - VP9Filter *lflvl; - DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[135 * 144 * 2]; - - // block reconstruction intermediates - int block_alloc_using_2pass; - int16_t *block_base, *block, *uvblock_base[2], *uvblock[2]; - uint8_t *eob_base, *uveob_base[2], *eob, *uveob[2]; - struct { int x, y; } min_mv, max_mv; - DECLARE_ALIGNED(32, uint8_t, tmp_y)[64 * 64 * 2]; - DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][64 * 64 * 2]; - uint16_t mvscale[3][2]; - uint8_t mvstep[3][2]; -} VP9Context; - -extern const int16_t ff_vp9_subpel_filters[3][16][8]; - -void ff_vp9dsp_init(VP9DSPContext *dsp, int bpp, int bitexact); - -void ff_vp9dsp_init_8(VP9DSPContext *dsp); -void ff_vp9dsp_init_10(VP9DSPContext *dsp); -void ff_vp9dsp_init_12(VP9DSPContext *dsp); - -void ff_vp9dsp_init_aarch64(VP9DSPContext *dsp, int bpp); -void ff_vp9dsp_init_arm(VP9DSPContext *dsp, int bpp); -void ff_vp9dsp_init_x86(VP9DSPContext *dsp, int bpp, int bitexact); -void ff_vp9dsp_init_mips(VP9DSPContext *dsp, int bpp); - -void ff_vp9_fill_mv(VP9Context *s, VP56mv *mv, int mode, int sb); - -void ff_vp9_adapt_probs(VP9Context *s); - -void ff_vp9_decode_block(AVCodecContext *ctx, int row, int col, - VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, - enum BlockLevel bl, enum BlockPartition bp); - #endif /* AVCODEC_VP9_H */ diff --git a/libavcodec/vp9block.c b/libavcodec/vp9block.c index e5e117134df11..f91ef1a2a9910 100644 --- a/libavcodec/vp9block.c +++ b/libavcodec/vp9block.c @@ -29,6 +29,7 @@ #include "vp56.h" #include "vp9.h" #include "vp9data.h" +#include "vp9dec.h" static const uint8_t bwh_tab[2][N_BS_SIZES][2] = { { diff --git a/libavcodec/vp9data.h b/libavcodec/vp9data.h index 084e8820f8427..f27ab0b267a8d 100644 --- a/libavcodec/vp9data.h +++ b/libavcodec/vp9data.h @@ -24,7 +24,7 @@ #include -#include "vp9.h" +#include "vp9dec.h" extern const int8_t ff_vp9_partition_tree[3][2]; extern const uint8_t ff_vp9_default_kf_partition_probs[4][4][3]; diff --git a/libavcodec/vp9dec.h b/libavcodec/vp9dec.h new file mode 100644 index 0000000000000..ba821f3a5fce8 --- /dev/null +++ b/libavcodec/vp9dec.h @@ -0,0 +1,206 @@ +/* + * VP9 compatible video decoder + * + * Copyright (C) 2013 Ronald S. Bultje + * Copyright (C) 2013 Clément Bœsch + * + * 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 + */ + +#ifndef AVCODEC_VP9DEC_H +#define AVCODEC_VP9DEC_H + +#include +#include + +#include "libavutil/buffer.h" +#include "libavutil/internal.h" + +#include "vp9.h" +#include "vp9dsp.h" + +enum MVJoint { + MV_JOINT_ZERO, + MV_JOINT_H, + MV_JOINT_V, + MV_JOINT_HV, +}; + +typedef struct ProbContext { + uint8_t y_mode[4][9]; + uint8_t uv_mode[10][9]; + uint8_t filter[4][2]; + uint8_t mv_mode[7][3]; + uint8_t intra[4]; + uint8_t comp[5]; + uint8_t single_ref[5][2]; + uint8_t comp_ref[5]; + uint8_t tx32p[2][3]; + uint8_t tx16p[2][2]; + uint8_t tx8p[2]; + uint8_t skip[3]; + uint8_t mv_joint[3]; + struct { + uint8_t sign; + uint8_t classes[10]; + uint8_t class0; + uint8_t bits[10]; + uint8_t class0_fp[2][3]; + uint8_t fp[3]; + uint8_t class0_hp; + uint8_t hp; + } mv_comp[2]; + uint8_t partition[4][4][3]; +} ProbContext; + +typedef struct VP9Filter { + uint8_t level[8 * 8]; + uint8_t /* bit=col */ mask[2 /* 0=y, 1=uv */][2 /* 0=col, 1=row */] + [8 /* rows */][4 /* 0=16, 1=8, 2=4, 3=inner4 */]; +} VP9Filter; + +typedef struct VP9Block { + uint8_t seg_id, intra, comp, ref[2], mode[4], uvmode, skip; + enum FilterMode filter; + VP56mv mv[4 /* b_idx */][2 /* ref */]; + enum BlockSize bs; + enum TxfmMode tx, uvtx; + enum BlockLevel bl; + enum BlockPartition bp; +} VP9Block; + +typedef struct VP9Context { + VP9SharedContext s; + + VP9DSPContext dsp; + VideoDSPContext vdsp; + GetBitContext gb; + VP56RangeCoder c; + VP56RangeCoder *c_b; + unsigned c_b_size; + VP9Block *b_base, *b; + int pass; + int row, row7, col, col7; + uint8_t *dst[3]; + ptrdiff_t y_stride, uv_stride; + + uint8_t ss_h, ss_v; + uint8_t last_bpp, bpp_index, bytesperpixel; + uint8_t last_keyframe; + // sb_cols/rows, rows/cols and last_fmt are used for allocating all internal + // arrays, and are thus per-thread. w/h and gf_fmt are synced between threads + // and are therefore per-stream. pix_fmt represents the value in the header + // of the currently processed frame. + int w, h; + enum AVPixelFormat pix_fmt, last_fmt, gf_fmt; + unsigned sb_cols, sb_rows, rows, cols; + ThreadFrame next_refs[8]; + + struct { + uint8_t lim_lut[64]; + uint8_t mblim_lut[64]; + } filter_lut; + unsigned tile_row_start, tile_row_end, tile_col_start, tile_col_end; + struct { + ProbContext p; + uint8_t coef[4][2][2][6][6][3]; + } prob_ctx[4]; + struct { + ProbContext p; + uint8_t coef[4][2][2][6][6][11]; + } prob; + struct { + unsigned y_mode[4][10]; + unsigned uv_mode[10][10]; + unsigned filter[4][3]; + unsigned mv_mode[7][4]; + unsigned intra[4][2]; + unsigned comp[5][2]; + unsigned single_ref[5][2][2]; + unsigned comp_ref[5][2]; + unsigned tx32p[2][4]; + unsigned tx16p[2][3]; + unsigned tx8p[2][2]; + unsigned skip[3][2]; + unsigned mv_joint[4]; + struct { + unsigned sign[2]; + unsigned classes[11]; + unsigned class0[2]; + unsigned bits[10][2]; + unsigned class0_fp[2][4]; + unsigned fp[4]; + unsigned class0_hp[2]; + unsigned hp[2]; + } mv_comp[2]; + unsigned partition[4][4][4]; + unsigned coef[4][2][2][6][6][3]; + unsigned eob[4][2][2][6][6][2]; + } counts; + + // contextual (left/above) cache + DECLARE_ALIGNED(16, uint8_t, left_y_nnz_ctx)[16]; + DECLARE_ALIGNED(16, uint8_t, left_mode_ctx)[16]; + DECLARE_ALIGNED(16, VP56mv, left_mv_ctx)[16][2]; + DECLARE_ALIGNED(16, uint8_t, left_uv_nnz_ctx)[2][16]; + DECLARE_ALIGNED(8, uint8_t, left_partition_ctx)[8]; + DECLARE_ALIGNED(8, uint8_t, left_skip_ctx)[8]; + DECLARE_ALIGNED(8, uint8_t, left_txfm_ctx)[8]; + DECLARE_ALIGNED(8, uint8_t, left_segpred_ctx)[8]; + DECLARE_ALIGNED(8, uint8_t, left_intra_ctx)[8]; + DECLARE_ALIGNED(8, uint8_t, left_comp_ctx)[8]; + DECLARE_ALIGNED(8, uint8_t, left_ref_ctx)[8]; + DECLARE_ALIGNED(8, uint8_t, left_filter_ctx)[8]; + uint8_t *above_partition_ctx; + uint8_t *above_mode_ctx; + // FIXME maybe merge some of the below in a flags field? + uint8_t *above_y_nnz_ctx; + uint8_t *above_uv_nnz_ctx[2]; + uint8_t *above_skip_ctx; // 1bit + uint8_t *above_txfm_ctx; // 2bit + uint8_t *above_segpred_ctx; // 1bit + uint8_t *above_intra_ctx; // 1bit + uint8_t *above_comp_ctx; // 1bit + uint8_t *above_ref_ctx; // 2bit + uint8_t *above_filter_ctx; + VP56mv (*above_mv_ctx)[2]; + + // whole-frame cache + uint8_t *intra_pred_data[3]; + VP9Filter *lflvl; + DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[135 * 144 * 2]; + + // block reconstruction intermediates + int block_alloc_using_2pass; + int16_t *block_base, *block, *uvblock_base[2], *uvblock[2]; + uint8_t *eob_base, *uveob_base[2], *eob, *uveob[2]; + struct { int x, y; } min_mv, max_mv; + DECLARE_ALIGNED(32, uint8_t, tmp_y)[64 * 64 * 2]; + DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][64 * 64 * 2]; + uint16_t mvscale[3][2]; + uint8_t mvstep[3][2]; +} VP9Context; + +void ff_vp9_fill_mv(VP9Context *s, VP56mv *mv, int mode, int sb); + +void ff_vp9_adapt_probs(VP9Context *s); + +void ff_vp9_decode_block(AVCodecContext *ctx, int row, int col, + VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, + enum BlockLevel bl, enum BlockPartition bp); + +#endif /* AVCODEC_VP9DEC_H */ diff --git a/libavcodec/vp9dsp.c b/libavcodec/vp9dsp.c index cf9de4a0ff82f..f6d73f73cd4d1 100644 --- a/libavcodec/vp9dsp.c +++ b/libavcodec/vp9dsp.c @@ -23,7 +23,7 @@ #include "libavutil/avassert.h" #include "libavutil/common.h" -#include "vp9.h" +#include "vp9dsp.h" const DECLARE_ALIGNED(16, int16_t, ff_vp9_subpel_filters)[3][16][8] = { [FILTER_8TAP_REGULAR] = { diff --git a/libavcodec/vp9dsp.h b/libavcodec/vp9dsp.h new file mode 100644 index 0000000000000..d2c48b4d1ba57 --- /dev/null +++ b/libavcodec/vp9dsp.h @@ -0,0 +1,136 @@ +/* + * VP9 compatible video decoder + * + * Copyright (C) 2013 Ronald S. Bultje + * Copyright (C) 2013 Clément Bœsch + * + * 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 + */ + +#ifndef AVCODEC_VP9DSP_H +#define AVCODEC_VP9DSP_H + +#include +#include + +#include "libavcodec/vp9.h" + +typedef void (*vp9_mc_func)(uint8_t *dst, ptrdiff_t dst_stride, + const uint8_t *ref, ptrdiff_t ref_stride, + int h, int mx, int my); +typedef void (*vp9_scaled_mc_func)(uint8_t *dst, ptrdiff_t dst_stride, + const uint8_t *ref, ptrdiff_t ref_stride, + int h, int mx, int my, int dx, int dy); + +typedef struct VP9DSPContext { + /* + * dimension 1: 0=4x4, 1=8x8, 2=16x16, 3=32x32 + * dimension 2: intra prediction modes + * + * dst/left/top is aligned by transform-size (i.e. 4, 8, 16 or 32 pixels) + * stride is aligned by 16 pixels + * top[-1] is top/left; top[4,7] is top-right for 4x4 + */ + // FIXME(rbultje) maybe replace left/top pointers with HAVE_TOP/ + // HAVE_LEFT/HAVE_TOPRIGHT flags instead, and then handle it in-place? + // also needs to fit in with what H.264/VP8/etc do + void (*intra_pred[N_TXFM_SIZES][N_INTRA_PRED_MODES])(uint8_t *dst, + ptrdiff_t stride, + const uint8_t *left, + const uint8_t *top); + + /* + * dimension 1: 0=4x4, 1=8x8, 2=16x16, 3=32x32, 4=lossless (3-4=dct only) + * dimension 2: 0=dct/dct, 1=dct/adst, 2=adst/dct, 3=adst/adst + * + * dst is aligned by transform-size (i.e. 4, 8, 16 or 32 pixels) + * stride is aligned by 16 pixels + * block is 16-byte aligned + * eob indicates the position (+1) of the last non-zero coefficient, + * in scan-order. This can be used to write faster versions, e.g. a + * dc-only 4x4/8x8/16x16/32x32, or a 4x4-only (eob<10) 8x8/16x16/32x32, + * etc. + */ + // FIXME also write idct_add_block() versions for whole (inter) pred + // blocks, so we can do 2 4x4s at once + void (*itxfm_add[N_TXFM_SIZES + 1][N_TXFM_TYPES])(uint8_t *dst, + ptrdiff_t stride, + int16_t *block, int eob); + + /* + * dimension 1: width of filter (0=4, 1=8, 2=16) + * dimension 2: 0=col-edge filter (h), 1=row-edge filter (v) + * + * dst/stride are aligned by 8 + */ + void (*loop_filter_8[3][2])(uint8_t *dst, ptrdiff_t stride, + int mb_lim, int lim, int hev_thr); + + /* + * dimension 1: 0=col-edge filter (h), 1=row-edge filter (v) + * + * The width of filter is assumed to be 16; dst/stride are aligned by 16 + */ + void (*loop_filter_16[2])(uint8_t *dst, ptrdiff_t stride, + int mb_lim, int lim, int hev_thr); + + /* + * dimension 1/2: width of filter (0=4, 1=8) for each filter half + * dimension 3: 0=col-edge filter (h), 1=row-edge filter (v) + * + * dst/stride are aligned by operation size + * this basically calls loop_filter[d1][d3][0](), followed by + * loop_filter[d2][d3][0]() on the next 8 pixels + * mb_lim/lim/hev_thr contain two values in the lowest two bytes of the + * integer. + */ + // FIXME perhaps a mix4 that operates on 32px (for AVX2) + void (*loop_filter_mix2[2][2][2])(uint8_t *dst, ptrdiff_t stride, + int mb_lim, int lim, int hev_thr); + + /* + * dimension 1: hsize (0: 64, 1: 32, 2: 16, 3: 8, 4: 4) + * dimension 2: filter type (0: smooth, 1: regular, 2: sharp, 3: bilin) + * dimension 3: averaging type (0: put, 1: avg) + * dimension 4: x subpel interpolation (0: none, 1: 8tap/bilin) + * dimension 5: y subpel interpolation (0: none, 1: 8tap/bilin) + * + * dst/stride are aligned by hsize + */ + vp9_mc_func mc[5][4][2][2][2]; + + /* + * for scalable MC, first 3 dimensions identical to above, the other two + * don't exist since it changes per stepsize. + */ + vp9_scaled_mc_func smc[5][4][2]; +} VP9DSPContext; + +extern const int16_t ff_vp9_subpel_filters[3][16][8]; + +void ff_vp9dsp_init(VP9DSPContext *dsp, int bpp, int bitexact); + +void ff_vp9dsp_init_8(VP9DSPContext *dsp); +void ff_vp9dsp_init_10(VP9DSPContext *dsp); +void ff_vp9dsp_init_12(VP9DSPContext *dsp); + +void ff_vp9dsp_init_aarch64(VP9DSPContext *dsp, int bpp); +void ff_vp9dsp_init_arm(VP9DSPContext *dsp, int bpp); +void ff_vp9dsp_init_x86(VP9DSPContext *dsp, int bpp, int bitexact); +void ff_vp9dsp_init_mips(VP9DSPContext *dsp, int bpp); + +#endif /* AVCODEC_VP9DSP_H */ diff --git a/libavcodec/vp9dsp_template.c b/libavcodec/vp9dsp_template.c index 01b08cd349a70..bb54561a60b33 100644 --- a/libavcodec/vp9dsp_template.c +++ b/libavcodec/vp9dsp_template.c @@ -23,7 +23,7 @@ #include "libavutil/common.h" #include "bit_depth_template.c" -#include "vp9.h" +#include "vp9dsp.h" #if BIT_DEPTH != 12 diff --git a/libavcodec/vp9mvs.c b/libavcodec/vp9mvs.c index a66972bc8ba4c..e323bacc49c8f 100644 --- a/libavcodec/vp9mvs.c +++ b/libavcodec/vp9mvs.c @@ -25,6 +25,7 @@ #include "vp56.h" #include "vp9.h" #include "vp9data.h" +#include "vp9dec.h" static av_always_inline void clamp_mv(VP56mv *dst, const VP56mv *src, VP9Context *s) diff --git a/libavcodec/vp9prob.c b/libavcodec/vp9prob.c index b45d20d3d0e1b..cde909ce66a64 100644 --- a/libavcodec/vp9prob.c +++ b/libavcodec/vp9prob.c @@ -24,6 +24,7 @@ #include "vp56.h" #include "vp9.h" #include "vp9data.h" +#include "vp9dec.h" static av_always_inline void adapt_prob(uint8_t *p, unsigned ct0, unsigned ct1, int max_count, int update_factor) diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c index ae543771b0312..66363d46ad981 100644 --- a/libavcodec/x86/vp9dsp_init.c +++ b/libavcodec/x86/vp9dsp_init.c @@ -24,7 +24,7 @@ #include "libavutil/cpu.h" #include "libavutil/mem.h" #include "libavutil/x86/cpu.h" -#include "libavcodec/vp9.h" +#include "libavcodec/vp9dsp.h" #include "libavcodec/x86/vp9dsp_init.h" #if HAVE_YASM diff --git a/libavcodec/x86/vp9dsp_init.h b/libavcodec/x86/vp9dsp_init.h index 016dc7f28358c..e410cab3a12b6 100644 --- a/libavcodec/x86/vp9dsp_init.h +++ b/libavcodec/x86/vp9dsp_init.h @@ -23,7 +23,7 @@ #ifndef AVCODEC_X86_VP9DSP_INIT_H #define AVCODEC_X86_VP9DSP_INIT_H -#include "libavcodec/vp9.h" +#include "libavcodec/vp9dsp.h" // hack to force-expand BPC #define cat(a, bpp, b) a##bpp##b diff --git a/libavcodec/x86/vp9dsp_init_16bpp.c b/libavcodec/x86/vp9dsp_init_16bpp.c index 17aad50c60064..4576ff16922ca 100644 --- a/libavcodec/x86/vp9dsp_init_16bpp.c +++ b/libavcodec/x86/vp9dsp_init_16bpp.c @@ -24,7 +24,7 @@ #include "libavutil/cpu.h" #include "libavutil/mem.h" #include "libavutil/x86/cpu.h" -#include "libavcodec/vp9.h" +#include "libavcodec/vp9dsp.h" #include "libavcodec/x86/vp9dsp_init.h" #if HAVE_YASM diff --git a/libavcodec/x86/vp9dsp_init_16bpp_template.c b/libavcodec/x86/vp9dsp_init_16bpp_template.c index 6f37e4b35a2d1..4840b2844e3a3 100644 --- a/libavcodec/x86/vp9dsp_init_16bpp_template.c +++ b/libavcodec/x86/vp9dsp_init_16bpp_template.c @@ -24,7 +24,7 @@ #include "libavutil/cpu.h" #include "libavutil/mem.h" #include "libavutil/x86/cpu.h" -#include "libavcodec/vp9.h" +#include "libavcodec/vp9dsp.h" #include "libavcodec/x86/vp9dsp_init.h" #if HAVE_YASM From b823bbc10cc7b8674bb2dea50bd5dfc081e28620 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 27 Mar 2017 16:59:06 -0400 Subject: [PATCH 1352/3374] vp9: split out loopfilter functions in their own source file. --- libavcodec/Makefile | 2 +- libavcodec/vp9.c | 181 +-------------------------------------- libavcodec/vp9dec.h | 3 + libavcodec/vp9lpf.c | 202 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 208 insertions(+), 180 deletions(-) create mode 100644 libavcodec/vp9lpf.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index cf7ba258176aa..56515260859c7 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -610,7 +610,7 @@ OBJS-$(CONFIG_VP8_DECODER) += vp8.o vp56rac.o OBJS-$(CONFIG_VP8_CUVID_DECODER) += cuvid.o OBJS-$(CONFIG_VP8_MEDIACODEC_DECODER) += mediacodecdec.o OBJS-$(CONFIG_VP8_VAAPI_ENCODER) += vaapi_encode_vp8.o -OBJS-$(CONFIG_VP9_DECODER) += vp9.o vp9data.o vp9dsp.o \ +OBJS-$(CONFIG_VP9_DECODER) += vp9.o vp9data.o vp9dsp.o vp9lpf.o \ vp9block.o vp9prob.o vp9mvs.o vp56rac.o \ vp9dsp_8bpp.o vp9dsp_10bpp.o vp9dsp_12bpp.o OBJS-$(CONFIG_VP9_CUVID_DECODER) += cuvid.o diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 01b6a1b48c63f..4d7310f6d4d14 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -1056,184 +1056,6 @@ static void decode_sb_mem(AVCodecContext *avctx, int row, int col, VP9Filter *lf } } -static av_always_inline void filter_plane_cols(VP9Context *s, int col, int ss_h, int ss_v, - uint8_t *lvl, uint8_t (*mask)[4], - uint8_t *dst, ptrdiff_t ls) -{ - int y, x, bytesperpixel = s->bytesperpixel; - - // filter edges between columns (e.g. block1 | block2) - for (y = 0; y < 8; y += 2 << ss_v, dst += 16 * ls, lvl += 16 << ss_v) { - uint8_t *ptr = dst, *l = lvl, *hmask1 = mask[y], *hmask2 = mask[y + 1 + ss_v]; - unsigned hm1 = hmask1[0] | hmask1[1] | hmask1[2], hm13 = hmask1[3]; - unsigned hm2 = hmask2[1] | hmask2[2], hm23 = hmask2[3]; - unsigned hm = hm1 | hm2 | hm13 | hm23; - - for (x = 1; hm & ~(x - 1); x <<= 1, ptr += 8 * bytesperpixel >> ss_h) { - if (col || x > 1) { - if (hm1 & x) { - int L = *l, H = L >> 4; - int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - - if (hmask1[0] & x) { - if (hmask2[0] & x) { - av_assert2(l[8 << ss_v] == L); - s->dsp.loop_filter_16[0](ptr, ls, E, I, H); - } else { - s->dsp.loop_filter_8[2][0](ptr, ls, E, I, H); - } - } else if (hm2 & x) { - L = l[8 << ss_v]; - H |= (L >> 4) << 8; - E |= s->filter_lut.mblim_lut[L] << 8; - I |= s->filter_lut.lim_lut[L] << 8; - s->dsp.loop_filter_mix2[!!(hmask1[1] & x)] - [!!(hmask2[1] & x)] - [0](ptr, ls, E, I, H); - } else { - s->dsp.loop_filter_8[!!(hmask1[1] & x)] - [0](ptr, ls, E, I, H); - } - } else if (hm2 & x) { - int L = l[8 << ss_v], H = L >> 4; - int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - - s->dsp.loop_filter_8[!!(hmask2[1] & x)] - [0](ptr + 8 * ls, ls, E, I, H); - } - } - if (ss_h) { - if (x & 0xAA) - l += 2; - } else { - if (hm13 & x) { - int L = *l, H = L >> 4; - int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - - if (hm23 & x) { - L = l[8 << ss_v]; - H |= (L >> 4) << 8; - E |= s->filter_lut.mblim_lut[L] << 8; - I |= s->filter_lut.lim_lut[L] << 8; - s->dsp.loop_filter_mix2[0][0][0](ptr + 4 * bytesperpixel, ls, E, I, H); - } else { - s->dsp.loop_filter_8[0][0](ptr + 4 * bytesperpixel, ls, E, I, H); - } - } else if (hm23 & x) { - int L = l[8 << ss_v], H = L >> 4; - int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - - s->dsp.loop_filter_8[0][0](ptr + 8 * ls + 4 * bytesperpixel, ls, E, I, H); - } - l++; - } - } - } -} - -static av_always_inline void filter_plane_rows(VP9Context *s, int row, int ss_h, int ss_v, - uint8_t *lvl, uint8_t (*mask)[4], - uint8_t *dst, ptrdiff_t ls) -{ - int y, x, bytesperpixel = s->bytesperpixel; - - // block1 - // filter edges between rows (e.g. ------) - // block2 - for (y = 0; y < 8; y++, dst += 8 * ls >> ss_v) { - uint8_t *ptr = dst, *l = lvl, *vmask = mask[y]; - unsigned vm = vmask[0] | vmask[1] | vmask[2], vm3 = vmask[3]; - - for (x = 1; vm & ~(x - 1); x <<= (2 << ss_h), ptr += 16 * bytesperpixel, l += 2 << ss_h) { - if (row || y) { - if (vm & x) { - int L = *l, H = L >> 4; - int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - - if (vmask[0] & x) { - if (vmask[0] & (x << (1 + ss_h))) { - av_assert2(l[1 + ss_h] == L); - s->dsp.loop_filter_16[1](ptr, ls, E, I, H); - } else { - s->dsp.loop_filter_8[2][1](ptr, ls, E, I, H); - } - } else if (vm & (x << (1 + ss_h))) { - L = l[1 + ss_h]; - H |= (L >> 4) << 8; - E |= s->filter_lut.mblim_lut[L] << 8; - I |= s->filter_lut.lim_lut[L] << 8; - s->dsp.loop_filter_mix2[!!(vmask[1] & x)] - [!!(vmask[1] & (x << (1 + ss_h)))] - [1](ptr, ls, E, I, H); - } else { - s->dsp.loop_filter_8[!!(vmask[1] & x)] - [1](ptr, ls, E, I, H); - } - } else if (vm & (x << (1 + ss_h))) { - int L = l[1 + ss_h], H = L >> 4; - int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - - s->dsp.loop_filter_8[!!(vmask[1] & (x << (1 + ss_h)))] - [1](ptr + 8 * bytesperpixel, ls, E, I, H); - } - } - if (!ss_v) { - if (vm3 & x) { - int L = *l, H = L >> 4; - int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - - if (vm3 & (x << (1 + ss_h))) { - L = l[1 + ss_h]; - H |= (L >> 4) << 8; - E |= s->filter_lut.mblim_lut[L] << 8; - I |= s->filter_lut.lim_lut[L] << 8; - s->dsp.loop_filter_mix2[0][0][1](ptr + ls * 4, ls, E, I, H); - } else { - s->dsp.loop_filter_8[0][1](ptr + ls * 4, ls, E, I, H); - } - } else if (vm3 & (x << (1 + ss_h))) { - int L = l[1 + ss_h], H = L >> 4; - int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - - s->dsp.loop_filter_8[0][1](ptr + ls * 4 + 8 * bytesperpixel, ls, E, I, H); - } - } - } - if (ss_v) { - if (y & 1) - lvl += 16; - } else { - lvl += 8; - } - } -} - -static void loopfilter_sb(AVCodecContext *avctx, VP9Filter *lflvl, - int row, int col, ptrdiff_t yoff, ptrdiff_t uvoff) -{ - VP9Context *s = avctx->priv_data; - AVFrame *f = s->s.frames[CUR_FRAME].tf.f; - uint8_t *dst = f->data[0] + yoff; - ptrdiff_t ls_y = f->linesize[0], ls_uv = f->linesize[1]; - uint8_t (*uv_masks)[8][4] = lflvl->mask[s->ss_h | s->ss_v]; - int p; - - /* FIXME: In how far can we interleave the v/h loopfilter calls? E.g. - * if you think of them as acting on a 8x8 block max, we can interleave - * each v/h within the single x loop, but that only works if we work on - * 8 pixel blocks, and we won't always do that (we want at least 16px - * to use SSE2 optimizations, perhaps 32 for AVX2) */ - - filter_plane_cols(s, col, 0, 0, lflvl->level, lflvl->mask[0][0], dst, ls_y); - filter_plane_rows(s, row, 0, 0, lflvl->level, lflvl->mask[0][1], dst, ls_y); - - for (p = 0; p < 2; p++) { - dst = f->data[1 + p] + uvoff; - filter_plane_cols(s, col, s->ss_h, s->ss_v, lflvl->level, uv_masks[0], dst, ls_uv); - filter_plane_rows(s, row, s->ss_h, s->ss_v, lflvl->level, uv_masks[1], dst, ls_uv); - } -} - static void set_tile_offset(int *start, int *end, int idx, int log2_n, int n) { int sb_start = ( idx * n) >> log2_n; @@ -1522,7 +1344,8 @@ FF_ENABLE_DEPRECATION_WARNINGS for (col = 0; col < s->cols; col += 8, yoff2 += 64 * bytesperpixel, uvoff2 += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) { - loopfilter_sb(avctx, lflvl_ptr, row, col, yoff2, uvoff2); + ff_vp9_loopfilter_sb(avctx, lflvl_ptr, row, col, + yoff2, uvoff2); } } diff --git a/libavcodec/vp9dec.h b/libavcodec/vp9dec.h index ba821f3a5fce8..1f3348adb1b7f 100644 --- a/libavcodec/vp9dec.h +++ b/libavcodec/vp9dec.h @@ -203,4 +203,7 @@ void ff_vp9_decode_block(AVCodecContext *ctx, int row, int col, VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl, enum BlockPartition bp); +void ff_vp9_loopfilter_sb(AVCodecContext *avctx, VP9Filter *lflvl, + int row, int col, ptrdiff_t yoff, ptrdiff_t uvoff); + #endif /* AVCODEC_VP9DEC_H */ diff --git a/libavcodec/vp9lpf.c b/libavcodec/vp9lpf.c new file mode 100644 index 0000000000000..414cede8520ec --- /dev/null +++ b/libavcodec/vp9lpf.c @@ -0,0 +1,202 @@ +/* + * VP9 compatible video decoder + * + * Copyright (C) 2013 Ronald S. Bultje + * Copyright (C) 2013 Clément Bœsch + * + * 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 "vp9dec.h" + +static av_always_inline void filter_plane_cols(VP9Context *s, int col, int ss_h, int ss_v, + uint8_t *lvl, uint8_t (*mask)[4], + uint8_t *dst, ptrdiff_t ls) +{ + int y, x, bytesperpixel = s->bytesperpixel; + + // filter edges between columns (e.g. block1 | block2) + for (y = 0; y < 8; y += 2 << ss_v, dst += 16 * ls, lvl += 16 << ss_v) { + uint8_t *ptr = dst, *l = lvl, *hmask1 = mask[y], *hmask2 = mask[y + 1 + ss_v]; + unsigned hm1 = hmask1[0] | hmask1[1] | hmask1[2], hm13 = hmask1[3]; + unsigned hm2 = hmask2[1] | hmask2[2], hm23 = hmask2[3]; + unsigned hm = hm1 | hm2 | hm13 | hm23; + + for (x = 1; hm & ~(x - 1); x <<= 1, ptr += 8 * bytesperpixel >> ss_h) { + if (col || x > 1) { + if (hm1 & x) { + int L = *l, H = L >> 4; + int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; + + if (hmask1[0] & x) { + if (hmask2[0] & x) { + av_assert2(l[8 << ss_v] == L); + s->dsp.loop_filter_16[0](ptr, ls, E, I, H); + } else { + s->dsp.loop_filter_8[2][0](ptr, ls, E, I, H); + } + } else if (hm2 & x) { + L = l[8 << ss_v]; + H |= (L >> 4) << 8; + E |= s->filter_lut.mblim_lut[L] << 8; + I |= s->filter_lut.lim_lut[L] << 8; + s->dsp.loop_filter_mix2[!!(hmask1[1] & x)] + [!!(hmask2[1] & x)] + [0](ptr, ls, E, I, H); + } else { + s->dsp.loop_filter_8[!!(hmask1[1] & x)] + [0](ptr, ls, E, I, H); + } + } else if (hm2 & x) { + int L = l[8 << ss_v], H = L >> 4; + int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; + + s->dsp.loop_filter_8[!!(hmask2[1] & x)] + [0](ptr + 8 * ls, ls, E, I, H); + } + } + if (ss_h) { + if (x & 0xAA) + l += 2; + } else { + if (hm13 & x) { + int L = *l, H = L >> 4; + int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; + + if (hm23 & x) { + L = l[8 << ss_v]; + H |= (L >> 4) << 8; + E |= s->filter_lut.mblim_lut[L] << 8; + I |= s->filter_lut.lim_lut[L] << 8; + s->dsp.loop_filter_mix2[0][0][0](ptr + 4 * bytesperpixel, ls, E, I, H); + } else { + s->dsp.loop_filter_8[0][0](ptr + 4 * bytesperpixel, ls, E, I, H); + } + } else if (hm23 & x) { + int L = l[8 << ss_v], H = L >> 4; + int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; + + s->dsp.loop_filter_8[0][0](ptr + 8 * ls + 4 * bytesperpixel, ls, E, I, H); + } + l++; + } + } + } +} + +static av_always_inline void filter_plane_rows(VP9Context *s, int row, int ss_h, int ss_v, + uint8_t *lvl, uint8_t (*mask)[4], + uint8_t *dst, ptrdiff_t ls) +{ + int y, x, bytesperpixel = s->bytesperpixel; + + // block1 + // filter edges between rows (e.g. ------) + // block2 + for (y = 0; y < 8; y++, dst += 8 * ls >> ss_v) { + uint8_t *ptr = dst, *l = lvl, *vmask = mask[y]; + unsigned vm = vmask[0] | vmask[1] | vmask[2], vm3 = vmask[3]; + + for (x = 1; vm & ~(x - 1); x <<= (2 << ss_h), ptr += 16 * bytesperpixel, l += 2 << ss_h) { + if (row || y) { + if (vm & x) { + int L = *l, H = L >> 4; + int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; + + if (vmask[0] & x) { + if (vmask[0] & (x << (1 + ss_h))) { + av_assert2(l[1 + ss_h] == L); + s->dsp.loop_filter_16[1](ptr, ls, E, I, H); + } else { + s->dsp.loop_filter_8[2][1](ptr, ls, E, I, H); + } + } else if (vm & (x << (1 + ss_h))) { + L = l[1 + ss_h]; + H |= (L >> 4) << 8; + E |= s->filter_lut.mblim_lut[L] << 8; + I |= s->filter_lut.lim_lut[L] << 8; + s->dsp.loop_filter_mix2[!!(vmask[1] & x)] + [!!(vmask[1] & (x << (1 + ss_h)))] + [1](ptr, ls, E, I, H); + } else { + s->dsp.loop_filter_8[!!(vmask[1] & x)] + [1](ptr, ls, E, I, H); + } + } else if (vm & (x << (1 + ss_h))) { + int L = l[1 + ss_h], H = L >> 4; + int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; + + s->dsp.loop_filter_8[!!(vmask[1] & (x << (1 + ss_h)))] + [1](ptr + 8 * bytesperpixel, ls, E, I, H); + } + } + if (!ss_v) { + if (vm3 & x) { + int L = *l, H = L >> 4; + int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; + + if (vm3 & (x << (1 + ss_h))) { + L = l[1 + ss_h]; + H |= (L >> 4) << 8; + E |= s->filter_lut.mblim_lut[L] << 8; + I |= s->filter_lut.lim_lut[L] << 8; + s->dsp.loop_filter_mix2[0][0][1](ptr + ls * 4, ls, E, I, H); + } else { + s->dsp.loop_filter_8[0][1](ptr + ls * 4, ls, E, I, H); + } + } else if (vm3 & (x << (1 + ss_h))) { + int L = l[1 + ss_h], H = L >> 4; + int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; + + s->dsp.loop_filter_8[0][1](ptr + ls * 4 + 8 * bytesperpixel, ls, E, I, H); + } + } + } + if (ss_v) { + if (y & 1) + lvl += 16; + } else { + lvl += 8; + } + } +} + +void ff_vp9_loopfilter_sb(AVCodecContext *avctx, VP9Filter *lflvl, + int row, int col, ptrdiff_t yoff, ptrdiff_t uvoff) +{ + VP9Context *s = avctx->priv_data; + AVFrame *f = s->s.frames[CUR_FRAME].tf.f; + uint8_t *dst = f->data[0] + yoff; + ptrdiff_t ls_y = f->linesize[0], ls_uv = f->linesize[1]; + uint8_t (*uv_masks)[8][4] = lflvl->mask[s->ss_h | s->ss_v]; + int p; + + /* FIXME: In how far can we interleave the v/h loopfilter calls? E.g. + * if you think of them as acting on a 8x8 block max, we can interleave + * each v/h within the single x loop, but that only works if we work on + * 8 pixel blocks, and we won't always do that (we want at least 16px + * to use SSE2 optimizations, perhaps 32 for AVX2) */ + + filter_plane_cols(s, col, 0, 0, lflvl->level, lflvl->mask[0][0], dst, ls_y); + filter_plane_rows(s, row, 0, 0, lflvl->level, lflvl->mask[0][1], dst, ls_y); + + for (p = 0; p < 2; p++) { + dst = f->data[1 + p] + uvoff; + filter_plane_cols(s, col, s->ss_h, s->ss_v, lflvl->level, uv_masks[0], dst, ls_uv); + filter_plane_rows(s, row, s->ss_h, s->ss_v, lflvl->level, uv_masks[1], dst, ls_uv); + } +} From 6d0d1c4a43f5e5fc195226367fd1c49843d25d71 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 27 Mar 2017 17:32:20 -0400 Subject: [PATCH 1353/3374] vp9: split out reconstruction functions in their own source file. --- libavcodec/Makefile | 2 +- libavcodec/vp9_mc_template.c | 6 +- libavcodec/vp9block.c | 643 +---------------------------------- libavcodec/vp9data.c | 10 + libavcodec/vp9data.h | 1 + libavcodec/vp9dec.h | 7 + libavcodec/vp9recon.c | 639 ++++++++++++++++++++++++++++++++++ 7 files changed, 674 insertions(+), 634 deletions(-) create mode 100644 libavcodec/vp9recon.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 56515260859c7..876a69e013a3e 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -610,7 +610,7 @@ OBJS-$(CONFIG_VP8_DECODER) += vp8.o vp56rac.o OBJS-$(CONFIG_VP8_CUVID_DECODER) += cuvid.o OBJS-$(CONFIG_VP8_MEDIACODEC_DECODER) += mediacodecdec.o OBJS-$(CONFIG_VP8_VAAPI_ENCODER) += vaapi_encode_vp8.o -OBJS-$(CONFIG_VP9_DECODER) += vp9.o vp9data.o vp9dsp.o vp9lpf.o \ +OBJS-$(CONFIG_VP9_DECODER) += vp9.o vp9data.o vp9dsp.o vp9lpf.o vp9recon.o \ vp9block.o vp9prob.o vp9mvs.o vp56rac.o \ vp9dsp_8bpp.o vp9dsp_10bpp.o vp9dsp_12bpp.o OBJS-$(CONFIG_VP9_CUVID_DECODER) += cuvid.o diff --git a/libavcodec/vp9_mc_template.c b/libavcodec/vp9_mc_template.c index 2d1e9bf8fbaf9..8ff654bc380ba 100644 --- a/libavcodec/vp9_mc_template.c +++ b/libavcodec/vp9_mc_template.c @@ -405,8 +405,10 @@ static void FN(inter_pred)(AVCodecContext *avctx) } } else { int bwl = bwlog_tab[0][b->bs]; - int bw = bwh_tab[0][b->bs][0] * 4, bh = bwh_tab[0][b->bs][1] * 4; - int uvbw = bwh_tab[s->ss_h][b->bs][0] * 4, uvbh = bwh_tab[s->ss_v][b->bs][1] * 4; + int bw = ff_vp9_bwh_tab[0][b->bs][0] * 4; + int bh = ff_vp9_bwh_tab[0][b->bs][1] * 4; + int uvbw = ff_vp9_bwh_tab[s->ss_h][b->bs][0] * 4; + int uvbh = ff_vp9_bwh_tab[s->ss_v][b->bs][1] * 4; mc_luma_dir(s, mc[bwl][b->filter][0], s->dst[0], ls_y, ref1->data[0], ref1->linesize[0], tref1, diff --git a/libavcodec/vp9block.c b/libavcodec/vp9block.c index f91ef1a2a9910..ae2f0e4c6f752 100644 --- a/libavcodec/vp9block.c +++ b/libavcodec/vp9block.c @@ -31,16 +31,6 @@ #include "vp9data.h" #include "vp9dec.h" -static const uint8_t bwh_tab[2][N_BS_SIZES][2] = { - { - { 16, 16 }, { 16, 8 }, { 8, 16 }, { 8, 8 }, { 8, 4 }, { 4, 8 }, - { 4, 4 }, { 4, 2 }, { 2, 4 }, { 2, 2 }, { 2, 1 }, { 1, 2 }, { 1, 1 }, - }, { - { 8, 8 }, { 8, 4 }, { 4, 8 }, { 4, 4 }, { 4, 2 }, { 2, 4 }, - { 2, 2 }, { 2, 1 }, { 1, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, - } -}; - static av_always_inline void setctx_2d(uint8_t *ptr, int w, int h, ptrdiff_t stride, int v) { @@ -103,8 +93,8 @@ static void decode_mode(AVCodecContext *avctx) VP9Block *b = s->b; int row = s->row, col = s->col, row7 = s->row7; enum TxfmMode max_tx = max_tx_for_bl_bp[b->bs]; - int bw4 = bwh_tab[1][b->bs][0], w4 = FFMIN(s->cols - col, bw4); - int bh4 = bwh_tab[1][b->bs][1], h4 = FFMIN(s->rows - row, bh4), y; + int bw4 = ff_vp9_bwh_tab[1][b->bs][0], w4 = FFMIN(s->cols - col, bw4); + int bh4 = ff_vp9_bwh_tab[1][b->bs][1], h4 = FFMIN(s->rows - row, bh4), y; int have_a = row > 0, have_l = col > s->tile_col_start; int vref, filter_id; @@ -272,8 +262,8 @@ static void decode_mode(AVCodecContext *avctx) b->mode[2] = b->mode[1] = b->mode[0]; // FIXME this can probably be optimized - memset(a, b->mode[0], bwh_tab[0][b->bs][0]); - memset(l, b->mode[0], bwh_tab[0][b->bs][1]); + memset(a, b->mode[0], ff_vp9_bwh_tab[0][b->bs][0]); + memset(l, b->mode[0], ff_vp9_bwh_tab[0][b->bs][1]); } b->uvmode = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, ff_vp9_default_kf_uvmode_probs[b->mode[3]]); @@ -725,7 +715,7 @@ static void decode_mode(AVCodecContext *avctx) } #endif - switch (bwh_tab[1][b->bs][0]) { + switch (ff_vp9_bwh_tab[1][b->bs][0]) { #define SET_CTXS(dir, off, n) \ do { \ SPLAT_CTX(s->dir##_skip_ctx[off], b->skip, n); \ @@ -748,7 +738,7 @@ static void decode_mode(AVCodecContext *avctx) case 4: SET_CTXS(above, col, 4); break; case 8: SET_CTXS(above, col, 8); break; } - switch (bwh_tab[1][b->bs][1]) { + switch (ff_vp9_bwh_tab[1][b->bs][1]) { case 1: SET_CTXS(left, row7, 1); break; case 2: SET_CTXS(left, row7, 2); break; case 4: SET_CTXS(left, row7, 4); break; @@ -983,7 +973,7 @@ static av_always_inline int decode_coeffs(AVCodecContext *avctx, int is8bitsperp uint8_t (*p)[6][11] = s->prob.coef[b->tx][0 /* y */][!b->intra]; unsigned (*c)[6][3] = s->counts.coef[b->tx][0 /* y */][!b->intra]; unsigned (*e)[6][2] = s->counts.eob[b->tx][0 /* y */][!b->intra]; - int w4 = bwh_tab[1][b->bs][0] << 1, h4 = bwh_tab[1][b->bs][1] << 1; + int w4 = ff_vp9_bwh_tab[1][b->bs][0] << 1, h4 = ff_vp9_bwh_tab[1][b->bs][1] << 1; int end_x = FFMIN(2 * (s->cols - col), w4); int end_y = FFMIN(2 * (s->rows - row), h4); int n, pl, x, y, ret; @@ -1152,615 +1142,6 @@ static int decode_coeffs_16bpp(AVCodecContext *avctx) return decode_coeffs(avctx, 0); } -static av_always_inline int check_intra_mode(VP9Context *s, int mode, uint8_t **a, - uint8_t *dst_edge, ptrdiff_t stride_edge, - uint8_t *dst_inner, ptrdiff_t stride_inner, - uint8_t *l, int col, int x, int w, - int row, int y, enum TxfmMode tx, - int p, int ss_h, int ss_v, int bytesperpixel) -{ - int have_top = row > 0 || y > 0; - int have_left = col > s->tile_col_start || x > 0; - int have_right = x < w - 1; - int bpp = s->s.h.bpp; - static const uint8_t mode_conv[10][2 /* have_left */][2 /* have_top */] = { - [VERT_PRED] = { { DC_127_PRED, VERT_PRED }, - { DC_127_PRED, VERT_PRED } }, - [HOR_PRED] = { { DC_129_PRED, DC_129_PRED }, - { HOR_PRED, HOR_PRED } }, - [DC_PRED] = { { DC_128_PRED, TOP_DC_PRED }, - { LEFT_DC_PRED, DC_PRED } }, - [DIAG_DOWN_LEFT_PRED] = { { DC_127_PRED, DIAG_DOWN_LEFT_PRED }, - { DC_127_PRED, DIAG_DOWN_LEFT_PRED } }, - [DIAG_DOWN_RIGHT_PRED] = { { DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED }, - { DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED } }, - [VERT_RIGHT_PRED] = { { VERT_RIGHT_PRED, VERT_RIGHT_PRED }, - { VERT_RIGHT_PRED, VERT_RIGHT_PRED } }, - [HOR_DOWN_PRED] = { { HOR_DOWN_PRED, HOR_DOWN_PRED }, - { HOR_DOWN_PRED, HOR_DOWN_PRED } }, - [VERT_LEFT_PRED] = { { DC_127_PRED, VERT_LEFT_PRED }, - { DC_127_PRED, VERT_LEFT_PRED } }, - [HOR_UP_PRED] = { { DC_129_PRED, DC_129_PRED }, - { HOR_UP_PRED, HOR_UP_PRED } }, - [TM_VP8_PRED] = { { DC_129_PRED, VERT_PRED }, - { HOR_PRED, TM_VP8_PRED } }, - }; - static const struct { - uint8_t needs_left:1; - uint8_t needs_top:1; - uint8_t needs_topleft:1; - uint8_t needs_topright:1; - uint8_t invert_left:1; - } edges[N_INTRA_PRED_MODES] = { - [VERT_PRED] = { .needs_top = 1 }, - [HOR_PRED] = { .needs_left = 1 }, - [DC_PRED] = { .needs_top = 1, .needs_left = 1 }, - [DIAG_DOWN_LEFT_PRED] = { .needs_top = 1, .needs_topright = 1 }, - [DIAG_DOWN_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1, - .needs_topleft = 1 }, - [VERT_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1, - .needs_topleft = 1 }, - [HOR_DOWN_PRED] = { .needs_left = 1, .needs_top = 1, - .needs_topleft = 1 }, - [VERT_LEFT_PRED] = { .needs_top = 1, .needs_topright = 1 }, - [HOR_UP_PRED] = { .needs_left = 1, .invert_left = 1 }, - [TM_VP8_PRED] = { .needs_left = 1, .needs_top = 1, - .needs_topleft = 1 }, - [LEFT_DC_PRED] = { .needs_left = 1 }, - [TOP_DC_PRED] = { .needs_top = 1 }, - [DC_128_PRED] = { 0 }, - [DC_127_PRED] = { 0 }, - [DC_129_PRED] = { 0 } - }; - - av_assert2(mode >= 0 && mode < 10); - mode = mode_conv[mode][have_left][have_top]; - if (edges[mode].needs_top) { - uint8_t *top, *topleft; - int n_px_need = 4 << tx, n_px_have = (((s->cols - col) << !ss_h) - x) * 4; - int n_px_need_tr = 0; - - if (tx == TX_4X4 && edges[mode].needs_topright && have_right) - n_px_need_tr = 4; - - // if top of sb64-row, use s->intra_pred_data[] instead of - // dst[-stride] for intra prediction (it contains pre- instead of - // post-loopfilter data) - if (have_top) { - top = !(row & 7) && !y ? - s->intra_pred_data[p] + (col * (8 >> ss_h) + x * 4) * bytesperpixel : - y == 0 ? &dst_edge[-stride_edge] : &dst_inner[-stride_inner]; - if (have_left) - topleft = !(row & 7) && !y ? - s->intra_pred_data[p] + (col * (8 >> ss_h) + x * 4) * bytesperpixel : - y == 0 || x == 0 ? &dst_edge[-stride_edge] : - &dst_inner[-stride_inner]; - } - - if (have_top && - (!edges[mode].needs_topleft || (have_left && top == topleft)) && - (tx != TX_4X4 || !edges[mode].needs_topright || have_right) && - n_px_need + n_px_need_tr <= n_px_have) { - *a = top; - } else { - if (have_top) { - if (n_px_need <= n_px_have) { - memcpy(*a, top, n_px_need * bytesperpixel); - } else { -#define memset_bpp(c, i1, v, i2, num) do { \ - if (bytesperpixel == 1) { \ - memset(&(c)[(i1)], (v)[(i2)], (num)); \ - } else { \ - int n, val = AV_RN16A(&(v)[(i2) * 2]); \ - for (n = 0; n < (num); n++) { \ - AV_WN16A(&(c)[((i1) + n) * 2], val); \ - } \ - } \ -} while (0) - memcpy(*a, top, n_px_have * bytesperpixel); - memset_bpp(*a, n_px_have, (*a), n_px_have - 1, n_px_need - n_px_have); - } - } else { -#define memset_val(c, val, num) do { \ - if (bytesperpixel == 1) { \ - memset((c), (val), (num)); \ - } else { \ - int n; \ - for (n = 0; n < (num); n++) { \ - AV_WN16A(&(c)[n * 2], (val)); \ - } \ - } \ -} while (0) - memset_val(*a, (128 << (bpp - 8)) - 1, n_px_need); - } - if (edges[mode].needs_topleft) { - if (have_left && have_top) { -#define assign_bpp(c, i1, v, i2) do { \ - if (bytesperpixel == 1) { \ - (c)[(i1)] = (v)[(i2)]; \ - } else { \ - AV_COPY16(&(c)[(i1) * 2], &(v)[(i2) * 2]); \ - } \ -} while (0) - assign_bpp(*a, -1, topleft, -1); - } else { -#define assign_val(c, i, v) do { \ - if (bytesperpixel == 1) { \ - (c)[(i)] = (v); \ - } else { \ - AV_WN16A(&(c)[(i) * 2], (v)); \ - } \ -} while (0) - assign_val((*a), -1, (128 << (bpp - 8)) + (have_top ? +1 : -1)); - } - } - if (tx == TX_4X4 && edges[mode].needs_topright) { - if (have_top && have_right && - n_px_need + n_px_need_tr <= n_px_have) { - memcpy(&(*a)[4 * bytesperpixel], &top[4 * bytesperpixel], 4 * bytesperpixel); - } else { - memset_bpp(*a, 4, *a, 3, 4); - } - } - } - } - if (edges[mode].needs_left) { - if (have_left) { - int n_px_need = 4 << tx, i, n_px_have = (((s->rows - row) << !ss_v) - y) * 4; - uint8_t *dst = x == 0 ? dst_edge : dst_inner; - ptrdiff_t stride = x == 0 ? stride_edge : stride_inner; - - if (edges[mode].invert_left) { - if (n_px_need <= n_px_have) { - for (i = 0; i < n_px_need; i++) - assign_bpp(l, i, &dst[i * stride], -1); - } else { - for (i = 0; i < n_px_have; i++) - assign_bpp(l, i, &dst[i * stride], -1); - memset_bpp(l, n_px_have, l, n_px_have - 1, n_px_need - n_px_have); - } - } else { - if (n_px_need <= n_px_have) { - for (i = 0; i < n_px_need; i++) - assign_bpp(l, n_px_need - 1 - i, &dst[i * stride], -1); - } else { - for (i = 0; i < n_px_have; i++) - assign_bpp(l, n_px_need - 1 - i, &dst[i * stride], -1); - memset_bpp(l, 0, l, n_px_need - n_px_have, n_px_need - n_px_have); - } - } - } else { - memset_val(l, (128 << (bpp - 8)) + 1, 4 << tx); - } - } - - return mode; -} - -static av_always_inline void intra_recon(AVCodecContext *avctx, ptrdiff_t y_off, - ptrdiff_t uv_off, int bytesperpixel) -{ - VP9Context *s = avctx->priv_data; - VP9Block *b = s->b; - int row = s->row, col = s->col; - int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n; - int h4 = bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2); - int end_x = FFMIN(2 * (s->cols - col), w4); - int end_y = FFMIN(2 * (s->rows - row), h4); - int tx = 4 * s->s.h.lossless + b->tx, uvtx = b->uvtx + 4 * s->s.h.lossless; - int uvstep1d = 1 << b->uvtx, p; - uint8_t *dst = s->dst[0], *dst_r = s->s.frames[CUR_FRAME].tf.f->data[0] + y_off; - LOCAL_ALIGNED_32(uint8_t, a_buf, [96]); - LOCAL_ALIGNED_32(uint8_t, l, [64]); - - for (n = 0, y = 0; y < end_y; y += step1d) { - uint8_t *ptr = dst, *ptr_r = dst_r; - for (x = 0; x < end_x; x += step1d, ptr += 4 * step1d * bytesperpixel, - ptr_r += 4 * step1d * bytesperpixel, n += step) { - int mode = b->mode[b->bs > BS_8x8 && b->tx == TX_4X4 ? - y * 2 + x : 0]; - uint8_t *a = &a_buf[32]; - enum TxfmType txtp = ff_vp9_intra_txfm_type[mode]; - int eob = b->skip ? 0 : b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n]; - - mode = check_intra_mode(s, mode, &a, ptr_r, - s->s.frames[CUR_FRAME].tf.f->linesize[0], - ptr, s->y_stride, l, - col, x, w4, row, y, b->tx, 0, 0, 0, bytesperpixel); - s->dsp.intra_pred[b->tx][mode](ptr, s->y_stride, l, a); - if (eob) - s->dsp.itxfm_add[tx][txtp](ptr, s->y_stride, - s->block + 16 * n * bytesperpixel, eob); - } - dst_r += 4 * step1d * s->s.frames[CUR_FRAME].tf.f->linesize[0]; - dst += 4 * step1d * s->y_stride; - } - - // U/V - w4 >>= s->ss_h; - end_x >>= s->ss_h; - end_y >>= s->ss_v; - step = 1 << (b->uvtx * 2); - for (p = 0; p < 2; p++) { - dst = s->dst[1 + p]; - dst_r = s->s.frames[CUR_FRAME].tf.f->data[1 + p] + uv_off; - for (n = 0, y = 0; y < end_y; y += uvstep1d) { - uint8_t *ptr = dst, *ptr_r = dst_r; - for (x = 0; x < end_x; x += uvstep1d, ptr += 4 * uvstep1d * bytesperpixel, - ptr_r += 4 * uvstep1d * bytesperpixel, n += step) { - int mode = b->uvmode; - uint8_t *a = &a_buf[32]; - int eob = b->skip ? 0 : b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n]; - - mode = check_intra_mode(s, mode, &a, ptr_r, - s->s.frames[CUR_FRAME].tf.f->linesize[1], - ptr, s->uv_stride, l, col, x, w4, row, y, - b->uvtx, p + 1, s->ss_h, s->ss_v, bytesperpixel); - s->dsp.intra_pred[b->uvtx][mode](ptr, s->uv_stride, l, a); - if (eob) - s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride, - s->uvblock[p] + 16 * n * bytesperpixel, eob); - } - dst_r += 4 * uvstep1d * s->s.frames[CUR_FRAME].tf.f->linesize[1]; - dst += 4 * uvstep1d * s->uv_stride; - } - } -} - -static void intra_recon_8bpp(AVCodecContext *avctx, ptrdiff_t y_off, ptrdiff_t uv_off) -{ - intra_recon(avctx, y_off, uv_off, 1); -} - -static void intra_recon_16bpp(AVCodecContext *avctx, ptrdiff_t y_off, ptrdiff_t uv_off) -{ - intra_recon(avctx, y_off, uv_off, 2); -} - -static av_always_inline void mc_luma_unscaled(VP9Context *s, vp9_mc_func (*mc)[2], - uint8_t *dst, ptrdiff_t dst_stride, - const uint8_t *ref, ptrdiff_t ref_stride, - ThreadFrame *ref_frame, - ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, - int bw, int bh, int w, int h, int bytesperpixel) -{ - int mx = mv->x, my = mv->y, th; - - y += my >> 3; - x += mx >> 3; - ref += y * ref_stride + x * bytesperpixel; - mx &= 7; - my &= 7; - // FIXME bilinear filter only needs 0/1 pixels, not 3/4 - // we use +7 because the last 7 pixels of each sbrow can be changed in - // the longest loopfilter of the next sbrow - th = (y + bh + 4 * !!my + 7) >> 6; - ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); - // The arm/aarch64 _hv filters read one more row than what actually is - // needed, so switch to emulated edge one pixel sooner vertically - // (!!my * 5) than horizontally (!!mx * 4). - if (x < !!mx * 3 || y < !!my * 3 || - x + !!mx * 4 > w - bw || y + !!my * 5 > h - bh) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, - ref - !!my * 3 * ref_stride - !!mx * 3 * bytesperpixel, - 160, ref_stride, - bw + !!mx * 7, bh + !!my * 7, - x - !!mx * 3, y - !!my * 3, w, h); - ref = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; - ref_stride = 160; - } - mc[!!mx][!!my](dst, dst_stride, ref, ref_stride, bh, mx << 1, my << 1); -} - -static av_always_inline void mc_chroma_unscaled(VP9Context *s, vp9_mc_func (*mc)[2], - uint8_t *dst_u, uint8_t *dst_v, - ptrdiff_t dst_stride, - const uint8_t *ref_u, ptrdiff_t src_stride_u, - const uint8_t *ref_v, ptrdiff_t src_stride_v, - ThreadFrame *ref_frame, - ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, - int bw, int bh, int w, int h, int bytesperpixel) -{ - int mx = mv->x * (1 << !s->ss_h), my = mv->y * (1 << !s->ss_v), th; - - y += my >> 4; - x += mx >> 4; - ref_u += y * src_stride_u + x * bytesperpixel; - ref_v += y * src_stride_v + x * bytesperpixel; - mx &= 15; - my &= 15; - // FIXME bilinear filter only needs 0/1 pixels, not 3/4 - // we use +7 because the last 7 pixels of each sbrow can be changed in - // the longest loopfilter of the next sbrow - th = (y + bh + 4 * !!my + 7) >> (6 - s->ss_v); - ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); - // The arm/aarch64 _hv filters read one more row than what actually is - // needed, so switch to emulated edge one pixel sooner vertically - // (!!my * 5) than horizontally (!!mx * 4). - if (x < !!mx * 3 || y < !!my * 3 || - x + !!mx * 4 > w - bw || y + !!my * 5 > h - bh) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, - ref_u - !!my * 3 * src_stride_u - !!mx * 3 * bytesperpixel, - 160, src_stride_u, - bw + !!mx * 7, bh + !!my * 7, - x - !!mx * 3, y - !!my * 3, w, h); - ref_u = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; - mc[!!mx][!!my](dst_u, dst_stride, ref_u, 160, bh, mx, my); - - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, - ref_v - !!my * 3 * src_stride_v - !!mx * 3 * bytesperpixel, - 160, src_stride_v, - bw + !!mx * 7, bh + !!my * 7, - x - !!mx * 3, y - !!my * 3, w, h); - ref_v = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; - mc[!!mx][!!my](dst_v, dst_stride, ref_v, 160, bh, mx, my); - } else { - mc[!!mx][!!my](dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my); - mc[!!mx][!!my](dst_v, dst_stride, ref_v, src_stride_v, bh, mx, my); - } -} - -#define mc_luma_dir(s, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ - px, py, pw, ph, bw, bh, w, h, i) \ - mc_luma_unscaled(s, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ - mv, bw, bh, w, h, bytesperpixel) -#define mc_chroma_dir(s, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ - row, col, mv, px, py, pw, ph, bw, bh, w, h, i) \ - mc_chroma_unscaled(s, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ - row, col, mv, bw, bh, w, h, bytesperpixel) -#define SCALED 0 -#define FN(x) x##_8bpp -#define BYTES_PER_PIXEL 1 -#include "vp9_mc_template.c" -#undef FN -#undef BYTES_PER_PIXEL -#define FN(x) x##_16bpp -#define BYTES_PER_PIXEL 2 -#include "vp9_mc_template.c" -#undef mc_luma_dir -#undef mc_chroma_dir -#undef FN -#undef BYTES_PER_PIXEL -#undef SCALED - -static av_always_inline void mc_luma_scaled(VP9Context *s, vp9_scaled_mc_func smc, - vp9_mc_func (*mc)[2], - uint8_t *dst, ptrdiff_t dst_stride, - const uint8_t *ref, ptrdiff_t ref_stride, - ThreadFrame *ref_frame, - ptrdiff_t y, ptrdiff_t x, const VP56mv *in_mv, - int px, int py, int pw, int ph, - int bw, int bh, int w, int h, int bytesperpixel, - const uint16_t *scale, const uint8_t *step) -{ - if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width && - s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) { - mc_luma_unscaled(s, mc, dst, dst_stride, ref, ref_stride, ref_frame, - y, x, in_mv, bw, bh, w, h, bytesperpixel); - } else { -#define scale_mv(n, dim) (((int64_t)(n) * scale[dim]) >> 14) - int mx, my; - int refbw_m1, refbh_m1; - int th; - VP56mv mv; - - mv.x = av_clip(in_mv->x, -(x + pw - px + 4) * 8, (s->cols * 8 - x + px + 3) * 8); - mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 8, (s->rows * 8 - y + py + 3) * 8); - // BUG libvpx seems to scale the two components separately. This introduces - // rounding errors but we have to reproduce them to be exactly compatible - // with the output from libvpx... - mx = scale_mv(mv.x * 2, 0) + scale_mv(x * 16, 0); - my = scale_mv(mv.y * 2, 1) + scale_mv(y * 16, 1); - - y = my >> 4; - x = mx >> 4; - ref += y * ref_stride + x * bytesperpixel; - mx &= 15; - my &= 15; - refbw_m1 = ((bw - 1) * step[0] + mx) >> 4; - refbh_m1 = ((bh - 1) * step[1] + my) >> 4; - // FIXME bilinear filter only needs 0/1 pixels, not 3/4 - // we use +7 because the last 7 pixels of each sbrow can be changed in - // the longest loopfilter of the next sbrow - th = (y + refbh_m1 + 4 + 7) >> 6; - ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); - // The arm/aarch64 _hv filters read one more row than what actually is - // needed, so switch to emulated edge one pixel sooner vertically - // (y + 5 >= h - refbh_m1) than horizontally (x + 4 >= w - refbw_m1). - if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 5 >= h - refbh_m1) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, - ref - 3 * ref_stride - 3 * bytesperpixel, - 288, ref_stride, - refbw_m1 + 8, refbh_m1 + 8, - x - 3, y - 3, w, h); - ref = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; - ref_stride = 288; - } - smc(dst, dst_stride, ref, ref_stride, bh, mx, my, step[0], step[1]); - } -} - -static av_always_inline void mc_chroma_scaled(VP9Context *s, vp9_scaled_mc_func smc, - vp9_mc_func (*mc)[2], - uint8_t *dst_u, uint8_t *dst_v, - ptrdiff_t dst_stride, - const uint8_t *ref_u, ptrdiff_t src_stride_u, - const uint8_t *ref_v, ptrdiff_t src_stride_v, - ThreadFrame *ref_frame, - ptrdiff_t y, ptrdiff_t x, const VP56mv *in_mv, - int px, int py, int pw, int ph, - int bw, int bh, int w, int h, int bytesperpixel, - const uint16_t *scale, const uint8_t *step) -{ - if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width && - s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) { - mc_chroma_unscaled(s, mc, dst_u, dst_v, dst_stride, ref_u, src_stride_u, - ref_v, src_stride_v, ref_frame, - y, x, in_mv, bw, bh, w, h, bytesperpixel); - } else { - int mx, my; - int refbw_m1, refbh_m1; - int th; - VP56mv mv; - - if (s->ss_h) { - // BUG https://code.google.com/p/webm/issues/detail?id=820 - mv.x = av_clip(in_mv->x, -(x + pw - px + 4) * 16, (s->cols * 4 - x + px + 3) * 16); - mx = scale_mv(mv.x, 0) + (scale_mv(x * 16, 0) & ~15) + (scale_mv(x * 32, 0) & 15); - } else { - mv.x = av_clip(in_mv->x, -(x + pw - px + 4) * 8, (s->cols * 8 - x + px + 3) * 8); - mx = scale_mv(mv.x * 2, 0) + scale_mv(x * 16, 0); - } - if (s->ss_v) { - // BUG https://code.google.com/p/webm/issues/detail?id=820 - mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 16, (s->rows * 4 - y + py + 3) * 16); - my = scale_mv(mv.y, 1) + (scale_mv(y * 16, 1) & ~15) + (scale_mv(y * 32, 1) & 15); - } else { - mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 8, (s->rows * 8 - y + py + 3) * 8); - my = scale_mv(mv.y * 2, 1) + scale_mv(y * 16, 1); - } -#undef scale_mv - y = my >> 4; - x = mx >> 4; - ref_u += y * src_stride_u + x * bytesperpixel; - ref_v += y * src_stride_v + x * bytesperpixel; - mx &= 15; - my &= 15; - refbw_m1 = ((bw - 1) * step[0] + mx) >> 4; - refbh_m1 = ((bh - 1) * step[1] + my) >> 4; - // FIXME bilinear filter only needs 0/1 pixels, not 3/4 - // we use +7 because the last 7 pixels of each sbrow can be changed in - // the longest loopfilter of the next sbrow - th = (y + refbh_m1 + 4 + 7) >> (6 - s->ss_v); - ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); - // The arm/aarch64 _hv filters read one more row than what actually is - // needed, so switch to emulated edge one pixel sooner vertically - // (y + 5 >= h - refbh_m1) than horizontally (x + 4 >= w - refbw_m1). - if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 5 >= h - refbh_m1) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, - ref_u - 3 * src_stride_u - 3 * bytesperpixel, - 288, src_stride_u, - refbw_m1 + 8, refbh_m1 + 8, - x - 3, y - 3, w, h); - ref_u = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; - smc(dst_u, dst_stride, ref_u, 288, bh, mx, my, step[0], step[1]); - - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, - ref_v - 3 * src_stride_v - 3 * bytesperpixel, - 288, src_stride_v, - refbw_m1 + 8, refbh_m1 + 8, - x - 3, y - 3, w, h); - ref_v = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; - smc(dst_v, dst_stride, ref_v, 288, bh, mx, my, step[0], step[1]); - } else { - smc(dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my, step[0], step[1]); - smc(dst_v, dst_stride, ref_v, src_stride_v, bh, mx, my, step[0], step[1]); - } - } -} - -#define mc_luma_dir(s, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ - px, py, pw, ph, bw, bh, w, h, i) \ - mc_luma_scaled(s, s->dsp.s##mc, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ - mv, px, py, pw, ph, bw, bh, w, h, bytesperpixel, \ - s->mvscale[b->ref[i]], s->mvstep[b->ref[i]]) -#define mc_chroma_dir(s, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ - row, col, mv, px, py, pw, ph, bw, bh, w, h, i) \ - mc_chroma_scaled(s, s->dsp.s##mc, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ - row, col, mv, px, py, pw, ph, bw, bh, w, h, bytesperpixel, \ - s->mvscale[b->ref[i]], s->mvstep[b->ref[i]]) -#define SCALED 1 -#define FN(x) x##_scaled_8bpp -#define BYTES_PER_PIXEL 1 -#include "vp9_mc_template.c" -#undef FN -#undef BYTES_PER_PIXEL -#define FN(x) x##_scaled_16bpp -#define BYTES_PER_PIXEL 2 -#include "vp9_mc_template.c" -#undef mc_luma_dir -#undef mc_chroma_dir -#undef FN -#undef BYTES_PER_PIXEL -#undef SCALED - -static av_always_inline void inter_recon(AVCodecContext *avctx, int bytesperpixel) -{ - VP9Context *s = avctx->priv_data; - VP9Block *b = s->b; - int row = s->row, col = s->col; - - if (s->mvscale[b->ref[0]][0] || (b->comp && s->mvscale[b->ref[1]][0])) { - if (bytesperpixel == 1) { - inter_pred_scaled_8bpp(avctx); - } else { - inter_pred_scaled_16bpp(avctx); - } - } else { - if (bytesperpixel == 1) { - inter_pred_8bpp(avctx); - } else { - inter_pred_16bpp(avctx); - } - } - - if (!b->skip) { - /* mostly copied intra_recon() */ - - int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n; - int h4 = bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2); - int end_x = FFMIN(2 * (s->cols - col), w4); - int end_y = FFMIN(2 * (s->rows - row), h4); - int tx = 4 * s->s.h.lossless + b->tx, uvtx = b->uvtx + 4 * s->s.h.lossless; - int uvstep1d = 1 << b->uvtx, p; - uint8_t *dst = s->dst[0]; - - // y itxfm add - for (n = 0, y = 0; y < end_y; y += step1d) { - uint8_t *ptr = dst; - for (x = 0; x < end_x; x += step1d, - ptr += 4 * step1d * bytesperpixel, n += step) { - int eob = b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n]; - - if (eob) - s->dsp.itxfm_add[tx][DCT_DCT](ptr, s->y_stride, - s->block + 16 * n * bytesperpixel, eob); - } - dst += 4 * s->y_stride * step1d; - } - - // uv itxfm add - end_x >>= s->ss_h; - end_y >>= s->ss_v; - step = 1 << (b->uvtx * 2); - for (p = 0; p < 2; p++) { - dst = s->dst[p + 1]; - for (n = 0, y = 0; y < end_y; y += uvstep1d) { - uint8_t *ptr = dst; - for (x = 0; x < end_x; x += uvstep1d, - ptr += 4 * uvstep1d * bytesperpixel, n += step) { - int eob = b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n]; - - if (eob) - s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride, - s->uvblock[p] + 16 * n * bytesperpixel, eob); - } - dst += 4 * uvstep1d * s->uv_stride; - } - } - } -} - -static void inter_recon_8bpp(AVCodecContext *avctx) -{ - inter_recon(avctx, 1); -} - -static void inter_recon_16bpp(AVCodecContext *avctx) -{ - inter_recon(avctx, 2); -} - static av_always_inline void mask_edges(uint8_t (*mask)[8][4], int ss_h, int ss_v, int row_and_7, int col_and_7, int w, int h, int col_end, int row_end, @@ -1891,7 +1272,7 @@ void ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, VP9Block *b = s->b; enum BlockSize bs = bl * 3 + bp; int bytesperpixel = s->bytesperpixel; - int w4 = bwh_tab[1][bs][0], h4 = bwh_tab[1][bs][1], lvl; + int w4 = ff_vp9_bwh_tab[1][bs][0], h4 = ff_vp9_bwh_tab[1][bs][1], lvl; int emu[2]; AVFrame *f = s->s.frames[CUR_FRAME].tf.f; @@ -2001,15 +1382,15 @@ void ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, } if (b->intra) { if (s->s.h.bpp > 8) { - intra_recon_16bpp(avctx, yoff, uvoff); + ff_vp9_intra_recon_16bpp(avctx, yoff, uvoff); } else { - intra_recon_8bpp(avctx, yoff, uvoff); + ff_vp9_intra_recon_8bpp(avctx, yoff, uvoff); } } else { if (s->s.h.bpp > 8) { - inter_recon_16bpp(avctx); + ff_vp9_inter_recon_16bpp(avctx); } else { - inter_recon_8bpp(avctx); + ff_vp9_inter_recon_8bpp(avctx); } } if (emu[0]) { diff --git a/libavcodec/vp9data.c b/libavcodec/vp9data.c index 4057c736963bf..7af8a97b1e442 100644 --- a/libavcodec/vp9data.c +++ b/libavcodec/vp9data.c @@ -22,6 +22,16 @@ #include "vp9.h" #include "vp9data.h" +const uint8_t ff_vp9_bwh_tab[2][N_BS_SIZES][2] = { + { + { 16, 16 }, { 16, 8 }, { 8, 16 }, { 8, 8 }, { 8, 4 }, { 4, 8 }, + { 4, 4 }, { 4, 2 }, { 2, 4 }, { 2, 2 }, { 2, 1 }, { 1, 2 }, { 1, 1 }, + }, { + { 8, 8 }, { 8, 4 }, { 4, 8 }, { 4, 4 }, { 4, 2 }, { 2, 4 }, + { 2, 2 }, { 2, 1 }, { 1, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, + } +}; + const int8_t ff_vp9_partition_tree[3][2] = { { -PARTITION_NONE, 1 }, // '0' { -PARTITION_H, 2 }, // '10' diff --git a/libavcodec/vp9data.h b/libavcodec/vp9data.h index f27ab0b267a8d..086dbdec06dd8 100644 --- a/libavcodec/vp9data.h +++ b/libavcodec/vp9data.h @@ -26,6 +26,7 @@ #include "vp9dec.h" +extern const uint8_t ff_vp9_bwh_tab[2][N_BS_SIZES][2]; extern const int8_t ff_vp9_partition_tree[3][2]; extern const uint8_t ff_vp9_default_kf_partition_probs[4][4][3]; extern const int8_t ff_vp9_segmentation_tree[7][2]; diff --git a/libavcodec/vp9dec.h b/libavcodec/vp9dec.h index 1f3348adb1b7f..f05e478a4aca2 100644 --- a/libavcodec/vp9dec.h +++ b/libavcodec/vp9dec.h @@ -206,4 +206,11 @@ void ff_vp9_decode_block(AVCodecContext *ctx, int row, int col, void ff_vp9_loopfilter_sb(AVCodecContext *avctx, VP9Filter *lflvl, int row, int col, ptrdiff_t yoff, ptrdiff_t uvoff); +void ff_vp9_intra_recon_8bpp(AVCodecContext *avctx, + ptrdiff_t y_off, ptrdiff_t uv_off); +void ff_vp9_intra_recon_16bpp(AVCodecContext *avctx, + ptrdiff_t y_off, ptrdiff_t uv_off); +void ff_vp9_inter_recon_8bpp(AVCodecContext *avctx); +void ff_vp9_inter_recon_16bpp(AVCodecContext *avctx); + #endif /* AVCODEC_VP9DEC_H */ diff --git a/libavcodec/vp9recon.c b/libavcodec/vp9recon.c new file mode 100644 index 0000000000000..afdb51350c50b --- /dev/null +++ b/libavcodec/vp9recon.c @@ -0,0 +1,639 @@ +/* + * VP9 compatible video decoder + * + * Copyright (C) 2013 Ronald S. Bultje + * Copyright (C) 2013 Clément Bœsch + * + * 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 "libavutil/avassert.h" + +#include "avcodec.h" +#include "internal.h" +#include "videodsp.h" +#include "vp9data.h" +#include "vp9dec.h" + +static av_always_inline int check_intra_mode(VP9Context *s, int mode, uint8_t **a, + uint8_t *dst_edge, ptrdiff_t stride_edge, + uint8_t *dst_inner, ptrdiff_t stride_inner, + uint8_t *l, int col, int x, int w, + int row, int y, enum TxfmMode tx, + int p, int ss_h, int ss_v, int bytesperpixel) +{ + int have_top = row > 0 || y > 0; + int have_left = col > s->tile_col_start || x > 0; + int have_right = x < w - 1; + int bpp = s->s.h.bpp; + static const uint8_t mode_conv[10][2 /* have_left */][2 /* have_top */] = { + [VERT_PRED] = { { DC_127_PRED, VERT_PRED }, + { DC_127_PRED, VERT_PRED } }, + [HOR_PRED] = { { DC_129_PRED, DC_129_PRED }, + { HOR_PRED, HOR_PRED } }, + [DC_PRED] = { { DC_128_PRED, TOP_DC_PRED }, + { LEFT_DC_PRED, DC_PRED } }, + [DIAG_DOWN_LEFT_PRED] = { { DC_127_PRED, DIAG_DOWN_LEFT_PRED }, + { DC_127_PRED, DIAG_DOWN_LEFT_PRED } }, + [DIAG_DOWN_RIGHT_PRED] = { { DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED }, + { DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED } }, + [VERT_RIGHT_PRED] = { { VERT_RIGHT_PRED, VERT_RIGHT_PRED }, + { VERT_RIGHT_PRED, VERT_RIGHT_PRED } }, + [HOR_DOWN_PRED] = { { HOR_DOWN_PRED, HOR_DOWN_PRED }, + { HOR_DOWN_PRED, HOR_DOWN_PRED } }, + [VERT_LEFT_PRED] = { { DC_127_PRED, VERT_LEFT_PRED }, + { DC_127_PRED, VERT_LEFT_PRED } }, + [HOR_UP_PRED] = { { DC_129_PRED, DC_129_PRED }, + { HOR_UP_PRED, HOR_UP_PRED } }, + [TM_VP8_PRED] = { { DC_129_PRED, VERT_PRED }, + { HOR_PRED, TM_VP8_PRED } }, + }; + static const struct { + uint8_t needs_left:1; + uint8_t needs_top:1; + uint8_t needs_topleft:1; + uint8_t needs_topright:1; + uint8_t invert_left:1; + } edges[N_INTRA_PRED_MODES] = { + [VERT_PRED] = { .needs_top = 1 }, + [HOR_PRED] = { .needs_left = 1 }, + [DC_PRED] = { .needs_top = 1, .needs_left = 1 }, + [DIAG_DOWN_LEFT_PRED] = { .needs_top = 1, .needs_topright = 1 }, + [DIAG_DOWN_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1, + .needs_topleft = 1 }, + [VERT_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1, + .needs_topleft = 1 }, + [HOR_DOWN_PRED] = { .needs_left = 1, .needs_top = 1, + .needs_topleft = 1 }, + [VERT_LEFT_PRED] = { .needs_top = 1, .needs_topright = 1 }, + [HOR_UP_PRED] = { .needs_left = 1, .invert_left = 1 }, + [TM_VP8_PRED] = { .needs_left = 1, .needs_top = 1, + .needs_topleft = 1 }, + [LEFT_DC_PRED] = { .needs_left = 1 }, + [TOP_DC_PRED] = { .needs_top = 1 }, + [DC_128_PRED] = { 0 }, + [DC_127_PRED] = { 0 }, + [DC_129_PRED] = { 0 } + }; + + av_assert2(mode >= 0 && mode < 10); + mode = mode_conv[mode][have_left][have_top]; + if (edges[mode].needs_top) { + uint8_t *top, *topleft; + int n_px_need = 4 << tx, n_px_have = (((s->cols - col) << !ss_h) - x) * 4; + int n_px_need_tr = 0; + + if (tx == TX_4X4 && edges[mode].needs_topright && have_right) + n_px_need_tr = 4; + + // if top of sb64-row, use s->intra_pred_data[] instead of + // dst[-stride] for intra prediction (it contains pre- instead of + // post-loopfilter data) + if (have_top) { + top = !(row & 7) && !y ? + s->intra_pred_data[p] + (col * (8 >> ss_h) + x * 4) * bytesperpixel : + y == 0 ? &dst_edge[-stride_edge] : &dst_inner[-stride_inner]; + if (have_left) + topleft = !(row & 7) && !y ? + s->intra_pred_data[p] + (col * (8 >> ss_h) + x * 4) * bytesperpixel : + y == 0 || x == 0 ? &dst_edge[-stride_edge] : + &dst_inner[-stride_inner]; + } + + if (have_top && + (!edges[mode].needs_topleft || (have_left && top == topleft)) && + (tx != TX_4X4 || !edges[mode].needs_topright || have_right) && + n_px_need + n_px_need_tr <= n_px_have) { + *a = top; + } else { + if (have_top) { + if (n_px_need <= n_px_have) { + memcpy(*a, top, n_px_need * bytesperpixel); + } else { +#define memset_bpp(c, i1, v, i2, num) do { \ + if (bytesperpixel == 1) { \ + memset(&(c)[(i1)], (v)[(i2)], (num)); \ + } else { \ + int n, val = AV_RN16A(&(v)[(i2) * 2]); \ + for (n = 0; n < (num); n++) { \ + AV_WN16A(&(c)[((i1) + n) * 2], val); \ + } \ + } \ +} while (0) + memcpy(*a, top, n_px_have * bytesperpixel); + memset_bpp(*a, n_px_have, (*a), n_px_have - 1, n_px_need - n_px_have); + } + } else { +#define memset_val(c, val, num) do { \ + if (bytesperpixel == 1) { \ + memset((c), (val), (num)); \ + } else { \ + int n; \ + for (n = 0; n < (num); n++) { \ + AV_WN16A(&(c)[n * 2], (val)); \ + } \ + } \ +} while (0) + memset_val(*a, (128 << (bpp - 8)) - 1, n_px_need); + } + if (edges[mode].needs_topleft) { + if (have_left && have_top) { +#define assign_bpp(c, i1, v, i2) do { \ + if (bytesperpixel == 1) { \ + (c)[(i1)] = (v)[(i2)]; \ + } else { \ + AV_COPY16(&(c)[(i1) * 2], &(v)[(i2) * 2]); \ + } \ +} while (0) + assign_bpp(*a, -1, topleft, -1); + } else { +#define assign_val(c, i, v) do { \ + if (bytesperpixel == 1) { \ + (c)[(i)] = (v); \ + } else { \ + AV_WN16A(&(c)[(i) * 2], (v)); \ + } \ +} while (0) + assign_val((*a), -1, (128 << (bpp - 8)) + (have_top ? +1 : -1)); + } + } + if (tx == TX_4X4 && edges[mode].needs_topright) { + if (have_top && have_right && + n_px_need + n_px_need_tr <= n_px_have) { + memcpy(&(*a)[4 * bytesperpixel], &top[4 * bytesperpixel], 4 * bytesperpixel); + } else { + memset_bpp(*a, 4, *a, 3, 4); + } + } + } + } + if (edges[mode].needs_left) { + if (have_left) { + int n_px_need = 4 << tx, i, n_px_have = (((s->rows - row) << !ss_v) - y) * 4; + uint8_t *dst = x == 0 ? dst_edge : dst_inner; + ptrdiff_t stride = x == 0 ? stride_edge : stride_inner; + + if (edges[mode].invert_left) { + if (n_px_need <= n_px_have) { + for (i = 0; i < n_px_need; i++) + assign_bpp(l, i, &dst[i * stride], -1); + } else { + for (i = 0; i < n_px_have; i++) + assign_bpp(l, i, &dst[i * stride], -1); + memset_bpp(l, n_px_have, l, n_px_have - 1, n_px_need - n_px_have); + } + } else { + if (n_px_need <= n_px_have) { + for (i = 0; i < n_px_need; i++) + assign_bpp(l, n_px_need - 1 - i, &dst[i * stride], -1); + } else { + for (i = 0; i < n_px_have; i++) + assign_bpp(l, n_px_need - 1 - i, &dst[i * stride], -1); + memset_bpp(l, 0, l, n_px_need - n_px_have, n_px_need - n_px_have); + } + } + } else { + memset_val(l, (128 << (bpp - 8)) + 1, 4 << tx); + } + } + + return mode; +} + +static av_always_inline void intra_recon(AVCodecContext *avctx, ptrdiff_t y_off, + ptrdiff_t uv_off, int bytesperpixel) +{ + VP9Context *s = avctx->priv_data; + VP9Block *b = s->b; + int row = s->row, col = s->col; + int w4 = ff_vp9_bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n; + int h4 = ff_vp9_bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2); + int end_x = FFMIN(2 * (s->cols - col), w4); + int end_y = FFMIN(2 * (s->rows - row), h4); + int tx = 4 * s->s.h.lossless + b->tx, uvtx = b->uvtx + 4 * s->s.h.lossless; + int uvstep1d = 1 << b->uvtx, p; + uint8_t *dst = s->dst[0], *dst_r = s->s.frames[CUR_FRAME].tf.f->data[0] + y_off; + LOCAL_ALIGNED_32(uint8_t, a_buf, [96]); + LOCAL_ALIGNED_32(uint8_t, l, [64]); + + for (n = 0, y = 0; y < end_y; y += step1d) { + uint8_t *ptr = dst, *ptr_r = dst_r; + for (x = 0; x < end_x; x += step1d, ptr += 4 * step1d * bytesperpixel, + ptr_r += 4 * step1d * bytesperpixel, n += step) { + int mode = b->mode[b->bs > BS_8x8 && b->tx == TX_4X4 ? + y * 2 + x : 0]; + uint8_t *a = &a_buf[32]; + enum TxfmType txtp = ff_vp9_intra_txfm_type[mode]; + int eob = b->skip ? 0 : b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n]; + + mode = check_intra_mode(s, mode, &a, ptr_r, + s->s.frames[CUR_FRAME].tf.f->linesize[0], + ptr, s->y_stride, l, + col, x, w4, row, y, b->tx, 0, 0, 0, bytesperpixel); + s->dsp.intra_pred[b->tx][mode](ptr, s->y_stride, l, a); + if (eob) + s->dsp.itxfm_add[tx][txtp](ptr, s->y_stride, + s->block + 16 * n * bytesperpixel, eob); + } + dst_r += 4 * step1d * s->s.frames[CUR_FRAME].tf.f->linesize[0]; + dst += 4 * step1d * s->y_stride; + } + + // U/V + w4 >>= s->ss_h; + end_x >>= s->ss_h; + end_y >>= s->ss_v; + step = 1 << (b->uvtx * 2); + for (p = 0; p < 2; p++) { + dst = s->dst[1 + p]; + dst_r = s->s.frames[CUR_FRAME].tf.f->data[1 + p] + uv_off; + for (n = 0, y = 0; y < end_y; y += uvstep1d) { + uint8_t *ptr = dst, *ptr_r = dst_r; + for (x = 0; x < end_x; x += uvstep1d, ptr += 4 * uvstep1d * bytesperpixel, + ptr_r += 4 * uvstep1d * bytesperpixel, n += step) { + int mode = b->uvmode; + uint8_t *a = &a_buf[32]; + int eob = b->skip ? 0 : b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n]; + + mode = check_intra_mode(s, mode, &a, ptr_r, + s->s.frames[CUR_FRAME].tf.f->linesize[1], + ptr, s->uv_stride, l, col, x, w4, row, y, + b->uvtx, p + 1, s->ss_h, s->ss_v, bytesperpixel); + s->dsp.intra_pred[b->uvtx][mode](ptr, s->uv_stride, l, a); + if (eob) + s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride, + s->uvblock[p] + 16 * n * bytesperpixel, eob); + } + dst_r += 4 * uvstep1d * s->s.frames[CUR_FRAME].tf.f->linesize[1]; + dst += 4 * uvstep1d * s->uv_stride; + } + } +} + +void ff_vp9_intra_recon_8bpp(AVCodecContext *avctx, ptrdiff_t y_off, ptrdiff_t uv_off) +{ + intra_recon(avctx, y_off, uv_off, 1); +} + +void ff_vp9_intra_recon_16bpp(AVCodecContext *avctx, ptrdiff_t y_off, ptrdiff_t uv_off) +{ + intra_recon(avctx, y_off, uv_off, 2); +} + +static av_always_inline void mc_luma_unscaled(VP9Context *s, vp9_mc_func (*mc)[2], + uint8_t *dst, ptrdiff_t dst_stride, + const uint8_t *ref, ptrdiff_t ref_stride, + ThreadFrame *ref_frame, + ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, + int bw, int bh, int w, int h, int bytesperpixel) +{ + int mx = mv->x, my = mv->y, th; + + y += my >> 3; + x += mx >> 3; + ref += y * ref_stride + x * bytesperpixel; + mx &= 7; + my &= 7; + // FIXME bilinear filter only needs 0/1 pixels, not 3/4 + // we use +7 because the last 7 pixels of each sbrow can be changed in + // the longest loopfilter of the next sbrow + th = (y + bh + 4 * !!my + 7) >> 6; + ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); + // The arm/aarch64 _hv filters read one more row than what actually is + // needed, so switch to emulated edge one pixel sooner vertically + // (!!my * 5) than horizontally (!!mx * 4). + if (x < !!mx * 3 || y < !!my * 3 || + x + !!mx * 4 > w - bw || y + !!my * 5 > h - bh) { + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + ref - !!my * 3 * ref_stride - !!mx * 3 * bytesperpixel, + 160, ref_stride, + bw + !!mx * 7, bh + !!my * 7, + x - !!mx * 3, y - !!my * 3, w, h); + ref = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; + ref_stride = 160; + } + mc[!!mx][!!my](dst, dst_stride, ref, ref_stride, bh, mx << 1, my << 1); +} + +static av_always_inline void mc_chroma_unscaled(VP9Context *s, vp9_mc_func (*mc)[2], + uint8_t *dst_u, uint8_t *dst_v, + ptrdiff_t dst_stride, + const uint8_t *ref_u, ptrdiff_t src_stride_u, + const uint8_t *ref_v, ptrdiff_t src_stride_v, + ThreadFrame *ref_frame, + ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, + int bw, int bh, int w, int h, int bytesperpixel) +{ + int mx = mv->x * (1 << !s->ss_h), my = mv->y * (1 << !s->ss_v), th; + + y += my >> 4; + x += mx >> 4; + ref_u += y * src_stride_u + x * bytesperpixel; + ref_v += y * src_stride_v + x * bytesperpixel; + mx &= 15; + my &= 15; + // FIXME bilinear filter only needs 0/1 pixels, not 3/4 + // we use +7 because the last 7 pixels of each sbrow can be changed in + // the longest loopfilter of the next sbrow + th = (y + bh + 4 * !!my + 7) >> (6 - s->ss_v); + ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); + // The arm/aarch64 _hv filters read one more row than what actually is + // needed, so switch to emulated edge one pixel sooner vertically + // (!!my * 5) than horizontally (!!mx * 4). + if (x < !!mx * 3 || y < !!my * 3 || + x + !!mx * 4 > w - bw || y + !!my * 5 > h - bh) { + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + ref_u - !!my * 3 * src_stride_u - !!mx * 3 * bytesperpixel, + 160, src_stride_u, + bw + !!mx * 7, bh + !!my * 7, + x - !!mx * 3, y - !!my * 3, w, h); + ref_u = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; + mc[!!mx][!!my](dst_u, dst_stride, ref_u, 160, bh, mx, my); + + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + ref_v - !!my * 3 * src_stride_v - !!mx * 3 * bytesperpixel, + 160, src_stride_v, + bw + !!mx * 7, bh + !!my * 7, + x - !!mx * 3, y - !!my * 3, w, h); + ref_v = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; + mc[!!mx][!!my](dst_v, dst_stride, ref_v, 160, bh, mx, my); + } else { + mc[!!mx][!!my](dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my); + mc[!!mx][!!my](dst_v, dst_stride, ref_v, src_stride_v, bh, mx, my); + } +} + +#define mc_luma_dir(s, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ + px, py, pw, ph, bw, bh, w, h, i) \ + mc_luma_unscaled(s, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ + mv, bw, bh, w, h, bytesperpixel) +#define mc_chroma_dir(s, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ + row, col, mv, px, py, pw, ph, bw, bh, w, h, i) \ + mc_chroma_unscaled(s, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ + row, col, mv, bw, bh, w, h, bytesperpixel) +#define SCALED 0 +#define FN(x) x##_8bpp +#define BYTES_PER_PIXEL 1 +#include "vp9_mc_template.c" +#undef FN +#undef BYTES_PER_PIXEL +#define FN(x) x##_16bpp +#define BYTES_PER_PIXEL 2 +#include "vp9_mc_template.c" +#undef mc_luma_dir +#undef mc_chroma_dir +#undef FN +#undef BYTES_PER_PIXEL +#undef SCALED + +static av_always_inline void mc_luma_scaled(VP9Context *s, vp9_scaled_mc_func smc, + vp9_mc_func (*mc)[2], + uint8_t *dst, ptrdiff_t dst_stride, + const uint8_t *ref, ptrdiff_t ref_stride, + ThreadFrame *ref_frame, + ptrdiff_t y, ptrdiff_t x, const VP56mv *in_mv, + int px, int py, int pw, int ph, + int bw, int bh, int w, int h, int bytesperpixel, + const uint16_t *scale, const uint8_t *step) +{ + if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width && + s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) { + mc_luma_unscaled(s, mc, dst, dst_stride, ref, ref_stride, ref_frame, + y, x, in_mv, bw, bh, w, h, bytesperpixel); + } else { +#define scale_mv(n, dim) (((int64_t)(n) * scale[dim]) >> 14) + int mx, my; + int refbw_m1, refbh_m1; + int th; + VP56mv mv; + + mv.x = av_clip(in_mv->x, -(x + pw - px + 4) * 8, (s->cols * 8 - x + px + 3) * 8); + mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 8, (s->rows * 8 - y + py + 3) * 8); + // BUG libvpx seems to scale the two components separately. This introduces + // rounding errors but we have to reproduce them to be exactly compatible + // with the output from libvpx... + mx = scale_mv(mv.x * 2, 0) + scale_mv(x * 16, 0); + my = scale_mv(mv.y * 2, 1) + scale_mv(y * 16, 1); + + y = my >> 4; + x = mx >> 4; + ref += y * ref_stride + x * bytesperpixel; + mx &= 15; + my &= 15; + refbw_m1 = ((bw - 1) * step[0] + mx) >> 4; + refbh_m1 = ((bh - 1) * step[1] + my) >> 4; + // FIXME bilinear filter only needs 0/1 pixels, not 3/4 + // we use +7 because the last 7 pixels of each sbrow can be changed in + // the longest loopfilter of the next sbrow + th = (y + refbh_m1 + 4 + 7) >> 6; + ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); + // The arm/aarch64 _hv filters read one more row than what actually is + // needed, so switch to emulated edge one pixel sooner vertically + // (y + 5 >= h - refbh_m1) than horizontally (x + 4 >= w - refbw_m1). + if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 5 >= h - refbh_m1) { + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + ref - 3 * ref_stride - 3 * bytesperpixel, + 288, ref_stride, + refbw_m1 + 8, refbh_m1 + 8, + x - 3, y - 3, w, h); + ref = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; + ref_stride = 288; + } + smc(dst, dst_stride, ref, ref_stride, bh, mx, my, step[0], step[1]); + } +} + +static av_always_inline void mc_chroma_scaled(VP9Context *s, vp9_scaled_mc_func smc, + vp9_mc_func (*mc)[2], + uint8_t *dst_u, uint8_t *dst_v, + ptrdiff_t dst_stride, + const uint8_t *ref_u, ptrdiff_t src_stride_u, + const uint8_t *ref_v, ptrdiff_t src_stride_v, + ThreadFrame *ref_frame, + ptrdiff_t y, ptrdiff_t x, const VP56mv *in_mv, + int px, int py, int pw, int ph, + int bw, int bh, int w, int h, int bytesperpixel, + const uint16_t *scale, const uint8_t *step) +{ + if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width && + s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) { + mc_chroma_unscaled(s, mc, dst_u, dst_v, dst_stride, ref_u, src_stride_u, + ref_v, src_stride_v, ref_frame, + y, x, in_mv, bw, bh, w, h, bytesperpixel); + } else { + int mx, my; + int refbw_m1, refbh_m1; + int th; + VP56mv mv; + + if (s->ss_h) { + // BUG https://code.google.com/p/webm/issues/detail?id=820 + mv.x = av_clip(in_mv->x, -(x + pw - px + 4) * 16, (s->cols * 4 - x + px + 3) * 16); + mx = scale_mv(mv.x, 0) + (scale_mv(x * 16, 0) & ~15) + (scale_mv(x * 32, 0) & 15); + } else { + mv.x = av_clip(in_mv->x, -(x + pw - px + 4) * 8, (s->cols * 8 - x + px + 3) * 8); + mx = scale_mv(mv.x * 2, 0) + scale_mv(x * 16, 0); + } + if (s->ss_v) { + // BUG https://code.google.com/p/webm/issues/detail?id=820 + mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 16, (s->rows * 4 - y + py + 3) * 16); + my = scale_mv(mv.y, 1) + (scale_mv(y * 16, 1) & ~15) + (scale_mv(y * 32, 1) & 15); + } else { + mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 8, (s->rows * 8 - y + py + 3) * 8); + my = scale_mv(mv.y * 2, 1) + scale_mv(y * 16, 1); + } +#undef scale_mv + y = my >> 4; + x = mx >> 4; + ref_u += y * src_stride_u + x * bytesperpixel; + ref_v += y * src_stride_v + x * bytesperpixel; + mx &= 15; + my &= 15; + refbw_m1 = ((bw - 1) * step[0] + mx) >> 4; + refbh_m1 = ((bh - 1) * step[1] + my) >> 4; + // FIXME bilinear filter only needs 0/1 pixels, not 3/4 + // we use +7 because the last 7 pixels of each sbrow can be changed in + // the longest loopfilter of the next sbrow + th = (y + refbh_m1 + 4 + 7) >> (6 - s->ss_v); + ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); + // The arm/aarch64 _hv filters read one more row than what actually is + // needed, so switch to emulated edge one pixel sooner vertically + // (y + 5 >= h - refbh_m1) than horizontally (x + 4 >= w - refbw_m1). + if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 5 >= h - refbh_m1) { + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + ref_u - 3 * src_stride_u - 3 * bytesperpixel, + 288, src_stride_u, + refbw_m1 + 8, refbh_m1 + 8, + x - 3, y - 3, w, h); + ref_u = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; + smc(dst_u, dst_stride, ref_u, 288, bh, mx, my, step[0], step[1]); + + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + ref_v - 3 * src_stride_v - 3 * bytesperpixel, + 288, src_stride_v, + refbw_m1 + 8, refbh_m1 + 8, + x - 3, y - 3, w, h); + ref_v = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; + smc(dst_v, dst_stride, ref_v, 288, bh, mx, my, step[0], step[1]); + } else { + smc(dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my, step[0], step[1]); + smc(dst_v, dst_stride, ref_v, src_stride_v, bh, mx, my, step[0], step[1]); + } + } +} + +#define mc_luma_dir(s, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ + px, py, pw, ph, bw, bh, w, h, i) \ + mc_luma_scaled(s, s->dsp.s##mc, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ + mv, px, py, pw, ph, bw, bh, w, h, bytesperpixel, \ + s->mvscale[b->ref[i]], s->mvstep[b->ref[i]]) +#define mc_chroma_dir(s, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ + row, col, mv, px, py, pw, ph, bw, bh, w, h, i) \ + mc_chroma_scaled(s, s->dsp.s##mc, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ + row, col, mv, px, py, pw, ph, bw, bh, w, h, bytesperpixel, \ + s->mvscale[b->ref[i]], s->mvstep[b->ref[i]]) +#define SCALED 1 +#define FN(x) x##_scaled_8bpp +#define BYTES_PER_PIXEL 1 +#include "vp9_mc_template.c" +#undef FN +#undef BYTES_PER_PIXEL +#define FN(x) x##_scaled_16bpp +#define BYTES_PER_PIXEL 2 +#include "vp9_mc_template.c" +#undef mc_luma_dir +#undef mc_chroma_dir +#undef FN +#undef BYTES_PER_PIXEL +#undef SCALED + +static av_always_inline void inter_recon(AVCodecContext *avctx, int bytesperpixel) +{ + VP9Context *s = avctx->priv_data; + VP9Block *b = s->b; + int row = s->row, col = s->col; + + if (s->mvscale[b->ref[0]][0] || (b->comp && s->mvscale[b->ref[1]][0])) { + if (bytesperpixel == 1) { + inter_pred_scaled_8bpp(avctx); + } else { + inter_pred_scaled_16bpp(avctx); + } + } else { + if (bytesperpixel == 1) { + inter_pred_8bpp(avctx); + } else { + inter_pred_16bpp(avctx); + } + } + + if (!b->skip) { + /* mostly copied intra_recon() */ + + int w4 = ff_vp9_bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n; + int h4 = ff_vp9_bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2); + int end_x = FFMIN(2 * (s->cols - col), w4); + int end_y = FFMIN(2 * (s->rows - row), h4); + int tx = 4 * s->s.h.lossless + b->tx, uvtx = b->uvtx + 4 * s->s.h.lossless; + int uvstep1d = 1 << b->uvtx, p; + uint8_t *dst = s->dst[0]; + + // y itxfm add + for (n = 0, y = 0; y < end_y; y += step1d) { + uint8_t *ptr = dst; + for (x = 0; x < end_x; x += step1d, + ptr += 4 * step1d * bytesperpixel, n += step) { + int eob = b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n]; + + if (eob) + s->dsp.itxfm_add[tx][DCT_DCT](ptr, s->y_stride, + s->block + 16 * n * bytesperpixel, eob); + } + dst += 4 * s->y_stride * step1d; + } + + // uv itxfm add + end_x >>= s->ss_h; + end_y >>= s->ss_v; + step = 1 << (b->uvtx * 2); + for (p = 0; p < 2; p++) { + dst = s->dst[p + 1]; + for (n = 0, y = 0; y < end_y; y += uvstep1d) { + uint8_t *ptr = dst; + for (x = 0; x < end_x; x += uvstep1d, + ptr += 4 * uvstep1d * bytesperpixel, n += step) { + int eob = b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n]; + + if (eob) + s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride, + s->uvblock[p] + 16 * n * bytesperpixel, eob); + } + dst += 4 * uvstep1d * s->uv_stride; + } + } + } +} + +void ff_vp9_inter_recon_8bpp(AVCodecContext *avctx) +{ + inter_recon(avctx, 1); +} + +void ff_vp9_inter_recon_16bpp(AVCodecContext *avctx) +{ + inter_recon(avctx, 2); +} From 0c466417846f80a134dd7078435829c8e47fcbb0 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 27 Mar 2017 22:05:17 -0400 Subject: [PATCH 1354/3374] vp9: split out generic decoding skeleton interface API from VP9 types. This allows vp9dsp.h to only include the VP9 types header, and not the decoder skeleton interface which is for hardware decoders (dxva2/vaapi). --- .../arm/vp9dsp_init_16bpp_arm_template.c | 1 + libavcodec/arm/vp9dsp_init_arm.c | 1 + libavcodec/dxva2_vp9.c | 2 +- libavcodec/vaapi_vp9.c | 2 +- libavcodec/vp9.h | 145 +-------------- libavcodec/vp9dec.h | 1 + libavcodec/vp9dsp.h | 4 +- libavcodec/vp9shared.h | 169 ++++++++++++++++++ 8 files changed, 178 insertions(+), 147 deletions(-) create mode 100644 libavcodec/vp9shared.h diff --git a/libavcodec/arm/vp9dsp_init_16bpp_arm_template.c b/libavcodec/arm/vp9dsp_init_16bpp_arm_template.c index 3620535065273..1b0007859d341 100644 --- a/libavcodec/arm/vp9dsp_init_16bpp_arm_template.c +++ b/libavcodec/arm/vp9dsp_init_16bpp_arm_template.c @@ -21,6 +21,7 @@ #include #include "libavutil/attributes.h" +#include "libavutil/internal.h" #include "libavutil/arm/cpu.h" #include "vp9dsp_init.h" diff --git a/libavcodec/arm/vp9dsp_init_arm.c b/libavcodec/arm/vp9dsp_init_arm.c index 4c57fd6ba05b5..cb7f48d5cac23 100644 --- a/libavcodec/arm/vp9dsp_init_arm.c +++ b/libavcodec/arm/vp9dsp_init_arm.c @@ -21,6 +21,7 @@ #include #include "libavutil/attributes.h" +#include "libavutil/internal.h" #include "libavutil/arm/cpu.h" #include "libavcodec/vp9dsp.h" #include "vp9dsp_init.h" diff --git a/libavcodec/dxva2_vp9.c b/libavcodec/dxva2_vp9.c index d53b32764a332..fd7bd98afd312 100644 --- a/libavcodec/dxva2_vp9.c +++ b/libavcodec/dxva2_vp9.c @@ -23,7 +23,7 @@ #include "libavutil/avassert.h" #include "libavutil/pixdesc.h" -#include "vp9.h" +#include "vp9shared.h" // The headers above may include w32threads.h, which uses the original // _WIN32_WINNT define, while dxva2_internal.h redefines it to target a diff --git a/libavcodec/vaapi_vp9.c b/libavcodec/vaapi_vp9.c index 7374465d49c92..d8ece75df4fe9 100644 --- a/libavcodec/vaapi_vp9.c +++ b/libavcodec/vaapi_vp9.c @@ -24,7 +24,7 @@ #include "hwaccel.h" #include "vaapi_decode.h" -#include "vp9.h" +#include "vp9shared.h" static VASurfaceID vaapi_vp9_surface_id(const VP9Frame *vf) { diff --git a/libavcodec/vp9.h b/libavcodec/vp9.h index 6d2abaf24ec2a..c8d07ad9860bb 100644 --- a/libavcodec/vp9.h +++ b/libavcodec/vp9.h @@ -24,13 +24,6 @@ #ifndef AVCODEC_VP9_H #define AVCODEC_VP9_H -#include -#include - -#include "avcodec.h" -#include "thread.h" -#include "vp56.h" - enum TxfmMode { TX_4X4, TX_8X8, @@ -73,142 +66,8 @@ enum FilterMode { FILTER_8TAP_REGULAR, FILTER_8TAP_SHARP, FILTER_BILINEAR, - FILTER_SWITCHABLE, -}; - -enum BlockPartition { - PARTITION_NONE, // [ ] <-. - PARTITION_H, // [-] | - PARTITION_V, // [|] | - PARTITION_SPLIT, // [+] --' -}; - -enum InterPredMode { - NEARESTMV = 10, - NEARMV = 11, - ZEROMV = 12, - NEWMV = 13, -}; - -enum CompPredMode { - PRED_SINGLEREF, - PRED_COMPREF, - PRED_SWITCHABLE, + N_FILTERS, + FILTER_SWITCHABLE = N_FILTERS, }; -typedef struct VP9mvrefPair { - VP56mv mv[2]; - int8_t ref[2]; -} VP9mvrefPair; - -typedef struct VP9Frame { - ThreadFrame tf; - AVBufferRef *extradata; - uint8_t *segmentation_map; - VP9mvrefPair *mv; - int uses_2pass; - - AVBufferRef *hwaccel_priv_buf; - void *hwaccel_picture_private; -} VP9Frame; - -enum BlockLevel { - BL_64X64, - BL_32X32, - BL_16X16, - BL_8X8, -}; - -enum BlockSize { - BS_64x64, - BS_64x32, - BS_32x64, - BS_32x32, - BS_32x16, - BS_16x32, - BS_16x16, - BS_16x8, - BS_8x16, - BS_8x8, - BS_8x4, - BS_4x8, - BS_4x4, - N_BS_SIZES, -}; - -typedef struct VP9BitstreamHeader { - // bitstream header - uint8_t profile; - uint8_t bpp; - uint8_t keyframe; - uint8_t invisible; - uint8_t errorres; - uint8_t intraonly; - uint8_t resetctx; - uint8_t refreshrefmask; - uint8_t highprecisionmvs; - enum FilterMode filtermode; - uint8_t allowcompinter; - uint8_t refreshctx; - uint8_t parallelmode; - uint8_t framectxid; - uint8_t use_last_frame_mvs; - uint8_t refidx[3]; - uint8_t signbias[3]; - uint8_t fixcompref; - uint8_t varcompref[2]; - struct { - uint8_t level; - int8_t sharpness; - } filter; - struct { - uint8_t enabled; - uint8_t updated; - int8_t mode[2]; - int8_t ref[4]; - } lf_delta; - uint8_t yac_qi; - int8_t ydc_qdelta, uvdc_qdelta, uvac_qdelta; - uint8_t lossless; -#define MAX_SEGMENT 8 - struct { - uint8_t enabled; - uint8_t temporal; - uint8_t absolute_vals; - uint8_t update_map; - uint8_t prob[7]; - uint8_t pred_prob[3]; - struct { - uint8_t q_enabled; - uint8_t lf_enabled; - uint8_t ref_enabled; - uint8_t skip_enabled; - uint8_t ref_val; - int16_t q_val; - int8_t lf_val; - int16_t qmul[2][2]; - uint8_t lflvl[4][2]; - } feat[MAX_SEGMENT]; - } segmentation; - enum TxfmMode txfmmode; - enum CompPredMode comppredmode; - struct { - unsigned log2_tile_cols, log2_tile_rows; - unsigned tile_cols, tile_rows; - } tiling; - - int uncompressed_header_size; - int compressed_header_size; -} VP9BitstreamHeader; - -typedef struct VP9SharedContext { - VP9BitstreamHeader h; - - ThreadFrame refs[8]; -#define CUR_FRAME 0 -#define REF_FRAME_MVPAIR 1 -#define REF_FRAME_SEGMAP 2 - VP9Frame frames[3]; -} VP9SharedContext; - #endif /* AVCODEC_VP9_H */ diff --git a/libavcodec/vp9dec.h b/libavcodec/vp9dec.h index f05e478a4aca2..4002b3a694588 100644 --- a/libavcodec/vp9dec.h +++ b/libavcodec/vp9dec.h @@ -32,6 +32,7 @@ #include "vp9.h" #include "vp9dsp.h" +#include "vp9shared.h" enum MVJoint { MV_JOINT_ZERO, diff --git a/libavcodec/vp9dsp.h b/libavcodec/vp9dsp.h index d2c48b4d1ba57..e2256316a8f58 100644 --- a/libavcodec/vp9dsp.h +++ b/libavcodec/vp9dsp.h @@ -111,13 +111,13 @@ typedef struct VP9DSPContext { * * dst/stride are aligned by hsize */ - vp9_mc_func mc[5][4][2][2][2]; + vp9_mc_func mc[5][N_FILTERS][2][2][2]; /* * for scalable MC, first 3 dimensions identical to above, the other two * don't exist since it changes per stepsize. */ - vp9_scaled_mc_func smc[5][4][2]; + vp9_scaled_mc_func smc[5][N_FILTERS][2]; } VP9DSPContext; extern const int16_t ff_vp9_subpel_filters[3][16][8]; diff --git a/libavcodec/vp9shared.h b/libavcodec/vp9shared.h new file mode 100644 index 0000000000000..54726df742f90 --- /dev/null +++ b/libavcodec/vp9shared.h @@ -0,0 +1,169 @@ +/* + * VP9 compatible video decoder + * + * Copyright (C) 2013 Ronald S. Bultje + * Copyright (C) 2013 Clément Bœsch + * + * 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 + */ + +#ifndef AVCODEC_VP9SHARED_H +#define AVCODEC_VP9SHARED_H + +#include +#include + +#include "vp9.h" +#include "thread.h" +#include "vp56.h" + +enum BlockPartition { + PARTITION_NONE, // [ ] <-. + PARTITION_H, // [-] | + PARTITION_V, // [|] | + PARTITION_SPLIT, // [+] --' +}; + +enum InterPredMode { + NEARESTMV = 10, + NEARMV = 11, + ZEROMV = 12, + NEWMV = 13, +}; + +enum CompPredMode { + PRED_SINGLEREF, + PRED_COMPREF, + PRED_SWITCHABLE, +}; + +typedef struct VP9mvrefPair { + VP56mv mv[2]; + int8_t ref[2]; +} VP9mvrefPair; + +typedef struct VP9Frame { + ThreadFrame tf; + AVBufferRef *extradata; + uint8_t *segmentation_map; + VP9mvrefPair *mv; + int uses_2pass; + + AVBufferRef *hwaccel_priv_buf; + void *hwaccel_picture_private; +} VP9Frame; + +enum BlockLevel { + BL_64X64, + BL_32X32, + BL_16X16, + BL_8X8, +}; + +enum BlockSize { + BS_64x64, + BS_64x32, + BS_32x64, + BS_32x32, + BS_32x16, + BS_16x32, + BS_16x16, + BS_16x8, + BS_8x16, + BS_8x8, + BS_8x4, + BS_4x8, + BS_4x4, + N_BS_SIZES, +}; + +typedef struct VP9BitstreamHeader { + // bitstream header + uint8_t profile; + uint8_t bpp; + uint8_t keyframe; + uint8_t invisible; + uint8_t errorres; + uint8_t intraonly; + uint8_t resetctx; + uint8_t refreshrefmask; + uint8_t highprecisionmvs; + enum FilterMode filtermode; + uint8_t allowcompinter; + uint8_t refreshctx; + uint8_t parallelmode; + uint8_t framectxid; + uint8_t use_last_frame_mvs; + uint8_t refidx[3]; + uint8_t signbias[3]; + uint8_t fixcompref; + uint8_t varcompref[2]; + struct { + uint8_t level; + int8_t sharpness; + } filter; + struct { + uint8_t enabled; + uint8_t updated; + int8_t mode[2]; + int8_t ref[4]; + } lf_delta; + uint8_t yac_qi; + int8_t ydc_qdelta, uvdc_qdelta, uvac_qdelta; + uint8_t lossless; +#define MAX_SEGMENT 8 + struct { + uint8_t enabled; + uint8_t temporal; + uint8_t absolute_vals; + uint8_t update_map; + uint8_t prob[7]; + uint8_t pred_prob[3]; + struct { + uint8_t q_enabled; + uint8_t lf_enabled; + uint8_t ref_enabled; + uint8_t skip_enabled; + uint8_t ref_val; + int16_t q_val; + int8_t lf_val; + int16_t qmul[2][2]; + uint8_t lflvl[4][2]; + } feat[MAX_SEGMENT]; + } segmentation; + enum TxfmMode txfmmode; + enum CompPredMode comppredmode; + struct { + unsigned log2_tile_cols, log2_tile_rows; + unsigned tile_cols, tile_rows; + } tiling; + + int uncompressed_header_size; + int compressed_header_size; +} VP9BitstreamHeader; + +typedef struct VP9SharedContext { + VP9BitstreamHeader h; + + ThreadFrame refs[8]; +#define CUR_FRAME 0 +#define REF_FRAME_MVPAIR 1 +#define REF_FRAME_SEGMAP 2 + VP9Frame frames[3]; +} VP9SharedContext; + +#endif /* AVCODEC_VP9SHARED_H */ From 8c2aa45d4a99dc0d9990dfb56782487006f718c3 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 27 Mar 2017 09:39:24 -0400 Subject: [PATCH 1355/3374] h264: revert 1189af429211ac650aac730368a6cf5b23756605. The patch introduces race conditions. --- libavcodec/h264_slice.c | 3 --- libavcodec/h264dec.c | 24 ------------------------ libavcodec/h264dec.h | 8 -------- 3 files changed, 35 deletions(-) diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index a7038538720d8..fa1e9ae829cf2 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -383,9 +383,6 @@ int ff_h264_update_thread_context(AVCodecContext *dst, h->picture_structure = h1->picture_structure; h->mb_aff_frame = h1->mb_aff_frame; h->droppable = h1->droppable; - h->backup_width = h1->backup_width; - h->backup_height = h1->backup_height; - h->backup_pix_fmt = h1->backup_pix_fmt; for (i = 0; i < H264_MAX_PICTURE_COUNT; i++) { ff_h264_unref_picture(h, &h->DPB[i]); diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 585ce86f37339..25aeba7d71a0d 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -307,9 +307,6 @@ static int h264_init_context(AVCodecContext *avctx, H264Context *h) int i; h->avctx = avctx; - h->backup_width = -1; - h->backup_height = -1; - h->backup_pix_fmt = AV_PIX_FMT_NONE; h->cur_chroma_format_idc = -1; h->picture_structure = PICT_FRAME; @@ -861,14 +858,6 @@ static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp) av_dict_set(&dst->metadata, "stereo_mode", ff_h264_sei_stereo_mode(&h->sei.frame_packing), 0); - h->backup_width = h->avctx->width; - h->backup_height = h->avctx->height; - h->backup_pix_fmt = h->avctx->pix_fmt; - - h->avctx->width = dst->width; - h->avctx->height = dst->height; - h->avctx->pix_fmt = dst->format; - if (srcp->sei_recovery_frame_cnt == 0) dst->key_frame = 1; if (!srcp->crop) @@ -1003,19 +992,6 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data, h->setup_finished = 0; h->nb_slice_ctx_queued = 0; - if (h->backup_width != -1) { - avctx->width = h->backup_width; - h->backup_width = -1; - } - if (h->backup_height != -1) { - avctx->height = h->backup_height; - h->backup_height = -1; - } - if (h->backup_pix_fmt != AV_PIX_FMT_NONE) { - avctx->pix_fmt = h->backup_pix_fmt; - h->backup_pix_fmt = AV_PIX_FMT_NONE; - } - ff_h264_unref_picture(h, &h->last_pic_for_ec); /* end of stream, output what is still in the buffers */ diff --git a/libavcodec/h264dec.h b/libavcodec/h264dec.h index 5f868b76cb635..e994f7e7fe88d 100644 --- a/libavcodec/h264dec.h +++ b/libavcodec/h264dec.h @@ -363,14 +363,6 @@ typedef struct H264Context { int width, height; int chroma_x_shift, chroma_y_shift; - /** - * Backup frame properties: needed, because they can be different - * between returned frame and last decoded frame. - **/ - int backup_width; - int backup_height; - enum AVPixelFormat backup_pix_fmt; - int droppable; int coded_picture_number; From bddabfaab65808e40605181d579ffcd85bfe4c26 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 27 Mar 2017 09:56:38 -0400 Subject: [PATCH 1356/3374] hevc: initialize no_rasl_output_flag in hevc_frame_start(). This prevents a race condition in files with multiple slices per frame. --- libavcodec/hevcdec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 98ed2a022b2d0..ef21595c4436c 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -826,8 +826,6 @@ static int hls_slice_header(HEVCContext *s) s->HEVClc->tu.cu_qp_offset_cb = 0; s->HEVClc->tu.cu_qp_offset_cr = 0; - s->no_rasl_output_flag = IS_IDR(s) || IS_BLA(s) || (s->nal_unit_type == HEVC_NAL_CRA_NUT && s->last_eos); - return 0; } @@ -2677,6 +2675,8 @@ static int hevc_frame_start(HEVCContext *s) s->is_decoded = 0; s->first_nal_type = s->nal_unit_type; + s->no_rasl_output_flag = IS_IDR(s) || IS_BLA(s) || (s->nal_unit_type == HEVC_NAL_CRA_NUT && s->last_eos); + if (s->ps.pps->tiles_enabled_flag) lc->end_of_tiles_x = s->ps.pps->column_width[0] << s->ps.sps->log2_ctb_size; From 027ee9b3ed697ff080be0f14b47a11c89ce68cdd Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 28 Mar 2017 15:04:46 -0400 Subject: [PATCH 1357/3374] pthread_frame: don't sync items between threads for intra-only codecs. Intra-only codecs should either be able to read these items from the bitstream, or they should be set upon codec initialization. In both cases, syncing these items at runtime is unnecessary. In practice, this fixes race conditions for decoders that read these values from the bitstream. --- libavcodec/pthread_frame.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index b618be0bf538e..295763a76de9f 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -244,7 +244,7 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, { int err = 0; - if (dst != src) { + if (dst != src && (for_user || !(av_codec_get_codec_descriptor(src)->props & AV_CODEC_PROP_INTRA_ONLY))) { dst->time_base = src->time_base; dst->framerate = src->framerate; dst->width = src->width; From c31cbeef584f818884916722b8426b70f47a581a Mon Sep 17 00:00:00 2001 From: James Almer Date: Tue, 28 Mar 2017 23:02:09 -0300 Subject: [PATCH 1358/3374] aarch64/vp9dsp: add missing header includes --- libavcodec/aarch64/vp9dsp_init_16bpp_aarch64_template.c | 1 + libavcodec/aarch64/vp9dsp_init_aarch64.c | 1 + 2 files changed, 2 insertions(+) diff --git a/libavcodec/aarch64/vp9dsp_init_16bpp_aarch64_template.c b/libavcodec/aarch64/vp9dsp_init_16bpp_aarch64_template.c index d5649f781d148..8dcfdeaaf7caf 100644 --- a/libavcodec/aarch64/vp9dsp_init_16bpp_aarch64_template.c +++ b/libavcodec/aarch64/vp9dsp_init_16bpp_aarch64_template.c @@ -21,6 +21,7 @@ #include #include "libavutil/attributes.h" +#include "libavutil/internal.h" #include "libavutil/aarch64/cpu.h" #include "vp9dsp_init.h" diff --git a/libavcodec/aarch64/vp9dsp_init_aarch64.c b/libavcodec/aarch64/vp9dsp_init_aarch64.c index 91a82d822df77..4c699759fe87f 100644 --- a/libavcodec/aarch64/vp9dsp_init_aarch64.c +++ b/libavcodec/aarch64/vp9dsp_init_aarch64.c @@ -21,6 +21,7 @@ #include #include "libavutil/attributes.h" +#include "libavutil/internal.h" #include "libavutil/aarch64/cpu.h" #include "libavcodec/vp9dsp.h" #include "vp9dsp_init.h" From 53f1d6a8ee365ce41eca96586fb3840fa28d2bf8 Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 22 Mar 2017 12:35:44 -0300 Subject: [PATCH 1359/3374] fate: add tests for ac3_fixed 5.1 downmix Reviewed-by: Michael Niedermayer Signed-off-by: James Almer --- tests/fate/ac3.mak | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/fate/ac3.mak b/tests/fate/ac3.mak index e6362718ea8df..76be2e869a3e7 100644 --- a/tests/fate/ac3.mak +++ b/tests/fate/ac3.mak @@ -36,6 +36,14 @@ FATE_AC3 += fate-ac3-fixed-4.0-downmix-mono fate-ac3-fixed-4.0-downmix-mono: CMD = pcm -c ac3_fixed -request_channel_layout 4 -i $(TARGET_SAMPLES)/ac3/millers_crossing_4.0.ac3 fate-ac3-fixed-4.0-downmix-mono: REF = $(SAMPLES)/ac3/millers_crossing_4.0_mono_v2.pcm +FATE_AC3 += fate-ac3-fixed-5.1-downmix-mono +fate-ac3-fixed-5.1-downmix-mono: CMD = pcm -c ac3_fixed -request_channel_layout 4 -i $(TARGET_SAMPLES)/ac3/monsters_inc_5.1_448_small.ac3 +fate-ac3-fixed-5.1-downmix-mono: REF = $(SAMPLES)/ac3/monsters_inc_5.1_448_small_mono_v2.pcm + +FATE_AC3 += fate-ac3-fixed-5.1-downmix-stereo +fate-ac3-fixed-5.1-downmix-stereo: CMD = pcm -c ac3_fixed -request_channel_layout 3 -i $(TARGET_SAMPLES)/ac3/monsters_inc_5.1_448_small.ac3 +fate-ac3-fixed-5.1-downmix-stereo: REF = $(SAMPLES)/ac3/monsters_inc_5.1_448_small_stereo_v2.pcm + FATE_EAC3 += fate-eac3-1 fate-eac3-1: CMD = pcm -i $(TARGET_SAMPLES)/eac3/csi_miami_5.1_256_spx_small.eac3 fate-eac3-1: REF = $(SAMPLES)/eac3/csi_miami_5.1_256_spx_small_v2.pcm From 91ccd38c0befb17d788c1621d1d4362dc1c40bd6 Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 22 Mar 2017 12:28:58 -0300 Subject: [PATCH 1360/3374] avcodec/ac3dsp: add special-case handling for the C downmix_fixed function Reviewed-by: Michael Niedermayer Signed-off-by: James Almer --- libavcodec/ac3dsp.c | 61 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/libavcodec/ac3dsp.c b/libavcodec/ac3dsp.c index 74f9e3caae9aa..43438da1314ca 100644 --- a/libavcodec/ac3dsp.c +++ b/libavcodec/ac3dsp.c @@ -279,6 +279,49 @@ static void ac3_downmix_c(float **samples, float **matrix, } } +static void ac3_downmix_5_to_2_symmetric_c_fixed(int32_t **samples, int16_t **matrix, + int len) +{ + int i; + int64_t v0, v1; + int16_t front_mix = matrix[0][0]; + int16_t center_mix = matrix[0][1]; + int16_t surround_mix = matrix[0][3]; + + for (i = 0; i < len; i++) { + v0 = (int64_t)samples[0][i] * front_mix + + (int64_t)samples[1][i] * center_mix + + (int64_t)samples[3][i] * surround_mix; + + v1 = (int64_t)samples[1][i] * center_mix + + (int64_t)samples[2][i] * front_mix + + (int64_t)samples[4][i] * surround_mix; + + samples[0][i] = (v0+2048)>>12; + samples[1][i] = (v1+2048)>>12; + } +} + +static void ac3_downmix_5_to_1_symmetric_c_fixed(int32_t **samples, int16_t **matrix, + int len) +{ + int i; + int64_t v0; + int16_t front_mix = matrix[0][0]; + int16_t center_mix = matrix[0][1]; + int16_t surround_mix = matrix[0][3]; + + for (i = 0; i < len; i++) { + v0 = (int64_t)samples[0][i] * front_mix + + (int64_t)samples[1][i] * center_mix + + (int64_t)samples[2][i] * front_mix + + (int64_t)samples[3][i] * surround_mix + + (int64_t)samples[4][i] * surround_mix; + + samples[0][i] = (v0+2048)>>12; + } +} + static void ac3_downmix_c_fixed(int32_t **samples, int16_t **matrix, int out_ch, int in_ch, int len) { @@ -307,6 +350,24 @@ static void ac3_downmix_c_fixed(int32_t **samples, int16_t **matrix, void ff_ac3dsp_downmix_fixed(AC3DSPContext *c, int32_t **samples, int16_t **matrix, int out_ch, int in_ch, int len) { + if (c->in_channels != in_ch || c->out_channels != out_ch) { + c->in_channels = in_ch; + c->out_channels = out_ch; + c->downmix_fixed = NULL; + + if (in_ch == 5 && out_ch == 2 && + !(matrix[1][0] | matrix[0][2] | + matrix[1][3] | matrix[0][4] | + (matrix[0][1] ^ matrix[1][1]) | + (matrix[0][0] ^ matrix[1][2]))) { + c->downmix_fixed = ac3_downmix_5_to_2_symmetric_c_fixed; + } else if (in_ch == 5 && out_ch == 1 && + matrix[0][0] == matrix[0][2] && + matrix[0][3] == matrix[0][4]) { + c->downmix_fixed = ac3_downmix_5_to_1_symmetric_c_fixed; + } + } + if (c->downmix_fixed) c->downmix_fixed(samples, matrix, len); else From 4cf1f68903cebcf6a6bede970f1b8f1509edf710 Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 27 Mar 2017 14:25:53 +0200 Subject: [PATCH 1361/3374] pthread_frame: minor simplification to error handling Get rid of the "ret" variable, and always use err. Report the packet as consumed if err is unset. This should be equivalent to the old code, which obviously required err=0 for p->result>=0 (and otherwise, p->result must have had the value err was last set to). The code block added by commit 32a5b631267 is also not needed anymore, because the new code strictly returns err if it's >=0. Reviewed-by: "Ronald S. Bultje" --- libavcodec/pthread_frame.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 295763a76de9f..5b5f5fb289260 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -468,7 +468,7 @@ int ff_thread_decode_frame(AVCodecContext *avctx, FrameThreadContext *fctx = avctx->internal->thread_ctx; int finished = fctx->next_finished; PerThreadContext *p; - int err, ret = 0; + int err; /* release the async lock, permitting blocked hwaccel threads to * go forward while we are in this function */ @@ -496,7 +496,7 @@ int ff_thread_decode_frame(AVCodecContext *avctx, if (fctx->delaying) { *got_picture_ptr=0; if (avpkt->size) { - ret = avpkt->size; + err = avpkt->size; goto finish; } } @@ -542,21 +542,12 @@ int ff_thread_decode_frame(AVCodecContext *avctx, fctx->next_finished = finished; - /* - * When no frame was found while flushing, but an error occurred in - * any thread, return it instead of 0. - * Otherwise the error can get lost. - */ - if (!avpkt->size && !*got_picture_ptr) - goto finish; - /* return the size of the consumed packet if no error occurred */ - ret = (p->result >= 0) ? avpkt->size : p->result; + if (err >= 0) + err = avpkt->size; finish: async_lock(fctx); - if (err < 0) - return err; - return ret; + return err; } void ff_thread_report_progress(ThreadFrame *f, int n, int field) From 9bed10afb8b28f9aa8a90ab24b7103d9a35de3cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 29 Mar 2017 13:45:09 +0200 Subject: [PATCH 1362/3374] doc/examples/encode_audio: add missing return --- doc/examples/encode_audio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/examples/encode_audio.c b/doc/examples/encode_audio.c index f3bb102d51bbc..4f6371e328bf7 100644 --- a/doc/examples/encode_audio.c +++ b/doc/examples/encode_audio.c @@ -222,4 +222,6 @@ int main(int argc, char **argv) av_frame_free(&frame); avcodec_free_context(&c); + + return 0; } From 944e5ce3ec7d4d9cf36e3f5c628b4e71186fa93a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 29 Mar 2017 14:18:10 +0200 Subject: [PATCH 1363/3374] doc/examples/{de,en}code_audio: fix includes Consistent with other examples. --- doc/examples/decode_audio.c | 4 ++-- doc/examples/encode_audio.c | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/examples/decode_audio.c b/doc/examples/decode_audio.c index a091cdc74c87f..d9ee7e7bbadf3 100644 --- a/doc/examples/decode_audio.c +++ b/doc/examples/decode_audio.c @@ -31,9 +31,9 @@ #include #include -#include "libavcodec/avcodec.h" +#include -#include "libavutil/frame.h" +#include #define AUDIO_INBUF_SIZE 20480 #define AUDIO_REFILL_THRESH 4096 diff --git a/doc/examples/encode_audio.c b/doc/examples/encode_audio.c index 4f6371e328bf7..88d0a6fd46492 100644 --- a/doc/examples/encode_audio.c +++ b/doc/examples/encode_audio.c @@ -31,12 +31,12 @@ #include #include -#include "libavcodec/avcodec.h" +#include -#include "libavutil/channel_layout.h" -#include "libavutil/common.h" -#include "libavutil/frame.h" -#include "libavutil/samplefmt.h" +#include +#include +#include +#include /* check that a given sample format is supported by the encoder */ static int check_sample_fmt(const AVCodec *codec, enum AVSampleFormat sample_fmt) From bfdcdd6d829c13eb019c194e214db0ec7dcf76cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Mon, 27 Mar 2017 01:05:18 +0200 Subject: [PATCH 1364/3374] lavu: add av_fourcc_make_string() and av_fourcc2str() --- doc/APIchanges | 4 ++++ libavutil/avutil.h | 14 ++++++++++++++ libavutil/utils.c | 23 +++++++++++++++++++++++ libavutil/version.h | 2 +- 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index 2274543024b7c..819433ba3fd80 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,10 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-03-xx - xxxxxxx - lavu 55.52.100 - avutil.h + add av_fourcc_make_string() function and av_fourcc2str() macro to replace + av_get_codec_tag_string() from lavc. + 2017-03-xx - xxxxxxx - lavf 57.68.100 - avformat.h Deprecate that demuxers export the stream rotation angle in AVStream.metadata (via an entry named "rotate"). Use av_stream_get_side_data() with diff --git a/libavutil/avutil.h b/libavutil/avutil.h index e9aaa03722ea7..4d633156d14df 100644 --- a/libavutil/avutil.h +++ b/libavutil/avutil.h @@ -343,6 +343,20 @@ FILE *av_fopen_utf8(const char *path, const char *mode); */ AVRational av_get_time_base_q(void); +#define AV_FOURCC_MAX_STRING_SIZE 32 + +#define av_fourcc2str(fourcc) av_fourcc_make_string((char[AV_FOURCC_MAX_STRING_SIZE]){0}, fourcc) + +/** + * Fill the provided buffer with a string containing a FourCC (four-character + * code) representation. + * + * @param buf a buffer with size in bytes of at least AV_FOURCC_MAX_STRING_SIZE + * @param fourcc the fourcc to represent + * @return the buffer in input + */ +char *av_fourcc_make_string(char *buf, uint32_t fourcc); + /** * @} * @} diff --git a/libavutil/utils.c b/libavutil/utils.c index 36e4dd5fdbe30..8cc7a9516cae9 100644 --- a/libavutil/utils.c +++ b/libavutil/utils.c @@ -121,6 +121,29 @@ unsigned av_int_list_length_for_size(unsigned elsize, return i; } +char *av_fourcc_make_string(char *buf, uint32_t fourcc) +{ + int i; + char *orig_buf = buf; + size_t buf_size = AV_FOURCC_MAX_STRING_SIZE; + + for (i = 0; i < 4; i++) { + const int c = fourcc & 0xff; + const int print_chr = (c >= '0' && c <= '9') || + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c && strchr(". -_", c)); + const int len = snprintf(buf, buf_size, print_chr ? "%c" : "[%d]", c); + if (len < 0) + break; + buf += len; + buf_size = buf_size > len ? buf_size - len : 0; + fourcc >>= 8; + } + + return orig_buf; +} + AVRational av_get_time_base_q(void) { return (AVRational){1, AV_TIME_BASE}; diff --git a/libavutil/version.h b/libavutil/version.h index 3c86c26638fdf..d6d78e7dc251b 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 51 +#define LIBAVUTIL_VERSION_MINOR 52 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From f156d35321bb600b2309b78185d600b2fa64d84a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Mon, 27 Mar 2017 01:11:41 +0200 Subject: [PATCH 1365/3374] lavc: deprecate av_get_codec_tag_string() --- libavcodec/avcodec.h | 5 +++++ libavcodec/version.h | 3 +++ 2 files changed, 8 insertions(+) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 4f3303366fe9c..60f7acefbd3d8 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -5667,6 +5667,7 @@ attribute_deprecated void avcodec_set_dimensions(AVCodecContext *s, int width, int height); #endif +#if FF_API_TAG_STRING /** * Put a string representing the codec tag codec_tag in buf. * @@ -5675,8 +5676,12 @@ void avcodec_set_dimensions(AVCodecContext *s, int width, int height); * @param codec_tag codec tag to assign * @return the length of the string that would have been generated if * enough space had been available, excluding the trailing null + * + * @deprecated see av_fourcc_make_string() and av_fourcc2str(). */ +attribute_deprecated size_t av_get_codec_tag_string(char *buf, size_t buf_size, unsigned int codec_tag); +#endif void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode); diff --git a/libavcodec/version.h b/libavcodec/version.h index 37defbc365153..8dea5cb97b572 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -235,6 +235,9 @@ #ifndef FF_API_MERGE_SD_API #define FF_API_MERGE_SD_API (LIBAVCODEC_VERSION_MAJOR < 59) #endif +#ifndef FF_API_TAG_STRING +#define FF_API_TAG_STRING (LIBAVCODEC_VERSION_MAJOR < 59) +#endif #endif /* AVCODEC_VERSION_H */ From 67e370ee527e9aa88d8754afd7345ffd9f6f6159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Mon, 27 Mar 2017 01:31:37 +0200 Subject: [PATCH 1366/3374] lavc: fix usages of av_get_codec_tag_string() --- libavcodec/dds.c | 12 ++++-------- libavcodec/mjpegdec.c | 8 +++----- libavcodec/mmaldec.c | 15 ++++++--------- libavcodec/sheervideo.c | 4 +--- libavcodec/utils.c | 9 +++------ 5 files changed, 17 insertions(+), 31 deletions(-) diff --git a/libavcodec/dds.c b/libavcodec/dds.c index fa0f34d7e7473..84b440f741de2 100644 --- a/libavcodec/dds.c +++ b/libavcodec/dds.c @@ -117,7 +117,6 @@ static int parse_pixel_format(AVCodecContext *avctx) { DDSContext *ctx = avctx->priv_data; GetByteContext *gbc = &ctx->gbc; - char buf[32]; uint32_t flags, fourcc, gimp_tag; enum DDSDXGIFormat dxgi; int size, bpp, r, g, b, a; @@ -161,13 +160,10 @@ static int parse_pixel_format(AVCodecContext *avctx) bytestream2_skip(gbc, 4); // caps4 bytestream2_skip(gbc, 4); // reserved2 - av_get_codec_tag_string(buf, sizeof(buf), fourcc); av_log(avctx, AV_LOG_VERBOSE, "fourcc %s bpp %d " - "r 0x%x g 0x%x b 0x%x a 0x%x\n", buf, bpp, r, g, b, a); - if (gimp_tag) { - av_get_codec_tag_string(buf, sizeof(buf), gimp_tag); - av_log(avctx, AV_LOG_VERBOSE, "and GIMP-DDS tag %s\n", buf); - } + "r 0x%x g 0x%x b 0x%x a 0x%x\n", av_fourcc2str(fourcc), bpp, r, g, b, a); + if (gimp_tag) + av_log(avctx, AV_LOG_VERBOSE, "and GIMP-DDS tag %s\n", av_fourcc2str(gimp_tag)); if (ctx->compressed) avctx->pix_fmt = AV_PIX_FMT_RGBA; @@ -344,7 +340,7 @@ static int parse_pixel_format(AVCodecContext *avctx) } break; default: - av_log(avctx, AV_LOG_ERROR, "Unsupported %s fourcc.\n", buf); + av_log(avctx, AV_LOG_ERROR, "Unsupported %s fourcc.\n", av_fourcc2str(fourcc)); return AVERROR_INVALIDDATA; } } else if (ctx->paletted) { diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index f26e8a3f9ac05..1973132bc63c6 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -1649,11 +1649,9 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) id = get_bits_long(&s->gb, 32); len -= 6; - if (s->avctx->debug & FF_DEBUG_STARTCODE) { - char id_str[32]; - av_get_codec_tag_string(id_str, sizeof(id_str), av_bswap32(id)); - av_log(s->avctx, AV_LOG_DEBUG, "APPx (%s / %8X) len=%d\n", id_str, id, len); - } + if (s->avctx->debug & FF_DEBUG_STARTCODE) + av_log(s->avctx, AV_LOG_DEBUG, "APPx (%s / %8X) len=%d\n", + av_fourcc2str(av_bswap32(id)), id, len); /* Buggy AVID, it puts EOI only at every 10th frame. */ /* Also, this fourcc is used by non-avid files too, it holds some diff --git a/libavcodec/mmaldec.c b/libavcodec/mmaldec.c index 284f26d6fe134..81fcebce23234 100644 --- a/libavcodec/mmaldec.c +++ b/libavcodec/mmaldec.c @@ -228,9 +228,8 @@ static void control_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) status = *(uint32_t *)buffer->data; av_log(avctx, AV_LOG_ERROR, "MMAL error %d on control port\n", (int)status); } else { - char s[20]; - av_get_codec_tag_string(s, sizeof(s), buffer->cmd); - av_log(avctx, AV_LOG_WARNING, "Unknown MMAL event %s on control port\n", s); + av_log(avctx, AV_LOG_WARNING, "Unknown MMAL event %s on control port\n", + av_fourcc2str(buffer->cmd)); } mmal_buffer_header_release(buffer); @@ -352,7 +351,6 @@ static av_cold int ffmmal_init_decoder(AVCodecContext *avctx) MMAL_STATUS_T status; MMAL_ES_FORMAT_T *format_in; MMAL_COMPONENT_T *decoder; - char tmp[32]; int ret = 0; bcm_host_init(); @@ -399,8 +397,8 @@ static av_cold int ffmmal_init_decoder(AVCodecContext *avctx) format_in->es->video.par.den = avctx->sample_aspect_ratio.den; format_in->flags = MMAL_ES_FORMAT_FLAG_FRAMED; - av_get_codec_tag_string(tmp, sizeof(tmp), format_in->encoding); - av_log(avctx, AV_LOG_DEBUG, "Using MMAL %s encoding.\n", tmp); + av_log(avctx, AV_LOG_DEBUG, "Using MMAL %s encoding.\n", + av_fourcc2str(format_in->encoding)); #if HAVE_MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS if (mmal_port_parameter_set_uint32(decoder->input[0], MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS, @@ -742,9 +740,8 @@ static int ffmmal_read_frame(AVCodecContext *avctx, AVFrame *frame, int *got_fra mmal_buffer_header_release(buffer); continue; } else if (buffer->cmd) { - char s[20]; - av_get_codec_tag_string(s, sizeof(s), buffer->cmd); - av_log(avctx, AV_LOG_WARNING, "Unknown MMAL event %s on output port\n", s); + av_log(avctx, AV_LOG_WARNING, "Unknown MMAL event %s on output port\n", + av_fourcc2str(buffer->cmd)); goto done; } else if (buffer->length == 0) { // Unused output buffer that got drained after format change. diff --git a/libavcodec/sheervideo.c b/libavcodec/sheervideo.c index 9d2da7ffb4872..092ac6ed82cb7 100644 --- a/libavcodec/sheervideo.c +++ b/libavcodec/sheervideo.c @@ -2879,7 +2879,6 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p = data; GetBitContext gb; unsigned format; - char format_str[32]; int ret; if (avpkt->size <= 20) @@ -2891,8 +2890,7 @@ static int decode_frame(AVCodecContext *avctx, s->alt = 0; format = AV_RL32(avpkt->data + 16); - av_get_codec_tag_string(format_str, sizeof(format_str), format); - av_log(avctx, AV_LOG_DEBUG, "format: %s\n", format_str); + av_log(avctx, AV_LOG_DEBUG, "format: %s\n", av_fourcc2str(format)); switch (format) { case MKTAG(' ', 'R', 'G', 'B'): avctx->pix_fmt = AV_PIX_FMT_RGB0; diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 365ee260565c8..3e8677d0f43b9 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -3256,12 +3256,9 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) ", %d reference frame%s", enc->refs, enc->refs > 1 ? "s" : ""); - if (enc->codec_tag) { - char tag_buf[32]; - av_get_codec_tag_string(tag_buf, sizeof(tag_buf), enc->codec_tag); - snprintf(buf + strlen(buf), buf_size - strlen(buf), - " (%s / 0x%04X)", tag_buf, enc->codec_tag); - } + if (enc->codec_tag) + snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%s / 0x%04X)", + av_fourcc2str(enc->codec_tag), enc->codec_tag); switch (enc->codec_type) { case AVMEDIA_TYPE_VIDEO: From cd4d6cba122b2d79da8667fa787919b734fa8133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Mon, 27 Mar 2017 01:31:52 +0200 Subject: [PATCH 1367/3374] lavf: fix usages of av_get_codec_tag_string() --- libavformat/aiffdec.c | 8 +++----- libavformat/apngdec.c | 8 ++------ libavformat/avidec.c | 8 ++------ libavformat/matroskadec.c | 7 ++----- libavformat/movenc.c | 6 +----- libavformat/mux.c | 7 +++---- libavformat/rsd.c | 4 +--- libavformat/wavdec.c | 5 ++--- 8 files changed, 16 insertions(+), 37 deletions(-) diff --git a/libavformat/aiffdec.c b/libavformat/aiffdec.c index 7dcc85f1ed491..2ef9386edb84e 100644 --- a/libavformat/aiffdec.c +++ b/libavformat/aiffdec.c @@ -128,11 +128,9 @@ static int get_aiff_header(AVFormatContext *s, int size, } else if (version == AIFF_C_VERSION1) { par->codec_tag = avio_rl32(pb); par->codec_id = ff_codec_get_id(ff_codec_aiff_tags, par->codec_tag); - if (par->codec_id == AV_CODEC_ID_NONE) { - char tag[32]; - av_get_codec_tag_string(tag, sizeof(tag), par->codec_tag); - avpriv_request_sample(s, "unknown or unsupported codec tag: %s", tag); - } + if (par->codec_id == AV_CODEC_ID_NONE) + avpriv_request_sample(s, "unknown or unsupported codec tag: %s", + av_fourcc2str(par->codec_tag)); size -= 4; } diff --git a/libavformat/apngdec.c b/libavformat/apngdec.c index 75dcf74a0ca7c..e1ea29b713c33 100644 --- a/libavformat/apngdec.c +++ b/libavformat/apngdec.c @@ -404,13 +404,9 @@ static int apng_read_packet(AVFormatContext *s, AVPacket *pkt) return ret; return 0; default: - { - char tag_buf[32]; - - av_get_codec_tag_string(tag_buf, sizeof(tag_buf), tag); - avpriv_request_sample(s, "In-stream tag=%s (0x%08X) len=%"PRIu32, tag_buf, tag, len); + avpriv_request_sample(s, "In-stream tag=%s (0x%08X) len=%"PRIu32, + av_fourcc2str(tag), tag, len); avio_skip(pb, len + 4); - } } /* Handle the unsupported yet cases */ diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 788a3abf3b2d3..31c33ded5602a 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -811,14 +811,12 @@ FF_ENABLE_DEPRECATION_WARNINGS tag1); /* If codec is not found yet, try with the mov tags. */ if (!st->codecpar->codec_id) { - char tag_buf[32]; - av_get_codec_tag_string(tag_buf, sizeof(tag_buf), tag1); st->codecpar->codec_id = ff_codec_get_id(ff_codec_movvideo_tags, tag1); if (st->codecpar->codec_id) av_log(s, AV_LOG_WARNING, "mov tag found in avi (fourcc %s)\n", - tag_buf); + av_fourcc2str(tag1)); } /* This is needed to get the pict type which is necessary * for generating correct pts. */ @@ -992,13 +990,11 @@ FF_ENABLE_DEPRECATION_WARNINGS } default: if (size > 1000000) { - char tag_buf[32]; - av_get_codec_tag_string(tag_buf, sizeof(tag_buf), tag); av_log(s, AV_LOG_ERROR, "Something went wrong during header parsing, " "tag %s has size %u, " "I will ignore it and try to continue anyway.\n", - tag_buf, size); + av_fourcc2str(tag), size); if (s->error_recognition & AV_EF_EXPLODE) goto fail; avi->movi_list = avio_tell(pb) - 4; diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 2e3c9bf197d4c..2e2a814b4ff30 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -2212,12 +2212,9 @@ static int matroska_parse_tracks(AVFormatContext *s) fourcc = MKTAG('S','V','Q','3'); codec_id = ff_codec_get_id(ff_codec_movvideo_tags, fourcc); } - if (codec_id == AV_CODEC_ID_NONE) { - char buf[32]; - av_get_codec_tag_string(buf, sizeof(buf), fourcc); + if (codec_id == AV_CODEC_ID_NONE) av_log(matroska->ctx, AV_LOG_ERROR, - "mov FourCC not found %s.\n", buf); - } + "mov FourCC not found %s.\n", av_fourcc2str(fourcc)); if (track->codec_priv.size >= 86) { bit_depth = AV_RB16(track->codec_priv.data + 82); ffio_init_context(&b, track->codec_priv.data, diff --git a/libavformat/movenc.c b/libavformat/movenc.c index a660645efea49..298d87290333a 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -2377,13 +2377,9 @@ static int mov_write_hdlr_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra hdlr_type = "tmcd"; descr = "TimeCodeHandler"; } else { - char tag_buf[32]; - av_get_codec_tag_string(tag_buf, sizeof(tag_buf), - track->par->codec_tag); - av_log(s, AV_LOG_WARNING, "Unknown hldr_type for %s / 0x%04X, writing dummy values\n", - tag_buf, track->par->codec_tag); + av_fourcc2str(track->par->codec_tag), track->par->codec_tag); } if (track->st) { // hdlr.name is used by some players to identify the content title diff --git a/libavformat/mux.c b/libavformat/mux.c index 11b09f1b6ed74..424b3346c9477 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -370,12 +370,11 @@ FF_ENABLE_DEPRECATION_WARNINGS } if (par->codec_tag) { if (!validate_codec_tag(s, st)) { - char tagbuf[32], tagbuf2[32]; - av_get_codec_tag_string(tagbuf, sizeof(tagbuf), par->codec_tag); - av_get_codec_tag_string(tagbuf2, sizeof(tagbuf2), av_codec_get_tag(s->oformat->codec_tag, par->codec_id)); + const uint32_t otag = av_codec_get_tag(s->oformat->codec_tag, par->codec_id); av_log(s, AV_LOG_ERROR, "Tag %s/0x%08x incompatible with output codec id '%d' (%s)\n", - tagbuf, par->codec_tag, par->codec_id, tagbuf2); + av_fourcc2str(par->codec_tag), par->codec_tag, + par->codec_id, av_fourcc2str(otag)); ret = AVERROR_INVALIDDATA; goto fail; } diff --git a/libavformat/rsd.c b/libavformat/rsd.c index 27a3d73981080..1c99f8c21ca58 100644 --- a/libavformat/rsd.c +++ b/libavformat/rsd.c @@ -70,9 +70,7 @@ static int rsd_read_header(AVFormatContext *s) par->codec_tag = avio_rl32(pb); par->codec_id = ff_codec_get_id(rsd_tags, par->codec_tag); if (!par->codec_id) { - char tag_buf[32]; - - av_get_codec_tag_string(tag_buf, sizeof(tag_buf), par->codec_tag); + const char *tag_buf = av_fourcc2str(par->codec_tag); for (i=0; i < FF_ARRAY_ELEMS(rsd_unsupported_tags); i++) { if (par->codec_tag == rsd_unsupported_tags[i]) { avpriv_request_sample(s, "Codec tag: %s", tag_buf); diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c index a3cd4ffa068f1..602ce975302e1 100644 --- a/libavformat/wavdec.c +++ b/libavformat/wavdec.c @@ -323,7 +323,6 @@ static int wav_read_header(AVFormatContext *s) int64_t size, av_uninit(data_size); int64_t sample_count = 0; int rf64 = 0; - char start_code[32]; uint32_t tag; AVIOContext *pb = s->pb; AVStream *st = NULL; @@ -347,8 +346,8 @@ static int wav_read_header(AVFormatContext *s) rf64 = 1; break; default: - av_get_codec_tag_string(start_code, sizeof(start_code), tag); - av_log(s, AV_LOG_ERROR, "invalid start code %s in RIFF header\n", start_code); + av_log(s, AV_LOG_ERROR, "invalid start code %s in RIFF header\n", + av_fourcc2str(tag)); return AVERROR_INVALIDDATA; } From 337c68d07142d1eeb540d73e2049896b9ab4f04e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Mon, 27 Mar 2017 01:32:13 +0200 Subject: [PATCH 1368/3374] tools/fourcc2pixfmt: fix usages of av_get_codec_tag_string() --- tools/fourcc2pixfmt.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/tools/fourcc2pixfmt.c b/tools/fourcc2pixfmt.c index 625f531f5c86d..75bb6077b5f1b 100644 --- a/tools/fourcc2pixfmt.c +++ b/tools/fourcc2pixfmt.c @@ -51,13 +51,9 @@ static void print_pix_fmt_fourccs(enum AVPixelFormat pix_fmt, const PixelFormatT { int i; - for (i = 0; pix_fmt_tags[i].pix_fmt != AV_PIX_FMT_NONE; i++) { - if (pix_fmt_tags[i].pix_fmt == pix_fmt) { - char buf[32]; - av_get_codec_tag_string(buf, sizeof(buf), pix_fmt_tags[i].fourcc); - printf("%s%c", buf, sep); - } - } + for (i = 0; pix_fmt_tags[i].pix_fmt != AV_PIX_FMT_NONE; i++) + if (pix_fmt_tags[i].pix_fmt == pix_fmt) + printf("%s%c", av_fourcc2str(pix_fmt_tags[i].fourcc), sep); } int main(int argc, char **argv) @@ -92,13 +88,10 @@ int main(int argc, char **argv) } } - if (list_fourcc_pix_fmt) { - for (i = 0; pix_fmt_tags[i].pix_fmt != AV_PIX_FMT_NONE; i++) { - char buf[32]; - av_get_codec_tag_string(buf, sizeof(buf), pix_fmt_tags[i].fourcc); - printf("%s: %s\n", buf, av_get_pix_fmt_name(pix_fmt_tags[i].pix_fmt)); - } - } + if (list_fourcc_pix_fmt) + for (i = 0; pix_fmt_tags[i].pix_fmt != AV_PIX_FMT_NONE; i++) + printf("%s: %s\n", av_fourcc2str(pix_fmt_tags[i].fourcc), + av_get_pix_fmt_name(pix_fmt_tags[i].pix_fmt)); if (list_pix_fmt_fourccs) { for (i = 0; av_pix_fmt_desc_get(i); i++) { From fa0a8faaa4510c946901446e4d2651e3f5f41b60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Mon, 27 Mar 2017 01:36:53 +0200 Subject: [PATCH 1369/3374] ffprobe: fix usage of av_get_codec_tag_string() --- ffprobe.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ffprobe.c b/ffprobe.c index 67c4ed40fae6d..4d5270feb6f6a 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -2382,8 +2382,7 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id #endif /* print AVI/FourCC tag */ - av_get_codec_tag_string(val_str, sizeof(val_str), par->codec_tag); - print_str("codec_tag_string", val_str); + print_str("codec_tag_string", av_fourcc2str(par->codec_tag)); print_fmt("codec_tag", "0x%04x", par->codec_tag); switch (par->codec_type) { From 656823220cde2439bf5c636a104e9216227769a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Mon, 27 Mar 2017 01:37:09 +0200 Subject: [PATCH 1370/3374] ffmpeg_videotoolbox: fix usage of av_get_codec_tag_string() --- ffmpeg_videotoolbox.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ffmpeg_videotoolbox.c b/ffmpeg_videotoolbox.c index 744a2a000933b..e9039654b93de 100644 --- a/ffmpeg_videotoolbox.c +++ b/ffmpeg_videotoolbox.c @@ -48,7 +48,6 @@ static int videotoolbox_retrieve_data(AVCodecContext *s, AVFrame *frame) uint8_t *data[4] = { 0 }; int linesize[4] = { 0 }; int planes, ret, i; - char codec_str[32]; av_frame_unref(vt->tmp_frame); @@ -60,9 +59,9 @@ static int videotoolbox_retrieve_data(AVCodecContext *s, AVFrame *frame) case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange: vt->tmp_frame->format = AV_PIX_FMT_NV12; break; #endif default: - av_get_codec_tag_string(codec_str, sizeof(codec_str), s->codec_tag); av_log(NULL, AV_LOG_ERROR, - "%s: Unsupported pixel format: %s\n", codec_str, videotoolbox_pixfmt); + "%s: Unsupported pixel format: %s\n", + av_fourcc2str(s->codec_tag), videotoolbox_pixfmt); return AVERROR(ENOSYS); } From d3cedc54cc872a376851828c88103c653fc8c395 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Mon, 27 Mar 2017 09:41:34 +0200 Subject: [PATCH 1371/3374] lavf/ape: remove unused magic field --- libavformat/ape.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/libavformat/ape.c b/libavformat/ape.c index 50a1aa13c16a3..c06db78480831 100644 --- a/libavformat/ape.c +++ b/libavformat/ape.c @@ -57,7 +57,6 @@ typedef struct APEContext { APEFrame *frames; /* Info from Descriptor Block */ - char magic[4]; int16_t fileversion; int16_t padding1; uint32_t descriptorlength; @@ -102,7 +101,6 @@ static void ape_dumpinfo(AVFormatContext * s, APEContext * ape_ctx) int i; av_log(s, AV_LOG_DEBUG, "Descriptor Block:\n\n"); - av_log(s, AV_LOG_DEBUG, "magic = \"%c%c%c%c\"\n", ape_ctx->magic[0], ape_ctx->magic[1], ape_ctx->magic[2], ape_ctx->magic[3]); av_log(s, AV_LOG_DEBUG, "fileversion = %"PRId16"\n", ape_ctx->fileversion); av_log(s, AV_LOG_DEBUG, "descriptorlength = %"PRIu32"\n", ape_ctx->descriptorlength); av_log(s, AV_LOG_DEBUG, "headerlength = %"PRIu32"\n", ape_ctx->headerlength); From bec96a7286bc415dd737c8c8f430f0176999e720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Mon, 27 Mar 2017 09:45:35 +0200 Subject: [PATCH 1372/3374] lavf: use av_fourcc2str() where appropriate --- libavformat/avidec.c | 10 +++------- libavformat/cafdec.c | 6 ++---- libavformat/dxa.c | 6 ++++-- libavformat/iff.c | 4 ++-- libavformat/mlvdec.c | 3 ++- libavformat/mov.c | 5 ++--- libavformat/rmdec.c | 9 ++------- libavformat/wc3movie.c | 10 ++++------ libavformat/westwood_vqa.c | 5 ++--- 9 files changed, 23 insertions(+), 35 deletions(-) diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 31c33ded5602a..4e694fe447fd0 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -117,13 +117,9 @@ static const AVMetadataConv avi_metadata_conv[] = { static int avi_load_index(AVFormatContext *s); static int guess_ni_flag(AVFormatContext *s); -#define print_tag(str, tag, size) \ - av_log(NULL, AV_LOG_TRACE, "pos:%"PRIX64" %s: tag=%c%c%c%c size=0x%x\n", \ - avio_tell(pb), str, tag & 0xff, \ - (tag >> 8) & 0xff, \ - (tag >> 16) & 0xff, \ - (tag >> 24) & 0xff, \ - size) +#define print_tag(str, tag, size) \ + av_log(NULL, AV_LOG_TRACE, "pos:%"PRIX64" %s: tag=%s size=0x%x\n", \ + avio_tell(pb), str, av_fourcc2str(tag), size) \ static inline int get_duration(AVIStream *ast, int len) { diff --git a/libavformat/cafdec.c b/libavformat/cafdec.c index fc85fd9799ed3..19939d3a859fa 100644 --- a/libavformat/cafdec.c +++ b/libavformat/cafdec.c @@ -298,11 +298,9 @@ static int read_header(AVFormatContext *s) break; default: -#define _(x) ((x) >= ' ' ? (x) : ' ') av_log(s, AV_LOG_WARNING, - "skipping CAF chunk: %08"PRIX32" (%c%c%c%c), size %"PRId64"\n", - tag, _(tag>>24), _((tag>>16)&0xFF), _((tag>>8)&0xFF), _(tag&0xFF), size); -#undef _ + "skipping CAF chunk: %08"PRIX32" (%s), size %"PRId64"\n", + tag, av_fourcc2str(av_bswap32(tag)), size); case MKBETAG('f','r','e','e'): if (size < 0) return AVERROR_INVALIDDATA; diff --git a/libavformat/dxa.c b/libavformat/dxa.c index 162838c1351a9..50193907be1fd 100644 --- a/libavformat/dxa.c +++ b/libavformat/dxa.c @@ -171,11 +171,13 @@ static int dxa_read_packet(AVFormatContext *s, AVPacket *pkt) } avio_seek(s->pb, c->vidpos, SEEK_SET); while(!avio_feof(s->pb) && c->frames){ + uint32_t tag; if ((ret = avio_read(s->pb, buf, 4)) != 4) { av_log(s, AV_LOG_ERROR, "failed reading chunk type\n"); return ret < 0 ? ret : AVERROR_INVALIDDATA; } - switch(AV_RL32(buf)){ + tag = AV_RL32(buf); + switch (tag) { case MKTAG('N', 'U', 'L', 'L'): if(av_new_packet(pkt, 4 + pal_size) < 0) return AVERROR(ENOMEM); @@ -217,7 +219,7 @@ static int dxa_read_packet(AVFormatContext *s, AVPacket *pkt) c->readvid = 0; return 0; default: - av_log(s, AV_LOG_ERROR, "Unknown tag %c%c%c%c\n", buf[0], buf[1], buf[2], buf[3]); + av_log(s, AV_LOG_ERROR, "Unknown tag %s\n", av_fourcc2str(tag)); return AVERROR_INVALIDDATA; } } diff --git a/libavformat/iff.c b/libavformat/iff.c index 29fb7bf139b6f..6a09eb0e31631 100644 --- a/libavformat/iff.c +++ b/libavformat/iff.c @@ -296,8 +296,8 @@ static int parse_dsd_prop(AVFormatContext *s, AVStream *st, uint64_t eof) st->codecpar->codec_tag = tag = avio_rl32(pb); st->codecpar->codec_id = ff_codec_get_id(dsd_codec_tags, tag); if (!st->codecpar->codec_id) { - av_log(s, AV_LOG_ERROR, "'%c%c%c%c' compression is not supported\n", - tag&0xFF, (tag>>8)&0xFF, (tag>>16)&0xFF, (tag>>24)&0xFF); + av_log(s, AV_LOG_ERROR, "'%s' compression is not supported\n", + av_fourcc2str(tag)); return AVERROR_PATCHWELCOME; } break; diff --git a/libavformat/mlvdec.c b/libavformat/mlvdec.c index 90c3779e443cd..319cd26de4f00 100644 --- a/libavformat/mlvdec.c +++ b/libavformat/mlvdec.c @@ -242,7 +242,8 @@ static int scan_file(AVFormatContext *avctx, AVStream *vst, AVStream *ast, int f } else if (type == MKTAG('N','U','L','L')) { } else if (type == MKTAG('M','L','V','I')) { /* occurs when MLV and Mnn files are concatenated */ } else { - av_log(avctx, AV_LOG_INFO, "unsupported tag %c%c%c%c, size %u\n", type&0xFF, (type>>8)&0xFF, (type>>16)&0xFF, (type>>24)&0xFF, size); + av_log(avctx, AV_LOG_INFO, "unsupported tag %s, size %u\n", + av_fourcc2str(type), size); } avio_skip(pb, size); } diff --git a/libavformat/mov.c b/libavformat/mov.c index 4034ca5e046a5..14b85d0d25b34 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -2284,9 +2284,8 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) id = mov_codec_id(st, format); av_log(c->fc, AV_LOG_TRACE, - "size=%"PRId64" 4CC= %c%c%c%c/0x%08x codec_type=%d\n", size, - (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff, - (format >> 24) & 0xff, format, st->codecpar->codec_type); + "size=%"PRId64" 4CC=%s/0x%08x codec_type=%d\n", size, + av_fourcc2str(format), format, st->codecpar->codec_type); if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) { st->codecpar->codec_id = id; diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c index e6a1fe88424de..88c2b9abf9148 100644 --- a/libavformat/rmdec.c +++ b/libavformat/rmdec.c @@ -564,13 +564,8 @@ static int rm_read_header(AVFormatContext *s) tag = avio_rl32(pb); tag_size = avio_rb32(pb); avio_rb16(pb); - av_log(s, AV_LOG_TRACE, "tag=%c%c%c%c (%08x) size=%d\n", - (tag ) & 0xff, - (tag >> 8) & 0xff, - (tag >> 16) & 0xff, - (tag >> 24) & 0xff, - tag, - tag_size); + av_log(s, AV_LOG_TRACE, "tag=%s size=%d\n", + av_fourcc2str(tag), tag_size); if (tag_size < 10 && tag != MKTAG('D', 'A', 'T', 'A')) goto fail; switch(tag) { diff --git a/libavformat/wc3movie.c b/libavformat/wc3movie.c index d8fc18eb5fc80..cb4d4d933ba3a 100644 --- a/libavformat/wc3movie.c +++ b/libavformat/wc3movie.c @@ -150,9 +150,8 @@ static int wc3_read_header(AVFormatContext *s) break; default: - av_log(s, AV_LOG_ERROR, " unrecognized WC3 chunk: %c%c%c%c (0x%02X%02X%02X%02X)\n", - (uint8_t)fourcc_tag, (uint8_t)(fourcc_tag >> 8), (uint8_t)(fourcc_tag >> 16), (uint8_t)(fourcc_tag >> 24), - (uint8_t)fourcc_tag, (uint8_t)(fourcc_tag >> 8), (uint8_t)(fourcc_tag >> 16), (uint8_t)(fourcc_tag >> 24)); + av_log(s, AV_LOG_ERROR, "unrecognized WC3 chunk: %s\n", + av_fourcc2str(fourcc_tag)); return AVERROR_INVALIDDATA; } @@ -274,9 +273,8 @@ static int wc3_read_packet(AVFormatContext *s, break; default: - av_log (s, AV_LOG_ERROR, " unrecognized WC3 chunk: %c%c%c%c (0x%02X%02X%02X%02X)\n", - (uint8_t)fourcc_tag, (uint8_t)(fourcc_tag >> 8), (uint8_t)(fourcc_tag >> 16), (uint8_t)(fourcc_tag >> 24), - (uint8_t)fourcc_tag, (uint8_t)(fourcc_tag >> 8), (uint8_t)(fourcc_tag >> 16), (uint8_t)(fourcc_tag >> 24)); + av_log(s, AV_LOG_ERROR, "unrecognized WC3 chunk: %s\n", + av_fourcc2str(fourcc_tag)); ret = AVERROR_INVALIDDATA; packet_read = 1; break; diff --git a/libavformat/westwood_vqa.c b/libavformat/westwood_vqa.c index 3635c6ab36f9d..5a54f130a0a6d 100644 --- a/libavformat/westwood_vqa.c +++ b/libavformat/westwood_vqa.c @@ -144,9 +144,8 @@ static int wsvqa_read_header(AVFormatContext *s) break; default: - av_log (s, AV_LOG_ERROR, " note: unknown chunk seen (%c%c%c%c)\n", - scratch[0], scratch[1], - scratch[2], scratch[3]); + av_log(s, AV_LOG_ERROR, " note: unknown chunk seen (%s)\n", + av_fourcc2str(chunk_tag)); break; } From 2d12b910f71093b782726d00b94643f7f21ca27d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Mon, 27 Mar 2017 09:45:11 +0200 Subject: [PATCH 1373/3374] lavc: use av_fourcc2str() where appropriate --- libavcodec/pngdec.c | 7 ++----- libavcodec/vqavideo.c | 8 ++------ 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index a4eb6cce1b187..c08665be7c547 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -1143,11 +1143,8 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, } tag = bytestream2_get_le32(&s->gb); if (avctx->debug & FF_DEBUG_STARTCODE) - av_log(avctx, AV_LOG_DEBUG, "png: tag=%c%c%c%c length=%u\n", - (tag & 0xff), - ((tag >> 8) & 0xff), - ((tag >> 16) & 0xff), - ((tag >> 24) & 0xff), length); + av_log(avctx, AV_LOG_DEBUG, "png: tag=%s length=%u\n", + av_fourcc2str(tag), length); if (avctx->codec_id == AV_CODEC_ID_PNG && avctx->skip_frame == AVDISCARD_ALL) { diff --git a/libavcodec/vqavideo.c b/libavcodec/vqavideo.c index 81d50bb5a4f8d..0e70be1000a1f 100644 --- a/libavcodec/vqavideo.c +++ b/libavcodec/vqavideo.c @@ -384,12 +384,8 @@ static int vqa_decode_chunk(VqaContext *s, AVFrame *frame) break; default: - av_log(s->avctx, AV_LOG_ERROR, "Found unknown chunk type: %c%c%c%c (%08X)\n", - (chunk_type >> 24) & 0xFF, - (chunk_type >> 16) & 0xFF, - (chunk_type >> 8) & 0xFF, - (chunk_type >> 0) & 0xFF, - chunk_type); + av_log(s->avctx, AV_LOG_ERROR, "Found unknown chunk type: %s (%08X)\n", + av_fourcc2str(av_bswap32(chunk_type)), chunk_type); break; } From 8f9edf89d5d4a90eed4a798175e97e07a885ab79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sun, 26 Mar 2017 20:41:41 +0200 Subject: [PATCH 1374/3374] lavfi/dynaudnorm: rename pow2 to pow_2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This conflict with the DJGPP libc which includes a pow2 function¹ We cannot make DJGPP POSIX only (using -D_POSIX_SOURCE) to avoid this kind of symbols conflicts due to the lack of both posix_memalign and memalign (DJGPP non standard function) in that POSIX mode. We currently rely on memalign for aligned heap allocation. [1]: http://www.delorie.com/djgpp/doc/libc-2.02/libc_536.html --- libavfilter/af_dynaudnorm.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavfilter/af_dynaudnorm.c b/libavfilter/af_dynaudnorm.c index ddbef26ab5954..aa5b28e6475dc 100644 --- a/libavfilter/af_dynaudnorm.c +++ b/libavfilter/af_dynaudnorm.c @@ -341,7 +341,7 @@ static inline double fade(double prev, double next, int pos, return fade_factors[0][pos] * prev + fade_factors[1][pos] * next; } -static inline double pow2(const double value) +static inline double pow_2(const double value) { return value * value; } @@ -384,7 +384,7 @@ static double compute_frame_rms(AVFrame *frame, int channel) const double *data_ptr = (double *)frame->extended_data[c]; for (i = 0; i < frame->nb_samples; i++) { - rms_value += pow2(data_ptr[i]); + rms_value += pow_2(data_ptr[i]); } } @@ -392,7 +392,7 @@ static double compute_frame_rms(AVFrame *frame, int channel) } else { const double *data_ptr = (double *)frame->extended_data[channel]; for (i = 0; i < frame->nb_samples; i++) { - rms_value += pow2(data_ptr[i]); + rms_value += pow_2(data_ptr[i]); } rms_value /= frame->nb_samples; @@ -545,7 +545,7 @@ static double compute_frame_std_dev(DynamicAudioNormalizerContext *s, const double *data_ptr = (double *)frame->extended_data[c]; for (i = 0; i < frame->nb_samples; i++) { - variance += pow2(data_ptr[i]); // Assume that MEAN is *zero* + variance += pow_2(data_ptr[i]); // Assume that MEAN is *zero* } } variance /= (s->channels * frame->nb_samples) - 1; @@ -553,7 +553,7 @@ static double compute_frame_std_dev(DynamicAudioNormalizerContext *s, const double *data_ptr = (double *)frame->extended_data[channel]; for (i = 0; i < frame->nb_samples; i++) { - variance += pow2(data_ptr[i]); // Assume that MEAN is *zero* + variance += pow_2(data_ptr[i]); // Assume that MEAN is *zero* } variance /= frame->nb_samples - 1; } From 4ea8f57548f36b0104bc372b2a6d3d4eaae0ce70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sun, 26 Mar 2017 20:43:11 +0200 Subject: [PATCH 1375/3374] lavfi/psnr: rename pow2 to pow_2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This conflict with the DJGPP libc which includes a pow2 function¹ We cannot make DJGPP POSIX only (using -D_POSIX_SOURCE) to avoid this kind of symbols conflicts due to the lack of both posix_memalign and memalign (DJGPP non standard function) in that POSIX mode. We currently rely on memalign for aligned heap allocation. [1]: http://www.delorie.com/djgpp/doc/libc-2.02/libc_536.html --- libavfilter/vf_psnr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavfilter/vf_psnr.c b/libavfilter/vf_psnr.c index af9397123bd2e..1201b2cd7c3a8 100644 --- a/libavfilter/vf_psnr.c +++ b/libavfilter/vf_psnr.c @@ -70,14 +70,14 @@ static const AVOption psnr_options[] = { AVFILTER_DEFINE_CLASS(psnr); -static inline unsigned pow2(unsigned base) +static inline unsigned pow_2(unsigned base) { return base*base; } static inline double get_psnr(double mse, uint64_t nb_frames, int max) { - return 10.0 * log10(pow2(max) / (mse / nb_frames)); + return 10.0 * log10(pow_2(max) / (mse / nb_frames)); } static uint64_t sse_line_8bit(const uint8_t *main_line, const uint8_t *ref_line, int outw) @@ -86,7 +86,7 @@ static uint64_t sse_line_8bit(const uint8_t *main_line, const uint8_t *ref_line unsigned m2 = 0; for (j = 0; j < outw; j++) - m2 += pow2(main_line[j] - ref_line[j]); + m2 += pow_2(main_line[j] - ref_line[j]); return m2; } @@ -99,7 +99,7 @@ static uint64_t sse_line_16bit(const uint8_t *_main_line, const uint8_t *_ref_li const uint16_t *ref_line = (const uint16_t *) _ref_line; for (j = 0; j < outw; j++) - m2 += pow2(main_line[j] - ref_line[j]); + m2 += pow_2(main_line[j] - ref_line[j]); return m2; } From 46068070314d56f66b681796635d38d497ef3bda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sun, 26 Mar 2017 20:51:14 +0200 Subject: [PATCH 1376/3374] lavfi/xbr: undef PI if defined This conflict with the DJGPP libc math.h which includes a PI macro (to M_PI). We cannot make DJGPP POSIX only (using -D_POSIX_SOURCE) to avoid this kind of symbols conflicts due to the lack of both posix_memalign and memalign (DJGPP non standard function) in that POSIX mode. We currently rely on memalign for aligned heap allocation. --- libavfilter/vf_xbr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavfilter/vf_xbr.c b/libavfilter/vf_xbr.c index 9893e0cc80318..d0d51045cc7ce 100644 --- a/libavfilter/vf_xbr.c +++ b/libavfilter/vf_xbr.c @@ -37,6 +37,10 @@ #define RED_BLUE_MASK 0x00FF00FF #define GREEN_MASK 0x0000FF00 +#ifdef PI +#undef PI +#endif + typedef int (*xbrfunc_t)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); typedef struct { From 1473afac5d11a0a90810b6cd8107d63640c9fd38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Mon, 27 Mar 2017 20:30:24 +0200 Subject: [PATCH 1377/3374] lavu/mem: clamp alignment to 16 for DJGPP See also https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80208 --- libavutil/mem.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavutil/mem.h b/libavutil/mem.h index 718a143c4c64e..527cd03191a90 100644 --- a/libavutil/mem.h +++ b/libavutil/mem.h @@ -97,6 +97,9 @@ #define DECLARE_ASM_CONST(n,t,v) \ AV_PRAGMA(DATA_ALIGN(v,n)) \ static const t __attribute__((aligned(n))) v +#elif defined(__DJGPP__) + #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (FFMIN(n, 16)))) v + #define DECLARE_ASM_CONST(n,t,v) static const t av_used __attribute__ ((aligned (FFMIN(n, 16)))) v #elif defined(__GNUC__) || defined(__clang__) #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v #define DECLARE_ASM_CONST(n,t,v) static const t av_used __attribute__ ((aligned (n))) v From 549045254c4614d5d61b5c36e340171a6914d57c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Mon, 27 Mar 2017 21:31:46 +0200 Subject: [PATCH 1378/3374] Fix all -Wformat warnings raised by DJGPP --- doc/libav-merge.txt | 1 - ffmpeg.c | 2 +- ffprobe.c | 2 +- libavcodec/alsdec.c | 4 ++-- libavcodec/apedec.c | 2 +- libavcodec/bitstream.c | 5 +++-- libavcodec/bmp.c | 3 ++- libavcodec/dnxhddec.c | 9 +++++---- libavcodec/dvdec.c | 4 ++-- libavcodec/dvdsubdec.c | 2 +- libavcodec/dvdsubenc.c | 2 +- libavcodec/dxv.c | 4 ++-- libavcodec/ffv1dec.c | 2 +- libavcodec/hevc_ps.c | 2 +- libavcodec/hqx.c | 2 +- libavcodec/iff.c | 4 ++-- libavcodec/microdvddec.c | 6 +++--- libavcodec/mpegaudiodec_template.c | 3 ++- libavcodec/parser.c | 4 ++-- libavcodec/pixlet.c | 5 +++-- libavcodec/shorten.c | 3 ++- libavcodec/tiff_common.c | 2 +- libavcodec/vorbisdec.c | 6 +++--- libavcodec/wmaprodec.c | 2 +- libavfilter/af_hdcd.c | 7 +++++-- libavfilter/f_perms.c | 2 +- libavfilter/vf_palettegen.c | 2 +- libavfilter/vf_paletteuse.c | 4 ++-- libavfilter/vsrc_cellauto.c | 2 +- libavfilter/vsrc_life.c | 2 +- libavformat/aadec.c | 3 ++- libavformat/apngdec.c | 2 +- libavformat/astdec.c | 2 +- libavformat/brstm.c | 2 +- libavformat/dashenc.c | 2 +- libavformat/dump.c | 3 ++- libavformat/framecrcenc.c | 2 +- libavformat/ircamdec.c | 2 +- libavformat/mov.c | 23 ++++++++++++----------- libavformat/mov_chan.c | 5 +++-- libavformat/movenc.c | 6 +++--- libavformat/mp3enc.c | 2 +- libavformat/mpegtsenc.c | 10 ++++++---- libavformat/mux.c | 5 ++--- libavformat/nistspheredec.c | 8 ++++---- libavformat/nsvdec.c | 4 ++-- libavformat/omaenc.c | 4 ++-- libavformat/rmdec.c | 3 ++- libavformat/rpl.c | 8 ++++---- libavformat/rtpenc.c | 2 +- libavformat/srtdec.c | 2 +- libavformat/uncodedframecrcenc.c | 2 +- libavformat/westwood_vqa.c | 3 ++- libavformat/xwma.c | 5 +++-- libavutil/log.c | 6 +++--- libavutil/timecode.c | 3 ++- 56 files changed, 118 insertions(+), 101 deletions(-) diff --git a/doc/libav-merge.txt b/doc/libav-merge.txt index 847b620bf905a..44547c94e7057 100644 --- a/doc/libav-merge.txt +++ b/doc/libav-merge.txt @@ -98,7 +98,6 @@ Stuff that didn't reach the codebase: - Removal of the custom atomic API (5cc0057f49, see http://ffmpeg.org/pipermail/ffmpeg-devel/2017-March/209003.html) - Use the new bitstream filter for extracting extradata (see 8e2ea69135 and 096a8effa3) - ADD_RES_MMX_4_8 in libavcodec/x86/hevc_add_res.asm probably needs updating (see 589880710) -- ISO printf warnings raised by DJGPP (c454dfcff9, currently under review: http://ffmpeg.org/pipermail/ffmpeg-devel/2017-March/209239.html) Collateral damage that needs work locally: ------------------------------------------ diff --git a/ffmpeg.c b/ffmpeg.c index 3aa1e7854da51..41c709d6813a7 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -2509,7 +2509,7 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output, 1000, AV_TIME_BASE); if (end < ist->prev_sub.subtitle.end_display_time) { av_log(ist->dec_ctx, AV_LOG_DEBUG, - "Subtitle duration reduced from %d to %d%s\n", + "Subtitle duration reduced from %"PRId32" to %d%s\n", ist->prev_sub.subtitle.end_display_time, end, end <= 0 ? ", dropping it" : ""); ist->prev_sub.subtitle.end_display_time = end; diff --git a/ffprobe.c b/ffprobe.c index 4d5270feb6f6a..77ea3494d2644 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -2383,7 +2383,7 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id /* print AVI/FourCC tag */ print_str("codec_tag_string", av_fourcc2str(par->codec_tag)); - print_fmt("codec_tag", "0x%04x", par->codec_tag); + print_fmt("codec_tag", "0x%04"PRIx32, par->codec_tag); switch (par->codec_type) { case AVMEDIA_TYPE_VIDEO: diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c index 3986347ee2e91..d95e30d10d3f2 100644 --- a/libavcodec/alsdec.c +++ b/libavcodec/alsdec.c @@ -1500,7 +1500,7 @@ static int read_diff_float_data(ALSDecContext *ctx, unsigned int ra_frame) { tmp_32 = ff_mlz_decompression(ctx->mlz, gb, nchars, larray); if(tmp_32 != nchars) { - av_log(ctx->avctx, AV_LOG_ERROR, "Error in MLZ decompression (%d, %d).\n", tmp_32, nchars); + av_log(ctx->avctx, AV_LOG_ERROR, "Error in MLZ decompression (%"PRId32", %d).\n", tmp_32, nchars); return AVERROR_INVALIDDATA; } @@ -1543,7 +1543,7 @@ static int read_diff_float_data(ALSDecContext *ctx, unsigned int ra_frame) { tmp_32 = ff_mlz_decompression(ctx->mlz, gb, nchars, larray); if(tmp_32 != nchars) { - av_log(ctx->avctx, AV_LOG_ERROR, "Error in MLZ decompression (%d, %d).\n", tmp_32, nchars); + av_log(ctx->avctx, AV_LOG_ERROR, "Error in MLZ decompression (%"PRId32", %d).\n", tmp_32, nchars); return AVERROR_INVALIDDATA; } diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index b99598b4ee74e..a6b14b8e247c7 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -495,7 +495,7 @@ static inline int ape_decode_value_3860(APEContext *ctx, GetBitContext *gb, else if(rice->k <= MIN_CACHE_BITS) { x = (overflow << rice->k) + get_bits(gb, rice->k); } else { - av_log(ctx->avctx, AV_LOG_ERROR, "Too many bits: %d\n", rice->k); + av_log(ctx->avctx, AV_LOG_ERROR, "Too many bits: %"PRIu32"\n", rice->k); return AVERROR_INVALIDDATA; } rice->ksum += x - (rice->ksum + 8 >> 4); diff --git a/libavcodec/bitstream.c b/libavcodec/bitstream.c index 69deabe770108..ed528fe4af7d1 100644 --- a/libavcodec/bitstream.c +++ b/libavcodec/bitstream.c @@ -176,7 +176,7 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, n = codes[i].bits; code = codes[i].code; symbol = codes[i].symbol; - ff_dlog(NULL, "i=%d n=%d code=0x%x\n", i, n, code); + ff_dlog(NULL, "i=%d n=%d code=0x%"PRIx32"\n", i, n, code); if (n <= table_nb_bits) { /* no need to add another table */ j = code >> (32 - table_nb_bits); @@ -310,7 +310,8 @@ int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes, } \ GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size); \ if (buf[j].code >= (1LL<pix_fmt = alpha ? AV_PIX_FMT_RGBA : AV_PIX_FMT_RGB0; else { - av_log(avctx, AV_LOG_ERROR, "Unknown bitfields %0X %0X %0X\n", rgb[0], rgb[1], rgb[2]); + av_log(avctx, AV_LOG_ERROR, "Unknown bitfields " + "%0"PRIX32" %0"PRIX32" %0"PRIX32"\n", rgb[0], rgb[1], rgb[2]); return AVERROR(EINVAL); } } else { diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c index 305fd52daa4a0..f67763ef47e8f 100644 --- a/libavcodec/dnxhddec.c +++ b/libavcodec/dnxhddec.c @@ -111,7 +111,7 @@ static int dnxhd_init_vlc(DNXHDContext *ctx, uint32_t cid, int bitdepth) int index; if ((index = ff_dnxhd_get_cid_table(cid)) < 0) { - av_log(ctx->avctx, AV_LOG_ERROR, "unsupported cid %d\n", cid); + av_log(ctx->avctx, AV_LOG_ERROR, "unsupported cid %"PRIu32"\n", cid); return AVERROR(ENOSYS); } if (ff_dnxhd_cid_table[index].bit_depth != bitdepth && @@ -120,7 +120,7 @@ static int dnxhd_init_vlc(DNXHDContext *ctx, uint32_t cid, int bitdepth) return AVERROR_INVALIDDATA; } ctx->cid_table = &ff_dnxhd_cid_table[index]; - av_log(ctx->avctx, AV_LOG_VERBOSE, "Profile cid %d.\n", cid); + av_log(ctx->avctx, AV_LOG_VERBOSE, "Profile cid %"PRIu32".\n", cid); ff_free_vlc(&ctx->ac_vlc); ff_free_vlc(&ctx->dc_vlc); @@ -316,10 +316,11 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, for (i = 0; i < ctx->mb_height; i++) { ctx->mb_scan_index[i] = AV_RB32(buf + 0x170 + (i << 2)); - ff_dlog(ctx->avctx, "mb scan index %d, pos %d: %u\n", i, 0x170 + (i << 2), ctx->mb_scan_index[i]); + ff_dlog(ctx->avctx, "mb scan index %d, pos %d: %"PRIu32"\n", + i, 0x170 + (i << 2), ctx->mb_scan_index[i]); if (buf_size - ctx->data_offset < ctx->mb_scan_index[i]) { av_log(ctx->avctx, AV_LOG_ERROR, - "invalid mb scan index (%u vs %u).\n", + "invalid mb scan index (%"PRIu32" vs %u).\n", ctx->mb_scan_index[i], buf_size - ctx->data_offset); return AVERROR_INVALIDDATA; } diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c index a8d7a07ae471f..7b16787e2745c 100644 --- a/libavcodec/dvdec.c +++ b/libavcodec/dvdec.c @@ -222,8 +222,8 @@ static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, int16_t *block) /* get the AC coefficients until last_index is reached */ for (;;) { - ff_dlog(NULL, "%2d: bits=%04x index=%u\n", pos, SHOW_UBITS(re, gb, 16), - re_index); + ff_dlog(NULL, "%2d: bits=%04"PRIx32" index=%u\n", + pos, SHOW_UBITS(re, gb, 16), re_index); /* our own optimized GET_RL_VLC */ index = NEG_USR32(re_cache, TEX_VLC_BITS); vlc_len = ff_dv_rl_vlc[index].len; diff --git a/libavcodec/dvdsubdec.c b/libavcodec/dvdsubdec.c index e91d63ea295c7..22ce728ea6f96 100644 --- a/libavcodec/dvdsubdec.c +++ b/libavcodec/dvdsubdec.c @@ -747,7 +747,7 @@ static av_cold int dvdsub_init(AVCodecContext *avctx) int i; av_log(avctx, AV_LOG_DEBUG, "palette:"); for(i=0;i<16;i++) - av_log(avctx, AV_LOG_DEBUG, " 0x%06x", ctx->palette[i]); + av_log(avctx, AV_LOG_DEBUG, " 0x%06"PRIx32, ctx->palette[i]); av_log(avctx, AV_LOG_DEBUG, "\n"); } diff --git a/libavcodec/dvdsubenc.c b/libavcodec/dvdsubenc.c index 29e0322daac25..26afdc666b430 100644 --- a/libavcodec/dvdsubenc.c +++ b/libavcodec/dvdsubenc.c @@ -343,7 +343,7 @@ FF_ENABLE_DEPRECATION_WARNINGS av_log(avctx, AV_LOG_DEBUG, "Selected palette:"); for (i = 0; i < 4; i++) - av_log(avctx, AV_LOG_DEBUG, " 0x%06x@@%02x (0x%x,0x%x)", + av_log(avctx, AV_LOG_DEBUG, " 0x%06"PRIx32"@@%02x (0x%x,0x%x)", dvdc->global_palette[out_palette[i]], out_alpha[i], out_palette[i], out_alpha[i] >> 4); av_log(avctx, AV_LOG_DEBUG, "\n"); diff --git a/libavcodec/dxv.c b/libavcodec/dxv.c index b1f826ac41ccb..4b1c2d25ccfa0 100644 --- a/libavcodec/dxv.c +++ b/libavcodec/dxv.c @@ -374,7 +374,7 @@ static int dxv_decode(AVCodecContext *avctx, void *data, break; case MKBETAG('Y', 'C', 'G', '6'): case MKBETAG('Y', 'G', '1', '0'): - avpriv_report_missing_feature(avctx, "Tag 0x%08X", tag); + avpriv_report_missing_feature(avctx, "Tag 0x%08"PRIX32, tag); return AVERROR_PATCHWELCOME; default: /* Old version does not have a real header, just size and type. */ @@ -401,7 +401,7 @@ static int dxv_decode(AVCodecContext *avctx, void *data, ctx->tex_funct = ctx->texdsp.dxt1_block; ctx->tex_step = 8; } else { - av_log(avctx, AV_LOG_ERROR, "Unsupported header (0x%08X)\n.", tag); + av_log(avctx, AV_LOG_ERROR, "Unsupported header (0x%08"PRIX32")\n.", tag); return AVERROR_INVALIDDATA; } ctx->tex_rat = 1; diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index 7f1bc4fcf43bf..1a5076717126f 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -870,7 +870,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac fs->slice_damaged = 1; } if (avctx->debug & FF_DEBUG_PICT_INFO) { - av_log(avctx, AV_LOG_DEBUG, "slice %d, CRC: 0x%08X\n", i, AV_RB32(buf_p + v - 4)); + av_log(avctx, AV_LOG_DEBUG, "slice %d, CRC: 0x%08"PRIX32"\n", i, AV_RB32(buf_p + v - 4)); } } diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index 287b24e832daa..acd55cc513cf5 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -649,7 +649,7 @@ static void decode_vui(GetBitContext *gb, AVCodecContext *avctx, vui->vui_num_units_in_tick = get_bits_long(gb, 32); vui->vui_time_scale = get_bits_long(gb, 32); if (alt) { - av_log(avctx, AV_LOG_INFO, "Retry got %i/%i fps\n", + av_log(avctx, AV_LOG_INFO, "Retry got %"PRIu32"/%"PRIu32" fps\n", vui->vui_time_scale, vui->vui_num_units_in_tick); } vui->vui_poc_proportional_to_timing_flag = get_bits1(gb); diff --git a/libavcodec/hqx.c b/libavcodec/hqx.c index 138d9604118c7..1bc123e659179 100644 --- a/libavcodec/hqx.c +++ b/libavcodec/hqx.c @@ -417,7 +417,7 @@ static int hqx_decode_frame(AVCodecContext *avctx, void *data, info_tag = AV_RL32(src); if (info_tag == MKTAG('I', 'N', 'F', 'O')) { - unsigned info_offset = AV_RL32(src + 4); + uint32_t info_offset = AV_RL32(src + 4); if (info_offset > INT_MAX || info_offset + 8 > avpkt->size) { av_log(avctx, AV_LOG_ERROR, "Invalid INFO header offset: 0x%08"PRIX32" is too large.\n", diff --git a/libavcodec/iff.c b/libavcodec/iff.c index 995e908791814..075ada6ddd1d1 100644 --- a/libavcodec/iff.c +++ b/libavcodec/iff.c @@ -934,7 +934,7 @@ static void decode_delta_j(uint8_t *dst, offset = bytestream2_get_be16(&gb); if (cols * bpp == 0 || bytestream2_get_bytes_left(&gb) < cols * bpp) { - av_log(NULL, AV_LOG_ERROR, "cols*bpp is invalid (%d*%d)", cols, bpp); + av_log(NULL, AV_LOG_ERROR, "cols*bpp is invalid (%"PRId32"*%d)", cols, bpp); return; } @@ -982,7 +982,7 @@ static void decode_delta_j(uint8_t *dst, unsigned noffset = offset + (r * pitch) + d * planepitch; if (!bytes || bytestream2_get_bytes_left(&gb) < bytes) { - av_log(NULL, AV_LOG_ERROR, "bytes %d is invalid", bytes); + av_log(NULL, AV_LOG_ERROR, "bytes %"PRId32" is invalid", bytes); return; } diff --git a/libavcodec/microdvddec.c b/libavcodec/microdvddec.c index e8d271931f460..4a34267793735 100644 --- a/libavcodec/microdvddec.c +++ b/libavcodec/microdvddec.c @@ -214,7 +214,7 @@ static void microdvd_open_tags(AVBPrint *new_line, struct microdvd_tag *tags) break; case 'c': - av_bprintf(new_line, "{\\c&H%06X&}", tags[i].data1); + av_bprintf(new_line, "{\\c&H%06"PRIX32"&}", tags[i].data1); break; case 'f': @@ -223,7 +223,7 @@ static void microdvd_open_tags(AVBPrint *new_line, struct microdvd_tag *tags) break; case 's': - av_bprintf(new_line, "{\\fs%d}", tags[i].data1); + av_bprintf(new_line, "{\\fs%"PRId32"}", tags[i].data1); break; case 'p': @@ -232,7 +232,7 @@ static void microdvd_open_tags(AVBPrint *new_line, struct microdvd_tag *tags) break; case 'o': - av_bprintf(new_line, "{\\pos(%d,%d)}", + av_bprintf(new_line, "{\\pos(%"PRId32",%"PRId32")}", tags[i].data1, tags[i].data2); break; } diff --git a/libavcodec/mpegaudiodec_template.c b/libavcodec/mpegaudiodec_template.c index ec109b3d45559..9cce88e263b73 100644 --- a/libavcodec/mpegaudiodec_template.c +++ b/libavcodec/mpegaudiodec_template.c @@ -280,7 +280,8 @@ static av_cold void decode_init_static(void) scale_factor_mult[i][0] = MULLx(norm, FIXR(1.0 * 2.0), FRAC_BITS); scale_factor_mult[i][1] = MULLx(norm, FIXR(0.7937005259 * 2.0), FRAC_BITS); scale_factor_mult[i][2] = MULLx(norm, FIXR(0.6299605249 * 2.0), FRAC_BITS); - ff_dlog(NULL, "%d: norm=%x s=%x %x %x\n", i, norm, + ff_dlog(NULL, "%d: norm=%x s=%"PRIx32" %"PRIx32" %"PRIx32"\n", i, + (unsigned)norm, scale_factor_mult[i][0], scale_factor_mult[i][1], scale_factor_mult[i][2]); diff --git a/libavcodec/parser.c b/libavcodec/parser.c index 30cfc55cbcb7f..f87e8631b1654 100644 --- a/libavcodec/parser.c +++ b/libavcodec/parser.c @@ -251,7 +251,7 @@ int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_size) { if (pc->overread) { - ff_dlog(NULL, "overread %d, state:%X next:%d index:%d o_index:%d\n", + ff_dlog(NULL, "overread %d, state:%"PRIX32" next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); ff_dlog(NULL, "%X %X %X %X\n", (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]); @@ -314,7 +314,7 @@ int ff_combine_frame(ParseContext *pc, int next, } if (pc->overread) { - ff_dlog(NULL, "overread %d, state:%X next:%d index:%d o_index:%d\n", + ff_dlog(NULL, "overread %d, state:%"PRIX32" next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); ff_dlog(NULL, "%X %X %X %X\n", (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]); diff --git a/libavcodec/pixlet.c b/libavcodec/pixlet.c index 1d4734d397deb..4aa59f8f33d23 100644 --- a/libavcodec/pixlet.c +++ b/libavcodec/pixlet.c @@ -324,7 +324,8 @@ static int read_highpass(AVCodecContext *avctx, uint8_t *ptr, int plane, AVFrame magic = bytestream2_get_be32(&ctx->gb); if (magic != 0xDEADBEEF) { - av_log(avctx, AV_LOG_ERROR, "wrong magic number: 0x%08X for plane %d, band %d\n", magic, plane, i); + av_log(avctx, AV_LOG_ERROR, "wrong magic number: 0x%08"PRIX32 + " for plane %d, band %d\n", magic, plane, i); return AVERROR_INVALIDDATA; } @@ -575,7 +576,7 @@ static int pixlet_decode_frame(AVCodecContext *avctx, void *data, pktsize = bytestream2_get_be32(&ctx->gb); if (pktsize <= 44 || pktsize - 4 > bytestream2_get_bytes_left(&ctx->gb)) { - av_log(avctx, AV_LOG_ERROR, "Invalid packet size %u.\n", pktsize); + av_log(avctx, AV_LOG_ERROR, "Invalid packet size %"PRIu32"\n", pktsize); return AVERROR_INVALIDDATA; } diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c index ff90d12c5c1ac..3157c11da11ce 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -491,7 +491,8 @@ static int read_header(ShortenContext *s) if ((ret = decode_aiff_header(s->avctx, s->header, s->header_size)) < 0) return ret; } else { - avpriv_report_missing_feature(s->avctx, "unsupported bit packing %X", AV_RL32(s->header)); + avpriv_report_missing_feature(s->avctx, "unsupported bit packing %" + PRIX32, AV_RL32(s->header)); return AVERROR_PATCHWELCOME; } diff --git a/libavcodec/tiff_common.c b/libavcodec/tiff_common.c index 35119af558b64..0af62ee96219a 100644 --- a/libavcodec/tiff_common.c +++ b/libavcodec/tiff_common.c @@ -97,7 +97,7 @@ int ff_tadd_rational_metadata(int count, const char *name, const char *sep, for (i = 0; i < count; i++) { nom = ff_tget_long(gb, le); denom = ff_tget_long(gb, le); - av_bprintf(&bp, "%s%7i:%-7i", auto_sep(count, sep, i, 4), nom, denom); + av_bprintf(&bp, "%s%7"PRId32":%-7"PRId32, auto_sep(count, sep, i, 4), nom, denom); } if ((i = av_bprint_finalize(&bp, &ap))) { diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c index 0a5eaa68794bc..bc6c5875c2e80 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -731,7 +731,7 @@ static int vorbis_parse_setup_hdr_residues(vorbis_context *vc) if (!res_setup->classifs) return AVERROR(ENOMEM); - ff_dlog(NULL, " begin %d end %d part.size %d classif.s %d classbook %d \n", + ff_dlog(NULL, " begin %"PRIu32" end %"PRIu32" part.size %d classif.s %d classbook %d \n", res_setup->begin, res_setup->end, res_setup->partition_size, res_setup->classifications, res_setup->classbook); @@ -876,7 +876,7 @@ static int create_map(vorbis_context *vc, unsigned floor_number) } for (idx = 0; idx <= n; ++idx) { - ff_dlog(NULL, "floor0 map: map at pos %d is %d\n", idx, map[idx]); + ff_dlog(NULL, "floor0 map: map at pos %d is %"PRId32"\n", idx, map[idx]); } return 0; @@ -1012,7 +1012,7 @@ static int vorbis_parse_id_hdr(vorbis_context *vc) if (!vc->fdsp) return AVERROR(ENOMEM); - ff_dlog(NULL, " vorbis version %d \n audio_channels %d \n audio_samplerate %d \n bitrate_max %d \n bitrate_nom %d \n bitrate_min %d \n blk_0 %d blk_1 %d \n ", + ff_dlog(NULL, " vorbis version %"PRIu32" \n audio_channels %"PRIu8" \n audio_samplerate %"PRIu32" \n bitrate_max %"PRIu32" \n bitrate_nom %"PRIu32" \n bitrate_min %"PRIu32" \n blk_0 %"PRIu32" blk_1 %"PRIu32" \n ", vc->version, vc->audio_channels, vc->audio_samplerate, vc->bitrate_maximum, vc->bitrate_nominal, vc->bitrate_minimum, vc->blocksize[0], vc->blocksize[1]); /* diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index 5b1fe40a422e3..5c99628c52d28 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -701,7 +701,7 @@ static int decode_tilehdr(WMAProDecodeCtx *s) int i; int offset = 0; for (i = 0; i < s->channel[c].num_subframes; i++) { - ff_dlog(s->avctx, "frame[%i] channel[%i] subframe[%i]" + ff_dlog(s->avctx, "frame[%"PRIu32"] channel[%i] subframe[%i]" " len %i\n", s->frame_num, c, i, s->channel[c].subframe_len[i]); s->channel[c].subframe_offset[i] = offset; diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c index 1248fd9b75897..2800ed9d80857 100644 --- a/libavfilter/af_hdcd.c +++ b/libavfilter/af_hdcd.c @@ -1077,7 +1077,8 @@ static int hdcd_integrate(HDCDContext *ctx, hdcd_state *states, int channels, in /* one of bits 3, 6, or 7 was not 0 */ states[i].code_counterA_almost++; av_log(ctx->fctx, AV_LOG_VERBOSE, - "hdcd error: Control A almost: 0x%02x near %d\n", wbits & 0xff, ctx->sample_count); + "hdcd error: Control A almost: 0x%02"PRIx32" near %d\n", + wbits & 0xff, ctx->sample_count); } } else if ((wbits & 0xa0060000) == 0xa0060000) { /* B: 8-bit code, 8-bit XOR check, 0x7e0fa006[....] */ @@ -1091,7 +1092,9 @@ static int hdcd_integrate(HDCDContext *ctx, hdcd_state *states, int channels, in /* XOR check failed */ states[i].code_counterB_checkfails++; av_log(ctx->fctx, AV_LOG_VERBOSE, - "hdcd error: Control B check failed: 0x%04x (0x%02x vs 0x%02x) near %d\n", wbits & 0xffff, (wbits & 0xff00) >> 8, ~wbits & 0xff, ctx->sample_count); + "hdcd error: Control B check failed: 0x%04"PRIx32 + " (0x%02"PRIx32" vs 0x%02"PRIx32") near %d\n", + wbits & 0xffff, (wbits & 0xff00) >> 8, ~wbits & 0xff, ctx->sample_count); } } if (f) { diff --git a/libavfilter/f_perms.c b/libavfilter/f_perms.c index 40b8811149523..da11d506a76e9 100644 --- a/libavfilter/f_perms.c +++ b/libavfilter/f_perms.c @@ -64,7 +64,7 @@ static av_cold int init(AVFilterContext *ctx) if (s->random_seed == -1) s->random_seed = av_get_random_seed(); seed = s->random_seed; - av_log(ctx, AV_LOG_INFO, "random seed: 0x%08x\n", seed); + av_log(ctx, AV_LOG_INFO, "random seed: 0x%08"PRIx32"\n", seed); av_lfg_init(&s->lfg, seed); } diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c index 5e69873b4cf76..b470079ccc8f0 100644 --- a/libavfilter/vf_palettegen.c +++ b/libavfilter/vf_palettegen.c @@ -239,7 +239,7 @@ static void write_palette(AVFilterContext *ctx, AVFrame *out) if (box_id < s->nb_boxes) { pal[x] = s->boxes[box_id++].color; if ((x || y) && pal[x] == last_color) - av_log(ctx, AV_LOG_WARNING, "Dupped color: %08X\n", pal[x]); + av_log(ctx, AV_LOG_WARNING, "Dupped color: %08"PRIX32"\n", pal[x]); last_color = pal[x]; } else { pal[x] = 0xff000000; // pad with black diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c index 69d3be92da8c3..e8dde572cdc19 100644 --- a/libavfilter/vf_paletteuse.c +++ b/libavfilter/vf_paletteuse.c @@ -491,7 +491,7 @@ static void disp_node(AVBPrint *buf, av_bprintf(buf, "%*cnode%d [" "label=\"%c%02X%c%02X%c%02X%c\" " "fillcolor=\"#%02x%02x%02x\" " - "fontcolor=\"#%06X\"]\n", + "fontcolor=\"#%06"PRIX32"\"]\n", depth*INDENT, ' ', node->palette_id, "[ "[node->split], node->val[0], "][ "[node->split], node->val[1], @@ -552,7 +552,7 @@ static int debug_accuracy(const struct color_node *node, const uint32_t *palette const int d2 = diff(palrgb2, rgb); if (d1 != d2) { av_log(NULL, AV_LOG_ERROR, - "/!\\ %02X%02X%02X: %d ! %d (%06X ! %06X) / dist: %d ! %d\n", + "/!\\ %02X%02X%02X: %d ! %d (%06"PRIX32" ! %06"PRIX32") / dist: %d ! %d\n", r, g, b, r1, r2, c1 & 0xffffff, c2 & 0xffffff, d1, d2); ret = 1; } diff --git a/libavfilter/vsrc_cellauto.c b/libavfilter/vsrc_cellauto.c index 4961f762f4268..afdceff7f1060 100644 --- a/libavfilter/vsrc_cellauto.c +++ b/libavfilter/vsrc_cellauto.c @@ -199,7 +199,7 @@ static av_cold int init(AVFilterContext *ctx) } av_log(ctx, AV_LOG_VERBOSE, - "s:%dx%d r:%d/%d rule:%d stitch:%d scroll:%d full:%d seed:%u\n", + "s:%dx%d r:%d/%d rule:%d stitch:%d scroll:%d full:%d seed:%"PRIu32"\n", s->w, s->h, s->frame_rate.num, s->frame_rate.den, s->rule, s->stitch, s->scroll, s->start_full, s->random_seed); diff --git a/libavfilter/vsrc_life.c b/libavfilter/vsrc_life.c index 8d510514870c7..afe805a67521e 100644 --- a/libavfilter/vsrc_life.c +++ b/libavfilter/vsrc_life.c @@ -260,7 +260,7 @@ static av_cold int init(AVFilterContext *ctx) } av_log(ctx, AV_LOG_VERBOSE, - "s:%dx%d r:%d/%d rule:%s stay_rule:%d born_rule:%d stitch:%d seed:%u\n", + "s:%dx%d r:%d/%d rule:%s stay_rule:%d born_rule:%d stitch:%d seed:%"PRIu32"\n", life->w, life->h, life->frame_rate.num, life->frame_rate.den, life->rule_str, life->stay_rule, life->born_rule, life->stitch, life->random_seed); diff --git a/libavformat/aadec.c b/libavformat/aadec.c index 39dea40b80b2c..8d39b1d9baa04 100644 --- a/libavformat/aadec.c +++ b/libavformat/aadec.c @@ -112,7 +112,8 @@ static int aa_read_header(AVFormatContext *s) header_seed = atoi(val); } else if (!strcmp(key, "HeaderKey")) { // this looks like "1234567890 1234567890 1234567890 1234567890" av_log(s, AV_LOG_DEBUG, "HeaderKey is <%s>\n", val); - sscanf(val, "%u%u%u%u", &header_key_part[0], &header_key_part[1], &header_key_part[2], &header_key_part[3]); + sscanf(val, "%"SCNu32"%"SCNu32"%"SCNu32"%"SCNu32, + &header_key_part[0], &header_key_part[1], &header_key_part[2], &header_key_part[3]); for (idx = 0; idx < 4; idx++) { AV_WB32(&header_key[idx * 4], header_key_part[idx]); // convert each part to BE! } diff --git a/libavformat/apngdec.c b/libavformat/apngdec.c index e1ea29b713c33..ffff03710a0e4 100644 --- a/libavformat/apngdec.c +++ b/libavformat/apngdec.c @@ -404,7 +404,7 @@ static int apng_read_packet(AVFormatContext *s, AVPacket *pkt) return ret; return 0; default: - avpriv_request_sample(s, "In-stream tag=%s (0x%08X) len=%"PRIu32, + avpriv_request_sample(s, "In-stream tag=%s (0x%08"PRIX32") len=%"PRIu32, av_fourcc2str(tag), tag, len); avio_skip(pb, len + 4); } diff --git a/libavformat/astdec.c b/libavformat/astdec.c index 7a53d0bb70800..4ba08c21807d3 100644 --- a/libavformat/astdec.c +++ b/libavformat/astdec.c @@ -102,7 +102,7 @@ static int ast_read_packet(AVFormatContext *s, AVPacket *pkt) pkt->stream_index = 0; pkt->pos = pos; } else { - av_log(s, AV_LOG_ERROR, "unknown chunk %x\n", type); + av_log(s, AV_LOG_ERROR, "unknown chunk %"PRIx32"\n", type); avio_skip(s->pb, size); ret = AVERROR_INVALIDDATA; } diff --git a/libavformat/brstm.c b/libavformat/brstm.c index 2e1cada158eda..87690e3f73e42 100644 --- a/libavformat/brstm.c +++ b/libavformat/brstm.c @@ -230,7 +230,7 @@ static int read_header(AVFormatContext *s) b->current_block = 0; b->block_count = read32(s); if (b->block_count > UINT16_MAX) { - av_log(s, AV_LOG_WARNING, "too many blocks: %u\n", b->block_count); + av_log(s, AV_LOG_WARNING, "too many blocks: %"PRIu32"\n", b->block_count); return AVERROR_INVALIDDATA; } diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 1f31968ab99d0..6232c70da243d 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -134,7 +134,7 @@ static void set_codec_str(AVFormatContext *s, AVCodecParameters *par, tags[0] = ff_mp4_obj_type; oti = av_codec_get_tag(tags, par->codec_id); if (oti) - av_strlcatf(str, size, ".%02x", oti); + av_strlcatf(str, size, ".%02"PRIx32, oti); else return; diff --git a/libavformat/dump.c b/libavformat/dump.c index 3e6218303d47e..7c811ce5d2bd7 100644 --- a/libavformat/dump.c +++ b/libavformat/dump.c @@ -421,7 +421,8 @@ static void dump_sidedata(void *ctx, AVStream *st, const char *indent) dump_audioservicetype(ctx, &sd); break; case AV_PKT_DATA_QUALITY_STATS: - av_log(ctx, AV_LOG_INFO, "quality factor: %d, pict_type: %c", AV_RL32(sd.data), av_get_picture_type_char(sd.data[4])); + av_log(ctx, AV_LOG_INFO, "quality factor: %"PRId32", pict_type: %c", + AV_RL32(sd.data), av_get_picture_type_char(sd.data[4])); break; case AV_PKT_DATA_CPB_PROPERTIES: av_log(ctx, AV_LOG_INFO, "cpb: "); diff --git a/libavformat/framecrcenc.c b/libavformat/framecrcenc.c index 91bcdcd99e259..a567b5299c83d 100644 --- a/libavformat/framecrcenc.c +++ b/libavformat/framecrcenc.c @@ -68,7 +68,7 @@ static int framecrc_write_packet(struct AVFormatContext *s, AVPacket *pkt) pkt->side_data[i].data, pkt->side_data[i].size); } - av_strlcatf(buf, sizeof(buf), ", %8d, 0x%08x", pkt->side_data[i].size, side_data_crc); + av_strlcatf(buf, sizeof(buf), ", %8d, 0x%08"PRIx32, pkt->side_data[i].size, side_data_crc); } } av_strlcatf(buf, sizeof(buf), "\n"); diff --git a/libavformat/ircamdec.c b/libavformat/ircamdec.c index a6b7a280f3daa..d376ffef63fe2 100644 --- a/libavformat/ircamdec.c +++ b/libavformat/ircamdec.c @@ -94,7 +94,7 @@ static int ircam_read_header(AVFormatContext *s) st->codecpar->codec_id = ff_codec_get_id(tags, tag); if (st->codecpar->codec_id == AV_CODEC_ID_NONE) { - av_log(s, AV_LOG_ERROR, "unknown tag %X\n", tag); + av_log(s, AV_LOG_ERROR, "unknown tag %"PRIx32"\n", tag); return AVERROR_INVALIDDATA; } diff --git a/libavformat/mov.c b/libavformat/mov.c index 14b85d0d25b34..127aec1d1d9a1 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -412,7 +412,7 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom) key = c->meta_keys[index]; } else { av_log(c->fc, AV_LOG_WARNING, - "The index of 'data' is out of range: %d < 1 or >= %d.\n", + "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n", index, c->meta_keys_count); } } @@ -686,7 +686,7 @@ static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom) avio_skip(pb, len); } } else { - av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08x size %d\n", + av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n", dref->type, size); entries--; i--; @@ -700,7 +700,7 @@ static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; uint32_t type; - uint32_t av_unused ctype; + uint32_t ctype; int64_t title_size; char *title_str; int ret; @@ -712,8 +712,8 @@ static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom) ctype = avio_rl32(pb); type = avio_rl32(pb); /* component subtype */ - av_log(c->fc, AV_LOG_TRACE, "ctype= %.4s (0x%08x)\n", (char*)&ctype, ctype); - av_log(c->fc, AV_LOG_TRACE, "stype= %.4s\n", (char*)&type); + av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype)); + av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type)); if (c->trak_index < 0) { // meta not inside a trak if (type == MKTAG('m','d','t','a')) { @@ -2284,8 +2284,8 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) id = mov_codec_id(st, format); av_log(c->fc, AV_LOG_TRACE, - "size=%"PRId64" 4CC=%s/0x%08x codec_type=%d\n", size, - av_fourcc2str(format), format, st->codecpar->codec_type); + "size=%"PRId64" 4CC=%s codec_type=%d\n", size, + av_fourcc2str(format), st->codecpar->codec_type); if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) { st->codecpar->codec_id = id; @@ -3816,7 +3816,7 @@ static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom) count = avio_rb32(pb); if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) { av_log(c->fc, AV_LOG_ERROR, - "The 'keys' atom with the invalid key count: %d\n", count); + "The 'keys' atom with the invalid key count: %"PRIu32"\n", count); return AVERROR_INVALIDDATA; } @@ -3830,7 +3830,8 @@ static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom) uint32_t type = avio_rl32(pb); if (key_size < 8) { av_log(c->fc, AV_LOG_ERROR, - "The key# %d in meta has invalid size: %d\n", i, key_size); + "The key# %"PRIu32" in meta has invalid size:" + "%"PRIu32"\n", i, key_size); return AVERROR_INVALIDDATA; } key_size -= 8; @@ -5379,8 +5380,8 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) total_size += 8; } } - av_log(c->fc, AV_LOG_TRACE, "type: %08x '%.4s' parent:'%.4s' sz: %"PRId64" %"PRId64" %"PRId64"\n", - a.type, (char*)&a.type, (char*)&atom.type, a.size, total_size, atom.size); + av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n", + av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size); if (a.size == 0) { a.size = atom.size - total_size + 8; } diff --git a/libavformat/mov_chan.c b/libavformat/mov_chan.c index dc8bf8dccc31f..324dd5f91394d 100644 --- a/libavformat/mov_chan.c +++ b/libavformat/mov_chan.c @@ -557,8 +557,9 @@ int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, bitmap = avio_rb32(pb); num_descr = avio_rb32(pb); - av_log(s, AV_LOG_TRACE, "chan: layout=%u bitmap=%u num_descr=%u\n", - layout_tag, bitmap, num_descr); + av_log(s, AV_LOG_TRACE, "chan: layout=%"PRIu32" " + "bitmap=%"PRIu32" num_descr=%"PRIu32"\n", + layout_tag, bitmap, num_descr); if (size < 12ULL + num_descr * 20ULL) return 0; diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 298d87290333a..a54aa879e903c 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -1716,7 +1716,7 @@ static int mov_write_gama_tag(AVIOContext *pb, MOVTrack *track, double gamma) if (gamma > 1e-6) { gama = (uint32_t)lrint((double)(1<<16) * gamma); - av_log(pb, AV_LOG_DEBUG, "writing gama value %d\n", gama); + av_log(pb, AV_LOG_DEBUG, "writing gama value %"PRId32"\n", gama); av_assert0(track->mode == MODE_MOV); avio_wb32(pb, 12); @@ -2378,8 +2378,8 @@ static int mov_write_hdlr_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra descr = "TimeCodeHandler"; } else { av_log(s, AV_LOG_WARNING, - "Unknown hldr_type for %s / 0x%04X, writing dummy values\n", - av_fourcc2str(track->par->codec_tag), track->par->codec_tag); + "Unknown hldr_type for %s, writing dummy values\n", + av_fourcc2str(track->par->codec_tag)); } if (track->st) { // hdlr.name is used by some players to identify the content title diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c index 034862261a00a..3cbf7bd13702e 100644 --- a/libavformat/mp3enc.c +++ b/libavformat/mp3enc.c @@ -319,7 +319,7 @@ static int mp3_write_audio_packet(AVFormatContext *s, AVPacket *pkt) if ((mpah.bit_rate == 0) || (mp3->initial_bitrate != mpah.bit_rate)) mp3->has_variable_bitrate = 1; } else { - av_log(s, AV_LOG_WARNING, "Audio packet of size %d (starting with %08X...) " + av_log(s, AV_LOG_WARNING, "Audio packet of size %d (starting with %08"PRIX32"...) " "is invalid, writing it anyway.\n", pkt->size, h); } diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 3250dde311edf..acea2e93a641c 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -1433,7 +1433,8 @@ int ff_check_h264_startcode(AVFormatContext *s, const AVStream *st, const AVPack return AVERROR_INVALIDDATA; } av_log(s, AV_LOG_WARNING, "H.264 bitstream error, startcode missing, size %d", pkt->size); - if (pkt->size) av_log(s, AV_LOG_WARNING, " data %08X", AV_RB32(pkt->data)); + if (pkt->size) + av_log(s, AV_LOG_WARNING, " data %08"PRIX32, AV_RB32(pkt->data)); av_log(s, AV_LOG_WARNING, "\n"); } return 0; @@ -1447,7 +1448,8 @@ static int check_hevc_startcode(AVFormatContext *s, const AVStream *st, const AV return AVERROR_PATCHWELCOME; } av_log(s, AV_LOG_WARNING, "HEVC bitstream error, startcode missing, size %d", pkt->size); - if (pkt->size) av_log(s, AV_LOG_WARNING, " data %08X", AV_RB32(pkt->data)); + if (pkt->size) + av_log(s, AV_LOG_WARNING, " data %08"PRIX32, AV_RB32(pkt->data)); av_log(s, AV_LOG_WARNING, "\n"); } return 0; @@ -1565,7 +1567,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) do { p = avpriv_find_start_code(p, buf_end, &state); - av_log(s, AV_LOG_TRACE, "nal %d\n", state & 0x1f); + av_log(s, AV_LOG_TRACE, "nal %"PRId32"\n", state & 0x1f); if ((state & 0x1f) == 7) extradd = 0; } while (p < buf_end && (state & 0x1f) != 9 && @@ -1631,7 +1633,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) do { p = avpriv_find_start_code(p, buf_end, &state); - av_log(s, AV_LOG_TRACE, "nal %d\n", (state & 0x7e)>>1); + av_log(s, AV_LOG_TRACE, "nal %"PRId32"\n", (state & 0x7e)>>1); if ((state & 0x7e) == 2*32) extradd = 0; } while (p < buf_end && (state & 0x7e) != 2*35 && diff --git a/libavformat/mux.c b/libavformat/mux.c index 424b3346c9477..e684385b4d68d 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -372,9 +372,8 @@ FF_ENABLE_DEPRECATION_WARNINGS if (!validate_codec_tag(s, st)) { const uint32_t otag = av_codec_get_tag(s->oformat->codec_tag, par->codec_id); av_log(s, AV_LOG_ERROR, - "Tag %s/0x%08x incompatible with output codec id '%d' (%s)\n", - av_fourcc2str(par->codec_tag), par->codec_tag, - par->codec_id, av_fourcc2str(otag)); + "Tag %s incompatible with output codec id '%d' (%s)\n", + av_fourcc2str(par->codec_tag), par->codec_id, av_fourcc2str(otag)); ret = AVERROR_INVALIDDATA; goto fail; } diff --git a/libavformat/nistspheredec.c b/libavformat/nistspheredec.c index 782d1dfbfbb94..55f22ebcf4f0e 100644 --- a/libavformat/nistspheredec.c +++ b/libavformat/nistspheredec.c @@ -89,7 +89,7 @@ static int nist_read_header(AVFormatContext *s) return 0; } else if (!memcmp(buffer, "channel_count", 13)) { - sscanf(buffer, "%*s %*s %"SCNd32, &st->codecpar->channels); + sscanf(buffer, "%*s %*s %u", &st->codecpar->channels); } else if (!memcmp(buffer, "sample_byte_format", 18)) { sscanf(buffer, "%*s %*s %31s", format); @@ -108,11 +108,11 @@ static int nist_read_header(AVFormatContext *s) } else if (!memcmp(buffer, "sample_count", 12)) { sscanf(buffer, "%*s %*s %"SCNd64, &st->duration); } else if (!memcmp(buffer, "sample_n_bytes", 14)) { - sscanf(buffer, "%*s %*s %"SCNd32, &bps); + sscanf(buffer, "%*s %*s %d", &bps); } else if (!memcmp(buffer, "sample_rate", 11)) { - sscanf(buffer, "%*s %*s %"SCNd32, &st->codecpar->sample_rate); + sscanf(buffer, "%*s %*s %d", &st->codecpar->sample_rate); } else if (!memcmp(buffer, "sample_sig_bits", 15)) { - sscanf(buffer, "%*s %*s %"SCNd32, &st->codecpar->bits_per_coded_sample); + sscanf(buffer, "%*s %*s %d", &st->codecpar->bits_per_coded_sample); } else { char key[32], value[32]; if (sscanf(buffer, "%31s %*s %31s", key, value) == 2) { diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c index ae179991cefe2..c6ddb67bbddcb 100644 --- a/libavformat/nsvdec.c +++ b/libavformat/nsvdec.c @@ -228,7 +228,7 @@ static int nsv_resync(AVFormatContext *s) v <<= 8; v |= avio_r8(pb); if (i < 8) { - av_log(s, AV_LOG_TRACE, "NSV resync: [%d] = %02x\n", i, v & 0x0FF); + av_log(s, AV_LOG_TRACE, "NSV resync: [%d] = %02"PRIx32"\n", i, v & 0x0FF); } if ((v & 0x0000ffff) == 0xefbe) { /* BEEF */ @@ -543,7 +543,7 @@ static int nsv_read_chunk(AVFormatContext *s, int fill_header) asize = avio_rl16(pb); vsize = (vsize << 4) | (auxcount >> 4); auxcount &= 0x0f; - av_log(s, AV_LOG_TRACE, "NSV CHUNK %d aux, %u bytes video, %d bytes audio\n", auxcount, vsize, asize); + av_log(s, AV_LOG_TRACE, "NSV CHUNK %d aux, %"PRIu32" bytes video, %d bytes audio\n", auxcount, vsize, asize); /* skip aux stuff */ for (i = 0; i < auxcount; i++) { uint32_t av_unused auxtag; diff --git a/libavformat/omaenc.c b/libavformat/omaenc.c index d89cc37ee0a76..7952808bf862b 100644 --- a/libavformat/omaenc.c +++ b/libavformat/omaenc.c @@ -84,8 +84,8 @@ static av_cold int oma_write_header(AVFormatContext *s) (par->block_align/8 - 1)); break; default: - av_log(s, AV_LOG_ERROR, "unsupported codec tag %d for write\n", - par->codec_tag); + av_log(s, AV_LOG_ERROR, "unsupported codec tag %s for write\n", + av_fourcc2str(par->codec_tag)); return AVERROR(EINVAL); } for (i = 0; i < (EA3_HEADER_SIZE - 36)/4; i++) diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c index 88c2b9abf9148..178eaea57d89d 100644 --- a/libavformat/rmdec.c +++ b/libavformat/rmdec.c @@ -380,7 +380,8 @@ int ff_rm_read_mdpr_codecdata(AVFormatContext *s, AVIOContext *pb, st->codecpar->codec_tag = avio_rl32(pb); st->codecpar->codec_id = ff_codec_get_id(ff_rm_codec_tags, st->codecpar->codec_tag); - av_log(s, AV_LOG_TRACE, "%X %X\n", st->codecpar->codec_tag, MKTAG('R', 'V', '2', '0')); + av_log(s, AV_LOG_TRACE, "%"PRIX32" %X\n", + st->codecpar->codec_tag, MKTAG('R', 'V', '2', '0')); if (st->codecpar->codec_id == AV_CODEC_ID_NONE) goto fail1; st->codecpar->width = avio_rb16(pb); diff --git a/libavformat/rpl.c b/libavformat/rpl.c index a794d3b48535d..d373600478600 100644 --- a/libavformat/rpl.c +++ b/libavformat/rpl.c @@ -170,8 +170,8 @@ static int rpl_read_header(AVFormatContext *s) vst->codecpar->codec_id = AV_CODEC_ID_ESCAPE130; break; default: - avpriv_report_missing_feature(s, "Video format %i", - vst->codecpar->codec_tag); + avpriv_report_missing_feature(s, "Video format %s", + av_fourcc2str(vst->codecpar->codec_tag)); vst->codecpar->codec_id = AV_CODEC_ID_NONE; } @@ -233,8 +233,8 @@ static int rpl_read_header(AVFormatContext *s) rpl->frames_per_chunk = read_line_and_int(pb, &error); // video frames per chunk if (rpl->frames_per_chunk > 1 && vst->codecpar->codec_tag != 124) av_log(s, AV_LOG_WARNING, - "Don't know how to split frames for video format %i. " - "Video stream will be broken!\n", vst->codecpar->codec_tag); + "Don't know how to split frames for video format %s. " + "Video stream will be broken!\n", av_fourcc2str(vst->codecpar->codec_tag)); number_of_chunks = read_line_and_int(pb, &error); // number of chunks in the file // The number in the header is actually the index of the last chunk. diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index eee17d07a6bbb..af631a883aa87 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -285,7 +285,7 @@ static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time, int bye) RTPMuxContext *s = s1->priv_data; uint32_t rtp_ts; - av_log(s1, AV_LOG_TRACE, "RTCP: %02x %"PRIx64" %x\n", s->payload_type, ntp_time, s->timestamp); + av_log(s1, AV_LOG_TRACE, "RTCP: %02x %"PRIx64" %"PRIx32"\n", s->payload_type, ntp_time, s->timestamp); s->last_rtcp_ntp_time = ntp_time; rtp_ts = av_rescale_q(ntp_time - s->first_rtcp_ntp_time, (AVRational){1, 1000000}, diff --git a/libavformat/srtdec.c b/libavformat/srtdec.c index 067db63f21560..56bd0c43f6902 100644 --- a/libavformat/srtdec.c +++ b/libavformat/srtdec.c @@ -78,7 +78,7 @@ static int get_event_info(const char *line, struct event_info *ei) ei->pts = AV_NOPTS_VALUE; ei->pos = -1; if (sscanf(line, "%d:%d:%d%*1[,.]%d --> %d:%d:%d%*1[,.]%d" - "%*[ ]X1:%u X2:%u Y1:%u Y2:%u", + "%*[ ]X1:%"PRId32" X2:%"PRId32" Y1:%"PRId32" Y2:%"PRId32, &hh1, &mm1, &ss1, &ms1, &hh2, &mm2, &ss2, &ms2, &ei->x1, &ei->x2, &ei->y1, &ei->y2) >= 8) { diff --git a/libavformat/uncodedframecrcenc.c b/libavformat/uncodedframecrcenc.c index 5e1a445f4fa13..ecc42d28695fb 100644 --- a/libavformat/uncodedframecrcenc.c +++ b/libavformat/uncodedframecrcenc.c @@ -115,7 +115,7 @@ static void audio_frame_cksum(AVBPrint *bp, AVFrame *frame) default: av_assert0(!"reached"); } - av_bprintf(bp, ", 0x%08x", cksum); + av_bprintf(bp, ", 0x%08"PRIx32, cksum); } } diff --git a/libavformat/westwood_vqa.c b/libavformat/westwood_vqa.c index 5a54f130a0a6d..efb9847ff0912 100644 --- a/libavformat/westwood_vqa.c +++ b/libavformat/westwood_vqa.c @@ -250,7 +250,8 @@ static int wsvqa_read_packet(AVFormatContext *s, case CMDS_TAG: break; default: - av_log(s, AV_LOG_INFO, "Skipping unknown chunk 0x%08X\n", chunk_type); + av_log(s, AV_LOG_INFO, "Skipping unknown chunk %s\n", + av_fourcc2str(av_bswap32(chunk_type))); } avio_skip(pb, chunk_size + skip_byte); } diff --git a/libavformat/xwma.c b/libavformat/xwma.c index 9235157a773a1..1c187729289b8 100644 --- a/libavformat/xwma.c +++ b/libavformat/xwma.c @@ -87,8 +87,9 @@ static int xwma_read_header(AVFormatContext *s) */ if (st->codecpar->codec_id != AV_CODEC_ID_WMAV2 && st->codecpar->codec_id != AV_CODEC_ID_WMAPRO) { - avpriv_request_sample(s, "Unexpected codec (tag 0x%04x; id %d)", - st->codecpar->codec_tag, st->codecpar->codec_id); + avpriv_request_sample(s, "Unexpected codec (tag %s; id %d)", + av_fourcc2str(st->codecpar->codec_tag), + st->codecpar->codec_id); } else { /* In all xWMA files I have seen, there is no extradata. But the WMA * codecs require extradata, so we provide our own fake extradata. diff --git a/libavutil/log.c b/libavutil/log.c index 44c11cb0917e8..be806202ffbb8 100644 --- a/libavutil/log.c +++ b/libavutil/log.c @@ -168,19 +168,19 @@ static void colored_fputs(int level, int tint, const char *str) #else if (local_use_color == 1) { fprintf(stderr, - "\033[%d;3%dm%s\033[0m", + "\033[%"PRIu32";3%"PRIu32"m%s\033[0m", (color[level] >> 4) & 15, color[level] & 15, str); } else if (tint && use_color == 256) { fprintf(stderr, - "\033[48;5;%dm\033[38;5;%dm%s\033[0m", + "\033[48;5;%"PRIu32"m\033[38;5;%dm%s\033[0m", (color[level] >> 16) & 0xff, tint, str); } else if (local_use_color == 256) { fprintf(stderr, - "\033[48;5;%dm\033[38;5;%dm%s\033[0m", + "\033[48;5;%"PRIu32"m\033[38;5;%"PRIu32"m%s\033[0m", (color[level] >> 16) & 0xff, (color[level] >> 8) & 0xff, str); diff --git a/libavutil/timecode.c b/libavutil/timecode.c index fa92df1ef98d5..c0c67c8478689 100644 --- a/libavutil/timecode.c +++ b/libavutil/timecode.c @@ -129,7 +129,8 @@ char *av_timecode_make_smpte_tc_string(char *buf, uint32_t tcsmpte, int prevent_ char *av_timecode_make_mpeg_tc_string(char *buf, uint32_t tc25bit) { - snprintf(buf, AV_TIMECODE_STR_SIZE, "%02u:%02u:%02u%c%02u", + snprintf(buf, AV_TIMECODE_STR_SIZE, + "%02"PRIu32":%02"PRIu32":%02"PRIu32"%c%02"PRIu32, tc25bit>>19 & 0x1f, // 5-bit hours tc25bit>>13 & 0x3f, // 6-bit minutes tc25bit>>6 & 0x3f, // 6-bit seconds From eaa67bb9c0595d2e2e7b555c38e864f5d6f851a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 29 Mar 2017 12:20:32 +0200 Subject: [PATCH 1379/3374] lavc/pthread_slice: remove pointless condition --- libavcodec/pthread_slice.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/libavcodec/pthread_slice.c b/libavcodec/pthread_slice.c index 96a7643f6a208..60f5b7889190a 100644 --- a/libavcodec/pthread_slice.c +++ b/libavcodec/pthread_slice.c @@ -156,11 +156,7 @@ static int thread_execute(AVCodecContext *avctx, action_func* func, void *arg, i c->job_size = job_size; c->args = arg; c->func = func; - if (ret) { - c->rets = ret; - } else { - c->rets = NULL; - } + c->rets = ret; c->current_execute++; pthread_cond_broadcast(&c->current_job_cond); From d467740f45eb20e217de6bc6b9c91d57d6f8a88e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 29 Mar 2017 15:07:29 +0200 Subject: [PATCH 1380/3374] lavc/idctdsp: use prefix restrict with av_ --- libavcodec/idctdsp.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/idctdsp.h b/libavcodec/idctdsp.h index 0b80aef50023d..f9ba6c3131430 100644 --- a/libavcodec/idctdsp.h +++ b/libavcodec/idctdsp.h @@ -53,13 +53,13 @@ int ff_init_scantable_permutation_x86(uint8_t *idct_permutation, typedef struct IDCTDSPContext { /* pixel ops : interface with DCT */ void (*put_pixels_clamped)(const int16_t *block /* align 16 */, - uint8_t *restrict pixels /* align 8 */, + uint8_t *av_restrict pixels /* align 8 */, ptrdiff_t line_size); void (*put_signed_pixels_clamped)(const int16_t *block /* align 16 */, - uint8_t *restrict pixels /* align 8 */, + uint8_t *av_restrict pixels /* align 8 */, ptrdiff_t line_size); void (*add_pixels_clamped)(const int16_t *block /* align 16 */, - uint8_t *restrict pixels /* align 8 */, + uint8_t *av_restrict pixels /* align 8 */, ptrdiff_t line_size); void (*idct)(int16_t *block /* align 16 */); From 247d0339ca5ddab692aee49baf43cd1324466028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 29 Mar 2017 16:09:28 +0200 Subject: [PATCH 1381/3374] lavfi/signature: fix -Wformat warnings raised by DJGPP This was forgotten due to the non-gpl build used in 549045254. --- libavfilter/signature_lookup.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/libavfilter/signature_lookup.c b/libavfilter/signature_lookup.c index 5bc2904409866..871a10ced9e5c 100644 --- a/libavfilter/signature_lookup.c +++ b/libavfilter/signature_lookup.c @@ -551,20 +551,27 @@ static MatchingInfo lookup_signatures(AVFilterContext *ctx, SignatureContext *sc if (find_next_coarsecandidate(sc, second->coarsesiglist, &cs, &cs2, 1) == 0) return bestmatch; /* no candidate found */ do { - av_log(ctx, AV_LOG_DEBUG, "Stage 1: got coarsesignature pair. indices of first frame: %d and %d\n", cs->first->index, cs2->first->index); + av_log(ctx, AV_LOG_DEBUG, "Stage 1: got coarsesignature pair. " + "indices of first frame: %"PRIu32" and %"PRIu32"\n", + cs->first->index, cs2->first->index); /* stage 2: l1-distance and hough-transform */ av_log(ctx, AV_LOG_DEBUG, "Stage 2: calculate matching parameters\n"); infos = get_matching_parameters(ctx, sc, cs->first, cs2->first); if (av_log_get_level() == AV_LOG_DEBUG) { for (i = infos; i != NULL; i = i->next) { - av_log(ctx, AV_LOG_DEBUG, "Stage 2: matching pair at %d and %d, ratio %f, offset %d\n", i->first->index, i->second->index, i->framerateratio, i->offset); + av_log(ctx, AV_LOG_DEBUG, "Stage 2: matching pair at %"PRIu32" and %"PRIu32", " + "ratio %f, offset %d\n", i->first->index, i->second->index, + i->framerateratio, i->offset); } } /* stage 3: evaluation */ av_log(ctx, AV_LOG_DEBUG, "Stage 3: evaluate\n"); if (infos) { bestmatch = evaluate_parameters(ctx, sc, infos, bestmatch, mode); - av_log(ctx, AV_LOG_DEBUG, "Stage 3: best matching pair at %d and %d, ratio %f, offset %d, score %d, %d frames matching\n", bestmatch.first->index, bestmatch.second->index, bestmatch.framerateratio, bestmatch.offset, bestmatch.score, bestmatch.matchframes); + av_log(ctx, AV_LOG_DEBUG, "Stage 3: best matching pair at %"PRIu32" and %"PRIu32", " + "ratio %f, offset %d, score %d, %d frames matching\n", + bestmatch.first->index, bestmatch.second->index, + bestmatch.framerateratio, bestmatch.offset, bestmatch.score, bestmatch.matchframes); sll_free(infos); } } while (find_next_coarsecandidate(sc, second->coarsesiglist, &cs, &cs2, 0) && !bestmatch.whole); From b4016ef31a6ea007e481427ade35ac35d1519170 Mon Sep 17 00:00:00 2001 From: Martin Vignali Date: Sat, 18 Mar 2017 18:24:55 +0100 Subject: [PATCH 1382/3374] avcodec/exr: add support for uint32 --- libavcodec/exr.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/libavcodec/exr.c b/libavcodec/exr.c index 034920ff6cc9f..ddce1e50f196e 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -3,7 +3,7 @@ * Copyright (c) 2006 Industrial Light & Magic, a division of Lucas Digital Ltd. LLC * Copyright (c) 2009 Jimmy Christensen * - * B44/B44A, Tile added by Jokyo Images support by CNC - French National Center for Cinema + * B44/B44A, Tile, UINT32 added by Jokyo Images support by CNC - French National Center for Cinema * * This file is part of FFmpeg. * @@ -1236,7 +1236,7 @@ static int decode_block(AVCodecContext *avctx, void *tdata, *ptr_x++ = exr_flt2uint(bytestream_get_le32(&a)); } } - } else { + } else if (s->pixel_type == EXR_HALF) { // 16-bit for (x = 0; x < td->xsize; x++) { int c; @@ -1247,6 +1247,15 @@ static int decode_block(AVCodecContext *avctx, void *tdata, if (channel_buffer[3]) *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&a)); } + } else if (s->pixel_type == EXR_UINT) { + for (x = 0; x < td->xsize; x++) { + for (c = 0; c < rgb_channel_count; c++) { + *ptr_x++ = bytestream_get_le32(&rgb[c]) >> 16; + } + + if (channel_buffer[3]) + *ptr_x++ = bytestream_get_le32(&a) >> 16; + } } // Zero out the end if xmax+1 is not w @@ -1648,6 +1657,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, switch (s->pixel_type) { case EXR_FLOAT: case EXR_HALF: + case EXR_UINT: if (s->channel_offsets[3] >= 0) { if (!s->is_luma) { avctx->pix_fmt = AV_PIX_FMT_RGBA64; @@ -1662,9 +1672,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, } } break; - case EXR_UINT: - avpriv_request_sample(avctx, "32-bit unsigned int"); - return AVERROR_PATCHWELCOME; default: av_log(avctx, AV_LOG_ERROR, "Missing channel list.\n"); return AVERROR_INVALIDDATA; From c14b3ea93c4f009a25ffa82452b5cf8b36a1bbbe Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 25 Mar 2017 13:47:15 -0300 Subject: [PATCH 1383/3374] ffprobe: fix printing packet side data information Signed-off-by: James Almer --- ffprobe.c | 4 ++-- tests/ref/fate/mov-aac-2048-priming | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ffprobe.c b/ffprobe.c index 77ea3494d2644..fa608948336f0 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -1856,12 +1856,12 @@ static void print_pkt_side_data(WriterContext *w, { int i; - writer_print_section_header(w, SECTION_ID_STREAM_SIDE_DATA_LIST); + writer_print_section_header(w, id_data_list); for (i = 0; i < nb_side_data; i++) { const AVPacketSideData *sd = &side_data[i]; const char *name = av_packet_side_data_name(sd->type); - writer_print_section_header(w, SECTION_ID_STREAM_SIDE_DATA); + writer_print_section_header(w, id_data); print_str("side_data_type", name ? name : "unknown"); if (sd->type == AV_PKT_DATA_DISPLAYMATRIX && sd->size >= 9*4) { writer_print_integers(w, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1); diff --git a/tests/ref/fate/mov-aac-2048-priming b/tests/ref/fate/mov-aac-2048-priming index 57e12f203d96a..2616944de343d 100644 --- a/tests/ref/fate/mov-aac-2048-priming +++ b/tests/ref/fate/mov-aac-2048-priming @@ -1,4 +1,4 @@ -packet|codec_type=audio|stream_index=0|pts=-2048|pts_time=-0.046440|dts=-2048|dts_time=-0.046440|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=258|pos=36|flags=KDside_data| +packet|codec_type=audio|stream_index=0|pts=-2048|pts_time=-0.046440|dts=-2048|dts_time=-0.046440|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=258|pos=36|flags=KDside_data|side_data_type=Skip Samples|skip_samples=2048|discard_padding=0|skip_reason=0|discard_reason=0 packet|codec_type=audio|stream_index=0|pts=-1024|pts_time=-0.023220|dts=-1024|dts_time=-0.023220|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=258|pos=294|flags=KD packet|codec_type=audio|stream_index=0|pts=0|pts_time=0.000000|dts=0|dts_time=0.000000|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=146|pos=552|flags=K_ From 5f019909c0e21e81646cdd43ef537e2e1404ccc4 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 28 Mar 2017 23:50:03 +0200 Subject: [PATCH 1384/3374] avfilter: Add AV_OPT_FLAG_FILTERING_PARAM where it is missing Signed-off-by: Michael Niedermayer --- libavfilter/vf_deinterlace_qsv.c | 2 +- libavfilter/vf_scale_qsv.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libavfilter/vf_deinterlace_qsv.c b/libavfilter/vf_deinterlace_qsv.c index bd43ef7bbaeb6..2810bffe461b8 100644 --- a/libavfilter/vf_deinterlace_qsv.c +++ b/libavfilter/vf_deinterlace_qsv.c @@ -527,7 +527,7 @@ static int qsvdeint_request_frame(AVFilterLink *outlink) } #define OFFSET(x) offsetof(QSVDeintContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM static const AVOption options[] = { { NULL }, }; diff --git a/libavfilter/vf_scale_qsv.c b/libavfilter/vf_scale_qsv.c index 8b262b68af8e4..a5f5be7d66d79 100644 --- a/libavfilter/vf_scale_qsv.c +++ b/libavfilter/vf_scale_qsv.c @@ -581,7 +581,7 @@ static int qsvscale_filter_frame(AVFilterLink *link, AVFrame *in) } #define OFFSET(x) offsetof(QSVScaleContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM static const AVOption options[] = { { "w", "Output video width", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str = "iw" }, .flags = FLAGS }, { "h", "Output video height", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str = "ih" }, .flags = FLAGS }, From ad7aff035517e0639c66f2003243c388450a86ac Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 30 Mar 2017 02:41:10 +0200 Subject: [PATCH 1385/3374] tests/fate/source-check: Use git grep in place of grep grep -L is not posix, solaris default grep does not support it Signed-off-by: Michael Niedermayer --- tests/fate/source-check.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fate/source-check.sh b/tests/fate/source-check.sh index f108d69c7b115..5f3fd8960e867 100755 --- a/tests/fate/source-check.sh +++ b/tests/fate/source-check.sh @@ -27,7 +27,7 @@ for f in `git ls-files | grep '\.h$'` ; do -e 's/_vaf_/_/' \ | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`" - grep -L "^#define $macro$" $f + git grep -L "^#define $macro$" $f done echo "Use of av_clip() where av_clip_uintp2() could be used:" From 744916908167951c8d3590bc8efeac0ffe35c1ee Mon Sep 17 00:00:00 2001 From: Leo Izen Date: Tue, 28 Mar 2017 17:07:47 -0400 Subject: [PATCH 1386/3374] avformat/nut: Add HEVC and Opus support Signed-off-by: Michael Niedermayer --- libavformat/nut.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavformat/nut.c b/libavformat/nut.c index 04776e249f015..592fe4dc28a9b 100644 --- a/libavformat/nut.c +++ b/libavformat/nut.c @@ -42,6 +42,7 @@ const AVCodecTag ff_nut_video_tags[] = { { AV_CODEC_ID_GIF, MKTAG('G', 'I', 'F', 0 ) }, { AV_CODEC_ID_XFACE, MKTAG('X', 'F', 'A', 'C') }, { AV_CODEC_ID_VP9, MKTAG('V', 'P', '9', '0') }, + { AV_CODEC_ID_HEVC, MKTAG('H', 'E', 'V', 'C') }, { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 15 ) }, { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 15 ) }, { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 16 ) }, @@ -201,6 +202,7 @@ const AVCodecTag ff_nut_audio_extra_tags[] = { { AV_CODEC_ID_PCM_ALAW, MKTAG('A', 'L', 'A', 'W') }, { AV_CODEC_ID_PCM_MULAW, MKTAG('U', 'L', 'A', 'W') }, { AV_CODEC_ID_MP3, MKTAG('M', 'P', '3', ' ') }, + { AV_CODEC_ID_OPUS, MKTAG('O', 'p', 'u', 's') }, { AV_CODEC_ID_WAVPACK, MKTAG('w', 'v', 'p', 'k') }, { AV_CODEC_ID_NONE, 0 } }; From b22c4d822b3315449ebb975a691f36933c14a00b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Thu, 30 Mar 2017 13:59:15 +0200 Subject: [PATCH 1387/3374] doc/codecs: add jedec-p22 --- doc/codecs.texi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/codecs.texi b/doc/codecs.texi index 6093605d20a01..1f74c83554411 100644 --- a/doc/codecs.texi +++ b/doc/codecs.texi @@ -1075,6 +1075,8 @@ SMPTE ST 428-1 SMPTE 431-2 @item smpte432 SMPTE 432-1 +@item jedec-p22 +JEDEC P22 @end table @item color_trc @var{integer} (@emph{decoding/encoding,video}) From afd257b43feb6ba60d823b65f02b283f404a7e13 Mon Sep 17 00:00:00 2001 From: Matthieu Bouron Date: Wed, 29 Mar 2017 14:58:01 +0200 Subject: [PATCH 1388/3374] doc/examples/filtering_video: switch to new decoding API --- doc/examples/filtering_video.c | 46 ++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/doc/examples/filtering_video.c b/doc/examples/filtering_video.c index 15116d3881f87..4d973024f181b 100644 --- a/doc/examples/filtering_video.c +++ b/doc/examples/filtering_video.c @@ -213,7 +213,6 @@ int main(int argc, char **argv) AVPacket packet; AVFrame *frame = av_frame_alloc(); AVFrame *filt_frame = av_frame_alloc(); - int got_frame; if (!frame || !filt_frame) { perror("Could not allocate frame"); @@ -238,33 +237,42 @@ int main(int argc, char **argv) break; if (packet.stream_index == video_stream_index) { - got_frame = 0; - ret = avcodec_decode_video2(dec_ctx, frame, &got_frame, &packet); + ret = avcodec_send_packet(dec_ctx, &packet); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error decoding video\n"); + av_log(NULL, AV_LOG_ERROR, "Error while sending a packet to the decoder\n"); break; } - if (got_frame) { - frame->pts = av_frame_get_best_effort_timestamp(frame); - - /* push the decoded frame into the filtergraph */ - if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0) { - av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n"); + while (ret >= 0) { + ret = avcodec_receive_frame(dec_ctx, frame); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { break; + } else if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error while receiving a frame from the decoder\n"); + goto end; } - /* pull filtered frames from the filtergraph */ - while (1) { - ret = av_buffersink_get_frame(buffersink_ctx, filt_frame); - if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + if (ret >= 0) { + frame->pts = av_frame_get_best_effort_timestamp(frame); + + /* push the decoded frame into the filtergraph */ + if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0) { + av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n"); break; - if (ret < 0) - goto end; - display_frame(filt_frame, buffersink_ctx->inputs[0]->time_base); - av_frame_unref(filt_frame); + } + + /* pull filtered frames from the filtergraph */ + while (1) { + ret = av_buffersink_get_frame(buffersink_ctx, filt_frame); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + break; + if (ret < 0) + goto end; + display_frame(filt_frame, buffersink_ctx->inputs[0]->time_base); + av_frame_unref(filt_frame); + } + av_frame_unref(frame); } - av_frame_unref(frame); } } av_packet_unref(&packet); From 03372d0a90c01ad4e74f7f35cb0022d6bc681575 Mon Sep 17 00:00:00 2001 From: Matthieu Bouron Date: Wed, 29 Mar 2017 16:25:24 +0200 Subject: [PATCH 1389/3374] doc/examples/filtering_audio: switch to new decoding API --- doc/examples/filtering_audio.c | 63 ++++++++++++++++------------------ 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/doc/examples/filtering_audio.c b/doc/examples/filtering_audio.c index c6a930ba8b620..679218c82fa35 100644 --- a/doc/examples/filtering_audio.c +++ b/doc/examples/filtering_audio.c @@ -216,10 +216,9 @@ static void print_frame(const AVFrame *frame) int main(int argc, char **argv) { int ret; - AVPacket packet0, packet; + AVPacket packet; AVFrame *frame = av_frame_alloc(); AVFrame *filt_frame = av_frame_alloc(); - int got_frame; if (!frame || !filt_frame) { perror("Could not allocate frame"); @@ -239,50 +238,48 @@ int main(int argc, char **argv) goto end; /* read all packets */ - packet0.data = NULL; - packet.data = NULL; while (1) { - if (!packet0.data) { - if ((ret = av_read_frame(fmt_ctx, &packet)) < 0) - break; - packet0 = packet; - } + if ((ret = av_read_frame(fmt_ctx, &packet)) < 0) + break; if (packet.stream_index == audio_stream_index) { - got_frame = 0; - ret = avcodec_decode_audio4(dec_ctx, frame, &got_frame, &packet); + ret = avcodec_send_packet(dec_ctx, &packet); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error decoding audio\n"); - continue; + av_log(NULL, AV_LOG_ERROR, "Error while sending a packet to the decoder\n"); + break; } - packet.size -= ret; - packet.data += ret; - if (got_frame) { - /* push the audio data from decoded frame into the filtergraph */ - if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, 0) < 0) { - av_log(NULL, AV_LOG_ERROR, "Error while feeding the audio filtergraph\n"); + while (ret >= 0) { + ret = avcodec_receive_frame(dec_ctx, frame); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { break; + } else if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error while receiving a frame from the decoder\n"); + goto end; } - /* pull filtered audio from the filtergraph */ - while (1) { - ret = av_buffersink_get_frame(buffersink_ctx, filt_frame); - if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + if (ret >= 0) { + /* push the audio data from decoded frame into the filtergraph */ + if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0) { + av_log(NULL, AV_LOG_ERROR, "Error while feeding the audio filtergraph\n"); break; - if (ret < 0) - goto end; - print_frame(filt_frame); - av_frame_unref(filt_frame); + } + + /* pull filtered audio from the filtergraph */ + while (1) { + ret = av_buffersink_get_frame(buffersink_ctx, filt_frame); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + break; + if (ret < 0) + goto end; + print_frame(filt_frame); + av_frame_unref(filt_frame); + } + av_frame_unref(frame); } } - - if (packet.size <= 0) - av_packet_unref(&packet0); - } else { - /* discard non-wanted packets */ - av_packet_unref(&packet0); } + av_packet_unref(&packet); } end: avfilter_graph_free(&filter_graph); From 8779ec91b22338ac916c48f5e6255570c44443b0 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 30 Mar 2017 15:58:32 +0200 Subject: [PATCH 1390/3374] avformat/mux: Check return code of av_packet_split_side_data() Fixes CID1403225 Signed-off-by: Michael Niedermayer --- libavformat/mux.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libavformat/mux.c b/libavformat/mux.c index e684385b4d68d..3a5e876913c4d 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -883,8 +883,11 @@ static int do_packet_auto_bsf(AVFormatContext *s, AVPacket *pkt) { #if FF_API_LAVF_MERGE_SD FF_DISABLE_DEPRECATION_WARNINGS - if (st->internal->nb_bsfcs) - av_packet_split_side_data(pkt); + if (st->internal->nb_bsfcs) { + ret = av_packet_split_side_data(pkt); + if (ret < 0) + av_log(s, AV_LOG_WARNING, "Failed to split side data before bitstream filter\n"); + } FF_ENABLE_DEPRECATION_WARNINGS #endif From 004f27f0fb6e8ebf6b4078c77d21b0f248a2213f Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 30 Mar 2017 16:13:22 +0200 Subject: [PATCH 1391/3374] ffmpeg: Fix avframe memleak Fixes CID1401674 Signed-off-by: Michael Niedermayer --- ffmpeg.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ffmpeg.c b/ffmpeg.c index 1a0e909fb0037..11faf0d4a8001 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -2176,8 +2176,10 @@ static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame) if (!av_fifo_space(ifilter->frame_queue)) { ret = av_fifo_realloc2(ifilter->frame_queue, 2 * av_fifo_size(ifilter->frame_queue)); - if (ret < 0) + if (ret < 0) { + av_frame_free(&tmp); return ret; + } } av_fifo_generic_write(ifilter->frame_queue, &tmp, sizeof(tmp), NULL); return 0; From 59b8c2a4e668d129dedfab696cd8c07f5103343c Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 30 Mar 2017 15:12:19 +0200 Subject: [PATCH 1392/3374] doc/examples/encode_audio: Favor a sample rate close to 44khz instead of the maximum sample rate This is an example, people will copy and use this. The maximum supported is quite unreasonable as a default choice Reviewed-by: Steven Liu Signed-off-by: Michael Niedermayer --- doc/examples/encode_audio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/examples/encode_audio.c b/doc/examples/encode_audio.c index 88d0a6fd46492..ba9ef6ddb8a48 100644 --- a/doc/examples/encode_audio.c +++ b/doc/examples/encode_audio.c @@ -62,7 +62,8 @@ static int select_sample_rate(const AVCodec *codec) p = codec->supported_samplerates; while (*p) { - best_samplerate = FFMAX(*p, best_samplerate); + if (!best_samplerate || abs(44100 - *p) < abs(44100 - best_samplerate)) + best_samplerate = *p; p++; } return best_samplerate; From 2104e3383fd1e9340c693451d9c7abb6501683ac Mon Sep 17 00:00:00 2001 From: Gyan Doshi Date: Thu, 23 Mar 2017 19:04:30 +0530 Subject: [PATCH 1393/3374] avfilter/avf_abitscope: Correct range for framerate Signed-off-by: Gyan Doshi Signed-off-by: Paul B Mahol (via IRC) --- libavfilter/avf_abitscope.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavfilter/avf_abitscope.c b/libavfilter/avf_abitscope.c index 4f5d4c7b1ca20..0f3e3594c1f31 100644 --- a/libavfilter/avf_abitscope.c +++ b/libavfilter/avf_abitscope.c @@ -46,8 +46,8 @@ typedef struct AudioBitScopeContext { #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM static const AVOption abitscope_options[] = { - { "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str="25"}, 0, 0, FLAGS }, - { "r", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str="25"}, 0, 0, FLAGS }, + { "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str="25"}, 0, INT_MAX, FLAGS }, + { "r", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str="25"}, 0, INT_MAX, FLAGS }, { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str="1024x256"}, 0, 0, FLAGS }, { "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str="1024x256"}, 0, 0, FLAGS }, { "colors", "set channels colors", OFFSET(colors), AV_OPT_TYPE_STRING, {.str = "red|green|blue|yellow|orange|lime|pink|magenta|brown" }, 0, 0, FLAGS }, From e976e68fc5513fea05b45556cbe959e6675dbe7d Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 30 Mar 2017 19:00:00 +0200 Subject: [PATCH 1394/3374] avcodec/atrac3: Check init_get_bits8() for failure This is more for correctness than actually fixing a missing error path Fixes CID1399967 Signed-off-by: Michael Niedermayer --- libavcodec/atrac3.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index 88ee9babcc790..6cdcdf19644e8 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -693,8 +693,10 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *databuf, /* set the bitstream reader at the start of the second Sound Unit */ - init_get_bits8(&q->gb, + ret = init_get_bits8(&q->gb, ptr1, q->decoded_bytes_buffer + js_block_align - ptr1); + if (ret < 0) + return ret; /* Fill the Weighting coeffs delay buffer */ memmove(q->weighting_delay[js_pair], &q->weighting_delay[js_pair][2], From 4064f3f0dfe71f6d378b9252a390f89c4315bf54 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 30 Mar 2017 22:15:21 +0200 Subject: [PATCH 1395/3374] avfilter/af_sofalizer: Fix bad shift Fixes CID1396835 Signed-off-by: Michael Niedermayer --- libavfilter/af_sofalizer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/af_sofalizer.c b/libavfilter/af_sofalizer.c index 5f0ab31a2ad08..252f524c231d2 100644 --- a/libavfilter/af_sofalizer.c +++ b/libavfilter/af_sofalizer.c @@ -450,7 +450,7 @@ static int get_speaker_pos(AVFilterContext *ctx, /* set speaker positions according to input channel configuration: */ for (m = 0, ch = 0; ch < n_conv && m < 64; m++) { - uint64_t mask = channels_layout & (1 << m); + uint64_t mask = channels_layout & (1ULL << m); switch (mask) { case AV_CH_FRONT_LEFT: azim[ch] = 30; break; From 4798237f01cf7f27e5528bbbfdc6ef40a0b50660 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 30 Mar 2017 22:21:29 +0200 Subject: [PATCH 1396/3374] avfilter/deshake_opencl: Remove redundant return Fixes: CID1396846 Signed-off-by: Michael Niedermayer --- libavfilter/deshake_opencl.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/libavfilter/deshake_opencl.c b/libavfilter/deshake_opencl.c index 91ae7d5859b58..877ec1dc03fba 100644 --- a/libavfilter/deshake_opencl.c +++ b/libavfilter/deshake_opencl.c @@ -194,7 +194,5 @@ int ff_opencl_deshake_process_inout_buf(AVFilterContext *ctx, AVFrame *in, AVFra deshake->opencl_ctx.cl_inbuf_size, 0, in->data,deshake->opencl_ctx.in_plane_size, deshake->opencl_ctx.plane_num); - if(ret < 0) - return ret; return ret; } From 855305fac2399c0d484f51be4e6bb67e520835e0 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 30 Mar 2017 22:24:47 +0200 Subject: [PATCH 1397/3374] avfilter/vf_minterpolate: Use dx and dy Fixes CID1396283 and CID1396284 Signed-off-by: Michael Niedermayer --- libavfilter/vf_minterpolate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_minterpolate.c b/libavfilter/vf_minterpolate.c index 3da696b15ecba..6c5c26400557d 100644 --- a/libavfilter/vf_minterpolate.c +++ b/libavfilter/vf_minterpolate.c @@ -654,7 +654,7 @@ static int cluster_mvs(MIContext *mi_ctx) dx = avg_x - mv_x; dy = avg_y - mv_y; - if (FFABS(avg_x - mv_x) > CLUSTER_THRESHOLD || FFABS(avg_y - mv_y) > CLUSTER_THRESHOLD) { + if (FFABS(dx) > CLUSTER_THRESHOLD || FFABS(dy) > CLUSTER_THRESHOLD) { for (d = 1; d < 5; d++) for (y = FFMAX(mb_y - d, 0); y < FFMIN(mb_y + d + 1, mi_ctx->b_height); y++) From fe46d92c15ca7bd35324ff667c433a06af8b845c Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 30 Mar 2017 22:12:12 +0200 Subject: [PATCH 1398/3374] avcodec/clearvideo: Do not lose the return code of decode_mb() Fixes CID1401671 Reviewed-by: Paul B Mahol Reviewed-by: Nicolas George Signed-off-by: Michael Niedermayer --- libavcodec/clearvideo.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libavcodec/clearvideo.c b/libavcodec/clearvideo.c index e2644e3090d11..437c459aa55b1 100644 --- a/libavcodec/clearvideo.c +++ b/libavcodec/clearvideo.c @@ -281,6 +281,7 @@ static int clv_decode_frame(AVCodecContext *avctx, void *data, uint32_t frame_type; int i, j; int ret; + int mb_ret = 0; bytestream2_init(&gb, buf, buf_size); if (avctx->codec_tag == MKTAG('C','L','V','1')) { @@ -312,7 +313,9 @@ static int clv_decode_frame(AVCodecContext *avctx, void *data, for (j = 0; j < c->mb_height; j++) { for (i = 0; i < c->mb_width; i++) { - ret |= decode_mb(c, i, j); + ret = decode_mb(c, i, j); + if (ret < 0) + mb_ret = ret; } } } else { @@ -323,7 +326,7 @@ static int clv_decode_frame(AVCodecContext *avctx, void *data, *got_frame = 1; - return ret < 0 ? ret : buf_size; + return mb_ret < 0 ? mb_ret : buf_size; } static av_cold int clv_decode_init(AVCodecContext *avctx) From 477ba8f9391f779b7927305c89b5c24120930925 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 30 Mar 2017 22:12:13 +0200 Subject: [PATCH 1399/3374] avfilter/af_chorus & aecho: Handle NULL return from av_strtok() Fixes CID1396260 Reviewed-by: Paul B Mahol Signed-off-by: Michael Niedermayer --- libavfilter/af_aecho.c | 3 ++- libavfilter/af_chorus.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libavfilter/af_aecho.c b/libavfilter/af_aecho.c index 82049e95411b9..cfaea3de43057 100644 --- a/libavfilter/af_aecho.c +++ b/libavfilter/af_aecho.c @@ -77,7 +77,8 @@ static void fill_items(char *item_str, int *nb_items, float *items) for (i = 0; i < *nb_items; i++) { char *tstr = av_strtok(p, "|", &saveptr); p = NULL; - new_nb_items += sscanf(tstr, "%f", &items[i]) == 1; + if (tstr) + new_nb_items += sscanf(tstr, "%f", &items[new_nb_items]) == 1; } *nb_items = new_nb_items; diff --git a/libavfilter/af_chorus.c b/libavfilter/af_chorus.c index c596164382df4..87c82900970ba 100644 --- a/libavfilter/af_chorus.c +++ b/libavfilter/af_chorus.c @@ -96,7 +96,8 @@ static void fill_items(char *item_str, int *nb_items, float *items) for (i = 0; i < *nb_items; i++) { char *tstr = av_strtok(p, "|", &saveptr); p = NULL; - new_nb_items += sscanf(tstr, "%f", &items[i]) == 1; + if (tstr) + new_nb_items += sscanf(tstr, "%f", &items[new_nb_items]) == 1; } *nb_items = new_nb_items; From bd8201566d754384105923bb1fb3bb3a5c08cc8b Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 30 Mar 2017 22:55:28 +0200 Subject: [PATCH 1400/3374] avformat/libopenmpt: Check for avio_size() failure Fixes CID1396850 Signed-off-by: Michael Niedermayer --- libavformat/libopenmpt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/libopenmpt.c b/libavformat/libopenmpt.c index 35fd28f5f4d36..a7e385959a6f1 100644 --- a/libavformat/libopenmpt.c +++ b/libavformat/libopenmpt.c @@ -73,7 +73,7 @@ static int read_header_openmpt(AVFormatContext *s) AVStream *st; OpenMPTContext *openmpt = s->priv_data; int64_t size = avio_size(s->pb); - if (!size) + if (size <= 0) return AVERROR_INVALIDDATA; char *buf = av_malloc(size); int ret; From 77a3c288bd57cb47aa8382ce57732775f6730519 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 30 Mar 2017 23:03:24 +0200 Subject: [PATCH 1401/3374] avformat/mov: Init ref_sc / ref_st to NULL This is more robust in case some change or corner case causes them to be dereferenced before being set Fixes CID1396274, CID1396275 Signed-off-by: Michael Niedermayer --- libavformat/mov.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 127aec1d1d9a1..e487e596343db 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -4338,8 +4338,8 @@ static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom) uint8_t version; unsigned i, track_id; AVStream *st = NULL; - AVStream *ref_st; - MOVStreamContext *sc, *ref_sc; + AVStream *ref_st = NULL; + MOVStreamContext *sc, *ref_sc = NULL; MOVFragmentIndex *index = NULL; MOVFragmentIndex **tmp; AVRational timescale; From afebf470ca73c17cc8393bfd7eeebfdf6809c2b8 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 30 Mar 2017 23:07:52 +0200 Subject: [PATCH 1402/3374] avutil/tests/dict: Check return of av_dict_parse_string() Fixes: CID1396402 Signed-off-by: Michael Niedermayer --- libavutil/tests/dict.c | 5 ++++- tests/ref/fate/dict | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/libavutil/tests/dict.c b/libavutil/tests/dict.c index 0039ba5ff96e2..56e98557a729b 100644 --- a/libavutil/tests/dict.c +++ b/libavutil/tests/dict.c @@ -35,12 +35,15 @@ static void test_separators(const AVDictionary *m, const char pair, const char v char vals[] = {val, '\0'}; char *buffer = NULL; + int ret; + av_dict_copy(&dict, m, 0); print_dict(dict); av_dict_get_string(dict, &buffer, val, pair); printf("%s\n", buffer); av_dict_free(&dict); - av_dict_parse_string(&dict, buffer, vals, pairs, 0); + ret = av_dict_parse_string(&dict, buffer, vals, pairs, 0); + printf("ret %d\n", ret); av_freep(&buffer); print_dict(dict); av_dict_free(&dict); diff --git a/tests/ref/fate/dict b/tests/ref/fate/dict index 837f7b02e50be..7205e4c8455c0 100644 --- a/tests/ref/fate/dict +++ b/tests/ref/fate/dict @@ -2,24 +2,31 @@ Testing av_dict_get_string() and av_dict_parse_string() aaa aaa b,b bbb c=c ccc ddd d,d eee e=e f,f f=f g=g g,g aaa=aaa,b\,b=bbb,c\=c=ccc,ddd=d\,d,eee=e\=e,f\,f=f\=f,g\=g=g\,g +ret 0 aaa aaa b,b bbb c=c ccc ddd d,d eee e=e f,f f=f g=g g,g aaa aaa bbb bbb ccc ccc \,='" \,='" aaa=aaa"bbb=bbb"ccc=ccc"\\,\=\'\"=\\,\=\'\" +ret 0 aaa aaa bbb bbb ccc ccc \,='" \,='" aaa aaa bbb bbb ccc ccc \,='" \,='" aaa=aaa'bbb=bbb'ccc=ccc'\\,\=\'"=\\,\=\'" +ret 0 aaa aaa bbb bbb ccc ccc \,='" \,='" aaa aaa bbb bbb ccc ccc \,='" \,='" aaa"aaa,bbb"bbb,ccc"ccc,\\\,=\'\""\\\,=\'\" +ret 0 aaa aaa bbb bbb ccc ccc \,='" \,='" aaa aaa bbb bbb ccc ccc \,='" \,='" aaa'aaa,bbb'bbb,ccc'ccc,\\\,=\'"'\\\,=\'" +ret 0 aaa aaa bbb bbb ccc ccc \,='" \,='" aaa aaa bbb bbb ccc ccc \,='" \,='" aaa"aaa'bbb"bbb'ccc"ccc'\\,=\'\""\\,=\'\" +ret 0 aaa aaa bbb bbb ccc ccc \,='" \,='" aaa aaa bbb bbb ccc ccc \,='" \,='" aaa'aaa"bbb'bbb"ccc'ccc"\\,=\'\"'\\,=\'\" +ret 0 aaa aaa bbb bbb ccc ccc \,='" \,='" Testing av_dict_set() From ebce1332285b16418dacb369defcfd7bae06d319 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Thu, 30 Mar 2017 22:58:59 +0100 Subject: [PATCH 1403/3374] pthread_frame: Propagate sw_pix_fmt across threads This is required by the VP9 hwaccels (both DXVA2 and VAAPI) when threads are enabled. Tested-by: Hendrik Leppkes --- libavcodec/pthread_frame.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 5b5f5fb289260..4e1ad9d686392 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -250,6 +250,7 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, dst->width = src->width; dst->height = src->height; dst->pix_fmt = src->pix_fmt; + dst->sw_pix_fmt = src->sw_pix_fmt; dst->coded_width = src->coded_width; dst->coded_height = src->coded_height; From 12bfed2fd9ed25cca3b9ad495197f63d466d130a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Fri, 31 Mar 2017 11:30:38 +0200 Subject: [PATCH 1404/3374] configure: remove redundant info Based on d1a91ebe4990001e0800ee9ac54ed2207e4f56ff --- configure | 3 --- 1 file changed, 3 deletions(-) diff --git a/configure b/configure index e90041e5e5d03..6d76cf7e1e929 100755 --- a/configure +++ b/configure @@ -6594,9 +6594,6 @@ echo "postprocessing support ${postproc-no}" echo "network support ${network-no}" echo "threading support ${thread_type-no}" echo "safe bitstream reader ${safe_bitstream_reader-no}" -echo "SDL2 support ${sdl2-no}" -echo "opencl enabled ${opencl-no}" -echo "JNI support ${jni-no}" echo "texi2html enabled ${texi2html-no}" echo "perl enabled ${perl-no}" echo "pod2man enabled ${pod2man-no}" From c217027c1173668c13b243c42e9b7c9d21c64170 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 31 Mar 2017 03:21:47 +0200 Subject: [PATCH 1405/3374] avcodec/mips: fix build Found-by: Shivraj Patil Suggested-by: "Ronald S. Bultje" Signed-off-by: Michael Niedermayer --- libavcodec/mips/hevcpred_mips.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/mips/hevcpred_mips.h b/libavcodec/mips/hevcpred_mips.h index 12f57a2a3c531..f22feff85e7cf 100644 --- a/libavcodec/mips/hevcpred_mips.h +++ b/libavcodec/mips/hevcpred_mips.h @@ -21,7 +21,7 @@ #ifndef AVCODEC_MIPS_HEVCPRED_MIPS_H #define AVCODEC_MIPS_HEVCPRED_MIPS_H -#include "libavcodec/hevcdsp.h" +#include "libavcodec/hevcpred.h" void ff_hevc_intra_pred_planar_0_msa(uint8_t *dst, const uint8_t *src_top, @@ -67,7 +67,7 @@ void ff_pred_intra_pred_angular_3_msa(uint8_t *dst, const uint8_t *src_left, ptrdiff_t stride, int c_idx, int mode); -void ff_intra_pred_8_16x16_msa(HEVCContext *s, int x0, int y0, int c_idx); -void ff_intra_pred_8_32x32_msa(HEVCContext *s, int x0, int y0, int c_idx); +void ff_intra_pred_8_16x16_msa(struct HEVCContext *s, int x0, int y0, int c_idx); +void ff_intra_pred_8_32x32_msa(struct HEVCContext *s, int x0, int y0, int c_idx); #endif // #ifndef AVCODEC_MIPS_HEVCPRED_MIPS_H From 5036e214b0e1028e035d628f7e7f89cb1ba6a0d6 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 30 Mar 2017 23:34:48 +0200 Subject: [PATCH 1406/3374] avfilter/vf_zoompan: Free out frame on error Fixes: CID1398578 Reviewed-by: Paul B Mahol Signed-off-by: Michael Niedermayer --- libavfilter/vf_zoompan.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libavfilter/vf_zoompan.c b/libavfilter/vf_zoompan.c index 136d6c83fdcac..53a0700e37a95 100644 --- a/libavfilter/vf_zoompan.c +++ b/libavfilter/vf_zoompan.c @@ -191,7 +191,7 @@ static int output_single_frame(AVFilterContext *ctx, AVFrame *in, double *var_va s->sws = sws_alloc_context(); if (!s->sws) { ret = AVERROR(ENOMEM); - return ret; + goto error; } for (k = 0; in->data[k]; k++) @@ -206,7 +206,7 @@ static int output_single_frame(AVFilterContext *ctx, AVFrame *in, double *var_va av_opt_set_int(s->sws, "sws_flags", SWS_BICUBIC, 0); if ((ret = sws_init_context(s->sws, NULL, NULL)) < 0) - return ret; + goto error; sws_scale(s->sws, (const uint8_t *const *)&input, in->linesize, 0, h, out->data, out->linesize); @@ -218,6 +218,9 @@ static int output_single_frame(AVFilterContext *ctx, AVFrame *in, double *var_va s->sws = NULL; s->current_frame++; return ret; +error: + av_frame_free(&out); + return ret; } static int filter_frame(AVFilterLink *inlink, AVFrame *in) From 55d53cb59380bebea79ae8f99d4e119b2b006629 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 30 Mar 2017 22:45:40 +0200 Subject: [PATCH 1407/3374] avfilter/avfiltergraph: Check for allocation failure in avfilter_graph_queue_command() Fixes: CID1396538 Reviewed-by: Paul B Mahol Signed-off-by: Michael Niedermayer --- libavfilter/avfiltergraph.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 75bd516896842..f7fbf119ebedf 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -1324,6 +1324,9 @@ int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const queue = &(*queue)->next; next = *queue; *queue = av_mallocz(sizeof(AVFilterCommand)); + if (!*queue) + return AVERROR(ENOMEM); + (*queue)->command = av_strdup(command); (*queue)->arg = av_strdup(arg); (*queue)->time = ts; From 1317a9f7aaab50b3f6109948f5c96c8fa701ad1e Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 31 Mar 2017 13:20:20 +0200 Subject: [PATCH 1408/3374] doc/APIchanges: Update --- doc/APIchanges | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index dba8a928dd2cc..6314937964a53 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -19,11 +19,11 @@ API changes, most recent first: Add av_hwframe_map() and associated AV_HWFRAME_MAP_* flags. Add av_hwframe_ctx_create_derived(). -2017-03-xx - xxxxxxx - lavu 55.52.100 - avutil.h +2017-03-29 - bfdcdd6d82 - lavu 55.52.100 - avutil.h add av_fourcc_make_string() function and av_fourcc2str() macro to replace av_get_codec_tag_string() from lavc. -2017-03-xx - xxxxxxx - lavf 57.68.100 - avformat.h +2017-03-27 - ddef3d902f - lavf 57.68.100 - avformat.h Deprecate that demuxers export the stream rotation angle in AVStream.metadata (via an entry named "rotate"). Use av_stream_get_side_data() with AV_PKT_DATA_DISPLAYMATRIX instead, and read the rotation angle with @@ -31,19 +31,19 @@ API changes, most recent first: "rotate" entry to AVStream.metadata, AV_PKT_DATA_DISPLAYMATRIX side data has to be added to the AVStream. -2017-03-xx - xxxxxxx - lavc 57.85.101 - avcodec.h +2017-03-23 - 7e4ba776a2 - lavc 57.85.101 - avcodec.h vdpau hardware accelerated decoding now supports the new hwaccel API, which can create the decoder context and allocate hardware frame automatically. See AVCodecContext.hw_device_ctx and AVCodecContext.hw_frames_ctx. -2017-03-xx - xxxxxxx - lavc 57.85.100 - avcodec.h +2017-03-23 - 156bd8278f - lavc 57.85.100 - avcodec.h Add AVCodecContext.hwaccel_flags field. This will control some hwaccels at a later point. 2017-03-21 - xxxxxxx - lavf 57.67.100 / 57.08.0 - avio.h Add AVIO_SEEKABLE_TIME flag. -2017-03-21 - xxxxxxx - lavf 57.66.105, lavc 57.83.101 - avformat.h, avcodec.h +2017-03-21 - d682ae70b4 - lavf 57.66.105, lavc 57.83.101 - avformat.h, avcodec.h Deprecate AVFMT_FLAG_KEEP_SIDE_DATA. It will be ignored after the next major bump, and libavformat will behave as if it were always set. Deprecate av_packet_merge_side_data() and av_packet_split_side_data(). @@ -55,7 +55,7 @@ API changes, most recent first: 2017-03-20 - 9c2436e - lavu 55.49.100 - pixdesc.h Add AV_PIX_FMT_FLAG_BAYER pixel format flag. -2017-03-18 - xxxxxxx - lavfi 6.77.100 - avfilter.h +2017-03-18 - 3796fb2692 - lavfi 6.77.100 - avfilter.h Deprecate AVFilterGraph.resample_lavr_opts It's never been used by avfilter nor passed to anything. @@ -64,38 +64,38 @@ API changes, most recent first: and projection-specific properties (bound_left, bound_top, bound_right, bound_bottom, padding) to AVSphericalMapping. -2017-03-02 - xxxxxxx - lavc 57.81.104 - videotoolbox.h +2017-03-02 - ade7c1a232 - lavc 57.81.104 - videotoolbox.h AVVideotoolboxContext.cv_pix_fmt_type can now be set to 0 to output the native decoder format. (The default value is not changed.) -2017-03-02 - xxxxxxx - lavu 55.47.101, lavc 57.81.102, lavf 57.66.103 +2017-03-02 - 554bc4eea8 - lavu 55.47.101, lavc 57.81.102, lavf 57.66.103 Remove requirement to use AVOption or accessors to access certain fields in AVFrame, AVCodecContext, and AVFormatContext that were previously documented as "no direct access" allowed. -2017-02-13 - xxxxxxx - lavc 57.80.100 - avcodec.h +2017-02-13 - c1a5fca06f - lavc 57.80.100 - avcodec.h Add AVCodecContext.hw_device_ctx. -2017-02-11 - xxxxxxx - lavu 55.47.100 - frame.h +2017-02-11 - e3af49b14b - lavu 55.47.100 - frame.h Add AVFrame.opaque_ref. 2017-01-31 - xxxxxxx - lavu 55.46.100 / 55.20.0 - cpu.h Add AV_CPU_FLAG_SSSE3SLOW. -2017-01-24 - xxxxxxx - lavu 55.45.100 - channel_layout.h +2017-01-24 - c4618f842a - lavu 55.45.100 - channel_layout.h Add av_get_extended_channel_layout() -2017-01-22 - xxxxxxx - lavu 55.44.100 - lfg.h +2017-01-22 - 76c5a69e26 - lavu 55.44.100 - lfg.h Add av_lfg_init_from_data(). -2017-01-xx - xxxxxxx - lavc 57.74.100 - vaapi.h +2017-01-17 - 2a4a8653b6 - lavc 57.74.100 - vaapi.h Deprecate struct vaapi_context and the vaapi.h installed header. Callers should set AVCodecContext.hw_frames_ctx instead. -2017-01-12 - xxxxxxx - lavfi 6.69.100- buffersink.h +2017-01-12 - dbe9dbed31 - lavfi 6.69.100- buffersink.h Add av_buffersink_get_*() functions. -2017-01-06 - xxxxxxx - lavf 57.62.100- avio.h +2017-01-06 - 9488032e10 - lavf 57.62.100- avio.h Add avio_get_dyn_buf() 2016-12-10 - xxxxxxx - lavu xx.xx.100- imgutils.h @@ -109,17 +109,17 @@ API changes, most recent first: Add AV_FRAME_DATA_SPHERICAL value, av_spherical_alloc() API and AVSphericalMapping type to export and describe spherical video properties. -2016-11-18 - xxxxxxx - lavf 57.58.100 - avformat.h +2016-11-18 - 2ab50647ff - lavf 57.58.100 - avformat.h Add av_stream_add_side_data(). -2016-xx-xx - xxxxxxx - lavu 55.39.100 - hwcontext_vaapi.h +2016-11-13 - 775a8477b7 - lavu 55.39.100 - hwcontext_vaapi.h Add AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE. -2016-xx-xx - xxxxxxx - lavu 55.38.100 - hwcontext_vaapi.h +2016-11-13 - a8d51bb424 - lavu 55.38.100 - hwcontext_vaapi.h Add driver quirks field to VAAPI-specific hwdevice and enum with members AV_VAAPI_DRIVER_QUIRK_* to represent its values. -2016-11-10 - xxxxxxx - lavu 55.36.100 - pixfmt.h +2016-11-10 - 638b216d4f - lavu 55.36.100 - pixfmt.h Add AV_PIX_FMT_GRAY12(LE/BE). -------- 8< --------- FFmpeg 3.2 was cut here -------- 8< --------- From fc332f3e29a07fea096b8878fa2044911366ebbd Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 31 Mar 2017 12:33:25 +0200 Subject: [PATCH 1409/3374] Bump minor versions for staring release/3.3 branch Signed-off-by: Michael Niedermayer --- libavcodec/version.h | 4 ++-- libavdevice/version.h | 4 ++-- libavfilter/version.h | 2 +- libavformat/version.h | 2 +- libavresample/version.h | 2 +- libavutil/version.h | 2 +- libpostproc/version.h | 2 +- libswresample/version.h | 2 +- libswscale/version.h | 4 ++-- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/libavcodec/version.h b/libavcodec/version.h index 5dbbc703ab0d4..d7159b9a07020 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 86 -#define LIBAVCODEC_VERSION_MICRO 104 +#define LIBAVCODEC_VERSION_MINOR 87 +#define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavdevice/version.h b/libavdevice/version.h index 74af12960458f..0dabfef2d1faf 100644 --- a/libavdevice/version.h +++ b/libavdevice/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVDEVICE_VERSION_MAJOR 57 -#define LIBAVDEVICE_VERSION_MINOR 3 -#define LIBAVDEVICE_VERSION_MICRO 101 +#define LIBAVDEVICE_VERSION_MINOR 4 +#define LIBAVDEVICE_VERSION_MICRO 100 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ LIBAVDEVICE_VERSION_MINOR, \ diff --git a/libavfilter/version.h b/libavfilter/version.h index 784fa391bca04..36a8fe1e9dea4 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 6 -#define LIBAVFILTER_VERSION_MINOR 79 +#define LIBAVFILTER_VERSION_MINOR 80 #define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavformat/version.h b/libavformat/version.h index ba2b912908c54..d4f7aefb820eb 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ // 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 57 -#define LIBAVFORMAT_VERSION_MINOR 68 +#define LIBAVFORMAT_VERSION_MINOR 69 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ diff --git a/libavresample/version.h b/libavresample/version.h index 42317943b774d..230b4d135da74 100644 --- a/libavresample/version.h +++ b/libavresample/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVRESAMPLE_VERSION_MAJOR 3 -#define LIBAVRESAMPLE_VERSION_MINOR 2 +#define LIBAVRESAMPLE_VERSION_MINOR 3 #define LIBAVRESAMPLE_VERSION_MICRO 0 #define LIBAVRESAMPLE_VERSION_INT AV_VERSION_INT(LIBAVRESAMPLE_VERSION_MAJOR, \ diff --git a/libavutil/version.h b/libavutil/version.h index fedc6fa17777e..27fd840a10ab9 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 54 +#define LIBAVUTIL_VERSION_MINOR 55 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ diff --git a/libpostproc/version.h b/libpostproc/version.h index 6f1a97a054ea8..857d76279836f 100644 --- a/libpostproc/version.h +++ b/libpostproc/version.h @@ -29,7 +29,7 @@ #include "libavutil/avutil.h" #define LIBPOSTPROC_VERSION_MAJOR 54 -#define LIBPOSTPROC_VERSION_MINOR 2 +#define LIBPOSTPROC_VERSION_MINOR 3 #define LIBPOSTPROC_VERSION_MICRO 100 #define LIBPOSTPROC_VERSION_INT AV_VERSION_INT(LIBPOSTPROC_VERSION_MAJOR, \ diff --git a/libswresample/version.h b/libswresample/version.h index 37d44dde4b938..64733cc77503b 100644 --- a/libswresample/version.h +++ b/libswresample/version.h @@ -29,7 +29,7 @@ #include "libavutil/avutil.h" #define LIBSWRESAMPLE_VERSION_MAJOR 2 -#define LIBSWRESAMPLE_VERSION_MINOR 4 +#define LIBSWRESAMPLE_VERSION_MINOR 5 #define LIBSWRESAMPLE_VERSION_MICRO 100 #define LIBSWRESAMPLE_VERSION_INT AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \ diff --git a/libswscale/version.h b/libswscale/version.h index 0d67738fa4ac4..e37b31f055a69 100644 --- a/libswscale/version.h +++ b/libswscale/version.h @@ -27,8 +27,8 @@ #include "libavutil/version.h" #define LIBSWSCALE_VERSION_MAJOR 4 -#define LIBSWSCALE_VERSION_MINOR 3 -#define LIBSWSCALE_VERSION_MICRO 101 +#define LIBSWSCALE_VERSION_MINOR 4 +#define LIBSWSCALE_VERSION_MICRO 100 #define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \ LIBSWSCALE_VERSION_MINOR, \ From 58b867a7cfea914aa6cad858a4da9b7dfeff9546 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 31 Mar 2017 12:35:26 +0200 Subject: [PATCH 1410/3374] Bump minor versions for master after release/3.3 branchpoint Signed-off-by: Michael Niedermayer --- RELEASE | 2 +- libavcodec/version.h | 2 +- libavdevice/version.h | 2 +- libavfilter/version.h | 2 +- libavformat/version.h | 2 +- libavresample/version.h | 2 +- libavutil/version.h | 2 +- libpostproc/version.h | 2 +- libswresample/version.h | 2 +- libswscale/version.h | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/RELEASE b/RELEASE index 9e15093aeb53e..48ea63d1809a3 100644 --- a/RELEASE +++ b/RELEASE @@ -1 +1 @@ -3.2.git +3.3.git diff --git a/libavcodec/version.h b/libavcodec/version.h index d7159b9a07020..27b0d48af2b88 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 87 +#define LIBAVCODEC_VERSION_MINOR 88 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ diff --git a/libavdevice/version.h b/libavdevice/version.h index 0dabfef2d1faf..d5aedf4e277ca 100644 --- a/libavdevice/version.h +++ b/libavdevice/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVDEVICE_VERSION_MAJOR 57 -#define LIBAVDEVICE_VERSION_MINOR 4 +#define LIBAVDEVICE_VERSION_MINOR 5 #define LIBAVDEVICE_VERSION_MICRO 100 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ diff --git a/libavfilter/version.h b/libavfilter/version.h index 36a8fe1e9dea4..d90e83e9a117c 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 6 -#define LIBAVFILTER_VERSION_MINOR 80 +#define LIBAVFILTER_VERSION_MINOR 81 #define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavformat/version.h b/libavformat/version.h index d4f7aefb820eb..894b7248612b2 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ // 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 57 -#define LIBAVFORMAT_VERSION_MINOR 69 +#define LIBAVFORMAT_VERSION_MINOR 70 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ diff --git a/libavresample/version.h b/libavresample/version.h index 230b4d135da74..37ad1ff1826a5 100644 --- a/libavresample/version.h +++ b/libavresample/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVRESAMPLE_VERSION_MAJOR 3 -#define LIBAVRESAMPLE_VERSION_MINOR 3 +#define LIBAVRESAMPLE_VERSION_MINOR 4 #define LIBAVRESAMPLE_VERSION_MICRO 0 #define LIBAVRESAMPLE_VERSION_INT AV_VERSION_INT(LIBAVRESAMPLE_VERSION_MAJOR, \ diff --git a/libavutil/version.h b/libavutil/version.h index 27fd840a10ab9..9d2a4e322be2f 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 55 +#define LIBAVUTIL_VERSION_MINOR 56 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ diff --git a/libpostproc/version.h b/libpostproc/version.h index 857d76279836f..a174017332f51 100644 --- a/libpostproc/version.h +++ b/libpostproc/version.h @@ -29,7 +29,7 @@ #include "libavutil/avutil.h" #define LIBPOSTPROC_VERSION_MAJOR 54 -#define LIBPOSTPROC_VERSION_MINOR 3 +#define LIBPOSTPROC_VERSION_MINOR 4 #define LIBPOSTPROC_VERSION_MICRO 100 #define LIBPOSTPROC_VERSION_INT AV_VERSION_INT(LIBPOSTPROC_VERSION_MAJOR, \ diff --git a/libswresample/version.h b/libswresample/version.h index 64733cc77503b..2e80552b492a2 100644 --- a/libswresample/version.h +++ b/libswresample/version.h @@ -29,7 +29,7 @@ #include "libavutil/avutil.h" #define LIBSWRESAMPLE_VERSION_MAJOR 2 -#define LIBSWRESAMPLE_VERSION_MINOR 5 +#define LIBSWRESAMPLE_VERSION_MINOR 6 #define LIBSWRESAMPLE_VERSION_MICRO 100 #define LIBSWRESAMPLE_VERSION_INT AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \ diff --git a/libswscale/version.h b/libswscale/version.h index e37b31f055a69..e026848dccf61 100644 --- a/libswscale/version.h +++ b/libswscale/version.h @@ -27,7 +27,7 @@ #include "libavutil/version.h" #define LIBSWSCALE_VERSION_MAJOR 4 -#define LIBSWSCALE_VERSION_MINOR 4 +#define LIBSWSCALE_VERSION_MINOR 5 #define LIBSWSCALE_VERSION_MICRO 100 #define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \ From ef71dc7948322254d1f0fa41218b91f2da0279d9 Mon Sep 17 00:00:00 2001 From: Sasi Inguva Date: Mon, 9 Jan 2017 09:23:38 -0800 Subject: [PATCH 1411/3374] lavf/mov.c: Add -advanced_editlist option for mov format. Adding an MOV format option to turn on/off the editlist supporting code, introduced in https://github.com/FFmpeg/FFmpeg/commit/ca6cae73db207f17a0d5507609de12842d8f0ca3 Signed-off-by: Sasi Inguva Signed-off-by: Michael Niedermayer --- libavformat/isom.h | 1 + libavformat/mov.c | 27 +++++++++++++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/libavformat/isom.h b/libavformat/isom.h index abcacab25a594..d9956cf63ac9b 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -234,6 +234,7 @@ typedef struct MOVContext { unsigned int nb_chapter_tracks; int use_absolute_path; int ignore_editlist; + int advanced_editlist; int ignore_chapters; int seek_individually; int64_t next_root_atom; ///< offset of the next root atom diff --git a/libavformat/mov.c b/libavformat/mov.c index e487e596343db..4550cf0ad4135 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -3309,7 +3309,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st) uint64_t stream_size = 0; if (sc->elst_count) { - int i, edit_start_index = 0; + int i, edit_start_index = 0, multiple_edits = 0; int64_t empty_duration = 0; // empty duration of the first edit list entry int64_t start_time = 0; // start time of the media @@ -3322,15 +3322,28 @@ static void mov_build_index(MOVContext *mov, AVStream *st) edit_start_index = 1; } else if (i == edit_start_index && e->time >= 0) { start_time = e->time; + } else { + multiple_edits = 1; } } + if (multiple_edits && !mov->advanced_editlist) + av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, " + "Use -advanced_editlist to correctly decode otherwise " + "a/v desync might occur\n"); + /* adjust first dts according to edit list */ if ((empty_duration || start_time) && mov->time_scale > 0) { if (empty_duration) empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale); sc->time_offset = start_time - empty_duration; + if (!mov->advanced_editlist) + current_dts = -sc->time_offset; } + + if (!multiple_edits && !mov->advanced_editlist && + st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0) + sc->start_pad = start_time; } /* only use old uncompressed audio chunk demuxing when stts specifies it */ @@ -3564,8 +3577,10 @@ static void mov_build_index(MOVContext *mov, AVStream *st) } } - // Fix index according to edit lists. - mov_fix_index(mov, st); + if (!mov->ignore_editlist && mov->advanced_editlist) { + // Fix index according to edit lists. + mov_fix_index(mov, st); + } } static int test_same_origin(const char *src, const char *ref) { @@ -6478,7 +6493,11 @@ static const AVOption mov_options[] = { "Seek each stream individually to the to the closest point", OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS}, - {"ignore_editlist", "", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0}, + {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0}, + 0, 1, FLAGS}, + {"advanced_editlist", + "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.", + OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, FLAGS}, {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, FLAGS}, From f800d6508d7e8fbd8d9777b775d333a4f02112ef Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 28 Mar 2017 19:37:42 -0400 Subject: [PATCH 1412/3374] dnxhd: initialize DNXHDContext::avctx to each thread's respective one. Otherwise all thread's private contexts have the avctx pointer set to the AVCodecContext of the first thread, which means all writes to ctx->avctx->* (in e.g. read_header) are effectively race conditions. Fixes fate-dnxhd under tsan. --- libavcodec/dnxhddec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c index f67763ef47e8f..383e64ca9e07a 100644 --- a/libavcodec/dnxhddec.c +++ b/libavcodec/dnxhddec.c @@ -145,6 +145,7 @@ static av_cold int dnxhd_decode_init_thread_copy(AVCodecContext *avctx) { DNXHDContext *ctx = avctx->priv_data; + ctx->avctx = avctx; // make sure VLC tables will be loaded when cid is parsed ctx->cid = -1; From 9e2050b698b204bcc4af39e014b3e621294a114a Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 28 Mar 2017 19:40:59 -0400 Subject: [PATCH 1413/3374] codec_desc: mark fraps as an intra-only codec. Fixes reported race conditions by tsan in fate-avio-direct. --- libavcodec/codec_desc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 4e98cf954903b..9711019e9d1d8 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -520,7 +520,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_VIDEO, .name = "fraps", .long_name = NULL_IF_CONFIG_SMALL("Fraps"), - .props = AV_CODEC_PROP_LOSSLESS, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_TRUEMOTION2, From 73f863d751df84db7a0ca1bd83cdff1b95dc94dd Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 28 Mar 2017 19:52:07 -0400 Subject: [PATCH 1414/3374] fic: set pict_type/key_frame after (instead of during) slice decoding. This fixes a race condition that was already documented in the source code, and is also reported by tsan in fate-fic-avi. --- libavcodec/fic.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/libavcodec/fic.c b/libavcodec/fic.c index d3952a4c0154d..2bec3d7b03a93 100644 --- a/libavcodec/fic.c +++ b/libavcodec/fic.c @@ -34,6 +34,7 @@ typedef struct FICThreadContext { int slice_h; int src_size; int y_off; + int p_frame; } FICThreadContext; typedef struct FICContext { @@ -133,16 +134,13 @@ static void fic_idct_put(uint8_t *dst, int stride, int16_t *block) } } static int fic_decode_block(FICContext *ctx, GetBitContext *gb, - uint8_t *dst, int stride, int16_t *block) + uint8_t *dst, int stride, int16_t *block, int *is_p) { int i, num_coeff; /* Is it a skip block? */ if (get_bits1(gb)) { - /* This is a P-frame. */ - ctx->frame->key_frame = 0; - ctx->frame->pict_type = AV_PICTURE_TYPE_P; - + *is_p = 1; return 0; } @@ -182,7 +180,8 @@ static int fic_decode_slice(AVCodecContext *avctx, void *tdata) for (x = 0; x < (ctx->aligned_width >> !!p); x += 8) { int ret; - if ((ret = fic_decode_block(ctx, &gb, dst + x, stride, tctx->block)) != 0) + if ((ret = fic_decode_block(ctx, &gb, dst + x, stride, + tctx->block, &tctx->p_frame)) != 0) return ret; } @@ -348,15 +347,6 @@ static int fic_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - /* - * Set the frametype to I initially. It will be set to P if the frame - * has any dependencies (skip blocks). There will be a race condition - * inside the slice decode function to set these, but we do not care. - * since they will only ever be set to 0/P. - */ - ctx->frame->key_frame = 1; - ctx->frame->pict_type = AV_PICTURE_TYPE_I; - /* Allocate slice data. */ av_fast_malloc(&ctx->slice_data, &ctx->slice_data_size, nslices * sizeof(ctx->slice_data[0])); @@ -398,6 +388,15 @@ static int fic_decode_frame(AVCodecContext *avctx, void *data, NULL, nslices, sizeof(ctx->slice_data[0]))) < 0) return ret; + ctx->frame->key_frame = 1; + ctx->frame->pict_type = AV_PICTURE_TYPE_I; + for (slice = 0; slice < nslices; slice++) { + if (ctx->slice_data[slice].p_frame) { + ctx->frame->key_frame = 0; + ctx->frame->pict_type = AV_PICTURE_TYPE_P; + break; + } + } av_frame_free(&ctx->final_frame); ctx->final_frame = av_frame_clone(ctx->frame); if (!ctx->final_frame) { From 081c21ca55d72921125848c8c2c191a6ff8b5f88 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 28 Mar 2017 20:11:43 -0400 Subject: [PATCH 1415/3374] lagarith: assign correct per-thread value to LagarithContext::avctx. This fixes race conditions reported by tsan in fate-lagarith. The races were because each thread's LagarithContext::avctx was set to the first thread's AVCodecContext. --- libavcodec/lagarith.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c index f03305fdd493a..469eec42327c8 100644 --- a/libavcodec/lagarith.c +++ b/libavcodec/lagarith.c @@ -730,6 +730,16 @@ static av_cold int lag_decode_init(AVCodecContext *avctx) return 0; } +#if HAVE_THREADS +static av_cold int lag_decode_init_thread_copy(AVCodecContext *avctx) +{ + LagarithContext *l = avctx->priv_data; + l->avctx = avctx; + + return 0; +} +#endif + static av_cold int lag_decode_end(AVCodecContext *avctx) { LagarithContext *l = avctx->priv_data; @@ -746,6 +756,7 @@ AVCodec ff_lagarith_decoder = { .id = AV_CODEC_ID_LAGARITH, .priv_data_size = sizeof(LagarithContext), .init = lag_decode_init, + .init_thread_copy = ONLY_IF_THREADS_ENABLED(lag_decode_init_thread_copy), .close = lag_decode_end, .decode = lag_decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, From b5300c8ad8c5384ab3654d6cb27693422bc424e7 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Wed, 29 Mar 2017 09:03:49 -0400 Subject: [PATCH 1416/3374] h264: don't write to source picture object in ff_h264_ref_picture(). Doing so is analogous to writing to source data in memcpy(), and causes (harmless) tsan warnings in fate-h264. --- libavcodec/h264_picture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/h264_picture.c b/libavcodec/h264_picture.c index f634d2a1a705a..db9673793a7b9 100644 --- a/libavcodec/h264_picture.c +++ b/libavcodec/h264_picture.c @@ -70,8 +70,8 @@ int ff_h264_ref_picture(H264Context *h, H264Picture *dst, H264Picture *src) av_assert0(!dst->f->buf[0]); av_assert0(src->f->buf[0]); + av_assert0(src->tf.f == src->f); - src->tf.f = src->f; dst->tf.f = dst->f; ret = ff_thread_ref_frame(&dst->tf, &src->tf); if (ret < 0) From 1ddc37051f11bd4bbadbcd17ea49b76a965d6a47 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Wed, 29 Mar 2017 09:33:47 -0400 Subject: [PATCH 1417/3374] h264: only assign H264Picture::mbaff for first slice. The value must be identical between slices, since mbaff depends on picture_structure and sps, both of which are checked to be identical to the first slice before this point. In practice, this silences some tsan warnings in fate-h264. --- libavcodec/h264_direct.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c index 4e7202b986d85..a7a107c8c2163 100644 --- a/libavcodec/h264_direct.c +++ b/libavcodec/h264_direct.c @@ -138,7 +138,11 @@ void ff_h264_direct_ref_list_init(const H264Context *const h, H264SliceContext * memcpy(cur->ref_poc[1], cur->ref_poc[0], sizeof(cur->ref_poc[0])); } - cur->mbaff = FRAME_MBAFF(h); + if (h->current_slice == 0) { + cur->mbaff = FRAME_MBAFF(h); + } else { + av_assert0(cur->mbaff == FRAME_MBAFF(h)); + } sl->col_fieldoff = 0; From 0505a1d9c4bec2e0e709dd6d9987b342b49a6360 Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 31 Mar 2017 11:31:41 -0300 Subject: [PATCH 1418/3374] doc/libav-merge: remove line about AC3 fixed decoder speedup It was addressed in commit 91ccd38c0befb17d788c1621d1d4362dc1c40bd6 --- doc/libav-merge.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/libav-merge.txt b/doc/libav-merge.txt index 44547c94e7057..9c904c3e9b45a 100644 --- a/doc/libav-merge.txt +++ b/doc/libav-merge.txt @@ -111,5 +111,4 @@ Extra changes needed to be aligned with Libav: ---------------------------------------------- - Switching our examples to the new encode/decode API (see 67d28f4a0f) -- AC3 speed-up for our fixed version (see a9ba59591e) - HEVC IDCT bit depth 12-bit support (Libav added 8 and 10 but doesn't have 12) From 76dd87c9296917bf6394b2a41820f92aeaeae447 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Fri, 31 Mar 2017 06:54:01 +0200 Subject: [PATCH 1419/3374] lavf/amr: Return AVERROR_EOF on EOF. Fixes ticket #6280. --- libavformat/amr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavformat/amr.c b/libavformat/amr.c index 59963e14b890b..b5194a2d9e3a7 100644 --- a/libavformat/amr.c +++ b/libavformat/amr.c @@ -118,7 +118,7 @@ static int amr_read_packet(AVFormatContext *s, AVPacket *pkt) AMRContext *amr = s->priv_data; if (avio_feof(s->pb)) { - return AVERROR(EIO); + return AVERROR_EOF; } // FIXME this is wrong, this should rather be in an AVParser @@ -156,6 +156,8 @@ static int amr_read_packet(AVFormatContext *s, AVPacket *pkt) if (read != size - 1) { av_packet_unref(pkt); + if (read < 0) + return read; return AVERROR(EIO); } From 9033e8723c86ed31872b22bd576602d48e2b9d0e Mon Sep 17 00:00:00 2001 From: James Almer Date: Tue, 28 Mar 2017 23:49:40 -0300 Subject: [PATCH 1420/3374] avutil/spherical: add av_spherical_projection_name() Reviewed-by: Benoit Fouet Reviewed-by: Vittorio Giovara Signed-off-by: James Almer --- doc/APIchanges | 4 ++++ libavutil/spherical.c | 27 +++++++++++++++++++++++++++ libavutil/spherical.h | 18 ++++++++++++++++++ libavutil/version.h | 2 +- 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index 6314937964a53..adff13385592f 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,10 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-03-31 - xxxxxxx - lavu 55.57.100 - spherical.h + Add av_spherical_projection_name(). + Add av_spherical_from_name(). + 2017-03-30 - xxxxxxx - lavu 55.53.100 / 55.27.0 - hwcontext.h Add av_hwframe_map() and associated AV_HWFRAME_MAP_* flags. Add av_hwframe_ctx_create_derived(). diff --git a/libavutil/spherical.c b/libavutil/spherical.c index f0b622128a57e..4be55f36cff99 100644 --- a/libavutil/spherical.c +++ b/libavutil/spherical.c @@ -50,3 +50,30 @@ void av_spherical_tile_bounds(const AVSphericalMapping *map, *right = orig_width - width - *left; *bottom = orig_height - height - *top; } + +static const char *spherical_projection_names[] = { + [AV_SPHERICAL_EQUIRECTANGULAR] = "equirectangular", + [AV_SPHERICAL_CUBEMAP] = "cubemap", + [AV_SPHERICAL_EQUIRECTANGULAR_TILE] = "tiled equirectangular", +}; + +const char *av_spherical_projection_name(enum AVSphericalProjection projection) +{ + if ((unsigned)projection >= FF_ARRAY_ELEMS(spherical_projection_names)) + return "unknown"; + + return spherical_projection_names[projection]; +} + +int av_spherical_from_name(const char *name) +{ + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(spherical_projection_names); i++) { + size_t len = strlen(spherical_projection_names[i]); + if (!strncmp(spherical_projection_names[i], name, len)) + return i; + } + + return -1; +} diff --git a/libavutil/spherical.h b/libavutil/spherical.h index a7952875af76e..cef759cf278bf 100644 --- a/libavutil/spherical.h +++ b/libavutil/spherical.h @@ -206,6 +206,24 @@ void av_spherical_tile_bounds(const AVSphericalMapping *map, size_t width, size_t height, size_t *left, size_t *top, size_t *right, size_t *bottom); + +/** + * Provide a human-readable name of a given AVSphericalProjection. + * + * @param projection The input AVSphericalProjection. + * + * @return The name of the AVSphericalProjection, or "unknown". + */ +const char *av_spherical_projection_name(enum AVSphericalProjection projection); + +/** + * Get the AVSphericalProjection form a human-readable name. + * + * @param name The input string. + * + * @return The AVSphericalProjection value, or -1 if not found. + */ +int av_spherical_from_name(const char *name); /** * @} * @} diff --git a/libavutil/version.h b/libavutil/version.h index 9d2a4e322be2f..d89a4187e8bb3 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 56 +#define LIBAVUTIL_VERSION_MINOR 57 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From 2efb70c37992b16b589e7405cd36e2f15a34c8ec Mon Sep 17 00:00:00 2001 From: James Almer Date: Tue, 28 Mar 2017 23:49:48 -0300 Subject: [PATCH 1421/3374] avformat/dump: use av_spherical_projection_name() to print spherical projection names Reviewed-by: Vittorio Giovara Signed-off-by: James Almer --- libavformat/dump.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/libavformat/dump.c b/libavformat/dump.c index 7c811ce5d2bd7..ef4a6b093bbc6 100644 --- a/libavformat/dump.c +++ b/libavformat/dump.c @@ -353,16 +353,7 @@ static void dump_spherical(void *ctx, AVCodecParameters *par, AVPacketSideData * return; } - if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR) - av_log(ctx, AV_LOG_INFO, "equirectangular "); - else if (spherical->projection == AV_SPHERICAL_CUBEMAP) - av_log(ctx, AV_LOG_INFO, "cubemap "); - else if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE) - av_log(ctx, AV_LOG_INFO, "tiled equirectangular "); - else { - av_log(ctx, AV_LOG_WARNING, "unknown"); - return; - } + av_log(ctx, AV_LOG_INFO, "%s ", av_spherical_projection_name(spherical->projection)); yaw = ((double)spherical->yaw) / (1 << 16); pitch = ((double)spherical->pitch) / (1 << 16); From 2a2854f57842e843ae0d4bd0ebe617135b2f63a0 Mon Sep 17 00:00:00 2001 From: James Almer Date: Tue, 28 Mar 2017 23:49:55 -0300 Subject: [PATCH 1422/3374] ffprobe: use av_spherical_projection_name() to print spherical projection names Reviewed-by: Vittorio Giovara Signed-off-by: James Almer --- ffprobe.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/ffprobe.c b/ffprobe.c index fa608948336f0..356746870e2d3 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -1872,22 +1872,18 @@ static void print_pkt_side_data(WriterContext *w, print_int("inverted", !!(stereo->flags & AV_STEREO3D_FLAG_INVERT)); } else if (sd->type == AV_PKT_DATA_SPHERICAL) { const AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data; - if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR) - print_str("projection", "equirectangular"); - else if (spherical->projection == AV_SPHERICAL_CUBEMAP) { - print_str("projection", "cubemap"); + print_str("projection", av_spherical_projection_name(spherical->projection)); + if (spherical->projection == AV_SPHERICAL_CUBEMAP) { print_int("padding", spherical->padding); } else if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE) { size_t l, t, r, b; av_spherical_tile_bounds(spherical, par->width, par->height, &l, &t, &r, &b); - print_str("projection", "tiled equirectangular"); print_int("bound_left", l); print_int("bound_top", t); print_int("bound_right", r); print_int("bound_bottom", b); - } else - print_str("projection", "unknown"); + } print_int("yaw", (double) spherical->yaw / (1 << 16)); print_int("pitch", (double) spherical->pitch / (1 << 16)); From 183635b9e96be0f4864e9e441b0aa93e8761b0ea Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 31 Mar 2017 15:31:50 -0300 Subject: [PATCH 1423/3374] doc/libav-merge: mention aac_adtstoasc extradata update fix for matroska --- doc/libav-merge.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/libav-merge.txt b/doc/libav-merge.txt index 9c904c3e9b45a..34d512bc916ac 100644 --- a/doc/libav-merge.txt +++ b/doc/libav-merge.txt @@ -98,6 +98,7 @@ Stuff that didn't reach the codebase: - Removal of the custom atomic API (5cc0057f49, see http://ffmpeg.org/pipermail/ffmpeg-devel/2017-March/209003.html) - Use the new bitstream filter for extracting extradata (see 8e2ea69135 and 096a8effa3) - ADD_RES_MMX_4_8 in libavcodec/x86/hevc_add_res.asm probably needs updating (see 589880710) +- Read aac_adtstoasc extradata updates from packet side data on Matroska once mov and the bsf in question are fixed (See 13a211e632 and 5ef1959080) Collateral damage that needs work locally: ------------------------------------------ From b27dd80255a0a5f22b02b512ba218ffb44f5902a Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 31 Mar 2017 16:50:39 -0300 Subject: [PATCH 1424/3374] doc/decode_audio: use <> to include libav* headers Found-by: ubitux --- doc/examples/decode_audio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/examples/decode_audio.c b/doc/examples/decode_audio.c index a24e0d0672d18..add0e313ae630 100644 --- a/doc/examples/decode_audio.c +++ b/doc/examples/decode_audio.c @@ -31,10 +31,10 @@ #include #include -#include "libavutil/frame.h" -#include "libavutil/mem.h" +#include +#include -#include "libavcodec/avcodec.h" +#include #define AUDIO_INBUF_SIZE 20480 #define AUDIO_REFILL_THRESH 4096 From 6426f74272c33a47cffd0ab0cc7b7a6b286af0ce Mon Sep 17 00:00:00 2001 From: Martin Vignali Date: Sat, 18 Mar 2017 13:45:06 +0100 Subject: [PATCH 1425/3374] fate/exr : add test for uint32 data Signed-off-by: Michael Niedermayer --- tests/fate/image.mak | 6 ++++++ tests/ref/fate/exr-rgb-scanline-b44-uint32 | 6 ++++++ tests/ref/fate/exr-rgb-scanline-pxr24-uint32 | 6 ++++++ 3 files changed, 18 insertions(+) create mode 100644 tests/ref/fate/exr-rgb-scanline-b44-uint32 create mode 100644 tests/ref/fate/exr-rgb-scanline-pxr24-uint32 diff --git a/tests/fate/image.mak b/tests/fate/image.mak index b299ea642d418..ef0495584b456 100644 --- a/tests/fate/image.mak +++ b/tests/fate/image.mak @@ -247,6 +247,12 @@ fate-exr-rgb-scanline-raw-half-float-l1: CMD = framecrc -i $(TARGET_SAMPLES)/exr FATE_EXR += fate-exr-rgb-scanline-raw-half-float-l2 fate-exr-rgb-scanline-raw-half-float-l2: CMD = framecrc -layer "VRaySamplerInfo" -i $(TARGET_SAMPLES)/exr/rgb_scanline_raw_half_float.exr -pix_fmt rgba64le +FATE_EXR += fate-exr-rgb-scanline-b44-uint32 +fate-exr-rgb-scanline-b44-uint32: CMD = framecrc -i $(TARGET_SAMPLES)/exr/rgb_scanline_b44_uint32.exr -pix_fmt rgb48le + +FATE_EXR += fate-exr-rgb-scanline-pxr24-uint32 +fate-exr-rgb-scanline-pxr24-uint32: CMD = framecrc -i $(TARGET_SAMPLES)/exr/rgb_scanline_pxr24_uint32.exr -pix_fmt rgb48le + FATE_EXR-$(call DEMDEC, IMAGE2, EXR) += $(FATE_EXR) FATE_IMAGE += $(FATE_EXR-yes) diff --git a/tests/ref/fate/exr-rgb-scanline-b44-uint32 b/tests/ref/fate/exr-rgb-scanline-b44-uint32 new file mode 100644 index 0000000000000..abe41b8a7a7cb --- /dev/null +++ b/tests/ref/fate/exr-rgb-scanline-b44-uint32 @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 12x8 +#sar 0: 1/1 +0, 0, 0, 1, 576, 0x6b950ce3 diff --git a/tests/ref/fate/exr-rgb-scanline-pxr24-uint32 b/tests/ref/fate/exr-rgb-scanline-pxr24-uint32 new file mode 100644 index 0000000000000..abe41b8a7a7cb --- /dev/null +++ b/tests/ref/fate/exr-rgb-scanline-pxr24-uint32 @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 12x8 +#sar 0: 1/1 +0, 0, 0, 1, 576, 0x6b950ce3 From b62a87591ebe57923bc9aabf487dbce0a7af2627 Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 31 Mar 2017 20:35:16 -0300 Subject: [PATCH 1426/3374] doc/libav-merge: link to the relevant ml thread in the extract_extradata line --- doc/libav-merge.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/libav-merge.txt b/doc/libav-merge.txt index 34d512bc916ac..0cbd9f4a90861 100644 --- a/doc/libav-merge.txt +++ b/doc/libav-merge.txt @@ -96,7 +96,7 @@ Stuff that didn't reach the codebase: - e7078e842 hevcdsp: add x86 SIMD for MC - VAAPI VP8 decode hwaccel (currently under review: http://ffmpeg.org/pipermail/ffmpeg-devel/2017-February/thread.html#207348) - Removal of the custom atomic API (5cc0057f49, see http://ffmpeg.org/pipermail/ffmpeg-devel/2017-March/209003.html) -- Use the new bitstream filter for extracting extradata (see 8e2ea69135 and 096a8effa3) +- Use the new bitstream filter for extracting extradata (8e2ea69135 and 096a8effa3, see https://ffmpeg.org/pipermail/ffmpeg-devel/2017-March/209068.html) - ADD_RES_MMX_4_8 in libavcodec/x86/hevc_add_res.asm probably needs updating (see 589880710) - Read aac_adtstoasc extradata updates from packet side data on Matroska once mov and the bsf in question are fixed (See 13a211e632 and 5ef1959080) From 6171f178e70ebe75e5964531f47ccc32455d5557 Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 31 Mar 2017 20:42:16 -0300 Subject: [PATCH 1427/3374] x86/hevc_add_res: merge last remaining changes from 3d6535983282bea542dac2e568ae50da5796be34 See https://lists.libav.org/pipermail/libav-devel/2016-October/079829.html --- doc/libav-merge.txt | 1 - libavcodec/x86/hevc_add_res.asm | 46 +++++++++++---------------------- 2 files changed, 15 insertions(+), 32 deletions(-) diff --git a/doc/libav-merge.txt b/doc/libav-merge.txt index 0cbd9f4a90861..30518c0a67337 100644 --- a/doc/libav-merge.txt +++ b/doc/libav-merge.txt @@ -97,7 +97,6 @@ Stuff that didn't reach the codebase: - VAAPI VP8 decode hwaccel (currently under review: http://ffmpeg.org/pipermail/ffmpeg-devel/2017-February/thread.html#207348) - Removal of the custom atomic API (5cc0057f49, see http://ffmpeg.org/pipermail/ffmpeg-devel/2017-March/209003.html) - Use the new bitstream filter for extracting extradata (8e2ea69135 and 096a8effa3, see https://ffmpeg.org/pipermail/ffmpeg-devel/2017-March/209068.html) -- ADD_RES_MMX_4_8 in libavcodec/x86/hevc_add_res.asm probably needs updating (see 589880710) - Read aac_adtstoasc extradata updates from packet side data on Matroska once mov and the bsf in question are fixed (See 13a211e632 and 5ef1959080) Collateral damage that needs work locally: diff --git a/libavcodec/x86/hevc_add_res.asm b/libavcodec/x86/hevc_add_res.asm index d97e4abddbc49..36d4d8e2e2e41 100644 --- a/libavcodec/x86/hevc_add_res.asm +++ b/libavcodec/x86/hevc_add_res.asm @@ -28,25 +28,23 @@ cextern pw_1023 ; the add_res macros and functions were largely inspired by h264_idct.asm from the x264 project %macro ADD_RES_MMX_4_8 0 - mova m2, [r1] - mova m4, [r1+8] + mova m0, [r1] + mova m2, [r1+8] + pxor m1, m1 pxor m3, m3 + psubw m1, m0 psubw m3, m2 - packuswb m2, m2 - packuswb m3, m3 - pxor m5, m5 - psubw m5, m4 - packuswb m4, m4 - packuswb m5, m5 - - movh m0, [r0] - movh m1, [r0+r2] + packuswb m0, m2 + packuswb m1, m3 + + movd m2, [r0] + movd m3, [r0+r2] + punpckldq m2, m3 paddusb m0, m2 - paddusb m1, m4 - psubusb m0, m3 - psubusb m1, m5 - movh [r0], m0 - movh [r0+r2], m1 + psubusb m0, m1 + movd [r0], m0 + psrlq m0, 32 + movd [r0+r2], m0 %endmacro @@ -95,15 +93,8 @@ cglobal hevc_add_residual_4_8, 3, 3, 6 vinserti128 m2, m2, [r1+%1+32], 1 vinserti128 m6, m6, [r1+%1+48], 1 %endif -%if cpuflag(avx) psubw m1, m0, m2 psubw m5, m0, m6 -%else - mova m1, m0 - mova m5, m0 - psubw m1, m2 - psubw m5, m6 -%endif packuswb m2, m6 packuswb m1, m5 @@ -113,15 +104,8 @@ cglobal hevc_add_residual_4_8, 3, 3, 6 vinserti128 m4, m4, [r1+%1+96 ], 1 vinserti128 m6, m6, [r1+%1+112], 1 %endif -%if cpuflag(avx) psubw m3, m0, m4 psubw m5, m0, m6 -%else - mova m3, m0 - mova m5, m0 - psubw m3, m4 - psubw m5, m6 -%endif packuswb m4, m6 packuswb m3, m5 @@ -192,7 +176,7 @@ cglobal hevc_add_residual_32_8, 3, 5, 7 dec r4d jg .loop RET -%endif +%endif ;HAVE_AVX2_EXTERNAL %macro ADD_RES_SSE_8_10 4 mova m0, [%4] From 99e5d81ef997cb88b1a40e6f253f37f7cbf251d9 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Sat, 1 Apr 2017 10:55:04 +0800 Subject: [PATCH 1428/3374] avutil/avstring: add av_strreplace API into avstring refer to: http://creativeandcritical.net/str-replace-c add av_strreplace API for replace string operations. Signed-off-by: Steven Liu --- libavutil/avstring.c | 77 ++++++++++++++++++++++++++++++++++++++++++++ libavutil/avstring.h | 5 +++ 2 files changed, 82 insertions(+) diff --git a/libavutil/avstring.c b/libavutil/avstring.c index 1787a1ef54f68..52e6e6cd139d2 100644 --- a/libavutil/avstring.c +++ b/libavutil/avstring.c @@ -231,6 +231,83 @@ int av_strncasecmp(const char *a, const char *b, size_t n) return c1 - c2; } +char *av_strreplace(const char *str, const char *from, const char *to) +{ + /* Adjust each of the below values to suit your needs. */ + /* Increment positions cache size initially by this number. */ + size_t cache_sz_inc = 16; + /* Thereafter, each time capacity needs to be increased, + * multiply the increment by this factor. */ + const size_t cache_sz_inc_factor = 3; + /* But never increment capacity by more than this number. */ + const size_t cache_sz_inc_max = 1048576; + + char *pret, *ret = NULL; + const char *pstr2, *pstr = str; + size_t i, count = 0; + uintptr_t *pos_cache_tmp, *pos_cache = NULL; + size_t cache_sz = 0; + size_t cpylen, orglen, retlen, tolen, fromlen = strlen(from); + + /* Find all matches and cache their positions. */ + while ((pstr2 = av_stristr(pstr, from))) { + count++; + /* Increase the cache size when necessary. */ + if (cache_sz < count) { + cache_sz += cache_sz_inc; + pos_cache_tmp = av_realloc(pos_cache, sizeof(*pos_cache) * cache_sz); + if (!pos_cache_tmp) { + goto end_strreplace; + } else pos_cache = pos_cache_tmp; + cache_sz_inc *= cache_sz_inc_factor; + if (cache_sz_inc > cache_sz_inc_max) { + cache_sz_inc = cache_sz_inc_max; + } + } + + pos_cache[count-1] = pstr2 - str; + pstr = pstr2 + fromlen; + } + orglen = pstr - str + strlen(pstr); + /* Allocate memory for the post-replacement string. */ + if (count > 0) { + tolen = strlen(to); + retlen = orglen + (tolen - fromlen) * count; + } else { + retlen = orglen; + } + ret = av_malloc(retlen + 1); + if (!ret) { + goto end_strreplace; + } + + if (!count) { + /* If no matches, then just duplicate the string. */ + av_strlcpy(ret, str, retlen + 1); + } else { + /* Otherwise, duplicate the string whilst performing + * the replacements using the position cache. */ + pret = ret; + memcpy(pret, str, pos_cache[0]); + pret += pos_cache[0]; + for (i = 0; i < count; i++) { + memcpy(pret, to, tolen); + pret += tolen; + pstr = str + pos_cache[i] + fromlen; + cpylen = (i == count-1 ? orglen : pos_cache[i+1]) - pos_cache[i] - fromlen; + memcpy(pret, pstr, cpylen); + pret += cpylen; + } + ret[retlen] = '\0'; + } + +end_strreplace: + /* Free the cache and return the post-replacement string, + * which will be NULL in the event of an error. */ + av_free(pos_cache); + return ret; +} + const char *av_basename(const char *path) { char *p = strrchr(path, '/'); diff --git a/libavutil/avstring.h b/libavutil/avstring.h index dd2876990f260..33be8bf484d17 100644 --- a/libavutil/avstring.h +++ b/libavutil/avstring.h @@ -266,6 +266,11 @@ int av_strcasecmp(const char *a, const char *b); */ int av_strncasecmp(const char *a, const char *b, size_t n); +/** + * Locale-independent strings replace. + * @note This means only ASCII-range characters are replace + */ +char *av_strreplace(const char *str, const char *from, const char *to); /** * Thread safe basename. From fa0a6ce34d00673c5a6efaf243308a21daa5f8b3 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Sat, 1 Apr 2017 01:09:19 +0200 Subject: [PATCH 1429/3374] configure: Fix GPL dependency for avisynth / avxsynth. --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 8b4921be3b6db..292766a2b1534 100755 --- a/configure +++ b/configure @@ -1501,6 +1501,7 @@ EXTERNAL_AUTODETECT_LIBRARY_LIST=" " EXTERNAL_LIBRARY_GPL_LIST=" + avisynth frei0r libcdio librubberband @@ -1533,7 +1534,6 @@ EXTERNAL_LIBRARY_LIST=" $EXTERNAL_LIBRARY_NONFREE_LIST $EXTERNAL_LIBRARY_VERSION3_LIST $EXTERNAL_LIBRARY_GPLV3_LIST - avisynth chromaprint crystalhd decklink From e181e2909b214e043016c108ea0bc3b8094fc63b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sat, 1 Apr 2017 12:45:33 +0200 Subject: [PATCH 1430/3374] doc/examples/transcode_aac: replace local get_error_text with av_err2str --- doc/examples/transcode_aac.c | 40 +++++++++++++----------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/doc/examples/transcode_aac.c b/doc/examples/transcode_aac.c index d7947b496aa1a..6c2f4fb47560c 100644 --- a/doc/examples/transcode_aac.c +++ b/doc/examples/transcode_aac.c @@ -45,18 +45,6 @@ /** The number of output channels */ #define OUTPUT_CHANNELS 2 -/** - * Convert an error code into a text message. - * @param error Error code to be converted - * @return Corresponding error text (not thread-safe) - */ -static const char *get_error_text(const int error) -{ - static char error_buffer[255]; - av_strerror(error, error_buffer, sizeof(error_buffer)); - return error_buffer; -} - /** Open an input file and the required decoder. */ static int open_input_file(const char *filename, AVFormatContext **input_format_context, @@ -70,7 +58,7 @@ static int open_input_file(const char *filename, if ((error = avformat_open_input(input_format_context, filename, NULL, NULL)) < 0) { fprintf(stderr, "Could not open input file '%s' (error '%s')\n", - filename, get_error_text(error)); + filename, av_err2str(error)); *input_format_context = NULL; return error; } @@ -78,7 +66,7 @@ static int open_input_file(const char *filename, /** Get information on the input file (number of streams etc.). */ if ((error = avformat_find_stream_info(*input_format_context, NULL)) < 0) { fprintf(stderr, "Could not open find stream info (error '%s')\n", - get_error_text(error)); + av_err2str(error)); avformat_close_input(input_format_context); return error; } @@ -117,7 +105,7 @@ static int open_input_file(const char *filename, /** Open the decoder for the audio stream to use it later. */ if ((error = avcodec_open2(avctx, input_codec, NULL)) < 0) { fprintf(stderr, "Could not open input codec (error '%s')\n", - get_error_text(error)); + av_err2str(error)); avcodec_free_context(&avctx); avformat_close_input(input_format_context); return error; @@ -149,7 +137,7 @@ static int open_output_file(const char *filename, if ((error = avio_open(&output_io_context, filename, AVIO_FLAG_WRITE)) < 0) { fprintf(stderr, "Could not open output file '%s' (error '%s')\n", - filename, get_error_text(error)); + filename, av_err2str(error)); return error; } @@ -219,7 +207,7 @@ static int open_output_file(const char *filename, /** Open the encoder for the audio stream to use it later. */ if ((error = avcodec_open2(avctx, output_codec, NULL)) < 0) { fprintf(stderr, "Could not open output codec (error '%s')\n", - get_error_text(error)); + av_err2str(error)); goto cleanup; } @@ -325,7 +313,7 @@ static int write_output_file_header(AVFormatContext *output_format_context) int error; if ((error = avformat_write_header(output_format_context, NULL)) < 0) { fprintf(stderr, "Could not write output file header (error '%s')\n", - get_error_text(error)); + av_err2str(error)); return error; } return 0; @@ -349,7 +337,7 @@ static int decode_audio_frame(AVFrame *frame, *finished = 1; else { fprintf(stderr, "Could not read frame (error '%s')\n", - get_error_text(error)); + av_err2str(error)); return error; } } @@ -363,7 +351,7 @@ static int decode_audio_frame(AVFrame *frame, if ((error = avcodec_decode_audio4(input_codec_context, frame, data_present, &input_packet)) < 0) { fprintf(stderr, "Could not decode frame (error '%s')\n", - get_error_text(error)); + av_err2str(error)); av_packet_unref(&input_packet); return error; } @@ -410,7 +398,7 @@ static int init_converted_samples(uint8_t ***converted_input_samples, output_codec_context->sample_fmt, 0)) < 0) { fprintf(stderr, "Could not allocate converted input samples (error '%s')\n", - get_error_text(error)); + av_err2str(error)); av_freep(&(*converted_input_samples)[0]); free(*converted_input_samples); return error; @@ -434,7 +422,7 @@ static int convert_samples(const uint8_t **input_data, converted_data, frame_size, input_data , frame_size)) < 0) { fprintf(stderr, "Could not convert input samples (error '%s')\n", - get_error_text(error)); + av_err2str(error)); return error; } @@ -567,7 +555,7 @@ static int init_output_frame(AVFrame **frame, */ if ((error = av_frame_get_buffer(*frame, 0)) < 0) { fprintf(stderr, "Could not allocate output frame samples (error '%s')\n", - get_error_text(error)); + av_err2str(error)); av_frame_free(frame); return error; } @@ -602,7 +590,7 @@ static int encode_audio_frame(AVFrame *frame, if ((error = avcodec_encode_audio2(output_codec_context, &output_packet, frame, data_present)) < 0) { fprintf(stderr, "Could not encode frame (error '%s')\n", - get_error_text(error)); + av_err2str(error)); av_packet_unref(&output_packet); return error; } @@ -611,7 +599,7 @@ static int encode_audio_frame(AVFrame *frame, if (*data_present) { if ((error = av_write_frame(output_format_context, &output_packet)) < 0) { fprintf(stderr, "Could not write frame (error '%s')\n", - get_error_text(error)); + av_err2str(error)); av_packet_unref(&output_packet); return error; } @@ -671,7 +659,7 @@ static int write_output_file_trailer(AVFormatContext *output_format_context) int error; if ((error = av_write_trailer(output_format_context)) < 0) { fprintf(stderr, "Could not write output file trailer (error '%s')\n", - get_error_text(error)); + av_err2str(error)); return error; } return 0; From e3d8963c3cb5b8cd31460dd9b3b9dba2a2343bf5 Mon Sep 17 00:00:00 2001 From: Takayuki 'January June' Suwa Date: Sat, 1 Apr 2017 02:14:13 +0900 Subject: [PATCH 1431/3374] avcodec/dsddec: correct for DSD silence bit-ordering Reviewed-by: Paul B Mahol Signed-off-by: Michael Niedermayer --- libavcodec/dsddec.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/libavcodec/dsddec.c b/libavcodec/dsddec.c index 880d69191c5e2..2c5c357acc51f 100644 --- a/libavcodec/dsddec.c +++ b/libavcodec/dsddec.c @@ -31,10 +31,18 @@ #include "avcodec.h" #include "dsd.h" +#define DSD_SILENCE 0x69 +/* 0x69 = 01101001 + * This pattern "on repeat" makes a low energy 352.8 kHz tone + * and a high energy 1.0584 MHz tone which should be filtered + * out completely by any playback system --> silence + */ + static av_cold int decode_init(AVCodecContext *avctx) { DSDContext * s; int i; + uint8_t silence; ff_init_dsd_data(); @@ -42,15 +50,10 @@ static av_cold int decode_init(AVCodecContext *avctx) if (!s) return AVERROR(ENOMEM); + silence = avctx->codec_id == AV_CODEC_ID_DSD_LSBF || avctx->codec_id == AV_CODEC_ID_DSD_LSBF_PLANAR ? ff_reverse[DSD_SILENCE] : DSD_SILENCE; for (i = 0; i < avctx->channels; i++) { s[i].pos = 0; - memset(s[i].buf, 0x69, sizeof(s[i].buf)); - - /* 0x69 = 01101001 - * This pattern "on repeat" makes a low energy 352.8 kHz tone - * and a high energy 1.0584 MHz tone which should be filtered - * out completely by any playback system --> silence - */ + memset(s[i].buf, silence, sizeof(s[i].buf)); } avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; From 75afad774b2b3b984bf554dd8526fd8027c704ac Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sat, 1 Apr 2017 15:32:17 +0100 Subject: [PATCH 1432/3374] vf_deinterlace_vaapi: Mark as hwframe-aware Commits ade370a4 and e3fb74f7 were reordered while merging, so this change got lost. --- libavfilter/vf_deinterlace_vaapi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavfilter/vf_deinterlace_vaapi.c b/libavfilter/vf_deinterlace_vaapi.c index 032e65b2257a7..91652d852b1c7 100644 --- a/libavfilter/vf_deinterlace_vaapi.c +++ b/libavfilter/vf_deinterlace_vaapi.c @@ -631,4 +631,5 @@ AVFilter ff_vf_deinterlace_vaapi = { .inputs = deint_vaapi_inputs, .outputs = deint_vaapi_outputs, .priv_class = &deint_vaapi_class, + .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, }; From 68e3c9a3b680ffdc5ea4961090d8d7ec3efbdb1f Mon Sep 17 00:00:00 2001 From: Dzung Hoang Date: Sat, 25 Mar 2017 12:40:08 +0100 Subject: [PATCH 1433/3374] avcodec/exr: add support for scanline file where offsets are set to zero --- libavcodec/exr.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/libavcodec/exr.c b/libavcodec/exr.c index ddce1e50f196e..e5dea0756d550 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -1647,7 +1647,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int y, ret; int out_line_size; - int nb_blocks;/* nb scanline or nb tile */ + int nb_blocks; /* nb scanline or nb tile */ + uint64_t *table; /* scanline offset table */ + uint8_t *marker; /* used to recreate invalid scanline offset table */ + uint8_t *head; bytestream2_init(&s->gb, avpkt->data, avpkt->size); @@ -1733,6 +1736,20 @@ static int decode_frame(AVCodecContext *avctx, void *data, if (bytestream2_get_bytes_left(&s->gb) < nb_blocks * 8) return AVERROR_INVALIDDATA; + // check offset table and recreate it if need + if (!s->is_tile && bytestream2_peek_le64(&s->gb) == 0) { + head = avpkt->data; + table = (uint64_t *)s->gb.buffer; + marker = head + bytestream2_tell(&s->gb) + nb_blocks * 8; + + av_log(s->avctx, AV_LOG_DEBUG, "recreating invalid scanline offset table\n"); + + for (y = 0; y < nb_blocks; y++) { + table[y] = marker - head; + marker += ((uint32_t *)marker)[1] + 8; + } + } + // save pointer we are going to use in decode_block s->buf = avpkt->data; s->buf_size = avpkt->size; From a3fc5f535adc7f684babee02772b7fdfc090abca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sat, 1 Apr 2017 18:21:11 +0200 Subject: [PATCH 1434/3374] doc/libav-merge: document hlsenc encryption state --- doc/libav-merge.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/libav-merge.txt b/doc/libav-merge.txt index 30518c0a67337..2b632381afa3a 100644 --- a/doc/libav-merge.txt +++ b/doc/libav-merge.txt @@ -106,6 +106,7 @@ Collateral damage that needs work locally: - Merge proresenc_anatoliy.c and proresenc_kostya.c - Remove ADVANCED_PARSER in libavcodec/hevc_parser.c - Fix MIPS AC3 downmix +- hlsenc encryption support may need some adjustment (see edc43c571d) Extra changes needed to be aligned with Libav: ---------------------------------------------- From f078bc4c5e6675a93166a7e5b23feb5b04ac9320 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sat, 25 Mar 2017 20:19:26 +0100 Subject: [PATCH 1435/3374] avcodec/dnxhdenc: DNxHR 444 and HQX support Signed-off-by: Paul B Mahol --- libavcodec/dnxhdenc.c | 280 ++++++++++++++++++++++++++++++++---------- libavcodec/dnxhdenc.h | 6 +- 2 files changed, 216 insertions(+), 70 deletions(-) diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c index 33f25fb4ac9fc..7a889b68256c5 100644 --- a/libavcodec/dnxhdenc.c +++ b/libavcodec/dnxhdenc.c @@ -112,6 +112,65 @@ void dnxhd_10bit_get_pixels_8x4_sym(int16_t *av_restrict block, memcpy(block + 4 * 8, pixels + 3 * line_size, 8 * sizeof(*block)); } +static int dnxhd_10bit_dct_quantize_444(MpegEncContext *ctx, int16_t *block, + int n, int qscale, int *overflow) +{ + int i, j, level, last_non_zero, start_i; + const int *qmat; + const uint8_t *scantable= ctx->intra_scantable.scantable; + int bias; + int max = 0; + unsigned int threshold1, threshold2; + + ctx->fdsp.fdct(block); + + block[0] = (block[0] + 2) >> 2; + start_i = 1; + last_non_zero = 0; + qmat = n < 4 ? ctx->q_intra_matrix[qscale] : ctx->q_chroma_intra_matrix[qscale]; + bias= ctx->intra_quant_bias * (1 << (16 - 8)); + threshold1 = (1 << 16) - bias - 1; + threshold2 = (threshold1 << 1); + + for (i = 63; i >= start_i; i--) { + j = scantable[i]; + level = block[j] * qmat[j]; + + if (((unsigned)(level + threshold1)) > threshold2) { + last_non_zero = i; + break; + } else{ + block[j]=0; + } + } + + for (i = start_i; i <= last_non_zero; i++) { + j = scantable[i]; + level = block[j] * qmat[j]; + + if (((unsigned)(level + threshold1)) > threshold2) { + if (level > 0) { + level = (bias + level) >> 16; + block[j] = level; + } else{ + level = (bias - level) >> 16; + block[j] = -level; + } + max |= level; + } else { + block[j] = 0; + } + } + *overflow = ctx->max_qcoeff < max; //overflow might have happened + + /* we need this permutation so that we correct the IDCT, we only permute the !=0 elements */ + if (ctx->idsp.perm_type != FF_IDCT_PERM_NONE) + ff_block_permute(block, ctx->idsp.idct_permutation, + scantable, last_non_zero); + + return last_non_zero; +} + static int dnxhd_10bit_dct_quantize(MpegEncContext *ctx, int16_t *block, int n, int qscale, int *overflow) { @@ -146,7 +205,7 @@ static int dnxhd_10bit_dct_quantize(MpegEncContext *ctx, int16_t *block, static av_cold int dnxhd_init_vlc(DNXHDEncContext *ctx) { int i, j, level, run; - int max_level = 1 << (ctx->cid_table->bit_depth + 2); + int max_level = 1 << (ctx->bit_depth + 2); FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->vlc_codes, max_level, 4 * sizeof(*ctx->vlc_codes), fail); @@ -223,7 +282,7 @@ static av_cold int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias) (ctx->m.avctx->qmax + 1), 64 * 2 * sizeof(uint16_t), fail); - if (ctx->cid_table->bit_depth == 8) { + if (ctx->bit_depth == 8) { for (i = 1; i < 64; i++) { int j = ctx->m.idsp.idct_permutation[ff_zigzag_direct[i]]; weight_matrix[j] = ctx->cid_table->luma_weight[i]; @@ -309,17 +368,20 @@ static int dnxhd_get_hr_frame_size(const CIDEntry* profile, int mb_num) result = (result + 2048) / 4096 * 4096; return FFMAX(result, 8192); } + static av_cold int dnxhd_encode_init(AVCodecContext *avctx) { DNXHDEncContext *ctx = avctx->priv_data; - int i, index, bit_depth, ret; + int i, index, ret; switch (avctx->pix_fmt) { case AV_PIX_FMT_YUV422P: - bit_depth = 8; + ctx->bit_depth = 8; break; case AV_PIX_FMT_YUV422P10: - bit_depth = 10; + case AV_PIX_FMT_YUV444P10: + case AV_PIX_FMT_GBRP10: + ctx->bit_depth = 10; break; default: av_log(avctx, AV_LOG_ERROR, @@ -327,15 +389,32 @@ static av_cold int dnxhd_encode_init(AVCodecContext *avctx) return AVERROR(EINVAL); } - if (ctx->profile == FF_PROFILE_DNXHR_444 || - ctx->profile == FF_PROFILE_DNXHR_HQX) { - avpriv_report_missing_feature(avctx, - "dnxhr_444 or dnxhr_hqx profile"); - return AVERROR_PATCHWELCOME; + if ((ctx->profile == FF_PROFILE_DNXHR_444 && (avctx->pix_fmt != AV_PIX_FMT_YUV444P10 && + avctx->pix_fmt != AV_PIX_FMT_GBRP10)) || + (ctx->profile != FF_PROFILE_DNXHR_444 && (avctx->pix_fmt == AV_PIX_FMT_YUV444P10 || + avctx->pix_fmt == AV_PIX_FMT_GBRP10))) { + av_log(avctx, AV_LOG_ERROR, + "pixel format is incompatible with DNxHD profile\n"); + return AVERROR(EINVAL); + } + + if (ctx->profile == FF_PROFILE_DNXHR_HQX && avctx->pix_fmt != AV_PIX_FMT_YUV422P10) { + av_log(avctx, AV_LOG_ERROR, + "pixel format is incompatible with DNxHR HQX profile\n"); + return AVERROR(EINVAL); + } + + if ((ctx->profile == FF_PROFILE_DNXHR_LB || + ctx->profile == FF_PROFILE_DNXHR_SQ || + ctx->profile == FF_PROFILE_DNXHR_HQ) && avctx->pix_fmt != AV_PIX_FMT_YUV422P) { + av_log(avctx, AV_LOG_ERROR, + "pixel format is incompatible with DNxHR LB/SQ/HQ profile\n"); + return AVERROR(EINVAL); } + ctx->is_444 = ctx->profile == FF_PROFILE_DNXHR_444; avctx->profile = ctx->profile; - ctx->cid = ff_dnxhd_find_cid(avctx, bit_depth); + ctx->cid = ff_dnxhd_find_cid(avctx, ctx->bit_depth); if (!ctx->cid) { av_log(avctx, AV_LOG_ERROR, "video parameters incompatible with DNxHD. Valid DNxHD profiles:\n"); @@ -362,7 +441,7 @@ static av_cold int dnxhd_encode_init(AVCodecContext *avctx) ctx->m.mb_intra = 1; ctx->m.h263_aic = 1; - avctx->bits_per_raw_sample = ctx->cid_table->bit_depth; + avctx->bits_per_raw_sample = ctx->bit_depth; ff_blockdsp_init(&ctx->bdsp, avctx); ff_fdctdsp_init(&ctx->m.fdsp, avctx); @@ -372,12 +451,16 @@ static av_cold int dnxhd_encode_init(AVCodecContext *avctx) ff_dct_encode_init(&ctx->m); if (ctx->profile != FF_PROFILE_DNXHD) - ff_videodsp_init(&ctx->m.vdsp, bit_depth); + ff_videodsp_init(&ctx->m.vdsp, ctx->bit_depth); if (!ctx->m.dct_quantize) ctx->m.dct_quantize = ff_dct_quantize_c; - if (ctx->cid_table->bit_depth == 10) { + if (ctx->is_444 || ctx->profile == FF_PROFILE_DNXHR_HQX) { + ctx->m.dct_quantize = dnxhd_10bit_dct_quantize_444; + ctx->get_pixels_8x4_sym = dnxhd_10bit_get_pixels_8x4_sym; + ctx->block_width_l2 = 4; + } else if (ctx->bit_depth == 10) { ctx->m.dct_quantize = dnxhd_10bit_dct_quantize; ctx->get_pixels_8x4_sym = dnxhd_10bit_get_pixels_8x4_sym; ctx->block_width_l2 = 4; @@ -490,10 +573,10 @@ static int dnxhd_write_header(AVCodecContext *avctx, uint8_t *buf) AV_WB16(buf + 0x1a, avctx->width); // SPL AV_WB16(buf + 0x1d, avctx->height >> ctx->interlaced); // NAL - buf[0x21] = ctx->cid_table->bit_depth == 10 ? 0x58 : 0x38; + buf[0x21] = ctx->bit_depth == 10 ? 0x58 : 0x38; buf[0x22] = 0x88 + (ctx->interlaced << 2); AV_WB32(buf + 0x28, ctx->cid); // CID - buf[0x2c] = ctx->interlaced ? 0 : 0x80; + buf[0x2c] = (!ctx->interlaced << 7) | (ctx->is_444 << 6) | (avctx->pix_fmt == AV_PIX_FMT_YUV444P10); buf[0x5f] = 0x01; // UDL @@ -554,8 +637,13 @@ void dnxhd_unquantize_c(DNXHDEncContext *ctx, int16_t *block, int n, int level; int i; - weight_matrix = (n & 2) ? ctx->cid_table->chroma_weight - : ctx->cid_table->luma_weight; + if (ctx->is_444) { + weight_matrix = ((n % 6) < 2) ? ctx->cid_table->luma_weight + : ctx->cid_table->chroma_weight; + } else { + weight_matrix = (n & 2) ? ctx->cid_table->chroma_weight + : ctx->cid_table->luma_weight; + } for (i = 1; i <= last_index; i++) { int j = ctx->m.intra_scantable.permutated[i]; @@ -563,7 +651,7 @@ void dnxhd_unquantize_c(DNXHDEncContext *ctx, int16_t *block, int n, if (level) { if (level < 0) { level = (1 - 2 * level) * qscale * weight_matrix[i]; - if (ctx->cid_table->bit_depth == 10) { + if (ctx->bit_depth == 10) { if (weight_matrix[i] != 8) level += 8; level >>= 4; @@ -575,7 +663,7 @@ void dnxhd_unquantize_c(DNXHDEncContext *ctx, int16_t *block, int n, level = -level; } else { level = (2 * level + 1) * qscale * weight_matrix[i]; - if (ctx->cid_table->bit_depth == 10) { + if (ctx->bit_depth == 10) { if (weight_matrix[i] != 8) level += 8; level >>= 4; @@ -630,14 +718,14 @@ void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y) const uint8_t *ptr_y = ctx->thread[0]->src[0] + ((mb_y << 4) * ctx->m.linesize) + (mb_x << bs + 1); const uint8_t *ptr_u = ctx->thread[0]->src[1] + - ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << bs); + ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << bs + ctx->is_444); const uint8_t *ptr_v = ctx->thread[0]->src[2] + - ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << bs); + ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << bs + ctx->is_444); PixblockDSPContext *pdsp = &ctx->m.pdsp; VideoDSPContext *vdsp = &ctx->m.vdsp; - if (vdsp->emulated_edge_mc && ((mb_x << 4) + 16 > ctx->m.avctx->width || - (mb_y << 4) + 16 > ctx->m.avctx->height)) { + if (ctx->bit_depth != 10 && vdsp->emulated_edge_mc && ((mb_x << 4) + 16 > ctx->m.avctx->width || + (mb_y << 4) + 16 > ctx->m.avctx->height)) { int y_w = ctx->m.avctx->width - (mb_x << 4); int y_h = ctx->m.avctx->height - (mb_y << 4); int uv_w = (y_w + 1) / 2; @@ -658,6 +746,33 @@ void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y) uvlinesize, 16, 0, 0, uv_w, uv_h); + dct_y_offset = bw * linesize; + dct_uv_offset = bw * uvlinesize; + ptr_y = &ctx->edge_buf_y[0]; + ptr_u = &ctx->edge_buf_uv[0][0]; + ptr_v = &ctx->edge_buf_uv[1][0]; + } else if (ctx->bit_depth == 10 && vdsp->emulated_edge_mc && ((mb_x << 3) + 8 > ctx->m.avctx->width || + (mb_y << 3) + 8 > ctx->m.avctx->height)) { + int y_w = ctx->m.avctx->width - (mb_x << 3); + int y_h = ctx->m.avctx->height - (mb_y << 3); + int uv_w = ctx->is_444 ? y_w : (y_w + 1) / 2; + int uv_h = y_h; + linesize = 16; + uvlinesize = 8 + 8 * ctx->is_444; + + vdsp->emulated_edge_mc(&ctx->edge_buf_y[0], ptr_y, + linesize, ctx->m.linesize, + linesize / 2, 16, + 0, 0, y_w, y_h); + vdsp->emulated_edge_mc(&ctx->edge_buf_uv[0][0], ptr_u, + uvlinesize, ctx->m.uvlinesize, + uvlinesize / 2, 16, + 0, 0, uv_w, uv_h); + vdsp->emulated_edge_mc(&ctx->edge_buf_uv[1][0], ptr_v, + uvlinesize, ctx->m.uvlinesize, + uvlinesize / 2, 16, + 0, 0, uv_w, uv_h); + dct_y_offset = bw * linesize; dct_uv_offset = bw * uvlinesize; ptr_y = &ctx->edge_buf_y[0]; @@ -665,48 +780,72 @@ void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y) ptr_v = &ctx->edge_buf_uv[1][0]; } - pdsp->get_pixels(ctx->blocks[0], ptr_y, linesize); - pdsp->get_pixels(ctx->blocks[1], ptr_y + bw, linesize); - pdsp->get_pixels(ctx->blocks[2], ptr_u, uvlinesize); - pdsp->get_pixels(ctx->blocks[3], ptr_v, uvlinesize); - - if (mb_y + 1 == ctx->m.mb_height && ctx->m.avctx->height == 1080) { - if (ctx->interlaced) { - ctx->get_pixels_8x4_sym(ctx->blocks[4], - ptr_y + dct_y_offset, - linesize); - ctx->get_pixels_8x4_sym(ctx->blocks[5], - ptr_y + dct_y_offset + bw, - linesize); - ctx->get_pixels_8x4_sym(ctx->blocks[6], - ptr_u + dct_uv_offset, - uvlinesize); - ctx->get_pixels_8x4_sym(ctx->blocks[7], - ptr_v + dct_uv_offset, - uvlinesize); + if (!ctx->is_444) { + pdsp->get_pixels(ctx->blocks[0], ptr_y, linesize); + pdsp->get_pixels(ctx->blocks[1], ptr_y + bw, linesize); + pdsp->get_pixels(ctx->blocks[2], ptr_u, uvlinesize); + pdsp->get_pixels(ctx->blocks[3], ptr_v, uvlinesize); + + if (mb_y + 1 == ctx->m.mb_height && ctx->m.avctx->height == 1080) { + if (ctx->interlaced) { + ctx->get_pixels_8x4_sym(ctx->blocks[4], + ptr_y + dct_y_offset, + linesize); + ctx->get_pixels_8x4_sym(ctx->blocks[5], + ptr_y + dct_y_offset + bw, + linesize); + ctx->get_pixels_8x4_sym(ctx->blocks[6], + ptr_u + dct_uv_offset, + uvlinesize); + ctx->get_pixels_8x4_sym(ctx->blocks[7], + ptr_v + dct_uv_offset, + uvlinesize); + } else { + ctx->bdsp.clear_block(ctx->blocks[4]); + ctx->bdsp.clear_block(ctx->blocks[5]); + ctx->bdsp.clear_block(ctx->blocks[6]); + ctx->bdsp.clear_block(ctx->blocks[7]); + } } else { - ctx->bdsp.clear_block(ctx->blocks[4]); - ctx->bdsp.clear_block(ctx->blocks[5]); - ctx->bdsp.clear_block(ctx->blocks[6]); - ctx->bdsp.clear_block(ctx->blocks[7]); + pdsp->get_pixels(ctx->blocks[4], + ptr_y + dct_y_offset, linesize); + pdsp->get_pixels(ctx->blocks[5], + ptr_y + dct_y_offset + bw, linesize); + pdsp->get_pixels(ctx->blocks[6], + ptr_u + dct_uv_offset, uvlinesize); + pdsp->get_pixels(ctx->blocks[7], + ptr_v + dct_uv_offset, uvlinesize); } } else { - pdsp->get_pixels(ctx->blocks[4], - ptr_y + dct_y_offset, linesize); - pdsp->get_pixels(ctx->blocks[5], - ptr_y + dct_y_offset + bw, linesize); - pdsp->get_pixels(ctx->blocks[6], - ptr_u + dct_uv_offset, uvlinesize); - pdsp->get_pixels(ctx->blocks[7], - ptr_v + dct_uv_offset, uvlinesize); + pdsp->get_pixels(ctx->blocks[0], ptr_y, linesize); + pdsp->get_pixels(ctx->blocks[1], ptr_y + bw, linesize); + pdsp->get_pixels(ctx->blocks[6], ptr_y + dct_y_offset, linesize); + pdsp->get_pixels(ctx->blocks[7], ptr_y + dct_y_offset + bw, linesize); + + pdsp->get_pixels(ctx->blocks[2], ptr_u, uvlinesize); + pdsp->get_pixels(ctx->blocks[3], ptr_u + bw, uvlinesize); + pdsp->get_pixels(ctx->blocks[8], ptr_u + dct_uv_offset, uvlinesize); + pdsp->get_pixels(ctx->blocks[9], ptr_u + dct_uv_offset + bw, uvlinesize); + + pdsp->get_pixels(ctx->blocks[4], ptr_v, uvlinesize); + pdsp->get_pixels(ctx->blocks[5], ptr_v + bw, uvlinesize); + pdsp->get_pixels(ctx->blocks[10], ptr_v + dct_uv_offset, uvlinesize); + pdsp->get_pixels(ctx->blocks[11], ptr_v + dct_uv_offset + bw, uvlinesize); } } static av_always_inline int dnxhd_switch_matrix(DNXHDEncContext *ctx, int i) { - const static uint8_t component[8]={0,0,1,2,0,0,1,2}; - return component[i]; + int x; + + if (ctx->is_444) { + x = (i >> 1) % 3; + } else { + const static uint8_t component[8]={0,0,1,2,0,0,1,2}; + x = component[i]; + } + return x; } static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg, @@ -720,7 +859,7 @@ static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg, ctx->m.last_dc[0] = ctx->m.last_dc[1] = - ctx->m.last_dc[2] = 1 << (ctx->cid_table->bit_depth + 2); + ctx->m.last_dc[2] = 1 << (ctx->bit_depth + 2); for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) { unsigned mb = mb_y * ctx->m.mb_width + mb_x; @@ -731,13 +870,14 @@ static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg, dnxhd_get_blocks(ctx, mb_x, mb_y); - for (i = 0; i < 8; i++) { + for (i = 0; i < 8 + 4 * ctx->is_444; i++) { int16_t *src_block = ctx->blocks[i]; int overflow, nbits, diff, last_index; int n = dnxhd_switch_matrix(ctx, i); memcpy(block, src_block, 64 * sizeof(*block)); - last_index = ctx->m.dct_quantize(&ctx->m, block, 4 & (2*i), + last_index = ctx->m.dct_quantize(&ctx->m, block, + ctx->is_444 ? 4 * (n > 0): 4 & (2*i), qscale, &overflow); ac_bits += dnxhd_calc_ac_bits(ctx, block, last_index); @@ -747,7 +887,7 @@ static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg, else nbits = av_log2_16bit(2 * diff); - av_assert1(nbits < ctx->cid_table->bit_depth + 4); + av_assert1(nbits < ctx->bit_depth + 4); dc_bits += ctx->cid_table->dc_bits[nbits] + nbits; ctx->m.last_dc[n] = block[0]; @@ -760,7 +900,7 @@ static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg, } ctx->mb_rc[(qscale * ctx->m.mb_num) + mb].ssd = ssd; ctx->mb_rc[(qscale * ctx->m.mb_num) + mb].bits = ac_bits + dc_bits + 12 + - 8 * ctx->vlc_bits[0]; + (1 + ctx->is_444) * 8 * ctx->vlc_bits[0]; } return 0; } @@ -776,20 +916,22 @@ static int dnxhd_encode_thread(AVCodecContext *avctx, void *arg, ctx->m.last_dc[0] = ctx->m.last_dc[1] = - ctx->m.last_dc[2] = 1 << (ctx->cid_table->bit_depth + 2); + ctx->m.last_dc[2] = 1 << (ctx->bit_depth + 2); for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) { unsigned mb = mb_y * ctx->m.mb_width + mb_x; int qscale = ctx->mb_qscale[mb]; int i; - put_bits(&ctx->m.pb, 12, qscale << 1); + put_bits(&ctx->m.pb, 11, qscale); + put_bits(&ctx->m.pb, 1, avctx->pix_fmt == AV_PIX_FMT_YUV444P10); dnxhd_get_blocks(ctx, mb_x, mb_y); - for (i = 0; i < 8; i++) { + for (i = 0; i < 8 + 4 * ctx->is_444; i++) { int16_t *block = ctx->blocks[i]; int overflow, n = dnxhd_switch_matrix(ctx, i); - int last_index = ctx->m.dct_quantize(&ctx->m, block, 4 & (2*i), + int last_index = ctx->m.dct_quantize(&ctx->m, block, + ctx->is_444 ? (((i >> 1) % 3) < 1 ? 0 : 4): 4 & (2*i), qscale, &overflow); // START_TIMER; dnxhd_encode_block(ctx, block, last_index, n); @@ -830,7 +972,7 @@ static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg, ((avctx->height >> ctx->interlaced) & 0xF); ctx = ctx->thread[threadnr]; - if (ctx->cid_table->bit_depth == 8) { + if (ctx->bit_depth == 8) { uint8_t *pix = ctx->thread[0]->src[0] + ((mb_y << 4) * ctx->m.linesize); for (mb_x = 0; mb_x < ctx->m.mb_width; ++mb_x, pix += 16) { unsigned mb = mb_y * ctx->m.mb_width + mb_x; @@ -1214,7 +1356,7 @@ FF_ENABLE_DEPRECATION_WARNINGS static av_cold int dnxhd_encode_end(AVCodecContext *avctx) { DNXHDEncContext *ctx = avctx->priv_data; - int max_level = 1 << (ctx->cid_table->bit_depth + 2); + int max_level = 1 << (ctx->bit_depth + 2); int i; av_free(ctx->vlc_codes - max_level * 2); @@ -1259,6 +1401,8 @@ AVCodec ff_dnxhd_encoder = { .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV422P10, + AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_GBRP10, AV_PIX_FMT_NONE }, .priv_class = &dnxhd_class, diff --git a/libavcodec/dnxhdenc.h b/libavcodec/dnxhdenc.h index bcb25cd83282f..9b43f6e9c6580 100644 --- a/libavcodec/dnxhdenc.h +++ b/libavcodec/dnxhdenc.h @@ -48,6 +48,8 @@ typedef struct DNXHDEncContext { int cid; int profile; + int bit_depth; + int is_444; const CIDEntry *cid_table; uint8_t *msip; ///< Macroblock Scan Indexes Payload uint32_t *slice_size; @@ -72,9 +74,9 @@ typedef struct DNXHDEncContext { unsigned min_padding; int intra_quant_bias; - DECLARE_ALIGNED(16, int16_t, blocks)[8][64]; + DECLARE_ALIGNED(16, int16_t, blocks)[12][64]; DECLARE_ALIGNED(16, uint8_t, edge_buf_y)[256]; - DECLARE_ALIGNED(16, uint8_t, edge_buf_uv)[2][128]; + DECLARE_ALIGNED(16, uint8_t, edge_buf_uv)[2][256]; int (*qmatrix_c) [64]; int (*qmatrix_l) [64]; From 358d4524cc8fda2660679d8080cfe937b41c73c3 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sat, 1 Apr 2017 18:50:30 +0200 Subject: [PATCH 1436/3374] avcodec/dnxhdenc: fix indentation issue Signed-off-by: Paul B Mahol --- libavcodec/dnxhdenc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c index 7a889b68256c5..665a99270659a 100644 --- a/libavcodec/dnxhdenc.c +++ b/libavcodec/dnxhdenc.c @@ -364,9 +364,9 @@ static av_cold int dnxhd_init_rc(DNXHDEncContext *ctx) static int dnxhd_get_hr_frame_size(const CIDEntry* profile, int mb_num) { - int result = mb_num * profile->packet_scale.num / profile->packet_scale.den; - result = (result + 2048) / 4096 * 4096; - return FFMAX(result, 8192); + int result = mb_num * profile->packet_scale.num / profile->packet_scale.den; + result = (result + 2048) / 4096 * 4096; + return FFMAX(result, 8192); } static av_cold int dnxhd_encode_init(AVCodecContext *avctx) From 5f23d8b405fa24496c909f373a1b28454740ef16 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 1 Apr 2017 13:38:50 -0300 Subject: [PATCH 1437/3374] fate: add bitexact sws_flags to hevc-extradata-reload Makes the test output consistent across all targets. Reviewed-by: nevcairiel Signed-off-by: James Almer --- tests/fate/hevc.mak | 2 +- tests/ref/fate/hevc-extradata-reload | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/fate/hevc.mak b/tests/fate/hevc.mak index d1611c1dbded0..d23d1ba9fea9c 100644 --- a/tests/fate/hevc.mak +++ b/tests/fate/hevc.mak @@ -241,7 +241,7 @@ FATE_HEVC-$(call DEMDEC, HEVC, HEVC) += $(FATE_HEVC) # this sample has two stsd entries and needs to reload extradata FATE_HEVC-$(call DEMDEC, MOV, HEVC) += fate-hevc-extradata-reload -fate-hevc-extradata-reload: CMD = framemd5 -i $(TARGET_SAMPLES)/hevc/extradata-reload-multi-stsd.mov +fate-hevc-extradata-reload: CMD = framemd5 -i $(TARGET_SAMPLES)/hevc/extradata-reload-multi-stsd.mov -sws_flags bitexact FATE_SAMPLES_AVCONV += $(FATE_HEVC-yes) diff --git a/tests/ref/fate/hevc-extradata-reload b/tests/ref/fate/hevc-extradata-reload index e04d6dcb04506..b08754ed2bd19 100644 --- a/tests/ref/fate/hevc-extradata-reload +++ b/tests/ref/fate/hevc-extradata-reload @@ -9,5 +9,5 @@ #stream#, dts, pts, duration, size, hash 0, 0, 0, 1, 24576, 0d01217c5d1ec6799643fc7d75ba2337 0, 1, 1, 1, 24576, f73d9cca9b4c1765d0ead242c3f0c339 -0, 2, 2, 1, 24576, aea8b931d694e38ffa54ea4c88e04491 -0, 3, 3, 1, 24576, 9d8f6a78c1bae37eabcab29295fd02a8 +0, 2, 2, 1, 24576, 39a8714d763c623ae7f6faae34e107d1 +0, 3, 3, 1, 24576, 5db2600aa268b4fd28b64ab28a096f32 From 679a315424e6ffaafd21ebf7a86108bd4e743793 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 1 Apr 2017 19:18:34 +0200 Subject: [PATCH 1438/3374] avformat/oggparsedaala: Check duration for AV_NOPTS_VALUE This avoids an integer overflow the solution matches oggparsevorbis.c and 45581ed15d2ad5955e24d809820c1675da68f500 Fixes: 700242 Found-by: Thomas Guilbert Reviewed-by: Rostislav Pehlivanov Signed-off-by: Michael Niedermayer --- libavformat/oggparsedaala.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/oggparsedaala.c b/libavformat/oggparsedaala.c index 89bda589943f4..ce65b2bd7a8fb 100644 --- a/libavformat/oggparsedaala.c +++ b/libavformat/oggparsedaala.c @@ -232,7 +232,7 @@ static int daala_packet(AVFormatContext *s, int idx) os->lastpts = os->lastdts = daala_gptopts(s, idx, os->granule, NULL) - duration; if(s->streams[idx]->start_time == AV_NOPTS_VALUE) { s->streams[idx]->start_time = os->lastpts; - if (s->streams[idx]->duration) + if (s->streams[idx]->duration != AV_NOPTS_VALUE) s->streams[idx]->duration -= s->streams[idx]->start_time; } } From 23ae3cc822915ede2bb4e85047ab46cc5bc71268 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 1 Apr 2017 19:18:35 +0200 Subject: [PATCH 1439/3374] avformat/oggparsedaala: Do not leave an invalid value in gpshift Fixes: undefined behavior Fixes: 702974 Found-by: Thomas Guilbert Reviewed-by: Rostislav Pehlivanov Signed-off-by: Michael Niedermayer --- libavformat/oggparsedaala.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/oggparsedaala.c b/libavformat/oggparsedaala.c index ce65b2bd7a8fb..a373b41b4cac4 100644 --- a/libavformat/oggparsedaala.c +++ b/libavformat/oggparsedaala.c @@ -126,6 +126,7 @@ static int daala_header(AVFormatContext *s, int idx) if (hdr->gpshift >= 32) { av_log(s, AV_LOG_ERROR, "Too large gpshift %d (>= 32).\n", hdr->gpshift); + hdr->gpshift = 0; return AVERROR_INVALIDDATA; } hdr->gpmask = (1U << hdr->gpshift) - 1; From cbd25029399873ef6ff2c7344efbfb0c74b12e37 Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 24 Mar 2017 22:37:34 -0300 Subject: [PATCH 1440/3374] avcodec/extract_extradata_bsf: make sure all parameter set NAL units were found for h264/hevc Signed-off-by: James Almer --- libavcodec/extract_extradata_bsf.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/libavcodec/extract_extradata_bsf.c b/libavcodec/extract_extradata_bsf.c index 1e92f8ebdb918..4cd0ca1137626 100644 --- a/libavcodec/extract_extradata_bsf.c +++ b/libavcodec/extract_extradata_bsf.c @@ -65,7 +65,7 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt, int extradata_size = 0; const int *extradata_nal_types; int nb_extradata_nal_types; - int i, ret = 0; + int i, has_sps = 0, has_vps = 0, ret = 0; if (ctx->par_in->codec_id == AV_CODEC_ID_HEVC) { extradata_nal_types = extradata_nal_types_hevc; @@ -82,11 +82,20 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt, for (i = 0; i < h2645_pkt.nb_nals; i++) { H2645NAL *nal = &h2645_pkt.nals[i]; - if (val_in_array(extradata_nal_types, nb_extradata_nal_types, nal->type)) + if (val_in_array(extradata_nal_types, nb_extradata_nal_types, nal->type)) { extradata_size += nal->raw_size + 3; + if (ctx->par_in->codec_id == AV_CODEC_ID_HEVC) { + if (nal->type == HEVC_NAL_SPS) has_sps = 1; + if (nal->type == HEVC_NAL_VPS) has_vps = 1; + } else { + if (nal->type == H264_NAL_SPS) has_sps = 1; + } + } } - if (extradata_size) { + if (extradata_size && + ((ctx->par_in->codec_id == AV_CODEC_ID_HEVC && has_sps && has_vps) || + (ctx->par_in->codec_id == AV_CODEC_ID_H264 && has_sps))) { AVBufferRef *filtered_buf; uint8_t *extradata, *filtered_data; From 7942907878dd4c263ba7431067c33ce6b5d53ceb Mon Sep 17 00:00:00 2001 From: James Almer Date: Sun, 2 Apr 2017 00:57:17 -0300 Subject: [PATCH 1441/3374] compat/atomics: fix atomic_fetch_xor --- compat/atomics/dummy/stdatomic.h | 2 +- compat/atomics/gcc/stdatomic.h | 4 ++-- compat/atomics/pthread/stdatomic.h | 2 +- compat/atomics/suncc/stdatomic.h | 2 +- compat/atomics/win32/stdatomic.h | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compat/atomics/dummy/stdatomic.h b/compat/atomics/dummy/stdatomic.h index c26f629aa2c5e..59d85f915d620 100644 --- a/compat/atomics/dummy/stdatomic.h +++ b/compat/atomics/dummy/stdatomic.h @@ -156,7 +156,7 @@ FETCH_MODIFY(and, &) atomic_fetch_or(object, operand) #define atomic_fetch_xor_explicit(object, operand, order) \ - atomic_fetch_sub(object, operand) + atomic_fetch_xor(object, operand) #define atomic_fetch_and_explicit(object, operand, order) \ atomic_fetch_and(object, operand) diff --git a/compat/atomics/gcc/stdatomic.h b/compat/atomics/gcc/stdatomic.h index 2b64687437b93..e13ed0e068b8f 100644 --- a/compat/atomics/gcc/stdatomic.h +++ b/compat/atomics/gcc/stdatomic.h @@ -147,10 +147,10 @@ do { \ atomic_fetch_or(object, operand) #define atomic_fetch_xor(object, operand) \ - __sync_fetch_and_sub(object, operand) + __sync_fetch_and_xor(object, operand) #define atomic_fetch_xor_explicit(object, operand, order) \ - atomic_fetch_sub(object, operand) + atomic_fetch_xor(object, operand) #define atomic_fetch_and(object, operand) \ __sync_fetch_and_and(object, operand) diff --git a/compat/atomics/pthread/stdatomic.h b/compat/atomics/pthread/stdatomic.h index 1b7278e4fd547..81a60f102bb67 100644 --- a/compat/atomics/pthread/stdatomic.h +++ b/compat/atomics/pthread/stdatomic.h @@ -177,7 +177,7 @@ FETCH_MODIFY(and, &) atomic_fetch_or(object, operand) #define atomic_fetch_xor_explicit(object, operand, order) \ - atomic_fetch_sub(object, operand) + atomic_fetch_xor(object, operand) #define atomic_fetch_and_explicit(object, operand, order) \ atomic_fetch_and(object, operand) diff --git a/compat/atomics/suncc/stdatomic.h b/compat/atomics/suncc/stdatomic.h index 119c2ba3c9466..4a864a4ae96d3 100644 --- a/compat/atomics/suncc/stdatomic.h +++ b/compat/atomics/suncc/stdatomic.h @@ -166,7 +166,7 @@ static inline intptr_t atomic_fetch_and(intptr_t *object, intptr_t operand) atomic_fetch_or(object, operand) #define atomic_fetch_xor_explicit(object, operand, order) \ - atomic_fetch_sub(object, operand) + atomic_fetch_xor(object, operand) #define atomic_fetch_and_explicit(object, operand, order) \ atomic_fetch_and(object, operand) diff --git a/compat/atomics/win32/stdatomic.h b/compat/atomics/win32/stdatomic.h index 4cbba9c78d5fe..fa7ef51ea5488 100644 --- a/compat/atomics/win32/stdatomic.h +++ b/compat/atomics/win32/stdatomic.h @@ -159,7 +159,7 @@ static inline int atomic_compare_exchange_strong(intptr_t *object, intptr_t *exp atomic_fetch_or(object, operand) #define atomic_fetch_xor_explicit(object, operand, order) \ - atomic_fetch_sub(object, operand) + atomic_fetch_xor(object, operand) #define atomic_fetch_and_explicit(object, operand, order) \ atomic_fetch_and(object, operand) From e1cc7f83df001b471313fb7f03fd4b0fa1c5a747 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 2 Apr 2017 19:49:45 +0200 Subject: [PATCH 1442/3374] Bump minor for 3.3 Signed-off-by: Michael Niedermayer --- libavcodec/version.h | 2 +- libavdevice/version.h | 2 +- libavfilter/version.h | 2 +- libavformat/version.h | 2 +- libavresample/version.h | 2 +- libavutil/version.h | 2 +- libpostproc/version.h | 2 +- libswresample/version.h | 2 +- libswscale/version.h | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libavcodec/version.h b/libavcodec/version.h index 27b0d48af2b88..51df9e0084df5 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 88 +#define LIBAVCODEC_VERSION_MINOR 89 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ diff --git a/libavdevice/version.h b/libavdevice/version.h index d5aedf4e277ca..986ca98303b0d 100644 --- a/libavdevice/version.h +++ b/libavdevice/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVDEVICE_VERSION_MAJOR 57 -#define LIBAVDEVICE_VERSION_MINOR 5 +#define LIBAVDEVICE_VERSION_MINOR 6 #define LIBAVDEVICE_VERSION_MICRO 100 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ diff --git a/libavfilter/version.h b/libavfilter/version.h index d90e83e9a117c..4cbd1857dbf8a 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 6 -#define LIBAVFILTER_VERSION_MINOR 81 +#define LIBAVFILTER_VERSION_MINOR 82 #define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavformat/version.h b/libavformat/version.h index 894b7248612b2..fc054ee84ca86 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ // 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 57 -#define LIBAVFORMAT_VERSION_MINOR 70 +#define LIBAVFORMAT_VERSION_MINOR 71 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ diff --git a/libavresample/version.h b/libavresample/version.h index 37ad1ff1826a5..89b4746d4e58d 100644 --- a/libavresample/version.h +++ b/libavresample/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVRESAMPLE_VERSION_MAJOR 3 -#define LIBAVRESAMPLE_VERSION_MINOR 4 +#define LIBAVRESAMPLE_VERSION_MINOR 5 #define LIBAVRESAMPLE_VERSION_MICRO 0 #define LIBAVRESAMPLE_VERSION_INT AV_VERSION_INT(LIBAVRESAMPLE_VERSION_MAJOR, \ diff --git a/libavutil/version.h b/libavutil/version.h index d89a4187e8bb3..abea2163be35b 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 57 +#define LIBAVUTIL_VERSION_MINOR 58 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ diff --git a/libpostproc/version.h b/libpostproc/version.h index a174017332f51..0d2dc40fdbc88 100644 --- a/libpostproc/version.h +++ b/libpostproc/version.h @@ -29,7 +29,7 @@ #include "libavutil/avutil.h" #define LIBPOSTPROC_VERSION_MAJOR 54 -#define LIBPOSTPROC_VERSION_MINOR 4 +#define LIBPOSTPROC_VERSION_MINOR 5 #define LIBPOSTPROC_VERSION_MICRO 100 #define LIBPOSTPROC_VERSION_INT AV_VERSION_INT(LIBPOSTPROC_VERSION_MAJOR, \ diff --git a/libswresample/version.h b/libswresample/version.h index 2e80552b492a2..fb76f566fea70 100644 --- a/libswresample/version.h +++ b/libswresample/version.h @@ -29,7 +29,7 @@ #include "libavutil/avutil.h" #define LIBSWRESAMPLE_VERSION_MAJOR 2 -#define LIBSWRESAMPLE_VERSION_MINOR 6 +#define LIBSWRESAMPLE_VERSION_MINOR 7 #define LIBSWRESAMPLE_VERSION_MICRO 100 #define LIBSWRESAMPLE_VERSION_INT AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \ diff --git a/libswscale/version.h b/libswscale/version.h index e026848dccf61..c1090ca1dae3a 100644 --- a/libswscale/version.h +++ b/libswscale/version.h @@ -27,7 +27,7 @@ #include "libavutil/version.h" #define LIBSWSCALE_VERSION_MAJOR 4 -#define LIBSWSCALE_VERSION_MINOR 5 +#define LIBSWSCALE_VERSION_MINOR 6 #define LIBSWSCALE_VERSION_MICRO 100 #define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \ From 22b0daa1b3f0ac5d91cc1a057d230995590847cd Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 2 Apr 2017 19:54:12 +0200 Subject: [PATCH 1443/3374] Bump versions for master after 3.3 Signed-off-by: Michael Niedermayer --- libavcodec/version.h | 2 +- libavdevice/version.h | 2 +- libavfilter/version.h | 2 +- libavformat/version.h | 2 +- libavresample/version.h | 2 +- libavutil/version.h | 2 +- libpostproc/version.h | 2 +- libswresample/version.h | 2 +- libswscale/version.h | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libavcodec/version.h b/libavcodec/version.h index 51df9e0084df5..77da9b36b8a8a 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 89 +#define LIBAVCODEC_VERSION_MINOR 90 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ diff --git a/libavdevice/version.h b/libavdevice/version.h index 986ca98303b0d..0c0660209857e 100644 --- a/libavdevice/version.h +++ b/libavdevice/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVDEVICE_VERSION_MAJOR 57 -#define LIBAVDEVICE_VERSION_MINOR 6 +#define LIBAVDEVICE_VERSION_MINOR 7 #define LIBAVDEVICE_VERSION_MICRO 100 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ diff --git a/libavfilter/version.h b/libavfilter/version.h index 4cbd1857dbf8a..9a4d1c7feaa27 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 6 -#define LIBAVFILTER_VERSION_MINOR 82 +#define LIBAVFILTER_VERSION_MINOR 83 #define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavformat/version.h b/libavformat/version.h index fc054ee84ca86..0920b481458d6 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ // 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 57 -#define LIBAVFORMAT_VERSION_MINOR 71 +#define LIBAVFORMAT_VERSION_MINOR 72 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ diff --git a/libavresample/version.h b/libavresample/version.h index 89b4746d4e58d..f6d99cba0836d 100644 --- a/libavresample/version.h +++ b/libavresample/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVRESAMPLE_VERSION_MAJOR 3 -#define LIBAVRESAMPLE_VERSION_MINOR 5 +#define LIBAVRESAMPLE_VERSION_MINOR 6 #define LIBAVRESAMPLE_VERSION_MICRO 0 #define LIBAVRESAMPLE_VERSION_INT AV_VERSION_INT(LIBAVRESAMPLE_VERSION_MAJOR, \ diff --git a/libavutil/version.h b/libavutil/version.h index abea2163be35b..b0f9ba4f4e0d1 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 58 +#define LIBAVUTIL_VERSION_MINOR 59 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ diff --git a/libpostproc/version.h b/libpostproc/version.h index 0d2dc40fdbc88..3d7f8ea472d74 100644 --- a/libpostproc/version.h +++ b/libpostproc/version.h @@ -29,7 +29,7 @@ #include "libavutil/avutil.h" #define LIBPOSTPROC_VERSION_MAJOR 54 -#define LIBPOSTPROC_VERSION_MINOR 5 +#define LIBPOSTPROC_VERSION_MINOR 6 #define LIBPOSTPROC_VERSION_MICRO 100 #define LIBPOSTPROC_VERSION_INT AV_VERSION_INT(LIBPOSTPROC_VERSION_MAJOR, \ diff --git a/libswresample/version.h b/libswresample/version.h index fb76f566fea70..379177a1f46bf 100644 --- a/libswresample/version.h +++ b/libswresample/version.h @@ -29,7 +29,7 @@ #include "libavutil/avutil.h" #define LIBSWRESAMPLE_VERSION_MAJOR 2 -#define LIBSWRESAMPLE_VERSION_MINOR 7 +#define LIBSWRESAMPLE_VERSION_MINOR 8 #define LIBSWRESAMPLE_VERSION_MICRO 100 #define LIBSWRESAMPLE_VERSION_INT AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \ diff --git a/libswscale/version.h b/libswscale/version.h index c1090ca1dae3a..259ae7af63530 100644 --- a/libswscale/version.h +++ b/libswscale/version.h @@ -27,7 +27,7 @@ #include "libavutil/version.h" #define LIBSWSCALE_VERSION_MAJOR 4 -#define LIBSWSCALE_VERSION_MINOR 6 +#define LIBSWSCALE_VERSION_MINOR 7 #define LIBSWSCALE_VERSION_MICRO 100 #define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \ From f8e29a371622316c68db7017ab04dd447b0114ba Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 2 Apr 2017 16:09:16 -0300 Subject: [PATCH 1444/3374] build: Add missing object dependency for extract_extradata bitstream filter Cherry-picked from libav commit cfee5e1a0fa892fadd19b8848545d62f2386a6e7 Signed-off-by: James Almer --- libavcodec/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 7414d93424745..0dd0c7b1bb0c5 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -973,7 +973,8 @@ OBJS-$(CONFIG_AAC_ADTSTOASC_BSF) += aac_adtstoasc_bsf.o aacadtsdec.o \ OBJS-$(CONFIG_CHOMP_BSF) += chomp_bsf.o OBJS-$(CONFIG_DUMP_EXTRADATA_BSF) += dump_extradata_bsf.o OBJS-$(CONFIG_DCA_CORE_BSF) += dca_core_bsf.o -OBJS-$(CONFIG_EXTRACT_EXTRADATA_BSF) += extract_extradata_bsf.o +OBJS-$(CONFIG_EXTRACT_EXTRADATA_BSF) += extract_extradata_bsf.o \ + h2645_parse.o OBJS-$(CONFIG_H264_MP4TOANNEXB_BSF) += h264_mp4toannexb_bsf.o OBJS-$(CONFIG_HEVC_MP4TOANNEXB_BSF) += hevc_mp4toannexb_bsf.o OBJS-$(CONFIG_IMX_DUMP_HEADER_BSF) += imx_dump_header_bsf.o From 50e594956651cfc9f29745aa611ec6c8c1230864 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sun, 2 Apr 2017 18:38:36 -0300 Subject: [PATCH 1445/3374] Changelog: add 3.3 --- Changelog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Changelog b/Changelog index ad53c9dd553e9..28952a8fa9f84 100644 --- a/Changelog +++ b/Changelog @@ -2,6 +2,8 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. version : + +version 3.3: - CrystalHD decoder moved to new decode API - add internal ebur128 library, remove external libebur128 dependency - Pro-MPEG CoP #3-R2 FEC protocol From 7ab9d3f341016b76927d0876a47a13137369eb40 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sun, 2 Apr 2017 18:39:01 -0300 Subject: [PATCH 1446/3374] Changelog: add missing entry for VP8 QSV decoder --- Changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog b/Changelog index 28952a8fa9f84..d2e348c51af61 100644 --- a/Changelog +++ b/Changelog @@ -34,6 +34,7 @@ version 3.3: - Removed the legacy X11 screen grabber, use XCB instead - MPEG-7 Video Signature filter - Removed asyncts filter (use af_aresample instead) +- Intel QSV-accelerated VP8 video decoding version 3.2: From 3cbf717425b68ef1a731147748edd5c087af15a1 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 2 Apr 2017 22:55:33 +0100 Subject: [PATCH 1447/3374] Changelog: fix position of VAAPI MPEG-2/VP8 encode entry This was merged in the wrong place. --- Changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Changelog b/Changelog index d2e348c51af61..e76b324f61bc3 100644 --- a/Changelog +++ b/Changelog @@ -24,6 +24,7 @@ version 3.3: - threshold filter - midequalizer filter - Optimal Huffman tables for (M)JPEG encoding +- VAAPI-accelerated MPEG-2 and VP8 encoding - FM Screen Capture Codec decoder - native Opus encoder - ScreenPressor decoder @@ -122,7 +123,6 @@ version 3.1: - libutvideo wrapper removed - YUY2 Lossless Codec decoder - VideoToolbox H.264 encoder -- VAAPI-accelerated MPEG-2 and VP8 encoding version 3.0: From 08087f54626780b6955e470d59b1c7eff6c57f72 Mon Sep 17 00:00:00 2001 From: Jun Zhao Date: Wed, 29 Mar 2017 17:18:59 +0800 Subject: [PATCH 1448/3374] lavc/vaapi_encode: fix p_per_i calculate issue. now gop_size <= (max_b_frames + 1) * p_per_i + 1 (IDR frame), so celing p_per_i = (gop_size - 1 + max_b_frames) / (max_b_frames + 1) Signed-off-by: Jun Zhao Signed-off-by: Leilei Signed-off-by: Mark Thompson --- libavcodec/vaapi_encode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index 070ff5f2442f6..7e9c00f51d23f 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -1433,7 +1433,7 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) ctx->output_order = - ctx->output_delay - 1; // Currently we never generate I frames, only IDR. - ctx->p_per_i = ((avctx->gop_size + avctx->max_b_frames) / + ctx->p_per_i = ((avctx->gop_size - 1 + avctx->max_b_frames) / (avctx->max_b_frames + 1)); ctx->b_per_p = avctx->max_b_frames; From 8163314967ae0f08971eac9745177e5de0550754 Mon Sep 17 00:00:00 2001 From: Martin Vignali Date: Sun, 2 Apr 2017 21:11:32 +0200 Subject: [PATCH 1449/3374] libavcodec/exr : fix scanline offset table recreation on big endian Signed-off-by: Michael Niedermayer --- libavcodec/exr.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/libavcodec/exr.c b/libavcodec/exr.c index e5dea0756d550..7cf3620d7f0d0 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -1648,9 +1648,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int y, ret; int out_line_size; int nb_blocks; /* nb scanline or nb tile */ - uint64_t *table; /* scanline offset table */ - uint8_t *marker; /* used to recreate invalid scanline offset table */ - uint8_t *head; + uint64_t start_offset_table; + uint64_t start_next_scanline; + PutByteContext offset_table_writer; bytestream2_init(&s->gb, avpkt->data, avpkt->size); @@ -1738,16 +1738,21 @@ static int decode_frame(AVCodecContext *avctx, void *data, // check offset table and recreate it if need if (!s->is_tile && bytestream2_peek_le64(&s->gb) == 0) { - head = avpkt->data; - table = (uint64_t *)s->gb.buffer; - marker = head + bytestream2_tell(&s->gb) + nb_blocks * 8; - av_log(s->avctx, AV_LOG_DEBUG, "recreating invalid scanline offset table\n"); + start_offset_table = bytestream2_tell(&s->gb); + start_next_scanline = start_offset_table + nb_blocks * 8; + bytestream2_init_writer(&offset_table_writer, &avpkt->data[start_offset_table], nb_blocks * 8); + for (y = 0; y < nb_blocks; y++) { - table[y] = marker - head; - marker += ((uint32_t *)marker)[1] + 8; + /* write offset of prev scanline in offset table */ + bytestream2_put_le64(&offset_table_writer, start_next_scanline); + + /* get len of next scanline */ + bytestream2_seek(&s->gb, start_next_scanline + 4, SEEK_SET);/* skip line number */ + start_next_scanline += (bytestream2_get_le32(&s->gb) + 8); } + bytestream2_seek(&s->gb, start_offset_table, SEEK_SET); } // save pointer we are going to use in decode_block From 4db2bfa63c4e2a82a6858a6953812ed64885e2dc Mon Sep 17 00:00:00 2001 From: Martin Vignali Date: Sun, 2 Apr 2017 21:13:01 +0200 Subject: [PATCH 1450/3374] fate : add test for exr with offset table set to 0 Signed-off-by: Michael Niedermayer --- tests/fate/image.mak | 3 +++ .../fate/exr-rgb-scanline-zip1-half-float-l1-zero-offsets | 6 ++++++ 2 files changed, 9 insertions(+) create mode 100644 tests/ref/fate/exr-rgb-scanline-zip1-half-float-l1-zero-offsets diff --git a/tests/fate/image.mak b/tests/fate/image.mak index ef0495584b456..8284ed2a6349d 100644 --- a/tests/fate/image.mak +++ b/tests/fate/image.mak @@ -253,6 +253,9 @@ fate-exr-rgb-scanline-b44-uint32: CMD = framecrc -i $(TARGET_SAMPLES)/exr/rgb_sc FATE_EXR += fate-exr-rgb-scanline-pxr24-uint32 fate-exr-rgb-scanline-pxr24-uint32: CMD = framecrc -i $(TARGET_SAMPLES)/exr/rgb_scanline_pxr24_uint32.exr -pix_fmt rgb48le +FATE_EXR += fate-exr-rgb-scanline-zip1-half-float-l1-zero-offsets +fate-exr-rgb-scanline-zip1-half-float-l1-zero-offsets: CMD = framecrc -i $(TARGET_SAMPLES)/exr/rgb_scanline_zip1_half_float_zero_offsets.exr -pix_fmt rgb48le + FATE_EXR-$(call DEMDEC, IMAGE2, EXR) += $(FATE_EXR) FATE_IMAGE += $(FATE_EXR-yes) diff --git a/tests/ref/fate/exr-rgb-scanline-zip1-half-float-l1-zero-offsets b/tests/ref/fate/exr-rgb-scanline-zip1-half-float-l1-zero-offsets new file mode 100644 index 0000000000000..af042043e7ee9 --- /dev/null +++ b/tests/ref/fate/exr-rgb-scanline-zip1-half-float-l1-zero-offsets @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 12x8 +#sar 0: 1/1 +0, 0, 0, 1, 576, 0x5ede004c From e72690b18da064f6c0f04f09ccde72b6636e3159 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 3 Apr 2017 09:25:15 -0400 Subject: [PATCH 1451/3374] h264: don't sync pic_id between threads. This is how the ref list manager links bitstream IDs to H264Picture/Ref objects, and is local to the producer thread. There is no need for the consumer thread to know the bitstream IDs of its references in their respective producer threads. In practice, this fixes tsan warnings when running fate-h264: WARNING: ThreadSanitizer: data race (pid=19295) Read of size 4 at 0x7dbc0000e614 by main thread (mutexes: write M1914): #0 ff_h264_ref_picture src/libavcodec/h264_picture.c:112 (ffmpeg+0x0000013b3709) [..] Previous write of size 4 at 0x7dbc0000e614 by thread T2 (mutexes: write M1917): #0 build_def_list src/libavcodec/h264_refs.c:91 (ffmpeg+0x0000013b46cf) --- libavcodec/h264_picture.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libavcodec/h264_picture.c b/libavcodec/h264_picture.c index db9673793a7b9..2dbe5ee40b48d 100644 --- a/libavcodec/h264_picture.c +++ b/libavcodec/h264_picture.c @@ -109,7 +109,6 @@ int ff_h264_ref_picture(H264Context *h, H264Picture *dst, H264Picture *src) dst->poc = src->poc; dst->frame_num = src->frame_num; dst->mmco_reset = src->mmco_reset; - dst->pic_id = src->pic_id; dst->long_ref = src->long_ref; dst->mbaff = src->mbaff; dst->field_picture = src->field_picture; From 467a0538100b193d205a922737358dcc8e957e94 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 3 Apr 2017 09:36:32 -0400 Subject: [PATCH 1452/3374] codec_desc: mark some lossless audio codecs as intraonly. Fixes tsan warnings in several audio codecs (flac, alac, wavpack, tta and tak) that look like this: WARNING: ThreadSanitizer: data race (pid=14340) Read of size 4 at 0x7d64000169d8 by main thread (mutexes: write M1335): #0 update_context_from_thread src/libavcodec/pthread_frame.c:284 (ffmpeg+0x000000dc795f) [..] Previous write of size 4 at 0x7d64000169d8 by thread T1 (mutexes: write M1333): #0 wavpack_decode_block src/libavcodec/wavpack.c:1012 (ffmpeg+0x00000112b175) --- libavcodec/avcodec.h | 2 +- libavcodec/codec_desc.c | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index d7804773cbefa..6f38b3fdd65e0 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -724,7 +724,7 @@ typedef struct AVCodecDescriptor { /** * Codec uses only intra compression. - * Video codecs only. + * Video and audio codecs only. */ #define AV_CODEC_PROP_INTRA_ONLY (1 << 0) /** diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 9711019e9d1d8..041b797a22fb8 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -2313,7 +2313,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_AUDIO, .name = "flac", .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"), - .props = AV_CODEC_PROP_LOSSLESS, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_MP3ADU, @@ -2341,7 +2341,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_AUDIO, .name = "alac", .long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"), - .props = AV_CODEC_PROP_LOSSLESS, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_WESTWOOD_SND1, @@ -2383,7 +2383,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_AUDIO, .name = "tta", .long_name = NULL_IF_CONFIG_SMALL("TTA (True Audio)"), - .props = AV_CODEC_PROP_LOSSLESS, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_SMACKAUDIO, @@ -2404,7 +2404,8 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_AUDIO, .name = "wavpack", .long_name = NULL_IF_CONFIG_SMALL("WavPack"), - .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS, + .props = AV_CODEC_PROP_INTRA_ONLY | + AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_DSICINAUDIO, @@ -2712,7 +2713,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_AUDIO, .name = "tak", .long_name = NULL_IF_CONFIG_SMALL("TAK (Tom's lossless Audio Kompressor)"), - .props = AV_CODEC_PROP_LOSSLESS, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_METASOUND, From 76d8c77430e9e0110623705bfb54d922cc2ac3ea Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 31 Mar 2017 11:27:20 -0400 Subject: [PATCH 1453/3374] ffmpeg: make transcode_init_done atomic. Should fix tsan warnings in fate-fifo-muxer-h264/wav: WARNING: ThreadSanitizer: data race (pid=26552) Write of size 4 at 0x000001e0d7c0 by main thread: #0 transcode_init src/ffmpeg.c:3761 (ffmpeg+0x00000050ca1c) [..] Previous read of size 4 at 0x000001e0d7c0 by thread T1: #0 decode_interrupt_cb src/ffmpeg.c:460 (ffmpeg+0x0000004fde19) --- ffmpeg.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index 11faf0d4a8001..ea03179c21e8a 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #if HAVE_IO_H @@ -319,7 +320,7 @@ void term_exit(void) static volatile int received_sigterm = 0; static volatile int received_nb_signals = 0; -static volatile int transcode_init_done = 0; +static atomic_int transcode_init_done = ATOMIC_VAR_INIT(0); static volatile int ffmpeg_exited = 0; static int main_return_code = 0; @@ -457,7 +458,7 @@ static int read_key(void) static int decode_interrupt_cb(void *ctx) { - return received_nb_signals > transcode_init_done; + return received_nb_signals > atomic_load(&transcode_init_done); } const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL }; @@ -612,7 +613,7 @@ static void ffmpeg_cleanup(int ret) if (received_sigterm) { av_log(NULL, AV_LOG_INFO, "Exiting normally, received signal %d.\n", (int) received_sigterm); - } else if (ret && transcode_init_done) { + } else if (ret && atomic_load(&transcode_init_done)) { av_log(NULL, AV_LOG_INFO, "Conversion failed!\n"); } term_exit(); @@ -3758,7 +3759,7 @@ static int transcode_init(void) return ret; } - transcode_init_done = 1; + atomic_store(&transcode_init_done, 1); return 0; } From 1269cd5b6f540bef5913bf134d2f461aac50d70b Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 3 Apr 2017 09:48:53 -0400 Subject: [PATCH 1454/3374] pthread_frame: call update_context_from_user() after acquiring lock. Otherwise the thread may still be in the middle of decoding a previous frame, which would effectively trigger a race condition on any field concurrently read and written. In practice, this fixes tsan warnings like the following: WARNING: ThreadSanitizer: data race (pid=17380) Write of size 4 at 0x7d64000160fc by main thread: #0 update_context_from_user src/libavcodec/pthread_frame.c:335 (ffmpeg+0x000000dca515) [..] Previous read of size 4 at 0x7d64000160fc by thread T2 (mutexes: write M1821): #0 ff_thread_report_progress src/libavcodec/pthread_frame.c:565 (ffmpeg+0x000000dcb08a) --- libavcodec/pthread_frame.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 4e1ad9d686392..9a6b83ac459cd 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -380,7 +380,8 @@ static void release_delayed_buffers(PerThreadContext *p) } } -static int submit_packet(PerThreadContext *p, AVPacket *avpkt) +static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx, + AVPacket *avpkt) { FrameThreadContext *fctx = p->parent; PerThreadContext *prev_thread = fctx->prev_thread; @@ -392,6 +393,12 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt) pthread_mutex_lock(&p->mutex); + ret = update_context_from_user(p->avctx, user_avctx); + if (ret) { + pthread_mutex_unlock(&p->mutex); + return ret; + } + release_delayed_buffers(p); if (prev_thread) { @@ -480,10 +487,7 @@ int ff_thread_decode_frame(AVCodecContext *avctx, */ p = &fctx->threads[fctx->next_decoding]; - err = update_context_from_user(p->avctx, avctx); - if (err) - goto finish; - err = submit_packet(p, avpkt); + err = submit_packet(p, avctx, avpkt); if (err) goto finish; From 1f50baa2b2da7fdbfccf0662883f38a763ff6619 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 3 Apr 2017 09:51:10 -0400 Subject: [PATCH 1455/3374] hevc: only write to max_ra and pocTid0 in the first slice. Values from subsequent values are guaranteed to be identical (since poc and nal_unit_type are checked to be the same between slices), so this doesn't affect output in any way, but does resolve the remaining reported race conditions (by tsan) in fate-hevc. In practice, this fixes tsan warnings like this: WARNING: ThreadSanitizer: data race (pid=25334) Read of size 4 at 0x7d9c0001adcc by main thread (mutexes: write M1386): #0 hevc_update_thread_context src/libavcodec/hevcdec.c:3310 (ffmpeg+0x000000b41c7c) [..] Previous write of size 4 at 0x7d9c0001adcc by thread T1 (mutexes: write M1383): #0 hls_slice_header src/libavcodec/hevcdec.c:596 (ffmpeg+0x000000b43a22) --- libavcodec/hevcdec.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index ef21595c4436c..f9e8ff0c9f2af 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -585,7 +585,7 @@ static int hls_slice_header(HEVCContext *s) } /* 8.3.1 */ - if (s->temporal_id == 0 && + if (sh->first_slice_in_pic_flag && s->temporal_id == 0 && s->nal_unit_type != HEVC_NAL_TRAIL_N && s->nal_unit_type != HEVC_NAL_TSA_N && s->nal_unit_type != HEVC_NAL_STSA_N && @@ -2771,25 +2771,25 @@ static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal) if (ret < 0) return ret; - if (s->max_ra == INT_MAX) { - if (s->nal_unit_type == HEVC_NAL_CRA_NUT || IS_BLA(s)) { - s->max_ra = s->poc; + if (s->sh.first_slice_in_pic_flag) { + if (s->max_ra == INT_MAX) { + if (s->nal_unit_type == HEVC_NAL_CRA_NUT || IS_BLA(s)) { + s->max_ra = s->poc; + } else { + if (IS_IDR(s)) + s->max_ra = INT_MIN; + } + } + + if ((s->nal_unit_type == HEVC_NAL_RASL_R || s->nal_unit_type == HEVC_NAL_RASL_N) && + s->poc <= s->max_ra) { + s->is_decoded = 0; + break; } else { - if (IS_IDR(s)) + if (s->nal_unit_type == HEVC_NAL_RASL_R && s->poc > s->max_ra) s->max_ra = INT_MIN; } - } - - if ((s->nal_unit_type == HEVC_NAL_RASL_R || s->nal_unit_type == HEVC_NAL_RASL_N) && - s->poc <= s->max_ra) { - s->is_decoded = 0; - break; - } else { - if (s->nal_unit_type == HEVC_NAL_RASL_R && s->poc > s->max_ra) - s->max_ra = INT_MIN; - } - if (s->sh.first_slice_in_pic_flag) { ret = hevc_frame_start(s); if (ret < 0) return ret; From 478f1c3d5e5463a284ea7efecfc62d47ba3be11a Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 3 Apr 2017 10:08:29 -0400 Subject: [PATCH 1456/3374] png: split header state and data state in two separate variables. Fixes a reported (but false) race condition in tsan for fate-apng: WARNING: ThreadSanitizer: data race (pid=6274) Read of size 4 at 0x7d680001ec78 by main thread (mutexes: write M1338): #0 update_thread_context src/libavcodec/pngdec.c:1456 (ffmpeg+0x000000dacf0c) [..] Previous write of size 4 at 0x7d680001ec78 by thread T1 (mutexes: write M1335): #0 decode_idat_chunk src/libavcodec/pngdec.c:737 (ffmpeg+0x000000dae951) --- libavcodec/png.h | 5 ---- libavcodec/pngdec.c | 65 +++++++++++++++++++++++++++------------------ 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/libavcodec/png.h b/libavcodec/png.h index 948c2f714f33f..e967fcf38fb11 100644 --- a/libavcodec/png.h +++ b/libavcodec/png.h @@ -42,11 +42,6 @@ #define PNG_FILTER_VALUE_PAETH 4 #define PNG_FILTER_VALUE_MIXED 5 -#define PNG_IHDR 0x0001 -#define PNG_IDAT 0x0002 -#define PNG_ALLIMAGE 0x0004 -#define PNG_PLTE 0x0008 - #define NB_PASSES 7 #define PNGSIG 0x89504e470d0a1a0a diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index c08665be7c547..d184c34b81bd6 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -36,6 +36,16 @@ #include +enum PNGHeaderState { + PNG_IHDR = 1 << 0, + PNG_PLTE = 1 << 1, +}; + +enum PNGImageState { + PNG_IDAT = 1 << 0, + PNG_ALLIMAGE = 1 << 1, +}; + typedef struct PNGDecContext { PNGDSPContext dsp; AVCodecContext *avctx; @@ -45,7 +55,8 @@ typedef struct PNGDecContext { ThreadFrame last_picture; ThreadFrame picture; - int state; + enum PNGHeaderState hdr_state; + enum PNGImageState pic_state; int width, height; int cur_w, cur_h; int last_w, last_h; @@ -334,7 +345,7 @@ static void png_handle_row(PNGDecContext *s) } s->y++; if (s->y == s->cur_h) { - s->state |= PNG_ALLIMAGE; + s->pic_state |= PNG_ALLIMAGE; if (s->filter_type == PNG_FILTER_TYPE_LOCO) { if (s->bit_depth == 16) { deloco_rgb16((uint16_t *)ptr, s->row_size / 2, @@ -369,7 +380,7 @@ static void png_handle_row(PNGDecContext *s) memset(s->last_row, 0, s->row_size); for (;;) { if (s->pass == NB_PASSES - 1) { - s->state |= PNG_ALLIMAGE; + s->pic_state |= PNG_ALLIMAGE; goto the_end; } else { s->pass++; @@ -404,7 +415,7 @@ static int png_decode_idat(PNGDecContext *s, int length) return AVERROR_EXTERNAL; } if (s->zstream.avail_out == 0) { - if (!(s->state & PNG_ALLIMAGE)) { + if (!(s->pic_state & PNG_ALLIMAGE)) { png_handle_row(s); } s->zstream.avail_out = s->crow_size; @@ -541,12 +552,12 @@ static int decode_ihdr_chunk(AVCodecContext *avctx, PNGDecContext *s, if (length != 13) return AVERROR_INVALIDDATA; - if (s->state & PNG_IDAT) { + if (s->pic_state & PNG_IDAT) { av_log(avctx, AV_LOG_ERROR, "IHDR after IDAT\n"); return AVERROR_INVALIDDATA; } - if (s->state & PNG_IHDR) { + if (s->hdr_state & PNG_IHDR) { av_log(avctx, AV_LOG_ERROR, "Multiple IHDR\n"); return AVERROR_INVALIDDATA; } @@ -569,7 +580,7 @@ static int decode_ihdr_chunk(AVCodecContext *avctx, PNGDecContext *s, s->filter_type = bytestream2_get_byte(&s->gb); s->interlace_type = bytestream2_get_byte(&s->gb); bytestream2_skip(&s->gb, 4); /* crc */ - s->state |= PNG_IHDR; + s->hdr_state |= PNG_IHDR; if (avctx->debug & FF_DEBUG_PICT_INFO) av_log(avctx, AV_LOG_DEBUG, "width=%d height=%d depth=%d color_type=%d " "compression_type=%d filter_type=%d interlace_type=%d\n", @@ -585,7 +596,7 @@ static int decode_ihdr_chunk(AVCodecContext *avctx, PNGDecContext *s, static int decode_phys_chunk(AVCodecContext *avctx, PNGDecContext *s) { - if (s->state & PNG_IDAT) { + if (s->pic_state & PNG_IDAT) { av_log(avctx, AV_LOG_ERROR, "pHYs after IDAT\n"); return AVERROR_INVALIDDATA; } @@ -605,11 +616,11 @@ static int decode_idat_chunk(AVCodecContext *avctx, PNGDecContext *s, int ret; size_t byte_depth = s->bit_depth > 8 ? 2 : 1; - if (!(s->state & PNG_IHDR)) { + if (!(s->hdr_state & PNG_IHDR)) { av_log(avctx, AV_LOG_ERROR, "IDAT without IHDR\n"); return AVERROR_INVALIDDATA; } - if (!(s->state & PNG_IDAT)) { + if (!(s->pic_state & PNG_IDAT)) { /* init image info */ avctx->width = s->width; avctx->height = s->height; @@ -734,7 +745,7 @@ static int decode_idat_chunk(AVCodecContext *avctx, PNGDecContext *s, s->zstream.next_out = s->crow_buf; } - s->state |= PNG_IDAT; + s->pic_state |= PNG_IDAT; /* set image to non-transparent bpp while decompressing */ if (s->has_trns && s->color_type != PNG_COLOR_TYPE_PALETTE) @@ -770,7 +781,7 @@ static int decode_plte_chunk(AVCodecContext *avctx, PNGDecContext *s, } for (; i < 256; i++) s->palette[i] = (0xFFU << 24); - s->state |= PNG_PLTE; + s->hdr_state |= PNG_PLTE; bytestream2_skip(&s->gb, 4); /* crc */ return 0; @@ -781,18 +792,18 @@ static int decode_trns_chunk(AVCodecContext *avctx, PNGDecContext *s, { int v, i; - if (!(s->state & PNG_IHDR)) { + if (!(s->hdr_state & PNG_IHDR)) { av_log(avctx, AV_LOG_ERROR, "trns before IHDR\n"); return AVERROR_INVALIDDATA; } - if (s->state & PNG_IDAT) { + if (s->pic_state & PNG_IDAT) { av_log(avctx, AV_LOG_ERROR, "trns after IDAT\n"); return AVERROR_INVALIDDATA; } if (s->color_type == PNG_COLOR_TYPE_PALETTE) { - if (length > 256 || !(s->state & PNG_PLTE)) + if (length > 256 || !(s->hdr_state & PNG_PLTE)) return AVERROR_INVALIDDATA; for (i = 0; i < length; i++) { @@ -906,7 +917,7 @@ static int decode_fctl_chunk(AVCodecContext *avctx, PNGDecContext *s, if (length != 26) return AVERROR_INVALIDDATA; - if (!(s->state & PNG_IHDR)) { + if (!(s->hdr_state & PNG_IHDR)) { av_log(avctx, AV_LOG_ERROR, "fctl before IHDR\n"); return AVERROR_INVALIDDATA; } @@ -1122,13 +1133,13 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, } if (CONFIG_APNG_DECODER && avctx->codec_id == AV_CODEC_ID_APNG && length == 0) { - if (!(s->state & PNG_IDAT)) + if (!(s->pic_state & PNG_IDAT)) return 0; else goto exit_loop; } av_log(avctx, AV_LOG_ERROR, "%d bytes left\n", length); - if ( s->state & PNG_ALLIMAGE + if ( s->pic_state & PNG_ALLIMAGE && avctx->strict_std_compliance <= FF_COMPLIANCE_NORMAL) goto exit_loop; ret = AVERROR_INVALIDDATA; @@ -1228,9 +1239,9 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, break; } case MKTAG('I', 'E', 'N', 'D'): - if (!(s->state & PNG_ALLIMAGE)) + if (!(s->pic_state & PNG_ALLIMAGE)) av_log(avctx, AV_LOG_ERROR, "IEND without all image\n"); - if (!(s->state & (PNG_ALLIMAGE|PNG_IDAT))) { + if (!(s->pic_state & (PNG_ALLIMAGE|PNG_IDAT))) { ret = AVERROR_INVALIDDATA; goto fail; } @@ -1330,7 +1341,9 @@ static int decode_frame_png(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } - s->y = s->state = s->has_trns = 0; + s->y = s->has_trns = 0; + s->hdr_state = 0; + s->pic_state = 0; /* init the zlib */ s->zstream.zalloc = ff_png_zalloc; @@ -1377,7 +1390,7 @@ static int decode_frame_apng(AVCodecContext *avctx, FFSWAP(ThreadFrame, s->picture, s->last_picture); p = s->picture.f; - if (!(s->state & PNG_IHDR)) { + if (!(s->hdr_state & PNG_IHDR)) { if (!avctx->extradata_size) return AVERROR_INVALIDDATA; @@ -1397,14 +1410,14 @@ static int decode_frame_apng(AVCodecContext *avctx, goto end; } s->y = 0; - s->state &= ~(PNG_IDAT | PNG_ALLIMAGE); + s->pic_state = 0; bytestream2_init(&s->gb, avpkt->data, avpkt->size); if ((ret = decode_frame_common(avctx, s, p, avpkt)) < 0) goto end; - if (!(s->state & PNG_ALLIMAGE)) + if (!(s->pic_state & PNG_ALLIMAGE)) av_log(avctx, AV_LOG_WARNING, "Frame did not contain a complete image\n"); - if (!(s->state & (PNG_ALLIMAGE|PNG_IDAT))) { + if (!(s->pic_state & (PNG_ALLIMAGE|PNG_IDAT))) { ret = AVERROR_INVALIDDATA; goto end; } @@ -1453,7 +1466,7 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) memcpy(pdst->palette, psrc->palette, sizeof(pdst->palette)); - pdst->state |= psrc->state & (PNG_IHDR | PNG_PLTE); + pdst->hdr_state |= psrc->hdr_state; ff_thread_release_buffer(dst, &pdst->last_picture); if (psrc->last_picture.f->data[0] && From eff2861a757b8a46398e6fcb844b960b4775daad Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 3 Apr 2017 14:43:40 -0400 Subject: [PATCH 1457/3374] png: set AVFrame flags/fields before calling setup_finished(). Fixes tsan warnings in fate-apng: WARNING: ThreadSanitizer: data race (pid=51230) Read of size 4 at 0x7d50000042fc by main thread (mutexes: write M1000): #0 frame_copy_props frame.c:302 (ffmpeg:x86_64+0x1019a35d6) [..] Previous write of size 4 at 0x7d50000042fc by thread T1 (mutexes: write M997): #0 decode_idat_chunk pngdec.c:708 (ffmpeg:x86_64+0x100f5562a) --- libavcodec/pngdec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index d184c34b81bd6..102551972ead3 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -701,12 +701,12 @@ static int decode_idat_chunk(AVCodecContext *avctx, PNGDecContext *s, if ((ret = ff_thread_get_buffer(avctx, &s->previous_picture, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; } - ff_thread_finish_setup(avctx); - p->pict_type = AV_PICTURE_TYPE_I; p->key_frame = 1; p->interlaced_frame = !!s->interlace_type; + ff_thread_finish_setup(avctx); + /* compute the compressed row size */ if (!s->interlace_type) { s->crow_size = s->row_size + 1; From 7e59393d40b784bcf34ae231fb8e99673585e3e1 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 2 Apr 2017 22:07:04 +0200 Subject: [PATCH 1458/3374] avfilter/vf_pad: add aspect option Signed-off-by: Paul B Mahol --- doc/filters.texi | 3 +++ libavfilter/vf_pad.c | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/doc/filters.texi b/doc/filters.texi index 8e5e21f9eda97..bc37e667e0bf4 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -10453,6 +10453,9 @@ Evaluate expressions for each incoming frame. Default value is @samp{init}. +@item aspect +Pad to aspect instead to a resolution. + @end table The value for the @var{width}, @var{height}, @var{x}, and @var{y} diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c index 61927b654aba1..44a8fec0cb3f9 100644 --- a/libavfilter/vf_pad.c +++ b/libavfilter/vf_pad.c @@ -24,6 +24,8 @@ * video padding filter */ +#include /* DBL_MAX */ + #include "avfilter.h" #include "formats.h" #include "internal.h" @@ -87,6 +89,7 @@ typedef struct PadContext { int x, y; ///< offsets of the input area with respect to the padded area int in_w, in_h; ///< width and height for the padded input video, which has to be aligned to the chroma values in order to avoid chroma issues int inlink_w, inlink_h; + AVRational aspect; char *w_expr; ///< width expression string char *h_expr; ///< height expression string @@ -103,6 +106,7 @@ static int config_input(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; PadContext *s = ctx->priv; + AVRational adjusted_aspect = s->aspect; int ret; double var_values[VARS_NB], res; char *expr; @@ -143,6 +147,15 @@ static int config_input(AVFilterLink *inlink) if (!s->w) var_values[VAR_OUT_W] = var_values[VAR_OW] = s->w = inlink->w; + if (adjusted_aspect.num && adjusted_aspect.den) { + adjusted_aspect = av_div_q(adjusted_aspect, inlink->sample_aspect_ratio); + if (s->h < av_rescale(s->w, adjusted_aspect.den, adjusted_aspect.num)) { + s->h = var_values[VAR_OUT_H] = var_values[VAR_OH] = av_rescale(s->w, adjusted_aspect.den, adjusted_aspect.num); + } else { + s->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = av_rescale(s->h, adjusted_aspect.num, adjusted_aspect.den); + } + } + /* evaluate x and y */ av_expr_parse_and_eval(&res, (expr = s->x_expr), var_names, var_values, @@ -409,6 +422,7 @@ static const AVOption pad_options[] = { { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_INIT}, 0, EVAL_MODE_NB-1, FLAGS, "eval" }, { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" }, { "frame", "eval expressions during initialization and per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" }, + { "aspect", "pad to fit an aspect instead of a resolution", OFFSET(aspect), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, DBL_MAX, FLAGS }, { NULL } }; From c169ab4112c063f53440c51f007ffce0c0d394b1 Mon Sep 17 00:00:00 2001 From: James Almer Date: Mon, 3 Apr 2017 18:08:43 -0300 Subject: [PATCH 1459/3374] avcodec/Makefile: fix truehd encoder dependencies Signed-off-by: James Almer --- libavcodec/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 0dd0c7b1bb0c5..adba0c1b2abc8 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -560,7 +560,7 @@ OBJS-$(CONFIG_TIFF_DECODER) += tiff.o lzw.o faxcompr.o tiff_data.o ti OBJS-$(CONFIG_TIFF_ENCODER) += tiffenc.o rle.o lzwenc.o tiff_data.o OBJS-$(CONFIG_TMV_DECODER) += tmv.o cga_data.o OBJS-$(CONFIG_TRUEHD_DECODER) += mlpdec.o mlpdsp.o -OBJS-$(CONFIG_TRUEHD_ENCODER) += mlpenc.o +OBJS-$(CONFIG_TRUEHD_ENCODER) += mlpenc.o mlp.o OBJS-$(CONFIG_TRUEMOTION1_DECODER) += truemotion1.o OBJS-$(CONFIG_TRUEMOTION2_DECODER) += truemotion2.o OBJS-$(CONFIG_TRUEMOTION2RT_DECODER) += truemotion2rt.o From 39ee3ddff87a12e108fc4e0d36f756d0ca080472 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 1 Apr 2017 19:18:36 +0200 Subject: [PATCH 1460/3374] avformat/mov: Check creation_time for overflow Fixes integer overflow Fixes: 701640 Found-by: Found-by: Thomas Guilbert Signed-off-by: Michael Niedermayer --- libavformat/mov.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libavformat/mov.c b/libavformat/mov.c index 4550cf0ad4135..90bc2499da2fe 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1186,6 +1186,12 @@ static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time) if (time) { if(time >= 2082844800) time -= 2082844800; /* seconds between 1904-01-01 and Epoch */ + + if ((int64_t)(time * 1000000ULL) / 1000000 != time) { + av_log(NULL, AV_LOG_DEBUG, "creation_time is not representable\n"); + return; + } + avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000); } } From dc1a1b8bd795f5fa6ec3b8f38eb97b8d98ed73fc Mon Sep 17 00:00:00 2001 From: Thomas Turner Date: Sun, 2 Apr 2017 15:27:57 -0700 Subject: [PATCH 1461/3374] tests/fate/filter-video: add owdenoise test Signed-off-by: Michael Niedermayer --- tests/fate/filter-video.mak | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak index b067cc146f3b2..b40422a4dcdd8 100644 --- a/tests/fate/filter-video.mak +++ b/tests/fate/filter-video.mak @@ -1,3 +1,10 @@ +FATE_FILTER_SAMPLES-$(call ALLYES, SMJPEG_DEMUXER MJPEG_DECODER PERMS_FILTER OWDENOISE_FILTER) += fate-filter-owdenoise-sample +fate-filter-owdenoise-sample: CMD = ffmpeg -idct simple -i $(TARGET_SAMPLES)/smjpeg/scenwin.mjpg -vf "trim=duration=0.5,perms=random,owdenoise=10:20:20:enable=not(between(t\,0.2\,1.2))" -an -f rawvideo - +fate-filter-owdenoise-sample: REF = $(TARGET_SAMPLES)/filter-reference/owdenoise-scenwin.raw +fate-filter-owdenoise-sample: CMP_TARGET = 1 +fate-filter-owdenoise-sample: FUZZ = 3539 +fate-filter-owdenoise-sample: CMP = oneoff + FATE_FILTER_SAMPLES-$(call ALLYES, PERMS_FILTER DELOGO_FILTER RM_DEMUXER RV30_DECODER) += fate-filter-delogo fate-filter-delogo: CMD = framecrc -i $(TARGET_SAMPLES)/real/rv30.rm -vf perms=random,delogo=show=0:x=290:y=25:w=26:h=16 -an From 2a88ebd096f3c748a2d99ed1b60b22879b3c567c Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 30 Mar 2017 16:58:04 +0200 Subject: [PATCH 1462/3374] ffprobe: port to new decode API Not sure if it behaves ideally in presence of decoding errors. --- ffprobe.c | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/ffprobe.c b/ffprobe.c index 356746870e2d3..0a9ba14d8dc43 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -2130,7 +2130,8 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream, static av_always_inline int process_frame(WriterContext *w, InputFile *ifile, - AVFrame *frame, AVPacket *pkt) + AVFrame *frame, AVPacket *pkt, + int *packet_new) { AVFormatContext *fmt_ctx = ifile->fmt_ctx; AVCodecContext *dec_ctx = ifile->streams[pkt->stream_index].dec_ctx; @@ -2142,24 +2143,39 @@ static av_always_inline int process_frame(WriterContext *w, if (dec_ctx && dec_ctx->codec) { switch (par->codec_type) { case AVMEDIA_TYPE_VIDEO: - ret = avcodec_decode_video2(dec_ctx, frame, &got_frame, pkt); - break; - case AVMEDIA_TYPE_AUDIO: - ret = avcodec_decode_audio4(dec_ctx, frame, &got_frame, pkt); + if (*packet_new) { + ret = avcodec_send_packet(dec_ctx, pkt); + if (ret == AVERROR(EAGAIN)) { + ret = 0; + } else if (ret >= 0 || ret == AVERROR_EOF) { + ret = 0; + *packet_new = 0; + } + } + if (ret >= 0) { + ret = avcodec_receive_frame(dec_ctx, frame); + if (ret >= 0) { + got_frame = 1; + } else if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { + ret = 0; + } + } break; case AVMEDIA_TYPE_SUBTITLE: ret = avcodec_decode_subtitle2(dec_ctx, &sub, &got_frame, pkt); + *packet_new = 0; break; + default: + *packet_new = 0; } + } else { + *packet_new = 0; } if (ret < 0) return ret; - ret = FFMIN(ret, pkt->size); /* guard against bogus return values */ - pkt->data += ret; - pkt->size -= ret; if (got_frame) { int is_sub = (par->codec_type == AVMEDIA_TYPE_SUBTITLE); nb_streams_frames[pkt->stream_index]++; @@ -2171,7 +2187,7 @@ static av_always_inline int process_frame(WriterContext *w, if (is_sub) avsubtitle_free(&sub); } - return got_frame; + return got_frame || *packet_new; } static void log_read_interval(const ReadInterval *interval, void *log_ctx, int log_level) @@ -2202,7 +2218,7 @@ static int read_interval_packets(WriterContext *w, InputFile *ifile, const ReadInterval *interval, int64_t *cur_ts) { AVFormatContext *fmt_ctx = ifile->fmt_ctx; - AVPacket pkt, pkt1; + AVPacket pkt; AVFrame *frame = NULL; int ret = 0, i = 0, frame_count = 0; int64_t start = -INT64_MAX, end = interval->end; @@ -2279,8 +2295,8 @@ static int read_interval_packets(WriterContext *w, InputFile *ifile, nb_streams_packets[pkt.stream_index]++; } if (do_read_frames) { - pkt1 = pkt; - while (pkt1.size && process_frame(w, ifile, frame, &pkt1) > 0); + int packet_new = 1; + while (process_frame(w, ifile, frame, &pkt, &packet_new) > 0); } } av_packet_unref(&pkt); @@ -2292,7 +2308,7 @@ static int read_interval_packets(WriterContext *w, InputFile *ifile, for (i = 0; i < fmt_ctx->nb_streams; i++) { pkt.stream_index = i; if (do_read_frames) - while (process_frame(w, ifile, frame, &pkt) > 0); + while (process_frame(w, ifile, frame, &pkt, &(int){1}) > 0); } end: From 0c20f9fcab41fe7468a898919d2e3cf7bb6b432a Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 3 Apr 2017 12:13:30 +0200 Subject: [PATCH 1463/3374] doc/muxers: fix default value for image2 option start_number. --- doc/muxers.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index 166c929369261..844bbce990af0 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -794,7 +794,7 @@ ffmpeg -f v4l2 -r 1 -i /dev/video0 -f image2 -strftime 1 "%Y-%m-%d_%H-%M-%S.jpg" @table @option @item start_number -Start the sequence from the specified number. Default value is 0. +Start the sequence from the specified number. Default value is 1. @item update If set to 1, the filename will always be interpreted as just a From 9ac1e884365314765f75517e91563be0351f6bd1 Mon Sep 17 00:00:00 2001 From: Hendrik Leppkes Date: Tue, 4 Apr 2017 09:33:23 +0200 Subject: [PATCH 1464/3374] stdatomic/win32: only include the lean windows headers to avoid conflicts --- compat/atomics/win32/stdatomic.h | 1 + 1 file changed, 1 insertion(+) diff --git a/compat/atomics/win32/stdatomic.h b/compat/atomics/win32/stdatomic.h index fa7ef51ea5488..092f453978757 100644 --- a/compat/atomics/win32/stdatomic.h +++ b/compat/atomics/win32/stdatomic.h @@ -19,6 +19,7 @@ #ifndef COMPAT_ATOMICS_WIN32_STDATOMIC_H #define COMPAT_ATOMICS_WIN32_STDATOMIC_H +#define WIN32_LEAN_AND_MEAN #include #include #include From 6ffaf90b32e42b6114cf558ed92bbd4fa93c6f49 Mon Sep 17 00:00:00 2001 From: Matthieu Bouron Date: Tue, 4 Apr 2017 09:07:54 +0200 Subject: [PATCH 1465/3374] lavc/mediacodecdec: switch to AV_CODEC_CAP_DELAY --- libavcodec/mediacodecdec.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c index 79a51ec68406b..4cbec09acd790 100644 --- a/libavcodec/mediacodecdec.c +++ b/libavcodec/mediacodecdec.c @@ -552,7 +552,7 @@ AVCodec ff_h264_mediacodec_decoder = { .decode = mediacodec_decode_frame, .flush = mediacodec_decode_flush, .close = mediacodec_decode_close, - .capabilities = CODEC_CAP_DELAY, + .capabilities = AV_CODEC_CAP_DELAY, .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS, }; #endif @@ -568,7 +568,7 @@ AVCodec ff_hevc_mediacodec_decoder = { .decode = mediacodec_decode_frame, .flush = mediacodec_decode_flush, .close = mediacodec_decode_close, - .capabilities = CODEC_CAP_DELAY, + .capabilities = AV_CODEC_CAP_DELAY, .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS, }; #endif @@ -584,7 +584,7 @@ AVCodec ff_mpeg4_mediacodec_decoder = { .decode = mediacodec_decode_frame, .flush = mediacodec_decode_flush, .close = mediacodec_decode_close, - .capabilities = CODEC_CAP_DELAY, + .capabilities = AV_CODEC_CAP_DELAY, .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS, }; #endif @@ -600,7 +600,7 @@ AVCodec ff_vp8_mediacodec_decoder = { .decode = mediacodec_decode_frame, .flush = mediacodec_decode_flush, .close = mediacodec_decode_close, - .capabilities = CODEC_CAP_DELAY, + .capabilities = AV_CODEC_CAP_DELAY, .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS, }; #endif @@ -616,7 +616,7 @@ AVCodec ff_vp9_mediacodec_decoder = { .decode = mediacodec_decode_frame, .flush = mediacodec_decode_flush, .close = mediacodec_decode_close, - .capabilities = CODEC_CAP_DELAY, + .capabilities = AV_CODEC_CAP_DELAY, .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS, }; #endif From 3fce174d4f08f76a82ad6d4a481463cfb8611dfe Mon Sep 17 00:00:00 2001 From: Matthieu Bouron Date: Tue, 4 Apr 2017 09:12:42 +0200 Subject: [PATCH 1466/3374] lavc/mediacodecdec: set AV_CODEC_CAP_AVOID_PROBING capability --- libavcodec/mediacodecdec.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c index 4cbec09acd790..857e7a5fedc92 100644 --- a/libavcodec/mediacodecdec.c +++ b/libavcodec/mediacodecdec.c @@ -552,7 +552,7 @@ AVCodec ff_h264_mediacodec_decoder = { .decode = mediacodec_decode_frame, .flush = mediacodec_decode_flush, .close = mediacodec_decode_close, - .capabilities = AV_CODEC_CAP_DELAY, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING, .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS, }; #endif @@ -568,7 +568,7 @@ AVCodec ff_hevc_mediacodec_decoder = { .decode = mediacodec_decode_frame, .flush = mediacodec_decode_flush, .close = mediacodec_decode_close, - .capabilities = AV_CODEC_CAP_DELAY, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING, .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS, }; #endif @@ -584,7 +584,7 @@ AVCodec ff_mpeg4_mediacodec_decoder = { .decode = mediacodec_decode_frame, .flush = mediacodec_decode_flush, .close = mediacodec_decode_close, - .capabilities = AV_CODEC_CAP_DELAY, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING, .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS, }; #endif @@ -600,7 +600,7 @@ AVCodec ff_vp8_mediacodec_decoder = { .decode = mediacodec_decode_frame, .flush = mediacodec_decode_flush, .close = mediacodec_decode_close, - .capabilities = AV_CODEC_CAP_DELAY, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING, .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS, }; #endif @@ -616,7 +616,7 @@ AVCodec ff_vp9_mediacodec_decoder = { .decode = mediacodec_decode_frame, .flush = mediacodec_decode_flush, .close = mediacodec_decode_close, - .capabilities = AV_CODEC_CAP_DELAY, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING, .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS, }; #endif From 8c5c6871ba677fee59808fa9231e7f39a1cd75f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Tue, 4 Apr 2017 09:58:29 +0200 Subject: [PATCH 1467/3374] lavc: add AV_ prefix to CODEC_CAP_DELAY in doxy --- libavcodec/avcodec.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 377aa5309424f..4b7c3f1e33924 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -4902,13 +4902,13 @@ int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, * and reusing a get_buffer written for video codecs would probably perform badly * due to a potentially very different allocation pattern. * - * Some decoders (those marked with CODEC_CAP_DELAY) have a delay between input + * Some decoders (those marked with AV_CODEC_CAP_DELAY) have a delay between input * and output. This means that for some packets they will not immediately * produce decoded output and need to be flushed at the end of decoding to get * all the decoded data. Flushing is done by calling this function with packets * with avpkt->data set to NULL and avpkt->size set to 0 until it stops * returning subtitles. It is safe to flush even those decoders that are not - * marked with CODEC_CAP_DELAY, then no subtitles will be returned. + * marked with AV_CODEC_CAP_DELAY, then no subtitles will be returned. * * @note The AVCodecContext MUST have been opened with @ref avcodec_open2() * before packets may be fed to the decoder. From 34ec327f693ac1ad17c522e89ebff2b8c57d9b34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Tue, 4 Apr 2017 11:17:35 +0200 Subject: [PATCH 1468/3374] examples/decode_audio: reduce the scope of 2 variables --- doc/examples/decode_audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/examples/decode_audio.c b/doc/examples/decode_audio.c index add0e313ae630..9cad3730477d7 100644 --- a/doc/examples/decode_audio.c +++ b/doc/examples/decode_audio.c @@ -97,7 +97,6 @@ int main(int argc, char **argv) avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f); while (avpkt.size > 0) { - int i, ch; int got_frame = 0; if (!decoded_frame) { @@ -113,6 +112,7 @@ int main(int argc, char **argv) exit(1); } if (got_frame) { + int i, ch; /* if a frame has been decoded, output it */ int data_size = av_get_bytes_per_sample(c->sample_fmt); if (data_size < 0) { From 82116bd8a45c9c5ad8874233ebc2f5583170856f Mon Sep 17 00:00:00 2001 From: Matthieu Bouron Date: Mon, 3 Apr 2017 15:25:09 +0200 Subject: [PATCH 1469/3374] doc/examples/extract_mvs: switch to new decoding API --- doc/examples/extract_mvs.c | 72 ++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 37 deletions(-) diff --git a/doc/examples/extract_mvs.c b/doc/examples/extract_mvs.c index 8b22b40c116aa..d6730db3a2b46 100644 --- a/doc/examples/extract_mvs.c +++ b/doc/examples/extract_mvs.c @@ -34,39 +34,46 @@ static AVFrame *frame = NULL; static AVPacket pkt; static int video_frame_count = 0; -static int decode_packet(int *got_frame, int cached) +static int decode_packet(void) { - int decoded = pkt.size; - - *got_frame = 0; - if (pkt.stream_index == video_stream_idx) { - int ret = avcodec_decode_video2(video_dec_ctx, frame, got_frame, &pkt); + int ret = avcodec_send_packet(video_dec_ctx, &pkt); if (ret < 0) { - fprintf(stderr, "Error decoding video frame (%s)\n", av_err2str(ret)); + fprintf(stderr, "Error while sending a packet to the decoder: %s\n", av_err2str(ret)); return ret; } - if (*got_frame) { - int i; - AVFrameSideData *sd; - - video_frame_count++; - sd = av_frame_get_side_data(frame, AV_FRAME_DATA_MOTION_VECTORS); - if (sd) { - const AVMotionVector *mvs = (const AVMotionVector *)sd->data; - for (i = 0; i < sd->size / sizeof(*mvs); i++) { - const AVMotionVector *mv = &mvs[i]; - printf("%d,%2d,%2d,%2d,%4d,%4d,%4d,%4d,0x%"PRIx64"\n", - video_frame_count, mv->source, - mv->w, mv->h, mv->src_x, mv->src_y, - mv->dst_x, mv->dst_y, mv->flags); + while (ret >= 0) { + ret = avcodec_receive_frame(video_dec_ctx, frame); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { + break; + } else if (ret < 0) { + fprintf(stderr, "Error while receiving a frame from the decoder: %s\n", av_err2str(ret)); + return ret; + } + + if (ret >= 0) { + int i; + AVFrameSideData *sd; + + video_frame_count++; + sd = av_frame_get_side_data(frame, AV_FRAME_DATA_MOTION_VECTORS); + if (sd) { + const AVMotionVector *mvs = (const AVMotionVector *)sd->data; + for (i = 0; i < sd->size / sizeof(*mvs); i++) { + const AVMotionVector *mv = &mvs[i]; + printf("%d,%2d,%2d,%2d,%4d,%4d,%4d,%4d,0x%"PRIx64"\n", + video_frame_count, mv->source, + mv->w, mv->h, mv->src_x, mv->src_y, + mv->dst_x, mv->dst_y, mv->flags); + } } + av_frame_unref(frame); } } } - return decoded; + return 0; } static int open_codec_context(AVFormatContext *fmt_ctx, enum AVMediaType type) @@ -116,7 +123,7 @@ static int open_codec_context(AVFormatContext *fmt_ctx, enum AVMediaType type) int main(int argc, char **argv) { - int ret = 0, got_frame; + int ret = 0; if (argc != 2) { fprintf(stderr, "Usage: %s diff --git a/ffprobe.c b/ffprobe.c index f6d9be0df9280..3d9f795d2eda4 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -2105,6 +2105,31 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream, print_int("interlaced_frame", frame->interlaced_frame); print_int("top_field_first", frame->top_field_first); print_int("repeat_pict", frame->repeat_pict); + + if (frame->color_range != AVCOL_RANGE_UNSPECIFIED) + print_str("color_range", av_color_range_name(frame->color_range)); + else + print_str_opt("color_range", av_color_range_name(frame->color_range)); + + if (frame->colorspace != AVCOL_SPC_UNSPECIFIED) + print_str("color_space", av_color_space_name(frame->colorspace)); + else + print_str_opt("color_space", av_color_space_name(frame->colorspace)); + + if (frame->color_primaries != AVCOL_PRI_UNSPECIFIED) + print_str("color_primaries", av_color_primaries_name(frame->color_primaries)); + else + print_str_opt("color_primaries", av_color_primaries_name(frame->color_primaries)); + + if (frame->color_trc != AVCOL_TRC_UNSPECIFIED) + print_str("color_transfer", av_color_transfer_name(frame->color_trc)); + else + print_str_opt("color_transfer", av_color_transfer_name(frame->color_trc)); + + if (frame->chroma_location != AVCHROMA_LOC_UNSPECIFIED) + print_str("chroma_location", av_chroma_location_name(frame->chroma_location)); + else + print_str_opt("chroma_location", av_chroma_location_name(frame->chroma_location)); break; case AVMEDIA_TYPE_AUDIO: diff --git a/tests/ref/fate/exif-image-embedded b/tests/ref/fate/exif-image-embedded index 22a74e1f3fbb5..306ae0854b1a8 100644 --- a/tests/ref/fate/exif-image-embedded +++ b/tests/ref/fate/exif-image-embedded @@ -22,6 +22,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=pc +color_space=bt470bg +color_primaries=unknown +color_transfer=unknown +chroma_location=center TAG:UserComment=AppleMark [/FRAME] diff --git a/tests/ref/fate/exif-image-jpg b/tests/ref/fate/exif-image-jpg index adbd752ffaed0..b266501191bed 100644 --- a/tests/ref/fate/exif-image-jpg +++ b/tests/ref/fate/exif-image-jpg @@ -22,6 +22,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=pc +color_space=bt470bg +color_primaries=unknown +color_transfer=unknown +chroma_location=center TAG:ImageDescription= TAG:Make=Canon TAG:Model=Canon PowerShot SX200 IS diff --git a/tests/ref/fate/exif-image-tiff b/tests/ref/fate/exif-image-tiff index 85067983483d6..51580601e196f 100644 --- a/tests/ref/fate/exif-image-tiff +++ b/tests/ref/fate/exif-image-tiff @@ -22,6 +22,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=unknown +color_space=unknown +color_primaries=unknown +color_transfer=unknown +chroma_location=unspecified TAG:document_name=image_small.tiff TAG:page_number= 0 / 1 TAG:software=ImageMagick 6.5.8-0 2010-02-09 Q16 http://www.imagemagick.org diff --git a/tests/ref/fate/exif-image-webp b/tests/ref/fate/exif-image-webp index b8891cd1ea2fe..d520ecd0dbaab 100644 --- a/tests/ref/fate/exif-image-webp +++ b/tests/ref/fate/exif-image-webp @@ -22,6 +22,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=tv +color_space=bt470bg +color_primaries=unknown +color_transfer=unknown +chroma_location=unspecified TAG:ImageDescription= TAG:Make=Canon TAG:Model=Canon PowerShot SX200 IS diff --git a/tests/ref/fate/ffprobe_compact b/tests/ref/fate/ffprobe_compact index 1948697e19370..910837d290ae3 100644 --- a/tests/ref/fate/ffprobe_compact +++ b/tests/ref/fate/ffprobe_compact @@ -1,31 +1,31 @@ packet|codec_type=audio|stream_index=0|pts=0|pts_time=0.000000|dts=0|dts_time=0.000000|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=2048|pos=647|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=0|pkt_pts_time=0.000000|pkt_dts=0|pkt_dts_time=0.000000|best_effort_timestamp=0|best_effort_timestamp_time=0.000000|pkt_duration=1024|pkt_duration_time=0.023220|pkt_pos=647|pkt_size=2048|sample_fmt=s16|nb_samples=1024|channels=1|channel_layout=unknown packet|codec_type=video|stream_index=1|pts=0|pts_time=0.000000|dts=0|dts_time=0.000000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=230400|pos=2722|flags=K_ -frame|media_type=video|stream_index=1|key_frame=1|pkt_pts=0|pkt_pts_time=0.000000|pkt_dts=0|pkt_dts_time=0.000000|best_effort_timestamp=0|best_effort_timestamp_time=0.000000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=2722|pkt_size=230400|width=320|height=240|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=1|key_frame=1|pkt_pts=0|pkt_pts_time=0.000000|pkt_dts=0|pkt_dts_time=0.000000|best_effort_timestamp=0|best_effort_timestamp_time=0.000000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=2722|pkt_size=230400|width=320|height=240|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=unknown|color_space=unknown|color_primaries=unknown|color_transfer=unknown|chroma_location=unspecified packet|codec_type=video|stream_index=2|pts=0|pts_time=0.000000|dts=0|dts_time=0.000000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=30000|pos=233143|flags=K_ -frame|media_type=video|stream_index=2|key_frame=1|pkt_pts=0|pkt_pts_time=0.000000|pkt_dts=0|pkt_dts_time=0.000000|best_effort_timestamp=0|best_effort_timestamp_time=0.000000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=233143|pkt_size=30000|width=100|height=100|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=2|key_frame=1|pkt_pts=0|pkt_pts_time=0.000000|pkt_dts=0|pkt_dts_time=0.000000|best_effort_timestamp=0|best_effort_timestamp_time=0.000000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=233143|pkt_size=30000|width=100|height=100|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=unknown|color_space=unknown|color_primaries=unknown|color_transfer=unknown|chroma_location=unspecified packet|codec_type=audio|stream_index=0|pts=1024|pts_time=0.023220|dts=1024|dts_time=0.023220|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=2048|pos=263148|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=1024|pkt_pts_time=0.023220|pkt_dts=1024|pkt_dts_time=0.023220|best_effort_timestamp=1024|best_effort_timestamp_time=0.023220|pkt_duration=1024|pkt_duration_time=0.023220|pkt_pos=263148|pkt_size=2048|sample_fmt=s16|nb_samples=1024|channels=1|channel_layout=unknown packet|codec_type=video|stream_index=1|pts=2048|pts_time=0.040000|dts=2048|dts_time=0.040000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=230400|pos=265226|flags=K_ -frame|media_type=video|stream_index=1|key_frame=1|pkt_pts=2048|pkt_pts_time=0.040000|pkt_dts=2048|pkt_dts_time=0.040000|best_effort_timestamp=2048|best_effort_timestamp_time=0.040000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=265226|pkt_size=230400|width=320|height=240|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=1|key_frame=1|pkt_pts=2048|pkt_pts_time=0.040000|pkt_dts=2048|pkt_dts_time=0.040000|best_effort_timestamp=2048|best_effort_timestamp_time=0.040000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=265226|pkt_size=230400|width=320|height=240|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=unknown|color_space=unknown|color_primaries=unknown|color_transfer=unknown|chroma_location=unspecified packet|codec_type=video|stream_index=2|pts=2048|pts_time=0.040000|dts=2048|dts_time=0.040000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=30000|pos=495650|flags=K_ -frame|media_type=video|stream_index=2|key_frame=1|pkt_pts=2048|pkt_pts_time=0.040000|pkt_dts=2048|pkt_dts_time=0.040000|best_effort_timestamp=2048|best_effort_timestamp_time=0.040000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=495650|pkt_size=30000|width=100|height=100|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=2|key_frame=1|pkt_pts=2048|pkt_pts_time=0.040000|pkt_dts=2048|pkt_dts_time=0.040000|best_effort_timestamp=2048|best_effort_timestamp_time=0.040000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=495650|pkt_size=30000|width=100|height=100|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=unknown|color_space=unknown|color_primaries=unknown|color_transfer=unknown|chroma_location=unspecified packet|codec_type=audio|stream_index=0|pts=2048|pts_time=0.046440|dts=2048|dts_time=0.046440|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=2048|pos=525655|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=2048|pkt_pts_time=0.046440|pkt_dts=2048|pkt_dts_time=0.046440|best_effort_timestamp=2048|best_effort_timestamp_time=0.046440|pkt_duration=1024|pkt_duration_time=0.023220|pkt_pos=525655|pkt_size=2048|sample_fmt=s16|nb_samples=1024|channels=1|channel_layout=unknown packet|codec_type=audio|stream_index=0|pts=3072|pts_time=0.069660|dts=3072|dts_time=0.069660|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=2048|pos=527726|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=3072|pkt_pts_time=0.069660|pkt_dts=3072|pkt_dts_time=0.069660|best_effort_timestamp=3072|best_effort_timestamp_time=0.069660|pkt_duration=1024|pkt_duration_time=0.023220|pkt_pos=527726|pkt_size=2048|sample_fmt=s16|nb_samples=1024|channels=1|channel_layout=unknown packet|codec_type=video|stream_index=1|pts=4096|pts_time=0.080000|dts=4096|dts_time=0.080000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=230400|pos=529804|flags=K_ -frame|media_type=video|stream_index=1|key_frame=1|pkt_pts=4096|pkt_pts_time=0.080000|pkt_dts=4096|pkt_dts_time=0.080000|best_effort_timestamp=4096|best_effort_timestamp_time=0.080000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=529804|pkt_size=230400|width=320|height=240|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=1|key_frame=1|pkt_pts=4096|pkt_pts_time=0.080000|pkt_dts=4096|pkt_dts_time=0.080000|best_effort_timestamp=4096|best_effort_timestamp_time=0.080000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=529804|pkt_size=230400|width=320|height=240|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=unknown|color_space=unknown|color_primaries=unknown|color_transfer=unknown|chroma_location=unspecified packet|codec_type=video|stream_index=2|pts=4096|pts_time=0.080000|dts=4096|dts_time=0.080000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=30000|pos=760228|flags=K_ -frame|media_type=video|stream_index=2|key_frame=1|pkt_pts=4096|pkt_pts_time=0.080000|pkt_dts=4096|pkt_dts_time=0.080000|best_effort_timestamp=4096|best_effort_timestamp_time=0.080000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=760228|pkt_size=30000|width=100|height=100|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=2|key_frame=1|pkt_pts=4096|pkt_pts_time=0.080000|pkt_dts=4096|pkt_dts_time=0.080000|best_effort_timestamp=4096|best_effort_timestamp_time=0.080000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=760228|pkt_size=30000|width=100|height=100|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=unknown|color_space=unknown|color_primaries=unknown|color_transfer=unknown|chroma_location=unspecified packet|codec_type=audio|stream_index=0|pts=4096|pts_time=0.092880|dts=4096|dts_time=0.092880|duration=1024|duration_time=0.023220|convergence_duration=N/A|convergence_duration_time=N/A|size=2048|pos=790233|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=4096|pkt_pts_time=0.092880|pkt_dts=4096|pkt_dts_time=0.092880|best_effort_timestamp=4096|best_effort_timestamp_time=0.092880|pkt_duration=1024|pkt_duration_time=0.023220|pkt_pos=790233|pkt_size=2048|sample_fmt=s16|nb_samples=1024|channels=1|channel_layout=unknown packet|codec_type=audio|stream_index=0|pts=5120|pts_time=0.116100|dts=5120|dts_time=0.116100|duration=393|duration_time=0.008912|convergence_duration=N/A|convergence_duration_time=N/A|size=786|pos=792304|flags=K_ frame|media_type=audio|stream_index=0|key_frame=1|pkt_pts=5120|pkt_pts_time=0.116100|pkt_dts=5120|pkt_dts_time=0.116100|best_effort_timestamp=5120|best_effort_timestamp_time=0.116100|pkt_duration=393|pkt_duration_time=0.008912|pkt_pos=792304|pkt_size=786|sample_fmt=s16|nb_samples=393|channels=1|channel_layout=unknown packet|codec_type=video|stream_index=1|pts=6144|pts_time=0.120000|dts=6144|dts_time=0.120000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=230400|pos=793120|flags=K_ -frame|media_type=video|stream_index=1|key_frame=1|pkt_pts=6144|pkt_pts_time=0.120000|pkt_dts=6144|pkt_dts_time=0.120000|best_effort_timestamp=6144|best_effort_timestamp_time=0.120000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=793120|pkt_size=230400|width=320|height=240|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=1|key_frame=1|pkt_pts=6144|pkt_pts_time=0.120000|pkt_dts=6144|pkt_dts_time=0.120000|best_effort_timestamp=6144|best_effort_timestamp_time=0.120000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=793120|pkt_size=230400|width=320|height=240|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=unknown|color_space=unknown|color_primaries=unknown|color_transfer=unknown|chroma_location=unspecified packet|codec_type=video|stream_index=2|pts=6144|pts_time=0.120000|dts=6144|dts_time=0.120000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=30000|pos=1023544|flags=K_ -frame|media_type=video|stream_index=2|key_frame=1|pkt_pts=6144|pkt_pts_time=0.120000|pkt_dts=6144|pkt_dts_time=0.120000|best_effort_timestamp=6144|best_effort_timestamp_time=0.120000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=1023544|pkt_size=30000|width=100|height=100|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=2|key_frame=1|pkt_pts=6144|pkt_pts_time=0.120000|pkt_dts=6144|pkt_dts_time=0.120000|best_effort_timestamp=6144|best_effort_timestamp_time=0.120000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=1023544|pkt_size=30000|width=100|height=100|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=unknown|color_space=unknown|color_primaries=unknown|color_transfer=unknown|chroma_location=unspecified stream|index=0|codec_name=pcm_s16le|profile=unknown|codec_type=audio|codec_time_base=1/44100|codec_tag_string=PSD[16]|codec_tag=0x10445350|sample_fmt=s16|sample_rate=44100|channels=1|channel_layout=unknown|bits_per_sample=16|id=N/A|r_frame_rate=0/0|avg_frame_rate=0/0|time_base=1/44100|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=705600|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=6|nb_read_packets=6|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|tag:E=mc²|tag:encoder=Lavc pcm_s16le stream|index=1|codec_name=rawvideo|profile=unknown|codec_type=video|codec_time_base=1/25|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=320|height=240|coded_width=320|coded_height=240|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=4:3|pix_fmt=rgb24|level=-99|color_range=N/A|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=unspecified|field_order=unknown|timecode=N/A|refs=1|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|tag:title=foobar|tag:duration_ts=field-and-tags-conflict-attempt|tag:encoder=Lavc rawvideo stream|index=2|codec_name=rawvideo|profile=unknown|codec_type=video|codec_time_base=1/25|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=100|height=100|coded_width=100|coded_height=100|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=1:1|pix_fmt=rgb24|level=-99|color_range=N/A|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=unspecified|field_order=unknown|timecode=N/A|refs=1|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|tag:encoder=Lavc rawvideo diff --git a/tests/ref/fate/ffprobe_csv b/tests/ref/fate/ffprobe_csv index 88c79582f0388..90e033f547890 100644 --- a/tests/ref/fate/ffprobe_csv +++ b/tests/ref/fate/ffprobe_csv @@ -1,31 +1,31 @@ packet,audio,0,0,0.000000,0,0.000000,1024,0.023220,N/A,N/A,2048,647,K_ frame,audio,0,1,0,0.000000,0,0.000000,0,0.000000,1024,0.023220,647,2048,s16,1024,1,unknown packet,video,1,0,0.000000,0,0.000000,2048,0.040000,N/A,N/A,230400,2722,K_ -frame,video,1,1,0,0.000000,0,0.000000,0,0.000000,2048,0.040000,2722,230400,320,240,rgb24,1:1,I,0,0,0,0,0 +frame,video,1,1,0,0.000000,0,0.000000,0,0.000000,2048,0.040000,2722,230400,320,240,rgb24,1:1,I,0,0,0,0,0,unknown,unknown,unknown,unknown,unspecified packet,video,2,0,0.000000,0,0.000000,2048,0.040000,N/A,N/A,30000,233143,K_ -frame,video,2,1,0,0.000000,0,0.000000,0,0.000000,2048,0.040000,233143,30000,100,100,rgb24,1:1,I,0,0,0,0,0 +frame,video,2,1,0,0.000000,0,0.000000,0,0.000000,2048,0.040000,233143,30000,100,100,rgb24,1:1,I,0,0,0,0,0,unknown,unknown,unknown,unknown,unspecified packet,audio,0,1024,0.023220,1024,0.023220,1024,0.023220,N/A,N/A,2048,263148,K_ frame,audio,0,1,1024,0.023220,1024,0.023220,1024,0.023220,1024,0.023220,263148,2048,s16,1024,1,unknown packet,video,1,2048,0.040000,2048,0.040000,2048,0.040000,N/A,N/A,230400,265226,K_ -frame,video,1,1,2048,0.040000,2048,0.040000,2048,0.040000,2048,0.040000,265226,230400,320,240,rgb24,1:1,I,0,0,0,0,0 +frame,video,1,1,2048,0.040000,2048,0.040000,2048,0.040000,2048,0.040000,265226,230400,320,240,rgb24,1:1,I,0,0,0,0,0,unknown,unknown,unknown,unknown,unspecified packet,video,2,2048,0.040000,2048,0.040000,2048,0.040000,N/A,N/A,30000,495650,K_ -frame,video,2,1,2048,0.040000,2048,0.040000,2048,0.040000,2048,0.040000,495650,30000,100,100,rgb24,1:1,I,0,0,0,0,0 +frame,video,2,1,2048,0.040000,2048,0.040000,2048,0.040000,2048,0.040000,495650,30000,100,100,rgb24,1:1,I,0,0,0,0,0,unknown,unknown,unknown,unknown,unspecified packet,audio,0,2048,0.046440,2048,0.046440,1024,0.023220,N/A,N/A,2048,525655,K_ frame,audio,0,1,2048,0.046440,2048,0.046440,2048,0.046440,1024,0.023220,525655,2048,s16,1024,1,unknown packet,audio,0,3072,0.069660,3072,0.069660,1024,0.023220,N/A,N/A,2048,527726,K_ frame,audio,0,1,3072,0.069660,3072,0.069660,3072,0.069660,1024,0.023220,527726,2048,s16,1024,1,unknown packet,video,1,4096,0.080000,4096,0.080000,2048,0.040000,N/A,N/A,230400,529804,K_ -frame,video,1,1,4096,0.080000,4096,0.080000,4096,0.080000,2048,0.040000,529804,230400,320,240,rgb24,1:1,I,0,0,0,0,0 +frame,video,1,1,4096,0.080000,4096,0.080000,4096,0.080000,2048,0.040000,529804,230400,320,240,rgb24,1:1,I,0,0,0,0,0,unknown,unknown,unknown,unknown,unspecified packet,video,2,4096,0.080000,4096,0.080000,2048,0.040000,N/A,N/A,30000,760228,K_ -frame,video,2,1,4096,0.080000,4096,0.080000,4096,0.080000,2048,0.040000,760228,30000,100,100,rgb24,1:1,I,0,0,0,0,0 +frame,video,2,1,4096,0.080000,4096,0.080000,4096,0.080000,2048,0.040000,760228,30000,100,100,rgb24,1:1,I,0,0,0,0,0,unknown,unknown,unknown,unknown,unspecified packet,audio,0,4096,0.092880,4096,0.092880,1024,0.023220,N/A,N/A,2048,790233,K_ frame,audio,0,1,4096,0.092880,4096,0.092880,4096,0.092880,1024,0.023220,790233,2048,s16,1024,1,unknown packet,audio,0,5120,0.116100,5120,0.116100,393,0.008912,N/A,N/A,786,792304,K_ frame,audio,0,1,5120,0.116100,5120,0.116100,5120,0.116100,393,0.008912,792304,786,s16,393,1,unknown packet,video,1,6144,0.120000,6144,0.120000,2048,0.040000,N/A,N/A,230400,793120,K_ -frame,video,1,1,6144,0.120000,6144,0.120000,6144,0.120000,2048,0.040000,793120,230400,320,240,rgb24,1:1,I,0,0,0,0,0 +frame,video,1,1,6144,0.120000,6144,0.120000,6144,0.120000,2048,0.040000,793120,230400,320,240,rgb24,1:1,I,0,0,0,0,0,unknown,unknown,unknown,unknown,unspecified packet,video,2,6144,0.120000,6144,0.120000,2048,0.040000,N/A,N/A,30000,1023544,K_ -frame,video,2,1,6144,0.120000,6144,0.120000,6144,0.120000,2048,0.040000,1023544,30000,100,100,rgb24,1:1,I,0,0,0,0,0 +frame,video,2,1,6144,0.120000,6144,0.120000,6144,0.120000,2048,0.040000,1023544,30000,100,100,rgb24,1:1,I,0,0,0,0,0,unknown,unknown,unknown,unknown,unspecified stream,0,pcm_s16le,unknown,audio,1/44100,PSD[16],0x10445350,s16,44100,1,unknown,16,N/A,0/0,0/0,1/44100,0,0.000000,N/A,N/A,705600,N/A,N/A,N/A,6,6,0,0,0,0,0,0,0,0,0,0,0,0,mc²,Lavc pcm_s16le stream,1,rawvideo,unknown,video,1/25,RGB[24],0x18424752,320,240,320,240,0,1:1,4:3,rgb24,-99,N/A,unknown,unknown,unknown,unspecified,unknown,N/A,1,N/A,25/1,25/1,1/51200,0,0.000000,N/A,N/A,N/A,N/A,N/A,N/A,4,4,0,0,0,0,0,0,0,0,0,0,0,0,foobar,field-and-tags-conflict-attempt,Lavc rawvideo stream,2,rawvideo,unknown,video,1/25,RGB[24],0x18424752,100,100,100,100,0,1:1,1:1,rgb24,-99,N/A,unknown,unknown,unknown,unspecified,unknown,N/A,1,N/A,25/1,25/1,1/51200,0,0.000000,N/A,N/A,N/A,N/A,N/A,N/A,4,4,0,0,0,0,0,0,0,0,0,0,0,0,Lavc rawvideo diff --git a/tests/ref/fate/ffprobe_default b/tests/ref/fate/ffprobe_default index 067e6049de80c..bb3cf8a8d2b41 100644 --- a/tests/ref/fate/ffprobe_default +++ b/tests/ref/fate/ffprobe_default @@ -71,6 +71,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=unknown +color_space=unknown +color_primaries=unknown +color_transfer=unknown +chroma_location=unspecified [/FRAME] [PACKET] codec_type=video @@ -111,6 +116,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=unknown +color_space=unknown +color_primaries=unknown +color_transfer=unknown +chroma_location=unspecified [/FRAME] [PACKET] codec_type=audio @@ -185,6 +195,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=unknown +color_space=unknown +color_primaries=unknown +color_transfer=unknown +chroma_location=unspecified [/FRAME] [PACKET] codec_type=video @@ -225,6 +240,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=unknown +color_space=unknown +color_primaries=unknown +color_transfer=unknown +chroma_location=unspecified [/FRAME] [PACKET] codec_type=audio @@ -333,6 +353,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=unknown +color_space=unknown +color_primaries=unknown +color_transfer=unknown +chroma_location=unspecified [/FRAME] [PACKET] codec_type=video @@ -373,6 +398,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=unknown +color_space=unknown +color_primaries=unknown +color_transfer=unknown +chroma_location=unspecified [/FRAME] [PACKET] codec_type=audio @@ -481,6 +511,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=unknown +color_space=unknown +color_primaries=unknown +color_transfer=unknown +chroma_location=unspecified [/FRAME] [PACKET] codec_type=video @@ -521,6 +556,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=unknown +color_space=unknown +color_primaries=unknown +color_transfer=unknown +chroma_location=unspecified [/FRAME] [STREAM] index=0 diff --git a/tests/ref/fate/ffprobe_flat b/tests/ref/fate/ffprobe_flat index 056bc29761249..ac657db1ee790 100644 --- a/tests/ref/fate/ffprobe_flat +++ b/tests/ref/fate/ffprobe_flat @@ -64,6 +64,11 @@ packets_and_frames.frame.1.display_picture_number=0 packets_and_frames.frame.1.interlaced_frame=0 packets_and_frames.frame.1.top_field_first=0 packets_and_frames.frame.1.repeat_pict=0 +packets_and_frames.frame.1.color_range="unknown" +packets_and_frames.frame.1.color_space="unknown" +packets_and_frames.frame.1.color_primaries="unknown" +packets_and_frames.frame.1.color_transfer="unknown" +packets_and_frames.frame.1.chroma_location="unspecified" packets_and_frames.packet.2.codec_type="video" packets_and_frames.packet.2.stream_index=2 packets_and_frames.packet.2.pts=0 @@ -100,6 +105,11 @@ packets_and_frames.frame.2.display_picture_number=0 packets_and_frames.frame.2.interlaced_frame=0 packets_and_frames.frame.2.top_field_first=0 packets_and_frames.frame.2.repeat_pict=0 +packets_and_frames.frame.2.color_range="unknown" +packets_and_frames.frame.2.color_space="unknown" +packets_and_frames.frame.2.color_primaries="unknown" +packets_and_frames.frame.2.color_transfer="unknown" +packets_and_frames.frame.2.chroma_location="unspecified" packets_and_frames.packet.3.codec_type="audio" packets_and_frames.packet.3.stream_index=0 packets_and_frames.packet.3.pts=1024 @@ -166,6 +176,11 @@ packets_and_frames.frame.4.display_picture_number=0 packets_and_frames.frame.4.interlaced_frame=0 packets_and_frames.frame.4.top_field_first=0 packets_and_frames.frame.4.repeat_pict=0 +packets_and_frames.frame.4.color_range="unknown" +packets_and_frames.frame.4.color_space="unknown" +packets_and_frames.frame.4.color_primaries="unknown" +packets_and_frames.frame.4.color_transfer="unknown" +packets_and_frames.frame.4.chroma_location="unspecified" packets_and_frames.packet.5.codec_type="video" packets_and_frames.packet.5.stream_index=2 packets_and_frames.packet.5.pts=2048 @@ -202,6 +217,11 @@ packets_and_frames.frame.5.display_picture_number=0 packets_and_frames.frame.5.interlaced_frame=0 packets_and_frames.frame.5.top_field_first=0 packets_and_frames.frame.5.repeat_pict=0 +packets_and_frames.frame.5.color_range="unknown" +packets_and_frames.frame.5.color_space="unknown" +packets_and_frames.frame.5.color_primaries="unknown" +packets_and_frames.frame.5.color_transfer="unknown" +packets_and_frames.frame.5.chroma_location="unspecified" packets_and_frames.packet.6.codec_type="audio" packets_and_frames.packet.6.stream_index=0 packets_and_frames.packet.6.pts=2048 @@ -298,6 +318,11 @@ packets_and_frames.frame.8.display_picture_number=0 packets_and_frames.frame.8.interlaced_frame=0 packets_and_frames.frame.8.top_field_first=0 packets_and_frames.frame.8.repeat_pict=0 +packets_and_frames.frame.8.color_range="unknown" +packets_and_frames.frame.8.color_space="unknown" +packets_and_frames.frame.8.color_primaries="unknown" +packets_and_frames.frame.8.color_transfer="unknown" +packets_and_frames.frame.8.chroma_location="unspecified" packets_and_frames.packet.9.codec_type="video" packets_and_frames.packet.9.stream_index=2 packets_and_frames.packet.9.pts=4096 @@ -334,6 +359,11 @@ packets_and_frames.frame.9.display_picture_number=0 packets_and_frames.frame.9.interlaced_frame=0 packets_and_frames.frame.9.top_field_first=0 packets_and_frames.frame.9.repeat_pict=0 +packets_and_frames.frame.9.color_range="unknown" +packets_and_frames.frame.9.color_space="unknown" +packets_and_frames.frame.9.color_primaries="unknown" +packets_and_frames.frame.9.color_transfer="unknown" +packets_and_frames.frame.9.chroma_location="unspecified" packets_and_frames.packet.10.codec_type="audio" packets_and_frames.packet.10.stream_index=0 packets_and_frames.packet.10.pts=4096 @@ -430,6 +460,11 @@ packets_and_frames.frame.12.display_picture_number=0 packets_and_frames.frame.12.interlaced_frame=0 packets_and_frames.frame.12.top_field_first=0 packets_and_frames.frame.12.repeat_pict=0 +packets_and_frames.frame.12.color_range="unknown" +packets_and_frames.frame.12.color_space="unknown" +packets_and_frames.frame.12.color_primaries="unknown" +packets_and_frames.frame.12.color_transfer="unknown" +packets_and_frames.frame.12.chroma_location="unspecified" packets_and_frames.packet.13.codec_type="video" packets_and_frames.packet.13.stream_index=2 packets_and_frames.packet.13.pts=6144 @@ -466,6 +501,11 @@ packets_and_frames.frame.13.display_picture_number=0 packets_and_frames.frame.13.interlaced_frame=0 packets_and_frames.frame.13.top_field_first=0 packets_and_frames.frame.13.repeat_pict=0 +packets_and_frames.frame.13.color_range="unknown" +packets_and_frames.frame.13.color_space="unknown" +packets_and_frames.frame.13.color_primaries="unknown" +packets_and_frames.frame.13.color_transfer="unknown" +packets_and_frames.frame.13.chroma_location="unspecified" streams.stream.0.index=0 streams.stream.0.codec_name="pcm_s16le" streams.stream.0.profile="unknown" diff --git a/tests/ref/fate/ffprobe_ini b/tests/ref/fate/ffprobe_ini index a89b43a71d96d..37e1563c38b3b 100644 --- a/tests/ref/fate/ffprobe_ini +++ b/tests/ref/fate/ffprobe_ini @@ -73,6 +73,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=unknown +color_space=unknown +color_primaries=unknown +color_transfer=unknown +chroma_location=unspecified [packets_and_frames.packet.2] codec_type=video @@ -113,6 +118,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=unknown +color_space=unknown +color_primaries=unknown +color_transfer=unknown +chroma_location=unspecified [packets_and_frames.packet.3] codec_type=audio @@ -187,6 +197,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=unknown +color_space=unknown +color_primaries=unknown +color_transfer=unknown +chroma_location=unspecified [packets_and_frames.packet.5] codec_type=video @@ -227,6 +242,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=unknown +color_space=unknown +color_primaries=unknown +color_transfer=unknown +chroma_location=unspecified [packets_and_frames.packet.6] codec_type=audio @@ -335,6 +355,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=unknown +color_space=unknown +color_primaries=unknown +color_transfer=unknown +chroma_location=unspecified [packets_and_frames.packet.9] codec_type=video @@ -375,6 +400,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=unknown +color_space=unknown +color_primaries=unknown +color_transfer=unknown +chroma_location=unspecified [packets_and_frames.packet.10] codec_type=audio @@ -483,6 +513,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=unknown +color_space=unknown +color_primaries=unknown +color_transfer=unknown +chroma_location=unspecified [packets_and_frames.packet.13] codec_type=video @@ -523,6 +558,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=unknown +color_space=unknown +color_primaries=unknown +color_transfer=unknown +chroma_location=unspecified [streams.stream.0] index=0 diff --git a/tests/ref/fate/h264-dts_5frames b/tests/ref/fate/h264-dts_5frames index 1c4c349bff364..6049b9ff3237d 100644 --- a/tests/ref/fate/h264-dts_5frames +++ b/tests/ref/fate/h264-dts_5frames @@ -22,6 +22,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=unknown +color_space=unknown +color_primaries=unknown +color_transfer=unknown +chroma_location=left [/FRAME] [FRAME] media_type=video @@ -47,6 +52,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=unknown +color_space=unknown +color_primaries=unknown +color_transfer=unknown +chroma_location=left [/FRAME] [FRAME] media_type=video @@ -72,6 +82,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=unknown +color_space=unknown +color_primaries=unknown +color_transfer=unknown +chroma_location=left [/FRAME] [FRAME] media_type=video @@ -97,6 +112,11 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=unknown +color_space=unknown +color_primaries=unknown +color_transfer=unknown +chroma_location=left [/FRAME] [FRAME] media_type=video @@ -122,4 +142,9 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 +color_range=unknown +color_space=unknown +color_primaries=unknown +color_transfer=unknown +chroma_location=left [/FRAME] diff --git a/tests/ref/fate/mov-zombie b/tests/ref/fate/mov-zombie index 522417dce7176..e89abb1167682 100644 --- a/tests/ref/fate/mov-zombie +++ b/tests/ref/fate/mov-zombie @@ -1,133 +1,133 @@ packet|codec_type=video|stream_index=0|pts=0|pts_time=0.000000|dts=-3004|dts_time=-0.033378|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=4133|pos=11309|flags=K_ -frame|media_type=video|stream_index=0|key_frame=1|pkt_pts=0|pkt_pts_time=0.000000|pkt_dts=-3004|pkt_dts_time=-0.033378|best_effort_timestamp=0|best_effort_timestamp_time=0.000000|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=11309|pkt_size=4133|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=1|pkt_pts=0|pkt_pts_time=0.000000|pkt_dts=-3004|pkt_dts_time=-0.033378|best_effort_timestamp=0|best_effort_timestamp_time=0.000000|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=11309|pkt_size=4133|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=5440|pts_time=0.060444|dts=-567|dts_time=-0.006300|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1077|pos=15442|flags=__ packet|codec_type=video|stream_index=0|pts=2437|pts_time=0.027078|dts=2436|dts_time=0.027067|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=355|pos=16519|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=2437|pkt_pts_time=0.027078|pkt_dts=2436|pkt_dts_time=0.027067|best_effort_timestamp=2437|best_effort_timestamp_time=0.027078|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=16519|pkt_size=355|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=2|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=2437|pkt_pts_time=0.027078|pkt_dts=2436|pkt_dts_time=0.027067|best_effort_timestamp=2437|best_effort_timestamp_time=0.027078|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=16519|pkt_size=355|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=2|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=11446|pts_time=0.127178|dts=5439|dts_time=0.060433|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1110|pos=16874|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=5440|pkt_pts_time=0.060444|pkt_dts=5439|pkt_dts_time=0.060433|best_effort_timestamp=5440|best_effort_timestamp_time=0.060444|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=15442|pkt_size=1077|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=1|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=5440|pkt_pts_time=0.060444|pkt_dts=5439|pkt_dts_time=0.060433|best_effort_timestamp=5440|best_effort_timestamp_time=0.060444|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=15442|pkt_size=1077|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=1|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=8443|pts_time=0.093811|dts=8442|dts_time=0.093800|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=430|pos=17984|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=8443|pkt_pts_time=0.093811|pkt_dts=8442|pkt_dts_time=0.093800|best_effort_timestamp=8443|best_effort_timestamp_time=0.093811|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=17984|pkt_size=430|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=4|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=8443|pkt_pts_time=0.093811|pkt_dts=8442|pkt_dts_time=0.093800|best_effort_timestamp=8443|best_effort_timestamp_time=0.093811|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=17984|pkt_size=430|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=4|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=17452|pts_time=0.193911|dts=11445|dts_time=0.127167|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1485|pos=18414|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=11446|pkt_pts_time=0.127178|pkt_dts=11445|pkt_dts_time=0.127167|best_effort_timestamp=11446|best_effort_timestamp_time=0.127178|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=16874|pkt_size=1110|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=3|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=11446|pkt_pts_time=0.127178|pkt_dts=11445|pkt_dts_time=0.127167|best_effort_timestamp=11446|best_effort_timestamp_time=0.127178|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=16874|pkt_size=1110|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=3|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=14449|pts_time=0.160544|dts=14448|dts_time=0.160533|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1005|pos=19899|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=14449|pkt_pts_time=0.160544|pkt_dts=14448|pkt_dts_time=0.160533|best_effort_timestamp=14449|best_effort_timestamp_time=0.160544|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=19899|pkt_size=1005|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=6|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=14449|pkt_pts_time=0.160544|pkt_dts=14448|pkt_dts_time=0.160533|best_effort_timestamp=14449|best_effort_timestamp_time=0.160544|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=19899|pkt_size=1005|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=6|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=23458|pts_time=0.260644|dts=17451|dts_time=0.193900|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1976|pos=20904|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=17452|pkt_pts_time=0.193911|pkt_dts=17451|pkt_dts_time=0.193900|best_effort_timestamp=17452|best_effort_timestamp_time=0.193911|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=18414|pkt_size=1485|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=5|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=17452|pkt_pts_time=0.193911|pkt_dts=17451|pkt_dts_time=0.193900|best_effort_timestamp=17452|best_effort_timestamp_time=0.193911|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=18414|pkt_size=1485|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=5|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=20455|pts_time=0.227278|dts=20454|dts_time=0.227267|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=904|pos=22880|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=20455|pkt_pts_time=0.227278|pkt_dts=20454|pkt_dts_time=0.227267|best_effort_timestamp=20455|best_effort_timestamp_time=0.227278|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=22880|pkt_size=904|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=8|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=20455|pkt_pts_time=0.227278|pkt_dts=20454|pkt_dts_time=0.227267|best_effort_timestamp=20455|best_effort_timestamp_time=0.227278|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=22880|pkt_size=904|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=8|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=29464|pts_time=0.327378|dts=23457|dts_time=0.260633|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1254|pos=23784|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=23458|pkt_pts_time=0.260644|pkt_dts=23457|pkt_dts_time=0.260633|best_effort_timestamp=23458|best_effort_timestamp_time=0.260644|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=20904|pkt_size=1976|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=7|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=23458|pkt_pts_time=0.260644|pkt_dts=23457|pkt_dts_time=0.260633|best_effort_timestamp=23458|best_effort_timestamp_time=0.260644|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=20904|pkt_size=1976|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=7|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=26461|pts_time=0.294011|dts=26460|dts_time=0.294000|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=700|pos=25038|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=26461|pkt_pts_time=0.294011|pkt_dts=26460|pkt_dts_time=0.294000|best_effort_timestamp=26461|best_effort_timestamp_time=0.294011|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=25038|pkt_size=700|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=10|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=26461|pkt_pts_time=0.294011|pkt_dts=26460|pkt_dts_time=0.294000|best_effort_timestamp=26461|best_effort_timestamp_time=0.294011|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=25038|pkt_size=700|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=10|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=35470|pts_time=0.394111|dts=29463|dts_time=0.327367|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1311|pos=25738|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=29464|pkt_pts_time=0.327378|pkt_dts=29463|pkt_dts_time=0.327367|best_effort_timestamp=29464|best_effort_timestamp_time=0.327378|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=23784|pkt_size=1254|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=9|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=29464|pkt_pts_time=0.327378|pkt_dts=29463|pkt_dts_time=0.327367|best_effort_timestamp=29464|best_effort_timestamp_time=0.327378|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=23784|pkt_size=1254|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=9|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=32467|pts_time=0.360744|dts=32466|dts_time=0.360733|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=631|pos=27049|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=32467|pkt_pts_time=0.360744|pkt_dts=32466|pkt_dts_time=0.360733|best_effort_timestamp=32467|best_effort_timestamp_time=0.360744|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=27049|pkt_size=631|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=12|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=32467|pkt_pts_time=0.360744|pkt_dts=32466|pkt_dts_time=0.360733|best_effort_timestamp=32467|best_effort_timestamp_time=0.360744|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=27049|pkt_size=631|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=12|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=41476|pts_time=0.460844|dts=35469|dts_time=0.394100|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1296|pos=27680|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=35470|pkt_pts_time=0.394111|pkt_dts=35469|pkt_dts_time=0.394100|best_effort_timestamp=35470|best_effort_timestamp_time=0.394111|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=25738|pkt_size=1311|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=11|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=35470|pkt_pts_time=0.394111|pkt_dts=35469|pkt_dts_time=0.394100|best_effort_timestamp=35470|best_effort_timestamp_time=0.394111|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=25738|pkt_size=1311|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=11|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=38473|pts_time=0.427478|dts=38472|dts_time=0.427467|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=466|pos=28976|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=38473|pkt_pts_time=0.427478|pkt_dts=38472|pkt_dts_time=0.427467|best_effort_timestamp=38473|best_effort_timestamp_time=0.427478|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=28976|pkt_size=466|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=14|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=38473|pkt_pts_time=0.427478|pkt_dts=38472|pkt_dts_time=0.427467|best_effort_timestamp=38473|best_effort_timestamp_time=0.427478|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=28976|pkt_size=466|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=14|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=47482|pts_time=0.527578|dts=41475|dts_time=0.460833|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1638|pos=29442|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=41476|pkt_pts_time=0.460844|pkt_dts=41475|pkt_dts_time=0.460833|best_effort_timestamp=41476|best_effort_timestamp_time=0.460844|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=27680|pkt_size=1296|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=13|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=41476|pkt_pts_time=0.460844|pkt_dts=41475|pkt_dts_time=0.460833|best_effort_timestamp=41476|best_effort_timestamp_time=0.460844|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=27680|pkt_size=1296|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=13|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=44479|pts_time=0.494211|dts=44478|dts_time=0.494200|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=907|pos=31080|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=44479|pkt_pts_time=0.494211|pkt_dts=44478|pkt_dts_time=0.494200|best_effort_timestamp=44479|best_effort_timestamp_time=0.494211|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=31080|pkt_size=907|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=16|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=44479|pkt_pts_time=0.494211|pkt_dts=44478|pkt_dts_time=0.494200|best_effort_timestamp=44479|best_effort_timestamp_time=0.494211|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=31080|pkt_size=907|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=16|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=53488|pts_time=0.594311|dts=47481|dts_time=0.527567|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1362|pos=31987|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=47482|pkt_pts_time=0.527578|pkt_dts=47481|pkt_dts_time=0.527567|best_effort_timestamp=47482|best_effort_timestamp_time=0.527578|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=29442|pkt_size=1638|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=15|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=47482|pkt_pts_time=0.527578|pkt_dts=47481|pkt_dts_time=0.527567|best_effort_timestamp=47482|best_effort_timestamp_time=0.527578|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=29442|pkt_size=1638|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=15|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=50485|pts_time=0.560944|dts=50484|dts_time=0.560933|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=682|pos=33349|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=50485|pkt_pts_time=0.560944|pkt_dts=50484|pkt_dts_time=0.560933|best_effort_timestamp=50485|best_effort_timestamp_time=0.560944|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=33349|pkt_size=682|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=18|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=50485|pkt_pts_time=0.560944|pkt_dts=50484|pkt_dts_time=0.560933|best_effort_timestamp=50485|best_effort_timestamp_time=0.560944|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=33349|pkt_size=682|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=18|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=59494|pts_time=0.661044|dts=53487|dts_time=0.594300|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2917|pos=34031|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=53488|pkt_pts_time=0.594311|pkt_dts=53487|pkt_dts_time=0.594300|best_effort_timestamp=53488|best_effort_timestamp_time=0.594311|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=31987|pkt_size=1362|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=17|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=53488|pkt_pts_time=0.594311|pkt_dts=53487|pkt_dts_time=0.594300|best_effort_timestamp=53488|best_effort_timestamp_time=0.594311|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=31987|pkt_size=1362|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=17|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=56491|pts_time=0.627678|dts=56490|dts_time=0.627667|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1174|pos=36948|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=56491|pkt_pts_time=0.627678|pkt_dts=56490|pkt_dts_time=0.627667|best_effort_timestamp=56491|best_effort_timestamp_time=0.627678|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=36948|pkt_size=1174|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=20|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=56491|pkt_pts_time=0.627678|pkt_dts=56490|pkt_dts_time=0.627667|best_effort_timestamp=56491|best_effort_timestamp_time=0.627678|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=36948|pkt_size=1174|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=20|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=65500|pts_time=0.727778|dts=59493|dts_time=0.661033|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1748|pos=38122|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=59494|pkt_pts_time=0.661044|pkt_dts=59493|pkt_dts_time=0.661033|best_effort_timestamp=59494|best_effort_timestamp_time=0.661044|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=34031|pkt_size=2917|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=19|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=59494|pkt_pts_time=0.661044|pkt_dts=59493|pkt_dts_time=0.661033|best_effort_timestamp=59494|best_effort_timestamp_time=0.661044|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=34031|pkt_size=2917|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=19|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=62497|pts_time=0.694411|dts=62496|dts_time=0.694400|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=926|pos=39870|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=62497|pkt_pts_time=0.694411|pkt_dts=62496|pkt_dts_time=0.694400|best_effort_timestamp=62497|best_effort_timestamp_time=0.694411|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=39870|pkt_size=926|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=22|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=62497|pkt_pts_time=0.694411|pkt_dts=62496|pkt_dts_time=0.694400|best_effort_timestamp=62497|best_effort_timestamp_time=0.694411|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=39870|pkt_size=926|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=22|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=68503|pts_time=0.761144|dts=65499|dts_time=0.727767|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=918|pos=40796|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=65500|pkt_pts_time=0.727778|pkt_dts=65499|pkt_dts_time=0.727767|best_effort_timestamp=65500|best_effort_timestamp_time=0.727778|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=38122|pkt_size=1748|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=21|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=65500|pkt_pts_time=0.727778|pkt_dts=65499|pkt_dts_time=0.727767|best_effort_timestamp=65500|best_effort_timestamp_time=0.727778|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=38122|pkt_size=1748|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=21|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=71506|pts_time=0.794511|dts=68502|dts_time=0.761133|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=3846|pos=41714|flags=K_ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=68503|pkt_pts_time=0.761144|pkt_dts=68502|pkt_dts_time=0.761133|best_effort_timestamp=68503|best_effort_timestamp_time=0.761144|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=40796|pkt_size=918|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=23|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=68503|pkt_pts_time=0.761144|pkt_dts=68502|pkt_dts_time=0.761133|best_effort_timestamp=68503|best_effort_timestamp_time=0.761144|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=40796|pkt_size=918|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=23|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=77512|pts_time=0.861244|dts=71505|dts_time=0.794500|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1932|pos=45560|flags=__ -frame|media_type=video|stream_index=0|key_frame=1|pkt_pts=71506|pkt_pts_time=0.794511|pkt_dts=71505|pkt_dts_time=0.794500|best_effort_timestamp=71506|best_effort_timestamp_time=0.794511|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=41714|pkt_size=3846|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=I|coded_picture_number=24|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=1|pkt_pts=71506|pkt_pts_time=0.794511|pkt_dts=71505|pkt_dts_time=0.794500|best_effort_timestamp=71506|best_effort_timestamp_time=0.794511|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=41714|pkt_size=3846|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=I|coded_picture_number=24|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=74509|pts_time=0.827878|dts=74508|dts_time=0.827867|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1159|pos=47492|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=74509|pkt_pts_time=0.827878|pkt_dts=74508|pkt_dts_time=0.827867|best_effort_timestamp=74509|best_effort_timestamp_time=0.827878|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=47492|pkt_size=1159|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=26|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=74509|pkt_pts_time=0.827878|pkt_dts=74508|pkt_dts_time=0.827867|best_effort_timestamp=74509|best_effort_timestamp_time=0.827878|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=47492|pkt_size=1159|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=26|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=83518|pts_time=0.927978|dts=77511|dts_time=0.861233|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1522|pos=48651|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=77512|pkt_pts_time=0.861244|pkt_dts=77511|pkt_dts_time=0.861233|best_effort_timestamp=77512|best_effort_timestamp_time=0.861244|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=45560|pkt_size=1932|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=25|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=77512|pkt_pts_time=0.861244|pkt_dts=77511|pkt_dts_time=0.861233|best_effort_timestamp=77512|best_effort_timestamp_time=0.861244|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=45560|pkt_size=1932|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=25|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=80515|pts_time=0.894611|dts=80514|dts_time=0.894600|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=719|pos=50173|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=80515|pkt_pts_time=0.894611|pkt_dts=80514|pkt_dts_time=0.894600|best_effort_timestamp=80515|best_effort_timestamp_time=0.894611|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=50173|pkt_size=719|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=28|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=80515|pkt_pts_time=0.894611|pkt_dts=80514|pkt_dts_time=0.894600|best_effort_timestamp=80515|best_effort_timestamp_time=0.894611|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=50173|pkt_size=719|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=28|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=89524|pts_time=0.994711|dts=83517|dts_time=0.927967|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1700|pos=50892|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=83518|pkt_pts_time=0.927978|pkt_dts=83517|pkt_dts_time=0.927967|best_effort_timestamp=83518|best_effort_timestamp_time=0.927978|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=48651|pkt_size=1522|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=27|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=83518|pkt_pts_time=0.927978|pkt_dts=83517|pkt_dts_time=0.927967|best_effort_timestamp=83518|best_effort_timestamp_time=0.927978|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=48651|pkt_size=1522|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=27|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=86521|pts_time=0.961344|dts=86520|dts_time=0.961333|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1099|pos=52592|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=86521|pkt_pts_time=0.961344|pkt_dts=86520|pkt_dts_time=0.961333|best_effort_timestamp=86521|best_effort_timestamp_time=0.961344|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=52592|pkt_size=1099|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=30|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=86521|pkt_pts_time=0.961344|pkt_dts=86520|pkt_dts_time=0.961333|best_effort_timestamp=86521|best_effort_timestamp_time=0.961344|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=52592|pkt_size=1099|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=30|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=95530|pts_time=1.061444|dts=89523|dts_time=0.994700|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2558|pos=53691|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=89524|pkt_pts_time=0.994711|pkt_dts=89523|pkt_dts_time=0.994700|best_effort_timestamp=89524|best_effort_timestamp_time=0.994711|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=50892|pkt_size=1700|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=29|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=89524|pkt_pts_time=0.994711|pkt_dts=89523|pkt_dts_time=0.994700|best_effort_timestamp=89524|best_effort_timestamp_time=0.994711|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=50892|pkt_size=1700|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=29|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=92527|pts_time=1.028078|dts=92526|dts_time=1.028067|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1008|pos=56249|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=92527|pkt_pts_time=1.028078|pkt_dts=92526|pkt_dts_time=1.028067|best_effort_timestamp=92527|best_effort_timestamp_time=1.028078|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=56249|pkt_size=1008|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=32|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=92527|pkt_pts_time=1.028078|pkt_dts=92526|pkt_dts_time=1.028067|best_effort_timestamp=92527|best_effort_timestamp_time=1.028078|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=56249|pkt_size=1008|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=32|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=101536|pts_time=1.128178|dts=95529|dts_time=1.061433|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1236|pos=57257|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=95530|pkt_pts_time=1.061444|pkt_dts=95529|pkt_dts_time=1.061433|best_effort_timestamp=95530|best_effort_timestamp_time=1.061444|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=53691|pkt_size=2558|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=31|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=95530|pkt_pts_time=1.061444|pkt_dts=95529|pkt_dts_time=1.061433|best_effort_timestamp=95530|best_effort_timestamp_time=1.061444|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=53691|pkt_size=2558|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=31|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=98533|pts_time=1.094811|dts=98532|dts_time=1.094800|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=607|pos=58493|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=98533|pkt_pts_time=1.094811|pkt_dts=98532|pkt_dts_time=1.094800|best_effort_timestamp=98533|best_effort_timestamp_time=1.094811|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=58493|pkt_size=607|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=34|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=98533|pkt_pts_time=1.094811|pkt_dts=98532|pkt_dts_time=1.094800|best_effort_timestamp=98533|best_effort_timestamp_time=1.094811|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=58493|pkt_size=607|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=34|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=107542|pts_time=1.194911|dts=101535|dts_time=1.128167|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1883|pos=59100|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=101536|pkt_pts_time=1.128178|pkt_dts=101535|pkt_dts_time=1.128167|best_effort_timestamp=101536|best_effort_timestamp_time=1.128178|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=57257|pkt_size=1236|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=33|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=101536|pkt_pts_time=1.128178|pkt_dts=101535|pkt_dts_time=1.128167|best_effort_timestamp=101536|best_effort_timestamp_time=1.128178|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=57257|pkt_size=1236|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=33|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=104539|pts_time=1.161544|dts=104538|dts_time=1.161533|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=893|pos=60983|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=104539|pkt_pts_time=1.161544|pkt_dts=104538|pkt_dts_time=1.161533|best_effort_timestamp=104539|best_effort_timestamp_time=1.161544|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=60983|pkt_size=893|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=36|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=104539|pkt_pts_time=1.161544|pkt_dts=104538|pkt_dts_time=1.161533|best_effort_timestamp=104539|best_effort_timestamp_time=1.161544|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=60983|pkt_size=893|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=36|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=113548|pts_time=1.261644|dts=107541|dts_time=1.194900|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1305|pos=61876|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=107542|pkt_pts_time=1.194911|pkt_dts=107541|pkt_dts_time=1.194900|best_effort_timestamp=107542|best_effort_timestamp_time=1.194911|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=59100|pkt_size=1883|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=35|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=107542|pkt_pts_time=1.194911|pkt_dts=107541|pkt_dts_time=1.194900|best_effort_timestamp=107542|best_effort_timestamp_time=1.194911|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=59100|pkt_size=1883|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=35|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=110545|pts_time=1.228278|dts=110544|dts_time=1.228267|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=472|pos=63181|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=110545|pkt_pts_time=1.228278|pkt_dts=110544|pkt_dts_time=1.228267|best_effort_timestamp=110545|best_effort_timestamp_time=1.228278|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=63181|pkt_size=472|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=38|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=110545|pkt_pts_time=1.228278|pkt_dts=110544|pkt_dts_time=1.228267|best_effort_timestamp=110545|best_effort_timestamp_time=1.228278|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=63181|pkt_size=472|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=38|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=119554|pts_time=1.328378|dts=113547|dts_time=1.261633|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1411|pos=63653|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=113548|pkt_pts_time=1.261644|pkt_dts=113547|pkt_dts_time=1.261633|best_effort_timestamp=113548|best_effort_timestamp_time=1.261644|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=61876|pkt_size=1305|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=37|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=113548|pkt_pts_time=1.261644|pkt_dts=113547|pkt_dts_time=1.261633|best_effort_timestamp=113548|best_effort_timestamp_time=1.261644|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=61876|pkt_size=1305|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=37|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=116551|pts_time=1.295011|dts=116550|dts_time=1.295000|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=616|pos=65064|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=116551|pkt_pts_time=1.295011|pkt_dts=116550|pkt_dts_time=1.295000|best_effort_timestamp=116551|best_effort_timestamp_time=1.295011|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=65064|pkt_size=616|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=40|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=116551|pkt_pts_time=1.295011|pkt_dts=116550|pkt_dts_time=1.295000|best_effort_timestamp=116551|best_effort_timestamp_time=1.295011|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=65064|pkt_size=616|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=40|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=125560|pts_time=1.395111|dts=119553|dts_time=1.328367|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1291|pos=65680|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=119554|pkt_pts_time=1.328378|pkt_dts=119553|pkt_dts_time=1.328367|best_effort_timestamp=119554|best_effort_timestamp_time=1.328378|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=63653|pkt_size=1411|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=39|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=119554|pkt_pts_time=1.328378|pkt_dts=119553|pkt_dts_time=1.328367|best_effort_timestamp=119554|best_effort_timestamp_time=1.328378|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=63653|pkt_size=1411|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=39|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=122557|pts_time=1.361744|dts=122556|dts_time=1.361733|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=470|pos=66971|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=122557|pkt_pts_time=1.361744|pkt_dts=122556|pkt_dts_time=1.361733|best_effort_timestamp=122557|best_effort_timestamp_time=1.361744|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=66971|pkt_size=470|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=42|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=122557|pkt_pts_time=1.361744|pkt_dts=122556|pkt_dts_time=1.361733|best_effort_timestamp=122557|best_effort_timestamp_time=1.361744|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=66971|pkt_size=470|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=42|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=131566|pts_time=1.461844|dts=125559|dts_time=1.395100|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1977|pos=67441|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=125560|pkt_pts_time=1.395111|pkt_dts=125559|pkt_dts_time=1.395100|best_effort_timestamp=125560|best_effort_timestamp_time=1.395111|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=65680|pkt_size=1291|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=41|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=125560|pkt_pts_time=1.395111|pkt_dts=125559|pkt_dts_time=1.395100|best_effort_timestamp=125560|best_effort_timestamp_time=1.395111|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=65680|pkt_size=1291|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=41|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=128563|pts_time=1.428478|dts=128562|dts_time=1.428467|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=436|pos=69418|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=128563|pkt_pts_time=1.428478|pkt_dts=128562|pkt_dts_time=1.428467|best_effort_timestamp=128563|best_effort_timestamp_time=1.428478|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=69418|pkt_size=436|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=44|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=128563|pkt_pts_time=1.428478|pkt_dts=128562|pkt_dts_time=1.428467|best_effort_timestamp=128563|best_effort_timestamp_time=1.428478|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=69418|pkt_size=436|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=44|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=137572|pts_time=1.528578|dts=131565|dts_time=1.461833|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2566|pos=69854|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=131566|pkt_pts_time=1.461844|pkt_dts=131565|pkt_dts_time=1.461833|best_effort_timestamp=131566|best_effort_timestamp_time=1.461844|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=67441|pkt_size=1977|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=43|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=131566|pkt_pts_time=1.461844|pkt_dts=131565|pkt_dts_time=1.461833|best_effort_timestamp=131566|best_effort_timestamp_time=1.461844|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=67441|pkt_size=1977|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=43|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=134569|pts_time=1.495211|dts=134568|dts_time=1.495200|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=886|pos=72420|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=134569|pkt_pts_time=1.495211|pkt_dts=134568|pkt_dts_time=1.495200|best_effort_timestamp=134569|best_effort_timestamp_time=1.495211|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=72420|pkt_size=886|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=46|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=134569|pkt_pts_time=1.495211|pkt_dts=134568|pkt_dts_time=1.495200|best_effort_timestamp=134569|best_effort_timestamp_time=1.495211|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=72420|pkt_size=886|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=46|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=140575|pts_time=1.561944|dts=137571|dts_time=1.528567|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1330|pos=73306|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=137572|pkt_pts_time=1.528578|pkt_dts=137571|pkt_dts_time=1.528567|best_effort_timestamp=137572|best_effort_timestamp_time=1.528578|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=69854|pkt_size=2566|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=45|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=137572|pkt_pts_time=1.528578|pkt_dts=137571|pkt_dts_time=1.528567|best_effort_timestamp=137572|best_effort_timestamp_time=1.528578|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=69854|pkt_size=2566|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=45|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=143578|pts_time=1.595311|dts=140574|dts_time=1.561933|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2227|pos=74636|flags=K_ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=140575|pkt_pts_time=1.561944|pkt_dts=140574|pkt_dts_time=1.561933|best_effort_timestamp=140575|best_effort_timestamp_time=1.561944|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=73306|pkt_size=1330|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=47|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=140575|pkt_pts_time=1.561944|pkt_dts=140574|pkt_dts_time=1.561933|best_effort_timestamp=140575|best_effort_timestamp_time=1.561944|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=73306|pkt_size=1330|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=47|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=149584|pts_time=1.662044|dts=143577|dts_time=1.595300|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2210|pos=76863|flags=__ -frame|media_type=video|stream_index=0|key_frame=1|pkt_pts=143578|pkt_pts_time=1.595311|pkt_dts=143577|pkt_dts_time=1.595300|best_effort_timestamp=143578|best_effort_timestamp_time=1.595311|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=74636|pkt_size=2227|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=I|coded_picture_number=48|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=1|pkt_pts=143578|pkt_pts_time=1.595311|pkt_dts=143577|pkt_dts_time=1.595300|best_effort_timestamp=143578|best_effort_timestamp_time=1.595311|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=74636|pkt_size=2227|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=I|coded_picture_number=48|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=146581|pts_time=1.628678|dts=146580|dts_time=1.628667|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1498|pos=79073|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=146581|pkt_pts_time=1.628678|pkt_dts=146580|pkt_dts_time=1.628667|best_effort_timestamp=146581|best_effort_timestamp_time=1.628678|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=79073|pkt_size=1498|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=50|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=146581|pkt_pts_time=1.628678|pkt_dts=146580|pkt_dts_time=1.628667|best_effort_timestamp=146581|best_effort_timestamp_time=1.628678|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=79073|pkt_size=1498|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=50|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=155590|pts_time=1.728778|dts=149583|dts_time=1.662033|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1721|pos=80571|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=149584|pkt_pts_time=1.662044|pkt_dts=149583|pkt_dts_time=1.662033|best_effort_timestamp=149584|best_effort_timestamp_time=1.662044|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=76863|pkt_size=2210|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=49|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=149584|pkt_pts_time=1.662044|pkt_dts=149583|pkt_dts_time=1.662033|best_effort_timestamp=149584|best_effort_timestamp_time=1.662044|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=76863|pkt_size=2210|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=49|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=152587|pts_time=1.695411|dts=152586|dts_time=1.695400|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1238|pos=82292|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=152587|pkt_pts_time=1.695411|pkt_dts=152586|pkt_dts_time=1.695400|best_effort_timestamp=152587|best_effort_timestamp_time=1.695411|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=82292|pkt_size=1238|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=52|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=152587|pkt_pts_time=1.695411|pkt_dts=152586|pkt_dts_time=1.695400|best_effort_timestamp=152587|best_effort_timestamp_time=1.695411|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=82292|pkt_size=1238|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=52|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=161596|pts_time=1.795511|dts=155589|dts_time=1.728767|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1753|pos=83530|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=155590|pkt_pts_time=1.728778|pkt_dts=155589|pkt_dts_time=1.728767|best_effort_timestamp=155590|best_effort_timestamp_time=1.728778|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=80571|pkt_size=1721|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=51|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=155590|pkt_pts_time=1.728778|pkt_dts=155589|pkt_dts_time=1.728767|best_effort_timestamp=155590|best_effort_timestamp_time=1.728778|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=80571|pkt_size=1721|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=51|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=158593|pts_time=1.762144|dts=158592|dts_time=1.762133|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1014|pos=85283|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=158593|pkt_pts_time=1.762144|pkt_dts=158592|pkt_dts_time=1.762133|best_effort_timestamp=158593|best_effort_timestamp_time=1.762144|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=85283|pkt_size=1014|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=54|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=158593|pkt_pts_time=1.762144|pkt_dts=158592|pkt_dts_time=1.762133|best_effort_timestamp=158593|best_effort_timestamp_time=1.762144|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=85283|pkt_size=1014|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=54|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=167602|pts_time=1.862244|dts=161595|dts_time=1.795500|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2408|pos=86297|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=161596|pkt_pts_time=1.795511|pkt_dts=161595|pkt_dts_time=1.795500|best_effort_timestamp=161596|best_effort_timestamp_time=1.795511|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=83530|pkt_size=1753|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=53|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=161596|pkt_pts_time=1.795511|pkt_dts=161595|pkt_dts_time=1.795500|best_effort_timestamp=161596|best_effort_timestamp_time=1.795511|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=83530|pkt_size=1753|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=53|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=164599|pts_time=1.828878|dts=164598|dts_time=1.828867|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1727|pos=88705|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=164599|pkt_pts_time=1.828878|pkt_dts=164598|pkt_dts_time=1.828867|best_effort_timestamp=164599|best_effort_timestamp_time=1.828878|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=88705|pkt_size=1727|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=56|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=164599|pkt_pts_time=1.828878|pkt_dts=164598|pkt_dts_time=1.828867|best_effort_timestamp=164599|best_effort_timestamp_time=1.828878|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=88705|pkt_size=1727|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=56|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=173608|pts_time=1.928978|dts=167601|dts_time=1.862233|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1504|pos=90432|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=167602|pkt_pts_time=1.862244|pkt_dts=167601|pkt_dts_time=1.862233|best_effort_timestamp=167602|best_effort_timestamp_time=1.862244|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=86297|pkt_size=2408|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=55|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=167602|pkt_pts_time=1.862244|pkt_dts=167601|pkt_dts_time=1.862233|best_effort_timestamp=167602|best_effort_timestamp_time=1.862244|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=86297|pkt_size=2408|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=55|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=170605|pts_time=1.895611|dts=170604|dts_time=1.895600|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=957|pos=91936|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=170605|pkt_pts_time=1.895611|pkt_dts=170604|pkt_dts_time=1.895600|best_effort_timestamp=170605|best_effort_timestamp_time=1.895611|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=91936|pkt_size=957|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=58|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=170605|pkt_pts_time=1.895611|pkt_dts=170604|pkt_dts_time=1.895600|best_effort_timestamp=170605|best_effort_timestamp_time=1.895611|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=91936|pkt_size=957|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=58|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=179614|pts_time=1.995711|dts=173607|dts_time=1.928967|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1890|pos=92893|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=173608|pkt_pts_time=1.928978|pkt_dts=173607|pkt_dts_time=1.928967|best_effort_timestamp=173608|best_effort_timestamp_time=1.928978|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=90432|pkt_size=1504|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=57|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=173608|pkt_pts_time=1.928978|pkt_dts=173607|pkt_dts_time=1.928967|best_effort_timestamp=173608|best_effort_timestamp_time=1.928978|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=90432|pkt_size=1504|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=57|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=176611|pts_time=1.962344|dts=176610|dts_time=1.962333|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1239|pos=94783|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=176611|pkt_pts_time=1.962344|pkt_dts=176610|pkt_dts_time=1.962333|best_effort_timestamp=176611|best_effort_timestamp_time=1.962344|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=94783|pkt_size=1239|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=60|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=176611|pkt_pts_time=1.962344|pkt_dts=176610|pkt_dts_time=1.962333|best_effort_timestamp=176611|best_effort_timestamp_time=1.962344|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=94783|pkt_size=1239|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=60|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=185620|pts_time=2.062444|dts=179613|dts_time=1.995700|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1856|pos=96022|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=179614|pkt_pts_time=1.995711|pkt_dts=179613|pkt_dts_time=1.995700|best_effort_timestamp=179614|best_effort_timestamp_time=1.995711|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=92893|pkt_size=1890|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=59|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=179614|pkt_pts_time=1.995711|pkt_dts=179613|pkt_dts_time=1.995700|best_effort_timestamp=179614|best_effort_timestamp_time=1.995711|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=92893|pkt_size=1890|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=59|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=182617|pts_time=2.029078|dts=182616|dts_time=2.029067|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1302|pos=97878|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=182617|pkt_pts_time=2.029078|pkt_dts=182616|pkt_dts_time=2.029067|best_effort_timestamp=182617|best_effort_timestamp_time=2.029078|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=97878|pkt_size=1302|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=62|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=182617|pkt_pts_time=2.029078|pkt_dts=182616|pkt_dts_time=2.029067|best_effort_timestamp=182617|best_effort_timestamp_time=2.029078|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=97878|pkt_size=1302|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=62|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=191626|pts_time=2.129178|dts=185619|dts_time=2.062433|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1666|pos=99180|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=185620|pkt_pts_time=2.062444|pkt_dts=185619|pkt_dts_time=2.062433|best_effort_timestamp=185620|best_effort_timestamp_time=2.062444|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=96022|pkt_size=1856|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=61|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=185620|pkt_pts_time=2.062444|pkt_dts=185619|pkt_dts_time=2.062433|best_effort_timestamp=185620|best_effort_timestamp_time=2.062444|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=96022|pkt_size=1856|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=61|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=188623|pts_time=2.095811|dts=188622|dts_time=2.095800|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=974|pos=100846|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=188623|pkt_pts_time=2.095811|pkt_dts=188622|pkt_dts_time=2.095800|best_effort_timestamp=188623|best_effort_timestamp_time=2.095811|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=100846|pkt_size=974|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=64|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=188623|pkt_pts_time=2.095811|pkt_dts=188622|pkt_dts_time=2.095800|best_effort_timestamp=188623|best_effort_timestamp_time=2.095811|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=100846|pkt_size=974|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=64|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft packet|codec_type=video|stream_index=0|pts=197632|pts_time=2.195911|dts=191625|dts_time=2.129167|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=580|pos=101820|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=191626|pkt_pts_time=2.129178|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=191626|best_effort_timestamp_time=2.129178|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=99180|pkt_size=1666|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=63|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0 +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=191626|pkt_pts_time=2.129178|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=191626|best_effort_timestamp_time=2.129178|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=99180|pkt_size=1666|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=63|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft stream|index=0|codec_name=h264|profile=77|codec_type=video|codec_time_base=212521/12744000|codec_tag_string=avc1|codec_tag=0x31637661|width=160|height=240|coded_width=160|coded_height=240|has_b_frames=0|sample_aspect_ratio=2:1|display_aspect_ratio=4:3|pix_fmt=yuv420p|level=12|color_range=tv|color_space=smpte170m|color_transfer=bt709|color_primaries=smpte170m|chroma_location=topleft|field_order=unknown|timecode=N/A|refs=2|is_avc=true|nal_length_size=4|id=N/A|r_frame_rate=30000/1001|avg_frame_rate=6372000/212521|time_base=1/90000|start_pts=0|start_time=0.000000|duration_ts=2125200|duration=23.613333|bit_rate=333874|max_bit_rate=N/A|bits_per_raw_sample=8|nb_frames=708|nb_read_frames=65|nb_read_packets=66|disposition:default=1|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|tag:rotate=0|tag:creation_time=2008-05-12T20:59:27.000000Z|tag:language=eng|tag:handler_name=Apple Alias Data Handler|tag:encoder=H.264 side_data|side_data_type=Display Matrix|displaymatrix=\n00000000: 131072 0 0\n00000001: 0 65536 0\n00000002: 0 0 1073741824\n|rotation=0 From f48efb14f9f9000ae8b62fd8e1ddb55d2b8cb1ea Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sat, 22 Jul 2017 21:49:46 +0100 Subject: [PATCH 2616/3374] pixdesc: Explicitly handle invalid arguments to av_find_best_pix_fmt_of_2() --- libavutil/pixdesc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index 1983ce9ef5438..e606b8e5c8e72 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -2633,6 +2633,11 @@ enum AVPixelFormat av_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, en const AVPixFmtDescriptor *desc2 = av_pix_fmt_desc_get(dst_pix_fmt2); int score1, score2; + if (!desc1) { + dst_pix_fmt = dst_pix_fmt2; + } else if (!desc2) { + dst_pix_fmt = dst_pix_fmt1; + } else { loss_mask= loss_ptr?~*loss_ptr:~0; /* use loss mask if provided */ if(!has_alpha) loss_mask &= ~FF_LOSS_ALPHA; @@ -2649,6 +2654,7 @@ enum AVPixelFormat av_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, en } else { dst_pix_fmt = score1 < score2 ? dst_pix_fmt2 : dst_pix_fmt1; } + } if (loss_ptr) *loss_ptr = av_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha); From f2c11b9337c90b98c315d8e24de43fffb48fed60 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sat, 22 Jul 2017 21:51:41 +0100 Subject: [PATCH 2617/3374] pixdesc: Reindent after previous commit --- libavutil/pixdesc.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index e606b8e5c8e72..cea5b0ffd912e 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -2638,22 +2638,22 @@ enum AVPixelFormat av_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, en } else if (!desc2) { dst_pix_fmt = dst_pix_fmt1; } else { - loss_mask= loss_ptr?~*loss_ptr:~0; /* use loss mask if provided */ - if(!has_alpha) - loss_mask &= ~FF_LOSS_ALPHA; + loss_mask= loss_ptr?~*loss_ptr:~0; /* use loss mask if provided */ + if(!has_alpha) + loss_mask &= ~FF_LOSS_ALPHA; - score1 = get_pix_fmt_score(dst_pix_fmt1, src_pix_fmt, &loss1, loss_mask); - score2 = get_pix_fmt_score(dst_pix_fmt2, src_pix_fmt, &loss2, loss_mask); + score1 = get_pix_fmt_score(dst_pix_fmt1, src_pix_fmt, &loss1, loss_mask); + score2 = get_pix_fmt_score(dst_pix_fmt2, src_pix_fmt, &loss2, loss_mask); - if (score1 == score2) { - if(av_get_padded_bits_per_pixel(desc2) != av_get_padded_bits_per_pixel(desc1)) { - dst_pix_fmt = av_get_padded_bits_per_pixel(desc2) < av_get_padded_bits_per_pixel(desc1) ? dst_pix_fmt2 : dst_pix_fmt1; + if (score1 == score2) { + if(av_get_padded_bits_per_pixel(desc2) != av_get_padded_bits_per_pixel(desc1)) { + dst_pix_fmt = av_get_padded_bits_per_pixel(desc2) < av_get_padded_bits_per_pixel(desc1) ? dst_pix_fmt2 : dst_pix_fmt1; + } else { + dst_pix_fmt = desc2->nb_components < desc1->nb_components ? dst_pix_fmt2 : dst_pix_fmt1; + } } else { - dst_pix_fmt = desc2->nb_components < desc1->nb_components ? dst_pix_fmt2 : dst_pix_fmt1; + dst_pix_fmt = score1 < score2 ? dst_pix_fmt2 : dst_pix_fmt1; } - } else { - dst_pix_fmt = score1 < score2 ? dst_pix_fmt2 : dst_pix_fmt1; - } } if (loss_ptr) From 34fb84a97d112d85091369e9ef9ce177a05644e9 Mon Sep 17 00:00:00 2001 From: foo86 Date: Sat, 22 Jul 2017 18:16:13 +0300 Subject: [PATCH 2618/3374] avcodec/dcaadpcm: check for av_malloc() failure Fixes CID 1409915. --- libavcodec/dcaadpcm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavcodec/dcaadpcm.c b/libavcodec/dcaadpcm.c index 8742c7ccf6357..cc82241a5f2b3 100644 --- a/libavcodec/dcaadpcm.c +++ b/libavcodec/dcaadpcm.c @@ -215,6 +215,9 @@ av_cold int ff_dcaadpcm_init(DCAADPCMEncContext *s) return -1; s->private_data = av_malloc(sizeof(premultiplied_coeffs) * DCA_ADPCM_VQCODEBOOK_SZ); + if (!s->private_data) + return AVERROR(ENOMEM); + precalc(s->private_data); return 0; } From dd4b7badb416a5c2688da7310a7fe80fe4e4f209 Mon Sep 17 00:00:00 2001 From: foo86 Date: Sat, 22 Jul 2017 18:20:04 +0300 Subject: [PATCH 2619/3374] avcodec/dcaadpcm: fix use of uninitialized variable Fixes CID 1409924. --- libavcodec/dcaadpcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/dcaadpcm.c b/libavcodec/dcaadpcm.c index cc82241a5f2b3..9f615e379359d 100644 --- a/libavcodec/dcaadpcm.c +++ b/libavcodec/dcaadpcm.c @@ -80,7 +80,7 @@ static int64_t find_best_filter(const DCAADPCMEncContext *s, const int32_t *in, { const premultiplied_coeffs *precalc_data = s->private_data; int i, j, k = 0; - int vq; + int vq = -1; int64_t err; int64_t min_err = 1ll << 62; int64_t corr[15]; From 47c93657249f1a4bc8a7aaf2f9f3a33510bee38c Mon Sep 17 00:00:00 2001 From: Vodyannikov Aleksandr Date: Fri, 21 Jul 2017 11:49:45 +0200 Subject: [PATCH 2620/3374] avcodec/cfhd: Fix decoding regression due to height check Fixes: Ticket6546 Regression since: 54aaadf648073149f1ac34f56cbde4e6c5aa22ef Reviewed-by: Muhammad Faiz Reviewed-by: Kieran Kunhya Signed-off-by: Michael Niedermayer --- libavcodec/cfhd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c index f78bad9ae1afd..5ea8f24821a77 100644 --- a/libavcodec/cfhd.c +++ b/libavcodec/cfhd.c @@ -332,7 +332,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, s->plane[s->channel_num].band[0][0].stride = data; } else if (tag == 28) { av_log(avctx, AV_LOG_DEBUG, "Lowpass height %"PRIu16"\n", data); - if (data < 3 || data > s->plane[s->channel_num].band[0][0].height) { + if (data < 3 || data > s->plane[s->channel_num].band[0][0].a_height) { av_log(avctx, AV_LOG_ERROR, "Invalid lowpass height\n"); ret = AVERROR(EINVAL); break; From 6a6eec485d23b0c47a7cfeb94995db1be91c0e1a Mon Sep 17 00:00:00 2001 From: Brice Waegeneire Date: Sat, 22 Jul 2017 00:09:29 +0200 Subject: [PATCH 2621/3374] doc/filters: typo in frei0r Signed-off-by: Brice Waegeneire Signed-off-by: Michael Niedermayer --- doc/filters.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/filters.texi b/doc/filters.texi index 119d1be69d8fb..4c1ef0f48598e 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -8606,7 +8606,7 @@ It accepts the following parameters: @item filter_name The name of the frei0r effect to load. If the environment variable @env{FREI0R_PATH} is defined, the frei0r effect is searched for in each of the -directories specified by the colon-separated list in @env{FREIOR_PATH}. +directories specified by the colon-separated list in @env{FREI0R_PATH}. Otherwise, the standard frei0r paths are searched, in this order: @file{HOME/.frei0r-1/lib/}, @file{/usr/local/lib/frei0r-1/}, @file{/usr/lib/frei0r-1/}. From 7e9f5500039a31148dc971270ab569015e0ea247 Mon Sep 17 00:00:00 2001 From: Muhammad Faiz Date: Sat, 22 Jul 2017 18:46:07 +0700 Subject: [PATCH 2622/3374] avfilter/w3fdif: do not write to line before start line That line has been written by previous job. Fix tsan warning. Reviewed-by: Paul B Mahol Signed-off-by: Muhammad Faiz --- libavfilter/vf_w3fdif.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavfilter/vf_w3fdif.c b/libavfilter/vf_w3fdif.c index b7872db341929..c6a65507784c6 100644 --- a/libavfilter/vf_w3fdif.c +++ b/libavfilter/vf_w3fdif.c @@ -366,7 +366,7 @@ static int deinterlace_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_ int j, y_in, y_out; /* copy unchanged the lines of the field */ - y_out = start + (s->field == cur->top_field_first) - (start & 1); + y_out = start + ((s->field == cur->top_field_first) ^ (start & 1)); in_line = cur_data + (y_out * cur_line_stride); out_line = dst_data + (y_out * dst_line_stride); @@ -379,7 +379,7 @@ static int deinterlace_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_ } /* interpolate other lines of the field */ - y_out = start + (s->field != cur->top_field_first) - (start & 1); + y_out = start + ((s->field != cur->top_field_first) ^ (start & 1)); out_line = dst_data + (y_out * dst_line_stride); From 69e7daf6ce2a5893936ba18572c58180b29d67f9 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 19 Jul 2017 01:43:24 +0200 Subject: [PATCH 2623/3374] avcodec/dirac_vlc: Fix undefined shift Fixes: runtime error: shift exponent 64 is too large for 64-bit type 'residual' (aka 'unsigned long') Fixes: 2674/clusterfuzz-testcase-minimized-4999700518273024 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/dirac_vlc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libavcodec/dirac_vlc.c b/libavcodec/dirac_vlc.c index 336d22a182989..773f720858d9e 100644 --- a/libavcodec/dirac_vlc.c +++ b/libavcodec/dirac_vlc.c @@ -216,9 +216,14 @@ static void generate_offset_lut(DiracGolombLUT *lut, int off) INIT_RESIDUE(res); SET_RESIDUE(res, idx, LUT_BITS); - l->preamble = CONVERT_TO_RESIDUE(res >> (RSIZE_BITS - off), off); l->preamble_bits = off; - l->sign = ((l->preamble >> (RSIZE_BITS - l->preamble_bits)) & 1) ? -1 : +1; + if (off) { + l->preamble = CONVERT_TO_RESIDUE(res >> (RSIZE_BITS - off), off); + l->sign = ((l->preamble >> (RSIZE_BITS - l->preamble_bits)) & 1) ? -1 : +1; + } else { + l->preamble = 0; + l->sign = 1; + } search_for_golomb(l, res << off, LUT_BITS - off); } From 2dfb8c417891e0cc3670f8e0791ea0c7071314fe Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 23 Jul 2017 16:52:47 +0200 Subject: [PATCH 2624/3374] avcodec/aacdec_fixed: fix: left shift of negative value -1 Fixes: 2699/clusterfuzz-testcase-minimized-5631303862976512 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/aacdec_fixed.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/aacdec_fixed.c b/libavcodec/aacdec_fixed.c index 2b340bd7625b3..ccfef7f6526d7 100644 --- a/libavcodec/aacdec_fixed.c +++ b/libavcodec/aacdec_fixed.c @@ -432,7 +432,7 @@ static void apply_independent_coupling_fixed(AACContext *ac, else { for (i = 0; i < len; i++) { tmp = (int)(((int64_t)src[i] * c + (int64_t)0x1000000000) >> 37); - dest[i] += tmp << shift; + dest[i] += tmp * (1 << shift); } } } From aff93e19297cc469a560927fe728905705a1845c Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 20 Jun 2017 00:37:41 +0200 Subject: [PATCH 2625/3374] avcodec/mpegvideo_enc: Use intra/inter scantable matching mb type in quantization Signed-off-by: Michael Niedermayer --- libavcodec/mpegvideo_enc.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index fffb113096561..97257ce98c4cf 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -4056,8 +4056,8 @@ static int dct_quantize_trellis_c(MpegEncContext *s, int qscale, int *overflow){ const int *qmat; const uint16_t *matrix; - const uint8_t *scantable= s->intra_scantable.scantable; - const uint8_t *perm_scantable= s->intra_scantable.permutated; + const uint8_t *scantable; + const uint8_t *perm_scantable; int max=0; unsigned int threshold1, threshold2; int bias=0; @@ -4090,6 +4090,8 @@ static int dct_quantize_trellis_c(MpegEncContext *s, else mpeg2_qscale = qscale << 1; if (s->mb_intra) { + scantable= s->intra_scantable.scantable; + perm_scantable= s->intra_scantable.permutated; int q; if (!s->h263_aic) { if (n < 4) @@ -4120,6 +4122,8 @@ static int dct_quantize_trellis_c(MpegEncContext *s, last_length= s->intra_ac_vlc_last_length; } } else { + scantable= s->inter_scantable.scantable; + perm_scantable= s->inter_scantable.permutated; start_i = 0; last_non_zero = -1; qmat = s->q_inter_matrix[qscale]; @@ -4387,8 +4391,8 @@ static int dct_quantize_refine(MpegEncContext *s, //FIXME breaks denoise? int n, int qscale){ int16_t rem[64]; LOCAL_ALIGNED_16(int16_t, d1, [64]); - const uint8_t *scantable= s->intra_scantable.scantable; - const uint8_t *perm_scantable= s->intra_scantable.permutated; + const uint8_t *scantable; + const uint8_t *perm_scantable; // unsigned int threshold1, threshold2; // int bias=0; int run_tab[65]; @@ -4415,6 +4419,8 @@ static int messed_sign=0; qmul= qscale*2; qadd= (qscale-1)|1; if (s->mb_intra) { + scantable= s->intra_scantable.scantable; + perm_scantable= s->intra_scantable.permutated; if (!s->h263_aic) { if (n < 4) q = s->y_dc_scale; @@ -4440,6 +4446,8 @@ static int messed_sign=0; last_length= s->intra_ac_vlc_last_length; } } else { + scantable= s->inter_scantable.scantable; + perm_scantable= s->inter_scantable.permutated; dc= 0; start_i = 0; length = s->inter_ac_vlc_length; @@ -4804,7 +4812,7 @@ int ff_dct_quantize_c(MpegEncContext *s, { int i, j, level, last_non_zero, q, start_i; const int *qmat; - const uint8_t *scantable= s->intra_scantable.scantable; + const uint8_t *scantable; int bias; int max=0; unsigned int threshold1, threshold2; @@ -4815,6 +4823,7 @@ int ff_dct_quantize_c(MpegEncContext *s, s->denoise_dct(s, block); if (s->mb_intra) { + scantable= s->intra_scantable.scantable; if (!s->h263_aic) { if (n < 4) q = s->y_dc_scale; @@ -4832,6 +4841,7 @@ int ff_dct_quantize_c(MpegEncContext *s, qmat = n < 4 ? s->q_intra_matrix[qscale] : s->q_chroma_intra_matrix[qscale]; bias= s->intra_quant_bias*(1<<(QMAT_SHIFT - QUANT_BIAS_SHIFT)); } else { + scantable= s->inter_scantable.scantable; start_i = 0; last_non_zero = -1; qmat = s->q_inter_matrix[qscale]; From f21457f8e0db369bd1624e9a17c84ad00b7ac40d Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Mon, 24 Jul 2017 19:55:19 +0800 Subject: [PATCH 2626/3374] avformat/hlsenc: fix hls fmp4 extention name bug ticket-id: #6541 when use hls fmp4 muxer, the extention name is not .m4s, this code can fix it. Found-by: JohnPi Signed-off-by: Steven Liu --- libavformat/hlsenc.c | 47 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 8a233270b5a39..b0625dc9d43fd 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -147,6 +147,7 @@ typedef struct HLSContext { HLSSegment *old_segments; char *basename; + char *base_output_dirname; char *vtt_basename; char *vtt_m3u8_name; char *baseurl; @@ -584,7 +585,7 @@ static int hls_mux_init(AVFormatContext *s) if (hls->segment_type == SEGMENT_TYPE_FMP4) { hls->fmp4_init_mode = 1; - if ((ret = s->io_open(s, &oc->pb, hls->fmp4_init_filename, AVIO_FLAG_WRITE, NULL)) < 0) { + if ((ret = s->io_open(s, &oc->pb, hls->base_output_dirname, AVIO_FLAG_WRITE, NULL)) < 0) { av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", hls->fmp4_init_filename); return ret; } @@ -1286,14 +1287,19 @@ static int hls_start(AVFormatContext *s) return err; } -static const char * get_default_pattern_localtime_fmt(void) +static const char * get_default_pattern_localtime_fmt(AVFormatContext *s) { char b[21]; time_t t = time(NULL); struct tm *p, tmbuf; + HLSContext *hls = s->priv_data; + p = localtime_r(&t, &tmbuf); // no %s support when strftime returned error or left format string unchanged // also no %s support on MSVC, which invokes the invalid parameter handler on unsupported format strings, instead of returning an error + if (hls->segment_type == SEGMENT_TYPE_FMP4) { + return (HAVE_LIBC_MSVCRT || !strftime(b, sizeof(b), "%s", p) || !strcmp(b, "%s")) ? "-%Y%m%d%H%M%S.m4s" : "-%s.m4s"; + } return (HAVE_LIBC_MSVCRT || !strftime(b, sizeof(b), "%s", p) || !strcmp(b, "%s")) ? "-%Y%m%d%H%M%S.ts" : "-%s.ts"; } @@ -1303,16 +1309,19 @@ static int hls_write_header(AVFormatContext *s) int ret, i; char *p; const char *pattern = "%d.ts"; - const char *pattern_localtime_fmt = get_default_pattern_localtime_fmt(); + const char *pattern_localtime_fmt = get_default_pattern_localtime_fmt(s); const char *vtt_pattern = "%d.vtt"; AVDictionary *options = NULL; int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0); int basename_size; int vtt_basename_size; - if (hls->segment_type == SEGMENT_TYPE_FMP4 && byterange_mode) { - av_log(s, AV_LOG_WARNING, "Have not support fmp4 byterange mode yet now\n"); - return AVERROR_PATCHWELCOME; + if (hls->segment_type == SEGMENT_TYPE_FMP4) { + if (byterange_mode) { + av_log(s, AV_LOG_WARNING, "Have not support fmp4 byterange mode yet now\n"); + return AVERROR_PATCHWELCOME; + } + pattern = "%d.m4s"; } if ((hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH) || (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_FORMATTED_DATETIME)) { @@ -1412,6 +1421,31 @@ static int hls_write_header(AVFormatContext *s) } else { av_strlcat(hls->basename, pattern, basename_size); } + + if (av_strcasecmp(hls->fmp4_init_filename, "init.mp4")) { + int fmp4_init_filename_len = strlen(hls->fmp4_init_filename) + 1; + hls->base_output_dirname = av_malloc(fmp4_init_filename_len); + if (!hls->base_output_dirname) { + ret = AVERROR(ENOMEM); + goto fail; + } + av_strlcpy(hls->base_output_dirname, hls->fmp4_init_filename, fmp4_init_filename_len); + } else { + hls->base_output_dirname = av_malloc(basename_size); + if (!hls->base_output_dirname) { + ret = AVERROR(ENOMEM); + goto fail; + } + + av_strlcpy(hls->base_output_dirname, s->filename, basename_size); + p = strrchr(hls->base_output_dirname, '/'); + if (p) { + *(p + 1) = '\0'; + av_strlcat(hls->base_output_dirname, hls->fmp4_init_filename, basename_size); + } else { + av_strlcpy(hls->base_output_dirname, hls->fmp4_init_filename, basename_size); + } + } } if (!hls->use_localtime) { ret = sls_flag_check_duration_size_index(hls); @@ -1686,6 +1720,7 @@ static int hls_write_trailer(struct AVFormatContext *s) ff_format_io_close(s, &vtt_oc->pb); } av_freep(&hls->basename); + av_freep(&hls->base_output_dirname); av_freep(&hls->key_basename); avformat_free_context(oc); From 850a45aef10b50a2344a71055a30987aea23e48a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Fri, 21 Jul 2017 10:30:19 +0200 Subject: [PATCH 2627/3374] lavf/movenc: support GPMF track (gpmd) remuxing See https://github.com/gopro/gpmf-parser for more information on the data stream itself. --- libavformat/movenc.c | 25 +++++++++++++++++++++++++ tests/fate/mov.mak | 5 +++++ 2 files changed, 30 insertions(+) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 3989ac167e1b3..0e5b45d150cd2 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -2060,6 +2060,18 @@ static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track) return update_size(pb, pos); } +static int mov_write_gpmd_tag(AVIOContext *pb, const MOVTrack *track) +{ + int64_t pos = avio_tell(pb); + avio_wb32(pb, 0); /* size */ + ffio_wfourcc(pb, "gpmd"); + avio_wb32(pb, 0); /* Reserved */ + avio_wb16(pb, 0); /* Reserved */ + avio_wb16(pb, 1); /* Data-reference index */ + avio_wb32(pb, 0); /* Reserved */ + return update_size(pb, pos); +} + static int mov_write_stsd_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track) { int64_t pos = avio_tell(pb); @@ -2077,6 +2089,8 @@ static int mov_write_stsd_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext mov_write_rtp_tag(pb, track); else if (track->par->codec_tag == MKTAG('t','m','c','d')) mov_write_tmcd_tag(pb, track); + else if (track->par->codec_tag == MKTAG('g','p','m','d')) + mov_write_gpmd_tag(pb, track); return update_size(pb, pos); } @@ -2377,6 +2391,12 @@ static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack *track) ffio_wfourcc(pb, "tmcd"); mov_write_tcmi_tag(pb, track); update_size(pb, tmcd_pos); + } else if (track->par->codec_tag == MKTAG('g','p','m','d')) { + int64_t gpmd_pos = avio_tell(pb); + avio_wb32(pb, 0); /* size */ + ffio_wfourcc(pb, "gpmd"); + avio_wb32(pb, 0); /* version */ + update_size(pb, gpmd_pos); } return update_size(pb, pos); } @@ -2443,6 +2463,9 @@ static int mov_write_hdlr_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra } else if (track->par->codec_tag == MKTAG('t','m','c','d')) { hdlr_type = "tmcd"; descr = "TimeCodeHandler"; + } else if (track->par->codec_tag == MKTAG('g','p','m','d')) { + hdlr_type = "meta"; + descr = "GoPro MET"; // GoPro Metadata } else { av_log(s, AV_LOG_WARNING, "Unknown hldr_type for %s, writing dummy values\n", @@ -2514,6 +2537,8 @@ static int mov_write_minf_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext mov_write_nmhd_tag(pb); else mov_write_gmhd_tag(pb, track); + } else if (track->tag == MKTAG('g','p','m','d')) { + mov_write_gmhd_tag(pb, track); } if (track->mode == MODE_MOV) /* FIXME: Why do it for MODE_MOV only ? */ mov_write_hdlr_tag(s, pb, NULL); diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak index eac2f3789ed60..cfdada7a2e070 100644 --- a/tests/fate/mov.mak +++ b/tests/fate/mov.mak @@ -6,6 +6,7 @@ FATE_MOV = fate-mov-3elist \ fate-mov-1elist-ends-last-bframe \ fate-mov-2elist-elist1-ends-bframe \ fate-mov-3elist-encrypted \ + fate-mov-gpmf-remux \ FATE_MOV_FFPROBE = fate-mov-aac-2048-priming \ fate-mov-zombie \ @@ -47,3 +48,7 @@ fate-mov-init-nonkeyframe: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_packets - fate-mov-displaymatrix: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream=display_aspect_ratio,sample_aspect_ratio:stream_side_data_list -select_streams v -v 0 $(TARGET_SAMPLES)/mov/displaymatrix.mov fate-mov-spherical-mono: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream_side_data_list -select_streams v -v 0 $(TARGET_SAMPLES)/mov/spherical.mov + +fate-mov-gpmf-remux: CMD = md5 -i $(TARGET_SAMPLES)/mov/fake-gp-media-with-real-gpmf.mp4 -map 0 -c copy -fflags +bitexact -f mp4 +fate-mov-gpmf-remux: CMP = oneline +fate-mov-gpmf-remux: REF = 8f48e435ee1f6b7e173ea756141eabf3 From 0764fe1d09833ae4dcf9e427df09378d0d6a3386 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 22 Jul 2017 00:44:14 +0200 Subject: [PATCH 2628/3374] avcodec/aacps: Fix multiple integer overflow in map_val_34_to_20() Fixes: avcodec/aacps.c:511:40: runtime error: signed integer overflow: 1509077651 + 758068176 cannot be represented in type 'int' Fixes: 2678/clusterfuzz-testcase-minimized-4702787684270080 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/aacps.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/aacps.c b/libavcodec/aacps.c index 5758b919a1ee8..b16c3393d1061 100644 --- a/libavcodec/aacps.c +++ b/libavcodec/aacps.c @@ -504,13 +504,13 @@ static void map_idx_34_to_20(int8_t *par_mapped, const int8_t *par, int full) static void map_val_34_to_20(INTFLOAT par[PS_MAX_NR_IIDICC]) { #if USE_FIXED - par[ 0] = (int)(((int64_t)(par[ 0] + (par[ 1]>>1)) * 1431655765 + \ + par[ 0] = (int)(((int64_t)(par[ 0] + (unsigned)(par[ 1]>>1)) * 1431655765 + \ 0x40000000) >> 31); - par[ 1] = (int)(((int64_t)((par[ 1]>>1) + par[ 2]) * 1431655765 + \ + par[ 1] = (int)(((int64_t)((par[ 1]>>1) + (unsigned)par[ 2]) * 1431655765 + \ 0x40000000) >> 31); - par[ 2] = (int)(((int64_t)(par[ 3] + (par[ 4]>>1)) * 1431655765 + \ + par[ 2] = (int)(((int64_t)(par[ 3] + (unsigned)(par[ 4]>>1)) * 1431655765 + \ 0x40000000) >> 31); - par[ 3] = (int)(((int64_t)((par[ 4]>>1) + par[ 5]) * 1431655765 + \ + par[ 3] = (int)(((int64_t)((par[ 4]>>1) + (unsigned)par[ 5]) * 1431655765 + \ 0x40000000) >> 31); #else par[ 0] = (2*par[ 0] + par[ 1]) * 0.33333333f; From 03a9e6ff303ad82e75b734edbe4917ca5fd60159 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 22 Jul 2017 02:57:12 +0200 Subject: [PATCH 2629/3374] avcodec/ylc: Fix shift overflow Fixes: runtime error: shift exponent 32 is too large for 32-bit type 'unsigned int' Fixes: 2698/clusterfuzz-testcase-minimized-4713541443518464 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/ylc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/ylc.c b/libavcodec/ylc.c index ae46b3b8c2667..11333222b9479 100644 --- a/libavcodec/ylc.c +++ b/libavcodec/ylc.c @@ -69,7 +69,7 @@ static void get_tree_codes(uint32_t *bits, int16_t *lens, uint8_t *xlat, s = nodes[node].sym; if (s != -1) { - bits[*pos] = (~pfx) & ((1U << FFMAX(pl, 1)) - 1); + bits[*pos] = (~pfx) & ((1ULL << FFMAX(pl, 1)) - 1); lens[*pos] = FFMAX(pl, 1); xlat[*pos] = s + (pl == 0); (*pos)++; From 805ce25b1d2f08ac4a8e9dcdb9657ad5f5e83d9e Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Tue, 25 Jul 2017 10:31:29 +0800 Subject: [PATCH 2630/3374] avformat/hlsenc: improve hls encrypt get key file operation get key file only once time is ok, no need more times. Ticket-id: #6545 Found-by: JohnPi Signed-off-by: Steven Liu --- libavformat/hlsenc.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index b0625dc9d43fd..f98f04100c711 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -1223,12 +1223,15 @@ static int hls_start(AVFormatContext *s) av_log(s, AV_LOG_WARNING, "Cannot use both -hls_key_info_file and -hls_enc," " will use -hls_key_info_file priority\n"); } - if (c->key_info_file) { - if ((err = hls_encryption_start(s)) < 0) - goto fail; - } else { - if ((err = do_encrypt(s)) < 0) - goto fail; + + if (c->number <= 1) { + if (c->key_info_file) { + if ((err = hls_encryption_start(s)) < 0) + goto fail; + } else { + if ((err = do_encrypt(s)) < 0) + goto fail; + } } if ((err = av_dict_set(&options, "encryption_key", c->key_string, 0)) < 0) From 4a654be3fb0a2575ce4c7a2a0f6924b5aa23ff93 Mon Sep 17 00:00:00 2001 From: James Almer Date: Tue, 25 Jul 2017 00:58:16 -0300 Subject: [PATCH 2631/3374] avcodec/mpegvideo_enc: fix mixed declarations and code warning --- libavcodec/mpegvideo_enc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index 97257ce98c4cf..918728391d46a 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -4090,9 +4090,9 @@ static int dct_quantize_trellis_c(MpegEncContext *s, else mpeg2_qscale = qscale << 1; if (s->mb_intra) { + int q; scantable= s->intra_scantable.scantable; perm_scantable= s->intra_scantable.permutated; - int q; if (!s->h263_aic) { if (n < 4) q = s->y_dc_scale; From bbc7cfbf1e0b02323d4af512612342d2627080d8 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Thu, 20 Jul 2017 17:35:44 +0200 Subject: [PATCH 2632/3374] lavfi/testsrc2: fix completely transparent alpha. --- doc/filters.texi | 5 +++++ libavfilter/vsrc_testsrc.c | 12 +++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 4c1ef0f48598e..2324b96867c23 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -16394,6 +16394,11 @@ The sources accept the following parameters: @table @option +@item alpha +Specify the alpha (opacity) of the background, only available in the +@code{testsrc2} source. The value must be between 0 (fully transparent) and +255 (fully opaque, the default). + @item color, c Specify the color of the source, only available in the @code{color} source. For the syntax of this option, check the "Color" section in the diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c index c4a5ae37422ea..fe0d50aa41a6a 100644 --- a/libavfilter/vsrc_testsrc.c +++ b/libavfilter/vsrc_testsrc.c @@ -66,6 +66,9 @@ typedef struct TestSourceContext { /* only used by testsrc */ int nb_decimals; + /* only used by testsrc2 */ + int alpha; + /* only used by color */ FFDrawContext draw; FFDrawColor color; @@ -685,6 +688,7 @@ AVFilter ff_vsrc_testsrc = { static const AVOption testsrc2_options[] = { COMMON_OPTIONS + { "alpha", "set global alpha (opacity)", OFFSET(alpha), AV_OPT_TYPE_INT, {.i64 = 255}, 0, 255, FLAGS }, { NULL } }; @@ -735,6 +739,7 @@ static void test2_fill_picture(AVFilterContext *ctx, AVFrame *frame) { TestSourceContext *s = ctx->priv; FFDrawColor color; + unsigned alpha = (uint32_t)s->alpha << 24; /* colored background */ { @@ -746,7 +751,8 @@ static void test2_fill_picture(AVFilterContext *ctx, AVFrame *frame) x2 = ff_draw_round_to_sub(&s->draw, 0, 0, x2); set_color(s, &color, ((i & 1) ? 0xFF0000 : 0) | ((i & 2) ? 0x00FF00 : 0) | - ((i & 4) ? 0x0000FF : 0)); + ((i & 4) ? 0x0000FF : 0) | + alpha); ff_fill_rectangle(&s->draw, &color, frame->data, frame->linesize, x, 0, x2 - x, frame->height); x = x2; @@ -763,7 +769,7 @@ static void test2_fill_picture(AVFilterContext *ctx, AVFrame *frame) g0 = av_rescale_q(s->pts, s->time_base, av_make_q(1, 128)); for (x = 0; x < s->w; x += dx) { g = (av_rescale(x, 6 * 256, s->w) + g0) % (6 * 256); - set_color(s, &color, color_gradient(g)); + set_color(s, &color, color_gradient(g) | alpha); y = y0 + av_rescale(x, s->h / 2, s->w); y %= 2 * (s->h - 16); if (y > s->h - 16) @@ -785,7 +791,7 @@ static void test2_fill_picture(AVFilterContext *ctx, AVFrame *frame) int c, i; for (c = 0; c < 3; c++) { - set_color(s, &color, 0xBBBBBB ^ (0xFF << (c << 3))); + set_color(s, &color, (0xBBBBBB ^ (0xFF << (c << 3))) | alpha); pos = av_rescale_q(s->pts, s->time_base, av_make_q(64 >> (c << 1), cycle)) % cycle; xh = pos < 1 * l ? pos : pos < 2 * l ? l : From 24de4fddcad9ae7ee598ff5984e013af14f10c2f Mon Sep 17 00:00:00 2001 From: Rostislav Pehlivanov Date: Thu, 20 Jul 2017 21:46:21 +0100 Subject: [PATCH 2633/3374] lavu/frame: add new side data type for ICC profiles Many image formats support embedding of ICC profiles directly in their bitstreams. Add a new side data type to allow exposing them to API users. Signed-off-by: Rostislav Pehlivanov --- libavutil/frame.h | 7 +++++++ libavutil/version.h | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/libavutil/frame.h b/libavutil/frame.h index 26261d7e40ba7..5a987a1dfa103 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -134,6 +134,13 @@ enum AVFrameSideDataType { * the form of the AVContentLightMetadata struct. */ AV_FRAME_DATA_CONTENT_LIGHT_LEVEL, + + /** + * The data contains an ICC profile as an opaque octet buffer following the + * format described by ISO 15076-1 with an optional name defined in the + * metadata key entry "name". + */ + AV_FRAME_DATA_ICC_PROFILE, }; enum AVActiveFormatDescription { diff --git a/libavutil/version.h b/libavutil/version.h index d4f9335a2fdea..35987e7b5007c 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -80,7 +80,7 @@ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 68 +#define LIBAVUTIL_VERSION_MINOR 69 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From 2e08bbb282109d731194019967dc66ed7b966cb6 Mon Sep 17 00:00:00 2001 From: Rostislav Pehlivanov Date: Thu, 20 Jul 2017 21:46:22 +0100 Subject: [PATCH 2634/3374] pngdec: decode and expose iCCP chunks as side data Signed-off-by: Rostislav Pehlivanov --- libavcodec/pngdec.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index 083f61f4f802f..f83884dfc2224 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -836,6 +836,46 @@ static int decode_trns_chunk(AVCodecContext *avctx, PNGDecContext *s, return 0; } +static int decode_iccp_chunk(PNGDecContext *s, int length, AVFrame *f) +{ + int ret, cnt = 0; + uint8_t *data, profile_name[82]; + AVBPrint bp; + AVFrameSideData *sd; + + while ((profile_name[cnt++] = bytestream2_get_byte(&s->gb)) && cnt < 81); + if (cnt > 80) { + av_log(s->avctx, AV_LOG_ERROR, "iCCP with invalid name!\n"); + return AVERROR_INVALIDDATA; + } + + length = FFMAX(length - cnt, 0); + + if (bytestream2_get_byte(&s->gb) != 0) { + av_log(s->avctx, AV_LOG_ERROR, "iCCP with invalid compression!\n"); + return AVERROR_INVALIDDATA; + } + + length = FFMAX(length - 1, 0); + + if ((ret = decode_zbuf(&bp, s->gb.buffer, s->gb.buffer + length) < 0)) + return ret; + + av_bprint_finalize(&bp, (char **)&data); + + if (!(sd = av_frame_new_side_data(f, AV_FRAME_DATA_ICC_PROFILE, bp.len))) + return AVERROR(ENOMEM); + + av_dict_set(&sd->metadata, "name", profile_name, 0); + memcpy(sd->data, data, bp.len); + av_free(data); + + /* ICC compressed data and CRC */ + bytestream2_skip(&s->gb, length + 4); + + return 0; +} + static void handle_small_bpp(PNGDecContext *s, AVFrame *p) { if (s->bits_per_pixel == 1 && s->color_type == PNG_COLOR_TYPE_PALETTE) { @@ -1239,6 +1279,11 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, bytestream2_skip(&s->gb, 4); /* crc */ break; } + case MKTAG('i', 'C', 'C', 'P'): { + if (decode_iccp_chunk(s, length, p) < 0) + goto fail; + break; + } case MKTAG('I', 'E', 'N', 'D'): if (!(s->pic_state & PNG_ALLIMAGE)) av_log(avctx, AV_LOG_ERROR, "IEND without all image\n"); From 0563a5d175428943c741be2d18ac6010b868fc91 Mon Sep 17 00:00:00 2001 From: Rostislav Pehlivanov Date: Tue, 25 Jul 2017 04:31:48 +0100 Subject: [PATCH 2635/3374] mdct15: simplify prereindexing and forward transform postrotation Equivalent. Signed-off-by: Rostislav Pehlivanov --- libavcodec/mdct15.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/libavcodec/mdct15.c b/libavcodec/mdct15.c index cc7d83316546b..d68372c3443ab 100644 --- a/libavcodec/mdct15.c +++ b/libavcodec/mdct15.c @@ -80,7 +80,7 @@ static inline int init_pfa_reindex_tabs(MDCT15Context *s) const int q_post = (((j*inv_1)/15) + (i*inv_2)) >> b_ptwo; const int k_pre = 15*i + (j - q_pre*15)*(1 << b_ptwo); const int k_post = i*inv_2*15 + j*inv_1 - 15*q_post*l_ptwo; - s->pfa_prereindex[i*15 + j] = k_pre; + s->pfa_prereindex[i*15 + j] = k_pre << 1; s->pfa_postreindex[k_post] = l_ptwo*j + i; } } @@ -173,16 +173,16 @@ static void mdct15(MDCT15Context *s, float *dst, const float *src, ptrdiff_t str /* Folding and pre-reindexing */ for (i = 0; i < l_ptwo; i++) { for (j = 0; j < 15; j++) { - float re, im; const int k = s->pfa_prereindex[i*15 + j]; - if (k < len8) { - re = -src[2*k+len3] - src[len3-1-2*k]; - im = -src[len4+2*k] + src[len4-1-2*k]; + FFTComplex tmp, exp = s->twiddle_exptab[k >> 1]; + if (k < len4) { + tmp.re = -src[ len4 + k] + src[1*len4 - 1 - k]; + tmp.im = -src[ len3 + k] - src[1*len3 - 1 - k]; } else { - re = src[2*k-len4] - src[1*len3-1-2*k]; - im = -src[2*k+len4] - src[5*len4-1-2*k]; + tmp.re = -src[ len4 + k] - src[5*len4 - 1 - k]; + tmp.im = src[-len4 + k] - src[1*len3 - 1 - k]; } - CMUL(fft15in[j].re, fft15in[j].im, re, im, s->twiddle_exptab[k].re, -s->twiddle_exptab[k].im); + CMUL(fft15in[j].im, fft15in[j].re, tmp.re, tmp.im, exp.re, exp.im); } s->fft15(s->tmp + s->ptwo_fft.revtab[i], fft15in, s->exptab, l_ptwo); } @@ -193,16 +193,13 @@ static void mdct15(MDCT15Context *s, float *dst, const float *src, ptrdiff_t str /* Reindex again, apply twiddles and output */ for (i = 0; i < len8; i++) { - float re0, im0, re1, im1; const int i0 = len8 + i, i1 = len8 - i - 1; const int s0 = s->pfa_postreindex[i0], s1 = s->pfa_postreindex[i1]; - CMUL(im1, re0, s->tmp[s1].re, s->tmp[s1].im, s->twiddle_exptab[i1].im, s->twiddle_exptab[i1].re); - CMUL(im0, re1, s->tmp[s0].re, s->tmp[s0].im, s->twiddle_exptab[i0].im, s->twiddle_exptab[i0].re); - dst[2*i1*stride ] = re0; - dst[2*i1*stride + stride] = im0; - dst[2*i0*stride ] = re1; - dst[2*i0*stride + stride] = im1; + CMUL(dst[2*i1*stride + stride], dst[2*i0*stride], s->tmp[s0].re, s->tmp[s0].im, + s->twiddle_exptab[i0].im, s->twiddle_exptab[i0].re); + CMUL(dst[2*i0*stride + stride], dst[2*i1*stride], s->tmp[s1].re, s->tmp[s1].im, + s->twiddle_exptab[i1].im, s->twiddle_exptab[i1].re); } } @@ -218,8 +215,8 @@ static void imdct15_half(MDCT15Context *s, float *dst, const float *src, for (i = 0; i < l_ptwo; i++) { for (j = 0; j < 15; j++) { const int k = s->pfa_prereindex[i*15 + j]; - FFTComplex tmp = { *(in2 - 2*k*stride), *(in1 + 2*k*stride) }; - CMUL3(fft15in[j], tmp, s->twiddle_exptab[k]); + FFTComplex tmp = { in2[-k*stride], in1[k*stride] }; + CMUL3(fft15in[j], tmp, s->twiddle_exptab[k >> 1]); } s->fft15(s->tmp + s->ptwo_fft.revtab[i], fft15in, s->exptab, l_ptwo); } @@ -233,8 +230,10 @@ static void imdct15_half(MDCT15Context *s, float *dst, const float *src, const int i0 = len8 + i, i1 = len8 - i - 1; const int s0 = s->pfa_postreindex[i0], s1 = s->pfa_postreindex[i1]; - CMUL(z[i1].re, z[i0].im, s->tmp[s1].im, s->tmp[s1].re, s->twiddle_exptab[i1].im, s->twiddle_exptab[i1].re); - CMUL(z[i0].re, z[i1].im, s->tmp[s0].im, s->tmp[s0].re, s->twiddle_exptab[i0].im, s->twiddle_exptab[i0].re); + CMUL(z[i1].re, z[i0].im, s->tmp[s1].im, s->tmp[s1].re, + s->twiddle_exptab[i1].im, s->twiddle_exptab[i1].re); + CMUL(z[i0].re, z[i1].im, s->tmp[s0].im, s->tmp[s0].re, + s->twiddle_exptab[i0].im, s->twiddle_exptab[i0].re); } } From a776cb2074484f4c07ddcdc03398879d9587edcd Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Mon, 24 Jul 2017 18:11:53 +0530 Subject: [PATCH 2636/3374] libavcodec/mips: Optimize avc idct 4x4 for msa Removed memset call and improved performance. Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/h264idct_msa.c | 104 +++++++++++++++------------- libavutil/mips/generic_macros_msa.h | 18 +++++ 2 files changed, 74 insertions(+), 48 deletions(-) diff --git a/libavcodec/mips/h264idct_msa.c b/libavcodec/mips/h264idct_msa.c index fac1e7add41b1..81e09e9b1657b 100644 --- a/libavcodec/mips/h264idct_msa.c +++ b/libavcodec/mips/h264idct_msa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com) + * Copyright (c) 2015 - 2017 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com) * * This file is part of FFmpeg. * @@ -36,48 +36,6 @@ BUTTERFLY_4(tmp0_m, tmp1_m, tmp2_m, tmp3_m, out0, out1, out2, out3); \ } -static void avc_idct4x4_addblk_msa(uint8_t *dst, int16_t *src, - int32_t dst_stride) -{ - v8i16 src0, src1, src2, src3; - v8i16 hres0, hres1, hres2, hres3; - v8i16 vres0, vres1, vres2, vres3; - v8i16 zeros = { 0 }; - - LD4x4_SH(src, src0, src1, src2, src3); - AVC_ITRANS_H(src0, src1, src2, src3, hres0, hres1, hres2, hres3); - TRANSPOSE4x4_SH_SH(hres0, hres1, hres2, hres3, hres0, hres1, hres2, hres3); - AVC_ITRANS_H(hres0, hres1, hres2, hres3, vres0, vres1, vres2, vres3); - SRARI_H4_SH(vres0, vres1, vres2, vres3, 6); - ADDBLK_ST4x4_UB(vres0, vres1, vres2, vres3, dst, dst_stride); - ST_SH2(zeros, zeros, src, 8); -} - -static void avc_idct4x4_addblk_dc_msa(uint8_t *dst, int16_t *src, - int32_t dst_stride) -{ - int16_t dc; - uint32_t src0, src1, src2, src3; - v16u8 pred = { 0 }; - v16i8 out; - v8i16 input_dc, pred_r, pred_l; - - dc = (src[0] + 32) >> 6; - input_dc = __msa_fill_h(dc); - src[0] = 0; - - LW4(dst, dst_stride, src0, src1, src2, src3); - INSERT_W4_UB(src0, src1, src2, src3, pred); - UNPCK_UB_SH(pred, pred_r, pred_l); - - pred_r += input_dc; - pred_l += input_dc; - - CLIP_SH2_0_255(pred_r, pred_l); - out = __msa_pckev_b((v16i8) pred_l, (v16i8) pred_r); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); -} - static void avc_deq_idct_luma_dc_msa(int16_t *dst, int16_t *src, int32_t de_q_val) { @@ -317,11 +275,45 @@ static void avc_idct8_dc_addblk_msa(uint8_t *dst, int16_t *src, ST8x4_UB(dst2, dst3, dst, dst_stride); } -void ff_h264_idct_add_msa(uint8_t *dst, int16_t *src, - int32_t dst_stride) +void ff_h264_idct_add_msa(uint8_t *dst, int16_t *src, int32_t dst_stride) { - avc_idct4x4_addblk_msa(dst, src, dst_stride); - memset(src, 0, 16 * sizeof(dctcoef)); + uint32_t src0_m, src1_m, src2_m, src3_m, out0_m, out1_m, out2_m, out3_m; + v16i8 dst0_m = { 0 }; + v16i8 dst1_m = { 0 }; + v8i16 hres0, hres1, hres2, hres3, vres0, vres1, vres2, vres3; + v8i16 inp0_m, inp1_m, res0_m, res1_m, src1, src3; + const v8i16 src0 = LD_SH(src); + const v8i16 src2 = LD_SH(src + 8); + const v8i16 zero = { 0 }; + const uint8_t *dst1 = dst + dst_stride; + const uint8_t *dst2 = dst + 2 * dst_stride; + const uint8_t *dst3 = dst + 3 * dst_stride; + + ILVL_D2_SH(src0, src0, src2, src2, src1, src3); + ST_SH2(zero, zero, src, 8); + AVC_ITRANS_H(src0, src1, src2, src3, hres0, hres1, hres2, hres3); + TRANSPOSE4x4_SH_SH(hres0, hres1, hres2, hres3, hres0, hres1, hres2, hres3); + AVC_ITRANS_H(hres0, hres1, hres2, hres3, vres0, vres1, vres2, vres3); + src0_m = LW(dst); + src1_m = LW(dst1); + SRARI_H4_SH(vres0, vres1, vres2, vres3, 6); + src2_m = LW(dst2); + src3_m = LW(dst3); + ILVR_D2_SH(vres1, vres0, vres3, vres2, inp0_m, inp1_m); + INSERT_W2_SB(src0_m, src1_m, dst0_m); + INSERT_W2_SB(src2_m, src3_m, dst1_m); + ILVR_B2_SH(zero, dst0_m, zero, dst1_m, res0_m, res1_m); + ADD2(res0_m, inp0_m, res1_m, inp1_m, res0_m, res1_m); + CLIP_SH2_0_255(res0_m, res1_m); + PCKEV_B2_SB(res0_m, res0_m, res1_m, res1_m, dst0_m, dst1_m); + out0_m = __msa_copy_u_w((v4i32) dst0_m, 0); + out1_m = __msa_copy_u_w((v4i32) dst0_m, 1); + out2_m = __msa_copy_u_w((v4i32) dst1_m, 0); + out3_m = __msa_copy_u_w((v4i32) dst1_m, 1); + SW(out0_m, dst); + SW(out1_m, dst1); + SW(out2_m, dst2); + SW(out3_m, dst3); } void ff_h264_idct8_addblk_msa(uint8_t *dst, int16_t *src, @@ -334,7 +326,23 @@ void ff_h264_idct8_addblk_msa(uint8_t *dst, int16_t *src, void ff_h264_idct4x4_addblk_dc_msa(uint8_t *dst, int16_t *src, int32_t dst_stride) { - avc_idct4x4_addblk_dc_msa(dst, src, dst_stride); + v16u8 pred = { 0 }; + v16i8 out; + v8i16 pred_r, pred_l; + const uint32_t src0 = LW(dst); + const uint32_t src1 = LW(dst + dst_stride); + const uint32_t src2 = LW(dst + 2 * dst_stride); + const uint32_t src3 = LW(dst + 3 * dst_stride); + const int16_t dc = (src[0] + 32) >> 6; + const v8i16 input_dc = __msa_fill_h(dc); + + src[0] = 0; + INSERT_W4_UB(src0, src1, src2, src3, pred); + UNPCK_UB_SH(pred, pred_r, pred_l); + ADD2(pred_r, input_dc, pred_l, input_dc, pred_r, pred_l); + CLIP_SH2_0_255(pred_r, pred_l); + out = __msa_pckev_b((v16i8) pred_l, (v16i8) pred_r); + ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); } void ff_h264_idct8_dc_addblk_msa(uint8_t *dst, int16_t *src, diff --git a/libavutil/mips/generic_macros_msa.h b/libavutil/mips/generic_macros_msa.h index 61a8ee0e5426e..407d46e616a91 100644 --- a/libavutil/mips/generic_macros_msa.h +++ b/libavutil/mips/generic_macros_msa.h @@ -1531,6 +1531,24 @@ #define ILVR_D4_SB(...) ILVR_D4(v16i8, __VA_ARGS__) #define ILVR_D4_UB(...) ILVR_D4(v16u8, __VA_ARGS__) +/* Description : Interleave left half of double word elements from vectors + Arguments : Inputs - in0, in1, in2, in3 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Left half of double word elements of in0 and left half of + double word elements of in1 are interleaved and copied to out0. + Left half of double word elements of in2 and left half of + double word elements of in3 are interleaved and copied to out1. +*/ +#define ILVL_D2(RTYPE, in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_ilvl_d((v2i64) in0, (v2i64) in1); \ + out1 = (RTYPE) __msa_ilvl_d((v2i64) in2, (v2i64) in3); \ +} +#define ILVL_D2_UB(...) ILVL_D2(v16u8, __VA_ARGS__) +#define ILVL_D2_SB(...) ILVL_D2(v16i8, __VA_ARGS__) +#define ILVL_D2_SH(...) ILVL_D2(v8i16, __VA_ARGS__) + /* Description : Interleave both left and right half of input vectors Arguments : Inputs - in0, in1 Outputs - out0, out1 From 7140761481e4296723a592019a0244ebe6c1a8cf Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 25 Jul 2017 03:19:07 +0200 Subject: [PATCH 2637/3374] avformat/oggparsecelt: Do not re-allocate os->private Fixes: double free Fixes: clusterfuzz-testcase-minimized-5080550145785856 Found-by: ClusterFuzz Reviewed-by: Nicolas George Signed-off-by: Michael Niedermayer --- libavformat/oggparsecelt.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libavformat/oggparsecelt.c b/libavformat/oggparsecelt.c index 6d567f988a307..9c438a096ae3d 100644 --- a/libavformat/oggparsecelt.c +++ b/libavformat/oggparsecelt.c @@ -65,9 +65,14 @@ static int celt_header(AVFormatContext *s, int idx) st->codecpar->channels = nb_channels; if (sample_rate) avpriv_set_pts_info(st, 64, 1, sample_rate); - priv->extra_headers_left = 1 + extra_headers; - av_free(os->private); + + if (os->private) { + av_free(priv); + priv = os->private; + } os->private = priv; + priv->extra_headers_left = 1 + extra_headers; + AV_WL32(st->codecpar->extradata + 0, overlap); AV_WL32(st->codecpar->extradata + 4, version); return 1; From c8305079dae1044d7e6d978ec3251176464fb5f6 Mon Sep 17 00:00:00 2001 From: Muhammad Faiz Date: Sat, 22 Jul 2017 06:52:45 +0700 Subject: [PATCH 2638/3374] avcodec/rdft: reorder calculation old: 165188 decicycles in rdft, 65536 runs, 0 skips 165865 decicycles in irdft, 65536 runs, 0 skips new: 142487 decicycles in rdft, 65536 runs, 0 skips 141498 decicycles in irdft, 65536 runs, 0 skips Signed-off-by: Muhammad Faiz --- libavcodec/rdft.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/libavcodec/rdft.c b/libavcodec/rdft.c index 194e0bc4ee13b..6ba7484238536 100644 --- a/libavcodec/rdft.c +++ b/libavcodec/rdft.c @@ -35,7 +35,7 @@ static void rdft_calc_c(RDFTContext *s, FFTSample *data) { int i, i1, i2; - FFTComplex ev, od; + FFTComplex ev, od, odsum; const int n = 1 << s->nbits; const float k1 = 0.5; const float k2 = 0.5 - s->inverse; @@ -58,14 +58,16 @@ static void rdft_calc_c(RDFTContext *s, FFTSample *data) i2 = n-i1; \ /* Separate even and odd FFTs */ \ ev.re = k1*(data[i1 ]+data[i2 ]); \ - od.im = -k2*(data[i1 ]-data[i2 ]); \ + od.im = k2*(data[i2 ]-data[i1 ]); \ ev.im = k1*(data[i1+1]-data[i2+1]); \ od.re = k2*(data[i1+1]+data[i2+1]); \ /* Apply twiddle factors to the odd FFT and add to the even FFT */ \ - data[i1 ] = ev.re + od.re*tcos[i] sign0 od.im*tsin[i]; \ - data[i1+1] = ev.im + od.im*tcos[i] sign1 od.re*tsin[i]; \ - data[i2 ] = ev.re - od.re*tcos[i] sign1 od.im*tsin[i]; \ - data[i2+1] = -ev.im + od.im*tcos[i] sign1 od.re*tsin[i]; \ + odsum.re = od.re*tcos[i] sign0 od.im*tsin[i]; \ + odsum.im = od.im*tcos[i] sign1 od.re*tsin[i]; \ + data[i1 ] = ev.re + odsum.re; \ + data[i1+1] = ev.im + odsum.im; \ + data[i2 ] = ev.re - odsum.re; \ + data[i2+1] = odsum.im - ev.im; \ } if (s->negative_sin) { From 4cebf0fc456ceb4f8c4f328b2fe849bd7e8a1c4a Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 26 Jul 2017 00:38:22 -0300 Subject: [PATCH 2639/3374] avutil/frame: add ICC Profile to av_frame_side_data_name Reviwed-by: Rostislav Pehlivanov Signed-off-by: James Almer --- libavutil/frame.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavutil/frame.c b/libavutil/frame.c index 24d5d5f1849b6..1f2b2356fc10a 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -778,6 +778,7 @@ const char *av_frame_side_data_name(enum AVFrameSideDataType type) case AV_FRAME_DATA_MASTERING_DISPLAY_METADATA: return "Mastering display metadata"; case AV_FRAME_DATA_CONTENT_LIGHT_LEVEL: return "Content light level metadata"; case AV_FRAME_DATA_GOP_TIMECODE: return "GOP timecode"; + case AV_FRAME_DATA_ICC_PROFILE: return "ICC profile"; } return NULL; } From 5e4e9afaa127acbfa9ac445a8572b49dadb68b17 Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 26 Jul 2017 00:42:51 -0300 Subject: [PATCH 2640/3374] ffprobe: add support for ICC Profile frame side data Print the name metadata entry and the buffer size. Reviwed-by: Rostislav Pehlivanov Signed-off-by: James Almer --- ffprobe.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ffprobe.c b/ffprobe.c index 3d9f795d2eda4..f22c4f57ade5f 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -2190,6 +2190,11 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream, AVContentLightMetadata *metadata = (AVContentLightMetadata *)sd->data; print_int("max_content", metadata->MaxCLL); print_int("max_average", metadata->MaxFALL); + } else if (sd->type == AV_FRAME_DATA_ICC_PROFILE) { + AVDictionaryEntry *tag = av_dict_get(sd->metadata, "name", NULL, AV_DICT_MATCH_CASE); + if (tag) + print_str(tag->key, tag->value); + print_int("size", sd->size); } writer_print_section_footer(w); } From c220fe008c5a3f7c652dbd03ce2a58e392e59e19 Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 26 Jul 2017 01:28:35 -0300 Subject: [PATCH 2641/3374] avcodec/webp: add support for ICCP chunks Export the raw data as ICC Profile frame side data. Reviwed-by: Rostislav Pehlivanov Signed-off-by: James Almer --- libavcodec/webp.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/libavcodec/webp.c b/libavcodec/webp.c index a0d4d1812d94a..efa864a6f141d 100644 --- a/libavcodec/webp.c +++ b/libavcodec/webp.c @@ -33,10 +33,10 @@ * * @author James Almer * Exif metadata + * ICC profile * * Unimplemented: * - Animation - * - ICC profile * - XMP metadata */ @@ -197,6 +197,7 @@ typedef struct WebPContext { uint8_t *alpha_data; /* alpha chunk data */ int alpha_data_size; /* alpha chunk data size */ int has_exif; /* set after an EXIF chunk has been processed */ + int has_iccp; /* set after an ICCP chunk has been processed */ int width; /* image width */ int height; /* image height */ int lossless; /* indicates lossless or lossy */ @@ -1381,6 +1382,7 @@ static int webp_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, *got_frame = 0; s->has_alpha = 0; s->has_exif = 0; + s->has_iccp = 0; bytestream2_init(&gb, avpkt->data, avpkt->size); if (bytestream2_get_bytes_left(&gb) < 12) @@ -1514,7 +1516,27 @@ static int webp_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, bytestream2_skip(&gb, chunk_size); break; } - case MKTAG('I', 'C', 'C', 'P'): + case MKTAG('I', 'C', 'C', 'P'): { + AVFrameSideData *sd; + + if (s->has_iccp) { + av_log(avctx, AV_LOG_VERBOSE, "Ignoring extra ICCP chunk\n"); + bytestream2_skip(&gb, chunk_size); + break; + } + if (!(vp8x_flags & VP8X_FLAG_ICC)) + av_log(avctx, AV_LOG_WARNING, + "ICCP chunk present, but ICC Profile bit not set in the " + "VP8X header\n"); + + s->has_iccp = 1; + sd = av_frame_new_side_data(p, AV_FRAME_DATA_ICC_PROFILE, chunk_size); + if (!sd) + return AVERROR(ENOMEM); + + bytestream2_get_buffer(&gb, sd->data, chunk_size); + break; + } case MKTAG('A', 'N', 'I', 'M'): case MKTAG('A', 'N', 'M', 'F'): case MKTAG('X', 'M', 'P', ' '): From 74c1c22d7f0d25f527ed2ebf62493be5ad52c972 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 24 Jul 2017 15:48:37 +0200 Subject: [PATCH 2642/3374] avcodec/hevc_ps: fix integer overflow in log2_parallel_merge_level_minus2 Fixes: runtime error: signed integer overflow: -2147483647 - 2 cannot be represented in type 'int' Fixes: 2702/clusterfuzz-testcase-minimized-4511932591636480 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/hevc_ps.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index 7358b318b0c72..21dbaf85a5faf 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -1432,6 +1432,7 @@ int ff_hevc_decode_nal_pps(GetBitContext *gb, AVCodecContext *avctx, int i, ret = 0; unsigned int pps_id = 0; ptrdiff_t nal_size; + unsigned log2_parallel_merge_level_minus2; AVBufferRef *pps_buf; HEVCPPS *pps = av_mallocz(sizeof(*pps)); @@ -1629,13 +1630,14 @@ int ff_hevc_decode_nal_pps(GetBitContext *gb, AVCodecContext *avctx, goto err; } pps->lists_modification_present_flag = get_bits1(gb); - pps->log2_parallel_merge_level = get_ue_golomb_long(gb) + 2; - if (pps->log2_parallel_merge_level > sps->log2_ctb_size) { + log2_parallel_merge_level_minus2 = get_ue_golomb_long(gb); + if (log2_parallel_merge_level_minus2 > sps->log2_ctb_size) { av_log(avctx, AV_LOG_ERROR, "log2_parallel_merge_level_minus2 out of range: %d\n", - pps->log2_parallel_merge_level - 2); + log2_parallel_merge_level_minus2); ret = AVERROR_INVALIDDATA; goto err; } + pps->log2_parallel_merge_level = log2_parallel_merge_level_minus2 + 2; pps->slice_header_extension_present_flag = get_bits1(gb); From 1b00600319506a9bd81b114d2b374051dc1a29a6 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 24 Jul 2017 16:43:24 +0200 Subject: [PATCH 2643/3374] avcodec/jpeg2000dec: Fix division by zero in jp2_find_codestream() Fixes: 2707/clusterfuzz-testcase-minimized-5179636394754048 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/jpeg2000dec.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index b67efc76bb646..dd9c60feb4521 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -2075,6 +2075,11 @@ static int jp2_find_codestream(Jpeg2000DecoderContext *s) hden = bytestream2_get_be16u(&s->g); vexp = bytestream2_get_byteu(&s->g); hexp = bytestream2_get_byteu(&s->g); + if (!vnum || !vden || !hnum || !vden) { + bytestream2_seek(&s->g, atom2_end, SEEK_SET); + av_log(s->avctx, AV_LOG_WARNING, "RES box invalid\n"); + continue; + } if (vexp > hexp) { vexp -= hexp; hexp = 0; From 2ba20d799ad25650e8fb400e0d0a33782394accf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 26 Jul 2017 19:56:28 +0200 Subject: [PATCH 2644/3374] lavc/htmlsubtitles: simplify 1-char tags case insensitive test --- libavcodec/htmlsubtitles.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/htmlsubtitles.c b/libavcodec/htmlsubtitles.c index e6bac713c160d..e1fb7bc3cf0d1 100644 --- a/libavcodec/htmlsubtitles.c +++ b/libavcodec/htmlsubtitles.c @@ -165,7 +165,7 @@ int ff_htmlmarkup_to_ass(void *log_ctx, AVBPrint *dst, const char *in) if (stack[sptr].param[i][0]) av_bprintf(dst, "%s", stack[sptr].param[i]); } - } else if (tagname[0] && !tagname[1] && av_stristr("bisu", tagname)) { + } else if (tagname[0] && !tagname[1] && strchr("bisu", av_tolower(tagname[0]))) { av_bprintf(dst, "{\\%c%d}", (char)av_tolower(tagname[0]), !tag_close); } else if (!av_strcasecmp(tagname, "br")) { av_bprintf(dst, "\\N"); From 56277f6d1905af033d58588c631956dcb19fdf7a Mon Sep 17 00:00:00 2001 From: foo86 Date: Sat, 22 Jul 2017 17:13:04 +0300 Subject: [PATCH 2645/3374] avcodec/dolby_e: add 'f' suffixes to floating point literals --- libavcodec/dolby_e.h | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/libavcodec/dolby_e.h b/libavcodec/dolby_e.h index 055e1121cfbcc..0390233720e1b 100644 --- a/libavcodec/dolby_e.h +++ b/libavcodec/dolby_e.h @@ -649,30 +649,30 @@ static av_cold void init_tables(void) int i, j; for (i = 1; i < 17; i++) - mantissa_tab1[i][0] = 1.0 / (1 << i - 1); + mantissa_tab1[i][0] = 1.0f / (1 << i - 1); for (i = 2; i < 16; i++) { - mantissa_tab1[i][1] = 1.0 / ((1 << i) - 1); - mantissa_tab1[i][2] = 0.5 / ((1 << i) - 1); - mantissa_tab1[i][3] = 0.25 / ((1 << i) - 1); + mantissa_tab1[i][1] = 1.0f / ((1 << i) - 1); + mantissa_tab1[i][2] = 0.5f / ((1 << i) - 1); + mantissa_tab1[i][3] = 0.25f / ((1 << i) - 1); } - mantissa_tab1[i][1] = 0.5 / (1 << 15); - mantissa_tab1[i][2] = 0.75 / (1 << 15); - mantissa_tab1[i][3] = 0.875 / (1 << 15); + mantissa_tab1[i][1] = 0.5f / (1 << 15); + mantissa_tab1[i][2] = 0.75f / (1 << 15); + mantissa_tab1[i][3] = 0.875f / (1 << 15); for (i = 1; i < 17; i++) { - mantissa_tab2[i][1] = mantissa_tab1[i][0] * 0.5; - mantissa_tab2[i][2] = mantissa_tab1[i][0] * 0.75; - mantissa_tab2[i][3] = mantissa_tab1[i][0] * 0.875; + mantissa_tab2[i][1] = mantissa_tab1[i][0] * 0.5f; + mantissa_tab2[i][2] = mantissa_tab1[i][0] * 0.75f; + mantissa_tab2[i][3] = mantissa_tab1[i][0] * 0.875f; for (j = 1; j < 4; j++) - mantissa_tab3[i][j] = 1.0 / (1 << i) + 1.0 / (1 << j) - 1.0 / (1 << i + j); + mantissa_tab3[i][j] = 1.0f / (1 << i) + 1.0f / (1 << j) - 1.0f / (1 << i + j); } - mantissa_tab3[1][3] = 0.6875; + mantissa_tab3[1][3] = 0.6875f; for (i = 0; i < 25; i++) { - exponent_tab[i * 2 ] = 1.0 / (1 << i); + exponent_tab[i * 2 ] = 1.0f / (1 << i); exponent_tab[i * 2 + 1] = M_SQRT1_2 / (1 << i); } @@ -680,7 +680,7 @@ static av_cold void init_tables(void) gain_tab[i] = exp2f((i - 960) / 64.0f); // short 1 - ff_kbd_window_init(window, 3.0, 128); + ff_kbd_window_init(window, 3.0f, 128); for (i = 0; i < 128; i++) window[128 + i] = window[127 - i]; @@ -704,12 +704,12 @@ static av_cold void init_tables(void) for (i = 0; i < 128; i++) window[960 + i] = window[i]; for (i = 0; i < 64; i++) - window[1088 + i] = 1.0; + window[1088 + i] = 1.0f; // long - ff_kbd_window_init(window + 1408, 3.0, 256); + ff_kbd_window_init(window + 1408, 3.0f, 256); for (i = 0; i < 640; i++) - window[1664 + i] = 1.0; + window[1664 + i] = 1.0f; for (i = 0; i < 256; i++) window[2304 + i] = window[1152 + i] = window[1663 - i]; From 0689cc2475557339a00240d05b7fc4fcb70e21cd Mon Sep 17 00:00:00 2001 From: foo86 Date: Sat, 22 Jul 2017 17:18:47 +0300 Subject: [PATCH 2646/3374] avcodec/dolby_e: add AV_CODEC_CAP_CHANNEL_CONF capability --- libavcodec/dolby_e.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/dolby_e.c b/libavcodec/dolby_e.c index 6f390d959f168..f811db4d8e84a 100644 --- a/libavcodec/dolby_e.c +++ b/libavcodec/dolby_e.c @@ -701,7 +701,7 @@ AVCodec ff_dolby_e_decoder = { .decode = dolby_e_decode_frame, .close = dolby_e_close, .flush = dolby_e_flush, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; From 5e715b583dab85735660b15a8d217a69164675fe Mon Sep 17 00:00:00 2001 From: foo86 Date: Sat, 22 Jul 2017 17:19:25 +0300 Subject: [PATCH 2647/3374] avcodec/dolby_e: fix potentially undefined pointer arithmetic Avoid undefined behavior in skip_input() by checking that enough data is available before incrementing input pointer. Check return values of parse_key() and skip_input() and exit early with error if there is not enough data. --- libavcodec/dolby_e.c | 45 +++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/libavcodec/dolby_e.c b/libavcodec/dolby_e.c index f811db4d8e84a..91a00ce87851c 100644 --- a/libavcodec/dolby_e.c +++ b/libavcodec/dolby_e.c @@ -28,21 +28,28 @@ #include "dolby_e.h" #include "fft.h" -static void skip_input(DBEContext *s, int nb_words) +static int skip_input(DBEContext *s, int nb_words) { + if (nb_words > s->input_size) { + av_log(s->avctx, AV_LOG_ERROR, "Packet too short\n"); + return AVERROR_INVALIDDATA; + } + s->input += nb_words * s->word_bytes; s->input_size -= nb_words; + return 0; } static int parse_key(DBEContext *s) { - int key = 0; - - if (s->key_present && s->input_size > 0) - key = AV_RB24(s->input) >> 24 - s->word_bits; - - skip_input(s, s->key_present); - return key; + if (s->key_present) { + uint8_t *key = s->input; + int ret = skip_input(s, 1); + if (ret < 0) + return ret; + return AV_RB24(key) >> 24 - s->word_bits; + } + return 0; } static int convert_input(DBEContext *s, int nb_words, int key) @@ -83,8 +90,10 @@ static int convert_input(DBEContext *s, int nb_words, int key) static int parse_metadata(DBEContext *s) { - int i, ret, key = parse_key(s), mtd_size; + int i, ret, key, mtd_size; + if ((key = parse_key(s)) < 0) + return key; if ((ret = convert_input(s, 1, key)) < 0) return ret; @@ -135,14 +144,13 @@ static int parse_metadata(DBEContext *s) return AVERROR_INVALIDDATA; } - skip_input(s, mtd_size + 1); - return 0; + return skip_input(s, mtd_size + 1); } static int parse_metadata_ext(DBEContext *s) { if (s->mtd_ext_size) - skip_input(s, s->key_present + s->mtd_ext_size + 1); + return skip_input(s, s->key_present + s->mtd_ext_size + 1); return 0; } @@ -455,7 +463,10 @@ static int parse_channel(DBEContext *s, int ch, int seg_id) static int parse_audio(DBEContext *s, int start, int end, int seg_id) { - int ch, ret, key = parse_key(s); + int ch, ret, key; + + if ((key = parse_key(s)) < 0) + return key; for (ch = start; ch < end; ch++) { if (!s->ch_size[ch]) { @@ -469,17 +480,17 @@ static int parse_audio(DBEContext *s, int start, int end, int seg_id) return ret; s->channels[seg_id][ch].nb_groups = 0; } - skip_input(s, s->ch_size[ch]); + if ((ret = skip_input(s, s->ch_size[ch])) < 0) + return ret; } - skip_input(s, 1); - return 0; + return skip_input(s, 1); } static int parse_meter(DBEContext *s) { if (s->meter_size) - skip_input(s, s->key_present + s->meter_size + 1); + return skip_input(s, s->key_present + s->meter_size + 1); return 0; } From 6029b8a6bbc8bbf7799108582e71078ec0bde1cf Mon Sep 17 00:00:00 2001 From: foo86 Date: Sat, 22 Jul 2017 17:27:28 +0300 Subject: [PATCH 2648/3374] avformat/s337m: fix potentially undefined pointer arithmetic Use integer position instead of pointer for loop variable. Also only skip header fields after header has been fully validated. --- libavformat/s337m.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/libavformat/s337m.c b/libavformat/s337m.c index 1f4ba5edafa82..2e85d487b5ee9 100644 --- a/libavformat/s337m.c +++ b/libavformat/s337m.c @@ -86,22 +86,21 @@ static int s337m_probe(AVProbeData *p) { uint64_t state = 0; int markers[3] = { 0 }; - int i, sum, max, data_type, data_size, offset; + int i, pos, sum, max, data_type, data_size, offset; uint8_t *buf; - for (buf = p->buf; buf < p->buf + p->buf_size; buf++) { - state = (state << 8) | *buf; + for (pos = 0; pos < p->buf_size; pos++) { + state = (state << 8) | p->buf[pos]; if (!IS_LE_MARKER(state)) continue; + buf = p->buf + pos + 1; if (IS_16LE_MARKER(state)) { - data_type = AV_RL16(buf + 1); - data_size = AV_RL16(buf + 3); - buf += 4; + data_type = AV_RL16(buf ); + data_size = AV_RL16(buf + 2); } else { - data_type = AV_RL24(buf + 1); - data_size = AV_RL24(buf + 4); - buf += 6; + data_type = AV_RL24(buf ); + data_size = AV_RL24(buf + 3); } if (s337m_get_offset_and_codec(NULL, state, data_type, data_size, &offset, NULL)) @@ -110,7 +109,8 @@ static int s337m_probe(AVProbeData *p) i = IS_16LE_MARKER(state) ? 0 : IS_20LE_MARKER(state) ? 1 : 2; markers[i]++; - buf += offset; + pos += IS_16LE_MARKER(state) ? 4 : 6; + pos += offset; state = 0; } From 5d0b69f3b7e5b28804c84e50c593606b597f5956 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 26 Jul 2017 20:22:49 +0200 Subject: [PATCH 2649/3374] avcodec/jpeg2000dec: Fix h/vden typo Signed-off-by: Michael Niedermayer --- libavcodec/jpeg2000dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index dd9c60feb4521..9a5e64e85408a 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -2075,7 +2075,7 @@ static int jp2_find_codestream(Jpeg2000DecoderContext *s) hden = bytestream2_get_be16u(&s->g); vexp = bytestream2_get_byteu(&s->g); hexp = bytestream2_get_byteu(&s->g); - if (!vnum || !vden || !hnum || !vden) { + if (!vnum || !vden || !hnum || !hden) { bytestream2_seek(&s->g, atom2_end, SEEK_SET); av_log(s->avctx, AV_LOG_WARNING, "RES box invalid\n"); continue; From 133dafe24fc7167b049bb14fb5ec2d199d8cddcc Mon Sep 17 00:00:00 2001 From: Rostislav Pehlivanov Date: Wed, 26 Jul 2017 23:54:14 +0100 Subject: [PATCH 2650/3374] pngdec: fix potential memory leak Fixes CID1412026. Signed-off-by: Rostislav Pehlivanov --- libavcodec/pngdec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index f83884dfc2224..4fc1c5a062786 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -863,8 +863,11 @@ static int decode_iccp_chunk(PNGDecContext *s, int length, AVFrame *f) av_bprint_finalize(&bp, (char **)&data); - if (!(sd = av_frame_new_side_data(f, AV_FRAME_DATA_ICC_PROFILE, bp.len))) + sd = av_frame_new_side_data(f, AV_FRAME_DATA_ICC_PROFILE, bp.len); + if (!sd) { + av_free(data); return AVERROR(ENOMEM); + } av_dict_set(&sd->metadata, "name", profile_name, 0); memcpy(sd->data, data, bp.len); From 296debd213bd6dce7647cedd34eb64e5b94cdc92 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 26 Jul 2017 03:26:59 +0200 Subject: [PATCH 2651/3374] avcodec/dnxhddec: Move mb height check out of non hr branch Fixes: out of array access Fixes: poc.dnxhd Found-by: Bingchang, Liu@VARAS of IIE Signed-off-by: Michael Niedermayer --- libavcodec/dnxhddec.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c index 40d41f9bf11e5..f46e41a456239 100644 --- a/libavcodec/dnxhddec.c +++ b/libavcodec/dnxhddec.c @@ -298,14 +298,18 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, if (ctx->mb_height > 68 && ff_dnxhd_check_header_prefix_hr(header_prefix)) { ctx->data_offset = 0x170 + (ctx->mb_height << 2); } else { - if (ctx->mb_height > 68 || - (ctx->mb_height << frame->interlaced_frame) > (ctx->height + 15) >> 4) { + if (ctx->mb_height > 68) { av_log(ctx->avctx, AV_LOG_ERROR, "mb height too big: %d\n", ctx->mb_height); return AVERROR_INVALIDDATA; } ctx->data_offset = 0x280; } + if ((ctx->mb_height << frame->interlaced_frame) > (ctx->height + 15) >> 4) { + av_log(ctx->avctx, AV_LOG_ERROR, + "mb height too big: %d\n", ctx->mb_height); + return AVERROR_INVALIDDATA; + } if (buf_size < ctx->data_offset) { av_log(ctx->avctx, AV_LOG_ERROR, From 60008c0fe94bd78be15097e5aceffd9fcb80c1b6 Mon Sep 17 00:00:00 2001 From: Tobias Rapp Date: Tue, 25 Jul 2017 09:42:21 +0200 Subject: [PATCH 2652/3374] fate: update pixfmt_best test to check for endianness Signed-off-by: Tobias Rapp --- libavutil/tests/pixfmt_best.c | 14 ++++++++++++++ tests/ref/fate/pixfmt_best | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/libavutil/tests/pixfmt_best.c b/libavutil/tests/pixfmt_best.c index a617633e9b948..e98fcc19a50b6 100644 --- a/libavutil/tests/pixfmt_best.c +++ b/libavutil/tests/pixfmt_best.c @@ -117,6 +117,20 @@ int main(void) TEST(AV_PIX_FMT_GBRAP10, AV_PIX_FMT_RGB48); TEST(AV_PIX_FMT_GBRAP12, AV_PIX_FMT_RGB48); + // Formats containing the same data in different endianness. + TEST(AV_PIX_FMT_GRAY10BE, AV_PIX_FMT_GRAY10); + TEST(AV_PIX_FMT_GRAY10LE, AV_PIX_FMT_GRAY10); + TEST(AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_GRAY16); + TEST(AV_PIX_FMT_GRAY16LE, AV_PIX_FMT_GRAY16); + TEST(AV_PIX_FMT_YUV422P10BE, AV_PIX_FMT_YUV422P10); + TEST(AV_PIX_FMT_YUV422P10LE, AV_PIX_FMT_YUV422P10); + TEST(AV_PIX_FMT_YUV444P16BE, AV_PIX_FMT_YUV444P16); + TEST(AV_PIX_FMT_YUV444P16LE, AV_PIX_FMT_YUV444P16); + TEST(AV_PIX_FMT_RGB565BE, AV_PIX_FMT_RGB565); + TEST(AV_PIX_FMT_RGB565LE, AV_PIX_FMT_RGB565); + TEST(AV_PIX_FMT_RGB48BE, AV_PIX_FMT_RGB48); + TEST(AV_PIX_FMT_RGB48LE, AV_PIX_FMT_RGB48); + // Opaque formats are least unlike each other. TEST(AV_PIX_FMT_DXVA2_VLD, AV_PIX_FMT_VDPAU); diff --git a/tests/ref/fate/pixfmt_best b/tests/ref/fate/pixfmt_best index 1118198098a01..699e2e4213c83 100644 --- a/tests/ref/fate/pixfmt_best +++ b/tests/ref/fate/pixfmt_best @@ -1 +1 @@ -60 tests passed, 0 tests failed. +72 tests passed, 0 tests failed. From 9835ee60da31184dd6f6700328e75c78fa485efe Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Mon, 26 Jun 2017 09:22:58 +0200 Subject: [PATCH 2653/3374] avcodec/dnxhdenc: enable frame threading Signed-off-by: Paul B Mahol --- libavcodec/dnxhdenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c index 6e9b54de4f0e4..f8bf7db90a9ff 100644 --- a/libavcodec/dnxhdenc.c +++ b/libavcodec/dnxhdenc.c @@ -1391,7 +1391,7 @@ AVCodec ff_dnxhd_encoder = { .init = dnxhd_encode_init, .encode2 = dnxhd_encode_picture, .close = dnxhd_encode_end, - .capabilities = AV_CODEC_CAP_SLICE_THREADS, + .capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV422P10, From 9f449227a3adb1b139ccb7171b1f3b366a1c323a Mon Sep 17 00:00:00 2001 From: James Almer Date: Thu, 27 Jul 2017 14:21:41 -0300 Subject: [PATCH 2654/3374] doc/APIChanges: add missing entry for ICC Profile side data type. --- doc/APIchanges | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/APIchanges b/doc/APIchanges index 69f876e6c3e81..63fac21000609 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-07-25 - 24de4fddca - lavu 55.69.100 - frame.h + Add AV_FRAME_DATA_ICC_PROFILE side data type. + 2017-xx-xx - xxxxxxx - lavc 57.100.100 - avcodec.h DXVA2 and D3D11 hardware accelerated decoding now supports the new hwaccel API, which can create the decoder context and allocate hardware frame automatically. From 8c3b329da21a05a977b21d1a3ad3ed8ce72f997b Mon Sep 17 00:00:00 2001 From: Wan-Teh Chang Date: Tue, 18 Jul 2017 16:34:40 -0700 Subject: [PATCH 2655/3374] avcodec/h264_slice: don't sync default_ref[] between threads. default_ref[] is unconditionally initialized in h264_initialise_ref_list() (called from ff_h264_build_ref_list(), called from h264_slice_init()). This fixes the following tsan warning when running fate-h264: WARNING: ThreadSanitizer: data race (pid=31070) Write of size 8 at 0x7bbc000082a8 by thread T1 (mutexes: write M1628): #0 memcpy /work/release-test/final/llvm.src/projects/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:655:5 (ffmpeg+0x10de9d) #1 h264_initialise_ref_list ffmpeg/libavcodec/h264_refs.c:214:29 (ffmpeg+0x1186b3f) #2 ff_h264_build_ref_list ffmpeg/libavcodec/h264_refs.c:306 (ffmpeg+0x1186b3f) #3 h264_slice_init ffmpeg/libavcodec/h264_slice.c:1900:11 (ffmpeg+0x1191149) [..] Previous read of size 8 at 0x7bbc000082a8 by main thread (mutexes: write M1630): #0 memcpy /work/release-test/final/llvm.src/projects/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:655:5 (ffmpeg+0x10de9d) #1 ff_h264_update_thread_context ffmpeg/libavcodec/h264_slice.c:411:5 (ffmpeg+0x118b7dc) Signed-off-by: Wan-Teh Chang Signed-off-by: Ronald S. Bultje --- libavcodec/h264_slice.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 6deb08fe6d064..2fb89b189d718 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -408,7 +408,6 @@ int ff_h264_update_thread_context(AVCodecContext *dst, memcpy(&h->poc, &h1->poc, sizeof(h->poc)); - memcpy(h->default_ref, h1->default_ref, sizeof(h->default_ref)); memcpy(h->short_ref, h1->short_ref, sizeof(h->short_ref)); memcpy(h->long_ref, h1->long_ref, sizeof(h->long_ref)); memcpy(h->delayed_pic, h1->delayed_pic, sizeof(h->delayed_pic)); From 58fbcf885d97d9b83c54cc57e3631c76caa208cf Mon Sep 17 00:00:00 2001 From: Wan-Teh Chang Date: Tue, 18 Jul 2017 09:11:09 -0700 Subject: [PATCH 2656/3374] pthread_frame: revert 2e664b9c1e73c80aab91070c1eb7676f04bdd12d. The patch does not fix the tsan warning it was intended to fix. Reverting the patch moves the av_log() back to the outside of the lock. Signed-off-by: Wan-Teh Chang Signed-off-by: Ronald S. Bultje --- libavcodec/pthread_frame.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 2cea232a36239..08e182c3d19c7 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -570,11 +570,12 @@ void ff_thread_report_progress(ThreadFrame *f, int n, int field) p = f->owner[field]->internal->thread_ctx; - pthread_mutex_lock(&p->progress_mutex); if (atomic_load_explicit(&p->debug_threads, memory_order_relaxed)) av_log(f->owner[field], AV_LOG_DEBUG, "%p finished %d field %d\n", progress, n, field); + pthread_mutex_lock(&p->progress_mutex); + atomic_store_explicit(&progress[field], n, memory_order_release); pthread_cond_broadcast(&p->progress_cond); @@ -592,10 +593,11 @@ void ff_thread_await_progress(ThreadFrame *f, int n, int field) p = f->owner[field]->internal->thread_ctx; - pthread_mutex_lock(&p->progress_mutex); if (atomic_load_explicit(&p->debug_threads, memory_order_relaxed)) av_log(f->owner[field], AV_LOG_DEBUG, "thread awaiting %d field %d from %p\n", n, field, progress); + + pthread_mutex_lock(&p->progress_mutex); while (atomic_load_explicit(&progress[field], memory_order_relaxed) < n) pthread_cond_wait(&p->progress_cond, &p->progress_mutex); pthread_mutex_unlock(&p->progress_mutex); From aeddb3607be94b1d6fef41b602b07f08223ea565 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 26 Jul 2017 20:10:28 +0200 Subject: [PATCH 2657/3374] avcodec/pixlet: Simplify nbits computation Fixes multiple integer overflows Fixes: runtime error: signed integer overflow: 1 + 2147483647 cannot be represented in type 'int' Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Reviewed-by: Paul B Mahol Signed-off-by: Michael Niedermayer --- libavcodec/pixlet.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/pixlet.c b/libavcodec/pixlet.c index 0e541a9ccb40e..a9661d3ab6812 100644 --- a/libavcodec/pixlet.c +++ b/libavcodec/pixlet.c @@ -206,8 +206,8 @@ static int read_high_coeffs(AVCodecContext *avctx, uint8_t *src, int16_t *dst, i if ((ret = init_get_bits8(b, src, bytestream2_get_bytes_left(&ctx->gb))) < 0) return ret; - if ((a >= 0) + (a ^ (a >> 31)) - (a >> 31) != 1) { - nbits = 33 - ff_clz((a >= 0) + (a ^ (a >> 31)) - (a >> 31) - 1); + if (a ^ (a >> 31)) { + nbits = 33 - ff_clz(a ^ (a >> 31)); if (nbits > 16) return AVERROR_INVALIDDATA; } else { From 8e275a74b09cc87f4334ed572f919b7647d4bea1 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 26 Jul 2017 20:26:43 +0200 Subject: [PATCH 2658/3374] avcodec/diracdec: Fix integer overflow in signed multiplication in UNPACK_ARITH() Fixes: runtime error: signed integer overflow: 1073741823 * 4 cannot be represented in type 'int' Fixes: 2729/clusterfuzz-testcase-minimized-5902915464069120 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/diracdec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c index 71d0ff41b25b3..d2262ebbf5692 100644 --- a/libavcodec/diracdec.c +++ b/libavcodec/diracdec.c @@ -454,7 +454,8 @@ static inline int coeff_unpack_golomb(GetBitContext *gb, int qfactor, int qoffse static inline void coeff_unpack_arith_##n(DiracArith *c, int qfactor, int qoffset, \ SubBand *b, type *buf, int x, int y) \ { \ - int coeff, sign, sign_pred = 0, pred_ctx = CTX_ZPZN_F1; \ + int sign, sign_pred = 0, pred_ctx = CTX_ZPZN_F1; \ + unsigned coeff; \ const int mstride = -(b->stride >> (1+b->pshift)); \ if (b->parent) { \ const type *pbuf = (type *)b->parent->ibuf; \ From 36ea41de37367e5a959881488b5006d77437757d Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Fri, 28 Jul 2017 14:12:06 +0530 Subject: [PATCH 2659/3374] libavcodec/mips: Improve avc dequant-idct luma dc msa function Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/h264idct_msa.c | 66 +++++++++++++++++----------------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/libavcodec/mips/h264idct_msa.c b/libavcodec/mips/h264idct_msa.c index 81e09e9b1657b..861befe244bbb 100644 --- a/libavcodec/mips/h264idct_msa.c +++ b/libavcodec/mips/h264idct_msa.c @@ -40,17 +40,20 @@ static void avc_deq_idct_luma_dc_msa(int16_t *dst, int16_t *src, int32_t de_q_val) { #define DC_DEST_STRIDE 16 - int16_t out0, out1, out2, out3; - v8i16 src0, src1, src2, src3; + int16_t out0, out1, out2, out3, out4, out5, out6, out7; + v8i16 src1, src3; v8i16 vec0, vec1, vec2, vec3; + v8i16 tmp0, tmp1, tmp2, tmp3; v8i16 hres0, hres1, hres2, hres3; v8i16 vres0, vres1, vres2, vres3; v4i32 vres0_r, vres1_r, vres2_r, vres3_r; - v4i32 de_q_vec = __msa_fill_w(de_q_val); + const v4i32 de_q_vec = __msa_fill_w(de_q_val); + const v8i16 src0 = LD_SH(src); + const v8i16 src2 = LD_SH(src + 8); - LD4x4_SH(src, src0, src1, src2, src3); - TRANSPOSE4x4_SH_SH(src0, src1, src2, src3, src0, src1, src2, src3); - BUTTERFLY_4(src0, src2, src3, src1, vec0, vec3, vec2, vec1); + ILVL_D2_SH(src0, src0, src2, src2, src1, src3); + TRANSPOSE4x4_SH_SH(src0, src1, src2, src3, tmp0, tmp1, tmp2, tmp3); + BUTTERFLY_4(tmp0, tmp2, tmp3, tmp1, vec0, vec3, vec2, vec1); BUTTERFLY_4(vec0, vec1, vec2, vec3, hres0, hres3, hres2, hres1); TRANSPOSE4x4_SH_SH(hres0, hres1, hres2, hres3, hres0, hres1, hres2, hres3); BUTTERFLY_4(hres0, hres1, hres3, hres2, vec0, vec3, vec2, vec1); @@ -72,40 +75,35 @@ static void avc_deq_idct_luma_dc_msa(int16_t *dst, int16_t *src, out1 = __msa_copy_s_h(vec0, 1); out2 = __msa_copy_s_h(vec0, 2); out3 = __msa_copy_s_h(vec0, 3); - SH(out0, dst); - SH(out1, (dst + 2 * DC_DEST_STRIDE)); - SH(out2, (dst + 8 * DC_DEST_STRIDE)); + out4 = __msa_copy_s_h(vec0, 4); + out5 = __msa_copy_s_h(vec0, 5); + out6 = __msa_copy_s_h(vec0, 6); + out7 = __msa_copy_s_h(vec0, 7); + SH(out0, (dst + 0 * DC_DEST_STRIDE)); + SH(out1, (dst + 2 * DC_DEST_STRIDE)); + SH(out2, (dst + 8 * DC_DEST_STRIDE)); SH(out3, (dst + 10 * DC_DEST_STRIDE)); - dst += DC_DEST_STRIDE; - - out0 = __msa_copy_s_h(vec0, 4); - out1 = __msa_copy_s_h(vec0, 5); - out2 = __msa_copy_s_h(vec0, 6); - out3 = __msa_copy_s_h(vec0, 7); - SH(out0, dst); - SH(out1, (dst + 2 * DC_DEST_STRIDE)); - SH(out2, (dst + 8 * DC_DEST_STRIDE)); - SH(out3, (dst + 10 * DC_DEST_STRIDE)); - dst += (3 * DC_DEST_STRIDE); + SH(out4, (dst + 1 * DC_DEST_STRIDE)); + SH(out5, (dst + 3 * DC_DEST_STRIDE)); + SH(out6, (dst + 9 * DC_DEST_STRIDE)); + SH(out7, (dst + 11 * DC_DEST_STRIDE)); out0 = __msa_copy_s_h(vec1, 0); out1 = __msa_copy_s_h(vec1, 1); out2 = __msa_copy_s_h(vec1, 2); out3 = __msa_copy_s_h(vec1, 3); - SH(out0, dst); - SH(out1, (dst + 2 * DC_DEST_STRIDE)); - SH(out2, (dst + 8 * DC_DEST_STRIDE)); - SH(out3, (dst + 10 * DC_DEST_STRIDE)); - dst += DC_DEST_STRIDE; - - out0 = __msa_copy_s_h(vec1, 4); - out1 = __msa_copy_s_h(vec1, 5); - out2 = __msa_copy_s_h(vec1, 6); - out3 = __msa_copy_s_h(vec1, 7); - SH(out0, dst); - SH(out1, (dst + 2 * DC_DEST_STRIDE)); - SH(out2, (dst + 8 * DC_DEST_STRIDE)); - SH(out3, (dst + 10 * DC_DEST_STRIDE)); + out4 = __msa_copy_s_h(vec1, 4); + out5 = __msa_copy_s_h(vec1, 5); + out6 = __msa_copy_s_h(vec1, 6); + out7 = __msa_copy_s_h(vec1, 7); + SH(out0, (dst + 4 * DC_DEST_STRIDE)); + SH(out1, (dst + 6 * DC_DEST_STRIDE)); + SH(out2, (dst + 12 * DC_DEST_STRIDE)); + SH(out3, (dst + 14 * DC_DEST_STRIDE)); + SH(out4, (dst + 5 * DC_DEST_STRIDE)); + SH(out5, (dst + 7 * DC_DEST_STRIDE)); + SH(out6, (dst + 13 * DC_DEST_STRIDE)); + SH(out7, (dst + 15 * DC_DEST_STRIDE)); #undef DC_DEST_STRIDE } From 08c073434e25cba8c43aae5ed9554fdd594adfb0 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 28 Jul 2017 13:41:59 +0200 Subject: [PATCH 2660/3374] avformat/rtmppkt: Convert ff_amf_tag_size() to bytestream2 Fixes: out of array accesses Fixes: crash-9238fa9e8d4fde3beda1f279626f53812cb001cb-SEGV Found-by: JunDong Xie of Ant-financial Light-Year Security Lab Signed-off-by: Michael Niedermayer --- libavformat/rtmppkt.c | 68 ++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c index 833a3dbadebed..572e165498aab 100644 --- a/libavformat/rtmppkt.c +++ b/libavformat/rtmppkt.c @@ -433,50 +433,78 @@ void ff_rtmp_packet_destroy(RTMPPacket *pkt) pkt->size = 0; } -int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end) +static int amf_tag_skip(GetByteContext *gb) { - const uint8_t *base = data; AMFDataType type; unsigned nb = -1; int parse_key = 1; - if (data >= data_end) + if (bytestream2_get_bytes_left(gb) < 1) return -1; - switch ((type = *data++)) { - case AMF_DATA_TYPE_NUMBER: return 9; - case AMF_DATA_TYPE_BOOL: return 2; - case AMF_DATA_TYPE_STRING: return 3 + AV_RB16(data); - case AMF_DATA_TYPE_LONG_STRING: return 5 + AV_RB32(data); - case AMF_DATA_TYPE_NULL: return 1; - case AMF_DATA_TYPE_DATE: return 11; + + type = bytestream2_get_byte(gb); + switch (type) { + case AMF_DATA_TYPE_NUMBER: + bytestream2_get_be64(gb); + return 0; + case AMF_DATA_TYPE_BOOL: + bytestream2_get_byte(gb); + return 0; + case AMF_DATA_TYPE_STRING: + bytestream2_skip(gb, bytestream2_get_be16(gb)); + return 0; + case AMF_DATA_TYPE_LONG_STRING: + bytestream2_skip(gb, bytestream2_get_be32(gb)); + return 0; + case AMF_DATA_TYPE_NULL: + return 0; + case AMF_DATA_TYPE_DATE: + bytestream2_skip(gb, 10); + return 0; case AMF_DATA_TYPE_ARRAY: parse_key = 0; case AMF_DATA_TYPE_MIXEDARRAY: - nb = bytestream_get_be32(&data); + nb = bytestream2_get_be32(gb); case AMF_DATA_TYPE_OBJECT: while (nb-- > 0 || type != AMF_DATA_TYPE_ARRAY) { int t; if (parse_key) { - int size = bytestream_get_be16(&data); + int size = bytestream2_get_be16(gb); if (!size) { - data++; + bytestream2_get_byte(gb); break; } - if (size < 0 || size >= data_end - data) + if (size < 0 || size >= bytestream2_get_bytes_left(gb)) return -1; - data += size; + bytestream2_skip(gb, size); } - t = ff_amf_tag_size(data, data_end); - if (t < 0 || t >= data_end - data) + t = amf_tag_skip(gb); + if (t < 0 || bytestream2_get_bytes_left(gb) <= 0) return -1; - data += t; } - return data - base; - case AMF_DATA_TYPE_OBJECT_END: return 1; + return 0; + case AMF_DATA_TYPE_OBJECT_END: return 0; default: return -1; } } +int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end) +{ + GetByteContext gb; + int ret; + + if (data >= data_end) + return -1; + + bytestream2_init(&gb, data, data_end - data); + + ret = amf_tag_skip(&gb); + if (ret < 0 || bytestream2_get_bytes_left(&gb) <= 0) + return -1; + av_assert0(bytestream2_tell(&gb) >= 0 && bytestream2_tell(&gb) <= data_end - data); + return bytestream2_tell(&gb); +} + int ff_amf_get_field_value(const uint8_t *data, const uint8_t *data_end, const uint8_t *name, uint8_t *dst, int dst_size) { From ffcc82219cef0928bed2d558b19ef6ea35634130 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 28 Jul 2017 14:37:26 +0200 Subject: [PATCH 2661/3374] avformat/rtmppkt: Convert ff_amf_get_field_value() to bytestream2 Fixes: out of array accesses Found-by: JunDong Xie of Ant-financial Light-Year Security Lab Signed-off-by: Michael Niedermayer --- libavformat/rtmppkt.c | 57 ++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c index 572e165498aab..3ae605d28049b 100644 --- a/libavformat/rtmppkt.c +++ b/libavformat/rtmppkt.c @@ -505,53 +505,70 @@ int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end) return bytestream2_tell(&gb); } -int ff_amf_get_field_value(const uint8_t *data, const uint8_t *data_end, +static int amf_get_field_value2(GetByteContext *gb, const uint8_t *name, uint8_t *dst, int dst_size) { int namelen = strlen(name); int len; - while (*data != AMF_DATA_TYPE_OBJECT && data < data_end) { - len = ff_amf_tag_size(data, data_end); - if (len < 0) - len = data_end - data; - data += len; + while (bytestream2_peek_byte(gb) != AMF_DATA_TYPE_OBJECT && bytestream2_get_bytes_left(gb) > 0) { + int ret = amf_tag_skip(gb); + if (ret < 0) + return -1; } - if (data_end - data < 3) + if (bytestream2_get_bytes_left(gb) < 3) return -1; - data++; + bytestream2_get_byte(gb); + for (;;) { - int size = bytestream_get_be16(&data); + int size = bytestream2_get_be16(gb); if (!size) break; - if (size < 0 || size >= data_end - data) + if (size < 0 || size >= bytestream2_get_bytes_left(gb)) return -1; - data += size; - if (size == namelen && !memcmp(data-size, name, namelen)) { - switch (*data++) { + bytestream2_skip(gb, size); + if (size == namelen && !memcmp(gb->buffer-size, name, namelen)) { + switch (bytestream2_get_byte(gb)) { case AMF_DATA_TYPE_NUMBER: - snprintf(dst, dst_size, "%g", av_int2double(AV_RB64(data))); + snprintf(dst, dst_size, "%g", av_int2double(bytestream2_get_be64(gb))); break; case AMF_DATA_TYPE_BOOL: - snprintf(dst, dst_size, "%s", *data ? "true" : "false"); + snprintf(dst, dst_size, "%s", bytestream2_get_byte(gb) ? "true" : "false"); break; case AMF_DATA_TYPE_STRING: - len = bytestream_get_be16(&data); - av_strlcpy(dst, data, FFMIN(len+1, dst_size)); + len = bytestream2_get_be16(gb); + if (dst_size < 1) + return -1; + if (dst_size < len + 1) + len = dst_size - 1; + bytestream2_get_buffer(gb, dst, len); + dst[len] = 0; break; default: return -1; } return 0; } - len = ff_amf_tag_size(data, data_end); - if (len < 0 || len >= data_end - data) + len = amf_tag_skip(gb); + if (len < 0 || bytestream2_get_bytes_left(gb) <= 0) return -1; - data += len; } return -1; } +int ff_amf_get_field_value(const uint8_t *data, const uint8_t *data_end, + const uint8_t *name, uint8_t *dst, int dst_size) +{ + GetByteContext gb; + + if (data >= data_end) + return -1; + + bytestream2_init(&gb, data, data_end - data); + + return amf_get_field_value2(&gb, name, dst, dst_size); +} + static const char* rtmp_packet_type(int type) { switch (type) { From 2c630d159ffe8a9822e81f9c041652762b37e068 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 27 Jul 2017 23:49:26 +0200 Subject: [PATCH 2662/3374] avcodec/takdec: Fix integer overflow in decode_subframe() Fixes: runtime error: signed integer overflow: -536870912 - 1972191120 cannot be represented in type 'int' Fixes: 2711/clusterfuzz-testcase-minimized-4975142398590976 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/takdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c index e555482b235de..1676313b7cb9f 100644 --- a/libavcodec/takdec.c +++ b/libavcodec/takdec.c @@ -491,7 +491,7 @@ static int decode_subframe(TAKDecContext *s, int32_t *decoded, s->residues[i + j + 1] * s->filter[j + 1] + s->residues[i + j ] * s->filter[j ]; } - v = (av_clip_intp2(v >> filter_quant, 13) * (1 << dshift)) - *decoded; + v = (av_clip_intp2(v >> filter_quant, 13) * (1 << dshift)) - (unsigned)*decoded; *decoded++ = v; s->residues[filter_order + i] = v >> dshift; } From c0220c768c7fc933a76c863ebbb0abdf68a88533 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 27 Jul 2017 23:49:27 +0200 Subject: [PATCH 2663/3374] avcodec/diracdec: Fix integer overflow in divide3() Fixes: runtime error: signed integer overflow: -1073746548 * 21845 cannot be represented in type 'int' Fixes: 2729/clusterfuzz-testcase-minimized-5902915464069120 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/diracdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c index d2262ebbf5692..d2aaeab01151c 100644 --- a/libavcodec/diracdec.c +++ b/libavcodec/diracdec.c @@ -249,7 +249,7 @@ enum dirac_subband { /* magic number division by 3 from schroedinger */ static inline int divide3(int x) { - return ((x+1)*21845 + 10922) >> 16; + return (int)((x+1U)*21845 + 10922) >> 16; } static DiracFrame *remove_frame(DiracFrame *framelist[], int picnum) From bf8ab72ae95bb11f2c281d464594c2f6ba70326b Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 28 Jul 2017 03:22:40 +0200 Subject: [PATCH 2664/3374] avcodec/dirac_dwt: Fix multiple integer overflows in COMPOSE_DD97iH0() Fixes: runtime error: signed integer overflow: 9 * 335544320 cannot be represented in type 'int' Fixes: 2739/clusterfuzz-testcase-minimized-6737297955356672 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/dirac_dwt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/dirac_dwt.h b/libavcodec/dirac_dwt.h index 4d338651fae2a..62f8472b41bdd 100644 --- a/libavcodec/dirac_dwt.h +++ b/libavcodec/dirac_dwt.h @@ -99,7 +99,7 @@ void ff_spatial_idwt_slice2(DWTContext *d, int y); (b1 + ((b0 + b2 + 1) >> 1)) #define COMPOSE_DD97iH0(b0, b1, b2, b3, b4)\ - (b2 + ((-b0 + 9*b1 + 9*b3 - b4 + 8) >> 4)) + (b2 + ((int)(-b0 + 9U*b1 + 9U*b3 - b4 + 8) >> 4)) #define COMPOSE_DD137iL0(b0, b1, b2, b3, b4)\ (b2 - ((-b0 + 9*b1 + 9*b3 - b4 + 16) >> 5)) From 1e0c75ea165c926c544d42f0a1e51d7f6fa95354 Mon Sep 17 00:00:00 2001 From: Jun Zhao Date: Thu, 20 Jul 2017 00:58:56 -0400 Subject: [PATCH 2665/3374] examples/hw_decode: Add a HWAccel decoding example. Works with VAAPI, VDPAU, DXVA2 and D3D11VA. Signed-off-by: Liu, Kaixuan Signed-off-by: Jun Zhao Reviewed-by: Steven Liu Signed-off-by: Mark Thompson --- configure | 2 + doc/Makefile | 1 + doc/examples/Makefile | 1 + doc/examples/hw_decode.c | 266 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 270 insertions(+) create mode 100644 doc/examples/hw_decode.c diff --git a/configure b/configure index 5811ee149a726..66c7b948e4cdb 100755 --- a/configure +++ b/configure @@ -1468,6 +1468,7 @@ EXAMPLE_LIST=" filtering_audio_example filtering_video_example http_multiclient_example + hw_decode_example metadata_example muxing_example qsvdec_example @@ -3208,6 +3209,7 @@ filter_audio_example_deps="avfilter avutil" filtering_audio_example_deps="avfilter avcodec avformat avutil" filtering_video_example_deps="avfilter avcodec avformat avutil" http_multiclient_example_deps="avformat avutil fork" +hw_decode_example_deps="avcodec avformat avutil" metadata_example_deps="avformat avutil" muxing_example_deps="avcodec avformat avutil swscale" qsvdec_example_deps="avcodec avutil libmfx h264_qsv_decoder" diff --git a/doc/Makefile b/doc/Makefile index 4cc9eedd12132..b670f0bd4c7c0 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -48,6 +48,7 @@ DOC_EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE) += filter_audio DOC_EXAMPLES-$(CONFIG_FILTERING_AUDIO_EXAMPLE) += filtering_audio DOC_EXAMPLES-$(CONFIG_FILTERING_VIDEO_EXAMPLE) += filtering_video DOC_EXAMPLES-$(CONFIG_HTTP_MULTICLIENT_EXAMPLE) += http_multiclient +DOC_EXAMPLES-$(CONFIG_HW_DECODE_EXAMPLE) += hw_decode DOC_EXAMPLES-$(CONFIG_METADATA_EXAMPLE) += metadata DOC_EXAMPLES-$(CONFIG_MUXING_EXAMPLE) += muxing DOC_EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE) += qsvdec diff --git a/doc/examples/Makefile b/doc/examples/Makefile index 2d0a3062c2d9d..6428154c51d66 100644 --- a/doc/examples/Makefile +++ b/doc/examples/Makefile @@ -22,6 +22,7 @@ EXAMPLES= avio_dir_cmd \ filtering_video \ filtering_audio \ http_multiclient \ + hw_decode \ metadata \ muxing \ remuxing \ diff --git a/doc/examples/hw_decode.c b/doc/examples/hw_decode.c new file mode 100644 index 0000000000000..9c7adbf51a072 --- /dev/null +++ b/doc/examples/hw_decode.c @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2017 Jun Zhao + * Copyright (c) 2017 Kaixuan Liu + * + * HW Acceleration API (video decoding) decode sample + * + * 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 + */ + +/** + * @file + * HW-Accelerated decoding example. + * + * @example hw_decode.c + * This example shows how to do HW-accelerated decoding with output + * frames from the HW video surfaces. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +static AVBufferRef *hw_device_ctx = NULL; +static enum AVPixelFormat hw_pix_fmt; +static FILE *output_file = NULL; + +static enum AVPixelFormat find_fmt_by_hw_type(const enum AVHWDeviceType type) +{ + enum AVPixelFormat fmt; + + switch (type) { + case AV_HWDEVICE_TYPE_VAAPI: + fmt = AV_PIX_FMT_VAAPI; + break; + case AV_HWDEVICE_TYPE_DXVA2: + fmt = AV_PIX_FMT_DXVA2_VLD; + break; + case AV_HWDEVICE_TYPE_D3D11VA: + fmt = AV_PIX_FMT_D3D11; + break; + case AV_HWDEVICE_TYPE_VDPAU: + fmt = AV_PIX_FMT_VDPAU; + break; + case AV_HWDEVICE_TYPE_VIDEOTOOLBOX: + fmt = AV_PIX_FMT_VIDEOTOOLBOX; + break; + default: + fmt = AV_PIX_FMT_NONE; + break; + } + + return fmt; +} + +static int hw_decoder_init(AVCodecContext *ctx, const enum AVHWDeviceType type) +{ + int err = 0; + + if ((err = av_hwdevice_ctx_create(&hw_device_ctx, type, + NULL, NULL, 0)) < 0) { + fprintf(stderr, "Failed to create specified HW device.\n"); + return err; + } + ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx); + + return err; +} + +static enum AVPixelFormat get_hw_format(AVCodecContext *ctx, + const enum AVPixelFormat *pix_fmts) +{ + const enum AVPixelFormat *p; + + for (p = pix_fmts; *p != -1; p++) { + if (*p == hw_pix_fmt) + return *p; + } + + fprintf(stderr, "Failed to get HW surface format.\n"); + return AV_PIX_FMT_NONE; +} + +static int decode_write(AVCodecContext *avctx, AVPacket *packet) +{ + AVFrame *frame = NULL, *sw_frame = NULL; + AVFrame *tmp_frame = NULL; + uint8_t *buffer = NULL; + int size; + int ret = 0; + + ret = avcodec_send_packet(avctx, packet); + if (ret < 0) { + fprintf(stderr, "Error during decoding\n"); + return ret; + } + + while (ret >= 0) { + if (!(frame = av_frame_alloc()) || !(sw_frame = av_frame_alloc())) { + fprintf(stderr, "Can not alloc frame\n"); + ret = AVERROR(ENOMEM); + goto fail; + } + + ret = avcodec_receive_frame(avctx, frame); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { + av_frame_free(&frame); + av_frame_free(&sw_frame); + return 0; + } else if (ret < 0) { + fprintf(stderr, "Error while decoding\n"); + goto fail; + } + + if (frame->format == hw_pix_fmt) { + /* retrieve data from GPU to CPU */ + if ((ret = av_hwframe_transfer_data(sw_frame, frame, 0)) < 0) { + fprintf(stderr, "Error transferring the data to system memory\n"); + goto fail; + } + tmp_frame = sw_frame; + } else + tmp_frame = frame; + + size = av_image_get_buffer_size(tmp_frame->format, tmp_frame->width, + tmp_frame->height, 1); + buffer = av_malloc(size); + if (!buffer) { + fprintf(stderr, "Can not alloc buffer\n"); + ret = AVERROR(ENOMEM); + goto fail; + } + ret = av_image_copy_to_buffer(buffer, size, + (const uint8_t * const *)tmp_frame->data, + (const int *)tmp_frame->linesize, tmp_frame->format, + tmp_frame->width, tmp_frame->height, 1); + if (ret < 0) { + fprintf(stderr, "Can not copy image to buffer\n"); + goto fail; + } + + if ((ret = fwrite(buffer, 1, size, output_file)) < 0) { + fprintf(stderr, "Failed to dump raw data.\n"); + goto fail; + } + + fail: + av_frame_free(&frame); + av_frame_free(&sw_frame); + if (buffer) + av_freep(&buffer); + if (ret < 0) + return ret; + } + + return 0; +} + +int main(int argc, char *argv[]) +{ + AVFormatContext *input_ctx = NULL; + int video_stream, ret; + AVStream *video = NULL; + AVCodecContext *decoder_ctx = NULL; + AVCodec *decoder = NULL; + AVPacket packet; + enum AVHWDeviceType type; + + if (argc < 4) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return -1; + } + + av_register_all(); + + type = av_hwdevice_find_type_by_name(argv[1]); + hw_pix_fmt = find_fmt_by_hw_type(type); + if (hw_pix_fmt == -1) { + fprintf(stderr, "Cannot support '%s' in this example.\n", argv[1]); + return -1; + } + + /* open the input file */ + if (avformat_open_input(&input_ctx, argv[2], NULL, NULL) != 0) { + fprintf(stderr, "Cannot open input file '%s'\n", argv[2]); + return -1; + } + + if (avformat_find_stream_info(input_ctx, NULL) < 0) { + fprintf(stderr, "Cannot find input stream information.\n"); + return -1; + } + + /* find the video stream information */ + ret = av_find_best_stream(input_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0); + if (ret < 0) { + fprintf(stderr, "Cannot find a video stream in the input file\n"); + return -1; + } + video_stream = ret; + + if (!(decoder_ctx = avcodec_alloc_context3(decoder))) + return AVERROR(ENOMEM); + + video = input_ctx->streams[video_stream]; + if (avcodec_parameters_to_context(decoder_ctx, video->codecpar) < 0) + return -1; + + decoder_ctx->get_format = get_hw_format; + av_opt_set_int(decoder_ctx, "refcounted_frames", 1, 0); + + if (hw_decoder_init(decoder_ctx, type) < 0) + return -1; + + if ((ret = avcodec_open2(decoder_ctx, decoder, NULL)) < 0) { + fprintf(stderr, "Failed to open codec for stream #%u\n", video_stream); + return -1; + } + + /* open the file to dump raw data */ + output_file = fopen(argv[3], "w+"); + + /* actual decoding and dump the raw data */ + while (ret >= 0) { + if ((ret = av_read_frame(input_ctx, &packet)) < 0) + break; + + if (video_stream == packet.stream_index) + ret = decode_write(decoder_ctx, &packet); + + av_packet_unref(&packet); + } + + /* flush the decoder */ + packet.data = NULL; + packet.size = 0; + ret = decode_write(decoder_ctx, &packet); + av_packet_unref(&packet); + + if (output_file) + fclose(output_file); + avcodec_free_context(&decoder_ctx); + avformat_close_input(&input_ctx); + av_buffer_unref(&hw_device_ctx); + + return 0; +} From a3833bee9482fe650e05ee99718209414bd3356e Mon Sep 17 00:00:00 2001 From: Matt Oliver Date: Sat, 1 Jul 2017 23:16:42 +1000 Subject: [PATCH 2666/3374] win32_dlfcn: Support WinRT/UWP. This only enables dlls that are packaged with the application to be loaded. Due to the limitations of WinRT/UWP it is not allowed to load external/system dlls so this cannot be used as a complete replacement for normal win32 dll loading. Signed-off-by: Matt Oliver --- compat/w32dlfcn.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/compat/w32dlfcn.h b/compat/w32dlfcn.h index bc9bb8c9f51e8..78cc8f4c96d6c 100644 --- a/compat/w32dlfcn.h +++ b/compat/w32dlfcn.h @@ -21,7 +21,7 @@ #ifdef _WIN32 #include -#if _WIN32_WINNT < 0x0602 +#if (_WIN32_WINNT < 0x0602) || HAVE_WINRT #include "libavutil/wchar_filename.h" #endif /** @@ -71,7 +71,17 @@ static inline HMODULE win32_dlopen(const char *name) #ifndef LOAD_LIBRARY_SEARCH_SYSTEM32 # define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 #endif +#if HAVE_WINRT + wchar_t *name_w = NULL; + int ret; + if (utf8towchar(name, &name_w)) + return NULL; + ret = LoadPackagedLibrary(name_w, 0); + av_free(name_w); + return ret; +#else return LoadLibraryExA(name, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32); +#endif } #define dlopen(name, flags) win32_dlopen(name) #define dlclose FreeLibrary From 6cc677c0e828b2c40a7760013279c331a7748535 Mon Sep 17 00:00:00 2001 From: Matt Oliver Date: Wed, 12 Jul 2017 20:02:58 +1000 Subject: [PATCH 2667/3374] lavf/os_support: Use existing WinRT config value. Signed-off-by: Matt Oliver --- libavformat/os_support.h | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/libavformat/os_support.h b/libavformat/os_support.h index 6e245a88d81ef..91220e9716a41 100644 --- a/libavformat/os_support.h +++ b/libavformat/os_support.h @@ -146,18 +146,6 @@ int ff_poll(struct pollfd *fds, nfds_t numfds, int timeout); #include #include "libavutil/wchar_filename.h" -#ifdef WINAPI_FAMILY -#include -// If a WINAPI_FAMILY is defined, check that the desktop API subset -// is enabled -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) -#define USE_MOVEFILEEXA -#endif -#else -// If no WINAPI_FAMILY is defined, assume the full API subset -#define USE_MOVEFILEEXA -#endif - #define DEF_FS_FUNCTION(name, wfunc, afunc) \ static inline int win32_##name(const char *filename_utf8) \ { \ @@ -232,7 +220,7 @@ static inline int win32_rename(const char *src_utf8, const char *dest_utf8) fallback: /* filename may be be in CP_ACP */ -#ifdef USE_MOVEFILEEXA +#if !HAVE_WINRT ret = MoveFileExA(src_utf8, dest_utf8, MOVEFILE_REPLACE_EXISTING); if (ret) errno = EPERM; From b0c61209cd30f9ddf3356d5ded6df488f25d1bd5 Mon Sep 17 00:00:00 2001 From: Matt Oliver Date: Sat, 29 Jul 2017 21:09:19 +1000 Subject: [PATCH 2668/3374] lavc/makefile: Add missing file dependencies. ac3dsp.c uses tables from ac3.c ac3.c uses tables from ac3tab.c hevc_ps uses tables from hevc_data.c intrax8.c uses tables from msmpeg4data.c Signed-off-by: Matt Oliver --- libavcodec/Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 357fa1a361f50..74de41ab0fe05 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -53,7 +53,7 @@ OBJS = allcodecs.o \ # subsystems OBJS-$(CONFIG_AANDCTTABLES) += aandcttab.o -OBJS-$(CONFIG_AC3DSP) += ac3dsp.o +OBJS-$(CONFIG_AC3DSP) += ac3dsp.o ac3.o ac3tab.o OBJS-$(CONFIG_AUDIO_FRAME_QUEUE) += audio_frame_queue.o OBJS-$(CONFIG_AUDIODSP) += audiodsp.o OBJS-$(CONFIG_BLOCKDSP) += blockdsp.o @@ -79,7 +79,7 @@ OBJS-$(CONFIG_H264DSP) += h264dsp.o h264idct.o OBJS-$(CONFIG_H264PARSE) += h264_parse.o h2645_parse.o h264_ps.o OBJS-$(CONFIG_H264PRED) += h264pred.o OBJS-$(CONFIG_H264QPEL) += h264qpel.o -OBJS-$(CONFIG_HEVCPARSE) += hevc_parse.o h2645_parse.o hevc_ps.o hevc_sei.o +OBJS-$(CONFIG_HEVCPARSE) += hevc_parse.o h2645_parse.o hevc_ps.o hevc_sei.o hevc_data.o OBJS-$(CONFIG_HPELDSP) += hpeldsp.o OBJS-$(CONFIG_HUFFMAN) += huffman.o OBJS-$(CONFIG_HUFFYUVDSP) += huffyuvdsp.o @@ -87,7 +87,7 @@ OBJS-$(CONFIG_HUFFYUVENCDSP) += huffyuvencdsp.o OBJS-$(CONFIG_IDCTDSP) += idctdsp.o simple_idct.o jrevdct.o OBJS-$(CONFIG_IIRFILTER) += iirfilter.o OBJS-$(CONFIG_MDCT15) += mdct15.o -OBJS-$(CONFIG_INTRAX8) += intrax8.o intrax8dsp.o +OBJS-$(CONFIG_INTRAX8) += intrax8.o intrax8dsp.o msmpeg4data.o OBJS-$(CONFIG_IVIDSP) += ivi_dsp.o OBJS-$(CONFIG_JNI) += ffjni.o jni.o OBJS-$(CONFIG_JPEGTABLES) += jpegtables.o @@ -158,8 +158,8 @@ OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o aacenctab.o \ aacenc_pred.o \ psymodel.o mpeg4audio.o kbdwin.o cbrt_data.o OBJS-$(CONFIG_AASC_DECODER) += aasc.o msrledec.o -OBJS-$(CONFIG_AC3_DECODER) += ac3dec_float.o ac3dec_data.o ac3.o kbdwin.o -OBJS-$(CONFIG_AC3_FIXED_DECODER) += ac3dec_fixed.o ac3dec_data.o ac3.o kbdwin.o +OBJS-$(CONFIG_AC3_DECODER) += ac3dec_float.o ac3dec_data.o ac3.o kbdwin.o ac3tab.o +OBJS-$(CONFIG_AC3_FIXED_DECODER) += ac3dec_fixed.o ac3dec_data.o ac3.o kbdwin.o ac3tab.o OBJS-$(CONFIG_AC3_ENCODER) += ac3enc_float.o ac3enc.o ac3tab.o \ ac3.o kbdwin.o OBJS-$(CONFIG_AC3_FIXED_ENCODER) += ac3enc_fixed.o ac3enc.o ac3tab.o ac3.o From 70eb77b34e9f08cd5e431921a2792f31e4b5265c Mon Sep 17 00:00:00 2001 From: Rostislav Pehlivanov Date: Sat, 29 Jul 2017 21:27:01 +0100 Subject: [PATCH 2669/3374] mdct15: add inverse transform postrotation SIMD 2.5ms frames: Before (c): 2638 decicycles in postrotate, 2097040 runs, 112 skips After (sse3): 1467 decicycles in postrotate, 2097083 runs, 69 skips After (avx2): 1244 decicycles in postrotate, 2097085 runs, 67 skips 5ms frames: Before (c): 4987 decicycles in postrotate, 1048371 runs, 205 skips After (sse3): 2644 decicycles in postrotate, 1048509 runs, 67 skips After (avx2): 2031 decicycles in postrotate, 1048523 runs, 53 skips 10ms frames: Before (c): 9153 decicycles in postrotate, 523575 runs, 713 skips After (sse3): 5110 decicycles in postrotate, 523726 runs, 562 skips After (avx2): 3738 decicycles in postrotate, 524223 runs, 65 skips 20ms frames: Before (c): 17857 decicycles in postrotate, 261866 runs, 278 skips After (sse3): 10041 decicycles in postrotate, 261746 runs, 398 skips After (avx2): 7050 decicycles in postrotate, 262116 runs, 28 skips Improves total decoding performance for real world content by 9% with avx2. Signed-off-by: Rostislav Pehlivanov --- libavcodec/mdct15.c | 38 +++++++++------ libavcodec/mdct15.h | 3 ++ libavcodec/x86/mdct15.asm | 93 ++++++++++++++++++++++++++++++++++-- libavcodec/x86/mdct15_init.c | 9 ++++ 4 files changed, 123 insertions(+), 20 deletions(-) diff --git a/libavcodec/mdct15.c b/libavcodec/mdct15.c index d68372c3443ab..6f35059bfe8fe 100644 --- a/libavcodec/mdct15.c +++ b/libavcodec/mdct15.c @@ -65,11 +65,11 @@ static inline int init_pfa_reindex_tabs(MDCT15Context *s) const int inv_1 = l_ptwo << ((4 - b_ptwo) & 3); /* (2^b_ptwo)^-1 mod 15 */ const int inv_2 = 0xeeeeeeef & ((1U << b_ptwo) - 1); /* 15^-1 mod 2^b_ptwo */ - s->pfa_prereindex = av_malloc(15 * l_ptwo * sizeof(*s->pfa_prereindex)); + s->pfa_prereindex = av_malloc_array(15 * l_ptwo, sizeof(*s->pfa_prereindex)); if (!s->pfa_prereindex) return 1; - s->pfa_postreindex = av_malloc(15 * l_ptwo * sizeof(*s->pfa_postreindex)); + s->pfa_postreindex = av_malloc_array(15 * l_ptwo, sizeof(*s->pfa_postreindex)); if (!s->pfa_postreindex) return 1; @@ -225,15 +225,22 @@ static void imdct15_half(MDCT15Context *s, float *dst, const float *src, for (i = 0; i < 15; i++) s->ptwo_fft.fft_calc(&s->ptwo_fft, s->tmp + l_ptwo*i); + /* Reindex again, apply twiddles and output */ + s->postreindex(z, s->tmp, s->twiddle_exptab, s->pfa_postreindex, len8); +} + +static void postrotate_c(FFTComplex *out, FFTComplex *in, FFTComplex *exp, + int *lut, ptrdiff_t len8) +{ + int i; + /* Reindex again, apply twiddles and output */ for (i = 0; i < len8; i++) { const int i0 = len8 + i, i1 = len8 - i - 1; - const int s0 = s->pfa_postreindex[i0], s1 = s->pfa_postreindex[i1]; + const int s0 = lut[i0], s1 = lut[i1]; - CMUL(z[i1].re, z[i0].im, s->tmp[s1].im, s->tmp[s1].re, - s->twiddle_exptab[i1].im, s->twiddle_exptab[i1].re); - CMUL(z[i0].re, z[i1].im, s->tmp[s0].im, s->tmp[s0].re, - s->twiddle_exptab[i0].im, s->twiddle_exptab[i0].re); + CMUL(out[i1].re, out[i0].im, in[s1].im, in[s1].re, exp[i1].im, exp[i1].re); + CMUL(out[i0].re, out[i1].im, in[s0].im, in[s0].re, exp[i0].im, exp[i0].re); } } @@ -253,13 +260,14 @@ av_cold int ff_mdct15_init(MDCT15Context **ps, int inverse, int N, double scale) if (!s) return AVERROR(ENOMEM); - s->fft_n = N - 1; - s->len4 = len2 / 2; - s->len2 = len2; - s->inverse = inverse; - s->fft15 = fft15_c; - s->mdct = mdct15; - s->imdct_half = imdct15_half; + s->fft_n = N - 1; + s->len4 = len2 / 2; + s->len2 = len2; + s->inverse = inverse; + s->fft15 = fft15_c; + s->mdct = mdct15; + s->imdct_half = imdct15_half; + s->postreindex = postrotate_c; if (ff_fft_init(&s->ptwo_fft, N - 1, s->inverse) < 0) goto fail; @@ -271,7 +279,7 @@ av_cold int ff_mdct15_init(MDCT15Context **ps, int inverse, int N, double scale) if (!s->tmp) goto fail; - s->twiddle_exptab = av_malloc_array(s->len4, sizeof(*s->twiddle_exptab)); + s->twiddle_exptab = av_malloc_array(s->len4, sizeof(*s->twiddle_exptab)); if (!s->twiddle_exptab) goto fail; diff --git a/libavcodec/mdct15.h b/libavcodec/mdct15.h index 1c2149d436f21..42e60f3e102c2 100644 --- a/libavcodec/mdct15.h +++ b/libavcodec/mdct15.h @@ -42,6 +42,9 @@ typedef struct MDCT15Context { /* 15-point FFT */ void (*fft15)(FFTComplex *out, FFTComplex *in, FFTComplex *exptab, ptrdiff_t stride); + /* PFA postrotate and exptab */ + void (*postreindex)(FFTComplex *out, FFTComplex *in, FFTComplex *exp, int *lut, ptrdiff_t len8); + /* Calculate a full 2N -> N MDCT */ void (*mdct)(struct MDCT15Context *s, float *dst, const float *src, ptrdiff_t stride); diff --git a/libavcodec/x86/mdct15.asm b/libavcodec/x86/mdct15.asm index f8b895944da66..03091125387ae 100644 --- a/libavcodec/x86/mdct15.asm +++ b/libavcodec/x86/mdct15.asm @@ -22,14 +22,21 @@ %include "libavutil/x86/x86util.asm" -%if ARCH_X86_64 +SECTION_RODATA 32 -SECTION_RODATA +perm_neg: dd 2, 5, 3, 4, 6, 1, 7, 0 +perm_pos: dd 0, 7, 1, 6, 4, 3, 5, 2 +sign_adjust_r: times 4 dd 0x80000000, 0x00000000 sign_adjust_5: dd 0x00000000, 0x80000000, 0x80000000, 0x00000000 SECTION .text +%if ARCH_X86_64 + +;***************************************************************************************** +;void ff_fft15_avx(FFTComplex *out, FFTComplex *in, FFTComplex *exptab, ptrdiff_t stride); +;***************************************************************************************** %macro FFT5 3 ; %1 - in_offset, %2 - dst1 (64bit used), %3 - dst2 VBROADCASTSD m0, [inq + %1] ; in[ 0].re, in[ 0].im, in[ 0].re, in[ 0].im movsd xm1, [inq + 1*16 + 8 + %1] ; in[ 3].re, in[ 3].im, 0, 0 @@ -103,9 +110,6 @@ SECTION .text movhps [%2q + strideq*4], xm1 %endmacro -;***************************************************************************************** -;void ff_fft15_avx(FFTComplex *out, FFTComplex *in, FFTComplex *exptab, ptrdiff_t stride); -;***************************************************************************************** INIT_YMM avx cglobal fft15, 4, 6, 14, out, in, exptab, stride, stride3, stride5 %define out0q inq @@ -138,4 +142,83 @@ cglobal fft15, 4, 6, 14, out, in, exptab, stride, stride3, stride5 RET +%endif ; ARCH_X86_64 + +;******************************************************************************************************* +;void ff_mdct15_postreindex(FFTComplex *out, FFTComplex *in, FFTComplex *exp, int *lut, ptrdiff_t len8); +;******************************************************************************************************* +%macro LUT_LOAD_4D 3 + mov r4d, [lutq + %3q*4 + 0] + movsd xmm%1, [inq + r4q*8] + mov r4d, [lutq + %3q*4 + 4] + movhps xmm%1, [inq + r4q*8] +%if cpuflag(avx2) + mov r4d, [lutq + %3q*4 + 8] + movsd %2, [inq + r4q*8] + mov r4d, [lutq + %3q*4 + 12] + movhps %2, [inq + r4q*8] + vinsertf128 %1, %1, %2, 1 +%endif +%endmacro + +%macro POSTROTATE_FN 1 +cglobal mdct15_postreindex, 5, 7, 8 + cpuflag(avx2)*2, out, in, exp, lut, len8, offset_p, offset_n + + xor offset_nq, offset_nq + lea offset_pq, [len8q*2 - %1] + + movaps m7, [sign_adjust_r] + +%if cpuflag(avx2) + movaps m8, [perm_pos] + movaps m9, [perm_neg] +%endif + +.loop: + movups m0, [expq + offset_pq*8] ; exp[p0].re, exp[p0].im, exp[p1].re, exp[p1].im, exp[p2].re, exp[p2].im, exp[p3].re, exp[p3].im + movups m1, [expq + offset_nq*8] ; exp[n3].re, exp[n3].im, exp[n2].re, exp[n2].im, exp[n1].re, exp[n1].im, exp[n0].re, exp[n0].im + + LUT_LOAD_4D m3, xm4, offset_p ; in[p0].re, in[p0].im, in[p1].re, in[p1].im, in[p2].re, in[p2].im, in[p3].re, in[p3].im + LUT_LOAD_4D m4, xm5, offset_n ; in[n3].re, in[n3].im, in[n2].re, in[n2].im, in[n1].re, in[n1].im, in[n0].re, in[n0].im + + mulps m5, m3, m0 ; in[p].reim * exp[p].reim + mulps m6, m4, m1 ; in[n].reim * exp[n].reim + + xorps m5, m7 ; in[p].re *= -1, in[p].im *= 1 + xorps m6, m7 ; in[n].re *= -1, in[n].im *= 1 + + shufps m3, m3, m3, q2301 ; in[p].imre + shufps m4, m4, m4, q2301 ; in[n].imre + + mulps m3, m0 ; in[p].imre * exp[p].reim + mulps m4, m1 ; in[n].imre * exp[n].reim + + haddps m3, m6 ; out[n0].im, out[n1].im, out[n3].re, out[n2].re, out[n2].im, out[n3].im, out[n1].re, out[n0].re + haddps m5, m4 ; out[p0].re, out[p1].re, out[p3].im, out[p2].im, out[p2].re, out[p3].re, out[p1].im, out[p0].im + +%if cpuflag(avx2) + vpermps m3, m9, m3 ; out[n3].im, out[n3].re, out[n2].im, out[n2].re, out[n1].im, out[n1].re, out[n0].im, out[n0].re + vpermps m5, m8, m5 ; out[p0].re, out[p0].im, out[p1].re, out[p1].im, out[p2].re, out[p2].im, out[p3].re, out[p3].im +%else + shufps m3, m3, m3, q0312 + shufps m5, m5, m5, q2130 +%endif + + movups [outq + offset_nq*8], m3 + movups [outq + offset_pq*8], m5 + + sub offset_pq, %1 + add offset_nq, %1 + cmp offset_nq, offset_pq + jle .loop + + REP_RET +%endmacro + +INIT_XMM sse3 +POSTROTATE_FN 2 + +%if ARCH_X86_64 && HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +POSTROTATE_FN 4 %endif diff --git a/libavcodec/x86/mdct15_init.c b/libavcodec/x86/mdct15_init.c index ba3d94c2ec751..45b91b7e212da 100644 --- a/libavcodec/x86/mdct15_init.c +++ b/libavcodec/x86/mdct15_init.c @@ -25,6 +25,9 @@ #include "libavutil/x86/cpu.h" #include "libavcodec/mdct15.h" +void ff_mdct15_postreindex_sse3(FFTComplex *out, FFTComplex *in, FFTComplex *exp, int *lut, ptrdiff_t len8); +void ff_mdct15_postreindex_avx2(FFTComplex *out, FFTComplex *in, FFTComplex *exp, int *lut, ptrdiff_t len8); + void ff_fft15_avx(FFTComplex *out, FFTComplex *in, FFTComplex *exptab, ptrdiff_t stride); static void perm_twiddles(MDCT15Context *s) @@ -85,11 +88,17 @@ av_cold void ff_mdct15_init_x86(MDCT15Context *s) int adjust_twiddles = 0; int cpu_flags = av_get_cpu_flags(); + if (EXTERNAL_SSE3(cpu_flags)) + s->postreindex = ff_mdct15_postreindex_sse3; + if (ARCH_X86_64 && EXTERNAL_AVX(cpu_flags)) { s->fft15 = ff_fft15_avx; adjust_twiddles = 1; } + if (ARCH_X86_64 && EXTERNAL_AVX2_FAST(cpu_flags)) + s->postreindex = ff_mdct15_postreindex_avx2; + if (adjust_twiddles) perm_twiddles(s); } From 1daacba91f7c8a29858fb2de58f8695f33308fa7 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Sun, 16 Jul 2017 17:03:50 +0200 Subject: [PATCH 2670/3374] Revert "Revert "lavfi/buffersrc: push the frame deeper if requested."" This reverts commit 04aa09c4bcf2d5a634a35da3a3ae3fc1abe30ef8 and reintroduces 0ff5567a30be6d7c804e95997ae282d6bacd76c3 that was temporarily reverted due to minor regressions. It also reverts e5bce8b4ce7b1f3a83998febdfa86a3771df96ce that fixed FATE refs. The fate-ffm change is caused by field_order now being set on the output format because the first frame arrives earlier. The fate-mxf change is assumed to be the same. --- libavfilter/buffersrc.c | 25 +++++++++++++++++++++++++ tests/ref/lavf/ffm | 2 +- tests/ref/lavf/mxf | 6 +++--- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c index 587b29b91a8f3..e8f59c2de71a3 100644 --- a/libavfilter/buffersrc.c +++ b/libavfilter/buffersrc.c @@ -173,6 +173,20 @@ int attribute_align_arg av_buffersrc_add_frame_flags(AVFilterContext *ctx, AVFra return ret; } +static int push_frame(AVFilterGraph *graph) +{ + int ret; + + while (1) { + ret = ff_filter_graph_run_once(graph); + if (ret == AVERROR(EAGAIN)) + break; + if (ret < 0) + return ret; + } + return 0; +} + static int av_buffersrc_add_frame_internal(AVFilterContext *ctx, AVFrame *frame, int flags) { @@ -185,6 +199,11 @@ static int av_buffersrc_add_frame_internal(AVFilterContext *ctx, if (!frame) { s->eof = 1; ff_avfilter_link_set_in_status(ctx->outputs[0], AVERROR_EOF, AV_NOPTS_VALUE); + if ((flags & AV_BUFFERSRC_FLAG_PUSH)) { + ret = push_frame(ctx->graph); + if (ret < 0) + return ret; + } return 0; } else if (s->eof) return AVERROR(EINVAL); @@ -239,6 +258,12 @@ static int av_buffersrc_add_frame_internal(AVFilterContext *ctx, if ((ret = ctx->output_pads[0].request_frame(ctx->outputs[0])) < 0) return ret; + if ((flags & AV_BUFFERSRC_FLAG_PUSH)) { + ret = push_frame(ctx->graph); + if (ret < 0) + return ret; + } + return 0; } diff --git a/tests/ref/lavf/ffm b/tests/ref/lavf/ffm index 54c56034aa0fe..d9fa8d52cbcf5 100644 --- a/tests/ref/lavf/ffm +++ b/tests/ref/lavf/ffm @@ -1,3 +1,3 @@ -a0e9616f0d9a8c1029f3220b1b9175f4 *./tests/data/lavf/lavf.ffm +ca2a450cd0d1e299514a345923b4c82a *./tests/data/lavf/lavf.ffm 376832 ./tests/data/lavf/lavf.ffm ./tests/data/lavf/lavf.ffm CRC=0x000e23ae diff --git a/tests/ref/lavf/mxf b/tests/ref/lavf/mxf index 9ab4432c6394e..48fe95a235661 100644 --- a/tests/ref/lavf/mxf +++ b/tests/ref/lavf/mxf @@ -1,9 +1,9 @@ -dbdbb7d8677dc29b0d90eedcf418ce13 *./tests/data/lavf/lavf.mxf +eaac3125ac1a61fe5f968c7af83fa71e *./tests/data/lavf/lavf.mxf 525369 ./tests/data/lavf/lavf.mxf ./tests/data/lavf/lavf.mxf CRC=0x8dddfaab -40fcb0a898f8825a17f5754b23762f49 *./tests/data/lavf/lavf.mxf +1562530330b13e9e70f522fe20265632 *./tests/data/lavf/lavf.mxf 560697 ./tests/data/lavf/lavf.mxf ./tests/data/lavf/lavf.mxf CRC=0xf21b1b48 -9233d192af20fc2a89304f5ae93c21ee *./tests/data/lavf/lavf.mxf +e07858715997313ae66a1cdd6fde5f66 *./tests/data/lavf/lavf.mxf 525369 ./tests/data/lavf/lavf.mxf ./tests/data/lavf/lavf.mxf CRC=0x8dddfaab From cffea1b4837bf09ffadd5dd2eca48e51cb9e69ff Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Sun, 16 Jul 2017 17:17:00 +0200 Subject: [PATCH 2671/3374] lavfi: copy framesync into framesync2. framesync2 will be the base for the version using activate. Most of the logic will be the same, but the code cannot be shared. Copying the file initially without change will make the diff easier to read. --- libavfilter/framesync2.c | 343 +++++++++++++++++++++++++++++++++++++++ libavfilter/framesync2.h | 297 +++++++++++++++++++++++++++++++++ 2 files changed, 640 insertions(+) create mode 100644 libavfilter/framesync2.c create mode 100644 libavfilter/framesync2.h diff --git a/libavfilter/framesync2.c b/libavfilter/framesync2.c new file mode 100644 index 0000000000000..eb05d66a86eb6 --- /dev/null +++ b/libavfilter/framesync2.c @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2013 Nicolas George + * + * 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 + */ + +#define FF_INTERNAL_FIELDS 1 +#include "framequeue.h" + +#include "libavutil/avassert.h" +#include "avfilter.h" +#include "bufferqueue.h" +#include "framesync.h" +#include "internal.h" + +#define OFFSET(member) offsetof(FFFrameSync, member) + +static const char *framesync_name(void *ptr) +{ + return "framesync"; +} + +static const AVClass framesync_class = { + .version = LIBAVUTIL_VERSION_INT, + .class_name = "framesync", + .item_name = framesync_name, + .category = AV_CLASS_CATEGORY_FILTER, + .option = NULL, + .parent_log_context_offset = OFFSET(parent), +}; + +enum { + STATE_BOF, + STATE_RUN, + STATE_EOF, +}; + +int ff_framesync_init(FFFrameSync *fs, void *parent, unsigned nb_in) +{ + fs->class = &framesync_class; + fs->parent = parent; + fs->nb_in = nb_in; + + fs->in = av_calloc(nb_in, sizeof(*fs->in)); + if (!fs->in) + return AVERROR(ENOMEM); + return 0; +} + +static void framesync_sync_level_update(FFFrameSync *fs) +{ + unsigned i, level = 0; + + for (i = 0; i < fs->nb_in; i++) + if (fs->in[i].state != STATE_EOF) + level = FFMAX(level, fs->in[i].sync); + av_assert0(level <= fs->sync_level); + if (level < fs->sync_level) + av_log(fs, AV_LOG_VERBOSE, "Sync level %u\n", level); + if (level) + fs->sync_level = level; + else + fs->eof = 1; +} + +int ff_framesync_configure(FFFrameSync *fs) +{ + unsigned i; + int64_t gcd, lcm; + + if (!fs->time_base.num) { + for (i = 0; i < fs->nb_in; i++) { + if (fs->in[i].sync) { + if (fs->time_base.num) { + gcd = av_gcd(fs->time_base.den, fs->in[i].time_base.den); + lcm = (fs->time_base.den / gcd) * fs->in[i].time_base.den; + if (lcm < AV_TIME_BASE / 2) { + fs->time_base.den = lcm; + fs->time_base.num = av_gcd(fs->time_base.num, + fs->in[i].time_base.num); + } else { + fs->time_base.num = 1; + fs->time_base.den = AV_TIME_BASE; + break; + } + } else { + fs->time_base = fs->in[i].time_base; + } + } + } + if (!fs->time_base.num) { + av_log(fs, AV_LOG_ERROR, "Impossible to set time base\n"); + return AVERROR(EINVAL); + } + av_log(fs, AV_LOG_VERBOSE, "Selected %d/%d time base\n", + fs->time_base.num, fs->time_base.den); + } + + for (i = 0; i < fs->nb_in; i++) + fs->in[i].pts = fs->in[i].pts_next = AV_NOPTS_VALUE; + fs->sync_level = UINT_MAX; + framesync_sync_level_update(fs); + + return 0; +} + +static void framesync_advance(FFFrameSync *fs) +{ + int latest; + unsigned i; + int64_t pts; + + if (fs->eof) + return; + while (!fs->frame_ready) { + latest = -1; + for (i = 0; i < fs->nb_in; i++) { + if (!fs->in[i].have_next) { + if (latest < 0 || fs->in[i].pts < fs->in[latest].pts) + latest = i; + } + } + if (latest >= 0) { + fs->in_request = latest; + break; + } + + pts = fs->in[0].pts_next; + for (i = 1; i < fs->nb_in; i++) + if (fs->in[i].pts_next < pts) + pts = fs->in[i].pts_next; + if (pts == INT64_MAX) { + fs->eof = 1; + break; + } + for (i = 0; i < fs->nb_in; i++) { + if (fs->in[i].pts_next == pts || + (fs->in[i].before == EXT_INFINITY && + fs->in[i].state == STATE_BOF)) { + av_frame_free(&fs->in[i].frame); + fs->in[i].frame = fs->in[i].frame_next; + fs->in[i].pts = fs->in[i].pts_next; + fs->in[i].frame_next = NULL; + fs->in[i].pts_next = AV_NOPTS_VALUE; + fs->in[i].have_next = 0; + fs->in[i].state = fs->in[i].frame ? STATE_RUN : STATE_EOF; + if (fs->in[i].sync == fs->sync_level && fs->in[i].frame) + fs->frame_ready = 1; + if (fs->in[i].state == STATE_EOF && + fs->in[i].after == EXT_STOP) + fs->eof = 1; + } + } + if (fs->eof) + fs->frame_ready = 0; + if (fs->frame_ready) + for (i = 0; i < fs->nb_in; i++) + if ((fs->in[i].state == STATE_BOF && + fs->in[i].before == EXT_STOP)) + fs->frame_ready = 0; + fs->pts = pts; + } +} + +static int64_t framesync_pts_extrapolate(FFFrameSync *fs, unsigned in, + int64_t pts) +{ + /* Possible enhancement: use the link's frame rate */ + return pts + 1; +} + +static void framesync_inject_frame(FFFrameSync *fs, unsigned in, AVFrame *frame) +{ + int64_t pts; + + av_assert0(!fs->in[in].have_next); + if (frame) { + pts = av_rescale_q(frame->pts, fs->in[in].time_base, fs->time_base); + frame->pts = pts; + } else { + pts = fs->in[in].state != STATE_RUN || fs->in[in].after == EXT_INFINITY + ? INT64_MAX : framesync_pts_extrapolate(fs, in, fs->in[in].pts); + fs->in[in].sync = 0; + framesync_sync_level_update(fs); + } + fs->in[in].frame_next = frame; + fs->in[in].pts_next = pts; + fs->in[in].have_next = 1; +} + +int ff_framesync_add_frame(FFFrameSync *fs, unsigned in, AVFrame *frame) +{ + av_assert1(in < fs->nb_in); + if (!fs->in[in].have_next) + framesync_inject_frame(fs, in, frame); + else + ff_bufqueue_add(fs, &fs->in[in].queue, frame); + return 0; +} + +void ff_framesync_next(FFFrameSync *fs) +{ + unsigned i; + + av_assert0(!fs->frame_ready); + for (i = 0; i < fs->nb_in; i++) + if (!fs->in[i].have_next && fs->in[i].queue.available) + framesync_inject_frame(fs, i, ff_bufqueue_get(&fs->in[i].queue)); + fs->frame_ready = 0; + framesync_advance(fs); +} + +void ff_framesync_drop(FFFrameSync *fs) +{ + fs->frame_ready = 0; +} + +int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, + unsigned get) +{ + AVFrame *frame; + unsigned need_copy = 0, i; + int64_t pts_next; + int ret; + + if (!fs->in[in].frame) { + *rframe = NULL; + return 0; + } + frame = fs->in[in].frame; + if (get) { + /* Find out if we need to copy the frame: is there another sync + stream, and do we know if its current frame will outlast this one? */ + pts_next = fs->in[in].have_next ? fs->in[in].pts_next : INT64_MAX; + for (i = 0; i < fs->nb_in && !need_copy; i++) + if (i != in && fs->in[i].sync && + (!fs->in[i].have_next || fs->in[i].pts_next < pts_next)) + need_copy = 1; + if (need_copy) { + if (!(frame = av_frame_clone(frame))) + return AVERROR(ENOMEM); + if ((ret = av_frame_make_writable(frame)) < 0) { + av_frame_free(&frame); + return ret; + } + } else { + fs->in[in].frame = NULL; + } + fs->frame_ready = 0; + } + *rframe = frame; + return 0; +} + +void ff_framesync_uninit(FFFrameSync *fs) +{ + unsigned i; + + for (i = 0; i < fs->nb_in; i++) { + av_frame_free(&fs->in[i].frame); + av_frame_free(&fs->in[i].frame_next); + ff_bufqueue_discard_all(&fs->in[i].queue); + } + + av_freep(&fs->in); +} + +int ff_framesync_process_frame(FFFrameSync *fs, unsigned all) +{ + int ret, count = 0; + + av_assert0(fs->on_event); + while (1) { + ff_framesync_next(fs); + if (fs->eof || !fs->frame_ready) + break; + if ((ret = fs->on_event(fs)) < 0) + return ret; + ff_framesync_drop(fs); + count++; + if (!all) + break; + } + if (!count && fs->eof) + return AVERROR_EOF; + return count; +} + +int ff_framesync_filter_frame(FFFrameSync *fs, AVFilterLink *inlink, + AVFrame *in) +{ + int ret; + + if ((ret = ff_framesync_process_frame(fs, 1)) < 0) + return ret; + if ((ret = ff_framesync_add_frame(fs, FF_INLINK_IDX(inlink), in)) < 0) + return ret; + if ((ret = ff_framesync_process_frame(fs, 0)) < 0) + return ret; + return 0; +} + +int ff_framesync_request_frame(FFFrameSync *fs, AVFilterLink *outlink) +{ + AVFilterContext *ctx = outlink->src; + int input, ret, i; + + if ((ret = ff_framesync_process_frame(fs, 0)) < 0) + return ret; + if (ret > 0) + return 0; + if (fs->eof) + return AVERROR_EOF; + input = fs->in_request; + /* Detect status change early */ + for (i = 0; i < fs->nb_in; i++) + if (!ff_framequeue_queued_frames(&ctx->inputs[i]->fifo) && + ctx->inputs[i]->status_in && !ctx->inputs[i]->status_out) + input = i; + ret = ff_request_frame(ctx->inputs[input]); + if (ret == AVERROR_EOF) { + if ((ret = ff_framesync_add_frame(fs, input, NULL)) < 0) + return ret; + if ((ret = ff_framesync_process_frame(fs, 0)) < 0) + return ret; + ret = 0; + } + return ret; +} diff --git a/libavfilter/framesync2.h b/libavfilter/framesync2.h new file mode 100644 index 0000000000000..074d30394f1c7 --- /dev/null +++ b/libavfilter/framesync2.h @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2013 Nicolas George + * + * 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 + */ + +#ifndef AVFILTER_FRAMESYNC2_H +#define AVFILTER_FRAMESYNC2_H + +#include "bufferqueue.h" + +/* + * TODO + * Callback-based API similar to dualinput. + * Export convenient options. + */ + +/** + * This API is intended as a helper for filters that have several video + * input and need to combine them somehow. If the inputs have different or + * variable frame rate, getting the input frames to match requires a rather + * complex logic and a few user-tunable options. + * + * In this API, when a set of synchronized input frames is ready to be + * procesed is called a frame event. Frame event can be generated in + * response to input frames on any or all inputs and the handling of + * situations where some stream extend beyond the beginning or the end of + * others can be configured. + * + * The basic working of this API is the following: + * + * - When a frame is available on any input, add it using + * ff_framesync_add_frame(). + * + * - When a frame event is ready to be processed (i.e. after adding a frame + * or when requested on input): + * - call ff_framesync_next(); + * - if fs->frame_ready is true, process the frames; + * - call ff_framesync_drop(). + */ + +/** + * Stream extrapolation mode + * + * Describe how the frames of a stream are extrapolated before the first one + * and after EOF to keep sync with possibly longer other streams. + */ +enum FFFrameSyncExtMode { + + /** + * Completely stop all streams with this one. + */ + EXT_STOP, + + /** + * Ignore this stream and continue processing the other ones. + */ + EXT_NULL, + + /** + * Extend the frame to infinity. + */ + EXT_INFINITY, +}; + +/** + * Input stream structure + */ +typedef struct FFFrameSyncIn { + + /** + * Queue of incoming AVFrame, and NULL to mark EOF + */ + struct FFBufQueue queue; + + /** + * Extrapolation mode for timestamps before the first frame + */ + enum FFFrameSyncExtMode before; + + /** + * Extrapolation mode for timestamps after the last frame + */ + enum FFFrameSyncExtMode after; + + /** + * Time base for the incoming frames + */ + AVRational time_base; + + /** + * Current frame, may be NULL before the first one or after EOF + */ + AVFrame *frame; + + /** + * Next frame, for internal use + */ + AVFrame *frame_next; + + /** + * PTS of the current frame + */ + int64_t pts; + + /** + * PTS of the next frame, for internal use + */ + int64_t pts_next; + + /** + * Boolean flagging the next frame, for internal use + */ + uint8_t have_next; + + /** + * State: before first, in stream or after EOF, for internal use + */ + uint8_t state; + + /** + * Synchronization level: frames on input at the highest sync level will + * generate output frame events. + * + * For example, if inputs #0 and #1 have sync level 2 and input #2 has + * sync level 1, then a frame on either input #0 or #1 will generate a + * frame event, but not a frame on input #2 until both inputs #0 and #1 + * have reached EOF. + * + * If sync is 0, no frame event will be generated. + */ + unsigned sync; + +} FFFrameSyncIn; + +/** + * Frame sync structure. + */ +typedef struct FFFrameSync { + const AVClass *class; + void *parent; + + /** + * Number of input streams + */ + unsigned nb_in; + + /** + * Time base for the output events + */ + AVRational time_base; + + /** + * Timestamp of the current event + */ + int64_t pts; + + /** + * Callback called when a frame event is ready + */ + int (*on_event)(struct FFFrameSync *fs); + + /** + * Opaque pointer, not used by the API + */ + void *opaque; + + /** + * Index of the input that requires a request + */ + unsigned in_request; + + /** + * Synchronization level: only inputs with the same sync level are sync + * sources. + */ + unsigned sync_level; + + /** + * Flag indicating that a frame event is ready + */ + uint8_t frame_ready; + + /** + * Flag indicating that output has reached EOF. + */ + uint8_t eof; + + /** + * Pointer to array of inputs. + */ + FFFrameSyncIn *in; + +} FFFrameSync; + +/** + * Initialize a frame sync structure. + * + * The entire structure is expected to be already set to 0. + * + * @param fs frame sync structure to initialize + * @param parent parent object, used for logging + * @param nb_in number of inputs + * @return >= 0 for success or a negative error code + */ +int ff_framesync_init(FFFrameSync *fs, void *parent, unsigned nb_in); + +/** + * Configure a frame sync structure. + * + * Must be called after all options are set but before all use. + * + * @return >= 0 for success or a negative error code + */ +int ff_framesync_configure(FFFrameSync *fs); + +/** + * Free all memory currently allocated. + */ +void ff_framesync_uninit(FFFrameSync *fs); + +/** + * Add a frame to an input + * + * Typically called from the filter_frame() method. + * + * @param fs frame sync structure + * @param in index of the input + * @param frame input frame, or NULL for EOF + */ +int ff_framesync_add_frame(FFFrameSync *fs, unsigned in, AVFrame *frame); + +/** + * Prepare the next frame event. + * + * The status of the operation can be found in fs->frame_ready and fs->eof. + */ +void ff_framesync_next(FFFrameSync *fs); + +/** + * Drop the current frame event. + */ +void ff_framesync_drop(FFFrameSync *fs); + +/** + * Get the current frame in an input. + * + * @param fs frame sync structure + * @param in index of the input + * @param rframe used to return the current frame (or NULL) + * @param get if not zero, the calling code needs to get ownership of + * the returned frame; the current frame will either be + * duplicated or removed from the framesync structure + */ +int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, + unsigned get); + +/** + * Process one or several frame using the on_event callback. + * + * @return number of frames processed or negative error code + */ +int ff_framesync_process_frame(FFFrameSync *fs, unsigned all); + + +/** + * Accept a frame on a filter input. + * + * This function can be the complete implementation of all filter_frame + * methods of a filter using framesync. + */ +int ff_framesync_filter_frame(FFFrameSync *fs, AVFilterLink *inlink, + AVFrame *in); + +/** + * Request a frame on the filter output. + * + * This function can be the complete implementation of all filter_frame + * methods of a filter using framesync if it has only one output. + */ +int ff_framesync_request_frame(FFFrameSync *fs, AVFilterLink *outlink); + +#endif /* AVFILTER_FRAMESYNC2_H */ From 873306f265de255f9ef30a77b3e9b8c33d16dab8 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Sun, 16 Jul 2017 17:26:48 +0200 Subject: [PATCH 2672/3374] lavfi/framesync2: rename all conflicting symbols. --- libavfilter/framesync2.c | 42 ++++++++++++++++++++-------------------- libavfilter/framesync2.h | 30 ++++++++++++++-------------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/libavfilter/framesync2.c b/libavfilter/framesync2.c index eb05d66a86eb6..8d81bb5c487e9 100644 --- a/libavfilter/framesync2.c +++ b/libavfilter/framesync2.c @@ -24,7 +24,7 @@ #include "libavutil/avassert.h" #include "avfilter.h" #include "bufferqueue.h" -#include "framesync.h" +#include "framesync2.h" #include "internal.h" #define OFFSET(member) offsetof(FFFrameSync, member) @@ -49,7 +49,7 @@ enum { STATE_EOF, }; -int ff_framesync_init(FFFrameSync *fs, void *parent, unsigned nb_in) +int ff_framesync2_init(FFFrameSync *fs, void *parent, unsigned nb_in) { fs->class = &framesync_class; fs->parent = parent; @@ -77,7 +77,7 @@ static void framesync_sync_level_update(FFFrameSync *fs) fs->eof = 1; } -int ff_framesync_configure(FFFrameSync *fs) +int ff_framesync2_configure(FFFrameSync *fs) { unsigned i; int64_t gcd, lcm; @@ -202,7 +202,7 @@ static void framesync_inject_frame(FFFrameSync *fs, unsigned in, AVFrame *frame) fs->in[in].have_next = 1; } -int ff_framesync_add_frame(FFFrameSync *fs, unsigned in, AVFrame *frame) +int ff_framesync2_add_frame(FFFrameSync *fs, unsigned in, AVFrame *frame) { av_assert1(in < fs->nb_in); if (!fs->in[in].have_next) @@ -212,7 +212,7 @@ int ff_framesync_add_frame(FFFrameSync *fs, unsigned in, AVFrame *frame) return 0; } -void ff_framesync_next(FFFrameSync *fs) +void ff_framesync2_next(FFFrameSync *fs) { unsigned i; @@ -224,13 +224,13 @@ void ff_framesync_next(FFFrameSync *fs) framesync_advance(fs); } -void ff_framesync_drop(FFFrameSync *fs) +void ff_framesync2_drop(FFFrameSync *fs) { fs->frame_ready = 0; } -int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, - unsigned get) +int ff_framesync2_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, + unsigned get) { AVFrame *frame; unsigned need_copy = 0, i; @@ -266,7 +266,7 @@ int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, return 0; } -void ff_framesync_uninit(FFFrameSync *fs) +void ff_framesync2_uninit(FFFrameSync *fs) { unsigned i; @@ -279,18 +279,18 @@ void ff_framesync_uninit(FFFrameSync *fs) av_freep(&fs->in); } -int ff_framesync_process_frame(FFFrameSync *fs, unsigned all) +int ff_framesync2_process_frame(FFFrameSync *fs, unsigned all) { int ret, count = 0; av_assert0(fs->on_event); while (1) { - ff_framesync_next(fs); + ff_framesync2_next(fs); if (fs->eof || !fs->frame_ready) break; if ((ret = fs->on_event(fs)) < 0) return ret; - ff_framesync_drop(fs); + ff_framesync2_drop(fs); count++; if (!all) break; @@ -300,26 +300,26 @@ int ff_framesync_process_frame(FFFrameSync *fs, unsigned all) return count; } -int ff_framesync_filter_frame(FFFrameSync *fs, AVFilterLink *inlink, - AVFrame *in) +int ff_framesync2_filter_frame(FFFrameSync *fs, AVFilterLink *inlink, + AVFrame *in) { int ret; - if ((ret = ff_framesync_process_frame(fs, 1)) < 0) + if ((ret = ff_framesync2_process_frame(fs, 1)) < 0) return ret; - if ((ret = ff_framesync_add_frame(fs, FF_INLINK_IDX(inlink), in)) < 0) + if ((ret = ff_framesync2_add_frame(fs, FF_INLINK_IDX(inlink), in)) < 0) return ret; - if ((ret = ff_framesync_process_frame(fs, 0)) < 0) + if ((ret = ff_framesync2_process_frame(fs, 0)) < 0) return ret; return 0; } -int ff_framesync_request_frame(FFFrameSync *fs, AVFilterLink *outlink) +int ff_framesync2_request_frame(FFFrameSync *fs, AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; int input, ret, i; - if ((ret = ff_framesync_process_frame(fs, 0)) < 0) + if ((ret = ff_framesync2_process_frame(fs, 0)) < 0) return ret; if (ret > 0) return 0; @@ -333,9 +333,9 @@ int ff_framesync_request_frame(FFFrameSync *fs, AVFilterLink *outlink) input = i; ret = ff_request_frame(ctx->inputs[input]); if (ret == AVERROR_EOF) { - if ((ret = ff_framesync_add_frame(fs, input, NULL)) < 0) + if ((ret = ff_framesync2_add_frame(fs, input, NULL)) < 0) return ret; - if ((ret = ff_framesync_process_frame(fs, 0)) < 0) + if ((ret = ff_framesync2_process_frame(fs, 0)) < 0) return ret; ret = 0; } diff --git a/libavfilter/framesync2.h b/libavfilter/framesync2.h index 074d30394f1c7..e19d0f37e8b74 100644 --- a/libavfilter/framesync2.h +++ b/libavfilter/framesync2.h @@ -44,13 +44,13 @@ * The basic working of this API is the following: * * - When a frame is available on any input, add it using - * ff_framesync_add_frame(). + * ff_framesync2_add_frame(). * * - When a frame event is ready to be processed (i.e. after adding a frame * or when requested on input): - * - call ff_framesync_next(); + * - call ff_framesync2_next(); * - if fs->frame_ready is true, process the frames; - * - call ff_framesync_drop(). + * - call ff_framesync2_drop(). */ /** @@ -217,7 +217,7 @@ typedef struct FFFrameSync { * @param nb_in number of inputs * @return >= 0 for success or a negative error code */ -int ff_framesync_init(FFFrameSync *fs, void *parent, unsigned nb_in); +int ff_framesync2_init(FFFrameSync *fs, void *parent, unsigned nb_in); /** * Configure a frame sync structure. @@ -226,12 +226,12 @@ int ff_framesync_init(FFFrameSync *fs, void *parent, unsigned nb_in); * * @return >= 0 for success or a negative error code */ -int ff_framesync_configure(FFFrameSync *fs); +int ff_framesync2_configure(FFFrameSync *fs); /** * Free all memory currently allocated. */ -void ff_framesync_uninit(FFFrameSync *fs); +void ff_framesync2_uninit(FFFrameSync *fs); /** * Add a frame to an input @@ -242,19 +242,19 @@ void ff_framesync_uninit(FFFrameSync *fs); * @param in index of the input * @param frame input frame, or NULL for EOF */ -int ff_framesync_add_frame(FFFrameSync *fs, unsigned in, AVFrame *frame); +int ff_framesync2_add_frame(FFFrameSync *fs, unsigned in, AVFrame *frame); /** * Prepare the next frame event. * * The status of the operation can be found in fs->frame_ready and fs->eof. */ -void ff_framesync_next(FFFrameSync *fs); +void ff_framesync2_next(FFFrameSync *fs); /** * Drop the current frame event. */ -void ff_framesync_drop(FFFrameSync *fs); +void ff_framesync2_drop(FFFrameSync *fs); /** * Get the current frame in an input. @@ -266,15 +266,15 @@ void ff_framesync_drop(FFFrameSync *fs); * the returned frame; the current frame will either be * duplicated or removed from the framesync structure */ -int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, - unsigned get); +int ff_framesync2_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, + unsigned get); /** * Process one or several frame using the on_event callback. * * @return number of frames processed or negative error code */ -int ff_framesync_process_frame(FFFrameSync *fs, unsigned all); +int ff_framesync2_process_frame(FFFrameSync *fs, unsigned all); /** @@ -283,8 +283,8 @@ int ff_framesync_process_frame(FFFrameSync *fs, unsigned all); * This function can be the complete implementation of all filter_frame * methods of a filter using framesync. */ -int ff_framesync_filter_frame(FFFrameSync *fs, AVFilterLink *inlink, - AVFrame *in); +int ff_framesync2_filter_frame(FFFrameSync *fs, AVFilterLink *inlink, + AVFrame *in); /** * Request a frame on the filter output. @@ -292,6 +292,6 @@ int ff_framesync_filter_frame(FFFrameSync *fs, AVFilterLink *inlink, * This function can be the complete implementation of all filter_frame * methods of a filter using framesync if it has only one output. */ -int ff_framesync_request_frame(FFFrameSync *fs, AVFilterLink *outlink); +int ff_framesync2_request_frame(FFFrameSync *fs, AVFilterLink *outlink); #endif /* AVFILTER_FRAMESYNC2_H */ From b77f041dff5f669d1d297697a34023de1c33a33f Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 17 Jul 2017 14:33:11 +0200 Subject: [PATCH 2673/3374] lavfi: make FFERROR_NOT_READY available to filters. I am not entirely sure that this return code is useful, but having and using it makes no harm. --- libavfilter/avfilter.c | 2 -- libavfilter/filters.h | 5 +++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index e60b0247bce69..185ba8df00a3a 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -1304,8 +1304,6 @@ static int forward_status_change(AVFilterContext *filter, AVFilterLink *in) return 0; } -#define FFERROR_NOT_READY FFERRTAG('N','R','D','Y') - static int ff_filter_activate_default(AVFilterContext *filter) { unsigned i; diff --git a/libavfilter/filters.h b/libavfilter/filters.h index 2c78d60e62f48..370d99b38be3f 100644 --- a/libavfilter/filters.h +++ b/libavfilter/filters.h @@ -27,6 +27,11 @@ #include "avfilter.h" +/** + * Special return code when activate() did not do anything. + */ +#define FFERROR_NOT_READY FFERRTAG('N','R','D','Y') + /** * Mark a filter ready and schedule it for activation. * From ed1c884b9e0d7f63199d5d47350b1fa65374d126 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 17 Jul 2017 14:34:41 +0200 Subject: [PATCH 2674/3374] lavfi: add outlink helper functions. These wrappers cost nothing, they make the namespace more consistent and they will be useful if/when locking becomes necessary. --- libavfilter/filters.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/libavfilter/filters.h b/libavfilter/filters.h index 370d99b38be3f..1cbc18158fcfe 100644 --- a/libavfilter/filters.h +++ b/libavfilter/filters.h @@ -26,6 +26,7 @@ */ #include "avfilter.h" +#include "internal.h" /** * Special return code when activate() did not do anything. @@ -139,4 +140,24 @@ int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts */ void ff_inlink_request_frame(AVFilterLink *link); +/** + * Test if a frame is wanted on an output link. + */ +static inline int ff_outlink_frame_wanted(AVFilterLink *link) +{ + return link->frame_wanted_out; +} + +/** + * Set the status field of a link from the source filter. + * The pts should reflect the timestamp of the status change, + * in link time base and relative to the frames timeline. + * In particular, for AVERROR_EOF, it should reflect the + * end time of the last frame. + */ +static inline void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts) +{ + ff_avfilter_link_set_in_status(link, status, pts); +} + #endif /* AVFILTER_FILTERS_H */ From 4e0e9ce2dc67a94c98d40a46e91fe5aa53ad0376 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 17 Jul 2017 14:36:42 +0200 Subject: [PATCH 2675/3374] lavfi/framesync2: implement "activate" design. With this helper API, filters that used the first framesync helper API can easily be changed to use the new and more extensible design for filters with a single activate() callback. --- libavfilter/framesync2.c | 166 ++++++++++++++++----------------------- libavfilter/framesync2.h | 77 ++++-------------- 2 files changed, 82 insertions(+), 161 deletions(-) diff --git a/libavfilter/framesync2.c b/libavfilter/framesync2.c index 8d81bb5c487e9..0e9f6f210c6ef 100644 --- a/libavfilter/framesync2.c +++ b/libavfilter/framesync2.c @@ -18,12 +18,9 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define FF_INTERNAL_FIELDS 1 -#include "framequeue.h" - #include "libavutil/avassert.h" #include "avfilter.h" -#include "bufferqueue.h" +#include "filters.h" #include "framesync2.h" #include "internal.h" @@ -49,8 +46,13 @@ enum { STATE_EOF, }; -int ff_framesync2_init(FFFrameSync *fs, void *parent, unsigned nb_in) +int ff_framesync2_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in) { + /* For filters with several outputs, we will not be able to assume which + output is relevant for ff_outlink_frame_wanted() and + ff_outlink_set_status(). To be designed when needed. */ + av_assert0(parent->nb_outputs == 1); + fs->class = &framesync_class; fs->parent = parent; fs->nb_in = nb_in; @@ -61,6 +63,13 @@ int ff_framesync2_init(FFFrameSync *fs, void *parent, unsigned nb_in) return 0; } +static void framesync_eof(FFFrameSync *fs) +{ + fs->eof = 1; + fs->frame_ready = 0; + ff_outlink_set_status(fs->parent->outputs[0], AVERROR_EOF, AV_NOPTS_VALUE); +} + static void framesync_sync_level_update(FFFrameSync *fs) { unsigned i, level = 0; @@ -74,7 +83,7 @@ static void framesync_sync_level_update(FFFrameSync *fs) if (level) fs->sync_level = level; else - fs->eof = 1; + framesync_eof(fs); } int ff_framesync2_configure(FFFrameSync *fs) @@ -144,7 +153,7 @@ static void framesync_advance(FFFrameSync *fs) if (fs->in[i].pts_next < pts) pts = fs->in[i].pts_next; if (pts == INT64_MAX) { - fs->eof = 1; + framesync_eof(fs); break; } for (i = 0; i < fs->nb_in; i++) { @@ -162,11 +171,9 @@ static void framesync_advance(FFFrameSync *fs) fs->frame_ready = 1; if (fs->in[i].state == STATE_EOF && fs->in[i].after == EXT_STOP) - fs->eof = 1; + framesync_eof(fs); } } - if (fs->eof) - fs->frame_ready = 0; if (fs->frame_ready) for (i = 0; i < fs->nb_in; i++) if ((fs->in[i].state == STATE_BOF && @@ -188,45 +195,24 @@ static void framesync_inject_frame(FFFrameSync *fs, unsigned in, AVFrame *frame) int64_t pts; av_assert0(!fs->in[in].have_next); - if (frame) { - pts = av_rescale_q(frame->pts, fs->in[in].time_base, fs->time_base); - frame->pts = pts; - } else { - pts = fs->in[in].state != STATE_RUN || fs->in[in].after == EXT_INFINITY - ? INT64_MAX : framesync_pts_extrapolate(fs, in, fs->in[in].pts); - fs->in[in].sync = 0; - framesync_sync_level_update(fs); - } + av_assert0(frame); + pts = av_rescale_q(frame->pts, fs->in[in].time_base, fs->time_base); + frame->pts = pts; fs->in[in].frame_next = frame; fs->in[in].pts_next = pts; fs->in[in].have_next = 1; } -int ff_framesync2_add_frame(FFFrameSync *fs, unsigned in, AVFrame *frame) -{ - av_assert1(in < fs->nb_in); - if (!fs->in[in].have_next) - framesync_inject_frame(fs, in, frame); - else - ff_bufqueue_add(fs, &fs->in[in].queue, frame); - return 0; -} - -void ff_framesync2_next(FFFrameSync *fs) -{ - unsigned i; - - av_assert0(!fs->frame_ready); - for (i = 0; i < fs->nb_in; i++) - if (!fs->in[i].have_next && fs->in[i].queue.available) - framesync_inject_frame(fs, i, ff_bufqueue_get(&fs->in[i].queue)); - fs->frame_ready = 0; - framesync_advance(fs); -} - -void ff_framesync2_drop(FFFrameSync *fs) +static void framesync_inject_status(FFFrameSync *fs, unsigned in, int status, int64_t pts) { - fs->frame_ready = 0; + av_assert0(!fs->in[in].have_next); + pts = fs->in[in].state != STATE_RUN || fs->in[in].after == EXT_INFINITY + ? INT64_MAX : framesync_pts_extrapolate(fs, in, fs->in[in].pts); + fs->in[in].sync = 0; + framesync_sync_level_update(fs); + fs->in[in].frame_next = NULL; + fs->in[in].pts_next = pts; + fs->in[in].have_next = 1; } int ff_framesync2_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, @@ -273,71 +259,55 @@ void ff_framesync2_uninit(FFFrameSync *fs) for (i = 0; i < fs->nb_in; i++) { av_frame_free(&fs->in[i].frame); av_frame_free(&fs->in[i].frame_next); - ff_bufqueue_discard_all(&fs->in[i].queue); } av_freep(&fs->in); } -int ff_framesync2_process_frame(FFFrameSync *fs, unsigned all) +int ff_framesync2_activate(FFFrameSync *fs) { - int ret, count = 0; + AVFilterContext *ctx = fs->parent; + AVFrame *frame = NULL; + int64_t pts; + unsigned i, nb_active, nb_miss; + int ret, status; - av_assert0(fs->on_event); - while (1) { - ff_framesync2_next(fs); - if (fs->eof || !fs->frame_ready) - break; - if ((ret = fs->on_event(fs)) < 0) + nb_active = nb_miss = 0; + for (i = 0; i < fs->nb_in; i++) { + if (fs->in[i].have_next || fs->in[i].state == STATE_EOF) + continue; + nb_active++; + ret = ff_inlink_consume_frame(ctx->inputs[i], &frame); + if (ret < 0) return ret; - ff_framesync2_drop(fs); - count++; - if (!all) - break; + if (ret) { + av_assert0(frame); + framesync_inject_frame(fs, i, frame); + } else { + ret = ff_inlink_acknowledge_status(ctx->inputs[i], &status, &pts); + if (ret > 0) { + framesync_inject_status(fs, i, status, pts); + } else if (!ret) { + nb_miss++; + } + } + } + if (nb_miss) { + if (nb_miss == nb_active && !ff_outlink_frame_wanted(ctx->outputs[0])) + return FFERROR_NOT_READY; + for (i = 0; i < fs->nb_in; i++) + if (!fs->in[i].have_next && fs->in[i].state != STATE_EOF) + ff_inlink_request_frame(ctx->inputs[i]); + return 0; } - if (!count && fs->eof) - return AVERROR_EOF; - return count; -} - -int ff_framesync2_filter_frame(FFFrameSync *fs, AVFilterLink *inlink, - AVFrame *in) -{ - int ret; - if ((ret = ff_framesync2_process_frame(fs, 1)) < 0) - return ret; - if ((ret = ff_framesync2_add_frame(fs, FF_INLINK_IDX(inlink), in)) < 0) - return ret; - if ((ret = ff_framesync2_process_frame(fs, 0)) < 0) + framesync_advance(fs); + if (fs->eof || !fs->frame_ready) + return 0; + ret = fs->on_event(fs); + if (ret < 0) return ret; - return 0; -} - -int ff_framesync2_request_frame(FFFrameSync *fs, AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - int input, ret, i; + fs->frame_ready = 0; - if ((ret = ff_framesync2_process_frame(fs, 0)) < 0) - return ret; - if (ret > 0) - return 0; - if (fs->eof) - return AVERROR_EOF; - input = fs->in_request; - /* Detect status change early */ - for (i = 0; i < fs->nb_in; i++) - if (!ff_framequeue_queued_frames(&ctx->inputs[i]->fifo) && - ctx->inputs[i]->status_in && !ctx->inputs[i]->status_out) - input = i; - ret = ff_request_frame(ctx->inputs[input]); - if (ret == AVERROR_EOF) { - if ((ret = ff_framesync2_add_frame(fs, input, NULL)) < 0) - return ret; - if ((ret = ff_framesync2_process_frame(fs, 0)) < 0) - return ret; - ret = 0; - } - return ret; + return 0; } diff --git a/libavfilter/framesync2.h b/libavfilter/framesync2.h index e19d0f37e8b74..2b37636ebba11 100644 --- a/libavfilter/framesync2.h +++ b/libavfilter/framesync2.h @@ -25,7 +25,6 @@ /* * TODO - * Callback-based API similar to dualinput. * Export convenient options. */ @@ -41,16 +40,9 @@ * situations where some stream extend beyond the beginning or the end of * others can be configured. * - * The basic working of this API is the following: - * - * - When a frame is available on any input, add it using - * ff_framesync2_add_frame(). - * - * - When a frame event is ready to be processed (i.e. after adding a frame - * or when requested on input): - * - call ff_framesync2_next(); - * - if fs->frame_ready is true, process the frames; - * - call ff_framesync2_drop(). + * The basic working of this API is the following: set the on_event + * callback, then call ff_framesync2_activate() from the filter's activate + * callback. */ /** @@ -82,11 +74,6 @@ enum FFFrameSyncExtMode { */ typedef struct FFFrameSyncIn { - /** - * Queue of incoming AVFrame, and NULL to mark EOF - */ - struct FFBufQueue queue; - /** * Extrapolation mode for timestamps before the first frame */ @@ -152,7 +139,11 @@ typedef struct FFFrameSyncIn { */ typedef struct FFFrameSync { const AVClass *class; - void *parent; + + /** + * Parent filter context. + */ + AVFilterContext *parent; /** * Number of input streams @@ -213,11 +204,11 @@ typedef struct FFFrameSync { * The entire structure is expected to be already set to 0. * * @param fs frame sync structure to initialize - * @param parent parent object, used for logging + * @param parent parent AVFilterContext object * @param nb_in number of inputs * @return >= 0 for success or a negative error code */ -int ff_framesync2_init(FFFrameSync *fs, void *parent, unsigned nb_in); +int ff_framesync2_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in); /** * Configure a frame sync structure. @@ -233,29 +224,6 @@ int ff_framesync2_configure(FFFrameSync *fs); */ void ff_framesync2_uninit(FFFrameSync *fs); -/** - * Add a frame to an input - * - * Typically called from the filter_frame() method. - * - * @param fs frame sync structure - * @param in index of the input - * @param frame input frame, or NULL for EOF - */ -int ff_framesync2_add_frame(FFFrameSync *fs, unsigned in, AVFrame *frame); - -/** - * Prepare the next frame event. - * - * The status of the operation can be found in fs->frame_ready and fs->eof. - */ -void ff_framesync2_next(FFFrameSync *fs); - -/** - * Drop the current frame event. - */ -void ff_framesync2_drop(FFFrameSync *fs); - /** * Get the current frame in an input. * @@ -270,28 +238,11 @@ int ff_framesync2_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, unsigned get); /** - * Process one or several frame using the on_event callback. - * - * @return number of frames processed or negative error code - */ -int ff_framesync2_process_frame(FFFrameSync *fs, unsigned all); - - -/** - * Accept a frame on a filter input. - * - * This function can be the complete implementation of all filter_frame - * methods of a filter using framesync. - */ -int ff_framesync2_filter_frame(FFFrameSync *fs, AVFilterLink *inlink, - AVFrame *in); - -/** - * Request a frame on the filter output. + * Examine the frames in the filter's input and try to produce output. * - * This function can be the complete implementation of all filter_frame - * methods of a filter using framesync if it has only one output. + * This function can be the complete implementation of the activate + * method of a filter using framesync2. */ -int ff_framesync2_request_frame(FFFrameSync *fs, AVFilterLink *outlink); +int ff_framesync2_activate(FFFrameSync *fs); #endif /* AVFILTER_FRAMESYNC2_H */ From 0dd8320e16bcdbe6b928e99489cf47abd16d3255 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 17 Jul 2017 14:37:00 +0200 Subject: [PATCH 2676/3374] lavfi/vf_stack: move to "activate" design. --- libavfilter/Makefile | 4 ++-- libavfilter/vf_stack.c | 32 +++++++++++++------------------- 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index ee163613bedad..6f8e7b5ae14ba 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -202,7 +202,7 @@ OBJS-$(CONFIG_HISTEQ_FILTER) += vf_histeq.o OBJS-$(CONFIG_HISTOGRAM_FILTER) += vf_histogram.o OBJS-$(CONFIG_HQDN3D_FILTER) += vf_hqdn3d.o OBJS-$(CONFIG_HQX_FILTER) += vf_hqx.o -OBJS-$(CONFIG_HSTACK_FILTER) += vf_stack.o framesync.o +OBJS-$(CONFIG_HSTACK_FILTER) += vf_stack.o framesync2.o OBJS-$(CONFIG_HUE_FILTER) += vf_hue.o OBJS-$(CONFIG_HWDOWNLOAD_FILTER) += vf_hwdownload.o OBJS-$(CONFIG_HWMAP_FILTER) += vf_hwmap.o @@ -322,7 +322,7 @@ OBJS-$(CONFIG_VFLIP_FILTER) += vf_vflip.o OBJS-$(CONFIG_VIDSTABDETECT_FILTER) += vidstabutils.o vf_vidstabdetect.o OBJS-$(CONFIG_VIDSTABTRANSFORM_FILTER) += vidstabutils.o vf_vidstabtransform.o OBJS-$(CONFIG_VIGNETTE_FILTER) += vf_vignette.o -OBJS-$(CONFIG_VSTACK_FILTER) += vf_stack.o framesync.o +OBJS-$(CONFIG_VSTACK_FILTER) += vf_stack.o framesync2.o OBJS-$(CONFIG_W3FDIF_FILTER) += vf_w3fdif.o OBJS-$(CONFIG_WAVEFORM_FILTER) += vf_waveform.o OBJS-$(CONFIG_WEAVE_FILTER) += vf_weave.o diff --git a/libavfilter/vf_stack.c b/libavfilter/vf_stack.c index 03643b6f96011..fa8a02257e8c9 100644 --- a/libavfilter/vf_stack.c +++ b/libavfilter/vf_stack.c @@ -26,7 +26,7 @@ #include "avfilter.h" #include "formats.h" #include "internal.h" -#include "framesync.h" +#include "framesync2.h" #include "video.h" typedef struct StackContext { @@ -58,12 +58,6 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_formats(ctx, pix_fmts); } -static int filter_frame(AVFilterLink *inlink, AVFrame *in) -{ - StackContext *s = inlink->dst->priv; - return ff_framesync_filter_frame(&s->fs, inlink, in); -} - static av_cold int init(AVFilterContext *ctx) { StackContext *s = ctx->priv; @@ -83,7 +77,6 @@ static av_cold int init(AVFilterContext *ctx) pad.name = av_asprintf("input%d", i); if (!pad.name) return AVERROR(ENOMEM); - pad.filter_frame = filter_frame; if ((ret = ff_insert_inpad(ctx, i, &pad)) < 0) { av_freep(&pad.name); @@ -104,7 +97,7 @@ static int process_frame(FFFrameSync *fs) int i, p, ret, offset[4] = { 0 }; for (i = 0; i < s->nb_inputs; i++) { - if ((ret = ff_framesync_get_frame(&s->fs, i, &in[i], 0)) < 0) + if ((ret = ff_framesync2_get_frame(&s->fs, i, &in[i], 0)) < 0) return ret; } @@ -187,7 +180,7 @@ static int config_output(AVFilterLink *outlink) outlink->time_base = time_base; outlink->frame_rate = frame_rate; - if ((ret = ff_framesync_init(&s->fs, ctx, s->nb_inputs)) < 0) + if ((ret = ff_framesync2_init(&s->fs, ctx, s->nb_inputs)) < 0) return ret; in = s->fs.in; @@ -203,13 +196,7 @@ static int config_output(AVFilterLink *outlink) in[i].after = s->shortest ? EXT_STOP : EXT_INFINITY; } - return ff_framesync_configure(&s->fs); -} - -static int request_frame(AVFilterLink *outlink) -{ - StackContext *s = outlink->src->priv; - return ff_framesync_request_frame(&s->fs, outlink); + return ff_framesync2_configure(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) @@ -217,13 +204,19 @@ static av_cold void uninit(AVFilterContext *ctx) StackContext *s = ctx->priv; int i; - ff_framesync_uninit(&s->fs); + ff_framesync2_uninit(&s->fs); av_freep(&s->frames); for (i = 0; i < ctx->nb_inputs; i++) av_freep(&ctx->input_pads[i].name); } +static int activate(AVFilterContext *ctx) +{ + StackContext *s = ctx->priv; + return ff_framesync2_activate(&s->fs); +} + #define OFFSET(x) offsetof(StackContext, x) #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM static const AVOption stack_options[] = { @@ -237,7 +230,6 @@ static const AVFilterPad outputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_output, - .request_frame = request_frame, }, { NULL } }; @@ -256,6 +248,7 @@ AVFilter ff_vf_hstack = { .outputs = outputs, .init = init, .uninit = uninit, + .activate = activate, .flags = AVFILTER_FLAG_DYNAMIC_INPUTS, }; @@ -275,6 +268,7 @@ AVFilter ff_vf_vstack = { .outputs = outputs, .init = init, .uninit = uninit, + .activate = activate, .flags = AVFILTER_FLAG_DYNAMIC_INPUTS, }; From d07e25de763ef7c991bac99e9c05eb290869ed79 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 17 Jul 2017 16:29:35 +0200 Subject: [PATCH 2677/3374] lavfi/vf_threshold: move to "activate" design. Also fix missing dependency. --- libavfilter/Makefile | 2 +- libavfilter/vf_threshold.c | 34 ++++++++++++---------------------- 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 6f8e7b5ae14ba..b34272830e836 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -308,7 +308,7 @@ OBJS-$(CONFIG_SWAPRECT_FILTER) += vf_swaprect.o OBJS-$(CONFIG_SWAPUV_FILTER) += vf_swapuv.o OBJS-$(CONFIG_TBLEND_FILTER) += vf_blend.o dualinput.o framesync.o OBJS-$(CONFIG_TELECINE_FILTER) += vf_telecine.o -OBJS-$(CONFIG_THRESHOLD_FILTER) += vf_threshold.o +OBJS-$(CONFIG_THRESHOLD_FILTER) += vf_threshold.o framesync2.o OBJS-$(CONFIG_THUMBNAIL_FILTER) += vf_thumbnail.o OBJS-$(CONFIG_TILE_FILTER) += vf_tile.o OBJS-$(CONFIG_TINTERLACE_FILTER) += vf_tinterlace.o diff --git a/libavfilter/vf_threshold.c b/libavfilter/vf_threshold.c index 1cb4c9aab8acb..6a64f270fef49 100644 --- a/libavfilter/vf_threshold.c +++ b/libavfilter/vf_threshold.c @@ -28,7 +28,7 @@ #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "avfilter.h" -#include "framesync.h" +#include "framesync2.h" #include "internal.h" #include "video.h" @@ -96,10 +96,10 @@ static int process_frame(FFFrameSync *fs) AVFrame *out, *in, *threshold, *min, *max; int ret; - if ((ret = ff_framesync_get_frame(&s->fs, 0, &in, 0)) < 0 || - (ret = ff_framesync_get_frame(&s->fs, 1, &threshold, 0)) < 0 || - (ret = ff_framesync_get_frame(&s->fs, 2, &min, 0)) < 0 || - (ret = ff_framesync_get_frame(&s->fs, 3, &max, 0)) < 0) + if ((ret = ff_framesync2_get_frame(&s->fs, 0, &in, 0)) < 0 || + (ret = ff_framesync2_get_frame(&s->fs, 1, &threshold, 0)) < 0 || + (ret = ff_framesync2_get_frame(&s->fs, 2, &min, 0)) < 0 || + (ret = ff_framesync2_get_frame(&s->fs, 3, &max, 0)) < 0) return ret; if (ctx->is_disabled) { @@ -256,7 +256,7 @@ static int config_output(AVFilterLink *outlink) outlink->sample_aspect_ratio = base->sample_aspect_ratio; outlink->frame_rate = base->frame_rate; - if ((ret = ff_framesync_init(&s->fs, ctx, 4)) < 0) + if ((ret = ff_framesync2_init(&s->fs, ctx, 4)) < 0) return ret; in = s->fs.in; @@ -279,49 +279,39 @@ static int config_output(AVFilterLink *outlink) s->fs.opaque = s; s->fs.on_event = process_frame; - return ff_framesync_configure(&s->fs); + return ff_framesync2_configure(&s->fs); } -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) +static int activate(AVFilterContext *ctx) { - ThresholdContext *s = inlink->dst->priv; - return ff_framesync_filter_frame(&s->fs, inlink, buf); -} - -static int request_frame(AVFilterLink *outlink) -{ - ThresholdContext *s = outlink->src->priv; - return ff_framesync_request_frame(&s->fs, outlink); + ThresholdContext *s = ctx->priv; + return ff_framesync2_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) { ThresholdContext *s = ctx->priv; - ff_framesync_uninit(&s->fs); + ff_framesync2_uninit(&s->fs); } static const AVFilterPad inputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, .config_props = config_input, }, { .name = "threshold", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, }, { .name = "min", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, }, { .name = "max", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, }, { NULL } }; @@ -331,7 +321,6 @@ static const AVFilterPad outputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_output, - .request_frame = request_frame, }, { NULL } }; @@ -343,6 +332,7 @@ AVFilter ff_vf_threshold = { .priv_class = &threshold_class, .uninit = uninit, .query_formats = query_formats, + .activate = activate, .inputs = inputs, .outputs = outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, From dbf7a670942d078c12aa7944b1fd469e188e6da2 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 17 Jul 2017 16:31:44 +0200 Subject: [PATCH 2678/3374] lavfi/vf_remap: move to "activate" design. --- libavfilter/Makefile | 2 +- libavfilter/vf_remap.c | 30 +++++++++++------------------- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index b34272830e836..7acf13b0aa6b2 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -265,7 +265,7 @@ OBJS-$(CONFIG_RANDOM_FILTER) += vf_random.o OBJS-$(CONFIG_READEIA608_FILTER) += vf_readeia608.o OBJS-$(CONFIG_READVITC_FILTER) += vf_readvitc.o OBJS-$(CONFIG_REALTIME_FILTER) += f_realtime.o -OBJS-$(CONFIG_REMAP_FILTER) += vf_remap.o framesync.o +OBJS-$(CONFIG_REMAP_FILTER) += vf_remap.o framesync2.o OBJS-$(CONFIG_REMOVEGRAIN_FILTER) += vf_removegrain.o OBJS-$(CONFIG_REMOVELOGO_FILTER) += bbox.o lswsutils.o lavfutils.o vf_removelogo.o OBJS-$(CONFIG_REPEATFIELDS_FILTER) += vf_repeatfields.o diff --git a/libavfilter/vf_remap.c b/libavfilter/vf_remap.c index b7182e9556265..d549912fcffef 100644 --- a/libavfilter/vf_remap.c +++ b/libavfilter/vf_remap.c @@ -41,7 +41,7 @@ #include "libavutil/opt.h" #include "avfilter.h" #include "formats.h" -#include "framesync.h" +#include "framesync2.h" #include "internal.h" #include "video.h" @@ -283,9 +283,9 @@ static int process_frame(FFFrameSync *fs) AVFrame *out, *in, *xpic, *ypic; int ret; - if ((ret = ff_framesync_get_frame(&s->fs, 0, &in, 0)) < 0 || - (ret = ff_framesync_get_frame(&s->fs, 1, &xpic, 0)) < 0 || - (ret = ff_framesync_get_frame(&s->fs, 2, &ypic, 0)) < 0) + if ((ret = ff_framesync2_get_frame(&s->fs, 0, &in, 0)) < 0 || + (ret = ff_framesync2_get_frame(&s->fs, 1, &xpic, 0)) < 0 || + (ret = ff_framesync2_get_frame(&s->fs, 2, &ypic, 0)) < 0) return ret; if (ctx->is_disabled) { @@ -330,7 +330,7 @@ static int config_output(AVFilterLink *outlink) outlink->sample_aspect_ratio = srclink->sample_aspect_ratio; outlink->frame_rate = srclink->frame_rate; - ret = ff_framesync_init(&s->fs, ctx, 3); + ret = ff_framesync2_init(&s->fs, ctx, 3); if (ret < 0) return ret; @@ -350,44 +350,36 @@ static int config_output(AVFilterLink *outlink) s->fs.opaque = s; s->fs.on_event = process_frame; - return ff_framesync_configure(&s->fs); + return ff_framesync2_configure(&s->fs); } -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) +static int activate(AVFilterContext *ctx) { - RemapContext *s = inlink->dst->priv; - return ff_framesync_filter_frame(&s->fs, inlink, buf); + RemapContext *s = ctx->priv; + return ff_framesync2_activate(&s->fs); } -static int request_frame(AVFilterLink *outlink) -{ - RemapContext *s = outlink->src->priv; - return ff_framesync_request_frame(&s->fs, outlink); -} static av_cold void uninit(AVFilterContext *ctx) { RemapContext *s = ctx->priv; - ff_framesync_uninit(&s->fs); + ff_framesync2_uninit(&s->fs); } static const AVFilterPad remap_inputs[] = { { .name = "source", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, .config_props = config_input, }, { .name = "xmap", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, }, { .name = "ymap", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, }, { NULL } }; @@ -397,7 +389,6 @@ static const AVFilterPad remap_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_output, - .request_frame = request_frame, }, { NULL } }; @@ -408,6 +399,7 @@ AVFilter ff_vf_remap = { .priv_size = sizeof(RemapContext), .uninit = uninit, .query_formats = query_formats, + .activate = activate, .inputs = remap_inputs, .outputs = remap_outputs, .priv_class = &remap_class, From b894415a703ed045b5b7c4c570960239c3e4d0a8 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 17 Jul 2017 16:33:20 +0200 Subject: [PATCH 2679/3374] lavfi/vf_premultiply: move to "activate" design. --- libavfilter/Makefile | 2 +- libavfilter/vf_premultiply.c | 28 ++++++++++------------------ 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 7acf13b0aa6b2..5acda236e681d 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -256,7 +256,7 @@ OBJS-$(CONFIG_PIXDESCTEST_FILTER) += vf_pixdesctest.o OBJS-$(CONFIG_PIXSCOPE_FILTER) += vf_datascope.o OBJS-$(CONFIG_PP_FILTER) += vf_pp.o OBJS-$(CONFIG_PP7_FILTER) += vf_pp7.o -OBJS-$(CONFIG_PREMULTIPLY_FILTER) += vf_premultiply.o framesync.o +OBJS-$(CONFIG_PREMULTIPLY_FILTER) += vf_premultiply.o framesync2.o OBJS-$(CONFIG_PREWITT_FILTER) += vf_convolution.o OBJS-$(CONFIG_PSNR_FILTER) += vf_psnr.o dualinput.o framesync.o OBJS-$(CONFIG_PULLUP_FILTER) += vf_pullup.o diff --git a/libavfilter/vf_premultiply.c b/libavfilter/vf_premultiply.c index 8a5f9eac6464f..4bb850edd5f22 100644 --- a/libavfilter/vf_premultiply.c +++ b/libavfilter/vf_premultiply.c @@ -23,7 +23,7 @@ #include "libavutil/opt.h" #include "avfilter.h" #include "formats.h" -#include "framesync.h" +#include "framesync2.h" #include "internal.h" #include "video.h" @@ -207,8 +207,8 @@ static int process_frame(FFFrameSync *fs) AVFrame *out, *base, *alpha; int ret; - if ((ret = ff_framesync_get_frame(&s->fs, 0, &base, 0)) < 0 || - (ret = ff_framesync_get_frame(&s->fs, 1, &alpha, 0)) < 0) + if ((ret = ff_framesync2_get_frame(&s->fs, 0, &base, 0)) < 0 || + (ret = ff_framesync2_get_frame(&s->fs, 1, &alpha, 0)) < 0) return ret; if (ctx->is_disabled) { @@ -345,7 +345,7 @@ static int config_output(AVFilterLink *outlink) outlink->sample_aspect_ratio = base->sample_aspect_ratio; outlink->frame_rate = base->frame_rate; - if ((ret = ff_framesync_init(&s->fs, ctx, 2)) < 0) + if ((ret = ff_framesync2_init(&s->fs, ctx, 2)) < 0) return ret; in = s->fs.in; @@ -360,39 +360,31 @@ static int config_output(AVFilterLink *outlink) s->fs.opaque = s; s->fs.on_event = process_frame; - return ff_framesync_configure(&s->fs); + return ff_framesync2_configure(&s->fs); } -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) +static int activate(AVFilterContext *ctx) { - PreMultiplyContext *s = inlink->dst->priv; - return ff_framesync_filter_frame(&s->fs, inlink, buf); -} - -static int request_frame(AVFilterLink *outlink) -{ - PreMultiplyContext *s = outlink->src->priv; - return ff_framesync_request_frame(&s->fs, outlink); + PreMultiplyContext *s = ctx->priv; + return ff_framesync2_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) { PreMultiplyContext *s = ctx->priv; - ff_framesync_uninit(&s->fs); + ff_framesync2_uninit(&s->fs); } static const AVFilterPad premultiply_inputs[] = { { .name = "main", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, .config_props = config_input, }, { .name = "alpha", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, }, { NULL } }; @@ -402,7 +394,6 @@ static const AVFilterPad premultiply_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_output, - .request_frame = request_frame, }, { NULL } }; @@ -413,6 +404,7 @@ AVFilter ff_vf_premultiply = { .priv_size = sizeof(PreMultiplyContext), .uninit = uninit, .query_formats = query_formats, + .activate = activate, .inputs = premultiply_inputs, .outputs = premultiply_outputs, .priv_class = &premultiply_class, From 620608467f262a6941660e0dd27bdb73bb7fe847 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 17 Jul 2017 16:36:20 +0200 Subject: [PATCH 2680/3374] lavfi/vf_midequalizer: move to "activate" design. --- libavfilter/Makefile | 2 +- libavfilter/vf_midequalizer.c | 28 ++++++++++------------------ 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 5acda236e681d..0edd33576f99d 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -231,7 +231,7 @@ OBJS-$(CONFIG_MCDEINT_FILTER) += vf_mcdeint.o OBJS-$(CONFIG_MERGEPLANES_FILTER) += vf_mergeplanes.o framesync.o OBJS-$(CONFIG_MESTIMATE_FILTER) += vf_mestimate.o motion_estimation.o OBJS-$(CONFIG_METADATA_FILTER) += f_metadata.o -OBJS-$(CONFIG_MIDEQUALIZER_FILTER) += vf_midequalizer.o framesync.o +OBJS-$(CONFIG_MIDEQUALIZER_FILTER) += vf_midequalizer.o framesync2.o OBJS-$(CONFIG_MINTERPOLATE_FILTER) += vf_minterpolate.o motion_estimation.o OBJS-$(CONFIG_MPDECIMATE_FILTER) += vf_mpdecimate.o OBJS-$(CONFIG_NEGATE_FILTER) += vf_lut.o diff --git a/libavfilter/vf_midequalizer.c b/libavfilter/vf_midequalizer.c index 99d26c751ed9d..9d9ad1aec1fde 100644 --- a/libavfilter/vf_midequalizer.c +++ b/libavfilter/vf_midequalizer.c @@ -25,7 +25,7 @@ #include "formats.h" #include "internal.h" #include "video.h" -#include "framesync.h" +#include "framesync2.h" typedef struct MidEqualizerContext { const AVClass *class; @@ -89,8 +89,8 @@ static int process_frame(FFFrameSync *fs) AVFrame *out, *in0, *in1; int ret; - if ((ret = ff_framesync_get_frame(&s->fs, 0, &in0, 0)) < 0 || - (ret = ff_framesync_get_frame(&s->fs, 1, &in1, 0)) < 0) + if ((ret = ff_framesync2_get_frame(&s->fs, 0, &in0, 0)) < 0 || + (ret = ff_framesync2_get_frame(&s->fs, 1, &in1, 0)) < 0) return ret; if (ctx->is_disabled) { @@ -311,7 +311,7 @@ static int config_output(AVFilterLink *outlink) outlink->sample_aspect_ratio = in0->sample_aspect_ratio; outlink->frame_rate = in0->frame_rate; - if ((ret = ff_framesync_init(&s->fs, ctx, 2)) < 0) + if ((ret = ff_framesync2_init(&s->fs, ctx, 2)) < 0) return ret; in = s->fs.in; @@ -326,26 +326,20 @@ static int config_output(AVFilterLink *outlink) s->fs.opaque = s; s->fs.on_event = process_frame; - return ff_framesync_configure(&s->fs); + return ff_framesync2_configure(&s->fs); } -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) +static int activate(AVFilterContext *ctx) { - MidEqualizerContext *s = inlink->dst->priv; - return ff_framesync_filter_frame(&s->fs, inlink, buf); -} - -static int request_frame(AVFilterLink *outlink) -{ - MidEqualizerContext *s = outlink->src->priv; - return ff_framesync_request_frame(&s->fs, outlink); + MidEqualizerContext *s = ctx->priv; + return ff_framesync2_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) { MidEqualizerContext *s = ctx->priv; - ff_framesync_uninit(&s->fs); + ff_framesync2_uninit(&s->fs); av_freep(&s->histogram[0]); av_freep(&s->histogram[1]); av_freep(&s->cchange); @@ -355,13 +349,11 @@ static const AVFilterPad midequalizer_inputs[] = { { .name = "in0", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, .config_props = config_input0, }, { .name = "in1", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, .config_props = config_input1, }, { NULL } @@ -372,7 +364,6 @@ static const AVFilterPad midequalizer_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_output, - .request_frame = request_frame, }, { NULL } }; @@ -383,6 +374,7 @@ AVFilter ff_vf_midequalizer = { .priv_size = sizeof(MidEqualizerContext), .uninit = uninit, .query_formats = query_formats, + .activate = activate, .inputs = midequalizer_inputs, .outputs = midequalizer_outputs, .priv_class = &midequalizer_class, From a5e3b0c1934f76f21957d001853cf976a94da47b Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 17 Jul 2017 16:38:18 +0200 Subject: [PATCH 2681/3374] lavfi/vf_maskedmerge: move to "activate" design. --- libavfilter/Makefile | 2 +- libavfilter/maskedmerge.h | 2 +- libavfilter/vf_maskedmerge.c | 29 ++++++++++------------------- 3 files changed, 12 insertions(+), 21 deletions(-) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 0edd33576f99d..5128f0f937171 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -226,7 +226,7 @@ OBJS-$(CONFIG_LUT3D_FILTER) += vf_lut3d.o OBJS-$(CONFIG_LUTRGB_FILTER) += vf_lut.o OBJS-$(CONFIG_LUTYUV_FILTER) += vf_lut.o OBJS-$(CONFIG_MASKEDCLAMP_FILTER) += vf_maskedclamp.o framesync.o -OBJS-$(CONFIG_MASKEDMERGE_FILTER) += vf_maskedmerge.o framesync.o +OBJS-$(CONFIG_MASKEDMERGE_FILTER) += vf_maskedmerge.o framesync2.o OBJS-$(CONFIG_MCDEINT_FILTER) += vf_mcdeint.o OBJS-$(CONFIG_MERGEPLANES_FILTER) += vf_mergeplanes.o framesync.o OBJS-$(CONFIG_MESTIMATE_FILTER) += vf_mestimate.o motion_estimation.o diff --git a/libavfilter/maskedmerge.h b/libavfilter/maskedmerge.h index 8e2b1cf676c14..3d670f6d5ddf4 100644 --- a/libavfilter/maskedmerge.h +++ b/libavfilter/maskedmerge.h @@ -22,7 +22,7 @@ #define AVFILTER_MASKEDMERGE_H #include "avfilter.h" -#include "framesync.h" +#include "framesync2.h" typedef struct MaskedMergeContext { const AVClass *class; diff --git a/libavfilter/vf_maskedmerge.c b/libavfilter/vf_maskedmerge.c index cf8a56814eca6..54def62820404 100644 --- a/libavfilter/vf_maskedmerge.c +++ b/libavfilter/vf_maskedmerge.c @@ -71,9 +71,9 @@ static int process_frame(FFFrameSync *fs) AVFrame *out, *base, *overlay, *mask; int ret; - if ((ret = ff_framesync_get_frame(&s->fs, 0, &base, 0)) < 0 || - (ret = ff_framesync_get_frame(&s->fs, 1, &overlay, 0)) < 0 || - (ret = ff_framesync_get_frame(&s->fs, 2, &mask, 0)) < 0) + if ((ret = ff_framesync2_get_frame(&s->fs, 0, &base, 0)) < 0 || + (ret = ff_framesync2_get_frame(&s->fs, 1, &overlay, 0)) < 0 || + (ret = ff_framesync2_get_frame(&s->fs, 2, &mask, 0)) < 0) return ret; if (ctx->is_disabled) { @@ -232,7 +232,7 @@ static int config_output(AVFilterLink *outlink) if ((ret = av_image_fill_linesizes(s->linesize, outlink->format, outlink->w)) < 0) return ret; - if ((ret = ff_framesync_init(&s->fs, ctx, 3)) < 0) + if ((ret = ff_framesync2_init(&s->fs, ctx, 3)) < 0) return ret; in = s->fs.in; @@ -251,44 +251,35 @@ static int config_output(AVFilterLink *outlink) s->fs.opaque = s; s->fs.on_event = process_frame; - return ff_framesync_configure(&s->fs); + return ff_framesync2_configure(&s->fs); } -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) +static int activate(AVFilterContext *ctx) { - MaskedMergeContext *s = inlink->dst->priv; - return ff_framesync_filter_frame(&s->fs, inlink, buf); -} - -static int request_frame(AVFilterLink *outlink) -{ - MaskedMergeContext *s = outlink->src->priv; - return ff_framesync_request_frame(&s->fs, outlink); + MaskedMergeContext *s = ctx->priv; + return ff_framesync2_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) { MaskedMergeContext *s = ctx->priv; - ff_framesync_uninit(&s->fs); + ff_framesync2_uninit(&s->fs); } static const AVFilterPad maskedmerge_inputs[] = { { .name = "base", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, .config_props = config_input, }, { .name = "overlay", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, }, { .name = "mask", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, }, { NULL } }; @@ -298,7 +289,6 @@ static const AVFilterPad maskedmerge_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_output, - .request_frame = request_frame, }, { NULL } }; @@ -309,6 +299,7 @@ AVFilter ff_vf_maskedmerge = { .priv_size = sizeof(MaskedMergeContext), .uninit = uninit, .query_formats = query_formats, + .activate = activate, .inputs = maskedmerge_inputs, .outputs = maskedmerge_outputs, .priv_class = &maskedmerge_class, From 0bc331bd57dc164acbbdd548ab4001fb4b95c97a Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 17 Jul 2017 16:40:28 +0200 Subject: [PATCH 2682/3374] lavfi/vf_mergeplanes: move to "activate" design. --- libavfilter/Makefile | 2 +- libavfilter/vf_mergeplanes.c | 25 +++++++++---------------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 5128f0f937171..16a7e87c04ba0 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -228,7 +228,7 @@ OBJS-$(CONFIG_LUTYUV_FILTER) += vf_lut.o OBJS-$(CONFIG_MASKEDCLAMP_FILTER) += vf_maskedclamp.o framesync.o OBJS-$(CONFIG_MASKEDMERGE_FILTER) += vf_maskedmerge.o framesync2.o OBJS-$(CONFIG_MCDEINT_FILTER) += vf_mcdeint.o -OBJS-$(CONFIG_MERGEPLANES_FILTER) += vf_mergeplanes.o framesync.o +OBJS-$(CONFIG_MERGEPLANES_FILTER) += vf_mergeplanes.o framesync2.o OBJS-$(CONFIG_MESTIMATE_FILTER) += vf_mestimate.o motion_estimation.o OBJS-$(CONFIG_METADATA_FILTER) += f_metadata.o OBJS-$(CONFIG_MIDEQUALIZER_FILTER) += vf_midequalizer.o framesync2.o diff --git a/libavfilter/vf_mergeplanes.c b/libavfilter/vf_mergeplanes.c index c21104320d136..b8ccee080297e 100644 --- a/libavfilter/vf_mergeplanes.c +++ b/libavfilter/vf_mergeplanes.c @@ -25,7 +25,7 @@ #include "libavutil/pixdesc.h" #include "avfilter.h" #include "internal.h" -#include "framesync.h" +#include "framesync2.h" typedef struct InputParam { int depth[4]; @@ -58,12 +58,6 @@ static const AVOption mergeplanes_options[] = { AVFILTER_DEFINE_CLASS(mergeplanes); -static int filter_frame(AVFilterLink *inlink, AVFrame *in) -{ - MergePlanesContext *s = inlink->dst->priv; - return ff_framesync_filter_frame(&s->fs, inlink, in); -} - static av_cold int init(AVFilterContext *ctx) { MergePlanesContext *s = ctx->priv; @@ -101,7 +95,6 @@ static av_cold int init(AVFilterContext *ctx) pad.name = av_asprintf("in%d", i); if (!pad.name) return AVERROR(ENOMEM); - pad.filter_frame = filter_frame; if ((ret = ff_insert_inpad(ctx, i, &pad)) < 0){ av_freep(&pad.name); @@ -150,7 +143,7 @@ static int process_frame(FFFrameSync *fs) int i, ret; for (i = 0; i < s->nb_inputs; i++) { - if ((ret = ff_framesync_get_frame(&s->fs, i, &in[i], 0)) < 0) + if ((ret = ff_framesync2_get_frame(&s->fs, i, &in[i], 0)) < 0) return ret; } @@ -179,7 +172,7 @@ static int config_output(AVFilterLink *outlink) FFFrameSyncIn *in; int i, ret; - if ((ret = ff_framesync_init(&s->fs, ctx, s->nb_inputs)) < 0) + if ((ret = ff_framesync2_init(&s->fs, ctx, s->nb_inputs)) < 0) return ret; in = s->fs.in; @@ -272,15 +265,15 @@ static int config_output(AVFilterLink *outlink) } } - return ff_framesync_configure(&s->fs); + return ff_framesync2_configure(&s->fs); fail: return AVERROR(EINVAL); } -static int request_frame(AVFilterLink *outlink) +static int activate(AVFilterContext *ctx) { - MergePlanesContext *s = outlink->src->priv; - return ff_framesync_request_frame(&s->fs, outlink); + MergePlanesContext *s = ctx->priv; + return ff_framesync2_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) @@ -288,7 +281,7 @@ static av_cold void uninit(AVFilterContext *ctx) MergePlanesContext *s = ctx->priv; int i; - ff_framesync_uninit(&s->fs); + ff_framesync2_uninit(&s->fs); for (i = 0; i < ctx->nb_inputs; i++) av_freep(&ctx->input_pads[i].name); @@ -299,7 +292,6 @@ static const AVFilterPad mergeplanes_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_output, - .request_frame = request_frame, }, { NULL } }; @@ -312,6 +304,7 @@ AVFilter ff_vf_mergeplanes = { .init = init, .uninit = uninit, .query_formats = query_formats, + .activate = activate, .inputs = NULL, .outputs = mergeplanes_outputs, .flags = AVFILTER_FLAG_DYNAMIC_INPUTS, From 27d8af03ae0d0cd15c01ed3de3a37add63966fed Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 17 Jul 2017 16:42:14 +0200 Subject: [PATCH 2683/3374] lavfi/vf_maskedclamp: move to "activate" design. --- libavfilter/Makefile | 2 +- libavfilter/vf_maskedclamp.c | 31 +++++++++++-------------------- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 16a7e87c04ba0..18d42a75961e6 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -225,7 +225,7 @@ OBJS-$(CONFIG_LUT2_FILTER) += vf_lut2.o framesync.o OBJS-$(CONFIG_LUT3D_FILTER) += vf_lut3d.o OBJS-$(CONFIG_LUTRGB_FILTER) += vf_lut.o OBJS-$(CONFIG_LUTYUV_FILTER) += vf_lut.o -OBJS-$(CONFIG_MASKEDCLAMP_FILTER) += vf_maskedclamp.o framesync.o +OBJS-$(CONFIG_MASKEDCLAMP_FILTER) += vf_maskedclamp.o framesync2.o OBJS-$(CONFIG_MASKEDMERGE_FILTER) += vf_maskedmerge.o framesync2.o OBJS-$(CONFIG_MCDEINT_FILTER) += vf_mcdeint.o OBJS-$(CONFIG_MERGEPLANES_FILTER) += vf_mergeplanes.o framesync2.o diff --git a/libavfilter/vf_maskedclamp.c b/libavfilter/vf_maskedclamp.c index 25c1a73be02f9..5ad8aa7f66fa1 100644 --- a/libavfilter/vf_maskedclamp.c +++ b/libavfilter/vf_maskedclamp.c @@ -25,7 +25,7 @@ #include "formats.h" #include "internal.h" #include "video.h" -#include "framesync.h" +#include "framesync2.h" #define OFFSET(x) offsetof(MaskedClampContext, x) #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM @@ -93,9 +93,9 @@ static int process_frame(FFFrameSync *fs) AVFrame *out, *base, *dark, *bright; int ret; - if ((ret = ff_framesync_get_frame(&s->fs, 0, &base, 0)) < 0 || - (ret = ff_framesync_get_frame(&s->fs, 1, &dark, 0)) < 0 || - (ret = ff_framesync_get_frame(&s->fs, 2, &bright, 0)) < 0) + if ((ret = ff_framesync2_get_frame(&s->fs, 0, &base, 0)) < 0 || + (ret = ff_framesync2_get_frame(&s->fs, 1, &dark, 0)) < 0 || + (ret = ff_framesync2_get_frame(&s->fs, 2, &bright, 0)) < 0) return ret; if (ctx->is_disabled) { @@ -265,7 +265,7 @@ static int config_output(AVFilterLink *outlink) outlink->sample_aspect_ratio = base->sample_aspect_ratio; outlink->frame_rate = base->frame_rate; - if ((ret = ff_framesync_init(&s->fs, ctx, 3)) < 0) + if ((ret = ff_framesync2_init(&s->fs, ctx, 3)) < 0) return ret; in = s->fs.in; @@ -284,44 +284,35 @@ static int config_output(AVFilterLink *outlink) s->fs.opaque = s; s->fs.on_event = process_frame; - return ff_framesync_configure(&s->fs); + return ff_framesync2_configure(&s->fs); } -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) +static int activate(AVFilterContext *ctx) { - MaskedClampContext *s = inlink->dst->priv; - return ff_framesync_filter_frame(&s->fs, inlink, buf); -} - -static int request_frame(AVFilterLink *outlink) -{ - MaskedClampContext *s = outlink->src->priv; - return ff_framesync_request_frame(&s->fs, outlink); + MaskedClampContext *s = ctx->priv; + return ff_framesync2_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) { MaskedClampContext *s = ctx->priv; - ff_framesync_uninit(&s->fs); + ff_framesync2_uninit(&s->fs); } static const AVFilterPad maskedclamp_inputs[] = { { .name = "base", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, .config_props = config_input, }, { .name = "dark", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, }, { .name = "bright", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, }, { NULL } }; @@ -331,7 +322,6 @@ static const AVFilterPad maskedclamp_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_output, - .request_frame = request_frame, }, { NULL } }; @@ -341,6 +331,7 @@ AVFilter ff_vf_maskedclamp = { .description = NULL_IF_CONFIG_SMALL("Clamp first stream with second stream and third stream."), .priv_size = sizeof(MaskedClampContext), .uninit = uninit, + .activate = activate, .query_formats = query_formats, .inputs = maskedclamp_inputs, .outputs = maskedclamp_outputs, From dbc4af862e74a7ee3a0e6f98a4e58d0615533301 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 17 Jul 2017 16:45:17 +0200 Subject: [PATCH 2684/3374] lavfi/vf_lut2: move to "activate" design. --- libavfilter/Makefile | 2 +- libavfilter/vf_lut2.c | 26 +++++++++----------------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 18d42a75961e6..27ceb339a4b83 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -221,7 +221,7 @@ OBJS-$(CONFIG_LIMITER_FILTER) += vf_limiter.o OBJS-$(CONFIG_LOOP_FILTER) += f_loop.o OBJS-$(CONFIG_LUMAKEY_FILTER) += vf_lumakey.o OBJS-$(CONFIG_LUT_FILTER) += vf_lut.o -OBJS-$(CONFIG_LUT2_FILTER) += vf_lut2.o framesync.o +OBJS-$(CONFIG_LUT2_FILTER) += vf_lut2.o framesync2.o OBJS-$(CONFIG_LUT3D_FILTER) += vf_lut3d.o OBJS-$(CONFIG_LUTRGB_FILTER) += vf_lut.o OBJS-$(CONFIG_LUTYUV_FILTER) += vf_lut.o diff --git a/libavfilter/vf_lut2.c b/libavfilter/vf_lut2.c index 25790bb3a3289..f7e4a6a65657f 100644 --- a/libavfilter/vf_lut2.c +++ b/libavfilter/vf_lut2.c @@ -28,7 +28,7 @@ #include "formats.h" #include "internal.h" #include "video.h" -#include "framesync.h" +#include "framesync2.h" static const char *const var_names[] = { "w", ///< width of the input video @@ -206,8 +206,8 @@ static int process_frame(FFFrameSync *fs) AVFrame *out, *srcx, *srcy; int ret; - if ((ret = ff_framesync_get_frame(&s->fs, 0, &srcx, 0)) < 0 || - (ret = ff_framesync_get_frame(&s->fs, 1, &srcy, 0)) < 0) + if ((ret = ff_framesync2_get_frame(&s->fs, 0, &srcx, 0)) < 0 || + (ret = ff_framesync2_get_frame(&s->fs, 1, &srcy, 0)) < 0) return ret; if (ctx->is_disabled) { @@ -266,7 +266,7 @@ static int config_output(AVFilterLink *outlink) outlink->sample_aspect_ratio = srcx->sample_aspect_ratio; outlink->frame_rate = srcx->frame_rate; - if ((ret = ff_framesync_init(&s->fs, ctx, 2)) < 0) + if ((ret = ff_framesync2_init(&s->fs, ctx, 2)) < 0) return ret; in = s->fs.in; @@ -323,32 +323,24 @@ static int config_output(AVFilterLink *outlink) } } - return ff_framesync_configure(&s->fs); + return ff_framesync2_configure(&s->fs); } -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) +static int activate(AVFilterContext *ctx) { - LUT2Context *s = inlink->dst->priv; - return ff_framesync_filter_frame(&s->fs, inlink, buf); -} - -static int request_frame(AVFilterLink *outlink) -{ - LUT2Context *s = outlink->src->priv; - return ff_framesync_request_frame(&s->fs, outlink); + LUT2Context *s = ctx->priv; + return ff_framesync2_activate(&s->fs); } static const AVFilterPad inputs[] = { { .name = "srcx", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, .config_props = config_inputx, }, { .name = "srcy", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, .config_props = config_inputy, }, { NULL } @@ -359,7 +351,6 @@ static const AVFilterPad outputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_output, - .request_frame = request_frame, }, { NULL } }; @@ -373,6 +364,7 @@ AVFilter ff_vf_lut2 = { .priv_class = &lut2_class, .uninit = uninit, .query_formats = query_formats, + .activate = activate, .inputs = inputs, .outputs = outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, From 5dbb111900b6208813fe299912d4ba8297c4525e Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 17 Jul 2017 16:54:23 +0200 Subject: [PATCH 2685/3374] lavfi/vf_hysteresis: move to "activate" design. --- libavfilter/Makefile | 2 +- libavfilter/vf_hysteresis.c | 28 ++++++++++------------------ 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 27ceb339a4b83..441e07843fc9c 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -208,7 +208,7 @@ OBJS-$(CONFIG_HWDOWNLOAD_FILTER) += vf_hwdownload.o OBJS-$(CONFIG_HWMAP_FILTER) += vf_hwmap.o OBJS-$(CONFIG_HWUPLOAD_CUDA_FILTER) += vf_hwupload_cuda.o OBJS-$(CONFIG_HWUPLOAD_FILTER) += vf_hwupload.o -OBJS-$(CONFIG_HYSTERESIS_FILTER) += vf_hysteresis.o framesync.o +OBJS-$(CONFIG_HYSTERESIS_FILTER) += vf_hysteresis.o framesync2.o OBJS-$(CONFIG_IDET_FILTER) += vf_idet.o OBJS-$(CONFIG_IL_FILTER) += vf_il.o OBJS-$(CONFIG_INFLATE_FILTER) += vf_neighbor.o diff --git a/libavfilter/vf_hysteresis.c b/libavfilter/vf_hysteresis.c index c0369b2066563..c3b769b8a7d18 100644 --- a/libavfilter/vf_hysteresis.c +++ b/libavfilter/vf_hysteresis.c @@ -26,7 +26,7 @@ #include "formats.h" #include "internal.h" #include "video.h" -#include "framesync.h" +#include "framesync2.h" #define OFFSET(x) offsetof(HysteresisContext, x) #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM @@ -94,8 +94,8 @@ static int process_frame(FFFrameSync *fs) AVFrame *out, *base, *alt; int ret; - if ((ret = ff_framesync_get_frame(&s->fs, 0, &base, 0)) < 0 || - (ret = ff_framesync_get_frame(&s->fs, 1, &alt, 0)) < 0) + if ((ret = ff_framesync2_get_frame(&s->fs, 0, &base, 0)) < 0 || + (ret = ff_framesync2_get_frame(&s->fs, 1, &alt, 0)) < 0) return ret; if (ctx->is_disabled) { @@ -324,7 +324,7 @@ static int config_output(AVFilterLink *outlink) outlink->sample_aspect_ratio = base->sample_aspect_ratio; outlink->frame_rate = base->frame_rate; - if ((ret = ff_framesync_init(&s->fs, ctx, 2)) < 0) + if ((ret = ff_framesync2_init(&s->fs, ctx, 2)) < 0) return ret; in = s->fs.in; @@ -339,26 +339,20 @@ static int config_output(AVFilterLink *outlink) s->fs.opaque = s; s->fs.on_event = process_frame; - return ff_framesync_configure(&s->fs); + return ff_framesync2_configure(&s->fs); } -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) +static int activate(AVFilterContext *ctx) { - HysteresisContext *s = inlink->dst->priv; - return ff_framesync_filter_frame(&s->fs, inlink, buf); -} - -static int request_frame(AVFilterLink *outlink) -{ - HysteresisContext *s = outlink->src->priv; - return ff_framesync_request_frame(&s->fs, outlink); + HysteresisContext *s = ctx->priv; + return ff_framesync2_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) { HysteresisContext *s = ctx->priv; - ff_framesync_uninit(&s->fs); + ff_framesync2_uninit(&s->fs); av_freep(&s->map); av_freep(&s->xy); } @@ -367,13 +361,11 @@ static const AVFilterPad hysteresis_inputs[] = { { .name = "base", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, .config_props = config_input, }, { .name = "alt", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, }, { NULL } }; @@ -383,7 +375,6 @@ static const AVFilterPad hysteresis_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_output, - .request_frame = request_frame, }, { NULL } }; @@ -394,6 +385,7 @@ AVFilter ff_vf_hysteresis = { .priv_size = sizeof(HysteresisContext), .uninit = uninit, .query_formats = query_formats, + .activate = activate, .inputs = hysteresis_inputs, .outputs = hysteresis_outputs, .priv_class = &hysteresis_class, From 8b2cd8e0e41284469cf1fb5051df329fb6d8d5c3 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 17 Jul 2017 17:00:23 +0200 Subject: [PATCH 2686/3374] lavfi/vf_displace: move to "activate" design. --- libavfilter/Makefile | 2 +- libavfilter/vf_displace.c | 31 +++++++++++-------------------- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 441e07843fc9c..4d61d7835e99b 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -168,7 +168,7 @@ OBJS-$(CONFIG_DELOGO_FILTER) += vf_delogo.o OBJS-$(CONFIG_DESHAKE_FILTER) += vf_deshake.o OBJS-$(CONFIG_DETELECINE_FILTER) += vf_detelecine.o OBJS-$(CONFIG_DILATION_FILTER) += vf_neighbor.o -OBJS-$(CONFIG_DISPLACE_FILTER) += vf_displace.o framesync.o +OBJS-$(CONFIG_DISPLACE_FILTER) += vf_displace.o framesync2.o OBJS-$(CONFIG_DOUBLEWEAVE_FILTER) += vf_weave.o OBJS-$(CONFIG_DRAWBOX_FILTER) += vf_drawbox.o OBJS-$(CONFIG_DRAWGRAPH_FILTER) += f_drawgraph.o diff --git a/libavfilter/vf_displace.c b/libavfilter/vf_displace.c index 9daa0c9ddba89..6100a249c6a98 100644 --- a/libavfilter/vf_displace.c +++ b/libavfilter/vf_displace.c @@ -23,7 +23,7 @@ #include "libavutil/opt.h" #include "avfilter.h" #include "formats.h" -#include "framesync.h" +#include "framesync2.h" #include "internal.h" #include "video.h" @@ -212,9 +212,9 @@ static int process_frame(FFFrameSync *fs) AVFrame *out, *in, *xpic, *ypic; int ret; - if ((ret = ff_framesync_get_frame(&s->fs, 0, &in, 0)) < 0 || - (ret = ff_framesync_get_frame(&s->fs, 1, &xpic, 0)) < 0 || - (ret = ff_framesync_get_frame(&s->fs, 2, &ypic, 0)) < 0) + if ((ret = ff_framesync2_get_frame(&s->fs, 0, &in, 0)) < 0 || + (ret = ff_framesync2_get_frame(&s->fs, 1, &xpic, 0)) < 0 || + (ret = ff_framesync2_get_frame(&s->fs, 2, &ypic, 0)) < 0) return ret; if (ctx->is_disabled) { @@ -310,7 +310,7 @@ static int config_output(AVFilterLink *outlink) outlink->sample_aspect_ratio = srclink->sample_aspect_ratio; outlink->frame_rate = srclink->frame_rate; - ret = ff_framesync_init(&s->fs, ctx, 3); + ret = ff_framesync2_init(&s->fs, ctx, 3); if (ret < 0) return ret; @@ -330,44 +330,35 @@ static int config_output(AVFilterLink *outlink) s->fs.opaque = s; s->fs.on_event = process_frame; - return ff_framesync_configure(&s->fs); + return ff_framesync2_configure(&s->fs); } -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) +static int activate(AVFilterContext *ctx) { - DisplaceContext *s = inlink->dst->priv; - return ff_framesync_filter_frame(&s->fs, inlink, buf); -} - -static int request_frame(AVFilterLink *outlink) -{ - DisplaceContext *s = outlink->src->priv; - return ff_framesync_request_frame(&s->fs, outlink); + DisplaceContext *s = ctx->priv; + return ff_framesync2_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) { DisplaceContext *s = ctx->priv; - ff_framesync_uninit(&s->fs); + ff_framesync2_uninit(&s->fs); } static const AVFilterPad displace_inputs[] = { { .name = "source", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, .config_props = config_input, }, { .name = "xmap", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, }, { .name = "ymap", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, }, { NULL } }; @@ -377,7 +368,6 @@ static const AVFilterPad displace_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_output, - .request_frame = request_frame, }, { NULL } }; @@ -388,6 +378,7 @@ AVFilter ff_vf_displace = { .priv_size = sizeof(DisplaceContext), .uninit = uninit, .query_formats = query_formats, + .activate = activate, .inputs = displace_inputs, .outputs = displace_outputs, .priv_class = &displace_class, From e433497160bd8997f461851419b5c86e6095d21d Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Mon, 24 Jul 2017 23:07:05 +0200 Subject: [PATCH 2687/3374] avdevice/decklink_dec: set field order via codecpar Signed-off-by: Marton Balint --- libavdevice/decklink_dec.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index 8b5c1a20c10ca..72449a8eca5fe 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -731,6 +731,19 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) st->codecpar->bit_rate = av_rescale(ctx->bmd_width * ctx->bmd_height * 16, st->time_base.den, st->time_base.num); } + switch (ctx->bmd_field_dominance) { + case bmdUpperFieldFirst: + st->codecpar->field_order = AV_FIELD_TT; + break; + case bmdLowerFieldFirst: + st->codecpar->field_order = AV_FIELD_BB; + break; + case bmdProgressiveFrame: + case bmdProgressiveSegmentedFrame: + st->codecpar->field_order = AV_FIELD_PROGRESSIVE; + break; + } + avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ ctx->video_st=st; @@ -788,15 +801,8 @@ int ff_decklink_read_packet(AVFormatContext *avctx, AVPacket *pkt) { struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data; struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; - AVFrame *frame = ctx->video_st->codec->coded_frame; avpacket_queue_get(&ctx->queue, pkt, 1); - if (frame && (ctx->bmd_field_dominance == bmdUpperFieldFirst || ctx->bmd_field_dominance == bmdLowerFieldFirst)) { - frame->interlaced_frame = 1; - if (ctx->bmd_field_dominance == bmdUpperFieldFirst) { - frame->top_field_first = 1; - } - } return 0; } From ca23d3491d4c3e316b968242dc14140603b27e70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Thu, 23 Mar 2017 23:21:07 +0100 Subject: [PATCH 2688/3374] sws/tests/pixdesc_query: save every pix fmts in a list This will be required for the next commit. --- libswscale/tests/pixdesc_query.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/libswscale/tests/pixdesc_query.c b/libswscale/tests/pixdesc_query.c index a4aa8ac487ef5..34b33c6851322 100644 --- a/libswscale/tests/pixdesc_query.c +++ b/libswscale/tests/pixdesc_query.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mem.h" #include "libswscale/swscale_internal.h" static const struct { @@ -45,17 +46,27 @@ static const struct { int main(void) { - int i; + int i, j; for (i = 0; i < FF_ARRAY_ELEMS(query_tab); i++) { + const char **pix_fmts = NULL; + int nb_pix_fmts = 0; const AVPixFmtDescriptor *pix_desc = NULL; - printf("%s:\n", query_tab[i].class); + while ((pix_desc = av_pix_fmt_desc_next(pix_desc))) { enum AVPixelFormat pix_fmt = av_pix_fmt_desc_get_id(pix_desc); if (query_tab[i].cond(pix_fmt)) - printf(" %s\n", pix_desc->name); + av_dynarray_add(&pix_fmts, &nb_pix_fmts, (void *)pix_desc->name); + } + + if (pix_fmts) { + printf("%s:\n", query_tab[i].class); + for (j = 0; j < nb_pix_fmts; j++) + printf(" %s\n", pix_fmts[j]); + printf("\n"); + + free(pix_fmts); } - printf("\n"); } return 0; } From d2c70fc8879024565f4a6397d0230bffdc0afb15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Thu, 23 Mar 2017 23:32:35 +0100 Subject: [PATCH 2689/3374] sws/tests/pixdesc_query: sort pixel formats --- libswscale/tests/pixdesc_query.c | 11 + tests/ref/fate/sws-pixdesc-query | 1158 +++++++++++++++--------------- 2 files changed, 590 insertions(+), 579 deletions(-) diff --git a/libswscale/tests/pixdesc_query.c b/libswscale/tests/pixdesc_query.c index 34b33c6851322..a0c843792a75d 100644 --- a/libswscale/tests/pixdesc_query.c +++ b/libswscale/tests/pixdesc_query.c @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + #include "libavutil/mem.h" #include "libswscale/swscale_internal.h" @@ -44,6 +46,13 @@ static const struct { {"usePal", usePal}, }; +static int cmp_str(const void *a, const void *b) +{ + const char *s1 = *(const char **)a; + const char *s2 = *(const char **)b; + return strcmp(s1, s2); +} + int main(void) { int i, j; @@ -60,6 +69,8 @@ int main(void) } if (pix_fmts) { + qsort(pix_fmts, nb_pix_fmts, sizeof(*pix_fmts), cmp_str); + printf("%s:\n", query_tab[i].class); for (j = 0; j < nb_pix_fmts; j++) printf(" %s\n", pix_fmts[j]); diff --git a/tests/ref/fate/sws-pixdesc-query b/tests/ref/fate/sws-pixdesc-query index e262a0cabff41..b014afc43171a 100644 --- a/tests/ref/fate/sws-pixdesc-query +++ b/tests/ref/fate/sws-pixdesc-query @@ -1,807 +1,807 @@ is16BPS: + ayuv64be + ayuv64le + bgr48be + bgr48le + bgra64be + bgra64le + gbrap16be + gbrap16le + gbrp16be + gbrp16le gray16be gray16le + p016be + p016le rgb48be rgb48le - yuv420p16le + rgba64be + rgba64le + ya16be + ya16le yuv420p16be - yuv422p16le + yuv420p16le yuv422p16be - yuv444p16le + yuv422p16le yuv444p16be - bgr48be - bgr48le - gbrp16be - gbrp16le + yuv444p16le yuva420p16be yuva420p16le yuva422p16be yuva422p16le yuva444p16be yuva444p16le - rgba64be - rgba64le - bgra64be - bgra64le - ya16be - ya16le - gbrap16be - gbrap16le - ayuv64le - ayuv64be - p016le - p016be isNBPS: - yuv420p9be - yuv420p9le - yuv420p10be - yuv420p10le - yuv422p10be - yuv422p10le - yuv444p9be - yuv444p9le - yuv444p10be - yuv444p10le - yuv422p9be - yuv422p9le - gbrp9be - gbrp9le + gbrap10be + gbrap10le + gbrap12be + gbrap12le gbrp10be gbrp10le - yuva420p9be - yuva420p9le - yuva422p9be - yuva422p9le - yuva444p9be - yuva444p9le - yuva420p10be - yuva420p10le - yuva422p10be - yuva422p10le - yuva444p10be - yuva444p10le - xyz12le - xyz12be - nv20le + gbrp12be + gbrp12le + gbrp14be + gbrp14le + gbrp9be + gbrp9le + gray10be + gray10le + gray12be + gray12le nv20be + nv20le + p010be + p010le + xyz12be + xyz12le + yuv420p10be + yuv420p10le yuv420p12be yuv420p12le yuv420p14be yuv420p14le + yuv420p9be + yuv420p9le + yuv422p10be + yuv422p10le yuv422p12be yuv422p12le yuv422p14be yuv422p14le + yuv422p9be + yuv422p9le + yuv440p10be + yuv440p10le + yuv440p12be + yuv440p12le + yuv444p10be + yuv444p10le yuv444p12be yuv444p12le yuv444p14be yuv444p14le + yuv444p9be + yuv444p9le + yuva420p10be + yuva420p10le + yuva420p9be + yuva420p9le + yuva422p10be + yuva422p10le + yuva422p9be + yuva422p9le + yuva444p10be + yuva444p10le + yuva444p9be + yuva444p9le + +isBE: + ayuv64be + bayer_bggr16be + bayer_gbrg16be + bayer_grbg16be + bayer_rggb16be + bgr444be + bgr48be + bgr555be + bgr565be + bgra64be + gbrap10be + gbrap12be + gbrap16be + gbrp10be gbrp12be - gbrp12le gbrp14be - gbrp14le - yuv440p10le - yuv440p10be - yuv440p12le - yuv440p12be - p010le - p010be - gbrap12be - gbrap12le - gbrap10be - gbrap10le - gray12be - gray12le + gbrp16be + gbrp9be gray10be - gray10le - -isBE: + gray12be gray16be + nv20be + p010be + p016be + rgb444be rgb48be - rgb565be rgb555be - bgr565be - bgr555be + rgb565be + rgba64be + xyz12be + ya16be + yuv420p10be + yuv420p12be + yuv420p14be yuv420p16be - yuv422p16be - yuv444p16be - rgb444be - bgr444be - bgr48be yuv420p9be - yuv420p10be yuv422p10be - yuv444p9be - yuv444p10be + yuv422p12be + yuv422p14be + yuv422p16be yuv422p9be - gbrp9be - gbrp10be - gbrp16be - yuva420p9be - yuva422p9be - yuva444p9be + yuv440p10be + yuv440p12be + yuv444p10be + yuv444p12be + yuv444p14be + yuv444p16be + yuv444p9be yuva420p10be - yuva422p10be - yuva444p10be yuva420p16be + yuva420p9be + yuva422p10be yuva422p16be + yuva422p9be + yuva444p10be yuva444p16be - xyz12be + yuva444p9be + +isYUV: + ayuv64be + ayuv64le + nv12 + nv16 nv20be - rgba64be - bgra64be + nv20le + nv21 + p010be + p010le + p016be + p016le + uyvy422 + uyyvyy411 + xyz12be + xyz12le ya16be - gbrap16be + ya16le + ya8 + yuv410p + yuv411p + yuv420p + yuv420p10be + yuv420p10le yuv420p12be + yuv420p12le yuv420p14be + yuv420p14le + yuv420p16be + yuv420p16le + yuv420p9be + yuv420p9le + yuv422p + yuv422p10be + yuv422p10le yuv422p12be + yuv422p12le yuv422p14be - yuv444p12be - yuv444p14be - gbrp12be - gbrp14be - bayer_bggr16be - bayer_rggb16be - bayer_gbrg16be - bayer_grbg16be + yuv422p14le + yuv422p16be + yuv422p16le + yuv422p9be + yuv422p9le + yuv440p yuv440p10be + yuv440p10le yuv440p12be - ayuv64be - p010be - gbrap12be - gbrap10be - gray12be - gray10be - p016be - -isYUV: - yuv420p - yuyv422 - yuv422p + yuv440p12le yuv444p - yuv410p - yuv411p - yuvj420p - yuvj422p - yuvj444p - uyvy422 - uyyvyy411 - nv12 - nv21 - yuv440p - yuvj440p - yuva420p - yuv420p16le - yuv420p16be - yuv422p16le - yuv422p16be - yuv444p16le + yuv444p10be + yuv444p10le + yuv444p12be + yuv444p12le + yuv444p14be + yuv444p14le yuv444p16be - ya8 - yuv420p9be - yuv420p9le - yuv420p10be - yuv420p10le - yuv422p10be - yuv422p10le + yuv444p16le yuv444p9be yuv444p9le - yuv444p10be - yuv444p10le - yuv422p9be - yuv422p9le - yuva422p - yuva444p - yuva420p9be - yuva420p9le - yuva422p9be - yuva422p9le - yuva444p9be - yuva444p9le + yuva420p yuva420p10be yuva420p10le - yuva422p10be - yuva422p10le - yuva444p10be - yuva444p10le yuva420p16be yuva420p16le + yuva420p9be + yuva420p9le + yuva422p + yuva422p10be + yuva422p10le yuva422p16be yuva422p16le + yuva422p9be + yuva422p9le + yuva444p + yuva444p10be + yuva444p10le yuva444p16be yuva444p16le - xyz12le - xyz12be + yuva444p9be + yuva444p9le + yuvj411p + yuvj420p + yuvj422p + yuvj440p + yuvj444p + yuyv422 + yvyu422 + +isPlanarYUV: + nv12 nv16 - nv20le nv20be - yvyu422 - ya16be - ya16le + nv20le + nv21 + p010be + p010le + p016be + p016le + yuv410p + yuv411p + yuv420p + yuv420p10be + yuv420p10le yuv420p12be yuv420p12le yuv420p14be yuv420p14le + yuv420p16be + yuv420p16le + yuv420p9be + yuv420p9le + yuv422p + yuv422p10be + yuv422p10le yuv422p12be yuv422p12le yuv422p14be yuv422p14le + yuv422p16be + yuv422p16le + yuv422p9be + yuv422p9le + yuv440p + yuv440p10be + yuv440p10le + yuv440p12be + yuv440p12le + yuv444p + yuv444p10be + yuv444p10le yuv444p12be yuv444p12le yuv444p14be yuv444p14le - yuvj411p - yuv440p10le - yuv440p10be - yuv440p12le - yuv440p12be - ayuv64le - ayuv64be - p010le - p010be - p016le - p016be - -isPlanarYUV: - yuv420p - yuv422p - yuv444p - yuv410p - yuv411p - yuvj420p - yuvj422p - yuvj444p - nv12 - nv21 - yuv440p - yuvj440p - yuva420p - yuv420p16le - yuv420p16be - yuv422p16le - yuv422p16be - yuv444p16le yuv444p16be - yuv420p9be - yuv420p9le - yuv420p10be - yuv420p10le - yuv422p10be - yuv422p10le + yuv444p16le yuv444p9be yuv444p9le - yuv444p10be - yuv444p10le - yuv422p9be - yuv422p9le - yuva422p - yuva444p - yuva420p9be - yuva420p9le - yuva422p9be - yuva422p9le - yuva444p9be - yuva444p9le + yuva420p yuva420p10be yuva420p10le - yuva422p10be - yuva422p10le - yuva444p10be - yuva444p10le yuva420p16be yuva420p16le + yuva420p9be + yuva420p9le + yuva422p + yuva422p10be + yuva422p10le yuva422p16be yuva422p16le + yuva422p9be + yuva422p9le + yuva444p + yuva444p10be + yuva444p10le yuva444p16be yuva444p16le - nv16 - nv20le - nv20be - yuv420p12be - yuv420p12le - yuv420p14be - yuv420p14le - yuv422p12be - yuv422p12le - yuv422p14be - yuv422p14le - yuv444p12be - yuv444p12le - yuv444p14be - yuv444p14le + yuva444p9be + yuva444p9le yuvj411p - yuv440p10le - yuv440p10be - yuv440p12le - yuv440p12be - p010le - p010be - p016le - p016be + yuvj420p + yuvj422p + yuvj440p + yuvj444p isRGB: - rgb24 + 0bgr + 0rgb + abgr + argb + bayer_bggr16be + bayer_bggr16le + bayer_bggr8 + bayer_gbrg16be + bayer_gbrg16le + bayer_gbrg8 + bayer_grbg16be + bayer_grbg16le + bayer_grbg8 + bayer_rggb16be + bayer_rggb16le + bayer_rggb8 + bgr0 bgr24 - bgr8 bgr4 - bgr4_byte - rgb8 - rgb4 - rgb4_byte - argb - rgba - abgr - bgra - rgb48be - rgb48le - rgb565be - rgb565le - rgb555be - rgb555le - bgr565be - bgr565le - bgr555be - bgr555le - rgb444le - rgb444be - bgr444le bgr444be + bgr444le bgr48be bgr48le - gbrp - gbrp9be - gbrp9le - gbrp10be - gbrp10le - gbrp16be - gbrp16le - rgba64be - rgba64le - bgra64be - bgra64le + bgr4_byte + bgr555be + bgr555le + bgr565be + bgr565le + bgr8 + bgra + bgra64be + bgra64le gbrap + gbrap10be + gbrap10le + gbrap12be + gbrap12le gbrap16be gbrap16le - 0rgb - rgb0 - 0bgr - bgr0 + gbrp + gbrp10be + gbrp10le gbrp12be gbrp12le gbrp14be gbrp14le - bayer_bggr8 - bayer_rggb8 - bayer_gbrg8 - bayer_grbg8 - bayer_bggr16le - bayer_bggr16be - bayer_rggb16le - bayer_rggb16be - bayer_gbrg16le - bayer_gbrg16be - bayer_grbg16le - bayer_grbg16be - gbrap12be - gbrap12le - gbrap10be - gbrap10le + gbrp16be + gbrp16le + gbrp9be + gbrp9le + rgb0 + rgb24 + rgb4 + rgb444be + rgb444le + rgb48be + rgb48le + rgb4_byte + rgb555be + rgb555le + rgb565be + rgb565le + rgb8 + rgba + rgba64be + rgba64le Gray: gray + gray10be + gray10le + gray12be + gray12le gray16be gray16le - ya8 ya16be ya16le - gray12be - gray12le - gray10be - gray10le + ya8 RGBinInt: - rgb24 - monow - monob - rgb8 - rgb4 - rgb4_byte abgr bgra + monob + monow + rgb24 + rgb4 + rgb444be + rgb444le rgb48be rgb48le - rgb565be - rgb565le + rgb4_byte rgb555be rgb555le - rgb444le - rgb444be + rgb565be + rgb565le + rgb8 rgba64be rgba64le BGRinInt: + argb bgr24 - monow - monob - bgr8 bgr4 - bgr4_byte - argb - rgba - bgr565be - bgr565le - bgr555be - bgr555le - bgr444le bgr444be + bgr444le bgr48be bgr48le + bgr4_byte + bgr555be + bgr555le + bgr565be + bgr565le + bgr8 bgra64be bgra64le + monob + monow + rgba Bayer: + bayer_bggr16be + bayer_bggr16le bayer_bggr8 - bayer_rggb8 + bayer_gbrg16be + bayer_gbrg16le bayer_gbrg8 + bayer_grbg16be + bayer_grbg16le bayer_grbg8 - bayer_bggr16le - bayer_bggr16be - bayer_rggb16le bayer_rggb16be - bayer_gbrg16le - bayer_gbrg16be - bayer_grbg16le - bayer_grbg16be + bayer_rggb16le + bayer_rggb8 AnyRGB: - rgb24 + 0bgr + 0rgb + abgr + argb + bayer_bggr16be + bayer_bggr16le + bayer_bggr8 + bayer_gbrg16be + bayer_gbrg16le + bayer_gbrg8 + bayer_grbg16be + bayer_grbg16le + bayer_grbg8 + bayer_rggb16be + bayer_rggb16le + bayer_rggb8 + bgr0 bgr24 - monow - monob - bgr8 bgr4 - bgr4_byte - rgb8 - rgb4 - rgb4_byte - argb - rgba - abgr - bgra - rgb48be - rgb48le - rgb565be - rgb565le - rgb555be - rgb555le - bgr565be - bgr565le - bgr555be - bgr555le - rgb444le - rgb444be - bgr444le bgr444be + bgr444le bgr48be bgr48le + bgr4_byte + bgr555be + bgr555le + bgr565be + bgr565le + bgr8 + bgra + bgra64be + bgra64le + gbrap + gbrap10be + gbrap10le + gbrap12be + gbrap12le + gbrap16be + gbrap16le gbrp - gbrp9be - gbrp9le gbrp10be gbrp10le + gbrp12be + gbrp12le + gbrp14be + gbrp14le gbrp16be gbrp16le + gbrp9be + gbrp9le + monob + monow + rgb0 + rgb24 + rgb4 + rgb444be + rgb444le + rgb48be + rgb48le + rgb4_byte + rgb555be + rgb555le + rgb565be + rgb565le + rgb8 + rgba rgba64be rgba64le + +ALPHA: + abgr + argb + ayuv64be + ayuv64le + bgra bgra64be bgra64le gbrap - gbrap16be - gbrap16le - 0rgb - rgb0 - 0bgr - bgr0 - gbrp12be - gbrp12le - gbrp14be - gbrp14le - bayer_bggr8 - bayer_rggb8 - bayer_gbrg8 - bayer_grbg8 - bayer_bggr16le - bayer_bggr16be - bayer_rggb16le - bayer_rggb16be - bayer_gbrg16le - bayer_gbrg16be - bayer_grbg16le - bayer_grbg16be - gbrap12be - gbrap12le gbrap10be gbrap10le - -ALPHA: + gbrap12be + gbrap12le + gbrap16be + gbrap16le pal8 - argb rgba - abgr - bgra - yuva420p + rgba64be + rgba64le + ya16be + ya16le ya8 - yuva422p - yuva444p - yuva420p9be - yuva420p9le - yuva422p9be - yuva422p9le - yuva444p9be - yuva444p9le + yuva420p yuva420p10be yuva420p10le - yuva422p10be - yuva422p10le - yuva444p10be - yuva444p10le yuva420p16be yuva420p16le + yuva420p9be + yuva420p9le + yuva422p + yuva422p10be + yuva422p10le yuva422p16be yuva422p16le + yuva422p9be + yuva422p9le + yuva444p + yuva444p10be + yuva444p10le yuva444p16be yuva444p16le - rgba64be - rgba64le - bgra64be - bgra64le - ya16be - ya16le - gbrap - gbrap16be - gbrap16le - ayuv64le - ayuv64be - gbrap12be - gbrap12le - gbrap10be - gbrap10le + yuva444p9be + yuva444p9le Packed: - yuyv422 - rgb24 + 0bgr + 0rgb + abgr + argb + ayuv64be + ayuv64le + bayer_bggr16be + bayer_bggr16le + bayer_bggr8 + bayer_gbrg16be + bayer_gbrg16le + bayer_gbrg8 + bayer_grbg16be + bayer_grbg16le + bayer_grbg8 + bayer_rggb16be + bayer_rggb16le + bayer_rggb8 + bgr0 bgr24 - monow - monob - pal8 - uyvy422 - uyyvyy411 - bgr8 bgr4 + bgr444be + bgr444le + bgr48be + bgr48le bgr4_byte - rgb8 - rgb4 - rgb4_byte - argb - rgba - abgr + bgr555be + bgr555le + bgr565be + bgr565le + bgr8 bgra + bgra64be + bgra64le + monob + monow + pal8 + rgb0 + rgb24 + rgb4 + rgb444be + rgb444le rgb48be rgb48le - rgb565be - rgb565le + rgb4_byte rgb555be rgb555le - bgr565be - bgr565le - bgr555be - bgr555le - rgb444le - rgb444be - bgr444le - bgr444be - ya8 - bgr48be - bgr48le - xyz12le - xyz12be + rgb565be + rgb565le + rgb8 + rgba rgba64be rgba64le - bgra64be - bgra64le - yvyu422 - ya16be - ya16le - 0rgb - rgb0 - 0bgr - bgr0 - bayer_bggr8 - bayer_rggb8 - bayer_gbrg8 - bayer_grbg8 - bayer_bggr16le - bayer_bggr16be - bayer_rggb16le - bayer_rggb16be - bayer_gbrg16le - bayer_gbrg16be - bayer_grbg16le - bayer_grbg16be - ayuv64le - ayuv64be + uyvy422 + uyyvyy411 + xyz12be + xyz12le + ya16be + ya16le + ya8 + yuyv422 + yvyu422 Planar: - yuv420p - yuv422p - yuv444p - yuv410p - yuv411p - yuvj420p - yuvj422p - yuvj444p - nv12 - nv21 - yuv440p - yuvj440p - yuva420p - yuv420p16le - yuv420p16be - yuv422p16le - yuv422p16be - yuv444p16le - yuv444p16be - yuv420p9be - yuv420p9le - yuv420p10be - yuv420p10le - yuv422p10be - yuv422p10le - yuv444p9be - yuv444p9le - yuv444p10be - yuv444p10le - yuv422p9be - yuv422p9le + gbrap + gbrap10be + gbrap10le + gbrap12be + gbrap12le + gbrap16be + gbrap16le gbrp - gbrp9be - gbrp9le gbrp10be gbrp10le + gbrp12be + gbrp12le + gbrp14be + gbrp14le gbrp16be gbrp16le - yuva422p - yuva444p - yuva420p9be - yuva420p9le - yuva422p9be - yuva422p9le - yuva444p9be - yuva444p9le - yuva420p10be - yuva420p10le - yuva422p10be - yuva422p10le - yuva444p10be - yuva444p10le - yuva420p16be - yuva420p16le - yuva422p16be - yuva422p16le - yuva444p16be - yuva444p16le + gbrp9be + gbrp9le + nv12 nv16 - nv20le nv20be - gbrap - gbrap16be - gbrap16le + nv20le + nv21 + p010be + p010le + p016be + p016le + yuv410p + yuv411p + yuv420p + yuv420p10be + yuv420p10le yuv420p12be yuv420p12le yuv420p14be yuv420p14le + yuv420p16be + yuv420p16le + yuv420p9be + yuv420p9le + yuv422p + yuv422p10be + yuv422p10le yuv422p12be yuv422p12le yuv422p14be yuv422p14le + yuv422p16be + yuv422p16le + yuv422p9be + yuv422p9le + yuv440p + yuv440p10be + yuv440p10le + yuv440p12be + yuv440p12le + yuv444p + yuv444p10be + yuv444p10le yuv444p12be yuv444p12le yuv444p14be yuv444p14le - gbrp12be - gbrp12le - gbrp14be - gbrp14le + yuv444p16be + yuv444p16le + yuv444p9be + yuv444p9le + yuva420p + yuva420p10be + yuva420p10le + yuva420p16be + yuva420p16le + yuva420p9be + yuva420p9le + yuva422p + yuva422p10be + yuva422p10le + yuva422p16be + yuva422p16le + yuva422p9be + yuva422p9le + yuva444p + yuva444p10be + yuva444p10le + yuva444p16be + yuva444p16le + yuva444p9be + yuva444p9le yuvj411p - yuv440p10le - yuv440p10be - yuv440p12le - yuv440p12be - p010le - p010be - gbrap12be - gbrap12le - gbrap10be - gbrap10le - p016le - p016be + yuvj420p + yuvj422p + yuvj440p + yuvj444p PackedRGB: - rgb24 + 0bgr + 0rgb + abgr + argb + bayer_bggr16be + bayer_bggr16le + bayer_bggr8 + bayer_gbrg16be + bayer_gbrg16le + bayer_gbrg8 + bayer_grbg16be + bayer_grbg16le + bayer_grbg8 + bayer_rggb16be + bayer_rggb16le + bayer_rggb8 + bgr0 bgr24 - bgr8 bgr4 + bgr444be + bgr444le + bgr48be + bgr48le bgr4_byte - rgb8 - rgb4 - rgb4_byte - argb - rgba - abgr + bgr555be + bgr555le + bgr565be + bgr565le + bgr8 bgra + bgra64be + bgra64le + rgb0 + rgb24 + rgb4 + rgb444be + rgb444le rgb48be rgb48le - rgb565be - rgb565le + rgb4_byte rgb555be rgb555le - bgr565be - bgr565le - bgr555be - bgr555le - rgb444le - rgb444be - bgr444le - bgr444be - bgr48be - bgr48le + rgb565be + rgb565le + rgb8 + rgba rgba64be rgba64le - bgra64be - bgra64le - 0rgb - rgb0 - 0bgr - bgr0 - bayer_bggr8 - bayer_rggb8 - bayer_gbrg8 - bayer_grbg8 - bayer_bggr16le - bayer_bggr16be - bayer_rggb16le - bayer_rggb16be - bayer_gbrg16le - bayer_gbrg16be - bayer_grbg16le - bayer_grbg16be PlanarRGB: - gbrp - gbrp9be - gbrp9le - gbrp10be - gbrp10le - gbrp16be - gbrp16le gbrap + gbrap10be + gbrap10le + gbrap12be + gbrap12le gbrap16be gbrap16le + gbrp + gbrp10be + gbrp10le gbrp12be gbrp12le gbrp14be gbrp14le - gbrap12be - gbrap12le - gbrap10be - gbrap10le + gbrp16be + gbrp16le + gbrp9be + gbrp9le usePal: + bgr4_byte + bgr8 gray pal8 - bgr8 - bgr4_byte - rgb8 rgb4_byte + rgb8 From 4158fba3cdb7c90f42071323f37f617e4f278414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Fri, 24 Mar 2017 00:51:32 +0100 Subject: [PATCH 2690/3374] sws/tests/pixdesc_query: replace rgb based pix fmts with endianess agnostic names Fixes ticket #6554 --- libswscale/tests/pixdesc_query.c | 11 ++++++-- tests/ref/fate/sws-pixdesc-query | 48 ++++++++++++++++---------------- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/libswscale/tests/pixdesc_query.c b/libswscale/tests/pixdesc_query.c index a0c843792a75d..417f481cd0aea 100644 --- a/libswscale/tests/pixdesc_query.c +++ b/libswscale/tests/pixdesc_query.c @@ -64,8 +64,15 @@ int main(void) while ((pix_desc = av_pix_fmt_desc_next(pix_desc))) { enum AVPixelFormat pix_fmt = av_pix_fmt_desc_get_id(pix_desc); - if (query_tab[i].cond(pix_fmt)) - av_dynarray_add(&pix_fmts, &nb_pix_fmts, (void *)pix_desc->name); + if (query_tab[i].cond(pix_fmt)) { + const char *pix_name = pix_desc->name; + if (pix_fmt == AV_PIX_FMT_RGB32) pix_name = "rgb32"; + else if (pix_fmt == AV_PIX_FMT_RGB32_1) pix_name = "rgb32_1"; + else if (pix_fmt == AV_PIX_FMT_BGR32) pix_name = "bgr32"; + else if (pix_fmt == AV_PIX_FMT_BGR32_1) pix_name = "bgr32_1"; + + av_dynarray_add(&pix_fmts, &nb_pix_fmts, (void *)pix_name); + } } if (pix_fmts) { diff --git a/tests/ref/fate/sws-pixdesc-query b/tests/ref/fate/sws-pixdesc-query index b014afc43171a..fb1e62f32619d 100644 --- a/tests/ref/fate/sws-pixdesc-query +++ b/tests/ref/fate/sws-pixdesc-query @@ -323,8 +323,6 @@ isPlanarYUV: isRGB: 0bgr 0rgb - abgr - argb bayer_bggr16be bayer_bggr16le bayer_bggr8 @@ -339,6 +337,8 @@ isRGB: bayer_rggb8 bgr0 bgr24 + bgr32 + bgr32_1 bgr4 bgr444be bgr444le @@ -350,7 +350,6 @@ isRGB: bgr565be bgr565le bgr8 - bgra bgra64be bgra64le gbrap @@ -373,6 +372,8 @@ isRGB: gbrp9le rgb0 rgb24 + rgb32 + rgb32_1 rgb4 rgb444be rgb444le @@ -384,7 +385,6 @@ isRGB: rgb565be rgb565le rgb8 - rgba rgba64be rgba64le @@ -401,11 +401,11 @@ Gray: ya8 RGBinInt: - abgr - bgra monob monow rgb24 + rgb32 + rgb32_1 rgb4 rgb444be rgb444le @@ -421,8 +421,9 @@ RGBinInt: rgba64le BGRinInt: - argb bgr24 + bgr32 + bgr32_1 bgr4 bgr444be bgr444le @@ -438,7 +439,6 @@ BGRinInt: bgra64le monob monow - rgba Bayer: bayer_bggr16be @@ -457,8 +457,6 @@ Bayer: AnyRGB: 0bgr 0rgb - abgr - argb bayer_bggr16be bayer_bggr16le bayer_bggr8 @@ -473,6 +471,8 @@ AnyRGB: bayer_rggb8 bgr0 bgr24 + bgr32 + bgr32_1 bgr4 bgr444be bgr444le @@ -484,7 +484,6 @@ AnyRGB: bgr565be bgr565le bgr8 - bgra bgra64be bgra64le gbrap @@ -509,6 +508,8 @@ AnyRGB: monow rgb0 rgb24 + rgb32 + rgb32_1 rgb4 rgb444be rgb444le @@ -520,16 +521,14 @@ AnyRGB: rgb565be rgb565le rgb8 - rgba rgba64be rgba64le ALPHA: - abgr - argb ayuv64be ayuv64le - bgra + bgr32 + bgr32_1 bgra64be bgra64le gbrap @@ -540,7 +539,8 @@ ALPHA: gbrap16be gbrap16le pal8 - rgba + rgb32 + rgb32_1 rgba64be rgba64le ya16be @@ -571,8 +571,6 @@ ALPHA: Packed: 0bgr 0rgb - abgr - argb ayuv64be ayuv64le bayer_bggr16be @@ -589,6 +587,8 @@ Packed: bayer_rggb8 bgr0 bgr24 + bgr32 + bgr32_1 bgr4 bgr444be bgr444le @@ -600,7 +600,6 @@ Packed: bgr565be bgr565le bgr8 - bgra bgra64be bgra64le monob @@ -608,6 +607,8 @@ Packed: pal8 rgb0 rgb24 + rgb32 + rgb32_1 rgb4 rgb444be rgb444le @@ -619,7 +620,6 @@ Packed: rgb565be rgb565le rgb8 - rgba rgba64be rgba64le uyvy422 @@ -730,8 +730,6 @@ Planar: PackedRGB: 0bgr 0rgb - abgr - argb bayer_bggr16be bayer_bggr16le bayer_bggr8 @@ -746,6 +744,8 @@ PackedRGB: bayer_rggb8 bgr0 bgr24 + bgr32 + bgr32_1 bgr4 bgr444be bgr444le @@ -757,11 +757,12 @@ PackedRGB: bgr565be bgr565le bgr8 - bgra bgra64be bgra64le rgb0 rgb24 + rgb32 + rgb32_1 rgb4 rgb444be rgb444le @@ -773,7 +774,6 @@ PackedRGB: rgb565be rgb565le rgb8 - rgba rgba64be rgba64le From 797c232ef84d3886a25270cef8b630caf5a491cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sun, 30 Jul 2017 20:48:04 +0200 Subject: [PATCH 2691/3374] sws/tests/pixdesc_query: fix use of free() instead of av_free() Fix CID 1415949 --- libswscale/tests/pixdesc_query.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libswscale/tests/pixdesc_query.c b/libswscale/tests/pixdesc_query.c index 417f481cd0aea..a5585c43149c8 100644 --- a/libswscale/tests/pixdesc_query.c +++ b/libswscale/tests/pixdesc_query.c @@ -83,7 +83,7 @@ int main(void) printf(" %s\n", pix_fmts[j]); printf("\n"); - free(pix_fmts); + av_free(pix_fmts); } } return 0; From b664d1f3ffbce07c206d679cc09a1fd29955de44 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Mon, 31 Jul 2017 14:07:27 +0200 Subject: [PATCH 2692/3374] doc/filters.texi: add another lut2 example Signed-off-by: Paul B Mahol --- doc/filters.texi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/filters.texi b/doc/filters.texi index 2324b96867c23..4089135807478 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -10004,6 +10004,12 @@ Highlight differences between two YUV video streams: @example lut2='ifnot(x-y,0,pow(2,bdx)-1):ifnot(x-y,pow(2,bdx-1),pow(2,bdx)-1):ifnot(x-y,pow(2,bdx-1),pow(2,bdx)-1)' @end example + +@item +Show max difference between two video streams: +@example +lut2='if(lt(x,y),0,if(gt(x,y),pow(2,bdx)-1,pow(2,bdx-1))):if(lt(x,y),0,if(gt(x,y),pow(2,bdx)-1,pow(2,bdx-1))):if(lt(x,y),0,if(gt(x,y),pow(2,bdx)-1,pow(2,bdx-1)))' +@end example @end itemize @section maskedclamp From 8f2f166c99df9d0fcfdabe3adb2041f9fa3bfaa2 Mon Sep 17 00:00:00 2001 From: James Almer Date: Thu, 20 Jul 2017 15:37:36 -0300 Subject: [PATCH 2693/3374] avcodec/atrac3p: use float_dsp in ff_atrac3p_power_compensation Signed-off-by: James Almer --- libavcodec/atrac3plus.h | 5 +++-- libavcodec/atrac3plusdec.c | 36 ++++++++++++++++++------------------ libavcodec/atrac3plusdsp.c | 10 +++++----- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/libavcodec/atrac3plus.h b/libavcodec/atrac3plus.h index a33c38a3ee21a..3c39e293c740f 100644 --- a/libavcodec/atrac3plus.h +++ b/libavcodec/atrac3plus.h @@ -199,13 +199,14 @@ void ff_atrac3p_generate_tones(Atrac3pChanUnitCtx *ch_unit, AVFloatDSPContext *f * Perform power compensation aka noise dithering. * * @param[in] ctx ptr to the channel context + * @param[in] fdsp pointer to float DSP context * @param[in] ch_index which channel to process * @param[in,out] sp ptr to channel spectrum to process * @param[in] rng_index indicates which RNG table to use * @param[in] sb_num which subband to process */ -void ff_atrac3p_power_compensation(Atrac3pChanUnitCtx *ctx, int ch_index, - float *sp, int rng_index, int sb_num); +void ff_atrac3p_power_compensation(Atrac3pChanUnitCtx *ctx, AVFloatDSPContext *fdsp, + int ch_index, float *sp, int rng_index, int sb_num); /** * Regular IMDCT and windowing without overlapping, diff --git a/libavcodec/atrac3plusdec.c b/libavcodec/atrac3plusdec.c index 7a2ab3ef95d63..666d1a5c01833 100644 --- a/libavcodec/atrac3plusdec.c +++ b/libavcodec/atrac3plusdec.c @@ -198,7 +198,7 @@ static av_cold int atrac3p_decode_init(AVCodecContext *avctx) return 0; } -static void decode_residual_spectrum(Atrac3pChanUnitCtx *ctx, +static void decode_residual_spectrum(ATRAC3PContext *ctx, Atrac3pChanUnitCtx *ch_unit, float out[2][ATRAC3P_FRAME_SAMPLES], int num_channels, AVCodecContext *avctx) @@ -209,17 +209,17 @@ static void decode_residual_spectrum(Atrac3pChanUnitCtx *ctx, /* calculate RNG table index for each subband */ int sb_RNG_index[ATRAC3P_SUBBANDS] = { 0 }; - if (ctx->mute_flag) { + if (ch_unit->mute_flag) { for (ch = 0; ch < num_channels; ch++) memset(out[ch], 0, ATRAC3P_FRAME_SAMPLES * sizeof(*out[ch])); return; } - for (qu = 0, RNG_index = 0; qu < ctx->used_quant_units; qu++) - RNG_index += ctx->channels[0].qu_sf_idx[qu] + - ctx->channels[1].qu_sf_idx[qu]; + for (qu = 0, RNG_index = 0; qu < ch_unit->used_quant_units; qu++) + RNG_index += ch_unit->channels[0].qu_sf_idx[qu] + + ch_unit->channels[1].qu_sf_idx[qu]; - for (sb = 0; sb < ctx->num_coded_subbands; sb++, RNG_index += 128) + for (sb = 0; sb < ch_unit->num_coded_subbands; sb++, RNG_index += 128) sb_RNG_index[sb] = RNG_index & 0x3FC; /* inverse quant and power compensation */ @@ -227,35 +227,35 @@ static void decode_residual_spectrum(Atrac3pChanUnitCtx *ctx, /* clear channel's residual spectrum */ memset(out[ch], 0, ATRAC3P_FRAME_SAMPLES * sizeof(*out[ch])); - for (qu = 0; qu < ctx->used_quant_units; qu++) { - src = &ctx->channels[ch].spectrum[ff_atrac3p_qu_to_spec_pos[qu]]; + for (qu = 0; qu < ch_unit->used_quant_units; qu++) { + src = &ch_unit->channels[ch].spectrum[ff_atrac3p_qu_to_spec_pos[qu]]; dst = &out[ch][ff_atrac3p_qu_to_spec_pos[qu]]; nspeclines = ff_atrac3p_qu_to_spec_pos[qu + 1] - ff_atrac3p_qu_to_spec_pos[qu]; - if (ctx->channels[ch].qu_wordlen[qu] > 0) { - q = ff_atrac3p_sf_tab[ctx->channels[ch].qu_sf_idx[qu]] * - ff_atrac3p_mant_tab[ctx->channels[ch].qu_wordlen[qu]]; + if (ch_unit->channels[ch].qu_wordlen[qu] > 0) { + q = ff_atrac3p_sf_tab[ch_unit->channels[ch].qu_sf_idx[qu]] * + ff_atrac3p_mant_tab[ch_unit->channels[ch].qu_wordlen[qu]]; for (i = 0; i < nspeclines; i++) dst[i] = src[i] * q; } } - for (sb = 0; sb < ctx->num_coded_subbands; sb++) - ff_atrac3p_power_compensation(ctx, ch, &out[ch][0], + for (sb = 0; sb < ch_unit->num_coded_subbands; sb++) + ff_atrac3p_power_compensation(ch_unit, ctx->fdsp, ch, &out[ch][0], sb_RNG_index[sb], sb); } - if (ctx->unit_type == CH_UNIT_STEREO) { - for (sb = 0; sb < ctx->num_coded_subbands; sb++) { - if (ctx->swap_channels[sb]) { + if (ch_unit->unit_type == CH_UNIT_STEREO) { + for (sb = 0; sb < ch_unit->num_coded_subbands; sb++) { + if (ch_unit->swap_channels[sb]) { for (i = 0; i < ATRAC3P_SUBBAND_SAMPLES; i++) FFSWAP(float, out[0][sb * ATRAC3P_SUBBAND_SAMPLES + i], out[1][sb * ATRAC3P_SUBBAND_SAMPLES + i]); } /* flip coefficients' sign if requested */ - if (ctx->negate_coeffs[sb]) + if (ch_unit->negate_coeffs[sb]) for (i = 0; i < ATRAC3P_SUBBAND_SAMPLES; i++) out[1][sb * ATRAC3P_SUBBAND_SAMPLES + i] = -(out[1][sb * ATRAC3P_SUBBAND_SAMPLES + i]); } @@ -369,7 +369,7 @@ static int atrac3p_decode_frame(AVCodecContext *avctx, void *data, avctx)) < 0) return ret; - decode_residual_spectrum(&ctx->ch_units[ch_block], ctx->samples, + decode_residual_spectrum(ctx, &ctx->ch_units[ch_block], ctx->samples, channels_to_process, avctx); reconstruct_frame(ctx, &ctx->ch_units[ch_block], channels_to_process, avctx); diff --git a/libavcodec/atrac3plusdsp.c b/libavcodec/atrac3plusdsp.c index d089588274c10..96aa402c2b2c7 100644 --- a/libavcodec/atrac3plusdsp.c +++ b/libavcodec/atrac3plusdsp.c @@ -415,11 +415,12 @@ static const int subband_to_qu[17] = { 0, 8, 12, 16, 18, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 }; -void ff_atrac3p_power_compensation(Atrac3pChanUnitCtx *ctx, int ch_index, - float *sp, int rng_index, int sb) +void ff_atrac3p_power_compensation(Atrac3pChanUnitCtx *ctx, AVFloatDSPContext *fdsp, + int ch_index, float *sp, int rng_index, int sb) { AtracGainInfo *g1, *g2; - float pwcsp[ATRAC3P_SUBBAND_SAMPLES], *dst, grp_lev, qu_lev; + LOCAL_ALIGNED_32(float, pwcsp, [ATRAC3P_SUBBAND_SAMPLES]); + float *dst, grp_lev, qu_lev; int i, gain_lev, gcv = 0, qu, nsp; int swap_ch = (ctx->unit_type == CH_UNIT_STEREO && ctx->swap_channels[sb]) ? 1 : 0; @@ -456,8 +457,7 @@ void ff_atrac3p_power_compensation(Atrac3pChanUnitCtx *ctx, int ch_index, dst = &sp[ff_atrac3p_qu_to_spec_pos[qu]]; nsp = ff_atrac3p_qu_to_spec_pos[qu + 1] - ff_atrac3p_qu_to_spec_pos[qu]; - for (i = 0; i < nsp; i++) - dst[i] += pwcsp[i] * qu_lev; + fdsp->vector_fmac_scalar(dst, pwcsp, qu_lev, nsp); } } From 46e407554968e7258c874f4caf517172ffa285cf Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 28 Jul 2017 02:23:25 +0200 Subject: [PATCH 2694/3374] avcodec/dirac_vlc: Fix invalid shift Fixes: runtime error: shift exponent 65 is too large for 64-bit type 'residual' (aka 'unsigned long') Fixes: 2737/clusterfuzz-testcase-minimized-4968639147016192 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/dirac_vlc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavcodec/dirac_vlc.c b/libavcodec/dirac_vlc.c index 773f720858d9e..d3b9900beba36 100644 --- a/libavcodec/dirac_vlc.c +++ b/libavcodec/dirac_vlc.c @@ -96,6 +96,9 @@ int ff_dirac_golomb_read_16bit(DiracGolombLUT *lut_ctx, const uint8_t *buf, if ((c_idx + 1) > coeffs) return c_idx; + if (res_bits >= RSIZE_BITS) + res_bits = res = 0; + if (res_bits && l->sign) { int32_t coeff = 1; APPEND_RESIDUE(res, l->preamble); From 880f5c59139e1d85d3a0b3433103f3fea17ff2d3 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 29 Jul 2017 15:46:50 +0200 Subject: [PATCH 2695/3374] avcodec/diracdec: Check weight_log2denom Fixes: runtime error: shift exponent -1 is negative Fixes: 2742/clusterfuzz-testcase-minimized-5724322402402304 Fixes: 2744/clusterfuzz-testcase-minimized-4672435653705728 Fixes: 2749/clusterfuzz-testcase-minimized-5298741273690112 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/diracdec.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c index d2aaeab01151c..f2837aca69e5b 100644 --- a/libavcodec/diracdec.c +++ b/libavcodec/diracdec.c @@ -1179,6 +1179,11 @@ static int dirac_unpack_prediction_parameters(DiracContext *s) if (get_bits1(gb)) { s->weight_log2denom = get_interleaved_ue_golomb(gb); + if (s->weight_log2denom < 1 || s->weight_log2denom > 8) { + av_log(s->avctx, AV_LOG_ERROR, "weight_log2denom unsupported or invalid\n"); + s->weight_log2denom = 1; + return AVERROR_INVALIDDATA; + } s->weight[0] = dirac_get_se_golomb(gb); if (s->num_refs == 2) s->weight[1] = dirac_get_se_golomb(gb); From b2d9d7226943d6229a17e31714ce5162bdf88b33 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 29 Jul 2017 15:55:36 +0200 Subject: [PATCH 2696/3374] avcodec/diracdsp: fix integer overflow Fixes: runtime error: signed integer overflow: 11 * 225726413 cannot be represented in type 'int' Fixes: 2764/clusterfuzz-testcase-minimized-5382561922547712 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/diracdsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/diracdsp.c b/libavcodec/diracdsp.c index cd1209e209dcb..8bc79b788ce6c 100644 --- a/libavcodec/diracdsp.c +++ b/libavcodec/diracdsp.c @@ -199,7 +199,7 @@ static void dequant_subband_ ## PX ## _c(uint8_t *src, uint8_t *dst, ptrdiff_t s for (i = 0; i < tot_h; i++) { \ c = *src_r++; \ sign = FFSIGN(c)*(!!c); \ - c = (FFABS(c)*qf + qs) >> 2; \ + c = (FFABS(c)*(unsigned)qf + qs) >> 2; \ *dst_r++ = c*sign; \ } \ src += tot_h << (sizeof(PX) >> 1); \ From f0f8da545d80665ae54d51df61e8f6903c85390a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sat, 29 Jul 2017 20:56:25 +0200 Subject: [PATCH 2697/3374] lavc/htmlsubtitles: improve handling broken garbage This commit switches off forced correct nesting of tags and only keeps it for font tags. See long explanations in the code for the rationale. This results in various FATE changes which I'll explain here: - various swapping in font attributes, this is mostly noise due to the old reverse stack way of printing them. The new one is more correct as the last attribute takes over the previous ones. - unrecognized tags disappears - invalid tags that were previously displayed aren't anymore (instead, we have a warning). This is better for the end user The main benefit of this commit is to be more tolerant to error, leading to a better handling of badly nested tags or random wrong formatting for the end user. --- libavcodec/htmlsubtitles.c | 201 ++++++++++++++++++++----------- tests/ref/fate/sub-sami2 | 4 +- tests/ref/fate/sub-srt | 14 +-- tests/ref/fate/sub-srt-badsyntax | 4 +- tests/ref/fate/sub-textenc | 14 +-- tests/ref/fate/sub-webvttenc | 14 +-- 6 files changed, 159 insertions(+), 92 deletions(-) diff --git a/libavcodec/htmlsubtitles.c b/libavcodec/htmlsubtitles.c index e1fb7bc3cf0d1..baed28450ef24 100644 --- a/libavcodec/htmlsubtitles.c +++ b/libavcodec/htmlsubtitles.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2010 Aurelien Jacobs + * Copyright (c) 2017 Clément Bœsch * * This file is part of FFmpeg. * @@ -18,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/avassert.h" #include "libavutil/avstring.h" #include "libavutil/common.h" #include "libavutil/parseutils.h" @@ -31,19 +33,6 @@ static int html_color_parse(void *log_ctx, const char *str) return rgba[0] | rgba[1] << 8 | rgba[2] << 16; } -enum { - PARAM_UNKNOWN = -1, - PARAM_SIZE, - PARAM_COLOR, - PARAM_FACE, - PARAM_NUMBER -}; - -typedef struct SrtStack { - char tag[128]; - char param[PARAM_NUMBER][128]; -} SrtStack; - static void rstrip_spaces_buf(AVBPrint *buf) { if (av_bprint_is_complete(buf)) @@ -75,17 +64,50 @@ static void handle_open_brace(AVBPrint *dst, const char **inp, int *an, int *clo av_bprint_chars(dst, *in, 1); } +struct font_tag { + char face[128]; + int size; + uint32_t color; +}; + +/* + * The general politic of the convert is to mask unsupported tags or formatting + * errors (but still alert the user/subtitles writer with an error/warning) + * without dropping any actual text content for the final user. + */ int ff_htmlmarkup_to_ass(void *log_ctx, AVBPrint *dst, const char *in) { - char *param, buffer[128], tmp[128]; - int len, tag_close, sptr = 1, line_start = 1, an = 0, end = 0; - SrtStack stack[16]; + char *param, buffer[128]; + int len, tag_close, sptr = 0, line_start = 1, an = 0, end = 0; int closing_brace_missing = 0; + int i, likely_a_tag; - stack[0].tag[0] = 0; - strcpy(stack[0].param[PARAM_SIZE], "{\\fs}"); - strcpy(stack[0].param[PARAM_COLOR], "{\\c}"); - strcpy(stack[0].param[PARAM_FACE], "{\\fn}"); + /* + * state stack is only present for fonts since they are the only tags where + * the state is not binary. Here is a typical use case: + * + * + * red 10 + * RED AND BIG + * red 10 again + * + * + * On the other hand, using the state system for all the tags should be + * avoided because it breaks wrongly nested tags such as: + * + * foo bar bla + * + * We don't want to break here; instead, we will treat all these tags as + * binary state markers. Basically, "" will activate bold, and "" + * will deactivate it, whatever the current state. + * + * This will also prevents cases where we have a random closing tag + * remaining after the opening one was dropped. Yes, this happens and we + * still don't want to print a "" at the end of the dialog event. + */ + struct font_tag stack[16]; + + memset(&stack[0], 0, sizeof(stack[0])); for (; !end && *in; in++) { switch (*in) { @@ -108,82 +130,127 @@ int ff_htmlmarkup_to_ass(void *log_ctx, AVBPrint *dst, const char *in) handle_open_brace(dst, &in, &an, &closing_brace_missing); break; case '<': + /* + * "<<" are likely latin guillemets in ASCII or some kind of random + * style effect; see sub/badsyntax.srt in the FATE samples + * directory for real test cases. + */ + + likely_a_tag = 1; + for (i = 0; in[1] == '<'; i++) { + av_bprint_chars(dst, '<', 1); + likely_a_tag = 0; + in++; + } + tag_close = in[1] == '/'; + if (tag_close) + likely_a_tag = 1; + + av_assert0(in[0] == '<'); + len = 0; + if (sscanf(in+tag_close+1, "%127[^<>]>%n", buffer, &len) >= 1 && len > 0) { + const int skip = len + tag_close; const char *tagname = buffer; - while (*tagname == ' ') + while (*tagname == ' ') { + likely_a_tag = 0; tagname++; + } if ((param = strchr(tagname, ' '))) *param++ = 0; - if ((!tag_close && sptr < FF_ARRAY_ELEMS(stack) && *tagname) || - ( tag_close && sptr > 0 && !av_strcasecmp(stack[sptr-1].tag, tagname))) { - int i, j, unknown = 0; - in += len + tag_close; - if (!tag_close) - memset(stack+sptr, 0, sizeof(*stack)); - if (!av_strcasecmp(tagname, "font")) { - if (tag_close) { - for (i=PARAM_NUMBER-1; i>=0; i--) - if (stack[sptr-1].param[i][0]) - for (j=sptr-2; j>=0; j--) - if (stack[j].param[i][0]) { - av_bprintf(dst, "%s", stack[j].param[i]); - break; - } - } else { + + /* Check if this is likely a tag */ +#define LIKELY_A_TAG_CHAR(x) (((x) >= '0' && (x) <= '9') || \ + ((x) >= 'a' && (x) <= 'z') || \ + ((x) >= 'A' && (x) <= 'Z') || \ + (x) == '_') + for (i = 0; tagname[i]; i++) { + if (!LIKELY_A_TAG_CHAR(tagname[i])) { + likely_a_tag = 0; + break; + } + } + + // TODO: reindent + + if (!av_strcasecmp(tagname, "font")) { + if (tag_close && sptr > 0) { + struct font_tag *cur_tag = &stack[sptr--]; + struct font_tag *last_tag = &stack[sptr]; + + if (cur_tag->size) { + if (!last_tag->size) + av_bprintf(dst, "{\\fs}"); + else if (last_tag->size != cur_tag->size) + av_bprintf(dst, "{\\fs%d}", last_tag->size); + } + + if (cur_tag->color & 0xff000000) { + if (!(last_tag->color & 0xff000000)) + av_bprintf(dst, "{\\c}"); + else if (last_tag->color != cur_tag->color) + av_bprintf(dst, "{\\c&H%X&}", last_tag->color & 0xffffff); + } + + if (cur_tag->face[0]) { + if (!last_tag->face[0]) + av_bprintf(dst, "{\\fn}"); + else if (strcmp(last_tag->face, cur_tag->face)) + av_bprintf(dst, "{\\fn%s}", last_tag->face); + } + } else if (!tag_close && sptr < FF_ARRAY_ELEMS(stack) - 1) { + struct font_tag *new_tag = &stack[sptr + 1]; + + *new_tag = stack[sptr++]; + while (param) { if (!av_strncasecmp(param, "size=", 5)) { - unsigned font_size; param += 5 + (param[5] == '"'); - if (sscanf(param, "%u", &font_size) == 1) { - snprintf(stack[sptr].param[PARAM_SIZE], - sizeof(stack[0].param[PARAM_SIZE]), - "{\\fs%u}", font_size); - } + if (sscanf(param, "%u", &new_tag->size) == 1) + av_bprintf(dst, "{\\fs%u}", new_tag->size); } else if (!av_strncasecmp(param, "color=", 6)) { + int color; param += 6 + (param[6] == '"'); - snprintf(stack[sptr].param[PARAM_COLOR], - sizeof(stack[0].param[PARAM_COLOR]), - "{\\c&H%X&}", - html_color_parse(log_ctx, param)); + color = html_color_parse(log_ctx, param); + if (color >= 0) { + new_tag->color = 0xff000000 | color; + av_bprintf(dst, "{\\c&H%X&}", new_tag->color & 0xffffff); + } } else if (!av_strncasecmp(param, "face=", 5)) { param += 5 + (param[5] == '"'); len = strcspn(param, param[-1] == '"' ? "\"" :" "); - av_strlcpy(tmp, param, - FFMIN(sizeof(tmp), len+1)); + av_strlcpy(new_tag->face, param, + FFMIN(sizeof(new_tag->face), len+1)); param += len; - snprintf(stack[sptr].param[PARAM_FACE], - sizeof(stack[0].param[PARAM_FACE]), - "{\\fn%s}", tmp); + av_bprintf(dst, "{\\fn%s}", new_tag->face); } if ((param = strchr(param, ' '))) param++; } - for (i=0; i", tagname); - } - if (tag_close) { - sptr--; - } else if (unknown && !strstr(in, tmp)) { - in -= len + tag_close; - av_bprint_chars(dst, *in, 1); - } else - av_strlcpy(stack[sptr++].tag, tagname, - sizeof(stack[0].tag)); - break; + av_bprint_chars(dst, '<', 1); } + } else { + av_bprint_chars(dst, *in, 1); } + break; default: av_bprint_chars(dst, *in, 1); break; diff --git a/tests/ref/fate/sub-sami2 b/tests/ref/fate/sub-sami2 index 9e9c80870d709..64656f06cbdd3 100644 --- a/tests/ref/fate/sub-sami2 +++ b/tests/ref/fate/sub-sami2 @@ -19,7 +19,7 @@ Dialogue: 0,0:00:17.67,0:00:21.72,Default,,0,0,0,,\N{\c&HCBC0FF&}{\fs6}It's{\fs} Dialogue: 0,0:00:21.84,0:00:21.84,Default,,0,0,0,,\N{\u1}매력적인 세계에서\N이 모든 것이 펼쳐집니다{\u1} Dialogue: 0,0:00:21.84,0:00:23.58,Default,,0,0,0,,\N{\i1}{\c&H9966CC&}of{\c}{\c&HC2A3E0&} what's{\c} {\c&HE0D1F0&}right{\c} {\c&HFCFAFE&}and{\c} wrong.{\i0} Dialogue: 0,0:00:23.69,0:00:23.69,Default,,0,0,0,,\N{\i1}이 주제를 심오한 철학으로\N담아내고 있어요{\i0} -Dialogue: 0,0:00:23.69,0:00:25.67,Default,,0,0,0,,\N{\fs20}{\c&HFF0000&}{\s1}It{\s0}{\c}{\fs} has {\fs15}{\c&HFFFF00&}a{\c}{\fs} great {\fs16}{\c&HFFCC00&}philosophy{\c}{\fs} about it. +Dialogue: 0,0:00:23.69,0:00:25.67,Default,,0,0,0,,\N{\c&HFF0000&}{\fs20}{\s1}It{\s0}{\fs}{\c} has {\c&HFFFF00&}{\fs15}a{\fs}{\c} great {\c&HFFCC00&}{\fs16}philosophy{\fs}{\c} about it. Dialogue: 0,0:00:40.22,0:00:40.22,Default,,0,0,0,,\N{\s1}"왕좌의 게임"은 웨스테로스라는 가상왕국의\N권력 분쟁 이야기입니다{\s0} Dialogue: 0,0:00:40.22,0:00:47.94,Default,,0,0,0,,\N{\c&HA5FF&}{\fs26}"Game of Thrones"{\fs}{\c} {\c&H2A2AA5&}{\b1}is{\b0}{\c}{\c&HFFFF&}{\fs24}{\i1} about{\i0}{\fs}{\c} {\c&H336699&}{\fs14}power{\fs}{\c}{\c&HFF&} struggles{\c}\N{\c&HA5FF&}{\fs8}in a fantasy{\fs}{\c&HCBC0FF&} kingdom{\c&HA5FF&}, called {\fs6}Westeros.{\fs}{\c} Dialogue: 0,0:00:48.06,0:00:48.06,Default,,0,0,0,,\N철의 왕좌를 둘러싼\N권력 분쟁이죠 @@ -51,7 +51,7 @@ Dialogue: 0,0:01:28.98,0:01:33.89,Default,,0,0,0,,\N{\u1}this common threat, tha Dialogue: 0,0:01:34.01,0:01:35.24,Default,,0,0,0,,\Npursuing their own interests. Dialogue: 0,0:01:35.36,0:01:35.36,Default,,0,0,0,,\N한편, 일곱 왕국의 밖에서는\N두 개의 거대한 위협이 부상합니다 Dialogue: 0,0:01:35.36,0:01:40.23,Default,,0,0,0,,\N{\fs30}And meanwhile, outside the Seven\NKingdoms, two great threats arising.{\fs} -Dialogue: 0,0:01:40.35,0:01:40.35,Default,,0,0,0,,\N하나는 바다 건너\N타가리엔 일족 유배자들이며 +Dialogue: 0,0:01:40.35,0:01:40.35,Default,,0,0,0,,\N하나는 바다 건너\N타가리엔 일족 유배자들이며 Dialogue: 0,0:01:40.35,0:01:44.06,Default,,0,0,0,,\NOne across the sea, in the exile\NTargaryen siblings, Dialogue: 0,0:01:44.17,0:01:44.17,Default,,0,0,0,,\N또 하나는 일곱 왕국의\N국경이 자리잡은 Dialogue: 0,0:01:44.17,0:01:47.39,Default,,0,0,0,,\Nand another far to the north,\Nbeyond the Wall, diff --git a/tests/ref/fate/sub-srt b/tests/ref/fate/sub-srt index 40b20cde90407..fd602909299ca 100644 --- a/tests/ref/fate/sub-srt +++ b/tests/ref/fate/sub-srt @@ -14,10 +14,10 @@ Dialogue: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,,Don't show this text it may be Dialogue: 0,0:00:01.50,0:00:04.50,Default,,0,0,0,,SubRip subtitles capability tester 1.3o by ale5000\N{\b1}{\i1}Use VLC 1.1 or higher as reference for most things and MPC Home Cinema for others{\i0}{\b0}\N{\c&HFF0000&}This text should be blue{\c}\N{\c&HFF&}This text should be red{\c}\N{\c&H0&}This text should be black{\c}\N{\fnWebdings}If you see this with the normal font, the player don't (fully) support font face{\fn} Dialogue: 0,0:00:04.50,0:00:04.50,Default,,0,0,0,,Hidden Dialogue: 0,0:00:04.50,0:00:07.50,Default,,0,0,0,,{\fs8}This text should be small{\fs}\NThis text should be normal\N{\fs35}This text should be big{\fs} -Dialogue: 0,0:00:07.50,0:00:11.50,Default,,0,0,0,,This should be an E with an accent: È\N日本語\N{\fs30}{\b1}{\i1}{\u1}This text should be bold, italics and underline{\u0}{\i0}{\b0}{\fs}\N{\fs9}{\c&HFF00&}This text should be small and green{\c}{\fs}\N{\fs9}{\c&HFF&}This text should be small and red{\c}{\fs}\N{\fs24}{\c&H2A2AA5&}This text should be big and brown{\c}{\fs} +Dialogue: 0,0:00:07.50,0:00:11.50,Default,,0,0,0,,This should be an E with an accent: È\N日本語\N{\fs30}{\b1}{\i1}{\u1}This text should be bold, italics and underline{\u0}{\i0}{\b0}{\fs}\N{\fs9}{\c&HFF00&}This text should be small and green{\fs}{\c}\N{\c&HFF&}{\fs9}This text should be small and red{\fs}{\c}\N{\c&H2A2AA5&}{\fs24}This text should be big and brown{\fs}{\c} Dialogue: 0,0:00:11.50,0:00:14.50,Default,,0,0,0,,{\b1}This line should be bold{\b0}\N{\i1}This line should be italics{\i0}\N{\u1}This line should be underline{\u0}\N{\s1}This line should be strikethrough{\s0}\N{\u1}Both lines\Nshould be underline{\u0} -Dialogue: 0,0:00:14.50,0:00:17.50,Default,,0,0,0,,>\NIt would be a good thing to\Nhide invalid html tags that are closed and show the text in them\Nbut show un-closed invalid html tags\NShow not opened tags\N< -Dialogue: 0,0:00:17.50,0:00:20.50,Default,,0,0,0,,and also\Nhide invalid html tags with parameters that are closed and show the text in them\Nbut show un-closed invalid html tags\N{\u1}This text should be showed underlined without problems also: 2<3,5>1,4<6{\u0}\NThis shouldn't be underlined +Dialogue: 0,0:00:14.50,0:00:17.50,Default,,0,0,0,,>\NIt would be a good thing to\Nhide invalid html tags that are closed and show the text in them\Nbut show un-closed invalid html tags\NShow not opened tags\N< +Dialogue: 0,0:00:17.50,0:00:20.50,Default,,0,0,0,,and also\Nhide invalid html tags with parameters that are closed and show the text in them\Nbut show un-closed invalid html tags\N{\u1}This text should be showed underlined without problems also: 2<3,5>1,4<6{\u0}\NThis shouldn't be underlined Dialogue: 0,0:00:20.50,0:00:21.50,Default,,0,0,0,,This text should be in the normal position... Dialogue: 0,0:00:21.50,0:00:22.50,Default,,0,0,0,,{\an5}{\pos(0,45)}This text should NOT be in the normal position Dialogue: 0,0:00:22.50,0:00:24.50,Default,,0,0,0,,Implementation is the same of the ASS tag\N{\an8}This text should be at the\Ntop and horizontally centered @@ -29,7 +29,7 @@ Dialogue: 0,0:00:24.50,0:00:26.50,Default,,0,0,0,,{\an1}This text should be at t Dialogue: 0,0:00:26.50,0:00:28.50,Default,,0,0,0,,{\an9}This text should be at the\Ntop and horizontally at the right Dialogue: 0,0:00:26.50,0:00:28.50,Default,,0,0,0,,{\an6}This text should be at the\Nmiddle and horizontally at the right Dialogue: 0,0:00:26.50,0:00:28.50,Default,,0,0,0,,{\an3}This text should be at the\Nbottom and horizontally at the right -Dialogue: 0,0:00:28.50,0:00:31.50,Default,,0,0,0,,{\fs6}{\c&HFF00&}This could be the {\fs35}m{\c&H0&}o{\c&HFF00&}st{\fs6} difficult thing to implement{\c}{\fs} +Dialogue: 0,0:00:28.50,0:00:31.50,Default,,0,0,0,,{\c&HFF00&}{\fs6}This could be the {\fs35}m{\c&H0&}o{\c&HFF00&}st{\fs6} difficult thing to implement{\fs}{\c} Dialogue: 0,0:00:31.50,0:00:50.50,Default,,0,0,0,,First text Dialogue: 0,0:00:33.50,0:00:35.50,Default,,0,0,0,,Second, it shouldn't overlap first Dialogue: 0,0:00:35.50,0:00:37.50,Default,,0,0,0,,Third, it should replace second @@ -44,6 +44,6 @@ Dialogue: 0,0:00:54.50,0:00:56.50,Default,,0,0,0,,{\an1}\N\h\h\h\h\hA (05 hard s Dialogue: 0,0:00:56.50,0:00:58.50,Default,,0,0,0,,\h\h\h\h\hA (05 hard spaces followed by a letter)\NA (Normal spaces followed by a letter)\NA (No hard spaces followed by a letter)\NShow this: \TEST and this: \-) Dialogue: 0,0:00:58.50,0:01:00.50,Default,,0,0,0,,{\an3}\NA letter followed by 05 hard spaces: A\h\h\h\h\h\NA letter followed by normal spaces: A\NA letter followed by no hard spaces: A\N05 hard spaces between letters: A\h\h\h\h\hA\N5 normal spaces between letters: A A\N\N^--Forced line break Dialogue: 0,0:01:00.50,0:01:02.50,Default,,0,0,0,,{\s1}Both line should be strikethrough,\Nyes.{\s0}\NCorrectly closed tags\Nshould be hidden. -Dialogue: 0,0:01:02.50,0:01:04.50,Default,,0,0,0,,It shouldn't be strikethrough,\Nnot opened tag showed as text.\NNot opened tag showed as text. -Dialogue: 0,0:01:04.50,0:01:06.50,Default,,0,0,0,,{\s1}Three lines should be strikethrough,\Nyes.\NNot closed tags showed as text -Dialogue: 0,0:01:06.50,0:01:08.50,Default,,0,0,0,,{\s1}Both line should be strikethrough but\Nthe wrong closing tag should be showed +Dialogue: 0,0:01:02.50,0:01:04.50,Default,,0,0,0,,It shouldn't be strikethrough,\Nnot opened tag showed as text.{\s0}\NNot opened tag showed as text. +Dialogue: 0,0:01:04.50,0:01:06.50,Default,,0,0,0,,{\s1}Three lines should be strikethrough,\Nyes.\NNot closed tags showed as text +Dialogue: 0,0:01:06.50,0:01:08.50,Default,,0,0,0,,{\s1}Both line should be strikethrough but\Nthe wrong closing tag should be showed{\b0} diff --git a/tests/ref/fate/sub-srt-badsyntax b/tests/ref/fate/sub-srt-badsyntax index 1ee2f95dccc14..791e00e691a37 100644 --- a/tests/ref/fate/sub-srt-badsyntax +++ b/tests/ref/fate/sub-srt-badsyntax @@ -14,8 +14,8 @@ Dialogue: 0,0:00:01.00,0:00:02.31,Default,,0,0,0,,<<<<<< Antes <<<<<<\NEla é hu Dialogue: 0,0:01:10.00,0:01:14.50,Default,,0,0,0,,>>> RebelSubTeam <<< Dialogue: 0,0:02:37.75,0:02:43.70,Default,,0,0,0,,{\b1}~ASUKO MARCH!~\N>>:<<\Ntranslation by: cangii\NRetiming by: furransu{\b0} Dialogue: 0,0:03:38.32,0:03:42.78,Default,,0,0,0,,<>\N<> -Dialogue: 0,0:04:50.43,0:05:01.03,Default,,0,0,0,,<pisode 4\Nsaison 1>\Nwww.SeriesSub.com> -Dialogue: 0,0:20:31.85,0:20:56.84,Default,,0,0,0,,{\c&HFFFFFFFF&}\N<<<>>>{\c} +Dialogue: 0,0:04:50.43,0:05:01.03,Default,,0,0,0,,<\Nwww.SeriesSub.com> +Dialogue: 0,0:20:31.85,0:20:56.84,Default,,0,0,0,,\N<<<>>> Dialogue: 0,0:37:59.69,0:38:01.59,Default,,0,0,0,,mint asztalt foglaltatni\Na <<>Le Cirque-ben. Dialogue: 0,0:53:43.78,0:53:45.94,Default,,0,0,0,,<> - he calmed himself. Dialogue: 0,0:53:46.22,0:53:49.09,Default,,0,0,0,,< It would be a good thing to hide invalid html tags that are closed and show the text in them -but show un-closed invalid html tags -Show not opened tags +but show un-closed invalid html tags +Show not opened tags < 8 00:00:17,501 --> 00:00:20,500 and also hide invalid html tags with parameters that are closed and show the text in them -but show un-closed invalid html tags +but show un-closed invalid html tags This text should be showed underlined without problems also: 2<3,5>1,4<6 This shouldn't be underlined @@ -197,17 +197,17 @@ should be hidden. 35 00:01:02,501 --> 00:01:04,500 It shouldn't be strikethrough, -not opened tag showed as text. -Not opened tag showed as text. +not opened tag showed as text. +Not opened tag showed as text. 36 00:01:04,501 --> 00:01:06,500 Three lines should be strikethrough, yes. -Not closed tags showed as text +Not closed tags showed as text 37 00:01:06,501 --> 00:01:08,500 Both line should be strikethrough but -the wrong closing tag should be showed +the wrong closing tag should be showed diff --git a/tests/ref/fate/sub-webvttenc b/tests/ref/fate/sub-webvttenc index ba567c33f68c0..45ae0b6131b66 100644 --- a/tests/ref/fate/sub-webvttenc +++ b/tests/ref/fate/sub-webvttenc @@ -39,14 +39,14 @@ should be underline > It would be a good thing to hide invalid html tags that are closed and show the text in them -but show un-closed invalid html tags -Show not opened tags +but show un-closed invalid html tags +Show not opened tags < 00:17.501 --> 00:20.500 and also hide invalid html tags with parameters that are closed and show the text in them -but show un-closed invalid html tags +but show un-closed invalid html tags This text should be showed underlined without problems also: 2<3,5>1,4<6 This shouldn't be underlined @@ -164,14 +164,14 @@ should be hidden. 01:02.501 --> 01:04.500 It shouldn't be strikethrough, -not opened tag showed as text. -Not opened tag showed as text. +not opened tag showed as text. +Not opened tag showed as text. 01:04.501 --> 01:06.500 Three lines should be strikethrough, yes. -Not closed tags showed as text +Not closed tags showed as text 01:06.501 --> 01:08.500 Both line should be strikethrough but -the wrong closing tag should be showed +the wrong closing tag should be showed From 55949e3e51890de36574d8b5c27889b44108a839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sat, 29 Jul 2017 20:56:55 +0200 Subject: [PATCH 2698/3374] lavc/tests: add htmlsubtitles --- libavcodec/Makefile | 1 + libavcodec/tests/.gitignore | 1 + libavcodec/tests/htmlsubtitles.c | 49 +++++++++++++++++++++++++ tests/fate/libavcodec.mak | 4 ++ tests/ref/fate/libavcodec-htmlsubtitles | 7 ++++ 5 files changed, 62 insertions(+) create mode 100644 libavcodec/tests/htmlsubtitles.c create mode 100644 tests/ref/fate/libavcodec-htmlsubtitles diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 74de41ab0fe05..b0c39ac04046b 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -1041,6 +1041,7 @@ SKIPHEADERS-$(CONFIG_VIDEOTOOLBOX) += videotoolbox.h vda_vt_internal.h TESTPROGS = avpacket \ celp_math \ + htmlsubtitles \ imgconvert \ jpeg2000dwt \ mathops \ diff --git a/libavcodec/tests/.gitignore b/libavcodec/tests/.gitignore index f22ac821cbea8..31947bf9bbc93 100644 --- a/libavcodec/tests/.gitignore +++ b/libavcodec/tests/.gitignore @@ -6,6 +6,7 @@ /fft-fixed /fft-fixed32 /golomb +/htmlsubtitles /iirfilter /imgconvert /jpeg2000dwt diff --git a/libavcodec/tests/htmlsubtitles.c b/libavcodec/tests/htmlsubtitles.c new file mode 100644 index 0000000000000..d0b55a45d36b9 --- /dev/null +++ b/libavcodec/tests/htmlsubtitles.c @@ -0,0 +1,49 @@ +/* + * 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 "libavutil/common.h" +#include "libavcodec/htmlsubtitles.c" + +static const char * const test_cases[] = { + /* latin guillemets and other < > garbage */ + "<>", // guillemets + "<<hello>>", // guillemets + tags + "< hello < 2000 > world >", // unlikely tags due to spaces + "

TITLE

", // likely unhandled tags + "< font color=red >red", // invalid format of valid tag + "Foo ", // not a tag (not alnum) + + " foo bar bla ", // broken nesting +}; + +int main(void) +{ + int i; + AVBPrint dst; + + av_bprint_init(&dst, 0, AV_BPRINT_SIZE_UNLIMITED); + for (i = 0; i < FF_ARRAY_ELEMS(test_cases); i++) { + int ret = ff_htmlmarkup_to_ass(NULL, &dst, test_cases[i]); + if (ret < 0) + return ret; + printf("%s --> %s\n", test_cases[i], dst.str); + av_bprint_clear(&dst); + } + av_bprint_finalize(&dst, NULL); + return 0; +} diff --git a/tests/fate/libavcodec.mak b/tests/fate/libavcodec.mak index b1e3446d68994..fc8075c532576 100644 --- a/tests/fate/libavcodec.mak +++ b/tests/fate/libavcodec.mak @@ -82,5 +82,9 @@ fate-libavcodec-huffman: CMD = run libavcodec/tests/mjpegenc_huffman fate-libavcodec-huffman: CMP = null fate-libavcodec-huffman: REF = /dev/null +FATE_LIBAVCODEC-yes += fate-libavcodec-htmlsubtitles +fate-libavcodec-htmlsubtitles: libavcodec/tests/htmlsubtitles$(EXESUF) +fate-libavcodec-htmlsubtitles: CMD = run libavcodec/tests/htmlsubtitles + FATE-$(CONFIG_AVCODEC) += $(FATE_LIBAVCODEC-yes) fate-libavcodec: $(FATE_LIBAVCODEC-yes) diff --git a/tests/ref/fate/libavcodec-htmlsubtitles b/tests/ref/fate/libavcodec-htmlsubtitles new file mode 100644 index 0000000000000..702f0b7ea307b --- /dev/null +++ b/tests/ref/fate/libavcodec-htmlsubtitles @@ -0,0 +1,7 @@ +<> --> <> +<<hello>> --> <<{\b1}hello{\b0}>> +< hello < 2000 > world > --> < hello < 2000 > world > +

TITLE

--> TITLE +< font color=red >red --> {\c&HFF&}red{\c} +Foo --> Foo + foo bar bla --> {\b1} foo {\i1} bar {\b0} bla {\i0} From e80037186327f97fffad75161e7d71cd9f5685f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sat, 29 Jul 2017 21:09:54 +0200 Subject: [PATCH 2699/3374] lavc/htmlsubtitles: improve line breaks handling --- libavcodec/htmlsubtitles.c | 5 +++-- libavcodec/tests/htmlsubtitles.c | 2 ++ tests/ref/fate/libavcodec-htmlsubtitles | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/libavcodec/htmlsubtitles.c b/libavcodec/htmlsubtitles.c index baed28450ef24..ae2c48b501149 100644 --- a/libavcodec/htmlsubtitles.c +++ b/libavcodec/htmlsubtitles.c @@ -165,7 +165,7 @@ int ff_htmlmarkup_to_ass(void *log_ctx, AVBPrint *dst, const char *in) #define LIKELY_A_TAG_CHAR(x) (((x) >= '0' && (x) <= '9') || \ ((x) >= 'a' && (x) <= 'z') || \ ((x) >= 'A' && (x) <= 'Z') || \ - (x) == '_') + (x) == '_' || (x) == '/') for (i = 0; tagname[i]; i++) { if (!LIKELY_A_TAG_CHAR(tagname[i])) { likely_a_tag = 0; @@ -237,7 +237,8 @@ int ff_htmlmarkup_to_ass(void *log_ctx, AVBPrint *dst, const char *in) } else if (tagname[0] && !tagname[1] && strchr("bisu", av_tolower(tagname[0]))) { av_bprintf(dst, "{\\%c%d}", (char)av_tolower(tagname[0]), !tag_close); in += skip; - } else if (!av_strcasecmp(tagname, "br")) { + } else if (!av_strncasecmp(tagname, "br", 2) && + (!tagname[2] || (tagname[2] == '/' && !tagname[3]))) { av_bprintf(dst, "\\N"); in += skip; } else if (likely_a_tag) { diff --git a/libavcodec/tests/htmlsubtitles.c b/libavcodec/tests/htmlsubtitles.c index d0b55a45d36b9..7c89ee97af952 100644 --- a/libavcodec/tests/htmlsubtitles.c +++ b/libavcodec/tests/htmlsubtitles.c @@ -29,6 +29,8 @@ static const char * const test_cases[] = { "Foo ", // not a tag (not alnum) " foo bar bla ", // broken nesting + + "A
B
C
D< Br >E", // misc line breaks }; int main(void) diff --git a/tests/ref/fate/libavcodec-htmlsubtitles b/tests/ref/fate/libavcodec-htmlsubtitles index 702f0b7ea307b..66dd8e8d48d2a 100644 --- a/tests/ref/fate/libavcodec-htmlsubtitles +++ b/tests/ref/fate/libavcodec-htmlsubtitles @@ -5,3 +5,4 @@ < font color=red >red --> {\c&HFF&}red{\c} Foo --> Foo foo bar bla --> {\b1} foo {\i1} bar {\b0} bla {\i0} +A
B
C
D< Br >E --> A\NB\NC\ND\NE From 479ab8c3f842145fcdd87a574b3fd7b4022034a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sat, 29 Jul 2017 21:22:17 +0200 Subject: [PATCH 2700/3374] lavc/htmlsubtitles: handle colors starting with many '#' --- libavcodec/htmlsubtitles.c | 4 ++++ tests/ref/fate/sub-srt-badsyntax | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/libavcodec/htmlsubtitles.c b/libavcodec/htmlsubtitles.c index ae2c48b501149..3205d57149057 100644 --- a/libavcodec/htmlsubtitles.c +++ b/libavcodec/htmlsubtitles.c @@ -28,6 +28,10 @@ static int html_color_parse(void *log_ctx, const char *str) { uint8_t rgba[4]; + int nb_sharps = 0; + while (str[nb_sharps] == '#') + nb_sharps++; + str += FFMAX(0, nb_sharps - 1); if (av_parse_color(rgba, str, strcspn(str, "\" >"), log_ctx) < 0) return -1; return rgba[0] | rgba[1] << 8 | rgba[2] << 16; diff --git a/tests/ref/fate/sub-srt-badsyntax b/tests/ref/fate/sub-srt-badsyntax index 791e00e691a37..1561d3f2f25ca 100644 --- a/tests/ref/fate/sub-srt-badsyntax +++ b/tests/ref/fate/sub-srt-badsyntax @@ -15,7 +15,7 @@ Dialogue: 0,0:01:10.00,0:01:14.50,Default,,0,0,0,,>>> RebelSubTeam <<< Dialogue: 0,0:02:37.75,0:02:43.70,Default,,0,0,0,,{\b1}~ASUKO MARCH!~\N>>:<<\Ntranslation by: cangii\NRetiming by: furransu{\b0} Dialogue: 0,0:03:38.32,0:03:42.78,Default,,0,0,0,,<>\N<> Dialogue: 0,0:04:50.43,0:05:01.03,Default,,0,0,0,,<\Nwww.SeriesSub.com> -Dialogue: 0,0:20:31.85,0:20:56.84,Default,,0,0,0,,\N<<<>>> +Dialogue: 0,0:20:31.85,0:20:56.84,Default,,0,0,0,,{\c&HFFFF&}\N<<<>>>{\c} Dialogue: 0,0:37:59.69,0:38:01.59,Default,,0,0,0,,mint asztalt foglaltatni\Na <<>Le Cirque-ben. Dialogue: 0,0:53:43.78,0:53:45.94,Default,,0,0,0,,<> - he calmed himself. Dialogue: 0,0:53:46.22,0:53:49.09,Default,,0,0,0,,< Date: Sat, 29 Jul 2017 21:24:34 +0200 Subject: [PATCH 2701/3374] lavc/htmlsubtitles: reindent after previous commits --- libavcodec/htmlsubtitles.c | 76 ++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 40 deletions(-) diff --git a/libavcodec/htmlsubtitles.c b/libavcodec/htmlsubtitles.c index 3205d57149057..1492570a747c1 100644 --- a/libavcodec/htmlsubtitles.c +++ b/libavcodec/htmlsubtitles.c @@ -177,8 +177,6 @@ int ff_htmlmarkup_to_ass(void *log_ctx, AVBPrint *dst, const char *in) } } - // TODO: reindent - if (!av_strcasecmp(tagname, "font")) { if (tag_close && sptr > 0) { struct font_tag *cur_tag = &stack[sptr--]; @@ -209,48 +207,46 @@ int ff_htmlmarkup_to_ass(void *log_ctx, AVBPrint *dst, const char *in) *new_tag = stack[sptr++]; - while (param) { - if (!av_strncasecmp(param, "size=", 5)) { - param += 5 + (param[5] == '"'); - if (sscanf(param, "%u", &new_tag->size) == 1) - av_bprintf(dst, "{\\fs%u}", new_tag->size); - } else if (!av_strncasecmp(param, "color=", 6)) { - int color; - param += 6 + (param[6] == '"'); - color = html_color_parse(log_ctx, param); - if (color >= 0) { - new_tag->color = 0xff000000 | color; - av_bprintf(dst, "{\\c&H%X&}", new_tag->color & 0xffffff); - } - } else if (!av_strncasecmp(param, "face=", 5)) { - param += 5 + (param[5] == '"'); - len = strcspn(param, - param[-1] == '"' ? "\"" :" "); - av_strlcpy(new_tag->face, param, - FFMIN(sizeof(new_tag->face), len+1)); - param += len; - av_bprintf(dst, "{\\fn%s}", new_tag->face); + while (param) { + if (!av_strncasecmp(param, "size=", 5)) { + param += 5 + (param[5] == '"'); + if (sscanf(param, "%u", &new_tag->size) == 1) + av_bprintf(dst, "{\\fs%u}", new_tag->size); + } else if (!av_strncasecmp(param, "color=", 6)) { + int color; + param += 6 + (param[6] == '"'); + color = html_color_parse(log_ctx, param); + if (color >= 0) { + new_tag->color = 0xff000000 | color; + av_bprintf(dst, "{\\c&H%X&}", new_tag->color & 0xffffff); } - if ((param = strchr(param, ' '))) - param++; + } else if (!av_strncasecmp(param, "face=", 5)) { + param += 5 + (param[5] == '"'); + len = strcspn(param, + param[-1] == '"' ? "\"" :" "); + av_strlcpy(new_tag->face, param, + FFMIN(sizeof(new_tag->face), len+1)); + param += len; + av_bprintf(dst, "{\\fn%s}", new_tag->face); } + if ((param = strchr(param, ' '))) + param++; } - + } in += skip; - - } else if (tagname[0] && !tagname[1] && strchr("bisu", av_tolower(tagname[0]))) { - av_bprintf(dst, "{\\%c%d}", (char)av_tolower(tagname[0]), !tag_close); - in += skip; - } else if (!av_strncasecmp(tagname, "br", 2) && - (!tagname[2] || (tagname[2] == '/' && !tagname[3]))) { - av_bprintf(dst, "\\N"); - in += skip; - } else if (likely_a_tag) { - if (!tag_close) // warn only once - av_log(log_ctx, AV_LOG_WARNING, "Unrecognized tag %s\n", tagname); - in += skip; - } else { - av_bprint_chars(dst, '<', 1); + } else if (tagname[0] && !tagname[1] && strchr("bisu", av_tolower(tagname[0]))) { + av_bprintf(dst, "{\\%c%d}", (char)av_tolower(tagname[0]), !tag_close); + in += skip; + } else if (!av_strncasecmp(tagname, "br", 2) && + (!tagname[2] || (tagname[2] == '/' && !tagname[3]))) { + av_bprintf(dst, "\\N"); + in += skip; + } else if (likely_a_tag) { + if (!tag_close) // warn only once + av_log(log_ctx, AV_LOG_WARNING, "Unrecognized tag %s\n", tagname); + in += skip; + } else { + av_bprint_chars(dst, '<', 1); } } else { av_bprint_chars(dst, *in, 1); From c79e7534712fa9e95a9ddde2c5e8c6815f5f2f6f Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Tue, 1 Aug 2017 11:32:22 +0200 Subject: [PATCH 2702/3374] avfilter: add unpremultiply filter Signed-off-by: Paul B Mahol --- Changelog | 1 + doc/filters.texi | 19 +++ libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/version.h | 2 +- libavfilter/vf_premultiply.c | 307 ++++++++++++++++++++++++++++++----- 6 files changed, 285 insertions(+), 46 deletions(-) diff --git a/Changelog b/Changelog index 187ae7950a8b7..30749420213cc 100644 --- a/Changelog +++ b/Changelog @@ -29,6 +29,7 @@ version : - limiter video filter - libvmaf video filter - Dolby E decoder and SMPTE 337M demuxer +- unpremultiply video filter version 3.3: - CrystalHD decoder moved to new decode API diff --git a/doc/filters.texi b/doc/filters.texi index 4089135807478..96abffbbdd041 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -14532,6 +14532,25 @@ ffmpeg -i INPUT -vf trim=duration=1 @end itemize +@section unpremultiply +Apply alpha unpremultiply effect to input video stream using first plane +of second stream as alpha. + +Both streams must have same dimensions and same pixel format. + +The filter accepts the following option: + +@table @option +@item planes +Set which planes will be processed, unprocessed planes will be copied. +By default value 0xf, all planes will be processed. + +If the format has 1 or 2 components, then luma is bit 0. +If the format has 3 or 4 components: +for RGB formats bit 0 is green, bit 1 is blue and bit 2 is red; +for YUV formats bit 0 is luma, bit 1 is chroma-U and bit 2 is chroma-V. +If present, the alpha channel is always the last bit. +@end table @anchor{unsharp} @section unsharp diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 4d61d7835e99b..f0bb8e77e51e7 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -314,6 +314,7 @@ OBJS-$(CONFIG_TILE_FILTER) += vf_tile.o OBJS-$(CONFIG_TINTERLACE_FILTER) += vf_tinterlace.o OBJS-$(CONFIG_TRANSPOSE_FILTER) += vf_transpose.o OBJS-$(CONFIG_TRIM_FILTER) += trim.o +OBJS-$(CONFIG_UNPREMULTIPLY_FILTER) += vf_premultiply.o framesync2.o OBJS-$(CONFIG_UNSHARP_FILTER) += vf_unsharp.o OBJS-$(CONFIG_USPP_FILTER) += vf_uspp.o OBJS-$(CONFIG_VAGUEDENOISER_FILTER) += vf_vaguedenoiser.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index b1c2d11024811..0fca662a234f5 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -325,6 +325,7 @@ static void register_all(void) REGISTER_FILTER(TINTERLACE, tinterlace, vf); REGISTER_FILTER(TRANSPOSE, transpose, vf); REGISTER_FILTER(TRIM, trim, vf); + REGISTER_FILTER(UNPREMULTIPLY, unpremultiply, vf); REGISTER_FILTER(UNSHARP, unsharp, vf); REGISTER_FILTER(USPP, uspp, vf); REGISTER_FILTER(VAGUEDENOISER, vaguedenoiser, vf); diff --git a/libavfilter/version.h b/libavfilter/version.h index a252aec17839e..01dd1dbb7285f 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 6 -#define LIBAVFILTER_VERSION_MINOR 95 +#define LIBAVFILTER_VERSION_MINOR 96 #define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vf_premultiply.c b/libavfilter/vf_premultiply.c index 4bb850edd5f22..9ecafe42d8adf 100644 --- a/libavfilter/vf_premultiply.c +++ b/libavfilter/vf_premultiply.c @@ -33,7 +33,8 @@ typedef struct PreMultiplyContext { int linesize[4]; int nb_planes; int planes; - int half, depth, offset; + int inverse; + int half, depth, offset, max; FFFrameSync fs; void (*premultiply[4])(const uint8_t *msrc, const uint8_t *asrc, @@ -47,11 +48,12 @@ typedef struct PreMultiplyContext { #define OFFSET(x) offsetof(PreMultiplyContext, x) #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM -static const AVOption premultiply_options[] = { +static const AVOption options[] = { { "planes", "set planes", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=0xF}, 0, 0xF, FLAGS }, { NULL } }; +#define premultiply_options options AVFILTER_DEFINE_CLASS(premultiply); static int query_formats(AVFilterContext *ctx) @@ -199,6 +201,153 @@ static void premultiply16offset(const uint8_t *mmsrc, const uint8_t *aasrc, } } +static void unpremultiply8(const uint8_t *msrc, const uint8_t *asrc, + uint8_t *dst, + ptrdiff_t mlinesize, ptrdiff_t alinesize, + ptrdiff_t dlinesize, + int w, int h, + int half, int max, int offset) +{ + int x, y; + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + if (asrc[x] > 0 && asrc[x] < 255) + dst[x] = FFMIN(msrc[x] * 255 / asrc[x], 255); + else + dst[x] = msrc[x]; + } + + dst += dlinesize; + msrc += mlinesize; + asrc += alinesize; + } +} + +static void unpremultiply8yuv(const uint8_t *msrc, const uint8_t *asrc, + uint8_t *dst, + ptrdiff_t mlinesize, ptrdiff_t alinesize, + ptrdiff_t dlinesize, + int w, int h, + int half, int max, int offset) +{ + int x, y; + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + if (asrc[x] > 0 && asrc[x] < 255) + dst[x] = FFMIN((msrc[x] - 128) * 255 / asrc[x] + 128, 255); + else + dst[x] = msrc[x]; + } + + dst += dlinesize; + msrc += mlinesize; + asrc += alinesize; + } +} + +static void unpremultiply8offset(const uint8_t *msrc, const uint8_t *asrc, + uint8_t *dst, + ptrdiff_t mlinesize, ptrdiff_t alinesize, + ptrdiff_t dlinesize, + int w, int h, + int half, int max, int offset) +{ + int x, y; + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + if (asrc[x] > 0 && asrc[x] < 255) + dst[x] = FFMIN((msrc[x] - offset) * 255 / asrc[x] + offset, 255); + else + dst[x] = msrc[x]; + } + + dst += dlinesize; + msrc += mlinesize; + asrc += alinesize; + } +} + +static void unpremultiply16(const uint8_t *mmsrc, const uint8_t *aasrc, + uint8_t *ddst, + ptrdiff_t mlinesize, ptrdiff_t alinesize, + ptrdiff_t dlinesize, + int w, int h, + int half, int max, int offset) +{ + const uint16_t *msrc = (const uint16_t *)mmsrc; + const uint16_t *asrc = (const uint16_t *)aasrc; + uint16_t *dst = (uint16_t *)ddst; + int x, y; + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + if (asrc[x] > 0 && asrc[x] < max) + dst[x] = FFMIN(msrc[x] * (unsigned)max / asrc[x], max); + else + dst[x] = msrc[x]; + } + + dst += dlinesize / 2; + msrc += mlinesize / 2; + asrc += alinesize / 2; + } +} + +static void unpremultiply16yuv(const uint8_t *mmsrc, const uint8_t *aasrc, + uint8_t *ddst, + ptrdiff_t mlinesize, ptrdiff_t alinesize, + ptrdiff_t dlinesize, + int w, int h, + int half, int max, int offset) +{ + const uint16_t *msrc = (const uint16_t *)mmsrc; + const uint16_t *asrc = (const uint16_t *)aasrc; + uint16_t *dst = (uint16_t *)ddst; + int x, y; + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + if (asrc[x] > 0 && asrc[x] < max) + dst[x] = FFMAX(FFMIN((msrc[x] - half) * max / asrc[x], half - 1), -half) + half; + else + dst[x] = msrc[x]; + } + + dst += dlinesize / 2; + msrc += mlinesize / 2; + asrc += alinesize / 2; + } +} + +static void unpremultiply16offset(const uint8_t *mmsrc, const uint8_t *aasrc, + uint8_t *ddst, + ptrdiff_t mlinesize, ptrdiff_t alinesize, + ptrdiff_t dlinesize, + int w, int h, + int half, int max, int offset) +{ + const uint16_t *msrc = (const uint16_t *)mmsrc; + const uint16_t *asrc = (const uint16_t *)aasrc; + uint16_t *dst = (uint16_t *)ddst; + int x, y; + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + if (asrc[x] > 0 && asrc[x] < max) + dst[x] = FFMAX(FFMIN((msrc[x] - offset) * (unsigned)max / asrc[x] + offset, max), 0); + else + dst[x] = msrc[x]; + } + + dst += dlinesize / 2; + msrc += mlinesize / 2; + asrc += alinesize / 2; + } +} + static int process_frame(FFFrameSync *fs) { AVFilterContext *ctx = fs->parent; @@ -226,48 +375,80 @@ static int process_frame(FFFrameSync *fs) full = base->color_range == AVCOL_RANGE_JPEG; limited = base->color_range == AVCOL_RANGE_MPEG; - switch (outlink->format) { - case AV_PIX_FMT_YUV444P: - s->premultiply[0] = full ? premultiply8 : premultiply8offset; - s->premultiply[1] = premultiply8yuv; - s->premultiply[2] = premultiply8yuv; - break; - case AV_PIX_FMT_YUVJ444P: - s->premultiply[0] = premultiply8; - s->premultiply[1] = premultiply8yuv; - s->premultiply[2] = premultiply8yuv; - break; - case AV_PIX_FMT_GBRP: - s->premultiply[0] = limited ? premultiply8offset : premultiply8; - s->premultiply[1] = limited ? premultiply8offset : premultiply8; - s->premultiply[2] = limited ? premultiply8offset : premultiply8; - break; - case AV_PIX_FMT_YUV444P9: - case AV_PIX_FMT_YUV444P10: - case AV_PIX_FMT_YUV444P12: - case AV_PIX_FMT_YUV444P14: - case AV_PIX_FMT_YUV444P16: - s->premultiply[0] = full ? premultiply16 : premultiply16offset; - s->premultiply[1] = premultiply16yuv; - s->premultiply[2] = premultiply16yuv; - break; - case AV_PIX_FMT_GBRP9: - case AV_PIX_FMT_GBRP10: - case AV_PIX_FMT_GBRP12: - case AV_PIX_FMT_GBRP14: - case AV_PIX_FMT_GBRP16: - s->premultiply[0] = limited ? premultiply16offset : premultiply16; - s->premultiply[1] = limited ? premultiply16offset : premultiply16; - s->premultiply[2] = limited ? premultiply16offset : premultiply16; - break; - case AV_PIX_FMT_GRAY8: - s->premultiply[0] = limited ? premultiply8offset : premultiply8; - break; - case AV_PIX_FMT_GRAY10: - case AV_PIX_FMT_GRAY12: - case AV_PIX_FMT_GRAY16: - s->premultiply[0] = limited ? premultiply16offset : premultiply16; - break; + if (s->inverse) { + switch (outlink->format) { + case AV_PIX_FMT_YUV444P: + s->premultiply[0] = full ? unpremultiply8 : unpremultiply8offset; + s->premultiply[1] = s->premultiply[2] = unpremultiply8yuv; + break; + case AV_PIX_FMT_YUVJ444P: + s->premultiply[0] = unpremultiply8; + s->premultiply[1] = s->premultiply[2] = unpremultiply8yuv; + break; + case AV_PIX_FMT_GBRP: + s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? unpremultiply8offset : unpremultiply8; + break; + case AV_PIX_FMT_YUV444P9: + case AV_PIX_FMT_YUV444P10: + case AV_PIX_FMT_YUV444P12: + case AV_PIX_FMT_YUV444P14: + case AV_PIX_FMT_YUV444P16: + s->premultiply[0] = full ? unpremultiply16 : unpremultiply16offset; + s->premultiply[1] = s->premultiply[2] = unpremultiply16yuv; + break; + case AV_PIX_FMT_GBRP9: + case AV_PIX_FMT_GBRP10: + case AV_PIX_FMT_GBRP12: + case AV_PIX_FMT_GBRP14: + case AV_PIX_FMT_GBRP16: + s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? unpremultiply16offset : unpremultiply16; + break; + case AV_PIX_FMT_GRAY8: + s->premultiply[0] = limited ? unpremultiply8offset : unpremultiply8; + break; + case AV_PIX_FMT_GRAY10: + case AV_PIX_FMT_GRAY12: + case AV_PIX_FMT_GRAY16: + s->premultiply[0] = limited ? unpremultiply16offset : unpremultiply16; + break; + } + } else { + switch (outlink->format) { + case AV_PIX_FMT_YUV444P: + s->premultiply[0] = full ? premultiply8 : premultiply8offset; + s->premultiply[1] = s->premultiply[2] = premultiply8yuv; + break; + case AV_PIX_FMT_YUVJ444P: + s->premultiply[0] = premultiply8; + s->premultiply[1] = s->premultiply[2] = premultiply8yuv; + break; + case AV_PIX_FMT_GBRP: + s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? premultiply8offset : premultiply8; + break; + case AV_PIX_FMT_YUV444P9: + case AV_PIX_FMT_YUV444P10: + case AV_PIX_FMT_YUV444P12: + case AV_PIX_FMT_YUV444P14: + case AV_PIX_FMT_YUV444P16: + s->premultiply[0] = full ? premultiply16 : premultiply16offset; + s->premultiply[1] = s->premultiply[2] = premultiply16yuv; + break; + case AV_PIX_FMT_GBRP9: + case AV_PIX_FMT_GBRP10: + case AV_PIX_FMT_GBRP12: + case AV_PIX_FMT_GBRP14: + case AV_PIX_FMT_GBRP16: + s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? premultiply16offset : premultiply16; + break; + case AV_PIX_FMT_GRAY8: + s->premultiply[0] = limited ? premultiply8offset : premultiply8; + break; + case AV_PIX_FMT_GRAY10: + case AV_PIX_FMT_GRAY12: + case AV_PIX_FMT_GRAY16: + s->premultiply[0] = limited ? premultiply16offset : premultiply16; + break; + } } for (p = 0; p < s->nb_planes; p++) { @@ -282,7 +463,7 @@ static int process_frame(FFFrameSync *fs) base->linesize[p], alpha->linesize[0], out->linesize[p], s->width[p], s->height[p], - s->half, s->depth, s->offset); + s->half, s->inverse ? s->max : s->depth, s->offset); } } out->pts = av_rescale_q(base->pts, s->fs.time_base, outlink->time_base); @@ -310,6 +491,7 @@ static int config_input(AVFilterLink *inlink) s->width[0] = s->width[3] = inlink->w; s->depth = desc->comp[0].depth; + s->max = (1 << s->depth) - 1; s->half = (1 << s->depth) / 2; s->offset = 16 << (s->depth - 8); @@ -369,6 +551,16 @@ static int activate(AVFilterContext *ctx) return ff_framesync2_activate(&s->fs); } +static av_cold int init(AVFilterContext *ctx) +{ + PreMultiplyContext *s = ctx->priv; + + if (!strcmp(ctx->filter->name, "unpremultiply")) + s->inverse = 1; + + return 0; +} + static av_cold void uninit(AVFilterContext *ctx) { PreMultiplyContext *s = ctx->priv; @@ -398,6 +590,8 @@ static const AVFilterPad premultiply_outputs[] = { { NULL } }; +#if CONFIG_PREMULTIPLY_FILTER + AVFilter ff_vf_premultiply = { .name = "premultiply", .description = NULL_IF_CONFIG_SMALL("PreMultiply first stream with first plane of second stream."), @@ -410,3 +604,26 @@ AVFilter ff_vf_premultiply = { .priv_class = &premultiply_class, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, }; + +#endif /* CONFIG_PREMULTIPLY_FILTER */ + +#if CONFIG_UNPREMULTIPLY_FILTER + +#define unpremultiply_options options +AVFILTER_DEFINE_CLASS(unpremultiply); + +AVFilter ff_vf_unpremultiply = { + .name = "unpremultiply", + .description = NULL_IF_CONFIG_SMALL("UnPreMultiply first stream with first plane of second stream."), + .priv_size = sizeof(PreMultiplyContext), + .init = init, + .uninit = uninit, + .query_formats = query_formats, + .activate = activate, + .inputs = premultiply_inputs, + .outputs = premultiply_outputs, + .priv_class = &unpremultiply_class, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, +}; + +#endif /* CONFIG_UNPREMULTIPLY_FILTER */ From 0aa8fa963f7965359d0eacc19b7e8db1f2288ce1 Mon Sep 17 00:00:00 2001 From: Aleksandr Slobodeniuk Date: Fri, 14 Jul 2017 14:03:20 +0300 Subject: [PATCH 2703/3374] avformat/riff.h : remove unused function parameter "const AVCodecTag *tags" of "void ff_put_bmp_header()" Reviewed-by: Derek Buitenhuis Signed-off-by: Michael Niedermayer --- libavformat/asfenc.c | 2 +- libavformat/avienc.c | 2 +- libavformat/matroskaenc.c | 2 +- libavformat/riff.h | 2 +- libavformat/riffenc.c | 2 +- libavformat/wtvenc.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libavformat/asfenc.c b/libavformat/asfenc.c index 1b67143afd814..3cfe75a5d5e0b 100644 --- a/libavformat/asfenc.c +++ b/libavformat/asfenc.c @@ -683,7 +683,7 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, avio_wl16(pb, 40 + par->extradata_size); /* size */ /* BITMAPINFOHEADER header */ - ff_put_bmp_header(pb, par, ff_codec_bmp_tags, 1, 0); + ff_put_bmp_header(pb, par, 1, 0); } end_header(pb, hpos); } diff --git a/libavformat/avienc.c b/libavformat/avienc.c index da3d3deb3bfbf..483f5b54b1464 100644 --- a/libavformat/avienc.c +++ b/libavformat/avienc.c @@ -450,7 +450,7 @@ static int avi_write_header(AVFormatContext *s) && par->bits_per_coded_sample == 15) par->bits_per_coded_sample = 16; avist->pal_offset = avio_tell(pb) + 40; - ff_put_bmp_header(pb, par, ff_codec_bmp_tags, 0, 0); + ff_put_bmp_header(pb, par, 0, 0); pix_fmt = avpriv_find_pix_fmt(avpriv_pix_fmt_bps_avi, par->bits_per_coded_sample); if ( !par->codec_tag diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 24114d6755b33..9cc7be352e27b 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -839,7 +839,7 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb, ret = AVERROR(EINVAL); } - ff_put_bmp_header(dyn_cp, par, ff_codec_bmp_tags, 0, 0); + ff_put_bmp_header(dyn_cp, par, 0, 0); } } else if (par->codec_type == AVMEDIA_TYPE_AUDIO) { unsigned int tag; diff --git a/libavformat/riff.h b/libavformat/riff.h index d30d793cd1d90..c916d1a587a32 100644 --- a/libavformat/riff.h +++ b/libavformat/riff.h @@ -45,7 +45,7 @@ void ff_end_tag(AVIOContext *pb, int64_t start); */ int ff_get_bmp_header(AVIOContext *pb, AVStream *st, unsigned *esize); -void ff_put_bmp_header(AVIOContext *pb, AVCodecParameters *par, const AVCodecTag *tags, int for_asf, int ignore_extradata); +void ff_put_bmp_header(AVIOContext *pb, AVCodecParameters *par, int for_asf, int ignore_extradata); /** * Tell ff_put_wav_header() to use WAVEFORMATEX even for PCM codecs. diff --git a/libavformat/riffenc.c b/libavformat/riffenc.c index c96329da48786..c04d55c4230dc 100644 --- a/libavformat/riffenc.c +++ b/libavformat/riffenc.c @@ -207,7 +207,7 @@ int ff_put_wav_header(AVFormatContext *s, AVIOContext *pb, /* BITMAPINFOHEADER header */ void ff_put_bmp_header(AVIOContext *pb, AVCodecParameters *par, - const AVCodecTag *tags, int for_asf, int ignore_extradata) + int for_asf, int ignore_extradata) { int keep_height = par->extradata_size >= 9 && !memcmp(par->extradata + par->extradata_size - 9, "BottomUp", 9); diff --git a/libavformat/wtvenc.c b/libavformat/wtvenc.c index a7ca1c39aab56..4925a60049876 100644 --- a/libavformat/wtvenc.c +++ b/libavformat/wtvenc.c @@ -241,7 +241,7 @@ static void put_videoinfoheader2(AVIOContext *pb, AVStream *st) avio_wl32(pb, 0); avio_wl32(pb, 0); - ff_put_bmp_header(pb, st->codecpar, ff_codec_bmp_tags, 0, 1); + ff_put_bmp_header(pb, st->codecpar, 0, 1); if (st->codecpar->codec_id == AV_CODEC_ID_MPEG2VIDEO) { int padding = (st->codecpar->extradata_size & 3) ? 4 - (st->codecpar->extradata_size & 3) : 0; From 50aeb6e4edf635147a6651859ec63d15a67f6b87 Mon Sep 17 00:00:00 2001 From: Aleksandr Slobodeniuk Date: Tue, 1 Aug 2017 14:48:39 +0300 Subject: [PATCH 2704/3374] avformat/riff: remove useless tag correlation 'mpg2'->MPEG1VIDEO. Signed-off-by: Michael Niedermayer --- libavformat/riff.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libavformat/riff.c b/libavformat/riff.c index 029e7efbd306f..3f0b390774fc7 100644 --- a/libavformat/riff.c +++ b/libavformat/riff.c @@ -153,7 +153,6 @@ const AVCodecTag ff_codec_bmp_tags[] = { { AV_CODEC_ID_DVVIDEO, MKTAG('S', 'L', 'D', 'V') }, { AV_CODEC_ID_DVVIDEO, MKTAG('A', 'V', 'd', '1') }, { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'g', '1') }, - { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'g', '2') }, { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'p', 'g', '2') }, { AV_CODEC_ID_MPEG2VIDEO, MKTAG('M', 'P', 'E', 'G') }, { AV_CODEC_ID_MPEG1VIDEO, MKTAG('P', 'I', 'M', '1') }, From d1bfa80ec464d475a0de3f513bbb62bcd356099a Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 1 Aug 2017 19:56:07 +0200 Subject: [PATCH 2705/3374] avcodec/h264idct_template: Fix integer overflow in ff_h264_idct_add() Fixes: runtime error: signed integer overflow: 26215360 + 2121330944 cannot be represented in type 'int' Fixes: 2809/clusterfuzz-testcase-minimized-4785181833560064 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg --- libavcodec/h264idct_template.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/h264idct_template.c b/libavcodec/h264idct_template.c index e1ef68756c7de..288107d5a4f27 100644 --- a/libavcodec/h264idct_template.c +++ b/libavcodec/h264idct_template.c @@ -40,10 +40,10 @@ void FUNCC(ff_h264_idct_add)(uint8_t *_dst, int16_t *_block, int stride) block[0] += 1 << 5; for(i=0; i<4; i++){ - const SUINT z0= block[i + 4*0] + block[i + 4*2]; - const SUINT z1= block[i + 4*0] - block[i + 4*2]; - const SUINT z2= (block[i + 4*1]>>1) - block[i + 4*3]; - const SUINT z3= block[i + 4*1] + (block[i + 4*3]>>1); + const SUINT z0= block[i + 4*0] + (unsigned)block[i + 4*2]; + const SUINT z1= block[i + 4*0] - (unsigned)block[i + 4*2]; + const SUINT z2= (block[i + 4*1]>>1) - (unsigned)block[i + 4*3]; + const SUINT z3= block[i + 4*1] + (unsigned)(block[i + 4*3]>>1); block[i + 4*0]= z0 + z3; block[i + 4*1]= z1 + z2; From 4ff94558f23a5de43aed4ca3429963dd1d995250 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 2 Aug 2017 00:46:49 +0200 Subject: [PATCH 2706/3374] avcodec/hevc_cabac: Check for ff_init_cabac_decoder() failure in cabac_reinit() Fixes: runtime error: left shift of negative value -967831544 Fixes: 2815/clusterfuzz-testcase-minimized-6062914471460864 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/hevc_cabac.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/libavcodec/hevc_cabac.c b/libavcodec/hevc_cabac.c index 4c14e77bcd23e..853fd3f72297c 100644 --- a/libavcodec/hevc_cabac.c +++ b/libavcodec/hevc_cabac.c @@ -462,9 +462,9 @@ static void load_states(HEVCContext *s) memcpy(s->HEVClc->cabac_state, s->cabac_state, HEVC_CONTEXTS); } -static void cabac_reinit(HEVCLocalContext *lc) +static int cabac_reinit(HEVCLocalContext *lc) { - skip_bytes(&lc->cc, 0); + return skip_bytes(&lc->cc, 0) == NULL ? AVERROR_INVALIDDATA : 0; } static int cabac_init_decoder(HEVCContext *s) @@ -524,25 +524,27 @@ int ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts) } else { if (s->ps.pps->tiles_enabled_flag && s->ps.pps->tile_id[ctb_addr_ts] != s->ps.pps->tile_id[ctb_addr_ts - 1]) { + int ret; if (s->threads_number == 1) - cabac_reinit(s->HEVClc); + ret = cabac_reinit(s->HEVClc); else { - int ret = cabac_init_decoder(s); - if (ret < 0) - return ret; + ret = cabac_init_decoder(s); } + if (ret < 0) + return ret; cabac_init_state(s); } if (s->ps.pps->entropy_coding_sync_enabled_flag) { if (ctb_addr_ts % s->ps.sps->ctb_width == 0) { + int ret; get_cabac_terminate(&s->HEVClc->cc); if (s->threads_number == 1) - cabac_reinit(s->HEVClc); + ret = cabac_reinit(s->HEVClc); else { - int ret = cabac_init_decoder(s); - if (ret < 0) - return ret; + ret = cabac_init_decoder(s); } + if (ret < 0) + return ret; if (s->ps.sps->ctb_width == 1) cabac_init_state(s); From effd2e7291a12760891289540f944d71ff32a1c8 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Thu, 3 Aug 2017 09:22:57 +0200 Subject: [PATCH 2707/3374] speedhq: fix behavior of single-field decoding The height convention for decoding frames with only a single field made sense for compatibility with legacy decoders, but doesn't really match the convention used by NDI, which is the primary (only?) user. Thus, change it to simply assuming that if the two fields overlap, the frame is meant to be a single field and the frame height matches the field height. Signed-off-by: James Almer --- libavcodec/speedhq.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libavcodec/speedhq.c b/libavcodec/speedhq.c index 60efb0222b276..47b1e4dc7a5b0 100644 --- a/libavcodec/speedhq.c +++ b/libavcodec/speedhq.c @@ -450,10 +450,13 @@ static int speedhq_decode_frame(AVCodecContext *avctx, if (second_field_offset == 4) { /* * Overlapping first and second fields is used to signal - * encoding only a single field (the second field then comes - * as a separate, later frame). + * encoding only a single field. In this case, "height" + * is ambiguous; it could mean either the height of the + * frame as a whole, or of the field. The former would make + * more sense for compatibility with legacy decoders, + * but this matches the convention used in NDI, which is + * the primary user of this trick. */ - frame->height >>= 1; if ((ret = decode_speedhq_field(s, buf, buf_size, frame, 0, 4, buf_size, 1)) < 0) return ret; } else { From 45ffe4645e682e0cd13a1c5c23de40dc1a00ff7c Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Thu, 3 Aug 2017 09:31:30 +0200 Subject: [PATCH 2708/3374] speedhq: add FATE tests Also add simple FATE tests, based on output produced by the NDI SDK. Signed-off-by: James Almer --- tests/Makefile | 1 + tests/fate/speedhq.mak | 8 ++++++++ tests/ref/fate/speedhq-422 | 6 ++++++ tests/ref/fate/speedhq-422-singlefield | 6 ++++++ 4 files changed, 21 insertions(+) create mode 100644 tests/fate/speedhq.mak create mode 100644 tests/ref/fate/speedhq-422 create mode 100644 tests/ref/fate/speedhq-422-singlefield diff --git a/tests/Makefile b/tests/Makefile index ab83ae855d83e..30f05bec15548 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -165,6 +165,7 @@ include $(SRC_PATH)/tests/fate/qtrle.mak include $(SRC_PATH)/tests/fate/real.mak include $(SRC_PATH)/tests/fate/screen.mak include $(SRC_PATH)/tests/fate/source.mak +include $(SRC_PATH)/tests/fate/speedhq.mak include $(SRC_PATH)/tests/fate/subtitles.mak include $(SRC_PATH)/tests/fate/utvideo.mak include $(SRC_PATH)/tests/fate/video.mak diff --git a/tests/fate/speedhq.mak b/tests/fate/speedhq.mak new file mode 100644 index 0000000000000..32405b710f136 --- /dev/null +++ b/tests/fate/speedhq.mak @@ -0,0 +1,8 @@ +FATE_SPEEDHQ = fate-speedhq-422 \ + fate-speedhq-422-singlefield + +fate-speedhq-422: CMD = framecrc -flags +bitexact -f rawvideo -c:v speedhq -tag:v SHQ2 -video_size 112x64 -i $(TARGET_SAMPLES)/speedhq/progressive.shq2 -pix_fmt yuv422p +fate-speedhq-422-singlefield: CMD = framecrc -flags +bitexact -f rawvideo -c:v speedhq -tag:v SHQ2 -video_size 112x32 -i $(TARGET_SAMPLES)/speedhq/singlefield.shq2 -pix_fmt yuv422p + +FATE_SAMPLES_FFMPEG-$(call DEMDEC, RAWVIDEO, SPEEDHQ) += $(FATE_SPEEDHQ) +fate-speedhq: $(FATE_SPEEDHQ) diff --git a/tests/ref/fate/speedhq-422 b/tests/ref/fate/speedhq-422 new file mode 100644 index 0000000000000..7bb0d2388d13b --- /dev/null +++ b/tests/ref/fate/speedhq-422 @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 112x64 +#sar 0: 0/1 +0, 0, 0, 1, 14336, 0x9bb6dc6d diff --git a/tests/ref/fate/speedhq-422-singlefield b/tests/ref/fate/speedhq-422-singlefield new file mode 100644 index 0000000000000..343c52645c8fd --- /dev/null +++ b/tests/ref/fate/speedhq-422-singlefield @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 112x32 +#sar 0: 0/1 +0, 0, 0, 1, 7168, 0x75de4109 From e67d6c37ee34515ca2cd79137e7ca6b87b170e28 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Thu, 3 Aug 2017 09:31:34 +0200 Subject: [PATCH 2709/3374] Add myself as speedhq maintainer, per request. Signed-off-by: James Almer --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index ae0e08d121e4e..ce5e1dae084a6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -233,6 +233,7 @@ Codecs: smvjpegdec.c Ash Hughes snow* Michael Niedermayer, Loren Merritt sonic.c Alex Beregszaszi + speedhq.c Steinar H. Gunderson srt* Aurelien Jacobs sunrast.c Ivo van Poorten svq3.c Michael Niedermayer @@ -598,6 +599,7 @@ Reynaldo H. Verdejo Pinochet 6E27 CD34 170C C78E 4D4F 5F40 C18E 077F 3114 452A Robert Swain EE7A 56EA 4A81 A7B5 2001 A521 67FA 362D A2FC 3E71 Sascha Sommer 38A0 F88B 868E 9D3A 97D4 D6A0 E823 706F 1E07 0D3C Stefano Sabatini 0D0B AD6B 5330 BBAD D3D6 6A0C 719C 2839 FC43 2D5F +Steinar H. Gunderson C2E9 004F F028 C18E 4EAD DB83 7F61 7561 7797 8F76 Stephan Hilb 4F38 0B3A 5F39 B99B F505 E562 8D5C 5554 4E17 8863 Tiancheng "Timothy" Gu 9456 AFC0 814A 8139 E994 8351 7FE6 B095 B582 B0D4 Tim Nicholson 38CF DB09 3ED0 F607 8B67 6CED 0C0B FC44 8B0B FC83 From cae2f1db107dcaab31f29a717ce6f0f9b339088a Mon Sep 17 00:00:00 2001 From: James Almer Date: Thu, 3 Aug 2017 17:51:51 -0300 Subject: [PATCH 2710/3374] avcodec/htmlsubtitles: fix format specifier in av_bprintf calls --- libavcodec/htmlsubtitles.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/htmlsubtitles.c b/libavcodec/htmlsubtitles.c index 1492570a747c1..fb9f90042228d 100644 --- a/libavcodec/htmlsubtitles.c +++ b/libavcodec/htmlsubtitles.c @@ -193,7 +193,7 @@ int ff_htmlmarkup_to_ass(void *log_ctx, AVBPrint *dst, const char *in) if (!(last_tag->color & 0xff000000)) av_bprintf(dst, "{\\c}"); else if (last_tag->color != cur_tag->color) - av_bprintf(dst, "{\\c&H%X&}", last_tag->color & 0xffffff); + av_bprintf(dst, "{\\c&H%"PRIX32"&}", last_tag->color & 0xffffff); } if (cur_tag->face[0]) { @@ -218,7 +218,7 @@ int ff_htmlmarkup_to_ass(void *log_ctx, AVBPrint *dst, const char *in) color = html_color_parse(log_ctx, param); if (color >= 0) { new_tag->color = 0xff000000 | color; - av_bprintf(dst, "{\\c&H%X&}", new_tag->color & 0xffffff); + av_bprintf(dst, "{\\c&H%"PRIX32"&}", new_tag->color & 0xffffff); } } else if (!av_strncasecmp(param, "face=", 5)) { param += 5 + (param[5] == '"'); From 2e8679373ab628a19885645ed5e1271be7797600 Mon Sep 17 00:00:00 2001 From: Yogender Gupta Date: Tue, 18 Jul 2017 16:01:02 +0530 Subject: [PATCH 2711/3374] hwupload_cuda : Add 10/16 bit format support Signed-off-by: Philip Langdale --- libavfilter/version.h | 2 +- libavfilter/vf_hwupload_cuda.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libavfilter/version.h b/libavfilter/version.h index 01dd1dbb7285f..04ea8b71f81fb 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -31,7 +31,7 @@ #define LIBAVFILTER_VERSION_MAJOR 6 #define LIBAVFILTER_VERSION_MINOR 96 -#define LIBAVFILTER_VERSION_MICRO 100 +#define LIBAVFILTER_VERSION_MICRO 101 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ LIBAVFILTER_VERSION_MINOR, \ diff --git a/libavfilter/vf_hwupload_cuda.c b/libavfilter/vf_hwupload_cuda.c index ef98233d12602..063f0285c355e 100644 --- a/libavfilter/vf_hwupload_cuda.c +++ b/libavfilter/vf_hwupload_cuda.c @@ -58,6 +58,7 @@ static int cudaupload_query_formats(AVFilterContext *ctx) static const enum AVPixelFormat input_pix_fmts[] = { AV_PIX_FMT_NV12, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_P010, AV_PIX_FMT_P016, AV_PIX_FMT_YUV444P16, AV_PIX_FMT_NONE, }; static const enum AVPixelFormat output_pix_fmts[] = { From 3407d8118c7236c94dc0eddabc82041e5c130201 Mon Sep 17 00:00:00 2001 From: Yogender Gupta Date: Tue, 18 Jul 2017 16:35:53 +0530 Subject: [PATCH 2712/3374] hwcontext_cuda : Support YUV444P16 format Signed-off-by: Philip Langdale --- libavutil/hwcontext_cuda.c | 8 +++++++- libavutil/version.h | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/libavutil/hwcontext_cuda.c b/libavutil/hwcontext_cuda.c index ed595c3e0faf8..dfb67bc941e27 100644 --- a/libavutil/hwcontext_cuda.c +++ b/libavutil/hwcontext_cuda.c @@ -37,6 +37,7 @@ static const enum AVPixelFormat supported_formats[] = { AV_PIX_FMT_YUV444P, AV_PIX_FMT_P010, AV_PIX_FMT_P016, + AV_PIX_FMT_YUV444P16, }; static int cuda_frames_get_constraints(AVHWDeviceContext *ctx, @@ -142,6 +143,9 @@ static int cuda_frames_init(AVHWFramesContext *ctx) case AV_PIX_FMT_P016: size = aligned_width * ctx->height * 3; break; + case AV_PIX_FMT_YUV444P16: + size = aligned_width * ctx->height * 6; + break; default: av_log(ctx, AV_LOG_ERROR, "BUG: Pixel format missing from size calculation."); return AVERROR_BUG; @@ -161,7 +165,8 @@ static int cuda_get_buffer(AVHWFramesContext *ctx, AVFrame *frame) int width_in_bytes = ctx->width; if (ctx->sw_format == AV_PIX_FMT_P010 || - ctx->sw_format == AV_PIX_FMT_P016) { + ctx->sw_format == AV_PIX_FMT_P016 || + ctx->sw_format == AV_PIX_FMT_YUV444P16) { width_in_bytes *= 2; } aligned_width = FFALIGN(width_in_bytes, CUDA_FRAME_ALIGNMENT); @@ -188,6 +193,7 @@ static int cuda_get_buffer(AVHWFramesContext *ctx, AVFrame *frame) frame->linesize[2] = aligned_width / 2; break; case AV_PIX_FMT_YUV444P: + case AV_PIX_FMT_YUV444P16: frame->data[0] = frame->buf[0]->data; frame->data[1] = frame->data[0] + aligned_width * ctx->height; frame->data[2] = frame->data[1] + aligned_width * ctx->height; diff --git a/libavutil/version.h b/libavutil/version.h index 35987e7b5007c..3dad41f74d11b 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -81,7 +81,7 @@ #define LIBAVUTIL_VERSION_MAJOR 55 #define LIBAVUTIL_VERSION_MINOR 69 -#define LIBAVUTIL_VERSION_MICRO 100 +#define LIBAVUTIL_VERSION_MICRO 101 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ LIBAVUTIL_VERSION_MINOR, \ From f2d23ec03f28c6233059687c65a9124f65f8c312 Mon Sep 17 00:00:00 2001 From: Muhammad Faiz Date: Thu, 3 Aug 2017 07:59:09 +0700 Subject: [PATCH 2713/3374] avfilter/vf_ssim: fix temp size calculation Also use av_mallocz_array. Fix Ticket6519. Reviewed-by: Tobias Rapp Signed-off-by: Muhammad Faiz --- libavfilter/vf_ssim.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libavfilter/vf_ssim.c b/libavfilter/vf_ssim.c index c3c204268f69c..d8c049177cc89 100644 --- a/libavfilter/vf_ssim.c +++ b/libavfilter/vf_ssim.c @@ -219,6 +219,8 @@ static float ssim_endn_8bit(const int (*sum0)[4], const int (*sum1)[4], int widt return ssim; } +#define SUM_LEN(w) (((w) >> 2) + 3) + static float ssim_plane_16bit(SSIMDSPContext *dsp, uint8_t *main, int main_stride, uint8_t *ref, int ref_stride, @@ -228,7 +230,7 @@ static float ssim_plane_16bit(SSIMDSPContext *dsp, int z = 0, y; float ssim = 0.0; int64_t (*sum0)[4] = temp; - int64_t (*sum1)[4] = sum0 + (width >> 2) + 3; + int64_t (*sum1)[4] = sum0 + SUM_LEN(width); width >>= 2; height >>= 2; @@ -256,7 +258,7 @@ static float ssim_plane(SSIMDSPContext *dsp, int z = 0, y; float ssim = 0.0; int (*sum0)[4] = temp; - int (*sum1)[4] = sum0 + (width >> 2) + 3; + int (*sum1)[4] = sum0 + SUM_LEN(width); width >>= 2; height >>= 2; @@ -402,7 +404,7 @@ static int config_input_ref(AVFilterLink *inlink) for (i = 0; i < s->nb_components; i++) s->coefs[i] = (double) s->planeheight[i] * s->planewidth[i] / sum; - s->temp = av_malloc_array((2 * inlink->w + 12), sizeof(*s->temp) * (1 + (desc->comp[0].depth > 8))); + s->temp = av_mallocz_array(2 * SUM_LEN(inlink->w), (desc->comp[0].depth > 8) ? sizeof(int64_t[4]) : sizeof(int[4])); if (!s->temp) return AVERROR(ENOMEM); s->max = (1 << desc->comp[0].depth) - 1; From 80bc648e77972482843017aedf8795e5246ee819 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Fri, 4 Aug 2017 10:29:12 +0200 Subject: [PATCH 2714/3374] avfilter: add tlut2 filter --- Changelog | 1 + doc/filters.texi | 8 +- libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/version.h | 4 +- libavfilter/vf_lut2.c | 185 +++++++++++++++++++++++++++++---------- 6 files changed, 150 insertions(+), 50 deletions(-) diff --git a/Changelog b/Changelog index 30749420213cc..86ce41807da7b 100644 --- a/Changelog +++ b/Changelog @@ -30,6 +30,7 @@ version : - libvmaf video filter - Dolby E decoder and SMPTE 337M demuxer - unpremultiply video filter +- tlut2 video filter version 3.3: - CrystalHD decoder moved to new decode API diff --git a/doc/filters.texi b/doc/filters.texi index 96abffbbdd041..a920bf935ebc7 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -9946,9 +9946,13 @@ lutyuv=u='(val-maxval/2)*2+maxval/2':v='(val-maxval/2)*2+maxval/2' @end example @end itemize -@section lut2 +@section lut2, tlut2 -Compute and apply a lookup table from two video inputs. +The @code{lut2} filter takes two input streams and outputs one +stream. + +The @code{tlut2} (time lut2) filter takes two consecutive frames +from one single stream. This filter accepts the following parameters: @table @option diff --git a/libavfilter/Makefile b/libavfilter/Makefile index f0bb8e77e51e7..f615c669e7ce0 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -312,6 +312,7 @@ OBJS-$(CONFIG_THRESHOLD_FILTER) += vf_threshold.o framesync2.o OBJS-$(CONFIG_THUMBNAIL_FILTER) += vf_thumbnail.o OBJS-$(CONFIG_TILE_FILTER) += vf_tile.o OBJS-$(CONFIG_TINTERLACE_FILTER) += vf_tinterlace.o +OBJS-$(CONFIG_TLUT2_FILTER) += vf_lut2.o framesync2.o OBJS-$(CONFIG_TRANSPOSE_FILTER) += vf_transpose.o OBJS-$(CONFIG_TRIM_FILTER) += trim.o OBJS-$(CONFIG_UNPREMULTIPLY_FILTER) += vf_premultiply.o framesync2.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 0fca662a234f5..32f26804b0d05 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -323,6 +323,7 @@ static void register_all(void) REGISTER_FILTER(THUMBNAIL, thumbnail, vf); REGISTER_FILTER(TILE, tile, vf); REGISTER_FILTER(TINTERLACE, tinterlace, vf); + REGISTER_FILTER(TLUT2, tlut2, vf); REGISTER_FILTER(TRANSPOSE, transpose, vf); REGISTER_FILTER(TRIM, trim, vf); REGISTER_FILTER(UNPREMULTIPLY, unpremultiply, vf); diff --git a/libavfilter/version.h b/libavfilter/version.h index 04ea8b71f81fb..ff0467cc15d0c 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,8 +30,8 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 6 -#define LIBAVFILTER_VERSION_MINOR 96 -#define LIBAVFILTER_VERSION_MICRO 101 +#define LIBAVFILTER_VERSION_MINOR 97 +#define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ LIBAVFILTER_VERSION_MINOR, \ diff --git a/libavfilter/vf_lut2.c b/libavfilter/vf_lut2.c index f7e4a6a65657f..0859285382a79 100644 --- a/libavfilter/vf_lut2.c +++ b/libavfilter/vf_lut2.c @@ -61,6 +61,8 @@ typedef struct LUT2Context { int width[4], height[4]; int nb_planes; int depth, depthx, depthy; + int tlut2; + AVFrame *prev_frame; /* only used with tlut2 */ void (*lut2)(struct LUT2Context *s, AVFrame *dst, AVFrame *srcx, AVFrame *srcy); @@ -70,7 +72,7 @@ typedef struct LUT2Context { #define OFFSET(x) offsetof(LUT2Context, x) #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM -static const AVOption lut2_options[] = { +static const AVOption options[] = { { "c0", "set component #0 expression", OFFSET(comp_expr_str[0]), AV_OPT_TYPE_STRING, { .str = "x" }, .flags = FLAGS }, { "c1", "set component #1 expression", OFFSET(comp_expr_str[1]), AV_OPT_TYPE_STRING, { .str = "x" }, .flags = FLAGS }, { "c2", "set component #2 expression", OFFSET(comp_expr_str[2]), AV_OPT_TYPE_STRING, { .str = "x" }, .flags = FLAGS }, @@ -83,6 +85,8 @@ static av_cold void uninit(AVFilterContext *ctx) LUT2Context *s = ctx->priv; int i; + av_frame_free(&s->prev_frame); + for (i = 0; i < 4; i++) { av_expr_free(s->comp_expr[i]); s->comp_expr[i] = NULL; @@ -133,6 +137,11 @@ static int config_inputx(AVFilterLink *inlink) s->depthx = desc->comp[0].depth; s->var_values[VAR_BITDEPTHX] = s->depthx; + if (s->tlut2) { + s->depthy = desc->comp[0].depth; + s->var_values[VAR_BITDEPTHY] = s->depthy; + } + return 0; } @@ -232,13 +241,64 @@ static int config_output(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; LUT2Context *s = ctx->priv; - AVFilterLink *srcx = ctx->inputs[0]; - AVFilterLink *srcy = ctx->inputs[1]; - FFFrameSyncIn *in; int p, ret; s->depth = s->depthx + s->depthy; + s->lut2 = s->depth > 16 ? lut2_16bit : lut2_8bit; + + for (p = 0; p < s->nb_planes; p++) { + s->lut[p] = av_malloc_array(1 << s->depth, sizeof(uint16_t)); + if (!s->lut[p]) + return AVERROR(ENOMEM); + } + + for (p = 0; p < s->nb_planes; p++) { + double res; + int x, y; + + /* create the parsed expression */ + av_expr_free(s->comp_expr[p]); + s->comp_expr[p] = NULL; + ret = av_expr_parse(&s->comp_expr[p], s->comp_expr_str[p], + var_names, NULL, NULL, NULL, NULL, 0, ctx); + if (ret < 0) { + av_log(ctx, AV_LOG_ERROR, + "Error when parsing the expression '%s' for the component %d.\n", + s->comp_expr_str[p], p); + return AVERROR(EINVAL); + } + + /* compute the lut */ + for (y = 0; y < (1 << s->depthx); y++) { + s->var_values[VAR_Y] = y; + for (x = 0; x < (1 << s->depthx); x++) { + s->var_values[VAR_X] = x; + res = av_expr_eval(s->comp_expr[p], s->var_values, s); + if (isnan(res)) { + av_log(ctx, AV_LOG_ERROR, + "Error when evaluating the expression '%s' for the values %d and %d for the component %d.\n", + s->comp_expr_str[p], x, y, p); + return AVERROR(EINVAL); + } + + s->lut[p][(y << s->depthx) + x] = res; + } + } + } + + return 0; +} + +static int lut2_config_output(AVFilterLink *outlink) +{ + AVFilterContext *ctx = outlink->src; + LUT2Context *s = ctx->priv; + AVFilterLink *srcx = ctx->inputs[0]; + AVFilterLink *srcy = ctx->inputs[1]; + FFFrameSyncIn *in; + int ret; + if (srcx->format != srcy->format) { av_log(ctx, AV_LOG_ERROR, "inputs must be of same pixel format\n"); return AVERROR(EINVAL); @@ -281,47 +341,8 @@ static int config_output(AVFilterLink *outlink) s->fs.opaque = s; s->fs.on_event = process_frame; - s->lut2 = s->depth > 16 ? lut2_16bit : lut2_8bit; - - for (p = 0; p < s->nb_planes; p++) { - s->lut[p] = av_malloc_array(1 << s->depth, sizeof(uint16_t)); - if (!s->lut[p]) - return AVERROR(ENOMEM); - } - - for (p = 0; p < s->nb_planes; p++) { - double res; - int x, y; - - /* create the parsed expression */ - av_expr_free(s->comp_expr[p]); - s->comp_expr[p] = NULL; - ret = av_expr_parse(&s->comp_expr[p], s->comp_expr_str[p], - var_names, NULL, NULL, NULL, NULL, 0, ctx); - if (ret < 0) { - av_log(ctx, AV_LOG_ERROR, - "Error when parsing the expression '%s' for the component %d.\n", - s->comp_expr_str[p], p); - return AVERROR(EINVAL); - } - - /* compute the lut */ - for (y = 0; y < (1 << s->depthx); y++) { - s->var_values[VAR_Y] = y; - for (x = 0; x < (1 << s->depthx); x++) { - s->var_values[VAR_X] = x; - res = av_expr_eval(s->comp_expr[p], s->var_values, s); - if (isnan(res)) { - av_log(ctx, AV_LOG_ERROR, - "Error when evaluating the expression '%s' for the values %d and %d for the component %d.\n", - s->comp_expr_str[p], x, y, p); - return AVERROR(EINVAL); - } - - s->lut[p][(y << s->depthx) + x] = res; - } - } - } + if ((ret = config_output(outlink)) < 0) + return ret; return ff_framesync2_configure(&s->fs); } @@ -350,11 +371,13 @@ static const AVFilterPad outputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_output, + .config_props = lut2_config_output, }, { NULL } }; +#define lut2_options options + AVFILTER_DEFINE_CLASS(lut2); AVFilter ff_vf_lut2 = { @@ -369,3 +392,73 @@ AVFilter ff_vf_lut2 = { .outputs = outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, }; + +#if CONFIG_TLUT2_FILTER + +static av_cold int init(AVFilterContext *ctx) +{ + LUT2Context *s = ctx->priv; + + s->tlut2 = !strcmp(ctx->filter->name, "tlut2"); + + return 0; +} + +static int tlut2_filter_frame(AVFilterLink *inlink, AVFrame *frame) +{ + LUT2Context *s = inlink->dst->priv; + AVFilterLink *outlink = inlink->dst->outputs[0]; + + if (s->prev_frame) { + AVFrame *out = ff_get_video_buffer(outlink, outlink->w, outlink->h); + if (!out) { + av_frame_free(&s->prev_frame); + s->prev_frame = frame; + return AVERROR(ENOMEM); + } + av_frame_copy_props(out, frame); + s->lut2(s, out, frame, s->prev_frame); + av_frame_free(&s->prev_frame); + s->prev_frame = frame; + return ff_filter_frame(outlink, out); + } + s->prev_frame = frame; + return 0; +} + +#define tlut2_options options + +AVFILTER_DEFINE_CLASS(tlut2); + +static const AVFilterPad tlut2_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .filter_frame = tlut2_filter_frame, + .config_props = config_inputx, + }, + { NULL } +}; + +static const AVFilterPad tlut2_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = config_output, + }, + { NULL } +}; + +AVFilter ff_vf_tlut2 = { + .name = "tlut2", + .description = NULL_IF_CONFIG_SMALL("Compute and apply a lookup table from two successive frames."), + .priv_size = sizeof(LUT2Context), + .priv_class = &tlut2_class, + .query_formats = query_formats, + .init = init, + .uninit = uninit, + .inputs = tlut2_inputs, + .outputs = tlut2_outputs, +}; + +#endif From 738b29cfb69b82965fd71d00da85f162b04a171e Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Fri, 4 Aug 2017 21:38:55 +0800 Subject: [PATCH 2715/3374] avformat/hlsenc: support fmp4 single file mode add byterange mode of the hls fmp4 Reviewed-by: Derek Buitenhuis Signed-off-by: Steven Liu --- libavformat/hlsenc.c | 77 ++++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 27 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index f98f04100c711..5cf8c89ee7041 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -531,6 +531,7 @@ static int hls_mux_init(AVFormatContext *s) HLSContext *hls = s->priv_data; AVFormatContext *oc; AVFormatContext *vtt_oc = NULL; + int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0); int i, ret; ret = avformat_alloc_output_context2(&hls->avf, hls->oformat, NULL, NULL); @@ -584,7 +585,11 @@ static int hls_mux_init(AVFormatContext *s) hls->fmp4_init_mode = 0; if (hls->segment_type == SEGMENT_TYPE_FMP4) { - hls->fmp4_init_mode = 1; + if (hls->max_seg_size > 0) { + av_log(s, AV_LOG_WARNING, "Multi-file byterange mode is currently unsupported in the HLS muxer.\n"); + return AVERROR_PATCHWELCOME; + } + hls->fmp4_init_mode = !byterange_mode; if ((ret = s->io_open(s, &oc->pb, hls->base_output_dirname, AVIO_FLAG_WRITE, NULL)) < 0) { av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", hls->fmp4_init_filename); return ret; @@ -980,9 +985,6 @@ static void write_m3u8_head_block(HLSContext *hls, AVIOContext *out, int version } avio_printf(out, "#EXT-X-TARGETDURATION:%d\n", target_duration); avio_printf(out, "#EXT-X-MEDIA-SEQUENCE:%"PRId64"\n", sequence); - if (hls->segment_type == SEGMENT_TYPE_FMP4) { - avio_printf(out, "#EXT-X-MAP:URI=\"%s\"\n", hls->fmp4_init_filename); - } av_log(hls, AV_LOG_VERBOSE, "EXT-X-MEDIA-SEQUENCE:%"PRId64"\n", sequence); } @@ -1066,13 +1068,21 @@ static int hls_window(AVFormatContext *s, int last) avio_printf(out, "#EXT-X-DISCONTINUITY\n"); } - if (hls->flags & HLS_ROUND_DURATIONS) - avio_printf(out, "#EXTINF:%ld,\n", lrint(en->duration)); - else - avio_printf(out, "#EXTINF:%f,\n", en->duration); - if (byterange_mode) - avio_printf(out, "#EXT-X-BYTERANGE:%"PRIi64"@%"PRIi64"\n", - en->size, en->pos); + if ((hls->segment_type == SEGMENT_TYPE_FMP4) && (en == hls->segments)) { + avio_printf(out, "#EXT-X-MAP:URI=\"%s\"", hls->fmp4_init_filename); + if (hls->flags & HLS_SINGLE_FILE) { + avio_printf(out, ",BYTERANGE=\"%"PRId64"@%"PRId64"\"", en->size, en->pos); + } + avio_printf(out, "\n"); + } else { + if (hls->flags & HLS_ROUND_DURATIONS) + avio_printf(out, "#EXTINF:%ld,\n", lrint(en->duration)); + else + avio_printf(out, "#EXTINF:%f,\n", en->duration); + if (byterange_mode) + avio_printf(out, "#EXT-X-BYTERANGE:%"PRId64"@%"PRId64"\n", + en->size, en->pos); + } if (hls->flags & HLS_PROGRAM_DATE_TIME) { time_t tt, wrongsecs; int milli; @@ -1097,9 +1107,11 @@ static int hls_window(AVFormatContext *s, int last) avio_printf(out, "#EXT-X-PROGRAM-DATE-TIME:%s.%03d%s\n", buf0, milli, buf1); prog_date_time += en->duration; } - if (hls->baseurl) - avio_printf(out, "%s", hls->baseurl); - avio_printf(out, "%s\n", en->filename); + if (!((hls->segment_type == SEGMENT_TYPE_FMP4) && (en == hls->segments))) { + if (hls->baseurl) + avio_printf(out, "%s", hls->baseurl); + avio_printf(out, "%s\n", en->filename); + } } if (last && (hls->flags & HLS_OMIT_ENDLIST)==0) @@ -1262,7 +1274,7 @@ static int hls_start(AVFormatContext *s) } av_dict_free(&options); - if (c->segment_type == SEGMENT_TYPE_FMP4) { + if (c->segment_type == SEGMENT_TYPE_FMP4 && !(c->flags & HLS_SINGLE_FILE)) { write_styp(oc->pb); } else { /* We only require one PAT/PMT per segment. */ @@ -1315,15 +1327,10 @@ static int hls_write_header(AVFormatContext *s) const char *pattern_localtime_fmt = get_default_pattern_localtime_fmt(s); const char *vtt_pattern = "%d.vtt"; AVDictionary *options = NULL; - int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0); int basename_size; int vtt_basename_size; if (hls->segment_type == SEGMENT_TYPE_FMP4) { - if (byterange_mode) { - av_log(s, AV_LOG_WARNING, "Have not support fmp4 byterange mode yet now\n"); - return AVERROR_PATCHWELCOME; - } pattern = "%d.m4s"; } if ((hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH) || @@ -1400,8 +1407,13 @@ static int hls_write_header(AVFormatContext *s) goto fail; } } else { - if (hls->flags & HLS_SINGLE_FILE) - pattern = ".ts"; + if (hls->flags & HLS_SINGLE_FILE) { + if (hls->segment_type == SEGMENT_TYPE_FMP4) { + pattern = ".m4s"; + } else { + pattern = ".ts"; + } + } if (hls->use_localtime) { basename_size = strlen(s->filename) + strlen(pattern_localtime_fmt) + 1; @@ -1490,6 +1502,14 @@ static int hls_write_header(AVFormatContext *s) av_strlcat(hls->vtt_basename, vtt_pattern, vtt_basename_size); } + if ((hls->flags & HLS_SINGLE_FILE) && (hls->segment_type == SEGMENT_TYPE_FMP4)) { + hls->fmp4_init_filename = av_strdup(hls->basename); + if (!hls->fmp4_init_filename) { + ret = AVERROR(ENOMEM); + goto fail; + } + } + if ((ret = hls_mux_init(s)) < 0) goto fail; @@ -1504,7 +1524,7 @@ static int hls_write_header(AVFormatContext *s) } } - if (hls->segment_type != SEGMENT_TYPE_FMP4) { + if (hls->segment_type != SEGMENT_TYPE_FMP4 || hls->flags & HLS_SINGLE_FILE) { if ((ret = hls_start(s)) < 0) goto fail; } @@ -1545,6 +1565,7 @@ static int hls_write_header(AVFormatContext *s) av_dict_free(&options); if (ret < 0) { + av_freep(&hls->fmp4_init_filename); av_freep(&hls->basename); av_freep(&hls->vtt_basename); av_freep(&hls->key_basename); @@ -1643,7 +1664,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) hls->number--; } - if (!hls->fmp4_init_mode) + if (!hls->fmp4_init_mode || byterange_mode) ret = hls_append_segment(s, hls, hls->duration, hls->start_pos, hls->size); hls->start_pos = new_start_pos; @@ -1679,9 +1700,10 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) return ret; } - if ((ret = hls_window(s, 0)) < 0) { - return ret; - } + if (!hls->fmp4_init_mode || byterange_mode) + if ((ret = hls_window(s, 0)) < 0) { + return ret; + } } ret = ff_write_chained(oc, stream_index, pkt, s, 0); @@ -1722,6 +1744,7 @@ static int hls_write_trailer(struct AVFormatContext *s) hls->size = avio_tell(hls->vtt_avf->pb) - hls->start_pos; ff_format_io_close(s, &vtt_oc->pb); } + av_freep(&hls->fmp4_init_filename); av_freep(&hls->basename); av_freep(&hls->base_output_dirname); av_freep(&hls->key_basename); From 44e9783ab9a1a26d718a9360adfb528d5015df6e Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Fri, 4 Aug 2017 22:18:22 +0800 Subject: [PATCH 2716/3374] doc/libav-merge: remove the hls merge TODO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This TODO is done. See 5caaa3a49e76b084ff8a9840d541bad64d96d7f7 Reviewed-by: Clément Bœsch Signed-off-by: Steven Liu --- doc/libav-merge.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/libav-merge.txt b/doc/libav-merge.txt index 690c4ef97f222..96b008b71b208 100644 --- a/doc/libav-merge.txt +++ b/doc/libav-merge.txt @@ -105,7 +105,6 @@ Collateral damage that needs work locally: - Merge proresdec2.c and proresdec_lgpl.c - Merge proresenc_anatoliy.c and proresenc_kostya.c - Fix MIPS AC3 downmix -- hlsenc encryption support may need some adjustment (see edc43c571d) Extra changes needed to be aligned with Libav: ---------------------------------------------- From c47491041466043a260412504f4294a2b458ebdb Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sat, 5 Aug 2017 10:36:48 +0200 Subject: [PATCH 2717/3374] doc/filters.texi: add yet another laplacian edge detector --- doc/filters.texi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/filters.texi b/doc/filters.texi index a920bf935ebc7..7e5a9a625aec2 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -5880,6 +5880,12 @@ Apply edge detect: convolution="0 1 0 1 -4 1 0 1 0:0 1 0 1 -4 1 0 1 0:0 1 0 1 -4 1 0 1 0:0 1 0 1 -4 1 0 1 0:5:5:5:1:0:128:128:128" @end example +@item +Apply laplacian edge detector which includes diagonals: +@example +convolution="1 1 1 1 -8 1 1 1 1:1 1 1 1 -8 1 1 1 1:1 1 1 1 -8 1 1 1 1:1 1 1 1 -8 1 1 1 1:5:5:5:1:0:128:128:0" +@end example + @item Apply emboss: @example From 2cc56741b1f4e33c4fdb8234da31bdfc3c5c5e05 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sat, 5 Aug 2017 20:27:32 +0200 Subject: [PATCH 2718/3374] avfilter: add floodfill filter --- Changelog | 1 + doc/filters.texi | 37 ++++ libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/version.h | 2 +- libavfilter/vf_floodfill.c | 433 +++++++++++++++++++++++++++++++++++++ 6 files changed, 474 insertions(+), 1 deletion(-) create mode 100644 libavfilter/vf_floodfill.c diff --git a/Changelog b/Changelog index 86ce41807da7b..c797d68a364f7 100644 --- a/Changelog +++ b/Changelog @@ -31,6 +31,7 @@ version : - Dolby E decoder and SMPTE 337M demuxer - unpremultiply video filter - tlut2 video filter +- floodfill video filter version 3.3: - CrystalHD decoder moved to new decode API diff --git a/doc/filters.texi b/doc/filters.texi index 7e5a9a625aec2..c1d572f71aa07 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -8404,6 +8404,43 @@ ffmpeg -i file.ts -vf find_rect=newref.pgm,cover_rect=cover.jpg:mode=cover new.m @end example @end itemize +@section floodfill + +Flood area with values of same pixel components with another values. + +It accepts the following options: +@table @option +@item x +Set pixel x coordinate. + +@item y +Set pixel y coordinate. + +@item s0 +Set source #0 component value. + +@item s1 +Set source #1 component value. + +@item s2 +Set source #2 component value. + +@item s3 +Set source #3 component value. + +@item d0 +Set destination #0 component value. + +@item d1 +Set destination #1 component value. + +@item d2 +Set destination #2 component value. + +@item d3 +Set destination #3 component value. +@end table + @anchor{format} @section format diff --git a/libavfilter/Makefile b/libavfilter/Makefile index f615c669e7ce0..06b915fc91f01 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -186,6 +186,7 @@ OBJS-$(CONFIG_FIELDHINT_FILTER) += vf_fieldhint.o OBJS-$(CONFIG_FIELDMATCH_FILTER) += vf_fieldmatch.o OBJS-$(CONFIG_FIELDORDER_FILTER) += vf_fieldorder.o OBJS-$(CONFIG_FIND_RECT_FILTER) += vf_find_rect.o lavfutils.o +OBJS-$(CONFIG_FLOODFILL_FILTER) += vf_floodfill.o OBJS-$(CONFIG_FORMAT_FILTER) += vf_format.o OBJS-$(CONFIG_FPS_FILTER) += vf_fps.o OBJS-$(CONFIG_FRAMEPACK_FILTER) += vf_framepack.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 32f26804b0d05..e58c0d5c82754 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -198,6 +198,7 @@ static void register_all(void) REGISTER_FILTER(FIELDMATCH, fieldmatch, vf); REGISTER_FILTER(FIELDORDER, fieldorder, vf); REGISTER_FILTER(FIND_RECT, find_rect, vf); + REGISTER_FILTER(FLOODFILL, floodfill, vf); REGISTER_FILTER(FORMAT, format, vf); REGISTER_FILTER(FPS, fps, vf); REGISTER_FILTER(FRAMEPACK, framepack, vf); diff --git a/libavfilter/version.h b/libavfilter/version.h index ff0467cc15d0c..1d37fd8e4b155 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 6 -#define LIBAVFILTER_VERSION_MINOR 97 +#define LIBAVFILTER_VERSION_MINOR 98 #define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vf_floodfill.c b/libavfilter/vf_floodfill.c new file mode 100644 index 0000000000000..323dd0e2fa1c4 --- /dev/null +++ b/libavfilter/vf_floodfill.c @@ -0,0 +1,433 @@ +/* + * Copyright (c) 2017 Paul B Mahol + * + * 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 "libavutil/opt.h" +#include "libavutil/imgutils.h" +#include "libavutil/intreadwrite.h" +#include "avfilter.h" +#include "formats.h" +#include "internal.h" +#include "video.h" + +typedef struct Points { + uint16_t x, y; +} Points; + +typedef struct FloodfillContext { + const AVClass *class; + + int x, y; + int s0, s1, s2, s3; + int d0, d1, d2, d3; + + int back, front; + Points *points; + + int (*is_same)(AVFrame *frame, int x, int y, + unsigned s0, unsigned s1, unsigned s2, unsigned s3); + void (*set_pixel)(AVFrame *frame, int x, int y, + unsigned d0, unsigned d1, unsigned d2, unsigned d3); + void (*pick_pixel)(AVFrame *frame, int x, int y, + int *s0, int *s1, int *s2, int *s3); +} FloodfillContext; + +static int is_inside(int x, int y, int w, int h) +{ + if (x >= 0 && x < w && y >= 0 && y < h) + return 1; + return 0; +} + +static int is_same4(AVFrame *frame, int x, int y, + unsigned s0, unsigned s1, unsigned s2, unsigned s3) +{ + unsigned c0 = frame->data[0][y * frame->linesize[0] + x]; + unsigned c1 = frame->data[1][y * frame->linesize[1] + x]; + unsigned c2 = frame->data[2][y * frame->linesize[2] + x]; + unsigned c3 = frame->data[3][y * frame->linesize[3] + x]; + + if (s0 == c0 && s1 == c1 && s2 == c2 && s3 == c3) + return 1; + return 0; +} + +static int is_same4_16(AVFrame *frame, int x, int y, + unsigned s0, unsigned s1, unsigned s2, unsigned s3) +{ + unsigned c0 = AV_RN16(frame->data[0] + y * frame->linesize[0] + 2 * x); + unsigned c1 = AV_RN16(frame->data[1] + y * frame->linesize[1] + 2 * x); + unsigned c2 = AV_RN16(frame->data[2] + y * frame->linesize[2] + 2 * x); + unsigned c3 = AV_RN16(frame->data[3] + y * frame->linesize[3] + 2 * x); + + if (s0 == c0 && s1 == c1 && s2 == c2 && s3 == c3) + return 1; + return 0; +} + +static int is_same3(AVFrame *frame, int x, int y, + unsigned s0, unsigned s1, unsigned s2, unsigned s3) +{ + unsigned c0 = frame->data[0][y * frame->linesize[0] + x]; + unsigned c1 = frame->data[1][y * frame->linesize[1] + x]; + unsigned c2 = frame->data[2][y * frame->linesize[2] + x]; + + if (s0 == c0 && s1 == c1 && s2 == c2) + return 1; + return 0; +} + +static int is_same3_16(AVFrame *frame, int x, int y, + unsigned s0, unsigned s1, unsigned s2, unsigned s3) +{ + unsigned c0 = AV_RN16(frame->data[0] + y * frame->linesize[0] + 2 * x); + unsigned c1 = AV_RN16(frame->data[1] + y * frame->linesize[1] + 2 * x); + unsigned c2 = AV_RN16(frame->data[2] + y * frame->linesize[2] + 2 * x); + + if (s0 == c0 && s1 == c1 && s2 == c2) + return 1; + return 0; +} + +static int is_same1(AVFrame *frame, int x, int y, + unsigned s0, unsigned s1, unsigned s2, unsigned s3) +{ + unsigned c0 = frame->data[0][y * frame->linesize[0] + x]; + + if (s0 == c0) + return 1; + return 0; +} + +static int is_same1_16(AVFrame *frame, int x, int y, + unsigned s0, unsigned s1, unsigned s2, unsigned s3) +{ + unsigned c0 = AV_RN16(frame->data[0] + y * frame->linesize[0] + 2 * x); + + if (s0 == c0) + return 1; + return 0; +} + +static void set_pixel1(AVFrame *frame, int x, int y, + unsigned d0, unsigned d1, unsigned d2, unsigned d3) +{ + frame->data[0][y * frame->linesize[0] + x] = d0; +} + +static void set_pixel1_16(AVFrame *frame, int x, int y, + unsigned d0, unsigned d1, unsigned d2, unsigned d3) +{ + AV_WN16(frame->data[0] + y * frame->linesize[0] + 2 * x, d0); +} + +static void set_pixel3(AVFrame *frame, int x, int y, + unsigned d0, unsigned d1, unsigned d2, unsigned d3) +{ + frame->data[0][y * frame->linesize[0] + x] = d0; + frame->data[1][y * frame->linesize[1] + x] = d1; + frame->data[2][y * frame->linesize[2] + x] = d2; +} + +static void set_pixel3_16(AVFrame *frame, int x, int y, + unsigned d0, unsigned d1, unsigned d2, unsigned d3) +{ + AV_WN16(frame->data[0] + y * frame->linesize[0] + 2 * x, d0); + AV_WN16(frame->data[1] + y * frame->linesize[1] + 2 * x, d1); + AV_WN16(frame->data[2] + y * frame->linesize[2] + 2 * x, d2); +} + +static void set_pixel4(AVFrame *frame, int x, int y, + unsigned d0, unsigned d1, unsigned d2, unsigned d3) +{ + frame->data[0][y * frame->linesize[0] + x] = d0; + frame->data[1][y * frame->linesize[1] + x] = d1; + frame->data[2][y * frame->linesize[2] + x] = d2; + frame->data[3][y * frame->linesize[3] + x] = d3; +} + +static void set_pixel4_16(AVFrame *frame, int x, int y, + unsigned d0, unsigned d1, unsigned d2, unsigned d3) +{ + AV_WN16(frame->data[0] + y * frame->linesize[0] + 2 * x, d0); + AV_WN16(frame->data[1] + y * frame->linesize[1] + 2 * x, d1); + AV_WN16(frame->data[2] + y * frame->linesize[2] + 2 * x, d2); + AV_WN16(frame->data[3] + y * frame->linesize[3] + 2 * x, d3); +} + +static void pick_pixel1(AVFrame *frame, int x, int y, + int *s0, int *s1, int *s2, int *s3) +{ + if (*s0 < 0) + *s0 = frame->data[0][y * frame->linesize[0] + x]; +} + +static void pick_pixel1_16(AVFrame *frame, int x, int y, + int *s0, int *s1, int *s2, int *s3) +{ + if (*s0 < 0) + *s0 = AV_RN16(frame->data[0] + y * frame->linesize[0] + 2 * x); +} + +static void pick_pixel3(AVFrame *frame, int x, int y, + int *s0, int *s1, int *s2, int *s3) +{ + if (*s0 < 0) + *s0 = frame->data[0][y * frame->linesize[0] + x]; + if (*s1 < 0) + *s1 = frame->data[1][y * frame->linesize[1] + x]; + if (*s2 < 0) + *s2 = frame->data[2][y * frame->linesize[2] + x]; +} + +static void pick_pixel3_16(AVFrame *frame, int x, int y, + int *s0, int *s1, int *s2, int *s3) +{ + if (*s0 < 0) + *s0 = AV_RN16(frame->data[0] + y * frame->linesize[0] + 2 * x); + if (*s1 < 0) + *s1 = AV_RN16(frame->data[1] + y * frame->linesize[1] + 2 * x); + if (*s2 < 0) + *s2 = AV_RN16(frame->data[2] + y * frame->linesize[2] + 2 * x); +} + +static void pick_pixel4(AVFrame *frame, int x, int y, + int *s0, int *s1, int *s2, int *s3) +{ + if (*s0 < 0) + *s0 = frame->data[0][y * frame->linesize[0] + x]; + if (*s1 < 0) + *s1 = frame->data[1][y * frame->linesize[1] + x]; + if (*s2 < 0) + *s2 = frame->data[2][y * frame->linesize[2] + x]; + if (*s3 < 0) + *s3 = frame->data[3][y * frame->linesize[3] + x]; +} + +static void pick_pixel4_16(AVFrame *frame, int x, int y, + int *s0, int *s1, int *s2, int *s3) +{ + if (*s0 < 0) + *s0 = AV_RN16(frame->data[0] + y * frame->linesize[0] + 2 * x); + if (*s1 < 0) + *s1 = AV_RN16(frame->data[1] + y * frame->linesize[1] + 2 * x); + if (*s2 < 0) + *s2 = AV_RN16(frame->data[2] + y * frame->linesize[2] + 2 * x); + if (*s3 < 0) + *s3 = AV_RN16(frame->data[3] + y * frame->linesize[3] + 2 * x); +} + +static int config_input(AVFilterLink *inlink) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + AVFilterContext *ctx = inlink->dst; + FloodfillContext *s = ctx->priv; + int nb_planes = av_pix_fmt_count_planes(inlink->format); + int depth; + + depth = desc->comp[0].depth; + if (depth == 8) { + switch (nb_planes) { + case 1: s->set_pixel = set_pixel1; + s->is_same = is_same1; + s->pick_pixel = pick_pixel1; break; + case 3: s->set_pixel = set_pixel3; + s->is_same = is_same3; + s->pick_pixel = pick_pixel3; break; + case 4: s->set_pixel = set_pixel4; + s->is_same = is_same4; + s->pick_pixel = pick_pixel4; break; + } + } else { + switch (nb_planes) { + case 1: s->set_pixel = set_pixel1_16; + s->is_same = is_same1_16; + s->pick_pixel = pick_pixel1_16; break; + case 3: s->set_pixel = set_pixel3_16; + s->is_same = is_same3_16; + s->pick_pixel = pick_pixel3_16; break; + case 4: s->set_pixel = set_pixel4_16; + s->is_same = is_same4_16; + s->pick_pixel = pick_pixel4_16; break; + } + } + + s->front = s->back = 0; + s->points = av_calloc(inlink->w * inlink->h, 4 * sizeof(Points)); + if (!s->points) + return AVERROR(ENOMEM); + + return 0; +} + +static int filter_frame(AVFilterLink *link, AVFrame *frame) +{ + AVFilterContext *ctx = link->dst; + FloodfillContext *s = ctx->priv; + const unsigned d0 = s->d0; + const unsigned d1 = s->d1; + const unsigned d2 = s->d2; + const unsigned d3 = s->d3; + int s0 = s->s0; + int s1 = s->s1; + int s2 = s->s2; + int s3 = s->s3; + const int w = frame->width; + const int h = frame->height; + int ret; + + if (ret = av_frame_make_writable(frame)) + return ret; + + if (is_inside(s->x, s->y, w, h)) { + s->pick_pixel(frame, s->x, s->y, &s0, &s1, &s2, &s3); + + if (s->is_same(frame, s->x, s->y, s0, s1, s2, s3)) { + s->points[s->front].x = s->x; + s->points[s->front].y = s->y; + s->front++; + } + + while (s->front > s->back) { + int x, y; + + s->front--; + x = s->points[s->front].x; + y = s->points[s->front].y; + + if (s->is_same(frame, x, y, s0, s1, s2, s3)) { + s->set_pixel(frame, x, y, d0, d1, d2, d3); + + if (is_inside(x + 1, y, w, h)) { + s->points[s->front] .x = x + 1; + s->points[s->front++].y = y; + } + + if (is_inside(x - 1, y, w, h)) { + s->points[s->front] .x = x - 1; + s->points[s->front++].y = y; + } + + if (is_inside(x, y + 1, w, h)) { + s->points[s->front] .x = x; + s->points[s->front++].y = y + 1; + } + + if (is_inside(x, y - 1, w, h)) { + s->points[s->front] .x = x; + s->points[s->front++].y = y - 1; + } + } + } + } + + return ff_filter_frame(ctx->outputs[0], frame); +} + +static av_cold int query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pixel_fmts[] = { + AV_PIX_FMT_GRAY8, + AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUVA444P, + AV_PIX_FMT_GBRP, + AV_PIX_FMT_GBRP9, + AV_PIX_FMT_GBRP10, + AV_PIX_FMT_GBRAP10, + AV_PIX_FMT_GBRP12, + AV_PIX_FMT_GBRAP12, + AV_PIX_FMT_GBRP14, + AV_PIX_FMT_GBRP16, + AV_PIX_FMT_GBRAP16, + AV_PIX_FMT_GBRAP, + AV_PIX_FMT_YUV444P9, + AV_PIX_FMT_YUVA444P9, + AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUVA444P10, + AV_PIX_FMT_YUV444P12, + AV_PIX_FMT_YUV444P14, + AV_PIX_FMT_GRAY16, + AV_PIX_FMT_YUV444P16, + AV_PIX_FMT_YUVA444P16, + AV_PIX_FMT_NONE + }; + AVFilterFormats *formats; + + formats = ff_make_format_list(pixel_fmts); + if (!formats) + return AVERROR(ENOMEM); + + return ff_set_common_formats(ctx, formats); +} + +static av_cold void uninit(AVFilterContext *ctx) +{ + FloodfillContext *s = ctx->priv; + + av_freep(&s->points); +} + +static const AVFilterPad floodfill_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .filter_frame = filter_frame, + .config_props = config_input, + }, + { NULL } +}; + +static const AVFilterPad floodfill_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + }, + { NULL } +}; + +#define OFFSET(x) offsetof(FloodfillContext, x) +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM + +static const AVOption floodfill_options[] = { + { "x", "set pixel x coordinate", OFFSET(x), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS }, + { "y", "set pixel y coordinate", OFFSET(y), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS }, + { "s0", "set source #0 component value", OFFSET(s0), AV_OPT_TYPE_INT, {.i64=0},-1, UINT16_MAX, FLAGS }, + { "s1", "set source #1 component value", OFFSET(s1), AV_OPT_TYPE_INT, {.i64=0},-1, UINT16_MAX, FLAGS }, + { "s2", "set source #2 component value", OFFSET(s2), AV_OPT_TYPE_INT, {.i64=0},-1, UINT16_MAX, FLAGS }, + { "s3", "set source #3 component value", OFFSET(s3), AV_OPT_TYPE_INT, {.i64=0},-1, UINT16_MAX, FLAGS }, + { "d0", "set destination #0 component value", OFFSET(d0), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS }, + { "d1", "set destination #1 component value", OFFSET(d1), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS }, + { "d2", "set destination #2 component value", OFFSET(d2), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS }, + { "d3", "set destination #3 component value", OFFSET(d3), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(floodfill); + +AVFilter ff_vf_floodfill = { + .name = "floodfill", + .description = NULL_IF_CONFIG_SMALL("Fill area with same color with another color."), + .priv_size = sizeof(FloodfillContext), + .priv_class = &floodfill_class, + .query_formats = query_formats, + .uninit = uninit, + .inputs = floodfill_inputs, + .outputs = floodfill_outputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, +}; From 013ec23cbe5d78a04b1b6c00c43f45773e45e7e5 Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Thu, 3 Aug 2017 16:21:54 +0100 Subject: [PATCH 2719/3374] swscale: fix gbrap16 alpha channel issues Fixes filter-pixfmts-scale test failing on big-endian systems due to alpSrc not being cast to (const int32_t**). Also fixes distortions in the output alpha channel values by copying the alpha channel code from the rgba64 case found elsewhere in output.c. Fixes ticket 6555. Signed-off-by: James Cowgill Signed-off-by: Michael Niedermayer --- libswscale/output.c | 16 ++++++++-------- tests/ref/fate/filter-pixfmts-scale | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/libswscale/output.c b/libswscale/output.c index 9774e9f327ea0..f30bce8dd3c1e 100644 --- a/libswscale/output.c +++ b/libswscale/output.c @@ -2026,24 +2026,24 @@ yuv2gbrp16_full_X_c(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrcx, int lumFilterSize, const int16_t *chrFilter, const int16_t **chrUSrcx, const int16_t **chrVSrcx, int chrFilterSize, - const int16_t **alpSrc, uint8_t **dest, + const int16_t **alpSrcx, uint8_t **dest, int dstW, int y) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->dstFormat); int i; - int hasAlpha = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) && alpSrc; + int hasAlpha = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) && alpSrcx; uint16_t **dest16 = (uint16_t**)dest; const int32_t **lumSrc = (const int32_t**)lumSrcx; const int32_t **chrUSrc = (const int32_t**)chrUSrcx; const int32_t **chrVSrc = (const int32_t**)chrVSrcx; - int A = 0; // init to silence warning + const int32_t **alpSrc = (const int32_t**)alpSrcx; for (i = 0; i < dstW; i++) { int j; int Y = -0x40000000; int U = -(128 << 23); int V = -(128 << 23); - int R, G, B; + int R, G, B, A; for (j = 0; j < lumFilterSize; j++) Y += lumSrc[j][i] * (unsigned)lumFilter[j]; @@ -2059,13 +2059,13 @@ yuv2gbrp16_full_X_c(SwsContext *c, const int16_t *lumFilter, V >>= 14; if (hasAlpha) { - A = 1 << 18; + A = -0x40000000; for (j = 0; j < lumFilterSize; j++) A += alpSrc[j][i] * lumFilter[j]; - if (A & 0xF8000000) - A = av_clip_uintp2(A, 27); + A >>= 1; + A += 0x20002000; } Y -= c->yuv2rgb_y_offset; @@ -2083,7 +2083,7 @@ yuv2gbrp16_full_X_c(SwsContext *c, const int16_t *lumFilter, dest16[1][i] = B >> 14; dest16[2][i] = R >> 14; if (hasAlpha) - dest16[3][i] = A >> 11; + dest16[3][i] = av_clip_uintp2(A, 30) >> 14; } if ((!isBE(c->dstFormat)) != (!HAVE_BIGENDIAN)) { for (i = 0; i < dstW; i++) { diff --git a/tests/ref/fate/filter-pixfmts-scale b/tests/ref/fate/filter-pixfmts-scale index 9b601b71daa33..dcc34bd4d107e 100644 --- a/tests/ref/fate/filter-pixfmts-scale +++ b/tests/ref/fate/filter-pixfmts-scale @@ -23,8 +23,8 @@ gbrap10be 6d89abb9248006c3e9017545e9474654 gbrap10le cf974e23f485a10740f5de74a5c8c3df gbrap12be 1d9b57766ba9c2192403f43967cb9af0 gbrap12le bb1ba1c157717db3dd612a76d38a018e -gbrap16be 81542b96575d1fe3b239d23899f5ece3 -gbrap16le 6feb8b9da131917abe867e0eaaf07b90 +gbrap16be c72b935a6e57a8e1c37bff08c2db55b1 +gbrap16le 13eb0e62b1ac9c1c86c81521eaefab5f gbrp dc3387f925f972c61aae7eb23cdc19f0 gbrp10be 0277d4c3a8498d75e2783fb81379e481 gbrp10le f3d70f8ab845c3c9b8f7452e4a6e285a From 949debd1d1df3a96315b3a3083831162845c1188 Mon Sep 17 00:00:00 2001 From: Steven Siloti Date: Tue, 18 Jul 2017 11:26:39 -0700 Subject: [PATCH 2720/3374] avformat/utils: fix memory leak in avformat_free_context The pointer to the packet queue is stored in the internal structure so the queue needs to be flushed before internal is freed. Signed-off-by: Steven Siloti Signed-off-by: Michael Niedermayer --- libavformat/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/utils.c b/libavformat/utils.c index 38d247c6cd59b..58283616dc2c5 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -4333,8 +4333,8 @@ void avformat_free_context(AVFormatContext *s) av_dict_free(&s->metadata); av_dict_free(&s->internal->id3v2_meta); av_freep(&s->streams); - av_freep(&s->internal); flush_packet_queue(s); + av_freep(&s->internal); av_free(s); } From 1f53bde6d817ae13a47748f321adbdfa79e15982 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 4 Aug 2017 02:41:05 +0200 Subject: [PATCH 2721/3374] avcodec/h264_slice: Fix overflow in slice offset Fixes: runtime error: signed integer overflow: 1610612736 * 2 cannot be represented in type 'int' Fixes: 2817/clusterfuzz-testcase-minimized-5289691240726528 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/h264_slice.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 2fb89b189d718..4e7eba4adb462 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1854,17 +1854,19 @@ static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl, sl->deblocking_filter ^= 1; // 1<->0 if (sl->deblocking_filter) { - sl->slice_alpha_c0_offset = get_se_golomb(&sl->gb) * 2; - sl->slice_beta_offset = get_se_golomb(&sl->gb) * 2; - if (sl->slice_alpha_c0_offset > 12 || - sl->slice_alpha_c0_offset < -12 || - sl->slice_beta_offset > 12 || - sl->slice_beta_offset < -12) { + int slice_alpha_c0_offset_div2 = get_se_golomb(&sl->gb); + int slice_beta_offset_div2 = get_se_golomb(&sl->gb); + if (slice_alpha_c0_offset_div2 > 6 || + slice_alpha_c0_offset_div2 < -6 || + slice_beta_offset_div2 > 6 || + slice_beta_offset_div2 < -6) { av_log(h->avctx, AV_LOG_ERROR, "deblocking filter parameters %d %d out of range\n", - sl->slice_alpha_c0_offset, sl->slice_beta_offset); + slice_alpha_c0_offset_div2, slice_beta_offset_div2); return AVERROR_INVALIDDATA; } + sl->slice_alpha_c0_offset = slice_alpha_c0_offset_div2 * 2; + sl->slice_beta_offset = slice_beta_offset_div2 * 2; } } From 1e443051b277f73b94a2f660d3fd31a1a7beab52 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 4 Aug 2017 03:26:30 +0200 Subject: [PATCH 2722/3374] avcodec/aacdec_fixed: fix invalid shift in predict() Fixes: runtime error: shift exponent -2 is negative Fixes: 2818/clusterfuzz-testcase-minimized-5062943676825600 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/aacdec_fixed.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libavcodec/aacdec_fixed.c b/libavcodec/aacdec_fixed.c index ccfef7f6526d7..f6a533010f2ac 100644 --- a/libavcodec/aacdec_fixed.c +++ b/libavcodec/aacdec_fixed.c @@ -305,8 +305,12 @@ static av_always_inline void predict(PredictorState *ps, int *coef, if (output_enable) { int shift = 28 - pv.exp; - if (shift < 31) - *coef += (pv.mant + (1 << (shift - 1))) >> shift; + if (shift < 31) { + if (shift > 0) { + *coef += (pv.mant + (1 << (shift - 1))) >> shift; + } else + *coef += pv.mant << -shift; + } } e0 = av_int2sf(*coef, 2); From eabeb9093abe0169a574945760ad3a26bf47cba4 Mon Sep 17 00:00:00 2001 From: DeHackEd Date: Sun, 6 Aug 2017 15:10:35 +0800 Subject: [PATCH 2723/3374] avformat/hlsenc: allow dynamic encryption key rotation Makes behaviour of 805ce25b1d2f optional, re-enables HLS key rotation feature Reviewed-by: Steven Liu Signed-off-by: DHE --- doc/muxers.texi | 7 ++++++- libavformat/hlsenc.c | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index 94472cef44fe7..2bec5f8954310 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -551,7 +551,7 @@ format. The optional third line specifies the initialization vector (IV) as a hexadecimal string to be used instead of the segment sequence number (default) for encryption. Changes to @var{key_info_file} will result in segment encryption with the new key/IV and an entry in the playlist for the new key -URI/IV. +URI/IV if @code{hls_flags periodic_rekey} is enabled. Key info file format: @example @@ -665,6 +665,11 @@ first segment's information. @item omit_endlist Do not append the @code{EXT-X-ENDLIST} tag at the end of the playlist. +@item periodic_rekey +The file specified by @code{hls_key_info_file} will be checked periodically and +detect updates to the encryption info. Be sure to replace this file atomically, +including the file containing the AES encryption key. + @item split_by_time Allow segments to start on frames other than keyframes. This improves behavior on some players when the time between keyframes is inconsistent, diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 5cf8c89ee7041..74a3249b734d2 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -85,6 +85,7 @@ typedef enum HLSFlags { HLS_SECOND_LEVEL_SEGMENT_DURATION = (1 << 9), // include segment duration (microsec) in segment filenames when use_localtime e.g.: %%09t HLS_SECOND_LEVEL_SEGMENT_SIZE = (1 << 10), // include segment size (bytes) in segment filenames when use_localtime e.g.: %%014s HLS_TEMP_FILE = (1 << 11), + HLS_PERIODIC_REKEY = (1 << 12), } HLSFlags; typedef enum { @@ -1236,7 +1237,7 @@ static int hls_start(AVFormatContext *s) " will use -hls_key_info_file priority\n"); } - if (c->number <= 1) { + if (c->number <= 1 || (c->flags & HLS_PERIODIC_REKEY)) { if (c->key_info_file) { if ((err = hls_encryption_start(s)) < 0) goto fail; @@ -1804,6 +1805,7 @@ static const AVOption options[] = { {"second_level_segment_index", "include segment index in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_INDEX }, 0, UINT_MAX, E, "flags"}, {"second_level_segment_duration", "include segment duration in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_DURATION }, 0, UINT_MAX, E, "flags"}, {"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"}, {"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 }, {"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" }, From 5621a99e27511f9eabcf097764cb5ca554aac639 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Mon, 7 Aug 2017 12:50:13 +0200 Subject: [PATCH 2724/3374] avfilter/drawutils: support gbrap10 too --- libavfilter/drawutils.c | 2 ++ tests/ref/fate/filter-pixfmts-pad | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libavfilter/drawutils.c b/libavfilter/drawutils.c index f19fc5df1d45a..fbe13bc9a42d3 100644 --- a/libavfilter/drawutils.c +++ b/libavfilter/drawutils.c @@ -64,6 +64,8 @@ int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt) case AV_PIX_FMT_GBRP16LE: case AV_PIX_FMT_GBRP16BE: case AV_PIX_FMT_GBRAP: + case AV_PIX_FMT_GBRAP10LE: + case AV_PIX_FMT_GBRAP10BE: case AV_PIX_FMT_GBRAP12LE: case AV_PIX_FMT_GBRAP12BE: case AV_PIX_FMT_GBRAP16LE: diff --git a/tests/ref/fate/filter-pixfmts-pad b/tests/ref/fate/filter-pixfmts-pad index b718552fd40e4..072a0611a02af 100644 --- a/tests/ref/fate/filter-pixfmts-pad +++ b/tests/ref/fate/filter-pixfmts-pad @@ -6,7 +6,7 @@ bgr0 32207a2de1b2ac7937e940a8459b97c0 bgr24 f8b65ad845905c7d0c93ca28dfbb826f bgra 929aac15e848038e367c250037575f9f gbrap 5f16cccab5a17cb766c882e865995167 -gbrap10le 454bf36e86ae92ab7853a9508bb75a99 +gbrap10le a677322100409f9b1d22136b14bfb534 gbrap12le e0e43f838cfbe98086042ba54b5f70be gbrap16le 0f4414db67b84a720106d7a3b2435766 gbrp 3c94d39256db2409015df913fd330a90 From ab6d89d7ee5cdb4b5e58efbf5bbc2517e39aa705 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sat, 5 Aug 2017 14:19:26 +0200 Subject: [PATCH 2725/3374] libavutil: add GRAY9 pixel format --- libavutil/pixdesc.c | 21 +++++++++++++++++++++ libavutil/pixfmt.h | 4 ++++ libavutil/version.h | 4 ++-- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index cea5b0ffd912e..9f1c21cc94338 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -560,6 +560,27 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { }, .flags = AV_PIX_FMT_FLAG_RGB, }, + [AV_PIX_FMT_GRAY9BE] = { + .name = "gray9be", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 9, 1, 8, 1 }, /* Y */ + }, + .flags = AV_PIX_FMT_FLAG_BE, + .alias = "y9be", + }, + [AV_PIX_FMT_GRAY9LE] = { + .name = "gray9le", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 9, 1, 8, 1 }, /* Y */ + }, + .alias = "y9le", + }, [AV_PIX_FMT_GRAY10BE] = { .name = "gray10be", .nb_components = 1, diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index e1e4074bee895..5798507e74f42 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -326,6 +326,9 @@ enum AVPixelFormat { */ AV_PIX_FMT_D3D11, + AV_PIX_FMT_GRAY9BE, ///< Y , 9bpp, big-endian + AV_PIX_FMT_GRAY9LE, ///< Y , 9bpp, little-endian + AV_PIX_FMT_NB ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions }; @@ -342,6 +345,7 @@ enum AVPixelFormat { #define AV_PIX_FMT_0RGB32 AV_PIX_FMT_NE(0RGB, BGR0) #define AV_PIX_FMT_0BGR32 AV_PIX_FMT_NE(0BGR, RGB0) +#define AV_PIX_FMT_GRAY9 AV_PIX_FMT_NE(GRAY9BE, GRAY9LE) #define AV_PIX_FMT_GRAY10 AV_PIX_FMT_NE(GRAY10BE, GRAY10LE) #define AV_PIX_FMT_GRAY12 AV_PIX_FMT_NE(GRAY12BE, GRAY12LE) #define AV_PIX_FMT_GRAY16 AV_PIX_FMT_NE(GRAY16BE, GRAY16LE) diff --git a/libavutil/version.h b/libavutil/version.h index 3dad41f74d11b..b1f9e9dd0015f 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -80,8 +80,8 @@ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 69 -#define LIBAVUTIL_VERSION_MICRO 101 +#define LIBAVUTIL_VERSION_MINOR 70 +#define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ LIBAVUTIL_VERSION_MINOR, \ From de48710c11cebd4c50bb51ebf3cb5fd0e6a79d40 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sat, 5 Aug 2017 14:28:45 +0200 Subject: [PATCH 2726/3374] libswscale: add gray9 support --- libavcodec/raw.c | 2 ++ libswscale/input.c | 2 ++ libswscale/swscale_unscaled.c | 1 + libswscale/utils.c | 4 ++++ libswscale/version.h | 2 +- tests/ref/fate/filter-pixdesc-gray9be | 1 + tests/ref/fate/filter-pixdesc-gray9le | 1 + tests/ref/fate/filter-pixfmts-copy | 2 ++ tests/ref/fate/filter-pixfmts-crop | 2 ++ tests/ref/fate/filter-pixfmts-field | 2 ++ tests/ref/fate/filter-pixfmts-fieldorder | 2 ++ tests/ref/fate/filter-pixfmts-hflip | 2 ++ tests/ref/fate/filter-pixfmts-il | 2 ++ tests/ref/fate/filter-pixfmts-null | 2 ++ tests/ref/fate/filter-pixfmts-pad | 1 + tests/ref/fate/filter-pixfmts-scale | 2 ++ tests/ref/fate/filter-pixfmts-vflip | 2 ++ 17 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 tests/ref/fate/filter-pixdesc-gray9be create mode 100644 tests/ref/fate/filter-pixdesc-gray9le diff --git a/libavcodec/raw.c b/libavcodec/raw.c index c6be686c53506..8da2a9735e801 100644 --- a/libavcodec/raw.c +++ b/libavcodec/raw.c @@ -119,6 +119,8 @@ const PixelFormatTag ff_raw_pix_fmt_tags[] = { { AV_PIX_FMT_RGB48BE, MKTAG( 48, 'R', 'G', 'B') }, { AV_PIX_FMT_BGR48LE, MKTAG('B', 'G', 'R', 48 ) }, { AV_PIX_FMT_BGR48BE, MKTAG( 48, 'B', 'G', 'R') }, + { AV_PIX_FMT_GRAY9LE, MKTAG('Y', '1', 0 , 9 ) }, + { AV_PIX_FMT_GRAY9BE, MKTAG( 9 , 0 , '1', 'Y') }, { AV_PIX_FMT_GRAY10LE, MKTAG('Y', '1', 0 , 10 ) }, { AV_PIX_FMT_GRAY10BE, MKTAG(10 , 0 , '1', 'Y') }, { AV_PIX_FMT_GRAY12LE, MKTAG('Y', '1', 0 , 12 ) }, diff --git a/libswscale/input.c b/libswscale/input.c index 04a51907113b0..bb2f4933ec425 100644 --- a/libswscale/input.c +++ b/libswscale/input.c @@ -1362,6 +1362,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_YUV422P16LE: case AV_PIX_FMT_YUV444P16LE: + case AV_PIX_FMT_GRAY9LE: case AV_PIX_FMT_GRAY10LE: case AV_PIX_FMT_GRAY12LE: case AV_PIX_FMT_GRAY16LE: @@ -1400,6 +1401,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_YUV422P16BE: case AV_PIX_FMT_YUV444P16BE: + case AV_PIX_FMT_GRAY9BE: case AV_PIX_FMT_GRAY10BE: case AV_PIX_FMT_GRAY12BE: case AV_PIX_FMT_GRAY16BE: diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index ba3d688a267ac..3b1b3667ce507 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -1796,6 +1796,7 @@ void ff_get_unscaled_swscale(SwsContext *c) IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR555) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR565) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGRA64) || + IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GRAY9) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GRAY10) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GRAY12) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GRAY16) || diff --git a/libswscale/utils.c b/libswscale/utils.c index 17c996734ab92..b75510d206ae3 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -131,6 +131,8 @@ static const FormatEntry format_entries[AV_PIX_FMT_NB] = { [AV_PIX_FMT_RGB0] = { 1, 1 }, [AV_PIX_FMT_0BGR] = { 1, 1 }, [AV_PIX_FMT_BGR0] = { 1, 1 }, + [AV_PIX_FMT_GRAY9BE] = { 1, 1 }, + [AV_PIX_FMT_GRAY9LE] = { 1, 1 }, [AV_PIX_FMT_GRAY10BE] = { 1, 1 }, [AV_PIX_FMT_GRAY10LE] = { 1, 1 }, [AV_PIX_FMT_GRAY12BE] = { 1, 1 }, @@ -1016,6 +1018,8 @@ static int handle_jpeg(enum AVPixelFormat *format) return 1; case AV_PIX_FMT_GRAY8: case AV_PIX_FMT_YA8: + case AV_PIX_FMT_GRAY9LE: + case AV_PIX_FMT_GRAY9BE: case AV_PIX_FMT_GRAY10LE: case AV_PIX_FMT_GRAY10BE: case AV_PIX_FMT_GRAY12LE: diff --git a/libswscale/version.h b/libswscale/version.h index dcdc85bc749e2..8dff77e48abed 100644 --- a/libswscale/version.h +++ b/libswscale/version.h @@ -28,7 +28,7 @@ #define LIBSWSCALE_VERSION_MAJOR 4 #define LIBSWSCALE_VERSION_MINOR 7 -#define LIBSWSCALE_VERSION_MICRO 101 +#define LIBSWSCALE_VERSION_MICRO 102 #define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \ LIBSWSCALE_VERSION_MINOR, \ diff --git a/tests/ref/fate/filter-pixdesc-gray9be b/tests/ref/fate/filter-pixdesc-gray9be new file mode 100644 index 0000000000000..bf92e299b55a9 --- /dev/null +++ b/tests/ref/fate/filter-pixdesc-gray9be @@ -0,0 +1 @@ +pixdesc-gray9be 19aef736657607fdc6191f5338860580 diff --git a/tests/ref/fate/filter-pixdesc-gray9le b/tests/ref/fate/filter-pixdesc-gray9le new file mode 100644 index 0000000000000..4c65fb97c2790 --- /dev/null +++ b/tests/ref/fate/filter-pixdesc-gray9le @@ -0,0 +1 @@ +pixdesc-gray9le f2a28bb71966f5d6e44eedef67e0118a diff --git a/tests/ref/fate/filter-pixfmts-copy b/tests/ref/fate/filter-pixfmts-copy index 927c8b74f3fe8..124dddeacbe6e 100644 --- a/tests/ref/fate/filter-pixfmts-copy +++ b/tests/ref/fate/filter-pixfmts-copy @@ -43,6 +43,8 @@ gray12be 9685614450f1282be433d2b07234ca1f gray12le 2700bd7fb3fea56e54eb03e31d6d4e57 gray16be 08d997a3faa25a3db9d6be272d282eef gray16le df65eb804360795e3e38a2701fa9641a +gray9be 6382a14594a8b68f0ec7de25531f9334 +gray9le 4eb1dda58706436e3b69aef29b0089db monob 8b04f859fee6a0be856be184acd7a0b5 monow 54d16d2c01abfd72ecdb5e51e283937c nv12 8e24feb2c544dc26a20047a71e4c27aa diff --git a/tests/ref/fate/filter-pixfmts-crop b/tests/ref/fate/filter-pixfmts-crop index cc588b1a969ad..e21479ceb0086 100644 --- a/tests/ref/fate/filter-pixfmts-crop +++ b/tests/ref/fate/filter-pixfmts-crop @@ -43,6 +43,8 @@ gray12be 472700c26cc49b8d5f74af141f6a0d38 gray12le 4f6537fe1f32b3963350f8c435009433 gray16be 38f599da990224de86e3dc7a543121a9 gray16le 9ff7c866bd98def4e6c91542c1c45f80 +gray9be 8ffcb18d699480f55414bfc21ab33321 +gray9le 4d1932d4968a248584f5e39c25f1dd43 nv12 92cda427f794374731ec0321ee00caac nv21 1bcfc197f4fb95de85ba58182d8d2f69 p010be 8b2de2eb6b099bbf355bfc55a0694ddc diff --git a/tests/ref/fate/filter-pixfmts-field b/tests/ref/fate/filter-pixfmts-field index 7799a28f67786..ba2af6e76fc44 100644 --- a/tests/ref/fate/filter-pixfmts-field +++ b/tests/ref/fate/filter-pixfmts-field @@ -43,6 +43,8 @@ gray12be d34c50810b37e6f97dffdf6a8ab958de gray12le cf71b8fee47ce7821f3ae9f9b62ae39a gray16be e1700e056de9917744a7ff4ab2ca63fd gray16le 338de7ac5f7d36d5ad5ac2c8d5bbea68 +gray9be 25e50940fa300a8f09edfb6eba4fd250 +gray9le 1146cfc1b92bfd07ed238e65ffcd134f monob 2129cc72a484d7e10a44de9117aa9f80 monow 03d783611d265cae78293f88ea126ea1 nv12 16f7a46708ef25ebd0b72e47920cc11e diff --git a/tests/ref/fate/filter-pixfmts-fieldorder b/tests/ref/fate/filter-pixfmts-fieldorder index c837cb5236f26..84a9e003c7e2f 100644 --- a/tests/ref/fate/filter-pixfmts-fieldorder +++ b/tests/ref/fate/filter-pixfmts-fieldorder @@ -43,6 +43,8 @@ gray12be 1c3285c150e1dddcf0fbee405cfb068e gray12le a57b6199f5690add0ac0150fa95c4988 gray16be 293a36548ce16543494790f8f7f76a05 gray16le 84f83f5fcbb5d458efb8395a50a3797e +gray9be ec877f5bcf0ea275a6f36c12cc9adf11 +gray9le fba944fde7923d5089f4f52d12988b9e rgb0 2e3d8c91c7a83d451593dfd06607ff39 rgb24 b82577f8215d3dc2681be60f1da247af rgb444be 1c3afc3a0c53c51139c76504f59bb1f4 diff --git a/tests/ref/fate/filter-pixfmts-hflip b/tests/ref/fate/filter-pixfmts-hflip index dddda78aa07b1..875980d8928dd 100644 --- a/tests/ref/fate/filter-pixfmts-hflip +++ b/tests/ref/fate/filter-pixfmts-hflip @@ -43,6 +43,8 @@ gray12be de7b5ef4b513e7e8270c617249d1cbdf gray12le e8d0739ff61649bd82722b3134cbe776 gray16be cf7294d9aa23e1b838692ec01ade587b gray16le d91ce41e304419bcf32ac792f01bd64f +gray9be ac8d260669479ae720a5b6d4d8639e34 +gray9le 424fc581947bc8c357c9ec5e3c1c04d1 nv12 801e58f1be5fd0b5bc4bf007c604b0b4 nv21 9f10dfff8963dc327d3395af21f0554f p010be 744b13e44d39e1ff7588983fa03e0101 diff --git a/tests/ref/fate/filter-pixfmts-il b/tests/ref/fate/filter-pixfmts-il index f05b321dde278..c6885b970ef42 100644 --- a/tests/ref/fate/filter-pixfmts-il +++ b/tests/ref/fate/filter-pixfmts-il @@ -43,6 +43,8 @@ gray12be c62bc3def5ea217dfb68433905cb9d64 gray12le 5bd0fef836928e1e19a315782a8c1302 gray16be 92c3b09f371b610cc1b6a9776034f4d0 gray16le 1db278d23a554e01910cedacc6c02521 +gray9be ed7db5bb2ddc09bc26068c8b858db204 +gray9le 2ec9188f0dcfefef76a09f371d7beb8e monob faba75df28033ba7ce3d82ff2a99ee68 monow 6e9cfb8d3a344c5f0c3e1d5e1297e580 nv12 3c3ba9b1b4c4dfff09c26f71b51dd146 diff --git a/tests/ref/fate/filter-pixfmts-null b/tests/ref/fate/filter-pixfmts-null index 927c8b74f3fe8..124dddeacbe6e 100644 --- a/tests/ref/fate/filter-pixfmts-null +++ b/tests/ref/fate/filter-pixfmts-null @@ -43,6 +43,8 @@ gray12be 9685614450f1282be433d2b07234ca1f gray12le 2700bd7fb3fea56e54eb03e31d6d4e57 gray16be 08d997a3faa25a3db9d6be272d282eef gray16le df65eb804360795e3e38a2701fa9641a +gray9be 6382a14594a8b68f0ec7de25531f9334 +gray9le 4eb1dda58706436e3b69aef29b0089db monob 8b04f859fee6a0be856be184acd7a0b5 monow 54d16d2c01abfd72ecdb5e51e283937c nv12 8e24feb2c544dc26a20047a71e4c27aa diff --git a/tests/ref/fate/filter-pixfmts-pad b/tests/ref/fate/filter-pixfmts-pad index 072a0611a02af..2f8e4dd7cf335 100644 --- a/tests/ref/fate/filter-pixfmts-pad +++ b/tests/ref/fate/filter-pixfmts-pad @@ -19,6 +19,7 @@ gray ddc663a0491df3959d9c5795dceaa72e gray10le fcec0e9ca335941047bf624d3ad39765 gray12le f9ebea57dd9931fd833a278f2e5fa38b gray16le 468bda6155bdc7a7a20c34d6e599fd16 +gray9le d06fab97364d7d480232426facfc362c nv12 381574979cb04be10c9168540310afad nv21 0fdeb2cdd56cf5a7147dc273456fa217 rgb0 78d500c8361ab6423a4826a00268c908 diff --git a/tests/ref/fate/filter-pixfmts-scale b/tests/ref/fate/filter-pixfmts-scale index dcc34bd4d107e..f43c5194286b0 100644 --- a/tests/ref/fate/filter-pixfmts-scale +++ b/tests/ref/fate/filter-pixfmts-scale @@ -43,6 +43,8 @@ gray12be 950de5d1b6b943a26c51f6a157e19a14 gray12le 9c3b154a8bb0a73a3b465892dbc23b36 gray16be 32891cb0928b1119d8d43a6e1bef0e2b gray16le f96cfb5652b090dad52615930f0ce65f +gray9be 779dec0c6c2df008128b91622a20daf8 +gray9le fa87a96ca275f82260358635f838b514 monob f01cb0b623357387827902d9d0963435 monow 35c68b86c226d6990b2dcb573a05ff6b nv12 b118d24a3653fe66e5d9e079033aef79 diff --git a/tests/ref/fate/filter-pixfmts-vflip b/tests/ref/fate/filter-pixfmts-vflip index 4e2df90c54244..84b9d56858ab5 100644 --- a/tests/ref/fate/filter-pixfmts-vflip +++ b/tests/ref/fate/filter-pixfmts-vflip @@ -43,6 +43,8 @@ gray12be 7423ce8a77fbc40c5d4776eb28fec60a gray12le 808158633559d7deebc7dac2d79e88f8 gray16be 29f24ba7cb0fc4fd2ae78963d008f6e6 gray16le a37e9c4ea76e8eeddc2af8f600ba2c10 +gray9be dda11d4ffd62b414012ffc4667fb4971 +gray9le 159bf6482d217b2b8276eb2216cd7a09 monob 7810c4857822ccfc844d78f5e803269a monow 90a947bfcd5f2261e83b577f48ec57b1 nv12 261ebe585ae2aa4e70d39a10c1679294 From 7bfbc2d787a4fe934f540039fbd37c1ab85b39a2 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sat, 5 Aug 2017 15:18:12 +0200 Subject: [PATCH 2727/3374] avfilter/vf_extractplanes: add 9 bitdepth support --- libavfilter/vf_extractplanes.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/libavfilter/vf_extractplanes.c b/libavfilter/vf_extractplanes.c index d3a90465b6054..f2118e6599dc4 100644 --- a/libavfilter/vf_extractplanes.c +++ b/libavfilter/vf_extractplanes.c @@ -103,6 +103,13 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUV440P12LE, AV_PIX_FMT_GBRP10LE, AV_PIX_FMT_GBRAP10LE, AV_PIX_FMT_GBRP12LE, AV_PIX_FMT_GBRAP12LE, + AV_PIX_FMT_YUV420P9LE, + AV_PIX_FMT_YUV422P9LE, + AV_PIX_FMT_YUV444P9LE, + AV_PIX_FMT_YUVA420P9LE, + AV_PIX_FMT_YUVA422P9LE, + AV_PIX_FMT_YUVA444P9LE, + AV_PIX_FMT_GBRP9LE, AV_PIX_FMT_NONE, }; static const enum AVPixelFormat in_pixfmts_be[] = { @@ -142,9 +149,18 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUV440P12BE, AV_PIX_FMT_GBRP10BE, AV_PIX_FMT_GBRAP10BE, AV_PIX_FMT_GBRP12BE, AV_PIX_FMT_GBRAP12BE, + AV_PIX_FMT_YUV420P9BE, + AV_PIX_FMT_YUV422P9BE, + AV_PIX_FMT_YUV444P9BE, + AV_PIX_FMT_YUVA420P9BE, + AV_PIX_FMT_YUVA422P9BE, + AV_PIX_FMT_YUVA444P9BE, + AV_PIX_FMT_GBRP9BE, AV_PIX_FMT_NONE, }; static const enum AVPixelFormat out8_pixfmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE }; + static const enum AVPixelFormat out9le_pixfmts[] = { AV_PIX_FMT_GRAY9LE, AV_PIX_FMT_NONE }; + static const enum AVPixelFormat out9be_pixfmts[] = { AV_PIX_FMT_GRAY9BE, AV_PIX_FMT_NONE }; static const enum AVPixelFormat out10le_pixfmts[] = { AV_PIX_FMT_GRAY10LE, AV_PIX_FMT_NONE }; static const enum AVPixelFormat out10be_pixfmts[] = { AV_PIX_FMT_GRAY10BE, AV_PIX_FMT_NONE }; static const enum AVPixelFormat out12le_pixfmts[] = { AV_PIX_FMT_GRAY12LE, AV_PIX_FMT_NONE }; @@ -184,6 +200,10 @@ static int query_formats(AVFilterContext *ctx) if (depth == 8) out_pixfmts = out8_pixfmts; + else if (!be && depth == 9) + out_pixfmts = out9le_pixfmts; + else if (be && depth == 9) + out_pixfmts = out9be_pixfmts; else if (!be && depth == 10) out_pixfmts = out10le_pixfmts; else if (be && depth == 10) From 86222a7ea0714fbc4572e21ad32360f6be363dae Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Mon, 7 Aug 2017 10:34:34 +0200 Subject: [PATCH 2728/3374] avfilter/vf_waveform: add support for 9 bit depth lowpass --- libavfilter/vf_waveform.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libavfilter/vf_waveform.c b/libavfilter/vf_waveform.c index efca49d22e9bf..0c574742a0a4d 100644 --- a/libavfilter/vf_waveform.c +++ b/libavfilter/vf_waveform.c @@ -166,7 +166,7 @@ static const enum AVPixelFormat in_lowpass_pix_fmts[] = { AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA420P, - AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV420P10, @@ -252,6 +252,11 @@ static const enum AVPixelFormat out_gray8_lowpass_pix_fmts[] = { AV_PIX_FMT_NONE }; +static const enum AVPixelFormat out_gray9_lowpass_pix_fmts[] = { + AV_PIX_FMT_GRAY9, + AV_PIX_FMT_NONE +}; + static const enum AVPixelFormat out_gray10_lowpass_pix_fmts[] = { AV_PIX_FMT_GRAY10, AV_PIX_FMT_NONE @@ -311,6 +316,8 @@ static int query_formats(AVFilterContext *ctx) if (s->filter == LOWPASS && ncomp == 1 && depth == 8) out_pix_fmts = out_gray8_lowpass_pix_fmts; + else if (s->filter == LOWPASS && ncomp == 1 && depth == 9) + out_pix_fmts = out_gray9_lowpass_pix_fmts; else if (s->filter == LOWPASS && ncomp == 1 && depth == 10) out_pix_fmts = out_gray10_lowpass_pix_fmts; else if (s->filter == LOWPASS && ncomp == 1 && depth == 12) From bac508fec1c45347bad8477075d77b70a0ee5c0a Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Mon, 7 Aug 2017 11:52:18 +0200 Subject: [PATCH 2729/3374] avfilter: add support for GRAY9 and GBRAP10 --- libavfilter/vf_atadenoise.c | 1 + libavfilter/vf_avgblur.c | 4 ++-- libavfilter/vf_bitplanenoise.c | 2 +- libavfilter/vf_convolution.c | 4 ++-- libavfilter/vf_deflicker.c | 2 +- libavfilter/vf_gblur.c | 4 ++-- libavfilter/vf_histogram.c | 6 ++++-- libavfilter/vf_hysteresis.c | 4 ++-- libavfilter/vf_limiter.c | 4 ++-- libavfilter/vf_lut.c | 1 + libavfilter/vf_lut2.c | 4 ++-- libavfilter/vf_maskedclamp.c | 4 ++-- libavfilter/vf_maskedmerge.c | 4 ++-- libavfilter/vf_midequalizer.c | 2 +- libavfilter/vf_premultiply.c | 4 +++- libavfilter/vf_psnr.c | 2 +- libavfilter/vf_remap.c | 3 +++ libavfilter/vf_ssim.c | 2 +- libavfilter/vf_threshold.c | 4 ++-- libavfilter/vf_vectorscope.c | 6 +++--- tests/ref/fate/filter-pixfmts-lut | 1 + 21 files changed, 39 insertions(+), 29 deletions(-) diff --git a/libavfilter/vf_atadenoise.c b/libavfilter/vf_atadenoise.c index 8d34403847051..03b772c6742fe 100644 --- a/libavfilter/vf_atadenoise.c +++ b/libavfilter/vf_atadenoise.c @@ -80,6 +80,7 @@ static int query_formats(AVFilterContext *ctx) { static const enum AVPixelFormat pixel_fmts[] = { AV_PIX_FMT_GRAY8, + AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, diff --git a/libavfilter/vf_avgblur.c b/libavfilter/vf_avgblur.c index 17e022d22a7be..afd4a6ab79581 100644 --- a/libavfilter/vf_avgblur.c +++ b/libavfilter/vf_avgblur.c @@ -241,8 +241,8 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16, AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, - AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, - AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, + AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, AV_PIX_FMT_NONE }; diff --git a/libavfilter/vf_bitplanenoise.c b/libavfilter/vf_bitplanenoise.c index 82318a7061617..dd6864bc5e34a 100644 --- a/libavfilter/vf_bitplanenoise.c +++ b/libavfilter/vf_bitplanenoise.c @@ -63,7 +63,7 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUV444P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV420P16, AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, - AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, AV_PIX_FMT_NONE }; diff --git a/libavfilter/vf_convolution.c b/libavfilter/vf_convolution.c index 530859422c876..602031999f338 100644 --- a/libavfilter/vf_convolution.c +++ b/libavfilter/vf_convolution.c @@ -104,8 +104,8 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16, AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, - AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, - AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16, + AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, AV_PIX_FMT_NONE }; diff --git a/libavfilter/vf_deflicker.c b/libavfilter/vf_deflicker.c index 2a33adc5033ff..863a3508c1eca 100644 --- a/libavfilter/vf_deflicker.c +++ b/libavfilter/vf_deflicker.c @@ -94,7 +94,7 @@ AVFILTER_DEFINE_CLASS(deflicker); static int query_formats(AVFilterContext *ctx) { static const enum AVPixelFormat pixel_fmts[] = { - AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, diff --git a/libavfilter/vf_gblur.c b/libavfilter/vf_gblur.c index fe1d5c77da8cb..fd901e20d46be 100644 --- a/libavfilter/vf_gblur.c +++ b/libavfilter/vf_gblur.c @@ -201,8 +201,8 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16, AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, - AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, - AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, + AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, AV_PIX_FMT_NONE }; diff --git a/libavfilter/vf_histogram.c b/libavfilter/vf_histogram.c index 7ee5fcd84f214..5185992de60a6 100644 --- a/libavfilter/vf_histogram.c +++ b/libavfilter/vf_histogram.c @@ -88,7 +88,7 @@ static const enum AVPixelFormat levels_in_pix_fmts[] = { AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV440P12, AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRP, - AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, + AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE @@ -125,7 +125,7 @@ static const enum AVPixelFormat levels_out_rgb9_pix_fmts[] = { }; static const enum AVPixelFormat levels_out_rgb10_pix_fmts[] = { - AV_PIX_FMT_GBRP10, + AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_NONE }; @@ -200,7 +200,9 @@ static int config_input(AVFilterLink *inlink) h->mult = h->histogram_size / 256; switch (inlink->format) { + case AV_PIX_FMT_GBRAP12: case AV_PIX_FMT_GBRP12: + case AV_PIX_FMT_GBRAP10: case AV_PIX_FMT_GBRP10: case AV_PIX_FMT_GBRP9: case AV_PIX_FMT_GBRAP: diff --git a/libavfilter/vf_hysteresis.c b/libavfilter/vf_hysteresis.c index c3b769b8a7d18..8ee827d8af289 100644 --- a/libavfilter/vf_hysteresis.c +++ b/libavfilter/vf_hysteresis.c @@ -78,8 +78,8 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16, AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, - AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, - AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, + AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, AV_PIX_FMT_NONE }; diff --git a/libavfilter/vf_limiter.c b/libavfilter/vf_limiter.c index c45df4972513b..9c62b11884923 100644 --- a/libavfilter/vf_limiter.c +++ b/libavfilter/vf_limiter.c @@ -80,8 +80,8 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16, AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, - AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, - AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, + AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, AV_PIX_FMT_NONE }; diff --git a/libavfilter/vf_lut.c b/libavfilter/vf_lut.c index d005afae87425..11c039ead771a 100644 --- a/libavfilter/vf_lut.c +++ b/libavfilter/vf_lut.c @@ -130,6 +130,7 @@ static av_cold void uninit(AVFilterContext *ctx) AV_PIX_FMT_RGB48LE, AV_PIX_FMT_RGBA64LE, \ AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, \ AV_PIX_FMT_GBRP9LE, AV_PIX_FMT_GBRP10LE, \ + AV_PIX_FMT_GBRAP10LE, \ AV_PIX_FMT_GBRP12LE, AV_PIX_FMT_GBRP14LE, \ AV_PIX_FMT_GBRP16LE, AV_PIX_FMT_GBRAP12LE, \ AV_PIX_FMT_GBRAP16LE diff --git a/libavfilter/vf_lut2.c b/libavfilter/vf_lut2.c index 0859285382a79..176b98ee80d54 100644 --- a/libavfilter/vf_lut2.c +++ b/libavfilter/vf_lut2.c @@ -110,8 +110,8 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, - AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP12, - AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, + AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_NONE }; diff --git a/libavfilter/vf_maskedclamp.c b/libavfilter/vf_maskedclamp.c index 5ad8aa7f66fa1..81ba05147cc27 100644 --- a/libavfilter/vf_maskedclamp.c +++ b/libavfilter/vf_maskedclamp.c @@ -77,8 +77,8 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16, AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, - AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, - AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, + AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, AV_PIX_FMT_NONE }; diff --git a/libavfilter/vf_maskedmerge.c b/libavfilter/vf_maskedmerge.c index 54def62820404..cd11c959f6bed 100644 --- a/libavfilter/vf_maskedmerge.c +++ b/libavfilter/vf_maskedmerge.c @@ -55,8 +55,8 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16, AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, - AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, - AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, + AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, AV_PIX_FMT_NONE }; diff --git a/libavfilter/vf_midequalizer.c b/libavfilter/vf_midequalizer.c index 9d9ad1aec1fde..8101741bdc816 100644 --- a/libavfilter/vf_midequalizer.c +++ b/libavfilter/vf_midequalizer.c @@ -66,7 +66,7 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, - AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12, diff --git a/libavfilter/vf_premultiply.c b/libavfilter/vf_premultiply.c index 9ecafe42d8adf..d16ffd3b9cc25 100644 --- a/libavfilter/vf_premultiply.c +++ b/libavfilter/vf_premultiply.c @@ -65,7 +65,7 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUV444P16, AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, - AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, AV_PIX_FMT_NONE }; @@ -406,6 +406,7 @@ static int process_frame(FFFrameSync *fs) case AV_PIX_FMT_GRAY8: s->premultiply[0] = limited ? unpremultiply8offset : unpremultiply8; break; + case AV_PIX_FMT_GRAY9: case AV_PIX_FMT_GRAY10: case AV_PIX_FMT_GRAY12: case AV_PIX_FMT_GRAY16: @@ -443,6 +444,7 @@ static int process_frame(FFFrameSync *fs) case AV_PIX_FMT_GRAY8: s->premultiply[0] = limited ? premultiply8offset : premultiply8; break; + case AV_PIX_FMT_GRAY9: case AV_PIX_FMT_GRAY10: case AV_PIX_FMT_GRAY12: case AV_PIX_FMT_GRAY16: diff --git a/libavfilter/vf_psnr.c b/libavfilter/vf_psnr.c index 20962c41f6f94..6ab21d8e229e0 100644 --- a/libavfilter/vf_psnr.c +++ b/libavfilter/vf_psnr.c @@ -252,7 +252,7 @@ static av_cold int init(AVFilterContext *ctx) static int query_formats(AVFilterContext *ctx) { static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, #define PF_NOALPHA(suf) AV_PIX_FMT_YUV420##suf, AV_PIX_FMT_YUV422##suf, AV_PIX_FMT_YUV444##suf #define PF_ALPHA(suf) AV_PIX_FMT_YUVA420##suf, AV_PIX_FMT_YUVA422##suf, AV_PIX_FMT_YUVA444##suf #define PF(suf) PF_NOALPHA(suf), PF_ALPHA(suf) diff --git a/libavfilter/vf_remap.c b/libavfilter/vf_remap.c index d549912fcffef..a62ec4c183358 100644 --- a/libavfilter/vf_remap.c +++ b/libavfilter/vf_remap.c @@ -83,6 +83,9 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, AV_PIX_FMT_RGB48, AV_PIX_FMT_BGR48, AV_PIX_FMT_RGBA64, AV_PIX_FMT_BGRA64, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, + AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, + AV_PIX_FMT_GRAY16, AV_PIX_FMT_NONE }; static const enum AVPixelFormat map_fmts[] = { diff --git a/libavfilter/vf_ssim.c b/libavfilter/vf_ssim.c index d8c049177cc89..371f6dba70071 100644 --- a/libavfilter/vf_ssim.c +++ b/libavfilter/vf_ssim.c @@ -352,7 +352,7 @@ static av_cold int init(AVFilterContext *ctx) static int query_formats(AVFilterContext *ctx) { static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, diff --git a/libavfilter/vf_threshold.c b/libavfilter/vf_threshold.c index 6a64f270fef49..4e31ab4c0fa12 100644 --- a/libavfilter/vf_threshold.c +++ b/libavfilter/vf_threshold.c @@ -79,8 +79,8 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16, AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, - AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP16, - AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, + AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12 , AV_PIX_FMT_GBRAP16, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, AV_PIX_FMT_NONE }; diff --git a/libavfilter/vf_vectorscope.c b/libavfilter/vf_vectorscope.c index 8c596c7a88dbe..e3e00797d0c13 100644 --- a/libavfilter/vf_vectorscope.c +++ b/libavfilter/vf_vectorscope.c @@ -154,7 +154,7 @@ static const enum AVPixelFormat out_rgb9_pix_fmts[] = { }; static const enum AVPixelFormat out_rgb10_pix_fmts[] = { - AV_PIX_FMT_GBRP10, + AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_NONE }; @@ -169,7 +169,7 @@ static const enum AVPixelFormat in1_pix_fmts[] = { AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUV444P12, AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRP, - AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, + AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_NONE }; @@ -181,7 +181,7 @@ static const enum AVPixelFormat in2_pix_fmts[] = { AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRP, - AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, + AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, diff --git a/tests/ref/fate/filter-pixfmts-lut b/tests/ref/fate/filter-pixfmts-lut index 876568e4f0ff5..db3fd417b7d69 100644 --- a/tests/ref/fate/filter-pixfmts-lut +++ b/tests/ref/fate/filter-pixfmts-lut @@ -3,6 +3,7 @@ argb 4f575be3cd02799389f581df99c4de38 bgr24 fa43e3b2abfde8d9e60e157a9acc553d bgra 4e2e689897ee7a8e42b16234597bab35 gbrap 0d1eb2c39e291c53c57302cdc653c2fc +gbrap10le fed58af6d557a7069a4a39e6d8f5f4e0 gbrap12le 43fec231bd1d3dd957cdd8478cab9259 gbrap16le 22ca3644658ae306541116c31e135074 gbrp e572d53183f3f2ed3951aa9940d440a1 From 181c9abd47cbee20511db4494a92f78dc11687cc Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Fri, 4 Aug 2017 22:28:53 +0200 Subject: [PATCH 2730/3374] avfilter/vf_premultiply: add inplace mode --- doc/filters.texi | 6 ++ libavfilter/vf_premultiply.c | 199 +++++++++++++++++++++++++---------- 2 files changed, 151 insertions(+), 54 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index c1d572f71aa07..eedc7b58968c5 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -11755,6 +11755,9 @@ The filter accepts the following option: @item planes Set which planes will be processed, unprocessed planes will be copied. By default value 0xf, all planes will be processed. + +@item inplace +Do not require 2nd input for processing, instead use alpha plane from input stream. @end table @section prewitt @@ -14597,6 +14600,9 @@ If the format has 3 or 4 components: for RGB formats bit 0 is green, bit 1 is blue and bit 2 is red; for YUV formats bit 0 is luma, bit 1 is chroma-U and bit 2 is chroma-V. If present, the alpha channel is always the last bit. + +@item inplace +Do not require 2nd input for processing, instead use alpha plane from input stream. @end table @anchor{unsharp} diff --git a/libavfilter/vf_premultiply.c b/libavfilter/vf_premultiply.c index d16ffd3b9cc25..148a9e55cb8f6 100644 --- a/libavfilter/vf_premultiply.c +++ b/libavfilter/vf_premultiply.c @@ -22,6 +22,7 @@ #include "libavutil/pixdesc.h" #include "libavutil/opt.h" #include "avfilter.h" +#include "filters.h" #include "formats.h" #include "framesync2.h" #include "internal.h" @@ -34,6 +35,7 @@ typedef struct PreMultiplyContext { int nb_planes; int planes; int inverse; + int inplace; int half, depth, offset, max; FFFrameSync fs; @@ -50,6 +52,7 @@ typedef struct PreMultiplyContext { static const AVOption options[] = { { "planes", "set planes", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=0xF}, 0, 0xF, FLAGS }, + { "inplace","enable inplace mode", OFFSET(inplace), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, { NULL } }; @@ -58,7 +61,9 @@ AVFILTER_DEFINE_CLASS(premultiply); static int query_formats(AVFilterContext *ctx) { - static const enum AVPixelFormat pix_fmts[] = { + PreMultiplyContext *s = ctx->priv; + + static const enum AVPixelFormat no_alpha_pix_fmts[] = { AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV444P14, @@ -69,7 +74,15 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_NONE }; - return ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); + static const enum AVPixelFormat alpha_pix_fmts[] = { + AV_PIX_FMT_YUVA444P, + AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P16, + AV_PIX_FMT_GBRAP, + AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, + AV_PIX_FMT_NONE + }; + + return ff_set_common_formats(ctx, ff_make_format_list(s->inplace ? alpha_pix_fmts : no_alpha_pix_fmts)); } static void premultiply8(const uint8_t *msrc, const uint8_t *asrc, @@ -348,29 +361,23 @@ static void unpremultiply16offset(const uint8_t *mmsrc, const uint8_t *aasrc, } } -static int process_frame(FFFrameSync *fs) +static int filter_frame(AVFilterContext *ctx, + AVFrame **out, AVFrame *base, AVFrame *alpha) { - AVFilterContext *ctx = fs->parent; - PreMultiplyContext *s = fs->opaque; + PreMultiplyContext *s = ctx->priv; AVFilterLink *outlink = ctx->outputs[0]; - AVFrame *out, *base, *alpha; - int ret; - - if ((ret = ff_framesync2_get_frame(&s->fs, 0, &base, 0)) < 0 || - (ret = ff_framesync2_get_frame(&s->fs, 1, &alpha, 0)) < 0) - return ret; if (ctx->is_disabled) { - out = av_frame_clone(base); - if (!out) + *out = av_frame_clone(base); + if (!*out) return AVERROR(ENOMEM); } else { int p, full, limited; - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) + *out = ff_get_video_buffer(outlink, outlink->w, outlink->h); + if (!*out) return AVERROR(ENOMEM); - av_frame_copy_props(out, base); + av_frame_copy_props(*out, base); full = base->color_range == AVCOL_RANGE_JPEG; limited = base->color_range == AVCOL_RANGE_MPEG; @@ -378,6 +385,7 @@ static int process_frame(FFFrameSync *fs) if (s->inverse) { switch (outlink->format) { case AV_PIX_FMT_YUV444P: + case AV_PIX_FMT_YUVA444P: s->premultiply[0] = full ? unpremultiply8 : unpremultiply8offset; s->premultiply[1] = s->premultiply[2] = unpremultiply8yuv; break; @@ -386,21 +394,28 @@ static int process_frame(FFFrameSync *fs) s->premultiply[1] = s->premultiply[2] = unpremultiply8yuv; break; case AV_PIX_FMT_GBRP: + case AV_PIX_FMT_GBRAP: s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? unpremultiply8offset : unpremultiply8; break; case AV_PIX_FMT_YUV444P9: + case AV_PIX_FMT_YUVA444P9: case AV_PIX_FMT_YUV444P10: + case AV_PIX_FMT_YUVA444P10: case AV_PIX_FMT_YUV444P12: case AV_PIX_FMT_YUV444P14: case AV_PIX_FMT_YUV444P16: + case AV_PIX_FMT_YUVA444P16: s->premultiply[0] = full ? unpremultiply16 : unpremultiply16offset; s->premultiply[1] = s->premultiply[2] = unpremultiply16yuv; break; case AV_PIX_FMT_GBRP9: case AV_PIX_FMT_GBRP10: + case AV_PIX_FMT_GBRAP10: case AV_PIX_FMT_GBRP12: + case AV_PIX_FMT_GBRAP12: case AV_PIX_FMT_GBRP14: case AV_PIX_FMT_GBRP16: + case AV_PIX_FMT_GBRAP16: s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? unpremultiply16offset : unpremultiply16; break; case AV_PIX_FMT_GRAY8: @@ -416,6 +431,7 @@ static int process_frame(FFFrameSync *fs) } else { switch (outlink->format) { case AV_PIX_FMT_YUV444P: + case AV_PIX_FMT_YUVA444P: s->premultiply[0] = full ? premultiply8 : premultiply8offset; s->premultiply[1] = s->premultiply[2] = premultiply8yuv; break; @@ -424,21 +440,28 @@ static int process_frame(FFFrameSync *fs) s->premultiply[1] = s->premultiply[2] = premultiply8yuv; break; case AV_PIX_FMT_GBRP: + case AV_PIX_FMT_GBRAP: s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? premultiply8offset : premultiply8; break; case AV_PIX_FMT_YUV444P9: + case AV_PIX_FMT_YUVA444P9: case AV_PIX_FMT_YUV444P10: + case AV_PIX_FMT_YUVA444P10: case AV_PIX_FMT_YUV444P12: case AV_PIX_FMT_YUV444P14: case AV_PIX_FMT_YUV444P16: + case AV_PIX_FMT_YUVA444P16: s->premultiply[0] = full ? premultiply16 : premultiply16offset; s->premultiply[1] = s->premultiply[2] = premultiply16yuv; break; case AV_PIX_FMT_GBRP9: case AV_PIX_FMT_GBRP10: + case AV_PIX_FMT_GBRAP10: case AV_PIX_FMT_GBRP12: + case AV_PIX_FMT_GBRAP12: case AV_PIX_FMT_GBRP14: case AV_PIX_FMT_GBRP16: + case AV_PIX_FMT_GBRAP16: s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? premultiply16offset : premultiply16; break; case AV_PIX_FMT_GRAY8: @@ -454,20 +477,39 @@ static int process_frame(FFFrameSync *fs) } for (p = 0; p < s->nb_planes; p++) { - if (!((1 << p) & s->planes)) { - av_image_copy_plane(out->data[p], out->linesize[p], base->data[p], base->linesize[p], + if (!((1 << p) & s->planes) || p == 3) { + av_image_copy_plane((*out)->data[p], (*out)->linesize[p], base->data[p], base->linesize[p], s->linesize[p], s->height[p]); continue; } - s->premultiply[p](base->data[p], alpha->data[0], - out->data[p], - base->linesize[p], alpha->linesize[0], - out->linesize[p], + s->premultiply[p](base->data[p], s->inplace ? alpha->data[3] : alpha->data[0], + (*out)->data[p], + base->linesize[p], s->inplace ? alpha->linesize[3] : alpha->linesize[0], + (*out)->linesize[p], s->width[p], s->height[p], s->half, s->inverse ? s->max : s->depth, s->offset); } } + + return 0; +} + +static int process_frame(FFFrameSync *fs) +{ + AVFilterContext *ctx = fs->parent; + PreMultiplyContext *s = fs->opaque; + AVFilterLink *outlink = ctx->outputs[0]; + AVFrame *out = NULL, *base, *alpha; + int ret; + + if ((ret = ff_framesync2_get_frame(&s->fs, 0, &base, 0)) < 0 || + (ret = ff_framesync2_get_frame(&s->fs, 1, &alpha, 0)) < 0) + return ret; + + if ((ret = filter_frame(ctx, &out, base, alpha)) < 0) + return ret; + out->pts = av_rescale_q(base->pts, s->fs.time_base, outlink->time_base); return ff_filter_frame(outlink, out); @@ -505,22 +547,26 @@ static int config_output(AVFilterLink *outlink) AVFilterContext *ctx = outlink->src; PreMultiplyContext *s = ctx->priv; AVFilterLink *base = ctx->inputs[0]; - AVFilterLink *alpha = ctx->inputs[1]; + AVFilterLink *alpha; FFFrameSyncIn *in; int ret; - if (base->format != alpha->format) { - av_log(ctx, AV_LOG_ERROR, "inputs must be of same pixel format\n"); - return AVERROR(EINVAL); - } - if (base->w != alpha->w || - base->h != alpha->h) { - av_log(ctx, AV_LOG_ERROR, "First input link %s parameters " - "(size %dx%d) do not match the corresponding " - "second input link %s parameters (%dx%d) ", - ctx->input_pads[0].name, base->w, base->h, - ctx->input_pads[1].name, alpha->w, alpha->h); - return AVERROR(EINVAL); + if (!s->inplace) { + alpha = ctx->inputs[1]; + + if (base->format != alpha->format) { + av_log(ctx, AV_LOG_ERROR, "inputs must be of same pixel format\n"); + return AVERROR(EINVAL); + } + if (base->w != alpha->w || + base->h != alpha->h) { + av_log(ctx, AV_LOG_ERROR, "First input link %s parameters " + "(size %dx%d) do not match the corresponding " + "second input link %s parameters (%dx%d) ", + ctx->input_pads[0].name, base->w, base->h, + ctx->input_pads[1].name, alpha->w, alpha->h); + return AVERROR(EINVAL); + } } outlink->w = base->w; @@ -529,6 +575,9 @@ static int config_output(AVFilterLink *outlink) outlink->sample_aspect_ratio = base->sample_aspect_ratio; outlink->frame_rate = base->frame_rate; + if (s->inplace) + return 0; + if ((ret = ff_framesync2_init(&s->fs, ctx, 2)) < 0) return ret; @@ -550,16 +599,67 @@ static int config_output(AVFilterLink *outlink) static int activate(AVFilterContext *ctx) { PreMultiplyContext *s = ctx->priv; - return ff_framesync2_activate(&s->fs); + + if (s->inplace) { + AVFrame *frame = NULL; + AVFrame *out = NULL; + int ret, status; + int64_t pts; + + if ((ret = ff_inlink_consume_frame(ctx->inputs[0], &frame)) > 0) { + if ((ret = filter_frame(ctx, &out, frame, frame)) < 0) + return ret; + av_frame_free(&frame); + ret = ff_filter_frame(ctx->outputs[0], out); + } + if (ret < 0) { + return ret; + } else if (ff_inlink_acknowledge_status(ctx->inputs[0], &status, &pts)) { + ff_outlink_set_status(ctx->outputs[0], status, pts); + return 0; + } else { + if (ff_outlink_frame_wanted(ctx->outputs[0])) + ff_inlink_request_frame(ctx->inputs[0]); + return 0; + } + } else { + return ff_framesync2_activate(&s->fs); + } } static av_cold int init(AVFilterContext *ctx) { PreMultiplyContext *s = ctx->priv; + AVFilterPad pad = { 0 }; + int ret; if (!strcmp(ctx->filter->name, "unpremultiply")) s->inverse = 1; + pad.type = AVMEDIA_TYPE_VIDEO; + pad.name = av_strdup("main"); + pad.config_props = config_input; + if (!pad.name) + return AVERROR(ENOMEM); + + if ((ret = ff_insert_inpad(ctx, 0, &pad)) < 0) { + av_freep(&pad.name); + return ret; + } + + if (!s->inplace) { + pad.type = AVMEDIA_TYPE_VIDEO; + pad.name = av_strdup("alpha"); + pad.config_props = NULL; + if (!pad.name) + return AVERROR(ENOMEM); + + if ((ret = ff_insert_inpad(ctx, 1, &pad)) < 0) { + av_freep(&pad.name); + return ret; + } + } + return 0; } @@ -567,22 +667,10 @@ static av_cold void uninit(AVFilterContext *ctx) { PreMultiplyContext *s = ctx->priv; - ff_framesync2_uninit(&s->fs); + if (!s->inplace) + ff_framesync2_uninit(&s->fs); } -static const AVFilterPad premultiply_inputs[] = { - { - .name = "main", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_input, - }, - { - .name = "alpha", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - static const AVFilterPad premultiply_outputs[] = { { .name = "default", @@ -598,13 +686,15 @@ AVFilter ff_vf_premultiply = { .name = "premultiply", .description = NULL_IF_CONFIG_SMALL("PreMultiply first stream with first plane of second stream."), .priv_size = sizeof(PreMultiplyContext), + .init = init, .uninit = uninit, .query_formats = query_formats, .activate = activate, - .inputs = premultiply_inputs, + .inputs = NULL, .outputs = premultiply_outputs, .priv_class = &premultiply_class, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | + AVFILTER_FLAG_DYNAMIC_INPUTS, }; #endif /* CONFIG_PREMULTIPLY_FILTER */ @@ -622,10 +712,11 @@ AVFilter ff_vf_unpremultiply = { .uninit = uninit, .query_formats = query_formats, .activate = activate, - .inputs = premultiply_inputs, + .inputs = NULL, .outputs = premultiply_outputs, .priv_class = &unpremultiply_class, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | + AVFILTER_FLAG_DYNAMIC_INPUTS, }; #endif /* CONFIG_UNPREMULTIPLY_FILTER */ From 1bef0088dce77e04d95981e2c1c0183d740584a1 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Mon, 7 Aug 2017 18:39:29 +0200 Subject: [PATCH 2731/3374] avfilter/drawutils: add gray9/10/12 support --- libavfilter/drawutils.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/libavfilter/drawutils.c b/libavfilter/drawutils.c index fbe13bc9a42d3..77ab86b775454 100644 --- a/libavfilter/drawutils.c +++ b/libavfilter/drawutils.c @@ -262,14 +262,16 @@ void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4 EXPAND(2); EXPAND(1); EXPAND(0); - } else if (draw->format == AV_PIX_FMT_GRAY8 || draw->format == AV_PIX_FMT_GRAY8A) { - color->comp[0].u8[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]); - color->comp[1].u8[0] = rgba[3]; - } else if (draw->format == AV_PIX_FMT_GRAY16LE || draw->format == AV_PIX_FMT_YA16LE) { + } else if (draw->format == AV_PIX_FMT_GRAY8 || draw->format == AV_PIX_FMT_GRAY8A || + draw->format == AV_PIX_FMT_GRAY16LE || draw->format == AV_PIX_FMT_YA16LE || + draw->format == AV_PIX_FMT_GRAY9LE || + draw->format == AV_PIX_FMT_GRAY10LE || + draw->format == AV_PIX_FMT_GRAY12LE) { + const AVPixFmtDescriptor *desc = draw->desc; color->comp[0].u8[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]); - color->comp[0].u16[0] = color->comp[0].u8[0] << 8; + EXPAND(0); color->comp[1].u8[0] = rgba[3]; - color->comp[1].u16[0] = color->comp[1].u8[0] << 8; + EXPAND(1); } else { av_log(NULL, AV_LOG_WARNING, "Color conversion not implemented for %s\n", draw->desc->name); From 45759540a5597bb6811afc749baa637f778a5ca0 Mon Sep 17 00:00:00 2001 From: James Almer Date: Tue, 8 Aug 2017 01:34:18 -0300 Subject: [PATCH 2732/3374] fate: update ref files for gray pixel formats changes --- tests/ref/fate/filter-pixfmts-pad | 6 +++--- tests/ref/fate/sws-pixdesc-query | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/ref/fate/filter-pixfmts-pad b/tests/ref/fate/filter-pixfmts-pad index 2f8e4dd7cf335..e777211cd9a0b 100644 --- a/tests/ref/fate/filter-pixfmts-pad +++ b/tests/ref/fate/filter-pixfmts-pad @@ -16,10 +16,10 @@ gbrp14le deb2c3af6b48faa52f6a1f6590a0cdf7 gbrp16le a6156d1a37e05ee621b2a343fb158bd6 gbrp9le 9e827f438e081d334a6cae7e282698b0 gray ddc663a0491df3959d9c5795dceaa72e -gray10le fcec0e9ca335941047bf624d3ad39765 -gray12le f9ebea57dd9931fd833a278f2e5fa38b +gray10le e6559c1c8c05ce89f44b465573db44e7 +gray12le 1e6c6757658c7ae8a1f830432c5b7722 gray16le 468bda6155bdc7a7a20c34d6e599fd16 -gray9le d06fab97364d7d480232426facfc362c +gray9le f8f3dfe31ca5fcba828285bceefdab9a nv12 381574979cb04be10c9168540310afad nv21 0fdeb2cdd56cf5a7147dc273456fa217 rgb0 78d500c8361ab6423a4826a00268c908 diff --git a/tests/ref/fate/sws-pixdesc-query b/tests/ref/fate/sws-pixdesc-query index fb1e62f32619d..9510b4ee0e0b3 100644 --- a/tests/ref/fate/sws-pixdesc-query +++ b/tests/ref/fate/sws-pixdesc-query @@ -49,6 +49,8 @@ isNBPS: gray10le gray12be gray12le + gray9be + gray9le nv20be nv20le p010be @@ -118,6 +120,7 @@ isBE: gray10be gray12be gray16be + gray9be nv20be p010be p016be @@ -396,6 +399,8 @@ Gray: gray12le gray16be gray16le + gray9be + gray9le ya16be ya16le ya8 From caa12027baf1180453846c58da08fc87accc0ff6 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 22 Jul 2017 23:05:13 +0200 Subject: [PATCH 2733/3374] lavc, lavu: move frame cropping to a convenience function Signed-off-by: Anton Khirnov Merged from Libav commit 47399ccdfd. --- doc/APIchanges | 3 ++ libavcodec/decode.c | 89 +-------------------------------------- libavutil/frame.c | 100 ++++++++++++++++++++++++++++++++++++++++++++ libavutil/frame.h | 34 +++++++++++++++ libavutil/version.h | 2 +- 5 files changed, 140 insertions(+), 88 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 63fac21000609..cd69ec7bc681c 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-08-08 - xxxxxxx - lavu 55.71.100 - frame.h + Add av_frame_apply_cropping(). + 2017-07-25 - 24de4fddca - lavu 55.69.100 - frame.h Add AV_FRAME_DATA_ICC_PROFILE side data type. diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 052f93d82fc94..9b57910842668 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -683,44 +683,8 @@ int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacke return 0; } -static int calc_cropping_offsets(size_t offsets[4], const AVFrame *frame, - const AVPixFmtDescriptor *desc) -{ - int i, j; - - for (i = 0; frame->data[i]; i++) { - const AVComponentDescriptor *comp = NULL; - int shift_x = (i == 1 || i == 2) ? desc->log2_chroma_w : 0; - int shift_y = (i == 1 || i == 2) ? desc->log2_chroma_h : 0; - - if (desc->flags & (AV_PIX_FMT_FLAG_PAL | AV_PIX_FMT_FLAG_PSEUDOPAL) && i == 1) { - offsets[i] = 0; - break; - } - - /* find any component descriptor for this plane */ - for (j = 0; j < desc->nb_components; j++) { - if (desc->comp[j].plane == i) { - comp = &desc->comp[j]; - break; - } - } - if (!comp) - return AVERROR_BUG; - - offsets[i] = (frame->crop_top >> shift_y) * frame->linesize[i] + - (frame->crop_left >> shift_x) * comp->step; - } - - return 0; -} - static int apply_cropping(AVCodecContext *avctx, AVFrame *frame) { - const AVPixFmtDescriptor *desc; - size_t offsets[4]; - int i; - /* make sure we are noisy about decoders returning invalid cropping data */ if (frame->crop_left >= INT_MAX - frame->crop_right || frame->crop_top >= INT_MAX - frame->crop_bottom || @@ -742,57 +706,8 @@ static int apply_cropping(AVCodecContext *avctx, AVFrame *frame) if (!avctx->apply_cropping) return 0; - desc = av_pix_fmt_desc_get(frame->format); - if (!desc) - return AVERROR_BUG; - - /* Apply just the right/bottom cropping for hwaccel formats. Bitstream - * formats cannot be easily handled here either (and corresponding decoders - * should not export any cropping anyway), so do the same for those as well. - * */ - if (desc->flags & (AV_PIX_FMT_FLAG_BITSTREAM | AV_PIX_FMT_FLAG_HWACCEL)) { - frame->width -= frame->crop_right; - frame->height -= frame->crop_bottom; - frame->crop_right = 0; - frame->crop_bottom = 0; - return 0; - } - - /* calculate the offsets for each plane */ - calc_cropping_offsets(offsets, frame, desc); - - /* adjust the offsets to avoid breaking alignment */ - if (!(avctx->flags & AV_CODEC_FLAG_UNALIGNED)) { - int log2_crop_align = frame->crop_left ? ff_ctz(frame->crop_left) : INT_MAX; - int min_log2_align = INT_MAX; - - for (i = 0; frame->data[i]; i++) { - int log2_align = offsets[i] ? ff_ctz(offsets[i]) : INT_MAX; - min_log2_align = FFMIN(log2_align, min_log2_align); - } - - /* we assume, and it should always be true, that the data alignment is - * related to the cropping alignment by a constant power-of-2 factor */ - if (log2_crop_align < min_log2_align) - return AVERROR_BUG; - - if (min_log2_align < 5) { - frame->crop_left &= ~((1 << (5 + log2_crop_align - min_log2_align)) - 1); - calc_cropping_offsets(offsets, frame, desc); - } - } - - for (i = 0; frame->data[i]; i++) - frame->data[i] += offsets[i]; - - frame->width -= (frame->crop_left + frame->crop_right); - frame->height -= (frame->crop_top + frame->crop_bottom); - frame->crop_left = 0; - frame->crop_right = 0; - frame->crop_top = 0; - frame->crop_bottom = 0; - - return 0; + return av_frame_apply_cropping(frame, avctx->flags & AV_CODEC_FLAG_UNALIGNED ? + AV_FRAME_CROP_UNALIGNED : 0); } int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame) diff --git a/libavutil/frame.c b/libavutil/frame.c index 1f2b2356fc10a..85d89b9ed540c 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -782,3 +782,103 @@ const char *av_frame_side_data_name(enum AVFrameSideDataType type) } return NULL; } + +static int calc_cropping_offsets(size_t offsets[4], const AVFrame *frame, + const AVPixFmtDescriptor *desc) +{ + int i, j; + + for (i = 0; frame->data[i]; i++) { + const AVComponentDescriptor *comp = NULL; + int shift_x = (i == 1 || i == 2) ? desc->log2_chroma_w : 0; + int shift_y = (i == 1 || i == 2) ? desc->log2_chroma_h : 0; + + if (desc->flags & (AV_PIX_FMT_FLAG_PAL | AV_PIX_FMT_FLAG_PSEUDOPAL) && i == 1) { + offsets[i] = 0; + break; + } + + /* find any component descriptor for this plane */ + for (j = 0; j < desc->nb_components; j++) { + if (desc->comp[j].plane == i) { + comp = &desc->comp[j]; + break; + } + } + if (!comp) + return AVERROR_BUG; + + offsets[i] = (frame->crop_top >> shift_y) * frame->linesize[i] + + (frame->crop_left >> shift_x) * comp->step; + } + + return 0; +} + +int av_frame_apply_cropping(AVFrame *frame, int flags) +{ + const AVPixFmtDescriptor *desc; + size_t offsets[4]; + int i; + + if (!(frame->width > 0 && frame->height > 0)) + return AVERROR(EINVAL); + + if (frame->crop_left >= INT_MAX - frame->crop_right || + frame->crop_top >= INT_MAX - frame->crop_bottom || + (frame->crop_left + frame->crop_right) >= frame->width || + (frame->crop_top + frame->crop_bottom) >= frame->height) + return AVERROR(ERANGE); + + desc = av_pix_fmt_desc_get(frame->format); + if (!desc) + return AVERROR_BUG; + + /* Apply just the right/bottom cropping for hwaccel formats. Bitstream + * formats cannot be easily handled here either (and corresponding decoders + * should not export any cropping anyway), so do the same for those as well. + * */ + if (desc->flags & (AV_PIX_FMT_FLAG_BITSTREAM | AV_PIX_FMT_FLAG_HWACCEL)) { + frame->width -= frame->crop_right; + frame->height -= frame->crop_bottom; + frame->crop_right = 0; + frame->crop_bottom = 0; + return 0; + } + + /* calculate the offsets for each plane */ + calc_cropping_offsets(offsets, frame, desc); + + /* adjust the offsets to avoid breaking alignment */ + if (!(flags & AV_FRAME_CROP_UNALIGNED)) { + int log2_crop_align = frame->crop_left ? ff_ctz(frame->crop_left) : INT_MAX; + int min_log2_align = INT_MAX; + + for (i = 0; frame->data[i]; i++) { + int log2_align = offsets[i] ? ff_ctz(offsets[i]) : INT_MAX; + min_log2_align = FFMIN(log2_align, min_log2_align); + } + + /* we assume, and it should always be true, that the data alignment is + * related to the cropping alignment by a constant power-of-2 factor */ + if (log2_crop_align < min_log2_align) + return AVERROR_BUG; + + if (min_log2_align < 5) { + frame->crop_left &= ~((1 << (5 + log2_crop_align - min_log2_align)) - 1); + calc_cropping_offsets(offsets, frame, desc); + } + } + + for (i = 0; frame->data[i]; i++) + frame->data[i] += offsets[i]; + + frame->width -= (frame->crop_left + frame->crop_right); + frame->height -= (frame->crop_top + frame->crop_bottom); + frame->crop_left = 0; + frame->crop_right = 0; + frame->crop_top = 0; + frame->crop_bottom = 0; + + return 0; +} diff --git a/libavutil/frame.h b/libavutil/frame.h index 5a987a1dfa103..013043c250c4a 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -773,6 +773,40 @@ AVFrameSideData *av_frame_get_side_data(const AVFrame *frame, */ void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type); + +/** + * Flags for frame cropping. + */ +enum { + /** + * Apply the maximum possible cropping, even if it requires setting the + * AVFrame.data[] entries to unaligned pointers. Passing unaligned data + * to Libav API is generally not allowed, and causes undefined behavior + * (such as crashes). You can pass unaligned data only to Libav APIs that + * are explicitly documented to accept it. Use this flag only if you + * absolutely know what you are doing. + */ + AV_FRAME_CROP_UNALIGNED = 1 << 0, +}; + +/** + * Crop the given video AVFrame according to its crop_left/crop_top/crop_right/ + * crop_bottom fields. If cropping is successful, the function will adjust the + * data pointers and the width/height fields, and set the crop fields to 0. + * + * In all cases, the cropping boundaries will be rounded to the inherent + * alignment of the pixel format. In some cases, such as for opaque hwaccel + * formats, the left/top cropping is ignored. The crop fields are set to 0 even + * if the cropping was rounded or ignored. + * + * @param frame the frame which should be cropped + * @param flags Some combination of AV_FRAME_CROP_* flags, or 0. + * + * @return >= 0 on success, a negative AVERROR on error. If the cropping fields + * were invalid, AVERROR(ERANGE) is returned, and nothing is changed. + */ +int av_frame_apply_cropping(AVFrame *frame, int flags); + /** * @return a string identifying the side data type */ diff --git a/libavutil/version.h b/libavutil/version.h index b1f9e9dd0015f..d70095e95fdff 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -80,7 +80,7 @@ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 70 +#define LIBAVUTIL_VERSION_MINOR 71 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From 463b81de2b252691d75417643597c42684bf830d Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 22 Jul 2017 23:05:14 +0200 Subject: [PATCH 2734/3374] imgutils: add function to clear an image to black Black isn't always just memset(ptr, 0, size). Limited YUV in particular requires relatively non-obvious values, and filling a frame with repeating 0 bytes is disallowed in some contexts. With component sizes larger than 8 or packed YUV, this can become relatively complicated. So having a generic function for this seems helpful. In order to handle the complex cases in a generic way without destroying performance, this code attempts to compute a black pixel, and then uses that value to clear the image data quickly by using a function like memset. Common cases like yuv410p10 or rgba can't be handled with a simple memset, so there is some code to fill memory with 2/4/8 byte patterns. For the remaining cases, a generic slow fallback is used. Signed-off-by: Anton Khirnov Merged from Libav commit 45df7adc1d9b7. --- doc/APIchanges | 3 + libavutil/imgutils.c | 167 +++++++++++++++++++++++++++++++++++++++++++ libavutil/imgutils.h | 27 +++++++ libavutil/version.h | 2 +- 4 files changed, 198 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index cd69ec7bc681c..c82de684ab220 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-08-08 - xxxxxxx - lavu 55.72.100 - imgutils.h + Add av_image_fill_black(). + 2017-08-08 - xxxxxxx - lavu 55.71.100 - frame.h Add av_frame_apply_cropping(). diff --git a/libavutil/imgutils.c b/libavutil/imgutils.c index f8f2244b89ddd..4de0fa0c3942c 100644 --- a/libavutil/imgutils.c +++ b/libavutil/imgutils.c @@ -491,3 +491,170 @@ int av_image_copy_to_buffer(uint8_t *dst, int dst_size, return size; } + +// Fill dst[0..dst_size] with the bytes in clear[0..clear_size]. The clear +// bytes are repeated until dst_size is reached. If dst_size is unaligned (i.e. +// dst_size%clear_size!=0), the remaining data will be filled with the beginning +// of the clear data only. +static void memset_bytes(uint8_t *dst, size_t dst_size, uint8_t *clear, + size_t clear_size) +{ + size_t pos = 0; + int same = 1; + int i; + + if (!clear_size) + return; + + // Reduce to memset() if possible. + for (i = 0; i < clear_size; i++) { + if (clear[i] != clear[0]) { + same = 0; + break; + } + } + if (same) + clear_size = 1; + + if (clear_size == 1) { + memset(dst, clear[0], dst_size); + dst_size = 0; + } else if (clear_size == 2) { + uint16_t val = AV_RN16(clear); + for (; dst_size >= 2; dst_size -= 2) { + AV_WN16(dst, val); + dst += 2; + } + } else if (clear_size == 4) { + uint32_t val = AV_RN32(clear); + for (; dst_size >= 4; dst_size -= 4) { + AV_WN32(dst, val); + dst += 4; + } + } else if (clear_size == 8) { + uint32_t val = AV_RN64(clear); + for (; dst_size >= 8; dst_size -= 8) { + AV_WN64(dst, val); + dst += 8; + } + } + + for (; dst_size; dst_size--) + *dst++ = clear[pos++ % clear_size]; +} + +// Maximum size in bytes of a plane element (usually a pixel, or multiple pixels +// if it's a subsampled packed format). +#define MAX_BLOCK_SIZE 32 + +int av_image_fill_black(uint8_t *dst_data[4], const ptrdiff_t dst_linesize[4], + enum AVPixelFormat pix_fmt, enum AVColorRange range, + int width, int height) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + int nb_planes = av_pix_fmt_count_planes(pix_fmt); + // A pixel or a group of pixels on each plane, with a value that represents black. + // Consider e.g. AV_PIX_FMT_UYVY422 for non-trivial cases. + uint8_t clear_block[4][MAX_BLOCK_SIZE] = {0}; // clear padding with 0 + int clear_block_size[4] = {0}; + ptrdiff_t plane_line_bytes[4] = {0}; + int rgb, limited; + int plane, c; + + if (!desc || nb_planes < 1 || nb_planes > 4 || desc->flags & AV_PIX_FMT_FLAG_HWACCEL) + return AVERROR(EINVAL); + + rgb = !!(desc->flags & AV_PIX_FMT_FLAG_RGB); + limited = !rgb && range != AVCOL_RANGE_JPEG; + + if (desc->flags & AV_PIX_FMT_FLAG_BITSTREAM) { + ptrdiff_t bytewidth = av_image_get_linesize(pix_fmt, width, 0); + uint8_t *data; + int mono = pix_fmt == AV_PIX_FMT_MONOWHITE || pix_fmt == AV_PIX_FMT_MONOBLACK; + int fill = pix_fmt == AV_PIX_FMT_MONOWHITE ? 0xFF : 0; + if (nb_planes != 1 || !(rgb || mono) || bytewidth < 1) + return AVERROR(EINVAL); + + if (!dst_data) + return 0; + + data = dst_data[0]; + + // (Bitstream + alpha will be handled incorrectly - it'll remain transparent.) + for (;height > 0; height--) { + memset(data, fill, bytewidth); + data += dst_linesize[0]; + } + return 0; + } + + for (c = 0; c < desc->nb_components; c++) { + const AVComponentDescriptor comp = desc->comp[c]; + + // We try to operate on entire non-subsampled pixel groups (for + // AV_PIX_FMT_UYVY422 this would mean two consecutive pixels). + clear_block_size[comp.plane] = FFMAX(clear_block_size[comp.plane], comp.step); + + if (clear_block_size[comp.plane] > MAX_BLOCK_SIZE) + return AVERROR(EINVAL); + } + + // Create a byte array for clearing 1 pixel (sometimes several pixels). + for (c = 0; c < desc->nb_components; c++) { + const AVComponentDescriptor comp = desc->comp[c]; + // (Multiple pixels happen e.g. with AV_PIX_FMT_UYVY422.) + int w = clear_block_size[comp.plane] / comp.step; + uint8_t *c_data[4]; + const int c_linesize[4] = {0}; + uint16_t src_array[MAX_BLOCK_SIZE]; + uint16_t src = 0; + int x; + + if (comp.depth > 16) + return AVERROR(EINVAL); + if (!rgb && comp.depth < 8) + return AVERROR(EINVAL); + if (w < 1) + return AVERROR(EINVAL); + + if (c == 0 && limited) { + src = 16 << (comp.depth - 8); + } else if ((c == 1 || c == 2) && !rgb) { + src = 128 << (comp.depth - 8); + } else if (c == 3) { + // (Assume even limited YUV uses full range alpha.) + src = (1 << comp.depth) - 1; + } + + for (x = 0; x < w; x++) + src_array[x] = src; + + for (x = 0; x < 4; x++) + c_data[x] = &clear_block[x][0]; + + av_write_image_line(src_array, c_data, c_linesize, desc, 0, 0, c, w); + } + + for (plane = 0; plane < nb_planes; plane++) { + plane_line_bytes[plane] = av_image_get_linesize(pix_fmt, width, plane); + if (plane_line_bytes[plane] < 0) + return AVERROR(EINVAL); + } + + if (!dst_data) + return 0; + + for (plane = 0; plane < nb_planes; plane++) { + size_t bytewidth = plane_line_bytes[plane]; + uint8_t *data = dst_data[plane]; + int chroma_div = plane == 1 || plane == 2 ? desc->log2_chroma_h : 0; + int plane_h = ((height + ( 1 << chroma_div) - 1)) >> chroma_div; + + for (; plane_h > 0; plane_h--) { + memset_bytes(data, bytewidth, &clear_block[plane][0], clear_block_size[plane]); + data += dst_linesize[plane]; + } + } + + return 0; +} diff --git a/libavutil/imgutils.h b/libavutil/imgutils.h index ea083b10f11e3..2ab90ac0339eb 100644 --- a/libavutil/imgutils.h +++ b/libavutil/imgutils.h @@ -238,6 +238,33 @@ int av_image_check_size2(unsigned int w, unsigned int h, int64_t max_pixels, enu */ int av_image_check_sar(unsigned int w, unsigned int h, AVRational sar); +/** + * Overwrite the image data with black. This is suitable for filling a + * sub-rectangle of an image, meaning the padding between the right most pixel + * and the left most pixel on the next line will not be overwritten. For some + * formats, the image size might be rounded up due to inherent alignment. + * + * If the pixel format has alpha, the alpha is cleared to opaque. + * + * This can return an error if the pixel format is not supported. Normally, all + * non-hwaccel pixel formats should be supported. + * + * Passing NULL for dst_data is allowed. Then the function returns whether the + * operation would have succeeded. (It can return an error if the pix_fmt is + * not supported.) + * + * @param dst_data data pointers to destination image + * @param dst_linesize linesizes for the destination image + * @param pix_fmt the pixel format of the image + * @param range the color range of the image (important for colorspaces such as YUV) + * @param width the width of the image in pixels + * @param height the height of the image in pixels + * @return 0 if the image data was cleared, a negative AVERROR code otherwise + */ +int av_image_fill_black(uint8_t *dst_data[4], const ptrdiff_t dst_linesize[4], + enum AVPixelFormat pix_fmt, enum AVColorRange range, + int width, int height); + /** * @} */ diff --git a/libavutil/version.h b/libavutil/version.h index d70095e95fdff..111b581a81745 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -80,7 +80,7 @@ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 71 +#define LIBAVUTIL_VERSION_MINOR 72 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From 41096904d03611de8024a8dbebb6935d643c3d6b Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Tue, 8 Aug 2017 18:45:32 +0200 Subject: [PATCH 2735/3374] avfilter/vf_separatefields: stop leaking last frame This can happen when filtering is ended without receiving EOF. --- libavfilter/vf_separatefields.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libavfilter/vf_separatefields.c b/libavfilter/vf_separatefields.c index 69653c991f39e..3ed222f271b55 100644 --- a/libavfilter/vf_separatefields.c +++ b/libavfilter/vf_separatefields.c @@ -118,6 +118,13 @@ static int request_frame(AVFilterLink *outlink) return ret; } +static av_cold void uninit(AVFilterContext *ctx) +{ + SeparateFieldsContext *s = ctx->priv; + + av_frame_free(&s->second); +} + static const AVFilterPad separatefields_inputs[] = { { .name = "default", @@ -141,6 +148,7 @@ AVFilter ff_vf_separatefields = { .name = "separatefields", .description = NULL_IF_CONFIG_SMALL("Split input video frames into fields."), .priv_size = sizeof(SeparateFieldsContext), + .uninit = uninit, .inputs = separatefields_inputs, .outputs = separatefields_outputs, }; From a5380f9c1c460acccb2edaa8609e4a57c0456088 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 6 Aug 2017 05:01:45 +0200 Subject: [PATCH 2736/3374] avcodec/dirac_dwt: Fixes integer overflows in COMPOSE_DAUB97* Fix multiple: runtime error: signed integer overflow: 6497 * 3409630 cannot be represented in type 'int' Fixes: 2819/clusterfuzz-testcase-minimized-4743700301217792 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/dirac_dwt.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/dirac_dwt.h b/libavcodec/dirac_dwt.h index 62f8472b41bdd..e715e53bc4292 100644 --- a/libavcodec/dirac_dwt.h +++ b/libavcodec/dirac_dwt.h @@ -117,16 +117,16 @@ void ff_spatial_idwt_slice2(DWTContext *d, int y); (b4 + ((-2*(b0+b8) + 10*(b1+b7) - 25*(b2+b6) + 81*(b3+b5) + 128) >> 8)) #define COMPOSE_DAUB97iL1(b0, b1, b2)\ - (b1 - ((1817*(b0 + b2) + 2048) >> 12)) + (b1 - ((int)(1817U*(b0 + b2) + 2048) >> 12)) #define COMPOSE_DAUB97iH1(b0, b1, b2)\ - (b1 - (( 113*(b0 + b2) + 64) >> 7)) + (b1 - ((int)( 113U*(b0 + b2) + 64) >> 7)) #define COMPOSE_DAUB97iL0(b0, b1, b2)\ - (b1 + (( 217*(b0 + b2) + 2048) >> 12)) + (b1 + ((int)( 217U*(b0 + b2) + 2048) >> 12)) #define COMPOSE_DAUB97iH0(b0, b1, b2)\ - (b1 + ((6497*(b0 + b2) + 2048) >> 12)) + (b1 + ((int)(6497U*(b0 + b2) + 2048) >> 12)) #endif /* AVCODEC_DWT_H */ From fea7bc9e7b9aea85c404cee58246f8e98e618bbf Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 7 Aug 2017 01:20:55 +0200 Subject: [PATCH 2737/3374] avcodec/dvenc: Support adjusting the quantizer deadzone Signed-off-by: Michael Niedermayer --- libavcodec/dv.h | 3 +++ libavcodec/dvenc.c | 24 +++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/libavcodec/dv.h b/libavcodec/dv.h index 6350a16dfff30..0e97bb200ea68 100644 --- a/libavcodec/dv.h +++ b/libavcodec/dv.h @@ -38,6 +38,7 @@ typedef struct DVwork_chunk { } DVwork_chunk; typedef struct DVVideoContext { + AVClass *avclass; const AVDVProfile *sys; const AVFrame *frame; AVCodecContext *avctx; @@ -51,6 +52,8 @@ typedef struct DVVideoContext { me_cmp_func ildct_cmp; DVwork_chunk work_chunks[4 * 12 * 27]; uint32_t idct_factor[2 * 4 * 16 * 64]; + + int quant_deadzone; } DVVideoContext; enum dv_section_type { diff --git a/libavcodec/dvenc.c b/libavcodec/dvenc.c index e3de18a510502..8474498ee6a2a 100644 --- a/libavcodec/dvenc.c +++ b/libavcodec/dvenc.c @@ -17,6 +17,8 @@ * 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 + * + * quant_deadzone code and fixes sponsored by NOA GmbH */ /** @@ -28,6 +30,7 @@ #include "libavutil/attributes.h" #include "libavutil/internal.h" +#include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "avcodec.h" @@ -265,6 +268,8 @@ static av_always_inline int dv_init_enc_block(EncBlockInfo *bi, uint8_t *data, #endif int max = classes[0]; int prev = 0; + const unsigned deadzone = s->quant_deadzone; + const unsigned threshold = 2 * deadzone; av_assert2((((int) blk) & 15) == 0); @@ -297,13 +302,15 @@ static av_always_inline int dv_init_enc_block(EncBlockInfo *bi, uint8_t *data, for (i = mb_area_start[area]; i < mb_area_start[area + 1]; i++) { int level = blk[zigzag_scan[i]]; - if (level + 15 > 30U) { + if (level + deadzone > threshold) { bi->sign[i] = (level >> 31) & 1; /* Weight it and shift down into range, adding for rounding. * The extra division by a factor of 2^4 reverses the 8x * expansion of the DCT AND the 2x doubling of the weights. */ level = (FFABS(level) * weight[i] + (1 << (dv_weight_bits + 3))) >> (dv_weight_bits + 4); + if (!level) + continue; bi->mb[i] = level; if (level > max) max = level; @@ -746,6 +753,20 @@ FF_ENABLE_DEPRECATION_WARNINGS return 0; } +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM +#define OFFSET(x) offsetof(DVVideoContext, x) +static const AVOption dv_options[] = { + { "quant_deadzone", "Quantizer dead zone", OFFSET(quant_deadzone), AV_OPT_TYPE_INT, { .i64 = 15 }, 0, 1024, VE }, + { NULL }, +}; + +static const AVClass dvvideo_encode_class = { + .class_name = "dvvideo encoder", + .item_name = av_default_item_name, + .option = dv_options, + .version = LIBAVUTIL_VERSION_INT, +}; + AVCodec ff_dvvideo_encoder = { .name = "dvvideo", .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"), @@ -759,4 +780,5 @@ AVCodec ff_dvvideo_encoder = { AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, + .priv_class = &dvvideo_encode_class, }; From abaeeb3ce08d49af4127fb14d63ae3ffb11073d8 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 7 Aug 2017 01:20:56 +0200 Subject: [PATCH 2738/3374] avcodec/dvenc: Change quantizer dead zone default to 7 This improves the quality and reduces the "blocking" in flat areas Signed-off-by: Michael Niedermayer --- libavcodec/dvenc.c | 2 +- tests/ref/lavf/dv_fmt | 12 ++++++------ tests/ref/vsynth/vsynth1-dv | 4 ++-- tests/ref/vsynth/vsynth1-dv-411 | 6 +++--- tests/ref/vsynth/vsynth1-dv-50 | 6 +++--- tests/ref/vsynth/vsynth2-dv | 6 +++--- tests/ref/vsynth/vsynth2-dv-411 | 6 +++--- tests/ref/vsynth/vsynth2-dv-50 | 6 +++--- tests/ref/vsynth/vsynth_lena-dv | 6 +++--- tests/ref/vsynth/vsynth_lena-dv-411 | 6 +++--- tests/ref/vsynth/vsynth_lena-dv-50 | 6 +++--- 11 files changed, 33 insertions(+), 33 deletions(-) diff --git a/libavcodec/dvenc.c b/libavcodec/dvenc.c index 8474498ee6a2a..ce2fc75daa184 100644 --- a/libavcodec/dvenc.c +++ b/libavcodec/dvenc.c @@ -756,7 +756,7 @@ FF_ENABLE_DEPRECATION_WARNINGS #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM #define OFFSET(x) offsetof(DVVideoContext, x) static const AVOption dv_options[] = { - { "quant_deadzone", "Quantizer dead zone", OFFSET(quant_deadzone), AV_OPT_TYPE_INT, { .i64 = 15 }, 0, 1024, VE }, + { "quant_deadzone", "Quantizer dead zone", OFFSET(quant_deadzone), AV_OPT_TYPE_INT, { .i64 = 7 }, 0, 1024, VE }, { NULL }, }; diff --git a/tests/ref/lavf/dv_fmt b/tests/ref/lavf/dv_fmt index dac43b68a1d33..0263202c8e88d 100644 --- a/tests/ref/lavf/dv_fmt +++ b/tests/ref/lavf/dv_fmt @@ -1,9 +1,9 @@ -5a622e1ae4fd16bec59cd514380d7882 *./tests/data/lavf/lavf.dv +7830f9c6716ceb6011f865f1e521b951 *./tests/data/lavf/lavf.dv 3600000 ./tests/data/lavf/lavf.dv -./tests/data/lavf/lavf.dv CRC=0x0a6edbd8 -155e8fd4ea1196edd56ae9ff09edcf85 *./tests/data/lavf/lavf.dv +./tests/data/lavf/lavf.dv CRC=0xd428d3ee +5569626370c7c72d40de2c4559e32856 *./tests/data/lavf/lavf.dv 3480000 ./tests/data/lavf/lavf.dv -./tests/data/lavf/lavf.dv CRC=0x3e5583fa -87d3b20f656235671383a7eaa2f66330 *./tests/data/lavf/lavf.dv +./tests/data/lavf/lavf.dv CRC=0xa0088163 +2fb332aab8f2ba9c33b1b2368194392a *./tests/data/lavf/lavf.dv 3600000 ./tests/data/lavf/lavf.dv -./tests/data/lavf/lavf.dv CRC=0xf3e6873c +./tests/data/lavf/lavf.dv CRC=0xbdaf7f52 diff --git a/tests/ref/vsynth/vsynth1-dv b/tests/ref/vsynth/vsynth1-dv index 6237b078c5a01..ea357b7723418 100644 --- a/tests/ref/vsynth/vsynth1-dv +++ b/tests/ref/vsynth/vsynth1-dv @@ -1,4 +1,4 @@ -4d572f758b55a1756adf9f54132f3b9e *tests/data/fate/vsynth1-dv.dv +4246668d61439617101d051d7a995108 *tests/data/fate/vsynth1-dv.dv 7200000 tests/data/fate/vsynth1-dv.dv -1cda5a62c3a2f17cc7d5b4cddccf2524 *tests/data/fate/vsynth1-dv.out.rawvideo +d52e7a9eac459ade9561d0b89bba58e7 *tests/data/fate/vsynth1-dv.out.rawvideo stddev: 6.90 PSNR: 31.34 MAXDIFF: 76 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth1-dv-411 b/tests/ref/vsynth/vsynth1-dv-411 index 48e01a140341a..ec88d67ece039 100644 --- a/tests/ref/vsynth/vsynth1-dv-411 +++ b/tests/ref/vsynth/vsynth1-dv-411 @@ -1,4 +1,4 @@ -f179899efba432c6f01149c36c709092 *tests/data/fate/vsynth1-dv-411.dv +df067afe65f1712d9e8efa7117aab6ea *tests/data/fate/vsynth1-dv-411.dv 7200000 tests/data/fate/vsynth1-dv-411.dv -48904744fabbbc3421a762f615ef6456 *tests/data/fate/vsynth1-dv-411.out.rawvideo -stddev: 9.44 PSNR: 28.62 MAXDIFF: 84 bytes: 7603200/ 7603200 +ed493bad827dc903188fce8d3b597fcb *tests/data/fate/vsynth1-dv-411.out.rawvideo +stddev: 9.45 PSNR: 28.62 MAXDIFF: 84 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth1-dv-50 b/tests/ref/vsynth/vsynth1-dv-50 index d5da88d78c0b1..4a2ff001104f6 100644 --- a/tests/ref/vsynth/vsynth1-dv-50 +++ b/tests/ref/vsynth/vsynth1-dv-50 @@ -1,4 +1,4 @@ -a193c5f92bf6e74c604e759d5f4f0f94 *tests/data/fate/vsynth1-dv-50.dv +adb1df1a65cecab225677003a5de9f28 *tests/data/fate/vsynth1-dv-50.dv 14400000 tests/data/fate/vsynth1-dv-50.dv -41c4df5f2d876fcd5245643b9ded6711 *tests/data/fate/vsynth1-dv-50.out.rawvideo -stddev: 1.72 PSNR: 43.38 MAXDIFF: 29 bytes: 7603200/ 7603200 +4ab1f5b7aad15fab9e3c1ea5b96da39b *tests/data/fate/vsynth1-dv-50.out.rawvideo +stddev: 1.72 PSNR: 43.37 MAXDIFF: 29 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-dv b/tests/ref/vsynth/vsynth2-dv index bb0602a70f4a3..3127b5628855d 100644 --- a/tests/ref/vsynth/vsynth2-dv +++ b/tests/ref/vsynth/vsynth2-dv @@ -1,4 +1,4 @@ -9002a5769a7744a4b8d24b01787abc3b *tests/data/fate/vsynth2-dv.dv +6a059698f1f619312dd91504697cca98 *tests/data/fate/vsynth2-dv.dv 7200000 tests/data/fate/vsynth2-dv.dv -22a62dc9108c4a8b1a3c708e5d383748 *tests/data/fate/vsynth2-dv.out.rawvideo -stddev: 1.99 PSNR: 42.12 MAXDIFF: 38 bytes: 7603200/ 7603200 +528fd407b6d19f5fe3b3446a3080d148 *tests/data/fate/vsynth2-dv.out.rawvideo +stddev: 1.99 PSNR: 42.13 MAXDIFF: 38 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-dv-411 b/tests/ref/vsynth/vsynth2-dv-411 index bdda6367bc36b..3cee4de303623 100644 --- a/tests/ref/vsynth/vsynth2-dv-411 +++ b/tests/ref/vsynth/vsynth2-dv-411 @@ -1,4 +1,4 @@ -701dac8c1d3fe69957eab7ba8d5ecb25 *tests/data/fate/vsynth2-dv-411.dv +a4afd3c595b4242fb5f1329c82a0b0c2 *tests/data/fate/vsynth2-dv-411.dv 7200000 tests/data/fate/vsynth2-dv-411.dv -bf821931bb81f4e92dc38f86d8187300 *tests/data/fate/vsynth2-dv-411.out.rawvideo -stddev: 3.48 PSNR: 37.28 MAXDIFF: 56 bytes: 7603200/ 7603200 +1ef9bd89b72a942c02571f32af03bb04 *tests/data/fate/vsynth2-dv-411.out.rawvideo +stddev: 3.48 PSNR: 37.29 MAXDIFF: 56 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-dv-50 b/tests/ref/vsynth/vsynth2-dv-50 index c21c525df4cea..707fd5c734e67 100644 --- a/tests/ref/vsynth/vsynth2-dv-50 +++ b/tests/ref/vsynth/vsynth2-dv-50 @@ -1,4 +1,4 @@ -9b9ebdf35911dad62203dfdf1f56754e *tests/data/fate/vsynth2-dv-50.dv +8774632954e780697c472d945c597daf *tests/data/fate/vsynth2-dv-50.dv 14400000 tests/data/fate/vsynth2-dv-50.dv -b4d324b2095bc919ad16891891d40b36 *tests/data/fate/vsynth2-dv-50.out.rawvideo -stddev: 0.88 PSNR: 49.20 MAXDIFF: 17 bytes: 7603200/ 7603200 +11167de05c205f974d462f91f56eb837 *tests/data/fate/vsynth2-dv-50.out.rawvideo +stddev: 0.86 PSNR: 49.43 MAXDIFF: 17 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth_lena-dv b/tests/ref/vsynth/vsynth_lena-dv index ad0549f6e64db..a8041f36a5c4c 100644 --- a/tests/ref/vsynth/vsynth_lena-dv +++ b/tests/ref/vsynth/vsynth_lena-dv @@ -1,4 +1,4 @@ -85b8d55b0b68bb3fc2e90babb580f9b7 *tests/data/fate/vsynth_lena-dv.dv +ab03241e988dcd5bd36a76b25372343f *tests/data/fate/vsynth_lena-dv.dv 7200000 tests/data/fate/vsynth_lena-dv.dv -7dac420637360b031ccae7c5a69c5e0c *tests/data/fate/vsynth_lena-dv.out.rawvideo -stddev: 1.70 PSNR: 43.47 MAXDIFF: 33 bytes: 7603200/ 7603200 +6e4b90be39ad408ddc1c0dc4ced40bf0 *tests/data/fate/vsynth_lena-dv.out.rawvideo +stddev: 1.69 PSNR: 43.54 MAXDIFF: 33 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth_lena-dv-411 b/tests/ref/vsynth/vsynth_lena-dv-411 index 736a35da5696e..164dd359b2f2f 100644 --- a/tests/ref/vsynth/vsynth_lena-dv-411 +++ b/tests/ref/vsynth/vsynth_lena-dv-411 @@ -1,4 +1,4 @@ -e428508f400327aeb96969c08fb9e1b5 *tests/data/fate/vsynth_lena-dv-411.dv +1a7f091993eb6fe5b6f9d927ba60387d *tests/data/fate/vsynth_lena-dv-411.dv 7200000 tests/data/fate/vsynth_lena-dv-411.dv -713ed907fde448c603d6e9aee5efedd1 *tests/data/fate/vsynth_lena-dv-411.out.rawvideo -stddev: 2.89 PSNR: 38.91 MAXDIFF: 45 bytes: 7603200/ 7603200 +e5624f3d4de96e514ac9b96c2b4b447c *tests/data/fate/vsynth_lena-dv-411.out.rawvideo +stddev: 2.87 PSNR: 38.97 MAXDIFF: 45 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth_lena-dv-50 b/tests/ref/vsynth/vsynth_lena-dv-50 index adee628b67fe1..2149fd553c09f 100644 --- a/tests/ref/vsynth/vsynth_lena-dv-50 +++ b/tests/ref/vsynth/vsynth_lena-dv-50 @@ -1,4 +1,4 @@ -0032a07167199e6f49e07fa7ed4d5f62 *tests/data/fate/vsynth_lena-dv-50.dv +c678b291e58a277725aa4557387efc58 *tests/data/fate/vsynth_lena-dv-50.dv 14400000 tests/data/fate/vsynth_lena-dv-50.dv -56c77e537291536b242857d1056de30c *tests/data/fate/vsynth_lena-dv-50.out.rawvideo -stddev: 0.82 PSNR: 49.82 MAXDIFF: 12 bytes: 7603200/ 7603200 +bda4f98f387f82986e521b78a9bc1eef *tests/data/fate/vsynth_lena-dv-50.out.rawvideo +stddev: 0.78 PSNR: 50.28 MAXDIFF: 12 bytes: 7603200/ 7603200 From 448c88e1a586adc350e5a07c18c0be6706101deb Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 8 Aug 2017 22:42:21 +0000 Subject: [PATCH 2739/3374] avfilter/dynaudnorm: increment input outside of the FFMIN macro so it doesn't get double incremented --- libavfilter/af_dynaudnorm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavfilter/af_dynaudnorm.c b/libavfilter/af_dynaudnorm.c index d4ebd96590591..5919304267768 100644 --- a/libavfilter/af_dynaudnorm.c +++ b/libavfilter/af_dynaudnorm.c @@ -460,7 +460,8 @@ static void update_gain_history(DynamicAudioNormalizerContext *s, int channel, int input = pre_fill_size; while (cqueue_size(s->gain_history_minimum[channel]) < pre_fill_size) { - initial_value = FFMIN(initial_value, cqueue_peek(s->gain_history_original[channel], ++input)); + input++; + initial_value = FFMIN(initial_value, cqueue_peek(s->gain_history_original[channel], input)); cqueue_enqueue(s->gain_history_minimum[channel], initial_value); } } From df884e038f5dc95f55ef07500b5b99b722835f8a Mon Sep 17 00:00:00 2001 From: Nicolas Sugino Date: Wed, 26 Jul 2017 15:29:02 -0300 Subject: [PATCH 2740/3374] avcodec/aacdec: Fix PCE channel_layout verification Signed-off-by: Michael Niedermayer --- libavcodec/aacdec_template.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/aacdec_template.c b/libavcodec/aacdec_template.c index 90cc1437819a1..a539f74e6f36d 100644 --- a/libavcodec/aacdec_template.c +++ b/libavcodec/aacdec_template.c @@ -763,7 +763,7 @@ static int decode_pce(AVCodecContext *avctx, MPEG4AudioConfig *m4ac, if (get_bits1(gb)) skip_bits(gb, 3); // mixdown_coeff_index and pseudo_surround - if (get_bits_left(gb) < 4 * (num_front + num_side + num_back + num_lfe + num_assoc_data + num_cc)) { + if (get_bits_left(gb) < 5 * (num_front + num_side + num_back + num_cc) + 4 *(num_lfe + num_assoc_data + num_cc)) { av_log(avctx, AV_LOG_ERROR, "decode_pce: " overread_err); return -1; } From e7e1fbc49bf64e1a1d19e2a469dd1962d4bdb770 Mon Sep 17 00:00:00 2001 From: Sasi Inguva Date: Tue, 8 Aug 2017 17:00:19 -0700 Subject: [PATCH 2741/3374] lavf/movenc.c: Set sgpd and sbgp atoms to represent decoder delay for AAC. According to https://developer.apple.com/library/content/documentation/QuickTime/QTFF/QTFFAppenG/QTFFAppenG.html and ISO-IEC-14496-12 Section 10.1.1.1 and 10.1.1.3 Signed-off-by: Sasi Inguva Reviewed-by: Derek Buitenhuis Signed-off-by: Michael Niedermayer --- libavformat/movenc.c | 22 +++++++++++++++------- tests/ref/fate/adtstoasc_ticket3715 | 4 ++-- tests/ref/fate/copy-psp | 4 ++-- tests/ref/fate/movenc | 12 ++++++------ 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 0e5b45d150cd2..5c53ab24e0ad4 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -2208,14 +2208,16 @@ static int mov_preroll_write_stbl_atoms(AVIOContext *pb, MOVTrack *track) (AVRational){1, 1000}, (AVRational){1, 48000}); - if (track->entry) { - sgpd_entries = av_malloc_array(track->entry, sizeof(*sgpd_entries)); - if (!sgpd_entries) - return AVERROR(ENOMEM); - } + if (!track->entry) + return 0; - av_assert0(track->par->codec_id == AV_CODEC_ID_OPUS); + sgpd_entries = av_malloc_array(track->entry, sizeof(*sgpd_entries)); + if (!sgpd_entries) + return AVERROR(ENOMEM); + av_assert0(track->par->codec_id == AV_CODEC_ID_OPUS || track->par->codec_id == AV_CODEC_ID_AAC); + + if (track->par->codec_id == AV_CODEC_ID_OPUS) { for (i = 0; i < track->entry; i++) { int roll_samples_remaining = roll_samples; int distance = 0; @@ -2242,6 +2244,12 @@ static int mov_preroll_write_stbl_atoms(AVIOContext *pb, MOVTrack *track) sgpd_entries[entries].group_description_index = distance ? ++group : 0; } } + } else { + entries++; + sgpd_entries[entries].count = track->sample_count; + sgpd_entries[entries].roll_distance = 1; + sgpd_entries[entries].group_description_index = ++group; + } entries++; if (!group) { @@ -2304,7 +2312,7 @@ static int mov_write_stbl_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext if (track->cenc.aes_ctr) { ff_mov_cenc_write_stbl_atoms(&track->cenc, pb); } - if (track->par->codec_id == AV_CODEC_ID_OPUS) { + if (track->par->codec_id == AV_CODEC_ID_OPUS || track->par->codec_id == AV_CODEC_ID_AAC) { mov_preroll_write_stbl_atoms(pb, track); } return update_size(pb, pos); diff --git a/tests/ref/fate/adtstoasc_ticket3715 b/tests/ref/fate/adtstoasc_ticket3715 index 949b565c2fa73..96795a2ca3928 100644 --- a/tests/ref/fate/adtstoasc_ticket3715 +++ b/tests/ref/fate/adtstoasc_ticket3715 @@ -1,5 +1,5 @@ -ef8ce3cbd1d86113e7c991a816086068 *tests/data/fate/adtstoasc_ticket3715.mov -33270 tests/data/fate/adtstoasc_ticket3715.mov +0221e04333e6ac432fa42960502f0d5a *tests/data/fate/adtstoasc_ticket3715.mov +33324 tests/data/fate/adtstoasc_ticket3715.mov #extradata 0: 2, 0x00340022 #tb 0: 1/44100 #media_type 0: audio diff --git a/tests/ref/fate/copy-psp b/tests/ref/fate/copy-psp index 6603d3ff266f2..81eb172549d09 100644 --- a/tests/ref/fate/copy-psp +++ b/tests/ref/fate/copy-psp @@ -1,5 +1,5 @@ -6889223644fc560069c8591984175a62 *tests/data/fate/copy-psp.psp -2041379 tests/data/fate/copy-psp.psp +cada61453a2483ef8ba1fb82c8bbff25 *tests/data/fate/copy-psp.psp +2041433 tests/data/fate/copy-psp.psp #extradata 0: 51, 0xaf6d1012 #extradata 1: 2, 0x00b200a1 #tb 0: 1/90000 diff --git a/tests/ref/fate/movenc b/tests/ref/fate/movenc index 09e603aeb7402..47bcf9d515c71 100644 --- a/tests/ref/fate/movenc +++ b/tests/ref/fate/movenc @@ -1,18 +1,18 @@ write_data len 36, time nopts, type header atom ftyp -write_data len 2335, time nopts, type header atom - +write_data len 2389, time nopts, type header atom - write_data len 788, time 1000000, type sync atom moof write_data len 110, time nopts, type trailer atom - -214242e9c7c93171d2f47f5b47776559 3269 non-empty-moov +17a37691eba8b858cf15e60aa9a7dbf7 3323 non-empty-moov write_data len 36, time nopts, type header atom ftyp -write_data len 2667, time nopts, type header atom - +write_data len 2721, time nopts, type header atom - write_data len 908, time 966667, type sync atom moof write_data len 110, time nopts, type trailer atom - -44467d568a3cc38d414fd8ed4b2a968f 3721 non-empty-moov-elst +0026ffe059c06c592021f972bf2c5e79 3775 non-empty-moov-elst write_data len 36, time nopts, type header atom ftyp -write_data len 2575, time nopts, type header atom - +write_data len 2629, time nopts, type header atom - write_data len 908, time 1000000, type sync atom moof write_data len 110, time nopts, type trailer atom - -de22b98a3885f9b4b83cdd48ff46aeb9 3629 non-empty-moov-no-elst +c184e168ac1e5bb3d9c70e580ab6179c 3683 non-empty-moov-no-elst write_data len 20, time nopts, type header atom ftyp write_data len 1171, time nopts, type header atom - write_data len 728, time 0, type sync atom moof From c100330a8ff4deef2a4994a9e55d387a00ea3cff Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 9 Aug 2017 23:15:38 -0300 Subject: [PATCH 2742/3374] avformat/movenc: reindent after the previous commit --- libavformat/movenc.c | 50 ++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 5c53ab24e0ad4..10b959ad02321 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -2218,32 +2218,32 @@ static int mov_preroll_write_stbl_atoms(AVIOContext *pb, MOVTrack *track) av_assert0(track->par->codec_id == AV_CODEC_ID_OPUS || track->par->codec_id == AV_CODEC_ID_AAC); if (track->par->codec_id == AV_CODEC_ID_OPUS) { - for (i = 0; i < track->entry; i++) { - int roll_samples_remaining = roll_samples; - int distance = 0; - for (j = i - 1; j >= 0; j--) { - roll_samples_remaining -= get_cluster_duration(track, j); - distance++; - if (roll_samples_remaining <= 0) - break; - } - /* We don't have enough preceeding samples to compute a valid - roll_distance here, so this sample can't be independently - 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)); - if (i && distance == sgpd_entries[entries].roll_distance) { - sgpd_entries[entries].count++; - } else { - entries++; - sgpd_entries[entries].count = 1; - sgpd_entries[entries].roll_distance = distance; - sgpd_entries[entries].group_description_index = distance ? ++group : 0; + for (i = 0; i < track->entry; i++) { + int roll_samples_remaining = roll_samples; + int distance = 0; + for (j = i - 1; j >= 0; j--) { + roll_samples_remaining -= get_cluster_duration(track, j); + distance++; + if (roll_samples_remaining <= 0) + break; + } + /* We don't have enough preceeding samples to compute a valid + roll_distance here, so this sample can't be independently + 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)); + if (i && distance == sgpd_entries[entries].roll_distance) { + sgpd_entries[entries].count++; + } else { + entries++; + sgpd_entries[entries].count = 1; + sgpd_entries[entries].roll_distance = distance; + sgpd_entries[entries].group_description_index = distance ? ++group : 0; + } } - } } else { entries++; sgpd_entries[entries].count = track->sample_count; From 9042402ec78ad050eb7ad129610450ef90371df4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 4 Jul 2017 20:03:00 +0300 Subject: [PATCH 2743/3374] d3d11va: Check WINAPI_FAMILY instead of HAVE_LOADLIBRARY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If using the winstore compat library, a fallback LoadLibrary function does exist, that only calls LoadPackagedLibrary though (which doesn't work for dynamically loading d3d11 DLLs). Therefore explicitly check the targeted API family instead. Make this check a reusable HAVE_* component which other parts of the libraries can check when necessary as well. Signed-off-by: Martin Storsjö Merged from Libav commit 4d330da006fe48178. --- configure | 14 +++++++++++++- libavutil/hwcontext_d3d11va.c | 6 +++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/configure b/configure index 66c7b948e4cdb..7201941c36e59 100755 --- a/configure +++ b/configure @@ -2072,6 +2072,7 @@ HAVE_LIST=" sndio texi2html threads + uwp vaapi_drm vaapi_x11 vdpau_x11 @@ -6134,7 +6135,18 @@ check_func_headers "windows.h" CreateDIBSection "$gdigrab_indev_extralibs" # d3d11va requires linking directly to dxgi and d3d11 if not building for # the desktop api partition -enabled LoadLibrary || d3d11va_extralibs="-ldxgi -ld3d11" +check_cpp < +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#error desktop, not uwp +#else +// WINAPI_FAMILY_APP, WINAPI_FAMILY_PHONE_APP => UWP +#endif +#else +#error no family set +#endif +EOF enabled vaapi && check_lib vaapi va/va.h vaInitialize -lva diff --git a/libavutil/hwcontext_d3d11va.c b/libavutil/hwcontext_d3d11va.c index 9a86d33b380b4..52683b92cd742 100644 --- a/libavutil/hwcontext_d3d11va.c +++ b/libavutil/hwcontext_d3d11va.c @@ -56,7 +56,7 @@ static PFN_D3D11_CREATE_DEVICE mD3D11CreateDevice; static av_cold void load_functions(void) { -#if HAVE_LOADLIBRARY +#if !HAVE_UWP // We let these "leak" - this is fine, as unloading has no great benefit, and // Windows will mark a DLL as loaded forever if its internal refcount overflows // from too many LoadLibrary calls. @@ -486,7 +486,7 @@ static int d3d11va_device_create(AVHWDeviceContext *ctx, const char *device, int ret; // (On UWP we can't check this.) -#if HAVE_LOADLIBRARY +#if !HAVE_UWP if (!LoadLibrary("d3d11_1sdklayers.dll")) is_debug = 0; #endif @@ -527,7 +527,7 @@ static int d3d11va_device_create(AVHWDeviceContext *ctx, const char *device, ID3D10Multithread_Release(pMultithread); } -#if HAVE_LOADLIBRARY && HAVE_DXGIDEBUG_H +#if !HAVE_UWP && HAVE_DXGIDEBUG_H if (is_debug) { HANDLE dxgidebug_dll = LoadLibrary("dxgidebug.dll"); if (dxgidebug_dll) { From 8c34a2024da77b50470e62789e4859b45959932e Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Fri, 9 Jun 2017 17:27:22 -0400 Subject: [PATCH 2744/3374] h264: Add support for alternative transfer characterics SEI The use of this SEI is for backward compatibility in HLG HDR systems: older devices that cannot interpret the "arib-std-b67" transfer will get the compatible transfer (usually bt709 or bt2020) from the VUI, while newer devices that can interpret HDR will read the SEI and use its value instead. Signed-off-by: Vittorio Giovara --- libavcodec/h264_sei.c | 11 +++++++++++ libavcodec/h264_sei.h | 9 ++++++++- libavcodec/h264_slice.c | 6 ++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c index a7e627eba38c6..889bea2ee0589 100644 --- a/libavcodec/h264_sei.c +++ b/libavcodec/h264_sei.c @@ -382,6 +382,14 @@ static int decode_green_metadata(H264SEIGreenMetaData *h, GetBitContext *gb) return 0; } +static int decode_alternative_transfer(H264SEIAlternativeTransfer *h, + GetBitContext *gb) +{ + h->present = 1; + h->preferred_transfer_characteristics = get_bits(gb, 8); + return 0; +} + int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb, const H264ParamSets *ps, void *logctx) { @@ -437,6 +445,9 @@ int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb, case SEI_TYPE_GREEN_METADATA: ret = decode_green_metadata(&h->green_metadata, gb); break; + case SEI_TYPE_ALTERNATIVE_TRANSFER: + ret = decode_alternative_transfer(&h->alternative_transfer, gb); + break; default: av_log(logctx, AV_LOG_DEBUG, "unknown SEI type %d\n", type); } diff --git a/libavcodec/h264_sei.h b/libavcodec/h264_sei.h index da3b391860376..5f5d895e89847 100644 --- a/libavcodec/h264_sei.h +++ b/libavcodec/h264_sei.h @@ -32,7 +32,8 @@ typedef enum { SEI_TYPE_RECOVERY_POINT = 6, ///< recovery point (frame # to decoder sync) SEI_TYPE_FRAME_PACKING = 45, ///< frame packing arrangement SEI_TYPE_DISPLAY_ORIENTATION = 47, ///< display orientation - SEI_TYPE_GREEN_METADATA = 56 ///< GreenMPEG information + SEI_TYPE_GREEN_METADATA = 56, ///< GreenMPEG information + SEI_TYPE_ALTERNATIVE_TRANSFER = 147, ///< alternative transfer } SEI_Type; /** @@ -144,6 +145,11 @@ typedef struct H264SEIGreenMetaData { uint16_t xsd_metric_value; } H264SEIGreenMetaData; +typedef struct H264SEIAlternativeTransfer { + int present; + int preferred_transfer_characteristics; +} H264SEIAlternativeTransfer; + typedef struct H264SEIContext { H264SEIPictureTiming picture_timing; H264SEIAFD afd; @@ -154,6 +160,7 @@ typedef struct H264SEIContext { H264SEIFramePacking frame_packing; H264SEIDisplayOrientation display_orientation; H264SEIGreenMetaData green_metadata; + H264SEIAlternativeTransfer alternative_transfer; } H264SEIContext; struct H264ParamSets; diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 4e7eba4adb462..ebff7b33e38b2 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1287,6 +1287,12 @@ static int h264_export_frame_props(H264Context *h) h->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS; } + if (h->sei.alternative_transfer.present && + av_color_transfer_name(h->sei.alternative_transfer.preferred_transfer_characteristics) && + h->sei.alternative_transfer.preferred_transfer_characteristics != AVCOL_TRC_UNSPECIFIED) { + h->avctx->color_trc = cur->f->color_trc = h->sei.alternative_transfer.preferred_transfer_characteristics; + } + return 0; } From f3571048669bf876681499f49e9df492f05f73c6 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Tue, 8 Aug 2017 16:30:32 +0200 Subject: [PATCH 2745/3374] pixfmt: Support chroma-derived and ictcp color matrices Signed-off-by: Vittorio Giovara --- libavutil/pixdesc.c | 3 +++ libavutil/pixfmt.h | 3 +++ libavutil/version.h | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index 9f1c21cc94338..59587328eaf7b 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -2246,6 +2246,9 @@ static const char *color_space_names[] = { [AVCOL_SPC_BT2020_NCL] = "bt2020nc", [AVCOL_SPC_BT2020_CL] = "bt2020c", [AVCOL_SPC_SMPTE2085] = "smpte2085", + [AVCOL_SPC_CHROMA_DERIVED_NCL] = "chroma-derived-nc", + [AVCOL_SPC_CHROMA_DERIVED_CL] = "chroma-derived-c", + [AVCOL_SPC_ICTCP] = "ictcp", }; static const char *chroma_location_names[] = { diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index 5798507e74f42..d4a39dcc01329 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -481,6 +481,9 @@ enum AVColorSpace { AVCOL_SPC_BT2020_NCL = 9, ///< ITU-R BT2020 non-constant luminance system AVCOL_SPC_BT2020_CL = 10, ///< ITU-R BT2020 constant luminance system AVCOL_SPC_SMPTE2085 = 11, ///< SMPTE 2085, Y'D'zD'x + AVCOL_SPC_CHROMA_DERIVED_NCL = 12, ///< Chromaticity-derived non-constant luminance system + AVCOL_SPC_CHROMA_DERIVED_CL = 13, ///< Chromaticity-derived constant luminance system + AVCOL_SPC_ICTCP = 14, ///< ITU-R BT.2100-0, ICtCp AVCOL_SPC_NB ///< Not part of ABI }; diff --git a/libavutil/version.h b/libavutil/version.h index 111b581a81745..02461ae0b2c4a 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -80,7 +80,7 @@ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 72 +#define LIBAVUTIL_VERSION_MINOR 73 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From 493f637d1e933ebdd9f63528a7782d3617c442cb Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sat, 5 Aug 2017 22:15:10 +0200 Subject: [PATCH 2746/3374] ffplay: add support for rendering yuv images with negative line size Signed-off-by: Marton Balint --- ffplay.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/ffplay.c b/ffplay.c index 7cc5ab1644df8..ee3d1628e8d4c 100644 --- a/ffplay.c +++ b/ffplay.c @@ -859,13 +859,18 @@ static int upload_texture(SDL_Texture *tex, AVFrame *frame, struct SwsContext ** int ret = 0; switch (frame->format) { case AV_PIX_FMT_YUV420P: - if (frame->linesize[0] < 0 || frame->linesize[1] < 0 || frame->linesize[2] < 0) { - av_log(NULL, AV_LOG_ERROR, "Negative linesize is not supported for YUV.\n"); + if (frame->linesize[0] > 0 && frame->linesize[1] > 0 && frame->linesize[2] > 0) { + ret = SDL_UpdateYUVTexture(tex, NULL, frame->data[0], frame->linesize[0], + frame->data[1], frame->linesize[1], + frame->data[2], frame->linesize[2]); + } else if (frame->linesize[0] < 0 && frame->linesize[1] < 0 && frame->linesize[2] < 0) { + ret = SDL_UpdateYUVTexture(tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0], + frame->data[1] + frame->linesize[1] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[1], + frame->data[2] + frame->linesize[2] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[2]); + } else { + av_log(NULL, AV_LOG_ERROR, "Mixed negative and positive linesizes are not supported.\n"); return -1; } - ret = SDL_UpdateYUVTexture(tex, NULL, frame->data[0], frame->linesize[0], - frame->data[1], frame->linesize[1], - frame->data[2], frame->linesize[2]); break; case AV_PIX_FMT_BGRA: if (frame->linesize[0] < 0) { From 7004ac5eeb8e0715f8cd06ad2558ea52eacd6fba Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sat, 5 Aug 2017 22:54:18 +0200 Subject: [PATCH 2747/3374] ffplay: add support for displaying rgb images with alpha Signed-off-by: Marton Balint --- ffplay.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ffplay.c b/ffplay.c index ee3d1628e8d4c..8174caf4a6b3e 100644 --- a/ffplay.c +++ b/ffplay.c @@ -957,7 +957,8 @@ static void video_image_display(VideoState *is) if (!vp->uploaded) { int sdl_pix_fmt = vp->frame->format == AV_PIX_FMT_YUV420P ? SDL_PIXELFORMAT_YV12 : SDL_PIXELFORMAT_ARGB8888; - if (realloc_texture(&is->vid_texture, sdl_pix_fmt, vp->frame->width, vp->frame->height, SDL_BLENDMODE_NONE, 0) < 0) + SDL_BlendMode sdl_blendmode = vp->frame->format == AV_PIX_FMT_YUV420P ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND; + if (realloc_texture(&is->vid_texture, sdl_pix_fmt, vp->frame->width, vp->frame->height, sdl_blendmode, 0) < 0) return; if (upload_texture(is->vid_texture, vp->frame, &is->img_convert_ctx) < 0) return; From 3bd2228d05a05eab5f91ac00b01efac9cb07649b Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sun, 6 Aug 2017 14:22:20 +0200 Subject: [PATCH 2748/3374] ffplay: add support for more SDL pixel formats when rendering video Signed-off-by: Marton Balint --- ffplay.c | 114 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 82 insertions(+), 32 deletions(-) diff --git a/ffplay.c b/ffplay.c index 8174caf4a6b3e..66e3673d2158c 100644 --- a/ffplay.c +++ b/ffplay.c @@ -362,6 +362,32 @@ static AVPacket flush_pkt; static SDL_Window *window; static SDL_Renderer *renderer; +static const struct TextureFormatEntry { + enum AVPixelFormat format; + int texture_fmt; +} sdl_texture_format_map[] = { + { AV_PIX_FMT_RGB8, SDL_PIXELFORMAT_RGB332 }, + { AV_PIX_FMT_RGB444, SDL_PIXELFORMAT_RGB444 }, + { AV_PIX_FMT_RGB555, SDL_PIXELFORMAT_RGB555 }, + { AV_PIX_FMT_BGR555, SDL_PIXELFORMAT_BGR555 }, + { AV_PIX_FMT_RGB565, SDL_PIXELFORMAT_RGB565 }, + { AV_PIX_FMT_BGR565, SDL_PIXELFORMAT_BGR565 }, + { AV_PIX_FMT_RGB24, SDL_PIXELFORMAT_RGB24 }, + { AV_PIX_FMT_BGR24, SDL_PIXELFORMAT_BGR24 }, + { AV_PIX_FMT_0RGB32, SDL_PIXELFORMAT_RGB888 }, + { AV_PIX_FMT_0BGR32, SDL_PIXELFORMAT_BGR888 }, + { AV_PIX_FMT_NE(RGB0, 0BGR), SDL_PIXELFORMAT_RGBX8888 }, + { AV_PIX_FMT_NE(BGR0, 0RGB), SDL_PIXELFORMAT_BGRX8888 }, + { AV_PIX_FMT_RGB32, SDL_PIXELFORMAT_ARGB8888 }, + { AV_PIX_FMT_RGB32_1, SDL_PIXELFORMAT_RGBA8888 }, + { AV_PIX_FMT_BGR32, SDL_PIXELFORMAT_ABGR8888 }, + { AV_PIX_FMT_BGR32_1, SDL_PIXELFORMAT_BGRA8888 }, + { AV_PIX_FMT_YUV420P, SDL_PIXELFORMAT_IYUV }, + { AV_PIX_FMT_YUYV422, SDL_PIXELFORMAT_YUY2 }, + { AV_PIX_FMT_UYVY422, SDL_PIXELFORMAT_UYVY }, + { AV_PIX_FMT_NONE, SDL_PIXELFORMAT_UNKNOWN }, +}; + #if CONFIG_AVFILTER static int opt_add_vfilter(void *optctx, const char *opt, const char *arg) { @@ -820,6 +846,7 @@ static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_wid memset(pixels, 0, pitch * new_height); SDL_UnlockTexture(*texture); } + av_log(NULL, AV_LOG_VERBOSE, "Created %dx%d texture with %s.\n", new_width, new_height, SDL_GetPixelFormatName(new_format)); } return 0; } @@ -855,31 +882,33 @@ static void calculate_display_rect(SDL_Rect *rect, rect->h = FFMAX(height, 1); } -static int upload_texture(SDL_Texture *tex, AVFrame *frame, struct SwsContext **img_convert_ctx) { +static void get_sdl_pix_fmt_and_blendmode(int format, Uint32 *sdl_pix_fmt, SDL_BlendMode *sdl_blendmode) +{ + int i; + *sdl_blendmode = SDL_BLENDMODE_NONE; + *sdl_pix_fmt = SDL_PIXELFORMAT_UNKNOWN; + if (format == AV_PIX_FMT_RGB32 || + format == AV_PIX_FMT_RGB32_1 || + format == AV_PIX_FMT_BGR32 || + format == AV_PIX_FMT_BGR32_1) + *sdl_blendmode = SDL_BLENDMODE_BLEND; + for (i = 0; i < FF_ARRAY_ELEMS(sdl_texture_format_map) - 1; i++) { + if (format == sdl_texture_format_map[i].format) { + *sdl_pix_fmt = sdl_texture_format_map[i].texture_fmt; + return; + } + } +} + +static int upload_texture(SDL_Texture **tex, AVFrame *frame, struct SwsContext **img_convert_ctx) { int ret = 0; - switch (frame->format) { - case AV_PIX_FMT_YUV420P: - if (frame->linesize[0] > 0 && frame->linesize[1] > 0 && frame->linesize[2] > 0) { - ret = SDL_UpdateYUVTexture(tex, NULL, frame->data[0], frame->linesize[0], - frame->data[1], frame->linesize[1], - frame->data[2], frame->linesize[2]); - } else if (frame->linesize[0] < 0 && frame->linesize[1] < 0 && frame->linesize[2] < 0) { - ret = SDL_UpdateYUVTexture(tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0], - frame->data[1] + frame->linesize[1] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[1], - frame->data[2] + frame->linesize[2] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[2]); - } else { - av_log(NULL, AV_LOG_ERROR, "Mixed negative and positive linesizes are not supported.\n"); - return -1; - } - break; - case AV_PIX_FMT_BGRA: - if (frame->linesize[0] < 0) { - ret = SDL_UpdateTexture(tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0]); - } else { - ret = SDL_UpdateTexture(tex, NULL, frame->data[0], frame->linesize[0]); - } - break; - default: + Uint32 sdl_pix_fmt; + SDL_BlendMode sdl_blendmode; + get_sdl_pix_fmt_and_blendmode(frame->format, &sdl_pix_fmt, &sdl_blendmode); + if (realloc_texture(tex, sdl_pix_fmt == SDL_PIXELFORMAT_UNKNOWN ? SDL_PIXELFORMAT_ARGB8888 : sdl_pix_fmt, frame->width, frame->height, sdl_blendmode, 0) < 0) + return -1; + switch (sdl_pix_fmt) { + case SDL_PIXELFORMAT_UNKNOWN: /* This should only happen if we are not using avfilter... */ *img_convert_ctx = sws_getCachedContext(*img_convert_ctx, frame->width, frame->height, frame->format, frame->width, frame->height, @@ -887,16 +916,37 @@ static int upload_texture(SDL_Texture *tex, AVFrame *frame, struct SwsContext ** if (*img_convert_ctx != NULL) { uint8_t *pixels[4]; int pitch[4]; - if (!SDL_LockTexture(tex, NULL, (void **)pixels, pitch)) { + if (!SDL_LockTexture(*tex, NULL, (void **)pixels, pitch)) { sws_scale(*img_convert_ctx, (const uint8_t * const *)frame->data, frame->linesize, 0, frame->height, pixels, pitch); - SDL_UnlockTexture(tex); + SDL_UnlockTexture(*tex); } } else { av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n"); ret = -1; } break; + case SDL_PIXELFORMAT_IYUV: + if (frame->linesize[0] > 0 && frame->linesize[1] > 0 && frame->linesize[2] > 0) { + ret = SDL_UpdateYUVTexture(*tex, NULL, frame->data[0], frame->linesize[0], + frame->data[1], frame->linesize[1], + frame->data[2], frame->linesize[2]); + } else if (frame->linesize[0] < 0 && frame->linesize[1] < 0 && frame->linesize[2] < 0) { + ret = SDL_UpdateYUVTexture(*tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0], + frame->data[1] + frame->linesize[1] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[1], + frame->data[2] + frame->linesize[2] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[2]); + } else { + av_log(NULL, AV_LOG_ERROR, "Mixed negative and positive linesizes are not supported.\n"); + return -1; + } + break; + default: + if (frame->linesize[0] < 0) { + ret = SDL_UpdateTexture(*tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0]); + } else { + ret = SDL_UpdateTexture(*tex, NULL, frame->data[0], frame->linesize[0]); + } + break; } return ret; } @@ -956,11 +1006,7 @@ static void video_image_display(VideoState *is) calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar); if (!vp->uploaded) { - int sdl_pix_fmt = vp->frame->format == AV_PIX_FMT_YUV420P ? SDL_PIXELFORMAT_YV12 : SDL_PIXELFORMAT_ARGB8888; - SDL_BlendMode sdl_blendmode = vp->frame->format == AV_PIX_FMT_YUV420P ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND; - if (realloc_texture(&is->vid_texture, sdl_pix_fmt, vp->frame->width, vp->frame->height, sdl_blendmode, 0) < 0) - return; - if (upload_texture(is->vid_texture, vp->frame, &is->img_convert_ctx) < 0) + if (upload_texture(&is->vid_texture, vp->frame, &is->img_convert_ctx) < 0) return; vp->uploaded = 1; vp->flip_v = vp->frame->linesize[0] < 0; @@ -1796,7 +1842,7 @@ static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph, static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame) { - static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE }; + enum AVPixelFormat pix_fmts[FF_ARRAY_ELEMS(sdl_texture_format_map)]; char sws_flags_str[512] = ""; char buffersrc_args[256]; int ret; @@ -1804,6 +1850,10 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c AVCodecParameters *codecpar = is->video_st->codecpar; AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL); AVDictionaryEntry *e = NULL; + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(pix_fmts); i++) + pix_fmts[i] = sdl_texture_format_map[i].format; while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) { if (!strcmp(e->key, "sws_flags")) { From 498c90c708446b5d30161e51b97e6fd4255dfad6 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Thu, 3 Aug 2017 01:48:06 +0200 Subject: [PATCH 2749/3374] avfilter/vf_overlay: fix alpha blending for planar formats with a transparent background When the background had an alpha channel, the old code in blend_plane calculated premultiplied alpha from the destination plane colors instead of the destination alpha. Also the calculation of the output alpha should only happen after the color planes are already finished. Fixes output of: ffplay -f lavfi "testsrc2=alpha=32[a];color=black[b];[b][a]overlay[out0]" Signed-off-by: Marton Balint --- libavfilter/vf_overlay.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c index ad292a61c1995..52f09fae1f48c 100644 --- a/libavfilter/vf_overlay.c +++ b/libavfilter/vf_overlay.c @@ -508,7 +508,7 @@ static av_always_inline void blend_plane(AVFilterContext *ctx, int dst_hp = AV_CEIL_RSHIFT(dst_h, vsub); int yp = y>>vsub; int xp = x>>hsub; - uint8_t *s, *sp, *d, *dp, *a, *ap; + uint8_t *s, *sp, *d, *dp, *dap, *a, *da, *ap; int jmax, j, k, kmax; j = FFMAX(-yp, 0); @@ -517,12 +517,14 @@ static av_always_inline void blend_plane(AVFilterContext *ctx, + (yp+j) * dst->linesize[dst_plane] + dst_offset; ap = src->data[3] + (j<linesize[3]; + dap = dst->data[3] + ((yp+j) << vsub) * dst->linesize[3]; for (jmax = FFMIN(-yp + dst_hp, src_hp); j < jmax; j++) { k = FFMAX(-xp, 0); d = dp + (xp+k) * dst_step; s = sp + k; a = ap + (k<linesize[3]] + - d[1] + d[src->linesize[3]+1]) >> 2; + alpha_d = (da[0] + da[dst->linesize[3]] + + da[1] + da[dst->linesize[3]+1]) >> 2; } else if (hsub || vsub) { alpha_h = hsub && k+1 < src_wp ? - (d[0] + d[1]) >> 1 : d[0]; + (da[0] + da[1]) >> 1 : da[0]; alpha_v = vsub && j+1 < src_hp ? - (d[0] + d[src->linesize[3]]) >> 1 : d[0]; + (da[0] + da[dst->linesize[3]]) >> 1 : da[0]; alpha_d = (alpha_v + alpha_h) >> 1; } else - alpha_d = d[0]; + alpha_d = da[0]; alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); } *d = FAST_DIV255(*d * (255 - alpha) + *s * alpha); s++; d += dst_step; + da += 1 << hsub; a += 1 << hsub; } dp += dst->linesize[dst_plane]; sp += src->linesize[i]; ap += (1 << vsub) * src->linesize[3]; + dap += (1 << vsub) * dst->linesize[3]; } } @@ -622,15 +626,15 @@ static av_always_inline void blend_image_yuv(AVFilterContext *ctx, const int dst_w = dst->width; const int dst_h = dst->height; - if (main_has_alpha) - alpha_composite(src, dst, src_w, src_h, dst_w, dst_h, x, y); - blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, x, y, main_has_alpha, s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, s->main_desc->comp[0].step); blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, x, y, main_has_alpha, s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, s->main_desc->comp[1].step); blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, x, y, main_has_alpha, s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, s->main_desc->comp[2].step); + + if (main_has_alpha) + alpha_composite(src, dst, src_w, src_h, dst_w, dst_h, x, y); } static av_always_inline void blend_image_planar_rgb(AVFilterContext *ctx, @@ -645,15 +649,15 @@ static av_always_inline void blend_image_planar_rgb(AVFilterContext *ctx, const int dst_w = dst->width; const int dst_h = dst->height; - if (main_has_alpha) - alpha_composite(src, dst, src_w, src_h, dst_w, dst_h, x, y); - blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, x, y, main_has_alpha, s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, s->main_desc->comp[1].step); blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, x, y, main_has_alpha, s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, s->main_desc->comp[2].step); blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, x, y, main_has_alpha, s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, s->main_desc->comp[0].step); + + if (main_has_alpha) + alpha_composite(src, dst, src_w, src_h, dst_w, dst_h, x, y); } static void blend_image_yuv420(AVFilterContext *ctx, AVFrame *dst, const AVFrame *src, int x, int y) From 1939b9030642106a5f75d7d2cfd1ec5208bea0ab Mon Sep 17 00:00:00 2001 From: Davinder Singh Date: Thu, 10 Aug 2017 07:08:34 +0530 Subject: [PATCH 2750/3374] avcodec/mjpegenc: disable unused code with AMV disable unused amv_encode_picture() when AMV encoder is not configured. Signed-off-by: Michael Niedermayer --- libavcodec/mjpegenc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c index ee77cde8cb411..9c3f863f6c050 100644 --- a/libavcodec/mjpegenc.c +++ b/libavcodec/mjpegenc.c @@ -346,6 +346,7 @@ void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[12][64]) } } +#if CONFIG_AMV_ENCODER // maximum over s->mjpeg_vsample[i] #define V_MAX 2 static int amv_encode_picture(AVCodecContext *avctx, AVPacket *pkt, @@ -387,6 +388,7 @@ static int amv_encode_picture(AVCodecContext *avctx, AVPacket *pkt, av_frame_free(&pic); return ret; } +#endif #define OFFSET(x) offsetof(MpegEncContext, x) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM From 4116b2b136f5c278cf58182a7a990566b96ac306 Mon Sep 17 00:00:00 2001 From: Davinder Singh Date: Thu, 10 Aug 2017 07:10:36 +0530 Subject: [PATCH 2751/3374] avcodec/mjpegenc: cosmetic changes Signed-off-by: Michael Niedermayer --- libavcodec/mjpegenc.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c index 9c3f863f6c050..e6cdaf63760f1 100644 --- a/libavcodec/mjpegenc.c +++ b/libavcodec/mjpegenc.c @@ -39,7 +39,6 @@ #include "mjpeg.h" #include "mjpegenc.h" - static int alloc_huffman(MpegEncContext *s) { MJpegContext *m = s->mjpeg_ctx; @@ -351,7 +350,6 @@ void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[12][64]) #define V_MAX 2 static int amv_encode_picture(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pic_arg, int *got_packet) - { MpegEncContext *s = avctx->priv_data; AVFrame *pic; @@ -405,7 +403,6 @@ FF_MPV_COMMON_OPTS }; #if CONFIG_MJPEG_ENCODER - static const AVClass mjpeg_class = { .class_name = "mjpeg encoder", .item_name = av_default_item_name, @@ -423,12 +420,13 @@ AVCodec ff_mjpeg_encoder = { .encode2 = ff_mpv_encode_picture, .close = ff_mpv_encode_end, .capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY, - .pix_fmts = (const enum AVPixelFormat[]){ + .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_NONE }, .priv_class = &mjpeg_class, }; #endif + #if CONFIG_AMV_ENCODER static const AVClass amv_class = { .class_name = "amv encoder", @@ -446,7 +444,7 @@ AVCodec ff_amv_encoder = { .init = ff_mpv_encode_init, .encode2 = amv_encode_picture, .close = ff_mpv_encode_end, - .pix_fmts = (const enum AVPixelFormat[]){ + .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_NONE }, .priv_class = &amv_class, From 86cbffdc4db268bab0d798dca1e30dc46606dad0 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 9 Jul 2017 03:10:51 +0200 Subject: [PATCH 2752/3374] avcodec/tests/dct: Add peak mean error check based on quotes of IEEE 1180 / ISO/IEC 23002-1 Signed-off-by: Michael Niedermayer --- libavcodec/tests/dct.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/tests/dct.c b/libavcodec/tests/dct.c index 29af3fea8a577..cf71b9650866d 100644 --- a/libavcodec/tests/dct.c +++ b/libavcodec/tests/dct.c @@ -244,6 +244,8 @@ static int dct_error(const struct algo *dct, int test, int is_idct, int speed, c ome = (double) err_sum / NB_ITS / 64; spec_err = is_idct && (err_inf > 1 || omse > 0.02 || fabs(ome) > 0.0015); + if (test < 2) + spec_err = is_idct && ((double) sysErrMax / NB_ITS > 0.015); printf("%s %s: max_err=%d omse=%0.8f ome=%0.8f syserr=%0.8f maxout=%d blockSumErr=%d\n", is_idct ? "IDCT" : "DCT", dct->name, err_inf, From 84786e928f9e54bdc3622f68db0ce35bae43fb46 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 9 Jul 2017 03:10:51 +0200 Subject: [PATCH 2753/3374] avcodec/tests/dct: Add Mean square error test based on quotes of IEEE 1180 / ISO/IEC 23002-1 Signed-off-by: Michael Niedermayer --- libavcodec/tests/dct.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libavcodec/tests/dct.c b/libavcodec/tests/dct.c index cf71b9650866d..b44c66f427494 100644 --- a/libavcodec/tests/dct.c +++ b/libavcodec/tests/dct.c @@ -182,6 +182,7 @@ static int dct_error(const struct algo *dct, int test, int is_idct, int speed, c int err_inf, v; int64_t err2, ti, ti1, it1, err_sum = 0; int64_t sysErr[64], sysErrMax = 0; + int64_t err2_matrix[64], err2_max = 0; int maxout = 0; int blockSumErrMax = 0, blockSumErr; AVLFG prng; @@ -194,7 +195,7 @@ static int dct_error(const struct algo *dct, int test, int is_idct, int speed, c err_inf = 0; err2 = 0; for (i = 0; i < 64; i++) - sysErr[i] = 0; + err2_matrix[i] = sysErr[i] = 0; for (it = 0; it < NB_ITS; it++) { init_block(block1, test, is_idct, &prng, vals); permute(block, block1, dct->perm_type); @@ -221,6 +222,7 @@ static int dct_error(const struct algo *dct, int test, int is_idct, int speed, c v = abs(err); if (v > err_inf) err_inf = v; + err2_matrix[i] += v * v; err2 += v * v; sysErr[i] += block[i] - block1[i]; blockSumErr += v; @@ -230,8 +232,10 @@ static int dct_error(const struct algo *dct, int test, int is_idct, int speed, c if (blockSumErrMax < blockSumErr) blockSumErrMax = blockSumErr; } - for (i = 0; i < 64; i++) + for (i = 0; i < 64; i++) { sysErrMax = FFMAX(sysErrMax, FFABS(sysErr[i])); + err2_max = FFMAX(err2_max , FFABS(err2_matrix[i])); + } for (i = 0; i < 64; i++) { if (i % 8 == 0) @@ -245,7 +249,7 @@ static int dct_error(const struct algo *dct, int test, int is_idct, int speed, c spec_err = is_idct && (err_inf > 1 || omse > 0.02 || fabs(ome) > 0.0015); if (test < 2) - spec_err = is_idct && ((double) sysErrMax / NB_ITS > 0.015); + spec_err = is_idct && ((double) err2_max / NB_ITS > 0.06 || (double) sysErrMax / NB_ITS > 0.015); printf("%s %s: max_err=%d omse=%0.8f ome=%0.8f syserr=%0.8f maxout=%d blockSumErr=%d\n", is_idct ? "IDCT" : "DCT", dct->name, err_inf, From 511e10f673a69c05744be0355cc9ce5705407bc2 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 8 Aug 2017 02:17:16 +0200 Subject: [PATCH 2754/3374] avformat/avidec: Move packet skip after prefix and related checks This fixes loosing packets Fixes: big.avi Signed-off-by: Michael Niedermayer --- libavformat/avidec.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/libavformat/avidec.c b/libavformat/avidec.c index df52092067124..9816a1dfacce7 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -1265,19 +1265,6 @@ static int avi_sync(AVFormatContext *s, int exit_early) } } - if (!avi->dv_demux && - ((st->discard >= AVDISCARD_DEFAULT && size == 0) /* || - // FIXME: needs a little reordering - (st->discard >= AVDISCARD_NONKEY && - !(pkt->flags & AV_PKT_FLAG_KEY)) */ - || st->discard >= AVDISCARD_ALL)) { - if (!exit_early) { - ast->frame_offset += get_duration(ast, size); - avio_skip(pb, size); - goto start_sync; - } - } - if (d[2] == 'p' && d[3] == 'c' && size <= 4 * 256 + 4) { int k = avio_r8(pb); int last = (k + avio_r8(pb) - 1) & 0xFF; @@ -1304,6 +1291,18 @@ static int avi_sync(AVFormatContext *s, int exit_early) ast->prefix_count = 0; } + if (!avi->dv_demux && + ((st->discard >= AVDISCARD_DEFAULT && size == 0) /* || + // FIXME: needs a little reordering + (st->discard >= AVDISCARD_NONKEY && + !(pkt->flags & AV_PKT_FLAG_KEY)) */ + || st->discard >= AVDISCARD_ALL)) { + + ast->frame_offset += get_duration(ast, size); + avio_skip(pb, size); + goto start_sync; + } + avi->stream_index = n; ast->packet_size = size + 8; ast->remaining = size; From 7735ed29741d985e1e670249ca56e7a1ce18b729 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 6 Aug 2017 13:32:54 +0200 Subject: [PATCH 2755/3374] avcodec/mpeg4videodec: Clear mcsel before decoding an image Fixes: runtime error: signed integer overflow: 2146467840 + 1032192 cannot be represented in type 'int' Fixes: 2826/clusterfuzz-testcase-minimized-5901511613743104 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/mpeg4videodec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index 89c4b367f7ca1..8f85e9362dd96 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -2290,6 +2290,7 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) int time_incr, time_increment; int64_t pts; + s->mcsel = 0; s->pict_type = get_bits(gb, 2) + AV_PICTURE_TYPE_I; /* pict type: I = 0 , P = 1 */ if (s->pict_type == AV_PICTURE_TYPE_B && s->low_delay && ctx->vol_control_parameters == 0 && !(s->avctx->flags & AV_CODEC_FLAG_LOW_DELAY)) { From 62702eebded6c6341d214405812a981f80e46ea2 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 11 Aug 2017 18:20:03 +0200 Subject: [PATCH 2756/3374] avcodec/ffv1dec_template: Fix undefined shift Fixes: runtime error: left shift of negative value -127 Fixes: 2834/clusterfuzz-testcase-minimized-5988039123795968 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/ffv1dec_template.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/ffv1dec_template.c b/libavcodec/ffv1dec_template.c index 61cdc901165d6..d41d807e64cea 100644 --- a/libavcodec/ffv1dec_template.c +++ b/libavcodec/ffv1dec_template.c @@ -149,7 +149,7 @@ static void RENAME(decode_rgb_frame)(FFV1Context *s, uint8_t *src[3], int w, int } if (lbd) - *((uint32_t*)(src[0] + x*4 + stride[0]*y)) = b + (g<<8) + (r<<16) + (a<<24); + *((uint32_t*)(src[0] + x*4 + stride[0]*y)) = b + ((unsigned)g<<8) + ((unsigned)r<<16) + ((unsigned)a<<24); else if (sizeof(TYPE) == 4) { *((uint16_t*)(src[0] + x*2 + stride[0]*y)) = g; *((uint16_t*)(src[1] + x*2 + stride[1]*y)) = b; From 0561bd2fc2bff0dbe651d5998e9f129c43d25eb3 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 11 Aug 2017 19:27:02 +0200 Subject: [PATCH 2757/3374] avcodec/gdv: Check available space before reading palette Fixes: Timeout Fixes: 2926/clusterfuzz-testcase-498711001458278 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/gdv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/gdv.c b/libavcodec/gdv.c index b324e4f26e3ba..dc91869edf94e 100644 --- a/libavcodec/gdv.c +++ b/libavcodec/gdv.c @@ -427,6 +427,8 @@ static int gdv_decode_frame(AVCodecContext *avctx, void *data, case 1: memset(gdv->frame + PREAMBLE_SIZE, 0, gdv->frame_size - PREAMBLE_SIZE); case 0: + if (bytestream2_get_bytes_left(gb) < 256*3) + return AVERROR_INVALIDDATA; for (i = 0; i < 256; i++) { unsigned r = bytestream2_get_byte(gb); unsigned g = bytestream2_get_byte(gb); From 5859b5b4394d3a0d654b6e821c2ba5e1e7842244 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 11 Aug 2017 21:47:31 +0200 Subject: [PATCH 2758/3374] avcodec/lagarith: Detect end of input in lag_decode_line() loop Fixes: timeout Fixes: 2933/clusterfuzz-testcase-5124990208835584 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/lagarith.c | 6 ++++-- libavcodec/lagarithrac.c | 1 + libavcodec/lagarithrac.h | 5 +++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c index 860381746d136..0f4aa89486e09 100644 --- a/libavcodec/lagarith.c +++ b/libavcodec/lagarith.c @@ -455,10 +455,12 @@ static int lag_decode_arith_plane(LagarithContext *l, uint8_t *dst, return -1; ff_lag_rac_init(&rac, &gb, length - stride); - - for (i = 0; i < height; i++) + for (i = 0; i < height; i++) { + if (rac.overread > MAX_OVERREAD) + return AVERROR_INVALIDDATA; read += lag_decode_line(l, &rac, dst + (i * stride), width, stride, esc_count); + } if (read > length) av_log(l->avctx, AV_LOG_WARNING, diff --git a/libavcodec/lagarithrac.c b/libavcodec/lagarithrac.c index 3d36d1b9e99e8..cdda67fb8153b 100644 --- a/libavcodec/lagarithrac.c +++ b/libavcodec/lagarithrac.c @@ -46,6 +46,7 @@ void ff_lag_rac_init(lag_rac *l, GetBitContext *gb, int length) l->range = 0x80; l->low = *l->bytestream >> 1; l->hash_shift = FFMAX(l->scale, 10) - 10; + l->overread = 0; for (i = j = 0; i < 1024; i++) { unsigned r = i << l->hash_shift; diff --git a/libavcodec/lagarithrac.h b/libavcodec/lagarithrac.h index dfdfea0db38e4..ee836d01db46f 100644 --- a/libavcodec/lagarithrac.h +++ b/libavcodec/lagarithrac.h @@ -47,6 +47,9 @@ typedef struct lag_rac { const uint8_t *bytestream; /**< Current position in input bytestream. */ const uint8_t *bytestream_end; /**< End position of input bytestream. */ + int overread; +#define MAX_OVERREAD 4 + uint32_t prob[258]; /**< Table of cumulative probability for each symbol. */ uint8_t range_hash[1024]; /**< Hash table mapping upper byte to approximate symbol. */ } lag_rac; @@ -62,6 +65,8 @@ static inline void lag_rac_refill(lag_rac *l) l->low |= 0xff & (AV_RB16(l->bytestream) >> 1); if (l->bytestream < l->bytestream_end) l->bytestream++; + else + l->overread++; } } From 77c5a54192b2bd662bdd6bfe5976707da6b68a35 Mon Sep 17 00:00:00 2001 From: Yogender Gupta Date: Mon, 14 Aug 2017 16:11:32 +0530 Subject: [PATCH 2759/3374] avfilter/scale_npp: fix passthrough mode Signed-off-by: Timo Rothenpieler --- libavfilter/vf_scale_npp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavfilter/vf_scale_npp.c b/libavfilter/vf_scale_npp.c index c36772e8005ec..f64ab956c7b17 100644 --- a/libavfilter/vf_scale_npp.c +++ b/libavfilter/vf_scale_npp.c @@ -320,7 +320,11 @@ static int init_processing_chain(AVFilterContext *ctx, int in_width, int in_heig } if (last_stage < 0) + { + ctx->outputs[0]->hw_frames_ctx = av_buffer_ref(ctx->inputs[0]->hw_frames_ctx); return 0; + } + ctx->outputs[0]->hw_frames_ctx = av_buffer_ref(s->stages[last_stage].frames_ctx); if (!ctx->outputs[0]->hw_frames_ctx) return AVERROR(ENOMEM); From f4ebbda566f73952a721c367877b1527ba697e7a Mon Sep 17 00:00:00 2001 From: Timo Rothenpieler Date: Mon, 14 Aug 2017 14:15:25 +0200 Subject: [PATCH 2760/3374] avfilter/scale_npp: check for buffer allocation failure I totally did not forget to amend this to the previous patch... --- libavfilter/vf_scale_npp.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/libavfilter/vf_scale_npp.c b/libavfilter/vf_scale_npp.c index f64ab956c7b17..3fe5bbe5008c6 100644 --- a/libavfilter/vf_scale_npp.c +++ b/libavfilter/vf_scale_npp.c @@ -319,13 +319,7 @@ static int init_processing_chain(AVFilterContext *ctx, int in_width, int in_heig last_stage = i; } - if (last_stage < 0) - { - ctx->outputs[0]->hw_frames_ctx = av_buffer_ref(ctx->inputs[0]->hw_frames_ctx); - return 0; - } - - ctx->outputs[0]->hw_frames_ctx = av_buffer_ref(s->stages[last_stage].frames_ctx); + ctx->outputs[0]->hw_frames_ctx = av_buffer_ref(s->stages[last_stage > 0 ? last_stage : 0].frames_ctx); if (!ctx->outputs[0]->hw_frames_ctx) return AVERROR(ENOMEM); From 62b75537db15816fde8b8a33976ffc4a8277f1fc Mon Sep 17 00:00:00 2001 From: Timo Rothenpieler Date: Mon, 14 Aug 2017 16:03:11 +0200 Subject: [PATCH 2761/3374] avfilter/scale_npp: fix logic used in previous patch --- libavfilter/vf_scale_npp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libavfilter/vf_scale_npp.c b/libavfilter/vf_scale_npp.c index 3fe5bbe5008c6..eadb3b5828935 100644 --- a/libavfilter/vf_scale_npp.c +++ b/libavfilter/vf_scale_npp.c @@ -319,7 +319,11 @@ static int init_processing_chain(AVFilterContext *ctx, int in_width, int in_heig last_stage = i; } - ctx->outputs[0]->hw_frames_ctx = av_buffer_ref(s->stages[last_stage > 0 ? last_stage : 0].frames_ctx); + if (last_stage < 0) + ctx->outputs[0]->hw_frames_ctx = av_buffer_ref(ctx->inputs[0]->hw_frames_ctx); + else + ctx->outputs[0]->hw_frames_ctx = av_buffer_ref(s->stages[last_stage].frames_ctx); + if (!ctx->outputs[0]->hw_frames_ctx) return AVERROR(ENOMEM); From 426a322aa2bfd8ec28e467743c79dad81c63c108 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 13 Aug 2017 18:42:45 +0200 Subject: [PATCH 2762/3374] avcodec/cavsdec: Check I frame mb decode for errors Fixes: timeout Fixes: 2943/clusterfuzz-testcase-5430257156882432 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/cavsdec.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c index 7a5f795dab8ef..02b3d213a9686 100644 --- a/libavcodec/cavsdec.c +++ b/libavcodec/cavsdec.c @@ -1070,10 +1070,14 @@ static int decode_pic(AVSContext *h) } else { h->alpha_offset = h->beta_offset = 0; } + + ret = 0; if (h->cur.f->pict_type == AV_PICTURE_TYPE_I) { do { check_for_slice(h); - decode_mb_i(h, 0); + ret = decode_mb_i(h, 0); + if (ret < 0) + break; } while (ff_cavs_next_mb(h)); } else if (h->cur.f->pict_type == AV_PICTURE_TYPE_P) { do { @@ -1109,12 +1113,12 @@ static int decode_pic(AVSContext *h) } while (ff_cavs_next_mb(h)); } emms_c(); - if (h->cur.f->pict_type != AV_PICTURE_TYPE_B) { + if (ret >= 0 && h->cur.f->pict_type != AV_PICTURE_TYPE_B) { av_frame_unref(h->DPB[1].f); FFSWAP(AVSFrame, h->cur, h->DPB[1]); FFSWAP(AVSFrame, h->DPB[0], h->DPB[1]); } - return 0; + return ret; } /***************************************************************************** From b9ce43625c43fe56aa2db726e147929380411790 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 13 Aug 2017 18:44:25 +0200 Subject: [PATCH 2763/3374] avcodec/cavsdec: Check P/B frame mb decode which return error codes Signed-off-by: Michael Niedermayer --- libavcodec/cavsdec.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c index 02b3d213a9686..06c752735ecef 100644 --- a/libavcodec/cavsdec.c +++ b/libavcodec/cavsdec.c @@ -1090,10 +1090,12 @@ static int decode_pic(AVSContext *h) } else { mb_type = get_ue_golomb(&h->gb) + P_SKIP + h->skip_mode_flag; if (mb_type > P_8X8) - decode_mb_i(h, mb_type - P_8X8 - 1); + ret = decode_mb_i(h, mb_type - P_8X8 - 1); else decode_mb_p(h, mb_type); } + if (ret < 0) + break; } while (ff_cavs_next_mb(h)); } else { /* AV_PICTURE_TYPE_B */ do { @@ -1102,14 +1104,16 @@ static int decode_pic(AVSContext *h) if (h->skip_mode_flag && (skip_count < 0)) skip_count = get_ue_golomb(&h->gb); if (h->skip_mode_flag && skip_count--) { - decode_mb_b(h, B_SKIP); + ret = decode_mb_b(h, B_SKIP); } else { mb_type = get_ue_golomb(&h->gb) + B_SKIP + h->skip_mode_flag; if (mb_type > B_8X8) - decode_mb_i(h, mb_type - B_8X8 - 1); + ret = decode_mb_i(h, mb_type - B_8X8 - 1); else - decode_mb_b(h, mb_type); + ret = decode_mb_b(h, mb_type); } + if (ret < 0) + break; } while (ff_cavs_next_mb(h)); } emms_c(); From 8d2da0939cbd21a7f3b79e2b8b93ae2a0a3d4c2c Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Tue, 15 Aug 2017 13:54:19 +0200 Subject: [PATCH 2764/3374] avfilter/vf_datascope: make it possible to change pixscope window position --- doc/filters.texi | 10 ++++- libavfilter/vf_datascope.c | 76 ++++++++++++++++++++------------------ 2 files changed, 49 insertions(+), 37 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index eedc7b58968c5..8b0c6d920bbdf 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -11527,10 +11527,10 @@ The filters accept the following options: @table @option @item x -Set scope X position, offset on X axis. +Set scope X position, relative offset on X axis. @item y -Set scope Y position, offset on Y axis. +Set scope Y position, relative offset on Y axis. @item w Set scope width. @@ -11540,6 +11540,12 @@ Set scope height. @item o Set window opacity. This window also holds statistics about pixel area. + +@item wx +Set window X position, relative offset on X axis. + +@item wy +Set window Y position, relative offset on Y axis. @end table @section pp diff --git a/libavfilter/vf_datascope.c b/libavfilter/vf_datascope.c index 476e65f6c6997..7a1dc4de01e5f 100644 --- a/libavfilter/vf_datascope.c +++ b/libavfilter/vf_datascope.c @@ -424,6 +424,7 @@ typedef struct PixscopeContext { const AVClass *class; float xpos, ypos; + float wx, wy; int w, h; float o; @@ -449,11 +450,13 @@ typedef struct PixscopeContext { #define POFFSET(x) offsetof(PixscopeContext, x) static const AVOption pixscope_options[] = { - { "x", "set scope x offset", POFFSET(xpos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS }, - { "y", "set scope y offset", POFFSET(ypos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS }, - { "w", "set scope width", POFFSET(w), AV_OPT_TYPE_INT, {.i64=7}, 1, 80, FLAGS }, - { "h", "set scope height", POFFSET(h), AV_OPT_TYPE_INT, {.i64=7}, 1, 80, FLAGS }, - { "o", "set window opacity", POFFSET(o), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS }, + { "x", "set scope x offset", POFFSET(xpos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS }, + { "y", "set scope y offset", POFFSET(ypos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS }, + { "w", "set scope width", POFFSET(w), AV_OPT_TYPE_INT, {.i64=7}, 1, 80, FLAGS }, + { "h", "set scope height", POFFSET(h), AV_OPT_TYPE_INT, {.i64=7}, 1, 80, FLAGS }, + { "o", "set window opacity", POFFSET(o), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS }, + { "wx", "set window x offset", POFFSET(wx), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, FLAGS }, + { "wy", "set window y offset", POFFSET(wy), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, FLAGS }, { NULL } }; @@ -520,6 +523,7 @@ static int pixscope_filter_frame(AVFilterLink *inlink, AVFrame *in) AVFilterContext *ctx = inlink->dst; PixscopeContext *s = ctx->priv; AVFilterLink *outlink = ctx->outputs[0]; + AVFrame *out = ff_get_video_buffer(outlink, in->width, in->height); int max[4] = { 0 }, min[4] = { INT_MAX, INT_MAX, INT_MAX, INT_MAX }; float average[4] = { 0 }; double rms[4] = { 0 }; @@ -528,19 +532,21 @@ static int pixscope_filter_frame(AVFilterLink *inlink, AVFrame *in) int x, y, X, Y, i, w, h; char text[128]; + if (!out) { + av_frame_free(&in); + return AVERROR(ENOMEM); + } + av_frame_copy_props(out, in); + av_frame_copy(out, in); + w = s->ww / s->w; h = s->ww / s->h; - if (s->x <= s->ww && s->y <= s->wh) { - X = in->width - s->ww; - Y = in->height - s->wh; - } else { - X = 0; - Y = 0; - } + X = (in->width - s->ww) * s->wx; + Y = (in->height - s->wh) * s->wy; - ff_blend_rectangle(&s->draw, &s->dark, in->data, in->linesize, - in->width, in->height, + ff_blend_rectangle(&s->draw, &s->dark, out->data, out->linesize, + out->width, out->height, X, Y, s->ww, @@ -552,7 +558,7 @@ static int pixscope_filter_frame(AVFilterLink *inlink, AVFrame *in) int value[4] = { 0 }; s->pick_color(&s->draw, &color, in, x + s->x, y + s->y, value); - ff_fill_rectangle(&s->draw, &color, in->data, in->linesize, + ff_fill_rectangle(&s->draw, &color, out->data, out->linesize, x * w + (s->ww - 4 - (s->w * w)) / 2 + X, y * h + 2 + Y, w, h); for (i = 0; i < 4; i++) { rms[i] += (double)value[i] * (double)value[i]; @@ -563,36 +569,36 @@ static int pixscope_filter_frame(AVFilterLink *inlink, AVFrame *in) } } - ff_blend_rectangle(&s->draw, &s->black, in->data, in->linesize, - in->width, in->height, + ff_blend_rectangle(&s->draw, &s->black, out->data, out->linesize, + out->width, out->height, s->x - 2, s->y - 2, s->w + 4, 1); - ff_blend_rectangle(&s->draw, &s->white, in->data, in->linesize, - in->width, in->height, + ff_blend_rectangle(&s->draw, &s->white, out->data, out->linesize, + out->width, out->height, s->x - 1, s->y - 1, s->w + 2, 1); - ff_blend_rectangle(&s->draw, &s->white, in->data, in->linesize, - in->width, in->height, + ff_blend_rectangle(&s->draw, &s->white, out->data, out->linesize, + out->width, out->height, s->x - 1, s->y - 1, 1, s->h + 2); - ff_blend_rectangle(&s->draw, &s->black, in->data, in->linesize, - in->width, in->height, + ff_blend_rectangle(&s->draw, &s->black, out->data, out->linesize, + out->width, out->height, s->x - 2, s->y - 2, 1, s->h + 4); - ff_blend_rectangle(&s->draw, &s->white, in->data, in->linesize, - in->width, in->height, + ff_blend_rectangle(&s->draw, &s->white, out->data, out->linesize, + out->width, out->height, s->x - 1, s->y + 1 + s->h, s->w + 3, 1); - ff_blend_rectangle(&s->draw, &s->black, in->data, in->linesize, - in->width, in->height, + ff_blend_rectangle(&s->draw, &s->black, out->data, out->linesize, + out->width, out->height, s->x - 2, s->y + 2 + s->h, s->w + 4, 1); - ff_blend_rectangle(&s->draw, &s->white, in->data, in->linesize, - in->width, in->height, + ff_blend_rectangle(&s->draw, &s->white, out->data, out->linesize, + out->width, out->height, s->x + 1 + s->w, s->y - 1, 1, s->h + 2); - ff_blend_rectangle(&s->draw, &s->black, in->data, in->linesize, - in->width, in->height, + ff_blend_rectangle(&s->draw, &s->black, out->data, out->linesize, + out->width, out->height, s->x + 2 + s->w, s->y - 2, 1, s->h + 5); for (i = 0; i < 4; i++) { @@ -602,15 +608,16 @@ static int pixscope_filter_frame(AVFilterLink *inlink, AVFrame *in) } snprintf(text, sizeof(text), "CH AVG MIN MAX RMS\n"); - draw_text(&s->draw, in, &s->white, X + 28, Y + s->ww + 20, text, 0); + draw_text(&s->draw, out, &s->white, X + 28, Y + s->ww + 20, text, 0); for (i = 0; i < s->nb_comps; i++) { int c = s->rgba_map[i]; snprintf(text, sizeof(text), "%c %07.1f %05d %05d %07.1f\n", s->is_rgb ? rgba[i] : yuva[i], average[c], min[c], max[c], rms[c]); - draw_text(&s->draw, in, s->colors[i], X + 28, Y + s->ww + 20 * (i + 2), text, 0); + draw_text(&s->draw, out, s->colors[i], X + 28, Y + s->ww + 20 * (i + 2), text, 0); } - return ff_filter_frame(outlink, in); + av_frame_free(&in); + return ff_filter_frame(outlink, out); } static const AVFilterPad pixscope_inputs[] = { @@ -619,7 +626,6 @@ static const AVFilterPad pixscope_inputs[] = { .type = AVMEDIA_TYPE_VIDEO, .filter_frame = pixscope_filter_frame, .config_props = pixscope_config_input, - .needs_writable = 1, }, { NULL } }; From 14604087031d5cb93f8513a8835be67d72547b4a Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Fri, 7 Jul 2017 17:42:57 -0400 Subject: [PATCH 2765/3374] Add single precision planar RGB pixel formats Add a pixel format flag to identify this family. Signed-off-by: Vittorio Giovara --- doc/APIchanges | 3 ++ libavutil/pixdesc.c | 54 ++++++++++++++++++++++++++++++++ libavutil/pixdesc.h | 6 ++++ libavutil/pixfmt.h | 7 +++++ libavutil/version.h | 2 +- tests/ref/fate/sws-pixdesc-query | 20 ++++++++++++ 6 files changed, 91 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index c82de684ab220..7babf5babb178 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-08-08 - xxxxxxx - lavu 55.74.100 - pixdesc.h + Add AV_PIX_FMT_FLAG_FLOAT pixel format flag. + 2017-08-08 - xxxxxxx - lavu 55.72.100 - imgutils.h Add av_image_fill_black(). diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index 59587328eaf7b..d45eae5772816 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -2183,6 +2183,60 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { .name = "d3d11", .flags = AV_PIX_FMT_FLAG_HWACCEL, }, + [AV_PIX_FMT_GBRPF32BE] = { + .name = "gbrpf32be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 4, 0, 0, 32, 3, 31, 1 }, /* R */ + { 0, 4, 0, 0, 32, 3, 31, 1 }, /* G */ + { 1, 4, 0, 0, 32, 3, 31, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | + AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_FLOAT, + }, + [AV_PIX_FMT_GBRPF32LE] = { + .name = "gbrpf32le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 4, 0, 0, 32, 3, 31, 1 }, /* R */ + { 0, 4, 0, 0, 32, 3, 31, 1 }, /* G */ + { 1, 4, 0, 0, 32, 3, 31, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_FLOAT | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRAPF32BE] = { + .name = "gbrapf32be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 4, 0, 0, 32, 3, 31, 1 }, /* R */ + { 0, 4, 0, 0, 32, 3, 31, 1 }, /* G */ + { 1, 4, 0, 0, 32, 3, 31, 1 }, /* B */ + { 3, 4, 0, 0, 32, 3, 31, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | + AV_PIX_FMT_FLAG_ALPHA | AV_PIX_FMT_FLAG_RGB | + AV_PIX_FMT_FLAG_FLOAT, + }, + [AV_PIX_FMT_GBRAPF32LE] = { + .name = "gbrapf32le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 4, 0, 0, 32, 3, 31, 1 }, /* R */ + { 0, 4, 0, 0, 32, 3, 31, 1 }, /* G */ + { 1, 4, 0, 0, 32, 3, 31, 1 }, /* B */ + { 3, 4, 0, 0, 32, 3, 31, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA | + AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_FLOAT, + }, }; #if FF_API_PLUS1_MINUS1 FF_ENABLE_DEPRECATION_WARNINGS diff --git a/libavutil/pixdesc.h b/libavutil/pixdesc.h index c3a6f27f49e1f..b0ec81b81bc3b 100644 --- a/libavutil/pixdesc.h +++ b/libavutil/pixdesc.h @@ -177,6 +177,12 @@ typedef struct AVPixFmtDescriptor { */ #define AV_PIX_FMT_FLAG_BAYER (1 << 8) +/** + * The pixel format contains IEEE-754 floating point values. Precision (double, + * single, or half) should be determined by the pixel size (64, 32, or 16 bits). + */ +#define AV_PIX_FMT_FLAG_FLOAT (1 << 9) + /** * Return the number of bits per pixel used by the pixel format * described by pixdesc. Note that this is not the same as the number diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index d4a39dcc01329..6dd094376f2bb 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -329,6 +329,11 @@ enum AVPixelFormat { AV_PIX_FMT_GRAY9BE, ///< Y , 9bpp, big-endian AV_PIX_FMT_GRAY9LE, ///< Y , 9bpp, little-endian + AV_PIX_FMT_GBRPF32BE, ///< IEEE-754 single precision planar GBR 4:4:4, 96bpp, big-endian + AV_PIX_FMT_GBRPF32LE, ///< IEEE-754 single precision planar GBR 4:4:4, 96bpp, little-endian + AV_PIX_FMT_GBRAPF32BE, ///< IEEE-754 single precision planar GBRA 4:4:4:4, 128bpp, big-endian + AV_PIX_FMT_GBRAPF32LE, ///< IEEE-754 single precision planar GBRA 4:4:4:4, 128bpp, little-endian + AV_PIX_FMT_NB ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions }; @@ -393,6 +398,8 @@ enum AVPixelFormat { #define AV_PIX_FMT_BAYER_GBRG16 AV_PIX_FMT_NE(BAYER_GBRG16BE, BAYER_GBRG16LE) #define AV_PIX_FMT_BAYER_GRBG16 AV_PIX_FMT_NE(BAYER_GRBG16BE, BAYER_GRBG16LE) +#define AV_PIX_FMT_GBRPF32 AV_PIX_FMT_NE(GBRPF32BE, GBRPF32LE) +#define AV_PIX_FMT_GBRAPF32 AV_PIX_FMT_NE(GBRAPF32BE, GBRAPF32LE) #define AV_PIX_FMT_YUVA420P9 AV_PIX_FMT_NE(YUVA420P9BE , YUVA420P9LE) #define AV_PIX_FMT_YUVA422P9 AV_PIX_FMT_NE(YUVA422P9BE , YUVA422P9LE) diff --git a/libavutil/version.h b/libavutil/version.h index 02461ae0b2c4a..6e25b4690c7c0 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -80,7 +80,7 @@ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 73 +#define LIBAVUTIL_VERSION_MINOR 74 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ diff --git a/tests/ref/fate/sws-pixdesc-query b/tests/ref/fate/sws-pixdesc-query index 9510b4ee0e0b3..0adfdcaf98592 100644 --- a/tests/ref/fate/sws-pixdesc-query +++ b/tests/ref/fate/sws-pixdesc-query @@ -112,11 +112,13 @@ isBE: gbrap10be gbrap12be gbrap16be + gbrapf32be gbrp10be gbrp12be gbrp14be gbrp16be gbrp9be + gbrpf32be gray10be gray12be gray16be @@ -362,6 +364,8 @@ isRGB: gbrap12le gbrap16be gbrap16le + gbrapf32be + gbrapf32le gbrp gbrp10be gbrp10le @@ -373,6 +377,8 @@ isRGB: gbrp16le gbrp9be gbrp9le + gbrpf32be + gbrpf32le rgb0 rgb24 rgb32 @@ -498,6 +504,8 @@ AnyRGB: gbrap12le gbrap16be gbrap16le + gbrapf32be + gbrapf32le gbrp gbrp10be gbrp10le @@ -509,6 +517,8 @@ AnyRGB: gbrp16le gbrp9be gbrp9le + gbrpf32be + gbrpf32le monob monow rgb0 @@ -543,6 +553,8 @@ ALPHA: gbrap12le gbrap16be gbrap16le + gbrapf32be + gbrapf32le pal8 rgb32 rgb32_1 @@ -645,6 +657,8 @@ Planar: gbrap12le gbrap16be gbrap16le + gbrapf32be + gbrapf32le gbrp gbrp10be gbrp10le @@ -656,6 +670,8 @@ Planar: gbrp16le gbrp9be gbrp9le + gbrpf32be + gbrpf32le nv12 nv16 nv20be @@ -790,6 +806,8 @@ PlanarRGB: gbrap12le gbrap16be gbrap16le + gbrapf32be + gbrapf32le gbrp gbrp10be gbrp10le @@ -801,6 +819,8 @@ PlanarRGB: gbrp16le gbrp9be gbrp9le + gbrpf32be + gbrpf32le usePal: bgr4_byte From 8b9ae9a8e03ca4f24edf9fc34779fbf365092cb0 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Mon, 10 Jul 2017 11:21:30 -0400 Subject: [PATCH 2766/3374] zscale: Enable single precision input/ouput filtering Signed-off-by: Vittorio Giovara --- libavfilter/vf_zscale.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/libavfilter/vf_zscale.c b/libavfilter/vf_zscale.c index 466689dbc5410..c303dd4d63dc7 100644 --- a/libavfilter/vf_zscale.c +++ b/libavfilter/vf_zscale.c @@ -36,6 +36,7 @@ #include "libavutil/avstring.h" #include "libavutil/eval.h" #include "libavutil/internal.h" +#include "libavutil/intreadwrite.h" #include "libavutil/mathematics.h" #include "libavutil/opt.h" #include "libavutil/parseutils.h" @@ -179,6 +180,7 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP16, + AV_PIX_FMT_GBRPF32, AV_PIX_FMT_GBRAPF32, AV_PIX_FMT_NONE }; int ret; @@ -429,7 +431,7 @@ static void format_init(zimg_image_format *format, AVFrame *frame, const AVPixFm format->subsample_w = desc->log2_chroma_w; format->subsample_h = desc->log2_chroma_h; format->depth = desc->comp[0].depth; - format->pixel_type = desc->comp[0].depth > 8 ? ZIMG_PIXEL_WORD : ZIMG_PIXEL_BYTE; + format->pixel_type = (desc->flags & AV_PIX_FMT_FLAG_FLOAT) ? ZIMG_PIXEL_FLOAT : desc->comp[0].depth > 8 ? ZIMG_PIXEL_WORD : ZIMG_PIXEL_BYTE; format->color_family = (desc->flags & AV_PIX_FMT_FLAG_RGB) ? ZIMG_COLOR_RGB : ZIMG_COLOR_YUV; format->matrix_coefficients = (desc->flags & AV_PIX_FMT_FLAG_RGB) ? ZIMG_MATRIX_RGB : colorspace == -1 ? convert_matrix(frame->colorspace) : colorspace; format->color_primaries = primaries == -1 ? convert_primaries(frame->color_primaries) : primaries; @@ -573,13 +575,13 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) s->alpha_src_format.width = in->width; s->alpha_src_format.height = in->height; s->alpha_src_format.depth = desc->comp[0].depth; - s->alpha_src_format.pixel_type = desc->comp[0].depth > 8 ? ZIMG_PIXEL_WORD : ZIMG_PIXEL_BYTE; + s->alpha_src_format.pixel_type = (desc->flags & AV_PIX_FMT_FLAG_FLOAT) ? ZIMG_PIXEL_FLOAT : desc->comp[0].depth > 8 ? ZIMG_PIXEL_WORD : ZIMG_PIXEL_BYTE; s->alpha_src_format.color_family = ZIMG_COLOR_GREY; s->alpha_dst_format.width = out->width; s->alpha_dst_format.height = out->height; s->alpha_dst_format.depth = odesc->comp[0].depth; - s->alpha_dst_format.pixel_type = odesc->comp[0].depth > 8 ? ZIMG_PIXEL_WORD : ZIMG_PIXEL_BYTE; + s->alpha_dst_format.pixel_type = (desc->flags & AV_PIX_FMT_FLAG_FLOAT) ? ZIMG_PIXEL_FLOAT : odesc->comp[0].depth > 8 ? ZIMG_PIXEL_WORD : ZIMG_PIXEL_BYTE; s->alpha_dst_format.color_family = ZIMG_COLOR_GREY; zimg_filter_graph_free(s->alpha_graph); @@ -641,10 +643,19 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) goto fail; } } else if (odesc->flags & AV_PIX_FMT_FLAG_ALPHA) { - int y; - - for (y = 0; y < outlink->h; y++) - memset(out->data[3] + y * out->linesize[3], 0xff, outlink->w); + int x, y; + + if (odesc->flags & AV_PIX_FMT_FLAG_FLOAT) { + for (y = 0; y < out->height; y++) { + for (x = 0; x < out->width; x++) { + AV_WN32(out->data[3] + x * odesc->comp[3].step + y * out->linesize[3], + av_float2int(1.0f)); + } + } + } else { + for (y = 0; y < outlink->h; y++) + memset(out->data[3] + y * out->linesize[3], 0xff, outlink->w); + } } fail: From 62dfa2ba14d9adbf88e8748a7e1c5ce68f0f8fa8 Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Mon, 10 Jul 2017 10:34:30 -0400 Subject: [PATCH 2767/3374] Add tonemap filter Based off mpv automatic tonemapping capabilities. Signed-off-by: Vittorio Giovara --- doc/filters.texi | 108 ++++++++++++ libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/version.h | 2 +- libavfilter/vf_tonemap.c | 354 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 465 insertions(+), 1 deletion(-) create mode 100644 libavfilter/vf_tonemap.c diff --git a/doc/filters.texi b/doc/filters.texi index 8b0c6d920bbdf..502ebd5e452d5 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -14442,6 +14442,113 @@ Vertical low-pass filtering can only be enabled for @option{mode} @end table +@section tonemap +Tone map colors from different dynamic ranges. + +This filter expects data in single precision floating point, as it needs to +operate on (and can output) out-of-range values. Another filter, such as +@ref{zscale}, is needed to convert the resulting frame to a usable format. + +The tonemapping algorithms implemented only work on linear light, so input +data should be linearized beforehand (and possibly correctly tagged). + +@example +ffmpeg -i INPUT -vf zscale=transfer=linear,tonemap=clip,zscale=transfer=bt709,format=yuv420p OUTPUT +@end example + +@subsection Options +The filter accepts the following options. + +@table @option +@item tonemap +Set the tone map algorithm to use. + +Possible values are: +@table @var +@item none +Do not apply any tone map, only desaturate overbright pixels. + +@item clip +Hard-clip any out-of-range values. Use it for perfect color accuracy for +in-range values, while distorting out-of-range values. + +@item linear +Stretch the entire reference gamut to a linear multiple of the display. + +@item gamma +Fit a logarithmic transfer between the tone curves. + +@item reinhard +Preserve overall image brightness with a simple curve, using nonlinear +contrast, which results in flattening details and degrading color accuracy. + +@item hable +Peserve both dark and bright details better than @var{reinhard}, at the cost +of slightly darkening everything. Use it when detail preservation is more +important than color and brightness accuracy. + +@item mobius +Smoothly map out-of-range values, while retaining contrast and colors for +in-range material as much as possible. Use it when color accuracy is more +important than detail preservation. +@end table + +Default is none. + +@item param +Tune the tone mapping algorithm. + +This affects the following algorithms: +@table @var +@item none +Ignored. + +@item linear +Specifies the scale factor to use while stretching. +Default to 1.0. + +@item gamma +Specifies the exponent of the function. +Default to 1.8. + +@item clip +Specify an extra linear coefficient to multiply into the signal before clipping. +Default to 1.0. + +@item reinhard +Specify the local contrast coefficient at the display peak. +Default to 0.5, which means that in-gamut values will be about half as bright +as when clipping. + +@item hable +Ignored. + +@item mobius +Specify the transition point from linear to mobius transform. Every value +below this point is guaranteed to be mapped 1:1. The higher the value, the +more accurate the result will be, at the cost of losing bright details. +Default to 0.3, which due to the steep initial slope still preserves in-range +colors fairly accurately. +@end table + +@item desat +Apply desaturation for highlights that exceed this level of brightness. The +higher the parameter, the more color information will be preserved. This +setting helps prevent unnaturally blown-out colors for super-highlights, by +(smoothly) turning into white instead. This makes images feel more natural, +at the cost of reducing information about out-of-range colors. + +The default of 2.0 is somewhat conservative and will mostly just apply to +skies or directly sunlit surfaces. A setting of 0.0 disables this option. + +This option works only if the input frame has a supported color tag. + +@item peak +Override signal/nominal/reference peak with this value. Useful when the +embedded peak information in display metadata is not reliable or when tone +mapping from a lower range to a higher range. +@end table + @section transpose Transpose rows with columns in the input video and optionally flip it. @@ -15627,6 +15734,7 @@ zoompan=z='min(max(zoom,pzoom)+0.0015,1.5)':d=1:x='iw/2-(iw/zoom/2)':y='ih/2-(ih @end example @end itemize +@anchor{zscale} @section zscale Scale (resize) the input video, using the z.lib library: https://github.com/sekrit-twc/zimg. diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 06b915fc91f01..545b871cd7020 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -314,6 +314,7 @@ OBJS-$(CONFIG_THUMBNAIL_FILTER) += vf_thumbnail.o OBJS-$(CONFIG_TILE_FILTER) += vf_tile.o OBJS-$(CONFIG_TINTERLACE_FILTER) += vf_tinterlace.o OBJS-$(CONFIG_TLUT2_FILTER) += vf_lut2.o framesync2.o +OBJS-$(CONFIG_TONEMAP_FILTER) += vf_tonemap.o OBJS-$(CONFIG_TRANSPOSE_FILTER) += vf_transpose.o OBJS-$(CONFIG_TRIM_FILTER) += trim.o OBJS-$(CONFIG_UNPREMULTIPLY_FILTER) += vf_premultiply.o framesync2.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index e58c0d5c82754..f1dacaffa86ff 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -325,6 +325,7 @@ static void register_all(void) REGISTER_FILTER(TILE, tile, vf); REGISTER_FILTER(TINTERLACE, tinterlace, vf); REGISTER_FILTER(TLUT2, tlut2, vf); + REGISTER_FILTER(TONEMAP, tonemap, vf); REGISTER_FILTER(TRANSPOSE, transpose, vf); REGISTER_FILTER(TRIM, trim, vf); REGISTER_FILTER(UNPREMULTIPLY, unpremultiply, vf); diff --git a/libavfilter/version.h b/libavfilter/version.h index 1d37fd8e4b155..5efb648c6d1c3 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 6 -#define LIBAVFILTER_VERSION_MINOR 98 +#define LIBAVFILTER_VERSION_MINOR 99 #define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vf_tonemap.c b/libavfilter/vf_tonemap.c new file mode 100644 index 0000000000000..10308bdb16cf2 --- /dev/null +++ b/libavfilter/vf_tonemap.c @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2017 Vittorio Giovara + * + * 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 + */ + +/** + * @file + * tonemap algorithms + */ + +#include +#include +#include + +#include "libavutil/imgutils.h" +#include "libavutil/internal.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/mastering_display_metadata.h" +#include "libavutil/opt.h" +#include "libavutil/pixdesc.h" + +#include "avfilter.h" +#include "formats.h" +#include "internal.h" +#include "video.h" + +#define REFERENCE_WHITE 100.0f + +enum TonemapAlgorithm { + TONEMAP_NONE, + TONEMAP_LINEAR, + TONEMAP_GAMMA, + TONEMAP_CLIP, + TONEMAP_REINHARD, + TONEMAP_HABLE, + TONEMAP_MOBIUS, + TONEMAP_MAX, +}; + +typedef struct LumaCoefficients { + double cr, cg, cb; +} LumaCoefficients; + + +static const struct LumaCoefficients luma_coefficients[AVCOL_SPC_NB] = { + [AVCOL_SPC_FCC] = { 0.30, 0.59, 0.11 }, + [AVCOL_SPC_BT470BG] = { 0.299, 0.587, 0.114 }, + [AVCOL_SPC_SMPTE170M] = { 0.299, 0.587, 0.114 }, + [AVCOL_SPC_BT709] = { 0.2126, 0.7152, 0.0722 }, + [AVCOL_SPC_SMPTE240M] = { 0.212, 0.701, 0.087 }, + [AVCOL_SPC_BT2020_NCL] = { 0.2627, 0.6780, 0.0593 }, + [AVCOL_SPC_BT2020_CL] = { 0.2627, 0.6780, 0.0593 }, +}; + +typedef struct TonemapContext { + const AVClass *class; + + enum TonemapAlgorithm tonemap; + double param; + double desat; + double peak; + + const LumaCoefficients *coeffs; +} TonemapContext; + +static const enum AVPixelFormat pix_fmts[] = { + AV_PIX_FMT_GBRPF32, + AV_PIX_FMT_GBRAPF32, + AV_PIX_FMT_NONE, +}; + +static int query_formats(AVFilterContext *ctx) +{ + return ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); +} + +static av_cold int init(AVFilterContext *ctx) +{ + TonemapContext *s = ctx->priv; + + switch(s->tonemap) { + case TONEMAP_GAMMA: + if (isnan(s->param)) + s->param = 1.8f; + break; + case TONEMAP_REINHARD: + if (!isnan(s->param)) + s->param = (1.0f - s->param) / s->param; + break; + case TONEMAP_MOBIUS: + if (isnan(s->param)) + s->param = 0.3f; + break; + } + + if (isnan(s->param)) + s->param = 1.0f; + + return 0; +} + +static double determine_signal_peak(AVFrame *in) +{ + AVFrameSideData *sd = av_frame_get_side_data(in, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL); + double peak = 0; + + if (sd) { + AVContentLightMetadata *clm = (AVContentLightMetadata *)sd->data; + peak = clm->MaxCLL / REFERENCE_WHITE; + } + + sd = av_frame_get_side_data(in, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA); + if (!peak && sd) { + AVMasteringDisplayMetadata *metadata = (AVMasteringDisplayMetadata *)sd->data; + if (metadata->has_luminance) + peak = av_q2d(metadata->max_luminance) / REFERENCE_WHITE; + } + + /* smpte2084 needs the side data above to work correctly + * if missing, assume that the original transfer was arib-std-b67 */ + if (!peak) + peak = 12; + + return peak; +} + +static float hable(float in) +{ + float a = 0.15f, b = 0.50f, c = 0.10f, d = 0.20f, e = 0.02f, f = 0.30f; + return (in * (in * a + b * c) + d * e) / (in * (in * a + b) + d * f) - e / f; +} + +static float mobius(float in, float j, double peak) +{ + float a, b; + + if (in <= j) + return in; + + a = -j * j * (peak - 1.0f) / (j * j - 2.0f * j + peak); + b = (j * j - 2.0f * j * peak + peak) / FFMAX(peak - 1.0f, 1e-6); + + return (b * b + 2.0f * b * j + j * j) / (b - a) * (in + a) / (in + b); +} + +#define MIX(x,y,a) (x) * (1 - (a)) + (y) * (a) +static void tonemap(TonemapContext *s, AVFrame *out, const AVFrame *in, + const AVPixFmtDescriptor *desc, int x, int y, double peak) +{ + const float *r_in = (const float *)(in->data[0] + x * desc->comp[0].step + y * in->linesize[0]); + const float *b_in = (const float *)(in->data[1] + x * desc->comp[1].step + y * in->linesize[1]); + const float *g_in = (const float *)(in->data[2] + x * desc->comp[2].step + y * in->linesize[2]); + float *r_out = (float *)(out->data[0] + x * desc->comp[0].step + y * out->linesize[0]); + float *b_out = (float *)(out->data[1] + x * desc->comp[1].step + y * out->linesize[1]); + float *g_out = (float *)(out->data[2] + x * desc->comp[2].step + y * out->linesize[2]); + float sig, sig_orig; + + /* load values */ + *r_out = *r_in; + *b_out = *b_in; + *g_out = *g_in; + + /* desaturate to prevent unnatural colors */ + if (s->desat > 0) { + float luma = s->coeffs->cr * *r_in + s->coeffs->cg * *g_in + s->coeffs->cb * *b_in; + float overbright = FFMAX(luma - s->desat, 1e-6) / FFMAX(luma, 1e-6); + *r_out = MIX(*r_in, luma, overbright); + *g_out = MIX(*g_in, luma, overbright); + *b_out = MIX(*b_in, luma, overbright); + } + + /* pick the brightest component, reducing the value range as necessary + * to keep the entire signal in range and preventing discoloration due to + * out-of-bounds clipping */ + sig = FFMAX(FFMAX3(*r_out, *g_out, *b_out), 1e-6); + sig_orig = sig; + + switch(s->tonemap) { + default: + case TONEMAP_NONE: + // do nothing + break; + case TONEMAP_LINEAR: + sig = sig * s->param / peak; + break; + case TONEMAP_GAMMA: + sig = sig > 0.05f ? pow(sig / peak, 1.0f / s->param) + : sig * pow(0.05f / peak, 1.0f / s->param) / 0.05f; + break; + case TONEMAP_CLIP: + sig = av_clipf(sig * s->param, 0, 1.0f); + break; + case TONEMAP_HABLE: + sig = hable(sig) / hable(peak); + break; + case TONEMAP_REINHARD: + sig = sig / (sig + s->param) * (peak + s->param) / peak; + break; + case TONEMAP_MOBIUS: + sig = mobius(sig, s->param, peak); + break; + } + + /* apply the computed scale factor to the color, + * linearly to prevent discoloration */ + *r_out *= sig / sig_orig; + *g_out *= sig / sig_orig; + *b_out *= sig / sig_orig; +} + +static int filter_frame(AVFilterLink *link, AVFrame *in) +{ + TonemapContext *s = link->dst->priv; + AVFilterLink *outlink = link->dst->outputs[0]; + AVFrame *out; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format); + const AVPixFmtDescriptor *odesc = av_pix_fmt_desc_get(outlink->format); + int ret, x, y; + double peak = s->peak; + + if (!desc || !odesc) { + av_frame_free(&in); + return AVERROR_BUG; + } + + out = ff_get_video_buffer(outlink, outlink->w, outlink->h); + if (!out) { + av_frame_free(&in); + return AVERROR(ENOMEM); + } + + ret = av_frame_copy_props(out, in); + if (ret < 0) { + av_frame_free(&in); + av_frame_free(&out); + return ret; + } + + /* input and output transfer will be linear */ + if (in->color_trc == AVCOL_TRC_UNSPECIFIED) { + av_log(s, AV_LOG_WARNING, "Untagged transfer, assuming linear light\n"); + out->color_trc = AVCOL_TRC_LINEAR; + } else if (in->color_trc != AVCOL_TRC_LINEAR) + av_log(s, AV_LOG_WARNING, "Tonemapping works on linear light only\n"); + + /* read peak from side data if not passed in */ + if (!peak) { + peak = determine_signal_peak(in); + av_log(s, AV_LOG_DEBUG, "Computed signal peak: %f\n", peak); + } + + /* load original color space even if pixel format is RGB to compute overbrights */ + s->coeffs = &luma_coefficients[in->colorspace]; + if (s->desat > 0 && (in->colorspace == AVCOL_SPC_UNSPECIFIED || !s->coeffs)) { + if (in->colorspace == AVCOL_SPC_UNSPECIFIED) + av_log(s, AV_LOG_WARNING, "Missing color space information, "); + else if (!s->coeffs) + av_log(s, AV_LOG_WARNING, "Unsupported color space '%s', ", + av_color_space_name(in->colorspace)); + av_log(s, AV_LOG_WARNING, "desaturation is disabled\n"); + s->desat = 0; + } + + /* do the tone map */ + for (y = 0; y < out->height; y++) + for (x = 0; x < out->width; x++) + tonemap(s, out, in, desc, x, y, peak); + + /* copy/generate alpha if needed */ + if (desc->flags & AV_PIX_FMT_FLAG_ALPHA && odesc->flags & AV_PIX_FMT_FLAG_ALPHA) { + av_image_copy_plane(out->data[3], out->linesize[3], + in->data[3], in->linesize[3], + out->linesize[3], outlink->h); + } else if (odesc->flags & AV_PIX_FMT_FLAG_ALPHA) { + for (y = 0; y < out->height; y++) { + for (x = 0; x < out->width; x++) { + AV_WN32(out->data[3] + x * odesc->comp[3].step + y * out->linesize[3], + av_float2int(1.0f)); + } + } + } + + av_frame_free(&in); + + return ff_filter_frame(outlink, out); +} + +#define OFFSET(x) offsetof(TonemapContext, x) +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM +static const AVOption tonemap_options[] = { + { "tonemap", "tonemap algorithm selection", OFFSET(tonemap), AV_OPT_TYPE_INT, {.i64 = TONEMAP_NONE}, TONEMAP_NONE, TONEMAP_MAX - 1, FLAGS, "tonemap" }, + { "none", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_NONE}, 0, 0, FLAGS, "tonemap" }, + { "linear", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_LINEAR}, 0, 0, FLAGS, "tonemap" }, + { "gamma", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_GAMMA}, 0, 0, FLAGS, "tonemap" }, + { "clip", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_CLIP}, 0, 0, FLAGS, "tonemap" }, + { "reinhard", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_REINHARD}, 0, 0, FLAGS, "tonemap" }, + { "hable", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_HABLE}, 0, 0, FLAGS, "tonemap" }, + { "mobius", 0, 0, AV_OPT_TYPE_CONST, {.i64 = TONEMAP_MOBIUS}, 0, 0, FLAGS, "tonemap" }, + { "param", "tonemap parameter", OFFSET(param), AV_OPT_TYPE_DOUBLE, {.dbl = NAN}, DBL_MIN, DBL_MAX, FLAGS }, + { "desat", "desaturation strength", OFFSET(desat), AV_OPT_TYPE_DOUBLE, {.dbl = 2}, 0, DBL_MAX, FLAGS }, + { "peak", "signal peak override", OFFSET(peak), AV_OPT_TYPE_DOUBLE, {.dbl = 0}, 0, DBL_MAX, FLAGS }, + { NULL } +}; + +static const AVClass tonemap_class = { + .class_name = "tonemap", + .item_name = av_default_item_name, + .option = tonemap_options, + .version = LIBAVUTIL_VERSION_INT, + .category = AV_CLASS_CATEGORY_FILTER, +}; + +static const AVFilterPad tonemap_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .filter_frame = filter_frame, + }, + { NULL } +}; + +static const AVFilterPad tonemap_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + }, + { NULL } +}; + +AVFilter ff_vf_tonemap = { + .name = "tonemap", + .description = NULL_IF_CONFIG_SMALL("Conversion to/from different dynamic ranges."), + .init = init, + .query_formats = query_formats, + .priv_size = sizeof(TonemapContext), + .priv_class = &tonemap_class, + .inputs = tonemap_inputs, + .outputs = tonemap_outputs, +}; From 0ac8fce2679e76e7caffde091141d6834405dbc1 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 15 Aug 2017 14:58:25 +0200 Subject: [PATCH 2768/3374] swresample/resample: Fix flush refelction length Reviewed-by: atomnuker Signed-off-by: Michael Niedermayer --- libswresample/resample.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libswresample/resample.c b/libswresample/resample.c index 39c242bf413d7..df49505bf9505 100644 --- a/libswresample/resample.c +++ b/libswresample/resample.c @@ -544,18 +544,21 @@ static int64_t get_out_samples(struct SwrContext *s, int in_samples) { } static int resample_flush(struct SwrContext *s) { + ResampleContext *c = s->resample; AudioData *a= &s->in_buffer; int i, j, ret; - if((ret = swri_realloc_audio(a, s->in_buffer_index + 2*s->in_buffer_count)) < 0) + int reflection = (FFMIN(s->in_buffer_count, c->filter_length) + 1) / 2; + + if((ret = swri_realloc_audio(a, s->in_buffer_index + s->in_buffer_count + reflection)) < 0) return ret; av_assert0(a->planar); for(i=0; ich_count; i++){ - for(j=0; jin_buffer_count; j++){ + for(j=0; jch[i] + (s->in_buffer_index+s->in_buffer_count+j )*a->bps, a->ch[i] + (s->in_buffer_index+s->in_buffer_count-j-1)*a->bps, a->bps); } } - s->in_buffer_count += (s->in_buffer_count+1)/2; + s->in_buffer_count += reflection; return 0; } From 4b54d5a721cc55288093417b098382bbb27a8d3f Mon Sep 17 00:00:00 2001 From: Nikolas Bowe Date: Tue, 15 Aug 2017 12:08:44 -0700 Subject: [PATCH 2769/3374] avformat/mov: Fix memory leak when reading DDTS box. Signed-off-by: Michael Niedermayer --- libavformat/mov.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavformat/mov.c b/libavformat/mov.c index 63f84be782fde..c02caf6719bc3 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -889,6 +889,7 @@ static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom) init_get_bits(&gb, buf, 8*ddts_size); if (c->fc->nb_streams < 1) { + av_free(buf); return 0; } st = c->fc->streams[c->fc->nb_streams-1]; @@ -896,6 +897,7 @@ static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom) st->codecpar->sample_rate = get_bits_long(&gb, 32); if (st->codecpar->sample_rate <= 0) { av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate); + av_free(buf); return AVERROR_INVALIDDATA; } skip_bits_long(&gb, 32); /* max bitrate */ @@ -923,6 +925,7 @@ static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom) ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0); st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout); + av_free(buf); return 0; } From cbd8e070561b0bec6ecf22dfd8e4db91824e8b07 Mon Sep 17 00:00:00 2001 From: Leo Izen Date: Thu, 10 Aug 2017 12:40:23 -0400 Subject: [PATCH 2770/3374] encoders.texi: Replace x264 --full-help suggestion with --fullhelp Reviewed-by: Steven Liu Signed-off-by: Michael Niedermayer --- doc/encoders.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/encoders.texi b/doc/encoders.texi index 690cca83dc93e..f20be54ce84f1 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -1793,7 +1793,7 @@ the documentation of the undocumented generic options, see @ref{codec-options,,the Codec Options chapter}. To get a more accurate and extensive documentation of the libx264 -options, invoke the command @command{x264 --full-help} or consult +options, invoke the command @command{x264 --fullhelp} or consult the libx264 documentation. @table @option From 7b19e76aeb0ace57b99aaef156bbfe592e43e65e Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Tue, 15 Aug 2017 20:12:32 +0200 Subject: [PATCH 2771/3374] avfilter/vf_transpose: rewrite for x86 SIMD Transpose first in chunks of 8x8 blocks. 15% faster overall. --- libavfilter/vf_transpose.c | 182 ++++++++++++++++++++++++++++--------- 1 file changed, 141 insertions(+), 41 deletions(-) diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c index 75b4dda41f4b3..982fb0c8ca496 100644 --- a/libavfilter/vf_transpose.c +++ b/libavfilter/vf_transpose.c @@ -58,6 +58,12 @@ typedef struct TransContext { int passthrough; ///< PassthroughType, landscape passthrough mode enabled int dir; ///< TransposeDir + + void (*transpose_8x8)(uint8_t *src, ptrdiff_t src_linesize, + uint8_t *dst, ptrdiff_t dst_linesize); + void (*transpose_block)(uint8_t *src, ptrdiff_t src_linesize, + uint8_t *dst, ptrdiff_t dst_linesize, + int w, int h); } TransContext; static int query_formats(AVFilterContext *ctx) @@ -79,6 +85,109 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_formats(ctx, pix_fmts); } +static inline void transpose_block_8_c(uint8_t *src, ptrdiff_t src_linesize, + uint8_t *dst, ptrdiff_t dst_linesize, + int w, int h) +{ + int x, y; + for (y = 0; y < h; y++, dst += dst_linesize, src++) + for (x = 0; x < w; x++) + dst[x] = src[x*src_linesize]; +} + +static void transpose_8x8_8_c(uint8_t *src, ptrdiff_t src_linesize, + uint8_t *dst, ptrdiff_t dst_linesize) +{ + transpose_block_8_c(src, src_linesize, dst, dst_linesize, 8, 8); +} + +static inline void transpose_block_16_c(uint8_t *src, ptrdiff_t src_linesize, + uint8_t *dst, ptrdiff_t dst_linesize, + int w, int h) +{ + int x, y; + for (y = 0; y < h; y++, dst += dst_linesize, src += 2) + for (x = 0; x < w; x++) + *((uint16_t *)(dst + 2*x)) = *((uint16_t *)(src + x*src_linesize)); +} + +static void transpose_8x8_16_c(uint8_t *src, ptrdiff_t src_linesize, + uint8_t *dst, ptrdiff_t dst_linesize) +{ + transpose_block_16_c(src, src_linesize, dst, dst_linesize, 8, 8); +} + +static inline void transpose_block_24_c(uint8_t *src, ptrdiff_t src_linesize, + uint8_t *dst, ptrdiff_t dst_linesize, + int w, int h) +{ + int x, y; + for (y = 0; y < h; y++, dst += dst_linesize) { + for (x = 0; x < w; x++) { + int32_t v = AV_RB24(src + x*src_linesize + y*3); + AV_WB24(dst + 3*x, v); + } + } +} + +static void transpose_8x8_24_c(uint8_t *src, ptrdiff_t src_linesize, + uint8_t *dst, ptrdiff_t dst_linesize) +{ + transpose_block_24_c(src, src_linesize, dst, dst_linesize, 8, 8); +} + +static inline void transpose_block_32_c(uint8_t *src, ptrdiff_t src_linesize, + uint8_t *dst, ptrdiff_t dst_linesize, + int w, int h) +{ + int x, y; + for (y = 0; y < h; y++, dst += dst_linesize, src += 4) { + for (x = 0; x < w; x++) + *((uint32_t *)(dst + 4*x)) = *((uint32_t *)(src + x*src_linesize)); + } +} + +static void transpose_8x8_32_c(uint8_t *src, ptrdiff_t src_linesize, + uint8_t *dst, ptrdiff_t dst_linesize) +{ + transpose_block_32_c(src, src_linesize, dst, dst_linesize, 8, 8); +} + +static inline void transpose_block_48_c(uint8_t *src, ptrdiff_t src_linesize, + uint8_t *dst, ptrdiff_t dst_linesize, + int w, int h) +{ + int x, y; + for (y = 0; y < h; y++, dst += dst_linesize, src += 6) { + for (x = 0; x < w; x++) { + int64_t v = AV_RB48(src + x*src_linesize); + AV_WB48(dst + 6*x, v); + } + } +} + +static void transpose_8x8_48_c(uint8_t *src, ptrdiff_t src_linesize, + uint8_t *dst, ptrdiff_t dst_linesize) +{ + transpose_block_48_c(src, src_linesize, dst, dst_linesize, 8, 8); +} + +static inline void transpose_block_64_c(uint8_t *src, ptrdiff_t src_linesize, + uint8_t *dst, ptrdiff_t dst_linesize, + int w, int h) +{ + int x, y; + for (y = 0; y < h; y++, dst += dst_linesize, src += 8) + for (x = 0; x < w; x++) + *((uint64_t *)(dst + 8*x)) = *((uint64_t *)(src + x*src_linesize)); +} + +static void transpose_8x8_64_c(uint8_t *src, ptrdiff_t src_linesize, + uint8_t *dst, ptrdiff_t dst_linesize) +{ + transpose_block_64_c(src, src_linesize, dst, dst_linesize, 8, 8); +} + static int config_props_output(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; @@ -118,6 +227,21 @@ static int config_props_output(AVFilterLink *outlink) else outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; + switch (s->pixsteps[0]) { + case 1: s->transpose_block = transpose_block_8_c; + s->transpose_8x8 = transpose_8x8_8_c; break; + case 2: s->transpose_block = transpose_block_16_c; + s->transpose_8x8 = transpose_8x8_16_c; break; + case 3: s->transpose_block = transpose_block_24_c; + s->transpose_8x8 = transpose_8x8_24_c; break; + case 4: s->transpose_block = transpose_block_32_c; + s->transpose_8x8 = transpose_8x8_32_c; break; + case 6: s->transpose_block = transpose_block_48_c; + s->transpose_8x8 = transpose_8x8_48_c; break; + case 8: s->transpose_block = transpose_block_64_c; + s->transpose_8x8 = transpose_8x8_64_c; break; + } + av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d dir:%d -> w:%d h:%d rotation:%s vflip:%d\n", inlink->w, inlink->h, s->dir, outlink->w, outlink->h, @@ -176,49 +300,25 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, dstlinesize *= -1; } - switch (pixstep) { - case 1: - for (y = start; y < end; y++, dst += dstlinesize) - for (x = 0; x < outw; x++) - dst[x] = src[x * srclinesize + y]; - break; - case 2: - for (y = start; y < end; y++, dst += dstlinesize) { - for (x = 0; x < outw; x++) - *((uint16_t *)(dst + 2 * x)) = - *((uint16_t *)(src + x * srclinesize + y * 2)); - } - break; - case 3: - for (y = start; y < end; y++, dst += dstlinesize) { - for (x = 0; x < outw; x++) { - int32_t v = AV_RB24(src + x * srclinesize + y * 3); - AV_WB24(dst + 3 * x, v); - } - } - break; - case 4: - for (y = start; y < end; y++, dst += dstlinesize) { - for (x = 0; x < outw; x++) - *((uint32_t *)(dst + 4 * x)) = - *((uint32_t *)(src + x * srclinesize + y * 4)); + for (y = start; y < end - 7; y += 8) { + for (x = 0; x < outw - 7; x += 8) { + s->transpose_8x8(src + x * srclinesize + y * pixstep, + srclinesize, + dst + (y - start) * dstlinesize + x * pixstep, + dstlinesize); } - break; - case 6: - for (y = start; y < end; y++, dst += dstlinesize) { - for (x = 0; x < outw; x++) { - int64_t v = AV_RB48(src + x * srclinesize + y*6); - AV_WB48(dst + 6*x, v); - } - } - break; - case 8: - for (y = start; y < end; y++, dst += dstlinesize) { - for (x = 0; x < outw; x++) - *((uint64_t *)(dst + 8*x)) = *((uint64_t *)(src + x * srclinesize + y*8)); - } - break; + if (outw - x > 0 && end - y > 0) + s->transpose_block(src + x * srclinesize + y * pixstep, + srclinesize, + dst + (y - start) * dstlinesize + x * pixstep, + dstlinesize, outw - x, end - y); } + + if (end - y > 0) + s->transpose_block(src + 0 * srclinesize + y * pixstep, + srclinesize, + dst + (y - start) * dstlinesize + 0 * pixstep, + dstlinesize, outw, end - y); } return 0; From 16efcfe4138f9e60e01e3d477fd5c2721e060ee0 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Wed, 16 Aug 2017 13:29:34 +0200 Subject: [PATCH 2772/3374] avfilter/vf_weave: fix top vs bottom field order Fixes #6590. --- libavfilter/vf_weave.c | 8 ++++---- tests/fate/filter-video.mak | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libavfilter/vf_weave.c b/libavfilter/vf_weave.c index 6d3dd7c299613..037f5d1cf2064 100644 --- a/libavfilter/vf_weave.c +++ b/libavfilter/vf_weave.c @@ -100,20 +100,20 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) for (i = 0; i < s->nb_planes; i++) { if (s->double_weave && !(inlink->frame_count_out & 1)) { - av_image_copy_plane(out->data[i] + out->linesize[i] * !s->first_field, + av_image_copy_plane(out->data[i] + out->linesize[i] * s->first_field, out->linesize[i] * 2, in->data[i], in->linesize[i], s->linesize[i], s->planeheight[i]); - av_image_copy_plane(out->data[i] + out->linesize[i] * s->first_field, + av_image_copy_plane(out->data[i] + out->linesize[i] * !s->first_field, out->linesize[i] * 2, s->prev->data[i], s->prev->linesize[i], s->linesize[i], s->planeheight[i]); } else { - av_image_copy_plane(out->data[i] + out->linesize[i] * s->first_field, + av_image_copy_plane(out->data[i] + out->linesize[i] * !s->first_field, out->linesize[i] * 2, in->data[i], in->linesize[i], s->linesize[i], s->planeheight[i]); - av_image_copy_plane(out->data[i] + out->linesize[i] * !s->first_field, + av_image_copy_plane(out->data[i] + out->linesize[i] * s->first_field, out->linesize[i] * 2, s->prev->data[i], s->prev->linesize[i], s->linesize[i], s->planeheight[i]); diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak index 53fc7a652814f..79bbc5c05c55b 100644 --- a/tests/fate/filter-video.mak +++ b/tests/fate/filter-video.mak @@ -289,7 +289,7 @@ FATE_FILTER_VSYNTH-$(CONFIG_SEPARATEFIELDS_FILTER) += fate-filter-separatefields fate-filter-separatefields: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf separatefields FATE_FILTER_VSYNTH-$(CONFIG_WEAVE_FILTER) += fate-filter-weave -fate-filter-weave: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf weave +fate-filter-weave: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf weave=bottom FATE_FILTER_VSYNTH-$(CONFIG_SELECT_FILTER) += fate-filter-select-alternate fate-filter-select-alternate: tests/data/filtergraphs/select-alternate From 366e6bfc517ca1728753f7c87cdfdeb384b4b000 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Fri, 11 Aug 2017 01:10:19 +0200 Subject: [PATCH 2773/3374] fate: add overlay filter tests with alpha Signed-off-by: Marton Balint --- tests/fate/filter-video.mak | 19 +++++++++++++++++++ tests/ref/fate/filter-overlay_gbrap_gbrap | 6 ++++++ tests/ref/fate/filter-overlay_gbrp_gbrap | 6 ++++++ tests/ref/fate/filter-overlay_rgb_rgba | 6 ++++++ tests/ref/fate/filter-overlay_rgba_rgba | 6 ++++++ tests/ref/fate/filter-overlay_yuv420_yuva420 | 6 ++++++ tests/ref/fate/filter-overlay_yuv422_yuva422 | 6 ++++++ tests/ref/fate/filter-overlay_yuv444_yuva444 | 6 ++++++ tests/ref/fate/filter-overlay_yuva420_yuva420 | 6 ++++++ tests/ref/fate/filter-overlay_yuva422_yuva422 | 6 ++++++ tests/ref/fate/filter-overlay_yuva444_yuva444 | 6 ++++++ 11 files changed, 79 insertions(+) create mode 100644 tests/ref/fate/filter-overlay_gbrap_gbrap create mode 100644 tests/ref/fate/filter-overlay_gbrp_gbrap create mode 100644 tests/ref/fate/filter-overlay_rgb_rgba create mode 100644 tests/ref/fate/filter-overlay_rgba_rgba create mode 100644 tests/ref/fate/filter-overlay_yuv420_yuva420 create mode 100644 tests/ref/fate/filter-overlay_yuv422_yuva422 create mode 100644 tests/ref/fate/filter-overlay_yuv444_yuva444 create mode 100644 tests/ref/fate/filter-overlay_yuva420_yuva420 create mode 100644 tests/ref/fate/filter-overlay_yuva422_yuva422 create mode 100644 tests/ref/fate/filter-overlay_yuva444_yuva444 diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak index 79bbc5c05c55b..670d9ded56c25 100644 --- a/tests/fate/filter-video.mak +++ b/tests/fate/filter-video.mak @@ -204,6 +204,25 @@ FATE_FILTER_VSYNTH-$(call ALLYES, SPLIT_FILTER SCALE_FILTER PAD_FILTER OVERLAY_F fate-filter-overlay_yuv444: tests/data/filtergraphs/overlay_yuv444 fate-filter-overlay_yuv444: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay_yuv444 +FATE_FILTER_OVERLAY_ALPHA += fate-filter-overlay_yuv420_yuva420 fate-filter-overlay_yuv422_yuva422 fate-filter-overlay_yuv444_yuva444 fate-filter-overlay_rgb_rgba fate-filter-overlay_gbrp_gbrap +FATE_FILTER_OVERLAY_ALPHA += fate-filter-overlay_yuva420_yuva420 fate-filter-overlay_yuva422_yuva422 fate-filter-overlay_yuva444_yuva444 fate-filter-overlay_rgba_rgba fate-filter-overlay_gbrap_gbrap +$(FATE_FILTER_OVERLAY_ALPHA): SRC = $(TARGET_SAMPLES)/png1/lena-rgba.png +$(FATE_FILTER_OVERLAY_ALPHA): CMD = framecrc -i $(SRC) -sws_flags +accurate_rnd+bitexact -vf $(FILTER) -frames:v 1 + +fate-filter-overlay_yuv420_yuva420: FILTER = "format=yuva420p[over];color=black:128x128,format=yuv420p[main];[main][over]overlay=format=yuv420" +fate-filter-overlay_yuv422_yuva422: FILTER = "format=yuva422p[over];color=black:128x128,format=yuv422p[main];[main][over]overlay=format=yuv422" +fate-filter-overlay_yuv444_yuva444: FILTER = "format=yuva444p[over];color=black:128x128,format=yuv444p[main];[main][over]overlay=format=yuv444" +fate-filter-overlay_rgb_rgba: FILTER = "format=rgba[over];color=black:128x128,format=rgb24[main];[main][over]overlay=format=rgb" +fate-filter-overlay_gbrp_gbrap: FILTER = "format=gbrap[over];color=black:128x128,format=gbrp[main];[main][over]overlay=format=gbrp" + +fate-filter-overlay_yuva420_yuva420: FILTER = "format=yuva420p[over];color=black:128x128,format=yuva420p[main];[main][over]overlay=format=yuv420" +fate-filter-overlay_yuva422_yuva422: FILTER = "format=yuva422p[over];color=black:128x128,format=yuva422p[main];[main][over]overlay=format=yuv422" +fate-filter-overlay_yuva444_yuva444: FILTER = "format=yuva444p[over];color=black:128x128,format=yuva444p[main];[main][over]overlay=format=yuv444" +fate-filter-overlay_rgba_rgba: FILTER = "format=rgba[over];color=black:128x128,format=rgba[main];[main][over]overlay=format=rgb" +fate-filter-overlay_gbrap_gbrap: FILTER = "format=gbrap[over];color=black:128x128,format=gbrap[main];[main][over]overlay=format=gbrp" + +FATE_FILTER_SAMPLES-$(call ALLYES, PNG_DECODER APNG_DEMUXER FORMAT_FILTER COLOR_FILTER OVERLAY_FILTER) += $(FATE_FILTER_OVERLAY_ALPHA) + FATE_FILTER_VSYNTH-$(CONFIG_PHASE_FILTER) += fate-filter-phase fate-filter-phase: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf phase diff --git a/tests/ref/fate/filter-overlay_gbrap_gbrap b/tests/ref/fate/filter-overlay_gbrap_gbrap new file mode 100644 index 0000000000000..49e14c643c3dd --- /dev/null +++ b/tests/ref/fate/filter-overlay_gbrap_gbrap @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 128x128 +#sar 0: 1/1 +0, 0, 0, 1, 65536, 0xbac99946 diff --git a/tests/ref/fate/filter-overlay_gbrp_gbrap b/tests/ref/fate/filter-overlay_gbrp_gbrap new file mode 100644 index 0000000000000..204c9d0625122 --- /dev/null +++ b/tests/ref/fate/filter-overlay_gbrp_gbrap @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 128x128 +#sar 0: 1/1 +0, 0, 0, 1, 49152, 0xa905d586 diff --git a/tests/ref/fate/filter-overlay_rgb_rgba b/tests/ref/fate/filter-overlay_rgb_rgba new file mode 100644 index 0000000000000..d7dc6980cc3c4 --- /dev/null +++ b/tests/ref/fate/filter-overlay_rgb_rgba @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 128x128 +#sar 0: 1/1 +0, 0, 0, 1, 49152, 0xb0e3d586 diff --git a/tests/ref/fate/filter-overlay_rgba_rgba b/tests/ref/fate/filter-overlay_rgba_rgba new file mode 100644 index 0000000000000..a1c85e69e4166 --- /dev/null +++ b/tests/ref/fate/filter-overlay_rgba_rgba @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 128x128 +#sar 0: 1/1 +0, 0, 0, 1, 65536, 0x33549946 diff --git a/tests/ref/fate/filter-overlay_yuv420_yuva420 b/tests/ref/fate/filter-overlay_yuv420_yuva420 new file mode 100644 index 0000000000000..ee0c82e062576 --- /dev/null +++ b/tests/ref/fate/filter-overlay_yuv420_yuva420 @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 128x128 +#sar 0: 1/1 +0, 0, 0, 1, 24576, 0x1505f000 diff --git a/tests/ref/fate/filter-overlay_yuv422_yuva422 b/tests/ref/fate/filter-overlay_yuv422_yuva422 new file mode 100644 index 0000000000000..7d21e1b84a5aa --- /dev/null +++ b/tests/ref/fate/filter-overlay_yuv422_yuva422 @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 128x128 +#sar 0: 1/1 +0, 0, 0, 1, 32768, 0x2d88b114 diff --git a/tests/ref/fate/filter-overlay_yuv444_yuva444 b/tests/ref/fate/filter-overlay_yuv444_yuva444 new file mode 100644 index 0000000000000..e1e5db2d7ddb1 --- /dev/null +++ b/tests/ref/fate/filter-overlay_yuv444_yuva444 @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 128x128 +#sar 0: 1/1 +0, 0, 0, 1, 49152, 0x92da3b63 diff --git a/tests/ref/fate/filter-overlay_yuva420_yuva420 b/tests/ref/fate/filter-overlay_yuva420_yuva420 new file mode 100644 index 0000000000000..a17cc5c2e54d3 --- /dev/null +++ b/tests/ref/fate/filter-overlay_yuva420_yuva420 @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 128x128 +#sar 0: 1/1 +0, 0, 0, 1, 40960, 0x0a1ab3c0 diff --git a/tests/ref/fate/filter-overlay_yuva422_yuva422 b/tests/ref/fate/filter-overlay_yuva422_yuva422 new file mode 100644 index 0000000000000..e4d2e3977ec6b --- /dev/null +++ b/tests/ref/fate/filter-overlay_yuva422_yuva422 @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 128x128 +#sar 0: 1/1 +0, 0, 0, 1, 49152, 0x369974d4 diff --git a/tests/ref/fate/filter-overlay_yuva444_yuva444 b/tests/ref/fate/filter-overlay_yuva444_yuva444 new file mode 100644 index 0000000000000..f2d9c564376db --- /dev/null +++ b/tests/ref/fate/filter-overlay_yuva444_yuva444 @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 128x128 +#sar 0: 1/1 +0, 0, 0, 1, 65536, 0xa279ff14 From 1e6cab874512070b36267a5a53fd053f90072fa2 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 15 Aug 2017 03:32:43 +0200 Subject: [PATCH 2774/3374] avcodec/diracdec: Check perspective_exp and zrs_exp. Fixes: undefined shift Fixes: runtime error: shift exponent 264 is too large for 32-bit type 'int' Fixes: 2860/clusterfuzz-testcase-minimized-4672811689836544 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/diracdec.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c index f2837aca69e5b..29042bd86b0ae 100644 --- a/libavcodec/diracdec.c +++ b/libavcodec/diracdec.c @@ -1161,6 +1161,10 @@ static int dirac_unpack_prediction_parameters(DiracContext *s) s->globalmc[ref].perspective[0] = dirac_get_se_golomb(gb); s->globalmc[ref].perspective[1] = dirac_get_se_golomb(gb); } + if (s->globalmc[ref].perspective_exp + (uint64_t)s->globalmc[ref].zrs_exp > 30) { + return AVERROR_INVALIDDATA; + } + } } From 92da23093c784b1d9f0db4db51d28ea80a59e759 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 15 Aug 2017 03:32:44 +0200 Subject: [PATCH 2775/3374] avcodec/diracdec: Fixes integer overflow Fixes: runtime error: signed integer overflow: 340018243 * 27 cannot be represented in type 'int' Fixes: 2861/clusterfuzz-testcase-minimized-5361070510178304 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/diracdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c index 29042bd86b0ae..0aee08f9e115c 100644 --- a/libavcodec/diracdec.c +++ b/libavcodec/diracdec.c @@ -442,7 +442,7 @@ static av_cold int dirac_decode_end(AVCodecContext *avctx) static inline int coeff_unpack_golomb(GetBitContext *gb, int qfactor, int qoffset) { int coeff = dirac_get_se_golomb(gb); - const int sign = FFSIGN(coeff); + const unsigned sign = FFSIGN(coeff); if (coeff) coeff = sign*((sign * coeff * qfactor + qoffset) >> 2); return coeff; From 28e9ba951d1a0b0aca53b242aa64f484ca75e874 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Thu, 17 Aug 2017 11:42:16 +0200 Subject: [PATCH 2776/3374] avcodec/dnxhdenc: call slice thread code only if slice threading is enabled --- libavcodec/dnxhdenc.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c index f8bf7db90a9ff..5a0e6de6a51a1 100644 --- a/libavcodec/dnxhdenc.c +++ b/libavcodec/dnxhdenc.c @@ -526,9 +526,11 @@ FF_DISABLE_DEPRECATION_WARNINGS FF_ENABLE_DEPRECATION_WARNINGS #endif - if (avctx->thread_count > MAX_THREADS) { - av_log(avctx, AV_LOG_ERROR, "too many threads\n"); - return AVERROR(EINVAL); + if (avctx->active_thread_type == FF_THREAD_SLICE) { + if (avctx->thread_count > MAX_THREADS) { + av_log(avctx, AV_LOG_ERROR, "too many threads\n"); + return AVERROR(EINVAL); + } } if (avctx->qmax <= 1) { @@ -537,9 +539,11 @@ FF_ENABLE_DEPRECATION_WARNINGS } ctx->thread[0] = ctx; - for (i = 1; i < avctx->thread_count; i++) { - ctx->thread[i] = av_malloc(sizeof(DNXHDEncContext)); - memcpy(ctx->thread[i], ctx, sizeof(DNXHDEncContext)); + if (avctx->active_thread_type == FF_THREAD_SLICE) { + for (i = 1; i < avctx->thread_count; i++) { + ctx->thread[i] = av_malloc(sizeof(DNXHDEncContext)); + memcpy(ctx->thread[i], ctx, sizeof(DNXHDEncContext)); + } } return 0; From 931c0ac95cebe62f2bdd53a81bf40e3916be6476 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 16 Aug 2017 16:03:23 +0200 Subject: [PATCH 2777/3374] avcodec/zmbv: Check decomp_size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: OOM Fixes: 2710/clusterfuzz-testcase-minimized-4750001420894208 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Reviewed-by: Tomas Härdin Signed-off-by: Michael Niedermayer --- libavcodec/zmbv.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/zmbv.c b/libavcodec/zmbv.c index f126515bd17fd..b09dc41ebd2ae 100644 --- a/libavcodec/zmbv.c +++ b/libavcodec/zmbv.c @@ -589,6 +589,11 @@ static av_cold int decode_init(AVCodecContext *avctx) // Needed if zlib unused or init aborted before inflateInit memset(&c->zstream, 0, sizeof(z_stream)); + if ((avctx->width + 255ULL) * (avctx->height + 64ULL) > FFMIN(avctx->max_pixels, INT_MAX / 4) ) { + av_log(avctx, AV_LOG_ERROR, "Internal buffer (decomp_size) larger than max_pixels or too large\n"); + return AVERROR_INVALIDDATA; + } + c->decomp_size = (avctx->width + 255) * 4 * (avctx->height + 64); /* Allocate decompression buffer */ From 7160992431b029b31bf407443faeaba86dc755a3 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Thu, 17 Aug 2017 00:20:01 +0200 Subject: [PATCH 2778/3374] avformat/utils: always av_reduce r_frame_rate Reviewed-by: Michael Niedermayer Signed-off-by: Marton Balint --- libavformat/utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/utils.c b/libavformat/utils.c index 58283616dc2c5..23865c88c43d9 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -3943,8 +3943,8 @@ FF_ENABLE_DEPRECATION_WARNINGS if (!st->r_frame_rate.num) { if ( avctx->time_base.den * (int64_t) st->time_base.num <= avctx->time_base.num * avctx->ticks_per_frame * (int64_t) st->time_base.den) { - st->r_frame_rate.num = avctx->time_base.den; - st->r_frame_rate.den = avctx->time_base.num * avctx->ticks_per_frame; + av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, + avctx->time_base.den, (int64_t)avctx->time_base.num * avctx->ticks_per_frame, INT_MAX); } else { st->r_frame_rate.num = st->time_base.den; st->r_frame_rate.den = st->time_base.num; From 801ba0f0ee7244f5405764c917a0b6adcbc6fb9e Mon Sep 17 00:00:00 2001 From: Werner Robitza Date: Wed, 16 Aug 2017 13:27:19 +0200 Subject: [PATCH 2779/3374] filters.texi: explain audio upsampling in loudnorm Explain that audio will be upsampled to 192 kHz. Addresses issues mentioned in issue 6570. Signed-off-by: Werner Robitza --- doc/filters.texi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/filters.texi b/doc/filters.texi index 502ebd5e452d5..ef0b2ca899369 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -3070,6 +3070,10 @@ EBU R128 loudness normalization. Includes both dynamic and linear normalization Support for both single pass (livestreams, files) and double pass (files) modes. This algorithm can target IL, LRA, and maximum true peak. +To accurately detect true peaks, the audio stream will be upsampled to 192 kHz. +Use the @code{-ar} option or @code{aresample} filter to set a different output +sample rate. + The filter accepts the following options: @table @option From 2955cd44828239747ef646a80e9908d5b962bfc1 Mon Sep 17 00:00:00 2001 From: Kyle Swanson Date: Thu, 17 Aug 2017 14:01:42 -0700 Subject: [PATCH 2780/3374] filters.texi: clarify audio upsampling in loudnorm Signed-off-by: Kyle Swanson --- doc/filters.texi | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index ef0b2ca899369..ba29a752745cc 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -3068,11 +3068,9 @@ If the specified value is not valid, it is ignored and prior one is kept. EBU R128 loudness normalization. Includes both dynamic and linear normalization modes. Support for both single pass (livestreams, files) and double pass (files) modes. -This algorithm can target IL, LRA, and maximum true peak. - -To accurately detect true peaks, the audio stream will be upsampled to 192 kHz. -Use the @code{-ar} option or @code{aresample} filter to set a different output -sample rate. +This algorithm can target IL, LRA, and maximum true peak. To accurately detect true peaks, +the audio stream will be upsampled to 192 kHz unless the normalization mode is linear. +Use the @code{-ar} option or @code{aresample} filter to explicitly set an output sample rate. The filter accepts the following options: From 7fb4b0368de18fc150e72a9190a4c87827d2d9d2 Mon Sep 17 00:00:00 2001 From: Zhao Zhili Date: Thu, 17 Aug 2017 10:24:01 +0800 Subject: [PATCH 2781/3374] ffprobe: fix use of uninitialized variable Signed-off-by: Michael Niedermayer --- ffprobe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ffprobe.c b/ffprobe.c index f22c4f57ade5f..50d7c1a777c95 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -3328,6 +3328,7 @@ static int parse_read_interval(const char *interval_spec, } interval->end = lli; } else { + interval->duration_frames = 0; ret = av_parse_time(&us, p, 1); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Invalid interval end/duration specification '%s'\n", p); From f4544163b27615ecfff1b42d6acdb3672ac92399 Mon Sep 17 00:00:00 2001 From: Jacob Trimble Date: Thu, 27 Jul 2017 10:34:32 -0700 Subject: [PATCH 2782/3374] libavformat/mov: Fix inserting frames before current_frame. When using streaming input, it may be possible to see frames that appear before the current_frame. When these frames are inserted into the index, the current_frame needs to be updated so it is still pointing at the same frame. Signed-off-by: Jacob Trimble Signed-off-by: Michael Niedermayer --- libavformat/mov.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index c02caf6719bc3..522ce60c2de51 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -4262,7 +4262,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) int64_t dts; int data_offset = 0; unsigned entries, first_sample_flags = frag->flags; - int flags, distance, i, err; + int flags, distance, i, err, old_nb_index_entries; for (i = 0; i < c->fc->nb_streams; i++) { if (c->fc->streams[i]->id == frag->track_id) { @@ -4355,13 +4355,19 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES)); if (keyframe) distance = 0; + old_nb_index_entries = st->nb_index_entries; err = av_add_index_entry(st, offset, dts, sample_size, distance, keyframe ? AVINDEX_KEYFRAME : 0); if (err < 0) { av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n"); + } else if (err <= sc->current_sample && err + 1 != st->nb_index_entries && + st->nb_index_entries != old_nb_index_entries) { + // if we inserted a new item before the current sample, move the + // counter ahead so it is still pointing to the same sample. + sc->current_sample++; } - av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", " - "size %u, distance %d, keyframe %d\n", st->index, sc->sample_count+i, + av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", " + "size %u, distance %d, keyframe %d\n", st->index, err, offset, dts, sample_size, distance, keyframe); distance++; dts += sample_duration; From c359c51947c9ac925cc4a5d1893ef20ea1d3b4c8 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 14 Aug 2017 00:15:54 +0200 Subject: [PATCH 2783/3374] avcodec/rangecoder: Do not increase the pointer beyond the buffer Fixes: undefined behavior Signed-off-by: Michael Niedermayer --- libavcodec/rangecoder.c | 1 + libavcodec/rangecoder.h | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libavcodec/rangecoder.c b/libavcodec/rangecoder.c index 0bb79c880e13a..0d53bef076073 100644 --- a/libavcodec/rangecoder.c +++ b/libavcodec/rangecoder.c @@ -58,6 +58,7 @@ av_cold void ff_init_range_decoder(RangeCoder *c, const uint8_t *buf, c->low = AV_RB16(c->bytestream); c->bytestream += 2; + c->overread = 0; if (c->low >= 0xFF00) { c->low = 0xFF00; c->bytestream_end = c->bytestream; diff --git a/libavcodec/rangecoder.h b/libavcodec/rangecoder.h index c3e81d0dcba7a..44af88b8f57f1 100644 --- a/libavcodec/rangecoder.h +++ b/libavcodec/rangecoder.h @@ -42,6 +42,8 @@ typedef struct RangeCoder { uint8_t *bytestream_start; uint8_t *bytestream; uint8_t *bytestream_end; + int overread; +#define MAX_OVERREAD 2 } RangeCoder; void ff_init_range_encoder(RangeCoder *c, uint8_t *buf, int buf_size); @@ -106,9 +108,11 @@ static inline void refill(RangeCoder *c) if (c->range < 0x100) { c->range <<= 8; c->low <<= 8; - if (c->bytestream < c->bytestream_end) + if (c->bytestream < c->bytestream_end) { c->low += c->bytestream[0]; - c->bytestream++; + c->bytestream++; + } else + c->overread ++; } } From b9f92093a10217b14d923220aaa186f41a0cf555 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 14 Aug 2017 00:15:55 +0200 Subject: [PATCH 2784/3374] avcodec/ffv1dec: Check for bitstream end in decode_line() Fixes: timeout Fixes: 2971/clusterfuzz-testcase-6130678276030464 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/ffv1dec.c | 24 +++++++++++++++++++++--- libavcodec/ffv1dec_template.c | 8 ++++++-- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index 20921c6adfb35..b13ecd3eabba0 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -93,6 +93,19 @@ static inline int get_vlc_symbol(GetBitContext *gb, VlcState *const state, return ret; } +static int is_input_end(FFV1Context *s) +{ + if (s->ac != AC_GOLOMB_RICE) { + RangeCoder *const c = &s->c; + if (c->overread > MAX_OVERREAD) + return AVERROR_INVALIDDATA; + } else { + if (get_bits_left(&s->gb) < 1) + return AVERROR_INVALIDDATA; + } + return 0; +} + #define TYPE int16_t #define RENAME(name) name #include "ffv1dec_template.c" @@ -103,7 +116,7 @@ static inline int get_vlc_symbol(GetBitContext *gb, VlcState *const state, #define RENAME(name) name ## 32 #include "ffv1dec_template.c" -static void decode_plane(FFV1Context *s, uint8_t *src, +static int decode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index, int pixel_stride) { @@ -127,11 +140,15 @@ static void decode_plane(FFV1Context *s, uint8_t *src, // { START_TIMER if (s->avctx->bits_per_raw_sample <= 8) { - decode_line(s, w, sample, plane_index, 8); + int ret = decode_line(s, w, sample, plane_index, 8); + if (ret < 0) + return ret; for (x = 0; x < w; x++) src[x*pixel_stride + stride * y] = sample[1][x]; } else { - decode_line(s, w, sample, plane_index, s->avctx->bits_per_raw_sample); + int ret = decode_line(s, w, sample, plane_index, s->avctx->bits_per_raw_sample); + if (ret < 0) + return ret; if (s->packed_at_lsb) { for (x = 0; x < w; x++) { ((uint16_t*)(src + stride*y))[x*pixel_stride] = sample[1][x]; @@ -144,6 +161,7 @@ static void decode_plane(FFV1Context *s, uint8_t *src, } // STOP_TIMER("decode-line") } } + return 0; } static int decode_slice_header(FFV1Context *f, FFV1Context *fs) diff --git a/libavcodec/ffv1dec_template.c b/libavcodec/ffv1dec_template.c index d41d807e64cea..37df7667737d3 100644 --- a/libavcodec/ffv1dec_template.c +++ b/libavcodec/ffv1dec_template.c @@ -20,7 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -static av_always_inline void RENAME(decode_line)(FFV1Context *s, int w, +static av_always_inline int RENAME(decode_line)(FFV1Context *s, int w, TYPE *sample[2], int plane_index, int bits) { @@ -31,6 +31,9 @@ static av_always_inline void RENAME(decode_line)(FFV1Context *s, int w, int run_mode = 0; int run_index = s->run_index; + if (is_input_end(s)) + return AVERROR_INVALIDDATA; + if (s->slice_coding_mode == 1) { int i; for (x = 0; x < w; x++) { @@ -41,7 +44,7 @@ static av_always_inline void RENAME(decode_line)(FFV1Context *s, int w, } sample[1][x] = v; } - return; + return 0; } for (x = 0; x < w; x++) { @@ -101,6 +104,7 @@ static av_always_inline void RENAME(decode_line)(FFV1Context *s, int w, sample[1][x] = av_mod_uintp2(RENAME(predict)(sample[1] + x, sample[0] + x) + (SUINT)diff, bits); } s->run_index = run_index; + return 0; } static void RENAME(decode_rgb_frame)(FFV1Context *s, uint8_t *src[3], int w, int h, int stride[3]) From cadab5a2a74d715fc16325bd89f8b8091def1083 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 17 Aug 2017 03:54:56 +0200 Subject: [PATCH 2785/3374] avcodec/pixlet: fixes integer overflow in read_highpass() Fixes: runtime error: negation of -2147483648 cannot be represented in type 'int32_t' (aka 'int'); cast to an unsigned type to negate this value to itself Fixes: 2879/clusterfuzz-testcase-minimized-6317542639403008 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/pixlet.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavcodec/pixlet.c b/libavcodec/pixlet.c index a9661d3ab6812..088226bdda83e 100644 --- a/libavcodec/pixlet.c +++ b/libavcodec/pixlet.c @@ -331,6 +331,9 @@ static int read_highpass(AVCodecContext *avctx, uint8_t *ptr, int plane, AVFrame return AVERROR_INVALIDDATA; } + if (a == INT32_MIN) + return AVERROR_INVALIDDATA; + ret = read_high_coeffs(avctx, ptr + bytestream2_tell(&ctx->gb), dest, size, c, (b >= FFABS(a)) ? b : a, d, ctx->band[plane][i + 1].width, stride); From 30ae07d7ef3555ec45fa53098849223fff204475 Mon Sep 17 00:00:00 2001 From: Ivan Kalvachev Date: Sat, 5 Aug 2017 20:18:50 +0300 Subject: [PATCH 2786/3374] Add macros to x86util.asm . Improved version of VBROADCASTSS that works like the avx2 instruction. Emulation of vpbroadcastd. Horizontal sum HSUMPS that places the result in all elements. Emulation of blendvps and pblendvb. Signed-off-by: Ivan Kalvachev --- libavutil/x86/x86util.asm | 106 +++++++++++++++++++++++++++++++++++--- 1 file changed, 98 insertions(+), 8 deletions(-) diff --git a/libavutil/x86/x86util.asm b/libavutil/x86/x86util.asm index cc7d272cada6d..e1220dfc1a431 100644 --- a/libavutil/x86/x86util.asm +++ b/libavutil/x86/x86util.asm @@ -832,14 +832,25 @@ pmaxsd %1, %2 %endmacro -%macro VBROADCASTSS 2 ; dst xmm/ymm, src m32 -%if cpuflag(avx) - vbroadcastss %1, %2 -%else ; sse -%ifnidn %1, %2 - movss %1, %2 -%endif - shufps %1, %1, 0 +%macro VBROADCASTSS 2 ; dst xmm/ymm, src m32/xmm +%if cpuflag(avx2) + vbroadcastss %1, %2 +%elif cpuflag(avx) + %ifnum sizeof%2 ; avx1 register + shufps xmm%1, xmm%2, xmm%2, q0000 + %if sizeof%1 >= 32 ; mmsize>=32 + vinsertf128 %1, %1, xmm%1, 1 + %endif + %else ; avx1 memory + vbroadcastss %1, %2 + %endif +%else + %ifnum sizeof%2 ; sse register + shufps %1, %2, %2, q0000 + %else ; sse memory + movss %1, %2 + shufps %1, %1, 0 + %endif %endif %endmacro @@ -854,6 +865,21 @@ %endif %endmacro +%macro VPBROADCASTD 2 ; dst xmm/ymm, src m32/xmm +%if cpuflag(avx2) + vpbroadcastd %1, %2 +%elif cpuflag(avx) && sizeof%1 >= 32 + %error vpbroadcastd not possible with ymm on avx1. try vbroadcastss +%else + %ifnum sizeof%2 ; sse2 register + pshufd %1, %2, q0000 + %else ; sse memory + movd %1, %2 + pshufd %1, %1, 0 + %endif +%endif +%endmacro + %macro SHUFFLE_MASK_W 8 %rep 8 %if %1>=0x80 @@ -918,3 +944,67 @@ movhlps %1, %2 ; may cause an int/float domain transition and has a dependency on dst %endif %endmacro + +; Horizontal Sum of Packed Single precision floats +; The resulting sum is in all elements. +%macro HSUMPS 2 ; dst/src, tmp +%if cpuflag(avx) + %if sizeof%1>=32 ; avx + vperm2f128 %2, %1, %1, (0)*16+(1) + addps %1, %2 + %endif + shufps %2, %1, %1, q1032 + addps %1, %2 + shufps %2, %1, %1, q0321 + addps %1, %2 +%else ; this form is a bit faster than the short avx-like emulation. + movaps %2, %1 + shufps %1, %1, q1032 + addps %1, %2 + movaps %2, %1 + shufps %1, %1, q0321 + addps %1, %2 + ; all %1 members should be equal for as long as float a+b==b+a +%endif +%endmacro + +; Emulate blendvps if not available +; +; src_b is destroyed when using emulation with logical operands +; SSE41 blendv instruction is hard coded to use xmm0 as mask +%macro BLENDVPS 3 ; dst/src_a, src_b, mask +%if cpuflag(avx) + blendvps %1, %1, %2, %3 +%elif cpuflag(sse4) + %ifnidn %3,xmm0 + %error sse41 blendvps uses xmm0 as default 3d operand, you used %3 + %endif + blendvps %1, %2, %3 +%else + xorps %2, %1 + andps %2, %3 + xorps %1, %2 +%endif +%endmacro + +; Emulate pblendvb if not available +; +; src_b is destroyed when using emulation with logical operands +; SSE41 blendv instruction is hard coded to use xmm0 as mask +%macro PBLENDVB 3 ; dst/src_a, src_b, mask +%if cpuflag(avx) + %if cpuflag(avx) && notcpuflag(avx2) && sizeof%1 >= 32 + %error pblendb not possible with ymm on avx1, try blendvps. + %endif + pblendvb %1, %1, %2, %3 +%elif cpuflag(sse4) + %ifnidn %3,xmm0 + %error sse41 pblendvd uses xmm0 as default 3d operand, you used %3 + %endif + pblendvb %1, %2, %3 +%else + pxor %2, %1 + pand %2, %3 + pxor %1, %2 +%endif +%endmacro From 7205513f8f4b32c403c733d7d2ce2f440837397d Mon Sep 17 00:00:00 2001 From: Ivan Kalvachev Date: Thu, 8 Jun 2017 22:24:33 +0300 Subject: [PATCH 2787/3374] SIMD opus pvq_search implementation Explanation on the workings and methods used by the Pyramid Vector Quantization Search function could be found in the following Work-In-Progress mail threads: http://ffmpeg.org/pipermail/ffmpeg-devel/2017-June/212146.html http://ffmpeg.org/pipermail/ffmpeg-devel/2017-June/212816.html http://ffmpeg.org/pipermail/ffmpeg-devel/2017-July/213030.html http://ffmpeg.org/pipermail/ffmpeg-devel/2017-July/213436.html Signed-off-by: Ivan Kalvachev --- libavcodec/opus_pvq.c | 3 + libavcodec/opus_pvq.h | 5 +- libavcodec/x86/Makefile | 3 + libavcodec/x86/opus_dsp_init.c | 45 ++++ libavcodec/x86/opus_pvq_search.asm | 395 +++++++++++++++++++++++++++++ 5 files changed, 449 insertions(+), 2 deletions(-) create mode 100644 libavcodec/x86/opus_dsp_init.c create mode 100644 libavcodec/x86/opus_pvq_search.asm diff --git a/libavcodec/opus_pvq.c b/libavcodec/opus_pvq.c index 2ac66a0ede3c8..2fb276099bc67 100644 --- a/libavcodec/opus_pvq.c +++ b/libavcodec/opus_pvq.c @@ -947,6 +947,9 @@ int av_cold ff_celt_pvq_init(CeltPVQ **pvq) s->encode_band = pvq_encode_band; s->band_cost = pvq_band_cost; + if (ARCH_X86) + ff_opus_dsp_init_x86(s); + *pvq = s; return 0; diff --git a/libavcodec/opus_pvq.h b/libavcodec/opus_pvq.h index 669149483813e..92463373603bb 100644 --- a/libavcodec/opus_pvq.h +++ b/libavcodec/opus_pvq.h @@ -33,8 +33,8 @@ float *lowband_scratch, int fill) struct CeltPVQ { - DECLARE_ALIGNED(32, int, qcoeff )[176]; - DECLARE_ALIGNED(32, float, hadamard_tmp)[176]; + DECLARE_ALIGNED(32, int, qcoeff )[256]; + DECLARE_ALIGNED(32, float, hadamard_tmp)[256]; float (*pvq_search)(float *X, int *y, int K, int N); @@ -45,6 +45,7 @@ struct CeltPVQ { }; int ff_celt_pvq_init (struct CeltPVQ **pvq); +void ff_opus_dsp_init_x86(struct CeltPVQ *s); void ff_celt_pvq_uninit(struct CeltPVQ **pvq); #endif /* AVCODEC_OPUS_PVQ_H */ diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile index 0dbc46504e53f..e36644c72a614 100644 --- a/libavcodec/x86/Makefile +++ b/libavcodec/x86/Makefile @@ -52,6 +52,8 @@ OBJS-$(CONFIG_APNG_DECODER) += x86/pngdsp_init.o OBJS-$(CONFIG_CAVS_DECODER) += x86/cavsdsp.o OBJS-$(CONFIG_DCA_DECODER) += x86/dcadsp_init.o x86/synth_filter_init.o OBJS-$(CONFIG_DNXHD_ENCODER) += x86/dnxhdenc_init.o +OBJS-$(CONFIG_OPUS_DECODER) += x86/opus_dsp_init.o +OBJS-$(CONFIG_OPUS_ENCODER) += x86/opus_dsp_init.o OBJS-$(CONFIG_HEVC_DECODER) += x86/hevcdsp_init.o OBJS-$(CONFIG_JPEG2000_DECODER) += x86/jpeg2000dsp_init.o OBJS-$(CONFIG_MLP_DECODER) += x86/mlpdsp_init.o @@ -123,6 +125,7 @@ X86ASM-OBJS-$(CONFIG_MDCT15) += x86/mdct15.o X86ASM-OBJS-$(CONFIG_ME_CMP) += x86/me_cmp.o X86ASM-OBJS-$(CONFIG_MPEGAUDIODSP) += x86/imdct36.o X86ASM-OBJS-$(CONFIG_MPEGVIDEOENC) += x86/mpegvideoencdsp.o +X86ASM-OBJS-$(CONFIG_OPUS_ENCODER) += x86/opus_pvq_search.o X86ASM-OBJS-$(CONFIG_PIXBLOCKDSP) += x86/pixblockdsp.o X86ASM-OBJS-$(CONFIG_QPELDSP) += x86/qpeldsp.o \ x86/fpel.o \ diff --git a/libavcodec/x86/opus_dsp_init.c b/libavcodec/x86/opus_dsp_init.c new file mode 100644 index 0000000000000..c51f786ee8d9e --- /dev/null +++ b/libavcodec/x86/opus_dsp_init.c @@ -0,0 +1,45 @@ +/* + * Opus encoder assembly optimizations + * Copyright (C) 2017 Ivan Kalvachev + * + * 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 "config.h" + +#include "libavutil/x86/cpu.h" +#include "libavcodec/opus_pvq.h" + +extern float ff_pvq_search_sse2(float *X, int *y, int K, int N); +extern float ff_pvq_search_sse4(float *X, int *y, int K, int N); +extern float ff_pvq_search_avx (float *X, int *y, int K, int N); + +av_cold void ff_opus_dsp_init_x86(CeltPVQ *s) +{ + int cpu_flags = av_get_cpu_flags(); + +#if CONFIG_OPUS_ENCODER + if (EXTERNAL_SSE2(cpu_flags)) + s->pvq_search = ff_pvq_search_sse2; + + if (EXTERNAL_SSE4(cpu_flags)) + s->pvq_search = ff_pvq_search_sse4; + + if (EXTERNAL_AVX(cpu_flags)) + s->pvq_search = ff_pvq_search_avx; +#endif +} diff --git a/libavcodec/x86/opus_pvq_search.asm b/libavcodec/x86/opus_pvq_search.asm new file mode 100644 index 0000000000000..f0d9950e3456b --- /dev/null +++ b/libavcodec/x86/opus_pvq_search.asm @@ -0,0 +1,395 @@ +;****************************************************************************** +;* SIMD optimized Opus encoder DSP function +;* +;* Copyright (C) 2017 Ivan Kalvachev +;* +;* 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 "config.asm" +%include "libavutil/x86/x86util.asm" + +%ifdef __NASM_VER__ +%use "smartalign" +ALIGNMODE p6 +%endif + +; Use float op that give half precision but execute for around 3 cycles. +; On Skylake & Ryzen the division is much faster (around 11c/3), +; that makes the full precision code about 2% slower. +; Opus also does use rsqrt approximation in their intrinsics code. +%define USE_APPROXIMATION 1 + +; Presearch tries to quantize by using the property Sum( abs(x[i]*K)/Sx ) = K. +; If we use truncation for the division result then the integer Sum would be <= K. +; By using nearest rounding we get closer approximation, but +; we could also get more than K pulses and we have to remove the extra ones. +; This method is the main improvement of the ffmpeg C function over the Opus original. +%define PRESEARCH_ROUNDING 1 + +SECTION_RODATA 64 + +const_float_abs_mask: times 8 dd 0x7fffffff +const_align_abs_edge: times 8 dd 0 + +const_float_0_5: times 8 dd 0.5 +const_float_1: times 8 dd 1.0 +const_float_sign_mask: times 8 dd 0x80000000 + +const_int32_offsets: + %rep 8 + dd $-const_int32_offsets + %endrep +SECTION .text + +; +; Setup High Register to be used +; for holding memory constants +; +; %1 - the register to be used, assmues it is >= mm8 +; %2 - name of the constant. +; +; Subsequent opcodes are going to use the constant in the form +; "addps m0, mm_const_name" and it would be turned into: +; "addps m0, [const_name]" on 32 bit arch or +; "addps m0, m8" on 64 bit arch +%macro SET_HI_REG_MM_CONSTANT 3 ; movop, reg, const_name +%if num_mmregs > 8 + %define mm_%3 %2 + %{1} %2, [%3] ; movaps m8, [const_name] +%else + %define mm_%3 [%3] +%endif +%endmacro + +; +; Set Position Independent Code +; Base address of a constant +; %1 - the register to be used, if PIC is set +; %2 - name of the constant. +; +; Subsequent opcode are going to use the base address in the form +; "movaps m0, [pic_base_constant_name+r4]" and it would be turned into +; "movaps m0, [r5 + r4]" if PIC is enabled +; "movaps m0, [constant_name + r4]" if texrel are used +%macro SET_PIC_BASE 3; reg, const_label +%ifdef PIC + %{1} %2, [%3] ; lea r5, [rip+const] + %define pic_base_%3 %2 +%else + %define pic_base_%3 %3 +%endif +%endmacro + +%macro PULSES_SEARCH 1 +; m6 Syy_norm +; m7 Sxy_norm + addps m6, mm_const_float_0_5 ; Syy_norm += 1.0/2 + pxor m1, m1 ; max_idx + xorps m3, m3 ; p_max + xor r4d, r4d +align 16 +%%distortion_search: + movd xm2, dword r4d ; movd zero extends +%ifidn %1,add + movaps m4, [tmpY + r4] ; y[i] + movaps m5, [tmpX + r4] ; X[i] + + %if USE_APPROXIMATION == 1 + xorps m0, m0 + cmpps m0, m0, m5, 4 ; m0 = (X[i] != 0.0) + %endif + + addps m4, m6 ; m4 = Syy_new = y[i] + Syy_norm + addps m5, m7 ; m5 = Sxy_new = X[i] + Sxy_norm + + %if USE_APPROXIMATION == 1 + andps m5, m0 ; if(X[i] == 0) Sxy_new = 0; Prevent aproximation error from setting pulses in array padding. + %endif + +%else + movaps m5, [tmpY + r4] ; m5 = y[i] + + xorps m0, m0 ; m0 = 0; + cmpps m0, m0, m5, 1 ; m0 = (0 p_max) + maxps m3, m5 ; m3=max(p_max,p) + ; maxps here is faster than blendvps, despite blend having lower latency. + + pand m2, m0 ; This version seems faster than sse41 pblendvb + pmaxsw m1, m2 ; SSE2 signed word, so it would work for N < 32768/4 + + add r4d, mmsize + cmp r4d, Nd + jb %%distortion_search + + por m1, mm_const_int32_offsets ; max_idx offsets per individual lane (skipped in the inner loop) + movdqa m4, m1 ; needed for the aligned y[max_idx]+=1; processing + +%if mmsize >= 32 +; Merge parallel maximums round 8 (4 vs 4) + + vextractf128 xm5, ym3, 1 ; xmm5 = ymm3[1x128] = ymm3[255..128b] + cmpps xm0, xm3, xm5, 1 ; m0 = (m3 < m5) = ( p[0x128] < p[1x128] ) + + vextracti128 xm2, ym1, 1 ; xmm2 = ymm1[1x128] = ymm1[255..128b] + BLENDVPS xm3, xm5, xm0 ; max_idx = m0 ? max_idx[1x128] : max_idx[0x128] + PBLENDVB xm1, xm2, xm0 ; p = m0 ? p[1x128] : p[0x128] +%endif + +; Merge parallel maximums round 4 (2 vs 2) + ; m3=p[3210] + movhlps xm5, xm3 ; m5=p[xx32] + cmpps xm0, xm3, xm5, 1 ; m0 = (m3 < m5) = ( p[1,0] < p[3,2] ) + + pshufd xm2, xm1, q3232 + BLENDVPS xm3, xm5, xm0 ; max_idx = m0 ? max_idx[3,2] : max_idx[1,0] + PBLENDVB xm1, xm2, xm0 ; p = m0 ? p[3,2] : p[1,0] + +; Merge parallel maximums final round (1 vs 1) + shufps xm0, xm3, xm3, q1111 ; m0 = m3[1] = p[1] + cmpss xm0, xm3, 5 ; m0 = !(m0 >= m3) = !( p[1] >= p[0] ) + + pshufd xm2, xm1, q1111 + PBLENDVB xm1, xm2, xm0 + + movd dword r4d, xm1 ; zero extends to the rest of r4q + + VBROADCASTSS m3, [tmpX + r4] + %{1}ps m7, m3 ; Sxy += X[max_idx] + + VBROADCASTSS m5, [tmpY + r4] + %{1}ps m6, m5 ; Syy += Y[max_idx] + + ; We have to update a single element in Y[i] + ; However writing 4 bytes and then doing 16 byte load in the inner loop + ; could cause a stall due to breaking write forwarding. + VPBROADCASTD m1, xm1 + pcmpeqd m1, m1, m4 ; exactly 1 element matches max_idx and this finds it + + and r4d, ~(mmsize-1) ; align address down, so the value pointed by max_idx is inside a mmsize load + movaps m5, [tmpY + r4] ; m5 = Y[y3...ym...y0] + andps m1, mm_const_float_1 ; m1 = [ 0...1.0...0] + %{1}ps m5, m1 ; m5 = Y[y3...ym...y0] +/- [0...1.0...0] + movaps [tmpY + r4], m5 ; Y[max_idx] +-= 1.0; +%endmacro + +; +; We need one more register for +; PIC relative addressing. Use this +; to count it in cglobal +; +%ifdef PIC + %define num_pic_regs 1 +%else + %define num_pic_regs 0 +%endif + +; +; Pyramid Vector Quantization Search implementation +; +; float * inX - Unaligned (SIMD) access, it will be overread, +; but extra data is masked away. +; int32 * outY - Should be aligned and padded buffer. +; It is used as temp buffer. +; uint32 K - Number of pulses to have after quantizations. +; uint32 N - Number of vector elements. Must be 0 < N < 256 +; +%macro PVQ_FAST_SEARCH 0 +cglobal pvq_search, 4, 5+num_pic_regs, 11, 256*4, inX, outY, K, N +%define tmpX rsp +%define tmpY outYq + + movaps m0, [const_float_abs_mask] + shl Nd, 2 ; N *= sizeof(float); also 32 bit operation zeroes the high 32 bits in 64 bit mode. + mov r4d, Nd + + neg r4d + and r4d, mmsize-1 + + SET_PIC_BASE lea, r5, const_align_abs_edge ; rip+const + movups m2, [pic_base_const_align_abs_edge + r4 - mmsize] + + add Nd, r4d ; N = align(N, mmsize) + + lea r4d, [Nd - mmsize] ; N is rounded up (aligned up) to mmsize, so r4 can't become negative here, unless N=0. + movups m1, [inXq + r4] + andps m1, m2 + movaps [tmpX + r4], m1 ; Sx = abs( X[N-1] ) + +align 16 +%%loop_abs_sum: + sub r4d, mmsize + jc %%end_loop_abs_sum + + movups m2, [inXq + r4] + andps m2, m0 + + movaps [tmpX + r4], m2 ; tmpX[i]=abs(X[i]) + addps m1, m2 ; Sx += abs(X[i]) + jmp %%loop_abs_sum + +align 16 +%%end_loop_abs_sum: + + HSUMPS m1, m2 ; m1 = Sx + + xorps m0, m0 + comiss xm0, xm1 ; + jz %%zero_input ; if (Sx==0) goto zero_input + + cvtsi2ss xm0, dword Kd ; m0 = K +%if USE_APPROXIMATION == 1 + rcpss xm1, xm1 ; m1 = approx(1/Sx) + mulss xm0, xm1 ; m0 = K*(1/Sx) +%else + divss xm0, xm1 ; b = K/Sx + ; b = K/max_x +%endif + + VBROADCASTSS m0, xm0 + + lea r4d, [Nd - mmsize] + pxor m5, m5 ; Sy ( Sum of abs( y[i]) ) + xorps m6, m6 ; Syy ( Sum of y[i]*y[i] ) + xorps m7, m7 ; Sxy ( Sum of X[i]*y[i] ) +align 16 +%%loop_guess: + movaps m1, [tmpX + r4] ; m1 = X[i] + mulps m2, m0, m1 ; m2 = res*X[i] + %if PRESEARCH_ROUNDING == 0 + cvttps2dq m2, m2 ; yt = (int)truncf( res*X[i] ) + %else + cvtps2dq m2, m2 ; yt = (int)lrintf( res*X[i] ) + %endif + paddd m5, m2 ; Sy += yt + cvtdq2ps m2, m2 ; yt = (float)yt + mulps m1, m2 ; m1 = X[i]*yt + movaps [tmpY + r4], m2 ; y[i] = m2 + addps m7, m1 ; Sxy += m1; + mulps m2, m2 ; m2 = yt*yt + addps m6, m2 ; Syy += m2 + + sub r4d, mmsize + jnc %%loop_guess + + HSUMPS m6, m1 ; Syy_norm + HADDD m5, m4 ; pulses + + movd dword r4d, xm5 ; zero extends to the rest of r4q + + sub Kd, r4d ; K -= pulses , also 32 bit operation zeroes high 32 bit in 64 bit mode. + jz %%finish ; K - pulses == 0 + + SET_HI_REG_MM_CONSTANT movaps, m8, const_float_0_5 + SET_HI_REG_MM_CONSTANT movaps, m9, const_float_1 + SET_HI_REG_MM_CONSTANT movdqa, m10, const_int32_offsets + ; Use Syy/2 in distortion parameter calculations. + ; Saves pre and post-caclulation to correct Y[] values. + ; Same precision, since float mantisa is normalized. + ; The SQRT approximation does differ. + HSUMPS m7, m0 ; Sxy_norm + mulps m6, mm_const_float_0_5 + + jc %%remove_pulses_loop ; K - pulses < 0 + +align 16 ; K - pulses > 0 +%%add_pulses_loop: + + PULSES_SEARCH add ; m6 Syy_norm ; m7 Sxy_norm + + sub Kd, 1 + jnz %%add_pulses_loop + + addps m6, m6 ; Syy*=2 + + jmp %%finish + +align 16 +%%remove_pulses_loop: + + PULSES_SEARCH sub ; m6 Syy_norm ; m7 Sxy_norm + + add Kd, 1 + jnz %%remove_pulses_loop + + addps m6, m6 ; Syy*=2 + +align 16 +%%finish: + lea r4d, [Nd - mmsize] + movaps m2, [const_float_sign_mask] + +align 16 +%%restore_sign_loop: + movaps m0, [tmpY + r4] ; m0 = Y[i] + movups m1, [inXq + r4] ; m1 = X[i] + andps m1, m2 ; m1 = sign(X[i]) + orps m0, m1 ; m0 = Y[i]*sign + cvtps2dq m3, m0 ; m3 = (int)m0 + movaps [outYq + r4], m3 + + sub r4d, mmsize + jnc %%restore_sign_loop +%%return: + +%if ARCH_X86_64 == 0 ; sbrdsp + movss r0m, xm6 ; return (float)Syy_norm + fld dword r0m +%else + movaps m0, m6 ; return (float)Syy_norm +%endif + + RET + +align 16 +%%zero_input: + lea r4d, [Nd - mmsize] + xorps m0, m0 +%%zero_loop: + movaps [outYq + r4], m0 + sub r4d, mmsize + jnc %%zero_loop + + movaps m6, [const_float_1] + jmp %%return +%endmacro + + +INIT_XMM sse2 +PVQ_FAST_SEARCH + +INIT_XMM sse4 +PVQ_FAST_SEARCH + +INIT_XMM avx +PVQ_FAST_SEARCH From 8e53cd1fab86b8774f0b5b0f186d8e0cd9c1895b Mon Sep 17 00:00:00 2001 From: Rostislav Pehlivanov Date: Fri, 18 Aug 2017 17:27:41 +0100 Subject: [PATCH 2788/3374] ops_pvq_search: remove dead macro There's no point in toggling it, even for debugging. Its just worse. Signed-off-by: Rostislav Pehlivanov --- libavcodec/x86/opus_pvq_search.asm | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/libavcodec/x86/opus_pvq_search.asm b/libavcodec/x86/opus_pvq_search.asm index f0d9950e3456b..beb6cbcc9b391 100644 --- a/libavcodec/x86/opus_pvq_search.asm +++ b/libavcodec/x86/opus_pvq_search.asm @@ -34,13 +34,6 @@ ALIGNMODE p6 ; Opus also does use rsqrt approximation in their intrinsics code. %define USE_APPROXIMATION 1 -; Presearch tries to quantize by using the property Sum( abs(x[i]*K)/Sx ) = K. -; If we use truncation for the division result then the integer Sum would be <= K. -; By using nearest rounding we get closer approximation, but -; we could also get more than K pulses and we have to remove the extra ones. -; This method is the main improvement of the ffmpeg C function over the Opus original. -%define PRESEARCH_ROUNDING 1 - SECTION_RODATA 64 const_float_abs_mask: times 8 dd 0x7fffffff @@ -286,11 +279,7 @@ align 16 %%loop_guess: movaps m1, [tmpX + r4] ; m1 = X[i] mulps m2, m0, m1 ; m2 = res*X[i] - %if PRESEARCH_ROUNDING == 0 - cvttps2dq m2, m2 ; yt = (int)truncf( res*X[i] ) - %else cvtps2dq m2, m2 ; yt = (int)lrintf( res*X[i] ) - %endif paddd m5, m2 ; Sy += yt cvtdq2ps m2, m2 ; yt = (float)yt mulps m1, m2 ; m1 = X[i]*yt From f386dd70acdc81d42d6bcb885d2889634cdf45b7 Mon Sep 17 00:00:00 2001 From: Rostislav Pehlivanov Date: Fri, 18 Aug 2017 17:28:40 +0100 Subject: [PATCH 2789/3374] opus_pvq_search: only use rsqrtps approximation on CPUs with avx Makes the search produce idential results with the C version. Signed-off-by: Rostislav Pehlivanov --- libavcodec/x86/opus_pvq_search.asm | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/libavcodec/x86/opus_pvq_search.asm b/libavcodec/x86/opus_pvq_search.asm index beb6cbcc9b391..2f4864c95c6e1 100644 --- a/libavcodec/x86/opus_pvq_search.asm +++ b/libavcodec/x86/opus_pvq_search.asm @@ -28,12 +28,6 @@ ALIGNMODE p6 %endif -; Use float op that give half precision but execute for around 3 cycles. -; On Skylake & Ryzen the division is much faster (around 11c/3), -; that makes the full precision code about 2% slower. -; Opus also does use rsqrt approximation in their intrinsics code. -%define USE_APPROXIMATION 1 - SECTION_RODATA 64 const_float_abs_mask: times 8 dd 0x7fffffff @@ -102,17 +96,17 @@ align 16 movaps m4, [tmpY + r4] ; y[i] movaps m5, [tmpX + r4] ; X[i] - %if USE_APPROXIMATION == 1 +%if !cpuflag(avx) ; for crappy ancient CPUs that have slow packed divs but fast 1/sqrt xorps m0, m0 cmpps m0, m0, m5, 4 ; m0 = (X[i] != 0.0) - %endif +%endif addps m4, m6 ; m4 = Syy_new = y[i] + Syy_norm addps m5, m7 ; m5 = Sxy_new = X[i] + Sxy_norm - %if USE_APPROXIMATION == 1 +%if !cpuflag(avx) andps m5, m0 ; if(X[i] == 0) Sxy_new = 0; Prevent aproximation error from setting pulses in array padding. - %endif +%endif %else movaps m5, [tmpY + r4] ; m5 = y[i] @@ -125,7 +119,7 @@ align 16 andps m5, m0 ; (0 Date: Fri, 18 Aug 2017 19:20:15 +0200 Subject: [PATCH 2790/3374] lavd/libdc1394: Do not crash if dc1394_camera_new() fails. Fixes Ubuntu bug 1710849 --- libavdevice/libdc1394.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libavdevice/libdc1394.c b/libavdevice/libdc1394.c index afffd89a8b7c9..003335fdd8832 100644 --- a/libavdevice/libdc1394.c +++ b/libavdevice/libdc1394.c @@ -190,6 +190,14 @@ static int dc1394_read_header(AVFormatContext *c) /* FIXME: To select a specific camera I need to search in list its guid */ dc1394->camera = dc1394_camera_new (dc1394->d, list->ids[0].guid); + + if (!dc1394->camera) { + av_log(c, AV_LOG_ERROR, "Unable to open camera with guid 0x%"PRIx64"\n", + list->ids[0].guid); + dc1394_camera_free_list(list); + goto out; + } + if (list->num > 1) { av_log(c, AV_LOG_INFO, "Working with the first camera found\n"); } From 3c99523a2864af729a8576c3fffe81fb884fa0d5 Mon Sep 17 00:00:00 2001 From: Rostislav Pehlivanov Date: Fri, 18 Aug 2017 19:29:33 +0100 Subject: [PATCH 2791/3374] opus_pvq_search: split functions into exactness and only use the exact if its faster This splits the asm function into exact and non-exact version. The exact version is as fast or faster on newer CPUs (which EXTERNAL_AVX_FAST describes well) whilst the non-exact version is faster than the exact on older CPUs. Also fixes yasm compilation which doesn't accept !cpuflags(avx) syntax. Signed-off-by: Rostislav Pehlivanov --- libavcodec/x86/opus_dsp_init.c | 14 ++++++------ libavcodec/x86/opus_pvq_search.asm | 34 ++++++++++++++++++------------ 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/libavcodec/x86/opus_dsp_init.c b/libavcodec/x86/opus_dsp_init.c index c51f786ee8d9e..a9f8a9615901b 100644 --- a/libavcodec/x86/opus_dsp_init.c +++ b/libavcodec/x86/opus_dsp_init.c @@ -24,9 +24,9 @@ #include "libavutil/x86/cpu.h" #include "libavcodec/opus_pvq.h" -extern float ff_pvq_search_sse2(float *X, int *y, int K, int N); -extern float ff_pvq_search_sse4(float *X, int *y, int K, int N); -extern float ff_pvq_search_avx (float *X, int *y, int K, int N); +extern float ff_pvq_search_approx_sse2(float *X, int *y, int K, int N); +extern float ff_pvq_search_approx_sse4(float *X, int *y, int K, int N); +extern float ff_pvq_search_exact_avx (float *X, int *y, int K, int N); av_cold void ff_opus_dsp_init_x86(CeltPVQ *s) { @@ -34,12 +34,12 @@ av_cold void ff_opus_dsp_init_x86(CeltPVQ *s) #if CONFIG_OPUS_ENCODER if (EXTERNAL_SSE2(cpu_flags)) - s->pvq_search = ff_pvq_search_sse2; + s->pvq_search = ff_pvq_search_approx_sse2; if (EXTERNAL_SSE4(cpu_flags)) - s->pvq_search = ff_pvq_search_sse4; + s->pvq_search = ff_pvq_search_approx_sse4; - if (EXTERNAL_AVX(cpu_flags)) - s->pvq_search = ff_pvq_search_avx; + if (EXTERNAL_AVX_FAST(cpu_flags)) + s->pvq_search = ff_pvq_search_exact_avx; #endif } diff --git a/libavcodec/x86/opus_pvq_search.asm b/libavcodec/x86/opus_pvq_search.asm index 2f4864c95c6e1..8cf040465dd07 100644 --- a/libavcodec/x86/opus_pvq_search.asm +++ b/libavcodec/x86/opus_pvq_search.asm @@ -82,7 +82,7 @@ SECTION .text %endif %endmacro -%macro PULSES_SEARCH 1 +%macro PULSES_SEARCH 2 ; %1 - add or sub, %2 - use approximation ; m6 Syy_norm ; m7 Sxy_norm addps m6, mm_const_float_0_5 ; Syy_norm += 1.0/2 @@ -96,7 +96,7 @@ align 16 movaps m4, [tmpY + r4] ; y[i] movaps m5, [tmpX + r4] ; X[i] -%if !cpuflag(avx) ; for crappy ancient CPUs that have slow packed divs but fast 1/sqrt +%if %2 xorps m0, m0 cmpps m0, m0, m5, 4 ; m0 = (X[i] != 0.0) %endif @@ -104,7 +104,7 @@ align 16 addps m4, m6 ; m4 = Syy_new = y[i] + Syy_norm addps m5, m7 ; m5 = Sxy_new = X[i] + Sxy_norm -%if !cpuflag(avx) +%if %2 andps m5, m0 ; if(X[i] == 0) Sxy_new = 0; Prevent aproximation error from setting pulses in array padding. %endif @@ -119,7 +119,7 @@ align 16 andps m5, m0 ; (0 0 %%add_pulses_loop: - PULSES_SEARCH add ; m6 Syy_norm ; m7 Sxy_norm + PULSES_SEARCH add, %1 ; m6 Syy_norm ; m7 Sxy_norm sub Kd, 1 jnz %%add_pulses_loop @@ -320,7 +325,7 @@ align 16 ; K - pulses > 0 align 16 %%remove_pulses_loop: - PULSES_SEARCH sub ; m6 Syy_norm ; m7 Sxy_norm + PULSES_SEARCH sub, %1 ; m6 Syy_norm ; m7 Sxy_norm add Kd, 1 jnz %%remove_pulses_loop @@ -367,12 +372,15 @@ align 16 jmp %%return %endmacro - +; if 1, use a float op that give half precision but execute for around 3 cycles. +; On Skylake & Ryzen the division is much faster (around 11c/3), +; that makes the full precision code about 2% slower. +; Opus also does use rsqrt approximation in their intrinsics code. INIT_XMM sse2 -PVQ_FAST_SEARCH +PVQ_FAST_SEARCH 1 INIT_XMM sse4 -PVQ_FAST_SEARCH +PVQ_FAST_SEARCH 1 INIT_XMM avx -PVQ_FAST_SEARCH +PVQ_FAST_SEARCH 0 From e3a4afca07b2753269f5f05c6fd5ca3034734c00 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Thu, 17 Aug 2017 18:01:01 +0200 Subject: [PATCH 2792/3374] avfilter: add pseudocolor filter --- Changelog | 1 + doc/filters.texi | 45 ++++++ libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/version.h | 2 +- libavfilter/vf_pseudocolor.c | 256 +++++++++++++++++++++++++++++++++++ 6 files changed, 305 insertions(+), 1 deletion(-) create mode 100644 libavfilter/vf_pseudocolor.c diff --git a/Changelog b/Changelog index c797d68a364f7..7a6987a169806 100644 --- a/Changelog +++ b/Changelog @@ -32,6 +32,7 @@ version : - unpremultiply video filter - tlut2 video filter - floodfill video filter +- pseudocolor video filter version 3.3: - CrystalHD decoder moved to new decode API diff --git a/doc/filters.texi b/doc/filters.texi index ba29a752745cc..3b5a38fc9f554 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -11785,6 +11785,51 @@ Set value which will be multiplied with filtered result. Set value which will be added to filtered result. @end table +@section pseudocolor + +Alter frame colors in video with pseudocolors. + +This filter accept the following options: + +@table @option +@item c0 +set pixel first component expression + +@item c1 +set pixel second component expression + +@item c2 +set pixel third component expression + +@item c3 +set pixel fourth component expression, corresponds to the alpha component + +@item i +set component to use as base for altering colors +@end table + +Each of them specifies the expression to use for computing the lookup table for +the corresponding pixel component values. + +The expressions can contain the following constants and functions: + +@table @option +@item w +@item h +The input width and height. + +@item val +The input value for the pixel component. + +@item ymin, umin, vmin, amin +The minimum allowed component value. + +@item ymax, umax, vmax, amax +The maximum allowed component value. +@end table + +All expressions default to "val". + @section psnr Obtain the average, maximum and minimum PSNR (Peak Signal to Noise diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 545b871cd7020..1d92dc172ca7d 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -259,6 +259,7 @@ OBJS-$(CONFIG_PP_FILTER) += vf_pp.o OBJS-$(CONFIG_PP7_FILTER) += vf_pp7.o OBJS-$(CONFIG_PREMULTIPLY_FILTER) += vf_premultiply.o framesync2.o OBJS-$(CONFIG_PREWITT_FILTER) += vf_convolution.o +OBJS-$(CONFIG_PSEUDOCOLOR_FILTER) += vf_pseudocolor.o OBJS-$(CONFIG_PSNR_FILTER) += vf_psnr.o dualinput.o framesync.o OBJS-$(CONFIG_PULLUP_FILTER) += vf_pullup.o OBJS-$(CONFIG_QP_FILTER) += vf_qp.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index f1dacaffa86ff..8b9b9a4d10344 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -270,6 +270,7 @@ static void register_all(void) REGISTER_FILTER(PP7, pp7, vf); REGISTER_FILTER(PREMULTIPLY, premultiply, vf); REGISTER_FILTER(PREWITT, prewitt, vf); + REGISTER_FILTER(PSEUDOCOLOR, pseudocolor, vf); REGISTER_FILTER(PSNR, psnr, vf); REGISTER_FILTER(PULLUP, pullup, vf); REGISTER_FILTER(QP, qp, vf); diff --git a/libavfilter/version.h b/libavfilter/version.h index 5efb648c6d1c3..22207127d0f1d 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 6 -#define LIBAVFILTER_VERSION_MINOR 99 +#define LIBAVFILTER_VERSION_MINOR 100 #define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vf_pseudocolor.c b/libavfilter/vf_pseudocolor.c new file mode 100644 index 0000000000000..642e2901e9ddf --- /dev/null +++ b/libavfilter/vf_pseudocolor.c @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2017 Paul B Mahol + * + * 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 "libavutil/attributes.h" +#include "libavutil/common.h" +#include "libavutil/eval.h" +#include "libavutil/imgutils.h" +#include "libavutil/opt.h" +#include "libavutil/pixdesc.h" +#include "avfilter.h" +#include "formats.h" +#include "internal.h" +#include "video.h" + +static const char *const var_names[] = { + "w", ///< width of the input video + "h", ///< height of the input video + "val", ///< input value for the pixel + "ymin", + "umin", + "vmin", + "amin", + "ymax", + "umax", + "vmax", + "amax", + NULL +}; + +enum var_name { + VAR_W, + VAR_H, + VAR_VAL, + VAR_YMIN, + VAR_UMIN, + VAR_VMIN, + VAR_AMIN, + VAR_YMAX, + VAR_UMAX, + VAR_VMAX, + VAR_AMAX, + VAR_VARS_NB +}; + +typedef struct PseudoColorContext { + const AVClass *class; + int max; + int index; + int nb_planes; + int color; + int linesize[4]; + int width[4], height[4]; + double var_values[VAR_VARS_NB]; + char *comp_expr_str[4]; + AVExpr *comp_expr[4]; + float lut[4][256]; +} PseudoColorContext; + +#define OFFSET(x) offsetof(PseudoColorContext, x) +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM + +static const AVOption pseudocolor_options[] = { + { "c0", "set component #0 expression", OFFSET(comp_expr_str[0]), AV_OPT_TYPE_STRING, {.str="val"}, .flags = FLAGS }, + { "c1", "set component #1 expression", OFFSET(comp_expr_str[1]), AV_OPT_TYPE_STRING, {.str="val"}, .flags = FLAGS }, + { "c2", "set component #2 expression", OFFSET(comp_expr_str[2]), AV_OPT_TYPE_STRING, {.str="val"}, .flags = FLAGS }, + { "c3", "set component #3 expression", OFFSET(comp_expr_str[3]), AV_OPT_TYPE_STRING, {.str="val"}, .flags = FLAGS }, + { "i", "set component as base", OFFSET(index), AV_OPT_TYPE_INT, {.i64=0}, 0, 3, .flags = FLAGS }, + { NULL } +}; + +static const enum AVPixelFormat pix_fmts[] = { + AV_PIX_FMT_GRAY8, + AV_PIX_FMT_YUV444P, AV_PIX_FMT_GBRP, + AV_PIX_FMT_YUVA444P, AV_PIX_FMT_GBRAP, + AV_PIX_FMT_NONE +}; + +static int query_formats(AVFilterContext *ctx) +{ + AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); + if (!fmts_list) + return AVERROR(ENOMEM); + return ff_set_common_formats(ctx, fmts_list); +} + +static int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + PseudoColorContext *s = ctx->priv; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + int depth, ret, hsub, vsub, color; + + depth = desc->comp[0].depth; + s->max = (1 << depth) - 1; + s->nb_planes = av_pix_fmt_count_planes(inlink->format); + + if (s->index >= s->nb_planes) { + av_log(ctx, AV_LOG_ERROR, "index out of allowed range\n"); + return AVERROR(EINVAL); + } + + if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0) + return ret; + + hsub = desc->log2_chroma_w; + vsub = desc->log2_chroma_h; + s->height[1] = s->height[2] = AV_CEIL_RSHIFT(inlink->h, vsub); + s->height[0] = s->height[3] = inlink->h; + s->width[1] = s->width[2] = AV_CEIL_RSHIFT(inlink->w, hsub); + s->width[0] = s->width[3] = inlink->w; + + s->var_values[VAR_W] = inlink->w; + s->var_values[VAR_H] = inlink->h; + + s->var_values[VAR_YMIN] = 16 * (1 << (depth - 8)); + s->var_values[VAR_UMIN] = 16 * (1 << (depth - 8)); + s->var_values[VAR_VMIN] = 16 * (1 << (depth - 8)); + s->var_values[VAR_AMIN] = 0; + s->var_values[VAR_YMAX] = 235 * (1 << (depth - 8)); + s->var_values[VAR_UMAX] = 240 * (1 << (depth - 8)); + s->var_values[VAR_VMAX] = 240 * (1 << (depth - 8)); + s->var_values[VAR_AMAX] = s->max; + + for (color = 0; color < s->nb_planes; color++) { + double res; + int val; + + /* create the parsed expression */ + av_expr_free(s->comp_expr[color]); + s->comp_expr[color] = NULL; + ret = av_expr_parse(&s->comp_expr[color], s->comp_expr_str[color], + var_names, NULL, NULL, NULL, NULL, 0, ctx); + if (ret < 0) { + av_log(ctx, AV_LOG_ERROR, + "Error when parsing the expression '%s' for the component %d and color %d.\n", + s->comp_expr_str[color], color, color); + return AVERROR(EINVAL); + } + + /* compute the lut */ + for (val = 0; val < FF_ARRAY_ELEMS(s->lut[color]); val++) { + s->var_values[VAR_VAL] = val; + + res = av_expr_eval(s->comp_expr[color], s->var_values, s); + if (isnan(res)) { + av_log(ctx, AV_LOG_ERROR, + "Error when evaluating the expression '%s' for the value %d for the component %d.\n", + s->comp_expr_str[color], val, color); + return AVERROR(EINVAL); + } + s->lut[color][val] = res; + } + } + + return 0; +} + +static int filter_frame(AVFilterLink *inlink, AVFrame *in) +{ + AVFilterContext *ctx = inlink->dst; + PseudoColorContext *s = ctx->priv; + AVFilterLink *outlink = ctx->outputs[0]; + AVFrame *out; + int x, y, plane; + + out = ff_get_video_buffer(outlink, outlink->w, outlink->h); + if (!out) { + av_frame_free(&in); + return AVERROR(ENOMEM); + } + av_frame_copy_props(out, in); + + for (plane = 0; plane < s->nb_planes; plane++) { + const uint8_t *index = in->data[s->index]; + const uint8_t *src = in->data[plane]; + uint8_t *dst = out->data[plane]; + + for (y = 0; y < s->height[plane]; y++) { + for (x = 0; x < s->width[plane]; x++) { + int v = s->lut[plane][index[x]]; + + if (v >= 0 && v <= s->max) { + dst[x] = v; + } else { + dst[x] = src[x]; + } + } + index += in->linesize[s->index]; + src += in->linesize[plane]; + dst += out->linesize[plane]; + } + } + + av_frame_free(&in); + return ff_filter_frame(outlink, out); +} + +static const AVFilterPad inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .filter_frame = filter_frame, + .config_props = config_input, + }, + { NULL } +}; + +static const AVFilterPad outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + }, + { NULL } +}; + +static av_cold void uninit(AVFilterContext *ctx) +{ + PseudoColorContext *s = ctx->priv; + int i; + + for (i = 0; i < 4; i++) { + av_expr_free(s->comp_expr[i]); + s->comp_expr[i] = NULL; + } +} + +AVFILTER_DEFINE_CLASS(pseudocolor); + +AVFilter ff_vf_pseudocolor = { + .name = "pseudocolor", + .description = NULL_IF_CONFIG_SMALL("Make pseudocolored video frames."), + .priv_size = sizeof(PseudoColorContext), + .priv_class = &pseudocolor_class, + .uninit = uninit, + .query_formats = query_formats, + .inputs = inputs, + .outputs = outputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, +}; From 1146133df8117c96cc6681a062df6df825fcae2d Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Fri, 18 Aug 2017 09:15:33 +0200 Subject: [PATCH 2793/3374] avutil/eval: add linear interpolation helper --- doc/utils.texi | 3 +++ libavutil/eval.c | 10 +++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/doc/utils.texi b/doc/utils.texi index d65bdf0b0e117..e635118565fdc 100644 --- a/doc/utils.texi +++ b/doc/utils.texi @@ -864,6 +864,9 @@ Load the value of the internal variable with number @var{var}, which was previously stored with st(@var{var}, @var{expr}). The function returns the loaded value. +@item lerp(x, y, z) +Return linear interpolation between @var{x} and @var{y} by amount of @var{z}. + @item log(x) Compute natural logarithm of @var{x}. diff --git a/libavutil/eval.c b/libavutil/eval.c index 638259adeffde..b5f4ea2409e76 100644 --- a/libavutil/eval.c +++ b/libavutil/eval.c @@ -155,7 +155,7 @@ struct AVExpr { e_pow, e_mul, e_div, e_add, e_last, e_st, e_while, e_taylor, e_root, e_floor, e_ceil, e_trunc, e_round, e_sqrt, e_not, e_random, e_hypot, e_gcd, - e_if, e_ifnot, e_print, e_bitand, e_bitor, e_between, e_clip, e_atan2 + e_if, e_ifnot, e_print, e_bitand, e_bitor, e_between, e_clip, e_atan2, e_lerp, } type; double value; // is sign in other types union { @@ -208,6 +208,12 @@ static double eval_expr(Parser *p, AVExpr *e) return e->value * (d >= eval_expr(p, e->param[1]) && d <= eval_expr(p, e->param[2])); } + case e_lerp: { + double v0 = eval_expr(p, e->param[0]); + double v1 = eval_expr(p, e->param[1]); + double f = eval_expr(p, e->param[2]); + return v0 + (v1 - v0) * f; + } case e_print: { double x = eval_expr(p, e->param[0]); int level = e->param[1] ? av_clip(eval_expr(p, e->param[1]), INT_MIN, INT_MAX) : AV_LOG_INFO; @@ -456,6 +462,7 @@ static int parse_primary(AVExpr **e, Parser *p) else if (strmatch(next, "between"))d->type = e_between; else if (strmatch(next, "clip" )) d->type = e_clip; else if (strmatch(next, "atan2" )) d->type = e_atan2; + else if (strmatch(next, "lerp" )) d->type = e_lerp; else { for (i=0; p->func1_names && p->func1_names[i]; i++) { if (strmatch(next, p->func1_names[i])) { @@ -654,6 +661,7 @@ static int verify_expr(AVExpr *e) && (!e->param[2] || verify_expr(e->param[2])); case e_between: case e_clip: + case e_lerp: return verify_expr(e->param[0]) && verify_expr(e->param[1]) && verify_expr(e->param[2]); From 43dab86bcd863739ce51a2742c9f4f5527b5ec7c Mon Sep 17 00:00:00 2001 From: Ivan Kalvachev Date: Sat, 19 Aug 2017 14:29:40 +0300 Subject: [PATCH 2794/3374] opus_pvq_search: Restore the proper use of conditional define and simplify the function name suffix handling. Using named define properly documents the code paths. It also avoids passing additional numbered arguments through multiple levels of macro templates. The suffix handling is done by concatenation, like in other asm functions and avoid having two separate "cglobal" defines. Signed-off-by: Ivan Kalvachev --- libavcodec/x86/opus_pvq_search.asm | 37 +++++++++++++++--------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/libavcodec/x86/opus_pvq_search.asm b/libavcodec/x86/opus_pvq_search.asm index 8cf040465dd07..5c1e6d6174ce6 100644 --- a/libavcodec/x86/opus_pvq_search.asm +++ b/libavcodec/x86/opus_pvq_search.asm @@ -82,7 +82,7 @@ SECTION .text %endif %endmacro -%macro PULSES_SEARCH 2 ; %1 - add or sub, %2 - use approximation +%macro PULSES_SEARCH 1 ; m6 Syy_norm ; m7 Sxy_norm addps m6, mm_const_float_0_5 ; Syy_norm += 1.0/2 @@ -96,17 +96,17 @@ align 16 movaps m4, [tmpY + r4] ; y[i] movaps m5, [tmpX + r4] ; X[i] -%if %2 + %if USE_APPROXIMATION == 1 xorps m0, m0 cmpps m0, m0, m5, 4 ; m0 = (X[i] != 0.0) -%endif + %endif addps m4, m6 ; m4 = Syy_new = y[i] + Syy_norm addps m5, m7 ; m5 = Sxy_new = X[i] + Sxy_norm -%if %2 + %if USE_APPROXIMATION == 1 andps m5, m0 ; if(X[i] == 0) Sxy_new = 0; Prevent aproximation error from setting pulses in array padding. -%endif + %endif %else movaps m5, [tmpY + r4] ; m5 = y[i] @@ -119,7 +119,7 @@ align 16 andps m5, m0 ; (0 0 %%add_pulses_loop: - PULSES_SEARCH add, %1 ; m6 Syy_norm ; m7 Sxy_norm + PULSES_SEARCH add ; m6 Syy_norm ; m7 Sxy_norm sub Kd, 1 jnz %%add_pulses_loop @@ -325,7 +320,7 @@ align 16 ; K - pulses > 0 align 16 %%remove_pulses_loop: - PULSES_SEARCH sub, %1 ; m6 Syy_norm ; m7 Sxy_norm + PULSES_SEARCH sub ; m6 Syy_norm ; m7 Sxy_norm add Kd, 1 jnz %%remove_pulses_loop @@ -376,11 +371,15 @@ align 16 ; On Skylake & Ryzen the division is much faster (around 11c/3), ; that makes the full precision code about 2% slower. ; Opus also does use rsqrt approximation in their intrinsics code. +%define USE_APPROXIMATION 1 + INIT_XMM sse2 -PVQ_FAST_SEARCH 1 +PVQ_FAST_SEARCH _approx INIT_XMM sse4 -PVQ_FAST_SEARCH 1 +PVQ_FAST_SEARCH _approx + +%define USE_APPROXIMATION 0 INIT_XMM avx -PVQ_FAST_SEARCH 0 +PVQ_FAST_SEARCH _exact From d132683ddd4050d3fe103ca88c73258c3442dc34 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 17 Aug 2017 20:32:03 +0200 Subject: [PATCH 2795/3374] avcodec/snowdec: Fix off by 1 error Fixes: runtime error: index 4 out of bounds for type 'int8_t [4]' Fixes: 3023/clusterfuzz-testcase-minimized-6421736130084864 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/snowdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/snowdec.c b/libavcodec/snowdec.c index c80901b7548b8..734f43e7d18aa 100644 --- a/libavcodec/snowdec.c +++ b/libavcodec/snowdec.c @@ -355,7 +355,7 @@ static int decode_header(SnowContext *s){ Plane *p= &s->plane[plane_index]; p->diag_mc= get_rac(&s->c, s->header_state); htaps= get_symbol(&s->c, s->header_state, 0)*2 + 2; - if((unsigned)htaps > HTAPS_MAX || htaps==0) + if((unsigned)htaps >= HTAPS_MAX || htaps==0) return AVERROR_INVALIDDATA; p->htaps= htaps; for(i= htaps/2; i; i--){ From 0c9d5b015c2022e8deebb93367f8ee8a8eb779e8 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 17 Aug 2017 18:24:37 +0200 Subject: [PATCH 2796/3374] avcodec/fic: Fixes signed integer overflow Fixes: runtime error: signed integer overflow: 1037142357 + 1227025305 cannot be represented in type 'int' Fixes: 3024/clusterfuzz-testcase-minimized-5885660323905536 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/fic.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libavcodec/fic.c b/libavcodec/fic.c index 46260ee281870..d7ee370423c6f 100644 --- a/libavcodec/fic.c +++ b/libavcodec/fic.c @@ -85,12 +85,12 @@ static const uint8_t fic_header[7] = { 0, 0, 1, 'F', 'I', 'C', 'V' }; static av_always_inline void fic_idct(int16_t *blk, int step, int shift, int rnd) { - const int t0 = 27246 * blk[3 * step] + 18405 * blk[5 * step]; - const int t1 = 27246 * blk[5 * step] - 18405 * blk[3 * step]; - const int t2 = 6393 * blk[7 * step] + 32139 * blk[1 * step]; - const int t3 = 6393 * blk[1 * step] - 32139 * blk[7 * step]; - const unsigned t4 = 5793U * (t2 + t0 + 0x800 >> 12); - const unsigned t5 = 5793U * (t3 + t1 + 0x800 >> 12); + const unsigned t0 = 27246 * blk[3 * step] + 18405 * blk[5 * step]; + const unsigned t1 = 27246 * blk[5 * step] - 18405 * blk[3 * step]; + const unsigned t2 = 6393 * blk[7 * step] + 32139 * blk[1 * step]; + const unsigned t3 = 6393 * blk[1 * step] - 32139 * blk[7 * step]; + const unsigned t4 = 5793U * ((int)(t2 + t0 + 0x800) >> 12); + const unsigned t5 = 5793U * ((int)(t3 + t1 + 0x800) >> 12); const unsigned t6 = t2 - t0; const unsigned t7 = t3 - t1; const unsigned t8 = 17734 * blk[2 * step] - 42813 * blk[6 * step]; From e7b9d136a1ba2d048b1a17df5778e426b825676d Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 17 Aug 2017 23:40:45 +0200 Subject: [PATCH 2797/3374] avcodec/cngdec: Check skip_samples Without this its possible to make the new decode API decode billions of samples out of a empty input and never return to the caller before all samples have been created and discarded. Fixes: Timeout Fixes: 2992/clusterfuzz-testcase-6649611793989632 Signed-off-by: Michael Niedermayer --- libavcodec/cngdec.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libavcodec/cngdec.c b/libavcodec/cngdec.c index 34f881448de86..1e884f3c33955 100644 --- a/libavcodec/cngdec.c +++ b/libavcodec/cngdec.c @@ -23,6 +23,7 @@ #include "libavutil/common.h" #include "libavutil/ffmath.h" +#include "libavutil/intreadwrite.h" #include "avcodec.h" #include "celp_filters.h" #include "internal.h" @@ -120,6 +121,11 @@ static int cng_decode_frame(AVCodecContext *avctx, void *data, } } + if (avctx->internal->skip_samples > 10 * avctx->frame_size) { + avctx->internal->skip_samples = 0; + return AVERROR_INVALIDDATA; + } + if (p->inited) { p->energy = p->energy / 2 + p->target_energy / 2; for (i = 0; i < p->order; i++) From e7053f3316f53fc31d25384e3b6c89c96f8a5b20 Mon Sep 17 00:00:00 2001 From: bnnm Date: Fri, 18 Aug 2017 19:45:16 +0200 Subject: [PATCH 2798/3374] lavf/bink: fix latest header and add all existing revisions KB2 'i' found in Life is Strange (Xbox 360), rest verified against binkconv.exe Signed-off-by: bnnm Signed-off-by: Michael Niedermayer --- libavformat/bink.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/libavformat/bink.c b/libavformat/bink.c index 20dba677dbd20..8a05082fcd8f3 100644 --- a/libavformat/bink.c +++ b/libavformat/bink.c @@ -65,10 +65,12 @@ static int probe(AVProbeData *p) int smush = AV_RN32(p->buf) == AV_RN32("SMUS"); do { - if (((b[0] == 'B' && b[1] == 'I' && b[2] == 'K' && - (b[3] == 'b' || b[3] == 'f' || b[3] == 'g' || b[3] == 'h' || b[3] == 'i')) || + if (((b[0] == 'B' && b[1] == 'I' && b[2] == 'K' && /* Bink 1 */ + (b[3] == 'b' || b[3] == 'f' || b[3] == 'g' || b[3] == 'h' || b[3] == 'i' || + b[3] == 'k')) || (b[0] == 'K' && b[1] == 'B' && b[2] == '2' && /* Bink 2 */ - (b[3] == 'a' || b[3] == 'd' || b[3] == 'f' || b[3] == 'g'))) && + (b[3] == 'a' || b[3] == 'd' || b[3] == 'f' || b[3] == 'g' || b[3] == 'h' || + b[3] == 'i' || b[3] == 'j' || b[3] == 'k'))) && AV_RL32(b+8) > 0 && // num_frames AV_RL32(b+20) > 0 && AV_RL32(b+20) <= BINK_MAX_WIDTH && AV_RL32(b+24) > 0 && AV_RL32(b+24) <= BINK_MAX_HEIGHT && @@ -159,7 +161,14 @@ static int read_header(AVFormatContext *s) } if (bink->num_audio_tracks) { - avio_skip(pb, 4 * bink->num_audio_tracks); + uint32_t signature = (vst->codecpar->codec_tag & 0xFFFFFF); + uint8_t revision = ((vst->codecpar->codec_tag >> 24) % 0xFF); + + if ((signature == AV_RL32("BIK") && (revision == 0x6b)) || /* k */ + (signature == AV_RL32("KB2") && (revision == 0x69 || revision == 0x6a || revision == 0x6b))) /* i,j,k */ + avio_skip(pb, 4); /* unknown new field */ + + avio_skip(pb, 4 * bink->num_audio_tracks); /* max decoded size */ for (i = 0; i < bink->num_audio_tracks; i++) { ast = avformat_new_stream(s, NULL); From 9c878651dbc8c795894740af74670b591551f619 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 30 Apr 2017 19:27:54 +0100 Subject: [PATCH 2799/3374] vaapi_encode: Move quality option to common code Use AVCodecContext.compression_level rather than a private option, replacing the H.264-specific quality option (which stays only for compatibility). This now works with the H.265 encoder in the i965 driver, as well as the existing cases with the H.264 encoder. (cherry picked from commit 19388a7200e5d99c703271f05dba1c806720e808) --- doc/encoders.texi | 9 ++++++--- libavcodec/vaapi_encode.c | 35 ++++++++++++++++++++++++++++++++++ libavcodec/vaapi_encode.h | 6 ++++++ libavcodec/vaapi_encode_h264.c | 25 ++---------------------- 4 files changed, 49 insertions(+), 26 deletions(-) diff --git a/doc/encoders.texi b/doc/encoders.texi index f20be54ce84f1..420c7969e103d 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -2554,7 +2554,13 @@ The following standard libavcodec options are used: @item @option{rc_init_occupancy} / @option{rc_initial_buffer_occupancy} @item +@option{compression_level} + +Speed / quality tradeoff: higher values are faster / worse quality. +@item @option{q} / @option{global_quality} + +Size / quality tradeoff: higher values are smaller / worse quality. @item @option{qmin} (only: @option{qmax} is not supported) @@ -2575,9 +2581,6 @@ The following standard libavcodec options are used: @option{level} sets the value of @emph{level_idc}. @table @option -@item quality -Set the local encoding quality/speed tradeoff (range 1-8, higher values are faster; not all -systems implement all levels). @item low_power Use low-power encoding mode. @end table diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index 2de5f76cabf32..22114bedbe6b6 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -1429,6 +1429,41 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) goto fail; } + if (avctx->compression_level >= 0) { +#if VA_CHECK_VERSION(0, 36, 0) + VAConfigAttrib attr = { VAConfigAttribEncQualityRange }; + + vas = vaGetConfigAttributes(ctx->hwctx->display, + ctx->va_profile, + ctx->va_entrypoint, + &attr, 1); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_WARNING, "Failed to query quality " + "attribute: will use default compression level.\n"); + } else { + if (avctx->compression_level > attr.value) { + av_log(avctx, AV_LOG_WARNING, "Invalid compression " + "level: valid range is 0-%d, using %d.\n", + attr.value, attr.value); + avctx->compression_level = attr.value; + } + + ctx->quality_params.misc.type = + VAEncMiscParameterTypeQualityLevel; + ctx->quality_params.quality.quality_level = + avctx->compression_level; + + ctx->global_params[ctx->nb_global_params] = + &ctx->quality_params.misc; + ctx->global_params_size[ctx->nb_global_params++] = + sizeof(ctx->quality_params); + } +#else + av_log(avctx, AV_LOG_WARNING, "The encode compression level " + "option is not supported with this VAAPI version.\n"); +#endif + } + ctx->input_order = 0; ctx->output_delay = avctx->max_b_frames; ctx->decode_delay = 1; diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h index 0edf27e4cbf7f..3bf0cc87c7d62 100644 --- a/libavcodec/vaapi_encode.h +++ b/libavcodec/vaapi_encode.h @@ -159,6 +159,12 @@ typedef struct VAAPIEncodeContext { VAEncMiscParameterBuffer misc; VAEncMiscParameterFrameRate fr; } fr_params; +#if VA_CHECK_VERSION(0, 36, 0) + struct { + VAEncMiscParameterBuffer misc; + VAEncMiscParameterBufferQualityLevel quality; + } quality_params; +#endif // Per-sequence parameter structure (VAEncSequenceParameterBuffer*). void *codec_sequence_params; diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index f9fcd805a49a9..0adb90328525d 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -154,14 +154,6 @@ typedef struct VAAPIEncodeH264Context { // Rate control configuration. int send_timing_sei; - -#if VA_CHECK_VERSION(0, 36, 0) - // Speed-quality tradeoff setting. - struct { - VAEncMiscParameterBuffer misc; - VAEncMiscParameterBufferQualityLevel quality; - } quality_params; -#endif } VAAPIEncodeH264Context; typedef struct VAAPIEncodeH264Options { @@ -1141,21 +1133,8 @@ static av_cold int vaapi_encode_h264_configure(AVCodecContext *avctx) av_assert0(0 && "Invalid RC mode."); } - if (opt->quality > 0) { -#if VA_CHECK_VERSION(0, 36, 0) - priv->quality_params.misc.type = - VAEncMiscParameterTypeQualityLevel; - priv->quality_params.quality.quality_level = opt->quality; - - ctx->global_params[ctx->nb_global_params] = - &priv->quality_params.misc; - ctx->global_params_size[ctx->nb_global_params++] = - sizeof(priv->quality_params); -#else - av_log(avctx, AV_LOG_WARNING, "The encode quality option is not " - "supported with this VAAPI version.\n"); -#endif - } + if (avctx->compression_level == FF_COMPRESSION_DEFAULT) + avctx->compression_level = opt->quality; return 0; } From c6a8c2a4f7396c4524a081df8a0ef9656946067d Mon Sep 17 00:00:00 2001 From: Jun Zhao Date: Tue, 8 Aug 2017 03:33:53 -0400 Subject: [PATCH 2800/3374] lavc/vaapi_encode_h264: add "coder" option support Follow libx264 style to support "coder" option, and set it to cabac by default. Signed-off-by: Yi A Wang Signed-off-by: Jun Zhao Reviewed-by: Steven Liu Signed-off-by: Mark Thompson --- libavcodec/vaapi_encode_h264.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index 0adb90328525d..90c7f7e3ccc85 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -160,6 +160,8 @@ typedef struct VAAPIEncodeH264Options { int qp; int quality; int low_power; + // Entropy encoder type. + int coder; } VAAPIEncodeH264Options; @@ -775,6 +777,8 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) VAEncPictureParameterBufferH264 *vpic = ctx->codec_picture_params; VAAPIEncodeH264Context *priv = ctx->priv_data; VAAPIEncodeH264MiscSequenceParams *mseq = &priv->misc_sequence_params; + VAAPIEncodeH264Options *opt = + (VAAPIEncodeH264Options*)ctx->codec_options_data; int i; { @@ -920,7 +924,7 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) vpic->num_ref_idx_l1_active_minus1 = 0; vpic->pic_fields.bits.entropy_coding_mode_flag = - ((avctx->profile & 0xff) != 66); + opt->coder ? ((avctx->profile & 0xff) != 66) : 0; vpic->pic_fields.bits.weighted_pred_flag = 0; vpic->pic_fields.bits.weighted_bipred_idc = 0; vpic->pic_fields.bits.transform_8x8_mode_flag = @@ -1262,6 +1266,12 @@ static const AVOption vaapi_encode_h264_options[] = { { "low_power", "Use low-power encoding mode (experimental: only supported " "on some platforms, does not support all features)", OFFSET(low_power), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS }, + { "coder", "Entropy coder type", + OFFSET(coder), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, FLAGS, "coder" }, + { "cavlc", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS, "coder" }, + { "cabac", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, FLAGS, "coder" }, + { "vlc", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS, "coder" }, + { "ac", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, FLAGS, "coder" }, { NULL }, }; From b8b84f9af55dede0df943083bc2dae38e4c06508 Mon Sep 17 00:00:00 2001 From: Jun Zhao Date: Tue, 15 Aug 2017 21:49:08 -0400 Subject: [PATCH 2801/3374] doc/encoders: add "coder" option documentation for h264_vaapi Signed-off-by: Jun Zhao Signed-off-by: Mark Thompson --- doc/encoders.texi | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/doc/encoders.texi b/doc/encoders.texi index 420c7969e103d..018fb4b07aace 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -2583,6 +2583,18 @@ Size / quality tradeoff: higher values are smaller / worse quality. @table @option @item low_power Use low-power encoding mode. +@item coder +Set entropy encoder (default is @emph{cabac}). Possible values: + +@table @samp +@item ac +@item cabac +Use CABAC. + +@item vlc +@item cavlc +Use CAVLC. +@end table @end table @item hevc_vaapi From f5361ee56f2164d3bf32fa4587dce6a1c35b4b92 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 20 Aug 2017 18:12:15 +0200 Subject: [PATCH 2802/3374] avfilter/vf_pseudocolor: add support for some subsampled formats --- libavfilter/vf_pseudocolor.c | 205 ++++++++++++++++++++++++++++++++--- 1 file changed, 190 insertions(+), 15 deletions(-) diff --git a/libavfilter/vf_pseudocolor.c b/libavfilter/vf_pseudocolor.c index 642e2901e9ddf..bc60ea0822142 100644 --- a/libavfilter/vf_pseudocolor.c +++ b/libavfilter/vf_pseudocolor.c @@ -71,6 +71,14 @@ typedef struct PseudoColorContext { char *comp_expr_str[4]; AVExpr *comp_expr[4]; float lut[4][256]; + + void (*filter[4])(int max, int width, int height, + const uint8_t *index, const uint8_t *src, + uint8_t *dst, + ptrdiff_t ilinesize, + ptrdiff_t slinesize, + ptrdiff_t dlinesize, + float *lut); } PseudoColorContext; #define OFFSET(x) offsetof(PseudoColorContext, x) @@ -87,6 +95,8 @@ static const AVOption pseudocolor_options[] = { static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_GRAY8, + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, + AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_GBRP, AV_PIX_FMT_YUVA444P, AV_PIX_FMT_GBRAP, AV_PIX_FMT_NONE @@ -100,6 +110,139 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_formats(ctx, fmts_list); } +static void pseudocolor_filter(int max, int width, int height, + const uint8_t *index, + const uint8_t *src, + uint8_t *dst, + ptrdiff_t ilinesize, + ptrdiff_t slinesize, + ptrdiff_t dlinesize, + float *lut) +{ + int x, y; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + int v = lut[index[x]]; + + if (v >= 0 && v <= max) { + dst[x] = v; + } else { + dst[x] = src[x]; + } + } + index += ilinesize; + src += slinesize; + dst += dlinesize; + } +} + +static void pseudocolor_filter_11(int max, int width, int height, + const uint8_t *index, + const uint8_t *src, + uint8_t *dst, + ptrdiff_t ilinesize, + ptrdiff_t slinesize, + ptrdiff_t dlinesize, + float *lut) +{ + int x, y; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + int v = lut[index[(y << 1) * ilinesize + (x << 1)]]; + + if (v >= 0 && v <= max) { + dst[x] = v; + } else { + dst[x] = src[x]; + } + } + src += slinesize; + dst += dlinesize; + } +} + +static void pseudocolor_filter_11d(int max, int width, int height, + const uint8_t *index, + const uint8_t *src, + uint8_t *dst, + ptrdiff_t ilinesize, + ptrdiff_t slinesize, + ptrdiff_t dlinesize, + float *lut) +{ + int x, y; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + int v = lut[index[(y >> 1) * ilinesize + (x >> 1)]]; + + if (v >= 0 && v <= max) { + dst[x] = v; + } else { + dst[x] = src[x]; + } + } + src += slinesize; + dst += dlinesize; + } +} + +static void pseudocolor_filter_10(int max, int width, int height, + const uint8_t *index, + const uint8_t *src, + uint8_t *dst, + ptrdiff_t ilinesize, + ptrdiff_t slinesize, + ptrdiff_t dlinesize, + float *lut) +{ + int x, y; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + int v = lut[index[x << 1]]; + + if (v >= 0 && v <= max) { + dst[x] = v; + } else { + dst[x] = src[x]; + } + } + index += ilinesize; + src += slinesize; + dst += dlinesize; + } +} + +static void pseudocolor_filter_10d(int max, int width, int height, + const uint8_t *index, + const uint8_t *src, + uint8_t *dst, + ptrdiff_t ilinesize, + ptrdiff_t slinesize, + ptrdiff_t dlinesize, + float *lut) +{ + int x, y; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + int v = lut[index[x >> 1]]; + + if (v >= 0 && v <= max) { + dst[x] = v; + } else { + dst[x] = src[x]; + } + } + index += ilinesize; + src += slinesize; + dst += dlinesize; + } +} + static int config_input(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; @@ -169,6 +312,46 @@ static int config_input(AVFilterLink *inlink) } } + switch (inlink->format) { + case AV_PIX_FMT_YUV444P: + case AV_PIX_FMT_YUVA444P: + case AV_PIX_FMT_GBRP: + case AV_PIX_FMT_GBRAP: + case AV_PIX_FMT_GRAY8: + s->filter[0] = s->filter[1] = s->filter[2] = s->filter[3] = pseudocolor_filter; + break; + case AV_PIX_FMT_YUV420P: + case AV_PIX_FMT_YUVA420P: + switch (s->index) { + case 0: + case 3: + s->filter[0] = s->filter[3] = pseudocolor_filter; + s->filter[1] = s->filter[2] = pseudocolor_filter_11; + break; + case 1: + case 2: + s->filter[0] = s->filter[3] = pseudocolor_filter_11d; + s->filter[1] = s->filter[2] = pseudocolor_filter; + break; + } + break; + case AV_PIX_FMT_YUV422P: + case AV_PIX_FMT_YUVA422P: + switch (s->index) { + case 0: + case 3: + s->filter[0] = s->filter[3] = pseudocolor_filter; + s->filter[1] = s->filter[2] = pseudocolor_filter_10; + break; + case 1: + case 2: + s->filter[0] = s->filter[3] = pseudocolor_filter_10d; + s->filter[1] = s->filter[2] = pseudocolor_filter; + break; + } + break; + } + return 0; } @@ -178,7 +361,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) PseudoColorContext *s = ctx->priv; AVFilterLink *outlink = ctx->outputs[0]; AVFrame *out; - int x, y, plane; + int plane; out = ff_get_video_buffer(outlink, outlink->w, outlink->h); if (!out) { @@ -191,21 +374,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) const uint8_t *index = in->data[s->index]; const uint8_t *src = in->data[plane]; uint8_t *dst = out->data[plane]; + ptrdiff_t ilinesize = in->linesize[s->index]; + ptrdiff_t slinesize = in->linesize[plane]; + ptrdiff_t dlinesize = out->linesize[plane]; - for (y = 0; y < s->height[plane]; y++) { - for (x = 0; x < s->width[plane]; x++) { - int v = s->lut[plane][index[x]]; - - if (v >= 0 && v <= s->max) { - dst[x] = v; - } else { - dst[x] = src[x]; - } - } - index += in->linesize[s->index]; - src += in->linesize[plane]; - dst += out->linesize[plane]; - } + s->filter[plane](s->max, s->width[plane], s->height[plane], + index, src, dst, ilinesize, slinesize, + dlinesize, s->lut[plane]); } av_frame_free(&in); From a165b53daa8a3a526d2328ca72c4aa9e7f163045 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 18 Aug 2017 16:42:58 +0200 Subject: [PATCH 2803/3374] avcodec/dirac_dwt_template: Fix integer overflow in vertical_compose53iL0() Fixes: runtime error: signed integer overflow: 2147483646 + 2 cannot be represented in type 'int' Fixes: 3013/clusterfuzz-testcase-minimized-4644084197097472 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/dirac_dwt_template.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/dirac_dwt_template.c b/libavcodec/dirac_dwt_template.c index 972c711cfff91..e436c247a1fd6 100644 --- a/libavcodec/dirac_dwt_template.c +++ b/libavcodec/dirac_dwt_template.c @@ -49,7 +49,7 @@ static void RENAME(vertical_compose53iL0)(uint8_t *_b0, uint8_t *_b1, uint8_t *_ TYPE *b1 = (TYPE *)_b1; TYPE *b2 = (TYPE *)_b2; for (i = 0; i < width; i++) - b1[i] -= (b0[i] + b2[i] + 2) >> 2; + b1[i] -= (int)(b0[i] + (unsigned)b2[i] + 2) >> 2; } static av_always_inline void RENAME(interleave)(TYPE *dst, TYPE *src0, TYPE *src1, int w2, From 8754ccd3b319fdf4e2beed5657a3e327999c64ce Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 18 Aug 2017 16:42:59 +0200 Subject: [PATCH 2804/3374] avcodec/pixlet: Fixes: undefined shift in av_mod_uintp2() Fixes: runtime error: shift exponent 4294967289 is too large for 32-bit type 'int' Fixes: 3030/clusterfuzz-testcase-minimized-4649809254285312 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/pixlet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/pixlet.c b/libavcodec/pixlet.c index 088226bdda83e..a9cfe085c9283 100644 --- a/libavcodec/pixlet.c +++ b/libavcodec/pixlet.c @@ -262,7 +262,7 @@ static int read_high_coeffs(AVCodecContext *avctx, uint8_t *src, int16_t *dst, i flag = 0; - if (state * 4ULL > 0xFF || i >= size) + if ((uint64_t)state > 0xFF / 4 || i >= size) continue; pfx = ((state + 8) >> 5) + (state ? ff_clz(state): 32) - 24; From 898ea658c8a46a105bcf831691a9aad3bb0f606d Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Fri, 18 Aug 2017 20:57:54 +0200 Subject: [PATCH 2805/3374] lavc/g726: Add a little-endian G.726 encoder. Fixes ticket #6596. --- libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 2 +- libavcodec/g726.c | 54 +++++++++++++++++++++++++++++++++++------- libavcodec/put_bits.h | 40 +++++++++++++++++++++++++++++++ libavcodec/version.h | 2 +- 5 files changed, 88 insertions(+), 11 deletions(-) diff --git a/libavcodec/Makefile b/libavcodec/Makefile index b0c39ac04046b..982d7f5179f87 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -763,6 +763,7 @@ OBJS-$(CONFIG_ADPCM_G722_ENCODER) += g722.o g722dsp.o g722enc.o OBJS-$(CONFIG_ADPCM_G726_DECODER) += g726.o OBJS-$(CONFIG_ADPCM_G726_ENCODER) += g726.o OBJS-$(CONFIG_ADPCM_G726LE_DECODER) += g726.o +OBJS-$(CONFIG_ADPCM_G726LE_ENCODER) += g726.o OBJS-$(CONFIG_ADPCM_IMA_AMV_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_APC_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_DAT4_DECODER) += adpcm.o adpcm_data.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 4712592a5fde9..1e5942d7d19ad 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -549,7 +549,7 @@ static void register_all(void) REGISTER_DECODER(ADPCM_EA_XAS, adpcm_ea_xas); REGISTER_ENCDEC (ADPCM_G722, adpcm_g722); REGISTER_ENCDEC (ADPCM_G726, adpcm_g726); - REGISTER_DECODER(ADPCM_G726LE, adpcm_g726le); + REGISTER_ENCDEC (ADPCM_G726LE, adpcm_g726le); REGISTER_DECODER(ADPCM_IMA_AMV, adpcm_ima_amv); REGISTER_DECODER(ADPCM_IMA_APC, adpcm_ima_apc); REGISTER_DECODER(ADPCM_IMA_DAT4, adpcm_ima_dat4); diff --git a/libavcodec/g726.c b/libavcodec/g726.c index 6922b40f87175..80cb064912839 100644 --- a/libavcodec/g726.c +++ b/libavcodec/g726.c @@ -292,7 +292,7 @@ static av_cold int g726_reset(G726Context *c) return 0; } -#if CONFIG_ADPCM_G726_ENCODER +#if CONFIG_ADPCM_G726_ENCODER || CONFIG_ADPCM_G726LE_ENCODER static int16_t g726_encode(G726Context* c, int16_t sig) { uint8_t i; @@ -308,6 +308,8 @@ static av_cold int g726_encode_init(AVCodecContext *avctx) { G726Context* c = avctx->priv_data; + c->little_endian = !strcmp(avctx->codec->name, "g726le"); + if (avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL && avctx->sample_rate != 8000) { av_log(avctx, AV_LOG_ERROR, "Sample rates other than 8kHz are not " @@ -356,9 +358,17 @@ static int g726_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, init_put_bits(&pb, avpkt->data, avpkt->size); for (i = 0; i < frame->nb_samples; i++) - put_bits(&pb, c->code_size, g726_encode(c, *samples++)); - - flush_put_bits(&pb); + if (c->little_endian) { + put_bits_le(&pb, c->code_size, g726_encode(c, *samples++)); + } else { + put_bits(&pb, c->code_size, g726_encode(c, *samples++)); + } + + if (c->little_endian) { + flush_put_bits_le(&pb); + } else { + flush_put_bits(&pb); + } avpkt->size = out_size; *got_packet_ptr = 1; @@ -372,6 +382,13 @@ static const AVOption options[] = { { NULL }, }; +static const AVCodecDefault defaults[] = { + { "b", "0" }, + { NULL }, +}; +#endif + +#if CONFIG_ADPCM_G726_ENCODER static const AVClass g726_class = { .class_name = "g726", .item_name = av_default_item_name, @@ -379,11 +396,6 @@ static const AVClass g726_class = { .version = LIBAVUTIL_VERSION_INT, }; -static const AVCodecDefault defaults[] = { - { "b", "0" }, - { NULL }, -}; - AVCodec ff_adpcm_g726_encoder = { .name = "g726", .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"), @@ -400,6 +412,30 @@ AVCodec ff_adpcm_g726_encoder = { }; #endif +#if CONFIG_ADPCM_G726LE_ENCODER +static const AVClass g726le_class = { + .class_name = "g726le", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_adpcm_g726le_encoder = { + .name = "g726le", + .long_name = NULL_IF_CONFIG_SMALL("G.726 little endian ADPCM (\"right-justified\")"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_ADPCM_G726LE, + .priv_data_size = sizeof(G726Context), + .init = g726_encode_init, + .encode2 = g726_encode_frame, + .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, + AV_SAMPLE_FMT_NONE }, + .priv_class = &g726le_class, + .defaults = defaults, +}; +#endif + #if CONFIG_ADPCM_G726_DECODER || CONFIG_ADPCM_G726LE_DECODER static av_cold int g726_decode_init(AVCodecContext *avctx) { diff --git a/libavcodec/put_bits.h b/libavcodec/put_bits.h index b85e88f28c33b..1ceb1cc766246 100644 --- a/libavcodec/put_bits.h +++ b/libavcodec/put_bits.h @@ -119,6 +119,18 @@ static inline void flush_put_bits(PutBitContext *s) s->bit_buf = 0; } +static inline void flush_put_bits_le(PutBitContext *s) +{ + while (s->bit_left < 32) { + av_assert0(s->buf_ptr < s->buf_end); + *s->buf_ptr++ = s->bit_buf; + s->bit_buf >>= 8; + s->bit_left += 8; + } + s->bit_left = 32; + s->bit_buf = 0; +} + #ifdef BITSTREAM_WRITER_LE #define avpriv_align_put_bits align_put_bits_unsupported_here #define avpriv_put_string ff_put_string_unsupported_here @@ -197,6 +209,34 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value) s->bit_left = bit_left; } +static inline void put_bits_le(PutBitContext *s, int n, unsigned int value) +{ + unsigned int bit_buf; + int bit_left; + + av_assert2(n <= 31 && value < (1U << n)); + + bit_buf = s->bit_buf; + bit_left = s->bit_left; + + bit_buf |= value << (32 - bit_left); + if (n >= bit_left) { + if (3 < s->buf_end - s->buf_ptr) { + AV_WL32(s->buf_ptr, bit_buf); + s->buf_ptr += 4; + } else { + av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); + av_assert2(0); + } + bit_buf = value >> bit_left; + bit_left += 32; + } + bit_left -= n; + + s->bit_buf = bit_buf; + s->bit_left = bit_left; +} + static inline void put_sbits(PutBitContext *pb, int n, int32_t value) { av_assert2(n >= 0 && n <= 31); diff --git a/libavcodec/version.h b/libavcodec/version.h index 02c4f41800a07..74730005793e0 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 102 +#define LIBAVCODEC_VERSION_MINOR 103 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ From bc488ec28aec4bc91ba47283c49c9f7f25696eaa Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 19 Aug 2017 23:38:58 +0200 Subject: [PATCH 2806/3374] avcodec/me_cmp: Fix crashes on ARM due to misalignment Adds a diff_pixels_unaligned() Fixes: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=872503 Signed-off-by: Michael Niedermayer --- libavcodec/me_cmp.c | 10 +++++----- libavcodec/pixblockdsp.c | 1 + libavcodec/pixblockdsp.h | 5 +++++ libavcodec/x86/pixblockdsp_init.c | 2 ++ 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/libavcodec/me_cmp.c b/libavcodec/me_cmp.c index 6639b919ff459..5e34a11593da3 100644 --- a/libavcodec/me_cmp.c +++ b/libavcodec/me_cmp.c @@ -628,7 +628,7 @@ static int dct_sad8x8_c(MpegEncContext *s, uint8_t *src1, av_assert2(h == 8); - s->pdsp.diff_pixels(temp, src1, src2, stride); + s->pdsp.diff_pixels_unaligned(temp, src1, src2, stride); s->fdsp.fdct(temp); return s->mecc.sum_abs_dctelem(temp); } @@ -668,7 +668,7 @@ static int dct264_sad8x8_c(MpegEncContext *s, uint8_t *src1, int16_t dct[8][8]; int i, sum = 0; - s->pdsp.diff_pixels(dct[0], src1, src2, stride); + s->pdsp.diff_pixels_unaligned(dct[0], src1, src2, stride); #define SRC(x) dct[i][x] #define DST(x, v) dct[i][x] = v @@ -695,7 +695,7 @@ static int dct_max8x8_c(MpegEncContext *s, uint8_t *src1, av_assert2(h == 8); - s->pdsp.diff_pixels(temp, src1, src2, stride); + s->pdsp.diff_pixels_unaligned(temp, src1, src2, stride); s->fdsp.fdct(temp); for (i = 0; i < 64; i++) @@ -714,7 +714,7 @@ static int quant_psnr8x8_c(MpegEncContext *s, uint8_t *src1, av_assert2(h == 8); s->mb_intra = 0; - s->pdsp.diff_pixels(temp, src1, src2, stride); + s->pdsp.diff_pixels_unaligned(temp, src1, src2, stride); memcpy(bak, temp, 64 * sizeof(int16_t)); @@ -817,7 +817,7 @@ static int bit8x8_c(MpegEncContext *s, uint8_t *src1, uint8_t *src2, av_assert2(h == 8); - s->pdsp.diff_pixels(temp, src1, src2, stride); + s->pdsp.diff_pixels_unaligned(temp, src1, src2, stride); s->block_last_index[0 /* FIXME */] = last = diff --git a/libavcodec/pixblockdsp.c b/libavcodec/pixblockdsp.c index 417c944e00bb0..50e1d1d735ef0 100644 --- a/libavcodec/pixblockdsp.c +++ b/libavcodec/pixblockdsp.c @@ -82,6 +82,7 @@ av_cold void ff_pixblockdsp_init(PixblockDSPContext *c, AVCodecContext *avctx) { const unsigned high_bit_depth = avctx->bits_per_raw_sample > 8; + c->diff_pixels_unaligned = c->diff_pixels = diff_pixels_c; switch (avctx->bits_per_raw_sample) { diff --git a/libavcodec/pixblockdsp.h b/libavcodec/pixblockdsp.h index 3ba1596a8856b..e036700ff067a 100644 --- a/libavcodec/pixblockdsp.h +++ b/libavcodec/pixblockdsp.h @@ -33,6 +33,11 @@ typedef struct PixblockDSPContext { const uint8_t *s1 /* align 8 */, const uint8_t *s2 /* align 8 */, ptrdiff_t stride); + void (*diff_pixels_unaligned)(int16_t *av_restrict block /* align 16 */, + const uint8_t *s1, + const uint8_t *s2, + ptrdiff_t stride); + } PixblockDSPContext; void ff_pixblockdsp_init(PixblockDSPContext *c, AVCodecContext *avctx); diff --git a/libavcodec/x86/pixblockdsp_init.c b/libavcodec/x86/pixblockdsp_init.c index fa9578a2d373a..ade55e01a3a48 100644 --- a/libavcodec/x86/pixblockdsp_init.c +++ b/libavcodec/x86/pixblockdsp_init.c @@ -39,12 +39,14 @@ av_cold void ff_pixblockdsp_init_x86(PixblockDSPContext *c, if (EXTERNAL_MMX(cpu_flags)) { if (!high_bit_depth) c->get_pixels = ff_get_pixels_mmx; + c->diff_pixels_unaligned = c->diff_pixels = ff_diff_pixels_mmx; } if (EXTERNAL_SSE2(cpu_flags)) { if (!high_bit_depth) c->get_pixels = ff_get_pixels_sse2; + c->diff_pixels_unaligned = c->diff_pixels = ff_diff_pixels_sse2; } } From 20a6b198b4849a5934736ac43517d24a70d20840 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Tue, 22 Aug 2017 10:21:42 +0800 Subject: [PATCH 2807/3374] avformat/hlsenc: move free fmp4_init_filename after hls_window operation fix ticket id: 6599 Signed-off-by: Steven Liu --- libavformat/hlsenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 74a3249b734d2..4a90886331beb 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -1745,7 +1745,6 @@ static int hls_write_trailer(struct AVFormatContext *s) hls->size = avio_tell(hls->vtt_avf->pb) - hls->start_pos; ff_format_io_close(s, &vtt_oc->pb); } - av_freep(&hls->fmp4_init_filename); av_freep(&hls->basename); av_freep(&hls->base_output_dirname); av_freep(&hls->key_basename); @@ -1754,6 +1753,7 @@ static int hls_write_trailer(struct AVFormatContext *s) hls->avf = NULL; hls_window(s, 1); + av_freep(&hls->fmp4_init_filename); if (vtt_oc) { av_freep(&hls->vtt_basename); av_freep(&hls->vtt_m3u8_name); From d8269519e4a338fa9521612db9b68c04a0fb2deb Mon Sep 17 00:00:00 2001 From: James Zern Date: Fri, 18 Aug 2017 16:37:02 -0700 Subject: [PATCH 2808/3374] vp9: set color range to MPEG for intraonly profile 0 this is undocumented in the vp9 bitstream and decoding specification doc, but matches libvpx Reviewed-by: "Ronald S. Bultje" Signed-off-by: James Zern --- libavcodec/vp9.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 7d8aced8c8929..94430db9a3c34 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -459,7 +459,7 @@ static int decode_frame_header(AVCodecContext *avctx, s->bytesperpixel = 1; s->pix_fmt = AV_PIX_FMT_YUV420P; avctx->colorspace = AVCOL_SPC_BT470BG; - avctx->color_range = AVCOL_RANGE_JPEG; + avctx->color_range = AVCOL_RANGE_MPEG; } s->s.h.refreshrefmask = get_bits(&s->gb, 8); w = get_bits(&s->gb, 16) + 1; From e1be40bbb57811b45d68a070dd66791315b01dc6 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Mon, 21 Aug 2017 15:32:32 +0200 Subject: [PATCH 2809/3374] avfilter/vf_pseudocolor: add high bitdepth support --- libavfilter/vf_pseudocolor.c | 235 ++++++++++++++++++++++++++++++++++- 1 file changed, 233 insertions(+), 2 deletions(-) diff --git a/libavfilter/vf_pseudocolor.c b/libavfilter/vf_pseudocolor.c index bc60ea0822142..f8f5372752904 100644 --- a/libavfilter/vf_pseudocolor.c +++ b/libavfilter/vf_pseudocolor.c @@ -70,7 +70,7 @@ typedef struct PseudoColorContext { double var_values[VAR_VARS_NB]; char *comp_expr_str[4]; AVExpr *comp_expr[4]; - float lut[4][256]; + float lut[4][256*256]; void (*filter[4])(int max, int width, int height, const uint8_t *index, const uint8_t *src, @@ -94,11 +94,28 @@ static const AVOption pseudocolor_options[] = { }; static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_GRAY8, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY16, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_GBRP, AV_PIX_FMT_YUVA444P, AV_PIX_FMT_GBRAP, + AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUVA422P9, + AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUVA420P9, + AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUVA444P9, + AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUVA420P10, + AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUVA422P10, + AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUVA444P10, + AV_PIX_FMT_YUV420P12, + AV_PIX_FMT_YUV422P12, + AV_PIX_FMT_YUV444P12, + AV_PIX_FMT_YUV420P14, + AV_PIX_FMT_YUV422P14, + AV_PIX_FMT_YUV444P14, + AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUVA420P16, + AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUVA422P16, + AV_PIX_FMT_YUV444P16, AV_PIX_FMT_YUVA444P16, + AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRAP10, + AV_PIX_FMT_GBRP16, AV_PIX_FMT_GBRAP16, AV_PIX_FMT_NONE }; @@ -243,6 +260,162 @@ static void pseudocolor_filter_10d(int max, int width, int height, } } +static void pseudocolor_filter_16(int max, int width, int height, + const uint8_t *iindex, + const uint8_t *ssrc, + uint8_t *ddst, + ptrdiff_t ilinesize, + ptrdiff_t slinesize, + ptrdiff_t dlinesize, + float *lut) +{ + const uint16_t *index = (const uint16_t *)iindex; + const uint16_t *src = (const uint16_t *)ssrc; + uint16_t *dst = (uint16_t *)ddst; + int x, y; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + int v = lut[index[x]]; + + if (v >= 0 && v <= max) { + dst[x] = v; + } else { + dst[x] = src[x]; + } + } + index += ilinesize / 2; + src += slinesize / 2; + dst += dlinesize / 2; + } +} + +static void pseudocolor_filter_16_10(int max, int width, int height, + const uint8_t *iindex, + const uint8_t *ssrc, + uint8_t *ddst, + ptrdiff_t ilinesize, + ptrdiff_t slinesize, + ptrdiff_t dlinesize, + float *lut) +{ + const uint16_t *index = (const uint16_t *)iindex; + const uint16_t *src = (const uint16_t *)ssrc; + uint16_t *dst = (uint16_t *)ddst; + int x, y; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + int v = lut[index[x << 1]]; + + if (v >= 0 && v <= max) { + dst[x] = v; + } else { + dst[x] = src[x]; + } + } + index += ilinesize / 2; + src += slinesize / 2; + dst += dlinesize / 2; + } +} + +static void pseudocolor_filter_16_10d(int max, int width, int height, + const uint8_t *iindex, + const uint8_t *ssrc, + uint8_t *ddst, + ptrdiff_t ilinesize, + ptrdiff_t slinesize, + ptrdiff_t dlinesize, + float *lut) +{ + const uint16_t *index = (const uint16_t *)iindex; + const uint16_t *src = (const uint16_t *)ssrc; + uint16_t *dst = (uint16_t *)ddst; + int x, y; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + int v = lut[index[x >> 1]]; + + if (v >= 0 && v <= max) { + dst[x] = v; + } else { + dst[x] = src[x]; + } + } + index += ilinesize / 2; + src += slinesize / 2; + dst += dlinesize / 2; + } +} + +static void pseudocolor_filter_16_11(int max, int width, int height, + const uint8_t *iindex, + const uint8_t *ssrc, + uint8_t *ddst, + ptrdiff_t ilinesize, + ptrdiff_t slinesize, + ptrdiff_t dlinesize, + float *lut) +{ + const uint16_t *index = (const uint16_t *)iindex; + const uint16_t *src = (const uint16_t *)ssrc; + uint16_t *dst = (uint16_t *)ddst; + int x, y; + + ilinesize /= 2; + dlinesize /= 2; + slinesize /= 2; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + int v = lut[index[(y << 1) * ilinesize + (x << 1)]]; + + if (v >= 0 && v <= max) { + dst[x] = v; + } else { + dst[x] = src[x]; + } + } + src += slinesize; + dst += dlinesize; + } +} + +static void pseudocolor_filter_16_11d(int max, int width, int height, + const uint8_t *iindex, + const uint8_t *ssrc, + uint8_t *ddst, + ptrdiff_t ilinesize, + ptrdiff_t slinesize, + ptrdiff_t dlinesize, + float *lut) +{ + const uint16_t *index = (const uint16_t *)iindex; + const uint16_t *src = (const uint16_t *)ssrc; + uint16_t *dst = (uint16_t *)ddst; + int x, y; + + ilinesize /= 2; + dlinesize /= 2; + slinesize /= 2; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + int v = lut[index[(y >> 1) * ilinesize + (x >> 1)]]; + + if (v >= 0 && v <= max) { + dst[x] = v; + } else { + dst[x] = src[x]; + } + } + src += slinesize; + dst += dlinesize; + } +} + static int config_input(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; @@ -350,6 +523,64 @@ static int config_input(AVFilterLink *inlink) break; } break; + case AV_PIX_FMT_YUV444P9: + case AV_PIX_FMT_YUVA444P9: + case AV_PIX_FMT_YUV444P10: + case AV_PIX_FMT_YUVA444P10: + case AV_PIX_FMT_YUV444P12: + case AV_PIX_FMT_YUV444P14: + case AV_PIX_FMT_YUV444P16: + case AV_PIX_FMT_YUVA444P16: + case AV_PIX_FMT_GBRP10: + case AV_PIX_FMT_GBRAP10: + case AV_PIX_FMT_GBRP16: + case AV_PIX_FMT_GBRAP16: + case AV_PIX_FMT_GRAY10: + case AV_PIX_FMT_GRAY16: + s->filter[0] = s->filter[1] = s->filter[2] = s->filter[3] = pseudocolor_filter_16; + break; + case AV_PIX_FMT_YUV422P9: + case AV_PIX_FMT_YUVA422P9: + case AV_PIX_FMT_YUV422P10: + case AV_PIX_FMT_YUVA422P10: + case AV_PIX_FMT_YUV422P12: + case AV_PIX_FMT_YUV422P14: + case AV_PIX_FMT_YUV422P16: + case AV_PIX_FMT_YUVA422P16: + switch (s->index) { + case 0: + case 3: + s->filter[0] = s->filter[3] = pseudocolor_filter_16; + s->filter[1] = s->filter[2] = pseudocolor_filter_16_10; + break; + case 1: + case 2: + s->filter[0] = s->filter[3] = pseudocolor_filter_16_10d; + s->filter[1] = s->filter[2] = pseudocolor_filter_16; + break; + } + break; + case AV_PIX_FMT_YUV420P9: + case AV_PIX_FMT_YUVA420P9: + case AV_PIX_FMT_YUV420P10: + case AV_PIX_FMT_YUVA420P10: + case AV_PIX_FMT_YUV420P12: + case AV_PIX_FMT_YUV420P14: + case AV_PIX_FMT_YUV420P16: + case AV_PIX_FMT_YUVA420P16: + switch (s->index) { + case 0: + case 3: + s->filter[0] = s->filter[3] = pseudocolor_filter_16; + s->filter[1] = s->filter[2] = pseudocolor_filter_16_11; + break; + case 1: + case 2: + s->filter[0] = s->filter[3] = pseudocolor_filter_16_11d; + s->filter[1] = s->filter[2] = pseudocolor_filter_16; + break; + } + break; } return 0; From a2e444d5bb2e3115d3afcc0cca9d1506c90436a2 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 22 Aug 2017 18:36:26 +0200 Subject: [PATCH 2810/3374] avcodec/pngdec: Fix () placement Signed-off-by: Michael Niedermayer --- libavcodec/pngdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index 4fc1c5a062786..dce8faf1688c2 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -858,7 +858,7 @@ static int decode_iccp_chunk(PNGDecContext *s, int length, AVFrame *f) length = FFMAX(length - 1, 0); - if ((ret = decode_zbuf(&bp, s->gb.buffer, s->gb.buffer + length) < 0)) + if ((ret = decode_zbuf(&bp, s->gb.buffer, s->gb.buffer + length)) < 0) return ret; av_bprint_finalize(&bp, (char **)&data); From 6f03ffb47d51368a4bbc87702df8446e4660845d Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 21 Aug 2017 02:15:49 +0200 Subject: [PATCH 2811/3374] avcodec/aacdec_template: Fix running cleanup in decode_ics_info() Fixes: out of array read Fixes: 2873/clusterfuzz-testcase-minimized-5924145713905664 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Previous version reviewed-by: Alex Converse Signed-off-by: Michael Niedermayer --- libavcodec/aacdec_template.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/libavcodec/aacdec_template.c b/libavcodec/aacdec_template.c index a539f74e6f36d..c59fd6aef61b9 100644 --- a/libavcodec/aacdec_template.c +++ b/libavcodec/aacdec_template.c @@ -1281,6 +1281,8 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics, const MPEG4AudioConfig *const m4ac = &ac->oc[1].m4ac; const int aot = m4ac->object_type; const int sampling_index = m4ac->sampling_index; + int ret_fail = AVERROR_INVALIDDATA; + if (aot != AOT_ER_AAC_ELD) { if (get_bits1(gb)) { av_log(ac->avctx, AV_LOG_ERROR, "Reserved bit set.\n"); @@ -1331,8 +1333,10 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics, ics->num_swb = ff_aac_num_swb_512[sampling_index]; ics->tns_max_bands = ff_tns_max_bands_512[sampling_index]; } - if (!ics->num_swb || !ics->swb_offset) - return AVERROR_BUG; + if (!ics->num_swb || !ics->swb_offset) { + ret_fail = AVERROR_BUG; + goto fail; + } } else { ics->swb_offset = ff_swb_offset_1024[sampling_index]; ics->num_swb = ff_aac_num_swb_1024[sampling_index]; @@ -1356,7 +1360,8 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics, if (aot == AOT_ER_AAC_LD) { av_log(ac->avctx, AV_LOG_ERROR, "LTP in ER AAC LD not yet implemented.\n"); - return AVERROR_PATCHWELCOME; + ret_fail = AVERROR_PATCHWELCOME; + goto fail; } if ((ics->ltp.present = get_bits(gb, 1))) decode_ltp(&ics->ltp, gb, ics->max_sfb); @@ -1375,7 +1380,7 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics, return 0; fail: ics->max_sfb = 0; - return AVERROR_INVALIDDATA; + return ret_fail; } /** From f3913dcc06854dbaf90890fa5853638e057b9bb1 Mon Sep 17 00:00:00 2001 From: Ravindra Date: Thu, 10 Aug 2017 11:59:30 +0530 Subject: [PATCH 2812/3374] libavdevice/decklink: configurablity to set max queue size Signed-off-by: Ravindra Patagar Signed-off-by: Marton Balint --- doc/indevs.texi | 5 +++++ libavdevice/decklink_common.h | 2 ++ libavdevice/decklink_common_c.h | 2 ++ libavdevice/decklink_dec.cpp | 7 +++++-- libavdevice/decklink_dec_c.c | 2 ++ libavdevice/version.h | 2 +- 6 files changed, 17 insertions(+), 3 deletions(-) diff --git a/doc/indevs.texi b/doc/indevs.texi index 09e33216dc88c..dc6cdb6deecd3 100644 --- a/doc/indevs.texi +++ b/doc/indevs.texi @@ -289,6 +289,11 @@ Sets the audio packet timestamp source. Must be @samp{video}, @samp{audio}, If set to @samp{true}, color bars are drawn in the event of a signal loss. Defaults to @samp{true}. +@item queue_size +Sets maximum input buffer size in bytes. If the buffering reaches this value, +incoming frames will be dropped. +Defaults to @samp{1073741824}. + @end table @subsection Examples diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h index c12cf18d70337..749eb0f8b8e59 100644 --- a/libavdevice/decklink_common.h +++ b/libavdevice/decklink_common.h @@ -1,6 +1,7 @@ /* * Blackmagic DeckLink common code * Copyright (c) 2013-2014 Ramiro Polla, Luca Barbato, Deti Fliegl + * Copyright (c) 2017 Akamai Technologies, Inc. * * This file is part of FFmpeg. * @@ -38,6 +39,7 @@ typedef struct AVPacketQueue { pthread_mutex_t mutex; pthread_cond_t cond; AVFormatContext *avctx; + int64_t max_q_size; } AVPacketQueue; struct decklink_ctx { diff --git a/libavdevice/decklink_common_c.h b/libavdevice/decklink_common_c.h index 72c5f9a71be17..e263480474cb9 100644 --- a/libavdevice/decklink_common_c.h +++ b/libavdevice/decklink_common_c.h @@ -1,6 +1,7 @@ /* * Blackmagic DeckLink common code * Copyright (c) 2013-2014 Ramiro Polla + * Copyright (c) 2017 Akamai Technologies, Inc. * * This file is part of FFmpeg. * @@ -48,6 +49,7 @@ struct decklink_cctx { int video_input; int draw_bars; char *format_code; + int64_t queue_size; }; #endif /* AVDEVICE_DECKLINK_COMMON_C_H */ diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index 72449a8eca5fe..64157b4c16fc4 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -1,6 +1,7 @@ /* * Blackmagic DeckLink input * Copyright (c) 2013-2014 Luca Barbato, Deti Fliegl + * Copyright (c) 2017 Akamai Technologies, Inc. * * This file is part of FFmpeg. * @@ -187,10 +188,12 @@ static uint8_t* teletext_data_unit_from_vanc_data(uint8_t *src, uint8_t *tgt, in static void avpacket_queue_init(AVFormatContext *avctx, AVPacketQueue *q) { + struct decklink_cctx *ctx = (struct decklink_cctx *)avctx->priv_data; memset(q, 0, sizeof(AVPacketQueue)); pthread_mutex_init(&q->mutex, NULL); pthread_cond_init(&q->cond, NULL); q->avctx = avctx; + q->max_q_size = ctx->queue_size; } static void avpacket_queue_flush(AVPacketQueue *q) @@ -230,8 +233,8 @@ static int avpacket_queue_put(AVPacketQueue *q, AVPacket *pkt) { AVPacketList *pkt1; - // Drop Packet if queue size is > 1GB - if (avpacket_queue_size(q) > 1024 * 1024 * 1024 ) { + // Drop Packet if queue size is > maximum queue size + if (avpacket_queue_size(q) > q->max_q_size) { av_log(q->avctx, AV_LOG_WARNING, "Decklink input buffer overrun!\n"); return -1; } diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c index 5b26d1257c461..e2118a619c7a3 100644 --- a/libavdevice/decklink_dec_c.c +++ b/libavdevice/decklink_dec_c.c @@ -1,6 +1,7 @@ /* * Blackmagic DeckLink input * Copyright (c) 2014 Deti Fliegl + * Copyright (c) 2017 Akamai Technologies, Inc. * * This file is part of FFmpeg. * @@ -64,6 +65,7 @@ static const AVOption options[] = { { "reference", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PTS_SRC_REFERENCE}, 0, 0, DEC, "pts_source"}, { "wallclock", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PTS_SRC_WALLCLOCK}, 0, 0, DEC, "pts_source"}, { "draw_bars", "draw bars on signal loss" , OFFSET(draw_bars), AV_OPT_TYPE_BOOL, { .i64 = 1}, 0, 1, DEC }, + { "queue_size", "input queue buffer size", OFFSET(queue_size), AV_OPT_TYPE_INT64, { .i64 = (1024 * 1024 * 1024)}, 0, INT64_MAX, DEC }, { NULL }, }; diff --git a/libavdevice/version.h b/libavdevice/version.h index 0c0660209857e..e0d3680578f83 100644 --- a/libavdevice/version.h +++ b/libavdevice/version.h @@ -29,7 +29,7 @@ #define LIBAVDEVICE_VERSION_MAJOR 57 #define LIBAVDEVICE_VERSION_MINOR 7 -#define LIBAVDEVICE_VERSION_MICRO 100 +#define LIBAVDEVICE_VERSION_MICRO 101 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ LIBAVDEVICE_VERSION_MINOR, \ From 8c2bb10ddfef1f151b9455d152c9aca91140a4b0 Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Sun, 20 Aug 2017 11:56:47 -0700 Subject: [PATCH 2813/3374] avcodec/utils: Fix signed integer overflow in rc_initial_buffer_occupancy initialization Signed integer overflow is undefined behavior. Detected with clang and -fsanitize=signed-integer-overflow Signed-off-by: Vitaly Buka Signed-off-by: Michael Niedermayer --- libavcodec/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 1336e921c92c2..1b8ad1d200b89 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -971,7 +971,7 @@ FF_ENABLE_DEPRECATION_WARNINGS } if (!avctx->rc_initial_buffer_occupancy) - avctx->rc_initial_buffer_occupancy = avctx->rc_buffer_size * 3 / 4; + avctx->rc_initial_buffer_occupancy = avctx->rc_buffer_size * 3LL / 4; if (avctx->ticks_per_frame && avctx->time_base.num && avctx->ticks_per_frame > INT_MAX / avctx->time_base.num) { From 4a404cb5b90b878cbe1bb528fac65cf508668cc5 Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Sun, 20 Aug 2017 11:56:47 -0700 Subject: [PATCH 2814/3374] avformat/mov: Fix signed integer overflows with total_size Signed integer overflow is undefined behavior. Detected with clang and -fsanitize=signed-integer-overflow Signed-off-by: Vitaly Buka Signed-off-by: Michael Niedermayer --- libavformat/mov.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 522ce60c2de51..a14c9f182beb2 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -5572,7 +5572,7 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (atom.size < 0) atom.size = INT64_MAX; - while (total_size + 8 <= atom.size && !avio_feof(pb)) { + while (total_size <= atom.size - 8 && !avio_feof(pb)) { int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL; a.size = atom.size; a.type=0; From eca2a49716ae1f42804dd3545da2f740edf03250 Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Sun, 20 Aug 2017 11:56:47 -0700 Subject: [PATCH 2815/3374] avformat/aviobuf: Fix signed integer overflow in avio_seek() Signed integer overflow is undefined behavior. Detected with clang and -fsanitize=signed-integer-overflow Signed-off-by: Vitaly Buka Signed-off-by: Michael Niedermayer --- libavformat/aviobuf.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index 7f4e740a33482..ec21fc7d38f24 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -259,6 +259,8 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence) offset1 = pos + (s->buf_ptr - s->buffer); if (offset == 0) return offset1; + if (offset > INT64_MAX - offset1) + return AVERROR(EINVAL); offset += offset1; } if (offset < 0) From c42a1388a6d1bfd8001bf6a4241d8ca27e49326d Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 23 Aug 2017 21:30:37 +0200 Subject: [PATCH 2816/3374] avformat/rtpdec_h264: Fix heap-buffer-overflow Fixes: rtp_sdp/poc.sdp Found-by: Bingchang Signed-off-by: Michael Niedermayer --- libavformat/rtpdec_h264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/rtpdec_h264.c b/libavformat/rtpdec_h264.c index 8dd56a549e444..6f8148ab6d5db 100644 --- a/libavformat/rtpdec_h264.c +++ b/libavformat/rtpdec_h264.c @@ -166,7 +166,7 @@ static int sdp_parse_fmtp_config_h264(AVFormatContext *s, parse_profile_level_id(s, h264_data, value); } else if (!strcmp(attr, "sprop-parameter-sets")) { int ret; - if (value[strlen(value) - 1] == ',') { + if (*value == 0 || value[strlen(value) - 1] == ',') { av_log(s, AV_LOG_WARNING, "Missing PPS in sprop-parameter-sets, ignoring\n"); return 0; } From 37e8edc9f51545ad91cbdf7dbe796af93f011abe Mon Sep 17 00:00:00 2001 From: Dale Curtis Date: Mon, 17 Jul 2017 17:38:09 -0700 Subject: [PATCH 2817/3374] avformat/mov: Fix trampling of ctts during seeks when sidx support is enabled. When sidx box support is enabled, the code will skip reading all trun boxes (each containing ctts entries for samples inthat box). If seeks are attempted before all ctts values are known, the old code would dump ctts entries into the wrong location. These are then used to compute pts values which leads to out of order and incorrectly timestamped packets. This patch fixes ctts processing by always using the index returned by av_add_index_entry() as the ctts_data index. When the index gains new entries old values are reshuffled as appropriate. This approach makes sense since the mov demuxer is already relying on the mapping of AVIndex entries to samples for correct demuxing. As a result of this all ctts entries are now 1-count. A followup change will be submitted to remove support for > 1 count entries which will simplify seeking. Notes for future improvement: Probably there are other boxes (stts, stsc, etc) that are impacted by this issue... this patch only attempts to fix ctts since it completely breaks packet timestamping. This patch continues using an array for the ctts data, which is not the most ideal given the rearrangement that needs to happen (via memmove as new entries are read in). Ideally AVIndex and the ctts data would be set-type structures so addition is always worst case O(lg(n)) instead of the O(n^2) that exists now; this slowdown is noticeable during seeks. Signed-off-by: Dale Curtis Signed-off-by: Michael Niedermayer --- libavformat/isom.h | 1 + libavformat/mov.c | 92 +++++++++++++++++---------- tests/fate/seek.mak | 3 + tests/ref/seek/extra-mp4 | 134 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 195 insertions(+), 35 deletions(-) create mode 100644 tests/ref/seek/extra-mp4 diff --git a/libavformat/isom.h b/libavformat/isom.h index ff009b0896933..fdd98c28f5bf9 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -137,6 +137,7 @@ typedef struct MOVStreamContext { unsigned int stts_count; MOVStts *stts_data; unsigned int ctts_count; + unsigned int ctts_allocated_size; MOVStts *ctts_data; unsigned int stsc_count; MOVStsc *stsc_data; diff --git a/libavformat/mov.c b/libavformat/mov.c index a14c9f182beb2..876f48d9125aa 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -74,6 +74,8 @@ typedef struct MOVParseTableEntry { static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom); static int mov_read_mfra(MOVContext *c, AVIOContext *f); +static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size, + int count, int duration); static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, unsigned len, const char *key) @@ -2711,7 +2713,7 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; MOVStreamContext *sc; - unsigned int i, entries, ctts_count = 0; + unsigned int i, j, entries, ctts_count = 0; if (c->fc->nb_streams < 1) return 0; @@ -2729,7 +2731,7 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (entries >= UINT_MAX / sizeof(*sc->ctts_data)) return AVERROR_INVALIDDATA; av_freep(&sc->ctts_data); - sc->ctts_data = av_realloc(NULL, entries * sizeof(*sc->ctts_data)); + sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data)); if (!sc->ctts_data) return AVERROR(ENOMEM); @@ -2744,9 +2746,9 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom) continue; } - sc->ctts_data[ctts_count].count = count; - sc->ctts_data[ctts_count].duration = duration; - ctts_count++; + /* Expand entries such that we have a 1-1 mapping with samples. */ + for (j = 0; j < count; j++) + add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size, 1, duration); av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n", count, duration); @@ -3049,7 +3051,6 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) int64_t index; int64_t index_ctts_count; int flags; - unsigned int ctts_allocated_size = 0; int64_t start_dts = 0; int64_t edit_list_media_time_dts = 0; int64_t edit_list_start_encountered = 0; @@ -3084,6 +3085,7 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) msc->ctts_count = 0; msc->ctts_index = 0; msc->ctts_sample = 0; + msc->ctts_allocated_size = 0; // If the dts_shift is positive (in case of negative ctts values in mov), // then negate the DTS by dts_shift @@ -3193,7 +3195,7 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) ctts_sample_old++; if (ctts_sample_old == ctts_data_old[ctts_index_old].count) { if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count, - &ctts_allocated_size, + &msc->ctts_allocated_size, ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample, ctts_data_old[ctts_index_old].duration) == -1) { av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n", @@ -3292,7 +3294,7 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) if (ctts_data_old && ctts_sample_old != 0) { if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count, - &ctts_allocated_size, + &msc->ctts_allocated_size, ctts_sample_old - edit_list_start_ctts_sample, ctts_data_old[ctts_index_old].duration) == -1) { av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n", @@ -4262,7 +4264,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) int64_t dts; int data_offset = 0; unsigned entries, first_sample_flags = frag->flags; - int flags, distance, i, err, old_nb_index_entries; + int flags, distance, i; for (i = 0; i < c->fc->nb_streams; i++) { if (c->fc->streams[i]->id == frag->track_id) { @@ -4290,21 +4292,20 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (!sc->ctts_count && sc->sample_count) { /* Complement ctts table if moov atom doesn't have ctts atom. */ - ctts_data = av_realloc(NULL, sizeof(*sc->ctts_data)); + ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, sizeof(*sc->ctts_data) * sc->sample_count); if (!ctts_data) return AVERROR(ENOMEM); + /* Don't use a count greater than 1 here since it will leave a gap in + * the ctts index which the code below relies on being sequential. */ sc->ctts_data = ctts_data; - sc->ctts_data[sc->ctts_count].count = sc->sample_count; - sc->ctts_data[sc->ctts_count].duration = 0; - sc->ctts_count++; + for (i = 0; i < sc->sample_count; i++) { + sc->ctts_data[sc->ctts_count].count = 1; + sc->ctts_data[sc->ctts_count].duration = 0; + sc->ctts_count++; + } } if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data)) return AVERROR_INVALIDDATA; - if ((err = av_reallocp_array(&sc->ctts_data, entries + sc->ctts_count, - sizeof(*sc->ctts_data))) < 0) { - sc->ctts_count = 0; - return err; - } if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb); if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb); dts = sc->track_end - sc->time_offset; @@ -4315,26 +4316,28 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) unsigned sample_size = frag->size; int sample_flags = i ? frag->flags : first_sample_flags; unsigned sample_duration = frag->duration; + unsigned ctts_duration = 0; int keyframe = 0; + int ctts_index = 0; + int old_nb_index_entries = st->nb_index_entries; if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb); if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb); if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb); - sc->ctts_data[sc->ctts_count].count = 1; - sc->ctts_data[sc->ctts_count].duration = (flags & MOV_TRUN_SAMPLE_CTS) ? - avio_rb32(pb) : 0; - mov_update_dts_shift(sc, sc->ctts_data[sc->ctts_count].duration); + if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb); + + mov_update_dts_shift(sc, ctts_duration); if (frag->time != AV_NOPTS_VALUE) { if (c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) { int64_t pts = frag->time; av_log(c->fc, AV_LOG_DEBUG, "found frag time %"PRId64 " sc->dts_shift %d ctts.duration %d" " sc->time_offset %"PRId64" flags & MOV_TRUN_SAMPLE_CTS %d\n", pts, - sc->dts_shift, sc->ctts_data[sc->ctts_count].duration, + sc->dts_shift, ctts_duration, sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS); dts = pts - sc->dts_shift; if (flags & MOV_TRUN_SAMPLE_CTS) { - dts -= sc->ctts_data[sc->ctts_count].duration; + dts -= ctts_duration; } else { dts -= sc->time_offset; } @@ -4346,7 +4349,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) } frag->time = AV_NOPTS_VALUE; } - sc->ctts_count++; + if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) keyframe = 1; else @@ -4355,19 +4358,38 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES)); if (keyframe) distance = 0; - old_nb_index_entries = st->nb_index_entries; - err = av_add_index_entry(st, offset, dts, sample_size, distance, - keyframe ? AVINDEX_KEYFRAME : 0); - if (err < 0) { + ctts_index = av_add_index_entry(st, offset, dts, sample_size, distance, + keyframe ? AVINDEX_KEYFRAME : 0); + if (ctts_index >= 0 && old_nb_index_entries < st->nb_index_entries) { + unsigned int size_needed = st->nb_index_entries * sizeof(*sc->ctts_data); + unsigned int request_size = size_needed > sc->ctts_allocated_size ? + FFMAX(size_needed, 2 * sc->ctts_allocated_size) : size_needed; + ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, request_size); + if (!ctts_data) { + av_freep(&sc->ctts_data); + return AVERROR(ENOMEM); + } + + sc->ctts_data = ctts_data; + if (ctts_index != old_nb_index_entries) { + memmove(sc->ctts_data + ctts_index + 1, sc->ctts_data + ctts_index, + sizeof(*sc->ctts_data) * (sc->ctts_count - ctts_index)); + if (ctts_index <= sc->current_sample) { + // if we inserted a new item before the current sample, move the + // counter ahead so it is still pointing to the same sample. + sc->current_sample++; + } + } + + sc->ctts_data[ctts_index].count = 1; + sc->ctts_data[ctts_index].duration = ctts_duration; + sc->ctts_count++; + } else { av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n"); - } else if (err <= sc->current_sample && err + 1 != st->nb_index_entries && - st->nb_index_entries != old_nb_index_entries) { - // if we inserted a new item before the current sample, move the - // counter ahead so it is still pointing to the same sample. - sc->current_sample++; } + av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", " - "size %u, distance %d, keyframe %d\n", st->index, err, + "size %u, distance %d, keyframe %d\n", st->index, ctts_index, offset, dts, sample_size, distance, keyframe); distance++; dts += sample_duration; diff --git a/tests/fate/seek.mak b/tests/fate/seek.mak index f835da5226ed2..1a6e584987052 100644 --- a/tests/fate/seek.mak +++ b/tests/fate/seek.mak @@ -248,7 +248,10 @@ FATE_SEEK += $(FATE_SEEK_LAVF-yes:%=fate-seek-lavf-%) FATE_SEEK_EXTRA-$(CONFIG_MP3_DEMUXER) += fate-seek-extra-mp3 FATE_SEEK_EXTRA-$(call ALLYES, CACHE_PROTOCOL PIPE_PROTOCOL MP3_DEMUXER) += fate-seek-cache-pipe FATE_SEEK_EXTRA-$(CONFIG_MATROSKA_DEMUXER) += fate-seek-mkv-codec-delay +FATE_SEEK_EXTRA-$(CONFIG_MOV_DEMUXER) += fate-seek-extra-mp4 + fate-seek-extra-mp3: CMD = run libavformat/tests/seek$(EXESUF) $(TARGET_SAMPLES)/gapless/gapless.mp3 -fastseek 1 +fate-seek-extra-mp4: CMD = run libavformat/tests/seek$(EXESUF) $(TARGET_SAMPLES)/mov/buck480p30_na.mp4 -duration 180 -frames 4 fate-seek-cache-pipe: CMD = cat $(TARGET_SAMPLES)/gapless/gapless.mp3 | run libavformat/tests/seek$(EXESUF) cache:pipe:0 -read_ahead_limit -1 fate-seek-mkv-codec-delay: CMD = run libavformat/tests/seek$(EXESUF) $(TARGET_SAMPLES)/mkv/codec_delay_opus.mkv diff --git a/tests/ref/seek/extra-mp4 b/tests/ref/seek/extra-mp4 new file mode 100644 index 0000000000000..c25544c0954b9 --- /dev/null +++ b/tests/ref/seek/extra-mp4 @@ -0,0 +1,134 @@ +ret: 0 st: 0 flags:1 dts:-0.033333 pts: 0.000000 pos: 1287 size: 183 +ret: 0 st: 0 flags:0 dts: 0.000000 pts: 0.033333 pos: 1470 size: 24 +ret: 0 st: 0 flags:0 dts: 0.033333 pts: 0.066667 pos: 1494 size: 6779 +ret: 0 st: 0 flags:0 dts: 0.066667 pts: 0.100000 pos: 8273 size: 11041 +ret: 0 st:-1 flags:0 ts:-1.000000 +ret: 0 st: 0 flags:1 dts:-0.033333 pts: 0.000000 pos: 1287 size: 183 +ret: 0 st: 0 flags:0 dts: 0.000000 pts: 0.033333 pos: 1470 size: 24 +ret: 0 st: 0 flags:0 dts: 0.033333 pts: 0.066667 pos: 1494 size: 6779 +ret: 0 st: 0 flags:0 dts: 0.066667 pts: 0.100000 pos: 8273 size: 11041 +ret: 0 st:-1 flags:1 ts: 101.894167 +ret: 0 st: 0 flags:1 dts: 101.300000 pts: 101.333333 pos:10982311 size: 67237 +ret: 0 st: 0 flags:0 dts: 101.333333 pts: 101.433333 pos:11049548 size: 3524 +ret: 0 st: 0 flags:0 dts: 101.366667 pts: 101.366667 pos:11053072 size: 562 +ret: 0 st: 0 flags:0 dts: 101.400000 pts: 101.400000 pos:11053634 size: 599 +ret: 0 st: 0 flags:0 ts: 24.788333 +ret: 0 st: 0 flags:1 dts: 25.300000 pts: 25.333333 pos:2607246 size: 40273 +ret: 0 st: 0 flags:0 dts: 25.333333 pts: 25.433333 pos:2647519 size: 2959 +ret: 0 st: 0 flags:0 dts: 25.366667 pts: 25.366667 pos:2650478 size: 197 +ret: 0 st: 0 flags:0 dts: 25.400000 pts: 25.400000 pos:2650675 size: 230 +ret: 0 st: 0 flags:1 ts: 127.682500 +ret: 0 st: 0 flags:1 dts: 126.633333 pts: 126.666667 pos:13359975 size: 68741 +ret: 0 st: 0 flags:0 dts: 126.666667 pts: 126.766667 pos:13428716 size: 2914 +ret: 0 st: 0 flags:0 dts: 126.700000 pts: 126.700000 pos:13431630 size: 781 +ret: 0 st: 0 flags:0 dts: 126.733333 pts: 126.733333 pos:13432411 size: 817 +ret: 0 st:-1 flags:0 ts: 50.576668 +ret: 0 st: 0 flags:1 dts: 50.600000 pts: 50.633333 pos:5858254 size: 67903 +ret: 0 st: 0 flags:0 dts: 50.633333 pts: 50.733333 pos:5926157 size: 1307 +ret: 0 st: 0 flags:0 dts: 50.666667 pts: 50.666667 pos:5927464 size: 150 +ret: 0 st: 0 flags:0 dts: 50.700000 pts: 50.700000 pos:5927614 size: 176 +ret: 0 st:-1 flags:1 ts: 153.470835 +ret: 0 st: 0 flags:1 dts: 153.466667 pts: 153.500000 pos:15867700 size: 96169 +ret: 0 st: 0 flags:0 dts: 153.500000 pts: 153.533333 pos:15963869 size: 785 +ret: 0 st: 0 flags:0 dts: 153.533333 pts: 153.633333 pos:15964654 size: 3135 +ret: 0 st: 0 flags:0 dts: 153.566667 pts: 153.566667 pos:15967789 size: 859 +ret: 0 st: 0 flags:0 ts: 76.365000 +ret: 0 st: 0 flags:1 dts: 77.833333 pts: 77.866667 pos:8659657 size: 41182 +ret: 0 st: 0 flags:0 dts: 77.866667 pts: 77.966667 pos:8700839 size: 4197 +ret: 0 st: 0 flags:0 dts: 77.900000 pts: 77.900000 pos:8705036 size: 653 +ret: 0 st: 0 flags:0 dts: 77.933333 pts: 77.933333 pos:8705689 size: 751 +ret: 0 st: 0 flags:1 ts:-0.740833 +ret: 0 st: 0 flags:1 dts:-0.033333 pts: 0.000000 pos: 1287 size: 183 +ret: 0 st: 0 flags:0 dts: 0.000000 pts: 0.033333 pos: 1470 size: 24 +ret: 0 st: 0 flags:0 dts: 0.033333 pts: 0.066667 pos: 1494 size: 6779 +ret: 0 st: 0 flags:0 dts: 0.066667 pts: 0.100000 pos: 8273 size: 11041 +ret: 0 st:-1 flags:0 ts: 102.153336 +ret: 0 st: 0 flags:1 dts: 104.066667 pts: 104.100000 pos:11116461 size:112929 +ret: 0 st: 0 flags:0 dts: 104.100000 pts: 104.133333 pos:11229390 size: 585 +ret: 0 st: 0 flags:0 dts: 104.133333 pts: 104.166667 pos:11229975 size: 797 +ret: 0 st: 0 flags:0 dts: 104.166667 pts: 104.200000 pos:11230772 size: 810 +ret: 0 st:-1 flags:1 ts: 25.047503 +ret: 0 st: 0 flags:1 dts: 20.233333 pts: 20.266667 pos:2223959 size: 51823 +ret: 0 st: 0 flags:0 dts: 20.266667 pts: 20.300000 pos:2275782 size: 488 +ret: 0 st: 0 flags:0 dts: 20.300000 pts: 20.400000 pos:2276270 size: 670 +ret: 0 st: 0 flags:0 dts: 20.333333 pts: 20.333333 pos:2276940 size: 84 +ret: 0 st: 0 flags:0 ts: 127.941667 +ret: 0 st: 0 flags:1 dts: 131.233333 pts: 131.266667 pos:13727953 size: 62229 +ret: 0 st: 0 flags:0 dts: 131.266667 pts: 131.366667 pos:13790182 size: 2349 +ret: 0 st: 0 flags:0 dts: 131.300000 pts: 131.300000 pos:13792531 size: 571 +ret: 0 st: 0 flags:0 dts: 131.333333 pts: 131.333333 pos:13793102 size: 1190 +ret: 0 st: 0 flags:1 ts: 50.835833 +ret: 0 st: 0 flags:1 dts: 50.600000 pts: 50.633333 pos:5858254 size: 67903 +ret: 0 st: 0 flags:0 dts: 50.633333 pts: 50.733333 pos:5926157 size: 1307 +ret: 0 st: 0 flags:0 dts: 50.666667 pts: 50.666667 pos:5927464 size: 150 +ret: 0 st: 0 flags:0 dts: 50.700000 pts: 50.700000 pos:5927614 size: 176 +ret: 0 st:-1 flags:0 ts: 153.730004 +ret: 0 st: 0 flags:1 dts: 157.033333 pts: 157.066667 pos:16225365 size: 82738 +ret: 0 st: 0 flags:0 dts: 157.066667 pts: 157.166667 pos:16308103 size: 2273 +ret: 0 st: 0 flags:0 dts: 157.100000 pts: 157.100000 pos:16310376 size: 350 +ret: 0 st: 0 flags:0 dts: 157.133333 pts: 157.133333 pos:16310726 size: 337 +ret: 0 st:-1 flags:1 ts: 76.624171 +ret: 0 st: 0 flags:1 dts: 75.966667 pts: 76.000000 pos:8520178 size: 94395 +ret: 0 st: 0 flags:0 dts: 76.000000 pts: 76.100000 pos:8614573 size: 483 +ret: 0 st: 0 flags:0 dts: 76.033333 pts: 76.033333 pos:8615056 size: 37 +ret: 0 st: 0 flags:0 dts: 76.066667 pts: 76.066667 pos:8615093 size: 56 +ret: 0 st: 0 flags:0 ts:-0.481667 +ret: 0 st: 0 flags:1 dts:-0.033333 pts: 0.000000 pos: 1287 size: 183 +ret: 0 st: 0 flags:0 dts: 0.000000 pts: 0.033333 pos: 1470 size: 24 +ret: 0 st: 0 flags:0 dts: 0.033333 pts: 0.066667 pos: 1494 size: 6779 +ret: 0 st: 0 flags:0 dts: 0.066667 pts: 0.100000 pos: 8273 size: 11041 +ret: 0 st: 0 flags:1 ts: 102.412500 +ret: 0 st: 0 flags:1 dts: 101.300000 pts: 101.333333 pos:10982311 size: 67237 +ret: 0 st: 0 flags:0 dts: 101.333333 pts: 101.433333 pos:11049548 size: 3524 +ret: 0 st: 0 flags:0 dts: 101.366667 pts: 101.366667 pos:11053072 size: 562 +ret: 0 st: 0 flags:0 dts: 101.400000 pts: 101.400000 pos:11053634 size: 599 +ret: 0 st:-1 flags:0 ts: 25.306672 +ret: 0 st: 0 flags:1 dts: 27.400000 pts: 27.433333 pos:2674605 size:127383 +ret: 0 st: 0 flags:0 dts: 27.433333 pts: 27.466667 pos:2801988 size: 68 +ret: 0 st: 0 flags:0 dts: 27.466667 pts: 27.500000 pos:2802268 size: 1754 +ret: 0 st: 0 flags:0 dts: 27.500000 pts: 27.533333 pos:2804022 size: 4071 +ret: 0 st:-1 flags:1 ts: 128.200839 +ret: 0 st: 0 flags:1 dts: 127.833333 pts: 127.866667 pos:13514072 size: 67382 +ret: 0 st: 0 flags:0 dts: 127.866667 pts: 127.966667 pos:13581454 size: 2936 +ret: 0 st: 0 flags:0 dts: 127.900000 pts: 127.900000 pos:13584390 size: 451 +ret: 0 st: 0 flags:0 dts: 127.933333 pts: 127.933333 pos:13584841 size: 537 +ret: 0 st: 0 flags:0 ts: 51.095011 +ret: 0 st: 0 flags:1 dts: 52.033333 pts: 52.066667 pos:6028050 size:115809 +ret: 0 st: 0 flags:0 dts: 52.066667 pts: 52.166667 pos:6143859 size: 1620 +ret: 0 st: 0 flags:0 dts: 52.100000 pts: 52.100000 pos:6145479 size: 92 +ret: 0 st: 0 flags:0 dts: 52.133333 pts: 52.133333 pos:6145571 size: 533 +ret: 0 st: 0 flags:1 ts: 153.989178 +ret: 0 st: 0 flags:1 dts: 153.466667 pts: 153.500000 pos:15867700 size: 96169 +ret: 0 st: 0 flags:0 dts: 153.500000 pts: 153.533333 pos:15963869 size: 785 +ret: 0 st: 0 flags:0 dts: 153.533333 pts: 153.633333 pos:15964654 size: 3135 +ret: 0 st: 0 flags:0 dts: 153.566667 pts: 153.566667 pos:15967789 size: 859 +ret: 0 st:-1 flags:0 ts: 76.883340 +ret: 0 st: 0 flags:1 dts: 77.833333 pts: 77.866667 pos:8659657 size: 41182 +ret: 0 st: 0 flags:0 dts: 77.866667 pts: 77.966667 pos:8700839 size: 4197 +ret: 0 st: 0 flags:0 dts: 77.900000 pts: 77.900000 pos:8705036 size: 653 +ret: 0 st: 0 flags:0 dts: 77.933333 pts: 77.933333 pos:8705689 size: 751 +ret: 0 st:-1 flags:1 ts:-0.222493 +ret: 0 st: 0 flags:1 dts:-0.033333 pts: 0.000000 pos: 1287 size: 183 +ret: 0 st: 0 flags:0 dts: 0.000000 pts: 0.033333 pos: 1470 size: 24 +ret: 0 st: 0 flags:0 dts: 0.033333 pts: 0.066667 pos: 1494 size: 6779 +ret: 0 st: 0 flags:0 dts: 0.066667 pts: 0.100000 pos: 8273 size: 11041 +ret: 0 st: 0 flags:0 ts: 102.671678 +ret: 0 st: 0 flags:1 dts: 104.066667 pts: 104.100000 pos:11116461 size:112929 +ret: 0 st: 0 flags:0 dts: 104.100000 pts: 104.133333 pos:11229390 size: 585 +ret: 0 st: 0 flags:0 dts: 104.133333 pts: 104.166667 pos:11229975 size: 797 +ret: 0 st: 0 flags:0 dts: 104.166667 pts: 104.200000 pos:11230772 size: 810 +ret: 0 st: 0 flags:1 ts: 25.565844 +ret: 0 st: 0 flags:1 dts: 25.300000 pts: 25.333333 pos:2607246 size: 40273 +ret: 0 st: 0 flags:0 dts: 25.333333 pts: 25.433333 pos:2647519 size: 2959 +ret: 0 st: 0 flags:0 dts: 25.366667 pts: 25.366667 pos:2650478 size: 197 +ret: 0 st: 0 flags:0 dts: 25.400000 pts: 25.400000 pos:2650675 size: 230 +ret: 0 st:-1 flags:0 ts: 128.460008 +ret: 0 st: 0 flags:1 dts: 131.233333 pts: 131.266667 pos:13727953 size: 62229 +ret: 0 st: 0 flags:0 dts: 131.266667 pts: 131.366667 pos:13790182 size: 2349 +ret: 0 st: 0 flags:0 dts: 131.300000 pts: 131.300000 pos:13792531 size: 571 +ret: 0 st: 0 flags:0 dts: 131.333333 pts: 131.333333 pos:13793102 size: 1190 +ret: 0 st:-1 flags:1 ts: 51.354175 +ret: 0 st: 0 flags:1 dts: 50.600000 pts: 50.633333 pos:5858254 size: 67903 +ret: 0 st: 0 flags:0 dts: 50.633333 pts: 50.733333 pos:5926157 size: 1307 +ret: 0 st: 0 flags:0 dts: 50.666667 pts: 50.666667 pos:5927464 size: 150 +ret: 0 st: 0 flags:0 dts: 50.700000 pts: 50.700000 pos:5927614 size: 176 From 2b44dcbc44e99daf9515753e9fd4c2e1ea53a2fa Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 21 Aug 2017 00:18:48 +0200 Subject: [PATCH 2818/3374] avcodec/hevc_ps: Check delta_pocs in ff_hevc_decode_short_term_rps() Fixes: integer overflow Fixes: 2893/clusterfuzz-testcase-minimized-5809330567774208 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/hevc_ps.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index 21dbaf85a5faf..37eae226e2967 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -225,6 +225,12 @@ int ff_hevc_decode_short_term_rps(GetBitContext *gb, AVCodecContext *avctx, prev = 0; for (i = 0; i < rps->num_negative_pics; i++) { delta_poc = get_ue_golomb_long(gb) + 1; + if (delta_poc < 1 || delta_poc > 32768) { + av_log(avctx, AV_LOG_ERROR, + "Invalid value of delta_poc: %d\n", + delta_poc); + return AVERROR_INVALIDDATA; + } prev -= delta_poc; rps->delta_poc[i] = prev; rps->used[i] = get_bits1(gb); @@ -232,6 +238,12 @@ int ff_hevc_decode_short_term_rps(GetBitContext *gb, AVCodecContext *avctx, prev = 0; for (i = 0; i < nb_positive_pics; i++) { delta_poc = get_ue_golomb_long(gb) + 1; + if (delta_poc < 1 || delta_poc > 32768) { + av_log(avctx, AV_LOG_ERROR, + "Invalid value of delta_poc: %d\n", + delta_poc); + return AVERROR_INVALIDDATA; + } prev += delta_poc; rps->delta_poc[rps->num_negative_pics + i] = prev; rps->used[rps->num_negative_pics + i] = get_bits1(gb); From 837cb4325b712ff1aab531bf41668933f61d75d2 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 22 Aug 2017 11:02:38 +0200 Subject: [PATCH 2819/3374] ffprobe: Fix null pointer dereference with color primaries Found-by: AD-lab of venustech Signed-off-by: Michael Niedermayer --- ffprobe.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/ffprobe.c b/ffprobe.c index 50d7c1a777c95..d4bdd9c09938c 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -1925,6 +1925,16 @@ static void print_pkt_side_data(WriterContext *w, writer_print_section_footer(w); } +static void print_primaries(WriterContext *w, enum AVColorPrimaries color_primaries) +{ + const char *val = av_color_primaries_name(color_primaries); + if (!val || color_primaries == AVCOL_PRI_UNSPECIFIED) { + print_str_opt("color_primaries", "unknown"); + } else { + print_str("color_primaries", val); + } +} + static void clear_log(int need_lock) { int i; @@ -2116,10 +2126,7 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream, else print_str_opt("color_space", av_color_space_name(frame->colorspace)); - if (frame->color_primaries != AVCOL_PRI_UNSPECIFIED) - print_str("color_primaries", av_color_primaries_name(frame->color_primaries)); - else - print_str_opt("color_primaries", av_color_primaries_name(frame->color_primaries)); + print_primaries(w, frame->color_primaries); if (frame->color_trc != AVCOL_TRC_UNSPECIFIED) print_str("color_transfer", av_color_transfer_name(frame->color_trc)); @@ -2516,10 +2523,7 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id else print_str_opt("color_transfer", av_color_transfer_name(par->color_trc)); - if (par->color_primaries != AVCOL_PRI_UNSPECIFIED) - print_str("color_primaries", av_color_primaries_name(par->color_primaries)); - else - print_str_opt("color_primaries", av_color_primaries_name(par->color_primaries)); + print_primaries(w, par->color_primaries); if (par->chroma_location != AVCHROMA_LOC_UNSPECIFIED) print_str("chroma_location", av_chroma_location_name(par->chroma_location)); From 351e28f9a799d9bbbb33dd10c964dca7219fa13b Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 22 Aug 2017 17:27:17 +0200 Subject: [PATCH 2820/3374] ffprobe: Fix NULL pointer handling in color parameter printing Signed-off-by: Michael Niedermayer --- ffprobe.c | 88 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 39 deletions(-) diff --git a/ffprobe.c b/ffprobe.c index d4bdd9c09938c..ba10563b9d098 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -1925,6 +1925,26 @@ static void print_pkt_side_data(WriterContext *w, writer_print_section_footer(w); } +static void print_color_range(WriterContext *w, enum AVColorRange color_range, const char *fallback) +{ + const char *val = av_color_range_name(color_range); + if (!val || color_range == AVCOL_RANGE_UNSPECIFIED) { + print_str_opt("color_range", fallback); + } else { + print_str("color_range", val); + } +} + +static void print_color_space(WriterContext *w, enum AVColorSpace color_space) +{ + const char *val = av_color_space_name(color_space); + if (!val || color_space == AVCOL_SPC_UNSPECIFIED) { + print_str_opt("color_space", "unknown"); + } else { + print_str("color_space", val); + } +} + static void print_primaries(WriterContext *w, enum AVColorPrimaries color_primaries) { const char *val = av_color_primaries_name(color_primaries); @@ -1935,6 +1955,27 @@ static void print_primaries(WriterContext *w, enum AVColorPrimaries color_primar } } +static void print_color_trc(WriterContext *w, enum AVColorTransferCharacteristic color_trc) +{ + const char *val = av_color_transfer_name(color_trc); + if (!val || color_trc == AVCOL_TRC_UNSPECIFIED) { + print_str_opt("color_transfer", "unknown"); + } else { + print_str("color_transfer", val); + } +} + +static void print_chroma_location(WriterContext *w, enum AVChromaLocation chroma_location) +{ + const char *val = av_chroma_location_name(chroma_location); + if (!val || chroma_location == AVCHROMA_LOC_UNSPECIFIED) { + print_str_opt("chroma_location", "unspecified"); + } else { + print_str("chroma_location", val); + } +} + + static void clear_log(int need_lock) { int i; @@ -2116,27 +2157,11 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream, print_int("top_field_first", frame->top_field_first); print_int("repeat_pict", frame->repeat_pict); - if (frame->color_range != AVCOL_RANGE_UNSPECIFIED) - print_str("color_range", av_color_range_name(frame->color_range)); - else - print_str_opt("color_range", av_color_range_name(frame->color_range)); - - if (frame->colorspace != AVCOL_SPC_UNSPECIFIED) - print_str("color_space", av_color_space_name(frame->colorspace)); - else - print_str_opt("color_space", av_color_space_name(frame->colorspace)); - + print_color_range(w, frame->color_range, "unknown"); + print_color_space(w, frame->colorspace); print_primaries(w, frame->color_primaries); - - if (frame->color_trc != AVCOL_TRC_UNSPECIFIED) - print_str("color_transfer", av_color_transfer_name(frame->color_trc)); - else - print_str_opt("color_transfer", av_color_transfer_name(frame->color_trc)); - - if (frame->chroma_location != AVCHROMA_LOC_UNSPECIFIED) - print_str("chroma_location", av_chroma_location_name(frame->chroma_location)); - else - print_str_opt("chroma_location", av_chroma_location_name(frame->chroma_location)); + print_color_trc(w, frame->color_trc); + print_chroma_location(w, frame->chroma_location); break; case AVMEDIA_TYPE_AUDIO: @@ -2508,27 +2533,12 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id if (s) print_str ("pix_fmt", s); else print_str_opt("pix_fmt", "unknown"); print_int("level", par->level); - if (par->color_range != AVCOL_RANGE_UNSPECIFIED) - print_str ("color_range", av_color_range_name(par->color_range)); - else - print_str_opt("color_range", "N/A"); - - if (par->color_space != AVCOL_SPC_UNSPECIFIED) - print_str("color_space", av_color_space_name(par->color_space)); - else - print_str_opt("color_space", av_color_space_name(par->color_space)); - - if (par->color_trc != AVCOL_TRC_UNSPECIFIED) - print_str("color_transfer", av_color_transfer_name(par->color_trc)); - else - print_str_opt("color_transfer", av_color_transfer_name(par->color_trc)); + print_color_range(w, par->color_range, "N/A"); + print_color_space(w, par->color_space); + print_color_trc(w, par->color_trc); print_primaries(w, par->color_primaries); - - if (par->chroma_location != AVCHROMA_LOC_UNSPECIFIED) - print_str("chroma_location", av_chroma_location_name(par->chroma_location)); - else - print_str_opt("chroma_location", av_chroma_location_name(par->chroma_location)); + print_chroma_location(w, par->chroma_location); if (par->field_order == AV_FIELD_PROGRESSIVE) print_str("field_order", "progressive"); From cb1a3eecac2d3395bf1e26289643082b4305f86a Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Wed, 23 Aug 2017 14:19:14 +0200 Subject: [PATCH 2821/3374] lsws/rgb2rgb: Add unscaled 48bit to 64bit rgb conversion. Based on b4befca2 and 6b7849e6 by Paul B Mahol. Fixes ticket #6608. --- libswscale/rgb2rgb.c | 38 +++++++++++++++++++++++++++++++++++ libswscale/rgb2rgb.h | 4 ++++ libswscale/swscale_unscaled.c | 17 ++++++++++++++++ libswscale/version.h | 2 +- 4 files changed, 60 insertions(+), 1 deletion(-) diff --git a/libswscale/rgb2rgb.c b/libswscale/rgb2rgb.c index f7f8188af1a3b..04b7908b5e7a9 100644 --- a/libswscale/rgb2rgb.c +++ b/libswscale/rgb2rgb.c @@ -391,3 +391,41 @@ void rgb64to48_ ## need_bswap(const uint8_t *src, \ DEFINE_RGB64TO48(nobswap, 0) DEFINE_RGB64TO48(bswap, 1) + +#define DEFINE_RGB48TOBGR64(need_bswap, swap) \ +void rgb48tobgr64_ ## need_bswap(const uint8_t *src, \ + uint8_t *dst, int src_size) \ +{ \ + uint16_t *d = (uint16_t *)dst; \ + uint16_t *s = (uint16_t *)src; \ + int i, num_pixels = src_size / 6; \ + \ + for (i = 0; i < num_pixels; i++) { \ + d[4 * i ] = swap ? av_bswap16(s[3 * i + 2]) : s[3 * i + 2]; \ + d[4 * i + 1] = swap ? av_bswap16(s[3 * i + 1]) : s[3 * i + 1]; \ + d[4 * i + 2] = swap ? av_bswap16(s[3 * i ]) : s[3 * i ]; \ + d[4 * i + 3] = 0xFFFF; \ + } \ +} + +DEFINE_RGB48TOBGR64(nobswap, 0) +DEFINE_RGB48TOBGR64(bswap, 1) + +#define DEFINE_RGB48TO64(need_bswap, swap) \ +void rgb48to64_ ## need_bswap(const uint8_t *src, \ + uint8_t *dst, int src_size) \ +{ \ + uint16_t *d = (uint16_t *)dst; \ + uint16_t *s = (uint16_t *)src; \ + int i, num_pixels = src_size / 6; \ + \ + for (i = 0; i < num_pixels; i++) { \ + d[4 * i ] = swap ? av_bswap16(s[3 * i ]) : s[3 * i ]; \ + d[4 * i + 1] = swap ? av_bswap16(s[3 * i + 1]) : s[3 * i + 1]; \ + d[4 * i + 2] = swap ? av_bswap16(s[3 * i + 2]) : s[3 * i + 2]; \ + d[4 * i + 3] = 0xFFFF; \ + } \ +} + +DEFINE_RGB48TO64(nobswap, 0) +DEFINE_RGB48TO64(bswap, 1) diff --git a/libswscale/rgb2rgb.h b/libswscale/rgb2rgb.h index 0645404eee7e0..6994839299da3 100644 --- a/libswscale/rgb2rgb.h +++ b/libswscale/rgb2rgb.h @@ -59,6 +59,10 @@ void rgb48tobgr48_nobswap(const uint8_t *src, uint8_t *dst, int src_size); void rgb48tobgr48_bswap(const uint8_t *src, uint8_t *dst, int src_size); void rgb64to48_nobswap(const uint8_t *src, uint8_t *dst, int src_size); void rgb64to48_bswap(const uint8_t *src, uint8_t *dst, int src_size); +void rgb48tobgr64_nobswap(const uint8_t *src, uint8_t *dst, int src_size); +void rgb48tobgr64_bswap(const uint8_t *src, uint8_t *dst, int src_size); +void rgb48to64_nobswap(const uint8_t *src, uint8_t *dst, int src_size); +void rgb48to64_bswap(const uint8_t *src, uint8_t *dst, int src_size); void rgb24to32(const uint8_t *src, uint8_t *dst, int src_size); void rgb32to24(const uint8_t *src, uint8_t *dst, int src_size); void rgb16tobgr32(const uint8_t *src, uint8_t *dst, int src_size); diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index 3b1b3667ce507..ef36aec500bec 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -1292,6 +1292,23 @@ static rgbConvFn findRgbConvFn(SwsContext *c) || CONV_IS(BGR48LE, RGB48BE) || CONV_IS(RGB48BE, BGR48LE) || CONV_IS(BGR48BE, RGB48LE)) conv = rgb48tobgr48_bswap; + } else if (isRGB48(srcFormat) && isRGBA64(dstFormat)) { + if (CONV_IS(RGB48LE, BGRA64LE) + || CONV_IS(BGR48LE, RGBA64LE) + || CONV_IS(RGB48BE, BGRA64BE) + || CONV_IS(BGR48BE, RGBA64BE)) conv = rgb48tobgr64_nobswap; + else if (CONV_IS(RGB48LE, BGRA64BE) + || CONV_IS(BGR48LE, RGBA64BE) + || CONV_IS(RGB48BE, BGRA64LE) + || CONV_IS(BGR48BE, RGBA64LE)) conv = rgb48tobgr64_bswap; + if (CONV_IS(RGB48LE, RGBA64LE) + || CONV_IS(BGR48LE, BGRA64LE) + || CONV_IS(RGB48BE, RGBA64BE) + || CONV_IS(BGR48BE, BGRA64BE)) conv = rgb48to64_nobswap; + else if (CONV_IS(RGB48LE, RGBA64BE) + || CONV_IS(BGR48LE, BGRA64BE) + || CONV_IS(RGB48BE, RGBA64LE) + || CONV_IS(BGR48BE, BGRA64LE)) conv = rgb48to64_bswap; } else if (isRGBA64(srcFormat) && isRGB48(dstFormat)) { if (CONV_IS(RGBA64LE, BGR48LE) || CONV_IS(BGRA64LE, RGB48LE) diff --git a/libswscale/version.h b/libswscale/version.h index 8dff77e48abed..dcf7959b23630 100644 --- a/libswscale/version.h +++ b/libswscale/version.h @@ -28,7 +28,7 @@ #define LIBSWSCALE_VERSION_MAJOR 4 #define LIBSWSCALE_VERSION_MINOR 7 -#define LIBSWSCALE_VERSION_MICRO 102 +#define LIBSWSCALE_VERSION_MICRO 103 #define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \ LIBSWSCALE_VERSION_MINOR, \ From f61e2dcfc399113e1b0408e58a085fca329d0da4 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Mon, 21 Aug 2017 16:17:17 +0200 Subject: [PATCH 2822/3374] lavf/g726: Demuxer for raw G.726 streams, both left- and right-justified. Compatible with the binary encoder attached to ticket #6596 (right-aligned) and a sample from a SEG Mp3-Player (left-aligned). --- Changelog | 1 + doc/general.texi | 1 + libavformat/Makefile | 2 + libavformat/allformats.c | 2 + libavformat/g726.c | 105 +++++++++++++++++++++++++++++++++++++++ libavformat/version.h | 2 +- 6 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 libavformat/g726.c diff --git a/Changelog b/Changelog index 7a6987a169806..f5dc1da9e0e8b 100644 --- a/Changelog +++ b/Changelog @@ -33,6 +33,7 @@ version : - tlut2 video filter - floodfill video filter - pseudocolor video filter +- raw G.726 demuxer, left- and right-justified version 3.3: - CrystalHD decoder moved to new decode API diff --git a/doc/general.texi b/doc/general.texi index 036c8c25d44fd..7d8da113e6d0c 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -341,6 +341,7 @@ library: @item FunCom ISS @tab @tab X @tab Audio format used in various games from FunCom like The Longest Journey. @item G.723.1 @tab X @tab X +@item G.726 @tab @tab X @tab Both left- and right-justified. @item G.729 BIT @tab X @tab X @item G.729 raw @tab @tab X @item GENH @tab @tab X diff --git a/libavformat/Makefile b/libavformat/Makefile index b0ef82cdd4601..8e2afb76fd6cd 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -188,6 +188,8 @@ OBJS-$(CONFIG_GSM_MUXER) += rawenc.o OBJS-$(CONFIG_GXF_DEMUXER) += gxf.o OBJS-$(CONFIG_GXF_MUXER) += gxfenc.o audiointerleave.o OBJS-$(CONFIG_G722_DEMUXER) += g722.o rawdec.o +OBJS-$(CONFIG_G726_DEMUXER) += g726.o +OBJS-$(CONFIG_G726LE_DEMUXER) += g726.o OBJS-$(CONFIG_G722_MUXER) += rawenc.o OBJS-$(CONFIG_G723_1_DEMUXER) += g723_1.o OBJS-$(CONFIG_G723_1_MUXER) += rawenc.o diff --git a/libavformat/allformats.c b/libavformat/allformats.c index 1ebc14231c275..78ff2ebf293e3 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -132,6 +132,8 @@ static void register_all(void) REGISTER_DEMUXER (FRM, frm); REGISTER_DEMUXER (FSB, fsb); REGISTER_MUXDEMUX(G722, g722); + REGISTER_DEMUXER (G726, g726); + REGISTER_DEMUXER (G726LE, g726le); REGISTER_MUXDEMUX(G723_1, g723_1); REGISTER_DEMUXER (G729, g729); REGISTER_DEMUXER (GDV, gdv); diff --git a/libavformat/g726.c b/libavformat/g726.c new file mode 100644 index 0000000000000..eca940486657f --- /dev/null +++ b/libavformat/g726.c @@ -0,0 +1,105 @@ +/* + * G.726 raw demuxer + * Copyright 2017 Carl Eugen Hoyos + * + * 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 "internal.h" +#include "libavutil/opt.h" + +typedef struct G726Context { + AVClass *class; + int code_size; + int sample_rate; +} G726Context; + +static int g726_read_header(AVFormatContext *s) +{ + G726Context *c = s->priv_data; + AVStream *st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + + st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; + st->codecpar->codec_id = s->iformat->raw_codec_id; + + st->codecpar->sample_rate = c->sample_rate; + st->codecpar->bits_per_coded_sample = c->code_size; + st->codecpar->bit_rate = ((int[]){ 16000, 24000, 32000, 40000 })[c->code_size - 2]; + st->codecpar->channels = 1; + + return 0; +} + +static int g726_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + int res; + res = av_get_packet(s->pb, pkt, 1020); // a size similar to RAW_PACKET_SIZE divisible by all code_size values + if (res < 0) + return res; + return 0; +} + +#define OFFSET(x) offsetof(G726Context, x) +static const AVOption options[] = { + { "code_size", "Bits per G.726 code", + OFFSET(code_size), AV_OPT_TYPE_INT, {.i64 = 4}, 2, 5, AV_OPT_FLAG_DECODING_PARAM }, + { "sample_rate", "", + OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 8000}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, + { NULL }, +}; + +#if CONFIG_G726_DEMUXER +static const AVClass g726le_demuxer_class = { + .class_name = "G.726 big-endian demuxer", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVInputFormat ff_g726_demuxer = { + .name = "g726", + .long_name = NULL_IF_CONFIG_SMALL("raw big-endian G.726 (\"left aligned\")"), + .read_header = g726_read_header, + .read_packet = g726_read_packet, + .priv_data_size = sizeof(G726Context), + .priv_class = &g726le_demuxer_class, + .raw_codec_id = AV_CODEC_ID_ADPCM_G726, +}; +#endif + +#if CONFIG_G726LE_DEMUXER +static const AVClass g726_demuxer_class = { + .class_name = "G.726 little-endian demuxer", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVInputFormat ff_g726le_demuxer = { + .name = "g726le", + .long_name = NULL_IF_CONFIG_SMALL("raw little-endian G.726 (\"right aligned\")"), + .read_header = g726_read_header, + .read_packet = g726_read_packet, + .priv_data_size = sizeof(G726Context), + .priv_class = &g726_demuxer_class, + .raw_codec_id = AV_CODEC_ID_ADPCM_G726LE, +}; +#endif + diff --git a/libavformat/version.h b/libavformat/version.h index 48b81f2e48e00..a8cf4c158ebd4 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ // 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 57 -#define LIBAVFORMAT_VERSION_MINOR 76 +#define LIBAVFORMAT_VERSION_MINOR 77 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ From f8d0689d3ff56bdeda708a14fad322cef8a219af Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Thu, 24 Aug 2017 14:43:00 +0200 Subject: [PATCH 2823/3374] avfilter/vf_blend: rename addition128 and difference128 to grainmerge and grainextract --- doc/filters.texi | 6 +++--- libavfilter/blend.h | 4 ++-- libavfilter/vf_blend.c | 18 ++++++++++-------- libavfilter/x86/vf_blend.asm | 4 ++-- libavfilter/x86/vf_blend_init.c | 14 +++++++------- 5 files changed, 24 insertions(+), 22 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 3b5a38fc9f554..8416ee44e52d2 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -4854,13 +4854,13 @@ of @var{all_mode}. Default value is @code{normal}. Available values for component modes are: @table @samp @item addition -@item addition128 +@item grainmerge @item and @item average @item burn @item darken @item difference -@item difference128 +@item grainextract @item divide @item dodge @item freeze @@ -4987,7 +4987,7 @@ blend=all_expr=if(gt(X,Y*(W/H)),A,B) @item Display differences between the current and the previous frame: @example -tblend=all_mode=difference128 +tblend=all_mode=grainextract @end example @end itemize diff --git a/libavfilter/blend.h b/libavfilter/blend.h index 0f27b4d29d2a0..eb2022683985b 100644 --- a/libavfilter/blend.h +++ b/libavfilter/blend.h @@ -33,7 +33,7 @@ enum BlendMode { BLEND_BURN, BLEND_DARKEN, BLEND_DIFFERENCE, - BLEND_DIFFERENCE128, + BLEND_GRAINEXTRACT, BLEND_DIVIDE, BLEND_DODGE, BLEND_EXCLUSION, @@ -54,7 +54,7 @@ enum BlendMode { BLEND_HARDMIX, BLEND_LINEARLIGHT, BLEND_GLOW, - BLEND_ADDITION128, + BLEND_GRAINMERGE, BLEND_MULTIPLY128, BLEND_HEAT, BLEND_FREEZE, diff --git a/libavfilter/vf_blend.c b/libavfilter/vf_blend.c index 9bde3b22a1ef0..109a51fa92130 100644 --- a/libavfilter/vf_blend.c +++ b/libavfilter/vf_blend.c @@ -66,13 +66,15 @@ typedef struct ThreadData { { "c3_mode", "set component #3 blend mode", OFFSET(params[3].mode), AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode"},\ { "all_mode", "set blend mode for all components", OFFSET(all_mode), AV_OPT_TYPE_INT, {.i64=-1},-1, BLEND_NB-1, FLAGS, "mode"},\ { "addition", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_ADDITION}, 0, 0, FLAGS, "mode" },\ - { "addition128", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_ADDITION128}, 0, 0, FLAGS, "mode" },\ + { "addition128","", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_GRAINMERGE}, 0, 0, FLAGS, "mode" },\ + { "grainmerge", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_GRAINMERGE}, 0, 0, FLAGS, "mode" },\ { "and", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_AND}, 0, 0, FLAGS, "mode" },\ { "average", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_AVERAGE}, 0, 0, FLAGS, "mode" },\ { "burn", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_BURN}, 0, 0, FLAGS, "mode" },\ { "darken", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DARKEN}, 0, 0, FLAGS, "mode" },\ { "difference", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DIFFERENCE}, 0, 0, FLAGS, "mode" },\ - { "difference128", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DIFFERENCE128}, 0, 0, FLAGS, "mode" },\ + { "difference128", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_GRAINEXTRACT}, 0, 0, FLAGS, "mode" },\ + { "grainextract", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_GRAINEXTRACT}, 0, 0, FLAGS, "mode" },\ { "divide", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DIVIDE}, 0, 0, FLAGS, "mode" },\ { "dodge", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DODGE}, 0, 0, FLAGS, "mode" },\ { "exclusion", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_EXCLUSION}, 0, 0, FLAGS, "mode" },\ @@ -236,7 +238,7 @@ static void blend_## name##_16bit(const uint8_t *_top, ptrdiff_t top_linesize, #define DODGE(a, b) (((a) == 255) ? (a) : FFMIN(255, (((b) << 8) / (255 - (a))))) DEFINE_BLEND8(addition, FFMIN(255, A + B)) -DEFINE_BLEND8(addition128, av_clip_uint8(A + B - 128)) +DEFINE_BLEND8(grainmerge, av_clip_uint8(A + B - 128)) DEFINE_BLEND8(average, (A + B) / 2) DEFINE_BLEND8(subtract, FFMAX(0, A - B)) DEFINE_BLEND8(multiply, MULTIPLY(1, A, B)) @@ -244,7 +246,7 @@ DEFINE_BLEND8(multiply128,av_clip_uint8((A - 128) * B / 32. + 128)) DEFINE_BLEND8(negation, 255 - FFABS(255 - A - B)) DEFINE_BLEND8(extremity, FFABS(255 - A - B)) DEFINE_BLEND8(difference, FFABS(A - B)) -DEFINE_BLEND8(difference128, av_clip_uint8(128 + A - B)) +DEFINE_BLEND8(grainextract, av_clip_uint8(128 + A - B)) DEFINE_BLEND8(screen, SCREEN(1, A, B)) DEFINE_BLEND8(overlay, (A < 128) ? MULTIPLY(2, A, B) : SCREEN(2, A, B)) DEFINE_BLEND8(hardlight, (B < 128) ? MULTIPLY(2, B, A) : SCREEN(2, B, A)) @@ -279,7 +281,7 @@ DEFINE_BLEND8(linearlight,av_clip_uint8((B < 128) ? B + 2 * A - 255 : B + 2 * (A #define DODGE(a, b) (((a) == 65535) ? (a) : FFMIN(65535, (((b) << 16) / (65535 - (a))))) DEFINE_BLEND16(addition, FFMIN(65535, A + B)) -DEFINE_BLEND16(addition128, av_clip_uint16(A + B - 32768)) +DEFINE_BLEND16(grainmerge, av_clip_uint16(A + B - 32768)) DEFINE_BLEND16(average, (A + B) / 2) DEFINE_BLEND16(subtract, FFMAX(0, A - B)) DEFINE_BLEND16(multiply, MULTIPLY(1, A, B)) @@ -287,7 +289,7 @@ DEFINE_BLEND16(multiply128, av_clip_uint16((A - 32768) * B / 8192. + 32768)) DEFINE_BLEND16(negation, 65535 - FFABS(65535 - A - B)) DEFINE_BLEND16(extremity, FFABS(65535 - A - B)) DEFINE_BLEND16(difference, FFABS(A - B)) -DEFINE_BLEND16(difference128, av_clip_uint16(32768 + A - B)) +DEFINE_BLEND16(grainextract, av_clip_uint16(32768 + A - B)) DEFINE_BLEND16(screen, SCREEN(1, A, B)) DEFINE_BLEND16(overlay, (A < 32768) ? MULTIPLY(2, A, B) : SCREEN(2, A, B)) DEFINE_BLEND16(hardlight, (B < 32768) ? MULTIPLY(2, B, A) : SCREEN(2, B, A)) @@ -450,13 +452,13 @@ void ff_blend_init(FilterParams *param, int is_16bit) { switch (param->mode) { case BLEND_ADDITION: param->blend = is_16bit ? blend_addition_16bit : blend_addition_8bit; break; - case BLEND_ADDITION128: param->blend = is_16bit ? blend_addition128_16bit : blend_addition128_8bit; break; + case BLEND_GRAINMERGE: param->blend = is_16bit ? blend_grainmerge_16bit : blend_grainmerge_8bit; break; case BLEND_AND: param->blend = is_16bit ? blend_and_16bit : blend_and_8bit; break; case BLEND_AVERAGE: param->blend = is_16bit ? blend_average_16bit : blend_average_8bit; break; case BLEND_BURN: param->blend = is_16bit ? blend_burn_16bit : blend_burn_8bit; break; case BLEND_DARKEN: param->blend = is_16bit ? blend_darken_16bit : blend_darken_8bit; break; case BLEND_DIFFERENCE: param->blend = is_16bit ? blend_difference_16bit : blend_difference_8bit; break; - case BLEND_DIFFERENCE128: param->blend = is_16bit ? blend_difference128_16bit: blend_difference128_8bit; break; + case BLEND_GRAINEXTRACT: param->blend = is_16bit ? blend_grainextract_16bit: blend_grainextract_8bit; break; case BLEND_DIVIDE: param->blend = is_16bit ? blend_divide_16bit : blend_divide_8bit; break; case BLEND_DODGE: param->blend = is_16bit ? blend_dodge_16bit : blend_dodge_8bit; break; case BLEND_EXCLUSION: param->blend = is_16bit ? blend_exclusion_16bit : blend_exclusion_8bit; break; diff --git a/libavfilter/x86/vf_blend.asm b/libavfilter/x86/vf_blend.asm index cef479d995601..4916aaf251e01 100644 --- a/libavfilter/x86/vf_blend.asm +++ b/libavfilter/x86/vf_blend.asm @@ -83,7 +83,7 @@ BLEND_SIMPLE subtract, subusb BLEND_SIMPLE darken, minub BLEND_SIMPLE lighten, maxub -BLEND_INIT difference128, 4 +BLEND_INIT grainextract, 4 pxor m2, m2 mova m3, [pw_128] .nextrow: @@ -181,7 +181,7 @@ BLEND_INIT average, 3 jl .loop BLEND_END -BLEND_INIT addition128, 4 +BLEND_INIT grainmerge, 4 pxor m2, m2 mova m3, [pw_128] .nextrow: diff --git a/libavfilter/x86/vf_blend_init.c b/libavfilter/x86/vf_blend_init.c index 71f9b0a68525e..a4fc9af2469de 100644 --- a/libavfilter/x86/vf_blend_init.c +++ b/libavfilter/x86/vf_blend_init.c @@ -31,11 +31,11 @@ void ff_blend_##name##_##opt(const uint8_t *top, ptrdiff_t top_linesize, \ struct FilterParams *param, double *values, int starty); BLEND_FUNC(addition, sse2) -BLEND_FUNC(addition128, sse2) +BLEND_FUNC(grainmerge, sse2) BLEND_FUNC(average, sse2) BLEND_FUNC(and, sse2) BLEND_FUNC(darken, sse2) -BLEND_FUNC(difference128, sse2) +BLEND_FUNC(grainextract, sse2) BLEND_FUNC(multiply, sse2) BLEND_FUNC(screen, sse2) BLEND_FUNC(hardmix, sse2) @@ -59,29 +59,29 @@ av_cold void ff_blend_init_x86(FilterParams *param, int is_16bit) if (EXTERNAL_SSE2(cpu_flags) && param->opacity == 1 && !is_16bit) { switch (param->mode) { case BLEND_ADDITION: param->blend = ff_blend_addition_sse2; break; - case BLEND_ADDITION128: param->blend = ff_blend_addition128_sse2; break; + case BLEND_GRAINMERGE: param->blend = ff_blend_grainmerge_sse2; break; case BLEND_AND: param->blend = ff_blend_and_sse2; break; case BLEND_AVERAGE: param->blend = ff_blend_average_sse2; break; case BLEND_DARKEN: param->blend = ff_blend_darken_sse2; break; - case BLEND_DIFFERENCE128: param->blend = ff_blend_difference128_sse2; break; + case BLEND_GRAINEXTRACT: param->blend = ff_blend_grainextract_sse2; break; case BLEND_DIVIDE: param->blend = ff_blend_divide_sse2; break; case BLEND_HARDMIX: param->blend = ff_blend_hardmix_sse2; break; case BLEND_LIGHTEN: param->blend = ff_blend_lighten_sse2; break; case BLEND_MULTIPLY: param->blend = ff_blend_multiply_sse2; break; case BLEND_OR: param->blend = ff_blend_or_sse2; break; case BLEND_PHOENIX: param->blend = ff_blend_phoenix_sse2; break; - case BLEND_SCREEN: param->blend = ff_blend_screen_sse2; break; + case BLEND_SCREEN: param->blend = ff_blend_screen_sse2; break; case BLEND_SUBTRACT: param->blend = ff_blend_subtract_sse2; break; case BLEND_XOR: param->blend = ff_blend_xor_sse2; break; case BLEND_DIFFERENCE: param->blend = ff_blend_difference_sse2; break; - case BLEND_EXTREMITY: param->blend = ff_blend_extremity_sse2; break; + case BLEND_EXTREMITY: param->blend = ff_blend_extremity_sse2; break; case BLEND_NEGATION: param->blend = ff_blend_negation_sse2; break; } } if (EXTERNAL_SSSE3(cpu_flags) && param->opacity == 1 && !is_16bit) { switch (param->mode) { case BLEND_DIFFERENCE: param->blend = ff_blend_difference_ssse3; break; - case BLEND_EXTREMITY: param->blend = ff_blend_extremity_ssse3; break; + case BLEND_EXTREMITY: param->blend = ff_blend_extremity_ssse3; break; case BLEND_NEGATION: param->blend = ff_blend_negation_ssse3; break; } } From f0f48884b02354173747c31d5016eaefe3db6a00 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Thu, 24 Aug 2017 20:34:35 +0200 Subject: [PATCH 2824/3374] avfilter/af_sidechaincompress: switch to activate --- libavfilter/af_sidechaincompress.c | 112 +++++++++++++++-------------- 1 file changed, 58 insertions(+), 54 deletions(-) diff --git a/libavfilter/af_sidechaincompress.c b/libavfilter/af_sidechaincompress.c index d1dfc106e2217..f174b70a5b06f 100644 --- a/libavfilter/af_sidechaincompress.c +++ b/libavfilter/af_sidechaincompress.c @@ -32,6 +32,7 @@ #include "audio.h" #include "avfilter.h" +#include "filters.h" #include "formats.h" #include "hermite.h" #include "internal.h" @@ -183,71 +184,76 @@ static void compressor(SidechainCompressContext *s, } #if CONFIG_SIDECHAINCOMPRESS_FILTER -static int filter_frame(AVFilterLink *link, AVFrame *frame) +static int activate(AVFilterContext *ctx) { - AVFilterContext *ctx = link->dst; SidechainCompressContext *s = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; AVFrame *out = NULL, *in[2] = { NULL }; + int ret, i, status, nb_samples; double *dst; - int nb_samples; - int i; + int64_t pts; - for (i = 0; i < 2; i++) - if (link == ctx->inputs[i]) - break; - av_assert0(i < 2); - av_audio_fifo_write(s->fifo[i], (void **)frame->extended_data, - frame->nb_samples); - av_frame_free(&frame); + if ((ret = ff_inlink_consume_frame(ctx->inputs[0], &in[0])) > 0) { + av_audio_fifo_write(s->fifo[0], (void **)in[0]->extended_data, + in[0]->nb_samples); + av_frame_free(&in[0]); + } + if (ret < 0) + return ret; + if ((ret = ff_inlink_consume_frame(ctx->inputs[1], &in[1])) > 0) { + av_audio_fifo_write(s->fifo[1], (void **)in[1]->extended_data, + in[1]->nb_samples); + av_frame_free(&in[1]); + } + if (ret < 0) + return ret; nb_samples = FFMIN(av_audio_fifo_size(s->fifo[0]), av_audio_fifo_size(s->fifo[1])); - if (!nb_samples) - return 0; - - out = ff_get_audio_buffer(outlink, nb_samples); - if (!out) - return AVERROR(ENOMEM); - for (i = 0; i < 2; i++) { - in[i] = ff_get_audio_buffer(ctx->inputs[i], nb_samples); - if (!in[i]) { - av_frame_free(&in[0]); - av_frame_free(&in[1]); - av_frame_free(&out); + if (nb_samples) { + out = ff_get_audio_buffer(ctx->outputs[0], nb_samples); + if (!out) return AVERROR(ENOMEM); + for (i = 0; i < 2; i++) { + in[i] = ff_get_audio_buffer(ctx->inputs[i], nb_samples); + if (!in[i]) { + av_frame_free(&in[0]); + av_frame_free(&in[1]); + av_frame_free(&out); + return AVERROR(ENOMEM); + } + av_audio_fifo_read(s->fifo[i], (void **)in[i]->data, nb_samples); } - av_audio_fifo_read(s->fifo[i], (void **)in[i]->data, nb_samples); - } - dst = (double *)out->data[0]; - out->pts = s->pts; - s->pts += nb_samples; + dst = (double *)out->data[0]; + out->pts = s->pts; + s->pts += nb_samples; - compressor(s, (double *)in[0]->data[0], dst, - (double *)in[1]->data[0], nb_samples, - s->level_in, s->level_sc, - ctx->inputs[0], ctx->inputs[1]); + compressor(s, (double *)in[0]->data[0], dst, + (double *)in[1]->data[0], nb_samples, + s->level_in, s->level_sc, + ctx->inputs[0], ctx->inputs[1]); - av_frame_free(&in[0]); - av_frame_free(&in[1]); + av_frame_free(&in[0]); + av_frame_free(&in[1]); - return ff_filter_frame(outlink, out); -} - -static int request_frame(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - SidechainCompressContext *s = ctx->priv; - int i; - - /* get a frame on each input */ - for (i = 0; i < 2; i++) { - AVFilterLink *inlink = ctx->inputs[i]; - if (!av_audio_fifo_size(s->fifo[i])) - return ff_request_frame(inlink); + ret = ff_filter_frame(ctx->outputs[0], out); + if (ret < 0) + return ret; + } + if (ff_inlink_acknowledge_status(ctx->inputs[0], &status, &pts)) { + ff_outlink_set_status(ctx->outputs[0], status, pts); + return 0; + } else if (ff_inlink_acknowledge_status(ctx->inputs[1], &status, &pts)) { + ff_outlink_set_status(ctx->outputs[0], status, pts); + return 0; + } else { + if (ff_outlink_frame_wanted(ctx->outputs[0])) { + if (!av_audio_fifo_size(s->fifo[0])) + ff_inlink_request_frame(ctx->inputs[0]); + if (!av_audio_fifo_size(s->fifo[1])) + ff_inlink_request_frame(ctx->inputs[1]); + } + return 0; } - - return 0; } static int query_formats(AVFilterContext *ctx) @@ -325,11 +331,9 @@ static const AVFilterPad sidechaincompress_inputs[] = { { .name = "main", .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, },{ .name = "sidechain", .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, }, { NULL } }; @@ -339,7 +343,6 @@ static const AVFilterPad sidechaincompress_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_AUDIO, .config_props = config_output, - .request_frame = request_frame, }, { NULL } }; @@ -350,6 +353,7 @@ AVFilter ff_af_sidechaincompress = { .priv_size = sizeof(SidechainCompressContext), .priv_class = &sidechaincompress_class, .query_formats = query_formats, + .activate = activate, .uninit = uninit, .inputs = sidechaincompress_inputs, .outputs = sidechaincompress_outputs, From dbc9a8f21f92d0613142ea23bb836356fc41de38 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Tue, 4 Jul 2017 16:59:13 +0200 Subject: [PATCH 2825/3374] avcodec/aac: Add floating point 960/120 MDCT window Co-Authored-By: Alex Converse Co-Authored-By: Rostislav Pehlivanov --- libavcodec/aac.h | 3 + libavcodec/aacdec_template.c | 124 ++++++++++++++++++++++++++++++++-- libavcodec/aactab.c | 120 ++++++++++++++++++++++++++++++++ libavcodec/aactab.h | 6 ++ libavcodec/sinewin.h | 4 +- libavcodec/sinewin_tablegen.h | 5 +- 6 files changed, 253 insertions(+), 9 deletions(-) diff --git a/libavcodec/aac.h b/libavcodec/aac.h index 97a2df6b869d7..4910c661d6197 100644 --- a/libavcodec/aac.h +++ b/libavcodec/aac.h @@ -327,7 +327,9 @@ struct AACContext { #if USE_FIXED AVFixedDSPContext *fdsp; #else + MDCT15Context *mdct120; MDCT15Context *mdct480; + MDCT15Context *mdct960; AVFloatDSPContext *fdsp; #endif /* USE_FIXED */ int random_state; @@ -353,6 +355,7 @@ struct AACContext { OutputConfiguration oc[2]; int warned_num_aac_frames; + int warned_960_sbr; /* aacdec functions pointers */ void (*imdct_and_windowing)(AACContext *ac, SingleChannelElement *sce); diff --git a/libavcodec/aacdec_template.c b/libavcodec/aacdec_template.c index c59fd6aef61b9..3558f1f5504e8 100644 --- a/libavcodec/aacdec_template.c +++ b/libavcodec/aacdec_template.c @@ -811,11 +811,21 @@ static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx, uint8_t layout_map[MAX_ELEM_ID*4][3]; int tags = 0; +#if USE_FIXED if (get_bits1(gb)) { // frameLengthFlag - avpriv_request_sample(avctx, "960/120 MDCT window"); + avpriv_report_missing_feature(avctx, "Fixed point 960/120 MDCT window"); return AVERROR_PATCHWELCOME; } m4ac->frame_length_short = 0; +#else + m4ac->frame_length_short = get_bits1(gb); + if (m4ac->frame_length_short && m4ac->sbr == 1) { + avpriv_report_missing_feature(avctx, "SBR with 960 frame length"); + if (ac) ac->warned_960_sbr = 1; + m4ac->sbr = 0; + m4ac->ps = 0; + } +#endif if (get_bits1(gb)) // dependsOnCoreCoder skip_bits(gb, 14); // coreCoderDelay @@ -1126,6 +1136,12 @@ static av_cold void aac_static_table_init(void) // window initialization AAC_RENAME(ff_kbd_window_init)(AAC_RENAME(ff_aac_kbd_long_1024), 4.0, 1024); AAC_RENAME(ff_kbd_window_init)(AAC_RENAME(ff_aac_kbd_short_128), 6.0, 128); +#if !USE_FIXED + AAC_RENAME(ff_kbd_window_init)(AAC_RENAME(ff_aac_kbd_long_960), 4.0, 960); + AAC_RENAME(ff_kbd_window_init)(AAC_RENAME(ff_aac_kbd_short_120), 6.0, 120); + AAC_RENAME(ff_sine_window_init)(AAC_RENAME(ff_sine_960), 960); + AAC_RENAME(ff_sine_window_init)(AAC_RENAME(ff_sine_120), 120); +#endif AAC_RENAME(ff_init_ff_sine_windows)(10); AAC_RENAME(ff_init_ff_sine_windows)( 9); AAC_RENAME(ff_init_ff_sine_windows)( 7); @@ -1211,9 +1227,15 @@ static av_cold int aac_decode_init(AVCodecContext *avctx) AAC_RENAME_32(ff_mdct_init)(&ac->mdct_small, 8, 1, 1.0 / RANGE15(128.0)); AAC_RENAME_32(ff_mdct_init)(&ac->mdct_ltp, 11, 0, RANGE15(-2.0)); #if !USE_FIXED + ret = ff_mdct15_init(&ac->mdct120, 1, 3, 1.0f/(16*1024*120*2)); + if (ret < 0) + return ret; ret = ff_mdct15_init(&ac->mdct480, 1, 5, 1.0f/(16*1024*960)); if (ret < 0) return ret; + ret = ff_mdct15_init(&ac->mdct960, 1, 6, 1.0f/(16*1024*960*2)); + if (ret < 0) + return ret; #endif return 0; @@ -1316,8 +1338,13 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics, } } ics->num_windows = 8; - ics->swb_offset = ff_swb_offset_128[sampling_index]; - ics->num_swb = ff_aac_num_swb_128[sampling_index]; + if (m4ac->frame_length_short) { + ics->swb_offset = ff_swb_offset_120[sampling_index]; + ics->num_swb = ff_aac_num_swb_120[sampling_index]; + } else { + ics->swb_offset = ff_swb_offset_128[sampling_index]; + ics->num_swb = ff_aac_num_swb_128[sampling_index]; + } ics->tns_max_bands = ff_tns_max_bands_128[sampling_index]; ics->predictor_present = 0; } else { @@ -1338,8 +1365,13 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics, goto fail; } } else { - ics->swb_offset = ff_swb_offset_1024[sampling_index]; - ics->num_swb = ff_aac_num_swb_1024[sampling_index]; + if (m4ac->frame_length_short) { + ics->num_swb = ff_aac_num_swb_960[sampling_index]; + ics->swb_offset = ff_swb_offset_960[sampling_index]; + } else { + ics->num_swb = ff_aac_num_swb_1024[sampling_index]; + ics->swb_offset = ff_swb_offset_1024[sampling_index]; + } ics->tns_max_bands = ff_tns_max_bands_1024[sampling_index]; } if (aot != AOT_ER_AAC_ELD) { @@ -2361,6 +2393,13 @@ static int decode_extension_payload(AACContext *ac, GetBitContext *gb, int cnt, if (!che) { av_log(ac->avctx, AV_LOG_ERROR, "SBR was found before the first channel element.\n"); return res; + } else if (ac->oc[1].m4ac.frame_length_short) { + if (!ac->warned_960_sbr) + avpriv_report_missing_feature(ac->avctx, + "SBR with 960 frame length"); + ac->warned_960_sbr = 1; + skip_bits_long(gb, 8 * cnt - 4); + return res; } else if (!ac->oc[1].m4ac.sbr) { av_log(ac->avctx, AV_LOG_ERROR, "SBR signaled to be not-present but was found in the bitstream.\n"); skip_bits_long(gb, 8 * cnt - 4); @@ -2620,6 +2659,72 @@ static void imdct_and_windowing(AACContext *ac, SingleChannelElement *sce) } } +/** + * Conduct IMDCT and windowing. + */ +static void imdct_and_windowing_960(AACContext *ac, SingleChannelElement *sce) +{ +#if !USE_FIXED + IndividualChannelStream *ics = &sce->ics; + INTFLOAT *in = sce->coeffs; + INTFLOAT *out = sce->ret; + INTFLOAT *saved = sce->saved; + const INTFLOAT *swindow = ics->use_kb_window[0] ? AAC_RENAME(ff_aac_kbd_short_120) : AAC_RENAME(ff_sine_120); + const INTFLOAT *lwindow_prev = ics->use_kb_window[1] ? AAC_RENAME(ff_aac_kbd_long_960) : AAC_RENAME(ff_sine_960); + const INTFLOAT *swindow_prev = ics->use_kb_window[1] ? AAC_RENAME(ff_aac_kbd_short_120) : AAC_RENAME(ff_sine_120); + INTFLOAT *buf = ac->buf_mdct; + INTFLOAT *temp = ac->temp; + int i; + + // imdct + if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { + for (i = 0; i < 8; i++) + ac->mdct120->imdct_half(ac->mdct120, buf + i * 120, in + i * 128, 1); + } else { + ac->mdct960->imdct_half(ac->mdct960, buf, in, 1); + } + + /* window overlapping + * NOTE: To simplify the overlapping code, all 'meaningless' short to long + * and long to short transitions are considered to be short to short + * transitions. This leaves just two cases (long to long and short to short) + * with a little special sauce for EIGHT_SHORT_SEQUENCE. + */ + + if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) && + (ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) { + ac->fdsp->vector_fmul_window( out, saved, buf, lwindow_prev, 480); + } else { + memcpy( out, saved, 420 * sizeof(*out)); + + if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { + ac->fdsp->vector_fmul_window(out + 420 + 0*120, saved + 420, buf + 0*120, swindow_prev, 60); + ac->fdsp->vector_fmul_window(out + 420 + 1*120, buf + 0*120 + 60, buf + 1*120, swindow, 60); + ac->fdsp->vector_fmul_window(out + 420 + 2*120, buf + 1*120 + 60, buf + 2*120, swindow, 60); + ac->fdsp->vector_fmul_window(out + 420 + 3*120, buf + 2*120 + 60, buf + 3*120, swindow, 60); + ac->fdsp->vector_fmul_window(temp, buf + 3*120 + 60, buf + 4*120, swindow, 60); + memcpy( out + 420 + 4*120, temp, 60 * sizeof(*out)); + } else { + ac->fdsp->vector_fmul_window(out + 420, saved + 420, buf, swindow_prev, 60); + memcpy( out + 540, buf + 60, 420 * sizeof(*out)); + } + } + + // buffer update + if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { + memcpy( saved, temp + 60, 60 * sizeof(*saved)); + ac->fdsp->vector_fmul_window(saved + 60, buf + 4*120 + 60, buf + 5*120, swindow, 60); + ac->fdsp->vector_fmul_window(saved + 180, buf + 5*120 + 60, buf + 6*120, swindow, 60); + ac->fdsp->vector_fmul_window(saved + 300, buf + 6*120 + 60, buf + 7*120, swindow, 60); + memcpy( saved + 420, buf + 7*120 + 60, 60 * sizeof(*saved)); + } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) { + memcpy( saved, buf + 480, 420 * sizeof(*saved)); + memcpy( saved + 420, buf + 7*120 + 60, 60 * sizeof(*saved)); + } else { // LONG_STOP or ONLY_LONG + memcpy( saved, buf + 480, 480 * sizeof(*saved)); + } +#endif +} static void imdct_and_windowing_ld(AACContext *ac, SingleChannelElement *sce) { IndividualChannelStream *ics = &sce->ics; @@ -2771,7 +2876,10 @@ static void spectral_to_sample(AACContext *ac, int samples) imdct_and_window = imdct_and_windowing_eld; break; default: - imdct_and_window = ac->imdct_and_windowing; + if (ac->oc[1].m4ac.frame_length_short) + imdct_and_window = imdct_and_windowing_960; + else + imdct_and_window = ac->imdct_and_windowing; } for (type = 3; type >= 0; type--) { for (i = 0; i < MAX_ELEM_ID; i++) { @@ -3015,7 +3123,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, err = AVERROR_INVALIDDATA; goto fail; } - samples = 1024; + samples = ac->oc[1].m4ac.frame_length_short ? 960 : 1024; che->present = 1; } @@ -3242,7 +3350,9 @@ static av_cold int aac_decode_close(AVCodecContext *avctx) ff_mdct_end(&ac->mdct_ld); ff_mdct_end(&ac->mdct_ltp); #if !USE_FIXED + ff_mdct15_uninit(&ac->mdct120); ff_mdct15_uninit(&ac->mdct480); + ff_mdct15_uninit(&ac->mdct960); #endif av_freep(&ac->fdsp); return 0; diff --git a/libavcodec/aactab.c b/libavcodec/aactab.c index 77d8732c47d01..df551b058f562 100644 --- a/libavcodec/aactab.c +++ b/libavcodec/aactab.c @@ -37,6 +37,8 @@ float ff_aac_pow34sf_tab[428]; DECLARE_ALIGNED(32, float, ff_aac_kbd_long_1024)[1024]; DECLARE_ALIGNED(32, float, ff_aac_kbd_short_128)[128]; +DECLARE_ALIGNED(32, float, ff_aac_kbd_long_960)[960]; +DECLARE_ALIGNED(32, float, ff_aac_kbd_short_120)[120]; DECLARE_ALIGNED(32, int, ff_aac_kbd_long_1024_fixed)[1024]; DECLARE_ALIGNED(32, int, ff_aac_kbd_short_128_fixed)[128]; @@ -44,6 +46,10 @@ const uint8_t ff_aac_num_swb_1024[] = { 41, 41, 47, 49, 49, 51, 47, 47, 43, 43, 43, 40, 40 }; +const uint8_t ff_aac_num_swb_960[] = { + 40, 40, 46, 49, 49, 49, 46, 46, 42, 42, 42, 40, 40 +}; + const uint8_t ff_aac_num_swb_512[] = { 0, 0, 0, 36, 36, 37, 31, 31, 0, 0, 0, 0, 0 }; @@ -56,6 +62,10 @@ const uint8_t ff_aac_num_swb_128[] = { 12, 12, 12, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15 }; +const uint8_t ff_aac_num_swb_120[] = { + 12, 12, 12, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15 +}; + const uint8_t ff_aac_pred_sfb_max[] = { 33, 33, 38, 40, 40, 40, 41, 41, 37, 37, 37, 34, 34 }; @@ -1229,6 +1239,100 @@ static const uint16_t swb_offset_128_8[] = { 36, 44, 52, 60, 72, 88, 108, 128 }; +static const uint16_t swb_offset_960_96[] = +{ + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, + 40, 44, 48, 52, 56, 64, 72, 80, 88, 96, + 108, 120, 132, 144, 156, 172, 188, 212, 240, 276, + 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, + 960 +}; + +static const uint16_t swb_offset_960_64[] = +{ + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, + 40, 44, 48, 52, 56, 64, 72, 80, 88, 100, + 112, 124, 140, 156, 172, 192, 216, 240, 268, 304, + 344, 384, 424, 464, 504, 544, 584, 624, 664, 704, + 744, 784, 824, 864, 904, 944, 960 +}; + +static const uint16_t swb_offset_960_48[] = +{ + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, + 40, 48, 56, 64, 72, 80, 88, 96, 108, 120, + 132, 144, 160, 176, 196, 216, 240, 264, 292, 320, + 352, 384, 416, 448, 480, 512, 544, 576, 608, 640, + 672, 704, 736, 768, 800, 832, 864, 896, 928, 960 +}; + +static const uint16_t swb_offset_960_32[] = +{ + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, + 40, 48, 56, 64, 72, 80, 88, 96, 108, 120, + 132, 144, 160, 176, 196, 216, 240, 264, 292, 320, + 352, 384, 416, 448, 480, 512, 544, 576, 608, 640, + 672, 704, 736, 768, 800, 832, 864, 896, 928, 960 +}; + +static const uint16_t swb_offset_960_24[] = +{ + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, + 40, 44, 52, 60, 68, 76, 84, 92, 100, 108, + 116, 124, 136, 148, 160, 172, 188, 204, 220, 240, + 260, 284, 308, 336, 364, 396, 432, 468, 508, 552, + 600, 652, 704, 768, 832, 896, 960 +}; + +static const uint16_t swb_offset_960_16[] = +{ + 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, + 80, 88, 100, 112, 124, 136, 148, 160, 172, 184, + 196, 212, 228, 244, 260, 280, 300, 320, 344, 368, + 396, 424, 456, 492, 532, 572, 616, 664, 716, 772, + 832, 896, 960 +}; + +static const uint16_t swb_offset_960_8[] = +{ + 0, 12, 24, 36, 48, 60, 72, 84, 96, 108, + 120, 132, 144, 156, 172, 188, 204, 220, 236, 252, + 268, 288, 308, 328, 348, 372, 396, 420, 448, 476, + 508, 544, 580, 620, 664, 712, 764, 820, 880, 944, + 960 +}; + + +static const uint16_t swb_offset_120_96[] = +{ + 0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 120 +}; + +static const uint16_t swb_offset_120_64[] = +{ + 0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 120 +}; + +static const uint16_t swb_offset_120_48[] = +{ + 0, 4, 8, 12, 16, 20, 28, 36, 44, 56, 68, 80, 96, 112, 120 +}; + +static const uint16_t swb_offset_120_24[] = +{ + 0, 4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 64, 76, 92, 108, 120 +}; + +static const uint16_t swb_offset_120_16[] = +{ + 0, 4, 8, 12, 16, 20, 24, 28, 32, 40, 48, 60, 72, 88, 108, 120 +}; + +static const uint16_t swb_offset_120_8[] = +{ + 0, 4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 60, 72, 88, 108, 120 +}; + const uint16_t * const ff_swb_offset_1024[] = { swb_offset_1024_96, swb_offset_1024_96, swb_offset_1024_64, swb_offset_1024_48, swb_offset_1024_48, swb_offset_1024_32, @@ -1237,6 +1341,14 @@ const uint16_t * const ff_swb_offset_1024[] = { swb_offset_1024_8 }; +const uint16_t * const ff_swb_offset_960[] = { + swb_offset_960_96, swb_offset_960_96, swb_offset_960_64, + swb_offset_960_48, swb_offset_960_48, swb_offset_960_32, + swb_offset_960_24, swb_offset_960_24, swb_offset_960_16, + swb_offset_960_16, swb_offset_960_16, swb_offset_960_8, + swb_offset_960_8 +}; + const uint16_t * const ff_swb_offset_512[] = { NULL, NULL, NULL, swb_offset_512_48, swb_offset_512_48, swb_offset_512_32, @@ -1263,6 +1375,14 @@ const uint16_t * const ff_swb_offset_128[] = { swb_offset_128_8 }; +const uint16_t * const ff_swb_offset_120[] = { + swb_offset_120_96, swb_offset_120_96, swb_offset_120_96, + swb_offset_120_48, swb_offset_120_48, swb_offset_120_48, + swb_offset_120_24, swb_offset_120_24, swb_offset_120_16, + swb_offset_120_16, swb_offset_120_16, swb_offset_120_8, + swb_offset_120_8 +}; + // @} /* @name ff_tns_max_bands diff --git a/libavcodec/aactab.h b/libavcodec/aactab.h index 48ca0fd163875..7cd812823177b 100644 --- a/libavcodec/aactab.h +++ b/libavcodec/aactab.h @@ -136,6 +136,8 @@ static const INTFLOAT * const tns_tmp2_map[4] = { */ DECLARE_ALIGNED(32, extern float, ff_aac_kbd_long_1024)[1024]; DECLARE_ALIGNED(32, extern float, ff_aac_kbd_short_128)[128]; +DECLARE_ALIGNED(32, extern float, ff_aac_kbd_long_960)[960]; +DECLARE_ALIGNED(32, extern float, ff_aac_kbd_short_120)[120]; DECLARE_ALIGNED(32, extern int, ff_aac_kbd_long_1024_fixed)[1024]; DECLARE_ALIGNED(32, extern int, ff_aac_kbd_long_512_fixed)[512]; DECLARE_ALIGNED(32, extern int, ff_aac_kbd_short_128_fixed)[128]; @@ -149,9 +151,11 @@ DECLARE_ALIGNED(32, extern const int, ff_aac_eld_window_480_fixed)[1800]; * @{ */ extern const uint8_t ff_aac_num_swb_1024[]; +extern const uint8_t ff_aac_num_swb_960 []; extern const uint8_t ff_aac_num_swb_512 []; extern const uint8_t ff_aac_num_swb_480 []; extern const uint8_t ff_aac_num_swb_128 []; +extern const uint8_t ff_aac_num_swb_120 []; // @} extern const uint8_t ff_aac_pred_sfb_max []; @@ -168,9 +172,11 @@ extern const float *ff_aac_codebook_vector_vals[]; extern const uint16_t *ff_aac_codebook_vector_idx[]; extern const uint16_t * const ff_swb_offset_1024[13]; +extern const uint16_t * const ff_swb_offset_960 [13]; extern const uint16_t * const ff_swb_offset_512 [13]; extern const uint16_t * const ff_swb_offset_480 [13]; extern const uint16_t * const ff_swb_offset_128 [13]; +extern const uint16_t * const ff_swb_offset_120 [13]; extern const uint8_t ff_tns_max_bands_1024[13]; extern const uint8_t ff_tns_max_bands_512 [13]; diff --git a/libavcodec/sinewin.h b/libavcodec/sinewin.h index 27c107ce5941c..6b97a7185f5fe 100644 --- a/libavcodec/sinewin.h +++ b/libavcodec/sinewin.h @@ -52,14 +52,16 @@ void AAC_RENAME(ff_init_ff_sine_windows)(int index); extern SINETABLE( 32); extern SINETABLE( 64); +extern SINETABLE( 120); extern SINETABLE( 128); extern SINETABLE( 256); extern SINETABLE( 512); +extern SINETABLE( 960); extern SINETABLE(1024); extern SINETABLE(2048); extern SINETABLE(4096); extern SINETABLE(8192); -extern SINETABLE_CONST INTFLOAT * const AAC_RENAME(ff_sine_windows)[14]; +extern SINETABLE_CONST INTFLOAT * const AAC_RENAME(ff_sine_windows)[16]; #endif /* AVCODEC_SINEWIN_H */ diff --git a/libavcodec/sinewin_tablegen.h b/libavcodec/sinewin_tablegen.h index 4432135f19fc3..30c8cbf769a9b 100644 --- a/libavcodec/sinewin_tablegen.h +++ b/libavcodec/sinewin_tablegen.h @@ -34,9 +34,11 @@ #if !CONFIG_HARDCODED_TABLES SINETABLE( 32); SINETABLE( 64); +SINETABLE( 120); SINETABLE( 128); SINETABLE( 256); SINETABLE( 512); +SINETABLE( 960); SINETABLE(1024); SINETABLE(2048); SINETABLE(4096); @@ -59,7 +61,8 @@ SINETABLE_CONST INTFLOAT * const AAC_RENAME(ff_sine_windows)[] = { NULL, NULL, NULL, NULL, NULL, // unused AAC_RENAME(ff_sine_32) , AAC_RENAME(ff_sine_64), AAC_RENAME(ff_sine_128), AAC_RENAME(ff_sine_256), AAC_RENAME(ff_sine_512), AAC_RENAME(ff_sine_1024), - AAC_RENAME(ff_sine_2048), AAC_RENAME(ff_sine_4096), AAC_RENAME(ff_sine_8192) + AAC_RENAME(ff_sine_2048), AAC_RENAME(ff_sine_4096), AAC_RENAME(ff_sine_8192), + AAC_RENAME(ff_sine_120), AAC_RENAME(ff_sine_960), }; // Generate a sine window. From cb96e9bea41839407e8e0bef722ac0b9d23812ae Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Fri, 18 Aug 2017 14:07:29 -0700 Subject: [PATCH 2826/3374] fate: add test vector aac-al04sf_48 --- tests/fate/aac.mak | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/fate/aac.mak b/tests/fate/aac.mak index 5ef8ddc2b94d7..e8cbcef54d7a9 100644 --- a/tests/fate/aac.mak +++ b/tests/fate/aac.mak @@ -2,6 +2,10 @@ FATE_AAC += fate-aac-al04_44 fate-aac-al04_44: CMD = pcm -i $(TARGET_SAMPLES)/aac/al04_44.mp4 fate-aac-al04_44: REF = $(SAMPLES)/aac/al04_44.s16 +FATE_AAC += fate-aac-al04sf_48 +fate-aac-al04sf_48: CMD = pcm -i $(TARGET_SAMPLES)/aac/al04sf_48.mp4 +fate-aac-al04sf_48: REF = $(SAMPLES)/aac/al04sf_48.s16 + FATE_AAC += fate-aac-al05_44 fate-aac-al05_44: CMD = pcm -i $(TARGET_SAMPLES)/aac/al05_44.mp4 fate-aac-al05_44: REF = $(SAMPLES)/aac/al05_44.s16 From e51073fe00d2f7ae1c455d441b305e2b5c8251bc Mon Sep 17 00:00:00 2001 From: James Almer Date: Thu, 24 Aug 2017 23:39:05 -0300 Subject: [PATCH 2827/3374] checkasm/vf_blend: rename addition128 and difference128 to grainmerge and grainextract This was missing from f8d0689d3f. Fixes checkasm. --- tests/checkasm/vf_blend.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/checkasm/vf_blend.c b/tests/checkasm/vf_blend.c index 4e018ac69ed49..be6573045288c 100644 --- a/tests/checkasm/vf_blend.c +++ b/tests/checkasm/vf_blend.c @@ -103,11 +103,11 @@ void checkasm_check_blend(void) check_blend_func(); check_and_report(addition, BLEND_ADDITION) - check_and_report(addition128, BLEND_ADDITION128) + check_and_report(grainmerge, BLEND_GRAINMERGE) check_and_report(and, BLEND_AND) check_and_report(average, BLEND_AVERAGE) check_and_report(darken, BLEND_DARKEN) - check_and_report(difference128, BLEND_DIFFERENCE128) + check_and_report(grainextract, BLEND_GRAINEXTRACT) check_and_report(hardmix, BLEND_HARDMIX) check_and_report(lighten, BLEND_LIGHTEN) check_and_report(multiply, BLEND_MULTIPLY) From ae1ce0db91b8c29c94bcb2ab398d6102346344ef Mon Sep 17 00:00:00 2001 From: Muhammad Faiz Date: Wed, 23 Aug 2017 01:35:35 +0700 Subject: [PATCH 2828/3374] avfilter/af_firequalizer: add min_phase option Signed-off-by: Muhammad Faiz --- doc/filters.texi | 3 + libavfilter/af_firequalizer.c | 147 +++++++++++++++++++++++++++++++++- 2 files changed, 147 insertions(+), 3 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 8416ee44e52d2..bc618a8eb91e6 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -2667,6 +2667,9 @@ Default is linlog. @item fft2 Enable 2-channel convolution using complex FFT. This improves speed significantly. Default is disabled. + +@item min_phase +Enable minimum phase impulse response. Default is disabled. @end table @subsection Examples diff --git a/libavfilter/af_firequalizer.c b/libavfilter/af_firequalizer.c index 7741057a65415..8348e7558b0eb 100644 --- a/libavfilter/af_firequalizer.c +++ b/libavfilter/af_firequalizer.c @@ -70,13 +70,17 @@ typedef struct FIREqualizerContext { RDFTContext *rdft; RDFTContext *irdft; FFTContext *fft_ctx; + RDFTContext *cepstrum_rdft; + RDFTContext *cepstrum_irdft; int analysis_rdft_len; int rdft_len; + int cepstrum_len; float *analysis_buf; float *dump_buf; float *kernel_tmp_buf; float *kernel_buf; + float *cepstrum_buf; float *conv_buf; OverlapIndex *conv_idx; int fir_len; @@ -99,6 +103,7 @@ typedef struct FIREqualizerContext { char *dumpfile; int dumpscale; int fft2; + int min_phase; int nb_gain_entry; int gain_entry_err; @@ -135,6 +140,7 @@ static const AVOption firequalizer_options[] = { { "dumpfile", "set dump file", OFFSET(dumpfile), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS }, { "dumpscale", "set dump scale", OFFSET(dumpscale), AV_OPT_TYPE_INT, { .i64 = SCALE_LINLOG }, 0, NB_SCALE-1, FLAGS, "scale" }, { "fft2", "set 2-channels fft", OFFSET(fft2), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, + { "min_phase", "set minimum phase mode", OFFSET(min_phase), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, { NULL } }; @@ -147,13 +153,18 @@ static void common_uninit(FIREqualizerContext *s) av_rdft_end(s->rdft); av_rdft_end(s->irdft); av_fft_end(s->fft_ctx); + av_rdft_end(s->cepstrum_rdft); + av_rdft_end(s->cepstrum_irdft); s->analysis_rdft = s->analysis_irdft = s->rdft = s->irdft = NULL; s->fft_ctx = NULL; + s->cepstrum_rdft = NULL; + s->cepstrum_irdft = NULL; av_freep(&s->analysis_buf); av_freep(&s->dump_buf); av_freep(&s->kernel_tmp_buf); av_freep(&s->kernel_buf); + av_freep(&s->cepstrum_buf); av_freep(&s->conv_buf); av_freep(&s->conv_idx); } @@ -235,6 +246,46 @@ static void fast_convolute(FIREqualizerContext *av_restrict s, const float *av_r } } +static void fast_convolute_nonlinear(FIREqualizerContext *av_restrict s, const float *av_restrict kernel_buf, + float *av_restrict conv_buf, OverlapIndex *av_restrict idx, + float *av_restrict data, int nsamples) +{ + if (nsamples <= s->nsamples_max) { + float *buf = conv_buf + idx->buf_idx * s->rdft_len; + float *obuf = conv_buf + !idx->buf_idx * s->rdft_len + idx->overlap_idx; + int k; + + memcpy(buf, data, nsamples * sizeof(*data)); + memset(buf + nsamples, 0, (s->rdft_len - nsamples) * sizeof(*data)); + av_rdft_calc(s->rdft, buf); + + buf[0] *= kernel_buf[0]; + buf[1] *= kernel_buf[1]; + for (k = 2; k < s->rdft_len; k += 2) { + float re, im; + re = buf[k] * kernel_buf[k] - buf[k+1] * kernel_buf[k+1]; + im = buf[k] * kernel_buf[k+1] + buf[k+1] * kernel_buf[k]; + buf[k] = re; + buf[k+1] = im; + } + + av_rdft_calc(s->irdft, buf); + for (k = 0; k < s->rdft_len - idx->overlap_idx; k++) + buf[k] += obuf[k]; + memcpy(data, buf, nsamples * sizeof(*data)); + idx->buf_idx = !idx->buf_idx; + idx->overlap_idx = nsamples; + } else { + while (nsamples > s->nsamples_max * 2) { + fast_convolute_nonlinear(s, kernel_buf, conv_buf, idx, data, s->nsamples_max); + data += s->nsamples_max; + nsamples -= s->nsamples_max; + } + fast_convolute_nonlinear(s, kernel_buf, conv_buf, idx, data, nsamples/2); + fast_convolute_nonlinear(s, kernel_buf, conv_buf, idx, data + nsamples/2, nsamples - nsamples/2); + } +} + static void fast_convolute2(FIREqualizerContext *av_restrict s, const float *av_restrict kernel_buf, FFTComplex *av_restrict conv_buf, OverlapIndex *av_restrict idx, float *av_restrict data0, float *av_restrict data1, int nsamples) { @@ -310,22 +361,32 @@ static void dump_fir(AVFilterContext *ctx, FILE *fp, int ch) double delay = s->zero_phase ? 0.0 : (double) center / rate; double vx, ya, yb; + if (!s->min_phase) { s->analysis_buf[0] *= s->rdft_len/2; for (x = 1; x <= center; x++) { s->analysis_buf[x] *= s->rdft_len/2; s->analysis_buf[s->analysis_rdft_len - x] *= s->rdft_len/2; } + } else { + for (x = 0; x < s->fir_len; x++) + s->analysis_buf[x] *= s->rdft_len/2; + } if (ch) fprintf(fp, "\n\n"); fprintf(fp, "# time[%d] (time amplitude)\n", ch); + if (!s->min_phase) { for (x = center; x > 0; x--) fprintf(fp, "%15.10f %15.10f\n", delay - (double) x / rate, (double) s->analysis_buf[s->analysis_rdft_len - x]); for (x = 0; x <= center; x++) fprintf(fp, "%15.10f %15.10f\n", delay + (double)x / rate , (double) s->analysis_buf[x]); + } else { + for (x = 0; x < s->fir_len; x++) + fprintf(fp, "%15.10f %15.10f\n", (double)x / rate, (double) s->analysis_buf[x]); + } av_rdft_calc(s->analysis_rdft, s->analysis_buf); @@ -337,7 +398,9 @@ static void dump_fir(AVFilterContext *ctx, FILE *fp, int ch) if (xlog) vx = log2(0.05*vx); ya = s->dump_buf[i]; - yb = s->analysis_buf[i]; + yb = s->min_phase && (i > 1) ? hypotf(s->analysis_buf[i], s->analysis_buf[i+1]) : s->analysis_buf[i]; + if (s->min_phase) + yb = fabs(yb); if (ylog) { ya = 20.0 * log10(fabs(ya)); yb = 20.0 * log10(fabs(yb)); @@ -487,6 +550,53 @@ enum VarOffset { VAR_NB }; +static void generate_min_phase_kernel(FIREqualizerContext *s, float *rdft_buf) +{ + int k, cepstrum_len = s->cepstrum_len, rdft_len = s->rdft_len; + double norm = 2.0 / cepstrum_len; + + memset(s->cepstrum_buf, 0, cepstrum_len * sizeof(*s->cepstrum_buf)); + memcpy(s->cepstrum_buf, rdft_buf, rdft_len/2 * sizeof(*rdft_buf)); + memcpy(s->cepstrum_buf + cepstrum_len - rdft_len/2, rdft_buf + rdft_len/2, rdft_len/2 * sizeof(*rdft_buf)); + + av_rdft_calc(s->cepstrum_rdft, s->cepstrum_buf); + + s->cepstrum_buf[0] = log(FFMAX(s->cepstrum_buf[0], 1e-10)); + s->cepstrum_buf[1] = log(FFMAX(s->cepstrum_buf[1], 1e-10)); + + for (k = 2; k < cepstrum_len; k += 2) { + s->cepstrum_buf[k] = log(FFMAX(s->cepstrum_buf[k], 1e-10)); + s->cepstrum_buf[k+1] = 0; + } + + av_rdft_calc(s->cepstrum_irdft, s->cepstrum_buf); + + memset(s->cepstrum_buf + cepstrum_len/2 + 1, 0, (cepstrum_len/2 - 1) * sizeof(*s->cepstrum_buf)); + for (k = 1; k < cepstrum_len/2; k++) + s->cepstrum_buf[k] *= 2; + + av_rdft_calc(s->cepstrum_rdft, s->cepstrum_buf); + + s->cepstrum_buf[0] = exp(s->cepstrum_buf[0] * norm) * norm; + s->cepstrum_buf[1] = exp(s->cepstrum_buf[1] * norm) * norm; + for (k = 2; k < cepstrum_len; k += 2) { + double mag = exp(s->cepstrum_buf[k] * norm) * norm; + double ph = s->cepstrum_buf[k+1] * norm; + s->cepstrum_buf[k] = mag * cos(ph); + s->cepstrum_buf[k+1] = mag * sin(ph); + } + + av_rdft_calc(s->cepstrum_irdft, s->cepstrum_buf); + memset(rdft_buf, 0, s->rdft_len * sizeof(*rdft_buf)); + memcpy(rdft_buf, s->cepstrum_buf, s->fir_len * sizeof(*rdft_buf)); + + if (s->dumpfile) { + memset(s->analysis_buf, 0, s->analysis_rdft_len * sizeof(*s->analysis_buf)); + memcpy(s->analysis_buf, s->cepstrum_buf, s->fir_len * sizeof(*s->analysis_buf)); + } + +} + static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *gain_entry) { FIREqualizerContext *s = ctx->priv; @@ -549,7 +659,7 @@ static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *g if (xlog) vars[VAR_F] = log2(0.05 * vars[VAR_F]); result = av_expr_eval(gain_expr, vars, ctx); - s->analysis_buf[2*k] = ylog ? pow(10.0, 0.05 * result) : result; + s->analysis_buf[2*k] = ylog ? pow(10.0, 0.05 * result) : s->min_phase ? fabs(result) : result; s->analysis_buf[2*k+1] = 0.0; } @@ -604,6 +714,8 @@ static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *g memset(s->analysis_buf + center + 1, 0, (s->analysis_rdft_len - s->fir_len) * sizeof(*s->analysis_buf)); memcpy(rdft_buf, s->analysis_buf, s->rdft_len/2 * sizeof(*s->analysis_buf)); memcpy(rdft_buf + s->rdft_len/2, s->analysis_buf + s->analysis_rdft_len - s->rdft_len/2, s->rdft_len/2 * sizeof(*s->analysis_buf)); + if (s->min_phase) + generate_min_phase_kernel(s, rdft_buf); av_rdft_calc(s->rdft, rdft_buf); for (k = 0; k < s->rdft_len; k++) { @@ -616,10 +728,12 @@ static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *g } } + if (!s->min_phase) { rdft_buf[s->rdft_len-1] = rdft_buf[1]; for (k = 0; k < s->rdft_len/2; k++) rdft_buf[k] = rdft_buf[2*k]; rdft_buf[s->rdft_len/2] = rdft_buf[s->rdft_len-1]; + } if (dump_fp) dump_fir(ctx, dump_fp, ch); @@ -670,6 +784,25 @@ static int config_input(AVFilterLink *inlink) if (s->fft2 && !s->multi && inlink->channels > 1 && !(s->fft_ctx = av_fft_init(rdft_bits, 0))) return AVERROR(ENOMEM); + if (s->min_phase) { + int cepstrum_bits = rdft_bits + 2; + if (cepstrum_bits > RDFT_BITS_MAX) { + av_log(ctx, AV_LOG_ERROR, "too large delay, please decrease it.\n"); + return AVERROR(EINVAL); + } + + cepstrum_bits = FFMIN(RDFT_BITS_MAX, cepstrum_bits + 1); + s->cepstrum_rdft = av_rdft_init(cepstrum_bits, DFT_R2C); + s->cepstrum_irdft = av_rdft_init(cepstrum_bits, IDFT_C2R); + if (!s->cepstrum_rdft || !s->cepstrum_irdft) + return AVERROR(ENOMEM); + + s->cepstrum_len = 1 << cepstrum_bits; + s->cepstrum_buf = av_malloc_array(s->cepstrum_len, sizeof(*s->cepstrum_buf)); + if (!s->cepstrum_buf) + return AVERROR(ENOMEM); + } + for ( ; rdft_bits <= RDFT_BITS_MAX; rdft_bits++) { s->analysis_rdft_len = 1 << rdft_bits; if (inlink->sample_rate <= s->accuracy * s->analysis_rdft_len) @@ -712,6 +845,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) FIREqualizerContext *s = ctx->priv; int ch; + if (!s->min_phase) { for (ch = 0; ch + 1 < inlink->channels && s->fft_ctx; ch += 2) { fast_convolute2(s, s->kernel_buf, (FFTComplex *)(s->conv_buf + 2 * ch * s->rdft_len), s->conv_idx + ch, (float *) frame->extended_data[ch], @@ -723,11 +857,18 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) s->conv_buf + 2 * ch * s->rdft_len, s->conv_idx + ch, (float *) frame->extended_data[ch], frame->nb_samples); } + } else { + for (ch = 0; ch < inlink->channels; ch++) { + fast_convolute_nonlinear(s, s->kernel_buf + (s->multi ? ch * s->rdft_len : 0), + s->conv_buf + 2 * ch * s->rdft_len, s->conv_idx + ch, + (float *) frame->extended_data[ch], frame->nb_samples); + } + } s->next_pts = AV_NOPTS_VALUE; if (frame->pts != AV_NOPTS_VALUE) { s->next_pts = frame->pts + av_rescale_q(frame->nb_samples, av_make_q(1, inlink->sample_rate), inlink->time_base); - if (s->zero_phase) + if (s->zero_phase && !s->min_phase) frame->pts -= av_rescale_q(s->fir_len/2, av_make_q(1, inlink->sample_rate), inlink->time_base); } s->frame_nsamples_max = FFMAX(s->frame_nsamples_max, frame->nb_samples); From e0e991f8a131c0b4417cf28a566a4b05f6372271 Mon Sep 17 00:00:00 2001 From: Muhammad Faiz Date: Fri, 25 Aug 2017 10:39:16 +0700 Subject: [PATCH 2829/3374] avfilter/af_firequalizer: reindent after previous commit Signed-off-by: Muhammad Faiz --- libavfilter/af_firequalizer.c | 38 +++++++++++++++++------------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/libavfilter/af_firequalizer.c b/libavfilter/af_firequalizer.c index 8348e7558b0eb..2b6245c698cd7 100644 --- a/libavfilter/af_firequalizer.c +++ b/libavfilter/af_firequalizer.c @@ -362,11 +362,11 @@ static void dump_fir(AVFilterContext *ctx, FILE *fp, int ch) double vx, ya, yb; if (!s->min_phase) { - s->analysis_buf[0] *= s->rdft_len/2; - for (x = 1; x <= center; x++) { - s->analysis_buf[x] *= s->rdft_len/2; - s->analysis_buf[s->analysis_rdft_len - x] *= s->rdft_len/2; - } + s->analysis_buf[0] *= s->rdft_len/2; + for (x = 1; x <= center; x++) { + s->analysis_buf[x] *= s->rdft_len/2; + s->analysis_buf[s->analysis_rdft_len - x] *= s->rdft_len/2; + } } else { for (x = 0; x < s->fir_len; x++) s->analysis_buf[x] *= s->rdft_len/2; @@ -729,10 +729,10 @@ static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *g } if (!s->min_phase) { - rdft_buf[s->rdft_len-1] = rdft_buf[1]; - for (k = 0; k < s->rdft_len/2; k++) - rdft_buf[k] = rdft_buf[2*k]; - rdft_buf[s->rdft_len/2] = rdft_buf[s->rdft_len-1]; + rdft_buf[s->rdft_len-1] = rdft_buf[1]; + for (k = 0; k < s->rdft_len/2; k++) + rdft_buf[k] = rdft_buf[2*k]; + rdft_buf[s->rdft_len/2] = rdft_buf[s->rdft_len-1]; } if (dump_fp) @@ -846,17 +846,17 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) int ch; if (!s->min_phase) { - for (ch = 0; ch + 1 < inlink->channels && s->fft_ctx; ch += 2) { - fast_convolute2(s, s->kernel_buf, (FFTComplex *)(s->conv_buf + 2 * ch * s->rdft_len), - s->conv_idx + ch, (float *) frame->extended_data[ch], - (float *) frame->extended_data[ch+1], frame->nb_samples); - } + for (ch = 0; ch + 1 < inlink->channels && s->fft_ctx; ch += 2) { + fast_convolute2(s, s->kernel_buf, (FFTComplex *)(s->conv_buf + 2 * ch * s->rdft_len), + s->conv_idx + ch, (float *) frame->extended_data[ch], + (float *) frame->extended_data[ch+1], frame->nb_samples); + } - for ( ; ch < inlink->channels; ch++) { - fast_convolute(s, s->kernel_buf + (s->multi ? ch * s->rdft_len : 0), - s->conv_buf + 2 * ch * s->rdft_len, s->conv_idx + ch, - (float *) frame->extended_data[ch], frame->nb_samples); - } + for ( ; ch < inlink->channels; ch++) { + fast_convolute(s, s->kernel_buf + (s->multi ? ch * s->rdft_len : 0), + s->conv_buf + 2 * ch * s->rdft_len, s->conv_idx + ch, + (float *) frame->extended_data[ch], frame->nb_samples); + } } else { for (ch = 0; ch < inlink->channels; ch++) { fast_convolute_nonlinear(s, s->kernel_buf + (s->multi ? ch * s->rdft_len : 0), From 4b96fd2b1ec6975c369fcd44f20ef5ce9441394c Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Fri, 25 Aug 2017 09:07:28 +0200 Subject: [PATCH 2830/3374] avfilter/af_agate: switch to activate Signed-off-by: Paul B Mahol --- libavfilter/af_agate.c | 114 +++++++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 55 deletions(-) diff --git a/libavfilter/af_agate.c b/libavfilter/af_agate.c index 328e25ba84ebb..f4fcabef93fd9 100644 --- a/libavfilter/af_agate.c +++ b/libavfilter/af_agate.c @@ -29,6 +29,7 @@ #include "libavutil/opt.h" #include "avfilter.h" #include "audio.h" +#include "filters.h" #include "formats.h" #include "hermite.h" @@ -265,71 +266,76 @@ AVFilter ff_af_agate = { #define sidechaingate_options options AVFILTER_DEFINE_CLASS(sidechaingate); -static int scfilter_frame(AVFilterLink *link, AVFrame *frame) +static int activate(AVFilterContext *ctx) { - AVFilterContext *ctx = link->dst; AudioGateContext *s = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - AVFrame *out, *in[2] = { NULL }; + AVFrame *out = NULL, *in[2] = { NULL }; + int ret, i, status, nb_samples; double *dst; - int nb_samples; - int i; + int64_t pts; - for (i = 0; i < 2; i++) - if (link == ctx->inputs[i]) - break; - av_assert0(i < 2); - av_audio_fifo_write(s->fifo[i], (void **)frame->extended_data, - frame->nb_samples); - av_frame_free(&frame); + if ((ret = ff_inlink_consume_frame(ctx->inputs[0], &in[0])) > 0) { + av_audio_fifo_write(s->fifo[0], (void **)in[0]->extended_data, + in[0]->nb_samples); + av_frame_free(&in[0]); + } + if (ret < 0) + return ret; + if ((ret = ff_inlink_consume_frame(ctx->inputs[1], &in[1])) > 0) { + av_audio_fifo_write(s->fifo[1], (void **)in[1]->extended_data, + in[1]->nb_samples); + av_frame_free(&in[1]); + } + if (ret < 0) + return ret; nb_samples = FFMIN(av_audio_fifo_size(s->fifo[0]), av_audio_fifo_size(s->fifo[1])); - if (!nb_samples) - return 0; - - out = ff_get_audio_buffer(outlink, nb_samples); - if (!out) - return AVERROR(ENOMEM); - for (i = 0; i < 2; i++) { - in[i] = ff_get_audio_buffer(ctx->inputs[i], nb_samples); - if (!in[i]) { - av_frame_free(&in[0]); - av_frame_free(&in[1]); - av_frame_free(&out); + if (nb_samples) { + out = ff_get_audio_buffer(ctx->outputs[0], nb_samples); + if (!out) return AVERROR(ENOMEM); + for (i = 0; i < 2; i++) { + in[i] = ff_get_audio_buffer(ctx->inputs[i], nb_samples); + if (!in[i]) { + av_frame_free(&in[0]); + av_frame_free(&in[1]); + av_frame_free(&out); + return AVERROR(ENOMEM); + } + av_audio_fifo_read(s->fifo[i], (void **)in[i]->data, nb_samples); } - av_audio_fifo_read(s->fifo[i], (void **)in[i]->data, nb_samples); - } - dst = (double *)out->data[0]; - out->pts = s->pts; - s->pts += nb_samples; + dst = (double *)out->data[0]; + out->pts = s->pts; + s->pts += nb_samples; - gate(s, (double *)in[0]->data[0], dst, - (double *)in[1]->data[0], nb_samples, - s->level_in, s->level_sc, - ctx->inputs[0], ctx->inputs[1]); + gate(s, (double *)in[0]->data[0], dst, + (double *)in[1]->data[0], nb_samples, + s->level_in, s->level_sc, + ctx->inputs[0], ctx->inputs[1]); - av_frame_free(&in[0]); - av_frame_free(&in[1]); + av_frame_free(&in[0]); + av_frame_free(&in[1]); - return ff_filter_frame(outlink, out); -} - -static int screquest_frame(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - AudioGateContext *s = ctx->priv; - int i; - - /* get a frame on each input */ - for (i = 0; i < 2; i++) { - AVFilterLink *inlink = ctx->inputs[i]; - if (!av_audio_fifo_size(s->fifo[i])) - return ff_request_frame(inlink); + ret = ff_filter_frame(ctx->outputs[0], out); + if (ret < 0) + return ret; + } + if (ff_inlink_acknowledge_status(ctx->inputs[0], &status, &pts)) { + ff_outlink_set_status(ctx->outputs[0], status, pts); + return 0; + } else if (ff_inlink_acknowledge_status(ctx->inputs[1], &status, &pts)) { + ff_outlink_set_status(ctx->outputs[0], status, pts); + return 0; + } else { + if (ff_outlink_frame_wanted(ctx->outputs[0])) { + if (!av_audio_fifo_size(s->fifo[0])) + ff_inlink_request_frame(ctx->inputs[0]); + if (!av_audio_fifo_size(s->fifo[1])) + ff_inlink_request_frame(ctx->inputs[1]); + } + return 0; } - - return 0; } static int scquery_formats(AVFilterContext *ctx) @@ -408,11 +414,9 @@ static const AVFilterPad sidechaingate_inputs[] = { { .name = "main", .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = scfilter_frame, },{ .name = "sidechain", .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = scfilter_frame, }, { NULL } }; @@ -422,7 +426,6 @@ static const AVFilterPad sidechaingate_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_AUDIO, .config_props = scconfig_output, - .request_frame = screquest_frame, }, { NULL } }; @@ -433,6 +436,7 @@ AVFilter ff_af_sidechaingate = { .priv_size = sizeof(AudioGateContext), .priv_class = &sidechaingate_class, .query_formats = scquery_formats, + .activate = activate, .uninit = uninit, .inputs = sidechaingate_inputs, .outputs = sidechaingate_outputs, From 1e7ce6d92513f0bf0037a0b7ebb96ffc7c0c7993 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Fri, 25 Aug 2017 09:36:22 +0200 Subject: [PATCH 2831/3374] avfilter/af_amix: check ff_insert_inpad() for failure --- libavfilter/af_amix.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c index 809c8bf9ca820..78be57ac3f9d0 100644 --- a/libavfilter/af_amix.c +++ b/libavfilter/af_amix.c @@ -483,7 +483,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) static av_cold int init(AVFilterContext *ctx) { MixContext *s = ctx->priv; - int i; + int i, ret; for (i = 0; i < s->nb_inputs; i++) { char name[32]; @@ -496,7 +496,10 @@ static av_cold int init(AVFilterContext *ctx) return AVERROR(ENOMEM); pad.filter_frame = filter_frame; - ff_insert_inpad(ctx, i, &pad); + if ((ret = ff_insert_inpad(ctx, i, &pad)) < 0) { + av_freep(&pad.name); + return ret; + } } s->fdsp = avpriv_float_dsp_alloc(0); From 13f9639e3e2af50017c48fd804d76bad455f61af Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Fri, 25 Aug 2017 09:45:20 +0200 Subject: [PATCH 2832/3374] avfilter/af_headphone: check ff_insert_inpad() for failure Signed-off-by: Paul B Mahol --- libavfilter/af_headphone.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libavfilter/af_headphone.c b/libavfilter/af_headphone.c index 4fd6191bc4dd8..f6edccc9bd2da 100644 --- a/libavfilter/af_headphone.c +++ b/libavfilter/af_headphone.c @@ -660,7 +660,7 @@ static int config_input(AVFilterLink *inlink) static av_cold int init(AVFilterContext *ctx) { HeadphoneContext *s = ctx->priv; - int i; + int i, ret; AVFilterPad pad = { .name = "in0", @@ -668,7 +668,8 @@ static av_cold int init(AVFilterContext *ctx) .config_props = config_input, .filter_frame = filter_frame, }; - ff_insert_inpad(ctx, 0, &pad); + if ((ret = ff_insert_inpad(ctx, 0, &pad)) < 0) + return ret; if (!s->map) { av_log(ctx, AV_LOG_ERROR, "Valid mapping must be set.\n"); @@ -690,7 +691,10 @@ static av_cold int init(AVFilterContext *ctx) }; if (!name) return AVERROR(ENOMEM); - ff_insert_inpad(ctx, i, &pad); + if ((ret = ff_insert_inpad(ctx, i, &pad)) < 0) { + av_freep(&pad.name); + return ret; + } } s->fdsp = avpriv_float_dsp_alloc(0); From db5604ac26f06be34030c8ae8040c19d549280f1 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Fri, 25 Aug 2017 09:49:01 +0200 Subject: [PATCH 2833/3374] avfilter/af_join: check ff_insert_inpad() for failure Signed-off-by: Paul B Mahol --- libavfilter/af_join.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavfilter/af_join.c b/libavfilter/af_join.c index 74ecce052dacf..f8af0a180402b 100644 --- a/libavfilter/af_join.c +++ b/libavfilter/af_join.c @@ -232,7 +232,10 @@ static av_cold int join_init(AVFilterContext *ctx) pad.needs_fifo = 1; - ff_insert_inpad(ctx, i, &pad); + if ((ret = ff_insert_inpad(ctx, i, &pad)) < 0) { + av_freep(&pad.name); + return ret; + } } return 0; From f39136b0a76e61d149bf50d287b2110273a8afa1 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Fri, 25 Aug 2017 09:50:57 +0200 Subject: [PATCH 2834/3374] avfilter/af_merge: check ff_insert_inpad() for failure Signed-off-by: Paul B Mahol --- libavfilter/af_amerge.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libavfilter/af_amerge.c b/libavfilter/af_amerge.c index cc974cdb7fb78..09c660ef49b55 100644 --- a/libavfilter/af_amerge.c +++ b/libavfilter/af_amerge.c @@ -322,7 +322,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) static av_cold int init(AVFilterContext *ctx) { AMergeContext *s = ctx->priv; - int i; + int i, ret; s->in = av_calloc(s->nb_inputs, sizeof(*s->in)); if (!s->in) @@ -336,7 +336,10 @@ static av_cold int init(AVFilterContext *ctx) }; if (!name) return AVERROR(ENOMEM); - ff_insert_inpad(ctx, i, &pad); + if ((ret = ff_insert_inpad(ctx, i, &pad)) < 0) { + av_freep(&pad.name); + return ret; + } } return 0; } From 9bd1bf382e18a1595f6ded05e87390f79fa0328b Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Fri, 25 Aug 2017 09:53:46 +0200 Subject: [PATCH 2835/3374] avfilter/f_interleave: check ff_insert_inpad() for failure Signed-off-by: Paul B Mahol --- libavfilter/f_interleave.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libavfilter/f_interleave.c b/libavfilter/f_interleave.c index a9889005948a0..d8a73b52e5d36 100644 --- a/libavfilter/f_interleave.c +++ b/libavfilter/f_interleave.c @@ -110,7 +110,7 @@ static av_cold int init(AVFilterContext *ctx) { InterleaveContext *s = ctx->priv; const AVFilterPad *outpad = &ctx->filter->outputs[0]; - int i; + int i, ret; s->queues = av_calloc(s->nb_inputs, sizeof(s->queues[0])); if (!s->queues) @@ -133,7 +133,10 @@ static av_cold int init(AVFilterContext *ctx) default: av_assert0(0); } - ff_insert_inpad(ctx, i, &inpad); + if ((ret = ff_insert_inpad(ctx, i, &inpad)) < 0) { + av_freep(&inpad.name); + return ret; + } } return 0; From 99dd47a647529a82036682259f4c077dcd3a38af Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Fri, 25 Aug 2017 09:57:53 +0200 Subject: [PATCH 2836/3374] avfilter/vf_extractplanes: check ff_insert_outpad() for failure Signed-off-by: Paul B Mahol --- libavfilter/vf_extractplanes.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libavfilter/vf_extractplanes.c b/libavfilter/vf_extractplanes.c index f2118e6599dc4..fc676a25fae38 100644 --- a/libavfilter/vf_extractplanes.c +++ b/libavfilter/vf_extractplanes.c @@ -348,7 +348,7 @@ static av_cold int init(AVFilterContext *ctx) { ExtractPlanesContext *s = ctx->priv; int planes = (s->requested_planes & 0xf) | (s->requested_planes >> 4); - int i; + int i, ret; for (i = 0; i < 4; i++) { char *name; @@ -365,7 +365,10 @@ static av_cold int init(AVFilterContext *ctx) pad.type = AVMEDIA_TYPE_VIDEO; pad.config_props = config_output; - ff_insert_outpad(ctx, ctx->nb_outputs, &pad); + if ((ret = ff_insert_outpad(ctx, ctx->nb_outputs, &pad)) < 0) { + av_freep(&pad.name); + return ret; + } } return 0; From 730734d4f3e0f976b50cae9f94588f55e1845473 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Fri, 25 Aug 2017 10:01:52 +0200 Subject: [PATCH 2837/3374] avfilter/af_channelsplit: check ff_insert_outpad() for failure Signed-off-by: Paul B Mahol --- libavfilter/af_channelsplit.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavfilter/af_channelsplit.c b/libavfilter/af_channelsplit.c index 248eaca7e0427..8c6b00fe4f507 100644 --- a/libavfilter/af_channelsplit.c +++ b/libavfilter/af_channelsplit.c @@ -71,7 +71,9 @@ static av_cold int init(AVFilterContext *ctx) pad.type = AVMEDIA_TYPE_AUDIO; pad.name = av_get_channel_name(channel); - ff_insert_outpad(ctx, i, &pad); + if ((ret = ff_insert_outpad(ctx, i, &pad)) < 0) { + return ret; + } } fail: From 01b986cf1819320aff5d5c7a43401bb74a95524a Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Fri, 25 Aug 2017 10:04:28 +0200 Subject: [PATCH 2838/3374] avfilter/f_select: check ff_insert_outpad() for failure Signed-off-by: Paul B Mahol --- libavfilter/f_select.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavfilter/f_select.c b/libavfilter/f_select.c index c8602626b55f0..b1b2cbc21a985 100644 --- a/libavfilter/f_select.c +++ b/libavfilter/f_select.c @@ -186,7 +186,10 @@ static av_cold int init(AVFilterContext *ctx) return AVERROR(ENOMEM); pad.type = ctx->filter->inputs[0].type; pad.request_frame = request_frame; - ff_insert_outpad(ctx, i, &pad); + if ((ret = ff_insert_outpad(ctx, i, &pad)) < 0) { + av_freep(&pad.name); + return ret; + } } return 0; From 1a58da434ad0e8ba0167c4066e3dc7980c7b2804 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Fri, 25 Aug 2017 10:13:48 +0200 Subject: [PATCH 2839/3374] avfilter/avf_concat: check ff_insert_pad() for failure Signed-off-by: Paul B Mahol --- libavfilter/avf_concat.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libavfilter/avf_concat.c b/libavfilter/avf_concat.c index 4c4936868b8d8..6198a33d53560 100644 --- a/libavfilter/avf_concat.c +++ b/libavfilter/avf_concat.c @@ -361,6 +361,7 @@ static av_cold int init(AVFilterContext *ctx) { ConcatContext *cat = ctx->priv; unsigned seg, type, str; + int ret; /* create input pads */ for (seg = 0; seg < cat->nb_segments; seg++) { @@ -373,7 +374,10 @@ static av_cold int init(AVFilterContext *ctx) .filter_frame = filter_frame, }; pad.name = av_asprintf("in%d:%c%d", seg, "va"[type], str); - ff_insert_inpad(ctx, ctx->nb_inputs, &pad); + if ((ret = ff_insert_inpad(ctx, ctx->nb_inputs, &pad)) < 0) { + av_freep(&pad.name); + return ret; + } } } } @@ -386,7 +390,10 @@ static av_cold int init(AVFilterContext *ctx) .request_frame = request_frame, }; pad.name = av_asprintf("out:%c%d", "va"[type], str); - ff_insert_outpad(ctx, ctx->nb_outputs, &pad); + if ((ret = ff_insert_outpad(ctx, ctx->nb_outputs, &pad)) < 0) { + av_freep(&pad.name); + return ret; + } } } From dfea94ce994a916eb7c1a278a09748fd3928c00d Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Fri, 25 Aug 2017 10:20:13 +0200 Subject: [PATCH 2840/3374] avfilter/vf_fieldmatch: check ff_insert_inpad() for failure Signed-off-by: Paul B Mahol --- libavfilter/vf_fieldmatch.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libavfilter/vf_fieldmatch.c b/libavfilter/vf_fieldmatch.c index 17402158d4871..3694f26d33fed 100644 --- a/libavfilter/vf_fieldmatch.c +++ b/libavfilter/vf_fieldmatch.c @@ -904,17 +904,24 @@ static av_cold int fieldmatch_init(AVFilterContext *ctx) .filter_frame = filter_frame, .config_props = config_input, }; + int ret; if (!pad.name) return AVERROR(ENOMEM); - ff_insert_inpad(ctx, INPUT_MAIN, &pad); + if ((ret = ff_insert_inpad(ctx, INPUT_MAIN, &pad)) < 0) { + av_freep(&pad.name); + return ret; + } if (fm->ppsrc) { pad.name = av_strdup("clean_src"); pad.config_props = NULL; if (!pad.name) return AVERROR(ENOMEM); - ff_insert_inpad(ctx, INPUT_CLEANSRC, &pad); + if ((ret = ff_insert_inpad(ctx, INPUT_CLEANSRC, &pad)) < 0) { + av_freep(&pad.name); + return ret; + } } if ((fm->blockx & (fm->blockx - 1)) || From 0b940c95b2171cb1035c79b85492f5f6cdb060a6 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Fri, 25 Aug 2017 10:23:21 +0200 Subject: [PATCH 2841/3374] avfilter/vf_decimate: check ff_insert_inpad() for failure Signed-off-by: Paul B Mahol --- libavfilter/vf_decimate.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libavfilter/vf_decimate.c b/libavfilter/vf_decimate.c index f9a40f2d4c736..53347c7f10936 100644 --- a/libavfilter/vf_decimate.c +++ b/libavfilter/vf_decimate.c @@ -276,17 +276,24 @@ static av_cold int decimate_init(AVFilterContext *ctx) .filter_frame = filter_frame, .config_props = config_input, }; + int ret; if (!pad.name) return AVERROR(ENOMEM); - ff_insert_inpad(ctx, INPUT_MAIN, &pad); + if ((ret = ff_insert_inpad(ctx, INPUT_MAIN, &pad)) < 0) { + av_freep(&pad.name); + return ret; + } if (dm->ppsrc) { pad.name = av_strdup("clean_src"); pad.config_props = NULL; if (!pad.name) return AVERROR(ENOMEM); - ff_insert_inpad(ctx, INPUT_CLEANSRC, &pad); + if ((ret = ff_insert_inpad(ctx, INPUT_CLEANSRC, &pad)) < 0) { + av_freep(&pad.name); + return ret; + } } if ((dm->blockx & (dm->blockx - 1)) || From 5e706a2afb09009bad49c4b12aaa997acf4491b1 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Fri, 25 Aug 2017 10:27:19 +0200 Subject: [PATCH 2842/3374] avfilter/split: check ff_insert_outpad() for failure Signed-off-by: Paul B Mahol --- libavfilter/split.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libavfilter/split.c b/libavfilter/split.c index b85a22135301c..8b260a9ba3371 100644 --- a/libavfilter/split.c +++ b/libavfilter/split.c @@ -47,7 +47,7 @@ typedef struct SplitContext { static av_cold int split_init(AVFilterContext *ctx) { SplitContext *s = ctx->priv; - int i; + int i, ret; for (i = 0; i < s->nb_outputs; i++) { char name[32]; @@ -59,7 +59,10 @@ static av_cold int split_init(AVFilterContext *ctx) if (!pad.name) return AVERROR(ENOMEM); - ff_insert_outpad(ctx, i, &pad); + if ((ret = ff_insert_outpad(ctx, i, &pad)) < 0) { + av_freep(&pad.name); + return ret; + } } return 0; From 48ddd8ddec3587453dffcfaa4130698d99228937 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Fri, 25 Aug 2017 10:29:50 +0200 Subject: [PATCH 2843/3374] avfilter/src_movie: check ff_insert_outpad() for failure Signed-off-by: Paul B Mahol --- libavfilter/src_movie.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavfilter/src_movie.c b/libavfilter/src_movie.c index a0dd66ea76929..258ba504a5717 100644 --- a/libavfilter/src_movie.c +++ b/libavfilter/src_movie.c @@ -313,7 +313,10 @@ static av_cold int movie_common_init(AVFilterContext *ctx) return AVERROR(ENOMEM); pad.config_props = movie_config_output_props; pad.request_frame = movie_request_frame; - ff_insert_outpad(ctx, i, &pad); + if ((ret = ff_insert_outpad(ctx, i, &pad)) < 0) { + av_freep(&pad.name); + return ret; + } if ( movie->st[i].st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && !movie->st[i].st->codecpar->channel_layout) { ret = guess_channel_layout(&movie->st[i], i, ctx); From 3ddd10290afb88ffbb25d15863076002cfca4827 Mon Sep 17 00:00:00 2001 From: Muhammad Faiz Date: Fri, 25 Aug 2017 17:36:04 +0700 Subject: [PATCH 2844/3374] avfilter/af_firequalizer: fix minval on cepstrum calculation The impulse response is scaled with 2/rdft_len. Signed-off-by: Muhammad Faiz --- libavfilter/af_firequalizer.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libavfilter/af_firequalizer.c b/libavfilter/af_firequalizer.c index 2b6245c698cd7..00ddc8734125d 100644 --- a/libavfilter/af_firequalizer.c +++ b/libavfilter/af_firequalizer.c @@ -554,6 +554,7 @@ static void generate_min_phase_kernel(FIREqualizerContext *s, float *rdft_buf) { int k, cepstrum_len = s->cepstrum_len, rdft_len = s->rdft_len; double norm = 2.0 / cepstrum_len; + double minval = 1e-7 / rdft_len; memset(s->cepstrum_buf, 0, cepstrum_len * sizeof(*s->cepstrum_buf)); memcpy(s->cepstrum_buf, rdft_buf, rdft_len/2 * sizeof(*rdft_buf)); @@ -561,11 +562,11 @@ static void generate_min_phase_kernel(FIREqualizerContext *s, float *rdft_buf) av_rdft_calc(s->cepstrum_rdft, s->cepstrum_buf); - s->cepstrum_buf[0] = log(FFMAX(s->cepstrum_buf[0], 1e-10)); - s->cepstrum_buf[1] = log(FFMAX(s->cepstrum_buf[1], 1e-10)); + s->cepstrum_buf[0] = log(FFMAX(s->cepstrum_buf[0], minval)); + s->cepstrum_buf[1] = log(FFMAX(s->cepstrum_buf[1], minval)); for (k = 2; k < cepstrum_len; k += 2) { - s->cepstrum_buf[k] = log(FFMAX(s->cepstrum_buf[k], 1e-10)); + s->cepstrum_buf[k] = log(FFMAX(s->cepstrum_buf[k], minval)); s->cepstrum_buf[k+1] = 0; } From 71907f25093966301770df11e61c7a0c76d6ac5e Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Fri, 25 Aug 2017 14:27:21 +0200 Subject: [PATCH 2845/3374] doc/filters: add pseudocolor example Signed-off-by: Paul B Mahol --- doc/filters.texi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/filters.texi b/doc/filters.texi index bc618a8eb91e6..fb56c1654a2bb 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -11833,6 +11833,16 @@ The maximum allowed component value. All expressions default to "val". +@subsection Examples + +@itemize +@item +Change too high luma values to gradient: +@example +pseudocolor='if(between(val,ymax,amax),lerp(ymin,ymax,(val-ymax)/(amax-ymax)),-1):if(between(val,ymax,amax),lerp(umax,umin,(val-ymax)/(amax-ymax)),-1):if(between(val,ymax,amax),lerp(vmin,vmax,(val-ymax)/(amax-ymax)),-1):-1' +@end example +@end itemize + @section psnr Obtain the average, maximum and minimum PSNR (Peak Signal to Noise From 9e02f35f6a1b27090fa2679e9a3897ecdf144b2a Mon Sep 17 00:00:00 2001 From: Derek Buitenhuis Date: Wed, 23 Aug 2017 17:08:44 +0100 Subject: [PATCH 2846/3374] mjpeg: Add support for ICC side data JPEGs store embedded profiles under the APP2 marker, signified with a "ICC_PROFILE" null-terminated string header, and can be split across multiple APP2 markers, out of order. Signed-off-by: Derek Buitenhuis --- libavcodec/mjpegdec.c | 109 ++++++++++++++++++++++++++++++++++++++++++ libavcodec/mjpegdec.h | 5 ++ 2 files changed, 114 insertions(+) diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 387ceadf559c4..5b2409755cb32 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -1901,6 +1901,72 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) } } + if (s->start_code == APP2 && id == AV_RB32("ICC_") && len >= 10) { + int id2; + unsigned seqno; + unsigned nummarkers; + + id = get_bits_long(&s->gb, 32); + id2 = get_bits_long(&s->gb, 24); + len -= 7; + if (id != AV_RB32("PROF") || id2 != AV_RB24("ILE")) { + av_log(s->avctx, AV_LOG_WARNING, "Invalid ICC_PROFILE header in APP2\n"); + goto out; + } + + skip_bits(&s->gb, 8); + seqno = get_bits(&s->gb, 8); + len -= 2; + if (seqno == 0) { + av_log(s->avctx, AV_LOG_WARNING, "Invalid sequence number in APP2\n"); + goto out; + } + + nummarkers = get_bits(&s->gb, 8); + len -= 1; + if (nummarkers == 0) { + av_log(s->avctx, AV_LOG_WARNING, "Invalid number of markers coded in APP2\n"); + goto out; + } else if (s->iccnum != 0 && nummarkers != s->iccnum) { + av_log(s->avctx, AV_LOG_WARNING, "Mistmatch in coded number of ICC markers between markers\n"); + goto out; + } else if (seqno > nummarkers) { + av_log(s->avctx, AV_LOG_WARNING, "Mismatching sequence number and coded number of ICC markers\n"); + goto out; + } + + /* Allocate if this is the first APP2 we've seen. */ + if (s->iccnum == 0) { + s->iccdata = av_mallocz(nummarkers * sizeof(*(s->iccdata))); + s->iccdatalens = av_mallocz(nummarkers * sizeof(*(s->iccdatalens))); + if (!s->iccdata || !s->iccdatalens) { + av_log(s->avctx, AV_LOG_ERROR, "Could not allocate ICC data arrays\n"); + return AVERROR(ENOMEM); + } + s->iccnum = nummarkers; + } + + if (s->iccdata[seqno - 1]) { + av_log(s->avctx, AV_LOG_WARNING, "Duplicate ICC sequence number\n"); + goto out; + } + + s->iccdatalens[seqno - 1] = len; + s->iccdata[seqno - 1] = av_malloc(len); + if (!s->iccdata[seqno - 1]) { + av_log(s->avctx, AV_LOG_ERROR, "Could not allocate ICC data buffer\n"); + return AVERROR(ENOMEM); + } + + memcpy(s->iccdata[seqno - 1], align_get_bits(&s->gb), len); + skip_bits(&s->gb, len << 3); + len = 0; + s->iccread++; + + if (s->iccread > s->iccnum) + av_log(s->avctx, AV_LOG_WARNING, "Read more ICC markers than are supposed to be coded\n"); + } + out: /* slow but needed for extreme adobe jpegs */ if (len < 0) @@ -2097,6 +2163,20 @@ int ff_mjpeg_find_marker(MJpegDecodeContext *s, return start_code; } +static void reset_icc_profile(MJpegDecodeContext *s) +{ + int i; + + if (s->iccdata) + for (i = 0; i < s->iccnum; i++) + av_freep(&s->iccdata[i]); + av_freep(&s->iccdata); + av_freep(&s->iccdatalens); + + s->iccread = 0; + s->iccnum = 0; +} + int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { @@ -2117,6 +2197,9 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, av_freep(&s->stereo3d); s->adobe_transform = -1; + if (s->iccnum != 0) + reset_icc_profile(s); + buf_ptr = buf; buf_end = buf + buf_size; while (buf_ptr < buf_end) { @@ -2509,6 +2592,29 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, av_freep(&s->stereo3d); } + if (s->iccnum != 0 && s->iccnum == s->iccread) { + AVFrameSideData *sd; + size_t offset = 0; + int total_size = 0; + int i; + + /* Sum size of all parts. */ + for (i = 0; i < s->iccnum; i++) + total_size += s->iccdatalens[i]; + + sd = av_frame_new_side_data(data, AV_FRAME_DATA_ICC_PROFILE, total_size); + if (!sd) { + av_log(s->avctx, AV_LOG_ERROR, "Could not allocate frame side data\n"); + return AVERROR(ENOMEM); + } + + /* Reassemble the parts, which are now in-order. */ + for (i = 0; i < s->iccnum; i++) { + memcpy(sd->data + offset, s->iccdata[i], s->iccdatalens[i]); + offset += s->iccdatalens[i]; + } + } + av_dict_copy(&((AVFrame *) data)->metadata, s->exif_metadata, 0); av_dict_free(&s->exif_metadata); @@ -2548,6 +2654,9 @@ av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx) av_freep(&s->last_nnz[i]); } av_dict_free(&s->exif_metadata); + + reset_icc_profile(s); + return 0; } diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h index 024cedcb5ad69..2bc69fa93066b 100644 --- a/libavcodec/mjpegdec.h +++ b/libavcodec/mjpegdec.h @@ -130,6 +130,11 @@ typedef struct MJpegDecodeContext { AVStereo3D *stereo3d; ///!< stereoscopic information (cached, since it is read before frame allocation) const AVPixFmtDescriptor *pix_desc; + + uint8_t **iccdata; + int *iccdatalens; + int iccnum; + int iccread; } MJpegDecodeContext; int ff_mjpeg_decode_init(AVCodecContext *avctx); From add7b3bc3fb7685cd0a3ccffd2b09cc0e32c39ec Mon Sep 17 00:00:00 2001 From: Derek Buitenhuis Date: Thu, 24 Aug 2017 21:00:01 +0100 Subject: [PATCH 2847/3374] utils: Do not expand a macro with 'defined' in it Fixes: libswscale/utils.c:1632:5: warning: macro expansion producing 'defined' has undefined behavior [-Wexpansion-to-defined] #if USE_MMAP ^ libswscale/utils.c:1577:49: note: expanded from macro 'USE_MMAP' #define USE_MMAP (HAVE_MMAP && HAVE_MPROTECT && defined MAP_ANONYMOUS) ^ Signed-off-by: Derek Buitenhuis --- libswscale/utils.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libswscale/utils.c b/libswscale/utils.c index b75510d206ae3..dcab707de64bb 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -1574,7 +1574,11 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, } } -#define USE_MMAP (HAVE_MMAP && HAVE_MPROTECT && defined MAP_ANONYMOUS) +#if HAVE_MMAP && HAVE_MPROTECT && defined(MAP_ANONYMOUS) +#define USE_MMAP 1 +#else +#define USE_MMAP 0 +#endif /* precalculate horizontal scaler filter coefficients */ { From 2c800eb7375c65ffd56164b03bb035bdb3f1e172 Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 25 Aug 2017 12:09:26 -0300 Subject: [PATCH 2848/3374] avcodec: make the avcodec_get_chroma_sub_sample deprecation effective Reviewed-by: Ronald S. Bultje --- libavcodec/avcodec.h | 16 ++++------------ libavcodec/version.h | 6 +++--- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index c59499376693c..655555092ae88 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -5665,22 +5665,14 @@ int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, * @{ */ +#if FF_API_GETCHROMA /** - * Utility function to access log2_chroma_w log2_chroma_h from - * the pixel format AVPixFmtDescriptor. - * - * This function asserts that pix_fmt is valid. See av_pix_fmt_get_chroma_sub_sample - * for one that returns a failure code and continues in case of invalid - * pix_fmts. - * - * @param[in] pix_fmt the pixel format - * @param[out] h_shift store log2_chroma_w - * @param[out] v_shift store log2_chroma_h - * - * @see av_pix_fmt_get_chroma_sub_sample + * @deprecated Use av_pix_fmt_get_chroma_sub_sample */ +attribute_deprecated void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift); +#endif /** * Return a value representing the fourCC code associated to the diff --git a/libavcodec/version.h b/libavcodec/version.h index 74730005793e0..48e57bd86b4fc 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -60,9 +60,6 @@ #ifndef FF_API_AVCODEC_RESAMPLE #define FF_API_AVCODEC_RESAMPLE FF_API_AUDIO_CONVERT #endif -#ifndef FF_API_GETCHROMA -#define FF_API_GETCHROMA (LIBAVCODEC_VERSION_MAJOR < 58) -#endif #ifndef FF_API_MISSING_SAMPLE #define FF_API_MISSING_SAMPLE (LIBAVCODEC_VERSION_MAJOR < 58) #endif @@ -238,6 +235,9 @@ #ifndef FF_API_TAG_STRING #define FF_API_TAG_STRING (LIBAVCODEC_VERSION_MAJOR < 59) #endif +#ifndef FF_API_GETCHROMA +#define FF_API_GETCHROMA (LIBAVCODEC_VERSION_MAJOR < 59) +#endif #endif /* AVCODEC_VERSION_H */ From 8a0954dd51ca5c8f8e1c6d2c2d0961ae24055814 Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 25 Aug 2017 13:44:52 -0300 Subject: [PATCH 2849/3374] avcodec: add missing FF_API_DEBUG_MV wrappers Signed-off-by: James Almer --- ffmpeg.c | 6 +++++- libavcodec/mpegpicture.c | 5 ++++- libavcodec/mpegvideo.c | 2 ++ libavcodec/options_table.h | 2 ++ libavcodec/pthread_frame.c | 2 ++ 5 files changed, 15 insertions(+), 2 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index 888d19a647f9f..ccb6638e0a414 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -3928,7 +3928,11 @@ static int check_keyboard_interaction(int64_t cur_time) if(key == 'D') { debug = input_streams[0]->st->codec->debug<<1; if(!debug) debug = 1; - while(debug & (FF_DEBUG_DCT_COEFF|FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) //unsupported, would just crash + while(debug & (FF_DEBUG_DCT_COEFF +#if FF_API_DEBUG_MV + |FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE +#endif + )) //unsupported, would just crash debug += debug; }else{ char buf[32]; diff --git a/libavcodec/mpegpicture.c b/libavcodec/mpegpicture.c index 302f9d20d3706..53fb35b4bdb49 100644 --- a/libavcodec/mpegpicture.c +++ b/libavcodec/mpegpicture.c @@ -202,7 +202,10 @@ static int alloc_picture_tables(AVCodecContext *avctx, Picture *pic, int encodin return AVERROR(ENOMEM); } - if (out_format == FMT_H263 || encoding || avctx->debug_mv || + if (out_format == FMT_H263 || encoding || +#if FF_API_DEBUG_MV + avctx->debug_mv || +#endif (avctx->flags2 & AV_CODEC_FLAG2_EXPORT_MVS)) { int mv_size = 2 * (b8_array_size + 4) * sizeof(int16_t); int ref_index_size = 4 * mb_array_size; diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index e29558b3a288a..82b94253aeee0 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -1743,6 +1743,7 @@ void ff_print_debug_info2(AVCodecContext *avctx, AVFrame *pict, uint8_t *mbskip_ } } +#if FF_API_DEBUG_MV if ((avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) || (avctx->debug_mv)) { int mb_y; @@ -1956,6 +1957,7 @@ void ff_print_debug_info2(AVCodecContext *avctx, AVFrame *pict, uint8_t *mbskip_ } } } +#endif } void ff_print_debug_info(MpegEncContext *s, Picture *p, AVFrame *pict) diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index 57a098e76e7a9..12712fb54192f 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -275,8 +275,10 @@ static const AVOption avcodec_options[] = { {"er", "error recognition", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_ER }, INT_MIN, INT_MAX, V|D, "debug"}, {"mmco", "memory management control operations (H.264)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MMCO }, INT_MIN, INT_MAX, V|D, "debug"}, {"bugs", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUGS }, INT_MIN, INT_MAX, V|D, "debug"}, +#if FF_API_DEBUG_MV {"vis_qp", "visualize quantization parameter (QP), lower QP are tinted greener", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_QP }, INT_MIN, INT_MAX, V|D, "debug"}, {"vis_mb_type", "visualize block types", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"}, +#endif {"buffers", "picture buffer allocations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUFFERS }, INT_MIN, INT_MAX, V|D, "debug"}, {"thread_ops", "threading operations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_THREADS }, INT_MIN, INT_MAX, V|A|D, "debug"}, {"nomc", "skip motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_NOMC }, INT_MIN, INT_MAX, V|A|D, "debug"}, diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 08e182c3d19c7..2c702c7372189 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -739,8 +739,10 @@ int ff_frame_thread_init(AVCodecContext *avctx) if (!thread_count) { int nb_cpus = av_cpu_count(); +#if FF_API_DEBUG_MV if ((avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) || avctx->debug_mv) nb_cpus = 1; +#endif // use number of cores + 1 as thread count if there is more than one if (nb_cpus > 1) thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS); From 7c10068da10aa288195f5eb5d7e34eb2d8ff7447 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 22 Aug 2017 03:31:49 +0200 Subject: [PATCH 2850/3374] avcodec/dvbsubdec: Check for duplicate regions in dvbsub_parse_page_segment() Fixes: OOM Fixes: 3051/clusterfuzz-testcase-minimized-5745818336231424 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/dvbsubdec.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c index 98619f9631a57..b683109643cf9 100644 --- a/libavcodec/dvbsubdec.c +++ b/libavcodec/dvbsubdec.c @@ -1302,6 +1302,15 @@ static int dvbsub_parse_page_segment(AVCodecContext *avctx, region_id = *buf++; buf += 1; + display = ctx->display_list; + while (display && display->region_id != region_id) { + display = display->next; + } + if (display) { + av_log(avctx, AV_LOG_ERROR, "duplicate region\n"); + break; + } + display = tmp_display_list; tmp_ptr = &tmp_display_list; From e0436ddaa49699fd3842ca36a9524bf31b55cfed Mon Sep 17 00:00:00 2001 From: pkviet Date: Tue, 22 Aug 2017 11:30:45 +0200 Subject: [PATCH 2851/3374] ffmpeg options: Enable trailing ? for map_channel The -map option allows for a trailing ? so that an error is not thrown if the input stream does not exist. This capability is extended to the map_channel option. This allows a ffmpeg command not to break if an input channel does not exist, which can be of use (for instance, scripts processing audio channels with sources having unset number of audio channels). Signed-off-by: Michael Niedermayer --- doc/ffmpeg.texi | 13 ++++++++++- ffmpeg_opt.c | 23 ++++++++++++++++--- tests/fate/ffmpeg.mak | 8 +++++++ .../fate/mapchan-2ch-extract-ch0-ch2-trailing | 1 + .../fate/mapchan-3ch-extract-ch0-ch2-trailing | 1 + 5 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 tests/ref/fate/mapchan-2ch-extract-ch0-ch2-trailing create mode 100644 tests/ref/fate/mapchan-3ch-extract-ch0-ch2-trailing diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index 4616a4239e71c..de6d3f139a663 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -996,7 +996,7 @@ such streams is attempted. Allow input streams with unknown type to be copied instead of failing if copying such streams is attempted. -@item -map_channel [@var{input_file_id}.@var{stream_specifier}.@var{channel_id}|-1][:@var{output_file_id}.@var{stream_specifier}] +@item -map_channel [@var{input_file_id}.@var{stream_specifier}.@var{channel_id}|-1][?][:@var{output_file_id}.@var{stream_specifier}] Map an audio channel from a given input to an output. If @var{output_file_id}.@var{stream_specifier} is not set, the audio channel will be mapped on all the audio streams. @@ -1005,6 +1005,10 @@ Using "-1" instead of @var{input_file_id}.@var{stream_specifier}.@var{channel_id} will map a muted channel. +A trailing @code{?} will allow the map_channel to be +optional: if the map_channel matches no channel the map_channel will be ignored instead +of failing. + For example, assuming @var{INPUT} is a stereo audio file, you can switch the two audio channels with the following command: @example @@ -1052,6 +1056,13 @@ video stream), you can use the following command: ffmpeg -i input.mkv -filter_complex "[0:1] [0:2] amerge" -c:a pcm_s16le -c:v copy output.mkv @end example +To map the first two audio channels from the first input, and using the +trailing @code{?}, ignore the audio channel mapping if the first input is +mono instead of stereo: +@example +ffmpeg -i INPUT -map_channel 0.0.0 -map_channel 0.0.1? OUTPUT +@end example + @item -map_metadata[:@var{metadata_spec_out}] @var{infile}[:@var{metadata_spec_in}] (@emph{output,per-metadata}) Set metadata information of the next output file from @var{infile}. Note that those are file indices (zero-based), not filenames. diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c index 1c4a11ef214c1..f275f711be070 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -405,6 +405,11 @@ static int opt_map_channel(void *optctx, const char *opt, const char *arg) int n; AVStream *st; AudioChannelMap *m; + char *allow_unused; + char *mapchan; + mapchan = av_strdup(arg); + if (!mapchan) + return AVERROR(ENOMEM); GROW_ARRAY(o->audio_channel_maps, o->nb_audio_channel_maps); m = &o->audio_channel_maps[o->nb_audio_channel_maps - 1]; @@ -415,6 +420,7 @@ static int opt_map_channel(void *optctx, const char *opt, const char *arg) m->file_idx = m->stream_idx = -1; if (n == 1) m->ofile_idx = m->ostream_idx = -1; + av_free(mapchan); return 0; } @@ -450,11 +456,22 @@ static int opt_map_channel(void *optctx, const char *opt, const char *arg) m->file_idx, m->stream_idx); exit_program(1); } + /* allow trailing ? to map_channel */ + if (allow_unused = strchr(mapchan, '?')) + *allow_unused = 0; if (m->channel_idx < 0 || m->channel_idx >= st->codecpar->channels) { - av_log(NULL, AV_LOG_FATAL, "mapchan: invalid audio channel #%d.%d.%d\n", - m->file_idx, m->stream_idx, m->channel_idx); - exit_program(1); + if (allow_unused) { + av_log(NULL, AV_LOG_VERBOSE, "mapchan: invalid audio channel #%d.%d.%d\n", + m->file_idx, m->stream_idx, m->channel_idx); + } else { + av_log(NULL, AV_LOG_FATAL, "mapchan: invalid audio channel #%d.%d.%d\n" + "To ignore this, add a trailing '?' to the map_channel.\n", + m->file_idx, m->stream_idx, m->channel_idx); + exit_program(1); + } + } + av_free(mapchan); return 0; } diff --git a/tests/fate/ffmpeg.mak b/tests/fate/ffmpeg.mak index 0ec5a34921d9f..f3fbc841b2b36 100644 --- a/tests/fate/ffmpeg.mak +++ b/tests/fate/ffmpeg.mak @@ -10,6 +10,14 @@ FATE_MAPCHAN-$(CONFIG_CHANNELMAP_FILTER) += fate-mapchan-silent-mono fate-mapchan-silent-mono: tests/data/asynth-22050-1.wav fate-mapchan-silent-mono: CMD = md5 -i $(TARGET_PATH)/tests/data/asynth-22050-1.wav -map_channel -1 -map_channel 0.0.0 -fflags +bitexact -f wav +FATE_MAPCHAN-$(CONFIG_CHANNELMAP_FILTER) += fate-mapchan-2ch-extract-ch0-ch2-trailing +fate-mapchan-2ch-extract-ch0-ch2-trailing: tests/data/asynth-44100-2.wav +fate-mapchan-2ch-extract-ch0-ch2-trailing: CMD = md5 -i $(TARGET_PATH)/tests/data/asynth-44100-2.wav -map_channel 0.0.0 -map_channel 0.0.2? -fflags +bitexact -f wav + +FATE_MAPCHAN-$(CONFIG_CHANNELMAP_FILTER) += fate-mapchan-3ch-extract-ch0-ch2-trailing +fate-mapchan-3ch-extract-ch0-ch2-trailing: tests/data/asynth-44100-3.wav +fate-mapchan-3ch-extract-ch0-ch2-trailing: CMD = md5 -i $(TARGET_PATH)/tests/data/asynth-44100-3.wav -map_channel 0.0.0 -map_channel 0.0.2? -fflags +bitexact -f wav + FATE_MAPCHAN = $(FATE_MAPCHAN-yes) FATE_FFMPEG += $(FATE_MAPCHAN) diff --git a/tests/ref/fate/mapchan-2ch-extract-ch0-ch2-trailing b/tests/ref/fate/mapchan-2ch-extract-ch0-ch2-trailing new file mode 100644 index 0000000000000..a5400373cf741 --- /dev/null +++ b/tests/ref/fate/mapchan-2ch-extract-ch0-ch2-trailing @@ -0,0 +1 @@ +b6e1d142b4e484221562e7b66b9bbbdc diff --git a/tests/ref/fate/mapchan-3ch-extract-ch0-ch2-trailing b/tests/ref/fate/mapchan-3ch-extract-ch0-ch2-trailing new file mode 100644 index 0000000000000..6237a988be0fa --- /dev/null +++ b/tests/ref/fate/mapchan-3ch-extract-ch0-ch2-trailing @@ -0,0 +1 @@ +ae533985186cab287309c04f6b3e866c From 9d6aab6fa160f0b7528dafb741573b7d0de3b0eb Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sat, 26 Aug 2017 11:26:48 +0200 Subject: [PATCH 2852/3374] avfilter/af_surround: make volume configurable for front center and lfe channel --- doc/filters.texi | 12 ++++++++++++ libavfilter/af_surround.c | 40 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index fb56c1654a2bb..be12c18fcc85e 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -3927,6 +3927,18 @@ Set LFE low cut off frequency. By default, this is @var{128} Hz. @item lfe_high Set LFE high cut off frequency. By default, this is @var{256} Hz. + +@item fc_in +Set front center input volume. By default, this is @var{1}. + +@item fc_out +Set front center output volume. By default, this is @var{1}. + +@item lfe_in +Set LFE input volume. By default, this is @var{1}. + +@item lfe_out +Set LFE output volume. By default, this is @var{1}. @end table @section treble diff --git a/libavfilter/af_surround.c b/libavfilter/af_surround.c index 01449d557a198..c7122379d6049 100644 --- a/libavfilter/af_surround.c +++ b/libavfilter/af_surround.c @@ -31,8 +31,16 @@ typedef struct AudioSurroundContext { char *out_channel_layout_str; char *in_channel_layout_str; + float level_in; float level_out; + float fc_in; + float fc_out; + float lfe_in; + float lfe_out; + + float *input_levels; + float *output_levels; int output_lfe; int lowcutf; int highcutf; @@ -148,6 +156,17 @@ static int config_input(AVFilterLink *inlink) return AVERROR(ENOMEM); } s->nb_in_channels = inlink->channels; + s->input_levels = av_malloc_array(s->nb_in_channels, sizeof(*s->input_levels)); + if (!s->input_levels) + return AVERROR(ENOMEM); + for (ch = 0; ch < s->nb_in_channels; ch++) + s->input_levels[ch] = s->level_in; + ch = av_get_channel_layout_channel_index(inlink->channel_layout, AV_CH_FRONT_CENTER); + if (ch >= 0) + s->input_levels[ch] *= s->fc_in; + ch = av_get_channel_layout_channel_index(inlink->channel_layout, AV_CH_LOW_FREQUENCY); + if (ch >= 0) + s->input_levels[ch] *= s->lfe_in; s->input = ff_get_audio_buffer(inlink, s->buf_size * 2); if (!s->input) @@ -179,6 +198,17 @@ static int config_output(AVFilterLink *outlink) return AVERROR(ENOMEM); } s->nb_out_channels = outlink->channels; + s->output_levels = av_malloc_array(s->nb_out_channels, sizeof(*s->output_levels)); + if (!s->output_levels) + return AVERROR(ENOMEM); + for (ch = 0; ch < s->nb_out_channels; ch++) + s->output_levels[ch] = s->level_out; + ch = av_get_channel_layout_channel_index(outlink->channel_layout, AV_CH_FRONT_CENTER); + if (ch >= 0) + s->output_levels[ch] *= s->fc_out; + ch = av_get_channel_layout_channel_index(outlink->channel_layout, AV_CH_LOW_FREQUENCY); + if (ch >= 0) + s->output_levels[ch] *= s->lfe_out; s->output = ff_get_audio_buffer(outlink, s->buf_size * 2); s->overlap_buffer = ff_get_audio_buffer(outlink, s->buf_size * 2); @@ -1068,7 +1098,7 @@ static int init(AVFilterContext *ctx) static int fft_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs) { AudioSurroundContext *s = ctx->priv; - const float level_in = s->level_in; + const float level_in = s->input_levels[ch]; float *dst; int n; @@ -1087,7 +1117,7 @@ static int fft_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs) static int ifft_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs) { AudioSurroundContext *s = ctx->priv; - const float level_out = s->level_out; + const float level_out = s->output_levels[ch]; AVFrame *out = arg; float *dst, *ptr; int n; @@ -1173,6 +1203,8 @@ static av_cold void uninit(AVFilterContext *ctx) for (ch = 0; ch < s->nb_out_channels; ch++) { av_rdft_end(s->irdft[ch]); } + av_freep(&s->input_levels); + av_freep(&s->output_levels); av_freep(&s->rdft); av_freep(&s->irdft); av_audio_fifo_free(s->fifo); @@ -1190,6 +1222,10 @@ static const AVOption surround_options[] = { { "lfe", "output LFE", OFFSET(output_lfe), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS }, { "lfe_low", "LFE low cut off", OFFSET(lowcutf), AV_OPT_TYPE_INT, {.i64=128}, 0, 256, FLAGS }, { "lfe_high", "LFE high cut off", OFFSET(highcutf), AV_OPT_TYPE_INT, {.i64=256}, 0, 512, FLAGS }, + { "fc_in", "set front center channel input level", OFFSET(fc_in), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS }, + { "fc_out", "set front center channel output level", OFFSET(fc_out), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS }, + { "lfe_in", "set lfe channel input level", OFFSET(lfe_in), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS }, + { "lfe_out", "set lfe channel output level", OFFSET(lfe_out), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS }, { NULL } }; From 9d494c5e553fe3430df2fde0c456a723ae15f4ab Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Sat, 26 Aug 2017 11:43:09 +0200 Subject: [PATCH 2853/3374] lavf/rawenc: Add little- and big-endian G.726 muxers. --- Changelog | 2 +- libavformat/Makefile | 6 ++++-- libavformat/allformats.c | 4 ++-- libavformat/rawenc.c | 24 ++++++++++++++++++++++++ libavformat/version.h | 2 +- 5 files changed, 32 insertions(+), 6 deletions(-) diff --git a/Changelog b/Changelog index f5dc1da9e0e8b..4eba31e1b651c 100644 --- a/Changelog +++ b/Changelog @@ -33,7 +33,7 @@ version : - tlut2 video filter - floodfill video filter - pseudocolor video filter -- raw G.726 demuxer, left- and right-justified +- raw G.726 muxer and demuxer, left- and right-justified version 3.3: - CrystalHD decoder moved to new decode API diff --git a/libavformat/Makefile b/libavformat/Makefile index 8e2afb76fd6cd..f2b465cfa2b95 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -188,11 +188,13 @@ OBJS-$(CONFIG_GSM_MUXER) += rawenc.o OBJS-$(CONFIG_GXF_DEMUXER) += gxf.o OBJS-$(CONFIG_GXF_MUXER) += gxfenc.o audiointerleave.o OBJS-$(CONFIG_G722_DEMUXER) += g722.o rawdec.o -OBJS-$(CONFIG_G726_DEMUXER) += g726.o -OBJS-$(CONFIG_G726LE_DEMUXER) += g726.o OBJS-$(CONFIG_G722_MUXER) += rawenc.o OBJS-$(CONFIG_G723_1_DEMUXER) += g723_1.o OBJS-$(CONFIG_G723_1_MUXER) += rawenc.o +OBJS-$(CONFIG_G726_DEMUXER) += g726.o +OBJS-$(CONFIG_G726_MUXER) += rawenc.o +OBJS-$(CONFIG_G726LE_DEMUXER) += g726.o +OBJS-$(CONFIG_G726LE_MUXER) += rawenc.o OBJS-$(CONFIG_G729_DEMUXER) += g729dec.o OBJS-$(CONFIG_GDV_DEMUXER) += gdv.o OBJS-$(CONFIG_GENH_DEMUXER) += genh.o diff --git a/libavformat/allformats.c b/libavformat/allformats.c index 78ff2ebf293e3..cd8200ea1c9f0 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -132,9 +132,9 @@ static void register_all(void) REGISTER_DEMUXER (FRM, frm); REGISTER_DEMUXER (FSB, fsb); REGISTER_MUXDEMUX(G722, g722); - REGISTER_DEMUXER (G726, g726); - REGISTER_DEMUXER (G726LE, g726le); REGISTER_MUXDEMUX(G723_1, g723_1); + REGISTER_MUXDEMUX(G726, g726); + REGISTER_MUXDEMUX(G726LE, g726le); REGISTER_DEMUXER (G729, g729); REGISTER_DEMUXER (GDV, gdv); REGISTER_DEMUXER (GENH, genh); diff --git a/libavformat/rawenc.c b/libavformat/rawenc.c index 26baa850e1be6..f640121cb4698 100644 --- a/libavformat/rawenc.c +++ b/libavformat/rawenc.c @@ -196,6 +196,30 @@ AVOutputFormat ff_g723_1_muxer = { }; #endif +#if CONFIG_G726_MUXER +AVOutputFormat ff_g726_muxer = { + .name = "g726", + .long_name = NULL_IF_CONFIG_SMALL("raw big-endian G.726 (\"left-justified\")"), + .audio_codec = AV_CODEC_ID_ADPCM_G726, + .video_codec = AV_CODEC_ID_NONE, + .write_header = force_one_stream, + .write_packet = ff_raw_write_packet, + .flags = AVFMT_NOTIMESTAMPS, +}; +#endif + +#if CONFIG_G726LE_MUXER +AVOutputFormat ff_g726le_muxer = { + .name = "g726le", + .long_name = NULL_IF_CONFIG_SMALL("raw little-endian G.726 (\"right-justified\")"), + .audio_codec = AV_CODEC_ID_ADPCM_G726LE, + .video_codec = AV_CODEC_ID_NONE, + .write_header = force_one_stream, + .write_packet = ff_raw_write_packet, + .flags = AVFMT_NOTIMESTAMPS, +}; +#endif + #if CONFIG_GSM_MUXER AVOutputFormat ff_gsm_muxer = { .name = "gsm", diff --git a/libavformat/version.h b/libavformat/version.h index a8cf4c158ebd4..94081aca81caf 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ // 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 57 -#define LIBAVFORMAT_VERSION_MINOR 77 +#define LIBAVFORMAT_VERSION_MINOR 78 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ From 1c56becb9b04219a36692479c32319765980521b Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Sat, 26 Aug 2017 11:59:34 +0200 Subject: [PATCH 2854/3374] lavc/utils: Calculate frame duration for little-endian G.726. --- libavcodec/utils.c | 2 +- libavcodec/version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 1b8ad1d200b89..baf4992b197ca 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -1757,7 +1757,7 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba, if (bps > 0) { /* calc from frame_bytes and bits_per_coded_sample */ - if (id == AV_CODEC_ID_ADPCM_G726) + if (id == AV_CODEC_ID_ADPCM_G726 || id == AV_CODEC_ID_ADPCM_G726LE) return frame_bytes * 8 / bps; } diff --git a/libavcodec/version.h b/libavcodec/version.h index 48e57bd86b4fc..1db347a9f3ebf 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 103 -#define LIBAVCODEC_VERSION_MICRO 100 +#define LIBAVCODEC_VERSION_MICRO 101 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From 094d4d8691ab9ac27f3cdeb40098dd1591f03748 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Sat, 26 Aug 2017 12:48:43 +0200 Subject: [PATCH 2855/3374] lavc/sinewin_tablegen: Fix compilation with --enable-hardcoded-tables. Reported by irc user JCount_. --- libavcodec/sinewin_tablegen.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libavcodec/sinewin_tablegen.h b/libavcodec/sinewin_tablegen.h index 30c8cbf769a9b..0fa3561abce8b 100644 --- a/libavcodec/sinewin_tablegen.h +++ b/libavcodec/sinewin_tablegen.h @@ -31,14 +31,16 @@ #include "libavutil/attributes.h" #include "libavutil/common.h" +#if !USE_FIXED +SINETABLE( 120); +SINETABLE( 960); +#endif #if !CONFIG_HARDCODED_TABLES SINETABLE( 32); SINETABLE( 64); -SINETABLE( 120); SINETABLE( 128); SINETABLE( 256); SINETABLE( 512); -SINETABLE( 960); SINETABLE(1024); SINETABLE(2048); SINETABLE(4096); @@ -62,7 +64,6 @@ SINETABLE_CONST INTFLOAT * const AAC_RENAME(ff_sine_windows)[] = { AAC_RENAME(ff_sine_32) , AAC_RENAME(ff_sine_64), AAC_RENAME(ff_sine_128), AAC_RENAME(ff_sine_256), AAC_RENAME(ff_sine_512), AAC_RENAME(ff_sine_1024), AAC_RENAME(ff_sine_2048), AAC_RENAME(ff_sine_4096), AAC_RENAME(ff_sine_8192), - AAC_RENAME(ff_sine_120), AAC_RENAME(ff_sine_960), }; // Generate a sine window. From 473e18fdbabbedd7e73ca589aa1edd821599175c Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sat, 26 Aug 2017 15:18:33 +0200 Subject: [PATCH 2856/3374] doc/filters: improve pseudocolor example Signed-off-by: Paul B Mahol --- doc/filters.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/filters.texi b/doc/filters.texi index be12c18fcc85e..779fd533173a4 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -11851,7 +11851,7 @@ All expressions default to "val". @item Change too high luma values to gradient: @example -pseudocolor='if(between(val,ymax,amax),lerp(ymin,ymax,(val-ymax)/(amax-ymax)),-1):if(between(val,ymax,amax),lerp(umax,umin,(val-ymax)/(amax-ymax)),-1):if(between(val,ymax,amax),lerp(vmin,vmax,(val-ymax)/(amax-ymax)),-1):-1' +pseudocolor="'if(between(val,ymax,amax),lerp(ymin,ymax,(val-ymax)/(amax-ymax)),-1):if(between(val,ymax,amax),lerp(umax,umin,(val-ymax)/(amax-ymax)),-1):if(between(val,ymax,amax),lerp(vmin,vmax,(val-ymax)/(amax-ymax)),-1):-1'" @end example @end itemize From 15e9c4afdc8efbf8da86bb3f7eaf374310b44bf8 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sat, 26 Aug 2017 17:47:56 +0200 Subject: [PATCH 2857/3374] avfilter/af_amix: switch to activate Really fixes hangs and infinite loops. Signed-off-by: Paul B Mahol --- libavfilter/af_amix.c | 162 +++++++++++++++++++++--------------------- 1 file changed, 82 insertions(+), 80 deletions(-) diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c index 78be57ac3f9d0..b24ae319df7d4 100644 --- a/libavfilter/af_amix.c +++ b/libavfilter/af_amix.c @@ -41,6 +41,7 @@ #include "audio.h" #include "avfilter.h" +#include "filters.h" #include "formats.h" #include "internal.h" @@ -151,6 +152,7 @@ static int frame_list_add_frame(FrameList *frame_list, int nb_samples, int64_t p return 0; } +/* FIXME: use directly links fifo */ typedef struct MixContext { const AVClass *class; /**< class for AVOptions */ @@ -263,21 +265,15 @@ static int config_output(AVFilterLink *outlink) return 0; } -static int calc_active_inputs(MixContext *s); - /** * Read samples from the input FIFOs, mix, and write to the output link. */ -static int output_frame(AVFilterLink *outlink, int need_request) +static int output_frame(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; MixContext *s = ctx->priv; AVFrame *out_buf, *in_buf; - int nb_samples, ns, ret, i; - - ret = calc_active_inputs(s); - if (ret < 0) - return ret; + int nb_samples, ns, i; if (s->input_state[0] & INPUT_ON) { /* first input live: use the corresponding frame size */ @@ -288,7 +284,7 @@ static int output_frame(AVFilterLink *outlink, int need_request) if (ns < nb_samples) { if (!(s->input_state[i] & INPUT_EOF)) /* unclosed input with not enough samples */ - return need_request ? ff_request_frame(ctx->inputs[i]) : 0; + return 0; /* closed input to drain */ nb_samples = ns; } @@ -303,8 +299,10 @@ static int output_frame(AVFilterLink *outlink, int need_request) nb_samples = FFMIN(nb_samples, ns); } } - if (nb_samples == INT_MAX) - return AVERROR_EOF; + if (nb_samples == INT_MAX) { + ff_outlink_set_status(outlink, AVERROR_EOF, s->next_pts); + return 0; + } } s->next_pts = frame_list_next_pts(s->frame_list); @@ -367,27 +365,18 @@ static int output_frame(AVFilterLink *outlink, int need_request) static int request_samples(AVFilterContext *ctx, int min_samples) { MixContext *s = ctx->priv; - int i, ret; + int i; av_assert0(s->nb_inputs > 1); for (i = 1; i < s->nb_inputs; i++) { - ret = 0; if (!(s->input_state[i] & INPUT_ON)) continue; if (av_audio_fifo_size(s->fifos[i]) >= min_samples) continue; - ret = ff_request_frame(ctx->inputs[i]); - if (ret == AVERROR_EOF) { - s->input_state[i] |= INPUT_EOF; - if (av_audio_fifo_size(s->fifos[i]) == 0) { - s->input_state[i] = 0; - continue; - } - } else if (ret < 0) - return ret; + ff_inlink_request_frame(ctx->inputs[i]); } - return output_frame(ctx->outputs[0], 1); + return output_frame(ctx->outputs[0]); } /** @@ -411,73 +400,87 @@ static int calc_active_inputs(MixContext *s) return 0; } -static int request_frame(AVFilterLink *outlink) +static int activate(AVFilterContext *ctx) { - AVFilterContext *ctx = outlink->src; - MixContext *s = ctx->priv; - int ret; - int wanted_samples; - - ret = calc_active_inputs(s); - if (ret < 0) - return ret; - - if (!(s->input_state[0] & INPUT_ON)) - return request_samples(ctx, 1); - - if (s->frame_list->nb_frames == 0) { - ret = ff_request_frame(ctx->inputs[0]); - if (ret == AVERROR_EOF) { - s->input_state[0] = 0; - if (s->nb_inputs == 1) - return AVERROR_EOF; - return output_frame(ctx->outputs[0], 1); - } - return ret; - } - av_assert0(s->frame_list->nb_frames > 0); + AVFilterLink *outlink = ctx->outputs[0]; + MixContext *s = ctx->priv; + AVFrame *buf = NULL; + int i, ret; - wanted_samples = frame_list_next_frame_size(s->frame_list); + for (i = 0; i < s->nb_inputs; i++) { + AVFilterLink *inlink = ctx->inputs[i]; + + if ((ret = ff_inlink_consume_frame(ctx->inputs[i], &buf)) > 0) { + if (i == 0) { + int64_t pts = av_rescale_q(buf->pts, inlink->time_base, + outlink->time_base); + ret = frame_list_add_frame(s->frame_list, buf->nb_samples, pts); + if (ret < 0) { + av_frame_free(&buf); + return ret; + } + } - return request_samples(ctx, wanted_samples); -} + ret = av_audio_fifo_write(s->fifos[i], (void **)buf->extended_data, + buf->nb_samples); + if (ret < 0) { + av_frame_free(&buf); + return ret; + } -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) -{ - AVFilterContext *ctx = inlink->dst; - MixContext *s = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - int i, ret = 0; + av_frame_free(&buf); - for (i = 0; i < ctx->nb_inputs; i++) - if (ctx->inputs[i] == inlink) - break; - if (i >= ctx->nb_inputs) { - av_log(ctx, AV_LOG_ERROR, "unknown input link\n"); - ret = AVERROR(EINVAL); - goto fail; + ret = output_frame(outlink); + if (ret < 0) + return ret; + } } - if (i == 0) { - int64_t pts = av_rescale_q(buf->pts, inlink->time_base, - outlink->time_base); - ret = frame_list_add_frame(s->frame_list, buf->nb_samples, pts); - if (ret < 0) - goto fail; + for (i = 0; i < s->nb_inputs; i++) { + int64_t pts; + int status; + + if (ff_inlink_acknowledge_status(ctx->inputs[i], &status, &pts)) { + if (status == AVERROR_EOF) { + if (i == 0) { + s->input_state[i] = 0; + if (s->nb_inputs == 1) { + ff_outlink_set_status(outlink, status, pts); + return 0; + } + } else { + s->input_state[i] |= INPUT_EOF; + if (av_audio_fifo_size(s->fifos[i]) == 0) { + s->input_state[i] = 0; + } + } + } + } } - ret = av_audio_fifo_write(s->fifos[i], (void **)buf->extended_data, - buf->nb_samples); - if (ret < 0) - goto fail; + if (calc_active_inputs(s)) { + ff_outlink_set_status(outlink, AVERROR_EOF, s->next_pts); + return 0; + } - av_frame_free(&buf); - return output_frame(outlink, 0); + if (ff_outlink_frame_wanted(outlink)) { + int wanted_samples; -fail: - av_frame_free(&buf); + if (!(s->input_state[0] & INPUT_ON)) + return request_samples(ctx, 1); - return ret; + if (s->frame_list->nb_frames == 0) { + ff_inlink_request_frame(ctx->inputs[0]); + return 0; + } + av_assert0(s->frame_list->nb_frames > 0); + + wanted_samples = frame_list_next_frame_size(s->frame_list); + + return request_samples(ctx, wanted_samples); + } + + return 0; } static av_cold int init(AVFilterContext *ctx) @@ -494,7 +497,6 @@ static av_cold int init(AVFilterContext *ctx) pad.name = av_strdup(name); if (!pad.name) return AVERROR(ENOMEM); - pad.filter_frame = filter_frame; if ((ret = ff_insert_inpad(ctx, i, &pad)) < 0) { av_freep(&pad.name); @@ -562,7 +564,6 @@ static const AVFilterPad avfilter_af_amix_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_AUDIO, .config_props = config_output, - .request_frame = request_frame }, { NULL } }; @@ -574,6 +575,7 @@ AVFilter ff_af_amix = { .priv_class = &amix_class, .init = init, .uninit = uninit, + .activate = activate, .query_formats = query_formats, .inputs = NULL, .outputs = avfilter_af_amix_outputs, From 7f5c655833c5516b6ff1b276e380da847529e210 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sat, 26 Aug 2017 21:17:27 +0200 Subject: [PATCH 2858/3374] avfilter/af_amix: simplify const entries for duration in amix_options[] Signed-off-by: Paul B Mahol --- libavfilter/af_amix.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c index b24ae319df7d4..d11edaaec917d 100644 --- a/libavfilter/af_amix.c +++ b/libavfilter/af_amix.c @@ -182,9 +182,9 @@ static const AVOption amix_options[] = { OFFSET(nb_inputs), AV_OPT_TYPE_INT, { .i64 = 2 }, 1, 1024, A|F }, { "duration", "How to determine the end-of-stream.", OFFSET(duration_mode), AV_OPT_TYPE_INT, { .i64 = DURATION_LONGEST }, 0, 2, A|F, "duration" }, - { "longest", "Duration of longest input.", 0, AV_OPT_TYPE_CONST, { .i64 = DURATION_LONGEST }, INT_MIN, INT_MAX, A|F, "duration" }, - { "shortest", "Duration of shortest input.", 0, AV_OPT_TYPE_CONST, { .i64 = DURATION_SHORTEST }, INT_MIN, INT_MAX, A|F, "duration" }, - { "first", "Duration of first input.", 0, AV_OPT_TYPE_CONST, { .i64 = DURATION_FIRST }, INT_MIN, INT_MAX, A|F, "duration" }, + { "longest", "Duration of longest input.", 0, AV_OPT_TYPE_CONST, { .i64 = DURATION_LONGEST }, 0, 0, A|F, "duration" }, + { "shortest", "Duration of shortest input.", 0, AV_OPT_TYPE_CONST, { .i64 = DURATION_SHORTEST }, 0, 0, A|F, "duration" }, + { "first", "Duration of first input.", 0, AV_OPT_TYPE_CONST, { .i64 = DURATION_FIRST }, 0, 0, A|F, "duration" }, { "dropout_transition", "Transition time, in seconds, for volume " "renormalization when an input stream ends.", OFFSET(dropout_transition), AV_OPT_TYPE_FLOAT, { .dbl = 2.0 }, 0, INT_MAX, A|F }, From 435dd2ee4e0864fd2b5940370879047c71317d55 Mon Sep 17 00:00:00 2001 From: Martin Vignali Date: Sat, 26 Aug 2017 21:26:00 +0200 Subject: [PATCH 2859/3374] configure: add avx2 enabled log Signed-off-by: James Almer --- configure | 1 + 1 file changed, 1 insertion(+) diff --git a/configure b/configure index 7201941c36e59..05f6dcc99a9c1 100755 --- a/configure +++ b/configure @@ -6649,6 +6649,7 @@ if enabled x86; then echo "SSSE3 enabled ${ssse3-no}" echo "AESNI enabled ${aesni-no}" echo "AVX enabled ${avx-no}" + echo "AVX2 enabled ${avx2-no}" echo "XOP enabled ${xop-no}" echo "FMA3 enabled ${fma3-no}" echo "FMA4 enabled ${fma4-no}" From 257f0d09f7b40050aee9cede5778d4df938dfc86 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 26 Aug 2017 22:08:47 -0300 Subject: [PATCH 2860/3374] avcoec/snowenc: silence some deprecation warnings --- libavcodec/snowenc.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c index ca55914d9e313..e03877a96c676 100644 --- a/libavcodec/snowenc.c +++ b/libavcodec/snowenc.c @@ -1644,8 +1644,12 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, } ff_snow_frame_start(s); +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS av_frame_unref(avctx->coded_frame); ret = av_frame_ref(avctx->coded_frame, s->current_picture); +FF_ENABLE_DEPRECATION_WARNINGS +#endif if (ret < 0) return ret; @@ -1675,7 +1679,9 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, s->m.f_code=1; s->m.pict_type = pic->pict_type; #if FF_API_MOTION_EST +FF_DISABLE_DEPRECATION_WARNINGS s->m.me_method= s->avctx->me_method; +FF_ENABLE_DEPRECATION_WARNINGS #endif s->m.motion_est= s->motion_est; s->m.me.scene_change_score=0; @@ -1878,10 +1884,14 @@ FF_ENABLE_DEPRECATION_WARNINGS if(avctx->flags&AV_CODEC_FLAG_PASS1) ff_write_pass1_stats(&s->m); s->m.last_pict_type = s->m.pict_type; +#if FF_API_STAT_BITS +FF_DISABLE_DEPRECATION_WARNINGS avctx->frame_bits = s->m.frame_bits; avctx->mv_bits = s->m.mv_bits; avctx->misc_bits = s->m.misc_bits; avctx->p_tex_bits = s->m.p_tex_bits; +FF_ENABLE_DEPRECATION_WARNINGS +#endif emms_c(); From 99b6e68441ce49838ee424d2c3b659c92c01b368 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 27 Aug 2017 08:49:58 +0200 Subject: [PATCH 2861/3374] avfilter/af_amix: do not request samples if inlink reached EOF Signed-off-by: Paul B Mahol --- libavfilter/af_amix.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c index d11edaaec917d..09848e5d91a92 100644 --- a/libavfilter/af_amix.c +++ b/libavfilter/af_amix.c @@ -370,7 +370,8 @@ static int request_samples(AVFilterContext *ctx, int min_samples) av_assert0(s->nb_inputs > 1); for (i = 1; i < s->nb_inputs; i++) { - if (!(s->input_state[i] & INPUT_ON)) + if (!(s->input_state[i] & INPUT_ON) || + (s->input_state[i] & INPUT_EOF)) continue; if (av_audio_fifo_size(s->fifos[i]) >= min_samples) continue; From 2ce43274e39295e3965c51dcfaf802628a5929f9 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 27 Aug 2017 16:51:24 +0200 Subject: [PATCH 2862/3374] avfilter/vf_zoompan: switch to activate Fixes #5182. Signed-off-by: Paul B Mahol --- libavfilter/vf_zoompan.c | 152 +++++++++++++++++++-------------------- 1 file changed, 72 insertions(+), 80 deletions(-) diff --git a/libavfilter/vf_zoompan.c b/libavfilter/vf_zoompan.c index 53a0700e37a95..6998441419dd2 100644 --- a/libavfilter/vf_zoompan.c +++ b/libavfilter/vf_zoompan.c @@ -23,6 +23,7 @@ #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "avfilter.h" +#include "filters.h" #include "formats.h" #include "internal.h" #include "video.h" @@ -217,97 +218,91 @@ static int output_single_frame(AVFilterContext *ctx, AVFrame *in, double *var_va sws_freeContext(s->sws); s->sws = NULL; s->current_frame++; + + if (s->current_frame >= s->nb_frames) { + if (*dx != -1) + s->x = *dx; + if (*dy != -1) + s->y = *dy; + if (*zoom != -1) + s->prev_zoom = *zoom; + s->prev_nb_frames = s->nb_frames; + s->nb_frames = 0; + s->current_frame = 0; + av_frame_free(&s->in); + s->finished = 1; + } return ret; error: av_frame_free(&out); return ret; } -static int filter_frame(AVFilterLink *inlink, AVFrame *in) +static int activate(AVFilterContext *ctx) { - AVFilterContext *ctx = inlink->dst; - AVFilterLink *outlink = ctx->outputs[0]; ZPContext *s = ctx->priv; - double nb_frames; - int ret; - - av_assert0(s->in == NULL); - - s->finished = 0; - s->var_values[VAR_IN_W] = s->var_values[VAR_IW] = in->width; - s->var_values[VAR_IN_H] = s->var_values[VAR_IH] = in->height; - s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = s->w; - s->var_values[VAR_OUT_H] = s->var_values[VAR_OH] = s->h; - s->var_values[VAR_IN] = inlink->frame_count_out + 1; - s->var_values[VAR_ON] = outlink->frame_count_in + 1; - s->var_values[VAR_PX] = s->x; - s->var_values[VAR_PY] = s->y; - s->var_values[VAR_X] = 0; - s->var_values[VAR_Y] = 0; - s->var_values[VAR_PZOOM] = s->prev_zoom; - s->var_values[VAR_ZOOM] = 1; - s->var_values[VAR_PDURATION] = s->prev_nb_frames; - s->var_values[VAR_A] = (double) in->width / in->height; - s->var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ? - (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1; - s->var_values[VAR_DAR] = s->var_values[VAR_A] * s->var_values[VAR_SAR]; - s->var_values[VAR_HSUB] = 1 << s->desc->log2_chroma_w; - s->var_values[VAR_VSUB] = 1 << s->desc->log2_chroma_h; - - if ((ret = av_expr_parse_and_eval(&nb_frames, s->duration_expr_str, - var_names, s->var_values, - NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) { - av_frame_free(&in); - return ret; - } - - s->var_values[VAR_DURATION] = s->nb_frames = nb_frames; - s->in = in; - - return 0; -} + AVFilterLink *inlink = ctx->inputs[0]; + AVFilterLink *outlink = ctx->outputs[0]; + int status, ret = 0; + int64_t pts; -static int request_frame(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - ZPContext *s = ctx->priv; - AVFrame *in = s->in; - double zoom=-1, dx=-1, dy=-1; - int ret = -1; + if (s->in && ff_outlink_frame_wanted(outlink)) { + double zoom = -1, dx = -1, dy = -1; - if (in) { - ret = output_single_frame(ctx, in, s->var_values, s->current_frame, + ret = output_single_frame(ctx, s->in, s->var_values, s->current_frame, &zoom, &dx, &dy); if (ret < 0) - goto fail; + return ret; } - if (s->current_frame >= s->nb_frames) { - if (dx != -1) - s->x = dx; - if (dy != -1) - s->y = dy; - if (zoom != -1) - s->prev_zoom = zoom; - s->prev_nb_frames = s->nb_frames; - s->nb_frames = 0; - s->current_frame = 0; - av_frame_free(&s->in); - s->finished = 1; - ret = ff_request_frame(ctx->inputs[0]); + if (!s->in && (ret = ff_inlink_consume_frame(inlink, &s->in)) > 0) { + double zoom = -1, dx = -1, dy = -1, nb_frames; + + s->finished = 0; + s->var_values[VAR_IN_W] = s->var_values[VAR_IW] = s->in->width; + s->var_values[VAR_IN_H] = s->var_values[VAR_IH] = s->in->height; + s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = s->w; + s->var_values[VAR_OUT_H] = s->var_values[VAR_OH] = s->h; + s->var_values[VAR_IN] = inlink->frame_count_out + 1; + s->var_values[VAR_ON] = outlink->frame_count_in + 1; + s->var_values[VAR_PX] = s->x; + s->var_values[VAR_PY] = s->y; + s->var_values[VAR_X] = 0; + s->var_values[VAR_Y] = 0; + s->var_values[VAR_PZOOM] = s->prev_zoom; + s->var_values[VAR_ZOOM] = 1; + s->var_values[VAR_PDURATION] = s->prev_nb_frames; + s->var_values[VAR_A] = (double) s->in->width / s->in->height; + s->var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ? + (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1; + s->var_values[VAR_DAR] = s->var_values[VAR_A] * s->var_values[VAR_SAR]; + s->var_values[VAR_HSUB] = 1 << s->desc->log2_chroma_w; + s->var_values[VAR_VSUB] = 1 << s->desc->log2_chroma_h; + + if ((ret = av_expr_parse_and_eval(&nb_frames, s->duration_expr_str, + var_names, s->var_values, + NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) { + av_frame_free(&s->in); + return ret; + } + + s->var_values[VAR_DURATION] = s->nb_frames = nb_frames; + + ret = output_single_frame(ctx, s->in, s->var_values, s->current_frame, + &zoom, &dx, &dy); + if (ret < 0) + return ret; + } + if (ret < 0) { + return ret; + } else if (s->finished && ff_inlink_acknowledge_status(inlink, &status, &pts)) { + ff_outlink_set_status(outlink, status, pts); + return 0; + } else { + if (ff_outlink_frame_wanted(outlink) && s->finished) + ff_inlink_request_frame(inlink); + return 0; } - -fail: - sws_freeContext(s->sws); - s->sws = NULL; - - return ret; -} - -static int poll_frame(AVFilterLink *link) -{ - ZPContext *s = link->src->priv; - return s->nb_frames - s->current_frame; } static int query_formats(AVFilterContext *ctx) @@ -344,8 +339,6 @@ static const AVFilterPad inputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - .needs_fifo = 1, }, { NULL } }; @@ -355,8 +348,6 @@ static const AVFilterPad outputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_output, - .poll_frame = poll_frame, - .request_frame = request_frame, }, { NULL } }; @@ -369,6 +360,7 @@ AVFilter ff_vf_zoompan = { .init = init, .uninit = uninit, .query_formats = query_formats, + .activate = activate, .inputs = inputs, .outputs = outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, From bf39f7eadc684ab291a6f42ee9a85a6c2d804bc7 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 27 Aug 2017 17:11:40 +0200 Subject: [PATCH 2863/3374] avfilter/vf_zoompan: parse zoom,x and y expression during initialization Fixes #6127. Signed-off-by: Paul B Mahol --- libavfilter/vf_zoompan.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/libavfilter/vf_zoompan.c b/libavfilter/vf_zoompan.c index 6998441419dd2..08575182175a4 100644 --- a/libavfilter/vf_zoompan.c +++ b/libavfilter/vf_zoompan.c @@ -81,6 +81,9 @@ typedef struct ZPcontext { char *x_expr_str; char *y_expr_str; char *duration_expr_str; + + AVExpr *zoom_expr, *x_expr, *y_expr; + int w, h; double x, y; double prev_zoom; @@ -123,6 +126,7 @@ static int config_output(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; ZPContext *s = ctx->priv; + int ret; outlink->w = s->w; outlink->h = s->h; @@ -130,6 +134,18 @@ static int config_output(AVFilterLink *outlink) outlink->frame_rate = s->framerate; s->desc = av_pix_fmt_desc_get(outlink->format); + ret = av_expr_parse(&s->zoom_expr, s->zoom_expr_str, var_names, NULL, NULL, NULL, NULL, 0, ctx); + if (ret < 0) + return ret; + + ret = av_expr_parse(&s->x_expr, s->x_expr_str, var_names, NULL, NULL, NULL, NULL, 0, ctx); + if (ret < 0) + return ret; + + ret = av_expr_parse(&s->y_expr, s->y_expr_str, var_names, NULL, NULL, NULL, NULL, 0, ctx); + if (ret < 0) + return ret; + return 0; } @@ -151,28 +167,22 @@ static int output_single_frame(AVFilterContext *ctx, AVFrame *in, double *var_va var_values[VAR_TIME] = pts * av_q2d(outlink->time_base); var_values[VAR_FRAME] = i; var_values[VAR_ON] = outlink->frame_count_in + 1; - if ((ret = av_expr_parse_and_eval(zoom, s->zoom_expr_str, - var_names, var_values, - NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) - return ret; + + *zoom = av_expr_eval(s->zoom_expr, var_values, NULL); *zoom = av_clipd(*zoom, 1, 10); var_values[VAR_ZOOM] = *zoom; w = in->width * (1.0 / *zoom); h = in->height * (1.0 / *zoom); - if ((ret = av_expr_parse_and_eval(dx, s->x_expr_str, - var_names, var_values, - NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) - return ret; + *dx = av_expr_eval(s->x_expr, var_values, NULL); + x = *dx = av_clipd(*dx, 0, FFMAX(in->width - w, 0)); var_values[VAR_X] = *dx; x &= ~((1 << s->desc->log2_chroma_w) - 1); - if ((ret = av_expr_parse_and_eval(dy, s->y_expr_str, - var_names, var_values, - NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) - return ret; + *dy = av_expr_eval(s->y_expr, var_values, NULL); + y = *dy = av_clipd(*dy, 0, FFMAX(in->height - h, 0)); var_values[VAR_Y] = *dy; y &= ~((1 << s->desc->log2_chroma_h) - 1); From 76a8b5e7adbb3b94611c8a7207003711c4473a1f Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sun, 27 Aug 2017 17:55:02 +0200 Subject: [PATCH 2864/3374] avdevice/decklink_dec: fix signed and unsigned comparison warning Signed-off-by: Marton Balint --- libavdevice/decklink_dec.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index 64157b4c16fc4..c271ff3639157 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -234,7 +234,7 @@ static int avpacket_queue_put(AVPacketQueue *q, AVPacket *pkt) AVPacketList *pkt1; // Drop Packet if queue size is > maximum queue size - if (avpacket_queue_size(q) > q->max_q_size) { + if (avpacket_queue_size(q) > (uint64_t)q->max_q_size) { av_log(q->avctx, AV_LOG_WARNING, "Decklink input buffer overrun!\n"); return -1; } From 84ee6512ed70e4eeb37559e2ed1d830d198c8a15 Mon Sep 17 00:00:00 2001 From: pkviet Date: Sun, 2 Jul 2017 23:50:56 +0200 Subject: [PATCH 2865/3374] avdevice/decklink_enc: enable 16 output channel Decklink devices can output 2, 8 or 16 audio channels along video. The code was limited to 2 or 8 channels. The commit enables 16 audio channels (relevant for SDI outputs). Signed-off-by: Marton Balint --- libavdevice/decklink_enc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavdevice/decklink_enc.cpp b/libavdevice/decklink_enc.cpp index be01bcd64cb12..25ce7d026c2c1 100644 --- a/libavdevice/decklink_enc.cpp +++ b/libavdevice/decklink_enc.cpp @@ -172,9 +172,9 @@ static int decklink_setup_audio(AVFormatContext *avctx, AVStream *st) " Only 48kHz is supported.\n"); return -1; } - if (c->channels != 2 && c->channels != 8) { + if (c->channels != 2 && c->channels != 8 && c->channels != 16) { av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels!" - " Only stereo and 7.1 are supported.\n"); + " Only 2, 8 or 16 channels are supported.\n"); return -1; } if (ctx->dlo->EnableAudioOutput(bmdAudioSampleRate48kHz, From 2634927fe30ea4a821db515c6b7f77458f5c4bc5 Mon Sep 17 00:00:00 2001 From: Maksym Veremeyenko Date: Fri, 18 Aug 2017 09:34:06 -0400 Subject: [PATCH 2866/3374] lavd: implement NewTek NDI input/output device support Signed-off-by: Marton Balint --- Changelog | 1 + configure | 9 + doc/indevs.texi | 48 ++++ doc/outdevs.texi | 45 ++++ libavdevice/Makefile | 4 + libavdevice/alldevices.c | 1 + libavdevice/libndi_newtek_common.h | 30 +++ libavdevice/libndi_newtek_dec.c | 340 +++++++++++++++++++++++++++++ libavdevice/libndi_newtek_enc.c | 299 +++++++++++++++++++++++++ libavdevice/version.h | 4 +- 10 files changed, 779 insertions(+), 2 deletions(-) create mode 100644 libavdevice/libndi_newtek_common.h create mode 100644 libavdevice/libndi_newtek_dec.c create mode 100644 libavdevice/libndi_newtek_enc.c diff --git a/Changelog b/Changelog index 4eba31e1b651c..1dfb8b5714f81 100644 --- a/Changelog +++ b/Changelog @@ -34,6 +34,7 @@ version : - floodfill video filter - pseudocolor video filter - raw G.726 muxer and demuxer, left- and right-justified +- NewTek NDI input/output device version 3.3: - CrystalHD decoder moved to new decode API diff --git a/configure b/configure index 05f6dcc99a9c1..61d8160491392 100755 --- a/configure +++ b/configure @@ -277,6 +277,7 @@ External library support: --enable-libzvbi enable teletext support via libzvbi [no] --disable-lzma disable lzma [autodetect] --enable-decklink enable Blackmagic DeckLink I/O support [no] + --enable-libndi_newtek enable Newteck NDI I/O support [no] --enable-mediacodec enable Android MediaCodec support [no] --enable-libmysofa enable libmysofa, needed for sofalizer filter [no] --enable-openal enable OpenAL 1.1 capture support [no] @@ -1508,6 +1509,7 @@ EXTERNAL_LIBRARY_GPL_LIST=" EXTERNAL_LIBRARY_NONFREE_LIST=" decklink + libndi_newtek libfdk_aac openssl " @@ -3014,6 +3016,10 @@ decklink_indev_deps="decklink threads" decklink_indev_extralibs="-lstdc++" decklink_outdev_deps="decklink threads" decklink_outdev_extralibs="-lstdc++" +libndi_newtek_indev_deps="libndi_newtek" +libndi_newtek_indev_extralibs="-lndi" +libndi_newtek_outdev_deps="libndi_newtek" +libndi_newtek_outdev_extralibs="-lndi" dshow_indev_deps="IBaseFilter" dshow_indev_extralibs="-lpsapi -lole32 -lstrmiids -luuid -loleaut32 -lshlwapi" dv1394_indev_deps="dv1394" @@ -5567,6 +5573,8 @@ avisynth_demuxer_extralibs='$ldl' cuda_extralibs='$ldl' decklink_outdev_extralibs="$decklink_outdev_extralibs $ldl" decklink_indev_extralibs="$decklink_indev_extralibs $ldl" +libndi_newtek_outdev_extralibs="$libndi_newtek_outdev_extralibs $ldl" +libndi_newtek_indev_extralibs="$libndi_newtek_indev_extralibs $ldl" frei0r_filter_extralibs='$ldl' frei0r_src_filter_extralibs='$ldl' ladspa_filter_extralibs='$ldl' @@ -5825,6 +5833,7 @@ enabled coreimage_filter && { check_header_objcc QuartzCore/CoreImage.h || disa enabled coreimagesrc_filter && { check_header_objcc QuartzCore/CoreImage.h || disable coreimagesrc_filter; } enabled decklink && { { check_header DeckLinkAPI.h || die "ERROR: DeckLinkAPI.h header not found"; } && { check_cpp_condition DeckLinkAPIVersion.h "BLACKMAGIC_DECKLINK_API_VERSION >= 0x0a060100" || die "ERROR: Decklink API version must be >= 10.6.1."; } } +enabled libndi_newtek && { check_header Processing.NDI.Lib.h || die "ERROR: Processing.NDI.Lib.h header not found"; } enabled frei0r && { check_header frei0r.h || die "ERROR: frei0r.h header not found"; } enabled gmp && require gmp gmp.h mpz_export -lgmp enabled gnutls && require_pkg_config gnutls gnutls/gnutls.h gnutls_global_init diff --git a/doc/indevs.texi b/doc/indevs.texi index dc6cdb6deecd3..5423bed32f283 100644 --- a/doc/indevs.texi +++ b/doc/indevs.texi @@ -332,6 +332,54 @@ ffmpeg -channels 16 -format_code Hi50 -f decklink -i 'UltraStudio Mini Recorder' @end itemize +@section libndi_newtek + +The libndi_newtek input device provides capture capabilities for using NDI (Network +Device Interface, standard created by NewTek). + +Input filename is a NDI source name that could be found by sending -find_sources 1 +to command line - it has no specific syntax but human-readable formatted. + +To enable this input device, you need the NDI SDK and you +need to configure with the appropriate @code{--extra-cflags} +and @code{--extra-ldflags}. + +@subsection Options + +@table @option + +@item find_sources +If set to @option{true}, print a list of found/available NDI sources and exit. +Defaults to @option{false}. + +@item wait_sources +Override time to wait until the number of online sources have changed. +Defaults to @option{0.5}. + +@item allow_video_fields +When this flag is @option{false}, all video that you receive will be progressive. +Defaults to @option{true}. + +@end table + +@subsection Examples + +@itemize + +@item +List input devices: +@example +ffmpeg -f libndi_newtek -find_sources 1 -i dummy +@end example + +@item +Restream to NDI: +@example +ffmpeg -f libndi_newtek -i "DEV-5.INTERNAL.M1STEREO.TV (NDI_SOURCE_NAME_1)" -f libndi_newtek -y NDI_SOURCE_NAME_2 +@end example + +@end itemize + @section dshow Windows DirectShow input device. diff --git a/doc/outdevs.texi b/doc/outdevs.texi index df41cc868feba..0012b0f04ca70 100644 --- a/doc/outdevs.texi +++ b/doc/outdevs.texi @@ -182,6 +182,51 @@ ffmpeg -i test.avi -f decklink -pix_fmt uyvy422 -s 720x486 -r 24000/1001 'DeckLi @end itemize +@section libndi_newtek + +The libndi_newtek output device provides playback capabilities for using NDI (Network +Device Interface, standard created by NewTek). + +Output filename is a NDI name. + +To enable this output device, you need the NDI SDK and you +need to configure with the appropriate @code{--extra-cflags} +and @code{--extra-ldflags}. + +NDI uses uyvy422 pixel format natively, but also supports bgra, bgr0, rgba and +rgb0. + +@subsection Options + +@table @option + +@item reference_level +The audio reference level in dB. This specifies how many dB above the +reference level (+4dBU) is the full range of 16 bit audio. +Defaults to @option{0}. + +@item clock_video +These specify whether video "clock" themselves. +Defaults to @option{false}. + +@item clock_audio +These specify whether audio "clock" themselves. +Defaults to @option{false}. + +@end table + +@subsection Examples + +@itemize + +@item +Play video clip: +@example +ffmpeg -i "udp://@@239.1.1.1:10480?fifo_size=1000000&overrun_nonfatal=1" -vf "scale=720:576,fps=fps=25,setdar=dar=16/9,format=pix_fmts=uyvy422" -f libndi_newtek NEW_NDI1 +@end example + +@end itemize + @section fbdev Linux framebuffer output device. diff --git a/libavdevice/Makefile b/libavdevice/Makefile index 1d4e9e69fe22c..80afa61e36c47 100644 --- a/libavdevice/Makefile +++ b/libavdevice/Makefile @@ -19,6 +19,8 @@ OBJS-$(CONFIG_BKTR_INDEV) += bktr.o OBJS-$(CONFIG_CACA_OUTDEV) += caca.o OBJS-$(CONFIG_DECKLINK_OUTDEV) += decklink_enc.o decklink_enc_c.o decklink_common.o OBJS-$(CONFIG_DECKLINK_INDEV) += decklink_dec.o decklink_dec_c.o decklink_common.o +OBJS-$(CONFIG_LIBNDI_NEWTEK_OUTDEV) += libndi_newtek_enc.o +OBJS-$(CONFIG_LIBNDI_NEWTEK_INDEV) += libndi_newtek_dec.o OBJS-$(CONFIG_DSHOW_INDEV) += dshow_crossbar.o dshow.o dshow_enummediatypes.o \ dshow_enumpins.o dshow_filter.o \ dshow_pin.o dshow_common.o @@ -60,6 +62,8 @@ SLIBOBJS-$(HAVE_GNU_WINDRES) += avdeviceres.o SKIPHEADERS += decklink_common.h SKIPHEADERS-$(CONFIG_DECKLINK) += decklink_enc.h decklink_dec.h \ decklink_common_c.h +SKIPHEADERS-$(CONFIG_LIBNDI_NEWTEK_INDEV) += libndi_newtek_common.h +SKIPHEADERS-$(CONFIG_LIBNDI_NEWTEK_OUTDEV) += libndi_newtek_common.h SKIPHEADERS-$(CONFIG_DSHOW_INDEV) += dshow_capture.h SKIPHEADERS-$(CONFIG_FBDEV_INDEV) += fbdev_common.h SKIPHEADERS-$(CONFIG_FBDEV_OUTDEV) += fbdev_common.h diff --git a/libavdevice/alldevices.c b/libavdevice/alldevices.c index a8ed53ae5deb3..8d1cb8648f5e7 100644 --- a/libavdevice/alldevices.c +++ b/libavdevice/alldevices.c @@ -46,6 +46,7 @@ static void register_all(void) REGISTER_INDEV (BKTR, bktr); REGISTER_OUTDEV (CACA, caca); REGISTER_INOUTDEV(DECKLINK, decklink); + REGISTER_INOUTDEV(LIBNDI_NEWTEK, libndi_newtek); REGISTER_INDEV (DSHOW, dshow); REGISTER_INDEV (DV1394, dv1394); REGISTER_INOUTDEV(FBDEV, fbdev); diff --git a/libavdevice/libndi_newtek_common.h b/libavdevice/libndi_newtek_common.h new file mode 100644 index 0000000000000..899031707d190 --- /dev/null +++ b/libavdevice/libndi_newtek_common.h @@ -0,0 +1,30 @@ +/* + * NewTek NDI common code + * Copyright (c) 2017 Maksym Veremeyenko + * + * 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 + */ + +#ifndef AVDEVICE_LIBNDI_NEWTEK_COMMON_H +#define AVDEVICE_LIBNDI_NEWTEK_COMMON_H + +#include + +#define NDI_TIME_BASE 10000000 +#define NDI_TIME_BASE_Q (AVRational){1, NDI_TIME_BASE} + +#endif diff --git a/libavdevice/libndi_newtek_dec.c b/libavdevice/libndi_newtek_dec.c new file mode 100644 index 0000000000000..8cbcd9a1d2058 --- /dev/null +++ b/libavdevice/libndi_newtek_dec.c @@ -0,0 +1,340 @@ +/* + * Newtek NDI input + * Copyright (c) 2017 Maksym Veremeyenko + * + * 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 "libavformat/avformat.h" +#include "libavformat/internal.h" +#include "libavutil/opt.h" +#include "libavutil/imgutils.h" + +#include "libndi_newtek_common.h" + +struct NDIContext { + const AVClass *cclass; + + /* Options */ + int find_sources; + int64_t wait_sources; + int allow_video_fields; + + /* Runtime */ + NDIlib_recv_create_t *recv; + NDIlib_find_instance_t ndi_find; + + /* Streams */ + AVStream *video_st, *audio_st; +}; + +static int ndi_set_video_packet(AVFormatContext *avctx, NDIlib_video_frame_t *v, AVPacket *pkt) +{ + int ret; + struct NDIContext *ctx = avctx->priv_data; + + ret = av_new_packet(pkt, v->yres * v->line_stride_in_bytes); + if (ret < 0) + return ret; + + pkt->dts = pkt->pts = av_rescale_q(v->timecode, NDI_TIME_BASE_Q, ctx->video_st->time_base); + pkt->duration = av_rescale_q(1, (AVRational){v->frame_rate_D, v->frame_rate_N}, ctx->video_st->time_base); + + av_log(avctx, AV_LOG_DEBUG, "%s: pkt->dts = pkt->pts = %"PRId64", duration=%"PRId64", timecode=%"PRId64"\n", + __func__, pkt->dts, pkt->duration, v->timecode); + + pkt->flags |= AV_PKT_FLAG_KEY; + pkt->stream_index = ctx->video_st->index; + + memcpy(pkt->data, v->p_data, pkt->size); + + return 0; +} + +static int ndi_set_audio_packet(AVFormatContext *avctx, NDIlib_audio_frame_t *a, AVPacket *pkt) +{ + int ret; + struct NDIContext *ctx = avctx->priv_data; + + NDIlib_audio_frame_interleaved_16s_t dst; + + ret = av_new_packet(pkt, 2 * a->no_samples * a->no_channels); + if (ret < 0) + return ret; + + pkt->dts = pkt->pts = av_rescale_q(a->timecode, NDI_TIME_BASE_Q, ctx->audio_st->time_base); + pkt->duration = av_rescale_q(1, (AVRational){a->no_samples, a->sample_rate}, ctx->audio_st->time_base); + + av_log(avctx, AV_LOG_DEBUG, "%s: pkt->dts = pkt->pts = %"PRId64", duration=%"PRId64", timecode=%"PRId64"\n", + __func__, pkt->dts, pkt->duration, a->timecode); + + pkt->flags |= AV_PKT_FLAG_KEY; + pkt->stream_index = ctx->audio_st->index; + + dst.reference_level = 0; + dst.p_data = (short *)pkt->data; + NDIlib_util_audio_to_interleaved_16s(a, &dst); + + return 0; +} + +static int ndi_find_sources(AVFormatContext *avctx, const char *name, NDIlib_source_t *source_to_connect_to) +{ + int j = AVERROR(ENODEV); + unsigned int n, i; + struct NDIContext *ctx = avctx->priv_data; + const NDIlib_source_t *ndi_srcs = NULL; + const NDIlib_find_create_t find_create_desc = { .show_local_sources = true, + .p_groups = NULL, .p_extra_ips = NULL }; + + if (!ctx->ndi_find) + ctx->ndi_find = NDIlib_find_create2(&find_create_desc); + if (!ctx->ndi_find) { + av_log(avctx, AV_LOG_ERROR, "NDIlib_find_create failed.\n"); + return AVERROR(EIO); + } + + while (1) + { + int f, t = ctx->wait_sources / 1000; + av_log(avctx, AV_LOG_DEBUG, "Waiting for sources %d miliseconds\n", t); + f = NDIlib_find_wait_for_sources(ctx->ndi_find, t); + av_log(avctx, AV_LOG_DEBUG, "NDIlib_find_wait_for_sources returns %d\n", f); + if (!f) + break; + }; + + ndi_srcs = NDIlib_find_get_current_sources(ctx->ndi_find, &n); + + if (ctx->find_sources) + av_log(avctx, AV_LOG_INFO, "Found %d NDI sources:\n", n); + + for (i = 0; i < n; i++) { + if (ctx->find_sources) + av_log(avctx, AV_LOG_INFO, "\t'%s'\t'%s'\n", ndi_srcs[i].p_ndi_name, ndi_srcs[i].p_ip_address); + + if (!strcmp(name, ndi_srcs[i].p_ndi_name)) { + *source_to_connect_to = ndi_srcs[i]; + j = i; + } + } + + return j; +} + +static int ndi_read_header(AVFormatContext *avctx) +{ + int ret; + NDIlib_recv_create_t recv_create_desc; + const NDIlib_tally_t tally_state = { .on_program = true, .on_preview = false }; + struct NDIContext *ctx = avctx->priv_data; + + if (!NDIlib_initialize()) { + av_log(avctx, AV_LOG_ERROR, "NDIlib_initialize failed.\n"); + return AVERROR_EXTERNAL; + } + + /* Find available sources. */ + ret = ndi_find_sources(avctx, avctx->filename, &recv_create_desc.source_to_connect_to); + if (ctx->find_sources) { + return AVERROR_EXIT; + } + if (ret < 0) + return ret; + + /* Create receiver description */ + recv_create_desc.color_format = NDIlib_recv_color_format_e_UYVY_RGBA; + recv_create_desc.bandwidth = NDIlib_recv_bandwidth_highest; + recv_create_desc.allow_video_fields = ctx->allow_video_fields; + + /* Create the receiver */ + ctx->recv = NDIlib_recv_create(&recv_create_desc); + if (!ctx->recv) { + av_log(avctx, AV_LOG_ERROR, "NDIlib_recv_create2 failed.\n"); + return AVERROR(EIO); + } + + /* Set tally */ + NDIlib_recv_set_tally(ctx->recv, &tally_state); + + avctx->ctx_flags |= AVFMTCTX_NOHEADER; + + return 0; +} + +static int ndi_create_video_stream(AVFormatContext *avctx, NDIlib_video_frame_t *v) +{ + AVStream *st; + AVRational tmp; + struct NDIContext *ctx = avctx->priv_data; + + st = avformat_new_stream(avctx, NULL); + if (!st) { + av_log(avctx, AV_LOG_ERROR, "Cannot add video stream\n"); + return AVERROR(ENOMEM); + } + + st->time_base = NDI_TIME_BASE_Q; + av_stream_set_r_frame_rate(st, av_make_q(v->frame_rate_N, v->frame_rate_D)); + + tmp = av_mul_q(av_d2q(v->picture_aspect_ratio, INT_MAX), (AVRational){v->yres, v->xres}); + av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den, tmp.num, tmp.den, 1000); + st->codecpar->sample_aspect_ratio = st->sample_aspect_ratio; + + st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; + st->codecpar->width = v->xres; + st->codecpar->height = v->yres; + st->codecpar->codec_id = AV_CODEC_ID_RAWVIDEO; + st->codecpar->bit_rate = av_rescale(v->xres * v->yres * 16, v->frame_rate_N, v->frame_rate_D); + st->codecpar->field_order = v->frame_format_type == NDIlib_frame_format_type_progressive + ? AV_FIELD_PROGRESSIVE : AV_FIELD_TT; + + if (NDIlib_FourCC_type_UYVY == v->FourCC || NDIlib_FourCC_type_UYVA == v->FourCC) { + st->codecpar->format = AV_PIX_FMT_UYVY422; + st->codecpar->codec_tag = MKTAG('U', 'Y', 'V', 'Y'); + if (NDIlib_FourCC_type_UYVA == v->FourCC) + av_log(avctx, AV_LOG_WARNING, "Alpha channel ignored\n"); + } else if (NDIlib_FourCC_type_BGRA == v->FourCC) { + st->codecpar->format = AV_PIX_FMT_BGRA; + st->codecpar->codec_tag = MKTAG('B', 'G', 'R', 'A'); + } else if (NDIlib_FourCC_type_BGRX == v->FourCC) { + st->codecpar->format = AV_PIX_FMT_BGR0; + st->codecpar->codec_tag = MKTAG('B', 'G', 'R', '0'); + } else if (NDIlib_FourCC_type_RGBA == v->FourCC) { + st->codecpar->format = AV_PIX_FMT_RGBA; + st->codecpar->codec_tag = MKTAG('R', 'G', 'B', 'A'); + } else if (NDIlib_FourCC_type_RGBX == v->FourCC) { + st->codecpar->format = AV_PIX_FMT_RGB0; + st->codecpar->codec_tag = MKTAG('R', 'G', 'B', '0'); + } else { + av_log(avctx, AV_LOG_ERROR, "Unsupported video stream format, v->FourCC=%d\n", v->FourCC); + return AVERROR(EINVAL); + } + + avpriv_set_pts_info(st, 64, 1, NDI_TIME_BASE); + + ctx->video_st = st; + + return 0; +} + +static int ndi_create_audio_stream(AVFormatContext *avctx, NDIlib_audio_frame_t *a) +{ + AVStream *st; + struct NDIContext *ctx = avctx->priv_data; + + st = avformat_new_stream(avctx, NULL); + if (!st) { + av_log(avctx, AV_LOG_ERROR, "Cannot add audio stream\n"); + return AVERROR(ENOMEM); + } + + st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; + st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE; + st->codecpar->sample_rate = a->sample_rate; + st->codecpar->channels = a->no_channels; + + avpriv_set_pts_info(st, 64, 1, NDI_TIME_BASE); + + ctx->audio_st = st; + + return 0; +} + +static int ndi_read_packet(AVFormatContext *avctx, AVPacket *pkt) +{ + int ret = 0; + struct NDIContext *ctx = avctx->priv_data; + + while (!ret) { + NDIlib_video_frame_t v; + NDIlib_audio_frame_t a; + NDIlib_metadata_frame_t m; + NDIlib_frame_type_e t; + + av_log(avctx, AV_LOG_DEBUG, "NDIlib_recv_capture...\n"); + t = NDIlib_recv_capture(ctx->recv, &v, &a, &m, 40); + av_log(avctx, AV_LOG_DEBUG, "NDIlib_recv_capture=%d\n", t); + + if (t == NDIlib_frame_type_video) { + if (!ctx->video_st) + ret = ndi_create_video_stream(avctx, &v); + if (!ret) + ret = ndi_set_video_packet(avctx, &v, pkt); + NDIlib_recv_free_video(ctx->recv, &v); + break; + } + else if (t == NDIlib_frame_type_audio) { + if (!ctx->audio_st) + ret = ndi_create_audio_stream(avctx, &a); + if (!ret) + ret = ndi_set_audio_packet(avctx, &a, pkt); + NDIlib_recv_free_audio(ctx->recv, &a); + break; + } + else if (t == NDIlib_frame_type_metadata) + NDIlib_recv_free_metadata(ctx->recv, &m); + else if (t == NDIlib_frame_type_error){ + av_log(avctx, AV_LOG_ERROR, "NDIlib_recv_capture failed with error\n"); + ret = AVERROR(EIO); + } + }; + + return ret; +} + +static int ndi_read_close(AVFormatContext *avctx) +{ + struct NDIContext *ctx = (struct NDIContext *)avctx->priv_data; + + if (ctx->recv) + NDIlib_recv_destroy(ctx->recv); + + if (ctx->ndi_find) + NDIlib_find_destroy(ctx->ndi_find); + + return 0; +} + +#define OFFSET(x) offsetof(struct NDIContext, x) +#define DEC AV_OPT_FLAG_DECODING_PARAM + +static const AVOption options[] = { + { "find_sources", "Find available sources" , OFFSET(find_sources), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, DEC }, + { "wait_sources", "Time to wait until the number of online sources have changed" , OFFSET(wait_sources), AV_OPT_TYPE_DURATION, { .i64 = 1000000 }, 100000, 20000000, DEC }, + { "allow_video_fields", "When this flag is FALSE, all video that you receive will be progressive" , OFFSET(allow_video_fields), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, DEC }, + { NULL }, +}; + +static const AVClass libndi_newtek_demuxer_class = { + .class_name = "NDI demuxer", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, + .category = AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT, +}; + +AVInputFormat ff_libndi_newtek_demuxer = { + .name = "libndi_newtek", + .long_name = NULL_IF_CONFIG_SMALL("Network Device Interface (NDI) input using NewTek library"), + .flags = AVFMT_NOFILE, + .priv_class = &libndi_newtek_demuxer_class, + .priv_data_size = sizeof(struct NDIContext), + .read_header = ndi_read_header, + .read_packet = ndi_read_packet, + .read_close = ndi_read_close, +}; diff --git a/libavdevice/libndi_newtek_enc.c b/libavdevice/libndi_newtek_enc.c new file mode 100644 index 0000000000000..6ca6f41b734ed --- /dev/null +++ b/libavdevice/libndi_newtek_enc.c @@ -0,0 +1,299 @@ +/* + * NewTek NDI output + * Copyright (c) 2017 Maksym Veremeyenko + * + * 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 "libavformat/avformat.h" +#include "libavformat/internal.h" +#include "libavutil/opt.h" +#include "libavutil/imgutils.h" + +#include "libndi_newtek_common.h" + +struct NDIContext { + const AVClass *cclass; + + /* Options */ + int reference_level; + int clock_video, clock_audio; + + NDIlib_video_frame_t *video; + NDIlib_audio_frame_interleaved_16s_t *audio; + NDIlib_send_instance_t ndi_send; + AVFrame *last_avframe; +}; + +static int ndi_write_trailer(AVFormatContext *avctx) +{ + struct NDIContext *ctx = avctx->priv_data; + + if (ctx->ndi_send) { + NDIlib_send_destroy(ctx->ndi_send); + av_frame_free(&ctx->last_avframe); + } + + av_freep(&ctx->video); + av_freep(&ctx->audio); + + return 0; +} + +static int ndi_write_video_packet(AVFormatContext *avctx, AVStream *st, AVPacket *pkt) +{ + struct NDIContext *ctx = avctx->priv_data; + AVFrame *avframe, *tmp = (AVFrame *)pkt->data; + + if (tmp->format != AV_PIX_FMT_UYVY422 && tmp->format != AV_PIX_FMT_BGRA && + tmp->format != AV_PIX_FMT_BGR0 && tmp->format != AV_PIX_FMT_RGBA && + tmp->format != AV_PIX_FMT_RGB0) { + av_log(avctx, AV_LOG_ERROR, "Got a frame with invalid pixel format.\n"); + return AVERROR(EINVAL); + } + + if (tmp->linesize[0] < 0) { + av_log(avctx, AV_LOG_ERROR, "Got a frame with negative linesize.\n"); + return AVERROR(EINVAL); + } + + if (tmp->width != ctx->video->xres || + tmp->height != ctx->video->yres) { + av_log(avctx, AV_LOG_ERROR, "Got a frame with invalid dimension.\n"); + av_log(avctx, AV_LOG_ERROR, "tmp->width=%d, tmp->height=%d, ctx->video->xres=%d, ctx->video->yres=%d\n", + tmp->width, tmp->height, ctx->video->xres, ctx->video->yres); + return AVERROR(EINVAL); + } + + avframe = av_frame_clone(tmp); + if (!avframe) + return AVERROR(ENOMEM); + + ctx->video->timecode = av_rescale_q(pkt->pts, st->time_base, NDI_TIME_BASE_Q); + + ctx->video->line_stride_in_bytes = avframe->linesize[0]; + ctx->video->p_data = (void *)(avframe->data[0]); + + av_log(avctx, AV_LOG_DEBUG, "%s: pkt->pts=%"PRId64", timecode=%"PRId64", st->time_base=%d/%d\n", + __func__, pkt->pts, ctx->video->timecode, st->time_base.num, st->time_base.den); + + /* asynchronous for one frame, but will block if a second frame + is given before the first one has been sent */ + NDIlib_send_send_video_async(ctx->ndi_send, ctx->video); + + av_frame_free(&ctx->last_avframe); + ctx->last_avframe = avframe; + + return 0; +} + +static int ndi_write_audio_packet(AVFormatContext *avctx, AVStream *st, AVPacket *pkt) +{ + struct NDIContext *ctx = avctx->priv_data; + + ctx->audio->p_data = (short *)pkt->data; + ctx->audio->timecode = av_rescale_q(pkt->pts, st->time_base, NDI_TIME_BASE_Q); + ctx->audio->no_samples = pkt->size / (ctx->audio->no_channels << 1); + + av_log(avctx, AV_LOG_DEBUG, "%s: pkt->pts=%"PRId64", timecode=%"PRId64", st->time_base=%d/%d\n", + __func__, pkt->pts, ctx->audio->timecode, st->time_base.num, st->time_base.den); + + NDIlib_util_send_send_audio_interleaved_16s(ctx->ndi_send, ctx->audio); + + return 0; +} + +static int ndi_write_packet(AVFormatContext *avctx, AVPacket *pkt) +{ + AVStream *st = avctx->streams[pkt->stream_index]; + + if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) + return ndi_write_video_packet(avctx, st, pkt); + else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) + return ndi_write_audio_packet(avctx, st, pkt); + + return AVERROR_BUG; +} + +static int ndi_setup_audio(AVFormatContext *avctx, AVStream *st) +{ + struct NDIContext *ctx = avctx->priv_data; + AVCodecParameters *c = st->codecpar; + + if (ctx->audio) { + av_log(avctx, AV_LOG_ERROR, "Only one audio stream is supported!\n"); + return AVERROR(EINVAL); + } + + ctx->audio = av_mallocz(sizeof(NDIlib_audio_frame_interleaved_16s_t)); + if (!ctx->audio) + return AVERROR(ENOMEM); + + ctx->audio->sample_rate = c->sample_rate; + ctx->audio->no_channels = c->channels; + ctx->audio->reference_level = ctx->reference_level; + + avpriv_set_pts_info(st, 64, 1, NDI_TIME_BASE); + + return 0; +} + +static int ndi_setup_video(AVFormatContext *avctx, AVStream *st) +{ + struct NDIContext *ctx = avctx->priv_data; + AVCodecParameters *c = st->codecpar; + + if (ctx->video) { + av_log(avctx, AV_LOG_ERROR, "Only one video stream is supported!\n"); + return AVERROR(EINVAL); + } + + if (c->codec_id != AV_CODEC_ID_WRAPPED_AVFRAME) { + av_log(avctx, AV_LOG_ERROR, "Unsupported codec format!" + " Only AV_CODEC_ID_WRAPPED_AVFRAME is supported (-vcodec wrapped_avframe).\n"); + return AVERROR(EINVAL); + } + + if (c->format != AV_PIX_FMT_UYVY422 && c->format != AV_PIX_FMT_BGRA && + c->format != AV_PIX_FMT_BGR0 && c->format != AV_PIX_FMT_RGBA && + c->format != AV_PIX_FMT_RGB0) { + av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format!" + " Only AV_PIX_FMT_UYVY422, AV_PIX_FMT_BGRA, AV_PIX_FMT_BGR0," + " AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB0 is supported.\n"); + return AVERROR(EINVAL); + } + + if (c->field_order == AV_FIELD_BB || c->field_order == AV_FIELD_BT) { + av_log(avctx, AV_LOG_ERROR, "Lower field-first disallowed"); + return AVERROR(EINVAL); + } + + ctx->video = av_mallocz(sizeof(NDIlib_video_frame_t)); + if (!ctx->video) + return AVERROR(ENOMEM); + + switch(c->format) { + case AV_PIX_FMT_UYVY422: + ctx->video->FourCC = NDIlib_FourCC_type_UYVY; + break; + case AV_PIX_FMT_BGRA: + ctx->video->FourCC = NDIlib_FourCC_type_BGRA; + break; + case AV_PIX_FMT_BGR0: + ctx->video->FourCC = NDIlib_FourCC_type_BGRX; + break; + case AV_PIX_FMT_RGBA: + ctx->video->FourCC = NDIlib_FourCC_type_RGBA; + break; + case AV_PIX_FMT_RGB0: + ctx->video->FourCC = NDIlib_FourCC_type_RGBX; + break; + } + + ctx->video->xres = c->width; + ctx->video->yres = c->height; + ctx->video->frame_rate_N = st->avg_frame_rate.num; + ctx->video->frame_rate_D = st->avg_frame_rate.den; + ctx->video->frame_format_type = c->field_order == AV_FIELD_PROGRESSIVE + ? NDIlib_frame_format_type_progressive + : NDIlib_frame_format_type_interleaved; + + if (st->sample_aspect_ratio.num) { + AVRational display_aspect_ratio; + av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den, + st->codecpar->width * (int64_t)st->sample_aspect_ratio.num, + st->codecpar->height * (int64_t)st->sample_aspect_ratio.den, + 1024 * 1024); + ctx->video->picture_aspect_ratio = av_q2d(display_aspect_ratio); + } + else + ctx->video->picture_aspect_ratio = (double)st->codecpar->width/st->codecpar->height; + + avpriv_set_pts_info(st, 64, 1, NDI_TIME_BASE); + + return 0; +} + +static int ndi_write_header(AVFormatContext *avctx) +{ + int ret = 0; + unsigned int n; + struct NDIContext *ctx = avctx->priv_data; + const NDIlib_send_create_t ndi_send_desc = { .p_ndi_name = avctx->filename, + .p_groups = NULL, .clock_video = ctx->clock_video, .clock_audio = ctx->clock_audio }; + + if (!NDIlib_initialize()) { + av_log(avctx, AV_LOG_ERROR, "NDIlib_initialize failed.\n"); + return AVERROR_EXTERNAL; + } + + /* check if streams compatible */ + for (n = 0; n < avctx->nb_streams; n++) { + AVStream *st = avctx->streams[n]; + AVCodecParameters *c = st->codecpar; + if (c->codec_type == AVMEDIA_TYPE_AUDIO) { + if ((ret = ndi_setup_audio(avctx, st))) + goto error; + } else if (c->codec_type == AVMEDIA_TYPE_VIDEO) { + if ((ret = ndi_setup_video(avctx, st))) + goto error; + } else { + av_log(avctx, AV_LOG_ERROR, "Unsupported stream type.\n"); + ret = AVERROR(EINVAL); + goto error; + } + } + + ctx->ndi_send = NDIlib_send_create(&ndi_send_desc); + if (!ctx->ndi_send) { + av_log(avctx, AV_LOG_ERROR, "Failed to create NDI output %s\n", avctx->filename); + ret = AVERROR_EXTERNAL; + } + +error: + return ret; +} + +#define OFFSET(x) offsetof(struct NDIContext, x) +static const AVOption options[] = { + { "reference_level", "The audio reference level in dB" , OFFSET(reference_level), AV_OPT_TYPE_INT, { .i64 = 0 }, -20, 20, AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM}, + { "clock_video", "These specify whether video 'clock' themselves" , OFFSET(clock_video), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM }, + { "clock_audio", "These specify whether audio 'clock' themselves" , OFFSET(clock_audio), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM }, + { NULL }, +}; + +static const AVClass libndi_newtek_muxer_class = { + .class_name = "NDI muxer", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, + .category = AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT, +}; + +AVOutputFormat ff_libndi_newtek_muxer = { + .name = "libndi_newtek", + .long_name = NULL_IF_CONFIG_SMALL("Network Device Interface (NDI) output using NewTek library"), + .audio_codec = AV_CODEC_ID_PCM_S16LE, + .video_codec = AV_CODEC_ID_WRAPPED_AVFRAME, + .subtitle_codec = AV_CODEC_ID_NONE, + .flags = AVFMT_NOFILE, + .priv_class = &libndi_newtek_muxer_class, + .priv_data_size = sizeof(struct NDIContext), + .write_header = ndi_write_header, + .write_packet = ndi_write_packet, + .write_trailer = ndi_write_trailer, +}; diff --git a/libavdevice/version.h b/libavdevice/version.h index e0d3680578f83..948e4e1e08fd6 100644 --- a/libavdevice/version.h +++ b/libavdevice/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVDEVICE_VERSION_MAJOR 57 -#define LIBAVDEVICE_VERSION_MINOR 7 -#define LIBAVDEVICE_VERSION_MICRO 101 +#define LIBAVDEVICE_VERSION_MINOR 8 +#define LIBAVDEVICE_VERSION_MICRO 100 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ LIBAVDEVICE_VERSION_MINOR, \ From 7ec414892ddcad88313848494b6fc5f437c9ca4a Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 26 Aug 2017 01:26:58 +0200 Subject: [PATCH 2867/3374] avformat/hls: Fix DoS due to infinite loop Fixes: loop.m3u The default max iteration count of 1000 is arbitrary and ideas for a better solution are welcome Found-by: Xiaohei and Wangchu from Alibaba Security Team Previous version reviewed-by: Steven Liu Signed-off-by: Michael Niedermayer --- doc/demuxers.texi | 18 ++++++++++++++++++ libavformat/hls.c | 7 +++++++ 2 files changed, 25 insertions(+) diff --git a/doc/demuxers.texi b/doc/demuxers.texi index 29a23d48b258c..73dc0feec194a 100644 --- a/doc/demuxers.texi +++ b/doc/demuxers.texi @@ -300,6 +300,24 @@ used to end the output video at the length of the shortest input file, which in this case is @file{input.mp4} as the GIF in this example loops infinitely. +@section hls + +HLS demuxer + +It accepts the following options: + +@table @option +@item live_start_index +segment index to start live streams at (negative values are from the end). + +@item allowed_extensions +',' separated list of file extensions that hls is allowed to access. + +@item max_reload +Maximum number of times a insufficient list is attempted to be reloaded. +Default value is 1000. +@end table + @section image2 Image file demuxer. diff --git a/libavformat/hls.c b/libavformat/hls.c index 01731bd36b0cf..0995345bbf2c4 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -205,6 +205,7 @@ typedef struct HLSContext { AVDictionary *avio_opts; int strict_std_compliance; char *allowed_extensions; + int max_reload; } HLSContext; static int read_chomp_line(AVIOContext *s, char *buf, int maxlen) @@ -1263,6 +1264,7 @@ static int read_data(void *opaque, uint8_t *buf, int buf_size) HLSContext *c = v->parent->priv_data; int ret, i; int just_opened = 0; + int reload_count = 0; restart: if (!v->needed) @@ -1294,6 +1296,9 @@ static int read_data(void *opaque, uint8_t *buf, int buf_size) reload_interval = default_reload_interval(v); reload: + reload_count++; + if (reload_count > c->max_reload) + return AVERROR_EOF; if (!v->finished && av_gettime_relative() - v->last_load_time >= reload_interval) { if ((ret = parse_playlist(c, v->url, v, NULL)) < 0) { @@ -2150,6 +2155,8 @@ static const AVOption hls_options[] = { OFFSET(allowed_extensions), AV_OPT_TYPE_STRING, {.str = "3gp,aac,avi,flac,mkv,m3u8,m4a,m4s,m4v,mpg,mov,mp2,mp3,mp4,mpeg,mpegts,ogg,ogv,oga,ts,vob,wav"}, INT_MIN, INT_MAX, FLAGS}, + {"max_reload", "Maximum number of times a insufficient list is attempted to be reloaded", + OFFSET(max_reload), AV_OPT_TYPE_INT, {.i64 = 1000}, 0, INT_MAX, FLAGS}, {NULL} }; From 7f9ec5593e04827249e7aeb466da06a98a0d7329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E6=B5=A9=20and=20=E5=BC=A0=E6=B4=AA=E4=BA=AE=28?= =?UTF-8?q?=E6=9C=9B=E5=88=9D=29?= Date: Fri, 25 Aug 2017 12:37:25 +0200 Subject: [PATCH 2868/3374] avformat/asfdec: Fix DoS due to lack of eof check Fixes: loop.asf Found-by: Xiaohei and Wangchu from Alibaba Security Team Signed-off-by: Michael Niedermayer --- libavformat/asfdec_f.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavformat/asfdec_f.c b/libavformat/asfdec_f.c index be09a92bd1e26..f3acbae2801b7 100644 --- a/libavformat/asfdec_f.c +++ b/libavformat/asfdec_f.c @@ -749,13 +749,15 @@ static int asf_read_marker(AVFormatContext *s, int64_t size) count = avio_rl32(pb); // markers count avio_rl16(pb); // reserved 2 bytes name_len = avio_rl16(pb); // name length - for (i = 0; i < name_len; i++) - avio_r8(pb); // skip the name + avio_skip(pb, name_len); for (i = 0; i < count; i++) { int64_t pres_time; int name_len; + if (avio_feof(pb)) + return AVERROR_INVALIDDATA; + avio_rl64(pb); // offset, 8 bytes pres_time = avio_rl64(pb); // presentation time pres_time -= asf->hdr.preroll * 10000; From 7e80b63ecd259d69d383623e75b318bf2bd491f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E6=B5=A9=20and=20=E5=BC=A0=E6=B4=AA=E4=BA=AE=28?= =?UTF-8?q?=E6=9C=9B=E5=88=9D=29?= Date: Fri, 25 Aug 2017 01:15:27 +0200 Subject: [PATCH 2869/3374] avformat/cinedec: Fix DoS due to lack of eof check Fixes: loop.cine Found-by: Xiaohei and Wangchu from Alibaba Security Team Signed-off-by: Michael Niedermayer --- libavformat/cinedec.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libavformat/cinedec.c b/libavformat/cinedec.c index 763b93ba2e178..de34fb9638201 100644 --- a/libavformat/cinedec.c +++ b/libavformat/cinedec.c @@ -267,8 +267,12 @@ static int cine_read_header(AVFormatContext *avctx) /* parse image offsets */ avio_seek(pb, offImageOffsets, SEEK_SET); - for (i = 0; i < st->duration; i++) + for (i = 0; i < st->duration; i++) { + if (avio_feof(pb)) + return AVERROR_INVALIDDATA; + av_add_index_entry(st, avio_rl64(pb), i, 0, 0, AVINDEX_KEYFRAME); + } return 0; } From 124eb202e70678539544f6268efc98131f19fa49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E6=B5=A9=20and=20=E5=BC=A0=E6=B4=AA=E4=BA=AE=28?= =?UTF-8?q?=E6=9C=9B=E5=88=9D=29?= Date: Fri, 25 Aug 2017 01:15:28 +0200 Subject: [PATCH 2870/3374] avformat/rmdec: Fix DoS due to lack of eof check Fixes: loop.ivr Found-by: Xiaohei and Wangchu from Alibaba Security Team Signed-off-by: Michael Niedermayer --- libavformat/rmdec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c index 178eaea57d89d..d6d7d9cd8414d 100644 --- a/libavformat/rmdec.c +++ b/libavformat/rmdec.c @@ -1223,8 +1223,11 @@ static int ivr_read_header(AVFormatContext *s) av_log(s, AV_LOG_DEBUG, "%s = '%s'\n", key, val); } else if (type == 4) { av_log(s, AV_LOG_DEBUG, "%s = '0x", key); - for (j = 0; j < len; j++) + for (j = 0; j < len; j++) { + if (avio_feof(pb)) + return AVERROR_INVALIDDATA; av_log(s, AV_LOG_DEBUG, "%X", avio_r8(pb)); + } av_log(s, AV_LOG_DEBUG, "'\n"); } else if (len == 4 && type == 3 && !strncmp(key, "StreamCount", tlen)) { nb_streams = value = avio_rb32(pb); From 96f24d1bee7fe7bac08e2b7c74db1a046c9dc0de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E6=B5=A9=20and=20=E5=BC=A0=E6=B4=AA=E4=BA=AE=28?= =?UTF-8?q?=E6=9C=9B=E5=88=9D=29?= Date: Fri, 25 Aug 2017 01:15:29 +0200 Subject: [PATCH 2871/3374] avformat/rl2: Fix DoS due to lack of eof check Fixes: loop.rl2 Found-by: Xiaohei and Wangchu from Alibaba Security Team Signed-off-by: Michael Niedermayer --- libavformat/rl2.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/libavformat/rl2.c b/libavformat/rl2.c index 0bec8f1d9aba8..eb1682dfcb7c2 100644 --- a/libavformat/rl2.c +++ b/libavformat/rl2.c @@ -170,12 +170,21 @@ static av_cold int rl2_read_header(AVFormatContext *s) } /** read offset and size tables */ - for(i=0; i < frame_count;i++) + for(i=0; i < frame_count;i++) { + if (avio_feof(pb)) + return AVERROR_INVALIDDATA; chunk_size[i] = avio_rl32(pb); - for(i=0; i < frame_count;i++) + } + for(i=0; i < frame_count;i++) { + if (avio_feof(pb)) + return AVERROR_INVALIDDATA; chunk_offset[i] = avio_rl32(pb); - for(i=0; i < frame_count;i++) + } + for(i=0; i < frame_count;i++) { + if (avio_feof(pb)) + return AVERROR_INVALIDDATA; audio_size[i] = avio_rl32(pb) & 0xFFFF; + } /** build the sample index */ for(i=0;i Date: Fri, 25 Aug 2017 01:15:30 +0200 Subject: [PATCH 2872/3374] avformat/mvdec: Fix DoS due to lack of eof check Fixes: loop.mv Found-by: Xiaohei and Wangchu from Alibaba Security Team Signed-off-by: Michael Niedermayer --- libavformat/mvdec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavformat/mvdec.c b/libavformat/mvdec.c index 0e12c8c6c18a1..f7aa4cbaecf86 100644 --- a/libavformat/mvdec.c +++ b/libavformat/mvdec.c @@ -342,6 +342,8 @@ static int mv_read_header(AVFormatContext *avctx) uint32_t pos = avio_rb32(pb); uint32_t asize = avio_rb32(pb); uint32_t vsize = avio_rb32(pb); + if (avio_feof(pb)) + return AVERROR_INVALIDDATA; avio_skip(pb, 8); av_add_index_entry(ast, pos, timestamp, asize, 0, AVINDEX_KEYFRAME); av_add_index_entry(vst, pos + asize, i, vsize, 0, AVINDEX_KEYFRAME); From eefb68c9c335dda423c9115ba11dc4bb3e73e3f9 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 26 Aug 2017 14:00:55 +0200 Subject: [PATCH 2873/3374] avcodec/sbrdsp_fixed: Fix undefined overflows in autocorrelate() Fixes: runtime error: signed integer overflow: 8903997421129740175 + 354481484684609529 cannot be represented in type 'long' Fixes: 2045/clusterfuzz-testcase-minimized-6751255865065472 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/sbrdsp_fixed.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/libavcodec/sbrdsp_fixed.c b/libavcodec/sbrdsp_fixed.c index fe4810402174d..896b2d75c6c6c 100644 --- a/libavcodec/sbrdsp_fixed.c +++ b/libavcodec/sbrdsp_fixed.c @@ -147,19 +147,19 @@ static av_always_inline void autocorrelate(const int x[40][2], SoftFloat phi[3][ if (lag) { for (i = 1; i < 38; i++) { - accu_re += (int64_t)x[i][0] * x[i+lag][0]; - accu_re += (int64_t)x[i][1] * x[i+lag][1]; - accu_im += (int64_t)x[i][0] * x[i+lag][1]; - accu_im -= (int64_t)x[i][1] * x[i+lag][0]; + accu_re += (uint64_t)x[i][0] * x[i+lag][0]; + accu_re += (uint64_t)x[i][1] * x[i+lag][1]; + accu_im += (uint64_t)x[i][0] * x[i+lag][1]; + accu_im -= (uint64_t)x[i][1] * x[i+lag][0]; } real_sum = accu_re; imag_sum = accu_im; - accu_re += (int64_t)x[ 0][0] * x[lag][0]; - accu_re += (int64_t)x[ 0][1] * x[lag][1]; - accu_im += (int64_t)x[ 0][0] * x[lag][1]; - accu_im -= (int64_t)x[ 0][1] * x[lag][0]; + accu_re += (uint64_t)x[ 0][0] * x[lag][0]; + accu_re += (uint64_t)x[ 0][1] * x[lag][1]; + accu_im += (uint64_t)x[ 0][0] * x[lag][1]; + accu_im -= (uint64_t)x[ 0][1] * x[lag][0]; phi[2-lag][1][0] = autocorr_calc(accu_re); phi[2-lag][1][1] = autocorr_calc(accu_im); @@ -167,28 +167,28 @@ static av_always_inline void autocorrelate(const int x[40][2], SoftFloat phi[3][ if (lag == 1) { accu_re = real_sum; accu_im = imag_sum; - accu_re += (int64_t)x[38][0] * x[39][0]; - accu_re += (int64_t)x[38][1] * x[39][1]; - accu_im += (int64_t)x[38][0] * x[39][1]; - accu_im -= (int64_t)x[38][1] * x[39][0]; + accu_re += (uint64_t)x[38][0] * x[39][0]; + accu_re += (uint64_t)x[38][1] * x[39][1]; + accu_im += (uint64_t)x[38][0] * x[39][1]; + accu_im -= (uint64_t)x[38][1] * x[39][0]; phi[0][0][0] = autocorr_calc(accu_re); phi[0][0][1] = autocorr_calc(accu_im); } } else { for (i = 1; i < 38; i++) { - accu_re += (int64_t)x[i][0] * x[i][0]; - accu_re += (int64_t)x[i][1] * x[i][1]; + accu_re += (uint64_t)x[i][0] * x[i][0]; + accu_re += (uint64_t)x[i][1] * x[i][1]; } real_sum = accu_re; - accu_re += (int64_t)x[ 0][0] * x[ 0][0]; - accu_re += (int64_t)x[ 0][1] * x[ 0][1]; + accu_re += (uint64_t)x[ 0][0] * x[ 0][0]; + accu_re += (uint64_t)x[ 0][1] * x[ 0][1]; phi[2][1][0] = autocorr_calc(accu_re); accu_re = real_sum; - accu_re += (int64_t)x[38][0] * x[38][0]; - accu_re += (int64_t)x[38][1] * x[38][1]; + accu_re += (uint64_t)x[38][0] * x[38][0]; + accu_re += (uint64_t)x[38][1] * x[38][1]; phi[1][0][0] = autocorr_calc(accu_re); } From 0181b202cc42133eacd74bad33745cf1ba699e6b Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 26 Aug 2017 14:08:51 +0200 Subject: [PATCH 2874/3374] avcodec/aacpsdsp_template: Fix undefined integer overflow in ps_add_squares_c() Fixes runtime error: signed integer overflow: 1997494407 + 613252359 cannot be represented in type 'int' Fixes: 2014/clusterfuzz-testcase-minimized-5186337030275072 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/aacpsdsp_template.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/aacpsdsp_template.c b/libavcodec/aacpsdsp_template.c index 9e1a95c1a14a6..e35e9699b0b5a 100644 --- a/libavcodec/aacpsdsp_template.c +++ b/libavcodec/aacpsdsp_template.c @@ -30,7 +30,7 @@ static void ps_add_squares_c(INTFLOAT *dst, const INTFLOAT (*src)[2], int n) { int i; for (i = 0; i < n; i++) - dst[i] += AAC_MADD28(src[i][0], src[i][0], src[i][1], src[i][1]); + dst[i] += (UINTFLOAT)AAC_MADD28(src[i][0], src[i][0], src[i][1], src[i][1]); } static void ps_mul_pair_single_c(INTFLOAT (*dst)[2], INTFLOAT (*src0)[2], INTFLOAT *src1, From aa26258faa9704b144dfe5bc5d263a1332d7a9dd Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 27 Aug 2017 20:41:56 +0200 Subject: [PATCH 2875/3374] avfilter/vf_zoompan: remove AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC Suggested-by: Fixes: assertion failure Signed-off-by: Michael Niedermayer --- libavfilter/vf_zoompan.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libavfilter/vf_zoompan.c b/libavfilter/vf_zoompan.c index 08575182175a4..14d0a1707b5c3 100644 --- a/libavfilter/vf_zoompan.c +++ b/libavfilter/vf_zoompan.c @@ -373,5 +373,4 @@ AVFilter ff_vf_zoompan = { .activate = activate, .inputs = inputs, .outputs = outputs, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, }; From ef0c6d9b01de773e5a1177de5fcbb981aac44d65 Mon Sep 17 00:00:00 2001 From: Timo Rothenpieler Date: Sun, 11 Jun 2017 16:05:45 +0200 Subject: [PATCH 2876/3374] libavutil/opencl: fix potential null dereference Fixes CID 1396840 Reviewed-by: Wei Gao Signed-off-by: Timo Rothenpieler --- libavutil/opencl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavutil/opencl.c b/libavutil/opencl.c index af35770e0654d..202756516b005 100644 --- a/libavutil/opencl.c +++ b/libavutil/opencl.c @@ -169,7 +169,7 @@ const char *av_opencl_errstr(cl_int status) static void free_device_list(AVOpenCLDeviceList *device_list) { int i, j; - if (!device_list) + if (!device_list || !device_list->platform_node) return; for (i = 0; i < device_list->platform_num; i++) { if (!device_list->platform_node[i]) From 385cafb07ac1e46433931ea9749a134efd7350be Mon Sep 17 00:00:00 2001 From: Jun Zhao Date: Fri, 25 Aug 2017 15:56:51 +0800 Subject: [PATCH 2877/3374] lavc/vaapi_encode_h265: Enable VBR mode Follow vaapi_h264 style, enable the VBR mode. Signed-off-by: Jun Zhao Signed-off-by: Mark Thompson --- libavcodec/vaapi_encode_h265.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c index cf6b9388d13c2..971458db8759f 100644 --- a/libavcodec/vaapi_encode_h265.c +++ b/libavcodec/vaapi_encode_h265.c @@ -1185,13 +1185,15 @@ static av_cold int vaapi_encode_h265_configure(AVCodecContext *avctx) "%d / %d / %d for IDR- / P- / B-frames.\n", priv->fixed_qp_idr, priv->fixed_qp_p, priv->fixed_qp_b); - } else if (ctx->va_rc_mode == VA_RC_CBR) { + } else if (ctx->va_rc_mode == VA_RC_CBR || + ctx->va_rc_mode == VA_RC_VBR) { // These still need to be set for pic_init_qp/slice_qp_delta. priv->fixed_qp_idr = 30; priv->fixed_qp_p = 30; priv->fixed_qp_b = 30; - av_log(avctx, AV_LOG_DEBUG, "Using constant-bitrate = %"PRId64" bps.\n", + av_log(avctx, AV_LOG_DEBUG, "Using %s-bitrate = %"PRId64" bps.\n", + ctx->va_rc_mode == VA_RC_CBR ? "constant" : "variable", avctx->bit_rate); } else { @@ -1251,9 +1253,12 @@ static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx) } ctx->va_entrypoint = VAEntrypointEncSlice; - if (avctx->bit_rate > 0) - ctx->va_rc_mode = VA_RC_CBR; - else + if (avctx->bit_rate > 0) { + if (avctx->rc_max_rate == avctx->bit_rate) + ctx->va_rc_mode = VA_RC_CBR; + else + ctx->va_rc_mode = VA_RC_VBR; + } else ctx->va_rc_mode = VA_RC_CQP; ctx->va_packed_headers = From e4a6eb70f471eda36592078e8fa1bad87fc9df73 Mon Sep 17 00:00:00 2001 From: Jun Zhao Date: Thu, 24 Aug 2017 09:13:01 +0800 Subject: [PATCH 2878/3374] lavc/vaapi_encode: Change the slice/parameter buffers to dynamic alloc. Change the slice/parameter buffers to be allocated dynamically. Signed-off-by: Wang, Yi A Signed-off-by: Jun Zhao Signed-off-by: Mark Thompson --- libavcodec/vaapi_encode.c | 42 ++++++++++++++++++++++++++++----------- libavcodec/vaapi_encode.h | 6 ++---- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index 22114bedbe6b6..4d7683f1460ea 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -36,13 +36,17 @@ static int vaapi_encode_make_packed_header(AVCodecContext *avctx, VAAPIEncodeContext *ctx = avctx->priv_data; VAStatus vas; VABufferID param_buffer, data_buffer; + VABufferID *tmp; VAEncPackedHeaderParameterBuffer params = { .type = type, .bit_length = bit_len, .has_emulation_bytes = 1, }; - av_assert0(pic->nb_param_buffers + 2 <= MAX_PARAM_BUFFERS); + tmp = av_realloc_array(pic->param_buffers, sizeof(*tmp), pic->nb_param_buffers + 2); + if (!tmp) + return AVERROR(ENOMEM); + pic->param_buffers = tmp; vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context, VAEncPackedHeaderParameterBufferType, @@ -77,9 +81,13 @@ static int vaapi_encode_make_param_buffer(AVCodecContext *avctx, { VAAPIEncodeContext *ctx = avctx->priv_data; VAStatus vas; + VABufferID *tmp; VABufferID buffer; - av_assert0(pic->nb_param_buffers + 1 <= MAX_PARAM_BUFFERS); + tmp = av_realloc_array(pic->param_buffers, sizeof(*tmp), pic->nb_param_buffers + 1); + if (!tmp) + return AVERROR(ENOMEM); + pic->param_buffers = tmp; vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context, type, len, 1, data, &buffer); @@ -313,15 +321,14 @@ static int vaapi_encode_issue(AVCodecContext *avctx, } } - av_assert0(pic->nb_slices <= MAX_PICTURE_SLICES); + pic->slices = av_mallocz_array(pic->nb_slices, sizeof(*pic->slices)); + if (!pic->slices) { + err = AVERROR(ENOMEM); + goto fail; + } for (i = 0; i < pic->nb_slices; i++) { - slice = av_mallocz(sizeof(*slice)); - if (!slice) { - err = AVERROR(ENOMEM); - goto fail; - } + slice = &pic->slices[i]; slice->index = i; - pic->slices[i] = slice; if (ctx->codec->slice_params_size > 0) { slice->codec_slice_params = av_mallocz(ctx->codec->slice_params_size); @@ -425,8 +432,16 @@ static int vaapi_encode_issue(AVCodecContext *avctx, fail: for(i = 0; i < pic->nb_param_buffers; i++) vaDestroyBuffer(ctx->hwctx->display, pic->param_buffers[i]); + for (i = 0; i < pic->nb_slices; i++) { + if (pic->slices) { + av_freep(&pic->slices[i].priv_data); + av_freep(&pic->slices[i].codec_slice_params); + } + } fail_at_end: av_freep(&pic->codec_picture_params); + av_freep(&pic->param_buffers); + av_freep(&pic->slices); av_frame_free(&pic->recon_image); av_buffer_unref(&pic->output_buffer_ref); pic->output_buffer = VA_INVALID_ID; @@ -535,15 +550,18 @@ static int vaapi_encode_free(AVCodecContext *avctx, vaapi_encode_discard(avctx, pic); for (i = 0; i < pic->nb_slices; i++) { - av_freep(&pic->slices[i]->priv_data); - av_freep(&pic->slices[i]->codec_slice_params); - av_freep(&pic->slices[i]); + if (pic->slices) { + av_freep(&pic->slices[i].priv_data); + av_freep(&pic->slices[i].codec_slice_params); + } } av_freep(&pic->codec_picture_params); av_frame_free(&pic->input_image); av_frame_free(&pic->recon_image); + av_freep(&pic->param_buffers); + av_freep(&pic->slices); // Output buffer should already be destroyed. av_assert0(pic->output_buffer == VA_INVALID_ID); diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h index 3bf0cc87c7d62..bcb9d57371a29 100644 --- a/libavcodec/vaapi_encode.h +++ b/libavcodec/vaapi_encode.h @@ -35,8 +35,6 @@ enum { MAX_CONFIG_ATTRIBUTES = 4, MAX_GLOBAL_PARAMS = 4, MAX_PICTURE_REFERENCES = 2, - MAX_PICTURE_SLICES = 112, - MAX_PARAM_BUFFERS = 128, MAX_REORDER_DELAY = 16, MAX_PARAM_BUFFER_SIZE = 1024, }; @@ -73,7 +71,7 @@ typedef struct VAAPIEncodePicture { VASurfaceID recon_surface; int nb_param_buffers; - VABufferID param_buffers[MAX_PARAM_BUFFERS]; + VABufferID *param_buffers; AVBufferRef *output_buffer_ref; VABufferID output_buffer; @@ -85,7 +83,7 @@ typedef struct VAAPIEncodePicture { struct VAAPIEncodePicture *refs[MAX_PICTURE_REFERENCES]; int nb_slices; - VAAPIEncodeSlice *slices[MAX_PICTURE_SLICES]; + VAAPIEncodeSlice *slices; } VAAPIEncodePicture; typedef struct VAAPIEncodeContext { From b264810ef7a3fcd7cfc8e232877cfb2fdf7954f6 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 14 May 2017 15:47:36 +0100 Subject: [PATCH 2879/3374] hevc: Add names for reserved NAL unit types While not yet used, these NAL units do already have some defined semantics and are referred to elsewhere. (cherry picked from commit 3daaa4417317ca732fb00476fdb3308d784f87e4) --- libavcodec/hevc.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h index de77d2ac43e58..f0fb919a7f26c 100644 --- a/libavcodec/hevc.h +++ b/libavcodec/hevc.h @@ -35,12 +35,28 @@ enum HEVCNALUnitType { HEVC_NAL_RADL_R = 7, HEVC_NAL_RASL_N = 8, HEVC_NAL_RASL_R = 9, + HEVC_NAL_VCL_N10 = 10, + HEVC_NAL_VCL_R11 = 11, + HEVC_NAL_VCL_N12 = 12, + HEVC_NAL_VCL_R13 = 13, + HEVC_NAL_VCL_N14 = 14, + HEVC_NAL_VCL_R15 = 15, HEVC_NAL_BLA_W_LP = 16, HEVC_NAL_BLA_W_RADL = 17, HEVC_NAL_BLA_N_LP = 18, HEVC_NAL_IDR_W_RADL = 19, HEVC_NAL_IDR_N_LP = 20, HEVC_NAL_CRA_NUT = 21, + HEVC_NAL_IRAP_VCL22 = 22, + HEVC_NAL_IRAP_VCL23 = 23, + HEVC_NAL_RSV_VCL24 = 24, + HEVC_NAL_RSV_VCL25 = 25, + HEVC_NAL_RSV_VCL26 = 26, + HEVC_NAL_RSV_VCL27 = 27, + HEVC_NAL_RSV_VCL28 = 28, + HEVC_NAL_RSV_VCL29 = 29, + HEVC_NAL_RSV_VCL30 = 30, + HEVC_NAL_RSV_VCL31 = 31, HEVC_NAL_VPS = 32, HEVC_NAL_SPS = 33, HEVC_NAL_PPS = 34, From d4fbe99dabe712d1fbda81bc060f325f8937862e Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Tue, 29 Aug 2017 01:33:47 +0200 Subject: [PATCH 2880/3374] lavf/dump: Remove superfluous cast. --- libavformat/dump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/dump.c b/libavformat/dump.c index 8fd58a0dbac9b..77043e3fdbff4 100644 --- a/libavformat/dump.c +++ b/libavformat/dump.c @@ -595,7 +595,7 @@ void av_dump_format(AVFormatContext *ic, int index, } av_log(NULL, AV_LOG_INFO, ", bitrate: "); if (ic->bit_rate) - av_log(NULL, AV_LOG_INFO, "%"PRId64" kb/s", (int64_t)ic->bit_rate / 1000); + av_log(NULL, AV_LOG_INFO, "%"PRId64" kb/s", ic->bit_rate / 1000); else av_log(NULL, AV_LOG_INFO, "N/A"); av_log(NULL, AV_LOG_INFO, "\n"); From 95a6de5674ab8f5116241cfa4bb02a0954b843d8 Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 25 Aug 2017 21:03:00 -0300 Subject: [PATCH 2881/3374] avcodec/snowenc: fix setting motion_est option Remove usage of FF_MPV_COMMON_OPTS, and set SnowContext.motion_est directly. Based on code from svq1enc.c Signed-off-by: James Almer Reviewed-by: Michael Niedermayer --- libavcodec/snow.h | 3 ++- libavcodec/snowenc.c | 11 +++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/libavcodec/snow.h b/libavcodec/snow.h index f7ed1f82e7ce2..41a3bef4dec1b 100644 --- a/libavcodec/snow.h +++ b/libavcodec/snow.h @@ -32,10 +32,11 @@ #include "rangecoder.h" #include "mathops.h" -#define FF_MPV_OFFSET(x) (offsetof(MpegEncContext, x) + offsetof(SnowContext, m)) #include "mpegvideo.h" #include "h264qpel.h" +#define FF_ME_ITER 3 + #define MID_STATE 128 #define MAX_PLANES 4 diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c index e03877a96c676..bb113d0a2b8c2 100644 --- a/libavcodec/snowenc.c +++ b/libavcodec/snowenc.c @@ -33,8 +33,6 @@ #include "mpegvideo.h" #include "h263.h" -#define FF_ME_ITER 50 - static av_cold int encode_init(AVCodecContext *avctx) { SnowContext *s = avctx->priv_data; @@ -86,6 +84,8 @@ FF_ENABLE_DEPRECATION_WARNINGS s->m.avctx = avctx; s->m.bit_rate= avctx->bit_rate; + s->m.lmin = avctx->mb_lmin; + s->m.lmax = avctx->mb_lmax; s->m.me.temp = s->m.me.scratchpad= av_mallocz_array((avctx->width+64), 2*16*2*sizeof(uint8_t)); @@ -1929,8 +1929,11 @@ static av_cold int encode_end(AVCodecContext *avctx) #define OFFSET(x) offsetof(SnowContext, x) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { - FF_MPV_COMMON_OPTS - { "iter", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_ITER }, 0, 0, FF_MPV_OPT_FLAGS, "motion_est" }, + {"motion_est", "motion estimation algorithm", OFFSET(motion_est), AV_OPT_TYPE_INT, {.i64 = FF_ME_EPZS }, FF_ME_ZERO, FF_ME_ITER, VE, "motion_est" }, + { "zero", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_ZERO }, 0, 0, VE, "motion_est" }, + { "epzs", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_EPZS }, 0, 0, VE, "motion_est" }, + { "xone", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_XONE }, 0, 0, VE, "motion_est" }, + { "iter", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_ITER }, 0, 0, VE, "motion_est" }, { "memc_only", "Only do ME/MC (I frames -> ref, P frame -> ME+MC).", OFFSET(memc_only), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, { "no_bitstream", "Skip final bitstream writeout.", OFFSET(no_bitstream), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, { "intra_penalty", "Penalty for intra blocks in block decission", OFFSET(intra_penalty), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, From 6bde475cf2f930ff929517f89f493a2ac4a2c3df Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 31 Jul 2017 13:47:34 +0200 Subject: [PATCH 2882/3374] lavfi/f_streamselect: convert to framesync2. --- libavfilter/Makefile | 4 ++-- libavfilter/f_streamselect.c | 33 +++++++++++++-------------------- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 1d92dc172ca7d..55b6ce933ac4e 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -67,7 +67,7 @@ OBJS-$(CONFIG_ASHOWINFO_FILTER) += af_ashowinfo.o OBJS-$(CONFIG_ASIDEDATA_FILTER) += f_sidedata.o OBJS-$(CONFIG_ASPLIT_FILTER) += split.o OBJS-$(CONFIG_ASTATS_FILTER) += af_astats.o -OBJS-$(CONFIG_ASTREAMSELECT_FILTER) += f_streamselect.o +OBJS-$(CONFIG_ASTREAMSELECT_FILTER) += f_streamselect.o framesync2.o OBJS-$(CONFIG_ATEMPO_FILTER) += af_atempo.o OBJS-$(CONFIG_ATRIM_FILTER) += trim.o OBJS-$(CONFIG_AZMQ_FILTER) += f_zmq.o @@ -303,7 +303,7 @@ OBJS-$(CONFIG_SPLIT_FILTER) += split.o OBJS-$(CONFIG_SPP_FILTER) += vf_spp.o OBJS-$(CONFIG_SSIM_FILTER) += vf_ssim.o dualinput.o framesync.o OBJS-$(CONFIG_STEREO3D_FILTER) += vf_stereo3d.o -OBJS-$(CONFIG_STREAMSELECT_FILTER) += f_streamselect.o +OBJS-$(CONFIG_STREAMSELECT_FILTER) += f_streamselect.o framesync2.o OBJS-$(CONFIG_SUBTITLES_FILTER) += vf_subtitles.o OBJS-$(CONFIG_SUPER2XSAI_FILTER) += vf_super2xsai.o OBJS-$(CONFIG_SWAPRECT_FILTER) += vf_swaprect.o diff --git a/libavfilter/f_streamselect.c b/libavfilter/f_streamselect.c index 1a517bfc95821..10607de9b89ae 100644 --- a/libavfilter/f_streamselect.c +++ b/libavfilter/f_streamselect.c @@ -22,7 +22,7 @@ #include "avfilter.h" #include "audio.h" #include "formats.h" -#include "framesync.h" +#include "framesync2.h" #include "internal.h" #include "video.h" @@ -48,12 +48,6 @@ static const AVOption streamselect_options[] = { AVFILTER_DEFINE_CLASS(streamselect); -static int filter_frame(AVFilterLink *inlink, AVFrame *in) -{ - StreamSelectContext *s = inlink->dst->priv; - return ff_framesync_filter_frame(&s->fs, inlink, in); -} - static int process_frame(FFFrameSync *fs) { AVFilterContext *ctx = fs->parent; @@ -62,7 +56,7 @@ static int process_frame(FFFrameSync *fs) int i, j, ret = 0; for (i = 0; i < ctx->nb_inputs; i++) { - if ((ret = ff_framesync_get_frame(&s->fs, i, &in[i], 0)) < 0) + if ((ret = ff_framesync2_get_frame(&s->fs, i, &in[i], 0)) < 0) return ret; } @@ -90,10 +84,10 @@ static int process_frame(FFFrameSync *fs) return ret; } -static int request_frame(AVFilterLink *outlink) +static int activate(AVFilterContext *ctx) { - StreamSelectContext *s = outlink->src->priv; - return ff_framesync_request_frame(&s->fs, outlink); + StreamSelectContext *s = ctx->priv; + return ff_framesync2_activate(&s->fs); } static int config_output(AVFilterLink *outlink) @@ -130,7 +124,7 @@ static int config_output(AVFilterLink *outlink) if (s->fs.opaque == s) return 0; - if ((ret = ff_framesync_init(&s->fs, ctx, ctx->nb_inputs)) < 0) + if ((ret = ff_framesync2_init(&s->fs, ctx, ctx->nb_inputs)) < 0) return ret; in = s->fs.in; @@ -148,12 +142,11 @@ static int config_output(AVFilterLink *outlink) if (!s->frames) return AVERROR(ENOMEM); - return ff_framesync_configure(&s->fs); + return ff_framesync2_configure(&s->fs); } -static int parse_definition(AVFilterContext *ctx, int nb_pads, void *filter_frame, int is_audio) +static int parse_definition(AVFilterContext *ctx, int nb_pads, int is_input, int is_audio) { - const int is_input = !!filter_frame; const char *padtype = is_input ? "in" : "out"; int i = 0, ret = 0; @@ -169,11 +162,9 @@ static int parse_definition(AVFilterContext *ctx, int nb_pads, void *filter_fram av_log(ctx, AV_LOG_DEBUG, "Add %s pad %s\n", padtype, pad.name); if (is_input) { - pad.filter_frame = filter_frame; ret = ff_insert_inpad(ctx, i, &pad); } else { pad.config_props = config_output; - pad.request_frame = request_frame; ret = ff_insert_outpad(ctx, i, &pad); } @@ -281,8 +272,8 @@ static av_cold int init(AVFilterContext *ctx) if (!s->last_pts) return AVERROR(ENOMEM); - if ((ret = parse_definition(ctx, s->nb_inputs, filter_frame, s->is_audio)) < 0 || - (ret = parse_definition(ctx, nb_outputs, NULL, s->is_audio)) < 0) + if ((ret = parse_definition(ctx, s->nb_inputs, 1, s->is_audio)) < 0 || + (ret = parse_definition(ctx, nb_outputs, 0, s->is_audio)) < 0) return ret; av_log(ctx, AV_LOG_DEBUG, "Configured with %d inpad and %d outpad\n", @@ -298,7 +289,7 @@ static av_cold void uninit(AVFilterContext *ctx) av_freep(&s->last_pts); av_freep(&s->map); av_freep(&s->frames); - ff_framesync_uninit(&s->fs); + ff_framesync2_uninit(&s->fs); } static int query_formats(AVFilterContext *ctx) @@ -332,6 +323,7 @@ AVFilter ff_vf_streamselect = { .query_formats = query_formats, .process_command = process_command, .uninit = uninit, + .activate = activate, .priv_size = sizeof(StreamSelectContext), .priv_class = &streamselect_class, .flags = AVFILTER_FLAG_DYNAMIC_INPUTS | AVFILTER_FLAG_DYNAMIC_OUTPUTS, @@ -347,6 +339,7 @@ AVFilter ff_af_astreamselect = { .query_formats = query_formats, .process_command = process_command, .uninit = uninit, + .activate = activate, .priv_size = sizeof(StreamSelectContext), .priv_class = &astreamselect_class, .flags = AVFILTER_FLAG_DYNAMIC_INPUTS | AVFILTER_FLAG_DYNAMIC_OUTPUTS, From 0ae8df4109da6bae77bef24fc889eceadd98c6b7 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 17 Jul 2017 20:45:52 +0200 Subject: [PATCH 2883/3374] lavfi/framesync2: add dualinput helper functions. --- libavfilter/framesync2.c | 99 +++++++++++++++++++++++++++++++--------- libavfilter/framesync2.h | 25 ++++++++++ 2 files changed, 103 insertions(+), 21 deletions(-) diff --git a/libavfilter/framesync2.c b/libavfilter/framesync2.c index 0e9f6f210c6ef..0f78a1733bead 100644 --- a/libavfilter/framesync2.c +++ b/libavfilter/framesync2.c @@ -46,6 +46,8 @@ enum { STATE_EOF, }; +static int consume_from_fifos(FFFrameSync *fs); + int ff_framesync2_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in) { /* For filters with several outputs, we will not be able to assume which @@ -127,30 +129,20 @@ int ff_framesync2_configure(FFFrameSync *fs) return 0; } -static void framesync_advance(FFFrameSync *fs) +static int framesync_advance(FFFrameSync *fs) { - int latest; unsigned i; int64_t pts; + int ret; - if (fs->eof) - return; - while (!fs->frame_ready) { - latest = -1; - for (i = 0; i < fs->nb_in; i++) { - if (!fs->in[i].have_next) { - if (latest < 0 || fs->in[i].pts < fs->in[latest].pts) - latest = i; - } - } - if (latest >= 0) { - fs->in_request = latest; - break; - } + while (!(fs->frame_ready || fs->eof)) { + ret = consume_from_fifos(fs); + if (ret <= 0) + return ret; - pts = fs->in[0].pts_next; - for (i = 1; i < fs->nb_in; i++) - if (fs->in[i].pts_next < pts) + pts = INT64_MAX; + for (i = 0; i < fs->nb_in; i++) + if (fs->in[i].have_next && fs->in[i].pts_next < pts) pts = fs->in[i].pts_next; if (pts == INT64_MAX) { framesync_eof(fs); @@ -181,6 +173,7 @@ static void framesync_advance(FFFrameSync *fs) fs->frame_ready = 0; fs->pts = pts; } + return 0; } static int64_t framesync_pts_extrapolate(FFFrameSync *fs, unsigned in, @@ -264,7 +257,7 @@ void ff_framesync2_uninit(FFFrameSync *fs) av_freep(&fs->in); } -int ff_framesync2_activate(FFFrameSync *fs) +static int consume_from_fifos(FFFrameSync *fs) { AVFilterContext *ctx = fs->parent; AVFrame *frame = NULL; @@ -300,8 +293,16 @@ int ff_framesync2_activate(FFFrameSync *fs) ff_inlink_request_frame(ctx->inputs[i]); return 0; } + return 1; +} - framesync_advance(fs); +int ff_framesync2_activate(FFFrameSync *fs) +{ + int ret; + + ret = framesync_advance(fs); + if (ret < 0) + return ret; if (fs->eof || !fs->frame_ready) return 0; ret = fs->on_event(fs); @@ -311,3 +312,59 @@ int ff_framesync2_activate(FFFrameSync *fs) return 0; } + +int ff_framesync2_init_dualinput(FFFrameSync *fs, AVFilterContext *parent) +{ + int ret; + + ret = ff_framesync2_init(fs, parent, 2); + if (ret < 0) + return ret; + fs->in[0].time_base = parent->inputs[0]->time_base; + fs->in[1].time_base = parent->inputs[1]->time_base; + fs->in[0].sync = 2; + fs->in[0].before = EXT_STOP; + fs->in[0].after = EXT_INFINITY; + fs->in[1].sync = 1; + fs->in[1].before = EXT_NULL; + fs->in[1].after = EXT_INFINITY; + return 0; +} + +int ff_framesync2_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1) +{ + AVFilterContext *ctx = fs->parent; + AVFrame *mainpic = NULL, *secondpic = NULL; + int ret = 0; + + if ((ret = ff_framesync2_get_frame(fs, 0, &mainpic, 1)) < 0 || + (ret = ff_framesync2_get_frame(fs, 1, &secondpic, 0)) < 0) { + av_frame_free(&mainpic); + return ret; + } + if (ret < 0) + return ret; + av_assert0(mainpic); + mainpic->pts = av_rescale_q(fs->pts, fs->time_base, ctx->outputs[0]->time_base); + if (ctx->is_disabled) + secondpic = NULL; + *f0 = mainpic; + *f1 = secondpic; + return 0; +} + +int ff_framesync2_dualinput_get_writable(FFFrameSync *fs, AVFrame **f0, AVFrame **f1) +{ + int ret; + + ret = ff_framesync2_dualinput_get(fs, f0, f1); + if (ret < 0) + return ret; + ret = ff_inlink_make_frame_writable(fs->parent->inputs[0], f0); + if (ret < 0) { + av_frame_free(f0); + av_frame_free(f1); + return ret; + } + return 0; +} diff --git a/libavfilter/framesync2.h b/libavfilter/framesync2.h index 2b37636ebba11..9a54b2b701b13 100644 --- a/libavfilter/framesync2.h +++ b/libavfilter/framesync2.h @@ -245,4 +245,29 @@ int ff_framesync2_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, */ int ff_framesync2_activate(FFFrameSync *fs); +/** + * Initialize a frame sync structure for dualinput. + * + * Compared to generic framesync, dualinput assumes the first input is the + * main one and the filtering is performed on it. The first input will be + * the only one with sync set and generic timeline support will just pass it + * unchanged when disabled. + * + * Equivalent to ff_framesync2_init(fs, parent, 2) then setting the time + * base, sync and ext modes on the inputs. + */ +int ff_framesync2_init_dualinput(FFFrameSync *fs, AVFilterContext *parent); + +/** + * @param f0 used to return the main frame + * @param f1 used to return the second frame, or NULL if disabled + * @return >=0 for success or AVERROR code + */ +int ff_framesync2_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1); + +/** + * Same as ff_framesync2_dualinput_get(), but make sure that f0 is writable. + */ +int ff_framesync2_dualinput_get_writable(FFFrameSync *fs, AVFrame **f0, AVFrame **f1); + #endif /* AVFILTER_FRAMESYNC2_H */ From 19804024d5b26e9568ce2f21f15c6664717006cd Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 17 Jul 2017 20:46:31 +0200 Subject: [PATCH 2884/3374] lavfi/vf_overlay: move to framesync2. --- libavfilter/Makefile | 2 +- libavfilter/vf_overlay.c | 70 ++++++++++++++++++++++------------------ 2 files changed, 39 insertions(+), 33 deletions(-) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 55b6ce933ac4e..e5fe47f2ccbfb 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -245,7 +245,7 @@ OBJS-$(CONFIG_OCR_FILTER) += vf_ocr.o OBJS-$(CONFIG_OCV_FILTER) += vf_libopencv.o OBJS-$(CONFIG_OPENCL) += deshake_opencl.o unsharp_opencl.o OBJS-$(CONFIG_OSCILLOSCOPE_FILTER) += vf_datascope.o -OBJS-$(CONFIG_OVERLAY_FILTER) += vf_overlay.o dualinput.o framesync.o +OBJS-$(CONFIG_OVERLAY_FILTER) += vf_overlay.o framesync2.o OBJS-$(CONFIG_OWDENOISE_FILTER) += vf_owdenoise.o OBJS-$(CONFIG_PAD_FILTER) += vf_pad.o OBJS-$(CONFIG_PALETTEGEN_FILTER) += vf_palettegen.o diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c index 52f09fae1f48c..34e652bdd0eec 100644 --- a/libavfilter/vf_overlay.c +++ b/libavfilter/vf_overlay.c @@ -36,8 +36,8 @@ #include "libavutil/opt.h" #include "libavutil/timestamp.h" #include "internal.h" -#include "dualinput.h" #include "drawutils.h" +#include "framesync2.h" #include "video.h" static const char *const var_names[] = { @@ -121,7 +121,7 @@ typedef struct OverlayContext { int format; ///< OverlayFormat int eval_mode; ///< EvalMode - FFDualInputContext dinput; + FFFrameSync fs; int main_pix_step[4]; ///< steps per pixel for each plane of the main output int overlay_pix_step[4]; ///< steps per pixel for each plane of the overlay @@ -132,6 +132,8 @@ typedef struct OverlayContext { char *x_expr, *y_expr; int eof_action; ///< action to take on EOF from source + int opt_shortest; + int opt_repeatlast; AVExpr *x_pexpr, *y_pexpr; @@ -142,7 +144,7 @@ static av_cold void uninit(AVFilterContext *ctx) { OverlayContext *s = ctx->priv; - ff_dualinput_uninit(&s->dinput); + ff_framesync2_uninit(&s->fs); av_expr_free(s->x_pexpr); s->x_pexpr = NULL; av_expr_free(s->y_pexpr); s->y_pexpr = NULL; } @@ -390,14 +392,20 @@ static int config_output(AVFilterLink *outlink) OverlayContext *s = ctx->priv; int ret; - if ((ret = ff_dualinput_init(ctx, &s->dinput)) < 0) + if ((ret = ff_framesync2_init_dualinput(&s->fs, ctx)) < 0) return ret; + if (s->opt_shortest) + s->fs.in[0].after = s->fs.in[1].after = EXT_STOP; + if (!s->opt_repeatlast) { + s->fs.in[1].after = EXT_NULL; + s->fs.in[1].sync = 0; + } outlink->w = ctx->inputs[MAIN]->w; outlink->h = ctx->inputs[MAIN]->h; outlink->time_base = ctx->inputs[MAIN]->time_base; - return 0; + return ff_framesync2_configure(&s->fs); } // divide by 255 and round to nearest @@ -770,11 +778,19 @@ static int config_input_main(AVFilterLink *inlink) return 0; } -static AVFrame *do_blend(AVFilterContext *ctx, AVFrame *mainpic, - const AVFrame *second) +static int do_blend(FFFrameSync *fs) { + AVFilterContext *ctx = fs->parent; + AVFrame *mainpic, *second; OverlayContext *s = ctx->priv; AVFilterLink *inlink = ctx->inputs[0]; + int ret; + + ret = ff_framesync2_dualinput_get_writable(fs, &mainpic, &second); + if (ret < 0) + return ret; + if (!second) + return ff_filter_frame(ctx->outputs[0], mainpic); if (s->eval_mode == EVAL_MODE_FRAME) { int64_t pos = mainpic->pkt_pos; @@ -799,39 +815,32 @@ static AVFrame *do_blend(AVFilterContext *ctx, AVFrame *mainpic, if (s->x < mainpic->width && s->x + second->width >= 0 || s->y < mainpic->height && s->y + second->height >= 0) s->blend_image(ctx, mainpic, second, s->x, s->y); - return mainpic; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) -{ - OverlayContext *s = inlink->dst->priv; - av_log(inlink->dst, AV_LOG_DEBUG, "Incoming frame (time:%s) from link #%d\n", av_ts2timestr(inpicref->pts, &inlink->time_base), FF_INLINK_IDX(inlink)); - return ff_dualinput_filter_frame(&s->dinput, inlink, inpicref); -} - -static int request_frame(AVFilterLink *outlink) -{ - OverlayContext *s = outlink->src->priv; - return ff_dualinput_request_frame(&s->dinput, outlink); + return ff_filter_frame(ctx->outputs[0], mainpic); } static av_cold int init(AVFilterContext *ctx) { OverlayContext *s = ctx->priv; - if (!s->dinput.repeatlast || s->eof_action == EOF_ACTION_PASS) { - s->dinput.repeatlast = 0; + if (!s->opt_repeatlast || s->eof_action == EOF_ACTION_PASS) { + s->opt_repeatlast = 0; s->eof_action = EOF_ACTION_PASS; } - if (s->dinput.shortest || s->eof_action == EOF_ACTION_ENDALL) { - s->dinput.shortest = 1; + if (s->opt_shortest || s->eof_action == EOF_ACTION_ENDALL) { + s->opt_shortest = 1; s->eof_action = EOF_ACTION_ENDALL; } - s->dinput.process = do_blend; + s->fs.on_event = do_blend; return 0; } +static int activate(AVFilterContext *ctx) +{ + OverlayContext *s = ctx->priv; + return ff_framesync2_activate(&s->fs); +} + #define OFFSET(x) offsetof(OverlayContext, x) #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM @@ -847,7 +856,7 @@ static const AVOption overlay_options[] = { { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_FRAME}, 0, EVAL_MODE_NB-1, FLAGS, "eval" }, { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" }, { "frame", "eval expressions per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" }, - { "shortest", "force termination when the shortest input terminates", OFFSET(dinput.shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, + { "shortest", "force termination when the shortest input terminates", OFFSET(opt_shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, { "format", "set output format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=OVERLAY_FORMAT_YUV420}, 0, OVERLAY_FORMAT_NB-1, FLAGS, "format" }, { "yuv420", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420}, .flags = FLAGS, .unit = "format" }, { "yuv422", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV422}, .flags = FLAGS, .unit = "format" }, @@ -855,7 +864,7 @@ static const AVOption overlay_options[] = { { "rgb", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_RGB}, .flags = FLAGS, .unit = "format" }, { "gbrp", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_GBRP}, .flags = FLAGS, .unit = "format" }, { "auto", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_AUTO}, .flags = FLAGS, .unit = "format" }, - { "repeatlast", "repeat overlay of the last overlay frame", OFFSET(dinput.repeatlast), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS }, + { "repeatlast", "repeat overlay of the last overlay frame", OFFSET(opt_repeatlast), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS }, { NULL } }; @@ -866,14 +875,11 @@ static const AVFilterPad avfilter_vf_overlay_inputs[] = { .name = "main", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_input_main, - .filter_frame = filter_frame, - .needs_writable = 1, }, { .name = "overlay", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_input_overlay, - .filter_frame = filter_frame, }, { NULL } }; @@ -883,7 +889,6 @@ static const AVFilterPad avfilter_vf_overlay_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_output, - .request_frame = request_frame, }, { NULL } }; @@ -896,6 +901,7 @@ AVFilter ff_vf_overlay = { .priv_size = sizeof(OverlayContext), .priv_class = &overlay_class, .query_formats = query_formats, + .activate = activate, .process_command = process_command, .inputs = avfilter_vf_overlay_inputs, .outputs = avfilter_vf_overlay_outputs, From f8d7b5febba075035a94de5d7d1dc9083ad2f3ed Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 31 Jul 2017 00:29:01 +0200 Subject: [PATCH 2885/3374] lavfi: add a preinit callback to filters. It is necessary for filters with child objects, to set the class and default options values. --- libavfilter/avfilter.c | 8 ++++++++ libavfilter/avfilter.h | 15 +++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 185ba8df00a3a..dcd975e104d00 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -692,6 +692,7 @@ static int default_execute(AVFilterContext *ctx, avfilter_action_func *func, voi AVFilterContext *ff_filter_alloc(const AVFilter *filter, const char *inst_name) { AVFilterContext *ret; + int preinited = 0; if (!filter) return NULL; @@ -708,6 +709,11 @@ AVFilterContext *ff_filter_alloc(const AVFilter *filter, const char *inst_name) if (!ret->priv) goto err; } + if (filter->preinit) { + if (filter->preinit(ret) < 0) + goto err; + preinited = 1; + } av_opt_set_defaults(ret); if (filter->priv_class) { @@ -745,6 +751,8 @@ AVFilterContext *ff_filter_alloc(const AVFilter *filter, const char *inst_name) return ret; err: + if (preinited) + filter->uninit(ret); av_freep(&ret->inputs); av_freep(&ret->input_pads); ret->nb_inputs = 0; diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index 60662c19acaaf..73a723d583311 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -194,6 +194,21 @@ typedef struct AVFilter { ***************************************************************** */ + /** + * Filter pre-initialization function + * + * This callback will be called immediately after the filter context is + * allocated, to allow allocating and initing sub-objects. + * + * If this callback is not NULL, the uninit callback will be called on + * allocation failure. + * + * @return 0 on success, + * AVERROR code on failure (but the code will be + * dropped and treated as ENOMEM by the calling code) + */ + int (*preinit)(AVFilterContext *ctx); + /** * Filter initialization function. * From dfa3aaa22a2bac6c98ed0eb4a42cd93347d9a954 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Sun, 30 Jul 2017 16:57:12 +0200 Subject: [PATCH 2886/3374] lavfi: search options on child objects. The child objects must be allocated and inited in the preinit() callback. --- libavfilter/avfilter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index dcd975e104d00..6a97456054205 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -897,7 +897,7 @@ static int process_options(AVFilterContext *ctx, AVDictionary **options, } } else { av_dict_set(options, key, value, 0); - if ((ret = av_opt_set(ctx->priv, key, value, 0)) < 0) { + if ((ret = av_opt_set(ctx->priv, key, value, AV_OPT_SEARCH_CHILDREN)) < 0) { if (!av_opt_find(ctx->priv, key, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) { if (ret == AVERROR_OPTION_NOT_FOUND) av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key); @@ -948,7 +948,7 @@ int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options) } if (ctx->filter->priv_class) { - ret = av_opt_set_dict(ctx->priv, options); + ret = av_opt_set_dict2(ctx->priv, options, AV_OPT_SEARCH_CHILDREN); if (ret < 0) { av_log(ctx, AV_LOG_ERROR, "Error applying options to the filter.\n"); return ret; From 05a23b2565849c9ad96526c9e2ccdb9272add565 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Sun, 30 Jul 2017 16:58:49 +0200 Subject: [PATCH 2887/3374] lavfi/framesync2: add common options. Also add functions and macros to help filters chaining these options to their own. --- libavfilter/framesync2.c | 55 ++++++++++++++++++++++++++++++++++++++-- libavfilter/framesync2.h | 44 +++++++++++++++++++++++++++++++- 2 files changed, 96 insertions(+), 3 deletions(-) diff --git a/libavfilter/framesync2.c b/libavfilter/framesync2.c index 0f78a1733bead..fae06aa1f5bf8 100644 --- a/libavfilter/framesync2.c +++ b/libavfilter/framesync2.c @@ -19,24 +19,43 @@ */ #include "libavutil/avassert.h" +#include "libavutil/opt.h" #include "avfilter.h" #include "filters.h" #include "framesync2.h" #include "internal.h" #define OFFSET(member) offsetof(FFFrameSync, member) +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM + +enum EOFAction { + EOF_ACTION_REPEAT, + EOF_ACTION_ENDALL, + EOF_ACTION_PASS +}; static const char *framesync_name(void *ptr) { return "framesync"; } +static const AVOption framesync_options[] = { + { "eof_action", "Action to take when encountering EOF from secondary input ", + OFFSET(opt_eof_action), AV_OPT_TYPE_INT, { .i64 = EOF_ACTION_REPEAT }, + EOF_ACTION_REPEAT, EOF_ACTION_PASS, .flags = FLAGS, "eof_action" }, + { "repeat", "Repeat the previous frame.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_REPEAT }, .flags = FLAGS, "eof_action" }, + { "endall", "End both streams.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_ENDALL }, .flags = FLAGS, "eof_action" }, + { "pass", "Pass through the main input.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_PASS }, .flags = FLAGS, "eof_action" }, + { "shortest", "force termination when the shortest input terminates", OFFSET(opt_shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, + { "repeatlast", "repeat overlay of the last overlay frame", OFFSET(opt_repeatlast), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS }, + { NULL } +}; static const AVClass framesync_class = { .version = LIBAVUTIL_VERSION_INT, .class_name = "framesync", .item_name = framesync_name, .category = AV_CLASS_CATEGORY_FILTER, - .option = NULL, + .option = framesync_options, .parent_log_context_offset = OFFSET(parent), }; @@ -48,6 +67,19 @@ enum { static int consume_from_fifos(FFFrameSync *fs); +const AVClass *framesync2_get_class(void) +{ + return &framesync_class; +} + +void ff_framesync2_preinit(FFFrameSync *fs) +{ + if (fs->class) + return; + fs->class = &framesync_class; + av_opt_set_defaults(fs); +} + int ff_framesync2_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in) { /* For filters with several outputs, we will not be able to assume which @@ -55,7 +87,7 @@ int ff_framesync2_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in) ff_outlink_set_status(). To be designed when needed. */ av_assert0(parent->nb_outputs == 1); - fs->class = &framesync_class; + ff_framesync2_preinit(fs); fs->parent = parent; fs->nb_in = nb_in; @@ -93,6 +125,25 @@ int ff_framesync2_configure(FFFrameSync *fs) unsigned i; int64_t gcd, lcm; + if (!fs->opt_repeatlast || fs->opt_eof_action == EOF_ACTION_PASS) { + fs->opt_repeatlast = 0; + fs->opt_eof_action = EOF_ACTION_PASS; + } + if (fs->opt_shortest || fs->opt_eof_action == EOF_ACTION_ENDALL) { + fs->opt_shortest = 1; + fs->opt_eof_action = EOF_ACTION_ENDALL; + } + if (fs->opt_shortest) { + for (i = 0; i < fs->nb_in; i++) + fs->in[i].after = EXT_STOP; + } + if (!fs->opt_repeatlast) { + for (i = 1; i < fs->nb_in; i++) { + fs->in[i].after = EXT_NULL; + fs->in[i].sync = 0; + } + } + if (!fs->time_base.num) { for (i = 0; i < fs->nb_in; i++) { if (fs->in[i].sync) { diff --git a/libavfilter/framesync2.h b/libavfilter/framesync2.h index 9a54b2b701b13..745e896bc84af 100644 --- a/libavfilter/framesync2.h +++ b/libavfilter/framesync2.h @@ -196,12 +196,30 @@ typedef struct FFFrameSync { */ FFFrameSyncIn *in; + int opt_repeatlast; + int opt_shortest; + int opt_eof_action; + } FFFrameSync; /** - * Initialize a frame sync structure. + * Get the class for the framesync2 object. + */ +const AVClass *framesync2_get_class(void); + +/** + * Pre-initialize a frame sync structure. * + * It sets the class pointer and inits the options to their default values. * The entire structure is expected to be already set to 0. + * This step is optional, but necessary to use the options. + */ +void ff_framesync2_preinit(FFFrameSync *fs); + +/** + * Initialize a frame sync structure. + * + * The entire structure is expected to be already set to 0 or preinited. * * @param fs frame sync structure to initialize * @param parent parent AVFilterContext object @@ -270,4 +288,28 @@ int ff_framesync2_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1); */ int ff_framesync2_dualinput_get_writable(FFFrameSync *fs, AVFrame **f0, AVFrame **f1); +#define FRAMESYNC_DEFINE_CLASS(name, context, field) \ +static int name##_framesync_preinit(AVFilterContext *ctx) { \ + context *s = ctx->priv; \ + ff_framesync2_preinit(&s->field); \ + return 0; \ +} \ +static const AVClass *name##_child_class_next(const AVClass *prev) { \ + return prev ? NULL : framesync2_get_class(); \ +} \ +static void *name##_child_next(void *obj, void *prev) { \ + context *s = obj; \ + s->fs.class = framesync2_get_class(); /* FIXME */ \ + return prev ? NULL : &s->field; \ +} \ +static const AVClass name##_class = { \ + .class_name = #name, \ + .item_name = av_default_item_name, \ + .option = name##_options, \ + .version = LIBAVUTIL_VERSION_INT, \ + .category = AV_CLASS_CATEGORY_FILTER, \ + .child_class_next = name##_child_class_next, \ + .child_next = name##_child_next, \ +} + #endif /* AVFILTER_FRAMESYNC2_H */ From 878fd0545a930391baf1ded32550af1d1d2e8c88 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Sun, 30 Jul 2017 17:00:00 +0200 Subject: [PATCH 2888/3374] lavfi/vf_overlay: use framesync2 options. --- libavfilter/vf_overlay.c | 45 ++++------------------------------------ 1 file changed, 4 insertions(+), 41 deletions(-) diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c index 34e652bdd0eec..4166e7c095af0 100644 --- a/libavfilter/vf_overlay.c +++ b/libavfilter/vf_overlay.c @@ -70,16 +70,6 @@ enum var_name { VAR_VARS_NB }; -enum EOFAction { - EOF_ACTION_REPEAT, - EOF_ACTION_ENDALL, - EOF_ACTION_PASS -}; - -static const char * const eof_action_str[] = { - "repeat", "endall", "pass" -}; - #define MAIN 0 #define OVERLAY 1 @@ -131,10 +121,6 @@ typedef struct OverlayContext { double var_values[VAR_VARS_NB]; char *x_expr, *y_expr; - int eof_action; ///< action to take on EOF from source - int opt_shortest; - int opt_repeatlast; - AVExpr *x_pexpr, *y_pexpr; void (*blend_image)(AVFilterContext *ctx, AVFrame *dst, const AVFrame *src, int x, int y); @@ -377,12 +363,11 @@ static int config_input_overlay(AVFilterLink *inlink) } av_log(ctx, AV_LOG_VERBOSE, - "main w:%d h:%d fmt:%s overlay w:%d h:%d fmt:%s eof_action:%s\n", + "main w:%d h:%d fmt:%s overlay w:%d h:%d fmt:%s\n", ctx->inputs[MAIN]->w, ctx->inputs[MAIN]->h, av_get_pix_fmt_name(ctx->inputs[MAIN]->format), ctx->inputs[OVERLAY]->w, ctx->inputs[OVERLAY]->h, - av_get_pix_fmt_name(ctx->inputs[OVERLAY]->format), - eof_action_str[s->eof_action]); + av_get_pix_fmt_name(ctx->inputs[OVERLAY]->format)); return 0; } @@ -394,12 +379,6 @@ static int config_output(AVFilterLink *outlink) if ((ret = ff_framesync2_init_dualinput(&s->fs, ctx)) < 0) return ret; - if (s->opt_shortest) - s->fs.in[0].after = s->fs.in[1].after = EXT_STOP; - if (!s->opt_repeatlast) { - s->fs.in[1].after = EXT_NULL; - s->fs.in[1].sync = 0; - } outlink->w = ctx->inputs[MAIN]->w; outlink->h = ctx->inputs[MAIN]->h; @@ -822,15 +801,6 @@ static av_cold int init(AVFilterContext *ctx) { OverlayContext *s = ctx->priv; - if (!s->opt_repeatlast || s->eof_action == EOF_ACTION_PASS) { - s->opt_repeatlast = 0; - s->eof_action = EOF_ACTION_PASS; - } - if (s->opt_shortest || s->eof_action == EOF_ACTION_ENDALL) { - s->opt_shortest = 1; - s->eof_action = EOF_ACTION_ENDALL; - } - s->fs.on_event = do_blend; return 0; } @@ -847,16 +817,9 @@ static int activate(AVFilterContext *ctx) static const AVOption overlay_options[] = { { "x", "set the x expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str = "0"}, CHAR_MIN, CHAR_MAX, FLAGS }, { "y", "set the y expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str = "0"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "eof_action", "Action to take when encountering EOF from secondary input ", - OFFSET(eof_action), AV_OPT_TYPE_INT, { .i64 = EOF_ACTION_REPEAT }, - EOF_ACTION_REPEAT, EOF_ACTION_PASS, .flags = FLAGS, "eof_action" }, - { "repeat", "Repeat the previous frame.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_REPEAT }, .flags = FLAGS, "eof_action" }, - { "endall", "End both streams.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_ENDALL }, .flags = FLAGS, "eof_action" }, - { "pass", "Pass through the main input.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_PASS }, .flags = FLAGS, "eof_action" }, { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_FRAME}, 0, EVAL_MODE_NB-1, FLAGS, "eval" }, { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" }, { "frame", "eval expressions per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" }, - { "shortest", "force termination when the shortest input terminates", OFFSET(opt_shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, { "format", "set output format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=OVERLAY_FORMAT_YUV420}, 0, OVERLAY_FORMAT_NB-1, FLAGS, "format" }, { "yuv420", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420}, .flags = FLAGS, .unit = "format" }, { "yuv422", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV422}, .flags = FLAGS, .unit = "format" }, @@ -864,11 +827,10 @@ static const AVOption overlay_options[] = { { "rgb", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_RGB}, .flags = FLAGS, .unit = "format" }, { "gbrp", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_GBRP}, .flags = FLAGS, .unit = "format" }, { "auto", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_AUTO}, .flags = FLAGS, .unit = "format" }, - { "repeatlast", "repeat overlay of the last overlay frame", OFFSET(opt_repeatlast), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS }, { NULL } }; -AVFILTER_DEFINE_CLASS(overlay); +FRAMESYNC_DEFINE_CLASS(overlay, OverlayContext, fs); static const AVFilterPad avfilter_vf_overlay_inputs[] = { { @@ -896,6 +858,7 @@ static const AVFilterPad avfilter_vf_overlay_outputs[] = { AVFilter ff_vf_overlay = { .name = "overlay", .description = NULL_IF_CONFIG_SMALL("Overlay a video source on top of the input."), + .preinit = overlay_framesync_preinit, .init = init, .uninit = uninit, .priv_size = sizeof(OverlayContext), From c1d8d33a51e3ef36e6ce2e8428c5c33cfae5b02d Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 31 Jul 2017 11:02:14 +0200 Subject: [PATCH 2889/3374] lavfi/vf_blend: convert to framesync2. --- libavfilter/Makefile | 4 ++-- libavfilter/vf_blend.c | 48 ++++++++++++++++++++++++------------------ 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index e5fe47f2ccbfb..57dd395d6a46a 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -136,7 +136,7 @@ OBJS-$(CONFIG_BENCH_FILTER) += f_bench.o OBJS-$(CONFIG_BITPLANENOISE_FILTER) += vf_bitplanenoise.o OBJS-$(CONFIG_BLACKDETECT_FILTER) += vf_blackdetect.o OBJS-$(CONFIG_BLACKFRAME_FILTER) += vf_blackframe.o -OBJS-$(CONFIG_BLEND_FILTER) += vf_blend.o dualinput.o framesync.o +OBJS-$(CONFIG_BLEND_FILTER) += vf_blend.o framesync2.o OBJS-$(CONFIG_BOXBLUR_FILTER) += vf_boxblur.o OBJS-$(CONFIG_BWDIF_FILTER) += vf_bwdif.o OBJS-$(CONFIG_CHROMAKEY_FILTER) += vf_chromakey.o @@ -308,7 +308,7 @@ OBJS-$(CONFIG_SUBTITLES_FILTER) += vf_subtitles.o OBJS-$(CONFIG_SUPER2XSAI_FILTER) += vf_super2xsai.o OBJS-$(CONFIG_SWAPRECT_FILTER) += vf_swaprect.o OBJS-$(CONFIG_SWAPUV_FILTER) += vf_swapuv.o -OBJS-$(CONFIG_TBLEND_FILTER) += vf_blend.o dualinput.o framesync.o +OBJS-$(CONFIG_TBLEND_FILTER) += vf_blend.o framesync2.o OBJS-$(CONFIG_TELECINE_FILTER) += vf_telecine.o OBJS-$(CONFIG_THRESHOLD_FILTER) += vf_threshold.o framesync2.o OBJS-$(CONFIG_THUMBNAIL_FILTER) += vf_thumbnail.o diff --git a/libavfilter/vf_blend.c b/libavfilter/vf_blend.c index 109a51fa92130..4939b101509d8 100644 --- a/libavfilter/vf_blend.c +++ b/libavfilter/vf_blend.c @@ -25,8 +25,8 @@ #include "avfilter.h" #include "bufferqueue.h" #include "formats.h" +#include "framesync2.h" #include "internal.h" -#include "dualinput.h" #include "video.h" #include "blend.h" @@ -35,7 +35,7 @@ typedef struct BlendContext { const AVClass *class; - FFDualInputContext dinput; + FFFrameSync fs; int hsub, vsub; ///< chroma subsampling values int nb_planes; char *all_expr; @@ -116,12 +116,10 @@ typedef struct ThreadData { static const AVOption blend_options[] = { COMMON_OPTIONS, - { "shortest", "force termination when the shortest input terminates", OFFSET(dinput.shortest), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, - { "repeatlast", "repeat last bottom frame", OFFSET(dinput.repeatlast), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS }, { NULL } }; -AVFILTER_DEFINE_CLASS(blend); +FRAMESYNC_DEFINE_CLASS(blend, BlendContext, fs); #define COPY(src) \ static void blend_copy ## src(const uint8_t *top, ptrdiff_t top_linesize, \ @@ -407,13 +405,28 @@ static AVFrame *blend_frame(AVFilterContext *ctx, AVFrame *top_buf, return dst_buf; } +static int blend_frame_for_dualinput(FFFrameSync *fs) +{ + AVFilterContext *ctx = fs->parent; + AVFrame *top_buf, *bottom_buf, *dst_buf; + int ret; + + ret = ff_framesync2_dualinput_get(fs, &top_buf, &bottom_buf); + if (ret < 0) + return ret; + if (!bottom_buf) + return ff_filter_frame(ctx->outputs[0], top_buf); + dst_buf = blend_frame(ctx, top_buf, bottom_buf); + return ff_filter_frame(ctx->outputs[0], dst_buf); +} + static av_cold int init(AVFilterContext *ctx) { BlendContext *s = ctx->priv; s->tblend = !strcmp(ctx->filter->name, "tblend"); - s->dinput.process = blend_frame; + s->fs.on_event = blend_frame_for_dualinput; return 0; } @@ -441,7 +454,7 @@ static av_cold void uninit(AVFilterContext *ctx) BlendContext *s = ctx->priv; int i; - ff_dualinput_uninit(&s->dinput); + ff_framesync2_uninit(&s->fs); av_frame_free(&s->prev_frame); for (i = 0; i < FF_ARRAY_ELEMS(s->params); i++) @@ -541,7 +554,7 @@ static int config_output(AVFilterLink *outlink) s->nb_planes = av_pix_fmt_count_planes(toplink->format); if (!s->tblend) - if ((ret = ff_dualinput_init(ctx, &s->dinput)) < 0) + if ((ret = ff_framesync2_init_dualinput(&s->fs, ctx)) < 0) return ret; for (plane = 0; plane < FF_ARRAY_ELEMS(s->params); plane++) { @@ -568,32 +581,24 @@ static int config_output(AVFilterLink *outlink) } } - return 0; + return s->tblend ? 0 : ff_framesync2_configure(&s->fs); } #if CONFIG_BLEND_FILTER -static int request_frame(AVFilterLink *outlink) +static int activate(AVFilterContext *ctx) { - BlendContext *s = outlink->src->priv; - return ff_dualinput_request_frame(&s->dinput, outlink); -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) -{ - BlendContext *s = inlink->dst->priv; - return ff_dualinput_filter_frame(&s->dinput, inlink, buf); + BlendContext *s = ctx->priv; + return ff_framesync2_activate(&s->fs); } static const AVFilterPad blend_inputs[] = { { .name = "top", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, },{ .name = "bottom", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, }, { NULL } }; @@ -603,7 +608,6 @@ static const AVFilterPad blend_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_output, - .request_frame = request_frame, }, { NULL } }; @@ -611,10 +615,12 @@ static const AVFilterPad blend_outputs[] = { AVFilter ff_vf_blend = { .name = "blend", .description = NULL_IF_CONFIG_SMALL("Blend two video frames into each other."), + .preinit = blend_framesync_preinit, .init = init, .uninit = uninit, .priv_size = sizeof(BlendContext), .query_formats = query_formats, + .activate = activate, .inputs = blend_inputs, .outputs = blend_outputs, .priv_class = &blend_class, From a8ab52fae7286d4e7eec9256a08b6ad0b1e39d6c Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 31 Jul 2017 11:40:25 +0200 Subject: [PATCH 2890/3374] lavfi/vf_libvmaf: convert to framesync2. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After this commit, the code compiles, but on my setup it segfaults before and after. It also prints the very worrying warning: src/libavfilter/vf_libvmaf.c:161:66: warning: passing argument 4 of ‘compute_vmaf’ from incompatible pointer type [-Wincompatible-pointer-types] /tmp/i/include/libvmaf.h:26:8: note: expected ‘int (*)(float *, float *, float *, int, void *)’ but argument is of type ‘int (*)(float *, float *, float *, int, double *, void *)’ ==12116== Thread 6: ==12116== Conditional jump or move depends on uninitialised value(s) ==12116== at 0x526D432: cons_ (ocval.h:1188) ==12116== by 0x526D432: GenericIT (ocval.h:1119) ==12116== by 0x526D432: OC::TranslateForNumPyClassesToArray(OC::Val&) (pickleloader.h:92) ==12116== by 0x5211F5D: loads (pickleloader.h:566) ==12116== by 0x5211F5D: LoadValFromArray (chooseser.h:290) ==12116== by 0x5211F5D: LoadValFromFile (chooseser.h:405) ==12116== by 0x5211F5D: _read_and_assert_model(char const*, OC::Val&, OC::Val&, OC::Val&, OC::Val&, OC::Val&, OC::Val&) (vmaf.cpp:77) ==12116== by 0x5212B0F: VmafRunner::run(Asset, int (*)(float*, float*, float*, int, void*), void*, bool, bool, bool, bool, bool) (vmaf.cpp:149) ==12116== by 0x52165B6: RunVmaf(char const*, int, int, int (*)(float*, float*, float*, int, void*), void*, char const*, char const*, char const*, bool, bool, bool, bool, bool, char const*) (vmaf.cpp:645) ==12116== by 0x518AFFF: compute_vmaf_score (vf_libvmaf.c:161) ==12116== by 0x518AFFF: call_vmaf (vf_libvmaf.c:170) ==12116== by 0x7967493: start_thread (pthread_create.c:333) ==12116== by 0x7F69A8E: clone (clone.S:97) ==12116== ==12116== Conditional jump or move depends on uninitialised value(s) ==12116== at 0x526D432: cons_ (ocval.h:1188) ==12116== by 0x526D432: GenericIT (ocval.h:1119) ==12116== by 0x526D432: OC::TranslateForNumPyClassesToArray(OC::Val&) (pickleloader.h:92) ==12116== by 0x526D50D: OC::TranslateForNumPyClassesToArray(OC::Val&) (pickleloader.h:94) ==12116== by 0x5211F5D: loads (pickleloader.h:566) ==12116== by 0x5211F5D: LoadValFromArray (chooseser.h:290) ==12116== by 0x5211F5D: LoadValFromFile (chooseser.h:405) ==12116== by 0x5211F5D: _read_and_assert_model(char const*, OC::Val&, OC::Val&, OC::Val&, OC::Val&, OC::Val&, OC::Val&) (vmaf.cpp:77) ==12116== by 0x5212B0F: VmafRunner::run(Asset, int (*)(float*, float*, float*, int, void*), void*, bool, bool, bool, bool, bool) (vmaf.cpp:149) ==12116== by 0x52165B6: RunVmaf(char const*, int, int, int (*)(float*, float*, float*, int, void*), void*, char const*, char const*, char const*, bool, bool, bool, bool, bool, char const*) (vmaf.cpp:645) ==12116== by 0x518AFFF: compute_vmaf_score (vf_libvmaf.c:161) ==12116== by 0x518AFFF: call_vmaf (vf_libvmaf.c:170) ==12116== by 0x7967493: start_thread (pthread_create.c:333) ==12116== by 0x7F69A8E: clone (clone.S:97) ==12116== ==12116== Conditional jump or move depends on uninitialised value(s) ==12116== at 0x526D432: cons_ (ocval.h:1188) ==12116== by 0x526D432: GenericIT (ocval.h:1119) ==12116== by 0x526D432: OC::TranslateForNumPyClassesToArray(OC::Val&) (pickleloader.h:92) ==12116== by 0x526D50D: OC::TranslateForNumPyClassesToArray(OC::Val&) (pickleloader.h:94) ==12116== by 0x526D50D: OC::TranslateForNumPyClassesToArray(OC::Val&) (pickleloader.h:94) ==12116== by 0x5211F5D: loads (pickleloader.h:566) ==12116== by 0x5211F5D: LoadValFromArray (chooseser.h:290) ==12116== by 0x5211F5D: LoadValFromFile (chooseser.h:405) ==12116== by 0x5211F5D: _read_and_assert_model(char const*, OC::Val&, OC::Val&, OC::Val&, OC::Val&, OC::Val&, OC::Val&) (vmaf.cpp:77) ==12116== by 0x5212B0F: VmafRunner::run(Asset, int (*)(float*, float*, float*, int, void*), void*, bool, bool, bool, bool, bool) (vmaf.cpp:149) ==12116== by 0x52165B6: RunVmaf(char const*, int, int, int (*)(float*, float*, float*, int, void*), void*, char const*, char const*, char const*, bool, bool, bool, bool, bool, char const*) (vmaf.cpp:645) ==12116== by 0x518AFFF: compute_vmaf_score (vf_libvmaf.c:161) ==12116== by 0x518AFFF: call_vmaf (vf_libvmaf.c:170) ==12116== by 0x7967493: start_thread (pthread_create.c:333) ==12116== by 0x7F69A8E: clone (clone.S:97) ==12116== ==12116== Use of uninitialised value of size 8 ==12116== at 0x518AC79: read_frame_8bit (vf_libvmaf.c:147) ==12116== by 0x52AB5E8: combo (combo.c:149) ==12116== by 0x5212E95: VmafRunner::run(Asset, int (*)(float*, float*, float*, int, void*), void*, bool, bool, bool, bool, bool) (vmaf.cpp:278) ==12116== by 0x52165B6: RunVmaf(char const*, int, int, int (*)(float*, float*, float*, int, void*), void*, char const*, char const*, char const*, bool, bool, bool, bool, bool, char const*) (vmaf.cpp:645) ==12116== by 0x518AFFF: compute_vmaf_score (vf_libvmaf.c:161) ==12116== by 0x518AFFF: call_vmaf (vf_libvmaf.c:170) ==12116== by 0x7967493: start_thread (pthread_create.c:333) ==12116== by 0x7F69A8E: clone (clone.S:97) ==12116== ==12116== Invalid read of size 4 ==12116== at 0x518AC79: read_frame_8bit (vf_libvmaf.c:147) ==12116== by 0x52AB5E8: combo (combo.c:149) ==12116== by 0x5212E95: VmafRunner::run(Asset, int (*)(float*, float*, float*, int, void*), void*, bool, bool, bool, bool, bool) (vmaf.cpp:278) ==12116== by 0x52165B6: RunVmaf(char const*, int, int, int (*)(float*, float*, float*, int, void*), void*, char const*, char const*, char const*, bool, bool, bool, bool, bool, char const*) (vmaf.cpp:645) ==12116== by 0x518AFFF: compute_vmaf_score (vf_libvmaf.c:161) ==12116== by 0x518AFFF: call_vmaf (vf_libvmaf.c:170) ==12116== by 0x7967493: start_thread (pthread_create.c:333) ==12116== by 0x7F69A8E: clone (clone.S:97) ==12116== Address 0x40 is not stack'd, malloc'd or (recently) free'd ==12116== ==12116== ==12116== Process terminating with default action of signal 11 (SIGSEGV) ==12116== Access not within mapped region at address 0x40 ==12116== at 0x518AC79: read_frame_8bit (vf_libvmaf.c:147) ==12116== by 0x52AB5E8: combo (combo.c:149) ==12116== by 0x5212E95: VmafRunner::run(Asset, int (*)(float*, float*, float*, int, void*), void*, bool, bool, bool, bool, bool) (vmaf.cpp:278) ==12116== by 0x52165B6: RunVmaf(char const*, int, int, int (*)(float*, float*, float*, int, void*), void*, char const*, char const*, char const*, bool, bool, bool, bool, bool, char const*) (vmaf.cpp:645) ==12116== by 0x518AFFF: compute_vmaf_score (vf_libvmaf.c:161) ==12116== by 0x518AFFF: call_vmaf (vf_libvmaf.c:170) ==12116== by 0x7967493: start_thread (pthread_create.c:333) ==12116== by 0x7F69A8E: clone (clone.S:97) --- libavfilter/Makefile | 2 +- libavfilter/vf_libvmaf.c | 45 ++++++++++++++++++++++------------------ 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 57dd395d6a46a..06e3428e56412 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -217,7 +217,7 @@ OBJS-$(CONFIG_INTERLACE_FILTER) += vf_interlace.o OBJS-$(CONFIG_INTERLEAVE_FILTER) += f_interleave.o OBJS-$(CONFIG_KERNDEINT_FILTER) += vf_kerndeint.o OBJS-$(CONFIG_LENSCORRECTION_FILTER) += vf_lenscorrection.o -OBJS-$(CONFIG_LIBVMAF_FILTER) += vf_libvmaf.o dualinput.o framesync.o +OBJS-$(CONFIG_LIBVMAF_FILTER) += vf_libvmaf.o framesync2.o OBJS-$(CONFIG_LIMITER_FILTER) += vf_limiter.o OBJS-$(CONFIG_LOOP_FILTER) += f_loop.o OBJS-$(CONFIG_LUMAKEY_FILTER) += vf_lumakey.o diff --git a/libavfilter/vf_libvmaf.c b/libavfilter/vf_libvmaf.c index 3345cad67095a..2165561c5aede 100644 --- a/libavfilter/vf_libvmaf.c +++ b/libavfilter/vf_libvmaf.c @@ -31,15 +31,15 @@ #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "avfilter.h" -#include "dualinput.h" #include "drawutils.h" #include "formats.h" +#include "framesync2.h" #include "internal.h" #include "video.h" typedef struct LIBVMAFContext { const AVClass *class; - FFDualInputContext dinput; + FFFrameSync fs; const AVPixFmtDescriptor *desc; char *format; int width; @@ -81,7 +81,7 @@ static const AVOption libvmaf_options[] = { { NULL } }; -AVFILTER_DEFINE_CLASS(libvmaf); +FRAMESYNC_DEFINE_CLASS(libvmaf, LIBVMAFContext, fs); #define read_frame_fn(type, bits) \ static int read_frame_##bits##bit(float *ref_data, float *main_data, \ @@ -172,9 +172,18 @@ static void *call_vmaf(void *ctx) pthread_exit(NULL); } -static AVFrame *do_vmaf(AVFilterContext *ctx, AVFrame *main, const AVFrame *ref) +static int do_vmaf(FFFrameSync *fs) { + AVFilterContext *ctx = fs->parent; LIBVMAFContext *s = ctx->priv; + AVFrame *main, *ref; + int ret; + + ret = ff_framesync2_dualinput_get(fs, &main, &ref); + if (ret < 0) + return ret; + if (!ref) + return ff_filter_frame(ctx->outputs[0], main); pthread_mutex_lock(&s->lock); @@ -190,7 +199,7 @@ static AVFrame *do_vmaf(AVFilterContext *ctx, AVFrame *main, const AVFrame *ref) pthread_cond_signal(&s->cond); pthread_mutex_unlock(&s->lock); - return main; + return ff_filter_frame(ctx->outputs[0], main); } static av_cold int init(AVFilterContext *ctx) @@ -203,7 +212,7 @@ static av_cold int init(AVFilterContext *ctx) pthread_mutex_init(&s->lock, NULL); pthread_cond_init (&s->cond, NULL); - s->dinput.process = do_vmaf; + s->fs.on_event = do_vmaf; return 0; } @@ -259,34 +268,31 @@ static int config_output(AVFilterLink *outlink) AVFilterLink *mainlink = ctx->inputs[0]; int ret; + ret = ff_framesync2_init_dualinput(&s->fs, ctx); + if (ret < 0) + return ret; outlink->w = mainlink->w; outlink->h = mainlink->h; outlink->time_base = mainlink->time_base; outlink->sample_aspect_ratio = mainlink->sample_aspect_ratio; outlink->frame_rate = mainlink->frame_rate; - if ((ret = ff_dualinput_init(ctx, &s->dinput)) < 0) + if ((ret = ff_framesync2_configure(&s->fs)) < 0) return ret; return 0; } -static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) +static int activate(AVFilterContext *ctx) { - LIBVMAFContext *s = inlink->dst->priv; - return ff_dualinput_filter_frame(&s->dinput, inlink, inpicref); -} - -static int request_frame(AVFilterLink *outlink) -{ - LIBVMAFContext *s = outlink->src->priv; - return ff_dualinput_request_frame(&s->dinput, outlink); + LIBVMAFContext *s = ctx->priv; + return ff_framesync2_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) { LIBVMAFContext *s = ctx->priv; - ff_dualinput_uninit(&s->dinput); + ff_framesync2_uninit(&s->fs); pthread_mutex_lock(&s->lock); s->eof = 1; @@ -306,11 +312,9 @@ static const AVFilterPad libvmaf_inputs[] = { { .name = "main", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, },{ .name = "reference", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, .config_props = config_input_ref, }, { NULL } @@ -321,7 +325,6 @@ static const AVFilterPad libvmaf_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_output, - .request_frame = request_frame, }, { NULL } }; @@ -329,9 +332,11 @@ static const AVFilterPad libvmaf_outputs[] = { AVFilter ff_vf_libvmaf = { .name = "libvmaf", .description = NULL_IF_CONFIG_SMALL("Calculate the VMAF between two video streams."), + .preinit = libvmaf_framesync_preinit, .init = init, .uninit = uninit, .query_formats = query_formats, + .activate = activate, .priv_size = sizeof(LIBVMAFContext), .priv_class = &libvmaf_class, .inputs = libvmaf_inputs, From eacb3ec961035b39e4bf69b589df9b110f591710 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 31 Jul 2017 12:03:03 +0200 Subject: [PATCH 2891/3374] lavfi/vf_lut3d: convert to framesync2. --- libavfilter/Makefile | 2 +- libavfilter/vf_lut3d.c | 49 ++++++++++++++++++++++-------------------- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 06e3428e56412..4b8c34d35b62d 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -197,7 +197,7 @@ OBJS-$(CONFIG_FSPP_FILTER) += vf_fspp.o OBJS-$(CONFIG_GBLUR_FILTER) += vf_gblur.o OBJS-$(CONFIG_GEQ_FILTER) += vf_geq.o OBJS-$(CONFIG_GRADFUN_FILTER) += vf_gradfun.o -OBJS-$(CONFIG_HALDCLUT_FILTER) += vf_lut3d.o dualinput.o framesync.o +OBJS-$(CONFIG_HALDCLUT_FILTER) += vf_lut3d.o framesync2.o OBJS-$(CONFIG_HFLIP_FILTER) += vf_hflip.o OBJS-$(CONFIG_HISTEQ_FILTER) += vf_histeq.o OBJS-$(CONFIG_HISTOGRAM_FILTER) += vf_histogram.o diff --git a/libavfilter/vf_lut3d.c b/libavfilter/vf_lut3d.c index 7a294b07610f3..5ba91f7e47993 100644 --- a/libavfilter/vf_lut3d.c +++ b/libavfilter/vf_lut3d.c @@ -31,8 +31,8 @@ #include "libavutil/avstring.h" #include "avfilter.h" #include "drawutils.h" -#include "dualinput.h" #include "formats.h" +#include "framesync2.h" #include "internal.h" #include "video.h" @@ -70,7 +70,7 @@ typedef struct LUT3DContext { int clut_step; int clut_is16bit; int clut_width; - FFDualInputContext dinput; + FFFrameSync fs; #endif } LUT3DContext; @@ -681,24 +681,21 @@ static int config_output(AVFilterLink *outlink) LUT3DContext *lut3d = ctx->priv; int ret; + ret = ff_framesync2_init_dualinput(&lut3d->fs, ctx); + if (ret < 0) + return ret; outlink->w = ctx->inputs[0]->w; outlink->h = ctx->inputs[0]->h; outlink->time_base = ctx->inputs[0]->time_base; - if ((ret = ff_dualinput_init(ctx, &lut3d->dinput)) < 0) + if ((ret = ff_framesync2_configure(&lut3d->fs)) < 0) return ret; return 0; } -static int filter_frame_hald(AVFilterLink *inlink, AVFrame *inpicref) -{ - LUT3DContext *s = inlink->dst->priv; - return ff_dualinput_filter_frame(&s->dinput, inlink, inpicref); -} - -static int request_frame(AVFilterLink *outlink) +static int activate(AVFilterContext *ctx) { - LUT3DContext *s = outlink->src->priv; - return ff_dualinput_request_frame(&s->dinput, outlink); + LUT3DContext *s = ctx->priv; + return ff_framesync2_activate(&s->fs); } static int config_clut(AVFilterLink *inlink) @@ -751,45 +748,50 @@ static int config_clut(AVFilterLink *inlink) return 0; } -static AVFrame *update_apply_clut(AVFilterContext *ctx, AVFrame *main, - const AVFrame *second) +static int update_apply_clut(FFFrameSync *fs) { + AVFilterContext *ctx = fs->parent; AVFilterLink *inlink = ctx->inputs[0]; + AVFrame *main, *second, *out; + int ret; + + ret = ff_framesync2_dualinput_get(fs, &main, &second); + if (ret < 0) + return ret; + if (!second) + return ff_filter_frame(ctx->outputs[0], main); update_clut(ctx->priv, second); - return apply_lut(inlink, main); + out = apply_lut(inlink, main); + return ff_filter_frame(ctx->outputs[0], out); } static av_cold int haldclut_init(AVFilterContext *ctx) { LUT3DContext *lut3d = ctx->priv; - lut3d->dinput.process = update_apply_clut; + lut3d->fs.on_event = update_apply_clut; return 0; } static av_cold void haldclut_uninit(AVFilterContext *ctx) { LUT3DContext *lut3d = ctx->priv; - ff_dualinput_uninit(&lut3d->dinput); + ff_framesync2_uninit(&lut3d->fs); } static const AVOption haldclut_options[] = { - { "shortest", "force termination when the shortest input terminates", OFFSET(dinput.shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, - { "repeatlast", "continue applying the last clut after eos", OFFSET(dinput.repeatlast), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS }, COMMON_OPTIONS }; -AVFILTER_DEFINE_CLASS(haldclut); +FRAMESYNC_DEFINE_CLASS(haldclut, LUT3DContext, fs); static const AVFilterPad haldclut_inputs[] = { { .name = "main", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame_hald, .config_props = config_input, },{ .name = "clut", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame_hald, .config_props = config_clut, }, { NULL } @@ -799,7 +801,6 @@ static const AVFilterPad haldclut_outputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, .config_props = config_output, }, { NULL } @@ -809,9 +810,11 @@ AVFilter ff_vf_haldclut = { .name = "haldclut", .description = NULL_IF_CONFIG_SMALL("Adjust colors using a Hald CLUT."), .priv_size = sizeof(LUT3DContext), + .preinit = haldclut_framesync_preinit, .init = haldclut_init, .uninit = haldclut_uninit, .query_formats = query_formats, + .activate = activate, .inputs = haldclut_inputs, .outputs = haldclut_outputs, .priv_class = &haldclut_class, From 23000c3de5940271f6daa58d629871c9355cd37c Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 31 Jul 2017 12:27:58 +0200 Subject: [PATCH 2892/3374] lavfi/vf_paletteuse: convert to framesync2. --- libavfilter/Makefile | 2 +- libavfilter/vf_paletteuse.c | 60 +++++++++++++++++++++++-------------- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 4b8c34d35b62d..b6229b057064c 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -249,7 +249,7 @@ OBJS-$(CONFIG_OVERLAY_FILTER) += vf_overlay.o framesync2.o OBJS-$(CONFIG_OWDENOISE_FILTER) += vf_owdenoise.o OBJS-$(CONFIG_PAD_FILTER) += vf_pad.o OBJS-$(CONFIG_PALETTEGEN_FILTER) += vf_palettegen.o -OBJS-$(CONFIG_PALETTEUSE_FILTER) += vf_paletteuse.o dualinput.o framesync.o +OBJS-$(CONFIG_PALETTEUSE_FILTER) += vf_paletteuse.o framesync2.o OBJS-$(CONFIG_PERMS_FILTER) += f_perms.o OBJS-$(CONFIG_PERSPECTIVE_FILTER) += vf_perspective.o OBJS-$(CONFIG_PHASE_FILTER) += vf_phase.o diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c index b25c6a9eac493..3d16c2dd842e3 100644 --- a/libavfilter/vf_paletteuse.c +++ b/libavfilter/vf_paletteuse.c @@ -27,8 +27,10 @@ #include "libavutil/internal.h" #include "libavutil/opt.h" #include "libavutil/qsort.h" -#include "dualinput.h" #include "avfilter.h" +#include "filters.h" +#include "framesync2.h" +#include "internal.h" enum dithering_mode { DITHERING_NONE, @@ -80,7 +82,7 @@ typedef int (*set_frame_func)(struct PaletteUseContext *s, AVFrame *out, AVFrame typedef struct PaletteUseContext { const AVClass *class; - FFDualInputContext dinput; + FFFrameSync fs; struct cache_node cache[CACHE_SIZE]; /* lookup cache */ struct color_node map[AVPALETTE_COUNT]; /* 3D-Tree (KD-Tree with K=3) for reverse colormap */ uint32_t palette[AVPALETTE_COUNT]; @@ -129,6 +131,8 @@ static const AVOption paletteuse_options[] = { AVFILTER_DEFINE_CLASS(paletteuse); +static int load_apply_palette(FFFrameSync *fs); + static int query_formats(AVFilterContext *ctx) { static const enum AVPixelFormat in_fmts[] = {AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE}; @@ -900,11 +904,18 @@ static int config_output(AVFilterLink *outlink) AVFilterContext *ctx = outlink->src; PaletteUseContext *s = ctx->priv; + ret = ff_framesync2_init_dualinput(&s->fs, ctx); + if (ret < 0) + return ret; + s->fs.opt_repeatlast = 1; // only 1 frame in the palette + s->fs.in[1].before = s->fs.in[1].after = EXT_INFINITY; + s->fs.on_event = load_apply_palette; + outlink->w = ctx->inputs[0]->w; outlink->h = ctx->inputs[0]->h; outlink->time_base = ctx->inputs[0]->time_base; - if ((ret = ff_dualinput_init(ctx, &s->dinput)) < 0) + if ((ret = ff_framesync2_configure(&s->fs)) < 0) return ret; return 0; } @@ -951,21 +962,32 @@ static void load_palette(PaletteUseContext *s, const AVFrame *palette_frame) s->palette_loaded = 1; } -static AVFrame *load_apply_palette(AVFilterContext *ctx, AVFrame *main, - const AVFrame *second) +static int load_apply_palette(FFFrameSync *fs) { + AVFilterContext *ctx = fs->parent; AVFilterLink *inlink = ctx->inputs[0]; PaletteUseContext *s = ctx->priv; + AVFrame *main, *second, *out; + int ret; + + // writable for error diffusal dithering + ret = ff_framesync2_dualinput_get_writable(fs, &main, &second); + if (ret < 0) + return ret; + if (!main || !second) { + ret = AVERROR_BUG; + goto error; + } if (!s->palette_loaded) { load_palette(s, second); } - return apply_palette(inlink, main); -} + out = apply_palette(inlink, main); + return ff_filter_frame(ctx->outputs[0], out); -static int filter_frame(AVFilterLink *inlink, AVFrame *in) -{ - PaletteUseContext *s = inlink->dst->priv; - return ff_dualinput_filter_frame(&s->dinput, inlink, in); +error: + av_frame_free(&main); + av_frame_free(&second); + return ret; } #define DEFINE_SET_FRAME(color_search, name, value) \ @@ -1013,9 +1035,6 @@ static int dither_value(int p) static av_cold int init(AVFilterContext *ctx) { PaletteUseContext *s = ctx->priv; - s->dinput.repeatlast = 1; // only 1 frame in the palette - s->dinput.skip_initial_unpaired = 1; - s->dinput.process = load_apply_palette; s->set_frame = set_frame_lut[s->color_search_method][s->dither]; @@ -1030,10 +1049,10 @@ static av_cold int init(AVFilterContext *ctx) return 0; } -static int request_frame(AVFilterLink *outlink) +static int activate(AVFilterContext *ctx) { - PaletteUseContext *s = outlink->src->priv; - return ff_dualinput_request_frame(&s->dinput, outlink); + PaletteUseContext *s = ctx->priv; + return ff_framesync2_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) @@ -1041,7 +1060,7 @@ static av_cold void uninit(AVFilterContext *ctx) int i; PaletteUseContext *s = ctx->priv; - ff_dualinput_uninit(&s->dinput); + ff_framesync2_uninit(&s->fs); for (i = 0; i < CACHE_SIZE; i++) av_freep(&s->cache[i].entries); av_frame_free(&s->last_in); @@ -1052,13 +1071,10 @@ static const AVFilterPad paletteuse_inputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - .needs_writable = 1, // for error diffusal dithering },{ .name = "palette", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_input_palette, - .filter_frame = filter_frame, }, { NULL } }; @@ -1068,7 +1084,6 @@ static const AVFilterPad paletteuse_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_output, - .request_frame = request_frame, }, { NULL } }; @@ -1080,6 +1095,7 @@ AVFilter ff_vf_paletteuse = { .query_formats = query_formats, .init = init, .uninit = uninit, + .activate = activate, .inputs = paletteuse_inputs, .outputs = paletteuse_outputs, .priv_class = &paletteuse_class, From 3bd11df459866d7303c1ad6779473528c2cfb76d Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 31 Jul 2017 12:44:13 +0200 Subject: [PATCH 2893/3374] lavfi/vf_psnr: convert to framesync2. --- libavfilter/Makefile | 2 +- libavfilter/vf_psnr.c | 50 +++++++++++++++++++++++-------------------- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index b6229b057064c..3da821ee3eba2 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -260,7 +260,7 @@ OBJS-$(CONFIG_PP7_FILTER) += vf_pp7.o OBJS-$(CONFIG_PREMULTIPLY_FILTER) += vf_premultiply.o framesync2.o OBJS-$(CONFIG_PREWITT_FILTER) += vf_convolution.o OBJS-$(CONFIG_PSEUDOCOLOR_FILTER) += vf_pseudocolor.o -OBJS-$(CONFIG_PSNR_FILTER) += vf_psnr.o dualinput.o framesync.o +OBJS-$(CONFIG_PSNR_FILTER) += vf_psnr.o framesync2.o OBJS-$(CONFIG_PULLUP_FILTER) += vf_pullup.o OBJS-$(CONFIG_QP_FILTER) += vf_qp.o OBJS-$(CONFIG_RANDOM_FILTER) += vf_random.o diff --git a/libavfilter/vf_psnr.c b/libavfilter/vf_psnr.c index 6ab21d8e229e0..a8eb315445ae2 100644 --- a/libavfilter/vf_psnr.c +++ b/libavfilter/vf_psnr.c @@ -29,16 +29,16 @@ #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "avfilter.h" -#include "dualinput.h" #include "drawutils.h" #include "formats.h" +#include "framesync2.h" #include "internal.h" #include "psnr.h" #include "video.h" typedef struct PSNRContext { const AVClass *class; - FFDualInputContext dinput; + FFFrameSync fs; double mse, min_mse, max_mse, mse_comp[4]; uint64_t nb_frames; FILE *stats_file; @@ -68,7 +68,7 @@ static const AVOption psnr_options[] = { { NULL } }; -AVFILTER_DEFINE_CLASS(psnr); +FRAMESYNC_DEFINE_CLASS(psnr, PSNRContext, fs); static inline unsigned pow_2(unsigned base) { @@ -142,13 +142,21 @@ static void set_meta(AVDictionary **metadata, const char *key, char comp, float } } -static AVFrame *do_psnr(AVFilterContext *ctx, AVFrame *main, - const AVFrame *ref) +static int do_psnr(FFFrameSync *fs) { + AVFilterContext *ctx = fs->parent; PSNRContext *s = ctx->priv; + AVFrame *main, *ref; double comp_mse[4], mse = 0; - int j, c; - AVDictionary **metadata = &main->metadata; + int ret, j, c; + AVDictionary **metadata; + + ret = ff_framesync2_dualinput_get(fs, &main, &ref); + if (ret < 0) + return ret; + if (!ref) + return ff_filter_frame(ctx->outputs[0], main); + metadata = &main->metadata; compute_images_mse(s, (const uint8_t **)main->data, main->linesize, (const uint8_t **)ref->data, ref->linesize, @@ -214,7 +222,7 @@ static AVFrame *do_psnr(AVFilterContext *ctx, AVFrame *main, fprintf(s->stats_file, "\n"); } - return main; + return ff_filter_frame(ctx->outputs[0], main); } static av_cold int init(AVFilterContext *ctx) @@ -245,7 +253,7 @@ static av_cold int init(AVFilterContext *ctx) } } - s->dinput.process = do_psnr; + s->fs.on_event = do_psnr; return 0; } @@ -331,27 +339,24 @@ static int config_output(AVFilterLink *outlink) AVFilterLink *mainlink = ctx->inputs[0]; int ret; + ret = ff_framesync2_init_dualinput(&s->fs, ctx); + if (ret < 0) + return ret; outlink->w = mainlink->w; outlink->h = mainlink->h; outlink->time_base = mainlink->time_base; outlink->sample_aspect_ratio = mainlink->sample_aspect_ratio; outlink->frame_rate = mainlink->frame_rate; - if ((ret = ff_dualinput_init(ctx, &s->dinput)) < 0) + if ((ret = ff_framesync2_configure(&s->fs)) < 0) return ret; return 0; } -static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) +static int activate(AVFilterContext *ctx) { - PSNRContext *s = inlink->dst->priv; - return ff_dualinput_filter_frame(&s->dinput, inlink, inpicref); -} - -static int request_frame(AVFilterLink *outlink) -{ - PSNRContext *s = outlink->src->priv; - return ff_dualinput_request_frame(&s->dinput, outlink); + PSNRContext *s = ctx->priv; + return ff_framesync2_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) @@ -375,7 +380,7 @@ static av_cold void uninit(AVFilterContext *ctx) get_psnr(s->min_mse, 1, s->average_max)); } - ff_dualinput_uninit(&s->dinput); + ff_framesync2_uninit(&s->fs); if (s->stats_file && s->stats_file != stdout) fclose(s->stats_file); @@ -385,11 +390,9 @@ static const AVFilterPad psnr_inputs[] = { { .name = "main", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, },{ .name = "reference", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, .config_props = config_input_ref, }, { NULL } @@ -400,7 +403,6 @@ static const AVFilterPad psnr_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_output, - .request_frame = request_frame, }, { NULL } }; @@ -408,9 +410,11 @@ static const AVFilterPad psnr_outputs[] = { AVFilter ff_vf_psnr = { .name = "psnr", .description = NULL_IF_CONFIG_SMALL("Calculate the PSNR between two video streams."), + .preinit = psnr_framesync_preinit, .init = init, .uninit = uninit, .query_formats = query_formats, + .activate = activate, .priv_size = sizeof(PSNRContext), .priv_class = &psnr_class, .inputs = psnr_inputs, From ef2176473d3d5ac5bf36aa9bcd7bba760121ad84 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 31 Jul 2017 13:37:06 +0200 Subject: [PATCH 2894/3374] vf_ssim: convert to framesync2. --- libavfilter/Makefile | 2 +- libavfilter/vf_ssim.c | 52 ++++++++++++++++++++++--------------------- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 3da821ee3eba2..ee840b02e5e1a 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -301,7 +301,7 @@ OBJS-$(CONFIG_SMARTBLUR_FILTER) += vf_smartblur.o OBJS-$(CONFIG_SOBEL_FILTER) += vf_convolution.o OBJS-$(CONFIG_SPLIT_FILTER) += split.o OBJS-$(CONFIG_SPP_FILTER) += vf_spp.o -OBJS-$(CONFIG_SSIM_FILTER) += vf_ssim.o dualinput.o framesync.o +OBJS-$(CONFIG_SSIM_FILTER) += vf_ssim.o framesync2.o OBJS-$(CONFIG_STEREO3D_FILTER) += vf_stereo3d.o OBJS-$(CONFIG_STREAMSELECT_FILTER) += f_streamselect.o framesync2.o OBJS-$(CONFIG_SUBTITLES_FILTER) += vf_subtitles.o diff --git a/libavfilter/vf_ssim.c b/libavfilter/vf_ssim.c index 371f6dba70071..5f5bed7a0ed8a 100644 --- a/libavfilter/vf_ssim.c +++ b/libavfilter/vf_ssim.c @@ -38,16 +38,16 @@ #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "avfilter.h" -#include "dualinput.h" #include "drawutils.h" #include "formats.h" +#include "framesync2.h" #include "internal.h" #include "ssim.h" #include "video.h" typedef struct SSIMContext { const AVClass *class; - FFDualInputContext dinput; + FFFrameSync fs; FILE *stats_file; char *stats_file_str; int nb_components; @@ -78,7 +78,7 @@ static const AVOption ssim_options[] = { { NULL } }; -AVFILTER_DEFINE_CLASS(ssim); +FRAMESYNC_DEFINE_CLASS(ssim, SSIMContext, fs); static void set_meta(AVDictionary **metadata, const char *key, char comp, float d) { @@ -282,13 +282,21 @@ static double ssim_db(double ssim, double weight) return 10 * log10(weight / (weight - ssim)); } -static AVFrame *do_ssim(AVFilterContext *ctx, AVFrame *main, - const AVFrame *ref) +static int do_ssim(FFFrameSync *fs) { - AVDictionary **metadata = &main->metadata; + AVFilterContext *ctx = fs->parent; SSIMContext *s = ctx->priv; + AVFrame *main, *ref; + AVDictionary **metadata; float c[4], ssimv = 0.0; - int i; + int ret, i; + + ret = ff_framesync2_dualinput_get(fs, &main, &ref); + if (ret < 0) + return ret; + if (!ref) + return ff_filter_frame(ctx->outputs[0], main); + metadata = &main->metadata; s->nb_frames++; @@ -320,7 +328,7 @@ static AVFrame *do_ssim(AVFilterContext *ctx, AVFrame *main, fprintf(s->stats_file, "All:%f (%f)\n", ssimv, ssim_db(ssimv, 1.0)); } - return main; + return ff_filter_frame(ctx->outputs[0], main); } static av_cold int init(AVFilterContext *ctx) @@ -343,9 +351,7 @@ static av_cold int init(AVFilterContext *ctx) } } - s->dinput.process = do_ssim; - s->dinput.shortest = 1; - s->dinput.repeatlast = 0; + s->fs.on_event = do_ssim; return 0; } @@ -425,28 +431,25 @@ static int config_output(AVFilterLink *outlink) AVFilterLink *mainlink = ctx->inputs[0]; int ret; + ret = ff_framesync2_init_dualinput(&s->fs, ctx); + if (ret < 0) + return ret; outlink->w = mainlink->w; outlink->h = mainlink->h; outlink->time_base = mainlink->time_base; outlink->sample_aspect_ratio = mainlink->sample_aspect_ratio; outlink->frame_rate = mainlink->frame_rate; - if ((ret = ff_dualinput_init(ctx, &s->dinput)) < 0) + if ((ret = ff_framesync2_configure(&s->fs)) < 0) return ret; return 0; } -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) +static int activate(AVFilterContext *ctx) { - SSIMContext *s = inlink->dst->priv; - return ff_dualinput_filter_frame(&s->dinput, inlink, buf); -} - -static int request_frame(AVFilterLink *outlink) -{ - SSIMContext *s = outlink->src->priv; - return ff_dualinput_request_frame(&s->dinput, outlink); + SSIMContext *s = ctx->priv; + return ff_framesync2_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) @@ -466,7 +469,7 @@ static av_cold void uninit(AVFilterContext *ctx) s->ssim_total / s->nb_frames, ssim_db(s->ssim_total, s->nb_frames)); } - ff_dualinput_uninit(&s->dinput); + ff_framesync2_uninit(&s->fs); if (s->stats_file && s->stats_file != stdout) fclose(s->stats_file); @@ -478,11 +481,9 @@ static const AVFilterPad ssim_inputs[] = { { .name = "main", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, },{ .name = "reference", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, .config_props = config_input_ref, }, { NULL } @@ -493,7 +494,6 @@ static const AVFilterPad ssim_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_output, - .request_frame = request_frame, }, { NULL } }; @@ -501,9 +501,11 @@ static const AVFilterPad ssim_outputs[] = { AVFilter ff_vf_ssim = { .name = "ssim", .description = NULL_IF_CONFIG_SMALL("Calculate the SSIM between two video streams."), + .preinit = ssim_framesync_preinit, .init = init, .uninit = uninit, .query_formats = query_formats, + .activate = activate, .priv_size = sizeof(SSIMContext), .priv_class = &ssim_class, .inputs = ssim_inputs, From 607900c905c4112bb43f2710bd76d98491d584a9 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 31 Jul 2017 13:38:22 +0200 Subject: [PATCH 2895/3374] lavfi: remove dualinput. --- libavfilter/dualinput.c | 90 ----------------------------------------- libavfilter/dualinput.h | 46 --------------------- 2 files changed, 136 deletions(-) delete mode 100644 libavfilter/dualinput.c delete mode 100644 libavfilter/dualinput.h diff --git a/libavfilter/dualinput.c b/libavfilter/dualinput.c deleted file mode 100644 index 44750973a60e0..0000000000000 --- a/libavfilter/dualinput.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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 "dualinput.h" -#include "libavutil/timestamp.h" - -static int process_frame(FFFrameSync *fs) -{ - AVFilterContext *ctx = fs->parent; - FFDualInputContext *s = fs->opaque; - AVFrame *mainpic = NULL, *secondpic = NULL; - int ret = 0; - - if ((ret = ff_framesync_get_frame(&s->fs, 0, &mainpic, 1)) < 0 || - (ret = ff_framesync_get_frame(&s->fs, 1, &secondpic, 0)) < 0) { - av_frame_free(&mainpic); - return ret; - } - av_assert0(mainpic); - mainpic->pts = av_rescale_q(s->fs.pts, s->fs.time_base, ctx->outputs[0]->time_base); - if (secondpic && !ctx->is_disabled) - mainpic = s->process(ctx, mainpic, secondpic); - ret = ff_filter_frame(ctx->outputs[0], mainpic); - av_assert1(ret != AVERROR(EAGAIN)); - return ret; -} - -int ff_dualinput_init(AVFilterContext *ctx, FFDualInputContext *s) -{ - FFFrameSyncIn *in; - int ret; - - if ((ret = ff_framesync_init(&s->fs, ctx, 2)) < 0) - return ret; - - in = s->fs.in; - s->fs.opaque = s; - s->fs.on_event = process_frame; - in[0].time_base = ctx->inputs[0]->time_base; - in[1].time_base = ctx->inputs[1]->time_base; - in[0].sync = 2; - in[0].before = EXT_STOP; - in[0].after = EXT_INFINITY; - in[1].sync = 1; - in[1].before = EXT_NULL; - in[1].after = EXT_INFINITY; - - if (s->shortest) - in[0].after = in[1].after = EXT_STOP; - if (!s->repeatlast) { - in[1].after = EXT_NULL; - in[1].sync = 0; - } - if (s->skip_initial_unpaired) { - in[1].before = EXT_STOP; - } - - return ff_framesync_configure(&s->fs); -} - -int ff_dualinput_filter_frame(FFDualInputContext *s, - AVFilterLink *inlink, AVFrame *in) -{ - return ff_framesync_filter_frame(&s->fs, inlink, in); -} - -int ff_dualinput_request_frame(FFDualInputContext *s, AVFilterLink *outlink) -{ - return ff_framesync_request_frame(&s->fs, outlink); -} - -void ff_dualinput_uninit(FFDualInputContext *s) -{ - ff_framesync_uninit(&s->fs); -} diff --git a/libavfilter/dualinput.h b/libavfilter/dualinput.h deleted file mode 100644 index fcde0d6aa1dab..0000000000000 --- a/libavfilter/dualinput.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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 - */ - -/** - * @file - * Double input streams helper for filters - */ - -#ifndef AVFILTER_DUALINPUT_H -#define AVFILTER_DUALINPUT_H - -#include -#include "bufferqueue.h" -#include "framesync.h" -#include "internal.h" - -typedef struct FFDualInputContext { - FFFrameSync fs; - - AVFrame *(*process)(AVFilterContext *ctx, AVFrame *main, const AVFrame *second); - int shortest; ///< terminate stream when the second input terminates - int repeatlast; ///< repeat last second frame - int skip_initial_unpaired; ///< Skip initial frames that do not have a 2nd input -} FFDualInputContext; - -int ff_dualinput_init(AVFilterContext *ctx, FFDualInputContext *s); -int ff_dualinput_filter_frame(FFDualInputContext *s, AVFilterLink *inlink, AVFrame *in); -int ff_dualinput_request_frame(FFDualInputContext *s, AVFilterLink *outlink); -void ff_dualinput_uninit(FFDualInputContext *s); - -#endif /* AVFILTER_DUALINPUT_H */ From 844bc0d89e1d59f1593448bfc0fc52fec34e0946 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Thu, 10 Aug 2017 13:32:19 +0200 Subject: [PATCH 2896/3374] doc/filters: document framesync options. --- Changelog | 3 ++ doc/filters.texi | 76 ++++++++++++++++++++++++++++-------------------- 2 files changed, 48 insertions(+), 31 deletions(-) diff --git a/Changelog b/Changelog index 1dfb8b5714f81..b064328c3f8c3 100644 --- a/Changelog +++ b/Changelog @@ -35,6 +35,9 @@ version : - pseudocolor video filter - raw G.726 muxer and demuxer, left- and right-justified - NewTek NDI input/output device +- Some video filters with several inputs now use a common set of options: + blend, libvmaf, lut3d, overlay, psnr, ssim. + They must always be used by name. version 3.3: - CrystalHD decoder moved to new decode API diff --git a/doc/filters.texi b/doc/filters.texi index 779fd533173a4..19e13a1346a3b 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -311,6 +311,39 @@ See @code{ffmpeg -filters} to view which filters have timeline support. @c man end FILTERGRAPH DESCRIPTION +@anchor{framesync} +@chapter Options for filters with several inputs (framesync) +@c man begin OPTIONS FOR FILTERS WITH SEVERAL INPUTS + +Some filters with several inputs support a common set of options. +These options can only be set by name, not with the short notation. + +@table @option +@item eof_action +The action to take when EOF is encountered on the secondary input; it accepts +one of the following values: + +@table @option +@item repeat +Repeat the last frame (the default). +@item endall +End both streams. +@item pass +Pass the main input through. +@end table + +@item shortest +If set to 1, force the output to terminate when the shortest input +terminates. Default value is 0. + +@item repeatlast +If set to 1, force the filter to draw the last overlay frame over the +main input until the end of the stream. A value of 0 disables this +behavior. Default value is 1. +@end table + +@c man end OPTIONS FOR FILTERS WITH SEVERAL INPUTS + @chapter Audio Filters @c man begin AUDIO FILTERS @@ -4949,17 +4982,10 @@ Value of pixel component at current location for first video frame (top layer). @item BOTTOM, B Value of pixel component at current location for second video frame (bottom layer). @end table - -@item shortest -Force termination when the shortest input terminates. Default is -@code{0}. This option is only defined for the @code{blend} filter. - -@item repeatlast -Continue applying the last bottom frame after the end of the stream. A value of -@code{0} disable the filter after the last frame of the bottom layer is reached. -Default is @code{1}. This option is only defined for the @code{blend} filter. @end table +The @code{blend} filter also supports the @ref{framesync} options. + @subsection Examples @itemize @@ -9757,6 +9783,8 @@ Enables computing ms_ssim along with vmaf. Set the pool method to be used for computing vmaf. @end table +This filter also supports the @ref{framesync} options. + For example: @example ffmpeg -i main.mpg -i ref.mpg -lavfi libvmaf -f null - @@ -9838,6 +9866,8 @@ Interpolate values using a tetrahedron. @end table @end table +This filter also supports the @ref{framesync} options. + @section lumakey Turn certain luma values into transparency. @@ -10866,19 +10896,6 @@ on the main video. Default value is "0" for both expressions. In case the expression is invalid, it is set to a huge value (meaning that the overlay will not be displayed within the output visible area). -@item eof_action -The action to take when EOF is encountered on the secondary input; it accepts -one of the following values: - -@table @option -@item repeat -Repeat the last frame (the default). -@item endall -End both streams. -@item pass -Pass the main input through. -@end table - @item eval Set when the expressions for @option{x}, and @option{y} are evaluated. @@ -10894,10 +10911,6 @@ evaluate expressions for each incoming frame Default value is @samp{frame}. -@item shortest -If set to 1, force the output to terminate when the shortest input -terminates. Default value is 0. - @item format Set the format for the output video. @@ -10923,11 +10936,6 @@ automatically pick format @end table Default value is @samp{yuv420}. - -@item repeatlast -If set to 1, force the filter to draw the last overlay frame over the -main input until the end of the stream. A value of 0 disables this -behavior. Default value is 1. @end table The @option{x}, and @option{y} expressions can contain the following @@ -10964,6 +10972,8 @@ The timestamp, expressed in seconds. It's NAN if the input timestamp is unknown. @end table +This filter also supports the @ref{framesync} options. + Note that the @var{n}, @var{pos}, @var{t} variables are available only when evaluation is done @emph{per frame}, and will evaluate to NAN when @option{eval} is set to @samp{init}. @@ -11902,6 +11912,8 @@ Requires stats_version >= 2. If this is set and stats_version < 2, the filter will return an error. @end table +This filter also supports the @ref{framesync} options. + The file printed if @var{stats_file} is selected, contains a sequence of key/value pairs of the form @var{key}:@var{value} for each compared couple of frames. @@ -13655,6 +13667,8 @@ SSIM of the compared frames for the whole frame. Same as above but in dB representation. @end table +This filter also supports the @ref{framesync} options. + For example: @example movie=ref_movie.mpg, setpts=PTS-STARTPTS [main]; From 7302d5e325977d4a8ff61422fdabdae0dc504ec0 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Tue, 29 Aug 2017 15:46:36 +0200 Subject: [PATCH 2897/3374] lavfi: bump minor version after change in options. --- libavfilter/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/version.h b/libavfilter/version.h index 22207127d0f1d..60f18f7c51379 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 6 -#define LIBAVFILTER_VERSION_MINOR 100 +#define LIBAVFILTER_VERSION_MINOR 101 #define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ From 429f3266c14ac4851da007fcb3461f9acc99cbad Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 29 Aug 2017 02:13:20 +0200 Subject: [PATCH 2898/3374] avformat/mxfenc: Check that the video codec in D-10 is MPEG-2 Others do not work, but nothing rejects them prior to this patch if the parameters otherwise match Reviewed-by: Matthieu Bouron Signed-off-by: Michael Niedermayer --- libavformat/mxfenc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index 12fc9abbc6c8c..a07da69b11aea 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -2101,6 +2101,10 @@ static int mxf_write_header(AVFormatContext *s) sc->video_bit_rate = st->codecpar->bit_rate; if (s->oformat == &ff_mxf_d10_muxer) { + if (st->codecpar->codec_id != AV_CODEC_ID_MPEG2VIDEO) { + av_log(s, AV_LOG_ERROR, "error MXF D-10 only support MPEG-2 Video\n"); + return AVERROR(EINVAL); + } if ((sc->video_bit_rate == 50000000) && (mxf->time_base.den == 25)) { sc->index = 3; } else if ((sc->video_bit_rate == 49999840 || sc->video_bit_rate == 50000000) && (mxf->time_base.den != 25)) { From 6def8b8d924af985514ebb1b1a51871c94d26d33 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 17 Aug 2017 01:06:14 +0200 Subject: [PATCH 2899/3374] avcodec/h264idct_template: Fix integer overflow in ff_h264_idct8_add() Fixes: 2891/clusterfuzz-testcase-minimized-5881795457318912 Fixes: runtime error: signed integer overflow: 1551827968 - -775913984 cannot be represented in type 'int' Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/h264idct_template.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/libavcodec/h264idct_template.c b/libavcodec/h264idct_template.c index 288107d5a4f27..3ad58c4a11d8b 100644 --- a/libavcodec/h264idct_template.c +++ b/libavcodec/h264idct_template.c @@ -76,20 +76,20 @@ void FUNCC(ff_h264_idct8_add)(uint8_t *_dst, int16_t *_block, int stride){ for( i = 0; i < 8; i++ ) { - const int a0 = block[i+0*8] + block[i+4*8]; - const int a2 = block[i+0*8] - block[i+4*8]; - const int a4 = (block[i+2*8]>>1) - block[i+6*8]; - const int a6 = (block[i+6*8]>>1) + block[i+2*8]; - - const int b0 = a0 + a6; - const int b2 = a2 + a4; - const int b4 = a2 - a4; - const int b6 = a0 - a6; - - const int a1 = -block[i+3*8] + block[i+5*8] - block[i+7*8] - (block[i+7*8]>>1); - const int a3 = block[i+1*8] + block[i+7*8] - block[i+3*8] - (block[i+3*8]>>1); - const int a5 = -block[i+1*8] + block[i+7*8] + block[i+5*8] + (block[i+5*8]>>1); - const int a7 = block[i+3*8] + block[i+5*8] + block[i+1*8] + (block[i+1*8]>>1); + const unsigned int a0 = block[i+0*8] + block[i+4*8]; + const unsigned int a2 = block[i+0*8] - block[i+4*8]; + const unsigned int a4 = (block[i+2*8]>>1) - block[i+6*8]; + const unsigned int a6 = (block[i+6*8]>>1) + block[i+2*8]; + + const unsigned int b0 = a0 + a6; + const unsigned int b2 = a2 + a4; + const unsigned int b4 = a2 - a4; + const unsigned int b6 = a0 - a6; + + const int a1 = -block[i+3*8] + (unsigned)block[i+5*8] - block[i+7*8] - (block[i+7*8]>>1); + const int a3 = block[i+1*8] + (unsigned)block[i+7*8] - block[i+3*8] - (block[i+3*8]>>1); + const int a5 = -block[i+1*8] + (unsigned)block[i+7*8] + block[i+5*8] + (block[i+5*8]>>1); + const int a7 = block[i+3*8] + (unsigned)block[i+5*8] + block[i+1*8] + (block[i+1*8]>>1); const int b1 = (a7>>2) + a1; const int b3 = a3 + (a5>>2); From 2a83866c9f9531eb096c9b9fe0550e742b931ad1 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 27 Aug 2017 23:59:09 +0200 Subject: [PATCH 2900/3374] avcodec/hevc_ps: Fix undefined shift in pcm code Fixes: runtime error: shift exponent -1 is negative Fixes: 3091/clusterfuzz-testcase-minimized-6229767969832960 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/hevc_ps.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index 37eae226e2967..ee31cc093c61c 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -1028,10 +1028,10 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, sps->pcm.log2_min_pcm_cb_size = get_ue_golomb_long(gb) + 3; sps->pcm.log2_max_pcm_cb_size = sps->pcm.log2_min_pcm_cb_size + get_ue_golomb_long(gb); - if (sps->pcm.bit_depth > sps->bit_depth) { + if (FFMAX(sps->pcm.bit_depth, sps->pcm.bit_depth_chroma) > sps->bit_depth) { av_log(avctx, AV_LOG_ERROR, - "PCM bit depth (%d) is greater than normal bit depth (%d)\n", - sps->pcm.bit_depth, sps->bit_depth); + "PCM bit depth (%d, %d) is greater than normal bit depth (%d)\n", + sps->pcm.bit_depth, sps->pcm.bit_depth_chroma, sps->bit_depth); return AVERROR_INVALIDDATA; } From 732f9764561558a388c05483ed6a722a5c67b05c Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 28 Aug 2017 00:30:33 +0200 Subject: [PATCH 2901/3374] avcodec/snowdec: Fix integer overflow in decode_subband_slice_buffered() Fixes: runtime error: signed integer overflow: 267 * 8388608 cannot be represented in type 'int' Fixes: 2743/clusterfuzz-testcase-minimized-5820652076400640 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/snowdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/snowdec.c b/libavcodec/snowdec.c index 734f43e7d18aa..b74c468ce32cf 100644 --- a/libavcodec/snowdec.c +++ b/libavcodec/snowdec.c @@ -140,7 +140,7 @@ static inline void decode_subband_slice_buffered(SnowContext *s, SubBand *b, sli v = b->x_coeff[new_index].coeff; x = b->x_coeff[new_index++].x; while(x < w){ - register int t= ( (v>>1)*qmul + qadd)>>QEXPSHIFT; + register int t= (int)( (v>>1)*(unsigned)qmul + qadd)>>QEXPSHIFT; register int u= -(v&1); line[x] = (t^u) - u; From f762555a90790dbfca016ff81b3a4972c39babb4 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 29 Aug 2017 02:13:21 +0200 Subject: [PATCH 2902/3374] avformat/mxfenc: Replace literal numbers by named enum values. Signed-off-by: Michael Niedermayer --- libavformat/mxfenc.c | 83 ++++++++++++++++++++++++++++++++------------ 1 file changed, 61 insertions(+), 22 deletions(-) diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index a07da69b11aea..cc9ec8c93a071 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -120,6 +120,45 @@ static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st); static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st); static void mxf_write_generic_sound_desc(AVFormatContext *s, AVStream *st); +enum { + INDEX_MPEG2 = 0, + INDEX_AES3, + INDEX_WAV, + INDEX_D10_625_50_50_VIDEO, + INDEX_D10_625_50_50_AUDIO, + INDEX_D10_525_60_50_VIDEO, + INDEX_D10_525_60_50_AUDIO, + INDEX_D10_625_50_40_VIDEO, + INDEX_D10_625_50_40_AUDIO, + INDEX_D10_525_60_40_VIDEO, + INDEX_D10_525_60_40_AUDIO, + INDEX_D10_625_50_30_VIDEO, + INDEX_D10_625_50_30_AUDIO, + INDEX_D10_525_60_30_VIDEO, + INDEX_D10_525_60_30_AUDIO, + INDEX_DV, + INDEX_DV25_525_60, + INDEX_DV25_625_50, + INDEX_DV50_525_60, + INDEX_DV50_625_50, + INDEX_DV100_1080_60, + INDEX_DV100_1080_50, + INDEX_DV100_720_60, + INDEX_DV100_720_50, + INDEX_DNXHD_1080p_10bit_HIGH, + INDEX_DNXHD_1080p_8bit_MEDIUM, + INDEX_DNXHD_1080p_8bit_HIGH, + INDEX_DNXHD_1080i_10bit_HIGH, + INDEX_DNXHD_1080i_8bit_MEDIUM, + INDEX_DNXHD_1080i_8bit_HIGH, + INDEX_DNXHD_720p_10bit, + INDEX_DNXHD_720p_8bit_HIGH, + INDEX_DNXHD_720p_8bit_MEDIUM, + INDEX_DNXHD_720p_8bit_LOW, + INDEX_JPEG2000, + INDEX_H264, +}; + static const MXFContainerEssenceEntry mxf_essence_container_uls[] = { { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x60,0x01 }, { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 }, @@ -1680,37 +1719,37 @@ AVPacket *pkt) switch (cid) { case 1235: - sc->index = 24; + sc->index = INDEX_DNXHD_1080p_10bit_HIGH; sc->component_depth = 10; break; case 1237: - sc->index = 25; + sc->index = INDEX_DNXHD_1080p_8bit_MEDIUM; break; case 1238: - sc->index = 26; + sc->index = INDEX_DNXHD_1080p_8bit_HIGH; break; case 1241: - sc->index = 27; + sc->index = INDEX_DNXHD_1080i_10bit_HIGH; sc->component_depth = 10; break; case 1242: - sc->index = 28; + sc->index = INDEX_DNXHD_1080i_8bit_MEDIUM; break; case 1243: - sc->index = 29; + sc->index = INDEX_DNXHD_1080i_8bit_HIGH; break; case 1250: - sc->index = 30; + sc->index = INDEX_DNXHD_720p_10bit; sc->component_depth = 10; break; case 1251: - sc->index = 31; + sc->index = INDEX_DNXHD_720p_8bit_HIGH; break; case 1252: - sc->index = 32; + sc->index = INDEX_DNXHD_720p_8bit_MEDIUM; break; case 1253: - sc->index = 33; + sc->index = INDEX_DNXHD_720p_8bit_LOW; break; default: return -1; @@ -1771,7 +1810,7 @@ static int mxf_parse_dv_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt) switch (stype) { case 0x18: // DV100 720p - ul_index = 6 + pal; + ul_index = INDEX_DV100_720_50 + pal; frame_size = pal ? 288000 : 240000; if (sc->interlaced) { av_log(s, AV_LOG_ERROR, "source marked as interlaced but codec profile is progressive\n"); @@ -1779,19 +1818,19 @@ static int mxf_parse_dv_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt) } break; case 0x14: // DV100 1080i - ul_index = 4 + pal; + ul_index = INDEX_DV100_1080_50 + pal; frame_size = pal ? 576000 : 480000; break; case 0x04: // DV50 - ul_index = 2 + pal; + ul_index = INDEX_DV50_525_60 + pal; frame_size = pal ? 288000 : 240000; break; default: // DV25 - ul_index = 0 + pal; + ul_index = INDEX_DV25_525_60 + pal; frame_size = pal ? 144000 : 120000; } - sc->index = ul_index + 16; + sc->index = ul_index; sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul; if(s->oformat == &ff_mxf_opatom_muxer) { @@ -2106,15 +2145,15 @@ static int mxf_write_header(AVFormatContext *s) return AVERROR(EINVAL); } if ((sc->video_bit_rate == 50000000) && (mxf->time_base.den == 25)) { - sc->index = 3; + sc->index = INDEX_D10_625_50_50_VIDEO; } else if ((sc->video_bit_rate == 49999840 || sc->video_bit_rate == 50000000) && (mxf->time_base.den != 25)) { - sc->index = 5; + sc->index = INDEX_D10_525_60_50_VIDEO; } else if (sc->video_bit_rate == 40000000) { - if (mxf->time_base.den == 25) sc->index = 7; - else sc->index = 9; + if (mxf->time_base.den == 25) sc->index = INDEX_D10_625_50_40_VIDEO; + else sc->index = INDEX_D10_525_60_40_VIDEO; } else if (sc->video_bit_rate == 30000000) { - if (mxf->time_base.den == 25) sc->index = 11; - else sc->index = 13; + if (mxf->time_base.den == 25) sc->index = INDEX_D10_625_50_30_VIDEO; + else sc->index = INDEX_D10_525_60_30_VIDEO; } else { av_log(s, AV_LOG_ERROR, "error MXF D-10 only support 30/40/50 mbit/s\n"); return -1; @@ -2172,7 +2211,7 @@ static int mxf_write_header(AVFormatContext *s) mxf->timecode_base = (tbc.den + tbc.num/2) / tbc.num; mxf->edit_unit_byte_count = (av_get_bits_per_sample(st->codecpar->codec_id) * st->codecpar->channels) >> 3; - sc->index = 2; + sc->index = INDEX_WAV; } else { mxf->slice_count = 1; } From 1ac03c8dc0a9359cdd33e341303296862a0e5f84 Mon Sep 17 00:00:00 2001 From: Timo Rothenpieler Date: Tue, 29 Aug 2017 13:30:29 +0200 Subject: [PATCH 2903/3374] configure: add support for libnpp* from cuda sdk 9 Signed-off-by: Timo Rothenpieler --- configure | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 61d8160491392..172ff3fc070d7 100755 --- a/configure +++ b/configure @@ -5875,7 +5875,9 @@ enabled libmfx && { use_pkg_config libmfx "mfx/mfxvideo.h" MFXInit || enabled libmodplug && require_pkg_config libmodplug libmodplug/modplug.h ModPlug_Load enabled libmp3lame && require "libmp3lame >= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame enabled libmysofa && require libmysofa "mysofa.h" mysofa_load -lmysofa -enabled libnpp && require libnpp npp.h nppGetLibVersion -lnppi -lnppc +enabled libnpp && { check_lib libnpp npp.h nppGetLibVersion -lnppig -lnppicc -lnppc || + check_lib libnpp npp.h nppGetLibVersion -lnppi -lnppc || + die "ERROR: libnpp not found"; } enabled libopencore_amrnb && require libopencore_amrnb opencore-amrnb/interf_dec.h Decoder_Interface_init -lopencore-amrnb enabled libopencore_amrwb && require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb enabled libopencv && { check_header opencv2/core/core_c.h && From 7fbc0825773eb597c5a3f5679a8d58ced0d9456f Mon Sep 17 00:00:00 2001 From: Ricardo Constantino Date: Tue, 29 Aug 2017 01:46:13 +0100 Subject: [PATCH 2904/3374] compat/cuda/ptx2c: strip CR from each line Windows nvcc + cl.exe produce a .ctx file with CR+LF newlines which need to be stripped to work with gcc. Signed-off-by: Timo Rothenpieler --- compat/cuda/ptx2c.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compat/cuda/ptx2c.sh b/compat/cuda/ptx2c.sh index 1f3702329005a..5ccabbf56f1e0 100755 --- a/compat/cuda/ptx2c.sh +++ b/compat/cuda/ptx2c.sh @@ -29,7 +29,7 @@ NAME="$(basename "$IN" | sed 's/\..*//')" printf "const char %s_ptx[] = \\" "$NAME" > "$OUT" while read LINE do - printf "\n\t\"%s\\\n\"" "$(printf "%s" "$LINE" | sed 's/["\\]/\\&/g')" >> "$OUT" + printf "\n\t\"%s\\\n\"" "$(printf "%s" "$LINE" | sed -e 's/\r//g' -e 's/["\\]/\\&/g')" >> "$OUT" done < "$IN" printf ";\n" >> "$OUT" From 61e4db4bb730409798dff8d87d83459cb888786e Mon Sep 17 00:00:00 2001 From: Paras Chadha Date: Tue, 29 Aug 2017 22:46:44 +0530 Subject: [PATCH 2905/3374] Add FITS Decoder Signed-off-by: Paras Chadha --- Changelog | 1 + doc/general.texi | 2 + libavcodec/Makefile | 2 + libavcodec/allcodecs.c | 1 + libavcodec/avcodec.h | 1 + libavcodec/codec_desc.c | 7 + libavcodec/fits.c | 203 +++++++++++++++++++++++++ libavcodec/fits.h | 79 ++++++++++ libavcodec/fitsdec.c | 318 ++++++++++++++++++++++++++++++++++++++++ libavcodec/version.h | 4 +- 10 files changed, 616 insertions(+), 2 deletions(-) create mode 100644 libavcodec/fits.c create mode 100644 libavcodec/fits.h create mode 100644 libavcodec/fitsdec.c diff --git a/Changelog b/Changelog index b064328c3f8c3..548f67d202507 100644 --- a/Changelog +++ b/Changelog @@ -38,6 +38,7 @@ version : - Some video filters with several inputs now use a common set of options: blend, libvmaf, lut3d, overlay, psnr, ssim. They must always be used by name. +- FITS demuxer and decoder version 3.3: - CrystalHD decoder moved to new decode API diff --git a/doc/general.texi b/doc/general.texi index 7d8da113e6d0c..686460e5aa213 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -593,6 +593,8 @@ following image formats are supported: @tab Digital Picture Exchange @item EXR @tab @tab X @tab OpenEXR +@item FITS @tab @tab X + @tab Flexible Image Transport System @item JPEG @tab X @tab X @tab Progressive JPEG is not supported. @item JPEG 2000 @tab X @tab X diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 982d7f5179f87..6988c03596193 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -291,6 +291,7 @@ OBJS-$(CONFIG_FFV1_DECODER) += ffv1dec.o ffv1.o OBJS-$(CONFIG_FFV1_ENCODER) += ffv1enc.o ffv1.o OBJS-$(CONFIG_FFWAVESYNTH_DECODER) += ffwavesynth.o OBJS-$(CONFIG_FIC_DECODER) += fic.o +OBJS-$(CONFIG_FITS_DECODER) += fitsdec.o fits.o OBJS-$(CONFIG_FLAC_DECODER) += flacdec.o flacdata.o flac.o OBJS-$(CONFIG_FLAC_ENCODER) += flacenc.o flacdata.o flac.o vorbis_data.o OBJS-$(CONFIG_FLASHSV_DECODER) += flashsv.o @@ -847,6 +848,7 @@ OBJS-$(CONFIG_ISO_MEDIA) += mpeg4audio.o mpegaudiodata.o OBJS-$(CONFIG_ADTS_MUXER) += mpeg4audio.o OBJS-$(CONFIG_CAF_DEMUXER) += ac3tab.o OBJS-$(CONFIG_DNXHD_DEMUXER) += dnxhddata.o +OBJS-$(CONFIG_FITS_DEMUXER) += fits.o OBJS-$(CONFIG_FLV_DEMUXER) += mpeg4audio.o OBJS-$(CONFIG_LATM_MUXER) += mpeg4audio.o OBJS-$(CONFIG_MATROSKA_AUDIO_MUXER) += mpeg4audio.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 1e5942d7d19ad..dbde1f985ae8e 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -192,6 +192,7 @@ static void register_all(void) REGISTER_ENCDEC (FFV1, ffv1); REGISTER_ENCDEC (FFVHUFF, ffvhuff); REGISTER_DECODER(FIC, fic); + REGISTER_DECODER(FITS, fits); REGISTER_ENCDEC (FLASHSV, flashsv); REGISTER_ENCDEC (FLASHSV2, flashsv2); REGISTER_DECODER(FLIC, flic); diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 655555092ae88..513236a863728 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -447,6 +447,7 @@ enum AVCodecID { AV_CODEC_ID_SRGC, AV_CODEC_ID_SVG, AV_CODEC_ID_GDV, + AV_CODEC_ID_FITS, /* various PCM "codecs" */ AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 6f43b68b8357b..2fea6805ab64d 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -1463,6 +1463,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS, }, + { + .id = AV_CODEC_ID_FITS, + .type = AVMEDIA_TYPE_VIDEO, + .name = "fits", + .long_name = NULL_IF_CONFIG_SMALL("FITS image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, { .id = AV_CODEC_ID_GIF, .type = AVMEDIA_TYPE_VIDEO, diff --git a/libavcodec/fits.c b/libavcodec/fits.c new file mode 100644 index 0000000000000..365347fc6406a --- /dev/null +++ b/libavcodec/fits.c @@ -0,0 +1,203 @@ +/* + * FITS implementation of common functions + * Copyright (c) 2017 Paras Chadha + * + * 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 "avcodec.h" +#include "libavutil/dict.h" +#include "fits.h" + +int avpriv_fits_header_init(FITSHeader *header, FITSHeaderState state) +{ + header->state = state; + header->naxis_index = 0; + header->blank_found = 0; + header->pcount = 0; + header->gcount = 1; + header->groups = 0; + header->rgb = 0; + header->image_extension = 0; + header->bscale = 1.0; + header->bzero = 0; + header->data_min_found = 0; + header->data_max_found = 0; + return 0; +} + +static int dict_set_if_not_null(AVDictionary ***metadata, char *keyword, char *value) +{ + if (metadata) + av_dict_set(*metadata, keyword, value, 0); + return 0; +} + +/** + * Extract keyword and value from a header line (80 bytes) and store them in keyword and value strings respectively + * @param ptr8 pointer to the data + * @param keyword pointer to the char array in which keyword is to be stored + * @param value pointer to the char array in which value is to be stored + * @return 0 if calculated successfully otherwise AVERROR_INVALIDDATA + */ +static int read_keyword_value(const uint8_t *ptr8, char *keyword, char *value) +{ + int i; + + for (i = 0; i < 8 && ptr8[i] != ' '; i++) { + keyword[i] = ptr8[i]; + } + keyword[i] = '\0'; + + if (ptr8[8] == '=') { + i = 10; + while (i < 80 && ptr8[i] == ' ') { + i++; + } + + if (i < 80) { + *value++ = ptr8[i]; + i++; + if (ptr8[i-1] == '\'') { + for (; i < 80 && ptr8[i] != '\''; i++) { + *value++ = ptr8[i]; + } + *value++ = '\''; + } else if (ptr8[i-1] == '(') { + for (; i < 80 && ptr8[i] != ')'; i++) { + *value++ = ptr8[i]; + } + *value++ = ')'; + } else { + for (; i < 80 && ptr8[i] != ' ' && ptr8[i] != '/'; i++) { + *value++ = ptr8[i]; + } + } + } + } + *value = '\0'; + return 0; +} + +#define CHECK_KEYWORD(key) \ + if (strcmp(keyword, key)) { \ + av_log(avcl, AV_LOG_ERROR, "expected %s keyword, found %s = %s\n", key, keyword, value); \ + return AVERROR_INVALIDDATA; \ + } + +#define CHECK_VALUE(key, val) \ + if (sscanf(value, "%d", &header->val) != 1) { \ + av_log(avcl, AV_LOG_ERROR, "invalid value of %s keyword, %s = %s\n", key, keyword, value); \ + return AVERROR_INVALIDDATA; \ + } + +int avpriv_fits_header_parse_line(void *avcl, FITSHeader *header, const uint8_t line[80], AVDictionary ***metadata) +{ + int dim_no, ret; + int64_t t; + double d; + char keyword[10], value[72], c; + + read_keyword_value(line, keyword, value); + switch (header->state) { + case STATE_SIMPLE: + CHECK_KEYWORD("SIMPLE"); + + if (value[0] == 'F') { + av_log(avcl, AV_LOG_WARNING, "not a standard FITS file\n"); + } else if (value[0] != 'T') { + av_log(avcl, AV_LOG_ERROR, "invalid value of SIMPLE keyword, SIMPLE = %c\n", value[0]); + return AVERROR_INVALIDDATA; + } + + header->state = STATE_BITPIX; + break; + case STATE_XTENSION: + CHECK_KEYWORD("XTENSION"); + + if (!strcmp(value, "'IMAGE '")) { + header->image_extension = 1; + } + + header->state = STATE_BITPIX; + break; + case STATE_BITPIX: + CHECK_KEYWORD("BITPIX"); + CHECK_VALUE("BITPIX", bitpix); + dict_set_if_not_null(metadata, keyword, value); + + header->state = STATE_NAXIS; + break; + case STATE_NAXIS: + CHECK_KEYWORD("NAXIS"); + CHECK_VALUE("NAXIS", naxis); + dict_set_if_not_null(metadata, keyword, value); + + if (header->naxis) { + header->state = STATE_NAXIS_N; + } else { + header->state = STATE_REST; + } + break; + case STATE_NAXIS_N: + ret = sscanf(keyword, "NAXIS%d", &dim_no); + if (ret != 1 || dim_no != header->naxis_index + 1) { + av_log(avcl, AV_LOG_ERROR, "expected NAXIS%d keyword, found %s = %s\n", header->naxis_index + 1, keyword, value); + return AVERROR_INVALIDDATA; + } + + if (sscanf(value, "%d", &header->naxisn[header->naxis_index]) != 1) { + av_log(avcl, AV_LOG_ERROR, "invalid value of NAXIS%d keyword, %s = %s\n", header->naxis_index + 1, keyword, value); + return AVERROR_INVALIDDATA; + } + + dict_set_if_not_null(metadata, keyword, value); + header->naxis_index++; + if (header->naxis_index == header->naxis) { + header->state = STATE_REST; + } + break; + case STATE_REST: + if (!strcmp(keyword, "BLANK") && sscanf(value, "%"SCNd64"", &t) == 1) { + header->blank = t; + header->blank_found = 1; + } else if (!strcmp(keyword, "BSCALE") && sscanf(value, "%lf", &d) == 1) { + header->bscale = d; + } else if (!strcmp(keyword, "BZERO") && sscanf(value, "%lf", &d) == 1) { + header->bzero = d; + } else if (!strcmp(keyword, "CTYPE3") && !strncmp(value, "'RGB", 4)) { + header->rgb = 1; + } else if (!strcmp(keyword, "DATAMAX") && sscanf(value, "%lf", &d) == 1) { + header->data_max_found = 1; + header->data_max = d; + } else if (!strcmp(keyword, "DATAMIN") && sscanf(value, "%lf", &d) == 1) { + header->data_min_found = 1; + header->data_min = d; + } else if (!strcmp(keyword, "END")) { + return 1; + } else if (!strcmp(keyword, "GROUPS") && sscanf(value, "%c", &c) == 1) { + header->groups = (c == 'T'); + } else if (!strcmp(keyword, "GCOUNT") && sscanf(value, "%"SCNd64"", &t) == 1) { + header->gcount = t; + } else if (!strcmp(keyword, "PCOUNT") && sscanf(value, "%"SCNd64"", &t) == 1) { + header->pcount = t; + } + dict_set_if_not_null(metadata, keyword, value); + break; + } + return 0; +} diff --git a/libavcodec/fits.h b/libavcodec/fits.h new file mode 100644 index 0000000000000..2cf9e7c1312b2 --- /dev/null +++ b/libavcodec/fits.h @@ -0,0 +1,79 @@ +/* + * FITS image format common prototypes and structures + * Copyright (c) 2017 Paras Chadha + * + * 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 + */ + +#ifndef AVCODEC_FITS_H +#define AVCODEC_FITS_H + +typedef enum FITSHeaderState { + STATE_SIMPLE, + STATE_XTENSION, + STATE_BITPIX, + STATE_NAXIS, + STATE_NAXIS_N, + STATE_PCOUNT, + STATE_GCOUNT, + STATE_REST, +} FITSHeaderState; + +/** + * Structure to store the header keywords in FITS file + */ +typedef struct FITSHeader { + FITSHeaderState state; + unsigned naxis_index; + int bitpix; + int64_t blank; + int blank_found; + int naxis; + int naxisn[999]; + int pcount; + int gcount; + int groups; + int rgb; /**< 1 if file contains RGB image, 0 otherwise */ + int image_extension; + double bscale; + double bzero; + int data_min_found; + double data_min; + int data_max_found; + double data_max; +} FITSHeader; + + +/** + * Initialize a single header line + * @param header pointer to the header + * @param state current state of parsing the header + * @return 0 if successful otherwise AVERROR_INVALIDDATA + */ +int avpriv_fits_header_init(FITSHeader *header, FITSHeaderState state); + +/** + * Parse a single header line + * @param avcl used in av_log + * @param header pointer to the header + * @param line one header line + * @param metadata used to store metadata while decoding + * @return 0 if successful otherwise AVERROR_INVALIDDATA + */ +int avpriv_fits_header_parse_line(void *avcl, FITSHeader *header, const uint8_t line[80], AVDictionary ***metadata); + +#endif /* AVCODEC_FITS_H */ diff --git a/libavcodec/fitsdec.c b/libavcodec/fitsdec.c new file mode 100644 index 0000000000000..8ede0bcbfad4f --- /dev/null +++ b/libavcodec/fitsdec.c @@ -0,0 +1,318 @@ +/* + * FITS image decoder + * Copyright (c) 2017 Paras Chadha + * + * 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 + */ + +/** + * @file + * FITS image decoder + * + * Specification: https://fits.gsfc.nasa.gov/fits_standard.html Version 3.0 + * + * Support all 2d images alongwith, bzero, bscale and blank keywords. + * RGBA images are supported as NAXIS3 = 3 or 4 i.e. Planes in RGBA order. Also CTYPE = 'RGB ' should be present. + * Also to interpret data, values are linearly scaled using min-max scaling but not RGB images. + */ + +#include "avcodec.h" +#include "internal.h" +#include +#include "libavutil/intreadwrite.h" +#include "libavutil/intfloat.h" +#include "libavutil/dict.h" +#include "libavutil/opt.h" +#include "fits.h" + +typedef struct FITSContext { + const AVClass *class; + int blank_val; +} FITSContext; + +/** + * Calculate the data_min and data_max values from the data. + * This is called if the values are not present in the header. + * @param ptr8 pointer to the data + * @param header pointer to the header + * @param end pointer to end of packet + * @return 0 if calculated successfully otherwise AVERROR_INVALIDDATA + */ +static int fill_data_min_max(const uint8_t *ptr8, FITSHeader *header, const uint8_t *end) +{ + uint8_t t8; + int16_t t16; + int32_t t32; + int64_t t64; + float tflt; + double tdbl; + int i, j; + + header->data_min = DBL_MAX; + header->data_max = DBL_MIN; + switch (header->bitpix) { +#define CASE_N(a, t, rd) \ + case a: \ + for (i = 0; i < header->naxisn[1]; i++) { \ + for (j = 0; j < header->naxisn[0]; j++) { \ + t = rd; \ + if (!header->blank_found || t != header->blank) { \ + if (t > header->data_max) \ + header->data_max = t; \ + if (t < header->data_min) \ + header->data_min = t; \ + } \ + ptr8 += abs(a) >> 3; \ + } \ + } \ + break + + CASE_N(-64, tdbl, av_int2double(AV_RB64(ptr8))); + CASE_N(-32, tflt, av_int2float(AV_RB32(ptr8))); + CASE_N(8, t8, ptr8[0]); + CASE_N(16, t16, AV_RB16(ptr8)); + CASE_N(32, t32, AV_RB32(ptr8)); + CASE_N(64, t64, AV_RB64(ptr8)); + default: + return AVERROR_INVALIDDATA; + } + return 0; +} + +/** + * Read the fits header and store the values in FITSHeader pointed by header + * @param avctx AVCodec context + * @param ptr pointer to pointer to the data + * @param header pointer to the FITSHeader + * @param end pointer to end of packet + * @param metadata pointer to pointer to AVDictionary to store metadata + * @return 0 if calculated successfully otherwise AVERROR_INVALIDDATA + */ +static int fits_read_header(AVCodecContext *avctx, const uint8_t **ptr, FITSHeader *header, + const uint8_t *end, AVDictionary **metadata) +{ + const uint8_t *ptr8 = *ptr; + int lines_read, bytes_left, i, ret; + size_t size; + + lines_read = 1; // to account for first header line, SIMPLE or XTENSION which is not included in packet... + avpriv_fits_header_init(header, STATE_BITPIX); + do { + if (end - ptr8 < 80) + return AVERROR_INVALIDDATA; + ret = avpriv_fits_header_parse_line(avctx, header, ptr8, &metadata); + ptr8 += 80; + lines_read++; + } while (!ret); + if (ret < 0) + return ret; + + bytes_left = (((lines_read + 35) / 36) * 36 - lines_read) * 80; + if (end - ptr8 < bytes_left) + return AVERROR_INVALIDDATA; + ptr8 += bytes_left; + + if (header->rgb && (header->naxis != 3 || (header->naxisn[2] != 3 && header->naxisn[2] != 4))) { + av_log(avctx, AV_LOG_ERROR, "File contains RGB image but NAXIS = %d and NAXIS3 = %d\n", header->naxis, header->naxisn[2]); + return AVERROR_INVALIDDATA; + } + + if (!header->rgb && header->naxis != 2) { + av_log(avctx, AV_LOG_ERROR, "unsupported number of dimensions, NAXIS = %d\n", header->naxis); + return AVERROR_INVALIDDATA; + } + + if (header->blank_found && (header->bitpix == -32 || header->bitpix == -64)) { + av_log(avctx, AV_LOG_WARNING, "BLANK keyword found but BITPIX = %d\n. Ignoring BLANK", header->bitpix); + header->blank_found = 0; + } + + size = abs(header->bitpix) >> 3; + for (i = 0; i < header->naxis; i++) { + if (header->naxisn[i] > SIZE_MAX / size) { + av_log(avctx, AV_LOG_ERROR, "unsupported size of FITS image"); + return AVERROR_INVALIDDATA; + } + size *= header->naxisn[i]; + } + + if (end - ptr8 < size) + return AVERROR_INVALIDDATA; + *ptr = ptr8; + + if (!header->rgb && (!header->data_min_found || !header->data_max_found)) { + ret = fill_data_min_max(ptr8, header, end); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "invalid BITPIX, %d\n", header->bitpix); + return ret; + } + } else { + /* + * instead of applying bscale and bzero to every element, + * we can do inverse transformation on data_min and data_max + */ + header->data_min = (header->data_min - header->bzero) / header->bscale; + header->data_max = (header->data_max - header->bzero) / header->bscale; + } + + return 0; +} + +static int fits_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) +{ + AVFrame *p=data; + const uint8_t *ptr8 = avpkt->data, *end; + uint8_t t8; + int16_t t16; + int32_t t32; + int64_t t64; + float tflt; + double tdbl; + int ret, i, j, k; + const int map[] = {2, 0, 1, 3}; // mapping from GBRA -> RGBA as RGBA is to be stored in FITS file.. + uint8_t *dst8; + uint16_t *dst16; + uint64_t t; + FITSHeader header; + FITSContext * fitsctx = avctx->priv_data; + + end = ptr8 + avpkt->size; + p->metadata = NULL; + ret = fits_read_header(avctx, &ptr8, &header, end, &p->metadata); + if (ret < 0) + return ret; + + if (header.rgb) { + if (header.bitpix == 8) { + if (header.naxisn[2] == 3) { + avctx->pix_fmt = AV_PIX_FMT_GBRP; + } else { + avctx->pix_fmt = AV_PIX_FMT_GBRAP; + } + } else if (header.bitpix == 16) { + if (header.naxisn[2] == 3) { + avctx->pix_fmt = AV_PIX_FMT_GBRP16; + } else { + avctx->pix_fmt = AV_PIX_FMT_GBRAP16; + } + } else { + av_log(avctx, AV_LOG_ERROR, "unsupported BITPIX = %d\n", header.bitpix); + return AVERROR_INVALIDDATA; + } + } else { + if (header.bitpix == 8) { + avctx->pix_fmt = AV_PIX_FMT_GRAY8; + } else { + avctx->pix_fmt = AV_PIX_FMT_GRAY16; + } + } + + if ((ret = ff_set_dimensions(avctx, header.naxisn[0], header.naxisn[1])) < 0) + return ret; + + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) + return ret; + + /* + * FITS stores images with bottom row first. Therefore we have + * to fill the image from bottom to top. + */ + if (header.rgb) { + switch(header.bitpix) { +#define CASE_RGB(cas, dst, type, dref) \ + case cas: \ + for (k = 0; k < header.naxisn[2]; k++) { \ + for (i = 0; i < avctx->height; i++) { \ + dst = (type *) (p->data[map[k]] + (avctx->height - i - 1) * p->linesize[map[k]]); \ + for (j = 0; j < avctx->width; j++) { \ + t32 = dref(ptr8); \ + if (!header.blank_found || t32 != header.blank) { \ + t = t32 * header.bscale + header.bzero; \ + } else { \ + t = fitsctx->blank_val; \ + } \ + *dst++ = (type) t; \ + ptr8 += cas >> 3; \ + } \ + } \ + } \ + break + + CASE_RGB(8, dst8, uint8_t, *); + CASE_RGB(16, dst16, uint16_t, AV_RB16); + } + } else { + switch (header.bitpix) { +#define CASE_GRAY(cas, dst, type, t, rd) \ + case cas: \ + for (i = 0; i < avctx->height; i++) { \ + dst = (type *) (p->data[0] + (avctx->height-i-1)* p->linesize[0]); \ + for (j = 0; j < avctx->width; j++) { \ + t = rd; \ + if (!header.blank_found || t != header.blank) { \ + t = ((t - header.data_min) * ((1 << (sizeof(type) * 8)) - 1)) / (header.data_max - header.data_min); \ + } else { \ + t = fitsctx->blank_val; \ + } \ + *dst++ = (type) t; \ + ptr8 += abs(cas) >> 3; \ + } \ + } \ + break + + CASE_GRAY(-64, dst16, uint16_t, tdbl, av_int2double(AV_RB64(ptr8))); + CASE_GRAY(-32, dst16, uint16_t, tflt, av_int2float(AV_RB32(ptr8))); + CASE_GRAY(8, dst8, uint8_t, t8, ptr8[0]); + CASE_GRAY(16, dst16, uint16_t, t16, AV_RB16(ptr8)); + CASE_GRAY(32, dst16, uint16_t, t32, AV_RB32(ptr8)); + CASE_GRAY(64, dst16, uint16_t, t64, AV_RB64(ptr8)); + default: + av_log(avctx, AV_LOG_ERROR, "invalid BITPIX, %d\n", header.bitpix); + return AVERROR_INVALIDDATA; + } + } + + p->key_frame = 1; + p->pict_type = AV_PICTURE_TYPE_I; + + *got_frame = 1; + + return avpkt->size; +} + +static const AVOption fits_options[] = { + { "blank_value", "value that is used to replace BLANK pixels in data array", offsetof(FITSContext, blank_val), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 65535, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM}, + { NULL }, +}; + +static const AVClass fits_decoder_class = { + .class_name = "FITS decoder", + .item_name = av_default_item_name, + .option = fits_options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_fits_decoder = { + .name = "fits", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_FITS, + .priv_data_size = sizeof(FITSContext), + .decode = fits_decode_frame, + .capabilities = AV_CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("Flexible Image Transport System"), + .priv_class = &fits_decoder_class +}; diff --git a/libavcodec/version.h b/libavcodec/version.h index 1db347a9f3ebf..22cab7b0ddf0a 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 103 -#define LIBAVCODEC_VERSION_MICRO 101 +#define LIBAVCODEC_VERSION_MINOR 104 +#define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From 207f0cff2ac8e79747eca0de06666bfcd823d4b7 Mon Sep 17 00:00:00 2001 From: Paras Chadha Date: Tue, 29 Aug 2017 22:42:26 +0530 Subject: [PATCH 2906/3374] Add FITS Demuxer Signed-off-by: Paras Chadha --- libavformat/Makefile | 1 + libavformat/allformats.c | 1 + libavformat/fitsdec.c | 231 +++++++++++++++++++++++++++++++++++++++ libavformat/version.h | 2 +- 4 files changed, 234 insertions(+), 1 deletion(-) create mode 100644 libavformat/fitsdec.c diff --git a/libavformat/Makefile b/libavformat/Makefile index f2b465cfa2b95..dfae160beebf7 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -164,6 +164,7 @@ OBJS-$(CONFIG_FFMETADATA_MUXER) += ffmetaenc.o OBJS-$(CONFIG_FIFO_MUXER) += fifo.o OBJS-$(CONFIG_FILMSTRIP_DEMUXER) += filmstripdec.o OBJS-$(CONFIG_FILMSTRIP_MUXER) += filmstripenc.o +OBJS-$(CONFIG_FITS_DEMUXER) += fitsdec.o OBJS-$(CONFIG_FLAC_DEMUXER) += flacdec.o rawdec.o \ flac_picture.o \ oggparsevorbis.o \ diff --git a/libavformat/allformats.c b/libavformat/allformats.c index cd8200ea1c9f0..f23a9a06e56f6 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -121,6 +121,7 @@ static void register_all(void) REGISTER_MUXDEMUX(FFMETADATA, ffmetadata); REGISTER_MUXER (FIFO, fifo); REGISTER_MUXDEMUX(FILMSTRIP, filmstrip); + REGISTER_DEMUXER (FITS, fits); REGISTER_MUXDEMUX(FLAC, flac); REGISTER_DEMUXER (FLIC, flic); REGISTER_MUXDEMUX(FLV, flv); diff --git a/libavformat/fitsdec.c b/libavformat/fitsdec.c new file mode 100644 index 0000000000000..4b288b3903939 --- /dev/null +++ b/libavformat/fitsdec.c @@ -0,0 +1,231 @@ +/* + * FITS demuxer + * Copyright (c) 2017 Paras Chadha + * + * 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 + */ + +/** + * @file + * FITS demuxer. + */ + +#include "libavutil/intreadwrite.h" +#include "internal.h" +#include "libavutil/opt.h" +#include "libavcodec/fits.h" +#include "libavutil/bprint.h" + +#define FITS_BLOCK_SIZE 2880 + +typedef struct FITSContext { + const AVClass *class; + AVRational framerate; + int first_image; + int64_t pts; +} FITSContext; + +static int fits_probe(AVProbeData *p) +{ + const uint8_t *b = p->buf; + if (!memcmp(b, "SIMPLE = T", 30)) + return AVPROBE_SCORE_MAX - 1; + return 0; +} + +static int fits_read_header(AVFormatContext *s) +{ + AVStream *st; + FITSContext * fits = s->priv_data; + + st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + + st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; + st->codecpar->codec_id = AV_CODEC_ID_FITS; + + avpriv_set_pts_info(st, 64, fits->framerate.den, fits->framerate.num); + fits->pts = 0; + fits->first_image = 1; + return 0; +} + +/** + * Parses header and checks that the current HDU contains image or not + * It also stores the header in the avbuf and stores the size of data part in data_size + * @param s pointer to AVFormat Context + * @param fits pointer to FITSContext + * @param header pointer to FITSHeader + * @param avbuf pointer to AVBPrint to store the header + * @param data_size to store the size of data part + * @return 1 if image found, 0 if any other extension and AVERROR_INVALIDDATA otherwise + */ +static int64_t is_image(AVFormatContext *s, FITSContext *fits, FITSHeader *header, + AVBPrint *avbuf, uint64_t *data_size) +{ + int i, ret, image = 0; + char buf[FITS_BLOCK_SIZE] = { 0 }; + int64_t buf_size = 0, size = 0, t; + + do { + ret = avio_read(s->pb, buf, FITS_BLOCK_SIZE); + if (ret < 0) { + return ret; + } else if (ret < FITS_BLOCK_SIZE) { + return AVERROR_INVALIDDATA; + } + + av_bprint_append_data(avbuf, buf, FITS_BLOCK_SIZE); + ret = 0; + buf_size = 0; + while(!ret && buf_size < FITS_BLOCK_SIZE) { + ret = avpriv_fits_header_parse_line(s, header, buf + buf_size, NULL); + buf_size += 80; + } + } while (!ret); + if (ret < 0) + return ret; + + image = fits->first_image || header->image_extension; + fits->first_image = 0; + + if (header->groups) { + image = 0; + if (header->naxis > 1) + size = 1; + } else if (header->naxis) { + size = header->naxisn[0]; + } else { + image = 0; + } + + for (i = 1; i < header->naxis; i++) { + if(size && header->naxisn[i] > UINT64_MAX / size) + return AVERROR_INVALIDDATA; + size *= header->naxisn[i]; + } + + if(header->pcount > UINT64_MAX - size) + return AVERROR_INVALIDDATA; + size += header->pcount; + + t = (abs(header->bitpix) >> 3) * ((int64_t) header->gcount); + if(size && t > UINT64_MAX / size) + return AVERROR_INVALIDDATA; + size *= t; + + if (!size) { + image = 0; + } else { + if(FITS_BLOCK_SIZE - 1 > UINT64_MAX - size) + return AVERROR_INVALIDDATA; + size = ((size + FITS_BLOCK_SIZE - 1) / FITS_BLOCK_SIZE) * FITS_BLOCK_SIZE; + } + *data_size = size; + return image; +} + +static int fits_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + int64_t pos, ret; + uint64_t size; + FITSContext *fits = s->priv_data; + FITSHeader header; + AVBPrint avbuf; + char *buf; + + if (fits->first_image) { + avpriv_fits_header_init(&header, STATE_SIMPLE); + } else { + avpriv_fits_header_init(&header, STATE_XTENSION); + } + + av_bprint_init(&avbuf, FITS_BLOCK_SIZE, AV_BPRINT_SIZE_UNLIMITED); + while ((ret = is_image(s, fits, &header, &avbuf, &size)) == 0) { + pos = avio_skip(s->pb, size); + if (pos < 0) + return pos; + + av_bprint_finalize(&avbuf, NULL); + av_bprint_init(&avbuf, FITS_BLOCK_SIZE, AV_BPRINT_SIZE_UNLIMITED); + avpriv_fits_header_init(&header, STATE_XTENSION); + } + if (ret < 0) + goto fail; + + if (!av_bprint_is_complete(&avbuf)) { + ret = AVERROR(ENOMEM); + goto fail; + } + + // Header is sent with the first line removed... + ret = av_new_packet(pkt, avbuf.len - 80 + size); + if (ret < 0) + goto fail; + + pkt->stream_index = 0; + pkt->flags |= AV_PKT_FLAG_KEY; + + ret = av_bprint_finalize(&avbuf, &buf); + if (ret < 0) { + av_packet_unref(pkt); + return ret; + } + + memcpy(pkt->data, buf + 80, avbuf.len - 80); + pkt->size = avbuf.len - 80; + av_freep(&buf); + ret = avio_read(s->pb, pkt->data + pkt->size, size); + if (ret < 0) { + av_packet_unref(pkt); + return ret; + } + + pkt->size += ret; + pkt->pts = fits->pts; + fits->pts++; + + return 0; + +fail: + av_bprint_finalize(&avbuf, NULL); + return ret; +} + +static const AVOption fits_options[] = { + { "framerate", "set the framerate", offsetof(FITSContext, framerate), AV_OPT_TYPE_VIDEO_RATE, {.str = "1"}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM}, + { NULL }, +}; + +static const AVClass fits_demuxer_class = { + .class_name = "FITS demuxer", + .item_name = av_default_item_name, + .option = fits_options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVInputFormat ff_fits_demuxer = { + .name = "fits", + .long_name = NULL_IF_CONFIG_SMALL("Flexible Image Transport System"), + .priv_data_size = sizeof(FITSContext), + .read_probe = fits_probe, + .read_header = fits_read_header, + .read_packet = fits_read_packet, + .priv_class = &fits_demuxer_class, + .raw_codec_id = AV_CODEC_ID_FITS, +}; diff --git a/libavformat/version.h b/libavformat/version.h index 94081aca81caf..3029a5e767945 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ // 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 57 -#define LIBAVFORMAT_VERSION_MINOR 78 +#define LIBAVFORMAT_VERSION_MINOR 79 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ From 6e02f66f1bc7c9d559bc7ef3393c66cd800d4651 Mon Sep 17 00:00:00 2001 From: Paras Chadha Date: Tue, 29 Aug 2017 22:49:30 +0530 Subject: [PATCH 2907/3374] Add FITS Encoder Signed-off-by: Paras Chadha --- Changelog | 1 + doc/general.texi | 2 +- libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 2 +- libavcodec/fitsenc.c | 129 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 libavcodec/fitsenc.c diff --git a/Changelog b/Changelog index 548f67d202507..830941757e61a 100644 --- a/Changelog +++ b/Changelog @@ -39,6 +39,7 @@ version : blend, libvmaf, lut3d, overlay, psnr, ssim. They must always be used by name. - FITS demuxer and decoder +- FITS muxer and encoder version 3.3: - CrystalHD decoder moved to new decode API diff --git a/doc/general.texi b/doc/general.texi index 686460e5aa213..5299a9b58cade 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -593,7 +593,7 @@ following image formats are supported: @tab Digital Picture Exchange @item EXR @tab @tab X @tab OpenEXR -@item FITS @tab @tab X +@item FITS @tab X @tab X @tab Flexible Image Transport System @item JPEG @tab X @tab X @tab Progressive JPEG is not supported. diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 6988c03596193..999632cf9e001 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -292,6 +292,7 @@ OBJS-$(CONFIG_FFV1_ENCODER) += ffv1enc.o ffv1.o OBJS-$(CONFIG_FFWAVESYNTH_DECODER) += ffwavesynth.o OBJS-$(CONFIG_FIC_DECODER) += fic.o OBJS-$(CONFIG_FITS_DECODER) += fitsdec.o fits.o +OBJS-$(CONFIG_FITS_ENCODER) += fitsenc.o OBJS-$(CONFIG_FLAC_DECODER) += flacdec.o flacdata.o flac.o OBJS-$(CONFIG_FLAC_ENCODER) += flacenc.o flacdata.o flac.o vorbis_data.o OBJS-$(CONFIG_FLASHSV_DECODER) += flashsv.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index dbde1f985ae8e..ce0bc7ecf30d7 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -192,7 +192,7 @@ static void register_all(void) REGISTER_ENCDEC (FFV1, ffv1); REGISTER_ENCDEC (FFVHUFF, ffvhuff); REGISTER_DECODER(FIC, fic); - REGISTER_DECODER(FITS, fits); + REGISTER_ENCDEC (FITS, fits); REGISTER_ENCDEC (FLASHSV, flashsv); REGISTER_ENCDEC (FLASHSV2, flashsv2); REGISTER_DECODER(FLIC, flic); diff --git a/libavcodec/fitsenc.c b/libavcodec/fitsenc.c new file mode 100644 index 0000000000000..b44507e43660d --- /dev/null +++ b/libavcodec/fitsenc.c @@ -0,0 +1,129 @@ +/* + * FITS image encoder + * Copyright (c) 2017 Paras Chadha + * + * 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 + */ + +/** + * @file + * FITS image encoder + * + * Specification: https://fits.gsfc.nasa.gov/fits_standard.html Version 3.0 + * + * RGBA images are encoded as planes in RGBA order. So, NAXIS3 is 3 or 4 for them. + * Also CTYPE3 = 'RGB ' is added to the header to distinguish them from 3d images. + */ + +#include "libavutil/intreadwrite.h" +#include "avcodec.h" +#include "bytestream.h" +#include "internal.h" + +static int fits_encode_frame(AVCodecContext *avctx, AVPacket *pkt, + const AVFrame *pict, int *got_packet) +{ + AVFrame * const p = (AVFrame *)pict; + uint8_t *bytestream, *bytestream_start, *ptr; + const uint16_t flip = (1 << 15); + uint64_t data_size = 0, padded_data_size = 0; + int ret, bitpix, naxis3 = 1, i, j, k, bytes_left; + int map[] = {2, 0, 1, 3}; // mapping from GBRA -> RGBA as RGBA is to be stored in FITS file.. + + switch (avctx->pix_fmt) { + case AV_PIX_FMT_GRAY8: + case AV_PIX_FMT_GRAY16BE: + map[0] = 0; // grayscale images should be directly mapped + if (avctx->pix_fmt == AV_PIX_FMT_GRAY8) { + bitpix = 8; + } else { + bitpix = 16; + } + break; + case AV_PIX_FMT_GBRP: + case AV_PIX_FMT_GBRAP: + bitpix = 8; + if (avctx->pix_fmt == AV_PIX_FMT_GBRP) { + naxis3 = 3; + } else { + naxis3 = 4; + } + break; + case AV_PIX_FMT_GBRP16BE: + case AV_PIX_FMT_GBRAP16BE: + bitpix = 16; + if (avctx->pix_fmt == AV_PIX_FMT_GBRP16BE) { + naxis3 = 3; + } else { + naxis3 = 4; + } + break; + default: + av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n"); + return AVERROR(EINVAL); + } + + data_size = (bitpix >> 3) * avctx->height * avctx->width * naxis3; + padded_data_size = ((data_size + 2879) / 2880 ) * 2880; + + if ((ret = ff_alloc_packet2(avctx, pkt, padded_data_size, 0)) < 0) + return ret; + + bytestream_start = + bytestream = pkt->data; + + for (k = 0; k < naxis3; k++) { + for (i = 0; i < avctx->height; i++) { + ptr = p->data[map[k]] + (avctx->height - i - 1) * p->linesize[map[k]]; + if (bitpix == 16) { + for (j = 0; j < avctx->width; j++) { + // subtracting bzero is equivalent to first bit flip + bytestream_put_be16(&bytestream, AV_RB16(ptr) ^ flip); + ptr += 2; + } + } else { + memcpy(bytestream, ptr, avctx->width); + bytestream += avctx->width; + } + } + } + + bytes_left = padded_data_size - data_size; + memset(bytestream, 0, bytes_left); + bytestream += bytes_left; + + pkt->size = bytestream - bytestream_start; + pkt->flags |= AV_PKT_FLAG_KEY; + *got_packet = 1; + + return 0; +} + +AVCodec ff_fits_encoder = { + .name = "fits", + .long_name = NULL_IF_CONFIG_SMALL("Flexible Image Transport System"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_FITS, + .encode2 = fits_encode_frame, + .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_GBRAP16BE, + AV_PIX_FMT_GBRP16BE, + AV_PIX_FMT_GBRP, + AV_PIX_FMT_GBRAP, + AV_PIX_FMT_GRAY16BE, + AV_PIX_FMT_GRAY8, + AV_PIX_FMT_NONE }, +}; From df475db9a29e5f3e93dc5f4faa663d30f75ec80b Mon Sep 17 00:00:00 2001 From: Paras Chadha Date: Tue, 29 Aug 2017 22:50:33 +0530 Subject: [PATCH 2908/3374] Add FITS Muxer Signed-off-by: Paras Chadha --- libavformat/Makefile | 1 + libavformat/allformats.c | 2 +- libavformat/fitsenc.c | 183 +++++++++++++++++++++++++++++++++++++++ libavformat/img2enc.c | 2 + 4 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 libavformat/fitsenc.c diff --git a/libavformat/Makefile b/libavformat/Makefile index dfae160beebf7..36f5839aa85ff 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -165,6 +165,7 @@ OBJS-$(CONFIG_FIFO_MUXER) += fifo.o OBJS-$(CONFIG_FILMSTRIP_DEMUXER) += filmstripdec.o OBJS-$(CONFIG_FILMSTRIP_MUXER) += filmstripenc.o OBJS-$(CONFIG_FITS_DEMUXER) += fitsdec.o +OBJS-$(CONFIG_FITS_MUXER) += fitsenc.o OBJS-$(CONFIG_FLAC_DEMUXER) += flacdec.o rawdec.o \ flac_picture.o \ oggparsevorbis.o \ diff --git a/libavformat/allformats.c b/libavformat/allformats.c index f23a9a06e56f6..cb09a60e6f42c 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -121,7 +121,7 @@ static void register_all(void) REGISTER_MUXDEMUX(FFMETADATA, ffmetadata); REGISTER_MUXER (FIFO, fifo); REGISTER_MUXDEMUX(FILMSTRIP, filmstrip); - REGISTER_DEMUXER (FITS, fits); + REGISTER_MUXDEMUX(FITS, fits); REGISTER_MUXDEMUX(FLAC, flac); REGISTER_DEMUXER (FLIC, flic); REGISTER_MUXDEMUX(FLV, flv); diff --git a/libavformat/fitsenc.c b/libavformat/fitsenc.c new file mode 100644 index 0000000000000..0dcdcdfb04f31 --- /dev/null +++ b/libavformat/fitsenc.c @@ -0,0 +1,183 @@ +/* + * FITS muxer + * Copyright (c) 2017 Paras Chadha + * + * 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 + */ + +/** + * @file + * FITS muxer. + */ + +#include "internal.h" + +typedef struct FITSContext { + int first_image; +} FITSContext; + +static int fits_write_header(AVFormatContext *s) +{ + FITSContext *fitsctx = s->priv_data; + fitsctx->first_image = 1; + return 0; +} + +/** + * Write one header line comprising of keyword and value(int) + * @param s AVFormat Context + * @param keyword pointer to the char array in which keyword is stored + * @param value the value corresponding to the keyword + * @param lines_written to keep track of lines written so far + * @return 0 + */ +static int write_keyword_value(AVFormatContext *s, const char *keyword, int value, int *lines_written) +{ + int len, ret; + uint8_t header[80]; + + len = strlen(keyword); + memset(header, ' ', sizeof(header)); + memcpy(header, keyword, len); + + header[8] = '='; + header[9] = ' '; + + ret = snprintf(header + 10, 70, "%d", value); + header[ret + 10] = ' '; + + avio_write(s->pb, header, sizeof(header)); + *lines_written += 1; + return 0; +} + +static int write_image_header(AVFormatContext *s) +{ + AVStream *st = s->streams[0]; + AVCodecParameters *encctx = st->codecpar; + FITSContext *fitsctx = s->priv_data; + uint8_t buffer[80]; + int bitpix, naxis, naxis3 = 1, bzero = 0, rgb = 0, lines_written = 0, lines_left; + + switch (encctx->format) { + case AV_PIX_FMT_GRAY8: + bitpix = 8; + naxis = 2; + break; + case AV_PIX_FMT_GRAY16BE: + bitpix = 16; + naxis = 2; + bzero = 32768; + break; + case AV_PIX_FMT_GBRP: + case AV_PIX_FMT_GBRAP: + bitpix = 8; + naxis = 3; + rgb = 1; + if (encctx->format == AV_PIX_FMT_GBRP) { + naxis3 = 3; + } else { + naxis3 = 4; + } + break; + case AV_PIX_FMT_GBRP16BE: + case AV_PIX_FMT_GBRAP16BE: + bitpix = 16; + naxis = 3; + rgb = 1; + if (encctx->format == AV_PIX_FMT_GBRP16BE) { + naxis3 = 3; + } else { + naxis3 = 4; + } + bzero = 32768; + break; + } + + if (fitsctx->first_image) { + memcpy(buffer, "SIMPLE = ", 10); + memset(buffer + 10, ' ', 70); + buffer[29] = 'T'; + avio_write(s->pb, buffer, sizeof(buffer)); + } else { + memcpy(buffer, "XTENSION= 'IMAGE '", 20); + memset(buffer + 20, ' ', 60); + avio_write(s->pb, buffer, sizeof(buffer)); + } + lines_written++; + + write_keyword_value(s, "BITPIX", bitpix, &lines_written); // no of bits per pixel + write_keyword_value(s, "NAXIS", naxis, &lines_written); // no of dimensions of image + write_keyword_value(s, "NAXIS1", encctx->width, &lines_written); // first dimension i.e. width + write_keyword_value(s, "NAXIS2", encctx->height, &lines_written); // second dimension i.e. height + + if (rgb) + write_keyword_value(s, "NAXIS3", naxis3, &lines_written); // third dimension to store RGBA planes + + if (!fitsctx->first_image) { + write_keyword_value(s, "PCOUNT", 0, &lines_written); + write_keyword_value(s, "GCOUNT", 1, &lines_written); + } else { + fitsctx->first_image = 0; + } + + /* + * Since FITS does not support unsigned 16 bit integers, + * BZERO = 32768 is used to store unsigned 16 bit integers as + * signed integers so that it can be read properly. + */ + if (bitpix == 16) + write_keyword_value(s, "BZERO", bzero, &lines_written); + + if (rgb) { + memcpy(buffer, "CTYPE3 = 'RGB '", 20); + memset(buffer + 20, ' ', 60); + avio_write(s->pb, buffer, sizeof(buffer)); + lines_written++; + } + + memcpy(buffer, "END", 3); + memset(buffer + 3, ' ', 77); + avio_write(s->pb, buffer, sizeof(buffer)); + lines_written++; + + lines_left = ((lines_written + 35) / 36) * 36 - lines_written; + memset(buffer, ' ', 80); + while (lines_left > 0) { + avio_write(s->pb, buffer, sizeof(buffer)); + lines_left--; + } + return 0; +} + +static int fits_write_packet(AVFormatContext *s, AVPacket *pkt) +{ + write_image_header(s); + avio_write(s->pb, pkt->data, pkt->size); + return 0; +} + +AVOutputFormat ff_fits_muxer = { + .name = "fits", + .long_name = NULL_IF_CONFIG_SMALL("Flexible Image Transport System"), + .extensions = "fits", + .priv_data_size = sizeof(FITSContext), + .audio_codec = AV_CODEC_ID_NONE, + .video_codec = AV_CODEC_ID_FITS, + .write_header = fits_write_header, + .write_packet = fits_write_packet, +}; diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c index 1297b1aaba5f8..87b5ec231737d 100644 --- a/libavformat/img2enc.c +++ b/libavformat/img2enc.c @@ -62,6 +62,8 @@ static int write_header(AVFormatContext *s) if (st->codecpar->codec_id == AV_CODEC_ID_GIF) { img->muxer = "gif"; + } else if (st->codecpar->codec_id == AV_CODEC_ID_FITS) { + img->muxer = "fits"; } else if (st->codecpar->codec_id == AV_CODEC_ID_RAWVIDEO) { const char *str = strrchr(img->path, '.'); img->split_planes = str From 9d99f0afbeedf3e170478c3e8c05789bf2eef48f Mon Sep 17 00:00:00 2001 From: Paras Chadha Date: Tue, 29 Aug 2017 23:06:42 +0530 Subject: [PATCH 2909/3374] FATE: Add FITS tests Signed-off-by: Paras Chadha --- tests/Makefile | 1 + tests/fate/avformat.mak | 1 + tests/fate/demux.mak | 4 ++ tests/fate/fits.mak | 59 +++++++++++++++++++++++++ tests/lavf-regression.sh | 9 ++++ tests/ref/fate/fits-demux | 10 +++++ tests/ref/fate/fitsdec-bitpix-32 | 6 +++ tests/ref/fate/fitsdec-bitpix-64 | 6 +++ tests/ref/fate/fitsdec-blank_bitpix32 | 6 +++ tests/ref/fate/fitsdec-ext_data_min_max | 6 +++ tests/ref/fate/fitsdec-gbrap16 | 6 +++ tests/ref/fate/fitsdec-gbrp | 6 +++ tests/ref/fate/fitsdec-gbrp16 | 6 +++ tests/ref/fate/fitsdec-gray | 6 +++ tests/ref/fate/fitsdec-multi | 10 +++++ tests/ref/fate/fitsenc-gbrap | 10 +++++ tests/ref/fate/fitsenc-gbrap16be | 10 +++++ tests/ref/fate/fitsenc-gbrp | 10 +++++ tests/ref/fate/fitsenc-gbrp16be | 10 +++++ tests/ref/fate/fitsenc-gray | 10 +++++ tests/ref/fate/fitsenc-gray16be | 10 +++++ tests/ref/lavf/fits | 18 ++++++++ 22 files changed, 220 insertions(+) create mode 100644 tests/fate/fits.mak create mode 100644 tests/ref/fate/fits-demux create mode 100644 tests/ref/fate/fitsdec-bitpix-32 create mode 100644 tests/ref/fate/fitsdec-bitpix-64 create mode 100644 tests/ref/fate/fitsdec-blank_bitpix32 create mode 100644 tests/ref/fate/fitsdec-ext_data_min_max create mode 100644 tests/ref/fate/fitsdec-gbrap16 create mode 100644 tests/ref/fate/fitsdec-gbrp create mode 100644 tests/ref/fate/fitsdec-gbrp16 create mode 100644 tests/ref/fate/fitsdec-gray create mode 100644 tests/ref/fate/fitsdec-multi create mode 100644 tests/ref/fate/fitsenc-gbrap create mode 100644 tests/ref/fate/fitsenc-gbrap16be create mode 100644 tests/ref/fate/fitsenc-gbrp create mode 100644 tests/ref/fate/fitsenc-gbrp16be create mode 100644 tests/ref/fate/fitsenc-gray create mode 100644 tests/ref/fate/fitsenc-gray16be create mode 100644 tests/ref/lavf/fits diff --git a/tests/Makefile b/tests/Makefile index 30f05bec15548..18fe9c5b4ac3f 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -131,6 +131,7 @@ include $(SRC_PATH)/tests/fate/fft.mak include $(SRC_PATH)/tests/fate/fifo-muxer.mak include $(SRC_PATH)/tests/fate/filter-audio.mak include $(SRC_PATH)/tests/fate/filter-video.mak +include $(SRC_PATH)/tests/fate/fits.mak include $(SRC_PATH)/tests/fate/flac.mak include $(SRC_PATH)/tests/fate/flvenc.mak include $(SRC_PATH)/tests/fate/gapless.mak diff --git a/tests/fate/avformat.mak b/tests/fate/avformat.mak index 82a531c7a5240..c4cf2bc473a76 100644 --- a/tests/fate/avformat.mak +++ b/tests/fate/avformat.mak @@ -10,6 +10,7 @@ FATE_LAVF-$(call ENCDEC, PCM_S16BE, CAF) += caf FATE_LAVF-$(call ENCDEC, DPX, IMAGE2) += dpx FATE_LAVF-$(call ENCDEC2, DVVIDEO, PCM_S16LE, AVI) += dv_fmt FATE_LAVF-$(call ENCDEC2, MPEG1VIDEO, MP2, FFM) += ffm +FATE_LAVF-$(call ENCDEC, FITS, IMAGE2) += fits FATE_LAVF-$(call ENCDEC, RAWVIDEO, FILMSTRIP) += flm FATE_LAVF-$(call ENCDEC, FLV, FLV) += flv_fmt FATE_LAVF-$(call ENCDEC, GIF, IMAGE2) += gif diff --git a/tests/fate/demux.mak b/tests/fate/demux.mak index 8a2703fc840e8..261b004d691f1 100644 --- a/tests/fate/demux.mak +++ b/tests/fate/demux.mak @@ -36,6 +36,10 @@ fate-d-cinema-demux: CMD = framecrc -i $(TARGET_SAMPLES)/d-cinema/THX_Science_FL FATE_SAMPLES_DEMUX-$(CONFIG_EA_DEMUXER) += fate-d-eavp6-demux fate-d-eavp6-demux: CMD = framecrc -i $(TARGET_SAMPLES)/ea-vp6/SmallRing.vp6 -map 0 -vcodec copy +FATE_SAMPLES_DEMUX-$(CONFIG_FITS_DEMUXER) += fate-fits-demux +fate-fits-demux: tests/data/fits-multi.fits +fate-fits-demux: CMD = framecrc -i $(TARGET_PATH)/tests/data/fits-multi.fits -vcodec copy + FATE_SAMPLES_DEMUX-$(CONFIG_FLV_DEMUXER) += fate-flv-demux fate-flv-demux: CMD = framecrc -i $(TARGET_SAMPLES)/flv/Enigma_Principles_of_Lust-part.flv -codec copy diff --git a/tests/fate/fits.mak b/tests/fate/fits.mak new file mode 100644 index 0000000000000..bc1b771a525c6 --- /dev/null +++ b/tests/fate/fits.mak @@ -0,0 +1,59 @@ +tests/data/fits-multi.fits: TAG = GEN +tests/data/fits-multi.fits: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data + $(M)$(TARGET_EXEC) $(TARGET_PATH)/$< \ + -i $(TARGET_SAMPLES)/gif/m4nb.gif \ + -y $(TARGET_PATH)/$(@) 2>/dev/null + +#mapping of fits file formats to png filenames +map.tests/data/lena-gray.fits := gray8 +map.tests/data/lena-gbrp.fits := rgb24 +map.tests/data/lena-gbrp16.fits := rgb48 +map.tests/data/lena-gbrap16.fits := rgba64 + +tests/data/lena%.fits: TAG = GEN +tests/data/lena%.fits: NAME = $(map.$(@)) +tests/data/lena%.fits: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data + $(M)$(TARGET_EXEC) $(TARGET_PATH)/$< \ + -i $(TARGET_SAMPLES)/png1/lena-$(map.$(@)).png \ + -y $(TARGET_PATH)/$(@) 2>/dev/null + +FATE_FITS_DEC-$(call DEMDEC, FITS, FITS) += fate-fitsdec-ext_data_min_max +fate-fitsdec-ext_data_min_max: CMD = framecrc -i $(TARGET_SAMPLES)/fits/x0cj010ct_d0h.fit -pix_fmt gray16 + +FATE_FITS_DEC-$(call DEMDEC, FITS, FITS) += fate-fitsdec-blank_bitpix32 +fate-fitsdec-blank_bitpix32: CMD = framecrc -blank_value 65535 -i $(TARGET_SAMPLES)/fits/file008.fits -pix_fmt gray16 + +FATE_FITS_DEC-$(call DEMDEC, FITS, FITS) += fate-fitsdec-bitpix-32 +fate-fitsdec-bitpix-32: CMD = framecrc -i $(TARGET_SAMPLES)/fits/tst0005.fits -pix_fmt gray16 + +FATE_FITS_DEC-$(call DEMDEC, FITS, FITS) += fate-fitsdec-bitpix-64 +fate-fitsdec-bitpix-64: CMD = framecrc -i $(TARGET_SAMPLES)/fits/tst0006.fits -pix_fmt gray16 + +FATE_FITS_DEC-$(call DEMDEC, FITS, FITS) += fate-fitsdec-multi +fate-fitsdec-multi: tests/data/fits-multi.fits +fate-fitsdec-multi: CMD = framecrc -i $(TARGET_PATH)/tests/data/fits-multi.fits -pix_fmt gbrap + +fate-fitsdec%: PIXFMT = $(word 3, $(subst -, ,$(@))) +fate-fitsdec%: SRC = $(TARGET_PATH)/tests/data/lena-$(PIXFMT).fits +fate-fitsdec%: CMD = framecrc -i $(SRC) -pix_fmt $(PIXFMT) + +FATE_FITS_DEC_PIXFMT = gray gbrp gbrp16 gbrap16 +$(FATE_FITS_DEC_PIXFMT:%=fate-fitsdec-%): fate-fitsdec-%: tests/data/lena-%.fits +FATE_FITS_DEC-$(call DEMDEC, FITS, FITS) += $(FATE_FITS_DEC_PIXFMT:%=fate-fitsdec-%) + +FATE_FITS += $(FATE_FITS_DEC-yes) +fate-fitsdec: $(FATE_FITS_DEC-yes) + +fate-fitsenc%: PIXFMT = $(word 3, $(subst -, ,$(@))) +fate-fitsenc%: SRC = $(TARGET_PATH)/tests/data/fits-multi.fits +fate-fitsenc%: CMD = framecrc -i $(SRC) -c:v fits -pix_fmt $(PIXFMT) + +FATE_FITS_ENC_PIXFMT = gray gray16be gbrp gbrap gbrp16be gbrap16be +$(FATE_FITS_ENC_PIXFMT:%=fate-fitsenc-%): tests/data/fits-multi.fits +FATE_FITS_ENC-$(call ENCDEC, FITS, FITS) += $(FATE_FITS_ENC_PIXFMT:%=fate-fitsenc-%) + +FATE_FITS += $(FATE_FITS_ENC-yes) +fate-fitsenc: $(FATE_FITS_ENC-yes) + +FATE_SAMPLES_FFMPEG += $(FATE_FITS) +fate-fits: $(FATE_FITS) diff --git a/tests/lavf-regression.sh b/tests/lavf-regression.sh index eda40f25dbb5f..d9026de021ad2 100755 --- a/tests/lavf-regression.sh +++ b/tests/lavf-regression.sh @@ -230,6 +230,15 @@ do_avconv $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $ENC_OPTS -t 1 -q #do_avconv_crc $file -i $target_path/$file fi +if [ -n "$do_fits" ] ; then +pix_fmts="gray gray16be gbrp gbrap gbrp16be gbrap16be" +for pix_fmt in $pix_fmts ; do + file=${outfile}${pix_fmt}lavf.fits + do_avconv $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $ENC_OPTS -pix_fmt $pix_fmt + do_avconv_crc $file $DEC_OPTS -i $target_path/$file -pix_fmt $pix_fmt +done +fi + # image formats if [ -n "$do_pgm" ] ; then diff --git a/tests/ref/fate/fits-demux b/tests/ref/fate/fits-demux new file mode 100644 index 0000000000000..85605ab11aea8 --- /dev/null +++ b/tests/ref/fate/fits-demux @@ -0,0 +1,10 @@ +#tb 0: 1/1 +#media_type 0: video +#codec_id 0: fits +#dimensions 0: 72x36 +#sar 0: 0/1 +0, 0, 0, 1, 14320, 0x0ecf72e0 +0, 1, 1, 1, 14320, 0xd94af6eb +0, 2, 2, 1, 14320, 0x15c21892 +0, 3, 3, 1, 14320, 0xb18adc01 +0, 4, 4, 1, 14320, 0xc2be706d diff --git a/tests/ref/fate/fitsdec-bitpix-32 b/tests/ref/fate/fitsdec-bitpix-32 new file mode 100644 index 0000000000000..9bce361555098 --- /dev/null +++ b/tests/ref/fate/fitsdec-bitpix-32 @@ -0,0 +1,6 @@ +#tb 0: 1/1 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 102x109 +#sar 0: 0/1 +0, 0, 0, 1, 22236, 0x34490902 diff --git a/tests/ref/fate/fitsdec-bitpix-64 b/tests/ref/fate/fitsdec-bitpix-64 new file mode 100644 index 0000000000000..9febdd68f4d58 --- /dev/null +++ b/tests/ref/fate/fitsdec-bitpix-64 @@ -0,0 +1,6 @@ +#tb 0: 1/1 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 77x173 +#sar 0: 0/1 +0, 0, 0, 1, 26642, 0x0ad2a46a diff --git a/tests/ref/fate/fitsdec-blank_bitpix32 b/tests/ref/fate/fitsdec-blank_bitpix32 new file mode 100644 index 0000000000000..184fd41c59eb7 --- /dev/null +++ b/tests/ref/fate/fitsdec-blank_bitpix32 @@ -0,0 +1,6 @@ +#tb 0: 1/1 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 256x256 +#sar 0: 0/1 +0, 0, 0, 1, 131072, 0x7fb22427 diff --git a/tests/ref/fate/fitsdec-ext_data_min_max b/tests/ref/fate/fitsdec-ext_data_min_max new file mode 100644 index 0000000000000..9009a4efb3492 --- /dev/null +++ b/tests/ref/fate/fitsdec-ext_data_min_max @@ -0,0 +1,6 @@ +#tb 0: 1/1 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 512x512 +#sar 0: 0/1 +0, 0, 0, 1, 524288, 0xc327ed23 diff --git a/tests/ref/fate/fitsdec-gbrap16 b/tests/ref/fate/fitsdec-gbrap16 new file mode 100644 index 0000000000000..78abb5cde7eeb --- /dev/null +++ b/tests/ref/fate/fitsdec-gbrap16 @@ -0,0 +1,6 @@ +#tb 0: 1/1 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 128x128 +#sar 0: 0/1 +0, 0, 0, 1, 131072, 0x487894b2 diff --git a/tests/ref/fate/fitsdec-gbrp b/tests/ref/fate/fitsdec-gbrp new file mode 100644 index 0000000000000..8767b6715f1fd --- /dev/null +++ b/tests/ref/fate/fitsdec-gbrp @@ -0,0 +1,6 @@ +#tb 0: 1/1 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 128x128 +#sar 0: 0/1 +0, 0, 0, 1, 49152, 0x565c3dee diff --git a/tests/ref/fate/fitsdec-gbrp16 b/tests/ref/fate/fitsdec-gbrp16 new file mode 100644 index 0000000000000..f6368f2c02451 --- /dev/null +++ b/tests/ref/fate/fitsdec-gbrp16 @@ -0,0 +1,6 @@ +#tb 0: 1/1 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 128x128 +#sar 0: 0/1 +0, 0, 0, 1, 98304, 0x1b917bdc diff --git a/tests/ref/fate/fitsdec-gray b/tests/ref/fate/fitsdec-gray new file mode 100644 index 0000000000000..425b31fc0f172 --- /dev/null +++ b/tests/ref/fate/fitsdec-gray @@ -0,0 +1,6 @@ +#tb 0: 1/1 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 128x128 +#sar 0: 0/1 +0, 0, 0, 1, 16384, 0xd788a2d2 diff --git a/tests/ref/fate/fitsdec-multi b/tests/ref/fate/fitsdec-multi new file mode 100644 index 0000000000000..f24f0adaab19b --- /dev/null +++ b/tests/ref/fate/fitsdec-multi @@ -0,0 +1,10 @@ +#tb 0: 1/1 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 72x36 +#sar 0: 0/1 +0, 0, 0, 1, 10368, 0xb4490cc8 +0, 1, 1, 1, 10368, 0x37198e4f +0, 2, 2, 1, 10368, 0x1e89afe7 +0, 3, 3, 1, 10368, 0x80127365 +0, 4, 4, 1, 10368, 0xfd2d07d1 diff --git a/tests/ref/fate/fitsenc-gbrap b/tests/ref/fate/fitsenc-gbrap new file mode 100644 index 0000000000000..3e32fc687e320 --- /dev/null +++ b/tests/ref/fate/fitsenc-gbrap @@ -0,0 +1,10 @@ +#tb 0: 1/1 +#media_type 0: video +#codec_id 0: fits +#dimensions 0: 72x36 +#sar 0: 0/1 +0, 0, 0, 1, 11520, 0xeb0a0cc8 +0, 1, 1, 1, 11520, 0x9d7d8e4f +0, 2, 2, 1, 11520, 0xd9e6afe7 +0, 3, 3, 1, 11520, 0x75bd7365 +0, 4, 4, 1, 11520, 0x86f107d1 diff --git a/tests/ref/fate/fitsenc-gbrap16be b/tests/ref/fate/fitsenc-gbrap16be new file mode 100644 index 0000000000000..1f74f4e750b71 --- /dev/null +++ b/tests/ref/fate/fitsenc-gbrap16be @@ -0,0 +1,10 @@ +#tb 0: 1/1 +#media_type 0: video +#codec_id 0: fits +#dimensions 0: 72x36 +#sar 0: 0/1 +0, 0, 0, 1, 23040, 0xfa4ff4f0 +0, 1, 1, 1, 23040, 0xf57102d4 +0, 2, 2, 1, 23040, 0x58e0294d +0, 3, 3, 1, 23040, 0x8097502a +0, 4, 4, 1, 23040, 0x65fd7b54 diff --git a/tests/ref/fate/fitsenc-gbrp b/tests/ref/fate/fitsenc-gbrp new file mode 100644 index 0000000000000..4101a0e4522a4 --- /dev/null +++ b/tests/ref/fate/fitsenc-gbrp @@ -0,0 +1,10 @@ +#tb 0: 1/1 +#media_type 0: video +#codec_id 0: fits +#dimensions 0: 72x36 +#sar 0: 0/1 +0, 0, 0, 1, 8640, 0xf6b9f643 +0, 1, 1, 1, 8640, 0x250d77d9 +0, 2, 2, 1, 8640, 0x652595e5 +0, 3, 3, 1, 8640, 0x4b8e5963 +0, 4, 4, 1, 8640, 0xd8d611ab diff --git a/tests/ref/fate/fitsenc-gbrp16be b/tests/ref/fate/fitsenc-gbrp16be new file mode 100644 index 0000000000000..d4b043ffe6816 --- /dev/null +++ b/tests/ref/fate/fitsenc-gbrp16be @@ -0,0 +1,10 @@ +#tb 0: 1/1 +#media_type 0: video +#codec_id 0: fits +#dimensions 0: 72x36 +#sar 0: 0/1 +0, 0, 0, 1, 17280, 0x6b87eec5 +0, 1, 1, 1, 17280, 0x1bf0fc9a +0, 2, 2, 1, 17280, 0xaf071b1e +0, 3, 3, 1, 17280, 0xfbe941fb +0, 4, 4, 1, 17280, 0xbbc26d01 diff --git a/tests/ref/fate/fitsenc-gray b/tests/ref/fate/fitsenc-gray new file mode 100644 index 0000000000000..46eb76c43baa3 --- /dev/null +++ b/tests/ref/fate/fitsenc-gray @@ -0,0 +1,10 @@ +#tb 0: 1/1 +#media_type 0: video +#codec_id 0: fits +#dimensions 0: 72x36 +#sar 0: 0/1 +0, 0, 0, 1, 2880, 0xd2d83752 +0, 1, 1, 1, 2880, 0x77246e79 +0, 2, 2, 1, 2880, 0xdf480c1f +0, 3, 3, 1, 2880, 0x559247a9 +0, 4, 4, 1, 2880, 0xc3df2cc4 diff --git a/tests/ref/fate/fitsenc-gray16be b/tests/ref/fate/fitsenc-gray16be new file mode 100644 index 0000000000000..ec4e0efd3c81b --- /dev/null +++ b/tests/ref/fate/fitsenc-gray16be @@ -0,0 +1,10 @@ +#tb 0: 1/1 +#media_type 0: video +#codec_id 0: fits +#dimensions 0: 72x36 +#sar 0: 0/1 +0, 0, 0, 1, 5760, 0x317ba180 +0, 1, 1, 1, 5760, 0x439c9e40 +0, 2, 2, 1, 5760, 0x6136ff8f +0, 3, 3, 1, 5760, 0x2c331324 +0, 4, 4, 1, 5760, 0x2f0816c1 diff --git a/tests/ref/lavf/fits b/tests/ref/lavf/fits new file mode 100644 index 0000000000000..489542b32bea7 --- /dev/null +++ b/tests/ref/lavf/fits @@ -0,0 +1,18 @@ +ed9fd697d0d782df6201f6a2db184552 *./tests/data/lavf/graylavf.fits +5328000 ./tests/data/lavf/graylavf.fits +./tests/data/lavf/graylavf.fits CRC=0xbacf446c +48e6caf6a59e32f9a8a39979c9183a7f *./tests/data/lavf/gray16belavf.fits +10368000 ./tests/data/lavf/gray16belavf.fits +./tests/data/lavf/gray16belavf.fits CRC=0xae2b58d4 +be2f7112fd193c9a909304c81e662769 *./tests/data/lavf/gbrplavf.fits +15408000 ./tests/data/lavf/gbrplavf.fits +./tests/data/lavf/gbrplavf.fits CRC=0x04ed3828 +c89a72185cfad363aa9cc42e84fed301 *./tests/data/lavf/gbraplavf.fits +20448000 ./tests/data/lavf/gbraplavf.fits +./tests/data/lavf/gbraplavf.fits CRC=0x032a6409 +d539b9e02f5ab8fb85717c8adb60b6cc *./tests/data/lavf/gbrp16belavf.fits +30672000 ./tests/data/lavf/gbrp16belavf.fits +./tests/data/lavf/gbrp16belavf.fits CRC=0x81897ff7 +3dc3622fb09a338b406d8a12a30f2545 *./tests/data/lavf/gbrap16belavf.fits +40752000 ./tests/data/lavf/gbrap16belavf.fits +./tests/data/lavf/gbrap16belavf.fits CRC=0x247dd7b9 From a4d18a3f54e5b0277234d8fcff65dff8516417a0 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Wed, 30 Aug 2017 12:06:47 +0200 Subject: [PATCH 2910/3374] avfilter/vf_lut2: add framesync options Also stop leaking memory. Signed-off-by: Paul B Mahol --- libavfilter/vf_lut2.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libavfilter/vf_lut2.c b/libavfilter/vf_lut2.c index 176b98ee80d54..ba599c3d14963 100644 --- a/libavfilter/vf_lut2.c +++ b/libavfilter/vf_lut2.c @@ -52,6 +52,7 @@ enum var_name { typedef struct LUT2Context { const AVClass *class; + FFFrameSync fs; char *comp_expr_str[4]; @@ -66,7 +67,6 @@ typedef struct LUT2Context { void (*lut2)(struct LUT2Context *s, AVFrame *dst, AVFrame *srcx, AVFrame *srcy); - FFFrameSync fs; } LUT2Context; #define OFFSET(x) offsetof(LUT2Context, x) @@ -85,6 +85,7 @@ static av_cold void uninit(AVFilterContext *ctx) LUT2Context *s = ctx->priv; int i; + ff_framesync2_uninit(&s->fs); av_frame_free(&s->prev_frame); for (i = 0; i < 4; i++) { @@ -212,14 +213,14 @@ static int process_frame(FFFrameSync *fs) AVFilterContext *ctx = fs->parent; LUT2Context *s = fs->opaque; AVFilterLink *outlink = ctx->outputs[0]; - AVFrame *out, *srcx, *srcy; + AVFrame *out, *srcx = NULL, *srcy = NULL; int ret; if ((ret = ff_framesync2_get_frame(&s->fs, 0, &srcx, 0)) < 0 || (ret = ff_framesync2_get_frame(&s->fs, 1, &srcy, 0)) < 0) return ret; - if (ctx->is_disabled) { + if (ctx->is_disabled || !srcy) { out = av_frame_clone(srcx); if (!out) return AVERROR(ENOMEM); @@ -332,7 +333,7 @@ static int lut2_config_output(AVFilterLink *outlink) in = s->fs.in; in[0].time_base = srcx->time_base; in[1].time_base = srcy->time_base; - in[0].sync = 1; + in[0].sync = 2; in[0].before = EXT_STOP; in[0].after = EXT_INFINITY; in[1].sync = 1; @@ -378,11 +379,12 @@ static const AVFilterPad outputs[] = { #define lut2_options options -AVFILTER_DEFINE_CLASS(lut2); +FRAMESYNC_DEFINE_CLASS(lut2, LUT2Context, fs); AVFilter ff_vf_lut2 = { .name = "lut2", .description = NULL_IF_CONFIG_SMALL("Compute and apply a lookup table from two video inputs."), + .preinit = lut2_framesync_preinit, .priv_size = sizeof(LUT2Context), .priv_class = &lut2_class, .uninit = uninit, From 2b9fd157342fbe3db86228db4f9e23b52670c264 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Wed, 30 Aug 2017 12:18:22 +0200 Subject: [PATCH 2911/3374] avcodec/codec_desc: make FITS description longer Signed-off-by: Paul B Mahol --- libavcodec/codec_desc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 2fea6805ab64d..6a13bbbf0ee0c 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -1467,7 +1467,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .id = AV_CODEC_ID_FITS, .type = AVMEDIA_TYPE_VIDEO, .name = "fits", - .long_name = NULL_IF_CONFIG_SMALL("FITS image"), + .long_name = NULL_IF_CONFIG_SMALL("FITS (Flexible Image Transport System)"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { From 2a4a26fa4f3c9310cd8cf6a0d093c927f64ef8a7 Mon Sep 17 00:00:00 2001 From: Ashish Singh Date: Thu, 3 Aug 2017 11:04:01 +0530 Subject: [PATCH 2912/3374] avfilter/vf_libvmaf: fix pre convert to framesync2 bugs Hi, it fixes the errors while converting to framesync2. libvmaf was changed recently, double *score variable is removed in the new version since it's not used anywhere. This patch fixes all the warnings and segmentation faults. Signed-off-by: Ashish Singh Signed-off-by: Ronald S. Bultje --- libavfilter/vf_libvmaf.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/libavfilter/vf_libvmaf.c b/libavfilter/vf_libvmaf.c index 2165561c5aede..405820f182864 100644 --- a/libavfilter/vf_libvmaf.c +++ b/libavfilter/vf_libvmaf.c @@ -24,7 +24,6 @@ * Calculate the VMAF between two input videos. */ -#include #include #include #include "libavutil/avstring.h" @@ -84,11 +83,10 @@ static const AVOption libvmaf_options[] = { FRAMESYNC_DEFINE_CLASS(libvmaf, LIBVMAFContext, fs); #define read_frame_fn(type, bits) \ - static int read_frame_##bits##bit(float *ref_data, float *main_data, \ - float *temp_data, int stride, \ - double *score, void *ctx) \ + static int read_frame_##bits##bit(float *ref_data, float *main_data, \ + float *temp_data, int stride, void *ctx) \ { \ - LIBVMAFContext *s = (LIBVMAFContext *) ctx; \ + LIBVMAFContext *s = (LIBVMAFContext *) ctx; \ int ret; \ \ pthread_mutex_lock(&s->lock); \ @@ -150,7 +148,7 @@ read_frame_fn(uint16_t, 10); static void compute_vmaf_score(LIBVMAFContext *s) { int (*read_frame)(float *ref_data, float *main_data, float *temp_data, - int stride, double *score, void *ctx); + int stride, void *ctx); if (s->desc->comp[0].depth <= 8) { read_frame = read_frame_8bit; From 1dc33c123715e195f7f19b2dca8f192a550f047c Mon Sep 17 00:00:00 2001 From: Ashish Singh Date: Tue, 1 Aug 2017 20:44:18 +0530 Subject: [PATCH 2913/3374] configure: require pkg-config for libvmaf This patch makes the libvmaf filter use pkg-config to detect and link to libvmaf. Signed-off-by: Ashish Singh Signed-off-by: Ronald S. Bultje --- configure | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/configure b/configure index 172ff3fc070d7..4f1c172333e1f 100755 --- a/configure +++ b/configure @@ -5920,8 +5920,7 @@ enabled libtwolame && require libtwolame twolame.h twolame_init -ltwolame die "ERROR: libtwolame must be installed and version must be >= 0.3.10"; } enabled libv4l2 && require_pkg_config libv4l2 libv4l2.h v4l2_ioctl enabled libvidstab && require_pkg_config "vidstab >= 0.98" vid.stab/libvidstab.h vsMotionDetectInit -enabled libvmaf && { check_lib libvmaf "libvmaf.h" "compute_vmaf" -lvmaf -lstdc++ -lpthread -lm || - die "ERROR: libvmaf must be installed"; } +enabled libvmaf && require_pkg_config libvmaf libvmaf.h compute_vmaf enabled libvo_amrwbenc && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc enabled libvorbis && require_pkg_config vorbis vorbis/codec.h vorbis_info_init && require_pkg_config vorbisenc vorbis/vorbisenc.h vorbis_encode_init From 350dc01dcb80345eafe45e85850bc8f8028e298d Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 30 Aug 2017 14:06:49 -0300 Subject: [PATCH 2914/3374] fate: remove usage of deprecated AVCodecContext.me_method in vsynth snow tests Signed-off-by: James Almer --- tests/fate/vcodec.mak | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/fate/vcodec.mak b/tests/fate/vcodec.mak index 8c2451093700f..5fc27c02cd1b1 100644 --- a/tests/fate/vcodec.mak +++ b/tests/fate/vcodec.mak @@ -376,11 +376,11 @@ fate-vsynth%-rv20: FMT = rm FATE_VCODEC-$(call ENCDEC, SNOW, AVI) += snow snow-hpel snow-ll fate-vsynth%-snow: ENCOPTS = -qscale 2 -flags +qpel \ - -me_method iter -dia_size 2 \ + -motion_est iter -dia_size 2 \ -cmp 12 -subcmp 12 -s 128x64 fate-vsynth%-snow-hpel: ENCOPTS = -qscale 2 \ - -me_method iter -dia_size 2 \ + -motion_est iter -dia_size 2 \ -cmp 12 -subcmp 12 -s 128x64 fate-vsynth%-snow-ll: ENCOPTS = -qscale .001 -pred 1 \ From ec07574a15bacabe0f6e4e496842e4935862c094 Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 30 Aug 2017 14:14:54 -0300 Subject: [PATCH 2915/3374] fate: stop using deprecated filter syntax in hls tests Signed-off-by: James Almer --- tests/fate/filter-audio.mak | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/fate/filter-audio.mak b/tests/fate/filter-audio.mak index 8030641ed67ba..5035e8f073782 100644 --- a/tests/fate/filter-audio.mak +++ b/tests/fate/filter-audio.mak @@ -145,7 +145,7 @@ fate-filter-compand: CMD = framecrc -i $(SRC) -frames:a 20 -filter_complex_scrip tests/data/hls-list.m3u8: TAG = GEN tests/data/hls-list.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data $(M)$(TARGET_EXEC) $(TARGET_PATH)/$< \ - -f lavfi -i "aevalsrc=cos(2*PI*t)*sin(2*PI*(440+4*t)*t)::d=20" -f segment -segment_time 10 -map 0 -flags +bitexact -codec:a mp2fixed \ + -f lavfi -i "aevalsrc=cos(2*PI*t)*sin(2*PI*(440+4*t)*t):d=20" -f segment -segment_time 10 -map 0 -flags +bitexact -codec:a mp2fixed \ -segment_list $(TARGET_PATH)/$@ -y $(TARGET_PATH)/tests/data/hls-out-%03d.ts 2>/dev/null FATE_AFILTER-$(call ALLYES, HLS_DEMUXER MPEGTS_MUXER MPEGTS_DEMUXER AEVALSRC_FILTER LAVFI_INDEV MP2FIXED_ENCODER) += fate-filter-hls @@ -155,10 +155,10 @@ fate-filter-hls: CMD = framecrc -flags +bitexact -i $(TARGET_PATH)/tests/data/hl tests/data/hls-list-append.m3u8: TAG = GEN tests/data/hls-list-append.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data $(M)$(TARGET_EXEC) $(TARGET_PATH)/$< \ - -f lavfi -i "aevalsrc=cos(2*PI*t)*sin(2*PI*(440+4*t)*t)::d=20" -f segment -segment_time 10 -map 0 -flags +bitexact -codec:a mp2fixed \ + -f lavfi -i "aevalsrc=cos(2*PI*t)*sin(2*PI*(440+4*t)*t):d=20" -f segment -segment_time 10 -map 0 -flags +bitexact -codec:a mp2fixed \ -segment_list $(TARGET_PATH)/$@ -y $(TARGET_PATH)/tests/data/hls-append-out-%03d.ts 2>/dev/null; \ $(TARGET_EXEC) $(TARGET_PATH)/$< \ - -f lavfi -i "aevalsrc=cos(2*PI*t)*sin(2*PI*(440+4*t)*t)::d=20" -f hls -hls_time 10 -map 0 -flags +bitexact \ + -f lavfi -i "aevalsrc=cos(2*PI*t)*sin(2*PI*(440+4*t)*t):d=20" -f hls -hls_time 10 -map 0 -flags +bitexact \ -hls_flags append_list -codec:a mp2fixed -hls_segment_filename $(TARGET_PATH)/tests/data/hls-append-out-%03d.ts \ $(TARGET_PATH)/tests/data/hls-list-append.m3u8 2>/dev/null From f7d4c60ac47547f69ddc96e7bed682f54436cd1a Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 30 Aug 2017 14:34:04 -0300 Subject: [PATCH 2916/3374] avfilter/vf_mcdeint: free the AVCodecContext struct properly Signed-off-by: James Almer --- libavfilter/vf_mcdeint.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libavfilter/vf_mcdeint.c b/libavfilter/vf_mcdeint.c index 26387b84e764b..d53322b40d653 100644 --- a/libavfilter/vf_mcdeint.c +++ b/libavfilter/vf_mcdeint.c @@ -154,10 +154,7 @@ static av_cold void uninit(AVFilterContext *ctx) { MCDeintContext *mcdeint = ctx->priv; - if (mcdeint->enc_ctx) { - avcodec_close(mcdeint->enc_ctx); - av_freep(&mcdeint->enc_ctx); - } + avcodec_free_context(&mcdeint->enc_ctx); } static int query_formats(AVFilterContext *ctx) From 2b7da70a70fef364f9a42e69b6d34133b3d089f8 Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 30 Aug 2017 14:43:22 -0300 Subject: [PATCH 2917/3374] postproc: remove usage of deprecated QP_STORE_T define Signed-off-by: James Almer --- libpostproc/postprocess.c | 12 ++++++------ libpostproc/postprocess_internal.h | 6 +++--- libpostproc/postprocess_template.c | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/libpostproc/postprocess.c b/libpostproc/postprocess.c index 6aa4ace33766e..1fef8747c00eb 100644 --- a/libpostproc/postprocess.c +++ b/libpostproc/postprocess.c @@ -558,10 +558,10 @@ static av_always_inline void do_a_deblock_C(uint8_t *src, int step, #endif typedef void (*pp_fn)(const uint8_t src[], int srcStride, uint8_t dst[], int dstStride, int width, int height, - const QP_STORE_T QPs[], int QPStride, int isColor, PPContext *c2); + const int8_t QPs[], int QPStride, int isColor, PPContext *c2); static inline void postProcess(const uint8_t src[], int srcStride, uint8_t dst[], int dstStride, int width, int height, - const QP_STORE_T QPs[], int QPStride, int isColor, pp_mode *vm, pp_context *vc) + const int8_t QPs[], int QPStride, int isColor, pp_mode *vm, pp_context *vc) { pp_fn pp = postProcess_C; PPContext *c= (PPContext *)vc; @@ -870,9 +870,9 @@ static void reallocBuffers(PPContext *c, int width, int height, int stride, int } reallocAlign((void **)&c->deintTemp, 2*width+32); - reallocAlign((void **)&c->nonBQPTable, qpStride*mbHeight*sizeof(QP_STORE_T)); - reallocAlign((void **)&c->stdQPTable, qpStride*mbHeight*sizeof(QP_STORE_T)); - reallocAlign((void **)&c->forcedQPTable, mbWidth*sizeof(QP_STORE_T)); + reallocAlign((void **)&c->nonBQPTable, qpStride*mbHeight*sizeof(int8_t)); + reallocAlign((void **)&c->stdQPTable, qpStride*mbHeight*sizeof(int8_t)); + reallocAlign((void **)&c->forcedQPTable, mbWidth*sizeof(int8_t)); } static const char * context_to_name(void * ptr) { @@ -940,7 +940,7 @@ av_cold void pp_free_context(void *vc){ void pp_postprocess(const uint8_t * src[3], const int srcStride[3], uint8_t * dst[3], const int dstStride[3], int width, int height, - const QP_STORE_T *QP_store, int QPStride, + const int8_t *QP_store, int QPStride, pp_mode *vm, void *vc, int pict_type) { int mbWidth = (width+15)>>4; diff --git a/libpostproc/postprocess_internal.h b/libpostproc/postprocess_internal.h index d128dfbe2f6d6..765fdeb14ac7f 100644 --- a/libpostproc/postprocess_internal.h +++ b/libpostproc/postprocess_internal.h @@ -149,9 +149,9 @@ typedef struct PPContext{ DECLARE_ALIGNED(32, uint64_t, mmxDcOffset)[64]; DECLARE_ALIGNED(32, uint64_t, mmxDcThreshold)[64]; - QP_STORE_T *stdQPTable; ///< used to fix MPEG2 style qscale - QP_STORE_T *nonBQPTable; - QP_STORE_T *forcedQPTable; + int8_t *stdQPTable; ///< used to fix MPEG2 style qscale + int8_t *nonBQPTable; + int8_t *forcedQPTable; int QP; int nonBQP; diff --git a/libpostproc/postprocess_template.c b/libpostproc/postprocess_template.c index 2a25ce44e33ac..0a4398926681b 100644 --- a/libpostproc/postprocess_template.c +++ b/libpostproc/postprocess_template.c @@ -3081,7 +3081,7 @@ static av_always_inline void RENAME(do_a_deblock)(uint8_t *src, int step, int st #endif //TEMPLATE_PP_MMX static void RENAME(postProcess)(const uint8_t src[], int srcStride, uint8_t dst[], int dstStride, int width, int height, - const QP_STORE_T QPs[], int QPStride, int isColor, PPContext *c); + const int8_t QPs[], int QPStride, int isColor, PPContext *c); /** * Copy a block from src to dst and fixes the blacklevel. @@ -3309,7 +3309,7 @@ static inline void RENAME(prefetcht2)(const void *p) * Filter array of bytes (Y or U or V values) */ static void RENAME(postProcess)(const uint8_t src[], int srcStride, uint8_t dst[], int dstStride, int width, int height, - const QP_STORE_T QPs[], int QPStride, int isColor, PPContext *c2) + const int8_t QPs[], int QPStride, int isColor, PPContext *c2) { DECLARE_ALIGNED(8, PPContext, c)= *c2; //copy to stack for faster access int x,y; From 6ccd32c36760ac8b8261d68eb32b07cf5c762e52 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Wed, 30 Aug 2017 18:14:10 +0200 Subject: [PATCH 2918/3374] avfilter/af_adelay: remove requirement that at least one delay should be provided Such requirement is not necessary and code works without it just fine. Signed-off-by: Paul B Mahol --- doc/filters.texi | 1 - libavfilter/af_adelay.c | 5 ----- 2 files changed, 6 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 19e13a1346a3b..afcb99d876ee3 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -551,7 +551,6 @@ The filter accepts the following option: @table @option @item delays Set list of delays in milliseconds for each channel separated by '|'. -At least one delay greater than 0 should be provided. Unused delays will be silently ignored. If number of given delays is smaller than number of channels all remaining channels will not be delayed. If you want to delay exact number of samples, append 'S' to number. diff --git a/libavfilter/af_adelay.c b/libavfilter/af_adelay.c index 187cacf28afd5..983f089c21bcf 100644 --- a/libavfilter/af_adelay.c +++ b/libavfilter/af_adelay.c @@ -171,11 +171,6 @@ static int config_input(AVFilterLink *inlink) s->max_delay = FFMAX(s->max_delay, d->delay); } - if (!s->max_delay) { - av_log(ctx, AV_LOG_ERROR, "At least one delay >0 must be specified.\n"); - return AVERROR(EINVAL); - } - switch (inlink->format) { case AV_SAMPLE_FMT_U8P : s->delay_channel = delay_channel_u8p ; break; case AV_SAMPLE_FMT_S16P: s->delay_channel = delay_channel_s16p; break; From 027c682fa07999820a11cbcbf7a7ba9edbb9ecab Mon Sep 17 00:00:00 2001 From: James Almer Date: Mon, 28 Aug 2017 13:40:06 -0300 Subject: [PATCH 2919/3374] avfilter/vf_mcdeint: remove usage of deprecated AVCodecContext.me_method Signed-off-by: James Almer --- libavfilter/vf_mcdeint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_mcdeint.c b/libavfilter/vf_mcdeint.c index d53322b40d653..9cdec6308d80f 100644 --- a/libavfilter/vf_mcdeint.c +++ b/libavfilter/vf_mcdeint.c @@ -134,7 +134,7 @@ static int config_props(AVFilterLink *inlink) case MODE_EXTRA_SLOW: enc_ctx->refs = 3; case MODE_SLOW: - enc_ctx->me_method = ME_ITER; + av_dict_set(&opts, "motion_est", "iter", 0); case MODE_MEDIUM: enc_ctx->flags |= AV_CODEC_FLAG_4MV; enc_ctx->dia_size = 2; From 2fcf47e2d175397c44e0d4b9063dc1ad78614d78 Mon Sep 17 00:00:00 2001 From: Martin Vignali Date: Sun, 2 Apr 2017 23:25:33 +0200 Subject: [PATCH 2920/3374] fate/pixlet : add test for rgb Signed-off-by: Michael Niedermayer --- tests/Makefile | 1 + tests/fate/pixlet.mak | 5 +++++ tests/ref/fate/pixlet-rgb | 6 ++++++ 3 files changed, 12 insertions(+) create mode 100644 tests/fate/pixlet.mak create mode 100644 tests/ref/fate/pixlet-rgb diff --git a/tests/Makefile b/tests/Makefile index 18fe9c5b4ac3f..99f7e1730b579 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -159,6 +159,7 @@ include $(SRC_PATH)/tests/fate/mpeg4.mak include $(SRC_PATH)/tests/fate/mxf.mak include $(SRC_PATH)/tests/fate/opus.mak include $(SRC_PATH)/tests/fate/pcm.mak +include $(SRC_PATH)/tests/fate/pixlet.mak include $(SRC_PATH)/tests/fate/probe.mak include $(SRC_PATH)/tests/fate/prores.mak include $(SRC_PATH)/tests/fate/qt.mak diff --git a/tests/fate/pixlet.mak b/tests/fate/pixlet.mak new file mode 100644 index 0000000000000..c720f32616981 --- /dev/null +++ b/tests/fate/pixlet.mak @@ -0,0 +1,5 @@ +FATE_PIXLET += fate-pixlet-rgb +fate-pixlet-rgb: CMD = framecrc -i $(TARGET_SAMPLES)/pixlet/pixlet_rgb.mov -an -pix_fmt yuv420p16le + +FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, PIXLET) += $(FATE_PIXLET) +fate-pixlet: $(FATE_PIXLET) diff --git a/tests/ref/fate/pixlet-rgb b/tests/ref/fate/pixlet-rgb new file mode 100644 index 0000000000000..a445fddfa7739 --- /dev/null +++ b/tests/ref/fate/pixlet-rgb @@ -0,0 +1,6 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 13x9 +#sar 0: 1/1 +0, 0, 0, 1, 374, 0x93f1ba6d From 6e131a7cd970a39bcc8cbfdd32d10a90e3ab51c5 Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 30 Aug 2017 22:31:35 -0300 Subject: [PATCH 2921/3374] ffmpeg_opt: add proper deprecation guards to lowres code Signed-off-by: James Almer --- ffmpeg_opt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c index f275f711be070..100fa76e46f29 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -791,14 +791,16 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) case AVMEDIA_TYPE_VIDEO: if(!ist->dec) ist->dec = avcodec_find_decoder(par->codec_id); -#if FF_API_EMU_EDGE +#if FF_API_LOWRES if (av_codec_get_lowres(st->codec)) { av_codec_set_lowres(ist->dec_ctx, av_codec_get_lowres(st->codec)); ist->dec_ctx->width = st->codec->width; ist->dec_ctx->height = st->codec->height; ist->dec_ctx->coded_width = st->codec->coded_width; ist->dec_ctx->coded_height = st->codec->coded_height; +#if FF_API_EMU_EDGE ist->dec_ctx->flags |= CODEC_FLAG_EMU_EDGE; +#endif } #endif From b34c16a38d3e6fa02b5d39ae6ed73acf12dff92c Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 30 Aug 2017 23:21:41 -0300 Subject: [PATCH 2922/3374] fate/flvenc: set bitexact output format flag explicitly Using the encoder flags to set the muxer in bitexact mode is deprecated. Signed-off-by: James Almer --- tests/fate/flvenc.mak | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fate/flvenc.mak b/tests/fate/flvenc.mak index 3881bcd105c74..4fdeeff4c15db 100644 --- a/tests/fate/flvenc.mak +++ b/tests/fate/flvenc.mak @@ -1,7 +1,7 @@ tests/data/add_keyframe_index.flv: TAG = GEN tests/data/add_keyframe_index.flv: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data $(M)$(TARGET_EXEC) $(TARGET_PATH)/$< \ - -f lavfi -i "sws_flags=+accurate_rnd+bitexact;testsrc=r=7:n=2:d=20" -sws_flags '+accurate_rnd+bitexact' -metadata "encoder=Lavf" -pix_fmt yuv420p -c:v flv1 -g 7 -f flv -flags +bitexact \ + -f lavfi -i "sws_flags=+accurate_rnd+bitexact;testsrc=r=7:n=2:d=20" -sws_flags '+accurate_rnd+bitexact' -metadata "encoder=Lavf" -pix_fmt yuv420p -c:v flv1 -g 7 -f flv -flags +bitexact -fflags +bitexact \ -flvflags add_keyframe_index -idct simple -dct int -y $(TARGET_PATH)/tests/data/add_keyframe_index.flv 2> /dev/null; FATE_AFILTER-$(call ALLYES, FLV_MUXER FLV_DEMUXER AVDEVICE TESTSRC_FILTER LAVFI_INDEV FLV_ENCODER) += fate-flv-add_keyframe_index From b7101151b36c85b96da4976fe0c4f817e2ea3cfc Mon Sep 17 00:00:00 2001 From: Tobias Rapp Date: Thu, 17 Aug 2017 14:40:40 +0200 Subject: [PATCH 2923/3374] fate: add tests for some video source filters Adds FATE tests for the previously untested allrgb, allyuv, rgbtestsrc, smptebars, smptehdbars and yuvtestsrc filters. Also adds a test for testsrc2 filter with rgb+alpha. Tested-by: Michael Niedermayer Signed-off-by: Tobias Rapp --- tests/fate/filter-video.mak | 24 +++++++ tests/ref/fate/filter-allrgb | 10 +++ tests/ref/fate/filter-allyuv | 10 +++ tests/ref/fate/filter-rgbtestsrc | 10 +++ tests/ref/fate/filter-smptebars | 10 +++ tests/ref/fate/filter-smptehdbars | 10 +++ tests/ref/fate/filter-testsrc2-rgba | 75 ++++++++++++++++++++++ tests/ref/fate/filter-yuvtestsrc-yuv444p | 10 +++ tests/ref/fate/filter-yuvtestsrc-yuv444p12 | 10 +++ 9 files changed, 169 insertions(+) create mode 100644 tests/ref/fate/filter-allrgb create mode 100644 tests/ref/fate/filter-allyuv create mode 100644 tests/ref/fate/filter-rgbtestsrc create mode 100644 tests/ref/fate/filter-smptebars create mode 100644 tests/ref/fate/filter-smptehdbars create mode 100644 tests/ref/fate/filter-testsrc2-rgba create mode 100644 tests/ref/fate/filter-yuvtestsrc-yuv444p create mode 100644 tests/ref/fate/filter-yuvtestsrc-yuv444p12 diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak index 670d9ded56c25..620487872b79a 100644 --- a/tests/fate/filter-video.mak +++ b/tests/fate/filter-video.mak @@ -80,6 +80,30 @@ fate-filter-testsrc2-yuv444p: CMD = framecrc -lavfi testsrc2=r=7:d=10 -pix_fmt y FATE_FILTER-$(call ALLYES, TESTSRC2_FILTER) += fate-filter-testsrc2-rgb24 fate-filter-testsrc2-rgb24: CMD = framecrc -lavfi testsrc2=r=7:d=10 -pix_fmt rgb24 +FATE_FILTER-$(call ALLYES, LAVFI_INDEV TESTSRC2_FILTER) += fate-filter-testsrc2-rgba +fate-filter-testsrc2-rgba: CMD = framecrc -lavfi testsrc2=r=7:d=10 -pix_fmt rgba + +FATE_FILTER-$(call ALLYES, LAVFI_INDEV ALLRGB_FILTER) += fate-filter-allrgb +fate-filter-allrgb: CMD = framecrc -lavfi allrgb=rate=5:duration=1 -pix_fmt rgb24 + +FATE_FILTER-$(call ALLYES, LAVFI_INDEV ALLYUV_FILTER) += fate-filter-allyuv +fate-filter-allyuv: CMD = framecrc -lavfi allyuv=rate=5:duration=1 -pix_fmt yuv444p + +FATE_FILTER-$(call ALLYES, LAVFI_INDEV RGBTESTSRC_FILTER) += fate-filter-rgbtestsrc +fate-filter-rgbtestsrc: CMD = framecrc -lavfi rgbtestsrc=rate=5:duration=1 -pix_fmt rgb24 + +FATE_FILTER-$(call ALLYES, LAVFI_INDEV SMPTEBARS_FILTER) += fate-filter-smptebars +fate-filter-smptebars: CMD = framecrc -lavfi smptebars=rate=5:duration=1 -pix_fmt yuv420p + +FATE_FILTER-$(call ALLYES, LAVFI_INDEV SMPTEHDBARS_FILTER) += fate-filter-smptehdbars +fate-filter-smptehdbars: CMD = framecrc -lavfi smptehdbars=rate=5:duration=1 -pix_fmt yuv444p + +FATE_FILTER-$(call ALLYES, LAVFI_INDEV YUVTESTSRC_FILTER) += fate-filter-yuvtestsrc-yuv444p +fate-filter-yuvtestsrc-yuv444p: CMD = framecrc -lavfi yuvtestsrc=rate=5:duration=1 -pix_fmt yuv444p + +FATE_FILTER-$(call ALLYES, LAVFI_INDEV YUVTESTSRC_FILTER) += fate-filter-yuvtestsrc-yuv444p12 +fate-filter-yuvtestsrc-yuv444p12: CMD = framecrc -lavfi yuvtestsrc=rate=5:duration=1,format=yuv444p12 -pix_fmt yuv444p12le + FATE_FILTER-$(call ALLYES, AVDEVICE TESTSRC_FILTER FORMAT_FILTER CONCAT_FILTER SCALE_FILTER) += fate-filter-lavd-scalenorm fate-filter-lavd-scalenorm: tests/data/filtergraphs/scalenorm fate-filter-lavd-scalenorm: CMD = framecrc -f lavfi -graph_file $(TARGET_PATH)/tests/data/filtergraphs/scalenorm -i dummy diff --git a/tests/ref/fate/filter-allrgb b/tests/ref/fate/filter-allrgb new file mode 100644 index 0000000000000..b54efc550433b --- /dev/null +++ b/tests/ref/fate/filter-allrgb @@ -0,0 +1,10 @@ +#tb 0: 1/5 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 4096x4096 +#sar 0: 1/1 +0, 0, 0, 1, 50331648, 0x9cc26aca +0, 1, 1, 1, 50331648, 0x9cc26aca +0, 2, 2, 1, 50331648, 0x9cc26aca +0, 3, 3, 1, 50331648, 0x9cc26aca +0, 4, 4, 1, 50331648, 0x9cc26aca diff --git a/tests/ref/fate/filter-allyuv b/tests/ref/fate/filter-allyuv new file mode 100644 index 0000000000000..477992f0ea495 --- /dev/null +++ b/tests/ref/fate/filter-allyuv @@ -0,0 +1,10 @@ +#tb 0: 1/5 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 4096x4096 +#sar 0: 1/1 +0, 0, 0, 1, 50331648, 0x70b16aca +0, 1, 1, 1, 50331648, 0x70b16aca +0, 2, 2, 1, 50331648, 0x70b16aca +0, 3, 3, 1, 50331648, 0x70b16aca +0, 4, 4, 1, 50331648, 0x70b16aca diff --git a/tests/ref/fate/filter-rgbtestsrc b/tests/ref/fate/filter-rgbtestsrc new file mode 100644 index 0000000000000..e18d364fdb3b7 --- /dev/null +++ b/tests/ref/fate/filter-rgbtestsrc @@ -0,0 +1,10 @@ +#tb 0: 1/5 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 320x240 +#sar 0: 1/1 +0, 0, 0, 1, 230400, 0x8c0018bb +0, 1, 1, 1, 230400, 0x8c0018bb +0, 2, 2, 1, 230400, 0x8c0018bb +0, 3, 3, 1, 230400, 0x8c0018bb +0, 4, 4, 1, 230400, 0x8c0018bb diff --git a/tests/ref/fate/filter-smptebars b/tests/ref/fate/filter-smptebars new file mode 100644 index 0000000000000..2242aef57601f --- /dev/null +++ b/tests/ref/fate/filter-smptebars @@ -0,0 +1,10 @@ +#tb 0: 1/5 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 320x240 +#sar 0: 1/1 +0, 0, 0, 1, 115200, 0x87d91dc5 +0, 1, 1, 1, 115200, 0x87d91dc5 +0, 2, 2, 1, 115200, 0x87d91dc5 +0, 3, 3, 1, 115200, 0x87d91dc5 +0, 4, 4, 1, 115200, 0x87d91dc5 diff --git a/tests/ref/fate/filter-smptehdbars b/tests/ref/fate/filter-smptehdbars new file mode 100644 index 0000000000000..7a105fb69ed75 --- /dev/null +++ b/tests/ref/fate/filter-smptehdbars @@ -0,0 +1,10 @@ +#tb 0: 1/5 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 320x240 +#sar 0: 1/1 +0, 0, 0, 1, 230400, 0x85f40706 +0, 1, 1, 1, 230400, 0x85f40706 +0, 2, 2, 1, 230400, 0x85f40706 +0, 3, 3, 1, 230400, 0x85f40706 +0, 4, 4, 1, 230400, 0x85f40706 diff --git a/tests/ref/fate/filter-testsrc2-rgba b/tests/ref/fate/filter-testsrc2-rgba new file mode 100644 index 0000000000000..42ecfe571d03a --- /dev/null +++ b/tests/ref/fate/filter-testsrc2-rgba @@ -0,0 +1,75 @@ +#tb 0: 1/7 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 320x240 +#sar 0: 1/1 +0, 0, 0, 1, 307200, 0xa2e60897 +0, 1, 1, 1, 307200, 0x67f03406 +0, 2, 2, 1, 307200, 0x683843a1 +0, 3, 3, 1, 307200, 0x285a682c +0, 4, 4, 1, 307200, 0x7444a71e +0, 5, 5, 1, 307200, 0xde9e40d7 +0, 6, 6, 1, 307200, 0xc8bbd13d +0, 7, 7, 1, 307200, 0x6f179555 +0, 8, 8, 1, 307200, 0x274254c9 +0, 9, 9, 1, 307200, 0xb3ee50db +0, 10, 10, 1, 307200, 0x0ebe40d8 +0, 11, 11, 1, 307200, 0xa8216930 +0, 12, 12, 1, 307200, 0x467778e2 +0, 13, 13, 1, 307200, 0xe6b02e74 +0, 14, 14, 1, 307200, 0x18a5a923 +0, 15, 15, 1, 307200, 0x3ff2086b +0, 16, 16, 1, 307200, 0x71ebe464 +0, 17, 17, 1, 307200, 0x671cf604 +0, 18, 18, 1, 307200, 0xe55dfee7 +0, 19, 19, 1, 307200, 0xc9c497ea +0, 20, 20, 1, 307200, 0xb263b768 +0, 21, 21, 1, 307200, 0xd24ee5a8 +0, 22, 22, 1, 307200, 0x9b77a2b7 +0, 23, 23, 1, 307200, 0x729c1b08 +0, 24, 24, 1, 307200, 0x725574db +0, 25, 25, 1, 307200, 0x413cf660 +0, 26, 26, 1, 307200, 0xe8db86b0 +0, 27, 27, 1, 307200, 0xf538a378 +0, 28, 28, 1, 307200, 0x89638534 +0, 29, 29, 1, 307200, 0x0858618b +0, 30, 30, 1, 307200, 0x8b5f961c +0, 31, 31, 1, 307200, 0xddbb5e48 +0, 32, 32, 1, 307200, 0x9352a610 +0, 33, 33, 1, 307200, 0xcf466635 +0, 34, 34, 1, 307200, 0xaf69099c +0, 35, 35, 1, 307200, 0x18811110 +0, 36, 36, 1, 307200, 0x7b7dcbd1 +0, 37, 37, 1, 307200, 0x27e2f523 +0, 38, 38, 1, 307200, 0x563debe1 +0, 39, 39, 1, 307200, 0x48c71784 +0, 40, 40, 1, 307200, 0x4b6476b4 +0, 41, 41, 1, 307200, 0xa7a21b13 +0, 42, 42, 1, 307200, 0xd14d86c0 +0, 43, 43, 1, 307200, 0x12b1caef +0, 44, 44, 1, 307200, 0xae58ad7e +0, 45, 45, 1, 307200, 0x908bbb66 +0, 46, 46, 1, 307200, 0xc6d4f77e +0, 47, 47, 1, 307200, 0x08a90cdf +0, 48, 48, 1, 307200, 0x6c344d22 +0, 49, 49, 1, 307200, 0xb351a388 +0, 50, 50, 1, 307200, 0x8209bbff +0, 51, 51, 1, 307200, 0xfa1e34e0 +0, 52, 52, 1, 307200, 0x76dd4c48 +0, 53, 53, 1, 307200, 0xb01ab30f +0, 54, 54, 1, 307200, 0x2e2ec7c5 +0, 55, 55, 1, 307200, 0x6382f929 +0, 56, 56, 1, 307200, 0xa5cfce14 +0, 57, 57, 1, 307200, 0xd9339546 +0, 58, 58, 1, 307200, 0xf5b9a815 +0, 59, 59, 1, 307200, 0x99bbc602 +0, 60, 60, 1, 307200, 0x642242e6 +0, 61, 61, 1, 307200, 0x9626ad04 +0, 62, 62, 1, 307200, 0xba276036 +0, 63, 63, 1, 307200, 0x04bb2e18 +0, 64, 64, 1, 307200, 0x57bf0cc6 +0, 65, 65, 1, 307200, 0xce4c0f05 +0, 66, 66, 1, 307200, 0x9fa71634 +0, 67, 67, 1, 307200, 0xb0525b7f +0, 68, 68, 1, 307200, 0x5a6c7523 +0, 69, 69, 1, 307200, 0x1dfc11fa diff --git a/tests/ref/fate/filter-yuvtestsrc-yuv444p b/tests/ref/fate/filter-yuvtestsrc-yuv444p new file mode 100644 index 0000000000000..44fcf08441156 --- /dev/null +++ b/tests/ref/fate/filter-yuvtestsrc-yuv444p @@ -0,0 +1,10 @@ +#tb 0: 1/5 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 320x240 +#sar 0: 1/1 +0, 0, 0, 1, 230400, 0x0e1e2a4f +0, 1, 1, 1, 230400, 0x0e1e2a4f +0, 2, 2, 1, 230400, 0x0e1e2a4f +0, 3, 3, 1, 230400, 0x0e1e2a4f +0, 4, 4, 1, 230400, 0x0e1e2a4f diff --git a/tests/ref/fate/filter-yuvtestsrc-yuv444p12 b/tests/ref/fate/filter-yuvtestsrc-yuv444p12 new file mode 100644 index 0000000000000..8abac6f9d9ec2 --- /dev/null +++ b/tests/ref/fate/filter-yuvtestsrc-yuv444p12 @@ -0,0 +1,10 @@ +#tb 0: 1/5 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 320x240 +#sar 0: 1/1 +0, 0, 0, 1, 460800, 0x3ec49be7 +0, 1, 1, 1, 460800, 0x3ec49be7 +0, 2, 2, 1, 460800, 0x3ec49be7 +0, 3, 3, 1, 460800, 0x3ec49be7 +0, 4, 4, 1, 460800, 0x3ec49be7 From 1291a6d0ff9afb61100f5da46c65360418a4a8ef Mon Sep 17 00:00:00 2001 From: James Almer Date: Thu, 31 Aug 2017 11:26:36 -0300 Subject: [PATCH 2924/3374] avcodec/fits: add missing header includes Fixes checkheaders. Signed-off-by: James Almer --- libavcodec/fits.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/fits.h b/libavcodec/fits.h index 2cf9e7c1312b2..b2f9b4cb39cb9 100644 --- a/libavcodec/fits.h +++ b/libavcodec/fits.h @@ -22,6 +22,10 @@ #ifndef AVCODEC_FITS_H #define AVCODEC_FITS_H +#include + +#include + typedef enum FITSHeaderState { STATE_SIMPLE, STATE_XTENSION, From 1a0d9b503d2e9c4278d6e93d40873dff9d191a25 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 28 Aug 2017 22:45:20 -0400 Subject: [PATCH 2925/3374] avformat/concatdec: add fallback for calculating file duration If a file does not have a known duration, this leads to the timestamps starting over for the next file, causing non-monotonic timestamps. To prevent this, track the duration during demuxing and use it to determine the current file duration before opening the next file. Signed-off-by: Derek Buitenhuis --- libavformat/concatdec.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c index e8b37d6a085f6..0e189012adf27 100644 --- a/libavformat/concatdec.c +++ b/libavformat/concatdec.c @@ -44,6 +44,7 @@ typedef struct { int64_t file_start_time; int64_t file_inpoint; int64_t duration; + int64_t next_dts; ConcatStream *streams; int64_t inpoint; int64_t outpoint; @@ -149,6 +150,7 @@ static int add_file(AVFormatContext *avf, char *filename, ConcatFile **rfile, file->url = url; file->start_time = AV_NOPTS_VALUE; file->duration = AV_NOPTS_VALUE; + file->next_dts = AV_NOPTS_VALUE; file->inpoint = AV_NOPTS_VALUE; file->outpoint = AV_NOPTS_VALUE; @@ -509,8 +511,14 @@ static int open_next_file(AVFormatContext *avf) ConcatContext *cat = avf->priv_data; unsigned fileno = cat->cur_file - cat->files; - if (cat->cur_file->duration == AV_NOPTS_VALUE) - cat->cur_file->duration = cat->avf->duration - (cat->cur_file->file_inpoint - cat->cur_file->file_start_time); + if (cat->cur_file->duration == AV_NOPTS_VALUE) { + if (cat->avf->duration > 0 || cat->cur_file->next_dts == AV_NOPTS_VALUE) { + cat->cur_file->duration = cat->avf->duration; + } else { + cat->cur_file->duration = cat->cur_file->next_dts; + } + cat->cur_file->duration -= (cat->cur_file->file_inpoint - cat->cur_file->file_start_time); + } if (++fileno >= cat->nb_files) { cat->eof = 1; @@ -627,6 +635,14 @@ static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt) memcpy(metadata, packed_metadata, metadata_len); av_freep(&packed_metadata); } + + if (cat->cur_file->duration == AV_NOPTS_VALUE && st->cur_dts != AV_NOPTS_VALUE) { + int64_t next_dts = av_rescale_q(st->cur_dts, st->time_base, AV_TIME_BASE_Q); + if (cat->cur_file->next_dts == AV_NOPTS_VALUE || next_dts > cat->cur_file->next_dts) { + cat->cur_file->next_dts = next_dts; + } + } + return ret; } From f1e47f87131dd7c3718496b83911e17586e26e80 Mon Sep 17 00:00:00 2001 From: Dale Curtis Date: Mon, 31 Jul 2017 13:44:22 -0700 Subject: [PATCH 2926/3374] avformat/mov: Bail when invalid sample data is present. ctts data in ffmpeg relies on the index entries array to be 1:1 with samples... yet sc->sample_count can be read directly from the 'stsz' box and index entries are only generated if a chunk count has been read from 'stco' box. Ensure that if sc->sample_count > 0, sc->chunk_count is too as a basic sanity check. Additionally we need to check that after the index is built we have the right number of entries, so we also check in mov_read_trun() that sc->sample_count == st->nb_index_entries. Signed-off-by: Michael Niedermayer --- libavformat/mov.c | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 876f48d9125aa..89b2af75974f9 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -3755,8 +3755,9 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) c->trak_index = -1; /* sanity checks */ - if (sc->chunk_count && (!sc->stts_count || !sc->stsc_count || - (!sc->sample_size && !sc->sample_count))) { + if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count || + (!sc->sample_size && !sc->sample_count))) || + (!sc->chunk_count && sc->sample_count)) { av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n", st->index); return 0; @@ -4284,26 +4285,6 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) entries = avio_rb32(pb); av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries); - /* Always assume the presence of composition time offsets. - * Without this assumption, for instance, we cannot deal with a track in fragmented movies that meet the following. - * 1) in the initial movie, there are no samples. - * 2) in the first movie fragment, there is only one sample without composition time offset. - * 3) in the subsequent movie fragments, there are samples with composition time offset. */ - if (!sc->ctts_count && sc->sample_count) - { - /* Complement ctts table if moov atom doesn't have ctts atom. */ - ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, sizeof(*sc->ctts_data) * sc->sample_count); - if (!ctts_data) - return AVERROR(ENOMEM); - /* Don't use a count greater than 1 here since it will leave a gap in - * the ctts index which the code below relies on being sequential. */ - sc->ctts_data = ctts_data; - for (i = 0; i < sc->sample_count; i++) { - sc->ctts_data[sc->ctts_count].count = 1; - sc->ctts_data[sc->ctts_count].duration = 0; - sc->ctts_count++; - } - } if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data)) return AVERROR_INVALIDDATA; if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb); @@ -4364,13 +4345,19 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) unsigned int size_needed = st->nb_index_entries * sizeof(*sc->ctts_data); unsigned int request_size = size_needed > sc->ctts_allocated_size ? FFMAX(size_needed, 2 * sc->ctts_allocated_size) : size_needed; + unsigned int old_ctts_size = sc->ctts_allocated_size; ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, request_size); if (!ctts_data) { av_freep(&sc->ctts_data); return AVERROR(ENOMEM); } - sc->ctts_data = ctts_data; + + // In case there were samples without ctts entries, ensure they get + // zero valued entries. This ensures clips which mix boxes with and + // without ctts entries don't pickup uninitialized data. + memset((uint8_t*)(sc->ctts_data) + old_ctts_size, 0, sc->ctts_allocated_size - old_ctts_size); + if (ctts_index != old_nb_index_entries) { memmove(sc->ctts_data + ctts_index + 1, sc->ctts_data + ctts_index, sizeof(*sc->ctts_data) * (sc->ctts_count - ctts_index)); From feb1dbc7bd4c395400c48055c563ac23d5251716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Gl=C3=B6ckner?= Date: Sun, 6 Aug 2017 03:04:53 +0200 Subject: [PATCH 2927/3374] avformat/mov: prevent duplication of first fragment's ctts_data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MP4 files with fragments might have the first moof box that is mentioned in a fragment index before the first mdat box. Since it is then already parsed by mov_read_header, we have to make sure that mov_switch_root will not parse it again when seeking by setting the headers_read flag in the index. Parsing it a second time would cause the ctts_data array to receive a second copy of the information from the trun box, leading to wrong PTS values for the second and following fragments in presence of B-frames. Fixes ticket 6560. Signed-off-by: Daniel Glöckner Reviewed-by: Dale Curtis Signed-off-by: Michael Niedermayer --- libavformat/mov.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libavformat/mov.c b/libavformat/mov.c index 89b2af75974f9..994e9c6ebafc1 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -6363,6 +6363,13 @@ static int mov_read_header(AVFormatContext *s) } ff_configure_buffers_for_index(s, AV_TIME_BASE); + for (i = 0; i < mov->fragment_index_count; i++) { + MOVFragmentIndex *idx = mov->fragment_index_data[i]; + for (j = 0; j < idx->item_count; j++) + if (idx->items[j].moof_offset <= mov->fragment.moof_offset) + idx->items[j].headers_read = 1; + } + return 0; } From 73bed07373f2672275e33851ad31e447b73b08f9 Mon Sep 17 00:00:00 2001 From: pkviet Date: Fri, 1 Sep 2017 00:44:11 +0200 Subject: [PATCH 2928/3374] avocdec/libopus: fix typo Signed-off-by: Michael Niedermayer --- libavcodec/libopusenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/libopusenc.c b/libavcodec/libopusenc.c index c40fcde7ba044..77d8310048db6 100644 --- a/libavcodec/libopusenc.c +++ b/libavcodec/libopusenc.c @@ -368,7 +368,7 @@ static av_cold int libopus_encode_init(AVCodecContext *avctx) goto fail; } - /* Header includes channel mapping table if and only if mapping family is 0 */ + /* Header includes channel mapping table if and only if mapping family is NOT 0 */ header_size = 19 + (mapping_family == 0 ? 0 : 2 + avctx->channels); avctx->extradata = av_malloc(header_size + AV_INPUT_BUFFER_PADDING_SIZE); if (!avctx->extradata) { From c24bcb553650b91e9eff15ef6e54ca73de2453b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E6=B5=A9=28=E6=99=93=E9=BB=91=29?= Date: Tue, 29 Aug 2017 23:59:21 +0200 Subject: [PATCH 2929/3374] avformat/nsvdec: Fix DoS due to lack of eof check in nsvs_file_offset loop. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: 20170829.nsv Co-Author: 张洪亮(望初)" Found-by: Xiaohei and Wangchu from Alibaba Security Team Signed-off-by: Michael Niedermayer --- libavformat/nsvdec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c index c6ddb67bbddcb..d8ce656817cab 100644 --- a/libavformat/nsvdec.c +++ b/libavformat/nsvdec.c @@ -335,8 +335,11 @@ static int nsv_parse_NSVf_header(AVFormatContext *s) if (!nsv->nsvs_file_offset) return AVERROR(ENOMEM); - for(i=0;insvs_file_offset[i] = avio_rl32(pb) + size; + } if(table_entries > table_entries_used && avio_rl32(pb) == MKTAG('T','O','C','2')) { From 900f39692ca0337a98a7cf047e4e2611071810c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E6=B5=A9=28=E6=99=93=E9=BB=91=29?= Date: Tue, 29 Aug 2017 23:59:21 +0200 Subject: [PATCH 2930/3374] avformat/mxfdec: Fix DoS issues in mxf_read_index_entry_array() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: 20170829A.mxf Co-Author: 张洪亮(望初)" Found-by: Xiaohei and Wangchu from Alibaba Security Team Signed-off-by: Michael Niedermayer --- libavformat/mxfdec.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index f8d0f9e0570bb..6adb77d81fbf2 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -899,6 +899,8 @@ static int mxf_read_index_entry_array(AVIOContext *pb, MXFIndexTableSegment *seg segment->nb_index_entries = avio_rb32(pb); length = avio_rb32(pb); + if(segment->nb_index_entries && length < 11) + return AVERROR_INVALIDDATA; if (!(segment->temporal_offset_entries=av_calloc(segment->nb_index_entries, sizeof(*segment->temporal_offset_entries))) || !(segment->flag_entries = av_calloc(segment->nb_index_entries, sizeof(*segment->flag_entries))) || @@ -909,6 +911,8 @@ static int mxf_read_index_entry_array(AVIOContext *pb, MXFIndexTableSegment *seg } for (i = 0; i < segment->nb_index_entries; i++) { + if(avio_feof(pb)) + return AVERROR_INVALIDDATA; segment->temporal_offset_entries[i] = avio_r8(pb); avio_r8(pb); /* KeyFrameOffset */ segment->flag_entries[i] = avio_r8(pb); From 9d00fb9d70ee8c0cc7002b89318c5be00f1bbdad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E6=B5=A9=28=E6=99=93=E9=BB=91=29?= Date: Tue, 29 Aug 2017 23:59:21 +0200 Subject: [PATCH 2931/3374] avformat/mxfdec: Fix Sign error in mxf_read_primer_pack() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: 20170829B.mxf Co-Author: 张洪亮(望初)" Found-by: Xiaohei and Wangchu from Alibaba Security Team Signed-off-by: Michael Niedermayer --- libavformat/mxfdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 6adb77d81fbf2..91731a7533c15 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -500,7 +500,7 @@ static int mxf_read_primer_pack(void *arg, AVIOContext *pb, int tag, int size, U avpriv_request_sample(pb, "Primer pack item length %d", item_len); return AVERROR_PATCHWELCOME; } - if (item_num > 65536) { + if (item_num > 65536 || item_num < 0) { av_log(mxf->fc, AV_LOG_ERROR, "item_num %d is too large\n", item_num); return AVERROR_INVALIDDATA; } From 837580f458f2ccbbd6e82d3c7591916deb81ef02 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Fri, 1 Sep 2017 10:20:56 +0800 Subject: [PATCH 2932/3374] avformat/dash: move reused API to common file and header file move from dashenc, move DASHTmplId and dash_fill_tmpl_params to dash.c, they will be used by dash demuxer and dash muxer. v2 fixed: 1. rename common file from dashcomm.* to dash.* Suggested-by: Hendrik Leppkes v3 fixed: 1. rename header file pre defined 2. add ff_ prefix for the internal API Suggested-by: James Almer Suggested-by: Timo Rothenpieler Reviewed-by: wm4 Signed-off-by: Steven Liu --- libavformat/Makefile | 2 +- libavformat/dash.c | 136 ++++++++++++++++++++++++++++++++++++++++++ libavformat/dash.h | 39 ++++++++++++ libavformat/dashenc.c | 130 ++-------------------------------------- 4 files changed, 180 insertions(+), 127 deletions(-) create mode 100644 libavformat/dash.c create mode 100644 libavformat/dash.h diff --git a/libavformat/Makefile b/libavformat/Makefile index 36f5839aa85ff..de954af1306bc 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -132,7 +132,7 @@ OBJS-$(CONFIG_CONCAT_DEMUXER) += concatdec.o OBJS-$(CONFIG_CRC_MUXER) += crcenc.o OBJS-$(CONFIG_DATA_DEMUXER) += rawdec.o OBJS-$(CONFIG_DATA_MUXER) += rawenc.o -OBJS-$(CONFIG_DASH_MUXER) += dashenc.o +OBJS-$(CONFIG_DASH_MUXER) += dash.o dashenc.o OBJS-$(CONFIG_DAUD_DEMUXER) += dauddec.o OBJS-$(CONFIG_DAUD_MUXER) += daudenc.o OBJS-$(CONFIG_DCSTR_DEMUXER) += dcstr.o diff --git a/libavformat/dash.c b/libavformat/dash.c new file mode 100644 index 0000000000000..b0b1ed4f4307e --- /dev/null +++ b/libavformat/dash.c @@ -0,0 +1,136 @@ +#include "config.h" +#if HAVE_UNISTD_H +#include +#endif + +#include "libavutil/avassert.h" +#include "libavutil/avstring.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/mathematics.h" +#include "libavutil/opt.h" +#include "libavutil/rational.h" +#include "libavutil/time_internal.h" + +#include "avc.h" +#include "avformat.h" +#include "avio_internal.h" +#include "internal.h" +#include "isom.h" +#include "os_support.h" +#include "url.h" +#include "dash.h" + +static DASHTmplId dash_read_tmpl_id(const char *identifier, char *format_tag, + size_t format_tag_size, const char **ptr) { + const char *next_ptr; + DASHTmplId id_type = DASH_TMPL_ID_UNDEFINED; + + if (av_strstart(identifier, "$$", &next_ptr)) { + id_type = DASH_TMPL_ID_ESCAPE; + *ptr = next_ptr; + } else if (av_strstart(identifier, "$RepresentationID$", &next_ptr)) { + id_type = DASH_TMPL_ID_REP_ID; + // default to basic format, as $RepresentationID$ identifiers + // are not allowed to have custom format-tags. + av_strlcpy(format_tag, "%d", format_tag_size); + *ptr = next_ptr; + } else { // the following identifiers may have an explicit format_tag + if (av_strstart(identifier, "$Number", &next_ptr)) + id_type = DASH_TMPL_ID_NUMBER; + else if (av_strstart(identifier, "$Bandwidth", &next_ptr)) + id_type = DASH_TMPL_ID_BANDWIDTH; + else if (av_strstart(identifier, "$Time", &next_ptr)) + id_type = DASH_TMPL_ID_TIME; + else + id_type = DASH_TMPL_ID_UNDEFINED; + + // next parse the dash format-tag and generate a c-string format tag + // (next_ptr now points at the first '%' at the beginning of the format-tag) + if (id_type != DASH_TMPL_ID_UNDEFINED) { + const char *number_format = (id_type == DASH_TMPL_ID_TIME) ? PRId64 : "d"; + if (next_ptr[0] == '$') { // no dash format-tag + snprintf(format_tag, format_tag_size, "%%%s", number_format); + *ptr = &next_ptr[1]; + } else { + const char *width_ptr; + // only tolerate single-digit width-field (i.e. up to 9-digit width) + if (av_strstart(next_ptr, "%0", &width_ptr) && + av_isdigit(width_ptr[0]) && + av_strstart(&width_ptr[1], "d$", &next_ptr)) { + // yes, we're using a format tag to build format_tag. + snprintf(format_tag, format_tag_size, "%s%c%s", "%0", width_ptr[0], number_format); + *ptr = next_ptr; + } else { + av_log(NULL, AV_LOG_WARNING, "Failed to parse format-tag beginning with %s. Expected either a " + "closing '$' character or a format-string like '%%0[width]d', " + "where width must be a single digit\n", next_ptr); + id_type = DASH_TMPL_ID_UNDEFINED; + } + } + } + } + return id_type; +} + +void ff_dash_fill_tmpl_params(char *dst, size_t buffer_size, + const char *template, int rep_id, + int number, int bit_rate, + int64_t time) { + int dst_pos = 0; + const char *t_cur = template; + while (dst_pos < buffer_size - 1 && *t_cur) { + char format_tag[7]; // May be "%d", "%0Xd", or "%0Xlld" (for $Time$), where X is in [0-9] + int n = 0; + DASHTmplId id_type; + const char *t_next = strchr(t_cur, '$'); // copy over everything up to the first '$' character + if (t_next) { + int num_copy_bytes = FFMIN(t_next - t_cur, buffer_size - dst_pos - 1); + av_strlcpy(&dst[dst_pos], t_cur, num_copy_bytes + 1); + // advance + dst_pos += num_copy_bytes; + t_cur = t_next; + } else { // no more DASH identifiers to substitute - just copy the rest over and break + av_strlcpy(&dst[dst_pos], t_cur, buffer_size - dst_pos); + break; + } + + if (dst_pos >= buffer_size - 1 || !*t_cur) + break; + + // t_cur is now pointing to a '$' character + id_type = dash_read_tmpl_id(t_cur, format_tag, sizeof(format_tag), &t_next); + switch (id_type) { + case DASH_TMPL_ID_ESCAPE: + av_strlcpy(&dst[dst_pos], "$", 2); + n = 1; + break; + case DASH_TMPL_ID_REP_ID: + n = snprintf(&dst[dst_pos], buffer_size - dst_pos, format_tag, rep_id); + break; + case DASH_TMPL_ID_NUMBER: + n = snprintf(&dst[dst_pos], buffer_size - dst_pos, format_tag, number); + break; + case DASH_TMPL_ID_BANDWIDTH: + n = snprintf(&dst[dst_pos], buffer_size - dst_pos, format_tag, bit_rate); + break; + case DASH_TMPL_ID_TIME: + n = snprintf(&dst[dst_pos], buffer_size - dst_pos, format_tag, time); + break; + case DASH_TMPL_ID_UNDEFINED: + // copy over one byte and advance + av_strlcpy(&dst[dst_pos], t_cur, 2); + n = 1; + t_next = &t_cur[1]; + break; + } + // t_next points just past the processed identifier + // n is the number of bytes that were attempted to be written to dst + // (may have failed to write all because buffer_size). + + // advance + dst_pos += FFMIN(n, buffer_size - dst_pos - 1); + t_cur = t_next; + } +} + + diff --git a/libavformat/dash.h b/libavformat/dash.h new file mode 100644 index 0000000000000..c6d9d2c33187b --- /dev/null +++ b/libavformat/dash.h @@ -0,0 +1,39 @@ +/* + * MPEG-DASH ISO BMFF segmenter + * Copyright (c) 2014 Martin Storsjo + * + * 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 + */ + +#ifndef AVFORMAT_DASH_H +#define AVFORMAT_DASH_H +#include "avformat.h" + +// See ISO/IEC 23009-1:2014 5.3.9.4.4 +typedef enum { + DASH_TMPL_ID_UNDEFINED = -1, + DASH_TMPL_ID_ESCAPE, + DASH_TMPL_ID_REP_ID, + DASH_TMPL_ID_NUMBER, + DASH_TMPL_ID_BANDWIDTH, + DASH_TMPL_ID_TIME, +} DASHTmplId; + + +void ff_dash_fill_tmpl_params(char *dst, size_t buffer_size, const char *template, int rep_id, int number, int bit_rate, int64_t time); + +#endif /* AVFORMAT_DASH_H */ diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index bdb332c71ab4a..6471649eb7410 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -39,16 +39,7 @@ #include "isom.h" #include "os_support.h" #include "url.h" - -// See ISO/IEC 23009-1:2014 5.3.9.4.4 -typedef enum { - DASH_TMPL_ID_UNDEFINED = -1, - DASH_TMPL_ID_ESCAPE, - DASH_TMPL_ID_REP_ID, - DASH_TMPL_ID_NUMBER, - DASH_TMPL_ID_BANDWIDTH, - DASH_TMPL_ID_TIME, -} DASHTmplId; +#include "dash.h" typedef struct Segment { char file[1024]; @@ -259,119 +250,6 @@ static void output_segment_list(OutputStream *os, AVIOContext *out, DASHContext } } -static DASHTmplId dash_read_tmpl_id(const char *identifier, char *format_tag, - size_t format_tag_size, const char **ptr) { - const char *next_ptr; - DASHTmplId id_type = DASH_TMPL_ID_UNDEFINED; - - if (av_strstart(identifier, "$$", &next_ptr)) { - id_type = DASH_TMPL_ID_ESCAPE; - *ptr = next_ptr; - } else if (av_strstart(identifier, "$RepresentationID$", &next_ptr)) { - id_type = DASH_TMPL_ID_REP_ID; - // default to basic format, as $RepresentationID$ identifiers - // are not allowed to have custom format-tags. - av_strlcpy(format_tag, "%d", format_tag_size); - *ptr = next_ptr; - } else { // the following identifiers may have an explicit format_tag - if (av_strstart(identifier, "$Number", &next_ptr)) - id_type = DASH_TMPL_ID_NUMBER; - else if (av_strstart(identifier, "$Bandwidth", &next_ptr)) - id_type = DASH_TMPL_ID_BANDWIDTH; - else if (av_strstart(identifier, "$Time", &next_ptr)) - id_type = DASH_TMPL_ID_TIME; - else - id_type = DASH_TMPL_ID_UNDEFINED; - - // next parse the dash format-tag and generate a c-string format tag - // (next_ptr now points at the first '%' at the beginning of the format-tag) - if (id_type != DASH_TMPL_ID_UNDEFINED) { - const char *number_format = (id_type == DASH_TMPL_ID_TIME) ? PRId64 : "d"; - if (next_ptr[0] == '$') { // no dash format-tag - snprintf(format_tag, format_tag_size, "%%%s", number_format); - *ptr = &next_ptr[1]; - } else { - const char *width_ptr; - // only tolerate single-digit width-field (i.e. up to 9-digit width) - if (av_strstart(next_ptr, "%0", &width_ptr) && - av_isdigit(width_ptr[0]) && - av_strstart(&width_ptr[1], "d$", &next_ptr)) { - // yes, we're using a format tag to build format_tag. - snprintf(format_tag, format_tag_size, "%s%c%s", "%0", width_ptr[0], number_format); - *ptr = next_ptr; - } else { - av_log(NULL, AV_LOG_WARNING, "Failed to parse format-tag beginning with %s. Expected either a " - "closing '$' character or a format-string like '%%0[width]d', " - "where width must be a single digit\n", next_ptr); - id_type = DASH_TMPL_ID_UNDEFINED; - } - } - } - } - return id_type; -} - -static void dash_fill_tmpl_params(char *dst, size_t buffer_size, - const char *template, int rep_id, - int number, int bit_rate, - int64_t time) { - int dst_pos = 0; - const char *t_cur = template; - while (dst_pos < buffer_size - 1 && *t_cur) { - char format_tag[7]; // May be "%d", "%0Xd", or "%0Xlld" (for $Time$), where X is in [0-9] - int n = 0; - DASHTmplId id_type; - const char *t_next = strchr(t_cur, '$'); // copy over everything up to the first '$' character - if (t_next) { - int num_copy_bytes = FFMIN(t_next - t_cur, buffer_size - dst_pos - 1); - av_strlcpy(&dst[dst_pos], t_cur, num_copy_bytes + 1); - // advance - dst_pos += num_copy_bytes; - t_cur = t_next; - } else { // no more DASH identifiers to substitute - just copy the rest over and break - av_strlcpy(&dst[dst_pos], t_cur, buffer_size - dst_pos); - break; - } - - if (dst_pos >= buffer_size - 1 || !*t_cur) - break; - - // t_cur is now pointing to a '$' character - id_type = dash_read_tmpl_id(t_cur, format_tag, sizeof(format_tag), &t_next); - switch (id_type) { - case DASH_TMPL_ID_ESCAPE: - av_strlcpy(&dst[dst_pos], "$", 2); - n = 1; - break; - case DASH_TMPL_ID_REP_ID: - n = snprintf(&dst[dst_pos], buffer_size - dst_pos, format_tag, rep_id); - break; - case DASH_TMPL_ID_NUMBER: - n = snprintf(&dst[dst_pos], buffer_size - dst_pos, format_tag, number); - break; - case DASH_TMPL_ID_BANDWIDTH: - n = snprintf(&dst[dst_pos], buffer_size - dst_pos, format_tag, bit_rate); - break; - case DASH_TMPL_ID_TIME: - n = snprintf(&dst[dst_pos], buffer_size - dst_pos, format_tag, time); - break; - case DASH_TMPL_ID_UNDEFINED: - // copy over one byte and advance - av_strlcpy(&dst[dst_pos], t_cur, 2); - n = 1; - t_next = &t_cur[1]; - break; - } - // t_next points just past the processed identifier - // n is the number of bytes that were attempted to be written to dst - // (may have failed to write all because buffer_size). - - // advance - dst_pos += FFMIN(n, buffer_size - dst_pos - 1); - t_cur = t_next; - } -} - static char *xmlescape(const char *str) { int outlen = strlen(str)*3/2 + 6; char *out = av_realloc(NULL, outlen + 1); @@ -660,11 +538,11 @@ static int dash_init(AVFormatContext *s) if (c->single_file) { if (c->single_file_name) - dash_fill_tmpl_params(os->initfile, sizeof(os->initfile), c->single_file_name, i, 0, os->bit_rate, 0); + ff_dash_fill_tmpl_params(os->initfile, sizeof(os->initfile), c->single_file_name, i, 0, os->bit_rate, 0); else snprintf(os->initfile, sizeof(os->initfile), "%s-stream%d.m4s", basename, i); } else { - dash_fill_tmpl_params(os->initfile, sizeof(os->initfile), c->init_seg_name, i, 0, os->bit_rate, 0); + ff_dash_fill_tmpl_params(os->initfile, sizeof(os->initfile), c->init_seg_name, i, 0, os->bit_rate, 0); } snprintf(filename, sizeof(filename), "%s%s", c->dirname, os->initfile); ret = s->io_open(s, &os->out, filename, AVIO_FLAG_WRITE, NULL); @@ -865,7 +743,7 @@ static int dash_flush(AVFormatContext *s, int final, int stream) start_pos = avio_tell(os->ctx->pb); 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); + ff_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), use_rename ? "%s.tmp" : "%s", full_path); ret = s->io_open(s, &os->out, temp_path, AVIO_FLAG_WRITE, NULL); From b12e4d3bb8df994f042ff1216fb8de2b967aab9e Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 27 Aug 2017 13:26:58 -0300 Subject: [PATCH 2933/3374] avio: add a destructor for AVIOContext Before this commit, AVIOContext is to be freed with a plain av_free(), which prevents us from adding any deeper structure to it. (cherry picked from commit 99684f3ae752fc8bfb44a2dd1482f8d7a3d8536d) Signed-off-by: James Almer --- doc/APIchanges | 3 +++ libavformat/avio.h | 8 ++++++++ libavformat/aviobuf.c | 17 ++++++++++++++--- libavformat/version.h | 2 +- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 7babf5babb178..1e9b29fdbb923 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-09-01 - xxxxxxx - lavf 57.80.100 / 57.11.0 - avio.h + Add avio_context_free(). From now on it must be used for freeing AVIOContext. + 2017-08-08 - xxxxxxx - lavu 55.74.100 - pixdesc.h Add AV_PIX_FMT_FLAG_FLOAT pixel format flag. diff --git a/libavformat/avio.h b/libavformat/avio.h index f14b003ba5d75..ea56dad503f8d 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -467,6 +467,14 @@ AVIOContext *avio_alloc_context( int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), int64_t (*seek)(void *opaque, int64_t offset, int whence)); +/** + * Free the supplied IO context and everything associated with it. + * + * @param s Double pointer to the IO context. This function will write NULL + * into s. + */ +void avio_context_free(AVIOContext **s); + void avio_w8(AVIOContext *s, int b); void avio_write(AVIOContext *s, const unsigned char *buf, int size); void avio_wl64(AVIOContext *s, uint64_t val); diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index ec21fc7d38f24..716c42eda9c02 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -143,6 +143,11 @@ AVIOContext *avio_alloc_context( return s; } +void avio_context_free(AVIOContext **ps) +{ + av_freep(ps); +} + static void writeout(AVIOContext *s, const uint8_t *data, int len) { if (!s->error) { @@ -1123,7 +1128,9 @@ int avio_close(AVIOContext *s) else av_log(s, AV_LOG_DEBUG, "Statistics: %"PRId64" bytes read, %d seeks\n", s->bytes_read, s->seek_count); av_opt_free(s); - av_free(s); + + avio_context_free(&s); + return ffurl_close(h); } @@ -1356,7 +1363,9 @@ int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer) *pbuffer = d->buffer; size = d->size; av_free(d); - av_free(s); + + avio_context_free(&s); + return size - padding; } @@ -1399,6 +1408,8 @@ int ffio_close_null_buf(AVIOContext *s) size = d->size; av_free(d); - av_free(s); + + avio_context_free(&s); + return size; } diff --git a/libavformat/version.h b/libavformat/version.h index 3029a5e767945..0af524c16bfe4 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ // 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 57 -#define LIBAVFORMAT_VERSION_MINOR 79 +#define LIBAVFORMAT_VERSION_MINOR 80 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ From 78a7af823b7c2a1e3184e6680f2b49bf67101e5c Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 1 Sep 2017 02:16:33 -0300 Subject: [PATCH 2934/3374] Use the new AVIOContext destructor. (cherry picked from commit 6f554521afdf7ab4edbfaa9536660a1dca946b19) Signed-off-by: James Almer --- libavformat/avidec.c | 2 +- libavformat/flac_picture.c | 4 ++-- libavformat/hdsenc.c | 2 +- libavformat/mpjpegdec.c | 2 +- libavformat/rdt.c | 2 +- libavformat/segment.c | 2 +- libavformat/smoothstreamingenc.c | 2 +- libavformat/swfdec.c | 2 +- libavformat/tests/movenc.c | 2 +- libavformat/wtvdec.c | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 9816a1dfacce7..b8a31dcff2875 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -1124,7 +1124,7 @@ static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt) error: av_freep(&ast->sub_ctx); - av_freep(&pb); + avio_context_free(&pb); } return 0; } diff --git a/libavformat/flac_picture.c b/libavformat/flac_picture.c index a3217f02a6b50..38982b960de44 100644 --- a/libavformat/flac_picture.c +++ b/libavformat/flac_picture.c @@ -140,14 +140,14 @@ int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size) if (desc) av_dict_set(&st->metadata, "title", desc, AV_DICT_DONT_STRDUP_VAL); - av_freep(&pb); + avio_context_free(&pb); return 0; fail: av_buffer_unref(&data); av_freep(&desc); - av_freep(&pb); + avio_context_free(&pb); return ret; } diff --git a/libavformat/hdsenc.c b/libavformat/hdsenc.c index d01b5fa84ec82..72829f7257a28 100644 --- a/libavformat/hdsenc.c +++ b/libavformat/hdsenc.c @@ -145,7 +145,7 @@ static void hds_free(AVFormatContext *s) if (os->ctx && os->ctx_inited) av_write_trailer(os->ctx); if (os->ctx) - av_freep(&os->ctx->pb); + avio_context_free(&os->ctx->pb); if (os->ctx) avformat_free_context(os->ctx); av_freep(&os->metadata); diff --git a/libavformat/mpjpegdec.c b/libavformat/mpjpegdec.c index 4c7764412f0f0..83aa70d0c9726 100644 --- a/libavformat/mpjpegdec.c +++ b/libavformat/mpjpegdec.c @@ -126,7 +126,7 @@ static int mpjpeg_read_probe(AVProbeData *p) ret = (parse_multipart_header(pb, &size, "--", NULL) >= 0) ? AVPROBE_SCORE_MAX : 0; - av_free(pb); + avio_context_free(&pb); return ret; } diff --git a/libavformat/rdt.c b/libavformat/rdt.c index 8670eadce67d4..b69827fcbfcd6 100644 --- a/libavformat/rdt.c +++ b/libavformat/rdt.c @@ -323,7 +323,7 @@ rdt_parse_packet (AVFormatContext *ctx, PayloadContext *rdt, AVStream *st, st, rdt->rmst[st->index], pkt); if (rdt->audio_pkt_cnt == 0 && st->codecpar->codec_id == AV_CODEC_ID_AAC) - av_freep(&rdt->rmctx->pb); + avio_context_free(&rdt->rmctx->pb); } pkt->stream_index = st->index; pkt->pts = *timestamp; diff --git a/libavformat/segment.c b/libavformat/segment.c index 0e8bcddb00be6..b0ef6dd38e08a 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -569,7 +569,7 @@ static int open_null_ctx(AVIOContext **ctx) static void close_null_ctxp(AVIOContext **pb) { av_freep(&(*pb)->buffer); - av_freep(pb); + avio_context_free(pb); } static int select_reference_stream(AVFormatContext *s) diff --git a/libavformat/smoothstreamingenc.c b/libavformat/smoothstreamingenc.c index 083af49212953..86618351b800d 100644 --- a/libavformat/smoothstreamingenc.c +++ b/libavformat/smoothstreamingenc.c @@ -182,7 +182,7 @@ static void ism_free(AVFormatContext *s) if (os->ctx && os->ctx_inited) av_write_trailer(os->ctx); if (os->ctx && os->ctx->pb) - av_freep(&os->ctx->pb); + avio_context_free(&os->ctx->pb); if (os->ctx) avformat_free_context(os->ctx); av_freep(&os->private_str); diff --git a/libavformat/swfdec.c b/libavformat/swfdec.c index b91560c56ce3d..57b619fb203d0 100644 --- a/libavformat/swfdec.c +++ b/libavformat/swfdec.c @@ -531,7 +531,7 @@ static av_cold int swf_read_close(AVFormatContext *avctx) inflateEnd(&s->zstream); av_freep(&s->zbuf_in); av_freep(&s->zbuf_out); - av_freep(&s->zpb); + avio_context_free(&s->zpb); return 0; } #endif diff --git a/libavformat/tests/movenc.c b/libavformat/tests/movenc.c index ab871765d9391..7a66395efd286 100644 --- a/libavformat/tests/movenc.c +++ b/libavformat/tests/movenc.c @@ -344,7 +344,7 @@ static void signal_init_ts(void) static void finish(void) { av_write_trailer(ctx); - av_free(ctx->pb); + avio_context_free(&ctx->pb); avformat_free_context(ctx); ctx = NULL; } diff --git a/libavformat/wtvdec.c b/libavformat/wtvdec.c index 3ac45013066b6..27be5c9c04d90 100644 --- a/libavformat/wtvdec.c +++ b/libavformat/wtvdec.c @@ -305,7 +305,7 @@ static void wtvfile_close(AVIOContext *pb) av_freep(&wf->sectors); av_freep(&pb->opaque); av_freep(&pb->buffer); - av_free(pb); + avio_context_free(&pb); } /* From a0b69e2b0a7ba994b722393a0273bb3464fd5efe Mon Sep 17 00:00:00 2001 From: Timo Rothenpieler Date: Wed, 30 Aug 2017 21:06:25 +0200 Subject: [PATCH 2935/3374] avcodec/nvenc: add support for specifying entropy coding mode Signed-off-by: Timo Rothenpieler --- libavcodec/nvenc.c | 9 +++++++++ libavcodec/nvenc.h | 1 + libavcodec/nvenc_h264.c | 7 +++++++ libavcodec/version.h | 2 +- 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index f79b9a502e33c..422ac6c73e688 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -317,6 +317,12 @@ static int nvenc_check_capabilities(AVCodecContext *avctx) return AVERROR(ENOSYS); } + ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_CABAC); + if (ctx->coder == NV_ENC_H264_ENTROPY_CODING_MODE_CABAC && ret <= 0) { + av_log(avctx, AV_LOG_VERBOSE, "CABAC entropy coding not supported\n"); + return AVERROR(ENOSYS); + } + return 0; } @@ -916,6 +922,9 @@ static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx) h264->level = ctx->level; + if (ctx->coder >= 0) + h264->entropyCodingMode = ctx->coder; + return 0; } diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h index 2e24604cea12e..2c682275dac97 100644 --- a/libavcodec/nvenc.h +++ b/libavcodec/nvenc.h @@ -162,6 +162,7 @@ typedef struct NvencContext int init_qp_i; int cqp; int weighted_pred; + int coder; } NvencContext; int ff_nvenc_encode_init(AVCodecContext *avctx); diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c index 5fcbcb9f4f8f3..9adbe9f9090da 100644 --- a/libavcodec/nvenc_h264.c +++ b/libavcodec/nvenc_h264.c @@ -119,6 +119,13 @@ static const AVOption options[] = { OFFSET(cqp), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE }, { "weighted_pred","Set 1 to enable weighted prediction", OFFSET(weighted_pred),AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, + { "coder", "Coder type", OFFSET(coder), AV_OPT_TYPE_INT, { .i64 = -1 },-1, 2, VE, "coder" }, + { "default", "", 0, AV_OPT_TYPE_CONST, { .i64 = -1 }, 0, 0, VE, "coder" }, + { "auto", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_ENTROPY_CODING_MODE_AUTOSELECT }, 0, 0, VE, "coder" }, + { "cabac", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_ENTROPY_CODING_MODE_CABAC }, 0, 0, VE, "coder" }, + { "cavlc", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_ENTROPY_CODING_MODE_CAVLC }, 0, 0, VE, "coder" }, + { "ac", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_ENTROPY_CODING_MODE_CABAC }, 0, 0, VE, "coder" }, + { "vlc", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_ENTROPY_CODING_MODE_CAVLC }, 0, 0, VE, "coder" }, { NULL } }; diff --git a/libavcodec/version.h b/libavcodec/version.h index 22cab7b0ddf0a..29cdb85589a98 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 104 -#define LIBAVCODEC_VERSION_MICRO 100 +#define LIBAVCODEC_VERSION_MICRO 101 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From 0e995eac2035ecd3c4c61cccdbc8cec478441779 Mon Sep 17 00:00:00 2001 From: Timo Rothenpieler Date: Wed, 30 Aug 2017 21:12:23 +0200 Subject: [PATCH 2936/3374] avcodec/nvenc: only push cuda context on encoder close if encoder exists Signed-off-by: Timo Rothenpieler --- libavcodec/nvenc.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 422ac6c73e688..1220ae4b8c40d 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -1330,17 +1330,17 @@ av_cold int ff_nvenc_encode_close(AVCodecContext *avctx) CUcontext dummy; int i; - 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; - } - /* the encoder has to be flushed before it can be closed */ if (ctx->nvencoder) { NV_ENC_PIC_PARAMS params = { .version = NV_ENC_PIC_PARAMS_VER, .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; + } + p_nvenc->nvEncEncodePicture(ctx->nvencoder, ¶ms); } @@ -1373,15 +1373,16 @@ av_cold int ff_nvenc_encode_close(AVCodecContext *avctx) av_freep(&ctx->surfaces); ctx->nb_surfaces = 0; - if (ctx->nvencoder) + if (ctx->nvencoder) { p_nvenc->nvEncDestroyEncoder(ctx->nvencoder); - ctx->nvencoder = NULL; - 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; + 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; + } } + ctx->nvencoder = NULL; if (ctx->cu_context_internal) dl_fn->cuda_dl->cuCtxDestroy(ctx->cu_context_internal); From adeb41afb80f0211af235f6d5b51df45a858170e Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Fri, 1 Sep 2017 18:52:56 +0800 Subject: [PATCH 2937/3374] avformat/dash:add copyright to dash.c Signed-off-by: Steven Liu --- libavformat/dash.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/libavformat/dash.c b/libavformat/dash.c index b0b1ed4f4307e..d2501f013a7c8 100644 --- a/libavformat/dash.c +++ b/libavformat/dash.c @@ -1,3 +1,24 @@ +/* + * MPEG-DASH ISO BMFF segmenter + * Copyright (c) 2014 Martin Storsjo + * + * 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 "config.h" #if HAVE_UNISTD_H #include From 877076ffa17bcf56badedc036cdc1adcd9f38b24 Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 1 Sep 2017 12:26:28 -0300 Subject: [PATCH 2938/3374] avformat/avio: update avio_alloc_context() doxy It must be freed using avio_context_free() starting with commit b12e4d3bb8df994f042ff1216fb8de2b967aab9e. Found-by: Ronald S. Bultje Signed-off-by: James Almer --- libavformat/avio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/avio.h b/libavformat/avio.h index ea56dad503f8d..89ad5c04ea3f1 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -439,7 +439,7 @@ void avio_free_directory_entry(AVIODirEntry **entry); /** * Allocate and initialize an AVIOContext for buffered I/O. It must be later - * freed with av_free(). + * freed with avio_context_free(). * * @param buffer Memory block for input/output operations via AVIOContext. * The buffer must be allocated with av_malloc() and friends. From 5d76674756806e3b458e484788775fcee34aac2a Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 17 Aug 2017 15:01:44 +0200 Subject: [PATCH 2939/3374] lavf: make avio_read_partial() public Main use-case is proxying avio through a foreign I/O layer and a custom AVIO context, without losing latency and performance characteristics. Signed-off-by: Luca Barbato Merged from Libav commit 173b56218f39c64. --- doc/APIchanges | 3 +++ libavformat/avio.h | 9 +++++++++ libavformat/avio_internal.h | 8 -------- libavformat/aviobuf.c | 2 +- libavformat/rawdec.c | 2 +- libavformat/rtsp.c | 2 +- libavformat/version.h | 2 +- 7 files changed, 16 insertions(+), 12 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 1e9b29fdbb923..4effbf9364556 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-09-01 - xxxxxxx - lavf 57.81.100 - avio.h + Add avio_read_partial(). + 2017-09-01 - xxxxxxx - lavf 57.80.100 / 57.11.0 - avio.h Add avio_context_free(). From now on it must be used for freeing AVIOContext. diff --git a/libavformat/avio.h b/libavformat/avio.h index 89ad5c04ea3f1..f9c5972adae65 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -598,6 +598,15 @@ void avio_flush(AVIOContext *s); */ int avio_read(AVIOContext *s, unsigned char *buf, int size); +/** + * Read size bytes from AVIOContext into buf. Unlike avio_read(), this is allowed + * to read fewer bytes than requested. The missing bytes can be read in the next + * call. This always tries to read at least 1 byte. + * Useful to reduce latency in certain cases. + * @return number of bytes read or AVERROR + */ +int avio_read_partial(AVIOContext *s, unsigned char *buf, int size); + /** * @name Functions for reading from AVIOContext * @{ diff --git a/libavformat/avio_internal.h b/libavformat/avio_internal.h index fdb323c8f1e5e..c01835df96fc1 100644 --- a/libavformat/avio_internal.h +++ b/libavformat/avio_internal.h @@ -53,14 +53,6 @@ int ffio_init_context(AVIOContext *s, */ int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, const unsigned char **data); -/** - * Read size bytes from AVIOContext into buf. - * This reads at most 1 packet. If that is not enough fewer bytes will be - * returned. - * @return number of bytes read or AVERROR - */ -int ffio_read_partial(AVIOContext *s, unsigned char *buf, int size); - void ffio_fill(AVIOContext *s, int b, int count); static av_always_inline void ffio_wfourcc(AVIOContext *pb, const uint8_t *s) diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index 716c42eda9c02..636cb46161ad0 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -703,7 +703,7 @@ int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, const unsig } } -int ffio_read_partial(AVIOContext *s, unsigned char *buf, int size) +int avio_read_partial(AVIOContext *s, unsigned char *buf, int size) { int len; diff --git a/libavformat/rawdec.c b/libavformat/rawdec.c index 876a6e6a7532a..e926549a60332 100644 --- a/libavformat/rawdec.c +++ b/libavformat/rawdec.c @@ -43,7 +43,7 @@ int ff_raw_read_partial_packet(AVFormatContext *s, AVPacket *pkt) pkt->pos= avio_tell(s->pb); pkt->stream_index = 0; - ret = ffio_read_partial(s->pb, pkt->data, size); + ret = avio_read_partial(s->pb, pkt->data, size); if (ret < 0) { av_packet_unref(pkt); return ret; diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 261e970b75a28..0bd72dc5ce352 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -2136,7 +2136,7 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt) wait_end && wait_end < av_gettime_relative()) len = AVERROR(EAGAIN); else - len = ffio_read_partial(s->pb, rt->recvbuf, RECVBUF_SIZE); + len = avio_read_partial(s->pb, rt->recvbuf, RECVBUF_SIZE); len = pick_stream(s, &rtsp_st, rt->recvbuf, len); if (len > 0 && rtsp_st->transport_priv && rt->transport == RTSP_TRANSPORT_RTP) ff_rtp_check_and_send_back_rr(rtsp_st->transport_priv, NULL, s->pb, len); diff --git a/libavformat/version.h b/libavformat/version.h index 0af524c16bfe4..9cca76ee00276 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ // 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 57 -#define LIBAVFORMAT_VERSION_MINOR 80 +#define LIBAVFORMAT_VERSION_MINOR 81 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ From 3ec6d9c6b2975c993d772936cb37fa075292cd92 Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 30 Aug 2017 01:41:43 -0300 Subject: [PATCH 2940/3374] avfilter: remove duplicate and disabled trace log function It's already defined and actually enabled depending on compiler options elsewhere. Signed-off-by: James Almer --- libavfilter/internal.h | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/libavfilter/internal.h b/libavfilter/internal.h index 2ff75aa778e18..f9679ed1d77f9 100644 --- a/libavfilter/internal.h +++ b/libavfilter/internal.h @@ -33,6 +33,7 @@ #include "version.h" #include "video.h" #include "libavcodec/avcodec.h" +#include "libavcodec/internal.h" typedef struct AVFilterCommand { double time; ///< time expressed in seconds @@ -246,14 +247,6 @@ void ff_command_queue_pop(AVFilterContext *filter); /* misc trace functions */ -/* #define FF_AVFILTER_TRACE */ - -#ifdef FF_AVFILTER_TRACE -# define ff_tlog(pctx, ...) av_log(pctx, AV_LOG_DEBUG, __VA_ARGS__) -#else -# define ff_tlog(pctx, ...) do { if (0) av_log(pctx, AV_LOG_DEBUG, __VA_ARGS__); } while (0) -#endif - #define FF_TPRINTF_START(ctx, func) ff_tlog(NULL, "%-16s: ", #func) char *ff_get_ref_perms_string(char *buf, size_t buf_size, int perms); From 9aa24699302c691459281b8f5da5484605eaf82b Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 1 Sep 2017 14:44:27 -0300 Subject: [PATCH 2941/3374] avcodec/internal: move FF_QSCALE_TYPE defines from avcodec.h Their use in the public header is deprecated and will be removed, but they are still needed by some codecs at least as long as qscale related deprecated fields in the AVFrame struct remain in the tree. --- libavcodec/internal.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libavcodec/internal.h b/libavcodec/internal.h index 64120ea92a211..e5824cc62d93b 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -76,6 +76,13 @@ #define FF_DEFAULT_QUANT_BIAS 999999 #endif +#if !FF_API_QSCALE_TYPE +#define FF_QSCALE_TYPE_MPEG1 0 +#define FF_QSCALE_TYPE_MPEG2 1 +#define FF_QSCALE_TYPE_H264 2 +#define FF_QSCALE_TYPE_VP56 3 +#endif + #define FF_SANE_NB_CHANNELS 64U #define FF_SIGNBIT(x) ((x) >> CHAR_BIT * sizeof(x) - 1) From 4e6638abb4fc176739be021d5e5b3b1bc8de099c Mon Sep 17 00:00:00 2001 From: Timo Rothenpieler Date: Sat, 2 Sep 2017 15:39:24 +0200 Subject: [PATCH 2942/3374] avcodec/nvenc: always output picture timing SEI Interlaced encoding profits from it, or might even need it in some players. No harm in enabling it unconditionally. Signed-off-by: Timo Rothenpieler --- libavcodec/nvenc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 1220ae4b8c40d..744e5e0e01ffa 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -879,9 +879,10 @@ static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx) if (IS_CBR(cc->rcParams.rateControlMode)) { h264->outputBufferingPeriodSEI = 1; - h264->outputPictureTimingSEI = 1; } + h264->outputPictureTimingSEI = 1; + if (cc->rcParams.rateControlMode == NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ || cc->rcParams.rateControlMode == NV_ENC_PARAMS_RC_CBR_HQ || cc->rcParams.rateControlMode == NV_ENC_PARAMS_RC_VBR_HQ) { @@ -966,9 +967,10 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx) if (IS_CBR(cc->rcParams.rateControlMode)) { hevc->outputBufferingPeriodSEI = 1; - hevc->outputPictureTimingSEI = 1; } + hevc->outputPictureTimingSEI = 1; + switch (ctx->profile) { case NV_ENC_HEVC_PROFILE_MAIN: cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN_GUID; From e70e2a7abdd45f550e785d705afe442e9c427581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Fri, 28 Jul 2017 12:18:59 +0200 Subject: [PATCH 2943/3374] build: group z libs with other autodetected libraries --- configure | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/configure b/configure index 4f1c172333e1f..8dc05711b9fe5 100755 --- a/configure +++ b/configure @@ -3602,6 +3602,9 @@ enable_weak xlib enable_weak cuda cuvid nvenc vda_framework videotoolbox videotoolbox_encoder +# Enable compression/decompression libraries by default +enable_weak zlib bzlib lzma + disabled logging && logfile=/dev/null die_license_disabled() { @@ -5800,9 +5803,9 @@ fi enabled pthreads && check_builtin sem_timedwait semaphore.h "sem_t *s; sem_init(s,0,0); sem_timedwait(s,0); sem_destroy(s)" -disabled zlib || check_lib zlib zlib.h zlibVersion -lz -disabled bzlib || check_lib bzlib bzlib.h BZ2_bzlibVersion -lbz2 -disabled lzma || check_lib lzma lzma.h lzma_version_number -llzma +enabled zlib && check_lib zlib zlib.h zlibVersion -lz +enabled bzlib && check_lib bzlib bzlib.h BZ2_bzlibVersion -lbz2 +enabled lzma && check_lib lzma lzma.h lzma_version_number -llzma check_lib libm math.h sin -lm && LIBM="-lm" disabled crystalhd || check_lib crystalhd "stdint.h libcrystalhd/libcrystalhd_if.h" DtsCrystalHDVersion -lcrystalhd From 55fdfc88b844aa31af58bb4cdae7b071c76869a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Fri, 28 Jul 2017 12:55:43 +0200 Subject: [PATCH 2944/3374] build: treat crystalhd like other hwaccels --- configure | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/configure b/configure index 8dc05711b9fe5..75a3c97bcb2b8 100755 --- a/configure +++ b/configure @@ -1532,7 +1532,6 @@ EXTERNAL_LIBRARY_LIST=" $EXTERNAL_LIBRARY_VERSION3_LIST $EXTERNAL_LIBRARY_GPLV3_LIST chromaprint - crystalhd gcrypt gnutls jni @@ -1589,6 +1588,7 @@ EXTERNAL_LIBRARY_LIST=" " HWACCEL_AUTODETECT_LIBRARY_LIST=" audiotoolbox + crystalhd cuda cuvid d3d11va @@ -3597,7 +3597,7 @@ done enable_weak audiotoolbox # Enable hwaccels by default. -enable_weak d3d11va dxva2 vaapi vda vdpau videotoolbox_hwaccel xvmc +enable_weak crystalhd d3d11va dxva2 vaapi vda vdpau videotoolbox_hwaccel xvmc enable_weak xlib enable_weak cuda cuvid nvenc vda_framework videotoolbox videotoolbox_encoder @@ -5808,7 +5808,6 @@ enabled bzlib && check_lib bzlib bzlib.h BZ2_bzlibVersion -lbz2 enabled lzma && check_lib lzma lzma.h lzma_version_number -llzma check_lib libm math.h sin -lm && LIBM="-lm" -disabled crystalhd || check_lib crystalhd "stdint.h libcrystalhd/libcrystalhd_if.h" DtsCrystalHDVersion -lcrystalhd atan2f_args=2 copysign_args=2 @@ -6181,6 +6180,8 @@ enabled vdpau && enabled vdpau && check_lib vdpau_x11 "vdpau/vdpau.h vdpau/vdpau_x11.h" vdp_device_create_x11 -lvdpau -lX11 +enabled crystalhd && check_lib crystalhd "stdint.h libcrystalhd/libcrystalhd_if.h" DtsCrystalHDVersion -lcrystalhd + if enabled x86; then case $target_os in mingw32*|mingw64*|win32|win64|linux|cygwin*) From c9075d2c652bd90a5b559a9fa38dd0fd3de377e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Fri, 28 Jul 2017 12:58:39 +0200 Subject: [PATCH 2945/3374] build: treat iconv like other autodetected libraries --- configure | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 75a3c97bcb2b8..5dc0ed47f6ebe 100755 --- a/configure +++ b/configure @@ -3605,6 +3605,8 @@ enable_weak cuda cuvid nvenc vda_framework videotoolbox videotoolbox_encoder # Enable compression/decompression libraries by default enable_weak zlib bzlib lzma +enable_weak iconv + disabled logging && logfile=/dev/null die_license_disabled() { @@ -6203,7 +6205,7 @@ int main(void) { return 0; } EOF # Funny iconv installations are not unusual, so check it after all flags have been set -disabled iconv || check_func_headers iconv.h iconv || check_lib iconv iconv.h iconv -liconv +enabled iconv && check_func_headers iconv.h iconv || check_lib iconv iconv.h iconv -liconv enabled debug && add_cflags -g"$debuglevel" && add_asflags -g"$debuglevel" From 1c08ff08adc479cd37ca67b8285b0479cbac73b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Fri, 28 Jul 2017 13:16:42 +0200 Subject: [PATCH 2946/3374] build: treat libxcb like other autodetected libraries --- configure | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/configure b/configure index 5dc0ed47f6ebe..faad475bd7349 100755 --- a/configure +++ b/configure @@ -3598,7 +3598,7 @@ enable_weak audiotoolbox # Enable hwaccels by default. enable_weak crystalhd d3d11va dxva2 vaapi vda vdpau videotoolbox_hwaccel xvmc -enable_weak xlib +enable_weak xlib libxcb libxcb_shm libxcb_shape libxcb_xfixes enable_weak cuda cuvid nvenc vda_framework videotoolbox videotoolbox_encoder @@ -6119,31 +6119,17 @@ if enabled libcdio; then die "ERROR: No usable libcdio/cdparanoia found" fi -if ! disabled libxcb; then - check_pkg_config "xcb >= 1.4" xcb/xcb.h xcb_connect || { - enabled libxcb && die "ERROR: libxcb >= 1.4 not found"; - } && enable libxcb +enabled libxcb && check_pkg_config "xcb >= 1.4" xcb/xcb.h xcb_connect || disable libxcb if enabled libxcb; then - disabled libxcb_shm || { - check_pkg_config xcb-shm xcb/shm.h xcb_shm_attach || { - enabled libxcb_shm && die "ERROR: libxcb_shm not found"; - } && check_header sys/shm.h && enable libxcb_shm; } - disabled libxcb_xfixes || { - check_pkg_config xcb-xfixes xcb/xfixes.h xcb_xfixes_get_cursor_image || { - enabled libxcb_xfixes && die "ERROR: libxcb_xfixes not found"; - } && enable libxcb_xfixes; } - - disabled libxcb_shape || { - check_pkg_config xcb-shape xcb/shape.h xcb_shape_get_rectangles || { - enabled libxcb_shape && die "ERROR: libxcb_shape not found"; - } && enable libxcb_shape; } + enabled libxcb_shm && check_pkg_config xcb-shm xcb/shm.h xcb_shm_attach || disable libxcb_shm + enabled libxcb_shape && check_pkg_config xcb-shape xcb/shape.h xcb_shape_get_rectangles || disable libxcb_shape + enabled libxcb_xfixes && check_pkg_config xcb-xfixes xcb/xfixes.h xcb_xfixes_get_cursor_image || disable libxcb_xfixes add_cflags $xcb_cflags $xcb_shm_cflags $xcb_xfixes_cflags $xcb_shape_cflags add_extralibs $xcb_extralibs $xcb_shm_extralibs $xcb_xfixes_extralibs $xcb_shape_extralibs fi -fi check_func_headers "windows.h" CreateDIBSection "$gdigrab_indev_extralibs" From 72655616d9d1c92fac2af48c67bcdcd2b989bcf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Fri, 28 Jul 2017 13:22:40 +0200 Subject: [PATCH 2947/3374] build: treat securetransport and schannel like other autodetected libraries --- configure | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/configure b/configure index faad475bd7349..5a1e3809247d4 100755 --- a/configure +++ b/configure @@ -3606,6 +3606,7 @@ enable_weak cuda cuvid nvenc vda_framework videotoolbox videotoolbox_encoder enable_weak zlib bzlib lzma enable_weak iconv +enable_weak securetransport schannel disabled logging && logfile=/dev/null @@ -6055,11 +6056,16 @@ if enabled decklink; then esac fi -disabled securetransport || { check_func SecIdentityCreate "-Wl,-framework,CoreFoundation -Wl,-framework,Security" && - check_lib securetransport "Security/SecureTransport.h Security/Security.h" "SSLCreateContext SecItemImport" "-Wl,-framework,CoreFoundation -Wl,-framework,Security"; } +enabled securetransport && + check_func SecIdentityCreate "-Wl,-framework,CoreFoundation -Wl,-framework,Security" && + check_lib securetransport "Security/SecureTransport.h Security/Security.h" "SSLCreateContext SecItemImport" "-Wl,-framework,CoreFoundation -Wl,-framework,Security" || + disable securetransport -disabled schannel || { check_func_headers "windows.h security.h" InitializeSecurityContext -DSECURITY_WIN32 -lsecur32 && - check_cpp_condition winerror.h "defined(SEC_I_CONTEXT_EXPIRED)" && enable schannel && add_extralibs -lsecur32; } +enabled schannel && + check_func_headers "windows.h security.h" InitializeSecurityContext -DSECURITY_WIN32 -lsecur32 && + check_cpp_condition winerror.h "defined(SEC_I_CONTEXT_EXPIRED)" && + add_extralibs -lsecur32 || + disable schannel makeinfo --version > /dev/null 2>&1 && enable makeinfo || disable makeinfo enabled makeinfo \ From 778fa6350e24540304c9f61f1d3d4a602b37849a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 30 Aug 2017 13:12:14 +0200 Subject: [PATCH 2948/3374] build: isolate sdl-to-sdl2 aliasing This simplifies incoming SDL related changes by removing potential mismatching states of sdl and sdl2 variables. Since a component can have all kind of states (such as unset, enabled, disabled or requested), keeping these variables in sync manually in random places is not robust. --- configure | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/configure b/configure index 5a1e3809247d4..aa520e3064795 100755 --- a/configure +++ b/configure @@ -1488,7 +1488,6 @@ EXTERNAL_AUTODETECT_LIBRARY_LIST=" libxcb_xfixes lzma schannel - sdl sdl2 securetransport xlib @@ -3524,6 +3523,9 @@ for opt do action=${opt%%-random=*} do_random ${action#--} $optval ;; + --enable-sdl) + enable sdl2 + ;; --enable-*=*|--disable-*=*) eval $(echo "${opt%%=*}" | sed 's/--/action=/;s/-/ thing=/') is_in "${thing}s" $COMPONENT_LIST || die_unknown "$opt" @@ -6025,7 +6027,6 @@ if enabled gcrypt; then fi fi -disabled sdl && disable sdl2 if ! disabled sdl2; then SDL2_CONFIG="${cross_prefix}sdl2-config" if check_pkg_config sdl2 SDL_events.h SDL_PollEvent; then @@ -6045,7 +6046,7 @@ if ! disabled sdl2; then sdl2_extralibs="$sdl2_extralibs -mconsole" fi fi -enabled sdl2 && enable sdl && add_cflags $sdl2_cflags && add_extralibs $sdl2_extralibs +enabled sdl2 && add_cflags $sdl2_cflags && add_extralibs $sdl2_extralibs if enabled decklink; then case $target_os in From b802971d6db5ad09d8d7dd0bbc20e3eea4c25f54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 30 Aug 2017 13:13:08 +0200 Subject: [PATCH 2949/3374] build: treat sdl2 like other autodetected libraries --- configure | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/configure b/configure index aa520e3064795..c666f4b32bad2 100755 --- a/configure +++ b/configure @@ -6027,20 +6027,22 @@ if enabled gcrypt; then fi fi -if ! disabled sdl2; then +if enabled sdl2; then SDL2_CONFIG="${cross_prefix}sdl2-config" if check_pkg_config sdl2 SDL_events.h SDL_PollEvent; then check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) >= 0x020001" $sdl2_cflags && check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) < 0x020100" $sdl2_cflags && - check_func SDL_Init $sdl2_extralibs $sdl2_cflags && enable sdl2 - else - if "${SDL2_CONFIG}" --version > /dev/null 2>&1; then + check_func SDL_Init $sdl2_extralibs $sdl2_cflags || + disable sdl2 + elif "${SDL2_CONFIG}" --version > /dev/null 2>&1; then sdl2_cflags=$("${SDL2_CONFIG}" --cflags) sdl2_extralibs=$("${SDL2_CONFIG}" --libs) check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) >= 0x020001" $sdl2_cflags && check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) < 0x020100" $sdl2_cflags && - check_func SDL_Init $sdl2_extralibs $sdl2_cflags && enable sdl2 - fi + check_func SDL_Init $sdl2_extralibs $sdl2_cflags || + disable sdl2 + else + disable sdl2 fi if test $target_os = "mingw32"; then sdl2_extralibs="$sdl2_extralibs -mconsole" From 353c2e384c7000fa65092d36773d687d44c6ab95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 30 Aug 2017 13:46:38 +0200 Subject: [PATCH 2950/3374] build: replace use of HAVE_SDL2 with existing CONFIG_SDL2 There is no need for duplication. --- configure | 1 - libavdevice/opengl_enc.c | 22 +++++++++++----------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/configure b/configure index c666f4b32bad2..9c08fb2cbe90f 100755 --- a/configure +++ b/configure @@ -2068,7 +2068,6 @@ HAVE_LIST=" MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS perl pod2man - sdl2 section_data_rel_ro sndio texi2html diff --git a/libavdevice/opengl_enc.c b/libavdevice/opengl_enc.c index 1fc7ddd003968..bb6787c6f13ba 100644 --- a/libavdevice/opengl_enc.c +++ b/libavdevice/opengl_enc.c @@ -46,7 +46,7 @@ #include #endif -#if HAVE_SDL2 +#if CONFIG_SDL2 #include #endif @@ -174,7 +174,7 @@ static const GLushort g_index[6] = typedef struct OpenGLContext { AVClass *class; ///< class for private options -#if HAVE_SDL2 +#if CONFIG_SDL2 SDL_Window *window; SDL_GLContext glcontext; #endif @@ -343,7 +343,7 @@ static int opengl_control_message(AVFormatContext *h, int type, void *data, size return AVERROR(ENOSYS); } -#if HAVE_SDL2 +#if CONFIG_SDL2 static int opengl_sdl_process_events(AVFormatContext *h) { OpenGLContext *opengl = h->priv_data; @@ -448,14 +448,14 @@ static int av_cold opengl_sdl_load_procedures(OpenGLContext *opengl) #undef LOAD_OPENGL_FUN } -#endif /* HAVE_SDL2 */ +#endif /* CONFIG_SDL2 */ #if defined(__APPLE__) static int av_cold opengl_load_procedures(OpenGLContext *opengl) { FFOpenGLFunctions *procs = &opengl->glprocs; -#if HAVE_SDL2 +#if CONFIG_SDL2 if (!opengl->no_window) return opengl_sdl_load_procedures(opengl); #endif @@ -505,7 +505,7 @@ static int av_cold opengl_load_procedures(OpenGLContext *opengl) return AVERROR(ENOSYS); \ } -#if HAVE_SDL2 +#if CONFIG_SDL2 if (!opengl->no_window) return opengl_sdl_load_procedures(opengl); #endif @@ -931,7 +931,7 @@ static int opengl_create_window(AVFormatContext *h) int ret; if (!opengl->no_window) { -#if HAVE_SDL2 +#if CONFIG_SDL2 if ((ret = opengl_sdl_create_window(h)) < 0) { av_log(opengl, AV_LOG_ERROR, "Cannot create default SDL window.\n"); return ret; @@ -963,7 +963,7 @@ static int opengl_release_window(AVFormatContext *h) int ret; OpenGLContext *opengl = h->priv_data; if (!opengl->no_window) { -#if HAVE_SDL2 +#if CONFIG_SDL2 SDL_GL_DeleteContext(opengl->glcontext); SDL_DestroyWindow(opengl->window); SDL_Quit(); @@ -1099,7 +1099,7 @@ static av_cold int opengl_write_header(AVFormatContext *h) glClear(GL_COLOR_BUFFER_BIT); -#if HAVE_SDL2 +#if CONFIG_SDL2 if (!opengl->no_window) SDL_GL_SwapWindow(opengl->window); #endif @@ -1194,7 +1194,7 @@ static int opengl_draw(AVFormatContext *h, void *input, int repaint, int is_pkt) const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); int ret; -#if HAVE_SDL2 +#if CONFIG_SDL2 if (!opengl->no_window && (ret = opengl_sdl_process_events(h)) < 0) goto fail; #endif @@ -1235,7 +1235,7 @@ static int opengl_draw(AVFormatContext *h, void *input, int repaint, int is_pkt) ret = AVERROR_EXTERNAL; OPENGL_ERROR_CHECK(opengl); -#if HAVE_SDL2 +#if CONFIG_SDL2 if (!opengl->no_window) SDL_GL_SwapWindow(opengl->window); #endif From 7e98c3cbb372dc1ff8abba7c7d2ffaa932fda3cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Fri, 28 Jul 2017 13:31:35 +0200 Subject: [PATCH 2951/3374] build: remove vda_framework from enable_weak vda_framework is already pulled by the weakly enabled vda and videotoolbox. --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 9c08fb2cbe90f..b5e3629db0cdb 100755 --- a/configure +++ b/configure @@ -3601,7 +3601,7 @@ enable_weak audiotoolbox enable_weak crystalhd d3d11va dxva2 vaapi vda vdpau videotoolbox_hwaccel xvmc enable_weak xlib libxcb libxcb_shm libxcb_shape libxcb_xfixes -enable_weak cuda cuvid nvenc vda_framework videotoolbox videotoolbox_encoder +enable_weak cuda cuvid nvenc videotoolbox videotoolbox_encoder # Enable compression/decompression libraries by default enable_weak zlib bzlib lzma From 9ef5a2f5f30bdc4ac86275ae4b4708ab4681b21d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Fri, 28 Jul 2017 13:39:00 +0200 Subject: [PATCH 2952/3374] build: simplify weak-enabling of autodetected libraries --- configure | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/configure b/configure index b5e3629db0cdb..fea9f956b8c41 100755 --- a/configure +++ b/configure @@ -3593,21 +3593,9 @@ done for lib in $AUTODETECT_LIBS; do enabled $lib && request $lib done - -# Enable platform codecs by default. -enable_weak audiotoolbox - -# Enable hwaccels by default. -enable_weak crystalhd d3d11va dxva2 vaapi vda vdpau videotoolbox_hwaccel xvmc -enable_weak xlib libxcb libxcb_shm libxcb_shape libxcb_xfixes - -enable_weak cuda cuvid nvenc videotoolbox videotoolbox_encoder - -# Enable compression/decompression libraries by default -enable_weak zlib bzlib lzma - -enable_weak iconv -enable_weak securetransport schannel +#TODO: switch to $AUTODETECT_LIBS when $THREADS_LIST is supported the same way +enable_weak $EXTERNAL_AUTODETECT_LIBRARY_LIST +enable_weak $HWACCEL_AUTODETECT_LIBRARY_LIST disabled logging && logfile=/dev/null From e3c1219c7c7457f4b157cfb299e4387c1ebdabe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Fri, 28 Jul 2017 13:44:07 +0200 Subject: [PATCH 2953/3374] build: add --disable-autodetect switch --- Changelog | 1 + configure | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/Changelog b/Changelog index 830941757e61a..ccbcdf6328f85 100644 --- a/Changelog +++ b/Changelog @@ -40,6 +40,7 @@ version : They must always be used by name. - FITS demuxer and decoder - FITS muxer and encoder +- add --disable-autodetect build switch version 3.3: - CrystalHD decoder moved to new decode API diff --git a/configure b/configure index fea9f956b8c41..f29fe1145c020 100755 --- a/configure +++ b/configure @@ -109,6 +109,7 @@ Configuration options: --enable-gray enable full grayscale support (slower color) --disable-swscale-alpha disable alpha channel support in swscale --disable-all disable building components, libraries and programs + --disable-autodetect disable automatically detected external libraries [no] Program options: --disable-programs do not build command line programs @@ -1685,6 +1686,7 @@ CONFIG_LIST=" $LIBRARY_LIST $PROGRAM_LIST $SUBSYSTEM_LIST + autodetect fontconfig memory_poisoning neon_clobber_test @@ -3589,6 +3591,10 @@ for e in $env; do eval "export $e" done +if disabled autodetect; then + disable_weak $EXTERNAL_AUTODETECT_LIBRARY_LIST + disable_weak $HWACCEL_AUTODETECT_LIBRARY_LIST +fi # Mark specifically enabled, but normally autodetected libraries as requested. for lib in $AUTODETECT_LIBS; do enabled $lib && request $lib From fe9c85e4e2650dc9537b54b1eabb4f9be7b628ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 30 Aug 2017 12:26:01 +0200 Subject: [PATCH 2954/3374] build: make sure a disabled autodetect still pick the libc's iconv --- configure | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/configure b/configure index f29fe1145c020..7c2a196585283 100755 --- a/configure +++ b/configure @@ -3592,6 +3592,11 @@ for e in $env; do done if disabled autodetect; then + + # Unless iconv is explicitely disabled by the user, we still want to probe + # for the iconv from the libc. + disabled iconv || enable libc_iconv + disable_weak $EXTERNAL_AUTODETECT_LIBRARY_LIST disable_weak $HWACCEL_AUTODETECT_LIBRARY_LIST fi @@ -6193,7 +6198,11 @@ int main(void) { return 0; } EOF # Funny iconv installations are not unusual, so check it after all flags have been set -enabled iconv && check_func_headers iconv.h iconv || check_lib iconv iconv.h iconv -liconv +if enabled libc_iconv; then + check_func_headers iconv.h iconv +elif enabled iconv; then + check_func_headers iconv.h iconv || check_lib iconv iconv.h iconv -liconv +fi enabled debug && add_cflags -g"$debuglevel" && add_asflags -g"$debuglevel" From b447629093d75f18d0a8fc44ec768022322b2182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 30 Aug 2017 13:28:49 +0200 Subject: [PATCH 2955/3374] build: make alsa part of the autodetected libraries alsa libs are already autodetected, this commit makes sure --disable-autodetect actually disable it unless --enable-alsa is specified. --- configure | 6 +++--- libavdevice/Makefile | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/configure b/configure index 7c2a196585283..9e9fbf29a4695 100755 --- a/configure +++ b/configure @@ -201,6 +201,7 @@ External library support: Also note that the following help text describes the purpose of the libraries themselves, not all their features will necessarily be usable by FFmpeg. + --disable-alsa disable ALSA support [autodetect] --enable-avisynth enable reading of AviSynth script files [no] --disable-bzlib disable bzlib [autodetect] --enable-chromaprint enable audio fingerprinting with chromaprint [no] @@ -1481,6 +1482,7 @@ EXAMPLE_LIST=" transcoding_example " EXTERNAL_AUTODETECT_LIBRARY_LIST=" + alsa bzlib iconv libxcb @@ -2060,7 +2062,6 @@ HAVE_LIST=" $THREADS_LIST $TOOLCHAIN_FEATURES $TYPES_LIST - alsa atomics_native dos_paths jack @@ -6112,8 +6113,7 @@ EOF fi check_header soundcard.h -enabled_any alsa_indev alsa_outdev && - check_lib alsa alsa/asoundlib.h snd_pcm_htimestamp -lasound +enabled alsa && check_lib alsa alsa/asoundlib.h snd_pcm_htimestamp -lasound enabled jack_indev && check_lib jack jack/jack.h jack_client_open -ljack && check_func jack_port_get_latency_range -ljack diff --git a/libavdevice/Makefile b/libavdevice/Makefile index 80afa61e36c47..58362e3f2ded2 100644 --- a/libavdevice/Makefile +++ b/libavdevice/Makefile @@ -70,7 +70,7 @@ SKIPHEADERS-$(CONFIG_FBDEV_OUTDEV) += fbdev_common.h SKIPHEADERS-$(CONFIG_LIBPULSE) += pulse_audio_common.h SKIPHEADERS-$(CONFIG_V4L2_INDEV) += v4l2-common.h SKIPHEADERS-$(CONFIG_V4L2_OUTDEV) += v4l2-common.h -SKIPHEADERS-$(HAVE_ALSA) += alsa.h +SKIPHEADERS-$(CONFIG_ALSA) += alsa.h SKIPHEADERS-$(HAVE_SNDIO) += sndio.h TESTPROGS-$(CONFIG_JACK_INDEV) += timefilter From b7fbb3516a99ebfa511143bdd8f63d8bd0d89385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 30 Aug 2017 13:34:50 +0200 Subject: [PATCH 2956/3374] build: make jack part of the autodetected libraries jack is already autodetected, this commit makes sure --disable-autodetect actually disable it unless --enable-jack is specified. --- configure | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 9e9fbf29a4695..dd580d9461ffd 100755 --- a/configure +++ b/configure @@ -213,6 +213,7 @@ External library support: --enable-gnutls enable gnutls, needed for https support if openssl is not used [no] --disable-iconv disable iconv [autodetect] + --disable-jack disable libjack support [autodetect] --enable-jni enable JNI support [no] --enable-ladspa enable LADSPA audio filtering [no] --enable-libass enable libass subtitles rendering, @@ -1485,6 +1486,7 @@ EXTERNAL_AUTODETECT_LIBRARY_LIST=" alsa bzlib iconv + jack libxcb libxcb_shm libxcb_shape @@ -2064,7 +2066,6 @@ HAVE_LIST=" $TYPES_LIST atomics_native dos_paths - jack libc_msvcrt makeinfo makeinfo_html @@ -6115,7 +6116,7 @@ check_header soundcard.h enabled alsa && check_lib alsa alsa/asoundlib.h snd_pcm_htimestamp -lasound -enabled jack_indev && check_lib jack jack/jack.h jack_client_open -ljack && +enabled jack && check_lib jack jack/jack.h jack_client_open -ljack && check_func jack_port_get_latency_range -ljack enabled_any sndio_indev sndio_outdev && check_lib sndio sndio.h sio_open -lsndio From e090e750bac863f066515cff6fd363c157ea3c21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 30 Aug 2017 13:41:23 +0200 Subject: [PATCH 2957/3374] build: make sndio part of the autodetected libraries sndio is already autodetected, this commit makes sure --disable-autodetect actually disable it unless --enable-sndio is specified. --- configure | 5 +++-- libavdevice/Makefile | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/configure b/configure index dd580d9461ffd..5b24317490222 100755 --- a/configure +++ b/configure @@ -288,6 +288,7 @@ External library support: --enable-opengl enable OpenGL rendering [no] --enable-openssl enable openssl, needed for https support if gnutls is not used [no] + --disable-sndio disable sndio support [autodetect] --disable-schannel disable SChannel SSP, needed for TLS support on Windows if openssl and gnutls are not used [autodetect] --disable-sdl2 disable sdl2 [autodetect] @@ -1495,6 +1496,7 @@ EXTERNAL_AUTODETECT_LIBRARY_LIST=" schannel sdl2 securetransport + sndio xlib zlib " @@ -2073,7 +2075,6 @@ HAVE_LIST=" perl pod2man section_data_rel_ro - sndio texi2html threads uwp @@ -6119,7 +6120,7 @@ enabled alsa && check_lib alsa alsa/asoundlib.h snd_pcm_htimestamp -lasound enabled jack && check_lib jack jack/jack.h jack_client_open -ljack && check_func jack_port_get_latency_range -ljack -enabled_any sndio_indev sndio_outdev && check_lib sndio sndio.h sio_open -lsndio +enabled sndio && check_lib sndio sndio.h sio_open -lsndio if enabled libcdio; then check_lib libcdio "cdio/cdda.h cdio/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio || diff --git a/libavdevice/Makefile b/libavdevice/Makefile index 58362e3f2ded2..cd077b292ec52 100644 --- a/libavdevice/Makefile +++ b/libavdevice/Makefile @@ -71,6 +71,6 @@ SKIPHEADERS-$(CONFIG_LIBPULSE) += pulse_audio_common.h SKIPHEADERS-$(CONFIG_V4L2_INDEV) += v4l2-common.h SKIPHEADERS-$(CONFIG_V4L2_OUTDEV) += v4l2-common.h SKIPHEADERS-$(CONFIG_ALSA) += alsa.h -SKIPHEADERS-$(HAVE_SNDIO) += sndio.h +SKIPHEADERS-$(CONFIG_SNDIO) += sndio.h TESTPROGS-$(CONFIG_JACK_INDEV) += timefilter From 69e6877de8ad33a533379213d2b046a3dd4a446a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 30 Aug 2017 13:56:27 +0200 Subject: [PATCH 2958/3374] build: drop unused sndio_h and asoundlib_h --- configure | 2 -- 1 file changed, 2 deletions(-) diff --git a/configure b/configure index 5b24317490222..445d953e4fd11 100755 --- a/configure +++ b/configure @@ -1854,7 +1854,6 @@ HAVE_LIST_PUB=" " HEADERS_LIST=" - alsa_asoundlib_h altivec_h arpa_inet_h asm_types_h @@ -1887,7 +1886,6 @@ HEADERS_LIST=" openjpeg_1_5_openjpeg_h OpenGL_gl3_h poll_h - sndio_h soundcard_h stdatomic_h sys_mman_h From 2a0823ae966be3ad40e5dba6ec4c4dc1e8c6bcad Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 1 Sep 2017 19:56:10 +0200 Subject: [PATCH 2959/3374] avcodec/diracdec: Fix integer overflow in INTRA_DC_PRED() Fixes: runtime error: signed integer overflow: 1168175789 + 1168178473 cannot be represented in type 'int' Fixes: 3081/clusterfuzz-testcase-minimized-4807564879462400 Fixes: 2844/clusterfuzz-testcase-minimized-5561715838156800 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/diracdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c index 0aee08f9e115c..f2aed6057da1d 100644 --- a/libavcodec/diracdec.c +++ b/libavcodec/diracdec.c @@ -586,7 +586,7 @@ static inline void codeblock(DiracContext *s, SubBand *b, } \ INTRA_DC_PRED(8, int16_t) -INTRA_DC_PRED(10, int32_t) +INTRA_DC_PRED(10, uint32_t) /** * Dirac Specification -> From f71cd44147e7a914f80fcfacca46c9e7b0374362 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 1 Sep 2017 19:56:11 +0200 Subject: [PATCH 2960/3374] avcodec/dirac_dwt: Fix multiple overflows in 9/7 lifting Fixes: runtime error: signed integer overflow: 1073901567 + 1073901567 cannot be represented in type 'int' Fixes: 3124/clusterfuzz-testcase-minimized-454643435752652 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/dirac_dwt.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/dirac_dwt.h b/libavcodec/dirac_dwt.h index e715e53bc4292..adf5178714dba 100644 --- a/libavcodec/dirac_dwt.h +++ b/libavcodec/dirac_dwt.h @@ -117,16 +117,16 @@ void ff_spatial_idwt_slice2(DWTContext *d, int y); (b4 + ((-2*(b0+b8) + 10*(b1+b7) - 25*(b2+b6) + 81*(b3+b5) + 128) >> 8)) #define COMPOSE_DAUB97iL1(b0, b1, b2)\ - (b1 - ((int)(1817U*(b0 + b2) + 2048) >> 12)) + (b1 - ((int)(1817*(b0 + (unsigned)b2) + 2048) >> 12)) #define COMPOSE_DAUB97iH1(b0, b1, b2)\ - (b1 - ((int)( 113U*(b0 + b2) + 64) >> 7)) + (b1 - ((int)( 113*(b0 + (unsigned)b2) + 64) >> 7)) #define COMPOSE_DAUB97iL0(b0, b1, b2)\ - (b1 + ((int)( 217U*(b0 + b2) + 2048) >> 12)) + (b1 + ((int)( 217*(b0 + (unsigned)b2) + 2048) >> 12)) #define COMPOSE_DAUB97iH0(b0, b1, b2)\ - (b1 + ((int)(6497U*(b0 + b2) + 2048) >> 12)) + (b1 + ((int)(6497*(b0 + (unsigned)b2) + 2048) >> 12)) #endif /* AVCODEC_DWT_H */ From c595139f1fdb5ce5ee128c317ed9e4e836282436 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 1 Sep 2017 19:56:12 +0200 Subject: [PATCH 2961/3374] avcodec/dirac_vlc: Fix invalid shift in ff_dirac_golomb_read_32bit() Fixes: runtime error: shift exponent 64 is too large for 64-bit type 'residual' (aka 'unsigned long') Fixes: 2838/clusterfuzz-testcase-minimized-6260066086813696 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/dirac_vlc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavcodec/dirac_vlc.c b/libavcodec/dirac_vlc.c index d3b9900beba36..bd37f31f469f3 100644 --- a/libavcodec/dirac_vlc.c +++ b/libavcodec/dirac_vlc.c @@ -56,6 +56,9 @@ int ff_dirac_golomb_read_32bit(DiracGolombLUT *lut_ctx, const uint8_t *buf, if ((c_idx + 1) > coeffs) return c_idx; + if (res_bits >= RSIZE_BITS) + res_bits = res = 0; + /* res_bits is a hint for better branch prediction */ if (res_bits && l->sign) { int32_t coeff = 1; From b4b1285fa1b6b84cc68cad67e7ea1389863cd178 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sun, 3 Sep 2017 00:18:57 +0200 Subject: [PATCH 2962/3374] lavd: drop disabled v4l code This code is disabled since 2012. V4L1 was dropped from the kernel more than 10 years ago. --- configure | 2 - libavdevice/Makefile | 1 - libavdevice/alldevices.c | 1 - libavdevice/v4l.c | 364 --------------------------------------- 4 files changed, 368 deletions(-) delete mode 100644 libavdevice/v4l.c diff --git a/configure b/configure index 445d953e4fd11..d58270550ca61 100755 --- a/configure +++ b/configure @@ -3048,7 +3048,6 @@ qtkit_indev_select="qtkit" sdl2_outdev_deps="sdl2" sndio_indev_deps="sndio" sndio_outdev_deps="sndio" -v4l_indev_deps="linux_videodev_h" v4l2_indev_deps_any="linux_videodev2_h sys_videoio_h" v4l2_outdev_deps_any="linux_videodev2_h sys_videoio_h" vfwcap_indev_deps="vfw32 vfwcap_defines" @@ -6079,7 +6078,6 @@ pod2man --help > /dev/null 2>&1 && enable pod2man || disable pod2man rsync --help 2> /dev/null | grep -q 'contimeout' && enable rsync_contimeout || disable rsync_contimeout check_header linux/fb.h -check_header linux/videodev.h check_header linux/videodev2.h check_code cc linux/videodev2.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_safe struct_v4l2_frmivalenum_discrete diff --git a/libavdevice/Makefile b/libavdevice/Makefile index cd077b292ec52..0efb3f905f6b1 100644 --- a/libavdevice/Makefile +++ b/libavdevice/Makefile @@ -47,7 +47,6 @@ OBJS-$(CONFIG_SNDIO_INDEV) += sndio_dec.o sndio.o OBJS-$(CONFIG_SNDIO_OUTDEV) += sndio_enc.o sndio.o OBJS-$(CONFIG_V4L2_INDEV) += v4l2.o v4l2-common.o timefilter.o OBJS-$(CONFIG_V4L2_OUTDEV) += v4l2enc.o v4l2-common.o -OBJS-$(CONFIG_V4L_INDEV) += v4l.o OBJS-$(CONFIG_VFWCAP_INDEV) += vfwcap.o OBJS-$(CONFIG_XCBGRAB_INDEV) += xcbgrab.o OBJS-$(CONFIG_XV_OUTDEV) += xv.o diff --git a/libavdevice/alldevices.c b/libavdevice/alldevices.c index 8d1cb8648f5e7..4bf08d798db8e 100644 --- a/libavdevice/alldevices.c +++ b/libavdevice/alldevices.c @@ -62,7 +62,6 @@ static void register_all(void) REGISTER_OUTDEV (SDL2, sdl2); REGISTER_INOUTDEV(SNDIO, sndio); REGISTER_INOUTDEV(V4L2, v4l2); -// REGISTER_INDEV (V4L, v4l REGISTER_INDEV (VFWCAP, vfwcap); REGISTER_INDEV (XCBGRAB, xcbgrab); REGISTER_OUTDEV (XV, xv); diff --git a/libavdevice/v4l.c b/libavdevice/v4l.c deleted file mode 100644 index 81653e02fb5cc..0000000000000 --- a/libavdevice/v4l.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Linux video grab interface - * Copyright (c) 2000,2001 Fabrice Bellard - * - * 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 "avdevice.h" - -#undef __STRICT_ANSI__ //workaround due to broken kernel headers -#include "config.h" -#include "libavutil/rational.h" -#include "libavutil/imgutils.h" -#include "libavutil/internal.h" -#include "libavutil/log.h" -#include "libavutil/opt.h" -#include "libavformat/internal.h" -#include "libavcodec/dsputil.h" -#include -#include -#include -#include -#include -#define _LINUX_TIME_H 1 -#include -#include - -typedef struct { - AVClass *class; - int fd; - int frame_format; /* see VIDEO_PALETTE_xxx */ - int use_mmap; - AVRational time_base; - int64_t time_frame; - int frame_size; - struct video_capability video_cap; - struct video_audio audio_saved; - struct video_window video_win; - uint8_t *video_buf; - struct video_mbuf gb_buffers; - struct video_mmap gb_buf; - int gb_frame; - int standard; -} VideoData; - -static const struct { - int palette; - int depth; - enum AVPixelFormat pix_fmt; -} video_formats [] = { - {.palette = VIDEO_PALETTE_YUV420P, .depth = 12, .pix_fmt = AV_PIX_FMT_YUV420P }, - {.palette = VIDEO_PALETTE_YUV422, .depth = 16, .pix_fmt = AV_PIX_FMT_YUYV422 }, - {.palette = VIDEO_PALETTE_UYVY, .depth = 16, .pix_fmt = AV_PIX_FMT_UYVY422 }, - {.palette = VIDEO_PALETTE_YUYV, .depth = 16, .pix_fmt = AV_PIX_FMT_YUYV422 }, - /* NOTE: v4l uses BGR24, not RGB24 */ - {.palette = VIDEO_PALETTE_RGB24, .depth = 24, .pix_fmt = AV_PIX_FMT_BGR24 }, - {.palette = VIDEO_PALETTE_RGB565, .depth = 16, .pix_fmt = AV_PIX_FMT_BGR565 }, - {.palette = VIDEO_PALETTE_GREY, .depth = 8, .pix_fmt = AV_PIX_FMT_GRAY8 }, -}; - - -static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) -{ - VideoData *s = s1->priv_data; - AVStream *st; - int video_fd; - int desired_palette, desired_depth; - struct video_tuner tuner; - struct video_audio audio; - struct video_picture pict; - int j; - int vformat_num = FF_ARRAY_ELEMS(video_formats); - - av_log(s1, AV_LOG_WARNING, "V4L input device is deprecated and will be removed in the next release."); - - if (ap->time_base.den <= 0) { - av_log(s1, AV_LOG_ERROR, "Wrong time base (%d)\n", ap->time_base.den); - return -1; - } - s->time_base = ap->time_base; - - s->video_win.width = ap->width; - s->video_win.height = ap->height; - - st = avformat_new_stream(s1, NULL); - if (!st) - return AVERROR(ENOMEM); - avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ - - video_fd = open(s1->filename, O_RDWR); - if (video_fd < 0) { - av_log(s1, AV_LOG_ERROR, "%s: %s\n", s1->filename, strerror(errno)); - goto fail; - } - - if (ioctl(video_fd, VIDIOCGCAP, &s->video_cap) < 0) { - av_log(s1, AV_LOG_ERROR, "VIDIOCGCAP: %s\n", strerror(errno)); - goto fail; - } - - if (!(s->video_cap.type & VID_TYPE_CAPTURE)) { - av_log(s1, AV_LOG_ERROR, "Fatal: grab device does not handle capture\n"); - goto fail; - } - - /* no values set, autodetect them */ - if (s->video_win.width <= 0 || s->video_win.height <= 0) { - if (ioctl(video_fd, VIDIOCGWIN, &s->video_win, sizeof(s->video_win)) < 0) { - av_log(s1, AV_LOG_ERROR, "VIDIOCGWIN: %s\n", strerror(errno)); - goto fail; - } - } - - if(av_image_check_size(s->video_win.width, s->video_win.height, 0, s1) < 0) - return -1; - - desired_palette = -1; - desired_depth = -1; - for (j = 0; j < vformat_num; j++) { - if (ap->pix_fmt == video_formats[j].pix_fmt) { - desired_palette = video_formats[j].palette; - desired_depth = video_formats[j].depth; - break; - } - } - - /* set tv standard */ - if (!ioctl(video_fd, VIDIOCGTUNER, &tuner)) { - tuner.mode = s->standard; - ioctl(video_fd, VIDIOCSTUNER, &tuner); - } - - /* unmute audio */ - audio.audio = 0; - ioctl(video_fd, VIDIOCGAUDIO, &audio); - memcpy(&s->audio_saved, &audio, sizeof(audio)); - audio.flags &= ~VIDEO_AUDIO_MUTE; - ioctl(video_fd, VIDIOCSAUDIO, &audio); - - ioctl(video_fd, VIDIOCGPICT, &pict); - ff_dlog(s1, "v4l: colour=%d hue=%d brightness=%d constrast=%d whiteness=%d\n", - pict.colour, pict.hue, pict.brightness, pict.contrast, pict.whiteness); - /* try to choose a suitable video format */ - pict.palette = desired_palette; - pict.depth= desired_depth; - if (desired_palette == -1 || ioctl(video_fd, VIDIOCSPICT, &pict) < 0) { - for (j = 0; j < vformat_num; j++) { - pict.palette = video_formats[j].palette; - pict.depth = video_formats[j].depth; - if (-1 != ioctl(video_fd, VIDIOCSPICT, &pict)) - break; - } - if (j >= vformat_num) - goto fail1; - } - - if (ioctl(video_fd, VIDIOCGMBUF, &s->gb_buffers) < 0) { - /* try to use read based access */ - int val; - - s->video_win.x = 0; - s->video_win.y = 0; - s->video_win.chromakey = -1; - s->video_win.flags = 0; - - if (ioctl(video_fd, VIDIOCSWIN, s->video_win) < 0) { - av_log(s1, AV_LOG_ERROR, "VIDIOCSWIN: %s\n", strerror(errno)); - goto fail; - } - - s->frame_format = pict.palette; - - val = 1; - if (ioctl(video_fd, VIDIOCCAPTURE, &val) < 0) { - av_log(s1, AV_LOG_ERROR, "VIDIOCCAPTURE: %s\n", strerror(errno)); - goto fail; - } - - s->time_frame = av_gettime() * s->time_base.den / s->time_base.num; - s->use_mmap = 0; - } else { - s->video_buf = mmap(0, s->gb_buffers.size, PROT_READ|PROT_WRITE, MAP_SHARED, video_fd, 0); - if ((unsigned char*)-1 == s->video_buf) { - s->video_buf = mmap(0, s->gb_buffers.size, PROT_READ|PROT_WRITE, MAP_PRIVATE, video_fd, 0); - if ((unsigned char*)-1 == s->video_buf) { - av_log(s1, AV_LOG_ERROR, "mmap: %s\n", strerror(errno)); - goto fail; - } - } - s->gb_frame = 0; - s->time_frame = av_gettime() * s->time_base.den / s->time_base.num; - - /* start to grab the first frame */ - s->gb_buf.frame = s->gb_frame % s->gb_buffers.frames; - s->gb_buf.height = s->video_win.height; - s->gb_buf.width = s->video_win.width; - s->gb_buf.format = pict.palette; - - if (ioctl(video_fd, VIDIOCMCAPTURE, &s->gb_buf) < 0) { - if (errno != EAGAIN) { - fail1: - av_log(s1, AV_LOG_ERROR, "VIDIOCMCAPTURE: %s\n", strerror(errno)); - } else { - av_log(s1, AV_LOG_ERROR, "Fatal: grab device does not receive any video signal\n"); - } - goto fail; - } - for (j = 1; j < s->gb_buffers.frames; j++) { - s->gb_buf.frame = j; - ioctl(video_fd, VIDIOCMCAPTURE, &s->gb_buf); - } - s->frame_format = s->gb_buf.format; - s->use_mmap = 1; - } - - for (j = 0; j < vformat_num; j++) { - if (s->frame_format == video_formats[j].palette) { - s->frame_size = s->video_win.width * s->video_win.height * video_formats[j].depth / 8; - st->codec->pix_fmt = video_formats[j].pix_fmt; - break; - } - } - - if (j >= vformat_num) - goto fail; - - s->fd = video_fd; - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_RAWVIDEO; - st->codec->width = s->video_win.width; - st->codec->height = s->video_win.height; - st->codec->time_base = s->time_base; - st->codec->bit_rate = s->frame_size * 1/av_q2d(st->codec->time_base) * 8; - - return 0; - fail: - if (video_fd >= 0) - close(video_fd); - return AVERROR(EIO); -} - -static int v4l_mm_read_picture(VideoData *s, uint8_t *buf) -{ - uint8_t *ptr; - - while (ioctl(s->fd, VIDIOCSYNC, &s->gb_frame) < 0 && - (errno == EAGAIN || errno == EINTR)); - - ptr = s->video_buf + s->gb_buffers.offsets[s->gb_frame]; - memcpy(buf, ptr, s->frame_size); - - /* Setup to capture the next frame */ - s->gb_buf.frame = s->gb_frame; - if (ioctl(s->fd, VIDIOCMCAPTURE, &s->gb_buf) < 0) { - if (errno == EAGAIN) - av_log(NULL, AV_LOG_ERROR, "Cannot Sync\n"); - else - av_log(NULL, AV_LOG_ERROR, "VIDIOCMCAPTURE: %s\n", strerror(errno)); - return AVERROR(EIO); - } - - /* This is now the grabbing frame */ - s->gb_frame = (s->gb_frame + 1) % s->gb_buffers.frames; - - return s->frame_size; -} - -static int grab_read_packet(AVFormatContext *s1, AVPacket *pkt) -{ - VideoData *s = s1->priv_data; - int64_t curtime, delay; - struct timespec ts; - - /* Calculate the time of the next frame */ - s->time_frame += INT64_C(1000000); - - /* wait based on the frame rate */ - for(;;) { - curtime = av_gettime(); - delay = s->time_frame * s->time_base.num / s->time_base.den - curtime; - if (delay <= 0) { - if (delay < INT64_C(-1000000) * s->time_base.num / s->time_base.den) { - /* printf("grabbing is %d frames late (dropping)\n", (int) -(delay / 16666)); */ - s->time_frame += INT64_C(1000000); - } - break; - } - ts.tv_sec = delay / 1000000; - ts.tv_nsec = (delay % 1000000) * 1000; - nanosleep(&ts, NULL); - } - - if (av_new_packet(pkt, s->frame_size) < 0) - return AVERROR(EIO); - - pkt->pts = curtime; - - /* read one frame */ - if (s->use_mmap) { - return v4l_mm_read_picture(s, pkt->data); - } else { - if (read(s->fd, pkt->data, pkt->size) != pkt->size) - return AVERROR(EIO); - return s->frame_size; - } -} - -static int grab_read_close(AVFormatContext *s1) -{ - VideoData *s = s1->priv_data; - - if (s->use_mmap) - munmap(s->video_buf, s->gb_buffers.size); - - /* mute audio. we must force it because the BTTV driver does not - return its state correctly */ - s->audio_saved.flags |= VIDEO_AUDIO_MUTE; - ioctl(s->fd, VIDIOCSAUDIO, &s->audio_saved); - - close(s->fd); - return 0; -} - -static const AVOption options[] = { - { "standard", "", offsetof(VideoData, standard), AV_OPT_TYPE_INT, {.i64 = VIDEO_MODE_NTSC}, VIDEO_MODE_PAL, VIDEO_MODE_NTSC, AV_OPT_FLAG_DECODING_PARAM, "standard" }, - { "PAL", "", 0, AV_OPT_TYPE_CONST, {.i64 = VIDEO_MODE_PAL}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" }, - { "SECAM", "", 0, AV_OPT_TYPE_CONST, {.i64 = VIDEO_MODE_SECAM}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" }, - { "NTSC", "", 0, AV_OPT_TYPE_CONST, {.i64 = VIDEO_MODE_NTSC}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" }, - { NULL }, -}; - -static const AVClass v4l_class = { - .class_name = "V4L indev", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, - .category = AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT, -}; - -AVInputFormat ff_v4l_demuxer = { - .name = "video4linux,v4l", - .long_name = NULL_IF_CONFIG_SMALL("Video4Linux device grab"), - .priv_data_size = sizeof(VideoData), - .read_header = grab_read_header, - .read_packet = grab_read_packet, - .read_close = grab_read_close, - .flags = AVFMT_NOFILE, - .priv_class = &v4l_class, -}; From dda1c23c20d727b7b9dbe1121cc63c2ba54f51ff Mon Sep 17 00:00:00 2001 From: Leo Izen Date: Sun, 3 Sep 2017 05:01:13 -0400 Subject: [PATCH 2963/3374] doc/filters.texi: Add default values to vf_vaguedenoiser options --- doc/filters.texi | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index afcb99d876ee3..c898c435575d7 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -14911,7 +14911,7 @@ This filter accepts the following options: @item threshold The filtering strength. The higher, the more filtered the video will be. Hard thresholding can use a higher threshold than soft thresholding -before the video looks overfiltered. +before the video looks overfiltered. Default value is 2. @item method The filtering method the filter will use. @@ -14930,13 +14930,15 @@ Scales or nullifies coefficients - intermediary between (more) soft and (less) hard thresholding. @end table +Default is garrote. + @item nsteps Number of times, the wavelet will decompose the picture. Picture can't be decomposed beyond a particular point (typically, 8 for a 640x480 -frame - as 2^9 = 512 > 480) +frame - as 2^9 = 512 > 480). Valid values are integers between 1 and 32. Default value is 6. @item percent -Partial of full denoising (limited coefficients shrinking), from 0 to 100. +Partial of full denoising (limited coefficients shrinking), from 0 to 100. Default value is 85. @item planes A list of the planes to process. By default all planes are processed. From f19e4118e9ca392f89d3c264aa8490b7d9ac3284 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Wed, 30 Aug 2017 21:04:02 +0200 Subject: [PATCH 2964/3374] avfilter/vf_subtitles: enable processing of alpha channel Fixes #6605. Signed-off-by: Paul B Mahol --- doc/filters.texi | 3 +++ libavfilter/vf_subtitles.c | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/filters.texi b/doc/filters.texi index c898c435575d7..19ca055076a95 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -14005,6 +14005,9 @@ correctly scale the fonts if the aspect ratio has been changed. Set a directory path containing fonts that can be used by the filter. These fonts will be used in addition to whatever the font provider uses. +@item alpha +Process alpha channel, by default alpha channel is untouched. + @item charenc Set subtitles input character encoding. @code{subtitles} filter only. Only useful if not UTF-8. diff --git a/libavfilter/vf_subtitles.c b/libavfilter/vf_subtitles.c index 805ee2d7e0d92..66a564699a0b2 100644 --- a/libavfilter/vf_subtitles.c +++ b/libavfilter/vf_subtitles.c @@ -54,6 +54,7 @@ typedef struct AssContext { char *charenc; char *force_style; int stream_index; + int alpha; uint8_t rgba_map[4]; int pix_step[4]; ///< steps per pixel for each plane of the main output int original_w, original_h; @@ -69,6 +70,7 @@ typedef struct AssContext { {"f", "set the filename of file to read", OFFSET(filename), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, \ {"original_size", "set the size of the original video (used to scale fonts)", OFFSET(original_w), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, \ {"fontsdir", "set the directory containing the fonts to read", OFFSET(fontsdir), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, \ + {"alpha", "enable processing of alpha channel", OFFSET(alpha), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, FLAGS }, \ /* libass supports a log level ranging from 0 to 7 */ static const int ass_libavfilter_log_level_map[] = { @@ -140,7 +142,7 @@ static int config_input(AVFilterLink *inlink) { AssContext *ass = inlink->dst->priv; - ff_draw_init(&ass->draw, inlink->format, 0); + ff_draw_init(&ass->draw, inlink->format, ass->alpha ? FF_DRAW_PROCESS_ALPHA : 0); ass_set_frame_size (ass->renderer, inlink->w, inlink->h); if (ass->original_w && ass->original_h) From 06ed3768c88cce44ba157ec81676acf96e50a61a Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 3 Sep 2017 13:37:43 +0200 Subject: [PATCH 2965/3374] avfilter/vf_displace: remove useless requirement that SAR matches between input streams Signed-off-by: Paul B Mahol --- libavfilter/vf_displace.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/libavfilter/vf_displace.c b/libavfilter/vf_displace.c index 6100a249c6a98..a894021bff7ae 100644 --- a/libavfilter/vf_displace.c +++ b/libavfilter/vf_displace.c @@ -280,27 +280,17 @@ static int config_output(AVFilterLink *outlink) av_log(ctx, AV_LOG_ERROR, "inputs must be of same pixel format\n"); return AVERROR(EINVAL); } - if (srclink->w != xlink->w || - srclink->h != xlink->h || - srclink->sample_aspect_ratio.num != xlink->sample_aspect_ratio.num || - srclink->sample_aspect_ratio.den != xlink->sample_aspect_ratio.den || - srclink->w != ylink->w || - srclink->h != ylink->h || - srclink->sample_aspect_ratio.num != ylink->sample_aspect_ratio.num || - srclink->sample_aspect_ratio.den != ylink->sample_aspect_ratio.den) { + if (srclink->w != xlink->w || + srclink->h != xlink->h || + srclink->w != ylink->w || + srclink->h != ylink->h) { av_log(ctx, AV_LOG_ERROR, "First input link %s parameters " - "(size %dx%d, SAR %d:%d) do not match the corresponding " - "second input link %s parameters (%dx%d, SAR %d:%d) " - "and/or third input link %s parameters (%dx%d, SAR %d:%d)\n", + "(size %dx%d) do not match the corresponding " + "second input link %s parameters (%dx%d) " + "and/or third input link %s parameters (%dx%d)\n", ctx->input_pads[0].name, srclink->w, srclink->h, - srclink->sample_aspect_ratio.num, - srclink->sample_aspect_ratio.den, ctx->input_pads[1].name, xlink->w, xlink->h, - xlink->sample_aspect_ratio.num, - xlink->sample_aspect_ratio.den, - ctx->input_pads[2].name, ylink->w, ylink->h, - ylink->sample_aspect_ratio.num, - ylink->sample_aspect_ratio.den); + ctx->input_pads[2].name, ylink->w, ylink->h); return AVERROR(EINVAL); } From e6e58de03d6048f8cb7233881465ec6288c7cf7f Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 3 Sep 2017 14:15:33 +0200 Subject: [PATCH 2966/3374] avfilter/vf_displace: add mirror edge mode Signed-off-by: Paul B Mahol --- doc/filters.texi | 3 +++ libavfilter/vf_displace.c | 42 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 19ca055076a95..abc3a0cae80d7 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -6890,6 +6890,9 @@ Adjacent pixels will spread out to replace missing pixels. @item wrap Out of range pixels are wrapped so they point to pixels of other side. + +@item mirror +Out of range pixels will be replaced with mirrored pixels. @end table Default is @samp{smear}. diff --git a/libavfilter/vf_displace.c b/libavfilter/vf_displace.c index a894021bff7ae..9f16ad441fa65 100644 --- a/libavfilter/vf_displace.c +++ b/libavfilter/vf_displace.c @@ -31,6 +31,7 @@ enum EdgeMode { EDGE_BLANK, EDGE_SMEAR, EDGE_WRAP, + EDGE_MIRROR, EDGE_NB }; @@ -53,9 +54,10 @@ typedef struct DisplaceContext { static const AVOption displace_options[] = { { "edge", "set edge mode", OFFSET(edge), AV_OPT_TYPE_INT, {.i64=EDGE_SMEAR}, 0, EDGE_NB-1, FLAGS, "edge" }, - { "blank", "", 0, AV_OPT_TYPE_CONST, {.i64=EDGE_BLANK}, 0, 0, FLAGS, "edge" }, - { "smear", "", 0, AV_OPT_TYPE_CONST, {.i64=EDGE_SMEAR}, 0, 0, FLAGS, "edge" }, - { "wrap" , "", 0, AV_OPT_TYPE_CONST, {.i64=EDGE_WRAP}, 0, 0, FLAGS, "edge" }, + { "blank", "", 0, AV_OPT_TYPE_CONST, {.i64=EDGE_BLANK}, 0, 0, FLAGS, "edge" }, + { "smear", "", 0, AV_OPT_TYPE_CONST, {.i64=EDGE_SMEAR}, 0, 0, FLAGS, "edge" }, + { "wrap" , "", 0, AV_OPT_TYPE_CONST, {.i64=EDGE_WRAP}, 0, 0, FLAGS, "edge" }, + { "mirror" , "", 0, AV_OPT_TYPE_CONST, {.i64=EDGE_MIRROR}, 0, 0, FLAGS, "edge" }, { NULL } }; @@ -130,6 +132,22 @@ static void displace_planar(DisplaceContext *s, const AVFrame *in, dst[x] = src[Y * slinesize + X]; } break; + case EDGE_MIRROR: + for (x = 0; x < w; x++) { + int Y = y + ysrc[x] - 128; + int X = x + xsrc[x] - 128; + + if (Y < 0) + Y = (-Y) % h; + if (X < 0) + X = (-X) % w; + if (Y >= h) + Y = h - (Y % h) - 1; + if (X >= w) + X = w - (X % w) - 1; + dst[x] = src[Y * slinesize + X]; + } + break; } ysrc += ylinesize; @@ -196,6 +214,24 @@ static void displace_packed(DisplaceContext *s, const AVFrame *in, } } break; + case EDGE_MIRROR: + for (x = 0; x < w; x++) { + for (c = 0; c < s->nb_components; c++) { + int Y = y + ysrc[x * step + c] - 128; + int X = x + xsrc[x * step + c] - 128; + + if (Y < 0) + Y = (-Y) % h; + if (X < 0) + X = (-X) % w; + if (Y >= h) + Y = h - (Y % h) - 1; + if (X >= w) + X = w - (X % w) - 1; + dst[x * step + c] = src[Y * slinesize + X * step + c]; + } + } + break; } ysrc += ylinesize; From 05b1c606870cc4646da8197a86e9af5301654499 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 3 Sep 2017 20:00:08 +0200 Subject: [PATCH 2967/3374] doc/filters: add one more blend example Signed-off-by: Paul B Mahol --- doc/filters.texi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/filters.texi b/doc/filters.texi index abc3a0cae80d7..710294860e1bf 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -4994,6 +4994,12 @@ Apply transition from bottom layer to top layer in first 10 seconds: blend=all_expr='A*(if(gte(T,10),1,T/10))+B*(1-(if(gte(T,10),1,T/10)))' @end example +@item +Apply linear horizontal transition from top layer to bottom layer: +@example +blend=all_expr='A*(X/W)+B*(1-X/W)' +@end example + @item Apply 1x1 checkerboard effect: @example From 8b193e553055f7c89f6a8263ebdc2e6756af7fb1 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 3 Sep 2017 20:00:53 +0200 Subject: [PATCH 2968/3374] doc/filters: add missing '' for blend example Signed-off-by: Paul B Mahol --- doc/filters.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/filters.texi b/doc/filters.texi index 710294860e1bf..649e101876ea7 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -5027,7 +5027,7 @@ blend=all_expr='if(gte(T*SH*40+Y,H)*gte((T*40*SW+X)*W/H,W),A,B)' @item Split diagonally video and shows top and bottom layer on each side: @example -blend=all_expr=if(gt(X,Y*(W/H)),A,B) +blend=all_expr='if(gt(X,Y*(W/H)),A,B)' @end example @item From f3c0f34f53c26b800aae0d4e63608b065d73f4ec Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 3 Sep 2017 20:42:04 +0200 Subject: [PATCH 2969/3374] avfilter/vf_datascope: add timeline support to pixscope and oscilloscope Signed-off-by: Paul B Mahol --- libavfilter/vf_datascope.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavfilter/vf_datascope.c b/libavfilter/vf_datascope.c index 7a1dc4de01e5f..a0482cdb7552d 100644 --- a/libavfilter/vf_datascope.c +++ b/libavfilter/vf_datascope.c @@ -646,6 +646,7 @@ AVFilter ff_vf_pixscope = { .query_formats = query_formats, .inputs = pixscope_inputs, .outputs = pixscope_outputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, }; typedef struct PixelValues { @@ -1027,4 +1028,5 @@ AVFilter ff_vf_oscilloscope = { .uninit = oscilloscope_uninit, .inputs = oscilloscope_inputs, .outputs = oscilloscope_outputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, }; From 4d2b9ece45e576474a2f03eb47f5cc088eec3f0c Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Tue, 29 Aug 2017 10:47:26 -0700 Subject: [PATCH 2970/3374] avformat/flvdec: Set need_context_update when setting the initial extradata Fixes ticket 6398. Debugged with the help of James Almer and Hendrik Leppkes. --- libavformat/flvdec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 94c9e28334382..2e70352c5374c 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -754,6 +754,7 @@ static int flv_get_extradata(AVFormatContext *s, AVStream *st, int size) av_freep(&st->codecpar->extradata); if (ff_get_extradata(s, st->codecpar, s->pb, size) < 0) return AVERROR(ENOMEM); + st->internal->need_context_update = 1; return 0; } From 833a38dbe5b3faa07cfdded65f1c2ddecafad11c Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Mon, 4 Sep 2017 14:20:29 +0200 Subject: [PATCH 2971/3374] avfilter/vf_datascope: make it possible for output window to automatically change position Signed-off-by: Paul B Mahol --- libavfilter/vf_datascope.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/libavfilter/vf_datascope.c b/libavfilter/vf_datascope.c index a0482cdb7552d..467663556e04b 100644 --- a/libavfilter/vf_datascope.c +++ b/libavfilter/vf_datascope.c @@ -455,8 +455,8 @@ static const AVOption pixscope_options[] = { { "w", "set scope width", POFFSET(w), AV_OPT_TYPE_INT, {.i64=7}, 1, 80, FLAGS }, { "h", "set scope height", POFFSET(h), AV_OPT_TYPE_INT, {.i64=7}, 1, 80, FLAGS }, { "o", "set window opacity", POFFSET(o), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS }, - { "wx", "set window x offset", POFFSET(wx), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, FLAGS }, - { "wy", "set window y offset", POFFSET(wy), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, FLAGS }, + { "wx", "set window x offset", POFFSET(wx), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 1, FLAGS }, + { "wy", "set window y offset", POFFSET(wy), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 1, FLAGS }, { NULL } }; @@ -542,8 +542,30 @@ static int pixscope_filter_frame(AVFilterLink *inlink, AVFrame *in) w = s->ww / s->w; h = s->ww / s->h; - X = (in->width - s->ww) * s->wx; - Y = (in->height - s->wh) * s->wy; + if (s->wx >= 0) { + X = (in->width - s->ww) * s->wx; + } else { + X = (in->width - s->ww) * -s->wx; + } + if (s->wy >= 0) { + Y = (in->height - s->wh) * s->wy; + } else { + Y = (in->height - s->wh) * -s->wy; + } + + if (s->wx < 0) { + if (s->x + s->w >= X && (s->x + s->w <= X + s->ww) && + s->y + s->h >= Y && (s->y + s->h <= Y + s->wh)) { + X = (in->width - s->ww) * (1 + s->wx); + } + } + + if (s->wy < 0) { + if (s->x + s->w >= X && (s->x + s->w <= X + s->ww) && + s->y + s->h >= Y && (s->y + s->h <= Y + s->wh)) { + Y = (in->height - s->wh) * (1 + s->wy); + } + } ff_blend_rectangle(&s->draw, &s->dark, out->data, out->linesize, out->width, out->height, From ca7dc3ee901f27fac44cc2a541151fa551c0d1b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Mon, 4 Sep 2017 15:45:11 +0200 Subject: [PATCH 2972/3374] lavd: drop QTKit indev QTKit has been deprecated in favor of AVFoundation for years, and we have an avfoundation input device. See https://developer.apple.com/documentation/qtkit --- Changelog | 1 + MAINTAINERS | 1 - configure | 3 - doc/indevs.texi | 44 ----- libavdevice/Makefile | 1 - libavdevice/alldevices.c | 1 - libavdevice/qtkit.m | 362 --------------------------------------- 7 files changed, 1 insertion(+), 412 deletions(-) delete mode 100644 libavdevice/qtkit.m diff --git a/Changelog b/Changelog index ccbcdf6328f85..cbeb248655a9f 100644 --- a/Changelog +++ b/Changelog @@ -41,6 +41,7 @@ version : - FITS demuxer and decoder - FITS muxer and encoder - add --disable-autodetect build switch +- drop deprecated qtkit input device (use avfoundation instead) version 3.3: - CrystalHD decoder moved to new decode API diff --git a/MAINTAINERS b/MAINTAINERS index ce5e1dae084a6..8a6ac9840f7b1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -291,7 +291,6 @@ libavdevice libdc1394.c Roman Shaposhnik opengl_enc.c Lukasz Marek pulse_audio_enc.c Lukasz Marek - qtkit.m Thilo Borgmann sdl Stefano Sabatini sdl2.c Josh de Kock v4l2.c Giorgio Vazzana diff --git a/configure b/configure index d58270550ca61..f7558f699879a 100755 --- a/configure +++ b/configure @@ -3043,8 +3043,6 @@ oss_indev_deps_any="soundcard_h sys_soundcard_h" oss_outdev_deps_any="soundcard_h sys_soundcard_h" pulse_indev_deps="libpulse" pulse_outdev_deps="libpulse" -qtkit_indev_extralibs="-framework QTKit -framework Foundation -framework QuartzCore" -qtkit_indev_select="qtkit" sdl2_outdev_deps="sdl2" sndio_indev_deps="sndio" sndio_outdev_deps="sndio" @@ -6010,7 +6008,6 @@ enabled openssl && { use_pkg_config openssl openssl/ssl.h OPENSSL_init check_lib openssl openssl/ssl.h SSL_library_init -lssl32 -leay32 || check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 || die "ERROR: openssl not found"; } -enabled qtkit_indev && { check_header_objcc QTKit/QTKit.h || disable qtkit_indev; } if enabled gcrypt; then GCRYPT_CONFIG="${cross_prefix}libgcrypt-config" diff --git a/doc/indevs.texi b/doc/indevs.texi index 5423bed32f283..ad6418751bc9d 100644 --- a/doc/indevs.texi +++ b/doc/indevs.texi @@ -68,7 +68,6 @@ Set the number of channels. Default is 2. AVFoundation input device. AVFoundation is the currently recommended framework by Apple for streamgrabbing on OSX >= 10.7 as well as on iOS. -The older QTKit framework has been marked deprecated since OSX version 10.7. The input filename has to be given in the following syntax: @example @@ -1141,49 +1140,6 @@ Record a stream from default device: ffmpeg -f pulse -i default /tmp/pulse.wav @end example -@section qtkit - -QTKit input device. - -The filename passed as input is parsed to contain either a device name or index. -The device index can also be given by using -video_device_index. -A given device index will override any given device name. -If the desired device consists of numbers only, use -video_device_index to identify it. -The default device will be chosen if an empty string or the device name "default" is given. -The available devices can be enumerated by using -list_devices. - -@example -ffmpeg -f qtkit -i "0" out.mpg -@end example - -@example -ffmpeg -f qtkit -video_device_index 0 -i "" out.mpg -@end example - -@example -ffmpeg -f qtkit -i "default" out.mpg -@end example - -@example -ffmpeg -f qtkit -list_devices true -i "" -@end example - -@subsection Options - -@table @option - -@item frame_rate -Set frame rate. Default is 30. - -@item list_devices -If set to @code{true}, print a list of devices and exit. Default is -@code{false}. - -@item video_device_index -Select the video device by index for devices with the same name (starts at 0). - -@end table - @section sndio sndio input device. diff --git a/libavdevice/Makefile b/libavdevice/Makefile index 0efb3f905f6b1..2a27d2038832d 100644 --- a/libavdevice/Makefile +++ b/libavdevice/Makefile @@ -41,7 +41,6 @@ OBJS-$(CONFIG_PULSE_INDEV) += pulse_audio_dec.o \ pulse_audio_common.o timefilter.o OBJS-$(CONFIG_PULSE_OUTDEV) += pulse_audio_enc.o \ pulse_audio_common.o -OBJS-$(CONFIG_QTKIT_INDEV) += qtkit.o OBJS-$(CONFIG_SDL2_OUTDEV) += sdl2.o OBJS-$(CONFIG_SNDIO_INDEV) += sndio_dec.o sndio.o OBJS-$(CONFIG_SNDIO_OUTDEV) += sndio_enc.o sndio.o diff --git a/libavdevice/alldevices.c b/libavdevice/alldevices.c index 4bf08d798db8e..38010e288afa1 100644 --- a/libavdevice/alldevices.c +++ b/libavdevice/alldevices.c @@ -58,7 +58,6 @@ static void register_all(void) REGISTER_OUTDEV (OPENGL, opengl); REGISTER_INOUTDEV(OSS, oss); REGISTER_INOUTDEV(PULSE, pulse); - REGISTER_INDEV (QTKIT, qtkit); REGISTER_OUTDEV (SDL2, sdl2); REGISTER_INOUTDEV(SNDIO, sndio); REGISTER_INOUTDEV(V4L2, v4l2); diff --git a/libavdevice/qtkit.m b/libavdevice/qtkit.m deleted file mode 100644 index 22a94ca561cdf..0000000000000 --- a/libavdevice/qtkit.m +++ /dev/null @@ -1,362 +0,0 @@ -/* - * QTKit input device - * Copyright (c) 2013 Vadim Kalinsky - * - * 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 - */ - -/** - * @file - * QTKit input device - * @author Vadim Kalinsky - */ - -#if defined(__clang__) -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#endif - -#import -#include - -#include "libavutil/pixdesc.h" -#include "libavutil/opt.h" -#include "libavformat/internal.h" -#include "libavutil/internal.h" -#include "libavutil/time.h" -#include "avdevice.h" - -#define QTKIT_TIMEBASE 100 - -static const AVRational kQTKitTimeBase_q = { - .num = 1, - .den = QTKIT_TIMEBASE -}; - -typedef struct -{ - AVClass* class; - - float frame_rate; - int frames_captured; - int64_t first_pts; - pthread_mutex_t frame_lock; - pthread_cond_t frame_wait_cond; - id qt_delegate; - - int list_devices; - int video_device_index; - - QTCaptureSession* capture_session; - QTCaptureDecompressedVideoOutput* video_output; - CVImageBufferRef current_frame; -} CaptureContext; - -static void lock_frames(CaptureContext* ctx) -{ - pthread_mutex_lock(&ctx->frame_lock); -} - -static void unlock_frames(CaptureContext* ctx) -{ - pthread_mutex_unlock(&ctx->frame_lock); -} - -/** FrameReciever class - delegate for QTCaptureSession - */ -@interface FFMPEG_FrameReceiver : NSObject -{ - CaptureContext* _context; -} - -- (id)initWithContext:(CaptureContext*)context; - -- (void)captureOutput:(QTCaptureOutput *)captureOutput - didOutputVideoFrame:(CVImageBufferRef)videoFrame - withSampleBuffer:(QTSampleBuffer *)sampleBuffer - fromConnection:(QTCaptureConnection *)connection; - -@end - -@implementation FFMPEG_FrameReceiver - -- (id)initWithContext:(CaptureContext*)context -{ - if (self = [super init]) { - _context = context; - } - return self; -} - -- (void)captureOutput:(QTCaptureOutput *)captureOutput - didOutputVideoFrame:(CVImageBufferRef)videoFrame - withSampleBuffer:(QTSampleBuffer *)sampleBuffer - fromConnection:(QTCaptureConnection *)connection -{ - lock_frames(_context); - if (_context->current_frame != nil) { - CVBufferRelease(_context->current_frame); - } - - _context->current_frame = CVBufferRetain(videoFrame); - - pthread_cond_signal(&_context->frame_wait_cond); - - unlock_frames(_context); - - ++_context->frames_captured; -} - -@end - -static void destroy_context(CaptureContext* ctx) -{ - [ctx->capture_session stopRunning]; - - [ctx->capture_session release]; - [ctx->video_output release]; - [ctx->qt_delegate release]; - - ctx->capture_session = NULL; - ctx->video_output = NULL; - ctx->qt_delegate = NULL; - - pthread_mutex_destroy(&ctx->frame_lock); - pthread_cond_destroy(&ctx->frame_wait_cond); - - if (ctx->current_frame) - CVBufferRelease(ctx->current_frame); -} - -static int qtkit_read_header(AVFormatContext *s) -{ - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - - CaptureContext* ctx = (CaptureContext*)s->priv_data; - - ctx->first_pts = av_gettime(); - - pthread_mutex_init(&ctx->frame_lock, NULL); - pthread_cond_init(&ctx->frame_wait_cond, NULL); - - // List devices if requested - if (ctx->list_devices) { - av_log(ctx, AV_LOG_INFO, "QTKit video devices:\n"); - NSArray *devices = [QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo]; - for (QTCaptureDevice *device in devices) { - const char *name = [[device localizedDisplayName] UTF8String]; - int index = [devices indexOfObject:device]; - av_log(ctx, AV_LOG_INFO, "[%d] %s\n", index, name); - } - goto fail; - } - - // Find capture device - QTCaptureDevice *video_device = nil; - - // check for device index given in filename - if (ctx->video_device_index == -1) { - sscanf(s->filename, "%d", &ctx->video_device_index); - } - - if (ctx->video_device_index >= 0) { - NSArray *devices = [QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo]; - - if (ctx->video_device_index >= [devices count]) { - av_log(ctx, AV_LOG_ERROR, "Invalid device index\n"); - goto fail; - } - - video_device = [devices objectAtIndex:ctx->video_device_index]; - } else if (strncmp(s->filename, "", 1) && - strncmp(s->filename, "default", 7)) { - NSArray *devices = [QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo]; - - for (QTCaptureDevice *device in devices) { - if (!strncmp(s->filename, [[device localizedDisplayName] UTF8String], strlen(s->filename))) { - video_device = device; - break; - } - } - if (!video_device) { - av_log(ctx, AV_LOG_ERROR, "Video device not found\n"); - goto fail; - } - } else { - video_device = [QTCaptureDevice defaultInputDeviceWithMediaType:QTMediaTypeMuxed]; - } - - BOOL success = [video_device open:nil]; - - // Video capture device not found, looking for QTMediaTypeVideo - if (!success) { - video_device = [QTCaptureDevice defaultInputDeviceWithMediaType:QTMediaTypeVideo]; - success = [video_device open:nil]; - - if (!success) { - av_log(s, AV_LOG_ERROR, "No QT capture device found\n"); - goto fail; - } - } - - NSString* dev_display_name = [video_device localizedDisplayName]; - av_log (s, AV_LOG_DEBUG, "'%s' opened\n", [dev_display_name UTF8String]); - - // Initialize capture session - ctx->capture_session = [[QTCaptureSession alloc] init]; - - QTCaptureDeviceInput* capture_dev_input = [[[QTCaptureDeviceInput alloc] initWithDevice:video_device] autorelease]; - success = [ctx->capture_session addInput:capture_dev_input error:nil]; - - if (!success) { - av_log (s, AV_LOG_ERROR, "Failed to add QT capture device to session\n"); - goto fail; - } - - // Attaching output - // FIXME: Allow for a user defined pixel format - ctx->video_output = [[QTCaptureDecompressedVideoOutput alloc] init]; - - NSDictionary *captureDictionary = [NSDictionary dictionaryWithObject: - [NSNumber numberWithUnsignedInt:kCVPixelFormatType_24RGB] - forKey:(id)kCVPixelBufferPixelFormatTypeKey]; - - [ctx->video_output setPixelBufferAttributes:captureDictionary]; - - ctx->qt_delegate = [[FFMPEG_FrameReceiver alloc] initWithContext:ctx]; - - [ctx->video_output setDelegate:ctx->qt_delegate]; - [ctx->video_output setAutomaticallyDropsLateVideoFrames:YES]; - [ctx->video_output setMinimumVideoFrameInterval:1.0/ctx->frame_rate]; - - success = [ctx->capture_session addOutput:ctx->video_output error:nil]; - - if (!success) { - av_log (s, AV_LOG_ERROR, "can't add video output to capture session\n"); - goto fail; - } - - [ctx->capture_session startRunning]; - - // Take stream info from the first frame. - while (ctx->frames_captured < 1) { - CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, YES); - } - - lock_frames(ctx); - - AVStream* stream = avformat_new_stream(s, NULL); - - if (!stream) { - goto fail; - } - - avpriv_set_pts_info(stream, 64, 1, QTKIT_TIMEBASE); - - stream->codec->codec_id = AV_CODEC_ID_RAWVIDEO; - stream->codec->codec_type = AVMEDIA_TYPE_VIDEO; - stream->codec->width = (int)CVPixelBufferGetWidth (ctx->current_frame); - stream->codec->height = (int)CVPixelBufferGetHeight(ctx->current_frame); - stream->codec->pix_fmt = AV_PIX_FMT_RGB24; - - CVBufferRelease(ctx->current_frame); - ctx->current_frame = nil; - - unlock_frames(ctx); - - [pool release]; - - return 0; - -fail: - [pool release]; - - destroy_context(ctx); - - return AVERROR(EIO); -} - -static int qtkit_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - CaptureContext* ctx = (CaptureContext*)s->priv_data; - - do { - lock_frames(ctx); - - if (ctx->current_frame != nil) { - if (av_new_packet(pkt, (int)CVPixelBufferGetDataSize(ctx->current_frame)) < 0) { - return AVERROR(EIO); - } - - pkt->pts = pkt->dts = av_rescale_q(av_gettime() - ctx->first_pts, AV_TIME_BASE_Q, kQTKitTimeBase_q); - pkt->stream_index = 0; - pkt->flags |= AV_PKT_FLAG_KEY; - - CVPixelBufferLockBaseAddress(ctx->current_frame, 0); - - void* data = CVPixelBufferGetBaseAddress(ctx->current_frame); - memcpy(pkt->data, data, pkt->size); - - CVPixelBufferUnlockBaseAddress(ctx->current_frame, 0); - CVBufferRelease(ctx->current_frame); - ctx->current_frame = nil; - } else { - pkt->data = NULL; - pthread_cond_wait(&ctx->frame_wait_cond, &ctx->frame_lock); - } - - unlock_frames(ctx); - } while (!pkt->data); - - return 0; -} - -static int qtkit_close(AVFormatContext *s) -{ - CaptureContext* ctx = (CaptureContext*)s->priv_data; - - destroy_context(ctx); - - return 0; -} - -static const AVOption options[] = { - { "frame_rate", "set frame rate", offsetof(CaptureContext, frame_rate), AV_OPT_TYPE_FLOAT, { .dbl = 30.0 }, 0.1, 30.0, AV_OPT_TYPE_VIDEO_RATE, NULL }, - { "list_devices", "list available devices", offsetof(CaptureContext, list_devices), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM, "list_devices" }, - { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "list_devices" }, - { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "list_devices" }, - { "video_device_index", "select video device by index for devices with same name (starts at 0)", offsetof(CaptureContext, video_device_index), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, - { NULL }, -}; - -static const AVClass qtkit_class = { - .class_name = "QTKit input device", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, - .category = AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT, -}; - -AVInputFormat ff_qtkit_demuxer = { - .name = "qtkit", - .long_name = NULL_IF_CONFIG_SMALL("QTKit input device"), - .priv_data_size = sizeof(CaptureContext), - .read_header = qtkit_read_header, - .read_packet = qtkit_read_packet, - .read_close = qtkit_close, - .flags = AVFMT_NOFILE, - .priv_class = &qtkit_class, -}; From 2726b2d7e8dcbd6e66ebb48224b3d85773c8064a Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Mon, 4 Sep 2017 18:24:00 +0200 Subject: [PATCH 2973/3374] avfilter/vf_fftfilt: cache rdft contexts Signed-off-by: Paul B Mahol --- libavfilter/vf_fftfilt.c | 41 +++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/libavfilter/vf_fftfilt.c b/libavfilter/vf_fftfilt.c index 8a47ed5be45d0..38dd50d6ae3a3 100644 --- a/libavfilter/vf_fftfilt.c +++ b/libavfilter/vf_fftfilt.c @@ -36,7 +36,10 @@ typedef struct FFTFILTContext { const AVClass *class; - RDFTContext *rdft; + RDFTContext *hrdft[MAX_PLANES]; + RDFTContext *vrdft[MAX_PLANES]; + RDFTContext *ihrdft[MAX_PLANES]; + RDFTContext *ivrdft[MAX_PLANES]; int rdft_hbits[MAX_PLANES]; int rdft_vbits[MAX_PLANES]; size_t rdft_hlen[MAX_PLANES]; @@ -96,7 +99,6 @@ static void copy_rev (FFTSample *dest, int w, int w2) static void rdft_horizontal(FFTFILTContext *s, AVFrame *in, int w, int h, int plane) { int i, j; - s->rdft = av_rdft_init(s->rdft_hbits[plane], DFT_R2C); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) @@ -106,16 +108,13 @@ static void rdft_horizontal(FFTFILTContext *s, AVFrame *in, int w, int h, int pl } for (i = 0; i < h; i++) - av_rdft_calc(s->rdft, s->rdft_hdata[plane] + i * s->rdft_hlen[plane]); - - av_rdft_end(s->rdft); + av_rdft_calc(s->hrdft[plane], s->rdft_hdata[plane] + i * s->rdft_hlen[plane]); } /*Vertical pass - RDFT*/ static void rdft_vertical(FFTFILTContext *s, int h, int plane) { int i, j; - s->rdft = av_rdft_init(s->rdft_vbits[plane], DFT_R2C); for (i = 0; i < s->rdft_hlen[plane]; i++) { for (j = 0; j < h; j++) @@ -125,33 +124,29 @@ static void rdft_vertical(FFTFILTContext *s, int h, int plane) } for (i = 0; i < s->rdft_hlen[plane]; i++) - av_rdft_calc(s->rdft, s->rdft_vdata[plane] + i * s->rdft_vlen[plane]); - - av_rdft_end(s->rdft); + av_rdft_calc(s->vrdft[plane], s->rdft_vdata[plane] + i * s->rdft_vlen[plane]); } /*Vertical pass - IRDFT*/ static void irdft_vertical(FFTFILTContext *s, int h, int plane) { int i, j; - s->rdft = av_rdft_init(s->rdft_vbits[plane], IDFT_C2R); + for (i = 0; i < s->rdft_hlen[plane]; i++) - av_rdft_calc(s->rdft, s->rdft_vdata[plane] + i * s->rdft_vlen[plane]); + av_rdft_calc(s->ivrdft[plane], s->rdft_vdata[plane] + i * s->rdft_vlen[plane]); for (i = 0; i < s->rdft_hlen[plane]; i++) for (j = 0; j < h; j++) s->rdft_hdata[plane][j * s->rdft_hlen[plane] + i] = s->rdft_vdata[plane][i * s->rdft_vlen[plane] + j]; - - av_rdft_end(s->rdft); } /*Horizontal pass - IRDFT*/ static void irdft_horizontal(FFTFILTContext *s, AVFrame *out, int w, int h, int plane) { int i, j; - s->rdft = av_rdft_init(s->rdft_hbits[plane], IDFT_C2R); + for (i = 0; i < h; i++) - av_rdft_calc(s->rdft, s->rdft_hdata[plane] + i * s->rdft_hlen[plane]); + av_rdft_calc(s->ihrdft[plane], s->rdft_hdata[plane] + i * s->rdft_hlen[plane]); for (i = 0; i < h; i++) for (j = 0; j < w; j++) @@ -159,8 +154,6 @@ static void irdft_horizontal(FFTFILTContext *s, AVFrame *out, int w, int h, int *s->rdft_hlen[plane] + j] * 4 / (s->rdft_hlen[plane] * s->rdft_vlen[plane]), 0, 255); - - av_rdft_end(s->rdft); } static av_cold int initialize(AVFilterContext *ctx) @@ -216,12 +209,22 @@ static int config_props(AVFilterLink *inlink) if (!(s->rdft_hdata[i] = av_malloc_array(h, s->rdft_hlen[i] * sizeof(FFTSample)))) return AVERROR(ENOMEM); + if (!(s->hrdft[i] = av_rdft_init(s->rdft_hbits[i], DFT_R2C))) + return AVERROR(ENOMEM); + if (!(s->ihrdft[i] = av_rdft_init(s->rdft_hbits[i], IDFT_C2R))) + return AVERROR(ENOMEM); + /* RDFT - Array initialization for Vertical pass*/ for (rdft_vbits = 1; 1 << rdft_vbits < h*10/9; rdft_vbits++); s->rdft_vbits[i] = rdft_vbits; s->rdft_vlen[i] = 1 << rdft_vbits; if (!(s->rdft_vdata[i] = av_malloc_array(s->rdft_hlen[i], s->rdft_vlen[i] * sizeof(FFTSample)))) return AVERROR(ENOMEM); + + if (!(s->vrdft[i] = av_rdft_init(s->rdft_vbits[i], DFT_R2C))) + return AVERROR(ENOMEM); + if (!(s->ivrdft[i] = av_rdft_init(s->rdft_vbits[i], IDFT_C2R))) + return AVERROR(ENOMEM); } /*Luminance value - Array initialization*/ @@ -300,6 +303,10 @@ static av_cold void uninit(AVFilterContext *ctx) av_free(s->rdft_vdata[i]); av_expr_free(s->weight_expr[i]); av_free(s->weight[i]); + av_rdft_end(s->hrdft[i]); + av_rdft_end(s->ihrdft[i]); + av_rdft_end(s->vrdft[i]); + av_rdft_end(s->ivrdft[i]); } } From 2170ca41f423b8a38b69e7ad2571546baa4749d5 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Mon, 4 Sep 2017 18:36:37 +0200 Subject: [PATCH 2974/3374] avfilter/vf_fftfilt: add support for more pixel formats Signed-off-by: Paul B Mahol --- libavfilter/vf_fftfilt.c | 42 ++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/libavfilter/vf_fftfilt.c b/libavfilter/vf_fftfilt.c index 38dd50d6ae3a3..aa282edc8692e 100644 --- a/libavfilter/vf_fftfilt.c +++ b/libavfilter/vf_fftfilt.c @@ -36,6 +36,11 @@ typedef struct FFTFILTContext { const AVClass *class; + int depth; + int nb_planes; + int planewidth[MAX_PLANES]; + int planeheight[MAX_PLANES]; + RDFTContext *hrdft[MAX_PLANES]; RDFTContext *vrdft[MAX_PLANES]; RDFTContext *ihrdft[MAX_PLANES]; @@ -198,9 +203,17 @@ static int config_props(AVFilterLink *inlink) double values[VAR_VARS_NB]; desc = av_pix_fmt_desc_get(inlink->format); + s->depth = desc->comp[0].depth; + s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w); + s->planewidth[0] = s->planewidth[3] = inlink->w; + s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h); + s->planeheight[0] = s->planeheight[3] = inlink->h; + + s->nb_planes = av_pix_fmt_count_planes(inlink->format); + for (i = 0; i < desc->nb_components; i++) { - int w = inlink->w; - int h = inlink->h; + int w = s->planewidth[i]; + int h = s->planeheight[i]; /* RDFT - Array initialization for Horizontal pass*/ for (rdft_hbits = 1; 1 << rdft_hbits < w*10/9; rdft_hbits++); @@ -228,10 +241,10 @@ static int config_props(AVFilterLink *inlink) } /*Luminance value - Array initialization*/ - values[VAR_W] = inlink->w; - values[VAR_H] = inlink->h; - for (plane = 0; plane < 3; plane++) - { + for (plane = 0; plane < 3; plane++) { + values[VAR_W] = s->planewidth[plane]; + values[VAR_H] = s->planeheight[plane]; + if(!(s->weight[plane] = av_malloc_array(s->rdft_hlen[plane], s->rdft_vlen[plane] * sizeof(double)))) return AVERROR(ENOMEM); for (i = 0; i < s->rdft_hlen[plane]; i++) @@ -252,7 +265,6 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *ctx = inlink->dst; AVFilterLink *outlink = inlink->dst->outputs[0]; - const AVPixFmtDescriptor *desc; FFTFILTContext *s = ctx->priv; AVFrame *out; int i, j, plane; @@ -265,15 +277,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) av_frame_copy_props(out, in); - desc = av_pix_fmt_desc_get(inlink->format); - for (plane = 0; plane < desc->nb_components; plane++) { - int w = inlink->w; - int h = inlink->h; - - if (plane == 1 || plane == 2) { - w = AV_CEIL_RSHIFT(w, desc->log2_chroma_w); - h = AV_CEIL_RSHIFT(h, desc->log2_chroma_h); - } + for (plane = 0; plane < s->nb_planes; plane++) { + int w = s->planewidth[plane]; + int h = s->planeheight[plane]; rdft_horizontal(s, in, w, h, plane); rdft_vertical(s, h, plane); @@ -314,7 +320,9 @@ static int query_formats(AVFilterContext *ctx) { static const enum AVPixelFormat pixel_fmts_fftfilt[] = { AV_PIX_FMT_GRAY8, - AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P, + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVJ420P, + AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_NONE }; From 4705a80fb0246f6e6cc3594869dc7a54c1bbd950 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Mon, 4 Sep 2017 19:04:31 +0200 Subject: [PATCH 2975/3374] avfilter/vf_fftfilt: add generic timeline support Signed-off-by: Paul B Mahol --- libavfilter/vf_fftfilt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavfilter/vf_fftfilt.c b/libavfilter/vf_fftfilt.c index aa282edc8692e..4437409185a34 100644 --- a/libavfilter/vf_fftfilt.c +++ b/libavfilter/vf_fftfilt.c @@ -360,4 +360,5 @@ AVFilter ff_vf_fftfilt = { .query_formats = query_formats, .init = initialize, .uninit = uninit, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, }; From b43cd67862467dfb8671663c1064b8d4105c4cec Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Mon, 4 Sep 2017 19:29:37 +0200 Subject: [PATCH 2976/3374] avfilter/vf_fftfilt: make it possible to evaluate expressions per frame Signed-off-by: Paul B Mahol --- doc/filters.texi | 17 +++++++++++++ libavfilter/vf_fftfilt.c | 55 +++++++++++++++++++++++++++------------- 2 files changed, 55 insertions(+), 17 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 649e101876ea7..ce3f75dbd6501 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -7926,6 +7926,20 @@ Set the frequency domain weight expression for the 1st chroma plane. @item weight_V Set the frequency domain weight expression for the 2nd chroma plane. +@item eval +Set when the expressions are evaluated. + +It accepts the following values: +@table @samp +@item init +Only evaluate expressions once during the filter initialization. + +@item frame +Evaluate expressions for each incoming frame. +@end table + +Default value is @samp{init}. + The filter accepts the following variables: @item X @item Y @@ -7934,6 +7948,9 @@ The coordinates of the current sample. @item W @item H The width and height of the image. + +@item N +The number of input frame, starting from 0. @end table @subsection Examples diff --git a/libavfilter/vf_fftfilt.c b/libavfilter/vf_fftfilt.c index 4437409185a34..7f60ca1f87b7e 100644 --- a/libavfilter/vf_fftfilt.c +++ b/libavfilter/vf_fftfilt.c @@ -33,9 +33,16 @@ #define MAX_PLANES 4 +enum EvalMode { + EVAL_MODE_INIT, + EVAL_MODE_FRAME, + EVAL_MODE_NB +}; + typedef struct FFTFILTContext { const AVClass *class; + int eval_mode; int depth; int nb_planes; int planewidth[MAX_PLANES]; @@ -59,8 +66,8 @@ typedef struct FFTFILTContext { } FFTFILTContext; -static const char *const var_names[] = { "X", "Y", "W", "H", NULL }; -enum { VAR_X, VAR_Y, VAR_W, VAR_H, VAR_VARS_NB }; +static const char *const var_names[] = { "X", "Y", "W", "H", "N", NULL }; +enum { VAR_X, VAR_Y, VAR_W, VAR_H, VAR_N, VAR_VARS_NB }; enum { Y = 0, U, V }; @@ -74,6 +81,9 @@ static const AVOption fftfilt_options[] = { { "weight_Y", "set luminance expression in Y plane", OFFSET(weight_str[Y]), AV_OPT_TYPE_STRING, {.str = "1"}, CHAR_MIN, CHAR_MAX, FLAGS }, { "weight_U", "set chrominance expression in U plane", OFFSET(weight_str[U]), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, { "weight_V", "set chrominance expression in V plane", OFFSET(weight_str[V]), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, + { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_INIT}, 0, EVAL_MODE_NB-1, FLAGS, "eval" }, + { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" }, + { "frame", "eval expressions per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" }, {NULL}, }; @@ -195,12 +205,30 @@ static av_cold int initialize(AVFilterContext *ctx) return ret; } +static void do_eval(FFTFILTContext *s, AVFilterLink *inlink, int plane) +{ + double values[VAR_VARS_NB]; + int i, j; + + values[VAR_N] = inlink->frame_count_out; + values[VAR_W] = s->planewidth[plane]; + values[VAR_H] = s->planeheight[plane]; + + for (i = 0; i < s->rdft_hlen[plane]; i++) { + values[VAR_X] = i; + for (j = 0; j < s->rdft_vlen[plane]; j++) { + values[VAR_Y] = j; + s->weight[plane][i * s->rdft_vlen[plane] + j] = + av_expr_eval(s->weight_expr[plane], values, s); + } + } +} + static int config_props(AVFilterLink *inlink) { FFTFILTContext *s = inlink->dst->priv; const AVPixFmtDescriptor *desc; - int rdft_hbits, rdft_vbits, i, j, plane; - double values[VAR_VARS_NB]; + int rdft_hbits, rdft_vbits, i, plane; desc = av_pix_fmt_desc_get(inlink->format); s->depth = desc->comp[0].depth; @@ -242,21 +270,11 @@ static int config_props(AVFilterLink *inlink) /*Luminance value - Array initialization*/ for (plane = 0; plane < 3; plane++) { - values[VAR_W] = s->planewidth[plane]; - values[VAR_H] = s->planeheight[plane]; - if(!(s->weight[plane] = av_malloc_array(s->rdft_hlen[plane], s->rdft_vlen[plane] * sizeof(double)))) return AVERROR(ENOMEM); - for (i = 0; i < s->rdft_hlen[plane]; i++) - { - values[VAR_X] = i; - for (j = 0; j < s->rdft_vlen[plane]; j++) - { - values[VAR_Y] = j; - s->weight[plane][i * s->rdft_vlen[plane] + j] = - av_expr_eval(s->weight_expr[plane], values, s); - } - } + + if (s->eval_mode == EVAL_MODE_INIT) + do_eval(s, inlink, plane); } return 0; } @@ -281,6 +299,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) int w = s->planewidth[plane]; int h = s->planeheight[plane]; + if (s->eval_mode == EVAL_MODE_FRAME) + do_eval(s, inlink, plane); + rdft_horizontal(s, in, w, h, plane); rdft_vertical(s, h, plane); From 6cadbb16e97117d9db3e2562370b23c8076b8bd8 Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 1 Sep 2017 14:56:05 -0300 Subject: [PATCH 2977/3374] avcodec: add AV_HWACCEL_CODEC_CAP_EXPERIMENTAL flag This flag replaces the deprecated, non-prefixed HWACCEL_CODEC_CAP_EXPERIMENTAL one. Reviewed-by: Michael Niedermayer Signed-off-by: James Almer --- doc/APIchanges | 4 ++++ libavcodec/avcodec.h | 8 +++++++- libavcodec/decode.c | 2 +- libavcodec/version.h | 4 ++-- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 4effbf9364556..b98a3419c4761 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,10 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-09-04 - xxxxxxx - lavc 57.105.100 - avcodec.h + Add AV_HWACCEL_CODEC_CAP_EXPERIMENTAL, replacing the deprecated + HWACCEL_CODEC_CAP_EXPERIMENTAL flag. + 2017-09-01 - xxxxxxx - lavf 57.81.100 - avio.h Add avio_read_partial(). diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 513236a863728..7708bb2adb9b4 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3879,7 +3879,7 @@ typedef struct AVHWAccel { /** * Hardware accelerated codec capabilities. - * see HWACCEL_CODEC_CAP_* + * see AV_HWACCEL_CODEC_CAP_* */ int capabilities; @@ -3987,6 +3987,12 @@ typedef struct AVHWAccel { int caps_internal; } AVHWAccel; +/** + * HWAccel is experimental and is thus avoided in favor of non experimental + * codecs + */ +#define AV_HWACCEL_CODEC_CAP_EXPERIMENTAL 0x0200 + /** * Hardware acceleration should be used for decoding even if the codec level * used is unknown or higher than the maximum supported level reported by the diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 9b57910842668..892143c1d2cfe 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -1150,7 +1150,7 @@ static int setup_hwaccel(AVCodecContext *avctx, return AVERROR(ENOENT); } - if (hwa->capabilities & HWACCEL_CODEC_CAP_EXPERIMENTAL && + if (hwa->capabilities & AV_HWACCEL_CODEC_CAP_EXPERIMENTAL && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { av_log(avctx, AV_LOG_WARNING, "Ignoring experimental hwaccel: %s\n", hwa->name); diff --git a/libavcodec/version.h b/libavcodec/version.h index 29cdb85589a98..55b8ddc13c172 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 104 -#define LIBAVCODEC_VERSION_MICRO 101 +#define LIBAVCODEC_VERSION_MINOR 105 +#define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From 6faa1275a2e163471e0cd16526713955d3500aa2 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Mon, 28 Aug 2017 14:32:25 +0200 Subject: [PATCH 2978/3374] avfilter: add despill filter Signed-off-by: Paul B Mahol --- Changelog | 1 + doc/filters.texi | 35 ++++++++ libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/version.h | 2 +- libavfilter/vf_despill.c | 183 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 libavfilter/vf_despill.c diff --git a/Changelog b/Changelog index cbeb248655a9f..cae5254e2b797 100644 --- a/Changelog +++ b/Changelog @@ -42,6 +42,7 @@ version : - FITS muxer and encoder - add --disable-autodetect build switch - drop deprecated qtkit input device (use avfoundation instead) +- despill video filter version 3.3: - CrystalHD decoder moved to new decode API diff --git a/doc/filters.texi b/doc/filters.texi index ce3f75dbd6501..862290550debb 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -6811,6 +6811,41 @@ FFmpeg was configured with @code{--enable-opencl}. Default value is 0. @end table +@section despill + +Remove unwanted contamination of foreground colors, caused by reflected color of +greenscreen or bluescreen. + +This filter accepts the following options: + +@table @option +@item type +Set what type of despill to use. + +@item mix +Set how spillmap will be generated. + +@item expand +Set how much to get rid of still remaining spill. + +@item red +Controls ammount of red in spill area. + +@item green +Controls ammount of green in spill area. +Should be -1 for greenscreen. + +@item blue +Controls ammount of blue in spill area. +Should be -1 for bluescreen. + +@item brightness +Controls brightness of spill area, preserving colors. + +@item alpha +Modify alpha from generated spillmap. +@end table + @section detelecine Apply an exact inverse of the telecine operation. It requires a predefined diff --git a/libavfilter/Makefile b/libavfilter/Makefile index ee840b02e5e1a..1e460ab988642 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -166,6 +166,7 @@ OBJS-$(CONFIG_DEINTERLACE_VAAPI_FILTER) += vf_deinterlace_vaapi.o OBJS-$(CONFIG_DEJUDDER_FILTER) += vf_dejudder.o OBJS-$(CONFIG_DELOGO_FILTER) += vf_delogo.o OBJS-$(CONFIG_DESHAKE_FILTER) += vf_deshake.o +OBJS-$(CONFIG_DESPILL_FILTER) += vf_despill.o OBJS-$(CONFIG_DETELECINE_FILTER) += vf_detelecine.o OBJS-$(CONFIG_DILATION_FILTER) += vf_neighbor.o OBJS-$(CONFIG_DISPLACE_FILTER) += vf_displace.o framesync2.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 8b9b9a4d10344..9a2cfea14874d 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -178,6 +178,7 @@ static void register_all(void) REGISTER_FILTER(DEJUDDER, dejudder, vf); REGISTER_FILTER(DELOGO, delogo, vf); REGISTER_FILTER(DESHAKE, deshake, vf); + REGISTER_FILTER(DESPILL, despill, vf); REGISTER_FILTER(DETELECINE, detelecine, vf); REGISTER_FILTER(DILATION, dilation, vf); REGISTER_FILTER(DISPLACE, displace, vf); diff --git a/libavfilter/version.h b/libavfilter/version.h index 60f18f7c51379..4b16de1f8ae63 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 6 -#define LIBAVFILTER_VERSION_MINOR 101 +#define LIBAVFILTER_VERSION_MINOR 102 #define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vf_despill.c b/libavfilter/vf_despill.c new file mode 100644 index 0000000000000..eff9877a1c21d --- /dev/null +++ b/libavfilter/vf_despill.c @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2017 Paul B Mahol + * + * 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 "libavutil/opt.h" +#include "libavutil/imgutils.h" +#include "avfilter.h" +#include "formats.h" +#include "internal.h" +#include "video.h" + +typedef struct DespillContext { + const AVClass *class; + + int co[4]; /* color offsets rgba */ + + int alpha; + int type; + float spillmix; + float spillexpand; + float redscale; + float greenscale; + float bluescale; + float brightness; +} DespillContext; + +static int do_despill_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + DespillContext *s = ctx->priv; + AVFrame *frame = arg; + const int ro = s->co[0], go = s->co[1], bo = s->co[2], ao = s->co[3]; + const int slice_start = (frame->height * jobnr) / nb_jobs; + const int slice_end = (frame->height * (jobnr + 1)) / nb_jobs; + const float brightness = s->brightness; + const float redscale = s->redscale; + const float greenscale = s->greenscale; + const float bluescale = s->bluescale; + const float spillmix = s->spillmix; + const float factor = (1.f - spillmix) * (1.f - s->spillexpand); + float red, green, blue; + int x, y; + + for (y = slice_start; y < slice_end; y++) { + uint8_t *dst = frame->data[0] + y * frame->linesize[0]; + + for (x = 0; x < frame->width; x++) { + float spillmap; + + red = dst[x * 4 + ro] / 255.f; + green = dst[x * 4 + go] / 255.f; + blue = dst[x * 4 + bo] / 255.f; + + if (s->type) { + spillmap = FFMAX(blue - (red * spillmix + green * factor), 0.f); + } else { + spillmap = FFMAX(green - (red * spillmix + blue * factor), 0.f); + } + + red = FFMAX(red + spillmap * redscale + brightness * spillmap, 0.f); + green = FFMAX(green + spillmap * greenscale + brightness * spillmap, 0.f); + blue = FFMAX(blue + spillmap * bluescale + brightness * spillmap, 0.f); + + dst[x * 4 + ro] = av_clip_uint8(red * 255); + dst[x * 4 + go] = av_clip_uint8(green * 255); + dst[x * 4 + bo] = av_clip_uint8(blue * 255); + if (s->alpha) { + spillmap = 1.f - spillmap; + dst[x * 4 + ao] = av_clip_uint8(spillmap * 255); + } + } + } + + return 0; +} + +static int filter_frame(AVFilterLink *link, AVFrame *frame) +{ + AVFilterContext *ctx = link->dst; + int ret; + + if (ret = av_frame_make_writable(frame)) + return ret; + + if (ret = ctx->internal->execute(ctx, do_despill_slice, frame, NULL, FFMIN(frame->height, ff_filter_get_nb_threads(ctx)))) + return ret; + + return ff_filter_frame(ctx->outputs[0], frame); +} + +static av_cold int config_output(AVFilterLink *outlink) +{ + AVFilterContext *ctx = outlink->src; + DespillContext *s = ctx->priv; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(outlink->format); + int i; + + for (i = 0; i < 4; ++i) + s->co[i] = desc->comp[i].offset; + + return 0; +} + +static av_cold int query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pixel_fmts[] = { + AV_PIX_FMT_ARGB, + AV_PIX_FMT_RGBA, + AV_PIX_FMT_ABGR, + AV_PIX_FMT_BGRA, + AV_PIX_FMT_NONE + }; + AVFilterFormats *formats = NULL; + + formats = ff_make_format_list(pixel_fmts); + if (!formats) + return AVERROR(ENOMEM); + + return ff_set_common_formats(ctx, formats); +} + +static const AVFilterPad despill_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .filter_frame = filter_frame, + }, + { NULL } +}; + +static const AVFilterPad despill_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = config_output, + }, + { NULL } +}; + +#define OFFSET(x) offsetof(DespillContext, x) +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM + +static const AVOption despill_options[] = { + { "type", "set the screen type", OFFSET(type), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "type" }, + { "green", "greenscreen", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "type" }, + { "blue", "bluescreen", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "type" }, + { "mix", "set the spillmap mix", OFFSET(spillmix), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS }, + { "expand", "set the spillmap expand", OFFSET(spillexpand), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, FLAGS }, + { "red", "set red scale", OFFSET(bluescale), AV_OPT_TYPE_FLOAT, {.dbl=0}, -100, 100, FLAGS }, + { "green", "set green scale", OFFSET(greenscale), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -100, 100, FLAGS }, + { "blue", "set blue scale", OFFSET(bluescale), AV_OPT_TYPE_FLOAT, {.dbl=0}, -100, 100, FLAGS }, + { "brightness", "set brightness", OFFSET(brightness), AV_OPT_TYPE_FLOAT, {.dbl=0}, -10, 10, FLAGS }, + { "alpha", "change alpha component", OFFSET(alpha), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(despill); + +AVFilter ff_vf_despill = { + .name = "despill", + .description = NULL_IF_CONFIG_SMALL("Despill video."), + .priv_size = sizeof(DespillContext), + .priv_class = &despill_class, + .query_formats = query_formats, + .inputs = despill_inputs, + .outputs = despill_outputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, +}; From 2c10f054c2bcd4500ef7f2c88257c5df8933ef3c Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Tue, 5 Sep 2017 11:43:49 +0200 Subject: [PATCH 2979/3374] avfilter/avf_avectorscope: add possibility to auto zoom Signed-off-by: Paul B Mahol --- doc/filters.texi | 3 ++- libavfilter/avf_avectorscope.c | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 862290550debb..9ca24b3c8e255 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -17044,7 +17044,8 @@ Specify the red, green, blue and alpha fade. Default values are @code{15}, Allowed range is @code{[0, 255]}. @item zoom -Set the zoom factor. Default value is @code{1}. Allowed range is @code{[1, 10]}. +Set the zoom factor. Default value is @code{1}. Allowed range is @code{[0, 10]}. +Values lower than @var{1} will auto adjust zoom factor to maximal possible value. @item draw Set the vectorscope drawing mode. diff --git a/libavfilter/avf_avectorscope.c b/libavfilter/avf_avectorscope.c index 7cb5efb402ad8..b24011bd66c58 100644 --- a/libavfilter/avf_avectorscope.c +++ b/libavfilter/avf_avectorscope.c @@ -90,7 +90,7 @@ static const AVOption avectorscope_options[] = { { "gf", "set green fade", OFFSET(fade[1]), AV_OPT_TYPE_INT, {.i64=10}, 0, 255, FLAGS }, { "bf", "set blue fade", OFFSET(fade[2]), AV_OPT_TYPE_INT, {.i64=5}, 0, 255, FLAGS }, { "af", "set alpha fade", OFFSET(fade[3]), AV_OPT_TYPE_INT, {.i64=5}, 0, 255, FLAGS }, - { "zoom", "set zoom factor", OFFSET(zoom), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 1, 10, FLAGS }, + { "zoom", "set zoom factor", OFFSET(zoom), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 10, FLAGS }, { "draw", "set draw mode", OFFSET(draw), AV_OPT_TYPE_INT, {.i64=DOT}, 0, DRAW_NB-1, FLAGS, "draw" }, { "dot", "", 0, AV_OPT_TYPE_CONST, {.i64=DOT} , 0, 0, FLAGS, "draw" }, { "line", "", 0, AV_OPT_TYPE_CONST, {.i64=LINE}, 0, 0, FLAGS, "draw" }, @@ -234,7 +234,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) const int hh = s->hh; unsigned x, y; unsigned prev_x = s->prev_x, prev_y = s->prev_y; - const double zoom = s->zoom; + double zoom = s->zoom; int i; if (!s->outpicref || s->outpicref->width != outlink->w || @@ -254,6 +254,35 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) fade(s); + if (zoom < 1) { + float max = 0; + + switch (insamples->format) { + case AV_SAMPLE_FMT_S16: { + int16_t *samples = (int16_t *)insamples->data[0]; + + for (i = 0; i < insamples->nb_samples * 2; i++) { + float sample = samples[i] / (float)INT16_MAX; + max = FFMAX(FFABS(sample), max); + } + + } + break; + case AV_SAMPLE_FMT_FLT: { + float *samples = (float *)insamples->data[0] + i * 2; + + for (i = 0; i < insamples->nb_samples; i++) { + max = FFMAX(FFABS(samples[i]), max); + } + } + break; + default: + av_assert2(0); + } + + zoom = 1. / max; + } + for (i = 0; i < insamples->nb_samples; i++) { int16_t *samples = (int16_t *)insamples->data[0] + i * 2; float *samplesf = (float *)insamples->data[0] + i * 2; From a5e6cd79ec343937129c17747447ba37d006859b Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Tue, 5 Sep 2017 11:55:23 +0200 Subject: [PATCH 2980/3374] avfilter/avf_avectorscope: fix mistake in previous commit Signed-off-by: Paul B Mahol --- libavfilter/avf_avectorscope.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavfilter/avf_avectorscope.c b/libavfilter/avf_avectorscope.c index b24011bd66c58..c8ff0698e3c4c 100644 --- a/libavfilter/avf_avectorscope.c +++ b/libavfilter/avf_avectorscope.c @@ -269,9 +269,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) } break; case AV_SAMPLE_FMT_FLT: { - float *samples = (float *)insamples->data[0] + i * 2; + float *samples = (float *)insamples->data[0]; - for (i = 0; i < insamples->nb_samples; i++) { + for (i = 0; i < insamples->nb_samples * 2; i++) { max = FFMAX(FFABS(samples[i]), max); } } From 516ac7bcc76124989626bec2fff6e5a5333bf26e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Tue, 5 Sep 2017 12:45:20 +0200 Subject: [PATCH 2981/3374] build: consistent spacing between lists (cosmetics) --- configure | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/configure b/configure index f7558f699879a..2f3fa2ba3de15 100755 --- a/configure +++ b/configure @@ -1439,9 +1439,11 @@ AVDEVICE_COMPONENTS=" indevs outdevs " + AVFILTER_COMPONENTS=" filters " + AVFORMAT_COMPONENTS=" demuxers muxers @@ -1449,6 +1451,7 @@ AVFORMAT_COMPONENTS=" " AVRESAMPLE_COMPONENTS="" + AVUTIL_COMPONENTS="" COMPONENT_LIST=" @@ -1483,6 +1486,7 @@ EXAMPLE_LIST=" transcode_aac_example transcoding_example " + EXTERNAL_AUTODETECT_LIBRARY_LIST=" alsa bzlib @@ -1592,6 +1596,7 @@ EXTERNAL_LIBRARY_LIST=" opengl videotoolbox " + HWACCEL_AUTODETECT_LIBRARY_LIST=" audiotoolbox crystalhd From 837c55e07271b59cd151b3cbecb1822fc10adf77 Mon Sep 17 00:00:00 2001 From: Karthick J Date: Tue, 5 Sep 2017 23:30:52 +0800 Subject: [PATCH 2982/3374] avformat/hlsenc: Added configuration to override HTTP User-Agent Signed-off-by: Karthick J Signed-off-by: Steven Liu --- doc/muxers.texi | 4 ++++ libavformat/hlsenc.c | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/doc/muxers.texi b/doc/muxers.texi index 2bec5f8954310..5a4f17bf8d51a 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -728,6 +728,10 @@ server using the HTTP PUT method, and update the m3u8 files every @code{refresh} times using the same method. Note that the HTTP server must support the given method for uploading files. + +@item http_user_agent +Override User-Agent field in HTTP header. Applicable only for HTTP output. + @end table @anchor{ico} diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 4a90886331beb..895aa41bc367a 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -174,6 +174,7 @@ typedef struct HLSContext { double initial_prog_date_time; char current_segment_final_filename_fmt[1024]; // when renaming segments + char *user_agent; } HLSContext; static int get_int_from_double(double val) @@ -974,6 +975,9 @@ static void set_http_options(AVFormatContext *s, AVDictionary **options, HLSCont av_log(c, AV_LOG_WARNING, "No HTTP method set, hls muxer defaulting to method PUT.\n"); av_dict_set(options, "method", "PUT", 0); } + if (c->user_agent) + av_dict_set(options, "user_agent", c->user_agent, 0); + } static void write_m3u8_head_block(HLSContext *hls, AVIOContext *out, int version, @@ -1816,6 +1820,7 @@ static const AVOption options[] = { {"generic", "start_number value (default)", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_START_SEQUENCE_AS_START_NUMBER }, INT_MIN, INT_MAX, E, "start_sequence_source_type" }, {"epoch", "seconds since epoch", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH }, INT_MIN, INT_MAX, E, "start_sequence_source_type" }, {"datetime", "current datetime as YYYYMMDDhhmmss", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_START_SEQUENCE_AS_FORMATTED_DATETIME }, INT_MIN, INT_MAX, E, "start_sequence_source_type" }, + {"http_user_agent", "override User-Agent field in HTTP header", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E}, { NULL }, }; From 9a174d203ae42cc03360c695c70066d6eb1058db Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 30 Aug 2017 02:07:00 -0300 Subject: [PATCH 2983/3374] avfilter/lavfutils: remove usage of AVStream->codec Signed-off-by: James Almer --- libavfilter/lavfutils.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/libavfilter/lavfutils.c b/libavfilter/lavfutils.c index 35878b3d50f20..b6319cf02758a 100644 --- a/libavfilter/lavfutils.c +++ b/libavfilter/lavfutils.c @@ -29,6 +29,7 @@ int ff_load_image(uint8_t *data[4], int linesize[4], AVFormatContext *format_ctx = NULL; AVCodec *codec; AVCodecContext *codec_ctx; + AVCodecParameters *par; AVFrame *frame; int frame_decoded, ret = 0; AVPacket pkt; @@ -50,14 +51,27 @@ int ff_load_image(uint8_t *data[4], int linesize[4], return ret; } - codec_ctx = format_ctx->streams[0]->codec; - codec = avcodec_find_decoder(codec_ctx->codec_id); + par = format_ctx->streams[0]->codecpar; + codec = avcodec_find_decoder(par->codec_id); if (!codec) { av_log(log_ctx, AV_LOG_ERROR, "Failed to find codec\n"); ret = AVERROR(EINVAL); goto end; } + codec_ctx = avcodec_alloc_context3(codec); + if (!codec_ctx) { + av_log(log_ctx, AV_LOG_ERROR, "Failed to alloc video decoder context\n"); + ret = AVERROR(ENOMEM); + goto end; + } + + ret = avcodec_parameters_to_context(codec_ctx, par); + if (ret < 0) { + av_log(log_ctx, AV_LOG_ERROR, "Failed to copy codec parameters to decoder context\n"); + goto end; + } + av_dict_set(&opt, "thread_type", "slice", 0); if ((ret = avcodec_open2(codec_ctx, codec, &opt)) < 0) { av_log(log_ctx, AV_LOG_ERROR, "Failed to open codec\n"); @@ -96,7 +110,7 @@ int ff_load_image(uint8_t *data[4], int linesize[4], end: av_packet_unref(&pkt); - avcodec_close(codec_ctx); + avcodec_free_context(&codec_ctx); avformat_close_input(&format_ctx); av_frame_free(&frame); av_dict_free(&opt); From fa805df060aeae537e9f8a51ecd9429216ccc779 Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Mon, 31 Jul 2017 12:07:03 +0530 Subject: [PATCH 2984/3374] libavcodec/mips: Improve avc idct8 msa function Replace memset call with msa stores. Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/h264idct_msa.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/mips/h264idct_msa.c b/libavcodec/mips/h264idct_msa.c index 861befe244bbb..1e1a5c8cb82d8 100644 --- a/libavcodec/mips/h264idct_msa.c +++ b/libavcodec/mips/h264idct_msa.c @@ -120,11 +120,12 @@ static void avc_idct8_addblk_msa(uint8_t *dst, int16_t *src, int32_t dst_stride) v4i32 res0_r, res1_r, res2_r, res3_r, res4_r, res5_r, res6_r, res7_r; v4i32 res0_l, res1_l, res2_l, res3_l, res4_l, res5_l, res6_l, res7_l; v16i8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; - v16i8 zeros = { 0 }; + v8i16 zeros = { 0 }; src[0] += 32; LD_SH8(src, 8, src0, src1, src2, src3, src4, src5, src6, src7); + ST_SH8(zeros, zeros, zeros, zeros, zeros, zeros, zeros, zeros, src, 8); vec0 = src0 + src4; vec1 = src0 - src4; @@ -318,7 +319,6 @@ void ff_h264_idct8_addblk_msa(uint8_t *dst, int16_t *src, int32_t dst_stride) { avc_idct8_addblk_msa(dst, src, dst_stride); - memset(src, 0, 64 * sizeof(dctcoef)); } void ff_h264_idct4x4_addblk_dc_msa(uint8_t *dst, int16_t *src, From d8bc198d0979aa417469ddaac8c80146b1df9e4e Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 5 Sep 2017 15:26:52 +0200 Subject: [PATCH 2985/3374] avfilter/vf_overlay: Restore shorthand option order Signed-off-by: Michael Niedermayer --- doc/filters.texi | 9 +++++++++ libavfilter/framesync2.c | 6 ------ libavfilter/framesync2.h | 6 ++++++ libavfilter/vf_overlay.c | 8 ++++++++ 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 9ca24b3c8e255..779036759370d 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -10956,6 +10956,9 @@ on the main video. Default value is "0" for both expressions. In case the expression is invalid, it is set to a huge value (meaning that the overlay will not be displayed within the output visible area). +@item eof_action +See @ref{framesync}. + @item eval Set when the expressions for @option{x}, and @option{y} are evaluated. @@ -10971,6 +10974,9 @@ evaluate expressions for each incoming frame Default value is @samp{frame}. +@item shortest +See @ref{framesync}. + @item format Set the format for the output video. @@ -10996,6 +11002,9 @@ automatically pick format @end table Default value is @samp{yuv420}. + +@item repeatlast +See @ref{framesync}. @end table The @option{x}, and @option{y} expressions can contain the following diff --git a/libavfilter/framesync2.c b/libavfilter/framesync2.c index fae06aa1f5bf8..aea9937ce9fbc 100644 --- a/libavfilter/framesync2.c +++ b/libavfilter/framesync2.c @@ -28,12 +28,6 @@ #define OFFSET(member) offsetof(FFFrameSync, member) #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM -enum EOFAction { - EOF_ACTION_REPEAT, - EOF_ACTION_ENDALL, - EOF_ACTION_PASS -}; - static const char *framesync_name(void *ptr) { return "framesync"; diff --git a/libavfilter/framesync2.h b/libavfilter/framesync2.h index 745e896bc84af..63a0eabbeb8b4 100644 --- a/libavfilter/framesync2.h +++ b/libavfilter/framesync2.h @@ -23,6 +23,12 @@ #include "bufferqueue.h" +enum EOFAction { + EOF_ACTION_REPEAT, + EOF_ACTION_ENDALL, + EOF_ACTION_PASS +}; + /* * TODO * Export convenient options. diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c index 4166e7c095af0..619a5a6354905 100644 --- a/libavfilter/vf_overlay.c +++ b/libavfilter/vf_overlay.c @@ -817,9 +817,16 @@ static int activate(AVFilterContext *ctx) static const AVOption overlay_options[] = { { "x", "set the x expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str = "0"}, CHAR_MIN, CHAR_MAX, FLAGS }, { "y", "set the y expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str = "0"}, CHAR_MIN, CHAR_MAX, FLAGS }, + { "eof_action", "Action to take when encountering EOF from secondary input ", + OFFSET(fs.opt_eof_action), AV_OPT_TYPE_INT, { .i64 = EOF_ACTION_REPEAT }, + EOF_ACTION_REPEAT, EOF_ACTION_PASS, .flags = FLAGS, "eof_action" }, + { "repeat", "Repeat the previous frame.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_REPEAT }, .flags = FLAGS, "eof_action" }, + { "endall", "End both streams.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_ENDALL }, .flags = FLAGS, "eof_action" }, + { "pass", "Pass through the main input.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_PASS }, .flags = FLAGS, "eof_action" }, { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_FRAME}, 0, EVAL_MODE_NB-1, FLAGS, "eval" }, { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" }, { "frame", "eval expressions per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" }, + { "shortest", "force termination when the shortest input terminates", OFFSET(fs.opt_shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, { "format", "set output format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=OVERLAY_FORMAT_YUV420}, 0, OVERLAY_FORMAT_NB-1, FLAGS, "format" }, { "yuv420", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420}, .flags = FLAGS, .unit = "format" }, { "yuv422", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV422}, .flags = FLAGS, .unit = "format" }, @@ -827,6 +834,7 @@ static const AVOption overlay_options[] = { { "rgb", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_RGB}, .flags = FLAGS, .unit = "format" }, { "gbrp", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_GBRP}, .flags = FLAGS, .unit = "format" }, { "auto", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_AUTO}, .flags = FLAGS, .unit = "format" }, + { "repeatlast", "repeat overlay of the last overlay frame", OFFSET(fs.opt_repeatlast), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS }, { NULL } }; From eea69a9f250e565640f1dc69b285a4d27668f67b Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Wed, 6 Sep 2017 11:46:24 +0200 Subject: [PATCH 2986/3374] avfilter/af_dcshift: add direct path Signed-off-by: Paul B Mahol --- libavfilter/af_dcshift.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/libavfilter/af_dcshift.c b/libavfilter/af_dcshift.c index 7332c12b19562..2ca2d075351e5 100644 --- a/libavfilter/af_dcshift.c +++ b/libavfilter/af_dcshift.c @@ -90,11 +90,16 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) int i, j; double dcshift = s->dcshift; - if (!out) { - av_frame_free(&in); - return AVERROR(ENOMEM); + if (av_frame_is_writable(in)) { + out = in; + } else { + out = ff_get_audio_buffer(inlink, in->nb_samples); + if (!out) { + av_frame_free(&in); + return AVERROR(ENOMEM); + } + av_frame_copy_props(out, in); } - av_frame_copy_props(out, in); if (s->limitergain > 0) { for (i = 0; i < inlink->channels; i++) { @@ -134,7 +139,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) } } - av_frame_free(&in); + if (out != in) + av_frame_free(&in); return ff_filter_frame(outlink, out); } static const AVFilterPad dcshift_inputs[] = { From 7273e234dee5dfeee67cc365a8f7fa0b8211127c Mon Sep 17 00:00:00 2001 From: James Almer Date: Thu, 25 May 2017 11:00:47 -0300 Subject: [PATCH 2987/3374] avcodec/audiotoolboxdec: always use a copy of the AVCodecContext extradata Fixes memleaks introduced by 954e2b3d34b7c2d82871254f07e2f8a39bc451cb Signed-off-by: James Almer --- libavcodec/audiotoolboxdec.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libavcodec/audiotoolboxdec.c b/libavcodec/audiotoolboxdec.c index a8655f0421b2d..d499a0afc8c9b 100644 --- a/libavcodec/audiotoolboxdec.c +++ b/libavcodec/audiotoolboxdec.c @@ -399,8 +399,13 @@ static av_cold int ffat_create_decoder(AVCodecContext *avctx, AVPacket *pkt) static av_cold int ffat_init_decoder(AVCodecContext *avctx) { ATDecodeContext *at = avctx->priv_data; - at->extradata = avctx->extradata; - at->extradata_size = avctx->extradata_size; + if (avctx->extradata_size) { + at->extradata = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!at->extradata) + return AVERROR(ENOMEM); + at->extradata_size = avctx->extradata_size; + memcpy(at->extradata, avctx->extradata, avctx->extradata_size); + } if ((avctx->channels && avctx->sample_rate) || ffat_usable_extradata(avctx)) return ffat_create_decoder(avctx, NULL); @@ -599,6 +604,7 @@ static av_cold int ffat_close_decoder(AVCodecContext *avctx) av_packet_unref(&at->new_in_pkt); av_packet_unref(&at->in_pkt); av_free(at->decoded_data); + av_free(at->extradata); return 0; } From e49338a9c062df7f3167433d81a1528a978fd547 Mon Sep 17 00:00:00 2001 From: James Almer Date: Thu, 25 May 2017 11:07:42 -0300 Subject: [PATCH 2988/3374] avcodec/audiotoolboxdec: add FF_CODEC_CAP_INIT_CLEANUP to the decoder capabilities Extradata may be allocated and the AudioConverterRef may be created during init(), which in case of a failure would not be freed as close() isn't called afterwards. Signed-off-by: James Almer --- libavcodec/audiotoolboxdec.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libavcodec/audiotoolboxdec.c b/libavcodec/audiotoolboxdec.c index d499a0afc8c9b..c30817778fa28 100644 --- a/libavcodec/audiotoolboxdec.c +++ b/libavcodec/audiotoolboxdec.c @@ -599,7 +599,8 @@ static av_cold void ffat_decode_flush(AVCodecContext *avctx) static av_cold int ffat_close_decoder(AVCodecContext *avctx) { ATDecodeContext *at = avctx->priv_data; - AudioConverterDispose(at->converter); + if (at->converter) + AudioConverterDispose(at->converter); av_bsf_free(&at->bsf); av_packet_unref(&at->new_in_pkt); av_packet_unref(&at->in_pkt); @@ -628,7 +629,7 @@ static av_cold int ffat_close_decoder(AVCodecContext *avctx) .flush = ffat_decode_flush, \ .priv_class = &ffat_##NAME##_dec_class, \ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, \ - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, \ + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, \ }; FFAT_DEC(aac, AV_CODEC_ID_AAC) From 3242babf64a249fcba07a8a885f9e9825f4ffd3c Mon Sep 17 00:00:00 2001 From: James Almer Date: Thu, 25 May 2017 12:56:50 -0300 Subject: [PATCH 2989/3374] avcodec/audiotoolboxdec: switch to the new generic filtering mechanism Tested-by: ubitux Signed-off-by: James Almer --- libavcodec/audiotoolboxdec.c | 73 ++++++++++-------------------------- 1 file changed, 20 insertions(+), 53 deletions(-) diff --git a/libavcodec/audiotoolboxdec.c b/libavcodec/audiotoolboxdec.c index c30817778fa28..97514368bfed6 100644 --- a/libavcodec/audiotoolboxdec.c +++ b/libavcodec/audiotoolboxdec.c @@ -43,7 +43,6 @@ typedef struct ATDecodeContext { AudioStreamPacketDescription pkt_desc; AVPacket in_pkt; AVPacket new_in_pkt; - AVBSFContext *bsf; char *decoded_data; int channel_map[64]; @@ -478,42 +477,15 @@ static int ffat_decode(AVCodecContext *avctx, void *data, ATDecodeContext *at = avctx->priv_data; AVFrame *frame = data; int pkt_size = avpkt->size; - AVPacket filtered_packet = {0}; OSStatus ret; AudioBufferList out_buffers; - if (avctx->codec_id == AV_CODEC_ID_AAC && avpkt->size > 2 && - (AV_RB16(avpkt->data) & 0xfff0) == 0xfff0) { - AVPacket filter_pkt = {0}; - if (!at->bsf) { - const AVBitStreamFilter *bsf = av_bsf_get_by_name("aac_adtstoasc"); - if(!bsf) - return AVERROR_BSF_NOT_FOUND; - if ((ret = av_bsf_alloc(bsf, &at->bsf))) - return ret; - if (((ret = avcodec_parameters_from_context(at->bsf->par_in, avctx)) < 0) || - ((ret = av_bsf_init(at->bsf)) < 0)) { - av_bsf_free(&at->bsf); - return ret; - } - } - - if ((ret = av_packet_ref(&filter_pkt, avpkt)) < 0) - return ret; - - if ((ret = av_bsf_send_packet(at->bsf, &filter_pkt)) < 0) { - av_packet_unref(&filter_pkt); - return ret; - } - - if ((ret = av_bsf_receive_packet(at->bsf, &filtered_packet)) < 0) - return ret; - + if (avctx->codec_id == AV_CODEC_ID_AAC) { if (!at->extradata_size) { uint8_t *side_data; int side_data_size = 0; - side_data = av_packet_get_side_data(&filtered_packet, AV_PKT_DATA_NEW_EXTRADATA, + side_data = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, &side_data_size); if (side_data_size) { at->extradata = av_mallocz(side_data_size + AV_INPUT_BUFFER_PADDING_SIZE); @@ -523,13 +495,10 @@ static int ffat_decode(AVCodecContext *avctx, void *data, memcpy(at->extradata, side_data, side_data_size); } } - - avpkt = &filtered_packet; } if (!at->converter) { if ((ret = ffat_create_decoder(avctx, avpkt)) < 0) { - av_packet_unref(&filtered_packet); return ret; } } @@ -548,9 +517,7 @@ static int ffat_decode(AVCodecContext *avctx, void *data, av_packet_unref(&at->new_in_pkt); if (avpkt->size) { - if (filtered_packet.data) { - at->new_in_pkt = filtered_packet; - } else if ((ret = av_packet_ref(&at->new_in_pkt, avpkt)) < 0) { + if ((ret = av_packet_ref(&at->new_in_pkt, avpkt)) < 0) { return ret; } } else { @@ -601,7 +568,6 @@ static av_cold int ffat_close_decoder(AVCodecContext *avctx) ATDecodeContext *at = avctx->priv_data; if (at->converter) AudioConverterDispose(at->converter); - av_bsf_free(&at->bsf); av_packet_unref(&at->new_in_pkt); av_packet_unref(&at->in_pkt); av_free(at->decoded_data); @@ -615,7 +581,7 @@ static av_cold int ffat_close_decoder(AVCodecContext *avctx) .version = LIBAVUTIL_VERSION_INT, \ }; -#define FFAT_DEC(NAME, ID) \ +#define FFAT_DEC(NAME, ID, bsf_name) \ FFAT_DEC_CLASS(NAME) \ AVCodec ff_##NAME##_at_decoder = { \ .name = #NAME "_at", \ @@ -628,22 +594,23 @@ static av_cold int ffat_close_decoder(AVCodecContext *avctx) .decode = ffat_decode, \ .flush = ffat_decode_flush, \ .priv_class = &ffat_##NAME##_dec_class, \ + .bsfs = bsf_name, \ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, \ .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, \ }; -FFAT_DEC(aac, AV_CODEC_ID_AAC) -FFAT_DEC(ac3, AV_CODEC_ID_AC3) -FFAT_DEC(adpcm_ima_qt, AV_CODEC_ID_ADPCM_IMA_QT) -FFAT_DEC(alac, AV_CODEC_ID_ALAC) -FFAT_DEC(amr_nb, AV_CODEC_ID_AMR_NB) -FFAT_DEC(eac3, AV_CODEC_ID_EAC3) -FFAT_DEC(gsm_ms, AV_CODEC_ID_GSM_MS) -FFAT_DEC(ilbc, AV_CODEC_ID_ILBC) -FFAT_DEC(mp1, AV_CODEC_ID_MP1) -FFAT_DEC(mp2, AV_CODEC_ID_MP2) -FFAT_DEC(mp3, AV_CODEC_ID_MP3) -FFAT_DEC(pcm_alaw, AV_CODEC_ID_PCM_ALAW) -FFAT_DEC(pcm_mulaw, AV_CODEC_ID_PCM_MULAW) -FFAT_DEC(qdmc, AV_CODEC_ID_QDMC) -FFAT_DEC(qdm2, AV_CODEC_ID_QDM2) +FFAT_DEC(aac, AV_CODEC_ID_AAC, "aac_adtstoasc") +FFAT_DEC(ac3, AV_CODEC_ID_AC3, NULL) +FFAT_DEC(adpcm_ima_qt, AV_CODEC_ID_ADPCM_IMA_QT, NULL) +FFAT_DEC(alac, AV_CODEC_ID_ALAC, NULL) +FFAT_DEC(amr_nb, AV_CODEC_ID_AMR_NB, NULL) +FFAT_DEC(eac3, AV_CODEC_ID_EAC3, NULL) +FFAT_DEC(gsm_ms, AV_CODEC_ID_GSM_MS, NULL) +FFAT_DEC(ilbc, AV_CODEC_ID_ILBC, NULL) +FFAT_DEC(mp1, AV_CODEC_ID_MP1, NULL) +FFAT_DEC(mp2, AV_CODEC_ID_MP2, NULL) +FFAT_DEC(mp3, AV_CODEC_ID_MP3, NULL) +FFAT_DEC(pcm_alaw, AV_CODEC_ID_PCM_ALAW, NULL) +FFAT_DEC(pcm_mulaw, AV_CODEC_ID_PCM_MULAW, NULL) +FFAT_DEC(qdmc, AV_CODEC_ID_QDMC, NULL) +FFAT_DEC(qdm2, AV_CODEC_ID_QDM2, NULL) From f4e593f7b51f7cb30986186c187cff939c82d86d Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 6 Sep 2017 13:03:29 -0300 Subject: [PATCH 2990/3374] avcodec/audiotoolboxdec: use av_freep() This prevents leaving dangling pointers. --- libavcodec/audiotoolboxdec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/audiotoolboxdec.c b/libavcodec/audiotoolboxdec.c index 97514368bfed6..607d3ba4d4803 100644 --- a/libavcodec/audiotoolboxdec.c +++ b/libavcodec/audiotoolboxdec.c @@ -570,8 +570,8 @@ static av_cold int ffat_close_decoder(AVCodecContext *avctx) AudioConverterDispose(at->converter); av_packet_unref(&at->new_in_pkt); av_packet_unref(&at->in_pkt); - av_free(at->decoded_data); - av_free(at->extradata); + av_freep(&at->decoded_data); + av_freep(&at->extradata); return 0; } From edb4ba5bd4e7856fd6aaa37829150957dc5f4da3 Mon Sep 17 00:00:00 2001 From: Pavel Koshevoy Date: Sun, 3 Sep 2017 15:34:08 +0200 Subject: [PATCH 2991/3374] Revert "lavfi/atempo: avoid false triggering an assertion failure" This reverts commit 4240e5b047379b29c33dd3f4438bc4e610527b83. Fixes ticket #6540. Signed-off-by: Marton Balint --- libavfilter/af_atempo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavfilter/af_atempo.c b/libavfilter/af_atempo.c index 944df1dd32f2c..9eee8a63a8d6d 100644 --- a/libavfilter/af_atempo.c +++ b/libavfilter/af_atempo.c @@ -914,8 +914,8 @@ static int yae_flush(ATempoContext *atempo, atempo->state = YAE_FLUSH_OUTPUT; - if (atempo->position[0] >= frag->position[0] + frag->nsamples && - atempo->position[1] >= frag->position[1] + frag->nsamples) { + if (atempo->position[0] == frag->position[0] + frag->nsamples && + atempo->position[1] == frag->position[1] + frag->nsamples) { // the current fragment is already flushed: return 0; } From 25b5096400b2fd578e059eb4a5d2aba8f3cfddfb Mon Sep 17 00:00:00 2001 From: Pavel Koshevoy Date: Sun, 3 Sep 2017 20:44:31 -0600 Subject: [PATCH 2992/3374] lavfi/atempo: Avoid false triggering an assertion failure Steps to reproduce: 1. revert 4240e5b047379b29c33dd3f4438bc4e610527b83 2. ./ffmpeg -f lavfi -i sine=d=1 -af aselect=e=0,atempo=0.5 -y atempo.wav Signed-off-by: Marton Balint --- libavfilter/af_atempo.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavfilter/af_atempo.c b/libavfilter/af_atempo.c index 9eee8a63a8d6d..8b214bccd7bed 100644 --- a/libavfilter/af_atempo.c +++ b/libavfilter/af_atempo.c @@ -914,6 +914,11 @@ static int yae_flush(ATempoContext *atempo, atempo->state = YAE_FLUSH_OUTPUT; + if (!atempo->nfrag) { + // there is nothing to flush: + return 0; + } + if (atempo->position[0] == frag->position[0] + frag->nsamples && atempo->position[1] == frag->position[1] + frag->nsamples) { // the current fragment is already flushed: From ef7fe81b8554a2865d47a55edf47420878fa3d91 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Thu, 7 Sep 2017 08:30:14 +0800 Subject: [PATCH 2993/3374] flvdec: Check the avio_seek return value after reading a metadata packet merge from libav: 585dc1aecef0371ad6f16cb3750ae2a6da9cf00a If the metadata packet is corrupted, flv_read_metabody can accidentally read past the start of the next packet. If the start of the next packet had been flushed out of the IO buffer, we would be unable to seek to the right position (on a nonseekable stream). Prefer to clearly error out instead of silently trying to read from a desynced stream which will only be interpreted as garbage. Signed-off-by: Steven Liu --- libavformat/flvdec.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 2e70352c5374c..2d89bef15f25b 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -1015,7 +1015,13 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) "Skipping flv packet: type %d, size %d, flags %d.\n", type, size, flags); skip: - avio_seek(s->pb, next, SEEK_SET); + if (avio_seek(s->pb, next, SEEK_SET) != next) { + // This can happen if flv_read_metabody above read past + // next, on a non-seekable input, and the preceding data has + // been flushed out from the IO buffer. + av_log(s, AV_LOG_ERROR, "Unable to seek to the next packet\n"); + return AVERROR_INVALIDDATA; + } ret = FFERROR_REDO; goto leave; } From b07faf39ed10f5b24726aa25cd7134aeebb29e68 Mon Sep 17 00:00:00 2001 From: Paras Chadha Date: Sun, 3 Sep 2017 00:37:21 +0530 Subject: [PATCH 2994/3374] avcodec/fitsdec: write output to frame directly Signed-off-by: Paras Chadha Signed-off-by: James Almer --- libavcodec/fitsdec.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libavcodec/fitsdec.c b/libavcodec/fitsdec.c index 8ede0bcbfad4f..b0753813c9c92 100644 --- a/libavcodec/fitsdec.c +++ b/libavcodec/fitsdec.c @@ -264,11 +264,10 @@ static int fits_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, for (j = 0; j < avctx->width; j++) { \ t = rd; \ if (!header.blank_found || t != header.blank) { \ - t = ((t - header.data_min) * ((1 << (sizeof(type) * 8)) - 1)) / (header.data_max - header.data_min); \ + *dst++ = ((t - header.data_min) * ((1 << (sizeof(type) * 8)) - 1)) / (header.data_max - header.data_min); \ } else { \ - t = fitsctx->blank_val; \ + *dst++ = fitsctx->blank_val; \ } \ - *dst++ = (type) t; \ ptr8 += abs(cas) >> 3; \ } \ } \ From cf42f316c525a76680b8b2d3e68c61db71eaa50d Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 6 Sep 2017 22:53:17 -0300 Subject: [PATCH 2995/3374] fate: fix fate-lavf-fits dependencies We need the fits muxer/demuxer. --- tests/fate/avformat.mak | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fate/avformat.mak b/tests/fate/avformat.mak index c4cf2bc473a76..f65ef76648fb0 100644 --- a/tests/fate/avformat.mak +++ b/tests/fate/avformat.mak @@ -10,7 +10,7 @@ FATE_LAVF-$(call ENCDEC, PCM_S16BE, CAF) += caf FATE_LAVF-$(call ENCDEC, DPX, IMAGE2) += dpx FATE_LAVF-$(call ENCDEC2, DVVIDEO, PCM_S16LE, AVI) += dv_fmt FATE_LAVF-$(call ENCDEC2, MPEG1VIDEO, MP2, FFM) += ffm -FATE_LAVF-$(call ENCDEC, FITS, IMAGE2) += fits +FATE_LAVF-$(call ENCDEC, FITS, FITS) += fits FATE_LAVF-$(call ENCDEC, RAWVIDEO, FILMSTRIP) += flm FATE_LAVF-$(call ENCDEC, FLV, FLV) += flv_fmt FATE_LAVF-$(call ENCDEC, GIF, IMAGE2) += gif From a56d0497cbab6f9abf68f77f1b4fe16c4a53f101 Mon Sep 17 00:00:00 2001 From: Timo Rothenpieler Date: Sat, 2 Sep 2017 19:30:21 +0200 Subject: [PATCH 2996/3374] avcodec/nvenc: migrate to new encode API Signed-off-by: Timo Rothenpieler --- libavcodec/nvenc.c | 65 ++++++++++++++++++++++++++++++++++------- libavcodec/nvenc.h | 6 ++++ libavcodec/nvenc_h264.c | 6 ++++ libavcodec/nvenc_hevc.c | 4 +++ 4 files changed, 70 insertions(+), 11 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 744e5e0e01ffa..b54cb1275b465 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -1807,8 +1807,7 @@ static int output_ready(AVCodecContext *avctx, int flush) return (nb_ready > 0) && (nb_ready + nb_pending >= ctx->async_depth); } -int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, - const AVFrame *frame, int *got_packet) +int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) { NVENCSTATUS nv_status; CUresult cu_res; @@ -1823,12 +1822,16 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, NV_ENC_PIC_PARAMS pic_params = { 0 }; pic_params.version = NV_ENC_PIC_PARAMS_VER; + if (!ctx->cu_context || !ctx->nvencoder) + return AVERROR(EINVAL); + + if (ctx->encoder_flushing) + return AVERROR_EOF; + if (frame) { inSurf = get_free_frame(ctx); - if (!inSurf) { - av_log(avctx, AV_LOG_ERROR, "No free surfaces\n"); - return AVERROR_BUG; - } + if (!inSurf) + return AVERROR(EAGAIN); cu_res = dl_fn->cuda_dl->cuCtxPushCurrent(ctx->cu_context); if (cu_res != CUDA_SUCCESS) { @@ -1844,9 +1847,8 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return AVERROR_EXTERNAL; } - if (res) { + if (res) return res; - } pic_params.inputBuffer = inSurf->input_surface; pic_params.bufferFmt = inSurf->format; @@ -1876,6 +1878,7 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, nvenc_codec_specific_pic_params(avctx, &pic_params); } else { pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS; + ctx->encoder_flushing = 1; } cu_res = dl_fn->cuda_dl->cuCtxPushCurrent(ctx->cu_context); @@ -1914,7 +1917,23 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, } } - if (output_ready(avctx, !frame)) { + return 0; +} + +int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt) +{ + CUresult cu_res; + CUcontext dummy; + NvencSurface *tmpoutsurf; + int res; + + NvencContext *ctx = avctx->priv_data; + NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs; + + if (!ctx->cu_context || !ctx->nvencoder) + return AVERROR(EINVAL); + + if (output_ready(avctx, ctx->encoder_flushing)) { av_fifo_generic_read(ctx->output_surface_ready_queue, &tmpoutsurf, sizeof(tmpoutsurf), NULL); cu_res = dl_fn->cuda_dl->cuCtxPushCurrent(ctx->cu_context); @@ -1935,10 +1954,34 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return res; av_fifo_generic_write(ctx->unused_surface_queue, &tmpoutsurf, sizeof(tmpoutsurf), NULL); - - *got_packet = 1; + } else if (ctx->encoder_flushing) { + return AVERROR_EOF; } else { + return AVERROR(EAGAIN); + } + + return 0; +} + +int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, + const AVFrame *frame, int *got_packet) +{ + NvencContext *ctx = avctx->priv_data; + int res; + + if (!ctx->encoder_flushing) { + res = ff_nvenc_send_frame(avctx, frame); + if (res < 0) + return res; + } + + res = ff_nvenc_receive_packet(avctx, pkt); + if (res == AVERROR(EAGAIN) || res == AVERROR_EOF) { *got_packet = 0; + } else if (res < 0) { + return res; + } else { + *got_packet = 1; } return 0; diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h index 2c682275dac97..afb93cc22caed 100644 --- a/libavcodec/nvenc.h +++ b/libavcodec/nvenc.h @@ -116,6 +116,8 @@ typedef struct NvencContext AVFifoBuffer *output_surface_ready_queue; AVFifoBuffer *timestamp_list; + int encoder_flushing; + struct { CUdeviceptr ptr; NV_ENC_REGISTERED_PTR regptr; @@ -169,6 +171,10 @@ int ff_nvenc_encode_init(AVCodecContext *avctx); int ff_nvenc_encode_close(AVCodecContext *avctx); +int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame); + +int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt); + int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet); diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c index 9adbe9f9090da..c3b4bac7494dc 100644 --- a/libavcodec/nvenc_h264.c +++ b/libavcodec/nvenc_h264.c @@ -164,6 +164,8 @@ AVCodec ff_nvenc_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .init = nvenc_old_init, + .send_frame = ff_nvenc_send_frame, + .receive_packet = ff_nvenc_receive_packet, .encode2 = ff_nvenc_encode_frame, .close = ff_nvenc_encode_close, .priv_data_size = sizeof(NvencContext), @@ -190,6 +192,8 @@ AVCodec ff_nvenc_h264_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .init = nvenc_old_init, + .send_frame = ff_nvenc_send_frame, + .receive_packet = ff_nvenc_receive_packet, .encode2 = ff_nvenc_encode_frame, .close = ff_nvenc_encode_close, .priv_data_size = sizeof(NvencContext), @@ -216,6 +220,8 @@ AVCodec ff_h264_nvenc_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .init = ff_nvenc_encode_init, + .send_frame = ff_nvenc_send_frame, + .receive_packet = ff_nvenc_receive_packet, .encode2 = ff_nvenc_encode_frame, .close = ff_nvenc_encode_close, .priv_data_size = sizeof(NvencContext), diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c index 81da9d222db67..89e8c3e53a433 100644 --- a/libavcodec/nvenc_hevc.c +++ b/libavcodec/nvenc_hevc.c @@ -153,6 +153,8 @@ AVCodec ff_nvenc_hevc_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_HEVC, .init = nvenc_old_init, + .send_frame = ff_nvenc_send_frame, + .receive_packet = ff_nvenc_receive_packet, .encode2 = ff_nvenc_encode_frame, .close = ff_nvenc_encode_close, .priv_data_size = sizeof(NvencContext), @@ -178,6 +180,8 @@ AVCodec ff_hevc_nvenc_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_HEVC, .init = ff_nvenc_encode_init, + .send_frame = ff_nvenc_send_frame, + .receive_packet = ff_nvenc_receive_packet, .encode2 = ff_nvenc_encode_frame, .close = ff_nvenc_encode_close, .priv_data_size = sizeof(NvencContext), From d0961d30692ae9c4c509056544ac936b6b7177c0 Mon Sep 17 00:00:00 2001 From: Timo Rothenpieler Date: Sat, 2 Sep 2017 19:42:13 +0200 Subject: [PATCH 2997/3374] avcodec/nvenc: sanitize variable names --- libavcodec/nvenc.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index b54cb1275b465..e1d3316de39cf 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -1812,7 +1812,7 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) NVENCSTATUS nv_status; CUresult cu_res; CUcontext dummy; - NvencSurface *tmpoutsurf, *inSurf; + NvencSurface *tmp_out_surf, *in_surf; int res; NvencContext *ctx = avctx->priv_data; @@ -1829,8 +1829,8 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) return AVERROR_EOF; if (frame) { - inSurf = get_free_frame(ctx); - if (!inSurf) + in_surf = get_free_frame(ctx); + if (!in_surf) return AVERROR(EAGAIN); cu_res = dl_fn->cuda_dl->cuCtxPushCurrent(ctx->cu_context); @@ -1839,7 +1839,7 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) return AVERROR_EXTERNAL; } - res = nvenc_upload_frame(avctx, frame, inSurf); + res = nvenc_upload_frame(avctx, frame, in_surf); cu_res = dl_fn->cuda_dl->cuCtxPopCurrent(&dummy); if (cu_res != CUDA_SUCCESS) { @@ -1850,12 +1850,12 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) if (res) return res; - pic_params.inputBuffer = inSurf->input_surface; - pic_params.bufferFmt = inSurf->format; - pic_params.inputWidth = inSurf->width; - pic_params.inputHeight = inSurf->height; - pic_params.inputPitch = inSurf->pitch; - pic_params.outputBitstream = inSurf->output_surface; + pic_params.inputBuffer = in_surf->input_surface; + pic_params.bufferFmt = in_surf->format; + pic_params.inputWidth = in_surf->width; + pic_params.inputHeight = in_surf->height; + pic_params.inputPitch = in_surf->pitch; + pic_params.outputBitstream = in_surf->output_surface; if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) { if (frame->top_field_first) @@ -1900,7 +1900,7 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) return nvenc_print_error(avctx, nv_status, "EncodePicture failed!"); if (frame) { - av_fifo_generic_write(ctx->output_surface_queue, &inSurf, sizeof(inSurf), NULL); + av_fifo_generic_write(ctx->output_surface_queue, &in_surf, sizeof(in_surf), NULL); timestamp_queue_enqueue(ctx->timestamp_list, frame->pts); if (ctx->initial_pts[0] == AV_NOPTS_VALUE) @@ -1912,8 +1912,8 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) /* all the pending buffers are now ready for output */ if (nv_status == NV_ENC_SUCCESS) { while (av_fifo_size(ctx->output_surface_queue) > 0) { - av_fifo_generic_read(ctx->output_surface_queue, &tmpoutsurf, sizeof(tmpoutsurf), NULL); - av_fifo_generic_write(ctx->output_surface_ready_queue, &tmpoutsurf, sizeof(tmpoutsurf), NULL); + av_fifo_generic_read(ctx->output_surface_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL); + av_fifo_generic_write(ctx->output_surface_ready_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL); } } @@ -1924,7 +1924,7 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt) { CUresult cu_res; CUcontext dummy; - NvencSurface *tmpoutsurf; + NvencSurface *tmp_out_surf; int res; NvencContext *ctx = avctx->priv_data; @@ -1934,7 +1934,7 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt) return AVERROR(EINVAL); if (output_ready(avctx, ctx->encoder_flushing)) { - av_fifo_generic_read(ctx->output_surface_ready_queue, &tmpoutsurf, sizeof(tmpoutsurf), NULL); + av_fifo_generic_read(ctx->output_surface_ready_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL); cu_res = dl_fn->cuda_dl->cuCtxPushCurrent(ctx->cu_context); if (cu_res != CUDA_SUCCESS) { @@ -1942,7 +1942,7 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt) return AVERROR_EXTERNAL; } - res = process_output_surface(avctx, pkt, tmpoutsurf); + res = process_output_surface(avctx, pkt, tmp_out_surf); cu_res = dl_fn->cuda_dl->cuCtxPopCurrent(&dummy); if (cu_res != CUDA_SUCCESS) { @@ -1953,7 +1953,7 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt) if (res) return res; - av_fifo_generic_write(ctx->unused_surface_queue, &tmpoutsurf, sizeof(tmpoutsurf), NULL); + av_fifo_generic_write(ctx->unused_surface_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL); } else if (ctx->encoder_flushing) { return AVERROR_EOF; } else { From 912b6af26e0d2ed25df62296aa1213a3a620efae Mon Sep 17 00:00:00 2001 From: Tobias Rapp Date: Tue, 29 Aug 2017 10:51:05 +0200 Subject: [PATCH 2998/3374] ffprobe: use consistent string for unspecified color_range value Makes the handling of unspecified/unknown color_range values on stream level consistent to the value used on frame level. Signed-off-by: Tobias Rapp --- ffprobe.c | 8 ++++---- tests/ref/fate/ffprobe_compact | 4 ++-- tests/ref/fate/ffprobe_csv | 4 ++-- tests/ref/fate/ffprobe_default | 4 ++-- tests/ref/fate/ffprobe_flat | 4 ++-- tests/ref/fate/ffprobe_ini | 4 ++-- tests/ref/fate/mxf-probe-dnxhd | 2 +- tests/ref/fate/mxf-probe-dv25 | 2 +- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/ffprobe.c b/ffprobe.c index ba10563b9d098..b2e8949d9f909 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -1925,11 +1925,11 @@ static void print_pkt_side_data(WriterContext *w, writer_print_section_footer(w); } -static void print_color_range(WriterContext *w, enum AVColorRange color_range, const char *fallback) +static void print_color_range(WriterContext *w, enum AVColorRange color_range) { const char *val = av_color_range_name(color_range); if (!val || color_range == AVCOL_RANGE_UNSPECIFIED) { - print_str_opt("color_range", fallback); + print_str_opt("color_range", "unknown"); } else { print_str("color_range", val); } @@ -2157,7 +2157,7 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream, print_int("top_field_first", frame->top_field_first); print_int("repeat_pict", frame->repeat_pict); - print_color_range(w, frame->color_range, "unknown"); + print_color_range(w, frame->color_range); print_color_space(w, frame->colorspace); print_primaries(w, frame->color_primaries); print_color_trc(w, frame->color_trc); @@ -2534,7 +2534,7 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id else print_str_opt("pix_fmt", "unknown"); print_int("level", par->level); - print_color_range(w, par->color_range, "N/A"); + print_color_range(w, par->color_range); print_color_space(w, par->color_space); print_color_trc(w, par->color_trc); print_primaries(w, par->color_primaries); diff --git a/tests/ref/fate/ffprobe_compact b/tests/ref/fate/ffprobe_compact index 910837d290ae3..4a0f4ee77648f 100644 --- a/tests/ref/fate/ffprobe_compact +++ b/tests/ref/fate/ffprobe_compact @@ -27,6 +27,6 @@ frame|media_type=video|stream_index=1|key_frame=1|pkt_pts=6144|pkt_pts_time=0.12 packet|codec_type=video|stream_index=2|pts=6144|pts_time=0.120000|dts=6144|dts_time=0.120000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=30000|pos=1023544|flags=K_ frame|media_type=video|stream_index=2|key_frame=1|pkt_pts=6144|pkt_pts_time=0.120000|pkt_dts=6144|pkt_dts_time=0.120000|best_effort_timestamp=6144|best_effort_timestamp_time=0.120000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=1023544|pkt_size=30000|width=100|height=100|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=unknown|color_space=unknown|color_primaries=unknown|color_transfer=unknown|chroma_location=unspecified stream|index=0|codec_name=pcm_s16le|profile=unknown|codec_type=audio|codec_time_base=1/44100|codec_tag_string=PSD[16]|codec_tag=0x10445350|sample_fmt=s16|sample_rate=44100|channels=1|channel_layout=unknown|bits_per_sample=16|id=N/A|r_frame_rate=0/0|avg_frame_rate=0/0|time_base=1/44100|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=705600|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=6|nb_read_packets=6|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|tag:E=mc²|tag:encoder=Lavc pcm_s16le -stream|index=1|codec_name=rawvideo|profile=unknown|codec_type=video|codec_time_base=1/25|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=320|height=240|coded_width=320|coded_height=240|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=4:3|pix_fmt=rgb24|level=-99|color_range=N/A|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=unspecified|field_order=unknown|timecode=N/A|refs=1|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|tag:title=foobar|tag:duration_ts=field-and-tags-conflict-attempt|tag:encoder=Lavc rawvideo -stream|index=2|codec_name=rawvideo|profile=unknown|codec_type=video|codec_time_base=1/25|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=100|height=100|coded_width=100|coded_height=100|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=1:1|pix_fmt=rgb24|level=-99|color_range=N/A|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=unspecified|field_order=unknown|timecode=N/A|refs=1|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|tag:encoder=Lavc rawvideo +stream|index=1|codec_name=rawvideo|profile=unknown|codec_type=video|codec_time_base=1/25|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=320|height=240|coded_width=320|coded_height=240|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=4:3|pix_fmt=rgb24|level=-99|color_range=unknown|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=unspecified|field_order=unknown|timecode=N/A|refs=1|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|tag:title=foobar|tag:duration_ts=field-and-tags-conflict-attempt|tag:encoder=Lavc rawvideo +stream|index=2|codec_name=rawvideo|profile=unknown|codec_type=video|codec_time_base=1/25|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=100|height=100|coded_width=100|coded_height=100|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=1:1|pix_fmt=rgb24|level=-99|color_range=unknown|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=unspecified|field_order=unknown|timecode=N/A|refs=1|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|tag:encoder=Lavc rawvideo format|filename=tests/data/ffprobe-test.nut|nb_streams=3|nb_programs=0|format_name=nut|start_time=0.000000|duration=0.120000|size=1053624|bit_rate=70241600|probe_score=100|tag:title=ffprobe test file|tag:comment='A comment with CSV, XML & JSON special chars': |tag:comment2=I ♥ Üñîçød€ diff --git a/tests/ref/fate/ffprobe_csv b/tests/ref/fate/ffprobe_csv index 90e033f547890..dfbeb40e20ee1 100644 --- a/tests/ref/fate/ffprobe_csv +++ b/tests/ref/fate/ffprobe_csv @@ -27,6 +27,6 @@ frame,video,1,1,6144,0.120000,6144,0.120000,6144,0.120000,2048,0.040000,793120,2 packet,video,2,6144,0.120000,6144,0.120000,2048,0.040000,N/A,N/A,30000,1023544,K_ frame,video,2,1,6144,0.120000,6144,0.120000,6144,0.120000,2048,0.040000,1023544,30000,100,100,rgb24,1:1,I,0,0,0,0,0,unknown,unknown,unknown,unknown,unspecified stream,0,pcm_s16le,unknown,audio,1/44100,PSD[16],0x10445350,s16,44100,1,unknown,16,N/A,0/0,0/0,1/44100,0,0.000000,N/A,N/A,705600,N/A,N/A,N/A,6,6,0,0,0,0,0,0,0,0,0,0,0,0,mc²,Lavc pcm_s16le -stream,1,rawvideo,unknown,video,1/25,RGB[24],0x18424752,320,240,320,240,0,1:1,4:3,rgb24,-99,N/A,unknown,unknown,unknown,unspecified,unknown,N/A,1,N/A,25/1,25/1,1/51200,0,0.000000,N/A,N/A,N/A,N/A,N/A,N/A,4,4,0,0,0,0,0,0,0,0,0,0,0,0,foobar,field-and-tags-conflict-attempt,Lavc rawvideo -stream,2,rawvideo,unknown,video,1/25,RGB[24],0x18424752,100,100,100,100,0,1:1,1:1,rgb24,-99,N/A,unknown,unknown,unknown,unspecified,unknown,N/A,1,N/A,25/1,25/1,1/51200,0,0.000000,N/A,N/A,N/A,N/A,N/A,N/A,4,4,0,0,0,0,0,0,0,0,0,0,0,0,Lavc rawvideo +stream,1,rawvideo,unknown,video,1/25,RGB[24],0x18424752,320,240,320,240,0,1:1,4:3,rgb24,-99,unknown,unknown,unknown,unknown,unspecified,unknown,N/A,1,N/A,25/1,25/1,1/51200,0,0.000000,N/A,N/A,N/A,N/A,N/A,N/A,4,4,0,0,0,0,0,0,0,0,0,0,0,0,foobar,field-and-tags-conflict-attempt,Lavc rawvideo +stream,2,rawvideo,unknown,video,1/25,RGB[24],0x18424752,100,100,100,100,0,1:1,1:1,rgb24,-99,unknown,unknown,unknown,unknown,unspecified,unknown,N/A,1,N/A,25/1,25/1,1/51200,0,0.000000,N/A,N/A,N/A,N/A,N/A,N/A,4,4,0,0,0,0,0,0,0,0,0,0,0,0,Lavc rawvideo format,tests/data/ffprobe-test.nut,3,0,nut,0.000000,0.120000,1053624,70241600,100,ffprobe test file,"'A comment with CSV, XML & JSON special chars': ",I ♥ Üñîçød€ diff --git a/tests/ref/fate/ffprobe_default b/tests/ref/fate/ffprobe_default index bb3cf8a8d2b41..7562867e19cdb 100644 --- a/tests/ref/fate/ffprobe_default +++ b/tests/ref/fate/ffprobe_default @@ -621,7 +621,7 @@ sample_aspect_ratio=1:1 display_aspect_ratio=4:3 pix_fmt=rgb24 level=-99 -color_range=N/A +color_range=unknown color_space=unknown color_transfer=unknown color_primaries=unknown @@ -676,7 +676,7 @@ sample_aspect_ratio=1:1 display_aspect_ratio=1:1 pix_fmt=rgb24 level=-99 -color_range=N/A +color_range=unknown color_space=unknown color_transfer=unknown color_primaries=unknown diff --git a/tests/ref/fate/ffprobe_flat b/tests/ref/fate/ffprobe_flat index ac657db1ee790..fc82ee925d27f 100644 --- a/tests/ref/fate/ffprobe_flat +++ b/tests/ref/fate/ffprobe_flat @@ -562,7 +562,7 @@ streams.stream.1.sample_aspect_ratio="1:1" streams.stream.1.display_aspect_ratio="4:3" streams.stream.1.pix_fmt="rgb24" streams.stream.1.level=-99 -streams.stream.1.color_range="N/A" +streams.stream.1.color_range="unknown" streams.stream.1.color_space="unknown" streams.stream.1.color_transfer="unknown" streams.stream.1.color_primaries="unknown" @@ -615,7 +615,7 @@ streams.stream.2.sample_aspect_ratio="1:1" streams.stream.2.display_aspect_ratio="1:1" streams.stream.2.pix_fmt="rgb24" streams.stream.2.level=-99 -streams.stream.2.color_range="N/A" +streams.stream.2.color_range="unknown" streams.stream.2.color_space="unknown" streams.stream.2.color_transfer="unknown" streams.stream.2.color_primaries="unknown" diff --git a/tests/ref/fate/ffprobe_ini b/tests/ref/fate/ffprobe_ini index 37e1563c38b3b..a78690cc29aa3 100644 --- a/tests/ref/fate/ffprobe_ini +++ b/tests/ref/fate/ffprobe_ini @@ -627,7 +627,7 @@ sample_aspect_ratio=1\:1 display_aspect_ratio=4\:3 pix_fmt=rgb24 level=-99 -color_range=N/A +color_range=unknown color_space=unknown color_transfer=unknown color_primaries=unknown @@ -686,7 +686,7 @@ sample_aspect_ratio=1\:1 display_aspect_ratio=1\:1 pix_fmt=rgb24 level=-99 -color_range=N/A +color_range=unknown color_space=unknown color_transfer=unknown color_primaries=unknown diff --git a/tests/ref/fate/mxf-probe-dnxhd b/tests/ref/fate/mxf-probe-dnxhd index 6c7f4addcf0e6..c4de291d324c4 100644 --- a/tests/ref/fate/mxf-probe-dnxhd +++ b/tests/ref/fate/mxf-probe-dnxhd @@ -123,7 +123,7 @@ sample_aspect_ratio=1:1 display_aspect_ratio=4:3 pix_fmt=yuv422p level=-99 -color_range=N/A +color_range=unknown color_space=bt709 color_transfer=unknown color_primaries=unknown diff --git a/tests/ref/fate/mxf-probe-dv25 b/tests/ref/fate/mxf-probe-dv25 index 036069191f991..6e02dd9802cb2 100644 --- a/tests/ref/fate/mxf-probe-dv25 +++ b/tests/ref/fate/mxf-probe-dv25 @@ -15,7 +15,7 @@ sample_aspect_ratio=16:15 display_aspect_ratio=4:3 pix_fmt=yuv420p level=-99 -color_range=N/A +color_range=unknown color_space=unknown color_transfer=unknown color_primaries=unknown From 913feb6263e0404311f3f791b5d1d013708836d6 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 4 Sep 2017 19:36:09 +0200 Subject: [PATCH 2999/3374] avformat/gdv: Make FixedSize static Signed-off-by: Michael Niedermayer --- libavformat/gdv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/gdv.c b/libavformat/gdv.c index 32209320a72da..a69c349cab3c4 100644 --- a/libavformat/gdv.c +++ b/libavformat/gdv.c @@ -42,7 +42,7 @@ static int gdv_read_probe(AVProbeData *p) return 0; } -struct { +static struct { uint16_t id; uint16_t width; uint16_t height; From 9cb4eb772839c5e1de2855d126bf74ff16d13382 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 5 Sep 2017 00:16:29 +0200 Subject: [PATCH 3000/3374] avformat/mov: Fix DoS in read_tfra() Fixes: Missing EOF check in loop No testcase Found-by: Xiaohei and Wangchu from Alibaba Security Team Signed-off-by: Michael Niedermayer --- libavformat/mov.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libavformat/mov.c b/libavformat/mov.c index 994e9c6ebafc1..2519707345410 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -6094,6 +6094,13 @@ static int read_tfra(MOVContext *mov, AVIOContext *f) } for (i = 0; i < index->item_count; i++) { int64_t time, offset; + + if (avio_feof(f)) { + index->item_count = 0; + av_freep(&index->items); + return AVERROR_INVALIDDATA; + } + if (version == 1) { time = avio_rb64(f); offset = avio_rb64(f); From afc9c683ed9db01edb357bc8c19edad4282b3a97 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 5 Sep 2017 00:16:29 +0200 Subject: [PATCH 3001/3374] avformat/asfdec: Fix DoS in asf_build_simple_index() Fixes: Missing EOF check in loop No testcase Found-by: Xiaohei and Wangchu from Alibaba Security Team Signed-off-by: Michael Niedermayer --- libavformat/asfdec_f.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavformat/asfdec_f.c b/libavformat/asfdec_f.c index f3acbae2801b7..cc648b9a2f055 100644 --- a/libavformat/asfdec_f.c +++ b/libavformat/asfdec_f.c @@ -1610,6 +1610,11 @@ static int asf_build_simple_index(AVFormatContext *s, int stream_index) int64_t pos = s->internal->data_offset + s->packet_size * (int64_t)pktnum; int64_t index_pts = FFMAX(av_rescale(itime, i, 10000) - asf->hdr.preroll, 0); + if (avio_feof(s->pb)) { + ret = AVERROR_INVALIDDATA; + goto end; + } + if (pos != last_pos) { av_log(s, AV_LOG_DEBUG, "pktnum:%d, pktct:%d pts: %"PRId64"\n", pktnum, pktct, index_pts); From e1524de4546beab75cbf600fdde6c14204a66059 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Thu, 7 Sep 2017 16:49:46 +0200 Subject: [PATCH 3002/3374] avfilter/vf_zoompan: fix specific corner case when no frame was ever requested from input Reported-by: Nicolas George Signed-off-by: Paul B Mahol --- libavfilter/vf_zoompan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavfilter/vf_zoompan.c b/libavfilter/vf_zoompan.c index 14d0a1707b5c3..0635171b57877 100644 --- a/libavfilter/vf_zoompan.c +++ b/libavfilter/vf_zoompan.c @@ -133,6 +133,7 @@ static int config_output(AVFilterLink *outlink) outlink->time_base = av_inv_q(s->framerate); outlink->frame_rate = s->framerate; s->desc = av_pix_fmt_desc_get(outlink->format); + s->finished = 1; ret = av_expr_parse(&s->zoom_expr, s->zoom_expr_str, var_names, NULL, NULL, NULL, NULL, 0, ctx); if (ret < 0) From d47159a42d8a0a370fd94b02f7f59e3d4787ddf4 Mon Sep 17 00:00:00 2001 From: Tobias Rapp Date: Mon, 7 Aug 2017 11:55:39 +0200 Subject: [PATCH 3003/3374] fate: add test for asetnsamples filter with padding disabled Adds another test for asetnsamples filter where padding of the last frame is switched off. Renames the existing test to make the difference obvious. Tested-by: Michael Niedermayer Signed-off-by: Tobias Rapp --- tests/fate/filter-audio.mak | 13 +- tests/ref/fate/filter-asetnsamples-nopad | 523 ++++++++++++++++++ ...r-asetnsamples => filter-asetnsamples-pad} | 0 3 files changed, 532 insertions(+), 4 deletions(-) create mode 100644 tests/ref/fate/filter-asetnsamples-nopad rename tests/ref/fate/{filter-asetnsamples => filter-asetnsamples-pad} (100%) diff --git a/tests/fate/filter-audio.mak b/tests/fate/filter-audio.mak index 5035e8f073782..35ad0f8d23e23 100644 --- a/tests/fate/filter-audio.mak +++ b/tests/fate/filter-audio.mak @@ -84,10 +84,15 @@ fate-filter-anequalizer: tests/data/filtergraphs/anequalizer fate-filter-anequalizer: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav fate-filter-anequalizer: CMD = framecrc -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/anequalizer -FATE_AFILTER-$(call FILTERDEMDECENCMUX, ASETNSAMPLES, WAV, PCM_S16LE, PCM_S16LE, WAV) += fate-filter-asetnsamples -fate-filter-asetnsamples: tests/data/asynth-44100-2.wav -fate-filter-asetnsamples: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav -fate-filter-asetnsamples: CMD = framecrc -i $(SRC) -af asetnsamples=512:p=1 +FATE_AFILTER-$(call FILTERDEMDECENCMUX, ASETNSAMPLES, WAV, PCM_S16LE, PCM_S16LE, WAV) += fate-filter-asetnsamples-pad +fate-filter-asetnsamples-pad: tests/data/asynth-44100-2.wav +fate-filter-asetnsamples-pad: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav +fate-filter-asetnsamples-pad: CMD = framecrc -i $(SRC) -af asetnsamples=512:p=1 + +FATE_AFILTER-$(call FILTERDEMDECENCMUX, ASETNSAMPLES, WAV, PCM_S16LE, PCM_S16LE, WAV) += fate-filter-asetnsamples-nopad +fate-filter-asetnsamples-nopad: tests/data/asynth-44100-2.wav +fate-filter-asetnsamples-nopad: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav +fate-filter-asetnsamples-nopad: CMD = framecrc -i $(SRC) -af asetnsamples=512:p=0 FATE_AFILTER-$(call FILTERDEMDECENCMUX, ASETRATE, WAV, PCM_S16LE, PCM_S16LE, WAV) += fate-filter-asetrate fate-filter-asetrate: tests/data/asynth-44100-2.wav diff --git a/tests/ref/fate/filter-asetnsamples-nopad b/tests/ref/fate/filter-asetnsamples-nopad new file mode 100644 index 0000000000000..c1cc01a710221 --- /dev/null +++ b/tests/ref/fate/filter-asetnsamples-nopad @@ -0,0 +1,523 @@ +#tb 0: 1/44100 +#media_type 0: audio +#codec_id 0: pcm_s16le +#sample_rate 0: 44100 +#channel_layout 0: 3 +#channel_layout_name 0: stereo +0, 0, 0, 512, 2048, 0xd2dbf701 +0, 512, 512, 512, 2048, 0xdb22f7bf +0, 1024, 1024, 512, 2048, 0x82a103be +0, 1536, 1536, 512, 2048, 0xa3c707d8 +0, 2048, 2048, 512, 2048, 0x8aaafb8f +0, 2560, 2560, 512, 2048, 0x4bdafefb +0, 3072, 3072, 512, 2048, 0x75a3e833 +0, 3584, 3584, 512, 2048, 0xc130091c +0, 4096, 4096, 512, 2048, 0x99d8f36d +0, 4608, 4608, 512, 2048, 0xaf6efa15 +0, 5120, 5120, 512, 2048, 0xff5f0506 +0, 5632, 5632, 512, 2048, 0xcba4fb5b +0, 6144, 6144, 512, 2048, 0x729309c6 +0, 6656, 6656, 512, 2048, 0x63cdeb09 +0, 7168, 7168, 512, 2048, 0x386cfccb +0, 7680, 7680, 512, 2048, 0x602100c8 +0, 8192, 8192, 512, 2048, 0x3573f565 +0, 8704, 8704, 512, 2048, 0x47b9fce7 +0, 9216, 9216, 512, 2048, 0xd1e90b7a +0, 9728, 9728, 512, 2048, 0xf4c3ef77 +0, 10240, 10240, 512, 2048, 0x59ebfe3f +0, 10752, 10752, 512, 2048, 0x02d4f161 +0, 11264, 11264, 512, 2048, 0xbbf5ff05 +0, 11776, 11776, 512, 2048, 0xe26a047c +0, 12288, 12288, 512, 2048, 0x5452f02b +0, 12800, 12800, 512, 2048, 0x961e1056 +0, 13312, 13312, 512, 2048, 0x9192f803 +0, 13824, 13824, 512, 2048, 0x08d7ff49 +0, 14336, 14336, 512, 2048, 0x7c64ee03 +0, 14848, 14848, 512, 2048, 0xd303f4ff +0, 15360, 15360, 512, 2048, 0xda5902be +0, 15872, 15872, 512, 2048, 0x4096fe6b +0, 16384, 16384, 512, 2048, 0x178e016a +0, 16896, 16896, 512, 2048, 0x046700ac +0, 17408, 17408, 512, 2048, 0x5f20f4ad +0, 17920, 17920, 512, 2048, 0x40e2f093 +0, 18432, 18432, 512, 2048, 0x5c37fccd +0, 18944, 18944, 512, 2048, 0x9f85f963 +0, 19456, 19456, 512, 2048, 0x69461038 +0, 19968, 19968, 512, 2048, 0x1ff1ef4f +0, 20480, 20480, 512, 2048, 0x409304fc +0, 20992, 20992, 512, 2048, 0x36d3fe47 +0, 21504, 21504, 512, 2048, 0xea01f367 +0, 22016, 22016, 512, 2048, 0x11f5fd01 +0, 22528, 22528, 512, 2048, 0x6deeeea5 +0, 23040, 23040, 512, 2048, 0x7eec0d62 +0, 23552, 23552, 512, 2048, 0xb47bfb93 +0, 24064, 24064, 512, 2048, 0x87b8f7a3 +0, 24576, 24576, 512, 2048, 0xcba0fefb +0, 25088, 25088, 512, 2048, 0xa02efb77 +0, 25600, 25600, 512, 2048, 0x1030ecf1 +0, 26112, 26112, 512, 2048, 0xef7f08f4 +0, 26624, 26624, 512, 2048, 0x8d4efa1d +0, 27136, 27136, 512, 2048, 0xe88b070c +0, 27648, 27648, 512, 2048, 0x229cf957 +0, 28160, 28160, 512, 2048, 0xf7f2f3ed +0, 28672, 28672, 512, 2048, 0x8f5f0840 +0, 29184, 29184, 512, 2048, 0x4fcbe815 +0, 29696, 29696, 512, 2048, 0x57dd006a +0, 30208, 30208, 512, 2048, 0xd51af913 +0, 30720, 30720, 512, 2048, 0x63c50a68 +0, 31232, 31232, 512, 2048, 0x100e036c +0, 31744, 31744, 512, 2048, 0x0af0f5ad +0, 32256, 32256, 512, 2048, 0x99d5f9ef +0, 32768, 32768, 512, 2048, 0xd2dbf701 +0, 33280, 33280, 512, 2048, 0xdb22f7bf +0, 33792, 33792, 512, 2048, 0x82a103be +0, 34304, 34304, 512, 2048, 0xa3c707d8 +0, 34816, 34816, 512, 2048, 0x8aaafb8f +0, 35328, 35328, 512, 2048, 0x4bdafefb +0, 35840, 35840, 512, 2048, 0x75a3e833 +0, 36352, 36352, 512, 2048, 0xc130091c +0, 36864, 36864, 512, 2048, 0x99d8f36d +0, 37376, 37376, 512, 2048, 0xaf6efa15 +0, 37888, 37888, 512, 2048, 0xff5f0506 +0, 38400, 38400, 512, 2048, 0xcba4fb5b +0, 38912, 38912, 512, 2048, 0x729309c6 +0, 39424, 39424, 512, 2048, 0x63cdeb09 +0, 39936, 39936, 512, 2048, 0x386cfccb +0, 40448, 40448, 512, 2048, 0x602100c8 +0, 40960, 40960, 512, 2048, 0x3573f565 +0, 41472, 41472, 512, 2048, 0x47b9fce7 +0, 41984, 41984, 512, 2048, 0xd1e90b7a +0, 42496, 42496, 512, 2048, 0xf4c3ef77 +0, 43008, 43008, 512, 2048, 0x59ebfe3f +0, 43520, 43520, 512, 2048, 0x02d4f161 +0, 44032, 44032, 512, 2048, 0x2c09f943 +0, 44544, 44544, 512, 2048, 0x2158dd3f +0, 45056, 45056, 512, 2048, 0x9c150cf4 +0, 45568, 45568, 512, 2048, 0x2f66dfcb +0, 46080, 46080, 512, 2048, 0xd62c05c4 +0, 46592, 46592, 512, 2048, 0x755d0472 +0, 47104, 47104, 512, 2048, 0x4aece261 +0, 47616, 47616, 512, 2048, 0xa4b704ac +0, 48128, 48128, 512, 2048, 0x18410020 +0, 48640, 48640, 512, 2048, 0xa94ff9f5 +0, 49152, 49152, 512, 2048, 0xddf705ba +0, 49664, 49664, 512, 2048, 0xca7af583 +0, 50176, 50176, 512, 2048, 0xf57af029 +0, 50688, 50688, 512, 2048, 0x2cb60d16 +0, 51200, 51200, 512, 2048, 0x97f2f90b +0, 51712, 51712, 512, 2048, 0xd49cfd33 +0, 52224, 52224, 512, 2048, 0x4f56f1dd +0, 52736, 52736, 512, 2048, 0x343bfbc1 +0, 53248, 53248, 512, 2048, 0x2058fd6b +0, 53760, 53760, 512, 2048, 0x243bf921 +0, 54272, 54272, 512, 2048, 0x658b1272 +0, 54784, 54784, 512, 2048, 0xd68fe547 +0, 55296, 55296, 512, 2048, 0xab63068c +0, 55808, 55808, 512, 2048, 0x8f860afa +0, 56320, 56320, 512, 2048, 0x290de797 +0, 56832, 56832, 512, 2048, 0x9b990640 +0, 57344, 57344, 512, 2048, 0x859920bc +0, 57856, 57856, 512, 2048, 0x343f12ae +0, 58368, 58368, 512, 2048, 0xddf318e4 +0, 58880, 58880, 512, 2048, 0x55a6f535 +0, 59392, 59392, 512, 2048, 0x48ce08f6 +0, 59904, 59904, 512, 2048, 0x4e7ff8c3 +0, 60416, 60416, 512, 2048, 0xde8803c0 +0, 60928, 60928, 512, 2048, 0x1b79fe81 +0, 61440, 61440, 512, 2048, 0x853be72f +0, 61952, 61952, 512, 2048, 0xf4cff117 +0, 62464, 62464, 512, 2048, 0xb61df45f +0, 62976, 62976, 512, 2048, 0x6e38fdf7 +0, 63488, 63488, 512, 2048, 0x41c6042c +0, 64000, 64000, 512, 2048, 0xfbb2fd87 +0, 64512, 64512, 512, 2048, 0x6da4eb69 +0, 65024, 65024, 512, 2048, 0x8ff8054e +0, 65536, 65536, 512, 2048, 0x8c44ef81 +0, 66048, 66048, 512, 2048, 0x47faf17b +0, 66560, 66560, 512, 2048, 0x0bd5012a +0, 67072, 67072, 512, 2048, 0xe2d6fd37 +0, 67584, 67584, 512, 2048, 0x128ffedd +0, 68096, 68096, 512, 2048, 0x02f7facd +0, 68608, 68608, 512, 2048, 0x3f43f77d +0, 69120, 69120, 512, 2048, 0x7d65fe19 +0, 69632, 69632, 512, 2048, 0x66c705ba +0, 70144, 70144, 512, 2048, 0x182efbb7 +0, 70656, 70656, 512, 2048, 0xf718e481 +0, 71168, 71168, 512, 2048, 0xbfa10444 +0, 71680, 71680, 512, 2048, 0xc3aa0360 +0, 72192, 72192, 512, 2048, 0x90e0fa59 +0, 72704, 72704, 512, 2048, 0x903706c2 +0, 73216, 73216, 512, 2048, 0xff70001e +0, 73728, 73728, 512, 2048, 0x9240ef79 +0, 74240, 74240, 512, 2048, 0xd72c05c8 +0, 74752, 74752, 512, 2048, 0x9655f5f5 +0, 75264, 75264, 512, 2048, 0x27b60a0e +0, 75776, 75776, 512, 2048, 0x5917f885 +0, 76288, 76288, 512, 2048, 0xe39c107e +0, 76800, 76800, 512, 2048, 0x2a4812c0 +0, 77312, 77312, 512, 2048, 0x39180ac8 +0, 77824, 77824, 512, 2048, 0x8b9efe57 +0, 78336, 78336, 512, 2048, 0xf9eefd25 +0, 78848, 78848, 512, 2048, 0xd3660cae +0, 79360, 79360, 512, 2048, 0xa7ebf7d5 +0, 79872, 79872, 512, 2048, 0x4baaf59f +0, 80384, 80384, 512, 2048, 0x659ff209 +0, 80896, 80896, 512, 2048, 0x1cf80e0e +0, 81408, 81408, 512, 2048, 0x2df9ea69 +0, 81920, 81920, 512, 2048, 0xff8ffa2d +0, 82432, 82432, 512, 2048, 0xdd2732d8 +0, 82944, 82944, 512, 2048, 0xcd6e31ec +0, 83456, 83456, 512, 2048, 0x66d0fb9f +0, 83968, 83968, 512, 2048, 0xbc11f229 +0, 84480, 84480, 512, 2048, 0x3ae00cec +0, 84992, 84992, 512, 2048, 0xb032fb19 +0, 85504, 85504, 512, 2048, 0xb2c90414 +0, 86016, 86016, 512, 2048, 0xb7a1eeaf +0, 86528, 86528, 512, 2048, 0x7a5d0e70 +0, 87040, 87040, 512, 2048, 0x16f11516 +0, 87552, 87552, 512, 2048, 0xfa95fc7f +0, 88064, 88064, 512, 2048, 0x4fe705a6 +0, 88576, 88576, 512, 2048, 0x93d1c311 +0, 89088, 89088, 512, 2048, 0x8230f4f1 +0, 89600, 89600, 512, 2048, 0x6985e58f +0, 90112, 90112, 512, 2048, 0xc4d8f07f +0, 90624, 90624, 512, 2048, 0xb6b4c477 +0, 91136, 91136, 512, 2048, 0xc95bce8b +0, 91648, 91648, 512, 2048, 0x57efd56f +0, 92160, 92160, 512, 2048, 0xd453c295 +0, 92672, 92672, 512, 2048, 0x83c0da97 +0, 93184, 93184, 512, 2048, 0xf6bfe307 +0, 93696, 93696, 512, 2048, 0x0ce8ce27 +0, 94208, 94208, 512, 2048, 0xc925e53f +0, 94720, 94720, 512, 2048, 0x7fe9d121 +0, 95232, 95232, 512, 2048, 0x00d3dcf9 +0, 95744, 95744, 512, 2048, 0x9743d637 +0, 96256, 96256, 512, 2048, 0x5163f37f +0, 96768, 96768, 512, 2048, 0x9736dc27 +0, 97280, 97280, 512, 2048, 0xb0b1e85b +0, 97792, 97792, 512, 2048, 0x589f0c2c +0, 98304, 98304, 512, 2048, 0xb3b7aab9 +0, 98816, 98816, 512, 2048, 0x4df0d46d +0, 99328, 99328, 512, 2048, 0xb917d4db +0, 99840, 99840, 512, 2048, 0x6efdfe65 +0, 100352, 100352, 512, 2048, 0x426bd85d +0, 100864, 100864, 512, 2048, 0x824313f6 +0, 101376, 101376, 512, 2048, 0xe755cf47 +0, 101888, 101888, 512, 2048, 0xe4e8f157 +0, 102400, 102400, 512, 2048, 0x05a8d1cb +0, 102912, 102912, 512, 2048, 0xa405094a +0, 103424, 103424, 512, 2048, 0x5060e40d +0, 103936, 103936, 512, 2048, 0x3a17e253 +0, 104448, 104448, 512, 2048, 0xb8cdd80f +0, 104960, 104960, 512, 2048, 0x7073c517 +0, 105472, 105472, 512, 2048, 0x634b00c4 +0, 105984, 105984, 512, 2048, 0xd8ebd025 +0, 106496, 106496, 512, 2048, 0x3a65cff7 +0, 107008, 107008, 512, 2048, 0x1e61b661 +0, 107520, 107520, 512, 2048, 0x3a1dcae9 +0, 108032, 108032, 512, 2048, 0x8d280542 +0, 108544, 108544, 512, 2048, 0xe918f499 +0, 109056, 109056, 512, 2048, 0x701bd98b +0, 109568, 109568, 512, 2048, 0xd2a8e72f +0, 110080, 110080, 512, 2048, 0x16ededdb +0, 110592, 110592, 512, 2048, 0xfeb1fdbb +0, 111104, 111104, 512, 2048, 0x36b1f4f1 +0, 111616, 111616, 512, 2048, 0x5bc5f27b +0, 112128, 112128, 512, 2048, 0xb72605ee +0, 112640, 112640, 512, 2048, 0x718d112e +0, 113152, 113152, 512, 2048, 0x1ff7f25b +0, 113664, 113664, 512, 2048, 0x1dd115cc +0, 114176, 114176, 512, 2048, 0x1ff7fb15 +0, 114688, 114688, 512, 2048, 0xeb61f241 +0, 115200, 115200, 512, 2048, 0xc3bdeb83 +0, 115712, 115712, 512, 2048, 0xea80011a +0, 116224, 116224, 512, 2048, 0x8d3cee71 +0, 116736, 116736, 512, 2048, 0x8cfbf589 +0, 117248, 117248, 512, 2048, 0xba23f8e3 +0, 117760, 117760, 512, 2048, 0x87a1e86d +0, 118272, 118272, 512, 2048, 0x38e6f1a5 +0, 118784, 118784, 512, 2048, 0xe05a12fe +0, 119296, 119296, 512, 2048, 0x9a14e835 +0, 119808, 119808, 512, 2048, 0x11a11780 +0, 120320, 120320, 512, 2048, 0x0c2308e6 +0, 120832, 120832, 512, 2048, 0xc8adfa4b +0, 121344, 121344, 512, 2048, 0xfe4c118a +0, 121856, 121856, 512, 2048, 0xa6240ac0 +0, 122368, 122368, 512, 2048, 0x3ff3ee2b +0, 122880, 122880, 512, 2048, 0xc6aaf769 +0, 123392, 123392, 512, 2048, 0x4adafcdd +0, 123904, 123904, 512, 2048, 0xabd6e845 +0, 124416, 124416, 512, 2048, 0x25e6076a +0, 124928, 124928, 512, 2048, 0xb6e6d4b9 +0, 125440, 125440, 512, 2048, 0x7251f225 +0, 125952, 125952, 512, 2048, 0xc3b5f751 +0, 126464, 126464, 512, 2048, 0x4f27cecd +0, 126976, 126976, 512, 2048, 0x237c020c +0, 127488, 127488, 512, 2048, 0xb0580556 +0, 128000, 128000, 512, 2048, 0x717008a4 +0, 128512, 128512, 512, 2048, 0xf683e3fb +0, 129024, 129024, 512, 2048, 0x1ddefd33 +0, 129536, 129536, 512, 2048, 0x4c6c1496 +0, 130048, 130048, 512, 2048, 0x67f907fe +0, 130560, 130560, 512, 2048, 0x5bb10938 +0, 131072, 131072, 512, 2048, 0x24a20eac +0, 131584, 131584, 512, 2048, 0xf251effb +0, 132096, 132096, 512, 2048, 0xafd7eb04 +0, 132608, 132608, 512, 2048, 0xa1950245 +0, 133120, 133120, 512, 2048, 0x8cdefb0d +0, 133632, 133632, 512, 2048, 0x5694fa32 +0, 134144, 134144, 512, 2048, 0x0942eeb6 +0, 134656, 134656, 512, 2048, 0x715a01c1 +0, 135168, 135168, 512, 2048, 0x4531f63e +0, 135680, 135680, 512, 2048, 0x214ffbbc +0, 136192, 136192, 512, 2048, 0x0f50fe21 +0, 136704, 136704, 512, 2048, 0xe456046b +0, 137216, 137216, 512, 2048, 0xd6eaff4d +0, 137728, 137728, 512, 2048, 0xd8140634 +0, 138240, 138240, 512, 2048, 0x608e0bff +0, 138752, 138752, 512, 2048, 0x76610cee +0, 139264, 139264, 512, 2048, 0x6b48f0ff +0, 139776, 139776, 512, 2048, 0x03c7f9ce +0, 140288, 140288, 512, 2048, 0xf718fad1 +0, 140800, 140800, 512, 2048, 0x296bef29 +0, 141312, 141312, 512, 2048, 0x2311f2bf +0, 141824, 141824, 512, 2048, 0x069ffe60 +0, 142336, 142336, 512, 2048, 0x6126055d +0, 142848, 142848, 512, 2048, 0x9330eda6 +0, 143360, 143360, 512, 2048, 0xdfbeedc1 +0, 143872, 143872, 512, 2048, 0x8536f1b8 +0, 144384, 144384, 512, 2048, 0xfe30fd72 +0, 144896, 144896, 512, 2048, 0x13320264 +0, 145408, 145408, 512, 2048, 0x83ad09db +0, 145920, 145920, 512, 2048, 0xc08b0b31 +0, 146432, 146432, 512, 2048, 0xda8afea0 +0, 146944, 146944, 512, 2048, 0x0cb3f040 +0, 147456, 147456, 512, 2048, 0x80c0fc17 +0, 147968, 147968, 512, 2048, 0x9d80fdfb +0, 148480, 148480, 512, 2048, 0x9f1af1fd +0, 148992, 148992, 512, 2048, 0x92fef102 +0, 149504, 149504, 512, 2048, 0x5b62f7be +0, 150016, 150016, 512, 2048, 0x25800a5b +0, 150528, 150528, 512, 2048, 0xc660fba3 +0, 151040, 151040, 512, 2048, 0x0e21fbda +0, 151552, 151552, 512, 2048, 0x2e7f027d +0, 152064, 152064, 512, 2048, 0xcf65feb4 +0, 152576, 152576, 512, 2048, 0x4e0ffa6d +0, 153088, 153088, 512, 2048, 0x732bff36 +0, 153600, 153600, 512, 2048, 0x3df20e7e +0, 154112, 154112, 512, 2048, 0x2a5006e5 +0, 154624, 154624, 512, 2048, 0xfd3bfa2a +0, 155136, 155136, 512, 2048, 0x8e73f755 +0, 155648, 155648, 512, 2048, 0x6f93ece1 +0, 156160, 156160, 512, 2048, 0x78a4f735 +0, 156672, 156672, 512, 2048, 0x3a7cfc1c +0, 157184, 157184, 512, 2048, 0xbfc0f795 +0, 157696, 157696, 512, 2048, 0x7a8cfed2 +0, 158208, 158208, 512, 2048, 0x3d0fdee5 +0, 158720, 158720, 512, 2048, 0x902afc78 +0, 159232, 159232, 512, 2048, 0x51dcf0e2 +0, 159744, 159744, 512, 2048, 0x1f59fc00 +0, 160256, 160256, 512, 2048, 0x2dd0f390 +0, 160768, 160768, 512, 2048, 0x2ff30f7c +0, 161280, 161280, 512, 2048, 0x36f508b8 +0, 161792, 161792, 512, 2048, 0x51e8ef2d +0, 162304, 162304, 512, 2048, 0xf9660ed7 +0, 162816, 162816, 512, 2048, 0x50f3fd4d +0, 163328, 163328, 512, 2048, 0x366ef6b9 +0, 163840, 163840, 512, 2048, 0xf023f17a +0, 164352, 164352, 512, 2048, 0xf6c6f1f0 +0, 164864, 164864, 512, 2048, 0x6d1dfebf +0, 165376, 165376, 512, 2048, 0xead60e1d +0, 165888, 165888, 512, 2048, 0xbe5201a6 +0, 166400, 166400, 512, 2048, 0xb1940269 +0, 166912, 166912, 512, 2048, 0xb6cdf350 +0, 167424, 167424, 512, 2048, 0x7c44f80e +0, 167936, 167936, 512, 2048, 0x1fff03ef +0, 168448, 168448, 512, 2048, 0x514807c6 +0, 168960, 168960, 512, 2048, 0xe04eede7 +0, 169472, 169472, 512, 2048, 0x347e0272 +0, 169984, 169984, 512, 2048, 0x8c00fb96 +0, 170496, 170496, 512, 2048, 0x6660f607 +0, 171008, 171008, 512, 2048, 0xe9a7017d +0, 171520, 171520, 512, 2048, 0xca58e8ae +0, 172032, 172032, 512, 2048, 0x795af92a +0, 172544, 172544, 512, 2048, 0x7d6aee1b +0, 173056, 173056, 512, 2048, 0x4ab9f58f +0, 173568, 173568, 512, 2048, 0x3b91f617 +0, 174080, 174080, 512, 2048, 0x09e1f7d7 +0, 174592, 174592, 512, 2048, 0xc9280753 +0, 175104, 175104, 512, 2048, 0x8620f662 +0, 175616, 175616, 512, 2048, 0x6bb103fa +0, 176128, 176128, 512, 2048, 0xcfee0371 +0, 176640, 176640, 512, 2048, 0xe1e20294 +0, 177152, 177152, 512, 2048, 0xdb98fea4 +0, 177664, 177664, 512, 2048, 0x8d1fddeb +0, 178176, 178176, 512, 2048, 0x4e7501bf +0, 178688, 178688, 512, 2048, 0x68d0fb95 +0, 179200, 179200, 512, 2048, 0xf685001e +0, 179712, 179712, 512, 2048, 0x75dafa10 +0, 180224, 180224, 512, 2048, 0x534fe772 +0, 180736, 180736, 512, 2048, 0x28b4fe18 +0, 181248, 181248, 512, 2048, 0x2ba00678 +0, 181760, 181760, 512, 2048, 0xc884e0b7 +0, 182272, 182272, 512, 2048, 0x6ae40787 +0, 182784, 182784, 512, 2048, 0xc53cf35d +0, 183296, 183296, 512, 2048, 0x738d06b4 +0, 183808, 183808, 512, 2048, 0xb551f582 +0, 184320, 184320, 512, 2048, 0x8a5a8764 +0, 184832, 184832, 512, 2048, 0x711f175e +0, 185344, 185344, 512, 2048, 0xe5e1ed43 +0, 185856, 185856, 512, 2048, 0x34adfaeb +0, 186368, 186368, 512, 2048, 0x79fb0142 +0, 186880, 186880, 512, 2048, 0xf4f6ffeb +0, 187392, 187392, 512, 2048, 0xd3540a6b +0, 187904, 187904, 512, 2048, 0x49caf3c6 +0, 188416, 188416, 512, 2048, 0xc1db05b7 +0, 188928, 188928, 512, 2048, 0x26f0114a +0, 189440, 189440, 512, 2048, 0x576eead9 +0, 189952, 189952, 512, 2048, 0xb87f00e9 +0, 190464, 190464, 512, 2048, 0x470d030f +0, 190976, 190976, 512, 2048, 0x60ec02b2 +0, 191488, 191488, 512, 2048, 0xb84a0b44 +0, 192000, 192000, 512, 2048, 0x39b6ec45 +0, 192512, 192512, 512, 2048, 0x1e07e580 +0, 193024, 193024, 512, 2048, 0xfa3cf5d6 +0, 193536, 193536, 512, 2048, 0x0801f9b8 +0, 194048, 194048, 512, 2048, 0x55981a80 +0, 194560, 194560, 512, 2048, 0x9510f6ad +0, 195072, 195072, 512, 2048, 0x7d03fcc7 +0, 195584, 195584, 512, 2048, 0xf17bf84e +0, 196096, 196096, 512, 2048, 0x6d1ffe4c +0, 196608, 196608, 512, 2048, 0x91e210f9 +0, 197120, 197120, 512, 2048, 0xb881fa44 +0, 197632, 197632, 512, 2048, 0xb7cdf1f3 +0, 198144, 198144, 512, 2048, 0x1e9b17b5 +0, 198656, 198656, 512, 2048, 0x74dff0e3 +0, 199168, 199168, 512, 2048, 0x1f55050e +0, 199680, 199680, 512, 2048, 0x7498f1b8 +0, 200192, 200192, 512, 2048, 0x2d7c02e9 +0, 200704, 200704, 512, 2048, 0x8c84a5c4 +0, 201216, 201216, 512, 2048, 0x6feae10d +0, 201728, 201728, 512, 2048, 0xfda90b28 +0, 202240, 202240, 512, 2048, 0xb230fd72 +0, 202752, 202752, 512, 2048, 0x6298f728 +0, 203264, 203264, 512, 2048, 0xef60f871 +0, 203776, 203776, 512, 2048, 0x14e7ee01 +0, 204288, 204288, 512, 2048, 0x98d704a5 +0, 204800, 204800, 512, 2048, 0x1ccaf2b4 +0, 205312, 205312, 512, 2048, 0xb9ede721 +0, 205824, 205824, 512, 2048, 0x8c570d92 +0, 206336, 206336, 512, 2048, 0x2d7ef782 +0, 206848, 206848, 512, 2048, 0xa84cf55e +0, 207360, 207360, 512, 2048, 0x8033f5b9 +0, 207872, 207872, 512, 2048, 0x27f3ed27 +0, 208384, 208384, 512, 2048, 0xa6730c25 +0, 208896, 208896, 512, 2048, 0x489bf2fd +0, 209408, 209408, 512, 2048, 0xe1e20294 +0, 209920, 209920, 512, 2048, 0xdb98fea4 +0, 210432, 210432, 512, 2048, 0x8d1fddeb +0, 210944, 210944, 512, 2048, 0x4e7501bf +0, 211456, 211456, 512, 2048, 0x68d0fb95 +0, 211968, 211968, 512, 2048, 0xf685001e +0, 212480, 212480, 512, 2048, 0x75dafa10 +0, 212992, 212992, 512, 2048, 0x534fe772 +0, 213504, 213504, 512, 2048, 0x28b4fe18 +0, 214016, 214016, 512, 2048, 0x2ba00678 +0, 214528, 214528, 512, 2048, 0xc884e0b7 +0, 215040, 215040, 512, 2048, 0x6ae40787 +0, 215552, 215552, 512, 2048, 0xc53cf35d +0, 216064, 216064, 512, 2048, 0x738d06b4 +0, 216576, 216576, 512, 2048, 0xb551f582 +0, 217088, 217088, 512, 2048, 0x8a5a8764 +0, 217600, 217600, 512, 2048, 0x711f175e +0, 218112, 218112, 512, 2048, 0xe5e1ed43 +0, 218624, 218624, 512, 2048, 0x34adfaeb +0, 219136, 219136, 512, 2048, 0x79fb0142 +0, 219648, 219648, 512, 2048, 0xf4f6ffeb +0, 220160, 220160, 512, 2048, 0xd3540a6b +0, 220672, 220672, 512, 2048, 0x49caf3c6 +0, 221184, 221184, 512, 2048, 0xc1db05b7 +0, 221696, 221696, 512, 2048, 0x26f0114a +0, 222208, 222208, 512, 2048, 0x576eead9 +0, 222720, 222720, 512, 2048, 0xb87f00e9 +0, 223232, 223232, 512, 2048, 0x470d030f +0, 223744, 223744, 512, 2048, 0x60ec02b2 +0, 224256, 224256, 512, 2048, 0xb84a0b44 +0, 224768, 224768, 512, 2048, 0x39b6ec45 +0, 225280, 225280, 512, 2048, 0x1e07e580 +0, 225792, 225792, 512, 2048, 0xfa3cf5d6 +0, 226304, 226304, 512, 2048, 0x0801f9b8 +0, 226816, 226816, 512, 2048, 0x55981a80 +0, 227328, 227328, 512, 2048, 0x9510f6ad +0, 227840, 227840, 512, 2048, 0x7d03fcc7 +0, 228352, 228352, 512, 2048, 0xf17bf84e +0, 228864, 228864, 512, 2048, 0x6d1ffe4c +0, 229376, 229376, 512, 2048, 0x91e210f9 +0, 229888, 229888, 512, 2048, 0xb881fa44 +0, 230400, 230400, 512, 2048, 0xb7cdf1f3 +0, 230912, 230912, 512, 2048, 0x1e9b17b5 +0, 231424, 231424, 512, 2048, 0x74dff0e3 +0, 231936, 231936, 512, 2048, 0x1f55050e +0, 232448, 232448, 512, 2048, 0x7498f1b8 +0, 232960, 232960, 512, 2048, 0x2d7c02e9 +0, 233472, 233472, 512, 2048, 0x8c84a5c4 +0, 233984, 233984, 512, 2048, 0x6feae10d +0, 234496, 234496, 512, 2048, 0xfda90b28 +0, 235008, 235008, 512, 2048, 0xb230fd72 +0, 235520, 235520, 512, 2048, 0x6298f728 +0, 236032, 236032, 512, 2048, 0xef60f871 +0, 236544, 236544, 512, 2048, 0x14e7ee01 +0, 237056, 237056, 512, 2048, 0x98d704a5 +0, 237568, 237568, 512, 2048, 0x1ccaf2b4 +0, 238080, 238080, 512, 2048, 0xb9ede721 +0, 238592, 238592, 512, 2048, 0x8c570d92 +0, 239104, 239104, 512, 2048, 0x2d7ef782 +0, 239616, 239616, 512, 2048, 0xa84cf55e +0, 240128, 240128, 512, 2048, 0x8033f5b9 +0, 240640, 240640, 512, 2048, 0x27f3ed27 +0, 241152, 241152, 512, 2048, 0xa6730c25 +0, 241664, 241664, 512, 2048, 0x489bf2fd +0, 242176, 242176, 512, 2048, 0xe1e20294 +0, 242688, 242688, 512, 2048, 0xdb98fea4 +0, 243200, 243200, 512, 2048, 0x8d1fddeb +0, 243712, 243712, 512, 2048, 0x4e7501bf +0, 244224, 244224, 512, 2048, 0x68d0fb95 +0, 244736, 244736, 512, 2048, 0xf685001e +0, 245248, 245248, 512, 2048, 0x75dafa10 +0, 245760, 245760, 512, 2048, 0x534fe772 +0, 246272, 246272, 512, 2048, 0x28b4fe18 +0, 246784, 246784, 512, 2048, 0x2ba00678 +0, 247296, 247296, 512, 2048, 0xc884e0b7 +0, 247808, 247808, 512, 2048, 0x6ae40787 +0, 248320, 248320, 512, 2048, 0xc53cf35d +0, 248832, 248832, 512, 2048, 0x738d06b4 +0, 249344, 249344, 512, 2048, 0xb551f582 +0, 249856, 249856, 512, 2048, 0x8a5a8764 +0, 250368, 250368, 512, 2048, 0x711f175e +0, 250880, 250880, 512, 2048, 0xe5e1ed43 +0, 251392, 251392, 512, 2048, 0x34adfaeb +0, 251904, 251904, 512, 2048, 0x79fb0142 +0, 252416, 252416, 512, 2048, 0xf4f6ffeb +0, 252928, 252928, 512, 2048, 0xd3540a6b +0, 253440, 253440, 512, 2048, 0x49caf3c6 +0, 253952, 253952, 512, 2048, 0xc1db05b7 +0, 254464, 254464, 512, 2048, 0x26f0114a +0, 254976, 254976, 512, 2048, 0x576eead9 +0, 255488, 255488, 512, 2048, 0xb87f00e9 +0, 256000, 256000, 512, 2048, 0x470d030f +0, 256512, 256512, 512, 2048, 0x60ec02b2 +0, 257024, 257024, 512, 2048, 0xb84a0b44 +0, 257536, 257536, 512, 2048, 0x39b6ec45 +0, 258048, 258048, 512, 2048, 0x1e07e580 +0, 258560, 258560, 512, 2048, 0xfa3cf5d6 +0, 259072, 259072, 512, 2048, 0x0801f9b8 +0, 259584, 259584, 512, 2048, 0x55981a80 +0, 260096, 260096, 512, 2048, 0x9510f6ad +0, 260608, 260608, 512, 2048, 0x7d03fcc7 +0, 261120, 261120, 512, 2048, 0xf17bf84e +0, 261632, 261632, 512, 2048, 0x6d1ffe4c +0, 262144, 262144, 512, 2048, 0x91e210f9 +0, 262656, 262656, 512, 2048, 0xb881fa44 +0, 263168, 263168, 512, 2048, 0xb7cdf1f3 +0, 263680, 263680, 512, 2048, 0x1e9b17b5 +0, 264192, 264192, 408, 1632, 0xf412313e diff --git a/tests/ref/fate/filter-asetnsamples b/tests/ref/fate/filter-asetnsamples-pad similarity index 100% rename from tests/ref/fate/filter-asetnsamples rename to tests/ref/fate/filter-asetnsamples-pad From f5a9c63401c840024defeb50a3dab9f86551b67e Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Thu, 7 Sep 2017 10:45:54 +0200 Subject: [PATCH 3004/3374] lavfi: guess a timestamp for compat status change. Use the earliest input with the same status. If that fails, print a warning and use the earliest source. With this change, simple filter forward correctly the timestamp of EOF. Filters that are supposed to change it should be updated to actually forward it. --- libavfilter/avfilter.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 6a97456054205..e5c123818231b 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -427,6 +427,24 @@ int ff_request_frame(AVFilterLink *link) return 0; } +static int64_t guess_status_pts(AVFilterContext *ctx, int status) +{ + unsigned i; + int64_t r = INT64_MAX; + + for (i = 0; i < ctx->nb_inputs; i++) + if (ctx->inputs[i]->status_out == status) + r = FFMIN(r, ctx->inputs[i]->current_pts); + if (r < INT64_MAX) + return r; + av_log(ctx, AV_LOG_WARNING, "EOF timestamp not reliable\n"); + for (i = 0; i < ctx->nb_inputs; i++) + r = FFMIN(r, ctx->inputs[i]->status_in_pts); + if (r < INT64_MAX) + return r; + return AV_NOPTS_VALUE; +} + static int ff_request_frame_to_filter(AVFilterLink *link) { int ret = -1; @@ -440,7 +458,7 @@ static int ff_request_frame_to_filter(AVFilterLink *link) ret = ff_request_frame(link->src->inputs[0]); if (ret < 0) { if (ret != AVERROR(EAGAIN) && ret != link->status_in) - ff_avfilter_link_set_in_status(link, ret, AV_NOPTS_VALUE); + ff_avfilter_link_set_in_status(link, ret, guess_status_pts(link->src, ret)); if (ret == AVERROR_EOF) ret = 0; } From dfed8e2cbb48d750a16b6c2b4f764250f69ab4df Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 3 Apr 2017 13:49:59 +0200 Subject: [PATCH 3005/3374] ffmpeg: rename a variable. Makes the reason of the "FIXME" comment more obvious. Avoid name conflicts for the next commit. --- ffmpeg.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index ccb6638e0a414..c8ee64621c7a4 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -2628,7 +2628,7 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo // while we have more to decode or while the decoder did output something on EOF while (ist->decoding_needed) { - int64_t duration = 0; + int64_t duration_dts = 0; int got_output = 0; int decode_failed = 0; @@ -2645,22 +2645,22 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo &decode_failed); if (!repeating || !pkt || got_output) { if (pkt && pkt->duration) { - duration = av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q); + duration_dts = av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q); } else if(ist->dec_ctx->framerate.num != 0 && ist->dec_ctx->framerate.den != 0) { int ticks= av_stream_get_parser(ist->st) ? av_stream_get_parser(ist->st)->repeat_pict+1 : ist->dec_ctx->ticks_per_frame; - duration = ((int64_t)AV_TIME_BASE * + duration_dts = ((int64_t)AV_TIME_BASE * ist->dec_ctx->framerate.den * ticks) / ist->dec_ctx->framerate.num / ist->dec_ctx->ticks_per_frame; } - if(ist->dts != AV_NOPTS_VALUE && duration) { - ist->next_dts += duration; + if(ist->dts != AV_NOPTS_VALUE && duration_dts) { + ist->next_dts += duration_dts; }else ist->next_dts = AV_NOPTS_VALUE; } if (got_output) - ist->next_pts += duration; //FIXME the duration is not correct in some cases + ist->next_pts += duration_dts; //FIXME the duration is not correct in some cases break; case AVMEDIA_TYPE_SUBTITLE: if (repeating) From 36c111c40f4bd7da114df0e9c484833aa2cdf2dc Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 3 Apr 2017 14:40:44 +0200 Subject: [PATCH 3006/3374] ffmpeg: use reordered duration for stream PTS. --- ffmpeg.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index c8ee64621c7a4..b95addd277f25 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -2368,7 +2368,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output, return err < 0 ? err : ret; } -static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int eof, +static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int64_t *duration_pts, int eof, int *decode_failed) { AVFrame *decoded_frame; @@ -2459,6 +2459,7 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int eo ist->hwaccel_retrieved_pix_fmt = decoded_frame->format; best_effort_timestamp= decoded_frame->best_effort_timestamp; + *duration_pts = decoded_frame->pkt_duration; if (ist->framerate.num) best_effort_timestamp = ist->cfr_next_pts++; @@ -2629,6 +2630,7 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo // while we have more to decode or while the decoder did output something on EOF while (ist->decoding_needed) { int64_t duration_dts = 0; + int64_t duration_pts = 0; int got_output = 0; int decode_failed = 0; @@ -2641,7 +2643,7 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo &decode_failed); break; case AVMEDIA_TYPE_VIDEO: - ret = decode_video (ist, repeating ? NULL : &avpkt, &got_output, !pkt, + ret = decode_video (ist, repeating ? NULL : &avpkt, &got_output, &duration_pts, !pkt, &decode_failed); if (!repeating || !pkt || got_output) { if (pkt && pkt->duration) { @@ -2660,7 +2662,7 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo } if (got_output) - ist->next_pts += duration_dts; //FIXME the duration is not correct in some cases + ist->next_pts += av_rescale_q(duration_pts, ist->st->time_base, AV_TIME_BASE_Q); break; case AVMEDIA_TYPE_SUBTITLE: if (repeating) From 5ba2aef6ec47689300debd3ddd1f39cad010a971 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Mon, 3 Apr 2017 15:01:45 +0200 Subject: [PATCH 3007/3374] lavfi/buffersrc: add av_buffersrc_close(). --- doc/APIchanges | 3 +++ libavfilter/buffersrc.c | 22 ++++++++++++---------- libavfilter/buffersrc.h | 8 ++++++++ libavfilter/version.h | 2 +- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index b98a3419c4761..cc67cbf6f8767 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-09-08 - xxxxxxx - lavfi 6.103.100 - buffersrc.h + Add av_buffersrc_close(). + 2017-09-04 - xxxxxxx - lavc 57.105.100 - avcodec.h Add AV_HWACCEL_CODEC_CAP_EXPERIMENTAL, replacing the deprecated HWACCEL_CODEC_CAP_EXPERIMENTAL flag. diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c index e8f59c2de71a3..ad5aedd5f7de9 100644 --- a/libavfilter/buffersrc.c +++ b/libavfilter/buffersrc.c @@ -196,16 +196,9 @@ static int av_buffersrc_add_frame_internal(AVFilterContext *ctx, s->nb_failed_requests = 0; - if (!frame) { - s->eof = 1; - ff_avfilter_link_set_in_status(ctx->outputs[0], AVERROR_EOF, AV_NOPTS_VALUE); - if ((flags & AV_BUFFERSRC_FLAG_PUSH)) { - ret = push_frame(ctx->graph); - if (ret < 0) - return ret; - } - return 0; - } else if (s->eof) + if (!frame) + return av_buffersrc_close(ctx, AV_NOPTS_VALUE, flags); + if (s->eof) return AVERROR(EINVAL); refcounted = !!frame->buf[0]; @@ -267,6 +260,15 @@ static int av_buffersrc_add_frame_internal(AVFilterContext *ctx, return 0; } +int av_buffersrc_close(AVFilterContext *ctx, int64_t pts, unsigned flags) +{ + BufferSourceContext *s = ctx->priv; + + s->eof = 1; + ff_avfilter_link_set_in_status(ctx->outputs[0], AVERROR_EOF, pts); + return (flags & AV_BUFFERSRC_FLAG_PUSH) ? push_frame(ctx->graph) : 0; +} + static av_cold int init_video(AVFilterContext *ctx) { BufferSourceContext *c = ctx->priv; diff --git a/libavfilter/buffersrc.h b/libavfilter/buffersrc.h index e42c78196bd85..0652113f2bc13 100644 --- a/libavfilter/buffersrc.h +++ b/libavfilter/buffersrc.h @@ -193,6 +193,14 @@ av_warn_unused_result int av_buffersrc_add_frame_flags(AVFilterContext *buffer_src, AVFrame *frame, int flags); +/** + * Close the buffer source after EOF. + * + * This is similar to passing NULL to av_buffersrc_add_frame_flags() + * except it takes the timestamp of the EOF, i.e. the timestamp of the end + * of the last frame. + */ +int av_buffersrc_close(AVFilterContext *ctx, int64_t pts, unsigned flags); /** * @} diff --git a/libavfilter/version.h b/libavfilter/version.h index 4b16de1f8ae63..6d14cff1fbb67 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 6 -#define LIBAVFILTER_VERSION_MINOR 102 +#define LIBAVFILTER_VERSION_MINOR 103 #define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ From 8043d8eb3bf5e93709212850feb3441b9ec41b25 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Thu, 6 Apr 2017 10:40:12 +0200 Subject: [PATCH 3008/3374] ffmpeg: send EOF pts to filters. --- ffmpeg.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index b95addd277f25..1d248bc269d80 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -2223,14 +2223,14 @@ static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame) return 0; } -static int ifilter_send_eof(InputFilter *ifilter) +static int ifilter_send_eof(InputFilter *ifilter, int64_t pts) { int i, j, ret; ifilter->eof = 1; if (ifilter->filter) { - ret = av_buffersrc_add_frame_flags(ifilter->filter, NULL, AV_BUFFERSRC_FLAG_PUSH); + ret = av_buffersrc_close(ifilter->filter, pts, AV_BUFFERSRC_FLAG_PUSH); if (ret < 0) return ret; } else { @@ -2581,8 +2581,12 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output, static int send_filter_eof(InputStream *ist) { int i, ret; + /* TODO keep pts also in stream time base to avoid converting back */ + int64_t pts = av_rescale_q_rnd(ist->pts, AV_TIME_BASE_Q, ist->st->time_base, + AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX); + for (i = 0; i < ist->nb_filters; i++) { - ret = ifilter_send_eof(ist->filters[i]); + ret = ifilter_send_eof(ist->filters[i], pts); if (ret < 0) return ret; } From 2e79813a8ec7998ae4e86688e929a5ca9a131ae7 Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Mon, 4 Sep 2017 18:01:32 +0530 Subject: [PATCH 3009/3374] avcodec/mips: Improve vp9 lpf msa functions Updated VP9_LPF_FILTER4_4W macro to process on 8 bit data. Replaced VP9_LPF_FILTER4_8W with VP9_LPF_FILTER4_4W. Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/vp9_lpf_msa.c | 94 ++++++----------------------------- 1 file changed, 14 insertions(+), 80 deletions(-) diff --git a/libavcodec/mips/vp9_lpf_msa.c b/libavcodec/mips/vp9_lpf_msa.c index eef8afc4828e1..c82a9e98bc036 100644 --- a/libavcodec/mips/vp9_lpf_msa.c +++ b/libavcodec/mips/vp9_lpf_msa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Shivraj Patil (Shivraj.Patil@imgtec.com) + * Copyright (c) 2015 - 2017 Shivraj Patil (Shivraj.Patil@imgtec.com) * * This file is part of FFmpeg. * @@ -22,63 +22,12 @@ #include "libavutil/mips/generic_macros_msa.h" #include "vp9dsp_mips.h" -#define VP9_LPF_FILTER4_8W(p1_in, p0_in, q0_in, q1_in, mask_in, hev_in, \ - p1_out, p0_out, q0_out, q1_out) \ -{ \ - v16i8 p1_m, p0_m, q0_m, q1_m, q0_sub_p0, filt_sign; \ - v16i8 filt, filt1, filt2, cnst4b, cnst3b; \ - v8i16 q0_sub_p0_r, filt_r, cnst3h; \ - \ - p1_m = (v16i8) __msa_xori_b(p1_in, 0x80); \ - p0_m = (v16i8) __msa_xori_b(p0_in, 0x80); \ - q0_m = (v16i8) __msa_xori_b(q0_in, 0x80); \ - q1_m = (v16i8) __msa_xori_b(q1_in, 0x80); \ - \ - filt = __msa_subs_s_b(p1_m, q1_m); \ - filt = filt & (v16i8) hev_in; \ - q0_sub_p0 = q0_m - p0_m; \ - filt_sign = __msa_clti_s_b(filt, 0); \ - \ - cnst3h = __msa_ldi_h(3); \ - q0_sub_p0_r = (v8i16) __msa_ilvr_b(q0_sub_p0, q0_sub_p0); \ - q0_sub_p0_r = __msa_dotp_s_h((v16i8) q0_sub_p0_r, (v16i8) cnst3h); \ - filt_r = (v8i16) __msa_ilvr_b(filt_sign, filt); \ - filt_r += q0_sub_p0_r; \ - filt_r = __msa_sat_s_h(filt_r, 7); \ - \ - /* combine left and right part */ \ - filt = __msa_pckev_b((v16i8) filt_r, (v16i8) filt_r); \ - \ - filt = filt & (v16i8) mask_in; \ - cnst4b = __msa_ldi_b(4); \ - filt1 = __msa_adds_s_b(filt, cnst4b); \ - filt1 >>= 3; \ - \ - cnst3b = __msa_ldi_b(3); \ - filt2 = __msa_adds_s_b(filt, cnst3b); \ - filt2 >>= 3; \ - \ - q0_m = __msa_subs_s_b(q0_m, filt1); \ - q0_out = __msa_xori_b((v16u8) q0_m, 0x80); \ - p0_m = __msa_adds_s_b(p0_m, filt2); \ - p0_out = __msa_xori_b((v16u8) p0_m, 0x80); \ - \ - filt = __msa_srari_b(filt1, 1); \ - hev_in = __msa_xori_b((v16u8) hev_in, 0xff); \ - filt = filt & (v16i8) hev_in; \ - \ - q1_m = __msa_subs_s_b(q1_m, filt); \ - q1_out = __msa_xori_b((v16u8) q1_m, 0x80); \ - p1_m = __msa_adds_s_b(p1_m, filt); \ - p1_out = __msa_xori_b((v16u8) p1_m, 0x80); \ -} - #define VP9_LPF_FILTER4_4W(p1_in, p0_in, q0_in, q1_in, mask_in, hev_in, \ p1_out, p0_out, q0_out, q1_out) \ { \ - v16i8 p1_m, p0_m, q0_m, q1_m, q0_sub_p0, filt_sign; \ - v16i8 filt, filt1, filt2, cnst4b, cnst3b; \ - v8i16 q0_sub_p0_r, q0_sub_p0_l, filt_l, filt_r, cnst3h; \ + v16i8 p1_m, p0_m, q0_m, q1_m, q0_sub_p0, filt, filt1, filt2; \ + const v16i8 cnst4b = __msa_ldi_b(4); \ + const v16i8 cnst3b = __msa_ldi_b(3); \ \ p1_m = (v16i8) __msa_xori_b(p1_in, 0x80); \ p0_m = (v16i8) __msa_xori_b(p0_in, 0x80); \ @@ -89,30 +38,15 @@ \ filt = filt & (v16i8) hev_in; \ \ - q0_sub_p0 = q0_m - p0_m; \ - filt_sign = __msa_clti_s_b(filt, 0); \ - \ - cnst3h = __msa_ldi_h(3); \ - q0_sub_p0_r = (v8i16) __msa_ilvr_b(q0_sub_p0, q0_sub_p0); \ - q0_sub_p0_r = __msa_dotp_s_h((v16i8) q0_sub_p0_r, (v16i8) cnst3h); \ - filt_r = (v8i16) __msa_ilvr_b(filt_sign, filt); \ - filt_r += q0_sub_p0_r; \ - filt_r = __msa_sat_s_h(filt_r, 7); \ - \ - q0_sub_p0_l = (v8i16) __msa_ilvl_b(q0_sub_p0, q0_sub_p0); \ - q0_sub_p0_l = __msa_dotp_s_h((v16i8) q0_sub_p0_l, (v16i8) cnst3h); \ - filt_l = (v8i16) __msa_ilvl_b(filt_sign, filt); \ - filt_l += q0_sub_p0_l; \ - filt_l = __msa_sat_s_h(filt_l, 7); \ - \ - filt = __msa_pckev_b((v16i8) filt_l, (v16i8) filt_r); \ + q0_sub_p0 = __msa_subs_s_b(q0_m, p0_m); \ + filt = __msa_adds_s_b(filt, q0_sub_p0); \ + filt = __msa_adds_s_b(filt, q0_sub_p0); \ + filt = __msa_adds_s_b(filt, q0_sub_p0); \ filt = filt & (v16i8) mask_in; \ \ - cnst4b = __msa_ldi_b(4); \ filt1 = __msa_adds_s_b(filt, cnst4b); \ filt1 >>= 3; \ \ - cnst3b = __msa_ldi_b(3); \ filt2 = __msa_adds_s_b(filt, cnst3b); \ filt2 >>= 3; \ \ @@ -277,7 +211,7 @@ void ff_loop_filter_v_4_8_msa(uint8_t *src, ptrdiff_t pitch, LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, mask, flat); - VP9_LPF_FILTER4_8W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, + VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, q1_out); p1_d = __msa_copy_u_d((v2i64) p1_out, 0); @@ -342,7 +276,7 @@ void ff_loop_filter_v_8_8_msa(uint8_t *src, ptrdiff_t pitch, LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, mask, flat); VP9_FLAT4(p3, p2, p0, q0, q2, q3, flat); - VP9_LPF_FILTER4_8W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, + VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, q1_out); flat = (v16u8) __msa_ilvr_d((v2i64) zero, (v2i64) flat); @@ -1065,7 +999,7 @@ void ff_loop_filter_v_16_8_msa(uint8_t *src, ptrdiff_t pitch, LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, mask, flat); VP9_FLAT4(p3, p2, p0, q0, q2, q3, flat); - VP9_LPF_FILTER4_8W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, + VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, q1_out); flat = (v16u8) __msa_ilvr_d((v2i64) zero, (v2i64) flat); @@ -1280,7 +1214,7 @@ void ff_loop_filter_h_4_8_msa(uint8_t *src, ptrdiff_t pitch, p3, p2, p1, p0, q0, q1, q2, q3); LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, mask, flat); - VP9_LPF_FILTER4_8W(p1, p0, q0, q1, mask, hev, p1, p0, q0, q1); + VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1, p0, q0, q1); ILVR_B2_SH(p0, p1, q1, q0, vec0, vec1); ILVRL_H2_SH(vec1, vec0, vec2, vec3); @@ -1367,7 +1301,7 @@ void ff_loop_filter_h_8_8_msa(uint8_t *src, ptrdiff_t pitch, /* flat4 */ VP9_FLAT4(p3, p2, p0, q0, q2, q3, flat); /* filter4 */ - VP9_LPF_FILTER4_8W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, + VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, q1_out); flat = (v16u8) __msa_ilvr_d((v2i64) zero, (v2i64) flat); @@ -1868,7 +1802,7 @@ static int32_t vp9_vt_lpf_t4_and_t8_8w(uint8_t *src, uint8_t *filter48, /* flat4 */ VP9_FLAT4(p3, p2, p0, q0, q2, q3, flat); /* filter4 */ - VP9_LPF_FILTER4_8W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, + VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, q1_out); flat = (v16u8) __msa_ilvr_d((v2i64) zero, (v2i64) flat); From c75b23cbea79abc8129b7ed1d546e1c853be615c Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Mon, 4 Sep 2017 18:02:09 +0530 Subject: [PATCH 3010/3374] avcodec/mips: Improve vp9 idct msa functions Removed memset calls. Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/vp9_idct_msa.c | 118 +++++++++++++++++++-------------- 1 file changed, 70 insertions(+), 48 deletions(-) diff --git a/libavcodec/mips/vp9_idct_msa.c b/libavcodec/mips/vp9_idct_msa.c index 25ea16c72a060..bd762f269667d 100644 --- a/libavcodec/mips/vp9_idct_msa.c +++ b/libavcodec/mips/vp9_idct_msa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Shivraj Patil (Shivraj.Patil@imgtec.com) + * Copyright (c) 2015 - 2017 Shivraj Patil (Shivraj.Patil@imgtec.com) * * This file is part of FFmpeg. * @@ -352,6 +352,7 @@ static void vp9_idct4x4_1_add_msa(int16_t *input, uint8_t *dst, out = ROUND_POWER_OF_TWO((out * cospi_16_64), VP9_DCT_CONST_BITS); out = ROUND_POWER_OF_TWO(out, 4); vec = __msa_fill_h(out); + input[0] = 0; ADDBLK_ST4x4_UB(vec, vec, vec, vec, dst, dst_stride); } @@ -360,9 +361,11 @@ static void vp9_idct4x4_colcol_addblk_msa(int16_t *input, uint8_t *dst, int32_t dst_stride) { v8i16 in0, in1, in2, in3; + v8i16 zero = { 0 }; /* load vector elements of 4x4 block */ LD4x4_SH(input, in0, in1, in2, in3); + ST_SH2(zero, zero, input, 8); /* rows */ VP9_IDCT4x4(in0, in1, in2, in3, in0, in1, in2, in3); /* columns */ @@ -377,9 +380,11 @@ static void vp9_iadst4x4_colcol_addblk_msa(int16_t *input, uint8_t *dst, int32_t dst_stride) { v8i16 in0, in1, in2, in3; + v8i16 zero = { 0 }; /* load vector elements of 4x4 block */ LD4x4_SH(input, in0, in1, in2, in3); + ST_SH2(zero, zero, input, 8); /* rows */ VP9_IADST4x4(in0, in1, in2, in3, in0, in1, in2, in3); /* columns */ @@ -394,9 +399,11 @@ static void vp9_iadst_idct_4x4_add_msa(int16_t *input, uint8_t *dst, int32_t dst_stride, int32_t eob) { v8i16 in0, in1, in2, in3; + v8i16 zero = { 0 }; /* load vector elements of 4x4 block */ LD4x4_SH(input, in0, in1, in2, in3); + ST_SH2(zero, zero, input, 8); /* cols */ VP9_IADST4x4(in0, in1, in2, in3, in0, in1, in2, in3); /* columns */ @@ -411,9 +418,11 @@ static void vp9_idct_iadst_4x4_add_msa(int16_t *input, uint8_t *dst, int32_t dst_stride, int32_t eob) { v8i16 in0, in1, in2, in3; + v8i16 zero = { 0 }; /* load vector elements of 4x4 block */ LD4x4_SH(input, in0, in1, in2, in3); + ST_SH2(zero, zero, input, 8); /* cols */ VP9_IDCT4x4(in0, in1, in2, in3, in0, in1, in2, in3); /* columns */ @@ -585,6 +594,7 @@ static void vp9_idct8x8_1_add_msa(int16_t *input, uint8_t *dst, out = ROUND_POWER_OF_TWO((out * cospi_16_64), VP9_DCT_CONST_BITS); val = ROUND_POWER_OF_TWO(out, 5); vec = __msa_fill_h(val); + input[0] = 0; VP9_ADDBLK_ST8x4_UB(dst, dst_stride, vec, vec, vec, vec); dst += (4 * dst_stride); @@ -601,9 +611,9 @@ static void vp9_idct8x8_12_colcol_addblk_msa(int16_t *input, uint8_t *dst, /* load vector elements of 8x8 block */ LD_SH8(input, 8, in0, in1, in2, in3, in4, in5, in6, in7); + ST_SH8(zero, zero, zero, zero, zero, zero, zero, zero, input, 8); ILVR_D2_SH(in1, in0, in3, in2, in0, in1); ILVR_D2_SH(in5, in4, in7, in6, in2, in3); - //TRANSPOSE8X4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3); /* stage1 */ ILVL_H2_SH(in3, in0, in2, in1, s0, s1); @@ -659,9 +669,11 @@ static void vp9_idct8x8_colcol_addblk_msa(int16_t *input, uint8_t *dst, int32_t dst_stride) { v8i16 in0, in1, in2, in3, in4, in5, in6, in7; + v8i16 zero = { 0 }; /* load vector elements of 8x8 block */ LD_SH8(input, 8, in0, in1, in2, in3, in4, in5, in6, in7); + ST_SH8(zero, zero, zero, zero, zero, zero, zero, zero, input, 8); /* 1D idct8x8 */ VP9_IDCT8x8_1D(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4, in5, in6, in7); @@ -689,10 +701,11 @@ static void vp9_iadst8x8_colcol_addblk_msa(int16_t *input, uint8_t *dst, v8i16 out0, out1, out2, out3, out4, out5, out6, out7; v8i16 cnst0, cnst1, cnst2, cnst3, cnst4; v8i16 temp0, temp1, temp2, temp3, s0, s1; - v16i8 zero = { 0 }; + v8i16 zero = { 0 }; /* load vector elements of 8x8 block */ LD_SH8(input, 8, in0, in1, in2, in3, in4, in5, in6, in7); + ST_SH8(zero, zero, zero, zero, zero, zero, zero, zero, input, 8); /* 1D adst8x8 */ VP9_ADST8(in0, in1, in2, in3, in4, in5, in6, in7, @@ -736,13 +749,13 @@ static void vp9_iadst8x8_colcol_addblk_msa(int16_t *input, uint8_t *dst, dst0 = LD_UB(dst + 0 * dst_stride); dst7 = LD_UB(dst + 7 * dst_stride); - res0 = (v8i16) __msa_ilvr_b(zero, (v16i8) dst0); + res0 = (v8i16) __msa_ilvr_b((v16i8) zero, (v16i8) dst0); res0 += out0; res0 = CLIP_SH_0_255(res0); res0 = (v8i16) __msa_pckev_b((v16i8) res0, (v16i8) res0); ST8x1_UB(res0, dst); - res7 = (v8i16) __msa_ilvr_b(zero, (v16i8) dst7); + res7 = (v8i16) __msa_ilvr_b((v16i8) zero, (v16i8) dst7); res7 += out7; res7 = CLIP_SH_0_255(res7); res7 = (v8i16) __msa_pckev_b((v16i8) res7, (v16i8) res7); @@ -809,9 +822,11 @@ static void vp9_iadst_idct_8x8_add_msa(int16_t *input, uint8_t *dst, int32_t dst_stride, int32_t eob) { v8i16 in0, in1, in2, in3, in4, in5, in6, in7; + v8i16 zero = { 0 }; /* load vector elements of 8x8 block */ LD_SH8(input, 8, in1, in6, in3, in4, in5, in2, in7, in0); + ST_SH8(zero, zero, zero, zero, zero, zero, zero, zero, input, 8); /* 1D idct8x8 */ VP9_IADST8x8_1D(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4, in5, in6, in7); @@ -834,9 +849,11 @@ static void vp9_idct_iadst_8x8_add_msa(int16_t *input, uint8_t *dst, int32_t dst_stride, int32_t eob) { v8i16 in0, in1, in2, in3, in4, in5, in6, in7; + v8i16 zero = { 0 }; /* load vector elements of 8x8 block */ LD_SH8(input, 8, in0, in1, in2, in3, in4, in5, in6, in7); + ST_SH8(zero, zero, zero, zero, zero, zero, zero, zero, input, 8); /* 1D idct8x8 */ VP9_IDCT8x8_1D(in0, in1, in2, in3, in4, in5, in6, in7, @@ -937,12 +954,16 @@ static void vp9_idct16_1d_columns_addblk_msa(int16_t *input, uint8_t *dst, v8i16 reg0, reg2, reg4, reg6, reg8, reg10, reg12, reg14; v8i16 reg3, reg13, reg11, reg5, reg7, reg9, reg1, reg15; v8i16 tmp5, tmp6, tmp7; + v8i16 zero = { 0 }; + + /* load up 8x16 */ + LD_SH16(input, 16, + reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7, + reg8, reg9, reg10, reg11, reg12, reg13, reg14, reg15); - /* load up 8x8 */ - LD_SH8(input, 16, reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7); + ST_SH8(zero, zero, zero, zero, zero, zero, zero, zero, input, 16); input += 8 * 16; - /* load bottom 8x8 */ - LD_SH8(input, 16, reg8, reg9, reg10, reg11, reg12, reg13, reg14, reg15); + ST_SH8(zero, zero, zero, zero, zero, zero, zero, zero, input, 16); VP9_DOTP_CONST_PAIR(reg2, reg14, cospi_28_64, cospi_4_64, reg2, reg14); VP9_DOTP_CONST_PAIR(reg10, reg6, cospi_12_64, cospi_20_64, reg10, reg6); @@ -1036,12 +1057,16 @@ static void vp9_idct16_1d_columns_msa(int16_t *input, int16_t *output) v8i16 reg0, reg2, reg4, reg6, reg8, reg10, reg12, reg14; v8i16 reg3, reg13, reg11, reg5, reg7, reg9, reg1, reg15; v8i16 tmp5, tmp6, tmp7; + v8i16 zero = { 0 }; - /* load up 8x8 */ - LD_SH8(input, 16, reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7); - input += 8 * 16; - /* load bottom 8x8 */ - LD_SH8(input, 16, reg8, reg9, reg10, reg11, reg12, reg13, reg14, reg15); + /* load up 8x16 */ + LD_SH16(input, 16, + reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7, + reg8, reg9, reg10, reg11, reg12, reg13, reg14, reg15); + + ST_SH8(zero, zero, zero, zero, zero, zero, zero, zero, input, 16); + input += 16 * 8; + ST_SH8(zero, zero, zero, zero, zero, zero, zero, zero, input, 16); VP9_DOTP_CONST_PAIR(reg2, reg14, cospi_28_64, cospi_4_64, reg2, reg14); VP9_DOTP_CONST_PAIR(reg10, reg6, cospi_12_64, cospi_20_64, reg10, reg6); @@ -1141,11 +1166,11 @@ static void vp9_idct16x16_1_add_msa(int16_t *input, uint8_t *dst, out = ROUND_POWER_OF_TWO((input[0] * cospi_16_64), VP9_DCT_CONST_BITS); out = ROUND_POWER_OF_TWO((out * cospi_16_64), VP9_DCT_CONST_BITS); out = ROUND_POWER_OF_TWO(out, 6); + input[0] = 0; vec = __msa_fill_h(out); - for (i = 4; i--;) - { + for (i = 4; i--;) { LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); UNPCK_UB_SH(dst0, res0, res4); UNPCK_UB_SH(dst1, res1, res5); @@ -1229,12 +1254,17 @@ static void vp9_iadst16_1d_columns_msa(int16_t *input, int16_t *output) { v8i16 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15; v8i16 l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15; + v8i16 zero = { 0 }; /* load input data */ LD_SH16(input, 16, l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15); + ST_SH8(zero, zero, zero, zero, zero, zero, zero, zero, input, 16); + input += 16 * 8; + ST_SH8(zero, zero, zero, zero, zero, zero, zero, zero, input, 16); + /* ADST in horizontal */ VP9_IADST8x16_1D(l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, @@ -1591,9 +1621,11 @@ static void vp9_idct8x32_column_even_process_store(int16_t *tmp_buf, v8i16 vec0, vec1, vec2, vec3, loc0, loc1, loc2, loc3; v8i16 reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; v8i16 stp0, stp1, stp2, stp3, stp4, stp5, stp6, stp7; + v8i16 zero = { 0 }; /* Even stage 1 */ LD_SH8(tmp_buf, (4 * 32), reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7); + ST_SH8(zero, zero, zero, zero, zero, zero, zero, zero, tmp_buf, (4 * 32)); tmp_buf += (2 * 32); VP9_DOTP_CONST_PAIR(reg1, reg7, cospi_28_64, cospi_4_64, reg1, reg7); @@ -1613,6 +1645,7 @@ static void vp9_idct8x32_column_even_process_store(int16_t *tmp_buf, /* Even stage 2 */ /* Load 8 */ LD_SH8(tmp_buf, (4 * 32), reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7); + ST_SH8(zero, zero, zero, zero, zero, zero, zero, zero, tmp_buf, (4 * 32)); VP9_DOTP_CONST_PAIR(reg0, reg7, cospi_30_64, cospi_2_64, reg0, reg7); VP9_DOTP_CONST_PAIR(reg4, reg3, cospi_14_64, cospi_18_64, reg4, reg3); @@ -1671,6 +1704,7 @@ static void vp9_idct8x32_column_odd_process_store(int16_t *tmp_buf, { v8i16 vec0, vec1, vec2, vec3, loc0, loc1, loc2, loc3; v8i16 reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; + v8i16 zero = { 0 }; /* Odd stage 1 */ reg0 = LD_SH(tmp_buf + 32); @@ -1682,6 +1716,15 @@ static void vp9_idct8x32_column_odd_process_store(int16_t *tmp_buf, reg6 = LD_SH(tmp_buf + 25 * 32); reg7 = LD_SH(tmp_buf + 31 * 32); + ST_SH(zero, tmp_buf + 32); + ST_SH(zero, tmp_buf + 7 * 32); + ST_SH(zero, tmp_buf + 9 * 32); + ST_SH(zero, tmp_buf + 15 * 32); + ST_SH(zero, tmp_buf + 17 * 32); + ST_SH(zero, tmp_buf + 23 * 32); + ST_SH(zero, tmp_buf + 25 * 32); + ST_SH(zero, tmp_buf + 31 * 32); + VP9_DOTP_CONST_PAIR(reg0, reg7, cospi_31_64, cospi_1_64, reg0, reg7); VP9_DOTP_CONST_PAIR(reg4, reg3, cospi_15_64, cospi_17_64, reg3, reg4); VP9_DOTP_CONST_PAIR(reg2, reg5, cospi_23_64, cospi_9_64, reg2, reg5); @@ -1723,6 +1766,15 @@ static void vp9_idct8x32_column_odd_process_store(int16_t *tmp_buf, reg6 = LD_SH(tmp_buf + 27 * 32); reg7 = LD_SH(tmp_buf + 29 * 32); + ST_SH(zero, tmp_buf + 3 * 32); + ST_SH(zero, tmp_buf + 5 * 32); + ST_SH(zero, tmp_buf + 11 * 32); + ST_SH(zero, tmp_buf + 13 * 32); + ST_SH(zero, tmp_buf + 19 * 32); + ST_SH(zero, tmp_buf + 21 * 32); + ST_SH(zero, tmp_buf + 27 * 32); + ST_SH(zero, tmp_buf + 29 * 32); + VP9_DOTP_CONST_PAIR(reg1, reg6, cospi_27_64, cospi_5_64, reg1, reg6); VP9_DOTP_CONST_PAIR(reg5, reg2, cospi_11_64, cospi_21_64, reg2, reg5); VP9_DOTP_CONST_PAIR(reg3, reg4, cospi_19_64, cospi_13_64, reg3, reg4); @@ -1901,11 +1953,11 @@ static void vp9_idct32x32_1_add_msa(int16_t *input, uint8_t *dst, out = ROUND_POWER_OF_TWO((input[0] * cospi_16_64), VP9_DCT_CONST_BITS); out = ROUND_POWER_OF_TWO((out * cospi_16_64), VP9_DCT_CONST_BITS); out = ROUND_POWER_OF_TWO(out, 6); + input[0] = 0; vec = __msa_fill_h(out); - for (i = 16; i--;) - { + for (i = 16; i--;) { LD_UB2(dst, 16, dst0, dst1); LD_UB2(dst + dst_stride, 16, dst2, dst3); @@ -2004,11 +2056,9 @@ void ff_idct_idct_4x4_add_msa(uint8_t *dst, ptrdiff_t stride, { if (eob > 1) { vp9_idct4x4_colcol_addblk_msa(block, dst, stride); - memset(block, 0, 4 * 4 * sizeof(*block)); } else { vp9_idct4x4_1_add_msa(block, dst, stride); - block[0] = 0; } } @@ -2017,60 +2067,41 @@ void ff_idct_idct_8x8_add_msa(uint8_t *dst, ptrdiff_t stride, { if (eob == 1) { vp9_idct8x8_1_add_msa(block, dst, stride); - block[0] = 0; } else if (eob <= 12) { vp9_idct8x8_12_colcol_addblk_msa(block, dst, stride); - memset(block, 0, 4 * 8 * sizeof(*block)); } else { vp9_idct8x8_colcol_addblk_msa(block, dst, stride); - memset(block, 0, 8 * 8 * sizeof(*block)); } } void ff_idct_idct_16x16_add_msa(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob) { - int i; - if (eob == 1) { /* DC only DCT coefficient. */ vp9_idct16x16_1_add_msa(block, dst, stride); - block[0] = 0; } else if (eob <= 10) { vp9_idct16x16_10_colcol_addblk_msa(block, dst, stride); - for (i = 0; i < 4; ++i) { - memset(block, 0, 4 * sizeof(*block)); - block += 16; - } } else { vp9_idct16x16_colcol_addblk_msa(block, dst, stride); - memset(block, 0, 16 * 16 * sizeof(*block)); } } void ff_idct_idct_32x32_add_msa(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob) { - int i; - if (eob == 1) { vp9_idct32x32_1_add_msa(block, dst, stride); - block[0] = 0; } else if (eob <= 34) { vp9_idct32x32_34_colcol_addblk_msa(block, dst, stride); - for (i = 0; i < 8; ++i) { - memset(block, 0, 8 * sizeof(*block)); - block += 32; - } } else { vp9_idct32x32_colcol_addblk_msa(block, dst, stride); - memset(block, 0, 32 * 32 * sizeof(*block)); } } @@ -2078,61 +2109,52 @@ void ff_iadst_iadst_4x4_add_msa(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob) { vp9_iadst4x4_colcol_addblk_msa(block, dst, stride); - memset(block, 0, 4 * 4 * sizeof(*block)); } void ff_iadst_iadst_8x8_add_msa(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob) { vp9_iadst8x8_colcol_addblk_msa(block, dst, stride); - memset(block, 0, 8 * 8 * sizeof(*block)); } void ff_iadst_iadst_16x16_add_msa(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob) { vp9_iadst16x16_colcol_addblk_msa(block, dst, stride); - memset(block, 0, 16 * 16 * sizeof(*block)); } void ff_idct_iadst_4x4_add_msa(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob) { vp9_idct_iadst_4x4_add_msa(block, dst, stride, eob); - memset(block, 0, 4 * 4 * sizeof(*block)); } void ff_idct_iadst_8x8_add_msa(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob) { vp9_idct_iadst_8x8_add_msa(block, dst, stride, eob); - memset(block, 0, 8 * 8 * sizeof(*block)); } void ff_idct_iadst_16x16_add_msa(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob) { vp9_idct_iadst_16x16_add_msa(block, dst, stride, eob); - memset(block, 0, 16 * 16 * sizeof(*block)); } void ff_iadst_idct_4x4_add_msa(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob) { vp9_iadst_idct_4x4_add_msa(block, dst, stride, eob); - memset(block, 0, 4 * 4 * sizeof(*block)); } void ff_iadst_idct_8x8_add_msa(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob) { vp9_iadst_idct_8x8_add_msa(block, dst, stride, eob); - memset(block, 0, 8 * 8 * sizeof(*block)); } void ff_iadst_idct_16x16_add_msa(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob) { vp9_iadst_idct_16x16_add_msa(block, dst, stride, eob); - memset(block, 0, 16 * 16 * sizeof(*block)); } From 9b2c3c406fdd2393408847a6180b451c46d417db Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Mon, 4 Sep 2017 18:02:36 +0530 Subject: [PATCH 3011/3374] avcodec/mips: Improve vp9 mc msa functions Load the specific destination bytes instead of MSA load and pack. Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/h264qpel_msa.c | 17 +- libavcodec/mips/vp9_mc_msa.c | 759 +++++++++++++--------------- libavutil/mips/generic_macros_msa.h | 24 +- 3 files changed, 369 insertions(+), 431 deletions(-) diff --git a/libavcodec/mips/h264qpel_msa.c b/libavcodec/mips/h264qpel_msa.c index c38f1f7a42029..43d21f7d855c9 100644 --- a/libavcodec/mips/h264qpel_msa.c +++ b/libavcodec/mips/h264qpel_msa.c @@ -1479,7 +1479,8 @@ static void avc_luma_hz_and_aver_dst_8x8_msa(const uint8_t *src, plus20b, res0, res1, res2, res3); SRARI_H4_SH(res0, res1, res2, res3, 5); SAT_SH4_SH(res0, res1, res2, res3, 7); - CONVERT_UB_AVG_ST8x4_UB(res0, res1, res2, res3, dst0, dst1, dst2, dst3, + ILVR_D2_UB(dst1, dst0, dst3, dst2, dst0, dst1); + CONVERT_UB_AVG_ST8x4_UB(res0, res1, res2, res3, dst0, dst1, dst, dst_stride); dst += (4 * dst_stride); @@ -1825,8 +1826,8 @@ static void avc_luma_vt_and_aver_dst_8x8_msa(const uint8_t *src, SRARI_H4_SH(out0, out1, out2, out3, 5); SAT_SH4_SH(out0, out1, out2, out3, 7); LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - - CONVERT_UB_AVG_ST8x4_UB(out0, out1, out2, out3, dst0, dst1, dst2, dst3, + ILVR_D2_UB(dst1, dst0, dst3, dst2, dst0, dst1); + CONVERT_UB_AVG_ST8x4_UB(out0, out1, out2, out3, dst0, dst1, dst, dst_stride); dst += (4 * dst_stride); @@ -2229,7 +2230,8 @@ static void avc_luma_mid_and_aver_dst_8w_msa(const uint8_t *src, res3 = AVC_CALC_DPADD_H_6PIX_2COEFF_SH(hz_out3, hz_out4, hz_out5, hz_out6, hz_out7, hz_out8); LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - CONVERT_UB_AVG_ST8x4_UB(res0, res1, res2, res3, dst0, dst1, dst2, dst3, + ILVR_D2_UB(dst1, dst0, dst3, dst2, dst0, dst1); + CONVERT_UB_AVG_ST8x4_UB(res0, res1, res2, res3, dst0, dst1, dst, dst_stride); dst += (4 * dst_stride); @@ -2518,8 +2520,8 @@ static void avc_luma_midv_qrt_and_aver_dst_8w_msa(const uint8_t *src, res1 = __msa_aver_s_h(res2, res3); res2 = __msa_aver_s_h(res4, res5); res3 = __msa_aver_s_h(res6, res7); - - CONVERT_UB_AVG_ST8x4_UB(res0, res1, res2, res3, dst0, dst1, dst2, dst3, + ILVR_D2_UB(dst1, dst0, dst3, dst2, dst0, dst1); + CONVERT_UB_AVG_ST8x4_UB(res0, res1, res2, res3, dst0, dst1, dst, dst_stride); dst += (4 * dst_stride); @@ -2676,7 +2678,8 @@ static void avc_luma_hv_qrt_and_aver_dst_8x8_msa(const uint8_t *src_x, out3 = __msa_srari_h((hz_out3 + vert_out3), 1); SAT_SH4_SH(out0, out1, out2, out3, 7); - CONVERT_UB_AVG_ST8x4_UB(out0, out1, out2, out3, dst0, dst1, dst2, dst3, + ILVR_D2_UB(dst1, dst0, dst3, dst2, dst0, dst1); + CONVERT_UB_AVG_ST8x4_UB(out0, out1, out2, out3, dst0, dst1, dst, dst_stride); dst += (4 * dst_stride); diff --git a/libavcodec/mips/vp9_mc_msa.c b/libavcodec/mips/vp9_mc_msa.c index 1671d973a4a0d..749e8cbe82c0b 100644 --- a/libavcodec/mips/vp9_mc_msa.c +++ b/libavcodec/mips/vp9_mc_msa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Shivraj Patil (Shivraj.Patil@imgtec.com) + * Copyright (c) 2015 - 2017 Shivraj Patil (Shivraj.Patil@imgtec.com) * * This file is part of FFmpeg. * @@ -145,16 +145,15 @@ static const int8_t vp9_bilinear_filters_msa[15][2] = { ST_UB(tmp_m, (pdst)); \ } -#define PCKEV_AVG_ST8x4_UB(in1, dst0, in2, dst1, in3, dst2, in4, dst3, \ - pdst, stride) \ -{ \ - v16u8 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ - uint8_t *pdst_m = (uint8_t *) (pdst); \ - \ - PCKEV_B2_UB(in2, in1, in4, in3, tmp0_m, tmp1_m); \ - PCKEV_D2_UB(dst1, dst0, dst3, dst2, tmp2_m, tmp3_m); \ - AVER_UB2_UB(tmp0_m, tmp2_m, tmp1_m, tmp3_m, tmp0_m, tmp1_m); \ - ST8x4_UB(tmp0_m, tmp1_m, pdst_m, stride); \ +#define PCKEV_AVG_ST8x4_UB(in0, in1, in2, in3, dst0, dst1, \ + pdst, stride) \ +{ \ + v16u8 tmp0_m, tmp1_m; \ + uint8_t *pdst_m = (uint8_t *) (pdst); \ + \ + PCKEV_B2_UB(in1, in0, in3, in2, tmp0_m, tmp1_m); \ + AVER_UB2_UB(tmp0_m, dst0, tmp1_m, dst1, tmp0_m, tmp1_m); \ + ST8x4_UB(tmp0_m, tmp1_m, pdst_m, stride); \ } static void common_hz_8t_4x4_msa(const uint8_t *src, int32_t src_stride, @@ -224,64 +223,6 @@ static void common_hz_8t_4x8_msa(const uint8_t *src, int32_t src_stride, ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); } -static void common_hz_8t_4x16_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - const int8_t *filter) -{ - v16u8 mask0, mask1, mask2, mask3, out; - v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; - v8i16 filt, out0, out1, out2, out3; - - mask0 = LD_UB(&mc_filt_mask_arr[16]); - src -= 3; - - /* rearranging filter */ - filt = LD_SH(filter); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - mask3 = mask0 + 6; - - LD_SB4(src, src_stride, src0, src1, src2, src3); - XORI_B4_128_SB(src0, src1, src2, src3); - src += (4 * src_stride); - HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - mask3, filt0, filt1, filt2, filt3, out0, out1); - LD_SB4(src, src_stride, src0, src1, src2, src3); - XORI_B4_128_SB(src0, src1, src2, src3); - src += (4 * src_stride); - HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - mask3, filt0, filt1, filt2, filt3, out2, out3); - SRARI_H4_SH(out0, out1, out2, out3, 7); - SAT_SH4_SH(out0, out1, out2, out3, 7); - out = PCKEV_XORI128_UB(out0, out1); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); - dst += (4 * dst_stride); - out = PCKEV_XORI128_UB(out2, out3); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); - dst += (4 * dst_stride); - - LD_SB4(src, src_stride, src0, src1, src2, src3); - XORI_B4_128_SB(src0, src1, src2, src3); - src += (4 * src_stride); - HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - mask3, filt0, filt1, filt2, filt3, out0, out1); - LD_SB4(src, src_stride, src0, src1, src2, src3); - XORI_B4_128_SB(src0, src1, src2, src3); - src += (4 * src_stride); - HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - mask3, filt0, filt1, filt2, filt3, out2, out3); - - SRARI_H4_SH(out0, out1, out2, out3, 7); - SAT_SH4_SH(out0, out1, out2, out3, 7); - out = PCKEV_XORI128_UB(out0, out1); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); - dst += (4 * dst_stride); - out = PCKEV_XORI128_UB(out2, out3); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); -} - static void common_hz_8t_4w_msa(const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, const int8_t *filter, int32_t height) @@ -290,8 +231,6 @@ static void common_hz_8t_4w_msa(const uint8_t *src, int32_t src_stride, common_hz_8t_4x4_msa(src, src_stride, dst, dst_stride, filter); } else if (8 == height) { common_hz_8t_4x8_msa(src, src_stride, dst, dst_stride, filter); - } else if (16 == height) { - common_hz_8t_4x16_msa(src, src_stride, dst, dst_stride, filter); } } @@ -1050,8 +989,9 @@ static void common_hz_8t_and_aver_dst_4x4_msa(const uint8_t *src, uint8_t *dst, int32_t dst_stride, const int8_t *filter) { + uint32_t tp0, tp1, tp2, tp3; v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; - v16u8 dst0, dst1, dst2, dst3, res2, res3; + v16u8 dst0, res; v16u8 mask0, mask1, mask2, mask3; v8i16 filt, res0, res1; @@ -1070,14 +1010,13 @@ static void common_hz_8t_and_aver_dst_4x4_msa(const uint8_t *src, XORI_B4_128_SB(src0, src1, src2, src3); HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, filt0, filt1, filt2, filt3, res0, res1); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); + LW4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); SRARI_H2_SH(res0, res1, 7); SAT_SH2_SH(res0, res1, 7); - PCKEV_B2_UB(res0, res0, res1, res1, res2, res3); - ILVR_W2_UB(dst1, dst0, dst3, dst2, dst0, dst2); - XORI_B2_128_UB(res2, res3); - AVER_UB2_UB(res2, dst0, res3, dst2, res2, res3); - ST4x4_UB(res2, res3, 0, 1, 0, 1, dst, dst_stride); + res = PCKEV_XORI128_UB(res0, res1); + res = (v16u8) __msa_aver_u_b(res, dst0); + ST4x4_UB(res, res, 0, 1, 2, 3, dst, dst_stride); } static void common_hz_8t_and_aver_dst_4x8_msa(const uint8_t *src, @@ -1085,9 +1024,10 @@ static void common_hz_8t_and_aver_dst_4x8_msa(const uint8_t *src, uint8_t *dst, int32_t dst_stride, const int8_t *filter) { + uint32_t tp0, tp1, tp2, tp3; v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; v16u8 mask0, mask1, mask2, mask3, res0, res1, res2, res3; - v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; + v16u8 dst0, dst1; v8i16 filt, vec0, vec1, vec2, vec3; mask0 = LD_UB(&mc_filt_mask_arr[16]); @@ -1104,7 +1044,10 @@ static void common_hz_8t_and_aver_dst_4x8_msa(const uint8_t *src, LD_SB4(src, src_stride, src0, src1, src2, src3); XORI_B4_128_SB(src0, src1, src2, src3); src += (4 * src_stride); - LD_UB8(dst, dst_stride, dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7); + LW4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); + LW4(dst + 4 * dst_stride, dst_stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, dst1); HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, filt0, filt1, filt2, filt3, vec0, vec1); LD_SB4(src, src_stride, src0, src1, src2, src3); @@ -1117,10 +1060,7 @@ static void common_hz_8t_and_aver_dst_4x8_msa(const uint8_t *src, res0, res1, res2, res3); ILVR_D2_UB(res1, res0, res3, res2, res0, res2); XORI_B2_128_UB(res0, res2); - ILVR_W4_UB(dst1, dst0, dst3, dst2, dst5, dst4, dst7, dst6, - dst0, dst2, dst4, dst6); - ILVR_D2_UB(dst2, dst0, dst6, dst4, dst0, dst4); - AVER_UB2_UB(res0, dst0, res2, dst4, res0, res2); + AVER_UB2_UB(res0, dst0, res2, dst1, res0, res2); ST4x8_UB(res0, res2, dst, dst_stride); } @@ -1146,8 +1086,9 @@ static void common_hz_8t_and_aver_dst_8w_msa(const uint8_t *src, int32_t height) { int32_t loop_cnt; + int64_t tp0, tp1, tp2, tp3; v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; - v16u8 mask0, mask1, mask2, mask3, dst0, dst1, dst2, dst3; + v16u8 mask0, mask1, mask2, mask3, dst0, dst1; v8i16 filt, out0, out1, out2, out3; mask0 = LD_UB(&mc_filt_mask_arr[0]); @@ -1168,10 +1109,12 @@ static void common_hz_8t_and_aver_dst_8w_msa(const uint8_t *src, HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, filt0, filt1, filt2, filt3, out0, out1, out2, out3); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); + LD4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, dst0); + INSERT_D2_UB(tp2, tp3, dst1); SRARI_H4_SH(out0, out1, out2, out3, 7); SAT_SH4_SH(out0, out1, out2, out3, 7); - CONVERT_UB_AVG_ST8x4_UB(out0, out1, out2, out3, dst0, dst1, dst2, dst3, + CONVERT_UB_AVG_ST8x4_UB(out0, out1, out2, out3, dst0, dst1, dst, dst_stride); dst += (4 * dst_stride); } @@ -1363,8 +1306,9 @@ static void common_vt_8t_and_aver_dst_4w_msa(const uint8_t *src, int32_t height) { uint32_t loop_cnt; + uint32_t tp0, tp1, tp2, tp3; v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - v16u8 dst0, dst1, dst2, dst3, out; + v16u8 dst0, out; v16i8 src10_r, src32_r, src54_r, src76_r, src98_r, src21_r, src43_r; v16i8 src65_r, src87_r, src109_r, src2110, src4332, src6554, src8776; v16i8 src10998, filt0, filt1, filt2, filt3; @@ -1389,7 +1333,8 @@ static void common_vt_8t_and_aver_dst_4w_msa(const uint8_t *src, LD_SB4(src, src_stride, src7, src8, src9, src10); src += (4 * src_stride); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); + LW4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); ILVR_B4_SB(src7, src6, src8, src7, src9, src8, src10, src9, src76_r, src87_r, src98_r, src109_r); ILVR_D2_SB(src87_r, src76_r, src109_r, src98_r, src8776, src10998); @@ -1401,9 +1346,6 @@ static void common_vt_8t_and_aver_dst_4w_msa(const uint8_t *src, SRARI_H2_SH(out10, out32, 7); SAT_SH2_SH(out10, out32, 7); out = PCKEV_XORI128_UB(out10, out32); - ILVR_W2_UB(dst1, dst0, dst3, dst2, dst0, dst2); - - dst0 = (v16u8) __msa_ilvr_d((v2i64) dst2, (v2i64) dst0); out = __msa_aver_u_b(out, dst0); ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); @@ -1423,8 +1365,9 @@ static void common_vt_8t_and_aver_dst_8w_msa(const uint8_t *src, int32_t height) { uint32_t loop_cnt; + uint64_t tp0, tp1, tp2, tp3; v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - v16u8 dst0, dst1, dst2, dst3; + v16u8 dst0, dst1; v16i8 src10_r, src32_r, src54_r, src76_r, src98_r, src21_r, src43_r; v16i8 src65_r, src87_r, src109_r, filt0, filt1, filt2, filt3; v8i16 filt, out0, out1, out2, out3; @@ -1446,7 +1389,9 @@ static void common_vt_8t_and_aver_dst_8w_msa(const uint8_t *src, LD_SB4(src, src_stride, src7, src8, src9, src10); src += (4 * src_stride); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); + LD4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, dst0); + INSERT_D2_UB(tp2, tp3, dst1); XORI_B4_128_SB(src7, src8, src9, src10); ILVR_B4_SB(src7, src6, src8, src7, src9, src8, src10, src9, src76_r, src87_r, src98_r, src109_r); @@ -1460,7 +1405,7 @@ static void common_vt_8t_and_aver_dst_8w_msa(const uint8_t *src, filt1, filt2, filt3); SRARI_H4_SH(out0, out1, out2, out3, 7); SAT_SH4_SH(out0, out1, out2, out3, 7); - CONVERT_UB_AVG_ST8x4_UB(out0, out1, out2, out3, dst0, dst1, dst2, dst3, + CONVERT_UB_AVG_ST8x4_UB(out0, out1, out2, out3, dst0, dst1, dst, dst_stride); dst += (4 * dst_stride); @@ -1610,8 +1555,9 @@ static void common_hv_8ht_8vt_and_aver_dst_4w_msa(const uint8_t *src, int32_t height) { uint32_t loop_cnt; + uint32_t tp0, tp1, tp2, tp3; v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - v16u8 dst0, dst1, dst2, dst3, mask0, mask1, mask2, mask3, tmp0, tmp1; + v16u8 dst0, res, mask0, mask1, mask2, mask3; v16i8 filt_hz0, filt_hz1, filt_hz2, filt_hz3; v8i16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; v8i16 hz_out7, hz_out8, hz_out9, res0, res1, vec0, vec1, vec2, vec3, vec4; @@ -1653,7 +1599,8 @@ static void common_hv_8ht_8vt_and_aver_dst_4w_msa(const uint8_t *src, XORI_B4_128_SB(src7, src8, src9, src10); src += (4 * src_stride); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); + LW4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); hz_out7 = HORIZ_8TAP_FILT(src7, src8, mask0, mask1, mask2, mask3, filt_hz0, filt_hz1, filt_hz2, filt_hz3); hz_out6 = (v8i16) __msa_sldi_b((v16i8) hz_out7, (v16i8) hz_out5, 8); @@ -1667,14 +1614,12 @@ static void common_hv_8ht_8vt_and_aver_dst_4w_msa(const uint8_t *src, vec4 = (v8i16) __msa_ilvev_b((v16i8) hz_out9, (v16i8) hz_out8); res1 = FILT_8TAP_DPADD_S_H(vec1, vec2, vec3, vec4, filt_vt0, filt_vt1, filt_vt2, filt_vt3); - ILVR_W2_UB(dst1, dst0, dst3, dst2, dst0, dst2); SRARI_H2_SH(res0, res1, 7); SAT_SH2_SH(res0, res1, 7); - PCKEV_B2_UB(res0, res0, res1, res1, tmp0, tmp1); - XORI_B2_128_UB(tmp0, tmp1); - AVER_UB2_UB(tmp0, dst0, tmp1, dst2, tmp0, tmp1); - ST4x4_UB(tmp0, tmp1, 0, 1, 0, 1, dst, dst_stride); + res = PCKEV_XORI128_UB(res0, res1); + res = (v16u8) __msa_aver_u_b(res, dst0); + ST4x4_UB(res, res, 0, 1, 2, 3, dst, dst_stride); dst += (4 * dst_stride); hz_out5 = hz_out9; @@ -1693,10 +1638,11 @@ static void common_hv_8ht_8vt_and_aver_dst_8w_msa(const uint8_t *src, int32_t height) { uint32_t loop_cnt; + uint64_t tp0, tp1, tp2, tp3; v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; v16i8 filt_hz0, filt_hz1, filt_hz2, filt_hz3; v8i16 filt, filt_vt0, filt_vt1, filt_vt2, filt_vt3; - v16u8 dst0, dst1, dst2, dst3, mask0, mask1, mask2, mask3; + v16u8 dst0, dst1, mask0, mask1, mask2, mask3; v8i16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; v8i16 hz_out7, hz_out8, hz_out9, hz_out10, tmp0, tmp1, tmp2, tmp3; v8i16 out0, out1, out2, out3, out4, out5, out6, out7, out8, out9; @@ -1743,7 +1689,9 @@ static void common_hv_8ht_8vt_and_aver_dst_8w_msa(const uint8_t *src, XORI_B4_128_SB(src7, src8, src9, src10); src += (4 * src_stride); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); + LD4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, dst0); + INSERT_D2_UB(tp2, tp3, dst1); hz_out7 = HORIZ_8TAP_FILT(src7, src7, mask0, mask1, mask2, mask3, filt_hz0, filt_hz1, filt_hz2, filt_hz3); @@ -1771,7 +1719,7 @@ static void common_hv_8ht_8vt_and_aver_dst_8w_msa(const uint8_t *src, SRARI_H4_SH(tmp0, tmp1, tmp2, tmp3, 7); SAT_SH4_SH(tmp0, tmp1, tmp2, tmp3, 7); - CONVERT_UB_AVG_ST8x4_UB(tmp0, tmp1, tmp2, tmp3, dst0, dst1, dst2, dst3, + CONVERT_UB_AVG_ST8x4_UB(tmp0, tmp1, tmp2, tmp3, dst0, dst1, dst, dst_stride); dst += (4 * dst_stride); @@ -2873,8 +2821,9 @@ static void common_hz_2t_and_aver_dst_4x4_msa(const uint8_t *src, uint8_t *dst, int32_t dst_stride, const int8_t *filter) { + uint32_t tp0, tp1, tp2, tp3; v16i8 src0, src1, src2, src3, mask; - v16u8 filt0, dst0, dst1, dst2, dst3, vec0, vec1, res0, res1; + v16u8 filt0, dst0, vec0, vec1, res; v8u16 vec2, vec3, filt; mask = LD_SB(&mc_filt_mask_arr[16]); @@ -2884,14 +2833,16 @@ static void common_hz_2t_and_aver_dst_4x4_msa(const uint8_t *src, filt0 = (v16u8) __msa_splati_h((v8i16) filt, 0); LD_SB4(src, src_stride, src0, src1, src2, src3); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); + LW4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); VSHF_B2_UB(src0, src1, src2, src3, mask, mask, vec0, vec1); DOTP_UB2_UH(vec0, vec1, filt0, filt0, vec2, vec3); SRARI_H2_UH(vec2, vec3, 7); - PCKEV_B2_UB(vec2, vec2, vec3, vec3, res0, res1); - ILVR_W2_UB(dst1, dst0, dst3, dst2, dst0, dst2); - AVER_UB2_UB(res0, dst0, res1, dst2, res0, res1); - ST4x4_UB(res0, res1, 0, 1, 0, 1, dst, dst_stride); + + res = (v16u8) __msa_pckev_b((v16i8) vec3, (v16i8) vec2); + res = (v16u8) __msa_aver_u_b(res, dst0); + + ST4x4_UB(res, res, 0, 1, 2, 3, dst, dst_stride); } static void common_hz_2t_and_aver_dst_4x8_msa(const uint8_t *src, @@ -2899,9 +2850,10 @@ static void common_hz_2t_and_aver_dst_4x8_msa(const uint8_t *src, uint8_t *dst, int32_t dst_stride, const int8_t *filter) { + uint32_t tp0, tp1, tp2, tp3; v16i8 src0, src1, src2, src3, src4, src5, src6, src7, mask; v16u8 filt0, vec0, vec1, vec2, vec3, res0, res1, res2, res3; - v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; + v16u8 dst0, dst1; v8u16 vec4, vec5, vec6, vec7, filt; mask = LD_SB(&mc_filt_mask_arr[16]); @@ -2911,7 +2863,10 @@ static void common_hz_2t_and_aver_dst_4x8_msa(const uint8_t *src, filt0 = (v16u8) __msa_splati_h((v8i16) filt, 0); LD_SB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - LD_UB8(dst, dst_stride, dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7); + LW4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); + LW4(dst + 4 * dst_stride, dst_stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, dst1); VSHF_B2_UB(src0, src1, src2, src3, mask, mask, vec0, vec1); VSHF_B2_UB(src4, src5, src6, src7, mask, mask, vec2, vec3); DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec4, vec5, @@ -2919,13 +2874,9 @@ static void common_hz_2t_and_aver_dst_4x8_msa(const uint8_t *src, SRARI_H4_UH(vec4, vec5, vec6, vec7, 7); PCKEV_B4_UB(vec4, vec4, vec5, vec5, vec6, vec6, vec7, vec7, res0, res1, res2, res3); - ILVR_W4_UB(dst1, dst0, dst3, dst2, dst5, dst4, dst7, dst6, dst0, dst2, - dst4, dst6); - AVER_UB4_UB(res0, dst0, res1, dst2, res2, dst4, res3, dst6, res0, res1, - res2, res3); - ST4x4_UB(res0, res1, 0, 1, 0, 1, dst, dst_stride); - dst += (4 * dst_stride); - ST4x4_UB(res2, res3, 0, 1, 0, 1, dst, dst_stride); + ILVR_D2_UB(res1, res0, res3, res2, res0, res2); + AVER_UB2_UB(res0, dst0, res2, dst1, res0, res2); + ST4x8_UB(res0, res2, dst, dst_stride); } void ff_avg_bilin_4h_msa(uint8_t *dst, ptrdiff_t dst_stride, @@ -2948,8 +2899,9 @@ static void common_hz_2t_and_aver_dst_8x4_msa(const uint8_t *src, uint8_t *dst, int32_t dst_stride, const int8_t *filter) { + int64_t tp0, tp1, tp2, tp3; v16i8 src0, src1, src2, src3, mask; - v16u8 filt0, dst0, dst1, dst2, dst3; + v16u8 filt0, dst0, dst1; v8u16 vec0, vec1, vec2, vec3, filt; mask = LD_SB(&mc_filt_mask_arr[0]); @@ -2964,9 +2916,10 @@ static void common_hz_2t_and_aver_dst_8x4_msa(const uint8_t *src, DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, vec2, vec3); SRARI_H4_UH(vec0, vec1, vec2, vec3, 7); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - PCKEV_AVG_ST8x4_UB(vec0, dst0, vec1, dst1, vec2, dst2, vec3, dst3, - dst, dst_stride); + LD4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, dst0); + INSERT_D2_UB(tp2, tp3, dst1); + PCKEV_AVG_ST8x4_UB(vec0, vec1, vec2, vec3, dst0, dst1, dst, dst_stride); } static void common_hz_2t_and_aver_dst_8x8mult_msa(const uint8_t *src, @@ -2976,8 +2929,9 @@ static void common_hz_2t_and_aver_dst_8x8mult_msa(const uint8_t *src, const int8_t *filter, int32_t height) { + int64_t tp0, tp1, tp2, tp3; v16i8 src0, src1, src2, src3, mask; - v16u8 filt0, dst0, dst1, dst2, dst3; + v16u8 filt0, dst0, dst1; v8u16 vec0, vec1, vec2, vec3, filt; mask = LD_SB(&mc_filt_mask_arr[0]); @@ -2993,11 +2947,12 @@ static void common_hz_2t_and_aver_dst_8x8mult_msa(const uint8_t *src, DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, vec2, vec3); SRARI_H4_UH(vec0, vec1, vec2, vec3, 7); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); + LD4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, dst0); + INSERT_D2_UB(tp2, tp3, dst1); LD_SB4(src, src_stride, src0, src1, src2, src3); src += (4 * src_stride); - PCKEV_AVG_ST8x4_UB(vec0, dst0, vec1, dst1, vec2, dst2, vec3, dst3, - dst, dst_stride); + PCKEV_AVG_ST8x4_UB(vec0, vec1, vec2, vec3, dst0, dst1, dst, dst_stride); dst += (4 * dst_stride); VSHF_B2_UH(src0, src0, src1, src1, mask, mask, vec0, vec1); @@ -3005,9 +2960,10 @@ static void common_hz_2t_and_aver_dst_8x8mult_msa(const uint8_t *src, DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, vec2, vec3); SRARI_H4_UH(vec0, vec1, vec2, vec3, 7); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - PCKEV_AVG_ST8x4_UB(vec0, dst0, vec1, dst1, vec2, dst2, vec3, dst3, - dst, dst_stride); + LD4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, dst0); + INSERT_D2_UB(tp2, tp3, dst1); + PCKEV_AVG_ST8x4_UB(vec0, vec1, vec2, vec3, dst0, dst1, dst, dst_stride); dst += (4 * dst_stride); if (16 == height) { @@ -3019,10 +2975,11 @@ static void common_hz_2t_and_aver_dst_8x8mult_msa(const uint8_t *src, DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, vec2, vec3); SRARI_H4_UH(vec0, vec1, vec2, vec3, 7); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); + LD4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, dst0); + INSERT_D2_UB(tp2, tp3, dst1); LD_SB4(src, src_stride, src0, src1, src2, src3); - PCKEV_AVG_ST8x4_UB(vec0, dst0, vec1, dst1, vec2, dst2, vec3, dst3, - dst, dst_stride); + PCKEV_AVG_ST8x4_UB(vec0, vec1, vec2, vec3, dst0, dst1, dst, dst_stride); dst += (4 * dst_stride); VSHF_B2_UH(src0, src0, src1, src1, mask, mask, vec0, vec1); @@ -3030,9 +2987,10 @@ static void common_hz_2t_and_aver_dst_8x8mult_msa(const uint8_t *src, DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, vec2, vec3); SRARI_H4_UH(vec0, vec1, vec2, vec3, 7); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - PCKEV_AVG_ST8x4_UB(vec0, dst0, vec1, dst1, vec2, dst2, vec3, dst3, - dst, dst_stride); + LD4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, dst0); + INSERT_D2_UB(tp2, tp3, dst1); + PCKEV_AVG_ST8x4_UB(vec0, vec1, vec2, vec3, dst0, dst1, dst, dst_stride); } } @@ -3216,8 +3174,9 @@ static void common_vt_2t_and_aver_dst_4x4_msa(const uint8_t *src, uint8_t *dst, int32_t dst_stride, const int8_t *filter) { + uint32_t tp0, tp1, tp2, tp3; v16i8 src0, src1, src2, src3, src4; - v16u8 dst0, dst1, dst2, dst3, out, filt0, src2110, src4332; + v16u8 dst0, out, filt0, src2110, src4332; v16i8 src10_r, src32_r, src21_r, src43_r; v8i16 filt; v8u16 tmp0, tmp1; @@ -3231,9 +3190,8 @@ static void common_vt_2t_and_aver_dst_4x4_msa(const uint8_t *src, src4 = LD_SB(src); src += src_stride; - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - ILVR_W2_UB(dst1, dst0, dst3, dst2, dst0, dst1); - dst0 = (v16u8) __msa_ilvr_d((v2i64) dst1, (v2i64) dst0); + LW4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, src10_r, src21_r, src32_r, src43_r); ILVR_D2_UB(src21_r, src10_r, src43_r, src32_r, src2110, src4332); @@ -3252,7 +3210,8 @@ static void common_vt_2t_and_aver_dst_4x8_msa(const uint8_t *src, uint8_t *dst, int32_t dst_stride, const int8_t *filter) { - v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; + uint32_t tp0, tp1, tp2, tp3; + v16u8 dst0, dst1; v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src87_r; v16i8 src10_r, src32_r, src54_r, src76_r, src21_r, src43_r, src65_r; v16u8 src2110, src4332, src6554, src8776, filt0; @@ -3266,10 +3225,10 @@ static void common_vt_2t_and_aver_dst_4x8_msa(const uint8_t *src, src += (8 * src_stride); src8 = LD_SB(src); - LD_UB8(dst, dst_stride, dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7); - ILVR_W4_UB(dst1, dst0, dst3, dst2, dst5, dst4, dst7, dst6, dst0, dst1, - dst2, dst3); - ILVR_D2_UB(dst1, dst0, dst3, dst2, dst0, dst1); + LW4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); + LW4(dst + 4 * dst_stride, dst_stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, dst1); ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, src10_r, src21_r, src32_r, src43_r); ILVR_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, src54_r, src65_r, @@ -3282,9 +3241,7 @@ static void common_vt_2t_and_aver_dst_4x8_msa(const uint8_t *src, SAT_UH4_UH(tmp0, tmp1, tmp2, tmp3, 7); PCKEV_B2_UB(tmp1, tmp0, tmp3, tmp2, src2110, src4332); AVER_UB2_UB(src2110, dst0, src4332, dst1, src2110, src4332); - ST4x4_UB(src2110, src2110, 0, 1, 2, 3, dst, dst_stride); - dst += (4 * dst_stride); - ST4x4_UB(src4332, src4332, 0, 1, 2, 3, dst, dst_stride); + ST4x8_UB(src2110, src4332, dst, dst_stride); } void ff_avg_bilin_4v_msa(uint8_t *dst, ptrdiff_t dst_stride, @@ -3308,8 +3265,9 @@ static void common_vt_2t_and_aver_dst_8x4_msa(const uint8_t *src, int32_t dst_stride, const int8_t *filter) { + int64_t tp0, tp1, tp2, tp3; v16u8 src0, src1, src2, src3, src4; - v16u8 dst0, dst1, dst2, dst3, vec0, vec1, vec2, vec3, filt0; + v16u8 dst0, dst1, vec0, vec1, vec2, vec3, filt0; v8u16 tmp0, tmp1, tmp2, tmp3; v8i16 filt; @@ -3318,15 +3276,16 @@ static void common_vt_2t_and_aver_dst_8x4_msa(const uint8_t *src, filt0 = (v16u8) __msa_splati_h(filt, 0); LD_UB5(src, src_stride, src0, src1, src2, src3, src4); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); + LD4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, dst0); + INSERT_D2_UB(tp2, tp3, dst1); ILVR_B2_UB(src1, src0, src2, src1, vec0, vec1); ILVR_B2_UB(src3, src2, src4, src3, vec2, vec3); DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, tmp0, tmp1, tmp2, tmp3); SRARI_H4_UH(tmp0, tmp1, tmp2, tmp3, 7); SAT_UH4_UH(tmp0, tmp1, tmp2, tmp3, 7); - PCKEV_AVG_ST8x4_UB(tmp0, dst0, tmp1, dst1, tmp2, dst2, tmp3, dst3, - dst, dst_stride); + PCKEV_AVG_ST8x4_UB(tmp0, tmp1, tmp2, tmp3, dst0, dst1, dst, dst_stride); } static void common_vt_2t_and_aver_dst_8x8mult_msa(const uint8_t *src, @@ -3337,8 +3296,9 @@ static void common_vt_2t_and_aver_dst_8x8mult_msa(const uint8_t *src, int32_t height) { uint32_t loop_cnt; + int64_t tp0, tp1, tp2, tp3; v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8; - v16u8 dst1, dst2, dst3, dst4, dst5, dst6, dst7, dst8; + v16u8 dst0, dst1, dst2, dst3; v16u8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, filt0; v8u16 tmp0, tmp1, tmp2, tmp3; v8i16 filt; @@ -3353,7 +3313,13 @@ static void common_vt_2t_and_aver_dst_8x8mult_msa(const uint8_t *src, for (loop_cnt = (height >> 3); loop_cnt--;) { LD_UB8(src, src_stride, src1, src2, src3, src4, src5, src6, src7, src8); src += (8 * src_stride); - LD_UB8(dst, dst_stride, dst1, dst2, dst3, dst4, dst5, dst6, dst7, dst8); + + LD4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, dst0); + INSERT_D2_UB(tp2, tp3, dst1); + LD4(dst + 4 * dst_stride, dst_stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, dst2); + INSERT_D2_UB(tp2, tp3, dst3); ILVR_B4_UB(src1, src0, src2, src1, src3, src2, src4, src3, vec0, vec1, vec2, vec3); @@ -3363,16 +3329,14 @@ static void common_vt_2t_and_aver_dst_8x8mult_msa(const uint8_t *src, tmp0, tmp1, tmp2, tmp3); SRARI_H4_UH(tmp0, tmp1, tmp2, tmp3, 7); SAT_UH4_UH(tmp0, tmp1, tmp2, tmp3, 7); - PCKEV_AVG_ST8x4_UB(tmp0, dst1, tmp1, dst2, tmp2, dst3, tmp3, - dst4, dst, dst_stride); + PCKEV_AVG_ST8x4_UB(tmp0, tmp1, tmp2, tmp3, dst0, dst1, dst, dst_stride); dst += (4 * dst_stride); DOTP_UB4_UH(vec4, vec5, vec6, vec7, filt0, filt0, filt0, filt0, tmp0, tmp1, tmp2, tmp3); SRARI_H4_UH(tmp0, tmp1, tmp2, tmp3, 7); SAT_UH4_UH(tmp0, tmp1, tmp2, tmp3, 7); - PCKEV_AVG_ST8x4_UB(tmp0, dst5, tmp1, dst6, tmp2, dst7, tmp3, - dst8, dst, dst_stride); + PCKEV_AVG_ST8x4_UB(tmp0, tmp1, tmp2, tmp3, dst2, dst3, dst, dst_stride); dst += (4 * dst_stride); src0 = src8; @@ -3622,9 +3586,10 @@ static void common_hv_2ht_2vt_and_aver_dst_4x4_msa(const uint8_t *src, const int8_t *filter_horiz, const int8_t *filter_vert) { + uint32_t tp0, tp1, tp2, tp3; v16i8 src0, src1, src2, src3, src4, mask; v16u8 filt_hz, filt_vt, vec0, vec1; - v16u8 dst0, dst1, dst2, dst3, res0, res1; + v16u8 dst0, out; v8u16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, tmp0, tmp1, filt; mask = LD_SB(&mc_filt_mask_arr[16]); @@ -3645,14 +3610,17 @@ static void common_hv_2ht_2vt_and_aver_dst_4x4_msa(const uint8_t *src, hz_out3 = (v8u16) __msa_pckod_d((v2i64) hz_out4, (v2i64) hz_out2); ILVEV_B2_UB(hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - ILVR_W2_UB(dst1, dst0, dst3, dst2, dst0, dst2); + LW4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); + DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp0, tmp1); SRARI_H2_UH(tmp0, tmp1, 7); SAT_UH2_UH(tmp0, tmp1, 7); - PCKEV_B2_UB(tmp0, tmp0, tmp1, tmp1, res0, res1); - AVER_UB2_UB(res0, dst0, res1, dst2, res0, res1); - ST4x4_UB(res0, res1, 0, 1, 0, 1, dst, dst_stride); + + out = (v16u8) __msa_pckev_b((v16i8) tmp1, (v16i8) tmp0); + out = __msa_aver_u_b(out, dst0); + + ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); } static void common_hv_2ht_2vt_and_aver_dst_4x8_msa(const uint8_t *src, @@ -3662,9 +3630,10 @@ static void common_hv_2ht_2vt_and_aver_dst_4x8_msa(const uint8_t *src, const int8_t *filter_horiz, const int8_t *filter_vert) { + uint32_t tp0, tp1, tp2, tp3; v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, mask; - v16u8 filt_hz, filt_vt, vec0, vec1, vec2, vec3, res0, res1, res2, res3; - v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; + v16u8 filt_hz, filt_vt, vec0, vec1, vec2, vec3, res0, res1; + v16u8 dst0, dst1; v8u16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; v8u16 hz_out7, hz_out8, tmp0, tmp1, tmp2, tmp3; v8i16 filt; @@ -3691,22 +3660,19 @@ static void common_hv_2ht_2vt_and_aver_dst_4x8_msa(const uint8_t *src, hz_out3, hz_out5, 8); hz_out7 = (v8u16) __msa_pckod_d((v2i64) hz_out8, (v2i64) hz_out6); - LD_UB8(dst, dst_stride, dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7); - ILVR_W4_UB(dst1, dst0, dst3, dst2, dst5, dst4, dst7, dst6, dst0, dst2, - dst4, dst6); + LW4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); + LW4(dst + 4 * dst_stride, dst_stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, dst1); ILVEV_B2_UB(hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); ILVEV_B2_UB(hz_out4, hz_out5, hz_out6, hz_out7, vec2, vec3); DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt_vt, filt_vt, filt_vt, filt_vt, tmp0, tmp1, tmp2, tmp3); SRARI_H4_UH(tmp0, tmp1, tmp2, tmp3, 7); SAT_UH4_UH(tmp0, tmp1, tmp2, tmp3, 7); - PCKEV_B4_UB(tmp0, tmp0, tmp1, tmp1, tmp2, tmp2, tmp3, tmp3, res0, res1, - res2, res3); - AVER_UB4_UB(res0, dst0, res1, dst2, res2, dst4, res3, dst6, res0, res1, - res2, res3); - ST4x4_UB(res0, res1, 0, 1, 0, 1, dst, dst_stride); - dst += (4 * dst_stride); - ST4x4_UB(res2, res3, 0, 1, 0, 1, dst, dst_stride); + PCKEV_B2_UB(tmp1, tmp0, tmp3, tmp2, res0, res1); + AVER_UB2_UB(res0, dst0, res1, dst1, res0, res1); + ST4x8_UB(res0, res1, dst, dst_stride); } void ff_avg_bilin_4hv_msa(uint8_t *dst, ptrdiff_t dst_stride, @@ -3732,8 +3698,9 @@ static void common_hv_2ht_2vt_and_aver_dst_8x4_msa(const uint8_t *src, const int8_t *filter_horiz, const int8_t *filter_vert) { + uint64_t tp0, tp1, tp2, tp3; v16i8 src0, src1, src2, src3, src4, mask; - v16u8 filt_hz, filt_vt, dst0, dst1, dst2, dst3, vec0, vec1, vec2, vec3; + v16u8 filt_hz, filt_vt, dst0, dst1, vec0, vec1, vec2, vec3; v8u16 hz_out0, hz_out1, tmp0, tmp1, tmp2, tmp3; v8i16 filt; @@ -3749,7 +3716,9 @@ static void common_hv_2ht_2vt_and_aver_dst_8x4_msa(const uint8_t *src, LD_SB5(src, src_stride, src0, src1, src2, src3, src4); src += (5 * src_stride); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); + LD4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, dst0); + INSERT_D2_UB(tp2, tp3, dst1); hz_out0 = HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, 7); hz_out1 = HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, 7); vec0 = (v16u8) __msa_ilvev_b((v16i8) hz_out1, (v16i8) hz_out0); @@ -3769,8 +3738,7 @@ static void common_hv_2ht_2vt_and_aver_dst_8x4_msa(const uint8_t *src, SRARI_H4_UH(tmp0, tmp1, tmp2, tmp3, 7); SAT_UH4_UH(tmp0, tmp1, tmp2, tmp3, 7); - PCKEV_AVG_ST8x4_UB(tmp0, dst0, tmp1, dst1, tmp2, dst2, tmp3, dst3, - dst, dst_stride); + PCKEV_AVG_ST8x4_UB(tmp0, tmp1, tmp2, tmp3, dst0, dst1, dst, dst_stride); } static void common_hv_2ht_2vt_and_aver_dst_8x8mult_msa(const uint8_t *src, @@ -3782,8 +3750,9 @@ static void common_hv_2ht_2vt_and_aver_dst_8x8mult_msa(const uint8_t *src, int32_t height) { uint32_t loop_cnt; + uint64_t tp0, tp1, tp2, tp3; v16i8 src0, src1, src2, src3, src4, mask; - v16u8 filt_hz, filt_vt, vec0, dst0, dst1, dst2, dst3; + v16u8 filt_hz, filt_vt, vec0, dst0, dst1; v8u16 hz_out0, hz_out1, tmp0, tmp1, tmp2, tmp3; v8i16 filt; @@ -3826,9 +3795,10 @@ static void common_hv_2ht_2vt_and_aver_dst_8x8mult_msa(const uint8_t *src, SRARI_H2_UH(tmp2, tmp3, 7); SAT_UH2_UH(tmp2, tmp3, 7); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - PCKEV_AVG_ST8x4_UB(tmp0, dst0, tmp1, dst1, tmp2, dst2, tmp3, - dst3, dst, dst_stride); + LD4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, dst0); + INSERT_D2_UB(tp2, tp3, dst1); + PCKEV_AVG_ST8x4_UB(tmp0, tmp1, tmp2, tmp3, dst0, dst1, dst, dst_stride); dst += (4 * dst_stride); } } @@ -3956,53 +3926,13 @@ static void copy_width8_msa(const uint8_t *src, int32_t src_stride, { int32_t cnt; uint64_t out0, out1, out2, out3, out4, out5, out6, out7; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - - if (0 == height % 12) { - for (cnt = (height / 12); cnt--;) { - LD_UB8(src, src_stride, - src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - - out0 = __msa_copy_u_d((v2i64) src0, 0); - out1 = __msa_copy_u_d((v2i64) src1, 0); - out2 = __msa_copy_u_d((v2i64) src2, 0); - out3 = __msa_copy_u_d((v2i64) src3, 0); - out4 = __msa_copy_u_d((v2i64) src4, 0); - out5 = __msa_copy_u_d((v2i64) src5, 0); - out6 = __msa_copy_u_d((v2i64) src6, 0); - out7 = __msa_copy_u_d((v2i64) src7, 0); - - SD4(out0, out1, out2, out3, dst, dst_stride); - dst += (4 * dst_stride); - SD4(out4, out5, out6, out7, dst, dst_stride); - dst += (4 * dst_stride); - - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - out0 = __msa_copy_u_d((v2i64) src0, 0); - out1 = __msa_copy_u_d((v2i64) src1, 0); - out2 = __msa_copy_u_d((v2i64) src2, 0); - out3 = __msa_copy_u_d((v2i64) src3, 0); - SD4(out0, out1, out2, out3, dst, dst_stride); - dst += (4 * dst_stride); - } - } else if (0 == height % 8) { + if (0 == height % 8) { for (cnt = height >> 3; cnt--;) { - LD_UB8(src, src_stride, - src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - - out0 = __msa_copy_u_d((v2i64) src0, 0); - out1 = __msa_copy_u_d((v2i64) src1, 0); - out2 = __msa_copy_u_d((v2i64) src2, 0); - out3 = __msa_copy_u_d((v2i64) src3, 0); - out4 = __msa_copy_u_d((v2i64) src4, 0); - out5 = __msa_copy_u_d((v2i64) src5, 0); - out6 = __msa_copy_u_d((v2i64) src6, 0); - out7 = __msa_copy_u_d((v2i64) src7, 0); + LD4(src, src_stride, out0, out1, out2, out3); + src += (4 * src_stride); + LD4(src, src_stride, out4, out5, out6, out7); + src += (4 * src_stride); SD4(out0, out1, out2, out3, dst, dst_stride); dst += (4 * dst_stride); @@ -4011,56 +3941,12 @@ static void copy_width8_msa(const uint8_t *src, int32_t src_stride, } } else if (0 == height % 4) { for (cnt = (height / 4); cnt--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); + LD4(src, src_stride, out0, out1, out2, out3); src += (4 * src_stride); - out0 = __msa_copy_u_d((v2i64) src0, 0); - out1 = __msa_copy_u_d((v2i64) src1, 0); - out2 = __msa_copy_u_d((v2i64) src2, 0); - out3 = __msa_copy_u_d((v2i64) src3, 0); SD4(out0, out1, out2, out3, dst, dst_stride); dst += (4 * dst_stride); } - } else if (0 == height % 2) { - for (cnt = (height / 2); cnt--;) { - LD_UB2(src, src_stride, src0, src1); - src += (2 * src_stride); - out0 = __msa_copy_u_d((v2i64) src0, 0); - out1 = __msa_copy_u_d((v2i64) src1, 0); - - SD(out0, dst); - dst += dst_stride; - SD(out1, dst); - dst += dst_stride; - } - } -} - -static void copy_16multx8mult_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height, int32_t width) -{ - int32_t cnt, loop_cnt; - const uint8_t *src_tmp; - uint8_t *dst_tmp; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - - for (cnt = (width >> 4); cnt--;) { - src_tmp = src; - dst_tmp = dst; - - for (loop_cnt = (height >> 3); loop_cnt--;) { - LD_UB8(src_tmp, src_stride, - src0, src1, src2, src3, src4, src5, src6, src7); - src_tmp += (8 * src_stride); - - ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, - dst_tmp, dst_stride); - dst_tmp += (8 * dst_stride); - } - - src += 16; - dst += 16; } } @@ -4071,27 +3957,37 @@ static void copy_width16_msa(const uint8_t *src, int32_t src_stride, int32_t cnt; v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - if (0 == height % 12) { - for (cnt = (height / 12); cnt--;) { - LD_UB8(src, src_stride, - src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, - dst, dst_stride); - dst += (8 * dst_stride); - - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - ST_UB4(src0, src1, src2, src3, dst, dst_stride); - dst += (4 * dst_stride); - } - } else if (0 == height % 8) { - copy_16multx8mult_msa(src, src_stride, dst, dst_stride, height, 16); + if (8 == height) { + LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); + ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, dst, dst_stride); + } else if (16 == height) { + LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); + src += (8 * src_stride); + ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, dst, dst_stride); + dst += (8 * dst_stride); + LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); + src += (8 * src_stride); + ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, dst, dst_stride); + dst += (8 * dst_stride); + } else if (32 == height) { + LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); + src += (8 * src_stride); + ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, dst, dst_stride); + dst += (8 * dst_stride); + LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); + src += (8 * src_stride); + ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, dst, dst_stride); + dst += (8 * dst_stride); + LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); + src += (8 * src_stride); + ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, dst, dst_stride); + dst += (8 * dst_stride); + LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); + ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, dst, dst_stride); } else if (0 == height % 4) { for (cnt = (height >> 2); cnt--;) { LD_UB4(src, src_stride, src0, src1, src2, src3); src += (4 * src_stride); - ST_UB4(src0, src1, src2, src3, dst, dst_stride); dst += (4 * dst_stride); } @@ -4105,31 +4001,17 @@ static void copy_width32_msa(const uint8_t *src, int32_t src_stride, int32_t cnt; v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - if (0 == height % 12) { - for (cnt = (height / 12); cnt--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); - LD_UB4(src + 16, src_stride, src4, src5, src6, src7); - src += (4 * src_stride); - ST_UB4(src0, src1, src2, src3, dst, dst_stride); - ST_UB4(src4, src5, src6, src7, dst + 16, dst_stride); - dst += (4 * dst_stride); - - LD_UB4(src, src_stride, src0, src1, src2, src3); - LD_UB4(src + 16, src_stride, src4, src5, src6, src7); - src += (4 * src_stride); - ST_UB4(src0, src1, src2, src3, dst, dst_stride); - ST_UB4(src4, src5, src6, src7, dst + 16, dst_stride); - dst += (4 * dst_stride); - - LD_UB4(src, src_stride, src0, src1, src2, src3); - LD_UB4(src + 16, src_stride, src4, src5, src6, src7); - src += (4 * src_stride); - ST_UB4(src0, src1, src2, src3, dst, dst_stride); - ST_UB4(src4, src5, src6, src7, dst + 16, dst_stride); - dst += (4 * dst_stride); + if (0 == height % 8) { + for (cnt = (height >> 3); cnt--;) { + LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); + ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, dst, dst_stride); + LD_UB8(src + 16, src_stride, src0, src1, src2, src3, src4, src5, src6, + src7); + src += (8 * src_stride); + ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, dst + 16, + dst_stride); + dst += (8 * dst_stride); } - } else if (0 == height % 8) { - copy_16multx8mult_msa(src, src_stride, dst, dst_stride, height, 32); } else if (0 == height % 4) { for (cnt = (height >> 2); cnt--;) { LD_UB4(src, src_stride, src0, src1, src2, src3); @@ -4146,51 +4028,57 @@ static void copy_width64_msa(const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, int32_t height) { - copy_16multx8mult_msa(src, src_stride, dst, dst_stride, height, 64); + int32_t cnt; + v16u8 src0, src1, src2, src3, src4, src5, src6, src7; + v16u8 src8, src9, src10, src11, src12, src13, src14, src15; + + for (cnt = (height >> 2); cnt--;) { + LD_UB4(src, 16, src0, src1, src2, src3); + src += src_stride; + LD_UB4(src, 16, src4, src5, src6, src7); + src += src_stride; + LD_UB4(src, 16, src8, src9, src10, src11); + src += src_stride; + LD_UB4(src, 16, src12, src13, src14, src15); + src += src_stride; + + ST_UB4(src0, src1, src2, src3, dst, 16); + dst += dst_stride; + ST_UB4(src4, src5, src6, src7, dst, 16); + dst += dst_stride; + ST_UB4(src8, src9, src10, src11, dst, 16); + dst += dst_stride; + ST_UB4(src12, src13, src14, src15, dst, 16); + dst += dst_stride; + } } static void avg_width4_msa(const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, int32_t height) { - int32_t cnt; - uint32_t out0, out1, out2, out3; - v16u8 src0, src1, src2, src3; - v16u8 dst0, dst1, dst2, dst3; - - if (0 == (height % 4)) { - for (cnt = (height / 4); cnt--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - - AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, - dst0, dst1, dst2, dst3); - - out0 = __msa_copy_u_w((v4i32) dst0, 0); - out1 = __msa_copy_u_w((v4i32) dst1, 0); - out2 = __msa_copy_u_w((v4i32) dst2, 0); - out3 = __msa_copy_u_w((v4i32) dst3, 0); - SW4(out0, out1, out2, out3, dst, dst_stride); - dst += (4 * dst_stride); - } - } else if (0 == (height % 2)) { - for (cnt = (height / 2); cnt--;) { - LD_UB2(src, src_stride, src0, src1); - src += (2 * src_stride); - - LD_UB2(dst, dst_stride, dst0, dst1); - - AVER_UB2_UB(src0, dst0, src1, dst1, dst0, dst1); - - out0 = __msa_copy_u_w((v4i32) dst0, 0); - out1 = __msa_copy_u_w((v4i32) dst1, 0); - SW(out0, dst); - dst += dst_stride; - SW(out1, dst); - dst += dst_stride; - } + uint32_t tp0, tp1, tp2, tp3; + v16u8 src0 = { 0 }, src1 = { 0 }, dst0 = { 0 }, dst1 = { 0 }; + + if (8 == height) { + LW4(src, src_stride, tp0, tp1, tp2, tp3); + src += 4 * src_stride; + INSERT_W4_UB(tp0, tp1, tp2, tp3, src0); + LW4(src, src_stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, src1); + LW4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); + LW4(dst + 4 * dst_stride, dst_stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, dst1); + AVER_UB2_UB(src0, dst0, src1, dst1, dst0, dst1); + ST4x8_UB(dst0, dst1, dst, dst_stride); + } else if (4 == height) { + LW4(src, src_stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, src0); + LW4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); + dst0 = __msa_aver_u_b(src0, dst0); + ST4x4_UB(dst0, dst0, 0, 1, 2, 3, dst, dst_stride); } } @@ -4199,24 +4087,40 @@ static void avg_width8_msa(const uint8_t *src, int32_t src_stride, int32_t height) { int32_t cnt; - uint64_t out0, out1, out2, out3; + uint64_t tp0, tp1, tp2, tp3, tp4, tp5, tp6, tp7; v16u8 src0, src1, src2, src3; v16u8 dst0, dst1, dst2, dst3; - for (cnt = (height / 4); cnt--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - - AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, - dst0, dst1, dst2, dst3); - - out0 = __msa_copy_u_d((v2i64) dst0, 0); - out1 = __msa_copy_u_d((v2i64) dst1, 0); - out2 = __msa_copy_u_d((v2i64) dst2, 0); - out3 = __msa_copy_u_d((v2i64) dst3, 0); - SD4(out0, out1, out2, out3, dst, dst_stride); - dst += (4 * dst_stride); + if (0 == (height % 8)) { + for (cnt = (height >> 3); cnt--;) { + LD4(src, src_stride, tp0, tp1, tp2, tp3); + src += 4 * src_stride; + LD4(src, src_stride, tp4, tp5, tp6, tp7); + src += 4 * src_stride; + INSERT_D2_UB(tp0, tp1, src0); + INSERT_D2_UB(tp2, tp3, src1); + INSERT_D2_UB(tp4, tp5, src2); + INSERT_D2_UB(tp6, tp7, src3); + LD4(dst, dst_stride, tp0, tp1, tp2, tp3); + LD4(dst + 4 * dst_stride, dst_stride, tp4, tp5, tp6, tp7); + INSERT_D2_UB(tp0, tp1, dst0); + INSERT_D2_UB(tp2, tp3, dst1); + INSERT_D2_UB(tp4, tp5, dst2); + INSERT_D2_UB(tp6, tp7, dst3); + AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, dst0, + dst1, dst2, dst3); + ST8x8_UB(dst0, dst1, dst2, dst3, dst, dst_stride); + dst += 8 * dst_stride; + } + } else if (4 == height) { + LD4(src, src_stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, src0); + INSERT_D2_UB(tp2, tp3, src1); + LD4(dst, dst_stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, dst0); + INSERT_D2_UB(tp2, tp3, dst1); + AVER_UB2_UB(src0, dst0, src1, dst1, dst0, dst1); + ST8x4_UB(dst0, dst1, dst, dst_stride); } } @@ -4228,17 +4132,30 @@ static void avg_width16_msa(const uint8_t *src, int32_t src_stride, v16u8 src0, src1, src2, src3, src4, src5, src6, src7; v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; - for (cnt = (height / 8); cnt--;) { - LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - LD_UB8(dst, dst_stride, dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7); + if (0 == (height % 8)) { + for (cnt = (height / 8); cnt--;) { + LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); + src += (8 * src_stride); + LD_UB8(dst, dst_stride, dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7); - AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, - dst0, dst1, dst2, dst3); - AVER_UB4_UB(src4, dst4, src5, dst5, src6, dst6, src7, dst7, - dst4, dst5, dst6, dst7); - ST_UB8(dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7, dst, dst_stride); - dst += (8 * dst_stride); + AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, + dst0, dst1, dst2, dst3); + AVER_UB4_UB(src4, dst4, src5, dst5, src6, dst6, src7, dst7, + dst4, dst5, dst6, dst7); + ST_UB8(dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7, dst, dst_stride); + dst += (8 * dst_stride); + } + } else if (0 == (height % 4)) { + for (cnt = (height / 4); cnt--;) { + LD_UB4(src, src_stride, src0, src1, src2, src3); + src += (4 * src_stride); + LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); + + AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, + dst0, dst1, dst2, dst3); + ST_UB4(dst0, dst1, dst2, dst3, dst, dst_stride); + dst += (4 * dst_stride); + } } } @@ -4253,35 +4170,55 @@ static void avg_width32_msa(const uint8_t *src, int32_t src_stride, v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; v16u8 dst8, dst9, dst10, dst11, dst12, dst13, dst14, dst15; - for (cnt = (height / 8); cnt--;) { - LD_UB4(src, src_stride, src0, src2, src4, src6); - LD_UB4(src + 16, src_stride, src1, src3, src5, src7); - src += (4 * src_stride); - LD_UB4(dst_dup, dst_stride, dst0, dst2, dst4, dst6); - LD_UB4(dst_dup + 16, dst_stride, dst1, dst3, dst5, dst7); - dst_dup += (4 * dst_stride); - LD_UB4(src, src_stride, src8, src10, src12, src14); - LD_UB4(src + 16, src_stride, src9, src11, src13, src15); - src += (4 * src_stride); - LD_UB4(dst_dup, dst_stride, dst8, dst10, dst12, dst14); - LD_UB4(dst_dup + 16, dst_stride, dst9, dst11, dst13, dst15); - dst_dup += (4 * dst_stride); + if (0 == (height % 8)) { + for (cnt = (height / 8); cnt--;) { + LD_UB4(src, src_stride, src0, src2, src4, src6); + LD_UB4(src + 16, src_stride, src1, src3, src5, src7); + src += (4 * src_stride); + LD_UB4(dst_dup, dst_stride, dst0, dst2, dst4, dst6); + LD_UB4(dst_dup + 16, dst_stride, dst1, dst3, dst5, dst7); + dst_dup += (4 * dst_stride); + LD_UB4(src, src_stride, src8, src10, src12, src14); + LD_UB4(src + 16, src_stride, src9, src11, src13, src15); + src += (4 * src_stride); + LD_UB4(dst_dup, dst_stride, dst8, dst10, dst12, dst14); + LD_UB4(dst_dup + 16, dst_stride, dst9, dst11, dst13, dst15); + dst_dup += (4 * dst_stride); - AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, - dst0, dst1, dst2, dst3); - AVER_UB4_UB(src4, dst4, src5, dst5, src6, dst6, src7, dst7, - dst4, dst5, dst6, dst7); - AVER_UB4_UB(src8, dst8, src9, dst9, src10, dst10, src11, dst11, - dst8, dst9, dst10, dst11); - AVER_UB4_UB(src12, dst12, src13, dst13, src14, dst14, src15, dst15, - dst12, dst13, dst14, dst15); + AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, + dst0, dst1, dst2, dst3); + AVER_UB4_UB(src4, dst4, src5, dst5, src6, dst6, src7, dst7, + dst4, dst5, dst6, dst7); + AVER_UB4_UB(src8, dst8, src9, dst9, src10, dst10, src11, dst11, + dst8, dst9, dst10, dst11); + AVER_UB4_UB(src12, dst12, src13, dst13, src14, dst14, src15, dst15, + dst12, dst13, dst14, dst15); + + ST_UB4(dst0, dst2, dst4, dst6, dst, dst_stride); + ST_UB4(dst1, dst3, dst5, dst7, dst + 16, dst_stride); + dst += (4 * dst_stride); + ST_UB4(dst8, dst10, dst12, dst14, dst, dst_stride); + ST_UB4(dst9, dst11, dst13, dst15, dst + 16, dst_stride); + dst += (4 * dst_stride); + } + } else if (0 == (height % 4)) { + for (cnt = (height / 4); cnt--;) { + LD_UB4(src, src_stride, src0, src2, src4, src6); + LD_UB4(src + 16, src_stride, src1, src3, src5, src7); + src += (4 * src_stride); + LD_UB4(dst_dup, dst_stride, dst0, dst2, dst4, dst6); + LD_UB4(dst_dup + 16, dst_stride, dst1, dst3, dst5, dst7); + dst_dup += (4 * dst_stride); - ST_UB4(dst0, dst2, dst4, dst6, dst, dst_stride); - ST_UB4(dst1, dst3, dst5, dst7, dst + 16, dst_stride); - dst += (4 * dst_stride); - ST_UB4(dst8, dst10, dst12, dst14, dst, dst_stride); - ST_UB4(dst9, dst11, dst13, dst15, dst + 16, dst_stride); - dst += (4 * dst_stride); + AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, + dst0, dst1, dst2, dst3); + AVER_UB4_UB(src4, dst4, src5, dst5, src6, dst6, src7, dst7, + dst4, dst5, dst6, dst7); + + ST_UB4(dst0, dst2, dst4, dst6, dst, dst_stride); + ST_UB4(dst1, dst3, dst5, dst7, dst + 16, dst_stride); + dst += (4 * dst_stride); + } } } @@ -4413,8 +4350,8 @@ void ff_put_8tap_##type##_##SIZE##hv_msa(uint8_t *dst, ptrdiff_t dststride, \ ptrdiff_t srcstride, \ int h, int mx, int my) \ { \ - const uint8_t *hfilter = vp9_subpel_filters_msa[type_idx][mx-1]; \ - const uint8_t *vfilter = vp9_subpel_filters_msa[type_idx][my-1]; \ + const int8_t *hfilter = vp9_subpel_filters_msa[type_idx][mx-1]; \ + const int8_t *vfilter = vp9_subpel_filters_msa[type_idx][my-1]; \ \ common_hv_8ht_8vt_##SIZE##w_msa(src, srcstride, dst, dststride, hfilter, \ vfilter, h); \ @@ -4447,8 +4384,8 @@ void ff_avg_8tap_##type##_##SIZE##hv_msa(uint8_t *dst, ptrdiff_t dststride, \ ptrdiff_t srcstride, \ int h, int mx, int my) \ { \ - const uint8_t *hfilter = vp9_subpel_filters_msa[type_idx][mx-1]; \ - const uint8_t *vfilter = vp9_subpel_filters_msa[type_idx][my-1]; \ + const int8_t *hfilter = vp9_subpel_filters_msa[type_idx][mx-1]; \ + const int8_t *vfilter = vp9_subpel_filters_msa[type_idx][my-1]; \ \ common_hv_8ht_8vt_and_aver_dst_##SIZE##w_msa(src, srcstride, dst, \ dststride, hfilter, \ diff --git a/libavutil/mips/generic_macros_msa.h b/libavutil/mips/generic_macros_msa.h index 407d46e616a91..ee7d6632366d3 100644 --- a/libavutil/mips/generic_macros_msa.h +++ b/libavutil/mips/generic_macros_msa.h @@ -2773,20 +2773,18 @@ /* Description : Converts inputs to unsigned bytes, interleave, average & store as 8x4 unsigned byte block - Arguments : Inputs - in0, in1, in2, in3, dst0, dst1, dst2, dst3, - pdst, stride + Arguments : Inputs - in0, in1, in2, in3, dst0, dst1, pdst, stride */ -#define CONVERT_UB_AVG_ST8x4_UB(in0, in1, in2, in3, \ - dst0, dst1, dst2, dst3, pdst, stride) \ -{ \ - v16u8 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ - uint8_t *pdst_m = (uint8_t *) (pdst); \ - \ - tmp0_m = PCKEV_XORI128_UB(in0, in1); \ - tmp1_m = PCKEV_XORI128_UB(in2, in3); \ - ILVR_D2_UB(dst1, dst0, dst3, dst2, tmp2_m, tmp3_m); \ - AVER_UB2_UB(tmp0_m, tmp2_m, tmp1_m, tmp3_m, tmp0_m, tmp1_m); \ - ST8x4_UB(tmp0_m, tmp1_m, pdst_m, stride); \ +#define CONVERT_UB_AVG_ST8x4_UB(in0, in1, in2, in3, \ + dst0, dst1, pdst, stride) \ +{ \ + v16u8 tmp0_m, tmp1_m; \ + uint8_t *pdst_m = (uint8_t *) (pdst); \ + \ + tmp0_m = PCKEV_XORI128_UB(in0, in1); \ + tmp1_m = PCKEV_XORI128_UB(in2, in3); \ + AVER_UB2_UB(tmp0_m, dst0, tmp1_m, dst1, tmp0_m, tmp1_m); \ + ST8x4_UB(tmp0_m, tmp1_m, pdst_m, stride); \ } /* Description : Pack even byte elements, extract 0 & 2 index words from pair From fde5c7dc79eb017790ba232442ad2a4eecea4bf1 Mon Sep 17 00:00:00 2001 From: Mark Wachsler Date: Thu, 7 Sep 2017 09:42:07 -0400 Subject: [PATCH 3012/3374] libavcodec/h264_parse: don't use uninitialized value when chroma_format_idc==0 When parsing a monochrome file, chroma_log2_weight_denom was used without being initialized, which could lead to a bogus error message being printed, e.g. [h264 @ 0x61a000026480] chroma_log2_weight_denom 24576 is out of range It also could led to warnings using AddressSanitizer. Signed-off-by: Michael Niedermayer --- libavcodec/h264_parse.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/libavcodec/h264_parse.c b/libavcodec/h264_parse.c index 3d20075f6a0b4..a7c71d9bbbbed 100644 --- a/libavcodec/h264_parse.c +++ b/libavcodec/h264_parse.c @@ -34,21 +34,22 @@ int ff_h264_pred_weight_table(GetBitContext *gb, const SPS *sps, pwt->use_weight = 0; pwt->use_weight_chroma = 0; - pwt->luma_log2_weight_denom = get_ue_golomb(gb); - if (sps->chroma_format_idc) - pwt->chroma_log2_weight_denom = get_ue_golomb(gb); + pwt->luma_log2_weight_denom = get_ue_golomb(gb); if (pwt->luma_log2_weight_denom > 7U) { av_log(logctx, AV_LOG_ERROR, "luma_log2_weight_denom %d is out of range\n", pwt->luma_log2_weight_denom); pwt->luma_log2_weight_denom = 0; } - if (pwt->chroma_log2_weight_denom > 7U) { - av_log(logctx, AV_LOG_ERROR, "chroma_log2_weight_denom %d is out of range\n", pwt->chroma_log2_weight_denom); - pwt->chroma_log2_weight_denom = 0; - } + luma_def = 1 << pwt->luma_log2_weight_denom; - luma_def = 1 << pwt->luma_log2_weight_denom; - chroma_def = 1 << pwt->chroma_log2_weight_denom; + if (sps->chroma_format_idc) { + pwt->chroma_log2_weight_denom = get_ue_golomb(gb); + if (pwt->chroma_log2_weight_denom > 7U) { + av_log(logctx, AV_LOG_ERROR, "chroma_log2_weight_denom %d is out of range\n", pwt->chroma_log2_weight_denom); + pwt->chroma_log2_weight_denom = 0; + } + chroma_def = 1 << pwt->chroma_log2_weight_denom; + } for (list = 0; list < 2; list++) { pwt->luma_weight_flag[list] = 0; @@ -102,9 +103,11 @@ int ff_h264_pred_weight_table(GetBitContext *gb, const SPS *sps, if (picture_structure == PICT_FRAME) { pwt->luma_weight[16 + 2 * i][list][0] = pwt->luma_weight[16 + 2 * i + 1][list][0] = pwt->luma_weight[i][list][0]; pwt->luma_weight[16 + 2 * i][list][1] = pwt->luma_weight[16 + 2 * i + 1][list][1] = pwt->luma_weight[i][list][1]; - for (j = 0; j < 2; j++) { - pwt->chroma_weight[16 + 2 * i][list][j][0] = pwt->chroma_weight[16 + 2 * i + 1][list][j][0] = pwt->chroma_weight[i][list][j][0]; - pwt->chroma_weight[16 + 2 * i][list][j][1] = pwt->chroma_weight[16 + 2 * i + 1][list][j][1] = pwt->chroma_weight[i][list][j][1]; + if (sps->chroma_format_idc) { + for (j = 0; j < 2; j++) { + pwt->chroma_weight[16 + 2 * i][list][j][0] = pwt->chroma_weight[16 + 2 * i + 1][list][j][0] = pwt->chroma_weight[i][list][j][0]; + pwt->chroma_weight[16 + 2 * i][list][j][1] = pwt->chroma_weight[16 + 2 * i + 1][list][j][1] = pwt->chroma_weight[i][list][j][1]; + } } } } From 83c12fefd22fc2326a000019e5c1a33e90a874e8 Mon Sep 17 00:00:00 2001 From: Ilia Valiakhmetov Date: Fri, 8 Sep 2017 03:48:17 +0700 Subject: [PATCH 3013/3374] avcodec/pthread_slice: add ff_slice_thread_execute_with_mainfunc() Signed-off-by: Ilia Valiakhmetov Signed-off-by: Ronald S. Bultje --- libavcodec/internal.h | 4 ++++ libavcodec/pthread_slice.c | 22 ++++++++++++++++++++-- libavcodec/thread.h | 4 +++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/libavcodec/internal.h b/libavcodec/internal.h index e5824cc62d93b..faa923c11f275 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -64,6 +64,10 @@ * dimensions to coded rather than display values. */ #define FF_CODEC_CAP_EXPORTS_CROPPING (1 << 4) +/** + * Codec initializes slice-based threading with a main function + */ +#define FF_CODEC_CAP_SLICE_THREAD_HAS_MF (1 << 5) #ifdef TRACE # define ff_tlog(ctx, ...) av_log(ctx, AV_LOG_TRACE, __VA_ARGS__) diff --git a/libavcodec/pthread_slice.c b/libavcodec/pthread_slice.c index c781d350dc40d..d659f9b0ba809 100644 --- a/libavcodec/pthread_slice.c +++ b/libavcodec/pthread_slice.c @@ -38,11 +38,13 @@ typedef int (action_func)(AVCodecContext *c, void *arg); typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr); +typedef int (main_func)(AVCodecContext *c); typedef struct SliceThreadContext { AVSliceThread *thread; action_func *func; action_func2 *func2; + main_func *mainfunc; void *args; int *rets; int job_size; @@ -54,6 +56,12 @@ typedef struct SliceThreadContext { pthread_mutex_t *progress_mutex; } SliceThreadContext; +static void main_function(void *priv) { + AVCodecContext *avctx = priv; + SliceThreadContext *c = avctx->internal->thread_ctx; + c->mainfunc(avctx); +} + static void worker_func(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads) { AVCodecContext *avctx = priv; @@ -99,7 +107,7 @@ static int thread_execute(AVCodecContext *avctx, action_func* func, void *arg, i c->func = func; c->rets = ret; - avpriv_slicethread_execute(c->thread, job_count, 0); + avpriv_slicethread_execute(c->thread, job_count, !!c->mainfunc ); return 0; } @@ -110,10 +118,19 @@ static int thread_execute2(AVCodecContext *avctx, action_func2* func2, void *arg return thread_execute(avctx, NULL, arg, ret, job_count, 0); } +int ff_slice_thread_execute_with_mainfunc(AVCodecContext *avctx, action_func2* func2, main_func *mainfunc, void *arg, int *ret, int job_count) +{ + SliceThreadContext *c = avctx->internal->thread_ctx; + c->func2 = func2; + c->mainfunc = mainfunc; + return thread_execute(avctx, NULL, arg, ret, job_count, 0); +} + int ff_slice_thread_init(AVCodecContext *avctx) { SliceThreadContext *c; int thread_count = avctx->thread_count; + static void (*mainfunc)(void *); #if HAVE_W32THREADS w32thread_init(); @@ -142,7 +159,8 @@ int ff_slice_thread_init(AVCodecContext *avctx) } avctx->internal->thread_ctx = c = av_mallocz(sizeof(*c)); - if (!c || (thread_count = avpriv_slicethread_create(&c->thread, avctx, worker_func, NULL, thread_count)) <= 1) { + mainfunc = avctx->codec->caps_internal & FF_CODEC_CAP_SLICE_THREAD_HAS_MF ? &main_function : NULL; + if (!c || (thread_count = avpriv_slicethread_create(&c->thread, avctx, worker_func, mainfunc, thread_count)) <= 1) { if (c) avpriv_slicethread_free(&c->thread); av_freep(&avctx->internal->thread_ctx); diff --git a/libavcodec/thread.h b/libavcodec/thread.h index 90864b59d9231..318619316c988 100644 --- a/libavcodec/thread.h +++ b/libavcodec/thread.h @@ -133,8 +133,10 @@ void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f); int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src); int ff_thread_init(AVCodecContext *s); +int ff_slice_thread_execute_with_mainfunc(AVCodecContext *avctx, + int (*action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr), + int (*main_func)(AVCodecContext *c), void *arg, int *ret, int job_count); void ff_thread_free(AVCodecContext *s); - int ff_alloc_entries(AVCodecContext *avctx, int count); void ff_reset_entries(AVCodecContext *avctx); void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n); From e59da0f7ff129d570adb72c6479f7ce07cf5a0f9 Mon Sep 17 00:00:00 2001 From: Ilia Valiakhmetov Date: Fri, 8 Sep 2017 04:02:49 +0700 Subject: [PATCH 3014/3374] avcodec/vp9: Add tile threading support Signed-off-by: Ilia Valiakhmetov Signed-off-by: Ronald S. Bultje --- libavcodec/vp9.c | 665 +++++++++++++++++++++++++---------- libavcodec/vp9_mc_template.c | 202 +++++------ libavcodec/vp9block.c | 522 +++++++++++++-------------- libavcodec/vp9dec.h | 103 +++--- libavcodec/vp9mvs.c | 97 ++--- libavcodec/vp9prob.c | 64 ++-- libavcodec/vp9recon.c | 153 ++++---- 7 files changed, 1051 insertions(+), 755 deletions(-) diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 94430db9a3c34..a71045e08130e 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -36,6 +36,64 @@ #define VP9_SYNCCODE 0x498342 +#if HAVE_THREADS +static void vp9_free_entries(AVCodecContext *avctx) { + VP9Context *s = avctx->priv_data; + + if (avctx->active_thread_type & FF_THREAD_SLICE) { + pthread_mutex_destroy(&s->progress_mutex); + pthread_cond_destroy(&s->progress_cond); + av_freep(&s->entries); + } +} + +static int vp9_alloc_entries(AVCodecContext *avctx, int n) { + VP9Context *s = avctx->priv_data; + int i; + + if (avctx->active_thread_type & FF_THREAD_SLICE) { + if (s->entries) + av_freep(&s->entries); + + s->entries = av_malloc_array(n, sizeof(atomic_int)); + + if (!s->entries) { + av_freep(&s->entries); + return AVERROR(ENOMEM); + } + + for (i = 0; i < n; i++) + atomic_init(&s->entries[i], 0); + + pthread_mutex_init(&s->progress_mutex, NULL); + pthread_cond_init(&s->progress_cond, NULL); + } + return 0; +} + +static void vp9_report_tile_progress(VP9Context *s, int field, int n) { + pthread_mutex_lock(&s->progress_mutex); + atomic_fetch_add_explicit(&s->entries[field], n, memory_order_relaxed); + pthread_cond_signal(&s->progress_cond); + pthread_mutex_unlock(&s->progress_mutex); +} + +static void vp9_await_tile_progress(VP9Context *s, int field, int n) { + if (atomic_load_explicit(&s->entries[field], memory_order_acquire) >= n) + return; + + pthread_mutex_lock(&s->progress_mutex); + while (atomic_load_explicit(&s->entries[field], memory_order_relaxed) != n) + pthread_cond_wait(&s->progress_cond, &s->progress_mutex); + pthread_mutex_unlock(&s->progress_mutex); +} +#else +static void vp9_free_entries(VP9Context *s) {} +static int vp9_alloc_entries(AVCodecContext *avctx, int n) { return 0; } +static void vp9_report_tile_progress(VP9Context *s, int field, int n) {} +static void vp9_await_tile_progress(VP9Context *s, int field, int n) {} +#endif + static void vp9_frame_unref(AVCodecContext *avctx, VP9Frame *f) { ff_thread_release_buffer(avctx, &f->tf); @@ -118,6 +176,7 @@ static int update_size(AVCodecContext *avctx, int w, int h) VP9Context *s = avctx->priv_data; uint8_t *p; int bytesperpixel = s->bytesperpixel, ret, cols, rows; + int lflvl_len, i; av_assert0(w > 0 && h > 0); @@ -170,13 +229,14 @@ static int update_size(AVCodecContext *avctx, int w, int h) s->sb_rows = (h + 63) >> 6; s->cols = (w + 7) >> 3; s->rows = (h + 7) >> 3; + lflvl_len = avctx->active_thread_type == FF_THREAD_SLICE ? s->sb_rows : 1; #define assign(var, type, n) var = (type) p; p += s->sb_cols * (n) * sizeof(*var) av_freep(&s->intra_pred_data[0]); // FIXME we slightly over-allocate here for subsampled chroma, but a little // bit of padding shouldn't affect performance... p = av_malloc(s->sb_cols * (128 + 192 * bytesperpixel + - sizeof(*s->lflvl) + 16 * sizeof(*s->above_mv_ctx))); + lflvl_len * sizeof(*s->lflvl) + 16 * sizeof(*s->above_mv_ctx))); if (!p) return AVERROR(ENOMEM); assign(s->intra_pred_data[0], uint8_t *, 64 * bytesperpixel); @@ -195,12 +255,15 @@ static int update_size(AVCodecContext *avctx, int w, int h) assign(s->above_comp_ctx, uint8_t *, 8); assign(s->above_ref_ctx, uint8_t *, 8); assign(s->above_filter_ctx, uint8_t *, 8); - assign(s->lflvl, VP9Filter *, 1); + assign(s->lflvl, VP9Filter *, lflvl_len); #undef assign - // these will be re-allocated a little later - av_freep(&s->b_base); - av_freep(&s->block_base); + if (s->td) { + for (i = 0; i < s->active_tile_cols; i++) { + av_freep(&s->td[i].b_base); + av_freep(&s->td[i].block_base); + } + } if (s->s.h.bpp != s->last_bpp) { ff_vp9dsp_init(&s->dsp, s->s.h.bpp, avctx->flags & AV_CODEC_FLAG_BITEXACT); @@ -213,40 +276,50 @@ static int update_size(AVCodecContext *avctx, int w, int h) static int update_block_buffers(AVCodecContext *avctx) { + int i; VP9Context *s = avctx->priv_data; int chroma_blocks, chroma_eobs, bytesperpixel = s->bytesperpixel; + VP9TileData *td = &s->td[0]; - if (s->b_base && s->block_base && s->block_alloc_using_2pass == s->s.frames[CUR_FRAME].uses_2pass) + if (td->b_base && td->block_base && s->block_alloc_using_2pass == s->s.frames[CUR_FRAME].uses_2pass) return 0; - av_free(s->b_base); - av_free(s->block_base); + av_free(td->b_base); + av_free(td->block_base); chroma_blocks = 64 * 64 >> (s->ss_h + s->ss_v); chroma_eobs = 16 * 16 >> (s->ss_h + s->ss_v); if (s->s.frames[CUR_FRAME].uses_2pass) { int sbs = s->sb_cols * s->sb_rows; - s->b_base = av_malloc_array(s->cols * s->rows, sizeof(VP9Block)); - s->block_base = av_mallocz(((64 * 64 + 2 * chroma_blocks) * bytesperpixel * sizeof(int16_t) + + td->b_base = av_malloc_array(s->cols * s->rows, sizeof(VP9Block)); + td->block_base = av_mallocz(((64 * 64 + 2 * chroma_blocks) * bytesperpixel * sizeof(int16_t) + 16 * 16 + 2 * chroma_eobs) * sbs); - if (!s->b_base || !s->block_base) + if (!td->b_base || !td->block_base) return AVERROR(ENOMEM); - s->uvblock_base[0] = s->block_base + sbs * 64 * 64 * bytesperpixel; - s->uvblock_base[1] = s->uvblock_base[0] + sbs * chroma_blocks * bytesperpixel; - s->eob_base = (uint8_t *) (s->uvblock_base[1] + sbs * chroma_blocks * bytesperpixel); - s->uveob_base[0] = s->eob_base + 16 * 16 * sbs; - s->uveob_base[1] = s->uveob_base[0] + chroma_eobs * sbs; + td->uvblock_base[0] = td->block_base + sbs * 64 * 64 * bytesperpixel; + td->uvblock_base[1] = td->uvblock_base[0] + sbs * chroma_blocks * bytesperpixel; + td->eob_base = (uint8_t *) (td->uvblock_base[1] + sbs * chroma_blocks * bytesperpixel); + td->uveob_base[0] = td->eob_base + 16 * 16 * sbs; + td->uveob_base[1] = td->uveob_base[0] + chroma_eobs * sbs; } else { - s->b_base = av_malloc(sizeof(VP9Block)); - s->block_base = av_mallocz((64 * 64 + 2 * chroma_blocks) * bytesperpixel * sizeof(int16_t) + - 16 * 16 + 2 * chroma_eobs); - if (!s->b_base || !s->block_base) - return AVERROR(ENOMEM); - s->uvblock_base[0] = s->block_base + 64 * 64 * bytesperpixel; - s->uvblock_base[1] = s->uvblock_base[0] + chroma_blocks * bytesperpixel; - s->eob_base = (uint8_t *) (s->uvblock_base[1] + chroma_blocks * bytesperpixel); - s->uveob_base[0] = s->eob_base + 16 * 16; - s->uveob_base[1] = s->uveob_base[0] + chroma_eobs; + for (i = 1; i < s->active_tile_cols; i++) { + if (s->td[i].b_base && s->td[i].block_base) { + av_free(s->td[i].b_base); + av_free(s->td[i].block_base); + } + } + for (i = 0; i < s->active_tile_cols; i++) { + s->td[i].b_base = av_malloc(sizeof(VP9Block)); + s->td[i].block_base = av_mallocz((64 * 64 + 2 * chroma_blocks) * bytesperpixel * sizeof(int16_t) + + 16 * 16 + 2 * chroma_eobs); + if (!s->td[i].b_base || !s->td[i].block_base) + return AVERROR(ENOMEM); + s->td[i].uvblock_base[0] = s->td[i].block_base + 64 * 64 * bytesperpixel; + s->td[i].uvblock_base[1] = s->td[i].uvblock_base[0] + chroma_blocks * bytesperpixel; + s->td[i].eob_base = (uint8_t *) (s->td[i].uvblock_base[1] + chroma_blocks * bytesperpixel); + s->td[i].uveob_base[0] = s->td[i].eob_base + 16 * 16; + s->td[i].uveob_base[1] = s->td[i].uveob_base[0] + chroma_eobs; + } } s->block_alloc_using_2pass = s->s.frames[CUR_FRAME].uses_2pass; @@ -543,8 +616,20 @@ static int decode_frame_header(AVCodecContext *avctx, sharp = get_bits(&s->gb, 3); // if sharpness changed, reinit lim/mblim LUTs. if it didn't change, keep // the old cache values since they are still valid - if (s->s.h.filter.sharpness != sharp) - memset(s->filter_lut.lim_lut, 0, sizeof(s->filter_lut.lim_lut)); + if (s->s.h.filter.sharpness != sharp) { + for (i = 1; i <= 63; i++) { + int limit = i; + + if (sharp > 0) { + limit >>= (sharp + 3) >> 2; + limit = FFMIN(limit, 9 - sharp); + } + limit = FFMAX(limit, 1); + + s->filter_lut.lim_lut[i] = limit; + s->filter_lut.mblim_lut[i] = 2 * (i + 2) + limit; + } + } s->s.h.filter.sharpness = sharp; if ((s->s.h.lf_delta.enabled = get_bits1(&s->gb))) { if ((s->s.h.lf_delta.updated = get_bits1(&s->gb))) { @@ -662,12 +747,36 @@ static int decode_frame_header(AVCodecContext *avctx, s->s.h.tiling.log2_tile_rows = decode012(&s->gb); s->s.h.tiling.tile_rows = 1 << s->s.h.tiling.log2_tile_rows; if (s->s.h.tiling.tile_cols != (1 << s->s.h.tiling.log2_tile_cols)) { + int n_range_coders; + VP56RangeCoder *rc; + + if (s->td) { + for (i = 0; i < s->active_tile_cols; i++) { + av_free(s->td[i].b_base); + av_free(s->td[i].block_base); + } + av_free(s->td); + } + s->s.h.tiling.tile_cols = 1 << s->s.h.tiling.log2_tile_cols; - s->c_b = av_fast_realloc(s->c_b, &s->c_b_size, - sizeof(VP56RangeCoder) * s->s.h.tiling.tile_cols); - if (!s->c_b) { - av_log(avctx, AV_LOG_ERROR, "Ran out of memory during range coder init\n"); + vp9_free_entries(avctx); + s->active_tile_cols = avctx->active_thread_type == FF_THREAD_SLICE ? + s->s.h.tiling.tile_cols : 1; + vp9_alloc_entries(avctx, s->sb_rows); + if (avctx->active_thread_type == FF_THREAD_SLICE) { + n_range_coders = 4; // max_tile_rows + } else { + n_range_coders = s->s.h.tiling.tile_cols; + } + s->td = av_mallocz_array(s->active_tile_cols, sizeof(VP9TileData) + + n_range_coders * sizeof(VP56RangeCoder)); + if (!s->td) return AVERROR(ENOMEM); + rc = (VP56RangeCoder *) &s->td[s->active_tile_cols]; + for (i = 0; i < s->active_tile_cols; i++) { + s->td[i].s = s; + s->td[i].c_b = rc; + rc += n_range_coders; } } @@ -735,12 +844,15 @@ static int decode_frame_header(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } - if (s->s.h.keyframe || s->s.h.intraonly) { - memset(s->counts.coef, 0, sizeof(s->counts.coef)); - memset(s->counts.eob, 0, sizeof(s->counts.eob)); - } else { - memset(&s->counts, 0, sizeof(s->counts)); + for (i = 0; i < s->active_tile_cols; i++) { + if (s->s.h.keyframe || s->s.h.intraonly) { + memset(s->td[i].counts.coef, 0, sizeof(s->td[0].counts.coef)); + memset(s->td[i].counts.eob, 0, sizeof(s->td[0].counts.eob)); + } else { + memset(&s->td[i].counts, 0, sizeof(s->td[0].counts)); + } } + /* FIXME is it faster to not copy here, but do it down in the fw updates * as explicit copies if the fw update is missing (and skip the copy upon * fw update)? */ @@ -789,7 +901,7 @@ static int decode_frame_header(AVCodecContext *avctx, else p[n] = r[n]; } - p[3] = 0; + memcpy(&p[3], ff_vp9_model_pareto8[p[2]], 8); } } else { for (j = 0; j < 2; j++) @@ -801,7 +913,7 @@ static int decode_frame_header(AVCodecContext *avctx, if (m > 3 && l == 0) // dc only has 3 pt break; memcpy(p, r, 3); - p[3] = 0; + memcpy(&p[3], ff_vp9_model_pareto8[p[2]], 8); } } if (s->s.h.txfmmode == i) @@ -929,12 +1041,12 @@ static int decode_frame_header(AVCodecContext *avctx, return (data2 - data) + size2; } -static void decode_sb(AVCodecContext *avctx, int row, int col, VP9Filter *lflvl, +static void decode_sb(VP9TileData *td, int row, int col, VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl) { - VP9Context *s = avctx->priv_data; + const VP9Context *s = td->s; int c = ((s->above_partition_ctx[col] >> (3 - bl)) & 1) | - (((s->left_partition_ctx[row & 0x7] >> (3 - bl)) & 1) << 1); + (((td->left_partition_ctx[row & 0x7] >> (3 - bl)) & 1) << 1); const uint8_t *p = s->s.h.keyframe || s->s.h.intraonly ? ff_vp9_default_kf_partition_probs[bl][c] : s->prob.p.partition[bl][c]; enum BlockPartition bp; @@ -944,75 +1056,75 @@ static void decode_sb(AVCodecContext *avctx, int row, int col, VP9Filter *lflvl, int bytesperpixel = s->bytesperpixel; if (bl == BL_8X8) { - bp = vp8_rac_get_tree(&s->c, ff_vp9_partition_tree, p); - ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, bl, bp); + bp = vp8_rac_get_tree(td->c, ff_vp9_partition_tree, p); + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, bl, bp); } else if (col + hbs < s->cols) { // FIXME why not <=? if (row + hbs < s->rows) { // FIXME why not <=? - bp = vp8_rac_get_tree(&s->c, ff_vp9_partition_tree, p); + bp = vp8_rac_get_tree(td->c, ff_vp9_partition_tree, p); switch (bp) { case PARTITION_NONE: - ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, bl, bp); break; case PARTITION_H: - ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, bl, bp); yoff += hbs * 8 * y_stride; uvoff += hbs * 8 * uv_stride >> s->ss_v; - ff_vp9_decode_block(avctx, row + hbs, col, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(td, row + hbs, col, lflvl, yoff, uvoff, bl, bp); break; case PARTITION_V: - ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, bl, bp); yoff += hbs * 8 * bytesperpixel; uvoff += hbs * 8 * bytesperpixel >> s->ss_h; - ff_vp9_decode_block(avctx, row, col + hbs, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(td, row, col + hbs, lflvl, yoff, uvoff, bl, bp); break; case PARTITION_SPLIT: - decode_sb(avctx, row, col, lflvl, yoff, uvoff, bl + 1); - decode_sb(avctx, row, col + hbs, lflvl, + decode_sb(td, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(td, row, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel, uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); yoff += hbs * 8 * y_stride; uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_sb(avctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); - decode_sb(avctx, row + hbs, col + hbs, lflvl, + decode_sb(td, row + hbs, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(td, row + hbs, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel, uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); break; default: av_assert0(0); } - } else if (vp56_rac_get_prob_branchy(&s->c, p[1])) { + } else if (vp56_rac_get_prob_branchy(td->c, p[1])) { bp = PARTITION_SPLIT; - decode_sb(avctx, row, col, lflvl, yoff, uvoff, bl + 1); - decode_sb(avctx, row, col + hbs, lflvl, + decode_sb(td, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(td, row, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel, uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); } else { bp = PARTITION_H; - ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, bl, bp); } } else if (row + hbs < s->rows) { // FIXME why not <=? - if (vp56_rac_get_prob_branchy(&s->c, p[2])) { + if (vp56_rac_get_prob_branchy(td->c, p[2])) { bp = PARTITION_SPLIT; - decode_sb(avctx, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(td, row, col, lflvl, yoff, uvoff, bl + 1); yoff += hbs * 8 * y_stride; uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_sb(avctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(td, row + hbs, col, lflvl, yoff, uvoff, bl + 1); } else { bp = PARTITION_V; - ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, bl, bp); } } else { bp = PARTITION_SPLIT; - decode_sb(avctx, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(td, row, col, lflvl, yoff, uvoff, bl + 1); } - s->counts.partition[bl][c][bp]++; + td->counts.partition[bl][c][bp]++; } -static void decode_sb_mem(AVCodecContext *avctx, int row, int col, VP9Filter *lflvl, +static void decode_sb_mem(VP9TileData *td, int row, int col, VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl) { - VP9Context *s = avctx->priv_data; - VP9Block *b = s->b; + const VP9Context *s = td->s; + VP9Block *b = td->b; ptrdiff_t hbs = 4 >> bl; AVFrame *f = s->s.frames[CUR_FRAME].tf.f; ptrdiff_t y_stride = f->linesize[0], uv_stride = f->linesize[1]; @@ -1020,39 +1132,39 @@ static void decode_sb_mem(AVCodecContext *avctx, int row, int col, VP9Filter *lf if (bl == BL_8X8) { av_assert2(b->bl == BL_8X8); - ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp); - } else if (s->b->bl == bl) { - ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp); + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, b->bl, b->bp); + } else if (td->b->bl == bl) { + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, b->bl, b->bp); if (b->bp == PARTITION_H && row + hbs < s->rows) { yoff += hbs * 8 * y_stride; uvoff += hbs * 8 * uv_stride >> s->ss_v; - ff_vp9_decode_block(avctx, row + hbs, col, lflvl, yoff, uvoff, b->bl, b->bp); + ff_vp9_decode_block(td, row + hbs, col, lflvl, yoff, uvoff, b->bl, b->bp); } else if (b->bp == PARTITION_V && col + hbs < s->cols) { yoff += hbs * 8 * bytesperpixel; uvoff += hbs * 8 * bytesperpixel >> s->ss_h; - ff_vp9_decode_block(avctx, row, col + hbs, lflvl, yoff, uvoff, b->bl, b->bp); + ff_vp9_decode_block(td, row, col + hbs, lflvl, yoff, uvoff, b->bl, b->bp); } } else { - decode_sb_mem(avctx, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb_mem(td, row, col, lflvl, yoff, uvoff, bl + 1); if (col + hbs < s->cols) { // FIXME why not <=? if (row + hbs < s->rows) { - decode_sb_mem(avctx, row, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel, + decode_sb_mem(td, row, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel, uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); yoff += hbs * 8 * y_stride; uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_sb_mem(avctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); - decode_sb_mem(avctx, row + hbs, col + hbs, lflvl, + decode_sb_mem(td, row + hbs, col, lflvl, yoff, uvoff, bl + 1); + decode_sb_mem(td, row + hbs, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel, uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); } else { yoff += hbs * 8 * bytesperpixel; uvoff += hbs * 8 * bytesperpixel >> s->ss_h; - decode_sb_mem(avctx, row, col + hbs, lflvl, yoff, uvoff, bl + 1); + decode_sb_mem(td, row, col + hbs, lflvl, yoff, uvoff, bl + 1); } } else if (row + hbs < s->rows) { yoff += hbs * 8 * y_stride; uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_sb_mem(avctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); + decode_sb_mem(td, row + hbs, col, lflvl, yoff, uvoff, bl + 1); } } } @@ -1067,9 +1179,13 @@ static void set_tile_offset(int *start, int *end, int idx, int log2_n, int n) static void free_buffers(VP9Context *s) { + int i; + av_freep(&s->intra_pred_data[0]); - av_freep(&s->b_base); - av_freep(&s->block_base); + for (i = 0; i < s->active_tile_cols; i++) { + av_freep(&s->td[i].b_base); + av_freep(&s->td[i].block_base); + } } static av_cold int vp9_decode_free(AVCodecContext *avctx) @@ -1090,10 +1206,249 @@ static av_cold int vp9_decode_free(AVCodecContext *avctx) ff_thread_release_buffer(avctx, &s->next_refs[i]); av_frame_free(&s->next_refs[i].f); } + free_buffers(s); - av_freep(&s->c_b); - s->c_b_size = 0; + vp9_free_entries(avctx); + av_freep(&s->td); + return 0; +} + +static int decode_tiles(AVCodecContext *avctx, + const uint8_t *data, int size) +{ + VP9Context *s = avctx->priv_data; + VP9TileData *td = &s->td[0]; + int row, col, tile_row, tile_col, ret; + int bytesperpixel; + int tile_row_start, tile_row_end, tile_col_start, tile_col_end; + AVFrame *f; + ptrdiff_t yoff, uvoff, ls_y, ls_uv; + + f = s->s.frames[CUR_FRAME].tf.f; + ls_y = f->linesize[0]; + ls_uv =f->linesize[1]; + bytesperpixel = s->bytesperpixel; + + yoff = uvoff = 0; + for (tile_row = 0; tile_row < s->s.h.tiling.tile_rows; tile_row++) { + set_tile_offset(&tile_row_start, &tile_row_end, + tile_row, s->s.h.tiling.log2_tile_rows, s->sb_rows); + + for (tile_col = 0; tile_col < s->s.h.tiling.tile_cols; tile_col++) { + int64_t tile_size; + if (tile_col == s->s.h.tiling.tile_cols - 1 && + tile_row == s->s.h.tiling.tile_rows - 1) { + tile_size = size; + } else { + tile_size = AV_RB32(data); + data += 4; + size -= 4; + } + if (tile_size > size) { + ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); + return AVERROR_INVALIDDATA; + } + ret = ff_vp56_init_range_decoder(&td->c_b[tile_col], data, tile_size); + if (ret < 0) + return ret; + if (vp56_rac_get_prob_branchy(&td->c_b[tile_col], 128)) { // marker bit + ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); + return AVERROR_INVALIDDATA; + } + data += tile_size; + size -= tile_size; + } + + for (row = tile_row_start; row < tile_row_end; + row += 8, yoff += ls_y * 64, uvoff += ls_uv * 64 >> s->ss_v) { + VP9Filter *lflvl_ptr = s->lflvl; + ptrdiff_t yoff2 = yoff, uvoff2 = uvoff; + + for (tile_col = 0; tile_col < s->s.h.tiling.tile_cols; tile_col++) { + set_tile_offset(&tile_col_start, &tile_col_end, + tile_col, s->s.h.tiling.log2_tile_cols, s->sb_cols); + td->tile_col_start = tile_col_start; + if (s->pass != 2) { + memset(td->left_partition_ctx, 0, 8); + memset(td->left_skip_ctx, 0, 8); + if (s->s.h.keyframe || s->s.h.intraonly) { + memset(td->left_mode_ctx, DC_PRED, 16); + } else { + memset(td->left_mode_ctx, NEARESTMV, 8); + } + memset(td->left_y_nnz_ctx, 0, 16); + memset(td->left_uv_nnz_ctx, 0, 32); + memset(td->left_segpred_ctx, 0, 8); + + td->c = &td->c_b[tile_col]; + } + + for (col = tile_col_start; + col < tile_col_end; + col += 8, yoff2 += 64 * bytesperpixel, + uvoff2 += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) { + // FIXME integrate with lf code (i.e. zero after each + // use, similar to invtxfm coefficients, or similar) + if (s->pass != 1) { + memset(lflvl_ptr->mask, 0, sizeof(lflvl_ptr->mask)); + } + + if (s->pass == 2) { + decode_sb_mem(td, row, col, lflvl_ptr, + yoff2, uvoff2, BL_64X64); + } else { + decode_sb(td, row, col, lflvl_ptr, + yoff2, uvoff2, BL_64X64); + } + } + } + + if (s->pass == 1) + continue; + + // backup pre-loopfilter reconstruction data for intra + // prediction of next row of sb64s + if (row + 8 < s->rows) { + memcpy(s->intra_pred_data[0], + f->data[0] + yoff + 63 * ls_y, + 8 * s->cols * bytesperpixel); + memcpy(s->intra_pred_data[1], + f->data[1] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv, + 8 * s->cols * bytesperpixel >> s->ss_h); + memcpy(s->intra_pred_data[2], + f->data[2] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv, + 8 * s->cols * bytesperpixel >> s->ss_h); + } + + // loopfilter one row + if (s->s.h.filter.level) { + yoff2 = yoff; + uvoff2 = uvoff; + lflvl_ptr = s->lflvl; + for (col = 0; col < s->cols; + col += 8, yoff2 += 64 * bytesperpixel, + uvoff2 += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) { + ff_vp9_loopfilter_sb(avctx, lflvl_ptr, row, col, + yoff2, uvoff2); + } + } + + // FIXME maybe we can make this more finegrained by running the + // loopfilter per-block instead of after each sbrow + // In fact that would also make intra pred left preparation easier? + ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, row >> 3, 0); + } + } + return 0; +} + + +static av_always_inline +int decode_tiles_mt(AVCodecContext *avctx, void *tdata, int jobnr, + int threadnr) +{ + VP9Context *s = avctx->priv_data; + VP9TileData *td = &s->td[jobnr]; + ptrdiff_t uvoff, yoff, ls_y, ls_uv; + int bytesperpixel = s->bytesperpixel, row, col, tile_row; + unsigned tile_cols_len; + int tile_row_start, tile_row_end, tile_col_start, tile_col_end; + VP9Filter *lflvl_ptr_base; + AVFrame *f; + + f = s->s.frames[CUR_FRAME].tf.f; + ls_y = f->linesize[0]; + ls_uv =f->linesize[1]; + + set_tile_offset(&tile_col_start, &tile_col_end, + jobnr, s->s.h.tiling.log2_tile_cols, s->sb_cols); + td->tile_col_start = tile_col_start; + uvoff = (64 * bytesperpixel >> s->ss_h)*(tile_col_start >> 3); + yoff = (64 * bytesperpixel)*(tile_col_start >> 3); + lflvl_ptr_base = s->lflvl+(tile_col_start >> 3); + + for (tile_row = 0; tile_row < s->s.h.tiling.tile_rows; tile_row++) { + set_tile_offset(&tile_row_start, &tile_row_end, + tile_row, s->s.h.tiling.log2_tile_rows, s->sb_rows); + + td->c = &td->c_b[tile_row]; + for (row = tile_row_start; row < tile_row_end; + row += 8, yoff += ls_y * 64, uvoff += ls_uv * 64 >> s->ss_v) { + ptrdiff_t yoff2 = yoff, uvoff2 = uvoff; + VP9Filter *lflvl_ptr = lflvl_ptr_base+s->sb_cols*(row >> 3); + + memset(td->left_partition_ctx, 0, 8); + memset(td->left_skip_ctx, 0, 8); + if (s->s.h.keyframe || s->s.h.intraonly) { + memset(td->left_mode_ctx, DC_PRED, 16); + } else { + memset(td->left_mode_ctx, NEARESTMV, 8); + } + memset(td->left_y_nnz_ctx, 0, 16); + memset(td->left_uv_nnz_ctx, 0, 32); + memset(td->left_segpred_ctx, 0, 8); + + for (col = tile_col_start; + col < tile_col_end; + col += 8, yoff2 += 64 * bytesperpixel, + uvoff2 += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) { + // FIXME integrate with lf code (i.e. zero after each + // use, similar to invtxfm coefficients, or similar) + memset(lflvl_ptr->mask, 0, sizeof(lflvl_ptr->mask)); + decode_sb(td, row, col, lflvl_ptr, + yoff2, uvoff2, BL_64X64); + } + + // backup pre-loopfilter reconstruction data for intra + // prediction of next row of sb64s + tile_cols_len = tile_col_end - tile_col_start; + if (row + 8 < s->rows) { + memcpy(s->intra_pred_data[0] + (tile_col_start * 8 * bytesperpixel), + f->data[0] + yoff + 63 * ls_y, + 8 * tile_cols_len * bytesperpixel); + memcpy(s->intra_pred_data[1] + (tile_col_start * 8 * bytesperpixel >> s->ss_h), + f->data[1] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv, + 8 * tile_cols_len * bytesperpixel >> s->ss_h); + memcpy(s->intra_pred_data[2] + (tile_col_start * 8 * bytesperpixel >> s->ss_h), + f->data[2] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv, + 8 * tile_cols_len * bytesperpixel >> s->ss_h); + } + + vp9_report_tile_progress(s, row >> 3, 1); + } + } + return 0; +} + +static av_always_inline +int loopfilter_proc(AVCodecContext *avctx) +{ + VP9Context *s = avctx->priv_data; + ptrdiff_t uvoff, yoff, ls_y, ls_uv; + VP9Filter *lflvl_ptr; + int bytesperpixel = s->bytesperpixel, col, i; + AVFrame *f; + + f = s->s.frames[CUR_FRAME].tf.f; + ls_y = f->linesize[0]; + ls_uv =f->linesize[1]; + + for (i = 0; i < s->sb_rows; i++) { + vp9_await_tile_progress(s, i, s->s.h.tiling.tile_cols); + + if (s->s.h.filter.level) { + yoff = (ls_y * 64)*i; + uvoff = (ls_uv * 64 >> s->ss_v)*i; + lflvl_ptr = s->lflvl+s->sb_cols*i; + for (col = 0; col < s->cols; + col += 8, yoff += 64 * bytesperpixel, + uvoff += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) { + ff_vp9_loopfilter_sb(avctx, lflvl_ptr, i << 3, col, + yoff, uvoff); + } + } + } return 0; } @@ -1104,12 +1459,10 @@ static int vp9_decode_frame(AVCodecContext *avctx, void *frame, const uint8_t *data = pkt->data; int size = pkt->size; VP9Context *s = avctx->priv_data; - int ret, tile_row, tile_col, i, ref, row, col; + int ret, i, j, ref; int retain_segmap_ref = s->s.frames[REF_FRAME_SEGMAP].segmentation_map && (!s->s.h.segmentation.enabled || !s->s.h.segmentation.update_map); - ptrdiff_t yoff, uvoff, ls_y, ls_uv; AVFrame *f; - int bytesperpixel; if ((ret = decode_frame_header(avctx, data, size, &ref)) < 0) { return ret; @@ -1159,8 +1512,6 @@ FF_ENABLE_DEPRECATION_WARNINGS f = s->s.frames[CUR_FRAME].tf.f; f->key_frame = s->s.h.keyframe; f->pict_type = (s->s.h.keyframe || s->s.h.intraonly) ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; - ls_y = f->linesize[0]; - ls_uv =f->linesize[1]; if (s->s.frames[REF_FRAME_SEGMAP].tf.f->buf[0] && (s->s.frames[REF_FRAME_MVPAIR].tf.f->width != s->s.frames[CUR_FRAME].tf.f->width || @@ -1195,7 +1546,6 @@ FF_ENABLE_DEPRECATION_WARNINGS } // main tile decode loop - bytesperpixel = s->bytesperpixel; memset(s->above_partition_ctx, 0, s->cols); memset(s->above_skip_ctx, 0, s->cols); if (s->s.h.keyframe || s->s.h.intraonly) { @@ -1233,20 +1583,28 @@ FF_ENABLE_DEPRECATION_WARNINGS ff_thread_finish_setup(avctx); } + if (avctx->active_thread_type & FF_THREAD_SLICE) { + for (i = 0; i < s->sb_rows; i++) + atomic_store(&s->entries[i], 0); + } + do { - yoff = uvoff = 0; - s->b = s->b_base; - s->block = s->block_base; - s->uvblock[0] = s->uvblock_base[0]; - s->uvblock[1] = s->uvblock_base[1]; - s->eob = s->eob_base; - s->uveob[0] = s->uveob_base[0]; - s->uveob[1] = s->uveob_base[1]; - - for (tile_row = 0; tile_row < s->s.h.tiling.tile_rows; tile_row++) { - set_tile_offset(&s->tile_row_start, &s->tile_row_end, - tile_row, s->s.h.tiling.log2_tile_rows, s->sb_rows); - if (s->pass != 2) { + for (i = 0; i < s->active_tile_cols; i++) { + s->td[i].b = s->td[i].b_base; + s->td[i].block = s->td[i].block_base; + s->td[i].uvblock[0] = s->td[i].uvblock_base[0]; + s->td[i].uvblock[1] = s->td[i].uvblock_base[1]; + s->td[i].eob = s->td[i].eob_base; + s->td[i].uveob[0] = s->td[i].uveob_base[0]; + s->td[i].uveob[1] = s->td[i].uveob_base[1]; + } + + if (avctx->active_thread_type == FF_THREAD_SLICE) { + int tile_row, tile_col; + + assert(!pass); + + for (tile_row = 0; tile_row < s->s.h.tiling.tile_rows; tile_row++) { for (tile_col = 0; tile_col < s->s.h.tiling.tile_cols; tile_col++) { int64_t tile_size; @@ -1258,105 +1616,31 @@ FF_ENABLE_DEPRECATION_WARNINGS data += 4; size -= 4; } - if (tile_size > size) { - ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); + if (tile_size > size) return AVERROR_INVALIDDATA; - } - ret = ff_vp56_init_range_decoder(&s->c_b[tile_col], data, tile_size); + ret = ff_vp56_init_range_decoder(&s->td[tile_col].c_b[tile_row], data, tile_size); if (ret < 0) return ret; - if (vp56_rac_get_prob_branchy(&s->c_b[tile_col], 128)) { // marker bit - ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); + if (vp56_rac_get_prob_branchy(&s->td[tile_col].c_b[tile_row], 128)) // marker bit return AVERROR_INVALIDDATA; - } data += tile_size; size -= tile_size; } } - for (row = s->tile_row_start; row < s->tile_row_end; - row += 8, yoff += ls_y * 64, uvoff += ls_uv * 64 >> s->ss_v) { - VP9Filter *lflvl_ptr = s->lflvl; - ptrdiff_t yoff2 = yoff, uvoff2 = uvoff; - - for (tile_col = 0; tile_col < s->s.h.tiling.tile_cols; tile_col++) { - set_tile_offset(&s->tile_col_start, &s->tile_col_end, - tile_col, s->s.h.tiling.log2_tile_cols, s->sb_cols); - - if (s->pass != 2) { - memset(s->left_partition_ctx, 0, 8); - memset(s->left_skip_ctx, 0, 8); - if (s->s.h.keyframe || s->s.h.intraonly) { - memset(s->left_mode_ctx, DC_PRED, 16); - } else { - memset(s->left_mode_ctx, NEARESTMV, 8); - } - memset(s->left_y_nnz_ctx, 0, 16); - memset(s->left_uv_nnz_ctx, 0, 32); - memset(s->left_segpred_ctx, 0, 8); - - memcpy(&s->c, &s->c_b[tile_col], sizeof(s->c)); - } - - for (col = s->tile_col_start; - col < s->tile_col_end; - col += 8, yoff2 += 64 * bytesperpixel, - uvoff2 += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) { - // FIXME integrate with lf code (i.e. zero after each - // use, similar to invtxfm coefficients, or similar) - if (s->pass != 1) { - memset(lflvl_ptr->mask, 0, sizeof(lflvl_ptr->mask)); - } - - if (s->pass == 2) { - decode_sb_mem(avctx, row, col, lflvl_ptr, - yoff2, uvoff2, BL_64X64); - } else { - decode_sb(avctx, row, col, lflvl_ptr, - yoff2, uvoff2, BL_64X64); - } - } - if (s->pass != 2) - memcpy(&s->c_b[tile_col], &s->c, sizeof(s->c)); - } - - if (s->pass == 1) - continue; - - // backup pre-loopfilter reconstruction data for intra - // prediction of next row of sb64s - if (row + 8 < s->rows) { - memcpy(s->intra_pred_data[0], - f->data[0] + yoff + 63 * ls_y, - 8 * s->cols * bytesperpixel); - memcpy(s->intra_pred_data[1], - f->data[1] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv, - 8 * s->cols * bytesperpixel >> s->ss_h); - memcpy(s->intra_pred_data[2], - f->data[2] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv, - 8 * s->cols * bytesperpixel >> s->ss_h); - } - - // loopfilter one row - if (s->s.h.filter.level) { - yoff2 = yoff; - uvoff2 = uvoff; - lflvl_ptr = s->lflvl; - for (col = 0; col < s->cols; - col += 8, yoff2 += 64 * bytesperpixel, - uvoff2 += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) { - ff_vp9_loopfilter_sb(avctx, lflvl_ptr, row, col, - yoff2, uvoff2); - } - } - - // FIXME maybe we can make this more finegrained by running the - // loopfilter per-block instead of after each sbrow - // In fact that would also make intra pred left preparation easier? - ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, row >> 3, 0); - } + ff_slice_thread_execute_with_mainfunc(avctx, decode_tiles_mt, loopfilter_proc, s->td, NULL, s->s.h.tiling.tile_cols); + } else { + ret = decode_tiles(avctx, data, size); + if (ret < 0) + return ret; } + // Sum all counts fields into td[0].counts for tile threading + if (avctx->active_thread_type == FF_THREAD_SLICE) + for (i = 1; i < s->s.h.tiling.tile_cols; i++) + for (j = 0; j < sizeof(s->td[i].counts) / sizeof(unsigned); j++) + ((unsigned *)&s->td[0].counts)[j] += ((unsigned *)&s->td[i].counts)[j]; + if (s->pass < 2 && s->s.h.refreshctx && !s->s.h.parallelmode) { ff_vp9_adapt_probs(s); ff_thread_finish_setup(avctx); @@ -1492,7 +1776,8 @@ AVCodec ff_vp9_decoder = { .init = vp9_decode_init, .close = vp9_decode_free, .decode = vp9_decode_frame, - .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS, + .caps_internal = FF_CODEC_CAP_SLICE_THREAD_HAS_MF, .flush = vp9_decode_flush, .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp9_decode_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(vp9_decode_update_thread_context), diff --git a/libavcodec/vp9_mc_template.c b/libavcodec/vp9_mc_template.c index 8ff654bc380ba..31e692f36251e 100644 --- a/libavcodec/vp9_mc_template.c +++ b/libavcodec/vp9_mc_template.c @@ -27,19 +27,19 @@ (VP56mv) { .x = ROUNDED_DIV(a.x + b.x + c.x + d.x, 4), \ .y = ROUNDED_DIV(a.y + b.y + c.y + d.y, 4) } -static void FN(inter_pred)(AVCodecContext *avctx) +static void FN(inter_pred)(VP9TileData *td) { static const uint8_t bwlog_tab[2][N_BS_SIZES] = { { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 }, { 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4 }, }; - VP9Context *s = avctx->priv_data; - VP9Block *b = s->b; - int row = s->row, col = s->col; + VP9Context *s = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col; ThreadFrame *tref1 = &s->s.refs[s->s.h.refidx[b->ref[0]]], *tref2; AVFrame *ref1 = tref1->f, *ref2; int w1 = ref1->width, h1 = ref1->height, w2, h2; - ptrdiff_t ls_y = s->y_stride, ls_uv = s->uv_stride; + ptrdiff_t ls_y = td->y_stride, ls_uv = td->uv_stride; int bytesperpixel = BYTES_PER_PIXEL; if (b->comp) { @@ -55,26 +55,26 @@ static void FN(inter_pred)(AVCodecContext *avctx) #if SCALED == 0 if (b->bs == BS_8x4) { - mc_luma_dir(s, mc[3][b->filter][0], s->dst[0], ls_y, + mc_luma_dir(td, mc[3][b->filter][0], td->dst[0], ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, col << 3, &b->mv[0][0],,,,, 8, 4, w1, h1, 0); - mc_luma_dir(s, mc[3][b->filter][0], - s->dst[0] + 4 * ls_y, ls_y, + mc_luma_dir(td, mc[3][b->filter][0], + td->dst[0] + 4 * ls_y, ls_y, ref1->data[0], ref1->linesize[0], tref1, (row << 3) + 4, col << 3, &b->mv[2][0],,,,, 8, 4, w1, h1, 0); w1 = (w1 + s->ss_h) >> s->ss_h; if (s->ss_v) { h1 = (h1 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[2][0]); - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 2, col << (3 - s->ss_h), &uvmv,,,,, 8 >> s->ss_h, 4, w1, h1, 0); } else { - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 3, col << (3 - s->ss_h), @@ -87,8 +87,8 @@ static void FN(inter_pred)(AVCodecContext *avctx) } else { uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[2][0]); } - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][0], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][0], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, (row << 3) + 4, col << (3 - s->ss_h), @@ -96,26 +96,26 @@ static void FN(inter_pred)(AVCodecContext *avctx) } if (b->comp) { - mc_luma_dir(s, mc[3][b->filter][1], s->dst[0], ls_y, + mc_luma_dir(td, mc[3][b->filter][1], td->dst[0], ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, col << 3, &b->mv[0][1],,,,, 8, 4, w2, h2, 1); - mc_luma_dir(s, mc[3][b->filter][1], - s->dst[0] + 4 * ls_y, ls_y, + mc_luma_dir(td, mc[3][b->filter][1], + td->dst[0] + 4 * ls_y, ls_y, ref2->data[0], ref2->linesize[0], tref2, (row << 3) + 4, col << 3, &b->mv[2][1],,,,, 8, 4, w2, h2, 1); w2 = (w2 + s->ss_h) >> s->ss_h; if (s->ss_v) { h2 = (h2 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[2][1]); - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 2, col << (3 - s->ss_h), &uvmv,,,,, 8 >> s->ss_h, 4, w2, h2, 1); } else { - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 3, col << (3 - s->ss_h), @@ -128,8 +128,8 @@ static void FN(inter_pred)(AVCodecContext *avctx) } else { uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[2][1]); } - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][1], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][1], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, (row << 3) + 4, col << (3 - s->ss_h), @@ -137,32 +137,32 @@ static void FN(inter_pred)(AVCodecContext *avctx) } } } else if (b->bs == BS_4x8) { - mc_luma_dir(s, mc[4][b->filter][0], s->dst[0], ls_y, + mc_luma_dir(td, mc[4][b->filter][0], td->dst[0], ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, col << 3, &b->mv[0][0],,,,, 4, 8, w1, h1, 0); - mc_luma_dir(s, mc[4][b->filter][0], s->dst[0] + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][0], td->dst[0] + 4 * bytesperpixel, ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, (col << 3) + 4, &b->mv[1][0],,,,, 4, 8, w1, h1, 0); h1 = (h1 + s->ss_v) >> s->ss_v; if (s->ss_h) { w1 = (w1 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[1][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << (3 - s->ss_v), col << 2, &uvmv,,,,, 4, 8 >> s->ss_v, w1, h1, 0); } else { - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << (3 - s->ss_v), col << 3, &b->mv[0][0],,,,, 4, 8 >> s->ss_v, w1, h1, 0); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << (3 - s->ss_v), (col << 3) + 4, @@ -170,32 +170,32 @@ static void FN(inter_pred)(AVCodecContext *avctx) } if (b->comp) { - mc_luma_dir(s, mc[4][b->filter][1], s->dst[0], ls_y, + mc_luma_dir(td, mc[4][b->filter][1], td->dst[0], ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, col << 3, &b->mv[0][1],,,,, 4, 8, w2, h2, 1); - mc_luma_dir(s, mc[4][b->filter][1], s->dst[0] + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][1], td->dst[0] + 4 * bytesperpixel, ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, (col << 3) + 4, &b->mv[1][1],,,,, 4, 8, w2, h2, 1); h2 = (h2 + s->ss_v) >> s->ss_v; if (s->ss_h) { w2 = (w2 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[1][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << (3 - s->ss_v), col << 2, &uvmv,,,,, 4, 8 >> s->ss_v, w2, h2, 1); } else { - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << (3 - s->ss_v), col << 3, &b->mv[0][1],,,,, 4, 8 >> s->ss_v, w2, h2, 1); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << (3 - s->ss_v), (col << 3) + 4, @@ -211,21 +211,21 @@ static void FN(inter_pred)(AVCodecContext *avctx) // FIXME if two horizontally adjacent blocks have the same MV, // do a w8 instead of a w4 call - mc_luma_dir(s, mc[4][b->filter][0], s->dst[0], ls_y, + mc_luma_dir(td, mc[4][b->filter][0], td->dst[0], ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, col << 3, &b->mv[0][0], 0, 0, 8, 8, 4, 4, w1, h1, 0); - mc_luma_dir(s, mc[4][b->filter][0], s->dst[0] + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][0], td->dst[0] + 4 * bytesperpixel, ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, (col << 3) + 4, &b->mv[1][0], 4, 0, 8, 8, 4, 4, w1, h1, 0); - mc_luma_dir(s, mc[4][b->filter][0], - s->dst[0] + 4 * ls_y, ls_y, + mc_luma_dir(td, mc[4][b->filter][0], + td->dst[0] + 4 * ls_y, ls_y, ref1->data[0], ref1->linesize[0], tref1, (row << 3) + 4, col << 3, &b->mv[2][0], 0, 4, 8, 8, 4, 4, w1, h1, 0); - mc_luma_dir(s, mc[4][b->filter][0], - s->dst[0] + 4 * ls_y + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][0], + td->dst[0] + 4 * ls_y + 4 * bytesperpixel, ls_y, ref1->data[0], ref1->linesize[0], tref1, (row << 3) + 4, (col << 3) + 4, &b->mv[3][0], 4, 4, 8, 8, 4, 4, w1, h1, 0); @@ -235,24 +235,24 @@ static void FN(inter_pred)(AVCodecContext *avctx) w1 = (w1 + 1) >> 1; uvmv = ROUNDED_DIV_MVx4(b->mv[0][0], b->mv[1][0], b->mv[2][0], b->mv[3][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 2, col << 2, &uvmv, 0, 0, 4, 4, 4, 4, w1, h1, 0); } else { uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[2][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 2, col << 3, &uvmv, 0, 0, 8, 4, 4, 4, w1, h1, 0); uvmv = ROUNDED_DIV_MVx2(b->mv[1][0], b->mv[3][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 2, (col << 3) + 4, @@ -262,8 +262,8 @@ static void FN(inter_pred)(AVCodecContext *avctx) if (s->ss_h) { w1 = (w1 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[1][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 3, col << 2, @@ -272,35 +272,35 @@ static void FN(inter_pred)(AVCodecContext *avctx) // bottom block // https://code.google.com/p/webm/issues/detail?id=993 uvmv = ROUNDED_DIV_MVx2(b->mv[1][0], b->mv[2][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, (row << 3) + 4, col << 2, &uvmv, 0, 4, 4, 8, 4, 4, w1, h1, 0); } else { - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 3, col << 3, &b->mv[0][0], 0, 0, 8, 8, 4, 4, w1, h1, 0); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 3, (col << 3) + 4, &b->mv[1][0], 4, 0, 8, 8, 4, 4, w1, h1, 0); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, (row << 3) + 4, col << 3, &b->mv[2][0], 0, 4, 8, 8, 4, 4, w1, h1, 0); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * ls_uv + 4 * bytesperpixel, - s->dst[2] + 4 * ls_uv + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * ls_uv + 4 * bytesperpixel, + td->dst[2] + 4 * ls_uv + 4 * bytesperpixel, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, (row << 3) + 4, (col << 3) + 4, @@ -309,18 +309,18 @@ static void FN(inter_pred)(AVCodecContext *avctx) } if (b->comp) { - mc_luma_dir(s, mc[4][b->filter][1], s->dst[0], ls_y, + mc_luma_dir(td, mc[4][b->filter][1], td->dst[0], ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, col << 3, &b->mv[0][1], 0, 0, 8, 8, 4, 4, w2, h2, 1); - mc_luma_dir(s, mc[4][b->filter][1], s->dst[0] + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][1], td->dst[0] + 4 * bytesperpixel, ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, (col << 3) + 4, &b->mv[1][1], 4, 0, 8, 8, 4, 4, w2, h2, 1); - mc_luma_dir(s, mc[4][b->filter][1], - s->dst[0] + 4 * ls_y, ls_y, + mc_luma_dir(td, mc[4][b->filter][1], + td->dst[0] + 4 * ls_y, ls_y, ref2->data[0], ref2->linesize[0], tref2, (row << 3) + 4, col << 3, &b->mv[2][1], 0, 4, 8, 8, 4, 4, w2, h2, 1); - mc_luma_dir(s, mc[4][b->filter][1], - s->dst[0] + 4 * ls_y + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][1], + td->dst[0] + 4 * ls_y + 4 * bytesperpixel, ls_y, ref2->data[0], ref2->linesize[0], tref2, (row << 3) + 4, (col << 3) + 4, &b->mv[3][1], 4, 4, 8, 8, 4, 4, w2, h2, 1); if (s->ss_v) { @@ -329,24 +329,24 @@ static void FN(inter_pred)(AVCodecContext *avctx) w2 = (w2 + 1) >> 1; uvmv = ROUNDED_DIV_MVx4(b->mv[0][1], b->mv[1][1], b->mv[2][1], b->mv[3][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 2, col << 2, &uvmv, 0, 0, 4, 4, 4, 4, w2, h2, 1); } else { uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[2][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 2, col << 3, &uvmv, 0, 0, 8, 4, 4, 4, w2, h2, 1); uvmv = ROUNDED_DIV_MVx2(b->mv[1][1], b->mv[3][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 2, (col << 3) + 4, @@ -356,8 +356,8 @@ static void FN(inter_pred)(AVCodecContext *avctx) if (s->ss_h) { w2 = (w2 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[1][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 3, col << 2, @@ -366,35 +366,35 @@ static void FN(inter_pred)(AVCodecContext *avctx) // bottom block // https://code.google.com/p/webm/issues/detail?id=993 uvmv = ROUNDED_DIV_MVx2(b->mv[1][1], b->mv[2][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, (row << 3) + 4, col << 2, &uvmv, 0, 4, 4, 8, 4, 4, w2, h2, 1); } else { - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 3, col << 3, &b->mv[0][1], 0, 0, 8, 8, 4, 4, w2, h2, 1); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 3, (col << 3) + 4, &b->mv[1][1], 4, 0, 8, 8, 4, 4, w2, h2, 1); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, (row << 3) + 4, col << 3, &b->mv[2][1], 0, 4, 8, 8, 4, 4, w2, h2, 1); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * ls_uv + 4 * bytesperpixel, - s->dst[2] + 4 * ls_uv + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * ls_uv + 4 * bytesperpixel, + td->dst[2] + 4 * ls_uv + 4 * bytesperpixel, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, (row << 3) + 4, (col << 3) + 4, @@ -410,26 +410,26 @@ static void FN(inter_pred)(AVCodecContext *avctx) int uvbw = ff_vp9_bwh_tab[s->ss_h][b->bs][0] * 4; int uvbh = ff_vp9_bwh_tab[s->ss_v][b->bs][1] * 4; - mc_luma_dir(s, mc[bwl][b->filter][0], s->dst[0], ls_y, + mc_luma_dir(td, mc[bwl][b->filter][0], td->dst[0], ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, col << 3, &b->mv[0][0], 0, 0, bw, bh, bw, bh, w1, h1, 0); w1 = (w1 + s->ss_h) >> s->ss_h; h1 = (h1 + s->ss_v) >> s->ss_v; - mc_chroma_dir(s, mc[bwl + s->ss_h][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[bwl + s->ss_h][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << (3 - s->ss_v), col << (3 - s->ss_h), &b->mv[0][0], 0, 0, uvbw, uvbh, uvbw, uvbh, w1, h1, 0); if (b->comp) { - mc_luma_dir(s, mc[bwl][b->filter][1], s->dst[0], ls_y, + mc_luma_dir(td, mc[bwl][b->filter][1], td->dst[0], ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, col << 3, &b->mv[0][1], 0, 0, bw, bh, bw, bh, w2, h2, 1); w2 = (w2 + s->ss_h) >> s->ss_h; h2 = (h2 + s->ss_v) >> s->ss_v; - mc_chroma_dir(s, mc[bwl + s->ss_h][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[bwl + s->ss_h][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << (3 - s->ss_v), col << (3 - s->ss_h), diff --git a/libavcodec/vp9block.c b/libavcodec/vp9block.c index a16ccdccdb87f..d4ace149a56f5 100644 --- a/libavcodec/vp9block.c +++ b/libavcodec/vp9block.c @@ -77,7 +77,7 @@ static av_always_inline void setctx_2d(uint8_t *ptr, int w, int h, } } -static void decode_mode(AVCodecContext *avctx) +static void decode_mode(VP9TileData *td) { static const uint8_t left_ctx[N_BS_SIZES] = { 0x0, 0x8, 0x0, 0x8, 0xc, 0x8, 0xc, 0xe, 0xc, 0xe, 0xf, 0xe, 0xf @@ -89,25 +89,25 @@ static void decode_mode(AVCodecContext *avctx) TX_32X32, TX_32X32, TX_32X32, TX_32X32, TX_16X16, TX_16X16, TX_16X16, TX_8X8, TX_8X8, TX_8X8, TX_4X4, TX_4X4, TX_4X4 }; - VP9Context *s = avctx->priv_data; - VP9Block *b = s->b; - int row = s->row, col = s->col, row7 = s->row7; + VP9Context *s = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col, row7 = td->row7; enum TxfmMode max_tx = max_tx_for_bl_bp[b->bs]; int bw4 = ff_vp9_bwh_tab[1][b->bs][0], w4 = FFMIN(s->cols - col, bw4); int bh4 = ff_vp9_bwh_tab[1][b->bs][1], h4 = FFMIN(s->rows - row, bh4), y; - int have_a = row > 0, have_l = col > s->tile_col_start; + int have_a = row > 0, have_l = col > td->tile_col_start; int vref, filter_id; if (!s->s.h.segmentation.enabled) { b->seg_id = 0; } else if (s->s.h.keyframe || s->s.h.intraonly) { b->seg_id = !s->s.h.segmentation.update_map ? 0 : - vp8_rac_get_tree(&s->c, ff_vp9_segmentation_tree, s->s.h.segmentation.prob); + vp8_rac_get_tree(td->c, ff_vp9_segmentation_tree, s->s.h.segmentation.prob); } else if (!s->s.h.segmentation.update_map || (s->s.h.segmentation.temporal && - vp56_rac_get_prob_branchy(&s->c, + vp56_rac_get_prob_branchy(td->c, s->s.h.segmentation.pred_prob[s->above_segpred_ctx[col] + - s->left_segpred_ctx[row7]]))) { + td->left_segpred_ctx[row7]]))) { if (!s->s.h.errorres && s->s.frames[REF_FRAME_SEGMAP].segmentation_map) { int pred = 8, x; uint8_t *refsegmap = s->s.frames[REF_FRAME_SEGMAP].segmentation_map; @@ -126,13 +126,13 @@ static void decode_mode(AVCodecContext *avctx) } memset(&s->above_segpred_ctx[col], 1, w4); - memset(&s->left_segpred_ctx[row7], 1, h4); + memset(&td->left_segpred_ctx[row7], 1, h4); } else { - b->seg_id = vp8_rac_get_tree(&s->c, ff_vp9_segmentation_tree, + b->seg_id = vp8_rac_get_tree(td->c, ff_vp9_segmentation_tree, s->s.h.segmentation.prob); memset(&s->above_segpred_ctx[col], 0, w4); - memset(&s->left_segpred_ctx[row7], 0, h4); + memset(&td->left_segpred_ctx[row7], 0, h4); } if (s->s.h.segmentation.enabled && (s->s.h.segmentation.update_map || s->s.h.keyframe || s->s.h.intraonly)) { @@ -143,9 +143,9 @@ static void decode_mode(AVCodecContext *avctx) b->skip = s->s.h.segmentation.enabled && s->s.h.segmentation.feat[b->seg_id].skip_enabled; if (!b->skip) { - int c = s->left_skip_ctx[row7] + s->above_skip_ctx[col]; - b->skip = vp56_rac_get_prob(&s->c, s->prob.p.skip[c]); - s->counts.skip[c][b->skip]++; + int c = td->left_skip_ctx[row7] + s->above_skip_ctx[col]; + b->skip = vp56_rac_get_prob(td->c, s->prob.p.skip[c]); + td->counts.skip[c][b->skip]++; } if (s->s.h.keyframe || s->s.h.intraonly) { @@ -156,14 +156,14 @@ static void decode_mode(AVCodecContext *avctx) int c, bit; if (have_a && have_l) { - c = s->above_intra_ctx[col] + s->left_intra_ctx[row7]; + c = s->above_intra_ctx[col] + td->left_intra_ctx[row7]; c += (c == 2); } else { c = have_a ? 2 * s->above_intra_ctx[col] : - have_l ? 2 * s->left_intra_ctx[row7] : 0; + have_l ? 2 * td->left_intra_ctx[row7] : 0; } - bit = vp56_rac_get_prob(&s->c, s->prob.p.intra[c]); - s->counts.intra[c][bit]++; + bit = vp56_rac_get_prob(td->c, s->prob.p.intra[c]); + td->counts.intra[c][bit]++; b->intra = !bit; } @@ -173,37 +173,37 @@ static void decode_mode(AVCodecContext *avctx) if (have_l) { c = (s->above_skip_ctx[col] ? max_tx : s->above_txfm_ctx[col]) + - (s->left_skip_ctx[row7] ? max_tx : - s->left_txfm_ctx[row7]) > max_tx; + (td->left_skip_ctx[row7] ? max_tx : + td->left_txfm_ctx[row7]) > max_tx; } else { c = s->above_skip_ctx[col] ? 1 : (s->above_txfm_ctx[col] * 2 > max_tx); } } else if (have_l) { - c = s->left_skip_ctx[row7] ? 1 : - (s->left_txfm_ctx[row7] * 2 > max_tx); + c = td->left_skip_ctx[row7] ? 1 : + (td->left_txfm_ctx[row7] * 2 > max_tx); } else { c = 1; } switch (max_tx) { case TX_32X32: - b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][0]); + b->tx = vp56_rac_get_prob(td->c, s->prob.p.tx32p[c][0]); if (b->tx) { - b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][1]); + b->tx += vp56_rac_get_prob(td->c, s->prob.p.tx32p[c][1]); if (b->tx == 2) - b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][2]); + b->tx += vp56_rac_get_prob(td->c, s->prob.p.tx32p[c][2]); } - s->counts.tx32p[c][b->tx]++; + td->counts.tx32p[c][b->tx]++; break; case TX_16X16: - b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx16p[c][0]); + b->tx = vp56_rac_get_prob(td->c, s->prob.p.tx16p[c][0]); if (b->tx) - b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx16p[c][1]); - s->counts.tx16p[c][b->tx]++; + b->tx += vp56_rac_get_prob(td->c, s->prob.p.tx16p[c][1]); + td->counts.tx16p[c][b->tx]++; break; case TX_8X8: - b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx8p[c]); - s->counts.tx8p[c][b->tx]++; + b->tx = vp56_rac_get_prob(td->c, s->prob.p.tx8p[c]); + td->counts.tx8p[c][b->tx]++; break; case TX_4X4: b->tx = TX_4X4; @@ -215,7 +215,7 @@ static void decode_mode(AVCodecContext *avctx) if (s->s.h.keyframe || s->s.h.intraonly) { uint8_t *a = &s->above_mode_ctx[col * 2]; - uint8_t *l = &s->left_mode_ctx[(row7) << 1]; + uint8_t *l = &td->left_mode_ctx[(row7) << 1]; b->comp = 0; if (b->bs > BS_8x8) { @@ -223,10 +223,10 @@ static void decode_mode(AVCodecContext *avctx) // necessary, they're just there to make the code slightly // simpler for now b->mode[0] = - a[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + a[0] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, ff_vp9_default_kf_ymode_probs[a[0]][l[0]]); if (b->bs != BS_8x4) { - b->mode[1] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + b->mode[1] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, ff_vp9_default_kf_ymode_probs[a[1]][b->mode[0]]); l[0] = a[1] = b->mode[1]; @@ -237,10 +237,10 @@ static void decode_mode(AVCodecContext *avctx) } if (b->bs != BS_4x8) { b->mode[2] = - a[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + a[0] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, ff_vp9_default_kf_ymode_probs[a[0]][l[1]]); if (b->bs != BS_8x4) { - b->mode[3] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + b->mode[3] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, ff_vp9_default_kf_ymode_probs[a[1]][b->mode[2]]); l[1] = a[1] = b->mode[3]; @@ -256,7 +256,7 @@ static void decode_mode(AVCodecContext *avctx) b->mode[3] = b->mode[1]; } } else { - b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + b->mode[0] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, ff_vp9_default_kf_ymode_probs[*a][*l]); b->mode[3] = b->mode[2] = @@ -265,29 +265,29 @@ static void decode_mode(AVCodecContext *avctx) memset(a, b->mode[0], ff_vp9_bwh_tab[0][b->bs][0]); memset(l, b->mode[0], ff_vp9_bwh_tab[0][b->bs][1]); } - b->uvmode = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + b->uvmode = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, ff_vp9_default_kf_uvmode_probs[b->mode[3]]); } else if (b->intra) { b->comp = 0; if (b->bs > BS_8x8) { - b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + b->mode[0] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, s->prob.p.y_mode[0]); - s->counts.y_mode[0][b->mode[0]]++; + td->counts.y_mode[0][b->mode[0]]++; if (b->bs != BS_8x4) { - b->mode[1] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + b->mode[1] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, s->prob.p.y_mode[0]); - s->counts.y_mode[0][b->mode[1]]++; + td->counts.y_mode[0][b->mode[1]]++; } else { b->mode[1] = b->mode[0]; } if (b->bs != BS_4x8) { - b->mode[2] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + b->mode[2] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, s->prob.p.y_mode[0]); - s->counts.y_mode[0][b->mode[2]]++; + td->counts.y_mode[0][b->mode[2]]++; if (b->bs != BS_8x4) { - b->mode[3] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + b->mode[3] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, s->prob.p.y_mode[0]); - s->counts.y_mode[0][b->mode[3]]++; + td->counts.y_mode[0][b->mode[3]]++; } else { b->mode[3] = b->mode[2]; } @@ -301,16 +301,16 @@ static void decode_mode(AVCodecContext *avctx) }; int sz = size_group[b->bs]; - b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + b->mode[0] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, s->prob.p.y_mode[sz]); b->mode[1] = b->mode[2] = b->mode[3] = b->mode[0]; - s->counts.y_mode[sz][b->mode[3]]++; + td->counts.y_mode[sz][b->mode[3]]++; } - b->uvmode = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + b->uvmode = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, s->prob.p.uv_mode[b->mode[3]]); - s->counts.uv_mode[b->mode[3]][b->uvmode]++; + td->counts.uv_mode[b->mode[3]][b->uvmode]++; } else { static const uint8_t inter_mode_ctx_lut[14][14] = { { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, @@ -343,32 +343,32 @@ static void decode_mode(AVCodecContext *avctx) // FIXME add intra as ref=0xff (or -1) to make these easier? if (have_a) { if (have_l) { - if (s->above_comp_ctx[col] && s->left_comp_ctx[row7]) { + if (s->above_comp_ctx[col] && td->left_comp_ctx[row7]) { c = 4; } else if (s->above_comp_ctx[col]) { - c = 2 + (s->left_intra_ctx[row7] || - s->left_ref_ctx[row7] == s->s.h.fixcompref); - } else if (s->left_comp_ctx[row7]) { + c = 2 + (td->left_intra_ctx[row7] || + td->left_ref_ctx[row7] == s->s.h.fixcompref); + } else if (td->left_comp_ctx[row7]) { c = 2 + (s->above_intra_ctx[col] || s->above_ref_ctx[col] == s->s.h.fixcompref); } else { c = (!s->above_intra_ctx[col] && s->above_ref_ctx[col] == s->s.h.fixcompref) ^ - (!s->left_intra_ctx[row7] && - s->left_ref_ctx[row & 7] == s->s.h.fixcompref); + (!td->left_intra_ctx[row7] && + td->left_ref_ctx[row & 7] == s->s.h.fixcompref); } } else { c = s->above_comp_ctx[col] ? 3 : (!s->above_intra_ctx[col] && s->above_ref_ctx[col] == s->s.h.fixcompref); } } else if (have_l) { - c = s->left_comp_ctx[row7] ? 3 : - (!s->left_intra_ctx[row7] && s->left_ref_ctx[row7] == s->s.h.fixcompref); + c = td->left_comp_ctx[row7] ? 3 : + (!td->left_intra_ctx[row7] && td->left_ref_ctx[row7] == s->s.h.fixcompref); } else { c = 1; } - b->comp = vp56_rac_get_prob(&s->c, s->prob.p.comp[c]); - s->counts.comp[c][b->comp]++; + b->comp = vp56_rac_get_prob(td->c, s->prob.p.comp[c]); + td->counts.comp[c][b->comp]++; } // read actual references @@ -382,26 +382,26 @@ static void decode_mode(AVCodecContext *avctx) if (have_a) { if (have_l) { if (s->above_intra_ctx[col]) { - if (s->left_intra_ctx[row7]) { + if (td->left_intra_ctx[row7]) { c = 2; } else { - c = 1 + 2 * (s->left_ref_ctx[row7] != s->s.h.varcompref[1]); + c = 1 + 2 * (td->left_ref_ctx[row7] != s->s.h.varcompref[1]); } - } else if (s->left_intra_ctx[row7]) { + } else if (td->left_intra_ctx[row7]) { c = 1 + 2 * (s->above_ref_ctx[col] != s->s.h.varcompref[1]); } else { - int refl = s->left_ref_ctx[row7], refa = s->above_ref_ctx[col]; + int refl = td->left_ref_ctx[row7], refa = s->above_ref_ctx[col]; if (refl == refa && refa == s->s.h.varcompref[1]) { c = 0; - } else if (!s->left_comp_ctx[row7] && !s->above_comp_ctx[col]) { + } else if (!td->left_comp_ctx[row7] && !s->above_comp_ctx[col]) { if ((refa == s->s.h.fixcompref && refl == s->s.h.varcompref[0]) || (refl == s->s.h.fixcompref && refa == s->s.h.varcompref[0])) { c = 4; } else { c = (refa == refl) ? 3 : 1; } - } else if (!s->left_comp_ctx[row7]) { + } else if (!td->left_comp_ctx[row7]) { if (refa == s->s.h.varcompref[1] && refl != s->s.h.varcompref[1]) { c = 1; } else { @@ -429,37 +429,37 @@ static void decode_mode(AVCodecContext *avctx) } } } else if (have_l) { - if (s->left_intra_ctx[row7]) { + if (td->left_intra_ctx[row7]) { c = 2; - } else if (s->left_comp_ctx[row7]) { - c = 4 * (s->left_ref_ctx[row7] != s->s.h.varcompref[1]); + } else if (td->left_comp_ctx[row7]) { + c = 4 * (td->left_ref_ctx[row7] != s->s.h.varcompref[1]); } else { - c = 3 * (s->left_ref_ctx[row7] != s->s.h.varcompref[1]); + c = 3 * (td->left_ref_ctx[row7] != s->s.h.varcompref[1]); } } else { c = 2; } - bit = vp56_rac_get_prob(&s->c, s->prob.p.comp_ref[c]); + bit = vp56_rac_get_prob(td->c, s->prob.p.comp_ref[c]); b->ref[var_idx] = s->s.h.varcompref[bit]; - s->counts.comp_ref[c][bit]++; + td->counts.comp_ref[c][bit]++; } else /* single reference */ { int bit, c; if (have_a && !s->above_intra_ctx[col]) { - if (have_l && !s->left_intra_ctx[row7]) { - if (s->left_comp_ctx[row7]) { + if (have_l && !td->left_intra_ctx[row7]) { + if (td->left_comp_ctx[row7]) { if (s->above_comp_ctx[col]) { - c = 1 + (!s->s.h.fixcompref || !s->left_ref_ctx[row7] || + c = 1 + (!s->s.h.fixcompref || !td->left_ref_ctx[row7] || !s->above_ref_ctx[col]); } else { c = (3 * !s->above_ref_ctx[col]) + - (!s->s.h.fixcompref || !s->left_ref_ctx[row7]); + (!s->s.h.fixcompref || !td->left_ref_ctx[row7]); } } else if (s->above_comp_ctx[col]) { - c = (3 * !s->left_ref_ctx[row7]) + + c = (3 * !td->left_ref_ctx[row7]) + (!s->s.h.fixcompref || !s->above_ref_ctx[col]); } else { - c = 2 * !s->left_ref_ctx[row7] + 2 * !s->above_ref_ctx[col]; + c = 2 * !td->left_ref_ctx[row7] + 2 * !s->above_ref_ctx[col]; } } else if (s->above_intra_ctx[col]) { c = 2; @@ -468,26 +468,26 @@ static void decode_mode(AVCodecContext *avctx) } else { c = 4 * (!s->above_ref_ctx[col]); } - } else if (have_l && !s->left_intra_ctx[row7]) { - if (s->left_intra_ctx[row7]) { + } else if (have_l && !td->left_intra_ctx[row7]) { + if (td->left_intra_ctx[row7]) { c = 2; - } else if (s->left_comp_ctx[row7]) { - c = 1 + (!s->s.h.fixcompref || !s->left_ref_ctx[row7]); + } else if (td->left_comp_ctx[row7]) { + c = 1 + (!s->s.h.fixcompref || !td->left_ref_ctx[row7]); } else { - c = 4 * (!s->left_ref_ctx[row7]); + c = 4 * (!td->left_ref_ctx[row7]); } } else { c = 2; } - bit = vp56_rac_get_prob(&s->c, s->prob.p.single_ref[c][0]); - s->counts.single_ref[c][0][bit]++; + bit = vp56_rac_get_prob(td->c, s->prob.p.single_ref[c][0]); + td->counts.single_ref[c][0][bit]++; if (!bit) { b->ref[0] = 0; } else { // FIXME can this codeblob be replaced by some sort of LUT? if (have_a) { if (have_l) { - if (s->left_intra_ctx[row7]) { + if (td->left_intra_ctx[row7]) { if (s->above_intra_ctx[col]) { c = 2; } else if (s->above_comp_ctx[col]) { @@ -499,49 +499,49 @@ static void decode_mode(AVCodecContext *avctx) c = 4 * (s->above_ref_ctx[col] == 1); } } else if (s->above_intra_ctx[col]) { - if (s->left_intra_ctx[row7]) { + if (td->left_intra_ctx[row7]) { c = 2; - } else if (s->left_comp_ctx[row7]) { + } else if (td->left_comp_ctx[row7]) { c = 1 + 2 * (s->s.h.fixcompref == 1 || - s->left_ref_ctx[row7] == 1); - } else if (!s->left_ref_ctx[row7]) { + td->left_ref_ctx[row7] == 1); + } else if (!td->left_ref_ctx[row7]) { c = 3; } else { - c = 4 * (s->left_ref_ctx[row7] == 1); + c = 4 * (td->left_ref_ctx[row7] == 1); } } else if (s->above_comp_ctx[col]) { - if (s->left_comp_ctx[row7]) { - if (s->left_ref_ctx[row7] == s->above_ref_ctx[col]) { + if (td->left_comp_ctx[row7]) { + if (td->left_ref_ctx[row7] == s->above_ref_ctx[col]) { c = 3 * (s->s.h.fixcompref == 1 || - s->left_ref_ctx[row7] == 1); + td->left_ref_ctx[row7] == 1); } else { c = 2; } - } else if (!s->left_ref_ctx[row7]) { + } else if (!td->left_ref_ctx[row7]) { c = 1 + 2 * (s->s.h.fixcompref == 1 || s->above_ref_ctx[col] == 1); } else { - c = 3 * (s->left_ref_ctx[row7] == 1) + + c = 3 * (td->left_ref_ctx[row7] == 1) + (s->s.h.fixcompref == 1 || s->above_ref_ctx[col] == 1); } - } else if (s->left_comp_ctx[row7]) { + } else if (td->left_comp_ctx[row7]) { if (!s->above_ref_ctx[col]) { c = 1 + 2 * (s->s.h.fixcompref == 1 || - s->left_ref_ctx[row7] == 1); + td->left_ref_ctx[row7] == 1); } else { c = 3 * (s->above_ref_ctx[col] == 1) + - (s->s.h.fixcompref == 1 || s->left_ref_ctx[row7] == 1); + (s->s.h.fixcompref == 1 || td->left_ref_ctx[row7] == 1); } } else if (!s->above_ref_ctx[col]) { - if (!s->left_ref_ctx[row7]) { + if (!td->left_ref_ctx[row7]) { c = 3; } else { - c = 4 * (s->left_ref_ctx[row7] == 1); + c = 4 * (td->left_ref_ctx[row7] == 1); } - } else if (!s->left_ref_ctx[row7]) { + } else if (!td->left_ref_ctx[row7]) { c = 4 * (s->above_ref_ctx[col] == 1); } else { - c = 2 * (s->left_ref_ctx[row7] == 1) + + c = 2 * (td->left_ref_ctx[row7] == 1) + 2 * (s->above_ref_ctx[col] == 1); } } else { @@ -555,19 +555,19 @@ static void decode_mode(AVCodecContext *avctx) } } } else if (have_l) { - if (s->left_intra_ctx[row7] || - (!s->left_comp_ctx[row7] && !s->left_ref_ctx[row7])) { + if (td->left_intra_ctx[row7] || + (!td->left_comp_ctx[row7] && !td->left_ref_ctx[row7])) { c = 2; - } else if (s->left_comp_ctx[row7]) { - c = 3 * (s->s.h.fixcompref == 1 || s->left_ref_ctx[row7] == 1); + } else if (td->left_comp_ctx[row7]) { + c = 3 * (s->s.h.fixcompref == 1 || td->left_ref_ctx[row7] == 1); } else { - c = 4 * (s->left_ref_ctx[row7] == 1); + c = 4 * (td->left_ref_ctx[row7] == 1); } } else { c = 2; } - bit = vp56_rac_get_prob(&s->c, s->prob.p.single_ref[c][1]); - s->counts.single_ref[c][1][bit]++; + bit = vp56_rac_get_prob(td->c, s->prob.p.single_ref[c][1]); + td->counts.single_ref[c][1][bit]++; b->ref[0] = 1 + bit; } } @@ -587,14 +587,14 @@ static void decode_mode(AVCodecContext *avctx) // FIXME this needs to use the LUT tables from find_ref_mvs // because not all are -1,0/0,-1 int c = inter_mode_ctx_lut[s->above_mode_ctx[col + off[b->bs]]] - [s->left_mode_ctx[row7 + off[b->bs]]]; + [td->left_mode_ctx[row7 + off[b->bs]]]; - b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree, + b->mode[0] = vp8_rac_get_tree(td->c, ff_vp9_inter_mode_tree, s->prob.p.mv_mode[c]); b->mode[1] = b->mode[2] = b->mode[3] = b->mode[0]; - s->counts.mv_mode[c][b->mode[0] - 10]++; + td->counts.mv_mode[c][b->mode[0] - 10]++; } } @@ -602,39 +602,39 @@ static void decode_mode(AVCodecContext *avctx) int c; if (have_a && s->above_mode_ctx[col] >= NEARESTMV) { - if (have_l && s->left_mode_ctx[row7] >= NEARESTMV) { - c = s->above_filter_ctx[col] == s->left_filter_ctx[row7] ? - s->left_filter_ctx[row7] : 3; + if (have_l && td->left_mode_ctx[row7] >= NEARESTMV) { + c = s->above_filter_ctx[col] == td->left_filter_ctx[row7] ? + td->left_filter_ctx[row7] : 3; } else { c = s->above_filter_ctx[col]; } - } else if (have_l && s->left_mode_ctx[row7] >= NEARESTMV) { - c = s->left_filter_ctx[row7]; + } else if (have_l && td->left_mode_ctx[row7] >= NEARESTMV) { + c = td->left_filter_ctx[row7]; } else { c = 3; } - filter_id = vp8_rac_get_tree(&s->c, ff_vp9_filter_tree, + filter_id = vp8_rac_get_tree(td->c, ff_vp9_filter_tree, s->prob.p.filter[c]); - s->counts.filter[c][filter_id]++; + td->counts.filter[c][filter_id]++; b->filter = ff_vp9_filter_lut[filter_id]; } else { b->filter = s->s.h.filtermode; } if (b->bs > BS_8x8) { - int c = inter_mode_ctx_lut[s->above_mode_ctx[col]][s->left_mode_ctx[row7]]; + int c = inter_mode_ctx_lut[s->above_mode_ctx[col]][td->left_mode_ctx[row7]]; - b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree, + b->mode[0] = vp8_rac_get_tree(td->c, ff_vp9_inter_mode_tree, s->prob.p.mv_mode[c]); - s->counts.mv_mode[c][b->mode[0] - 10]++; - ff_vp9_fill_mv(s, b->mv[0], b->mode[0], 0); + td->counts.mv_mode[c][b->mode[0] - 10]++; + ff_vp9_fill_mv(td, b->mv[0], b->mode[0], 0); if (b->bs != BS_8x4) { - b->mode[1] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree, + b->mode[1] = vp8_rac_get_tree(td->c, ff_vp9_inter_mode_tree, s->prob.p.mv_mode[c]); - s->counts.mv_mode[c][b->mode[1] - 10]++; - ff_vp9_fill_mv(s, b->mv[1], b->mode[1], 1); + td->counts.mv_mode[c][b->mode[1] - 10]++; + ff_vp9_fill_mv(td, b->mv[1], b->mode[1], 1); } else { b->mode[1] = b->mode[0]; AV_COPY32(&b->mv[1][0], &b->mv[0][0]); @@ -642,16 +642,16 @@ static void decode_mode(AVCodecContext *avctx) } if (b->bs != BS_4x8) { - b->mode[2] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree, + b->mode[2] = vp8_rac_get_tree(td->c, ff_vp9_inter_mode_tree, s->prob.p.mv_mode[c]); - s->counts.mv_mode[c][b->mode[2] - 10]++; - ff_vp9_fill_mv(s, b->mv[2], b->mode[2], 2); + td->counts.mv_mode[c][b->mode[2] - 10]++; + ff_vp9_fill_mv(td, b->mv[2], b->mode[2], 2); if (b->bs != BS_8x4) { - b->mode[3] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree, + b->mode[3] = vp8_rac_get_tree(td->c, ff_vp9_inter_mode_tree, s->prob.p.mv_mode[c]); - s->counts.mv_mode[c][b->mode[3] - 10]++; - ff_vp9_fill_mv(s, b->mv[3], b->mode[3], 3); + td->counts.mv_mode[c][b->mode[3] - 10]++; + ff_vp9_fill_mv(td, b->mv[3], b->mode[3], 3); } else { b->mode[3] = b->mode[2]; AV_COPY32(&b->mv[3][0], &b->mv[2][0]); @@ -666,7 +666,7 @@ static void decode_mode(AVCodecContext *avctx) AV_COPY32(&b->mv[3][1], &b->mv[1][1]); } } else { - ff_vp9_fill_mv(s, b->mv[0], b->mode[0], -1); + ff_vp9_fill_mv(td, b->mv[0], b->mode[0], -1); AV_COPY32(&b->mv[1][0], &b->mv[0][0]); AV_COPY32(&b->mv[2][0], &b->mv[0][0]); AV_COPY32(&b->mv[3][0], &b->mv[0][0]); @@ -716,33 +716,33 @@ static void decode_mode(AVCodecContext *avctx) #endif switch (ff_vp9_bwh_tab[1][b->bs][0]) { -#define SET_CTXS(dir, off, n) \ +#define SET_CTXS(perf, dir, off, n) \ do { \ - SPLAT_CTX(s->dir##_skip_ctx[off], b->skip, n); \ - SPLAT_CTX(s->dir##_txfm_ctx[off], b->tx, n); \ - SPLAT_CTX(s->dir##_partition_ctx[off], dir##_ctx[b->bs], n); \ + SPLAT_CTX(perf->dir##_skip_ctx[off], b->skip, n); \ + SPLAT_CTX(perf->dir##_txfm_ctx[off], b->tx, n); \ + SPLAT_CTX(perf->dir##_partition_ctx[off], dir##_ctx[b->bs], n); \ if (!s->s.h.keyframe && !s->s.h.intraonly) { \ - SPLAT_CTX(s->dir##_intra_ctx[off], b->intra, n); \ - SPLAT_CTX(s->dir##_comp_ctx[off], b->comp, n); \ - SPLAT_CTX(s->dir##_mode_ctx[off], b->mode[3], n); \ + SPLAT_CTX(perf->dir##_intra_ctx[off], b->intra, n); \ + SPLAT_CTX(perf->dir##_comp_ctx[off], b->comp, n); \ + SPLAT_CTX(perf->dir##_mode_ctx[off], b->mode[3], n); \ if (!b->intra) { \ - SPLAT_CTX(s->dir##_ref_ctx[off], vref, n); \ + SPLAT_CTX(perf->dir##_ref_ctx[off], vref, n); \ if (s->s.h.filtermode == FILTER_SWITCHABLE) { \ - SPLAT_CTX(s->dir##_filter_ctx[off], filter_id, n); \ + SPLAT_CTX(perf->dir##_filter_ctx[off], filter_id, n); \ } \ } \ } \ } while (0) - case 1: SET_CTXS(above, col, 1); break; - case 2: SET_CTXS(above, col, 2); break; - case 4: SET_CTXS(above, col, 4); break; - case 8: SET_CTXS(above, col, 8); break; + case 1: SET_CTXS(s, above, col, 1); break; + case 2: SET_CTXS(s, above, col, 2); break; + case 4: SET_CTXS(s, above, col, 4); break; + case 8: SET_CTXS(s, above, col, 8); break; } switch (ff_vp9_bwh_tab[1][b->bs][1]) { - case 1: SET_CTXS(left, row7, 1); break; - case 2: SET_CTXS(left, row7, 2); break; - case 4: SET_CTXS(left, row7, 4); break; - case 8: SET_CTXS(left, row7, 8); break; + case 1: SET_CTXS(td, left, row7, 1); break; + case 2: SET_CTXS(td, left, row7, 2); break; + case 4: SET_CTXS(td, left, row7, 4); break; + case 8: SET_CTXS(td, left, row7, 8); break; } #undef SPLAT_CTX #undef SET_CTXS @@ -751,10 +751,10 @@ static void decode_mode(AVCodecContext *avctx) if (b->bs > BS_8x8) { int mv0 = AV_RN32A(&b->mv[3][0]), mv1 = AV_RN32A(&b->mv[3][1]); - AV_COPY32(&s->left_mv_ctx[row7 * 2 + 0][0], &b->mv[1][0]); - AV_COPY32(&s->left_mv_ctx[row7 * 2 + 0][1], &b->mv[1][1]); - AV_WN32A(&s->left_mv_ctx[row7 * 2 + 1][0], mv0); - AV_WN32A(&s->left_mv_ctx[row7 * 2 + 1][1], mv1); + AV_COPY32(&td->left_mv_ctx[row7 * 2 + 0][0], &b->mv[1][0]); + AV_COPY32(&td->left_mv_ctx[row7 * 2 + 0][1], &b->mv[1][1]); + AV_WN32A(&td->left_mv_ctx[row7 * 2 + 1][0], mv0); + AV_WN32A(&td->left_mv_ctx[row7 * 2 + 1][1], mv1); AV_COPY32(&s->above_mv_ctx[col * 2 + 0][0], &b->mv[2][0]); AV_COPY32(&s->above_mv_ctx[col * 2 + 0][1], &b->mv[2][1]); AV_WN32A(&s->above_mv_ctx[col * 2 + 1][0], mv0); @@ -767,8 +767,8 @@ static void decode_mode(AVCodecContext *avctx) AV_WN32A(&s->above_mv_ctx[col * 2 + n][1], mv1); } for (n = 0; n < h4 * 2; n++) { - AV_WN32A(&s->left_mv_ctx[row7 * 2 + n][0], mv0); - AV_WN32A(&s->left_mv_ctx[row7 * 2 + n][1], mv1); + AV_WN32A(&td->left_mv_ctx[row7 * 2 + n][0], mv0); + AV_WN32A(&td->left_mv_ctx[row7 * 2 + n][1], mv1); } } } @@ -806,10 +806,10 @@ decode_coeffs_b_generic(VP56RangeCoder *c, int16_t *coef, int n_coeffs, int is_tx32x32, int is8bitsperpixel, int bpp, unsigned (*cnt)[6][3], unsigned (*eob)[6][2], uint8_t (*p)[6][11], int nnz, const int16_t *scan, const int16_t (*nb)[2], - const int16_t *band_counts, const int16_t *qmul) + const int16_t *band_counts, int16_t *qmul) { int i = 0, band = 0, band_left = band_counts[band]; - uint8_t *tp = p[0][nnz]; + const uint8_t *tp = p[0][nnz]; uint8_t cache[1024]; do { @@ -839,10 +839,6 @@ decode_coeffs_b_generic(VP56RangeCoder *c, int16_t *coef, int n_coeffs, val = 1; cache[rc] = 1; } else { - // fill in p[3-10] (model fill) - only once per frame for each pos - if (!tp[3]) - memcpy(&tp[3], ff_vp9_model_pareto8[tp[2]], 8); - cnt[band][nnz][2]++; if (!vp56_rac_get_prob_branchy(c, tp[3])) { // 2, 3, 4 if (!vp56_rac_get_prob_branchy(c, tp[4])) { @@ -925,54 +921,54 @@ decode_coeffs_b_generic(VP56RangeCoder *c, int16_t *coef, int n_coeffs, return i; } -static int decode_coeffs_b_8bpp(VP9Context *s, int16_t *coef, int n_coeffs, +static int decode_coeffs_b_8bpp(VP9TileData *td, int16_t *coef, int n_coeffs, unsigned (*cnt)[6][3], unsigned (*eob)[6][2], uint8_t (*p)[6][11], int nnz, const int16_t *scan, const int16_t (*nb)[2], const int16_t *band_counts, - const int16_t *qmul) + int16_t *qmul) { - return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 0, 1, 8, cnt, eob, p, + return decode_coeffs_b_generic(td->c, coef, n_coeffs, 0, 1, 8, cnt, eob, p, nnz, scan, nb, band_counts, qmul); } -static int decode_coeffs_b32_8bpp(VP9Context *s, int16_t *coef, int n_coeffs, +static int decode_coeffs_b32_8bpp(VP9TileData *td, int16_t *coef, int n_coeffs, unsigned (*cnt)[6][3], unsigned (*eob)[6][2], uint8_t (*p)[6][11], int nnz, const int16_t *scan, const int16_t (*nb)[2], const int16_t *band_counts, - const int16_t *qmul) + int16_t *qmul) { - return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 1, 1, 8, cnt, eob, p, + return decode_coeffs_b_generic(td->c, coef, n_coeffs, 1, 1, 8, cnt, eob, p, nnz, scan, nb, band_counts, qmul); } -static int decode_coeffs_b_16bpp(VP9Context *s, int16_t *coef, int n_coeffs, +static int decode_coeffs_b_16bpp(VP9TileData *td, int16_t *coef, int n_coeffs, unsigned (*cnt)[6][3], unsigned (*eob)[6][2], uint8_t (*p)[6][11], int nnz, const int16_t *scan, const int16_t (*nb)[2], const int16_t *band_counts, - const int16_t *qmul) + int16_t *qmul) { - return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 0, 0, s->s.h.bpp, cnt, eob, p, + return decode_coeffs_b_generic(td->c, coef, n_coeffs, 0, 0, td->s->s.h.bpp, cnt, eob, p, nnz, scan, nb, band_counts, qmul); } -static int decode_coeffs_b32_16bpp(VP9Context *s, int16_t *coef, int n_coeffs, +static int decode_coeffs_b32_16bpp(VP9TileData *td, int16_t *coef, int n_coeffs, unsigned (*cnt)[6][3], unsigned (*eob)[6][2], uint8_t (*p)[6][11], int nnz, const int16_t *scan, const int16_t (*nb)[2], const int16_t *band_counts, - const int16_t *qmul) + int16_t *qmul) { - return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 1, 0, s->s.h.bpp, cnt, eob, p, + return decode_coeffs_b_generic(td->c, coef, n_coeffs, 1, 0, td->s->s.h.bpp, cnt, eob, p, nnz, scan, nb, band_counts, qmul); } -static av_always_inline int decode_coeffs(AVCodecContext *avctx, int is8bitsperpixel) +static av_always_inline int decode_coeffs(VP9TileData *td, int is8bitsperpixel) { - VP9Context *s = avctx->priv_data; - VP9Block *b = s->b; - int row = s->row, col = s->col; + VP9Context *s = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col; uint8_t (*p)[6][11] = s->prob.coef[b->tx][0 /* y */][!b->intra]; - unsigned (*c)[6][3] = s->counts.coef[b->tx][0 /* y */][!b->intra]; - unsigned (*e)[6][2] = s->counts.eob[b->tx][0 /* y */][!b->intra]; + unsigned (*c)[6][3] = td->counts.coef[b->tx][0 /* y */][!b->intra]; + unsigned (*e)[6][2] = td->counts.eob[b->tx][0 /* y */][!b->intra]; int w4 = ff_vp9_bwh_tab[1][b->bs][0] << 1, h4 = ff_vp9_bwh_tab[1][b->bs][1] << 1; int end_x = FFMIN(2 * (s->cols - col), w4); int end_y = FFMIN(2 * (s->rows - row), h4); @@ -984,7 +980,7 @@ static av_always_inline int decode_coeffs(AVCodecContext *avctx, int is8bitsperp const int16_t *uvscan = ff_vp9_scans[b->uvtx][DCT_DCT]; const int16_t (*uvnb)[2] = ff_vp9_scans_nb[b->uvtx][DCT_DCT]; uint8_t *a = &s->above_y_nnz_ctx[col * 2]; - uint8_t *l = &s->left_y_nnz_ctx[(row & 7) << 1]; + uint8_t *l = &td->left_y_nnz_ctx[(row & 7) << 1]; static const int16_t band_counts[4][8] = { { 1, 2, 3, 4, 3, 16 - 13 }, { 1, 2, 3, 4, 11, 64 - 21 }, @@ -1010,15 +1006,15 @@ static av_always_inline int decode_coeffs(AVCodecContext *avctx, int is8bitsperp for (x = 0; x < end_x; x += step, n += step * step) { \ enum TxfmType txtp = ff_vp9_intra_txfm_type[b->mode[mode_index]]; \ ret = (is8bitsperpixel ? decode_coeffs_b##v##_8bpp : decode_coeffs_b##v##_16bpp) \ - (s, s->block + 16 * n * bytesperpixel, 16 * step * step, \ + (td, td->block + 16 * n * bytesperpixel, 16 * step * step, \ c, e, p, a[x] + l[y], yscans[txtp], \ ynbs[txtp], y_band_counts, qmul[0]); \ a[x] = l[y] = !!ret; \ total_coeff |= !!ret; \ if (step >= 4) { \ - AV_WN16A(&s->eob[n], ret); \ + AV_WN16A(&td->eob[n], ret); \ } else { \ - s->eob[n] = ret; \ + td->eob[n] = ret; \ } \ } \ } @@ -1084,29 +1080,29 @@ static av_always_inline int decode_coeffs(AVCodecContext *avctx, int is8bitsperp for (n = 0, y = 0; y < end_y; y += step) { \ for (x = 0; x < end_x; x += step, n += step * step) { \ ret = (is8bitsperpixel ? decode_coeffs_b##v##_8bpp : decode_coeffs_b##v##_16bpp) \ - (s, s->uvblock[pl] + 16 * n * bytesperpixel, \ + (td, td->uvblock[pl] + 16 * n * bytesperpixel, \ 16 * step * step, c, e, p, a[x] + l[y], \ uvscan, uvnb, uv_band_counts, qmul[1]); \ a[x] = l[y] = !!ret; \ total_coeff |= !!ret; \ if (step >= 4) { \ - AV_WN16A(&s->uveob[pl][n], ret); \ + AV_WN16A(&td->uveob[pl][n], ret); \ } else { \ - s->uveob[pl][n] = ret; \ + td->uveob[pl][n] = ret; \ } \ } \ } p = s->prob.coef[b->uvtx][1 /* uv */][!b->intra]; - c = s->counts.coef[b->uvtx][1 /* uv */][!b->intra]; - e = s->counts.eob[b->uvtx][1 /* uv */][!b->intra]; + c = td->counts.coef[b->uvtx][1 /* uv */][!b->intra]; + e = td->counts.eob[b->uvtx][1 /* uv */][!b->intra]; w4 >>= s->ss_h; end_x >>= s->ss_h; h4 >>= s->ss_v; end_y >>= s->ss_v; for (pl = 0; pl < 2; pl++) { a = &s->above_uv_nnz_ctx[pl][col << !s->ss_h]; - l = &s->left_uv_nnz_ctx[pl][(row & 7) << !s->ss_v]; + l = &td->left_uv_nnz_ctx[pl][(row & 7) << !s->ss_v]; switch (b->uvtx) { case TX_4X4: DECODE_UV_COEF_LOOP(1,); @@ -1132,14 +1128,14 @@ static av_always_inline int decode_coeffs(AVCodecContext *avctx, int is8bitsperp return total_coeff; } -static int decode_coeffs_8bpp(AVCodecContext *avctx) +static int decode_coeffs_8bpp(VP9TileData *td) { - return decode_coeffs(avctx, 1); + return decode_coeffs(td, 1); } -static int decode_coeffs_16bpp(AVCodecContext *avctx) +static int decode_coeffs_16bpp(VP9TileData *td) { - return decode_coeffs(avctx, 0); + return decode_coeffs(td, 0); } static av_always_inline void mask_edges(uint8_t (*mask)[8][4], int ss_h, int ss_v, @@ -1264,33 +1260,33 @@ static av_always_inline void mask_edges(uint8_t (*mask)[8][4], int ss_h, int ss_ } } -void ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, +void ff_vp9_decode_block(VP9TileData *td, int row, int col, VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl, enum BlockPartition bp) { - VP9Context *s = avctx->priv_data; - VP9Block *b = s->b; + VP9Context *s = td->s; + VP9Block *b = td->b; enum BlockSize bs = bl * 3 + bp; int bytesperpixel = s->bytesperpixel; int w4 = ff_vp9_bwh_tab[1][bs][0], h4 = ff_vp9_bwh_tab[1][bs][1], lvl; int emu[2]; AVFrame *f = s->s.frames[CUR_FRAME].tf.f; - s->row = row; - s->row7 = row & 7; - s->col = col; - s->col7 = col & 7; + td->row = row; + td->row7 = row & 7; + td->col = col; + td->col7 = col & 7; - s->min_mv.x = -(128 + col * 64); - s->min_mv.y = -(128 + row * 64); - s->max_mv.x = 128 + (s->cols - col - w4) * 64; - s->max_mv.y = 128 + (s->rows - row - h4) * 64; + td->min_mv.x = -(128 + col * 64); + td->min_mv.y = -(128 + row * 64); + td->max_mv.x = 128 + (s->cols - col - w4) * 64; + td->max_mv.y = 128 + (s->rows - row - h4) * 64; if (s->pass < 2) { b->bs = bs; b->bl = bl; b->bp = bp; - decode_mode(avctx); + decode_mode(td); b->uvtx = b->tx - ((s->ss_h && w4 * 2 == (1 << b->tx)) || (s->ss_v && h4 * 2 == (1 << b->tx))); @@ -1298,17 +1294,17 @@ void ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, int has_coeffs; if (bytesperpixel == 1) { - has_coeffs = decode_coeffs_8bpp(avctx); + has_coeffs = decode_coeffs_8bpp(td); } else { - has_coeffs = decode_coeffs_16bpp(avctx); + has_coeffs = decode_coeffs_16bpp(td); } if (!has_coeffs && b->bs <= BS_8x8 && !b->intra) { b->skip = 1; memset(&s->above_skip_ctx[col], 1, w4); - memset(&s->left_skip_ctx[s->row7], 1, h4); + memset(&td->left_skip_ctx[td->row7], 1, h4); } } else { - int row7 = s->row7; + int row7 = td->row7; #define SPLAT_ZERO_CTX(v, n) \ switch (n) { \ @@ -1320,38 +1316,38 @@ void ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, } #define SPLAT_ZERO_YUV(dir, var, off, n, dir2) \ do { \ - SPLAT_ZERO_CTX(s->dir##_y_##var[off * 2], n * 2); \ + SPLAT_ZERO_CTX(dir##_y_##var[off * 2], n * 2); \ if (s->ss_##dir2) { \ - SPLAT_ZERO_CTX(s->dir##_uv_##var[0][off], n); \ - SPLAT_ZERO_CTX(s->dir##_uv_##var[1][off], n); \ + SPLAT_ZERO_CTX(dir##_uv_##var[0][off], n); \ + SPLAT_ZERO_CTX(dir##_uv_##var[1][off], n); \ } else { \ - SPLAT_ZERO_CTX(s->dir##_uv_##var[0][off * 2], n * 2); \ - SPLAT_ZERO_CTX(s->dir##_uv_##var[1][off * 2], n * 2); \ + SPLAT_ZERO_CTX(dir##_uv_##var[0][off * 2], n * 2); \ + SPLAT_ZERO_CTX(dir##_uv_##var[1][off * 2], n * 2); \ } \ } while (0) switch (w4) { - case 1: SPLAT_ZERO_YUV(above, nnz_ctx, col, 1, h); break; - case 2: SPLAT_ZERO_YUV(above, nnz_ctx, col, 2, h); break; - case 4: SPLAT_ZERO_YUV(above, nnz_ctx, col, 4, h); break; - case 8: SPLAT_ZERO_YUV(above, nnz_ctx, col, 8, h); break; + case 1: SPLAT_ZERO_YUV(s->above, nnz_ctx, col, 1, h); break; + case 2: SPLAT_ZERO_YUV(s->above, nnz_ctx, col, 2, h); break; + case 4: SPLAT_ZERO_YUV(s->above, nnz_ctx, col, 4, h); break; + case 8: SPLAT_ZERO_YUV(s->above, nnz_ctx, col, 8, h); break; } switch (h4) { - case 1: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 1, v); break; - case 2: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 2, v); break; - case 4: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 4, v); break; - case 8: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 8, v); break; + case 1: SPLAT_ZERO_YUV(td->left, nnz_ctx, row7, 1, v); break; + case 2: SPLAT_ZERO_YUV(td->left, nnz_ctx, row7, 2, v); break; + case 4: SPLAT_ZERO_YUV(td->left, nnz_ctx, row7, 4, v); break; + case 8: SPLAT_ZERO_YUV(td->left, nnz_ctx, row7, 8, v); break; } } if (s->pass == 1) { - s->b++; - s->block += w4 * h4 * 64 * bytesperpixel; - s->uvblock[0] += w4 * h4 * 64 * bytesperpixel >> (s->ss_h + s->ss_v); - s->uvblock[1] += w4 * h4 * 64 * bytesperpixel >> (s->ss_h + s->ss_v); - s->eob += 4 * w4 * h4; - s->uveob[0] += 4 * w4 * h4 >> (s->ss_h + s->ss_v); - s->uveob[1] += 4 * w4 * h4 >> (s->ss_h + s->ss_v); + s->td[0].b++; + s->td[0].block += w4 * h4 * 64 * bytesperpixel; + s->td[0].uvblock[0] += w4 * h4 * 64 * bytesperpixel >> (s->ss_h + s->ss_v); + s->td[0].uvblock[1] += w4 * h4 * 64 * bytesperpixel >> (s->ss_h + s->ss_v); + s->td[0].eob += 4 * w4 * h4; + s->td[0].uveob[0] += 4 * w4 * h4 >> (s->ss_h + s->ss_v); + s->td[0].uveob[1] += 4 * w4 * h4 >> (s->ss_h + s->ss_v); return; } @@ -1365,32 +1361,32 @@ void ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, emu[1] = ((col + w4) * 8 >> s->ss_h) * bytesperpixel > f->linesize[1] || (row + h4) > s->rows; if (emu[0]) { - s->dst[0] = s->tmp_y; - s->y_stride = 128; + td->dst[0] = td->tmp_y; + td->y_stride = 128; } else { - s->dst[0] = f->data[0] + yoff; - s->y_stride = f->linesize[0]; + td->dst[0] = f->data[0] + yoff; + td->y_stride = f->linesize[0]; } if (emu[1]) { - s->dst[1] = s->tmp_uv[0]; - s->dst[2] = s->tmp_uv[1]; - s->uv_stride = 128; + td->dst[1] = td->tmp_uv[0]; + td->dst[2] = td->tmp_uv[1]; + td->uv_stride = 128; } else { - s->dst[1] = f->data[1] + uvoff; - s->dst[2] = f->data[2] + uvoff; - s->uv_stride = f->linesize[1]; + td->dst[1] = f->data[1] + uvoff; + td->dst[2] = f->data[2] + uvoff; + td->uv_stride = f->linesize[1]; } if (b->intra) { if (s->s.h.bpp > 8) { - ff_vp9_intra_recon_16bpp(avctx, yoff, uvoff); + ff_vp9_intra_recon_16bpp(td, yoff, uvoff); } else { - ff_vp9_intra_recon_8bpp(avctx, yoff, uvoff); + ff_vp9_intra_recon_8bpp(td, yoff, uvoff); } } else { if (s->s.h.bpp > 8) { - ff_vp9_inter_recon_16bpp(avctx); + ff_vp9_inter_recon_16bpp(td); } else { - ff_vp9_inter_recon_8bpp(avctx); + ff_vp9_inter_recon_8bpp(td); } } if (emu[0]) { @@ -1402,7 +1398,7 @@ void ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, av_assert2(n <= 4); if (w & bw) { s->dsp.mc[n][0][0][0][0](f->data[0] + yoff + o * bytesperpixel, f->linesize[0], - s->tmp_y + o * bytesperpixel, 128, h, 0, 0); + td->tmp_y + o * bytesperpixel, 128, h, 0, 0); o += bw; } } @@ -1417,9 +1413,9 @@ void ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, av_assert2(n <= 4); if (w & bw) { s->dsp.mc[n][0][0][0][0](f->data[1] + uvoff + o * bytesperpixel, f->linesize[1], - s->tmp_uv[0] + o * bytesperpixel, 128, h, 0, 0); + td->tmp_uv[0] + o * bytesperpixel, 128, h, 0, 0); s->dsp.mc[n][0][0][0][0](f->data[2] + uvoff + o * bytesperpixel, f->linesize[2], - s->tmp_uv[1] + o * bytesperpixel, 128, h, 0, 0); + td->tmp_uv[1] + o * bytesperpixel, 128, h, 0, 0); o += bw; } } @@ -1430,7 +1426,7 @@ void ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, (lvl = s->s.h.segmentation.feat[b->seg_id].lflvl[b->intra ? 0 : b->ref[0] + 1] [b->mode[3] != ZEROMV]) > 0) { int x_end = FFMIN(s->cols - col, w4), y_end = FFMIN(s->rows - row, h4); - int skip_inter = !b->intra && b->skip, col7 = s->col7, row7 = s->row7; + int skip_inter = !b->intra && b->skip, col7 = td->col7, row7 = td->row7; setctx_2d(&lflvl->level[row7 * 8 + col7], w4, h4, 8, lvl); mask_edges(lflvl->mask[0], 0, 0, row7, col7, x_end, y_end, 0, 0, b->tx, skip_inter); @@ -1439,29 +1435,15 @@ void ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, s->cols & 1 && col + w4 >= s->cols ? s->cols & 7 : 0, s->rows & 1 && row + h4 >= s->rows ? s->rows & 7 : 0, b->uvtx, skip_inter); - - if (!s->filter_lut.lim_lut[lvl]) { - int sharp = s->s.h.filter.sharpness; - int limit = lvl; - - if (sharp > 0) { - limit >>= (sharp + 3) >> 2; - limit = FFMIN(limit, 9 - sharp); - } - limit = FFMAX(limit, 1); - - s->filter_lut.lim_lut[lvl] = limit; - s->filter_lut.mblim_lut[lvl] = 2 * (lvl + 2) + limit; - } } if (s->pass == 2) { - s->b++; - s->block += w4 * h4 * 64 * bytesperpixel; - s->uvblock[0] += w4 * h4 * 64 * bytesperpixel >> (s->ss_v + s->ss_h); - s->uvblock[1] += w4 * h4 * 64 * bytesperpixel >> (s->ss_v + s->ss_h); - s->eob += 4 * w4 * h4; - s->uveob[0] += 4 * w4 * h4 >> (s->ss_v + s->ss_h); - s->uveob[1] += 4 * w4 * h4 >> (s->ss_v + s->ss_h); + s->td[0].b++; + s->td[0].block += w4 * h4 * 64 * bytesperpixel; + s->td[0].uvblock[0] += w4 * h4 * 64 * bytesperpixel >> (s->ss_v + s->ss_h); + s->td[0].uvblock[1] += w4 * h4 * 64 * bytesperpixel >> (s->ss_v + s->ss_h); + s->td[0].eob += 4 * w4 * h4; + s->td[0].uveob[0] += 4 * w4 * h4 >> (s->ss_v + s->ss_h); + s->td[0].uveob[1] += 4 * w4 * h4 >> (s->ss_v + s->ss_h); } } diff --git a/libavcodec/vp9dec.h b/libavcodec/vp9dec.h index 4002b3a694588..15e0122918116 100644 --- a/libavcodec/vp9dec.h +++ b/libavcodec/vp9dec.h @@ -26,8 +26,10 @@ #include #include +#include #include "libavutil/buffer.h" +#include "libavutil/thread.h" #include "libavutil/internal.h" #include "vp9.h" @@ -84,20 +86,21 @@ typedef struct VP9Block { enum BlockPartition bp; } VP9Block; +typedef struct VP9TileData VP9TileData; + typedef struct VP9Context { + VP9TileData *td; VP9SharedContext s; VP9DSPContext dsp; VideoDSPContext vdsp; GetBitContext gb; VP56RangeCoder c; - VP56RangeCoder *c_b; - unsigned c_b_size; - VP9Block *b_base, *b; - int pass; - int row, row7, col, col7; - uint8_t *dst[3]; - ptrdiff_t y_stride, uv_stride; + int pass, active_tile_cols; + + pthread_mutex_t progress_mutex; + pthread_cond_t progress_cond; + atomic_int *entries; uint8_t ss_h, ss_v; uint8_t last_bpp, bpp_index, bytesperpixel; @@ -115,7 +118,6 @@ typedef struct VP9Context { uint8_t lim_lut[64]; uint8_t mblim_lut[64]; } filter_lut; - unsigned tile_row_start, tile_row_end, tile_col_start, tile_col_end; struct { ProbContext p; uint8_t coef[4][2][2][6][6][3]; @@ -124,6 +126,44 @@ typedef struct VP9Context { ProbContext p; uint8_t coef[4][2][2][6][6][11]; } prob; + + // contextual (above) cache + uint8_t *above_partition_ctx; + uint8_t *above_mode_ctx; + // FIXME maybe merge some of the below in a flags field? + uint8_t *above_y_nnz_ctx; + uint8_t *above_uv_nnz_ctx[2]; + uint8_t *above_skip_ctx; // 1bit + uint8_t *above_txfm_ctx; // 2bit + uint8_t *above_segpred_ctx; // 1bit + uint8_t *above_intra_ctx; // 1bit + uint8_t *above_comp_ctx; // 1bit + uint8_t *above_ref_ctx; // 2bit + uint8_t *above_filter_ctx; + VP56mv (*above_mv_ctx)[2]; + + // whole-frame cache + uint8_t *intra_pred_data[3]; + VP9Filter *lflvl; + + // block reconstruction intermediates + int block_alloc_using_2pass; + uint16_t mvscale[3][2]; + uint8_t mvstep[3][2]; +} VP9Context; + +struct VP9TileData { + //VP9Context should be const, but because of the threading API(generates + //a lot of warnings) it's not. + VP9Context *s; + VP56RangeCoder *c_b; + VP56RangeCoder *c; + int row, row7, col, col7; + uint8_t *dst[3]; + ptrdiff_t y_stride, uv_stride; + VP9Block *b_base, *b; + unsigned tile_col_start; + struct { unsigned y_mode[4][10]; unsigned uv_mode[10][10]; @@ -153,7 +193,10 @@ typedef struct VP9Context { unsigned eob[4][2][2][6][6][2]; } counts; - // contextual (left/above) cache + // whole-frame cache + DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[135 * 144 * 2]; + + // contextual (left) cache DECLARE_ALIGNED(16, uint8_t, left_y_nnz_ctx)[16]; DECLARE_ALIGNED(16, uint8_t, left_mode_ctx)[16]; DECLARE_ALIGNED(16, VP56mv, left_mv_ctx)[16][2]; @@ -166,52 +209,30 @@ typedef struct VP9Context { DECLARE_ALIGNED(8, uint8_t, left_comp_ctx)[8]; DECLARE_ALIGNED(8, uint8_t, left_ref_ctx)[8]; DECLARE_ALIGNED(8, uint8_t, left_filter_ctx)[8]; - uint8_t *above_partition_ctx; - uint8_t *above_mode_ctx; - // FIXME maybe merge some of the below in a flags field? - uint8_t *above_y_nnz_ctx; - uint8_t *above_uv_nnz_ctx[2]; - uint8_t *above_skip_ctx; // 1bit - uint8_t *above_txfm_ctx; // 2bit - uint8_t *above_segpred_ctx; // 1bit - uint8_t *above_intra_ctx; // 1bit - uint8_t *above_comp_ctx; // 1bit - uint8_t *above_ref_ctx; // 2bit - uint8_t *above_filter_ctx; - VP56mv (*above_mv_ctx)[2]; - - // whole-frame cache - uint8_t *intra_pred_data[3]; - VP9Filter *lflvl; - DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[135 * 144 * 2]; - // block reconstruction intermediates - int block_alloc_using_2pass; - int16_t *block_base, *block, *uvblock_base[2], *uvblock[2]; - uint8_t *eob_base, *uveob_base[2], *eob, *uveob[2]; - struct { int x, y; } min_mv, max_mv; DECLARE_ALIGNED(32, uint8_t, tmp_y)[64 * 64 * 2]; DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][64 * 64 * 2]; - uint16_t mvscale[3][2]; - uint8_t mvstep[3][2]; -} VP9Context; + struct { int x, y; } min_mv, max_mv; + int16_t *block_base, *block, *uvblock_base[2], *uvblock[2]; + uint8_t *eob_base, *uveob_base[2], *eob, *uveob[2]; +}; -void ff_vp9_fill_mv(VP9Context *s, VP56mv *mv, int mode, int sb); +void ff_vp9_fill_mv(VP9TileData *td, VP56mv *mv, int mode, int sb); void ff_vp9_adapt_probs(VP9Context *s); -void ff_vp9_decode_block(AVCodecContext *ctx, int row, int col, +void ff_vp9_decode_block(VP9TileData *td, int row, int col, VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl, enum BlockPartition bp); void ff_vp9_loopfilter_sb(AVCodecContext *avctx, VP9Filter *lflvl, int row, int col, ptrdiff_t yoff, ptrdiff_t uvoff); -void ff_vp9_intra_recon_8bpp(AVCodecContext *avctx, +void ff_vp9_intra_recon_8bpp(VP9TileData *td, ptrdiff_t y_off, ptrdiff_t uv_off); -void ff_vp9_intra_recon_16bpp(AVCodecContext *avctx, +void ff_vp9_intra_recon_16bpp(VP9TileData *td, ptrdiff_t y_off, ptrdiff_t uv_off); -void ff_vp9_inter_recon_8bpp(AVCodecContext *avctx); -void ff_vp9_inter_recon_16bpp(AVCodecContext *avctx); +void ff_vp9_inter_recon_8bpp(VP9TileData *td); +void ff_vp9_inter_recon_16bpp(VP9TileData *td); #endif /* AVCODEC_VP9DEC_H */ diff --git a/libavcodec/vp9mvs.c b/libavcodec/vp9mvs.c index e323bacc49c8f..88db1c341c16d 100644 --- a/libavcodec/vp9mvs.c +++ b/libavcodec/vp9mvs.c @@ -28,13 +28,13 @@ #include "vp9dec.h" static av_always_inline void clamp_mv(VP56mv *dst, const VP56mv *src, - VP9Context *s) + VP9TileData *td) { - dst->x = av_clip(src->x, s->min_mv.x, s->max_mv.x); - dst->y = av_clip(src->y, s->min_mv.y, s->max_mv.y); + dst->x = av_clip(src->x, td->min_mv.x, td->max_mv.x); + dst->y = av_clip(src->y, td->min_mv.y, td->max_mv.y); } -static void find_ref_mvs(VP9Context *s, +static void find_ref_mvs(VP9TileData *td, VP56mv *pmv, int ref, int z, int idx, int sb) { static const int8_t mv_ref_blk_off[N_BS_SIZES][8][2] = { @@ -65,8 +65,9 @@ static void find_ref_mvs(VP9Context *s, [BS_4x4] = { { 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } }, }; - VP9Block *b = s->b; - int row = s->row, col = s->col, row7 = s->row7; + VP9Context *s = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col, row7 = td->row7; const int8_t (*p)[2] = mv_ref_blk_off[b->bs]; #define INVALID_MV 0x80008000U uint32_t mem = INVALID_MV, mem_sub8x8 = INVALID_MV; @@ -103,7 +104,7 @@ static void find_ref_mvs(VP9Context *s, av_assert2(idx == 1); \ av_assert2(mem != INVALID_MV); \ if (mem_sub8x8 == INVALID_MV) { \ - clamp_mv(&tmp, &mv, s); \ + clamp_mv(&tmp, &mv, td); \ m = AV_RN32A(&tmp); \ if (m != mem) { \ AV_WN32A(pmv, m); \ @@ -111,7 +112,7 @@ static void find_ref_mvs(VP9Context *s, } \ mem_sub8x8 = AV_RN32A(&mv); \ } else if (mem_sub8x8 != AV_RN32A(&mv)) { \ - clamp_mv(&tmp, &mv, s); \ + clamp_mv(&tmp, &mv, td); \ m = AV_RN32A(&tmp); \ if (m != mem) { \ AV_WN32A(pmv, m); \ @@ -124,12 +125,12 @@ static void find_ref_mvs(VP9Context *s, } else { \ uint32_t m = AV_RN32A(&mv); \ if (!idx) { \ - clamp_mv(pmv, &mv, s); \ + clamp_mv(pmv, &mv, td); \ return; \ } else if (mem == INVALID_MV) { \ mem = m; \ } else if (m != mem) { \ - clamp_mv(pmv, &mv, s); \ + clamp_mv(pmv, &mv, td); \ return; \ } \ } \ @@ -142,12 +143,12 @@ static void find_ref_mvs(VP9Context *s, else if (mv->ref[1] == ref) RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][1]); } - if (col > s->tile_col_start) { + if (col > td->tile_col_start) { VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[row * s->sb_cols * 8 + col - 1]; if (mv->ref[0] == ref) - RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][0]); + RETURN_MV(td->left_mv_ctx[2 * row7 + (sb >> 1)][0]); else if (mv->ref[1] == ref) - RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][1]); + RETURN_MV(td->left_mv_ctx[2 * row7 + (sb >> 1)][1]); } i = 2; } else { @@ -158,7 +159,7 @@ static void find_ref_mvs(VP9Context *s, for (; i < 8; i++) { int c = p[i][0] + col, r = p[i][1] + row; - if (c >= s->tile_col_start && c < s->cols && + if (c >= td->tile_col_start && c < s->cols && r >= 0 && r < s->rows) { VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c]; @@ -195,7 +196,7 @@ static void find_ref_mvs(VP9Context *s, for (i = 0; i < 8; i++) { int c = p[i][0] + col, r = p[i][1] + row; - if (c >= s->tile_col_start && c < s->cols && r >= 0 && r < s->rows) { + if (c >= td->tile_col_start && c < s->cols && r >= 0 && r < s->rows) { VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c]; if (mv->ref[0] != ref && mv->ref[0] >= 0) @@ -226,69 +227,71 @@ static void find_ref_mvs(VP9Context *s, } AV_ZERO32(pmv); - clamp_mv(pmv, pmv, s); + clamp_mv(pmv, pmv, td); #undef INVALID_MV #undef RETURN_MV #undef RETURN_SCALE_MV } -static av_always_inline int read_mv_component(VP9Context *s, int idx, int hp) +static av_always_inline int read_mv_component(VP9TileData *td, int idx, int hp) { - int bit, sign = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].sign); - int n, c = vp8_rac_get_tree(&s->c, ff_vp9_mv_class_tree, + VP9Context *s = td->s; + int bit, sign = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].sign); + int n, c = vp8_rac_get_tree(td->c, ff_vp9_mv_class_tree, s->prob.p.mv_comp[idx].classes); - s->counts.mv_comp[idx].sign[sign]++; - s->counts.mv_comp[idx].classes[c]++; + td->counts.mv_comp[idx].sign[sign]++; + td->counts.mv_comp[idx].classes[c]++; if (c) { int m; for (n = 0, m = 0; m < c; m++) { - bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].bits[m]); + bit = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].bits[m]); n |= bit << m; - s->counts.mv_comp[idx].bits[m][bit]++; + td->counts.mv_comp[idx].bits[m][bit]++; } n <<= 3; - bit = vp8_rac_get_tree(&s->c, ff_vp9_mv_fp_tree, + bit = vp8_rac_get_tree(td->c, ff_vp9_mv_fp_tree, s->prob.p.mv_comp[idx].fp); n |= bit << 1; - s->counts.mv_comp[idx].fp[bit]++; + td->counts.mv_comp[idx].fp[bit]++; if (hp) { - bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].hp); - s->counts.mv_comp[idx].hp[bit]++; + bit = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].hp); + td->counts.mv_comp[idx].hp[bit]++; n |= bit; } else { n |= 1; // bug in libvpx - we count for bw entropy purposes even if the // bit wasn't coded - s->counts.mv_comp[idx].hp[1]++; + td->counts.mv_comp[idx].hp[1]++; } n += 8 << c; } else { - n = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].class0); - s->counts.mv_comp[idx].class0[n]++; - bit = vp8_rac_get_tree(&s->c, ff_vp9_mv_fp_tree, + n = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].class0); + td->counts.mv_comp[idx].class0[n]++; + bit = vp8_rac_get_tree(td->c, ff_vp9_mv_fp_tree, s->prob.p.mv_comp[idx].class0_fp[n]); - s->counts.mv_comp[idx].class0_fp[n][bit]++; + td->counts.mv_comp[idx].class0_fp[n][bit]++; n = (n << 3) | (bit << 1); if (hp) { - bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].class0_hp); - s->counts.mv_comp[idx].class0_hp[bit]++; + bit = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].class0_hp); + td->counts.mv_comp[idx].class0_hp[bit]++; n |= bit; } else { n |= 1; // bug in libvpx - we count for bw entropy purposes even if the // bit wasn't coded - s->counts.mv_comp[idx].class0_hp[1]++; + td->counts.mv_comp[idx].class0_hp[1]++; } } return sign ? -(n + 1) : (n + 1); } -void ff_vp9_fill_mv(VP9Context *s, VP56mv *mv, int mode, int sb) +void ff_vp9_fill_mv(VP9TileData *td, VP56mv *mv, int mode, int sb) { - VP9Block *b = s->b; + VP9Context *s = td->s; + VP9Block *b = td->b; if (mode == ZEROMV) { AV_ZERO64(mv); @@ -296,7 +299,7 @@ void ff_vp9_fill_mv(VP9Context *s, VP56mv *mv, int mode, int sb) int hp; // FIXME cache this value and reuse for other subblocks - find_ref_mvs(s, &mv[0], b->ref[0], 0, mode == NEARMV, + find_ref_mvs(td, &mv[0], b->ref[0], 0, mode == NEARMV, mode == NEWMV ? -1 : sb); // FIXME maybe move this code into find_ref_mvs() if ((mode == NEWMV || sb == -1) && @@ -316,19 +319,19 @@ void ff_vp9_fill_mv(VP9Context *s, VP56mv *mv, int mode, int sb) } } if (mode == NEWMV) { - enum MVJoint j = vp8_rac_get_tree(&s->c, ff_vp9_mv_joint_tree, + enum MVJoint j = vp8_rac_get_tree(td->c, ff_vp9_mv_joint_tree, s->prob.p.mv_joint); - s->counts.mv_joint[j]++; + td->counts.mv_joint[j]++; if (j >= MV_JOINT_V) - mv[0].y += read_mv_component(s, 0, hp); + mv[0].y += read_mv_component(td, 0, hp); if (j & 1) - mv[0].x += read_mv_component(s, 1, hp); + mv[0].x += read_mv_component(td, 1, hp); } if (b->comp) { // FIXME cache this value and reuse for other subblocks - find_ref_mvs(s, &mv[1], b->ref[1], 1, mode == NEARMV, + find_ref_mvs(td, &mv[1], b->ref[1], 1, mode == NEARMV, mode == NEWMV ? -1 : sb); if ((mode == NEWMV || sb == -1) && !(hp = s->s.h.highprecisionmvs && @@ -347,14 +350,14 @@ void ff_vp9_fill_mv(VP9Context *s, VP56mv *mv, int mode, int sb) } } if (mode == NEWMV) { - enum MVJoint j = vp8_rac_get_tree(&s->c, ff_vp9_mv_joint_tree, + enum MVJoint j = vp8_rac_get_tree(td->c, ff_vp9_mv_joint_tree, s->prob.p.mv_joint); - s->counts.mv_joint[j]++; + td->counts.mv_joint[j]++; if (j >= MV_JOINT_V) - mv[1].y += read_mv_component(s, 0, hp); + mv[1].y += read_mv_component(td, 0, hp); if (j & 1) - mv[1].x += read_mv_component(s, 1, hp); + mv[1].x += read_mv_component(td, 1, hp); } } } diff --git a/libavcodec/vp9prob.c b/libavcodec/vp9prob.c index cde909ce66a64..fb295b482d0b3 100644 --- a/libavcodec/vp9prob.c +++ b/libavcodec/vp9prob.c @@ -56,8 +56,8 @@ void ff_vp9_adapt_probs(VP9Context *s) for (l = 0; l < 6; l++) for (m = 0; m < 6; m++) { uint8_t *pp = s->prob_ctx[s->s.h.framectxid].coef[i][j][k][l][m]; - unsigned *e = s->counts.eob[i][j][k][l][m]; - unsigned *c = s->counts.coef[i][j][k][l][m]; + unsigned *e = s->td[0].counts.eob[i][j][k][l][m]; + unsigned *c = s->td[0].counts.coef[i][j][k][l][m]; if (l == 0 && m >= 3) // dc only has 3 pt break; @@ -77,32 +77,32 @@ void ff_vp9_adapt_probs(VP9Context *s) // skip flag for (i = 0; i < 3; i++) - adapt_prob(&p->skip[i], s->counts.skip[i][0], - s->counts.skip[i][1], 20, 128); + adapt_prob(&p->skip[i], s->td[0].counts.skip[i][0], + s->td[0].counts.skip[i][1], 20, 128); // intra/inter flag for (i = 0; i < 4; i++) - adapt_prob(&p->intra[i], s->counts.intra[i][0], - s->counts.intra[i][1], 20, 128); + adapt_prob(&p->intra[i], s->td[0].counts.intra[i][0], + s->td[0].counts.intra[i][1], 20, 128); // comppred flag if (s->s.h.comppredmode == PRED_SWITCHABLE) { for (i = 0; i < 5; i++) - adapt_prob(&p->comp[i], s->counts.comp[i][0], - s->counts.comp[i][1], 20, 128); + adapt_prob(&p->comp[i], s->td[0].counts.comp[i][0], + s->td[0].counts.comp[i][1], 20, 128); } // reference frames if (s->s.h.comppredmode != PRED_SINGLEREF) { for (i = 0; i < 5; i++) - adapt_prob(&p->comp_ref[i], s->counts.comp_ref[i][0], - s->counts.comp_ref[i][1], 20, 128); + adapt_prob(&p->comp_ref[i], s->td[0].counts.comp_ref[i][0], + s->td[0].counts.comp_ref[i][1], 20, 128); } if (s->s.h.comppredmode != PRED_COMPREF) { for (i = 0; i < 5; i++) { uint8_t *pp = p->single_ref[i]; - unsigned (*c)[2] = s->counts.single_ref[i]; + unsigned (*c)[2] = s->td[0].counts.single_ref[i]; adapt_prob(&pp[0], c[0][0], c[0][1], 20, 128); adapt_prob(&pp[1], c[1][0], c[1][1], 20, 128); @@ -113,7 +113,7 @@ void ff_vp9_adapt_probs(VP9Context *s) for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) { uint8_t *pp = p->partition[i][j]; - unsigned *c = s->counts.partition[i][j]; + unsigned *c = s->td[0].counts.partition[i][j]; adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); @@ -123,10 +123,10 @@ void ff_vp9_adapt_probs(VP9Context *s) // tx size if (s->s.h.txfmmode == TX_SWITCHABLE) { for (i = 0; i < 2; i++) { - unsigned *c16 = s->counts.tx16p[i], *c32 = s->counts.tx32p[i]; + unsigned *c16 = s->td[0].counts.tx16p[i], *c32 = s->td[0].counts.tx32p[i]; - adapt_prob(&p->tx8p[i], s->counts.tx8p[i][0], - s->counts.tx8p[i][1], 20, 128); + adapt_prob(&p->tx8p[i], s->td[0].counts.tx8p[i][0], + s->td[0].counts.tx8p[i][1], 20, 128); adapt_prob(&p->tx16p[i][0], c16[0], c16[1] + c16[2], 20, 128); adapt_prob(&p->tx16p[i][1], c16[1], c16[2], 20, 128); adapt_prob(&p->tx32p[i][0], c32[0], c32[1] + c32[2] + c32[3], 20, 128); @@ -139,7 +139,7 @@ void ff_vp9_adapt_probs(VP9Context *s) if (s->s.h.filtermode == FILTER_SWITCHABLE) { for (i = 0; i < 4; i++) { uint8_t *pp = p->filter[i]; - unsigned *c = s->counts.filter[i]; + unsigned *c = s->td[0].counts.filter[i]; adapt_prob(&pp[0], c[0], c[1] + c[2], 20, 128); adapt_prob(&pp[1], c[1], c[2], 20, 128); @@ -149,7 +149,7 @@ void ff_vp9_adapt_probs(VP9Context *s) // inter modes for (i = 0; i < 7; i++) { uint8_t *pp = p->mv_mode[i]; - unsigned *c = s->counts.mv_mode[i]; + unsigned *c = s->td[0].counts.mv_mode[i]; adapt_prob(&pp[0], c[2], c[1] + c[0] + c[3], 20, 128); adapt_prob(&pp[1], c[0], c[1] + c[3], 20, 128); @@ -159,7 +159,7 @@ void ff_vp9_adapt_probs(VP9Context *s) // mv joints { uint8_t *pp = p->mv_joint; - unsigned *c = s->counts.mv_joint; + unsigned *c = s->td[0].counts.mv_joint; adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); @@ -171,11 +171,11 @@ void ff_vp9_adapt_probs(VP9Context *s) uint8_t *pp; unsigned *c, (*c2)[2], sum; - adapt_prob(&p->mv_comp[i].sign, s->counts.mv_comp[i].sign[0], - s->counts.mv_comp[i].sign[1], 20, 128); + adapt_prob(&p->mv_comp[i].sign, s->td[0].counts.mv_comp[i].sign[0], + s->td[0].counts.mv_comp[i].sign[1], 20, 128); pp = p->mv_comp[i].classes; - c = s->counts.mv_comp[i].classes; + c = s->td[0].counts.mv_comp[i].classes; sum = c[1] + c[2] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9] + c[10]; adapt_prob(&pp[0], c[0], sum, 20, 128); @@ -193,39 +193,39 @@ void ff_vp9_adapt_probs(VP9Context *s) adapt_prob(&pp[8], c[7], c[8], 20, 128); adapt_prob(&pp[9], c[9], c[10], 20, 128); - adapt_prob(&p->mv_comp[i].class0, s->counts.mv_comp[i].class0[0], - s->counts.mv_comp[i].class0[1], 20, 128); + adapt_prob(&p->mv_comp[i].class0, s->td[0].counts.mv_comp[i].class0[0], + s->td[0].counts.mv_comp[i].class0[1], 20, 128); pp = p->mv_comp[i].bits; - c2 = s->counts.mv_comp[i].bits; + c2 = s->td[0].counts.mv_comp[i].bits; for (j = 0; j < 10; j++) adapt_prob(&pp[j], c2[j][0], c2[j][1], 20, 128); for (j = 0; j < 2; j++) { pp = p->mv_comp[i].class0_fp[j]; - c = s->counts.mv_comp[i].class0_fp[j]; + c = s->td[0].counts.mv_comp[i].class0_fp[j]; adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); adapt_prob(&pp[2], c[2], c[3], 20, 128); } pp = p->mv_comp[i].fp; - c = s->counts.mv_comp[i].fp; + c = s->td[0].counts.mv_comp[i].fp; adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); adapt_prob(&pp[2], c[2], c[3], 20, 128); if (s->s.h.highprecisionmvs) { adapt_prob(&p->mv_comp[i].class0_hp, - s->counts.mv_comp[i].class0_hp[0], - s->counts.mv_comp[i].class0_hp[1], 20, 128); - adapt_prob(&p->mv_comp[i].hp, s->counts.mv_comp[i].hp[0], - s->counts.mv_comp[i].hp[1], 20, 128); + s->td[0].counts.mv_comp[i].class0_hp[0], + s->td[0].counts.mv_comp[i].class0_hp[1], 20, 128); + adapt_prob(&p->mv_comp[i].hp, s->td[0].counts.mv_comp[i].hp[0], + s->td[0].counts.mv_comp[i].hp[1], 20, 128); } } // y intra modes for (i = 0; i < 4; i++) { uint8_t *pp = p->y_mode[i]; - unsigned *c = s->counts.y_mode[i], sum, s2; + unsigned *c = s->td[0].counts.y_mode[i], sum, s2; sum = c[0] + c[1] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9]; adapt_prob(&pp[0], c[DC_PRED], sum, 20, 128); @@ -250,7 +250,7 @@ void ff_vp9_adapt_probs(VP9Context *s) // uv intra modes for (i = 0; i < 10; i++) { uint8_t *pp = p->uv_mode[i]; - unsigned *c = s->counts.uv_mode[i], sum, s2; + unsigned *c = s->td[0].counts.uv_mode[i], sum, s2; sum = c[0] + c[1] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9]; adapt_prob(&pp[0], c[DC_PRED], sum, 20, 128); diff --git a/libavcodec/vp9recon.c b/libavcodec/vp9recon.c index afdb51350c50b..49bb04e1f40ff 100644 --- a/libavcodec/vp9recon.c +++ b/libavcodec/vp9recon.c @@ -29,15 +29,16 @@ #include "vp9data.h" #include "vp9dec.h" -static av_always_inline int check_intra_mode(VP9Context *s, int mode, uint8_t **a, +static av_always_inline int check_intra_mode(VP9TileData *td, int mode, uint8_t **a, uint8_t *dst_edge, ptrdiff_t stride_edge, uint8_t *dst_inner, ptrdiff_t stride_inner, uint8_t *l, int col, int x, int w, int row, int y, enum TxfmMode tx, int p, int ss_h, int ss_v, int bytesperpixel) { + VP9Context *s = td->s; int have_top = row > 0 || y > 0; - int have_left = col > s->tile_col_start || x > 0; + int have_left = col > td->tile_col_start || x > 0; int have_right = x < w - 1; int bpp = s->s.h.bpp; static const uint8_t mode_conv[10][2 /* have_left */][2 /* have_top */] = { @@ -214,19 +215,19 @@ static av_always_inline int check_intra_mode(VP9Context *s, int mode, uint8_t ** return mode; } -static av_always_inline void intra_recon(AVCodecContext *avctx, ptrdiff_t y_off, +static av_always_inline void intra_recon(VP9TileData *td, ptrdiff_t y_off, ptrdiff_t uv_off, int bytesperpixel) { - VP9Context *s = avctx->priv_data; - VP9Block *b = s->b; - int row = s->row, col = s->col; + VP9Context *s = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col; int w4 = ff_vp9_bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n; int h4 = ff_vp9_bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2); int end_x = FFMIN(2 * (s->cols - col), w4); int end_y = FFMIN(2 * (s->rows - row), h4); int tx = 4 * s->s.h.lossless + b->tx, uvtx = b->uvtx + 4 * s->s.h.lossless; int uvstep1d = 1 << b->uvtx, p; - uint8_t *dst = s->dst[0], *dst_r = s->s.frames[CUR_FRAME].tf.f->data[0] + y_off; + uint8_t *dst = td->dst[0], *dst_r = s->s.frames[CUR_FRAME].tf.f->data[0] + y_off; LOCAL_ALIGNED_32(uint8_t, a_buf, [96]); LOCAL_ALIGNED_32(uint8_t, l, [64]); @@ -238,19 +239,19 @@ static av_always_inline void intra_recon(AVCodecContext *avctx, ptrdiff_t y_off, y * 2 + x : 0]; uint8_t *a = &a_buf[32]; enum TxfmType txtp = ff_vp9_intra_txfm_type[mode]; - int eob = b->skip ? 0 : b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n]; + int eob = b->skip ? 0 : b->tx > TX_8X8 ? AV_RN16A(&td->eob[n]) : td->eob[n]; - mode = check_intra_mode(s, mode, &a, ptr_r, + mode = check_intra_mode(td, mode, &a, ptr_r, s->s.frames[CUR_FRAME].tf.f->linesize[0], - ptr, s->y_stride, l, + ptr, td->y_stride, l, col, x, w4, row, y, b->tx, 0, 0, 0, bytesperpixel); - s->dsp.intra_pred[b->tx][mode](ptr, s->y_stride, l, a); + s->dsp.intra_pred[b->tx][mode](ptr, td->y_stride, l, a); if (eob) - s->dsp.itxfm_add[tx][txtp](ptr, s->y_stride, - s->block + 16 * n * bytesperpixel, eob); + s->dsp.itxfm_add[tx][txtp](ptr, td->y_stride, + td->block + 16 * n * bytesperpixel, eob); } dst_r += 4 * step1d * s->s.frames[CUR_FRAME].tf.f->linesize[0]; - dst += 4 * step1d * s->y_stride; + dst += 4 * step1d * td->y_stride; } // U/V @@ -259,7 +260,7 @@ static av_always_inline void intra_recon(AVCodecContext *avctx, ptrdiff_t y_off, end_y >>= s->ss_v; step = 1 << (b->uvtx * 2); for (p = 0; p < 2; p++) { - dst = s->dst[1 + p]; + dst = td->dst[1 + p]; dst_r = s->s.frames[CUR_FRAME].tf.f->data[1 + p] + uv_off; for (n = 0, y = 0; y < end_y; y += uvstep1d) { uint8_t *ptr = dst, *ptr_r = dst_r; @@ -267,40 +268,41 @@ static av_always_inline void intra_recon(AVCodecContext *avctx, ptrdiff_t y_off, ptr_r += 4 * uvstep1d * bytesperpixel, n += step) { int mode = b->uvmode; uint8_t *a = &a_buf[32]; - int eob = b->skip ? 0 : b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n]; + int eob = b->skip ? 0 : b->uvtx > TX_8X8 ? AV_RN16A(&td->uveob[p][n]) : td->uveob[p][n]; - mode = check_intra_mode(s, mode, &a, ptr_r, + mode = check_intra_mode(td, mode, &a, ptr_r, s->s.frames[CUR_FRAME].tf.f->linesize[1], - ptr, s->uv_stride, l, col, x, w4, row, y, + ptr, td->uv_stride, l, col, x, w4, row, y, b->uvtx, p + 1, s->ss_h, s->ss_v, bytesperpixel); - s->dsp.intra_pred[b->uvtx][mode](ptr, s->uv_stride, l, a); + s->dsp.intra_pred[b->uvtx][mode](ptr, td->uv_stride, l, a); if (eob) - s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride, - s->uvblock[p] + 16 * n * bytesperpixel, eob); + s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, td->uv_stride, + td->uvblock[p] + 16 * n * bytesperpixel, eob); } dst_r += 4 * uvstep1d * s->s.frames[CUR_FRAME].tf.f->linesize[1]; - dst += 4 * uvstep1d * s->uv_stride; + dst += 4 * uvstep1d * td->uv_stride; } } } -void ff_vp9_intra_recon_8bpp(AVCodecContext *avctx, ptrdiff_t y_off, ptrdiff_t uv_off) +void ff_vp9_intra_recon_8bpp(VP9TileData *td, ptrdiff_t y_off, ptrdiff_t uv_off) { - intra_recon(avctx, y_off, uv_off, 1); + intra_recon(td, y_off, uv_off, 1); } -void ff_vp9_intra_recon_16bpp(AVCodecContext *avctx, ptrdiff_t y_off, ptrdiff_t uv_off) +void ff_vp9_intra_recon_16bpp(VP9TileData *td, ptrdiff_t y_off, ptrdiff_t uv_off) { - intra_recon(avctx, y_off, uv_off, 2); + intra_recon(td, y_off, uv_off, 2); } -static av_always_inline void mc_luma_unscaled(VP9Context *s, vp9_mc_func (*mc)[2], +static av_always_inline void mc_luma_unscaled(VP9TileData *td, vp9_mc_func (*mc)[2], uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *ref, ptrdiff_t ref_stride, ThreadFrame *ref_frame, ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, int bw, int bh, int w, int h, int bytesperpixel) { + VP9Context *s = td->s; int mx = mv->x, my = mv->y, th; y += my >> 3; @@ -318,18 +320,18 @@ static av_always_inline void mc_luma_unscaled(VP9Context *s, vp9_mc_func (*mc)[2 // (!!my * 5) than horizontally (!!mx * 4). if (x < !!mx * 3 || y < !!my * 3 || x + !!mx * 4 > w - bw || y + !!my * 5 > h - bh) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + s->vdsp.emulated_edge_mc(td->edge_emu_buffer, ref - !!my * 3 * ref_stride - !!mx * 3 * bytesperpixel, 160, ref_stride, bw + !!mx * 7, bh + !!my * 7, x - !!mx * 3, y - !!my * 3, w, h); - ref = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; + ref = td->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; ref_stride = 160; } mc[!!mx][!!my](dst, dst_stride, ref, ref_stride, bh, mx << 1, my << 1); } -static av_always_inline void mc_chroma_unscaled(VP9Context *s, vp9_mc_func (*mc)[2], +static av_always_inline void mc_chroma_unscaled(VP9TileData *td, vp9_mc_func (*mc)[2], uint8_t *dst_u, uint8_t *dst_v, ptrdiff_t dst_stride, const uint8_t *ref_u, ptrdiff_t src_stride_u, @@ -338,6 +340,7 @@ static av_always_inline void mc_chroma_unscaled(VP9Context *s, vp9_mc_func (*mc) ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, int bw, int bh, int w, int h, int bytesperpixel) { + VP9Context *s = td->s; int mx = mv->x * (1 << !s->ss_h), my = mv->y * (1 << !s->ss_v), th; y += my >> 4; @@ -356,20 +359,20 @@ static av_always_inline void mc_chroma_unscaled(VP9Context *s, vp9_mc_func (*mc) // (!!my * 5) than horizontally (!!mx * 4). if (x < !!mx * 3 || y < !!my * 3 || x + !!mx * 4 > w - bw || y + !!my * 5 > h - bh) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + s->vdsp.emulated_edge_mc(td->edge_emu_buffer, ref_u - !!my * 3 * src_stride_u - !!mx * 3 * bytesperpixel, 160, src_stride_u, bw + !!mx * 7, bh + !!my * 7, x - !!mx * 3, y - !!my * 3, w, h); - ref_u = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; + ref_u = td->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; mc[!!mx][!!my](dst_u, dst_stride, ref_u, 160, bh, mx, my); - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + s->vdsp.emulated_edge_mc(td->edge_emu_buffer, ref_v - !!my * 3 * src_stride_v - !!mx * 3 * bytesperpixel, 160, src_stride_v, bw + !!mx * 7, bh + !!my * 7, x - !!mx * 3, y - !!my * 3, w, h); - ref_v = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; + ref_v = td->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; mc[!!mx][!!my](dst_v, dst_stride, ref_v, 160, bh, mx, my); } else { mc[!!mx][!!my](dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my); @@ -377,13 +380,13 @@ static av_always_inline void mc_chroma_unscaled(VP9Context *s, vp9_mc_func (*mc) } } -#define mc_luma_dir(s, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ +#define mc_luma_dir(td, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ px, py, pw, ph, bw, bh, w, h, i) \ - mc_luma_unscaled(s, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ + mc_luma_unscaled(td, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ mv, bw, bh, w, h, bytesperpixel) -#define mc_chroma_dir(s, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ +#define mc_chroma_dir(td, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ row, col, mv, px, py, pw, ph, bw, bh, w, h, i) \ - mc_chroma_unscaled(s, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ + mc_chroma_unscaled(td, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ row, col, mv, bw, bh, w, h, bytesperpixel) #define SCALED 0 #define FN(x) x##_8bpp @@ -400,7 +403,7 @@ static av_always_inline void mc_chroma_unscaled(VP9Context *s, vp9_mc_func (*mc) #undef BYTES_PER_PIXEL #undef SCALED -static av_always_inline void mc_luma_scaled(VP9Context *s, vp9_scaled_mc_func smc, +static av_always_inline void mc_luma_scaled(VP9TileData *td, vp9_scaled_mc_func smc, vp9_mc_func (*mc)[2], uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *ref, ptrdiff_t ref_stride, @@ -410,9 +413,10 @@ static av_always_inline void mc_luma_scaled(VP9Context *s, vp9_scaled_mc_func sm int bw, int bh, int w, int h, int bytesperpixel, const uint16_t *scale, const uint8_t *step) { + VP9Context *s = td->s; if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width && s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) { - mc_luma_unscaled(s, mc, dst, dst_stride, ref, ref_stride, ref_frame, + mc_luma_unscaled(td, mc, dst, dst_stride, ref, ref_stride, ref_frame, y, x, in_mv, bw, bh, w, h, bytesperpixel); } else { #define scale_mv(n, dim) (((int64_t)(n) * scale[dim]) >> 14) @@ -445,19 +449,19 @@ static av_always_inline void mc_luma_scaled(VP9Context *s, vp9_scaled_mc_func sm // needed, so switch to emulated edge one pixel sooner vertically // (y + 5 >= h - refbh_m1) than horizontally (x + 4 >= w - refbw_m1). if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 5 >= h - refbh_m1) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + s->vdsp.emulated_edge_mc(td->edge_emu_buffer, ref - 3 * ref_stride - 3 * bytesperpixel, 288, ref_stride, refbw_m1 + 8, refbh_m1 + 8, x - 3, y - 3, w, h); - ref = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; + ref = td->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; ref_stride = 288; } smc(dst, dst_stride, ref, ref_stride, bh, mx, my, step[0], step[1]); } } -static av_always_inline void mc_chroma_scaled(VP9Context *s, vp9_scaled_mc_func smc, +static av_always_inline void mc_chroma_scaled(VP9TileData *td, vp9_scaled_mc_func smc, vp9_mc_func (*mc)[2], uint8_t *dst_u, uint8_t *dst_v, ptrdiff_t dst_stride, @@ -469,9 +473,10 @@ static av_always_inline void mc_chroma_scaled(VP9Context *s, vp9_scaled_mc_func int bw, int bh, int w, int h, int bytesperpixel, const uint16_t *scale, const uint8_t *step) { + VP9Context *s = td->s; if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width && s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) { - mc_chroma_unscaled(s, mc, dst_u, dst_v, dst_stride, ref_u, src_stride_u, + mc_chroma_unscaled(td, mc, dst_u, dst_v, dst_stride, ref_u, src_stride_u, ref_v, src_stride_v, ref_frame, y, x, in_mv, bw, bh, w, h, bytesperpixel); } else { @@ -514,20 +519,20 @@ static av_always_inline void mc_chroma_scaled(VP9Context *s, vp9_scaled_mc_func // needed, so switch to emulated edge one pixel sooner vertically // (y + 5 >= h - refbh_m1) than horizontally (x + 4 >= w - refbw_m1). if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 5 >= h - refbh_m1) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + s->vdsp.emulated_edge_mc(td->edge_emu_buffer, ref_u - 3 * src_stride_u - 3 * bytesperpixel, 288, src_stride_u, refbw_m1 + 8, refbh_m1 + 8, x - 3, y - 3, w, h); - ref_u = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; + ref_u = td->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; smc(dst_u, dst_stride, ref_u, 288, bh, mx, my, step[0], step[1]); - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + s->vdsp.emulated_edge_mc(td->edge_emu_buffer, ref_v - 3 * src_stride_v - 3 * bytesperpixel, 288, src_stride_v, refbw_m1 + 8, refbh_m1 + 8, x - 3, y - 3, w, h); - ref_v = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; + ref_v = td->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; smc(dst_v, dst_stride, ref_v, 288, bh, mx, my, step[0], step[1]); } else { smc(dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my, step[0], step[1]); @@ -536,14 +541,14 @@ static av_always_inline void mc_chroma_scaled(VP9Context *s, vp9_scaled_mc_func } } -#define mc_luma_dir(s, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ +#define mc_luma_dir(td, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ px, py, pw, ph, bw, bh, w, h, i) \ - mc_luma_scaled(s, s->dsp.s##mc, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ + mc_luma_scaled(td, s->dsp.s##mc, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ mv, px, py, pw, ph, bw, bh, w, h, bytesperpixel, \ s->mvscale[b->ref[i]], s->mvstep[b->ref[i]]) -#define mc_chroma_dir(s, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ +#define mc_chroma_dir(td, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ row, col, mv, px, py, pw, ph, bw, bh, w, h, i) \ - mc_chroma_scaled(s, s->dsp.s##mc, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ + mc_chroma_scaled(td, s->dsp.s##mc, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ row, col, mv, px, py, pw, ph, bw, bh, w, h, bytesperpixel, \ s->mvscale[b->ref[i]], s->mvstep[b->ref[i]]) #define SCALED 1 @@ -561,23 +566,23 @@ static av_always_inline void mc_chroma_scaled(VP9Context *s, vp9_scaled_mc_func #undef BYTES_PER_PIXEL #undef SCALED -static av_always_inline void inter_recon(AVCodecContext *avctx, int bytesperpixel) +static av_always_inline void inter_recon(VP9TileData *td, int bytesperpixel) { - VP9Context *s = avctx->priv_data; - VP9Block *b = s->b; - int row = s->row, col = s->col; + VP9Context *s = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col; if (s->mvscale[b->ref[0]][0] || (b->comp && s->mvscale[b->ref[1]][0])) { if (bytesperpixel == 1) { - inter_pred_scaled_8bpp(avctx); + inter_pred_scaled_8bpp(td); } else { - inter_pred_scaled_16bpp(avctx); + inter_pred_scaled_16bpp(td); } } else { if (bytesperpixel == 1) { - inter_pred_8bpp(avctx); + inter_pred_8bpp(td); } else { - inter_pred_16bpp(avctx); + inter_pred_16bpp(td); } } @@ -590,20 +595,20 @@ static av_always_inline void inter_recon(AVCodecContext *avctx, int bytesperpixe int end_y = FFMIN(2 * (s->rows - row), h4); int tx = 4 * s->s.h.lossless + b->tx, uvtx = b->uvtx + 4 * s->s.h.lossless; int uvstep1d = 1 << b->uvtx, p; - uint8_t *dst = s->dst[0]; + uint8_t *dst = td->dst[0]; // y itxfm add for (n = 0, y = 0; y < end_y; y += step1d) { uint8_t *ptr = dst; for (x = 0; x < end_x; x += step1d, ptr += 4 * step1d * bytesperpixel, n += step) { - int eob = b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n]; + int eob = b->tx > TX_8X8 ? AV_RN16A(&td->eob[n]) : td->eob[n]; if (eob) - s->dsp.itxfm_add[tx][DCT_DCT](ptr, s->y_stride, - s->block + 16 * n * bytesperpixel, eob); + s->dsp.itxfm_add[tx][DCT_DCT](ptr, td->y_stride, + td->block + 16 * n * bytesperpixel, eob); } - dst += 4 * s->y_stride * step1d; + dst += 4 * td->y_stride * step1d; } // uv itxfm add @@ -611,29 +616,29 @@ static av_always_inline void inter_recon(AVCodecContext *avctx, int bytesperpixe end_y >>= s->ss_v; step = 1 << (b->uvtx * 2); for (p = 0; p < 2; p++) { - dst = s->dst[p + 1]; + dst = td->dst[p + 1]; for (n = 0, y = 0; y < end_y; y += uvstep1d) { uint8_t *ptr = dst; for (x = 0; x < end_x; x += uvstep1d, ptr += 4 * uvstep1d * bytesperpixel, n += step) { - int eob = b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n]; + int eob = b->uvtx > TX_8X8 ? AV_RN16A(&td->uveob[p][n]) : td->uveob[p][n]; if (eob) - s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride, - s->uvblock[p] + 16 * n * bytesperpixel, eob); + s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, td->uv_stride, + td->uvblock[p] + 16 * n * bytesperpixel, eob); } - dst += 4 * uvstep1d * s->uv_stride; + dst += 4 * uvstep1d * td->uv_stride; } } } } -void ff_vp9_inter_recon_8bpp(AVCodecContext *avctx) +void ff_vp9_inter_recon_8bpp(VP9TileData *td) { - inter_recon(avctx, 1); + inter_recon(td, 1); } -void ff_vp9_inter_recon_16bpp(AVCodecContext *avctx) +void ff_vp9_inter_recon_16bpp(VP9TileData *td) { - inter_recon(avctx, 2); + inter_recon(td, 2); } From cf0eed2525bda50991ba0af4f808533403b08f7c Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Wed, 6 Sep 2017 14:06:38 +0200 Subject: [PATCH 3015/3374] avfilter: add Haas stereo enhancer Signed-off-by: Paul B Mahol --- Changelog | 1 + doc/filters.texi | 64 +++++++++++ libavfilter/Makefile | 1 + libavfilter/af_haas.c | 228 +++++++++++++++++++++++++++++++++++++++ libavfilter/allfilters.c | 1 + libavfilter/version.h | 2 +- 6 files changed, 296 insertions(+), 1 deletion(-) create mode 100644 libavfilter/af_haas.c diff --git a/Changelog b/Changelog index cae5254e2b797..189a803ed32b2 100644 --- a/Changelog +++ b/Changelog @@ -43,6 +43,7 @@ version : - add --disable-autodetect build switch - drop deprecated qtkit input device (use avfoundation instead) - despill video filter +- haas audio filter version 3.3: - CrystalHD decoder moved to new decode API diff --git a/doc/filters.texi b/doc/filters.texi index 779036759370d..c3c54fdda5be0 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -2770,6 +2770,70 @@ Set delay-line interpolation, @var{linear} or @var{quadratic}. Default is @var{linear}. @end table +@section haas +Apply Haas effect to audio. + +Note that this makes most sense to apply on mono signals. +With this filter applied to mono signals it give some directionality and +streches its stereo image. + +The filter accepts the following options: + +@table @option +@item level_in +Set input level. By default is @var{1}, or 0dB + +@item level_out +Set output level. By default is @var{1}, or 0dB. + +@item side_gain +Set gain applied to side part of signal. By default is @var{1}. + +@item middle_source +Set kind of middle source. Can be one of the following: + +@table @samp +@item left +Pick left channel. + +@item right +Pick right channel. + +@item mid +Pick middle part signal of stereo image. + +@item side +Pick side part signal of stereo image. +@end table + +@item middle_phase +Change middle phase. By default is disabled. + +@item left_delay +Set left channel delay. By default is @var{2.05} milliseconds. + +@item left_balance +Set left channel balance. By default is @var{-1}. + +@item left_gain +Set left channel gain. By default is @var{1}. + +@item left_phase +Change left phase. By default is disabled. + +@item right_delay +Set right channel delay. By defaults is @var{2.12} milliseconds. + +@item right_balance +Set right channel balance. By default is @var{1}. + +@item right_gain +Set right channel gain. By default is @var{1}. + +@item right_phase +Change right phase. By default is enabled. +@end table + @section hdcd Decodes High Definition Compatible Digital (HDCD) data. A 16-bit PCM stream with diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 1e460ab988642..42686339085e9 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -91,6 +91,7 @@ OBJS-$(CONFIG_EQUALIZER_FILTER) += af_biquads.o OBJS-$(CONFIG_EXTRASTEREO_FILTER) += af_extrastereo.o OBJS-$(CONFIG_FIREQUALIZER_FILTER) += af_firequalizer.o OBJS-$(CONFIG_FLANGER_FILTER) += af_flanger.o generate_wave_table.o +OBJS-$(CONFIG_HAAS_FILTER) += af_haas.o OBJS-$(CONFIG_HDCD_FILTER) += af_hdcd.o OBJS-$(CONFIG_HEADPHONE_FILTER) += af_headphone.o OBJS-$(CONFIG_HIGHPASS_FILTER) += af_biquads.o diff --git a/libavfilter/af_haas.c b/libavfilter/af_haas.c new file mode 100644 index 0000000000000..691c251f54e08 --- /dev/null +++ b/libavfilter/af_haas.c @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2001-2010 Vladimir Sadovnikov + * + * 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 "libavutil/channel_layout.h" +#include "libavutil/opt.h" +#include "avfilter.h" +#include "audio.h" +#include "formats.h" + +#define MAX_HAAS_DELAY 40 + +typedef struct HaasContext { + const AVClass *class; + + int par_m_source; + double par_delay0; + double par_delay1; + int par_phase0; + int par_phase1; + int par_middle_phase; + double par_side_gain; + double par_gain0; + double par_gain1; + double par_balance0; + double par_balance1; + double level_in; + double level_out; + + double *buffer; + size_t buffer_size; + uint32_t write_ptr; + uint32_t delay[2]; + double balance_l[2]; + double balance_r[2]; + double phase0; + double phase1; +} HaasContext; + +#define OFFSET(x) offsetof(HaasContext, x) +#define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM + +static const AVOption haas_options[] = { + { "level_in", "set level in", OFFSET(level_in), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.015625, 64, A }, + { "level_out", "set level out", OFFSET(level_out), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.015625, 64, A }, + { "side_gain", "set side gain", OFFSET(par_side_gain), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.015625, 64, A }, + { "middle_source", "set middle source", OFFSET(par_m_source), AV_OPT_TYPE_INT, {.i64=2}, 0, 3, A, "source" }, + { "left", 0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, A, "source" }, + { "right", 0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, A, "source" }, + { "mid", "L+R", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, A, "source" }, + { "side", "L-R", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, A, "source" }, + { "middle_phase", "set middle phase", OFFSET(par_middle_phase), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, A }, + { "left_delay", "set left delay", OFFSET(par_delay0), AV_OPT_TYPE_DOUBLE, {.dbl=2.05}, 0, MAX_HAAS_DELAY, A }, + { "left_balance", "set left balance", OFFSET(par_balance0), AV_OPT_TYPE_DOUBLE, {.dbl=-1.0}, -1, 1, A }, + { "left_gain", "set left gain", OFFSET(par_gain0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.015625, 64, A }, + { "left_phase", "set left phase", OFFSET(par_phase0), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, A }, + { "right_delay", "set right delay", OFFSET(par_delay1), AV_OPT_TYPE_DOUBLE, {.dbl=2.12}, 0, MAX_HAAS_DELAY, A }, + { "right_balance", "set right balance", OFFSET(par_balance1), AV_OPT_TYPE_DOUBLE, {.dbl=1}, -1, 1, A }, + { "right_gain", "set right gain", OFFSET(par_gain1), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.015625, 64, A }, + { "right_phase", "set right phase", OFFSET(par_phase1), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, A }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(haas); + +static int query_formats(AVFilterContext *ctx) +{ + AVFilterFormats *formats = NULL; + AVFilterChannelLayouts *layout = NULL; + int ret; + + if ((ret = ff_add_format (&formats, AV_SAMPLE_FMT_DBL )) < 0 || + (ret = ff_set_common_formats (ctx , formats )) < 0 || + (ret = ff_add_channel_layout (&layout , AV_CH_LAYOUT_STEREO)) < 0 || + (ret = ff_set_common_channel_layouts (ctx , layout )) < 0) + return ret; + + formats = ff_all_samplerates(); + return ff_set_common_samplerates(ctx, formats); +} + +static int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + HaasContext *s = ctx->priv; + size_t min_buf_size = (size_t)(inlink->sample_rate * MAX_HAAS_DELAY * 0.001); + size_t new_buf_size = 1; + + while (new_buf_size < min_buf_size) + new_buf_size <<= 1; + + av_freep(&s->buffer); + s->buffer = av_calloc(new_buf_size, sizeof(*s->buffer)); + if (!s->buffer) + return AVERROR(ENOMEM); + + s->buffer_size = new_buf_size; + s->write_ptr = 0; + + s->delay[0] = (uint32_t)(s->par_delay0 * 0.001 * inlink->sample_rate); + s->delay[1] = (uint32_t)(s->par_delay1 * 0.001 * inlink->sample_rate); + + s->phase0 = s->par_phase0 ? 1.0 : -1.0; + s->phase1 = s->par_phase1 ? 1.0 : -1.0; + + s->balance_l[0] = (s->par_balance0 + 1) / 2 * s->par_gain0 * s->phase0; + s->balance_r[0] = (1.0 - (s->par_balance0 + 1) / 2) * (s->par_gain0) * s->phase0; + s->balance_l[1] = (s->par_balance1 + 1) / 2 * s->par_gain1 * s->phase1; + s->balance_r[1] = (1.0 - (s->par_balance1 + 1) / 2) * (s->par_gain1) * s->phase1; + + return 0; +} + +static int filter_frame(AVFilterLink *inlink, AVFrame *in) +{ + AVFilterContext *ctx = inlink->dst; + AVFilterLink *outlink = ctx->outputs[0]; + HaasContext *s = ctx->priv; + const double *src = (const double *)in->data[0]; + const double level_in = s->level_in; + const double level_out = s->level_out; + const uint32_t mask = s->buffer_size - 1; + double *buffer = s->buffer; + AVFrame *out; + double *dst; + int n; + + if (av_frame_is_writable(in)) { + out = in; + } else { + out = ff_get_audio_buffer(inlink, in->nb_samples); + if (!out) { + av_frame_free(&in); + return AVERROR(ENOMEM); + } + av_frame_copy_props(out, in); + } + dst = (double *)out->data[0]; + + for (n = 0; n < in->nb_samples; n++, src += 2, dst += 2) { + double mid, side[2], side_l, side_r; + uint32_t s0_ptr, s1_ptr; + + switch (s->par_m_source) { + case 0: mid = src[0]; break; + case 1: mid = src[1]; break; + case 2: mid = (src[0] + src[1]) * 0.5; break; + case 3: mid = (src[0] - src[1]) * 0.5; break; + } + + mid *= level_in; + + buffer[s->write_ptr] = mid; + + s0_ptr = (s->write_ptr + s->buffer_size - s->delay[0]) & mask; + s1_ptr = (s->write_ptr + s->buffer_size - s->delay[1]) & mask; + + if (s->par_middle_phase) + mid = -mid; + + side[0] = buffer[s0_ptr] * s->par_side_gain; + side[1] = buffer[s1_ptr] * s->par_side_gain; + side_l = side[0] * s->balance_l[0] - side[1] * s->balance_l[1]; + side_r = side[1] * s->balance_r[1] - side[0] * s->balance_r[0]; + + dst[0] = (mid + side_l) * level_out; + dst[1] = (mid + side_r) * level_out; + + s->write_ptr = (s->write_ptr + 1) & mask; + } + + if (out != in) + av_frame_free(&in); + return ff_filter_frame(outlink, out); +} + +static av_cold void uninit(AVFilterContext *ctx) +{ + HaasContext *s = ctx->priv; + + av_freep(&s->buffer); + s->buffer_size = 0; +} + +static const AVFilterPad inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_AUDIO, + .filter_frame = filter_frame, + .config_props = config_input, + }, + { NULL } +}; + +static const AVFilterPad outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_AUDIO, + }, + { NULL } +}; + +AVFilter ff_af_haas = { + .name = "haas", + .description = NULL_IF_CONFIG_SMALL("Apply Haas Stereo Enhancer."), + .query_formats = query_formats, + .priv_size = sizeof(HaasContext), + .priv_class = &haas_class, + .uninit = uninit, + .inputs = inputs, + .outputs = outputs, +}; diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 9a2cfea14874d..9bbc6d6fdcb01 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -104,6 +104,7 @@ static void register_all(void) REGISTER_FILTER(EXTRASTEREO, extrastereo, af); REGISTER_FILTER(FIREQUALIZER, firequalizer, af); REGISTER_FILTER(FLANGER, flanger, af); + REGISTER_FILTER(HAAS, haas, af); REGISTER_FILTER(HDCD, hdcd, af); REGISTER_FILTER(HEADPHONE, headphone, af); REGISTER_FILTER(HIGHPASS, highpass, af); diff --git a/libavfilter/version.h b/libavfilter/version.h index 6d14cff1fbb67..38c56d876eb5c 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 6 -#define LIBAVFILTER_VERSION_MINOR 103 +#define LIBAVFILTER_VERSION_MINOR 104 #define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ From e0d56f097f42bcdbe6c3b2f57df62a4da63f2094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Fri, 1 Sep 2017 15:11:18 +0200 Subject: [PATCH 3016/3374] checkasm: use perf API on Linux ARM* On ARM platforms, accessing the PMU registers requires special user access permissions. Since there is no other way to get accurate timers, the current implementation of timers in FFmpeg rely on these registers. Unfortunately, enabling user access to these registers on Linux is not trivial, and generally involve compiling a random and unreliable github kernel module, or patching somehow your kernel. Such module is very unlikely to reach the upstream anytime soon. Quoting Robin Murphin from ARM: > Say you do give userspace direct access to the PMU; now run two or more > programs at once that believe they can use the counters for their own > "minimal-overhead" profiling. Have fun interpreting those results... > > And that's not even getting into the implications of scheduling across > different CPUs, CPUidle, etc. where the PMU state is completely beyond > userspace's control. In general, the plan to provide userspace with > something which might happen to just about work in a few corner cases, > but is meaningless, misleading or downright broken in all others, is to > never do so. As a result, the alternative is to use the Performance Monitoring Linux API which makes use of these registers internally (assuming the PMU of your ARM board is supported in the kernel, which is definitely not a given...). While the Linux API is obviously cross platform, it does have a significant overhead which needs to be taken into account. As a result, that mode is only weakly enabled on ARM platforms exclusively. Note on the non flexibility of the implementation: the timers (native FFmpeg vs Linux API) are selected at compilation time to prevent the need of function calls, which would result in a negative impact on the cycle counters. --- configure | 3 ++ tests/checkasm/checkasm.c | 107 +++++++++++++++++++++++++++++++------- tests/checkasm/checkasm.h | 47 +++++++++++++++-- 3 files changed, 132 insertions(+), 25 deletions(-) diff --git a/configure b/configure index 2f3fa2ba3de15..a2aad677c8bea 100755 --- a/configure +++ b/configure @@ -448,6 +448,7 @@ Developer options (useful when working on FFmpeg itself): --libfuzzer=PATH path to libfuzzer --ignore-tests=TESTS comma-separated list (without "fate-" prefix in the name) of tests whose result is ignored + --enable-linux-perf enable Linux Performance Monitor API NOTE: Object files are built at the place where configure is launched. EOF @@ -1699,6 +1700,7 @@ CONFIG_LIST=" $SUBSYSTEM_LIST autodetect fontconfig + linux_perf memory_poisoning neon_clobber_test ossfuzz @@ -5015,6 +5017,7 @@ case $target_os in linux) enable dv1394 enable section_data_rel_ro + enabled_any arm aarch64 && enable_weak linux_perf ;; irix*) target_os=irix diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c index 9173ed19d98fa..ba729ac1bf4ae 100644 --- a/tests/checkasm/checkasm.c +++ b/tests/checkasm/checkasm.c @@ -20,6 +20,14 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include "config.h" + +#if CONFIG_LINUX_PERF +# ifndef _GNU_SOURCE +# define _GNU_SOURCE // for syscall (performance monitoring API) +# endif +#endif + #include #include #include @@ -190,8 +198,7 @@ typedef struct CheckasmFuncVersion { void *func; int ok; int cpu; - int iterations; - uint64_t cycles; + CheckasmPerf perf; } CheckasmFuncVersion; /* Binary search tree node */ @@ -212,7 +219,11 @@ static struct { int bench_pattern_len; int num_checked; int num_failed; + + /* perf */ int nop_time; + int sysfd; + int cpu_flag; const char *cpu_flag_name; const char *test_name; @@ -396,7 +407,6 @@ static const char *cpu_suffix(int cpu) return "c"; } -#ifdef AV_READ_TIME static int cmp_nop(const void *a, const void *b) { return *(const uint16_t*)a - *(const uint16_t*)b; @@ -407,10 +417,13 @@ static int measure_nop_time(void) { uint16_t nops[10000]; int i, nop_sum = 0; + av_unused const int sysfd = state.sysfd; + uint64_t t = 0; for (i = 0; i < 10000; i++) { - uint64_t t = AV_READ_TIME(); - nops[i] = AV_READ_TIME() - t; + PERF_START(t); + PERF_STOP(t); + nops[i] = t; } qsort(nops, 10000, sizeof(uint16_t), cmp_nop); @@ -430,8 +443,9 @@ static void print_benchs(CheckasmFunc *f) if (f->versions.cpu || f->versions.next) { CheckasmFuncVersion *v = &f->versions; do { - if (v->iterations) { - int decicycles = (10*v->cycles/v->iterations - state.nop_time) / 4; + CheckasmPerf *p = &v->perf; + if (p->iterations) { + int decicycles = (10*p->cycles/p->iterations - state.nop_time) / 4; printf("%s_%s: %d.%d\n", f->name, cpu_suffix(v->cpu), decicycles/10, decicycles%10); } } while ((v = v->next)); @@ -440,7 +454,6 @@ static void print_benchs(CheckasmFunc *f) print_benchs(f->child[1]); } } -#endif /* ASCIIbetical sort except preserving natural order for numbers */ static int cmp_func_names(const char *a, const char *b) @@ -543,6 +556,63 @@ static void print_cpu_name(void) } } +#if CONFIG_LINUX_PERF +static int bench_init_linux(void) +{ + struct perf_event_attr attr = { + .type = PERF_TYPE_HARDWARE, + .size = sizeof(struct perf_event_attr), + .config = PERF_COUNT_HW_CPU_CYCLES, + .disabled = 1, // start counting only on demand + .exclude_kernel = 1, + .exclude_hv = 1, + }; + + printf("benchmarking with Linux Perf Monitoring API\n"); + + state.sysfd = syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0); + if (state.sysfd == -1) { + perror("syscall"); + return -1; + } + return 0; +} +#endif + +static int bench_init_ffmpeg(void) +{ +#ifdef AV_READ_TIME + printf("benchmarking with native FFmpeg timers\n"); + return 0; +#else + fprintf(stderr, "checkasm: --bench is not supported on your system\n"); + return -1; +#endif +} + +static int bench_init(void) +{ +#if CONFIG_LINUX_PERF + int ret = bench_init_linux(); +#else + int ret = bench_init_ffmpeg(); +#endif + if (ret < 0) + return ret; + + state.nop_time = measure_nop_time(); + printf("nop: %d.%d\n", state.nop_time/10, state.nop_time%10); + return 0; +} + +static void bench_uninit(void) +{ +#if CONFIG_LINUX_PERF + if (state.sysfd > 0) + close(state.sysfd); +#endif +} + int main(int argc, char *argv[]) { unsigned int seed = av_get_random_seed(); @@ -560,10 +630,8 @@ int main(int argc, char *argv[]) while (argc > 1) { if (!strncmp(argv[1], "--bench", 7)) { -#ifndef AV_READ_TIME - fprintf(stderr, "checkasm: --bench is not supported on your system\n"); - return 1; -#endif + if (bench_init() < 0) + return 1; if (argv[1][7] == '=') { state.bench_pattern = argv[1] + 8; state.bench_pattern_len = strlen(state.bench_pattern); @@ -591,16 +659,13 @@ int main(int argc, char *argv[]) ret = 1; } else { fprintf(stderr, "checkasm: all %d tests passed\n", state.num_checked); -#ifdef AV_READ_TIME if (state.bench_pattern) { - state.nop_time = measure_nop_time(); - printf("nop: %d.%d\n", state.nop_time/10, state.nop_time%10); print_benchs(state.funcs); } -#endif } destroy_func_tree(state.funcs); + bench_uninit(); return ret; } @@ -678,11 +743,13 @@ void checkasm_fail_func(const char *msg, ...) } } -/* Update benchmark results of the current function */ -void checkasm_update_bench(int iterations, uint64_t cycles) +/* Get the benchmark context of the current function */ +CheckasmPerf *checkasm_get_perf_context(void) { - state.current_func_ver->iterations += iterations; - state.current_func_ver->cycles += cycles; + CheckasmPerf *perf = &state.current_func_ver->perf; + memset(perf, 0, sizeof(*perf)); + perf->sysfd = state.sysfd; + return perf; } /* Print the outcome of all tests performed since the last time this function was called */ diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h index 3165b21086c61..b29a61331e4f0 100644 --- a/tests/checkasm/checkasm.h +++ b/tests/checkasm/checkasm.h @@ -25,6 +25,14 @@ #include #include "config.h" + +#if CONFIG_LINUX_PERF +#include // read(3) +#include +#include +#include +#endif + #include "libavutil/avstring.h" #include "libavutil/cpu.h" #include "libavutil/internal.h" @@ -58,10 +66,12 @@ void checkasm_check_vp8dsp(void); void checkasm_check_vp9dsp(void); void checkasm_check_videodsp(void); +struct CheckasmPerf; + void *checkasm_check_func(void *func, const char *name, ...) av_printf_format(2, 3); int checkasm_bench_func(void); void checkasm_fail_func(const char *msg, ...) av_printf_format(1, 2); -void checkasm_update_bench(int iterations, uint64_t cycles); +struct CheckasmPerf *checkasm_get_perf_context(void); void checkasm_report(const char *name, ...) av_printf_format(1, 2); /* float compare utilities */ @@ -178,32 +188,59 @@ void checkasm_checked_call(void *func, ...); #define declare_new_float(ret, ...) declare_new(ret, __VA_ARGS__) #endif +typedef struct CheckasmPerf { + int sysfd; + uint64_t cycles; + int iterations; +} CheckasmPerf; + +#if defined(AV_READ_TIME) || CONFIG_LINUX_PERF + +#if CONFIG_LINUX_PERF +#define PERF_START(t) do { \ + ioctl(sysfd, PERF_EVENT_IOC_RESET, 0); \ + ioctl(sysfd, PERF_EVENT_IOC_ENABLE, 0); \ +} while (0) +#define PERF_STOP(t) do { \ + ioctl(sysfd, PERF_EVENT_IOC_DISABLE, 0); \ + read(sysfd, &t, sizeof(t)); \ +} while (0) +#else +#define PERF_START(t) t = AV_READ_TIME() +#define PERF_STOP(t) t = AV_READ_TIME() - t +#endif + /* Benchmark the function */ -#ifdef AV_READ_TIME #define bench_new(...)\ do {\ if (checkasm_bench_func()) {\ + struct CheckasmPerf *perf = checkasm_get_perf_context();\ + av_unused const int sysfd = perf->sysfd;\ func_type *tfunc = func_new;\ uint64_t tsum = 0;\ int ti, tcount = 0;\ + uint64_t t = 0; \ for (ti = 0; ti < BENCH_RUNS; ti++) {\ - uint64_t t = AV_READ_TIME();\ + PERF_START(t);\ tfunc(__VA_ARGS__);\ tfunc(__VA_ARGS__);\ tfunc(__VA_ARGS__);\ tfunc(__VA_ARGS__);\ - t = AV_READ_TIME() - t;\ + PERF_STOP(t);\ if (t*tcount <= tsum*4 && ti > 0) {\ tsum += t;\ tcount++;\ }\ }\ emms_c();\ - checkasm_update_bench(tcount, tsum);\ + perf->cycles += t;\ + perf->iterations++;\ }\ } while (0) #else #define bench_new(...) while(0) +#define PERF_START(t) while(0) +#define PERF_STOP(t) while(0) #endif #endif /* TESTS_CHECKASM_CHECKASM_H */ From 9c0d823a7c2c29560f298a007289b9a63d0e3b87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sat, 2 Sep 2017 19:17:45 +0200 Subject: [PATCH 3017/3374] lavu/timer.h: factor out timer report This commit is meant to reduce the diff in the following one. --- libavutil/timer.h | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/libavutil/timer.h b/libavutil/timer.h index ed3b04787087a..da0761b607c24 100644 --- a/libavutil/timer.h +++ b/libavutil/timer.h @@ -60,23 +60,17 @@ # define FF_TIMER_UNITS "UNITS" #endif -#ifdef AV_READ_TIME -#define START_TIMER \ - uint64_t tend; \ - uint64_t tstart = AV_READ_TIME(); \ - -#define STOP_TIMER(id) \ - tend = AV_READ_TIME(); \ +#define TIMER_REPORT(id, tdiff) \ { \ static uint64_t tsum = 0; \ static int tcount = 0; \ static int tskip_count = 0; \ static int thistogram[32] = {0}; \ - thistogram[av_log2(tend - tstart)]++; \ - if (tcount < 2 || \ - tend - tstart < 8 * tsum / tcount || \ - tend - tstart < 2000) { \ - tsum+= tend - tstart; \ + thistogram[av_log2(tdiff)]++; \ + if (tcount < 2 || \ + (tdiff) < 8 * tsum / tcount || \ + (tdiff) < 2000) { \ + tsum += (tdiff); \ tcount++; \ } else \ tskip_count++; \ @@ -90,6 +84,15 @@ av_log(NULL, AV_LOG_ERROR, "\n"); \ } \ } + +#ifdef AV_READ_TIME +#define START_TIMER \ + uint64_t tend; \ + uint64_t tstart = AV_READ_TIME(); \ + +#define STOP_TIMER(id) \ + tend = AV_READ_TIME(); \ + TIMER_REPORT(id, tend - tstart) #else #define START_TIMER #define STOP_TIMER(id) { } From dc27df47ff99fb29ed36711a62efb78ee28dba97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Thu, 7 Sep 2017 15:56:56 +0200 Subject: [PATCH 3018/3374] lavu/tests/des: rename crypt to crypt_ref This will prevent a symbol clash with crypt(3) after unistd.h is included. --- libavutil/tests/des.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavutil/tests/des.c b/libavutil/tests/des.c index 309be294732c7..eac33d47d4b99 100644 --- a/libavutil/tests/des.c +++ b/libavutil/tests/des.c @@ -34,7 +34,7 @@ static uint64_t rand64(void) static const uint8_t test_key[] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 }; static const DECLARE_ALIGNED(8, uint8_t, plain)[] = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }; -static const DECLARE_ALIGNED(8, uint8_t, crypt)[] = { 0x4a, 0xb6, 0x5b, 0x3d, 0x4b, 0x06, 0x15, 0x18 }; +static const DECLARE_ALIGNED(8, uint8_t, crypt_ref)[] = { 0x4a, 0xb6, 0x5b, 0x3d, 0x4b, 0x06, 0x15, 0x18 }; static DECLARE_ALIGNED(8, uint8_t, tmp)[8]; static DECLARE_ALIGNED(8, uint8_t, large_buffer)[10002][8]; static const uint8_t cbc_key[] = { @@ -82,13 +82,13 @@ int main(void) key[0].word = AV_RB64(test_key); data.word = AV_RB64(plain); gen_roundkeys(roundkeys, key[0].word); - if (des_encdec(data.word, roundkeys, 0) != AV_RB64(crypt)) { + if (des_encdec(data.word, roundkeys, 0) != AV_RB64(crypt_ref)) { printf("Test 1 failed\n"); return 1; } av_des_init(&d, test_key, 64, 0); av_des_crypt(&d, tmp, plain, 1, NULL, 0); - if (memcmp(tmp, crypt, sizeof(crypt))) { + if (memcmp(tmp, crypt_ref, sizeof(crypt_ref))) { printf("Public API decryption failed\n"); return 1; } From e0b9b3e60ea3b970c5fcdbccb401cd9d93b9a63f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Thu, 7 Sep 2017 15:52:47 +0200 Subject: [PATCH 3019/3374] lavu/tests: move timer.h include earlier In the next commit, timer.h will require a _GNU_SOURCE to be set before including system headers. This commit prevents compilation failures. --- libavutil/tests/adler32.c | 4 +++- libavutil/tests/aes.c | 3 +++ libavutil/tests/base64.c | 4 +++- libavutil/tests/des.c | 2 ++ libavutil/tests/eval.c | 3 ++- libavutil/tests/softfloat.c | 2 ++ 6 files changed, 15 insertions(+), 3 deletions(-) diff --git a/libavutil/tests/adler32.c b/libavutil/tests/adler32.c index 511bf1e401cb3..13f760b4775a6 100644 --- a/libavutil/tests/adler32.c +++ b/libavutil/tests/adler32.c @@ -17,10 +17,12 @@ */ // LCOV_EXCL_START + +#include "libavutil/timer.h" + #include #include "libavutil/log.h" -#include "libavutil/timer.h" #include "libavutil/adler32.h" #define LEN 7001 diff --git a/libavutil/tests/aes.c b/libavutil/tests/aes.c index 1291ad66336e2..c7f842c1c76d9 100644 --- a/libavutil/tests/aes.c +++ b/libavutil/tests/aes.c @@ -17,6 +17,9 @@ */ // LCOV_EXCL_START + +#include "libavutil/timer.h" + #include #include "libavutil/aes.h" diff --git a/libavutil/tests/base64.c b/libavutil/tests/base64.c index 88fd55c2203fc..400e01cefe417 100644 --- a/libavutil/tests/base64.c +++ b/libavutil/tests/base64.c @@ -17,12 +17,14 @@ */ // LCOV_EXCL_START + +#include "libavutil/timer.h" + #include #include #include "libavutil/common.h" #include "libavutil/base64.h" -#include "libavutil/timer.h" #define MAX_DATA_SIZE 1024 #define MAX_ENCODED_SIZE 2048 diff --git a/libavutil/tests/des.c b/libavutil/tests/des.c index eac33d47d4b99..f2a5c34f1abe6 100644 --- a/libavutil/tests/des.c +++ b/libavutil/tests/des.c @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/timer.h" + #include "libavutil/des.c" #include diff --git a/libavutil/tests/eval.c b/libavutil/tests/eval.c index 2a1afcc4dc43c..b64c6d635dd19 100644 --- a/libavutil/tests/eval.c +++ b/libavutil/tests/eval.c @@ -16,12 +16,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/timer.h" + #include #include #include #include "libavutil/libm.h" -#include "libavutil/timer.h" #include "libavutil/eval.h" static const double const_values[] = { diff --git a/libavutil/tests/softfloat.c b/libavutil/tests/softfloat.c index 16788d4da974d..c06de449334c1 100644 --- a/libavutil/tests/softfloat.c +++ b/libavutil/tests/softfloat.c @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/timer.h" + #include #include "libavutil/softfloat.h" From f61379cbd45a91b26c7a1ddd3f16417466c435cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sat, 2 Sep 2017 19:25:10 +0200 Subject: [PATCH 3020/3374] lavu/timer.h: add Linux Perf API support Refer to "checkasm: use perf API on Linux ARM*" commit for the rationale. The implementation is somehow duplicated with checkasm, but so is the current usage of AV_READ_TIME(). Until these implementations and heuristics are made consistent, I don't see a way of sharing that code. Note: when using libavutil/timer.h, it is now important to include before any other include due to the _GNU_SOURCE requirement. --- libavutil/timer.h | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/libavutil/timer.h b/libavutil/timer.h index da0761b607c24..f7ab455df22fe 100644 --- a/libavutil/timer.h +++ b/libavutil/timer.h @@ -26,12 +26,22 @@ #ifndef AVUTIL_TIMER_H #define AVUTIL_TIMER_H +#include "config.h" + +#if CONFIG_LINUX_PERF +# ifndef _GNU_SOURCE +# define _GNU_SOURCE +# endif +# include // read(3) +# include +# include +# include +#endif + #include #include #include -#include "config.h" - #if HAVE_MACH_MACH_TIME_H #include #endif @@ -85,7 +95,37 @@ } \ } -#ifdef AV_READ_TIME +#if CONFIG_LINUX_PERF + +#define START_TIMER \ + static int linux_perf_fd; \ + uint64_t tperf; \ + if (!linux_perf_fd) { \ + struct perf_event_attr attr = { \ + .type = PERF_TYPE_HARDWARE, \ + .size = sizeof(struct perf_event_attr), \ + .config = PERF_COUNT_HW_CPU_CYCLES, \ + .disabled = 1, \ + .exclude_kernel = 1, \ + .exclude_hv = 1, \ + }; \ + linux_perf_fd = syscall(__NR_perf_event_open, &attr, \ + 0, -1, -1, 0); \ + } \ + if (linux_perf_fd == -1) { \ + av_log(NULL, AV_LOG_ERROR, "perf_event_open failed: %s\n", \ + av_err2str(AVERROR(errno))); \ + } else { \ + ioctl(linux_perf_fd, PERF_EVENT_IOC_RESET, 0); \ + ioctl(linux_perf_fd, PERF_EVENT_IOC_ENABLE, 0); \ + } + +#define STOP_TIMER(id) \ + ioctl(linux_perf_fd, PERF_EVENT_IOC_DISABLE, 0); \ + read(linux_perf_fd, &tperf, sizeof(tperf)); \ + TIMER_REPORT(id, tperf) + +#elif defined(AV_READ_TIME) #define START_TIMER \ uint64_t tend; \ uint64_t tstart = AV_READ_TIME(); \ From b476e7720c067d75cd72190db7d36e72c3ff6abb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Tue, 5 Sep 2017 18:06:29 +0200 Subject: [PATCH 3021/3374] build: fix objcc header check $headers is a variable set in the context of other functions (we don't use the "local" keyword in our scripts, so those variables are global). Currently, when checking for AVFoundation/AVFoundation.h, the actual enabled header is math.h. Similarly, when testing for QuartzCore/CoreImage.h, the actual enabled header is CoreGraphics/CoreGraphics.h. This is completely broken and may be the reason why these checks are made in random places. --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index a2aad677c8bea..334b597a8bf21 100755 --- a/configure +++ b/configure @@ -1118,7 +1118,7 @@ check_header_objcc(){ { echo "#include <$header>" echo "int main(void) { return 0; }" - } | check_objcc && check_stat "$TMPO" && enable_safe $headers + } | check_objcc && check_stat "$TMPO" && enable_safe $header } check_func(){ From f8519529cfed6453bc7cc7634660021d539049a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Tue, 5 Sep 2017 18:09:37 +0200 Subject: [PATCH 3022/3374] lavfi/coreimage: reduce dependency scope from QuartzCore to CoreImage What is required by the filter is CoreImage, there is no QuartzCore usage. QuartzCore/CoreImage.h is simply an include to CoreImage/CoreImage.h. --- configure | 8 ++++---- libavfilter/vf_coreimage.m | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/configure b/configure index 334b597a8bf21..996cb9f3092ca 100755 --- a/configure +++ b/configure @@ -5591,8 +5591,8 @@ frei0r_filter_extralibs='$ldl' frei0r_src_filter_extralibs='$ldl' ladspa_filter_extralibs='$ldl' nvenc_extralibs='$ldl' -coreimage_filter_extralibs="-framework QuartzCore -framework AppKit -framework OpenGL" -coreimagesrc_filter_extralibs="-framework QuartzCore -framework AppKit -framework OpenGL" +coreimage_filter_extralibs="-framework CoreImage -framework AppKit -framework OpenGL" +coreimagesrc_filter_extralibs="-framework CoreImage -framework AppKit -framework OpenGL" if ! disabled network; then check_func getaddrinfo $network_extralibs @@ -5840,8 +5840,8 @@ enabled cuda_sdk && require cuda_sdk cuda.h cuCtxCreate -lcuda enabled cuvid && { enabled cuda || die "ERROR: CUVID requires CUDA"; } enabled chromaprint && require chromaprint chromaprint.h chromaprint_get_version -lchromaprint -enabled coreimage_filter && { check_header_objcc QuartzCore/CoreImage.h || disable coreimage_filter; } -enabled coreimagesrc_filter && { check_header_objcc QuartzCore/CoreImage.h || disable coreimagesrc_filter; } +enabled coreimage_filter && { check_header_objcc CoreImage/CoreImage.h || disable coreimage_filter; } +enabled coreimagesrc_filter && { check_header_objcc CoreImage/CoreImage.h || disable coreimagesrc_filter; } enabled decklink && { { check_header DeckLinkAPI.h || die "ERROR: DeckLinkAPI.h header not found"; } && { check_cpp_condition DeckLinkAPIVersion.h "BLACKMAGIC_DECKLINK_API_VERSION >= 0x0a060100" || die "ERROR: Decklink API version must be >= 10.6.1."; } } enabled libndi_newtek && { check_header Processing.NDI.Lib.h || die "ERROR: Processing.NDI.Lib.h header not found"; } diff --git a/libavfilter/vf_coreimage.m b/libavfilter/vf_coreimage.m index 9c8db02858263..323a28caa1d0f 100644 --- a/libavfilter/vf_coreimage.m +++ b/libavfilter/vf_coreimage.m @@ -23,7 +23,7 @@ * Video processing based on Apple's CoreImage API */ -#import +#import #import #include "avfilter.h" From b6dce64a8ea5e98ce09916a056a7ac51316c9bce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 6 Sep 2017 11:29:23 +0200 Subject: [PATCH 3023/3374] build: add check_apple_framework() This will be used in the following commits. --- configure | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/configure b/configure index 996cb9f3092ca..8d4ab439332bd 100755 --- a/configure +++ b/configure @@ -1121,6 +1121,15 @@ check_header_objcc(){ } | check_objcc && check_stat "$TMPO" && enable_safe $header } +check_apple_framework(){ + log check_apple_framework "$@" + framework="$1" + name="$(tolower $framework)" + header="${framework}/${framework}.h" + disable $name + check_header_objcc $header && enable $name && add_extralibs "-framework $framework" +} + check_func(){ log check_func "$@" func=$1 From 97d8013582f5b6a34d742ff9d5aea4012863ab39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 6 Sep 2017 11:31:40 +0200 Subject: [PATCH 3024/3374] build: add --disable-avfoundation autodetect switch --- configure | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/configure b/configure index 8d4ab439332bd..b7534d2f00dc6 100755 --- a/configure +++ b/configure @@ -202,6 +202,7 @@ External library support: themselves, not all their features will necessarily be usable by FFmpeg. --disable-alsa disable ALSA support [autodetect] + --disable-avfoundation disable Apple AVFoundation framework [autodetect] --enable-avisynth enable reading of AviSynth script files [no] --disable-bzlib disable bzlib [autodetect] --enable-chromaprint enable audio fingerprinting with chromaprint [no] @@ -1499,6 +1500,7 @@ EXAMPLE_LIST=" EXTERNAL_AUTODETECT_LIBRARY_LIST=" alsa + avfoundation bzlib iconv jack @@ -3025,8 +3027,8 @@ xwma_demuxer_select="riffdec" # indevs / outdevs alsa_indev_deps="alsa" alsa_outdev_deps="alsa" -avfoundation_indev_deps="pthreads" -avfoundation_indev_extralibs="-framework Foundation -framework AVFoundation -framework CoreVideo -framework CoreMedia" +avfoundation_indev_deps="avfoundation pthreads" +avfoundation_indev_extralibs="-framework Foundation -framework CoreVideo -framework CoreMedia" bktr_indev_deps_any="dev_bktr_ioctl_bt848_h machine_ioctl_bt848_h dev_video_bktr_ioctl_bt848_h dev_ic_bt8xx_h" caca_outdev_deps="libcaca" decklink_indev_deps="decklink threads" @@ -5758,6 +5760,13 @@ check_lib psapi "windows.h psapi.h" GetProcessMemoryInfo -lpsapi check_lib coreservices "CoreServices/CoreServices.h" UTGetOSTypeFromString "-framework CoreServices" +enabled avfoundation && check_apple_framework AVFoundation + +enabled avfoundation && { + check_lib avfoundation CoreGraphics/CoreGraphics.h CGGetActiveDisplayList "-framework CoreGraphics" || + check_lib avfoundation ApplicationServices/ApplicationServices.h CGGetActiveDisplayList "-framework ApplicationServices"; } + + check_struct "sys/time.h sys/resource.h" "struct rusage" ru_maxrss check_type "windows.h dxva.h" "DXVA_PicParams_HEVC" -DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP -D_CRT_BUILD_DESKTOP_APP=0 @@ -5842,9 +5851,6 @@ for func in $COMPLEX_FUNCS; do done # these are off by default, so fail if requested and not available -enabled avfoundation_indev && { check_header_objcc AVFoundation/AVFoundation.h || disable avfoundation_indev; } -enabled avfoundation_indev && { check_lib avfoundation_indev CoreGraphics/CoreGraphics.h CGGetActiveDisplayList -framework CoreGraphics || - check_lib avfoundation_indev ApplicationServices/ApplicationServices.h CGGetActiveDisplayList -framework ApplicationServices; } enabled cuda_sdk && require cuda_sdk cuda.h cuCtxCreate -lcuda enabled cuvid && { enabled cuda || die "ERROR: CUVID requires CUDA"; } From 496d0178b0ed4bbb8551ffab68d7c84e230b4ba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 6 Sep 2017 11:33:20 +0200 Subject: [PATCH 3025/3374] build: add --disable-coreimage autodetect switch --- configure | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/configure b/configure index b7534d2f00dc6..cd2c3be301468 100755 --- a/configure +++ b/configure @@ -205,6 +205,7 @@ External library support: --disable-avfoundation disable Apple AVFoundation framework [autodetect] --enable-avisynth enable reading of AviSynth script files [no] --disable-bzlib disable bzlib [autodetect] + --disable-coreimage disable Apple CoreImage framework [autodetect] --enable-chromaprint enable audio fingerprinting with chromaprint [no] --enable-frei0r enable frei0r video filtering [no] --enable-gcrypt enable gcrypt, needed for rtmp(t)e support @@ -1502,6 +1503,7 @@ EXTERNAL_AUTODETECT_LIBRARY_LIST=" alsa avfoundation bzlib + coreimage iconv jack libxcb @@ -3136,6 +3138,10 @@ blackframe_filter_deps="gpl" boxblur_filter_deps="gpl" bs2b_filter_deps="libbs2b" colormatrix_filter_deps="gpl" +coreimage_filter_deps="coreimage" +coreimage_filter_extralibs="-framework OpenGL -framework AppKit" +coreimagesrc_filter_deps="coreimage" +coreimagesrc_filter_extralibs="-framework OpenGL -framework AppKit" cover_rect_filter_deps="avcodec avformat gpl" cropdetect_filter_deps="gpl" deinterlace_qsv_filter_deps="libmfx" @@ -5602,8 +5608,6 @@ frei0r_filter_extralibs='$ldl' frei0r_src_filter_extralibs='$ldl' ladspa_filter_extralibs='$ldl' nvenc_extralibs='$ldl' -coreimage_filter_extralibs="-framework CoreImage -framework AppKit -framework OpenGL" -coreimagesrc_filter_extralibs="-framework CoreImage -framework AppKit -framework OpenGL" if ! disabled network; then check_func getaddrinfo $network_extralibs @@ -5761,6 +5765,7 @@ check_lib psapi "windows.h psapi.h" GetProcessMemoryInfo -lpsapi check_lib coreservices "CoreServices/CoreServices.h" UTGetOSTypeFromString "-framework CoreServices" enabled avfoundation && check_apple_framework AVFoundation +enabled coreimage && check_apple_framework CoreImage enabled avfoundation && { check_lib avfoundation CoreGraphics/CoreGraphics.h CGGetActiveDisplayList "-framework CoreGraphics" || @@ -5855,8 +5860,6 @@ enabled cuda_sdk && require cuda_sdk cuda.h cuCtxCreate -lcuda enabled cuvid && { enabled cuda || die "ERROR: CUVID requires CUDA"; } enabled chromaprint && require chromaprint chromaprint.h chromaprint_get_version -lchromaprint -enabled coreimage_filter && { check_header_objcc CoreImage/CoreImage.h || disable coreimage_filter; } -enabled coreimagesrc_filter && { check_header_objcc CoreImage/CoreImage.h || disable coreimagesrc_filter; } enabled decklink && { { check_header DeckLinkAPI.h || die "ERROR: DeckLinkAPI.h header not found"; } && { check_cpp_condition DeckLinkAPIVersion.h "BLACKMAGIC_DECKLINK_API_VERSION >= 0x0a060100" || die "ERROR: Decklink API version must be >= 10.6.1."; } } enabled libndi_newtek && { check_header Processing.NDI.Lib.h || die "ERROR: Processing.NDI.Lib.h header not found"; } From 1cf23e3fddd1a804281b9ffc1b80c62151a46753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 6 Sep 2017 11:42:54 +0200 Subject: [PATCH 3026/3374] build: cleanup audiotoolbox handling *_at codecs only need the AudioToolbox framework, which is now checked like the other Apple frameworks. --- configure | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/configure b/configure index cd2c3be301468..ede51368483e4 100755 --- a/configure +++ b/configure @@ -2612,10 +2612,6 @@ zlib_encoder_select="zlib" zmbv_decoder_select="zlib" zmbv_encoder_select="zlib" -# platform codecs -audiotoolbox_deps="AudioToolbox_AudioToolbox_h" -audiotoolbox_extralibs="-framework CoreFoundation -framework AudioToolbox -framework CoreMedia" - # hardware accelerators crystalhd_deps="libcrystalhd_libcrystalhd_if_h" cuda_deps_any="dlopen LoadLibrary" @@ -5721,7 +5717,6 @@ check_func_headers glob.h glob enabled xlib && check_func_headers "X11/Xlib.h X11/extensions/Xvlib.h" XvGetPortAttribute -lXv -lX11 -lXext -check_header AudioToolbox/AudioToolbox.h check_header d3d11.h check_header direct.h check_header dirent.h @@ -5764,6 +5759,7 @@ check_lib psapi "windows.h psapi.h" GetProcessMemoryInfo -lpsapi check_lib coreservices "CoreServices/CoreServices.h" UTGetOSTypeFromString "-framework CoreServices" +enabled audiotoolbox && check_apple_framework AudioToolbox enabled avfoundation && check_apple_framework AVFoundation enabled coreimage && check_apple_framework CoreImage From 260ea7a7b395891b12eeddbd9042e0a4d3c72db9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 6 Sep 2017 11:53:48 +0200 Subject: [PATCH 3027/3374] build: cleanup videotoolbox - there is no need for kCVImageBufferColorPrimaries_ITU_R_2020 checks, it's done at runtime - VideoToolbox presence is now checked with check_apple_framework() - link to CoreServices is only done when videotoolbox is enabled --- configure | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/configure b/configure index ede51368483e4..3ac0a3cf4c050 100755 --- a/configure +++ b/configure @@ -1608,7 +1608,6 @@ EXTERNAL_LIBRARY_LIST=" openal opencl opengl - videotoolbox " HWACCEL_AUTODETECT_LIBRARY_LIST=" @@ -1622,7 +1621,7 @@ HWACCEL_AUTODETECT_LIBRARY_LIST=" vaapi vda vdpau - videotoolbox_hwaccel + videotoolbox xvmc " @@ -2180,7 +2179,6 @@ CONFIG_EXTRA=" vp3dsp vp56dsp vp8dsp - vt_bt2020 wma_freqs wmv2dsp " @@ -2938,11 +2936,9 @@ libx265_encoder_deps="libx265" libxavs_encoder_deps="libxavs" libxvid_encoder_deps="libxvid" libzvbi_teletext_decoder_deps="libzvbi" -videotoolbox_deps="VideoToolbox_VideoToolbox_h" videotoolbox_extralibs="-framework CoreFoundation -framework VideoToolbox -framework CoreMedia -framework CoreVideo" videotoolbox_encoder_deps="videotoolbox VTCompressionSessionPrepareToEncodeFrames" -videotoolbox_encoder_suggest="vda_framework vt_bt2020" -vt_bt2020_deps="kCVImageBufferColorPrimaries_ITU_R_2020" +videotoolbox_encoder_suggest="vda_framework" # demuxers / muxers ac3_demuxer_select="ac3_parser" @@ -5740,9 +5736,7 @@ check_header termios.h check_header unistd.h check_header valgrind/valgrind.h check_header VideoDecodeAcceleration/VDADecoder.h -check_header VideoToolbox/VideoToolbox.h check_func_headers VideoToolbox/VTCompressionSession.h VTCompressionSessionPrepareToEncodeFrames -framework VideoToolbox -enabled videotoolbox && check_func_headers CoreVideo/CVImageBuffer.h kCVImageBufferColorPrimaries_ITU_R_2020 -framework CoreVideo check_header windows.h check_header X11/extensions/XvMClib.h check_header asm/types.h @@ -5757,16 +5751,17 @@ check_lib shell32 "windows.h shellapi.h" CommandLineToArgvW -lshell32 check_lib wincrypt "windows.h wincrypt.h" CryptGenRandom -ladvapi32 check_lib psapi "windows.h psapi.h" GetProcessMemoryInfo -lpsapi -check_lib coreservices "CoreServices/CoreServices.h" UTGetOSTypeFromString "-framework CoreServices" - enabled audiotoolbox && check_apple_framework AudioToolbox enabled avfoundation && check_apple_framework AVFoundation enabled coreimage && check_apple_framework CoreImage +enabled videotoolbox && check_apple_framework VideoToolbox enabled avfoundation && { check_lib avfoundation CoreGraphics/CoreGraphics.h CGGetActiveDisplayList "-framework CoreGraphics" || check_lib avfoundation ApplicationServices/ApplicationServices.h CGGetActiveDisplayList "-framework ApplicationServices"; } +enabled videotoolbox && + check_lib coreservices CoreServices/CoreServices.h UTGetOSTypeFromString "-framework CoreServices" check_struct "sys/time.h sys/resource.h" "struct rusage" ru_maxrss From 27b7800ba907ff4fbb8ecacc50e19a1386f1c643 Mon Sep 17 00:00:00 2001 From: James Almer Date: Thu, 1 Jun 2017 23:47:32 -0300 Subject: [PATCH 3028/3374] avformat/matroskaenc: also write tags when output is WebM WebM supports a subset of elements from the Tags master. See https://www.webmproject.org/docs/container/#tagging Reviewed-by: Ivan Janatra Signed-off-by: James Almer --- libavformat/matroskaenc.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 9cc7be352e27b..17094f82b0c34 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -1681,17 +1681,20 @@ static int mkv_write_tags(AVFormatContext *s) } } - for (i = 0; i < s->nb_chapters; i++) { - AVChapter *ch = s->chapters[i]; + if (mkv->mode != MODE_WEBM) { + for (i = 0; i < s->nb_chapters; i++) { + AVChapter *ch = s->chapters[i]; - if (!mkv_check_tag(ch->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID)) - continue; + if (!mkv_check_tag(ch->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID)) + continue; - ret = mkv_write_tag(s, ch->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID, ch->id + mkv->chapter_id_offset, &mkv->tags); - if (ret < 0) return ret; + ret = mkv_write_tag(s, ch->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID, ch->id + mkv->chapter_id_offset, &mkv->tags); + if (ret < 0) + return ret; + } } - if (mkv->have_attachments) { + if (mkv->have_attachments && mkv->mode != MODE_WEBM) { for (i = 0; i < mkv->attachments->num_entries; i++) { mkv_attachment *attachment = &mkv->attachments->entries[i]; AVStream *st = s->streams[attachment->stream_idx]; @@ -1988,12 +1991,12 @@ static int mkv_write_header(AVFormatContext *s) ret = mkv_write_attachments(s); if (ret < 0) goto fail; - - ret = mkv_write_tags(s); - if (ret < 0) - goto fail; } + ret = mkv_write_tags(s); + if (ret < 0) + goto fail; + if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live) mkv_write_seekhead(pb, mkv); From 96d70694aea64616c68db8be306c159c73fb3980 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Sat, 9 Sep 2017 08:32:03 +0800 Subject: [PATCH 3029/3374] avformat/dashdec: add dash demuxer base version ffmpeg need a dash demuxer for demux the dash formats base on https://github.com/samsamsam-iptvplayer/exteplayer3/blob/master/tmp/ffmpeg/patches/3.2.2/000001_add_dash_demux.patch TODO: 1. support multi bitrate dash. v2 fixed: 1. from autodetect to disabled 2. from camelCase code style to ffmpeg code style 3. from RepType to AVMediaType 4. fix variable typo 5. change time value from uint32_t to uint64_t 6. removed be used once API 7. change 'time(NULL)`, except it is not 2038-safe.' to av_gettime and av_timegm 8. merge complex free operation to free_fragment 9. use API from snprintf to av_asprintf v3 fixed: 1. fix typo from --enabled-xml2 to --enable-xml2 v4 fixed: 1. from --enable-xml2 to --enable-libxml2 2. move system includes to top 3. remove nouse includes 4. rename enum name 5. add a trailing comma for the last entry enum 6. fix comment typo 7. add const to DASHContext class front 8. check sscanf if return arguments and give warning message when error 9. check validity before free seg->url and seg 10. check if the val is null, before use atoll v5 fixed: 1. fix typo from mainifest to manifest v6 fixed: 1. from realloc to av_realloc 2. from free to av_free v7 fixed: 1. remove the -lxml2 from configure when require_pkg_config v8 fixed: 1. fix replace filename template by av_asprintf secure problem v9 modified: 1. make manifest parser clearly v10 fixed: 1. fix function API name code style 2. remove redundant strreplace call 3. remove redundant memory operation and check return value from get_content_url() 4. add space between ) and { 5. remove no need to log the value for print v11 fixed: 1. from atoll to strtoll Suggested-by: Michael Niedermayer v12 fixed: 1. remove strreplace and instead by av_strreplace Suggested-by: Nicolas George v13 fixed: 1. fix bug: cannot play: http://dash.edgesuite.net/akamai/bbb_30fps/bbb_30fps.mpd Reported-by: Andy Furniss v14 fixed: 1. fix bug: TLS connection was non-properly terminated 2. fix bug: No trailing CRLF found in HTTP header Reported-by: Andy Furniss v15 fixed: 1. play youtube link: ffmpeg -i $(youtube-dl -J "https://www.youtube.com/watch?v=XmL19DOP_Ls" | jq -r ".requested_formats[0].manifest_url") 2. code refine for timeline living stream Reported-by: Ricardo Constantino v16 fixed: 1. remove the snprintf and instead by get_segment_filename make safety 2. remove unnecessary loops 3. updated xmlStrcmp and xmlFree to av_* functions 4. merge code repeat into one function 5. add memory alloc faild check 6. update update_init_section and open_url 7. output safety error message when filename template not safe Suggested-by : wm4 v17 fixed: 1. add memory alloc faild check 2. fix resource space error at free_representation v18 fixed: 1. add condition of template format v19 fixed: 1. fix typo of the option describe v20 fixed: 1. add the c->base_url alloc check 2. make the DASHTmplId same to dashenc v21 fixed: 1. remove get_repl_pattern_and_format and get_segment_filename 2. process use dashcomm APIs v22 fixed: 1. modify the include "dashcomm.h" to include "dash.h" 2. use internal API from dash_fill_tmpl_params to ff_dash_fill_tmpl_params Signed-off-by: Steven Liu Signed-off-by: samsamsam --- configure | 4 + libavformat/Makefile | 1 + libavformat/allformats.c | 2 +- libavformat/dashdec.c | 1848 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 1854 insertions(+), 1 deletion(-) create mode 100644 libavformat/dashdec.c diff --git a/configure b/configure index 3ac0a3cf4c050..4dd11efe5e72e 100755 --- a/configure +++ b/configure @@ -277,6 +277,7 @@ External library support: --enable-libxcb-shape enable X11 grabbing shape rendering [autodetect] --enable-libxvid enable Xvid encoding via xvidcore, native MPEG-4/Xvid encoder exists [no] + --enable-libxml2 enable XML parsing using the C library libxml2 [no] --enable-libzimg enable z.lib, needed for zscale filter [no] --enable-libzmq enable message passing via libzmq [no] --enable-libzvbi enable teletext support via libzvbi [no] @@ -1601,6 +1602,7 @@ EXTERNAL_LIBRARY_LIST=" libvpx libwavpack libwebp + libxml2 libzimg libzmq libzvbi @@ -2952,6 +2954,7 @@ avi_muxer_select="riffenc" caf_demuxer_select="iso_media riffdec" caf_muxer_select="iso_media" dash_muxer_select="mp4_muxer" +dash_demuxer_deps="libxml2" dirac_demuxer_select="dirac_parser" dts_demuxer_select="dca_parser" dtshd_demuxer_select="dca_parser" @@ -5990,6 +5993,7 @@ enabled libzmq && require_pkg_config libzmq zmq.h zmq_ctx_new enabled libzvbi && require libzvbi libzvbi.h vbi_decoder_new -lzvbi && { check_cpp_condition libzvbi.h "VBI_VERSION_MAJOR > 0 || VBI_VERSION_MINOR > 2 || VBI_VERSION_MINOR == 2 && VBI_VERSION_MICRO >= 28" || enabled gpl || die "ERROR: libzvbi requires version 0.2.28 or --enable-gpl."; } +enabled libxml2 && require_pkg_config libxml-2.0 libxml2/libxml/xmlversion.h xmlCheckVersion enabled mediacodec && { enabled jni || die "ERROR: mediacodec requires --enable-jni"; } enabled mmal && { check_lib mmal interface/mmal/mmal.h mmal_port_connect -lmmal_core -lmmal_util -lmmal_vc_client -lbcm_host || { ! enabled cross_compile && diff --git a/libavformat/Makefile b/libavformat/Makefile index de954af1306bc..ac03e0d47157d 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -133,6 +133,7 @@ OBJS-$(CONFIG_CRC_MUXER) += crcenc.o OBJS-$(CONFIG_DATA_DEMUXER) += rawdec.o OBJS-$(CONFIG_DATA_MUXER) += rawenc.o OBJS-$(CONFIG_DASH_MUXER) += dash.o dashenc.o +OBJS-$(CONFIG_DASH_DEMUXER) += dashdec.o OBJS-$(CONFIG_DAUD_DEMUXER) += dauddec.o OBJS-$(CONFIG_DAUD_MUXER) += daudenc.o OBJS-$(CONFIG_DCSTR_DEMUXER) += dcstr.o diff --git a/libavformat/allformats.c b/libavformat/allformats.c index cb09a60e6f42c..416e5e1127aff 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -96,7 +96,7 @@ static void register_all(void) REGISTER_DEMUXER (CINE, cine); REGISTER_DEMUXER (CONCAT, concat); REGISTER_MUXER (CRC, crc); - REGISTER_MUXER (DASH, dash); + REGISTER_MUXDEMUX(DASH, dash); REGISTER_MUXDEMUX(DATA, data); REGISTER_MUXDEMUX(DAUD, daud); REGISTER_DEMUXER (DCSTR, dcstr); diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c new file mode 100644 index 0000000000000..9a3a199d4e094 --- /dev/null +++ b/libavformat/dashdec.c @@ -0,0 +1,1848 @@ +/* + * Dynamic Adaptive Streaming over HTTP demux + * Copyright (c) 2017 samsamsam@o2.pl based on HLS demux + * Copyright (c) 2017 Steven Liu + * + * 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 +#include "libavutil/intreadwrite.h" +#include "libavutil/opt.h" +#include "libavutil/time.h" +#include "libavutil/parseutils.h" +#include "internal.h" +#include "avio_internal.h" +#include "dash.h" + +#define INITIAL_BUFFER_SIZE 32768 + +struct fragment { + int64_t url_offset; + int64_t size; + char *url; +}; + +/* + * reference to : ISO_IEC_23009-1-DASH-2012 + * Section: 5.3.9.6.2 + * Table: Table 17 — Semantics of SegmentTimeline element + * */ +struct timeline { + /* starttime: Element or Attribute Name + * specifies the MPD start time, in @timescale units, + * the first Segment in the series starts relative to the beginning of the Period. + * The value of this attribute must be equal to or greater than the sum of the previous S + * element earliest presentation time and the sum of the contiguous Segment durations. + * If the value of the attribute is greater than what is expressed by the previous S element, + * it expresses discontinuities in the timeline. + * If not present then the value shall be assumed to be zero for the first S element + * and for the subsequent S elements, the value shall be assumed to be the sum of + * the previous S element's earliest presentation time and contiguous duration + * (i.e. previous S@starttime + @duration * (@repeat + 1)). + * */ + int64_t starttime; + /* repeat: Element or Attribute Name + * specifies the repeat count of the number of following contiguous Segments with + * the same duration expressed by the value of @duration. This value is zero-based + * (e.g. a value of three means four Segments in the contiguous series). + * */ + int64_t repeat; + /* duration: Element or Attribute Name + * specifies the Segment duration, in units of the value of the @timescale. + * */ + int64_t duration; +}; + +/* + * Each playlist has its own demuxer. If it is currently active, + * it has an opened AVIOContext too, and potentially an AVPacket + * containing the next packet from this stream. + */ +struct representation { + char *url_template; + AVIOContext pb; + AVIOContext *input; + AVFormatContext *parent; + AVFormatContext *ctx; + AVPacket pkt; + int rep_idx; + int rep_count; + int stream_index; + + enum AVMediaType type; + + int n_fragments; + struct fragment **fragments; /* VOD list of fragment for profile */ + + int n_timelines; + struct timeline **timelines; + + int64_t first_seq_no; + int64_t last_seq_no; + int64_t start_number; /* used in case when we have dynamic list of segment to know which segments are new one*/ + + int64_t fragment_duration; + int64_t fragment_timescale; + + int64_t presentation_timeoffset; + + int64_t cur_seq_no; + int64_t cur_seg_offset; + int64_t cur_seg_size; + struct fragment *cur_seg; + + /* Currently active Media Initialization Section */ + struct fragment *init_section; + uint8_t *init_sec_buf; + uint32_t init_sec_buf_size; + uint32_t init_sec_data_len; + uint32_t init_sec_buf_read_offset; + int64_t cur_timestamp; + int is_restart_needed; +}; + +typedef struct DASHContext { + const AVClass *class; + char *base_url; + struct representation *cur_video; + struct representation *cur_audio; + + /* MediaPresentationDescription Attribute */ + uint64_t media_presentation_duration; + uint64_t suggested_presentation_delay; + uint64_t availability_start_time; + uint64_t publish_time; + uint64_t minimum_update_period; + uint64_t time_shift_buffer_depth; + uint64_t min_buffer_time; + + /* Period Attribute */ + uint64_t period_duration; + uint64_t period_start; + + 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; +} DASHContext; + +static uint64_t get_current_time_in_sec(void) +{ + return av_gettime() / 1000000; +} + +static uint64_t get_utc_date_time_insec(AVFormatContext *s, const char *datetime) +{ + struct tm timeinfo; + int year = 0; + int month = 0; + int day = 0; + int hour = 0; + int minute = 0; + int ret = 0; + float second = 0.0; + + /* ISO-8601 date parser */ + if (!datetime) + return 0; + + ret = sscanf(datetime, "%d-%d-%dT%d:%d:%fZ", &year, &month, &day, &hour, &minute, &second); + /* year, month, day, hour, minute, second 6 arguments */ + if (ret != 6) { + av_log(s, AV_LOG_WARNING, "get_utc_date_time_insec get a wrong time format\n"); + } + timeinfo.tm_year = year - 1900; + timeinfo.tm_mon = month - 1; + timeinfo.tm_mday = day; + timeinfo.tm_hour = hour; + timeinfo.tm_min = minute; + timeinfo.tm_sec = (int)second; + + return av_timegm(&timeinfo); +} + +static uint32_t get_duration_insec(AVFormatContext *s, const char *duration) +{ + /* ISO-8601 duration parser */ + uint32_t days = 0; + uint32_t hours = 0; + uint32_t mins = 0; + uint32_t secs = 0; + int size = 0; + float value = 0; + char type = '\0'; + const char *ptr = duration; + + while (*ptr) { + if (*ptr == 'P' || *ptr == 'T') { + ptr++; + continue; + } + + if (sscanf(ptr, "%f%c%n", &value, &type, &size) != 2) { + av_log(s, AV_LOG_WARNING, "get_duration_insec get a wrong time format\n"); + return 0; /* parser error */ + } + switch (type) { + case 'D': + days = (uint32_t)value; + break; + case 'H': + hours = (uint32_t)value; + break; + case 'M': + mins = (uint32_t)value; + break; + case 'S': + secs = (uint32_t)value; + break; + default: + // handle invalid type + break; + } + ptr += size; + } + return ((days * 24 + hours) * 60 + mins) * 60 + secs; +} + +static int64_t get_segment_start_time_based_on_timeline(struct representation *pls, int64_t cur_seq_no) +{ + int64_t start_time = 0; + int64_t i = 0; + int64_t j = 0; + int64_t num = 0; + + if (pls->n_timelines) { + for (i = 0; i < pls->n_timelines; i++) { + if (pls->timelines[i]->starttime > 0) { + start_time = pls->timelines[i]->starttime; + } + if (num == cur_seq_no) + goto finish; + + start_time += pls->timelines[i]->duration; + for (j = 0; j < pls->timelines[i]->repeat; j++) { + num++; + if (num == cur_seq_no) + goto finish; + start_time += pls->timelines[i]->duration; + } + num++; + } + } +finish: + return start_time; +} + +static int64_t calc_next_seg_no_from_timelines(struct representation *pls, int64_t cur_time) +{ + int64_t i = 0; + int64_t j = 0; + int64_t num = 0; + int64_t start_time = 0; + + for (i = 0; i < pls->n_timelines; i++) { + if (pls->timelines[i]->starttime > 0) { + start_time = pls->timelines[i]->starttime; + } + if (start_time > cur_time) + goto finish; + + start_time += pls->timelines[i]->duration; + for (j = 0; j < pls->timelines[i]->repeat; j++) { + num++; + if (start_time > cur_time) + goto finish; + start_time += pls->timelines[i]->duration; + } + num++; + } + + return -1; + +finish: + return num; +} + +static void free_fragment(struct fragment **seg) +{ + if (!(*seg)) { + return; + } + av_freep(&(*seg)->url); + av_freep(seg); +} + +static void free_fragment_list(struct representation *pls) +{ + int i; + + for (i = 0; i < pls->n_fragments; i++) { + free_fragment(&pls->fragments[i]); + } + av_freep(&pls->fragments); + pls->n_fragments = 0; +} + +static void free_timelines_list(struct representation *pls) +{ + int i; + + for (i = 0; i < pls->n_timelines; i++) { + av_freep(&pls->timelines[i]); + } + av_freep(&pls->timelines); + pls->n_timelines = 0; +} + +static void free_representation(struct representation *pls) +{ + free_fragment_list(pls); + free_timelines_list(pls); + free_fragment(&pls->cur_seg); + free_fragment(&pls->init_section); + av_freep(&pls->init_sec_buf); + av_freep(&pls->pb.buffer); + if (pls->input) + ff_format_io_close(pls->parent, &pls->input); + if (pls->ctx) { + pls->ctx->pb = NULL; + avformat_close_input(&pls->ctx); + } + + av_freep(&pls->url_template); + av_freep(pls); +} + +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) +{ + DASHContext *c = s->priv_data; + AVDictionary *tmp = NULL; + const char *proto_name = NULL; + int ret; + + av_dict_copy(&tmp, opts, 0); + av_dict_copy(&tmp, opts2, 0); + + if (av_strstart(url, "crypto", NULL)) { + if (url[6] == '+' || url[6] == ':') + proto_name = avio_find_protocol_name(url + 7); + } + + if (!proto_name) + proto_name = avio_find_protocol_name(url); + + if (!proto_name) + return AVERROR_INVALIDDATA; + + // only http(s) & file are allowed + if (av_strstart(proto_name, "file", NULL)) { + if (strcmp(c->allowed_extensions, "ALL") && !av_match_ext(url, c->allowed_extensions)) { + av_log(s, AV_LOG_ERROR, + "Filename extension of \'%s\' is not a common multimedia extension, blocked for security reasons.\n" + "If you wish to override this adjust allowed_extensions, you can set it to \'ALL\' to allow all\n", + url); + return AVERROR_INVALIDDATA; + } + } else if (av_strstart(proto_name, "http", NULL)) { + ; + } else + return AVERROR_INVALIDDATA; + + if (!strncmp(proto_name, url, strlen(proto_name)) && url[strlen(proto_name)] == ':') + ; + else if (av_strstart(url, "crypto", NULL) && !strncmp(proto_name, url + 7, strlen(proto_name)) && url[7 + strlen(proto_name)] == ':') + ; + else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5)) + return AVERROR_INVALIDDATA; + + ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp); + if (ret >= 0) { + // update cookies on http response with setcookies. + char *new_cookies = NULL; + + if (!(s->flags & AVFMT_FLAG_CUSTOM_IO)) + 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", c->cookies, 0); + } + + av_dict_free(&tmp); + + if (is_http) + *is_http = av_strstart(proto_name, "http", NULL); + + return ret; +} + +static char *get_content_url(xmlNodePtr *baseurl_nodes, + int n_baseurl_nodes, + char *rep_id_val, + char *rep_bandwidth_val, + char *val) +{ + int i; + char *text; + char *url = NULL; + char tmp_str[MAX_URL_SIZE]; + char tmp_str_2[MAX_URL_SIZE]; + + memset(tmp_str, 0, sizeof(tmp_str)); + + for (i = 0; i < n_baseurl_nodes; ++i) { + if (baseurl_nodes[i] && + baseurl_nodes[i]->children && + baseurl_nodes[i]->children->type == XML_TEXT_NODE) { + text = xmlNodeGetContent(baseurl_nodes[i]->children); + if (text) { + memset(tmp_str, 0, sizeof(tmp_str)); + memset(tmp_str_2, 0, sizeof(tmp_str_2)); + ff_make_absolute_url(tmp_str_2, MAX_URL_SIZE, tmp_str, text); + av_strlcpy(tmp_str, tmp_str_2, sizeof(tmp_str)); + av_free(text); + } + } + } + + if (val) + av_strlcat(tmp_str, (const char*)val, sizeof(tmp_str)); + + if (rep_id_val) { + url = av_strireplace(tmp_str, "$RepresentationID$", (const char*)rep_id_val); + if (!url) { + return NULL; + } + av_strlcpy(tmp_str, url, sizeof(tmp_str)); + av_free(url); + } + if (rep_bandwidth_val && tmp_str[0] != '\0') { + url = av_strireplace(tmp_str, "$Bandwidth$", (const char*)rep_bandwidth_val); + if (!url) { + return NULL; + } + } + return url; +} + +static char *get_val_from_nodes_tab(xmlNodePtr *nodes, const int n_nodes, const char *attrname) +{ + int i; + char *val; + + for (i = 0; i < n_nodes; ++i) { + if (nodes[i]) { + val = xmlGetProp(nodes[i], attrname); + if (val) + return val; + } + } + + return NULL; +} + +static xmlNodePtr find_child_node_by_name(xmlNodePtr rootnode, const char *nodename) +{ + xmlNodePtr node = rootnode; + if (!node) { + return NULL; + } + + node = xmlFirstElementChild(node); + while (node) { + if (!av_strcasecmp(node->name, nodename)) { + return node; + } + node = xmlNextElementSibling(node); + } + return NULL; +} + +static enum AVMediaType get_content_type(xmlNodePtr node) +{ + enum AVMediaType type = AVMEDIA_TYPE_UNKNOWN; + int i = 0; + const char *attr; + char *val = NULL; + + if (node) { + for (i = 0; i < 2; i++) { + attr = i ? "mimeType" : "contentType"; + val = xmlGetProp(node, attr); + if (val) { + if (av_stristr((const char *)val, "video")) { + type = AVMEDIA_TYPE_VIDEO; + } else if (av_stristr((const char *)val, "audio")) { + type = AVMEDIA_TYPE_AUDIO; + } + av_free(val); + } + } + } + return type; +} + +static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representation *rep, + xmlNodePtr fragmenturl_node, + xmlNodePtr *baseurl_nodes, + char *rep_id_val, + char *rep_bandwidth_val) +{ + char *initialization_val = NULL; + char *media_val = NULL; + + if (!av_strcasecmp(fragmenturl_node->name, (const char *)"Initialization")) { + initialization_val = xmlGetProp(fragmenturl_node, "sourceURL"); + if (initialization_val) { + rep->init_section = av_mallocz(sizeof(struct fragment)); + if (!rep->init_section) { + av_free(initialization_val); + return AVERROR(ENOMEM); + } + rep->init_section->url = get_content_url(baseurl_nodes, 4, + rep_id_val, + rep_bandwidth_val, + initialization_val); + if (!rep->init_section->url) { + av_free(rep->init_section); + av_free(initialization_val); + return AVERROR(ENOMEM); + } + rep->init_section->size = -1; + av_free(initialization_val); + } + } else if (!av_strcasecmp(fragmenturl_node->name, (const char *)"SegmentURL")) { + media_val = xmlGetProp(fragmenturl_node, "media"); + if (media_val) { + struct fragment *seg = av_mallocz(sizeof(struct fragment)); + if (!seg) { + av_free(media_val); + return AVERROR(ENOMEM); + } + seg->url = get_content_url(baseurl_nodes, 4, + rep_id_val, + rep_bandwidth_val, + media_val); + if (!seg->url) { + av_free(seg); + av_free(media_val); + return AVERROR(ENOMEM); + } + seg->size = -1; + dynarray_add(&rep->fragments, &rep->n_fragments, seg); + av_free(media_val); + } + } + + return 0; +} + +static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representation *rep, + xmlNodePtr fragment_timeline_node) +{ + xmlAttrPtr attr = NULL; + char *val = NULL; + + if (!av_strcasecmp(fragment_timeline_node->name, (const char *)"S")) { + struct timeline *tml = av_mallocz(sizeof(struct timeline)); + if (!tml) { + return AVERROR(ENOMEM); + } + attr = fragment_timeline_node->properties; + while (attr) { + val = xmlGetProp(fragment_timeline_node, attr->name); + + if (!val) { + av_log(s, AV_LOG_WARNING, "parse_manifest_segmenttimeline attr->name = %s val is NULL\n", attr->name); + continue; + } + + if (!av_strcasecmp(attr->name, (const char *)"t")) { + tml->starttime = (int64_t)strtoll(val, NULL, 10); + } else if (!av_strcasecmp(attr->name, (const char *)"r")) { + tml->repeat =(int64_t) strtoll(val, NULL, 10); + } else if (!av_strcasecmp(attr->name, (const char *)"d")) { + tml->duration = (int64_t)strtoll(val, NULL, 10); + } + attr = attr->next; + av_free(val); + } + dynarray_add(&rep->timelines, &rep->n_timelines, tml); + } + + return 0; +} + +static int parse_manifest_representation(AVFormatContext *s, const char *url, + xmlNodePtr node, + xmlNodePtr adaptionset_node, + xmlNodePtr mpd_baseurl_node, + xmlNodePtr period_baseurl_node, + xmlNodePtr fragment_template_node, + xmlNodePtr content_component_node, + xmlNodePtr adaptionset_baseurl_node) +{ + int32_t ret = 0; + int32_t audio_rep_idx = 0; + int32_t video_rep_idx = 0; + DASHContext *c = s->priv_data; + struct representation *rep = NULL; + struct fragment *seg = NULL; + xmlNodePtr representation_segmenttemplate_node = NULL; + xmlNodePtr representation_baseurl_node = NULL; + xmlNodePtr representation_segmentlist_node = NULL; + xmlNodePtr fragment_timeline_node = NULL; + xmlNodePtr fragment_templates_tab[2]; + char *duration_val = NULL; + char *presentation_timeoffset_val = NULL; + char *startnumber_val = NULL; + char *timescale_val = NULL; + char *initialization_val = NULL; + char *media_val = NULL; + xmlNodePtr baseurl_nodes[4]; + xmlNodePtr representation_node = node; + char *rep_id_val = xmlGetProp(representation_node, "id"); + char *rep_bandwidth_val = xmlGetProp(representation_node, "bandwidth"); + enum AVMediaType type = AVMEDIA_TYPE_UNKNOWN; + + // try get information from representation + if (type == AVMEDIA_TYPE_UNKNOWN) + type = get_content_type(representation_node); + // try get information from contentComponen + if (type == AVMEDIA_TYPE_UNKNOWN) + type = get_content_type(content_component_node); + // try get information from adaption set + if (type == AVMEDIA_TYPE_UNKNOWN) + type = get_content_type(adaptionset_node); + if (type == AVMEDIA_TYPE_UNKNOWN) { + av_log(s, AV_LOG_VERBOSE, "Parsing '%s' - skipp not supported representation type\n", url); + } else if ((type == AVMEDIA_TYPE_VIDEO && !c->cur_video) || (type == AVMEDIA_TYPE_AUDIO && !c->cur_audio)) { + // convert selected representation to our internal struct + rep = av_mallocz(sizeof(struct representation)); + if (!rep) { + ret = AVERROR(ENOMEM); + goto end; + } + representation_segmenttemplate_node = find_child_node_by_name(representation_node, "SegmentTemplate"); + representation_baseurl_node = find_child_node_by_name(representation_node, "BaseURL"); + representation_segmentlist_node = find_child_node_by_name(representation_node, "SegmentList"); + + baseurl_nodes[0] = mpd_baseurl_node; + baseurl_nodes[1] = period_baseurl_node; + baseurl_nodes[2] = adaptionset_baseurl_node; + baseurl_nodes[3] = representation_baseurl_node; + + if (representation_segmenttemplate_node || fragment_template_node) { + fragment_timeline_node = NULL; + fragment_templates_tab[0] = representation_segmenttemplate_node; + fragment_templates_tab[1] = fragment_template_node; + + presentation_timeoffset_val = get_val_from_nodes_tab(fragment_templates_tab, 2, "presentationTimeOffset"); + duration_val = get_val_from_nodes_tab(fragment_templates_tab, 2, "duration"); + startnumber_val = get_val_from_nodes_tab(fragment_templates_tab, 2, "startNumber"); + timescale_val = get_val_from_nodes_tab(fragment_templates_tab, 2, "timescale"); + initialization_val = get_val_from_nodes_tab(fragment_templates_tab, 2, "initialization"); + media_val = get_val_from_nodes_tab(fragment_templates_tab, 2, "media"); + + if (initialization_val) { + rep->init_section = av_mallocz(sizeof(struct fragment)); + if (!rep->init_section) { + av_free(rep); + ret = AVERROR(ENOMEM); + goto end; + } + rep->init_section->url = get_content_url(baseurl_nodes, 4, rep_id_val, rep_bandwidth_val, initialization_val); + if (!rep->init_section->url) { + av_free(rep->init_section); + av_free(rep); + ret = AVERROR(ENOMEM); + goto end; + } + rep->init_section->size = -1; + av_free(initialization_val); + } + + if (media_val) { + rep->url_template = get_content_url(baseurl_nodes, 4, rep_id_val, rep_bandwidth_val, media_val); + av_free(media_val); + } + + if (presentation_timeoffset_val) { + rep->presentation_timeoffset = (int64_t) strtoll(presentation_timeoffset_val, NULL, 10); + av_free(presentation_timeoffset_val); + } + if (duration_val) { + rep->fragment_duration = (int64_t) strtoll(duration_val, NULL, 10); + av_free(duration_val); + } + if (timescale_val) { + rep->fragment_timescale = (int64_t) strtoll(timescale_val, NULL, 10); + av_free(timescale_val); + } + if (startnumber_val) { + rep->first_seq_no = (int64_t) strtoll(startnumber_val, NULL, 10); + av_free(startnumber_val); + } + + fragment_timeline_node = find_child_node_by_name(representation_segmenttemplate_node, "SegmentTimeline"); + + if (!fragment_timeline_node) + fragment_timeline_node = find_child_node_by_name(fragment_template_node, "SegmentTimeline"); + if (fragment_timeline_node) { + fragment_timeline_node = xmlFirstElementChild(fragment_timeline_node); + while (fragment_timeline_node) { + ret = parse_manifest_segmenttimeline(s, rep, fragment_timeline_node); + if (ret < 0) { + return ret; + } + fragment_timeline_node = xmlNextElementSibling(fragment_timeline_node); + } + } + } else if (representation_baseurl_node && !representation_segmentlist_node) { + seg = av_mallocz(sizeof(struct fragment)); + if (!seg) { + ret = AVERROR(ENOMEM); + goto end; + } + seg->url = get_content_url(baseurl_nodes, 4, rep_id_val, rep_bandwidth_val, NULL); + if (!seg->url) { + av_free(seg); + ret = AVERROR(ENOMEM); + goto end; + } + seg->size = -1; + dynarray_add(&rep->fragments, &rep->n_fragments, seg); + } else if (representation_segmentlist_node) { + // TODO: https://www.brendanlong.com/the-structure-of-an-mpeg-dash-mpd.html + // http://www-itec.uni-klu.ac.at/dash/ddash/mpdGenerator.php?fragmentlength=15&type=full + xmlNodePtr fragmenturl_node = NULL; + duration_val = xmlGetProp(representation_segmentlist_node, "duration"); + timescale_val = xmlGetProp(representation_segmentlist_node, "timescale"); + if (duration_val) { + rep->fragment_duration = (int64_t) strtoll(duration_val, NULL, 10); + av_free(duration_val); + } + if (timescale_val) { + rep->fragment_timescale = (int64_t) strtoll(timescale_val, NULL, 10); + av_free(timescale_val); + } + fragmenturl_node = xmlFirstElementChild(representation_segmentlist_node); + while (fragmenturl_node) { + ret = parse_manifest_segmenturlnode(s, rep, fragmenturl_node, + baseurl_nodes, + rep_id_val, + rep_bandwidth_val); + if (ret < 0) { + return ret; + } + fragmenturl_node = xmlNextElementSibling(fragmenturl_node); + } + + fragment_timeline_node = find_child_node_by_name(representation_segmenttemplate_node, "SegmentTimeline"); + + if (!fragment_timeline_node) + fragment_timeline_node = find_child_node_by_name(fragment_template_node, "SegmentTimeline"); + if (fragment_timeline_node) { + fragment_timeline_node = xmlFirstElementChild(fragment_timeline_node); + while (fragment_timeline_node) { + ret = parse_manifest_segmenttimeline(s, rep, fragment_timeline_node); + if (ret < 0) { + return ret; + } + fragment_timeline_node = xmlNextElementSibling(fragment_timeline_node); + } + } + } else { + free_representation(rep); + rep = NULL; + av_log(s, AV_LOG_ERROR, "Unknown format of Representation node id[%s] \n", (const char *)rep_id_val); + } + + if (rep) { + if (rep->fragment_duration > 0 && !rep->fragment_timescale) + rep->fragment_timescale = 1; + if (type == AVMEDIA_TYPE_VIDEO) { + rep->rep_idx = video_rep_idx; + c->cur_video = rep; + } else { + rep->rep_idx = audio_rep_idx; + c->cur_audio = rep; + } + } + } + + video_rep_idx += type == AVMEDIA_TYPE_VIDEO; + audio_rep_idx += type == AVMEDIA_TYPE_AUDIO; + +end: + if (rep_id_val) + av_free(rep_id_val); + if (rep_bandwidth_val) + av_free(rep_bandwidth_val); + + return ret; +} + +static int parse_manifest_adaptationset(AVFormatContext *s, const char *url, + xmlNodePtr adaptionset_node, + xmlNodePtr mpd_baseurl_node, + xmlNodePtr period_baseurl_node) +{ + int ret = 0; + xmlNodePtr fragment_template_node = NULL; + xmlNodePtr content_component_node = NULL; + xmlNodePtr adaptionset_baseurl_node = NULL; + xmlNodePtr node = NULL; + + node = xmlFirstElementChild(adaptionset_node); + while (node) { + if (!av_strcasecmp(node->name, (const char *)"SegmentTemplate")) { + fragment_template_node = node; + } else if (!av_strcasecmp(node->name, (const char *)"ContentComponent")) { + content_component_node = node; + } else if (!av_strcasecmp(node->name, (const char *)"BaseURL")) { + adaptionset_baseurl_node = node; + } else if (!av_strcasecmp(node->name, (const char *)"Representation")) { + ret = parse_manifest_representation(s, url, node, + adaptionset_node, + mpd_baseurl_node, + period_baseurl_node, + fragment_template_node, + content_component_node, + adaptionset_baseurl_node); + if (ret < 0) { + return ret; + } + } + node = xmlNextElementSibling(node); + } + return 0; +} + +static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) +{ + DASHContext *c = s->priv_data; + int ret = 0; + int close_in = 0; + uint8_t *new_url = NULL; + int64_t filesize = 0; + char *buffer = NULL; + AVDictionary *opts = NULL; + xmlDoc *doc = NULL; + xmlNodePtr root_element = NULL; + xmlNodePtr node = NULL; + xmlNodePtr period_node = NULL; + xmlNodePtr mpd_baseurl_node = NULL; + xmlNodePtr period_baseurl_node = NULL; + xmlNodePtr adaptionset_node = NULL; + xmlAttrPtr attr = NULL; + char *val = NULL; + uint32_t perdiod_duration_sec = 0; + uint32_t perdiod_start_sec = 0; + int32_t audio_rep_idx = 0; + int32_t video_rep_idx = 0; + + if (!in) { + close_in = 1; + + set_httpheader_options(c, opts); + ret = avio_open2(&in, url, AVIO_FLAG_READ, c->interrupt_callback, &opts); + av_dict_free(&opts); + if (ret < 0) + return ret; + } + + if (av_opt_get(in, "location", AV_OPT_SEARCH_CHILDREN, &new_url) >= 0) { + c->base_url = av_strdup(new_url); + } else { + c->base_url = av_strdup(url); + } + + filesize = avio_size(in); + if (filesize <= 0) { + filesize = 8 * 1024; + } + + buffer = av_mallocz(filesize); + if (!buffer) { + av_free(c->base_url); + return AVERROR(ENOMEM); + } + + filesize = avio_read(in, buffer, filesize); + if (filesize <= 0) { + av_log(s, AV_LOG_ERROR, "Unable to read to offset '%s'\n", url); + ret = AVERROR_INVALIDDATA; + } else { + LIBXML_TEST_VERSION + + doc = xmlReadMemory(buffer, filesize, c->base_url, NULL, 0); + root_element = xmlDocGetRootElement(doc); + node = root_element; + + if (!node) { + ret = AVERROR_INVALIDDATA; + av_log(s, AV_LOG_ERROR, "Unable to parse '%s' - missing root node\n", url); + goto cleanup; + } + + if (node->type != XML_ELEMENT_NODE || + av_strcasecmp(node->name, (const char *)"MPD")) { + ret = AVERROR_INVALIDDATA; + av_log(s, AV_LOG_ERROR, "Unable to parse '%s' - wrong root node name[%s] type[%d]\n", url, node->name, (int)node->type); + goto cleanup; + } + + val = xmlGetProp(node, "type"); + if (!val) { + av_log(s, AV_LOG_ERROR, "Unable to parse '%s' - missing type attrib\n", url); + ret = AVERROR_INVALIDDATA; + goto cleanup; + } + if (!av_strcasecmp(val, (const char *)"dynamic")) + c->is_live = 1; + av_free(val); + + attr = node->properties; + while (attr) { + val = xmlGetProp(node, attr->name); + + if (!av_strcasecmp(attr->name, (const char *)"availabilityStartTime")) { + c->availability_start_time = get_utc_date_time_insec(s, (const char *)val); + } else if (!av_strcasecmp(attr->name, (const char *)"publishTime")) { + c->publish_time = get_utc_date_time_insec(s, (const char *)val); + } else if (!av_strcasecmp(attr->name, (const char *)"minimumUpdatePeriod")) { + c->minimum_update_period = get_duration_insec(s, (const char *)val); + } else if (!av_strcasecmp(attr->name, (const char *)"timeShiftBufferDepth")) { + c->time_shift_buffer_depth = get_duration_insec(s, (const char *)val); + } else if (!av_strcasecmp(attr->name, (const char *)"minBufferTime")) { + c->min_buffer_time = get_duration_insec(s, (const char *)val); + } else if (!av_strcasecmp(attr->name, (const char *)"suggestedPresentationDelay")) { + c->suggested_presentation_delay = get_duration_insec(s, (const char *)val); + } else if (!av_strcasecmp(attr->name, (const char *)"mediaPresentationDuration")) { + c->media_presentation_duration = get_duration_insec(s, (const char *)val); + } + attr = attr->next; + av_free(val); + } + + mpd_baseurl_node = find_child_node_by_name(node, "BaseURL"); + + // at now we can handle only one period, with the longest duration + node = xmlFirstElementChild(node); + while (node) { + if (!av_strcasecmp(node->name, (const char *)"Period")) { + perdiod_duration_sec = 0; + perdiod_start_sec = 0; + attr = node->properties; + while (attr) { + val = xmlGetProp(node, attr->name); + if (!av_strcasecmp(attr->name, (const char *)"duration")) { + perdiod_duration_sec = get_duration_insec(s, (const char *)val); + } else if (!av_strcasecmp(attr->name, (const char *)"start")) { + perdiod_start_sec = get_duration_insec(s, (const char *)val); + } + attr = attr->next; + av_free(val); + } + if ((perdiod_duration_sec) >= (c->period_duration)) { + period_node = node; + c->period_duration = perdiod_duration_sec; + c->period_start = perdiod_start_sec; + if (c->period_start > 0) + c->media_presentation_duration = c->period_duration; + } + } + node = xmlNextElementSibling(node); + } + if (!period_node) { + av_log(s, AV_LOG_ERROR, "Unable to parse '%s' - missing Period node\n", url); + ret = AVERROR_INVALIDDATA; + goto cleanup; + } + + adaptionset_node = xmlFirstElementChild(period_node); + while (adaptionset_node) { + if (!av_strcasecmp(adaptionset_node->name, (const char *)"BaseURL")) { + period_baseurl_node = adaptionset_node; + } else if (!av_strcasecmp(adaptionset_node->name, (const char *)"AdaptationSet")) { + parse_manifest_adaptationset(s, url, adaptionset_node, mpd_baseurl_node, period_baseurl_node); + } + adaptionset_node = xmlNextElementSibling(adaptionset_node); + } + if (c->cur_video) { + c->cur_video->rep_count = video_rep_idx; + av_log(s, AV_LOG_VERBOSE, "rep_idx[%d]\n", (int)c->cur_video->rep_idx); + av_log(s, AV_LOG_VERBOSE, "rep_count[%d]\n", (int)video_rep_idx); + } + if (c->cur_audio) { + c->cur_audio->rep_count = audio_rep_idx; + } +cleanup: + /*free the document */ + xmlFreeDoc(doc); + xmlCleanupParser(); + } + + av_free(new_url); + av_free(buffer); + if (close_in) { + avio_close(in); + } + return ret; +} + +static int64_t calc_cur_seg_no(AVFormatContext *s, struct representation *pls) +{ + DASHContext *c = s->priv_data; + int64_t num = 0; + int64_t start_time_offset = 0; + + if (c->is_live) { + if (pls->n_fragments) { + num = pls->first_seq_no; + } else if (pls->n_timelines) { + start_time_offset = get_segment_start_time_based_on_timeline(pls, 0xFFFFFFFF) - pls->timelines[pls->first_seq_no]->starttime; // total duration of playlist + if (start_time_offset < 60 * pls->fragment_timescale) + start_time_offset = 0; + else + start_time_offset = start_time_offset - 60 * pls->fragment_timescale; + + num = calc_next_seg_no_from_timelines(pls, pls->timelines[pls->first_seq_no]->starttime + start_time_offset); + if (num == -1) + num = pls->first_seq_no; + } else if (pls->fragment_duration){ + if (pls->presentation_timeoffset) { + num = pls->presentation_timeoffset * pls->fragment_timescale / pls->fragment_duration; + } 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; + } 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; + } + } + } else { + num = pls->first_seq_no; + } + return num; +} + +static int64_t calc_min_seg_no(AVFormatContext *s, struct representation *pls) +{ + DASHContext *c = s->priv_data; + int64_t num = 0; + + if (c->is_live && pls->fragment_duration) { + 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; + } + return num; +} + +static int64_t calc_max_seg_no(struct representation *pls) +{ + DASHContext *c = pls->parent->priv_data; + int64_t num = 0; + + if (pls->n_fragments) { + num = pls->first_seq_no + pls->n_fragments - 1; + } else if (pls->n_timelines) { + 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; + } + } 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; + } else if (pls->fragment_duration) { + num = pls->first_seq_no + (c->media_presentation_duration * pls->fragment_timescale) / pls->fragment_duration; + } + + return num; +} + +static void move_timelines(struct representation *rep_src, struct representation *rep_dest) +{ + if (rep_dest && rep_src ) { + free_timelines_list(rep_dest); + rep_dest->timelines = rep_src->timelines; + rep_dest->n_timelines = rep_src->n_timelines; + rep_dest->first_seq_no = rep_src->first_seq_no; + rep_dest->last_seq_no = calc_max_seg_no(rep_dest); + rep_src->timelines = NULL; + rep_src->n_timelines = 0; + rep_dest->cur_seq_no = rep_src->cur_seq_no; + } +} + +static void move_segments(struct representation *rep_src, struct representation *rep_dest) +{ + if (rep_dest && rep_src ) { + free_fragment_list(rep_dest); + if (rep_src->start_number > (rep_dest->start_number + rep_dest->n_fragments)) + rep_dest->cur_seq_no = 0; + else + rep_dest->cur_seq_no += rep_src->start_number - rep_dest->start_number; + rep_dest->fragments = rep_src->fragments; + rep_dest->n_fragments = rep_src->n_fragments; + rep_dest->parent = rep_src->parent; + rep_dest->last_seq_no = calc_max_seg_no(rep_dest); + rep_src->fragments = NULL; + rep_src->n_fragments = 0; + } +} + + +static int refresh_manifest(AVFormatContext *s) +{ + + int ret = 0; + DASHContext *c = s->priv_data; + + // save current context + struct representation *cur_video = c->cur_video; + struct representation *cur_audio = c->cur_audio; + char *base_url = c->base_url; + + c->base_url = NULL; + c->cur_video = NULL; + c->cur_audio = NULL; + ret = parse_manifest(s, s->filename, NULL); + if (ret) + goto finish; + + if (cur_video && cur_video->timelines || cur_audio && cur_audio->timelines) { + // calc current time + int64_t currentVideoTime = 0; + int64_t currentAudioTime = 0; + if (cur_video && cur_video->timelines) + currentVideoTime = get_segment_start_time_based_on_timeline(cur_video, cur_video->cur_seq_no) / cur_video->fragment_timescale; + if (cur_audio && cur_audio->timelines) + currentAudioTime = get_segment_start_time_based_on_timeline(cur_audio, cur_audio->cur_seq_no) / cur_audio->fragment_timescale; + // update segments + if (cur_video && cur_video->timelines) { + c->cur_video->cur_seq_no = calc_next_seg_no_from_timelines(c->cur_video, currentVideoTime * cur_video->fragment_timescale - 1); + if (c->cur_video->cur_seq_no >= 0) { + move_timelines(c->cur_video, cur_video); + } + } + if (cur_audio && cur_audio->timelines) { + c->cur_audio->cur_seq_no = calc_next_seg_no_from_timelines(c->cur_audio, currentAudioTime * cur_audio->fragment_timescale - 1); + if (c->cur_audio->cur_seq_no >= 0) { + move_timelines(c->cur_audio, cur_audio); + } + } + } + if (cur_video && cur_video->fragments) { + move_segments(c->cur_video, cur_video); + } + if (cur_audio && cur_audio->fragments) { + move_segments(c->cur_audio, cur_audio); + } + +finish: + // restore context + if (c->base_url) + av_free(base_url); + else + c->base_url = base_url; + if (c->cur_audio) + free_representation(c->cur_audio); + if (c->cur_video) + free_representation(c->cur_video); + c->cur_audio = cur_audio; + c->cur_video = cur_video; + return ret; +} + +static struct fragment *get_current_fragment(struct representation *pls) +{ + int64_t min_seq_no = 0; + int64_t max_seq_no = 0; + struct fragment *seg = NULL; + struct fragment *seg_ptr = NULL; + DASHContext *c = pls->parent->priv_data; + + while (( !ff_check_interrupt(c->interrupt_callback)&& pls->n_fragments > 0)) { + if (pls->cur_seq_no < pls->n_fragments) { + seg_ptr = pls->fragments[pls->cur_seq_no]; + seg = av_mallocz(sizeof(struct fragment)); + if (!seg) { + return NULL; + } + seg->url = av_strdup(seg_ptr->url); + if (!seg->url) { + av_free(seg); + return NULL; + } + seg->size = seg_ptr->size; + seg->url_offset = seg_ptr->url_offset; + return seg; + } else if (c->is_live) { + refresh_manifest(pls->parent); + } else { + break; + } + } + if (c->is_live) { + min_seq_no = calc_min_seg_no(pls->parent, pls); + max_seq_no = calc_max_seg_no(pls); + + if (pls->timelines || pls->fragments) { + refresh_manifest(pls->parent); + } + if (pls->cur_seq_no <= min_seq_no) { + av_log(pls->parent, AV_LOG_VERBOSE, "old fragment: cur[%"PRId64"] min[%"PRId64"] max[%"PRId64"], playlist %d\n", (int64_t)pls->cur_seq_no, min_seq_no, max_seq_no, (int)pls->rep_idx); + pls->cur_seq_no = calc_cur_seg_no(pls->parent, pls); + } else if (pls->cur_seq_no > max_seq_no) { + av_log(pls->parent, AV_LOG_VERBOSE, "new fragment: min[%"PRId64"] max[%"PRId64"], playlist %d\n", min_seq_no, max_seq_no, (int)pls->rep_idx); + } + seg = av_mallocz(sizeof(struct fragment)); + if (!seg) { + return NULL; + } + } else if (pls->cur_seq_no <= pls->last_seq_no) { + seg = av_mallocz(sizeof(struct fragment)); + if (!seg) { + return NULL; + } + } + if (seg) { + char tmpfilename[MAX_URL_SIZE]; + + ff_dash_fill_tmpl_params(tmpfilename, sizeof(tmpfilename), pls->url_template, 0, pls->cur_seq_no, 0, get_segment_start_time_based_on_timeline(pls, pls->cur_seq_no)); + seg->url = av_strireplace(pls->url_template, pls->url_template, tmpfilename); + if (!seg->url) { + av_log(pls->parent, AV_LOG_WARNING, "Unable to resolve template url '%s', try to use origin template\n", pls->url_template); + seg->url = av_strdup(pls->url_template); + if (!seg->url) { + av_log(pls->parent, AV_LOG_ERROR, "Cannot resolve template url '%s'\n", pls->url_template); + return NULL; + } + } + + seg->size = -1; + } + + 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) +{ + int ret; + + /* limit read if the fragment was only a part of a file */ + 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); + } + if (ret > 0) + pls->cur_seg_offset += ret; + + return ret; +} + +static int open_input(DASHContext *c, struct representation *pls, struct fragment *seg) +{ + AVDictionary *opts = NULL; + char url[MAX_URL_SIZE]; + int ret; + + 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) */ + av_dict_set_int(&opts, "offset", seg->url_offset, 0); + av_dict_set_int(&opts, "end_offset", seg->url_offset + seg->size, 0); + } + + ff_make_absolute_url(url, MAX_URL_SIZE, c->base_url, seg->url); + av_log(pls->parent, AV_LOG_VERBOSE, "DASH request for url '%s', offset %"PRId64", playlist %d\n", + url, seg->url_offset, pls->rep_idx); + ret = open_url(pls->parent, &pls->input, url, c->avio_opts, opts, NULL); + if (ret < 0) { + goto cleanup; + } + + /* Seek to the requested position. If this was a HTTP request, the offset + * should already be where want it to, but this allows e.g. local testing + * without a HTTP server. */ + if (!ret && seg->url_offset) { + int64_t seekret = avio_seek(pls->input, seg->url_offset, SEEK_SET); + if (seekret < 0) { + av_log(pls->parent, AV_LOG_ERROR, "Unable to seek to offset %"PRId64" of DASH fragment '%s'\n", seg->url_offset, seg->url); + ret = (int) seekret; + ff_format_io_close(pls->parent, &pls->input); + } + } + +cleanup: + av_dict_free(&opts); + pls->cur_seg_offset = 0; + pls->cur_seg_size = seg->size; + return ret; +} + +static int update_init_section(struct representation *pls) +{ + static const int max_init_section_size = 1024 * 1024; + DASHContext *c = pls->parent->priv_data; + int64_t sec_size; + int64_t urlsize; + int ret; + + if (!pls->init_section || pls->init_sec_buf) + return 0; + + ret = open_input(c, pls, pls->init_section); + if (ret < 0) { + av_log(pls->parent, AV_LOG_WARNING, + "Failed to open an initialization section in playlist %d\n", + pls->rep_idx); + return ret; + } + + if (pls->init_section->size >= 0) + sec_size = pls->init_section->size; + else if ((urlsize = avio_size(pls->input)) >= 0) + sec_size = urlsize; + else + sec_size = max_init_section_size; + + av_log(pls->parent, AV_LOG_DEBUG, + "Downloading an initialization section of size %"PRId64"\n", + sec_size); + + sec_size = FFMIN(sec_size, max_init_section_size); + + 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); + ff_format_io_close(pls->parent, &pls->input); + + if (ret < 0) + return ret; + + pls->init_sec_data_len = ret; + pls->init_sec_buf_read_offset = 0; + + return 0; +} + +static int64_t seek_data(void *opaque, int64_t offset, int whence) +{ + struct representation *v = opaque; + if (v->n_fragments && !v->init_sec_data_len) { + return avio_seek(v->input, offset, whence); + } + + return AVERROR(ENOSYS); +} + +static int read_data(void *opaque, uint8_t *buf, int buf_size) +{ + int ret = 0; + struct representation *v = opaque; + DASHContext *c = v->parent->priv_data; + +restart: + if (!v->input) { + free_fragment(&v->cur_seg); + v->cur_seg = get_current_fragment(v); + if (!v->cur_seg) { + ret = AVERROR_EOF; + goto end; + } + + /* load/update Media Initialization Section, if any */ + ret = update_init_section(v); + if (ret) + goto end; + + ret = open_input(c, v, v->cur_seg); + if (ret < 0) { + if (ff_check_interrupt(c->interrupt_callback)) { + goto end; + ret = AVERROR_EXIT; + } + av_log(v->parent, AV_LOG_WARNING, "Failed to open fragment of playlist %d\n", v->rep_idx); + v->cur_seq_no++; + goto restart; + } + } + + if (v->init_sec_buf_read_offset < v->init_sec_data_len) { + /* Push init section out first before first actual fragment */ + int copy_size = FFMIN(v->init_sec_data_len - v->init_sec_buf_read_offset, buf_size); + memcpy(buf, v->init_sec_buf, copy_size); + v->init_sec_buf_read_offset += copy_size; + ret = copy_size; + goto end; + } + + /* check the v->cur_seg, if it is null, get current and double check if the new v->cur_seg*/ + if (!v->cur_seg) { + v->cur_seg = get_current_fragment(v); + } + if (!v->cur_seg) { + ret = AVERROR_EOF; + goto end; + } + ret = read_from_url(v, v->cur_seg, buf, buf_size, READ_NORMAL); + if (ret > 0) + goto end; + + if (!v->is_restart_needed) + v->cur_seq_no++; + v->is_restart_needed = 1; + +end: + return ret; +} + +static int save_avio_options(AVFormatContext *s) +{ + DASHContext *c = s->priv_data; + const char *opts[] = { "headers", "user_agent", "user-agent", "cookies", NULL }, **opt = opts; + uint8_t *buf = NULL; + int ret = 0; + + while (*opt) { + if (av_opt_get(s->pb, *opt, AV_OPT_SEARCH_CHILDREN, &buf) >= 0) { + if (buf[0] != '\0') { + ret = av_dict_set(&c->avio_opts, *opt, buf, AV_DICT_DONT_STRDUP_VAL); + if (ret < 0) + return ret; + } + } + opt++; + } + + return ret; +} + +static int nested_io_open(AVFormatContext *s, AVIOContext **pb, const char *url, + int flags, AVDictionary **opts) +{ + av_log(s, AV_LOG_ERROR, + "A DASH playlist item '%s' referred to an external file '%s'. " + "Opening this file was forbidden for security reasons\n", + s->filename, url); + return AVERROR(EPERM); +} + +static int reopen_demux_for_component(AVFormatContext *s, struct representation *pls) +{ + DASHContext *c = s->priv_data; + AVInputFormat *in_fmt = NULL; + AVDictionary *in_fmt_opts = NULL; + uint8_t *avio_ctx_buffer = NULL; + int ret = 0; + + if (pls->ctx) { + /* note: the internal buffer could have changed, and be != avio_ctx_buffer */ + av_freep(&pls->pb.buffer); + memset(&pls->pb, 0x00, sizeof(AVIOContext)); + pls->ctx->pb = NULL; + avformat_close_input(&pls->ctx); + pls->ctx = NULL; + } + if (!(pls->ctx = avformat_alloc_context())) { + ret = AVERROR(ENOMEM); + goto fail; + } + + avio_ctx_buffer = av_malloc(INITIAL_BUFFER_SIZE); + if (!avio_ctx_buffer ) { + ret = AVERROR(ENOMEM); + avformat_free_context(pls->ctx); + pls->ctx = NULL; + goto fail; + } + if (c->is_live) { + ffio_init_context(&pls->pb, avio_ctx_buffer , INITIAL_BUFFER_SIZE, 0, pls, read_data, NULL, NULL); + } else { + ffio_init_context(&pls->pb, avio_ctx_buffer , INITIAL_BUFFER_SIZE, 0, pls, read_data, NULL, seek_data); + } + pls->pb.seekable = 0; + + if ((ret = ff_copy_whiteblacklists(pls->ctx, s)) < 0) + goto fail; + + pls->ctx->flags = AVFMT_FLAG_CUSTOM_IO; + pls->ctx->probesize = 1024 * 4; + pls->ctx->max_analyze_duration = 4 * AV_TIME_BASE; + ret = av_probe_input_buffer(&pls->pb, &in_fmt, "", NULL, 0, 0); + if (ret < 0) { + av_log(s, AV_LOG_ERROR, "Error when loading first fragment, playlist %d\n", (int)pls->rep_idx); + avformat_free_context(pls->ctx); + pls->ctx = NULL; + goto fail; + } + + pls->ctx->pb = &pls->pb; + pls->ctx->io_open = nested_io_open; + + // provide additional information from mpd if available + ret = avformat_open_input(&pls->ctx, "", in_fmt, &in_fmt_opts); //pls->init_section->url + av_dict_free(&in_fmt_opts); + if (ret < 0) + goto fail; + if (pls->n_fragments) { + ret = avformat_find_stream_info(pls->ctx, NULL); + if (ret < 0) + goto fail; + } + +fail: + return ret; +} + +static int open_demux_for_component(AVFormatContext *s, struct representation *pls) +{ + int ret = 0; + int i; + + pls->parent = s; + pls->cur_seq_no = calc_cur_seg_no(s, pls); + pls->last_seq_no = calc_max_seg_no(pls); + + ret = reopen_demux_for_component(s, pls); + if (ret < 0) { + goto fail; + } + for (i = 0; i < pls->ctx->nb_streams; i++) { + AVStream *st = avformat_new_stream(s, NULL); + AVStream *ist = pls->ctx->streams[i]; + if (!st) { + ret = AVERROR(ENOMEM); + goto fail; + } + st->id = i; + avcodec_parameters_copy(st->codecpar, pls->ctx->streams[i]->codecpar); + avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den); + } + + return 0; +fail: + return ret; +} + +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; + + 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->filename, s->pb)) < 0) + goto fail; + + if ((ret = save_avio_options(s)) < 0) + goto fail; + + /* If this isn't a live stream, fill the total duration of the + * stream. */ + if (!c->is_live) { + s->duration = (int64_t) c->media_presentation_duration * AV_TIME_BASE; + } + + /* Open the demuxer for curent video and current audio components if available */ + if (!ret && c->cur_video) { + ret = open_demux_for_component(s, c->cur_video); + if (!ret) { + c->cur_video->stream_index = stream_index; + ++stream_index; + } else { + free_representation(c->cur_video); + c->cur_video = NULL; + } + } + + if (!ret && c->cur_audio) { + ret = open_demux_for_component(s, c->cur_audio); + if (!ret) { + c->cur_audio->stream_index = stream_index; + ++stream_index; + } else { + free_representation(c->cur_audio); + c->cur_audio = NULL; + } + } + + if (!stream_index) { + ret = AVERROR_INVALIDDATA; + goto fail; + } + + /* Create a program */ + if (!ret) { + AVProgram *program; + program = av_new_program(s, 0); + if (!program) { + goto fail; + } + + if (c->cur_video) { + av_program_add_stream_index(s, 0, c->cur_video->stream_index); + } + if (c->cur_audio) { + av_program_add_stream_index(s, 0, c->cur_audio->stream_index); + } + } + + return 0; +fail: + return ret; +} + +static int dash_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + DASHContext *c = s->priv_data; + int ret = 0; + struct representation *cur = NULL; + + if (!c->cur_audio && !c->cur_video ) { + return AVERROR_INVALIDDATA; + } + if (c->cur_audio && !c->cur_video) { + cur = c->cur_audio; + } else if (!c->cur_audio && c->cur_video) { + cur = c->cur_video; + } else if (c->cur_video->cur_timestamp < c->cur_audio->cur_timestamp) { + cur = c->cur_video; + } else { + cur = c->cur_audio; + } + + if (cur->ctx) { + while (!ff_check_interrupt(c->interrupt_callback) && !ret) { + ret = av_read_frame(cur->ctx, pkt); + if (ret >= 0) { + /* If we got a packet, return it */ + cur->cur_timestamp = av_rescale(pkt->pts, (int64_t)cur->ctx->streams[0]->time_base.num * 90000, cur->ctx->streams[0]->time_base.den); + pkt->stream_index = cur->stream_index; + return 0; + } + if (cur->is_restart_needed) { + cur->cur_seg_offset = 0; + cur->init_sec_buf_read_offset = 0; + if (cur->input) + ff_format_io_close(cur->parent, &cur->input); + ret = reopen_demux_for_component(s, cur); + cur->is_restart_needed = 0; + } + + } + } + return AVERROR_EOF; +} + +static int dash_close(AVFormatContext *s) +{ + DASHContext *c = s->priv_data; + if (c->cur_audio) { + free_representation(c->cur_audio); + } + if (c->cur_video) { + free_representation(c->cur_video); + } + + av_freep(&c->cookies); + av_freep(&c->user_agent); + av_dict_free(&c->avio_opts); + av_freep(&c->base_url); + return 0; +} + +static int dash_seek(AVFormatContext *s, struct representation *pls, int64_t seek_pos_msec, int flags) +{ + int ret = 0; + int i = 0; + int j = 0; + int64_t duration = 0; + + av_log(pls->parent, AV_LOG_VERBOSE, "DASH seek pos[%"PRId64"ms], playlist %d\n", seek_pos_msec, pls->rep_idx); + + // single fragment mode + if (pls->n_fragments == 1) { + pls->cur_timestamp = 0; + pls->cur_seg_offset = 0; + ff_read_frame_flush(pls->ctx); + return av_seek_frame(pls->ctx, -1, seek_pos_msec * 1000, flags); + } + + if (pls->input) + ff_format_io_close(pls->parent, &pls->input); + + // find the nearest fragment + if (pls->n_timelines > 0 && pls->fragment_timescale > 0) { + int64_t num = pls->first_seq_no; + av_log(pls->parent, AV_LOG_VERBOSE, "dash_seek with SegmentTimeline start n_timelines[%d] " + "last_seq_no[%"PRId64"], playlist %d.\n", + (int)pls->n_timelines, (int64_t)pls->last_seq_no, (int)pls->rep_idx); + for (i = 0; i < pls->n_timelines; i++) { + if (pls->timelines[i]->starttime > 0) { + duration = pls->timelines[i]->starttime; + } + duration += pls->timelines[i]->duration; + if (seek_pos_msec < ((duration * 1000) / pls->fragment_timescale)) { + goto set_seq_num; + } + for (j = 0; j < pls->timelines[i]->repeat; j++) { + duration += pls->timelines[i]->duration; + num++; + if (seek_pos_msec < ((duration * 1000) / pls->fragment_timescale)) { + goto set_seq_num; + } + } + num++; + } + +set_seq_num: + pls->cur_seq_no = num > pls->last_seq_no ? pls->last_seq_no : num; + av_log(pls->parent, AV_LOG_VERBOSE, "dash_seek with SegmentTimeline end cur_seq_no[%"PRId64"], playlist %d.\n", + (int64_t)pls->cur_seq_no, (int)pls->rep_idx); + } else if (pls->fragment_duration > 0) { + pls->cur_seq_no = pls->first_seq_no + ((seek_pos_msec * pls->fragment_timescale) / pls->fragment_duration) / 1000; + } else { + av_log(pls->parent, AV_LOG_ERROR, "dash_seek missing fragment_duration\n"); + pls->cur_seq_no = pls->first_seq_no; + } + pls->cur_timestamp = 0; + pls->cur_seg_offset = 0; + pls->init_sec_buf_read_offset = 0; + ret = reopen_demux_for_component(s, pls); + + return ret; +} + +static int dash_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) +{ + int ret = 0; + DASHContext *c = s->priv_data; + int64_t seek_pos_msec = av_rescale_rnd(timestamp, 1000, + s->streams[stream_index]->time_base.den, + flags & AVSEEK_FLAG_BACKWARD ? + AV_ROUND_DOWN : AV_ROUND_UP); + if ((flags & AVSEEK_FLAG_BYTE) || c->is_live) + return AVERROR(ENOSYS); + if (c->cur_audio) { + ret = dash_seek(s, c->cur_audio, seek_pos_msec, flags); + } + if (!ret && c->cur_video) { + ret = dash_seek(s, c->cur_video, seek_pos_msec, flags); + } + return ret; +} + +static int dash_probe(AVProbeData *p) +{ + if (!av_stristr(p->buf, "buf, "dash:profile:isoff-on-demand:2011") || + av_stristr(p->buf, "dash:profile:isoff-live:2011") || + av_stristr(p->buf, "dash:profile:isoff-live:2012") || + av_stristr(p->buf, "dash:profile:isoff-main:2011")) { + return AVPROBE_SCORE_MAX; + } + if (av_stristr(p->buf, "dash:profile")) { + return AVPROBE_SCORE_MAX; + } + + return 0; +} + +#define OFFSET(x) offsetof(DASHContext, x) +#define FLAGS AV_OPT_FLAG_DECODING_PARAM +static const AVOption dash_options[] = { + {"allowed_extensions", "List of file extensions that dash is allowed to access", + OFFSET(allowed_extensions), AV_OPT_TYPE_STRING, + {.str = "aac,m4a,m4s,m4v,mov,mp4"}, + INT_MIN, INT_MAX, FLAGS}, + {NULL} +}; + +static const AVClass dash_class = { + .class_name = "dash", + .item_name = av_default_item_name, + .option = dash_options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVInputFormat ff_dash_demuxer = { + .name = "dash", + .long_name = NULL_IF_CONFIG_SMALL("Dynamic Adaptive Streaming over HTTP"), + .priv_class = &dash_class, + .priv_data_size = sizeof(DASHContext), + .read_probe = dash_probe, + .read_header = dash_read_header, + .read_packet = dash_read_packet, + .read_close = dash_close, + .read_seek = dash_read_seek, + .flags = AVFMT_NO_BYTE_SEEK, +}; From ab96e2ca81d7dd7d02c2b2176fc3dac85d9e8cb9 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Sat, 9 Sep 2017 08:34:07 +0800 Subject: [PATCH 3030/3374] avformat/dashdec: free resource allocated by xml modify from av_free to xmlFree Suggested-by: wm4 Signed-off-by: Steven Liu --- libavformat/dashdec.c | 44 +++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 9a3a199d4e094..f63f1fffbd33f 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -440,7 +440,7 @@ static char *get_content_url(xmlNodePtr *baseurl_nodes, memset(tmp_str_2, 0, sizeof(tmp_str_2)); ff_make_absolute_url(tmp_str_2, MAX_URL_SIZE, tmp_str, text); av_strlcpy(tmp_str, tmp_str_2, sizeof(tmp_str)); - av_free(text); + xmlFree(text); } } } @@ -515,7 +515,7 @@ static enum AVMediaType get_content_type(xmlNodePtr node) } else if (av_stristr((const char *)val, "audio")) { type = AVMEDIA_TYPE_AUDIO; } - av_free(val); + xmlFree(val); } } } @@ -536,7 +536,7 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati if (initialization_val) { rep->init_section = av_mallocz(sizeof(struct fragment)); if (!rep->init_section) { - av_free(initialization_val); + xmlFree(initialization_val); return AVERROR(ENOMEM); } rep->init_section->url = get_content_url(baseurl_nodes, 4, @@ -545,18 +545,18 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati initialization_val); if (!rep->init_section->url) { av_free(rep->init_section); - av_free(initialization_val); + xmlFree(initialization_val); return AVERROR(ENOMEM); } rep->init_section->size = -1; - av_free(initialization_val); + xmlFree(initialization_val); } } else if (!av_strcasecmp(fragmenturl_node->name, (const char *)"SegmentURL")) { media_val = xmlGetProp(fragmenturl_node, "media"); if (media_val) { struct fragment *seg = av_mallocz(sizeof(struct fragment)); if (!seg) { - av_free(media_val); + xmlFree(media_val); return AVERROR(ENOMEM); } seg->url = get_content_url(baseurl_nodes, 4, @@ -565,12 +565,12 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati media_val); if (!seg->url) { av_free(seg); - av_free(media_val); + xmlFree(media_val); return AVERROR(ENOMEM); } seg->size = -1; dynarray_add(&rep->fragments, &rep->n_fragments, seg); - av_free(media_val); + xmlFree(media_val); } } @@ -605,7 +605,7 @@ static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representat tml->duration = (int64_t)strtoll(val, NULL, 10); } attr = attr->next; - av_free(val); + xmlFree(val); } dynarray_add(&rep->timelines, &rep->n_timelines, tml); } @@ -699,29 +699,29 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, goto end; } rep->init_section->size = -1; - av_free(initialization_val); + xmlFree(initialization_val); } if (media_val) { rep->url_template = get_content_url(baseurl_nodes, 4, rep_id_val, rep_bandwidth_val, media_val); - av_free(media_val); + xmlFree(media_val); } if (presentation_timeoffset_val) { rep->presentation_timeoffset = (int64_t) strtoll(presentation_timeoffset_val, NULL, 10); - av_free(presentation_timeoffset_val); + xmlFree(presentation_timeoffset_val); } if (duration_val) { rep->fragment_duration = (int64_t) strtoll(duration_val, NULL, 10); - av_free(duration_val); + xmlFree(duration_val); } if (timescale_val) { rep->fragment_timescale = (int64_t) strtoll(timescale_val, NULL, 10); - av_free(timescale_val); + xmlFree(timescale_val); } if (startnumber_val) { rep->first_seq_no = (int64_t) strtoll(startnumber_val, NULL, 10); - av_free(startnumber_val); + xmlFree(startnumber_val); } fragment_timeline_node = find_child_node_by_name(representation_segmenttemplate_node, "SegmentTimeline"); @@ -760,11 +760,11 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, timescale_val = xmlGetProp(representation_segmentlist_node, "timescale"); if (duration_val) { rep->fragment_duration = (int64_t) strtoll(duration_val, NULL, 10); - av_free(duration_val); + xmlFree(duration_val); } if (timescale_val) { rep->fragment_timescale = (int64_t) strtoll(timescale_val, NULL, 10); - av_free(timescale_val); + xmlFree(timescale_val); } fragmenturl_node = xmlFirstElementChild(representation_segmentlist_node); while (fragmenturl_node) { @@ -816,9 +816,9 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, end: if (rep_id_val) - av_free(rep_id_val); + xmlFree(rep_id_val); if (rep_bandwidth_val) - av_free(rep_bandwidth_val); + xmlFree(rep_bandwidth_val); return ret; } @@ -941,7 +941,7 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) } if (!av_strcasecmp(val, (const char *)"dynamic")) c->is_live = 1; - av_free(val); + xmlFree(val); attr = node->properties; while (attr) { @@ -963,7 +963,7 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) c->media_presentation_duration = get_duration_insec(s, (const char *)val); } attr = attr->next; - av_free(val); + xmlFree(val); } mpd_baseurl_node = find_child_node_by_name(node, "BaseURL"); @@ -983,7 +983,7 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) perdiod_start_sec = get_duration_insec(s, (const char *)val); } attr = attr->next; - av_free(val); + xmlFree(val); } if ((perdiod_duration_sec) >= (c->period_duration)) { period_node = node; From 7a6bd541528b4d00b52d422d02f01d42346e68df Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Tue, 30 Sep 2014 11:01:17 +0300 Subject: [PATCH 3031/3374] Add SUP/PGS subtitle muxer Fixes ticket #2208 --- Changelog | 1 + doc/general.texi | 2 +- libavformat/Makefile | 1 + libavformat/allformats.c | 2 +- libavformat/supenc.c | 96 ++++++++++++++++++++++++++++++++++++++++ libavformat/version.h | 2 +- 6 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 libavformat/supenc.c diff --git a/Changelog b/Changelog index 189a803ed32b2..e5524b5c0352d 100644 --- a/Changelog +++ b/Changelog @@ -44,6 +44,7 @@ version : - drop deprecated qtkit input device (use avfoundation instead) - despill video filter - haas audio filter +- SUP/PGS subtitle muxer version 3.3: - CrystalHD decoder moved to new decode API diff --git a/doc/general.texi b/doc/general.texi index 5299a9b58cade..a40400612ea03 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -530,7 +530,7 @@ library: @item Sony Wave64 (W64) @tab X @tab X @item SoX native format @tab X @tab X @item SUN AU format @tab X @tab X -@item SUP raw PGS subtitles @tab @tab X +@item SUP raw PGS subtitles @tab X @tab X @item SVAG @tab @tab X @tab Audio format used in Konami PS2 games. @item TDSC @tab @tab X diff --git a/libavformat/Makefile b/libavformat/Makefile index ac03e0d47157d..df709c29dd253 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -474,6 +474,7 @@ OBJS-$(CONFIG_STR_DEMUXER) += psxstr.o OBJS-$(CONFIG_SUBVIEWER1_DEMUXER) += subviewer1dec.o subtitles.o OBJS-$(CONFIG_SUBVIEWER_DEMUXER) += subviewerdec.o subtitles.o OBJS-$(CONFIG_SUP_DEMUXER) += supdec.o +OBJS-$(CONFIG_SUP_MUXER) += supenc.o OBJS-$(CONFIG_SVAG_DEMUXER) += svag.o OBJS-$(CONFIG_SWF_DEMUXER) += swfdec.o swf.o OBJS-$(CONFIG_SWF_MUXER) += swfenc.o swf.o diff --git a/libavformat/allformats.c b/libavformat/allformats.c index 416e5e1127aff..405ddb5ad9f00 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -303,7 +303,7 @@ static void register_all(void) REGISTER_DEMUXER (STL, stl); REGISTER_DEMUXER (SUBVIEWER1, subviewer1); REGISTER_DEMUXER (SUBVIEWER, subviewer); - REGISTER_DEMUXER (SUP, sup); + REGISTER_MUXDEMUX(SUP, sup); REGISTER_DEMUXER (SVAG, svag); REGISTER_MUXDEMUX(SWF, swf); REGISTER_DEMUXER (TAK, tak); diff --git a/libavformat/supenc.c b/libavformat/supenc.c new file mode 100644 index 0000000000000..f5f6b58c87f4a --- /dev/null +++ b/libavformat/supenc.c @@ -0,0 +1,96 @@ +/* + * SUP muxer + * Copyright (c) 2014 Petri Hintukainen + * + * 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 "internal.h" +#include "libavutil/intreadwrite.h" + +#define SUP_PGS_MAGIC 0x5047 /* "PG", big endian */ + +static int sup_write_packet(AVFormatContext *s, AVPacket *pkt) +{ + uint8_t *data = pkt->data; + size_t size = pkt->size; + uint32_t pts = 0, dts = 0; + + if (pkt->pts != AV_NOPTS_VALUE) { + pts = (uint32_t)pkt->pts; + } + if (pkt->dts != AV_NOPTS_VALUE) { + dts = (uint32_t)pkt->dts; + } + + /* + Split frame to segments. + mkvmerge stores multiple segments in one frame. + */ + while (size > 2) { + size_t len = AV_RB16(data + 1) + 3; + + if (len > size) { + av_log(s, AV_LOG_ERROR, "Not enough data, skipping %d bytes\n", + (int)size); + return AVERROR_INVALIDDATA; + } + + /* header */ + avio_wb16(s->pb, SUP_PGS_MAGIC); + avio_wb32(s->pb, pts); + avio_wb32(s->pb, dts); + + avio_write(s->pb, data, len); + + data += len; + size -= len; + } + + if (size > 0) { + av_log(s, AV_LOG_ERROR, "Skipping %d bytes after last segment in frame\n", + (int)size); + return AVERROR_INVALIDDATA; + } + + return 0; +} + +static int sup_write_header(AVFormatContext *s) +{ + if (s->nb_streams != 1) { + av_log(s, AV_LOG_ERROR, "%s files have exactly one stream\n", + s->oformat->name); + return AVERROR(EINVAL); + } + + avpriv_set_pts_info(s->streams[0], 32, 1, 90000); + + return 0; +} + +AVOutputFormat ff_sup_muxer = { + .name = "sup", + .long_name = NULL_IF_CONFIG_SMALL("raw HDMV Presentation Graphic Stream subtitles"), + .extensions = "sup", + .mime_type = "application/x-pgs", + .subtitle_codec = AV_CODEC_ID_HDMV_PGS_SUBTITLE, + .write_header = sup_write_header, + .write_packet = sup_write_packet, + .flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT, +}; diff --git a/libavformat/version.h b/libavformat/version.h index 9cca76ee00276..aeb594041028a 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ // 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 57 -#define LIBAVFORMAT_VERSION_MINOR 81 +#define LIBAVFORMAT_VERSION_MINOR 82 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ From a918f16f7ccc7eb75330c97036888cf05c14b311 Mon Sep 17 00:00:00 2001 From: Jun Zhao Date: Tue, 5 Sep 2017 23:07:15 -0400 Subject: [PATCH 3032/3374] lavc/vaapi_encode_mpeg2: fix frame rate calc error when use time_base. fix frame rate calc error when use time_base. Signed-off-by: Yun Zhou Signed-off-by: Jun Zhao Signed-off-by: Mark Thompson --- libavcodec/vaapi_encode_mpeg2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vaapi_encode_mpeg2.c b/libavcodec/vaapi_encode_mpeg2.c index fbddfa5d5a8ee..dc918884e89cc 100644 --- a/libavcodec/vaapi_encode_mpeg2.c +++ b/libavcodec/vaapi_encode_mpeg2.c @@ -208,7 +208,7 @@ static int vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx) if (avctx->framerate.num > 0 && avctx->framerate.den > 0) vseq->frame_rate = (float)avctx->framerate.num / avctx->framerate.den; else - vseq->frame_rate = (float)avctx->time_base.num / avctx->time_base.den; + vseq->frame_rate = (float)avctx->time_base.den / avctx->time_base.num; vseq->aspect_ratio_information = 1; vseq->vbv_buffer_size = avctx->rc_buffer_size / (16 * 1024); From 4d41db7a31db0c426294ee692fb816faba39eba3 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Thu, 31 Aug 2017 12:07:58 +0200 Subject: [PATCH 3033/3374] avfilter: add generic FFT video convolve filter Signed-off-by: Paul B Mahol --- Changelog | 1 + doc/filters.texi | 18 ++ libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/version.h | 2 +- libavfilter/vf_convolve.c | 418 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 440 insertions(+), 1 deletion(-) create mode 100644 libavfilter/vf_convolve.c diff --git a/Changelog b/Changelog index e5524b5c0352d..22928de4b9d0a 100644 --- a/Changelog +++ b/Changelog @@ -45,6 +45,7 @@ version : - despill video filter - haas audio filter - SUP/PGS subtitle muxer +- convolve video filter version 3.3: - CrystalHD decoder moved to new decode API diff --git a/doc/filters.texi b/doc/filters.texi index c3c54fdda5be0..4111532512629 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -6005,6 +6005,24 @@ convolution="-2 -1 0 -1 1 1 0 1 2:-2 -1 0 -1 1 1 0 1 2:-2 -1 0 -1 1 1 0 1 2:-2 - @end example @end itemize +@section convolve + +Apply 2D convolution of video stream in frequency domain using second stream +as impulse. + +The filter accepts the following options: + +@table @option +@item planes +Set which planes to process. + +@item impulse +Set which impulse video frames will be processed, can be @var{first} +or @var{all}. Default is @var{all}. +@end table + +The @code{convolve} filter also supports the @ref{framesync} options. + @section copy Copy the input video source unchanged to the output. This is mainly useful for diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 42686339085e9..510cf5ad1971a 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -150,6 +150,7 @@ OBJS-$(CONFIG_COLORLEVELS_FILTER) += vf_colorlevels.o OBJS-$(CONFIG_COLORMATRIX_FILTER) += vf_colormatrix.o OBJS-$(CONFIG_COLORSPACE_FILTER) += vf_colorspace.o colorspacedsp.o OBJS-$(CONFIG_CONVOLUTION_FILTER) += vf_convolution.o +OBJS-$(CONFIG_CONVOLVE_FILTER) += vf_convolve.o framesync2.o OBJS-$(CONFIG_COPY_FILTER) += vf_copy.o OBJS-$(CONFIG_COREIMAGE_FILTER) += vf_coreimage.o OBJS-$(CONFIG_COVER_RECT_FILTER) += vf_cover_rect.o lavfutils.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 9bbc6d6fdcb01..63e86721cdf56 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -162,6 +162,7 @@ static void register_all(void) REGISTER_FILTER(COLORMATRIX, colormatrix, vf); REGISTER_FILTER(COLORSPACE, colorspace, vf); REGISTER_FILTER(CONVOLUTION, convolution, vf); + REGISTER_FILTER(CONVOLVE, convolve, vf); REGISTER_FILTER(COPY, copy, vf); REGISTER_FILTER(COREIMAGE, coreimage, vf); REGISTER_FILTER(COVER_RECT, cover_rect, vf); diff --git a/libavfilter/version.h b/libavfilter/version.h index 38c56d876eb5c..5d6aa5fc706e1 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 6 -#define LIBAVFILTER_VERSION_MINOR 104 +#define LIBAVFILTER_VERSION_MINOR 105 #define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vf_convolve.c b/libavfilter/vf_convolve.c new file mode 100644 index 0000000000000..95280aa04ed9f --- /dev/null +++ b/libavfilter/vf_convolve.c @@ -0,0 +1,418 @@ +/* + * Copyright (c) 2017 Paul B Mahol + * + * 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 "libavutil/imgutils.h" +#include "libavutil/opt.h" +#include "libavutil/pixdesc.h" +#include "libavcodec/avfft.h" + +#include "avfilter.h" +#include "formats.h" +#include "framesync2.h" +#include "internal.h" +#include "video.h" + +typedef struct ConvolveContext { + const AVClass *class; + FFFrameSync fs; + + FFTContext *fft[4]; + FFTContext *ifft[4]; + + int fft_bits[4]; + int fft_len[4]; + int planewidth[4]; + int planeheight[4]; + + FFTComplex *fft_hdata[4]; + FFTComplex *fft_vdata[4]; + FFTComplex *fft_hdata_impulse[4]; + FFTComplex *fft_vdata_impulse[4]; + + int depth; + int planes; + int impulse; + int nb_planes; + int got_impulse[4]; +} ConvolveContext; + +#define OFFSET(x) offsetof(ConvolveContext, x) +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM + +static const AVOption convolve_options[] = { + { "planes", "set planes to convolve", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=7}, 0, 15, FLAGS }, + { "impulse", "when to process impulses", OFFSET(impulse), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, "impulse" }, + { "first", "process only first impulse, ignore rest", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "impulse" }, + { "all", "process all impulses", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "impulse" }, + { NULL }, +}; + +FRAMESYNC_DEFINE_CLASS(convolve, ConvolveContext, fs); + +static int query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pixel_fmts_fftfilt[] = { + AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV440P, + AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, + AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUV420P, + AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P, + AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, + AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, + AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV440P12, + AV_PIX_FMT_YUV420P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV444P14, + AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, + AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA444P9, + AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA444P10, + AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16, + AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, + AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, + AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, + AV_PIX_FMT_NONE + }; + + AVFilterFormats *fmts_list = ff_make_format_list(pixel_fmts_fftfilt); + if (!fmts_list) + return AVERROR(ENOMEM); + return ff_set_common_formats(ctx, fmts_list); +} + +static int config_input_main(AVFilterLink *inlink) +{ + ConvolveContext *s = inlink->dst->priv; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + int fft_bits, i; + + s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w); + s->planewidth[0] = s->planewidth[3] = inlink->w; + s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h); + s->planeheight[0] = s->planeheight[3] = inlink->h; + + s->nb_planes = desc->nb_components; + s->depth = desc->comp[0].depth; + + for (i = 0; i < s->nb_planes; i++) { + int w = s->planewidth[i]; + int h = s->planeheight[i]; + int n = FFMAX(w, h) * 10/9; + + for (fft_bits = 1; 1 << fft_bits < n; fft_bits++); + + s->fft_bits[i] = fft_bits; + s->fft_len[i] = 1 << s->fft_bits[i]; + + if (!(s->fft_hdata[i] = av_calloc(s->fft_len[i], s->fft_len[i] * sizeof(FFTComplex)))) + return AVERROR(ENOMEM); + + if (!(s->fft_vdata[i] = av_calloc(s->fft_len[i], s->fft_len[i] * sizeof(FFTComplex)))) + return AVERROR(ENOMEM); + + if (!(s->fft_hdata_impulse[i] = av_calloc(s->fft_len[i], s->fft_len[i] * sizeof(FFTComplex)))) + return AVERROR(ENOMEM); + + if (!(s->fft_vdata_impulse[i] = av_calloc(s->fft_len[i], s->fft_len[i] * sizeof(FFTComplex)))) + return AVERROR(ENOMEM); + } + + return 0; +} + +static int config_input_impulse(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + + if (ctx->inputs[0]->w != ctx->inputs[1]->w || + ctx->inputs[0]->h != ctx->inputs[1]->h) { + av_log(ctx, AV_LOG_ERROR, "Width and height of input videos must be same.\n"); + return AVERROR(EINVAL); + } + if (ctx->inputs[0]->format != ctx->inputs[1]->format) { + av_log(ctx, AV_LOG_ERROR, "Inputs must be of same pixel format.\n"); + return AVERROR(EINVAL); + } + + return 0; +} + +static void fft_horizontal(ConvolveContext *s, FFTComplex *fft_hdata, + AVFrame *in, int w, int h, int n, int plane, float scale) +{ + int y, x; + + for (y = 0; y < h; y++) { + if (s->depth == 8) { + const uint8_t *src = in->data[plane] + in->linesize[plane] * y; + + for (x = 0; x < w; x++) { + fft_hdata[y * n + x].re = src[x] * scale; + fft_hdata[y * n + x].im = 0; + } + } else { + const uint16_t *src = (const uint16_t *)(in->data[plane] + in->linesize[plane] * y); + + for (x = 0; x < w; x++) { + fft_hdata[y * n + x].re = src[x] * scale; + fft_hdata[y * n + x].im = 0; + } + } + for (; x < n; x++) { + fft_hdata[y * n + x].re = 0; + fft_hdata[y * n + x].im = 0; + } + } + + for (; y < n; y++) { + for (x = 0; x < n; x++) { + fft_hdata[y * n + x].re = 0; + fft_hdata[y * n + x].im = 0; + } + } + + for (y = 0; y < n; y++) { + av_fft_permute(s->fft[plane], fft_hdata + y * n); + av_fft_calc(s->fft[plane], fft_hdata + y * n); + } +} + +static void fft_vertical(ConvolveContext *s, FFTComplex *fft_hdata, FFTComplex *fft_vdata, + int n, int plane) +{ + int y, x; + + for (y = 0; y < n; y++) { + for (x = 0; x < n; x++) { + fft_vdata[y * n + x].re = fft_hdata[x * n + y].re; + fft_vdata[y * n + x].im = fft_hdata[x * n + y].im; + } + for (; x < n; x++) { + fft_vdata[y * n + x].re = 0; + fft_vdata[y * n + x].im = 0; + } + av_fft_permute(s->fft[plane], fft_vdata + y * n); + av_fft_calc(s->fft[plane], fft_vdata + y * n); + } +} + +static void ifft_vertical(ConvolveContext *s, int n, int plane) +{ + int y, x; + + for (y = 0; y < n; y++) { + av_fft_permute(s->ifft[plane], s->fft_vdata[plane] + y * n); + av_fft_calc(s->ifft[plane], s->fft_vdata[plane] + y * n); + for (x = 0; x < n; x++) { + s->fft_hdata[plane][x * n + y].re = s->fft_vdata[plane][y * n + x].re; + s->fft_hdata[plane][x * n + y].im = s->fft_vdata[plane][y * n + x].im; + } + } +} + +static void ifft_horizontal(ConvolveContext *s, AVFrame *out, + int w, int h, int n, int plane) +{ + const float scale = 1.f / (n * n); + const int max = (1 << s->depth) - 1; + const int oh = h / 2; + const int ow = w / 2; + int y, x; + + for (y = 0; y < n; y++) { + av_fft_permute(s->ifft[plane], s->fft_hdata[plane] + y * n); + av_fft_calc(s->ifft[plane], s->fft_hdata[plane] + y * n); + } + + if (s->depth == 8) { + for (y = 0; y < h; y++) { + uint8_t *dst = out->data[plane] + y * out->linesize[plane]; + for (x = 0; x < w; x++) + dst[x] = av_clip(s->fft_hdata[plane][(y+oh) * n + x+ow].re * scale, 0, 255); + } + } else { + for (y = 0; y < h; y++) { + uint16_t *dst = (uint16_t *)(out->data[plane] + y * out->linesize[plane]); + for (x = 0; x < w; x++) + dst[x] = av_clip(s->fft_hdata[plane][(y+oh) * n + x+ow].re * scale, 0, max); + } + } +} + +static int do_convolve(FFFrameSync *fs) +{ + AVFilterContext *ctx = fs->parent; + AVFilterLink *outlink = ctx->outputs[0]; + ConvolveContext *s = ctx->priv; + AVFrame *mainpic = NULL, *impulsepic = NULL; + int ret, y, x, plane; + + ret = ff_framesync2_dualinput_get(fs, &mainpic, &impulsepic); + if (ret < 0) + return ret; + if (!impulsepic) + return ff_filter_frame(outlink, mainpic); + + for (plane = 0; plane < s->nb_planes; plane++) { + const int n = s->fft_len[plane]; + const int w = s->planewidth[plane]; + const int h = s->planeheight[plane]; + float total = 0; + + if (!(s->planes & (1 << plane))) { + continue; + } + + fft_horizontal(s, s->fft_hdata[plane], mainpic, w, h, n, plane, 1.f); + fft_vertical(s, s->fft_hdata[plane], s->fft_vdata[plane], + n, plane); + + if ((!s->impulse && !s->got_impulse[plane]) || s->impulse) { + if (s->depth == 8) { + for (y = 0; y < h; y++) { + const uint8_t *src = (const uint8_t *)(impulsepic->data[plane] + y * impulsepic->linesize[plane]) ; + for (x = 0; x < w; x++) { + total += src[x]; + } + } + } else { + for (y = 0; y < h; y++) { + const uint16_t *src = (const uint16_t *)(impulsepic->data[plane] + y * impulsepic->linesize[plane]) ; + for (x = 0; x < w; x++) { + total += src[x]; + } + } + } + total = FFMAX(1, total); + + fft_horizontal(s, s->fft_hdata_impulse[plane], impulsepic, w, h, n, plane, 1 / total); + fft_vertical(s, s->fft_hdata_impulse[plane], s->fft_vdata_impulse[plane], + n, plane); + + s->got_impulse[plane] = 1; + } + + for (y = 0; y < n; y++) { + for (x = 0; x < n; x++) { + FFTSample re, im, ire, iim; + + re = s->fft_vdata[plane][y*n + x].re; + im = s->fft_vdata[plane][y*n + x].im; + ire = s->fft_vdata_impulse[plane][y*n + x].re; + iim = s->fft_vdata_impulse[plane][y*n + x].im; + + s->fft_vdata[plane][y*n + x].re = ire * re - iim * im; + s->fft_vdata[plane][y*n + x].im = iim * re + ire * im; + } + } + + ifft_vertical(s, n, plane); + ifft_horizontal(s, mainpic, w, h, n, plane); + } + + return ff_filter_frame(outlink, mainpic); +} + +static int config_output(AVFilterLink *outlink) +{ + AVFilterContext *ctx = outlink->src; + ConvolveContext *s = ctx->priv; + AVFilterLink *mainlink = ctx->inputs[0]; + int ret, i; + + s->fs.on_event = do_convolve; + ret = ff_framesync2_init_dualinput(&s->fs, ctx); + if (ret < 0) + return ret; + outlink->w = mainlink->w; + outlink->h = mainlink->h; + outlink->time_base = mainlink->time_base; + outlink->sample_aspect_ratio = mainlink->sample_aspect_ratio; + outlink->frame_rate = mainlink->frame_rate; + + if ((ret = ff_framesync2_configure(&s->fs)) < 0) + return ret; + + for (i = 0; i < s->nb_planes; i++) { + s->fft[i] = av_fft_init(s->fft_bits[i], 0); + s->ifft[i] = av_fft_init(s->fft_bits[i], 1); + if (!s->fft[i] || !s->ifft[i]) + return AVERROR(ENOMEM); + } + + return 0; +} + +static int activate(AVFilterContext *ctx) +{ + ConvolveContext *s = ctx->priv; + return ff_framesync2_activate(&s->fs); +} + +static av_cold void uninit(AVFilterContext *ctx) +{ + ConvolveContext *s = ctx->priv; + int i; + + for (i = 0; i < 4; i++) { + av_freep(&s->fft_hdata[i]); + av_freep(&s->fft_vdata[i]); + av_freep(&s->fft_hdata_impulse[i]); + av_freep(&s->fft_vdata_impulse[i]); + av_fft_end(s->fft[i]); + av_fft_end(s->ifft[i]); + } + + ff_framesync2_uninit(&s->fs); +} + +static const AVFilterPad convolve_inputs[] = { + { + .name = "main", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = config_input_main, + },{ + .name = "impulse", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = config_input_impulse, + }, + { NULL } +}; + +static const AVFilterPad convolve_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = config_output, + }, + { NULL } +}; + +AVFilter ff_vf_convolve = { + .name = "convolve", + .description = NULL_IF_CONFIG_SMALL("Convolve first video stream with second video stream."), + .preinit = convolve_framesync_preinit, + .uninit = uninit, + .query_formats = query_formats, + .activate = activate, + .priv_size = sizeof(ConvolveContext), + .priv_class = &convolve_class, + .inputs = convolve_inputs, + .outputs = convolve_outputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, +}; From d98d29a775d6de9357731fec872642644e57b233 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 9 Sep 2017 15:51:45 +0200 Subject: [PATCH 3034/3374] avcodec/dirac_vlc: limit res_bits in APPEND_RESIDUE() Fixes: runtime error: left shift of 1073741838 by 1 places cannot be represented in type 'int32_t' (aka 'int') Fixes: 3279/clusterfuzz-testcase-minimized-4564805744590848 Suggested-by: Reviewed-by: Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/dirac_vlc.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/libavcodec/dirac_vlc.c b/libavcodec/dirac_vlc.c index bd37f31f469f3..496d8177cd886 100644 --- a/libavcodec/dirac_vlc.c +++ b/libavcodec/dirac_vlc.c @@ -37,7 +37,7 @@ #define APPEND_RESIDUE(N, M) \ N |= M >> (N ## _bits); \ - N ## _bits += (M ## _bits) + N ## _bits = (N ## _bits + (M ## _bits)) & 0x3F int ff_dirac_golomb_read_32bit(DiracGolombLUT *lut_ctx, const uint8_t *buf, int bytes, uint8_t *_dst, int coeffs) @@ -56,9 +56,6 @@ int ff_dirac_golomb_read_32bit(DiracGolombLUT *lut_ctx, const uint8_t *buf, if ((c_idx + 1) > coeffs) return c_idx; - if (res_bits >= RSIZE_BITS) - res_bits = res = 0; - /* res_bits is a hint for better branch prediction */ if (res_bits && l->sign) { int32_t coeff = 1; @@ -99,9 +96,6 @@ int ff_dirac_golomb_read_16bit(DiracGolombLUT *lut_ctx, const uint8_t *buf, if ((c_idx + 1) > coeffs) return c_idx; - if (res_bits >= RSIZE_BITS) - res_bits = res = 0; - if (res_bits && l->sign) { int32_t coeff = 1; APPEND_RESIDUE(res, l->preamble); From 27a86b8ece6fa86827da90ff39eba339cf8ff449 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 9 Sep 2017 22:02:25 -0300 Subject: [PATCH 3035/3374] avfilter/vf_convolve: use av_clip_uint8 Fixes fate-source. --- libavfilter/vf_convolve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_convolve.c b/libavfilter/vf_convolve.c index 95280aa04ed9f..63f38095981a2 100644 --- a/libavfilter/vf_convolve.c +++ b/libavfilter/vf_convolve.c @@ -243,7 +243,7 @@ static void ifft_horizontal(ConvolveContext *s, AVFrame *out, for (y = 0; y < h; y++) { uint8_t *dst = out->data[plane] + y * out->linesize[plane]; for (x = 0; x < w; x++) - dst[x] = av_clip(s->fft_hdata[plane][(y+oh) * n + x+ow].re * scale, 0, 255); + dst[x] = av_clip_uint8(s->fft_hdata[plane][(y+oh) * n + x+ow].re * scale); } } else { for (y = 0; y < h; y++) { From cbe181c8e1611aaee2a85ab522e17b1322bdd4de Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 28 Feb 2017 22:12:00 +0100 Subject: [PATCH 3036/3374] build: Skip generating .version files when cleaning Signed-off-by: James Almer --- ffbuild/library.mak | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ffbuild/library.mak b/ffbuild/library.mak index 22f1e4c37f68e..ee19c3c797c78 100644 --- a/ffbuild/library.mak +++ b/ffbuild/library.mak @@ -1,6 +1,8 @@ include $(SRC_PATH)/ffbuild/common.mak +ifeq (,$(filter %clean,$(MAKECMDGOALS))) -include $(SUBDIR)lib$(NAME).version +endif LIBVERSION := $(lib$(NAME)_VERSION) LIBMAJOR := $(lib$(NAME)_VERSION_MAJOR) From 981f04b2ae2d6e0355386aaff39840eb5d390a36 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 8 Sep 2017 23:29:13 +0200 Subject: [PATCH 3037/3374] avcodec/scpr: optimize shift loop. Speeds code up from 50sec to 15sec Fixes Timeout Fixes: 3242/clusterfuzz-testcase-5811951672229888 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Reviewed-by: James Almer Signed-off-by: Michael Niedermayer --- libavcodec/scpr.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/libavcodec/scpr.c b/libavcodec/scpr.c index 37fbe7a106469..cbe1bc40d9c81 100644 --- a/libavcodec/scpr.c +++ b/libavcodec/scpr.c @@ -826,8 +826,19 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (ret < 0) return ret; + // scale up each sample by 8 for (y = 0; y < avctx->height; y++) { - for (x = 0; x < avctx->width * 4; x++) { + // If the image is sufficiently aligned, compute 8 samples at once + if (!(((uintptr_t)dst) & 7)) { + uint64_t *dst64 = (uint64_t *)dst; + int w = avctx->width>>1; + for (x = 0; x < w; x++) { + dst64[x] = (dst64[x] << 3) & 0xFCFCFCFCFCFCFCFCULL; + } + x *= 8; + } else + x = 0; + for (; x < avctx->width * 4; x++) { dst[x] = dst[x] << 3; } dst += frame->linesize[0]; From 8e17cd20b9cd189b18c73d10391a7729edf44070 Mon Sep 17 00:00:00 2001 From: Jesse Liu Date: Sun, 10 Sep 2017 13:31:16 +0800 Subject: [PATCH 3038/3374] add missing ignore files Signed-off-by: Michael Niedermayer --- doc/examples/.gitignore | 1 + libavcodec/tests/.gitignore | 1 + libavutil/tests/.gitignore | 1 + 3 files changed, 3 insertions(+) diff --git a/doc/examples/.gitignore b/doc/examples/.gitignore index 6bd9dc15088a1..154c8415f6c4b 100644 --- a/doc/examples/.gitignore +++ b/doc/examples/.gitignore @@ -10,6 +10,7 @@ /filtering_audio /filtering_video /http_multiclient +/hw_decode /metadata /muxing /pc-uninstalled diff --git a/libavcodec/tests/.gitignore b/libavcodec/tests/.gitignore index 31947bf9bbc93..7f9e3825b6148 100644 --- a/libavcodec/tests/.gitignore +++ b/libavcodec/tests/.gitignore @@ -1,6 +1,7 @@ /avfft /avpacket /cabac +/celp_math /dct /fft /fft-fixed diff --git a/libavutil/tests/.gitignore b/libavutil/tests/.gitignore index a88cd97e50652..8ede0708870ed 100644 --- a/libavutil/tests/.gitignore +++ b/libavutil/tests/.gitignore @@ -34,6 +34,7 @@ /pca /pixdesc /pixelutils +/pixfmt_best /random_seed /rational /ripemd From b5995856a4236c27f231210bb08d70688e045192 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 10 Sep 2017 01:32:50 +0200 Subject: [PATCH 3039/3374] avcodec/diracdec: Fix overflow in DC computation Fixes: runtime error: signed integer overflow: 11896 + 2147483646 cannot be represented in type 'int' Fixes: 3053/clusterfuzz-testcase-minimized-6355082062856192 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/diracdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c index f2aed6057da1d..0abb8b05990b2 100644 --- a/libavcodec/diracdec.c +++ b/libavcodec/diracdec.c @@ -1421,7 +1421,7 @@ static void decode_block_params(DiracContext *s, DiracArith arith[8], DiracBlock if (!block->ref) { pred_block_dc(block, stride, x, y); for (i = 0; i < 3; i++) - block->u.dc[i] += dirac_get_arith_int(arith+1+i, CTX_DC_F1, CTX_DC_DATA); + block->u.dc[i] += (unsigned)dirac_get_arith_int(arith+1+i, CTX_DC_F1, CTX_DC_DATA); return; } From c225da68cffbea11270a758ff42859194c980863 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 10 Sep 2017 01:32:51 +0200 Subject: [PATCH 3040/3374] avcodec/hevcdsp_template: Fix undefined shift in put_hevc_pel_bi_w_pixels Fixes: runtime error: left shift of negative value -95 Fixes: 3077/clusterfuzz-testcase-minimized-4684917524922368 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/hevcdsp_template.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/hevcdsp_template.c b/libavcodec/hevcdsp_template.c index 25f1a812021eb..75763ce85e6e3 100644 --- a/libavcodec/hevcdsp_template.c +++ b/libavcodec/hevcdsp_template.c @@ -593,7 +593,7 @@ static void FUNC(put_hevc_pel_bi_w_pixels)(uint8_t *_dst, ptrdiff_t _dststride, ox1 = ox1 * (1 << (BIT_DEPTH - 8)); for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { - dst[x] = av_clip_pixel(( (src[x] << (14 - BIT_DEPTH)) * wx1 + src2[x] * wx0 + ((ox0 + ox1 + 1) << log2Wd)) >> (log2Wd + 1)); + dst[x] = av_clip_pixel(( (src[x] << (14 - BIT_DEPTH)) * wx1 + src2[x] * wx0 + (ox0 + ox1 + 1) * (1 << log2Wd)) >> (log2Wd + 1)); } src += srcstride; dst += dststride; From f0efd795f460aa64d06bb542c6eadd113c2585c2 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 10 Sep 2017 01:32:52 +0200 Subject: [PATCH 3041/3374] avcodec/clearvideo: Only output a frame if one is coded in the packet Fixes: Timeout (183 ms instead of about 20 sec) Fixes: 3147/clusterfuzz-testcase-4870592182353920 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/clearvideo.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/libavcodec/clearvideo.c b/libavcodec/clearvideo.c index a9fa0228bd92f..067942a131666 100644 --- a/libavcodec/clearvideo.c +++ b/libavcodec/clearvideo.c @@ -290,11 +290,6 @@ static int clv_decode_frame(AVCodecContext *avctx, void *data, } frame_type = bytestream2_get_byte(&gb); - if ((ret = ff_reget_buffer(avctx, c->pic)) < 0) - return ret; - - c->pic->key_frame = frame_type & 0x20 ? 1 : 0; - c->pic->pict_type = frame_type & 0x20 ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; if (frame_type & 0x2) { if (buf_size < c->mb_width * c->mb_height) { @@ -302,6 +297,12 @@ static int clv_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } + if ((ret = ff_reget_buffer(avctx, c->pic)) < 0) + return ret; + + c->pic->key_frame = frame_type & 0x20 ? 1 : 0; + c->pic->pict_type = frame_type & 0x20 ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; + bytestream2_get_be32(&gb); // frame size; c->ac_quant = bytestream2_get_byte(&gb); c->luma_dc_quant = 32; @@ -323,13 +324,13 @@ static int clv_decode_frame(AVCodecContext *avctx, void *data, mb_ret = ret; } } - } else { - } - if ((ret = av_frame_ref(data, c->pic)) < 0) - return ret; + if ((ret = av_frame_ref(data, c->pic)) < 0) + return ret; - *got_frame = 1; + *got_frame = 1; + } else { + } return mb_ret < 0 ? mb_ret : buf_size; } From 2d025e742843ca3532bd49ebbfebeacd51337347 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 8 Sep 2017 23:29:12 +0200 Subject: [PATCH 3042/3374] avcodec/jpeg2000dsp: Fix multiple integer overflows in ict_int() Fixes: runtime error: signed integer overflow: 22553 * -188962 cannot be represented in type 'int' Fixes: 3042/clusterfuzz-testcase-minimized-5174210131394560 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/jpeg2000dsp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/jpeg2000dsp.c b/libavcodec/jpeg2000dsp.c index c746aed9248f0..85a12d0e9b715 100644 --- a/libavcodec/jpeg2000dsp.c +++ b/libavcodec/jpeg2000dsp.c @@ -65,9 +65,9 @@ static void ict_int(void *_src0, void *_src1, void *_src2, int csize) for (i = 0; i < csize; i++) { i0 = *src0 + *src2 + (((26345 * *src2) + (1 << 15)) >> 16); - i1 = *src0 - (((i_ict_params[1] * *src1) + (1 << 15)) >> 16) + i1 = *src0 - ((int)(((unsigned)i_ict_params[1] * *src1) + (1 << 15)) >> 16) - (((i_ict_params[2] * *src2) + (1 << 15)) >> 16); - i2 = *src0 + (2 * *src1) + (((-14942 * *src1) + (1 << 15)) >> 16); + i2 = *src0 + (2 * *src1) + ((int)((-14942U * *src1) + (1 << 15)) >> 16); *src0++ = i0; *src1++ = i1; *src2++ = i2; From 9bab39dee52a44ff97975aafc70b8b428d8ca7b6 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sat, 9 Sep 2017 23:24:31 -0400 Subject: [PATCH 3043/3374] vp9: fix compilation with threading disabled. --- libavcodec/vp9.c | 15 +++++++++------ libavcodec/vp9dec.h | 2 ++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index a71045e08130e..f626f815b9c0f 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -88,10 +88,8 @@ static void vp9_await_tile_progress(VP9Context *s, int field, int n) { pthread_mutex_unlock(&s->progress_mutex); } #else -static void vp9_free_entries(VP9Context *s) {} +static void vp9_free_entries(AVCodecContext *avctx) {} static int vp9_alloc_entries(AVCodecContext *avctx, int n) { return 0; } -static void vp9_report_tile_progress(VP9Context *s, int field, int n) {} -static void vp9_await_tile_progress(VP9Context *s, int field, int n) {} #endif static void vp9_frame_unref(AVCodecContext *avctx, VP9Frame *f) @@ -1343,7 +1341,7 @@ static int decode_tiles(AVCodecContext *avctx, return 0; } - +#if HAVE_THREADS static av_always_inline int decode_tiles_mt(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr) @@ -1451,7 +1449,7 @@ int loopfilter_proc(AVCodecContext *avctx) } return 0; } - +#endif static int vp9_decode_frame(AVCodecContext *avctx, void *frame, int *got_frame, AVPacket *pkt) @@ -1583,10 +1581,12 @@ FF_ENABLE_DEPRECATION_WARNINGS ff_thread_finish_setup(avctx); } +#if HAVE_THREADS if (avctx->active_thread_type & FF_THREAD_SLICE) { for (i = 0; i < s->sb_rows; i++) atomic_store(&s->entries[i], 0); } +#endif do { for (i = 0; i < s->active_tile_cols; i++) { @@ -1599,6 +1599,7 @@ FF_ENABLE_DEPRECATION_WARNINGS s->td[i].uveob[1] = s->td[i].uveob_base[1]; } +#if HAVE_THREADS if (avctx->active_thread_type == FF_THREAD_SLICE) { int tile_row, tile_col; @@ -1629,7 +1630,9 @@ FF_ENABLE_DEPRECATION_WARNINGS } ff_slice_thread_execute_with_mainfunc(avctx, decode_tiles_mt, loopfilter_proc, s->td, NULL, s->s.h.tiling.tile_cols); - } else { + } else +#endif + { ret = decode_tiles(avctx, data, size); if (ret < 0) return ret; diff --git a/libavcodec/vp9dec.h b/libavcodec/vp9dec.h index 15e0122918116..96c0e43cd2dae 100644 --- a/libavcodec/vp9dec.h +++ b/libavcodec/vp9dec.h @@ -98,9 +98,11 @@ typedef struct VP9Context { VP56RangeCoder c; int pass, active_tile_cols; +#if HAVE_THREADS pthread_mutex_t progress_mutex; pthread_cond_t progress_cond; atomic_int *entries; +#endif uint8_t ss_h, ss_v; uint8_t last_bpp, bpp_index, bytesperpixel; From 86eb50549a575deff189ca6f649c6cb739525151 Mon Sep 17 00:00:00 2001 From: Ilia Valiakhmetov Date: Mon, 11 Sep 2017 01:18:36 +0700 Subject: [PATCH 3044/3374] Changelog: add vp9 tile threading support Signed-off-by: Ilia Valiakhmetov Signed-off-by: Ronald S. Bultje --- Changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog b/Changelog index 22928de4b9d0a..ca0758aca2abc 100644 --- a/Changelog +++ b/Changelog @@ -46,6 +46,7 @@ version : - haas audio filter - SUP/PGS subtitle muxer - convolve video filter +- VP9 tile threading support version 3.3: - CrystalHD decoder moved to new decode API From ad0d016f1cd2a626edeabae7f461b0043e660ee4 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Mon, 11 Sep 2017 22:40:46 +0800 Subject: [PATCH 3045/3374] MAINTAINERS: Add myself to maintainer of dashdec Add dash maintainer. --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 8a6ac9840f7b1..0b0f7fa1e451d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -394,6 +394,7 @@ Muxers/Demuxers: caf* Peter Ross cdxl.c Paul B Mahol crc.c Michael Niedermayer + dashdec.c Steven Liu daud.c Reimar Doeffinger dss.c Oleksij Rempel dtsdec.c foo86 From 4ce99e96d6115ccd1fc82f826d4c628240ef53ed Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 11 Sep 2017 15:41:24 -0400 Subject: [PATCH 3046/3374] vp9: assert -> av_assert and fix associated compile error. --- libavcodec/vp9.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index f626f815b9c0f..66ccb6c49ca01 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -1603,7 +1603,7 @@ FF_ENABLE_DEPRECATION_WARNINGS if (avctx->active_thread_type == FF_THREAD_SLICE) { int tile_row, tile_col; - assert(!pass); + av_assert1(!s->pass); for (tile_row = 0; tile_row < s->s.h.tiling.tile_rows; tile_row++) { for (tile_col = 0; tile_col < s->s.h.tiling.tile_cols; tile_col++) { From c9a1cd08eafe57d1fecaaf605929b3e68165a6e4 Mon Sep 17 00:00:00 2001 From: James Almer Date: Thu, 7 Sep 2017 21:23:04 -0300 Subject: [PATCH 3047/3374] avcodec/hevc_ps: improve check for missing default display window bitstream Fixes ticket #6644 Reviewed-by: Michael Niedermayer Signed-off-by: James Almer --- libavcodec/hevc_ps.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index ee31cc093c61c..eb104ca1b95ff 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -550,7 +550,7 @@ int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx, static void decode_vui(GetBitContext *gb, AVCodecContext *avctx, int apply_defdispwin, HEVCSPS *sps) { - VUI *vui = &sps->vui; + VUI backup_vui, *vui = &sps->vui; GetBitContext backup; int sar_present, alt = 0; @@ -618,13 +618,14 @@ static void decode_vui(GetBitContext *gb, AVCodecContext *avctx, vui->field_seq_flag = get_bits1(gb); vui->frame_field_info_present_flag = get_bits1(gb); + // Backup context in case an alternate header is detected + memcpy(&backup, gb, sizeof(backup)); + memcpy(&backup_vui, vui, sizeof(backup_vui)); if (get_bits_left(gb) >= 68 && show_bits_long(gb, 21) == 0x100000) { vui->default_display_window_flag = 0; av_log(avctx, AV_LOG_WARNING, "Invalid default display window\n"); } else vui->default_display_window_flag = get_bits1(gb); - // Backup context in case an alternate header is detected - memcpy(&backup, gb, sizeof(backup)); if (vui->default_display_window_flag) { int vert_mult = 1 + (sps->chroma_format_idc < 2); @@ -651,18 +652,19 @@ static void decode_vui(GetBitContext *gb, AVCodecContext *avctx, } } +timing_info: vui->vui_timing_info_present_flag = get_bits1(gb); if (vui->vui_timing_info_present_flag) { - if( get_bits_left(gb) < 66) { + if( get_bits_left(gb) < 66 && !alt) { // The alternate syntax seem to have timing info located // at where def_disp_win is normally located av_log(avctx, AV_LOG_WARNING, "Strange VUI timing information, retrying...\n"); - vui->default_display_window_flag = 0; - memset(&vui->def_disp_win, 0, sizeof(vui->def_disp_win)); + memcpy(vui, &backup_vui, sizeof(backup_vui)); memcpy(gb, &backup, sizeof(backup)); alt = 1; + goto timing_info; } vui->vui_num_units_in_tick = get_bits_long(gb, 32); vui->vui_time_scale = get_bits_long(gb, 32); @@ -680,6 +682,15 @@ static void decode_vui(GetBitContext *gb, AVCodecContext *avctx, vui->bitstream_restriction_flag = get_bits1(gb); if (vui->bitstream_restriction_flag) { + if (get_bits_left(gb) < 8 && !alt) { + av_log(avctx, AV_LOG_WARNING, + "Strange VUI bitstream restriction information, retrying" + " from timing information...\n"); + memcpy(vui, &backup_vui, sizeof(backup_vui)); + memcpy(gb, &backup, sizeof(backup)); + alt = 1; + goto timing_info; + } vui->tiles_fixed_structure_flag = get_bits1(gb); vui->motion_vectors_over_pic_boundaries_flag = get_bits1(gb); vui->restricted_ref_pic_lists_flag = get_bits1(gb); @@ -689,6 +700,16 @@ static void decode_vui(GetBitContext *gb, AVCodecContext *avctx, vui->log2_max_mv_length_horizontal = get_ue_golomb_long(gb); vui->log2_max_mv_length_vertical = get_ue_golomb_long(gb); } + + if (get_bits_left(gb) < 1 && !alt) { + // XXX: Alternate syntax when sps_range_extension_flag != 0? + av_log(avctx, AV_LOG_WARNING, + "Overread in VUI, retrying from timing information...\n"); + memcpy(vui, &backup_vui, sizeof(backup_vui)); + memcpy(gb, &backup, sizeof(backup)); + alt = 1; + goto timing_info; + } } static void set_default_scaling_list_data(ScalingList *sl) From 380659604f2692b625928a3a76a1c046f473c9f6 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 10 Sep 2017 21:10:16 +0200 Subject: [PATCH 3048/3374] avcodec/shorten: Move buffer allocation and offset init to end of read_header() They are time consuming operations, performing them after the other checks improves the speed with damaged input dramatically. Fixes: Timeout Fixes: 2928/clusterfuzz-testcase-4992812120539136 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Reviewed-by: Paul B Mahol Signed-off-by: Michael Niedermayer --- libavcodec/shorten.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c index 18b77300a07d6..49af6beec6af6 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -462,12 +462,6 @@ static int read_header(ShortenContext *s) } s->nwrap = FFMAX(NWRAP, maxnlpc); - if ((ret = allocate_buffers(s)) < 0) - return ret; - - if ((ret = init_offset(s)) < 0) - return ret; - if (s->version > 1) s->lpcqoffset = V2LPCQOFFSET; @@ -504,6 +498,13 @@ static int read_header(ShortenContext *s) } end: + + if ((ret = allocate_buffers(s)) < 0) + return ret; + + if ((ret = init_offset(s)) < 0) + return ret; + s->cur_chan = 0; s->bitshift = 0; From abf3f9fa232409c00b60041464604a91fa5612c0 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 10 Sep 2017 21:10:17 +0200 Subject: [PATCH 3049/3374] avcodec/hevc_ps: Fix c?_qp_offset_list size Fixes: runtime error: index 5 out of bounds for type 'int8_t const[5]' Fixes:3175/clusterfuzz-testcase-minimized-4736774054084608 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/hevc_ps.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/hevc_ps.h b/libavcodec/hevc_ps.h index 78f9dd876ec9d..4e6c3bc8496fc 100644 --- a/libavcodec/hevc_ps.h +++ b/libavcodec/hevc_ps.h @@ -366,8 +366,8 @@ typedef struct HEVCPPS { uint8_t chroma_qp_offset_list_enabled_flag; uint8_t diff_cu_chroma_qp_offset_depth; uint8_t chroma_qp_offset_list_len_minus1; - int8_t cb_qp_offset_list[5]; - int8_t cr_qp_offset_list[5]; + int8_t cb_qp_offset_list[6]; + int8_t cr_qp_offset_list[6]; uint8_t log2_sao_offset_scale_luma; uint8_t log2_sao_offset_scale_chroma; From e952d4b7ace607132130599905c75f25aaea9e56 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 10 Sep 2017 21:10:18 +0200 Subject: [PATCH 3050/3374] avcodec/hevc_ps: Fix limit of chroma_qp_offset_list_len_minus1 A value of 5 is allowed Signed-off-by: Michael Niedermayer --- libavcodec/hevc_ps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index eb104ca1b95ff..500fee03d86c2 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -1302,7 +1302,7 @@ static int pps_range_extensions(GetBitContext *gb, AVCodecContext *avctx, if (pps->chroma_qp_offset_list_enabled_flag) { pps->diff_cu_chroma_qp_offset_depth = get_ue_golomb_long(gb); pps->chroma_qp_offset_list_len_minus1 = get_ue_golomb_long(gb); - if (pps->chroma_qp_offset_list_len_minus1 && pps->chroma_qp_offset_list_len_minus1 >= 5) { + if (pps->chroma_qp_offset_list_len_minus1 > 5) { av_log(avctx, AV_LOG_ERROR, "chroma_qp_offset_list_len_minus1 shall be in the range [0, 5].\n"); return AVERROR_INVALIDDATA; From 76613618d978f9dbee0f391a85a732f77fac75cd Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Thu, 31 Aug 2017 17:05:04 +0200 Subject: [PATCH 3051/3374] lavfi: add helper functions and macros for activate. --- libavfilter/avfilter.c | 20 +++++++++++ libavfilter/filters.h | 78 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index e5c123818231b..58917ed44548d 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -1668,6 +1668,26 @@ void ff_inlink_request_frame(AVFilterLink *link) ff_filter_set_ready(link->src, 100); } +void ff_inlink_set_status(AVFilterLink *link, int status) +{ + if (link->status_out) + return; + link->frame_wanted_out = 0; + link->frame_blocked_in = 0; + ff_avfilter_link_set_out_status(link, status, AV_NOPTS_VALUE); + while (ff_framequeue_queued_frames(&link->fifo)) { + AVFrame *frame = ff_framequeue_take(&link->fifo); + av_frame_free(&frame); + } + if (!link->status_in) + link->status_in = status; +} + +int ff_outlink_get_status(AVFilterLink *link) +{ + return link->status_in; +} + const AVClass *avfilter_get_class(void) { return &avfilter_class; diff --git a/libavfilter/filters.h b/libavfilter/filters.h index 1cbc18158fcfe..4e2652ebe52cf 100644 --- a/libavfilter/filters.h +++ b/libavfilter/filters.h @@ -140,6 +140,12 @@ int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts */ void ff_inlink_request_frame(AVFilterLink *link); +/** + * Set the status on an input link. + * Also discard all frames in the link's FIFO. + */ +void ff_inlink_set_status(AVFilterLink *link, int status); + /** * Test if a frame is wanted on an output link. */ @@ -148,6 +154,11 @@ static inline int ff_outlink_frame_wanted(AVFilterLink *link) return link->frame_wanted_out; } +/** + * Get the status on an output link. + */ +int ff_outlink_get_status(AVFilterLink *link); + /** * Set the status field of a link from the source filter. * The pts should reflect the timestamp of the status change, @@ -160,4 +171,71 @@ static inline void ff_outlink_set_status(AVFilterLink *link, int status, int64_t ff_avfilter_link_set_in_status(link, status, pts); } +/** + * Forward the status on an output link to an input link. + * If the status is set, it will discard all queued frames and this macro + * will return immediately. + */ +#define FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink) do { \ + int ret = ff_outlink_get_status(outlink); \ + if (ret) { \ + ff_inlink_set_status(inlink, ret); \ + return 0; \ + } \ +} while (0) + +/** + * Forward the status on an output link to all input links. + * If the status is set, it will discard all queued frames and this macro + * will return immediately. + */ +#define FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, filter) do { \ + int ret = ff_outlink_get_status(outlink); \ + if (ret) { \ + unsigned i; \ + for (i = 0; i < filter->nb_inputs; i++) \ + ff_inlink_set_status(filter->inputs[i], ret); \ + return 0; \ + } \ +} while (0) + +/** + * Acknowledge the status on an input link and forward it to an output link. + * If the status is set, this macro will return immediately. + */ +#define FF_FILTER_FORWARD_STATUS(inlink, outlink) do { \ + int status; \ + int64_t pts; \ + if (ff_inlink_acknowledge_status(inlink, &status, &pts)) { \ + ff_outlink_set_status(outlink, status, pts); \ + return 0; \ + } \ +} while (0) + +/** + * Acknowledge the status on an input link and forward it to an output link. + * If the status is set, this macro will return immediately. + */ +#define FF_FILTER_FORWARD_STATUS_ALL(inlink, filter) do { \ + int status; \ + int64_t pts; \ + if (ff_inlink_acknowledge_status(inlink, &status, &pts)) { \ + unsigned i; \ + for (i = 0; i < filter->nb_outputs; i++) \ + ff_outlink_set_status(filter->outputs[i], status, pts); \ + return 0; \ + } \ +} while (0) + +/** + * Forward the frame_wanted_out flag from an output link to an input link. + * If the flag is set, this macro will return immediately. + */ +#define FF_FILTER_FORWARD_WANTED(outlink, inlink) do { \ + if (ff_outlink_frame_wanted(outlink)) { \ + ff_inlink_request_frame(inlink); \ + return 0; \ + } \ +} while (0) + #endif /* AVFILTER_FILTERS_H */ From 567d318b1cc11c7733dfe2f43a4bfe16c001865c Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Thu, 31 Aug 2017 16:53:35 +0200 Subject: [PATCH 3052/3374] lavfi/af_agate: use helper macros. --- libavfilter/af_agate.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/libavfilter/af_agate.c b/libavfilter/af_agate.c index f4fcabef93fd9..20905ccb19025 100644 --- a/libavfilter/af_agate.c +++ b/libavfilter/af_agate.c @@ -270,10 +270,10 @@ static int activate(AVFilterContext *ctx) { AudioGateContext *s = ctx->priv; AVFrame *out = NULL, *in[2] = { NULL }; - int ret, i, status, nb_samples; + int ret, i, nb_samples; double *dst; - int64_t pts; + FF_FILTER_FORWARD_STATUS_BACK_ALL(ctx->outputs[0], ctx); if ((ret = ff_inlink_consume_frame(ctx->inputs[0], &in[0])) > 0) { av_audio_fifo_write(s->fifo[0], (void **)in[0]->extended_data, in[0]->nb_samples); @@ -321,13 +321,9 @@ static int activate(AVFilterContext *ctx) if (ret < 0) return ret; } - if (ff_inlink_acknowledge_status(ctx->inputs[0], &status, &pts)) { - ff_outlink_set_status(ctx->outputs[0], status, pts); - return 0; - } else if (ff_inlink_acknowledge_status(ctx->inputs[1], &status, &pts)) { - ff_outlink_set_status(ctx->outputs[0], status, pts); - return 0; - } else { + FF_FILTER_FORWARD_STATUS(ctx->inputs[0], ctx->outputs[0]); + FF_FILTER_FORWARD_STATUS(ctx->inputs[1], ctx->outputs[0]); + /* TODO reindent */ if (ff_outlink_frame_wanted(ctx->outputs[0])) { if (!av_audio_fifo_size(s->fifo[0])) ff_inlink_request_frame(ctx->inputs[0]); @@ -335,7 +331,6 @@ static int activate(AVFilterContext *ctx) ff_inlink_request_frame(ctx->inputs[1]); } return 0; - } } static int scquery_formats(AVFilterContext *ctx) From 61b0b03f3fdc7553bd17325ad8932223a83ea816 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Thu, 31 Aug 2017 17:40:26 +0200 Subject: [PATCH 3053/3374] lavfi/af_sidechaincompress: use helper macros. --- libavfilter/af_sidechaincompress.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/libavfilter/af_sidechaincompress.c b/libavfilter/af_sidechaincompress.c index f174b70a5b06f..55bed438446c2 100644 --- a/libavfilter/af_sidechaincompress.c +++ b/libavfilter/af_sidechaincompress.c @@ -188,10 +188,10 @@ static int activate(AVFilterContext *ctx) { SidechainCompressContext *s = ctx->priv; AVFrame *out = NULL, *in[2] = { NULL }; - int ret, i, status, nb_samples; + int ret, i, nb_samples; double *dst; - int64_t pts; + FF_FILTER_FORWARD_STATUS_BACK_ALL(ctx->outputs[0], ctx); if ((ret = ff_inlink_consume_frame(ctx->inputs[0], &in[0])) > 0) { av_audio_fifo_write(s->fifo[0], (void **)in[0]->extended_data, in[0]->nb_samples); @@ -239,13 +239,9 @@ static int activate(AVFilterContext *ctx) if (ret < 0) return ret; } - if (ff_inlink_acknowledge_status(ctx->inputs[0], &status, &pts)) { - ff_outlink_set_status(ctx->outputs[0], status, pts); - return 0; - } else if (ff_inlink_acknowledge_status(ctx->inputs[1], &status, &pts)) { - ff_outlink_set_status(ctx->outputs[0], status, pts); - return 0; - } else { + FF_FILTER_FORWARD_STATUS(ctx->inputs[0], ctx->outputs[0]); + FF_FILTER_FORWARD_STATUS(ctx->inputs[1], ctx->outputs[0]); + /* TODO reindent */ if (ff_outlink_frame_wanted(ctx->outputs[0])) { if (!av_audio_fifo_size(s->fifo[0])) ff_inlink_request_frame(ctx->inputs[0]); @@ -253,7 +249,6 @@ static int activate(AVFilterContext *ctx) ff_inlink_request_frame(ctx->inputs[1]); } return 0; - } } static int query_formats(AVFilterContext *ctx) From 1b8e061cc574d7d5ce7def14c5648eaef07d9187 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Thu, 31 Aug 2017 17:42:57 +0200 Subject: [PATCH 3054/3374] lavfi: remove framesync. --- libavfilter/framesync.c | 343 ---------------------------------------- libavfilter/framesync.h | 297 ---------------------------------- 2 files changed, 640 deletions(-) delete mode 100644 libavfilter/framesync.c delete mode 100644 libavfilter/framesync.h diff --git a/libavfilter/framesync.c b/libavfilter/framesync.c deleted file mode 100644 index eb05d66a86eb6..0000000000000 --- a/libavfilter/framesync.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright (c) 2013 Nicolas George - * - * 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 - */ - -#define FF_INTERNAL_FIELDS 1 -#include "framequeue.h" - -#include "libavutil/avassert.h" -#include "avfilter.h" -#include "bufferqueue.h" -#include "framesync.h" -#include "internal.h" - -#define OFFSET(member) offsetof(FFFrameSync, member) - -static const char *framesync_name(void *ptr) -{ - return "framesync"; -} - -static const AVClass framesync_class = { - .version = LIBAVUTIL_VERSION_INT, - .class_name = "framesync", - .item_name = framesync_name, - .category = AV_CLASS_CATEGORY_FILTER, - .option = NULL, - .parent_log_context_offset = OFFSET(parent), -}; - -enum { - STATE_BOF, - STATE_RUN, - STATE_EOF, -}; - -int ff_framesync_init(FFFrameSync *fs, void *parent, unsigned nb_in) -{ - fs->class = &framesync_class; - fs->parent = parent; - fs->nb_in = nb_in; - - fs->in = av_calloc(nb_in, sizeof(*fs->in)); - if (!fs->in) - return AVERROR(ENOMEM); - return 0; -} - -static void framesync_sync_level_update(FFFrameSync *fs) -{ - unsigned i, level = 0; - - for (i = 0; i < fs->nb_in; i++) - if (fs->in[i].state != STATE_EOF) - level = FFMAX(level, fs->in[i].sync); - av_assert0(level <= fs->sync_level); - if (level < fs->sync_level) - av_log(fs, AV_LOG_VERBOSE, "Sync level %u\n", level); - if (level) - fs->sync_level = level; - else - fs->eof = 1; -} - -int ff_framesync_configure(FFFrameSync *fs) -{ - unsigned i; - int64_t gcd, lcm; - - if (!fs->time_base.num) { - for (i = 0; i < fs->nb_in; i++) { - if (fs->in[i].sync) { - if (fs->time_base.num) { - gcd = av_gcd(fs->time_base.den, fs->in[i].time_base.den); - lcm = (fs->time_base.den / gcd) * fs->in[i].time_base.den; - if (lcm < AV_TIME_BASE / 2) { - fs->time_base.den = lcm; - fs->time_base.num = av_gcd(fs->time_base.num, - fs->in[i].time_base.num); - } else { - fs->time_base.num = 1; - fs->time_base.den = AV_TIME_BASE; - break; - } - } else { - fs->time_base = fs->in[i].time_base; - } - } - } - if (!fs->time_base.num) { - av_log(fs, AV_LOG_ERROR, "Impossible to set time base\n"); - return AVERROR(EINVAL); - } - av_log(fs, AV_LOG_VERBOSE, "Selected %d/%d time base\n", - fs->time_base.num, fs->time_base.den); - } - - for (i = 0; i < fs->nb_in; i++) - fs->in[i].pts = fs->in[i].pts_next = AV_NOPTS_VALUE; - fs->sync_level = UINT_MAX; - framesync_sync_level_update(fs); - - return 0; -} - -static void framesync_advance(FFFrameSync *fs) -{ - int latest; - unsigned i; - int64_t pts; - - if (fs->eof) - return; - while (!fs->frame_ready) { - latest = -1; - for (i = 0; i < fs->nb_in; i++) { - if (!fs->in[i].have_next) { - if (latest < 0 || fs->in[i].pts < fs->in[latest].pts) - latest = i; - } - } - if (latest >= 0) { - fs->in_request = latest; - break; - } - - pts = fs->in[0].pts_next; - for (i = 1; i < fs->nb_in; i++) - if (fs->in[i].pts_next < pts) - pts = fs->in[i].pts_next; - if (pts == INT64_MAX) { - fs->eof = 1; - break; - } - for (i = 0; i < fs->nb_in; i++) { - if (fs->in[i].pts_next == pts || - (fs->in[i].before == EXT_INFINITY && - fs->in[i].state == STATE_BOF)) { - av_frame_free(&fs->in[i].frame); - fs->in[i].frame = fs->in[i].frame_next; - fs->in[i].pts = fs->in[i].pts_next; - fs->in[i].frame_next = NULL; - fs->in[i].pts_next = AV_NOPTS_VALUE; - fs->in[i].have_next = 0; - fs->in[i].state = fs->in[i].frame ? STATE_RUN : STATE_EOF; - if (fs->in[i].sync == fs->sync_level && fs->in[i].frame) - fs->frame_ready = 1; - if (fs->in[i].state == STATE_EOF && - fs->in[i].after == EXT_STOP) - fs->eof = 1; - } - } - if (fs->eof) - fs->frame_ready = 0; - if (fs->frame_ready) - for (i = 0; i < fs->nb_in; i++) - if ((fs->in[i].state == STATE_BOF && - fs->in[i].before == EXT_STOP)) - fs->frame_ready = 0; - fs->pts = pts; - } -} - -static int64_t framesync_pts_extrapolate(FFFrameSync *fs, unsigned in, - int64_t pts) -{ - /* Possible enhancement: use the link's frame rate */ - return pts + 1; -} - -static void framesync_inject_frame(FFFrameSync *fs, unsigned in, AVFrame *frame) -{ - int64_t pts; - - av_assert0(!fs->in[in].have_next); - if (frame) { - pts = av_rescale_q(frame->pts, fs->in[in].time_base, fs->time_base); - frame->pts = pts; - } else { - pts = fs->in[in].state != STATE_RUN || fs->in[in].after == EXT_INFINITY - ? INT64_MAX : framesync_pts_extrapolate(fs, in, fs->in[in].pts); - fs->in[in].sync = 0; - framesync_sync_level_update(fs); - } - fs->in[in].frame_next = frame; - fs->in[in].pts_next = pts; - fs->in[in].have_next = 1; -} - -int ff_framesync_add_frame(FFFrameSync *fs, unsigned in, AVFrame *frame) -{ - av_assert1(in < fs->nb_in); - if (!fs->in[in].have_next) - framesync_inject_frame(fs, in, frame); - else - ff_bufqueue_add(fs, &fs->in[in].queue, frame); - return 0; -} - -void ff_framesync_next(FFFrameSync *fs) -{ - unsigned i; - - av_assert0(!fs->frame_ready); - for (i = 0; i < fs->nb_in; i++) - if (!fs->in[i].have_next && fs->in[i].queue.available) - framesync_inject_frame(fs, i, ff_bufqueue_get(&fs->in[i].queue)); - fs->frame_ready = 0; - framesync_advance(fs); -} - -void ff_framesync_drop(FFFrameSync *fs) -{ - fs->frame_ready = 0; -} - -int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, - unsigned get) -{ - AVFrame *frame; - unsigned need_copy = 0, i; - int64_t pts_next; - int ret; - - if (!fs->in[in].frame) { - *rframe = NULL; - return 0; - } - frame = fs->in[in].frame; - if (get) { - /* Find out if we need to copy the frame: is there another sync - stream, and do we know if its current frame will outlast this one? */ - pts_next = fs->in[in].have_next ? fs->in[in].pts_next : INT64_MAX; - for (i = 0; i < fs->nb_in && !need_copy; i++) - if (i != in && fs->in[i].sync && - (!fs->in[i].have_next || fs->in[i].pts_next < pts_next)) - need_copy = 1; - if (need_copy) { - if (!(frame = av_frame_clone(frame))) - return AVERROR(ENOMEM); - if ((ret = av_frame_make_writable(frame)) < 0) { - av_frame_free(&frame); - return ret; - } - } else { - fs->in[in].frame = NULL; - } - fs->frame_ready = 0; - } - *rframe = frame; - return 0; -} - -void ff_framesync_uninit(FFFrameSync *fs) -{ - unsigned i; - - for (i = 0; i < fs->nb_in; i++) { - av_frame_free(&fs->in[i].frame); - av_frame_free(&fs->in[i].frame_next); - ff_bufqueue_discard_all(&fs->in[i].queue); - } - - av_freep(&fs->in); -} - -int ff_framesync_process_frame(FFFrameSync *fs, unsigned all) -{ - int ret, count = 0; - - av_assert0(fs->on_event); - while (1) { - ff_framesync_next(fs); - if (fs->eof || !fs->frame_ready) - break; - if ((ret = fs->on_event(fs)) < 0) - return ret; - ff_framesync_drop(fs); - count++; - if (!all) - break; - } - if (!count && fs->eof) - return AVERROR_EOF; - return count; -} - -int ff_framesync_filter_frame(FFFrameSync *fs, AVFilterLink *inlink, - AVFrame *in) -{ - int ret; - - if ((ret = ff_framesync_process_frame(fs, 1)) < 0) - return ret; - if ((ret = ff_framesync_add_frame(fs, FF_INLINK_IDX(inlink), in)) < 0) - return ret; - if ((ret = ff_framesync_process_frame(fs, 0)) < 0) - return ret; - return 0; -} - -int ff_framesync_request_frame(FFFrameSync *fs, AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - int input, ret, i; - - if ((ret = ff_framesync_process_frame(fs, 0)) < 0) - return ret; - if (ret > 0) - return 0; - if (fs->eof) - return AVERROR_EOF; - input = fs->in_request; - /* Detect status change early */ - for (i = 0; i < fs->nb_in; i++) - if (!ff_framequeue_queued_frames(&ctx->inputs[i]->fifo) && - ctx->inputs[i]->status_in && !ctx->inputs[i]->status_out) - input = i; - ret = ff_request_frame(ctx->inputs[input]); - if (ret == AVERROR_EOF) { - if ((ret = ff_framesync_add_frame(fs, input, NULL)) < 0) - return ret; - if ((ret = ff_framesync_process_frame(fs, 0)) < 0) - return ret; - ret = 0; - } - return ret; -} diff --git a/libavfilter/framesync.h b/libavfilter/framesync.h deleted file mode 100644 index 7ba99d5d86151..0000000000000 --- a/libavfilter/framesync.h +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright (c) 2013 Nicolas George - * - * 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 - */ - -#ifndef AVFILTER_FRAMESYNC_H -#define AVFILTER_FRAMESYNC_H - -#include "bufferqueue.h" - -/* - * TODO - * Callback-based API similar to dualinput. - * Export convenient options. - */ - -/** - * This API is intended as a helper for filters that have several video - * input and need to combine them somehow. If the inputs have different or - * variable frame rate, getting the input frames to match requires a rather - * complex logic and a few user-tunable options. - * - * In this API, when a set of synchronized input frames is ready to be - * procesed is called a frame event. Frame event can be generated in - * response to input frames on any or all inputs and the handling of - * situations where some stream extend beyond the beginning or the end of - * others can be configured. - * - * The basic working of this API is the following: - * - * - When a frame is available on any input, add it using - * ff_framesync_add_frame(). - * - * - When a frame event is ready to be processed (i.e. after adding a frame - * or when requested on input): - * - call ff_framesync_next(); - * - if fs->frame_ready is true, process the frames; - * - call ff_framesync_drop(). - */ - -/** - * Stream extrapolation mode - * - * Describe how the frames of a stream are extrapolated before the first one - * and after EOF to keep sync with possibly longer other streams. - */ -enum FFFrameSyncExtMode { - - /** - * Completely stop all streams with this one. - */ - EXT_STOP, - - /** - * Ignore this stream and continue processing the other ones. - */ - EXT_NULL, - - /** - * Extend the frame to infinity. - */ - EXT_INFINITY, -}; - -/** - * Input stream structure - */ -typedef struct FFFrameSyncIn { - - /** - * Queue of incoming AVFrame, and NULL to mark EOF - */ - struct FFBufQueue queue; - - /** - * Extrapolation mode for timestamps before the first frame - */ - enum FFFrameSyncExtMode before; - - /** - * Extrapolation mode for timestamps after the last frame - */ - enum FFFrameSyncExtMode after; - - /** - * Time base for the incoming frames - */ - AVRational time_base; - - /** - * Current frame, may be NULL before the first one or after EOF - */ - AVFrame *frame; - - /** - * Next frame, for internal use - */ - AVFrame *frame_next; - - /** - * PTS of the current frame - */ - int64_t pts; - - /** - * PTS of the next frame, for internal use - */ - int64_t pts_next; - - /** - * Boolean flagging the next frame, for internal use - */ - uint8_t have_next; - - /** - * State: before first, in stream or after EOF, for internal use - */ - uint8_t state; - - /** - * Synchronization level: frames on input at the highest sync level will - * generate output frame events. - * - * For example, if inputs #0 and #1 have sync level 2 and input #2 has - * sync level 1, then a frame on either input #0 or #1 will generate a - * frame event, but not a frame on input #2 until both inputs #0 and #1 - * have reached EOF. - * - * If sync is 0, no frame event will be generated. - */ - unsigned sync; - -} FFFrameSyncIn; - -/** - * Frame sync structure. - */ -typedef struct FFFrameSync { - const AVClass *class; - void *parent; - - /** - * Number of input streams - */ - unsigned nb_in; - - /** - * Time base for the output events - */ - AVRational time_base; - - /** - * Timestamp of the current event - */ - int64_t pts; - - /** - * Callback called when a frame event is ready - */ - int (*on_event)(struct FFFrameSync *fs); - - /** - * Opaque pointer, not used by the API - */ - void *opaque; - - /** - * Index of the input that requires a request - */ - unsigned in_request; - - /** - * Synchronization level: only inputs with the same sync level are sync - * sources. - */ - unsigned sync_level; - - /** - * Flag indicating that a frame event is ready - */ - uint8_t frame_ready; - - /** - * Flag indicating that output has reached EOF. - */ - uint8_t eof; - - /** - * Pointer to array of inputs. - */ - FFFrameSyncIn *in; - -} FFFrameSync; - -/** - * Initialize a frame sync structure. - * - * The entire structure is expected to be already set to 0. - * - * @param fs frame sync structure to initialize - * @param parent parent object, used for logging - * @param nb_in number of inputs - * @return >= 0 for success or a negative error code - */ -int ff_framesync_init(FFFrameSync *fs, void *parent, unsigned nb_in); - -/** - * Configure a frame sync structure. - * - * Must be called after all options are set but before all use. - * - * @return >= 0 for success or a negative error code - */ -int ff_framesync_configure(FFFrameSync *fs); - -/** - * Free all memory currently allocated. - */ -void ff_framesync_uninit(FFFrameSync *fs); - -/** - * Add a frame to an input - * - * Typically called from the filter_frame() method. - * - * @param fs frame sync structure - * @param in index of the input - * @param frame input frame, or NULL for EOF - */ -int ff_framesync_add_frame(FFFrameSync *fs, unsigned in, AVFrame *frame); - -/** - * Prepare the next frame event. - * - * The status of the operation can be found in fs->frame_ready and fs->eof. - */ -void ff_framesync_next(FFFrameSync *fs); - -/** - * Drop the current frame event. - */ -void ff_framesync_drop(FFFrameSync *fs); - -/** - * Get the current frame in an input. - * - * @param fs frame sync structure - * @param in index of the input - * @param rframe used to return the current frame (or NULL) - * @param get if not zero, the calling code needs to get ownership of - * the returned frame; the current frame will either be - * duplicated or removed from the framesync structure - */ -int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, - unsigned get); - -/** - * Process one or several frame using the on_event callback. - * - * @return number of frames processed or negative error code - */ -int ff_framesync_process_frame(FFFrameSync *fs, unsigned all); - - -/** - * Accept a frame on a filter input. - * - * This function can be the complete implementation of all filter_frame - * methods of a filter using framesync. - */ -int ff_framesync_filter_frame(FFFrameSync *fs, AVFilterLink *inlink, - AVFrame *in); - -/** - * Request a frame on the filter output. - * - * This function can be the complete implementation of all filter_frame - * methods of a filter using framesync if it has only one output. - */ -int ff_framesync_request_frame(FFFrameSync *fs, AVFilterLink *outlink); - -#endif /* AVFILTER_FRAMESYNC_H */ From 5f5dcf44e3c40da8c2334b9d2e62f30739d644c0 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Thu, 31 Aug 2017 19:47:37 +0200 Subject: [PATCH 3055/3374] lavfi: rename framesync2 to framesync. --- libavfilter/Makefile | 50 +++++++++++------------ libavfilter/f_streamselect.c | 12 +++--- libavfilter/{framesync2.c => framesync.c} | 32 +++++++-------- libavfilter/{framesync2.h => framesync.h} | 42 +++++++++---------- libavfilter/maskedmerge.h | 2 +- libavfilter/vf_blend.c | 12 +++--- libavfilter/vf_convolve.c | 12 +++--- libavfilter/vf_displace.c | 16 ++++---- libavfilter/vf_hysteresis.c | 14 +++---- libavfilter/vf_libvmaf.c | 12 +++--- libavfilter/vf_lut2.c | 14 +++---- libavfilter/vf_lut3d.c | 12 +++--- libavfilter/vf_maskedclamp.c | 16 ++++---- libavfilter/vf_maskedmerge.c | 14 +++---- libavfilter/vf_mergeplanes.c | 12 +++--- libavfilter/vf_midequalizer.c | 14 +++---- libavfilter/vf_overlay.c | 12 +++--- libavfilter/vf_paletteuse.c | 12 +++--- libavfilter/vf_premultiply.c | 14 +++---- libavfilter/vf_psnr.c | 12 +++--- libavfilter/vf_remap.c | 16 ++++---- libavfilter/vf_ssim.c | 12 +++--- libavfilter/vf_stack.c | 12 +++--- libavfilter/vf_threshold.c | 18 ++++---- 24 files changed, 197 insertions(+), 197 deletions(-) rename libavfilter/{framesync2.c => framesync.c} (93%) rename libavfilter/{framesync2.h => framesync.h} (86%) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 510cf5ad1971a..8aa974e115a4a 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -67,7 +67,7 @@ OBJS-$(CONFIG_ASHOWINFO_FILTER) += af_ashowinfo.o OBJS-$(CONFIG_ASIDEDATA_FILTER) += f_sidedata.o OBJS-$(CONFIG_ASPLIT_FILTER) += split.o OBJS-$(CONFIG_ASTATS_FILTER) += af_astats.o -OBJS-$(CONFIG_ASTREAMSELECT_FILTER) += f_streamselect.o framesync2.o +OBJS-$(CONFIG_ASTREAMSELECT_FILTER) += f_streamselect.o framesync.o OBJS-$(CONFIG_ATEMPO_FILTER) += af_atempo.o OBJS-$(CONFIG_ATRIM_FILTER) += trim.o OBJS-$(CONFIG_AZMQ_FILTER) += f_zmq.o @@ -137,7 +137,7 @@ OBJS-$(CONFIG_BENCH_FILTER) += f_bench.o OBJS-$(CONFIG_BITPLANENOISE_FILTER) += vf_bitplanenoise.o OBJS-$(CONFIG_BLACKDETECT_FILTER) += vf_blackdetect.o OBJS-$(CONFIG_BLACKFRAME_FILTER) += vf_blackframe.o -OBJS-$(CONFIG_BLEND_FILTER) += vf_blend.o framesync2.o +OBJS-$(CONFIG_BLEND_FILTER) += vf_blend.o framesync.o OBJS-$(CONFIG_BOXBLUR_FILTER) += vf_boxblur.o OBJS-$(CONFIG_BWDIF_FILTER) += vf_bwdif.o OBJS-$(CONFIG_CHROMAKEY_FILTER) += vf_chromakey.o @@ -150,7 +150,7 @@ OBJS-$(CONFIG_COLORLEVELS_FILTER) += vf_colorlevels.o OBJS-$(CONFIG_COLORMATRIX_FILTER) += vf_colormatrix.o OBJS-$(CONFIG_COLORSPACE_FILTER) += vf_colorspace.o colorspacedsp.o OBJS-$(CONFIG_CONVOLUTION_FILTER) += vf_convolution.o -OBJS-$(CONFIG_CONVOLVE_FILTER) += vf_convolve.o framesync2.o +OBJS-$(CONFIG_CONVOLVE_FILTER) += vf_convolve.o framesync.o OBJS-$(CONFIG_COPY_FILTER) += vf_copy.o OBJS-$(CONFIG_COREIMAGE_FILTER) += vf_coreimage.o OBJS-$(CONFIG_COVER_RECT_FILTER) += vf_cover_rect.o lavfutils.o @@ -171,7 +171,7 @@ OBJS-$(CONFIG_DESHAKE_FILTER) += vf_deshake.o OBJS-$(CONFIG_DESPILL_FILTER) += vf_despill.o OBJS-$(CONFIG_DETELECINE_FILTER) += vf_detelecine.o OBJS-$(CONFIG_DILATION_FILTER) += vf_neighbor.o -OBJS-$(CONFIG_DISPLACE_FILTER) += vf_displace.o framesync2.o +OBJS-$(CONFIG_DISPLACE_FILTER) += vf_displace.o framesync.o OBJS-$(CONFIG_DOUBLEWEAVE_FILTER) += vf_weave.o OBJS-$(CONFIG_DRAWBOX_FILTER) += vf_drawbox.o OBJS-$(CONFIG_DRAWGRAPH_FILTER) += f_drawgraph.o @@ -200,19 +200,19 @@ OBJS-$(CONFIG_FSPP_FILTER) += vf_fspp.o OBJS-$(CONFIG_GBLUR_FILTER) += vf_gblur.o OBJS-$(CONFIG_GEQ_FILTER) += vf_geq.o OBJS-$(CONFIG_GRADFUN_FILTER) += vf_gradfun.o -OBJS-$(CONFIG_HALDCLUT_FILTER) += vf_lut3d.o framesync2.o +OBJS-$(CONFIG_HALDCLUT_FILTER) += vf_lut3d.o framesync.o OBJS-$(CONFIG_HFLIP_FILTER) += vf_hflip.o OBJS-$(CONFIG_HISTEQ_FILTER) += vf_histeq.o OBJS-$(CONFIG_HISTOGRAM_FILTER) += vf_histogram.o OBJS-$(CONFIG_HQDN3D_FILTER) += vf_hqdn3d.o OBJS-$(CONFIG_HQX_FILTER) += vf_hqx.o -OBJS-$(CONFIG_HSTACK_FILTER) += vf_stack.o framesync2.o +OBJS-$(CONFIG_HSTACK_FILTER) += vf_stack.o framesync.o OBJS-$(CONFIG_HUE_FILTER) += vf_hue.o OBJS-$(CONFIG_HWDOWNLOAD_FILTER) += vf_hwdownload.o OBJS-$(CONFIG_HWMAP_FILTER) += vf_hwmap.o OBJS-$(CONFIG_HWUPLOAD_CUDA_FILTER) += vf_hwupload_cuda.o OBJS-$(CONFIG_HWUPLOAD_FILTER) += vf_hwupload.o -OBJS-$(CONFIG_HYSTERESIS_FILTER) += vf_hysteresis.o framesync2.o +OBJS-$(CONFIG_HYSTERESIS_FILTER) += vf_hysteresis.o framesync.o OBJS-$(CONFIG_IDET_FILTER) += vf_idet.o OBJS-$(CONFIG_IL_FILTER) += vf_il.o OBJS-$(CONFIG_INFLATE_FILTER) += vf_neighbor.o @@ -220,22 +220,22 @@ OBJS-$(CONFIG_INTERLACE_FILTER) += vf_interlace.o OBJS-$(CONFIG_INTERLEAVE_FILTER) += f_interleave.o OBJS-$(CONFIG_KERNDEINT_FILTER) += vf_kerndeint.o OBJS-$(CONFIG_LENSCORRECTION_FILTER) += vf_lenscorrection.o -OBJS-$(CONFIG_LIBVMAF_FILTER) += vf_libvmaf.o framesync2.o +OBJS-$(CONFIG_LIBVMAF_FILTER) += vf_libvmaf.o framesync.o OBJS-$(CONFIG_LIMITER_FILTER) += vf_limiter.o OBJS-$(CONFIG_LOOP_FILTER) += f_loop.o OBJS-$(CONFIG_LUMAKEY_FILTER) += vf_lumakey.o OBJS-$(CONFIG_LUT_FILTER) += vf_lut.o -OBJS-$(CONFIG_LUT2_FILTER) += vf_lut2.o framesync2.o +OBJS-$(CONFIG_LUT2_FILTER) += vf_lut2.o framesync.o OBJS-$(CONFIG_LUT3D_FILTER) += vf_lut3d.o OBJS-$(CONFIG_LUTRGB_FILTER) += vf_lut.o OBJS-$(CONFIG_LUTYUV_FILTER) += vf_lut.o -OBJS-$(CONFIG_MASKEDCLAMP_FILTER) += vf_maskedclamp.o framesync2.o -OBJS-$(CONFIG_MASKEDMERGE_FILTER) += vf_maskedmerge.o framesync2.o +OBJS-$(CONFIG_MASKEDCLAMP_FILTER) += vf_maskedclamp.o framesync.o +OBJS-$(CONFIG_MASKEDMERGE_FILTER) += vf_maskedmerge.o framesync.o OBJS-$(CONFIG_MCDEINT_FILTER) += vf_mcdeint.o -OBJS-$(CONFIG_MERGEPLANES_FILTER) += vf_mergeplanes.o framesync2.o +OBJS-$(CONFIG_MERGEPLANES_FILTER) += vf_mergeplanes.o framesync.o OBJS-$(CONFIG_MESTIMATE_FILTER) += vf_mestimate.o motion_estimation.o OBJS-$(CONFIG_METADATA_FILTER) += f_metadata.o -OBJS-$(CONFIG_MIDEQUALIZER_FILTER) += vf_midequalizer.o framesync2.o +OBJS-$(CONFIG_MIDEQUALIZER_FILTER) += vf_midequalizer.o framesync.o OBJS-$(CONFIG_MINTERPOLATE_FILTER) += vf_minterpolate.o motion_estimation.o OBJS-$(CONFIG_MPDECIMATE_FILTER) += vf_mpdecimate.o OBJS-$(CONFIG_NEGATE_FILTER) += vf_lut.o @@ -248,11 +248,11 @@ OBJS-$(CONFIG_OCR_FILTER) += vf_ocr.o OBJS-$(CONFIG_OCV_FILTER) += vf_libopencv.o OBJS-$(CONFIG_OPENCL) += deshake_opencl.o unsharp_opencl.o OBJS-$(CONFIG_OSCILLOSCOPE_FILTER) += vf_datascope.o -OBJS-$(CONFIG_OVERLAY_FILTER) += vf_overlay.o framesync2.o +OBJS-$(CONFIG_OVERLAY_FILTER) += vf_overlay.o framesync.o OBJS-$(CONFIG_OWDENOISE_FILTER) += vf_owdenoise.o OBJS-$(CONFIG_PAD_FILTER) += vf_pad.o OBJS-$(CONFIG_PALETTEGEN_FILTER) += vf_palettegen.o -OBJS-$(CONFIG_PALETTEUSE_FILTER) += vf_paletteuse.o framesync2.o +OBJS-$(CONFIG_PALETTEUSE_FILTER) += vf_paletteuse.o framesync.o OBJS-$(CONFIG_PERMS_FILTER) += f_perms.o OBJS-$(CONFIG_PERSPECTIVE_FILTER) += vf_perspective.o OBJS-$(CONFIG_PHASE_FILTER) += vf_phase.o @@ -260,17 +260,17 @@ OBJS-$(CONFIG_PIXDESCTEST_FILTER) += vf_pixdesctest.o OBJS-$(CONFIG_PIXSCOPE_FILTER) += vf_datascope.o OBJS-$(CONFIG_PP_FILTER) += vf_pp.o OBJS-$(CONFIG_PP7_FILTER) += vf_pp7.o -OBJS-$(CONFIG_PREMULTIPLY_FILTER) += vf_premultiply.o framesync2.o +OBJS-$(CONFIG_PREMULTIPLY_FILTER) += vf_premultiply.o framesync.o OBJS-$(CONFIG_PREWITT_FILTER) += vf_convolution.o OBJS-$(CONFIG_PSEUDOCOLOR_FILTER) += vf_pseudocolor.o -OBJS-$(CONFIG_PSNR_FILTER) += vf_psnr.o framesync2.o +OBJS-$(CONFIG_PSNR_FILTER) += vf_psnr.o framesync.o OBJS-$(CONFIG_PULLUP_FILTER) += vf_pullup.o OBJS-$(CONFIG_QP_FILTER) += vf_qp.o OBJS-$(CONFIG_RANDOM_FILTER) += vf_random.o OBJS-$(CONFIG_READEIA608_FILTER) += vf_readeia608.o OBJS-$(CONFIG_READVITC_FILTER) += vf_readvitc.o OBJS-$(CONFIG_REALTIME_FILTER) += f_realtime.o -OBJS-$(CONFIG_REMAP_FILTER) += vf_remap.o framesync2.o +OBJS-$(CONFIG_REMAP_FILTER) += vf_remap.o framesync.o OBJS-$(CONFIG_REMOVEGRAIN_FILTER) += vf_removegrain.o OBJS-$(CONFIG_REMOVELOGO_FILTER) += bbox.o lswsutils.o lavfutils.o vf_removelogo.o OBJS-$(CONFIG_REPEATFIELDS_FILTER) += vf_repeatfields.o @@ -304,24 +304,24 @@ OBJS-$(CONFIG_SMARTBLUR_FILTER) += vf_smartblur.o OBJS-$(CONFIG_SOBEL_FILTER) += vf_convolution.o OBJS-$(CONFIG_SPLIT_FILTER) += split.o OBJS-$(CONFIG_SPP_FILTER) += vf_spp.o -OBJS-$(CONFIG_SSIM_FILTER) += vf_ssim.o framesync2.o +OBJS-$(CONFIG_SSIM_FILTER) += vf_ssim.o framesync.o OBJS-$(CONFIG_STEREO3D_FILTER) += vf_stereo3d.o -OBJS-$(CONFIG_STREAMSELECT_FILTER) += f_streamselect.o framesync2.o +OBJS-$(CONFIG_STREAMSELECT_FILTER) += f_streamselect.o framesync.o OBJS-$(CONFIG_SUBTITLES_FILTER) += vf_subtitles.o OBJS-$(CONFIG_SUPER2XSAI_FILTER) += vf_super2xsai.o OBJS-$(CONFIG_SWAPRECT_FILTER) += vf_swaprect.o OBJS-$(CONFIG_SWAPUV_FILTER) += vf_swapuv.o -OBJS-$(CONFIG_TBLEND_FILTER) += vf_blend.o framesync2.o +OBJS-$(CONFIG_TBLEND_FILTER) += vf_blend.o framesync.o OBJS-$(CONFIG_TELECINE_FILTER) += vf_telecine.o -OBJS-$(CONFIG_THRESHOLD_FILTER) += vf_threshold.o framesync2.o +OBJS-$(CONFIG_THRESHOLD_FILTER) += vf_threshold.o framesync.o OBJS-$(CONFIG_THUMBNAIL_FILTER) += vf_thumbnail.o OBJS-$(CONFIG_TILE_FILTER) += vf_tile.o OBJS-$(CONFIG_TINTERLACE_FILTER) += vf_tinterlace.o -OBJS-$(CONFIG_TLUT2_FILTER) += vf_lut2.o framesync2.o +OBJS-$(CONFIG_TLUT2_FILTER) += vf_lut2.o framesync.o OBJS-$(CONFIG_TONEMAP_FILTER) += vf_tonemap.o OBJS-$(CONFIG_TRANSPOSE_FILTER) += vf_transpose.o OBJS-$(CONFIG_TRIM_FILTER) += trim.o -OBJS-$(CONFIG_UNPREMULTIPLY_FILTER) += vf_premultiply.o framesync2.o +OBJS-$(CONFIG_UNPREMULTIPLY_FILTER) += vf_premultiply.o framesync.o OBJS-$(CONFIG_UNSHARP_FILTER) += vf_unsharp.o OBJS-$(CONFIG_USPP_FILTER) += vf_uspp.o OBJS-$(CONFIG_VAGUEDENOISER_FILTER) += vf_vaguedenoiser.o @@ -330,7 +330,7 @@ OBJS-$(CONFIG_VFLIP_FILTER) += vf_vflip.o OBJS-$(CONFIG_VIDSTABDETECT_FILTER) += vidstabutils.o vf_vidstabdetect.o OBJS-$(CONFIG_VIDSTABTRANSFORM_FILTER) += vidstabutils.o vf_vidstabtransform.o OBJS-$(CONFIG_VIGNETTE_FILTER) += vf_vignette.o -OBJS-$(CONFIG_VSTACK_FILTER) += vf_stack.o framesync2.o +OBJS-$(CONFIG_VSTACK_FILTER) += vf_stack.o framesync.o OBJS-$(CONFIG_W3FDIF_FILTER) += vf_w3fdif.o OBJS-$(CONFIG_WAVEFORM_FILTER) += vf_waveform.o OBJS-$(CONFIG_WEAVE_FILTER) += vf_weave.o diff --git a/libavfilter/f_streamselect.c b/libavfilter/f_streamselect.c index 10607de9b89ae..923deb1a85486 100644 --- a/libavfilter/f_streamselect.c +++ b/libavfilter/f_streamselect.c @@ -22,7 +22,7 @@ #include "avfilter.h" #include "audio.h" #include "formats.h" -#include "framesync2.h" +#include "framesync.h" #include "internal.h" #include "video.h" @@ -56,7 +56,7 @@ static int process_frame(FFFrameSync *fs) int i, j, ret = 0; for (i = 0; i < ctx->nb_inputs; i++) { - if ((ret = ff_framesync2_get_frame(&s->fs, i, &in[i], 0)) < 0) + if ((ret = ff_framesync_get_frame(&s->fs, i, &in[i], 0)) < 0) return ret; } @@ -87,7 +87,7 @@ static int process_frame(FFFrameSync *fs) static int activate(AVFilterContext *ctx) { StreamSelectContext *s = ctx->priv; - return ff_framesync2_activate(&s->fs); + return ff_framesync_activate(&s->fs); } static int config_output(AVFilterLink *outlink) @@ -124,7 +124,7 @@ static int config_output(AVFilterLink *outlink) if (s->fs.opaque == s) return 0; - if ((ret = ff_framesync2_init(&s->fs, ctx, ctx->nb_inputs)) < 0) + if ((ret = ff_framesync_init(&s->fs, ctx, ctx->nb_inputs)) < 0) return ret; in = s->fs.in; @@ -142,7 +142,7 @@ static int config_output(AVFilterLink *outlink) if (!s->frames) return AVERROR(ENOMEM); - return ff_framesync2_configure(&s->fs); + return ff_framesync_configure(&s->fs); } static int parse_definition(AVFilterContext *ctx, int nb_pads, int is_input, int is_audio) @@ -289,7 +289,7 @@ static av_cold void uninit(AVFilterContext *ctx) av_freep(&s->last_pts); av_freep(&s->map); av_freep(&s->frames); - ff_framesync2_uninit(&s->fs); + ff_framesync_uninit(&s->fs); } static int query_formats(AVFilterContext *ctx) diff --git a/libavfilter/framesync2.c b/libavfilter/framesync.c similarity index 93% rename from libavfilter/framesync2.c rename to libavfilter/framesync.c index aea9937ce9fbc..ebfbcaf090087 100644 --- a/libavfilter/framesync2.c +++ b/libavfilter/framesync.c @@ -22,7 +22,7 @@ #include "libavutil/opt.h" #include "avfilter.h" #include "filters.h" -#include "framesync2.h" +#include "framesync.h" #include "internal.h" #define OFFSET(member) offsetof(FFFrameSync, member) @@ -61,12 +61,12 @@ enum { static int consume_from_fifos(FFFrameSync *fs); -const AVClass *framesync2_get_class(void) +const AVClass *framesync_get_class(void) { return &framesync_class; } -void ff_framesync2_preinit(FFFrameSync *fs) +void ff_framesync_preinit(FFFrameSync *fs) { if (fs->class) return; @@ -74,14 +74,14 @@ void ff_framesync2_preinit(FFFrameSync *fs) av_opt_set_defaults(fs); } -int ff_framesync2_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in) +int ff_framesync_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in) { /* For filters with several outputs, we will not be able to assume which output is relevant for ff_outlink_frame_wanted() and ff_outlink_set_status(). To be designed when needed. */ av_assert0(parent->nb_outputs == 1); - ff_framesync2_preinit(fs); + ff_framesync_preinit(fs); fs->parent = parent; fs->nb_in = nb_in; @@ -114,7 +114,7 @@ static void framesync_sync_level_update(FFFrameSync *fs) framesync_eof(fs); } -int ff_framesync2_configure(FFFrameSync *fs) +int ff_framesync_configure(FFFrameSync *fs) { unsigned i; int64_t gcd, lcm; @@ -253,7 +253,7 @@ static void framesync_inject_status(FFFrameSync *fs, unsigned in, int status, in fs->in[in].have_next = 1; } -int ff_framesync2_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, +int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, unsigned get) { AVFrame *frame; @@ -290,7 +290,7 @@ int ff_framesync2_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, return 0; } -void ff_framesync2_uninit(FFFrameSync *fs) +void ff_framesync_uninit(FFFrameSync *fs) { unsigned i; @@ -341,7 +341,7 @@ static int consume_from_fifos(FFFrameSync *fs) return 1; } -int ff_framesync2_activate(FFFrameSync *fs) +int ff_framesync_activate(FFFrameSync *fs) { int ret; @@ -358,11 +358,11 @@ int ff_framesync2_activate(FFFrameSync *fs) return 0; } -int ff_framesync2_init_dualinput(FFFrameSync *fs, AVFilterContext *parent) +int ff_framesync_init_dualinput(FFFrameSync *fs, AVFilterContext *parent) { int ret; - ret = ff_framesync2_init(fs, parent, 2); + ret = ff_framesync_init(fs, parent, 2); if (ret < 0) return ret; fs->in[0].time_base = parent->inputs[0]->time_base; @@ -376,14 +376,14 @@ int ff_framesync2_init_dualinput(FFFrameSync *fs, AVFilterContext *parent) return 0; } -int ff_framesync2_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1) +int ff_framesync_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1) { AVFilterContext *ctx = fs->parent; AVFrame *mainpic = NULL, *secondpic = NULL; int ret = 0; - if ((ret = ff_framesync2_get_frame(fs, 0, &mainpic, 1)) < 0 || - (ret = ff_framesync2_get_frame(fs, 1, &secondpic, 0)) < 0) { + if ((ret = ff_framesync_get_frame(fs, 0, &mainpic, 1)) < 0 || + (ret = ff_framesync_get_frame(fs, 1, &secondpic, 0)) < 0) { av_frame_free(&mainpic); return ret; } @@ -398,11 +398,11 @@ int ff_framesync2_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1) return 0; } -int ff_framesync2_dualinput_get_writable(FFFrameSync *fs, AVFrame **f0, AVFrame **f1) +int ff_framesync_dualinput_get_writable(FFFrameSync *fs, AVFrame **f0, AVFrame **f1) { int ret; - ret = ff_framesync2_dualinput_get(fs, f0, f1); + ret = ff_framesync_dualinput_get(fs, f0, f1); if (ret < 0) return ret; ret = ff_inlink_make_frame_writable(fs->parent->inputs[0], f0); diff --git a/libavfilter/framesync2.h b/libavfilter/framesync.h similarity index 86% rename from libavfilter/framesync2.h rename to libavfilter/framesync.h index 63a0eabbeb8b4..9fdc4d1ae2db0 100644 --- a/libavfilter/framesync2.h +++ b/libavfilter/framesync.h @@ -18,8 +18,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef AVFILTER_FRAMESYNC2_H -#define AVFILTER_FRAMESYNC2_H +#ifndef AVFILTER_FRAMESYNC_H +#define AVFILTER_FRAMESYNC_H #include "bufferqueue.h" @@ -47,7 +47,7 @@ enum EOFAction { * others can be configured. * * The basic working of this API is the following: set the on_event - * callback, then call ff_framesync2_activate() from the filter's activate + * callback, then call ff_framesync_activate() from the filter's activate * callback. */ @@ -209,9 +209,9 @@ typedef struct FFFrameSync { } FFFrameSync; /** - * Get the class for the framesync2 object. + * Get the class for the framesync object. */ -const AVClass *framesync2_get_class(void); +const AVClass *framesync_get_class(void); /** * Pre-initialize a frame sync structure. @@ -220,7 +220,7 @@ const AVClass *framesync2_get_class(void); * The entire structure is expected to be already set to 0. * This step is optional, but necessary to use the options. */ -void ff_framesync2_preinit(FFFrameSync *fs); +void ff_framesync_preinit(FFFrameSync *fs); /** * Initialize a frame sync structure. @@ -232,7 +232,7 @@ void ff_framesync2_preinit(FFFrameSync *fs); * @param nb_in number of inputs * @return >= 0 for success or a negative error code */ -int ff_framesync2_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in); +int ff_framesync_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in); /** * Configure a frame sync structure. @@ -241,12 +241,12 @@ int ff_framesync2_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in) * * @return >= 0 for success or a negative error code */ -int ff_framesync2_configure(FFFrameSync *fs); +int ff_framesync_configure(FFFrameSync *fs); /** * Free all memory currently allocated. */ -void ff_framesync2_uninit(FFFrameSync *fs); +void ff_framesync_uninit(FFFrameSync *fs); /** * Get the current frame in an input. @@ -258,16 +258,16 @@ void ff_framesync2_uninit(FFFrameSync *fs); * the returned frame; the current frame will either be * duplicated or removed from the framesync structure */ -int ff_framesync2_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, +int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, unsigned get); /** * Examine the frames in the filter's input and try to produce output. * * This function can be the complete implementation of the activate - * method of a filter using framesync2. + * method of a filter using framesync. */ -int ff_framesync2_activate(FFFrameSync *fs); +int ff_framesync_activate(FFFrameSync *fs); /** * Initialize a frame sync structure for dualinput. @@ -277,35 +277,35 @@ int ff_framesync2_activate(FFFrameSync *fs); * the only one with sync set and generic timeline support will just pass it * unchanged when disabled. * - * Equivalent to ff_framesync2_init(fs, parent, 2) then setting the time + * Equivalent to ff_framesync_init(fs, parent, 2) then setting the time * base, sync and ext modes on the inputs. */ -int ff_framesync2_init_dualinput(FFFrameSync *fs, AVFilterContext *parent); +int ff_framesync_init_dualinput(FFFrameSync *fs, AVFilterContext *parent); /** * @param f0 used to return the main frame * @param f1 used to return the second frame, or NULL if disabled * @return >=0 for success or AVERROR code */ -int ff_framesync2_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1); +int ff_framesync_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1); /** - * Same as ff_framesync2_dualinput_get(), but make sure that f0 is writable. + * Same as ff_framesync_dualinput_get(), but make sure that f0 is writable. */ -int ff_framesync2_dualinput_get_writable(FFFrameSync *fs, AVFrame **f0, AVFrame **f1); +int ff_framesync_dualinput_get_writable(FFFrameSync *fs, AVFrame **f0, AVFrame **f1); #define FRAMESYNC_DEFINE_CLASS(name, context, field) \ static int name##_framesync_preinit(AVFilterContext *ctx) { \ context *s = ctx->priv; \ - ff_framesync2_preinit(&s->field); \ + ff_framesync_preinit(&s->field); \ return 0; \ } \ static const AVClass *name##_child_class_next(const AVClass *prev) { \ - return prev ? NULL : framesync2_get_class(); \ + return prev ? NULL : framesync_get_class(); \ } \ static void *name##_child_next(void *obj, void *prev) { \ context *s = obj; \ - s->fs.class = framesync2_get_class(); /* FIXME */ \ + s->fs.class = framesync_get_class(); /* FIXME */ \ return prev ? NULL : &s->field; \ } \ static const AVClass name##_class = { \ @@ -318,4 +318,4 @@ static const AVClass name##_class = { \ .child_next = name##_child_next, \ } -#endif /* AVFILTER_FRAMESYNC2_H */ +#endif /* AVFILTER_FRAMESYNC_H */ diff --git a/libavfilter/maskedmerge.h b/libavfilter/maskedmerge.h index 3d670f6d5ddf4..8e2b1cf676c14 100644 --- a/libavfilter/maskedmerge.h +++ b/libavfilter/maskedmerge.h @@ -22,7 +22,7 @@ #define AVFILTER_MASKEDMERGE_H #include "avfilter.h" -#include "framesync2.h" +#include "framesync.h" typedef struct MaskedMergeContext { const AVClass *class; diff --git a/libavfilter/vf_blend.c b/libavfilter/vf_blend.c index 4939b101509d8..054c0d55d099d 100644 --- a/libavfilter/vf_blend.c +++ b/libavfilter/vf_blend.c @@ -25,7 +25,7 @@ #include "avfilter.h" #include "bufferqueue.h" #include "formats.h" -#include "framesync2.h" +#include "framesync.h" #include "internal.h" #include "video.h" #include "blend.h" @@ -411,7 +411,7 @@ static int blend_frame_for_dualinput(FFFrameSync *fs) AVFrame *top_buf, *bottom_buf, *dst_buf; int ret; - ret = ff_framesync2_dualinput_get(fs, &top_buf, &bottom_buf); + ret = ff_framesync_dualinput_get(fs, &top_buf, &bottom_buf); if (ret < 0) return ret; if (!bottom_buf) @@ -454,7 +454,7 @@ static av_cold void uninit(AVFilterContext *ctx) BlendContext *s = ctx->priv; int i; - ff_framesync2_uninit(&s->fs); + ff_framesync_uninit(&s->fs); av_frame_free(&s->prev_frame); for (i = 0; i < FF_ARRAY_ELEMS(s->params); i++) @@ -554,7 +554,7 @@ static int config_output(AVFilterLink *outlink) s->nb_planes = av_pix_fmt_count_planes(toplink->format); if (!s->tblend) - if ((ret = ff_framesync2_init_dualinput(&s->fs, ctx)) < 0) + if ((ret = ff_framesync_init_dualinput(&s->fs, ctx)) < 0) return ret; for (plane = 0; plane < FF_ARRAY_ELEMS(s->params); plane++) { @@ -581,7 +581,7 @@ static int config_output(AVFilterLink *outlink) } } - return s->tblend ? 0 : ff_framesync2_configure(&s->fs); + return s->tblend ? 0 : ff_framesync_configure(&s->fs); } #if CONFIG_BLEND_FILTER @@ -589,7 +589,7 @@ static int config_output(AVFilterLink *outlink) static int activate(AVFilterContext *ctx) { BlendContext *s = ctx->priv; - return ff_framesync2_activate(&s->fs); + return ff_framesync_activate(&s->fs); } static const AVFilterPad blend_inputs[] = { diff --git a/libavfilter/vf_convolve.c b/libavfilter/vf_convolve.c index 63f38095981a2..e00a44d63d776 100644 --- a/libavfilter/vf_convolve.c +++ b/libavfilter/vf_convolve.c @@ -25,7 +25,7 @@ #include "avfilter.h" #include "formats.h" -#include "framesync2.h" +#include "framesync.h" #include "internal.h" #include "video.h" @@ -262,7 +262,7 @@ static int do_convolve(FFFrameSync *fs) AVFrame *mainpic = NULL, *impulsepic = NULL; int ret, y, x, plane; - ret = ff_framesync2_dualinput_get(fs, &mainpic, &impulsepic); + ret = ff_framesync_dualinput_get(fs, &mainpic, &impulsepic); if (ret < 0) return ret; if (!impulsepic) @@ -336,7 +336,7 @@ static int config_output(AVFilterLink *outlink) int ret, i; s->fs.on_event = do_convolve; - ret = ff_framesync2_init_dualinput(&s->fs, ctx); + ret = ff_framesync_init_dualinput(&s->fs, ctx); if (ret < 0) return ret; outlink->w = mainlink->w; @@ -345,7 +345,7 @@ static int config_output(AVFilterLink *outlink) outlink->sample_aspect_ratio = mainlink->sample_aspect_ratio; outlink->frame_rate = mainlink->frame_rate; - if ((ret = ff_framesync2_configure(&s->fs)) < 0) + if ((ret = ff_framesync_configure(&s->fs)) < 0) return ret; for (i = 0; i < s->nb_planes; i++) { @@ -361,7 +361,7 @@ static int config_output(AVFilterLink *outlink) static int activate(AVFilterContext *ctx) { ConvolveContext *s = ctx->priv; - return ff_framesync2_activate(&s->fs); + return ff_framesync_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) @@ -378,7 +378,7 @@ static av_cold void uninit(AVFilterContext *ctx) av_fft_end(s->ifft[i]); } - ff_framesync2_uninit(&s->fs); + ff_framesync_uninit(&s->fs); } static const AVFilterPad convolve_inputs[] = { diff --git a/libavfilter/vf_displace.c b/libavfilter/vf_displace.c index 9f16ad441fa65..768af6def478d 100644 --- a/libavfilter/vf_displace.c +++ b/libavfilter/vf_displace.c @@ -23,7 +23,7 @@ #include "libavutil/opt.h" #include "avfilter.h" #include "formats.h" -#include "framesync2.h" +#include "framesync.h" #include "internal.h" #include "video.h" @@ -248,9 +248,9 @@ static int process_frame(FFFrameSync *fs) AVFrame *out, *in, *xpic, *ypic; int ret; - if ((ret = ff_framesync2_get_frame(&s->fs, 0, &in, 0)) < 0 || - (ret = ff_framesync2_get_frame(&s->fs, 1, &xpic, 0)) < 0 || - (ret = ff_framesync2_get_frame(&s->fs, 2, &ypic, 0)) < 0) + if ((ret = ff_framesync_get_frame(&s->fs, 0, &in, 0)) < 0 || + (ret = ff_framesync_get_frame(&s->fs, 1, &xpic, 0)) < 0 || + (ret = ff_framesync_get_frame(&s->fs, 2, &ypic, 0)) < 0) return ret; if (ctx->is_disabled) { @@ -336,7 +336,7 @@ static int config_output(AVFilterLink *outlink) outlink->sample_aspect_ratio = srclink->sample_aspect_ratio; outlink->frame_rate = srclink->frame_rate; - ret = ff_framesync2_init(&s->fs, ctx, 3); + ret = ff_framesync_init(&s->fs, ctx, 3); if (ret < 0) return ret; @@ -356,20 +356,20 @@ static int config_output(AVFilterLink *outlink) s->fs.opaque = s; s->fs.on_event = process_frame; - return ff_framesync2_configure(&s->fs); + return ff_framesync_configure(&s->fs); } static int activate(AVFilterContext *ctx) { DisplaceContext *s = ctx->priv; - return ff_framesync2_activate(&s->fs); + return ff_framesync_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) { DisplaceContext *s = ctx->priv; - ff_framesync2_uninit(&s->fs); + ff_framesync_uninit(&s->fs); } static const AVFilterPad displace_inputs[] = { diff --git a/libavfilter/vf_hysteresis.c b/libavfilter/vf_hysteresis.c index 8ee827d8af289..a788e1b9ee64b 100644 --- a/libavfilter/vf_hysteresis.c +++ b/libavfilter/vf_hysteresis.c @@ -26,7 +26,7 @@ #include "formats.h" #include "internal.h" #include "video.h" -#include "framesync2.h" +#include "framesync.h" #define OFFSET(x) offsetof(HysteresisContext, x) #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM @@ -94,8 +94,8 @@ static int process_frame(FFFrameSync *fs) AVFrame *out, *base, *alt; int ret; - if ((ret = ff_framesync2_get_frame(&s->fs, 0, &base, 0)) < 0 || - (ret = ff_framesync2_get_frame(&s->fs, 1, &alt, 0)) < 0) + if ((ret = ff_framesync_get_frame(&s->fs, 0, &base, 0)) < 0 || + (ret = ff_framesync_get_frame(&s->fs, 1, &alt, 0)) < 0) return ret; if (ctx->is_disabled) { @@ -324,7 +324,7 @@ static int config_output(AVFilterLink *outlink) outlink->sample_aspect_ratio = base->sample_aspect_ratio; outlink->frame_rate = base->frame_rate; - if ((ret = ff_framesync2_init(&s->fs, ctx, 2)) < 0) + if ((ret = ff_framesync_init(&s->fs, ctx, 2)) < 0) return ret; in = s->fs.in; @@ -339,20 +339,20 @@ static int config_output(AVFilterLink *outlink) s->fs.opaque = s; s->fs.on_event = process_frame; - return ff_framesync2_configure(&s->fs); + return ff_framesync_configure(&s->fs); } static int activate(AVFilterContext *ctx) { HysteresisContext *s = ctx->priv; - return ff_framesync2_activate(&s->fs); + return ff_framesync_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) { HysteresisContext *s = ctx->priv; - ff_framesync2_uninit(&s->fs); + ff_framesync_uninit(&s->fs); av_freep(&s->map); av_freep(&s->xy); } diff --git a/libavfilter/vf_libvmaf.c b/libavfilter/vf_libvmaf.c index 405820f182864..2c3a9f33493ad 100644 --- a/libavfilter/vf_libvmaf.c +++ b/libavfilter/vf_libvmaf.c @@ -32,7 +32,7 @@ #include "avfilter.h" #include "drawutils.h" #include "formats.h" -#include "framesync2.h" +#include "framesync.h" #include "internal.h" #include "video.h" @@ -177,7 +177,7 @@ static int do_vmaf(FFFrameSync *fs) AVFrame *main, *ref; int ret; - ret = ff_framesync2_dualinput_get(fs, &main, &ref); + ret = ff_framesync_dualinput_get(fs, &main, &ref); if (ret < 0) return ret; if (!ref) @@ -266,7 +266,7 @@ static int config_output(AVFilterLink *outlink) AVFilterLink *mainlink = ctx->inputs[0]; int ret; - ret = ff_framesync2_init_dualinput(&s->fs, ctx); + ret = ff_framesync_init_dualinput(&s->fs, ctx); if (ret < 0) return ret; outlink->w = mainlink->w; @@ -274,7 +274,7 @@ static int config_output(AVFilterLink *outlink) outlink->time_base = mainlink->time_base; outlink->sample_aspect_ratio = mainlink->sample_aspect_ratio; outlink->frame_rate = mainlink->frame_rate; - if ((ret = ff_framesync2_configure(&s->fs)) < 0) + if ((ret = ff_framesync_configure(&s->fs)) < 0) return ret; return 0; @@ -283,14 +283,14 @@ static int config_output(AVFilterLink *outlink) static int activate(AVFilterContext *ctx) { LIBVMAFContext *s = ctx->priv; - return ff_framesync2_activate(&s->fs); + return ff_framesync_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) { LIBVMAFContext *s = ctx->priv; - ff_framesync2_uninit(&s->fs); + ff_framesync_uninit(&s->fs); pthread_mutex_lock(&s->lock); s->eof = 1; diff --git a/libavfilter/vf_lut2.c b/libavfilter/vf_lut2.c index ba599c3d14963..585d121ca3539 100644 --- a/libavfilter/vf_lut2.c +++ b/libavfilter/vf_lut2.c @@ -28,7 +28,7 @@ #include "formats.h" #include "internal.h" #include "video.h" -#include "framesync2.h" +#include "framesync.h" static const char *const var_names[] = { "w", ///< width of the input video @@ -85,7 +85,7 @@ static av_cold void uninit(AVFilterContext *ctx) LUT2Context *s = ctx->priv; int i; - ff_framesync2_uninit(&s->fs); + ff_framesync_uninit(&s->fs); av_frame_free(&s->prev_frame); for (i = 0; i < 4; i++) { @@ -216,8 +216,8 @@ static int process_frame(FFFrameSync *fs) AVFrame *out, *srcx = NULL, *srcy = NULL; int ret; - if ((ret = ff_framesync2_get_frame(&s->fs, 0, &srcx, 0)) < 0 || - (ret = ff_framesync2_get_frame(&s->fs, 1, &srcy, 0)) < 0) + if ((ret = ff_framesync_get_frame(&s->fs, 0, &srcx, 0)) < 0 || + (ret = ff_framesync_get_frame(&s->fs, 1, &srcy, 0)) < 0) return ret; if (ctx->is_disabled || !srcy) { @@ -327,7 +327,7 @@ static int lut2_config_output(AVFilterLink *outlink) outlink->sample_aspect_ratio = srcx->sample_aspect_ratio; outlink->frame_rate = srcx->frame_rate; - if ((ret = ff_framesync2_init(&s->fs, ctx, 2)) < 0) + if ((ret = ff_framesync_init(&s->fs, ctx, 2)) < 0) return ret; in = s->fs.in; @@ -345,13 +345,13 @@ static int lut2_config_output(AVFilterLink *outlink) if ((ret = config_output(outlink)) < 0) return ret; - return ff_framesync2_configure(&s->fs); + return ff_framesync_configure(&s->fs); } static int activate(AVFilterContext *ctx) { LUT2Context *s = ctx->priv; - return ff_framesync2_activate(&s->fs); + return ff_framesync_activate(&s->fs); } static const AVFilterPad inputs[] = { diff --git a/libavfilter/vf_lut3d.c b/libavfilter/vf_lut3d.c index 5ba91f7e47993..39cd73f0de4f4 100644 --- a/libavfilter/vf_lut3d.c +++ b/libavfilter/vf_lut3d.c @@ -32,7 +32,7 @@ #include "avfilter.h" #include "drawutils.h" #include "formats.h" -#include "framesync2.h" +#include "framesync.h" #include "internal.h" #include "video.h" @@ -681,13 +681,13 @@ static int config_output(AVFilterLink *outlink) LUT3DContext *lut3d = ctx->priv; int ret; - ret = ff_framesync2_init_dualinput(&lut3d->fs, ctx); + ret = ff_framesync_init_dualinput(&lut3d->fs, ctx); if (ret < 0) return ret; outlink->w = ctx->inputs[0]->w; outlink->h = ctx->inputs[0]->h; outlink->time_base = ctx->inputs[0]->time_base; - if ((ret = ff_framesync2_configure(&lut3d->fs)) < 0) + if ((ret = ff_framesync_configure(&lut3d->fs)) < 0) return ret; return 0; } @@ -695,7 +695,7 @@ static int config_output(AVFilterLink *outlink) static int activate(AVFilterContext *ctx) { LUT3DContext *s = ctx->priv; - return ff_framesync2_activate(&s->fs); + return ff_framesync_activate(&s->fs); } static int config_clut(AVFilterLink *inlink) @@ -755,7 +755,7 @@ static int update_apply_clut(FFFrameSync *fs) AVFrame *main, *second, *out; int ret; - ret = ff_framesync2_dualinput_get(fs, &main, &second); + ret = ff_framesync_dualinput_get(fs, &main, &second); if (ret < 0) return ret; if (!second) @@ -775,7 +775,7 @@ static av_cold int haldclut_init(AVFilterContext *ctx) static av_cold void haldclut_uninit(AVFilterContext *ctx) { LUT3DContext *lut3d = ctx->priv; - ff_framesync2_uninit(&lut3d->fs); + ff_framesync_uninit(&lut3d->fs); } static const AVOption haldclut_options[] = { diff --git a/libavfilter/vf_maskedclamp.c b/libavfilter/vf_maskedclamp.c index 81ba05147cc27..67a979f8c06ae 100644 --- a/libavfilter/vf_maskedclamp.c +++ b/libavfilter/vf_maskedclamp.c @@ -25,7 +25,7 @@ #include "formats.h" #include "internal.h" #include "video.h" -#include "framesync2.h" +#include "framesync.h" #define OFFSET(x) offsetof(MaskedClampContext, x) #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM @@ -93,9 +93,9 @@ static int process_frame(FFFrameSync *fs) AVFrame *out, *base, *dark, *bright; int ret; - if ((ret = ff_framesync2_get_frame(&s->fs, 0, &base, 0)) < 0 || - (ret = ff_framesync2_get_frame(&s->fs, 1, &dark, 0)) < 0 || - (ret = ff_framesync2_get_frame(&s->fs, 2, &bright, 0)) < 0) + if ((ret = ff_framesync_get_frame(&s->fs, 0, &base, 0)) < 0 || + (ret = ff_framesync_get_frame(&s->fs, 1, &dark, 0)) < 0 || + (ret = ff_framesync_get_frame(&s->fs, 2, &bright, 0)) < 0) return ret; if (ctx->is_disabled) { @@ -265,7 +265,7 @@ static int config_output(AVFilterLink *outlink) outlink->sample_aspect_ratio = base->sample_aspect_ratio; outlink->frame_rate = base->frame_rate; - if ((ret = ff_framesync2_init(&s->fs, ctx, 3)) < 0) + if ((ret = ff_framesync_init(&s->fs, ctx, 3)) < 0) return ret; in = s->fs.in; @@ -284,20 +284,20 @@ static int config_output(AVFilterLink *outlink) s->fs.opaque = s; s->fs.on_event = process_frame; - return ff_framesync2_configure(&s->fs); + return ff_framesync_configure(&s->fs); } static int activate(AVFilterContext *ctx) { MaskedClampContext *s = ctx->priv; - return ff_framesync2_activate(&s->fs); + return ff_framesync_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) { MaskedClampContext *s = ctx->priv; - ff_framesync2_uninit(&s->fs); + ff_framesync_uninit(&s->fs); } static const AVFilterPad maskedclamp_inputs[] = { diff --git a/libavfilter/vf_maskedmerge.c b/libavfilter/vf_maskedmerge.c index cd11c959f6bed..d31b92659e2f4 100644 --- a/libavfilter/vf_maskedmerge.c +++ b/libavfilter/vf_maskedmerge.c @@ -71,9 +71,9 @@ static int process_frame(FFFrameSync *fs) AVFrame *out, *base, *overlay, *mask; int ret; - if ((ret = ff_framesync2_get_frame(&s->fs, 0, &base, 0)) < 0 || - (ret = ff_framesync2_get_frame(&s->fs, 1, &overlay, 0)) < 0 || - (ret = ff_framesync2_get_frame(&s->fs, 2, &mask, 0)) < 0) + if ((ret = ff_framesync_get_frame(&s->fs, 0, &base, 0)) < 0 || + (ret = ff_framesync_get_frame(&s->fs, 1, &overlay, 0)) < 0 || + (ret = ff_framesync_get_frame(&s->fs, 2, &mask, 0)) < 0) return ret; if (ctx->is_disabled) { @@ -232,7 +232,7 @@ static int config_output(AVFilterLink *outlink) if ((ret = av_image_fill_linesizes(s->linesize, outlink->format, outlink->w)) < 0) return ret; - if ((ret = ff_framesync2_init(&s->fs, ctx, 3)) < 0) + if ((ret = ff_framesync_init(&s->fs, ctx, 3)) < 0) return ret; in = s->fs.in; @@ -251,20 +251,20 @@ static int config_output(AVFilterLink *outlink) s->fs.opaque = s; s->fs.on_event = process_frame; - return ff_framesync2_configure(&s->fs); + return ff_framesync_configure(&s->fs); } static int activate(AVFilterContext *ctx) { MaskedMergeContext *s = ctx->priv; - return ff_framesync2_activate(&s->fs); + return ff_framesync_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) { MaskedMergeContext *s = ctx->priv; - ff_framesync2_uninit(&s->fs); + ff_framesync_uninit(&s->fs); } static const AVFilterPad maskedmerge_inputs[] = { diff --git a/libavfilter/vf_mergeplanes.c b/libavfilter/vf_mergeplanes.c index b8ccee080297e..4b4f91be5d2c3 100644 --- a/libavfilter/vf_mergeplanes.c +++ b/libavfilter/vf_mergeplanes.c @@ -25,7 +25,7 @@ #include "libavutil/pixdesc.h" #include "avfilter.h" #include "internal.h" -#include "framesync2.h" +#include "framesync.h" typedef struct InputParam { int depth[4]; @@ -143,7 +143,7 @@ static int process_frame(FFFrameSync *fs) int i, ret; for (i = 0; i < s->nb_inputs; i++) { - if ((ret = ff_framesync2_get_frame(&s->fs, i, &in[i], 0)) < 0) + if ((ret = ff_framesync_get_frame(&s->fs, i, &in[i], 0)) < 0) return ret; } @@ -172,7 +172,7 @@ static int config_output(AVFilterLink *outlink) FFFrameSyncIn *in; int i, ret; - if ((ret = ff_framesync2_init(&s->fs, ctx, s->nb_inputs)) < 0) + if ((ret = ff_framesync_init(&s->fs, ctx, s->nb_inputs)) < 0) return ret; in = s->fs.in; @@ -265,7 +265,7 @@ static int config_output(AVFilterLink *outlink) } } - return ff_framesync2_configure(&s->fs); + return ff_framesync_configure(&s->fs); fail: return AVERROR(EINVAL); } @@ -273,7 +273,7 @@ static int config_output(AVFilterLink *outlink) static int activate(AVFilterContext *ctx) { MergePlanesContext *s = ctx->priv; - return ff_framesync2_activate(&s->fs); + return ff_framesync_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) @@ -281,7 +281,7 @@ static av_cold void uninit(AVFilterContext *ctx) MergePlanesContext *s = ctx->priv; int i; - ff_framesync2_uninit(&s->fs); + ff_framesync_uninit(&s->fs); for (i = 0; i < ctx->nb_inputs; i++) av_freep(&ctx->input_pads[i].name); diff --git a/libavfilter/vf_midequalizer.c b/libavfilter/vf_midequalizer.c index 8101741bdc816..c03814a24fadc 100644 --- a/libavfilter/vf_midequalizer.c +++ b/libavfilter/vf_midequalizer.c @@ -25,7 +25,7 @@ #include "formats.h" #include "internal.h" #include "video.h" -#include "framesync2.h" +#include "framesync.h" typedef struct MidEqualizerContext { const AVClass *class; @@ -89,8 +89,8 @@ static int process_frame(FFFrameSync *fs) AVFrame *out, *in0, *in1; int ret; - if ((ret = ff_framesync2_get_frame(&s->fs, 0, &in0, 0)) < 0 || - (ret = ff_framesync2_get_frame(&s->fs, 1, &in1, 0)) < 0) + if ((ret = ff_framesync_get_frame(&s->fs, 0, &in0, 0)) < 0 || + (ret = ff_framesync_get_frame(&s->fs, 1, &in1, 0)) < 0) return ret; if (ctx->is_disabled) { @@ -311,7 +311,7 @@ static int config_output(AVFilterLink *outlink) outlink->sample_aspect_ratio = in0->sample_aspect_ratio; outlink->frame_rate = in0->frame_rate; - if ((ret = ff_framesync2_init(&s->fs, ctx, 2)) < 0) + if ((ret = ff_framesync_init(&s->fs, ctx, 2)) < 0) return ret; in = s->fs.in; @@ -326,20 +326,20 @@ static int config_output(AVFilterLink *outlink) s->fs.opaque = s; s->fs.on_event = process_frame; - return ff_framesync2_configure(&s->fs); + return ff_framesync_configure(&s->fs); } static int activate(AVFilterContext *ctx) { MidEqualizerContext *s = ctx->priv; - return ff_framesync2_activate(&s->fs); + return ff_framesync_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) { MidEqualizerContext *s = ctx->priv; - ff_framesync2_uninit(&s->fs); + ff_framesync_uninit(&s->fs); av_freep(&s->histogram[0]); av_freep(&s->histogram[1]); av_freep(&s->cchange); diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c index 619a5a6354905..5bf3d66cf1f2b 100644 --- a/libavfilter/vf_overlay.c +++ b/libavfilter/vf_overlay.c @@ -37,7 +37,7 @@ #include "libavutil/timestamp.h" #include "internal.h" #include "drawutils.h" -#include "framesync2.h" +#include "framesync.h" #include "video.h" static const char *const var_names[] = { @@ -130,7 +130,7 @@ static av_cold void uninit(AVFilterContext *ctx) { OverlayContext *s = ctx->priv; - ff_framesync2_uninit(&s->fs); + ff_framesync_uninit(&s->fs); av_expr_free(s->x_pexpr); s->x_pexpr = NULL; av_expr_free(s->y_pexpr); s->y_pexpr = NULL; } @@ -377,14 +377,14 @@ static int config_output(AVFilterLink *outlink) OverlayContext *s = ctx->priv; int ret; - if ((ret = ff_framesync2_init_dualinput(&s->fs, ctx)) < 0) + if ((ret = ff_framesync_init_dualinput(&s->fs, ctx)) < 0) return ret; outlink->w = ctx->inputs[MAIN]->w; outlink->h = ctx->inputs[MAIN]->h; outlink->time_base = ctx->inputs[MAIN]->time_base; - return ff_framesync2_configure(&s->fs); + return ff_framesync_configure(&s->fs); } // divide by 255 and round to nearest @@ -765,7 +765,7 @@ static int do_blend(FFFrameSync *fs) AVFilterLink *inlink = ctx->inputs[0]; int ret; - ret = ff_framesync2_dualinput_get_writable(fs, &mainpic, &second); + ret = ff_framesync_dualinput_get_writable(fs, &mainpic, &second); if (ret < 0) return ret; if (!second) @@ -808,7 +808,7 @@ static av_cold int init(AVFilterContext *ctx) static int activate(AVFilterContext *ctx) { OverlayContext *s = ctx->priv; - return ff_framesync2_activate(&s->fs); + return ff_framesync_activate(&s->fs); } #define OFFSET(x) offsetof(OverlayContext, x) diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c index 3d16c2dd842e3..ffd37bf1da067 100644 --- a/libavfilter/vf_paletteuse.c +++ b/libavfilter/vf_paletteuse.c @@ -29,7 +29,7 @@ #include "libavutil/qsort.h" #include "avfilter.h" #include "filters.h" -#include "framesync2.h" +#include "framesync.h" #include "internal.h" enum dithering_mode { @@ -904,7 +904,7 @@ static int config_output(AVFilterLink *outlink) AVFilterContext *ctx = outlink->src; PaletteUseContext *s = ctx->priv; - ret = ff_framesync2_init_dualinput(&s->fs, ctx); + ret = ff_framesync_init_dualinput(&s->fs, ctx); if (ret < 0) return ret; s->fs.opt_repeatlast = 1; // only 1 frame in the palette @@ -915,7 +915,7 @@ static int config_output(AVFilterLink *outlink) outlink->h = ctx->inputs[0]->h; outlink->time_base = ctx->inputs[0]->time_base; - if ((ret = ff_framesync2_configure(&s->fs)) < 0) + if ((ret = ff_framesync_configure(&s->fs)) < 0) return ret; return 0; } @@ -971,7 +971,7 @@ static int load_apply_palette(FFFrameSync *fs) int ret; // writable for error diffusal dithering - ret = ff_framesync2_dualinput_get_writable(fs, &main, &second); + ret = ff_framesync_dualinput_get_writable(fs, &main, &second); if (ret < 0) return ret; if (!main || !second) { @@ -1052,7 +1052,7 @@ static av_cold int init(AVFilterContext *ctx) static int activate(AVFilterContext *ctx) { PaletteUseContext *s = ctx->priv; - return ff_framesync2_activate(&s->fs); + return ff_framesync_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) @@ -1060,7 +1060,7 @@ static av_cold void uninit(AVFilterContext *ctx) int i; PaletteUseContext *s = ctx->priv; - ff_framesync2_uninit(&s->fs); + ff_framesync_uninit(&s->fs); for (i = 0; i < CACHE_SIZE; i++) av_freep(&s->cache[i].entries); av_frame_free(&s->last_in); diff --git a/libavfilter/vf_premultiply.c b/libavfilter/vf_premultiply.c index 148a9e55cb8f6..5120adc476693 100644 --- a/libavfilter/vf_premultiply.c +++ b/libavfilter/vf_premultiply.c @@ -24,7 +24,7 @@ #include "avfilter.h" #include "filters.h" #include "formats.h" -#include "framesync2.h" +#include "framesync.h" #include "internal.h" #include "video.h" @@ -503,8 +503,8 @@ static int process_frame(FFFrameSync *fs) AVFrame *out = NULL, *base, *alpha; int ret; - if ((ret = ff_framesync2_get_frame(&s->fs, 0, &base, 0)) < 0 || - (ret = ff_framesync2_get_frame(&s->fs, 1, &alpha, 0)) < 0) + if ((ret = ff_framesync_get_frame(&s->fs, 0, &base, 0)) < 0 || + (ret = ff_framesync_get_frame(&s->fs, 1, &alpha, 0)) < 0) return ret; if ((ret = filter_frame(ctx, &out, base, alpha)) < 0) @@ -578,7 +578,7 @@ static int config_output(AVFilterLink *outlink) if (s->inplace) return 0; - if ((ret = ff_framesync2_init(&s->fs, ctx, 2)) < 0) + if ((ret = ff_framesync_init(&s->fs, ctx, 2)) < 0) return ret; in = s->fs.in; @@ -593,7 +593,7 @@ static int config_output(AVFilterLink *outlink) s->fs.opaque = s; s->fs.on_event = process_frame; - return ff_framesync2_configure(&s->fs); + return ff_framesync_configure(&s->fs); } static int activate(AVFilterContext *ctx) @@ -623,7 +623,7 @@ static int activate(AVFilterContext *ctx) return 0; } } else { - return ff_framesync2_activate(&s->fs); + return ff_framesync_activate(&s->fs); } } @@ -668,7 +668,7 @@ static av_cold void uninit(AVFilterContext *ctx) PreMultiplyContext *s = ctx->priv; if (!s->inplace) - ff_framesync2_uninit(&s->fs); + ff_framesync_uninit(&s->fs); } static const AVFilterPad premultiply_outputs[] = { diff --git a/libavfilter/vf_psnr.c b/libavfilter/vf_psnr.c index a8eb315445ae2..adf16444ff0c6 100644 --- a/libavfilter/vf_psnr.c +++ b/libavfilter/vf_psnr.c @@ -31,7 +31,7 @@ #include "avfilter.h" #include "drawutils.h" #include "formats.h" -#include "framesync2.h" +#include "framesync.h" #include "internal.h" #include "psnr.h" #include "video.h" @@ -151,7 +151,7 @@ static int do_psnr(FFFrameSync *fs) int ret, j, c; AVDictionary **metadata; - ret = ff_framesync2_dualinput_get(fs, &main, &ref); + ret = ff_framesync_dualinput_get(fs, &main, &ref); if (ret < 0) return ret; if (!ref) @@ -339,7 +339,7 @@ static int config_output(AVFilterLink *outlink) AVFilterLink *mainlink = ctx->inputs[0]; int ret; - ret = ff_framesync2_init_dualinput(&s->fs, ctx); + ret = ff_framesync_init_dualinput(&s->fs, ctx); if (ret < 0) return ret; outlink->w = mainlink->w; @@ -347,7 +347,7 @@ static int config_output(AVFilterLink *outlink) outlink->time_base = mainlink->time_base; outlink->sample_aspect_ratio = mainlink->sample_aspect_ratio; outlink->frame_rate = mainlink->frame_rate; - if ((ret = ff_framesync2_configure(&s->fs)) < 0) + if ((ret = ff_framesync_configure(&s->fs)) < 0) return ret; return 0; @@ -356,7 +356,7 @@ static int config_output(AVFilterLink *outlink) static int activate(AVFilterContext *ctx) { PSNRContext *s = ctx->priv; - return ff_framesync2_activate(&s->fs); + return ff_framesync_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) @@ -380,7 +380,7 @@ static av_cold void uninit(AVFilterContext *ctx) get_psnr(s->min_mse, 1, s->average_max)); } - ff_framesync2_uninit(&s->fs); + ff_framesync_uninit(&s->fs); if (s->stats_file && s->stats_file != stdout) fclose(s->stats_file); diff --git a/libavfilter/vf_remap.c b/libavfilter/vf_remap.c index a62ec4c183358..d24284703b855 100644 --- a/libavfilter/vf_remap.c +++ b/libavfilter/vf_remap.c @@ -41,7 +41,7 @@ #include "libavutil/opt.h" #include "avfilter.h" #include "formats.h" -#include "framesync2.h" +#include "framesync.h" #include "internal.h" #include "video.h" @@ -286,9 +286,9 @@ static int process_frame(FFFrameSync *fs) AVFrame *out, *in, *xpic, *ypic; int ret; - if ((ret = ff_framesync2_get_frame(&s->fs, 0, &in, 0)) < 0 || - (ret = ff_framesync2_get_frame(&s->fs, 1, &xpic, 0)) < 0 || - (ret = ff_framesync2_get_frame(&s->fs, 2, &ypic, 0)) < 0) + if ((ret = ff_framesync_get_frame(&s->fs, 0, &in, 0)) < 0 || + (ret = ff_framesync_get_frame(&s->fs, 1, &xpic, 0)) < 0 || + (ret = ff_framesync_get_frame(&s->fs, 2, &ypic, 0)) < 0) return ret; if (ctx->is_disabled) { @@ -333,7 +333,7 @@ static int config_output(AVFilterLink *outlink) outlink->sample_aspect_ratio = srclink->sample_aspect_ratio; outlink->frame_rate = srclink->frame_rate; - ret = ff_framesync2_init(&s->fs, ctx, 3); + ret = ff_framesync_init(&s->fs, ctx, 3); if (ret < 0) return ret; @@ -353,13 +353,13 @@ static int config_output(AVFilterLink *outlink) s->fs.opaque = s; s->fs.on_event = process_frame; - return ff_framesync2_configure(&s->fs); + return ff_framesync_configure(&s->fs); } static int activate(AVFilterContext *ctx) { RemapContext *s = ctx->priv; - return ff_framesync2_activate(&s->fs); + return ff_framesync_activate(&s->fs); } @@ -367,7 +367,7 @@ static av_cold void uninit(AVFilterContext *ctx) { RemapContext *s = ctx->priv; - ff_framesync2_uninit(&s->fs); + ff_framesync_uninit(&s->fs); } static const AVFilterPad remap_inputs[] = { diff --git a/libavfilter/vf_ssim.c b/libavfilter/vf_ssim.c index 5f5bed7a0ed8a..40f09ad5aa432 100644 --- a/libavfilter/vf_ssim.c +++ b/libavfilter/vf_ssim.c @@ -40,7 +40,7 @@ #include "avfilter.h" #include "drawutils.h" #include "formats.h" -#include "framesync2.h" +#include "framesync.h" #include "internal.h" #include "ssim.h" #include "video.h" @@ -291,7 +291,7 @@ static int do_ssim(FFFrameSync *fs) float c[4], ssimv = 0.0; int ret, i; - ret = ff_framesync2_dualinput_get(fs, &main, &ref); + ret = ff_framesync_dualinput_get(fs, &main, &ref); if (ret < 0) return ret; if (!ref) @@ -431,7 +431,7 @@ static int config_output(AVFilterLink *outlink) AVFilterLink *mainlink = ctx->inputs[0]; int ret; - ret = ff_framesync2_init_dualinput(&s->fs, ctx); + ret = ff_framesync_init_dualinput(&s->fs, ctx); if (ret < 0) return ret; outlink->w = mainlink->w; @@ -440,7 +440,7 @@ static int config_output(AVFilterLink *outlink) outlink->sample_aspect_ratio = mainlink->sample_aspect_ratio; outlink->frame_rate = mainlink->frame_rate; - if ((ret = ff_framesync2_configure(&s->fs)) < 0) + if ((ret = ff_framesync_configure(&s->fs)) < 0) return ret; return 0; @@ -449,7 +449,7 @@ static int config_output(AVFilterLink *outlink) static int activate(AVFilterContext *ctx) { SSIMContext *s = ctx->priv; - return ff_framesync2_activate(&s->fs); + return ff_framesync_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) @@ -469,7 +469,7 @@ static av_cold void uninit(AVFilterContext *ctx) s->ssim_total / s->nb_frames, ssim_db(s->ssim_total, s->nb_frames)); } - ff_framesync2_uninit(&s->fs); + ff_framesync_uninit(&s->fs); if (s->stats_file && s->stats_file != stdout) fclose(s->stats_file); diff --git a/libavfilter/vf_stack.c b/libavfilter/vf_stack.c index fa8a02257e8c9..2467302159f3f 100644 --- a/libavfilter/vf_stack.c +++ b/libavfilter/vf_stack.c @@ -26,7 +26,7 @@ #include "avfilter.h" #include "formats.h" #include "internal.h" -#include "framesync2.h" +#include "framesync.h" #include "video.h" typedef struct StackContext { @@ -97,7 +97,7 @@ static int process_frame(FFFrameSync *fs) int i, p, ret, offset[4] = { 0 }; for (i = 0; i < s->nb_inputs; i++) { - if ((ret = ff_framesync2_get_frame(&s->fs, i, &in[i], 0)) < 0) + if ((ret = ff_framesync_get_frame(&s->fs, i, &in[i], 0)) < 0) return ret; } @@ -180,7 +180,7 @@ static int config_output(AVFilterLink *outlink) outlink->time_base = time_base; outlink->frame_rate = frame_rate; - if ((ret = ff_framesync2_init(&s->fs, ctx, s->nb_inputs)) < 0) + if ((ret = ff_framesync_init(&s->fs, ctx, s->nb_inputs)) < 0) return ret; in = s->fs.in; @@ -196,7 +196,7 @@ static int config_output(AVFilterLink *outlink) in[i].after = s->shortest ? EXT_STOP : EXT_INFINITY; } - return ff_framesync2_configure(&s->fs); + return ff_framesync_configure(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) @@ -204,7 +204,7 @@ static av_cold void uninit(AVFilterContext *ctx) StackContext *s = ctx->priv; int i; - ff_framesync2_uninit(&s->fs); + ff_framesync_uninit(&s->fs); av_freep(&s->frames); for (i = 0; i < ctx->nb_inputs; i++) @@ -214,7 +214,7 @@ static av_cold void uninit(AVFilterContext *ctx) static int activate(AVFilterContext *ctx) { StackContext *s = ctx->priv; - return ff_framesync2_activate(&s->fs); + return ff_framesync_activate(&s->fs); } #define OFFSET(x) offsetof(StackContext, x) diff --git a/libavfilter/vf_threshold.c b/libavfilter/vf_threshold.c index 4e31ab4c0fa12..88f6ef28d78f0 100644 --- a/libavfilter/vf_threshold.c +++ b/libavfilter/vf_threshold.c @@ -28,7 +28,7 @@ #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "avfilter.h" -#include "framesync2.h" +#include "framesync.h" #include "internal.h" #include "video.h" @@ -96,10 +96,10 @@ static int process_frame(FFFrameSync *fs) AVFrame *out, *in, *threshold, *min, *max; int ret; - if ((ret = ff_framesync2_get_frame(&s->fs, 0, &in, 0)) < 0 || - (ret = ff_framesync2_get_frame(&s->fs, 1, &threshold, 0)) < 0 || - (ret = ff_framesync2_get_frame(&s->fs, 2, &min, 0)) < 0 || - (ret = ff_framesync2_get_frame(&s->fs, 3, &max, 0)) < 0) + if ((ret = ff_framesync_get_frame(&s->fs, 0, &in, 0)) < 0 || + (ret = ff_framesync_get_frame(&s->fs, 1, &threshold, 0)) < 0 || + (ret = ff_framesync_get_frame(&s->fs, 2, &min, 0)) < 0 || + (ret = ff_framesync_get_frame(&s->fs, 3, &max, 0)) < 0) return ret; if (ctx->is_disabled) { @@ -256,7 +256,7 @@ static int config_output(AVFilterLink *outlink) outlink->sample_aspect_ratio = base->sample_aspect_ratio; outlink->frame_rate = base->frame_rate; - if ((ret = ff_framesync2_init(&s->fs, ctx, 4)) < 0) + if ((ret = ff_framesync_init(&s->fs, ctx, 4)) < 0) return ret; in = s->fs.in; @@ -279,20 +279,20 @@ static int config_output(AVFilterLink *outlink) s->fs.opaque = s; s->fs.on_event = process_frame; - return ff_framesync2_configure(&s->fs); + return ff_framesync_configure(&s->fs); } static int activate(AVFilterContext *ctx) { ThresholdContext *s = ctx->priv; - return ff_framesync2_activate(&s->fs); + return ff_framesync_activate(&s->fs); } static av_cold void uninit(AVFilterContext *ctx) { ThresholdContext *s = ctx->priv; - ff_framesync2_uninit(&s->fs); + ff_framesync_uninit(&s->fs); } static const AVFilterPad inputs[] = { From 064c9d45ff10fec5d735c49999212881e93a0fd4 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Thu, 31 Aug 2017 17:05:31 +0200 Subject: [PATCH 3056/3374] doc: update filter_design.txt. --- doc/filter_design.txt | 251 +++++++++++++++++++++++------------------- 1 file changed, 135 insertions(+), 116 deletions(-) diff --git a/doc/filter_design.txt b/doc/filter_design.txt index e8a7c53ee91d1..885b19b6f65d2 100644 --- a/doc/filter_design.txt +++ b/doc/filter_design.txt @@ -5,7 +5,7 @@ This document explains guidelines that should be observed (or ignored with good reason) when writing filters for libavfilter. In this document, the word “frame” indicates either a video frame or a group -of audio samples, as stored in an AVFilterBuffer structure. +of audio samples, as stored in an AVFrame structure. Format negotiation @@ -35,32 +35,31 @@ Format negotiation to set the formats supported on another. -Buffer references ownership and permissions -=========================================== +Frame references ownership and permissions +========================================== Principle --------- - Audio and video data are voluminous; the buffer and buffer reference + Audio and video data are voluminous; the frame and frame reference mechanism is intended to avoid, as much as possible, expensive copies of that data while still allowing the filters to produce correct results. - The data is stored in buffers represented by AVFilterBuffer structures. - They must not be accessed directly, but through references stored in - AVFilterBufferRef structures. Several references can point to the - same buffer; the buffer is automatically deallocated once all - corresponding references have been destroyed. + The data is stored in buffers represented by AVFrame structures. + Several references can point to the same frame buffer; the buffer is + automatically deallocated once all corresponding references have been + destroyed. The characteristics of the data (resolution, sample rate, etc.) are stored in the reference; different references for the same buffer can show different characteristics. In particular, a video reference can point to only a part of a video buffer. - A reference is usually obtained as input to the start_frame or - filter_frame method or requested using the ff_get_video_buffer or - ff_get_audio_buffer functions. A new reference on an existing buffer can - be created with the avfilter_ref_buffer. A reference is destroyed using - the avfilter_unref_bufferp function. + A reference is usually obtained as input to the filter_frame method or + requested using the ff_get_video_buffer or ff_get_audio_buffer + functions. A new reference on an existing buffer can be created with + av_frame_ref(). A reference is destroyed using + the av_frame_free() function. Reference ownership ------------------- @@ -73,17 +72,13 @@ Buffer references ownership and permissions Here are the (fairly obvious) rules for reference ownership: - * A reference received by the filter_frame method (or its start_frame - deprecated version) belongs to the corresponding filter. + * A reference received by the filter_frame method belongs to the + corresponding filter. - Special exception: for video references: the reference may be used - internally for automatic copying and must not be destroyed before - end_frame; it can be given away to ff_start_frame. + * A reference passed to ff_filter_frame is given away and must no longer + be used. - * A reference passed to ff_filter_frame (or the deprecated - ff_start_frame) is given away and must no longer be used. - - * A reference created with avfilter_ref_buffer belongs to the code that + * A reference created with av_frame_ref() belongs to the code that created it. * A reference obtained with ff_get_video_buffer or ff_get_audio_buffer @@ -95,89 +90,32 @@ Buffer references ownership and permissions Link reference fields --------------------- - The AVFilterLink structure has a few AVFilterBufferRef fields. The - cur_buf and out_buf were used with the deprecated - start_frame/draw_slice/end_frame API and should no longer be used. - src_buf and partial_buf are used by libavfilter internally - and must not be accessed by filters. - - Reference permissions - --------------------- - - The AVFilterBufferRef structure has a perms field that describes what - the code that owns the reference is allowed to do to the buffer data. - Different references for the same buffer can have different permissions. - - For video filters that implement the deprecated - start_frame/draw_slice/end_frame API, the permissions only apply to the - parts of the buffer that have already been covered by the draw_slice - method. - - The value is a binary OR of the following constants: - - * AV_PERM_READ: the owner can read the buffer data; this is essentially - always true and is there for self-documentation. - - * AV_PERM_WRITE: the owner can modify the buffer data. - - * AV_PERM_PRESERVE: the owner can rely on the fact that the buffer data - will not be modified by previous filters. - - * AV_PERM_REUSE: the owner can output the buffer several times, without - modifying the data in between. - - * AV_PERM_REUSE2: the owner can output the buffer several times and - modify the data in between (useless without the WRITE permissions). - - * AV_PERM_ALIGN: the owner can access the data using fast operations - that require data alignment. - - The READ, WRITE and PRESERVE permissions are about sharing the same - buffer between several filters to avoid expensive copies without them - doing conflicting changes on the data. - - The REUSE and REUSE2 permissions are about special memory for direct - rendering. For example a buffer directly allocated in video memory must - not modified once it is displayed on screen, or it will cause tearing; - it will therefore not have the REUSE2 permission. - - The ALIGN permission is about extracting part of the buffer, for - copy-less padding or cropping for example. - + The AVFilterLink structure has a few AVFrame fields. - References received on input pads are guaranteed to have all the - permissions stated in the min_perms field and none of the permissions - stated in the rej_perms. + partial_buf is used by libavfilter internally and must not be accessed + by filters. - References obtained by ff_get_video_buffer and ff_get_audio_buffer are - guaranteed to have at least all the permissions requested as argument. + fifo contains frames queued in the filter's input. They belong to the + framework until they are taken by the filter. - References created by avfilter_ref_buffer have the same permissions as - the original reference minus the ones explicitly masked; the mask is - usually ~0 to keep the same permissions. - - Filters should remove permissions on reference they give to output - whenever necessary. It can be automatically done by setting the - rej_perms field on the output pad. - - Here are a few guidelines corresponding to common situations: + Reference permissions + --------------------- - * Filters that modify and forward their frame (like drawtext) need the - WRITE permission. + Since the same frame data can be shared by several frames, modifying may + have unintended consequences. A frame is considered writable if only one + reference to it exists. The code owning that reference it then allowed + to modify the data. - * Filters that read their input to produce a new frame on output (like - scale) need the READ permission on input and must request a buffer - with the WRITE permission. + A filter can check if a frame is writable by using the + av_frame_is_writable() function. - * Filters that intend to keep a reference after the filtering process - is finished (after filter_frame returns) must have the PRESERVE - permission on it and remove the WRITE permission if they create a new - reference to give it away. + A filter can ensure that a frame is writable at some point of the code + by using the ff_inlink_make_frame_writable() function. It will duplicate + the frame if needed. - * Filters that intend to modify a reference they have kept after the end - of the filtering process need the REUSE2 permission and must remove - the PRESERVE permission if they create a new reference to give it - away. + A filter can ensure that the frame passed to the filter_frame() callback + is writable by setting the needs_writable flag on the corresponding + input pad. It does not apply to the activate() callback. Frame scheduling @@ -189,11 +127,100 @@ Frame scheduling Simple filters that output one frame for each input frame should not have to worry about it. + There are two design for filters: one using the filter_frame() and + request_frame() callbacks and the other using the activate() callback. + + The design using filter_frame() and request_frame() is legacy, but it is + suitable for filters that have a single input and process one frame at a + time. New filters with several inputs, that treat several frames at a time + or that require a special treatment at EOF should probably use the design + using activate(). + + activate + -------- + + This method is called when something must be done in a filter; the + definition of that "something" depends on the semantic of the filter. + + The callback must examine the status of the filter's links and proceed + accordingly. + + The status of output links is stored in the frame_wanted_out, status_in + and status_out fields and tested by the ff_outlink_frame_wanted() + function. If this function returns true, then the processing requires a + frame on this link and the filter is expected to make efforts in that + direction. + + The status of input links is stored by the status_in, fifo and + status_out fields; they must not be accessed directly. The fifo field + contains the frames that are queued in the input for processing by the + filter. The status_in and status_out fields contains the queued status + (EOF or error) of the link; status_in is a status change that must be + taken into account after all frames in fifo have been processed; + status_out is the status that have been taken into account, it is final + when it is not 0. + + The typical task of an activate callback is to first check the backward + status of output links, and if relevant forward it to the corresponding + input. Then, if relevant, for each input link: test the availability of + frames in fifo and process them; if no frame is available, test and + acknowledge a change of status using ff_inlink_acknowledge_status(); and + forward the result (frame or status change) to the corresponding input. + If nothing is possible, test the status of outputs and forward it to the + corresponding input(s). If still not possible, return FFERROR_NOT_READY. + + If the filters stores internally one or a few frame for some input, it + can consider them to be part of the FIFO and delay acknowledging a + status change accordingly. + + Example code: + + ret = ff_outlink_get_status(outlink); + if (ret) { + ff_inlink_set_status(inlink, ret); + return 0; + } + if (priv->next_frame) { + /* use it */ + return 0; + } + ret = ff_inlink_consume_frame(inlink, &frame); + if (ret < 0) + return ret; + if (ret) { + /* use it */ + return 0; + } + ret = ff_inlink_acknowledge_status(inlink, &status, &pts); + if (ret) { + /* flush */ + ff_outlink_set_status(outlink, status, pts); + return 0; + } + if (ff_outlink_frame_wanted(outlink)) { + ff_inlink_request_frame(inlink); + return 0; + } + return FFERROR_NOT_READY; + + The exact code depends on how similar the /* use it */ blocks are and + how related they are to the /* flush */ block, and needs to apply these + operations to the correct inlink or outlink if there are several. + + Macros are available to factor that when no extra processing is needed: + + FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink); + FF_FILTER_FORWARD_STATUS_ALL(outlink, filter); + FF_FILTER_FORWARD_STATUS(inlink, outlink); + FF_FILTER_FORWARD_STATUS_ALL(inlink, filter); + FF_FILTER_FORWARD_WANTED(outlink, inlink); + filter_frame ------------ - This method is called when a frame is pushed to the filter's input. It - can be called at any time except in a reentrant way. + For filters that do not use the activate() callback, this method is + called when a frame is pushed to the filter's input. It can be called at + any time except in a reentrant way. If the input frame is enough to produce output, then the filter should push the output frames on the output link immediately. @@ -222,9 +249,10 @@ Frame scheduling request_frame ------------- - This method is called when a frame is wanted on an output. + For filters that do not use the activate() callback, this method is + called when a frame is wanted on an output. - For an input, it should directly call filter_frame on the corresponding + For a source, it should directly call filter_frame on the corresponding output. For a filter, if there are queued frames already ready, one of these @@ -254,16 +282,7 @@ Frame scheduling } return 0; - Note that, except for filters that can have queued frames, request_frame - does not push frames: it requests them to its input, and as a reaction, - the filter_frame method possibly will be called and do the work. - -Legacy API -========== - - Until libavfilter 3.23, the filter_frame method was split: - - - for video filters, it was made of start_frame, draw_slice (that could be - called several times on distinct parts of the frame) and end_frame; - - - for audio filters, it was called filter_samples. + Note that, except for filters that can have queued frames and sources, + request_frame does not push frames: it requests them to its input, and + as a reaction, the filter_frame method possibly will be called and do + the work. From 9bad5e53191092ee17c0a95c597cccd527594d10 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Tue, 12 Sep 2017 11:14:25 +0200 Subject: [PATCH 3057/3374] lavfi/framesync: reword repeatlast option help. --- doc/filters.texi | 6 +++--- libavfilter/framesync.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 4111532512629..830de549094cc 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -337,9 +337,9 @@ If set to 1, force the output to terminate when the shortest input terminates. Default value is 0. @item repeatlast -If set to 1, force the filter to draw the last overlay frame over the -main input until the end of the stream. A value of 0 disables this -behavior. Default value is 1. +If set to 1, force the filter to extend the last frame of secondary streams +until the end of the primary stream. A value of 0 disables this behavior. +Default value is 1. @end table @c man end OPTIONS FOR FILTERS WITH SEVERAL INPUTS diff --git a/libavfilter/framesync.c b/libavfilter/framesync.c index ebfbcaf090087..5567d660ab69f 100644 --- a/libavfilter/framesync.c +++ b/libavfilter/framesync.c @@ -41,7 +41,7 @@ static const AVOption framesync_options[] = { { "endall", "End both streams.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_ENDALL }, .flags = FLAGS, "eof_action" }, { "pass", "Pass through the main input.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_PASS }, .flags = FLAGS, "eof_action" }, { "shortest", "force termination when the shortest input terminates", OFFSET(opt_shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, - { "repeatlast", "repeat overlay of the last overlay frame", OFFSET(opt_repeatlast), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS }, + { "repeatlast", "extend last frame of secondary streams beyond EOF", OFFSET(opt_repeatlast), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS }, { NULL } }; static const AVClass framesync_class = { From 549ef6ef9a8168281640b9cd0240abe071cbbda3 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Tue, 12 Sep 2017 11:23:39 +0200 Subject: [PATCH 3058/3374] lavfi/framesync: remove dead code. Fix CID 1416960. --- libavfilter/framesync.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libavfilter/framesync.c b/libavfilter/framesync.c index 5567d660ab69f..82d715750c4bc 100644 --- a/libavfilter/framesync.c +++ b/libavfilter/framesync.c @@ -380,15 +380,13 @@ int ff_framesync_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1) { AVFilterContext *ctx = fs->parent; AVFrame *mainpic = NULL, *secondpic = NULL; - int ret = 0; + int ret; if ((ret = ff_framesync_get_frame(fs, 0, &mainpic, 1)) < 0 || (ret = ff_framesync_get_frame(fs, 1, &secondpic, 0)) < 0) { av_frame_free(&mainpic); return ret; } - if (ret < 0) - return ret; av_assert0(mainpic); mainpic->pts = av_rescale_q(fs->pts, fs->time_base, ctx->outputs[0]->time_base); if (ctx->is_disabled) From 183216b21870f21c86c904a7530d53682d7db46d Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 11 Sep 2017 09:58:47 -0400 Subject: [PATCH 3059/3374] frame_thread_encoder: make 'exit' member atomic. Should fix the following tsan warning: WARNING: ThreadSanitizer: data race (pid=19806) Read of size 4 at 0x7b84000012f0 by thread T9: #0 worker src/libavcodec/frame_thread_encoder.c:66 (ffmpeg+0x0000007f349e) [..] Previous write of size 4 at 0x7b84000012f0 by main thread (mutexes: write M1395): #0 ff_frame_thread_encoder_free src/libavcodec/frame_thread_encoder.c:239 (ffmpeg+0x0000007f379e) [..] --- libavcodec/frame_thread_encoder.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/libavcodec/frame_thread_encoder.c b/libavcodec/frame_thread_encoder.c index 33928fe5f0393..35a37c4372d27 100644 --- a/libavcodec/frame_thread_encoder.c +++ b/libavcodec/frame_thread_encoder.c @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + #include "frame_thread_encoder.h" #include "libavutil/fifo.h" @@ -55,7 +57,7 @@ typedef struct{ unsigned finished_task_index; pthread_t worker[MAX_THREADS]; - int exit; + atomic_int exit; } ThreadContext; static void * attribute_align_arg worker(void *v){ @@ -63,7 +65,7 @@ static void * attribute_align_arg worker(void *v){ ThreadContext *c = avctx->internal->frame_thread_encoder; AVPacket *pkt = NULL; - while(!c->exit){ + while (!atomic_load(&c->exit)) { int got_packet, ret; AVFrame *frame; Task task; @@ -73,8 +75,8 @@ static void * attribute_align_arg worker(void *v){ av_init_packet(pkt); pthread_mutex_lock(&c->task_fifo_mutex); - while (av_fifo_size(c->task_fifo) <= 0 || c->exit) { - if(c->exit){ + while (av_fifo_size(c->task_fifo) <= 0 || atomic_load(&c->exit)) { + if (atomic_load(&c->exit)) { pthread_mutex_unlock(&c->task_fifo_mutex); goto end; } @@ -187,6 +189,7 @@ int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){ pthread_mutex_init(&c->buffer_mutex, NULL); pthread_cond_init(&c->task_fifo_cond, NULL); pthread_cond_init(&c->finished_task_cond, NULL); + atomic_init(&c->exit, 0); for(i=0; ithread_count ; i++){ AVDictionary *tmp = NULL; @@ -236,7 +239,7 @@ void ff_frame_thread_encoder_free(AVCodecContext *avctx){ ThreadContext *c= avctx->internal->frame_thread_encoder; pthread_mutex_lock(&c->task_fifo_mutex); - c->exit = 1; + atomic_store(&c->exit, 1); pthread_cond_broadcast(&c->task_fifo_cond); pthread_mutex_unlock(&c->task_fifo_mutex); From 4c88087f934b24caa1dc3a333501223438eb462a Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 10 Sep 2017 22:10:43 +0200 Subject: [PATCH 3060/3374] avformat/mxfenc: Replace more literal magic numbers by enum values. This also moves the enum table up as it is needed earlier Signed-off-by: Michael Niedermayer --- libavformat/mxfenc.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index cc9ec8c93a071..893ab13ac7d26 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -100,27 +100,7 @@ typedef struct MXFContainerEssenceEntry { void (*write_desc)(AVFormatContext *, AVStream *); } MXFContainerEssenceEntry; -static const struct { - enum AVCodecID id; - int index; -} mxf_essence_mappings[] = { - { AV_CODEC_ID_MPEG2VIDEO, 0 }, - { AV_CODEC_ID_PCM_S24LE, 1 }, - { AV_CODEC_ID_PCM_S16LE, 1 }, - { AV_CODEC_ID_DVVIDEO, 15 }, - { AV_CODEC_ID_DNXHD, 24 }, - { AV_CODEC_ID_JPEG2000, 34 }, - { AV_CODEC_ID_H264, 35 }, - { AV_CODEC_ID_NONE } -}; - -static void mxf_write_wav_desc(AVFormatContext *s, AVStream *st); -static void mxf_write_aes3_desc(AVFormatContext *s, AVStream *st); -static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st); -static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st); -static void mxf_write_generic_sound_desc(AVFormatContext *s, AVStream *st); - -enum { +enum ULIndex { INDEX_MPEG2 = 0, INDEX_AES3, INDEX_WAV, @@ -159,6 +139,26 @@ enum { INDEX_H264, }; +static const struct { + enum AVCodecID id; + enum ULIndex index; +} mxf_essence_mappings[] = { + { AV_CODEC_ID_MPEG2VIDEO, INDEX_MPEG2 }, + { AV_CODEC_ID_PCM_S24LE, INDEX_AES3 }, + { AV_CODEC_ID_PCM_S16LE, INDEX_AES3 }, + { AV_CODEC_ID_DVVIDEO, INDEX_DV }, + { AV_CODEC_ID_DNXHD, INDEX_DNXHD_1080p_10bit_HIGH }, + { AV_CODEC_ID_JPEG2000, INDEX_JPEG2000 }, + { AV_CODEC_ID_H264, INDEX_H264 }, + { AV_CODEC_ID_NONE } +}; + +static void mxf_write_wav_desc(AVFormatContext *s, AVStream *st); +static void mxf_write_aes3_desc(AVFormatContext *s, AVStream *st); +static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st); +static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st); +static void mxf_write_generic_sound_desc(AVFormatContext *s, AVStream *st); + static const MXFContainerEssenceEntry mxf_essence_container_uls[] = { { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x60,0x01 }, { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 }, From 4c33ec004fd879ccc7e927bd50604aa3fadf7e43 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 10 Sep 2017 22:10:44 +0200 Subject: [PATCH 3061/3374] avformat/mxfenc: Comment edit rate write code like the surrounding code Signed-off-by: Michael Niedermayer --- libavformat/mxfenc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index 893ab13ac7d26..8dc760e8f3be1 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -843,6 +843,7 @@ static void mxf_write_track(AVFormatContext *s, AVStream *st, enum MXFMetadataSe else avio_write(pb, sc->track_essence_element_key + 12, 4); + // write edit rate mxf_write_local_tag(pb, 8, 0x4B01); if (st == mxf->timecode_track && s->oformat == &ff_mxf_opatom_muxer){ From de03eb622d30f7e23e0b9c76e581ad8fd788dfb3 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 10 Sep 2017 22:10:45 +0200 Subject: [PATCH 3062/3374] avformat/mxfenc: Correct the Sample rate for PCM outside D10 Based on mail from IRT Signed-off-by: Michael Niedermayer --- libavformat/mxfenc.c | 17 ++++++++++++++--- tests/ref/fate/copy-trac4914 | 2 +- tests/ref/lavf/mxf | 6 +++--- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index 8dc760e8f3be1..7289e0b05b3b3 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -21,7 +21,7 @@ */ /* - * signal_standard, color_siting, store_user_comments and klv_fill_key version + * signal_standard, color_siting, store_user_comments, sample rate and klv_fill_key version * fixes sponsored by NOA GmbH */ @@ -1034,8 +1034,19 @@ static void mxf_write_generic_desc(AVFormatContext *s, AVStream *st, const UID k avio_wb32(pb, st->index+2); mxf_write_local_tag(pb, 8, 0x3001); - avio_wb32(pb, mxf->time_base.den); - avio_wb32(pb, mxf->time_base.num); + if (s->oformat == &ff_mxf_d10_muxer) { + avio_wb32(pb, mxf->time_base.den); + avio_wb32(pb, mxf->time_base.num); + } else { + if (st->codecpar->codec_id == AV_CODEC_ID_PCM_S16LE || + st->codecpar->codec_id == AV_CODEC_ID_PCM_S24LE) { + avio_wb32(pb, st->codecpar->sample_rate); + avio_wb32(pb, 1); + } else { + avio_wb32(pb, mxf->time_base.den); + avio_wb32(pb, mxf->time_base.num); + } + } mxf_write_local_tag(pb, 16, 0x3004); avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16); diff --git a/tests/ref/fate/copy-trac4914 b/tests/ref/fate/copy-trac4914 index ef06b8f816a00..e0864a0035ca9 100644 --- a/tests/ref/fate/copy-trac4914 +++ b/tests/ref/fate/copy-trac4914 @@ -1,4 +1,4 @@ -8868ae16d99ed03916e9dc7105285471 *tests/data/fate/copy-trac4914.mxf +d51f6bcc96885a2ce8517ae8c774f610 *tests/data/fate/copy-trac4914.mxf 560697 tests/data/fate/copy-trac4914.mxf #tb 0: 1001/30000 #media_type 0: video diff --git a/tests/ref/lavf/mxf b/tests/ref/lavf/mxf index 48fe95a235661..b9c37334a9735 100644 --- a/tests/ref/lavf/mxf +++ b/tests/ref/lavf/mxf @@ -1,9 +1,9 @@ -eaac3125ac1a61fe5f968c7af83fa71e *./tests/data/lavf/lavf.mxf +1c06a9d69b6e309579784db5ecb0b69f *./tests/data/lavf/lavf.mxf 525369 ./tests/data/lavf/lavf.mxf ./tests/data/lavf/lavf.mxf CRC=0x8dddfaab -1562530330b13e9e70f522fe20265632 *./tests/data/lavf/lavf.mxf +50b4f9ca0493e6d83f4c52dc3aa2b7a5 *./tests/data/lavf/lavf.mxf 560697 ./tests/data/lavf/lavf.mxf ./tests/data/lavf/lavf.mxf CRC=0xf21b1b48 -e07858715997313ae66a1cdd6fde5f66 *./tests/data/lavf/lavf.mxf +4b71b154ae37364c8028cb50850a54c5 *./tests/data/lavf/lavf.mxf 525369 ./tests/data/lavf/lavf.mxf ./tests/data/lavf/lavf.mxf CRC=0x8dddfaab From 04b9010f7f546dbe82e301fcb7fd3ea157d49155 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Tue, 12 Sep 2017 20:26:44 +0200 Subject: [PATCH 3063/3374] avfilter/af_dcshift: do not leak out frame Signed-off-by: Paul B Mahol --- libavfilter/af_dcshift.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavfilter/af_dcshift.c b/libavfilter/af_dcshift.c index 2ca2d075351e5..6d33daee0b62b 100644 --- a/libavfilter/af_dcshift.c +++ b/libavfilter/af_dcshift.c @@ -85,7 +85,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *ctx = inlink->dst; AVFilterLink *outlink = ctx->outputs[0]; - AVFrame *out = ff_get_audio_buffer(inlink, in->nb_samples); + AVFrame *out; DCShiftContext *s = ctx->priv; int i, j; double dcshift = s->dcshift; @@ -93,7 +93,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) if (av_frame_is_writable(in)) { out = in; } else { - out = ff_get_audio_buffer(inlink, in->nb_samples); + out = ff_get_audio_buffer(outlink, in->nb_samples); if (!out) { av_frame_free(&in); return AVERROR(ENOMEM); From 1db03e952b4ee998f2a19c037f60d17dc90e8f6c Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 12 Sep 2017 15:02:20 -0400 Subject: [PATCH 3064/3374] vp9: fix explicit memory order for report_progress. --- libavcodec/vp9.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 66ccb6c49ca01..6b5de19266f33 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -73,7 +73,7 @@ static int vp9_alloc_entries(AVCodecContext *avctx, int n) { static void vp9_report_tile_progress(VP9Context *s, int field, int n) { pthread_mutex_lock(&s->progress_mutex); - atomic_fetch_add_explicit(&s->entries[field], n, memory_order_relaxed); + atomic_fetch_add_explicit(&s->entries[field], n, memory_order_release); pthread_cond_signal(&s->progress_cond); pthread_mutex_unlock(&s->progress_mutex); } From 6eb102a616364d06a4cc994339b72910b3547e5f Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Mon, 15 May 2017 22:42:14 +0100 Subject: [PATCH 3065/3374] h264_sei: Add namespace prefix to all SEI values This avoids confusion with equivalent H.265 SEI values when both are being used at the same time. (cherry picked from commit 6ea220cbeec8863e2006a03b73bed52db2b13ee7) --- libavcodec/h264_parser.c | 26 ++++++++++---------- libavcodec/h264_sei.c | 20 ++++++++-------- libavcodec/h264_sei.h | 43 +++++++++++++++++----------------- libavcodec/h264_slice.c | 24 +++++++++---------- libavcodec/vaapi_encode_h264.c | 6 ++--- libavcodec/videotoolboxenc.c | 6 ++--- 6 files changed, 63 insertions(+), 62 deletions(-) diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c index 2564c6c6c35ac..dd0a965af033e 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -473,23 +473,23 @@ static inline int parse_nal_units(AVCodecParserContext *s, 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: + case H264_SEI_PIC_STRUCT_TOP_FIELD: + case H264_SEI_PIC_STRUCT_BOTTOM_FIELD: s->repeat_pict = 0; break; - case SEI_PIC_STRUCT_FRAME: - case SEI_PIC_STRUCT_TOP_BOTTOM: - case SEI_PIC_STRUCT_BOTTOM_TOP: + case H264_SEI_PIC_STRUCT_FRAME: + case H264_SEI_PIC_STRUCT_TOP_BOTTOM: + case H264_SEI_PIC_STRUCT_BOTTOM_TOP: s->repeat_pict = 1; break; - case SEI_PIC_STRUCT_TOP_BOTTOM_TOP: - case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM: + case H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP: + case H264_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM: s->repeat_pict = 2; break; - case SEI_PIC_STRUCT_FRAME_DOUBLING: + case H264_SEI_PIC_STRUCT_FRAME_DOUBLING: s->repeat_pict = 3; break; - case SEI_PIC_STRUCT_FRAME_TRIPLING: + case H264_SEI_PIC_STRUCT_FRAME_TRIPLING: s->repeat_pict = 5; break; default: @@ -504,12 +504,12 @@ static inline int parse_nal_units(AVCodecParserContext *s, s->picture_structure = AV_PICTURE_STRUCTURE_FRAME; 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: + case H264_SEI_PIC_STRUCT_TOP_BOTTOM: + case H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP: s->field_order = AV_FIELD_TT; break; - case SEI_PIC_STRUCT_BOTTOM_TOP: - case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM: + case H264_SEI_PIC_STRUCT_BOTTOM_TOP: + case H264_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM: s->field_order = AV_FIELD_BB; break; default: diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c index 889bea2ee0589..2afe48e2fe53b 100644 --- a/libavcodec/h264_sei.c +++ b/libavcodec/h264_sei.c @@ -81,7 +81,7 @@ static int decode_picture_timing(H264SEIPictureTiming *h, GetBitContext *gb, h->pic_struct = get_bits(gb, 4); h->ct_type = 0; - if (h->pic_struct > SEI_PIC_STRUCT_FRAME_TRIPLING) + if (h->pic_struct > H264_SEI_PIC_STRUCT_FRAME_TRIPLING) return AVERROR_INVALIDDATA; num_clock_ts = sei_num_clock_ts_table[h->pic_struct]; @@ -421,31 +421,31 @@ int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb, next = get_bits_count(gb) + 8 * size; switch (type) { - case SEI_TYPE_PIC_TIMING: // Picture timing SEI + case H264_SEI_TYPE_PIC_TIMING: // Picture timing SEI ret = decode_picture_timing(&h->picture_timing, gb, ps, logctx); break; - case SEI_TYPE_USER_DATA_REGISTERED: + case H264_SEI_TYPE_USER_DATA_REGISTERED: ret = decode_registered_user_data(h, gb, logctx, size); break; - case SEI_TYPE_USER_DATA_UNREGISTERED: + case H264_SEI_TYPE_USER_DATA_UNREGISTERED: ret = decode_unregistered_user_data(&h->unregistered, gb, logctx, size); break; - case SEI_TYPE_RECOVERY_POINT: + case H264_SEI_TYPE_RECOVERY_POINT: ret = decode_recovery_point(&h->recovery_point, gb); break; - case SEI_TYPE_BUFFERING_PERIOD: + case H264_SEI_TYPE_BUFFERING_PERIOD: ret = decode_buffering_period(&h->buffering_period, gb, ps, logctx); break; - case SEI_TYPE_FRAME_PACKING: + case H264_SEI_TYPE_FRAME_PACKING: ret = decode_frame_packing_arrangement(&h->frame_packing, gb); break; - case SEI_TYPE_DISPLAY_ORIENTATION: + case H264_SEI_TYPE_DISPLAY_ORIENTATION: ret = decode_display_orientation(&h->display_orientation, gb); break; - case SEI_TYPE_GREEN_METADATA: + case H264_SEI_TYPE_GREEN_METADATA: ret = decode_green_metadata(&h->green_metadata, gb); break; - case SEI_TYPE_ALTERNATIVE_TRANSFER: + case H264_SEI_TYPE_ALTERNATIVE_TRANSFER: ret = decode_alternative_transfer(&h->alternative_transfer, gb); break; default: diff --git a/libavcodec/h264_sei.h b/libavcodec/h264_sei.h index 5f5d895e89847..8cad5ea99785f 100644 --- a/libavcodec/h264_sei.h +++ b/libavcodec/h264_sei.h @@ -25,31 +25,32 @@ * SEI message types */ typedef enum { - SEI_TYPE_BUFFERING_PERIOD = 0, ///< buffering period (H.264, D.1.1) - SEI_TYPE_PIC_TIMING = 1, ///< picture timing - SEI_TYPE_USER_DATA_REGISTERED = 4, ///< registered user data as specified by Rec. ITU-T T.35 - SEI_TYPE_USER_DATA_UNREGISTERED = 5, ///< unregistered user data - SEI_TYPE_RECOVERY_POINT = 6, ///< recovery point (frame # to decoder sync) - SEI_TYPE_FRAME_PACKING = 45, ///< frame packing arrangement - SEI_TYPE_DISPLAY_ORIENTATION = 47, ///< display orientation - SEI_TYPE_GREEN_METADATA = 56, ///< GreenMPEG information - SEI_TYPE_ALTERNATIVE_TRANSFER = 147, ///< alternative transfer -} SEI_Type; + H264_SEI_TYPE_BUFFERING_PERIOD = 0, ///< buffering period (H.264, D.1.1) + H264_SEI_TYPE_PIC_TIMING = 1, ///< picture timing + H264_SEI_TYPE_FILLER_PAYLOAD = 3, ///< filler data + H264_SEI_TYPE_USER_DATA_REGISTERED = 4, ///< registered user data as specified by Rec. ITU-T T.35 + H264_SEI_TYPE_USER_DATA_UNREGISTERED = 5, ///< unregistered user data + H264_SEI_TYPE_RECOVERY_POINT = 6, ///< recovery point (frame # to decoder sync) + H264_SEI_TYPE_FRAME_PACKING = 45, ///< frame packing arrangement + H264_SEI_TYPE_DISPLAY_ORIENTATION = 47, ///< display orientation + H264_SEI_TYPE_GREEN_METADATA = 56, ///< GreenMPEG information + H264_SEI_TYPE_ALTERNATIVE_TRANSFER = 147, ///< alternative transfer +} H264_SEI_Type; /** * pic_struct in picture timing SEI message */ typedef enum { - SEI_PIC_STRUCT_FRAME = 0, ///< 0: %frame - SEI_PIC_STRUCT_TOP_FIELD = 1, ///< 1: top field - SEI_PIC_STRUCT_BOTTOM_FIELD = 2, ///< 2: bottom field - SEI_PIC_STRUCT_TOP_BOTTOM = 3, ///< 3: top field, bottom field, in that order - SEI_PIC_STRUCT_BOTTOM_TOP = 4, ///< 4: bottom field, top field, in that order - SEI_PIC_STRUCT_TOP_BOTTOM_TOP = 5, ///< 5: top field, bottom field, top field repeated, in that order - SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM = 6, ///< 6: bottom field, top field, bottom field repeated, in that order - SEI_PIC_STRUCT_FRAME_DOUBLING = 7, ///< 7: %frame doubling - SEI_PIC_STRUCT_FRAME_TRIPLING = 8 ///< 8: %frame tripling -} SEI_PicStructType; + H264_SEI_PIC_STRUCT_FRAME = 0, ///< 0: %frame + H264_SEI_PIC_STRUCT_TOP_FIELD = 1, ///< 1: top field + H264_SEI_PIC_STRUCT_BOTTOM_FIELD = 2, ///< 2: bottom field + H264_SEI_PIC_STRUCT_TOP_BOTTOM = 3, ///< 3: top field, bottom field, in that order + H264_SEI_PIC_STRUCT_BOTTOM_TOP = 4, ///< 4: bottom field, top field, in that order + H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP = 5, ///< 5: top field, bottom field, top field repeated, in that order + H264_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM = 6, ///< 6: bottom field, top field, bottom field repeated, in that order + H264_SEI_PIC_STRUCT_FRAME_DOUBLING = 7, ///< 7: %frame doubling + H264_SEI_PIC_STRUCT_FRAME_TRIPLING = 8 ///< 8: %frame tripling +} H264_SEI_PicStructType; /** * frame_packing_arrangement types @@ -66,7 +67,7 @@ typedef enum { typedef struct H264SEIPictureTiming { int present; - SEI_PicStructType pic_struct; + H264_SEI_PicStructType pic_struct; /** * Bit set of clock types for fields/frames in picture timing SEI message. diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index ebff7b33e38b2..2577edd8a6d9f 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1150,37 +1150,37 @@ static int h264_export_frame_props(H264Context *h) 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: + case H264_SEI_PIC_STRUCT_FRAME: break; - case SEI_PIC_STRUCT_TOP_FIELD: - case SEI_PIC_STRUCT_BOTTOM_FIELD: + case H264_SEI_PIC_STRUCT_TOP_FIELD: + case H264_SEI_PIC_STRUCT_BOTTOM_FIELD: cur->f->interlaced_frame = 1; break; - case SEI_PIC_STRUCT_TOP_BOTTOM: - case SEI_PIC_STRUCT_BOTTOM_TOP: + case H264_SEI_PIC_STRUCT_TOP_BOTTOM: + case H264_SEI_PIC_STRUCT_BOTTOM_TOP: if (FIELD_OR_MBAFF_PICTURE(h)) cur->f->interlaced_frame = 1; else // try to flag soft telecine progressive cur->f->interlaced_frame = h->prev_interlaced_frame; break; - case SEI_PIC_STRUCT_TOP_BOTTOM_TOP: - case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM: + case H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP: + case H264_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM: /* Signal the possibility of telecined film externally * (pic_struct 5,6). From these hints, let the applications * decide if they apply deinterlacing. */ cur->f->repeat_pict = 1; break; - case SEI_PIC_STRUCT_FRAME_DOUBLING: + case H264_SEI_PIC_STRUCT_FRAME_DOUBLING: cur->f->repeat_pict = 2; break; - case SEI_PIC_STRUCT_FRAME_TRIPLING: + case H264_SEI_PIC_STRUCT_FRAME_TRIPLING: cur->f->repeat_pict = 4; break; } if ((pt->ct_type & 3) && - pt->pic_struct <= SEI_PIC_STRUCT_BOTTOM_TOP) + pt->pic_struct <= H264_SEI_PIC_STRUCT_BOTTOM_TOP) cur->f->interlaced_frame = (pt->ct_type & (1 << 1)) != 0; } else { /* Derive interlacing flag from used decoding process. */ @@ -1195,8 +1195,8 @@ static int h264_export_frame_props(H264Context *h) 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 || - h->sei.picture_timing.pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM_TOP) + if (h->sei.picture_timing.pic_struct == H264_SEI_PIC_STRUCT_TOP_BOTTOM || + h->sei.picture_timing.pic_struct == H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP) cur->f->top_field_first = 1; else cur->f->top_field_first = 0; diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index 90c7f7e3ccc85..549867ef3f51b 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -644,18 +644,18 @@ static void vaapi_encode_h264_write_sei(PutBitContext *pbc, for (payload_type = 0; payload_type < 64; payload_type++) { switch (payload_type) { - case SEI_TYPE_BUFFERING_PERIOD: + case H264_SEI_TYPE_BUFFERING_PERIOD: if (!priv->send_timing_sei || pic->type != PICTURE_TYPE_IDR) continue; write_payload = &vaapi_encode_h264_write_buffering_period; break; - case SEI_TYPE_PIC_TIMING: + case H264_SEI_TYPE_PIC_TIMING: if (!priv->send_timing_sei) continue; write_payload = &vaapi_encode_h264_write_pic_timing; break; - case SEI_TYPE_USER_DATA_UNREGISTERED: + case H264_SEI_TYPE_USER_DATA_UNREGISTERED: if (pic->encode_order != 0) continue; write_payload = &vaapi_encode_h264_write_identifier; diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c index 22eaeb0a60904..eba6cc672f81d 100644 --- a/libavcodec/videotoolboxenc.c +++ b/libavcodec/videotoolboxenc.c @@ -1599,7 +1599,7 @@ static int copy_replace_length_codes( remaining_dst_size--; wrote_bytes = write_sei(sei, - SEI_TYPE_USER_DATA_REGISTERED, + H264_SEI_TYPE_USER_DATA_REGISTERED, dst_data, remaining_dst_size); @@ -1655,7 +1655,7 @@ static int copy_replace_length_codes( return status; wrote_bytes = write_sei(sei, - SEI_TYPE_USER_DATA_REGISTERED, + H264_SEI_TYPE_USER_DATA_REGISTERED, new_sei, remaining_dst_size - old_sei_length); if (wrote_bytes < 0) @@ -1751,7 +1751,7 @@ static int vtenc_cm_to_avpacket( if (sei) { size_t msg_size = get_sei_msg_bytes(sei, - SEI_TYPE_USER_DATA_REGISTERED); + H264_SEI_TYPE_USER_DATA_REGISTERED); sei_nalu_size = sizeof(start_code) + 1 + msg_size + 1; } From 9669c05baf37025f6fa038dc6b00b45f9c57de90 Mon Sep 17 00:00:00 2001 From: James Almer Date: Tue, 12 Sep 2017 19:59:23 -0300 Subject: [PATCH 3066/3374] avcodec/h264_sei: add namespace prefix to frame packingarrangement enum values Missed in 6eb102a616364d06a4cc994339b72910b3547e5f. Signed-off-by: James Almer --- libavcodec/h264_sei.c | 14 +++++++------- libavcodec/h264_sei.h | 18 +++++++++--------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c index 2afe48e2fe53b..332ae508606c0 100644 --- a/libavcodec/h264_sei.c +++ b/libavcodec/h264_sei.c @@ -469,37 +469,37 @@ const char *ff_h264_sei_stereo_mode(const H264SEIFramePacking *h) { if (h->frame_packing_arrangement_cancel_flag == 0) { switch (h->frame_packing_arrangement_type) { - case SEI_FPA_TYPE_CHECKERBOARD: + case H264_SEI_FPA_TYPE_CHECKERBOARD: if (h->content_interpretation_type == 2) return "checkerboard_rl"; else return "checkerboard_lr"; - case SEI_FPA_TYPE_INTERLEAVE_COLUMN: + case H264_SEI_FPA_TYPE_INTERLEAVE_COLUMN: if (h->content_interpretation_type == 2) return "col_interleaved_rl"; else return "col_interleaved_lr"; - case SEI_FPA_TYPE_INTERLEAVE_ROW: + case H264_SEI_FPA_TYPE_INTERLEAVE_ROW: if (h->content_interpretation_type == 2) return "row_interleaved_rl"; else return "row_interleaved_lr"; - case SEI_FPA_TYPE_SIDE_BY_SIDE: + case H264_SEI_FPA_TYPE_SIDE_BY_SIDE: if (h->content_interpretation_type == 2) return "right_left"; else return "left_right"; - case SEI_FPA_TYPE_TOP_BOTTOM: + case H264_SEI_FPA_TYPE_TOP_BOTTOM: if (h->content_interpretation_type == 2) return "bottom_top"; else return "top_bottom"; - case SEI_FPA_TYPE_INTERLEAVE_TEMPORAL: + case H264_SEI_FPA_TYPE_INTERLEAVE_TEMPORAL: if (h->content_interpretation_type == 2) return "block_rl"; else return "block_lr"; - case SEI_FPA_TYPE_2D: + case H264_SEI_FPA_TYPE_2D: default: return "mono"; } diff --git a/libavcodec/h264_sei.h b/libavcodec/h264_sei.h index 8cad5ea99785f..a53f1899fade5 100644 --- a/libavcodec/h264_sei.h +++ b/libavcodec/h264_sei.h @@ -56,14 +56,14 @@ typedef enum { * frame_packing_arrangement types */ typedef enum { - SEI_FPA_TYPE_CHECKERBOARD = 0, - SEI_FPA_TYPE_INTERLEAVE_COLUMN = 1, - SEI_FPA_TYPE_INTERLEAVE_ROW = 2, - SEI_FPA_TYPE_SIDE_BY_SIDE = 3, - SEI_FPA_TYPE_TOP_BOTTOM = 4, - SEI_FPA_TYPE_INTERLEAVE_TEMPORAL = 5, - SEI_FPA_TYPE_2D = 6, -} SEI_FpaType; + H264_SEI_FPA_TYPE_CHECKERBOARD = 0, + H264_SEI_FPA_TYPE_INTERLEAVE_COLUMN = 1, + H264_SEI_FPA_TYPE_INTERLEAVE_ROW = 2, + H264_SEI_FPA_TYPE_SIDE_BY_SIDE = 3, + H264_SEI_FPA_TYPE_TOP_BOTTOM = 4, + H264_SEI_FPA_TYPE_INTERLEAVE_TEMPORAL = 5, + H264_SEI_FPA_TYPE_2D = 6, +} H264_SEI_FpaType; typedef struct H264SEIPictureTiming { int present; @@ -121,7 +121,7 @@ typedef struct H264SEIFramePacking { int present; int frame_packing_arrangement_id; int frame_packing_arrangement_cancel_flag; ///< is previous arrangement canceled, -1 if never received - SEI_FpaType frame_packing_arrangement_type; + H264_SEI_FpaType frame_packing_arrangement_type; int frame_packing_arrangement_repetition_period; int content_interpretation_type; int quincunx_sampling_flag; From 6ce4a635ed19db9003dae36f52d432f2b8988bb7 Mon Sep 17 00:00:00 2001 From: Paras Chadha Date: Sun, 3 Sep 2017 00:37:22 +0530 Subject: [PATCH 3067/3374] avformat/fitsenc: fill header line with spaces Signed-off-by: Paras Chadha Signed-off-by: James Almer --- libavformat/fitsenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/fitsenc.c b/libavformat/fitsenc.c index 0dcdcdfb04f31..7cb171596c4e2 100644 --- a/libavformat/fitsenc.c +++ b/libavformat/fitsenc.c @@ -58,7 +58,7 @@ static int write_keyword_value(AVFormatContext *s, const char *keyword, int valu header[9] = ' '; ret = snprintf(header + 10, 70, "%d", value); - header[ret + 10] = ' '; + memset(&header[ret + 10], ' ', sizeof(header) - (ret + 10)); avio_write(s->pb, header, sizeof(header)); *lines_written += 1; From 4d390344ec385f8eb7d46456df48cb07a0f946b0 Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 13 Sep 2017 14:07:21 -0300 Subject: [PATCH 3068/3374] configure: check if NAN can be used as a constant initializer Some targets, like NetBSD and DJGPP, don't seem to support it. Signed-off-by: James Almer --- configure | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 4dd11efe5e72e..6e3a3509c6b3e 100755 --- a/configure +++ b/configure @@ -3210,6 +3210,7 @@ pixfmts_super2xsai_test_deps="super2xsai_filter" tinterlace_filter_deps="gpl" tinterlace_merge_test_deps="tinterlace_filter" tinterlace_pad_test_deps="tinterlace_filter" +tonemap_filter_deps="const_nan" uspp_filter_deps="gpl avcodec" vaguedenoiser_filter_deps="gpl" vidstabdetect_filter_deps="libvidstab" @@ -3217,7 +3218,7 @@ vidstabtransform_filter_deps="libvidstab" libvmaf_filter_deps="libvmaf" zmq_filter_deps="libzmq" zoompan_filter_deps="swscale" -zscale_filter_deps="libzimg" +zscale_filter_deps="libzimg const_nan" scale_vaapi_filter_deps="vaapi VAProcPipelineParameterBuffer" # examples @@ -5312,6 +5313,11 @@ unsigned int endian = 'B' << 24 | 'I' << 16 | 'G' << 8 | 'E'; EOF od -t x1 $TMPO | grep -q '42 *49 *47 *45' && enable bigendian +check_cc < +void foo(void) { struct { double d; } static const bar[] = { { NAN } }; } +EOF + if ! enabled ppc64 || enabled bigendian; then disable vsx fi From 7bae17e37ab63d1cfcea22c68c455f859db3663c Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 13 Sep 2017 17:03:56 -0300 Subject: [PATCH 3069/3374] avcodec/extract_extradata: return an error when buffer allocation fails ret is 0 by default. Reviewed-by: Mark Thompson Signed-off-by: James Almer --- libavcodec/extract_extradata_bsf.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/extract_extradata_bsf.c b/libavcodec/extract_extradata_bsf.c index 4cd0ca1137626..ed6509c681add 100644 --- a/libavcodec/extract_extradata_bsf.c +++ b/libavcodec/extract_extradata_bsf.c @@ -101,14 +101,17 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt, if (s->remove) { filtered_buf = av_buffer_alloc(pkt->size + AV_INPUT_BUFFER_PADDING_SIZE); - if (!filtered_buf) + if (!filtered_buf) { + ret = AVERROR(ENOMEM); goto fail; + } filtered_data = filtered_buf->data; } extradata = av_malloc(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); if (!extradata) { av_buffer_unref(&filtered_buf); + ret = AVERROR(ENOMEM); goto fail; } From 9cb23cd9fe58e262273ce606b6febfef0509e316 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 18 Jun 2017 18:16:27 +0100 Subject: [PATCH 3070/3374] lavu: Add DRM hwcontext --- configure | 3 + doc/APIchanges | 3 + libavutil/Makefile | 2 + libavutil/hwcontext.c | 4 + libavutil/hwcontext.h | 1 + libavutil/hwcontext_drm.c | 289 +++++++++++++++++++++++++++++++++ libavutil/hwcontext_drm.h | 166 +++++++++++++++++++ libavutil/hwcontext_internal.h | 1 + libavutil/pixdesc.c | 4 + libavutil/pixfmt.h | 7 + libavutil/version.h | 2 +- 11 files changed, 481 insertions(+), 1 deletion(-) create mode 100644 libavutil/hwcontext_drm.c create mode 100644 libavutil/hwcontext_drm.h diff --git a/configure b/configure index 6e3a3509c6b3e..832f26ba10995 100755 --- a/configure +++ b/configure @@ -307,6 +307,7 @@ External library support: --disable-cuvid disable Nvidia CUVID support [autodetect] --disable-d3d11va disable Microsoft Direct3D 11 video acceleration code [autodetect] --disable-dxva2 disable Microsoft DirectX 9 video acceleration code [autodetect] + --enable-libdrm enable DRM code (Linux) [no] --enable-libmfx enable Intel MediaSDK (AKA Quick Sync Video) code via libmfx [no] --enable-libnpp enable Nvidia Performance Primitives-based code [no] --enable-mmal enable Broadcom Multi-Media Abstraction Layer (Raspberry Pi) via MMAL [no] @@ -1567,6 +1568,7 @@ EXTERNAL_LIBRARY_LIST=" libcaca libcelt libdc1394 + libdrm libflite libfontconfig libfreetype @@ -5877,6 +5879,7 @@ enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 && die "ERROR: libcelt must be installed and version must be >= 0.11.0."; } enabled libcaca && require_pkg_config caca caca.h caca_create_canvas enabled libdc1394 && require_pkg_config libdc1394-2 dc1394/dc1394.h dc1394_new +enabled libdrm && require_pkg_config libdrm xf86drm.h drmGetVersion enabled libfdk_aac && { use_pkg_config fdk-aac "fdk-aac/aacenc_lib.h" aacEncOpen || { require libfdk_aac fdk-aac/aacenc_lib.h aacEncOpen -lfdk-aac && warn "using libfdk without pkg-config"; } } diff --git a/doc/APIchanges b/doc/APIchanges index cc67cbf6f8767..c37de0613829b 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-09-13 - xxxxxxx - lavu 55.75.100 - hwcontext.h hwcontext_drm.h + Add AV_HWDEVICE_TYPE_DRM and implementation. + 2017-09-08 - xxxxxxx - lavfi 6.103.100 - buffersrc.h Add av_buffersrc_close(). diff --git a/libavutil/Makefile b/libavutil/Makefile index e45871fd1116f..65e285a70114a 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -34,6 +34,7 @@ HEADERS = adler32.h \ hwcontext.h \ hwcontext_cuda.h \ hwcontext_d3d11va.h \ + hwcontext_drm.h \ hwcontext_dxva2.h \ hwcontext_qsv.h \ hwcontext_vaapi.h \ @@ -161,6 +162,7 @@ OBJS-$(CONFIG_CUDA) += hwcontext_cuda.o OBJS-$(CONFIG_D3D11VA) += hwcontext_d3d11va.o OBJS-$(CONFIG_DXVA2) += hwcontext_dxva2.o OBJS-$(CONFIG_QSV) += hwcontext_qsv.o +OBJS-$(CONFIG_LIBDRM) += hwcontext_drm.o OBJS-$(CONFIG_LZO) += lzo.o OBJS-$(CONFIG_OPENCL) += opencl.o opencl_internal.o OBJS-$(CONFIG_VAAPI) += hwcontext_vaapi.o diff --git a/libavutil/hwcontext.c b/libavutil/hwcontext.c index 2a755a6878731..aa6b3ad176d0c 100644 --- a/libavutil/hwcontext.c +++ b/libavutil/hwcontext.c @@ -35,6 +35,9 @@ static const HWContextType *const hw_table[] = { #if CONFIG_D3D11VA &ff_hwcontext_type_d3d11va, #endif +#if CONFIG_LIBDRM + &ff_hwcontext_type_drm, +#endif #if CONFIG_DXVA2 &ff_hwcontext_type_dxva2, #endif @@ -55,6 +58,7 @@ static const HWContextType *const hw_table[] = { static const char *const hw_type_names[] = { [AV_HWDEVICE_TYPE_CUDA] = "cuda", + [AV_HWDEVICE_TYPE_DRM] = "drm", [AV_HWDEVICE_TYPE_DXVA2] = "dxva2", [AV_HWDEVICE_TYPE_D3D11VA] = "d3d11va", [AV_HWDEVICE_TYPE_QSV] = "qsv", diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h index afb0d80d5964a..03334e20e06ca 100644 --- a/libavutil/hwcontext.h +++ b/libavutil/hwcontext.h @@ -33,6 +33,7 @@ enum AVHWDeviceType { AV_HWDEVICE_TYPE_VIDEOTOOLBOX, AV_HWDEVICE_TYPE_NONE, AV_HWDEVICE_TYPE_D3D11VA, + AV_HWDEVICE_TYPE_DRM, }; typedef struct AVHWDeviceInternal AVHWDeviceInternal; diff --git a/libavutil/hwcontext_drm.c b/libavutil/hwcontext_drm.c new file mode 100644 index 0000000000000..32cbde82ebfae --- /dev/null +++ b/libavutil/hwcontext_drm.c @@ -0,0 +1,289 @@ +/* + * 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 +#include +#include + +#include +#include + +#include "avassert.h" +#include "hwcontext.h" +#include "hwcontext_drm.h" +#include "hwcontext_internal.h" +#include "imgutils.h" + + +static void drm_device_free(AVHWDeviceContext *hwdev) +{ + AVDRMDeviceContext *hwctx = hwdev->hwctx; + + close(hwctx->fd); +} + +static int drm_device_create(AVHWDeviceContext *hwdev, const char *device, + AVDictionary *opts, int flags) +{ + AVDRMDeviceContext *hwctx = hwdev->hwctx; + drmVersionPtr version; + + hwctx->fd = open(device, O_RDWR); + if (hwctx->fd < 0) + return AVERROR(errno); + + version = drmGetVersion(hwctx->fd); + if (!version) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get version information " + "from %s: probably not a DRM device?\n", device); + close(hwctx->fd); + return AVERROR(EINVAL); + } + + av_log(hwdev, AV_LOG_VERBOSE, "Opened DRM device %s: driver %s " + "version %d.%d.%d.\n", device, version->name, + version->version_major, version->version_minor, + version->version_patchlevel); + + drmFreeVersion(version); + + hwdev->free = &drm_device_free; + + return 0; +} + +static int drm_get_buffer(AVHWFramesContext *hwfc, AVFrame *frame) +{ + frame->buf[0] = av_buffer_pool_get(hwfc->pool); + if (!frame->buf[0]) + return AVERROR(ENOMEM); + + frame->data[0] = (uint8_t*)frame->buf[0]->data; + + frame->format = AV_PIX_FMT_DRM_PRIME; + frame->width = hwfc->width; + frame->height = hwfc->height; + + return 0; +} + +typedef struct DRMMapping { + // Address and length of each mmap()ed region. + int nb_regions; + void *address[AV_DRM_MAX_PLANES]; + size_t length[AV_DRM_MAX_PLANES]; +} DRMMapping; + +static void drm_unmap_frame(AVHWFramesContext *hwfc, + HWMapDescriptor *hwmap) +{ + DRMMapping *map = hwmap->priv; + int i; + + for (i = 0; i < map->nb_regions; i++) + munmap(map->address[i], map->length[i]); + + av_free(map); +} + +static int drm_map_frame(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src, int flags) +{ + const AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor*)src->data[0]; + DRMMapping *map; + int err, i, p, plane; + int mmap_prot; + void *addr; + + map = av_mallocz(sizeof(*map)); + if (!map) + return AVERROR(ENOMEM); + + mmap_prot = 0; + if (flags & AV_HWFRAME_MAP_READ) + mmap_prot |= PROT_READ; + if (flags & AV_HWFRAME_MAP_WRITE) + mmap_prot |= PROT_WRITE; + + av_assert0(desc->nb_objects <= AV_DRM_MAX_PLANES); + for (i = 0; i < desc->nb_objects; i++) { + addr = mmap(NULL, desc->objects[i].size, mmap_prot, MAP_SHARED, + desc->objects[i].fd, 0); + if (addr == MAP_FAILED) { + err = AVERROR(errno); + av_log(hwfc, AV_LOG_ERROR, "Failed to map DRM object %d to " + "memory: %d.\n", desc->objects[i].fd, errno); + goto fail; + } + + map->address[i] = addr; + map->length[i] = desc->objects[i].size; + } + map->nb_regions = i; + + plane = 0; + for (i = 0; i < desc->nb_layers; i++) { + const AVDRMLayerDescriptor *layer = &desc->layers[i]; + for (p = 0; p < layer->nb_planes; p++) { + dst->data[plane] = + (uint8_t*)map->address[layer->planes[p].object_index] + + layer->planes[p].offset; + dst->linesize[plane] = layer->planes[p].pitch; + ++plane; + } + } + av_assert0(plane <= AV_DRM_MAX_PLANES); + + dst->width = src->width; + dst->height = src->height; + + err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, + &drm_unmap_frame, map); + if (err < 0) + goto fail; + + return 0; + +fail: + for (i = 0; i < desc->nb_objects; i++) { + if (map->address[i]) + munmap(map->address[i], map->length[i]); + } + av_free(map); + return err; +} + +static int drm_transfer_get_formats(AVHWFramesContext *ctx, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats) +{ + enum AVPixelFormat *pix_fmts; + + pix_fmts = av_malloc_array(2, sizeof(*pix_fmts)); + if (!pix_fmts) + return AVERROR(ENOMEM); + + pix_fmts[0] = ctx->sw_format; + pix_fmts[1] = AV_PIX_FMT_NONE; + + *formats = pix_fmts; + return 0; +} + +static int drm_transfer_data_from(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src) +{ + AVFrame *map; + int err; + + if (dst->width > hwfc->width || dst->height > hwfc->height) + return AVERROR(EINVAL); + + map = av_frame_alloc(); + if (!map) + return AVERROR(ENOMEM); + map->format = dst->format; + + err = drm_map_frame(hwfc, map, src, AV_HWFRAME_MAP_READ); + if (err) + goto fail; + + map->width = dst->width; + map->height = dst->height; + + err = av_frame_copy(dst, map); + if (err) + goto fail; + + err = 0; +fail: + av_frame_free(&map); + return err; +} + +static int drm_transfer_data_to(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src) +{ + AVFrame *map; + int err; + + if (src->width > hwfc->width || src->height > hwfc->height) + return AVERROR(EINVAL); + + map = av_frame_alloc(); + if (!map) + return AVERROR(ENOMEM); + map->format = src->format; + + err = drm_map_frame(hwfc, map, dst, AV_HWFRAME_MAP_WRITE | + AV_HWFRAME_MAP_OVERWRITE); + if (err) + goto fail; + + map->width = src->width; + map->height = src->height; + + err = av_frame_copy(map, src); + if (err) + goto fail; + + err = 0; +fail: + av_frame_free(&map); + return err; +} + +static int drm_map_from(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + int err; + + if (hwfc->sw_format != dst->format) + return AVERROR(ENOSYS); + + err = drm_map_frame(hwfc, dst, src, flags); + if (err) + return err; + + err = av_frame_copy_props(dst, src); + if (err) + return err; + + return 0; +} + +const HWContextType ff_hwcontext_type_drm = { + .type = AV_HWDEVICE_TYPE_DRM, + .name = "DRM", + + .device_hwctx_size = sizeof(AVDRMDeviceContext), + + .device_create = &drm_device_create, + + .frames_get_buffer = &drm_get_buffer, + + .transfer_get_formats = &drm_transfer_get_formats, + .transfer_data_to = &drm_transfer_data_to, + .transfer_data_from = &drm_transfer_data_from, + .map_from = &drm_map_from, + + .pix_fmts = (const enum AVPixelFormat[]) { + AV_PIX_FMT_DRM_PRIME, + AV_PIX_FMT_NONE + }, +}; diff --git a/libavutil/hwcontext_drm.h b/libavutil/hwcontext_drm.h new file mode 100644 index 0000000000000..2e225451e1158 --- /dev/null +++ b/libavutil/hwcontext_drm.h @@ -0,0 +1,166 @@ +/* + * 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 + */ + +#ifndef AVUTIL_HWCONTEXT_DRM_H +#define AVUTIL_HWCONTEXT_DRM_H + +#include +#include + +/** + * @file + * API-specific header for AV_HWDEVICE_TYPE_DRM. + * + * Internal frame allocation is not currently supported - all frames + * must be allocated by the user. Thus AVHWFramesContext is always + * NULL, though this may change if support for frame allocation is + * added in future. + */ + +enum { + /** + * The maximum number of layers/planes in a DRM frame. + */ + AV_DRM_MAX_PLANES = 4 +}; + +/** + * DRM object descriptor. + * + * Describes a single DRM object, addressing it as a PRIME file + * descriptor. + */ +typedef struct AVDRMObjectDescriptor { + /** + * DRM PRIME fd for the object. + */ + int fd; + /** + * Total size of the object. + * + * (This includes any parts not which do not contain image data.) + */ + size_t size; + /** + * Format modifier applied to the object (DRM_FORMAT_MOD_*). + */ + uint64_t format_modifier; +} AVDRMObjectDescriptor; + +/** + * DRM plane descriptor. + * + * Describes a single plane of a layer, which is contained within + * a single object. + */ +typedef struct AVDRMPlaneDescriptor { + /** + * Index of the object containing this plane in the objects + * array of the enclosing frame descriptor. + */ + int object_index; + /** + * Offset within that object of this plane. + */ + ptrdiff_t offset; + /** + * Pitch (linesize) of this plane. + */ + ptrdiff_t pitch; +} AVDRMPlaneDescriptor; + +/** + * DRM layer descriptor. + * + * Describes a single layer within a frame. This has the structure + * defined by its format, and will contain one or more planes. + */ +typedef struct AVDRMLayerDescriptor { + /** + * Format of the layer (DRM_FORMAT_*). + */ + uint32_t format; + /** + * Number of planes in the layer. + * + * This must match the number of planes required by format. + */ + int nb_planes; + /** + * Array of planes in this layer. + */ + AVDRMPlaneDescriptor planes[AV_DRM_MAX_PLANES]; +} AVDRMLayerDescriptor; + +/** + * DRM frame descriptor. + * + * This is used as the data pointer for AV_PIX_FMT_DRM_PRIME frames. + * It is also used by user-allocated frame pools - allocating in + * AVHWFramesContext.pool must return AVBufferRefs which contain + * an object of this type. + * + * The fields of this structure should be set such it can be + * imported directly by EGL using the EGL_EXT_image_dma_buf_import + * and EGL_EXT_image_dma_buf_import_modifiers extensions. + * (Note that the exact layout of a particular format may vary between + * platforms - we only specify that the same platform should be able + * to import it.) + * + * The total number of planes must not exceed AV_DRM_MAX_PLANES, and + * the order of the planes by increasing layer index followed by + * increasing plane index must be the same as the order which would + * be used for the data pointers in the equivalent software format. + */ +typedef struct AVDRMFrameDescriptor { + /** + * Number of DRM objects making up this frame. + */ + int nb_objects; + /** + * Array of objects making up the frame. + */ + AVDRMObjectDescriptor objects[AV_DRM_MAX_PLANES]; + /** + * Number of layers in the frame. + */ + int nb_layers; + /** + * Array of layers in the frame. + */ + AVDRMLayerDescriptor layers[AV_DRM_MAX_PLANES]; +} AVDRMFrameDescriptor; + +/** + * DRM device. + * + * Allocated as AVHWDeviceContext.hwctx. + */ +typedef struct AVDRMDeviceContext { + /** + * File descriptor of DRM device. + * + * This is used as the device to create frames on, and may also be + * used in some derivation and mapping operations. + * + * If no device is required, set to -1. + */ + int fd; +} AVDRMDeviceContext; + +#endif /* AVUTIL_HWCONTEXT_DRM_H */ diff --git a/libavutil/hwcontext_internal.h b/libavutil/hwcontext_internal.h index c4913a649f063..2d75d3db0877e 100644 --- a/libavutil/hwcontext_internal.h +++ b/libavutil/hwcontext_internal.h @@ -159,6 +159,7 @@ int ff_hwframe_map_create(AVBufferRef *hwframe_ref, extern const HWContextType ff_hwcontext_type_cuda; extern const HWContextType ff_hwcontext_type_d3d11va; +extern const HWContextType ff_hwcontext_type_drm; extern const HWContextType ff_hwcontext_type_dxva2; extern const HWContextType ff_hwcontext_type_qsv; extern const HWContextType ff_hwcontext_type_vaapi; diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index d45eae5772816..33aa2d705fd5e 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -2237,6 +2237,10 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_FLOAT, }, + [AV_PIX_FMT_DRM_PRIME] = { + .name = "drm_prime", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, }; #if FF_API_PLUS1_MINUS1 FF_ENABLE_DEPRECATION_WARNINGS diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index 6dd094376f2bb..24889c8e5288c 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -334,6 +334,13 @@ enum AVPixelFormat { AV_PIX_FMT_GBRAPF32BE, ///< IEEE-754 single precision planar GBRA 4:4:4:4, 128bpp, big-endian AV_PIX_FMT_GBRAPF32LE, ///< IEEE-754 single precision planar GBRA 4:4:4:4, 128bpp, little-endian + /** + * DRM-managed buffers exposed through PRIME buffer sharing. + * + * data[0] points to an AVDRMFrameDescriptor. + */ + AV_PIX_FMT_DRM_PRIME, + AV_PIX_FMT_NB ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions }; diff --git a/libavutil/version.h b/libavutil/version.h index 6e25b4690c7c0..d99eff5d15aae 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -80,7 +80,7 @@ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 74 +#define LIBAVUTIL_VERSION_MINOR 75 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From 170c65335caad782db6e474f4a0c55911803e8d7 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sat, 2 Sep 2017 18:08:34 +0100 Subject: [PATCH 3071/3374] hwcontext_vaapi: Add DRM to VAAPI mapping --- libavutil/hwcontext_vaapi.c | 229 +++++++++++++++++++++++++++++++++++- 1 file changed, 228 insertions(+), 1 deletion(-) diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index 3970726d30060..2cc6f26715b2c 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -25,6 +25,11 @@ # include #endif +#if CONFIG_LIBDRM +# include +# include +#endif + #include #if HAVE_UNISTD_H # include @@ -41,6 +46,10 @@ #include "pixdesc.h" #include "pixfmt.h" +#if CONFIG_LIBDRM +# include "hwcontext_drm.h" +#endif + typedef struct VAAPIDevicePriv { #if HAVE_VAAPI_X11 Display *x11_display; @@ -897,6 +906,173 @@ static int vaapi_map_from(AVHWFramesContext *hwfc, AVFrame *dst, return 0; } +#if CONFIG_LIBDRM + +#define DRM_MAP(va, layers, ...) { \ + VA_FOURCC_ ## va, \ + layers, \ + { __VA_ARGS__ } \ + } +static const struct { + uint32_t va_fourcc; + int nb_layer_formats; + uint32_t layer_formats[AV_DRM_MAX_PLANES]; +} vaapi_drm_format_map[] = { + DRM_MAP(NV12, 2, DRM_FORMAT_R8, DRM_FORMAT_RG88), + DRM_MAP(NV12, 1, DRM_FORMAT_NV12), +#ifdef VA_FOURCC_P010 + DRM_MAP(P010, 2, DRM_FORMAT_R16, DRM_FORMAT_RG1616), +#endif + DRM_MAP(BGRA, 1, DRM_FORMAT_BGRA8888), + DRM_MAP(BGRX, 1, DRM_FORMAT_BGRX8888), + DRM_MAP(RGBA, 1, DRM_FORMAT_RGBA8888), + DRM_MAP(RGBX, 1, DRM_FORMAT_RGBX8888), +#ifdef VA_FOURCC_ABGR + DRM_MAP(ABGR, 1, DRM_FORMAT_ABGR8888), + DRM_MAP(XBGR, 1, DRM_FORMAT_XBGR8888), +#endif + DRM_MAP(ARGB, 1, DRM_FORMAT_ARGB8888), + DRM_MAP(XRGB, 1, DRM_FORMAT_XRGB8888), +}; +#undef DRM_MAP + +static void vaapi_unmap_from_drm(AVHWFramesContext *dst_fc, + HWMapDescriptor *hwmap) +{ + AVVAAPIDeviceContext *dst_dev = dst_fc->device_ctx->hwctx; + + VASurfaceID surface_id = (VASurfaceID)(uintptr_t)hwmap->priv; + + av_log(dst_fc, AV_LOG_DEBUG, "Destroy surface %#x.\n", surface_id); + + vaDestroySurfaces(dst_dev->display, &surface_id, 1); +} + +static int vaapi_map_from_drm(AVHWFramesContext *src_fc, AVFrame *dst, + const AVFrame *src, int flags) +{ + AVHWFramesContext *dst_fc = + (AVHWFramesContext*)dst->hw_frames_ctx->data; + AVVAAPIDeviceContext *dst_dev = dst_fc->device_ctx->hwctx; + const AVDRMFrameDescriptor *desc; + VASurfaceID surface_id; + VAStatus vas; + uint32_t va_fourcc, va_rt_format; + int err, i, j, k; + + unsigned long buffer_handle; + VASurfaceAttribExternalBuffers buffer_desc; + VASurfaceAttrib attrs[2] = { + { + .type = VASurfaceAttribMemoryType, + .flags = VA_SURFACE_ATTRIB_SETTABLE, + .value.type = VAGenericValueTypeInteger, + .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME, + }, + { + .type = VASurfaceAttribExternalBufferDescriptor, + .flags = VA_SURFACE_ATTRIB_SETTABLE, + .value.type = VAGenericValueTypePointer, + .value.value.p = &buffer_desc, + } + }; + + desc = (AVDRMFrameDescriptor*)src->data[0]; + + if (desc->nb_objects != 1) { + av_log(dst_fc, AV_LOG_ERROR, "VAAPI can only map frames " + "made from a single DRM object.\n"); + return AVERROR(EINVAL); + } + + va_fourcc = 0; + for (i = 0; i < FF_ARRAY_ELEMS(vaapi_drm_format_map); i++) { + if (desc->nb_layers != vaapi_drm_format_map[i].nb_layer_formats) + continue; + for (j = 0; j < desc->nb_layers; j++) { + if (desc->layers[j].format != + vaapi_drm_format_map[i].layer_formats[j]) + break; + } + if (j != desc->nb_layers) + continue; + va_fourcc = vaapi_drm_format_map[i].va_fourcc; + break; + } + if (!va_fourcc) { + av_log(dst_fc, AV_LOG_ERROR, "DRM format not supported " + "by VAAPI.\n"); + return AVERROR(EINVAL); + } + + av_log(dst_fc, AV_LOG_DEBUG, "Map DRM object %d to VAAPI as " + "%08x.\n", desc->objects[0].fd, va_fourcc); + + for (i = 0; i < FF_ARRAY_ELEMS(vaapi_format_map); i++) { + if (vaapi_format_map[i].fourcc == va_fourcc) + va_rt_format = vaapi_format_map[i].rt_format; + } + + buffer_handle = desc->objects[0].fd; + buffer_desc.pixel_format = va_fourcc; + buffer_desc.width = src_fc->width; + buffer_desc.height = src_fc->height; + buffer_desc.data_size = desc->objects[0].size; + buffer_desc.buffers = &buffer_handle; + buffer_desc.num_buffers = 1; + buffer_desc.flags = 0; + + k = 0; + for (i = 0; i < desc->nb_layers; i++) { + for (j = 0; j < desc->layers[i].nb_planes; j++) { + buffer_desc.pitches[k] = desc->layers[i].planes[j].pitch; + buffer_desc.offsets[k] = desc->layers[i].planes[j].offset; + ++k; + } + } + buffer_desc.num_planes = k; + + vas = vaCreateSurfaces(dst_dev->display, va_rt_format, + src->width, src->height, + &surface_id, 1, + attrs, FF_ARRAY_ELEMS(attrs)); + if (vas != VA_STATUS_SUCCESS) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to create surface from DRM " + "object: %d (%s).\n", vas, vaErrorStr(vas)); + return AVERROR(EIO); + } + av_log(dst_fc, AV_LOG_DEBUG, "Create surface %#x.\n", surface_id); + + err = ff_hwframe_map_create(dst->hw_frames_ctx, dst, src, + &vaapi_unmap_from_drm, + (void*)(uintptr_t)surface_id); + if (err < 0) + return err; + + dst->width = src->width; + dst->height = src->height; + dst->data[3] = (uint8_t*)(uintptr_t)surface_id; + + av_log(dst_fc, AV_LOG_DEBUG, "Mapped DRM object %d to " + "surface %#x.\n", desc->objects[0].fd, surface_id); + + return 0; +} +#endif + +static int vaapi_map_to(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + switch (src->format) { +#if CONFIG_LIBDRM + case AV_PIX_FMT_DRM_PRIME: + return vaapi_map_from_drm(hwfc, dst, src, flags); +#endif + default: + return AVERROR(ENOSYS); + } +} + static void vaapi_device_free(AVHWDeviceContext *ctx) { AVVAAPIDeviceContext *hwctx = ctx->hwctx; @@ -999,6 +1175,56 @@ static int vaapi_device_create(AVHWDeviceContext *ctx, const char *device, return 0; } +static int vaapi_device_derive(AVHWDeviceContext *ctx, + AVHWDeviceContext *src_ctx, int flags) +{ +#if CONFIG_LIBDRM + if (src_ctx->type == AV_HWDEVICE_TYPE_DRM) { + AVDRMDeviceContext *src_hwctx = src_ctx->hwctx; + AVVAAPIDeviceContext *hwctx = ctx->hwctx; + VADisplay *display; + VAStatus vas; + VAAPIDevicePriv *priv; + int major, minor; + + if (src_hwctx->fd < 0) { + av_log(ctx, AV_LOG_ERROR, "DRM instance requires an associated " + "device to derive a VA display from.\n"); + return AVERROR(EINVAL); + } + + priv = av_mallocz(sizeof(*priv)); + if (!priv) + return AVERROR(ENOMEM); + + // Inherits the fd from the source context, which will close it. + priv->drm_fd = -1; + + ctx->user_opaque = priv; + ctx->free = &vaapi_device_free; + + display = vaGetDisplayDRM(src_hwctx->fd); + if (!display) { + av_log(ctx, AV_LOG_ERROR, "Failed to open a VA display from " + "DRM device.\n"); + return AVERROR(EIO); + } + + hwctx->display = display; + + vas = vaInitialize(display, &major, &minor); + if (vas != VA_STATUS_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed to initialise VAAPI " + "connection: %d (%s).\n", vas, vaErrorStr(vas)); + return AVERROR(EIO); + } + + return 0; + } +#endif + return AVERROR(ENOSYS); +} + const HWContextType ff_hwcontext_type_vaapi = { .type = AV_HWDEVICE_TYPE_VAAPI, .name = "VAAPI", @@ -1010,6 +1236,7 @@ const HWContextType ff_hwcontext_type_vaapi = { .frames_priv_size = sizeof(VAAPIFramesContext), .device_create = &vaapi_device_create, + .device_derive = &vaapi_device_derive, .device_init = &vaapi_device_init, .device_uninit = &vaapi_device_uninit, .frames_get_constraints = &vaapi_frames_get_constraints, @@ -1019,7 +1246,7 @@ const HWContextType ff_hwcontext_type_vaapi = { .transfer_get_formats = &vaapi_transfer_get_formats, .transfer_data_to = &vaapi_transfer_data_to, .transfer_data_from = &vaapi_transfer_data_from, - .map_to = NULL, + .map_to = &vaapi_map_to, .map_from = &vaapi_map_from, .pix_fmts = (const enum AVPixelFormat[]) { From 82342cead15bbc47b84be4c0b50e7fd7401cdb96 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Thu, 7 Sep 2017 22:27:09 +0100 Subject: [PATCH 3072/3374] lavc: Add flag to mark packets containing trusted input --- doc/APIchanges | 3 +++ libavcodec/avcodec.h | 7 +++++++ libavcodec/version.h | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index c37de0613829b..c20ab9c98848b 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-09-13 - xxxxxxx - lavc 57.106.100 - avcodec.h + Add AV_PKT_FLAG_TRUSTED. + 2017-09-13 - xxxxxxx - lavu 55.75.100 - hwcontext.h hwcontext_drm.h Add AV_HWDEVICE_TYPE_DRM and implementation. diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 7708bb2adb9b4..fdf93f9a5476a 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1709,6 +1709,13 @@ typedef struct AVPacket { * after decoding. **/ #define AV_PKT_FLAG_DISCARD 0x0004 +/** + * The packet comes from a trusted source. + * + * Otherwise-unsafe constructs such as arbitrary pointers to data + * outside the packet may be followed. + */ +#define AV_PKT_FLAG_TRUSTED 0x0008 enum AVSideDataParamChangeFlags { AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT = 0x0001, diff --git a/libavcodec/version.h b/libavcodec/version.h index 55b8ddc13c172..2aff092cf42db 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 105 +#define LIBAVCODEC_VERSION_MINOR 106 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ From c8dea81921504c5e25a705dec4438dc95463f49b Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sat, 2 Sep 2017 20:32:27 +0100 Subject: [PATCH 3073/3374] lavc: Add wrapped_avframe decoder Intended for use with hardware frames for which rawvideo is not sufficient. Requires the trusted packet flag to be set - decoding fails if not to avoid security issues (the wrapped AVFrame can contain pointers to arbitrary data). --- libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 2 +- libavcodec/version.h | 2 +- libavcodec/wrapped_avframe.c | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 999632cf9e001..943e5db51131b 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -653,6 +653,7 @@ OBJS-$(CONFIG_WMV2_DECODER) += wmv2dec.o wmv2.o wmv2data.o \ OBJS-$(CONFIG_WMV2_ENCODER) += wmv2enc.o wmv2.o wmv2data.o \ msmpeg4.o msmpeg4enc.o msmpeg4data.o OBJS-$(CONFIG_WNV1_DECODER) += wnv1.o +OBJS-$(CONFIG_WRAPPED_AVFRAME_DECODER) += wrapped_avframe.o OBJS-$(CONFIG_WRAPPED_AVFRAME_ENCODER) += wrapped_avframe.o OBJS-$(CONFIG_WS_SND1_DECODER) += ws-snd1.o OBJS-$(CONFIG_XAN_DPCM_DECODER) += dpcm.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index ce0bc7ecf30d7..625720578f6d3 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -377,7 +377,7 @@ static void register_all(void) REGISTER_DECODER(VQA, vqa); REGISTER_DECODER(BITPACKED, bitpacked); REGISTER_DECODER(WEBP, webp); - REGISTER_ENCODER(WRAPPED_AVFRAME, wrapped_avframe); + REGISTER_ENCDEC (WRAPPED_AVFRAME, wrapped_avframe); REGISTER_ENCDEC (WMV1, wmv1); REGISTER_ENCDEC (WMV2, wmv2); REGISTER_DECODER(WMV3, wmv3); diff --git a/libavcodec/version.h b/libavcodec/version.h index 2aff092cf42db..e1224752bd74b 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 106 -#define LIBAVCODEC_VERSION_MICRO 100 +#define LIBAVCODEC_VERSION_MICRO 101 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavcodec/wrapped_avframe.c b/libavcodec/wrapped_avframe.c index 14360320ffa42..5f88a668b927d 100644 --- a/libavcodec/wrapped_avframe.c +++ b/libavcodec/wrapped_avframe.c @@ -75,6 +75,33 @@ static int wrapped_avframe_encode(AVCodecContext *avctx, AVPacket *pkt, return 0; } +static int wrapped_avframe_decode(AVCodecContext *avctx, void *data, + int *got_frame, AVPacket *pkt) +{ + AVFrame *in, *out; + int err; + + if (!(pkt->flags & AV_PKT_FLAG_TRUSTED)) { + // This decoder is not usable with untrusted input. + return AVERROR(EPERM); + } + + if (pkt->size < sizeof(AVFrame)) + return AVERROR(EINVAL); + + in = (AVFrame*)pkt->data; + out = data; + + err = ff_decode_frame_props(avctx, out); + if (err < 0) + return err; + + av_frame_move_ref(out, in); + + *got_frame = 1; + return 0; +} + AVCodec ff_wrapped_avframe_encoder = { .name = "wrapped_avframe", .long_name = NULL_IF_CONFIG_SMALL("AVFrame to AVPacket passthrough"), @@ -83,3 +110,12 @@ AVCodec ff_wrapped_avframe_encoder = { .encode2 = wrapped_avframe_encode, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; + +AVCodec ff_wrapped_avframe_decoder = { + .name = "wrapped_avframe", + .long_name = NULL_IF_CONFIG_SMALL("AVPacket to AVFrame passthrough"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_WRAPPED_AVFRAME, + .decode = wrapped_avframe_decode, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, +}; From 52194f0bcb2b62c4e093a71aa8b3951500cab3f9 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sat, 2 Sep 2017 18:14:27 +0100 Subject: [PATCH 3074/3374] lavd: Add KMS screen grabber --- Changelog | 1 + configure | 1 + libavdevice/Makefile | 1 + libavdevice/alldevices.c | 1 + libavdevice/kmsgrab.c | 455 +++++++++++++++++++++++++++++++++++++++ libavdevice/version.h | 2 +- 6 files changed, 460 insertions(+), 1 deletion(-) create mode 100644 libavdevice/kmsgrab.c diff --git a/Changelog b/Changelog index ca0758aca2abc..ea48e81efe474 100644 --- a/Changelog +++ b/Changelog @@ -47,6 +47,7 @@ version : - SUP/PGS subtitle muxer - convolve video filter - VP9 tile threading support +- KMS screen grabber version 3.3: - CrystalHD decoder moved to new decode API diff --git a/configure b/configure index 832f26ba10995..78670c41aeb14 100755 --- a/configure +++ b/configure @@ -3050,6 +3050,7 @@ gdigrab_indev_select="bmp_decoder" iec61883_indev_deps="libiec61883" jack_indev_deps="jack" jack_indev_deps_any="sem_timedwait dispatch_dispatch_h" +kmsgrab_indev_deps="libdrm" lavfi_indev_deps="avfilter" libcdio_indev_deps="libcdio" libdc1394_indev_deps="libdc1394" diff --git a/libavdevice/Makefile b/libavdevice/Makefile index 2a27d2038832d..f40f4d5298a7e 100644 --- a/libavdevice/Makefile +++ b/libavdevice/Makefile @@ -32,6 +32,7 @@ OBJS-$(CONFIG_FBDEV_OUTDEV) += fbdev_enc.o \ OBJS-$(CONFIG_GDIGRAB_INDEV) += gdigrab.o OBJS-$(CONFIG_IEC61883_INDEV) += iec61883.o OBJS-$(CONFIG_JACK_INDEV) += jack.o timefilter.o +OBJS-$(CONFIG_KMSGRAB_INDEV) += kmsgrab.o OBJS-$(CONFIG_LAVFI_INDEV) += lavfi.o OBJS-$(CONFIG_OPENAL_INDEV) += openal-dec.o OBJS-$(CONFIG_OPENGL_OUTDEV) += opengl_enc.o diff --git a/libavdevice/alldevices.c b/libavdevice/alldevices.c index 38010e288afa1..b31558bcb54b5 100644 --- a/libavdevice/alldevices.c +++ b/libavdevice/alldevices.c @@ -53,6 +53,7 @@ static void register_all(void) REGISTER_INDEV (GDIGRAB, gdigrab); REGISTER_INDEV (IEC61883, iec61883); REGISTER_INDEV (JACK, jack); + REGISTER_INDEV (KMSGRAB, kmsgrab); REGISTER_INDEV (LAVFI, lavfi); REGISTER_INDEV (OPENAL, openal); REGISTER_OUTDEV (OPENGL, opengl); diff --git a/libavdevice/kmsgrab.c b/libavdevice/kmsgrab.c new file mode 100644 index 0000000000000..d0b9cf50019fc --- /dev/null +++ b/libavdevice/kmsgrab.c @@ -0,0 +1,455 @@ +/* + * KMS/DRM input device + * + * 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 +#include + +#include +#include +#include +#include +#include + +#include "libavutil/hwcontext.h" +#include "libavutil/hwcontext_drm.h" +#include "libavutil/internal.h" +#include "libavutil/mathematics.h" +#include "libavutil/opt.h" +#include "libavutil/pixfmt.h" +#include "libavutil/pixdesc.h" +#include "libavutil/time.h" + +#include "libavformat/avformat.h" +#include "libavformat/internal.h" + +typedef struct KMSGrabContext { + const AVClass *class; + + AVBufferRef *device_ref; + AVHWDeviceContext *device; + AVDRMDeviceContext *hwctx; + + AVBufferRef *frames_ref; + AVHWFramesContext *frames; + + uint32_t plane_id; + uint32_t drm_format; + unsigned int width; + unsigned int height; + + int64_t frame_delay; + int64_t frame_last; + + const char *device_path; + enum AVPixelFormat format; + int64_t drm_format_modifier; + int64_t source_plane; + int64_t source_crtc; + AVRational framerate; +} KMSGrabContext; + +static void kmsgrab_free_desc(void *opaque, uint8_t *data) +{ + AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor*)data; + + close(desc->objects[0].fd); + + av_free(desc); +} + +static void kmsgrab_free_frame(void *opaque, uint8_t *data) +{ + AVFrame *frame = (AVFrame*)data; + + av_frame_free(&frame); +} + +static int kmsgrab_read_packet(AVFormatContext *avctx, AVPacket *pkt) +{ + KMSGrabContext *ctx = avctx->priv_data; + drmModePlane *plane; + drmModeFB *fb; + AVDRMFrameDescriptor *desc; + AVFrame *frame; + int64_t now; + int err, fd; + + now = av_gettime(); + if (ctx->frame_last) { + int64_t delay; + while (1) { + delay = ctx->frame_last + ctx->frame_delay - now; + if (delay <= 0) + break; + av_usleep(delay); + now = av_gettime(); + } + } + ctx->frame_last = now; + + plane = drmModeGetPlane(ctx->hwctx->fd, ctx->plane_id); + if (!plane) { + av_log(avctx, AV_LOG_ERROR, "Failed to get plane " + "%"PRIu32".\n", ctx->plane_id); + return AVERROR(EIO); + } + if (!plane->fb_id) { + av_log(avctx, AV_LOG_ERROR, "Plane %"PRIu32" no longer has " + "an associated framebuffer.\n", ctx->plane_id); + return AVERROR(EIO); + } + + fb = drmModeGetFB(ctx->hwctx->fd, plane->fb_id); + if (!fb) { + av_log(avctx, AV_LOG_ERROR, "Failed to get framebuffer " + "%"PRIu32".\n", plane->fb_id); + return AVERROR(EIO); + } + if (fb->width != ctx->width || fb->height != ctx->height) { + av_log(avctx, AV_LOG_ERROR, "Plane %"PRIu32" framebuffer " + "dimensions changed: now %"PRIu32"x%"PRIu32".\n", + ctx->plane_id, fb->width, fb->height); + return AVERROR(EIO); + } + if (!fb->handle) { + av_log(avctx, AV_LOG_ERROR, "No handle set on framebuffer.\n"); + return AVERROR(EIO); + } + + err = drmPrimeHandleToFD(ctx->hwctx->fd, fb->handle, O_RDONLY, &fd); + if (err < 0) { + err = errno; + av_log(avctx, AV_LOG_ERROR, "Failed to get PRIME fd from " + "framebuffer handle: %s.\n", strerror(errno)); + return AVERROR(err); + } + + desc = av_mallocz(sizeof(*desc)); + if (!desc) + return AVERROR(ENOMEM); + + *desc = (AVDRMFrameDescriptor) { + .nb_objects = 1, + .objects[0] = { + .fd = fd, + .size = fb->height * fb->pitch, + .format_modifier = ctx->drm_format_modifier, + }, + .nb_layers = 1, + .layers[0] = { + .format = ctx->drm_format, + .nb_planes = 1, + .planes[0] = { + .object_index = 0, + .offset = 0, + .pitch = fb->pitch, + }, + }, + }; + + frame = av_frame_alloc(); + if (!frame) + return AVERROR(ENOMEM); + + frame->hw_frames_ctx = av_buffer_ref(ctx->frames_ref); + if (!frame->hw_frames_ctx) + return AVERROR(ENOMEM); + + frame->buf[0] = av_buffer_create((uint8_t*)desc, sizeof(*desc), + &kmsgrab_free_desc, avctx, 0); + if (!frame->buf[0]) + return AVERROR(ENOMEM); + + frame->data[0] = (uint8_t*)desc; + frame->format = AV_PIX_FMT_DRM_PRIME; + frame->width = fb->width; + frame->height = fb->height; + + drmModeFreeFB(fb); + drmModeFreePlane(plane); + + pkt->buf = av_buffer_create((uint8_t*)frame, sizeof(*frame), + &kmsgrab_free_frame, avctx, 0); + if (!pkt->buf) + return AVERROR(ENOMEM); + + pkt->data = (uint8_t*)frame; + pkt->size = sizeof(*frame); + pkt->pts = now; + pkt->flags = AV_PKT_FLAG_TRUSTED; + + return 0; +} + +static const struct { + enum AVPixelFormat pixfmt; + uint32_t drm_format; +} kmsgrab_formats[] = { + { AV_PIX_FMT_GRAY8, DRM_FORMAT_R8 }, + { AV_PIX_FMT_GRAY16LE, DRM_FORMAT_R16 }, + { AV_PIX_FMT_RGB24, DRM_FORMAT_RGB888 }, + { AV_PIX_FMT_BGR24, DRM_FORMAT_BGR888 }, + { AV_PIX_FMT_0RGB, DRM_FORMAT_XRGB8888 }, + { AV_PIX_FMT_0BGR, DRM_FORMAT_XBGR8888 }, + { AV_PIX_FMT_RGB0, DRM_FORMAT_RGBX8888 }, + { AV_PIX_FMT_BGR0, DRM_FORMAT_BGRX8888 }, + { AV_PIX_FMT_ARGB, DRM_FORMAT_ARGB8888 }, + { AV_PIX_FMT_ABGR, DRM_FORMAT_ABGR8888 }, + { AV_PIX_FMT_RGBA, DRM_FORMAT_RGBA8888 }, + { AV_PIX_FMT_BGRA, DRM_FORMAT_BGRA8888 }, + { AV_PIX_FMT_YUYV422, DRM_FORMAT_YUYV }, + { AV_PIX_FMT_YVYU422, DRM_FORMAT_YVYU }, + { AV_PIX_FMT_UYVY422, DRM_FORMAT_UYVY }, + { AV_PIX_FMT_NV12, DRM_FORMAT_NV12 }, + { AV_PIX_FMT_YUV420P, DRM_FORMAT_YUV420 }, + { AV_PIX_FMT_YUV422P, DRM_FORMAT_YUV422 }, + { AV_PIX_FMT_YUV444P, DRM_FORMAT_YUV444 }, +}; + +static av_cold int kmsgrab_read_header(AVFormatContext *avctx) +{ + KMSGrabContext *ctx = avctx->priv_data; + drmModePlaneRes *plane_res = NULL; + drmModePlane *plane = NULL; + drmModeFB *fb = NULL; + AVStream *stream; + int err, i; + + for (i = 0; i < FF_ARRAY_ELEMS(kmsgrab_formats); i++) { + if (kmsgrab_formats[i].pixfmt == ctx->format) { + ctx->drm_format = kmsgrab_formats[i].drm_format; + break; + } + } + if (i >= FF_ARRAY_ELEMS(kmsgrab_formats)) { + av_log(avctx, AV_LOG_ERROR, "Unsupported format %s.\n", + av_get_pix_fmt_name(ctx->format)); + return AVERROR(EINVAL); + } + + err = av_hwdevice_ctx_create(&ctx->device_ref, AV_HWDEVICE_TYPE_DRM, + ctx->device_path, NULL, 0); + if (err < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to open DRM device.\n"); + return err; + } + ctx->device = (AVHWDeviceContext*) ctx->device_ref->data; + ctx->hwctx = (AVDRMDeviceContext*)ctx->device->hwctx; + + err = drmSetClientCap(ctx->hwctx->fd, + DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); + if (err < 0) { + av_log(avctx, AV_LOG_WARNING, "Failed to set universal planes " + "capability: primary planes will not be usable.\n"); + } + + if (ctx->source_plane > 0) { + plane = drmModeGetPlane(ctx->hwctx->fd, ctx->source_plane); + if (!plane) { + err = errno; + av_log(avctx, AV_LOG_ERROR, "Failed to get plane %"PRId64": " + "%s.\n", ctx->source_plane, strerror(err)); + err = AVERROR(err); + goto fail; + } + + if (plane->fb_id == 0) { + av_log(avctx, AV_LOG_ERROR, "Plane %"PRId64" does not have " + "an attached framebuffer.\n", ctx->source_plane); + err = AVERROR(EINVAL); + goto fail; + } + } else { + plane_res = drmModeGetPlaneResources(ctx->hwctx->fd); + if (!plane_res) { + av_log(avctx, AV_LOG_ERROR, "Failed to get plane " + "resources: %s.\n", strerror(errno)); + err = AVERROR(EINVAL); + goto fail; + } + + for (i = 0; i < plane_res->count_planes; i++) { + plane = drmModeGetPlane(ctx->hwctx->fd, + plane_res->planes[i]); + if (!plane) { + err = errno; + av_log(avctx, AV_LOG_VERBOSE, "Failed to get " + "plane %"PRIu32": %s.\n", + plane_res->planes[i], strerror(err)); + continue; + } + + av_log(avctx, AV_LOG_DEBUG, "Plane %"PRIu32": " + "CRTC %"PRIu32" FB %"PRIu32".\n", + plane->plane_id, plane->crtc_id, plane->fb_id); + + if ((ctx->source_crtc > 0 && + plane->crtc_id != ctx->source_crtc) || + plane->fb_id == 0) { + // Either not connected to the target source CRTC + // or not active. + drmModeFreePlane(plane); + plane = NULL; + continue; + } + + break; + } + + if (i == plane_res->count_planes) { + if (ctx->source_crtc > 0) { + av_log(avctx, AV_LOG_ERROR, "No usable planes found on " + "CRTC %"PRId64".\n", ctx->source_crtc); + } else { + av_log(avctx, AV_LOG_ERROR, "No usable planes found.\n"); + } + err = AVERROR(EINVAL); + goto fail; + } + + av_log(avctx, AV_LOG_INFO, "Using plane %"PRIu32" to " + "locate framebuffers.\n", plane->plane_id); + } + + ctx->plane_id = plane->plane_id; + + fb = drmModeGetFB(ctx->hwctx->fd, plane->fb_id); + if (!fb) { + err = errno; + av_log(avctx, AV_LOG_ERROR, "Failed to get " + "framebuffer %"PRIu32": %s.\n", + plane->fb_id, strerror(err)); + err = AVERROR(err); + goto fail; + } + + av_log(avctx, AV_LOG_INFO, "Template framebuffer is %"PRIu32": " + "%"PRIu32"x%"PRIu32" %"PRIu32"bpp %"PRIu32"b depth.\n", + fb->fb_id, fb->width, fb->height, fb->bpp, fb->depth); + + ctx->width = fb->width; + ctx->height = fb->height; + + if (!fb->handle) { + av_log(avctx, AV_LOG_ERROR, "No handle set on framebuffer: " + "maybe you need some additional capabilities?\n"); + err = AVERROR(EINVAL); + goto fail; + } + + stream = avformat_new_stream(avctx, NULL); + if (!stream) { + err = AVERROR(ENOMEM); + goto fail; + } + + stream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; + stream->codecpar->codec_id = AV_CODEC_ID_WRAPPED_AVFRAME; + stream->codecpar->width = fb->width; + stream->codecpar->height = fb->height; + stream->codecpar->format = AV_PIX_FMT_DRM_PRIME; + + avpriv_set_pts_info(stream, 64, 1, 1000000); + + ctx->frames_ref = av_hwframe_ctx_alloc(ctx->device_ref); + if (!ctx->frames_ref) { + err = AVERROR(ENOMEM); + goto fail; + } + ctx->frames = (AVHWFramesContext*)ctx->frames_ref->data; + + ctx->frames->format = AV_PIX_FMT_DRM_PRIME; + ctx->frames->sw_format = ctx->format, + ctx->frames->width = fb->width; + ctx->frames->height = fb->height; + + err = av_hwframe_ctx_init(ctx->frames_ref); + if (err < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to initialise " + "hardware frames context: %d.\n", err); + goto fail; + } + + ctx->frame_delay = av_rescale_q(1, (AVRational) { ctx->framerate.den, + ctx->framerate.num }, AV_TIME_BASE_Q); + + err = 0; +fail: + if (plane_res) + drmModeFreePlaneResources(plane_res); + if (plane) + drmModeFreePlane(plane); + if (fb) + drmModeFreeFB(fb); + + return err; +} + +static av_cold int kmsgrab_read_close(AVFormatContext *avctx) +{ + KMSGrabContext *ctx = avctx->priv_data; + + av_buffer_unref(&ctx->frames_ref); + av_buffer_unref(&ctx->device_ref); + + return 0; +} + +#define OFFSET(x) offsetof(KMSGrabContext, x) +#define FLAGS AV_OPT_FLAG_DECODING_PARAM +static const AVOption options[] = { + { "device", "DRM device path", + OFFSET(device_path), AV_OPT_TYPE_STRING, + { .str = "/dev/dri/card0" }, 0, 0, FLAGS }, + { "format", "Pixel format for framebuffer", + OFFSET(format), AV_OPT_TYPE_PIXEL_FMT, + { .i64 = AV_PIX_FMT_BGR0 }, 0, UINT32_MAX, FLAGS }, + { "format_modifier", "DRM format modifier for framebuffer", + OFFSET(drm_format_modifier), AV_OPT_TYPE_INT64, + { .i64 = DRM_FORMAT_MOD_NONE }, 0, INT64_MAX, FLAGS }, + { "crtc_id", "CRTC ID to define capture source", + OFFSET(source_crtc), AV_OPT_TYPE_INT64, + { .i64 = 0 }, 0, UINT32_MAX, FLAGS }, + { "plane_id", "Plane ID to define capture source", + OFFSET(source_plane), AV_OPT_TYPE_INT64, + { .i64 = 0 }, 0, UINT32_MAX, FLAGS }, + { "framerate", "Framerate to capture at", + OFFSET(framerate), AV_OPT_TYPE_RATIONAL, + { .dbl = 30.0 }, 0, 1000, FLAGS }, + { NULL }, +}; + +static const AVClass kmsgrab_class = { + .class_name = "kmsgrab indev", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVInputFormat ff_kmsgrab_demuxer = { + .name = "kmsgrab", + .long_name = NULL_IF_CONFIG_SMALL("KMS screen capture"), + .priv_data_size = sizeof(KMSGrabContext), + .read_header = &kmsgrab_read_header, + .read_packet = &kmsgrab_read_packet, + .read_close = &kmsgrab_read_close, + .flags = AVFMT_NOFILE, + .priv_class = &kmsgrab_class, +}; diff --git a/libavdevice/version.h b/libavdevice/version.h index 948e4e1e08fd6..358b6ff969bee 100644 --- a/libavdevice/version.h +++ b/libavdevice/version.h @@ -29,7 +29,7 @@ #define LIBAVDEVICE_VERSION_MAJOR 57 #define LIBAVDEVICE_VERSION_MINOR 8 -#define LIBAVDEVICE_VERSION_MICRO 100 +#define LIBAVDEVICE_VERSION_MICRO 101 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ LIBAVDEVICE_VERSION_MINOR, \ From ec1573f879b1974050c68fdcb69b654e500efdfa Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Tue, 12 Sep 2017 00:19:03 +0100 Subject: [PATCH 3075/3374] doc/indevs: Document kmsgrab input device --- doc/indevs.texi | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/doc/indevs.texi b/doc/indevs.texi index ad6418751bc9d..30b7ac23805c6 100644 --- a/doc/indevs.texi +++ b/doc/indevs.texi @@ -331,6 +331,68 @@ ffmpeg -channels 16 -format_code Hi50 -f decklink -i 'UltraStudio Mini Recorder' @end itemize +@section kmsgrab + +KMS video input device. + +Captures the KMS scanout framebuffer associated with a specified CRTC or plane as a +DRM object that can be passed to other hardware functions. + +Requires either DRM master or CAP_SYS_ADMIN to run. + +If you don't understand what all of that means, you probably don't want this. Look at +@option{x11grab} instead. + +@subsection Options + +@table @option + +@item device +DRM device to capture on. Defaults to @option{/dev/dri/card0}. + +@item format +Pixel format of the framebuffer. Defaults to @option{bgr0}. + +@item format_modifier +Format modifier to signal on output frames. This is necessary to import correctly into +some APIs, but can't be autodetected. See the libdrm documentation for possible values. + +@item crtc_id +KMS CRTC ID to define the capture source. The first active plane on the given CRTC +will be used. + +@item plane_id +KMS plane ID to define the capture source. Defaults to the first active plane found if +neither @option{crtc_id} nor @option{plane_id} are specified. + +@item framerate +Framerate to capture at. This is not synchronised to any page flipping or framebuffer +changes - it just defines the interval at which the framebuffer is sampled. Sampling +faster than the framebuffer update rate will generate independent frames with the same +content. Defaults to @code{30}. + +@end table + +@subsection Examples + +@itemize + +@item +Capture from the first active plane, download the result to normal frames and encode. +This will only work if the framebuffer is both linear and mappable - if not, the result +may be scrambled or fail to download. +@example +ffmpeg -f kmsgrab -i - -vf 'hwdownload,format=bgr0' output.mp4 +@end example + +@item +Capture from CRTC ID 42 at 60fps, map the result to VAAPI, convert to NV12 and encode as H.264. +@example +ffmpeg -crtc_id 42 -framerate 60 -f kmsgrab -i - -vf 'hwmap=derive_device=vaapi,scale_vaapi=w=1920:h=1080:format=nv12' -c:v h264_vaapi output.mp4 +@end example + +@end itemize + @section libndi_newtek The libndi_newtek input device provides capture capabilities for using NDI (Network From 6561cdd70c55cb45fb8ef75269be77936456a02e Mon Sep 17 00:00:00 2001 From: James Almer Date: Thu, 14 Sep 2017 01:43:52 -0300 Subject: [PATCH 3076/3374] avcodec.h: fix doxygen comment --- libavcodec/avcodec.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index fdf93f9a5476a..5c84974e03b2f 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3564,7 +3564,7 @@ typedef struct AVCodecContext { */ char *codec_whitelist; - /* + /** * Properties of the stream that gets decoded * - encoding: unused * - decoding: set by libavcodec From 16b44d9ab9fd81e4dfc5631a5fbc081b564f1037 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Thu, 14 Sep 2017 09:14:36 +0100 Subject: [PATCH 3077/3374] lavd/kmsgrab: Fix packet flag setting Found-by: James Almer --- libavdevice/kmsgrab.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavdevice/kmsgrab.c b/libavdevice/kmsgrab.c index d0b9cf50019fc..d222abfd609bf 100644 --- a/libavdevice/kmsgrab.c +++ b/libavdevice/kmsgrab.c @@ -190,10 +190,10 @@ static int kmsgrab_read_packet(AVFormatContext *avctx, AVPacket *pkt) if (!pkt->buf) return AVERROR(ENOMEM); - pkt->data = (uint8_t*)frame; - pkt->size = sizeof(*frame); - pkt->pts = now; - pkt->flags = AV_PKT_FLAG_TRUSTED; + pkt->data = (uint8_t*)frame; + pkt->size = sizeof(*frame); + pkt->pts = now; + pkt->flags |= AV_PKT_FLAG_TRUSTED; return 0; } From 133002e8ae51078709d626ffa2eff9ec8779bd80 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Thu, 14 Sep 2017 18:05:57 +0200 Subject: [PATCH 3078/3374] avfilter/vf_despill: fix assigment Reported-by: Moritz Barsnick Signed-off-by: Paul B Mahol --- libavfilter/vf_despill.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_despill.c b/libavfilter/vf_despill.c index eff9877a1c21d..64c27f4060926 100644 --- a/libavfilter/vf_despill.c +++ b/libavfilter/vf_despill.c @@ -161,7 +161,7 @@ static const AVOption despill_options[] = { { "blue", "bluescreen", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "type" }, { "mix", "set the spillmap mix", OFFSET(spillmix), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS }, { "expand", "set the spillmap expand", OFFSET(spillexpand), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, FLAGS }, - { "red", "set red scale", OFFSET(bluescale), AV_OPT_TYPE_FLOAT, {.dbl=0}, -100, 100, FLAGS }, + { "red", "set red scale", OFFSET(redscale), AV_OPT_TYPE_FLOAT, {.dbl=0}, -100, 100, FLAGS }, { "green", "set green scale", OFFSET(greenscale), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -100, 100, FLAGS }, { "blue", "set blue scale", OFFSET(bluescale), AV_OPT_TYPE_FLOAT, {.dbl=0}, -100, 100, FLAGS }, { "brightness", "set brightness", OFFSET(brightness), AV_OPT_TYPE_FLOAT, {.dbl=0}, -10, 10, FLAGS }, From 462568185b0af4d651441ae397cc83bdb7e573ed Mon Sep 17 00:00:00 2001 From: Jun Zhao Date: Wed, 13 Sep 2017 20:21:38 -0400 Subject: [PATCH 3079/3374] kmsgrab: Fix build failure with old libdrm DRM_FORMAT_R8 was added in libdrm 2.4.68. DRM_FORMAT_R16 was added in libdrm 2.4.82. Signed-off-by: Jun Zhao Signed-off-by: Mark Thompson --- libavdevice/kmsgrab.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavdevice/kmsgrab.c b/libavdevice/kmsgrab.c index d222abfd609bf..67a83ef84aa91 100644 --- a/libavdevice/kmsgrab.c +++ b/libavdevice/kmsgrab.c @@ -202,8 +202,12 @@ static const struct { enum AVPixelFormat pixfmt; uint32_t drm_format; } kmsgrab_formats[] = { +#ifdef DRM_FORMAT_R8 { AV_PIX_FMT_GRAY8, DRM_FORMAT_R8 }, +#endif +#ifdef DRM_FORMAT_R16 { AV_PIX_FMT_GRAY16LE, DRM_FORMAT_R16 }, +#endif { AV_PIX_FMT_RGB24, DRM_FORMAT_RGB888 }, { AV_PIX_FMT_BGR24, DRM_FORMAT_BGR888 }, { AV_PIX_FMT_0RGB, DRM_FORMAT_XRGB8888 }, From 197d298ab3b27d1ec2ee7bf568debca105881a54 Mon Sep 17 00:00:00 2001 From: Jun Zhao Date: Wed, 13 Sep 2017 20:21:38 -0400 Subject: [PATCH 3080/3374] hwcontext_vaapi: Fix build failure with old libdrm Signed-off-by: Jun Zhao Signed-off-by: Mark Thompson --- libavutil/hwcontext_vaapi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index 2cc6f26715b2c..852f0abda2bb0 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -918,9 +918,11 @@ static const struct { int nb_layer_formats; uint32_t layer_formats[AV_DRM_MAX_PLANES]; } vaapi_drm_format_map[] = { +#ifdef DRM_FORMAT_R8 DRM_MAP(NV12, 2, DRM_FORMAT_R8, DRM_FORMAT_RG88), +#endif DRM_MAP(NV12, 1, DRM_FORMAT_NV12), -#ifdef VA_FOURCC_P010 +#if defined(VA_FOURCC_P010) && defined(DRM_FORMAT_R16) DRM_MAP(P010, 2, DRM_FORMAT_R16, DRM_FORMAT_RG1616), #endif DRM_MAP(BGRA, 1, DRM_FORMAT_BGRA8888), From f692e55aab79729ca6d6b00c2671cac116903958 Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Tue, 12 Sep 2017 16:45:12 +0530 Subject: [PATCH 3081/3374] avcodec/mips: Improve hevc lpf msa functions Seperate the filter processing in all strong, all weak and strong + weak cases. Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/hevc_lpf_sao_msa.c | 750 +++++++++++++++++++++-------- 1 file changed, 556 insertions(+), 194 deletions(-) diff --git a/libavcodec/mips/hevc_lpf_sao_msa.c b/libavcodec/mips/hevc_lpf_sao_msa.c index da1db51ef5ffc..79b156fe5c60e 100644 --- a/libavcodec/mips/hevc_lpf_sao_msa.c +++ b/libavcodec/mips/hevc_lpf_sao_msa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com) + * Copyright (c) 2015 -2017 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com) * * This file is part of FFmpeg. * @@ -35,12 +35,14 @@ static void hevc_loopfilter_luma_hor_msa(uint8_t *src, int32_t stride, uint8_t *q3 = src + (stride << 1) + stride; uint8_t flag0, flag1; int32_t dp00, dq00, dp30, dq30, d00, d30; + int32_t d0030, d0434; int32_t dp04, dq04, dp34, dq34, d04, d34; int32_t tc0, p_is_pcm0, q_is_pcm0, beta30, beta20, tc250; int32_t tc4, p_is_pcm4, q_is_pcm4, tc254, tmp; uint64_t dst_val0, dst_val1; v16u8 dst0, dst1, dst2, dst3, dst4, dst5; v2i64 cmp0, cmp1, cmp2, p_is_pcm_vec, q_is_pcm_vec; + v2i64 cmp3; v8u16 temp0, temp1; v8i16 temp2; v8i16 tc_pos, tc_neg; @@ -54,62 +56,86 @@ static void hevc_loopfilter_luma_hor_msa(uint8_t *src, int32_t stride, dq30 = abs(q2[3] - (q1[3] << 1) + q0[3]); d00 = dp00 + dq00; d30 = dp30 + dq30; - p_is_pcm0 = p_is_pcm[0]; - q_is_pcm0 = q_is_pcm[0]; dp04 = abs(p2[4] - (p1[4] << 1) + p0[4]); dq04 = abs(q2[4] - (q1[4] << 1) + q0[4]); dp34 = abs(p2[7] - (p1[7] << 1) + p0[7]); dq34 = abs(q2[7] - (q1[7] << 1) + q0[7]); d04 = dp04 + dq04; d34 = dp34 + dq34; + + p_is_pcm0 = p_is_pcm[0]; p_is_pcm4 = p_is_pcm[1]; + q_is_pcm0 = q_is_pcm[0]; q_is_pcm4 = q_is_pcm[1]; - if (!p_is_pcm0 || !p_is_pcm4 || !q_is_pcm0 || !q_is_pcm4) { - if (!(d00 + d30 >= beta) || !(d04 + d34 >= beta)) { - p3_src = LD_UH(p3); - p2_src = LD_UH(p2); - p1_src = LD_UH(p1); - p0_src = LD_UH(p0); - q0_src = LD_UH(q0); - q1_src = LD_UH(q1); - q2_src = LD_UH(q2); - q3_src = LD_UH(q3); - - tc0 = tc[0]; - beta30 = beta >> 3; - beta20 = beta >> 2; - tc250 = ((tc0 * 5 + 1) >> 1); - tc4 = tc[1]; - tc254 = ((tc4 * 5 + 1) >> 1); - - flag0 = (abs(p3[0] - p0[0]) + abs(q3[0] - q0[0]) < beta30 && - abs(p0[0] - q0[0]) < tc250 && - abs(p3[3] - p0[3]) + abs(q3[3] - q0[3]) < beta30 && - abs(p0[3] - q0[3]) < tc250 && - (d00 << 1) < beta20 && (d30 << 1) < beta20); - cmp0 = __msa_fill_d(flag0); - - flag1 = (abs(p3[4] - p0[4]) + abs(q3[4] - q0[4]) < beta30 && - abs(p0[4] - q0[4]) < tc254 && - abs(p3[7] - p0[7]) + abs(q3[7] - q0[7]) < beta30 && - abs(p0[7] - q0[7]) < tc254 && - (d04 << 1) < beta20 && (d34 << 1) < beta20); - cmp1 = __msa_fill_d(flag1); - cmp2 = __msa_ilvev_d(cmp1, cmp0); - cmp2 = __msa_ceqi_d(cmp2, 0); - - ILVR_B8_UH(zero, p3_src, zero, p2_src, zero, p1_src, zero, p0_src, - zero, q0_src, zero, q1_src, zero, q2_src, zero, q3_src, - p3_src, p2_src, p1_src, p0_src, q0_src, q1_src, q2_src, - q3_src); - - cmp0 = (v2i64) __msa_fill_h(tc0); - cmp1 = (v2i64) __msa_fill_h(tc4); - tc_pos = (v8i16) __msa_ilvev_d(cmp1, cmp0); + cmp0 = __msa_fill_d(p_is_pcm0); + cmp1 = __msa_fill_d(p_is_pcm4); + p_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); + p_is_pcm_vec = __msa_ceqi_d(p_is_pcm_vec, 0); + + d0030 = (d00 + d30) >= beta; + d0434 = (d04 + d34) >= beta; + + cmp0 = (v2i64) __msa_fill_w(d0030); + cmp1 = (v2i64) __msa_fill_w(d0434); + cmp3 = (v2i64) __msa_ilvev_w((v4i32) cmp1, (v4i32) cmp0); + cmp3 = (v2i64) __msa_ceqi_w((v4i32) cmp3, 0); + + if ((!p_is_pcm0 || !p_is_pcm4 || !q_is_pcm0 || !q_is_pcm4) && + (!d0030 || !d0434)) { + p3_src = LD_UH(p3); + p2_src = LD_UH(p2); + p1_src = LD_UH(p1); + p0_src = LD_UH(p0); + + cmp0 = __msa_fill_d(q_is_pcm0); + cmp1 = __msa_fill_d(q_is_pcm4); + q_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); + q_is_pcm_vec = __msa_ceqi_d(q_is_pcm_vec, 0); + + tc0 = tc[0]; + beta30 = beta >> 3; + beta20 = beta >> 2; + tc250 = ((tc0 * 5 + 1) >> 1); + tc4 = tc[1]; + tc254 = ((tc4 * 5 + 1) >> 1); + + cmp0 = (v2i64) __msa_fill_h(tc0); + cmp1 = (v2i64) __msa_fill_h(tc4); + + ILVR_B4_UH(zero, p3_src, zero, p2_src, zero, p1_src, zero, p0_src, + p3_src, p2_src, p1_src, p0_src); + q0_src = LD_UH(q0); + q1_src = LD_UH(q1); + q2_src = LD_UH(q2); + q3_src = LD_UH(q3); + + flag0 = abs(p3[0] - p0[0]) + abs(q3[0] - q0[0]) < beta30 && + abs(p0[0] - q0[0]) < tc250; + flag0 = flag0 && (abs(p3[3] - p0[3]) + abs(q3[3] - q0[3]) < beta30 && + abs(p0[3] - q0[3]) < tc250 && (d00 << 1) < beta20 && + (d30 << 1) < beta20); + + tc_pos = (v8i16) __msa_ilvev_d(cmp1, cmp0); + ILVR_B4_UH(zero, q0_src, zero, q1_src, zero, q2_src, zero, q3_src, + q0_src, q1_src, q2_src, q3_src); + flag1 = abs(p3[4] - p0[4]) + abs(q3[4] - q0[4]) < beta30 && + abs(p0[4] - q0[4]) < tc254; + flag1 = flag1 && (abs(p3[7] - p0[7]) + abs(q3[7] - q0[7]) < beta30 && + abs(p0[7] - q0[7]) < tc254 && (d04 << 1) < beta20 && + (d34 << 1) < beta20); + + cmp0 = (v2i64) __msa_fill_w(flag0); + cmp1 = (v2i64) __msa_fill_w(flag1); + cmp2 = (v2i64) __msa_ilvev_w((v4i32) cmp1, (v4i32) cmp0); + cmp2 = (v2i64) __msa_ceqi_w((v4i32) cmp2, 0); + + if (flag0 && flag1) { /* strong only */ + /* strong filter */ tc_pos <<= 1; tc_neg = -tc_pos; + /* p part */ temp0 = (p1_src + p0_src + q0_src); temp1 = ((p3_src + p2_src) << 1) + p2_src + temp0; temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); @@ -129,15 +155,11 @@ static void hevc_loopfilter_luma_hor_msa(uint8_t *src, int32_t stride, temp2 = CLIP_SH(temp2, tc_neg, tc_pos); dst2 = (v16u8) (temp2 + (v8i16) p0_src); - cmp0 = __msa_fill_d(p_is_pcm0); - cmp1 = __msa_fill_d(p_is_pcm4); - p_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); - p_is_pcm_vec = __msa_ceqi_d(p_is_pcm_vec, 0); - dst0 = __msa_bmz_v(dst0, (v16u8) p2_src, (v16u8) p_is_pcm_vec); dst1 = __msa_bmz_v(dst1, (v16u8) p1_src, (v16u8) p_is_pcm_vec); dst2 = __msa_bmz_v(dst2, (v16u8) p0_src, (v16u8) p_is_pcm_vec); + /* q part */ temp0 = (q1_src + p0_src + q0_src); temp1 = ((q3_src + q2_src) << 1) + q2_src + temp0; @@ -158,15 +180,176 @@ static void hevc_loopfilter_luma_hor_msa(uint8_t *src, int32_t stride, temp2 = CLIP_SH(temp2, tc_neg, tc_pos); dst3 = (v16u8) (temp2 + (v8i16) q0_src); - cmp0 = __msa_fill_d(q_is_pcm0); - cmp1 = __msa_fill_d(q_is_pcm4); - q_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); - q_is_pcm_vec = __msa_ceqi_d(q_is_pcm_vec, 0); + dst3 = __msa_bmz_v(dst3, (v16u8) q0_src, (v16u8) q_is_pcm_vec); + dst4 = __msa_bmz_v(dst4, (v16u8) q1_src, (v16u8) q_is_pcm_vec); + dst5 = __msa_bmz_v(dst5, (v16u8) q2_src, (v16u8) q_is_pcm_vec); + + /* pack results to 8 bit */ + PCKEV_B2_UB(dst1, dst0, dst3, dst2, dst0, dst1); + dst2 = (v16u8) __msa_pckev_b((v16i8) dst5, (v16i8) dst4); + + /* pack src to 8 bit */ + PCKEV_B2_UB(p1_src, p2_src, q0_src, p0_src, dst3, dst4); + dst5 = (v16u8) __msa_pckev_b((v16i8) q2_src, (v16i8) q1_src); + + dst0 = __msa_bmz_v(dst0, dst3, (v16u8) cmp3); + dst1 = __msa_bmz_v(dst1, dst4, (v16u8) cmp3); + dst2 = __msa_bmz_v(dst2, dst5, (v16u8) cmp3); + + dst_val0 = __msa_copy_u_d((v2i64) dst2, 0); + dst_val1 = __msa_copy_u_d((v2i64) dst2, 1); + + ST8x4_UB(dst0, dst1, p2, stride); + p2 += (4 * stride); + SD(dst_val0, p2); + p2 += stride; + SD(dst_val1, p2); + /* strong filter ends */ + } else if (flag0 == flag1) { /* weak only */ + /* weak filter */ + tc_neg = -tc_pos; + + diff0 = (v8i16) (q0_src - p0_src); + diff1 = (v8i16) (q1_src - p1_src); + diff0 = (diff0 << 3) + diff0; + diff1 = (diff1 << 1) + diff1; + delta0 = diff0 - diff1; + delta0 = __msa_srari_h(delta0, 4); + + temp1 = (v8u16) ((tc_pos << 3) + (tc_pos << 1)); + abs_delta0 = __msa_add_a_h(delta0, (v8i16) zero); + abs_delta0 = (v8u16) abs_delta0 < temp1; + + delta0 = CLIP_SH(delta0, tc_neg, tc_pos); + + temp0 = (v8u16) (delta0 + p0_src); + temp0 = (v8u16) CLIP_SH_0_255(temp0); + temp0 = (v8u16) __msa_bmz_v((v16u8) temp0, (v16u8) p0_src, + (v16u8) p_is_pcm_vec); + + temp2 = (v8i16) (q0_src - delta0); + temp2 = CLIP_SH_0_255(temp2); + temp2 = (v8i16) __msa_bmz_v((v16u8) temp2, (v16u8) q0_src, + (v16u8) q_is_pcm_vec); + + p_is_pcm_vec = ~p_is_pcm_vec; + q_is_pcm_vec = ~q_is_pcm_vec; + tmp = (beta + (beta >> 1)) >> 3; + cmp0 = __msa_fill_d(dp00 + dp30 < tmp); + cmp1 = __msa_fill_d(dp04 + dp34 < tmp); + cmp0 = __msa_ilvev_d(cmp1, cmp0); + cmp0 = __msa_ceqi_d(cmp0, 0); + p_is_pcm_vec = p_is_pcm_vec | cmp0; + + cmp0 = __msa_fill_d(dq00 + dq30 < tmp); + cmp1 = __msa_fill_d(dq04 + dq34 < tmp); + cmp0 = __msa_ilvev_d(cmp1, cmp0); + cmp0 = __msa_ceqi_d(cmp0, 0); + q_is_pcm_vec = q_is_pcm_vec | cmp0; + + tc_pos >>= 1; + tc_neg = -tc_pos; + + delta1 = (v8i16) __msa_aver_u_h(p2_src, p0_src); + delta1 -= (v8i16) p1_src; + delta1 += delta0; + delta1 >>= 1; + delta1 = CLIP_SH(delta1, tc_neg, tc_pos); + delta1 = (v8i16) p1_src + (v8i16) delta1; + delta1 = CLIP_SH_0_255(delta1); + delta1 = (v8i16) __msa_bmnz_v((v16u8) delta1, (v16u8) p1_src, + (v16u8) p_is_pcm_vec); + + delta2 = (v8i16) __msa_aver_u_h(q0_src, q2_src); + delta2 = delta2 - (v8i16) q1_src; + delta2 = delta2 - delta0; + delta2 = delta2 >> 1; + delta2 = CLIP_SH(delta2, tc_neg, tc_pos); + delta2 = (v8i16) q1_src + (v8i16) delta2; + delta2 = CLIP_SH_0_255(delta2); + delta2 = (v8i16) __msa_bmnz_v((v16u8) delta2, (v16u8) q1_src, + (v16u8) q_is_pcm_vec); + + dst1 = (v16u8) __msa_bmz_v((v16u8) delta1, (v16u8) p1_src, + (v16u8) abs_delta0); + dst2 = (v16u8) __msa_bmz_v((v16u8) temp0, (v16u8) p0_src, + (v16u8) abs_delta0); + dst3 = (v16u8) __msa_bmz_v((v16u8) temp2, (v16u8) q0_src, + (v16u8) abs_delta0); + dst4 = (v16u8) __msa_bmz_v((v16u8) delta2, (v16u8) q1_src, + (v16u8) abs_delta0); + /* pack results to 8 bit */ + PCKEV_B2_UB(dst2, dst1, dst4, dst3, dst0, dst1); + + /* pack src to 8 bit */ + PCKEV_B2_UB(p0_src, p1_src, q1_src, q0_src, dst2, dst3); + + dst0 = __msa_bmz_v(dst0, dst2, (v16u8) cmp3); + dst1 = __msa_bmz_v(dst1, dst3, (v16u8) cmp3); + + p2 += stride; + ST8x4_UB(dst0, dst1, p2, stride); + /* weak filter ends */ + } else { /* strong + weak */ + /* strong filter */ + tc_pos <<= 1; + tc_neg = -tc_pos; + + /* p part */ + temp0 = (p1_src + p0_src + q0_src); + temp1 = ((p3_src + p2_src) << 1) + p2_src + temp0; + temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); + temp2 = (v8i16) (temp1 - p2_src); + temp2 = CLIP_SH(temp2, tc_neg, tc_pos); + dst0 = (v16u8) (temp2 + (v8i16) p2_src); + + temp1 = temp0 + p2_src; + temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 2); + temp2 = (v8i16) (temp1 - p1_src); + temp2 = CLIP_SH(temp2, tc_neg, tc_pos); + dst1 = (v16u8) (temp2 + (v8i16) p1_src); + + temp1 = (temp0 << 1) + p2_src + q1_src; + temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); + temp2 = (v8i16) (temp1 - p0_src); + temp2 = CLIP_SH(temp2, tc_neg, tc_pos); + dst2 = (v16u8) (temp2 + (v8i16) p0_src); + + dst0 = __msa_bmz_v(dst0, (v16u8) p2_src, (v16u8) p_is_pcm_vec); + dst1 = __msa_bmz_v(dst1, (v16u8) p1_src, (v16u8) p_is_pcm_vec); + dst2 = __msa_bmz_v(dst2, (v16u8) p0_src, (v16u8) p_is_pcm_vec); + + /* q part */ + temp0 = (q1_src + p0_src + q0_src); + + temp1 = ((q3_src + q2_src) << 1) + q2_src + temp0; + temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); + temp2 = (v8i16) (temp1 - q2_src); + temp2 = CLIP_SH(temp2, tc_neg, tc_pos); + dst5 = (v16u8) (temp2 + (v8i16) q2_src); + + temp1 = temp0 + q2_src; + temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 2); + temp2 = (v8i16) (temp1 - q1_src); + temp2 = CLIP_SH(temp2, tc_neg, tc_pos); + dst4 = (v16u8) (temp2 + (v8i16) q1_src); + + temp1 = (temp0 << 1) + p1_src + q2_src; + temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); + temp2 = (v8i16) (temp1 - q0_src); + temp2 = CLIP_SH(temp2, tc_neg, tc_pos); + dst3 = (v16u8) (temp2 + (v8i16) q0_src); dst3 = __msa_bmz_v(dst3, (v16u8) q0_src, (v16u8) q_is_pcm_vec); dst4 = __msa_bmz_v(dst4, (v16u8) q1_src, (v16u8) q_is_pcm_vec); dst5 = __msa_bmz_v(dst5, (v16u8) q2_src, (v16u8) q_is_pcm_vec); + /* pack strong results to 8 bit */ + PCKEV_B2_UB(dst1, dst0, dst3, dst2, dst0, dst1); + dst2 = (v16u8) __msa_pckev_b((v16i8) dst5, (v16i8) dst4); + /* strong filter ends */ + + /* weak filter */ tc_pos >>= 1; tc_neg = -tc_pos; @@ -193,16 +376,18 @@ static void hevc_loopfilter_luma_hor_msa(uint8_t *src, int32_t stride, temp2 = (v8i16) __msa_bmz_v((v16u8) temp2, (v16u8) q0_src, (v16u8) q_is_pcm_vec); + p_is_pcm_vec = ~p_is_pcm_vec; + q_is_pcm_vec = ~q_is_pcm_vec; tmp = (beta + (beta >> 1)) >> 3; - cmp0 = __msa_fill_d(!p_is_pcm0 && ((dp00 + dp30) < tmp)); - cmp1 = __msa_fill_d(!p_is_pcm4 && ((dp04 + dp34) < tmp)); - p_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); - p_is_pcm_vec = __msa_ceqi_d(p_is_pcm_vec, 0); + cmp0 = __msa_fill_d(dp00 + dp30 < tmp); + cmp1 = __msa_fill_d(dp04 + dp34 < tmp); + cmp0 = __msa_ilvev_d(cmp1, cmp0); + p_is_pcm_vec = p_is_pcm_vec | __msa_ceqi_d(cmp0, 0); - cmp0 = (v2i64) __msa_fill_h((!q_is_pcm0) && (dq00 + dq30 < tmp)); - cmp1 = (v2i64) __msa_fill_h((!q_is_pcm4) && (dq04 + dq34 < tmp)); - q_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); - q_is_pcm_vec = __msa_ceqi_d(q_is_pcm_vec, 0); + cmp0 = __msa_fill_d(dq00 + dq30 < tmp); + cmp1 = __msa_fill_d(dq04 + dq34 < tmp); + cmp0 = __msa_ilvev_d(cmp1, cmp0); + q_is_pcm_vec = q_is_pcm_vec | __msa_ceqi_d(cmp0, 0); tc_pos >>= 1; tc_neg = -tc_pos; @@ -235,28 +420,24 @@ static void hevc_loopfilter_luma_hor_msa(uint8_t *src, int32_t stride, (v16u8) abs_delta0); delta2 = (v8i16) __msa_bmz_v((v16u8) delta2, (v16u8) q1_src, (v16u8) abs_delta0); + /* weak filter ends */ - dst2 = __msa_bmnz_v(dst2, (v16u8) temp0, (v16u8) cmp2); - dst3 = __msa_bmnz_v(dst3, (v16u8) temp2, (v16u8) cmp2); - dst1 = __msa_bmnz_v(dst1, (v16u8) delta1, (v16u8) cmp2); - dst4 = __msa_bmnz_v(dst4, (v16u8) delta2, (v16u8) cmp2); - dst0 = __msa_bmnz_v(dst0, (v16u8) p2_src, (v16u8) cmp2); - dst5 = __msa_bmnz_v(dst5, (v16u8) q2_src, (v16u8) cmp2); + /* pack weak results to 8 bit */ + PCKEV_B2_UB(delta1, p2_src, temp2, temp0, dst3, dst4); + dst5 = (v16u8) __msa_pckev_b((v16i8) q2_src, (v16i8) delta2); - cmp0 = __msa_fill_d(d00 + d30 >= beta); - cmp1 = __msa_fill_d(d04 + d34 >= beta); - cmp0 = __msa_ilvev_d(cmp1, cmp0); - cmp0 = __msa_ceqi_d(cmp0, 0); + /* select between weak or strong */ + dst0 = __msa_bmnz_v(dst0, dst3, (v16u8) cmp2); + dst1 = __msa_bmnz_v(dst1, dst4, (v16u8) cmp2); + dst2 = __msa_bmnz_v(dst2, dst5, (v16u8) cmp2); - dst0 = __msa_bmz_v(dst0, (v16u8) p2_src, (v16u8) cmp0); - dst1 = __msa_bmz_v(dst1, (v16u8) p1_src, (v16u8) cmp0); - dst2 = __msa_bmz_v(dst2, (v16u8) p0_src, (v16u8) cmp0); - dst3 = __msa_bmz_v(dst3, (v16u8) q0_src, (v16u8) cmp0); - dst4 = __msa_bmz_v(dst4, (v16u8) q1_src, (v16u8) cmp0); - dst5 = __msa_bmz_v(dst5, (v16u8) q2_src, (v16u8) cmp0); + /* pack src to 8 bit */ + PCKEV_B2_UB(p1_src, p2_src, q0_src, p0_src, dst3, dst4); + dst5 = (v16u8) __msa_pckev_b((v16i8) q2_src, (v16i8) q1_src); - PCKEV_B2_UB(dst1, dst0, dst3, dst2, dst0, dst1); - dst2 = (v16u8) __msa_pckev_b((v16i8) dst5, (v16i8) dst4); + dst0 = __msa_bmz_v(dst0, dst3, (v16u8) cmp3); + dst1 = __msa_bmz_v(dst1, dst4, (v16u8) cmp3); + dst2 = __msa_bmz_v(dst2, dst5, (v16u8) cmp3); dst_val0 = __msa_copy_u_d((v2i64) dst2, 0); dst_val1 = __msa_copy_u_d((v2i64) dst2, 1); @@ -282,11 +463,13 @@ static void hevc_loopfilter_luma_ver_msa(uint8_t *src, int32_t stride, uint16_t tmp0, tmp1; uint32_t tmp2, tmp3; int32_t dp00, dq00, dp30, dq30, d00, d30; + int32_t d0030, d0434; int32_t dp04, dq04, dp34, dq34, d04, d34; int32_t tc0, p_is_pcm0, q_is_pcm0, beta30, beta20, tc250; int32_t tc4, p_is_pcm4, q_is_pcm4, tc254, tmp; v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; v2i64 cmp0, cmp1, cmp2, p_is_pcm_vec, q_is_pcm_vec; + v2i64 cmp3; v8u16 temp0, temp1; v8i16 temp2; v8i16 tc_pos, tc_neg; @@ -312,51 +495,71 @@ static void hevc_loopfilter_luma_ver_msa(uint8_t *src, int32_t stride, p_is_pcm4 = p_is_pcm[1]; q_is_pcm4 = q_is_pcm[1]; - if (!p_is_pcm0 || !p_is_pcm4 || !q_is_pcm0 || !q_is_pcm4) { - if (!(d00 + d30 >= beta) || !(d04 + d34 >= beta)) { - src -= 4; - LD_UH8(src, stride, - p3_src, p2_src, p1_src, p0_src, q0_src, q1_src, q2_src, - q3_src); - - tc0 = tc[0]; - beta30 = beta >> 3; - beta20 = beta >> 2; - tc250 = ((tc0 * 5 + 1) >> 1); - - tc4 = tc[1]; - tc254 = ((tc4 * 5 + 1) >> 1); - - TRANSPOSE8x8_UB_UH(p3_src, p2_src, p1_src, p0_src, q0_src, q1_src, - q2_src, q3_src, p3_src, p2_src, p1_src, p0_src, - q0_src, q1_src, q2_src, q3_src); - - flag0 = (abs(p3[-4] - p3[-1]) + abs(p3[3] - p3[0]) < beta30 && - abs(p3[-1] - p3[0]) < tc250 && - abs(p2[-4] - p2[-1]) + abs(p2[3] - p2[0]) < beta30 && - abs(p2[-1] - p2[0]) < tc250 && - (d00 << 1) < beta20 && (d30 << 1) < beta20); - cmp0 = __msa_fill_d(flag0); - - flag1 = (abs(p1[-4] - p1[-1]) + abs(p1[3] - p1[0]) < beta30 && - abs(p1[-1] - p1[0]) < tc254 && - abs(p0[-4] - p0[-1]) + abs(p0[3] - p0[0]) < beta30 && - abs(p0[-1] - p0[0]) < tc254 && - (d04 << 1) < beta20 && (d34 << 1) < beta20); - cmp1 = __msa_fill_d(flag1); - cmp2 = __msa_ilvev_d(cmp1, cmp0); - cmp2 = __msa_ceqi_d(cmp2, 0); - - ILVR_B8_UH(zero, p3_src, zero, p2_src, zero, p1_src, zero, p0_src, - zero, q0_src, zero, q1_src, zero, q2_src, zero, q3_src, - p3_src, p2_src, p1_src, p0_src, q0_src, q1_src, q2_src, - q3_src); - - cmp0 = (v2i64) __msa_fill_h(tc0 << 1); - cmp1 = (v2i64) __msa_fill_h(tc4 << 1); - tc_pos = (v8i16) __msa_ilvev_d(cmp1, cmp0); + cmp0 = __msa_fill_d(p_is_pcm0); + cmp1 = __msa_fill_d(p_is_pcm4); + p_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); + p_is_pcm_vec = __msa_ceqi_d(p_is_pcm_vec, 0); + + d0030 = (d00 + d30) >= beta; + d0434 = (d04 + d34) >= beta; + + cmp0 = __msa_fill_d(d0030); + cmp1 = __msa_fill_d(d0434); + cmp3 = __msa_ilvev_d(cmp1, cmp0); + cmp3 = (v2i64) __msa_ceqi_d(cmp3, 0); + + if ((!p_is_pcm0 || !p_is_pcm4 || !q_is_pcm0 || !q_is_pcm4) && + (!d0030 || !d0434)) { + src -= 4; + LD_UH8(src, stride, p3_src, p2_src, p1_src, p0_src, q0_src, q1_src, + q2_src, q3_src); + + cmp0 = __msa_fill_d(q_is_pcm0); + cmp1 = __msa_fill_d(q_is_pcm4); + q_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); + q_is_pcm_vec = __msa_ceqi_d(q_is_pcm_vec, 0); + + tc0 = tc[0]; + beta30 = beta >> 3; + beta20 = beta >> 2; + tc250 = ((tc0 * 5 + 1) >> 1); + + tc4 = tc[1]; + tc254 = ((tc4 * 5 + 1) >> 1); + cmp0 = (v2i64) __msa_fill_h(tc0 << 1); + cmp1 = (v2i64) __msa_fill_h(tc4 << 1); + tc_pos = (v8i16) __msa_ilvev_d(cmp1, cmp0); + + TRANSPOSE8x8_UB_UH(p3_src, p2_src, p1_src, p0_src, q0_src, q1_src, + q2_src, q3_src, p3_src, p2_src, p1_src, p0_src, + q0_src, q1_src, q2_src, q3_src); + + flag0 = abs(p3[-4] - p3[-1]) + abs(p3[3] - p3[0]) < beta30 && + abs(p3[-1] - p3[0]) < tc250; + flag0 = flag0 && (abs(p2[-4] - p2[-1]) + abs(p2[3] - p2[0]) < beta30 && + abs(p2[-1] - p2[0]) < tc250 && (d00 << 1) < beta20 && + (d30 << 1) < beta20); + cmp0 = __msa_fill_d(flag0); + ILVR_B4_UH(zero, p3_src, zero, p2_src, zero, p1_src, zero, p0_src, + p3_src, p2_src, p1_src, p0_src); + + flag1 = abs(p1[-4] - p1[-1]) + abs(p1[3] - p1[0]) < beta30 && + abs(p1[-1] - p1[0]) < tc254; + flag1 = flag1 && (abs(p0[-4] - p0[-1]) + abs(p0[3] - p0[0]) < beta30 && + abs(p0[-1] - p0[0]) < tc254 && (d04 << 1) < beta20 && + (d34 << 1) < beta20); + ILVR_B4_UH(zero, q0_src, zero, q1_src, zero, q2_src, zero, q3_src, + q0_src, q1_src, q2_src, q3_src); + + cmp1 = __msa_fill_d(flag1); + cmp2 = __msa_ilvev_d(cmp1, cmp0); + cmp2 = __msa_ceqi_d(cmp2, 0); + + if (flag0 && flag1) { /* strong only */ + /* strong filter */ tc_neg = -tc_pos; + /* p part */ temp0 = (p1_src + p0_src + q0_src); temp1 = ((p3_src + p2_src) << 1) + p2_src + temp0; @@ -377,15 +580,11 @@ static void hevc_loopfilter_luma_ver_msa(uint8_t *src, int32_t stride, temp2 = CLIP_SH(temp2, tc_neg, tc_pos); dst2 = (v16u8) (temp2 + (v8i16) p0_src); - cmp0 = __msa_fill_d(p_is_pcm0); - cmp1 = __msa_fill_d(p_is_pcm4); - p_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); - p_is_pcm_vec = __msa_ceqi_d(p_is_pcm_vec, 0); - dst0 = __msa_bmz_v(dst0, (v16u8) p2_src, (v16u8) p_is_pcm_vec); dst1 = __msa_bmz_v(dst1, (v16u8) p1_src, (v16u8) p_is_pcm_vec); dst2 = __msa_bmz_v(dst2, (v16u8) p0_src, (v16u8) p_is_pcm_vec); + /* q part */ temp0 = (q1_src + p0_src + q0_src); temp1 = ((q3_src + q2_src) << 1) + q2_src + temp0; temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); @@ -405,22 +604,19 @@ static void hevc_loopfilter_luma_ver_msa(uint8_t *src, int32_t stride, temp2 = CLIP_SH(temp2, tc_neg, tc_pos); dst3 = (v16u8) (temp2 + (v8i16) q0_src); - cmp0 = __msa_fill_d(q_is_pcm0); - cmp1 = __msa_fill_d(q_is_pcm4); - q_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); - q_is_pcm_vec = __msa_ceqi_d(q_is_pcm_vec, 0); - dst3 = __msa_bmz_v(dst3, (v16u8) q0_src, (v16u8) q_is_pcm_vec); dst4 = __msa_bmz_v(dst4, (v16u8) q1_src, (v16u8) q_is_pcm_vec); dst5 = __msa_bmz_v(dst5, (v16u8) q2_src, (v16u8) q_is_pcm_vec); - + /* strong filter ends */ + } else if (flag0 == flag1) { /* weak only */ + /* weak filter */ tc_pos >>= 1; tc_neg = -tc_pos; diff0 = (v8i16) (q0_src - p0_src); diff1 = (v8i16) (q1_src - p1_src); - diff0 = (v8i16) (diff0 << 3) + diff0; - diff1 = (v8i16) (diff1 << 1) + diff1; + diff0 = (diff0 << 3) + diff0; + diff1 = (diff1 << 1) + diff1; delta0 = diff0 - diff1; delta0 = __msa_srari_h(delta0, 4); @@ -429,19 +625,19 @@ static void hevc_loopfilter_luma_ver_msa(uint8_t *src, int32_t stride, abs_delta0 = (v8u16) abs_delta0 < temp1; delta0 = CLIP_SH(delta0, tc_neg, tc_pos); - temp0 = (v8u16) delta0 + p0_src; + temp0 = (v8u16) (delta0 + p0_src); temp0 = (v8u16) CLIP_SH_0_255(temp0); temp0 = (v8u16) __msa_bmz_v((v16u8) temp0, (v16u8) p0_src, (v16u8) p_is_pcm_vec); - temp2 = (v8i16) q0_src - delta0; + temp2 = (v8i16) (q0_src - delta0); temp2 = CLIP_SH_0_255(temp2); temp2 = (v8i16) __msa_bmz_v((v16u8) temp2, (v16u8) q0_src, (v16u8) q_is_pcm_vec); tmp = ((beta + (beta >> 1)) >> 3); - cmp0 = __msa_fill_d(!p_is_pcm0 && (dp00 + dp30 < tmp)); - cmp1 = __msa_fill_d(!p_is_pcm4 && (dp04 + dp34 < tmp)); + cmp0 = __msa_fill_d(!p_is_pcm0 && ((dp00 + dp30) < tmp)); + cmp1 = __msa_fill_d(!p_is_pcm4 && ((dp04 + dp34) < tmp)); p_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); p_is_pcm_vec = __msa_ceqi_d(p_is_pcm_vec, 0); @@ -472,86 +668,252 @@ static void hevc_loopfilter_luma_ver_msa(uint8_t *src, int32_t stride, delta2 = CLIP_SH_0_255(delta2); delta2 = (v8i16) __msa_bmnz_v((v16u8) delta2, (v16u8) q1_src, (v16u8) q_is_pcm_vec); - delta1 = (v8i16) __msa_bmz_v((v16u8) delta1, (v16u8) p1_src, - (v16u8) abs_delta0); - temp0 = (v8u16) __msa_bmz_v((v16u8) temp0, (v16u8) p0_src, - (v16u8) abs_delta0); - temp2 = (v8i16) __msa_bmz_v((v16u8) temp2, (v16u8) q0_src, - (v16u8) abs_delta0); - delta2 = (v8i16) __msa_bmz_v((v16u8) delta2, (v16u8) q1_src, - (v16u8) abs_delta0); - dst2 = __msa_bmnz_v(dst2, (v16u8) temp0, (v16u8) cmp2); - dst3 = __msa_bmnz_v(dst3, (v16u8) temp2, (v16u8) cmp2); - dst1 = __msa_bmnz_v(dst1, (v16u8) delta1, (v16u8) cmp2); - dst4 = __msa_bmnz_v(dst4, (v16u8) delta2, (v16u8) cmp2); - dst0 = __msa_bmnz_v(dst0, (v16u8) p2_src, (v16u8) cmp2); - dst5 = __msa_bmnz_v(dst5, (v16u8) q2_src, (v16u8) cmp2); + dst0 = __msa_bmz_v((v16u8) delta1, (v16u8) p1_src, + (v16u8) abs_delta0); + dst1 = __msa_bmz_v((v16u8) temp0, (v16u8) p0_src, + (v16u8) abs_delta0); + dst2 = __msa_bmz_v((v16u8) temp2, (v16u8) q0_src, + (v16u8) abs_delta0); + dst3 = __msa_bmz_v((v16u8) delta2, (v16u8) q1_src, + (v16u8) abs_delta0); + /* weak filter ends */ - cmp0 = __msa_fill_d(d00 + d30 >= beta); - dst7 = (v16u8) __msa_fill_d(d04 + d34 >= beta); - cmp0 = __msa_ilvev_d((v2i64) dst7, cmp0); - dst6 = (v16u8) __msa_ceqi_d(cmp0, 0); + dst0 = __msa_bmz_v(dst0, (v16u8) p1_src, (v16u8) cmp3); + dst1 = __msa_bmz_v(dst1, (v16u8) p0_src, (v16u8) cmp3); + dst2 = __msa_bmz_v(dst2, (v16u8) q0_src, (v16u8) cmp3); + dst3 = __msa_bmz_v(dst3, (v16u8) q1_src, (v16u8) cmp3); - dst0 = __msa_bmz_v(dst0, (v16u8) p2_src, dst6); - dst1 = __msa_bmz_v(dst1, (v16u8) p1_src, dst6); - dst2 = __msa_bmz_v(dst2, (v16u8) p0_src, dst6); - dst3 = __msa_bmz_v(dst3, (v16u8) q0_src, dst6); - dst4 = __msa_bmz_v(dst4, (v16u8) q1_src, dst6); - dst5 = __msa_bmz_v(dst5, (v16u8) q2_src, dst6); + PCKEV_B2_UB(dst2, dst0, dst3, dst1, dst0, dst1); - PCKEV_B4_UB(dst0, dst0, dst1, dst1, dst2, dst2, dst3, dst3, - dst0, dst1, dst2, dst3); - PCKEV_B2_UB(dst4, dst4, dst5, dst5, dst4, dst5); + /* transpose */ + ILVRL_B2_UB(dst1, dst0, dst4, dst5); + ILVRL_H2_UB(dst5, dst4, dst0, dst1); - TRANSPOSE8x8_UB_UB(dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7, - dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7); - - src += 1; + src += 2; tmp2 = __msa_copy_u_w((v4i32) dst0, 0); - tmp0 = __msa_copy_u_h((v8i16) dst0, 2); - tmp3 = __msa_copy_u_w((v4i32) dst1, 0); - tmp1 = __msa_copy_u_h((v8i16) dst1, 2); + tmp3 = __msa_copy_u_w((v4i32) dst0, 1); SW(tmp2, src); - SH(tmp0, src + 4); src += stride; SW(tmp3, src); - SH(tmp1, src + 4); src += stride; - tmp2 = __msa_copy_u_w((v4i32) dst2, 0); - tmp0 = __msa_copy_u_h((v8i16) dst2, 2); - tmp3 = __msa_copy_u_w((v4i32) dst3, 0); - tmp1 = __msa_copy_u_h((v8i16) dst3, 2); + tmp2 = __msa_copy_u_w((v4i32) dst0, 2); + tmp3 = __msa_copy_u_w((v4i32) dst0, 3); SW(tmp2, src); - SH(tmp0, src + 4); src += stride; SW(tmp3, src); - SH(tmp1, src + 4); src += stride; - tmp2 = __msa_copy_u_w((v4i32) dst4, 0); - tmp0 = __msa_copy_u_h((v8i16) dst4, 2); - tmp3 = __msa_copy_u_w((v4i32) dst5, 0); - tmp1 = __msa_copy_u_h((v8i16) dst5, 2); + tmp2 = __msa_copy_u_w((v4i32) dst1, 0); + tmp3 = __msa_copy_u_w((v4i32) dst1, 1); SW(tmp2, src); - SH(tmp0, src + 4); src += stride; SW(tmp3, src); - SH(tmp1, src + 4); src += stride; - tmp2 = __msa_copy_u_w((v4i32) dst6, 0); - tmp0 = __msa_copy_u_h((v8i16) dst6, 2); - tmp3 = __msa_copy_u_w((v4i32) dst7, 0); - tmp1 = __msa_copy_u_h((v8i16) dst7, 2); + tmp2 = __msa_copy_u_w((v4i32) dst1, 2); + tmp3 = __msa_copy_u_w((v4i32) dst1, 3); SW(tmp2, src); - SH(tmp0, src + 4); src += stride; SW(tmp3, src); - SH(tmp1, src + 4); + + return; + } else { /* strong + weak */ + /* strong filter */ + tc_neg = -tc_pos; + + /* p part */ + temp0 = (p1_src + p0_src + q0_src); + + temp1 = ((p3_src + p2_src) << 1) + p2_src + temp0; + temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); + temp2 = (v8i16) (temp1 - p2_src); + temp2 = CLIP_SH(temp2, tc_neg, tc_pos); + dst0 = (v16u8) (temp2 + (v8i16) p2_src); + + temp1 = temp0 + p2_src; + temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 2); + temp2 = (v8i16) (temp1 - p1_src); + temp2 = CLIP_SH(temp2, tc_neg, tc_pos); + dst1 = (v16u8) (temp2 + (v8i16) p1_src); + + temp1 = (temp0 << 1) + p2_src + q1_src; + temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); + temp2 = (v8i16) (temp1 - p0_src); + temp2 = CLIP_SH(temp2, tc_neg, tc_pos); + dst2 = (v16u8) (temp2 + (v8i16) p0_src); + + dst0 = __msa_bmz_v(dst0, (v16u8) p2_src, (v16u8) p_is_pcm_vec); + dst1 = __msa_bmz_v(dst1, (v16u8) p1_src, (v16u8) p_is_pcm_vec); + dst2 = __msa_bmz_v(dst2, (v16u8) p0_src, (v16u8) p_is_pcm_vec); + + /* q part */ + temp0 = (q1_src + p0_src + q0_src); + temp1 = ((q3_src + q2_src) << 1) + q2_src + temp0; + temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); + temp2 = (v8i16) (temp1 - q2_src); + temp2 = CLIP_SH(temp2, tc_neg, tc_pos); + dst5 = (v16u8) (temp2 + (v8i16) q2_src); + + temp1 = temp0 + q2_src; + temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 2); + temp2 = (v8i16) (temp1 - q1_src); + temp2 = CLIP_SH(temp2, tc_neg, tc_pos); + dst4 = (v16u8) (temp2 + (v8i16) q1_src); + + temp1 = (temp0 << 1) + p1_src + q2_src; + temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); + temp2 = (v8i16) (temp1 - q0_src); + temp2 = CLIP_SH(temp2, tc_neg, tc_pos); + dst3 = (v16u8) (temp2 + (v8i16) q0_src); + + dst3 = __msa_bmz_v(dst3, (v16u8) q0_src, (v16u8) q_is_pcm_vec); + dst4 = __msa_bmz_v(dst4, (v16u8) q1_src, (v16u8) q_is_pcm_vec); + dst5 = __msa_bmz_v(dst5, (v16u8) q2_src, (v16u8) q_is_pcm_vec); + /* strong filter ends */ + + /* weak filter */ + tc_pos >>= 1; + tc_neg = -tc_pos; + + diff0 = (v8i16) (q0_src - p0_src); + diff1 = (v8i16) (q1_src - p1_src); + diff0 = (diff0 << 3) + diff0; + diff1 = (diff1 << 1) + diff1; + delta0 = diff0 - diff1; + delta0 = __msa_srari_h(delta0, 4); + + temp1 = (v8u16) ((tc_pos << 3) + (tc_pos << 1)); + abs_delta0 = __msa_add_a_h(delta0, (v8i16) zero); + abs_delta0 = (v8u16) abs_delta0 < temp1; + + delta0 = CLIP_SH(delta0, tc_neg, tc_pos); + + temp0 = (v8u16) (delta0 + p0_src); + temp0 = (v8u16) CLIP_SH_0_255(temp0); + temp0 = (v8u16) __msa_bmz_v((v16u8) temp0, (v16u8) p0_src, + (v16u8) p_is_pcm_vec); + + temp2 = (v8i16) (q0_src - delta0); + temp2 = CLIP_SH_0_255(temp2); + temp2 = (v8i16) __msa_bmz_v((v16u8) temp2, (v16u8) q0_src, + (v16u8) q_is_pcm_vec); + + tmp = (beta + (beta >> 1)) >> 3; + cmp0 = __msa_fill_d(!p_is_pcm0 && ((dp00 + dp30) < tmp)); + cmp1 = __msa_fill_d(!p_is_pcm4 && ((dp04 + dp34) < tmp)); + p_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); + p_is_pcm_vec = __msa_ceqi_d(p_is_pcm_vec, 0); + + cmp0 = (v2i64) __msa_fill_h((!q_is_pcm0) && (dq00 + dq30 < tmp)); + cmp1 = (v2i64) __msa_fill_h((!q_is_pcm4) && (dq04 + dq34 < tmp)); + q_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); + q_is_pcm_vec = __msa_ceqi_d(q_is_pcm_vec, 0); + + tc_pos >>= 1; + tc_neg = -tc_pos; + + delta1 = (v8i16) __msa_aver_u_h(p2_src, p0_src); + delta1 -= (v8i16) p1_src; + delta1 += delta0; + delta1 >>= 1; + delta1 = CLIP_SH(delta1, tc_neg, tc_pos); + delta1 = (v8i16) p1_src + (v8i16) delta1; + delta1 = CLIP_SH_0_255(delta1); + delta1 = (v8i16) __msa_bmnz_v((v16u8) delta1, (v16u8) p1_src, + (v16u8) p_is_pcm_vec); + + delta2 = (v8i16) __msa_aver_u_h(q0_src, q2_src); + delta2 = delta2 - (v8i16) q1_src; + delta2 = delta2 - delta0; + delta2 = delta2 >> 1; + delta2 = CLIP_SH(delta2, tc_neg, tc_pos); + delta2 = (v8i16) q1_src + (v8i16) delta2; + delta2 = CLIP_SH_0_255(delta2); + delta2 = (v8i16) __msa_bmnz_v((v16u8) delta2, (v16u8) q1_src, + (v16u8) q_is_pcm_vec); + delta1 = (v8i16) __msa_bmz_v((v16u8) delta1, (v16u8) p1_src, + (v16u8) abs_delta0); + temp0 = (v8u16) __msa_bmz_v((v16u8) temp0, (v16u8) p0_src, + (v16u8) abs_delta0); + temp2 = (v8i16) __msa_bmz_v((v16u8) temp2, (v16u8) q0_src, + (v16u8) abs_delta0); + delta2 = (v8i16) __msa_bmz_v((v16u8) delta2, (v16u8) q1_src, + (v16u8) abs_delta0); + /* weak filter ends*/ + + /* select between weak or strong */ + dst2 = __msa_bmnz_v(dst2, (v16u8) temp0, (v16u8) cmp2); + dst3 = __msa_bmnz_v(dst3, (v16u8) temp2, (v16u8) cmp2); + dst1 = __msa_bmnz_v(dst1, (v16u8) delta1, (v16u8) cmp2); + dst4 = __msa_bmnz_v(dst4, (v16u8) delta2, (v16u8) cmp2); + dst0 = __msa_bmnz_v(dst0, (v16u8) p2_src, (v16u8) cmp2); + dst5 = __msa_bmnz_v(dst5, (v16u8) q2_src, (v16u8) cmp2); } + + dst0 = __msa_bmz_v(dst0, (v16u8) p2_src, (v16u8) cmp3); + dst1 = __msa_bmz_v(dst1, (v16u8) p1_src, (v16u8) cmp3); + dst2 = __msa_bmz_v(dst2, (v16u8) p0_src, (v16u8) cmp3); + dst3 = __msa_bmz_v(dst3, (v16u8) q0_src, (v16u8) cmp3); + dst4 = __msa_bmz_v(dst4, (v16u8) q1_src, (v16u8) cmp3); + dst5 = __msa_bmz_v(dst5, (v16u8) q2_src, (v16u8) cmp3); + + /* pack results to 8 bit */ + PCKEV_B4_UB(dst2, dst0, dst3, dst1, dst4, dst4, dst5, dst5, dst0, dst1, + dst2, dst3); + + /* transpose */ + ILVRL_B2_UB(dst1, dst0, dst4, dst5); + ILVRL_B2_UB(dst3, dst2, dst6, dst7); + ILVRL_H2_UB(dst5, dst4, dst0, dst1); + ILVRL_H2_UB(dst7, dst6, dst2, dst3); + + src += 1; + + tmp2 = __msa_copy_u_w((v4i32) dst0, 0); + tmp3 = __msa_copy_u_w((v4i32) dst0, 1); + tmp0 = __msa_copy_u_h((v8i16) dst2, 0); + tmp1 = __msa_copy_u_h((v8i16) dst2, 2); + SW(tmp2, src); + SH(tmp0, src + 4); + src += stride; + SW(tmp3, src); + SH(tmp1, src + 4); + src += stride; + + tmp2 = __msa_copy_u_w((v4i32) dst0, 2); + tmp3 = __msa_copy_u_w((v4i32) dst0, 3); + tmp0 = __msa_copy_u_h((v8i16) dst2, 4); + tmp1 = __msa_copy_u_h((v8i16) dst2, 6); + SW(tmp2, src); + SH(tmp0, src + 4); + src += stride; + SW(tmp3, src); + SH(tmp1, src + 4); + src += stride; + + tmp2 = __msa_copy_u_w((v4i32) dst1, 0); + tmp3 = __msa_copy_u_w((v4i32) dst1, 1); + tmp0 = __msa_copy_u_h((v8i16) dst3, 0); + tmp1 = __msa_copy_u_h((v8i16) dst3, 2); + SW(tmp2, src); + SH(tmp0, src + 4); + src += stride; + SW(tmp3, src); + SH(tmp1, src + 4); + src += stride; + + tmp2 = __msa_copy_u_w((v4i32) dst1, 2); + tmp3 = __msa_copy_u_w((v4i32) dst1, 3); + tmp0 = __msa_copy_u_h((v8i16) dst3, 4); + tmp1 = __msa_copy_u_h((v8i16) dst3, 6); + SW(tmp2, src); + SH(tmp0, src + 4); + src += stride; + SW(tmp3, src); + SH(tmp1, src + 4); } } From c6314cd750dfba2505a232cc16541395c986613a Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Tue, 12 Sep 2017 17:01:58 +0530 Subject: [PATCH 3082/3374] avcodec/mips: Improve hevc idct msa functions Align the buffers. Remove reduandant constant array. Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/hevc_idct_msa.c | 255 +++++++++++++++++++++----------- 1 file changed, 171 insertions(+), 84 deletions(-) diff --git a/libavcodec/mips/hevc_idct_msa.c b/libavcodec/mips/hevc_idct_msa.c index d483707e72955..09431196bb984 100644 --- a/libavcodec/mips/hevc_idct_msa.c +++ b/libavcodec/mips/hevc_idct_msa.c @@ -21,18 +21,18 @@ #include "libavutil/mips/generic_macros_msa.h" #include "libavcodec/mips/hevcdsp_mips.h" -static const int16_t gt8x8_cnst[16] = { +static const int16_t gt8x8_cnst[16] __attribute__ ((aligned (64))) = { 64, 64, 83, 36, 89, 50, 18, 75, 64, -64, 36, -83, 75, -89, -50, -18 }; -static const int16_t gt16x16_cnst[64] = { +static const int16_t gt16x16_cnst[64] __attribute__ ((aligned (64))) = { 64, 83, 64, 36, 89, 75, 50, 18, 90, 80, 57, 25, 70, 87, 9, 43, 64, 36, -64, -83, 75, -18, -89, -50, 87, 9, -80, -70, -43, 57, -25, -90, 64, -36, -64, 83, 50, -89, 18, 75, 80, -70, -25, 90, -87, 9, 43, 57, 64, -83, 64, -36, 18, -50, 75, -89, 70, -87, 90, -80, 9, -43, -57, 25 }; -static const int16_t gt32x32_cnst0[256] = { +static const int16_t gt32x32_cnst0[256] __attribute__ ((aligned (64))) = { 90, 90, 88, 85, 82, 78, 73, 67, 61, 54, 46, 38, 31, 22, 13, 4, 90, 82, 67, 46, 22, -4, -31, -54, -73, -85, -90, -88, -78, -61, -38, -13, 88, 67, 31, -13, -54, -82, -90, -78, -46, -4, 38, 73, 90, 85, 61, 22, @@ -51,21 +51,17 @@ static const int16_t gt32x32_cnst0[256] = { 4, -13, 22, -31, 38, -46, 54, -61, 67, -73, 78, -82, 85, -88, 90, -90 }; -static const int16_t gt32x32_cnst1[64] = { +static const int16_t gt32x32_cnst1[64] __attribute__ ((aligned (64))) = { 90, 87, 80, 70, 57, 43, 25, 9, 87, 57, 9, -43, -80, -90, -70, -25, 80, 9, -70, -87, -25, 57, 90, 43, 70, -43, -87, 9, 90, 25, -80, -57, 57, -80, -25, 90, -9, -87, 43, 70, 43, -90, 57, 25, -87, 70, 9, -80, 25, -70, 90, -80, 43, 9, -57, 87, 9, -25, 43, -57, 70, -80, 87, -90 }; -static const int16_t gt32x32_cnst2[16] = { +static const int16_t gt32x32_cnst2[16] __attribute__ ((aligned (64))) = { 89, 75, 50, 18, 75, -18, -89, -50, 50, -89, 18, 75, 18, -50, 75, -89 }; -static const int16_t gt32x32_cnst3[16] = { - 64, 64, 64, 64, 83, 36, -36, -83, 64, -64, -64, 64, 36, -83, 83, -36 -}; - #define HEVC_IDCT4x4_COL(in_r0, in_l0, in_r1, in_l1, \ sum0, sum1, sum2, sum3, shift) \ { \ @@ -323,8 +319,12 @@ static void hevc_idct_4x4_msa(int16_t *coeffs) HEVC_IDCT4x4_COL(in_r0, in_l0, in_r1, in_l1, sum0, sum1, sum2, sum3, 7); TRANSPOSE4x4_SW_SW(sum0, sum1, sum2, sum3, in_r0, in_l0, in_r1, in_l1); HEVC_IDCT4x4_COL(in_r0, in_l0, in_r1, in_l1, sum0, sum1, sum2, sum3, 12); - TRANSPOSE4x4_SW_SW(sum0, sum1, sum2, sum3, sum0, sum1, sum2, sum3); - PCKEV_H2_SH(sum1, sum0, sum3, sum2, in0, in1); + + /* Pack and transpose */ + PCKEV_H2_SH(sum2, sum0, sum3, sum1, in0, in1); + ILVRL_H2_SW(in1, in0, sum0, sum1); + ILVRL_W2_SH(sum1, sum0, in0, in1); + ST_SH2(in0, in1, coeffs, 8); } @@ -432,27 +432,35 @@ static void hevc_idct_8x32_column_msa(int16_t *coeffs, uint8_t buf_pitch, const int16_t *filter_ptr0 = >32x32_cnst0[0]; const int16_t *filter_ptr1 = >32x32_cnst1[0]; const int16_t *filter_ptr2 = >32x32_cnst2[0]; - const int16_t *filter_ptr3 = >32x32_cnst3[0]; + const int16_t *filter_ptr3 = >8x8_cnst[0]; int16_t *src0 = (coeffs + buf_pitch); int16_t *src1 = (coeffs + 2 * buf_pitch); int16_t *src2 = (coeffs + 4 * buf_pitch); int16_t *src3 = (coeffs); int32_t cnst0, cnst1; - int32_t tmp_buf[8 * 32]; - int32_t *tmp_buf_ptr = &tmp_buf[0]; + int32_t tmp_buf[8 * 32 + 15]; + int32_t *tmp_buf_ptr = tmp_buf + 15; v8i16 in0, in1, in2, in3, in4, in5, in6, in7; v8i16 src0_r, src1_r, src2_r, src3_r, src4_r, src5_r, src6_r, src7_r; v8i16 src0_l, src1_l, src2_l, src3_l, src4_l, src5_l, src6_l, src7_l; v8i16 filt0, filter0, filter1, filter2, filter3; v4i32 sum0_r, sum0_l, sum1_r, sum1_l, tmp0_r, tmp0_l, tmp1_r, tmp1_l; + /* Align pointer to 64 byte boundary */ + tmp_buf_ptr = (int32_t *)(((uintptr_t) tmp_buf_ptr) & ~(uintptr_t) 63); + /* process coeff 4, 12, 20, 28 */ LD_SH4(src2, 8 * buf_pitch, in0, in1, in2, in3); ILVR_H2_SH(in1, in0, in3, in2, src0_r, src1_r); ILVL_H2_SH(in1, in0, in3, in2, src0_l, src1_l); + LD_SH2(src3, 16 * buf_pitch, in4, in6); + LD_SH2((src3 + 8 * buf_pitch), 16 * buf_pitch, in5, in7); + ILVR_H2_SH(in6, in4, in7, in5, src2_r, src3_r); + ILVL_H2_SH(in6, in4, in7, in5, src2_l, src3_l); + /* loop for all columns of constants */ - for (i = 0; i < 4; i++) { + for (i = 0; i < 2; i++) { /* processing single column of constants */ cnst0 = LW(filter_ptr2); cnst1 = LW(filter_ptr2 + 2); @@ -462,37 +470,39 @@ static void hevc_idct_8x32_column_msa(int16_t *coeffs, uint8_t buf_pitch, DOTP_SH2_SW(src0_r, src0_l, filter0, filter0, sum0_r, sum0_l); DPADD_SH2_SW(src1_r, src1_l, filter1, filter1, sum0_r, sum0_l); - ST_SW2(sum0_r, sum0_l, (tmp_buf_ptr + i * 8), 4); + ST_SW2(sum0_r, sum0_l, (tmp_buf_ptr + 2 * i * 8), 4); - filter_ptr2 += 4; - } + /* processing single column of constants */ + cnst0 = LW(filter_ptr2 + 4); + cnst1 = LW(filter_ptr2 + 6); - /* process coeff 0, 8, 16, 24 */ - LD_SH2(src3, 16 * buf_pitch, in0, in2); - LD_SH2((src3 + 8 * buf_pitch), 16 * buf_pitch, in1, in3); + filter0 = (v8i16) __msa_fill_w(cnst0); + filter1 = (v8i16) __msa_fill_w(cnst1); + + DOTP_SH2_SW(src0_r, src0_l, filter0, filter0, sum0_r, sum0_l); + DPADD_SH2_SW(src1_r, src1_l, filter1, filter1, sum0_r, sum0_l); + ST_SW2(sum0_r, sum0_l, (tmp_buf_ptr + (2 * i + 1) * 8), 4); - ILVR_H2_SH(in2, in0, in3, in1, src0_r, src1_r); - ILVL_H2_SH(in2, in0, in3, in1, src0_l, src1_l); + filter_ptr2 += 8; + } + /* process coeff 0, 8, 16, 24 */ /* loop for all columns of constants */ for (i = 0; i < 2; i++) { /* processing first column of filter constants */ cnst0 = LW(filter_ptr3); - cnst1 = LW(filter_ptr3 + 4); + cnst1 = LW(filter_ptr3 + 2); filter0 = (v8i16) __msa_fill_w(cnst0); filter1 = (v8i16) __msa_fill_w(cnst1); - DOTP_SH4_SW(src0_r, src0_l, src1_r, src1_l, filter0, filter0, filter1, + DOTP_SH4_SW(src2_r, src2_l, src3_r, src3_l, filter0, filter0, filter1, filter1, sum0_r, sum0_l, tmp1_r, tmp1_l); - sum1_r = sum0_r; - sum1_l = sum0_l; - sum0_r += tmp1_r; - sum0_l += tmp1_l; - - sum1_r -= tmp1_r; - sum1_l -= tmp1_l; + sum1_r = sum0_r - tmp1_r; + sum1_l = sum0_l - tmp1_l; + sum0_r = sum0_r + tmp1_r; + sum0_l = sum0_l + tmp1_l; HEVC_EVEN16_CALC(tmp_buf_ptr, sum0_r, sum0_l, i, (7 - i)); HEVC_EVEN16_CALC(tmp_buf_ptr, sum1_r, sum1_l, (3 - i), (4 + i)); @@ -618,11 +628,14 @@ static void hevc_idct_32x32_msa(int16_t *coeffs) { uint8_t row_cnt, col_cnt; int16_t *src = coeffs; - int16_t tmp_buf[8 * 32]; - int16_t *tmp_buf_ptr = &tmp_buf[0]; + int16_t tmp_buf[8 * 32 + 31]; + int16_t *tmp_buf_ptr = tmp_buf + 31; uint8_t round; uint8_t buf_pitch; + /* Align pointer to 64 byte boundary */ + tmp_buf_ptr = (int16_t *)(((uintptr_t) tmp_buf_ptr) & ~(uintptr_t) 63); + /* column transform */ round = 7; buf_pitch = 32; @@ -758,21 +771,22 @@ static void hevc_addblk_16x16_msa(int16_t *coeffs, uint8_t *dst, int32_t stride) { uint8_t loop_cnt; uint8_t *temp_dst = dst; - v16u8 dst0, dst1, dst2, dst3; + v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; v8i16 dst_r0, dst_l0, dst_r1, dst_l1, dst_r2, dst_l2, dst_r3, dst_l3; v8i16 in0, in1, in2, in3, in4, in5, in6, in7; - for (loop_cnt = 4; loop_cnt--;) { - LD_SH4(coeffs, 16, in0, in2, in4, in6); - LD_SH4((coeffs + 8), 16, in1, in3, in5, in7); - coeffs += 64; - LD_UB4(temp_dst, stride, dst0, dst1, dst2, dst3); - temp_dst += (4 * stride); + /* Pre-load for next iteration */ + LD_UB4(temp_dst, stride, dst4, dst5, dst6, dst7); + temp_dst += (4 * stride); + LD_SH4(coeffs, 16, in0, in2, in4, in6); + LD_SH4((coeffs + 8), 16, in1, in3, in5, in7); + coeffs += 64; - UNPCK_UB_SH(dst0, dst_r0, dst_l0); - UNPCK_UB_SH(dst1, dst_r1, dst_l1); - UNPCK_UB_SH(dst2, dst_r2, dst_l2); - UNPCK_UB_SH(dst3, dst_r3, dst_l3); + for (loop_cnt = 3; loop_cnt--;) { + UNPCK_UB_SH(dst4, dst_r0, dst_l0); + UNPCK_UB_SH(dst5, dst_r1, dst_l1); + UNPCK_UB_SH(dst6, dst_r2, dst_l2); + UNPCK_UB_SH(dst7, dst_r3, dst_l3); dst_r0 += in0; dst_l0 += in1; @@ -783,6 +797,13 @@ static void hevc_addblk_16x16_msa(int16_t *coeffs, uint8_t *dst, int32_t stride) dst_r3 += in6; dst_l3 += in7; + /* Pre-load for next iteration */ + LD_UB4(temp_dst, stride, dst4, dst5, dst6, dst7); + temp_dst += (4 * stride); + LD_SH4(coeffs, 16, in0, in2, in4, in6); + LD_SH4((coeffs + 8), 16, in1, in3, in5, in7); + coeffs += 64; + CLIP_SH4_0_255(dst_r0, dst_l0, dst_r1, dst_l1); CLIP_SH4_0_255(dst_r2, dst_l2, dst_r3, dst_l3); PCKEV_B4_UB(dst_l0, dst_r0, dst_l1, dst_r1, dst_l2, dst_r2, dst_l3, @@ -790,25 +811,50 @@ static void hevc_addblk_16x16_msa(int16_t *coeffs, uint8_t *dst, int32_t stride) ST_UB4(dst0, dst1, dst2, dst3, dst, stride); dst += (4 * stride); } + + UNPCK_UB_SH(dst4, dst_r0, dst_l0); + UNPCK_UB_SH(dst5, dst_r1, dst_l1); + UNPCK_UB_SH(dst6, dst_r2, dst_l2); + UNPCK_UB_SH(dst7, dst_r3, dst_l3); + + dst_r0 += in0; + dst_l0 += in1; + dst_r1 += in2; + dst_l1 += in3; + dst_r2 += in4; + dst_l2 += in5; + dst_r3 += in6; + dst_l3 += in7; + + CLIP_SH4_0_255(dst_r0, dst_l0, dst_r1, dst_l1); + CLIP_SH4_0_255(dst_r2, dst_l2, dst_r3, dst_l3); + PCKEV_B4_UB(dst_l0, dst_r0, dst_l1, dst_r1, dst_l2, dst_r2, dst_l3, + dst_r3, dst0, dst1, dst2, dst3); + ST_UB4(dst0, dst1, dst2, dst3, dst, stride); } static void hevc_addblk_32x32_msa(int16_t *coeffs, uint8_t *dst, int32_t stride) { uint8_t loop_cnt; uint8_t *temp_dst = dst; - v16u8 dst0, dst1, dst2, dst3; + v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; v8i16 dst_r0, dst_l0, dst_r1, dst_l1, dst_r2, dst_l2, dst_r3, dst_l3; v8i16 in0, in1, in2, in3, in4, in5, in6, in7; - for (loop_cnt = 8; loop_cnt--;) { - LD_SH4(coeffs, 32, in0, in2, in4, in6); - LD_SH4((coeffs + 8), 32, in1, in3, in5, in7); - LD_UB4(temp_dst, stride, dst0, dst1, dst2, dst3); - - UNPCK_UB_SH(dst0, dst_r0, dst_l0); - UNPCK_UB_SH(dst1, dst_r1, dst_l1); - UNPCK_UB_SH(dst2, dst_r2, dst_l2); - UNPCK_UB_SH(dst3, dst_r3, dst_l3); + /* Pre-load for next iteration */ + LD_UB2(temp_dst, 16, dst4, dst5); + temp_dst += stride; + LD_UB2(temp_dst, 16, dst6, dst7); + temp_dst += stride; + LD_SH4(coeffs, 16, in0, in2, in4, in6); + LD_SH4((coeffs + 8), 16, in1, in3, in5, in7); + coeffs += 64; + + for (loop_cnt = 14; loop_cnt--;) { + UNPCK_UB_SH(dst4, dst_r0, dst_l0); + UNPCK_UB_SH(dst5, dst_r1, dst_l1); + UNPCK_UB_SH(dst6, dst_r2, dst_l2); + UNPCK_UB_SH(dst7, dst_r3, dst_l3); dst_r0 += in0; dst_l0 += in1; @@ -819,40 +865,77 @@ static void hevc_addblk_32x32_msa(int16_t *coeffs, uint8_t *dst, int32_t stride) dst_r3 += in6; dst_l3 += in7; + /* Pre-load for next iteration */ + LD_UB2(temp_dst, 16, dst4, dst5); + temp_dst += stride; + LD_UB2(temp_dst, 16, dst6, dst7); + temp_dst += stride; + LD_SH4(coeffs, 16, in0, in2, in4, in6); + LD_SH4((coeffs + 8), 16, in1, in3, in5, in7); + coeffs += 64; + CLIP_SH4_0_255(dst_r0, dst_l0, dst_r1, dst_l1); CLIP_SH4_0_255(dst_r2, dst_l2, dst_r3, dst_l3); PCKEV_B4_UB(dst_l0, dst_r0, dst_l1, dst_r1, dst_l2, dst_r2, dst_l3, dst_r3, dst0, dst1, dst2, dst3); - ST_UB4(dst0, dst1, dst2, dst3, dst, stride); - - LD_SH4((coeffs + 16), 32, in0, in2, in4, in6); - LD_SH4((coeffs + 24), 32, in1, in3, in5, in7); - coeffs += 128; - LD_UB4((temp_dst + 16), stride, dst0, dst1, dst2, dst3); - temp_dst += (4 * stride); - - UNPCK_UB_SH(dst0, dst_r0, dst_l0); - UNPCK_UB_SH(dst1, dst_r1, dst_l1); - UNPCK_UB_SH(dst2, dst_r2, dst_l2); - UNPCK_UB_SH(dst3, dst_r3, dst_l3); + ST_UB2(dst0, dst1, dst, 16); + dst += stride; + ST_UB2(dst2, dst3, dst, 16); + dst += stride; + } - dst_r0 += in0; - dst_l0 += in1; - dst_r1 += in2; - dst_l1 += in3; - dst_r2 += in4; - dst_l2 += in5; - dst_r3 += in6; - dst_l3 += in7; + UNPCK_UB_SH(dst4, dst_r0, dst_l0); + UNPCK_UB_SH(dst5, dst_r1, dst_l1); + UNPCK_UB_SH(dst6, dst_r2, dst_l2); + UNPCK_UB_SH(dst7, dst_r3, dst_l3); + + dst_r0 += in0; + dst_l0 += in1; + dst_r1 += in2; + dst_l1 += in3; + dst_r2 += in4; + dst_l2 += in5; + dst_r3 += in6; + dst_l3 += in7; + + /* Pre-load for next iteration */ + LD_UB2(temp_dst, 16, dst4, dst5); + temp_dst += stride; + LD_UB2(temp_dst, 16, dst6, dst7); + temp_dst += stride; + LD_SH4(coeffs, 16, in0, in2, in4, in6); + LD_SH4((coeffs + 8), 16, in1, in3, in5, in7); - CLIP_SH4_0_255(dst_r0, dst_l0, dst_r1, dst_l1); - CLIP_SH4_0_255(dst_r2, dst_l2, dst_r3, dst_l3); - PCKEV_B4_UB(dst_l0, dst_r0, dst_l1, dst_r1, dst_l2, dst_r2, dst_l3, - dst_r3, dst0, dst1, dst2, dst3); + CLIP_SH4_0_255(dst_r0, dst_l0, dst_r1, dst_l1); + CLIP_SH4_0_255(dst_r2, dst_l2, dst_r3, dst_l3); + PCKEV_B4_UB(dst_l0, dst_r0, dst_l1, dst_r1, dst_l2, dst_r2, dst_l3, + dst_r3, dst0, dst1, dst2, dst3); + ST_UB2(dst0, dst1, dst, 16); + dst += stride; + ST_UB2(dst2, dst3, dst, 16); + dst += stride; + + UNPCK_UB_SH(dst4, dst_r0, dst_l0); + UNPCK_UB_SH(dst5, dst_r1, dst_l1); + UNPCK_UB_SH(dst6, dst_r2, dst_l2); + UNPCK_UB_SH(dst7, dst_r3, dst_l3); + + dst_r0 += in0; + dst_l0 += in1; + dst_r1 += in2; + dst_l1 += in3; + dst_r2 += in4; + dst_l2 += in5; + dst_r3 += in6; + dst_l3 += in7; - ST_UB4(dst0, dst1, dst2, dst3, (dst + 16), stride); - dst += (4 * stride); - } + CLIP_SH4_0_255(dst_r0, dst_l0, dst_r1, dst_l1); + CLIP_SH4_0_255(dst_r2, dst_l2, dst_r3, dst_l3); + PCKEV_B4_UB(dst_l0, dst_r0, dst_l1, dst_r1, dst_l2, dst_r2, dst_l3, + dst_r3, dst0, dst1, dst2, dst3); + ST_UB2(dst0, dst1, dst, 16); + dst += stride; + ST_UB2(dst2, dst3, dst, 16); } static void hevc_idct_luma_4x4_msa(int16_t *coeffs) @@ -868,8 +951,12 @@ static void hevc_idct_luma_4x4_msa(int16_t *coeffs) TRANSPOSE4x4_SW_SW(res0, res1, res2, res3, in_r0, in_l0, in_r1, in_l1); HEVC_IDCT_LUMA4x4_COL(in_r0, in_l0, in_r1, in_l1, res0, res1, res2, res3, 12); - TRANSPOSE4x4_SW_SW(res0, res1, res2, res3, res0, res1, res2, res3); - PCKEV_H2_SH(res1, res0, res3, res2, dst0, dst1); + + /* Pack and transpose */ + PCKEV_H2_SH(res2, res0, res3, res1, dst0, dst1); + ILVRL_H2_SW(dst1, dst0, res0, res1); + ILVRL_W2_SH(res1, res0, dst0, dst1); + ST_SH2(dst0, dst1, coeffs, 8); } From eea64ef4cfb593cbe28465f45e6bd4c41a79cae1 Mon Sep 17 00:00:00 2001 From: Thierry Foucu Date: Tue, 12 Sep 2017 18:45:57 -0700 Subject: [PATCH 3083/3374] vf_fps: when reading EOF, using current_pts to duplicate the last frame if needed. Fix ticket #2674 Tested with examples from ticket 2674. Signed-off-by: Michael Niedermayer --- libavfilter/vf_fps.c | 44 ++++++++++++++++++++++++++++---- tests/ref/fate/filter-fps | 6 +++++ tests/ref/fate/filter-fps-r | 4 +++ tests/ref/fate/filter-mpdecimate | 1 - tests/ref/fate/m4v-cfr | 1 - 5 files changed, 49 insertions(+), 7 deletions(-) diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c index 20ccd797d10d3..09fc66a73c201 100644 --- a/libavfilter/vf_fps.c +++ b/libavfilter/vf_fps.c @@ -34,6 +34,8 @@ #include "libavutil/opt.h" #include "libavutil/parseutils.h" +#define FF_INTERNAL_FIELDS 1 +#include "framequeue.h" #include "avfilter.h" #include "internal.h" #include "video.h" @@ -137,13 +139,45 @@ static int request_frame(AVFilterLink *outlink) AVFrame *buf; av_fifo_generic_read(s->fifo, &buf, sizeof(buf), NULL); - buf->pts = av_rescale_q(s->first_pts, ctx->inputs[0]->time_base, - outlink->time_base) + s->frames_out; + if (av_fifo_size(s->fifo)) { + buf->pts = av_rescale_q(s->first_pts, ctx->inputs[0]->time_base, + outlink->time_base) + s->frames_out; - if ((ret = ff_filter_frame(outlink, buf)) < 0) - return ret; + if ((ret = ff_filter_frame(outlink, buf)) < 0) + return ret; - s->frames_out++; + s->frames_out++; + } else { + /* This is the last frame, we may have to duplicate it to match + * the last frame duration */ + int j; + int delta = av_rescale_q_rnd(ctx->inputs[0]->current_pts - s->first_pts, + ctx->inputs[0]->time_base, + outlink->time_base, s->rounding) - s->frames_out ; + /* if the delta is equal to 1, it means we just need to output + * the last frame. Greater than 1 means we will need duplicate + * delta-1 frames */ + if (delta > 0 ) { + for (j = 0; j < delta; j++) { + AVFrame *dup = av_frame_clone(buf); + + av_log(ctx, AV_LOG_DEBUG, "Duplicating frame.\n"); + dup->pts = av_rescale_q(s->first_pts, ctx->inputs[0]->time_base, + outlink->time_base) + s->frames_out; + + if ((ret = ff_filter_frame(outlink, dup)) < 0) + return ret; + + s->frames_out++; + if (j > 0) s->dup++; + } + } else { + /* for delta less or equal to 0, we should drop the frame, + * otherwise, we will have one or more extra frames */ + av_frame_free(&buf); + s->drop++; + } + } } return 0; } diff --git a/tests/ref/fate/filter-fps b/tests/ref/fate/filter-fps index 55712cfb1cff3..242fb04e85d46 100644 --- a/tests/ref/fate/filter-fps +++ b/tests/ref/fate/filter-fps @@ -85,3 +85,9 @@ 0, 79, 79, 1, 30576, 0xa2fcd06f 0, 80, 80, 1, 30576, 0xa2fcd06f 0, 81, 81, 1, 30576, 0xd4150aad +0, 82, 82, 1, 30576, 0xd4150aad +0, 83, 83, 1, 30576, 0xd4150aad +0, 84, 84, 1, 30576, 0xd4150aad +0, 85, 85, 1, 30576, 0xd4150aad +0, 86, 86, 1, 30576, 0xd4150aad +0, 87, 87, 1, 30576, 0xd4150aad diff --git a/tests/ref/fate/filter-fps-r b/tests/ref/fate/filter-fps-r index 826b1ed6c64c9..c1bc7d15479eb 100644 --- a/tests/ref/fate/filter-fps-r +++ b/tests/ref/fate/filter-fps-r @@ -72,3 +72,7 @@ 0, 79, 79, 1, 30576, 0xa2fcd06f 0, 80, 80, 1, 30576, 0xa2fcd06f 0, 82, 82, 1, 30576, 0xd4150aad +0, 83, 83, 1, 30576, 0xd4150aad +0, 84, 84, 1, 30576, 0xd4150aad +0, 85, 85, 1, 30576, 0xd4150aad +0, 86, 86, 1, 30576, 0xd4150aad diff --git a/tests/ref/fate/filter-mpdecimate b/tests/ref/fate/filter-mpdecimate index d438dacc2ee72..9c1dc3656264b 100644 --- a/tests/ref/fate/filter-mpdecimate +++ b/tests/ref/fate/filter-mpdecimate @@ -22,4 +22,3 @@ 0, 24, 24, 1, 115200, 0x056d40ca 0, 26, 26, 1, 115200, 0xa4374737 0, 27, 27, 1, 115200, 0x3eaa3ae8 -0, 29, 29, 1, 115200, 0x7551e9ee diff --git a/tests/ref/fate/m4v-cfr b/tests/ref/fate/m4v-cfr index 4eee84d01b953..e2d02032feb16 100644 --- a/tests/ref/fate/m4v-cfr +++ b/tests/ref/fate/m4v-cfr @@ -44,4 +44,3 @@ 0, 38, 38, 1, 115200, 0xf30825d5 0, 39, 39, 1, 115200, 0xe3c944a1 0, 40, 40, 1, 115200, 0x8fec4420 -0, 41, 41, 1, 115200, 0x9381fdab From e2f8f14052d99d7710cda0a821e236765b315d0b Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Thu, 20 Jul 2017 13:46:46 +0200 Subject: [PATCH 3084/3374] lavf/http: Reset compressed header flag, fix http 302 request Fixes ticket #6404. Fixes ticket #6666. Signed-off-by: Jacek Jendrzej --- libavformat/http.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/http.c b/libavformat/http.c index 30890bb7aa03a..f25977ab1f70d 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -1248,6 +1248,7 @@ static int http_connect(URLContext *h, const char *path, const char *local_path, s->willclose = 0; s->end_chunked_post = 0; s->end_header = 0; + s->compressed = 0; if (post && !s->post_data && !send_expect_100) { /* Pretend that it did work. We didn't read any header yet, since * we've still to send the POST data, but the code calling this From dd8ffb191fd24f5b783b9722f63019120d61c48c Mon Sep 17 00:00:00 2001 From: Matthieu Bouron Date: Fri, 15 Sep 2017 13:45:47 +0200 Subject: [PATCH 3085/3374] lavc/mediacodec_wrapper: fix jni vaargs types Fixes decoding on 32-bit devices with Android NDK >= 15. --- libavcodec/mediacodec_wrapper.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavcodec/mediacodec_wrapper.c b/libavcodec/mediacodec_wrapper.c index 4a37cd7cd7a72..f34450a6d8fd1 100644 --- a/libavcodec/mediacodec_wrapper.c +++ b/libavcodec/mediacodec_wrapper.c @@ -1448,7 +1448,7 @@ int ff_AMediaCodec_releaseOutputBuffer(FFAMediaCodec* codec, size_t idx, int ren JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL); - (*env)->CallVoidMethod(env, codec->object, codec->jfields.release_output_buffer_id, idx, render); + (*env)->CallVoidMethod(env, codec->object, codec->jfields.release_output_buffer_id, (jint)idx, (jboolean)render); if (ff_jni_exception_check(env, 1, codec) < 0) { ret = AVERROR_EXTERNAL; goto fail; @@ -1465,7 +1465,7 @@ int ff_AMediaCodec_releaseOutputBufferAtTime(FFAMediaCodec *codec, size_t idx, i JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL); - (*env)->CallVoidMethod(env, codec->object, codec->jfields.release_output_buffer_at_time_id, idx, timestampNs); + (*env)->CallVoidMethod(env, codec->object, codec->jfields.release_output_buffer_at_time_id, (jint)idx, timestampNs); if (ff_jni_exception_check(env, 1, codec) < 0) { ret = AVERROR_EXTERNAL; goto fail; @@ -1499,7 +1499,7 @@ int ff_AMediaCodec_queueInputBuffer(FFAMediaCodec* codec, size_t idx, off_t offs JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL); - (*env)->CallVoidMethod(env, codec->object, codec->jfields.queue_input_buffer_id, idx, offset, size, time, flags); + (*env)->CallVoidMethod(env, codec->object, codec->jfields.queue_input_buffer_id, (jint)idx, (jint)offset, (jint)size, time, flags); if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) { ret = AVERROR_EXTERNAL; goto fail; @@ -1572,7 +1572,7 @@ uint8_t* ff_AMediaCodec_getInputBuffer(FFAMediaCodec* codec, size_t idx, size_t JNI_GET_ENV_OR_RETURN(env, codec, NULL); if (codec->has_get_i_o_buffer) { - buffer = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_input_buffer_id, idx); + buffer = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_input_buffer_id, (jint)idx); if (ff_jni_exception_check(env, 1, codec) < 0) { goto fail; } @@ -1620,7 +1620,7 @@ uint8_t* ff_AMediaCodec_getOutputBuffer(FFAMediaCodec* codec, size_t idx, size_t JNI_GET_ENV_OR_RETURN(env, codec, NULL); if (codec->has_get_i_o_buffer) { - buffer = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_output_buffer_id, idx); + buffer = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_output_buffer_id, (jint)idx); if (ff_jni_exception_check(env, 1, codec) < 0) { goto fail; } From 1a08285f05c9b9cc8941bd5bb59400fdceb5bafa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Fri, 15 Sep 2017 14:27:36 +0200 Subject: [PATCH 3086/3374] build: fix coreimage filters dependency to AppKit framework AppKit is not present on iOS. --- configure | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/configure b/configure index 78670c41aeb14..2de20a02a4a52 100755 --- a/configure +++ b/configure @@ -202,6 +202,7 @@ External library support: themselves, not all their features will necessarily be usable by FFmpeg. --disable-alsa disable ALSA support [autodetect] + --disable-appkit disable Apple AppKit framework [autodetect] --disable-avfoundation disable Apple AVFoundation framework [autodetect] --enable-avisynth enable reading of AviSynth script files [no] --disable-bzlib disable bzlib [autodetect] @@ -1503,6 +1504,7 @@ EXAMPLE_LIST=" EXTERNAL_AUTODETECT_LIBRARY_LIST=" alsa + appkit avfoundation bzlib coreimage @@ -3136,10 +3138,10 @@ blackframe_filter_deps="gpl" boxblur_filter_deps="gpl" bs2b_filter_deps="libbs2b" colormatrix_filter_deps="gpl" -coreimage_filter_deps="coreimage" -coreimage_filter_extralibs="-framework OpenGL -framework AppKit" -coreimagesrc_filter_deps="coreimage" -coreimagesrc_filter_extralibs="-framework OpenGL -framework AppKit" +coreimage_filter_deps="coreimage appkit" +coreimage_filter_extralibs="-framework OpenGL" +coreimagesrc_filter_deps="coreimage appkit" +coreimagesrc_filter_extralibs="-framework OpenGL" cover_rect_filter_deps="avcodec avformat gpl" cropdetect_filter_deps="gpl" deinterlace_qsv_filter_deps="libmfx" @@ -5763,6 +5765,7 @@ check_lib shell32 "windows.h shellapi.h" CommandLineToArgvW -lshell32 check_lib wincrypt "windows.h wincrypt.h" CryptGenRandom -ladvapi32 check_lib psapi "windows.h psapi.h" GetProcessMemoryInfo -lpsapi +enabled appkit && check_apple_framework AppKit enabled audiotoolbox && check_apple_framework AudioToolbox enabled avfoundation && check_apple_framework AVFoundation enabled coreimage && check_apple_framework CoreImage From 6743351558001764d662bb52b9a3e0bbb63366d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Fri, 15 Sep 2017 15:09:54 +0200 Subject: [PATCH 3087/3374] lavf/http: fix compilation without zlib Regression since e2f8f14052d99d7710cda0a821e236765b315d0b. --- libavformat/http.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavformat/http.c b/libavformat/http.c index f25977ab1f70d..668cd51986680 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -1248,7 +1248,9 @@ static int http_connect(URLContext *h, const char *path, const char *local_path, s->willclose = 0; s->end_chunked_post = 0; s->end_header = 0; +#if CONFIG_ZLIB s->compressed = 0; +#endif if (post && !s->post_data && !send_expect_100) { /* Pretend that it did work. We didn't read any header yet, since * we've still to send the POST data, but the code calling this From e5a650e14154aa57d64a86837c247609909d2951 Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Fri, 15 Sep 2017 11:28:23 +0530 Subject: [PATCH 3088/3374] avcodec/mips: Improve avc lpf msa functions Optimize luma intra case by reducing conditional cases. Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/h264dsp_msa.c | 428 +++++++++++----------------------- 1 file changed, 138 insertions(+), 290 deletions(-) diff --git a/libavcodec/mips/h264dsp_msa.c b/libavcodec/mips/h264dsp_msa.c index 16e4858e6b532..a17eacb98ac74 100644 --- a/libavcodec/mips/h264dsp_msa.c +++ b/libavcodec/mips/h264dsp_msa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Parag Salasakar (Parag.Salasakar@imgtec.com) + * Copyright (c) 2015 - 2017 Parag Salasakar (Parag.Salasakar@imgtec.com) * * This file is part of FFmpeg. * @@ -644,96 +644,69 @@ static void avc_loopfilter_luma_intra_edge_hor_msa(uint8_t *data, uint8_t beta_in, uint32_t img_width) { - v16u8 p2_asub_p0, q2_asub_q0, p0_asub_q0; - v16u8 alpha, beta; - v16u8 is_less_than, is_less_than_beta, negate_is_less_than_beta; - v16u8 p2, p1, p0, q0, q1, q2; - v16u8 p3_org, p2_org, p1_org, p0_org, q0_org, q1_org, q2_org, q3_org; - v8i16 p1_org_r, p0_org_r, q0_org_r, q1_org_r; - v8i16 p1_org_l, p0_org_l, q0_org_l, q1_org_l; - v8i16 p2_r = { 0 }; - v8i16 p1_r = { 0 }; - v8i16 p0_r = { 0 }; - v8i16 q0_r = { 0 }; - v8i16 q1_r = { 0 }; - v8i16 q2_r = { 0 }; - v8i16 p2_l = { 0 }; - v8i16 p1_l = { 0 }; - v8i16 p0_l = { 0 }; - v8i16 q0_l = { 0 }; - v8i16 q1_l = { 0 }; - v8i16 q2_l = { 0 }; - v16u8 tmp_flag; - v16i8 zero = { 0 }; - - alpha = (v16u8) __msa_fill_b(alpha_in); - beta = (v16u8) __msa_fill_b(beta_in); + v16u8 p0_asub_q0, p1_asub_p0, q1_asub_q0; + v16u8 is_less_than, is_less_than_beta, is_less_than_alpha; + v16u8 p1_org, p0_org, q0_org, q1_org; LD_UB4(data - (img_width << 1), img_width, p1_org, p0_org, q0_org, q1_org); - { - v16u8 p1_asub_p0, q1_asub_q0, is_less_than_alpha; - - p0_asub_q0 = __msa_asub_u_b(p0_org, q0_org); - p1_asub_p0 = __msa_asub_u_b(p1_org, p0_org); - q1_asub_q0 = __msa_asub_u_b(q1_org, q0_org); + p0_asub_q0 = __msa_asub_u_b(p0_org, q0_org); + p1_asub_p0 = __msa_asub_u_b(p1_org, p0_org); + q1_asub_q0 = __msa_asub_u_b(q1_org, q0_org); - is_less_than_alpha = (p0_asub_q0 < alpha); - is_less_than_beta = (p1_asub_p0 < beta); - is_less_than = is_less_than_beta & is_less_than_alpha; - is_less_than_beta = (q1_asub_q0 < beta); - is_less_than = is_less_than_beta & is_less_than; - } + is_less_than_alpha = (p0_asub_q0 < alpha_in); + is_less_than_beta = (p1_asub_p0 < beta_in); + is_less_than = is_less_than_beta & is_less_than_alpha; + is_less_than_beta = (q1_asub_q0 < beta_in); + is_less_than = is_less_than_beta & is_less_than; if (!__msa_test_bz_v(is_less_than)) { - q2_org = LD_UB(data + (2 * img_width)); - p3_org = LD_UB(data - (img_width << 2)); - p2_org = LD_UB(data - (3 * img_width)); + v16u8 p2_asub_p0, q2_asub_q0, p0, q0, negate_is_less_than_beta; + v8i16 p0_r = { 0 }; + v8i16 q0_r = { 0 }; + v8i16 p0_l = { 0 }; + v8i16 q0_l = { 0 }; + v16i8 zero = { 0 }; + v8i16 p1_org_r, p0_org_r, q0_org_r, q1_org_r; + v8i16 p1_org_l, p0_org_l, q0_org_l, q1_org_l; + v16u8 q2_org = LD_UB(data + (2 * img_width)); + v16u8 p2_org = LD_UB(data - (3 * img_width)); + v16u8 tmp_flag = (v16u8)__msa_fill_b((alpha_in >> 2) + 2); UNPCK_UB_SH(p1_org, p1_org_r, p1_org_l); UNPCK_UB_SH(p0_org, p0_org_r, p0_org_l); UNPCK_UB_SH(q0_org, q0_org_r, q0_org_l); - tmp_flag = alpha >> 2; - tmp_flag = tmp_flag + 2; tmp_flag = (p0_asub_q0 < tmp_flag); p2_asub_p0 = __msa_asub_u_b(p2_org, p0_org); - is_less_than_beta = (p2_asub_p0 < beta); + is_less_than_beta = (p2_asub_p0 < beta_in); is_less_than_beta = is_less_than_beta & tmp_flag; negate_is_less_than_beta = __msa_xori_b(is_less_than_beta, 0xff); is_less_than_beta = is_less_than_beta & is_less_than; negate_is_less_than_beta = negate_is_less_than_beta & is_less_than; - { - v8u16 is_less_than_beta_l, is_less_than_beta_r; - - q1_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) q1_org); - - is_less_than_beta_r = - (v8u16) __msa_sldi_b((v16i8) is_less_than_beta, zero, 8); - if (!__msa_test_bz_v((v16u8) is_less_than_beta_r)) { - v8i16 p3_org_r; - - ILVR_B2_SH(zero, p3_org, zero, p2_org, p3_org_r, p2_r); - AVC_LPF_P0P1P2_OR_Q0Q1Q2(p3_org_r, p0_org_r, q0_org_r, p1_org_r, - p2_r, q1_org_r, p0_r, p1_r, p2_r); - } - - q1_org_l = (v8i16) __msa_ilvl_b(zero, (v16i8) q1_org); - is_less_than_beta_l = - (v8u16) __msa_sldi_b(zero, (v16i8) is_less_than_beta, 8); + q1_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) q1_org); + q1_org_l = (v8i16) __msa_ilvl_b(zero, (v16i8) q1_org); - if (!__msa_test_bz_v((v16u8) is_less_than_beta_l)) { - v8i16 p3_org_l; - - ILVL_B2_SH(zero, p3_org, zero, p2_org, p3_org_l, p2_l); - AVC_LPF_P0P1P2_OR_Q0Q1Q2(p3_org_l, p0_org_l, q0_org_l, p1_org_l, - p2_l, q1_org_l, p0_l, p1_l, p2_l); - } - } /* combine and store */ if (!__msa_test_bz_v(is_less_than_beta)) { + v8i16 p3_org_l, p3_org_r; + v16u8 p3_org = LD_UB(data - (img_width << 2)); + v16u8 p2, p1; + v8i16 p2_r = { 0 }; + v8i16 p2_l = { 0 }; + v8i16 p1_r = { 0 }; + v8i16 p1_l = { 0 }; + + ILVR_B2_SH(zero, p3_org, zero, p2_org, p3_org_r, p2_r); + AVC_LPF_P0P1P2_OR_Q0Q1Q2(p3_org_r, p0_org_r, q0_org_r, p1_org_r, + p2_r, q1_org_r, p0_r, p1_r, p2_r); + + ILVL_B2_SH(zero, p3_org, zero, p2_org, p3_org_l, p2_l); + AVC_LPF_P0P1P2_OR_Q0Q1Q2(p3_org_l, p0_org_l, q0_org_l, p1_org_l, + p2_l, q1_org_l, p0_l, p1_l, p2_l); + PCKEV_B3_UB(p0_l, p0_r, p1_l, p1_r, p2_l, p2_r, p0, p1, p2); p0_org = __msa_bmnz_v(p0_org, p0, is_less_than_beta); @@ -743,62 +716,42 @@ static void avc_loopfilter_luma_intra_edge_hor_msa(uint8_t *data, ST_UB(p1_org, data - (2 * img_width)); ST_UB(p2_org, data - (3 * img_width)); } - { - v8u16 negate_is_less_than_beta_r, negate_is_less_than_beta_l; - negate_is_less_than_beta_r = - (v8u16) __msa_sldi_b((v16i8) negate_is_less_than_beta, zero, 8); - if (!__msa_test_bz_v((v16u8) negate_is_less_than_beta_r)) { - AVC_LPF_P0_OR_Q0(p0_org_r, q1_org_r, p1_org_r, p0_r); - } + AVC_LPF_P0_OR_Q0(p0_org_r, q1_org_r, p1_org_r, p0_r); + AVC_LPF_P0_OR_Q0(p0_org_l, q1_org_l, p1_org_l, p0_l); - negate_is_less_than_beta_l = - (v8u16) __msa_sldi_b(zero, (v16i8) negate_is_less_than_beta, 8); - if (!__msa_test_bz_v((v16u8) negate_is_less_than_beta_l)) { - AVC_LPF_P0_OR_Q0(p0_org_l, q1_org_l, p1_org_l, p0_l); - } - } /* combine */ - if (!__msa_test_bz_v(negate_is_less_than_beta)) { - p0 = (v16u8) __msa_pckev_b((v16i8) p0_l, (v16i8) p0_r); - p0_org = __msa_bmnz_v(p0_org, p0, negate_is_less_than_beta); - } + p0 = (v16u8) __msa_pckev_b((v16i8) p0_l, (v16i8) p0_r); + p0_org = __msa_bmnz_v(p0_org, p0, negate_is_less_than_beta); ST_UB(p0_org, data - img_width); /* if (tmpFlag && (unsigned)ABS(q2-q0) < thresholds->beta_in) */ - q3_org = LD_UB(data + (3 * img_width)); q2_asub_q0 = __msa_asub_u_b(q2_org, q0_org); - is_less_than_beta = (q2_asub_q0 < beta); + is_less_than_beta = (q2_asub_q0 < beta_in); is_less_than_beta = is_less_than_beta & tmp_flag; negate_is_less_than_beta = __msa_xori_b(is_less_than_beta, 0xff); is_less_than_beta = is_less_than_beta & is_less_than; negate_is_less_than_beta = negate_is_less_than_beta & is_less_than; - { - v8u16 is_less_than_beta_l, is_less_than_beta_r; - is_less_than_beta_r = - (v8u16) __msa_sldi_b((v16i8) is_less_than_beta, zero, 8); - if (!__msa_test_bz_v((v16u8) is_less_than_beta_r)) { - v8i16 q3_org_r; - - ILVR_B2_SH(zero, q3_org, zero, q2_org, q3_org_r, q2_r); - AVC_LPF_P0P1P2_OR_Q0Q1Q2(q3_org_r, q0_org_r, p0_org_r, q1_org_r, - q2_r, p1_org_r, q0_r, q1_r, q2_r); - } - is_less_than_beta_l = - (v8u16) __msa_sldi_b(zero, (v16i8) is_less_than_beta, 8); - if (!__msa_test_bz_v((v16u8) is_less_than_beta_l)) { - v8i16 q3_org_l; - - ILVL_B2_SH(zero, q3_org, zero, q2_org, q3_org_l, q2_l); - AVC_LPF_P0P1P2_OR_Q0Q1Q2(q3_org_l, q0_org_l, p0_org_l, q1_org_l, - q2_l, p1_org_l, q0_l, q1_l, q2_l); - } - } - /* combine and store */ if (!__msa_test_bz_v(is_less_than_beta)) { + v8i16 q3_org_r, q3_org_l; + v16u8 q3_org = LD_UB(data + (3 * img_width)); + v16u8 q1, q2; + v8i16 q2_r = { 0 }; + v8i16 q2_l = { 0 }; + v8i16 q1_r = { 0 }; + v8i16 q1_l = { 0 }; + + ILVR_B2_SH(zero, q3_org, zero, q2_org, q3_org_r, q2_r); + AVC_LPF_P0P1P2_OR_Q0Q1Q2(q3_org_r, q0_org_r, p0_org_r, q1_org_r, + q2_r, p1_org_r, q0_r, q1_r, q2_r); + + ILVL_B2_SH(zero, q3_org, zero, q2_org, q3_org_l, q2_l); + AVC_LPF_P0P1P2_OR_Q0Q1Q2(q3_org_l, q0_org_l, p0_org_l, q1_org_l, + q2_l, p1_org_l, q0_l, q1_l, q2_l); + PCKEV_B3_UB(q0_l, q0_r, q1_l, q1_r, q2_l, q2_r, q0, q1, q2); q0_org = __msa_bmnz_v(q0_org, q0, is_less_than_beta); q1_org = __msa_bmnz_v(q1_org, q1, is_less_than_beta); @@ -807,25 +760,14 @@ static void avc_loopfilter_luma_intra_edge_hor_msa(uint8_t *data, ST_UB(q1_org, data + img_width); ST_UB(q2_org, data + 2 * img_width); } - { - v8u16 negate_is_less_than_beta_r, negate_is_less_than_beta_l; - negate_is_less_than_beta_r = - (v8u16) __msa_sldi_b((v16i8) negate_is_less_than_beta, zero, 8); - if (!__msa_test_bz_v((v16u8) negate_is_less_than_beta_r)) { - AVC_LPF_P0_OR_Q0(q0_org_r, p1_org_r, q1_org_r, q0_r); - } - negate_is_less_than_beta_l = - (v8u16) __msa_sldi_b(zero, (v16i8) negate_is_less_than_beta, 8); - if (!__msa_test_bz_v((v16u8) negate_is_less_than_beta_l)) { - AVC_LPF_P0_OR_Q0(q0_org_l, p1_org_l, q1_org_l, q0_l); - } - } + AVC_LPF_P0_OR_Q0(q0_org_r, p1_org_r, q1_org_r, q0_r); + AVC_LPF_P0_OR_Q0(q0_org_l, p1_org_l, q1_org_l, q0_l); + /* combine */ - if (!__msa_test_bz_v(negate_is_less_than_beta)) { - q0 = (v16u8) __msa_pckev_b((v16i8) q0_l, (v16i8) q0_r); - q0_org = __msa_bmnz_v(q0_org, q0, negate_is_less_than_beta); - } + q0 = (v16u8) __msa_pckev_b((v16i8) q0_l, (v16i8) q0_r); + q0_org = __msa_bmnz_v(q0_org, q0, negate_is_less_than_beta); + ST_UB(q0_org, data); } } @@ -835,29 +777,13 @@ static void avc_loopfilter_luma_intra_edge_ver_msa(uint8_t *data, uint8_t beta_in, uint32_t img_width) { - uint8_t *src; + uint8_t *src = data - 4; v16u8 alpha, beta, p0_asub_q0; - v16u8 is_less_than_alpha, is_less_than; - v16u8 is_less_than_beta, negate_is_less_than_beta; + v16u8 is_less_than_alpha, is_less_than, is_less_than_beta; v16u8 p3_org, p2_org, p1_org, p0_org, q0_org, q1_org, q2_org, q3_org; - v8i16 p1_org_r, p0_org_r, q0_org_r, q1_org_r; - v8i16 p1_org_l, p0_org_l, q0_org_l, q1_org_l; - v8i16 p2_r = { 0 }; - v8i16 p1_r = { 0 }; - v8i16 p0_r = { 0 }; - v8i16 q0_r = { 0 }; - v8i16 q1_r = { 0 }; - v8i16 q2_r = { 0 }; - v8i16 p2_l = { 0 }; - v8i16 p1_l = { 0 }; - v8i16 p0_l = { 0 }; - v8i16 q0_l = { 0 }; - v8i16 q1_l = { 0 }; - v8i16 q2_l = { 0 }; - v16i8 zero = { 0 }; - v16u8 tmp_flag; + v16u8 p1_asub_p0, q1_asub_q0; + - src = data - 4; { v16u8 row0, row1, row2, row3, row4, row5, row6, row7; v16u8 row8, row9, row10, row11, row12, row13, row14, row15; @@ -873,119 +799,77 @@ static void avc_loopfilter_luma_intra_edge_ver_msa(uint8_t *data, p3_org, p2_org, p1_org, p0_org, q0_org, q1_org, q2_org, q3_org); } - UNPCK_UB_SH(p1_org, p1_org_r, p1_org_l); - UNPCK_UB_SH(p0_org, p0_org_r, p0_org_l); - UNPCK_UB_SH(q0_org, q0_org_r, q0_org_l); - UNPCK_UB_SH(q1_org, q1_org_r, q1_org_l); - - /* if ( ((unsigned)ABS(p0-q0) < thresholds->alpha_in) && - ((unsigned)ABS(p1-p0) < thresholds->beta_in) && - ((unsigned)ABS(q1-q0) < thresholds->beta_in) ) */ - { - v16u8 p1_asub_p0, q1_asub_q0; - p0_asub_q0 = __msa_asub_u_b(p0_org, q0_org); - p1_asub_p0 = __msa_asub_u_b(p1_org, p0_org); - q1_asub_q0 = __msa_asub_u_b(q1_org, q0_org); + p0_asub_q0 = __msa_asub_u_b(p0_org, q0_org); + p1_asub_p0 = __msa_asub_u_b(p1_org, p0_org); + q1_asub_q0 = __msa_asub_u_b(q1_org, q0_org); - alpha = (v16u8) __msa_fill_b(alpha_in); - beta = (v16u8) __msa_fill_b(beta_in); + alpha = (v16u8) __msa_fill_b(alpha_in); + beta = (v16u8) __msa_fill_b(beta_in); - is_less_than_alpha = (p0_asub_q0 < alpha); - is_less_than_beta = (p1_asub_p0 < beta); - is_less_than = is_less_than_beta & is_less_than_alpha; - is_less_than_beta = (q1_asub_q0 < beta); - is_less_than = is_less_than_beta & is_less_than; - } + is_less_than_alpha = (p0_asub_q0 < alpha); + is_less_than_beta = (p1_asub_p0 < beta); + is_less_than = is_less_than_beta & is_less_than_alpha; + is_less_than_beta = (q1_asub_q0 < beta); + is_less_than = is_less_than_beta & is_less_than; if (!__msa_test_bz_v(is_less_than)) { + v8i16 p0_r = { 0 }; + v8i16 q0_r = { 0 }; + v8i16 p0_l = { 0 }; + v8i16 q0_l = { 0 }; + v16i8 zero = { 0 }; + v16u8 tmp_flag, p0, q0, p2_asub_p0, q2_asub_q0; + v16u8 negate_is_less_than_beta; + v8i16 p1_org_r, p0_org_r, q0_org_r, q1_org_r; + v8i16 p1_org_l, p0_org_l, q0_org_l, q1_org_l; + + UNPCK_UB_SH(p1_org, p1_org_r, p1_org_l); + UNPCK_UB_SH(p0_org, p0_org_r, p0_org_l); + UNPCK_UB_SH(q0_org, q0_org_r, q0_org_l); + UNPCK_UB_SH(q1_org, q1_org_r, q1_org_l); + tmp_flag = alpha >> 2; tmp_flag = tmp_flag + 2; tmp_flag = (p0_asub_q0 < tmp_flag); - { - v16u8 p2_asub_p0; - - p2_asub_p0 = __msa_asub_u_b(p2_org, p0_org); - is_less_than_beta = (p2_asub_p0 < beta); - } + p2_asub_p0 = __msa_asub_u_b(p2_org, p0_org); + is_less_than_beta = (p2_asub_p0 < beta); is_less_than_beta = tmp_flag & is_less_than_beta; negate_is_less_than_beta = __msa_xori_b(is_less_than_beta, 0xff); is_less_than_beta = is_less_than_beta & is_less_than; negate_is_less_than_beta = negate_is_less_than_beta & is_less_than; - /* right */ - { - v16u8 is_less_than_beta_r; - - is_less_than_beta_r = - (v16u8) __msa_sldi_b((v16i8) is_less_than_beta, zero, 8); - if (!__msa_test_bz_v(is_less_than_beta_r)) { - v8i16 p3_org_r; - - ILVR_B2_SH(zero, p3_org, zero, p2_org, p3_org_r, p2_r); - AVC_LPF_P0P1P2_OR_Q0Q1Q2(p3_org_r, p0_org_r, q0_org_r, p1_org_r, - p2_r, q1_org_r, p0_r, p1_r, p2_r); - } - } - /* left */ - { - v16u8 is_less_than_beta_l; - - is_less_than_beta_l = - (v16u8) __msa_sldi_b(zero, (v16i8) is_less_than_beta, 8); - if (!__msa_test_bz_v(is_less_than_beta_l)) { - v8i16 p3_org_l; - - ILVL_B2_SH(zero, p3_org, zero, p2_org, p3_org_l, p2_l); - AVC_LPF_P0P1P2_OR_Q0Q1Q2(p3_org_l, p0_org_l, q0_org_l, p1_org_l, - p2_l, q1_org_l, p0_l, p1_l, p2_l); - } - } - /* combine and store */ if (!__msa_test_bz_v(is_less_than_beta)) { - v16u8 p0, p2, p1; + v16u8 p2, p1; + v8i16 p3_org_r, p3_org_l; + v8i16 p2_l = { 0 }; + v8i16 p2_r = { 0 }; + v8i16 p1_l = { 0 }; + v8i16 p1_r = { 0 }; + + ILVR_B2_SH(zero, p3_org, zero, p2_org, p3_org_r, p2_r); + AVC_LPF_P0P1P2_OR_Q0Q1Q2(p3_org_r, p0_org_r, q0_org_r, p1_org_r, + p2_r, q1_org_r, p0_r, p1_r, p2_r); + + ILVL_B2_SH(zero, p3_org, zero, p2_org, p3_org_l, p2_l); + AVC_LPF_P0P1P2_OR_Q0Q1Q2(p3_org_l, p0_org_l, q0_org_l, p1_org_l, + p2_l, q1_org_l, p0_l, p1_l, p2_l); PCKEV_B3_UB(p0_l, p0_r, p1_l, p1_r, p2_l, p2_r, p0, p1, p2); p0_org = __msa_bmnz_v(p0_org, p0, is_less_than_beta); p1_org = __msa_bmnz_v(p1_org, p1, is_less_than_beta); p2_org = __msa_bmnz_v(p2_org, p2, is_less_than_beta); } - /* right */ - { - v16u8 negate_is_less_than_beta_r; - - negate_is_less_than_beta_r = - (v16u8) __msa_sldi_b((v16i8) negate_is_less_than_beta, zero, 8); - - if (!__msa_test_bz_v(negate_is_less_than_beta_r)) { - AVC_LPF_P0_OR_Q0(p0_org_r, q1_org_r, p1_org_r, p0_r); - } - } - /* left */ - { - v16u8 negate_is_less_than_beta_l; - negate_is_less_than_beta_l = - (v16u8) __msa_sldi_b(zero, (v16i8) negate_is_less_than_beta, 8); - if (!__msa_test_bz_v(negate_is_less_than_beta_l)) { - AVC_LPF_P0_OR_Q0(p0_org_l, q1_org_l, p1_org_l, p0_l); - } - } + AVC_LPF_P0_OR_Q0(p0_org_r, q1_org_r, p1_org_r, p0_r); + AVC_LPF_P0_OR_Q0(p0_org_l, q1_org_l, p1_org_l, p0_l); - if (!__msa_test_bz_v(negate_is_less_than_beta)) { - v16u8 p0; + p0 = (v16u8) __msa_pckev_b((v16i8) p0_l, (v16i8) p0_r); + p0_org = __msa_bmnz_v(p0_org, p0, negate_is_less_than_beta); - p0 = (v16u8) __msa_pckev_b((v16i8) p0_l, (v16i8) p0_r); - p0_org = __msa_bmnz_v(p0_org, p0, negate_is_less_than_beta); - } - - { - v16u8 q2_asub_q0; - - q2_asub_q0 = __msa_asub_u_b(q2_org, q0_org); - is_less_than_beta = (q2_asub_q0 < beta); - } + q2_asub_q0 = __msa_asub_u_b(q2_org, q0_org); + is_less_than_beta = (q2_asub_q0 < beta); is_less_than_beta = is_less_than_beta & tmp_flag; negate_is_less_than_beta = __msa_xori_b(is_less_than_beta, 0xff); @@ -993,37 +877,21 @@ static void avc_loopfilter_luma_intra_edge_ver_msa(uint8_t *data, is_less_than_beta = is_less_than_beta & is_less_than; negate_is_less_than_beta = negate_is_less_than_beta & is_less_than; - /* right */ - { - v16u8 is_less_than_beta_r; - - is_less_than_beta_r = - (v16u8) __msa_sldi_b((v16i8) is_less_than_beta, zero, 8); - if (!__msa_test_bz_v(is_less_than_beta_r)) { - v8i16 q3_org_r; - - ILVR_B2_SH(zero, q3_org, zero, q2_org, q3_org_r, q2_r); - AVC_LPF_P0P1P2_OR_Q0Q1Q2(q3_org_r, q0_org_r, p0_org_r, q1_org_r, - q2_r, p1_org_r, q0_r, q1_r, q2_r); - } - } - /* left */ - { - v16u8 is_less_than_beta_l; + if (!__msa_test_bz_v(is_less_than_beta)) { + v16u8 q1, q2; + v8i16 q3_org_r, q3_org_l; + v8i16 q1_l = { 0 }; + v8i16 q1_r = { 0 }; + v8i16 q2_l = { 0 }; + v8i16 q2_r = { 0 }; - is_less_than_beta_l = - (v16u8) __msa_sldi_b(zero, (v16i8) is_less_than_beta, 8); - if (!__msa_test_bz_v(is_less_than_beta_l)) { - v8i16 q3_org_l; + ILVR_B2_SH(zero, q3_org, zero, q2_org, q3_org_r, q2_r); + AVC_LPF_P0P1P2_OR_Q0Q1Q2(q3_org_r, q0_org_r, p0_org_r, q1_org_r, + q2_r, p1_org_r, q0_r, q1_r, q2_r); - ILVL_B2_SH(zero, q3_org, zero, q2_org, q3_org_l, q2_l); - AVC_LPF_P0P1P2_OR_Q0Q1Q2(q3_org_l, q0_org_l, p0_org_l, q1_org_l, - q2_l, p1_org_l, q0_l, q1_l, q2_l); - } - } - /* combine and store */ - if (!__msa_test_bz_v(is_less_than_beta)) { - v16u8 q0, q1, q2; + ILVL_B2_SH(zero, q3_org, zero, q2_org, q3_org_l, q2_l); + AVC_LPF_P0P1P2_OR_Q0Q1Q2(q3_org_l, q0_org_l, p0_org_l, q1_org_l, + q2_l, p1_org_l, q0_l, q1_l, q2_l); PCKEV_B3_UB(q0_l, q0_r, q1_l, q1_r, q2_l, q2_r, q0, q1, q2); q0_org = __msa_bmnz_v(q0_org, q0, is_less_than_beta); @@ -1031,33 +899,12 @@ static void avc_loopfilter_luma_intra_edge_ver_msa(uint8_t *data, q2_org = __msa_bmnz_v(q2_org, q2, is_less_than_beta); } - /* right */ - { - v16u8 negate_is_less_than_beta_r; + AVC_LPF_P0_OR_Q0(q0_org_r, p1_org_r, q1_org_r, q0_r); + AVC_LPF_P0_OR_Q0(q0_org_l, p1_org_l, q1_org_l, q0_l); - negate_is_less_than_beta_r = - (v16u8) __msa_sldi_b((v16i8) negate_is_less_than_beta, zero, 8); - if (!__msa_test_bz_v(negate_is_less_than_beta_r)) { - AVC_LPF_P0_OR_Q0(q0_org_r, p1_org_r, q1_org_r, q0_r); - } - } - /* left */ - { - v16u8 negate_is_less_than_beta_l; + q0 = (v16u8) __msa_pckev_b((v16i8) q0_l, (v16i8) q0_r); + q0_org = __msa_bmnz_v(q0_org, q0, negate_is_less_than_beta); - negate_is_less_than_beta_l = - (v16u8) __msa_sldi_b(zero, (v16i8) negate_is_less_than_beta, 8); - if (!__msa_test_bz_v(negate_is_less_than_beta_l)) { - AVC_LPF_P0_OR_Q0(q0_org_l, p1_org_l, q1_org_l, q0_l); - } - } - if (!__msa_test_bz_v(negate_is_less_than_beta)) { - v16u8 q0; - - q0 = (v16u8) __msa_pckev_b((v16i8) q0_l, (v16i8) q0_r); - q0_org = __msa_bmnz_v(q0_org, q0, negate_is_less_than_beta); - } - } { v8i16 tp0, tp1, tp2, tp3, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; @@ -1082,6 +929,7 @@ static void avc_loopfilter_luma_intra_edge_ver_msa(uint8_t *data, ST4x4_UB(tmp7, tmp7, 0, 1, 2, 3, src, img_width); ST2x4_UB(tmp5, 4, src + 4, img_width); } + } } static void avc_h_loop_filter_luma_mbaff_intra_msa(uint8_t *src, int32_t stride, From 0105ed551cb9610c62b6920a301125781e1161a0 Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Fri, 15 Sep 2017 11:43:01 +0530 Subject: [PATCH 3089/3374] avcodec/mips: Improve avc mc copy msa functions Remove loops and unroll as block sizes are known. Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/h264qpel_msa.c | 81 +++++++++++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 6 deletions(-) diff --git a/libavcodec/mips/h264qpel_msa.c b/libavcodec/mips/h264qpel_msa.c index 43d21f7d855c9..05dffeaad2aaa 100644 --- a/libavcodec/mips/h264qpel_msa.c +++ b/libavcodec/mips/h264qpel_msa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Parag Salasakar (Parag.Salasakar@imgtec.com) + * Copyright (c) 2015 -2017 Parag Salasakar (Parag.Salasakar@imgtec.com) * * This file is part of FFmpeg. * @@ -2966,31 +2966,100 @@ static void avg_width16_msa(const uint8_t *src, int32_t src_stride, void ff_put_h264_qpel16_mc00_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - copy_width16_msa(src, stride, dst, stride, 16); + v16u8 src0, src1, src2, src3, src4, src5, src6, src7; + v16u8 src8, src9, src10, src11, src12, src13, src14, src15; + + LD_UB8(src, stride, src0, src1, src2, src3, src4, src5, src6, src7); + src += (8 * stride); + LD_UB8(src, stride, src8, src9, src10, src11, src12, src13, src14, src15); + + ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, dst, stride); + dst += (8 * stride); + ST_UB8(src8, src9, src10, src11, src12, src13, src14, src15, dst, stride); } void ff_put_h264_qpel8_mc00_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - copy_width8_msa(src, stride, dst, stride, 8); + uint64_t src0, src1, src2, src3, src4, src5, src6, src7; + + LD4(src, stride, src0, src1, src2, src3); + src += 4 * stride; + LD4(src, stride, src4, src5, src6, src7); + SD4(src0, src1, src2, src3, dst, stride); + dst += 4 * stride; + SD4(src4, src5, src6, src7, dst, stride); } void ff_avg_h264_qpel16_mc00_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avg_width16_msa(src, stride, dst, stride, 16); + v16u8 src0, src1, src2, src3, src4, src5, src6, src7; + v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; + + LD_UB8(src, stride, src0, src1, src2, src3, src4, src5, src6, src7); + src += (8 * stride); + LD_UB8(dst, stride, dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7); + + AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, dst0, dst1, + dst2, dst3); + AVER_UB4_UB(src4, dst4, src5, dst5, src6, dst6, src7, dst7, dst4, dst5, + dst6, dst7); + ST_UB8(dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7, dst, stride); + dst += (8 * stride); + + LD_UB8(src, stride, src0, src1, src2, src3, src4, src5, src6, src7); + LD_UB8(dst, stride, dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7); + + AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, dst0, dst1, + dst2, dst3); + AVER_UB4_UB(src4, dst4, src5, dst5, src6, dst6, src7, dst7, dst4, dst5, + dst6, dst7); + ST_UB8(dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7, dst, stride); } void ff_avg_h264_qpel8_mc00_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avg_width8_msa(src, stride, dst, stride, 8); + uint64_t tp0, tp1, tp2, tp3, tp4, tp5, tp6, tp7; + v16u8 src0 = { 0 }, src1 = { 0 }, src2 = { 0 }, src3 = { 0 }; + v16u8 dst0 = { 0 }, dst1 = { 0 }, dst2 = { 0 }, dst3 = { 0 }; + + LD4(src, stride, tp0, tp1, tp2, tp3); + src += 4 * stride; + LD4(src, stride, tp4, tp5, tp6, tp7); + INSERT_D2_UB(tp0, tp1, src0); + INSERT_D2_UB(tp2, tp3, src1); + INSERT_D2_UB(tp4, tp5, src2); + INSERT_D2_UB(tp6, tp7, src3); + + LD4(dst, stride, tp0, tp1, tp2, tp3); + LD4(dst + 4 * stride, stride, tp4, tp5, tp6, tp7); + INSERT_D2_UB(tp0, tp1, dst0); + INSERT_D2_UB(tp2, tp3, dst1); + INSERT_D2_UB(tp4, tp5, dst2); + INSERT_D2_UB(tp6, tp7, dst3); + + AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, dst0, dst1, + dst2, dst3); + + ST8x8_UB(dst0, dst1, dst2, dst3, dst, stride); } void ff_avg_h264_qpel4_mc00_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avg_width4_msa(src, stride, dst, stride, 4); + uint32_t tp0, tp1, tp2, tp3; + v16u8 src0 = { 0 }, dst0 = { 0 }; + + LW4(src, stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, src0); + LW4(dst, stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); + + dst0 = __msa_aver_u_b(src0, dst0); + + ST4x4_UB(dst0, dst0, 0, 1, 2, 3, dst, stride); } void ff_put_h264_qpel16_mc10_msa(uint8_t *dst, const uint8_t *src, From 1a85fb7e1eb375b37ee9863ce8e6e7ada1742dbe Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Fri, 15 Sep 2017 17:06:34 +0530 Subject: [PATCH 3090/3374] avcodec/mips: Improve hevc sao band filter msa functions Preload data in band filter 0-8 for better pipeline parallelization. Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/hevc_lpf_sao_msa.c | 174 ++++++++++++++++++---------- libavutil/mips/generic_macros_msa.h | 1 + 2 files changed, 112 insertions(+), 63 deletions(-) diff --git a/libavcodec/mips/hevc_lpf_sao_msa.c b/libavcodec/mips/hevc_lpf_sao_msa.c index 79b156fe5c60e..1d77432676cdd 100644 --- a/libavcodec/mips/hevc_lpf_sao_msa.c +++ b/libavcodec/mips/hevc_lpf_sao_msa.c @@ -1049,29 +1049,28 @@ static void hevc_sao_band_filter_4width_msa(uint8_t *dst, int32_t dst_stride, int16_t *sao_offset_val, int32_t height) { - int32_t h_cnt; v16u8 src0, src1, src2, src3; v16i8 src0_r, src1_r; v16i8 offset, offset_val, mask; - v16i8 offset0 = { 0 }; - v16i8 offset1 = { 0 }; + v16i8 dst0, offset0, offset1; v16i8 zero = { 0 }; - v8i16 temp0, temp1, dst0, dst1; offset_val = LD_SB(sao_offset_val + 1); offset_val = (v16i8) __msa_pckev_d((v2i64) offset_val, (v2i64) offset_val); offset_val = __msa_pckev_b(offset_val, offset_val); - offset1 = (v16i8) __msa_insve_w((v4i32) offset1, 3, (v4i32) offset_val); - offset0 = __msa_sld_b(offset1, offset0, 28 - ((sao_left_class) & 31)); + offset1 = (v16i8) __msa_insve_w((v4i32) zero, 3, (v4i32) offset_val); + offset0 = __msa_sld_b(offset1, zero, 28 - ((sao_left_class) & 31)); offset1 = __msa_sld_b(zero, offset1, 28 - ((sao_left_class) & 31)); + /* load in advance. */ + LD_UB4(src, src_stride, src0, src1, src2, src3); + if (!((sao_left_class > 12) & (sao_left_class < 29))) { SWAP(offset0, offset1); } - for (h_cnt = height >> 2; h_cnt--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); + for (height -= 4; height; height -= 4) { src += (4 * src_stride); ILVEV_D2_SB(src0, src1, src2, src3, src0_r, src1_r); @@ -1080,14 +1079,30 @@ static void hevc_sao_band_filter_4width_msa(uint8_t *dst, int32_t dst_stride, mask = __msa_srli_b(src0_r, 3); offset = __msa_vshf_b(mask, offset1, offset0); - UNPCK_SB_SH(offset, temp0, temp1); - ILVRL_B2_SH(zero, src0_r, dst0, dst1); - ADD2(dst0, temp0, dst1, temp1, dst0, dst1); - CLIP_SH2_0_255(dst0, dst1); - dst0 = (v8i16) __msa_pckev_b((v16i8) dst1, (v16i8) dst0); + src0_r = (v16i8) __msa_xori_b((v16u8) src0_r, 128); + dst0 = __msa_adds_s_b(src0_r, offset); + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); + + /* load in advance. */ + LD_UB4(src, src_stride, src0, src1, src2, src3); + + /* store results */ ST4x4_UB(dst0, dst0, 0, 1, 2, 3, dst, dst_stride); dst += (4 * dst_stride); } + + ILVEV_D2_SB(src0, src1, src2, src3, src0_r, src1_r); + + src0_r = (v16i8) __msa_pckev_w((v4i32) src1_r, (v4i32) src0_r); + mask = __msa_srli_b(src0_r, 3); + offset = __msa_vshf_b(mask, offset1, offset0); + + src0_r = (v16i8) __msa_xori_b((v16u8) src0_r, 128); + dst0 = __msa_adds_s_b(src0_r, offset); + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); + + /* store results */ + ST4x4_UB(dst0, dst0, 0, 1, 2, 3, dst, dst_stride); } static void hevc_sao_band_filter_8width_msa(uint8_t *dst, int32_t dst_stride, @@ -1096,51 +1111,69 @@ static void hevc_sao_band_filter_8width_msa(uint8_t *dst, int32_t dst_stride, int16_t *sao_offset_val, int32_t height) { - int32_t h_cnt; v16u8 src0, src1, src2, src3; v16i8 src0_r, src1_r, mask0, mask1; - v16i8 offset, offset_val; - v16i8 offset0 = { 0 }; - v16i8 offset1 = { 0 }; + v16i8 offset_mask0, offset_mask1, offset_val; + v16i8 offset0, offset1, dst0, dst1; v16i8 zero = { 0 }; - v8i16 dst0, dst1, dst2, dst3; - v8i16 temp0, temp1, temp2, temp3; offset_val = LD_SB(sao_offset_val + 1); offset_val = (v16i8) __msa_pckev_d((v2i64) offset_val, (v2i64) offset_val); offset_val = __msa_pckev_b(offset_val, offset_val); - offset1 = (v16i8) __msa_insve_w((v4i32) offset1, 3, (v4i32) offset_val); - offset0 = __msa_sld_b(offset1, offset0, 28 - ((sao_left_class) & 31)); + offset1 = (v16i8) __msa_insve_w((v4i32) zero, 3, (v4i32) offset_val); + offset0 = __msa_sld_b(offset1, zero, 28 - ((sao_left_class) & 31)); offset1 = __msa_sld_b(zero, offset1, 28 - ((sao_left_class) & 31)); + /* load in advance. */ + LD_UB4(src, src_stride, src0, src1, src2, src3); + if (!((sao_left_class > 12) & (sao_left_class < 29))) { SWAP(offset0, offset1); } - for (h_cnt = height >> 2; h_cnt--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); + for (height -= 4; height; height -= 4) { + src += src_stride << 2; ILVR_D2_SB(src1, src0, src3, src2, src0_r, src1_r); mask0 = __msa_srli_b(src0_r, 3); mask1 = __msa_srli_b(src1_r, 3); - offset = __msa_vshf_b(mask0, offset1, offset0); - UNPCK_SB_SH(offset, temp0, temp1); + offset_mask0 = __msa_vshf_b(mask0, offset1, offset0); + offset_mask1 = __msa_vshf_b(mask1, offset1, offset0); - offset = __msa_vshf_b(mask1, offset1, offset0); - UNPCK_SB_SH(offset, temp2, temp3); + /* load in advance. */ + LD_UB4(src, src_stride, src0, src1, src2, src3); - UNPCK_UB_SH(src0_r, dst0, dst1); - UNPCK_UB_SH(src1_r, dst2, dst3); - ADD4(dst0, temp0, dst1, temp1, dst2, temp2, dst3, temp3, - dst0, dst1, dst2, dst3); - CLIP_SH4_0_255(dst0, dst1, dst2, dst3); - PCKEV_B2_SH(dst1, dst0, dst3, dst2, dst0, dst2); - ST8x4_UB(dst0, dst2, dst, dst_stride); - dst += (4 * dst_stride); + XORI_B2_128_SB(src0_r, src1_r); + + dst0 = __msa_adds_s_b(src0_r, offset_mask0); + dst1 = __msa_adds_s_b(src1_r, offset_mask1); + + XORI_B2_128_SB(dst0, dst1); + + /* store results */ + ST8x4_UB(dst0, dst1, dst, dst_stride); + dst += dst_stride << 2; } + + ILVR_D2_SB(src1, src0, src3, src2, src0_r, src1_r); + + mask0 = __msa_srli_b(src0_r, 3); + mask1 = __msa_srli_b(src1_r, 3); + + offset_mask0 = __msa_vshf_b(mask0, offset1, offset0); + offset_mask1 = __msa_vshf_b(mask1, offset1, offset0); + + XORI_B2_128_SB(src0_r, src1_r); + + dst0 = __msa_adds_s_b(src0_r, offset_mask0); + dst1 = __msa_adds_s_b(src1_r, offset_mask1); + + XORI_B2_128_SB(dst0, dst1); + + /* store results */ + ST8x4_UB(dst0, dst1, dst, dst_stride); } static void hevc_sao_band_filter_16multiple_msa(uint8_t *dst, @@ -1151,32 +1184,30 @@ static void hevc_sao_band_filter_16multiple_msa(uint8_t *dst, int16_t *sao_offset_val, int32_t width, int32_t height) { - int32_t h_cnt, w_cnt; + int32_t w_cnt; v16u8 src0, src1, src2, src3; - v8i16 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; v16i8 out0, out1, out2, out3; v16i8 mask0, mask1, mask2, mask3; v16i8 tmp0, tmp1, tmp2, tmp3, offset_val; - v16i8 offset0 = { 0 }; - v16i8 offset1 = { 0 }; + v16i8 offset0, offset1; v16i8 zero = { 0 }; - v8i16 temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7; offset_val = LD_SB(sao_offset_val + 1); offset_val = (v16i8) __msa_pckev_d((v2i64) offset_val, (v2i64) offset_val); offset_val = __msa_pckev_b(offset_val, offset_val); - offset1 = (v16i8) __msa_insve_w((v4i32) offset1, 3, (v4i32) offset_val); - offset0 = __msa_sld_b(offset1, offset0, 28 - ((sao_left_class) & 31)); + offset1 = (v16i8) __msa_insve_w((v4i32) zero, 3, (v4i32) offset_val); + offset0 = __msa_sld_b(offset1, zero, 28 - ((sao_left_class) & 31)); offset1 = __msa_sld_b(zero, offset1, 28 - ((sao_left_class) & 31)); if (!((sao_left_class > 12) & (sao_left_class < 29))) { SWAP(offset0, offset1); } - for (h_cnt = height >> 2; h_cnt--;) { - for (w_cnt = 0; w_cnt < (width >> 4); w_cnt++) { - LD_UB4(src + w_cnt * 16, src_stride, src0, src1, src2, src3); + while (height > 0) { + /* load in advance */ + LD_UB4(src, src_stride, src0, src1, src2, src3); + for (w_cnt = 16; w_cnt < width; w_cnt += 16) { mask0 = __msa_srli_b((v16i8) src0, 3); mask1 = __msa_srli_b((v16i8) src1, 3); mask2 = __msa_srli_b((v16i8) src2, 3); @@ -1186,27 +1217,44 @@ static void hevc_sao_band_filter_16multiple_msa(uint8_t *dst, tmp0, tmp1); VSHF_B2_SB(offset0, offset1, offset0, offset1, mask2, mask3, tmp2, tmp3); - UNPCK_SB_SH(tmp0, temp0, temp1); - UNPCK_SB_SH(tmp1, temp2, temp3); - UNPCK_SB_SH(tmp2, temp4, temp5); - UNPCK_SB_SH(tmp3, temp6, temp7); - ILVRL_B2_SH(zero, src0, dst0, dst1); - ILVRL_B2_SH(zero, src1, dst2, dst3); - ILVRL_B2_SH(zero, src2, dst4, dst5); - ILVRL_B2_SH(zero, src3, dst6, dst7); - ADD4(dst0, temp0, dst1, temp1, dst2, temp2, dst3, temp3, - dst0, dst1, dst2, dst3); - ADD4(dst4, temp4, dst5, temp5, dst6, temp6, dst7, temp7, - dst4, dst5, dst6, dst7); - CLIP_SH4_0_255(dst0, dst1, dst2, dst3); - CLIP_SH4_0_255(dst4, dst5, dst6, dst7); - PCKEV_B4_SB(dst1, dst0, dst3, dst2, dst5, dst4, dst7, dst6, - out0, out1, out2, out3); - ST_SB4(out0, out1, out2, out3, dst + w_cnt * 16, dst_stride); + XORI_B4_128_UB(src0, src1, src2, src3); + + out0 = __msa_adds_s_b((v16i8) src0, tmp0); + out1 = __msa_adds_s_b((v16i8) src1, tmp1); + out2 = __msa_adds_s_b((v16i8) src2, tmp2); + out3 = __msa_adds_s_b((v16i8) src3, tmp3); + + /* load for next iteration */ + LD_UB4(src + w_cnt, src_stride, src0, src1, src2, src3); + + XORI_B4_128_SB(out0, out1, out2, out3); + + ST_SB4(out0, out1, out2, out3, dst + w_cnt - 16, dst_stride); } + mask0 = __msa_srli_b((v16i8) src0, 3); + mask1 = __msa_srli_b((v16i8) src1, 3); + mask2 = __msa_srli_b((v16i8) src2, 3); + mask3 = __msa_srli_b((v16i8) src3, 3); + + VSHF_B2_SB(offset0, offset1, offset0, offset1, mask0, mask1, tmp0, + tmp1); + VSHF_B2_SB(offset0, offset1, offset0, offset1, mask2, mask3, tmp2, + tmp3); + XORI_B4_128_UB(src0, src1, src2, src3); + + out0 = __msa_adds_s_b((v16i8) src0, tmp0); + out1 = __msa_adds_s_b((v16i8) src1, tmp1); + out2 = __msa_adds_s_b((v16i8) src2, tmp2); + out3 = __msa_adds_s_b((v16i8) src3, tmp3); + + XORI_B4_128_SB(out0, out1, out2, out3); + + ST_SB4(out0, out1, out2, out3, dst + w_cnt - 16, dst_stride); + src += src_stride << 2; dst += dst_stride << 2; + height -= 4; } } diff --git a/libavutil/mips/generic_macros_msa.h b/libavutil/mips/generic_macros_msa.h index ee7d6632366d3..3ff94fdc99a60 100644 --- a/libavutil/mips/generic_macros_msa.h +++ b/libavutil/mips/generic_macros_msa.h @@ -1574,6 +1574,7 @@ out0 = (RTYPE) __msa_ilvr_h((v8i16) in0, (v8i16) in1); \ out1 = (RTYPE) __msa_ilvl_h((v8i16) in0, (v8i16) in1); \ } +#define ILVRL_H2_UB(...) ILVRL_H2(v16u8, __VA_ARGS__) #define ILVRL_H2_SB(...) ILVRL_H2(v16i8, __VA_ARGS__) #define ILVRL_H2_SH(...) ILVRL_H2(v8i16, __VA_ARGS__) #define ILVRL_H2_SW(...) ILVRL_H2(v4i32, __VA_ARGS__) From a7f6bfdc185a04a703bedd712ee306435372af12 Mon Sep 17 00:00:00 2001 From: Thomas Mundt Date: Wed, 30 Aug 2017 03:37:18 +0200 Subject: [PATCH 3091/3374] avfilter/interlace: prevent over-sharpening with the complex low-pass filter The complex vertical low-pass filter slightly over-sharpens the picture. This becomes visible when several transcodings are cascaded and the error potentises, e.g. some generations of HD->SD SD->HD. To prevent this behaviour the destination pixel must not exceed the source pixel when the average of the pixels above and below is less than the source pixel. And the other way around. Tested and approved in a visual transcoding cascade test by video professionals. SSIM/PSNR test with the first generation of an HD->SD file as a reference against the 6th generation(3 x SD->HD HD->SD): Results without the patch: SSIM Y:0.956508 (13.615881) U:0.991601 (20.757750) V:0.993004 (21.551382) All:0.974405 (15.918463) PSNR y:31.838009 u:48.424280 v:48.962711 average:34.759466 min:31.699297 max:40.857847 Results with the patch: SSIM Y:0.970051 (15.236232) U:0.991883 (20.905857) V:0.993174 (21.658049) All:0.981290 (17.279202) PSNR y:34.412108 u:48.504454 v:48.969496 average:37.264644 min:34.310637 max:42.373392 Signed-off-by: Thomas Mundt Signed-off-by: Michael Niedermayer --- libavfilter/vf_interlace.c | 17 ++++++-- libavfilter/vf_tinterlace.c | 17 ++++++-- libavfilter/x86/vf_interlace.asm | 55 +++++++++++++++---------- tests/ref/fate/filter-interlace-complex | 50 +++++++++++----------- 4 files changed, 84 insertions(+), 55 deletions(-) diff --git a/libavfilter/vf_interlace.c b/libavfilter/vf_interlace.c index d72cb43401051..1a9278082a25a 100644 --- a/libavfilter/vf_interlace.c +++ b/libavfilter/vf_interlace.c @@ -83,14 +83,23 @@ static void lowpass_line_complex_c(uint8_t *dstp, ptrdiff_t linesize, const uint8_t *srcp_below = srcp + pref; const uint8_t *srcp_above2 = srcp + mref * 2; const uint8_t *srcp_below2 = srcp + pref * 2; - int i; + int i, srcp_x, srcp_ab; for (i = 0; i < linesize; i++) { // this calculation is an integer representation of // '0.75 * current + 0.25 * above + 0.25 * below - 0.125 * above2 - 0.125 * below2' // '4 +' is for rounding. - dstp[i] = av_clip_uint8((4 + (srcp[i] << 2) - + ((srcp[i] + srcp_above[i] + srcp_below[i]) << 1) - - srcp_above2[i] - srcp_below2[i]) >> 3); + srcp_x = srcp[i] << 1; + srcp_ab = srcp_above[i] + srcp_below[i]; + dstp[i] = av_clip_uint8((4 + ((srcp[i] + srcp_x + srcp_ab) << 1) + - srcp_above2[i] - srcp_below2[i]) >> 3); + // Prevent over-sharpening: + // dst must not exceed src when the average of above and below + // is less than src. And the other way around. + if (srcp_ab > srcp_x) { + if (dstp[i] < srcp[i]) + dstp[i] = srcp[i]; + } else if (dstp[i] > srcp[i]) + dstp[i] = srcp[i]; } } diff --git a/libavfilter/vf_tinterlace.c b/libavfilter/vf_tinterlace.c index 65997076ade37..81d2d773e0d3a 100644 --- a/libavfilter/vf_tinterlace.c +++ b/libavfilter/vf_tinterlace.c @@ -110,14 +110,23 @@ static void lowpass_line_complex_c(uint8_t *dstp, ptrdiff_t width, const uint8_t const uint8_t *srcp_below = srcp + pref; const uint8_t *srcp_above2 = srcp + mref * 2; const uint8_t *srcp_below2 = srcp + pref * 2; - int i; + int i, srcp_x, srcp_ab; for (i = 0; i < width; i++) { // this calculation is an integer representation of // '0.75 * current + 0.25 * above + 0.25 * below - 0.125 * above2 - 0.125 * below2' // '4 +' is for rounding. - dstp[i] = av_clip_uint8((4 + (srcp[i] << 2) - + ((srcp[i] + srcp_above[i] + srcp_below[i]) << 1) - - srcp_above2[i] - srcp_below2[i]) >> 3); + srcp_x = srcp[i] << 1; + srcp_ab = srcp_above[i] + srcp_below[i]; + dstp[i] = av_clip_uint8((4 + ((srcp[i] + srcp_x + srcp_ab) << 1) + - srcp_above2[i] - srcp_below2[i]) >> 3); + // Prevent over-sharpening: + // dst must not exceed src when the average of above and below + // is less than src. And the other way around. + if (srcp_ab > srcp_x) { + if (dstp[i] < srcp[i]) + dstp[i] = srcp[i]; + } else if (dstp[i] > srcp[i]) + dstp[i] = srcp[i]; } } diff --git a/libavfilter/x86/vf_interlace.asm b/libavfilter/x86/vf_interlace.asm index c601fd7bf4f67..d0fffd293bede 100644 --- a/libavfilter/x86/vf_interlace.asm +++ b/libavfilter/x86/vf_interlace.asm @@ -63,41 +63,46 @@ REP_RET %endmacro %macro LOWPASS_LINE_COMPLEX 0 -cglobal lowpass_line_complex, 5, 5, 7, dst, h, src, mref, pref - pxor m6, m6 +cglobal lowpass_line_complex, 5, 5, 8, dst, h, src, mref, pref + pxor m7, m7 .loop: mova m0, [srcq+mrefq] mova m2, [srcq+prefq] mova m1, m0 mova m3, m2 - punpcklbw m0, m6 - punpcklbw m2, m6 - punpckhbw m1, m6 - punpckhbw m3, m6 + punpcklbw m0, m7 + punpcklbw m2, m7 + punpckhbw m1, m7 + punpckhbw m3, m7 paddw m0, m2 paddw m1, m3 + mova m6, m0 + mova m5, m1 + mova m2, [srcq] + mova m3, m2 + punpcklbw m2, m7 + punpckhbw m3, m7 + paddw m0, m2 + paddw m1, m3 + psllw m2, 1 + psllw m3, 1 + paddw m0, m2 + paddw m1, m3 + psllw m0, 1 + psllw m1, 1 + pcmpgtw m6, m2 + pcmpgtw m5, m3 + packsswb m6, m5 mova m2, [srcq+mrefq*2] mova m4, [srcq+prefq*2] mova m3, m2 mova m5, m4 - punpcklbw m2, m6 - punpcklbw m4, m6 - punpckhbw m3, m6 - punpckhbw m5, m6 + punpcklbw m2, m7 + punpcklbw m4, m7 + punpckhbw m3, m7 + punpckhbw m5, m7 paddw m2, m4 paddw m3, m5 - mova m4, [srcq] - mova m5, m4 - punpcklbw m4, m6 - punpckhbw m5, m6 - paddw m0, m4 - paddw m1, m5 - psllw m0, 1 - psllw m1, 1 - psllw m4, 2 - psllw m5, 2 - paddw m0, m4 - paddw m1, m5 paddw m0, [pw_4] paddw m1, [pw_4] psubusw m0, m2 @@ -105,6 +110,12 @@ cglobal lowpass_line_complex, 5, 5, 7, dst, h, src, mref, pref psrlw m0, 3 psrlw m1, 3 packuswb m0, m1 + mova m1, m0 + pmaxub m0, [srcq] + pminub m1, [srcq] + pand m0, m6 + pandn m6, m1 + por m0, m6 mova [dstq], m0 add dstq, mmsize diff --git a/tests/ref/fate/filter-interlace-complex b/tests/ref/fate/filter-interlace-complex index 3b7812581fd02..e8db46a93484f 100644 --- a/tests/ref/fate/filter-interlace-complex +++ b/tests/ref/fate/filter-interlace-complex @@ -3,28 +3,28 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 152064, 0x91290ae6 -0, 1, 1, 1, 152064, 0x24f34baf -0, 2, 2, 1, 152064, 0x799fc436 -0, 3, 3, 1, 152064, 0xfe42c0a9 -0, 4, 4, 1, 152064, 0xb496f879 -0, 5, 5, 1, 152064, 0xc43b36c9 -0, 6, 6, 1, 152064, 0xb65abbf4 -0, 7, 7, 1, 152064, 0xd1806312 -0, 8, 8, 1, 152064, 0x0faf56c1 -0, 9, 9, 1, 152064, 0x4de73b75 -0, 10, 10, 1, 152064, 0xf90f24ce -0, 11, 11, 1, 152064, 0xc1efd6e0 -0, 12, 12, 1, 152064, 0xeb8e5894 -0, 13, 13, 1, 152064, 0xe8aacabc -0, 14, 14, 1, 152064, 0x8bd2163c -0, 15, 15, 1, 152064, 0xbfc72ac2 -0, 16, 16, 1, 152064, 0x1e8f6f56 -0, 17, 17, 1, 152064, 0xe3d19450 -0, 18, 18, 1, 152064, 0x3872af32 -0, 19, 19, 1, 152064, 0xf23be72a -0, 20, 20, 1, 152064, 0x024f8f2b -0, 21, 21, 1, 152064, 0xb49301ea -0, 22, 22, 1, 152064, 0x84f5d056 -0, 23, 23, 1, 152064, 0xd2c09ca5 -0, 24, 24, 1, 152064, 0xe9b5ddfd +0, 0, 0, 1, 152064, 0x778ab0c1 +0, 1, 1, 1, 152064, 0xdc30f7c3 +0, 2, 2, 1, 152064, 0xcb637467 +0, 3, 3, 1, 152064, 0xcbf778ce +0, 4, 4, 1, 152064, 0x573d9f6d +0, 5, 5, 1, 152064, 0xd794df2c +0, 6, 6, 1, 152064, 0x3e885448 +0, 7, 7, 1, 152064, 0xccec1794 +0, 8, 8, 1, 152064, 0x6f32f51a +0, 9, 9, 1, 152064, 0x0657f5ac +0, 10, 10, 1, 152064, 0xfa82d600 +0, 11, 11, 1, 152064, 0x15ff7f32 +0, 12, 12, 1, 152064, 0x1cac0342 +0, 13, 13, 1, 152064, 0x6afb7c49 +0, 14, 14, 1, 152064, 0x6c47d554 +0, 15, 15, 1, 152064, 0xe0fbd132 +0, 16, 16, 1, 152064, 0x4f891e8d +0, 17, 17, 1, 152064, 0x88554045 +0, 18, 18, 1, 152064, 0x0c8e6192 +0, 19, 19, 1, 152064, 0xf73c91c3 +0, 20, 20, 1, 152064, 0x49ac328d +0, 21, 21, 1, 152064, 0xf18ebd82 +0, 22, 22, 1, 152064, 0x3359760d +0, 23, 23, 1, 152064, 0x5c85601a +0, 24, 24, 1, 152064, 0x28c1657b From ed48e22748ee199ce4790ed29da8cef937347f17 Mon Sep 17 00:00:00 2001 From: Thomas Mundt Date: Thu, 14 Sep 2017 21:20:24 +0200 Subject: [PATCH 3092/3374] avfilter/interlace: simplify code Signed-off-by: Thomas Mundt Signed-off-by: Michael Niedermayer --- libavfilter/vf_interlace.c | 31 +++++++++---------------------- libavfilter/vf_tinterlace.c | 29 +++++++++-------------------- 2 files changed, 18 insertions(+), 42 deletions(-) diff --git a/libavfilter/vf_interlace.c b/libavfilter/vf_interlace.c index 1a9278082a25a..55bf782af8daa 100644 --- a/libavfilter/vf_interlace.c +++ b/libavfilter/vf_interlace.c @@ -181,6 +181,8 @@ static void copy_picture_field(InterlaceContext *s, int lines = (plane == 1 || plane == 2) ? AV_CEIL_RSHIFT(inlink->h, vsub) : inlink->h; uint8_t *dstp = dst_frame->data[plane]; const uint8_t *srcp = src_frame->data[plane]; + int srcp_linesize = src_frame->linesize[plane] * 2; + int dstp_linesize = dst_frame->linesize[plane] * 2; av_assert0(cols >= 0 || lines >= 0); @@ -189,38 +191,23 @@ static void copy_picture_field(InterlaceContext *s, srcp += src_frame->linesize[plane]; dstp += dst_frame->linesize[plane]; } - if (lowpass == VLPF_LIN) { - int srcp_linesize = src_frame->linesize[plane] * 2; - int dstp_linesize = dst_frame->linesize[plane] * 2; + if (lowpass) { + int x = 0; + if (lowpass == VLPF_CMP) + x = 1; for (j = lines; j > 0; j--) { ptrdiff_t pref = src_frame->linesize[plane]; ptrdiff_t mref = -pref; - if (j == lines) - mref = 0; // there is no line above - else if (j == 1) - pref = 0; // there is no line below - s->lowpass_line(dstp, cols, srcp, mref, pref); - dstp += dstp_linesize; - srcp += srcp_linesize; - } - } else if (lowpass == VLPF_CMP) { - int srcp_linesize = src_frame->linesize[plane] * 2; - int dstp_linesize = dst_frame->linesize[plane] * 2; - for (j = lines; j > 0; j--) { - ptrdiff_t pref = src_frame->linesize[plane]; - ptrdiff_t mref = -pref; - if (j >= (lines - 1)) + if (j >= (lines - x)) mref = 0; - else if (j <= 2) + else if (j <= (1 + x)) pref = 0; s->lowpass_line(dstp, cols, srcp, mref, pref); dstp += dstp_linesize; srcp += srcp_linesize; } } else { - av_image_copy_plane(dstp, dst_frame->linesize[plane] * 2, - srcp, src_frame->linesize[plane] * 2, - cols, lines); + av_image_copy_plane(dstp, dstp_linesize, srcp, srcp_linesize, cols, lines); } } } diff --git a/libavfilter/vf_tinterlace.c b/libavfilter/vf_tinterlace.c index 81d2d773e0d3a..66c6d17ed9b1e 100644 --- a/libavfilter/vf_tinterlace.c +++ b/libavfilter/vf_tinterlace.c @@ -252,6 +252,8 @@ void copy_picture_field(TInterlaceContext *tinterlace, int cols = plane == 1 || plane == 2 ? AV_CEIL_RSHIFT( w, hsub) : w; uint8_t *dstp = dst[plane]; const uint8_t *srcp = src[plane]; + int srcp_linesize = src_linesize[plane] * k; + int dstp_linesize = dst_linesize[plane] * (interleave ? 2 : 1); lines = (lines + (src_field == FIELD_UPPER)) / k; if (src_field == FIELD_LOWER) @@ -261,35 +263,22 @@ void copy_picture_field(TInterlaceContext *tinterlace, // Low-pass filtering is required when creating an interlaced destination from // a progressive source which contains high-frequency vertical detail. // Filtering will reduce interlace 'twitter' and Moire patterning. - if (flags & TINTERLACE_FLAG_CVLPF) { - int srcp_linesize = src_linesize[plane] * k; - int dstp_linesize = dst_linesize[plane] * (interleave ? 2 : 1); + if (flags & TINTERLACE_FLAG_VLPF || flags & TINTERLACE_FLAG_CVLPF) { + int x = 0; + if (flags & TINTERLACE_FLAG_CVLPF) + x = 1; for (h = lines; h > 0; h--) { ptrdiff_t pref = src_linesize[plane]; ptrdiff_t mref = -pref; - if (h >= (lines - 1)) mref = 0; - else if (h <= 2) pref = 0; - - tinterlace->lowpass_line(dstp, cols, srcp, mref, pref); - dstp += dstp_linesize; - srcp += srcp_linesize; - } - } else if (flags & TINTERLACE_FLAG_VLPF) { - int srcp_linesize = src_linesize[plane] * k; - int dstp_linesize = dst_linesize[plane] * (interleave ? 2 : 1); - for (h = lines; h > 0; h--) { - ptrdiff_t pref = src_linesize[plane]; - ptrdiff_t mref = -pref; - if (h == lines) mref = 0; // there is no line above - else if (h == 1) pref = 0; // there is no line below + if (h >= (lines - x)) mref = 0; // there is no line above + else if (h <= (1 + x)) pref = 0; // there is no line below tinterlace->lowpass_line(dstp, cols, srcp, mref, pref); dstp += dstp_linesize; srcp += srcp_linesize; } } else { - av_image_copy_plane(dstp, dst_linesize[plane] * (interleave ? 2 : 1), - srcp, src_linesize[plane]*k, cols, lines); + av_image_copy_plane(dstp, dstp_linesize, srcp, srcp_linesize, cols, lines); } } } From 42a41c3956975a4404d0c48bedd51f144c90c08b Mon Sep 17 00:00:00 2001 From: Thierry Foucu Date: Fri, 15 Sep 2017 08:49:54 -0700 Subject: [PATCH 3093/3374] vf_fps: Fix memory leak introduced by eea64ef4 Signed-off-by: Michael Niedermayer --- libavfilter/vf_fps.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c index 09fc66a73c201..1e5d07e31c148 100644 --- a/libavfilter/vf_fps.c +++ b/libavfilter/vf_fps.c @@ -171,6 +171,7 @@ static int request_frame(AVFilterLink *outlink) s->frames_out++; if (j > 0) s->dup++; } + av_frame_free(&buf); } else { /* for delta less or equal to 0, we should drop the frame, * otherwise, we will have one or more extra frames */ From 73bf0f42e3423265662fb9cab28fb5cc1c5ae1cb Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Sat, 16 Sep 2017 10:32:28 +0800 Subject: [PATCH 3094/3374] avformat/hlsenc: fix segfault when using -hls_segment_type fmp4 with -hls_segment_filename previously, specifying -hls_segment_filename meant s->base_output_dirname was never set, causing a segfault: (lldb) bt * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0) * frame #0: 0x00007fffbf7d82d0 libsystem_platform.dylib`_platform_strcmp + 80 frame #1: 0x00000001005f4dcf libavformat.57.dylib`io_open_default(s=0x000000010481cc00, pb=0x0000000104806020, url=0x0000000000000000, flags=2, options=0x0000000000000000) at options.c:107 frame #2: 0x0000000100528968 libavformat.57.dylib`hls_mux_init(s=0x000000010481cc00) at hlsenc.c:595 frame #3: 0x00000001005273cb libavformat.57.dylib`hls_write_header(s=0x000000010481cc00) at hlsenc.c:1518 frame #4: 0x00000001005c08d0 libavformat.57.dylib`write_header_internal(s=0x000000010481cc00) at mux.c:486 frame #5: 0x00000001005c0774 libavformat.57.dylib`avformat_write_header(s=0x000000010481cc00, options=0x00000001029026e8) at mux.c:539 --- libavformat/hlsenc.c | 45 ++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 895aa41bc367a..3a9a235514630 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -1441,32 +1441,33 @@ static int hls_write_header(AVFormatContext *s) } else { av_strlcat(hls->basename, pattern, basename_size); } + } - if (av_strcasecmp(hls->fmp4_init_filename, "init.mp4")) { - int fmp4_init_filename_len = strlen(hls->fmp4_init_filename) + 1; - hls->base_output_dirname = av_malloc(fmp4_init_filename_len); - if (!hls->base_output_dirname) { - ret = AVERROR(ENOMEM); - goto fail; - } - av_strlcpy(hls->base_output_dirname, hls->fmp4_init_filename, fmp4_init_filename_len); - } else { - hls->base_output_dirname = av_malloc(basename_size); - if (!hls->base_output_dirname) { - ret = AVERROR(ENOMEM); - goto fail; - } + if (av_strcasecmp(hls->fmp4_init_filename, "init.mp4")) { + int fmp4_init_filename_len = strlen(hls->fmp4_init_filename) + 1; + hls->base_output_dirname = av_malloc(fmp4_init_filename_len); + if (!hls->base_output_dirname) { + ret = AVERROR(ENOMEM); + goto fail; + } + av_strlcpy(hls->base_output_dirname, hls->fmp4_init_filename, fmp4_init_filename_len); + } else { + hls->base_output_dirname = av_malloc(basename_size); + if (!hls->base_output_dirname) { + ret = AVERROR(ENOMEM); + goto fail; + } - av_strlcpy(hls->base_output_dirname, s->filename, basename_size); - p = strrchr(hls->base_output_dirname, '/'); - if (p) { - *(p + 1) = '\0'; - av_strlcat(hls->base_output_dirname, hls->fmp4_init_filename, basename_size); - } else { - av_strlcpy(hls->base_output_dirname, hls->fmp4_init_filename, basename_size); - } + av_strlcpy(hls->base_output_dirname, s->filename, basename_size); + p = strrchr(hls->base_output_dirname, '/'); + if (p) { + *(p + 1) = '\0'; + av_strlcat(hls->base_output_dirname, hls->fmp4_init_filename, basename_size); + } else { + av_strlcpy(hls->base_output_dirname, hls->fmp4_init_filename, basename_size); } } + if (!hls->use_localtime) { ret = sls_flag_check_duration_size_index(hls); if (ret < 0) { From a149fa97d9501d3a1749232cc60b6f122d9d2de8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reimar=20D=C3=B6ffinger?= Date: Wed, 13 Sep 2017 18:59:21 +0200 Subject: [PATCH 3095/3374] avcodec/frame_thread_encoder: Fix AV_OPT_TYPE_STRING handling in avctx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the equivalent to what 7d317d4706b49d572a1eb5269438753be18362c7 did for the codec-specific options. av_opt_copy has specific handling so it's fine that we already copied the whole context before. Signed-off-by: Reimar Döffinger --- libavcodec/frame_thread_encoder.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavcodec/frame_thread_encoder.c b/libavcodec/frame_thread_encoder.c index 35a37c4372d27..31a9fe9dae7e4 100644 --- a/libavcodec/frame_thread_encoder.c +++ b/libavcodec/frame_thread_encoder.c @@ -199,6 +199,9 @@ int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){ goto fail; tmpv = thread_avctx->priv_data; *thread_avctx = *avctx; + int ret = av_opt_copy(thread_avctx, avctx); + if (ret < 0) + goto fail; thread_avctx->priv_data = tmpv; thread_avctx->internal = NULL; if (avctx->codec->priv_class) { From 0f5576a22b11ef726a01b14d1eaae2fa780c2f52 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 16 Sep 2017 19:19:54 +0200 Subject: [PATCH 3096/3374] avutil/imgutils: Fix warning: missing braces around initializer Signed-off-by: Michael Niedermayer --- libavutil/imgutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavutil/imgutils.c b/libavutil/imgutils.c index 4de0fa0c3942c..50051788041d1 100644 --- a/libavutil/imgutils.c +++ b/libavutil/imgutils.c @@ -555,7 +555,7 @@ int av_image_fill_black(uint8_t *dst_data[4], const ptrdiff_t dst_linesize[4], int nb_planes = av_pix_fmt_count_planes(pix_fmt); // A pixel or a group of pixels on each plane, with a value that represents black. // Consider e.g. AV_PIX_FMT_UYVY422 for non-trivial cases. - uint8_t clear_block[4][MAX_BLOCK_SIZE] = {0}; // clear padding with 0 + uint8_t clear_block[4][MAX_BLOCK_SIZE] = {{0}}; // clear padding with 0 int clear_block_size[4] = {0}; ptrdiff_t plane_line_bytes[4] = {0}; int rgb, limited; From d76838c1adc2b75de44779336712c5d540ed5535 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 16 Sep 2017 19:20:28 +0200 Subject: [PATCH 3097/3374] avcodec/fits: Fix include type Signed-off-by: Michael Niedermayer --- libavcodec/fits.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/fits.h b/libavcodec/fits.h index b2f9b4cb39cb9..ebae85c9e55f1 100644 --- a/libavcodec/fits.h +++ b/libavcodec/fits.h @@ -24,7 +24,7 @@ #include -#include +#include "libavutil/dict.h" typedef enum FITSHeaderState { STATE_SIMPLE, From 08ec828de9663e46fbfe8feef5c15253f841c687 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 16 Sep 2017 19:21:35 +0200 Subject: [PATCH 3098/3374] avcodec/vorbisenc: Fix mixed declaration and statements Signed-off-by: Michael Niedermayer --- libavcodec/vorbisenc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/vorbisenc.c b/libavcodec/vorbisenc.c index bf21a3b1ff5c9..a4ecd8f754774 100644 --- a/libavcodec/vorbisenc.c +++ b/libavcodec/vorbisenc.c @@ -1026,6 +1026,7 @@ static int apply_window_and_mdct(vorbis_enc_context *venc) static AVFrame *spawn_empty_frame(AVCodecContext *avctx, int channels) { AVFrame *f = av_frame_alloc(); + int ch; if (!f) return NULL; @@ -1039,7 +1040,7 @@ static AVFrame *spawn_empty_frame(AVCodecContext *avctx, int channels) return NULL; } - for (int ch = 0; ch < channels; ch++) { + for (ch = 0; ch < channels; ch++) { size_t bps = av_get_bytes_per_sample(f->format); memset(f->extended_data[ch], 0, bps * f->nb_samples); } @@ -1108,8 +1109,9 @@ static int vorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, if (!frame) { if (venc->bufqueue.available * avctx->frame_size < frame_size) { int frames_needed = (frame_size/avctx->frame_size) - venc->bufqueue.available; + int i; - for (int i = 0; i < frames_needed; i++) { + for (i = 0; i < frames_needed; i++) { AVFrame *empty = spawn_empty_frame(avctx, venc->channels); if (!empty) return AVERROR(ENOMEM); From 9b8c1224d7e1804b0b750de11e6a8c4648f1e115 Mon Sep 17 00:00:00 2001 From: Martin Vignali Date: Sun, 17 Sep 2017 21:59:41 +0200 Subject: [PATCH 3099/3374] libavcodec/exr : add X86 SIMD for reorder_pixels Signed-off-by: James Almer --- libavcodec/Makefile | 2 +- libavcodec/exr.c | 38 +++++++++------------- libavcodec/exrdsp.c | 47 +++++++++++++++++++++++++++ libavcodec/exrdsp.h | 32 ++++++++++++++++++ libavcodec/x86/Makefile | 2 ++ libavcodec/x86/exrdsp.asm | 63 ++++++++++++++++++++++++++++++++++++ libavcodec/x86/exrdsp_init.c | 39 ++++++++++++++++++++++ 7 files changed, 199 insertions(+), 24 deletions(-) create mode 100644 libavcodec/exrdsp.c create mode 100644 libavcodec/exrdsp.h create mode 100644 libavcodec/x86/exrdsp.asm create mode 100644 libavcodec/x86/exrdsp_init.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 943e5db51131b..fad56129a3888 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -286,7 +286,7 @@ OBJS-$(CONFIG_EIGHTSVX_FIB_DECODER) += 8svx.o OBJS-$(CONFIG_ESCAPE124_DECODER) += escape124.o OBJS-$(CONFIG_ESCAPE130_DECODER) += escape130.o OBJS-$(CONFIG_EVRC_DECODER) += evrcdec.o acelp_vectors.o lsp.o -OBJS-$(CONFIG_EXR_DECODER) += exr.o +OBJS-$(CONFIG_EXR_DECODER) += exr.o exrdsp.o OBJS-$(CONFIG_FFV1_DECODER) += ffv1dec.o ffv1.o OBJS-$(CONFIG_FFV1_ENCODER) += ffv1enc.o ffv1.o OBJS-$(CONFIG_FFWAVESYNTH_DECODER) += ffwavesynth.o diff --git a/libavcodec/exr.c b/libavcodec/exr.c index 759880756dae9..de2f05d3a962d 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -51,6 +51,7 @@ #include "bswapdsp.h" #endif +#include "exrdsp.h" #include "get_bits.h" #include "internal.h" #include "mathops.h" @@ -121,6 +122,7 @@ typedef struct EXRContext { AVClass *class; AVFrame *picture; AVCodecContext *avctx; + ExrDSPContext dsp; #if HAVE_BIGENDIAN BswapDSPContext bbdsp; @@ -275,23 +277,7 @@ static void predictor(uint8_t *src, int size) } } -static void reorder_pixels(uint8_t *src, uint8_t *dst, int size) -{ - const uint8_t *t1 = src; - int half_size = size / 2; - const uint8_t *t2 = src + half_size; - uint8_t *s = dst; - int i; - - av_assert1(size % 2 == 0); - - for (i = 0; i < half_size; i++) { - *(s++) = *(t1++); - *(s++) = *(t2++); - } -} - -static int zip_uncompress(const uint8_t *src, int compressed_size, +static int zip_uncompress(EXRContext *s, const uint8_t *src, int compressed_size, int uncompressed_size, EXRThreadData *td) { unsigned long dest_len = uncompressed_size; @@ -300,13 +286,15 @@ static int zip_uncompress(const uint8_t *src, int compressed_size, dest_len != uncompressed_size) return AVERROR_INVALIDDATA; + av_assert1(uncompressed_size % 2 == 0); + predictor(td->tmp, uncompressed_size); - reorder_pixels(td->tmp, td->uncompressed_data, uncompressed_size); + s->dsp.reorder_pixels(td->tmp, td->uncompressed_data, uncompressed_size); return 0; } -static int rle_uncompress(const uint8_t *src, int compressed_size, +static int rle_uncompress(EXRContext *ctx, const uint8_t *src, int compressed_size, int uncompressed_size, EXRThreadData *td) { uint8_t *d = td->tmp; @@ -345,8 +333,10 @@ static int rle_uncompress(const uint8_t *src, int compressed_size, if (dend != d) return AVERROR_INVALIDDATA; + av_assert1(uncompressed_size % 2 == 0); + predictor(td->tmp, uncompressed_size); - reorder_pixels(td->tmp, td->uncompressed_data, uncompressed_size); + ctx->dsp.reorder_pixels(td->tmp, td->uncompressed_data, uncompressed_size); return 0; } @@ -1152,7 +1142,7 @@ static int decode_block(AVCodecContext *avctx, void *tdata, if (data_size < uncompressed_size) { av_fast_padded_malloc(&td->uncompressed_data, - &td->uncompressed_size, uncompressed_size); + &td->uncompressed_size, uncompressed_size + 64);/* Force 64 padding for AVX2 reorder_pixels dst */ if (!td->uncompressed_data) return AVERROR(ENOMEM); @@ -1161,7 +1151,7 @@ static int decode_block(AVCodecContext *avctx, void *tdata, switch (s->compression) { case EXR_ZIP1: case EXR_ZIP16: - ret = zip_uncompress(src, data_size, uncompressed_size, td); + ret = zip_uncompress(s, src, data_size, uncompressed_size, td); break; case EXR_PIZ: ret = piz_uncompress(s, src, data_size, uncompressed_size, td); @@ -1170,7 +1160,7 @@ static int decode_block(AVCodecContext *avctx, void *tdata, ret = pxr24_uncompress(s, src, data_size, uncompressed_size, td); break; case EXR_RLE: - ret = rle_uncompress(src, data_size, uncompressed_size, td); + ret = rle_uncompress(s, src, data_size, uncompressed_size, td); break; case EXR_B44: case EXR_B44A: @@ -1804,6 +1794,8 @@ static av_cold int decode_init(AVCodecContext *avctx) s->avctx = avctx; + ff_exrdsp_init(&s->dsp); + #if HAVE_BIGENDIAN ff_bswapdsp_init(&s->bbdsp); #endif diff --git a/libavcodec/exrdsp.c b/libavcodec/exrdsp.c new file mode 100644 index 0000000000000..e59dac3dc4fa2 --- /dev/null +++ b/libavcodec/exrdsp.c @@ -0,0 +1,47 @@ +/* + * This file is part of FFmpeg. + * + * Copyright (c) 2006 Industrial Light & Magic, a division of Lucas Digital Ltd. LLC + * + * 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 + +#include "libavutil/attributes.h" +#include "exrdsp.h" +#include "config.h" + +static void reorder_pixels_scalar(uint8_t *src, uint8_t *dst, ptrdiff_t size) +{ + const uint8_t *t1 = src; + int half_size = size / 2; + const uint8_t *t2 = src + half_size; + uint8_t *s = dst; + int i; + + for (i = 0; i < half_size; i++) { + *(s++) = *(t1++); + *(s++) = *(t2++); + } +} + +av_cold void ff_exrdsp_init(ExrDSPContext *c) +{ + c->reorder_pixels = reorder_pixels_scalar; + + if (ARCH_X86) + ff_exrdsp_init_x86(c); +} diff --git a/libavcodec/exrdsp.h b/libavcodec/exrdsp.h new file mode 100644 index 0000000000000..09a76a518e2b3 --- /dev/null +++ b/libavcodec/exrdsp.h @@ -0,0 +1,32 @@ +/* + * 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 + */ + +#ifndef AVCODEC_EXRDSP_H +#define AVCODEC_EXRDSP_H + +#include +#include "libavutil/common.h" + +typedef struct ExrDSPContext { + void (*reorder_pixels)(uint8_t *src, uint8_t *dst, ptrdiff_t size); +} ExrDSPContext; + +void ff_exrdsp_init(ExrDSPContext *c); +void ff_exrdsp_init_x86(ExrDSPContext *c); + +#endif /* AVCODEC_EXRDSP_H */ diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile index e36644c72a614..a805cd37b484f 100644 --- a/libavcodec/x86/Makefile +++ b/libavcodec/x86/Makefile @@ -52,6 +52,7 @@ OBJS-$(CONFIG_APNG_DECODER) += x86/pngdsp_init.o OBJS-$(CONFIG_CAVS_DECODER) += x86/cavsdsp.o OBJS-$(CONFIG_DCA_DECODER) += x86/dcadsp_init.o x86/synth_filter_init.o OBJS-$(CONFIG_DNXHD_ENCODER) += x86/dnxhdenc_init.o +OBJS-$(CONFIG_EXR_DECODER) += x86/exrdsp_init.o OBJS-$(CONFIG_OPUS_DECODER) += x86/opus_dsp_init.o OBJS-$(CONFIG_OPUS_ENCODER) += x86/opus_dsp_init.o OBJS-$(CONFIG_HEVC_DECODER) += x86/hevcdsp_init.o @@ -153,6 +154,7 @@ X86ASM-OBJS-$(CONFIG_DCA_DECODER) += x86/dcadsp.o x86/synth_filter.o X86ASM-OBJS-$(CONFIG_DIRAC_DECODER) += x86/diracdsp.o \ x86/dirac_dwt.o X86ASM-OBJS-$(CONFIG_DNXHD_ENCODER) += x86/dnxhdenc.o +X86ASM-OBJS-$(CONFIG_EXR_DECODER) += x86/exrdsp.o X86ASM-OBJS-$(CONFIG_FLAC_DECODER) += x86/flacdsp.o ifdef CONFIG_GPL X86ASM-OBJS-$(CONFIG_FLAC_ENCODER) += x86/flac_dsp_gpl.o diff --git a/libavcodec/x86/exrdsp.asm b/libavcodec/x86/exrdsp.asm new file mode 100644 index 0000000000000..91d9c0b0a7797 --- /dev/null +++ b/libavcodec/x86/exrdsp.asm @@ -0,0 +1,63 @@ +;****************************************************************************** +;* X86 Optimized functions for Open Exr Decoder +;* Copyright (c) 2006 Industrial Light & Magic, a division of Lucas Digital Ltd. LLC +;* +;* reorder_pixels based on patch by John Loy +;* port to ASM by Jokyo Images support by CNC - French National Center for Cinema +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION .text + +;------------------------------------------------------------------------------ +; void ff_reorder_pixels(uint8_t *src, uint8_t *dst, ptrdiff_t size) +;------------------------------------------------------------------------------ + +%macro REORDER_PIXELS 0 +cglobal reorder_pixels, 3,4,3, src1, dst, size, src2 + lea src2q, [src1q+sizeq] ; src2 = src + 2 * half_size + add dstq, sizeq ; dst offset by size + shr sizeq, 1 ; half_size + add src1q, sizeq ; offset src by half_size + neg sizeq ; size = offset for dst, src1, src2 +.loop: + +%if cpuflag(avx2) + vpermq m0, [src1q + sizeq], 0xd8; load first part + vpermq m1, [src2q + sizeq], 0xd8; load second part +%else + mova m0, [src1q+sizeq] ; load first part + movu m1, [src2q+sizeq] ; load second part +%endif + SBUTTERFLY bw, 0, 1, 2 ; interleaved + mova [dstq+2*sizeq ], m0 ; copy to dst + mova [dstq+2*sizeq+mmsize], m1 + add sizeq, mmsize + jl .loop + RET +%endmacro + +INIT_XMM sse2 +REORDER_PIXELS + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +REORDER_PIXELS +%endif diff --git a/libavcodec/x86/exrdsp_init.c b/libavcodec/x86/exrdsp_init.c new file mode 100644 index 0000000000000..c0f508b2c40ef --- /dev/null +++ b/libavcodec/x86/exrdsp_init.c @@ -0,0 +1,39 @@ +/* + * OpenEXR (.exr) image decoder + * + * 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 "libavutil/attributes.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/exrdsp.h" + +void ff_reorder_pixels_sse2(uint8_t *src, uint8_t *dst, ptrdiff_t size); + +void ff_reorder_pixels_avx2(uint8_t *src, uint8_t *dst, ptrdiff_t size); + +av_cold void ff_exrdsp_init_x86(ExrDSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE2(cpu_flags)) { + dsp->reorder_pixels = ff_reorder_pixels_sse2; + } + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + dsp->reorder_pixels = ff_reorder_pixels_avx2; + } +} From 98d7ad085e20f7cd3347bbaff251bd687db733ee Mon Sep 17 00:00:00 2001 From: James Almer Date: Sun, 17 Sep 2017 18:56:39 -0300 Subject: [PATCH 3100/3374] avcodec/exrdsp: improve the ExrDSPContext->reorder_pixels prototype Make dst be the first parameter and src const. It's more in line with the rest of the codebase. Signed-off-by: James Almer --- libavcodec/exr.c | 4 ++-- libavcodec/exrdsp.c | 2 +- libavcodec/exrdsp.h | 2 +- libavcodec/x86/exrdsp.asm | 4 ++-- libavcodec/x86/exrdsp_init.c | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libavcodec/exr.c b/libavcodec/exr.c index de2f05d3a962d..230d5bbca8c15 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -289,7 +289,7 @@ static int zip_uncompress(EXRContext *s, const uint8_t *src, int compressed_size av_assert1(uncompressed_size % 2 == 0); predictor(td->tmp, uncompressed_size); - s->dsp.reorder_pixels(td->tmp, td->uncompressed_data, uncompressed_size); + s->dsp.reorder_pixels(td->uncompressed_data, td->tmp, uncompressed_size); return 0; } @@ -336,7 +336,7 @@ static int rle_uncompress(EXRContext *ctx, const uint8_t *src, int compressed_si av_assert1(uncompressed_size % 2 == 0); predictor(td->tmp, uncompressed_size); - ctx->dsp.reorder_pixels(td->tmp, td->uncompressed_data, uncompressed_size); + ctx->dsp.reorder_pixels(td->uncompressed_data, td->tmp, uncompressed_size); return 0; } diff --git a/libavcodec/exrdsp.c b/libavcodec/exrdsp.c index e59dac3dc4fa2..871b6f1276d28 100644 --- a/libavcodec/exrdsp.c +++ b/libavcodec/exrdsp.c @@ -24,7 +24,7 @@ #include "exrdsp.h" #include "config.h" -static void reorder_pixels_scalar(uint8_t *src, uint8_t *dst, ptrdiff_t size) +static void reorder_pixels_scalar(uint8_t *dst, const uint8_t *src, ptrdiff_t size) { const uint8_t *t1 = src; int half_size = size / 2; diff --git a/libavcodec/exrdsp.h b/libavcodec/exrdsp.h index 09a76a518e2b3..d8cb002efcdb2 100644 --- a/libavcodec/exrdsp.h +++ b/libavcodec/exrdsp.h @@ -23,7 +23,7 @@ #include "libavutil/common.h" typedef struct ExrDSPContext { - void (*reorder_pixels)(uint8_t *src, uint8_t *dst, ptrdiff_t size); + void (*reorder_pixels)(uint8_t *dst, const uint8_t *src, ptrdiff_t size); } ExrDSPContext; void ff_exrdsp_init(ExrDSPContext *c); diff --git a/libavcodec/x86/exrdsp.asm b/libavcodec/x86/exrdsp.asm index 91d9c0b0a7797..b91a7be20d5bd 100644 --- a/libavcodec/x86/exrdsp.asm +++ b/libavcodec/x86/exrdsp.asm @@ -27,11 +27,11 @@ SECTION .text ;------------------------------------------------------------------------------ -; void ff_reorder_pixels(uint8_t *src, uint8_t *dst, ptrdiff_t size) +; void ff_reorder_pixels(uint8_t *dst, const uint8_t *src, ptrdiff_t size); ;------------------------------------------------------------------------------ %macro REORDER_PIXELS 0 -cglobal reorder_pixels, 3,4,3, src1, dst, size, src2 +cglobal reorder_pixels, 3,4,3, dst, src1, size, src2 lea src2q, [src1q+sizeq] ; src2 = src + 2 * half_size add dstq, sizeq ; dst offset by size shr sizeq, 1 ; half_size diff --git a/libavcodec/x86/exrdsp_init.c b/libavcodec/x86/exrdsp_init.c index c0f508b2c40ef..5669be3d9728e 100644 --- a/libavcodec/x86/exrdsp_init.c +++ b/libavcodec/x86/exrdsp_init.c @@ -22,9 +22,9 @@ #include "libavutil/x86/cpu.h" #include "libavcodec/exrdsp.h" -void ff_reorder_pixels_sse2(uint8_t *src, uint8_t *dst, ptrdiff_t size); +void ff_reorder_pixels_sse2(uint8_t *dst, const uint8_t *src, ptrdiff_t size); -void ff_reorder_pixels_avx2(uint8_t *src, uint8_t *dst, ptrdiff_t size); +void ff_reorder_pixels_avx2(uint8_t *dst, const uint8_t *src, ptrdiff_t size); av_cold void ff_exrdsp_init_x86(ExrDSPContext *dsp) { From 7323c896b2cb6b2f3c0643094d6dd3e1d7179690 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sun, 17 Sep 2017 18:48:02 -0300 Subject: [PATCH 3101/3374] checkasm: add an exrdsp test Signed-off-by: James Almer --- tests/checkasm/Makefile | 1 + tests/checkasm/checkasm.c | 3 ++ tests/checkasm/checkasm.h | 1 + tests/checkasm/exrdsp.c | 68 +++++++++++++++++++++++++++++++++++++++ tests/fate/checkasm.mak | 1 + 5 files changed, 74 insertions(+) create mode 100644 tests/checkasm/exrdsp.c diff --git a/tests/checkasm/Makefile b/tests/checkasm/Makefile index 184e9817546db..14916e5100c55 100644 --- a/tests/checkasm/Makefile +++ b/tests/checkasm/Makefile @@ -18,6 +18,7 @@ AVCODECOBJS-$(CONFIG_AAC_DECODER) += aacpsdsp.o \ sbrdsp.o AVCODECOBJS-$(CONFIG_ALAC_DECODER) += alacdsp.o AVCODECOBJS-$(CONFIG_DCA_DECODER) += synth_filter.o +AVCODECOBJS-$(CONFIG_EXR_DECODER) += exrdsp.o AVCODECOBJS-$(CONFIG_JPEG2000_DECODER) += jpeg2000dsp.o AVCODECOBJS-$(CONFIG_PIXBLOCKDSP) += pixblockdsp.o AVCODECOBJS-$(CONFIG_HEVC_DECODER) += hevc_add_res.o hevc_idct.o diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c index ba729ac1bf4ae..b8b0e32dbd4b5 100644 --- a/tests/checkasm/checkasm.c +++ b/tests/checkasm/checkasm.c @@ -92,6 +92,9 @@ static const struct { #if CONFIG_DCA_DECODER { "synth_filter", checkasm_check_synth_filter }, #endif + #if CONFIG_EXR_DECODER + { "exrdsp", checkasm_check_exrdsp }, + #endif #if CONFIG_FLACDSP { "flacdsp", checkasm_check_flacdsp }, #endif diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h index b29a61331e4f0..e5b1877dc00a3 100644 --- a/tests/checkasm/checkasm.h +++ b/tests/checkasm/checkasm.h @@ -46,6 +46,7 @@ void checkasm_check_blend(void); void checkasm_check_blockdsp(void); void checkasm_check_bswapdsp(void); void checkasm_check_colorspace(void); +void checkasm_check_exrdsp(void); void checkasm_check_fixed_dsp(void); void checkasm_check_flacdsp(void); void checkasm_check_float_dsp(void); diff --git a/tests/checkasm/exrdsp.c b/tests/checkasm/exrdsp.c new file mode 100644 index 0000000000000..6637f6fdd2e66 --- /dev/null +++ b/tests/checkasm/exrdsp.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2017 James Almer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU 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 + +#include "checkasm.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/exrdsp.h" +#include "libavutil/intreadwrite.h" + +#define BUF_SIZE 5120 +#define PADDED_BUF_SIZE BUF_SIZE+AV_INPUT_BUFFER_PADDING_SIZE*2 + +#define randomize_buffers() \ + do { \ + int i; \ + for (i = 0; i < BUF_SIZE; i += 4) { \ + uint32_t r = rnd(); \ + AV_WN32A(src + i, r); \ + } \ + } while (0) + +static void check_reorder_pixels(void) { + LOCAL_ALIGNED_32(uint8_t, src, [PADDED_BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst_ref, [PADDED_BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst_new, [PADDED_BUF_SIZE]); + + declare_func(void, uint8_t *dst, const uint8_t *src, ptrdiff_t size); + + memset(src, 0, PADDED_BUF_SIZE); + memset(dst_ref, 0, PADDED_BUF_SIZE); + memset(dst_new, 0, PADDED_BUF_SIZE); + randomize_buffers(); + call_ref(dst_ref, src, BUF_SIZE); + call_new(dst_new, src, BUF_SIZE); + if (memcmp(dst_ref, dst_new, BUF_SIZE)) + fail(); + bench_new(dst_new, src, BUF_SIZE); +} + +void checkasm_check_exrdsp(void) +{ + ExrDSPContext h; + + ff_exrdsp_init(&h); + + if (check_func(h.reorder_pixels, "reorder_pixels")) + check_reorder_pixels(); + + report("reorder_pixels"); +} diff --git a/tests/fate/checkasm.mak b/tests/fate/checkasm.mak index 824ae2f32d874..7e8623985c42e 100644 --- a/tests/fate/checkasm.mak +++ b/tests/fate/checkasm.mak @@ -3,6 +3,7 @@ FATE_CHECKASM = fate-checkasm-aacpsdsp \ fate-checkasm-audiodsp \ fate-checkasm-blockdsp \ fate-checkasm-bswapdsp \ + fate-checkasm-exrdsp \ fate-checkasm-fixed_dsp \ fate-checkasm-flacdsp \ fate-checkasm-float_dsp \ From 3118e81f86067e8f04d729b070fc90ca2c9090d8 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Mon, 18 Sep 2017 03:24:52 +0200 Subject: [PATCH 3102/3374] lavc/frame_thread_encoder: Do not mix variable declaration and code. Fixes a warning: ISO C90 forbids mixed declarations and code --- libavcodec/frame_thread_encoder.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/frame_thread_encoder.c b/libavcodec/frame_thread_encoder.c index 31a9fe9dae7e4..ffbf5caf29773 100644 --- a/libavcodec/frame_thread_encoder.c +++ b/libavcodec/frame_thread_encoder.c @@ -193,13 +193,14 @@ int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){ for(i=0; ithread_count ; i++){ AVDictionary *tmp = NULL; + int ret; void *tmpv; AVCodecContext *thread_avctx = avcodec_alloc_context3(avctx->codec); if(!thread_avctx) goto fail; tmpv = thread_avctx->priv_data; *thread_avctx = *avctx; - int ret = av_opt_copy(thread_avctx, avctx); + ret = av_opt_copy(thread_avctx, avctx); if (ret < 0) goto fail; thread_avctx->priv_data = tmpv; From 4492237e333c3b5eb57e255d3dba690dcf35940c Mon Sep 17 00:00:00 2001 From: Thomas Mundt Date: Sun, 17 Sep 2017 23:41:00 -0300 Subject: [PATCH 3103/3374] fate: add tinterlace lowpass filtering tests Signed-off-by: James Almer --- tests/fate/filter-video.mak | 6 ++++++ tests/ref/fate/filter-pixfmts-tinterlace_cvlpf | 14 ++++++++++++++ tests/ref/fate/filter-pixfmts-tinterlace_vlpf | 14 ++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 tests/ref/fate/filter-pixfmts-tinterlace_cvlpf create mode 100644 tests/ref/fate/filter-pixfmts-tinterlace_vlpf diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak index 620487872b79a..d1e13414f65bc 100644 --- a/tests/fate/filter-video.mak +++ b/tests/fate/filter-video.mak @@ -668,12 +668,18 @@ fate-filter-pixfmts-super2xsai: CMD = pixfmts FATE_FILTER_PIXFMTS-$(CONFIG_SWAPUV_FILTER) += fate-filter-pixfmts-swapuv fate-filter-pixfmts-swapuv: CMD = pixfmts +FATE_FILTER_PIXFMTS-$(CONFIG_TINTERLACE_FILTER) += fate-filter-pixfmts-tinterlace_cvlpf +fate-filter-pixfmts-tinterlace_cvlpf: CMD = pixfmts "interleave_top:cvlpf" + FATE_FILTER_PIXFMTS-$(CONFIG_TINTERLACE_FILTER) += fate-filter-pixfmts-tinterlace_merge fate-filter-pixfmts-tinterlace_merge: CMD = pixfmts "merge" FATE_FILTER_PIXFMTS-$(CONFIG_TINTERLACE_FILTER) += fate-filter-pixfmts-tinterlace_pad fate-filter-pixfmts-tinterlace_pad: CMD = pixfmts "pad" +FATE_FILTER_PIXFMTS-$(CONFIG_TINTERLACE_FILTER) += fate-filter-pixfmts-tinterlace_vlpf +fate-filter-pixfmts-tinterlace_vlpf: CMD = pixfmts "interleave_top:vlpf" + FATE_FILTER_PIXFMTS-$(CONFIG_VFLIP_FILTER) += fate-filter-pixfmts-vflip fate-filter-pixfmts-vflip: CMD = pixfmts diff --git a/tests/ref/fate/filter-pixfmts-tinterlace_cvlpf b/tests/ref/fate/filter-pixfmts-tinterlace_cvlpf new file mode 100644 index 0000000000000..8623636ff91ac --- /dev/null +++ b/tests/ref/fate/filter-pixfmts-tinterlace_cvlpf @@ -0,0 +1,14 @@ +gray 9849d71519ae9c584ae8abfa8adb2f8e +yuv410p 44ee4b74b95c82d6f79ddf53b5e3aa9d +yuv411p 5fa9d1fba7adfd6f7fa04464332b631a +yuv420p ee9591ea3ab06c73be902c4b8868c69e +yuv422p b1be7b55567bde86d655adf80fac1257 +yuv440p ddf6ee697f4ff4f90d501e6869392309 +yuv444p 7cb5d0c0997c8c2545a16bfc4cb9fd6d +yuva420p ee0761e2f76ec441c545feede77103e4 +yuva422p a8da2806e21a88449079faa7f4303ffa +yuva444p a3f57734d6f72bdf37f8f612ea7cce63 +yuvj420p 9f358e311b694bcd01e1a07d1120ade5 +yuvj422p 9a7628a9f1630d35c7176951ddc1b2f6 +yuvj440p 112fe35292c687746ec0c622a42c611b +yuvj444p f894438f40950229baa02545daa8812a diff --git a/tests/ref/fate/filter-pixfmts-tinterlace_vlpf b/tests/ref/fate/filter-pixfmts-tinterlace_vlpf new file mode 100644 index 0000000000000..2f52fd13f0994 --- /dev/null +++ b/tests/ref/fate/filter-pixfmts-tinterlace_vlpf @@ -0,0 +1,14 @@ +gray b79791449947c25cd5b36d9d3b9d1831 +yuv410p 5bc03f4cf6b441b421f0fdaeeff1e9ed +yuv411p 19046df1876c46ed1ef0458680270bd3 +yuv420p 69c743b84996be9430b051a55cfbcb29 +yuv422p d710ccd1941f6f389c97a09bc977e709 +yuv440p 1a482a23fe5a9b7d02388c299fd0a423 +yuv444p c968a92f4b7ab6706ee9b425eb5345b5 +yuva420p 3f89a166f309c0cda8b91a9e8a0ce937 +yuva422p ef8fdbe910d68e88e98227b0e99fb5a6 +yuva444p 3662eadd5f61a6edbc9d715ea8591415 +yuvj420p 14c4390b319c5d679184503309060ac3 +yuvj422p bbe00a26526931b72a024febe1cd6b90 +yuvj440p f654cf28b7879c6a6c950c3cb9612580 +yuvj444p c162a4fe7a665f4abf257443703f0d72 From 3af1060319b46005dbfb3b01f9104539caf30146 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sun, 17 Sep 2017 23:41:31 -0300 Subject: [PATCH 3104/3374] avfilter/tinterlace: Simplify checks for lowpass filtering flags --- libavfilter/vf_tinterlace.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/libavfilter/vf_tinterlace.c b/libavfilter/vf_tinterlace.c index 66c6d17ed9b1e..9ae9daafc151e 100644 --- a/libavfilter/vf_tinterlace.c +++ b/libavfilter/vf_tinterlace.c @@ -172,14 +172,12 @@ static int config_out_props(AVFilterLink *outlink) tinterlace->black_linesize[i] * h); } } - if ((tinterlace->flags & TINTERLACE_FLAG_VLPF - || tinterlace->flags & TINTERLACE_FLAG_CVLPF) + if (tinterlace->flags & (TINTERLACE_FLAG_VLPF | TINTERLACE_FLAG_CVLPF) && !(tinterlace->mode == MODE_INTERLEAVE_TOP || tinterlace->mode == MODE_INTERLEAVE_BOTTOM)) { av_log(ctx, AV_LOG_WARNING, "low_pass_filter flags ignored with mode %d\n", tinterlace->mode); - tinterlace->flags &= ~TINTERLACE_FLAG_VLPF; - tinterlace->flags &= ~TINTERLACE_FLAG_CVLPF; + tinterlace->flags &= ~(TINTERLACE_FLAG_VLPF | TINTERLACE_FLAG_CVLPF); } tinterlace->preout_time_base = inlink->time_base; if (tinterlace->mode == MODE_INTERLACEX2) { @@ -263,10 +261,8 @@ void copy_picture_field(TInterlaceContext *tinterlace, // Low-pass filtering is required when creating an interlaced destination from // a progressive source which contains high-frequency vertical detail. // Filtering will reduce interlace 'twitter' and Moire patterning. - if (flags & TINTERLACE_FLAG_VLPF || flags & TINTERLACE_FLAG_CVLPF) { - int x = 0; - if (flags & TINTERLACE_FLAG_CVLPF) - x = 1; + if (flags & (TINTERLACE_FLAG_VLPF | TINTERLACE_FLAG_CVLPF)) { + int x = !!(flags & TINTERLACE_FLAG_CVLPF); for (h = lines; h > 0; h--) { ptrdiff_t pref = src_linesize[plane]; ptrdiff_t mref = -pref; From 35d6be199a55e906b517fdf561841d43cdd81e2a Mon Sep 17 00:00:00 2001 From: Tobias Rapp Date: Thu, 14 Sep 2017 14:03:28 +0200 Subject: [PATCH 3105/3374] avformat/mxfenc: fix aspect ratio when writing 16:9 DV frames Signed-off-by: Tobias Rapp --- libavformat/mxfenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index 7289e0b05b3b3..da4d7b4e8e848 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -1810,7 +1810,7 @@ static int mxf_parse_dv_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt) stype = vs_pack[3] & 0x1f; pal = (vs_pack[3] >> 5) & 0x1; - if ((vs_pack[2] & 0x07) == 0x02) + if ((vsc_pack[2] & 0x07) == 0x02) sc->aspect_ratio = (AVRational){ 16, 9 }; else sc->aspect_ratio = (AVRational){ 4, 3 }; From 147bface1a56385917515ce264ab28c6f1407a61 Mon Sep 17 00:00:00 2001 From: Tobias Rapp Date: Thu, 14 Sep 2017 15:23:04 +0200 Subject: [PATCH 3106/3374] fate: add mxf_dv25/dvcpro50 regression tests Signed-off-by: Tobias Rapp --- tests/fate/avformat.mak | 2 ++ tests/fate/seek.mak | 4 +++ tests/lavf-regression.sh | 8 +++++ tests/ref/lavf/mxf_dv25 | 3 ++ tests/ref/lavf/mxf_dvcpro50 | 3 ++ tests/ref/seek/lavf-mxf_dv25 | 53 ++++++++++++++++++++++++++++++++ tests/ref/seek/lavf-mxf_dvcpro50 | 53 ++++++++++++++++++++++++++++++++ 7 files changed, 126 insertions(+) create mode 100644 tests/ref/lavf/mxf_dv25 create mode 100644 tests/ref/lavf/mxf_dvcpro50 create mode 100644 tests/ref/seek/lavf-mxf_dv25 create mode 100644 tests/ref/seek/lavf-mxf_dvcpro50 diff --git a/tests/fate/avformat.mak b/tests/fate/avformat.mak index f65ef76648fb0..c9ea99ad1b1fa 100644 --- a/tests/fate/avformat.mak +++ b/tests/fate/avformat.mak @@ -25,6 +25,8 @@ FATE_LAVF-$(call ENCDEC2, MPEG1VIDEO, MP2, MPEG1SYSTEM MPEGPS) += mpg FATE_LAVF-$(call ENCDEC, PCM_MULAW, PCM_MULAW) += mulaw FATE_LAVF-$(call ENCDEC2, MPEG2VIDEO, PCM_S16LE, MXF) += mxf FATE_LAVF-$(call ENCDEC2, MPEG2VIDEO, PCM_S16LE, MXF_D10 MXF) += mxf_d10 +FATE_LAVF-$(call ENCDEC2, DVVIDEO, PCM_S16LE, MXF) += mxf_dv25 +FATE_LAVF-$(call ENCDEC2, DVVIDEO, PCM_S16LE, MXF) += mxf_dvcpro50 FATE_LAVF-$(call ENCDEC2, DNXHD, PCM_S16LE, MXF_OPATOM MXF) += mxf_opatom FATE_LAVF-$(call ENCDEC2, DNXHD, PCM_S16LE, MXF_OPATOM MXF) += mxf_opatom_audio FATE_LAVF-$(call ENCDEC2, MPEG4, MP2, NUT) += nut diff --git a/tests/fate/seek.mak b/tests/fate/seek.mak index 1a6e584987052..c863b2aaa454b 100644 --- a/tests/fate/seek.mak +++ b/tests/fate/seek.mak @@ -180,6 +180,8 @@ FATE_SEEK_LAVF-$(call ENCDEC2, MPEG1VIDEO, MP2, MPEG1SYSTEM MPEGPS) += mpg FATE_SEEK_LAVF-$(call ENCDEC, PCM_MULAW, PCM_MULAW) += mulaw FATE_SEEK_LAVF-$(call ENCDEC2, MPEG2VIDEO, PCM_S16LE, MXF) += mxf FATE_SEEK_LAVF-$(call ENCDEC2, MPEG2VIDEO, PCM_S16LE, MXF_D10 MXF) += mxf_d10 +FATE_SEEK_LAVF-$(call ENCDEC2, DVVIDEO, PCM_S16LE, MXF) += mxf_dv25 +FATE_SEEK_LAVF-$(call ENCDEC2, DVVIDEO, PCM_S16LE, MXF) += mxf_dvcpro50 FATE_SEEK_LAVF-$(call ENCDEC2, DNXHD, PCM_S16LE, MXF_OPATOM MXF) += mxf_opatom FATE_SEEK_LAVF-$(call ENCDEC2, DNXHD, PCM_S16LE, MXF_OPATOM MXF) += mxf_opatom_audio FATE_SEEK_LAVF-$(call ENCDEC2, MPEG4, MP2, NUT) += nut @@ -220,6 +222,8 @@ fate-seek-lavf-mpg: SRC = lavf/lavf.mpg fate-seek-lavf-mulaw: SRC = lavf/lavf.ul fate-seek-lavf-mxf: SRC = lavf/lavf.mxf fate-seek-lavf-mxf_d10: SRC = lavf/lavf.mxf_d10 +fate-seek-lavf-mxf_dv25: SRC = lavf/lavf.mxf_dv25 +fate-seek-lavf-mxf_dvcpro50: SRC = lavf/lavf.mxf_dvcpro50 fate-seek-lavf-mxf_opatom: SRC = lavf/lavf.mxf_opatom fate-seek-lavf-mxf_opatom_audio: SRC = lavf/lavf.mxf_opatom_audio fate-seek-lavf-nut: SRC = lavf/lavf.nut diff --git a/tests/lavf-regression.sh b/tests/lavf-regression.sh index d9026de021ad2..45c877e4ac14a 100755 --- a/tests/lavf-regression.sh +++ b/tests/lavf-regression.sh @@ -90,6 +90,14 @@ if [ -n "$do_mxf_d10" ]; then do_lavf mxf_d10 "-ar 48000 -ac 2" "-r 25 -vf scale=720:576,pad=720:608:0:32 -vcodec mpeg2video -g 0 -flags +ildct+low_delay -dc 10 -non_linear_quant 1 -intra_vlc 1 -qscale 1 -ps 1 -qmin 1 -rc_max_vbv_use 1 -rc_min_vbv_use 1 -pix_fmt yuv422p -minrate 30000k -maxrate 30000k -b 30000k -bufsize 1200000 -top 1 -rc_init_occupancy 1200000 -qmax 12 -f mxf_d10" fi +if [ -n "$do_mxf_dv25" ]; then +do_lavf mxf_dv25 "-ar 48000 -ac 2" "-r 25 -vf scale=720:576,setdar=4/3 -vcodec dvvideo -pix_fmt yuv420p -b 25000k -top 0 -f mxf" +fi + +if [ -n "$do_mxf_dvcpro50" ]; then +do_lavf mxf_dvcpro50 "-ar 48000 -ac 2" "-r 25 -vf scale=720:576,setdar=16/9 -vcodec dvvideo -pix_fmt yuv422p -b 50000k -top 0 -f mxf" +fi + if [ -n "$do_mxf_opatom" ]; then do_lavf mxf_opatom "" "-s 1920x1080 -vcodec dnxhd -pix_fmt yuv422p -vb 36M -f mxf_opatom -map 0" fi diff --git a/tests/ref/lavf/mxf_dv25 b/tests/ref/lavf/mxf_dv25 new file mode 100644 index 0000000000000..adecc07e70cda --- /dev/null +++ b/tests/ref/lavf/mxf_dv25 @@ -0,0 +1,3 @@ +de98603ecc27c2f3cefd192d4820d3f4 *./tests/data/lavf/lavf.mxf_dv25 +3833389 ./tests/data/lavf/lavf.mxf_dv25 +./tests/data/lavf/lavf.mxf_dv25 CRC=0xbdaf7f52 diff --git a/tests/ref/lavf/mxf_dvcpro50 b/tests/ref/lavf/mxf_dvcpro50 new file mode 100644 index 0000000000000..1d0cf79996196 --- /dev/null +++ b/tests/ref/lavf/mxf_dvcpro50 @@ -0,0 +1,3 @@ +6c9cb62911ac16c3b55f0ad0b052c05b *./tests/data/lavf/lavf.mxf_dvcpro50 +7430189 ./tests/data/lavf/lavf.mxf_dvcpro50 +./tests/data/lavf/lavf.mxf_dvcpro50 CRC=0xe3bbe4b4 diff --git a/tests/ref/seek/lavf-mxf_dv25 b/tests/ref/seek/lavf-mxf_dv25 new file mode 100644 index 0000000000000..42b3bbdfce9c9 --- /dev/null +++ b/tests/ref/seek/lavf-mxf_dv25 @@ -0,0 +1,53 @@ +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:144000 +ret: 0 st:-1 flags:0 ts:-1.000000 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:144000 +ret: 0 st:-1 flags:1 ts: 1.894167 +ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3680256 size:144000 +ret: 0 st: 0 flags:0 ts: 0.800000 +ret: 0 st: 0 flags:1 dts: 0.800000 pts: 0.800000 pos:3067904 size:144000 +ret: 0 st: 0 flags:1 ts:-0.320000 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:144000 +ret: 0 st: 1 flags:0 ts: 2.576667 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:3680256 size:144000 +ret: 0 st: 1 flags:1 ts: 1.470833 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:3680256 size:144000 +ret: 0 st:-1 flags:0 ts: 0.365002 +ret: 0 st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos:1383936 size:144000 +ret: 0 st:-1 flags:1 ts:-0.740831 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:144000 +ret: 0 st: 0 flags:0 ts: 2.160000 +ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3680256 size:144000 +ret: 0 st: 0 flags:1 ts: 1.040000 +ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3680256 size:144000 +ret: 0 st: 1 flags:0 ts:-0.058333 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:144000 +ret: 0 st: 1 flags:1 ts: 2.835833 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:3680256 size:144000 +ret: 0 st:-1 flags:0 ts: 1.730004 +ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3680256 size:144000 +ret: 0 st:-1 flags:1 ts: 0.624171 +ret: 0 st: 0 flags:1 dts: 0.640000 pts: 0.640000 pos:2455552 size:144000 +ret: 0 st: 0 flags:0 ts:-0.480000 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:144000 +ret: 0 st: 0 flags:1 ts: 2.400000 +ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3680256 size:144000 +ret: 0 st: 1 flags:0 ts: 1.306667 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:3680256 size:144000 +ret: 0 st: 1 flags:1 ts: 0.200833 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 771584 size:144000 +ret: 0 st:-1 flags:0 ts:-0.904994 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:144000 +ret: 0 st:-1 flags:1 ts: 1.989173 +ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3680256 size:144000 +ret: 0 st: 0 flags:0 ts: 0.880000 +ret: 0 st: 0 flags:1 dts: 0.880000 pts: 0.880000 pos:3374080 size:144000 +ret: 0 st: 0 flags:1 ts:-0.240000 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:144000 +ret: 0 st: 1 flags:0 ts: 2.671667 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:3680256 size:144000 +ret: 0 st: 1 flags:1 ts: 1.565833 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:3680256 size:144000 +ret: 0 st:-1 flags:0 ts: 0.460008 +ret: 0 st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:1843200 size:144000 +ret: 0 st:-1 flags:1 ts:-0.645825 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:144000 diff --git a/tests/ref/seek/lavf-mxf_dvcpro50 b/tests/ref/seek/lavf-mxf_dvcpro50 new file mode 100644 index 0000000000000..c3d9d3afd72d9 --- /dev/null +++ b/tests/ref/seek/lavf-mxf_dvcpro50 @@ -0,0 +1,53 @@ +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:288000 +ret: 0 st:-1 flags:0 ts:-1.000000 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:288000 +ret: 0 st:-1 flags:1 ts: 1.894167 +ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:7133184 size:288000 +ret: 0 st: 0 flags:0 ts: 0.800000 +ret: 0 st: 0 flags:1 dts: 0.800000 pts: 0.800000 pos:5945344 size:288000 +ret: 0 st: 0 flags:1 ts:-0.320000 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:288000 +ret: 0 st: 1 flags:0 ts: 2.576667 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:7133184 size:288000 +ret: 0 st: 1 flags:1 ts: 1.470833 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:7133184 size:288000 +ret: 0 st:-1 flags:0 ts: 0.365002 +ret: 0 st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos:2678784 size:288000 +ret: 0 st:-1 flags:1 ts:-0.740831 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:288000 +ret: 0 st: 0 flags:0 ts: 2.160000 +ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:7133184 size:288000 +ret: 0 st: 0 flags:1 ts: 1.040000 +ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:7133184 size:288000 +ret: 0 st: 1 flags:0 ts:-0.058333 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:288000 +ret: 0 st: 1 flags:1 ts: 2.835833 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:7133184 size:288000 +ret: 0 st:-1 flags:0 ts: 1.730004 +ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:7133184 size:288000 +ret: 0 st:-1 flags:1 ts: 0.624171 +ret: 0 st: 0 flags:1 dts: 0.640000 pts: 0.640000 pos:4757504 size:288000 +ret: 0 st: 0 flags:0 ts:-0.480000 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:288000 +ret: 0 st: 0 flags:1 ts: 2.400000 +ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:7133184 size:288000 +ret: 0 st: 1 flags:0 ts: 1.306667 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:7133184 size:288000 +ret: 0 st: 1 flags:1 ts: 0.200833 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:1490944 size:288000 +ret: 0 st:-1 flags:0 ts:-0.904994 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:288000 +ret: 0 st:-1 flags:1 ts: 1.989173 +ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:7133184 size:288000 +ret: 0 st: 0 flags:0 ts: 0.880000 +ret: 0 st: 0 flags:1 dts: 0.880000 pts: 0.880000 pos:6539264 size:288000 +ret: 0 st: 0 flags:1 ts:-0.240000 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:288000 +ret: 0 st: 1 flags:0 ts: 2.671667 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:7133184 size:288000 +ret: 0 st: 1 flags:1 ts: 1.565833 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:7133184 size:288000 +ret: 0 st:-1 flags:0 ts: 0.460008 +ret: 0 st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:3569664 size:288000 +ret: 0 st:-1 flags:1 ts:-0.645825 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:288000 From 3ffd3b7f5f13080cdba7e8d6b5d9dd7c33ff2345 Mon Sep 17 00:00:00 2001 From: Tobias Rapp Date: Thu, 14 Sep 2017 16:05:31 +0200 Subject: [PATCH 3107/3374] avformat/mxfenc: cosmetic changes Signed-off-by: Tobias Rapp --- libavformat/mxfenc.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index da4d7b4e8e848..b8d3030c40316 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -846,7 +846,7 @@ static void mxf_write_track(AVFormatContext *s, AVStream *st, enum MXFMetadataSe // write edit rate mxf_write_local_tag(pb, 8, 0x4B01); - if (st == mxf->timecode_track && s->oformat == &ff_mxf_opatom_muxer){ + if (st == mxf->timecode_track && s->oformat == &ff_mxf_opatom_muxer) { avio_wb32(pb, mxf->tc.rate.num); avio_wb32(pb, mxf->tc.rate.den); } else { @@ -882,7 +882,7 @@ static void mxf_write_common_fields(AVFormatContext *s, AVStream *st) // write duration mxf_write_local_tag(pb, 8, 0x0202); - if (st != mxf->timecode_track && s->oformat == &ff_mxf_opatom_muxer && st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO){ + if (st != mxf->timecode_track && s->oformat == &ff_mxf_opatom_muxer && st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { avio_wb64(pb, mxf->body_offset / mxf->edit_unit_byte_count); } else { avio_wb64(pb, mxf->duration); @@ -1194,7 +1194,7 @@ static void mxf_write_generic_sound_common(AVFormatContext *s, AVStream *st, con mxf_write_generic_desc(s, st, key, size+duration_size+5+12+8+8); - if (duration_size > 0){ + if (duration_size > 0) { mxf_write_local_tag(pb, 8, 0x3002); avio_wb64(pb, mxf->body_offset / mxf->edit_unit_byte_count); } @@ -1328,7 +1328,7 @@ static void mxf_write_package(AVFormatContext *s, enum MXFMetadataSetType type, // write uid mxf_write_local_tag(pb, 16, 0x3C0A); mxf_write_uuid(pb, type, 0); - av_log(s,AV_LOG_DEBUG, "package type:%d\n", type); + av_log(s, AV_LOG_DEBUG, "package type:%d\n", type); PRINT_KEY(s, "package uid", pb->buf_ptr - 16); // write package umid @@ -1770,7 +1770,7 @@ AVPacket *pkt) sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul; sc->aspect_ratio = (AVRational){ 16, 9 }; - if(s->oformat == &ff_mxf_opatom_muxer){ + if (s->oformat == &ff_mxf_opatom_muxer) { mxf->edit_unit_byte_count = frame_size; return 1; } @@ -1810,10 +1810,11 @@ static int mxf_parse_dv_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt) stype = vs_pack[3] & 0x1f; pal = (vs_pack[3] >> 5) & 0x1; - if ((vsc_pack[2] & 0x07) == 0x02) + if ((vsc_pack[2] & 0x07) == 0x02) { sc->aspect_ratio = (AVRational){ 16, 9 }; - else + } else { sc->aspect_ratio = (AVRational){ 4, 3 }; + } sc->interlaced = (vsc_pack[3] >> 4) & 0x01; // TODO: fix dv encoder to set proper FF/FS value in VSC pack @@ -2097,7 +2098,7 @@ static int mxf_write_header(AVFormatContext *s) if (!s->nb_streams) return -1; - if (s->oformat == &ff_mxf_opatom_muxer && s->nb_streams !=1){ + if (s->oformat == &ff_mxf_opatom_muxer && s->nb_streams !=1) { av_log(s, AV_LOG_ERROR, "there must be exactly one stream for mxf opatom\n"); return -1; } @@ -2212,7 +2213,7 @@ static int mxf_write_header(AVFormatContext *s) } spf = ff_mxf_get_samples_per_frame(s, tbc); - if (!spf){ + if (!spf) { av_log(s, AV_LOG_ERROR, "Unsupported timecode frame rate %d/%d\n", tbc.den, tbc.num); return AVERROR(EINVAL); } @@ -2605,7 +2606,7 @@ static int mxf_write_footer(AVFormatContext *s) mxf_write_random_index_pack(s); if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) { - if (s->oformat == &ff_mxf_opatom_muxer){ + if (s->oformat == &ff_mxf_opatom_muxer) { /* rewrite body partition to update lengths */ avio_seek(pb, mxf->body_partition_offset[0], SEEK_SET); if ((err = mxf_write_opatom_body_partition(s)) < 0) From 18821e3ba1baa8e0fe037e11c77459ebc73f7e37 Mon Sep 17 00:00:00 2001 From: Henrik Gramner Date: Sun, 17 Sep 2017 22:52:13 -0300 Subject: [PATCH 3108/3374] x86/exrdsp: optimize ff_reorder_pixels_avx2() Tested with "checkasm --test=exrdsp -bench" Before: reorder_pixels_c: 5187.8 reorder_pixels_sse2: 377.0 reorder_pixels_avx2: 331.3 After: reorder_pixels_c: 5181.5 reorder_pixels_sse2: 377.0 reorder_pixels_avx2: 313.8 Signed-off-by: James Almer --- libavcodec/x86/exrdsp.asm | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/libavcodec/x86/exrdsp.asm b/libavcodec/x86/exrdsp.asm index b91a7be20d5bd..06c629e59eef9 100644 --- a/libavcodec/x86/exrdsp.asm +++ b/libavcodec/x86/exrdsp.asm @@ -39,16 +39,15 @@ cglobal reorder_pixels, 3,4,3, dst, src1, size, src2 neg sizeq ; size = offset for dst, src1, src2 .loop: -%if cpuflag(avx2) - vpermq m0, [src1q + sizeq], 0xd8; load first part - vpermq m1, [src2q + sizeq], 0xd8; load second part -%else mova m0, [src1q+sizeq] ; load first part movu m1, [src2q+sizeq] ; load second part -%endif SBUTTERFLY bw, 0, 1, 2 ; interleaved - mova [dstq+2*sizeq ], m0 ; copy to dst - mova [dstq+2*sizeq+mmsize], m1 + mova [dstq+2*sizeq ], xm0 ; copy to dst + mova [dstq+2*sizeq+16], xm1 +%if cpuflag(avx2) + vperm2i128 m0, m0, m1, q0301 + mova [dstq+2*sizeq+32], m0 +%endif add sizeq, mmsize jl .loop RET From b4ecf2b582f34ff898017836b7df865e6ad9ce92 Mon Sep 17 00:00:00 2001 From: Hendrik Leppkes Date: Tue, 19 Sep 2017 10:45:41 +0200 Subject: [PATCH 3109/3374] vp9: move VP9SharedContext back to the top of VP9Context VP9SharedContext needs to be the first member so its properties can be safely accessed from hardware accelerators, without the need to share the full VP9Context. Fixes ticket #6674. --- libavcodec/vp9dec.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vp9dec.h b/libavcodec/vp9dec.h index 96c0e43cd2dae..66573edc7911d 100644 --- a/libavcodec/vp9dec.h +++ b/libavcodec/vp9dec.h @@ -89,8 +89,8 @@ typedef struct VP9Block { typedef struct VP9TileData VP9TileData; typedef struct VP9Context { - VP9TileData *td; VP9SharedContext s; + VP9TileData *td; VP9DSPContext dsp; VideoDSPContext vdsp; From 375cf55fe9f574e42bd3519f08993125ac66c725 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Thu, 14 Sep 2017 22:11:45 +0100 Subject: [PATCH 3110/3374] vaapi: Disable deprecation warnings around use of old struct vaapi_context --- libavcodec/vaapi_decode.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/vaapi_decode.h b/libavcodec/vaapi_decode.h index 4fe414c504e05..550ee0543252a 100644 --- a/libavcodec/vaapi_decode.h +++ b/libavcodec/vaapi_decode.h @@ -59,9 +59,11 @@ typedef struct VAAPIDecodeContext { VAContextID va_context; #if FF_API_STRUCT_VAAPI_CONTEXT +FF_DISABLE_DEPRECATION_WARNINGS int have_old_context; struct vaapi_context *old_context; AVBufferRef *device_ref; +FF_ENABLE_DEPRECATION_WARNINGS #endif AVHWDeviceContext *device; From 22afa87a8e90c83d736400bf8fd6bb19152defaf Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Fri, 15 Sep 2017 20:48:18 +0100 Subject: [PATCH 3111/3374] kmsgrab: Fix DRM format definitions All DRM formats are defined in terms of little-endian words, so RGB formats like XRGB actually have the elements in the opposite order order in memory to the order they are in the name. This does not affect YUYV and similar YUV 4:2:2 formats, which are in the expected order. --- libavdevice/kmsgrab.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libavdevice/kmsgrab.c b/libavdevice/kmsgrab.c index 67a83ef84aa91..bcb6865f60a5c 100644 --- a/libavdevice/kmsgrab.c +++ b/libavdevice/kmsgrab.c @@ -210,14 +210,14 @@ static const struct { #endif { AV_PIX_FMT_RGB24, DRM_FORMAT_RGB888 }, { AV_PIX_FMT_BGR24, DRM_FORMAT_BGR888 }, - { AV_PIX_FMT_0RGB, DRM_FORMAT_XRGB8888 }, - { AV_PIX_FMT_0BGR, DRM_FORMAT_XBGR8888 }, - { AV_PIX_FMT_RGB0, DRM_FORMAT_RGBX8888 }, - { AV_PIX_FMT_BGR0, DRM_FORMAT_BGRX8888 }, - { AV_PIX_FMT_ARGB, DRM_FORMAT_ARGB8888 }, - { AV_PIX_FMT_ABGR, DRM_FORMAT_ABGR8888 }, - { AV_PIX_FMT_RGBA, DRM_FORMAT_RGBA8888 }, - { AV_PIX_FMT_BGRA, DRM_FORMAT_BGRA8888 }, + { AV_PIX_FMT_0RGB, DRM_FORMAT_BGRX8888 }, + { AV_PIX_FMT_0BGR, DRM_FORMAT_RGBX8888 }, + { AV_PIX_FMT_RGB0, DRM_FORMAT_XBGR8888 }, + { AV_PIX_FMT_BGR0, DRM_FORMAT_XRGB8888 }, + { AV_PIX_FMT_ARGB, DRM_FORMAT_BGRA8888 }, + { AV_PIX_FMT_ABGR, DRM_FORMAT_RGBA8888 }, + { AV_PIX_FMT_RGBA, DRM_FORMAT_ABGR8888 }, + { AV_PIX_FMT_BGRA, DRM_FORMAT_ARGB8888 }, { AV_PIX_FMT_YUYV422, DRM_FORMAT_YUYV }, { AV_PIX_FMT_YVYU422, DRM_FORMAT_YVYU }, { AV_PIX_FMT_UYVY422, DRM_FORMAT_UYVY }, From 9f9625ea80acf4b7272f740f7b2c15cebf96d09b Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Fri, 15 Sep 2017 20:54:26 +0100 Subject: [PATCH 3112/3374] kmsgrab: Remove multiple-plane formats The planes are unlikely to be contiguous, assuming they are results in very broken output. (Tested with NV12/NV16 on Rockchip.) --- libavdevice/kmsgrab.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libavdevice/kmsgrab.c b/libavdevice/kmsgrab.c index bcb6865f60a5c..e54534006eef0 100644 --- a/libavdevice/kmsgrab.c +++ b/libavdevice/kmsgrab.c @@ -221,10 +221,6 @@ static const struct { { AV_PIX_FMT_YUYV422, DRM_FORMAT_YUYV }, { AV_PIX_FMT_YVYU422, DRM_FORMAT_YVYU }, { AV_PIX_FMT_UYVY422, DRM_FORMAT_UYVY }, - { AV_PIX_FMT_NV12, DRM_FORMAT_NV12 }, - { AV_PIX_FMT_YUV420P, DRM_FORMAT_YUV420 }, - { AV_PIX_FMT_YUV422P, DRM_FORMAT_YUV422 }, - { AV_PIX_FMT_YUV444P, DRM_FORMAT_YUV444 }, }; static av_cold int kmsgrab_read_header(AVFormatContext *avctx) From b0ece2b31fdf6914bf31d02b7e5a007095d436d3 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Fri, 15 Sep 2017 21:05:49 +0100 Subject: [PATCH 3113/3374] hwcontext_vaapi: Fix DRM format mapping --- libavutil/hwcontext_vaapi.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index 852f0abda2bb0..c4473a229fe2d 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -925,16 +925,16 @@ static const struct { #if defined(VA_FOURCC_P010) && defined(DRM_FORMAT_R16) DRM_MAP(P010, 2, DRM_FORMAT_R16, DRM_FORMAT_RG1616), #endif - DRM_MAP(BGRA, 1, DRM_FORMAT_BGRA8888), - DRM_MAP(BGRX, 1, DRM_FORMAT_BGRX8888), - DRM_MAP(RGBA, 1, DRM_FORMAT_RGBA8888), - DRM_MAP(RGBX, 1, DRM_FORMAT_RGBX8888), + DRM_MAP(BGRA, 1, DRM_FORMAT_ARGB8888), + DRM_MAP(BGRX, 1, DRM_FORMAT_XRGB8888), + DRM_MAP(RGBA, 1, DRM_FORMAT_ABGR8888), + DRM_MAP(RGBX, 1, DRM_FORMAT_XBGR8888), #ifdef VA_FOURCC_ABGR - DRM_MAP(ABGR, 1, DRM_FORMAT_ABGR8888), - DRM_MAP(XBGR, 1, DRM_FORMAT_XBGR8888), + DRM_MAP(ABGR, 1, DRM_FORMAT_RGBA8888), + DRM_MAP(XBGR, 1, DRM_FORMAT_RGBX8888), #endif - DRM_MAP(ARGB, 1, DRM_FORMAT_ARGB8888), - DRM_MAP(XRGB, 1, DRM_FORMAT_XRGB8888), + DRM_MAP(ARGB, 1, DRM_FORMAT_BGRA8888), + DRM_MAP(XRGB, 1, DRM_FORMAT_BGRX8888), }; #undef DRM_MAP From f952edaa73ee8618fcc8c105b57b9032ca0d1cec Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Fri, 15 Sep 2017 21:24:48 +0100 Subject: [PATCH 3114/3374] kmsgrab: Add more DRM plane formats --- libavdevice/kmsgrab.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libavdevice/kmsgrab.c b/libavdevice/kmsgrab.c index e54534006eef0..11f23d8af7204 100644 --- a/libavdevice/kmsgrab.c +++ b/libavdevice/kmsgrab.c @@ -207,7 +207,18 @@ static const struct { #endif #ifdef DRM_FORMAT_R16 { AV_PIX_FMT_GRAY16LE, DRM_FORMAT_R16 }, + { AV_PIX_FMT_GRAY16BE, DRM_FORMAT_R16 | DRM_FORMAT_BIG_ENDIAN }, #endif + { AV_PIX_FMT_RGB8, DRM_FORMAT_RGB332 }, + { AV_PIX_FMT_BGR8, DRM_FORMAT_BGR233 }, + { AV_PIX_FMT_RGB555LE, DRM_FORMAT_XRGB1555 }, + { AV_PIX_FMT_RGB555BE, DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN }, + { AV_PIX_FMT_BGR555LE, DRM_FORMAT_XBGR1555 }, + { AV_PIX_FMT_BGR555BE, DRM_FORMAT_XBGR1555 | DRM_FORMAT_BIG_ENDIAN }, + { AV_PIX_FMT_RGB565LE, DRM_FORMAT_RGB565 }, + { AV_PIX_FMT_RGB565BE, DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN }, + { AV_PIX_FMT_BGR565LE, DRM_FORMAT_BGR565 }, + { AV_PIX_FMT_BGR565BE, DRM_FORMAT_BGR565 | DRM_FORMAT_BIG_ENDIAN }, { AV_PIX_FMT_RGB24, DRM_FORMAT_RGB888 }, { AV_PIX_FMT_BGR24, DRM_FORMAT_BGR888 }, { AV_PIX_FMT_0RGB, DRM_FORMAT_BGRX8888 }, From 18516d3e695980525bd9758dc7b8a8e36cd3f09e Mon Sep 17 00:00:00 2001 From: James Almer Date: Sun, 17 Sep 2017 00:17:42 -0300 Subject: [PATCH 3115/3374] avutil/hwcontext_dxva2: return an error when buffer allocation fails This also prevents the use of an uninitialized variable. Reviewed-by: Mark Thompson Signed-off-by: James Almer --- libavutil/hwcontext_dxva2.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavutil/hwcontext_dxva2.c b/libavutil/hwcontext_dxva2.c index 6c41788e2e99e..2ddd4be7b1df8 100644 --- a/libavutil/hwcontext_dxva2.c +++ b/libavutil/hwcontext_dxva2.c @@ -307,8 +307,10 @@ static int dxva2_map_frame(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame * } map = av_mallocz(sizeof(*map)); - if (!map) + if (!map) { + err = AVERROR(ENOMEM); goto fail; + } err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, dxva2_unmap_frame, map); From 5cb70381d99505af00b11721165b63560b95f1cc Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Wed, 20 Sep 2017 00:56:29 +0200 Subject: [PATCH 3116/3374] lavd/kmsgrab: Remove the mapping for AV_PIX_FMT_RGB8. The definitions are different: 3:3:2 vs 2:3:3. --- libavdevice/kmsgrab.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libavdevice/kmsgrab.c b/libavdevice/kmsgrab.c index 11f23d8af7204..6a6de09c3763b 100644 --- a/libavdevice/kmsgrab.c +++ b/libavdevice/kmsgrab.c @@ -209,7 +209,6 @@ static const struct { { AV_PIX_FMT_GRAY16LE, DRM_FORMAT_R16 }, { AV_PIX_FMT_GRAY16BE, DRM_FORMAT_R16 | DRM_FORMAT_BIG_ENDIAN }, #endif - { AV_PIX_FMT_RGB8, DRM_FORMAT_RGB332 }, { AV_PIX_FMT_BGR8, DRM_FORMAT_BGR233 }, { AV_PIX_FMT_RGB555LE, DRM_FORMAT_XRGB1555 }, { AV_PIX_FMT_RGB555BE, DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN }, From 2f3a3a7e3270d9c4486fc4d1ed708c2f54338f9c Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Sun, 17 Sep 2017 23:34:58 +0200 Subject: [PATCH 3117/3374] lavf/utils: Do not force chapter end time before chapter start. Fixes ticket #6671. --- libavformat/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/utils.c b/libavformat/utils.c index 23865c88c43d9..7abca632b56ff 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -3167,7 +3167,7 @@ static void compute_chapters_end(AVFormatContext *s) if (j != i && next_start > ch->start && next_start < end) end = next_start; } - ch->end = (end == INT64_MAX) ? ch->start : end; + ch->end = (end == INT64_MAX || end < ch->start) ? ch->start : end; } } From b4b02477bd8029daca389ec745bbb46457b74b5c Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Mon, 18 Sep 2017 23:10:06 +0200 Subject: [PATCH 3118/3374] lavfi/stereo3d: Set SAR for every output frame. Fixes ticket #6672. --- libavfilter/vf_stereo3d.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/libavfilter/vf_stereo3d.c b/libavfilter/vf_stereo3d.c index 3e23890208c56..8b22f880ca668 100644 --- a/libavfilter/vf_stereo3d.c +++ b/libavfilter/vf_stereo3d.c @@ -150,6 +150,7 @@ typedef struct Stereo3DContext { AVFrame *prev; int blanks; int in_off_left[4], in_off_right[4]; + AVRational aspect; Stereo3DDSPContext dsp; } Stereo3DContext; @@ -359,11 +360,11 @@ static int config_output(AVFilterLink *outlink) AVFilterContext *ctx = outlink->src; AVFilterLink *inlink = ctx->inputs[0]; Stereo3DContext *s = ctx->priv; - AVRational aspect = inlink->sample_aspect_ratio; AVRational fps = inlink->frame_rate; AVRational tb = inlink->time_base; const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(outlink->format); int ret; + s->aspect = inlink->sample_aspect_ratio; switch (s->in.format) { case INTERLEAVE_COLS_LR: @@ -404,25 +405,25 @@ static int config_output(AVFilterLink *outlink) switch (s->in.format) { case SIDE_BY_SIDE_2_LR: - aspect.num *= 2; + s->aspect.num *= 2; case SIDE_BY_SIDE_LR: s->width = inlink->w / 2; s->in.off_right = s->width; break; case SIDE_BY_SIDE_2_RL: - aspect.num *= 2; + s->aspect.num *= 2; case SIDE_BY_SIDE_RL: s->width = inlink->w / 2; s->in.off_left = s->width; break; case ABOVE_BELOW_2_LR: - aspect.den *= 2; + s->aspect.den *= 2; case ABOVE_BELOW_LR: s->in.row_right = s->height = inlink->h / 2; break; case ABOVE_BELOW_2_RL: - aspect.den *= 2; + s->aspect.den *= 2; case ABOVE_BELOW_RL: s->in.row_left = s->height = inlink->h / 2; @@ -486,19 +487,19 @@ static int config_output(AVFilterLink *outlink) break; } case SIDE_BY_SIDE_2_LR: - aspect.den *= 2; + s->aspect.den *= 2; case SIDE_BY_SIDE_LR: s->out.width = s->width * 2; s->out.off_right = s->width; break; case SIDE_BY_SIDE_2_RL: - aspect.den *= 2; + s->aspect.den *= 2; case SIDE_BY_SIDE_RL: s->out.width = s->width * 2; s->out.off_left = s->width; break; case ABOVE_BELOW_2_LR: - aspect.num *= 2; + s->aspect.num *= 2; case ABOVE_BELOW_LR: s->out.height = s->height * 2; s->out.row_right = s->height; @@ -514,7 +515,7 @@ static int config_output(AVFilterLink *outlink) s->out.row_right = s->height + s->blanks; break; case ABOVE_BELOW_2_RL: - aspect.num *= 2; + s->aspect.num *= 2; case ABOVE_BELOW_RL: s->out.height = s->height * 2; s->out.row_left = s->height; @@ -576,7 +577,7 @@ static int config_output(AVFilterLink *outlink) outlink->h = s->out.height; outlink->frame_rate = fps; outlink->time_base = tb; - outlink->sample_aspect_ratio = aspect; + outlink->sample_aspect_ratio = s->aspect; if ((ret = av_image_fill_linesizes(s->linesize, outlink->format, s->width)) < 0) return ret; @@ -1075,6 +1076,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) av_frame_free(&s->prev); av_frame_free(&inpicref); } + out->sample_aspect_ratio = s->aspect; return ff_filter_frame(outlink, out); } From ca72cd137d3ba57b03018dbeb83ca99d7ef96dca Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Wed, 13 Sep 2017 19:05:10 +0200 Subject: [PATCH 3119/3374] lavf/mpegts: Consider stream_type 0x0f just a hint towards AAC. It is also used in the wild to signal latm. Fixes ticket #6657. --- libavformat/mpegts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 4d2f5c6802be0..53cbcfb543bf3 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -814,7 +814,7 @@ static int mpegts_set_stream_info(AVStream *st, PESContext *pes, st->codecpar->codec_tag = pes->stream_type; mpegts_find_stream_type(st, pes->stream_type, ISO_types); - if (pes->stream_type == 4) + if (pes->stream_type == 4 || pes->stream_type == 0x0f) st->request_probe = 50; if ((prog_reg_desc == AV_RL32("HDMV") || prog_reg_desc == AV_RL32("HDPR")) && From 5480e82d77770e81e897a8c217f3c7f0c13a6de1 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 17 Sep 2017 02:42:11 +0200 Subject: [PATCH 3120/3374] avcodec/pngdec: Clean up on av_frame_ref() failure Fixes: memleak Fixes: 3203/clusterfuzz-testcase-minimized-4514553595428864 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Reviewed-by: James Almer Signed-off-by: Michael Niedermayer --- libavcodec/pngdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index dce8faf1688c2..0d6612cccafb8 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -1414,7 +1414,7 @@ static int decode_frame_png(AVCodecContext *avctx, } if ((ret = av_frame_ref(data, s->picture.f)) < 0) - return ret; + goto the_end; *got_frame = 1; From 9777836670aef00c86c19e3ee0f6b7fdacca72ba Mon Sep 17 00:00:00 2001 From: Thomas Mundt Date: Sat, 16 Sep 2017 01:57:27 +0200 Subject: [PATCH 3121/3374] MAINTAINERS: add myself for bwdif and (t)interlace Signed-off-by: Michael Niedermayer --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 0b0f7fa1e451d..69883ee8316ad 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -329,6 +329,7 @@ Filters: avf_avectorscope.c Paul B Mahol avf_showcqt.c Muhammad Faiz vf_blend.c Paul B Mahol + vf_bwdif Thomas Mundt (CC ) vf_chromakey.c Timo Rothenpieler vf_colorchannelmixer.c Paul B Mahol vf_colorbalance.c Paul B Mahol @@ -344,6 +345,7 @@ Filters: vf_hqx.c Clément Bœsch vf_idet.c Pascal Massimino vf_il.c Paul B Mahol + vf_(t)interlace Thomas Mundt (CC ) vf_lenscorrection.c Daniel Oberhoff vf_mergeplanes.c Paul B Mahol vf_mestimate.c Davinder Singh From f4ba85dc82f5bce5c05d4534e2126c5f9d7f26ab Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Mon, 18 Sep 2017 13:48:48 +0530 Subject: [PATCH 3122/3374] avcodec/mips: Fixed rnd_val variable to 6 in hevc uni mc msa functions Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/hevc_mc_uni_msa.c | 372 +++++++++++------------------- 1 file changed, 133 insertions(+), 239 deletions(-) diff --git a/libavcodec/mips/hevc_mc_uni_msa.c b/libavcodec/mips/hevc_mc_uni_msa.c index 754fbdbb413dd..cf22e7f1a1390 100644 --- a/libavcodec/mips/hevc_mc_uni_msa.c +++ b/libavcodec/mips/hevc_mc_uni_msa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com) + * Copyright (c) 2015 - 2017 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com) * * This file is part of FFmpeg. * @@ -359,16 +359,14 @@ static const uint8_t mc_filt_mask_arr[16 * 3] = { static void common_hz_8t_4x4_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, uint8_t rnd_val) + const int8_t *filter) { v16u8 mask0, mask1, mask2, mask3, out; v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; v8i16 filt, out0, out1; - v8i16 rnd_vec; mask0 = LD_UB(&mc_filt_mask_arr[16]); src -= 3; - rnd_vec = __msa_fill_h(rnd_val); /* rearranging filter */ filt = LD_SH(filter); @@ -382,7 +380,7 @@ static void common_hz_8t_4x4_msa(uint8_t *src, int32_t src_stride, XORI_B4_128_SB(src0, src1, src2, src3); HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, filt0, filt1, filt2, filt3, out0, out1); - SRAR_H2_SH(out0, out1, rnd_vec); + SRARI_H2_SH(out0, out1, 6); SAT_SH2_SH(out0, out1, 7); out = PCKEV_XORI128_UB(out0, out1); ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); @@ -390,17 +388,15 @@ static void common_hz_8t_4x4_msa(uint8_t *src, int32_t src_stride, static void common_hz_8t_4x8_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, uint8_t rnd_val) + const int8_t *filter) { v16i8 filt0, filt1, filt2, filt3; v16i8 src0, src1, src2, src3; v16u8 mask0, mask1, mask2, mask3, out; v8i16 filt, out0, out1, out2, out3; - v8i16 rnd_vec; mask0 = LD_UB(&mc_filt_mask_arr[16]); src -= 3; - rnd_vec = __msa_fill_h(rnd_val); /* rearranging filter */ filt = LD_SH(filter); @@ -419,7 +415,7 @@ static void common_hz_8t_4x8_msa(uint8_t *src, int32_t src_stride, XORI_B4_128_SB(src0, src1, src2, src3); HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, filt0, filt1, filt2, filt3, out2, out3); - SRAR_H4_SH(out0, out1, out2, out3, rnd_vec); + SRARI_H4_SH(out0, out1, out2, out3, 6); SAT_SH4_SH(out0, out1, out2, out3, 7); out = PCKEV_XORI128_UB(out0, out1); ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); @@ -430,16 +426,14 @@ static void common_hz_8t_4x8_msa(uint8_t *src, int32_t src_stride, static void common_hz_8t_4x16_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, uint8_t rnd_val) + const int8_t *filter) { v16u8 mask0, mask1, mask2, mask3, out; v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; v8i16 filt, out0, out1, out2, out3; - v8i16 rnd_vec; mask0 = LD_UB(&mc_filt_mask_arr[16]); src -= 3; - rnd_vec = __msa_fill_h(rnd_val); /* rearranging filter */ filt = LD_SH(filter); @@ -459,7 +453,7 @@ static void common_hz_8t_4x16_msa(uint8_t *src, int32_t src_stride, src += (4 * src_stride); HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, filt0, filt1, filt2, filt3, out2, out3); - SRAR_H4_SH(out0, out1, out2, out3, rnd_vec); + SRARI_H4_SH(out0, out1, out2, out3, 6); SAT_SH4_SH(out0, out1, out2, out3, 7); out = PCKEV_XORI128_UB(out0, out1); ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); @@ -479,7 +473,7 @@ static void common_hz_8t_4x16_msa(uint8_t *src, int32_t src_stride, HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, filt0, filt1, filt2, filt3, out2, out3); - SRAR_H4_SH(out0, out1, out2, out3, rnd_vec); + SRARI_H4_SH(out0, out1, out2, out3, 6); SAT_SH4_SH(out0, out1, out2, out3, 7); out = PCKEV_XORI128_UB(out0, out1); ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); @@ -490,30 +484,27 @@ static void common_hz_8t_4x16_msa(uint8_t *src, int32_t src_stride, static void common_hz_8t_4w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, uint8_t rnd_val) + const int8_t *filter, int32_t height) { if (4 == height) { - common_hz_8t_4x4_msa(src, src_stride, dst, dst_stride, filter, rnd_val); + common_hz_8t_4x4_msa(src, src_stride, dst, dst_stride, filter); } else if (8 == height) { - common_hz_8t_4x8_msa(src, src_stride, dst, dst_stride, filter, rnd_val); + common_hz_8t_4x8_msa(src, src_stride, dst, dst_stride, filter); } else if (16 == height) { - common_hz_8t_4x16_msa(src, src_stride, dst, dst_stride, filter, - rnd_val); + common_hz_8t_4x16_msa(src, src_stride, dst, dst_stride, filter); } } static void common_hz_8t_8x4_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, uint8_t rnd_val) + const int8_t *filter) { v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; v16u8 mask0, mask1, mask2, mask3, tmp0, tmp1; v8i16 filt, out0, out1, out2, out3; - v8i16 rnd_vec; mask0 = LD_UB(&mc_filt_mask_arr[0]); src -= 3; - rnd_vec = __msa_fill_h(rnd_val); /* rearranging filter */ filt = LD_SH(filter); @@ -528,7 +519,7 @@ static void common_hz_8t_8x4_msa(uint8_t *src, int32_t src_stride, HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, filt0, filt1, filt2, filt3, out0, out1, out2, out3); - SRAR_H4_SH(out0, out1, out2, out3, rnd_vec); + SRARI_H4_SH(out0, out1, out2, out3, 6); SAT_SH4_SH(out0, out1, out2, out3, 7); tmp0 = PCKEV_XORI128_UB(out0, out1); tmp1 = PCKEV_XORI128_UB(out2, out3); @@ -537,18 +528,15 @@ static void common_hz_8t_8x4_msa(uint8_t *src, int32_t src_stride, static void common_hz_8t_8x8mult_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { uint32_t loop_cnt; v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; v16u8 mask0, mask1, mask2, mask3, tmp0, tmp1; v8i16 filt, out0, out1, out2, out3; - v8i16 rnd_vec; mask0 = LD_UB(&mc_filt_mask_arr[0]); src -= 3; - rnd_vec = __msa_fill_h(rnd_val); /* rearranging filter */ filt = LD_SH(filter); @@ -565,7 +553,7 @@ static void common_hz_8t_8x8mult_msa(uint8_t *src, int32_t src_stride, HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, filt0, filt1, filt2, filt3, out0, out1, out2, out3); - SRAR_H4_SH(out0, out1, out2, out3, rnd_vec); + SRARI_H4_SH(out0, out1, out2, out3, 6); SAT_SH4_SH(out0, out1, out2, out3, 7); tmp0 = PCKEV_XORI128_UB(out0, out1); tmp1 = PCKEV_XORI128_UB(out2, out3); @@ -576,32 +564,28 @@ static void common_hz_8t_8x8mult_msa(uint8_t *src, int32_t src_stride, static void common_hz_8t_8w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { if (4 == height) { - common_hz_8t_8x4_msa(src, src_stride, dst, dst_stride, filter, rnd_val); + common_hz_8t_8x4_msa(src, src_stride, dst, dst_stride, filter); } else { common_hz_8t_8x8mult_msa(src, src_stride, dst, dst_stride, filter, - height, rnd_val); + height); } } static void common_hz_8t_12w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { uint8_t *src1_ptr, *dst1; uint32_t loop_cnt; v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; v8i16 filt, out0, out1, out2, out3; v16u8 mask0, mask1, mask2, mask3, mask4, mask5, mask6, mask00, tmp0, tmp1; - v8i16 rnd_vec; mask00 = LD_UB(&mc_filt_mask_arr[0]); mask0 = LD_UB(&mc_filt_mask_arr[16]); - rnd_vec = __msa_fill_h(rnd_val); src1_ptr = src - 3; dst1 = dst; @@ -628,7 +612,7 @@ static void common_hz_8t_12w_msa(uint8_t *src, int32_t src_stride, HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask00, mask1, mask2, mask3, filt0, filt1, filt2, filt3, out0, out1, out2, out3); - SRAR_H4_SH(out0, out1, out2, out3, rnd_vec); + SRARI_H4_SH(out0, out1, out2, out3, 6); SAT_SH4_SH(out0, out1, out2, out3, 7); tmp0 = PCKEV_XORI128_UB(out0, out1); tmp1 = PCKEV_XORI128_UB(out2, out3); @@ -642,7 +626,7 @@ static void common_hz_8t_12w_msa(uint8_t *src, int32_t src_stride, HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask4, mask5, mask6, filt0, filt1, filt2, filt3, out0, out1); - SRAR_H2_SH(out0, out1, rnd_vec); + SRARI_H2_SH(out0, out1, 6); SAT_SH2_SH(out0, out1, 7); tmp0 = PCKEV_XORI128_UB(out0, out1); ST4x4_UB(tmp0, tmp0, 0, 1, 2, 3, dst, dst_stride); @@ -652,18 +636,15 @@ static void common_hz_8t_12w_msa(uint8_t *src, int32_t src_stride, static void common_hz_8t_16w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { uint32_t loop_cnt; v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; v16u8 mask0, mask1, mask2, mask3, out; v8i16 filt, out0, out1, out2, out3; - v8i16 rnd_vec; mask0 = LD_UB(&mc_filt_mask_arr[0]); src -= 3; - rnd_vec = __msa_fill_h(rnd_val); /* rearranging filter */ filt = LD_SH(filter); @@ -681,7 +662,7 @@ static void common_hz_8t_16w_msa(uint8_t *src, int32_t src_stride, HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, filt0, filt1, filt2, filt3, out0, out1, out2, out3); - SRAR_H4_SH(out0, out1, out2, out3, rnd_vec); + SRARI_H4_SH(out0, out1, out2, out3, 6); SAT_SH4_SH(out0, out1, out2, out3, 7); out = PCKEV_XORI128_UB(out0, out1); ST_UB(out, dst); @@ -694,8 +675,7 @@ static void common_hz_8t_16w_msa(uint8_t *src, int32_t src_stride, static void common_hz_8t_24w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { uint32_t loop_cnt; v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; @@ -704,11 +684,9 @@ static void common_hz_8t_24w_msa(uint8_t *src, int32_t src_stride, v16i8 vec11; v8i16 out0, out1, out2, out3, out4, out5, out6, out7, out8, out9, out10; v8i16 out11, filt; - v8i16 rnd_vec; mask0 = LD_UB(&mc_filt_mask_arr[0]); src -= 3; - rnd_vec = __msa_fill_h(rnd_val); /* rearranging filter */ filt = LD_SH(filter); @@ -754,8 +732,8 @@ static void common_hz_8t_24w_msa(uint8_t *src, int32_t src_stride, ADDS_SH4_SH(out0, out4, out8, out10, out2, out6, out9, out11, out0, out8, out2, out9); ADDS_SH2_SH(out1, out5, out3, out7, out1, out3); - SRAR_H4_SH(out0, out8, out2, out9, rnd_vec); - SRAR_H2_SH(out1, out3, rnd_vec); + SRARI_H4_SH(out0, out8, out2, out9, 6); + SRARI_H2_SH(out1, out3, 6); SAT_SH4_SH(out0, out8, out2, out9, 7); SAT_SH2_SH(out1, out3, 7); out = PCKEV_XORI128_UB(out8, out9); @@ -771,18 +749,15 @@ static void common_hz_8t_24w_msa(uint8_t *src, int32_t src_stride, static void common_hz_8t_32w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { uint32_t loop_cnt; v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; v16u8 mask0, mask1, mask2, mask3, out; v8i16 filt, out0, out1, out2, out3; - v8i16 rnd_vec; mask0 = LD_UB(&mc_filt_mask_arr[0]); src -= 3; - rnd_vec = __msa_fill_h(rnd_val); /* rearranging filter */ filt = LD_SH(filter); @@ -802,7 +777,7 @@ static void common_hz_8t_32w_msa(uint8_t *src, int32_t src_stride, HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, filt0, filt1, filt2, filt3, out0, out1, out2, out3); - SRAR_H4_SH(out0, out1, out2, out3, rnd_vec); + SRARI_H4_SH(out0, out1, out2, out3, 6); SAT_SH4_SH(out0, out1, out2, out3, 7); src0 = LD_SB(src); @@ -821,7 +796,7 @@ static void common_hz_8t_32w_msa(uint8_t *src, int32_t src_stride, HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, filt0, filt1, filt2, filt3, out0, out1, out2, out3); - SRAR_H4_SH(out0, out1, out2, out3, rnd_vec); + SRARI_H4_SH(out0, out1, out2, out3, 6); SAT_SH4_SH(out0, out1, out2, out3, 7); out = PCKEV_XORI128_UB(out0, out1); ST_UB(out, dst); @@ -833,18 +808,15 @@ static void common_hz_8t_32w_msa(uint8_t *src, int32_t src_stride, static void common_hz_8t_48w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { uint32_t loop_cnt; v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3, vec0, vec1, vec2; v16u8 mask0, mask1, mask2, mask3, mask4, mask5, mask6, mask7, out; v8i16 filt, out0, out1, out2, out3, out4, out5, out6; - v8i16 rnd_vec; mask0 = LD_UB(&mc_filt_mask_arr[0]); src -= 3; - rnd_vec = __msa_fill_h(rnd_val); /* rearranging filter */ filt = LD_SH(filter); @@ -879,8 +851,8 @@ static void common_hz_8t_48w_msa(uint8_t *src, int32_t src_stride, out5 = __msa_dpadd_s_h(out5, vec2, filt3); ADDS_SH2_SH(out0, out3, out1, out4, out0, out1); out2 = __msa_adds_s_h(out2, out5); - SRAR_H2_SH(out0, out1, rnd_vec); - out6 = __msa_srar_h(out2, rnd_vec); + SRARI_H2_SH(out0, out1, 6); + out6 = __msa_srari_h(out2, 6); SAT_SH3_SH(out0, out1, out6, 7); out = PCKEV_XORI128_UB(out0, out1); ST_UB(out, dst); @@ -905,7 +877,8 @@ static void common_hz_8t_48w_msa(uint8_t *src, int32_t src_stride, out5 = __msa_dpadd_s_h(out5, vec2, filt3); ADDS_SH2_SH(out0, out3, out1, out4, out3, out4); out5 = __msa_adds_s_h(out2, out5); - SRAR_H3_SH(out3, out4, out5, rnd_vec); + SRARI_H2_SH(out3, out4, 6); + out5 = __msa_srari_h(out5, 6); SAT_SH3_SH(out3, out4, out5, 7); out = PCKEV_XORI128_UB(out6, out3); ST_UB(out, dst + 16); @@ -917,18 +890,15 @@ static void common_hz_8t_48w_msa(uint8_t *src, int32_t src_stride, static void common_hz_8t_64w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { int32_t loop_cnt; v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; v16u8 mask0, mask1, mask2, mask3, out; v8i16 filt, out0, out1, out2, out3; - v8i16 rnd_vec; mask0 = LD_UB(&mc_filt_mask_arr[0]); src -= 3; - rnd_vec = __msa_fill_h(rnd_val); /* rearranging filter */ filt = LD_SH(filter); @@ -948,7 +918,7 @@ static void common_hz_8t_64w_msa(uint8_t *src, int32_t src_stride, HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, filt0, filt1, filt2, filt3, out0, out1, out2, out3); - SRAR_H4_SH(out0, out1, out2, out3, rnd_vec); + SRARI_H4_SH(out0, out1, out2, out3, 6); SAT_SH4_SH(out0, out1, out2, out3, 7); out = PCKEV_XORI128_UB(out0, out1); ST_UB(out, dst); @@ -965,7 +935,7 @@ static void common_hz_8t_64w_msa(uint8_t *src, int32_t src_stride, HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, filt0, filt1, filt2, filt3, out0, out1, out2, out3); - SRAR_H4_SH(out0, out1, out2, out3, rnd_vec); + SRARI_H4_SH(out0, out1, out2, out3, 6); SAT_SH4_SH(out0, out1, out2, out3, 7); out = PCKEV_XORI128_UB(out0, out1); ST_UB(out, dst + 32); @@ -977,8 +947,7 @@ static void common_hz_8t_64w_msa(uint8_t *src, int32_t src_stride, static void common_vt_8t_4w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { uint32_t loop_cnt; v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; @@ -987,10 +956,8 @@ static void common_vt_8t_4w_msa(uint8_t *src, int32_t src_stride, v16i8 src10998, filt0, filt1, filt2, filt3; v16u8 out; v8i16 filt, out10, out32; - v8i16 rnd_vec; src -= (3 * src_stride); - rnd_vec = __msa_fill_h(rnd_val); filt = LD_SH(filter); SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); @@ -1017,7 +984,7 @@ static void common_vt_8t_4w_msa(uint8_t *src, int32_t src_stride, filt1, filt2, filt3); out32 = FILT_8TAP_DPADD_S_H(src4332, src6554, src8776, src10998, filt0, filt1, filt2, filt3); - SRAR_H2_SH(out10, out32, rnd_vec); + SRARI_H2_SH(out10, out32, 6); SAT_SH2_SH(out10, out32, 7); out = PCKEV_XORI128_UB(out10, out32); ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); @@ -1032,8 +999,7 @@ static void common_vt_8t_4w_msa(uint8_t *src, int32_t src_stride, static void common_vt_8t_8w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { uint32_t loop_cnt; v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; @@ -1041,10 +1007,8 @@ static void common_vt_8t_8w_msa(uint8_t *src, int32_t src_stride, v16i8 src65_r, src87_r, src109_r, filt0, filt1, filt2, filt3; v16u8 tmp0, tmp1; v8i16 filt, out0_r, out1_r, out2_r, out3_r; - v8i16 rnd_vec; src -= (3 * src_stride); - rnd_vec = __msa_fill_h(rnd_val); filt = LD_SH(filter); SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); @@ -1071,7 +1035,7 @@ static void common_vt_8t_8w_msa(uint8_t *src, int32_t src_stride, filt1, filt2, filt3); out3_r = FILT_8TAP_DPADD_S_H(src43_r, src65_r, src87_r, src109_r, filt0, filt1, filt2, filt3); - SRAR_H4_SH(out0_r, out1_r, out2_r, out3_r, rnd_vec); + SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, 6); SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); tmp0 = PCKEV_XORI128_UB(out0_r, out1_r); tmp1 = PCKEV_XORI128_UB(out2_r, out3_r); @@ -1090,8 +1054,7 @@ static void common_vt_8t_8w_msa(uint8_t *src, int32_t src_stride, static void common_vt_8t_12w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { int32_t loop_cnt; uint32_t out2, out3; @@ -1100,11 +1063,9 @@ static void common_vt_8t_12w_msa(uint8_t *src, int32_t src_stride, v16i8 res2, vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; v8i16 vec01, vec23, vec45, vec67, tmp0, tmp1, tmp2; v8i16 filt, filt0, filt1, filt2, filt3; - v8i16 rnd_vec; v4i32 mask = { 2, 6, 2, 6 }; src -= (3 * src_stride); - rnd_vec = __msa_fill_h(rnd_val); /* rearranging filter_y */ filt = LD_SH(filter); @@ -1140,7 +1101,8 @@ static void common_vt_8t_12w_msa(uint8_t *src, int32_t src_stride, vec45, vec67); tmp2 = FILT_8TAP_DPADD_S_H(vec01, vec23, vec45, vec67, filt0, filt1, filt2, filt3); - SRAR_H3_SH(tmp0, tmp1, tmp2, rnd_vec); + SRARI_H2_SH(tmp0, tmp1, 6); + tmp2 = __msa_srari_h(tmp2, 6); SAT_SH3_SH(tmp0, tmp1, tmp2, 7); PCKEV_B3_SB(tmp0, tmp0, tmp1, tmp1, tmp2, tmp2, res0, res1, res2); XORI_B3_128_SB(res0, res1, res2); @@ -1174,8 +1136,7 @@ static void common_vt_8t_12w_msa(uint8_t *src, int32_t src_stride, static void common_vt_8t_16w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { uint32_t loop_cnt; v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; @@ -1185,10 +1146,8 @@ static void common_vt_8t_16w_msa(uint8_t *src, int32_t src_stride, v16i8 src98_l, src21_l, src43_l, src65_l, src87_l, src109_l; v16u8 tmp0, tmp1, tmp2, tmp3; v8i16 filt, out0_r, out1_r, out2_r, out3_r, out0_l, out1_l, out2_l, out3_l; - v8i16 rnd_vec; src -= (3 * src_stride); - rnd_vec = __msa_fill_h(rnd_val); filt = LD_SH(filter); SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); @@ -1228,8 +1187,8 @@ static void common_vt_8t_16w_msa(uint8_t *src, int32_t src_stride, filt1, filt2, filt3); out3_l = FILT_8TAP_DPADD_S_H(src43_l, src65_l, src87_l, src109_l, filt0, filt1, filt2, filt3); - SRAR_H4_SH(out0_r, out1_r, out2_r, out3_r, rnd_vec); - SRAR_H4_SH(out0_l, out1_l, out2_l, out3_l, rnd_vec); + SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, 6); + SRARI_H4_SH(out0_l, out1_l, out2_l, out3_l, 6); SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); SAT_SH4_SH(out0_l, out1_l, out2_l, out3_l, 7); PCKEV_B4_UB(out0_l, out0_r, out1_l, out1_r, out2_l, out2_r, out3_l, @@ -1257,7 +1216,7 @@ static void common_vt_8t_16w_msa(uint8_t *src, int32_t src_stride, static void common_vt_8t_16w_mult_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, const int8_t *filter, int32_t height, - uint8_t rnd_val, int32_t width) + int32_t width) { uint8_t *src_tmp; uint8_t *dst_tmp; @@ -1269,10 +1228,8 @@ static void common_vt_8t_16w_mult_msa(uint8_t *src, int32_t src_stride, v16i8 src98_l, src21_l, src43_l, src65_l, src87_l, src109_l; v16u8 tmp0, tmp1, tmp2, tmp3; v8i16 filt, out0_r, out1_r, out2_r, out3_r, out0_l, out1_l, out2_l, out3_l; - v8i16 rnd_vec; src -= (3 * src_stride); - rnd_vec = __msa_fill_h(rnd_val); filt = LD_SH(filter); SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); @@ -1315,8 +1272,8 @@ static void common_vt_8t_16w_mult_msa(uint8_t *src, int32_t src_stride, filt0, filt1, filt2, filt3); out3_l = FILT_8TAP_DPADD_S_H(src43_l, src65_l, src87_l, src109_l, filt0, filt1, filt2, filt3); - SRAR_H4_SH(out0_r, out1_r, out2_r, out3_r, rnd_vec); - SRAR_H4_SH(out0_l, out1_l, out2_l, out3_l, rnd_vec); + SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, 6); + SRARI_H4_SH(out0_l, out1_l, out2_l, out3_l, 6); SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); SAT_SH4_SH(out0_l, out1_l, out2_l, out3_l, 7); PCKEV_B4_UB(out0_l, out0_r, out1_l, out1_r, out2_l, out2_r, out3_l, @@ -1347,37 +1304,37 @@ static void common_vt_8t_16w_mult_msa(uint8_t *src, int32_t src_stride, static void common_vt_8t_24w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, uint8_t rnd_val) + const int8_t *filter, int32_t height) { common_vt_8t_16w_mult_msa(src, src_stride, dst, dst_stride, filter, height, - rnd_val, 16); + 16); common_vt_8t_8w_msa(src + 16, src_stride, dst + 16, dst_stride, filter, - height, rnd_val); + height); } static void common_vt_8t_32w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, uint8_t rnd_val) + const int8_t *filter, int32_t height) { common_vt_8t_16w_mult_msa(src, src_stride, dst, dst_stride, filter, height, - rnd_val, 32); + 32); } static void common_vt_8t_48w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, uint8_t rnd_val) + const int8_t *filter, int32_t height) { common_vt_8t_16w_mult_msa(src, src_stride, dst, dst_stride, filter, height, - rnd_val, 48); + 48); } static void common_vt_8t_64w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, uint8_t rnd_val) + const int8_t *filter, int32_t height) { common_vt_8t_16w_mult_msa(src, src_stride, dst, dst_stride, filter, height, - rnd_val, 64); + 64); } static void hevc_hv_uni_8t_4w_msa(uint8_t *src, @@ -1736,16 +1693,14 @@ static void hevc_hv_uni_8t_64w_msa(uint8_t *src, static void common_hz_4t_4x2_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, uint8_t rnd_val) + const int8_t *filter) { v16i8 filt0, filt1, src0, src1, mask0, mask1, vec0, vec1; v16u8 out; v8i16 filt, res0; - v8i16 rnd_vec; mask0 = LD_SB(&mc_filt_mask_arr[16]); src -= 1; - rnd_vec = __msa_fill_h(rnd_val); /* rearranging filter */ filt = LD_SH(filter); @@ -1757,7 +1712,7 @@ static void common_hz_4t_4x2_msa(uint8_t *src, int32_t src_stride, XORI_B2_128_SB(src0, src1); VSHF_B2_SB(src0, src1, src0, src1, mask0, mask1, vec0, vec1); res0 = FILT_4TAP_DPADD_S_H(vec0, vec1, filt0, filt1); - res0 = __msa_srar_h(res0, rnd_vec); + res0 = __msa_srari_h(res0, 6); res0 = __msa_sat_s_h(res0, 7); out = PCKEV_XORI128_UB(res0, res0); ST4x2_UB(out, dst, dst_stride); @@ -1765,16 +1720,14 @@ static void common_hz_4t_4x2_msa(uint8_t *src, int32_t src_stride, static void common_hz_4t_4x4_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, uint8_t rnd_val) + const int8_t *filter) { v16i8 src0, src1, src2, src3, filt0, filt1, mask0, mask1; v8i16 filt, out0, out1; v16u8 out; - v8i16 rnd_vec; mask0 = LD_SB(&mc_filt_mask_arr[16]); src -= 1; - rnd_vec = __msa_fill_h(rnd_val); /* rearranging filter */ filt = LD_SH(filter); @@ -1786,7 +1739,7 @@ static void common_hz_4t_4x4_msa(uint8_t *src, int32_t src_stride, XORI_B4_128_SB(src0, src1, src2, src3); HORIZ_4TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, filt0, filt1, out0, out1); - SRAR_H2_SH(out0, out1, rnd_vec); + SRARI_H2_SH(out0, out1, 6); SAT_SH2_SH(out0, out1, 7); out = PCKEV_XORI128_UB(out0, out1); ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); @@ -1794,16 +1747,14 @@ static void common_hz_4t_4x4_msa(uint8_t *src, int32_t src_stride, static void common_hz_4t_4x8_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, uint8_t rnd_val) + const int8_t *filter) { v16i8 src0, src1, src2, src3, filt0, filt1, mask0, mask1; v16u8 out; v8i16 filt, out0, out1, out2, out3; - v8i16 rnd_vec; mask0 = LD_SB(&mc_filt_mask_arr[16]); src -= 1; - rnd_vec = __msa_fill_h(rnd_val); /* rearranging filter */ filt = LD_SH(filter); @@ -1821,7 +1772,7 @@ static void common_hz_4t_4x8_msa(uint8_t *src, int32_t src_stride, XORI_B4_128_SB(src0, src1, src2, src3); HORIZ_4TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, filt0, filt1, out2, out3); - SRAR_H4_SH(out0, out1, out2, out3, rnd_vec); + SRARI_H4_SH(out0, out1, out2, out3, 6); SAT_SH4_SH(out0, out1, out2, out3, 7); out = PCKEV_XORI128_UB(out0, out1); ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); @@ -1832,17 +1783,15 @@ static void common_hz_4t_4x8_msa(uint8_t *src, int32_t src_stride, static void common_hz_4t_4x16_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, uint8_t rnd_val) + const int8_t *filter) { v16i8 src0, src1, src2, src3, src4, src5, src6, src7; v16i8 filt0, filt1, mask0, mask1; v16u8 out; v8i16 filt, out0, out1, out2, out3; - v8i16 rnd_vec; mask0 = LD_SB(&mc_filt_mask_arr[16]); src -= 1; - rnd_vec = __msa_fill_h(rnd_val); /* rearranging filter */ filt = LD_SH(filter); @@ -1857,7 +1806,7 @@ static void common_hz_4t_4x16_msa(uint8_t *src, int32_t src_stride, filt0, filt1, out0, out1); HORIZ_4TAP_4WID_4VECS_FILT(src4, src5, src6, src7, mask0, mask1, filt0, filt1, out2, out3); - SRAR_H4_SH(out0, out1, out2, out3, rnd_vec); + SRARI_H4_SH(out0, out1, out2, out3, 6); SAT_SH4_SH(out0, out1, out2, out3, 7); out = PCKEV_XORI128_UB(out0, out1); ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); @@ -1873,7 +1822,7 @@ static void common_hz_4t_4x16_msa(uint8_t *src, int32_t src_stride, filt0, filt1, out0, out1); HORIZ_4TAP_4WID_4VECS_FILT(src4, src5, src6, src7, mask0, mask1, filt0, filt1, out2, out3); - SRAR_H4_SH(out0, out1, out2, out3, rnd_vec); + SRARI_H4_SH(out0, out1, out2, out3, 6); SAT_SH4_SH(out0, out1, out2, out3, 7); out = PCKEV_XORI128_UB(out0, out1); ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); @@ -1884,35 +1833,30 @@ static void common_hz_4t_4x16_msa(uint8_t *src, int32_t src_stride, static void common_hz_4t_4w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { if (2 == height) { - common_hz_4t_4x2_msa(src, src_stride, dst, dst_stride, filter, rnd_val); + common_hz_4t_4x2_msa(src, src_stride, dst, dst_stride, filter); } else if (4 == height) { - common_hz_4t_4x4_msa(src, src_stride, dst, dst_stride, filter, rnd_val); + common_hz_4t_4x4_msa(src, src_stride, dst, dst_stride, filter); } else if (8 == height) { - common_hz_4t_4x8_msa(src, src_stride, dst, dst_stride, filter, rnd_val); + common_hz_4t_4x8_msa(src, src_stride, dst, dst_stride, filter); } else if (16 == height) { - common_hz_4t_4x16_msa(src, src_stride, dst, dst_stride, filter, - rnd_val); + common_hz_4t_4x16_msa(src, src_stride, dst, dst_stride, filter); } } static void common_hz_4t_6w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { uint32_t loop_cnt; v16i8 src0, src1, src2, src3, filt0, filt1, mask0, mask1; v16u8 out4, out5; v8i16 filt, out0, out1, out2, out3; - v8i16 rnd_vec; mask0 = LD_SB(&mc_filt_mask_arr[0]); src -= 1; - rnd_vec = __msa_fill_h(rnd_val); /* rearranging filter */ filt = LD_SH(filter); @@ -1927,7 +1871,7 @@ static void common_hz_4t_6w_msa(uint8_t *src, int32_t src_stride, XORI_B4_128_SB(src0, src1, src2, src3); HORIZ_4TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, filt0, filt1, out0, out1, out2, out3); - SRAR_H4_SH(out0, out1, out2, out3, rnd_vec); + SRARI_H4_SH(out0, out1, out2, out3, 6); SAT_SH4_SH(out0, out1, out2, out3, 7); out4 = PCKEV_XORI128_UB(out0, out1); @@ -1939,18 +1883,15 @@ static void common_hz_4t_6w_msa(uint8_t *src, int32_t src_stride, static void common_hz_4t_8x2mult_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { uint32_t loop_cnt; v16i8 src0, src1, filt0, filt1, mask0, mask1; v16u8 out; v8i16 filt, vec0, vec1, vec2, vec3; - v8i16 rnd_vec; mask0 = LD_SB(&mc_filt_mask_arr[0]); src -= 1; - rnd_vec = __msa_fill_h(rnd_val); filt = LD_SH(filter); SPLATI_H2_SB(filt, 0, 1, filt0, filt1); @@ -1966,7 +1907,7 @@ static void common_hz_4t_8x2mult_msa(uint8_t *src, int32_t src_stride, DOTP_SB2_SH(vec0, vec1, filt0, filt0, vec0, vec1); VSHF_B2_SH(src0, src0, src1, src1, mask1, mask1, vec2, vec3); DPADD_SB2_SH(vec2, vec3, filt1, filt1, vec0, vec1); - SRAR_H2_SH(vec0, vec1, rnd_vec); + SRARI_H2_SH(vec0, vec1, 6); SAT_SH2_SH(vec0, vec1, 7); out = PCKEV_XORI128_UB(vec0, vec1); ST8x2_UB(out, dst, dst_stride); @@ -1976,18 +1917,15 @@ static void common_hz_4t_8x2mult_msa(uint8_t *src, int32_t src_stride, static void common_hz_4t_8x4mult_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { uint32_t loop_cnt; v16i8 src0, src1, src2, src3, filt0, filt1, mask0, mask1; v16u8 tmp0, tmp1; v8i16 filt, out0, out1, out2, out3; - v8i16 rnd_vec; mask0 = LD_SB(&mc_filt_mask_arr[0]); src -= 1; - rnd_vec = __msa_fill_h(rnd_val); /* rearranging filter */ filt = LD_SH(filter); @@ -2002,7 +1940,7 @@ static void common_hz_4t_8x4mult_msa(uint8_t *src, int32_t src_stride, XORI_B4_128_SB(src0, src1, src2, src3); HORIZ_4TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, filt0, filt1, out0, out1, out2, out3); - SRAR_H4_SH(out0, out1, out2, out3, rnd_vec); + SRARI_H4_SH(out0, out1, out2, out3, 6); SAT_SH4_SH(out0, out1, out2, out3, 7); tmp0 = PCKEV_XORI128_UB(out0, out1); tmp1 = PCKEV_XORI128_UB(out2, out3); @@ -2013,22 +1951,20 @@ static void common_hz_4t_8x4mult_msa(uint8_t *src, int32_t src_stride, static void common_hz_4t_8w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { if ((2 == height) || (6 == height)) { common_hz_4t_8x2mult_msa(src, src_stride, dst, dst_stride, filter, - height, rnd_val); + height); } else { common_hz_4t_8x4mult_msa(src, src_stride, dst, dst_stride, filter, - height, rnd_val); + height); } } static void common_hz_4t_12w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { uint32_t loop_cnt; v16i8 src0, src1, src2, src3, filt0, filt1, mask0, mask1, mask2, mask3; @@ -2036,7 +1972,6 @@ static void common_hz_4t_12w_msa(uint8_t *src, int32_t src_stride, v16i8 vec10, vec11; v16u8 tmp0, tmp1; v8i16 filt, out0, out1, out2, out3, out4, out5; - v8i16 rnd_vec; mask0 = LD_SB(&mc_filt_mask_arr[0]); mask2 = LD_SB(&mc_filt_mask_arr[32]); @@ -2050,8 +1985,6 @@ static void common_hz_4t_12w_msa(uint8_t *src, int32_t src_stride, mask1 = mask0 + 2; mask3 = mask2 + 2; - rnd_vec = __msa_fill_h(rnd_val); - for (loop_cnt = (height >> 2); loop_cnt--;) { LD_SB4(src, src_stride, src0, src1, src2, src3); src += (4 * src_stride); @@ -2069,8 +2002,8 @@ static void common_hz_4t_12w_msa(uint8_t *src, int32_t src_stride, DPADD_SB4_SH(vec8, vec9, vec10, vec11, filt1, filt1, filt1, filt1, out2, out3, out4, out5); DPADD_SB2_SH(vec2, vec3, filt1, filt1, out0, out1); - SRAR_H4_SH(out0, out1, out2, out3, rnd_vec); - SRAR_H2_SH(out4, out5, rnd_vec); + SRARI_H4_SH(out0, out1, out2, out3, 6); + SRARI_H2_SH(out4, out5, 6); SAT_SH4_SH(out0, out1, out2, out3, 7); SAT_SH2_SH(out4, out5, 7); tmp0 = PCKEV_XORI128_UB(out2, out3); @@ -2084,19 +2017,16 @@ static void common_hz_4t_12w_msa(uint8_t *src, int32_t src_stride, static void common_hz_4t_16w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { uint32_t loop_cnt; v16i8 src0, src1, src2, src3, src4, src5, src6, src7; v16i8 filt0, filt1, mask0, mask1; v8i16 filt, out0, out1, out2, out3, out4, out5, out6, out7; v16u8 out; - v8i16 rnd_vec; mask0 = LD_SB(&mc_filt_mask_arr[0]); src -= 1; - rnd_vec = __msa_fill_h(rnd_val); /* rearranging filter */ filt = LD_SH(filter); @@ -2114,8 +2044,8 @@ static void common_hz_4t_16w_msa(uint8_t *src, int32_t src_stride, filt1, out0, out1, out2, out3); HORIZ_4TAP_8WID_4VECS_FILT(src4, src5, src6, src7, mask0, mask1, filt0, filt1, out4, out5, out6, out7); - SRAR_H4_SH(out0, out1, out2, out3, rnd_vec); - SRAR_H4_SH(out4, out5, out6, out7, rnd_vec); + SRARI_H4_SH(out0, out1, out2, out3, 6); + SRARI_H4_SH(out4, out5, out6, out7, 6); SAT_SH4_SH(out0, out1, out2, out3, 7); SAT_SH4_SH(out4, out5, out6, out7, 7); out = PCKEV_XORI128_UB(out0, out1); @@ -2135,8 +2065,7 @@ static void common_hz_4t_16w_msa(uint8_t *src, int32_t src_stride, static void common_hz_4t_24w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { uint8_t *dst1 = dst + 16; uint32_t loop_cnt; @@ -2145,11 +2074,9 @@ static void common_hz_4t_24w_msa(uint8_t *src, int32_t src_stride, v16i8 filt0, filt1, mask0, mask1, mask00, mask11; v8i16 filt, out0, out1, out2, out3; v16u8 tmp0, tmp1; - v8i16 rnd_vec; mask0 = LD_SB(&mc_filt_mask_arr[0]); src -= 1; - rnd_vec = __msa_fill_h(rnd_val); /* rearranging filter */ filt = LD_SH(filter); @@ -2173,7 +2100,7 @@ static void common_hz_4t_24w_msa(uint8_t *src, int32_t src_stride, out0, out1, out2, out3); DPADD_SB4_SH(vec4, vec5, vec6, vec7, filt1, filt1, filt1, filt1, out0, out1, out2, out3); - SRAR_H4_SH(out0, out1, out2, out3, rnd_vec); + SRARI_H4_SH(out0, out1, out2, out3, 6); SAT_SH4_SH(out0, out1, out2, out3, 7); tmp0 = PCKEV_XORI128_UB(out0, out1); ST_UB(tmp0, dst); @@ -2190,7 +2117,7 @@ static void common_hz_4t_24w_msa(uint8_t *src, int32_t src_stride, out0, out1, out2, out3); DPADD_SB4_SH(vec4, vec5, vec6, vec7, filt1, filt1, filt1, filt1, out0, out1, out2, out3); - SRAR_H4_SH(out0, out1, out2, out3, rnd_vec); + SRARI_H4_SH(out0, out1, out2, out3, 6); SAT_SH4_SH(out0, out1, out2, out3, 7); tmp0 = PCKEV_XORI128_UB(out0, out1); ST_UB(tmp0, dst); @@ -2210,7 +2137,7 @@ static void common_hz_4t_24w_msa(uint8_t *src, int32_t src_stride, DPADD_SB4_SH(vec4, vec5, vec6, vec7, filt1, filt1, filt1, filt1, out0, out1, out2, out3); - SRAR_H4_SH(out0, out1, out2, out3, rnd_vec); + SRARI_H4_SH(out0, out1, out2, out3, 6); SAT_SH4_SH(out0, out1, out2, out3, 7); tmp0 = PCKEV_XORI128_UB(out0, out1); tmp1 = PCKEV_XORI128_UB(out2, out3); @@ -2221,19 +2148,16 @@ static void common_hz_4t_24w_msa(uint8_t *src, int32_t src_stride, static void common_hz_4t_32w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { uint32_t loop_cnt; v16i8 src0, src1, src2, src3, src4, src5, src6, src7; v16i8 filt0, filt1, mask0, mask1; v16u8 out; v8i16 filt, out0, out1, out2, out3, out4, out5, out6, out7; - v8i16 rnd_vec; mask0 = LD_SB(&mc_filt_mask_arr[0]); src -= 1; - rnd_vec = __msa_fill_h(rnd_val); /* rearranging filter */ filt = LD_SH(filter); @@ -2257,8 +2181,8 @@ static void common_hz_4t_32w_msa(uint8_t *src, int32_t src_stride, filt0, filt1, out0, out1, out2, out3); HORIZ_4TAP_8WID_4VECS_FILT(src4, src5, src6, src7, mask0, mask1, filt0, filt1, out4, out5, out6, out7); - SRAR_H4_SH(out0, out1, out2, out3, rnd_vec); - SRAR_H4_SH(out4, out5, out6, out7, rnd_vec); + SRARI_H4_SH(out0, out1, out2, out3, 6); + SRARI_H4_SH(out4, out5, out6, out7, 6); SAT_SH4_SH(out0, out1, out2, out3, 7); SAT_SH4_SH(out4, out5, out6, out7, 7); out = PCKEV_XORI128_UB(out0, out1); @@ -2276,16 +2200,14 @@ static void common_hz_4t_32w_msa(uint8_t *src, int32_t src_stride, static void common_vt_4t_4x2_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, uint8_t rnd_val) + const int8_t *filter) { v16i8 src0, src1, src2, src3, src4, src10_r, src32_r, src21_r, src43_r; v16i8 src2110, src4332, filt0, filt1; v16u8 out; v8i16 filt, out10; - v8i16 rnd_vec; src -= src_stride; - rnd_vec = __msa_fill_h(rnd_val); filt = LD_SH(filter); SPLATI_H2_SB(filt, 0, 1, filt0, filt1); @@ -2301,7 +2223,7 @@ static void common_vt_4t_4x2_msa(uint8_t *src, int32_t src_stride, src4332 = (v16i8) __msa_ilvr_d((v2i64) src43_r, (v2i64) src32_r); src4332 = (v16i8) __msa_xori_b((v16u8) src4332, 128); out10 = FILT_4TAP_DPADD_S_H(src2110, src4332, filt0, filt1); - out10 = __msa_srar_h(out10, rnd_vec); + out10 = __msa_srari_h(out10, 6); out10 = __msa_sat_s_h(out10, 7); out = PCKEV_XORI128_UB(out10, out10); ST4x2_UB(out, dst, dst_stride); @@ -2309,8 +2231,7 @@ static void common_vt_4t_4x2_msa(uint8_t *src, int32_t src_stride, static void common_vt_4t_4x4multiple_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { uint32_t loop_cnt; v16i8 src0, src1, src2, src3, src4, src5; @@ -2318,10 +2239,8 @@ static void common_vt_4t_4x4multiple_msa(uint8_t *src, int32_t src_stride, v16i8 src2110, src4332, filt0, filt1; v8i16 filt, out10, out32; v16u8 out; - v8i16 rnd_vec; src -= src_stride; - rnd_vec = __msa_fill_h(rnd_val); filt = LD_SH(filter); SPLATI_H2_SB(filt, 0, 1, filt0, filt1); @@ -2348,7 +2267,7 @@ static void common_vt_4t_4x4multiple_msa(uint8_t *src, int32_t src_stride, src2110 = (v16i8) __msa_ilvr_d((v2i64) src65_r, (v2i64) src54_r); src2110 = (v16i8) __msa_xori_b((v16u8) src2110, 128); out32 = FILT_4TAP_DPADD_S_H(src4332, src2110, filt0, filt1); - SRAR_H2_SH(out10, out32, rnd_vec); + SRARI_H2_SH(out10, out32, 6); SAT_SH2_SH(out10, out32, 7); out = PCKEV_XORI128_UB(out10, out32); ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); @@ -2358,30 +2277,26 @@ static void common_vt_4t_4x4multiple_msa(uint8_t *src, int32_t src_stride, static void common_vt_4t_4w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { if (2 == height) { - common_vt_4t_4x2_msa(src, src_stride, dst, dst_stride, filter, rnd_val); + common_vt_4t_4x2_msa(src, src_stride, dst, dst_stride, filter); } else { common_vt_4t_4x4multiple_msa(src, src_stride, dst, dst_stride, filter, - height, rnd_val); + height); } } static void common_vt_4t_6w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { uint32_t loop_cnt; v16u8 src0, src1, src2, src3, vec0, vec1, vec2, vec3, out0, out1; v8i16 vec01, vec12, vec23, vec30, tmp0, tmp1, tmp2, tmp3; v8i16 filt, filt0, filt1; - v8i16 rnd_vec; src -= src_stride; - rnd_vec = __msa_fill_h(rnd_val); /* rearranging filter_y */ filt = LD_SH(filter); @@ -2414,7 +2329,7 @@ static void common_vt_4t_6w_msa(uint8_t *src, int32_t src_stride, vec12 = (v8i16) __msa_ilvr_b((v16i8) vec2, (v16i8) vec1); tmp3 = FILT_4TAP_DPADD_S_H(vec30, vec12, filt0, filt1); - SRAR_H4_SH(tmp0, tmp1, tmp2, tmp3, rnd_vec); + SRARI_H4_SH(tmp0, tmp1, tmp2, tmp3, 6); SAT_SH4_SH(tmp0, tmp1, tmp2, tmp3, 7); out0 = PCKEV_XORI128_UB(tmp0, tmp1); out1 = PCKEV_XORI128_UB(tmp2, tmp3); @@ -2425,15 +2340,13 @@ static void common_vt_4t_6w_msa(uint8_t *src, int32_t src_stride, static void common_vt_4t_8x2_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, uint8_t rnd_val) + const int8_t *filter) { v16i8 src0, src1, src2, src3, src4; v8i16 src01, src12, src23, src34, tmp0, tmp1, filt, filt0, filt1; v16u8 out; - v8i16 rnd_vec; src -= src_stride; - rnd_vec = __msa_fill_h(rnd_val); /* rearranging filter_y */ filt = LD_SH(filter); @@ -2445,7 +2358,7 @@ static void common_vt_4t_8x2_msa(uint8_t *src, int32_t src_stride, tmp0 = FILT_4TAP_DPADD_S_H(src01, src23, filt0, filt1); ILVR_B2_SH(src2, src1, src4, src3, src12, src34); tmp1 = FILT_4TAP_DPADD_S_H(src12, src34, filt0, filt1); - SRAR_H2_SH(tmp0, tmp1, rnd_vec); + SRARI_H2_SH(tmp0, tmp1, 6); SAT_SH2_SH(tmp0, tmp1, 7); out = PCKEV_XORI128_UB(tmp0, tmp1); ST8x2_UB(out, dst, dst_stride); @@ -2453,17 +2366,15 @@ static void common_vt_4t_8x2_msa(uint8_t *src, int32_t src_stride, static void common_vt_4t_8x6_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, uint8_t rnd_val) + const int8_t *filter) { uint32_t loop_cnt; uint64_t out0, out1, out2; v16i8 src0, src1, src2, src3, src4, src5; v8i16 vec0, vec1, vec2, vec3, vec4, tmp0, tmp1, tmp2; v8i16 filt, filt0, filt1; - v8i16 rnd_vec; src -= src_stride; - rnd_vec = __msa_fill_h(rnd_val); /* rearranging filter_y */ filt = LD_SH(filter); @@ -2484,7 +2395,8 @@ static void common_vt_4t_8x6_msa(uint8_t *src, int32_t src_stride, tmp0 = FILT_4TAP_DPADD_S_H(vec0, vec1, filt0, filt1); tmp1 = FILT_4TAP_DPADD_S_H(vec2, vec3, filt0, filt1); tmp2 = FILT_4TAP_DPADD_S_H(vec1, vec4, filt0, filt1); - SRAR_H3_SH(tmp0, tmp1, tmp2, rnd_vec); + SRARI_H2_SH(tmp0, tmp1, 6); + tmp2 = __msa_srari_h(tmp2, 6); SAT_SH3_SH(tmp0, tmp1, tmp2, 7); PCKEV_B2_SH(tmp1, tmp0, tmp2, tmp2, tmp0, tmp2); XORI_B2_128_SH(tmp0, tmp2); @@ -2507,18 +2419,15 @@ static void common_vt_4t_8x6_msa(uint8_t *src, int32_t src_stride, static void common_vt_4t_8x4mult_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { uint32_t loop_cnt; v16i8 src0, src1, src2, src7, src8, src9, src10; v16i8 src10_r, src72_r, src98_r, src21_r, src87_r, src109_r, filt0, filt1; v16u8 tmp0, tmp1; v8i16 filt, out0_r, out1_r, out2_r, out3_r; - v8i16 rnd_vec; src -= src_stride; - rnd_vec = __msa_fill_h(rnd_val); filt = LD_SH(filter); SPLATI_H2_SB(filt, 0, 1, filt0, filt1); @@ -2540,7 +2449,7 @@ static void common_vt_4t_8x4mult_msa(uint8_t *src, int32_t src_stride, out1_r = FILT_4TAP_DPADD_S_H(src21_r, src87_r, filt0, filt1); out2_r = FILT_4TAP_DPADD_S_H(src72_r, src98_r, filt0, filt1); out3_r = FILT_4TAP_DPADD_S_H(src87_r, src109_r, filt0, filt1); - SRAR_H4_SH(out0_r, out1_r, out2_r, out3_r, rnd_vec); + SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, 6); SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); tmp0 = PCKEV_XORI128_UB(out0_r, out1_r); tmp1 = PCKEV_XORI128_UB(out2_r, out3_r); @@ -2555,23 +2464,21 @@ static void common_vt_4t_8x4mult_msa(uint8_t *src, int32_t src_stride, static void common_vt_4t_8w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { if (2 == height) { - common_vt_4t_8x2_msa(src, src_stride, dst, dst_stride, filter, rnd_val); + common_vt_4t_8x2_msa(src, src_stride, dst, dst_stride, filter); } else if (6 == height) { - common_vt_4t_8x6_msa(src, src_stride, dst, dst_stride, filter, rnd_val); + common_vt_4t_8x6_msa(src, src_stride, dst, dst_stride, filter); } else { common_vt_4t_8x4mult_msa(src, src_stride, dst, dst_stride, - filter, height, rnd_val); + filter, height); } } static void common_vt_4t_12w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { uint32_t loop_cnt; v16i8 src0, src1, src2, src3, src4, src5, src6; @@ -2580,14 +2487,11 @@ static void common_vt_4t_12w_msa(uint8_t *src, int32_t src_stride, v8i16 src10, src21, src32, src43, src54, src65, src87, src109, src1211; v8i16 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, filt, filt0, filt1; v4u32 mask = { 2, 6, 2, 6 }; - v8i16 rnd_vec; /* rearranging filter_y */ filt = LD_SH(filter); SPLATI_H2_SH(filt, 0, 1, filt0, filt1); - rnd_vec = __msa_fill_h(rnd_val); - src -= src_stride; LD_SB3(src, src_stride, src0, src1, src2); @@ -2613,8 +2517,8 @@ static void common_vt_4t_12w_msa(uint8_t *src, int32_t src_stride, ILVR_B3_SH(vec1, vec0, vec3, vec2, vec5, vec4, src87, src109, src1211); tmp4 = FILT_4TAP_DPADD_S_H(src87, src109, filt0, filt1); tmp5 = FILT_4TAP_DPADD_S_H(src109, src1211, filt0, filt1); - SRAR_H4_SH(tmp0, tmp1, tmp2, tmp3, rnd_vec); - SRAR_H2_SH(tmp4, tmp5, rnd_vec); + SRARI_H4_SH(tmp0, tmp1, tmp2, tmp3, 6); + SRARI_H2_SH(tmp4, tmp5, 6); SAT_SH4_SH(tmp0, tmp1, tmp2, tmp3, 7); SAT_SH2_SH(tmp4, tmp5, 7); out0 = PCKEV_XORI128_UB(tmp0, tmp1); @@ -2635,8 +2539,7 @@ static void common_vt_4t_12w_msa(uint8_t *src, int32_t src_stride, static void common_vt_4t_16w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { uint32_t loop_cnt; v16i8 src0, src1, src2, src3, src4, src5, src6; @@ -2644,10 +2547,8 @@ static void common_vt_4t_16w_msa(uint8_t *src, int32_t src_stride, v16i8 src32_l, src54_l, src21_l, src43_l, src65_l, filt0, filt1; v16u8 tmp0, tmp1, tmp2, tmp3; v8i16 filt, out0_r, out1_r, out2_r, out3_r, out0_l, out1_l, out2_l, out3_l; - v8i16 rnd_vec; src -= src_stride; - rnd_vec = __msa_fill_h(rnd_val); filt = LD_SH(filter); SPLATI_H2_SB(filt, 0, 1, filt0, filt1); @@ -2676,8 +2577,8 @@ static void common_vt_4t_16w_msa(uint8_t *src, int32_t src_stride, out1_l = FILT_4TAP_DPADD_S_H(src21_l, src43_l, filt0, filt1); out2_l = FILT_4TAP_DPADD_S_H(src32_l, src54_l, filt0, filt1); out3_l = FILT_4TAP_DPADD_S_H(src43_l, src65_l, filt0, filt1); - SRAR_H4_SH(out0_r, out1_r, out2_r, out3_r, rnd_vec); - SRAR_H4_SH(out0_l, out1_l, out2_l, out3_l, rnd_vec); + SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, 6); + SRARI_H4_SH(out0_l, out1_l, out2_l, out3_l, 6); SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); SAT_SH4_SH(out0_l, out1_l, out2_l, out3_l, 7); PCKEV_B4_UB(out0_l, out0_r, out1_l, out1_r, out2_l, out2_r, out3_l, @@ -2696,8 +2597,7 @@ static void common_vt_4t_16w_msa(uint8_t *src, int32_t src_stride, static void common_vt_4t_24w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { uint32_t loop_cnt; uint64_t out0, out1; @@ -2707,15 +2607,12 @@ static void common_vt_4t_24w_msa(uint8_t *src, int32_t src_stride, v16i8 src109_r, src10_l, src32_l, src21_l, src43_l; v16u8 out; v8i16 filt, out0_r, out1_r, out2_r, out3_r, out0_l, out1_l; - v8i16 rnd_vec; src -= src_stride; filt = LD_SH(filter); SPLATI_H2_SB(filt, 0, 1, filt0, filt1); - rnd_vec = __msa_fill_h(rnd_val); - /* 16 width */ LD_SB3(src, src_stride, src0, src1, src2); XORI_B3_128_SB(src0, src1, src2); @@ -2752,8 +2649,8 @@ static void common_vt_4t_24w_msa(uint8_t *src, int32_t src_stride, out3_r = FILT_4TAP_DPADD_S_H(src87_r, src109_r, filt0, filt1); /* 16 + 8 width */ - SRAR_H4_SH(out0_r, out1_r, out2_r, out3_r, rnd_vec); - SRAR_H2_SH(out0_l, out1_l, rnd_vec); + SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, 6); + SRARI_H2_SH(out0_l, out1_l, 6); SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); SAT_SH2_SH(out0_l, out1_l, 7); out = PCKEV_XORI128_UB(out0_r, out0_l); @@ -2792,8 +2689,8 @@ static void common_vt_4t_24w_msa(uint8_t *src, int32_t src_stride, out3_r = FILT_4TAP_DPADD_S_H(src109_r, src87_r, filt0, filt1); /* 16 + 8 width */ - SRAR_H4_SH(out0_r, out1_r, out2_r, out3_r, rnd_vec); - SRAR_H2_SH(out0_l, out1_l, rnd_vec); + SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, 6); + SRARI_H2_SH(out0_l, out1_l, 6); SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); SAT_SH2_SH(out0_l, out1_l, 7); out = PCKEV_XORI128_UB(out0_r, out0_l); @@ -2812,7 +2709,7 @@ static void common_vt_4t_24w_msa(uint8_t *src, int32_t src_stride, static void common_vt_4t_32w_mult_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, const int8_t *filter, int32_t height, - uint8_t rnd_val, int32_t width) + int32_t width) { uint32_t loop_cnt, cnt; uint8_t *dst_tmp, *src_tmp; @@ -2824,11 +2721,9 @@ static void common_vt_4t_32w_mult_msa(uint8_t *src, int32_t src_stride, v16i8 src21_l, src43_l, src87_l, src109_l; v8i16 filt; v16i8 filt0, filt1; - v8i16 rnd_vec; v16u8 out; src -= src_stride; - rnd_vec = __msa_fill_h(rnd_val); filt = LD_SH(filter); SPLATI_H2_SB(filt, 0, 1, filt0, filt1); @@ -2866,7 +2761,7 @@ static void common_vt_4t_32w_mult_msa(uint8_t *src, int32_t src_stride, out1_l = FILT_4TAP_DPADD_S_H(src21_l, src43_l, filt0, filt1); /* 16 width */ - SRAR_H4_SH(out0_r, out1_r, out0_l, out1_l, rnd_vec); + SRARI_H4_SH(out0_r, out1_r, out0_l, out1_l, 6); SAT_SH4_SH(out0_r, out1_r, out0_l, out1_l, 7); out = PCKEV_XORI128_UB(out0_r, out0_l); ST_UB(out, dst_tmp); @@ -2893,7 +2788,7 @@ static void common_vt_4t_32w_mult_msa(uint8_t *src, int32_t src_stride, out3_l = FILT_4TAP_DPADD_S_H(src87_l, src109_l, filt0, filt1); /* next 16 width */ - SRAR_H4_SH(out2_r, out3_r, out2_l, out3_l, rnd_vec); + SRARI_H4_SH(out2_r, out3_r, out2_l, out3_l, 6); SAT_SH4_SH(out2_r, out3_r, out2_l, out3_l, 7); out = PCKEV_XORI128_UB(out2_r, out2_l); ST_UB(out, dst_tmp + 16); @@ -2916,11 +2811,10 @@ static void common_vt_4t_32w_mult_msa(uint8_t *src, int32_t src_stride, static void common_vt_4t_32w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, - uint8_t rnd_val) + const int8_t *filter, int32_t height) { common_vt_4t_32w_mult_msa(src, src_stride, dst, dst_stride, - filter, height, rnd_val, 32); + filter, height, 32); } static void hevc_hv_uni_4t_4x2_msa(uint8_t *src, @@ -3885,7 +3779,7 @@ void ff_hevc_put_hevc_uni_##PEL##_##DIR##WIDTH##_8_msa(uint8_t *dst, \ const int8_t *filter = ff_hevc_##PEL##_filters[FILT_DIR - 1]; \ \ common_##DIR1##_##TAP##t_##WIDTH##w_msa(src, src_stride, dst, dst_stride, \ - filter, height, 6); \ + filter, height); \ } UNI_MC(qpel, h, 4, 8, hz, mx); From e428e5ded6266d8e68cecbd9953fdaba55b097e1 Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Mon, 18 Sep 2017 13:54:40 +0530 Subject: [PATCH 3123/3374] avcodec/mips: preload data in hevc sao edge 0 degree filter msa functions Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/hevc_lpf_sao_msa.c | 232 +++++++++++++++++------------ 1 file changed, 138 insertions(+), 94 deletions(-) diff --git a/libavcodec/mips/hevc_lpf_sao_msa.c b/libavcodec/mips/hevc_lpf_sao_msa.c index 1d77432676cdd..3472d32322c1b 100644 --- a/libavcodec/mips/hevc_lpf_sao_msa.c +++ b/libavcodec/mips/hevc_lpf_sao_msa.c @@ -1265,54 +1265,51 @@ static void hevc_sao_edge_filter_0degree_4width_msa(uint8_t *dst, int16_t *sao_offset_val, int32_t height) { - int32_t h_cnt; uint32_t dst_val0, dst_val1; - v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 }; + v16u8 cmp_minus10, diff_minus10, diff_minus11, src_minus10, src_minus11; + v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + v16i8 sao_offset = LD_SB(sao_offset_val); + v16i8 src_plus10, offset, src0, dst0; v16u8 const1 = (v16u8) __msa_ldi_b(1); - v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11; - v16u8 src_minus10, src_minus11; v16i8 zero = { 0 }; - v16i8 src_zero0, src_zero1, src_plus10, src_plus11, dst0; - v8i16 offset_mask0, offset_mask1; - v8i16 sao_offset, src00, src01; - sao_offset = LD_SH(sao_offset_val); + sao_offset = __msa_pckev_b(sao_offset, sao_offset); src -= 1; - for (h_cnt = (height >> 1); h_cnt--;) { - LD_UB2(src, src_stride, src_minus10, src_minus11); + /* load in advance */ + LD_UB2(src, src_stride, src_minus10, src_minus11); + + for (height -= 2; height; height -= 2) { src += (2 * src_stride); - SLDI_B2_0_SB(src_minus10, src_minus11, src_zero0, src_zero1, 1); - SLDI_B2_0_SB(src_minus10, src_minus11, src_plus10, src_plus11, 2); - ILVR_B2_UB(src_plus10, src_minus10, src_plus11, src_minus11, - src_minus10, src_minus11); - ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1, src_zero0, - src_zero1); + src_minus10 = (v16u8) __msa_pckev_d((v2i64) src_minus11, + (v2i64) src_minus10); - cmp_minus10 = ((v16u8) src_zero0 == src_minus10); + src0 = (v16i8) __msa_sldi_b(zero, (v16i8) src_minus10, 1); + src_plus10 = (v16i8) __msa_sldi_b(zero, (v16i8) src_minus10, 2); + + cmp_minus10 = ((v16u8) src0 == src_minus10); diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); - cmp_minus10 = (src_minus10 < (v16u8) src_zero0); + cmp_minus10 = (src_minus10 < (v16u8) src0); diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); - cmp_minus11 = ((v16u8) src_zero1 == src_minus11); - diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); - cmp_minus11 = (src_minus11 < (v16u8) src_zero1); - diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); + cmp_minus10 = ((v16u8) src0 == (v16u8) src_plus10); + diff_minus11 = __msa_nor_v(cmp_minus10, cmp_minus10); + cmp_minus10 = ((v16u8) src_plus10 < (v16u8) src0); + diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus10); - offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); - offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); + offset = (v16i8) diff_minus10 + (v16i8) diff_minus11 + 2; - VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0, - offset_mask0, offset_mask0, offset_mask0); - VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1, - offset_mask1, offset_mask1, offset_mask1); - ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01); - ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0, - offset_mask1); - CLIP_SH2_0_255(offset_mask0, offset_mask1); + /* load in advance */ + LD_UB2(src, src_stride, src_minus10, src_minus11); + + VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, + offset, offset); + + src0 = (v16i8) __msa_xori_b((v16u8) src0, 128); + dst0 = __msa_adds_s_b(src0, offset); + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); - dst0 = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); dst_val0 = __msa_copy_u_w((v4i32) dst0, 0); dst_val1 = __msa_copy_u_w((v4i32) dst0, 2); SW(dst_val0, dst); @@ -1320,6 +1317,37 @@ static void hevc_sao_edge_filter_0degree_4width_msa(uint8_t *dst, SW(dst_val1, dst); dst += dst_stride; } + + src_minus10 = (v16u8) __msa_pckev_d((v2i64) src_minus11, + (v2i64) src_minus10); + + src0 = (v16i8) __msa_sldi_b(zero, (v16i8) src_minus10, 1); + src_plus10 = (v16i8) __msa_sldi_b(zero, (v16i8) src_minus10, 2); + + cmp_minus10 = ((v16u8) src0 == src_minus10); + diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); + cmp_minus10 = (src_minus10 < (v16u8) src0); + diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); + + cmp_minus10 = ((v16u8) src0 == (v16u8) src_plus10); + diff_minus11 = __msa_nor_v(cmp_minus10, cmp_minus10); + cmp_minus10 = ((v16u8) src_plus10 < (v16u8) src0); + diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus10); + + offset = (v16i8) diff_minus10 + (v16i8) diff_minus11 + 2; + VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, + offset, offset); + + src0 = (v16i8) __msa_xori_b((v16u8) src0, 128); + dst0 = __msa_adds_s_b(src0, offset); + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); + + dst_val0 = __msa_copy_u_w((v4i32) dst0, 0); + dst_val1 = __msa_copy_u_w((v4i32) dst0, 2); + + SW(dst_val0, dst); + dst += dst_stride; + SW(dst_val1, dst); } static void hevc_sao_edge_filter_0degree_8width_msa(uint8_t *dst, @@ -1329,64 +1357,90 @@ static void hevc_sao_edge_filter_0degree_8width_msa(uint8_t *dst, int16_t *sao_offset_val, int32_t height) { - uint8_t *src_minus1; - int32_t h_cnt; uint64_t dst_val0, dst_val1; - v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 }; + v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; v16u8 const1 = (v16u8) __msa_ldi_b(1); - v16i8 dst0, dst1; - v16i8 zero = { 0 }; - v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11; - v16u8 src_minus10, src_minus11; - v16i8 src_zero0, src_plus10, src_zero1, src_plus11; - v8i16 sao_offset, src00, offset_mask0, src01, offset_mask1; + v16u8 cmp_minus10, diff_minus10, diff_minus11; + v16u8 src0, src1, dst0, src_minus10, src_minus11, src_plus10, src_plus11; + v16i8 offset, sao_offset = LD_SB(sao_offset_val); - sao_offset = LD_SH(sao_offset_val); + sao_offset = __msa_pckev_b(sao_offset, sao_offset); + src -= 1; - for (h_cnt = (height >> 1); h_cnt--;) { - src_minus1 = src - 1; - LD_UB2(src_minus1, src_stride, src_minus10, src_minus11); + /* load in advance */ + LD_UB2(src, src_stride, src_minus10, src_minus11); - SLDI_B2_0_SB(src_minus10, src_minus11, src_zero0, src_zero1, 1); - SLDI_B2_0_SB(src_minus10, src_minus11, src_plus10, src_plus11, 2); - ILVR_B2_UB(src_plus10, src_minus10, src_plus11, src_minus11, - src_minus10, src_minus11); - ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1, - src_zero0, src_zero1); + for (height -= 2; height; height -= 2) { + src += (src_stride << 1); - cmp_minus10 = ((v16u8) src_zero0 == src_minus10); + SLDI_B2_0_UB(src_minus10, src_minus11, src0, src1, 1); + SLDI_B2_0_UB(src_minus10, src_minus11, src_plus10, src_plus11, 2); + + PCKEV_D2_UB(src_minus11, src_minus10, src_plus11, src_plus10, + src_minus10, src_plus10); + src0 = (v16u8) __msa_pckev_d((v2i64) src1, (v2i64) src0); + + cmp_minus10 = (src0 == src_minus10); diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); - cmp_minus10 = (src_minus10 < (v16u8) src_zero0); + cmp_minus10 = (src_minus10 < src0); diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); - cmp_minus11 = ((v16u8) src_zero1 == src_minus11); - diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); - cmp_minus11 = (src_minus11 < (v16u8) src_zero1); - diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); + cmp_minus10 = (src0 == src_plus10); + diff_minus11 = __msa_nor_v(cmp_minus10, cmp_minus10); + cmp_minus10 = (src_plus10 < src0); + diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus10); - offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); - offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); + offset = (v16i8) diff_minus10 + (v16i8) diff_minus11 + 2; - VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0, - offset_mask0, offset_mask0, offset_mask0); - VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1, - offset_mask1, offset_mask1, offset_mask1); - ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01); + /* load in advance */ + LD_UB2(src, src_stride, src_minus10, src_minus11); - ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0, - offset_mask1); - CLIP_SH2_0_255(offset_mask0, offset_mask1); - PCKEV_B2_SB(offset_mask0, offset_mask0, offset_mask1, offset_mask1, - dst0, dst1); + VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, + offset, offset); + + src0 = __msa_xori_b(src0, 128); + dst0 = (v16u8) __msa_adds_s_b((v16i8) src0, offset); + dst0 = __msa_xori_b(dst0, 128); dst_val0 = __msa_copy_u_d((v2i64) dst0, 0); - dst_val1 = __msa_copy_u_d((v2i64) dst1, 0); + dst_val1 = __msa_copy_u_d((v2i64) dst0, 1); SD(dst_val0, dst); dst += dst_stride; SD(dst_val1, dst); dst += dst_stride; - src += (src_stride << 1); } + + SLDI_B2_0_UB(src_minus10, src_minus11, src0, src1, 1); + SLDI_B2_0_UB(src_minus10, src_minus11, src_plus10, src_plus11, 2); + + PCKEV_D2_UB(src_minus11, src_minus10, src_plus11, src_plus10, src_minus10, + src_plus10); + src0 = (v16u8) __msa_pckev_d((v2i64) src1, (v2i64) src0); + + cmp_minus10 = ((v16u8) src0 == src_minus10); + diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); + cmp_minus10 = (src_minus10 < (v16u8) src0); + diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); + + cmp_minus10 = (src0 == src_plus10); + diff_minus11 = __msa_nor_v(cmp_minus10, cmp_minus10); + cmp_minus10 = (src_plus10 < src0); + diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus10); + + offset = (v16i8) diff_minus10 + (v16i8) diff_minus11 + 2; + + VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, + offset, offset); + + src0 = __msa_xori_b(src0, 128); + dst0 = (v16u8) __msa_adds_s_b((v16i8) src0, offset); + dst0 = __msa_xori_b(dst0, 128); + + dst_val0 = __msa_copy_u_d((v2i64) dst0, 0); + dst_val1 = __msa_copy_u_d((v2i64) dst0, 1); + SD(dst_val0, dst); + dst += dst_stride; + SD(dst_val1, dst); } static void hevc_sao_edge_filter_0degree_16multiple_msa(uint8_t *dst, @@ -1398,7 +1452,7 @@ static void hevc_sao_edge_filter_0degree_16multiple_msa(uint8_t *dst, int32_t height) { uint8_t *dst_ptr, *src_minus1; - int32_t h_cnt, v_cnt; + int32_t v_cnt; v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; v16u8 const1 = (v16u8) __msa_ldi_b(1); v16i8 sao_offset; @@ -1411,20 +1465,18 @@ static void hevc_sao_edge_filter_0degree_16multiple_msa(uint8_t *dst, v16i8 offset_mask0, offset_mask1, offset_mask2, offset_mask3; v16i8 src_zero0, src_zero1, src_zero2, src_zero3; v16i8 src_plus10, src_plus11, src_plus12, src_plus13; - v8i16 src0, src1, src2, src3, src4, src5, src6, src7; - v8i16 temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7; sao_offset = LD_SB(sao_offset_val); sao_offset = __msa_pckev_b(sao_offset, sao_offset); - for (h_cnt = (height >> 2); h_cnt--;) { + for (; height; height -= 4) { src_minus1 = src - 1; LD_UB4(src_minus1, src_stride, src_minus10, src_minus11, src_minus12, src_minus13); - for (v_cnt = 0; v_cnt < (width >> 4); v_cnt++) { + for (v_cnt = 0; v_cnt < width; v_cnt += 16) { src_minus1 += 16; - dst_ptr = dst + (v_cnt << 4); + dst_ptr = dst + v_cnt; LD_UB4(src_minus1, src_stride, src10, src11, src12, src13); SLDI_B2_SB(src10, src11, src_minus10, src_minus11, src_zero0, @@ -1485,22 +1537,14 @@ static void hevc_sao_edge_filter_0degree_16multiple_msa(uint8_t *dst, VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask3, offset_mask3, offset_mask3, offset_mask3); - UNPCK_UB_SH(src_zero0, src0, src1); - UNPCK_SB_SH(offset_mask0, temp0, temp1); - UNPCK_UB_SH(src_zero1, src2, src3); - UNPCK_SB_SH(offset_mask1, temp2, temp3); - UNPCK_UB_SH(src_zero2, src4, src5); - UNPCK_SB_SH(offset_mask2, temp4, temp5); - UNPCK_UB_SH(src_zero3, src6, src7); - UNPCK_SB_SH(offset_mask3, temp6, temp7); - ADD4(temp0, src0, temp1, src1, temp2, src2, temp3, src3, temp0, - temp1, temp2, temp3); - ADD4(temp4, src4, temp5, src5, temp6, src6, temp7, src7, temp4, - temp5, temp6, temp7); - CLIP_SH4_0_255(temp0, temp1, temp2, temp3); - CLIP_SH4_0_255(temp4, temp5, temp6, temp7); - PCKEV_B4_UB(temp1, temp0, temp3, temp2, temp5, temp4, temp7, temp6, - dst0, dst1, dst2, dst3); + XORI_B4_128_SB(src_zero0, src_zero1, src_zero2, src_zero3); + + dst0 = (v16u8) __msa_adds_s_b((v16i8) src_zero0, offset_mask0); + dst1 = (v16u8) __msa_adds_s_b((v16i8) src_zero1, offset_mask1); + dst2 = (v16u8) __msa_adds_s_b((v16i8) src_zero2, offset_mask2); + dst3 = (v16u8) __msa_adds_s_b((v16i8) src_zero3, offset_mask3); + + XORI_B4_128_UB(dst0, dst1, dst2, dst3); src_minus10 = src10; ST_UB(dst0, dst_ptr); From b4093e60c51af493a6dad7819264ef769736227f Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Wed, 20 Sep 2017 03:31:48 +0200 Subject: [PATCH 3124/3374] lavf/caf: Support demuxing Opus. Introduced in macOS High Sierra and iOS 11. --- libavformat/caf.c | 1 + libavformat/cafdec.c | 2 ++ libavformat/cafenc.c | 1 + libavformat/version.h | 2 +- 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/libavformat/caf.c b/libavformat/caf.c index 8d394157946e2..fe242ff032724 100644 --- a/libavformat/caf.c +++ b/libavformat/caf.c @@ -52,6 +52,7 @@ const AVCodecTag ff_codec_caf_tags[] = { { AV_CODEC_ID_MP2, MKTAG('.','m','p','2') }, { AV_CODEC_ID_MP3, MKTAG('.','m','p','3') }, { AV_CODEC_ID_MP3, MKTAG('m','s', 0 ,'U') }, + { AV_CODEC_ID_OPUS, MKTAG('o','p','u','s') }, { AV_CODEC_ID_PCM_ALAW, MKTAG('a','l','a','w') }, { AV_CODEC_ID_PCM_MULAW, MKTAG('u','l','a','w') }, { AV_CODEC_ID_QCELP, MKTAG('Q','c','l','p') }, diff --git a/libavformat/cafdec.c b/libavformat/cafdec.c index 19939d3a859fa..4e47addc02678 100644 --- a/libavformat/cafdec.c +++ b/libavformat/cafdec.c @@ -166,6 +166,8 @@ static int read_kuki_chunk(AVFormatContext *s, int64_t size) } avio_skip(pb, size - ALAC_NEW_KUKI); } + } else if (st->codecpar->codec_id == AV_CODEC_ID_OPUS) { + avio_skip(pb, size); } else { av_freep(&st->codecpar->extradata); if (ff_get_extradata(s, st->codecpar, pb, size) < 0) diff --git a/libavformat/cafenc.c b/libavformat/cafenc.c index 7aa9e8cee1095..f550cd965a3c8 100644 --- a/libavformat/cafenc.c +++ b/libavformat/cafenc.c @@ -117,6 +117,7 @@ static int caf_write_header(AVFormatContext *s) switch (par->codec_id) { case AV_CODEC_ID_AAC: + case AV_CODEC_ID_OPUS: av_log(s, AV_LOG_ERROR, "muxing codec currently unsupported\n"); return AVERROR_PATCHWELCOME; } diff --git a/libavformat/version.h b/libavformat/version.h index aeb594041028a..499aecf6c7273 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -33,7 +33,7 @@ // Also please add any ticket numbers that you believe might be affected here #define LIBAVFORMAT_VERSION_MAJOR 57 #define LIBAVFORMAT_VERSION_MINOR 82 -#define LIBAVFORMAT_VERSION_MICRO 100 +#define LIBAVFORMAT_VERSION_MICRO 101 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ From 5a3b602acda68fe5ca09082dc753179450a97a13 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 19 Sep 2017 23:04:55 -0300 Subject: [PATCH 3125/3374] avformat/cafdec: reject multichannel Opus streams Multichannel Opus streams require channel mapping information in extradata. Signed-off-by: James Almer --- libavformat/cafdec.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libavformat/cafdec.c b/libavformat/cafdec.c index 4e47addc02678..7652d9e238597 100644 --- a/libavformat/cafdec.c +++ b/libavformat/cafdec.c @@ -167,6 +167,12 @@ static int read_kuki_chunk(AVFormatContext *s, int64_t size) avio_skip(pb, size - ALAC_NEW_KUKI); } } else if (st->codecpar->codec_id == AV_CODEC_ID_OPUS) { + // The data layout for Opus is currently unknown, so we do not export + // extradata at all. Multichannel streams are not supported. + if (st->codecpar->channels > 2) { + avpriv_request_sample(s, "multichannel Opus in CAF"); + return AVERROR_PATCHWELCOME; + } avio_skip(pb, size); } else { av_freep(&st->codecpar->extradata); From 598e41684066feba701d19ca7443d24b9e5efa77 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Fri, 15 Sep 2017 17:04:38 +0900 Subject: [PATCH 3126/3374] GnuTLS: eat PREMATURE_TERMINATION error GnuTLS is too strict on the SSL shutdown alert, and it's neither mandatory in the spec or critical. As it's ignored in OpenSSL, we should also suppress it in GnuTLS as well. Ticket: #6667 Reviewed-by: wm4 Signed-off-by: Michael Niedermayer --- libavformat/tls_gnutls.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/tls_gnutls.c b/libavformat/tls_gnutls.c index ecc80bfac3f05..38f8ea4804a9a 100644 --- a/libavformat/tls_gnutls.c +++ b/libavformat/tls_gnutls.c @@ -72,6 +72,7 @@ static int print_tls_error(URLContext *h, int ret) switch (ret) { case GNUTLS_E_AGAIN: case GNUTLS_E_INTERRUPTED: + case GNUTLS_E_PREMATURE_TERMINATION: break; case GNUTLS_E_WARNING_ALERT_RECEIVED: av_log(h, AV_LOG_WARNING, "%s\n", gnutls_strerror(ret)); From b5da07d4340a8e8e40dcd1900977a76ff31fbb84 Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Mon, 18 Sep 2017 14:00:13 +0530 Subject: [PATCH 3127/3374] avcodec/mips: Unrolled loops and expanded functions in avc put mc 10 & 30 msa functions Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/h264qpel_msa.c | 284 ++++++++++++++++++++++++++++++++- 1 file changed, 278 insertions(+), 6 deletions(-) diff --git a/libavcodec/mips/h264qpel_msa.c b/libavcodec/mips/h264qpel_msa.c index 05dffeaad2aaa..b7f6c3d5891fc 100644 --- a/libavcodec/mips/h264qpel_msa.c +++ b/libavcodec/mips/h264qpel_msa.c @@ -3065,37 +3065,309 @@ void ff_avg_h264_qpel4_mc00_msa(uint8_t *dst, const uint8_t *src, void ff_put_h264_qpel16_mc10_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_hz_qrt_16w_msa(src - 2, stride, dst, stride, 16, 0); + uint32_t loop_cnt; + v16i8 dst0, dst1, dst2, dst3, src0, src1, src2, src3, src4, src5, src6; + v16i8 mask0, mask1, mask2, mask3, mask4, mask5, src7, vec11; + v16i8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, vec9, vec10; + v8i16 res0, res1, res2, res3, res4, res5, res6, res7; + v16i8 minus5b = __msa_ldi_b(-5); + v16i8 plus20b = __msa_ldi_b(20); + + LD_SB3(&luma_mask_arr[0], 16, mask0, mask1, mask2); + mask3 = mask0 + 8; + mask4 = mask1 + 8; + mask5 = mask2 + 8; + src -= 2; + + for (loop_cnt = 4; loop_cnt--;) { + LD_SB2(src, 16, src0, src1); + src += stride; + LD_SB2(src, 16, src2, src3); + src += stride; + LD_SB2(src, 16, src4, src5); + src += stride; + LD_SB2(src, 16, src6, src7); + src += stride; + + XORI_B8_128_SB(src0, src1, src2, src3, src4, src5, src6, src7); + VSHF_B2_SB(src0, src0, src0, src1, mask0, mask3, vec0, vec3); + VSHF_B2_SB(src2, src2, src2, src3, mask0, mask3, vec6, vec9); + VSHF_B2_SB(src0, src0, src0, src1, mask1, mask4, vec1, vec4); + VSHF_B2_SB(src2, src2, src2, src3, mask1, mask4, vec7, vec10); + VSHF_B2_SB(src0, src0, src0, src1, mask2, mask5, vec2, vec5); + VSHF_B2_SB(src2, src2, src2, src3, mask2, mask5, vec8, vec11); + HADD_SB4_SH(vec0, vec3, vec6, vec9, res0, res1, res2, res3); + DPADD_SB4_SH(vec1, vec4, vec7, vec10, minus5b, minus5b, minus5b, + minus5b, res0, res1, res2, res3); + DPADD_SB4_SH(vec2, vec5, vec8, vec11, plus20b, plus20b, plus20b, + plus20b, res0, res1, res2, res3); + VSHF_B2_SB(src4, src4, src4, src5, mask0, mask3, vec0, vec3); + VSHF_B2_SB(src6, src6, src6, src7, mask0, mask3, vec6, vec9); + VSHF_B2_SB(src4, src4, src4, src5, mask1, mask4, vec1, vec4); + VSHF_B2_SB(src6, src6, src6, src7, mask1, mask4, vec7, vec10); + VSHF_B2_SB(src4, src4, src4, src5, mask2, mask5, vec2, vec5); + VSHF_B2_SB(src6, src6, src6, src7, mask2, mask5, vec8, vec11); + HADD_SB4_SH(vec0, vec3, vec6, vec9, res4, res5, res6, res7); + DPADD_SB4_SH(vec1, vec4, vec7, vec10, minus5b, minus5b, minus5b, + minus5b, res4, res5, res6, res7); + DPADD_SB4_SH(vec2, vec5, vec8, vec11, plus20b, plus20b, plus20b, + plus20b, res4, res5, res6, res7); + SLDI_B2_SB(src1, src3, src0, src2, src0, src2, 2); + SLDI_B2_SB(src5, src7, src4, src6, src4, src6, 2); + SRARI_H4_SH(res0, res1, res2, res3, 5); + SRARI_H4_SH(res4, res5, res6, res7, 5); + SAT_SH4_SH(res0, res1, res2, res3, 7); + SAT_SH4_SH(res4, res5, res6, res7, 7); + PCKEV_B2_SB(res1, res0, res3, res2, dst0, dst1); + PCKEV_B2_SB(res5, res4, res7, res6, dst2, dst3); + dst0 = __msa_aver_s_b(dst0, src0); + dst1 = __msa_aver_s_b(dst1, src2); + dst2 = __msa_aver_s_b(dst2, src4); + dst3 = __msa_aver_s_b(dst3, src6); + XORI_B4_128_SB(dst0, dst1, dst2, dst3); + ST_SB4(dst0, dst1, dst2, dst3, dst, stride); + dst += (4 * stride); + } } void ff_put_h264_qpel16_mc30_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_hz_qrt_16w_msa(src - 2, stride, dst, stride, 16, 1); + uint32_t loop_cnt; + v16i8 dst0, dst1, dst2, dst3, src0, src1, src2, src3, src4, src5, src6; + v16i8 mask0, mask1, mask2, mask3, mask4, mask5, src7, vec11; + v16i8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, vec9, vec10; + v8i16 res0, res1, res2, res3, res4, res5, res6, res7; + v16i8 minus5b = __msa_ldi_b(-5); + v16i8 plus20b = __msa_ldi_b(20); + + LD_SB3(&luma_mask_arr[0], 16, mask0, mask1, mask2); + mask3 = mask0 + 8; + mask4 = mask1 + 8; + mask5 = mask2 + 8; + src -= 2; + + for (loop_cnt = 4; loop_cnt--;) { + LD_SB2(src, 16, src0, src1); + src += stride; + LD_SB2(src, 16, src2, src3); + src += stride; + LD_SB2(src, 16, src4, src5); + src += stride; + LD_SB2(src, 16, src6, src7); + src += stride; + + XORI_B8_128_SB(src0, src1, src2, src3, src4, src5, src6, src7); + VSHF_B2_SB(src0, src0, src0, src1, mask0, mask3, vec0, vec3); + VSHF_B2_SB(src2, src2, src2, src3, mask0, mask3, vec6, vec9); + VSHF_B2_SB(src0, src0, src0, src1, mask1, mask4, vec1, vec4); + VSHF_B2_SB(src2, src2, src2, src3, mask1, mask4, vec7, vec10); + VSHF_B2_SB(src0, src0, src0, src1, mask2, mask5, vec2, vec5); + VSHF_B2_SB(src2, src2, src2, src3, mask2, mask5, vec8, vec11); + HADD_SB4_SH(vec0, vec3, vec6, vec9, res0, res1, res2, res3); + DPADD_SB4_SH(vec1, vec4, vec7, vec10, minus5b, minus5b, minus5b, + minus5b, res0, res1, res2, res3); + DPADD_SB4_SH(vec2, vec5, vec8, vec11, plus20b, plus20b, plus20b, + plus20b, res0, res1, res2, res3); + VSHF_B2_SB(src4, src4, src4, src5, mask0, mask3, vec0, vec3); + VSHF_B2_SB(src6, src6, src6, src7, mask0, mask3, vec6, vec9); + VSHF_B2_SB(src4, src4, src4, src5, mask1, mask4, vec1, vec4); + VSHF_B2_SB(src6, src6, src6, src7, mask1, mask4, vec7, vec10); + VSHF_B2_SB(src4, src4, src4, src5, mask2, mask5, vec2, vec5); + VSHF_B2_SB(src6, src6, src6, src7, mask2, mask5, vec8, vec11); + HADD_SB4_SH(vec0, vec3, vec6, vec9, res4, res5, res6, res7); + DPADD_SB4_SH(vec1, vec4, vec7, vec10, minus5b, minus5b, minus5b, + minus5b, res4, res5, res6, res7); + DPADD_SB4_SH(vec2, vec5, vec8, vec11, plus20b, plus20b, plus20b, + plus20b, res4, res5, res6, res7); + SLDI_B2_SB(src1, src3, src0, src2, src0, src2, 3); + SLDI_B2_SB(src5, src7, src4, src6, src4, src6, 3); + SRARI_H4_SH(res0, res1, res2, res3, 5); + SRARI_H4_SH(res4, res5, res6, res7, 5); + SAT_SH4_SH(res0, res1, res2, res3, 7); + SAT_SH4_SH(res4, res5, res6, res7, 7); + PCKEV_B2_SB(res1, res0, res3, res2, dst0, dst1); + PCKEV_B2_SB(res5, res4, res7, res6, dst2, dst3); + dst0 = __msa_aver_s_b(dst0, src0); + dst1 = __msa_aver_s_b(dst1, src2); + dst2 = __msa_aver_s_b(dst2, src4); + dst3 = __msa_aver_s_b(dst3, src6); + XORI_B4_128_SB(dst0, dst1, dst2, dst3); + ST_SB4(dst0, dst1, dst2, dst3, dst, stride); + dst += (4 * stride); + } } void ff_put_h264_qpel8_mc10_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_hz_qrt_8w_msa(src - 2, stride, dst, stride, 8, 0); + v16i8 src0, src1, src2, src3, src4, src5, src6, src7, mask0, mask1, mask2; + v16i8 tmp0, tmp1, tmp2, tmp3, vec11; + v16i8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, vec9, vec10; + v8i16 res0, res1, res2, res3, res4, res5, res6, res7; + v16i8 minus5b = __msa_ldi_b(-5); + v16i8 plus20b = __msa_ldi_b(20); + + LD_SB3(&luma_mask_arr[0], 16, mask0, mask1, mask2); + LD_SB8(src - 2, stride, src0, src1, src2, src3, src4, src5, src6, src7); + XORI_B8_128_SB(src0, src1, src2, src3, src4, src5, src6, src7); + VSHF_B2_SB(src0, src0, src1, src1, mask0, mask0, vec0, vec1); + VSHF_B2_SB(src2, src2, src3, src3, mask0, mask0, vec2, vec3); + HADD_SB4_SH(vec0, vec1, vec2, vec3, res0, res1, res2, res3); + VSHF_B2_SB(src0, src0, src1, src1, mask1, mask1, vec4, vec5); + VSHF_B2_SB(src2, src2, src3, src3, mask1, mask1, vec6, vec7); + DPADD_SB4_SH(vec4, vec5, vec6, vec7, minus5b, minus5b, minus5b, minus5b, + res0, res1, res2, res3); + VSHF_B2_SB(src0, src0, src1, src1, mask2, mask2, vec8, vec9); + VSHF_B2_SB(src2, src2, src3, src3, mask2, mask2, vec10, vec11); + DPADD_SB4_SH(vec8, vec9, vec10, vec11, plus20b, plus20b, plus20b, plus20b, + res0, res1, res2, res3); + VSHF_B2_SB(src4, src4, src5, src5, mask0, mask0, vec0, vec1); + VSHF_B2_SB(src6, src6, src7, src7, mask0, mask0, vec2, vec3); + HADD_SB4_SH(vec0, vec1, vec2, vec3, res4, res5, res6, res7); + VSHF_B2_SB(src4, src4, src5, src5, mask1, mask1, vec4, vec5); + VSHF_B2_SB(src6, src6, src7, src7, mask1, mask1, vec6, vec7); + DPADD_SB4_SH(vec4, vec5, vec6, vec7, minus5b, minus5b, minus5b, minus5b, + res4, res5, res6, res7); + VSHF_B2_SB(src4, src4, src5, src5, mask2, mask2, vec8, vec9); + VSHF_B2_SB(src6, src6, src7, src7, mask2, mask2, vec10, vec11); + DPADD_SB4_SH(vec8, vec9, vec10, vec11, plus20b, plus20b, plus20b, plus20b, + res4, res5, res6, res7); + SLDI_B2_SB(src0, src1, src0, src1, src0, src1, 2); + SLDI_B2_SB(src2, src3, src2, src3, src2, src3, 2); + SLDI_B2_SB(src4, src5, src4, src5, src4, src5, 2); + SLDI_B2_SB(src6, src7, src6, src7, src6, src7, 2); + PCKEV_D2_SB(src1, src0, src3, src2, src0, src1); + PCKEV_D2_SB(src5, src4, src7, src6, src4, src5); + SRARI_H4_SH(res0, res1, res2, res3, 5); + SRARI_H4_SH(res4, res5, res6, res7, 5); + SAT_SH4_SH(res0, res1, res2, res3, 7); + SAT_SH4_SH(res4, res5, res6, res7, 7); + PCKEV_B2_SB(res1, res0, res3, res2, tmp0, tmp1); + PCKEV_B2_SB(res5, res4, res7, res6, tmp2, tmp3); + tmp0 = __msa_aver_s_b(tmp0, src0); + tmp1 = __msa_aver_s_b(tmp1, src1); + tmp2 = __msa_aver_s_b(tmp2, src4); + tmp3 = __msa_aver_s_b(tmp3, src5); + XORI_B4_128_SB(tmp0, tmp1, tmp2, tmp3); + ST8x8_UB(tmp0, tmp1, tmp2, tmp3, dst, stride); } void ff_put_h264_qpel8_mc30_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_hz_qrt_8w_msa(src - 2, stride, dst, stride, 8, 1); + v16i8 src0, src1, src2, src3, src4, src5, src6, src7, mask0, mask1, mask2; + v16i8 tmp0, tmp1, tmp2, tmp3, vec11; + v16i8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, vec9, vec10; + v8i16 res0, res1, res2, res3, res4, res5, res6, res7; + v16i8 minus5b = __msa_ldi_b(-5); + v16i8 plus20b = __msa_ldi_b(20); + + LD_SB3(&luma_mask_arr[0], 16, mask0, mask1, mask2); + LD_SB8(src - 2, stride, src0, src1, src2, src3, src4, src5, src6, src7); + XORI_B8_128_SB(src0, src1, src2, src3, src4, src5, src6, src7); + VSHF_B2_SB(src0, src0, src1, src1, mask0, mask0, vec0, vec1); + VSHF_B2_SB(src2, src2, src3, src3, mask0, mask0, vec2, vec3); + HADD_SB4_SH(vec0, vec1, vec2, vec3, res0, res1, res2, res3); + VSHF_B2_SB(src0, src0, src1, src1, mask1, mask1, vec4, vec5); + VSHF_B2_SB(src2, src2, src3, src3, mask1, mask1, vec6, vec7); + DPADD_SB4_SH(vec4, vec5, vec6, vec7, minus5b, minus5b, minus5b, minus5b, + res0, res1, res2, res3); + VSHF_B2_SB(src0, src0, src1, src1, mask2, mask2, vec8, vec9); + VSHF_B2_SB(src2, src2, src3, src3, mask2, mask2, vec10, vec11); + DPADD_SB4_SH(vec8, vec9, vec10, vec11, plus20b, plus20b, plus20b, plus20b, + res0, res1, res2, res3); + VSHF_B2_SB(src4, src4, src5, src5, mask0, mask0, vec0, vec1); + VSHF_B2_SB(src6, src6, src7, src7, mask0, mask0, vec2, vec3); + HADD_SB4_SH(vec0, vec1, vec2, vec3, res4, res5, res6, res7); + VSHF_B2_SB(src4, src4, src5, src5, mask1, mask1, vec4, vec5); + VSHF_B2_SB(src6, src6, src7, src7, mask1, mask1, vec6, vec7); + DPADD_SB4_SH(vec4, vec5, vec6, vec7, minus5b, minus5b, minus5b, minus5b, + res4, res5, res6, res7); + VSHF_B2_SB(src4, src4, src5, src5, mask2, mask2, vec8, vec9); + VSHF_B2_SB(src6, src6, src7, src7, mask2, mask2, vec10, vec11); + DPADD_SB4_SH(vec8, vec9, vec10, vec11, plus20b, plus20b, plus20b, plus20b, + res4, res5, res6, res7); + SLDI_B2_SB(src0, src1, src0, src1, src0, src1, 3); + SLDI_B2_SB(src2, src3, src2, src3, src2, src3, 3); + SLDI_B2_SB(src4, src5, src4, src5, src4, src5, 3); + SLDI_B2_SB(src6, src7, src6, src7, src6, src7, 3); + PCKEV_D2_SB(src1, src0, src3, src2, src0, src1); + PCKEV_D2_SB(src5, src4, src7, src6, src4, src5); + SRARI_H4_SH(res0, res1, res2, res3, 5); + SRARI_H4_SH(res4, res5, res6, res7, 5); + SAT_SH4_SH(res0, res1, res2, res3, 7); + SAT_SH4_SH(res4, res5, res6, res7, 7); + PCKEV_B2_SB(res1, res0, res3, res2, tmp0, tmp1); + PCKEV_B2_SB(res5, res4, res7, res6, tmp2, tmp3); + tmp0 = __msa_aver_s_b(tmp0, src0); + tmp1 = __msa_aver_s_b(tmp1, src1); + tmp2 = __msa_aver_s_b(tmp2, src4); + tmp3 = __msa_aver_s_b(tmp3, src5); + XORI_B4_128_SB(tmp0, tmp1, tmp2, tmp3); + ST8x8_UB(tmp0, tmp1, tmp2, tmp3, dst, stride); } void ff_put_h264_qpel4_mc10_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_hz_qrt_4w_msa(src - 2, stride, dst, stride, 4, 0); + v16i8 src0, src1, src2, src3, res, mask0, mask1, mask2; + v16i8 vec0, vec1, vec2, vec3, vec4, vec5; + v8i16 res0, res1; + v16i8 minus5b = __msa_ldi_b(-5); + v16i8 plus20b = __msa_ldi_b(20); + + LD_SB3(&luma_mask_arr[48], 16, mask0, mask1, mask2); + LD_SB4(src - 2, stride, src0, src1, src2, src3); + XORI_B4_128_SB(src0, src1, src2, src3); + VSHF_B2_SB(src0, src1, src2, src3, mask0, mask0, vec0, vec1); + HADD_SB2_SH(vec0, vec1, res0, res1); + VSHF_B2_SB(src0, src1, src2, src3, mask1, mask1, vec2, vec3); + DPADD_SB2_SH(vec2, vec3, minus5b, minus5b, res0, res1); + VSHF_B2_SB(src0, src1, src2, src3, mask2, mask2, vec4, vec5); + DPADD_SB2_SH(vec4, vec5, plus20b, plus20b, res0, res1); + SRARI_H2_SH(res0, res1, 5); + SAT_SH2_SH(res0, res1, 7); + res = __msa_pckev_b((v16i8) res1, (v16i8) res0); + SLDI_B2_SB(src0, src1, src0, src1, src0, src1, 2); + SLDI_B2_SB(src2, src3, src2, src3, src2, src3, 2); + src0 = (v16i8) __msa_insve_w((v4i32) src0, 1, (v4i32) src1); + src1 = (v16i8) __msa_insve_w((v4i32) src2, 1, (v4i32) src3); + src0 = (v16i8) __msa_insve_d((v2i64) src0, 1, (v2i64) src1); + res = __msa_aver_s_b(res, src0); + res = (v16i8) __msa_xori_b((v16u8) res, 128); + ST4x4_UB(res, res, 0, 1, 2, 3, dst, stride); } void ff_put_h264_qpel4_mc30_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_hz_qrt_4w_msa(src - 2, stride, dst, stride, 4, 1); + v16i8 src0, src1, src2, src3, res, mask0, mask1, mask2; + v16i8 vec0, vec1, vec2, vec3, vec4, vec5; + v8i16 res0, res1; + v16i8 minus5b = __msa_ldi_b(-5); + v16i8 plus20b = __msa_ldi_b(20); + + LD_SB3(&luma_mask_arr[48], 16, mask0, mask1, mask2); + LD_SB4(src - 2, stride, src0, src1, src2, src3); + XORI_B4_128_SB(src0, src1, src2, src3); + VSHF_B2_SB(src0, src1, src2, src3, mask0, mask0, vec0, vec1); + HADD_SB2_SH(vec0, vec1, res0, res1); + VSHF_B2_SB(src0, src1, src2, src3, mask1, mask1, vec2, vec3); + DPADD_SB2_SH(vec2, vec3, minus5b, minus5b, res0, res1); + VSHF_B2_SB(src0, src1, src2, src3, mask2, mask2, vec4, vec5); + DPADD_SB2_SH(vec4, vec5, plus20b, plus20b, res0, res1); + SRARI_H2_SH(res0, res1, 5); + SAT_SH2_SH(res0, res1, 7); + res = __msa_pckev_b((v16i8) res1, (v16i8) res0); + SLDI_B2_SB(src0, src1, src0, src1, src0, src1, 3); + SLDI_B2_SB(src2, src3, src2, src3, src2, src3, 3); + src0 = (v16i8) __msa_insve_w((v4i32) src0, 1, (v4i32) src1); + src1 = (v16i8) __msa_insve_w((v4i32) src2, 1, (v4i32) src3); + src0 = (v16i8) __msa_insve_d((v2i64) src0, 1, (v2i64) src1); + res = __msa_aver_s_b(res, src0); + res = (v16i8) __msa_xori_b((v16u8) res, 128); + ST4x4_UB(res, res, 0, 1, 2, 3, dst, stride); } void ff_put_h264_qpel16_mc20_msa(uint8_t *dst, const uint8_t *src, From bba9c1c6bb17529ffbf44fe96984408ebb89dae0 Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Mon, 18 Sep 2017 14:08:37 +0530 Subject: [PATCH 3128/3374] avcodec/mips: Reduced conditional cases in avc inter lpf msa functions Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/h264dsp_msa.c | 274 ++++++++++++++-------------------- 1 file changed, 110 insertions(+), 164 deletions(-) diff --git a/libavcodec/mips/h264dsp_msa.c b/libavcodec/mips/h264dsp_msa.c index a17eacb98ac74..422703d03d46c 100644 --- a/libavcodec/mips/h264dsp_msa.c +++ b/libavcodec/mips/h264dsp_msa.c @@ -1250,21 +1250,7 @@ static void avc_loopfilter_luma_inter_edge_ver_msa(uint8_t *data, uint8_t beta_in, uint32_t img_width) { - uint8_t *src; - v16u8 beta, tmp_vec, bs = { 0 }; - v16u8 tc = { 0 }; - v16u8 is_less_than, is_less_than_beta; - v16u8 p1, p0, q0, q1; - v8i16 p0_r, q0_r, p1_r = { 0 }; - v8i16 q1_r = { 0 }; - v8i16 p0_l, q0_l, p1_l = { 0 }; - v8i16 q1_l = { 0 }; - v16u8 p3_org, p2_org, p1_org, p0_org, q0_org, q1_org, q2_org, q3_org; - v8i16 p2_org_r, p1_org_r, p0_org_r, q0_org_r, q1_org_r, q2_org_r; - v8i16 p2_org_l, p1_org_l, p0_org_l, q0_org_l, q1_org_l, q2_org_l; - v8i16 tc_r, tc_l; - v16i8 zero = { 0 }; - v16u8 is_bs_greater_than0; + v16u8 tmp_vec, bs = { 0 }; tmp_vec = (v16u8) __msa_fill_b(bs0); bs = (v16u8) __msa_insve_w((v4i32) bs, 0, (v4i32) tmp_vec); @@ -1276,6 +1262,14 @@ static void avc_loopfilter_luma_inter_edge_ver_msa(uint8_t *data, bs = (v16u8) __msa_insve_w((v4i32) bs, 3, (v4i32) tmp_vec); if (!__msa_test_bz_v(bs)) { + uint8_t *src = data - 4; + v16u8 p3_org, p2_org, p1_org, p0_org, q0_org, q1_org, q2_org, q3_org; + v16u8 p0_asub_q0, p1_asub_p0, q1_asub_q0, alpha, beta; + v16u8 is_less_than, is_less_than_beta, is_less_than_alpha; + v16u8 is_bs_greater_than0; + v16u8 tc = { 0 }; + v16i8 zero = { 0 }; + tmp_vec = (v16u8) __msa_fill_b(tc0); tc = (v16u8) __msa_insve_w((v4i32) tc, 0, (v4i32) tmp_vec); tmp_vec = (v16u8) __msa_fill_b(tc1); @@ -1291,9 +1285,6 @@ static void avc_loopfilter_luma_inter_edge_ver_msa(uint8_t *data, v16u8 row0, row1, row2, row3, row4, row5, row6, row7; v16u8 row8, row9, row10, row11, row12, row13, row14, row15; - src = data; - src -= 4; - LD_UB8(src, img_width, row0, row1, row2, row3, row4, row5, row6, row7); src += (8 * img_width); @@ -1306,27 +1297,28 @@ static void avc_loopfilter_luma_inter_edge_ver_msa(uint8_t *data, p3_org, p2_org, p1_org, p0_org, q0_org, q1_org, q2_org, q3_org); } - { - v16u8 p0_asub_q0, p1_asub_p0, q1_asub_q0, alpha; - v16u8 is_less_than_alpha; - - p0_asub_q0 = __msa_asub_u_b(p0_org, q0_org); - p1_asub_p0 = __msa_asub_u_b(p1_org, p0_org); - q1_asub_q0 = __msa_asub_u_b(q1_org, q0_org); - - alpha = (v16u8) __msa_fill_b(alpha_in); - beta = (v16u8) __msa_fill_b(beta_in); - - is_less_than_alpha = (p0_asub_q0 < alpha); - is_less_than_beta = (p1_asub_p0 < beta); - is_less_than = is_less_than_beta & is_less_than_alpha; - is_less_than_beta = (q1_asub_q0 < beta); - is_less_than = is_less_than_beta & is_less_than; - is_less_than = is_less_than & is_bs_greater_than0; - } + + p0_asub_q0 = __msa_asub_u_b(p0_org, q0_org); + p1_asub_p0 = __msa_asub_u_b(p1_org, p0_org); + q1_asub_q0 = __msa_asub_u_b(q1_org, q0_org); + + alpha = (v16u8) __msa_fill_b(alpha_in); + beta = (v16u8) __msa_fill_b(beta_in); + + is_less_than_alpha = (p0_asub_q0 < alpha); + is_less_than_beta = (p1_asub_p0 < beta); + is_less_than = is_less_than_beta & is_less_than_alpha; + is_less_than_beta = (q1_asub_q0 < beta); + is_less_than = is_less_than_beta & is_less_than; + is_less_than = is_less_than & is_bs_greater_than0; + if (!__msa_test_bz_v(is_less_than)) { v16i8 negate_tc, sign_negate_tc; - v8i16 negate_tc_r, i16_negatetc_l; + v16u8 p0, q0, p2_asub_p0, q2_asub_q0; + v8i16 tc_r, tc_l, negate_tc_r, i16_negatetc_l; + v8i16 p1_org_r, p0_org_r, q0_org_r, q1_org_r; + v8i16 p1_org_l, p0_org_l, q0_org_l, q1_org_l; + v8i16 p0_r, q0_r, p0_l, q0_l; negate_tc = zero - (v16i8) tc; sign_negate_tc = __msa_clti_s_b(negate_tc, 0); @@ -1338,34 +1330,22 @@ static void avc_loopfilter_luma_inter_edge_ver_msa(uint8_t *data, UNPCK_UB_SH(p0_org, p0_org_r, p0_org_l); UNPCK_UB_SH(q0_org, q0_org_r, q0_org_l); - { - v16u8 p2_asub_p0; - v16u8 is_less_than_beta_r, is_less_than_beta_l; - - p2_asub_p0 = __msa_asub_u_b(p2_org, p0_org); - is_less_than_beta = (p2_asub_p0 < beta); - is_less_than_beta = is_less_than_beta & is_less_than; - - is_less_than_beta_r = - (v16u8) __msa_sldi_b((v16i8) is_less_than_beta, zero, 8); - if (!__msa_test_bz_v(is_less_than_beta_r)) { - p2_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) p2_org); - - AVC_LPF_P1_OR_Q1(p0_org_r, q0_org_r, p1_org_r, p2_org_r, - negate_tc_r, tc_r, p1_r); - } - - is_less_than_beta_l = - (v16u8) __msa_sldi_b(zero, (v16i8) is_less_than_beta, 8); - if (!__msa_test_bz_v(is_less_than_beta_l)) { - p2_org_l = (v8i16) __msa_ilvl_b(zero, (v16i8) p2_org); - - AVC_LPF_P1_OR_Q1(p0_org_l, q0_org_l, p1_org_l, p2_org_l, - i16_negatetc_l, tc_l, p1_l); - } - } + p2_asub_p0 = __msa_asub_u_b(p2_org, p0_org); + is_less_than_beta = (p2_asub_p0 < beta); + is_less_than_beta = is_less_than_beta & is_less_than; if (!__msa_test_bz_v(is_less_than_beta)) { + v16u8 p1; + v8i16 p1_r = { 0 }; + v8i16 p1_l = { 0 }; + v8i16 p2_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) p2_org); + v8i16 p2_org_l = (v8i16) __msa_ilvl_b(zero, (v16i8) p2_org); + + AVC_LPF_P1_OR_Q1(p0_org_r, q0_org_r, p1_org_r, p2_org_r, + negate_tc_r, tc_r, p1_r); + AVC_LPF_P1_OR_Q1(p0_org_l, q0_org_l, p1_org_l, p2_org_l, + i16_negatetc_l, tc_l, p1_l); + p1 = (v16u8) __msa_pckev_b((v16i8) p1_l, (v16i8) p1_r); p1_org = __msa_bmnz_v(p1_org, p1, is_less_than_beta); @@ -1373,36 +1353,25 @@ static void avc_loopfilter_luma_inter_edge_ver_msa(uint8_t *data, tc = tc + is_less_than_beta; } - { - v16u8 u8_q2asub_q0; - v16u8 is_less_than_beta_l, is_less_than_beta_r; - - u8_q2asub_q0 = __msa_asub_u_b(q2_org, q0_org); - is_less_than_beta = (u8_q2asub_q0 < beta); - is_less_than_beta = is_less_than_beta & is_less_than; - - q1_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) q1_org); - - is_less_than_beta_r = - (v16u8) __msa_sldi_b((v16i8) is_less_than_beta, zero, 8); - if (!__msa_test_bz_v(is_less_than_beta_r)) { - q2_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) q2_org); - AVC_LPF_P1_OR_Q1(p0_org_r, q0_org_r, q1_org_r, q2_org_r, - negate_tc_r, tc_r, q1_r); - } - - q1_org_l = (v8i16) __msa_ilvl_b(zero, (v16i8) q1_org); - - is_less_than_beta_l = - (v16u8) __msa_sldi_b(zero, (v16i8) is_less_than_beta, 8); - if (!__msa_test_bz_v(is_less_than_beta_l)) { - q2_org_l = (v8i16) __msa_ilvl_b(zero, (v16i8) q2_org); - AVC_LPF_P1_OR_Q1(p0_org_l, q0_org_l, q1_org_l, q2_org_l, - i16_negatetc_l, tc_l, q1_l); - } - } + q2_asub_q0 = __msa_asub_u_b(q2_org, q0_org); + is_less_than_beta = (q2_asub_q0 < beta); + is_less_than_beta = is_less_than_beta & is_less_than; + + q1_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) q1_org); + q1_org_l = (v8i16) __msa_ilvl_b(zero, (v16i8) q1_org); if (!__msa_test_bz_v(is_less_than_beta)) { + v16u8 q1; + v8i16 q1_r = { 0 }; + v8i16 q1_l = { 0 }; + v8i16 q2_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) q2_org); + v8i16 q2_org_l = (v8i16) __msa_ilvl_b(zero, (v16i8) q2_org); + + AVC_LPF_P1_OR_Q1(p0_org_r, q0_org_r, q1_org_r, q2_org_r, + negate_tc_r, tc_r, q1_r); + AVC_LPF_P1_OR_Q1(p0_org_l, q0_org_l, q1_org_l, q2_org_l, + i16_negatetc_l, tc_l, q1_l); + q1 = (v16u8) __msa_pckev_b((v16i8) q1_l, (v16i8) q1_r); q1_org = __msa_bmnz_v(q1_org, q1, is_less_than_beta); @@ -1436,7 +1405,7 @@ static void avc_loopfilter_luma_inter_edge_ver_msa(uint8_t *data, p0_org = __msa_bmnz_v(p0_org, p0, is_less_than); q0_org = __msa_bmnz_v(q0_org, q0, is_less_than); - } + { v16i8 tp0, tp1, tp2, tp3; v8i16 tmp2, tmp5; @@ -1548,6 +1517,7 @@ static void avc_loopfilter_luma_inter_edge_ver_msa(uint8_t *data, SW(out2, src); SH(out3, (src + 4)); } + } } } @@ -1560,20 +1530,8 @@ static void avc_loopfilter_luma_inter_edge_hor_msa(uint8_t *data, uint8_t beta_in, uint32_t image_width) { - v16u8 p2_asub_p0, u8_q2asub_q0; - v16u8 alpha, beta, is_less_than, is_less_than_beta; - v16u8 p1, p0, q0, q1; - v8i16 p1_r = { 0 }; - v8i16 p0_r, q0_r, q1_r = { 0 }; - v8i16 p1_l = { 0 }; - v8i16 p0_l, q0_l, q1_l = { 0 }; - v16u8 p2_org, p1_org, p0_org, q0_org, q1_org, q2_org; - v8i16 p2_org_r, p1_org_r, p0_org_r, q0_org_r, q1_org_r, q2_org_r; - v8i16 p2_org_l, p1_org_l, p0_org_l, q0_org_l, q1_org_l, q2_org_l; - v16i8 zero = { 0 }; v16u8 tmp_vec; v16u8 bs = { 0 }; - v16i8 tc = { 0 }; tmp_vec = (v16u8) __msa_fill_b(bs0); bs = (v16u8) __msa_insve_w((v4i32) bs, 0, (v4i32) tmp_vec); @@ -1585,6 +1543,16 @@ static void avc_loopfilter_luma_inter_edge_hor_msa(uint8_t *data, bs = (v16u8) __msa_insve_w((v4i32) bs, 3, (v4i32) tmp_vec); if (!__msa_test_bz_v(bs)) { + v16u8 alpha, beta, is_less_than, is_less_than_beta; + v16u8 p0, q0, p2_org, p1_org, p0_org, q0_org, q1_org, q2_org; + v16u8 p0_asub_q0, p1_asub_p0, q1_asub_q0; + v16u8 is_less_than_alpha, is_bs_greater_than0; + v8i16 p0_r, q0_r, p0_l, q0_l; + v8i16 p1_org_r, p0_org_r, q0_org_r, q1_org_r; + v8i16 p1_org_l, p0_org_l, q0_org_l, q1_org_l; + v16i8 zero = { 0 }; + v16i8 tc = { 0 }; + tmp_vec = (v16u8) __msa_fill_b(tc0); tc = (v16i8) __msa_insve_w((v4i32) tc, 0, (v4i32) tmp_vec); tmp_vec = (v16u8) __msa_fill_b(tc1); @@ -1600,26 +1568,22 @@ static void avc_loopfilter_luma_inter_edge_hor_msa(uint8_t *data, LD_UB5(data - (3 * image_width), image_width, p2_org, p1_org, p0_org, q0_org, q1_org); - { - v16u8 p0_asub_q0, p1_asub_p0, q1_asub_q0; - v16u8 is_less_than_alpha, is_bs_greater_than0; - - is_bs_greater_than0 = ((v16u8) zero < bs); - p0_asub_q0 = __msa_asub_u_b(p0_org, q0_org); - p1_asub_p0 = __msa_asub_u_b(p1_org, p0_org); - q1_asub_q0 = __msa_asub_u_b(q1_org, q0_org); - - is_less_than_alpha = (p0_asub_q0 < alpha); - is_less_than_beta = (p1_asub_p0 < beta); - is_less_than = is_less_than_beta & is_less_than_alpha; - is_less_than_beta = (q1_asub_q0 < beta); - is_less_than = is_less_than_beta & is_less_than; - is_less_than = is_less_than & is_bs_greater_than0; - } + is_bs_greater_than0 = ((v16u8) zero < bs); + p0_asub_q0 = __msa_asub_u_b(p0_org, q0_org); + p1_asub_p0 = __msa_asub_u_b(p1_org, p0_org); + q1_asub_q0 = __msa_asub_u_b(q1_org, q0_org); + + is_less_than_alpha = (p0_asub_q0 < alpha); + is_less_than_beta = (p1_asub_p0 < beta); + is_less_than = is_less_than_beta & is_less_than_alpha; + is_less_than_beta = (q1_asub_q0 < beta); + is_less_than = is_less_than_beta & is_less_than; + is_less_than = is_less_than & is_bs_greater_than0; if (!__msa_test_bz_v(is_less_than)) { v16i8 sign_negate_tc, negate_tc; v8i16 negate_tc_r, i16_negatetc_l, tc_l, tc_r; + v16u8 p2_asub_p0, q2_asub_q0; q2_org = LD_UB(data + (2 * image_width)); negate_tc = zero - tc; @@ -1635,28 +1599,19 @@ static void avc_loopfilter_luma_inter_edge_hor_msa(uint8_t *data, p2_asub_p0 = __msa_asub_u_b(p2_org, p0_org); is_less_than_beta = (p2_asub_p0 < beta); is_less_than_beta = is_less_than_beta & is_less_than; - { - v8u16 is_less_than_beta_r, is_less_than_beta_l; - - is_less_than_beta_r = - (v8u16) __msa_sldi_b((v16i8) is_less_than_beta, zero, 8); - if (!__msa_test_bz_v((v16u8) is_less_than_beta_r)) { - p2_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) p2_org); - AVC_LPF_P1_OR_Q1(p0_org_r, q0_org_r, p1_org_r, p2_org_r, - negate_tc_r, tc_r, p1_r); - } + if (!__msa_test_bz_v(is_less_than_beta)) { + v16u8 p1; + v8i16 p1_r = { 0 }; + v8i16 p1_l = { 0 }; + v8i16 p2_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) p2_org); + v8i16 p2_org_l = (v8i16) __msa_ilvl_b(zero, (v16i8) p2_org); - is_less_than_beta_l = - (v8u16) __msa_sldi_b(zero, (v16i8) is_less_than_beta, 8); - if (!__msa_test_bz_v((v16u8) is_less_than_beta_l)) { - p2_org_l = (v8i16) __msa_ilvl_b(zero, (v16i8) p2_org); + AVC_LPF_P1_OR_Q1(p0_org_r, q0_org_r, p1_org_r, p2_org_r, + negate_tc_r, tc_r, p1_r); + AVC_LPF_P1_OR_Q1(p0_org_l, q0_org_l, p1_org_l, p2_org_l, + i16_negatetc_l, tc_l, p1_l); - AVC_LPF_P1_OR_Q1(p0_org_l, q0_org_l, p1_org_l, p2_org_l, - i16_negatetc_l, tc_l, p1_l); - } - } - if (!__msa_test_bz_v(is_less_than_beta)) { p1 = (v16u8) __msa_pckev_b((v16i8) p1_l, (v16i8) p1_r); p1_org = __msa_bmnz_v(p1_org, p1, is_less_than_beta); ST_UB(p1_org, data - (2 * image_width)); @@ -1665,34 +1620,25 @@ static void avc_loopfilter_luma_inter_edge_hor_msa(uint8_t *data, tc = tc + (v16i8) is_less_than_beta; } - u8_q2asub_q0 = __msa_asub_u_b(q2_org, q0_org); - is_less_than_beta = (u8_q2asub_q0 < beta); + q2_asub_q0 = __msa_asub_u_b(q2_org, q0_org); + is_less_than_beta = (q2_asub_q0 < beta); is_less_than_beta = is_less_than_beta & is_less_than; - { - v8u16 is_less_than_beta_r, is_less_than_beta_l; - is_less_than_beta_r = - (v8u16) __msa_sldi_b((v16i8) is_less_than_beta, zero, 8); - - q1_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) q1_org); - if (!__msa_test_bz_v((v16u8) is_less_than_beta_r)) { - q2_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) q2_org); - - AVC_LPF_P1_OR_Q1(p0_org_r, q0_org_r, q1_org_r, q2_org_r, - negate_tc_r, tc_r, q1_r); - } - is_less_than_beta_l = - (v8u16) __msa_sldi_b(zero, (v16i8) is_less_than_beta, 8); - - q1_org_l = (v8i16) __msa_ilvl_b(zero, (v16i8) q1_org); - if (!__msa_test_bz_v((v16u8) is_less_than_beta_l)) { - q2_org_l = (v8i16) __msa_ilvl_b(zero, (v16i8) q2_org); - - AVC_LPF_P1_OR_Q1(p0_org_l, q0_org_l, q1_org_l, q2_org_l, - i16_negatetc_l, tc_l, q1_l); - } - } + q1_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) q1_org); + q1_org_l = (v8i16) __msa_ilvl_b(zero, (v16i8) q1_org); + if (!__msa_test_bz_v(is_less_than_beta)) { + v16u8 q1; + v8i16 q1_r = { 0 }; + v8i16 q1_l = { 0 }; + v8i16 q2_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) q2_org); + v8i16 q2_org_l = (v8i16) __msa_ilvl_b(zero, (v16i8) q2_org); + + AVC_LPF_P1_OR_Q1(p0_org_r, q0_org_r, q1_org_r, q2_org_r, + negate_tc_r, tc_r, q1_r); + AVC_LPF_P1_OR_Q1(p0_org_l, q0_org_l, q1_org_l, q2_org_l, + i16_negatetc_l, tc_l, q1_l); + q1 = (v16u8) __msa_pckev_b((v16i8) q1_l, (v16i8) q1_r); q1_org = __msa_bmnz_v(q1_org, q1, is_less_than_beta); ST_UB(q1_org, data + image_width); From 6f15f1cdc85350b7adcfb7c50eedb5ecde6a384a Mon Sep 17 00:00:00 2001 From: Vittorio Giovara Date: Wed, 20 Sep 2017 13:27:10 +0200 Subject: [PATCH 3129/3374] pixdesc: Add API to map color property names to enum values Signed-off-by: Vittorio Giovara --- doc/APIchanges | 5 ++++ libavutil/pixdesc.c | 65 +++++++++++++++++++++++++++++++++++++++++++++ libavutil/pixdesc.h | 25 +++++++++++++++++ libavutil/version.h | 2 +- 4 files changed, 96 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index c20ab9c98848b..d06144f1e96de 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,11 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-xx-xx - xxxxxxx - lavu 55.76.100 / 56.6.0 - pixdesc.h + Add av_color_range_from_name(), av_color_primaries_from_name(), + av_color_transfer_from_name(), av_color_space_from_name(), and + av_chroma_location_from_name(). + 2017-09-13 - xxxxxxx - lavc 57.106.100 - avcodec.h Add AV_PKT_FLAG_TRUSTED. diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index 33aa2d705fd5e..b39afe37588c6 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -2749,26 +2749,91 @@ const char *av_color_range_name(enum AVColorRange range) color_range_names[range] : NULL; } +int av_color_range_from_name(const char *name) +{ + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(color_range_names); i++) { + size_t len = strlen(color_range_names[i]); + if (!strncmp(color_range_names[i], name, len)) + return i; + } + + return AVERROR(EINVAL); +} + const char *av_color_primaries_name(enum AVColorPrimaries primaries) { return (unsigned) primaries < AVCOL_PRI_NB ? color_primaries_names[primaries] : NULL; } +int av_color_primaries_from_name(const char *name) +{ + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(color_primaries_names); i++) { + size_t len = strlen(color_primaries_names[i]); + if (!strncmp(color_primaries_names[i], name, len)) + return i; + } + + return AVERROR(EINVAL); +} + const char *av_color_transfer_name(enum AVColorTransferCharacteristic transfer) { return (unsigned) transfer < AVCOL_TRC_NB ? color_transfer_names[transfer] : NULL; } +int av_color_transfer_from_name(const char *name) +{ + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(color_transfer_names); i++) { + size_t len = strlen(color_transfer_names[i]); + if (!strncmp(color_transfer_names[i], name, len)) + return i; + } + + return AVERROR(EINVAL); +} + const char *av_color_space_name(enum AVColorSpace space) { return (unsigned) space < AVCOL_SPC_NB ? color_space_names[space] : NULL; } +int av_color_space_from_name(const char *name) +{ + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(color_space_names); i++) { + size_t len = strlen(color_space_names[i]); + if (!strncmp(color_space_names[i], name, len)) + return i; + } + + return AVERROR(EINVAL); +} + const char *av_chroma_location_name(enum AVChromaLocation location) { return (unsigned) location < AVCHROMA_LOC_NB ? chroma_location_names[location] : NULL; } + +int av_chroma_location_from_name(const char *name) +{ + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(chroma_location_names); i++) { + size_t len = strlen(chroma_location_names[i]); + if (!strncmp(chroma_location_names[i], name, len)) + return i; + } + + return AVERROR(EINVAL); +} diff --git a/libavutil/pixdesc.h b/libavutil/pixdesc.h index b0ec81b81bc3b..fc3737c4adee6 100644 --- a/libavutil/pixdesc.h +++ b/libavutil/pixdesc.h @@ -250,26 +250,51 @@ int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt); */ const char *av_color_range_name(enum AVColorRange range); +/** + * @return the AVColorRange value for name or an AVError if not found. + */ +int av_color_range_from_name(const char *name); + /** * @return the name for provided color primaries or NULL if unknown. */ const char *av_color_primaries_name(enum AVColorPrimaries primaries); +/** + * @return the AVColorPrimaries value for name or an AVError if not found. + */ +int av_color_primaries_from_name(const char *name); + /** * @return the name for provided color transfer or NULL if unknown. */ const char *av_color_transfer_name(enum AVColorTransferCharacteristic transfer); +/** + * @return the AVColorTransferCharacteristic value for name or an AVError if not found. + */ +int av_color_transfer_from_name(const char *name); + /** * @return the name for provided color space or NULL if unknown. */ const char *av_color_space_name(enum AVColorSpace space); +/** + * @return the AVColorSpace value for name or an AVError if not found. + */ +int av_color_space_from_name(const char *name); + /** * @return the name for provided chroma location or NULL if unknown. */ const char *av_chroma_location_name(enum AVChromaLocation location); +/** + * @return the AVChromaLocation value for name or an AVError if not found. + */ +int av_chroma_location_from_name(const char *name); + /** * Return the pixel format corresponding to name. * diff --git a/libavutil/version.h b/libavutil/version.h index d99eff5d15aae..8ac41f49f5b41 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -80,7 +80,7 @@ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 75 +#define LIBAVUTIL_VERSION_MINOR 76 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From 7e9cdd3f49e50ef5d8f85d3510c8f0d305671dac Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Thu, 21 Sep 2017 23:08:00 +0800 Subject: [PATCH 3130/3374] avformat/hlsenc: fix CID 1418106 fix the "Uninitialized scalar variable (UNINIT)" problem. Signed-off-by: Steven Liu --- libavformat/hlsenc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 3a9a235514630..d70a2f7ff6016 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -1327,13 +1327,13 @@ static int hls_write_header(AVFormatContext *s) { HLSContext *hls = s->priv_data; int ret, i; - char *p; + char *p = NULL; const char *pattern = "%d.ts"; const char *pattern_localtime_fmt = get_default_pattern_localtime_fmt(s); const char *vtt_pattern = "%d.vtt"; AVDictionary *options = NULL; - int basename_size; - int vtt_basename_size; + int basename_size = 0; + int vtt_basename_size = 0; if (hls->segment_type == SEGMENT_TYPE_FMP4) { pattern = "%d.m4s"; From 02bf023afe0099d7e9e2f0d683b6345234cefcaf Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Thu, 21 Sep 2017 23:08:55 +0800 Subject: [PATCH 3131/3374] MAINTAINERS: modify the hlsenc description change the hlsenc from hls encryption to hlsenc Suggested-by: Aman Gupta Reviewed-by: Lou Logan Signed-off-by: Steven Liu --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 69883ee8316ad..77f48b984bdb5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -411,7 +411,7 @@ Muxers/Demuxers: gxf.c Reimar Doeffinger gxfenc.c Baptiste Coudurier hls.c Anssi Hannula - hls encryption (hlsenc.c) Christian Suloway, Steven Liu + hlsenc.c Christian Suloway, Steven Liu idcin.c Mike Melanson idroqdec.c Mike Melanson iff.c Jaikrishnan Menon From c34c0e3a649eb4fe8e6fb756b7784b7bfd9bd638 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Thu, 21 Sep 2017 23:10:57 +0800 Subject: [PATCH 3132/3374] avformat/hlsenc: support http method for hls fmp4 init file Signed-off-by: Steven Liu --- libavformat/hlsenc.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index d70a2f7ff6016..418f153c6f99f 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -215,6 +215,22 @@ static int mkdir_p(const char *path) { return ret; } +static void set_http_options(AVFormatContext *s, AVDictionary **options, HLSContext *c) +{ + const char *proto = avio_find_protocol_name(s->filename); + int http_base_proto = proto ? (!av_strcasecmp(proto, "http") || !av_strcasecmp(proto, "https")) : 0; + + if (c->method) { + av_dict_set(options, "method", c->method, 0); + } else if (http_base_proto) { + av_log(c, AV_LOG_WARNING, "No HTTP method set, hls muxer defaulting to method PUT.\n"); + av_dict_set(options, "method", "PUT", 0); + } + if (c->user_agent) + av_dict_set(options, "user_agent", c->user_agent, 0); + +} + static int replace_int_data_in_filename(char *buf, int buf_size, const char *filename, char placeholder, int64_t number) { const char *p; @@ -592,7 +608,8 @@ static int hls_mux_init(AVFormatContext *s) return AVERROR_PATCHWELCOME; } hls->fmp4_init_mode = !byterange_mode; - if ((ret = s->io_open(s, &oc->pb, hls->base_output_dirname, AVIO_FLAG_WRITE, NULL)) < 0) { + set_http_options(s, &options, hls); + if ((ret = s->io_open(s, &oc->pb, hls->base_output_dirname, AVIO_FLAG_WRITE, &options)) < 0) { av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", hls->fmp4_init_filename); return ret; } @@ -964,22 +981,6 @@ static void hls_free_segments(HLSSegment *p) } } -static void set_http_options(AVFormatContext *s, AVDictionary **options, HLSContext *c) -{ - const char *proto = avio_find_protocol_name(s->filename); - int http_base_proto = proto ? (!av_strcasecmp(proto, "http") || !av_strcasecmp(proto, "https")) : 0; - - if (c->method) { - av_dict_set(options, "method", c->method, 0); - } else if (http_base_proto) { - av_log(c, AV_LOG_WARNING, "No HTTP method set, hls muxer defaulting to method PUT.\n"); - av_dict_set(options, "method", "PUT", 0); - } - if (c->user_agent) - av_dict_set(options, "user_agent", c->user_agent, 0); - -} - static void write_m3u8_head_block(HLSContext *hls, AVIOContext *out, int version, int target_duration, int64_t sequence) { From 724cf83f100065ddabf827f55bf7ae9785875b4c Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Fri, 22 Sep 2017 01:33:22 +0200 Subject: [PATCH 3133/3374] Remove some unneeded casts of bit_rate. --- ffserver.c | 2 +- libavcodec/dcaenc.c | 2 +- libavcodec/libfdk-aacenc.c | 2 +- libavcodec/libgsmenc.c | 2 +- libavcodec/libopusenc.c | 4 ++-- libavcodec/libspeexenc.c | 4 ++-- libavcodec/mpegvideo_enc.c | 2 +- libavcodec/pcm-bluray.c | 2 +- libavcodec/pcm-dvd.c | 2 +- libavcodec/sipr.c | 2 +- libavcodec/utils.c | 4 ++-- libavcodec/wma.c | 2 +- libavcodec/wmaenc.c | 2 +- libavdevice/fbdev_dec.c | 2 +- libavformat/sdp.c | 2 +- libavformat/smoothstreamingenc.c | 6 +++--- libavformat/vqf.c | 2 +- 17 files changed, 22 insertions(+), 22 deletions(-) diff --git a/ffserver.c b/ffserver.c index f9f987acac8e6..d4885dfa0eeac 100644 --- a/ffserver.c +++ b/ffserver.c @@ -1916,7 +1916,7 @@ static inline void print_stream_params(AVIOContext *pb, FFServerStream *stream) avio_printf(pb, "%d%s%"PRId64 "%s%s\n", - i, type, (int64_t)st->codecpar->bit_rate/1000, + i, type, st->codecpar->bit_rate/1000, codec ? codec->name : "", parameters); } diff --git a/libavcodec/dcaenc.c b/libavcodec/dcaenc.c index c1d72bfd16b08..dd601ffae0077 100644 --- a/libavcodec/dcaenc.c +++ b/libavcodec/dcaenc.c @@ -216,7 +216,7 @@ static int encode_init(AVCodecContext *avctx) c->samplerate_index = i; if (avctx->bit_rate < 32000 || avctx->bit_rate > 3840000) { - av_log(avctx, AV_LOG_ERROR, "Bit rate %"PRId64" not supported.", (int64_t)avctx->bit_rate); + av_log(avctx, AV_LOG_ERROR, "Bit rate %"PRId64" not supported.", avctx->bit_rate); return AVERROR(EINVAL); } for (i = 0; ff_dca_bit_rates[i] < avctx->bit_rate; i++) diff --git a/libavcodec/libfdk-aacenc.c b/libavcodec/libfdk-aacenc.c index 98a817b537e27..0e2051b468aac 100644 --- a/libavcodec/libfdk-aacenc.c +++ b/libavcodec/libfdk-aacenc.c @@ -216,7 +216,7 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) if ((err = aacEncoder_SetParam(s->handle, AACENC_BITRATE, avctx->bit_rate)) != AACENC_OK) { av_log(avctx, AV_LOG_ERROR, "Unable to set the bitrate %"PRId64": %s\n", - (int64_t)avctx->bit_rate, aac_get_error(err)); + avctx->bit_rate, aac_get_error(err)); goto error; } } diff --git a/libavcodec/libgsmenc.c b/libavcodec/libgsmenc.c index 69ce439ec1db8..e25db95181009 100644 --- a/libavcodec/libgsmenc.c +++ b/libavcodec/libgsmenc.c @@ -63,7 +63,7 @@ static av_cold int libgsm_encode_init(AVCodecContext *avctx) { avctx->bit_rate != 13200 /* Very common */ && avctx->bit_rate != 0 /* Unknown; a.o. mov does not set bitrate when decoding */ ) { av_log(avctx, AV_LOG_ERROR, "Bitrate 13000bps required for GSM, got %"PRId64"bps\n", - (int64_t)avctx->bit_rate); + avctx->bit_rate); if (avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) return -1; } diff --git a/libavcodec/libopusenc.c b/libavcodec/libopusenc.c index 77d8310048db6..3d88c296d3289 100644 --- a/libavcodec/libopusenc.c +++ b/libavcodec/libopusenc.c @@ -351,12 +351,12 @@ static av_cold int libopus_encode_init(AVCodecContext *avctx) avctx->bit_rate = 64000 * opus->stream_count + 32000 * coupled_stream_count; av_log(avctx, AV_LOG_WARNING, - "No bit rate set. Defaulting to %"PRId64" bps.\n", (int64_t)avctx->bit_rate); + "No bit rate set. Defaulting to %"PRId64" bps.\n", avctx->bit_rate); } if (avctx->bit_rate < 500 || avctx->bit_rate > 256000 * avctx->channels) { av_log(avctx, AV_LOG_ERROR, "The bit rate %"PRId64" bps is unsupported. " - "Please choose a value between 500 and %d.\n", (int64_t)avctx->bit_rate, + "Please choose a value between 500 and %d.\n", avctx->bit_rate, 256000 * avctx->channels); ret = AVERROR(EINVAL); goto fail; diff --git a/libavcodec/libspeexenc.c b/libavcodec/libspeexenc.c index 4bdb9618dd3c4..a2b07a41cbf63 100644 --- a/libavcodec/libspeexenc.c +++ b/libavcodec/libspeexenc.c @@ -125,10 +125,10 @@ static av_cold void print_enc_params(AVCodecContext *avctx, av_log(avctx, AV_LOG_DEBUG, " quality: %f\n", s->vbr_quality); } else if (s->abr) { av_log(avctx, AV_LOG_DEBUG, "rate control: ABR\n"); - av_log(avctx, AV_LOG_DEBUG, " bitrate: %"PRId64" bps\n", (int64_t)avctx->bit_rate); + av_log(avctx, AV_LOG_DEBUG, " bitrate: %"PRId64" bps\n", avctx->bit_rate); } else { av_log(avctx, AV_LOG_DEBUG, "rate control: CBR\n"); - av_log(avctx, AV_LOG_DEBUG, " bitrate: %"PRId64" bps\n", (int64_t)avctx->bit_rate); + av_log(avctx, AV_LOG_DEBUG, " bitrate: %"PRId64" bps\n", avctx->bit_rate); } av_log(avctx, AV_LOG_DEBUG, "complexity: %d\n", avctx->compression_level); diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index 918728391d46a..5765ef339f554 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -506,7 +506,7 @@ FF_ENABLE_DEPRECATION_WARNINGS avctx->bit_rate * av_q2d(avctx->time_base) > avctx->bit_rate_tolerance) { av_log(avctx, AV_LOG_WARNING, - "bitrate tolerance %d too small for bitrate %"PRId64", overriding\n", avctx->bit_rate_tolerance, (int64_t)avctx->bit_rate); + "bitrate tolerance %d too small for bitrate %"PRId64", overriding\n", avctx->bit_rate_tolerance, avctx->bit_rate); avctx->bit_rate_tolerance = 5 * avctx->bit_rate * av_q2d(avctx->time_base); } diff --git a/libavcodec/pcm-bluray.c b/libavcodec/pcm-bluray.c index 22c1c08bcf150..517d7b518c97d 100644 --- a/libavcodec/pcm-bluray.c +++ b/libavcodec/pcm-bluray.c @@ -119,7 +119,7 @@ static int pcm_bluray_parse_header(AVCodecContext *avctx, ff_dlog(avctx, "pcm_bluray_parse_header: %d channels, %d bits per sample, %d Hz, %"PRId64" bit/s\n", avctx->channels, avctx->bits_per_coded_sample, - avctx->sample_rate, (int64_t)avctx->bit_rate); + avctx->sample_rate, avctx->bit_rate); return 0; } diff --git a/libavcodec/pcm-dvd.c b/libavcodec/pcm-dvd.c index 04c321e677e6f..0a751a81916b7 100644 --- a/libavcodec/pcm-dvd.c +++ b/libavcodec/pcm-dvd.c @@ -142,7 +142,7 @@ static int pcm_dvd_parse_header(AVCodecContext *avctx, const uint8_t *header) ff_dlog(avctx, "pcm_dvd_parse_header: %d channels, %d bits per sample, %d Hz, %"PRId64" bit/s\n", avctx->channels, avctx->bits_per_coded_sample, - avctx->sample_rate, (int64_t)avctx->bit_rate); + avctx->sample_rate, avctx->bit_rate); s->last_header = header_int; diff --git a/libavcodec/sipr.c b/libavcodec/sipr.c index 70d460a678f4d..1b6de25ffff07 100644 --- a/libavcodec/sipr.c +++ b/libavcodec/sipr.c @@ -494,7 +494,7 @@ static av_cold int sipr_decoder_init(AVCodecContext * avctx) else ctx->mode = MODE_5k0; av_log(avctx, AV_LOG_WARNING, "Invalid block_align: %d. Mode %s guessed based on bitrate: %"PRId64"\n", - avctx->block_align, modes[ctx->mode].mode_name, (int64_t)avctx->bit_rate); + avctx->block_align, modes[ctx->mode].mode_name, avctx->bit_rate); } av_log(avctx, AV_LOG_DEBUG, "Mode: %s\n", modes[ctx->mode].mode_name); diff --git a/libavcodec/utils.c b/libavcodec/utils.c index baf4992b197ca..9551f312e7224 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -967,7 +967,7 @@ FF_ENABLE_DEPRECATION_WARNINGS } if ( (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO) && avctx->bit_rate>0 && avctx->bit_rate<1000) { - av_log(avctx, AV_LOG_WARNING, "Bitrate %"PRId64" is extremely low, maybe you mean %"PRId64"k\n", (int64_t)avctx->bit_rate, (int64_t)avctx->bit_rate); + av_log(avctx, AV_LOG_WARNING, "Bitrate %"PRId64" is extremely low, maybe you mean %"PRId64"k\n", avctx->bit_rate, avctx->bit_rate); } if (!avctx->rc_initial_buffer_occupancy) @@ -1522,7 +1522,7 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) ", %"PRId64" kb/s", bitrate / 1000); } else if (enc->rc_max_rate > 0) { snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", max. %"PRId64" kb/s", (int64_t)enc->rc_max_rate / 1000); + ", max. %"PRId64" kb/s", enc->rc_max_rate / 1000); } } diff --git a/libavcodec/wma.c b/libavcodec/wma.c index f70937fe759de..b4992095ecd5a 100644 --- a/libavcodec/wma.c +++ b/libavcodec/wma.c @@ -186,7 +186,7 @@ av_cold int ff_wma_init(AVCodecContext *avctx, int flags2) } ff_dlog(s->avctx, "flags2=0x%x\n", flags2); ff_dlog(s->avctx, "version=%d channels=%d sample_rate=%d bitrate=%"PRId64" block_align=%d\n", - s->version, avctx->channels, avctx->sample_rate, (int64_t)avctx->bit_rate, + s->version, avctx->channels, avctx->sample_rate, avctx->bit_rate, avctx->block_align); ff_dlog(s->avctx, "bps=%f bps1=%f high_freq=%f bitoffset=%d\n", bps, bps1, high_freq, s->byte_offset_bits); diff --git a/libavcodec/wmaenc.c b/libavcodec/wmaenc.c index c68babd549355..091bc2ac3b91b 100644 --- a/libavcodec/wmaenc.c +++ b/libavcodec/wmaenc.c @@ -53,7 +53,7 @@ static av_cold int encode_init(AVCodecContext *avctx) if (avctx->bit_rate < 24 * 1000) { av_log(avctx, AV_LOG_ERROR, "bitrate too low: got %"PRId64", need 24000 or higher\n", - (int64_t)avctx->bit_rate); + avctx->bit_rate); return AVERROR(EINVAL); } diff --git a/libavdevice/fbdev_dec.c b/libavdevice/fbdev_dec.c index 3b31373fd646f..d9c75df2029b6 100644 --- a/libavdevice/fbdev_dec.c +++ b/libavdevice/fbdev_dec.c @@ -140,7 +140,7 @@ static av_cold int fbdev_read_header(AVFormatContext *avctx) fbdev->width, fbdev->height, fbdev->varinfo.bits_per_pixel, av_get_pix_fmt_name(pix_fmt), fbdev->framerate_q.num, fbdev->framerate_q.den, - (int64_t)st->codecpar->bit_rate); + st->codecpar->bit_rate); return 0; fail: diff --git a/libavformat/sdp.c b/libavformat/sdp.c index 4e37f65b09ebb..66e9dffbf0dd7 100644 --- a/libavformat/sdp.c +++ b/libavformat/sdp.c @@ -748,7 +748,7 @@ void ff_sdp_write_media(char *buff, int size, AVStream *st, int idx, av_strlcatf(buff, size, "m=%s %d RTP/AVP %d\r\n", type, port, payload_type); sdp_write_address(buff, size, dest_addr, dest_type, ttl); if (p->bit_rate) { - av_strlcatf(buff, size, "b=AS:%"PRId64"\r\n", (int64_t)p->bit_rate / 1000); + av_strlcatf(buff, size, "b=AS:%"PRId64"\r\n", p->bit_rate / 1000); } sdp_write_media_attributes(buff, size, st, payload_type, fmt); diff --git a/libavformat/smoothstreamingenc.c b/libavformat/smoothstreamingenc.c index 86618351b800d..54a1c49caae69 100644 --- a/libavformat/smoothstreamingenc.c +++ b/libavformat/smoothstreamingenc.c @@ -263,7 +263,7 @@ static int write_manifest(AVFormatContext *s, int final) if (s->streams[i]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO) continue; last = i; - avio_printf(out, "\n", index, (int64_t)s->streams[i]->codecpar->bit_rate, os->fourcc, s->streams[i]->codecpar->width, s->streams[i]->codecpar->height, os->private_str); + avio_printf(out, "\n", index, s->streams[i]->codecpar->bit_rate, os->fourcc, s->streams[i]->codecpar->width, s->streams[i]->codecpar->height, os->private_str); index++; } output_chunk_list(&c->streams[last], out, final, c->lookahead_count, c->window_size); @@ -277,7 +277,7 @@ static int write_manifest(AVFormatContext *s, int final) if (s->streams[i]->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) continue; last = i; - avio_printf(out, "\n", index, (int64_t)s->streams[i]->codecpar->bit_rate, os->fourcc, s->streams[i]->codecpar->sample_rate, s->streams[i]->codecpar->channels, os->packet_size, os->audio_tag, os->private_str); + avio_printf(out, "\n", index, s->streams[i]->codecpar->bit_rate, os->fourcc, s->streams[i]->codecpar->sample_rate, s->streams[i]->codecpar->channels, os->packet_size, os->audio_tag, os->private_str); index++; } output_chunk_list(&c->streams[last], out, final, c->lookahead_count, c->window_size); @@ -324,7 +324,7 @@ static int ism_write_header(AVFormatContext *s) ret = AVERROR(EINVAL); goto fail; } - snprintf(os->dirname, sizeof(os->dirname), "%s/QualityLevels(%"PRId64")", s->filename, (int64_t)s->streams[i]->codecpar->bit_rate); + snprintf(os->dirname, sizeof(os->dirname), "%s/QualityLevels(%"PRId64")", s->filename, s->streams[i]->codecpar->bit_rate); if (mkdir(os->dirname, 0777) == -1 && errno != EEXIST) { ret = AVERROR(errno); av_log(s, AV_LOG_ERROR, "mkdir failed\n"); diff --git a/libavformat/vqf.c b/libavformat/vqf.c index 841840edad9da..d00fa5e08c61c 100644 --- a/libavformat/vqf.c +++ b/libavformat/vqf.c @@ -212,7 +212,7 @@ static int vqf_read_header(AVFormatContext *s) break; default: av_log(s, AV_LOG_ERROR, "Mode not supported: %d Hz, %"PRId64" kb/s.\n", - st->codecpar->sample_rate, (int64_t)st->codecpar->bit_rate); + st->codecpar->sample_rate, st->codecpar->bit_rate); return -1; } c->frame_bit_len = st->codecpar->bit_rate*size/st->codecpar->sample_rate; From 183fd30e0f6fdc762fd955a24cfc7e6a49e1055c Mon Sep 17 00:00:00 2001 From: Lou Logan Date: Thu, 21 Sep 2017 15:10:56 -0800 Subject: [PATCH 3134/3374] Fix several typos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "apix_fmts" found by Marc Péchaud. "speedloss" found by Mikhail V. Signed-off-by: Lou Logan --- doc/decoders.texi | 4 ++-- doc/encoders.texi | 6 +++--- doc/ffmpeg.texi | 2 +- doc/ffprobe.texi | 2 +- doc/ffserver.texi | 4 ++-- doc/filters.texi | 28 ++++++++++++++-------------- doc/muxers.texi | 2 +- libavformat/segment.c | 4 ++-- libswscale/swscale.c | 2 +- 9 files changed, 27 insertions(+), 27 deletions(-) diff --git a/doc/decoders.texi b/doc/decoders.texi index babe129767207..d149d2bea5142 100644 --- a/doc/decoders.texi +++ b/doc/decoders.texi @@ -109,7 +109,7 @@ correctly by using lavc's old buggy lpc logic for decoding. @section ffwavesynth -Internal wave synthetizer. +Internal wave synthesizer. This decoder generates wave patterns according to predefined sequences. Its use is purely internal and the format of the data it accepts is not publicly @@ -275,7 +275,7 @@ Y offset of generated bitmaps, default is 0. Chops leading and trailing spaces and removes empty lines from the generated text. This option is useful for teletext based subtitles where empty spaces may be present at the start or at the end of the lines or empty lines may be -present between the subtitle lines because of double-sized teletext charactes. +present between the subtitle lines because of double-sized teletext characters. Default value is 1. @item txt_duration Sets the display duration of the decoded teletext pages or subtitles in diff --git a/doc/encoders.texi b/doc/encoders.texi index 018fb4b07aace..fb93ae009445e 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -92,12 +92,12 @@ using the value "enable", which is mainly useful for debugging or disabled using @item aac_is Sets intensity stereo coding tool usage. By default, it's enabled and will -automatically toggle IS for similar pairs of stereo bands if it's benefitial. +automatically toggle IS for similar pairs of stereo bands if it's beneficial. Can be disabled for debugging by setting the value to "disable". @item aac_pns Uses perceptual noise substitution to replace low entropy high frequency bands -with imperceivable white noise during the decoding process. By default, it's +with imperceptible white noise during the decoding process. By default, it's enabled, but can be disabled for debugging purposes by using "disable". @item aac_tns @@ -599,7 +599,7 @@ Channel mode @item auto The mode is chosen automatically for each frame @item indep -Chanels are independently coded +Channels are independently coded @item left_side @item right_side @item mid_side diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index de6d3f139a663..0405d009b967f 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -935,7 +935,7 @@ It disables matching streams from already created mappings. A trailing @code{?} after the stream index will allow the map to be optional: if the map matches no streams the map will be ignored instead of failing. Note the map will still fail if an invalid input file index -is used; such as if the map refers to a non-existant input. +is used; such as if the map refers to a non-existent input. An alternative @var{[linklabel]} form will map outputs from complex filter graphs (see the @option{-filter_complex} option) to the output file. diff --git a/doc/ffprobe.texi b/doc/ffprobe.texi index 3572957c8a00b..e3c34babdc7a0 100644 --- a/doc/ffprobe.texi +++ b/doc/ffprobe.texi @@ -471,7 +471,7 @@ Perform no escaping. @end table @item print_section, p -Print the section name at the begin of each line if the value is +Print the section name at the beginning of each line if the value is @code{1}, disable it with value set to @code{0}. Default value is @code{1}. diff --git a/doc/ffserver.texi b/doc/ffserver.texi index ad48f47a8f035..b3e1f1d7ef9a7 100644 --- a/doc/ffserver.texi +++ b/doc/ffserver.texi @@ -327,7 +327,7 @@ Name of options and sections are case-insensitive. An ACL (Access Control List) specifies the address which are allowed to access a given stream, or to write a given feed. -It accepts the folling forms +It accepts the following forms @itemize @item Allow/deny access to @var{address}. @@ -416,7 +416,7 @@ deprecated. @item NoDefaults Control whether default codec options are used for the all streams or not. Each stream may overwrite this setting for its own. Default is @var{UseDefaults}. -The lastest occurrence overrides previous if multiple definitions. +The last occurrence overrides the previous if multiple definitions exist. @end table @section Feed section diff --git a/doc/filters.texi b/doc/filters.texi index 830de549094cc..b09c3a0538b7e 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -601,7 +601,7 @@ separated by '|'. Allowed range for each @code{delay} is @code{(0 - 90000.0]}. Default is @code{1000}. @item decays -Set list of loudnesses of reflected signals separated by '|'. +Set list of loudness of reflected signals separated by '|'. Allowed range for each @code{decay} is @code{(0 - 1.0]}. Default is @code{0.5}. @end table @@ -2744,7 +2744,7 @@ The filter accepts the following options: Set base delay in milliseconds. Range from 0 to 30. Default value is 0. @item depth -Set added swep delay in milliseconds. Range from 0 to 10. Default value is 2. +Set added sweep delay in milliseconds. Range from 0 to 10. Default value is 2. @item regen Set percentage regeneration (delayed signal feedback). Range from -95 to 95. @@ -2775,7 +2775,7 @@ Apply Haas effect to audio. Note that this makes most sense to apply on mono signals. With this filter applied to mono signals it give some directionality and -streches its stereo image. +stretches its stereo image. The filter accepts the following options: @@ -3750,7 +3750,7 @@ Default is @var{freq}. Set custom positions of virtual loudspeakers. Syntax for this option is: [| |...]. Each virtual loudspeaker is described with short channel name following with -azimuth and elevation in degreees. +azimuth and elevation in degrees. Each virtual loudspeaker description is separated by '|'. For example to override front left and front right channel positions use: 'speakers=FL 45 15|FR 345 15'. @@ -5267,7 +5267,7 @@ the more similar the pixels color is to the key color. @item yuv Signals that the color passed is already in YUV instead of RGB. -Litteral colors like "green" or "red" don't make sense with this enabled anymore. +Literal colors like "green" or "red" don't make sense with this enabled anymore. This can be used to pass exact YUV values as hexadecimal numbers. @end table @@ -6911,14 +6911,14 @@ Set how spillmap will be generated. Set how much to get rid of still remaining spill. @item red -Controls ammount of red in spill area. +Controls amount of red in spill area. @item green -Controls ammount of green in spill area. +Controls amount of green in spill area. Should be -1 for greenscreen. @item blue -Controls ammount of blue in spill area. +Controls amount of blue in spill area. Should be -1 for bluescreen. @item brightness @@ -10553,7 +10553,7 @@ A description of the accepted options follows. @item max Set the maximum number of consecutive frames which can be dropped (if positive), or the minimum interval between dropped frames (if -negative). If the value is 0, the frame is dropped unregarding the +negative). If the value is 0, the frame is dropped disregarding the number of previous sequentially dropped frames. Default value is 0. @@ -10675,7 +10675,7 @@ Can be one of the following: @end table @item nns -Set the number of neurons in predicctor neural network. +Set the number of neurons in predictor neural network. Can be one of the following: @table @samp @@ -10738,7 +10738,7 @@ It accepts the following parameters: @item pix_fmts A '|'-separated list of pixel format names, such as -apix_fmts=yuv420p|monow|rgb24". +pix_fmts=yuv420p|monow|rgb24". @end table @@ -12199,7 +12199,7 @@ the following constants: 1 if index is not 129, 0 otherwise. @item qp -Sequentional index starting from -129 to 128. +Sequential index starting from -129 to 128. @end table @subsection Examples @@ -14723,7 +14723,7 @@ Preserve overall image brightness with a simple curve, using nonlinear contrast, which results in flattening details and degrading color accuracy. @item hable -Peserve both dark and bright details better than @var{reinhard}, at the cost +Preserve both dark and bright details better than @var{reinhard}, at the cost of slightly darkening everything. Use it when detail preservation is more important than color and brightness accuracy. @@ -17710,7 +17710,7 @@ perms/aperms filter can avoid this problem. @section realtime, arealtime -Slow down filtering to match real time approximatively. +Slow down filtering to match real time approximately. These filters will pause the filtering for a variable amount of time to match the output rate with the input timestamps. diff --git a/doc/muxers.texi b/doc/muxers.texi index 5a4f17bf8d51a..36769b8c1a048 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -1566,7 +1566,7 @@ inconsistent, but may make things worse on others, and can cause some oddities during seeking. Defaults to @code{0}. @item reset_timestamps @var{1|0} -Reset timestamps at the begin of each segment, so that each segment +Reset timestamps at the beginning of each segment, so that each segment will start with near-zero timestamps. It is meant to ease the playback of the generated segments. May not work with some combinations of muxers/codecs. It is set to @code{0} by default. diff --git a/libavformat/segment.c b/libavformat/segment.c index b0ef6dd38e08a..81d3f1d9408bc 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -111,7 +111,7 @@ typedef struct SegmentContext { int write_header_trailer; /**< Set by a private option. */ char *header_filename; ///< filename to write the output header to - int reset_timestamps; ///< reset timestamps at the begin of each segment + int reset_timestamps; ///< reset timestamps at the beginning of each segment int64_t initial_offset; ///< initial timestamps offset, expressed in microseconds char *reference_stream_specifier; ///< reference stream specifier int reference_stream_index; @@ -1052,7 +1052,7 @@ static const AVOption options[] = { { "individual_header_trailer", "write header/trailer to each segment", OFFSET(individual_header_trailer), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, E }, { "write_header_trailer", "write a header to the first segment and a trailer to the last one", OFFSET(write_header_trailer), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, E }, - { "reset_timestamps", "reset timestamps at the begin of each segment", OFFSET(reset_timestamps), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E }, + { "reset_timestamps", "reset timestamps at the beginning of each segment", OFFSET(reset_timestamps), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E }, { "initial_offset", "set initial timestamp offset", OFFSET(initial_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, -INT64_MAX, INT64_MAX, E }, { "write_empty_segments", "allow writing empty 'filler' segments", OFFSET(write_empty), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E }, { NULL }, diff --git a/libswscale/swscale.c b/libswscale/swscale.c index ba66314c7d46a..7f3e22355fe33 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -326,7 +326,7 @@ static int swscale(SwsContext *c, const uint8_t *src[], static int warnedAlready=0; int cpu_flags = av_get_cpu_flags(); if (HAVE_MMXEXT && (cpu_flags & AV_CPU_FLAG_SSE2) && !warnedAlready){ - av_log(c, AV_LOG_WARNING, "Warning: data is not aligned! This can lead to a speedloss\n"); + av_log(c, AV_LOG_WARNING, "Warning: data is not aligned! This can lead to a speed loss\n"); warnedAlready=1; } } From 21e077fcb3d968e3ed6772a0309e31f94cd7a2a5 Mon Sep 17 00:00:00 2001 From: Yogender Gupta Date: Mon, 4 Sep 2017 18:18:16 +0530 Subject: [PATCH 3135/3374] avfilter/thumbnail_cuda: add cuda thumbnail filter Signed-off-by: Timo Rothenpieler --- Changelog | 2 + configure | 1 + libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/version.h | 2 +- libavfilter/vf_thumbnail_cuda.c | 444 +++++++++++++++++++++++++++++++ libavfilter/vf_thumbnail_cuda.cu | 79 ++++++ 7 files changed, 529 insertions(+), 1 deletion(-) create mode 100644 libavfilter/vf_thumbnail_cuda.c create mode 100644 libavfilter/vf_thumbnail_cuda.cu diff --git a/Changelog b/Changelog index ea48e81efe474..38b125be39e30 100644 --- a/Changelog +++ b/Changelog @@ -48,6 +48,8 @@ version : - convolve video filter - VP9 tile threading support - KMS screen grabber +- CUDA thumbnail filter + version 3.3: - CrystalHD decoder moved to new decode API diff --git a/configure b/configure index 2de20a02a4a52..ff9a64292c4b2 100755 --- a/configure +++ b/configure @@ -2759,6 +2759,7 @@ vaapi_encode_deps="vaapi" hwupload_cuda_filter_deps="cuda" scale_npp_filter_deps="cuda libnpp" scale_cuda_filter_deps="cuda_sdk" +thumbnail_cuda_filter_deps="cuda_sdk" nvenc_deps="cuda" nvenc_deps_any="dlopen LoadLibrary" diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 8aa974e115a4a..98acb51bcbba8 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -315,6 +315,7 @@ OBJS-$(CONFIG_TBLEND_FILTER) += vf_blend.o framesync.o OBJS-$(CONFIG_TELECINE_FILTER) += vf_telecine.o OBJS-$(CONFIG_THRESHOLD_FILTER) += vf_threshold.o framesync.o OBJS-$(CONFIG_THUMBNAIL_FILTER) += vf_thumbnail.o +OBJS-$(CONFIG_THUMBNAIL_CUDA_FILTER) += vf_thumbnail_cuda.o vf_thumbnail_cuda.ptx.o OBJS-$(CONFIG_TILE_FILTER) += vf_tile.o OBJS-$(CONFIG_TINTERLACE_FILTER) += vf_tinterlace.o OBJS-$(CONFIG_TLUT2_FILTER) += vf_lut2.o framesync.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 63e86721cdf56..baa84a3e729d0 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -326,6 +326,7 @@ static void register_all(void) REGISTER_FILTER(TELECINE, telecine, vf); REGISTER_FILTER(THRESHOLD, threshold, vf); REGISTER_FILTER(THUMBNAIL, thumbnail, vf); + REGISTER_FILTER(THUMBNAIL_CUDA, thumbnail_cuda, vf); REGISTER_FILTER(TILE, tile, vf); REGISTER_FILTER(TINTERLACE, tinterlace, vf); REGISTER_FILTER(TLUT2, tlut2, vf); diff --git a/libavfilter/version.h b/libavfilter/version.h index 5d6aa5fc706e1..fb382d4e25282 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 6 -#define LIBAVFILTER_VERSION_MINOR 105 +#define LIBAVFILTER_VERSION_MINOR 106 #define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vf_thumbnail_cuda.c b/libavfilter/vf_thumbnail_cuda.c new file mode 100644 index 0000000000000..4c08a85121341 --- /dev/null +++ b/libavfilter/vf_thumbnail_cuda.c @@ -0,0 +1,444 @@ +/* +* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +*/ + +#include + +#include "libavutil/hwcontext.h" +#include "libavutil/hwcontext_cuda_internal.h" +#include "libavutil/opt.h" +#include "libavutil/pixdesc.h" + +#include "avfilter.h" +#include "internal.h" + +#define HIST_SIZE (3*256) +#define DIV_UP(a, b) ( ((a) + (b) - 1) / (b) ) +#define BLOCKX 32 +#define BLOCKY 16 + +static const enum AVPixelFormat supported_formats[] = { + AV_PIX_FMT_NV12, + AV_PIX_FMT_YUV420P, + AV_PIX_FMT_YUV444P, + AV_PIX_FMT_P010, + AV_PIX_FMT_P016, + AV_PIX_FMT_YUV444P16, +}; + +struct thumb_frame { + AVFrame *buf; ///< cached frame + int histogram[HIST_SIZE]; ///< RGB color distribution histogram of the frame +}; + +typedef struct ThumbnailCudaContext { + const AVClass *class; + int n; ///< current frame + int n_frames; ///< number of frames for analysis + struct thumb_frame *frames; ///< the n_frames frames + AVRational tb; ///< copy of the input timebase to ease access + + AVBufferRef *hw_frames_ctx; + + CUmodule cu_module; + + CUfunction cu_func_uchar; + CUfunction cu_func_uchar2; + CUfunction cu_func_ushort; + CUfunction cu_func_ushort2; + CUtexref cu_tex_uchar; + CUtexref cu_tex_uchar2; + CUtexref cu_tex_ushort; + CUtexref cu_tex_ushort2; + + CUdeviceptr data; +} ThumbnailCudaContext; + +#define OFFSET(x) offsetof(ThumbnailCudaContext, x) +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM + +static const AVOption thumbnail_cuda_options[] = { + { "n", "set the frames batch size", OFFSET(n_frames), AV_OPT_TYPE_INT, {.i64=100}, 2, INT_MAX, FLAGS }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(thumbnail_cuda); + +static av_cold int init(AVFilterContext *ctx) +{ + ThumbnailCudaContext *s = ctx->priv; + + s->frames = av_calloc(s->n_frames, sizeof(*s->frames)); + if (!s->frames) { + av_log(ctx, AV_LOG_ERROR, + "Allocation failure, try to lower the number of frames\n"); + return AVERROR(ENOMEM); + } + av_log(ctx, AV_LOG_VERBOSE, "batch size: %d frames\n", s->n_frames); + return 0; +} + +/** + * @brief Compute Sum-square deviation to estimate "closeness". + * @param hist color distribution histogram + * @param median average color distribution histogram + * @return sum of squared errors + */ +static double frame_sum_square_err(const int *hist, const double *median) +{ + int i; + double err, sum_sq_err = 0; + + for (i = 0; i < HIST_SIZE; i++) { + err = median[i] - (double)hist[i]; + sum_sq_err += err*err; + } + return sum_sq_err; +} + +static AVFrame *get_best_frame(AVFilterContext *ctx) +{ + AVFrame *picref; + ThumbnailCudaContext *s = ctx->priv; + int i, j, best_frame_idx = 0; + int nb_frames = s->n; + double avg_hist[HIST_SIZE] = {0}, sq_err, min_sq_err = -1; + + // average histogram of the N frames + for (j = 0; j < FF_ARRAY_ELEMS(avg_hist); j++) { + for (i = 0; i < nb_frames; i++) + avg_hist[j] += (double)s->frames[i].histogram[j]; + avg_hist[j] /= nb_frames; + } + + // find the frame closer to the average using the sum of squared errors + for (i = 0; i < nb_frames; i++) { + sq_err = frame_sum_square_err(s->frames[i].histogram, avg_hist); + if (i == 0 || sq_err < min_sq_err) + best_frame_idx = i, min_sq_err = sq_err; + } + + // free and reset everything (except the best frame buffer) + for (i = 0; i < nb_frames; i++) { + memset(s->frames[i].histogram, 0, sizeof(s->frames[i].histogram)); + if (i != best_frame_idx) + av_frame_free(&s->frames[i].buf); + } + s->n = 0; + + // raise the chosen one + picref = s->frames[best_frame_idx].buf; + av_log(ctx, AV_LOG_INFO, "frame id #%d (pts_time=%f) selected " + "from a set of %d images\n", best_frame_idx, + picref->pts * av_q2d(s->tb), nb_frames); + s->frames[best_frame_idx].buf = NULL; + + return picref; +} + +static int thumbnail_kernel(ThumbnailCudaContext *s, CUfunction func, CUtexref tex, int channels, + int *histogram, uint8_t *src_dptr, int src_width, int src_height, int src_pitch, int pixel_size) +{ + CUdeviceptr src_devptr = (CUdeviceptr)src_dptr; + void *args[] = { &histogram, &src_width, &src_height }; + CUDA_ARRAY_DESCRIPTOR desc; + + desc.Width = src_width; + desc.Height = src_height; + desc.NumChannels = channels; + if (pixel_size == 1) { + desc.Format = CU_AD_FORMAT_UNSIGNED_INT8; + } + else { + desc.Format = CU_AD_FORMAT_UNSIGNED_INT16; + } + + cuTexRefSetAddress2D_v3(tex, &desc, src_devptr, src_pitch); + cuLaunchKernel(func, DIV_UP(src_width, BLOCKX), DIV_UP(src_height, BLOCKY), 1, BLOCKX, BLOCKY, 1, 0, 0, args, NULL); + + return 0; +} + +static int thumbnail(AVFilterContext *ctx, int *histogram, AVFrame *in) +{ + AVHWFramesContext *in_frames_ctx = (AVHWFramesContext*)in->hw_frames_ctx->data; + ThumbnailCudaContext *s = ctx->priv; + + switch (in_frames_ctx->sw_format) { + case AV_PIX_FMT_NV12: + thumbnail_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1, + histogram, in->data[0], in->width, in->height, in->linesize[0], 1); + thumbnail_kernel(s, s->cu_func_uchar2, s->cu_tex_uchar2, 2, + histogram + 256, in->data[1], in->width / 2, in->height / 2, in->linesize[1], 1); + break; + case AV_PIX_FMT_YUV420P: + thumbnail_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1, + histogram, in->data[0], in->width, in->height, in->linesize[0], 1); + thumbnail_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1, + histogram + 256, in->data[1], in->width / 2, in->height / 2, in->linesize[1], 1); + thumbnail_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1, + histogram + 512, in->data[2], in->width / 2, in->height / 2, in->linesize[2], 1); + break; + case AV_PIX_FMT_YUV444P: + thumbnail_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1, + histogram, in->data[0], in->width, in->height, in->linesize[0], 1); + thumbnail_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1, + histogram + 256, in->data[1], in->width, in->height, in->linesize[1], 1); + thumbnail_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1, + histogram + 512, in->data[2], in->width, in->height, in->linesize[2], 1); + break; + case AV_PIX_FMT_P010LE: + case AV_PIX_FMT_P016LE: + thumbnail_kernel(s, s->cu_func_ushort, s->cu_tex_ushort, 1, + histogram, in->data[0], in->width, in->height, in->linesize[0], 2); + thumbnail_kernel(s, s->cu_func_ushort2, s->cu_tex_ushort2, 2, + histogram + 256, in->data[1], in->width / 2, in->height / 2, in->linesize[1], 2); + break; + case AV_PIX_FMT_YUV444P16: + thumbnail_kernel(s, s->cu_func_ushort2, s->cu_tex_uchar, 1, + histogram, in->data[0], in->width, in->height, in->linesize[0], 2); + thumbnail_kernel(s, s->cu_func_ushort2, s->cu_tex_uchar, 1, + histogram + 256, in->data[1], in->width, in->height, in->linesize[1], 2); + thumbnail_kernel(s, s->cu_func_ushort2, s->cu_tex_uchar, 1, + histogram + 512, in->data[2], in->width, in->height, in->linesize[2], 2); + break; + default: + return AVERROR_BUG; + } + + return 0; +} + +static int filter_frame(AVFilterLink *inlink, AVFrame *frame) +{ + AVFilterContext *ctx = inlink->dst; + ThumbnailCudaContext *s = ctx->priv; + AVFilterLink *outlink = ctx->outputs[0]; + int *hist = s->frames[s->n].histogram; + AVHWFramesContext *hw_frames_ctx = (AVHWFramesContext*)s->hw_frames_ctx->data; + AVCUDADeviceContext *device_hwctx = hw_frames_ctx->device_ctx->hwctx; + CUresult err; + CUcontext dummy; + CUDA_MEMCPY2D cpy = { 0 }; + int ret = 0; + + // keep a reference of each frame + s->frames[s->n].buf = frame; + + err = cuCtxPushCurrent(device_hwctx->cuda_ctx); + if (err != CUDA_SUCCESS) + return AVERROR_UNKNOWN; + + cuMemsetD8(s->data, 0, HIST_SIZE * sizeof(int)); + + thumbnail(ctx, (int*)s->data, frame); + + cpy.srcMemoryType = CU_MEMORYTYPE_DEVICE; + cpy.dstMemoryType = CU_MEMORYTYPE_HOST; + cpy.srcDevice = s->data; + cpy.dstHost = hist; + cpy.srcPitch = HIST_SIZE * sizeof(int); + cpy.dstPitch = HIST_SIZE * sizeof(int); + cpy.WidthInBytes = HIST_SIZE * sizeof(int); + cpy.Height = 1; + + err = cuMemcpy2D(&cpy); + if (err != CUDA_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Error transferring the data from the CUDA frame\n"); + return AVERROR_UNKNOWN; + } + + if (hw_frames_ctx->sw_format == AV_PIX_FMT_NV12 || hw_frames_ctx->sw_format == AV_PIX_FMT_YUV420P || + hw_frames_ctx->sw_format == AV_PIX_FMT_P010LE || hw_frames_ctx->sw_format == AV_PIX_FMT_P016LE) + { + for (int i = 256; i < HIST_SIZE; i++) + hist[i] = 4 * hist[i]; + } + + cuCtxPopCurrent(&dummy); + if (ret < 0) + return ret; + + // no selection until the buffer of N frames is filled up + s->n++; + if (s->n < s->n_frames) + return 0; + + return ff_filter_frame(outlink, get_best_frame(ctx)); +} + +static av_cold void uninit(AVFilterContext *ctx) +{ + int i; + ThumbnailCudaContext *s = ctx->priv; + + if (s->data) { + cuMemFree(s->data); + s->data = 0; + } + + if (s->cu_module) { + cuModuleUnload(s->cu_module); + s->cu_module = NULL; + } + + for (i = 0; i < s->n_frames && s->frames[i].buf; i++) + av_frame_free(&s->frames[i].buf); + av_freep(&s->frames); +} + +static int request_frame(AVFilterLink *link) +{ + AVFilterContext *ctx = link->src; + ThumbnailCudaContext *s = ctx->priv; + int ret = ff_request_frame(ctx->inputs[0]); + + if (ret == AVERROR_EOF && s->n) { + ret = ff_filter_frame(link, get_best_frame(ctx)); + if (ret < 0) + return ret; + ret = AVERROR_EOF; + } + if (ret < 0) + return ret; + return 0; +} + +static int format_is_supported(enum AVPixelFormat fmt) +{ + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) + if (supported_formats[i] == fmt) + return 1; + return 0; +} + +static int config_props(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + ThumbnailCudaContext *s = ctx->priv; + AVHWFramesContext *hw_frames_ctx = (AVHWFramesContext*)inlink->hw_frames_ctx->data; + AVCUDADeviceContext *device_hwctx = hw_frames_ctx->device_ctx->hwctx; + CUcontext dummy, cuda_ctx = device_hwctx->cuda_ctx; + CUresult err; + + extern char vf_thumbnail_cuda_ptx[]; + + err = cuCtxPushCurrent(cuda_ctx); + if (err != CUDA_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Error pushing cuda context\n"); + return AVERROR_UNKNOWN; + } + + err = cuModuleLoadData(&s->cu_module, vf_thumbnail_cuda_ptx); + if (err != CUDA_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Error loading module data\n"); + return AVERROR_UNKNOWN; + } + + cuModuleGetFunction(&s->cu_func_uchar, s->cu_module, "Thumbnail_uchar"); + cuModuleGetFunction(&s->cu_func_uchar2, s->cu_module, "Thumbnail_uchar2"); + cuModuleGetFunction(&s->cu_func_ushort, s->cu_module, "Thumbnail_ushort"); + cuModuleGetFunction(&s->cu_func_ushort2, s->cu_module, "Thumbnail_ushort2"); + + cuModuleGetTexRef(&s->cu_tex_uchar, s->cu_module, "uchar_tex"); + cuModuleGetTexRef(&s->cu_tex_uchar2, s->cu_module, "uchar2_tex"); + cuModuleGetTexRef(&s->cu_tex_ushort, s->cu_module, "ushort_tex"); + cuModuleGetTexRef(&s->cu_tex_ushort2, s->cu_module, "ushort2_tex"); + + cuTexRefSetFlags(s->cu_tex_uchar, CU_TRSF_READ_AS_INTEGER); + cuTexRefSetFlags(s->cu_tex_uchar2, CU_TRSF_READ_AS_INTEGER); + cuTexRefSetFlags(s->cu_tex_ushort, CU_TRSF_READ_AS_INTEGER); + cuTexRefSetFlags(s->cu_tex_ushort2, CU_TRSF_READ_AS_INTEGER); + + cuTexRefSetFilterMode(s->cu_tex_uchar, CU_TR_FILTER_MODE_LINEAR); + cuTexRefSetFilterMode(s->cu_tex_uchar2, CU_TR_FILTER_MODE_LINEAR); + cuTexRefSetFilterMode(s->cu_tex_ushort, CU_TR_FILTER_MODE_LINEAR); + cuTexRefSetFilterMode(s->cu_tex_ushort2, CU_TR_FILTER_MODE_LINEAR); + + err = cuMemAlloc(&s->data, HIST_SIZE * sizeof(int)); + if (err != CUDA_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Error allocating cuda memory\n"); + return AVERROR_UNKNOWN; + } + + cuCtxPopCurrent(&dummy); + + s->hw_frames_ctx = ctx->inputs[0]->hw_frames_ctx; + + ctx->outputs[0]->hw_frames_ctx = av_buffer_ref(s->hw_frames_ctx); + if (!ctx->outputs[0]->hw_frames_ctx) + return AVERROR(ENOMEM); + + s->tb = inlink->time_base; + + if (!format_is_supported(hw_frames_ctx->sw_format)) { + av_log(ctx, AV_LOG_ERROR, "Unsupported input format: %s\n", av_get_pix_fmt_name(hw_frames_ctx->sw_format)); + return AVERROR(ENOSYS); + } + + return 0; +} + +static int query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pix_fmts[] = { + AV_PIX_FMT_CUDA, + AV_PIX_FMT_NONE + }; + AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); + if (!fmts_list) + return AVERROR(ENOMEM); + return ff_set_common_formats(ctx, fmts_list); +} + +static const AVFilterPad thumbnail_cuda_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = config_props, + .filter_frame = filter_frame, + }, + { NULL } +}; + +static const AVFilterPad thumbnail_cuda_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .request_frame = request_frame, + }, + { NULL } +}; + +AVFilter ff_vf_thumbnail_cuda = { + .name = "thumbnail_cuda", + .description = NULL_IF_CONFIG_SMALL("Select the most representative frame in a given sequence of consecutive frames."), + .priv_size = sizeof(ThumbnailCudaContext), + .init = init, + .uninit = uninit, + .query_formats = query_formats, + .inputs = thumbnail_cuda_inputs, + .outputs = thumbnail_cuda_outputs, + .priv_class = &thumbnail_cuda_class, + .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, +}; diff --git a/libavfilter/vf_thumbnail_cuda.cu b/libavfilter/vf_thumbnail_cuda.cu new file mode 100644 index 0000000000000..98fad4303a74a --- /dev/null +++ b/libavfilter/vf_thumbnail_cuda.cu @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +extern "C" { + +texture uchar_tex; +texture uchar2_tex; +texture ushort_tex; +texture ushort2_tex; + +__global__ void Thumbnail_uchar(int *histogram, int src_width, int src_height) +{ + int x = blockIdx.x * blockDim.x + threadIdx.x; + int y = blockIdx.y * blockDim.y + threadIdx.y; + if (y < src_height && x < src_width) + { + unsigned char pixel = tex2D(uchar_tex, x, y); + atomicAdd(&histogram[pixel], 1); + } +} + +__global__ void Thumbnail_uchar2(int *histogram, int src_width, int src_height) +{ + int x = blockIdx.x * blockDim.x + threadIdx.x; + int y = blockIdx.y * blockDim.y + threadIdx.y; + + if (y < src_height && x < src_width) + { + uchar2 pixel = tex2D(uchar2_tex, x, y); + atomicAdd(&histogram[pixel.x], 1); + atomicAdd(&histogram[256 + pixel.y], 1); + } +} + +__global__ void Thumbnail_ushort(int *histogram, int src_width, int src_height) +{ + int x = blockIdx.x * blockDim.x + threadIdx.x; + int y = blockIdx.y * blockDim.y + threadIdx.y; + + if (y < src_height && x < src_width) + { + unsigned short pixel = (tex2D(ushort_tex, x, y) + 128) >> 8; + atomicAdd(&histogram[pixel], 1); + } +} + +__global__ void Thumbnail_ushort2(int *histogram, int src_width, int src_height) +{ + int x = blockIdx.x * blockDim.x + threadIdx.x; + int y = blockIdx.y * blockDim.y + threadIdx.y; + + if (y < src_height && x < src_width) + { + ushort2 pixel = tex2D(ushort2_tex, x, y); + atomicAdd(&histogram[(pixel.x + 128) >> 8], 1); + atomicAdd(&histogram[256 + (pixel.y + 128) >> 8], 1); + } +} + +} From 2b156269974995c42456586f7218ce22a525a1d9 Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Thu, 21 Sep 2017 12:17:40 +0530 Subject: [PATCH 3136/3374] avcodec/mips: preload data in hevc sao edge 90 degree filter msa functions Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/hevc_lpf_sao_msa.c | 181 +++++++++++++++++++---------- 1 file changed, 122 insertions(+), 59 deletions(-) diff --git a/libavcodec/mips/hevc_lpf_sao_msa.c b/libavcodec/mips/hevc_lpf_sao_msa.c index 3472d32322c1b..39c647ed7918b 100644 --- a/libavcodec/mips/hevc_lpf_sao_msa.c +++ b/libavcodec/mips/hevc_lpf_sao_msa.c @@ -1568,23 +1568,25 @@ static void hevc_sao_edge_filter_90degree_4width_msa(uint8_t *dst, int16_t *sao_offset_val, int32_t height) { - int32_t h_cnt; uint32_t dst_val0, dst_val1; - v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 }; + v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; v16u8 const1 = (v16u8) __msa_ldi_b(1); v16i8 dst0; - v16i8 zero = { 0 }; + v16i8 sao_offset = LD_SB(sao_offset_val); v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11; v16u8 src_minus10, src_minus11, src10, src11; v16i8 src_zero0, src_zero1; - v8i16 sao_offset, src00, src01, offset_mask0, offset_mask1; + v16i8 offset; + v8i16 offset_mask0, offset_mask1; - sao_offset = LD_SH(sao_offset_val); + sao_offset = __msa_pckev_b(sao_offset, sao_offset); + /* load in advance */ LD_UB2(src - src_stride, src_stride, src_minus10, src_minus11); + LD_UB2(src + src_stride, src_stride, src10, src11); - for (h_cnt = (height >> 1); h_cnt--;) { - LD_UB2(src + src_stride, src_stride, src10, src11); + for (height -= 2; height; height -= 2) { + src += (src_stride << 1); src_minus10 = (v16u8) __msa_ilvr_b((v16i8) src10, (v16i8) src_minus10); src_zero0 = __msa_ilvr_b((v16i8) src_minus11, (v16i8) src_minus11); @@ -1604,19 +1606,22 @@ static void hevc_sao_edge_filter_90degree_4width_msa(uint8_t *dst, offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); - VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0, - offset_mask0, offset_mask0, offset_mask0); - VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1, - offset_mask1, offset_mask1, offset_mask1); - ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01); - ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0, - offset_mask1); - CLIP_SH2_0_255(offset_mask0, offset_mask1); - dst0 = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); + offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); + dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); + + VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, + offset, offset); + + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); + dst0 = __msa_adds_s_b(dst0, offset); + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); src_minus10 = src10; src_minus11 = src11; + /* load in advance */ + LD_UB2(src + src_stride, src_stride, src10, src11); + dst_val0 = __msa_copy_u_w((v4i32) dst0, 0); dst_val1 = __msa_copy_u_w((v4i32) dst0, 2); SW(dst_val0, dst); @@ -1624,8 +1629,41 @@ static void hevc_sao_edge_filter_90degree_4width_msa(uint8_t *dst, SW(dst_val1, dst); dst += dst_stride; - src += (src_stride << 1); } + + src_minus10 = (v16u8) __msa_ilvr_b((v16i8) src10, (v16i8) src_minus10); + src_zero0 = __msa_ilvr_b((v16i8) src_minus11, (v16i8) src_minus11); + src_minus11 = (v16u8) __msa_ilvr_b((v16i8) src11, (v16i8) src_minus11); + src_zero1 = __msa_ilvr_b((v16i8) src10, (v16i8) src10); + + cmp_minus10 = ((v16u8) src_zero0 == src_minus10); + diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); + cmp_minus10 = (src_minus10 < (v16u8) src_zero0); + diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); + + cmp_minus11 = ((v16u8) src_zero1 == src_minus11); + diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); + cmp_minus11 = (src_minus11 < (v16u8) src_zero1); + diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); + + offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); + offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); + + offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); + dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); + + VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, + offset, offset, offset); + + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); + dst0 = __msa_adds_s_b(dst0, offset); + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); + + dst_val0 = __msa_copy_u_w((v4i32) dst0, 0); + dst_val1 = __msa_copy_u_w((v4i32) dst0, 2); + SW(dst_val0, dst); + dst += dst_stride; + SW(dst_val1, dst); } static void hevc_sao_edge_filter_90degree_8width_msa(uint8_t *dst, @@ -1635,22 +1673,23 @@ static void hevc_sao_edge_filter_90degree_8width_msa(uint8_t *dst, int16_t *sao_offset_val, int32_t height) { - int32_t h_cnt; uint64_t dst_val0, dst_val1; - v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 }; + v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; v16u8 const1 = (v16u8) __msa_ldi_b(1); - v16i8 zero = { 0 }; - v16i8 src_zero0, src_zero1, dst0, dst1; + v16i8 offset, sao_offset = LD_SB(sao_offset_val); + v16i8 src_zero0, src_zero1, dst0; v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11; v16u8 src_minus10, src_minus11, src10, src11; - v8i16 sao_offset, src00, offset_mask0, src01, offset_mask1; + v8i16 offset_mask0, offset_mask1; - sao_offset = LD_SH(sao_offset_val); + sao_offset = __msa_pckev_b(sao_offset, sao_offset); + /* load in advance */ LD_UB2(src - src_stride, src_stride, src_minus10, src_minus11); + LD_UB2(src + src_stride, src_stride, src10, src11); - for (h_cnt = (height >> 1); h_cnt--;) { - LD_UB2(src + src_stride, src_stride, src10, src11); + for (height -= 2; height; height -= 2) { + src += (src_stride << 1); src_minus10 = (v16u8) __msa_ilvr_b((v16i8) src10, (v16i8) src_minus10); src_zero0 = __msa_ilvr_b((v16i8) src_minus11, (v16i8) src_minus11); @@ -1670,28 +1709,63 @@ static void hevc_sao_edge_filter_90degree_8width_msa(uint8_t *dst, offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); - VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0, - offset_mask0, offset_mask0, offset_mask0); - VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1, - offset_mask1, offset_mask1, offset_mask1); - ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01); - ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0, - offset_mask1); - CLIP_SH2_0_255(offset_mask0, offset_mask1); - PCKEV_B2_SB(offset_mask0, offset_mask0, offset_mask1, offset_mask1, - dst0, dst1); + offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); + dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); + + VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, + offset, offset, offset); + + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); + dst0 = __msa_adds_s_b(dst0, offset); + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); src_minus10 = src10; src_minus11 = src11; + /* load in advance */ + LD_UB2(src + src_stride, src_stride, src10, src11); + dst_val0 = __msa_copy_u_d((v2i64) dst0, 0); - dst_val1 = __msa_copy_u_d((v2i64) dst1, 0); + dst_val1 = __msa_copy_u_d((v2i64) dst0, 1); SD(dst_val0, dst); dst += dst_stride; SD(dst_val1, dst); dst += dst_stride; - src += (src_stride << 1); } + + src_minus10 = (v16u8) __msa_ilvr_b((v16i8) src10, (v16i8) src_minus10); + src_zero0 = __msa_ilvr_b((v16i8) src_minus11, (v16i8) src_minus11); + src_minus11 = (v16u8) __msa_ilvr_b((v16i8) src11, (v16i8) src_minus11); + src_zero1 = __msa_ilvr_b((v16i8) src10, (v16i8) src10); + + cmp_minus10 = ((v16u8) src_zero0 == src_minus10); + diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); + cmp_minus10 = (src_minus10 < (v16u8) src_zero0); + diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); + + cmp_minus11 = ((v16u8) src_zero1 == src_minus11); + diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); + cmp_minus11 = (src_minus11 < (v16u8) src_zero1); + diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); + + offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); + offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); + + offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); + dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); + + VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, + offset, offset); + + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); + dst0 = __msa_adds_s_b(dst0, offset); + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); + + dst_val0 = __msa_copy_u_d((v2i64) dst0, 0); + dst_val1 = __msa_copy_u_d((v2i64) dst0, 1); + SD(dst_val0, dst); + dst += dst_stride; + SD(dst_val1, dst); } static void hevc_sao_edge_filter_90degree_16multiple_msa(uint8_t *dst, @@ -1715,15 +1789,13 @@ static void hevc_sao_edge_filter_90degree_16multiple_msa(uint8_t *dst, v16u8 src10, src_minus10, dst0, src11, src_minus11, dst1; v16u8 src12, dst2, src13, dst3; v16i8 offset_mask0, offset_mask1, offset_mask2, offset_mask3, sao_offset; - v8i16 src0, src1, src2, src3, src4, src5, src6, src7; - v8i16 temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7; sao_offset = LD_SB(sao_offset_val); sao_offset = __msa_pckev_b(sao_offset, sao_offset); - for (v_cnt = 0; v_cnt < (width >> 4); v_cnt++) { - src = src_orig + (v_cnt << 4); - dst = dst_orig + (v_cnt << 4); + for (v_cnt = 0; v_cnt < width; v_cnt += 16) { + src = src_orig + v_cnt; + dst = dst_orig + v_cnt; LD_UB2(src - src_stride, src_stride, src_minus10, src_minus11); @@ -1779,24 +1851,15 @@ static void hevc_sao_edge_filter_90degree_16multiple_msa(uint8_t *dst, VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask3, offset_mask3, offset_mask3, offset_mask3); - UNPCK_UB_SH(src_minus11, src0, src1); - UNPCK_SB_SH(offset_mask0, temp0, temp1); - UNPCK_UB_SH(src10, src2, src3); - UNPCK_SB_SH(offset_mask1, temp2, temp3); - UNPCK_UB_SH(src11, src4, src5); - UNPCK_SB_SH(offset_mask2, temp4, temp5); - UNPCK_UB_SH(src12, src6, src7); - UNPCK_SB_SH(offset_mask3, temp6, temp7); - ADD4(temp0, src0, temp1, src1, temp2, src2, temp3, src3, temp0, - temp1, temp2, temp3); - ADD4(temp4, src4, temp5, src5, temp6, src6, temp7, src7, temp4, - temp5, temp6, temp7); - CLIP_SH4_0_255(temp0, temp1, temp2, temp3); - CLIP_SH4_0_255(temp4, temp5, temp6, temp7); - PCKEV_B4_UB(temp1, temp0, temp3, temp2, temp5, temp4, temp7, temp6, - dst0, dst1, dst2, dst3); - src_minus10 = src12; + XORI_B4_128_UB(src_minus11, src10, src11, src12); + + dst0 = (v16u8) __msa_adds_s_b((v16i8) src_minus11, offset_mask0); + dst1 = (v16u8) __msa_adds_s_b((v16i8) src10, offset_mask1); + dst2 = (v16u8) __msa_adds_s_b((v16i8) src11, offset_mask2); + dst3 = (v16u8) __msa_adds_s_b((v16i8) src12, offset_mask3); + + XORI_B4_128_UB(dst0, dst1, dst2, dst3); src_minus11 = src13; ST_UB4(dst0, dst1, dst2, dst3, dst, dst_stride); From f160a63badfc6103ce9fdbfeff7c82111ba81ab8 Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Thu, 21 Sep 2017 12:45:28 +0530 Subject: [PATCH 3137/3374] avcodec/mips: Remove generic func use in hevc non-uni copy mc msa functions Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/hevcdsp_msa.c | 168 ++++++++++++++++++++++++++++++++-- 1 file changed, 160 insertions(+), 8 deletions(-) diff --git a/libavcodec/mips/hevcdsp_msa.c b/libavcodec/mips/hevcdsp_msa.c index f2bc748e37815..1a854b204ff35 100644 --- a/libavcodec/mips/hevcdsp_msa.c +++ b/libavcodec/mips/hevcdsp_msa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com) + * Copyright (c) 2015 - 2017 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com) * * This file is part of FFmpeg. * @@ -302,8 +302,34 @@ static void hevc_copy_16w_msa(uint8_t *src, int32_t src_stride, ST_SH4(in0_r, in1_r, in2_r, in3_r, dst, dst_stride); ST_SH4(in0_l, in1_l, in2_l, in3_l, (dst + 8), dst_stride); } else if (0 == (height % 8)) { - hevc_copy_16multx8mult_msa(src, src_stride, dst, dst_stride, - height, 16); + uint32_t loop_cnt; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7; + v8i16 in0_r, in1_r, in2_r, in3_r, in0_l, in1_l, in2_l, in3_l; + + for (loop_cnt = (height >> 3); loop_cnt--;) { + LD_SB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, + src7); + src += (8 * src_stride); + ILVR_B4_SH(zero, src0, zero, src1, zero, src2, zero, src3, in0_r, + in1_r, in2_r, in3_r); + ILVL_B4_SH(zero, src0, zero, src1, zero, src2, zero, src3, in0_l, + in1_l, in2_l, in3_l); + SLLI_4V(in0_r, in1_r, in2_r, in3_r, 6); + SLLI_4V(in0_l, in1_l, in2_l, in3_l, 6); + ST_SH4(in0_r, in1_r, in2_r, in3_r, dst, dst_stride); + ST_SH4(in0_l, in1_l, in2_l, in3_l, (dst + 8), dst_stride); + dst += (4 * dst_stride); + + ILVR_B4_SH(zero, src4, zero, src5, zero, src6, zero, src7, in0_r, + in1_r, in2_r, in3_r); + ILVL_B4_SH(zero, src4, zero, src5, zero, src6, zero, src7, in0_l, + in1_l, in2_l, in3_l); + SLLI_4V(in0_r, in1_r, in2_r, in3_r, 6); + SLLI_4V(in0_l, in1_l, in2_l, in3_l, 6); + ST_SH4(in0_r, in1_r, in2_r, in3_r, dst, dst_stride); + ST_SH4(in0_l, in1_l, in2_l, in3_l, (dst + 8), dst_stride); + dst += (4 * dst_stride); + } } } @@ -311,29 +337,155 @@ static void hevc_copy_24w_msa(uint8_t *src, int32_t src_stride, int16_t *dst, int32_t dst_stride, int32_t height) { - hevc_copy_16multx8mult_msa(src, src_stride, dst, dst_stride, height, 16); - hevc_copy_8w_msa(src + 16, src_stride, dst + 16, dst_stride, height); + uint32_t loop_cnt; + v16i8 zero = { 0 }; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7; + v8i16 in0_r, in1_r, in2_r, in3_r, in0_l, in1_l, in2_l, in3_l; + + for (loop_cnt = (height >> 2); loop_cnt--;) { + LD_SB4(src, src_stride, src0, src1, src2, src3); + LD_SB4((src + 16), src_stride, src4, src5, src6, src7); + src += (4 * src_stride); + ILVR_B4_SH(zero, src0, zero, src1, zero, src2, zero, src3, in0_r, in1_r, + in2_r, in3_r); + ILVL_B4_SH(zero, src0, zero, src1, zero, src2, zero, src3, in0_l, in1_l, + in2_l, in3_l); + SLLI_4V(in0_r, in1_r, in2_r, in3_r, 6); + SLLI_4V(in0_l, in1_l, in2_l, in3_l, 6); + ST_SH4(in0_r, in1_r, in2_r, in3_r, dst, dst_stride); + ST_SH4(in0_l, in1_l, in2_l, in3_l, (dst + 8), dst_stride); + ILVR_B4_SH(zero, src4, zero, src5, zero, src6, zero, src7, in0_r, in1_r, + in2_r, in3_r); + SLLI_4V(in0_r, in1_r, in2_r, in3_r, 6); + ST_SH4(in0_r, in1_r, in2_r, in3_r, (dst + 16), dst_stride); + dst += (4 * dst_stride); + } } static void hevc_copy_32w_msa(uint8_t *src, int32_t src_stride, int16_t *dst, int32_t dst_stride, int32_t height) { - hevc_copy_16multx8mult_msa(src, src_stride, dst, dst_stride, height, 32); + uint32_t loop_cnt; + v16i8 zero = { 0 }; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7; + v8i16 in0_r, in1_r, in2_r, in3_r, in0_l, in1_l, in2_l, in3_l; + + for (loop_cnt = (height >> 2); loop_cnt--;) { + LD_SB4(src, src_stride, src0, src2, src4, src6); + LD_SB4((src + 16), src_stride, src1, src3, src5, src7); + src += (4 * src_stride); + + ILVR_B4_SH(zero, src0, zero, src1, zero, src2, zero, src3, in0_r, in1_r, + in2_r, in3_r); + ILVL_B4_SH(zero, src0, zero, src1, zero, src2, zero, src3, in0_l, in1_l, + in2_l, in3_l); + SLLI_4V(in0_r, in1_r, in2_r, in3_r, 6); + SLLI_4V(in0_l, in1_l, in2_l, in3_l, 6); + ST_SH4(in0_r, in0_l, in1_r, in1_l, dst, 8); + dst += dst_stride; + ST_SH4(in2_r, in2_l, in3_r, in3_l, dst, 8); + dst += dst_stride; + + ILVR_B4_SH(zero, src4, zero, src5, zero, src6, zero, src7, in0_r, in1_r, + in2_r, in3_r); + ILVL_B4_SH(zero, src4, zero, src5, zero, src6, zero, src7, in0_l, in1_l, + in2_l, in3_l); + SLLI_4V(in0_r, in1_r, in2_r, in3_r, 6); + SLLI_4V(in0_l, in1_l, in2_l, in3_l, 6); + ST_SH4(in0_r, in0_l, in1_r, in1_l, dst, 8); + dst += dst_stride; + ST_SH4(in2_r, in2_l, in3_r, in3_l, dst, 8); + dst += dst_stride; + } } static void hevc_copy_48w_msa(uint8_t *src, int32_t src_stride, int16_t *dst, int32_t dst_stride, int32_t height) { - hevc_copy_16multx8mult_msa(src, src_stride, dst, dst_stride, height, 48); + uint32_t loop_cnt; + v16i8 zero = { 0 }; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7; + v16i8 src8, src9, src10, src11; + v8i16 in0_r, in1_r, in2_r, in3_r, in4_r, in5_r; + v8i16 in0_l, in1_l, in2_l, in3_l, in4_l, in5_l; + + for (loop_cnt = (height >> 2); loop_cnt--;) { + LD_SB3(src, 16, src0, src1, src2); + src += src_stride; + LD_SB3(src, 16, src3, src4, src5); + src += src_stride; + LD_SB3(src, 16, src6, src7, src8); + src += src_stride; + LD_SB3(src, 16, src9, src10, src11); + src += src_stride; + + ILVR_B4_SH(zero, src0, zero, src1, zero, src2, zero, src3, + in0_r, in1_r, in2_r, in3_r); + ILVL_B4_SH(zero, src0, zero, src1, zero, src2, zero, src3, + in0_l, in1_l, in2_l, in3_l); + ILVR_B2_SH(zero, src4, zero, src5, in4_r, in5_r); + ILVL_B2_SH(zero, src4, zero, src5, in4_l, in5_l); + SLLI_4V(in0_r, in1_r, in2_r, in3_r, 6); + SLLI_4V(in0_l, in1_l, in2_l, in3_l, 6); + SLLI_4V(in4_r, in5_r, in4_l, in5_l, 6); + ST_SH6(in0_r, in0_l, in1_r, in1_l, in2_r, in2_l, dst, 8); + dst += dst_stride; + ST_SH6(in3_r, in3_l, in4_r, in4_l, in5_r, in5_l, dst, 8); + dst += dst_stride; + + ILVR_B4_SH(zero, src6, zero, src7, zero, src8, zero, src9, + in0_r, in1_r, in2_r, in3_r); + ILVL_B4_SH(zero, src6, zero, src7, zero, src8, zero, src9, + in0_l, in1_l, in2_l, in3_l); + ILVR_B2_SH(zero, src10, zero, src11, in4_r, in5_r); + ILVL_B2_SH(zero, src10, zero, src11, in4_l, in5_l); + SLLI_4V(in0_r, in1_r, in2_r, in3_r, 6); + SLLI_4V(in0_l, in1_l, in2_l, in3_l, 6); + SLLI_4V(in4_r, in5_r, in4_l, in5_l, 6); + ST_SH6(in0_r, in0_l, in1_r, in1_l, in2_r, in2_l, dst, 8); + dst += dst_stride; + ST_SH6(in3_r, in3_l, in4_r, in4_l, in5_r, in5_l, dst, 8); + dst += dst_stride; + } } static void hevc_copy_64w_msa(uint8_t *src, int32_t src_stride, int16_t *dst, int32_t dst_stride, int32_t height) { - hevc_copy_16multx8mult_msa(src, src_stride, dst, dst_stride, height, 64); + uint32_t loop_cnt; + v16i8 zero = { 0 }; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7; + v8i16 in0_r, in1_r, in2_r, in3_r, in0_l, in1_l, in2_l, in3_l; + + for (loop_cnt = (height >> 1); loop_cnt--;) { + LD_SB4(src, 16, src0, src1, src2, src3); + src += src_stride; + LD_SB4(src, 16, src4, src5, src6, src7); + src += src_stride; + + ILVR_B4_SH(zero, src0, zero, src1, zero, src2, zero, src3, + in0_r, in1_r, in2_r, in3_r); + ILVL_B4_SH(zero, src0, zero, src1, zero, src2, zero, src3, + in0_l, in1_l, in2_l, in3_l); + SLLI_4V(in0_r, in1_r, in2_r, in3_r, 6); + SLLI_4V(in0_l, in1_l, in2_l, in3_l, 6); + ST_SH4(in0_r, in0_l, in1_r, in1_l, dst, 8); + ST_SH4(in2_r, in2_l, in3_r, in3_l, (dst + 32), 8); + dst += dst_stride; + + ILVR_B4_SH(zero, src4, zero, src5, zero, src6, zero, src7, + in0_r, in1_r, in2_r, in3_r); + ILVL_B4_SH(zero, src4, zero, src5, zero, src6, zero, src7, + in0_l, in1_l, in2_l, in3_l); + SLLI_4V(in0_r, in1_r, in2_r, in3_r, 6); + SLLI_4V(in0_l, in1_l, in2_l, in3_l, 6); + ST_SH4(in0_r, in0_l, in1_r, in1_l, dst, 8); + ST_SH4(in2_r, in2_l, in3_r, in3_l, (dst + 32), 8); + dst += dst_stride; + } } static void hevc_hz_8t_4w_msa(uint8_t *src, int32_t src_stride, From 2c933c51687db958d8045d25ed87848342e869f6 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 18 Sep 2017 17:03:55 +0200 Subject: [PATCH 3138/3374] avcodec/svq3: Fix overflow in svq3_add_idct_c() Fixes: runtime error: signed integer overflow: 2147392585 + 524288 cannot be represented in type 'int' Fixes: 3348/clusterfuzz-testcase-minimized-4809500517203968 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/svq3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index a766fa49ada46..5cb5bd45b7a5a 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -285,7 +285,7 @@ static void svq3_add_idct_c(uint8_t *dst, int16_t *block, const unsigned z1 = 13 * (block[i + 4 * 0] - block[i + 4 * 2]); const unsigned z2 = 7 * block[i + 4 * 1] - 17 * block[i + 4 * 3]; const unsigned z3 = 17 * block[i + 4 * 1] + 7 * block[i + 4 * 3]; - const int rr = (dc + 0x80000); + const int rr = (dc + 0x80000u); dst[i + stride * 0] = av_clip_uint8(dst[i + stride * 0] + ((int)((z0 + z3) * qmul + rr) >> 20)); dst[i + stride * 1] = av_clip_uint8(dst[i + stride * 1] + ((int)((z1 + z2) * qmul + rr) >> 20)); From d00fc952b6c261dd8eb0f7552b9ccf985dbc2b20 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 18 Sep 2017 17:26:09 +0200 Subject: [PATCH 3139/3374] avcodec/ffv1dec: Fix integer overflow in read_quant_table() Fixes: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int' Fixes: 3361/clusterfuzz-testcase-minimized-5065842955911168 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/ffv1dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index b13ecd3eabba0..d2bfee784fb36 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -372,7 +372,7 @@ static int read_quant_table(RangeCoder *c, int16_t *quant_table, int scale) memset(state, 128, sizeof(state)); for (v = 0; i < 128; v++) { - unsigned len = get_symbol(c, state, 0) + 1; + unsigned len = get_symbol(c, state, 0) + 1U; if (len > 128 - i || !len) return AVERROR_INVALIDDATA; From 67da2685e03805230207daab83ab43a390fbb887 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 18 Sep 2017 02:53:25 +0200 Subject: [PATCH 3140/3374] avcodec/dirac_dwt: Fix integer overflow in COMPOSE_FIDELITYi*() Fixes: runtime error: signed integer overflow: 161 * 13872281 cannot be represented in type 'int' Fixes: 3295/clusterfuzz-testcase-minimized-4738998142500864 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/dirac_dwt.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/dirac_dwt.h b/libavcodec/dirac_dwt.h index adf5178714dba..755d5e5d2def0 100644 --- a/libavcodec/dirac_dwt.h +++ b/libavcodec/dirac_dwt.h @@ -111,10 +111,10 @@ void ff_spatial_idwt_slice2(DWTContext *d, int y); (b0 + b1) #define COMPOSE_FIDELITYiL0(b0, b1, b2, b3, b4, b5, b6, b7, b8)\ - (b4 - ((-8*(b0+b8) + 21*(b1+b7) - 46*(b2+b6) + 161*(b3+b5) + 128) >> 8)) + (b4 - ((int)(-8*(b0+(unsigned)b8) + 21*(b1+(unsigned)b7) - 46*(b2+(unsigned)b6) + 161*(b3+(unsigned)b5) + 128) >> 8)) #define COMPOSE_FIDELITYiH0(b0, b1, b2, b3, b4, b5, b6, b7, b8)\ - (b4 + ((-2*(b0+b8) + 10*(b1+b7) - 25*(b2+b6) + 81*(b3+b5) + 128) >> 8)) + (b4 + ((int)(-2*(b0+(unsigned)b8) + 10*(b1+(unsigned)b7) - 25*(b2+(unsigned)b6) + 81*(b3+(unsigned)b5) + 128) >> 8)) #define COMPOSE_DAUB97iL1(b0, b1, b2)\ (b1 - ((int)(1817*(b0 + (unsigned)b2) + 2048) >> 12)) From bb4b7624d9dd17dcda44703d5d69292a85fe2d4d Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 23 Sep 2017 02:15:16 -0300 Subject: [PATCH 3141/3374] avformat/apngenc: use av_packet_alloc() Signed-off-by: James Almer --- libavformat/apngenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/apngenc.c b/libavformat/apngenc.c index 378a9b3b368f0..d4191c02cc65e 100644 --- a/libavformat/apngenc.c +++ b/libavformat/apngenc.c @@ -228,7 +228,7 @@ static int apng_write_packet(AVFormatContext *format_context, AVPacket *packet) int ret; if (!apng->prev_packet) { - apng->prev_packet = av_malloc(sizeof(*apng->prev_packet)); + apng->prev_packet = av_packet_alloc(); if (!apng->prev_packet) return AVERROR(ENOMEM); From afe674734bbe71ef6c32f96a98f5f84d007eea1c Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 23 Sep 2017 02:18:47 -0300 Subject: [PATCH 3142/3374] avformat/gif: use av_packet_alloc() Signed-off-by: James Almer --- libavformat/gif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/gif.c b/libavformat/gif.c index 91cd40db5c135..d6113dbc85fd5 100644 --- a/libavformat/gif.c +++ b/libavformat/gif.c @@ -186,7 +186,7 @@ static int gif_write_packet(AVFormatContext *s, AVPacket *pkt) AVStream *video_st = s->streams[0]; if (!gif->prev_pkt) { - gif->prev_pkt = av_malloc(sizeof(*gif->prev_pkt)); + gif->prev_pkt = av_packet_alloc(); if (!gif->prev_pkt) return AVERROR(ENOMEM); From 1ef7752d64cbe9af2f27cc65aba3a2ca3831c128 Mon Sep 17 00:00:00 2001 From: Jorge Ramirez-Ortiz Date: Wed, 20 Sep 2017 18:55:40 -0700 Subject: [PATCH 3143/3374] libavcodec: v4l2: add support for v4l2 mem2mem codecs This patchset enhances Alexis Ballier's original patch and validates it using Qualcomm's Venus hardware (driver recently landed upstream [1]). This has been tested on Qualcomm's DragonBoard 410c and 820c Configure/make scripts have been validated on Ubuntu 10.04 and 16.04. Tested decoders: - h264 - h263 - mpeg4 - vp8 - vp9 - hevc Tested encoders: - h264 - h263 - mpeg4 Tested transcoding (concurrent encoding/decoding) Some of the changes introduced: - v4l2: code cleanup and abstractions added - v4l2: follow the new encode/decode api. - v4l2: fix display size for NV12 output pool. - v4l2: handle EOS (EPIPE and draining) - v4l2: vp8 and mpeg4 decoding and encoding. - v4l2: hevc and vp9 support. - v4l2: generate EOF on dequeue errors. - v4l2: h264_mp4toannexb filtering. - v4l2: fixed make install and fate issues. - v4l2: codecs enabled/disabled depending on pixfmt defined - v4l2: pass timebase/framerate to the context - v4l2: runtime decoder reconfiguration. - v4l2: add more frame information - v4l2: free hardware resources on last reference being released - v4l2: encoding: disable b-frames for upstreaming (patch required) [1] https://lwn.net/Articles/697956/ System Level view: v42l_m2m_enc/dec --> v4l2_m2m --> v4l2_context --> v4l2_buffers Reviewed-by: Jorge Ramirez Reviewed-by: Alexis Ballier Tested-by: Jorge Ramirez Signed-off-by: wm4 --- Changelog | 1 + configure | 28 ++ libavcodec/Makefile | 15 + libavcodec/allcodecs.c | 9 + libavcodec/v4l2_buffers.c | 453 ++++++++++++++++++++++++++ libavcodec/v4l2_buffers.h | 121 +++++++ libavcodec/v4l2_context.c | 667 ++++++++++++++++++++++++++++++++++++++ libavcodec/v4l2_context.h | 181 +++++++++++ libavcodec/v4l2_fmt.c | 182 +++++++++++ libavcodec/v4l2_fmt.h | 34 ++ libavcodec/v4l2_m2m.c | 383 ++++++++++++++++++++++ libavcodec/v4l2_m2m.h | 103 ++++++ libavcodec/v4l2_m2m_dec.c | 228 +++++++++++++ libavcodec/v4l2_m2m_enc.c | 352 ++++++++++++++++++++ 14 files changed, 2757 insertions(+) create mode 100644 libavcodec/v4l2_buffers.c create mode 100644 libavcodec/v4l2_buffers.h create mode 100644 libavcodec/v4l2_context.c create mode 100644 libavcodec/v4l2_context.h create mode 100644 libavcodec/v4l2_fmt.c create mode 100644 libavcodec/v4l2_fmt.h create mode 100644 libavcodec/v4l2_m2m.c create mode 100644 libavcodec/v4l2_m2m.h create mode 100644 libavcodec/v4l2_m2m_dec.c create mode 100644 libavcodec/v4l2_m2m_enc.c diff --git a/Changelog b/Changelog index 38b125be39e30..678dcdadc734f 100644 --- a/Changelog +++ b/Changelog @@ -49,6 +49,7 @@ version : - VP9 tile threading support - KMS screen grabber - CUDA thumbnail filter +- V4L2 mem2mem HW assisted codecs version 3.3: diff --git a/configure b/configure index ff9a64292c4b2..16fc2bd074046 100755 --- a/configure +++ b/configure @@ -185,6 +185,7 @@ Individual component options: --enable-filter=NAME enable filter NAME --disable-filter=NAME disable filter NAME --disable-filters disable all filters + --disable-v4l2_m2m disable V4L2 mem2mem code [autodetect] External library support: @@ -1628,6 +1629,7 @@ HWACCEL_AUTODETECT_LIBRARY_LIST=" vda vdpau videotoolbox + v4l2_m2m xvmc " @@ -2755,6 +2757,7 @@ omx_rpi_select="omx" qsvdec_select="qsv" qsvenc_select="qsv" vaapi_encode_deps="vaapi" +v4l2_m2m_deps_any="linux_videodev2_h" hwupload_cuda_filter_deps="cuda" scale_npp_filter_deps="cuda libnpp" @@ -2765,6 +2768,8 @@ nvenc_deps="cuda" nvenc_deps_any="dlopen LoadLibrary" nvenc_encoder_deps="nvenc" +h263_v4l2m2m_decoder_deps="v4l2_m2m h263_v4l2_m2m" +h263_v4l2m2m_encoder_deps="v4l2_m2m h263_v4l2_m2m" h264_crystalhd_decoder_select="crystalhd h264_mp4toannexb_bsf h264_parser" h264_cuvid_decoder_deps="cuda cuvid" h264_cuvid_decoder_select="h264_mp4toannexb_bsf" @@ -2783,6 +2788,8 @@ h264_vda_decoder_deps="vda" h264_vda_decoder_select="h264_decoder" h264_vdpau_decoder_deps="vdpau" h264_vdpau_decoder_select="h264_decoder" +h264_v4l2m2m_decoder_deps="v4l2_m2m h264_v4l2_m2m" +h264_v4l2m2m_encoder_deps="v4l2_m2m h264_v4l2_m2m" hevc_cuvid_decoder_deps="cuda cuvid" hevc_cuvid_decoder_select="hevc_mp4toannexb_bsf" hevc_mediacodec_decoder_deps="mediacodec" @@ -2794,12 +2801,15 @@ hevc_qsv_encoder_deps="libmfx" hevc_qsv_encoder_select="hevcparse qsvenc" hevc_vaapi_encoder_deps="VAEncPictureParameterBufferHEVC" hevc_vaapi_encoder_select="vaapi_encode golomb" +hevc_v4l2m2m_decoder_deps="v4l2_m2m hevc_v4l2_m2m" +hevc_v4l2m2m_encoder_deps="v4l2_m2m hevc_v4l2_m2m" mjpeg_cuvid_decoder_deps="cuda cuvid" mjpeg_vaapi_encoder_deps="VAEncPictureParameterBufferJPEG" mjpeg_vaapi_encoder_select="vaapi_encode jpegtables" mpeg1_cuvid_decoder_deps="cuda cuvid" mpeg1_vdpau_decoder_deps="vdpau" mpeg1_vdpau_decoder_select="mpeg1video_decoder" +mpeg1_v4l2m2m_decoder_deps="v4l2_m2m mpeg1_v4l2_m2m" mpeg2_crystalhd_decoder_select="crystalhd" mpeg2_cuvid_decoder_deps="cuda cuvid" mpeg2_mmal_decoder_deps="mmal" @@ -2810,6 +2820,7 @@ mpeg2_qsv_encoder_deps="libmfx" mpeg2_qsv_encoder_select="qsvenc" mpeg2_vaapi_encoder_deps="VAEncPictureParameterBufferMPEG2" mpeg2_vaapi_encoder_select="vaapi_encode" +mpeg2_v4l2m2m_decoder_deps="v4l2_m2m mpeg2_v4l2_m2m" mpeg4_crystalhd_decoder_select="crystalhd" mpeg4_cuvid_decoder_deps="cuda cuvid" mpeg4_mediacodec_decoder_deps="mediacodec" @@ -2817,6 +2828,8 @@ mpeg4_mmal_decoder_deps="mmal" mpeg4_omx_encoder_deps="omx" mpeg4_vdpau_decoder_deps="vdpau" mpeg4_vdpau_decoder_select="mpeg4_decoder" +mpeg4_v4l2m2m_decoder_deps="v4l2_m2m mpeg4_v4l2_m2m" +mpeg4_v4l2m2m_encoder_deps="v4l2_m2m mpeg4_v4l2_m2m" mpeg_vdpau_decoder_deps="vdpau" mpeg_vdpau_decoder_select="mpeg2video_decoder" msmpeg4_crystalhd_decoder_select="crystalhd" @@ -2827,16 +2840,20 @@ vc1_cuvid_decoder_deps="cuda cuvid" vc1_mmal_decoder_deps="mmal" vc1_vdpau_decoder_deps="vdpau" vc1_vdpau_decoder_select="vc1_decoder" +vc1_v4l2m2m_decoder_deps="v4l2_m2m vc1_v4l2_m2m" vp8_cuvid_decoder_deps="cuda cuvid" vp8_mediacodec_decoder_deps="mediacodec" vp8_qsv_decoder_deps="libmfx" vp8_qsv_decoder_select="qsvdec vp8_qsv_hwaccel vp8_parser" vp8_vaapi_encoder_deps="VAEncPictureParameterBufferVP8" vp8_vaapi_encoder_select="vaapi_encode" +vp8_v4l2m2m_decoder_deps="v4l2_m2m vp8_v4l2_m2m" +vp8_v4l2m2m_encoder_deps="v4l2_m2m vp8_v4l2_m2m" vp9_cuvid_decoder_deps="cuda cuvid" vp9_mediacodec_decoder_deps="mediacodec" vp9_vaapi_encoder_deps="VAEncPictureParameterBufferVP9" vp9_vaapi_encoder_select="vaapi_encode" +vp9_v4l2m2m_decoder_deps="v4l2_m2m vp9_v4l2_m2m" wmv3_crystalhd_decoder_select="crystalhd" wmv3_vdpau_decoder_select="vc1_vdpau_decoder" @@ -6109,9 +6126,20 @@ perl -v > /dev/null 2>&1 && enable perl || disable perl pod2man --help > /dev/null 2>&1 && enable pod2man || disable pod2man rsync --help 2> /dev/null | grep -q 'contimeout' && enable rsync_contimeout || disable rsync_contimeout +# check V4L2 codecs available in the API check_header linux/fb.h check_header linux/videodev2.h check_code cc linux/videodev2.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_safe struct_v4l2_frmivalenum_discrete +check_code cc linux/videodev2.h "int i = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_VIDEO_M2M | V4L2_BUF_FLAG_LAST;" || disable v4l2_m2m +check_code cc linux/videodev2.h "int i = V4L2_PIX_FMT_VC1_ANNEX_G;" && enable vc1_v4l2_m2m +check_code cc linux/videodev2.h "int i = V4L2_PIX_FMT_MPEG1;" && enable mpeg1_v4l2_m2m +check_code cc linux/videodev2.h "int i = V4L2_PIX_FMT_MPEG2;" && enable mpeg2_v4l2_m2m +check_code cc linux/videodev2.h "int i = V4L2_PIX_FMT_MPEG4;" && enable mpeg4_v4l2_m2m +check_code cc linux/videodev2.h "int i = V4L2_PIX_FMT_HEVC;" && enable hevc_v4l2_m2m +check_code cc linux/videodev2.h "int i = V4L2_PIX_FMT_H263;" && enable h263_v4l2_m2m +check_code cc linux/videodev2.h "int i = V4L2_PIX_FMT_H264;" && enable h264_v4l2_m2m +check_code cc linux/videodev2.h "int i = V4L2_PIX_FMT_VP8;" && enable vp8_v4l2_m2m +check_code cc linux/videodev2.h "int i = V4L2_PIX_FMT_VP9;" && enable vp9_v4l2_m2m check_header sys/videoio.h check_code cc sys/videoio.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_safe struct_v4l2_frmivalenum_discrete diff --git a/libavcodec/Makefile b/libavcodec/Makefile index fad56129a3888..fa0cb97a4dbe4 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -137,6 +137,7 @@ OBJS-$(CONFIG_VIDEODSP) += videodsp.o OBJS-$(CONFIG_VP3DSP) += vp3dsp.o OBJS-$(CONFIG_VP56DSP) += vp56dsp.o OBJS-$(CONFIG_VP8DSP) += vp8dsp.o +OBJS-$(CONFIG_V4L2_M2M) += v4l2_m2m.o v4l2_context.o v4l2_buffers.o v4l2_fmt.o OBJS-$(CONFIG_WMA_FREQS) += wma_freqs.o OBJS-$(CONFIG_WMV2DSP) += wmv2dsp.o @@ -323,6 +324,8 @@ OBJS-$(CONFIG_H263_DECODER) += h263dec.o h263.o ituh263dec.o \ intelh263dec.o h263data.o OBJS-$(CONFIG_H263_ENCODER) += mpeg4videoenc.o mpeg4video.o \ h263.o ituh263enc.o flvenc.o h263data.o +OBJS-$(CONFIG_H263_V4L2M2M_DECODER) += v4l2_m2m_dec.o +OBJS-$(CONFIG_H263_V4L2M2M_ENCODER) += v4l2_m2m_enc.o OBJS-$(CONFIG_H264_DECODER) += h264dec.o h264_cabac.o h264_cavlc.o \ h264_direct.o h264_loopfilter.o \ h264_mb.o h264_picture.o \ @@ -340,6 +343,8 @@ OBJS-$(CONFIG_H264_QSV_DECODER) += qsvdec_h2645.o OBJS-$(CONFIG_H264_QSV_ENCODER) += qsvenc_h264.o OBJS-$(CONFIG_H264_VAAPI_ENCODER) += vaapi_encode_h264.o vaapi_encode_h26x.o OBJS-$(CONFIG_H264_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o +OBJS-$(CONFIG_H264_V4L2M2M_DECODER) += v4l2_m2m_dec.o +OBJS-$(CONFIG_H264_V4L2M2M_ENCODER) += v4l2_m2m_enc.o OBJS-$(CONFIG_HAP_DECODER) += hapdec.o hap.o OBJS-$(CONFIG_HAP_ENCODER) += hapenc.o hap.o OBJS-$(CONFIG_HEVC_DECODER) += hevcdec.o hevc_mvs.o \ @@ -353,6 +358,8 @@ OBJS-$(CONFIG_HEVC_QSV_DECODER) += qsvdec_h2645.o OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc_ps_enc.o \ hevc_data.o OBJS-$(CONFIG_HEVC_VAAPI_ENCODER) += vaapi_encode_h265.o vaapi_encode_h26x.o +OBJS-$(CONFIG_HEVC_V4L2M2M_DECODER) += v4l2_m2m_dec.o +OBJS-$(CONFIG_HEVC_V4L2M2M_ENCODER) += v4l2_m2m_enc.o OBJS-$(CONFIG_HNM4_VIDEO_DECODER) += hnm4video.o OBJS-$(CONFIG_HQ_HQA_DECODER) += hq_hqa.o hq_hqadata.o hq_hqadsp.o \ canopus.o @@ -422,6 +429,7 @@ OBJS-$(CONFIG_MPC8_DECODER) += mpc8.o mpc.o OBJS-$(CONFIG_MPEGVIDEO_DECODER) += mpeg12dec.o mpeg12.o mpeg12data.o OBJS-$(CONFIG_MPEG1VIDEO_DECODER) += mpeg12dec.o mpeg12.o mpeg12data.o OBJS-$(CONFIG_MPEG1VIDEO_ENCODER) += mpeg12enc.o mpeg12.o +OBJS-$(CONFIG_MPEG1_V4L2M2M_DECODER) += v4l2_m2m_dec.o OBJS-$(CONFIG_MPEG2_MMAL_DECODER) += mmaldec.o OBJS-$(CONFIG_MPEG2_QSV_DECODER) += qsvdec_other.o OBJS-$(CONFIG_MPEG2_QSV_ENCODER) += qsvenc_mpeg2.o @@ -429,9 +437,12 @@ OBJS-$(CONFIG_MPEG2VIDEO_DECODER) += mpeg12dec.o mpeg12.o mpeg12data.o OBJS-$(CONFIG_MPEG2VIDEO_ENCODER) += mpeg12enc.o mpeg12.o OBJS-$(CONFIG_MPEG2_MEDIACODEC_DECODER) += mediacodecdec.o OBJS-$(CONFIG_MPEG2_VAAPI_ENCODER) += vaapi_encode_mpeg2.o +OBJS-$(CONFIG_MPEG2_V4L2M2M_DECODER) += v4l2_m2m_dec.o OBJS-$(CONFIG_MPEG4_DECODER) += xvididct.o OBJS-$(CONFIG_MPEG4_MEDIACODEC_DECODER) += mediacodecdec.o OBJS-$(CONFIG_MPEG4_OMX_ENCODER) += omx.o +OBJS-$(CONFIG_MPEG4_V4L2M2M_DECODER) += v4l2_m2m_dec.o +OBJS-$(CONFIG_MPEG4_V4L2M2M_ENCODER) += v4l2_m2m_enc.o OBJS-$(CONFIG_MPL2_DECODER) += mpl2dec.o ass.o OBJS-$(CONFIG_MSA1_DECODER) += mss3.o OBJS-$(CONFIG_MSCC_DECODER) += mscc.o @@ -605,6 +616,7 @@ OBJS-$(CONFIG_VC1_DECODER) += vc1dec.o vc1_block.o vc1_loopfilter.o OBJS-$(CONFIG_VC1_CUVID_DECODER) += cuvid.o OBJS-$(CONFIG_VC1_MMAL_DECODER) += mmaldec.o OBJS-$(CONFIG_VC1_QSV_DECODER) += qsvdec_other.o +OBJS-$(CONFIG_VC1_V4L2M2M_DECODER) += v4l2_m2m_dec.o OBJS-$(CONFIG_VC2_ENCODER) += vc2enc.o vc2enc_dwt.o diractab.o OBJS-$(CONFIG_VCR1_DECODER) += vcr1.o OBJS-$(CONFIG_VMDAUDIO_DECODER) += vmdaudio.o @@ -624,6 +636,8 @@ OBJS-$(CONFIG_VP8_CUVID_DECODER) += cuvid.o OBJS-$(CONFIG_VP8_MEDIACODEC_DECODER) += mediacodecdec.o OBJS-$(CONFIG_VP8_QSV_DECODER) += qsvdec_other.o OBJS-$(CONFIG_VP8_VAAPI_ENCODER) += vaapi_encode_vp8.o +OBJS-$(CONFIG_VP8_V4L2M2M_DECODER) += v4l2_m2m_dec.o +OBJS-$(CONFIG_VP8_V4L2M2M_ENCODER) += v4l2_m2m_enc.o OBJS-$(CONFIG_VP9_DECODER) += vp9.o vp9data.o vp9dsp.o vp9lpf.o vp9recon.o \ vp9block.o vp9prob.o vp9mvs.o vp56rac.o \ vp9dsp_8bpp.o vp9dsp_10bpp.o vp9dsp_12bpp.o @@ -631,6 +645,7 @@ OBJS-$(CONFIG_VP9_CUVID_DECODER) += cuvid.o OBJS-$(CONFIG_VP9_MEDIACODEC_DECODER) += mediacodecdec.o OBJS-$(CONFIG_VP9_VAAPI_ENCODER) += vaapi_encode_vp9.o OBJS-$(CONFIG_VPLAYER_DECODER) += textdec.o ass.o +OBJS-$(CONFIG_VP9_V4L2M2M_DECODER) += v4l2_m2m_dec.o OBJS-$(CONFIG_VQA_DECODER) += vqavideo.o OBJS-$(CONFIG_WAVPACK_DECODER) += wavpack.o OBJS-$(CONFIG_WAVPACK_ENCODER) += wavpackenc.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 625720578f6d3..db2db158f3443 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -208,8 +208,10 @@ static void register_all(void) REGISTER_ENCDEC (H263, h263); REGISTER_DECODER(H263I, h263i); REGISTER_ENCDEC (H263P, h263p); + REGISTER_ENCDEC (H263_V4L2M2M, h263_v4l2m2m); REGISTER_DECODER(H264, h264); REGISTER_DECODER(H264_CRYSTALHD, h264_crystalhd); + REGISTER_ENCDEC (H264_V4L2M2M, h264_v4l2m2m); REGISTER_DECODER(H264_MEDIACODEC, h264_mediacodec); REGISTER_DECODER(H264_MMAL, h264_mmal); REGISTER_DECODER(H264_QSV, h264_qsv); @@ -220,6 +222,7 @@ static void register_all(void) REGISTER_ENCDEC (HAP, hap); REGISTER_DECODER(HEVC, hevc); REGISTER_DECODER(HEVC_QSV, hevc_qsv); + REGISTER_ENCDEC (HEVC_V4L2M2M, hevc_v4l2m2m); REGISTER_DECODER(HNM4_VIDEO, hnm4_video); REGISTER_DECODER(HQ_HQA, hq_hqa); REGISTER_DECODER(HQX, hqx); @@ -254,6 +257,7 @@ static void register_all(void) REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video); REGISTER_ENCDEC (MPEG4, mpeg4); REGISTER_DECODER(MPEG4_CRYSTALHD, mpeg4_crystalhd); + REGISTER_ENCDEC (MPEG4_V4L2M2M, mpeg4_v4l2m2m); REGISTER_DECODER(MPEG4_MMAL, mpeg4_mmal); #if FF_API_VDPAU REGISTER_DECODER(MPEG4_VDPAU, mpeg4_vdpau); @@ -263,8 +267,10 @@ static void register_all(void) REGISTER_DECODER(MPEG_VDPAU, mpeg_vdpau); REGISTER_DECODER(MPEG1_VDPAU, mpeg1_vdpau); #endif + REGISTER_DECODER(MPEG1_V4L2M2M, mpeg1_v4l2m2m); REGISTER_DECODER(MPEG2_MMAL, mpeg2_mmal); REGISTER_DECODER(MPEG2_CRYSTALHD, mpeg2_crystalhd); + REGISTER_DECODER(MPEG2_V4L2M2M, mpeg2_v4l2m2m); REGISTER_DECODER(MPEG2_QSV, mpeg2_qsv); REGISTER_DECODER(MPEG2_MEDIACODEC, mpeg2_mediacodec); REGISTER_DECODER(MSA1, msa1); @@ -362,6 +368,7 @@ static void register_all(void) REGISTER_DECODER(VC1IMAGE, vc1image); REGISTER_DECODER(VC1_MMAL, vc1_mmal); REGISTER_DECODER(VC1_QSV, vc1_qsv); + REGISTER_DECODER(VC1_V4L2M2M, vc1_v4l2m2m); REGISTER_ENCODER(VC2, vc2); REGISTER_DECODER(VCR1, vcr1); REGISTER_DECODER(VMDVIDEO, vmdvideo); @@ -373,7 +380,9 @@ static void register_all(void) REGISTER_DECODER(VP6F, vp6f); REGISTER_DECODER(VP7, vp7); REGISTER_DECODER(VP8, vp8); + REGISTER_ENCDEC (VP8_V4L2M2M, vp8_v4l2m2m); REGISTER_DECODER(VP9, vp9); + REGISTER_DECODER(VP9_V4L2M2M, vp9_v4l2m2m); REGISTER_DECODER(VQA, vqa); REGISTER_DECODER(BITPACKED, bitpacked); REGISTER_DECODER(WEBP, webp); diff --git a/libavcodec/v4l2_buffers.c b/libavcodec/v4l2_buffers.c new file mode 100644 index 0000000000000..ef7d0400322b9 --- /dev/null +++ b/libavcodec/v4l2_buffers.c @@ -0,0 +1,453 @@ +/* + * V4L2 buffer helper functions. + * + * Copyright (C) 2017 Alexis Ballier + * Copyright (C) 2017 Jorge Ramirez + * + * 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 +#include +#include +#include +#include +#include +#include "libavcodec/avcodec.h" +#include "libavcodec/internal.h" +#include "v4l2_context.h" +#include "v4l2_buffers.h" +#include "v4l2_m2m.h" + +#define USEC_PER_SEC 1000000 + +static inline V4L2m2mContext *buf_to_m2mctx(V4L2Buffer *buf) +{ + return V4L2_TYPE_IS_OUTPUT(buf->context->type) ? + container_of(buf->context, V4L2m2mContext, output) : + container_of(buf->context, V4L2m2mContext, capture); +} + +static inline AVCodecContext *logger(V4L2Buffer *buf) +{ + return buf_to_m2mctx(buf)->avctx; +} + +static inline void v4l2_set_pts(V4L2Buffer *out, int64_t pts) +{ + V4L2m2mContext *s = buf_to_m2mctx(out); + AVRational v4l2_timebase = { 1, USEC_PER_SEC }; + int64_t v4l2_pts; + + if (pts == AV_NOPTS_VALUE) + pts = 0; + + /* convert pts to v4l2 timebase */ + v4l2_pts = av_rescale_q(pts, s->avctx->time_base, v4l2_timebase); + out->buf.timestamp.tv_usec = v4l2_pts % USEC_PER_SEC; + out->buf.timestamp.tv_sec = v4l2_pts / USEC_PER_SEC; +} + +static inline uint64_t v4l2_get_pts(V4L2Buffer *avbuf) +{ + V4L2m2mContext *s = buf_to_m2mctx(avbuf); + AVRational v4l2_timebase = { 1, USEC_PER_SEC }; + int64_t v4l2_pts; + + /* convert pts back to encoder timebase */ + v4l2_pts = avbuf->buf.timestamp.tv_sec * USEC_PER_SEC + avbuf->buf.timestamp.tv_usec; + + return av_rescale_q(v4l2_pts, v4l2_timebase, s->avctx->time_base); +} + +static enum AVColorPrimaries v4l2_get_color_primaries(V4L2Buffer *buf) +{ + enum v4l2_ycbcr_encoding ycbcr; + enum v4l2_colorspace cs; + + cs = V4L2_TYPE_IS_MULTIPLANAR(buf->buf.type) ? + buf->context->format.fmt.pix_mp.colorspace : + buf->context->format.fmt.pix.colorspace; + + ycbcr = V4L2_TYPE_IS_MULTIPLANAR(buf->buf.type) ? + buf->context->format.fmt.pix_mp.ycbcr_enc: + buf->context->format.fmt.pix.ycbcr_enc; + + switch(ycbcr) { + case V4L2_YCBCR_ENC_XV709: + case V4L2_YCBCR_ENC_709: return AVCOL_PRI_BT709; + case V4L2_YCBCR_ENC_XV601: + case V4L2_YCBCR_ENC_601:return AVCOL_PRI_BT470M; + default: + break; + } + + switch(cs) { + case V4L2_COLORSPACE_470_SYSTEM_BG: return AVCOL_PRI_BT470BG; + case V4L2_COLORSPACE_SMPTE170M: return AVCOL_PRI_SMPTE170M; + case V4L2_COLORSPACE_SMPTE240M: return AVCOL_PRI_SMPTE240M; + case V4L2_COLORSPACE_BT2020: return AVCOL_PRI_BT2020; + default: + break; + } + + return AVCOL_PRI_UNSPECIFIED; +} + +static enum AVColorRange v4l2_get_color_range(V4L2Buffer *buf) +{ + enum v4l2_quantization qt; + + qt = V4L2_TYPE_IS_MULTIPLANAR(buf->buf.type) ? + buf->context->format.fmt.pix_mp.quantization : + buf->context->format.fmt.pix.quantization; + + switch (qt) { + case V4L2_QUANTIZATION_LIM_RANGE: return AVCOL_RANGE_MPEG; + case V4L2_QUANTIZATION_FULL_RANGE: return AVCOL_RANGE_JPEG; + default: + break; + } + + return AVCOL_RANGE_UNSPECIFIED; +} + +static enum AVColorSpace v4l2_get_color_space(V4L2Buffer *buf) +{ + enum v4l2_ycbcr_encoding ycbcr; + enum v4l2_colorspace cs; + + cs = V4L2_TYPE_IS_MULTIPLANAR(buf->buf.type) ? + buf->context->format.fmt.pix_mp.colorspace : + buf->context->format.fmt.pix.colorspace; + + ycbcr = V4L2_TYPE_IS_MULTIPLANAR(buf->buf.type) ? + buf->context->format.fmt.pix_mp.ycbcr_enc: + buf->context->format.fmt.pix.ycbcr_enc; + + switch(cs) { + case V4L2_COLORSPACE_SRGB: return AVCOL_SPC_RGB; + case V4L2_COLORSPACE_REC709: return AVCOL_SPC_BT709; + case V4L2_COLORSPACE_470_SYSTEM_M: return AVCOL_SPC_FCC; + case V4L2_COLORSPACE_470_SYSTEM_BG: return AVCOL_SPC_BT470BG; + case V4L2_COLORSPACE_SMPTE170M: return AVCOL_SPC_SMPTE170M; + case V4L2_COLORSPACE_SMPTE240M: return AVCOL_SPC_SMPTE240M; + case V4L2_COLORSPACE_BT2020: + if (ycbcr == V4L2_YCBCR_ENC_BT2020_CONST_LUM) + return AVCOL_SPC_BT2020_CL; + else + return AVCOL_SPC_BT2020_NCL; + default: + break; + } + + return AVCOL_SPC_UNSPECIFIED; +} + +static enum AVColorTransferCharacteristic v4l2_get_color_trc(V4L2Buffer *buf) +{ + enum v4l2_ycbcr_encoding ycbcr; + enum v4l2_xfer_func xfer; + enum v4l2_colorspace cs; + + cs = V4L2_TYPE_IS_MULTIPLANAR(buf->buf.type) ? + buf->context->format.fmt.pix_mp.colorspace : + buf->context->format.fmt.pix.colorspace; + + ycbcr = V4L2_TYPE_IS_MULTIPLANAR(buf->buf.type) ? + buf->context->format.fmt.pix_mp.ycbcr_enc: + buf->context->format.fmt.pix.ycbcr_enc; + + xfer = V4L2_TYPE_IS_MULTIPLANAR(buf->buf.type) ? + buf->context->format.fmt.pix_mp.xfer_func: + buf->context->format.fmt.pix.xfer_func; + + switch (xfer) { + case V4L2_XFER_FUNC_709: return AVCOL_TRC_BT709; + case V4L2_XFER_FUNC_SRGB: return AVCOL_TRC_IEC61966_2_1; + default: + break; + } + + switch (cs) { + case V4L2_COLORSPACE_470_SYSTEM_M: return AVCOL_TRC_GAMMA22; + case V4L2_COLORSPACE_470_SYSTEM_BG: return AVCOL_TRC_GAMMA28; + case V4L2_COLORSPACE_SMPTE170M: return AVCOL_TRC_SMPTE170M; + case V4L2_COLORSPACE_SMPTE240M: return AVCOL_TRC_SMPTE240M; + default: + break; + } + + switch (ycbcr) { + case V4L2_YCBCR_ENC_XV709: + case V4L2_YCBCR_ENC_XV601: return AVCOL_TRC_BT1361_ECG; + default: + break; + } + + return AVCOL_TRC_UNSPECIFIED; +} + +static void v4l2_free_buffer(void *opaque, uint8_t *unused) +{ + V4L2Buffer* avbuf = opaque; + V4L2m2mContext *s = buf_to_m2mctx(avbuf); + + atomic_fetch_sub_explicit(&s->refcount, 1, memory_order_acq_rel); + if (s->reinit) { + if (!atomic_load(&s->refcount)) + sem_post(&s->refsync); + return; + } + + if (avbuf->context->streamon) { + ff_v4l2_buffer_enqueue(avbuf); + return; + } + + if (!atomic_load(&s->refcount)) + ff_v4l2_m2m_codec_end(s->avctx); +} + +static int v4l2_buf_to_bufref(V4L2Buffer *in, int plane, AVBufferRef **buf) +{ + V4L2m2mContext *s = buf_to_m2mctx(in); + + if (plane >= in->num_planes) + return AVERROR(EINVAL); + + /* even though most encoders return 0 in data_offset encoding vp8 does require this value */ + *buf = av_buffer_create((char *)in->plane_info[plane].mm_addr + in->planes[plane].data_offset, + in->plane_info[plane].length, v4l2_free_buffer, in, 0); + if (!*buf) + return AVERROR(ENOMEM); + + in->status = V4L2BUF_RET_USER; + atomic_fetch_add_explicit(&s->refcount, 1, memory_order_relaxed); + + return 0; +} + +static int v4l2_bufref_to_buf(V4L2Buffer *out, int plane, const uint8_t* data, int size, AVBufferRef* bref) +{ + if (plane >= out->num_planes) + return AVERROR(EINVAL); + + memcpy(out->plane_info[plane].mm_addr, data, FFMIN(size, out->plane_info[plane].length)); + + out->planes[plane].bytesused = FFMIN(size, out->plane_info[plane].length); + out->planes[plane].length = out->plane_info[plane].length; + + return 0; +} + +/****************************************************************************** + * + * V4L2uffer interface + * + ******************************************************************************/ + +int ff_v4l2_buffer_avframe_to_buf(const AVFrame *frame, V4L2Buffer* out) +{ + int i, ret; + + for(i = 0; i < out->num_planes; i++) { + ret = v4l2_bufref_to_buf(out, i, frame->buf[i]->data, frame->buf[i]->size, frame->buf[i]); + if (ret) + return ret; + } + + v4l2_set_pts(out, frame->pts); + + return 0; +} + +int ff_v4l2_buffer_buf_to_avframe(AVFrame *frame, V4L2Buffer *avbuf) +{ + V4L2m2mContext *s = buf_to_m2mctx(avbuf); + int i, ret; + + av_frame_unref(frame); + + /* 1. get references to the actual data */ + for (i = 0; i < avbuf->num_planes; i++) { + ret = v4l2_buf_to_bufref(avbuf, i, &frame->buf[i]); + if (ret) + return ret; + + frame->linesize[i] = avbuf->plane_info[i].bytesperline; + frame->data[i] = frame->buf[i]->data; + } + + /* 1.1 fixup special cases */ + switch (avbuf->context->av_pix_fmt) { + case AV_PIX_FMT_NV12: + if (avbuf->num_planes > 1) + break; + frame->linesize[1] = avbuf->plane_info[0].bytesperline; + frame->data[1] = frame->buf[0]->data + avbuf->plane_info[0].bytesperline * avbuf->context->format.fmt.pix_mp.height; + break; + default: + break; + } + + /* 2. get frame information */ + frame->key_frame = !!(avbuf->buf.flags & V4L2_BUF_FLAG_KEYFRAME); + frame->format = avbuf->context->av_pix_fmt; + frame->color_primaries = v4l2_get_color_primaries(avbuf); + frame->colorspace = v4l2_get_color_space(avbuf); + frame->color_range = v4l2_get_color_range(avbuf); + frame->color_trc = v4l2_get_color_trc(avbuf); + frame->pts = v4l2_get_pts(avbuf); + + /* these two values are updated also during re-init in v4l2_process_driver_event */ + frame->height = s->output.height; + frame->width = s->output.width; + + /* 3. report errors upstream */ + if (avbuf->buf.flags & V4L2_BUF_FLAG_ERROR) { + av_log(logger(avbuf), AV_LOG_ERROR, "%s: driver decode error\n", avbuf->context->name); + frame->decode_error_flags |= FF_DECODE_ERROR_INVALID_BITSTREAM; + } + + return 0; +} + +int ff_v4l2_buffer_buf_to_avpkt(AVPacket *pkt, V4L2Buffer *avbuf) +{ + int ret; + + av_packet_unref(pkt); + ret = v4l2_buf_to_bufref(avbuf, 0, &pkt->buf); + if (ret) + return ret; + + pkt->size = V4L2_TYPE_IS_MULTIPLANAR(avbuf->buf.type) ? avbuf->buf.m.planes[0].bytesused : avbuf->buf.bytesused; + pkt->data = pkt->buf->data; + + if (avbuf->buf.flags & V4L2_BUF_FLAG_KEYFRAME) + pkt->flags |= AV_PKT_FLAG_KEY; + + if (avbuf->buf.flags & V4L2_BUF_FLAG_ERROR) { + av_log(logger(avbuf), AV_LOG_ERROR, "%s driver encode error\n", avbuf->context->name); + pkt->flags |= AV_PKT_FLAG_CORRUPT; + } + + pkt->dts = pkt->pts = v4l2_get_pts(avbuf); + + return 0; +} + +int ff_v4l2_buffer_avpkt_to_buf(const AVPacket *pkt, V4L2Buffer *out) +{ + int ret; + + ret = v4l2_bufref_to_buf(out, 0, pkt->data, pkt->size, pkt->buf); + if (ret) + return ret; + + v4l2_set_pts(out, pkt->pts); + + if (pkt->flags & AV_PKT_FLAG_KEY) + out->flags = V4L2_BUF_FLAG_KEYFRAME; + + return 0; +} + +int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index) +{ + V4L2Context *ctx = avbuf->context; + int ret, i; + + avbuf->buf.memory = V4L2_MEMORY_MMAP; + avbuf->buf.type = ctx->type; + avbuf->buf.index = index; + + if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) { + avbuf->buf.length = VIDEO_MAX_PLANES; + avbuf->buf.m.planes = avbuf->planes; + } + + ret = ioctl(buf_to_m2mctx(avbuf)->fd, VIDIOC_QUERYBUF, &avbuf->buf); + if (ret < 0) + return AVERROR(errno); + + if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) { + avbuf->num_planes = 0; + for (;;) { + /* in MP, the V4L2 API states that buf.length means num_planes */ + if (avbuf->num_planes >= avbuf->buf.length) + break; + if (avbuf->buf.m.planes[avbuf->num_planes].length) + avbuf->num_planes++; + } + } else + avbuf->num_planes = 1; + + for (i = 0; i < avbuf->num_planes; i++) { + + avbuf->plane_info[i].bytesperline = V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ? + ctx->format.fmt.pix_mp.plane_fmt[i].bytesperline : + ctx->format.fmt.pix.bytesperline; + + if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) { + avbuf->plane_info[i].length = avbuf->buf.m.planes[i].length; + avbuf->plane_info[i].mm_addr = mmap(NULL, avbuf->buf.m.planes[i].length, + PROT_READ | PROT_WRITE, MAP_SHARED, + buf_to_m2mctx(avbuf)->fd, avbuf->buf.m.planes[i].m.mem_offset); + } else { + avbuf->plane_info[i].length = avbuf->buf.length; + avbuf->plane_info[i].mm_addr = mmap(NULL, avbuf->buf.length, + PROT_READ | PROT_WRITE, MAP_SHARED, + buf_to_m2mctx(avbuf)->fd, avbuf->buf.m.offset); + } + + if (avbuf->plane_info[i].mm_addr == MAP_FAILED) + return AVERROR(ENOMEM); + } + + avbuf->status = V4L2BUF_AVAILABLE; + + if (V4L2_TYPE_IS_OUTPUT(ctx->type)) + return 0; + + if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) { + avbuf->buf.m.planes = avbuf->planes; + avbuf->buf.length = avbuf->num_planes; + + } else { + avbuf->buf.bytesused = avbuf->planes[0].bytesused; + avbuf->buf.length = avbuf->planes[0].length; + } + + return ff_v4l2_buffer_enqueue(avbuf); +} + +int ff_v4l2_buffer_enqueue(V4L2Buffer* avbuf) +{ + int ret; + + avbuf->buf.flags = avbuf->flags; + + ret = ioctl(buf_to_m2mctx(avbuf)->fd, VIDIOC_QBUF, &avbuf->buf); + if (ret < 0) + return AVERROR(errno); + + avbuf->status = V4L2BUF_IN_DRIVER; + + return 0; +} diff --git a/libavcodec/v4l2_buffers.h b/libavcodec/v4l2_buffers.h new file mode 100644 index 0000000000000..8901a0952f30d --- /dev/null +++ b/libavcodec/v4l2_buffers.h @@ -0,0 +1,121 @@ +/* + * V4L2 buffer helper functions. + * + * Copyright (C) 2017 Alexis Ballier + * Copyright (C) 2017 Jorge Ramirez + * + * 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 + */ + +#ifndef AVCODEC_V4L2_BUFFERS_H +#define AVCODEC_V4L2_BUFFERS_H + +enum V4L2Buffer_status { + V4L2BUF_AVAILABLE, + V4L2BUF_IN_DRIVER, + V4L2BUF_RET_USER, +}; + +/** + * V4L2Buffer (wrapper for v4l2_buffer management) + */ +typedef struct V4L2Buffer { + /* each buffer needs to have a reference to its context */ + struct V4L2Context *context; + + /* keep track of the mmap address and mmap length */ + struct V4L2Plane_info { + int bytesperline; + void * mm_addr; + size_t length; + } plane_info[VIDEO_MAX_PLANES]; + + int num_planes; + + /* the v4l2_buffer buf.m.planes pointer uses the planes[] mem */ + struct v4l2_buffer buf; + struct v4l2_plane planes[VIDEO_MAX_PLANES]; + + int flags; + enum V4L2Buffer_status status; + +} V4L2Buffer; + +/** + * Extracts the data from a V4L2Buffer to an AVFrame + * + * @param[in] frame The AVFRame to push the information to + * @param[in] buf The V4L2Buffer to get the information from + * + * @returns 0 in case of success, EINVAL if the number of planes is incorrect, + * ENOMEM if the AVBufferRef cant be created. + */ +int ff_v4l2_buffer_buf_to_avframe(AVFrame *frame, V4L2Buffer *buf); + +/** + * Extracts the data from a V4L2Buffer to an AVPacket + * + * @param[in] pkt The AVPacket to push the information to + * @param[in] buf The V4L2Buffer to get the information from + * + * @returns 0 in case of success, EINVAL if the number of planes is incorrect, + * ENOMEM if the AVBufferRef cant be created. + * + */ +int ff_v4l2_buffer_buf_to_avpkt(AVPacket *pkt, V4L2Buffer *buf); + +/** + * Extracts the data from an AVPacket to a V4L2Buffer + * + * @param[in] frame AVPacket to get the data from + * @param[in] avbuf V4L2Bfuffer to push the information to + * + * @returns 0 in case of success, negative otherwise + */ +int ff_v4l2_buffer_avpkt_to_buf(const AVPacket *pkt, V4L2Buffer *out); + +/** + * Extracts the data from an AVFrame to a V4L2Buffer + * + * @param[in] frame AVFrame to get the data from + * @param[in] avbuf V4L2Bfuffer to push the information to + * + * @returns 0 in case of success, negative otherwise + */ +int ff_v4l2_buffer_avframe_to_buf(const AVFrame *frame, V4L2Buffer* out); + +/** + * Initializes a V4L2Buffer + * + * @param[in] avbuf V4L2Bfuffer to initialize + * @param[in] index v4l2 buffer id + * + * @returns 0 in case of success, negative otherwise + */ +int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index); + +/** + * Enqueues a V4L2Buffer + * + * @param[in] avbuf V4L2Bfuffer to push to the driver + * + * @returns 0 in case of success, negative otherwise + */ +int ff_v4l2_buffer_enqueue(V4L2Buffer* avbuf); + + +#endif // AVCODEC_V4L2_BUFFERS_H diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c new file mode 100644 index 0000000000000..d675c55f2bbc9 --- /dev/null +++ b/libavcodec/v4l2_context.c @@ -0,0 +1,667 @@ +/* + * V4L2 context helper functions. + * + * Copyright (C) 2017 Alexis Ballier + * Copyright (C) 2017 Jorge Ramirez + * + * 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 +#include +#include +#include +#include +#include +#include "libavcodec/avcodec.h" +#include "libavcodec/internal.h" +#include "v4l2_buffers.h" +#include "v4l2_fmt.h" +#include "v4l2_m2m.h" + +struct v4l2_format_update { + uint32_t v4l2_fmt; + int update_v4l2; + + enum AVPixelFormat av_fmt; + int update_avfmt; +}; + +static inline V4L2m2mContext *ctx_to_m2mctx(V4L2Context *ctx) +{ + return V4L2_TYPE_IS_OUTPUT(ctx->type) ? + container_of(ctx, V4L2m2mContext, output) : + container_of(ctx, V4L2m2mContext, capture); +} + +static inline AVCodecContext *logger(V4L2Context *ctx) +{ + return ctx_to_m2mctx(ctx)->avctx; +} + +static inline unsigned int v4l2_get_width(struct v4l2_format *fmt) +{ + return V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? fmt->fmt.pix_mp.width : fmt->fmt.pix.width; +} + +static inline unsigned int v4l2_get_height(struct v4l2_format *fmt) +{ + return V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? fmt->fmt.pix_mp.height : fmt->fmt.pix.height; +} + +static inline unsigned int v4l2_resolution_changed(V4L2Context *ctx, struct v4l2_format *fmt2) +{ + struct v4l2_format *fmt1 = &ctx->format; + int ret = V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ? + fmt1->fmt.pix_mp.width != fmt2->fmt.pix_mp.width || + fmt1->fmt.pix_mp.height != fmt2->fmt.pix_mp.height + : + fmt1->fmt.pix.width != fmt2->fmt.pix.width || + fmt1->fmt.pix.height != fmt2->fmt.pix.height; + + if (ret) + av_log(logger(ctx), AV_LOG_DEBUG, "%s changed (%dx%d) -> (%dx%d)\n", + ctx->name, + v4l2_get_width(fmt1), v4l2_get_height(fmt1), + v4l2_get_width(fmt2), v4l2_get_height(fmt2)); + + return ret; +} + +static inline int v4l2_type_supported(V4L2Context *ctx) +{ + return ctx->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || + ctx->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE || + ctx->type == V4L2_BUF_TYPE_VIDEO_CAPTURE || + ctx->type == V4L2_BUF_TYPE_VIDEO_OUTPUT; +} + +static inline void v4l2_save_to_context(V4L2Context* ctx, struct v4l2_format_update *fmt) +{ + ctx->format.type = ctx->type; + + if (fmt->update_avfmt) + ctx->av_pix_fmt = fmt->av_fmt; + + if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) { + /* update the sizes to handle the reconfiguration of the capture stream at runtime */ + ctx->format.fmt.pix_mp.height = ctx->height; + ctx->format.fmt.pix_mp.width = ctx->width; + if (fmt->update_v4l2) + ctx->format.fmt.pix_mp.pixelformat = fmt->v4l2_fmt; + } else { + ctx->format.fmt.pix.height = ctx->height; + ctx->format.fmt.pix.width = ctx->width; + if (fmt->update_v4l2) + ctx->format.fmt.pix.pixelformat = fmt->v4l2_fmt; + } +} + +/** + * returns 1 if reinit was succesful, negative if it failed + * returns 0 if reinit was not executed + */ +static int v4l2_handle_event(V4L2Context *ctx) +{ + V4L2m2mContext *s = ctx_to_m2mctx(ctx); + struct v4l2_format cap_fmt = s->capture.format; + struct v4l2_format out_fmt = s->output.format; + struct v4l2_event evt = { 0 }; + int full_reinit, reinit, ret; + + ret = ioctl(s->fd, VIDIOC_DQEVENT, &evt); + if (ret < 0) { + av_log(logger(ctx), AV_LOG_ERROR, "%s VIDIOC_DQEVENT\n", ctx->name); + return 0; + } + + if (evt.type != V4L2_EVENT_SOURCE_CHANGE) + return 0; + + ret = ioctl(s->fd, VIDIOC_G_FMT, &out_fmt); + if (ret) { + av_log(logger(ctx), AV_LOG_ERROR, "%s VIDIOC_G_FMT\n", s->output.name); + return 0; + } + + ret = ioctl(s->fd, VIDIOC_G_FMT, &cap_fmt); + if (ret) { + av_log(logger(ctx), AV_LOG_ERROR, "%s VIDIOC_G_FMT\n", s->capture.name); + return 0; + } + + full_reinit = v4l2_resolution_changed(&s->output, &out_fmt); + if (full_reinit) { + s->output.height = v4l2_get_height(&out_fmt); + s->output.width = v4l2_get_width(&out_fmt); + } + + reinit = v4l2_resolution_changed(&s->capture, &cap_fmt); + if (reinit) { + s->capture.height = v4l2_get_height(&cap_fmt); + s->capture.width = v4l2_get_width(&cap_fmt); + } + + if (full_reinit || reinit) + s->reinit = 1; + + if (full_reinit) { + ret = ff_v4l2_m2m_codec_full_reinit(s); + if (ret) { + av_log(logger(ctx), AV_LOG_ERROR, "v4l2_m2m_codec_full_reinit\n"); + return -EINVAL; + } + goto reinit_run; + } + + if (reinit) { + ret = ff_set_dimensions(s->avctx, s->capture.width, s->capture.height); + if (ret < 0) + av_log(logger(ctx), AV_LOG_WARNING, "update avcodec height and width\n"); + + ret = ff_v4l2_m2m_codec_reinit(s); + if (ret) { + av_log(logger(ctx), AV_LOG_ERROR, "v4l2_m2m_codec_reinit\n"); + return -EINVAL; + } + goto reinit_run; + } + + /* dummy event received */ + return 0; + + /* reinit executed */ +reinit_run: + return 1; +} + +static int v4l2_stop_decode(V4L2Context *ctx) +{ + struct v4l2_decoder_cmd cmd = { + .cmd = V4L2_DEC_CMD_STOP, + }; + int ret; + + ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_DECODER_CMD, &cmd); + if (ret) { + /* DECODER_CMD is optional */ + if (errno == ENOTTY) + return ff_v4l2_context_set_status(ctx, VIDIOC_STREAMOFF); + } + + return 0; +} + +static int v4l2_stop_encode(V4L2Context *ctx) +{ + struct v4l2_encoder_cmd cmd = { + .cmd = V4L2_ENC_CMD_STOP, + }; + int ret; + + ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_ENCODER_CMD, &cmd); + if (ret) { + /* ENCODER_CMD is optional */ + if (errno == ENOTTY) + return ff_v4l2_context_set_status(ctx, VIDIOC_STREAMOFF); + } + + return 0; +} + +static V4L2Buffer* v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout) +{ + struct v4l2_plane planes[VIDEO_MAX_PLANES]; + struct v4l2_buffer buf = { 0 }; + V4L2Buffer* avbuf = NULL; + struct pollfd pfd = { + .events = POLLIN | POLLRDNORM | POLLPRI | POLLOUT | POLLWRNORM, /* default blocking capture */ + .fd = ctx_to_m2mctx(ctx)->fd, + }; + int ret; + + if (V4L2_TYPE_IS_OUTPUT(ctx->type)) + pfd.events = POLLOUT | POLLWRNORM; + + for (;;) { + ret = poll(&pfd, 1, timeout); + if (ret > 0) + break; + if (errno == EINTR) + continue; + + /* timeout is being used to indicate last valid bufer when draining */ + if (ctx_to_m2mctx(ctx)->draining) + ctx->done = 1; + + return NULL; + } + + /* 0. handle errors */ + if (pfd.revents & POLLERR) { + av_log(logger(ctx), AV_LOG_WARNING, "%s POLLERR\n", ctx->name); + return NULL; + } + + /* 1. handle resolution changes */ + if (pfd.revents & POLLPRI) { + ret = v4l2_handle_event(ctx); + if (ret < 0) { + /* if re-init failed, abort */ + ctx->done = EINVAL; + return NULL; + } + if (ret) { + /* if re-init was successfull drop the buffer (if there was one) + * since we had to reconfigure capture (unmap all buffers) + */ + return NULL; + } + } + + /* 2. dequeue the buffer */ + if (pfd.revents & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM)) { + + if (!V4L2_TYPE_IS_OUTPUT(ctx->type)) { + /* there is a capture buffer ready */ + if (pfd.revents & (POLLIN | POLLRDNORM)) + goto dequeue; + + /* the driver is ready to accept more input; instead of waiting for the capture + * buffer to complete we return NULL so input can proceed (we are single threaded) + */ + if (pfd.revents & (POLLOUT | POLLWRNORM)) + return NULL; + } + +dequeue: + memset(&buf, 0, sizeof(buf)); + buf.memory = V4L2_MEMORY_MMAP; + buf.type = ctx->type; + if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) { + memset(planes, 0, sizeof(planes)); + buf.length = VIDEO_MAX_PLANES; + buf.m.planes = planes; + } + + ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_DQBUF, &buf); + if (ret) { + if (errno != EAGAIN) { + ctx->done = errno; + if (errno != EPIPE) + av_log(logger(ctx), AV_LOG_DEBUG, "%s VIDIOC_DQBUF, errno (%s)\n", + ctx->name, av_err2str(AVERROR(errno))); + } + } else { + avbuf = &ctx->buffers[buf.index]; + avbuf->status = V4L2BUF_AVAILABLE; + avbuf->buf = buf; + if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) { + memcpy(avbuf->planes, planes, sizeof(planes)); + avbuf->buf.m.planes = avbuf->planes; + } + } + } + + return avbuf; +} + +static V4L2Buffer* v4l2_getfree_v4l2buf(V4L2Context *ctx) +{ + int timeout = 0; /* return when no more buffers to dequeue */ + int i; + + /* get back as many output buffers as possible */ + if (V4L2_TYPE_IS_OUTPUT(ctx->type)) { + do { + } while (v4l2_dequeue_v4l2buf(ctx, timeout)); + } + + for (i = 0; i < ctx->num_buffers; i++) { + if (ctx->buffers[i].status == V4L2BUF_AVAILABLE) + return &ctx->buffers[i]; + } + + return NULL; +} + +static int v4l2_release_buffers(V4L2Context* ctx) +{ + struct v4l2_requestbuffers req = { + .memory = V4L2_MEMORY_MMAP, + .type = ctx->type, + .count = 0, /* 0 -> unmaps buffers from the driver */ + }; + int i, j; + + for (i = 0; i < ctx->num_buffers; i++) { + V4L2Buffer *buffer = &ctx->buffers[i]; + + for (j = 0; j < buffer->num_planes; j++) { + struct V4L2Plane_info *p = &buffer->plane_info[j]; + if (p->mm_addr && p->length) + if (munmap(p->mm_addr, p->length) < 0) + av_log(logger(ctx), AV_LOG_ERROR, "%s unmap plane (%s))\n", ctx->name, av_err2str(AVERROR(errno))); + } + } + + return ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_REQBUFS, &req); +} + +static inline int v4l2_try_raw_format(V4L2Context* ctx, enum AVPixelFormat pixfmt) +{ + struct v4l2_format *fmt = &ctx->format; + uint32_t v4l2_fmt; + int ret; + + v4l2_fmt = ff_v4l2_format_avfmt_to_v4l2(pixfmt); + if (!v4l2_fmt) + return AVERROR(EINVAL); + + if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) + fmt->fmt.pix_mp.pixelformat = v4l2_fmt; + else + fmt->fmt.pix.pixelformat = v4l2_fmt; + + fmt->type = ctx->type; + + ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_TRY_FMT, fmt); + if (ret) + return AVERROR(EINVAL); + + return 0; +} + +static int v4l2_get_raw_format(V4L2Context* ctx, enum AVPixelFormat *p) +{ + enum AVPixelFormat pixfmt = ctx->av_pix_fmt; + struct v4l2_fmtdesc fdesc; + int ret; + + memset(&fdesc, 0, sizeof(fdesc)); + fdesc.type = ctx->type; + + if (pixfmt != AV_PIX_FMT_NONE) { + ret = v4l2_try_raw_format(ctx, pixfmt); + if (ret) + pixfmt = AV_PIX_FMT_NONE; + else + return 0; + } + + for (;;) { + ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_ENUM_FMT, &fdesc); + if (ret) + return AVERROR(EINVAL); + + pixfmt = ff_v4l2_format_v4l2_to_avfmt(fdesc.pixelformat, AV_CODEC_ID_RAWVIDEO); + ret = v4l2_try_raw_format(ctx, pixfmt); + if (ret){ + fdesc.index++; + continue; + } + + *p = pixfmt; + + return 0; + } + + return AVERROR(EINVAL); +} + +static int v4l2_get_coded_format(V4L2Context* ctx, uint32_t *p) +{ + struct v4l2_fmtdesc fdesc; + uint32_t v4l2_fmt; + int ret; + + /* translate to a valid v4l2 format */ + v4l2_fmt = ff_v4l2_format_avcodec_to_v4l2(ctx->av_codec_id); + if (!v4l2_fmt) + return AVERROR(EINVAL); + + /* check if the driver supports this format */ + memset(&fdesc, 0, sizeof(fdesc)); + fdesc.type = ctx->type; + + for (;;) { + ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_ENUM_FMT, &fdesc); + if (ret) + return AVERROR(EINVAL); + + if (fdesc.pixelformat == v4l2_fmt) + break; + + fdesc.index++; + } + + *p = v4l2_fmt; + + return 0; +} + + /***************************************************************************** + * + * V4L2 Context Interface + * + *****************************************************************************/ + +int ff_v4l2_context_set_status(V4L2Context* ctx, int cmd) +{ + int type = ctx->type; + int ret; + + ret = ioctl(ctx_to_m2mctx(ctx)->fd, cmd, &type); + if (ret < 0) + return AVERROR(errno); + + ctx->streamon = (cmd == VIDIOC_STREAMON); + + return 0; +} + +int ff_v4l2_context_enqueue_frame(V4L2Context* ctx, const AVFrame* frame) +{ + V4L2m2mContext *s = ctx_to_m2mctx(ctx); + V4L2Buffer* avbuf; + int ret; + + if (!frame) { + ret = v4l2_stop_encode(ctx); + if (ret) + av_log(logger(ctx), AV_LOG_ERROR, "%s stop_encode\n", ctx->name); + s->draining= 1; + return 0; + } + + avbuf = v4l2_getfree_v4l2buf(ctx); + if (!avbuf) + return AVERROR(ENOMEM); + + ret = ff_v4l2_buffer_avframe_to_buf(frame, avbuf); + if (ret) + return ret; + + return ff_v4l2_buffer_enqueue(avbuf); +} + +int ff_v4l2_context_enqueue_packet(V4L2Context* ctx, const AVPacket* pkt) +{ + V4L2m2mContext *s = ctx_to_m2mctx(ctx); + V4L2Buffer* avbuf; + int ret; + + if (!pkt->size) { + ret = v4l2_stop_decode(ctx); + if (ret) + av_log(logger(ctx), AV_LOG_ERROR, "%s stop_decode\n", ctx->name); + s->draining = 1; + return 0; + } + + avbuf = v4l2_getfree_v4l2buf(ctx); + if (!avbuf) + return AVERROR(ENOMEM); + + ret = ff_v4l2_buffer_avpkt_to_buf(pkt, avbuf); + if (ret) + return ret; + + return ff_v4l2_buffer_enqueue(avbuf); +} + +int ff_v4l2_context_dequeue_frame(V4L2Context* ctx, AVFrame* frame) +{ + V4L2Buffer* avbuf = NULL; + + /* if we are draining, we are no longer inputing data, therefore enable a + * timeout so we can dequeue and flag the last valid buffer. + * + * blocks until: + * 1. decoded frame available + * 2. an input buffer is ready to be dequeued + */ + avbuf = v4l2_dequeue_v4l2buf(ctx, ctx_to_m2mctx(ctx)->draining ? 200 : -1); + if (!avbuf) { + if (ctx->done) + return AVERROR_EOF; + + return AVERROR(EAGAIN); + } + + return ff_v4l2_buffer_buf_to_avframe(frame, avbuf); +} + +int ff_v4l2_context_dequeue_packet(V4L2Context* ctx, AVPacket* pkt) +{ + V4L2Buffer* avbuf = NULL; + + /* if we are draining, we are no longer inputing data, therefore enable a + * timeout so we can dequeue and flag the last valid buffer. + * + * blocks until: + * 1. encoded packet available + * 2. an input buffer ready to be dequeued + */ + avbuf = v4l2_dequeue_v4l2buf(ctx, ctx_to_m2mctx(ctx)->draining ? 200 : -1); + if (!avbuf) { + if (ctx->done) + return AVERROR_EOF; + + return AVERROR(EAGAIN); + } + + return ff_v4l2_buffer_buf_to_avpkt(pkt, avbuf); +} + +int ff_v4l2_context_get_format(V4L2Context* ctx) +{ + struct v4l2_format_update fmt = { 0 }; + int ret; + + if (ctx->av_codec_id == AV_CODEC_ID_RAWVIDEO) { + ret = v4l2_get_raw_format(ctx, &fmt.av_fmt); + if (ret) + return ret; + + fmt.update_avfmt = 1; + v4l2_save_to_context(ctx, &fmt); + + /* format has been tried already */ + return ret; + } + + ret = v4l2_get_coded_format(ctx, &fmt.v4l2_fmt); + if (ret) + return ret; + + fmt.update_v4l2 = 1; + v4l2_save_to_context(ctx, &fmt); + + return ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_TRY_FMT, &ctx->format); +} + +int ff_v4l2_context_set_format(V4L2Context* ctx) +{ + return ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_S_FMT, &ctx->format); +} + +void ff_v4l2_context_release(V4L2Context* ctx) +{ + int ret; + + if (!ctx->buffers) + return; + + ret = v4l2_release_buffers(ctx); + if (ret) + av_log(logger(ctx), AV_LOG_WARNING, "V4L2 failed to unmap the %s buffers\n", ctx->name); + + av_free(ctx->buffers); + ctx->buffers = NULL; +} + +int ff_v4l2_context_init(V4L2Context* ctx) +{ + V4L2m2mContext *s = ctx_to_m2mctx(ctx); + struct v4l2_requestbuffers req; + int ret, i; + + if (!v4l2_type_supported(ctx)) { + av_log(logger(ctx), AV_LOG_ERROR, "type %i not supported\n", ctx->type); + return AVERROR_PATCHWELCOME; + } + + ret = ioctl(s->fd, VIDIOC_G_FMT, &ctx->format); + if (ret) + av_log(logger(ctx), AV_LOG_ERROR, "%s VIDIOC_G_FMT failed\n", ctx->name); + + memset(&req, 0, sizeof(req)); + req.count = ctx->num_buffers; + req.memory = V4L2_MEMORY_MMAP; + req.type = ctx->type; + ret = ioctl(s->fd, VIDIOC_REQBUFS, &req); + if (ret < 0) + return AVERROR(errno); + + ctx->num_buffers = req.count; + ctx->buffers = av_mallocz(ctx->num_buffers * sizeof(V4L2Buffer)); + if (!ctx->buffers) { + av_log(logger(ctx), AV_LOG_ERROR, "%s malloc enomem\n", ctx->name); + return AVERROR(ENOMEM); + } + + for (i = 0; i < req.count; i++) { + ctx->buffers[i].context = ctx; + ret = ff_v4l2_buffer_initialize(&ctx->buffers[i], i); + if (ret < 0) { + av_log(logger(ctx), AV_LOG_ERROR, "%s buffer initialization (%s)\n", ctx->name, av_err2str(ret)); + av_free(ctx->buffers); + return ret; + } + } + + av_log(logger(ctx), AV_LOG_DEBUG, "%s: %s %02d buffers initialized: %04ux%04u, sizeimage %08u, bytesperline %08u\n", ctx->name, + V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ? av_fourcc2str(ctx->format.fmt.pix_mp.pixelformat) : av_fourcc2str(ctx->format.fmt.pix.pixelformat), + req.count, + v4l2_get_width(&ctx->format), + v4l2_get_height(&ctx->format), + V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ? ctx->format.fmt.pix_mp.plane_fmt[0].sizeimage : ctx->format.fmt.pix.sizeimage, + V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ? ctx->format.fmt.pix_mp.plane_fmt[0].bytesperline : ctx->format.fmt.pix.bytesperline); + + return 0; +} diff --git a/libavcodec/v4l2_context.h b/libavcodec/v4l2_context.h new file mode 100644 index 0000000000000..b6667a04e3ca1 --- /dev/null +++ b/libavcodec/v4l2_context.h @@ -0,0 +1,181 @@ +/* + * V4L2 context helper functions. + * + * Copyright (C) 2017 Alexis Ballier + * Copyright (C) 2017 Jorge Ramirez + * + * 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 + */ + +#ifndef AVCODEC_V4L2_CONTEXT_H +#define AVCODEC_V4L2_CONTEXT_H + +#include +#include "libavcodec/avcodec.h" +#include "libavutil/pixfmt.h" +#include "libavutil/frame.h" +#include "libavutil/buffer.h" +#include "v4l2_buffers.h" + +typedef struct V4L2Context { + /** + * context name. + */ + const char* name; + + /** + * Type of this buffer context. + * See V4L2_BUF_TYPE_VIDEO_* in videodev2.h + * Readonly after init. + */ + enum v4l2_buf_type type; + + /** + * AVPixelFormat corresponding to this buffer context. + * AV_PIX_FMT_NONE means this is an encoded stream. + */ + enum AVPixelFormat av_pix_fmt; + + /** + * AVCodecID corresponding to this buffer context. + * AV_CODEC_ID_RAWVIDEO means this is a raw stream and av_pix_fmt must be set to a valid value. + */ + enum AVCodecID av_codec_id; + + /** + * Format returned by the driver after initializing the buffer context. + * Readonly after init. + */ + struct v4l2_format format; + + /** + * Width and height of the frames it produces (in case of a capture context, e.g. when decoding) + * or accepts (in case of an output context, e.g. when encoding). + */ + int width, height; + + /** + * Indexed array of V4L2Buffers + */ + V4L2Buffer *buffers; + + /** + * Readonly after init. + */ + int num_buffers; + + /** + * Whether the stream has been started (VIDIOC_STREAMON has been sent). + */ + int streamon; + + /** + * Either no more buffers available or an unrecoverable error was notified + * by the V4L2 kernel driver: once set the context has to be exited. + */ + int done; + +} V4L2Context; + +/** + * Initializes a V4L2Context. + * + * @param[in] ctx A pointer to a V4L2Context. See V4L2Context description for required variables. + * @return 0 in case of success, a negative value representing the error otherwise. + */ +int ff_v4l2_context_init(V4L2Context* ctx); + +/** + * Sets the V4L2Context format in the v4l2 driver. + * + * @param[in] ctx A pointer to a V4L2Context. See V4L2Context description for required variables. + * @return 0 in case of success, a negative value representing the error otherwise. + */ +int ff_v4l2_context_set_format(V4L2Context* ctx); + +/** + * Queries the driver for a valid v4l2 format and copies it to the context. + * + * @param[in] ctx A pointer to a V4L2Context. See V4L2Context description for required variables. + * @return 0 in case of success, a negative value representing the error otherwise. + */ +int ff_v4l2_context_get_format(V4L2Context* ctx); + +/** + * Releases a V4L2Context. + * + * @param[in] ctx A pointer to a V4L2Context. + * The caller is reponsible for freeing it. + * It must not be used after calling this function. + */ +void ff_v4l2_context_release(V4L2Context* ctx); + +/** + * Sets the status of a V4L2Context. + * + * @param[in] ctx A pointer to a V4L2Context. + * @param[in] cmd The status to set (VIDIOC_STREAMON or VIDIOC_STREAMOFF). + * Warning: If VIDIOC_STREAMOFF is sent to a buffer context that still has some frames buffered, + * those frames will be dropped. + * @return 0 in case of success, a negative value representing the error otherwise. + */ +int ff_v4l2_context_set_status(V4L2Context* ctx, int cmd); + +/** + * Dequeues a buffer from a V4L2Context to an AVPacket. + * + * The pkt must be non NULL. + * @param[in] ctx The V4L2Context to dequeue from. + * @param[inout] pkt The AVPacket to dequeue to. + * @return 0 in case of success, AVERROR(EAGAIN) if no buffer was ready, another negative error in case of error. + */ +int ff_v4l2_context_dequeue_packet(V4L2Context* ctx, AVPacket* pkt); + +/** + * Dequeues a buffer from a V4L2Context to an AVFrame. + * + * The frame must be non NULL. + * @param[in] ctx The V4L2Context to dequeue from. + * @param[inout] f The AVFrame to dequeue to. + * @return 0 in case of success, AVERROR(EAGAIN) if no buffer was ready, another negative error in case of error. + */ +int ff_v4l2_context_dequeue_frame(V4L2Context* ctx, AVFrame* f); + +/** + * Enqueues a buffer to a V4L2Context from an AVPacket + * + * The packet must be non NULL. + * When the size of the pkt is null, the buffer is not queued but a V4L2_DEC_CMD_STOP command is sent instead to the driver. + * + * @param[in] ctx The V4L2Context to enqueue to. + * @param[in] pkt A pointer to an AVPacket. + * @return 0 in case of success, a negative error otherwise. + */ +int ff_v4l2_context_enqueue_packet(V4L2Context* ctx, const AVPacket* pkt); + +/** + * Enqueues a buffer to a V4L2Context from an AVFrame + * + * The frame must be non NULL. + * + * @param[in] ctx The V4L2Context to enqueue to. + * @param[in] f A pointer to an AVFrame to enqueue. + * @return 0 in case of success, a negative error otherwise. + */ +int ff_v4l2_context_enqueue_frame(V4L2Context* ctx, const AVFrame* f); + +#endif // AVCODEC_V4L2_CONTEXT_H diff --git a/libavcodec/v4l2_fmt.c b/libavcodec/v4l2_fmt.c new file mode 100644 index 0000000000000..a7ce30869623f --- /dev/null +++ b/libavcodec/v4l2_fmt.c @@ -0,0 +1,182 @@ +/* + * V4L2 format helper functions + * + * Copyright (C) 2017 Alexis Ballier + * Copyright (C) 2017 Jorge Ramirez + * + * 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 +#include +#include "v4l2_fmt.h" + +#define V4L2_FMT(x) V4L2_PIX_FMT_##x +#define AV_CODEC(x) AV_CODEC_ID_##x +#define AV_FMT(x) AV_PIX_FMT_##x + +static const struct fmt_conversion { + enum AVPixelFormat avfmt; + enum AVCodecID avcodec; + uint32_t v4l2_fmt; +} fmt_map[] = { + { AV_FMT(RGB555LE), AV_CODEC(RAWVIDEO), V4L2_FMT(RGB555) }, + { AV_FMT(RGB555BE), AV_CODEC(RAWVIDEO), V4L2_FMT(RGB555X) }, + { AV_FMT(RGB565LE), AV_CODEC(RAWVIDEO), V4L2_FMT(RGB565) }, + { AV_FMT(RGB565BE), AV_CODEC(RAWVIDEO), V4L2_FMT(RGB565X) }, + { AV_FMT(BGR24), AV_CODEC(RAWVIDEO), V4L2_FMT(BGR24) }, + { AV_FMT(RGB24), AV_CODEC(RAWVIDEO), V4L2_FMT(RGB24) }, + { AV_FMT(BGR0), AV_CODEC(RAWVIDEO), V4L2_FMT(BGR32) }, + { AV_FMT(0RGB), AV_CODEC(RAWVIDEO), V4L2_FMT(RGB32) }, + { AV_FMT(GRAY8), AV_CODEC(RAWVIDEO), V4L2_FMT(GREY) }, + { AV_FMT(YUV420P), AV_CODEC(RAWVIDEO), V4L2_FMT(YUV420) }, + { AV_FMT(YUYV422), AV_CODEC(RAWVIDEO), V4L2_FMT(YUYV) }, + { AV_FMT(UYVY422), AV_CODEC(RAWVIDEO), V4L2_FMT(UYVY) }, + { AV_FMT(YUV422P), AV_CODEC(RAWVIDEO), V4L2_FMT(YUV422P) }, + { AV_FMT(YUV411P), AV_CODEC(RAWVIDEO), V4L2_FMT(YUV411P) }, + { AV_FMT(YUV410P), AV_CODEC(RAWVIDEO), V4L2_FMT(YUV410) }, + { AV_FMT(YUV410P), AV_CODEC(RAWVIDEO), V4L2_FMT(YVU410) }, + { AV_FMT(NV12), AV_CODEC(RAWVIDEO), V4L2_FMT(NV12) }, + { AV_FMT(NONE), AV_CODEC(MJPEG), V4L2_FMT(MJPEG) }, + { AV_FMT(NONE), AV_CODEC(MJPEG), V4L2_FMT(JPEG) }, +#ifdef V4L2_PIX_FMT_SRGGB8 + { AV_FMT(BAYER_BGGR8), AV_CODEC(RAWVIDEO), V4L2_FMT(SBGGR8) }, + { AV_FMT(BAYER_GBRG8), AV_CODEC(RAWVIDEO), V4L2_FMT(SGBRG8) }, + { AV_FMT(BAYER_GRBG8), AV_CODEC(RAWVIDEO), V4L2_FMT(SGRBG8) }, + { AV_FMT(BAYER_RGGB8), AV_CODEC(RAWVIDEO), V4L2_FMT(SRGGB8) }, +#endif +#ifdef V4L2_PIX_FMT_Y16 + { AV_FMT(GRAY16LE), AV_CODEC(RAWVIDEO), V4L2_FMT(Y16) }, +#endif +#ifdef V4L2_PIX_FMT_NV12M + { AV_FMT(NV12), AV_CODEC(RAWVIDEO), V4L2_FMT(NV12M) }, +#endif +#ifdef V4L2_PIX_FMT_NV21M + { AV_FMT(NV21), AV_CODEC(RAWVIDEO), V4L2_FMT(NV21M) }, +#endif +#ifdef V4L2_PIX_FMT_YUV420M + { AV_FMT(YUV420P), AV_CODEC(RAWVIDEO), V4L2_FMT(YUV420M) }, +#endif +#ifdef V4L2_PIX_FMT_NV16M + { AV_FMT(NV16), AV_CODEC(RAWVIDEO), V4L2_FMT(NV16M) }, +#endif +#ifdef V4L2_PIX_FMT_H263 + { AV_FMT(NONE), AV_CODEC(H263), V4L2_FMT(H263) }, +#endif +#ifdef V4L2_PIX_FMT_H264 + { AV_FMT(NONE), AV_CODEC(H264), V4L2_FMT(H264) }, +#endif +#ifdef V4L2_PIX_FMT_MPEG4 + { AV_FMT(NONE), AV_CODEC(MPEG4), V4L2_FMT(MPEG4) }, +#endif +#ifdef V4L2_PIX_FMT_CPIA1 + { AV_FMT(NONE), AV_CODEC(CPIA), V4L2_FMT(CPIA1) }, +#endif +#ifdef V4L2_PIX_FMT_DV + { AV_FMT(NONE), AV_CODEC(DVVIDEO), V4L2_FMT(DV) }, +#endif +#ifdef V4L2_PIX_FMT_MPEG1 + { AV_FMT(NONE), AV_CODEC(MPEG1VIDEO), V4L2_FMT(MPEG1) }, +#endif +#ifdef V4L2_PIX_FMT_MPEG2 + { AV_FMT(NONE), AV_CODEC(MPEG2VIDEO), V4L2_FMT(MPEG2) }, +#endif +#ifdef V4L2_PIX_FMT_VP8 + { AV_FMT(NONE), AV_CODEC(VP8), V4L2_FMT(VP8) }, +#endif +#ifdef V4L2_PIX_FMT_VP9 + { AV_FMT(NONE), AV_CODEC(VP9), V4L2_FMT(VP9) }, +#endif +#ifdef V4L2_PIX_FMT_HEVC + { AV_FMT(NONE), AV_CODEC(HEVC), V4L2_FMT(HEVC) }, +#endif +#ifdef V4L2_PIX_FMT_VC1_ANNEX_G + { AV_FMT(NONE), AV_CODEC(VC1), V4L2_FMT(VC1_ANNEX_G) }, +#endif +}; + +static int match_codec(const void *a, const void *b) +{ + if (*(enum AVCodecID *)a == ((struct fmt_conversion *)b)->avcodec) + return 0; + + return 1; +} + +uint32_t ff_v4l2_format_avcodec_to_v4l2(enum AVCodecID avcodec) +{ + size_t len = FF_ARRAY_ELEMS(fmt_map); + struct fmt_conversion *item; + + item = lfind(&avcodec, fmt_map, &len, sizeof(fmt_map[0]), match_codec); + if (item) + return item->v4l2_fmt; + + return 0; +} + +static int match_fmt(const void *a, const void *b) +{ + if ( *(enum AVPixelFormat *)a == ((struct fmt_conversion *)b)->avfmt) + return 0; + + return 1; +} + +uint32_t ff_v4l2_format_avfmt_to_v4l2(enum AVPixelFormat avfmt) +{ + size_t len = FF_ARRAY_ELEMS(fmt_map); + struct fmt_conversion *item; + + item = lfind(&avfmt, fmt_map, &len, sizeof(fmt_map[0]), match_fmt); + if (item) + return item->v4l2_fmt; + + return 0; +} + +struct v4l2fmt_avcodec_pair { + enum AVCodecID avcodec; + uint32_t v4l2_fmt; +}; + +static int match_codecfmt(const void *a, const void *b) +{ + struct v4l2fmt_avcodec_pair *key = (struct v4l2fmt_avcodec_pair *) a; + struct fmt_conversion *item = (struct fmt_conversion *) b; + + if (key->avcodec == item->avcodec && key->v4l2_fmt == item->v4l2_fmt) + return 0; + + return 1; +} + +enum AVPixelFormat ff_v4l2_format_v4l2_to_avfmt(uint32_t v4l2_fmt, enum AVCodecID avcodec) +{ + struct v4l2fmt_avcodec_pair const key = { + .v4l2_fmt = v4l2_fmt, + .avcodec = avcodec, + }; + size_t len = FF_ARRAY_ELEMS(fmt_map); + struct fmt_conversion *item; + + item = lfind(&key, fmt_map, &len, sizeof(fmt_map[0]), match_codecfmt); + if (item) + return item->avfmt; + + return AV_PIX_FMT_NONE; +} diff --git a/libavcodec/v4l2_fmt.h b/libavcodec/v4l2_fmt.h new file mode 100644 index 0000000000000..01360029c837e --- /dev/null +++ b/libavcodec/v4l2_fmt.h @@ -0,0 +1,34 @@ +/* + * V4L2 format helper functions + * + * Copyright (C) 2017 Alexis Ballier + * Copyright (C) 2017 Jorge Ramirez + * + * 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 + */ + +#ifndef AVCODEC_V4L2_FMT_H +#define AVCODEC_V4L2_FMT_H + +#include "libavcodec/avcodec.h" +#include "libavutil/pixfmt.h" + +enum AVPixelFormat ff_v4l2_format_v4l2_to_avfmt(uint32_t v4l2_fmt, enum AVCodecID avcodec); +uint32_t ff_v4l2_format_avcodec_to_v4l2(enum AVCodecID avcodec); +uint32_t ff_v4l2_format_avfmt_to_v4l2(enum AVPixelFormat avfmt); + +#endif /* AVCODEC_V4L2_FMT_H*/ diff --git a/libavcodec/v4l2_m2m.c b/libavcodec/v4l2_m2m.c new file mode 100644 index 0000000000000..1d7a8521d80fd --- /dev/null +++ b/libavcodec/v4l2_m2m.c @@ -0,0 +1,383 @@ +/* + * V4L mem2mem + * + * Copyright (C) 2017 Alexis Ballier + * Copyright (C) 2017 Jorge Ramirez + * + * 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 +#include +#include +#include +#include +#include +#include "libavcodec/avcodec.h" +#include "libavcodec/internal.h" +#include "libavutil/pixdesc.h" +#include "libavutil/imgutils.h" +#include "libavutil/pixfmt.h" +#include "v4l2_context.h" +#include "v4l2_fmt.h" +#include "v4l2_m2m.h" + +static inline int v4l2_splane_video(struct v4l2_capability *cap) +{ + if (cap->capabilities & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT) && + cap->capabilities & V4L2_CAP_STREAMING) + return 1; + + if (cap->capabilities & V4L2_CAP_VIDEO_M2M) + return 1; + + return 0; +} + +static inline int v4l2_mplane_video(struct v4l2_capability *cap) +{ + if (cap->capabilities & (V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE) && + cap->capabilities & V4L2_CAP_STREAMING) + return 1; + + if (cap->capabilities & V4L2_CAP_VIDEO_M2M_MPLANE) + return 1; + + return 0; +} + +static int v4l2_prepare_contexts(V4L2m2mContext* s) +{ + struct v4l2_capability cap; + int ret; + + s->capture.done = s->output.done = 0; + s->capture.name = "capture"; + s->output.name = "output "; + atomic_init(&s->refcount, 0); + sem_init(&s->refsync, 0, 0); + + memset(&cap, 0, sizeof(cap)); + ret = ioctl(s->fd, VIDIOC_QUERYCAP, &cap); + if (ret < 0) + return ret; + + av_log(s->avctx, AV_LOG_INFO, "driver '%s' on card '%s'\n", cap.driver, cap.card); + + if (v4l2_mplane_video(&cap)) { + s->capture.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + s->output.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + return 0; + } + + if (v4l2_splane_video(&cap)) { + s->capture.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + s->output.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + return 0; + } + + return AVERROR(EINVAL); +} + +static int v4l2_probe_driver(V4L2m2mContext* s) +{ + int ret; + + s->fd = open(s->devname, O_RDWR | O_NONBLOCK, 0); + if (s->fd < 0) + return AVERROR(errno); + + ret = v4l2_prepare_contexts(s); + if (ret < 0) + goto done; + + ret = ff_v4l2_context_get_format(&s->output); + if (ret) { + av_log(s->avctx, AV_LOG_DEBUG, "v4l2 output format not supported\n"); + goto done; + } + + ret = ff_v4l2_context_get_format(&s->capture); + if (ret) { + av_log(s->avctx, AV_LOG_DEBUG, "v4l2 capture format not supported\n"); + goto done; + } + +done: + if (close(s->fd) < 0) { + ret = AVERROR(errno); + av_log(s->avctx, AV_LOG_ERROR, "failure closing %s (%s)\n", s->devname, av_err2str(AVERROR(errno))); + } + + s->fd = -1; + + return ret; +} + +static int v4l2_configure_contexts(V4L2m2mContext* s) +{ + void *log_ctx = s->avctx; + int ret; + + s->fd = open(s->devname, O_RDWR | O_NONBLOCK, 0); + if (s->fd < 0) + return AVERROR(errno); + + ret = v4l2_prepare_contexts(s); + if (ret < 0) + goto error; + + ret = ff_v4l2_context_set_format(&s->output); + if (ret) { + av_log(log_ctx, AV_LOG_ERROR, "can't set v4l2 output format\n"); + goto error; + } + + ret = ff_v4l2_context_set_format(&s->capture); + if (ret) { + av_log(log_ctx, AV_LOG_ERROR, "can't to set v4l2 capture format\n"); + goto error; + } + + ret = ff_v4l2_context_init(&s->output); + if (ret) { + av_log(log_ctx, AV_LOG_ERROR, "no v4l2 output context's buffers\n"); + goto error; + } + + /* decoder's buffers need to be updated at a later stage */ + if (!av_codec_is_decoder(s->avctx->codec)) { + ret = ff_v4l2_context_init(&s->capture); + if (ret) { + av_log(log_ctx, AV_LOG_ERROR, "no v4l2 capture context's buffers\n"); + goto error; + } + } + + return 0; + +error: + if (close(s->fd) < 0) { + ret = AVERROR(errno); + av_log(log_ctx, AV_LOG_ERROR, "error closing %s (%s)\n", + s->devname, av_err2str(AVERROR(errno))); + } + s->fd = -1; + + return ret; +} + +/****************************************************************************** + * + * V4L2 M2M Interface + * + ******************************************************************************/ +int ff_v4l2_m2m_codec_reinit(V4L2m2mContext* s) +{ + int ret; + + av_log(s->avctx, AV_LOG_DEBUG, "reinit context\n"); + + /* 1. streamoff */ + ret = ff_v4l2_context_set_status(&s->capture, VIDIOC_STREAMOFF); + if (ret) + av_log(s->avctx, AV_LOG_ERROR, "capture VIDIOC_STREAMOFF\n"); + + /* 2. unmap the capture buffers (v4l2 and ffmpeg): + * we must wait for all references to be released before being allowed + * to queue new buffers. + */ + av_log(s->avctx, AV_LOG_DEBUG, "waiting for user to release AVBufferRefs\n"); + if (atomic_load(&s->refcount)) + while(sem_wait(&s->refsync) == -1 && errno == EINTR); + + ff_v4l2_context_release(&s->capture); + + /* 3. get the new capture format */ + ret = ff_v4l2_context_get_format(&s->capture); + if (ret) { + av_log(s->avctx, AV_LOG_ERROR, "query the new capture format\n"); + return ret; + } + + /* 4. set the capture format */ + ret = ff_v4l2_context_set_format(&s->capture); + if (ret) { + av_log(s->avctx, AV_LOG_ERROR, "setting capture format\n"); + return ret; + } + + /* 5. complete reinit */ + sem_destroy(&s->refsync); + sem_init(&s->refsync, 0, 0); + s->draining = 0; + s->reinit = 0; + + return 0; +} + +int ff_v4l2_m2m_codec_full_reinit(V4L2m2mContext *s) +{ + void *log_ctx = s->avctx; + int ret; + + av_log(log_ctx, AV_LOG_DEBUG, "%s full reinit\n", s->devname); + + /* wait for pending buffer references */ + if (atomic_load(&s->refcount)) + while(sem_wait(&s->refsync) == -1 && errno == EINTR); + + /* close the driver */ + ff_v4l2_m2m_codec_end(s->avctx); + + /* start again now that we know the stream dimensions */ + s->draining = 0; + s->reinit = 0; + + s->fd = open(s->devname, O_RDWR | O_NONBLOCK, 0); + if (s->fd < 0) + return AVERROR(errno); + + ret = v4l2_prepare_contexts(s); + if (ret < 0) + goto error; + + /* if a full re-init was requested - probe didn't run - we need to populate + * the format for each context + */ + ret = ff_v4l2_context_get_format(&s->output); + if (ret) { + av_log(log_ctx, AV_LOG_DEBUG, "v4l2 output format not supported\n"); + goto error; + } + + ret = ff_v4l2_context_get_format(&s->capture); + if (ret) { + av_log(log_ctx, AV_LOG_DEBUG, "v4l2 capture format not supported\n"); + goto error; + } + + ret = ff_v4l2_context_set_format(&s->output); + if (ret) { + av_log(log_ctx, AV_LOG_ERROR, "can't set v4l2 output format\n"); + goto error; + } + + ret = ff_v4l2_context_set_format(&s->capture); + if (ret) { + av_log(log_ctx, AV_LOG_ERROR, "can't to set v4l2 capture format\n"); + goto error; + } + + ret = ff_v4l2_context_init(&s->output); + if (ret) { + av_log(log_ctx, AV_LOG_ERROR, "no v4l2 output context's buffers\n"); + goto error; + } + + /* decoder's buffers need to be updated at a later stage */ + if (!av_codec_is_decoder(s->avctx->codec)) { + ret = ff_v4l2_context_init(&s->capture); + if (ret) { + av_log(log_ctx, AV_LOG_ERROR, "no v4l2 capture context's buffers\n"); + goto error; + } + } + + return 0; + +error: + if (close(s->fd) < 0) { + ret = AVERROR(errno); + av_log(log_ctx, AV_LOG_ERROR, "error closing %s (%s)\n", + s->devname, av_err2str(AVERROR(errno))); + } + s->fd = -1; + + return ret; +} + +int ff_v4l2_m2m_codec_end(AVCodecContext *avctx) +{ + V4L2m2mContext* s = avctx->priv_data; + int ret; + + ret = ff_v4l2_context_set_status(&s->output, VIDIOC_STREAMOFF); + if (ret) + av_log(avctx, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->output.name); + + ret = ff_v4l2_context_set_status(&s->capture, VIDIOC_STREAMOFF); + if (ret) + av_log(avctx, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->capture.name); + + ff_v4l2_context_release(&s->output); + + if (atomic_load(&s->refcount)) + av_log(avctx, AV_LOG_ERROR, "ff_v4l2m2m_codec_end leaving pending buffers\n"); + + ff_v4l2_context_release(&s->capture); + sem_destroy(&s->refsync); + + /* release the hardware */ + if (close(s->fd) < 0 ) + av_log(avctx, AV_LOG_ERROR, "failure closing %s (%s)\n", s->devname, av_err2str(AVERROR(errno))); + + s->fd = -1; + + return 0; +} + +int ff_v4l2_m2m_codec_init(AVCodecContext *avctx) +{ + int ret = AVERROR(EINVAL); + struct dirent *entry; + char node[PATH_MAX]; + DIR *dirp; + + V4L2m2mContext *s = avctx->priv_data; + s->avctx = avctx; + + dirp = opendir("/dev"); + if (!dirp) + return AVERROR(errno); + + for (entry = readdir(dirp); entry; entry = readdir(dirp)) { + + if (strncmp(entry->d_name, "video", 5)) + continue; + + snprintf(node, sizeof(node), "/dev/%s", entry->d_name); + av_log(s->avctx, AV_LOG_DEBUG, "probing device %s\n", node); + strncpy(s->devname, node, strlen(node) + 1); + ret = v4l2_probe_driver(s); + if (!ret) + break; + } + + closedir(dirp); + + if (ret) { + av_log(s->avctx, AV_LOG_ERROR, "Could not find a valid device\n"); + memset(s->devname, 0, sizeof(s->devname)); + + return ret; + } + + av_log(s->avctx, AV_LOG_INFO, "Using device %s\n", node); + + return v4l2_configure_contexts(s); +} diff --git a/libavcodec/v4l2_m2m.h b/libavcodec/v4l2_m2m.h new file mode 100644 index 0000000000000..13e2285389f29 --- /dev/null +++ b/libavcodec/v4l2_m2m.h @@ -0,0 +1,103 @@ +/* + * V4L2 mem2mem helper functions + * + * Copyright (C) 2017 Alexis Ballier + * Copyright (C) 2017 Jorge Ramirez + * + * 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 + */ + +#ifndef AVCODEC_V4L2_M2M_H +#define AVCODEC_V4L2_M2M_H + +#include +#include +#include +#include "libavcodec/avcodec.h" +#include "v4l2_context.h" + +#define container_of(ptr, type, member) ({ \ + const __typeof__(((type *)0)->member ) *__mptr = (ptr); \ + (type *)((char *)__mptr - offsetof(type,member) );}) + +#define V4L_M2M_DEFAULT_OPTS \ + { "num_output_buffers", "Number of buffers in the output context",\ + OFFSET(output.num_buffers), AV_OPT_TYPE_INT, { .i64 = 16 }, 6, INT_MAX, FLAGS } + +typedef struct V4L2m2mContext +{ + AVClass *class; + char devname[PATH_MAX]; + int fd; + + /* the codec context queues */ + V4L2Context capture; + V4L2Context output; + + /* refcount of buffers held by the user */ + atomic_uint refcount; + + /* dynamic stream reconfig */ + AVCodecContext *avctx; + sem_t refsync; + int reinit; + + /* null frame/packet received */ + int draining; +} V4L2m2mContext; + +/** + * Probes the video nodes looking for the required codec capabilities. + * + * @param[in] ctx The AVCodecContext instantiated by the encoder/decoder. + * + * @returns 0 if a driver is found, a negative number otherwise. + */ +int ff_v4l2_m2m_codec_init(AVCodecContext *avctx); + +/** + * Releases all the codec resources if all AVBufferRefs have been returned to the + * ctx. Otherwise keep the driver open. + * + * @param[in] The AVCodecContext instantiated by the encoder/decoder. + * + * @returns 0 + * + */ +int ff_v4l2_m2m_codec_end(AVCodecContext *avctx); + +/** + * Reinitializes the V4L2m2mContext when the driver cant continue processing + * with the capture parameters. + * + * @param[in] ctx The V4L2m2mContext instantiated by the encoder/decoder. + * + * @returns 0 in case of success, negative number otherwise + */ +int ff_v4l2_m2m_codec_reinit(V4L2m2mContext *ctx); + +/** + * Reinitializes the V4L2m2mContext when the driver cant continue processing + * with the any of the current V4L2Contexts (ie, changes in output and capture). + * + * @param[in] ctx The V4L2m2mContext instantiated by the encoder/decoder. + * + * @returns 0 in case of success, negative number otherwise + */ +int ff_v4l2_m2m_codec_full_reinit(V4L2m2mContext *ctx); + +#endif /* AVCODEC_V4L2_M2M_H */ diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c new file mode 100644 index 0000000000000..958cdc522b91a --- /dev/null +++ b/libavcodec/v4l2_m2m_dec.c @@ -0,0 +1,228 @@ +/* + * V4L2 mem2mem decoders + * + * Copyright (C) 2017 Alexis Ballier + * Copyright (C) 2017 Jorge Ramirez + * + * 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 +#include +#include "libavutil/pixfmt.h" +#include "libavutil/pixdesc.h" +#include "libavutil/opt.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/decode.h" + +#include "v4l2_context.h" +#include "v4l2_m2m.h" +#include "v4l2_fmt.h" + +static int v4l2_try_start(AVCodecContext *avctx) +{ + V4L2m2mContext *s = avctx->priv_data; + V4L2Context *const capture = &s->capture; + V4L2Context *const output = &s->output; + struct v4l2_selection selection; + int ret; + + /* 1. start the output process */ + if (!output->streamon) { + ret = ff_v4l2_context_set_status(output, VIDIOC_STREAMON); + if (ret < 0) { + av_log(avctx, AV_LOG_DEBUG, "VIDIOC_STREAMON on output context\n"); + return ret; + } + } + + if (capture->streamon) + return 0; + + /* 2. get the capture format */ + capture->format.type = capture->type; + ret = ioctl(s->fd, VIDIOC_G_FMT, &capture->format); + if (ret) { + av_log(avctx, AV_LOG_WARNING, "VIDIOC_G_FMT ioctl\n"); + return ret; + } + + /* 2.1 update the AVCodecContext */ + avctx->pix_fmt = ff_v4l2_format_v4l2_to_avfmt(capture->format.fmt.pix_mp.pixelformat, AV_CODEC_ID_RAWVIDEO); + capture->av_pix_fmt = avctx->pix_fmt; + + /* 3. set the crop parameters */ + selection.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + selection.r.height = avctx->coded_height; + selection.r.width = avctx->coded_width; + ret = ioctl(s->fd, VIDIOC_S_SELECTION, &selection); + if (!ret) { + ret = ioctl(s->fd, VIDIOC_G_SELECTION, &selection); + if (ret) { + av_log(avctx, AV_LOG_WARNING, "VIDIOC_G_SELECTION ioctl\n"); + } else { + av_log(avctx, AV_LOG_DEBUG, "crop output %dx%d\n", selection.r.width, selection.r.height); + /* update the size of the resulting frame */ + capture->height = selection.r.height; + capture->width = selection.r.width; + } + } + + /* 4. init the capture context now that we have the capture format */ + if (!capture->buffers) { + ret = ff_v4l2_context_init(capture); + if (ret) { + av_log(avctx, AV_LOG_DEBUG, "can't request output buffers\n"); + return ret; + } + } + + /* 5. start the capture process */ + ret = ff_v4l2_context_set_status(capture, VIDIOC_STREAMON); + if (ret) { + av_log(avctx, AV_LOG_DEBUG, "VIDIOC_STREAMON, on capture context\n"); + return ret; + } + + return 0; +} + +static int v4l2_prepare_decoder(V4L2m2mContext *s) +{ + struct v4l2_event_subscription sub; + V4L2Context *output = &s->output; + int ret; + + /** + * requirements + */ + memset(&sub, 0, sizeof(sub)); + sub.type = V4L2_EVENT_SOURCE_CHANGE; + ret = ioctl(s->fd, VIDIOC_SUBSCRIBE_EVENT, &sub); + if ( ret < 0) { + if (output->height == 0 || output->width == 0) { + av_log(s->avctx, AV_LOG_ERROR, + "the v4l2 driver does not support VIDIOC_SUBSCRIBE_EVENT\n" + "you must provide codec_height and codec_width on input\n"); + return ret; + } + } + + return 0; +} + +static int v4l2_receive_frame(AVCodecContext *avctx, AVFrame *frame) +{ + V4L2m2mContext *s = avctx->priv_data; + V4L2Context *const capture = &s->capture; + V4L2Context *const output = &s->output; + AVPacket avpkt = {0}; + int ret; + + ret = ff_decode_get_packet(avctx, &avpkt); + if (ret < 0 && ret != AVERROR_EOF) + return ret; + + if (s->draining) + goto dequeue; + + ret = ff_v4l2_context_enqueue_packet(output, &avpkt); + if (ret < 0) { + if (ret != AVERROR(ENOMEM)) + return ret; + /* no input buffers available, continue dequeing */ + } + + if (avpkt.size) { + ret = v4l2_try_start(avctx); + if (ret) + return 0; + } + +dequeue: + return ff_v4l2_context_dequeue_frame(capture, frame); +} + +static av_cold int v4l2_decode_init(AVCodecContext *avctx) +{ + V4L2m2mContext *s = avctx->priv_data; + V4L2Context *capture = &s->capture; + V4L2Context *output = &s->output; + int ret; + + /* if these dimensions are invalid (ie, 0 or too small) an event will be raised + * by the v4l2 driver; this event will trigger a full pipeline reconfig and + * the proper values will be retrieved from the kernel driver. + */ + output->height = capture->height = avctx->coded_height; + output->width = capture->width = avctx->coded_width; + + output->av_codec_id = avctx->codec_id; + output->av_pix_fmt = AV_PIX_FMT_NONE; + + capture->av_codec_id = AV_CODEC_ID_RAWVIDEO; + capture->av_pix_fmt = avctx->pix_fmt; + + ret = ff_v4l2_m2m_codec_init(avctx); + if (ret) { + av_log(avctx, AV_LOG_ERROR, "can't configure decoder\n"); + return ret; + } + + return v4l2_prepare_decoder(s); +} + +#define OFFSET(x) offsetof(V4L2m2mContext, x) +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM + +static const AVOption options[] = { + V4L_M2M_DEFAULT_OPTS, + { "num_capture_buffers", "Number of buffers in the capture context", + OFFSET(capture.num_buffers), AV_OPT_TYPE_INT, {.i64 = 20}, 20, INT_MAX, FLAGS }, + { NULL}, +}; + +#define M2MDEC(NAME, LONGNAME, CODEC, bsf_name) \ +static const AVClass v4l2_m2m_ ## NAME ## _dec_class = {\ + .class_name = #NAME "_v4l2_m2m_decoder",\ + .item_name = av_default_item_name,\ + .option = options,\ + .version = LIBAVUTIL_VERSION_INT,\ +};\ +\ +AVCodec ff_ ## NAME ## _v4l2m2m_decoder = { \ + .name = #NAME "_v4l2m2m" ,\ + .long_name = NULL_IF_CONFIG_SMALL("V4L2 mem2mem " LONGNAME " decoder wrapper"),\ + .type = AVMEDIA_TYPE_VIDEO,\ + .id = CODEC ,\ + .priv_data_size = sizeof(V4L2m2mContext),\ + .priv_class = &v4l2_m2m_ ## NAME ## _dec_class,\ + .init = v4l2_decode_init,\ + .receive_frame = v4l2_receive_frame,\ + .close = ff_v4l2_m2m_codec_end,\ + .bsfs = bsf_name, \ +}; + +M2MDEC(h264, "H.264", AV_CODEC_ID_H264, "h264_mp4toannexb"); +M2MDEC(hevc, "HEVC", AV_CODEC_ID_HEVC, "hevc_mp4toannexb"); +M2MDEC(mpeg1, "MPEG1", AV_CODEC_ID_MPEG1VIDEO, NULL); +M2MDEC(mpeg2, "MPEG2", AV_CODEC_ID_MPEG2VIDEO, NULL); +M2MDEC(mpeg4, "MPEG4", AV_CODEC_ID_MPEG4, NULL); +M2MDEC(h263, "H.263", AV_CODEC_ID_H263, NULL); +M2MDEC(vc1 , "VC1", AV_CODEC_ID_VC1, NULL); +M2MDEC(vp8, "VP8", AV_CODEC_ID_VP8, NULL); +M2MDEC(vp9, "VP9", AV_CODEC_ID_VP9, NULL); diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c new file mode 100644 index 0000000000000..e40a120b533fd --- /dev/null +++ b/libavcodec/v4l2_m2m_enc.c @@ -0,0 +1,352 @@ +/* + * V4L2 mem2mem encoders + * + * Copyright (C) 2017 Alexis Ballier + * Copyright (C) 2017 Jorge Ramirez + * + * 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 +#include +#include +#include "libavcodec/avcodec.h" +#include "libavutil/pixdesc.h" +#include "libavutil/pixfmt.h" +#include "libavutil/opt.h" +#include "v4l2_context.h" +#include "v4l2_m2m.h" + +#define MPEG_CID(x) V4L2_CID_MPEG_VIDEO_##x +#define MPEG_VIDEO(x) V4L2_MPEG_VIDEO_##x + +static inline void v4l2_set_timeperframe(V4L2m2mContext *s, unsigned int num, unsigned int den) +{ + struct v4l2_streamparm parm = { 0 }; + + parm.type = V4L2_TYPE_IS_MULTIPLANAR(s->output.type) ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE : V4L2_BUF_TYPE_VIDEO_OUTPUT; + parm.parm.output.timeperframe.denominator = den; + parm.parm.output.timeperframe.numerator = num; + + if (ioctl(s->fd, VIDIOC_S_PARM, &parm) < 0) + av_log(s->avctx, AV_LOG_WARNING, "Failed to set timeperframe"); +} + +static inline void v4l2_set_ext_ctrl(V4L2m2mContext *s, unsigned int id, signed int value, const char *name) +{ + struct v4l2_ext_controls ctrls = { 0 }; + struct v4l2_ext_control ctrl = { 0 }; + + /* set ctrls */ + ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG; + ctrls.controls = &ctrl; + ctrls.count = 1; + + /* set ctrl*/ + ctrl.value = value; + ctrl.id = id ; + + if (ioctl(s->fd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0) + av_log(s->avctx, AV_LOG_WARNING, "Failed to set %s\n", name); + else + av_log(s->avctx, AV_LOG_DEBUG, "Encoder: %s = %d\n", name, value); +} + +static inline int v4l2_get_ext_ctrl(V4L2m2mContext *s, unsigned int id, signed int *value, const char *name) +{ + struct v4l2_ext_controls ctrls = { 0 }; + struct v4l2_ext_control ctrl = { 0 }; + int ret; + + /* set ctrls */ + ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG; + ctrls.controls = &ctrl; + ctrls.count = 1; + + /* set ctrl*/ + ctrl.id = id ; + + ret = ioctl(s->fd, VIDIOC_G_EXT_CTRLS, &ctrls); + if (ret < 0) { + av_log(s->avctx, AV_LOG_WARNING, "Failed to set %s\n", name); + return ret; + } + + *value = ctrl.value; + + return 0; +} + +static int match_profile(const void *a, const void *b) +{ + if (*(unsigned int *)a == *(unsigned int *)b) + return 0; + + return 1; +} + +static inline unsigned int v4l2_h264_profile_from_ff(int p) +{ + struct h264_profile { + unsigned int ffmpeg_val; + unsigned int v4l2_val; + } *val, profile[] = { + { FF_PROFILE_H264_CONSTRAINED_BASELINE, MPEG_VIDEO(H264_PROFILE_CONSTRAINED_BASELINE) }, + { FF_PROFILE_H264_HIGH_444_PREDICTIVE, MPEG_VIDEO(H264_PROFILE_HIGH_444_PREDICTIVE) }, + { FF_PROFILE_H264_HIGH_422_INTRA, MPEG_VIDEO(H264_PROFILE_HIGH_422_INTRA) }, + { FF_PROFILE_H264_HIGH_444_INTRA, MPEG_VIDEO(H264_PROFILE_HIGH_444_INTRA) }, + { FF_PROFILE_H264_HIGH_10_INTRA, MPEG_VIDEO(H264_PROFILE_HIGH_10_INTRA) }, + { FF_PROFILE_H264_HIGH_422, MPEG_VIDEO(H264_PROFILE_HIGH_422) }, + { FF_PROFILE_H264_BASELINE, MPEG_VIDEO(H264_PROFILE_BASELINE) }, + { FF_PROFILE_H264_EXTENDED, MPEG_VIDEO(H264_PROFILE_EXTENDED) }, + { FF_PROFILE_H264_HIGH_10, MPEG_VIDEO(H264_PROFILE_HIGH_10) }, + { FF_PROFILE_H264_MAIN, MPEG_VIDEO(H264_PROFILE_MAIN) }, + { FF_PROFILE_H264_HIGH, MPEG_VIDEO(H264_PROFILE_HIGH) }, + }; + size_t len = FF_ARRAY_ELEMS(profile); + + val = lfind(&p, profile, &len, sizeof(profile[0]), match_profile); + if (val) + return val->v4l2_val; + + return AVERROR(ENOENT); +} + +static inline int v4l2_mpeg4_profile_from_ff(int p) +{ + struct mpeg4_profile { + unsigned int ffmpeg_val; + unsigned int v4l2_val; + } *val, profile[] = { + { FF_PROFILE_MPEG4_ADVANCED_CODING, MPEG_VIDEO(MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY) }, + { FF_PROFILE_MPEG4_ADVANCED_SIMPLE, MPEG_VIDEO(MPEG4_PROFILE_ADVANCED_SIMPLE) }, + { FF_PROFILE_MPEG4_SIMPLE_SCALABLE, MPEG_VIDEO(MPEG4_PROFILE_SIMPLE_SCALABLE) }, + { FF_PROFILE_MPEG4_SIMPLE, MPEG_VIDEO(MPEG4_PROFILE_SIMPLE) }, + { FF_PROFILE_MPEG4_CORE, MPEG_VIDEO(MPEG4_PROFILE_CORE) }, + }; + size_t len = FF_ARRAY_ELEMS(profile); + + val = lfind(&p, profile, &len, sizeof(profile[0]), match_profile); + if (val) + return val->v4l2_val; + + return AVERROR(ENOENT); +} + +static int v4l2_check_b_frame_support(V4L2m2mContext *s) +{ + if (s->avctx->max_b_frames) + av_log(s->avctx, AV_LOG_WARNING, "Encoder does not support b-frames yet\n"); + + v4l2_set_ext_ctrl(s, MPEG_CID(B_FRAMES), 0, "number of B-frames"); + v4l2_get_ext_ctrl(s, MPEG_CID(B_FRAMES), &s->avctx->max_b_frames, "number of B-frames"); + if (s->avctx->max_b_frames == 0) + return 0; + + avpriv_report_missing_feature(s->avctx, "DTS/PTS calculation for V4L2 encoding"); + + return AVERROR_PATCHWELCOME; +} + +static int v4l2_prepare_encoder(V4L2m2mContext *s) +{ + AVCodecContext *avctx = s->avctx; + int qmin_cid, qmax_cid, qmin, qmax; + int ret, val; + + /** + * requirements + */ + ret = v4l2_check_b_frame_support(s); + if (ret) + return ret; + + /** + * settingss + */ + if (avctx->framerate.num || avctx->framerate.den) + v4l2_set_timeperframe(s, avctx->framerate.num, avctx->framerate.den); + + /* set ext ctrls */ + v4l2_set_ext_ctrl(s, MPEG_CID(HEADER_MODE), MPEG_VIDEO(HEADER_MODE_SEPARATE), "header mode"); + v4l2_set_ext_ctrl(s, MPEG_CID(BITRATE) , avctx->bit_rate, "bit rate"); + v4l2_set_ext_ctrl(s, MPEG_CID(GOP_SIZE), avctx->gop_size,"gop size"); + + av_log(avctx, AV_LOG_DEBUG, + "Encoder Context: id (%d), profile (%d), frame rate(%d/%d), number b-frames (%d), " + "gop size (%d), bit rate (%ld), qmin (%d), qmax (%d)\n", + avctx->codec_id, avctx->profile, avctx->framerate.num, avctx->framerate.den, + avctx->max_b_frames, avctx->gop_size, avctx->bit_rate, avctx->qmin, avctx->qmax); + + switch (avctx->codec_id) { + case AV_CODEC_ID_H264: + val = v4l2_h264_profile_from_ff(avctx->profile); + if (val < 0) + av_log(avctx, AV_LOG_WARNING, "h264 profile not found\n"); + else + v4l2_set_ext_ctrl(s, MPEG_CID(H264_PROFILE), val, "h264 profile"); + qmin_cid = MPEG_CID(H264_MIN_QP); + qmax_cid = MPEG_CID(H264_MAX_QP); + qmin = 0; + qmax = 51; + break; + case AV_CODEC_ID_MPEG4: + val = v4l2_mpeg4_profile_from_ff(avctx->profile); + if (val < 0) + av_log(avctx, AV_LOG_WARNING, "mpeg4 profile not found\n"); + else + v4l2_set_ext_ctrl(s, MPEG_CID(MPEG4_PROFILE), val, "mpeg4 profile"); + qmin_cid = MPEG_CID(MPEG4_MIN_QP); + qmax_cid = MPEG_CID(MPEG4_MAX_QP); + if (avctx->flags & CODEC_FLAG_QPEL) + v4l2_set_ext_ctrl(s, MPEG_CID(MPEG4_QPEL), 1, "qpel"); + qmin = 1; + qmax = 31; + break; + case AV_CODEC_ID_H263: + qmin_cid = MPEG_CID(H263_MIN_QP); + qmax_cid = MPEG_CID(H263_MAX_QP); + qmin = 1; + qmax = 31; + break; + case AV_CODEC_ID_VP8: + qmin_cid = MPEG_CID(VPX_MIN_QP); + qmax_cid = MPEG_CID(VPX_MAX_QP); + qmin = 0; + qmax = 127; + break; + case AV_CODEC_ID_VP9: + qmin_cid = MPEG_CID(VPX_MIN_QP); + qmax_cid = MPEG_CID(VPX_MAX_QP); + qmin = 0; + qmax = 255; + break; + default: + return 0; + } + + if (qmin != avctx->qmin || qmax != avctx->qmax) + av_log(avctx, AV_LOG_WARNING, "Encoder adjusted: qmin (%d), qmax (%d)\n", qmin, qmax); + + v4l2_set_ext_ctrl(s, qmin_cid, qmin, "minimum video quantizer scale"); + v4l2_set_ext_ctrl(s, qmax_cid, qmax, "maximum video quantizer scale"); + + return 0; +} + +static int v4l2_send_frame(AVCodecContext *avctx, const AVFrame *frame) +{ + V4L2m2mContext *s = avctx->priv_data; + V4L2Context *const output = &s->output; + + return ff_v4l2_context_enqueue_frame(output, frame); +} + +static int v4l2_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) +{ + V4L2m2mContext *s = avctx->priv_data; + V4L2Context *const capture = &s->capture; + V4L2Context *const output = &s->output; + int ret; + + if (s->draining) + goto dequeue; + + if (!output->streamon) { + ret = ff_v4l2_context_set_status(output, VIDIOC_STREAMON); + if (ret) { + av_log(avctx, AV_LOG_ERROR, "VIDIOC_STREAMOFF failed on output context\n"); + return ret; + } + } + + if (!capture->streamon) { + ret = ff_v4l2_context_set_status(capture, VIDIOC_STREAMON); + if (ret) { + av_log(avctx, AV_LOG_ERROR, "VIDIOC_STREAMON failed on capture context\n"); + return ret; + } + } + +dequeue: + return ff_v4l2_context_dequeue_packet(capture, avpkt); +} + +static av_cold int v4l2_encode_init(AVCodecContext *avctx) +{ + V4L2m2mContext *s = avctx->priv_data; + V4L2Context *capture = &s->capture; + V4L2Context *output = &s->output; + int ret; + + /* common settings output/capture */ + output->height = capture->height = avctx->height; + output->width = capture->width = avctx->width; + + /* output context */ + output->av_codec_id = AV_CODEC_ID_RAWVIDEO; + output->av_pix_fmt = avctx->pix_fmt; + + /* capture context */ + capture->av_codec_id = avctx->codec_id; + capture->av_pix_fmt = AV_PIX_FMT_NONE; + + ret = ff_v4l2_m2m_codec_init(avctx); + if (ret) { + av_log(avctx, AV_LOG_ERROR, "can't configure encoder\n"); + return ret; + } + + return v4l2_prepare_encoder(s); +} + +#define OFFSET(x) offsetof(V4L2m2mContext, x) +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM + +static const AVOption options[] = { + V4L_M2M_DEFAULT_OPTS, + { "num_capture_buffers", "Number of buffers in the capture context", + OFFSET(capture.num_buffers), AV_OPT_TYPE_INT, {.i64 = 4 }, 4, INT_MAX, FLAGS }, + { NULL }, +}; + +#define M2MENC(NAME, LONGNAME, CODEC) \ +static const AVClass v4l2_m2m_ ## NAME ## _enc_class = {\ + .class_name = #NAME "_v4l2_m2m_encoder",\ + .item_name = av_default_item_name,\ + .option = options,\ + .version = LIBAVUTIL_VERSION_INT,\ +};\ +\ +AVCodec ff_ ## NAME ## _v4l2m2m_encoder = { \ + .name = #NAME "_v4l2m2m" ,\ + .long_name = NULL_IF_CONFIG_SMALL("V4L2 mem2mem " LONGNAME " encoder wrapper"),\ + .type = AVMEDIA_TYPE_VIDEO,\ + .id = CODEC ,\ + .priv_data_size = sizeof(V4L2m2mContext),\ + .priv_class = &v4l2_m2m_ ## NAME ##_enc_class,\ + .init = v4l2_encode_init,\ + .send_frame = v4l2_send_frame,\ + .receive_packet = v4l2_receive_packet,\ + .close = ff_v4l2_m2m_codec_end,\ +}; + +M2MENC(mpeg4,"MPEG4", AV_CODEC_ID_MPEG4); +M2MENC(h263, "H.263", AV_CODEC_ID_H263); +M2MENC(h264, "H.264", AV_CODEC_ID_H264); +M2MENC(hevc, "HEVC", AV_CODEC_ID_HEVC); +M2MENC(vp8, "VP8", AV_CODEC_ID_VP8); From 2ad1768c7b48b6c77bbe9c42a4c2744f7b029182 Mon Sep 17 00:00:00 2001 From: Rostislav Pehlivanov Date: Sat, 23 Sep 2017 00:38:37 +0100 Subject: [PATCH 3144/3374] opusenc: implement a psychoacoustic system This commit implements a psychoacoustic system for the native Opus encoder. Its unlike any other psychoacoustic system known since its capable of using a lookahead to make better choices on how to treat the current frame and how many bits to allocate for it (and future frames). Also, whilst the main bulk of the analysis function has to run in a single thread, the per-frame anaylsis functions does not modify the main psychoacoustic context, so in the future it will be fairly trivial to run those as slice threads. Signed-off-by: Rostislav Pehlivanov --- libavcodec/Makefile | 3 +- libavcodec/opus_celt.h | 6 + libavcodec/opusenc.c | 270 +++++++++--------- libavcodec/opusenc.h | 56 ++++ libavcodec/opusenc_psy.c | 556 +++++++++++++++++++++++++++++++++++++ libavcodec/opusenc_psy.h | 104 +++++++ libavcodec/opusenc_utils.h | 82 ++++++ 7 files changed, 951 insertions(+), 126 deletions(-) create mode 100644 libavcodec/opusenc.h create mode 100644 libavcodec/opusenc_psy.c create mode 100644 libavcodec/opusenc_psy.h create mode 100644 libavcodec/opusenc_utils.h diff --git a/libavcodec/Makefile b/libavcodec/Makefile index fa0cb97a4dbe4..97969a085da6b 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -467,7 +467,8 @@ OBJS-$(CONFIG_NUV_DECODER) += nuv.o rtjpeg.o OBJS-$(CONFIG_ON2AVC_DECODER) += on2avc.o on2avcdata.o OBJS-$(CONFIG_OPUS_DECODER) += opusdec.o opus.o opus_celt.o opus_rc.o \ opus_pvq.o opus_silk.o opustab.o vorbis_data.o -OBJS-$(CONFIG_OPUS_ENCODER) += opusenc.o opus_rc.o opustab.o opus_pvq.o +OBJS-$(CONFIG_OPUS_ENCODER) += opusenc.o opus_rc.o opustab.o opus_pvq.o \ + opusenc_psy.o OBJS-$(CONFIG_PAF_AUDIO_DECODER) += pafaudio.o OBJS-$(CONFIG_PAF_VIDEO_DECODER) += pafvideo.o OBJS-$(CONFIG_PAM_DECODER) += pnmdec.o pnm.o diff --git a/libavcodec/opus_celt.h b/libavcodec/opus_celt.h index 31299912bd7eb..45d50ab27b9f2 100644 --- a/libavcodec/opus_celt.h +++ b/libavcodec/opus_celt.h @@ -120,6 +120,12 @@ struct CeltFrame { uint32_t seed; enum CeltSpread spread; + /* Encoder PF coeffs */ + int pf_octave; + int pf_period; + int pf_tapset; + float pf_gain; + /* Bit allocation */ int framebits; int remaining; diff --git a/libavcodec/opusenc.c b/libavcodec/opusenc.c index 8f2da4a7ba3cc..79d20dc6e693c 100644 --- a/libavcodec/opusenc.c +++ b/libavcodec/opusenc.c @@ -19,8 +19,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "opus_celt.h" +#include "opusenc.h" #include "opus_pvq.h" +#include "opusenc_psy.h" #include "opustab.h" #include "libavutil/float_dsp.h" @@ -29,28 +30,10 @@ #include "bytestream.h" #include "audio_frame_queue.h" -/* Determines the maximum delay the psychoacoustic system will use for lookahead */ -#define FF_BUFQUEUE_SIZE 145 -#include "libavfilter/bufferqueue.h" - -#define OPUS_MAX_LOOKAHEAD ((FF_BUFQUEUE_SIZE - 1)*2.5f) - -#define OPUS_MAX_CHANNELS 2 - -/* 120 ms / 2.5 ms = 48 frames (extremely improbable, but the encoder'll work) */ -#define OPUS_MAX_FRAMES_PER_PACKET 48 - -#define OPUS_BLOCK_SIZE(x) (2 * 15 * (1 << ((x) + 2))) - -#define OPUS_SAMPLES_TO_BLOCK_SIZE(x) (ff_log2((x) / (2 * 15)) - 2) - -typedef struct OpusEncOptions { - float max_delay_ms; -} OpusEncOptions; - typedef struct OpusEncContext { AVClass *av_class; OpusEncOptions options; + OpusPsyContext psyctx; AVCodecContext *avctx; AudioFrameQueue afq; AVFloatDSPContext *dsp; @@ -58,10 +41,10 @@ typedef struct OpusEncContext { CeltPVQ *pvq; struct FFBufQueue bufqueue; - enum OpusMode mode; - enum OpusBandwidth bandwidth; - int pkt_framesize; - int pkt_frames; + uint8_t enc_id[64]; + int enc_id_bits; + + OpusPacketInfo packet; int channels; @@ -100,18 +83,18 @@ static int opus_gen_toc(OpusEncContext *s, uint8_t *toc, int *size, int *fsize_n { { 3, 7, 11, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } }, /* 40 ms */ { { 4, 8, 12, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } }, /* 60 ms */ }; - int cfg = toc_cfg[s->pkt_framesize][s->mode][s->bandwidth]; + int cfg = toc_cfg[s->packet.framesize][s->packet.mode][s->packet.bandwidth]; *fsize_needed = 0; if (!cfg) return 1; - if (s->pkt_frames == 2) { /* 2 packets */ + if (s->packet.frames == 2) { /* 2 packets */ if (s->frame[0].framebits == s->frame[1].framebits) { /* same size */ tmp = 0x1; } else { /* different size */ tmp = 0x2; *fsize_needed = 1; /* put frame sizes in the packet */ } - } else if (s->pkt_frames > 2) { + } else if (s->packet.frames > 2) { tmp = 0x3; extended_toc = 1; } @@ -119,10 +102,11 @@ static int opus_gen_toc(OpusEncContext *s, uint8_t *toc, int *size, int *fsize_n tmp |= (cfg - 1) << 3; /* codec configuration */ *toc++ = tmp; if (extended_toc) { - for (i = 0; i < (s->pkt_frames - 1); i++) + for (i = 0; i < (s->packet.frames - 1); i++) *fsize_needed |= (s->frame[i].framebits != s->frame[i + 1].framebits); - tmp = (*fsize_needed) << 7; /* vbr flag */ - tmp |= s->pkt_frames; /* frame number - can be 0 as well */ + tmp = (*fsize_needed) << 7; /* vbr flag */ + tmp |= (0) << 6; /* padding flag */ + tmp |= s->packet.frames; *toc++ = tmp; } *size = 1 + extended_toc; @@ -134,7 +118,7 @@ static void celt_frame_setup_input(OpusEncContext *s, CeltFrame *f) int sf, ch; AVFrame *cur = NULL; const int subframesize = s->avctx->frame_size; - int subframes = OPUS_BLOCK_SIZE(s->pkt_framesize) / subframesize; + int subframes = OPUS_BLOCK_SIZE(s->packet.framesize) / subframesize; cur = ff_bufqueue_get(&s->bufqueue); @@ -174,7 +158,7 @@ static void celt_apply_preemph_filter(OpusEncContext *s, CeltFrame *f) { int i, sf, ch; const int subframesize = s->avctx->frame_size; - const int subframes = OPUS_BLOCK_SIZE(s->pkt_framesize) / subframesize; + const int subframes = OPUS_BLOCK_SIZE(s->packet.framesize) / subframesize; /* Filter overlap */ for (ch = 0; ch < f->channels; ch++) { @@ -207,7 +191,7 @@ static void celt_apply_preemph_filter(OpusEncContext *s, CeltFrame *f) /* Create the window and do the mdct */ static void celt_frame_mdct(OpusEncContext *s, CeltFrame *f) { - int t, ch; + int i, j, t, ch; float *win = s->scratch, *temp = s->scratch + 1920; if (f->transient) { @@ -245,12 +229,6 @@ static void celt_frame_mdct(OpusEncContext *s, CeltFrame *f) s->mdct[f->size]->mdct(s->mdct[f->size], b->coeffs, win, 1); } } -} - -/* Fills the bands and normalizes them */ -static void celt_frame_map_norm_bands(OpusEncContext *s, CeltFrame *f) -{ - int i, j, ch; for (ch = 0; ch < f->channels; ch++) { CeltBlock *block = &f->block[ch]; @@ -304,7 +282,7 @@ static void celt_enc_tf(OpusRangeCoder *rc, CeltFrame *f) f->tf_change[i] = ff_celt_tf_select[f->size][f->transient][tf_select][f->tf_change[i]]; } -static void ff_celt_enc_bitalloc(OpusRangeCoder *rc, CeltFrame *f) +void ff_celt_enc_bitalloc(OpusRangeCoder *rc, CeltFrame *f) { int i, j, low, high, total, done, bandbits, remaining, tbits_8ths; int skip_startband = f->start_band; @@ -324,6 +302,8 @@ static void ff_celt_enc_bitalloc(OpusRangeCoder *rc, CeltFrame *f) /* Tell the spread to the decoder */ if (opus_rc_tell(rc) + 4 <= f->framebits) ff_opus_rc_enc_cdf(rc, f->spread, ff_celt_model_spread); + else + f->spread = CELT_SPREAD_NORMAL; /* Generate static allocation caps */ for (i = 0; i < CELT_MAX_BANDS; i++) { @@ -629,6 +609,43 @@ static void ff_celt_enc_bitalloc(OpusRangeCoder *rc, CeltFrame *f) } } +static void celt_enc_quant_pfilter(OpusRangeCoder *rc, CeltFrame *f) +{ + float gain = f->pf_gain; + int i, txval, octave = f->pf_octave, period = f->pf_period, tapset = f->pf_tapset; + + ff_opus_rc_enc_log(rc, f->pfilter, 1); + if (!f->pfilter) + return; + + /* Octave */ + txval = FFMIN(octave, 6); + ff_opus_rc_enc_uint(rc, txval, 6); + octave = txval; + /* Period */ + txval = av_clip(period - (16 << octave) + 1, 0, (1 << (4 + octave)) - 1); + ff_opus_rc_put_raw(rc, period, 4 + octave); + period = txval + (16 << octave) - 1; + /* Gain */ + txval = FFMIN(((int)(gain / 0.09375f)) - 1, 7); + ff_opus_rc_put_raw(rc, txval, 3); + gain = 0.09375f * (txval + 1); + /* Tapset */ + if ((opus_rc_tell(rc) + 2) <= f->framebits) + ff_opus_rc_enc_cdf(rc, tapset, ff_celt_model_tapset); + else + tapset = 0; + /* Finally create the coeffs */ + for (i = 0; i < 2; i++) { + CeltBlock *block = &f->block[i]; + + block->pf_period_new = FFMAX(period, CELT_POSTFILTER_MINPERIOD); + block->pf_gains_new[0] = gain * ff_celt_postfilter_taps[tapset][0]; + block->pf_gains_new[1] = gain * ff_celt_postfilter_taps[tapset][1]; + block->pf_gains_new[2] = gain * ff_celt_postfilter_taps[tapset][2]; + } +} + static void exp_quant_coarse(OpusRangeCoder *rc, CeltFrame *f, float last_energy[][CELT_MAX_BANDS], int intra) { @@ -819,39 +836,64 @@ static void celt_quant_bands(OpusRangeCoder *rc, CeltFrame *f) } } -static void celt_encode_frame(OpusEncContext *s, OpusRangeCoder *rc, CeltFrame *f) +static void celt_encode_frame(OpusEncContext *s, OpusRangeCoder *rc, + CeltFrame *f, int index) { int i, ch; + ff_opus_rc_enc_init(rc); + + ff_opus_psy_celt_frame_init(&s->psyctx, f, index); + celt_frame_setup_input(s, f); + + if (f->silence) { + if (f->framebits >= 16) + ff_opus_rc_enc_log(rc, 1, 15); /* Silence (if using explicit singalling) */ + for (ch = 0; ch < s->channels; ch++) + memset(s->last_quantized_energy[ch], 0.0f, sizeof(float)*CELT_MAX_BANDS); + return; + } + + /* Filters */ celt_apply_preemph_filter(s, f); if (f->pfilter) { - /* Not implemented */ + ff_opus_rc_enc_log(rc, 0, 15); + celt_enc_quant_pfilter(rc, f); } + + /* Transform */ celt_frame_mdct(s, f); - celt_frame_map_norm_bands(s, f); - ff_opus_rc_enc_log(rc, f->silence, 15); + /* Need to handle transient/non-transient switches at any point during analysis */ + while (ff_opus_psy_celt_frame_process(&s->psyctx, f, index)) + celt_frame_mdct(s, f); - if (!f->start_band && opus_rc_tell(rc) + 16 <= f->framebits) - ff_opus_rc_enc_log(rc, f->pfilter, 1); + ff_opus_rc_enc_init(rc); - if (f->pfilter) { - /* Not implemented */ - } + /* Silence */ + ff_opus_rc_enc_log(rc, 0, 15); + + /* Pitch filter */ + if (!f->start_band && opus_rc_tell(rc) + 16 <= f->framebits) + celt_enc_quant_pfilter(rc, f); + /* Transient flag */ if (f->size && opus_rc_tell(rc) + 3 <= f->framebits) ff_opus_rc_enc_log(rc, f->transient, 3); + /* Main encoding */ celt_quant_coarse(rc, f, s->last_quantized_energy); celt_enc_tf (rc, f); ff_celt_enc_bitalloc(rc, f); celt_quant_fine (rc, f); celt_quant_bands (rc, f); + /* Anticollapse bit */ if (f->anticollapse_needed) ff_opus_rc_put_raw(rc, f->anticollapse, 1); + /* Final per-band energy adjustments from leftover bits */ celt_quant_final(s, rc, f); for (ch = 0; ch < f->channels; ch++) { @@ -861,49 +903,11 @@ static void celt_encode_frame(OpusEncContext *s, OpusRangeCoder *rc, CeltFrame * } } -static void ff_opus_psy_process(OpusEncContext *s, int end, int *need_more) +static inline int write_opuslacing(uint8_t *dst, int v) { - int max_delay_samples = (s->options.max_delay_ms*s->avctx->sample_rate)/1000; - int max_bsize = FFMIN(OPUS_SAMPLES_TO_BLOCK_SIZE(max_delay_samples), CELT_BLOCK_960); - - s->pkt_frames = 1; - s->pkt_framesize = max_bsize; - s->mode = OPUS_MODE_CELT; - s->bandwidth = OPUS_BANDWIDTH_FULLBAND; - - *need_more = s->bufqueue.available*s->avctx->frame_size < (max_delay_samples + CELT_OVERLAP); - /* Don't request more if we start being flushed with NULL frames */ - *need_more = !end && *need_more; -} - -static void ff_opus_psy_celt_frame_setup(OpusEncContext *s, CeltFrame *f, int index) -{ - int frame_size = OPUS_BLOCK_SIZE(s->pkt_framesize); - - f->avctx = s->avctx; - f->dsp = s->dsp; - f->pvq = s->pvq; - f->start_band = (s->mode == OPUS_MODE_HYBRID) ? 17 : 0; - f->end_band = ff_celt_band_end[s->bandwidth]; - f->channels = s->channels; - f->size = s->pkt_framesize; - - /* Decisions */ - f->silence = 0; - f->pfilter = 0; - f->transient = 0; - f->tf_select = 0; - f->anticollapse = 0; - f->alloc_trim = 5; - f->skip_band_floor = f->end_band; - f->intensity_stereo = f->end_band; - f->dual_stereo = 0; - f->spread = CELT_SPREAD_NORMAL; - memset(f->tf_change, 0, sizeof(int)*CELT_MAX_BANDS); - memset(f->alloc_boost, 0, sizeof(int)*CELT_MAX_BANDS); - - f->blocks = f->transient ? frame_size/CELT_OVERLAP : 1; - f->framebits = FFALIGN(lrintf((double)s->avctx->bit_rate/(s->avctx->sample_rate/frame_size)), 8); + dst[0] = FFMIN(v - FFALIGN(v - 255, 4), v); + dst[1] = v - dst[0] >> 2; + return 1 + (v >= 252); } static void opus_packet_assembler(OpusEncContext *s, AVPacket *avpkt) @@ -913,8 +917,18 @@ static void opus_packet_assembler(OpusEncContext *s, AVPacket *avpkt) /* Write toc */ opus_gen_toc(s, avpkt->data, &offset, &fsize_needed); - for (i = 0; i < s->pkt_frames; i++) { - ff_opus_rc_enc_end(&s->rc[i], avpkt->data + offset, s->frame[i].framebits >> 3); + /* Frame sizes if needed */ + if (fsize_needed) { + for (i = 0; i < s->packet.frames - 1; i++) { + offset += write_opuslacing(avpkt->data + offset, + s->frame[i].framebits >> 3); + } + } + + /* Packets */ + for (i = 0; i < s->packet.frames; i++) { + ff_opus_rc_enc_end(&s->rc[i], avpkt->data + offset, + s->frame[i].framebits >> 3); offset += s->frame[i].framebits >> 3; } @@ -946,29 +960,27 @@ static int opus_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr) { OpusEncContext *s = avctx->priv_data; - int i, ret, frame_size, need_more, alloc_size = 0; + int i, ret, frame_size, alloc_size = 0; if (frame) { /* Add new frame to queue */ if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) return ret; ff_bufqueue_add(avctx, &s->bufqueue, av_frame_clone(frame)); } else { + ff_opus_psy_signal_eof(&s->psyctx); if (!s->afq.remaining_samples) return 0; /* We've been flushed and there's nothing left to encode */ } /* Run the psychoacoustic system */ - ff_opus_psy_process(s, !frame, &need_more); - - /* Get more samples for lookahead/encoding */ - if (need_more) + if (ff_opus_psy_process(&s->psyctx, &s->packet)) return 0; - frame_size = OPUS_BLOCK_SIZE(s->pkt_framesize); + frame_size = OPUS_BLOCK_SIZE(s->packet.framesize); if (!frame) { /* This can go negative, that's not a problem, we only pad if positive */ - int pad_empty = s->pkt_frames*(frame_size/s->avctx->frame_size) - s->bufqueue.available + 1; + int pad_empty = s->packet.frames*(frame_size/s->avctx->frame_size) - s->bufqueue.available + 1; /* Pad with empty 2.5 ms frames to whatever framesize was decided, * this should only happen at the very last flush frame. The frames * allocated here will be freed (because they have no other references) @@ -981,15 +993,13 @@ static int opus_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, } } - for (i = 0; i < s->pkt_frames; i++) { - ff_opus_rc_enc_init(&s->rc[i]); - ff_opus_psy_celt_frame_setup(s, &s->frame[i], i); - celt_encode_frame(s, &s->rc[i], &s->frame[i]); + for (i = 0; i < s->packet.frames; i++) { + celt_encode_frame(s, &s->rc[i], &s->frame[i], i); alloc_size += s->frame[i].framebits >> 3; } /* Worst case toc + the frame lengths if needed */ - alloc_size += 2 + s->pkt_frames*2; + alloc_size += 2 + s->packet.frames*2; if ((ret = ff_alloc_packet2(avctx, avpkt, alloc_size, 0)) < 0) return ret; @@ -997,13 +1007,16 @@ static int opus_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, /* Assemble packet */ opus_packet_assembler(s, avpkt); + /* Update the psychoacoustic system */ + ff_opus_psy_postencode_update(&s->psyctx, s->frame, s->rc); + /* Remove samples from queue and skip if needed */ - ff_af_queue_remove(&s->afq, s->pkt_frames*frame_size, &avpkt->pts, &avpkt->duration); - if (s->pkt_frames*frame_size > avpkt->duration) { + ff_af_queue_remove(&s->afq, s->packet.frames*frame_size, &avpkt->pts, &avpkt->duration); + if (s->packet.frames*frame_size > avpkt->duration) { uint8_t *side = av_packet_new_side_data(avpkt, AV_PKT_DATA_SKIP_SAMPLES, 10); if (!side) return AVERROR(ENOMEM); - AV_WL32(&side[4], s->pkt_frames*frame_size - avpkt->duration + 120); + AV_WL32(&side[4], s->packet.frames*frame_size - avpkt->duration + 120); } *got_packet_ptr = 1; @@ -1024,6 +1037,7 @@ static av_cold int opus_encode_end(AVCodecContext *avctx) av_freep(&s->frame); av_freep(&s->rc); ff_af_queue_close(&s->afq); + ff_opus_psy_end(&s->psyctx); ff_bufqueue_discard_all(&s->bufqueue); av_freep(&avctx->extradata); @@ -1032,7 +1046,7 @@ static av_cold int opus_encode_end(AVCodecContext *avctx) static av_cold int opus_encode_init(AVCodecContext *avctx) { - int i, ch, ret; + int i, ch, ret, max_frames; OpusEncContext *s = avctx->priv_data; s->avctx = avctx; @@ -1057,14 +1071,6 @@ static av_cold int opus_encode_init(AVCodecContext *avctx) avctx->bit_rate = clipped_rate; } - /* Frame structs and range coder buffers */ - s->frame = av_malloc(OPUS_MAX_FRAMES_PER_PACKET*sizeof(CeltFrame)); - if (!s->frame) - return AVERROR(ENOMEM); - s->rc = av_malloc(OPUS_MAX_FRAMES_PER_PACKET*sizeof(OpusRangeCoder)); - if (!s->rc) - return AVERROR(ENOMEM); - /* Extradata */ avctx->extradata_size = 19; avctx->extradata = av_malloc(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); @@ -1085,27 +1091,41 @@ static av_cold int opus_encode_init(AVCodecContext *avctx) if ((ret = ff_mdct15_init(&s->mdct[i], 0, i + 3, 68 << (CELT_BLOCK_NB - 1 - i)))) return AVERROR(ENOMEM); - for (i = 0; i < OPUS_MAX_FRAMES_PER_PACKET; i++) { - s->frame[i].block[0].emph_coeff = s->frame[i].block[1].emph_coeff = 0.0f; - s->frame[i].seed = 0; - } - /* Zero out previous energy (matters for inter first frame) */ for (ch = 0; ch < s->channels; ch++) - for (i = 0; i < CELT_MAX_BANDS; i++) - s->last_quantized_energy[ch][i] = 0.0f; + memset(s->last_quantized_energy[ch], 0.0f, sizeof(float)*CELT_MAX_BANDS); /* Allocate an empty frame to use as overlap for the first frame of audio */ ff_bufqueue_add(avctx, &s->bufqueue, spawn_empty_frame(s)); if (!ff_bufqueue_peek(&s->bufqueue, 0)) return AVERROR(ENOMEM); + if ((ret = ff_opus_psy_init(&s->psyctx, s->avctx, &s->bufqueue, &s->options))) + return ret; + + /* Frame structs and range coder buffers */ + max_frames = ceilf(FFMIN(s->options.max_delay_ms, 120.0f)/2.5f); + s->frame = av_malloc(max_frames*sizeof(CeltFrame)); + if (!s->frame) + return AVERROR(ENOMEM); + s->rc = av_malloc(max_frames*sizeof(OpusRangeCoder)); + if (!s->rc) + return AVERROR(ENOMEM); + + for (i = 0; i < max_frames; i++) { + s->frame[i].dsp = s->dsp; + s->frame[i].avctx = s->avctx; + s->frame[i].seed = 0; + s->frame[i].pvq = s->pvq; + s->frame[i].block[0].emph_coeff = s->frame[i].block[1].emph_coeff = 0.0f; + } + return 0; } #define OPUSENC_FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM static const AVOption opusenc_options[] = { - { "opus_delay", "Maximum delay (and lookahead) in milliseconds", offsetof(OpusEncContext, options.max_delay_ms), AV_OPT_TYPE_FLOAT, { .dbl = OPUS_MAX_LOOKAHEAD }, 2.5f, OPUS_MAX_LOOKAHEAD, OPUSENC_FLAGS }, + { "opus_delay", "Maximum delay in milliseconds", offsetof(OpusEncContext, options.max_delay_ms), AV_OPT_TYPE_FLOAT, { .dbl = OPUS_MAX_LOOKAHEAD }, 2.5f, OPUS_MAX_LOOKAHEAD, OPUSENC_FLAGS, "max_delay_ms" }, { NULL }, }; diff --git a/libavcodec/opusenc.h b/libavcodec/opusenc.h new file mode 100644 index 0000000000000..3273d0a9a2a78 --- /dev/null +++ b/libavcodec/opusenc.h @@ -0,0 +1,56 @@ +/* + * Opus encoder + * Copyright (c) 2017 Rostislav Pehlivanov + * + * 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 + */ + +#ifndef AVCODEC_OPUSENC_H +#define AVCODEC_OPUSENC_H + +#include "internal.h" +#include "opus_celt.h" + +/* Determines the maximum delay the psychoacoustic system will use for lookahead */ +#define FF_BUFQUEUE_SIZE 145 +#include "libavfilter/bufferqueue.h" + +#define OPUS_MAX_LOOKAHEAD ((FF_BUFQUEUE_SIZE - 1)*2.5f) + +#define OPUS_MAX_CHANNELS 2 + +/* 120 ms / 2.5 ms = 48 frames (extremely improbable, but the encoder'll work) */ +#define OPUS_MAX_FRAMES_PER_PACKET 48 + +#define OPUS_BLOCK_SIZE(x) (2 * 15 * (1 << ((x) + 2))) + +#define OPUS_SAMPLES_TO_BLOCK_SIZE(x) (ff_log2((x) / (2 * 15)) - 2) + +typedef struct OpusEncOptions { + float max_delay_ms; +} OpusEncOptions; + +typedef struct OpusPacketInfo { + enum OpusMode mode; + enum OpusBandwidth bandwidth; + int framesize; + int frames; +} OpusPacketInfo; + +void ff_celt_enc_bitalloc(OpusRangeCoder *rc, CeltFrame *f); + +#endif /* AVCODEC_OPUSENC_H */ diff --git a/libavcodec/opusenc_psy.c b/libavcodec/opusenc_psy.c new file mode 100644 index 0000000000000..7c356fc56874a --- /dev/null +++ b/libavcodec/opusenc_psy.c @@ -0,0 +1,556 @@ +/* + * Opus encoder + * Copyright (c) 2017 Rostislav Pehlivanov + * + * 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 "opusenc_psy.h" +#include "opus_pvq.h" +#include "opustab.h" +#include "mdct15.h" +#include "libavutil/qsort.h" + +/* Populate metrics without taking into consideration neighbouring steps */ +static void step_collect_psy_metrics(OpusPsyContext *s, int index) +{ + int silence = 0, ch, i, j; + OpusPsyStep *st = s->steps[index]; + + st->index = index; + + for (ch = 0; ch < s->avctx->channels; ch++) { + const int lap_size = (1 << s->bsize_analysis); + for (i = 1; i <= FFMIN(lap_size, index); i++) { + const int offset = i*120; + AVFrame *cur = ff_bufqueue_peek(s->bufqueue, index - i); + memcpy(&s->scratch[offset], cur->extended_data[ch], cur->nb_samples*sizeof(float)); + } + for (i = 0; i < lap_size; i++) { + const int offset = i*120 + lap_size; + AVFrame *cur = ff_bufqueue_peek(s->bufqueue, index + i); + memcpy(&s->scratch[offset], cur->extended_data[ch], cur->nb_samples*sizeof(float)); + } + + s->dsp->vector_fmul(s->scratch, s->scratch, s->window[s->bsize_analysis], + (OPUS_BLOCK_SIZE(s->bsize_analysis) << 1)); + + s->mdct[s->bsize_analysis]->mdct(s->mdct[s->bsize_analysis], st->coeffs[ch], s->scratch, 1); + + for (i = 0; i < CELT_MAX_BANDS; i++) + st->bands[ch][i] = &st->coeffs[ch][ff_celt_freq_bands[i] << s->bsize_analysis]; + } + + for (ch = 0; ch < s->avctx->channels; ch++) { + for (i = 0; i < CELT_MAX_BANDS; i++) { + float avg_c_s, energy = 0.0f, dist_dev = 0.0f; + const int range = ff_celt_freq_range[i] << s->bsize_analysis; + const float *coeffs = st->bands[ch][i]; + for (j = 0; j < range; j++) + energy += coeffs[j]*coeffs[j]; + + st->energy[ch][i] += sqrtf(energy); + silence |= !!st->energy[ch][i]; + avg_c_s = energy / range; + + for (j = 0; j < range; j++) { + const float c_s = coeffs[j]*coeffs[j]; + dist_dev = (avg_c_s - c_s)*(avg_c_s - c_s); + } + + st->tone[ch][i] += sqrtf(dist_dev); + } + } + + st->silence = !silence; + + if (s->avctx->channels > 1) { + for (i = 0; i < CELT_MAX_BANDS; i++) { + float incompat = 0.0f; + const float *coeffs1 = st->bands[0][i]; + const float *coeffs2 = st->bands[1][i]; + const int range = ff_celt_freq_range[i] << s->bsize_analysis; + for (j = 0; j < range; j++) + incompat += (coeffs1[j] - coeffs2[j])*(coeffs1[j] - coeffs2[j]); + st->stereo[i] = sqrtf(incompat); + } + } + + for (ch = 0; ch < s->avctx->channels; ch++) { + for (i = 0; i < CELT_MAX_BANDS; i++) { + OpusBandExcitation *ex = &s->ex[ch][i]; + float bp_e = bessel_filter(&s->bfilter_lo[ch][i], st->energy[ch][i]); + bp_e = bessel_filter(&s->bfilter_hi[ch][i], bp_e); + bp_e *= bp_e; + if (bp_e > ex->excitation) { + st->change_amp[ch][i] = bp_e - ex->excitation; + st->total_change += st->change_amp[ch][i]; + ex->excitation = ex->excitation_init = bp_e; + ex->excitation_dist = 0.0f; + } + if (ex->excitation > 0.0f) { + ex->excitation -= av_clipf((1/expf(ex->excitation_dist)), ex->excitation_init/20, ex->excitation_init/1.09); + ex->excitation = FFMAX(ex->excitation, 0.0f); + ex->excitation_dist += 1.0f; + } + } + } +} + +static void search_for_change_points(OpusPsyContext *s, float tgt_change, + int offset_s, int offset_e, int resolution, + int level) +{ + int i; + float c_change = 0.0f; + if ((offset_e - offset_s) <= resolution) + return; + for (i = offset_s; i < offset_e; i++) { + c_change += s->steps[i]->total_change; + if (c_change > tgt_change) + break; + } + if (i == offset_e) + return; + search_for_change_points(s, tgt_change / 2.0f, offset_s, i + 0, resolution, level + 1); + s->inflection_points[s->inflection_points_count++] = i; + search_for_change_points(s, tgt_change / 2.0f, i + 1, offset_e, resolution, level + 1); +} + +static int flush_silent_frames(OpusPsyContext *s) +{ + int fsize, silent_frames; + + for (silent_frames = 0; silent_frames < s->buffered_steps; silent_frames++) + if (!s->steps[silent_frames]->silence) + break; + if (--silent_frames < 0) + return 0; + + for (fsize = CELT_BLOCK_960; fsize > CELT_BLOCK_120; fsize--) { + if ((1 << fsize) > silent_frames) + continue; + s->p.frames = FFMIN(silent_frames / (1 << fsize), 48 >> fsize); + s->p.framesize = fsize; + return 1; + } + + return 0; +} + +/* Main function which decides frame size and frames per current packet */ +static void psy_output_groups(OpusPsyContext *s) +{ + int max_delay_samples = (s->options->max_delay_ms*s->avctx->sample_rate)/1000; + int max_bsize = FFMIN(OPUS_SAMPLES_TO_BLOCK_SIZE(max_delay_samples), CELT_BLOCK_960); + + /* These don't change for now */ + s->p.mode = OPUS_MODE_CELT; + s->p.bandwidth = OPUS_BANDWIDTH_FULLBAND; + + /* Flush silent frames ASAP */ + if (s->steps[0]->silence && flush_silent_frames(s)) + return; + + s->p.framesize = FFMIN(max_bsize, CELT_BLOCK_960); + s->p.frames = 1; +} + +int ff_opus_psy_process(OpusPsyContext *s, OpusPacketInfo *p) +{ + int i; + float total_energy_change = 0.0f; + + if (s->buffered_steps < s->max_steps && !s->eof) { + const int awin = (1 << s->bsize_analysis); + if (++s->steps_to_process >= awin) { + step_collect_psy_metrics(s, s->buffered_steps - awin + 1); + s->steps_to_process = 0; + } + if ((++s->buffered_steps) < s->max_steps) + return 1; + } + + for (i = 0; i < s->buffered_steps; i++) + total_energy_change += s->steps[i]->total_change; + + search_for_change_points(s, total_energy_change / 2.0f, 0, + s->buffered_steps, 1, 0); + + psy_output_groups(s); + + p->frames = s->p.frames; + p->framesize = s->p.framesize; + p->mode = s->p.mode; + p->bandwidth = s->p.bandwidth; + + return 0; +} + +void ff_opus_psy_celt_frame_init(OpusPsyContext *s, CeltFrame *f, int index) +{ + int i, neighbouring_points = 0, start_offset = 0; + int radius = (1 << s->p.framesize), step_offset = radius*index; + int silence = 1; + + f->start_band = (s->p.mode == OPUS_MODE_HYBRID) ? 17 : 0; + f->end_band = ff_celt_band_end[s->p.bandwidth]; + f->channels = s->avctx->channels; + f->size = s->p.framesize; + + for (i = 0; i < (1 << f->size); i++) + silence &= s->steps[index*(1 << f->size) + i]->silence; + + f->silence = silence; + if (f->silence) { + f->framebits = 0; /* Otherwise the silence flag eats up 16(!) bits */ + return; + } + + for (i = 0; i < s->inflection_points_count; i++) { + if (s->inflection_points[i] >= step_offset) { + start_offset = i; + break; + } + } + + for (i = start_offset; i < FFMIN(radius, s->inflection_points_count - start_offset); i++) { + if (s->inflection_points[i] < (step_offset + radius)) { + neighbouring_points++; + } + } + + /* Transient flagging */ + f->transient = neighbouring_points > 0; + f->blocks = f->transient ? OPUS_BLOCK_SIZE(s->p.framesize)/CELT_OVERLAP : 1; + + /* Some sane defaults */ + f->pfilter = 0; + f->pf_gain = 0.5f; + f->pf_octave = 2; + f->pf_period = 1; + f->pf_tapset = 2; + + /* More sane defaults */ + f->tf_select = 0; + f->anticollapse = 1; + f->alloc_trim = 5; + f->skip_band_floor = f->end_band; + f->intensity_stereo = f->end_band; + f->dual_stereo = 0; + f->spread = CELT_SPREAD_NORMAL; + memset(f->tf_change, 0, sizeof(int)*CELT_MAX_BANDS); + memset(f->alloc_boost, 0, sizeof(int)*CELT_MAX_BANDS); +} + +static void celt_gauge_psy_weight(OpusPsyContext *s, OpusPsyStep **start, + CeltFrame *f_out) +{ + int i, f, ch; + int frame_size = OPUS_BLOCK_SIZE(s->p.framesize); + float rate, frame_bits = 0; + + /* Used for the global ROTATE flag */ + float tonal = 0.0f; + + /* Pseudo-weights */ + float band_score[CELT_MAX_BANDS] = { 0 }; + float max_score = 1.0f; + + /* Pass one - one loop around each band, computing unquant stuff */ + for (i = 0; i < CELT_MAX_BANDS; i++) { + float weight = 0.0f; + float tonal_contrib = 0.0f; + for (f = 0; f < (1 << s->p.framesize); f++) { + weight = start[f]->stereo[i]; + for (ch = 0; ch < s->avctx->channels; ch++) { + weight += start[f]->change_amp[ch][i] + start[f]->tone[ch][i] + start[f]->energy[ch][i]; + tonal_contrib += start[f]->tone[ch][i]; + } + } + tonal += tonal_contrib; + band_score[i] = weight; + } + + tonal /= (float)CELT_MAX_BANDS; + + for (i = 0; i < CELT_MAX_BANDS; i++) { + if (band_score[i] > max_score) + max_score = band_score[i]; + } + + for (i = 0; i < CELT_MAX_BANDS; i++) { + f_out->alloc_boost[i] = (int)((band_score[i]/max_score)*3.0f); + frame_bits += band_score[i]*8.0f; + } + + tonal /= 1333136.0f; + f_out->spread = av_clip(lrintf(tonal), 0, 3); + + rate = ((float)s->avctx->bit_rate) + frame_bits*frame_size*16; + rate *= s->lambda; + rate /= s->avctx->sample_rate/frame_size; + + f_out->framebits = lrintf(rate); + f_out->framebits = FFMIN(f_out->framebits, OPUS_MAX_PACKET_SIZE*8); + f_out->framebits = FFALIGN(f_out->framebits, 8); +} + +static int bands_dist(OpusPsyContext *s, CeltFrame *f, float *total_dist) +{ + int i, tdist = 0.0f; + OpusRangeCoder dump; + + ff_opus_rc_enc_init(&dump); + ff_celt_enc_bitalloc(&dump, f); + + for (i = 0; i < CELT_MAX_BANDS; i++) { + float bits = 0.0f; + float dist = f->pvq->band_cost(f->pvq, f, &dump, i, &bits, s->lambda); + tdist += dist; + } + + *total_dist = tdist; + + return 0; +} + +static void celt_search_for_dual_stereo(OpusPsyContext *s, CeltFrame *f) +{ + float td1, td2; + f->dual_stereo = 0; + bands_dist(s, f, &td1); + f->dual_stereo = 1; + bands_dist(s, f, &td2); + + f->dual_stereo = td2 < td1; + s->dual_stereo_used += td2 < td1; +} + +static void celt_search_for_intensity(OpusPsyContext *s, CeltFrame *f) +{ + int i, best_band = CELT_MAX_BANDS - 1; + float dist, best_dist = FLT_MAX; + + /* TODO: fix, make some heuristic up here using the lambda value */ + float end_band = 0; + + for (i = f->end_band; i >= end_band; i--) { + f->intensity_stereo = i; + bands_dist(s, f, &dist); + if (best_dist > dist) { + best_dist = dist; + best_band = i; + } + } + + f->intensity_stereo = best_band; + s->avg_is_band = (s->avg_is_band + f->intensity_stereo)/2.0f; +} + +static int celt_search_for_tf(OpusPsyContext *s, OpusPsyStep **start, CeltFrame *f) +{ + int i, j, k, cway, config[2][CELT_MAX_BANDS] = { { 0 } }; + float score[2] = { 0 }; + + for (cway = 0; cway < 2; cway++) { + int mag[2]; + int base = f->transient ? 120 : 960; + + for (int i = 0; i < 2; i++) { + int c = ff_celt_tf_select[f->size][f->transient][cway][i]; + mag[i] = c < 0 ? base >> FFABS(c) : base << FFABS(c); + } + + for (i = 0; i < CELT_MAX_BANDS; i++) { + float iscore0 = 0.0f; + float iscore1 = 0.0f; + for (j = 0; j < (1 << f->size); j++) { + for (k = 0; k < s->avctx->channels; k++) { + iscore0 += start[j]->tone[k][i]*start[j]->change_amp[k][i]/mag[0]; + iscore1 += start[j]->tone[k][i]*start[j]->change_amp[k][i]/mag[1]; + } + } + config[cway][i] = FFABS(iscore0 - 1.0f) < FFABS(iscore1 - 1.0f); + score[cway] += config[cway][i] ? iscore1 : iscore0; + } + } + + f->tf_select = score[0] < score[1]; + memcpy(f->tf_change, config[f->tf_select], sizeof(int)*CELT_MAX_BANDS); + + return 0; +} + +int ff_opus_psy_celt_frame_process(OpusPsyContext *s, CeltFrame *f, int index) +{ + int start_transient_flag = f->transient; + OpusPsyStep **start = &s->steps[index * (1 << s->p.framesize)]; + + if (f->silence) + return 0; + + celt_gauge_psy_weight(s, start, f); + celt_search_for_intensity(s, f); + celt_search_for_dual_stereo(s, f); + celt_search_for_tf(s, start, f); + + if (f->transient != start_transient_flag) { + f->blocks = f->transient ? OPUS_BLOCK_SIZE(s->p.framesize)/CELT_OVERLAP : 1; + s->redo_analysis = 1; + return 1; + } + + s->redo_analysis = 0; + + return 0; +} + +void ff_opus_psy_postencode_update(OpusPsyContext *s, CeltFrame *f, OpusRangeCoder *rc) +{ + int i, frame_size = OPUS_BLOCK_SIZE(s->p.framesize); + int steps_out = s->p.frames*(frame_size/120); + void *tmp[FF_BUFQUEUE_SIZE]; + float ideal_fbits; + + for (i = 0; i < steps_out; i++) + memset(s->steps[i], 0, sizeof(OpusPsyStep)); + + for (i = 0; i < s->max_steps; i++) + tmp[i] = s->steps[i]; + + for (i = 0; i < s->max_steps; i++) { + const int i_new = i - steps_out; + s->steps[i_new < 0 ? s->max_steps + i_new : i_new] = tmp[i]; + } + + for (i = steps_out; i < s->buffered_steps; i++) + s->steps[i]->index -= steps_out; + + ideal_fbits = s->avctx->bit_rate/(s->avctx->sample_rate/frame_size); + + for (i = 0; i < s->p.frames; i++) { + s->avg_is_band += f[i].intensity_stereo; + s->lambda *= ideal_fbits / f[i].framebits; + } + + s->avg_is_band /= (s->p.frames + 1); + + s->cs_num = 0; + s->steps_to_process = 0; + s->buffered_steps -= steps_out; + s->total_packets_out += s->p.frames; + s->inflection_points_count = 0; +} + +av_cold int ff_opus_psy_init(OpusPsyContext *s, AVCodecContext *avctx, + struct FFBufQueue *bufqueue, OpusEncOptions *options) +{ + int i, ch, ret; + + s->redo_analysis = 0; + s->lambda = 1.0f; + s->options = options; + s->avctx = avctx; + s->bufqueue = bufqueue; + s->max_steps = ceilf(s->options->max_delay_ms/2.5f); + s->bsize_analysis = CELT_BLOCK_960; + s->avg_is_band = CELT_MAX_BANDS - 1; + s->inflection_points_count = 0; + + s->inflection_points = av_mallocz(sizeof(*s->inflection_points)*s->max_steps); + if (!s->inflection_points) { + ret = AVERROR(ENOMEM); + goto fail; + } + + s->dsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); + if (!s->dsp) { + ret = AVERROR(ENOMEM); + goto fail; + } + + for (ch = 0; ch < s->avctx->channels; ch++) { + for (i = 0; i < CELT_MAX_BANDS; i++) { + bessel_init(&s->bfilter_hi[ch][i], 1.0f, 19.0f, 100.0f, 1); + bessel_init(&s->bfilter_lo[ch][i], 1.0f, 20.0f, 100.0f, 0); + } + } + + for (i = 0; i < s->max_steps; i++) { + s->steps[i] = av_mallocz(sizeof(OpusPsyStep)); + if (!s->steps[i]) { + ret = AVERROR(ENOMEM); + goto fail; + } + } + + for (i = 0; i < CELT_BLOCK_NB; i++) { + float tmp; + const int len = OPUS_BLOCK_SIZE(i); + s->window[i] = av_malloc(2*len*sizeof(float)); + if (!s->window[i]) { + ret = AVERROR(ENOMEM); + goto fail; + } + ff_generate_window_func(s->window[i], 2*len, WFUNC_SINE, &tmp); + if ((ret = ff_mdct15_init(&s->mdct[i], 0, i + 3, 68 << (CELT_BLOCK_NB - 1 - i)))) + goto fail; + } + + return 0; + +fail: + av_freep(&s->inflection_points); + av_freep(&s->dsp); + + for (i = 0; i < CELT_BLOCK_NB; i++) { + ff_mdct15_uninit(&s->mdct[i]); + av_freep(&s->window[i]); + } + + for (i = 0; i < s->max_steps; i++) + av_freep(&s->steps[i]); + + return ret; +} + +void ff_opus_psy_signal_eof(OpusPsyContext *s) +{ + s->eof = 1; +} + +av_cold int ff_opus_psy_end(OpusPsyContext *s) +{ + int i; + + av_freep(&s->inflection_points); + av_freep(&s->dsp); + + for (i = 0; i < CELT_BLOCK_NB; i++) { + ff_mdct15_uninit(&s->mdct[i]); + av_freep(&s->window[i]); + } + + for (i = 0; i < s->max_steps; i++) + av_freep(&s->steps[i]); + + av_log(s->avctx, AV_LOG_INFO, "Average Intensity Stereo band: %0.1f\n", s->avg_is_band); + av_log(s->avctx, AV_LOG_INFO, "Dual Stereo used: %0.2f%%\n", ((float)s->dual_stereo_used/s->total_packets_out)*100.0f); + + return 0; +} diff --git a/libavcodec/opusenc_psy.h b/libavcodec/opusenc_psy.h new file mode 100644 index 0000000000000..b91e4f1b8b989 --- /dev/null +++ b/libavcodec/opusenc_psy.h @@ -0,0 +1,104 @@ +/* + * Opus encoder + * Copyright (c) 2017 Rostislav Pehlivanov + * + * 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 + */ + +#ifndef AVCODEC_OPUSENC_PSY_H +#define AVCODEC_OPUSENC_PSY_H + +#include "opusenc.h" +#include "opusenc_utils.h" +#include "libavfilter/window_func.h" + +/* Each step is 2.5ms */ +typedef struct OpusPsyStep { + int index; /* Current index */ + int silence; + float energy[OPUS_MAX_CHANNELS][CELT_MAX_BANDS]; /* Masking effects included */ + float tone[OPUS_MAX_CHANNELS][CELT_MAX_BANDS]; /* Tonality */ + float stereo[CELT_MAX_BANDS]; /* IS/MS compatibility */ + float change_amp[OPUS_MAX_CHANNELS][CELT_MAX_BANDS]; /* Jump over last frame */ + float total_change; /* Total change */ + + float *bands[OPUS_MAX_CHANNELS][CELT_MAX_BANDS]; + float coeffs[OPUS_MAX_CHANNELS][OPUS_BLOCK_SIZE(CELT_BLOCK_960)]; +} OpusPsyStep; + +typedef struct OpusBandExcitation { + float excitation; + float excitation_dist; + float excitation_init; +} OpusBandExcitation; + +typedef struct PsyChain { + int start; + int end; +} PsyChain; + +typedef struct OpusPsyContext { + AVCodecContext *avctx; + AVFloatDSPContext *dsp; + struct FFBufQueue *bufqueue; + OpusEncOptions *options; + + PsyChain cs[128]; + int cs_num; + + OpusBandExcitation ex[OPUS_MAX_CHANNELS][CELT_MAX_BANDS]; + FFBesselFilter bfilter_lo[OPUS_MAX_CHANNELS][CELT_MAX_BANDS]; + FFBesselFilter bfilter_hi[OPUS_MAX_CHANNELS][CELT_MAX_BANDS]; + + OpusPsyStep *steps[FF_BUFQUEUE_SIZE + 1]; + int max_steps; + + float *window[CELT_BLOCK_NB]; + MDCT15Context *mdct[CELT_BLOCK_NB]; + int bsize_analysis; + + DECLARE_ALIGNED(32, float, scratch)[2048]; + + /* Stats */ + float rc_waste; + float avg_is_band; + int64_t dual_stereo_used; + int64_t total_packets_out; + + /* State */ + FFBesselFilter lambda_lp; + OpusPacketInfo p; + int redo_analysis; + int buffered_steps; + int steps_to_process; + int eof; + float lambda; + int *inflection_points; + int inflection_points_count; +} OpusPsyContext; + +int ff_opus_psy_process (OpusPsyContext *s, OpusPacketInfo *p); +void ff_opus_psy_celt_frame_init (OpusPsyContext *s, CeltFrame *f, int index); +int ff_opus_psy_celt_frame_process(OpusPsyContext *s, CeltFrame *f, int index); +void ff_opus_psy_postencode_update (OpusPsyContext *s, CeltFrame *f, OpusRangeCoder *rc); + +int ff_opus_psy_init(OpusPsyContext *s, AVCodecContext *avctx, + struct FFBufQueue *bufqueue, OpusEncOptions *options); +void ff_opus_psy_signal_eof(OpusPsyContext *s); +int ff_opus_psy_end(OpusPsyContext *s); + +#endif /* AVCODEC_OPUSENC_PSY_H */ diff --git a/libavcodec/opusenc_utils.h b/libavcodec/opusenc_utils.h new file mode 100644 index 0000000000000..8b9c5bffafc0a --- /dev/null +++ b/libavcodec/opusenc_utils.h @@ -0,0 +1,82 @@ +/* + * Opus encoder + * Copyright (c) 2017 Rostislav Pehlivanov + * + * 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 "opus.h" + +typedef struct FFBesselFilter { + float a[3]; + float b[2]; + float x[3]; + float y[3]; +} FFBesselFilter; + +/* Fills the coefficients, returns 1 if filter will be unstable */ +static inline int bessel_reinit(FFBesselFilter *s, float n, float f0, float fs, + int highpass) +{ + int unstable; + float c, cfreq, w0, k1, k2; + + if (!highpass) { + c = (1.0f/sqrtf(sqrtf(pow(2.0f, 1.0f/n) - 3.0f/4.0f) - 0.5f))/sqrtf(3.0f); + cfreq = c*f0/fs; + unstable = (cfreq <= 0.0f || cfreq >= 1.0f/4.0f); + } else { + c = sqrtf(3.0f)*sqrtf(sqrtf(pow(2.0f, 1.0f/n) - 3.0f/4.0f) - 0.5f); + cfreq = 0.5f - c*f0/fs; + unstable = (cfreq <= 3.0f/8.0f || cfreq >= 1.0f/2.0f); + } + + w0 = tanf(M_PI*cfreq); + k1 = 3.0f * w0; + k2 = 3.0f * w0; + + s->a[0] = k2/(1.0f + k1 + k2); + s->a[1] = 2.0f * s->a[0]; + s->a[2] = s->a[0]; + s->b[0] = 2.0f * s->a[0] * (1.0f/k2 - 1.0f); + s->b[1] = 1.0f - (s->a[0] + s->a[1] + s->a[2] + s->b[0]); + + if (highpass) { + s->a[1] *= -1; + s->b[0] *= -1; + } + + return unstable; +} + +static inline int bessel_init(FFBesselFilter *s, float n, float f0, float fs, + int highpass) +{ + memset(s, 0, sizeof(FFBesselFilter)); + return bessel_reinit(s, n, f0, fs, highpass); +} + +static inline float bessel_filter(FFBesselFilter *s, float x) +{ + s->x[2] = s->x[1]; + s->x[1] = s->x[0]; + s->x[0] = x; + s->y[2] = s->y[1]; + s->y[1] = s->y[0]; + s->y[0] = s->a[0]*s->x[0] + s->a[1]*s->x[1] + s->a[2]*s->x[2] + s->b[0]*s->y[1] + s->b[1]*s->y[2]; + return s->y[0]; +} From 039ebaa5f39ef45444f3cc42ab2ff71b0e9a1161 Mon Sep 17 00:00:00 2001 From: Rostislav Pehlivanov Date: Sat, 23 Sep 2017 14:21:22 +0100 Subject: [PATCH 3145/3374] lavfi: make window_func an inline function Eliminate lavc->lavfi dependency. The function isn't big and doesn't deserve its own file. Signed-off-by: Rostislav Pehlivanov --- libavcodec/opusenc_psy.c | 2 +- libavfilter/Makefile | 10 +- libavfilter/af_afftfilt.c | 2 +- libavfilter/avf_showfreqs.c | 2 +- libavfilter/avf_showspectrum.c | 2 +- libavfilter/vaf_spectrumsynth.c | 2 +- libavfilter/window_func.c | 178 -------------------------------- libavfilter/window_func.h | 158 +++++++++++++++++++++++++++- 8 files changed, 167 insertions(+), 189 deletions(-) delete mode 100644 libavfilter/window_func.c diff --git a/libavcodec/opusenc_psy.c b/libavcodec/opusenc_psy.c index 7c356fc56874a..e6858f1856113 100644 --- a/libavcodec/opusenc_psy.c +++ b/libavcodec/opusenc_psy.c @@ -507,7 +507,7 @@ av_cold int ff_opus_psy_init(OpusPsyContext *s, AVCodecContext *avctx, ret = AVERROR(ENOMEM); goto fail; } - ff_generate_window_func(s->window[i], 2*len, WFUNC_SINE, &tmp); + generate_window_func(s->window[i], 2*len, WFUNC_SINE, &tmp); if ((ret = ff_mdct15_init(&s->mdct[i], 0, i + 3, 68 << (CELT_BLOCK_NB - 1 - i)))) goto fail; } diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 98acb51bcbba8..9eeb7d218f0dd 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -37,7 +37,7 @@ OBJS-$(CONFIG_AECHO_FILTER) += af_aecho.o OBJS-$(CONFIG_AEMPHASIS_FILTER) += af_aemphasis.o OBJS-$(CONFIG_AEVAL_FILTER) += aeval.o OBJS-$(CONFIG_AFADE_FILTER) += af_afade.o -OBJS-$(CONFIG_AFFTFILT_FILTER) += af_afftfilt.o window_func.o +OBJS-$(CONFIG_AFFTFILT_FILTER) += af_afftfilt.o OBJS-$(CONFIG_AFIR_FILTER) += af_afir.o OBJS-$(CONFIG_AFORMAT_FILTER) += af_aformat.o OBJS-$(CONFIG_AGATE_FILTER) += af_agate.o @@ -369,13 +369,13 @@ OBJS-$(CONFIG_APHASEMETER_FILTER) += avf_aphasemeter.o OBJS-$(CONFIG_AVECTORSCOPE_FILTER) += avf_avectorscope.o OBJS-$(CONFIG_CONCAT_FILTER) += avf_concat.o OBJS-$(CONFIG_SHOWCQT_FILTER) += avf_showcqt.o lswsutils.o lavfutils.o -OBJS-$(CONFIG_SHOWFREQS_FILTER) += avf_showfreqs.o window_func.o -OBJS-$(CONFIG_SHOWSPECTRUM_FILTER) += avf_showspectrum.o window_func.o -OBJS-$(CONFIG_SHOWSPECTRUMPIC_FILTER) += avf_showspectrum.o window_func.o +OBJS-$(CONFIG_SHOWFREQS_FILTER) += avf_showfreqs.o +OBJS-$(CONFIG_SHOWSPECTRUM_FILTER) += avf_showspectrum.o +OBJS-$(CONFIG_SHOWSPECTRUMPIC_FILTER) += avf_showspectrum.o OBJS-$(CONFIG_SHOWVOLUME_FILTER) += avf_showvolume.o OBJS-$(CONFIG_SHOWWAVES_FILTER) += avf_showwaves.o OBJS-$(CONFIG_SHOWWAVESPIC_FILTER) += avf_showwaves.o -OBJS-$(CONFIG_SPECTRUMSYNTH_FILTER) += vaf_spectrumsynth.o window_func.o +OBJS-$(CONFIG_SPECTRUMSYNTH_FILTER) += vaf_spectrumsynth.o # multimedia sources OBJS-$(CONFIG_AMOVIE_FILTER) += src_movie.o diff --git a/libavfilter/af_afftfilt.c b/libavfilter/af_afftfilt.c index d166fa4190b38..52755a1fb42d3 100644 --- a/libavfilter/af_afftfilt.c +++ b/libavfilter/af_afftfilt.c @@ -166,7 +166,7 @@ static int config_input(AVFilterLink *inlink) sizeof(*s->window_func_lut)); if (!s->window_func_lut) return AVERROR(ENOMEM); - ff_generate_window_func(s->window_func_lut, s->window_size, s->win_func, &overlap); + generate_window_func(s->window_func_lut, s->window_size, s->win_func, &overlap); if (s->overlap == 1) s->overlap = overlap; diff --git a/libavfilter/avf_showfreqs.c b/libavfilter/avf_showfreqs.c index 068ff1fb88ecc..22f28ec387157 100644 --- a/libavfilter/avf_showfreqs.c +++ b/libavfilter/avf_showfreqs.c @@ -218,7 +218,7 @@ static int config_output(AVFilterLink *outlink) sizeof(*s->window_func_lut)); if (!s->window_func_lut) return AVERROR(ENOMEM); - ff_generate_window_func(s->window_func_lut, s->win_size, s->win_func, &overlap); + generate_window_func(s->window_func_lut, s->win_size, s->win_func, &overlap); if (s->overlap == 1.) s->overlap = overlap; s->hop_size = (1. - s->overlap) * s->win_size; diff --git a/libavfilter/avf_showspectrum.c b/libavfilter/avf_showspectrum.c index 4317161d7915b..956f62f3adba6 100644 --- a/libavfilter/avf_showspectrum.c +++ b/libavfilter/avf_showspectrum.c @@ -403,7 +403,7 @@ static int config_output(AVFilterLink *outlink) sizeof(*s->window_func_lut)); if (!s->window_func_lut) return AVERROR(ENOMEM); - ff_generate_window_func(s->window_func_lut, s->win_size, s->win_func, &overlap); + generate_window_func(s->window_func_lut, s->win_size, s->win_func, &overlap); if (s->overlap == 1) s->overlap = overlap; s->hop_size = (1. - s->overlap) * s->win_size; diff --git a/libavfilter/vaf_spectrumsynth.c b/libavfilter/vaf_spectrumsynth.c index ed191a3e34b96..fed2cbba030f6 100644 --- a/libavfilter/vaf_spectrumsynth.c +++ b/libavfilter/vaf_spectrumsynth.c @@ -210,7 +210,7 @@ static int config_output(AVFilterLink *outlink) sizeof(*s->window_func_lut)); if (!s->window_func_lut) return AVERROR(ENOMEM); - ff_generate_window_func(s->window_func_lut, s->win_size, s->win_func, &overlap); + generate_window_func(s->window_func_lut, s->win_size, s->win_func, &overlap); if (s->overlap == 1) s->overlap = overlap; s->hop_size = (1 - s->overlap) * s->win_size; diff --git a/libavfilter/window_func.c b/libavfilter/window_func.c deleted file mode 100644 index acf1b20847ca2..0000000000000 --- a/libavfilter/window_func.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2015 Paul B Mahol - * - * 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 - -#include "libavutil/avassert.h" -#include "window_func.h" - -void ff_generate_window_func(float *lut, int N, int win_func, float *overlap) -{ - int n; - - switch (win_func) { - case WFUNC_RECT: - for (n = 0; n < N; n++) - lut[n] = 1.; - *overlap = 0.; - break; - case WFUNC_BARTLETT: - for (n = 0; n < N; n++) - lut[n] = 1.-fabs((n-(N-1)/2.)/((N-1)/2.)); - *overlap = 0.5; - break; - case WFUNC_HANNING: - for (n = 0; n < N; n++) - lut[n] = .5*(1-cos(2*M_PI*n/(N-1))); - *overlap = 0.5; - break; - case WFUNC_HAMMING: - for (n = 0; n < N; n++) - lut[n] = .54-.46*cos(2*M_PI*n/(N-1)); - *overlap = 0.5; - break; - case WFUNC_BLACKMAN: - for (n = 0; n < N; n++) - lut[n] = .42659-.49656*cos(2*M_PI*n/(N-1))+.076849*cos(4*M_PI*n/(N-1)); - *overlap = 0.661; - break; - case WFUNC_WELCH: - for (n = 0; n < N; n++) - lut[n] = 1.-(n-(N-1)/2.)/((N-1)/2.)*(n-(N-1)/2.)/((N-1)/2.); - *overlap = 0.293; - break; - case WFUNC_FLATTOP: - for (n = 0; n < N; n++) - lut[n] = 1.-1.985844164102*cos( 2*M_PI*n/(N-1))+1.791176438506*cos( 4*M_PI*n/(N-1))- - 1.282075284005*cos( 6*M_PI*n/(N-1))+0.667777530266*cos( 8*M_PI*n/(N-1))- - 0.240160796576*cos(10*M_PI*n/(N-1))+0.056656381764*cos(12*M_PI*n/(N-1))- - 0.008134974479*cos(14*M_PI*n/(N-1))+0.000624544650*cos(16*M_PI*n/(N-1))- - 0.000019808998*cos(18*M_PI*n/(N-1))+0.000000132974*cos(20*M_PI*n/(N-1)); - *overlap = 0.841; - break; - case WFUNC_BHARRIS: - for (n = 0; n < N; n++) - lut[n] = 0.35875-0.48829*cos(2*M_PI*n/(N-1))+0.14128*cos(4*M_PI*n/(N-1))-0.01168*cos(6*M_PI*n/(N-1)); - *overlap = 0.661; - break; - case WFUNC_BNUTTALL: - for (n = 0; n < N; n++) - lut[n] = 0.3635819-0.4891775*cos(2*M_PI*n/(N-1))+0.1365995*cos(4*M_PI*n/(N-1))-0.0106411*cos(6*M_PI*n/(N-1)); - *overlap = 0.661; - break; - case WFUNC_BHANN: - for (n = 0; n < N; n++) - lut[n] = 0.62-0.48*fabs(n/(double)(N-1)-.5)-0.38*cos(2*M_PI*n/(N-1)); - *overlap = 0.5; - break; - case WFUNC_SINE: - for (n = 0; n < N; n++) - lut[n] = sin(M_PI*n/(N-1)); - *overlap = 0.75; - break; - case WFUNC_NUTTALL: - for (n = 0; n < N; n++) - lut[n] = 0.355768-0.487396*cos(2*M_PI*n/(N-1))+0.144232*cos(4*M_PI*n/(N-1))-0.012604*cos(6*M_PI*n/(N-1)); - *overlap = 0.663; - break; - case WFUNC_LANCZOS: -#define SINC(x) (!(x)) ? 1 : sin(M_PI * (x))/(M_PI * (x)); - for (n = 0; n < N; n++) - lut[n] = SINC((2.*n)/(N-1)-1); - *overlap = 0.75; - break; - case WFUNC_GAUSS: -#define SQR(x) ((x)*(x)) - for (n = 0; n < N; n++) - lut[n] = exp(-0.5 * SQR((n-(N-1)/2)/(0.4*(N-1)/2.f))); - *overlap = 0.75; - break; - case WFUNC_TUKEY: - for (n = 0; n < N; n++) { - float M = (N-1)/2.; - - if (FFABS(n - M) >= 0.3 * M) { - lut[n] = 0.5 * (1 + cos((M_PI*(FFABS(n - M) - 0.3 * M))/((1 - 0.3) * M))); - } else { - lut[n] = 1; - } - } - *overlap = 0.33; - break; - case WFUNC_DOLPH: { - double b = cosh(7.6009022095419887 / (N-1)), sum, t, c, norm = 0; - int j; - for (c = 1 - 1 / (b*b), n = (N-1) / 2; n >= 0; --n) { - for (sum = !n, b = t = j = 1; j <= n && sum != t; b *= (n-j) * (1./j), ++j) - t = sum, sum += (b *= c * (N - n - j) * (1./j)); - sum /= (N - 1 - n), sum /= (norm = norm ? norm : sum); - lut[n] = sum; - lut[N - 1 - n] = sum; - } - *overlap = 0.5;} - break; - case WFUNC_CAUCHY: - for (n = 0; n < N; n++) { - double x = 2 * ((n / (double)(N - 1)) - .5); - - if (x <= -.5 || x >= .5) { - lut[n] = 0; - } else { - lut[n] = FFMIN(1, fabs(1/(1+4*16*x*x))); - } - } - *overlap = 0.75; - break; - case WFUNC_PARZEN: - for (n = 0; n < N; n++) { - double x = 2 * ((n / (double)(N - 1)) - .5); - - if (x > 0.25 && x <= 0.5) { - lut[n] = -2 * powf(-1 + 2 * x, 3); - } else if (x >= -.5 && x < -.25) { - lut[n] = 2 * powf(1 + 2 * x, 3); - } else if (x >= -.25 && x < 0) { - lut[n] = 1 - 24 * x * x - 48 * x * x * x; - } else if (x >= 0 && x <= .25) { - lut[n] = 1 - 24 * x * x + 48 * x * x * x; - } else { - lut[n] = 0; - } - } - *overlap = 0.75; - break; - case WFUNC_POISSON: - for (n = 0; n < N; n++) { - double x = 2 * ((n / (double)(N - 1)) - .5); - - if (x >= 0 && x <= .5) { - lut[n] = exp(-6*x); - } else if (x < 0 && x >= -.5) { - lut[n] = exp(6*x); - } else { - lut[n] = 0; - } - } - *overlap = 0.75; - break; - default: - av_assert0(0); - } -} diff --git a/libavfilter/window_func.h b/libavfilter/window_func.h index 4611498d47bde..a94482c937942 100644 --- a/libavfilter/window_func.h +++ b/libavfilter/window_func.h @@ -22,6 +22,9 @@ #ifndef AVFILTER_WINDOW_FUNC_H #define AVFILTER_WINDOW_FUNC_H +#include +#include "libavutil/avassert.h" + enum WindowFunc { WFUNC_RECT, WFUNC_HANNING, WFUNC_HAMMING, WFUNC_BLACKMAN, WFUNC_BARTLETT, WFUNC_WELCH, WFUNC_FLATTOP, WFUNC_BHARRIS, WFUNC_BNUTTALL, WFUNC_SINE, WFUNC_NUTTALL, @@ -29,6 +32,159 @@ enum WindowFunc { WFUNC_RECT, WFUNC_HANNING, WFUNC_HAMMING, WFUNC_BLACKMAN, WFUNC_DOLPH, WFUNC_CAUCHY, WFUNC_PARZEN, WFUNC_POISSON, NB_WFUNC }; -void ff_generate_window_func(float *lut, int N, int win_func, float *overlap); +static inline void generate_window_func(float *lut, int N, int win_func, + float *overlap) +{ + int n; + + switch (win_func) { + case WFUNC_RECT: + for (n = 0; n < N; n++) + lut[n] = 1.; + *overlap = 0.; + break; + case WFUNC_BARTLETT: + for (n = 0; n < N; n++) + lut[n] = 1.-fabs((n-(N-1)/2.)/((N-1)/2.)); + *overlap = 0.5; + break; + case WFUNC_HANNING: + for (n = 0; n < N; n++) + lut[n] = .5*(1-cos(2*M_PI*n/(N-1))); + *overlap = 0.5; + break; + case WFUNC_HAMMING: + for (n = 0; n < N; n++) + lut[n] = .54-.46*cos(2*M_PI*n/(N-1)); + *overlap = 0.5; + break; + case WFUNC_BLACKMAN: + for (n = 0; n < N; n++) + lut[n] = .42659-.49656*cos(2*M_PI*n/(N-1))+.076849*cos(4*M_PI*n/(N-1)); + *overlap = 0.661; + break; + case WFUNC_WELCH: + for (n = 0; n < N; n++) + lut[n] = 1.-(n-(N-1)/2.)/((N-1)/2.)*(n-(N-1)/2.)/((N-1)/2.); + *overlap = 0.293; + break; + case WFUNC_FLATTOP: + for (n = 0; n < N; n++) + lut[n] = 1.-1.985844164102*cos( 2*M_PI*n/(N-1))+1.791176438506*cos( 4*M_PI*n/(N-1))- + 1.282075284005*cos( 6*M_PI*n/(N-1))+0.667777530266*cos( 8*M_PI*n/(N-1))- + 0.240160796576*cos(10*M_PI*n/(N-1))+0.056656381764*cos(12*M_PI*n/(N-1))- + 0.008134974479*cos(14*M_PI*n/(N-1))+0.000624544650*cos(16*M_PI*n/(N-1))- + 0.000019808998*cos(18*M_PI*n/(N-1))+0.000000132974*cos(20*M_PI*n/(N-1)); + *overlap = 0.841; + break; + case WFUNC_BHARRIS: + for (n = 0; n < N; n++) + lut[n] = 0.35875-0.48829*cos(2*M_PI*n/(N-1))+0.14128*cos(4*M_PI*n/(N-1))-0.01168*cos(6*M_PI*n/(N-1)); + *overlap = 0.661; + break; + case WFUNC_BNUTTALL: + for (n = 0; n < N; n++) + lut[n] = 0.3635819-0.4891775*cos(2*M_PI*n/(N-1))+0.1365995*cos(4*M_PI*n/(N-1))-0.0106411*cos(6*M_PI*n/(N-1)); + *overlap = 0.661; + break; + case WFUNC_BHANN: + for (n = 0; n < N; n++) + lut[n] = 0.62-0.48*fabs(n/(double)(N-1)-.5)-0.38*cos(2*M_PI*n/(N-1)); + *overlap = 0.5; + break; + case WFUNC_SINE: + for (n = 0; n < N; n++) + lut[n] = sin(M_PI*n/(N-1)); + *overlap = 0.75; + break; + case WFUNC_NUTTALL: + for (n = 0; n < N; n++) + lut[n] = 0.355768-0.487396*cos(2*M_PI*n/(N-1))+0.144232*cos(4*M_PI*n/(N-1))-0.012604*cos(6*M_PI*n/(N-1)); + *overlap = 0.663; + break; + case WFUNC_LANCZOS: + #define SINC(x) (!(x)) ? 1 : sin(M_PI * (x))/(M_PI * (x)); + for (n = 0; n < N; n++) + lut[n] = SINC((2.*n)/(N-1)-1); + *overlap = 0.75; + break; + case WFUNC_GAUSS: + #define SQR(x) ((x)*(x)) + for (n = 0; n < N; n++) + lut[n] = exp(-0.5 * SQR((n-(N-1)/2)/(0.4*(N-1)/2.f))); + *overlap = 0.75; + break; + case WFUNC_TUKEY: + for (n = 0; n < N; n++) { + float M = (N-1)/2.; + + if (FFABS(n - M) >= 0.3 * M) { + lut[n] = 0.5 * (1 + cos((M_PI*(FFABS(n - M) - 0.3 * M))/((1 - 0.3) * M))); + } else { + lut[n] = 1; + } + } + *overlap = 0.33; + break; + case WFUNC_DOLPH: { + double b = cosh(7.6009022095419887 / (N-1)), sum, t, c, norm = 0; + int j; + for (c = 1 - 1 / (b*b), n = (N-1) / 2; n >= 0; --n) { + for (sum = !n, b = t = j = 1; j <= n && sum != t; b *= (n-j) * (1./j), ++j) + t = sum, sum += (b *= c * (N - n - j) * (1./j)); + sum /= (N - 1 - n), sum /= (norm = norm ? norm : sum); + lut[n] = sum; + lut[N - 1 - n] = sum; + } + *overlap = 0.5;} + break; + case WFUNC_CAUCHY: + for (n = 0; n < N; n++) { + double x = 2 * ((n / (double)(N - 1)) - .5); + + if (x <= -.5 || x >= .5) { + lut[n] = 0; + } else { + lut[n] = FFMIN(1, fabs(1/(1+4*16*x*x))); + } + } + *overlap = 0.75; + break; + case WFUNC_PARZEN: + for (n = 0; n < N; n++) { + double x = 2 * ((n / (double)(N - 1)) - .5); + + if (x > 0.25 && x <= 0.5) { + lut[n] = -2 * powf(-1 + 2 * x, 3); + } else if (x >= -.5 && x < -.25) { + lut[n] = 2 * powf(1 + 2 * x, 3); + } else if (x >= -.25 && x < 0) { + lut[n] = 1 - 24 * x * x - 48 * x * x * x; + } else if (x >= 0 && x <= .25) { + lut[n] = 1 - 24 * x * x + 48 * x * x * x; + } else { + lut[n] = 0; + } + } + *overlap = 0.75; + break; + case WFUNC_POISSON: + for (n = 0; n < N; n++) { + double x = 2 * ((n / (double)(N - 1)) - .5); + + if (x >= 0 && x <= .5) { + lut[n] = exp(-6*x); + } else if (x < 0 && x >= -.5) { + lut[n] = exp(6*x); + } else { + lut[n] = 0; + } + } + *overlap = 0.75; + break; + default: + av_assert0(0); + } +} #endif /* AVFILTER_WINDOW_FUNC_H */ From b8eaecbf39a59fce256ee5ffa7c51dd44c83bec1 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 23 Sep 2017 13:22:51 -0300 Subject: [PATCH 3146/3374] avcodec/opusenc_utils: add missing preprocessor guards Fixes fate-source. Signed-off-by: James Almer --- libavcodec/opusenc_utils.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/opusenc_utils.h b/libavcodec/opusenc_utils.h index 8b9c5bffafc0a..be82e137672c7 100644 --- a/libavcodec/opusenc_utils.h +++ b/libavcodec/opusenc_utils.h @@ -19,6 +19,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifndef AVCODEC_OPUSENC_UTILS_H +#define AVCODEC_OPUSENC_UTILS_H + #include "opus.h" typedef struct FFBesselFilter { @@ -80,3 +83,5 @@ static inline float bessel_filter(FFBesselFilter *s, float x) s->y[0] = s->a[0]*s->x[0] + s->a[1]*s->x[1] + s->a[2]*s->x[2] + s->b[0]*s->y[1] + s->b[1]*s->y[2]; return s->y[0]; } + +#endif /* AVCODEC_OPUSENC_UTILS_H */ From e4fd7b1fea7e2d3306f159d285ea420a1f250dcc Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 23 Sep 2017 13:23:27 -0300 Subject: [PATCH 3147/3374] avcodec/opusenc_psy: use av_clip_uintp2() Fixes fate-source. Signed-off-by: James Almer --- libavcodec/opusenc_psy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/opusenc_psy.c b/libavcodec/opusenc_psy.c index e6858f1856113..bb673bef68ad1 100644 --- a/libavcodec/opusenc_psy.c +++ b/libavcodec/opusenc_psy.c @@ -299,7 +299,7 @@ static void celt_gauge_psy_weight(OpusPsyContext *s, OpusPsyStep **start, } tonal /= 1333136.0f; - f_out->spread = av_clip(lrintf(tonal), 0, 3); + f_out->spread = av_clip_uintp2(lrintf(tonal), 2); rate = ((float)s->avctx->bit_rate) + frame_bits*frame_size*16; rate *= s->lambda; From 7f80b065a626f3214ad90039c45efa390099572c Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Thu, 7 Sep 2017 16:09:13 +0200 Subject: [PATCH 3148/3374] avformat/mxfdec: factorize packet pts setter function Signed-off-by: Marton Balint --- libavformat/mxfdec.c | 52 ++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 91731a7533c15..3e2f5011ee427 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -3060,6 +3060,32 @@ static int mxf_set_audio_pts(MXFContext *mxf, AVCodecParameters *par, return 0; } +static int mxf_set_pts(MXFContext *mxf, AVStream *st, AVPacket *pkt, int64_t next_ofs) +{ + AVCodecParameters *par = st->codecpar; + MXFTrack *track = st->priv_data; + + if (par->codec_type == AVMEDIA_TYPE_VIDEO && next_ofs >= 0) { + /* mxf->current_edit_unit good - see if we have an + * index table to derive timestamps from */ + MXFIndexTable *t = &mxf->index_tables[0]; + + if (mxf->nb_index_tables >= 1 && mxf->current_edit_unit < t->nb_ptses) { + pkt->dts = mxf->current_edit_unit + t->first_dts; + pkt->pts = t->ptses[mxf->current_edit_unit]; + } else if (track && track->intra_only) { + /* intra-only -> PTS = EditUnit. + * let utils.c figure out DTS since it can be < PTS if low_delay = 0 (Sony IMX30) */ + pkt->pts = mxf->current_edit_unit; + } + } else if (par->codec_type == AVMEDIA_TYPE_AUDIO) { + int ret = mxf_set_audio_pts(mxf, par, pkt); + if (ret < 0) + return ret; + } + return 0; +} + static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt) { KLVPacket klv; @@ -3083,8 +3109,6 @@ static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt) int index = mxf_get_stream_index(s, &klv); int64_t next_ofs, next_klv; AVStream *st; - MXFTrack *track; - AVCodecParameters *par; if (index < 0) { av_log(s, AV_LOG_ERROR, @@ -3094,7 +3118,6 @@ static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt) } st = s->streams[index]; - track = st->priv_data; if (s->streams[index]->discard == AVDISCARD_ALL) goto skip; @@ -3129,26 +3152,9 @@ static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt) pkt->stream_index = index; pkt->pos = klv.offset; - par = st->codecpar; - - if (par->codec_type == AVMEDIA_TYPE_VIDEO && next_ofs >= 0) { - /* mxf->current_edit_unit good - see if we have an - * index table to derive timestamps from */ - MXFIndexTable *t = &mxf->index_tables[0]; - - if (mxf->nb_index_tables >= 1 && mxf->current_edit_unit < t->nb_ptses) { - pkt->dts = mxf->current_edit_unit + t->first_dts; - pkt->pts = t->ptses[mxf->current_edit_unit]; - } else if (track && track->intra_only) { - /* intra-only -> PTS = EditUnit. - * let utils.c figure out DTS since it can be < PTS if low_delay = 0 (Sony IMX30) */ - pkt->pts = mxf->current_edit_unit; - } - } else if (par->codec_type == AVMEDIA_TYPE_AUDIO) { - ret = mxf_set_audio_pts(mxf, par, pkt); - if (ret < 0) - return ret; - } + ret = mxf_set_pts(mxf, st, pkt, next_ofs); + if (ret < 0) + return ret; /* seek for truncated packets */ avio_seek(s->pb, next_klv, SEEK_SET); From 01911b9b3cad85ff1c346165659c0181db661b3e Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Thu, 7 Sep 2017 16:17:59 +0200 Subject: [PATCH 3149/3374] avformat/mxfdec: use the common packet pts setter function for opatom files Fixes ticket #6631. Signed-off-by: Marton Balint --- libavformat/mxfdec.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 3e2f5011ee427..476d284c96718 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -3217,15 +3217,9 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt) pkt->stream_index = st->index; - if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && t->ptses && - mxf->current_edit_unit >= 0 && mxf->current_edit_unit < t->nb_ptses) { - pkt->dts = mxf->current_edit_unit + t->first_dts; - pkt->pts = t->ptses[mxf->current_edit_unit]; - } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { - int ret = mxf_set_audio_pts(mxf, st->codecpar, pkt); - if (ret < 0) - return ret; - } + ret = mxf_set_pts(mxf, st, pkt, next_pos); + if (ret < 0) + return ret; mxf->current_edit_unit += edit_units; From 58ca446672fec10e851b820ce7df64bd2d1f3a70 Mon Sep 17 00:00:00 2001 From: Thomas Mundt Date: Mon, 18 Sep 2017 23:57:17 +0200 Subject: [PATCH 3150/3374] avfilter/tinterlace: use drawutils for pad mode Reviewed-by: Michael Niedermayer Signed-off-by: Thomas Mundt Signed-off-by: James Almer --- libavfilter/tinterlace.h | 3 +++ libavfilter/vf_tinterlace.c | 16 +++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/libavfilter/tinterlace.h b/libavfilter/tinterlace.h index 7f50d3c8ee169..cc13a6cc50aba 100644 --- a/libavfilter/tinterlace.h +++ b/libavfilter/tinterlace.h @@ -28,6 +28,7 @@ #define AVFILTER_TINTERLACE_H #include "libavutil/opt.h" +#include "drawutils.h" #include "avfilter.h" #define TINTERLACE_FLAG_VLPF 01 @@ -57,6 +58,8 @@ typedef struct TInterlaceContext { AVFrame *next; uint8_t *black_data[4]; ///< buffer used to fill padded lines int black_linesize[4]; + FFDrawContext draw; + FFDrawColor color; void (*lowpass_line)(uint8_t *dstp, ptrdiff_t width, const uint8_t *srcp, ptrdiff_t mref, ptrdiff_t pref); } TInterlaceContext; diff --git a/libavfilter/vf_tinterlace.c b/libavfilter/vf_tinterlace.c index 9ae9daafc151e..f934a06b6994d 100644 --- a/libavfilter/vf_tinterlace.c +++ b/libavfilter/vf_tinterlace.c @@ -156,21 +156,19 @@ static int config_out_props(AVFilterLink *outlink) av_make_q(2, 1)); if (tinterlace->mode == MODE_PAD) { - uint8_t black[4] = { 16, 128, 128, 16 }; - int i, ret; + uint8_t black[4] = { 0, 0, 0, 16 }; + int ret; + ff_draw_init(&tinterlace->draw, outlink->format, 0); + ff_draw_color(&tinterlace->draw, &tinterlace->color, black); if (ff_fmt_is_in(outlink->format, full_scale_yuvj_pix_fmts)) - black[0] = black[3] = 0; + tinterlace->color.comp[0].u8[0] = 0; ret = av_image_alloc(tinterlace->black_data, tinterlace->black_linesize, outlink->w, outlink->h, outlink->format, 16); if (ret < 0) return ret; - /* fill black picture with black */ - for (i = 0; i < 4 && tinterlace->black_data[i]; i++) { - int h = i == 1 || i == 2 ? AV_CEIL_RSHIFT(outlink->h, desc->log2_chroma_h) : outlink->h; - memset(tinterlace->black_data[i], black[i], - tinterlace->black_linesize[i] * h); - } + ff_fill_rectangle(&tinterlace->draw, &tinterlace->color, tinterlace->black_data, + tinterlace->black_linesize, 0, 0, outlink->w, outlink->h); } if (tinterlace->flags & (TINTERLACE_FLAG_VLPF | TINTERLACE_FLAG_CVLPF) && !(tinterlace->mode == MODE_INTERLEAVE_TOP From 40bfaa190c61b6eeff1b76b767c12edd6609967d Mon Sep 17 00:00:00 2001 From: Thomas Mundt Date: Tue, 19 Sep 2017 22:23:23 +0200 Subject: [PATCH 3151/3374] avfilter/interlace: add support for 10 and 12 bit Reviewed-by: Michael Niedermayer Signed-off-by: Thomas Mundt Signed-off-by: James Almer --- libavfilter/interlace.h | 5 +- libavfilter/tinterlace.h | 5 +- libavfilter/vf_interlace.c | 97 ++++++++++++++++--- libavfilter/vf_tinterlace.c | 78 ++++++++++++++- libavfilter/x86/vf_interlace.asm | 80 +++++++++++++-- libavfilter/x86/vf_interlace_init.c | 51 +++++++--- libavfilter/x86/vf_tinterlace_init.c | 51 +++++++--- .../ref/fate/filter-pixfmts-tinterlace_cvlpf | 11 +++ .../ref/fate/filter-pixfmts-tinterlace_merge | 11 +++ tests/ref/fate/filter-pixfmts-tinterlace_pad | 11 +++ tests/ref/fate/filter-pixfmts-tinterlace_vlpf | 11 +++ 11 files changed, 355 insertions(+), 56 deletions(-) diff --git a/libavfilter/interlace.h b/libavfilter/interlace.h index 2101b79939640..90a0198bdc4aa 100644 --- a/libavfilter/interlace.h +++ b/libavfilter/interlace.h @@ -25,9 +25,11 @@ #ifndef AVFILTER_INTERLACE_H #define AVFILTER_INTERLACE_H +#include "libavutil/bswap.h" #include "libavutil/common.h" #include "libavutil/imgutils.h" #include "libavutil/opt.h" +#include "libavutil/pixdesc.h" #include "avfilter.h" #include "formats.h" @@ -55,8 +57,9 @@ typedef struct InterlaceContext { enum ScanMode scan; // top or bottom field first scanning int lowpass; // enable or disable low pass filtering AVFrame *cur, *next; // the two frames from which the new one is obtained + const AVPixFmtDescriptor *csp; void (*lowpass_line)(uint8_t *dstp, ptrdiff_t linesize, const uint8_t *srcp, - ptrdiff_t mref, ptrdiff_t pref); + ptrdiff_t mref, ptrdiff_t pref, int clip_max); } InterlaceContext; void ff_interlace_init_x86(InterlaceContext *interlace); diff --git a/libavfilter/tinterlace.h b/libavfilter/tinterlace.h index cc13a6cc50aba..b5c39aac522e4 100644 --- a/libavfilter/tinterlace.h +++ b/libavfilter/tinterlace.h @@ -27,7 +27,9 @@ #ifndef AVFILTER_TINTERLACE_H #define AVFILTER_TINTERLACE_H +#include "libavutil/bswap.h" #include "libavutil/opt.h" +#include "libavutil/pixdesc.h" #include "drawutils.h" #include "avfilter.h" @@ -60,8 +62,9 @@ typedef struct TInterlaceContext { int black_linesize[4]; FFDrawContext draw; FFDrawColor color; + const AVPixFmtDescriptor *csp; void (*lowpass_line)(uint8_t *dstp, ptrdiff_t width, const uint8_t *srcp, - ptrdiff_t mref, ptrdiff_t pref); + ptrdiff_t mref, ptrdiff_t pref, int clip_max); } TInterlaceContext; void ff_tinterlace_init_x86(TInterlaceContext *interlace); diff --git a/libavfilter/vf_interlace.c b/libavfilter/vf_interlace.c index 55bf782af8daa..0fdfe70f4c8be 100644 --- a/libavfilter/vf_interlace.c +++ b/libavfilter/vf_interlace.c @@ -61,8 +61,8 @@ static const AVOption interlace_options[] = { AVFILTER_DEFINE_CLASS(interlace); static void lowpass_line_c(uint8_t *dstp, ptrdiff_t linesize, - const uint8_t *srcp, - ptrdiff_t mref, ptrdiff_t pref) + const uint8_t *srcp, ptrdiff_t mref, + ptrdiff_t pref, int clip_max) { const uint8_t *srcp_above = srcp + mref; const uint8_t *srcp_below = srcp + pref; @@ -75,9 +75,28 @@ static void lowpass_line_c(uint8_t *dstp, ptrdiff_t linesize, } } +static void lowpass_line_c_16(uint8_t *dst8, ptrdiff_t linesize, + const uint8_t *src8, ptrdiff_t mref, + ptrdiff_t pref, int clip_max) +{ + uint16_t *dstp = (uint16_t *)dst8; + const uint16_t *srcp = (const uint16_t *)src8; + const uint16_t *srcp_above = srcp + mref / 2; + const uint16_t *srcp_below = srcp + pref / 2; + int i, src_x; + for (i = 0; i < linesize; i++) { + // this calculation is an integer representation of + // '0.5 * current + 0.25 * above + 0.25 * below' + // '1 +' is for rounding. + src_x = av_le2ne16(srcp[i]) << 1; + dstp[i] = av_le2ne16((1 + src_x + av_le2ne16(srcp_above[i]) + + av_le2ne16(srcp_below[i])) >> 2); + } +} + static void lowpass_line_complex_c(uint8_t *dstp, ptrdiff_t linesize, - const uint8_t *srcp, - ptrdiff_t mref, ptrdiff_t pref) + const uint8_t *srcp, ptrdiff_t mref, + ptrdiff_t pref, int clip_max) { const uint8_t *srcp_above = srcp + mref; const uint8_t *srcp_below = srcp + pref; @@ -103,11 +122,51 @@ static void lowpass_line_complex_c(uint8_t *dstp, ptrdiff_t linesize, } } +static void lowpass_line_complex_c_16(uint8_t *dst8, ptrdiff_t linesize, + const uint8_t *src8, ptrdiff_t mref, + ptrdiff_t pref, int clip_max) +{ + uint16_t *dstp = (uint16_t *)dst8; + const uint16_t *srcp = (const uint16_t *)src8; + const uint16_t *srcp_above = srcp + mref / 2; + const uint16_t *srcp_below = srcp + pref / 2; + const uint16_t *srcp_above2 = srcp + mref; + const uint16_t *srcp_below2 = srcp + pref; + int i, dst_le, src_le, src_x, src_ab; + for (i = 0; i < linesize; i++) { + // this calculation is an integer representation of + // '0.75 * current + 0.25 * above + 0.25 * below - 0.125 * above2 - 0.125 * below2' + // '4 +' is for rounding. + src_le = av_le2ne16(srcp[i]); + src_x = src_le << 1; + src_ab = av_le2ne16(srcp_above[i]) + av_le2ne16(srcp_below[i]); + dst_le = av_clip((4 + ((src_le + src_x + src_ab) << 1) + - av_le2ne16(srcp_above2[i]) + - av_le2ne16(srcp_below2[i])) >> 3, 0, clip_max); + // Prevent over-sharpening: + // dst must not exceed src when the average of above and below + // is less than src. And the other way around. + if (src_ab > src_x) { + if (dst_le < src_le) + dstp[i] = av_le2ne16(src_le); + else + dstp[i] = av_le2ne16(dst_le); + } else if (dst_le > src_le) { + dstp[i] = av_le2ne16(src_le); + } else + dstp[i] = av_le2ne16(dst_le); + } +} + static const enum AVPixelFormat formats_supported[] = { - AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, - AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUVA420P, - AV_PIX_FMT_GRAY8, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, - AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_NONE + AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUV420P10LE, AV_PIX_FMT_YUV422P10LE, AV_PIX_FMT_YUV444P10LE, + AV_PIX_FMT_YUV420P12LE, AV_PIX_FMT_YUV422P12LE, AV_PIX_FMT_YUV444P12LE, + AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, + AV_PIX_FMT_YUVA420P10LE, AV_PIX_FMT_YUVA422P10LE, AV_PIX_FMT_YUVA444P10LE, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, + AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_NONE }; static int query_formats(AVFilterContext *ctx) @@ -150,12 +209,19 @@ static int config_out_props(AVFilterLink *outlink) outlink->time_base.num *= 2; outlink->frame_rate.den *= 2; - + s->csp = av_pix_fmt_desc_get(outlink->format); if (s->lowpass) { - if (s->lowpass == VLPF_LIN) - s->lowpass_line = lowpass_line_c; - else if (s->lowpass == VLPF_CMP) - s->lowpass_line = lowpass_line_complex_c; + if (s->lowpass == VLPF_LIN) { + if (s->csp->comp[0].depth > 8) + s->lowpass_line = lowpass_line_c_16; + else + s->lowpass_line = lowpass_line_c; + } else if (s->lowpass == VLPF_CMP) { + if (s->csp->comp[0].depth > 8) + s->lowpass_line = lowpass_line_complex_c_16; + else + s->lowpass_line = lowpass_line_complex_c; + } if (ARCH_X86) ff_interlace_init_x86(s); } @@ -183,6 +249,7 @@ static void copy_picture_field(InterlaceContext *s, const uint8_t *srcp = src_frame->data[plane]; int srcp_linesize = src_frame->linesize[plane] * 2; int dstp_linesize = dst_frame->linesize[plane] * 2; + int clip_max = (1 << s->csp->comp[plane].depth) - 1; av_assert0(cols >= 0 || lines >= 0); @@ -202,11 +269,13 @@ static void copy_picture_field(InterlaceContext *s, mref = 0; else if (j <= (1 + x)) pref = 0; - s->lowpass_line(dstp, cols, srcp, mref, pref); + s->lowpass_line(dstp, cols, srcp, mref, pref, clip_max); dstp += dstp_linesize; srcp += srcp_linesize; } } else { + if (s->csp->comp[plane].depth > 8) + cols *= 2; av_image_copy_plane(dstp, dstp_linesize, srcp, srcp_linesize, cols, lines); } } diff --git a/libavfilter/vf_tinterlace.c b/libavfilter/vf_tinterlace.c index f934a06b6994d..163ab7c18460e 100644 --- a/libavfilter/vf_tinterlace.c +++ b/libavfilter/vf_tinterlace.c @@ -78,7 +78,12 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUV420P10LE, AV_PIX_FMT_YUV422P10LE, + AV_PIX_FMT_YUV440P10LE, AV_PIX_FMT_YUV444P10LE, + AV_PIX_FMT_YUV420P12LE, AV_PIX_FMT_YUV422P12LE, + AV_PIX_FMT_YUV440P12LE, AV_PIX_FMT_YUV444P12LE, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, + AV_PIX_FMT_YUVA420P10LE, AV_PIX_FMT_YUVA422P10LE, AV_PIX_FMT_YUVA444P10LE, AV_PIX_FMT_GRAY8, FULL_SCALE_YUVJ_FORMATS, AV_PIX_FMT_NONE }; @@ -90,7 +95,7 @@ static int query_formats(AVFilterContext *ctx) } static void lowpass_line_c(uint8_t *dstp, ptrdiff_t width, const uint8_t *srcp, - ptrdiff_t mref, ptrdiff_t pref) + ptrdiff_t mref, ptrdiff_t pref, int clip_max) { const uint8_t *srcp_above = srcp + mref; const uint8_t *srcp_below = srcp + pref; @@ -103,8 +108,26 @@ static void lowpass_line_c(uint8_t *dstp, ptrdiff_t width, const uint8_t *srcp, } } +static void lowpass_line_c_16(uint8_t *dst8, ptrdiff_t width, const uint8_t *src8, + ptrdiff_t mref, ptrdiff_t pref, int clip_max) +{ + uint16_t *dstp = (uint16_t *)dst8; + const uint16_t *srcp = (const uint16_t *)src8; + const uint16_t *srcp_above = srcp + mref / 2; + const uint16_t *srcp_below = srcp + pref / 2; + int i, src_x; + for (i = 0; i < width; i++) { + // this calculation is an integer representation of + // '0.5 * current + 0.25 * above + 0.25 * below' + // '1 +' is for rounding. + src_x = av_le2ne16(srcp[i]) << 1; + dstp[i] = av_le2ne16((1 + src_x + av_le2ne16(srcp_above[i]) + + av_le2ne16(srcp_below[i])) >> 2); + } +} + static void lowpass_line_complex_c(uint8_t *dstp, ptrdiff_t width, const uint8_t *srcp, - ptrdiff_t mref, ptrdiff_t pref) + ptrdiff_t mref, ptrdiff_t pref, int clip_max) { const uint8_t *srcp_above = srcp + mref; const uint8_t *srcp_below = srcp + pref; @@ -130,6 +153,41 @@ static void lowpass_line_complex_c(uint8_t *dstp, ptrdiff_t width, const uint8_t } } +static void lowpass_line_complex_c_16(uint8_t *dst8, ptrdiff_t width, const uint8_t *src8, + ptrdiff_t mref, ptrdiff_t pref, int clip_max) +{ + uint16_t *dstp = (uint16_t *)dst8; + const uint16_t *srcp = (const uint16_t *)src8; + const uint16_t *srcp_above = srcp + mref / 2; + const uint16_t *srcp_below = srcp + pref / 2; + const uint16_t *srcp_above2 = srcp + mref; + const uint16_t *srcp_below2 = srcp + pref; + int i, dst_le, src_le, src_x, src_ab; + for (i = 0; i < width; i++) { + // this calculation is an integer representation of + // '0.75 * current + 0.25 * above + 0.25 * below - 0.125 * above2 - 0.125 * below2' + // '4 +' is for rounding. + src_le = av_le2ne16(srcp[i]); + src_x = src_le << 1; + src_ab = av_le2ne16(srcp_above[i]) + av_le2ne16(srcp_below[i]); + dst_le = av_clip((4 + ((src_le + src_x + src_ab) << 1) + - av_le2ne16(srcp_above2[i]) + - av_le2ne16(srcp_below2[i])) >> 3, 0, clip_max); + // Prevent over-sharpening: + // dst must not exceed src when the average of above and below + // is less than src. And the other way around. + if (src_ab > src_x) { + if (dst_le < src_le) + dstp[i] = av_le2ne16(src_le); + else + dstp[i] = av_le2ne16(dst_le); + } else if (dst_le > src_le) { + dstp[i] = av_le2ne16(src_le); + } else + dstp[i] = av_le2ne16(dst_le); + } +} + static av_cold void uninit(AVFilterContext *ctx) { TInterlaceContext *tinterlace = ctx->priv; @@ -198,12 +256,19 @@ static int config_out_props(AVFilterLink *outlink) (tinterlace->flags & TINTERLACE_FLAG_EXACT_TB)) outlink->time_base = tinterlace->preout_time_base; + tinterlace->csp = av_pix_fmt_desc_get(outlink->format); if (tinterlace->flags & TINTERLACE_FLAG_CVLPF) { - tinterlace->lowpass_line = lowpass_line_complex_c; + if (tinterlace->csp->comp[0].depth > 8) + tinterlace->lowpass_line = lowpass_line_complex_c_16; + else + tinterlace->lowpass_line = lowpass_line_complex_c; if (ARCH_X86) ff_tinterlace_init_x86(tinterlace); } else if (tinterlace->flags & TINTERLACE_FLAG_VLPF) { - tinterlace->lowpass_line = lowpass_line_c; + if (tinterlace->csp->comp[0].depth > 8) + tinterlace->lowpass_line = lowpass_line_c_16; + else + tinterlace->lowpass_line = lowpass_line_c; if (ARCH_X86) ff_tinterlace_init_x86(tinterlace); } @@ -250,6 +315,7 @@ void copy_picture_field(TInterlaceContext *tinterlace, const uint8_t *srcp = src[plane]; int srcp_linesize = src_linesize[plane] * k; int dstp_linesize = dst_linesize[plane] * (interleave ? 2 : 1); + int clip_max = (1 << tinterlace->csp->comp[plane].depth) - 1; lines = (lines + (src_field == FIELD_UPPER)) / k; if (src_field == FIELD_LOWER) @@ -267,11 +333,13 @@ void copy_picture_field(TInterlaceContext *tinterlace, if (h >= (lines - x)) mref = 0; // there is no line above else if (h <= (1 + x)) pref = 0; // there is no line below - tinterlace->lowpass_line(dstp, cols, srcp, mref, pref); + tinterlace->lowpass_line(dstp, cols, srcp, mref, pref, clip_max); dstp += dstp_linesize; srcp += srcp_linesize; } } else { + if (tinterlace->csp->comp[plane].depth > 8) + cols *= 2; av_image_copy_plane(dstp, dstp_linesize, srcp, srcp_linesize, cols, lines); } } diff --git a/libavfilter/x86/vf_interlace.asm b/libavfilter/x86/vf_interlace.asm index d0fffd293bede..7c0065d4d9489 100644 --- a/libavfilter/x86/vf_interlace.asm +++ b/libavfilter/x86/vf_interlace.asm @@ -30,27 +30,26 @@ pw_4: times 8 dw 4 SECTION .text -%macro LOWPASS_LINE 0 -cglobal lowpass_line, 5, 5, 7, dst, h, src, mref, pref +%macro LOWPASS 1 add dstq, hq add srcq, hq add mrefq, srcq add prefq, srcq neg hq - pcmpeqb m6, m6 + pcmpeq%1 m6, m6 .loop: mova m0, [mrefq+hq] mova m1, [mrefq+hq+mmsize] - pavgb m0, [prefq+hq] - pavgb m1, [prefq+hq+mmsize] + pavg%1 m0, [prefq+hq] + pavg%1 m1, [prefq+hq+mmsize] pxor m0, m6 pxor m1, m6 pxor m2, m6, [srcq+hq] pxor m3, m6, [srcq+hq+mmsize] - pavgb m0, m2 - pavgb m1, m3 + pavg%1 m0, m2 + pavg%1 m1, m3 pxor m0, m6 pxor m1, m6 mova [dstq+hq], m0 @@ -59,7 +58,15 @@ cglobal lowpass_line, 5, 5, 7, dst, h, src, mref, pref add hq, 2*mmsize jl .loop REP_RET +%endmacro + +%macro LOWPASS_LINE 0 +cglobal lowpass_line, 5, 5, 7, dst, h, src, mref, pref + LOWPASS b +cglobal lowpass_line_16, 5, 5, 7, dst, h, src, mref, pref + shl hq, 1 + LOWPASS w %endmacro %macro LOWPASS_LINE_COMPLEX 0 @@ -124,6 +131,65 @@ cglobal lowpass_line_complex, 5, 5, 8, dst, h, src, mref, pref jg .loop REP_RET +cglobal lowpass_line_complex_12, 5, 5, 8, 16, dst, h, src, mref, pref, clip_max + movd m7, DWORD clip_maxm + SPLATW m7, m7, 0 + mova [rsp], m7 +.loop: + mova m0, [srcq+mrefq] + mova m1, [srcq+mrefq+mmsize] + mova m2, [srcq+prefq] + mova m3, [srcq+prefq+mmsize] + paddw m0, m2 + paddw m1, m3 + mova m6, m0 + mova m7, m1 + mova m2, [srcq] + mova m3, [srcq+mmsize] + paddw m0, m2 + paddw m1, m3 + psllw m2, 1 + psllw m3, 1 + paddw m0, m2 + paddw m1, m3 + psllw m0, 1 + psllw m1, 1 + pcmpgtw m6, m2 + pcmpgtw m7, m3 + mova m2, [srcq+2*mrefq] + mova m3, [srcq+2*mrefq+mmsize] + mova m4, [srcq+2*prefq] + mova m5, [srcq+2*prefq+mmsize] + paddw m2, m4 + paddw m3, m5 + paddw m0, [pw_4] + paddw m1, [pw_4] + psubusw m0, m2 + psubusw m1, m3 + psrlw m0, 3 + psrlw m1, 3 + pminsw m0, [rsp] + pminsw m1, [rsp] + mova m2, m0 + mova m3, m1 + pmaxsw m0, [srcq] + pmaxsw m1, [srcq+mmsize] + pminsw m2, [srcq] + pminsw m3, [srcq+mmsize] + pand m0, m6 + pand m1, m7 + pandn m6, m2 + pandn m7, m3 + por m0, m6 + por m1, m7 + mova [dstq], m0 + mova [dstq+mmsize], m1 + + add dstq, 2*mmsize + add srcq, 2*mmsize + sub hd, mmsize + jg .loop +REP_RET %endmacro INIT_XMM sse2 diff --git a/libavfilter/x86/vf_interlace_init.c b/libavfilter/x86/vf_interlace_init.c index c0f04dcd978da..70fe86ccff046 100644 --- a/libavfilter/x86/vf_interlace_init.c +++ b/libavfilter/x86/vf_interlace_init.c @@ -27,27 +27,50 @@ #include "libavfilter/interlace.h" void ff_lowpass_line_sse2(uint8_t *dstp, ptrdiff_t linesize, - const uint8_t *srcp, - ptrdiff_t mref, ptrdiff_t pref); + const uint8_t *srcp, ptrdiff_t mref, + ptrdiff_t pref, int clip_max); void ff_lowpass_line_avx (uint8_t *dstp, ptrdiff_t linesize, - const uint8_t *srcp, - ptrdiff_t mref, ptrdiff_t pref); + const uint8_t *srcp, ptrdiff_t mref, + ptrdiff_t pref, int clip_max); + +void ff_lowpass_line_16_sse2(uint8_t *dstp, ptrdiff_t linesize, + const uint8_t *srcp, ptrdiff_t mref, + ptrdiff_t pref, int clip_max); +void ff_lowpass_line_16_avx (uint8_t *dstp, ptrdiff_t linesize, + const uint8_t *srcp, ptrdiff_t mref, + ptrdiff_t pref, int clip_max); void ff_lowpass_line_complex_sse2(uint8_t *dstp, ptrdiff_t linesize, - const uint8_t *srcp, - ptrdiff_t mref, ptrdiff_t pref); + const uint8_t *srcp, ptrdiff_t mref, + ptrdiff_t pref, int clip_max); + +void ff_lowpass_line_complex_12_sse2(uint8_t *dstp, ptrdiff_t linesize, + const uint8_t *srcp, ptrdiff_t mref, + ptrdiff_t pref, int clip_max); av_cold void ff_interlace_init_x86(InterlaceContext *s) { int cpu_flags = av_get_cpu_flags(); - if (EXTERNAL_SSE2(cpu_flags)) { - if (s->lowpass == VLPF_LIN) - s->lowpass_line = ff_lowpass_line_sse2; - else if (s->lowpass == VLPF_CMP) - s->lowpass_line = ff_lowpass_line_complex_sse2; + if (s->csp->comp[0].depth > 8) { + if (EXTERNAL_SSE2(cpu_flags)) { + if (s->lowpass == VLPF_LIN) + s->lowpass_line = ff_lowpass_line_16_sse2; + else if (s->lowpass == VLPF_CMP) + s->lowpass_line = ff_lowpass_line_complex_12_sse2; + } + if (EXTERNAL_AVX(cpu_flags)) + if (s->lowpass == VLPF_LIN) + s->lowpass_line = ff_lowpass_line_16_avx; + } else { + if (EXTERNAL_SSE2(cpu_flags)) { + if (s->lowpass == VLPF_LIN) + s->lowpass_line = ff_lowpass_line_sse2; + else if (s->lowpass == VLPF_CMP) + s->lowpass_line = ff_lowpass_line_complex_sse2; + } + if (EXTERNAL_AVX(cpu_flags)) + if (s->lowpass == VLPF_LIN) + s->lowpass_line = ff_lowpass_line_avx; } - if (EXTERNAL_AVX(cpu_flags)) - if (s->lowpass == VLPF_LIN) - s->lowpass_line = ff_lowpass_line_avx; } diff --git a/libavfilter/x86/vf_tinterlace_init.c b/libavfilter/x86/vf_tinterlace_init.c index 2b10e1b74c3bf..209812964d0ed 100644 --- a/libavfilter/x86/vf_tinterlace_init.c +++ b/libavfilter/x86/vf_tinterlace_init.c @@ -28,27 +28,50 @@ #include "libavfilter/tinterlace.h" void ff_lowpass_line_sse2(uint8_t *dstp, ptrdiff_t linesize, - const uint8_t *srcp, - ptrdiff_t mref, ptrdiff_t pref); + const uint8_t *srcp, ptrdiff_t mref, + ptrdiff_t pref, int clip_max); void ff_lowpass_line_avx (uint8_t *dstp, ptrdiff_t linesize, - const uint8_t *srcp, - ptrdiff_t mref, ptrdiff_t pref); + const uint8_t *srcp, ptrdiff_t mref, + ptrdiff_t pref, int clip_max); + +void ff_lowpass_line_16_sse2(uint8_t *dstp, ptrdiff_t linesize, + const uint8_t *srcp, ptrdiff_t mref, + ptrdiff_t pref, int clip_max); +void ff_lowpass_line_16_avx (uint8_t *dstp, ptrdiff_t linesize, + const uint8_t *srcp, ptrdiff_t mref, + ptrdiff_t pref, int clip_max); void ff_lowpass_line_complex_sse2(uint8_t *dstp, ptrdiff_t linesize, - const uint8_t *srcp, - ptrdiff_t mref, ptrdiff_t pref); + const uint8_t *srcp, ptrdiff_t mref, + ptrdiff_t pref, int clip_max); + +void ff_lowpass_line_complex_12_sse2(uint8_t *dstp, ptrdiff_t linesize, + const uint8_t *srcp, ptrdiff_t mref, + ptrdiff_t pref, int clip_max); av_cold void ff_tinterlace_init_x86(TInterlaceContext *s) { int cpu_flags = av_get_cpu_flags(); - if (EXTERNAL_SSE2(cpu_flags)) { - if (!(s->flags & TINTERLACE_FLAG_CVLPF)) - s->lowpass_line = ff_lowpass_line_sse2; - else - s->lowpass_line = ff_lowpass_line_complex_sse2; + if (s->csp->comp[0].depth > 8) { + if (EXTERNAL_SSE2(cpu_flags)) { + if (!(s->flags & TINTERLACE_FLAG_CVLPF)) + s->lowpass_line = ff_lowpass_line_16_sse2; + else + s->lowpass_line = ff_lowpass_line_complex_12_sse2; + } + if (EXTERNAL_AVX(cpu_flags)) + if (!(s->flags & TINTERLACE_FLAG_CVLPF)) + s->lowpass_line = ff_lowpass_line_16_avx; + } else { + if (EXTERNAL_SSE2(cpu_flags)) { + if (!(s->flags & TINTERLACE_FLAG_CVLPF)) + s->lowpass_line = ff_lowpass_line_sse2; + else + s->lowpass_line = ff_lowpass_line_complex_sse2; + } + if (EXTERNAL_AVX(cpu_flags)) + if (!(s->flags & TINTERLACE_FLAG_CVLPF)) + s->lowpass_line = ff_lowpass_line_avx; } - if (EXTERNAL_AVX(cpu_flags)) - if (!(s->flags & TINTERLACE_FLAG_CVLPF)) - s->lowpass_line = ff_lowpass_line_avx; } diff --git a/tests/ref/fate/filter-pixfmts-tinterlace_cvlpf b/tests/ref/fate/filter-pixfmts-tinterlace_cvlpf index 8623636ff91ac..99703fa1afd17 100644 --- a/tests/ref/fate/filter-pixfmts-tinterlace_cvlpf +++ b/tests/ref/fate/filter-pixfmts-tinterlace_cvlpf @@ -2,12 +2,23 @@ gray 9849d71519ae9c584ae8abfa8adb2f8e yuv410p 44ee4b74b95c82d6f79ddf53b5e3aa9d yuv411p 5fa9d1fba7adfd6f7fa04464332b631a yuv420p ee9591ea3ab06c73be902c4b8868c69e +yuv420p10le 19b2dcf5e82725b2c9e366d5d3a4b67b +yuv420p12le e5b76eb58cab2dfa42738f665d8b8059 yuv422p b1be7b55567bde86d655adf80fac1257 +yuv422p10le 66f7433c7423d6289ee20c19c4e8dd90 +yuv422p12le b4a4b5ed81341b36f685b14b2bb8a798 yuv440p ddf6ee697f4ff4f90d501e6869392309 +yuv440p10le 7e44a92d9e47e15f0728b125725ccd41 +yuv440p12le c2cac82661e10be4917bd9dacb419fce yuv444p 7cb5d0c0997c8c2545a16bfc4cb9fd6d +yuv444p10le 08fb13c69b40229014a6ccf0bdd5498f +yuv444p12le 796c5559b9f426470eb2997c21be5d14 yuva420p ee0761e2f76ec441c545feede77103e4 +yuva420p10le 4bb6b3a1cbf2fd1fe5aefcc11ce8029f yuva422p a8da2806e21a88449079faa7f4303ffa +yuva422p10le d2965b5b5a43a7165badaff0718a17d8 yuva444p a3f57734d6f72bdf37f8f612ea7cce63 +yuva444p10le e020512901fd9ac7088898a4e3a8c7c1 yuvj420p 9f358e311b694bcd01e1a07d1120ade5 yuvj422p 9a7628a9f1630d35c7176951ddc1b2f6 yuvj440p 112fe35292c687746ec0c622a42c611b diff --git a/tests/ref/fate/filter-pixfmts-tinterlace_merge b/tests/ref/fate/filter-pixfmts-tinterlace_merge index e5d3bf0383b2a..fa6151c2728c3 100644 --- a/tests/ref/fate/filter-pixfmts-tinterlace_merge +++ b/tests/ref/fate/filter-pixfmts-tinterlace_merge @@ -2,12 +2,23 @@ gray fab3a7abc4f076cf926205aeacadbe51 yuv410p d4506e49eeb64c7ce714c07597e7dd69 yuv411p 2e8bb385cb4a53a0f3771815020f7213 yuv420p c967d3d5f3200d1b2417b0f2356f12fc +yuv420p10le 404d90eca9b93f7c0949be23187804c7 +yuv420p12le eb2ef81b82f1342618e4c9fe8e086592 yuv422p febaa84ea2e3246af742a7ed37c030f6 +yuv422p10le 0dc5f3833c0f11a0fcd0422d76508c10 +yuv422p12le 190eb7e76af5fc481588ded472901b58 yuv440p 13a934b42df65f11e153314ebb4f311e +yuv440p10le 7fabea51d6e52b718ef3ab919b24f8d2 +yuv440p12le c7b138374a18f258bdd1a2d21b4421b0 yuv444p 45d4466f5689942a4effb0fd23e44949 +yuv444p10le fde95627ba0e66be7ec863386b3e5ca6 +yuv444p12le c1e15c934ce3bc562a869dd78c75db17 yuva420p dc1173a07c3f993b277ea0c94d513e1f +yuva420p10le d85972762437105a932759c4bb9759c9 yuva422p ca200be80e5bfdb159e1aea57129ed3a +yuva422p10le 06d4f79ee2ddf31d9fe15af8ca573f46 yuva444p 9f39c35d6899dcb8b9a9b07c339ca365 +yuva444p10le b0c54fc3efad73f252d86127407aa1fd yuvj420p 844359293bb6ff81549f3fc0090cc587 yuvj422p 526af049d43974822baa7b48aa1e1098 yuvj440p af9285194da8efbc40d93bf8109f9dc5 diff --git a/tests/ref/fate/filter-pixfmts-tinterlace_pad b/tests/ref/fate/filter-pixfmts-tinterlace_pad index dcf2168fe1b6a..8f6b1c42e20b5 100644 --- a/tests/ref/fate/filter-pixfmts-tinterlace_pad +++ b/tests/ref/fate/filter-pixfmts-tinterlace_pad @@ -2,12 +2,23 @@ gray 7ef396fecd8d1c9fe32173e4415ba671 yuv410p 35bc11d0d32efc9e9a969be7d720f4e6 yuv411p 17ef3cd22a74f7368b5e02f68779f294 yuv420p 93d5b6a4c44d67e4d4447e8dd0bf3d33 +yuv420p10le 14e754c6e9d41cb048ce3c93512d7d35 +yuv420p12le ce54a2e38d121a7575dff30542facaad yuv422p 3ee40b0b6533b9183764b85c853ec3f9 +yuv422p10le d4b61a84b93e74b07b7020ceed40e39e +yuv422p12le 8fd90be12a97307645ecfcd09d576643 yuv440p 1d3c1258a51d09e778cd8368b1a4126f +yuv440p10le 29d116cb550a05920e5619ab58284d30 +yuv440p12le d7518f941a3b2c137f944afe9da816a1 yuv444p 1093568ad8f479ec20e738d018dd3f8f +yuv444p10le c65233e1d8b01f3369c20738f7386801 +yuv444p12le 70dc51a857bfb215b3a81fceb114b74c yuva420p 4588aef20c0010e514550c9391219724 +yuva420p10le 3181e84fd7aaed606bb86eecd2e13f20 yuva422p 3426ed1ac9429202d8c29fa62a04d4c3 +yuva422p10le c00acd7c437d41755dff09c5ca3642cf yuva444p 1b9fc791c7d774b4ba8c9dc836f78cf5 +yuva444p10le 616b42a232c83b8f9e5c5168ec4b5da5 yuvj420p 9a872e0c1b3c0b6fe856415696b758bd yuvj422p da3c9ef25528a2ee96746ce44e6969f3 yuvj440p a9a5495c6b0e2bf6e561998ea1c356a7 diff --git a/tests/ref/fate/filter-pixfmts-tinterlace_vlpf b/tests/ref/fate/filter-pixfmts-tinterlace_vlpf index 2f52fd13f0994..5a5f80b115ef5 100644 --- a/tests/ref/fate/filter-pixfmts-tinterlace_vlpf +++ b/tests/ref/fate/filter-pixfmts-tinterlace_vlpf @@ -2,12 +2,23 @@ gray b79791449947c25cd5b36d9d3b9d1831 yuv410p 5bc03f4cf6b441b421f0fdaeeff1e9ed yuv411p 19046df1876c46ed1ef0458680270bd3 yuv420p 69c743b84996be9430b051a55cfbcb29 +yuv420p10le 85948ad609abded6b50882d459f5a2f8 +yuv420p12le 7cebe45f51bdadc766f66c68db8d347d yuv422p d710ccd1941f6f389c97a09bc977e709 +yuv422p10le c54873f77dac1d710fb2aa1b0ce2669c +yuv422p12le 94a527bb787b9d121ffbbcb3a6c545d8 yuv440p 1a482a23fe5a9b7d02388c299fd0a423 +yuv440p10le 506efa287ecce9c951da2039fa1de2ae +yuv440p12le 631bcf190f409ccbc5c27b9f0f6ba5e2 yuv444p c968a92f4b7ab6706ee9b425eb5345b5 +yuv444p10le 0af437e635d49feccf7dfae201e6dfc5 +yuv444p12le 2e9e9f7caae1fae3b026810246fc6ac1 yuva420p 3f89a166f309c0cda8b91a9e8a0ce937 +yuva420p10le 79de1cc549c03d4893cf6f1aca86e057 yuva422p ef8fdbe910d68e88e98227b0e99fb5a6 +yuva422p10le 257a4aec41f9b5412179272d8a7fb6f7 yuva444p 3662eadd5f61a6edbc9d715ea8591415 +yuva444p10le 0905cf5b7f42c11be3f0486a66533c71 yuvj420p 14c4390b319c5d679184503309060ac3 yuvj422p bbe00a26526931b72a024febe1cd6b90 yuvj440p f654cf28b7879c6a6c950c3cb9612580 From 015f976aaee5c8aee39276bc742cdbd32dd9dbf9 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 23 Sep 2017 17:50:58 -0300 Subject: [PATCH 3152/3374] avcodec/frame_thread_encoder: use av_packet_alloc() Signed-off-by: James Almer --- libavcodec/frame_thread_encoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/frame_thread_encoder.c b/libavcodec/frame_thread_encoder.c index ffbf5caf29773..215aee9fc06f6 100644 --- a/libavcodec/frame_thread_encoder.c +++ b/libavcodec/frame_thread_encoder.c @@ -70,7 +70,7 @@ static void * attribute_align_arg worker(void *v){ AVFrame *frame; Task task; - if(!pkt) pkt= av_mallocz(sizeof(*pkt)); + if(!pkt) pkt = av_packet_alloc(); if(!pkt) continue; av_init_packet(pkt); From ff7f859c2595f4daf9397d70af1a4a5d9da0ca59 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 23 Sep 2017 18:08:07 -0300 Subject: [PATCH 3153/3374] avcodec/Makefile: skip v4l2_m2m headers if needed Fixes checkheaders on systems where v4l2_m2m is unavailable. Signed-off-by: James Almer --- libavcodec/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 97969a085da6b..1b17c27408569 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -1059,6 +1059,7 @@ SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_decode.h vaapi_encode.h SKIPHEADERS-$(CONFIG_VDA) += vda.h vda_vt_internal.h SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h vdpau_internal.h SKIPHEADERS-$(CONFIG_VIDEOTOOLBOX) += videotoolbox.h vda_vt_internal.h +SKIPHEADERS-$(CONFIG_V4L2_M2M) += v4l2_buffers.h v4l2_context.h v4l2_m2m.h TESTPROGS = avpacket \ celp_math \ From d1e7e4fbe2b07f191311cb56e82ef4c18fd0fda4 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 23 Sep 2017 18:12:56 -0300 Subject: [PATCH 3154/3374] avcodec/v4l2_m2m: add missing header inclusions Should fix checkheaders on systems where v4l2_m2m is enabled. Signed-off-by: James Almer --- libavcodec/v4l2_buffers.h | 2 ++ libavcodec/v4l2_context.h | 2 ++ libavcodec/v4l2_m2m.h | 2 ++ 3 files changed, 6 insertions(+) diff --git a/libavcodec/v4l2_buffers.h b/libavcodec/v4l2_buffers.h index 8901a0952f30d..5d25a87750941 100644 --- a/libavcodec/v4l2_buffers.h +++ b/libavcodec/v4l2_buffers.h @@ -24,6 +24,8 @@ #ifndef AVCODEC_V4L2_BUFFERS_H #define AVCODEC_V4L2_BUFFERS_H +#include + enum V4L2Buffer_status { V4L2BUF_AVAILABLE, V4L2BUF_IN_DRIVER, diff --git a/libavcodec/v4l2_context.h b/libavcodec/v4l2_context.h index b6667a04e3ca1..503cc36dc4a2b 100644 --- a/libavcodec/v4l2_context.h +++ b/libavcodec/v4l2_context.h @@ -25,6 +25,8 @@ #define AVCODEC_V4L2_CONTEXT_H #include +#include + #include "libavcodec/avcodec.h" #include "libavutil/pixfmt.h" #include "libavutil/frame.h" diff --git a/libavcodec/v4l2_m2m.h b/libavcodec/v4l2_m2m.h index 13e2285389f29..afa3987c46635 100644 --- a/libavcodec/v4l2_m2m.h +++ b/libavcodec/v4l2_m2m.h @@ -27,6 +27,8 @@ #include #include #include +#include + #include "libavcodec/avcodec.h" #include "v4l2_context.h" From 86be73c7c1a5c789ad971d4ec620edc839d46820 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 23 Sep 2017 19:37:21 -0300 Subject: [PATCH 3155/3374] avformat/mpeg: zero initialize idx_pkt Prevents use of uninitialized stack. Signed-off-by: James Almer --- libavformat/mpeg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c index 68a848a6f6351..50fe7a1a76873 100644 --- a/libavformat/mpeg.c +++ b/libavformat/mpeg.c @@ -884,7 +884,7 @@ static int vobsub_read_packet(AVFormatContext *s, AVPacket *pkt) FFDemuxSubtitlesQueue *q; AVIOContext *pb = vobsub->sub_ctx->pb; int ret, psize, total_read = 0, i; - AVPacket idx_pkt; + AVPacket idx_pkt = { 0 }; int64_t min_ts = INT64_MAX; int sid = 0; From 5a9415533dd064d44605b3a3896a53377b7a5ca8 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 23 Sep 2017 20:13:58 -0300 Subject: [PATCH 3156/3374] ffplay: zero initialize copy avpacket Prevents potential use of uninitialized stack. Signed-off-by: James Almer --- ffplay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ffplay.c b/ffplay.c index 66e3673d2158c..45f2d78443fc0 100644 --- a/ffplay.c +++ b/ffplay.c @@ -2977,7 +2977,7 @@ static int read_thread(void *arg) } if (is->queue_attachments_req) { if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) { - AVPacket copy; + AVPacket copy = { 0 }; if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0) goto fail; packet_queue_put(&is->videoq, ©); From 00a1e1337f22376909338a5319a378b2e2afdde8 Mon Sep 17 00:00:00 2001 From: Jaroslav Beran Date: Wed, 20 Sep 2017 15:14:54 +0200 Subject: [PATCH 3157/3374] libavdevice/v4l2: fix invalid access to struct v4l2_buffer In case we are short of queued buffers, at first v4l2_buffer was enqueued to kernel so it's not owned by user-space anymore. After that it's timestamp field was read, but it might be overwritten by driver at that moment. It resulted in invalid timestamp sometimes. Signed-off-by: Michael Niedermayer --- libavdevice/v4l2.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c index 17451cdb60425..f087badf5ca74 100644 --- a/libavdevice/v4l2.c +++ b/libavdevice/v4l2.c @@ -492,6 +492,7 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt) .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, .memory = V4L2_MEMORY_MMAP }; + struct timeval buf_ts; int res; pkt->size = 0; @@ -508,6 +509,8 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt) return res; } + buf_ts = buf.timestamp; + if (buf.index >= s->buffers) { av_log(ctx, AV_LOG_ERROR, "Invalid buffer index received.\n"); return AVERROR(EINVAL); @@ -583,7 +586,7 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt) return AVERROR(ENOMEM); } } - pkt->pts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec; + pkt->pts = buf_ts.tv_sec * INT64_C(1000000) + buf_ts.tv_usec; convert_timestamp(ctx, &pkt->pts); return pkt->size; From 9cec1742475b0d8d9c8090b2c6e80f53d00727a9 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 23 Sep 2017 02:19:25 +0200 Subject: [PATCH 3158/3374] avcodec/snowenc: Replace "return -1" by named constants Reviewed-by: James Almer Signed-off-by: Michael Niedermayer --- libavcodec/snowenc.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c index bb113d0a2b8c2..0d800b9f49325 100644 --- a/libavcodec/snowenc.c +++ b/libavcodec/snowenc.c @@ -50,7 +50,7 @@ FF_ENABLE_DEPRECATION_WARNINGS && (avctx->flags & AV_CODEC_FLAG_QSCALE) && avctx->global_quality == 0){ av_log(avctx, AV_LOG_ERROR, "The 9/7 wavelet is incompatible with lossless mode.\n"); - return -1; + return AVERROR(EINVAL); } #if FF_API_MOTION_EST FF_DISABLE_DEPRECATION_WARNINGS @@ -107,8 +107,9 @@ FF_ENABLE_DEPRECATION_WARNINGS return AVERROR(ENOMEM); } if((avctx->flags&AV_CODEC_FLAG_PASS2) || !(avctx->flags&AV_CODEC_FLAG_QSCALE)){ - if(ff_rate_control_init(&s->m) < 0) - return -1; + ret = ff_rate_control_init(&s->m); + if(ret < 0) + return ret; } s->pass1_rc= !(avctx->flags & (AV_CODEC_FLAG_QSCALE|AV_CODEC_FLAG_PASS2)); @@ -130,7 +131,7 @@ FF_ENABLE_DEPRECATION_WARNINGS break;*/ default: av_log(avctx, AV_LOG_ERROR, "pixel format not supported\n"); - return -1; + return AVERROR_PATCHWELCOME; } avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift); @@ -833,7 +834,7 @@ static int encode_subband_c0run(SnowContext *s, SubBand *b, const IDWTELEM *src, for(y=0; yc.bytestream_end - s->c.bytestream < w*40){ av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; + return AVERROR(ENOMEM); } for(x=0; x Date: Sat, 23 Sep 2017 01:44:27 +0200 Subject: [PATCH 3159/3374] avcodec/flacenc: Replace "return -1" by named constant Signed-off-by: Michael Niedermayer --- libavcodec/flacenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c index 3575f5391dc8b..170c3caf4844f 100644 --- a/libavcodec/flacenc.c +++ b/libavcodec/flacenc.c @@ -268,7 +268,7 @@ static av_cold int flac_encode_init(AVCodecContext *avctx) /* find samplerate in table */ if (freq < 1) - return -1; + return AVERROR(EINVAL); for (i = 4; i < 12; i++) { if (freq == ff_flac_sample_rate_table[i]) { s->samplerate = ff_flac_sample_rate_table[i]; From 7f8417f22619366aaaad848ee2ff71be14637b7b Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Thu, 21 Sep 2017 13:45:34 +0530 Subject: [PATCH 3160/3374] avcodec/mips: Improve hevc uni-w copy mc msa functions Load the specific destination bytes instead of MSA load and pack. Pack the data to half word before clipping. Use immediate unsigned saturation for clip to max saving one vector register. Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/hevc_mc_uniw_msa.c | 559 +++++++++++++++++++--------- libavutil/mips/generic_macros_msa.h | 30 ++ 2 files changed, 415 insertions(+), 174 deletions(-) diff --git a/libavcodec/mips/hevc_mc_uniw_msa.c b/libavcodec/mips/hevc_mc_uniw_msa.c index ce10f413ed9ed..d18441957f2b7 100644 --- a/libavcodec/mips/hevc_mc_uniw_msa.c +++ b/libavcodec/mips/hevc_mc_uniw_msa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com) + * Copyright (c) 2015 - 2017 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com) * * This file is part of FFmpeg. * @@ -62,6 +62,31 @@ out2_r, out3_r, out2_l, out3_l); \ } +#define HEVC_UNIW_RND_CLIP2_MAX_SATU_H(in0_h, in1_h, wgt_w, offset_h, rnd_w, \ + out0_h, out1_h) \ +{ \ + v4i32 in0_r_m, in0_l_m, in1_r_m, in1_l_m; \ + \ + ILVRL_H2_SW(in0_h, in0_h, in0_r_m, in0_l_m); \ + ILVRL_H2_SW(in1_h, in1_h, in1_r_m, in1_l_m); \ + DOTP_SH4_SW(in0_r_m, in1_r_m, in0_l_m, in1_l_m, wgt_w, wgt_w, wgt_w, \ + wgt_w, in0_r_m, in1_r_m, in0_l_m, in1_l_m); \ + SRAR_W4_SW(in0_r_m, in1_r_m, in0_l_m, in1_l_m, rnd_w); \ + PCKEV_H2_SH(in0_l_m, in0_r_m, in1_l_m, in1_r_m, out0_h, out1_h); \ + ADDS_SH2_SH(out0_h, offset_h, out1_h, offset_h, out0_h, out1_h); \ + CLIP_SH2_0_255_MAX_SATU(out0_h, out1_h); \ +} + +#define HEVC_UNIW_RND_CLIP4_MAX_SATU_H(in0_h, in1_h, in2_h, in3_h, wgt_w, \ + offset_h, rnd_w, out0_h, out1_h, \ + out2_h, out3_h) \ +{ \ + HEVC_UNIW_RND_CLIP2_MAX_SATU_H(in0_h, in1_h, wgt_w, offset_h, rnd_w, \ + out0_h, out1_h); \ + HEVC_UNIW_RND_CLIP2_MAX_SATU_H(in2_h, in3_h, wgt_w, offset_h, rnd_w, \ + out2_h, out3_h); \ +} + static void hevc_uniwgt_copy_4w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, @@ -71,76 +96,60 @@ static void hevc_uniwgt_copy_4w_msa(uint8_t *src, int32_t offset, int32_t rnd_val) { + uint32_t loop_cnt, tp0, tp1, tp2, tp3; v16i8 zero = { 0 }; - v4i32 weight_vec, offset_vec, rnd_vec; + v16u8 out0, out1; + v16i8 src0 = { 0 }, src1 = { 0 }; + v8i16 dst0, dst1, dst2, dst3, offset_vec; + v4i32 weight_vec, rnd_vec; weight = weight & 0x0000FFFF; weight_vec = __msa_fill_w(weight); - offset_vec = __msa_fill_w(offset); + offset_vec = __msa_fill_h(offset); rnd_vec = __msa_fill_w(rnd_val); if (2 == height) { - v16i8 src0, src1; - v8i16 dst0; v4i32 dst0_r, dst0_l; - LD_SB2(src, src_stride, src0, src1); - src0 = (v16i8) __msa_ilvr_w((v4i32) src1, (v4i32) src0); + LW2(src, src_stride, tp0, tp1); + INSERT_W2_SB(tp0, tp1, src0); dst0 = (v8i16) __msa_ilvr_b(zero, src0); dst0 <<= 6; ILVRL_H2_SW(dst0, dst0, dst0_r, dst0_l); DOTP_SH2_SW(dst0_r, dst0_l, weight_vec, weight_vec, dst0_r, dst0_l); SRAR_W2_SW(dst0_r, dst0_l, rnd_vec); - ADD2(dst0_r, offset_vec, dst0_l, offset_vec, dst0_r, dst0_l); - dst0_r = CLIP_SW_0_255(dst0_r); - dst0_l = CLIP_SW_0_255(dst0_l); - - HEVC_PCK_SW_SB2(dst0_l, dst0_r, dst0_r); - ST4x2_UB(dst0_r, dst, dst_stride); + dst0 = __msa_pckev_h((v8i16) dst0_l, (v8i16) dst0_r); + dst0 += offset_vec; + dst0 = CLIP_SH_0_255_MAX_SATU(dst0); + out0 = (v16u8) __msa_pckev_b((v16i8) dst0, (v16i8) dst0); + ST4x2_UB(out0, dst, dst_stride); } else if (4 == height) { - v16i8 src0, src1, src2, src3; - v8i16 dst0, dst1; - v4i32 dst0_r, dst1_r; - v4i32 dst0_l, dst1_l; - - LD_SB4(src, src_stride, src0, src1, src2, src3); - ILVR_W2_SB(src1, src0, src3, src2, src0, src1); - ILVR_B2_SH(zero, src0, zero, src1, dst0, dst1); - dst0 <<= 6; - dst1 <<= 6; - - HEVC_UNIW_RND_CLIP2(dst0, dst1, weight_vec, offset_vec, rnd_vec, - dst0_r, dst1_r, dst0_l, dst1_l); - - HEVC_PCK_SW_SB4(dst0_l, dst0_r, dst1_l, dst1_r, dst0_r); - ST4x4_UB(dst0_r, dst0_r, 0, 1, 2, 3, dst, dst_stride); - } else if (0 == height % 8) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7; - v8i16 dst0, dst1, dst2, dst3; - v4i32 dst0_r, dst1_r, dst2_r, dst3_r; - v4i32 dst0_l, dst1_l, dst2_l, dst3_l; - + LW4(src, src_stride, tp0, tp1, tp2, tp3); + INSERT_W4_SB(tp0, tp1, tp2, tp3, src0); + ILVRL_B2_SH(zero, src0, dst0, dst1); + SLLI_2V(dst0, dst1, 6); + HEVC_UNIW_RND_CLIP2_MAX_SATU_H(dst0, dst1, weight_vec, offset_vec, + rnd_vec, dst0, dst1); + out0 = (v16u8) __msa_pckev_b((v16i8) dst1, (v16i8) dst0); + ST4x4_UB(out0, out0, 0, 1, 2, 3, dst, dst_stride); + } else if (0 == (height % 8)) { for (loop_cnt = (height >> 3); loop_cnt--;) { - LD_SB8(src, src_stride, - src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - ILVR_W4_SB(src1, src0, src3, src2, src5, src4, src7, src6, - src0, src1, src2, src3); - ILVR_B4_SH(zero, src0, zero, src1, zero, src2, zero, src3, - dst0, dst1, dst2, dst3); - + LW4(src, src_stride, tp0, tp1, tp2, tp3); + src += 4 * src_stride; + INSERT_W4_SB(tp0, tp1, tp2, tp3, src0); + LW4(src, src_stride, tp0, tp1, tp2, tp3); + src += 4 * src_stride; + INSERT_W4_SB(tp0, tp1, tp2, tp3, src1); + ILVRL_B2_SH(zero, src0, dst0, dst1); + ILVRL_B2_SH(zero, src1, dst2, dst3); SLLI_4V(dst0, dst1, dst2, dst3, 6); - HEVC_UNIW_RND_CLIP4(dst0, dst1, dst2, dst3, - weight_vec, offset_vec, rnd_vec, - dst0_r, dst1_r, dst2_r, dst3_r, - dst0_l, dst1_l, dst2_l, dst3_l); - - HEVC_PCK_SW_SB8(dst0_l, dst0_r, dst1_l, dst1_r, - dst2_l, dst2_r, dst3_l, dst3_r, dst0_r, dst1_r); - ST4x8_UB(dst0_r, dst1_r, dst, dst_stride); - dst += (8 * dst_stride); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst0, dst1, dst2, dst3, weight_vec, + offset_vec, rnd_vec, dst0, dst1, + dst2, dst3); + PCKEV_B2_UB(dst1, dst0, dst3, dst2, out0, out1); + ST4x8_UB(out0, out1, dst, dst_stride); + dst += 8 * dst_stride; } } } @@ -155,46 +164,48 @@ static void hevc_uniwgt_copy_6w_msa(uint8_t *src, int32_t rnd_val) { uint32_t loop_cnt; + uint64_t tp0, tp1, tp2, tp3; v16i8 zero = { 0 }; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7; - v8i16 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; - v4i32 dst0_r, dst1_r, dst2_r, dst3_r; - v4i32 dst0_l, dst1_l, dst2_l, dst3_l; - v4i32 weight_vec, offset_vec, rnd_vec; + v16u8 out0, out1, out2, out3; + v16i8 src0, src1, src2, src3; + v8i16 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7, offset_vec; + v4i32 weight_vec, rnd_vec; weight = weight & 0x0000FFFF; weight_vec = __msa_fill_w(weight); - offset_vec = __msa_fill_w(offset); + offset_vec = __msa_fill_h(offset); rnd_vec = __msa_fill_w(rnd_val); for (loop_cnt = (height >> 3); loop_cnt--;) { - LD_SB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - ILVR_B4_SH(zero, src0, zero, src1, zero, src2, zero, src3, - dst0, dst1, dst2, dst3); - ILVR_B4_SH(zero, src4, zero, src5, zero, src6, zero, src7, - dst4, dst5, dst6, dst7); + LD4(src, src_stride, tp0, tp1, tp2, tp3); + src += (4 * src_stride); + INSERT_D2_SB(tp0, tp1, src0); + INSERT_D2_SB(tp2, tp3, src1); + LD4(src, src_stride, tp0, tp1, tp2, tp3); + src += (4 * src_stride); + INSERT_D2_SB(tp0, tp1, src2); + INSERT_D2_SB(tp2, tp3, src3); + + ILVRL_B2_SH(zero, src0, dst0, dst1); + ILVRL_B2_SH(zero, src1, dst2, dst3); + ILVRL_B2_SH(zero, src2, dst4, dst5); + ILVRL_B2_SH(zero, src3, dst6, dst7); SLLI_4V(dst0, dst1, dst2, dst3, 6); SLLI_4V(dst4, dst5, dst6, dst7, 6); - HEVC_UNIW_RND_CLIP4(dst0, dst1, dst2, dst3, - weight_vec, offset_vec, rnd_vec, - dst0_r, dst1_r, dst2_r, dst3_r, - dst0_l, dst1_l, dst2_l, dst3_l); - HEVC_PCK_SW_SB8(dst0_l, dst0_r, dst1_l, dst1_r, - dst2_l, dst2_r, dst3_l, dst3_r, dst0_r, dst1_r); - ST6x4_UB(dst0_r, dst1_r, dst, dst_stride); - dst += (4 * dst_stride); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst0, dst1, dst2, dst3, weight_vec, + offset_vec, rnd_vec, dst0, dst1, dst2, + dst3); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst4, dst5, dst6, dst7, weight_vec, + offset_vec, rnd_vec, dst4, dst5, dst6, + dst7); + PCKEV_B2_UB(dst1, dst0, dst3, dst2, out0, out1); + PCKEV_B2_UB(dst5, dst4, dst7, dst6, out2, out3); - HEVC_UNIW_RND_CLIP4(dst4, dst5, dst6, dst7, - weight_vec, offset_vec, rnd_vec, - dst0_r, dst1_r, dst2_r, dst3_r, - dst0_l, dst1_l, dst2_l, dst3_l); - - HEVC_PCK_SW_SB8(dst0_l, dst0_r, dst1_l, dst1_r, - dst2_l, dst2_r, dst3_l, dst3_r, dst0_r, dst1_r); - ST6x4_UB(dst0_r, dst1_r, dst, dst_stride); + ST6x4_UB(out0, out1, dst, dst_stride); + dst += (4 * dst_stride); + ST6x4_UB(out2, out3, dst, dst_stride); dst += (4 * dst_stride); } } @@ -208,78 +219,89 @@ static void hevc_uniwgt_copy_8w_msa(uint8_t *src, int32_t offset, int32_t rnd_val) { + uint32_t loop_cnt; + uint64_t tp0, tp1, tp2, tp3; + v16i8 src0 = { 0 }, src1 = { 0 }, src2 = { 0 }, src3 = { 0 }; v16i8 zero = { 0 }; - v4i32 weight_vec, offset_vec, rnd_vec; + v16u8 out0, out1, out2, out3; + v8i16 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7, offset_vec; + v4i32 weight_vec, rnd_vec; weight = weight & 0x0000FFFF; weight_vec = __msa_fill_w(weight); - offset_vec = __msa_fill_w(offset); + offset_vec = __msa_fill_h(offset); rnd_vec = __msa_fill_w(rnd_val); if (2 == height) { - v16i8 src0, src1; - v8i16 dst0, dst1; - v4i32 dst0_r, dst1_r, dst0_l, dst1_l; - - LD_SB2(src, src_stride, src0, src1); - ILVR_B2_SH(zero, src0, zero, src1, dst0, dst1); - - dst0 <<= 6; - dst1 <<= 6; - HEVC_UNIW_RND_CLIP2(dst0, dst1, weight_vec, offset_vec, rnd_vec, - dst0_r, dst1_r, dst0_l, dst1_l); - - HEVC_PCK_SW_SB4(dst0_l, dst0_r, dst1_l, dst1_r, dst0_r); - ST8x2_UB(dst0_r, dst, dst_stride); + LD2(src, src_stride, tp0, tp1); + INSERT_D2_SB(tp0, tp1, src0); + ILVRL_B2_SH(zero, src0, dst0, dst1); + SLLI_2V(dst0, dst1, 6); + HEVC_UNIW_RND_CLIP2_MAX_SATU_H(dst0, dst1, weight_vec, offset_vec, + rnd_vec, dst0, dst1); + out0 = (v16u8) __msa_pckev_b((v16i8) dst1, (v16i8) dst0); + ST8x2_UB(out0, dst, dst_stride); + } else if (4 == height) { + LD4(src, src_stride, tp0, tp1, tp2, tp3); + INSERT_D2_SB(tp0, tp1, src0); + INSERT_D2_SB(tp2, tp3, src1); + ILVRL_B2_SH(zero, src0, dst0, dst1); + ILVRL_B2_SH(zero, src1, dst2, dst3); + SLLI_4V(dst0, dst1, dst2, dst3, 6); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst0, dst1, dst2, dst3, weight_vec, + offset_vec, rnd_vec, dst0, dst1, dst2, + dst3); + PCKEV_B2_UB(dst1, dst0, dst3, dst2, out0, out1); + ST8x4_UB(out0, out1, dst, dst_stride); } else if (6 == height) { - v16i8 src0, src1, src2, src3, src4, src5; - v8i16 dst0, dst1, dst2, dst3, dst4, dst5; - v4i32 dst0_r, dst1_r, dst2_r, dst3_r, dst4_r, dst5_r; - v4i32 dst0_l, dst1_l, dst2_l, dst3_l, dst4_l, dst5_l; - - LD_SB6(src, src_stride, src0, src1, src2, src3, src4, src5); - ILVR_B4_SH(zero, src0, zero, src1, zero, src2, zero, src3, - dst0, dst1, dst2, dst3); - ILVR_B2_SH(zero, src4, zero, src5, dst4, dst5); - + LD4(src, src_stride, tp0, tp1, tp2, tp3); + src += 4 * src_stride; + INSERT_D2_SB(tp0, tp1, src0); + INSERT_D2_SB(tp2, tp3, src1); + LD2(src, src_stride, tp0, tp1); + INSERT_D2_SB(tp0, tp1, src2); + ILVRL_B2_SH(zero, src0, dst0, dst1); + ILVRL_B2_SH(zero, src1, dst2, dst3); + ILVRL_B2_SH(zero, src2, dst4, dst5); SLLI_4V(dst0, dst1, dst2, dst3, 6); - dst4 <<= 6; - dst5 <<= 6; - HEVC_UNIW_RND_CLIP4(dst0, dst1, dst2, dst3, - weight_vec, offset_vec, rnd_vec, - dst0_r, dst1_r, dst2_r, dst3_r, - dst0_l, dst1_l, dst2_l, dst3_l); - HEVC_UNIW_RND_CLIP2(dst4, dst5, weight_vec, offset_vec, rnd_vec, - dst4_r, dst5_r, dst4_l, dst5_l); - - HEVC_PCK_SW_SB12(dst0_l, dst0_r, dst1_l, dst1_r, - dst2_l, dst2_r, dst3_l, dst3_r, - dst4_l, dst4_r, dst5_l, dst5_r, - dst0_r, dst1_r, dst2_r); - ST8x4_UB(dst0_r, dst1_r, dst, dst_stride); + SLLI_2V(dst4, dst5, 6); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst0, dst1, dst2, dst3, weight_vec, + offset_vec, rnd_vec, dst0, dst1, dst2, + dst3); + HEVC_UNIW_RND_CLIP2_MAX_SATU_H(dst4, dst5, weight_vec, offset_vec, + rnd_vec, dst4, dst5); + PCKEV_B3_UB(dst1, dst0, dst3, dst2, dst5, dst4, out0, out1, out2); + ST8x4_UB(out0, out1, dst, dst_stride); dst += (4 * dst_stride); - ST8x2_UB(dst2_r, dst, dst_stride); - } else if (0 == height % 4) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3; - v8i16 dst0, dst1, dst2, dst3; - v4i32 dst0_r, dst1_r, dst2_r, dst3_r, dst0_l, dst1_l, dst2_l, dst3_l; - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - ILVR_B4_SH(zero, src0, zero, src1, zero, src2, zero, src3, - dst0, dst1, dst2, dst3); - + ST8x2_UB(out2, dst, dst_stride); + } else if (0 == height % 8) { + for (loop_cnt = (height >> 3); loop_cnt--;) { + LD4(src, src_stride, tp0, tp1, tp2, tp3); + src += 4 * src_stride; + INSERT_D2_SB(tp0, tp1, src0); + INSERT_D2_SB(tp2, tp3, src1); + LD4(src, src_stride, tp0, tp1, tp2, tp3); + src += 4 * src_stride; + INSERT_D2_SB(tp0, tp1, src2); + INSERT_D2_SB(tp2, tp3, src3); + + ILVRL_B2_SH(zero, src0, dst0, dst1); + ILVRL_B2_SH(zero, src1, dst2, dst3); + ILVRL_B2_SH(zero, src2, dst4, dst5); + ILVRL_B2_SH(zero, src3, dst6, dst7); SLLI_4V(dst0, dst1, dst2, dst3, 6); - HEVC_UNIW_RND_CLIP4(dst0, dst1, dst2, dst3, - weight_vec, offset_vec, rnd_vec, - dst0_r, dst1_r, dst2_r, dst3_r, - dst0_l, dst1_l, dst2_l, dst3_l); - - HEVC_PCK_SW_SB8(dst0_l, dst0_r, dst1_l, dst1_r, - dst2_l, dst2_r, dst3_l, dst3_r, dst0_r, dst1_r); - ST8x4_UB(dst0_r, dst1_r, dst, dst_stride); + SLLI_4V(dst4, dst5, dst6, dst7, 6); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst0, dst1, dst2, dst3, weight_vec, + offset_vec, rnd_vec, dst0, dst1, + dst2, dst3); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst4, dst5, dst6, dst7, weight_vec, + offset_vec, rnd_vec, dst4, dst5, + dst6, dst7); + PCKEV_B2_UB(dst1, dst0, dst3, dst2, out0, out1); + PCKEV_B2_UB(dst5, dst4, dst7, dst6, out2, out3); + ST8x4_UB(out0, out1, dst, dst_stride); + dst += (4 * dst_stride); + ST8x4_UB(out2, out3, dst, dst_stride); dst += (4 * dst_stride); } } @@ -295,41 +317,36 @@ static void hevc_uniwgt_copy_12w_msa(uint8_t *src, int32_t rnd_val) { uint32_t loop_cnt; + v16u8 out0, out1, out2; v16i8 src0, src1, src2, src3; v8i16 dst0, dst1, dst2, dst3, dst4, dst5; - v4i32 dst0_r, dst1_r, dst2_r, dst3_r, dst4_r, dst5_r; - v4i32 dst0_l, dst1_l, dst2_l, dst3_l, dst4_l, dst5_l; + v8i16 offset_vec; v16i8 zero = { 0 }; - v4i32 weight_vec, offset_vec, rnd_vec; + v4i32 weight_vec, rnd_vec; weight = weight & 0x0000FFFF; weight_vec = __msa_fill_w(weight); - offset_vec = __msa_fill_w(offset); + offset_vec = __msa_fill_h(offset); rnd_vec = __msa_fill_w(rnd_val); - for (loop_cnt = (height >> 2); loop_cnt--;) { + for (loop_cnt = 4; loop_cnt--;) { LD_SB4(src, src_stride, src0, src1, src2, src3); src += (4 * src_stride); ILVR_B4_SH(zero, src0, zero, src1, zero, src2, zero, src3, dst0, dst1, dst2, dst3); - SLLI_4V(dst0, dst1, dst2, dst3, 6); ILVL_W2_SB(src1, src0, src3, src2, src0, src1); ILVR_B2_SH(zero, src0, zero, src1, dst4, dst5); - dst4 <<= 6; - dst5 <<= 6; - HEVC_UNIW_RND_CLIP4(dst0, dst1, dst2, dst3, - weight_vec, offset_vec, rnd_vec, - dst0_r, dst1_r, dst2_r, dst3_r, - dst0_l, dst1_l, dst2_l, dst3_l); - HEVC_UNIW_RND_CLIP2(dst4, dst5, weight_vec, offset_vec, rnd_vec, - dst4_r, dst5_r, dst4_l, dst5_l); - - HEVC_PCK_SW_SB12(dst0_l, dst0_r, dst1_l, dst1_r, - dst2_l, dst2_r, dst3_l, dst3_r, - dst4_l, dst4_r, dst5_l, dst5_r, - dst0_r, dst1_r, dst2_r); - ST12x4_UB(dst0_r, dst1_r, dst2_r, dst, dst_stride); + SLLI_4V(dst0, dst1, dst2, dst3, 6); + SLLI_2V(dst4, dst5, 6); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst0, dst1, dst2, dst3, weight_vec, + offset_vec, rnd_vec, dst0, dst1, dst2, + dst3); + HEVC_UNIW_RND_CLIP2_MAX_SATU_H(dst4, dst5, weight_vec, offset_vec, + rnd_vec, dst4, dst5); + + PCKEV_B3_UB(dst1, dst0, dst3, dst2, dst5, dst4, out0, out1, out2); + ST12x4_UB(out0, out1, out2, dst, dst_stride); dst += (4 * dst_stride); } } @@ -410,8 +427,38 @@ static void hevc_uniwgt_copy_16w_msa(uint8_t *src, int32_t offset, int32_t rnd_val) { - hevc_uniwgt_copy_16multx4mult_msa(src, src_stride, dst, dst_stride, - height, weight, offset, rnd_val, 16); + uint32_t loop_cnt; + v16u8 out0, out1, out2, out3; + v16i8 src0, src1, src2, src3; + v16i8 zero = { 0 }; + v8i16 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7, offset_vec; + v4i32 weight_vec, rnd_vec; + + weight = weight & 0x0000FFFF; + weight_vec = __msa_fill_w(weight); + offset_vec = __msa_fill_h(offset); + rnd_vec = __msa_fill_w(rnd_val); + + for (loop_cnt = height >> 2; loop_cnt--;) { + LD_SB4(src, src_stride, src0, src1, src2, src3); + src += (4 * src_stride); + ILVRL_B2_SH(zero, src0, dst0, dst1); + ILVRL_B2_SH(zero, src1, dst2, dst3); + ILVRL_B2_SH(zero, src2, dst4, dst5); + ILVRL_B2_SH(zero, src3, dst6, dst7); + SLLI_4V(dst0, dst1, dst2, dst3, 6); + SLLI_4V(dst4, dst5, dst6, dst7, 6); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst0, dst1, dst2, dst3, weight_vec, + offset_vec, rnd_vec, dst0, dst1, dst2, + dst3); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst4, dst5, dst6, dst7, weight_vec, + offset_vec, rnd_vec, dst4, dst5, dst6, + dst7); + PCKEV_B2_UB(dst1, dst0, dst3, dst2, out0, out1); + PCKEV_B2_UB(dst5, dst4, dst7, dst6, out2, out3); + ST_UB4(out0, out1, out2, out3, dst, dst_stride); + dst += (4 * dst_stride); + } } static void hevc_uniwgt_copy_24w_msa(uint8_t *src, @@ -423,11 +470,48 @@ static void hevc_uniwgt_copy_24w_msa(uint8_t *src, int32_t offset, int32_t rnd_val) { - hevc_uniwgt_copy_16multx4mult_msa(src, src_stride, dst, dst_stride, - height, weight, offset, rnd_val, 16); + uint32_t loop_cnt; + v16u8 out0, out1, out2, out3, out4, out5; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7; + v16i8 zero = { 0 }; + v8i16 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7, offset_vec; + v8i16 dst8, dst9, dst10, dst11; + v4i32 weight_vec, rnd_vec; - hevc_uniwgt_copy_8w_msa(src + 16, src_stride, dst + 16, dst_stride, - height, weight, offset, rnd_val); + weight = weight & 0x0000FFFF; + weight_vec = __msa_fill_w(weight); + offset_vec = __msa_fill_h(offset); + rnd_vec = __msa_fill_w(rnd_val); + + for (loop_cnt = (height >> 2); loop_cnt--;) { + LD_SB4(src, src_stride, src0, src1, src4, src5); + LD_SB4(src + 16, src_stride, src2, src3, src6, src7); + src += (4 * src_stride); + + ILVRL_B2_SH(zero, src0, dst0, dst1); + ILVRL_B2_SH(zero, src1, dst2, dst3); + ILVR_B2_SH(zero, src2, zero, src3, dst4, dst5); + ILVRL_B2_SH(zero, src4, dst6, dst7); + ILVRL_B2_SH(zero, src5, dst8, dst9); + ILVR_B2_SH(zero, src6, zero, src7, dst10, dst11); + SLLI_4V(dst0, dst1, dst2, dst3, 6); + SLLI_4V(dst4, dst5, dst6, dst7, 6); + SLLI_4V(dst8, dst9, dst10, dst11, 6); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst0, dst1, dst2, dst3, weight_vec, + offset_vec, rnd_vec, dst0, dst1, dst2, + dst3); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst4, dst5, dst6, dst7, weight_vec, + offset_vec, rnd_vec, dst4, dst5, dst6, + dst7); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst8, dst9, dst10, dst11, weight_vec, + offset_vec, rnd_vec, dst8, dst9, dst10, + dst11); + PCKEV_B3_UB(dst1, dst0, dst3, dst2, dst5, dst4, out0, out1, out2); + PCKEV_B3_UB(dst7, dst6, dst9, dst8, dst11, dst10, out3, out4, out5); + ST_UB4(out0, out1, out3, out4, dst, dst_stride); + ST8x4_UB(out2, out5, dst + 16, dst_stride); + dst += (4 * dst_stride); + } } static void hevc_uniwgt_copy_32w_msa(uint8_t *src, @@ -439,8 +523,41 @@ static void hevc_uniwgt_copy_32w_msa(uint8_t *src, int32_t offset, int32_t rnd_val) { - hevc_uniwgt_copy_16multx4mult_msa(src, src_stride, dst, dst_stride, - height, weight, offset, rnd_val, 32); + uint32_t loop_cnt; + v16u8 out0, out1, out2, out3; + v16i8 src0, src1, src2, src3; + v16i8 zero = { 0 }; + v8i16 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7, offset_vec; + v4i32 weight_vec, rnd_vec; + + weight = weight & 0x0000FFFF; + weight_vec = __msa_fill_w(weight); + offset_vec = __msa_fill_h(offset); + rnd_vec = __msa_fill_w(rnd_val); + + for (loop_cnt = (height >> 1); loop_cnt--;) { + LD_SB2(src, src_stride, src0, src1); + LD_SB2(src + 16, src_stride, src2, src3); + src += (2 * src_stride); + + ILVRL_B2_SH(zero, src0, dst0, dst1); + ILVRL_B2_SH(zero, src1, dst2, dst3); + ILVRL_B2_SH(zero, src2, dst4, dst5); + ILVRL_B2_SH(zero, src3, dst6, dst7); + SLLI_4V(dst0, dst1, dst2, dst3, 6); + SLLI_4V(dst4, dst5, dst6, dst7, 6); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst0, dst1, dst2, dst3, weight_vec, + offset_vec, rnd_vec, dst0, dst1, dst2, + dst3); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst4, dst5, dst6, dst7, weight_vec, + offset_vec, rnd_vec, dst4, dst5, dst6, + dst7); + PCKEV_B2_UB(dst1, dst0, dst3, dst2, out0, out1); + PCKEV_B2_UB(dst5, dst4, dst7, dst6, out2, out3); + ST_UB2(out0, out1, dst, dst_stride); + ST_UB2(out2, out3, dst + 16, dst_stride); + dst += (2 * dst_stride); + } } static void hevc_uniwgt_copy_48w_msa(uint8_t *src, @@ -452,8 +569,52 @@ static void hevc_uniwgt_copy_48w_msa(uint8_t *src, int32_t offset, int32_t rnd_val) { - hevc_uniwgt_copy_16multx4mult_msa(src, src_stride, dst, dst_stride, - height, weight, offset, rnd_val, 48); + uint32_t loop_cnt; + v16u8 out0, out1, out2, out3, out4, out5; + v16i8 src0, src1, src2, src3, src4, src5; + v16i8 zero = { 0 }; + v8i16 dst0, dst1, dst2, dst3, dst4, dst5, offset_vec; + v8i16 dst6, dst7, dst8, dst9, dst10, dst11; + v4i32 weight_vec, rnd_vec; + + weight = weight & 0x0000FFFF; + weight_vec = __msa_fill_w(weight); + offset_vec = __msa_fill_h(offset); + rnd_vec = __msa_fill_w(rnd_val); + + for (loop_cnt = (height >> 1); loop_cnt--;) { + LD_SB3(src, 16, src0, src1, src2); + src += src_stride; + LD_SB3(src, 16, src3, src4, src5); + src += src_stride; + + ILVRL_B2_SH(zero, src0, dst0, dst1); + ILVRL_B2_SH(zero, src1, dst2, dst3); + ILVRL_B2_SH(zero, src2, dst4, dst5); + ILVRL_B2_SH(zero, src3, dst6, dst7); + ILVRL_B2_SH(zero, src4, dst8, dst9); + ILVRL_B2_SH(zero, src5, dst10, dst11); + SLLI_4V(dst0, dst1, dst2, dst3, 6); + SLLI_4V(dst4, dst5, dst6, dst7, 6); + SLLI_4V(dst8, dst9, dst10, dst11, 6); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst0, dst1, dst2, dst3, weight_vec, + offset_vec, rnd_vec, dst0, dst1, dst2, + dst3); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst4, dst5, dst6, dst7, weight_vec, + offset_vec, rnd_vec, dst4, dst5, dst6, + dst7); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst8, dst9, dst10, dst11, weight_vec, + offset_vec, rnd_vec, dst8, dst9, dst10, + dst11); + PCKEV_B3_UB(dst1, dst0, dst3, dst2, dst5, dst4, out0, out1, out2); + PCKEV_B3_UB(dst7, dst6, dst9, dst8, dst11, dst10, out3, out4, out5); + ST_UB2(out0, out1, dst, 16); + ST_UB(out2, dst + 32); + dst += dst_stride; + ST_UB2(out3, out4, dst, 16); + ST_UB(out5, dst + 32); + dst += dst_stride; + } } static void hevc_uniwgt_copy_64w_msa(uint8_t *src, @@ -465,8 +626,58 @@ static void hevc_uniwgt_copy_64w_msa(uint8_t *src, int32_t offset, int32_t rnd_val) { - hevc_uniwgt_copy_16multx4mult_msa(src, src_stride, dst, dst_stride, - height, weight, offset, rnd_val, 64); + uint32_t loop_cnt; + v16u8 out0, out1, out2, out3, out4, out5, out6, out7; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7; + v16i8 zero = { 0 }; + v8i16 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7, offset_vec; + v8i16 dst8, dst9, dst10, dst11, dst12, dst13, dst14, dst15; + v4i32 weight_vec, rnd_vec; + + weight = weight & 0x0000FFFF; + weight_vec = __msa_fill_w(weight); + offset_vec = __msa_fill_h(offset); + rnd_vec = __msa_fill_w(rnd_val); + + for (loop_cnt = (height >> 1); loop_cnt--;) { + LD_SB4(src, 16, src0, src1, src2, src3); + src += src_stride; + LD_SB4(src, 16, src4, src5, src6, src7); + src += src_stride; + + ILVRL_B2_SH(zero, src0, dst0, dst1); + ILVRL_B2_SH(zero, src1, dst2, dst3); + ILVRL_B2_SH(zero, src2, dst4, dst5); + ILVRL_B2_SH(zero, src3, dst6, dst7); + ILVRL_B2_SH(zero, src4, dst8, dst9); + ILVRL_B2_SH(zero, src5, dst10, dst11); + ILVRL_B2_SH(zero, src6, dst12, dst13); + ILVRL_B2_SH(zero, src7, dst14, dst15); + SLLI_4V(dst0, dst1, dst2, dst3, 6); + SLLI_4V(dst4, dst5, dst6, dst7, 6); + SLLI_4V(dst8, dst9, dst10, dst11, 6); + SLLI_4V(dst12, dst13, dst14, dst15, 6); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst0, dst1, dst2, dst3, weight_vec, + offset_vec, rnd_vec, dst0, dst1, dst2, + dst3); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst4, dst5, dst6, dst7, weight_vec, + offset_vec, rnd_vec, dst4, dst5, dst6, + dst7); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst8, dst9, dst10, dst11, weight_vec, + offset_vec, rnd_vec, dst8, dst9, dst10, + dst11); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst12, dst13, dst14, dst15, weight_vec, + offset_vec, rnd_vec, dst12, dst13, dst14, + dst15); + PCKEV_B2_UB(dst1, dst0, dst3, dst2, out0, out1); + PCKEV_B2_UB(dst5, dst4, dst7, dst6, out2, out3); + PCKEV_B2_UB(dst9, dst8, dst11, dst10, out4, out5); + PCKEV_B2_UB(dst13, dst12, dst15, dst14, out6, out7); + ST_UB4(out0, out1, out2, out3, dst, 16); + dst += dst_stride; + ST_UB4(out4, out5, out6, out7, dst, 16); + dst += dst_stride; + } } static void hevc_hz_uniwgt_8t_4w_msa(uint8_t *src, diff --git a/libavutil/mips/generic_macros_msa.h b/libavutil/mips/generic_macros_msa.h index 3ff94fdc99a60..bda3ed263f397 100644 --- a/libavutil/mips/generic_macros_msa.h +++ b/libavutil/mips/generic_macros_msa.h @@ -204,6 +204,12 @@ out3 = LW((psrc) + 3 * stride); \ } +#define LW2(psrc, stride, out0, out1) \ +{ \ + out0 = LW((psrc)); \ + out1 = LW((psrc) + stride); \ +} + /* Description : Load double words with stride Arguments : Inputs - psrc (source pointer to load from) - stride @@ -1047,6 +1053,25 @@ CLIP_SH2_0_255(in2, in3); \ } +#define CLIP_SH_0_255_MAX_SATU(in) \ +( { \ + v8i16 out_m; \ + \ + out_m = __msa_maxi_s_h((v8i16) in, 0); \ + out_m = (v8i16) __msa_sat_u_h((v8u16) out_m, 7); \ + out_m; \ +} ) +#define CLIP_SH2_0_255_MAX_SATU(in0, in1) \ +{ \ + in0 = CLIP_SH_0_255_MAX_SATU(in0); \ + in1 = CLIP_SH_0_255_MAX_SATU(in1); \ +} +#define CLIP_SH4_0_255_MAX_SATU(in0, in1, in2, in3) \ +{ \ + CLIP_SH2_0_255_MAX_SATU(in0, in1); \ + CLIP_SH2_0_255_MAX_SATU(in2, in3); \ +} + /* Description : Clips all signed word elements of input vector between 0 & 255 Arguments : Inputs - in (input vector) @@ -1965,6 +1990,11 @@ result is in place written to 'in0' Similar for other pairs */ +#define SLLI_2V(in0, in1, shift) \ +{ \ + in0 = in0 << shift; \ + in1 = in1 << shift; \ +} #define SLLI_4V(in0, in1, in2, in3, shift) \ { \ in0 = in0 << shift; \ From d6737539e77e78fca9a04914d51996cfd1ccc55c Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Thu, 21 Sep 2017 19:02:30 +0530 Subject: [PATCH 3161/3374] avcodec/mips: Unrolled loops avc intra msa functions Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/h264pred_msa.c | 318 ++++++++++++++++----------------- 1 file changed, 158 insertions(+), 160 deletions(-) diff --git a/libavcodec/mips/h264pred_msa.c b/libavcodec/mips/h264pred_msa.c index cddcd2e87803e..c297aec879dd5 100644 --- a/libavcodec/mips/h264pred_msa.c +++ b/libavcodec/mips/h264pred_msa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Shivraj Patil (Shivraj.Patil@imgtec.com) + * Copyright (c) 2015 - 2017 Shivraj Patil (Shivraj.Patil@imgtec.com) * * This file is part of FFmpeg. * @@ -24,31 +24,21 @@ static void intra_predict_vert_8x8_msa(uint8_t *src, uint8_t *dst, int32_t dst_stride) { - uint32_t row; - uint32_t src_data1, src_data2; - - src_data1 = LW(src); - src_data2 = LW(src + 4); + uint64_t out = LD(src); - for (row = 8; row--;) { - SW(src_data1, dst); - SW(src_data2, (dst + 4)); - dst += dst_stride; - } + SD4(out, out, out, out, dst, dst_stride); + dst += (4 * dst_stride); + SD4(out, out, out, out, dst, dst_stride); } static void intra_predict_vert_16x16_msa(uint8_t *src, uint8_t *dst, int32_t dst_stride) { - uint32_t row; - v16u8 src0; - - src0 = LD_UB(src); + v16u8 out = LD_UB(src); - for (row = 16; row--;) { - ST_UB(src0, dst); - dst += dst_stride; - } + ST_UB8(out, out, out, out, out, out, out, out, dst, dst_stride); + dst += (8 * dst_stride); + ST_UB8(out, out, out, out, out, out, out, out, dst, dst_stride); } static void intra_predict_horiz_8x8_msa(uint8_t *src, int32_t src_stride, @@ -73,28 +63,47 @@ static void intra_predict_horiz_8x8_msa(uint8_t *src, int32_t src_stride, static void intra_predict_horiz_16x16_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride) { - uint32_t row; uint8_t inp0, inp1, inp2, inp3; - v16u8 src0, src1, src2, src3; - - for (row = 4; row--;) { - inp0 = src[0]; - src += src_stride; - inp1 = src[0]; - src += src_stride; - inp2 = src[0]; - src += src_stride; - inp3 = src[0]; - src += src_stride; - - src0 = (v16u8) __msa_fill_b(inp0); - src1 = (v16u8) __msa_fill_b(inp1); - src2 = (v16u8) __msa_fill_b(inp2); - src3 = (v16u8) __msa_fill_b(inp3); - - ST_UB4(src0, src1, src2, src3, dst, dst_stride); - dst += (4 * dst_stride); - } + v16u8 src0, src1, src2, src3, src4, src5, src6, src7; + v16u8 src8, src9, src10, src11, src12, src13, src14, src15; + + inp0 = src[0 * src_stride]; + inp1 = src[1 * src_stride]; + inp2 = src[2 * src_stride]; + inp3 = src[3 * src_stride]; + src0 = (v16u8) __msa_fill_b(inp0); + src1 = (v16u8) __msa_fill_b(inp1); + src2 = (v16u8) __msa_fill_b(inp2); + src3 = (v16u8) __msa_fill_b(inp3); + inp0 = src[4 * src_stride]; + inp1 = src[5 * src_stride]; + inp2 = src[6 * src_stride]; + inp3 = src[7 * src_stride]; + src4 = (v16u8) __msa_fill_b(inp0); + src5 = (v16u8) __msa_fill_b(inp1); + src6 = (v16u8) __msa_fill_b(inp2); + src7 = (v16u8) __msa_fill_b(inp3); + inp0 = src[ 8 * src_stride]; + inp1 = src[ 9 * src_stride]; + inp2 = src[10 * src_stride]; + inp3 = src[11 * src_stride]; + src8 = (v16u8) __msa_fill_b(inp0); + src9 = (v16u8) __msa_fill_b(inp1); + src10 = (v16u8) __msa_fill_b(inp2); + src11 = (v16u8) __msa_fill_b(inp3); + inp0 = src[12 * src_stride]; + inp1 = src[13 * src_stride]; + inp2 = src[14 * src_stride]; + inp3 = src[15 * src_stride]; + src12 = (v16u8) __msa_fill_b(inp0); + src13 = (v16u8) __msa_fill_b(inp1); + src14 = (v16u8) __msa_fill_b(inp2); + src15 = (v16u8) __msa_fill_b(inp3); + + ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, dst, dst_stride); + dst += (8 * dst_stride); + ST_UB8(src8, src9, src10, src11, src12, src13, src14, src15, + dst, dst_stride); } static void intra_predict_dc_8x8_msa(uint8_t *src_top, uint8_t *src_left, @@ -206,39 +215,29 @@ static void intra_predict_dc_16x16_msa(uint8_t *src_top, uint8_t *src_left, } } -#define INTRA_PREDICT_VALDC_8X8_MSA(val) \ -static void intra_predict_##val##dc_8x8_msa(uint8_t *dst, \ - int32_t dst_stride) \ -{ \ - uint32_t row, out; \ - v16i8 store; \ - \ - store = __msa_ldi_b(val); \ - out = __msa_copy_u_w((v4i32) store, 0); \ - \ - for (row = 8; row--;) { \ - SW(out, dst); \ - SW(out, (dst + 4)); \ - dst += dst_stride; \ - } \ +#define INTRA_PREDICT_VALDC_8X8_MSA(val) \ +static void intra_predict_##val##dc_8x8_msa(uint8_t *dst, int32_t dst_stride) \ +{ \ + v16i8 store = __msa_fill_b(val); \ + uint64_t out = __msa_copy_u_d((v2i64) store, 0); \ + \ + SD4(out, out, out, out, dst, dst_stride); \ + dst += (4 * dst_stride); \ + SD4(out, out, out, out, dst, dst_stride); \ } INTRA_PREDICT_VALDC_8X8_MSA(127); INTRA_PREDICT_VALDC_8X8_MSA(129); -#define INTRA_PREDICT_VALDC_16X16_MSA(val) \ -static void intra_predict_##val##dc_16x16_msa(uint8_t *dst, \ - int32_t dst_stride) \ -{ \ - uint32_t row; \ - v16u8 store; \ - \ - store = (v16u8) __msa_ldi_b(val); \ - \ - for (row = 16; row--;) { \ - ST_UB(store, dst); \ - dst += dst_stride; \ - } \ +#define INTRA_PREDICT_VALDC_16X16_MSA(val) \ +static void intra_predict_##val##dc_16x16_msa(uint8_t *dst, \ + int32_t dst_stride) \ +{ \ + v16u8 out = (v16u8) __msa_fill_b(val); \ + \ + ST_UB8(out, out, out, out, out, out, out, out, dst, dst_stride); \ + dst += (8 * dst_stride); \ + ST_UB8(out, out, out, out, out, out, out, out, dst, dst_stride); \ } INTRA_PREDICT_VALDC_16X16_MSA(127); @@ -321,8 +320,10 @@ static void intra_predict_plane_16x16_msa(uint8_t *src, int32_t stride) v8i16 short_multiplier = { 1, 2, 3, 4, 5, 6, 7, 8 }; v4i32 int_multiplier = { 0, 1, 2, 3 }; v16u8 src_top = { 0 }; - v8i16 vec9, vec10; + v16u8 store0, store1; + v8i16 vec9, vec10, vec11, vec12; v4i32 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, res_add; + v4i32 reg0, reg1, reg2, reg3; load0 = LD(src - (stride + 1)); load1 = LD(src - (stride + 1) + 9); @@ -362,18 +363,28 @@ static void intra_predict_plane_16x16_msa(uint8_t *src, int32_t stride) vec6 = vec8 * 4; vec7 = vec8 * int_multiplier; - for (lpcnt = 16; lpcnt--;) { + for (lpcnt = 8; lpcnt--;) { vec0 = vec7; + reg0 = vec7; vec0 += vec4; + vec4 += vec5; + reg0 += vec4; vec1 = vec0 + vec6; + reg1 = reg0 + vec6; vec2 = vec1 + vec6; + reg2 = reg1 + vec6; vec3 = vec2 + vec6; + reg3 = reg2 + vec6; SRA_4V(vec0, vec1, vec2, vec3, 5); + SRA_4V(reg0, reg1, reg2, reg3, 5); PCKEV_H2_SH(vec1, vec0, vec3, vec2, vec9, vec10); + PCKEV_H2_SH(reg1, reg0, reg3, reg2, vec11, vec12); CLIP_SH2_0_255(vec9, vec10); - PCKEV_ST_SB(vec9, vec10, src); - src += stride; + CLIP_SH2_0_255(vec11, vec12); + PCKEV_B2_UB(vec10, vec9, vec12, vec11, store0, store1); + ST_UB2(store0, store1, src, stride); + src += 2 * stride; vec4 += vec5; } @@ -381,9 +392,9 @@ static void intra_predict_plane_16x16_msa(uint8_t *src, int32_t stride) static void intra_predict_dc_4blk_8x8_msa(uint8_t *src, int32_t stride) { - uint8_t lp_cnt; - uint32_t src0, src1, src3, src2 = 0; + uint32_t src0, src1, src3, src2; uint32_t out0, out1, out2, out3; + uint64_t store0, store1; v16u8 src_top; v8u16 add; v4u32 sum; @@ -393,12 +404,14 @@ static void intra_predict_dc_4blk_8x8_msa(uint8_t *src, int32_t stride) sum = __msa_hadd_u_w(add, add); src0 = __msa_copy_u_w((v4i32) sum, 0); src1 = __msa_copy_u_w((v4i32) sum, 1); - - for (lp_cnt = 0; lp_cnt < 4; lp_cnt++) { - src0 += src[lp_cnt * stride - 1]; - src2 += src[(4 + lp_cnt) * stride - 1]; - } - + src0 += src[0 * stride - 1]; + src0 += src[1 * stride - 1]; + src0 += src[2 * stride - 1]; + src0 += src[3 * stride - 1]; + src2 = src[4 * stride - 1]; + src2 += src[5 * stride - 1]; + src2 += src[6 * stride - 1]; + src2 += src[7 * stride - 1]; src0 = (src0 + 4) >> 3; src3 = (src1 + src2 + 4) >> 3; src1 = (src1 + 2) >> 2; @@ -407,69 +420,62 @@ static void intra_predict_dc_4blk_8x8_msa(uint8_t *src, int32_t stride) out1 = src1 * 0x01010101; out2 = src2 * 0x01010101; out3 = src3 * 0x01010101; + store0 = ((uint64_t) out1 << 32) | out0; + store1 = ((uint64_t) out3 << 32) | out2; - for (lp_cnt = 4; lp_cnt--;) { - SW(out0, src); - SW(out1, (src + 4)); - SW(out2, (src + 4 * stride)); - SW(out3, (src + 4 * stride + 4)); - src += stride; - } + SD4(store0, store0, store0, store0, src, stride); + src += (4 * stride); + SD4(store1, store1, store1, store1, src, stride); } static void intra_predict_hor_dc_8x8_msa(uint8_t *src, int32_t stride) { - uint8_t lp_cnt; - uint32_t src0 = 0, src1 = 0; + uint32_t src0, src1; uint64_t out0, out1; - for (lp_cnt = 0; lp_cnt < 4; lp_cnt++) { - src0 += src[lp_cnt * stride - 1]; - src1 += src[(4 + lp_cnt) * stride - 1]; - } - + src0 = src[0 * stride - 1]; + src0 += src[1 * stride - 1]; + src0 += src[2 * stride - 1]; + src0 += src[3 * stride - 1]; + src1 = src[4 * stride - 1]; + src1 += src[5 * stride - 1]; + src1 += src[6 * stride - 1]; + src1 += src[7 * stride - 1]; src0 = (src0 + 2) >> 2; src1 = (src1 + 2) >> 2; out0 = src0 * 0x0101010101010101; out1 = src1 * 0x0101010101010101; - for (lp_cnt = 4; lp_cnt--;) { - SD(out0, src); - SD(out1, (src + 4 * stride)); - src += stride; - } + SD4(out0, out0, out0, out0, src, stride); + src += (4 * stride); + SD4(out1, out1, out1, out1, src, stride); } static void intra_predict_vert_dc_8x8_msa(uint8_t *src, int32_t stride) { - uint8_t lp_cnt; - uint32_t out0 = 0, out1 = 0; - v16u8 src_top; + uint64_t out0; + v16i8 mask = { 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0 }; + v16u8 src_top, res0; v8u16 add; v4u32 sum; - v4i32 res0, res1; src_top = LD_UB(src - stride); add = __msa_hadd_u_h(src_top, src_top); sum = __msa_hadd_u_w(add, add); sum = (v4u32) __msa_srari_w((v4i32) sum, 2); - res0 = (v4i32) __msa_splati_b((v16i8) sum, 0); - res1 = (v4i32) __msa_splati_b((v16i8) sum, 4); - out0 = __msa_copy_u_w(res0, 0); - out1 = __msa_copy_u_w(res1, 0); - - for (lp_cnt = 8; lp_cnt--;) { - SW(out0, src); - SW(out1, src + 4); - src += stride; - } + res0 = (v16u8) __msa_vshf_b(mask, (v16i8) sum, (v16i8) sum); + out0 = __msa_copy_u_d((v2i64) res0, 0); + + SD4(out0, out0, out0, out0, src, stride); + src += (4 * stride); + SD4(out0, out0, out0, out0, src, stride); } static void intra_predict_mad_cow_dc_l0t_8x8_msa(uint8_t *src, int32_t stride) { - uint8_t lp_cnt; - uint32_t src0, src1, src2 = 0; + uint32_t src0, src1, src2; uint32_t out0, out1, out2; + uint64_t store0, store1; v16u8 src_top; v8u16 add; v4u32 sum; @@ -480,30 +486,30 @@ static void intra_predict_mad_cow_dc_l0t_8x8_msa(uint8_t *src, int32_t stride) src0 = __msa_copy_u_w((v4i32) sum, 0); src1 = __msa_copy_u_w((v4i32) sum, 1); - for (lp_cnt = 0; lp_cnt < 4; lp_cnt++) { - src2 += src[lp_cnt * stride - 1]; - } + src2 = src[0 * stride - 1]; + src2 += src[1 * stride - 1]; + src2 += src[2 * stride - 1]; + src2 += src[3 * stride - 1]; src2 = (src0 + src2 + 4) >> 3; src0 = (src0 + 2) >> 2; src1 = (src1 + 2) >> 2; out0 = src0 * 0x01010101; out1 = src1 * 0x01010101; out2 = src2 * 0x01010101; + store1 = ((uint64_t) out1 << 32); + store0 = store1 | ((uint64_t) out2); + store1 = store1 | ((uint64_t) out0); - for (lp_cnt = 4; lp_cnt--;) { - SW(out2, src); - SW(out1, src + 4); - SW(out0, src + stride * 4); - SW(out1, src + stride * 4 + 4); - src += stride; - } + SD4(store0, store0, store0, store0, src, stride); + src += (4 * stride); + SD4(store1, store1, store1, store1, src, stride); } static void intra_predict_mad_cow_dc_0lt_8x8_msa(uint8_t *src, int32_t stride) { - uint8_t lp_cnt; - uint32_t src0, src1, src2 = 0, src3; + uint32_t src0, src1, src2, src3; uint32_t out0, out1, out2, out3; + uint64_t store0, store1; v16u8 src_top; v8u16 add; v4u32 sum; @@ -514,10 +520,10 @@ static void intra_predict_mad_cow_dc_0lt_8x8_msa(uint8_t *src, int32_t stride) src0 = __msa_copy_u_w((v4i32) sum, 0); src1 = __msa_copy_u_w((v4i32) sum, 1); - for (lp_cnt = 0; lp_cnt < 4; lp_cnt++) { - src2 += src[(4 + lp_cnt) * stride - 1]; - } - + src2 = src[4 * stride - 1]; + src2 += src[5 * stride - 1]; + src2 += src[6 * stride - 1]; + src2 += src[7 * stride - 1]; src0 = (src0 + 2) >> 2; src3 = (src1 + src2 + 4) >> 3; src1 = (src1 + 2) >> 2; @@ -527,57 +533,49 @@ static void intra_predict_mad_cow_dc_0lt_8x8_msa(uint8_t *src, int32_t stride) out1 = src1 * 0x01010101; out2 = src2 * 0x01010101; out3 = src3 * 0x01010101; + store0 = ((uint64_t) out1 << 32) | out0; + store1 = ((uint64_t) out3 << 32) | out2; - for (lp_cnt = 4; lp_cnt--;) { - SW(out0, src); - SW(out1, src + 4); - SW(out2, src + stride * 4); - SW(out3, src + stride * 4 + 4); - src += stride; - } + SD4(store0, store0, store0, store0, src, stride); + src += (4 * stride); + SD4(store1, store1, store1, store1, src, stride); } static void intra_predict_mad_cow_dc_l00_8x8_msa(uint8_t *src, int32_t stride) { - uint8_t lp_cnt; - uint32_t src0 = 0; + uint32_t src0; uint64_t out0, out1; - for (lp_cnt = 0; lp_cnt < 4; lp_cnt++) { - src0 += src[lp_cnt * stride - 1]; - } - + src0 = src[0 * stride - 1]; + src0 += src[1 * stride - 1]; + src0 += src[2 * stride - 1]; + src0 += src[3 * stride - 1]; src0 = (src0 + 2) >> 2; out0 = src0 * 0x0101010101010101; out1 = 0x8080808080808080; - for (lp_cnt = 4; lp_cnt--;) { - SD(out0, src); - SD(out1, src + stride * 4); - src += stride; - } + SD4(out0, out0, out0, out0, src, stride); + src += (4 * stride); + SD4(out1, out1, out1, out1, src, stride); } static void intra_predict_mad_cow_dc_0l0_8x8_msa(uint8_t *src, int32_t stride) { - uint8_t lp_cnt; - uint32_t src0 = 0; + uint32_t src0; uint64_t out0, out1; - for (lp_cnt = 0; lp_cnt < 4; lp_cnt++) { - src0 += src[(4 + lp_cnt) * stride - 1]; - } - + src0 = src[4 * stride - 1]; + src0 += src[5 * stride - 1]; + src0 += src[6 * stride - 1]; + src0 += src[7 * stride - 1]; src0 = (src0 + 2) >> 2; out0 = 0x8080808080808080; out1 = src0 * 0x0101010101010101; - for (lp_cnt = 4; lp_cnt--;) { - SD(out0, src); - SD(out1, src + stride * 4); - src += stride; - } + SD4(out0, out0, out0, out0, src, stride); + src += (4 * stride); + SD4(out1, out1, out1, out1, src, stride); } void ff_h264_intra_predict_plane_8x8_msa(uint8_t *src, ptrdiff_t stride) From 16adbfe60c35d42f440ec7ed4c320282333602ba Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Thu, 21 Sep 2017 19:29:39 +0530 Subject: [PATCH 3162/3374] avcodec/mips: Improve avc chroma horiz mc msa functions Replace generic with block size specific function. Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/h264chroma_msa.c | 231 ++++++++++++++++++------------- 1 file changed, 133 insertions(+), 98 deletions(-) diff --git a/libavcodec/mips/h264chroma_msa.c b/libavcodec/mips/h264chroma_msa.c index 940e12db317d5..c27830d760868 100644 --- a/libavcodec/mips/h264chroma_msa.c +++ b/libavcodec/mips/h264chroma_msa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Shivraj Patil (Shivraj.Patil@imgtec.com) + * Copyright (c) 2015 - 2017 Shivraj Patil (Shivraj.Patil@imgtec.com) * * This file is part of FFmpeg. * @@ -29,8 +29,7 @@ static const uint8_t chroma_mask_arr[16 * 5] = { 0, 1, 1, 2, 16, 17, 17, 18, 16, 17, 17, 18, 18, 19, 19, 20 }; -static void avc_chroma_hz_2x2_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, +static void avc_chroma_hz_2x2_msa(uint8_t *src, uint8_t *dst, int32_t stride, uint32_t coeff0, uint32_t coeff1) { uint16_t out0, out1; @@ -44,7 +43,7 @@ static void avc_chroma_hz_2x2_msa(uint8_t *src, int32_t src_stride, mask = LD_SB(&chroma_mask_arr[0]); - LD_SB2(src, src_stride, src0, src1); + LD_SB2(src, stride, src0, src1); src0 = __msa_vshf_b(mask, src1, src0); res_r = __msa_dotp_u_h((v16u8) src0, coeff_vec); @@ -57,12 +56,11 @@ static void avc_chroma_hz_2x2_msa(uint8_t *src, int32_t src_stride, out1 = __msa_copy_u_h(res, 2); SH(out0, dst); - dst += dst_stride; + dst += stride; SH(out1, dst); } -static void avc_chroma_hz_2x4_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, +static void avc_chroma_hz_2x4_msa(uint8_t *src, uint8_t *dst, int32_t stride, uint32_t coeff0, uint32_t coeff1) { v16u8 src0, src1, src2, src3; @@ -75,7 +73,7 @@ static void avc_chroma_hz_2x4_msa(uint8_t *src, int32_t src_stride, mask = LD_SB(&chroma_mask_arr[64]); - LD_UB4(src, src_stride, src0, src1, src2, src3); + LD_UB4(src, stride, src0, src1, src2, src3); VSHF_B2_UB(src0, src1, src2, src3, mask, mask, src0, src2); @@ -87,64 +85,21 @@ static void avc_chroma_hz_2x4_msa(uint8_t *src, int32_t src_stride, res_r = __msa_sat_u_h(res_r, 7); res = (v8i16) __msa_pckev_b((v16i8) res_r, (v16i8) res_r); - ST2x4_UB(res, 0, dst, dst_stride); -} - -static void avc_chroma_hz_2x8_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - uint32_t coeff0, uint32_t coeff1) -{ - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - v8u16 res_r; - v8i16 res; - v16i8 mask; - v16i8 coeff_vec0 = __msa_fill_b(coeff0); - v16i8 coeff_vec1 = __msa_fill_b(coeff1); - v16u8 coeff_vec = (v16u8) __msa_ilvr_b(coeff_vec0, coeff_vec1); - - mask = LD_SB(&chroma_mask_arr[64]); - - LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - - VSHF_B2_UB(src0, src1, src2, src3, mask, mask, src0, src2); - VSHF_B2_UB(src4, src5, src6, src7, mask, mask, src4, src6); - - ILVR_D2_UB(src2, src0, src6, src4, src0, src4); - - res_r = __msa_dotp_u_h(src0, coeff_vec); - res_r <<= 3; - res_r = (v8u16) __msa_srari_h((v8i16) res_r, 6); - res_r = __msa_sat_u_h(res_r, 7); - res = (v8i16) __msa_pckev_b((v16i8) res_r, (v16i8) res_r); - - ST2x4_UB(res, 0, dst, dst_stride); - dst += (4 * dst_stride); - - res_r = __msa_dotp_u_h(src4, coeff_vec); - res_r <<= 3; - res_r = (v8u16) __msa_srari_h((v8i16) res_r, 6); - res_r = __msa_sat_u_h(res_r, 7); - res = (v8i16) __msa_pckev_b((v16i8) res_r, (v16i8) res_r); - - ST2x4_UB(res, 0, dst, dst_stride); + ST2x4_UB(res, 0, dst, stride); } -static void avc_chroma_hz_2w_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, +static void avc_chroma_hz_2w_msa(uint8_t *src, uint8_t *dst, int32_t stride, uint32_t coeff0, uint32_t coeff1, int32_t height) { if (2 == height) { - avc_chroma_hz_2x2_msa(src, src_stride, dst, dst_stride, coeff0, coeff1); + avc_chroma_hz_2x2_msa(src, dst, stride, coeff0, coeff1); } else if (4 == height) { - avc_chroma_hz_2x4_msa(src, src_stride, dst, dst_stride, coeff0, coeff1); - } else if (8 == height) { - avc_chroma_hz_2x8_msa(src, src_stride, dst, dst_stride, coeff0, coeff1); + avc_chroma_hz_2x4_msa(src, dst, stride, coeff0, coeff1); } } -static void avc_chroma_hz_4x2_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, +static void avc_chroma_hz_4x2_msa(uint8_t *src, uint8_t *dst, int32_t stride, uint32_t coeff0, uint32_t coeff1) { v16i8 src0, src1; @@ -157,7 +112,7 @@ static void avc_chroma_hz_4x2_msa(uint8_t *src, int32_t src_stride, mask = LD_SB(&chroma_mask_arr[0]); - LD_SB2(src, src_stride, src0, src1); + LD_SB2(src, stride, src0, src1); src0 = __msa_vshf_b(mask, src1, src0); res_r = __msa_dotp_u_h((v16u8) src0, coeff_vec); @@ -166,18 +121,14 @@ static void avc_chroma_hz_4x2_msa(uint8_t *src, int32_t src_stride, res_r = __msa_sat_u_h(res_r, 7); res = (v4i32) __msa_pckev_b((v16i8) res_r, (v16i8) res_r); - ST4x2_UB(res, dst, dst_stride); + ST4x2_UB(res, dst, stride); } -static void avc_chroma_hz_4x4multiple_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - uint32_t coeff0, uint32_t coeff1, - int32_t height) +static void avc_chroma_hz_4x4_msa(uint8_t *src, uint8_t *dst, int32_t stride, + uint32_t coeff0, uint32_t coeff1) { - uint32_t row; - v16u8 src0, src1, src2, src3; + v16u8 src0, src1, src2, src3, out; v8u16 res0_r, res1_r; - v4i32 res0, res1; v16i8 mask; v16i8 coeff_vec0 = __msa_fill_b(coeff0); v16i8 coeff_vec1 = __msa_fill_b(coeff1); @@ -185,42 +136,113 @@ static void avc_chroma_hz_4x4multiple_msa(uint8_t *src, int32_t src_stride, mask = LD_SB(&chroma_mask_arr[0]); - for (row = (height >> 2); row--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - VSHF_B2_UB(src0, src1, src2, src3, mask, mask, src0, src2); - DOTP_UB2_UH(src0, src2, coeff_vec, coeff_vec, res0_r, res1_r); + LD_UB4(src, stride, src0, src1, src2, src3); + VSHF_B2_UB(src0, src1, src2, src3, mask, mask, src0, src2); + DOTP_UB2_UH(src0, src2, coeff_vec, coeff_vec, res0_r, res1_r); + res0_r <<= 3; + res1_r <<= 3; + SRARI_H2_UH(res0_r, res1_r, 6); + SAT_UH2_UH(res0_r, res1_r, 7); + out = (v16u8) __msa_pckev_b((v16i8) res1_r, (v16i8) res0_r); + ST4x4_UB(out, out, 0, 1, 2, 3, dst, stride); +} - res0_r <<= 3; - res1_r <<= 3; +static void avc_chroma_hz_4x8_msa(uint8_t *src, uint8_t *dst, int32_t stride, + uint32_t coeff0, uint32_t coeff1) +{ + v16u8 src0, src1, src2, src3, src4, src5, src6, src7, out0, out1; + v16i8 mask; + v8u16 res0, res1, res2, res3; + v16i8 coeff_vec0 = __msa_fill_b(coeff0); + v16i8 coeff_vec1 = __msa_fill_b(coeff1); + v16u8 coeff_vec = (v16u8) __msa_ilvr_b(coeff_vec0, coeff_vec1); - SRARI_H2_UH(res0_r, res1_r, 6); - SAT_UH2_UH(res0_r, res1_r, 7); - PCKEV_B2_SW(res0_r, res0_r, res1_r, res1_r, res0, res1); + mask = LD_SB(&chroma_mask_arr[0]); - ST4x4_UB(res0, res1, 0, 1, 0, 1, dst, dst_stride); - dst += (4 * dst_stride); - } + LD_UB8(src, stride, src0, src1, src2, src3, src4, src5, src6, src7); + VSHF_B2_UB(src0, src1, src2, src3, mask, mask, src0, src2); + VSHF_B2_UB(src4, src5, src6, src7, mask, mask, src4, src6); + DOTP_UB2_UH(src0, src2, coeff_vec, coeff_vec, res0, res1); + DOTP_UB2_UH(src4, src6, coeff_vec, coeff_vec, res2, res3); + SLLI_4V(res0, res1, res2, res3, 3); + SRARI_H4_UH(res0, res1, res2, res3, 6); + SAT_UH4_UH(res0, res1, res2, res3, 7); + PCKEV_B2_UB(res1, res0, res3, res2, out0, out1); + ST4x8_UB(out0, out1, dst, stride); } -static void avc_chroma_hz_4w_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, +static void avc_chroma_hz_4w_msa(uint8_t *src, uint8_t *dst, int32_t stride, uint32_t coeff0, uint32_t coeff1, int32_t height) { if (2 == height) { - avc_chroma_hz_4x2_msa(src, src_stride, dst, dst_stride, coeff0, coeff1); - } else { - avc_chroma_hz_4x4multiple_msa(src, src_stride, dst, dst_stride, coeff0, - coeff1, height); + avc_chroma_hz_4x2_msa(src, dst, stride, coeff0, coeff1); + } else if (4 == height) { + avc_chroma_hz_4x4_msa(src, dst, stride, coeff0, coeff1); + } else if (8 == height) { + avc_chroma_hz_4x8_msa(src, dst, stride, coeff0, coeff1); } } -static void avc_chroma_hz_8w_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - uint32_t coeff0, uint32_t coeff1, - int32_t height) +static void avc_chroma_hz_8x4_msa(uint8_t *src, uint8_t *dst, int32_t stride, + uint32_t coeff0, uint32_t coeff1) +{ + v16u8 src0, src1, src2, src3, out0, out1; + v8u16 res0, res1, res2, res3; + v16i8 mask; + v16i8 coeff_vec0 = __msa_fill_b(coeff0); + v16i8 coeff_vec1 = __msa_fill_b(coeff1); + v16u8 coeff_vec = (v16u8) __msa_ilvr_b(coeff_vec0, coeff_vec1); + + mask = LD_SB(&chroma_mask_arr[32]); + LD_UB4(src, stride, src0, src1, src2, src3); + VSHF_B2_UB(src0, src0, src1, src1, mask, mask, src0, src1); + VSHF_B2_UB(src2, src2, src3, src3, mask, mask, src2, src3); + DOTP_UB4_UH(src0, src1, src2, src3, coeff_vec, coeff_vec, coeff_vec, + coeff_vec, res0, res1, res2, res3); + SLLI_4V(res0, res1, res2, res3, 3); + SRARI_H4_UH(res0, res1, res2, res3, 6); + SAT_UH4_UH(res0, res1, res2, res3, 7); + PCKEV_B2_UB(res1, res0, res3, res2, out0, out1); + ST8x4_UB(out0, out1, dst, stride); +} + +static void avc_chroma_hz_8x8_msa(uint8_t *src, uint8_t *dst, int32_t stride, + uint32_t coeff0, uint32_t coeff1) +{ + v16u8 src0, src1, src2, src3, src4, src5, src6, src7; + v16u8 out0, out1, out2, out3; + v8u16 res0, res1, res2, res3, res4, res5, res6, res7; + v16i8 mask; + v16i8 coeff_vec0 = __msa_fill_b(coeff0); + v16i8 coeff_vec1 = __msa_fill_b(coeff1); + v16u8 coeff_vec = (v16u8) __msa_ilvr_b(coeff_vec0, coeff_vec1); + + mask = LD_SB(&chroma_mask_arr[32]); + + LD_UB8(src, stride, src0, src1, src2, src3, src4, src5, src6, src7); + VSHF_B2_UB(src0, src0, src1, src1, mask, mask, src0, src1); + VSHF_B2_UB(src2, src2, src3, src3, mask, mask, src2, src3); + VSHF_B2_UB(src4, src4, src5, src5, mask, mask, src4, src5); + VSHF_B2_UB(src6, src6, src7, src7, mask, mask, src6, src7); + DOTP_UB4_UH(src0, src1, src2, src3, coeff_vec, coeff_vec, coeff_vec, + coeff_vec, res0, res1, res2, res3); + DOTP_UB4_UH(src4, src5, src6, src7, coeff_vec, coeff_vec, coeff_vec, + coeff_vec, res4, res5, res6, res7); + SLLI_4V(res0, res1, res2, res3, 3); + SLLI_4V(res4, res5, res6, res7, 3); + SRARI_H4_UH(res0, res1, res2, res3, 6); + SRARI_H4_UH(res4, res5, res6, res7, 6); + SAT_UH4_UH(res0, res1, res2, res3, 7); + SAT_UH4_UH(res4, res5, res6, res7, 7); + PCKEV_B2_UB(res1, res0, res3, res2, out0, out1); + PCKEV_B2_UB(res5, res4, res7, res6, out2, out3); + ST8x8_UB(out0, out1, out2, out3, dst, stride); +} + +static void avc_chroma_hz_nonmult_msa(uint8_t *src, uint8_t *dst, + int32_t stride, uint32_t coeff0, + uint32_t coeff1, int32_t height) { uint32_t row; v16u8 src0, src1, src2, src3, out0, out1; @@ -233,8 +255,8 @@ static void avc_chroma_hz_8w_msa(uint8_t *src, int32_t src_stride, mask = LD_SB(&chroma_mask_arr[32]); for (row = height >> 2; row--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); + LD_UB4(src, stride, src0, src1, src2, src3); + src += (4 * stride); VSHF_B2_UB(src0, src0, src1, src1, mask, mask, src0, src1); VSHF_B2_UB(src2, src2, src3, src3, mask, mask, src2, src3); @@ -244,14 +266,14 @@ static void avc_chroma_hz_8w_msa(uint8_t *src, int32_t src_stride, SRARI_H4_UH(res0, res1, res2, res3, 6); SAT_UH4_UH(res0, res1, res2, res3, 7); PCKEV_B2_UB(res1, res0, res3, res2, out0, out1); - ST8x4_UB(out0, out1, dst, dst_stride); - dst += (4 * dst_stride); + ST8x4_UB(out0, out1, dst, stride); + dst += (4 * stride); } if (0 != (height % 4)) { for (row = (height % 4); row--;) { src0 = LD_UB(src); - src += src_stride; + src += stride; src0 = (v16u8) __msa_vshf_b(mask, (v16i8) src0, (v16i8) src0); @@ -262,11 +284,24 @@ static void avc_chroma_hz_8w_msa(uint8_t *src, int32_t src_stride, res0 = (v8u16) __msa_pckev_b((v16i8) res0, (v16i8) res0); ST8x1_UB(res0, dst); - dst += dst_stride; + dst += stride; } } } +static void avc_chroma_hz_8w_msa(uint8_t *src, uint8_t *dst, int32_t stride, + uint32_t coeff0, uint32_t coeff1, + int32_t height) +{ + if (4 == height) { + avc_chroma_hz_8x4_msa(src, dst, stride, coeff0, coeff1); + } else if (8 == height) { + avc_chroma_hz_8x8_msa(src, dst, stride, coeff0, coeff1); + } else { + avc_chroma_hz_nonmult_msa(src, dst, stride, coeff0, coeff1, height); + } +} + static void avc_chroma_vt_2x2_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, uint32_t coeff0, uint32_t coeff1) @@ -1877,7 +1912,7 @@ void ff_put_h264_chroma_mc8_msa(uint8_t *dst, uint8_t *src, avc_chroma_hv_8w_msa(src, stride, dst, stride, x, (8 - x), y, (8 - y), height); } else if (x) { - avc_chroma_hz_8w_msa(src, stride, dst, stride, x, (8 - x), height); + avc_chroma_hz_8w_msa(src, dst, stride, x, (8 - x), height); } else if (y) { avc_chroma_vt_8w_msa(src, stride, dst, stride, y, (8 - y), height); } else { @@ -1896,7 +1931,7 @@ void ff_put_h264_chroma_mc4_msa(uint8_t *dst, uint8_t *src, avc_chroma_hv_4w_msa(src, stride, dst, stride, x, (8 - x), y, (8 - y), height); } else if (x) { - avc_chroma_hz_4w_msa(src, stride, dst, stride, x, (8 - x), height); + avc_chroma_hz_4w_msa(src, dst, stride, x, (8 - x), height); } else if (y) { avc_chroma_vt_4w_msa(src, stride, dst, stride, y, (8 - y), height); } else { @@ -1920,7 +1955,7 @@ void ff_put_h264_chroma_mc2_msa(uint8_t *dst, uint8_t *src, avc_chroma_hv_2w_msa(src, stride, dst, stride, x, (8 - x), y, (8 - y), height); } else if (x) { - avc_chroma_hz_2w_msa(src, stride, dst, stride, x, (8 - x), height); + avc_chroma_hz_2w_msa(src, dst, stride, x, (8 - x), height); } else if (y) { avc_chroma_vt_2w_msa(src, stride, dst, stride, y, (8 - y), height); } else { From 3d2da6d585509daddcd65f206b1a262c9c78cbce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Heusipp?= Date: Sun, 17 Sep 2017 15:35:50 +0200 Subject: [PATCH 3163/3374] avformat/libopenmpt: Query duration and metadata after selecting subsong MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Duration depends on the selected subsong and thus must be queried after selecting the subsong. There is no compelling reason to query other metadata earlier either. Tested with libopenmpt version: 0.2.8760-beta27 Libopenmpt configure options: --without-ogg --without-vorbis --without-vorbisfile --without-portaudio --without-portaudiocpp --without-mpg123 --without-pulseaudio --without-sndfile --without-flac Signed-off-by: Jörn Heusipp Signed-off-by: Josh de Kock --- libavformat/libopenmpt.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/libavformat/libopenmpt.c b/libavformat/libopenmpt.c index a7e385959a6f1..af6eb1ac4a028 100644 --- a/libavformat/libopenmpt.c +++ b/libavformat/libopenmpt.c @@ -93,14 +93,7 @@ static int read_header_openmpt(AVFormatContext *s) if (!openmpt->module) return AVERROR_INVALIDDATA; - openmpt->channels = av_get_channel_layout_nb_channels(openmpt->layout); - openmpt->duration = openmpt_module_get_duration_seconds(openmpt->module); - - add_meta(s, "artist", openmpt_module_get_metadata(openmpt->module, "artist")); - add_meta(s, "title", openmpt_module_get_metadata(openmpt->module, "title")); - add_meta(s, "encoder", openmpt_module_get_metadata(openmpt->module, "tracker")); - add_meta(s, "comment", openmpt_module_get_metadata(openmpt->module, "message")); - add_meta(s, "date", openmpt_module_get_metadata(openmpt->module, "date")); + openmpt->channels = av_get_channel_layout_nb_channels(openmpt->layout); if (openmpt->subsong >= openmpt_module_get_num_subsongs(openmpt->module)) { openmpt_module_destroy(openmpt->module); @@ -120,6 +113,14 @@ static int read_header_openmpt(AVFormatContext *s) } } + openmpt->duration = openmpt_module_get_duration_seconds(openmpt->module); + + add_meta(s, "artist", openmpt_module_get_metadata(openmpt->module, "artist")); + add_meta(s, "title", openmpt_module_get_metadata(openmpt->module, "title")); + add_meta(s, "encoder", openmpt_module_get_metadata(openmpt->module, "tracker")); + add_meta(s, "comment", openmpt_module_get_metadata(openmpt->module, "message")); + add_meta(s, "date", openmpt_module_get_metadata(openmpt->module, "date")); + st = avformat_new_stream(s, NULL); if (!st) { openmpt_module_destroy(openmpt->module); From 3dabb9c69db114b1f30c30e0a2788cffc50bac40 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 22 Sep 2017 20:45:26 +0200 Subject: [PATCH 3164/3374] avcodec/takdec: Fix integer overflows in decode_subframe() Fixes: runtime error: signed integer overflow: -1562477869 + -691460395 cannot be represented in type 'int' Fixes: 3196/clusterfuzz-testcase-minimized-4528307146063872 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/takdec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c index 1676313b7cb9f..9c253c1e8e723 100644 --- a/libavcodec/takdec.c +++ b/libavcodec/takdec.c @@ -486,10 +486,10 @@ static int decode_subframe(TAKDecContext *s, int32_t *decoded, v += (unsigned)s->adsp.scalarproduct_int16(&s->residues[i], s->filter, filter_order & -16); for (j = filter_order & -16; j < filter_order; j += 4) { - v += s->residues[i + j + 3] * s->filter[j + 3] + - s->residues[i + j + 2] * s->filter[j + 2] + - s->residues[i + j + 1] * s->filter[j + 1] + - s->residues[i + j ] * s->filter[j ]; + v += s->residues[i + j + 3] * (unsigned)s->filter[j + 3] + + s->residues[i + j + 2] * (unsigned)s->filter[j + 2] + + s->residues[i + j + 1] * (unsigned)s->filter[j + 1] + + s->residues[i + j ] * (unsigned)s->filter[j ]; } v = (av_clip_intp2(v >> filter_quant, 13) * (1 << dshift)) - (unsigned)*decoded; *decoded++ = v; From 4f5eaf0b5956e492ee5023929669b1d09aaf6299 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 22 Sep 2017 20:45:28 +0200 Subject: [PATCH 3165/3374] avcodec/proresdec2: Check bits in DECODE_CODEWORD(), fixes invalid shift Fixes: runtime error: shift exponent 42 is too large for 32-bit type 'unsigned int' Fixes: 3410/clusterfuzz-testcase-minimized-5313377960198144 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/proresdec2.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c index 73b161f9a5c48..e0779080270f6 100644 --- a/libavcodec/proresdec2.c +++ b/libavcodec/proresdec2.c @@ -267,6 +267,8 @@ static int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, cons \ if (q > switch_bits) { /* exp golomb */ \ bits = exp_order - switch_bits + (q<<1); \ + if (bits > MIN_CACHE_BITS) \ + return AVERROR_INVALIDDATA; \ val = SHOW_UBITS(re, gb, bits) - (1 << exp_order) + \ ((switch_bits + 1) << rice_order); \ SKIP_BITS(re, gb, bits); \ @@ -286,7 +288,7 @@ static int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, cons static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70}; -static av_always_inline void decode_dc_coeffs(GetBitContext *gb, int16_t *out, +static av_always_inline int decode_dc_coeffs(GetBitContext *gb, int16_t *out, int blocks_per_slice) { int16_t prev_dc; @@ -310,6 +312,7 @@ static av_always_inline void decode_dc_coeffs(GetBitContext *gb, int16_t *out, out[0] = prev_dc; } CLOSE_READER(re, gb); + return 0; } // adaptive codebook switching lut according to previous run/level values @@ -376,7 +379,8 @@ static int decode_slice_luma(AVCodecContext *avctx, SliceContext *slice, init_get_bits(&gb, buf, buf_size << 3); - decode_dc_coeffs(&gb, blocks, blocks_per_slice); + if ((ret = decode_dc_coeffs(&gb, blocks, blocks_per_slice)) < 0) + return ret; if ((ret = decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice)) < 0) return ret; @@ -409,7 +413,8 @@ static int decode_slice_chroma(AVCodecContext *avctx, SliceContext *slice, init_get_bits(&gb, buf, buf_size << 3); - decode_dc_coeffs(&gb, blocks, blocks_per_slice); + if ((ret = decode_dc_coeffs(&gb, blocks, blocks_per_slice)) < 0) + return ret; if ((ret = decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice)) < 0) return ret; From 5d31f03a0264cac24434c8108daef4ccba6d28f9 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 22 Sep 2017 20:45:27 +0200 Subject: [PATCH 3166/3374] avcodec/takdec: Fix integer overflow in decode_lpc() Fixes: runtime error: signed integer overflow: 16748560 + 2143729712 cannot be represented in type 'int' Fixes: 3202/clusterfuzz-testcase-minimized-4988291642294272 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/takdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c index 9c253c1e8e723..0439a3ac9b922 100644 --- a/libavcodec/takdec.c +++ b/libavcodec/takdec.c @@ -206,7 +206,7 @@ static void decode_lpc(int32_t *coeffs, int mode, int length) unsigned a1 = *coeffs++; for (i = 0; i < length - 1 >> 1; i++) { *coeffs += a1; - coeffs[1] += *coeffs; + coeffs[1] += (unsigned)*coeffs; a1 = coeffs[1]; coeffs += 2; } From 45c15b7490cfb1106ce3153e77f04988b74a9ca1 Mon Sep 17 00:00:00 2001 From: Martin Vignali Date: Sat, 23 Sep 2017 21:43:44 +0200 Subject: [PATCH 3167/3374] libavformat : add mov dataformat tag for HapAlphaOnly and HapQAlpha Signed-off-by: Michael Niedermayer --- libavformat/isom.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavformat/isom.c b/libavformat/isom.c index 0ae84504697d2..77983c5eaabbf 100644 --- a/libavformat/isom.c +++ b/libavformat/isom.c @@ -274,6 +274,8 @@ const AVCodecTag ff_codec_movvideo_tags[] = { { AV_CODEC_ID_HAP, MKTAG('H', 'a', 'p', '1') }, { AV_CODEC_ID_HAP, MKTAG('H', 'a', 'p', '5') }, { AV_CODEC_ID_HAP, MKTAG('H', 'a', 'p', 'Y') }, + { AV_CODEC_ID_HAP, MKTAG('H', 'a', 'p', 'A') }, + { AV_CODEC_ID_HAP, MKTAG('H', 'a', 'p', 'M') }, { AV_CODEC_ID_DXV, MKTAG('D', 'X', 'D', '3') }, { AV_CODEC_ID_DXV, MKTAG('D', 'X', 'D', 'I') }, From cab71e4e4e51c8cee4fdd90af35498796797615c Mon Sep 17 00:00:00 2001 From: Martin Vignali Date: Sat, 23 Sep 2017 21:50:54 +0200 Subject: [PATCH 3168/3374] libavcodec/hapdec : add support HapAlphaOnly Signed-off-by: Michael Niedermayer --- libavcodec/hap.h | 1 + libavcodec/hapdec.c | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/libavcodec/hap.h b/libavcodec/hap.h index f39e621805fe7..0ee65335d913b 100644 --- a/libavcodec/hap.h +++ b/libavcodec/hap.h @@ -34,6 +34,7 @@ enum HapTextureFormat { HAP_FMT_RGBDXT1 = 0x0B, HAP_FMT_RGBADXT5 = 0x0E, HAP_FMT_YCOCGDXT5 = 0x0F, + HAP_FMT_RGTC1 = 0x01, }; enum HapCompressor { diff --git a/libavcodec/hapdec.c b/libavcodec/hapdec.c index a1cb0c76aaa91..fc9dff10f1923 100644 --- a/libavcodec/hapdec.c +++ b/libavcodec/hapdec.c @@ -24,7 +24,7 @@ * @file * Hap decoder * - * Fourcc: Hap1, Hap5, HapY + * Fourcc: Hap1, Hap5, HapY, HapA, HapM * * https://github.com/Vidvox/hap/blob/master/documentation/HapVideoDRAFT.md */ @@ -163,7 +163,8 @@ static int hap_parse_frame_header(AVCodecContext *avctx) if ((avctx->codec_tag == MKTAG('H','a','p','1') && (section_type & 0x0F) != HAP_FMT_RGBDXT1) || (avctx->codec_tag == MKTAG('H','a','p','5') && (section_type & 0x0F) != HAP_FMT_RGBADXT5) || - (avctx->codec_tag == MKTAG('H','a','p','Y') && (section_type & 0x0F) != HAP_FMT_YCOCGDXT5)) { + (avctx->codec_tag == MKTAG('H','a','p','Y') && (section_type & 0x0F) != HAP_FMT_YCOCGDXT5) || + (avctx->codec_tag == MKTAG('H','a','p','A') && (section_type & 0x0F) != HAP_FMT_RGTC1)) { av_log(avctx, AV_LOG_ERROR, "Invalid texture format %#04x.\n", section_type & 0x0F); return AVERROR_INVALIDDATA; @@ -403,6 +404,15 @@ static av_cold int hap_init(AVCodecContext *avctx) ctx->tex_fun = ctx->dxtc.dxt5ys_block; avctx->pix_fmt = AV_PIX_FMT_RGB0; break; + case MKTAG('H','a','p','A'): + texture_name = "RGTC1"; + ctx->tex_rat = 8; + ctx->tex_fun = ctx->dxtc.rgtc1u_block; + avctx->pix_fmt = AV_PIX_FMT_RGB0; + break; + case MKTAG('H','a','p','M'): + avpriv_report_missing_feature(avctx, "HapQAlpha"); + return AVERROR_PATCHWELCOME; default: return AVERROR_DECODER_NOT_FOUND; } From 4efb1658f5ab4e785b8420a1bc42694494a3d775 Mon Sep 17 00:00:00 2001 From: Paras Chadha Date: Sat, 16 Sep 2017 03:24:07 +0530 Subject: [PATCH 3169/3374] fate/fits: add missing png & gif dependencies Signed-off-by: Paras Chadha Signed-off-by: Michael Niedermayer --- tests/fate/demux.mak | 2 +- tests/fate/fits.mak | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/fate/demux.mak b/tests/fate/demux.mak index 261b004d691f1..68d4b6a54ce75 100644 --- a/tests/fate/demux.mak +++ b/tests/fate/demux.mak @@ -36,7 +36,7 @@ fate-d-cinema-demux: CMD = framecrc -i $(TARGET_SAMPLES)/d-cinema/THX_Science_FL FATE_SAMPLES_DEMUX-$(CONFIG_EA_DEMUXER) += fate-d-eavp6-demux fate-d-eavp6-demux: CMD = framecrc -i $(TARGET_SAMPLES)/ea-vp6/SmallRing.vp6 -map 0 -vcodec copy -FATE_SAMPLES_DEMUX-$(CONFIG_FITS_DEMUXER) += fate-fits-demux +FATE_SAMPLES_DEMUX-$(call ALLYES, GIF_DEMUXER FITS_DEMUXER GIF_DECODER FITS_ENCODER FITS_MUXER) += fate-fits-demux fate-fits-demux: tests/data/fits-multi.fits fate-fits-demux: CMD = framecrc -i $(TARGET_PATH)/tests/data/fits-multi.fits -vcodec copy diff --git a/tests/fate/fits.mak b/tests/fate/fits.mak index bc1b771a525c6..3d58f98807007 100644 --- a/tests/fate/fits.mak +++ b/tests/fate/fits.mak @@ -29,7 +29,7 @@ fate-fitsdec-bitpix-32: CMD = framecrc -i $(TARGET_SAMPLES)/fits/tst0005.fits -p FATE_FITS_DEC-$(call DEMDEC, FITS, FITS) += fate-fitsdec-bitpix-64 fate-fitsdec-bitpix-64: CMD = framecrc -i $(TARGET_SAMPLES)/fits/tst0006.fits -pix_fmt gray16 -FATE_FITS_DEC-$(call DEMDEC, FITS, FITS) += fate-fitsdec-multi +FATE_FITS_DEC-$(call ALLYES, GIF_DEMUXER FITS_DEMUXER GIF_DECODER FITS_DECODER FITS_ENCODER FITS_MUXER) += fate-fitsdec-multi fate-fitsdec-multi: tests/data/fits-multi.fits fate-fitsdec-multi: CMD = framecrc -i $(TARGET_PATH)/tests/data/fits-multi.fits -pix_fmt gbrap @@ -39,7 +39,7 @@ fate-fitsdec%: CMD = framecrc -i $(SRC) -pix_fmt $(PIXFMT) FATE_FITS_DEC_PIXFMT = gray gbrp gbrp16 gbrap16 $(FATE_FITS_DEC_PIXFMT:%=fate-fitsdec-%): fate-fitsdec-%: tests/data/lena-%.fits -FATE_FITS_DEC-$(call DEMDEC, FITS, FITS) += $(FATE_FITS_DEC_PIXFMT:%=fate-fitsdec-%) +FATE_FITS_DEC-$(call ALLYES, FITS_DEMUXER IMAGE2_DEMUXER FITS_DECODER PNG_DECODER FITS_ENCODER FITS_MUXER) += $(FATE_FITS_DEC_PIXFMT:%=fate-fitsdec-%) FATE_FITS += $(FATE_FITS_DEC-yes) fate-fitsdec: $(FATE_FITS_DEC-yes) @@ -50,7 +50,7 @@ fate-fitsenc%: CMD = framecrc -i $(SRC) -c:v fits -pix_fmt $(PIXFMT) FATE_FITS_ENC_PIXFMT = gray gray16be gbrp gbrap gbrp16be gbrap16be $(FATE_FITS_ENC_PIXFMT:%=fate-fitsenc-%): tests/data/fits-multi.fits -FATE_FITS_ENC-$(call ENCDEC, FITS, FITS) += $(FATE_FITS_ENC_PIXFMT:%=fate-fitsenc-%) +FATE_FITS_ENC-$(call ALLYES, GIF_DEMUXER GIF_DECODER FITS_ENCODER FITS_MUXER) += $(FATE_FITS_ENC_PIXFMT:%=fate-fitsenc-%) FATE_FITS += $(FATE_FITS_ENC-yes) fate-fitsenc: $(FATE_FITS_ENC-yes) From 5d07275529f6544dd61480875908287dd6f7a426 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Mon, 25 Sep 2017 12:12:13 +0200 Subject: [PATCH 3170/3374] avfilter/af_headphone: increase max ir length Signed-off-by: Paul B Mahol --- libavfilter/af_headphone.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/af_headphone.c b/libavfilter/af_headphone.c index f6edccc9bd2da..3b76d1d737054 100644 --- a/libavfilter/af_headphone.c +++ b/libavfilter/af_headphone.c @@ -335,7 +335,7 @@ static int read_ir(AVFilterLink *inlink, AVFrame *frame) av_frame_free(&frame); ir_len = av_audio_fifo_size(s->in[input_number].fifo); - max_ir_len = 4096; + max_ir_len = 65536; if (ir_len > max_ir_len) { av_log(ctx, AV_LOG_ERROR, "Too big length of IRs: %d > %d.\n", ir_len, max_ir_len); return AVERROR(EINVAL); From d491d6a0cd01d9a1ab2061c6c8a977b1aa578d70 Mon Sep 17 00:00:00 2001 From: Thomas Mundt Date: Tue, 19 Sep 2017 22:49:09 +0200 Subject: [PATCH 3171/3374] avfilter/interlace: rename two variables for consistency Signed-off-by: Thomas Mundt --- libavfilter/vf_interlace.c | 10 +++++----- libavfilter/vf_tinterlace.c | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/libavfilter/vf_interlace.c b/libavfilter/vf_interlace.c index 0fdfe70f4c8be..731069818f227 100644 --- a/libavfilter/vf_interlace.c +++ b/libavfilter/vf_interlace.c @@ -102,19 +102,19 @@ static void lowpass_line_complex_c(uint8_t *dstp, ptrdiff_t linesize, const uint8_t *srcp_below = srcp + pref; const uint8_t *srcp_above2 = srcp + mref * 2; const uint8_t *srcp_below2 = srcp + pref * 2; - int i, srcp_x, srcp_ab; + int i, src_x, src_ab; for (i = 0; i < linesize; i++) { // this calculation is an integer representation of // '0.75 * current + 0.25 * above + 0.25 * below - 0.125 * above2 - 0.125 * below2' // '4 +' is for rounding. - srcp_x = srcp[i] << 1; - srcp_ab = srcp_above[i] + srcp_below[i]; - dstp[i] = av_clip_uint8((4 + ((srcp[i] + srcp_x + srcp_ab) << 1) + src_x = srcp[i] << 1; + src_ab = srcp_above[i] + srcp_below[i]; + dstp[i] = av_clip_uint8((4 + ((srcp[i] + src_x + src_ab) << 1) - srcp_above2[i] - srcp_below2[i]) >> 3); // Prevent over-sharpening: // dst must not exceed src when the average of above and below // is less than src. And the other way around. - if (srcp_ab > srcp_x) { + if (src_ab > src_x) { if (dstp[i] < srcp[i]) dstp[i] = srcp[i]; } else if (dstp[i] > srcp[i]) diff --git a/libavfilter/vf_tinterlace.c b/libavfilter/vf_tinterlace.c index 163ab7c18460e..f13791d254f46 100644 --- a/libavfilter/vf_tinterlace.c +++ b/libavfilter/vf_tinterlace.c @@ -133,19 +133,19 @@ static void lowpass_line_complex_c(uint8_t *dstp, ptrdiff_t width, const uint8_t const uint8_t *srcp_below = srcp + pref; const uint8_t *srcp_above2 = srcp + mref * 2; const uint8_t *srcp_below2 = srcp + pref * 2; - int i, srcp_x, srcp_ab; + int i, src_x, src_ab; for (i = 0; i < width; i++) { // this calculation is an integer representation of // '0.75 * current + 0.25 * above + 0.25 * below - 0.125 * above2 - 0.125 * below2' // '4 +' is for rounding. - srcp_x = srcp[i] << 1; - srcp_ab = srcp_above[i] + srcp_below[i]; - dstp[i] = av_clip_uint8((4 + ((srcp[i] + srcp_x + srcp_ab) << 1) + src_x = srcp[i] << 1; + src_ab = srcp_above[i] + srcp_below[i]; + dstp[i] = av_clip_uint8((4 + ((srcp[i] + src_x + src_ab) << 1) - srcp_above2[i] - srcp_below2[i]) >> 3); // Prevent over-sharpening: // dst must not exceed src when the average of above and below // is less than src. And the other way around. - if (srcp_ab > srcp_x) { + if (src_ab > src_x) { if (dstp[i] < srcp[i]) dstp[i] = srcp[i]; } else if (dstp[i] > srcp[i]) From ecb9741ba294d7617ca85aaec0226ee9be7f518d Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 23 Sep 2017 15:59:56 -0300 Subject: [PATCH 3172/3374] avcodec/avpacket: deprecate av_copy_packet() It does the same thing as av_packet_ref(). Signed-off-by: James Almer --- libavcodec/avcodec.h | 3 +++ libavcodec/avpacket.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 5c84974e03b2f..07d9f3e255dcc 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -4614,7 +4614,10 @@ int av_dup_packet(AVPacket *pkt); * Copy packet, including contents * * @return 0 on success, negative AVERROR on fail + * + * @deprecated Use av_packet_ref */ +attribute_deprecated int av_copy_packet(AVPacket *dst, const AVPacket *src); /** diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index 5ce32281661d5..b07180eac883a 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -247,8 +247,6 @@ int av_copy_packet_side_data(AVPacket *pkt, const AVPacket *src) av_packet_unref(pkt); return AVERROR(ENOMEM); } -FF_ENABLE_DEPRECATION_WARNINGS -#endif int av_dup_packet(AVPacket *pkt) { @@ -266,6 +264,8 @@ int av_copy_packet(AVPacket *dst, const AVPacket *src) *dst = *src; return copy_packet_data(dst, src, 0); } +FF_ENABLE_DEPRECATION_WARNINGS +#endif void av_packet_free_side_data(AVPacket *pkt) { From a447b75de8edb8658ad3c50af0c342bcdda2b57b Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 23 Sep 2017 20:30:13 -0300 Subject: [PATCH 3173/3374] avformat: replace all uses of av_copy_packet() Signed-off-by: James Almer --- libavformat/aiffenc.c | 3 ++- libavformat/apngenc.c | 4 ++-- libavformat/gif.c | 4 ++-- libavformat/img2enc.c | 2 +- libavformat/movenc.c | 7 ++++--- libavformat/mp3enc.c | 2 +- libavformat/subtitles.c | 2 +- libavformat/webpenc.c | 2 +- libavformat/wtvenc.c | 2 +- 9 files changed, 15 insertions(+), 13 deletions(-) diff --git a/libavformat/aiffenc.c b/libavformat/aiffenc.c index fcadf149a0354..aab37418f0d35 100644 --- a/libavformat/aiffenc.c +++ b/libavformat/aiffenc.c @@ -233,7 +233,8 @@ static int aiff_write_packet(AVFormatContext *s, AVPacket *pkt) if (!pict_list) return AVERROR(ENOMEM); - if ((ret = av_copy_packet(&pict_list->pkt, pkt)) < 0) { + ret = av_packet_ref(&pict_list->pkt, pkt); + if (ret < 0) { av_freep(&pict_list); return ret; } diff --git a/libavformat/apngenc.c b/libavformat/apngenc.c index d4191c02cc65e..77c1c916c2e8d 100644 --- a/libavformat/apngenc.c +++ b/libavformat/apngenc.c @@ -218,7 +218,7 @@ static int flush_packet(AVFormatContext *format_context, AVPacket *packet) av_packet_unref(apng->prev_packet); if (packet) - av_copy_packet(apng->prev_packet, packet); + av_packet_ref(apng->prev_packet, packet); return 0; } @@ -232,7 +232,7 @@ static int apng_write_packet(AVFormatContext *format_context, AVPacket *packet) if (!apng->prev_packet) return AVERROR(ENOMEM); - av_copy_packet(apng->prev_packet, packet); + av_packet_ref(apng->prev_packet, packet); } else { ret = flush_packet(format_context, packet); if (ret < 0) diff --git a/libavformat/gif.c b/libavformat/gif.c index d6113dbc85fd5..01d98a27b0535 100644 --- a/libavformat/gif.c +++ b/libavformat/gif.c @@ -175,7 +175,7 @@ static int flush_packet(AVFormatContext *s, AVPacket *new) av_packet_unref(gif->prev_pkt); if (new) - av_copy_packet(gif->prev_pkt, new); + av_packet_ref(gif->prev_pkt, new); return 0; } @@ -206,7 +206,7 @@ static int gif_write_packet(AVFormatContext *s, AVPacket *pkt) gif_image_write_header(s->pb, video_st, gif->loop, palette); } - return av_copy_packet(gif->prev_pkt, pkt); + return av_packet_ref(gif->prev_pkt, pkt); } return flush_packet(s, pkt); } diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c index 87b5ec231737d..9b60bfc75cb6e 100644 --- a/libavformat/img2enc.c +++ b/libavformat/img2enc.c @@ -161,7 +161,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) st->id = pkt->stream_index; fmt->pb = pb[0]; - if ((ret = av_copy_packet(&pkt2, pkt)) < 0 || + if ((ret = av_packet_ref(&pkt2, pkt)) < 0 || (ret = av_dup_packet(&pkt2)) < 0 || (ret = avcodec_parameters_copy(st->codecpar, s->streams[0]->codecpar)) < 0 || (ret = avformat_write_header(fmt, NULL)) < 0 || diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 10b959ad02321..ba3e263f9f3e8 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -437,8 +437,8 @@ static int handle_eac3(MOVMuxContext *mov, AVPacket *pkt, MOVTrack *track) return AVERROR_INVALIDDATA; if (!info->num_blocks) { - int ret; - if ((ret = av_copy_packet(&info->pkt, pkt)) < 0) + int ret = av_packet_ref(&info->pkt, pkt); + if (ret < 0) return ret; info->num_blocks = num_blocks; return 0; @@ -454,7 +454,8 @@ static int handle_eac3(MOVMuxContext *mov, AVPacket *pkt, MOVTrack *track) if (info->num_blocks != 6) return 0; av_packet_unref(pkt); - if ((ret = av_copy_packet(pkt, &info->pkt)) < 0) + ret = av_packet_ref(pkt, &info->pkt); + if (ret < 0) return ret; av_packet_unref(&info->pkt); info->num_blocks = 0; diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c index 3cbf7bd13702e..826878eca179b 100644 --- a/libavformat/mp3enc.c +++ b/libavformat/mp3enc.c @@ -523,7 +523,7 @@ static int mp3_write_packet(AVFormatContext *s, AVPacket *pkt) return mp3_write_audio_packet(s, pkt); } - ret = av_copy_packet(&pktl->pkt, pkt); + ret = av_packet_ref(&pktl->pkt, pkt); if (ret < 0) { av_freep(&pktl); return ret; diff --git a/libavformat/subtitles.c b/libavformat/subtitles.c index 108f909c84872..93c9ef05cf0af 100644 --- a/libavformat/subtitles.c +++ b/libavformat/subtitles.c @@ -211,7 +211,7 @@ int ff_subtitles_queue_read_packet(FFDemuxSubtitlesQueue *q, AVPacket *pkt) if (q->current_sub_idx == q->nb_subs) return AVERROR_EOF; - if (av_copy_packet(pkt, sub) < 0) { + if (av_packet_ref(pkt, sub) < 0) { return AVERROR(ENOMEM); } diff --git a/libavformat/webpenc.c b/libavformat/webpenc.c index 2e0147cefd49a..9fb472257d7af 100644 --- a/libavformat/webpenc.c +++ b/libavformat/webpenc.c @@ -158,7 +158,7 @@ static int webp_write_packet(AVFormatContext *s, AVPacket *pkt) int ret; if ((ret = flush(s, 0, pkt->pts)) < 0) return ret; - av_copy_packet(&w->last_pkt, pkt); + av_packet_ref(&w->last_pkt, pkt); } ++w->frame_count; diff --git a/libavformat/wtvenc.c b/libavformat/wtvenc.c index 4925a60049876..4a68b8133f997 100644 --- a/libavformat/wtvenc.c +++ b/libavformat/wtvenc.c @@ -464,7 +464,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) AVStream *st = s->streams[pkt->stream_index]; if (st->codecpar->codec_id == AV_CODEC_ID_MJPEG && !wctx->thumbnail.size) { - av_copy_packet(&wctx->thumbnail, pkt); + av_packet_ref(&wctx->thumbnail, pkt); return 0; } else if (st->codecpar->codec_id == AV_CODEC_ID_H264) { int ret = ff_check_h264_startcode(s, st, pkt); From c463b81d037fd88fdda432324b995d82510a5bc7 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 23 Sep 2017 20:32:42 -0300 Subject: [PATCH 3174/3374] ffplay: replace use of av_copy_packet() Signed-off-by: James Almer --- ffplay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ffplay.c b/ffplay.c index 45f2d78443fc0..9f7774613c20a 100644 --- a/ffplay.c +++ b/ffplay.c @@ -2978,7 +2978,7 @@ static int read_thread(void *arg) if (is->queue_attachments_req) { if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) { AVPacket copy = { 0 }; - if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0) + if ((ret = av_packet_ref(©, &is->video_st->attached_pic)) < 0) goto fail; packet_queue_put(&is->videoq, ©); packet_queue_put_nullpacket(&is->videoq, is->video_stream); From 89a2472ec536cd4e22804d0c377d54c24b98f5f2 Mon Sep 17 00:00:00 2001 From: James Almer Date: Mon, 25 Sep 2017 23:14:14 -0300 Subject: [PATCH 3175/3374] avformat/img2enc: remove av_dup_packet() call It's unnecessary after a call to av_packet_ref(). Signed-off-by: James Almer --- libavformat/img2enc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c index 9b60bfc75cb6e..d793807b33cef 100644 --- a/libavformat/img2enc.c +++ b/libavformat/img2enc.c @@ -162,7 +162,6 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) fmt->pb = pb[0]; if ((ret = av_packet_ref(&pkt2, pkt)) < 0 || - (ret = av_dup_packet(&pkt2)) < 0 || (ret = avcodec_parameters_copy(st->codecpar, s->streams[0]->codecpar)) < 0 || (ret = avformat_write_header(fmt, NULL)) < 0 || (ret = av_interleaved_write_frame(fmt, &pkt2)) < 0 || From eec67f25224a48047da57be18b610b11b0fd0bfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Devernay?= Date: Tue, 12 Sep 2017 15:26:15 +0200 Subject: [PATCH 3176/3374] avcodec/dnxhdenc: fix DNxHR 444 encoding crashes Fixes #6649. --- libavcodec/dnxhdenc.c | 16 ++++++++-------- libavcodec/dnxhdenc.h | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c index 5a0e6de6a51a1..0d80381a2da85 100644 --- a/libavcodec/dnxhdenc.c +++ b/libavcodec/dnxhdenc.c @@ -749,14 +749,14 @@ void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y) ptr_y = &ctx->edge_buf_y[0]; ptr_u = &ctx->edge_buf_uv[0][0]; ptr_v = &ctx->edge_buf_uv[1][0]; - } else if (ctx->bit_depth == 10 && vdsp->emulated_edge_mc && ((mb_x << 3) + 8 > ctx->m.avctx->width || - (mb_y << 3) + 8 > ctx->m.avctx->height)) { - int y_w = ctx->m.avctx->width - (mb_x << 3); - int y_h = ctx->m.avctx->height - (mb_y << 3); + } else if (ctx->bit_depth == 10 && vdsp->emulated_edge_mc && ((mb_x << 4) + 16 > ctx->m.avctx->width || + (mb_y << 4) + 16 > ctx->m.avctx->height)) { + int y_w = ctx->m.avctx->width - (mb_x << 4); + int y_h = ctx->m.avctx->height - (mb_y << 4); int uv_w = ctx->is_444 ? y_w : (y_w + 1) / 2; int uv_h = y_h; - linesize = 16; - uvlinesize = 8 + 8 * ctx->is_444; + linesize = 32; + uvlinesize = 16 + 16 * ctx->is_444; vdsp->emulated_edge_mc(&ctx->edge_buf_y[0], ptr_y, linesize, ctx->m.linesize, @@ -771,8 +771,8 @@ void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y) uvlinesize / 2, 16, 0, 0, uv_w, uv_h); - dct_y_offset = bw * linesize; - dct_uv_offset = bw * uvlinesize; + dct_y_offset = bw * linesize / 2; + dct_uv_offset = bw * uvlinesize / 2; ptr_y = &ctx->edge_buf_y[0]; ptr_u = &ctx->edge_buf_uv[0][0]; ptr_v = &ctx->edge_buf_uv[1][0]; diff --git a/libavcodec/dnxhdenc.h b/libavcodec/dnxhdenc.h index 9b43f6e9c6580..26c3eec695f31 100644 --- a/libavcodec/dnxhdenc.h +++ b/libavcodec/dnxhdenc.h @@ -75,8 +75,8 @@ typedef struct DNXHDEncContext { int intra_quant_bias; DECLARE_ALIGNED(16, int16_t, blocks)[12][64]; - DECLARE_ALIGNED(16, uint8_t, edge_buf_y)[256]; - DECLARE_ALIGNED(16, uint8_t, edge_buf_uv)[2][256]; + DECLARE_ALIGNED(16, uint8_t, edge_buf_y)[512]; // has to hold 16x16 uint16 when depth=10 + DECLARE_ALIGNED(16, uint8_t, edge_buf_uv)[2][512]; // has to hold 16x16 uint16_t when depth=10 int (*qmatrix_c) [64]; int (*qmatrix_l) [64]; From 16c8a9feeab36239bb7cf5f87fa8cad4dc50ae8c Mon Sep 17 00:00:00 2001 From: Moritz Barsnick Date: Tue, 26 Sep 2017 13:25:53 +0200 Subject: [PATCH 3177/3374] lavf/tls_gnutls: fix compilation with GnuTLS 2.x Commit 598e41684066feba701d19ca7443d24b9e5efa77 added use of GNUTLS_E_PREMATURE_TERMINATION, which wasn't introduced to GnuTLS before 2.99.x / 3.x. This fixes compilation with older versions. Signed-off-by: Moritz Barsnick --- libavformat/tls_gnutls.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavformat/tls_gnutls.c b/libavformat/tls_gnutls.c index 38f8ea4804a9a..7174dfd3fc9ec 100644 --- a/libavformat/tls_gnutls.c +++ b/libavformat/tls_gnutls.c @@ -72,7 +72,9 @@ static int print_tls_error(URLContext *h, int ret) switch (ret) { case GNUTLS_E_AGAIN: case GNUTLS_E_INTERRUPTED: +#ifdef GNUTLS_E_PREMATURE_TERMINATION case GNUTLS_E_PREMATURE_TERMINATION: +#endif break; case GNUTLS_E_WARNING_ALERT_RECEIVED: av_log(h, AV_LOG_WARNING, "%s\n", gnutls_strerror(ret)); From 6bf48c4805cbb9754aa5a7bcb5f46df6bda95447 Mon Sep 17 00:00:00 2001 From: Moritz Barsnick Date: Tue, 26 Sep 2017 13:25:54 +0200 Subject: [PATCH 3178/3374] lavf/tls_gnutls: fix warnings from version check The GnuTLS version is checked through the macro GNUTLS_VERSION_NUMBER, but this wasn't introduced before 2.7.2. Building with older versions of GnuTLS (using icc) warns: src/libavformat/tls_gnutls.c(38): warning #193: zero used for undefined preprocessing identifier "GNUTLS_VERSION_NUMBER" #if HAVE_THREADS && GNUTLS_VERSION_NUMBER <= 0x020b00 This adds a fallback to the older, deprecated LIBGNUTLS_VERSION_NUMBER macro. Signed-off-by: Moritz Barsnick --- libavformat/tls_gnutls.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavformat/tls_gnutls.c b/libavformat/tls_gnutls.c index 7174dfd3fc9ec..5ce6c3d448ce6 100644 --- a/libavformat/tls_gnutls.c +++ b/libavformat/tls_gnutls.c @@ -35,6 +35,10 @@ #include "libavutil/opt.h" #include "libavutil/parseutils.h" +#ifndef GNUTLS_VERSION_NUMBER +#define GNUTLS_VERSION_NUMBER LIBGNUTLS_VERSION_NUMBER +#endif + #if HAVE_THREADS && GNUTLS_VERSION_NUMBER <= 0x020b00 #include #include "libavutil/thread.h" From 52223ffe44614738499ea6c0068810e250fb7b26 Mon Sep 17 00:00:00 2001 From: James Almer Date: Tue, 26 Sep 2017 13:59:56 -0300 Subject: [PATCH 3179/3374] Revert "lavf/dashenc: update bitrates on dash_write_trailer" This reverts commit 89c0fda5f43d8a3d3a1c538ff8d72e6737bc7d8e. A different solution will be committed instead. Signed-off-by: James Almer --- libavformat/dashenc.c | 42 ++++++++++++------------------------------ 1 file changed, 12 insertions(+), 30 deletions(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 6471649eb7410..ca24015115c74 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -443,30 +443,6 @@ static int write_manifest(AVFormatContext *s, int final) return 0; } -static int set_bitrate(AVFormatContext *s) -{ - DASHContext *c = s->priv_data; - int i; - - for (i = 0; i < s->nb_streams; i++) { - OutputStream *os = &c->streams[i]; - - os->bit_rate = s->streams[i]->codecpar->bit_rate; - if (os->bit_rate) { - snprintf(os->bandwidth_str, sizeof(os->bandwidth_str), - " bandwidth=\"%d\"", os->bit_rate); - } else { - int level = s->strict_std_compliance >= FF_COMPLIANCE_STRICT ? - AV_LOG_ERROR : AV_LOG_WARNING; - av_log(s, level, "No bit rate set for stream %d\n", i); - if (s->strict_std_compliance >= FF_COMPLIANCE_STRICT) - return AVERROR(EINVAL); - } - } - - return 0; -} - static int dash_init(AVFormatContext *s) { DASHContext *c = s->priv_data; @@ -503,10 +479,6 @@ static int dash_init(AVFormatContext *s) if (!c->streams) return AVERROR(ENOMEM); - ret = set_bitrate(s); - if (ret < 0) - return ret; - for (i = 0; i < s->nb_streams; i++) { OutputStream *os = &c->streams[i]; AVFormatContext *ctx; @@ -514,6 +486,18 @@ static int dash_init(AVFormatContext *s) AVDictionary *opts = NULL; char filename[1024]; + os->bit_rate = s->streams[i]->codecpar->bit_rate; + if (os->bit_rate) { + snprintf(os->bandwidth_str, sizeof(os->bandwidth_str), + " bandwidth=\"%d\"", os->bit_rate); + } else { + int level = s->strict_std_compliance >= FF_COMPLIANCE_STRICT ? + AV_LOG_ERROR : AV_LOG_WARNING; + av_log(s, level, "No bit rate set for stream %d\n", i); + if (s->strict_std_compliance >= FF_COMPLIANCE_STRICT) + return AVERROR(EINVAL); + } + ctx = avformat_alloc_context(); if (!ctx) return AVERROR(ENOMEM); @@ -878,8 +862,6 @@ static int dash_write_trailer(AVFormatContext *s) { DASHContext *c = s->priv_data; - set_bitrate(s); - if (s->nb_streams > 0) { OutputStream *os = &c->streams[0]; // If no segments have been written so far, try to do a crude From 8f2ab180635255a4cd41c6261187ba070540d605 Mon Sep 17 00:00:00 2001 From: James Almer Date: Tue, 26 Sep 2017 19:09:57 -0300 Subject: [PATCH 3180/3374] Revert "Merge commit '66988320794a107f2a460eaa71dbd9fab8056842'" This reverts commit 740e557d6eac3b579dfed53ed92ae70e2089c77c, reversing changes made to 932e28b13e9ae29262dfd28419b700e03716e85e. The commit apparently broke builds with shared libs, and "suggesting" the use of external libraries that need to be explicitly enable has dubious usefulness anyway. --- configure | 1 - 1 file changed, 1 deletion(-) diff --git a/configure b/configure index b154924d0965f..ba38a7390653e 100755 --- a/configure +++ b/configure @@ -3183,7 +3183,6 @@ deinterlace_vaapi_filter_deps="vaapi" delogo_filter_deps="gpl" deshake_filter_select="pixelutils" drawtext_filter_deps="libfreetype" -drawtext_filter_suggest="libfontconfig" elbg_filter_deps="avcodec" eq_filter_deps="gpl" fftfilt_filter_deps="avcodec" From f102a4efcef33014d414f9bf4492a04feab20c82 Mon Sep 17 00:00:00 2001 From: Tobias Rapp Date: Wed, 27 Sep 2017 14:29:21 +0200 Subject: [PATCH 3181/3374] avfilter/f_metadata: avoid trailing whitespace in filter output Signed-off-by: Tobias Rapp --- libavfilter/f_metadata.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavfilter/f_metadata.c b/libavfilter/f_metadata.c index 23bc254a75882..523a94d38cb20 100644 --- a/libavfilter/f_metadata.c +++ b/libavfilter/f_metadata.c @@ -314,14 +314,14 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) break; case METADATA_PRINT: if (!s->key && e) { - s->print(ctx, "frame:%-4"PRId64" pts:%-7s pts_time:%-7s\n", + s->print(ctx, "frame:%-4"PRId64" pts:%-7s pts_time:%s\n", inlink->frame_count_out, av_ts2str(frame->pts), av_ts2timestr(frame->pts, &inlink->time_base)); s->print(ctx, "%s=%s\n", e->key, e->value); while ((e = av_dict_get(*metadata, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL) { s->print(ctx, "%s=%s\n", e->key, e->value); } } else if (e && e->value && (!s->value || (e->value && s->compare(s, e->value, s->value)))) { - s->print(ctx, "frame:%-4"PRId64" pts:%-7s pts_time:%-7s\n", + s->print(ctx, "frame:%-4"PRId64" pts:%-7s pts_time:%s\n", inlink->frame_count_out, av_ts2str(frame->pts), av_ts2timestr(frame->pts, &inlink->time_base)); s->print(ctx, "%s=%s\n", s->key, e->value); } From bee01ee2ba2e62974447d5e8ea2afb27dbdb1e23 Mon Sep 17 00:00:00 2001 From: Tobias Rapp Date: Tue, 29 Aug 2017 14:45:13 +0200 Subject: [PATCH 3182/3374] fate: add tests for psnr and ssim filter Metadata filter output is passed through an Awk script comparing floats against reference values with specified "fuzz" tolerance to account for architectural differences (e.g. x86-32 vs. x86-64). Signed-off-by: Tobias Rapp --- tests/fate-run.sh | 9 ++++ tests/fate/filter-video.mak | 14 ++++++ tests/ref/fate/filter-refcmp-psnr-rgb | 45 +++++++++++++++++++ tests/ref/fate/filter-refcmp-psnr-yuv | 45 +++++++++++++++++++ tests/ref/fate/filter-refcmp-ssim-rgb | 30 +++++++++++++ tests/ref/fate/filter-refcmp-ssim-yuv | 30 +++++++++++++ tests/refcmp-metadata.awk | 64 +++++++++++++++++++++++++++ 7 files changed, 237 insertions(+) create mode 100644 tests/ref/fate/filter-refcmp-psnr-rgb create mode 100644 tests/ref/fate/filter-refcmp-psnr-yuv create mode 100644 tests/ref/fate/filter-refcmp-ssim-rgb create mode 100644 tests/ref/fate/filter-refcmp-ssim-yuv create mode 100644 tests/refcmp-metadata.awk diff --git a/tests/fate-run.sh b/tests/fate-run.sh index 9aa9a223951b1..c5480c7edee02 100755 --- a/tests/fate-run.sh +++ b/tests/fate-run.sh @@ -234,6 +234,15 @@ lavftest(){ ${base}/lavf-regression.sh $t lavf tests/vsynth1 "$target_exec" "$target_path" "$threads" "$thread_type" "$cpuflags" "$target_samples" } +refcmp_metadata(){ + refcmp=$1 + pixfmt=$2 + fuzz=${3:-0.001} + ffmpeg $FLAGS $ENC_OPTS \ + -lavfi "testsrc2=size=300x200:rate=1:duration=5,format=${pixfmt},split[ref][tmp];[tmp]avgblur=4[enc];[enc][ref]${refcmp},metadata=print:file=-" \ + -f null /dev/null | awk -v ref=${ref} -v fuzz=${fuzz} -f ${base}/refcmp-metadata.awk - +} + video_filter(){ filters=$1 shift diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak index d1e13414f65bc..78cd4711e6242 100644 --- a/tests/fate/filter-video.mak +++ b/tests/fate/filter-video.mak @@ -747,6 +747,20 @@ FATE_FILTER_SAMPLES-$(call ALLYES, MOV_DEMUXER H264_DECODER AAC_FIXED_DECODER PC fate-filter-meta-4560-rotate0: tests/data/file4560-override2rotate0.mov fate-filter-meta-4560-rotate0: CMD = framecrc -flags +bitexact -c:a aac_fixed -i $(TARGET_PATH)/tests/data/file4560-override2rotate0.mov +REFCMP_DEPS = FFMPEG LAVFI_INDEV TESTSRC2_FILTER AVGBLUR_FILTER METADATA_FILTER + +FATE_FILTER_SAMPLES-$(call ALLYES, $(REFCMP_DEPS) PSNR_FILTER) += fate-filter-refcmp-psnr-rgb +fate-filter-refcmp-psnr-rgb: CMD = refcmp_metadata psnr rgb24 + +FATE_FILTER_SAMPLES-$(call ALLYES, $(REFCMP_DEPS) PSNR_FILTER) += fate-filter-refcmp-psnr-yuv +fate-filter-refcmp-psnr-yuv: CMD = refcmp_metadata psnr yuv422p + +FATE_FILTER_SAMPLES-$(call ALLYES, $(REFCMP_DEPS) SSIM_FILTER) += fate-filter-refcmp-ssim-rgb +fate-filter-refcmp-ssim-rgb: CMD = refcmp_metadata ssim rgb24 + +FATE_FILTER_SAMPLES-$(call ALLYES, $(REFCMP_DEPS) SSIM_FILTER) += fate-filter-refcmp-ssim-yuv +fate-filter-refcmp-ssim-yuv: CMD = refcmp_metadata ssim yuv422p + FATE_SAMPLES_FFPROBE += $(FATE_METADATA_FILTER-yes) FATE_SAMPLES_FFMPEG += $(FATE_FILTER_SAMPLES-yes) FATE_FFMPEG += $(FATE_FILTER-yes) diff --git a/tests/ref/fate/filter-refcmp-psnr-rgb b/tests/ref/fate/filter-refcmp-psnr-rgb new file mode 100644 index 0000000000000..f06db575ac425 --- /dev/null +++ b/tests/ref/fate/filter-refcmp-psnr-rgb @@ -0,0 +1,45 @@ +frame:0 pts:0 pts_time:0 +lavfi.psnr.mse.r=1381.80 +lavfi.psnr.psnr.r=16.73 +lavfi.psnr.mse.g=896.00 +lavfi.psnr.psnr.g=18.61 +lavfi.psnr.mse.b=277.38 +lavfi.psnr.psnr.b=23.70 +lavfi.psnr.mse_avg=851.73 +lavfi.psnr.psnr_avg=18.83 +frame:1 pts:1 pts_time:1 +lavfi.psnr.mse.r=1380.37 +lavfi.psnr.psnr.r=16.73 +lavfi.psnr.mse.g=975.91 +lavfi.psnr.psnr.g=18.24 +lavfi.psnr.mse.b=435.72 +lavfi.psnr.psnr.b=21.74 +lavfi.psnr.mse_avg=930.67 +lavfi.psnr.psnr_avg=18.44 +frame:2 pts:2 pts_time:2 +lavfi.psnr.mse.r=1403.20 +lavfi.psnr.psnr.r=16.66 +lavfi.psnr.mse.g=954.05 +lavfi.psnr.psnr.g=18.34 +lavfi.psnr.mse.b=494.22 +lavfi.psnr.psnr.b=21.19 +lavfi.psnr.mse_avg=950.49 +lavfi.psnr.psnr_avg=18.35 +frame:3 pts:3 pts_time:3 +lavfi.psnr.mse.r=1452.80 +lavfi.psnr.psnr.r=16.51 +lavfi.psnr.mse.g=1001.02 +lavfi.psnr.psnr.g=18.13 +lavfi.psnr.mse.b=557.39 +lavfi.psnr.psnr.b=20.67 +lavfi.psnr.mse_avg=1003.74 +lavfi.psnr.psnr_avg=18.11 +frame:4 pts:4 pts_time:4 +lavfi.psnr.mse.r=1401.25 +lavfi.psnr.psnr.r=16.67 +lavfi.psnr.mse.g=1009.80 +lavfi.psnr.psnr.g=18.09 +lavfi.psnr.mse.b=602.42 +lavfi.psnr.psnr.b=20.33 +lavfi.psnr.mse_avg=1004.49 +lavfi.psnr.psnr_avg=18.11 diff --git a/tests/ref/fate/filter-refcmp-psnr-yuv b/tests/ref/fate/filter-refcmp-psnr-yuv new file mode 100644 index 0000000000000..0e634ed0e451f --- /dev/null +++ b/tests/ref/fate/filter-refcmp-psnr-yuv @@ -0,0 +1,45 @@ +frame:0 pts:0 pts_time:0 +lavfi.psnr.mse.y=222.06 +lavfi.psnr.psnr.y=24.67 +lavfi.psnr.mse.u=339.38 +lavfi.psnr.psnr.u=22.82 +lavfi.psnr.mse.v=705.41 +lavfi.psnr.psnr.v=19.65 +lavfi.psnr.mse_avg=372.23 +lavfi.psnr.psnr_avg=22.42 +frame:1 pts:1 pts_time:1 +lavfi.psnr.mse.y=236.74 +lavfi.psnr.psnr.y=24.39 +lavfi.psnr.mse.u=416.17 +lavfi.psnr.psnr.u=21.94 +lavfi.psnr.mse.v=704.98 +lavfi.psnr.psnr.v=19.65 +lavfi.psnr.mse_avg=398.66 +lavfi.psnr.psnr_avg=22.12 +frame:2 pts:2 pts_time:2 +lavfi.psnr.mse.y=234.79 +lavfi.psnr.psnr.y=24.42 +lavfi.psnr.mse.u=435.72 +lavfi.psnr.psnr.u=21.74 +lavfi.psnr.mse.v=699.60 +lavfi.psnr.psnr.v=19.68 +lavfi.psnr.mse_avg=401.23 +lavfi.psnr.psnr_avg=22.10 +frame:3 pts:3 pts_time:3 +lavfi.psnr.mse.y=250.88 +lavfi.psnr.psnr.y=24.14 +lavfi.psnr.mse.u=479.73 +lavfi.psnr.psnr.u=21.32 +lavfi.psnr.mse.v=707.55 +lavfi.psnr.psnr.v=19.63 +lavfi.psnr.mse_avg=422.26 +lavfi.psnr.psnr_avg=21.88 +frame:4 pts:4 pts_time:4 +lavfi.psnr.mse.y=241.05 +lavfi.psnr.psnr.y=24.31 +lavfi.psnr.mse.u=505.04 +lavfi.psnr.psnr.u=21.10 +lavfi.psnr.mse.v=716.00 +lavfi.psnr.psnr.v=19.58 +lavfi.psnr.mse_avg=425.79 +lavfi.psnr.psnr_avg=21.84 diff --git a/tests/ref/fate/filter-refcmp-ssim-rgb b/tests/ref/fate/filter-refcmp-ssim-rgb new file mode 100644 index 0000000000000..8c23c60b371bf --- /dev/null +++ b/tests/ref/fate/filter-refcmp-ssim-rgb @@ -0,0 +1,30 @@ +frame:0 pts:0 pts_time:0 +lavfi.ssim.R=0.72 +lavfi.ssim.G=0.76 +lavfi.ssim.B=0.89 +lavfi.ssim.All=0.79 +lavfi.ssim.dB=6.74 +frame:1 pts:1 pts_time:1 +lavfi.ssim.R=0.70 +lavfi.ssim.G=0.74 +lavfi.ssim.B=0.85 +lavfi.ssim.All=0.77 +lavfi.ssim.dB=6.31 +frame:2 pts:2 pts_time:2 +lavfi.ssim.R=0.71 +lavfi.ssim.G=0.75 +lavfi.ssim.B=0.84 +lavfi.ssim.All=0.76 +lavfi.ssim.dB=6.29 +frame:3 pts:3 pts_time:3 +lavfi.ssim.R=0.70 +lavfi.ssim.G=0.73 +lavfi.ssim.B=0.83 +lavfi.ssim.All=0.76 +lavfi.ssim.dB=6.11 +frame:4 pts:4 pts_time:4 +lavfi.ssim.R=0.71 +lavfi.ssim.G=0.74 +lavfi.ssim.B=0.80 +lavfi.ssim.All=0.75 +lavfi.ssim.dB=6.05 diff --git a/tests/ref/fate/filter-refcmp-ssim-yuv b/tests/ref/fate/filter-refcmp-ssim-yuv new file mode 100644 index 0000000000000..5c8ffb94830cd --- /dev/null +++ b/tests/ref/fate/filter-refcmp-ssim-yuv @@ -0,0 +1,30 @@ +frame:0 pts:0 pts_time:0 +lavfi.ssim.Y=0.80 +lavfi.ssim.U=0.76 +lavfi.ssim.V=0.69 +lavfi.ssim.All=0.76 +lavfi.ssim.dB=6.25 +frame:1 pts:1 pts_time:1 +lavfi.ssim.Y=0.80 +lavfi.ssim.U=0.73 +lavfi.ssim.V=0.68 +lavfi.ssim.All=0.75 +lavfi.ssim.dB=6.08 +frame:2 pts:2 pts_time:2 +lavfi.ssim.Y=0.80 +lavfi.ssim.U=0.73 +lavfi.ssim.V=0.68 +lavfi.ssim.All=0.75 +lavfi.ssim.dB=6.10 +frame:3 pts:3 pts_time:3 +lavfi.ssim.Y=0.79 +lavfi.ssim.U=0.72 +lavfi.ssim.V=0.68 +lavfi.ssim.All=0.75 +lavfi.ssim.dB=5.94 +frame:4 pts:4 pts_time:4 +lavfi.ssim.Y=0.80 +lavfi.ssim.U=0.72 +lavfi.ssim.V=0.68 +lavfi.ssim.All=0.75 +lavfi.ssim.dB=5.97 diff --git a/tests/refcmp-metadata.awk b/tests/refcmp-metadata.awk new file mode 100644 index 0000000000000..fa21aad0e0401 --- /dev/null +++ b/tests/refcmp-metadata.awk @@ -0,0 +1,64 @@ +# Compare metadata filter output containing float value strings to reference +# output data. Returns the whole reference data if delta of each value is below +# threshold, else returns the whole input data. + +function abs(val) { + return ((val < 0.0) ? -val : val); +} + +function max(val1, val2) { + return ((val1 >= val2) ? val1 : val2); +} + +function is_numeric_str(str) { + return (str ~ /^[+-]?[0-9]*\.?[0-9]+$/); +} + +BEGIN { + FS = "="; + # check for "fuzz" (threshold) program parameter, else use default + if (fuzz <= 0.0) { + fuzz = 0.1; + } + # check for "ref" (reference file) program parameter + if (ref) { + ref_nr = 0; + while ((getline line < ref) > 0) { + ref_nr++; + ref_lines[ref_nr] = line; + if (split(line, fields) == 2 && is_numeric_str(fields[2])) { + ref_keys[ref_nr] = fields[1]; + ref_vals[ref_nr] = fields[2] + 0; # convert to number + } + } + close(ref); + } + delta_max = 0; + result = (ref ? 1 : 0); +} + +{ + cmp_lines[NR] = $0; + if (NF == 2 && is_numeric_str($2) && ref_vals[NR]) { + val = $2 + 0; # convert to number + delta = abs((val / ref_vals[NR]) - 1); + delta_max = max(delta_max, delta); + result = result && ($1 == ref_keys[NR]) && (delta <= fuzz); + } else { + result = result && ($0 == ref_lines[NR]); + } +} + +END { + if (result) { + for (i = 1; i <= ref_nr; i++) + print ref_lines[i]; + } else { + for (i = 1; i <= NR; i++) + print cmp_lines[i]; + if (NR != ref_nr) + print "[refcmp] lines: " NR " != " ref_nr > "/dev/stderr"; + if (delta_max >= fuzz) + print "[refcmp] delta_max: " delta_max " >= " fuzz > "/dev/stderr"; + } +} From 56d2154b72fba96a65b806ecf4a6f85c3f69b021 Mon Sep 17 00:00:00 2001 From: Josh de Kock Date: Tue, 26 Sep 2017 15:49:18 +0100 Subject: [PATCH 3183/3374] lavd: remove deprecated dv1394 device Support for this device has been removed in kernel since v2.6.37. dv1394 has been superseded by libiec61883 which is functionally equivalent. Signed-off-by: Josh de Kock Signed-off-by: wm4 --- configure | 3 - doc/indevs.texi | 25 --- libavdevice/Makefile | 1 - libavdevice/alldevices.c | 1 - libavdevice/dv1394.c | 239 -------------------------- libavdevice/dv1394.h | 357 --------------------------------------- 6 files changed, 626 deletions(-) delete mode 100644 libavdevice/dv1394.c delete mode 100644 libavdevice/dv1394.h diff --git a/configure b/configure index 2cd727ea2fcc2..a168feea23965 100755 --- a/configure +++ b/configure @@ -3075,8 +3075,6 @@ libndi_newtek_outdev_deps="libndi_newtek" libndi_newtek_outdev_extralibs="-lndi" dshow_indev_deps="IBaseFilter" dshow_indev_extralibs="-lpsapi -lole32 -lstrmiids -luuid -loleaut32 -lshlwapi" -dv1394_indev_deps="dv1394" -dv1394_indev_select="dv_demuxer" fbdev_indev_deps="linux_fb_h" fbdev_outdev_deps="linux_fb_h" gdigrab_indev_deps="CreateDIBSection" @@ -5062,7 +5060,6 @@ case $target_os in add_cppflags -U__STRICT_ANSI__ ;; linux) - enable dv1394 enable section_data_rel_ro enabled_any arm aarch64 && enable_weak linux_perf ;; diff --git a/doc/indevs.texi b/doc/indevs.texi index 30b7ac23805c6..776e5631602d4 100644 --- a/doc/indevs.texi +++ b/doc/indevs.texi @@ -641,31 +641,6 @@ $ ffmpeg -f dshow -show_video_device_dialog true -crossbar_video_input_pin_numbe @end itemize -@section dv1394 - -Linux DV 1394 input device. - -@subsection Options - -@table @option - -@item framerate -Set the frame rate. Default is 25. - -@item standard - -Available values are: -@table @samp -@item pal - -@item ntsc - -@end table - -Default value is @code{ntsc}. - -@end table - @section fbdev Linux framebuffer input device. diff --git a/libavdevice/Makefile b/libavdevice/Makefile index f40f4d5298a7e..8228d6214793f 100644 --- a/libavdevice/Makefile +++ b/libavdevice/Makefile @@ -24,7 +24,6 @@ OBJS-$(CONFIG_LIBNDI_NEWTEK_INDEV) += libndi_newtek_dec.o OBJS-$(CONFIG_DSHOW_INDEV) += dshow_crossbar.o dshow.o dshow_enummediatypes.o \ dshow_enumpins.o dshow_filter.o \ dshow_pin.o dshow_common.o -OBJS-$(CONFIG_DV1394_INDEV) += dv1394.o OBJS-$(CONFIG_FBDEV_INDEV) += fbdev_dec.o \ fbdev_common.o OBJS-$(CONFIG_FBDEV_OUTDEV) += fbdev_enc.o \ diff --git a/libavdevice/alldevices.c b/libavdevice/alldevices.c index b31558bcb54b5..b767b6a718821 100644 --- a/libavdevice/alldevices.c +++ b/libavdevice/alldevices.c @@ -48,7 +48,6 @@ static void register_all(void) REGISTER_INOUTDEV(DECKLINK, decklink); REGISTER_INOUTDEV(LIBNDI_NEWTEK, libndi_newtek); REGISTER_INDEV (DSHOW, dshow); - REGISTER_INDEV (DV1394, dv1394); REGISTER_INOUTDEV(FBDEV, fbdev); REGISTER_INDEV (GDIGRAB, gdigrab); REGISTER_INDEV (IEC61883, iec61883); diff --git a/libavdevice/dv1394.c b/libavdevice/dv1394.c deleted file mode 100644 index c3483010fa0dc..0000000000000 --- a/libavdevice/dv1394.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Linux DV1394 interface - * Copyright (c) 2003 Max Krasnyansky - * - * 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 "config.h" -#include -#include -#include -#include -#include -#include - -#include "libavutil/internal.h" -#include "libavutil/log.h" -#include "libavutil/opt.h" -#include "avdevice.h" -#include "libavformat/dv.h" -#include "dv1394.h" - -struct dv1394_data { - AVClass *class; - int fd; - int channel; - int format; - - uint8_t *ring; /* Ring buffer */ - int index; /* Current frame index */ - int avail; /* Number of frames available for reading */ - int done; /* Number of completed frames */ - - DVDemuxContext* dv_demux; /* Generic DV muxing/demuxing context */ -}; - -/* - * The trick here is to kludge around well known problem with kernel Ooopsing - * when you try to capture PAL on a device node configure for NTSC. That's - * why we have to configure the device node for PAL, and then read only NTSC - * amount of data. - */ -static int dv1394_reset(struct dv1394_data *dv) -{ - struct dv1394_init init; - - init.channel = dv->channel; - init.api_version = DV1394_API_VERSION; - init.n_frames = DV1394_RING_FRAMES; - init.format = DV1394_PAL; - - if (ioctl(dv->fd, DV1394_INIT, &init) < 0) - return -1; - - dv->avail = dv->done = 0; - return 0; -} - -static int dv1394_start(struct dv1394_data *dv) -{ - /* Tell DV1394 driver to enable receiver */ - if (ioctl(dv->fd, DV1394_START_RECEIVE, 0) < 0) { - av_log(NULL, AV_LOG_ERROR, "Failed to start receiver: %s\n", strerror(errno)); - return -1; - } - return 0; -} - -static int dv1394_read_header(AVFormatContext * context) -{ - struct dv1394_data *dv = context->priv_data; - - dv->dv_demux = avpriv_dv_init_demux(context); - if (!dv->dv_demux) - goto failed; - - /* Open and initialize DV1394 device */ - dv->fd = avpriv_open(context->filename, O_RDONLY); - if (dv->fd < 0) { - av_log(context, AV_LOG_ERROR, "Failed to open DV interface: %s\n", strerror(errno)); - goto failed; - } - - if (dv1394_reset(dv) < 0) { - av_log(context, AV_LOG_ERROR, "Failed to initialize DV interface: %s\n", strerror(errno)); - goto failed; - } - - dv->ring = mmap(NULL, DV1394_PAL_FRAME_SIZE * DV1394_RING_FRAMES, - PROT_READ, MAP_PRIVATE, dv->fd, 0); - if (dv->ring == MAP_FAILED) { - av_log(context, AV_LOG_ERROR, "Failed to mmap DV ring buffer: %s\n", strerror(errno)); - goto failed; - } - - if (dv1394_start(dv) < 0) - goto failed; - - return 0; - -failed: - close(dv->fd); - return AVERROR(EIO); -} - -static int dv1394_read_packet(AVFormatContext *context, AVPacket *pkt) -{ - struct dv1394_data *dv = context->priv_data; - int size; - - size = avpriv_dv_get_packet(dv->dv_demux, pkt); - if (size > 0) - return size; - - if (!dv->avail) { - struct dv1394_status s; - struct pollfd p; - - if (dv->done) { - /* Request more frames */ - if (ioctl(dv->fd, DV1394_RECEIVE_FRAMES, dv->done) < 0) { - /* This usually means that ring buffer overflowed. - * We have to reset :(. - */ - - av_log(context, AV_LOG_ERROR, "DV1394: Ring buffer overflow. Resetting ..\n"); - - dv1394_reset(dv); - dv1394_start(dv); - } - dv->done = 0; - } - - /* Wait until more frames are available */ -restart_poll: - p.fd = dv->fd; - p.events = POLLIN | POLLERR | POLLHUP; - if (poll(&p, 1, -1) < 0) { - if (errno == EAGAIN || errno == EINTR) - goto restart_poll; - av_log(context, AV_LOG_ERROR, "Poll failed: %s\n", strerror(errno)); - return AVERROR(EIO); - } - - if (ioctl(dv->fd, DV1394_GET_STATUS, &s) < 0) { - av_log(context, AV_LOG_ERROR, "Failed to get status: %s\n", strerror(errno)); - return AVERROR(EIO); - } - av_log(context, AV_LOG_TRACE, "DV1394: status\n" - "\tactive_frame\t%d\n" - "\tfirst_clear_frame\t%d\n" - "\tn_clear_frames\t%d\n" - "\tdropped_frames\t%d\n", - s.active_frame, s.first_clear_frame, - s.n_clear_frames, s.dropped_frames); - - dv->avail = s.n_clear_frames; - dv->index = s.first_clear_frame; - dv->done = 0; - - if (s.dropped_frames) { - av_log(context, AV_LOG_ERROR, "DV1394: Frame drop detected (%d). Resetting ..\n", - s.dropped_frames); - - dv1394_reset(dv); - dv1394_start(dv); - } - } - - av_log(context, AV_LOG_TRACE, "index %d, avail %d, done %d\n", dv->index, dv->avail, - dv->done); - - size = avpriv_dv_produce_packet(dv->dv_demux, pkt, - dv->ring + (dv->index * DV1394_PAL_FRAME_SIZE), - DV1394_PAL_FRAME_SIZE, -1); - dv->index = (dv->index + 1) % DV1394_RING_FRAMES; - dv->done++; dv->avail--; - - return size; -} - -static int dv1394_close(AVFormatContext * context) -{ - struct dv1394_data *dv = context->priv_data; - - /* Shutdown DV1394 receiver */ - if (ioctl(dv->fd, DV1394_SHUTDOWN, 0) < 0) - av_log(context, AV_LOG_ERROR, "Failed to shutdown DV1394: %s\n", strerror(errno)); - - /* Unmap ring buffer */ - if (munmap(dv->ring, DV1394_NTSC_FRAME_SIZE * DV1394_RING_FRAMES) < 0) - av_log(context, AV_LOG_ERROR, "Failed to munmap DV1394 ring buffer: %s\n", strerror(errno)); - - close(dv->fd); - av_freep(&dv->dv_demux); - - return 0; -} - -static const AVOption options[] = { - { "standard", "", offsetof(struct dv1394_data, format), AV_OPT_TYPE_INT, {.i64 = DV1394_NTSC}, DV1394_NTSC, DV1394_PAL, AV_OPT_FLAG_DECODING_PARAM, "standard" }, - { "PAL", "", 0, AV_OPT_TYPE_CONST, {.i64 = DV1394_PAL}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" }, - { "NTSC", "", 0, AV_OPT_TYPE_CONST, {.i64 = DV1394_NTSC}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" }, - { "channel", "", offsetof(struct dv1394_data, channel), AV_OPT_TYPE_INT, {.i64 = DV1394_DEFAULT_CHANNEL}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, - { NULL }, -}; - -static const AVClass dv1394_class = { - .class_name = "DV1394 indev", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, - .category = AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT, -}; - -AVInputFormat ff_dv1394_demuxer = { - .name = "dv1394", - .long_name = NULL_IF_CONFIG_SMALL("DV1394 A/V grab"), - .priv_data_size = sizeof(struct dv1394_data), - .read_header = dv1394_read_header, - .read_packet = dv1394_read_packet, - .read_close = dv1394_close, - .flags = AVFMT_NOFILE, - .priv_class = &dv1394_class, -}; diff --git a/libavdevice/dv1394.h b/libavdevice/dv1394.h deleted file mode 100644 index b76d633ef698b..0000000000000 --- a/libavdevice/dv1394.h +++ /dev/null @@ -1,357 +0,0 @@ -/* - * DV input/output over IEEE 1394 on OHCI chips - * Copyright (C)2001 Daniel Maas - * receive, proc_fs by Dan Dennedy - * - * based on: - * video1394.h - driver for OHCI 1394 boards - * Copyright (C)1999,2000 Sebastien Rougeaux - * Peter Schlaile - * - * 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 - */ - -#ifndef AVDEVICE_DV1394_H -#define AVDEVICE_DV1394_H - -#define DV1394_DEFAULT_CHANNEL 63 -#define DV1394_DEFAULT_CARD 0 -#define DV1394_RING_FRAMES 20 - -#define DV1394_WIDTH 720 -#define DV1394_NTSC_HEIGHT 480 -#define DV1394_PAL_HEIGHT 576 - -/* This is the public user-space interface. Try not to break it. */ - -#define DV1394_API_VERSION 0x20011127 - -/* ******************** - ** ** - ** DV1394 API ** - ** ** - ******************** - - There are two methods of operating the DV1394 DV output device. - - 1) - - The simplest is an interface based on write(): simply write - full DV frames of data to the device, and they will be transmitted - as quickly as possible. The FD may be set for non-blocking I/O, - in which case you can use select() or poll() to wait for output - buffer space. - - To set the DV output parameters (e.g. whether you want NTSC or PAL - video), use the DV1394_INIT ioctl, passing in the parameters you - want in a struct dv1394_init. - - Example 1: - To play a raw .DV file: cat foo.DV > /dev/dv1394 - (cat will use write() internally) - - Example 2: - static struct dv1394_init init = { - 0x63, (broadcast channel) - 4, (four-frame ringbuffer) - DV1394_NTSC, (send NTSC video) - 0, 0 (default empty packet rate) - } - - ioctl(fd, DV1394_INIT, &init); - - while(1) { - read( , buf, DV1394_NTSC_FRAME_SIZE ); - write( , buf, DV1394_NTSC_FRAME_SIZE ); - } - - 2) - - For more control over buffering, and to avoid unnecessary copies - of the DV data, you can use the more sophisticated the mmap() interface. - First, call the DV1394_INIT ioctl to specify your parameters, - including the number of frames in the ringbuffer. Then, calling mmap() - on the dv1394 device will give you direct access to the ringbuffer - from which the DV card reads your frame data. - - The ringbuffer is simply one large, contiguous region of memory - containing two or more frames of packed DV data. Each frame of DV data - is 120000 bytes (NTSC) or 144000 bytes (PAL). - - Fill one or more frames in the ringbuffer, then use the DV1394_SUBMIT_FRAMES - ioctl to begin I/O. You can use either the DV1394_WAIT_FRAMES ioctl - or select()/poll() to wait until the frames are transmitted. Next, you'll - need to call the DV1394_GET_STATUS ioctl to determine which ringbuffer - frames are clear (ready to be filled with new DV data). Finally, use - DV1394_SUBMIT_FRAMES again to send the new data to the DV output. - - - Example: here is what a four-frame ringbuffer might look like - during DV transmission: - - - frame 0 frame 1 frame 2 frame 3 - - *--------------------------------------* - | CLEAR | DV data | DV data | CLEAR | - *--------------------------------------* - - - transmission goes in this direction --->>> - - - The DV hardware is currently transmitting the data in frame 1. - Once frame 1 is finished, it will automatically transmit frame 2. - (if frame 2 finishes before frame 3 is submitted, the device - will continue to transmit frame 2, and will increase the dropped_frames - counter each time it repeats the transmission). - - - If you called DV1394_GET_STATUS at this instant, you would - receive the following values: - - n_frames = 4 - active_frame = 1 - first_clear_frame = 3 - n_clear_frames = 2 - - At this point, you should write new DV data into frame 3 and optionally - frame 0. Then call DV1394_SUBMIT_FRAMES to inform the device that - it may transmit the new frames. - - ERROR HANDLING - - An error (buffer underflow/overflow or a break in the DV stream due - to a 1394 bus reset) can be detected by checking the dropped_frames - field of struct dv1394_status (obtained through the - DV1394_GET_STATUS ioctl). - - The best way to recover from such an error is to re-initialize - dv1394, either by using the DV1394_INIT ioctl call, or closing the - file descriptor and opening it again. (note that you must unmap all - ringbuffer mappings when closing the file descriptor, or else - dv1394 will still be considered 'in use'). - - MAIN LOOP - - For maximum efficiency and robustness against bus errors, you are - advised to model the main loop of your application after the - following pseudo-code example: - - (checks of system call return values omitted for brevity; always - check return values in your code!) - - while( frames left ) { - - struct pollfd *pfd = ...; - - pfd->fd = dv1394_fd; - pfd->revents = 0; - pfd->events = POLLOUT | POLLIN; (OUT for transmit, IN for receive) - - (add other sources of I/O here) - - poll(pfd, 1, -1); (or select(); add a timeout if you want) - - if(pfd->revents) { - struct dv1394_status status; - - ioctl(dv1394_fd, DV1394_GET_STATUS, &status); - - if(status.dropped_frames > 0) { - reset_dv1394(); - } else { - int i; - for (i = 0; i < status.n_clear_frames; i++) { - copy_DV_frame(); - } - } - } - } - - where copy_DV_frame() reads or writes on the dv1394 file descriptor - (read/write mode) or copies data to/from the mmap ringbuffer and - then calls ioctl(DV1394_SUBMIT_FRAMES) to notify dv1394 that new - frames are available (mmap mode). - - reset_dv1394() is called in the event of a buffer - underflow/overflow or a halt in the DV stream (e.g. due to a 1394 - bus reset). To guarantee recovery from the error, this function - should close the dv1394 file descriptor (and munmap() all - ringbuffer mappings, if you are using them), then re-open the - dv1394 device (and re-map the ringbuffer). - -*/ - - -/* maximum number of frames in the ringbuffer */ -#define DV1394_MAX_FRAMES 32 - -/* number of *full* isochronous packets per DV frame */ -#define DV1394_NTSC_PACKETS_PER_FRAME 250 -#define DV1394_PAL_PACKETS_PER_FRAME 300 - -/* size of one frame's worth of DV data, in bytes */ -#define DV1394_NTSC_FRAME_SIZE (480 * DV1394_NTSC_PACKETS_PER_FRAME) -#define DV1394_PAL_FRAME_SIZE (480 * DV1394_PAL_PACKETS_PER_FRAME) - - -/* ioctl() commands */ - -enum { - /* I don't like using 0 as a valid ioctl() */ - DV1394_INVALID = 0, - - - /* get the driver ready to transmit video. - pass a struct dv1394_init* as the parameter (see below), - or NULL to get default parameters */ - DV1394_INIT, - - - /* stop transmitting video and free the ringbuffer */ - DV1394_SHUTDOWN, - - - /* submit N new frames to be transmitted, where - the index of the first new frame is first_clear_buffer, - and the index of the last new frame is - (first_clear_buffer + N) % n_frames */ - DV1394_SUBMIT_FRAMES, - - - /* block until N buffers are clear (pass N as the parameter) - Because we re-transmit the last frame on underrun, there - will at most be n_frames - 1 clear frames at any time */ - DV1394_WAIT_FRAMES, - - /* capture new frames that have been received, where - the index of the first new frame is first_clear_buffer, - and the index of the last new frame is - (first_clear_buffer + N) % n_frames */ - DV1394_RECEIVE_FRAMES, - - - DV1394_START_RECEIVE, - - - /* pass a struct dv1394_status* as the parameter (see below) */ - DV1394_GET_STATUS, -}; - - - -enum pal_or_ntsc { - DV1394_NTSC = 0, - DV1394_PAL -}; - - - - -/* this is the argument to DV1394_INIT */ -struct dv1394_init { - /* DV1394_API_VERSION */ - unsigned int api_version; - - /* isochronous transmission channel to use */ - unsigned int channel; - - /* number of frames in the ringbuffer. Must be at least 2 - and at most DV1394_MAX_FRAMES. */ - unsigned int n_frames; - - /* send/receive PAL or NTSC video format */ - enum pal_or_ntsc format; - - /* the following are used only for transmission */ - - /* set these to zero unless you want a - non-default empty packet rate (see below) */ - unsigned long cip_n; - unsigned long cip_d; - - /* set this to zero unless you want a - non-default SYT cycle offset (default = 3 cycles) */ - unsigned int syt_offset; -}; - -/* NOTE: you may only allocate the DV frame ringbuffer once each time - you open the dv1394 device. DV1394_INIT will fail if you call it a - second time with different 'n_frames' or 'format' arguments (which - would imply a different size for the ringbuffer). If you need a - different buffer size, simply close and re-open the device, then - initialize it with your new settings. */ - -/* Q: What are cip_n and cip_d? */ - -/* - A: DV video streams do not utilize 100% of the potential bandwidth offered - by IEEE 1394 (FireWire). To achieve the correct rate of data transmission, - DV devices must periodically insert empty packets into the 1394 data stream. - Typically there is one empty packet per 14-16 data-carrying packets. - - Some DV devices will accept a wide range of empty packet rates, while others - require a precise rate. If the dv1394 driver produces empty packets at - a rate that your device does not accept, you may see ugly patterns on the - DV output, or even no output at all. - - The default empty packet insertion rate seems to work for many people; if - your DV output is stable, you can simply ignore this discussion. However, - we have exposed the empty packet rate as a parameter to support devices that - do not work with the default rate. - - The decision to insert an empty packet is made with a numerator/denominator - algorithm. Empty packets are produced at an average rate of CIP_N / CIP_D. - You can alter the empty packet rate by passing non-zero values for cip_n - and cip_d to the INIT ioctl. - - */ - - - -struct dv1394_status { - /* this embedded init struct returns the current dv1394 - parameters in use */ - struct dv1394_init init; - - /* the ringbuffer frame that is currently being - displayed. (-1 if the device is not transmitting anything) */ - int active_frame; - - /* index of the first buffer (ahead of active_frame) that - is ready to be filled with data */ - unsigned int first_clear_frame; - - /* how many buffers, including first_clear_buffer, are - ready to be filled with data */ - unsigned int n_clear_frames; - - /* how many times the DV stream has underflowed, overflowed, - or otherwise encountered an error, since the previous call - to DV1394_GET_STATUS */ - unsigned int dropped_frames; - - /* N.B. The dropped_frames counter is only a lower bound on the actual - number of dropped frames, with the special case that if dropped_frames - is zero, then it is guaranteed that NO frames have been dropped - since the last call to DV1394_GET_STATUS. - */ -}; - - -#endif /* AVDEVICE_DV1394_H */ From dc522cfa07896239d737e9fa37ee4163bce7f0d0 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Wed, 27 Sep 2017 19:48:26 +0200 Subject: [PATCH 3184/3374] lavf/version: Bump minor after dv1394 removal. --- libavdevice/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavdevice/version.h b/libavdevice/version.h index 358b6ff969bee..da43e55c32e31 100644 --- a/libavdevice/version.h +++ b/libavdevice/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVDEVICE_VERSION_MAJOR 57 -#define LIBAVDEVICE_VERSION_MINOR 8 -#define LIBAVDEVICE_VERSION_MICRO 101 +#define LIBAVDEVICE_VERSION_MINOR 9 +#define LIBAVDEVICE_VERSION_MICRO 100 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ LIBAVDEVICE_VERSION_MINOR, \ From 55cc0bccf357ca13d124472822477c172cd06336 Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 27 Sep 2017 15:01:58 -0300 Subject: [PATCH 3185/3374] Revert "Merge commit 'a97563c889fefd81ad6b3758471434d8c2e2e550'" This reverts commit 1985071e41f4df8fc693a564e25758676bba164a, reversing changes made to a901869c19ed14c7d3647901468bd1297c9f98c0. We autodetect libxcb, so this is not necessary. --- configure | 1 - 1 file changed, 1 deletion(-) diff --git a/configure b/configure index a168feea23965..a4baeb3b2acbe 100755 --- a/configure +++ b/configure @@ -3101,7 +3101,6 @@ v4l2_indev_deps_any="linux_videodev2_h sys_videoio_h" v4l2_outdev_deps_any="linux_videodev2_h sys_videoio_h" vfwcap_indev_deps="vfw32 vfwcap_defines" xcbgrab_indev_deps="libxcb" -xcbgrab_indev_suggest="libxcb_shm libxcb_shape libxcb_xfixes" xv_outdev_deps="X11_extensions_Xvlib_h XvGetPortAttribute" xv_outdev_extralibs="-lXv -lX11 -lXext" From deeaaba1ab1e7476ef8c9e17851eb6bf49d69682 Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Mon, 25 Sep 2017 18:08:35 +0530 Subject: [PATCH 3186/3374] avcodec/mips: preload data in hevc sao edge 45 degree filter msa functions Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/hevc_lpf_sao_msa.c | 197 ++++++++++++++++++++--------- 1 file changed, 135 insertions(+), 62 deletions(-) diff --git a/libavcodec/mips/hevc_lpf_sao_msa.c b/libavcodec/mips/hevc_lpf_sao_msa.c index 39c647ed7918b..c192265e85d8e 100644 --- a/libavcodec/mips/hevc_lpf_sao_msa.c +++ b/libavcodec/mips/hevc_lpf_sao_msa.c @@ -1878,23 +1878,25 @@ static void hevc_sao_edge_filter_45degree_4width_msa(uint8_t *dst, int32_t height) { uint8_t *src_orig; - int32_t h_cnt; uint32_t dst_val0, dst_val1; - v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 }; + v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; v16u8 const1 = (v16u8) __msa_ldi_b(1); - v16i8 zero = { 0 }; + v16i8 offset, sao_offset = LD_SB(sao_offset_val); v16u8 cmp_minus10, diff_minus10, src_minus10, cmp_minus11, diff_minus11; v16u8 src_minus11, src10, src11; v16i8 src_plus0, src_zero0, src_plus1, src_zero1, dst0; - v8i16 sao_offset, src00, src01, offset_mask0, offset_mask1; + v8i16 offset_mask0, offset_mask1; - sao_offset = LD_SH(sao_offset_val); + sao_offset = __msa_pckev_b(sao_offset, sao_offset); src_orig = src - 1; + + /* load in advance */ LD_UB2(src_orig - src_stride, src_stride, src_minus10, src_minus11); + LD_UB2(src_orig + src_stride, src_stride, src10, src11); - for (h_cnt = (height >> 1); h_cnt--;) { - LD_UB2(src_orig + src_stride, src_stride, src10, src11); + for (height -= 2; height; height -= 2) { + src_orig += (src_stride << 1); SLDI_B2_0_SB(src_minus11, src10, src_zero0, src_zero1, 1); SLDI_B2_0_SB(src10, src11, src_plus0, src_plus1, 2); @@ -1917,20 +1919,22 @@ static void hevc_sao_edge_filter_45degree_4width_msa(uint8_t *dst, offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); - VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0, - offset_mask0, offset_mask0, offset_mask0); - VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1, - offset_mask1, offset_mask1, offset_mask1); - ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01); - ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0, - offset_mask1); - CLIP_SH2_0_255(offset_mask0, offset_mask1); + offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); + dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); - dst0 = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); + VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, + offset, offset, offset); + + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); + dst0 = __msa_adds_s_b(dst0, offset); + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); src_minus10 = src10; src_minus11 = src11; + /* load in advance */ + LD_UB2(src_orig + src_stride, src_stride, src10, src11); + dst_val0 = __msa_copy_u_w((v4i32) dst0, 0); dst_val1 = __msa_copy_u_w((v4i32) dst0, 2); SW(dst_val0, dst); @@ -1938,8 +1942,44 @@ static void hevc_sao_edge_filter_45degree_4width_msa(uint8_t *dst, SW(dst_val1, dst); dst += dst_stride; - src_orig += (src_stride << 1); } + + SLDI_B2_0_SB(src_minus11, src10, src_zero0, src_zero1, 1); + SLDI_B2_0_SB(src10, src11, src_plus0, src_plus1, 2); + + ILVR_B2_UB(src_plus0, src_minus10, src_plus1, src_minus11, src_minus10, + src_minus11); + ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1, src_zero0, + src_zero1); + + cmp_minus10 = ((v16u8) src_zero0 == src_minus10); + diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); + cmp_minus10 = (src_minus10 < (v16u8) src_zero0); + diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); + + cmp_minus11 = ((v16u8) src_zero1 == src_minus11); + diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); + cmp_minus11 = (src_minus11 < (v16u8) src_zero1); + diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); + + offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); + offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); + + offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); + dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); + + VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, + offset, offset); + + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); + dst0 = __msa_adds_s_b(dst0, offset); + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); + + dst_val0 = __msa_copy_u_w((v4i32) dst0, 0); + dst_val1 = __msa_copy_u_w((v4i32) dst0, 2); + SW(dst_val0, dst); + dst += dst_stride; + SW(dst_val1, dst); } static void hevc_sao_edge_filter_45degree_8width_msa(uint8_t *dst, @@ -1950,23 +1990,24 @@ static void hevc_sao_edge_filter_45degree_8width_msa(uint8_t *dst, int32_t height) { uint8_t *src_orig; - int32_t h_cnt; uint64_t dst_val0, dst_val1; - v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 }; + v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; v16u8 const1 = (v16u8) __msa_ldi_b(1); - v16i8 zero = { 0 }; + v16i8 offset, sao_offset = LD_SB(sao_offset_val); v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11; v16u8 src_minus10, src10, src_minus11, src11; - v16i8 src_zero0, src_plus10, src_zero1, src_plus11, dst0, dst1; - v8i16 sao_offset, src00, offset_mask0, src01, offset_mask1; + v16i8 src_zero0, src_plus10, src_zero1, src_plus11, dst0; + v8i16 offset_mask0, offset_mask1; - sao_offset = LD_SH(sao_offset_val); + sao_offset = __msa_pckev_b(sao_offset, sao_offset); src_orig = src - 1; + /* load in advance */ LD_UB2(src_orig - src_stride, src_stride, src_minus10, src_minus11); + LD_UB2(src_orig + src_stride, src_stride, src10, src11); - for (h_cnt = (height >> 1); h_cnt--;) { - LD_UB2(src_orig + src_stride, src_stride, src10, src11); + for (height -= 2; height; height -= 2) { + src_orig += (src_stride << 1); SLDI_B2_0_SB(src_minus11, src10, src_zero0, src_zero1, 1); SLDI_B2_0_SB(src10, src11, src_plus10, src_plus11, 2); @@ -1989,29 +2030,71 @@ static void hevc_sao_edge_filter_45degree_8width_msa(uint8_t *dst, offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); - VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0, - offset_mask0, offset_mask0, offset_mask0); - VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1, - offset_mask1, offset_mask1, offset_mask1); - ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01); - ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0, - offset_mask1); - CLIP_SH2_0_255(offset_mask0, offset_mask1); - PCKEV_B2_SB(offset_mask0, offset_mask0, offset_mask1, offset_mask1, - dst0, dst1); + offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); + dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); + + VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, + offset, offset); + + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); + dst0 = __msa_adds_s_b(dst0, offset); + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); src_minus10 = src10; src_minus11 = src11; + /* load in advance */ + LD_UB2(src_orig + src_stride, src_stride, src10, src11); + dst_val0 = __msa_copy_u_d((v2i64) dst0, 0); - dst_val1 = __msa_copy_u_d((v2i64) dst1, 0); + dst_val1 = __msa_copy_u_d((v2i64) dst0, 1); SD(dst_val0, dst); dst += dst_stride; SD(dst_val1, dst); - dst += dst_stride; - src_orig += (src_stride << 1); } + + SLDI_B2_0_SB(src_minus11, src10, src_zero0, src_zero1, 1); + SLDI_B2_0_SB(src10, src11, src_plus10, src_plus11, 2); + ILVR_B2_UB(src_plus10, src_minus10, src_plus11, src_minus11, src_minus10, + src_minus11); + ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1, src_zero0, + src_zero1); + + cmp_minus10 = ((v16u8) src_zero0 == src_minus10); + diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); + cmp_minus10 = (src_minus10 < (v16u8) src_zero0); + diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); + + cmp_minus11 = ((v16u8) src_zero1 == src_minus11); + diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); + cmp_minus11 = (src_minus11 < (v16u8) src_zero1); + diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); + + offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); + offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); + + offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); + dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); + + VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, + offset, offset); + + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); + dst0 = __msa_adds_s_b(dst0, offset); + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); + + src_minus10 = src10; + src_minus11 = src11; + + /* load in advance */ + LD_UB2(src_orig + src_stride, src_stride, src10, src11); + + dst_val0 = __msa_copy_u_d((v2i64) dst0, 0); + dst_val1 = __msa_copy_u_d((v2i64) dst0, 1); + SD(dst_val0, dst); + dst += dst_stride; + SD(dst_val1, dst); } static void hevc_sao_edge_filter_45degree_16multiple_msa(uint8_t *dst, @@ -2025,7 +2108,7 @@ static void hevc_sao_edge_filter_45degree_16multiple_msa(uint8_t *dst, { uint8_t *src_orig = src; uint8_t *dst_orig = dst; - int32_t h_cnt, v_cnt; + int32_t v_cnt; v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; v16u8 const1 = (v16u8) __msa_ldi_b(1); v16u8 cmp_minus10, cmp_plus10, diff_minus10, diff_plus10, cmp_minus11; @@ -2037,22 +2120,20 @@ static void hevc_sao_edge_filter_45degree_16multiple_msa(uint8_t *dst, v16u8 src12, src_minus12, dst2, src13, src_minus13, dst3; v16i8 src_zero0, src_plus10, src_zero1, src_plus11, src_zero2, src_plus12; v16i8 src_zero3, sao_offset; - v8i16 src0, src1, src2, src3, src4, src5, src6, src7; - v8i16 temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7; sao_offset = LD_SB(sao_offset_val); sao_offset = __msa_pckev_b(sao_offset, sao_offset); - for (h_cnt = (height >> 2); h_cnt--;) { + for (; height; height -= 4) { src_orig = src - 1; dst_orig = dst; - LD_UB4(src_orig, src_stride, - src_minus11, src_minus12, src_minus13, src_minus14); + LD_UB4(src_orig, src_stride, src_minus11, src_minus12, src_minus13, + src_minus14); - for (v_cnt = 0; v_cnt < (width >> 4); v_cnt++) { + for (v_cnt = 0; v_cnt < width; v_cnt += 16) { src_minus10 = LD_UB(src_orig - src_stride); LD_UB4(src_orig + 16, src_stride, src10, src11, src12, src13); - src_plus13 = LD_UB(src + 1 + (v_cnt << 4) + (src_stride << 2)); + src_plus13 = LD_UB(src + 1 + v_cnt + (src_stride << 2)); src_orig += 16; SLDI_B2_SB(src10, src11, src_minus11, src_minus12, src_zero0, @@ -2114,22 +2195,14 @@ static void hevc_sao_edge_filter_45degree_16multiple_msa(uint8_t *dst, VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask3, offset_mask3, offset_mask3, offset_mask3); - UNPCK_UB_SH(src_zero0, src0, src1); - UNPCK_SB_SH(offset_mask0, temp0, temp1); - UNPCK_UB_SH(src_zero1, src2, src3); - UNPCK_SB_SH(offset_mask1, temp2, temp3); - UNPCK_UB_SH(src_zero2, src4, src5); - UNPCK_SB_SH(offset_mask2, temp4, temp5); - UNPCK_UB_SH(src_zero3, src6, src7); - UNPCK_SB_SH(offset_mask3, temp6, temp7); - ADD4(temp0, src0, temp1, src1, temp2, src2, temp3, src3, temp0, - temp1, temp2, temp3); - ADD4(temp4, src4, temp5, src5, temp6, src6, temp7, src7, temp4, - temp5, temp6, temp7); - CLIP_SH4_0_255(temp0, temp1, temp2, temp3); - CLIP_SH4_0_255(temp4, temp5, temp6, temp7); - PCKEV_B4_UB(temp1, temp0, temp3, temp2, temp5, temp4, - temp7, temp6, dst0, dst1, dst2, dst3); + XORI_B4_128_SB(src_zero0, src_zero1, src_zero2, src_zero3); + + dst0 = (v16u8) __msa_adds_s_b((v16i8) src_zero0, offset_mask0); + dst1 = (v16u8) __msa_adds_s_b((v16i8) src_zero1, offset_mask1); + dst2 = (v16u8) __msa_adds_s_b((v16i8) src_zero2, offset_mask2); + dst3 = (v16u8) __msa_adds_s_b((v16i8) src_zero3, offset_mask3); + + XORI_B4_128_UB(dst0, dst1, dst2, dst3); src_minus11 = src10; src_minus12 = src11; From ed1586b921d72ac4231a3e92e41411563123845b Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Tue, 26 Sep 2017 10:40:14 +0530 Subject: [PATCH 3187/3374] avcodec/mips: Removed generic function call in avc intra msa functions Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/h264pred_msa.c | 215 ++++++++++++++------------------- 1 file changed, 92 insertions(+), 123 deletions(-) diff --git a/libavcodec/mips/h264pred_msa.c b/libavcodec/mips/h264pred_msa.c index c297aec879dd5..b9990c13f0bc4 100644 --- a/libavcodec/mips/h264pred_msa.c +++ b/libavcodec/mips/h264pred_msa.c @@ -106,115 +106,6 @@ static void intra_predict_horiz_16x16_msa(uint8_t *src, int32_t src_stride, dst, dst_stride); } -static void intra_predict_dc_8x8_msa(uint8_t *src_top, uint8_t *src_left, - int32_t src_stride_left, - uint8_t *dst, int32_t dst_stride, - uint8_t is_above, uint8_t is_left) -{ - uint32_t row; - uint32_t out, addition = 0; - v16u8 src_above, store; - v8u16 sum_above; - v4u32 sum_top; - v2u64 sum; - - if (is_left && is_above) { - src_above = LD_UB(src_top); - - sum_above = __msa_hadd_u_h(src_above, src_above); - sum_top = __msa_hadd_u_w(sum_above, sum_above); - sum = __msa_hadd_u_d(sum_top, sum_top); - addition = __msa_copy_u_w((v4i32) sum, 0); - - for (row = 0; row < 8; row++) { - addition += src_left[row * src_stride_left]; - } - - addition = (addition + 8) >> 4; - store = (v16u8) __msa_fill_b(addition); - } else if (is_left) { - for (row = 0; row < 8; row++) { - addition += src_left[row * src_stride_left]; - } - - addition = (addition + 4) >> 3; - store = (v16u8) __msa_fill_b(addition); - } else if (is_above) { - src_above = LD_UB(src_top); - - sum_above = __msa_hadd_u_h(src_above, src_above); - sum_top = __msa_hadd_u_w(sum_above, sum_above); - sum = __msa_hadd_u_d(sum_top, sum_top); - sum = (v2u64) __msa_srari_d((v2i64) sum, 3); - store = (v16u8) __msa_splati_b((v16i8) sum, 0); - } else { - store = (v16u8) __msa_ldi_b(128); - } - - out = __msa_copy_u_w((v4i32) store, 0); - - for (row = 8; row--;) { - SW(out, dst); - SW(out, (dst + 4)); - dst += dst_stride; - } -} - -static void intra_predict_dc_16x16_msa(uint8_t *src_top, uint8_t *src_left, - int32_t src_stride_left, - uint8_t *dst, int32_t dst_stride, - uint8_t is_above, uint8_t is_left) -{ - uint32_t row; - uint32_t addition = 0; - v16u8 src_above, store; - v8u16 sum_above; - v4u32 sum_top; - v2u64 sum; - - if (is_left && is_above) { - src_above = LD_UB(src_top); - - sum_above = __msa_hadd_u_h(src_above, src_above); - sum_top = __msa_hadd_u_w(sum_above, sum_above); - sum = __msa_hadd_u_d(sum_top, sum_top); - sum_top = (v4u32) __msa_pckev_w((v4i32) sum, (v4i32) sum); - sum = __msa_hadd_u_d(sum_top, sum_top); - addition = __msa_copy_u_w((v4i32) sum, 0); - - for (row = 0; row < 16; row++) { - addition += src_left[row * src_stride_left]; - } - - addition = (addition + 16) >> 5; - store = (v16u8) __msa_fill_b(addition); - } else if (is_left) { - for (row = 0; row < 16; row++) { - addition += src_left[row * src_stride_left]; - } - - addition = (addition + 8) >> 4; - store = (v16u8) __msa_fill_b(addition); - } else if (is_above) { - src_above = LD_UB(src_top); - - sum_above = __msa_hadd_u_h(src_above, src_above); - sum_top = __msa_hadd_u_w(sum_above, sum_above); - sum = __msa_hadd_u_d(sum_top, sum_top); - sum_top = (v4u32) __msa_pckev_w((v4i32) sum, (v4i32) sum); - sum = __msa_hadd_u_d(sum_top, sum_top); - sum = (v2u64) __msa_srari_d((v2i64) sum, 4); - store = (v16u8) __msa_splati_b((v16i8) sum, 0); - } else { - store = (v16u8) __msa_ldi_b(128); - } - - for (row = 16; row--;) { - ST_UB(store, dst); - dst += dst_stride; - } -} - #define INTRA_PREDICT_VALDC_8X8_MSA(val) \ static void intra_predict_##val##dc_8x8_msa(uint8_t *dst, int32_t dst_stride) \ { \ @@ -646,8 +537,42 @@ void ff_h264_intra_pred_dc_16x16_msa(uint8_t *src, ptrdiff_t stride) uint8_t *src_top = src - stride; uint8_t *src_left = src - 1; uint8_t *dst = src; + uint32_t addition = 0; + v16u8 src_above, out; + v8u16 sum_above; + v4u32 sum_top; + v2u64 sum; - intra_predict_dc_16x16_msa(src_top, src_left, stride, dst, stride, 1, 1); + src_above = LD_UB(src_top); + + sum_above = __msa_hadd_u_h(src_above, src_above); + sum_top = __msa_hadd_u_w(sum_above, sum_above); + sum = __msa_hadd_u_d(sum_top, sum_top); + sum_top = (v4u32) __msa_pckev_w((v4i32) sum, (v4i32) sum); + sum = __msa_hadd_u_d(sum_top, sum_top); + addition = __msa_copy_u_w((v4i32) sum, 0); + addition += src_left[ 0 * stride]; + addition += src_left[ 1 * stride]; + addition += src_left[ 2 * stride]; + addition += src_left[ 3 * stride]; + addition += src_left[ 4 * stride]; + addition += src_left[ 5 * stride]; + addition += src_left[ 6 * stride]; + addition += src_left[ 7 * stride]; + addition += src_left[ 8 * stride]; + addition += src_left[ 9 * stride]; + addition += src_left[10 * stride]; + addition += src_left[11 * stride]; + addition += src_left[12 * stride]; + addition += src_left[13 * stride]; + addition += src_left[14 * stride]; + addition += src_left[15 * stride]; + addition = (addition + 16) >> 5; + out = (v16u8) __msa_fill_b(addition); + + ST_UB8(out, out, out, out, out, out, out, out, dst, stride); + dst += (8 * stride); + ST_UB8(out, out, out, out, out, out, out, out, dst, stride); } void ff_h264_intra_pred_vert_16x16_msa(uint8_t *src, ptrdiff_t stride) @@ -666,38 +591,82 @@ void ff_h264_intra_pred_horiz_16x16_msa(uint8_t *src, ptrdiff_t stride) void ff_h264_intra_pred_dc_left_16x16_msa(uint8_t *src, ptrdiff_t stride) { - uint8_t *src_top = src - stride; uint8_t *src_left = src - 1; uint8_t *dst = src; - - intra_predict_dc_16x16_msa(src_top, src_left, stride, dst, stride, 0, 1); + uint32_t addition; + v16u8 out; + + addition = src_left[ 0 * stride]; + addition += src_left[ 1 * stride]; + addition += src_left[ 2 * stride]; + addition += src_left[ 3 * stride]; + addition += src_left[ 4 * stride]; + addition += src_left[ 5 * stride]; + addition += src_left[ 6 * stride]; + addition += src_left[ 7 * stride]; + addition += src_left[ 8 * stride]; + addition += src_left[ 9 * stride]; + addition += src_left[10 * stride]; + addition += src_left[11 * stride]; + addition += src_left[12 * stride]; + addition += src_left[13 * stride]; + addition += src_left[14 * stride]; + addition += src_left[15 * stride]; + + addition = (addition + 8) >> 4; + out = (v16u8) __msa_fill_b(addition); + + ST_UB8(out, out, out, out, out, out, out, out, dst, stride); + dst += (8 * stride); + ST_UB8(out, out, out, out, out, out, out, out, dst, stride); } void ff_h264_intra_pred_dc_top_16x16_msa(uint8_t *src, ptrdiff_t stride) { uint8_t *src_top = src - stride; - uint8_t *src_left = src - 1; uint8_t *dst = src; + v16u8 src_above, out; + v8u16 sum_above; + v4u32 sum_top; + v2u64 sum; + + src_above = LD_UB(src_top); - intra_predict_dc_16x16_msa(src_top, src_left, stride, dst, stride, 1, 0); + sum_above = __msa_hadd_u_h(src_above, src_above); + sum_top = __msa_hadd_u_w(sum_above, sum_above); + sum = __msa_hadd_u_d(sum_top, sum_top); + sum_top = (v4u32) __msa_pckev_w((v4i32) sum, (v4i32) sum); + sum = __msa_hadd_u_d(sum_top, sum_top); + sum = (v2u64) __msa_srari_d((v2i64) sum, 4); + out = (v16u8) __msa_splati_b((v16i8) sum, 0); + + ST_UB8(out, out, out, out, out, out, out, out, dst, stride); + dst += (8 * stride); + ST_UB8(out, out, out, out, out, out, out, out, dst, stride); } void ff_h264_intra_pred_dc_128_8x8_msa(uint8_t *src, ptrdiff_t stride) { - uint8_t *src_top = src - stride; - uint8_t *src_left = src - 1; - uint8_t *dst = src; + uint64_t out; + v16u8 store; + + store = (v16u8) __msa_fill_b(128); + out = __msa_copy_u_d((v2i64) store, 0); - intra_predict_dc_8x8_msa(src_top, src_left, stride, dst, stride, 0, 0); + SD4(out, out, out, out, src, stride); + src += (4 * stride); + SD4(out, out, out, out, src, stride); } void ff_h264_intra_pred_dc_128_16x16_msa(uint8_t *src, ptrdiff_t stride) { - uint8_t *src_top = src - stride; - uint8_t *src_left = src - 1; - uint8_t *dst = src; + v16u8 out; + + out = (v16u8) __msa_fill_b(128); - intra_predict_dc_16x16_msa(src_top, src_left, stride, dst, stride, 0, 0); + ST_UB8(out, out, out, out, out, out, out, out, src, stride); + src += (8 * stride); + ST_UB8(out, out, out, out, out, out, out, out, src, stride); } void ff_vp8_pred8x8_127_dc_8_msa(uint8_t *src, ptrdiff_t stride) From 10ab5534e0438cb3bcbf43852010c67b0063f204 Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Tue, 26 Sep 2017 10:51:12 +0530 Subject: [PATCH 3188/3374] avcodec/mips: Improve avc weighted mc msa functions Replace generic with block size specific function. Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/h264dsp_msa.c | 423 ++++++++++++++++++---------- libavutil/mips/generic_macros_msa.h | 36 +++ 2 files changed, 306 insertions(+), 153 deletions(-) diff --git a/libavcodec/mips/h264dsp_msa.c b/libavcodec/mips/h264dsp_msa.c index 422703d03d46c..5b06bd934b38a 100644 --- a/libavcodec/mips/h264dsp_msa.c +++ b/libavcodec/mips/h264dsp_msa.c @@ -25,187 +25,201 @@ static void avc_wgt_4x2_msa(uint8_t *data, int32_t stride, int32_t log2_denom, int32_t src_weight, int32_t offset_in) { - uint32_t data0, data1; + uint32_t tp0, tp1, offset_val; v16u8 zero = { 0 }; - v16u8 src0, src1; - v4i32 res0, res1; - v8i16 temp0, temp1, vec0, vec1, wgt, denom, offset; - v8u16 out0, out1; + v16u8 src0 = { 0 }; + v8i16 src0_r, tmp0, wgt, denom, offset; - offset_in <<= (log2_denom); - - if (log2_denom) { - offset_in += (1 << (log2_denom - 1)); - } + offset_val = (unsigned) offset_in << log2_denom; wgt = __msa_fill_h(src_weight); - offset = __msa_fill_h(offset_in); + offset = __msa_fill_h(offset_val); denom = __msa_fill_h(log2_denom); - data0 = LW(data); - data1 = LW(data + stride); - - src0 = (v16u8) __msa_fill_w(data0); - src1 = (v16u8) __msa_fill_w(data1); + LW2(data, stride, tp0, tp1); + INSERT_W2_UB(tp0, tp1, src0); + src0_r = (v8i16) __msa_ilvr_b((v16i8) zero, (v16i8) src0); + tmp0 = wgt * src0_r; + tmp0 = __msa_adds_s_h(tmp0, offset); + tmp0 = __msa_maxi_s_h(tmp0, 0); + tmp0 = __msa_srlr_h(tmp0, denom); + tmp0 = (v8i16) __msa_sat_u_h((v8u16) tmp0, 7); + src0 = (v16u8) __msa_pckev_b((v16i8) tmp0, (v16i8) tmp0); + ST4x2_UB(src0, data, stride); +} - ILVR_B2_SH(zero, src0, zero, src1, vec0, vec1); - MUL2(wgt, vec0, wgt, vec1, temp0, temp1); - ADDS_SH2_SH(temp0, offset, temp1, offset, temp0, temp1); - MAXI_SH2_SH(temp0, temp1, 0); +static void avc_wgt_4x4_msa(uint8_t *data, int32_t stride, int32_t log2_denom, + int32_t src_weight, int32_t offset_in) +{ + uint32_t tp0, tp1, tp2, tp3, offset_val; + v16u8 src0 = { 0 }; + v8i16 src0_r, src1_r, tmp0, tmp1, wgt, denom, offset; - out0 = (v8u16) __msa_srl_h(temp0, denom); - out1 = (v8u16) __msa_srl_h(temp1, denom); + offset_val = (unsigned) offset_in << log2_denom; - SAT_UH2_UH(out0, out1, 7); - PCKEV_B2_SW(out0, out0, out1, out1, res0, res1); + wgt = __msa_fill_h(src_weight); + offset = __msa_fill_h(offset_val); + denom = __msa_fill_h(log2_denom); - data0 = __msa_copy_u_w(res0, 0); - data1 = __msa_copy_u_w(res1, 0); - SW(data0, data); - data += stride; - SW(data1, data); + LW4(data, stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, src0); + UNPCK_UB_SH(src0, src0_r, src1_r); + MUL2(wgt, src0_r, wgt, src1_r, tmp0, tmp1); + ADDS_SH2_SH(tmp0, offset, tmp1, offset, tmp0, tmp1); + MAXI_SH2_SH(tmp0, tmp1, 0); + tmp0 = __msa_srlr_h(tmp0, denom); + tmp1 = __msa_srlr_h(tmp1, denom); + SAT_UH2_SH(tmp0, tmp1, 7); + src0 = (v16u8) __msa_pckev_b((v16i8) tmp1, (v16i8) tmp0); + ST4x4_UB(src0, src0, 0, 1, 2, 3, data, stride); } -static void avc_wgt_4x4multiple_msa(uint8_t *data, int32_t stride, - int32_t height, int32_t log2_denom, - int32_t src_weight, int32_t offset_in) +static void avc_wgt_4x8_msa(uint8_t *data, int32_t stride, int32_t log2_denom, + int32_t src_weight, int32_t offset_in) { - uint8_t cnt; - uint32_t data0, data1, data2, data3; - v16u8 zero = { 0 }; - v16u8 src0, src1, src2, src3; - v8u16 temp0, temp1, temp2, temp3, wgt; - v8i16 denom, offset; + uint32_t tp0, tp1, tp2, tp3, offset_val; + v16u8 src0 = { 0 }, src1 = { 0 }; + v8i16 src0_r, src1_r, src2_r, src3_r, tmp0, tmp1, tmp2, tmp3; + v8i16 wgt, denom, offset; - offset_in <<= (log2_denom); + offset_val = (unsigned) offset_in << log2_denom; - if (log2_denom) { - offset_in += (1 << (log2_denom - 1)); - } - - wgt = (v8u16) __msa_fill_h(src_weight); - offset = __msa_fill_h(offset_in); + wgt = __msa_fill_h(src_weight); + offset = __msa_fill_h(offset_val); denom = __msa_fill_h(log2_denom); - for (cnt = height / 4; cnt--;) { - LW4(data, stride, data0, data1, data2, data3); - - src0 = (v16u8) __msa_fill_w(data0); - src1 = (v16u8) __msa_fill_w(data1); - src2 = (v16u8) __msa_fill_w(data2); - src3 = (v16u8) __msa_fill_w(data3); - - ILVR_B4_UH(zero, src0, zero, src1, zero, src2, zero, src3, - temp0, temp1, temp2, temp3); - MUL4(wgt, temp0, wgt, temp1, wgt, temp2, wgt, temp3, - temp0, temp1, temp2, temp3); - ADDS_SH4_UH(temp0, offset, temp1, offset, temp2, offset, temp3, offset, - temp0, temp1, temp2, temp3); - MAXI_SH4_UH(temp0, temp1, temp2, temp3, 0); - SRL_H4_UH(temp0, temp1, temp2, temp3, denom); - SAT_UH4_UH(temp0, temp1, temp2, temp3, 7); - PCKEV_ST4x4_UB(temp0, temp1, temp2, temp3, data, stride); - data += (4 * stride); - } + LW4(data, stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, src0); + LW4(data + 4 * stride, stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, src1); + UNPCK_UB_SH(src0, src0_r, src1_r); + UNPCK_UB_SH(src1, src2_r, src3_r); + MUL4(wgt, src0_r, wgt, src1_r, wgt, src2_r, wgt, src3_r, tmp0, tmp1, tmp2, + tmp3); + ADDS_SH4_SH(tmp0, offset, tmp1, offset, tmp2, offset, tmp3, offset, tmp0, + tmp1, tmp2, tmp3); + MAXI_SH4_SH(tmp0, tmp1, tmp2, tmp3, 0); + SRLR_H4_SH(tmp0, tmp1, tmp2, tmp3, denom); + SAT_UH4_SH(tmp0, tmp1, tmp2, tmp3, 7); + PCKEV_B2_UB(tmp1, tmp0, tmp3, tmp2, src0, src1); + ST4x8_UB(src0, src1, data, stride); } -static void avc_wgt_4width_msa(uint8_t *data, int32_t stride, - int32_t height, int32_t log2_denom, - int32_t src_weight, int32_t offset_in) +static void avc_wgt_8x4_msa(uint8_t *data, int32_t stride, int32_t log2_denom, + int32_t src_weight, int32_t offset_in) { - if (2 == height) { - avc_wgt_4x2_msa(data, stride, log2_denom, src_weight, offset_in); - } else { - avc_wgt_4x4multiple_msa(data, stride, height, log2_denom, src_weight, - offset_in); - } + uint32_t offset_val; + uint64_t tp0, tp1, tp2, tp3; + v16u8 src0 = { 0 }, src1 = { 0 }; + v8i16 src0_r, src1_r, src2_r, src3_r, tmp0, tmp1, tmp2, tmp3; + v8i16 wgt, denom, offset; + + offset_val = (unsigned) offset_in << log2_denom; + + wgt = __msa_fill_h(src_weight); + offset = __msa_fill_h(offset_val); + denom = __msa_fill_h(log2_denom); + + LD4(data, stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, src0); + INSERT_D2_UB(tp2, tp3, src1); + UNPCK_UB_SH(src0, src0_r, src1_r); + UNPCK_UB_SH(src1, src2_r, src3_r); + MUL4(wgt, src0_r, wgt, src1_r, wgt, src2_r, wgt, src3_r, tmp0, tmp1, tmp2, + tmp3); + ADDS_SH4_SH(tmp0, offset, tmp1, offset, tmp2, offset, tmp3, offset, tmp0, + tmp1, tmp2, tmp3); + MAXI_SH4_SH(tmp0, tmp1, tmp2, tmp3, 0); + SRLR_H4_SH(tmp0, tmp1, tmp2, tmp3, denom); + SAT_UH4_SH(tmp0, tmp1, tmp2, tmp3, 7); + PCKEV_B2_UB(tmp1, tmp0, tmp3, tmp2, src0, src1); + ST8x4_UB(src0, src1, data, stride); } -static void avc_wgt_8width_msa(uint8_t *data, int32_t stride, - int32_t height, int32_t log2_denom, - int32_t src_weight, int32_t offset_in) +static void avc_wgt_8x8_msa(uint8_t *data, int32_t stride, int32_t log2_denom, + int32_t src_weight, int32_t offset_in) { - uint8_t cnt; - v16u8 zero = { 0 }; - v16u8 src0, src1, src2, src3; - v8u16 src0_r, src1_r, src2_r, src3_r; - v8u16 temp0, temp1, temp2, temp3; - v8u16 wgt, denom, offset; - v16i8 out0, out1; + uint32_t offset_val; + uint64_t tp0, tp1, tp2, tp3; + v16u8 src0 = { 0 }, src1 = { 0 }, src2 = { 0 }, src3 = { 0 }; + v8i16 src0_r, src1_r, src2_r, src3_r, src4_r, src5_r, src6_r, src7_r; + v8i16 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + v8i16 wgt, denom, offset; - offset_in <<= (log2_denom); + offset_val = (unsigned) offset_in << log2_denom; - if (log2_denom) { - offset_in += (1 << (log2_denom - 1)); - } - - wgt = (v8u16) __msa_fill_h(src_weight); - offset = (v8u16) __msa_fill_h(offset_in); - denom = (v8u16) __msa_fill_h(log2_denom); + wgt = __msa_fill_h(src_weight); + offset = __msa_fill_h(offset_val); + denom = __msa_fill_h(log2_denom); - for (cnt = height / 4; cnt--;) { - LD_UB4(data, stride, src0, src1, src2, src3); - ILVR_B4_UH(zero, src0, zero, src1, zero, src2, zero, src3, - src0_r, src1_r, src2_r, src3_r); - MUL4(wgt, src0_r, wgt, src1_r, wgt, src2_r, wgt, src3_r, - temp0, temp1, temp2, temp3); - ADDS_SH4_UH(temp0, offset, temp1, offset, temp2, offset, temp3, offset, - temp0, temp1, temp2, temp3); - MAXI_SH4_UH(temp0, temp1, temp2, temp3, 0); - SRL_H4_UH(temp0, temp1, temp2, temp3, denom); - SAT_UH4_UH(temp0, temp1, temp2, temp3, 7); - PCKEV_B2_SB(temp1, temp0, temp3, temp2, out0, out1); - ST8x4_UB(out0, out1, data, stride); - data += (4 * stride); - } + LD4(data, stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, src0); + INSERT_D2_UB(tp2, tp3, src1); + LD4(data + 4 * stride, stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, src2); + INSERT_D2_UB(tp2, tp3, src3); + UNPCK_UB_SH(src0, src0_r, src1_r); + UNPCK_UB_SH(src1, src2_r, src3_r); + UNPCK_UB_SH(src2, src4_r, src5_r); + UNPCK_UB_SH(src3, src6_r, src7_r); + MUL4(wgt, src0_r, wgt, src1_r, wgt, src2_r, wgt, src3_r, tmp0, tmp1, tmp2, + tmp3); + MUL4(wgt, src4_r, wgt, src5_r, wgt, src6_r, wgt, src7_r, tmp4, tmp5, tmp6, + tmp7); + ADDS_SH4_SH(tmp0, offset, tmp1, offset, tmp2, offset, tmp3, offset, tmp0, + tmp1, tmp2, tmp3); + ADDS_SH4_SH(tmp4, offset, tmp5, offset, tmp6, offset, tmp7, offset, tmp4, + tmp5, tmp6, tmp7); + MAXI_SH8_SH(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, 0); + SRLR_H8_SH(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, denom); + SAT_UH8_SH(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, 7); + PCKEV_B4_UB(tmp1, tmp0, tmp3, tmp2, tmp5, tmp4, tmp7, tmp6, src0, src1, + src2, src3); + ST8x8_UB(src0, src1, src2, src3, data, stride); } -static void avc_wgt_16width_msa(uint8_t *data, int32_t stride, - int32_t height, int32_t log2_denom, - int32_t src_weight, int32_t offset_in) +static void avc_wgt_8x16_msa(uint8_t *data, int32_t stride, int32_t log2_denom, + int32_t src_weight, int32_t offset_in) { - uint8_t cnt; - v16i8 zero = { 0 }; - v16u8 src0, src1, src2, src3; - v16u8 dst0, dst1, dst2, dst3; - v8u16 src0_l, src1_l, src2_l, src3_l, src0_r, src1_r, src2_r, src3_r; - v8u16 temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7; - v8u16 wgt, denom, offset; - - offset_in <<= (log2_denom); + uint32_t offset_val, cnt; + uint64_t tp0, tp1, tp2, tp3; + v16u8 src0 = { 0 }, src1 = { 0 }, src2 = { 0 }, src3 = { 0 }; + v8i16 src0_r, src1_r, src2_r, src3_r, src4_r, src5_r, src6_r, src7_r; + v8i16 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + v8i16 wgt, denom, offset; - if (log2_denom) { - offset_in += (1 << (log2_denom - 1)); - } + offset_val = (unsigned) offset_in << log2_denom; - wgt = (v8u16) __msa_fill_h(src_weight); - offset = (v8u16) __msa_fill_h(offset_in); - denom = (v8u16) __msa_fill_h(log2_denom); + wgt = __msa_fill_h(src_weight); + offset = __msa_fill_h(offset_val); + denom = __msa_fill_h(log2_denom); - for (cnt = height / 4; cnt--;) { - LD_UB4(data, stride, src0, src1, src2, src3); - ILVR_B4_UH(zero, src0, zero, src1, zero, src2, zero, src3, - src0_r, src1_r, src2_r, src3_r); - ILVL_B4_UH(zero, src0, zero, src1, zero, src2, zero, src3, - src0_l, src1_l, src2_l, src3_l); - MUL4(wgt, src0_r, wgt, src0_l, wgt, src1_r, wgt, src1_l, - temp0, temp1, temp2, temp3); - MUL4(wgt, src2_r, wgt, src2_l, wgt, src3_r, wgt, src3_l, - temp4, temp5, temp6, temp7); - ADDS_SH4_UH(temp0, offset, temp1, offset, temp2, offset, temp3, offset, - temp0, temp1, temp2, temp3); - ADDS_SH4_UH(temp4, offset, temp5, offset, temp6, offset, temp7, offset, - temp4, temp5, temp6, temp7); - MAXI_SH4_UH(temp0, temp1, temp2, temp3, 0); - MAXI_SH4_UH(temp4, temp5, temp6, temp7, 0); - SRL_H4_UH(temp0, temp1, temp2, temp3, denom); - SRL_H4_UH(temp4, temp5, temp6, temp7, denom); - SAT_UH4_UH(temp0, temp1, temp2, temp3, 7); - SAT_UH4_UH(temp4, temp5, temp6, temp7, 7); - PCKEV_B4_UB(temp1, temp0, temp3, temp2, temp5, temp4, temp7, temp6, - dst0, dst1, dst2, dst3); - ST_UB4(dst0, dst1, dst2, dst3, data, stride); - data += 4 * stride; + for (cnt = 2; cnt--;) { + LD4(data, stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, src0); + INSERT_D2_UB(tp2, tp3, src1); + LD4(data + 4 * stride, stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, src2); + INSERT_D2_UB(tp2, tp3, src3); + UNPCK_UB_SH(src0, src0_r, src1_r); + UNPCK_UB_SH(src1, src2_r, src3_r); + UNPCK_UB_SH(src2, src4_r, src5_r); + UNPCK_UB_SH(src3, src6_r, src7_r); + MUL4(wgt, src0_r, wgt, src1_r, wgt, src2_r, wgt, src3_r, tmp0, tmp1, + tmp2, tmp3); + MUL4(wgt, src4_r, wgt, src5_r, wgt, src6_r, wgt, src7_r, tmp4, tmp5, + tmp6, tmp7); + ADDS_SH4_SH(tmp0, offset, tmp1, offset, tmp2, offset, tmp3, offset, + tmp0, tmp1, tmp2, tmp3); + ADDS_SH4_SH(tmp4, offset, tmp5, offset, tmp6, offset, tmp7, offset, + tmp4, tmp5, tmp6, tmp7); + MAXI_SH8_SH(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, 0); + SRLR_H8_SH(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, denom); + SAT_UH8_SH(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, 7); + PCKEV_B4_UB(tmp1, tmp0, tmp3, tmp2, tmp5, tmp4, tmp7, tmp6, src0, src1, + src2, src3); + ST8x8_UB(src0, src1, src2, src3, data, stride); + data += 8 * stride; } } @@ -2291,23 +2305,126 @@ void ff_h264_h_loop_filter_luma_mbaff_intra_msa(uint8_t *src, void ff_weight_h264_pixels16_8_msa(uint8_t *src, ptrdiff_t stride, int height, int log2_denom, - int weight_src, int offset) + int weight_src, int offset_in) { - avc_wgt_16width_msa(src, stride, height, log2_denom, weight_src, offset); + uint32_t offset_val; + v16i8 zero = { 0 }; + v16u8 src0, src1, src2, src3, src4, src5, src6, src7; + v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; + v8i16 src0_l, src1_l, src2_l, src3_l, src0_r, src1_r, src2_r, src3_r; + v8i16 src4_l, src5_l, src6_l, src7_l, src4_r, src5_r, src6_r, src7_r; + v8i16 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + v8i16 tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15; + v8i16 wgt, denom, offset; + + offset_val = (unsigned) offset_in << log2_denom; + + wgt = __msa_fill_h(weight_src); + offset = __msa_fill_h(offset_val); + denom = __msa_fill_h(log2_denom); + + LD_UB8(src, stride, src0, src1, src2, src3, src4, src5, src6, src7); + ILVR_B4_SH(zero, src0, zero, src1, zero, src2, zero, src3, src0_r, src1_r, + src2_r, src3_r); + ILVL_B4_SH(zero, src0, zero, src1, zero, src2, zero, src3, src0_l, src1_l, + src2_l, src3_l); + ILVR_B4_SH(zero, src4, zero, src5, zero, src6, zero, src7, src4_r, src5_r, + src6_r, src7_r); + ILVL_B4_SH(zero, src4, zero, src5, zero, src6, zero, src7, src4_l, src5_l, + src6_l, src7_l); + MUL4(wgt, src0_r, wgt, src0_l, wgt, src1_r, wgt, src1_l, tmp0, tmp1, tmp2, + tmp3); + MUL4(wgt, src2_r, wgt, src2_l, wgt, src3_r, wgt, src3_l, tmp4, tmp5, tmp6, + tmp7); + MUL4(wgt, src4_r, wgt, src4_l, wgt, src5_r, wgt, src5_l, tmp8, tmp9, tmp10, + tmp11); + MUL4(wgt, src6_r, wgt, src6_l, wgt, src7_r, wgt, src7_l, tmp12, tmp13, + tmp14, tmp15); + ADDS_SH4_SH(tmp0, offset, tmp1, offset, tmp2, offset, tmp3, offset, tmp0, + tmp1, tmp2, tmp3); + ADDS_SH4_SH(tmp4, offset, tmp5, offset, tmp6, offset, tmp7, offset, tmp4, + tmp5, tmp6, tmp7); + ADDS_SH4_SH(tmp8, offset, tmp9, offset, tmp10, offset, tmp11, offset, tmp8, + tmp9, tmp10, tmp11); + ADDS_SH4_SH(tmp12, offset, tmp13, offset, tmp14, offset, tmp15, offset, + tmp12, tmp13, tmp14, tmp15); + MAXI_SH8_SH(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, 0); + MAXI_SH8_SH(tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, 0); + SRLR_H8_SH(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, denom); + SRLR_H8_SH(tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, denom); + SAT_UH8_SH(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, 7); + SAT_UH8_SH(tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, 7); + PCKEV_B4_UB(tmp1, tmp0, tmp3, tmp2, tmp5, tmp4, tmp7, tmp6, dst0, dst1, + dst2, dst3); + PCKEV_B4_UB(tmp9, tmp8, tmp11, tmp10, tmp13, tmp12, tmp15, tmp14, dst4, + dst5, dst6, dst7); + ST_UB8(dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7, src, stride); + src += 8 * stride; + + if (16 == height) { + LD_UB8(src, stride, src0, src1, src2, src3, src4, src5, src6, src7); + ILVR_B4_SH(zero, src0, zero, src1, zero, src2, zero, src3, src0_r, + src1_r, src2_r, src3_r); + ILVL_B4_SH(zero, src0, zero, src1, zero, src2, zero, src3, src0_l, + src1_l, src2_l, src3_l); + ILVR_B4_SH(zero, src4, zero, src5, zero, src6, zero, src7, src4_r, + src5_r, src6_r, src7_r); + ILVL_B4_SH(zero, src4, zero, src5, zero, src6, zero, src7, src4_l, + src5_l, src6_l, src7_l); + MUL4(wgt, src0_r, wgt, src0_l, wgt, src1_r, wgt, src1_l, tmp0, tmp1, + tmp2, tmp3); + MUL4(wgt, src2_r, wgt, src2_l, wgt, src3_r, wgt, src3_l, tmp4, tmp5, + tmp6, tmp7); + MUL4(wgt, src4_r, wgt, src4_l, wgt, src5_r, wgt, src5_l, tmp8, tmp9, + tmp10, tmp11); + MUL4(wgt, src6_r, wgt, src6_l, wgt, src7_r, wgt, src7_l, tmp12, tmp13, + tmp14, tmp15); + ADDS_SH4_SH(tmp0, offset, tmp1, offset, tmp2, offset, tmp3, offset, + tmp0, tmp1, tmp2, tmp3); + ADDS_SH4_SH(tmp4, offset, tmp5, offset, tmp6, offset, tmp7, offset, + tmp4, tmp5, tmp6, tmp7); + ADDS_SH4_SH(tmp8, offset, tmp9, offset, tmp10, offset, tmp11, offset, + tmp8, tmp9, tmp10, tmp11); + ADDS_SH4_SH(tmp12, offset, tmp13, offset, tmp14, offset, tmp15, offset, + tmp12, tmp13, tmp14, tmp15); + MAXI_SH8_SH(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, 0); + MAXI_SH8_SH(tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, 0); + SRLR_H8_SH(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, denom); + SRLR_H8_SH(tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, denom); + SAT_UH8_SH(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, 7); + SAT_UH8_SH(tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, 7); + PCKEV_B4_UB(tmp1, tmp0, tmp3, tmp2, tmp5, tmp4, tmp7, tmp6, dst0, dst1, + dst2, dst3); + PCKEV_B4_UB(tmp9, tmp8, tmp11, tmp10, tmp13, tmp12, tmp15, tmp14, dst4, + dst5, dst6, dst7); + ST_UB8(dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7, src, stride); + } } void ff_weight_h264_pixels8_8_msa(uint8_t *src, ptrdiff_t stride, int height, int log2_denom, int weight_src, int offset) { - avc_wgt_8width_msa(src, stride, height, log2_denom, weight_src, offset); + if (4 == height) { + avc_wgt_8x4_msa(src, stride, log2_denom, weight_src, offset); + } else if (8 == height) { + avc_wgt_8x8_msa(src, stride, log2_denom, weight_src, offset); + } else { + avc_wgt_8x16_msa(src, stride, log2_denom, weight_src, offset); + } } void ff_weight_h264_pixels4_8_msa(uint8_t *src, ptrdiff_t stride, int height, int log2_denom, int weight_src, int offset) { - avc_wgt_4width_msa(src, stride, height, log2_denom, weight_src, offset); + if (2 == height) { + avc_wgt_4x2_msa(src, stride, log2_denom, weight_src, offset); + } else if (4 == height) { + avc_wgt_4x4_msa(src, stride, log2_denom, weight_src, offset); + } else { + avc_wgt_4x8_msa(src, stride, log2_denom, weight_src, offset); + } } void ff_biweight_h264_pixels16_8_msa(uint8_t *dst, uint8_t *src, diff --git a/libavutil/mips/generic_macros_msa.h b/libavutil/mips/generic_macros_msa.h index bda3ed263f397..7de97dd0f8117 100644 --- a/libavutil/mips/generic_macros_msa.h +++ b/libavutil/mips/generic_macros_msa.h @@ -1635,6 +1635,15 @@ MAXI_SH2(RTYPE, in2, in3, max_val); \ } #define MAXI_SH4_UH(...) MAXI_SH4(v8u16, __VA_ARGS__) +#define MAXI_SH4_SH(...) MAXI_SH4(v8i16, __VA_ARGS__) + +#define MAXI_SH8(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, max_val) \ +{ \ + MAXI_SH4(RTYPE, in0, in1, in2, in3, max_val); \ + MAXI_SH4(RTYPE, in4, in5, in6, in7, max_val); \ +} +#define MAXI_SH8_UH(...) MAXI_SH8(v8u16, __VA_ARGS__) +#define MAXI_SH8_SH(...) MAXI_SH8(v8i16, __VA_ARGS__) /* Description : Saturate the halfword element values to the max unsigned value of (sat_val+1 bits) @@ -1660,6 +1669,15 @@ SAT_UH2(RTYPE, in2, in3, sat_val); \ } #define SAT_UH4_UH(...) SAT_UH4(v8u16, __VA_ARGS__) +#define SAT_UH4_SH(...) SAT_UH4(v8i16, __VA_ARGS__) + +#define SAT_UH8(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, sat_val) \ +{ \ + SAT_UH4(RTYPE, in0, in1, in2, in3, sat_val); \ + SAT_UH4(RTYPE, in4, in5, in6, in7, sat_val); \ +} +#define SAT_UH8_UH(...) SAT_UH8(v8u16, __VA_ARGS__) +#define SAT_UH8_SH(...) SAT_UH8(v8i16, __VA_ARGS__) /* Description : Saturate the halfword element values to the max unsigned value of (sat_val+1 bits) @@ -2040,6 +2058,24 @@ } #define SRL_H4_UH(...) SRL_H4(v8u16, __VA_ARGS__) +#define SRLR_H4(RTYPE, in0, in1, in2, in3, shift) \ +{ \ + in0 = (RTYPE) __msa_srlr_h((v8i16) in0, (v8i16) shift); \ + in1 = (RTYPE) __msa_srlr_h((v8i16) in1, (v8i16) shift); \ + in2 = (RTYPE) __msa_srlr_h((v8i16) in2, (v8i16) shift); \ + in3 = (RTYPE) __msa_srlr_h((v8i16) in3, (v8i16) shift); \ +} +#define SRLR_H4_UH(...) SRLR_H4(v8u16, __VA_ARGS__) +#define SRLR_H4_SH(...) SRLR_H4(v8i16, __VA_ARGS__) + +#define SRLR_H8(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, shift) \ +{ \ + SRLR_H4(RTYPE, in0, in1, in2, in3, shift); \ + SRLR_H4(RTYPE, in4, in5, in6, in7, shift); \ +} +#define SRLR_H8_UH(...) SRLR_H8(v8u16, __VA_ARGS__) +#define SRLR_H8_SH(...) SRLR_H8(v8i16, __VA_ARGS__) + /* Description : Shift right arithmetic rounded halfwords Arguments : Inputs - in0, in1, shift Outputs - in0, in1, (in place) From b8854e2439c3db73e0d63b838763702d14a61767 Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Tue, 26 Sep 2017 10:56:27 +0530 Subject: [PATCH 3189/3374] avcodec/mips: Improve avc chroma vert mc msa functions Replace generic with block size specific function. Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/h264chroma_msa.c | 237 +++++++++++++++---------------- 1 file changed, 112 insertions(+), 125 deletions(-) diff --git a/libavcodec/mips/h264chroma_msa.c b/libavcodec/mips/h264chroma_msa.c index c27830d760868..16e2fe4ec7a7f 100644 --- a/libavcodec/mips/h264chroma_msa.c +++ b/libavcodec/mips/h264chroma_msa.c @@ -302,8 +302,7 @@ static void avc_chroma_hz_8w_msa(uint8_t *src, uint8_t *dst, int32_t stride, } } -static void avc_chroma_vt_2x2_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, +static void avc_chroma_vt_2x2_msa(uint8_t *src, uint8_t *dst, int32_t stride, uint32_t coeff0, uint32_t coeff1) { uint16_t out0, out1; @@ -315,7 +314,7 @@ static void avc_chroma_vt_2x2_msa(uint8_t *src, int32_t src_stride, v16i8 coeff_vec1 = __msa_fill_b(coeff1); v16u8 coeff_vec = (v16u8) __msa_ilvr_b(coeff_vec0, coeff_vec1); - LD_SB3(src, src_stride, src0, src1, src2); + LD_SB3(src, stride, src0, src1, src2); ILVR_B2_UB(src1, src0, src2, src1, tmp0, tmp1); @@ -331,12 +330,11 @@ static void avc_chroma_vt_2x2_msa(uint8_t *src, int32_t src_stride, out1 = __msa_copy_u_h(res, 2); SH(out0, dst); - dst += dst_stride; + dst += stride; SH(out1, dst); } -static void avc_chroma_vt_2x4_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, +static void avc_chroma_vt_2x4_msa(uint8_t *src, uint8_t *dst, int32_t stride, uint32_t coeff0, uint32_t coeff1) { v16u8 src0, src1, src2, src3, src4; @@ -347,39 +345,7 @@ static void avc_chroma_vt_2x4_msa(uint8_t *src, int32_t src_stride, v16i8 coeff_vec1 = __msa_fill_b(coeff1); v16u8 coeff_vec = (v16u8) __msa_ilvr_b(coeff_vec0, coeff_vec1); - LD_UB5(src, src_stride, src0, src1, src2, src3, src4); - ILVR_B4_UB(src1, src0, src2, src1, src3, src2, src4, src3, - tmp0, tmp1, tmp2, tmp3); - ILVR_W2_UB(tmp1, tmp0, tmp3, tmp2, tmp0, tmp2); - - tmp0 = (v16u8) __msa_ilvr_d((v2i64) tmp2, (v2i64) tmp0); - - res_r = __msa_dotp_u_h(tmp0, coeff_vec); - res_r <<= 3; - res_r = (v8u16) __msa_srari_h((v8i16) res_r, 6); - res_r = __msa_sat_u_h(res_r, 7); - - res = (v8i16) __msa_pckev_b((v16i8) res_r, (v16i8) res_r); - - ST2x4_UB(res, 0, dst, dst_stride); -} - -static void avc_chroma_vt_2x8_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - uint32_t coeff0, uint32_t coeff1) -{ - v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8; - v16u8 tmp0, tmp1, tmp2, tmp3; - v8i16 res; - v8u16 res_r; - v16i8 coeff_vec0 = __msa_fill_b(coeff0); - v16i8 coeff_vec1 = __msa_fill_b(coeff1); - v16u8 coeff_vec = (v16u8) __msa_ilvr_b(coeff_vec0, coeff_vec1); - - LD_UB5(src, src_stride, src0, src1, src2, src3, src4); - src += (5 * src_stride); - LD_UB4(src, src_stride, src5, src6, src7, src8); - + LD_UB5(src, stride, src0, src1, src2, src3, src4); ILVR_B4_UB(src1, src0, src2, src1, src3, src2, src4, src3, tmp0, tmp1, tmp2, tmp3); ILVR_W2_UB(tmp1, tmp0, tmp3, tmp2, tmp0, tmp2); @@ -393,42 +359,21 @@ static void avc_chroma_vt_2x8_msa(uint8_t *src, int32_t src_stride, res = (v8i16) __msa_pckev_b((v16i8) res_r, (v16i8) res_r); - ST2x4_UB(res, 0, dst, dst_stride); - dst += (4 * dst_stride); - - ILVR_B4_UB(src5, src4, src6, src5, src7, src6, src8, src7, - tmp0, tmp1, tmp2, tmp3); - ILVR_W2_UB(tmp1, tmp0, tmp3, tmp2, tmp0, tmp2); - - tmp0 = (v16u8) __msa_ilvr_d((v2i64) tmp2, (v2i64) tmp0); - - res_r = __msa_dotp_u_h(tmp0, coeff_vec); - res_r <<= 3; - res_r = (v8u16) __msa_srari_h((v8i16) res_r, 6); - res_r = __msa_sat_u_h(res_r, 7); - - res = (v8i16) __msa_pckev_b((v16i8) res_r, (v16i8) res_r); - - ST2x4_UB(res, 0, dst, dst_stride); - dst += (4 * dst_stride); + ST2x4_UB(res, 0, dst, stride); } -static void avc_chroma_vt_2w_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, +static void avc_chroma_vt_2w_msa(uint8_t *src, uint8_t *dst, int32_t stride, uint32_t coeff0, uint32_t coeff1, int32_t height) { if (2 == height) { - avc_chroma_vt_2x2_msa(src, src_stride, dst, dst_stride, coeff0, coeff1); + avc_chroma_vt_2x2_msa(src, dst, stride, coeff0, coeff1); } else if (4 == height) { - avc_chroma_vt_2x4_msa(src, src_stride, dst, dst_stride, coeff0, coeff1); - } else if (8 == height) { - avc_chroma_vt_2x8_msa(src, src_stride, dst, dst_stride, coeff0, coeff1); + avc_chroma_vt_2x4_msa(src, dst, stride, coeff0, coeff1); } } -static void avc_chroma_vt_4x2_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, +static void avc_chroma_vt_4x2_msa(uint8_t *src, uint8_t *dst, int32_t stride, uint32_t coeff0, uint32_t coeff1) { v16u8 src0, src1, src2; @@ -439,7 +384,7 @@ static void avc_chroma_vt_4x2_msa(uint8_t *src, int32_t src_stride, v16i8 coeff_vec1 = __msa_fill_b(coeff1); v16u8 coeff_vec = (v16u8) __msa_ilvr_b(coeff_vec0, coeff_vec1); - LD_UB3(src, src_stride, src0, src1, src2); + LD_UB3(src, stride, src0, src1, src2); ILVR_B2_UB(src1, src0, src2, src1, tmp0, tmp1); tmp0 = (v16u8) __msa_ilvr_d((v2i64) tmp1, (v2i64) tmp0); @@ -449,93 +394,135 @@ static void avc_chroma_vt_4x2_msa(uint8_t *src, int32_t src_stride, res_r = __msa_sat_u_h(res_r, 7); res = (v4i32) __msa_pckev_b((v16i8) res_r, (v16i8) res_r); - ST4x2_UB(res, dst, dst_stride); + ST4x2_UB(res, dst, stride); } -static void avc_chroma_vt_4x4multiple_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - uint32_t coeff0, uint32_t coeff1, - int32_t height) +static void avc_chroma_vt_4x4_msa(uint8_t *src, uint8_t *dst, int32_t stride, + uint32_t coeff0, uint32_t coeff1) { - uint32_t row; v16u8 src0, src1, src2, src3, src4; v16u8 tmp0, tmp1, tmp2, tmp3; + v16u8 out; v8u16 res0_r, res1_r; - v4i32 res0, res1; v16i8 coeff_vec0 = __msa_fill_b(coeff0); v16i8 coeff_vec1 = __msa_fill_b(coeff1); v16u8 coeff_vec = (v16u8) __msa_ilvr_b(coeff_vec0, coeff_vec1); - src0 = LD_UB(src); - src += src_stride; - - for (row = (height >> 2); row--;) { - LD_UB4(src, src_stride, src1, src2, src3, src4); - src += (4 * src_stride); - - ILVR_B4_UB(src1, src0, src2, src1, src3, src2, src4, src3, - tmp0, tmp1, tmp2, tmp3); - ILVR_D2_UB(tmp1, tmp0, tmp3, tmp2, tmp0, tmp2); - DOTP_UB2_UH(tmp0, tmp2, coeff_vec, coeff_vec, res0_r, res1_r); - - res0_r <<= 3; - res1_r <<= 3; + LD_UB5(src, stride, src0, src1, src2, src3, src4); + ILVR_B4_UB(src1, src0, src2, src1, src3, src2, src4, src3, tmp0, tmp1, tmp2, + tmp3); + ILVR_D2_UB(tmp1, tmp0, tmp3, tmp2, tmp0, tmp2); + DOTP_UB2_UH(tmp0, tmp2, coeff_vec, coeff_vec, res0_r, res1_r); + res0_r <<= 3; + res1_r <<= 3; + SRARI_H2_UH(res0_r, res1_r, 6); + SAT_UH2_UH(res0_r, res1_r, 7); + out = (v16u8) __msa_pckev_b((v16i8) res1_r, (v16i8) res0_r); + ST4x4_UB(out, out, 0, 1, 2, 3, dst, stride); +} - SRARI_H2_UH(res0_r, res1_r, 6); - SAT_UH2_UH(res0_r, res1_r, 7); - PCKEV_B2_SW(res0_r, res0_r, res1_r, res1_r, res0, res1); +static void avc_chroma_vt_4x8_msa(uint8_t *src, uint8_t *dst, int32_t stride, + uint32_t coeff0, uint32_t coeff1) +{ + v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8; + v16u8 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, out0, out1; + v8u16 res0, res1, res2, res3; + v16i8 coeff_vec0 = __msa_fill_b(coeff0); + v16i8 coeff_vec1 = __msa_fill_b(coeff1); + v16u8 coeff_vec = (v16u8) __msa_ilvr_b(coeff_vec0, coeff_vec1); - ST4x4_UB(res0, res1, 0, 1, 0, 1, dst, dst_stride); - dst += (4 * dst_stride); - src0 = src4; - } + LD_UB5(src, stride, src0, src1, src2, src3, src4); + src += (5 * stride); + LD_UB4(src, stride, src5, src6, src7, src8); + ILVR_B4_UB(src1, src0, src2, src1, src3, src2, src4, src3, tmp0, tmp1, tmp2, + tmp3); + ILVR_B4_UB(src5, src4, src6, src5, src7, src6, src8, src7, tmp4, tmp5, tmp6, + tmp7); + ILVR_D2_UB(tmp1, tmp0, tmp3, tmp2, tmp0, tmp2); + ILVR_D2_UB(tmp5, tmp4, tmp7, tmp6, tmp4, tmp6); + DOTP_UB2_UH(tmp0, tmp2, coeff_vec, coeff_vec, res0, res1); + DOTP_UB2_UH(tmp4, tmp6, coeff_vec, coeff_vec, res2, res3); + SLLI_4V(res0, res1, res2, res3, 3); + SRARI_H4_UH(res0, res1, res2, res3, 6); + SAT_UH4_UH(res0, res1, res2, res3, 7); + PCKEV_B2_UB(res1, res0, res3, res2, out0, out1); + ST4x8_UB(out0, out1, dst, stride); } -static void avc_chroma_vt_4w_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, +static void avc_chroma_vt_4w_msa(uint8_t *src, uint8_t *dst, int32_t stride, uint32_t coeff0, uint32_t coeff1, int32_t height) { if (2 == height) { - avc_chroma_vt_4x2_msa(src, src_stride, dst, dst_stride, coeff0, coeff1); - } else { - avc_chroma_vt_4x4multiple_msa(src, src_stride, dst, dst_stride, coeff0, - coeff1, height); + avc_chroma_vt_4x2_msa(src, dst, stride, coeff0, coeff1); + } else if (4 == height) { + avc_chroma_vt_4x4_msa(src, dst, stride, coeff0, coeff1); + } else if (8 == height) { + avc_chroma_vt_4x8_msa(src, dst, stride, coeff0, coeff1); } } -static void avc_chroma_vt_8w_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - uint32_t coeff0, uint32_t coeff1, - int32_t height) +static void avc_chroma_vt_8x4_msa(uint8_t *src, uint8_t *dst, int32_t stride, + uint32_t coeff0, uint32_t coeff1) { - uint32_t row; v16u8 src0, src1, src2, src3, src4, out0, out1; v8u16 res0, res1, res2, res3; v16i8 coeff_vec0 = __msa_fill_b(coeff0); v16i8 coeff_vec1 = __msa_fill_b(coeff1); v16u8 coeff_vec = (v16u8) __msa_ilvr_b(coeff_vec0, coeff_vec1); - src0 = LD_UB(src); - src += src_stride; - - for (row = height >> 2; row--;) { - LD_UB4(src, src_stride, src1, src2, src3, src4); - src += (4 * src_stride); + LD_UB5(src, stride, src0, src1, src2, src3, src4); + ILVR_B4_UB(src1, src0, src2, src1, src3, src2, src4, src3, src0, src1, src2, + src3); + DOTP_UB4_UH(src0, src1, src2, src3, coeff_vec, coeff_vec, coeff_vec, + coeff_vec, res0, res1, res2, res3); + SLLI_4V(res0, res1, res2, res3, 3); + SRARI_H4_UH(res0, res1, res2, res3, 6); + SAT_UH4_UH(res0, res1, res2, res3, 7); + PCKEV_B2_UB(res1, res0, res3, res2, out0, out1); + ST8x4_UB(out0, out1, dst, stride); +} - ILVR_B4_UB(src1, src0, src2, src1, src3, src2, src4, src3, - src0, src1, src2, src3); - DOTP_UB4_UH(src0, src1, src2, src3, coeff_vec, coeff_vec, coeff_vec, - coeff_vec, res0, res1, res2, res3); - SLLI_4V(res0, res1, res2, res3, 3); - SRARI_H4_UH(res0, res1, res2, res3, 6); - SAT_UH4_UH(res0, res1, res2, res3, 7); - PCKEV_B2_UB(res1, res0, res3, res2, out0, out1); +static void avc_chroma_vt_8x8_msa(uint8_t *src, uint8_t *dst, int32_t stride, + uint32_t coeff0, uint32_t coeff1) +{ + v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8; + v16u8 out0, out1, out2, out3; + v8u16 res0, res1, res2, res3, res4, res5, res6, res7; + v16i8 coeff_vec0 = __msa_fill_b(coeff0); + v16i8 coeff_vec1 = __msa_fill_b(coeff1); + v16u8 coeff_vec = (v16u8) __msa_ilvr_b(coeff_vec0, coeff_vec1); - ST8x4_UB(out0, out1, dst, dst_stride); + LD_UB5(src, stride, src0, src1, src2, src3, src4); + src += (5 * stride); + LD_UB4(src, stride, src5, src6, src7, src8); + ILVR_B4_UB(src1, src0, src2, src1, src3, src2, src4, src3, src0, src1, src2, + src3); + ILVR_B4_UB(src5, src4, src6, src5, src7, src6, src8, src7, src4, src5, src6, + src7); + DOTP_UB4_UH(src0, src1, src2, src3, coeff_vec, coeff_vec, coeff_vec, + coeff_vec, res0, res1, res2, res3); + DOTP_UB4_UH(src4, src5, src6, src7, coeff_vec, coeff_vec, coeff_vec, + coeff_vec, res4, res5, res6, res7); + SLLI_4V(res0, res1, res2, res3, 3); + SLLI_4V(res4, res5, res6, res7, 3); + SRARI_H4_UH(res0, res1, res2, res3, 6); + SRARI_H4_UH(res4, res5, res6, res7, 6); + SAT_UH4_UH(res0, res1, res2, res3, 7); + SAT_UH4_UH(res0, res1, res2, res3, 7); + PCKEV_B2_UB(res1, res0, res3, res2, out0, out1); + PCKEV_B2_UB(res5, res4, res7, res6, out2, out3); + ST8x8_UB(out0, out1, out2, out3, dst, stride); +} - dst += (4 * dst_stride); - src0 = src4; +static void avc_chroma_vt_8w_msa(uint8_t *src, uint8_t *dst, int32_t stride, + uint32_t coeff0, uint32_t coeff1, + int32_t height) +{ + if (4 == height) { + avc_chroma_vt_8x4_msa(src, dst, stride, coeff0, coeff1); + } else if (8 == height) { + avc_chroma_vt_8x8_msa(src, dst, stride, coeff0, coeff1); } } @@ -1914,7 +1901,7 @@ void ff_put_h264_chroma_mc8_msa(uint8_t *dst, uint8_t *src, } else if (x) { avc_chroma_hz_8w_msa(src, dst, stride, x, (8 - x), height); } else if (y) { - avc_chroma_vt_8w_msa(src, stride, dst, stride, y, (8 - y), height); + avc_chroma_vt_8w_msa(src, dst, stride, y, (8 - y), height); } else { copy_width8_msa(src, stride, dst, stride, height); } @@ -1933,7 +1920,7 @@ void ff_put_h264_chroma_mc4_msa(uint8_t *dst, uint8_t *src, } else if (x) { avc_chroma_hz_4w_msa(src, dst, stride, x, (8 - x), height); } else if (y) { - avc_chroma_vt_4w_msa(src, stride, dst, stride, y, (8 - y), height); + avc_chroma_vt_4w_msa(src, dst, stride, y, (8 - y), height); } else { for (cnt = height; cnt--;) { *((uint32_t *) dst) = *((uint32_t *) src); @@ -1957,7 +1944,7 @@ void ff_put_h264_chroma_mc2_msa(uint8_t *dst, uint8_t *src, } else if (x) { avc_chroma_hz_2w_msa(src, dst, stride, x, (8 - x), height); } else if (y) { - avc_chroma_vt_2w_msa(src, stride, dst, stride, y, (8 - y), height); + avc_chroma_vt_2w_msa(src, dst, stride, y, (8 - y), height); } else { for (cnt = height; cnt--;) { *((uint16_t *) dst) = *((uint16_t *) src); From 6796a1dd8c14843b77925cb83a3ef88706ae1dd0 Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Tue, 26 Sep 2017 13:20:23 +0530 Subject: [PATCH 3190/3374] avcodec/mips: Improve avc put mc 20, 01 and 03 msa functions Remove loops and unroll as block sizes are known. Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/h264qpel_msa.c | 441 ++++++++++++++++++++++++++++++++- 1 file changed, 432 insertions(+), 9 deletions(-) diff --git a/libavcodec/mips/h264qpel_msa.c b/libavcodec/mips/h264qpel_msa.c index b7f6c3d5891fc..0b42bc4f727f8 100644 --- a/libavcodec/mips/h264qpel_msa.c +++ b/libavcodec/mips/h264qpel_msa.c @@ -148,6 +148,17 @@ static const uint8_t luma_mask_arr[16 * 8] = { hz_out_m; \ } ) +#define AVC_DOT_SH3_SH(in0, in1, in2, coeff0, coeff1, coeff2) \ +( { \ + v8i16 out0_m; \ + \ + out0_m = __msa_dotp_s_h((v16i8) in0, (v16i8) coeff0); \ + out0_m = __msa_dpadd_s_h(out0_m, (v16i8) in1, (v16i8) coeff1); \ + out0_m = __msa_dpadd_s_h(out0_m, (v16i8) in2, (v16i8) coeff2); \ + \ + out0_m; \ +} ) + static void avc_luma_hz_4w_msa(const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, int32_t height) @@ -3373,55 +3384,467 @@ void ff_put_h264_qpel4_mc30_msa(uint8_t *dst, const uint8_t *src, void ff_put_h264_qpel16_mc20_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_hz_16w_msa(src - 2, stride, dst, stride, 16); + uint32_t loop_cnt; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7, mask0, mask1, mask2; + v16i8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, vec9, vec10; + v16i8 vec11; + v8i16 res0, res1, res2, res3, res4, res5, res6, res7; + v16i8 minus5b = __msa_ldi_b(-5); + v16i8 plus20b = __msa_ldi_b(20); + + LD_SB3(&luma_mask_arr[0], 16, mask0, mask1, mask2); + src -= 2; + + for (loop_cnt = 4; loop_cnt--;) { + LD_SB2(src, 8, src0, src1); + src += stride; + LD_SB2(src, 8, src2, src3); + src += stride; + LD_SB2(src, 8, src4, src5); + src += stride; + LD_SB2(src, 8, src6, src7); + src += stride; + + XORI_B8_128_SB(src0, src1, src2, src3, src4, src5, src6, src7); + VSHF_B2_SB(src0, src0, src1, src1, mask0, mask0, vec0, vec3); + VSHF_B2_SB(src2, src2, src3, src3, mask0, mask0, vec6, vec9); + VSHF_B2_SB(src0, src0, src1, src1, mask1, mask1, vec1, vec4); + VSHF_B2_SB(src2, src2, src3, src3, mask1, mask1, vec7, vec10); + VSHF_B2_SB(src0, src0, src1, src1, mask2, mask2, vec2, vec5); + VSHF_B2_SB(src2, src2, src3, src3, mask2, mask2, vec8, vec11); + HADD_SB4_SH(vec0, vec3, vec6, vec9, res0, res1, res2, res3); + DPADD_SB4_SH(vec1, vec4, vec7, vec10, minus5b, minus5b, minus5b, + minus5b, res0, res1, res2, res3); + DPADD_SB4_SH(vec2, vec5, vec8, vec11, plus20b, plus20b, plus20b, + plus20b, res0, res1, res2, res3); + VSHF_B2_SB(src4, src4, src5, src5, mask0, mask0, vec0, vec3); + VSHF_B2_SB(src6, src6, src7, src7, mask0, mask0, vec6, vec9); + VSHF_B2_SB(src4, src4, src5, src5, mask1, mask1, vec1, vec4); + VSHF_B2_SB(src6, src6, src7, src7, mask1, mask1, vec7, vec10); + VSHF_B2_SB(src4, src4, src5, src5, mask2, mask2, vec2, vec5); + VSHF_B2_SB(src6, src6, src7, src7, mask2, mask2, vec8, vec11); + HADD_SB4_SH(vec0, vec3, vec6, vec9, res4, res5, res6, res7); + DPADD_SB4_SH(vec1, vec4, vec7, vec10, minus5b, minus5b, minus5b, + minus5b, res4, res5, res6, res7); + DPADD_SB4_SH(vec2, vec5, vec8, vec11, plus20b, plus20b, plus20b, + plus20b, res4, res5, res6, res7); + SRARI_H4_SH(res0, res1, res2, res3, 5); + SRARI_H4_SH(res4, res5, res6, res7, 5); + SAT_SH4_SH(res0, res1, res2, res3, 7); + SAT_SH4_SH(res4, res5, res6, res7, 7); + PCKEV_B4_SB(res1, res0, res3, res2, res5, res4, res7, res6, vec0, vec1, + vec2, vec3); + XORI_B4_128_SB(vec0, vec1, vec2, vec3); + ST_SB4(vec0, vec1, vec2, vec3, dst, stride); + dst += (4 * stride); + } } void ff_put_h264_qpel8_mc20_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_hz_8w_msa(src - 2, stride, dst, stride, 8); + v16u8 out0, out1, out2, out3; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7, mask0, mask1, mask2; + v16i8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, vec9, vec10; + v16i8 vec11; + v8i16 res0, res1, res2, res3, res4, res5, res6, res7; + v16i8 minus5b = __msa_ldi_b(-5); + v16i8 plus20b = __msa_ldi_b(20); + + LD_SB3(&luma_mask_arr[0], 16, mask0, mask1, mask2); + LD_SB8(src - 2, stride, src0, src1, src2, src3, src4, src5, src6, src7); + XORI_B8_128_SB(src0, src1, src2, src3, src4, src5, src6, src7); + VSHF_B2_SB(src0, src0, src1, src1, mask0, mask0, vec0, vec1); + VSHF_B2_SB(src2, src2, src3, src3, mask0, mask0, vec2, vec3); + HADD_SB4_SH(vec0, vec1, vec2, vec3, res0, res1, res2, res3); + VSHF_B2_SB(src0, src0, src1, src1, mask1, mask1, vec4, vec5); + VSHF_B2_SB(src2, src2, src3, src3, mask1, mask1, vec6, vec7); + DPADD_SB4_SH(vec4, vec5, vec6, vec7, minus5b, minus5b, minus5b, minus5b, + res0, res1, res2, res3); + VSHF_B2_SB(src0, src0, src1, src1, mask2, mask2, vec8, vec9); + VSHF_B2_SB(src2, src2, src3, src3, mask2, mask2, vec10, vec11); + DPADD_SB4_SH(vec8, vec9, vec10, vec11, plus20b, plus20b, plus20b, + plus20b, res0, res1, res2, res3); + VSHF_B2_SB(src4, src4, src5, src5, mask0, mask0, vec0, vec1); + VSHF_B2_SB(src6, src6, src7, src7, mask0, mask0, vec2, vec3); + HADD_SB4_SH(vec0, vec1, vec2, vec3, res4, res5, res6, res7); + VSHF_B2_SB(src4, src4, src5, src5, mask1, mask1, vec4, vec5); + VSHF_B2_SB(src6, src6, src7, src7, mask1, mask1, vec6, vec7); + DPADD_SB4_SH(vec4, vec5, vec6, vec7, minus5b, minus5b, minus5b, minus5b, + res4, res5, res6, res7); + VSHF_B2_SB(src4, src4, src5, src5, mask2, mask2, vec8, vec9); + VSHF_B2_SB(src6, src6, src7, src7, mask2, mask2, vec10, vec11); + DPADD_SB4_SH(vec8, vec9, vec10, vec11, plus20b, plus20b, plus20b, + plus20b, res4, res5, res6, res7); + SRARI_H4_SH(res0, res1, res2, res3, 5); + SRARI_H4_SH(res4, res5, res6, res7, 5); + SAT_SH4_SH(res0, res1, res2, res3, 7); + SAT_SH4_SH(res4, res5, res6, res7, 7); + out0 = PCKEV_XORI128_UB(res0, res1); + out1 = PCKEV_XORI128_UB(res2, res3); + out2 = PCKEV_XORI128_UB(res4, res5); + out3 = PCKEV_XORI128_UB(res6, res7); + ST8x8_UB(out0, out1, out2, out3, dst, stride); } void ff_put_h264_qpel4_mc20_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_hz_4w_msa(src - 2, stride, dst, stride, 4); + v16u8 out; + v16i8 src0, src1, src2, src3, mask0, mask1, mask2; + v16i8 vec0, vec1, vec2, vec3, vec4, vec5; + v8i16 res0, res1; + v16i8 minus5b = __msa_ldi_b(-5); + v16i8 plus20b = __msa_ldi_b(20); + + LD_SB3(&luma_mask_arr[48], 16, mask0, mask1, mask2); + LD_SB4(src - 2, stride, src0, src1, src2, src3); + XORI_B4_128_SB(src0, src1, src2, src3); + VSHF_B2_SB(src0, src1, src2, src3, mask0, mask0, vec0, vec1); + HADD_SB2_SH(vec0, vec1, res0, res1); + VSHF_B2_SB(src0, src1, src2, src3, mask1, mask1, vec2, vec3); + DPADD_SB2_SH(vec2, vec3, minus5b, minus5b, res0, res1); + VSHF_B2_SB(src0, src1, src2, src3, mask2, mask2, vec4, vec5); + DPADD_SB2_SH(vec4, vec5, plus20b, plus20b, res0, res1); + SRARI_H2_SH(res0, res1, 5); + SAT_SH2_SH(res0, res1, 7); + out = PCKEV_XORI128_UB(res0, res1); + ST4x4_UB(out, out, 0, 1, 2, 3, dst, stride); } void ff_put_h264_qpel16_mc01_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_vt_qrt_16w_msa(src - (stride * 2), stride, dst, stride, 16, 0); + int32_t loop_cnt; + int16_t filt_const0 = 0xfb01; + int16_t filt_const1 = 0x1414; + int16_t filt_const2 = 0x1fb; + v16u8 res0, res1, res2, res3; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8; + v16i8 src10_r, src32_r, src54_r, src76_r, src21_r, src43_r, src65_r; + v16i8 src87_r, src10_l, src32_l, src54_l, src76_l, src21_l, src43_l; + v16i8 src65_l, src87_l, filt0, filt1, filt2; + v8i16 out0_r, out1_r, out2_r, out3_r, out0_l, out1_l, out2_l, out3_l; + + filt0 = (v16i8) __msa_fill_h(filt_const0); + filt1 = (v16i8) __msa_fill_h(filt_const1); + filt2 = (v16i8) __msa_fill_h(filt_const2); + + src -= (stride * 2); + + LD_SB5(src, stride, src0, src1, src2, src3, src4); + src += (5 * stride); + + XORI_B5_128_SB(src0, src1, src2, src3, src4); + ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, src10_r, src21_r, + src32_r, src43_r); + ILVL_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, src10_l, src21_l, + src32_l, src43_l); + + for (loop_cnt = 4; loop_cnt--;) { + LD_SB4(src, stride, src5, src6, src7, src8); + src += (4 * stride); + + XORI_B4_128_SB(src5, src6, src7, src8); + ILVR_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, src54_r, + src65_r, src76_r, src87_r); + ILVL_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, src54_l, + src65_l, src76_l, src87_l); + out0_r = AVC_DOT_SH3_SH(src10_r, src32_r, src54_r, filt0, filt1, filt2); + out1_r = AVC_DOT_SH3_SH(src21_r, src43_r, src65_r, filt0, filt1, filt2); + out2_r = AVC_DOT_SH3_SH(src32_r, src54_r, src76_r, filt0, filt1, filt2); + out3_r = AVC_DOT_SH3_SH(src43_r, src65_r, src87_r, filt0, filt1, filt2); + out0_l = AVC_DOT_SH3_SH(src10_l, src32_l, src54_l, filt0, filt1, filt2); + out1_l = AVC_DOT_SH3_SH(src21_l, src43_l, src65_l, filt0, filt1, filt2); + out2_l = AVC_DOT_SH3_SH(src32_l, src54_l, src76_l, filt0, filt1, filt2); + out3_l = AVC_DOT_SH3_SH(src43_l, src65_l, src87_l, filt0, filt1, filt2); + SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, 5); + SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); + SRARI_H4_SH(out0_l, out1_l, out2_l, out3_l, 5); + SAT_SH4_SH(out0_l, out1_l, out2_l, out3_l, 7); + PCKEV_B4_UB(out0_l, out0_r, out1_l, out1_r, out2_l, out2_r, out3_l, + out3_r, res0, res1, res2, res3); + res0 = (v16u8) __msa_aver_s_b((v16i8) res0, src2); + res1 = (v16u8) __msa_aver_s_b((v16i8) res1, src3); + res2 = (v16u8) __msa_aver_s_b((v16i8) res2, src4); + res3 = (v16u8) __msa_aver_s_b((v16i8) res3, src5); + XORI_B4_128_UB(res0, res1, res2, res3); + ST_UB4(res0, res1, res2, res3, dst, stride); + dst += (4 * stride); + + src10_r = src54_r; + src32_r = src76_r; + src21_r = src65_r; + src43_r = src87_r; + src10_l = src54_l; + src32_l = src76_l; + src21_l = src65_l; + src43_l = src87_l; + src2 = src6; + src3 = src7; + src4 = src8; + } } void ff_put_h264_qpel16_mc03_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_vt_qrt_16w_msa(src - (stride * 2), stride, dst, stride, 16, 1); + int32_t loop_cnt; + int16_t filt_const0 = 0xfb01; + int16_t filt_const1 = 0x1414; + int16_t filt_const2 = 0x1fb; + v16u8 res0, res1, res2, res3; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8; + v16i8 src10_r, src32_r, src54_r, src76_r, src21_r, src43_r, src65_r; + v16i8 src87_r, src10_l, src32_l, src54_l, src76_l, src21_l, src43_l; + v16i8 src65_l, src87_l, filt0, filt1, filt2; + v8i16 out0_r, out1_r, out2_r, out3_r, out0_l, out1_l, out2_l, out3_l; + + filt0 = (v16i8) __msa_fill_h(filt_const0); + filt1 = (v16i8) __msa_fill_h(filt_const1); + filt2 = (v16i8) __msa_fill_h(filt_const2); + + src -= (stride * 2); + + LD_SB5(src, stride, src0, src1, src2, src3, src4); + src += (5 * stride); + + XORI_B5_128_SB(src0, src1, src2, src3, src4); + ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, src10_r, src21_r, + src32_r, src43_r); + ILVL_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, src10_l, src21_l, + src32_l, src43_l); + + for (loop_cnt = 4; loop_cnt--;) { + LD_SB4(src, stride, src5, src6, src7, src8); + src += (4 * stride); + + XORI_B4_128_SB(src5, src6, src7, src8); + ILVR_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, src54_r, + src65_r, src76_r, src87_r); + ILVL_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, src54_l, + src65_l, src76_l, src87_l); + out0_r = AVC_DOT_SH3_SH(src10_r, src32_r, src54_r, filt0, filt1, filt2); + out1_r = AVC_DOT_SH3_SH(src21_r, src43_r, src65_r, filt0, filt1, filt2); + out2_r = AVC_DOT_SH3_SH(src32_r, src54_r, src76_r, filt0, filt1, filt2); + out3_r = AVC_DOT_SH3_SH(src43_r, src65_r, src87_r, filt0, filt1, filt2); + out0_l = AVC_DOT_SH3_SH(src10_l, src32_l, src54_l, filt0, filt1, filt2); + out1_l = AVC_DOT_SH3_SH(src21_l, src43_l, src65_l, filt0, filt1, filt2); + out2_l = AVC_DOT_SH3_SH(src32_l, src54_l, src76_l, filt0, filt1, filt2); + out3_l = AVC_DOT_SH3_SH(src43_l, src65_l, src87_l, filt0, filt1, filt2); + SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, 5); + SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); + SRARI_H4_SH(out0_l, out1_l, out2_l, out3_l, 5); + SAT_SH4_SH(out0_l, out1_l, out2_l, out3_l, 7); + PCKEV_B4_UB(out0_l, out0_r, out1_l, out1_r, out2_l, out2_r, out3_l, + out3_r, res0, res1, res2, res3); + res0 = (v16u8) __msa_aver_s_b((v16i8) res0, src3); + res1 = (v16u8) __msa_aver_s_b((v16i8) res1, src4); + res2 = (v16u8) __msa_aver_s_b((v16i8) res2, src5); + res3 = (v16u8) __msa_aver_s_b((v16i8) res3, src6); + XORI_B4_128_UB(res0, res1, res2, res3); + ST_UB4(res0, res1, res2, res3, dst, stride); + dst += (4 * stride); + + src10_r = src54_r; + src32_r = src76_r; + src21_r = src65_r; + src43_r = src87_r; + src10_l = src54_l; + src32_l = src76_l; + src21_l = src65_l; + src43_l = src87_l; + src3 = src7; + src4 = src8; + } } void ff_put_h264_qpel8_mc01_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_vt_qrt_8w_msa(src - (stride * 2), stride, dst, stride, 8, 0); + const int16_t filt_const0 = 0xfb01; + const int16_t filt_const1 = 0x1414; + const int16_t filt_const2 = 0x1fb; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; + v16i8 src11, src12, src10_r, src32_r, src54_r, src65_r, src76_r, src98_r; + v16i8 src21_r, src43_r, src87_r, src109_r, src1211_r, src1110_r; + v16i8 tmp0, tmp1, tmp2, tmp3, filt0, filt1, filt2, out0, out1, out2, out3; + v8i16 out0_r, out1_r, out2_r, out3_r, out4_r, out5_r, out6_r, out7_r; + + filt0 = (v16i8) __msa_fill_h(filt_const0); + filt1 = (v16i8) __msa_fill_h(filt_const1); + filt2 = (v16i8) __msa_fill_h(filt_const2); + + src -= (stride * 2); + + LD_SB5(src, stride, src0, src1, src2, src3, src4); + src += (5 * stride); + LD_SB8(src, stride, src5, src6, src7, src8, src9, src10, src11, src12); + XORI_B8_128_SB(src5, src6, src7, src8, src9, src10, src11, src12); + XORI_B5_128_SB(src0, src1, src2, src3, src4); + ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, src10_r, src21_r, + src32_r, src43_r); + ILVR_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, src54_r, src65_r, + src76_r, src87_r); + ILVR_B4_SB(src9, src8, src10, src9, src11, src10, src12, src11, src98_r, + src109_r, src1110_r, src1211_r); + out0_r = AVC_DOT_SH3_SH(src10_r, src32_r, src54_r, filt0, filt1, filt2); + out1_r = AVC_DOT_SH3_SH(src21_r, src43_r, src65_r, filt0, filt1, filt2); + out2_r = AVC_DOT_SH3_SH(src32_r, src54_r, src76_r, filt0, filt1, filt2); + out3_r = AVC_DOT_SH3_SH(src43_r, src65_r, src87_r, filt0, filt1, filt2); + out4_r = AVC_DOT_SH3_SH(src54_r, src76_r, src98_r, filt0, filt1, filt2); + out5_r = AVC_DOT_SH3_SH(src65_r, src87_r, src109_r, filt0, filt1, filt2); + out6_r = AVC_DOT_SH3_SH(src76_r, src98_r, src1110_r, filt0, filt1, filt2); + out7_r = AVC_DOT_SH3_SH(src87_r, src109_r, src1211_r, filt0, filt1, filt2); + PCKEV_D2_SB(src3, src2, src5, src4, tmp0, tmp1); + PCKEV_D2_SB(src7, src6, src9, src8, tmp2, tmp3); + SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, 5); + SRARI_H4_SH(out4_r, out5_r, out6_r, out7_r, 5); + SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); + SAT_SH4_SH(out4_r, out5_r, out6_r, out7_r, 7); + PCKEV_B2_SB(out1_r, out0_r, out3_r, out2_r, out0, out1); + PCKEV_B2_SB(out5_r, out4_r, out7_r, out6_r, out2, out3); + out0 = __msa_aver_s_b(out0, tmp0); + out1 = __msa_aver_s_b(out1, tmp1); + out2 = __msa_aver_s_b(out2, tmp2); + out3 = __msa_aver_s_b(out3, tmp3); + XORI_B4_128_SB(out0, out1, out2, out3); + ST8x8_UB(out0, out1, out2, out3, dst, stride); } void ff_put_h264_qpel8_mc03_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_vt_qrt_8w_msa(src - (stride * 2), stride, dst, stride, 8, 1); + const int16_t filt_const0 = 0xfb01; + const int16_t filt_const1 = 0x1414; + const int16_t filt_const2 = 0x1fb; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; + v16i8 src11, src12, src10_r, src32_r, src54_r, src65_r, src76_r, src98_r; + v16i8 src21_r, src43_r, src87_r, src109_r, src1211_r, src1110_r; + v16i8 filt0, filt1, filt2, out0, out1, out2, out3, tmp0, tmp1, tmp2, tmp3; + v8i16 out0_r, out1_r, out2_r, out3_r, out4_r, out5_r, out6_r, out7_r; + + filt0 = (v16i8) __msa_fill_h(filt_const0); + filt1 = (v16i8) __msa_fill_h(filt_const1); + filt2 = (v16i8) __msa_fill_h(filt_const2); + + src -= (stride * 2); + + LD_SB5(src, stride, src0, src1, src2, src3, src4); + src += (5 * stride); + LD_SB8(src, stride, src5, src6, src7, src8, src9, src10, src11, src12); + XORI_B5_128_SB(src0, src1, src2, src3, src4); + XORI_B8_128_SB(src5, src6, src7, src8, src9, src10, src11, src12); + ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, src10_r, src21_r, + src32_r, src43_r); + ILVR_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, src54_r, src65_r, + src76_r, src87_r); + ILVR_B4_SB(src9, src8, src10, src9, src11, src10, src12, src11, src98_r, + src109_r, src1110_r, src1211_r); + out0_r = AVC_DOT_SH3_SH(src10_r, src32_r, src54_r, filt0, filt1, filt2); + out1_r = AVC_DOT_SH3_SH(src21_r, src43_r, src65_r, filt0, filt1, filt2); + out2_r = AVC_DOT_SH3_SH(src32_r, src54_r, src76_r, filt0, filt1, filt2); + out3_r = AVC_DOT_SH3_SH(src43_r, src65_r, src87_r, filt0, filt1, filt2); + out4_r = AVC_DOT_SH3_SH(src54_r, src76_r, src98_r, filt0, filt1, filt2); + out5_r = AVC_DOT_SH3_SH(src65_r, src87_r, src109_r, filt0, filt1, filt2); + out6_r = AVC_DOT_SH3_SH(src76_r, src98_r, src1110_r, filt0, filt1, filt2); + out7_r = AVC_DOT_SH3_SH(src87_r, src109_r, src1211_r, filt0, filt1, filt2); + PCKEV_D2_SB(src4, src3, src6, src5, tmp0, tmp1); + PCKEV_D2_SB(src8, src7, src10, src9, tmp2, tmp3); + SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, 5); + SRARI_H4_SH(out4_r, out5_r, out6_r, out7_r, 5); + SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); + SAT_SH4_SH(out4_r, out5_r, out6_r, out7_r, 7); + PCKEV_B2_SB(out1_r, out0_r, out3_r, out2_r, out0, out1); + PCKEV_B2_SB(out5_r, out4_r, out7_r, out6_r, out2, out3); + out0 = __msa_aver_s_b(out0, tmp0); + out1 = __msa_aver_s_b(out1, tmp1); + out2 = __msa_aver_s_b(out2, tmp2); + out3 = __msa_aver_s_b(out3, tmp3); + XORI_B4_128_SB(out0, out1, out2, out3); + ST8x8_UB(out0, out1, out2, out3, dst, stride); } void ff_put_h264_qpel4_mc01_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_vt_qrt_4w_msa(src - (stride * 2), stride, dst, stride, 4, 0); + int16_t filt_const0 = 0xfb01; + int16_t filt_const1 = 0x1414; + int16_t filt_const2 = 0x1fb; + v16u8 out; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8; + v16i8 src10_r, src32_r, src54_r, src76_r, src21_r, src43_r, src65_r; + v16i8 src87_r, src2110, src4332, src6554, src8776, filt0, filt1, filt2; + v8i16 out10, out32; + + filt0 = (v16i8) __msa_fill_h(filt_const0); + filt1 = (v16i8) __msa_fill_h(filt_const1); + filt2 = (v16i8) __msa_fill_h(filt_const2); + + src -= (stride * 2); + + LD_SB5(src, stride, src0, src1, src2, src3, src4); + src += (5 * stride); + ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, src10_r, src21_r, + src32_r, src43_r); + ILVR_D2_SB(src21_r, src10_r, src43_r, src32_r, src2110, src4332); + XORI_B2_128_SB(src2110, src4332); + LD_SB4(src, stride, src5, src6, src7, src8); + ILVR_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, src54_r, src65_r, + src76_r, src87_r); + ILVR_D2_SB(src65_r, src54_r, src87_r, src76_r, src6554, src8776); + XORI_B2_128_SB(src6554, src8776); + out10 = AVC_DOT_SH3_SH(src2110, src4332, src6554, filt0, filt1, filt2); + out32 = AVC_DOT_SH3_SH(src4332, src6554, src8776, filt0, filt1, filt2); + SRARI_H2_SH(out10, out32, 5); + SAT_SH2_SH(out10, out32, 7); + out = PCKEV_XORI128_UB(out10, out32); + src32_r = (v16i8) __msa_insve_w((v4i32) src2, 1, (v4i32) src3); + src54_r = (v16i8) __msa_insve_w((v4i32) src4, 1, (v4i32) src5); + src32_r = (v16i8) __msa_insve_d((v2i64) src32_r, 1, (v2i64) src54_r); + out = __msa_aver_u_b(out, (v16u8) src32_r); + ST4x4_UB(out, out, 0, 1, 2, 3, dst, stride); } void ff_put_h264_qpel4_mc03_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_vt_qrt_4w_msa(src - (stride * 2), stride, dst, stride, 4, 1); + int16_t filt_const0 = 0xfb01; + int16_t filt_const1 = 0x1414; + int16_t filt_const2 = 0x1fb; + v16u8 out; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8; + v16i8 src10_r, src32_r, src54_r, src76_r, src21_r, src43_r, src65_r; + v16i8 src87_r, src2110, src4332, src6554, src8776, filt0, filt1, filt2; + v8i16 out10, out32; + + filt0 = (v16i8) __msa_fill_h(filt_const0); + filt1 = (v16i8) __msa_fill_h(filt_const1); + filt2 = (v16i8) __msa_fill_h(filt_const2); + + src -= (stride * 2); + + LD_SB5(src, stride, src0, src1, src2, src3, src4); + src += (5 * stride); + ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, src10_r, src21_r, + src32_r, src43_r); + ILVR_D2_SB(src21_r, src10_r, src43_r, src32_r, src2110, src4332); + XORI_B2_128_SB(src2110, src4332); + LD_SB4(src, stride, src5, src6, src7, src8); + ILVR_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, src54_r, src65_r, + src76_r, src87_r); + ILVR_D2_SB(src65_r, src54_r, src87_r, src76_r, src6554, src8776); + XORI_B2_128_SB(src6554, src8776); + out10 = AVC_DOT_SH3_SH(src2110, src4332, src6554, filt0, filt1, filt2); + out32 = AVC_DOT_SH3_SH(src4332, src6554, src8776, filt0, filt1, filt2); + SRARI_H2_SH(out10, out32, 5); + SAT_SH2_SH(out10, out32, 7); + out = PCKEV_XORI128_UB(out10, out32); + src32_r = (v16i8) __msa_insve_w((v4i32) src3, 1, (v4i32) src4); + src54_r = (v16i8) __msa_insve_w((v4i32) src5, 1, (v4i32) src6); + src32_r = (v16i8) __msa_insve_d((v2i64) src32_r, 1, (v2i64) src54_r); + out = __msa_aver_u_b(out, (v16u8) src32_r); + ST4x4_UB(out, out, 0, 1, 2, 3, dst, stride); } void ff_put_h264_qpel16_mc11_msa(uint8_t *dst, const uint8_t *src, From f3aefb3e1c3c6afeaca889d4fd2648458fd74dfe Mon Sep 17 00:00:00 2001 From: Lionel CHAZALLON Date: Sun, 24 Sep 2017 05:39:45 +0000 Subject: [PATCH 3191/3374] lavc: Add support for RockChip Media Process Platform This adds hardware decoding for H.264 / HEVC / VP8 / VP9 using the MPP Rockchip API. It returns frames holding an AVDRMFrameDescriptor struct in buf[0] that allows drm / dmabuf usage. Tested on RK3288 (TinkerBoard) and RK3328. Signed-off-by: Mark Thompson --- Changelog | 1 + configure | 15 ++ libavcodec/Makefile | 4 + libavcodec/allcodecs.c | 4 + libavcodec/rkmppdec.c | 596 +++++++++++++++++++++++++++++++++++++++++ libavcodec/version.h | 2 +- 6 files changed, 621 insertions(+), 1 deletion(-) create mode 100644 libavcodec/rkmppdec.c diff --git a/Changelog b/Changelog index 678dcdadc734f..c64cef4c89a7a 100644 --- a/Changelog +++ b/Changelog @@ -50,6 +50,7 @@ version : - KMS screen grabber - CUDA thumbnail filter - V4L2 mem2mem HW assisted codecs +- Rockchip MPP hardware decoding version 3.3: diff --git a/configure b/configure index 548f766e797d7..44c5637ea5df2 100755 --- a/configure +++ b/configure @@ -316,6 +316,7 @@ External library support: --disable-nvenc disable Nvidia video encoding code [autodetect] --enable-omx enable OpenMAX IL code [no] --enable-omx-rpi enable OpenMAX IL code for Raspberry Pi [no] + --enable-rkmpp enable Rockchip Media Process Platform code [no] --disable-vaapi disable Video Acceleration API (mainly Unix/Intel) code [autodetect] --disable-vda disable Apple Video Decode Acceleration code [autodetect] --disable-vdpau disable Nvidia Video Decode and Presentation API for Unix code [autodetect] @@ -1567,6 +1568,7 @@ EXTERNAL_LIBRARY_VERSION3_LIST=" libopencore_amrnb libopencore_amrwb libvo_amrwbenc + rkmpp " EXTERNAL_LIBRARY_GPLV3_LIST=" @@ -2801,6 +2803,8 @@ h264_qsv_decoder_deps="libmfx" h264_qsv_decoder_select="h264_mp4toannexb_bsf h264_parser qsvdec h264_qsv_hwaccel" h264_qsv_encoder_deps="libmfx" h264_qsv_encoder_select="qsvenc" +h264_rkmpp_decoder_deps="rkmpp" +h264_rkmpp_decoder_select="h264_mp4toannexb_bsf" h264_vaapi_encoder_deps="VAEncPictureParameterBufferH264" h264_vaapi_encoder_select="vaapi_encode golomb" h264_vda_decoder_deps="vda" @@ -2818,6 +2822,8 @@ hevc_qsv_decoder_deps="libmfx" hevc_qsv_decoder_select="hevc_mp4toannexb_bsf hevc_parser qsvdec hevc_qsv_hwaccel" hevc_qsv_encoder_deps="libmfx" hevc_qsv_encoder_select="hevcparse qsvenc" +hevc_rkmpp_decoder_deps="rkmpp" +hevc_rkmpp_decoder_select="hevc_mp4toannexb_bsf" hevc_vaapi_encoder_deps="VAEncPictureParameterBufferHEVC" hevc_vaapi_encoder_select="vaapi_encode golomb" hevc_v4l2m2m_decoder_deps="v4l2_m2m hevc_v4l2_m2m" @@ -2864,12 +2870,14 @@ vp8_cuvid_decoder_deps="cuda cuvid" vp8_mediacodec_decoder_deps="mediacodec" vp8_qsv_decoder_deps="libmfx" vp8_qsv_decoder_select="qsvdec vp8_qsv_hwaccel vp8_parser" +vp8_rkmpp_decoder_deps="rkmpp" vp8_vaapi_encoder_deps="VAEncPictureParameterBufferVP8" vp8_vaapi_encoder_select="vaapi_encode" vp8_v4l2m2m_decoder_deps="v4l2_m2m vp8_v4l2_m2m" vp8_v4l2m2m_encoder_deps="v4l2_m2m vp8_v4l2_m2m" vp9_cuvid_decoder_deps="cuda cuvid" vp9_mediacodec_decoder_deps="mediacodec" +vp9_rkmpp_decoder_deps="rkmpp" vp9_vaapi_encoder_deps="VAEncPictureParameterBufferVP9" vp9_vaapi_encoder_select="vaapi_encode" vp9_v4l2m2m_decoder_deps="v4l2_m2m vp9_v4l2_m2m" @@ -6066,6 +6074,13 @@ enabled openssl && { use_pkg_config "" openssl openssl/ssl.h OPENSSL_i check_lib openssl openssl/ssl.h SSL_library_init -lssl32 -leay32 || check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 || die "ERROR: openssl not found"; } +enabled rkmpp && { { require_pkg_config rockchip_mpp rockchip_mpp rockchip/rk_mpi.h mpp_create || + die "ERROR : Rockchip MPP was not found."; } && + { check_func_headers rockchip/rk_mpi_cmd.h "MPP_DEC_GET_FREE_PACKET_SLOT_COUNT" || + die "ERROR: Rockchip MPP is outdated, please get a more recent one."; } && + { enabled libdrm || + die "ERROR: rkmpp requires --enable-libdrm"; } + } if enabled gcrypt; then GCRYPT_CONFIG="${cross_prefix}libgcrypt-config" diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 1b17c27408569..c4ec09b1c4535 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -341,6 +341,7 @@ OBJS-$(CONFIG_H264_VDA_DECODER) += vda_h264_dec.o OBJS-$(CONFIG_H264_OMX_ENCODER) += omx.o OBJS-$(CONFIG_H264_QSV_DECODER) += qsvdec_h2645.o OBJS-$(CONFIG_H264_QSV_ENCODER) += qsvenc_h264.o +OBJS-$(CONFIG_H264_RKMPP_DECODER) += rkmppdec.o OBJS-$(CONFIG_H264_VAAPI_ENCODER) += vaapi_encode_h264.o vaapi_encode_h26x.o OBJS-$(CONFIG_H264_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o OBJS-$(CONFIG_H264_V4L2M2M_DECODER) += v4l2_m2m_dec.o @@ -357,6 +358,7 @@ OBJS-$(CONFIG_NVENC_HEVC_ENCODER) += nvenc_hevc.o OBJS-$(CONFIG_HEVC_QSV_DECODER) += qsvdec_h2645.o OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc_ps_enc.o \ hevc_data.o +OBJS-$(CONFIG_HEVC_RKMPP_DECODER) += rkmppdec.o OBJS-$(CONFIG_HEVC_VAAPI_ENCODER) += vaapi_encode_h265.o vaapi_encode_h26x.o OBJS-$(CONFIG_HEVC_V4L2M2M_DECODER) += v4l2_m2m_dec.o OBJS-$(CONFIG_HEVC_V4L2M2M_ENCODER) += v4l2_m2m_enc.o @@ -636,6 +638,7 @@ OBJS-$(CONFIG_VP8_DECODER) += vp8.o vp56rac.o OBJS-$(CONFIG_VP8_CUVID_DECODER) += cuvid.o OBJS-$(CONFIG_VP8_MEDIACODEC_DECODER) += mediacodecdec.o OBJS-$(CONFIG_VP8_QSV_DECODER) += qsvdec_other.o +OBJS-$(CONFIG_VP8_RKMPP_DECODER) += rkmppdec.o OBJS-$(CONFIG_VP8_VAAPI_ENCODER) += vaapi_encode_vp8.o OBJS-$(CONFIG_VP8_V4L2M2M_DECODER) += v4l2_m2m_dec.o OBJS-$(CONFIG_VP8_V4L2M2M_ENCODER) += v4l2_m2m_enc.o @@ -644,6 +647,7 @@ OBJS-$(CONFIG_VP9_DECODER) += vp9.o vp9data.o vp9dsp.o vp9lpf.o vp9r vp9dsp_8bpp.o vp9dsp_10bpp.o vp9dsp_12bpp.o OBJS-$(CONFIG_VP9_CUVID_DECODER) += cuvid.o OBJS-$(CONFIG_VP9_MEDIACODEC_DECODER) += mediacodecdec.o +OBJS-$(CONFIG_VP9_RKMPP_DECODER) += rkmppdec.o OBJS-$(CONFIG_VP9_VAAPI_ENCODER) += vaapi_encode_vp9.o OBJS-$(CONFIG_VPLAYER_DECODER) += textdec.o ass.o OBJS-$(CONFIG_VP9_V4L2M2M_DECODER) += v4l2_m2m_dec.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index db2db158f3443..f5ef280313626 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -215,6 +215,7 @@ static void register_all(void) REGISTER_DECODER(H264_MEDIACODEC, h264_mediacodec); REGISTER_DECODER(H264_MMAL, h264_mmal); REGISTER_DECODER(H264_QSV, h264_qsv); + REGISTER_DECODER(H264_RKMPP, h264_rkmpp); REGISTER_DECODER(H264_VDA, h264_vda); #if FF_API_VDPAU REGISTER_DECODER(H264_VDPAU, h264_vdpau); @@ -222,6 +223,7 @@ static void register_all(void) REGISTER_ENCDEC (HAP, hap); REGISTER_DECODER(HEVC, hevc); REGISTER_DECODER(HEVC_QSV, hevc_qsv); + REGISTER_DECODER(HEVC_RKMPP, hevc_rkmpp); REGISTER_ENCDEC (HEVC_V4L2M2M, hevc_v4l2m2m); REGISTER_DECODER(HNM4_VIDEO, hnm4_video); REGISTER_DECODER(HQ_HQA, hq_hqa); @@ -380,8 +382,10 @@ static void register_all(void) REGISTER_DECODER(VP6F, vp6f); REGISTER_DECODER(VP7, vp7); REGISTER_DECODER(VP8, vp8); + REGISTER_DECODER(VP8_RKMPP, vp8_rkmpp); REGISTER_ENCDEC (VP8_V4L2M2M, vp8_v4l2m2m); REGISTER_DECODER(VP9, vp9); + REGISTER_DECODER(VP9_RKMPP, vp9_rkmpp); REGISTER_DECODER(VP9_V4L2M2M, vp9_v4l2m2m); REGISTER_DECODER(VQA, vqa); REGISTER_DECODER(BITPACKED, bitpacked); diff --git a/libavcodec/rkmppdec.c b/libavcodec/rkmppdec.c new file mode 100644 index 0000000000000..ca307c894ecf8 --- /dev/null +++ b/libavcodec/rkmppdec.c @@ -0,0 +1,596 @@ +/* + * RockChip MPP Video Decoder + * Copyright (c) 2017 Lionel CHAZALLON + * + * 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 +#include +#include +#include +#include +#include + +#include "avcodec.h" +#include "decode.h" +#include "internal.h" +#include "libavutil/buffer.h" +#include "libavutil/common.h" +#include "libavutil/frame.h" +#include "libavutil/hwcontext.h" +#include "libavutil/hwcontext_drm.h" +#include "libavutil/imgutils.h" +#include "libavutil/log.h" + +#define RECEIVE_FRAME_TIMEOUT 100 +#define FRAMEGROUP_MAX_FRAMES 16 + +typedef struct { + MppCtx ctx; + MppApi *mpi; + MppBufferGroup frame_group; + + char first_frame; + char first_packet; + char eos_reached; + + AVBufferRef *frames_ref; + AVBufferRef *device_ref; +} RKMPPDecoder; + +typedef struct { + AVClass *av_class; + AVBufferRef *decoder_ref; +} RKMPPDecodeContext; + +typedef struct { + MppFrame frame; + AVBufferRef *decoder_ref; +} RKMPPFrameContext; + +static MppCodingType rkmpp_get_codingtype(AVCodecContext *avctx) +{ + switch (avctx->codec_id) { + case AV_CODEC_ID_H264: return MPP_VIDEO_CodingAVC; + case AV_CODEC_ID_HEVC: return MPP_VIDEO_CodingHEVC; + case AV_CODEC_ID_VP8: return MPP_VIDEO_CodingVP8; + case AV_CODEC_ID_VP9: return MPP_VIDEO_CodingVP9; + default: return MPP_VIDEO_CodingUnused; + } +} + +static uint32_t rkmpp_get_frameformat(MppFrameFormat mppformat) +{ + switch (mppformat) { + case MPP_FMT_YUV420SP: return DRM_FORMAT_NV12; +#ifdef DRM_FORMAT_NV12_10 + case MPP_FMT_YUV420SP_10BIT: return DRM_FORMAT_NV12_10; +#endif + default: return 0; + } +} + +static int rkmpp_write_data(AVCodecContext *avctx, uint8_t *buffer, int size, int64_t pts) +{ + RKMPPDecodeContext *rk_context = avctx->priv_data; + RKMPPDecoder *decoder = (RKMPPDecoder *)rk_context->decoder_ref->data; + int ret; + MppPacket packet; + + // create the MPP packet + ret = mpp_packet_init(&packet, buffer, size); + if (ret != MPP_OK) { + av_log(avctx, AV_LOG_ERROR, "Failed to init MPP packet (code = %d)\n", ret); + return AVERROR_UNKNOWN; + } + + mpp_packet_set_pts(packet, pts); + + if (!buffer) + mpp_packet_set_eos(packet); + + ret = decoder->mpi->decode_put_packet(decoder->ctx, packet); + if (ret != MPP_OK) { + if (ret == MPP_ERR_BUFFER_FULL) { + av_log(avctx, AV_LOG_DEBUG, "Buffer full writing %d bytes to decoder\n", size); + ret = AVERROR(EAGAIN); + } else + ret = AVERROR_UNKNOWN; + } + else + av_log(avctx, AV_LOG_DEBUG, "Wrote %d bytes to decoder\n", size); + + mpp_packet_deinit(&packet); + + return ret; +} + +static int rkmpp_close_decoder(AVCodecContext *avctx) +{ + RKMPPDecodeContext *rk_context = avctx->priv_data; + av_buffer_unref(&rk_context->decoder_ref); + return 0; +} + +static void rkmpp_release_decoder(void *opaque, uint8_t *data) +{ + RKMPPDecoder *decoder = (RKMPPDecoder *)data; + + if (decoder->mpi) { + decoder->mpi->reset(decoder->ctx); + mpp_destroy(decoder->ctx); + decoder->ctx = NULL; + } + + if (decoder->frame_group) { + mpp_buffer_group_put(decoder->frame_group); + decoder->frame_group = NULL; + } + + av_buffer_unref(&decoder->frames_ref); + av_buffer_unref(&decoder->device_ref); + + av_free(decoder); +} + +static int rkmpp_init_decoder(AVCodecContext *avctx) +{ + RKMPPDecodeContext *rk_context = avctx->priv_data; + RKMPPDecoder *decoder = NULL; + MppCodingType codectype = MPP_VIDEO_CodingUnused; + int ret; + RK_S64 paramS64; + RK_S32 paramS32; + + avctx->pix_fmt = AV_PIX_FMT_DRM_PRIME; + + // create a decoder and a ref to it + decoder = av_mallocz(sizeof(RKMPPDecoder)); + if (!decoder) { + ret = AVERROR(ENOMEM); + goto fail; + } + + rk_context->decoder_ref = av_buffer_create((uint8_t *)decoder, sizeof(*decoder), rkmpp_release_decoder, + NULL, AV_BUFFER_FLAG_READONLY); + if (!rk_context->decoder_ref) { + av_free(decoder); + ret = AVERROR(ENOMEM); + goto fail; + } + + av_log(avctx, AV_LOG_DEBUG, "Initializing RKMPP decoder.\n"); + + codectype = rkmpp_get_codingtype(avctx); + if (codectype == MPP_VIDEO_CodingUnused) { + av_log(avctx, AV_LOG_ERROR, "Unknown codec type (%d).\n", avctx->codec_id); + ret = AVERROR_UNKNOWN; + goto fail; + } + + ret = mpp_check_support_format(MPP_CTX_DEC, codectype); + if (ret != MPP_OK) { + av_log(avctx, AV_LOG_ERROR, "Codec type (%d) unsupported by MPP\n", avctx->codec_id); + ret = AVERROR_UNKNOWN; + goto fail; + } + + // Create the MPP context + ret = mpp_create(&decoder->ctx, &decoder->mpi); + if (ret != MPP_OK) { + av_log(avctx, AV_LOG_ERROR, "Failed to create MPP context (code = %d).\n", ret); + ret = AVERROR_UNKNOWN; + goto fail; + } + + // initialize mpp + ret = mpp_init(decoder->ctx, MPP_CTX_DEC, codectype); + if (ret != MPP_OK) { + av_log(avctx, AV_LOG_ERROR, "Failed to initialize MPP context (code = %d).\n", ret); + ret = AVERROR_UNKNOWN; + goto fail; + } + + // make decode calls blocking with a timeout + paramS32 = MPP_POLL_BLOCK; + ret = decoder->mpi->control(decoder->ctx, MPP_SET_OUTPUT_BLOCK, ¶mS32); + if (ret != MPP_OK) { + av_log(avctx, AV_LOG_ERROR, "Failed to set blocking mode on MPI (code = %d).\n", ret); + ret = AVERROR_UNKNOWN; + goto fail; + } + + paramS64 = RECEIVE_FRAME_TIMEOUT; + ret = decoder->mpi->control(decoder->ctx, MPP_SET_OUTPUT_BLOCK_TIMEOUT, ¶mS64); + if (ret != MPP_OK) { + av_log(avctx, AV_LOG_ERROR, "Failed to set block timeout on MPI (code = %d).\n", ret); + ret = AVERROR_UNKNOWN; + goto fail; + } + + ret = mpp_buffer_group_get_internal(&decoder->frame_group, MPP_BUFFER_TYPE_ION); + if (ret) { + av_log(avctx, AV_LOG_ERROR, "Failed to retrieve buffer group (code = %d)\n", ret); + ret = AVERROR_UNKNOWN; + goto fail; + } + + ret = decoder->mpi->control(decoder->ctx, MPP_DEC_SET_EXT_BUF_GROUP, decoder->frame_group); + if (ret) { + av_log(avctx, AV_LOG_ERROR, "Failed to assign buffer group (code = %d)\n", ret); + ret = AVERROR_UNKNOWN; + goto fail; + } + + ret = mpp_buffer_group_limit_config(decoder->frame_group, 0, FRAMEGROUP_MAX_FRAMES); + if (ret) { + av_log(avctx, AV_LOG_ERROR, "Failed to set buffer group limit (code = %d)\n", ret); + ret = AVERROR_UNKNOWN; + goto fail; + } + + decoder->first_packet = 1; + + av_log(avctx, AV_LOG_DEBUG, "RKMPP decoder initialized successfully.\n"); + + decoder->device_ref = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_DRM); + if (!decoder->device_ref) { + ret = AVERROR(ENOMEM); + goto fail; + } + ret = av_hwdevice_ctx_init(decoder->device_ref); + if (ret < 0) + goto fail; + + return 0; + +fail: + av_log(avctx, AV_LOG_ERROR, "Failed to initialize RKMPP decoder.\n"); + rkmpp_close_decoder(avctx); + return ret; +} + +static int rkmpp_send_packet(AVCodecContext *avctx, const AVPacket *avpkt) +{ + RKMPPDecodeContext *rk_context = avctx->priv_data; + RKMPPDecoder *decoder = (RKMPPDecoder *)rk_context->decoder_ref->data; + int ret; + + // handle EOF + if (!avpkt->size) { + av_log(avctx, AV_LOG_DEBUG, "End of stream.\n"); + decoder->eos_reached = 1; + ret = rkmpp_write_data(avctx, NULL, 0, 0); + if (ret) + av_log(avctx, AV_LOG_ERROR, "Failed to send EOS to decoder (code = %d)\n", ret); + return ret; + } + + // on first packet, send extradata + if (decoder->first_packet) { + if (avctx->extradata_size) { + ret = rkmpp_write_data(avctx, avctx->extradata, + avctx->extradata_size, + avpkt->pts); + if (ret) { + av_log(avctx, AV_LOG_ERROR, "Failed to write extradata to decoder (code = %d)\n", ret); + return ret; + } + } + decoder->first_packet = 0; + } + + // now send packet + ret = rkmpp_write_data(avctx, avpkt->data, avpkt->size, avpkt->pts); + if (ret && ret!=AVERROR(EAGAIN)) + av_log(avctx, AV_LOG_ERROR, "Failed to write data to decoder (code = %d)\n", ret); + + return ret; +} + +static void rkmpp_release_frame(void *opaque, uint8_t *data) +{ + AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor *)data; + AVBufferRef *framecontextref = (AVBufferRef *)opaque; + RKMPPFrameContext *framecontext = (RKMPPFrameContext *)framecontextref->data; + + mpp_frame_deinit(&framecontext->frame); + av_buffer_unref(&framecontext->decoder_ref); + av_buffer_unref(&framecontextref); + + av_free(desc); +} + +static int rkmpp_retrieve_frame(AVCodecContext *avctx, AVFrame *frame) +{ + RKMPPDecodeContext *rk_context = avctx->priv_data; + RKMPPDecoder *decoder = (RKMPPDecoder *)rk_context->decoder_ref->data; + RKMPPFrameContext *framecontext = NULL; + AVBufferRef *framecontextref = NULL; + int ret; + MppFrame mppframe = NULL; + MppBuffer buffer = NULL; + AVDRMFrameDescriptor *desc = NULL; + AVDRMLayerDescriptor *layer = NULL; + int retrycount = 0; + int mode; + MppFrameFormat mppformat; + uint32_t drmformat; + + // on start of decoding, MPP can return -1, which is supposed to be expected + // this is due to some internal MPP init which is not completed, that will + // only happen in the first few frames queries, but should not be interpreted + // as an error, Therefore we need to retry a couple times when we get -1 + // in order to let it time to complete it's init, then we sleep a bit between retries. +retry_get_frame: + ret = decoder->mpi->decode_get_frame(decoder->ctx, &mppframe); + if (ret != MPP_OK && ret != MPP_ERR_TIMEOUT && !decoder->first_frame) { + if (retrycount < 5) { + av_log(avctx, AV_LOG_DEBUG, "Failed to get a frame, retrying (code = %d, retrycount = %d)\n", ret, retrycount); + usleep(10000); + retrycount++; + goto retry_get_frame; + } else { + av_log(avctx, AV_LOG_ERROR, "Failed to get a frame from MPP (code = %d)\n", ret); + goto fail; + } + } + + if (mppframe) { + // Check wether we have a special frame or not + if (mpp_frame_get_info_change(mppframe)) { + AVHWFramesContext *hwframes; + + av_log(avctx, AV_LOG_INFO, "Decoder noticed an info change (%dx%d), format=%d\n", + (int)mpp_frame_get_width(mppframe), (int)mpp_frame_get_height(mppframe), + (int)mpp_frame_get_fmt(mppframe)); + + avctx->width = mpp_frame_get_width(mppframe); + avctx->height = mpp_frame_get_height(mppframe); + + decoder->mpi->control(decoder->ctx, MPP_DEC_SET_INFO_CHANGE_READY, NULL); + decoder->first_frame = 1; + + av_buffer_unref(&decoder->frames_ref); + + decoder->frames_ref = av_hwframe_ctx_alloc(decoder->device_ref); + if (!decoder->frames_ref) { + ret = AVERROR(ENOMEM); + goto fail; + } + + mppformat = mpp_frame_get_fmt(mppframe); + drmformat = rkmpp_get_frameformat(mppformat); + + hwframes = (AVHWFramesContext*)decoder->frames_ref->data; + hwframes->format = AV_PIX_FMT_DRM_PRIME; + hwframes->sw_format = drmformat == DRM_FORMAT_NV12 ? AV_PIX_FMT_NV12 : AV_PIX_FMT_NONE; + hwframes->width = avctx->width; + hwframes->height = avctx->height; + ret = av_hwframe_ctx_init(decoder->frames_ref); + if (ret < 0) + goto fail; + + // here decoder is fully initialized, we need to feed it again with data + ret = AVERROR(EAGAIN); + goto fail; + } else if (mpp_frame_get_eos(mppframe)) { + av_log(avctx, AV_LOG_DEBUG, "Received a EOS frame.\n"); + decoder->eos_reached = 1; + ret = AVERROR_EOF; + goto fail; + } else if (mpp_frame_get_discard(mppframe)) { + av_log(avctx, AV_LOG_DEBUG, "Received a discard frame.\n"); + ret = AVERROR(EAGAIN); + goto fail; + } else if (mpp_frame_get_errinfo(mppframe)) { + av_log(avctx, AV_LOG_ERROR, "Received a errinfo frame.\n"); + ret = AVERROR_UNKNOWN; + goto fail; + } + + // here we should have a valid frame + av_log(avctx, AV_LOG_DEBUG, "Received a frame.\n"); + + // setup general frame fields + frame->format = AV_PIX_FMT_DRM_PRIME; + frame->width = mpp_frame_get_width(mppframe); + frame->height = mpp_frame_get_height(mppframe); + frame->pts = mpp_frame_get_pts(mppframe); + frame->color_range = mpp_frame_get_color_range(mppframe); + frame->color_primaries = mpp_frame_get_color_primaries(mppframe); + frame->color_trc = mpp_frame_get_color_trc(mppframe); + frame->colorspace = mpp_frame_get_colorspace(mppframe); + + mode = mpp_frame_get_mode(mppframe); + frame->interlaced_frame = ((mode & MPP_FRAME_FLAG_FIELD_ORDER_MASK) == MPP_FRAME_FLAG_DEINTERLACED); + frame->top_field_first = ((mode & MPP_FRAME_FLAG_FIELD_ORDER_MASK) == MPP_FRAME_FLAG_TOP_FIRST); + + mppformat = mpp_frame_get_fmt(mppframe); + drmformat = rkmpp_get_frameformat(mppformat); + + // now setup the frame buffer info + buffer = mpp_frame_get_buffer(mppframe); + if (buffer) { + desc = av_mallocz(sizeof(AVDRMFrameDescriptor)); + if (!desc) { + ret = AVERROR(ENOMEM); + goto fail; + } + + desc->nb_objects = 1; + desc->objects[0].fd = mpp_buffer_get_fd(buffer); + desc->objects[0].size = mpp_buffer_get_size(buffer); + + desc->nb_layers = 1; + layer = &desc->layers[0]; + layer->format = drmformat; + layer->nb_planes = 2; + + layer->planes[0].object_index = 0; + layer->planes[0].offset = 0; + layer->planes[0].pitch = mpp_frame_get_hor_stride(mppframe); + + layer->planes[1].object_index = 0; + layer->planes[1].offset = layer->planes[0].pitch * mpp_frame_get_ver_stride(mppframe); + layer->planes[1].pitch = layer->planes[0].pitch; + + // we also allocate a struct in buf[0] that will allow to hold additionnal information + // for releasing properly MPP frames and decoder + framecontextref = av_buffer_allocz(sizeof(*framecontext)); + if (!framecontextref) { + ret = AVERROR(ENOMEM); + goto fail; + } + + // MPP decoder needs to be closed only when all frames have been released. + framecontext = (RKMPPFrameContext *)framecontextref->data; + framecontext->decoder_ref = av_buffer_ref(rk_context->decoder_ref); + framecontext->frame = mppframe; + + frame->data[0] = (uint8_t *)desc; + frame->buf[0] = av_buffer_create((uint8_t *)desc, sizeof(*desc), rkmpp_release_frame, + framecontextref, AV_BUFFER_FLAG_READONLY); + + if (!frame->buf[0]) { + ret = AVERROR(ENOMEM); + goto fail; + } + + frame->hw_frames_ctx = av_buffer_ref(decoder->frames_ref); + if (!frame->hw_frames_ctx) { + ret = AVERROR(ENOMEM); + goto fail; + } + + decoder->first_frame = 0; + return 0; + } else { + av_log(avctx, AV_LOG_ERROR, "Failed to retrieve the frame buffer, frame is dropped (code = %d)\n", ret); + mpp_frame_deinit(&mppframe); + } + } else if (decoder->eos_reached) { + return AVERROR_EOF; + } else if (ret == MPP_ERR_TIMEOUT) { + av_log(avctx, AV_LOG_DEBUG, "Timeout when trying to get a frame from MPP\n"); + } + + return AVERROR(EAGAIN); + +fail: + if (mppframe) + mpp_frame_deinit(&mppframe); + + if (framecontext) + av_buffer_unref(&framecontext->decoder_ref); + + if (framecontextref) + av_buffer_unref(&framecontextref); + + if (desc) + av_free(desc); + + return ret; +} + +static int rkmpp_receive_frame(AVCodecContext *avctx, AVFrame *frame) +{ + RKMPPDecodeContext *rk_context = avctx->priv_data; + RKMPPDecoder *decoder = (RKMPPDecoder *)rk_context->decoder_ref->data; + int ret = MPP_NOK; + AVPacket pkt = {0}; + RK_S32 freeslots; + + if (!decoder->eos_reached) { + // we get the available slots in decoder + ret = decoder->mpi->control(decoder->ctx, MPP_DEC_GET_FREE_PACKET_SLOT_COUNT, &freeslots); + if (ret != MPP_OK) { + av_log(avctx, AV_LOG_ERROR, "Failed to get decoder free slots (code = %d).\n", ret); + return ret; + } + + if (freeslots > 0) { + ret = ff_decode_get_packet(avctx, &pkt); + if (ret < 0 && ret != AVERROR_EOF) { + return ret; + } + + ret = rkmpp_send_packet(avctx, &pkt); + av_packet_unref(&pkt); + + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to send packet to decoder (code = %d)\n", ret); + return ret; + } + } + + // make sure we keep decoder full + if (freeslots > 1 && decoder->first_frame) + return AVERROR(EAGAIN); + } + + return rkmpp_retrieve_frame(avctx, frame); +} + +static void rkmpp_flush(AVCodecContext *avctx) +{ + RKMPPDecodeContext *rk_context = avctx->priv_data; + RKMPPDecoder *decoder = (RKMPPDecoder *)rk_context->decoder_ref->data; + int ret = MPP_NOK; + + av_log(avctx, AV_LOG_DEBUG, "Flush.\n"); + + ret = decoder->mpi->reset(decoder->ctx); + if (ret == MPP_OK) { + decoder->first_frame = 1; + decoder->first_packet = 1; + } else + av_log(avctx, AV_LOG_ERROR, "Failed to reset MPI (code = %d)\n", ret); +} + + +#define RKMPP_DEC_CLASS(NAME) \ + static const AVClass rkmpp_##NAME##_dec_class = { \ + .class_name = "rkmpp_" #NAME "_dec", \ + .version = LIBAVUTIL_VERSION_INT, \ + }; + +#define RKMPP_DEC(NAME, ID, BSFS) \ + RKMPP_DEC_CLASS(NAME) \ + AVCodec ff_##NAME##_rkmpp_decoder = { \ + .name = #NAME "_rkmpp", \ + .long_name = NULL_IF_CONFIG_SMALL(#NAME " (rkmpp)"), \ + .type = AVMEDIA_TYPE_VIDEO, \ + .id = ID, \ + .priv_data_size = sizeof(RKMPPDecodeContext), \ + .init = rkmpp_init_decoder, \ + .close = rkmpp_close_decoder, \ + .receive_frame = rkmpp_receive_frame, \ + .flush = rkmpp_flush, \ + .priv_class = &rkmpp_##NAME##_dec_class, \ + .capabilities = AV_CODEC_CAP_DELAY, \ + .caps_internal = AV_CODEC_CAP_AVOID_PROBING, \ + .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_DRM_PRIME, \ + AV_PIX_FMT_NONE}, \ + .bsfs = BSFS, \ + }; + +RKMPP_DEC(h264, AV_CODEC_ID_H264, "h264_mp4toannexb") +RKMPP_DEC(hevc, AV_CODEC_ID_HEVC, "hevc_mp4toannexb") +RKMPP_DEC(vp8, AV_CODEC_ID_VP8, NULL) +RKMPP_DEC(vp9, AV_CODEC_ID_VP9, NULL) diff --git a/libavcodec/version.h b/libavcodec/version.h index 3008460b93e52..39d9ad992ca22 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 106 -#define LIBAVCODEC_VERSION_MICRO 102 +#define LIBAVCODEC_VERSION_MICRO 103 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From da53c424b96f57d7471767d99072d35efe15a8e0 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Wed, 27 Sep 2017 23:06:49 +0100 Subject: [PATCH 3192/3374] lavc/v4l2: Add missing header include Fixes checkheaders. --- libavcodec/v4l2_buffers.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/v4l2_buffers.h b/libavcodec/v4l2_buffers.h index 5d25a87750941..b16f694b98c08 100644 --- a/libavcodec/v4l2_buffers.h +++ b/libavcodec/v4l2_buffers.h @@ -26,6 +26,8 @@ #include +#include "avcodec.h" + enum V4L2Buffer_status { V4L2BUF_AVAILABLE, V4L2BUF_IN_DRIVER, From c1f22c29593048ce2c457f8c592627234503bd4b Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Wed, 27 Sep 2017 23:34:06 +0100 Subject: [PATCH 3193/3374] lavc: Move V4L2 encoders lower in the list Their previous positioning would cause them to chosen before software encoders like libx264 or libvpx. --- libavcodec/allcodecs.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index f5ef280313626..7ae9e8cea1c9e 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -208,10 +208,10 @@ static void register_all(void) REGISTER_ENCDEC (H263, h263); REGISTER_DECODER(H263I, h263i); REGISTER_ENCDEC (H263P, h263p); - REGISTER_ENCDEC (H263_V4L2M2M, h263_v4l2m2m); + REGISTER_DECODER(H263_V4L2M2M, h263_v4l2m2m); REGISTER_DECODER(H264, h264); REGISTER_DECODER(H264_CRYSTALHD, h264_crystalhd); - REGISTER_ENCDEC (H264_V4L2M2M, h264_v4l2m2m); + REGISTER_DECODER(H264_V4L2M2M, h264_v4l2m2m); REGISTER_DECODER(H264_MEDIACODEC, h264_mediacodec); REGISTER_DECODER(H264_MMAL, h264_mmal); REGISTER_DECODER(H264_QSV, h264_qsv); @@ -224,7 +224,7 @@ static void register_all(void) REGISTER_DECODER(HEVC, hevc); REGISTER_DECODER(HEVC_QSV, hevc_qsv); REGISTER_DECODER(HEVC_RKMPP, hevc_rkmpp); - REGISTER_ENCDEC (HEVC_V4L2M2M, hevc_v4l2m2m); + REGISTER_DECODER(HEVC_V4L2M2M, hevc_v4l2m2m); REGISTER_DECODER(HNM4_VIDEO, hnm4_video); REGISTER_DECODER(HQ_HQA, hq_hqa); REGISTER_DECODER(HQX, hqx); @@ -259,7 +259,7 @@ static void register_all(void) REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video); REGISTER_ENCDEC (MPEG4, mpeg4); REGISTER_DECODER(MPEG4_CRYSTALHD, mpeg4_crystalhd); - REGISTER_ENCDEC (MPEG4_V4L2M2M, mpeg4_v4l2m2m); + REGISTER_DECODER(MPEG4_V4L2M2M, mpeg4_v4l2m2m); REGISTER_DECODER(MPEG4_MMAL, mpeg4_mmal); #if FF_API_VDPAU REGISTER_DECODER(MPEG4_VDPAU, mpeg4_vdpau); @@ -383,7 +383,7 @@ static void register_all(void) REGISTER_DECODER(VP7, vp7); REGISTER_DECODER(VP8, vp8); REGISTER_DECODER(VP8_RKMPP, vp8_rkmpp); - REGISTER_ENCDEC (VP8_V4L2M2M, vp8_v4l2m2m); + REGISTER_DECODER(VP8_V4L2M2M, vp8_v4l2m2m); REGISTER_DECODER(VP9, vp9); REGISTER_DECODER(VP9_RKMPP, vp9_rkmpp); REGISTER_DECODER(VP9_V4L2M2M, vp9_v4l2m2m); @@ -668,11 +668,13 @@ static void register_all(void) /* external libraries, that shouldn't be used by default if one of the * above is available */ + REGISTER_ENCODER(H263_V4L2M2M, h263_v4l2m2m); REGISTER_ENCDEC (LIBOPENH264, libopenh264); REGISTER_DECODER(H264_CUVID, h264_cuvid); REGISTER_ENCODER(H264_NVENC, h264_nvenc); REGISTER_ENCODER(H264_OMX, h264_omx); REGISTER_ENCODER(H264_QSV, h264_qsv); + REGISTER_ENCODER(H264_V4L2M2M, h264_v4l2m2m); REGISTER_ENCODER(H264_VAAPI, h264_vaapi); REGISTER_ENCODER(H264_VIDEOTOOLBOX, h264_videotoolbox); #if FF_API_NVENC_OLD_NAME @@ -684,6 +686,7 @@ static void register_all(void) REGISTER_DECODER(HEVC_MEDIACODEC, hevc_mediacodec); REGISTER_ENCODER(HEVC_NVENC, hevc_nvenc); REGISTER_ENCODER(HEVC_QSV, hevc_qsv); + REGISTER_ENCODER(HEVC_V4L2M2M, hevc_v4l2m2m); REGISTER_ENCODER(HEVC_VAAPI, hevc_vaapi); REGISTER_ENCODER(LIBKVAZAAR, libkvazaar); REGISTER_DECODER(MJPEG_CUVID, mjpeg_cuvid); @@ -694,10 +697,12 @@ static void register_all(void) REGISTER_ENCODER(MPEG2_VAAPI, mpeg2_vaapi); REGISTER_DECODER(MPEG4_CUVID, mpeg4_cuvid); REGISTER_DECODER(MPEG4_MEDIACODEC, mpeg4_mediacodec); + REGISTER_ENCODER(MPEG4_V4L2M2M, mpeg4_v4l2m2m); REGISTER_DECODER(VC1_CUVID, vc1_cuvid); REGISTER_DECODER(VP8_CUVID, vp8_cuvid); REGISTER_DECODER(VP8_MEDIACODEC, vp8_mediacodec); REGISTER_DECODER(VP8_QSV, vp8_qsv); + REGISTER_ENCODER(VP8_V4L2M2M, vp8_v4l2m2m); REGISTER_ENCODER(VP8_VAAPI, vp8_vaapi); REGISTER_DECODER(VP9_CUVID, vp9_cuvid); REGISTER_DECODER(VP9_MEDIACODEC, vp9_mediacodec); From 3b345d389be2d67017f904caa21713f53a8e8c90 Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 27 Sep 2017 23:10:09 -0300 Subject: [PATCH 3194/3374] avutil/cpu: split flag checks per arch in av_cpu_max_align() Signed-off-by: James Almer --- libavutil/aarch64/cpu.c | 10 ++++++++++ libavutil/arm/cpu.c | 10 ++++++++++ libavutil/cpu.c | 39 ++++++++------------------------------- libavutil/cpu_internal.h | 5 +++++ libavutil/ppc/cpu.c | 12 ++++++++++++ libavutil/x86/cpu.c | 27 +++++++++++++++++++++++++++ 6 files changed, 72 insertions(+), 31 deletions(-) diff --git a/libavutil/aarch64/cpu.c b/libavutil/aarch64/cpu.c index 8ef077aaea355..cc641da576ad1 100644 --- a/libavutil/aarch64/cpu.c +++ b/libavutil/aarch64/cpu.c @@ -26,3 +26,13 @@ int ff_get_cpu_flags_aarch64(void) AV_CPU_FLAG_NEON * HAVE_NEON | AV_CPU_FLAG_VFP * HAVE_VFP; } + +size_t ff_get_cpu_max_align_aarch64(void) +{ + int flags = av_get_cpu_flags(); + + if (flags & AV_CPU_FLAG_NEON) + return 16; + + return 8; +} diff --git a/libavutil/arm/cpu.c b/libavutil/arm/cpu.c index 3889ef011caa8..81e85e2525571 100644 --- a/libavutil/arm/cpu.c +++ b/libavutil/arm/cpu.c @@ -158,3 +158,13 @@ int ff_get_cpu_flags_arm(void) } #endif + +size_t ff_get_cpu_max_align_arm(void) +{ + int flags = av_get_cpu_flags(); + + if (flags & AV_CPU_FLAG_NEON) + return 16; + + return 8; +} diff --git a/libavutil/cpu.c b/libavutil/cpu.c index ab04494acf5e0..c8401b825809b 100644 --- a/libavutil/cpu.c +++ b/libavutil/cpu.c @@ -304,37 +304,14 @@ int av_cpu_count(void) size_t av_cpu_max_align(void) { - int av_unused flags = av_get_cpu_flags(); - -#if ARCH_ARM || ARCH_AARCH64 - if (flags & AV_CPU_FLAG_NEON) - return 16; -#elif ARCH_PPC - if (flags & (AV_CPU_FLAG_ALTIVEC | - AV_CPU_FLAG_VSX | - AV_CPU_FLAG_POWER8)) - return 16; -#elif ARCH_X86 - if (flags & (AV_CPU_FLAG_AVX2 | - AV_CPU_FLAG_AVX | - AV_CPU_FLAG_XOP | - AV_CPU_FLAG_FMA4 | - AV_CPU_FLAG_FMA3 | - AV_CPU_FLAG_AVXSLOW)) - return 32; - if (flags & (AV_CPU_FLAG_AESNI | - AV_CPU_FLAG_SSE42 | - AV_CPU_FLAG_SSE4 | - AV_CPU_FLAG_SSSE3 | - AV_CPU_FLAG_SSE3 | - AV_CPU_FLAG_SSE2 | - AV_CPU_FLAG_SSE | - AV_CPU_FLAG_ATOM | - AV_CPU_FLAG_SSSE3SLOW | - AV_CPU_FLAG_SSE3SLOW | - AV_CPU_FLAG_SSE2SLOW)) - return 16; -#endif + if (ARCH_AARCH64) + return ff_get_cpu_max_align_aarch64(); + if (ARCH_ARM) + return ff_get_cpu_max_align_arm(); + if (ARCH_PPC) + return ff_get_cpu_max_align_ppc(); + if (ARCH_X86) + return ff_get_cpu_max_align_x86(); return 8; } diff --git a/libavutil/cpu_internal.h b/libavutil/cpu_internal.h index 6c352abe1b675..b8bf1e5396482 100644 --- a/libavutil/cpu_internal.h +++ b/libavutil/cpu_internal.h @@ -44,4 +44,9 @@ int ff_get_cpu_flags_arm(void); int ff_get_cpu_flags_ppc(void); int ff_get_cpu_flags_x86(void); +size_t ff_get_cpu_max_align_aarch64(void); +size_t ff_get_cpu_max_align_arm(void); +size_t ff_get_cpu_max_align_ppc(void); +size_t ff_get_cpu_max_align_x86(void); + #endif /* AVUTIL_CPU_INTERNAL_H */ diff --git a/libavutil/ppc/cpu.c b/libavutil/ppc/cpu.c index 0f1e982624546..7bb7cd813c978 100644 --- a/libavutil/ppc/cpu.c +++ b/libavutil/ppc/cpu.c @@ -148,3 +148,15 @@ int ff_get_cpu_flags_ppc(void) #endif /* HAVE_ALTIVEC */ return 0; } + +size_t ff_get_cpu_max_align_ppc(void) +{ + int flags = av_get_cpu_flags(); + + if (flags & (AV_CPU_FLAG_ALTIVEC | + AV_CPU_FLAG_VSX | + AV_CPU_FLAG_POWER8)) + return 16; + + return 8; +} diff --git a/libavutil/x86/cpu.c b/libavutil/x86/cpu.c index 3800a11ad89d9..f33088c8c7385 100644 --- a/libavutil/x86/cpu.c +++ b/libavutil/x86/cpu.c @@ -233,3 +233,30 @@ int ff_get_cpu_flags_x86(void) return rval; } + +size_t ff_get_cpu_max_align_x86(void) +{ + int flags = av_get_cpu_flags(); + + if (flags & (AV_CPU_FLAG_AVX2 | + AV_CPU_FLAG_AVX | + AV_CPU_FLAG_XOP | + AV_CPU_FLAG_FMA4 | + AV_CPU_FLAG_FMA3 | + AV_CPU_FLAG_AVXSLOW)) + return 32; + if (flags & (AV_CPU_FLAG_AESNI | + AV_CPU_FLAG_SSE42 | + AV_CPU_FLAG_SSE4 | + AV_CPU_FLAG_SSSE3 | + AV_CPU_FLAG_SSE3 | + AV_CPU_FLAG_SSE2 | + AV_CPU_FLAG_SSE | + AV_CPU_FLAG_ATOM | + AV_CPU_FLAG_SSSE3SLOW | + AV_CPU_FLAG_SSE3SLOW | + AV_CPU_FLAG_SSE2SLOW)) + return 16; + + return 8; +} From 774295a3e01a52e20df5b34b56d54f5ff4f0746a Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 27 Sep 2017 23:57:30 -0300 Subject: [PATCH 3195/3374] doc/libav-merge: mention skipped or incomplete runtime alignment commits Signed-off-by: James Almer --- doc/libav-merge.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/libav-merge.txt b/doc/libav-merge.txt index 96b008b71b208..4a46bfcf464a8 100644 --- a/doc/libav-merge.txt +++ b/doc/libav-merge.txt @@ -98,6 +98,9 @@ Stuff that didn't reach the codebase: - Removal of the custom atomic API (5cc0057f49, see http://ffmpeg.org/pipermail/ffmpeg-devel/2017-March/209003.html) - new bitstream reader (see http://ffmpeg.org/pipermail/ffmpeg-devel/2017-April/209609.html) - use of the bsf instead of our parser for vp9 superframes (see fa1749dd34) +- use av_cpu_max_align() instead of hardcoding alignment requirements (see https://ffmpeg.org/pipermail/ffmpeg-devel/2017-September/215834.html) + - f44ec22e0 lavc: use av_cpu_max_align() instead of hardcoding alignment requirements + - 4de220d2e frame: allow align=0 (meaning automatic) for av_frame_get_buffer() Collateral damage that needs work locally: ------------------------------------------ From 93dfc4f174d89ad4c9a76fb542ddfed138e4f01b Mon Sep 17 00:00:00 2001 From: James Almer Date: Thu, 28 Sep 2017 00:49:05 -0300 Subject: [PATCH 3196/3374] avcodec/libopenh264dec: check for ff_set_dimensions() return value Was removed by accident in e9b6212de29a966f200833220ed35f51852f05f6. Signed-off-by: James Almer --- libavcodec/libopenh264dec.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/libopenh264dec.c b/libavcodec/libopenh264dec.c index 4a27a5a0a603e..d12e7151172a0 100644 --- a/libavcodec/libopenh264dec.c +++ b/libavcodec/libopenh264dec.c @@ -92,7 +92,7 @@ static int svc_decode_frame(AVCodecContext *avctx, void *data, SVCContext *s = avctx->priv_data; SBufferInfo info = { 0 }; uint8_t* ptrs[3]; - int linesize[3]; + int ret, linesize[3]; AVFrame *avframe = data; DECODING_STATE state; @@ -106,7 +106,9 @@ static int svc_decode_frame(AVCodecContext *avctx, void *data, return avpkt->size; } - ff_set_dimensions(avctx, info.UsrData.sSystemBuffer.iWidth, info.UsrData.sSystemBuffer.iHeight); + ret = ff_set_dimensions(avctx, info.UsrData.sSystemBuffer.iWidth, info.UsrData.sSystemBuffer.iHeight); + if (ret < 0) + return ret; // The decoder doesn't (currently) support decoding into a user // provided buffer, so do a copy instead. if (ff_get_buffer(avctx, avframe, 0) < 0) { From 07e4be7ec94cbd8e674a260c939054f018d337eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 26 Sep 2017 02:55:30 +0300 Subject: [PATCH 3197/3374] movenc: Add an option for enabling negative CTS offsets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reduces the need for an edit list; streams that start with e.g. dts=-1, pts=0 can be encoded as dts=0, pts=0 (which is valid in mov/mp4) by shifting the dts values of all packets forward. This avoids the need for edit lists for such streams (while they still are needed for audio streams with encoder delay). This eases conformance with the DASH-IF interoperability guidelines. Signed-off-by: Martin Storsjö Signed-off-by: Michael Niedermayer --- doc/muxers.texi | 6 ++++++ libavformat/movenc.c | 28 ++++++++++++++++++++++++---- libavformat/movenc.h | 2 ++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index 38d93919e7685..91bbe673c53f7 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -1117,6 +1117,12 @@ on the implicit end of the previous track fragment). @item -write_tmcd Specify @code{on} to force writing a timecode track, @code{off} to disable it and @code{auto} to write a timecode track only for mov and mp4 output (default). +@item -movflags negative_cts_offsets +Enables utilization of version 1 of the CTTS box, in which the CTS offsets can +be negative. This enables the initial sample to have DTS/CTS of zero, and +reduces the need for edit lists for some cases such as video tracks with +B-frames. Additionally, eases conformance with the DASH-IF interoperability +guidelines. @end table @subsection Example diff --git a/libavformat/movenc.c b/libavformat/movenc.c index ba3e263f9f3e8..9c3e6437d72e4 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -77,6 +77,7 @@ static const AVOption options[] = { { "write_gama", "Write deprecated gama atom", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_WRITE_GAMA}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, { "use_metadata_tags", "Use mdta atom for metadata.", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_USE_MDTA}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, { "skip_trailer", "Skip writing the mfra/tfra/mfro trailer for fragmented files", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_SKIP_TRAILER}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, + { "negative_cts_offsets", "Use negative CTS offsets (reducing the need for edit lists)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags), { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM}, { "iods_audio_profile", "iods audio profile atom.", offsetof(MOVMuxContext, iods_audio_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM}, @@ -2095,8 +2096,9 @@ static int mov_write_stsd_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext return update_size(pb, pos); } -static int mov_write_ctts_tag(AVIOContext *pb, MOVTrack *track) +static int mov_write_ctts_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track) { + MOVMuxContext *mov = s->priv_data; MOVStts *ctts_entries; uint32_t entries = 0; uint32_t atom_size; @@ -2120,7 +2122,11 @@ static int mov_write_ctts_tag(AVIOContext *pb, MOVTrack *track) atom_size = 16 + (entries * 8); avio_wb32(pb, atom_size); /* size */ ffio_wfourcc(pb, "ctts"); - avio_wb32(pb, 0); /* version & flags */ + if (mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS) + avio_w8(pb, 1); /* version */ + else + avio_w8(pb, 0); /* version */ + avio_wb24(pb, 0); /* flags */ avio_wb32(pb, entries); /* entry count */ for (i = 0; i < entries; i++) { avio_wb32(pb, ctts_entries[i].count); @@ -2304,7 +2310,7 @@ static int mov_write_stbl_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && track->flags & MOV_TRACK_CTTS && track->entry) { - if ((ret = mov_write_ctts_tag(pb, track)) < 0) + if ((ret = mov_write_ctts_tag(s, pb, track)) < 0) return ret; } mov_write_stsc_tag(pb, track); @@ -4045,7 +4051,10 @@ static int mov_write_trun_tag(AVIOContext *pb, MOVMuxContext *mov, avio_wb32(pb, 0); /* size placeholder */ ffio_wfourcc(pb, "trun"); - avio_w8(pb, 0); /* version */ + if (mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS) + avio_w8(pb, 1); /* version */ + else + avio_w8(pb, 0); /* version */ avio_wb24(pb, flags); avio_wb32(pb, end - first); /* sample count */ @@ -4490,6 +4499,8 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s) ffio_wfourcc(pb, "MSNV"); else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF) ffio_wfourcc(pb, "iso5"); // Required when using default-base-is-moof + else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS) + ffio_wfourcc(pb, "iso4"); else if (mov->mode == MODE_MP4) ffio_wfourcc(pb, "isom"); else if (mov->mode == MODE_IPOD) @@ -4760,6 +4771,8 @@ static int mov_flush_fragment(AVFormatContext *s, int force) if (!track->end_reliable) { AVPacket pkt; if (!ff_interleaved_peek(s, i, &pkt, 1)) { + if (track->dts_shift != AV_NOPTS_VALUE) + pkt.dts += track->dts_shift; track->track_duration = pkt.dts - track->start_dts; if (pkt.pts != AV_NOPTS_VALUE) track->end_pts = pkt.pts; @@ -5283,6 +5296,12 @@ static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt) mov->flags &= ~FF_MOV_FLAG_FRAG_DISCONT; } + if (mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS) { + if (trk->dts_shift == AV_NOPTS_VALUE) + trk->dts_shift = pkt->pts - pkt->dts; + pkt->dts += trk->dts_shift; + } + if (trk->par->codec_id == AV_CODEC_ID_MP4ALS || trk->par->codec_id == AV_CODEC_ID_AAC || trk->par->codec_id == AV_CODEC_ID_FLAC) { @@ -5923,6 +5942,7 @@ static int mov_init(AVFormatContext *s) track->start_dts = AV_NOPTS_VALUE; track->start_cts = AV_NOPTS_VALUE; track->end_pts = AV_NOPTS_VALUE; + track->dts_shift = AV_NOPTS_VALUE; if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') || track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') || diff --git a/libavformat/movenc.h b/libavformat/movenc.h index 4c4f3cdfc3f85..cc2a155d79aa4 100644 --- a/libavformat/movenc.h +++ b/libavformat/movenc.h @@ -116,6 +116,7 @@ typedef struct MOVTrack { int64_t start_cts; int64_t end_pts; int end_reliable; + int64_t dts_shift; int hint_track; ///< the track that hints this track, -1 if no hint track is set int src_track; ///< the track that this hint (or tmcd) track describes @@ -241,6 +242,7 @@ typedef struct MOVMuxContext { #define FF_MOV_FLAG_WRITE_GAMA (1 << 16) #define FF_MOV_FLAG_USE_MDTA (1 << 17) #define FF_MOV_FLAG_SKIP_TRAILER (1 << 18) +#define FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS (1 << 19) int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt); From 5455a44aa5077bcd33485f424e055807afcefeb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 23 Sep 2017 18:44:45 +0300 Subject: [PATCH 3198/3374] movenc-test: Add tests for negative cts offsets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö Signed-off-by: Michael Niedermayer --- libavformat/tests/movenc.c | 19 +++++++++++++++++++ tests/ref/fate/movenc | 11 +++++++++++ 2 files changed, 30 insertions(+) diff --git a/libavformat/tests/movenc.c b/libavformat/tests/movenc.c index 7a66395efd286..8e59b74259e92 100644 --- a/libavformat/tests/movenc.c +++ b/libavformat/tests/movenc.c @@ -766,6 +766,25 @@ int main(int argc, char **argv) clear_duration = 0; do_interleave = 0; + // Write a fragmented file with b-frames and audio preroll, + // with negative cts values, removing the edit list for the + // video track. + init_out("delay-moov-elst-neg-cts"); + av_dict_set(&opts, "movflags", "frag_keyframe+delay_moov+negative_cts_offsets", 0); + init(1, 1); + mux_gops(2); + finish(); + close_out(); + + // Write a fragmented file with b-frames without audio preroll, + // with negative cts values, avoiding any edit lists, allowing + // to use empty_moov instead of delay_moov. + init_out("empty-moov-neg-cts"); + av_dict_set(&opts, "movflags", "frag_keyframe+empty_moov+negative_cts_offsets", 0); + init(1, 0); + mux_gops(2); + finish(); + close_out(); av_free(md5); diff --git a/tests/ref/fate/movenc b/tests/ref/fate/movenc index 47bcf9d515c71..872796ebce66e 100644 --- a/tests/ref/fate/movenc +++ b/tests/ref/fate/movenc @@ -140,3 +140,14 @@ write_data len 668, time 1566667, type sync atom moof write_data len 440, time 2233333, type boundary atom moof write_data len 262, time nopts, type trailer atom - edd19deae2b70afcf2cd744b89b7013d 4209 vfr-noduration-interleave +write_data len 1231, time nopts, type header atom ftyp +write_data len 916, time 0, type sync atom moof +write_data len 908, time 1000000, type sync atom moof +write_data len 148, time nopts, type trailer atom - +781dbfd228f36903178e29faa727d78b 3203 delay-moov-elst-neg-cts +write_data len 36, time nopts, type header atom ftyp +write_data len 1123, time nopts, type header atom - +write_data len 1188, time 0, type sync atom moof +write_data len 908, time 1033333, type sync atom moof +write_data len 148, time nopts, type trailer atom - +7630fdf358e02c79e88f312f82a260b7 3403 empty-moov-neg-cts From cb8b729180cc3ccb85f6c0d2fa7190865cbc2cb7 Mon Sep 17 00:00:00 2001 From: Gildas Fargeas Date: Thu, 7 Sep 2017 14:46:31 +0200 Subject: [PATCH 3199/3374] avdevice/decklink_dec: add support for more pixel formats The decklink input pixel format can now be specified with the 'raw_format' option. The -bm_v210 option is now deprecated. Signed-off-by: Marton Balint --- doc/indevs.texi | 22 ++++++++++++++-- libavdevice/decklink_common.cpp | 2 +- libavdevice/decklink_common_c.h | 1 + libavdevice/decklink_dec.cpp | 46 ++++++++++++++++++++++++++++----- libavdevice/decklink_dec_c.c | 6 +++++ libavdevice/version.h | 2 +- 6 files changed, 68 insertions(+), 11 deletions(-) diff --git a/doc/indevs.texi b/doc/indevs.texi index 776e5631602d4..c6f96c41ea7d3 100644 --- a/doc/indevs.texi +++ b/doc/indevs.texi @@ -214,8 +214,9 @@ need to configure with the appropriate @code{--extra-cflags} and @code{--extra-ldflags}. On Windows, you need to run the IDL files through @command{widl}. -DeckLink is very picky about the formats it supports. Pixel format is -uyvy422 or v210, framerate and video size must be determined for your device with +DeckLink is very picky about the formats it supports. Pixel format of the +input can be set with @option{raw_format}. +Framerate and video size must be determined for your device with @command{-list_formats 1}. Audio sample rate is always 48 kHz and the number of channels can be 2, 8 or 16. Note that all audio channels are bundled in one single audio track. @@ -239,9 +240,26 @@ Note that there is a FourCC @option{'pal '} that can also be used as @option{pal} (3 letters). @item bm_v210 +This is a deprecated option, you can use @option{raw_format} instead. If set to @samp{1}, video is captured in 10 bit v210 instead of uyvy422. Not all Blackmagic devices support this option. +@item raw_format +Set the pixel format of the captured video. +Available values are: +@table @samp +@item uyvy422 + +@item yuv422p10 + +@item argb + +@item bgra + +@item rgb10 + +@end table + @item teletext_lines If set to nonzero, an additional teletext stream will be captured from the vertical ancillary data. Both SD PAL (576i) and HD (1080i or 1080p) diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp index cbb591ce64d99..ff2df959095e6 100644 --- a/libavdevice/decklink_common.cpp +++ b/libavdevice/decklink_common.cpp @@ -241,7 +241,7 @@ int ff_decklink_set_format(AVFormatContext *avctx, if (ctx->bmd_mode == bmdModeUnknown) return -1; if (direction == DIRECTION_IN) { - if (ctx->dli->DoesSupportVideoMode(ctx->bmd_mode, bmdFormat8BitYUV, + if (ctx->dli->DoesSupportVideoMode(ctx->bmd_mode, (BMDPixelFormat) cctx->raw_format, bmdVideoOutputFlagDefault, &support, NULL) != S_OK) return -1; diff --git a/libavdevice/decklink_common_c.h b/libavdevice/decklink_common_c.h index e263480474cb9..5616ab32f9cc6 100644 --- a/libavdevice/decklink_common_c.h +++ b/libavdevice/decklink_common_c.h @@ -49,6 +49,7 @@ struct decklink_cctx { int video_input; int draw_bars; char *format_code; + int raw_format; int64_t queue_size; }; diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index c271ff3639157..c93ca68b8066c 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -651,6 +651,11 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) return AVERROR_EXIT; } + if (cctx->v210) { + av_log(avctx, AV_LOG_WARNING, "The bm_v210 option is deprecated and will be removed. Please use the -raw_format yuv422p10.\n"); + cctx->raw_format = MKBETAG('v','2','1','0'); + } + strcpy (fname, avctx->filename); tmp=strchr (fname, '@'); if (tmp != NULL) { @@ -723,15 +728,42 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) st->time_base.num = ctx->bmd_tb_num; av_stream_set_r_frame_rate(st, av_make_q(st->time_base.den, st->time_base.num)); - if (cctx->v210) { - st->codecpar->codec_id = AV_CODEC_ID_V210; - st->codecpar->codec_tag = MKTAG('V', '2', '1', '0'); - st->codecpar->bit_rate = av_rescale(ctx->bmd_width * ctx->bmd_height * 64, st->time_base.den, st->time_base.num * 3); - } else { + switch((BMDPixelFormat)cctx->raw_format) { + case bmdFormat8BitYUV: st->codecpar->codec_id = AV_CODEC_ID_RAWVIDEO; - st->codecpar->format = AV_PIX_FMT_UYVY422; st->codecpar->codec_tag = MKTAG('U', 'Y', 'V', 'Y'); + st->codecpar->format = AV_PIX_FMT_UYVY422; st->codecpar->bit_rate = av_rescale(ctx->bmd_width * ctx->bmd_height * 16, st->time_base.den, st->time_base.num); + break; + case bmdFormat10BitYUV: + st->codecpar->codec_id = AV_CODEC_ID_V210; + st->codecpar->codec_tag = MKTAG('V','2','1','0'); + st->codecpar->bit_rate = av_rescale(ctx->bmd_width * ctx->bmd_height * 64, st->time_base.den, st->time_base.num * 3); + st->codecpar->bits_per_coded_sample = 10; + break; + case bmdFormat8BitARGB: + st->codecpar->codec_id = AV_CODEC_ID_RAWVIDEO; + st->codecpar->codec_tag = avcodec_pix_fmt_to_codec_tag((enum AVPixelFormat)st->codecpar->format);; + st->codecpar->format = AV_PIX_FMT_ARGB; + st->codecpar->bit_rate = av_rescale(ctx->bmd_width * ctx->bmd_height * 32, st->time_base.den, st->time_base.num); + break; + case bmdFormat8BitBGRA: + st->codecpar->codec_id = AV_CODEC_ID_RAWVIDEO; + st->codecpar->codec_tag = avcodec_pix_fmt_to_codec_tag((enum AVPixelFormat)st->codecpar->format); + st->codecpar->format = AV_PIX_FMT_BGRA; + st->codecpar->bit_rate = av_rescale(ctx->bmd_width * ctx->bmd_height * 32, st->time_base.den, st->time_base.num); + break; + case bmdFormat10BitRGB: + st->codecpar->codec_id = AV_CODEC_ID_R210; + st->codecpar->codec_tag = MKTAG('R','2','1','0'); + st->codecpar->format = AV_PIX_FMT_RGB48LE; + st->codecpar->bit_rate = av_rescale(ctx->bmd_width * ctx->bmd_height * 30, st->time_base.den, st->time_base.num); + st->codecpar->bits_per_coded_sample = 10; + break; + default: + av_log(avctx, AV_LOG_ERROR, "Raw Format %.4s not supported\n", (char*) &cctx->raw_format); + ret = AVERROR(EINVAL); + goto error; } switch (ctx->bmd_field_dominance) { @@ -776,7 +808,7 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) } result = ctx->dli->EnableVideoInput(ctx->bmd_mode, - cctx->v210 ? bmdFormat10BitYUV : bmdFormat8BitYUV, + (BMDPixelFormat) cctx->raw_format, bmdVideoInputFlagDefault); if (result != S_OK) { diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c index e2118a619c7a3..8b6ff067bc9fd 100644 --- a/libavdevice/decklink_dec_c.c +++ b/libavdevice/decklink_dec_c.c @@ -34,6 +34,12 @@ static const AVOption options[] = { { "list_formats", "list supported formats" , OFFSET(list_formats), AV_OPT_TYPE_INT , { .i64 = 0 }, 0, 1, DEC }, { "format_code", "set format by fourcc" , OFFSET(format_code), AV_OPT_TYPE_STRING, { .str = NULL}, 0, 0, DEC }, { "bm_v210", "v210 10 bit per channel" , OFFSET(v210), AV_OPT_TYPE_INT , { .i64 = 0 }, 0, 1, DEC }, + { "raw_format", "pixel format to be returned by the card when capturing" , OFFSET(raw_format), AV_OPT_TYPE_INT, { .i64 = MKBETAG('2','v','u','y')}, 0, UINT_MAX, DEC, "raw_format" }, + { "uyvy422", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MKBETAG('2','v','u','y') }, 0, 0, DEC, "raw_format"}, + { "yuv422p10", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MKBETAG('v','2','1','0') }, 0, 0, DEC, "raw_format"}, + { "argb", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 32 }, 0, 0, DEC, "raw_format"}, + { "bgra", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MKBETAG('B','G','R','A') }, 0, 0, DEC, "raw_format"}, + { "rgb10", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MKBETAG('r','2','1','0') }, 0, 0, DEC, "raw_format"}, { "teletext_lines", "teletext lines bitmask", OFFSET(teletext_lines), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, 0x7ffffffffLL, DEC, "teletext_lines"}, { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0x7fff9fffeLL}, 0, 0, DEC, "teletext_lines"}, { "all", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0x7ffffffffLL}, 0, 0, DEC, "teletext_lines"}, diff --git a/libavdevice/version.h b/libavdevice/version.h index da43e55c32e31..3fbd273fc3a92 100644 --- a/libavdevice/version.h +++ b/libavdevice/version.h @@ -29,7 +29,7 @@ #define LIBAVDEVICE_VERSION_MAJOR 57 #define LIBAVDEVICE_VERSION_MINOR 9 -#define LIBAVDEVICE_VERSION_MICRO 100 +#define LIBAVDEVICE_VERSION_MICRO 101 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ LIBAVDEVICE_VERSION_MINOR, \ From e6cdf30fb44f5e011ff94fbc04636b904a51a07e Mon Sep 17 00:00:00 2001 From: Karthick J Date: Tue, 29 Aug 2017 16:39:28 +0530 Subject: [PATCH 3200/3374] avdevice/decklink_dec: Added VANC search for all resolutions In preparation to make VANC decode modular, to support multiple other VANC data. Signed-off-by: Karthick J Signed-off-by: Marton Balint --- libavdevice/decklink_dec.cpp | 80 +++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 10 deletions(-) diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index c93ca68b8066c..b4f92e25d70a3 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -46,6 +46,63 @@ extern "C" { #include "decklink_common.h" #include "decklink_dec.h" +typedef struct VANCLineNumber { + BMDDisplayMode mode; + int vanc_start; + int field0_vanc_end; + int field1_vanc_start; + int vanc_end; +} VANCLineNumber; + +/* These VANC line numbers need not be very accurate. In any case + * GetBufferForVerticalBlankingLine() will return an error when invalid + * ancillary line number was requested. We just need to make sure that the + * entire VANC region is covered, while making sure we don't decode VANC of + * another source during switching*/ +static VANCLineNumber vanc_line_numbers[] = { + /* SD Modes */ + + {bmdModeNTSC, 11, 19, 274, 282}, + {bmdModeNTSC2398, 11, 19, 274, 282}, + {bmdModePAL, 7, 22, 320, 335}, + {bmdModeNTSCp, 11, -1, -1, 39}, + {bmdModePALp, 7, -1, -1, 45}, + + /* HD 1080 Modes */ + + {bmdModeHD1080p2398, 8, -1, -1, 42}, + {bmdModeHD1080p24, 8, -1, -1, 42}, + {bmdModeHD1080p25, 8, -1, -1, 42}, + {bmdModeHD1080p2997, 8, -1, -1, 42}, + {bmdModeHD1080p30, 8, -1, -1, 42}, + {bmdModeHD1080i50, 8, 20, 570, 585}, + {bmdModeHD1080i5994, 8, 20, 570, 585}, + {bmdModeHD1080i6000, 8, 20, 570, 585}, + {bmdModeHD1080p50, 8, -1, -1, 42}, + {bmdModeHD1080p5994, 8, -1, -1, 42}, + {bmdModeHD1080p6000, 8, -1, -1, 42}, + + /* HD 720 Modes */ + + {bmdModeHD720p50, 8, -1, -1, 26}, + {bmdModeHD720p5994, 8, -1, -1, 26}, + {bmdModeHD720p60, 8, -1, -1, 26}, + + /* For all other modes, for which we don't support VANC */ + {bmdModeUnknown, 0, -1, -1, -1} +}; + +static int get_vanc_line_idx(BMDDisplayMode mode) +{ + unsigned int i; + for (i = 0; i < FF_ARRAY_ELEMS(vanc_line_numbers); i++) { + if (mode == vanc_line_numbers[i].mode) + return i; + } + /* Return the VANC idx for Unknown mode */ + return i - 1; +} + static uint8_t calc_parity_and_line_offset(int line) { uint8_t ret = (line < 313) << 5; @@ -502,18 +559,21 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( } } #endif - if (videoFrame->GetWidth() == 1920 && vanc_format == bmdFormat10BitYUV) { - int first_active_line = ctx->bmd_field_dominance == bmdProgressiveFrame ? 42 : 584; - for (i = 8; i < first_active_line; i++) { + if (vanc_format == bmdFormat10BitYUV) { + int idx = get_vanc_line_idx(ctx->bmd_mode); + for (i = vanc_line_numbers[idx].vanc_start; i <= vanc_line_numbers[idx].vanc_end; i++) { uint8_t *buf; - if (vanc->GetBufferForVerticalBlankingLine(i, (void**)&buf) == S_OK) - txt_buf = teletext_data_unit_from_vanc_data(buf, txt_buf, ctx->teletext_lines); - if (ctx->bmd_field_dominance != bmdProgressiveFrame && i == 20) // skip field1 active lines - i = 569; - if (txt_buf - txt_buf0 > 1611) { // ensure we still have at least 1920 bytes free in the buffer - av_log(avctx, AV_LOG_ERROR, "Too many OP47 teletext packets.\n"); - break; + if (vanc->GetBufferForVerticalBlankingLine(i, (void**)&buf) == S_OK) { + if (videoFrame->GetWidth() == 1920) { + txt_buf = teletext_data_unit_from_vanc_data(buf, txt_buf, ctx->teletext_lines); + if (txt_buf - txt_buf0 > 1611) { // ensure we still have at least 1920 bytes free in the buffer + av_log(avctx, AV_LOG_ERROR, "Too many OP47 teletext packets.\n"); + break; + } + } } + if (i == vanc_line_numbers[idx].field0_vanc_end) + i = vanc_line_numbers[idx].field1_vanc_start - 1; } } vanc->Release(); From a8755785d7a940eace06ed5397d51cb779213749 Mon Sep 17 00:00:00 2001 From: Karthick J Date: Wed, 30 Aug 2017 10:21:00 +0530 Subject: [PATCH 3201/3374] avdevice/decklink_dec: Extraction of luma from V210 VANC modularized In preparation to support multiple VANC data decode Signed-off-by: Karthick J Signed-off-by: Marton Balint --- libavdevice/decklink_dec.cpp | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index b4f92e25d70a3..614bda0924f77 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -46,6 +46,8 @@ extern "C" { #include "decklink_common.h" #include "decklink_dec.h" +#define MAX_WIDTH_VANC 1920 + typedef struct VANCLineNumber { BMDDisplayMode mode; int vanc_start; @@ -103,6 +105,18 @@ static int get_vanc_line_idx(BMDDisplayMode mode) return i - 1; } +/* The 10-bit VANC data is packed in V210, we only need the luma component. */ +static void extract_luma_from_v210(uint16_t *dst, const uint8_t *src, int width) +{ + int i; + for (i = 0; i < width / 3; i += 3) { + *dst++ = (src[1] >> 2) + ((src[2] & 15) << 6); + *dst++ = src[4] + ((src[5] & 3) << 8); + *dst++ = (src[6] >> 4) + ((src[7] & 63) << 4); + src += 8; + } +} + static uint8_t calc_parity_and_line_offset(int line) { uint8_t ret = (line < 313) << 5; @@ -218,19 +232,10 @@ static uint8_t* teletext_data_unit_from_ancillary_packet(uint16_t *py, uint16_t return tgt; } -static uint8_t* teletext_data_unit_from_vanc_data(uint8_t *src, uint8_t *tgt, int64_t wanted_lines) +static uint8_t* teletext_data_unit_from_vanc_data(uint16_t *py, uint8_t *tgt, int64_t wanted_lines) { - uint16_t y[1920]; - uint16_t *py = y; - uint16_t *pend = y + 1920; - /* The 10-bit VANC data is packed in V210, we only need the luma component. */ - while (py < pend) { - *py++ = (src[1] >> 2) + ((src[2] & 15) << 6); - *py++ = src[4] + ((src[5] & 3) << 8); - *py++ = (src[6] >> 4) + ((src[7] & 63) << 4); - src += 8; - } - py = y; + uint16_t *pend = py + 1920; + while (py < pend - 6) { if (py[0] == 0 && py[1] == 0x3ff && py[2] == 0x3ff) { // ancillary data flag py += 3; @@ -559,13 +564,15 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( } } #endif - if (vanc_format == bmdFormat10BitYUV) { + if (vanc_format == bmdFormat10BitYUV && videoFrame->GetWidth() <= MAX_WIDTH_VANC) { int idx = get_vanc_line_idx(ctx->bmd_mode); for (i = vanc_line_numbers[idx].vanc_start; i <= vanc_line_numbers[idx].vanc_end; i++) { uint8_t *buf; if (vanc->GetBufferForVerticalBlankingLine(i, (void**)&buf) == S_OK) { + uint16_t luma_vanc[MAX_WIDTH_VANC]; + extract_luma_from_v210(luma_vanc, buf, videoFrame->GetWidth()); if (videoFrame->GetWidth() == 1920) { - txt_buf = teletext_data_unit_from_vanc_data(buf, txt_buf, ctx->teletext_lines); + txt_buf = teletext_data_unit_from_vanc_data(luma_vanc, txt_buf, ctx->teletext_lines); if (txt_buf - txt_buf0 > 1611) { // ensure we still have at least 1920 bytes free in the buffer av_log(avctx, AV_LOG_ERROR, "Too many OP47 teletext packets.\n"); break; From b6cf66ae1c4986f6d788a17233a6609b346c6aa6 Mon Sep 17 00:00:00 2001 From: Karthick J Date: Wed, 30 Aug 2017 11:43:16 +0530 Subject: [PATCH 3202/3374] avdevice/decklink_dec: Added Closed caption decode from VANC Signed-off-by: Karthick J Signed-off-by: Marton Balint --- doc/APIchanges | 3 + libavcodec/avcodec.h | 7 ++ libavcodec/avpacket.c | 1 + libavcodec/version.h | 2 +- libavdevice/decklink_dec.cpp | 196 ++++++++++++++++++++++++++++++++--- 5 files changed, 191 insertions(+), 18 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 606ba7f6c0a34..5c6376243fb68 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2017-09-28 - xxxxxxx - lavc 57.106.104 - avcodec.h + Add AV_PKT_DATA_A53_CC packet side data, to export closed captions + 2017-09-27 - xxxxxxx - lavu 55.77.101 / lavu 55.31.1 - frame.h Allow passing the value of 0 (meaning "automatic") as the required alignment to av_frame_get_buffer(). diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index b5bbc591ac6ee..dd7c4b4ce5e0b 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1599,6 +1599,13 @@ enum AVPacketSideDataType { */ AV_PKT_DATA_CONTENT_LIGHT_LEVEL, + /** + * ATSC A53 Part 4 Closed Captions. This metadata should be associated with + * a video stream. A53 CC bitstream is stored as uint8_t in AVPacketSideData.data. + * The number of bytes of CC data is AVPacketSideData.size. + */ + AV_PKT_DATA_A53_CC, + /** * The number of side data elements (in fact a bit more than it). * This is not part of the public API/ABI in the sense that it may diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index b07180eac883a..d1f4ea9eb3feb 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -387,6 +387,7 @@ const char *av_packet_side_data_name(enum AVPacketSideDataType type) case AV_PKT_DATA_MASTERING_DISPLAY_METADATA: return "Mastering display metadata"; case AV_PKT_DATA_CONTENT_LIGHT_LEVEL: return "Content light level metadata"; case AV_PKT_DATA_SPHERICAL: return "Spherical Mapping"; + case AV_PKT_DATA_A53_CC: return "A53 Closed Captions"; } return NULL; } diff --git a/libavcodec/version.h b/libavcodec/version.h index 39d9ad992ca22..7aee6f9cf30c5 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 106 -#define LIBAVCODEC_VERSION_MICRO 103 +#define LIBAVCODEC_VERSION_MICRO 104 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index 614bda0924f77..3ce2cab5f4d8b 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -1,6 +1,7 @@ /* * Blackmagic DeckLink input * Copyright (c) 2013-2014 Luca Barbato, Deti Fliegl + * Copyright (c) 2014 Rafaël Carré * Copyright (c) 2017 Akamai Technologies, Inc. * * This file is part of FFmpeg. @@ -105,6 +106,42 @@ static int get_vanc_line_idx(BMDDisplayMode mode) return i - 1; } +static inline uint16_t parity (uint16_t x) +{ + uint16_t i; + for (i = 4 * sizeof (x); i > 0; i /= 2) + x ^= x >> i; + return x & 1; +} + +static inline void clear_parity_bits(uint16_t *buf, int len) { + int i; + for (i = 0; i < len; i++) + buf[i] &= 0xff; +} + +static int check_vanc_parity_checksum(uint16_t *buf, int len, uint16_t checksum) { + int i; + uint16_t vanc_sum = 0; + for (i = 3; i < len - 1; i++) { + uint16_t v = buf[i]; + int np = v >> 8; + int p = parity(v & 0xff); + if ((!!p ^ !!(v & 0x100)) || (np != 1 && np != 2)) { + // Parity check failed + return -1; + } + vanc_sum += v; + } + vanc_sum &= 0x1ff; + vanc_sum |= ((~vanc_sum & 0x100) << 1); + if (checksum != vanc_sum) { + // Checksum verification failed + return -1; + } + return 0; +} + /* The 10-bit VANC data is packed in V210, we only need the luma component. */ static void extract_luma_from_v210(uint16_t *dst, const uint8_t *src, int width) { @@ -232,19 +269,148 @@ static uint8_t* teletext_data_unit_from_ancillary_packet(uint16_t *py, uint16_t return tgt; } -static uint8_t* teletext_data_unit_from_vanc_data(uint16_t *py, uint8_t *tgt, int64_t wanted_lines) +uint8_t *vanc_to_cc(AVFormatContext *avctx, uint16_t *buf, size_t words, + unsigned &cc_count) { - uint16_t *pend = py + 1920; + size_t i, len = (buf[5] & 0xff) + 6 + 1; + uint8_t cdp_sum, rate; + uint16_t hdr, ftr; + uint8_t *cc; + uint16_t *cdp = &buf[6]; // CDP follows + if (cdp[0] != 0x96 || cdp[1] != 0x69) { + av_log(avctx, AV_LOG_WARNING, "Invalid CDP header 0x%.2x 0x%.2x\n", cdp[0], cdp[1]); + return NULL; + } - while (py < pend - 6) { - if (py[0] == 0 && py[1] == 0x3ff && py[2] == 0x3ff) { // ancillary data flag - py += 3; - tgt = teletext_data_unit_from_ancillary_packet(py, pend, tgt, wanted_lines, 0); - py += py[2] & 255; + len -= 7; // remove VANC header and checksum + + if (cdp[2] != len) { + av_log(avctx, AV_LOG_WARNING, "CDP len %d != %zu\n", cdp[2], len); + return NULL; + } + + cdp_sum = 0; + for (i = 0; i < len - 1; i++) + cdp_sum += cdp[i]; + cdp_sum = cdp_sum ? 256 - cdp_sum : 0; + if (cdp[len - 1] != cdp_sum) { + av_log(avctx, AV_LOG_WARNING, "CDP checksum invalid 0x%.4x != 0x%.4x\n", cdp_sum, cdp[len-1]); + return NULL; + } + + rate = cdp[3]; + if (!(rate & 0x0f)) { + av_log(avctx, AV_LOG_WARNING, "CDP frame rate invalid (0x%.2x)\n", rate); + return NULL; + } + rate >>= 4; + if (rate > 8) { + av_log(avctx, AV_LOG_WARNING, "CDP frame rate invalid (0x%.2x)\n", rate); + return NULL; + } + + if (!(cdp[4] & 0x43)) /* ccdata_present | caption_service_active | reserved */ { + av_log(avctx, AV_LOG_WARNING, "CDP flags invalid (0x%.2x)\n", cdp[4]); + return NULL; + } + + hdr = (cdp[5] << 8) | cdp[6]; + if (cdp[7] != 0x72) /* ccdata_id */ { + av_log(avctx, AV_LOG_WARNING, "Invalid ccdata_id 0x%.2x\n", cdp[7]); + return NULL; + } + + cc_count = cdp[8]; + if (!(cc_count & 0xe0)) { + av_log(avctx, AV_LOG_WARNING, "Invalid cc_count 0x%.2x\n", cc_count); + return NULL; + } + + cc_count &= 0x1f; + if ((len - 13) < cc_count * 3) { + av_log(avctx, AV_LOG_WARNING, "Invalid cc_count %d (> %zu)\n", cc_count * 3, len - 13); + return NULL; + } + + if (cdp[len - 4] != 0x74) /* footer id */ { + av_log(avctx, AV_LOG_WARNING, "Invalid footer id 0x%.2x\n", cdp[len-4]); + return NULL; + } + + ftr = (cdp[len - 3] << 8) | cdp[len - 2]; + if (ftr != hdr) { + av_log(avctx, AV_LOG_WARNING, "Header 0x%.4x != Footer 0x%.4x\n", hdr, ftr); + return NULL; + } + + cc = (uint8_t *)av_malloc(cc_count * 3); + if (cc == NULL) { + av_log(avctx, AV_LOG_WARNING, "CC - av_malloc failed for cc_count = %d\n", cc_count); + return NULL; + } + + for (size_t i = 0; i < cc_count; i++) { + cc[3*i + 0] = cdp[9 + 3*i+0] /* & 3 */; + cc[3*i + 1] = cdp[9 + 3*i+1]; + cc[3*i + 2] = cdp[9 + 3*i+2]; + } + + cc_count *= 3; + return cc; +} + +uint8_t *get_metadata(AVFormatContext *avctx, uint16_t *buf, size_t width, + uint8_t *tgt, size_t tgt_size, AVPacket *pkt) +{ + decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data; + uint16_t *max_buf = buf + width; + + while (buf < max_buf - 6) { + int len; + uint16_t did = buf[3] & 0xFF; // data id + uint16_t sdid = buf[4] & 0xFF; // secondary data id + /* Check for VANC header */ + if (buf[0] != 0 || buf[1] != 0x3ff || buf[2] != 0x3ff) { + return tgt; + } + + len = (buf[5] & 0xff) + 6 + 1; + if (len > max_buf - buf) { + av_log(avctx, AV_LOG_WARNING, "Data Count (%d) > data left (%zu)\n", + len, max_buf - buf); + return tgt; + } + + if (did == 0x43 && (sdid == 0x02 || sdid == 0x03) && cctx->teletext_lines && + width == 1920 && tgt_size >= 1920) { + if (check_vanc_parity_checksum(buf, len, buf[len - 1]) < 0) { + av_log(avctx, AV_LOG_WARNING, "VANC parity or checksum incorrect\n"); + goto skip_packet; + } + tgt = teletext_data_unit_from_ancillary_packet(buf + 3, buf + len, tgt, cctx->teletext_lines, 0); + } else if (did == 0x61 && sdid == 0x01) { + unsigned int data_len; + uint8_t *data; + if (check_vanc_parity_checksum(buf, len, buf[len - 1]) < 0) { + av_log(avctx, AV_LOG_WARNING, "VANC parity or checksum incorrect\n"); + goto skip_packet; + } + clear_parity_bits(buf, len); + data = vanc_to_cc(avctx, buf, width, data_len); + if (data) { + uint8_t *pkt_cc = av_packet_new_side_data(pkt, AV_PKT_DATA_A53_CC, data_len); + if (pkt_cc) + memcpy(pkt_cc, data, data_len); + av_free(data); + } } else { - py++; + av_log(avctx, AV_LOG_DEBUG, "Unknown meta data DID = 0x%.2x SDID = 0x%.2x\n", + did, sdid); } +skip_packet: + buf += len; } + return tgt; } @@ -536,7 +702,7 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( videoFrame->GetHeight(); //fprintf(stderr,"Video Frame size %d ts %d\n", pkt.size, pkt.pts); - if (!no_video && ctx->teletext_lines) { + if (!no_video) { IDeckLinkVideoFrameAncillary *vanc; AVPacket txt_pkt; uint8_t txt_buf0[3531]; // 35 * 46 bytes decoded teletext lines + 1 byte data_identifier + 1920 bytes OP47 decode buffer @@ -549,7 +715,8 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( txt_buf[0] = 0x10; // data_identifier - EBU_data txt_buf++; #if CONFIG_LIBZVBI - if (ctx->bmd_mode == bmdModePAL && (vanc_format == bmdFormat8BitYUV || vanc_format == bmdFormat10BitYUV)) { + if (ctx->bmd_mode == bmdModePAL && ctx->teletext_lines && + (vanc_format == bmdFormat8BitYUV || vanc_format == bmdFormat10BitYUV)) { av_assert0(videoFrame->GetWidth() == 720); for (i = 6; i < 336; i++, line_mask <<= 1) { uint8_t *buf; @@ -571,13 +738,8 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( if (vanc->GetBufferForVerticalBlankingLine(i, (void**)&buf) == S_OK) { uint16_t luma_vanc[MAX_WIDTH_VANC]; extract_luma_from_v210(luma_vanc, buf, videoFrame->GetWidth()); - if (videoFrame->GetWidth() == 1920) { - txt_buf = teletext_data_unit_from_vanc_data(luma_vanc, txt_buf, ctx->teletext_lines); - if (txt_buf - txt_buf0 > 1611) { // ensure we still have at least 1920 bytes free in the buffer - av_log(avctx, AV_LOG_ERROR, "Too many OP47 teletext packets.\n"); - break; - } - } + txt_buf = get_metadata(avctx, luma_vanc, videoFrame->GetWidth(), + txt_buf, sizeof(txt_buf0) - (txt_buf - txt_buf0), &pkt); } if (i == vanc_line_numbers[idx].field0_vanc_end) i = vanc_line_numbers[idx].field1_vanc_start - 1; From f7b7d51a37ddbd15be5611b86799fb6d3e443fff Mon Sep 17 00:00:00 2001 From: Karthick J Date: Thu, 31 Aug 2017 16:40:05 +0530 Subject: [PATCH 3203/3374] avcodec/decode: Pass on the Closed Captions Side Data Signed-off-by: Karthick J Signed-off-by: Marton Balint --- libavcodec/decode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 892143c1d2cfe..1337ffb5271b9 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -1490,6 +1490,7 @@ int ff_init_buffer_info(AVCodecContext *avctx, AVFrame *frame) { AV_PKT_DATA_AUDIO_SERVICE_TYPE, AV_FRAME_DATA_AUDIO_SERVICE_TYPE }, { AV_PKT_DATA_MASTERING_DISPLAY_METADATA, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA }, { AV_PKT_DATA_CONTENT_LIGHT_LEVEL, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL }, + { AV_PKT_DATA_A53_CC, AV_FRAME_DATA_A53_CC }, }; if (pkt) { From 05dfa21d47f35f394938653abcab8b3baa3bc999 Mon Sep 17 00:00:00 2001 From: Rostislav Pehlivanov Date: Thu, 28 Sep 2017 22:39:36 +0100 Subject: [PATCH 3204/3374] opus_pvq: make max_den a float Prevents int->float conversions on every loop. Performance gain on synthetic benchmarks: 13%. Suggested by kamedo2. Signed-off-by: Rostislav Pehlivanov --- libavcodec/opus_pvq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/opus_pvq.c b/libavcodec/opus_pvq.c index 2fb276099bc67..f98b85d36fd33 100644 --- a/libavcodec/opus_pvq.c +++ b/libavcodec/opus_pvq.c @@ -381,8 +381,9 @@ static float ppp_pvq_search_c(float *X, int *y, int K, int N) } while (K) { - int max_idx = 0, max_den = 1, phase = FFSIGN(K); + int max_idx = 0, phase = FFSIGN(K); float max_num = 0.0f; + float max_den = 1.0f; y_norm += 1.0f; for (i = 0; i < N; i++) { From 1015982f45d832ee926a81460121673a97292333 Mon Sep 17 00:00:00 2001 From: Pablo Montilla Date: Thu, 28 Sep 2017 23:46:57 +0200 Subject: [PATCH 3205/3374] lavf/mov: Allow reading very large files. The Sample count in the time-to-sample table is defined as 32-bit unsigned integer by the QT specification. Fixes ticket #6700. --- libavformat/isom.h | 2 +- libavformat/mov.c | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/libavformat/isom.h b/libavformat/isom.h index 9aea629293dd1..b9380e9dcc3e9 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -52,7 +52,7 @@ struct AVAESCTR; */ typedef struct MOVStts { - int count; + unsigned int count; int duration; } MOVStts; diff --git a/libavformat/mov.c b/libavformat/mov.c index ede9cda9d352e..899690d920d47 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -2663,15 +2663,11 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom) for (i = 0; i < entries && !pb->eof_reached; i++) { int sample_duration; - int sample_count; + unsigned int sample_count; sample_count=avio_rb32(pb); sample_duration = avio_rb32(pb); - if (sample_count < 0) { - av_log(c->fc, AV_LOG_ERROR, "Invalid sample_count=%d\n", sample_count); - return AVERROR_INVALIDDATA; - } sc->stts_data[i].count= sample_count; sc->stts_data[i].duration= sample_duration; From c32077c0ee1bcc8e00f5a9a151d540adac33ea8c Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Tue, 26 Sep 2017 18:04:12 -0700 Subject: [PATCH 3206/3374] avcodec/hevc_ps: extract SPS fields required for hvcC construction Signed-off-by: Aman Gupta Reviewed-by: Michael Niedermayer --- libavcodec/hevc_ps.c | 3 ++- libavcodec/hevc_ps.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index 500fee03d86c2..902917d4ddaab 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -893,7 +893,7 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, return AVERROR_INVALIDDATA; } - skip_bits1(gb); // temporal_id_nesting_flag + sps->temporal_id_nesting_flag = get_bits(gb, 1); if ((ret = parse_ptl(gb, avctx, &sps->ptl, sps->max_sub_layers)) < 0) return ret; @@ -956,6 +956,7 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, sps->bit_depth, bit_depth_chroma); return AVERROR_INVALIDDATA; } + sps->bit_depth_chroma = bit_depth_chroma; ret = map_pixel_format(avctx, sps); if (ret < 0) diff --git a/libavcodec/hevc_ps.h b/libavcodec/hevc_ps.h index 4e6c3bc8496fc..76f8eb31e6ae1 100644 --- a/libavcodec/hevc_ps.h +++ b/libavcodec/hevc_ps.h @@ -232,6 +232,7 @@ typedef struct HEVCSPS { HEVCWindow pic_conf_win; int bit_depth; + int bit_depth_chroma; int pixel_shift; enum AVPixelFormat pix_fmt; @@ -244,6 +245,7 @@ typedef struct HEVCSPS { int num_reorder_pics; int max_latency_increase; } temporal_layer[HEVC_MAX_SUB_LAYERS]; + uint8_t temporal_id_nesting_flag; VUI vui; PTL ptl; From 3d4f8b9184a4693c577e0b73496e6cc1989c6bbf Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Tue, 26 Sep 2017 11:30:28 -0700 Subject: [PATCH 3207/3374] avcodec/videotoolbox: add hevc support Signed-off-by: Aman Gupta --- configure | 7 +- libavcodec/allcodecs.c | 1 + libavcodec/hevc_refs.c | 3 + libavcodec/hevcdec.c | 12 ++- libavcodec/vda_vt_internal.h | 1 + libavcodec/videotoolbox.c | 197 +++++++++++++++++++++++++++++++++++ 6 files changed, 219 insertions(+), 2 deletions(-) diff --git a/configure b/configure index c2f5fc2c984f3..9cf98c8cc2ac7 100755 --- a/configure +++ b/configure @@ -2081,6 +2081,7 @@ TOOLCHAIN_FEATURES=" TYPES_LIST=" CONDITION_VARIABLE_Ptr + kCMVideoCodecType_HEVC socklen_t struct_addrinfo struct_group_source_req @@ -2696,6 +2697,8 @@ hevc_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferHEVC" hevc_vaapi_hwaccel_select="hevc_decoder" hevc_vdpau_hwaccel_deps="vdpau VdpPictureInfoHEVC" hevc_vdpau_hwaccel_select="hevc_decoder" +hevc_videotoolbox_hwaccel_deps="videotoolbox" +hevc_videotoolbox_hwaccel_select="hevc_decoder" mjpeg_cuvid_hwaccel_deps="cuda cuvid" mjpeg_cuvid_hwaccel_select="mjpeg_cuvid_decoder" mpeg_xvmc_hwaccel_deps="xvmc" @@ -5814,8 +5817,10 @@ enabled avfoundation && { check_lib avfoundation CoreGraphics/CoreGraphics.h CGGetActiveDisplayList "-framework CoreGraphics" || check_lib avfoundation ApplicationServices/ApplicationServices.h CGGetActiveDisplayList "-framework ApplicationServices"; } -enabled videotoolbox && +enabled videotoolbox && { check_lib coreservices CoreServices/CoreServices.h UTGetOSTypeFromString "-framework CoreServices" + check_func_headers CoreMedia/CMFormatDescription.h kCMVideoCodecType_HEVC "-framework CoreMedia" +} check_struct "sys/time.h sys/resource.h" "struct rusage" ru_maxrss diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 7ae9e8cea1c9e..4f34312e67353 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -84,6 +84,7 @@ static void register_all(void) REGISTER_HWACCEL(HEVC_QSV, hevc_qsv); REGISTER_HWACCEL(HEVC_VAAPI, hevc_vaapi); REGISTER_HWACCEL(HEVC_VDPAU, hevc_vdpau); + REGISTER_HWACCEL(HEVC_VIDEOTOOLBOX, hevc_videotoolbox); REGISTER_HWACCEL(MJPEG_CUVID, mjpeg_cuvid); REGISTER_HWACCEL(MPEG1_CUVID, mpeg1_cuvid); REGISTER_HWACCEL(MPEG1_XVMC, mpeg1_xvmc); diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c index 68c730edcce1d..ac462d350b0ad 100644 --- a/libavcodec/hevc_refs.c +++ b/libavcodec/hevc_refs.c @@ -208,6 +208,9 @@ int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush) if (nb_output) { HEVCFrame *frame = &s->DPB[min_idx]; + if (frame->frame->format == AV_PIX_FMT_VIDEOTOOLBOX && frame->frame->buf[0]->size == 1) + return 0; + ret = av_frame_ref(out, frame->frame); if (frame->flags & HEVC_FRAME_FLAG_BUMPING) ff_hevc_unref_frame(s, frame, HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_BUMPING); diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 2306c51ed3763..2e4add2ae30ae 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -352,7 +352,11 @@ static void export_stream_params(AVCodecContext *avctx, const HEVCParamSets *ps, static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) { - #define HWACCEL_MAX (CONFIG_HEVC_DXVA2_HWACCEL + CONFIG_HEVC_D3D11VA_HWACCEL * 2 + CONFIG_HEVC_VAAPI_HWACCEL + CONFIG_HEVC_VDPAU_HWACCEL) +#define HWACCEL_MAX (CONFIG_HEVC_DXVA2_HWACCEL + \ + CONFIG_HEVC_D3D11VA_HWACCEL * 2 + \ + CONFIG_HEVC_VAAPI_HWACCEL + \ + CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL + \ + CONFIG_HEVC_VDPAU_HWACCEL) enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmt = pix_fmts; switch (sps->pix_fmt) { @@ -370,6 +374,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) #endif #if CONFIG_HEVC_VDPAU_HWACCEL *fmt++ = AV_PIX_FMT_VDPAU; +#endif +#if CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL + *fmt++ = AV_PIX_FMT_VIDEOTOOLBOX; #endif break; case AV_PIX_FMT_YUV420P10: @@ -382,6 +389,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) #endif #if CONFIG_HEVC_VAAPI_HWACCEL *fmt++ = AV_PIX_FMT_VAAPI; +#endif +#if CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL + *fmt++ = AV_PIX_FMT_VIDEOTOOLBOX; #endif break; } diff --git a/libavcodec/vda_vt_internal.h b/libavcodec/vda_vt_internal.h index e55a813899cd4..326a60a695647 100644 --- a/libavcodec/vda_vt_internal.h +++ b/libavcodec/vda_vt_internal.h @@ -59,4 +59,5 @@ int ff_videotoolbox_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size); CFDataRef ff_videotoolbox_avcc_extradata_create(AVCodecContext *avctx); +CFDataRef ff_videotoolbox_hvcc_extradata_create(AVCodecContext *avctx); #endif /* AVCODEC_VDA_VT_INTERNAL_H */ diff --git a/libavcodec/videotoolbox.c b/libavcodec/videotoolbox.c index dd13e2581b068..ec8b6d885c8e5 100644 --- a/libavcodec/videotoolbox.c +++ b/libavcodec/videotoolbox.c @@ -32,6 +32,7 @@ #include "libavutil/hwcontext.h" #include "bytestream.h" #include "h264dec.h" +#include "hevcdec.h" #include "mpegvideo.h" #include @@ -39,6 +40,10 @@ # define kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder CFSTR("RequireHardwareAcceleratedVideoDecoder") #endif +#if !HAVE_KCMVIDEOCODECTYPE_HEVC +enum { kCMVideoCodecType_HEVC = 'hvc1' }; +#endif + #define VIDEOTOOLBOX_ESDS_EXTRADATA_PADDING 12 static void videotoolbox_buffer_release(void *opaque, uint8_t *data) @@ -115,6 +120,164 @@ CFDataRef ff_videotoolbox_avcc_extradata_create(AVCodecContext *avctx) return data; } +CFDataRef ff_videotoolbox_hvcc_extradata_create(AVCodecContext *avctx) +{ + HEVCContext *h = avctx->priv_data; + const HEVCVPS *vps = (const HEVCVPS *)h->ps.vps_list[0]->data; + const HEVCSPS *sps = (const HEVCSPS *)h->ps.sps_list[0]->data; + int i, num_pps = 0; + const HEVCPPS *pps = h->ps.pps; + PTLCommon ptlc = vps->ptl.general_ptl; + VUI vui = sps->vui; + uint8_t parallelismType; + CFDataRef data = NULL; + uint8_t *p; + int vt_extradata_size = 23 + 5 + vps->data_size + 5 + sps->data_size + 3; + uint8_t *vt_extradata; + + for (i = 0; i < MAX_PPS_COUNT; i++) { + if (h->ps.pps_list[i]) { + const HEVCPPS *pps = (const HEVCPPS *)h->ps.pps_list[i]->data; + vt_extradata_size += 2 + pps->data_size; + num_pps++; + } + } + + vt_extradata = av_malloc(vt_extradata_size); + if (!vt_extradata) + return NULL; + p = vt_extradata; + + /* unsigned int(8) configurationVersion = 1; */ + AV_W8(p + 0, 1); + + /* + * unsigned int(2) general_profile_space; + * unsigned int(1) general_tier_flag; + * unsigned int(5) general_profile_idc; + */ + AV_W8(p + 1, ptlc.profile_space << 6 | + ptlc.tier_flag << 5 | + ptlc.profile_idc); + + /* unsigned int(32) general_profile_compatibility_flags; */ + memcpy(p + 2, ptlc.profile_compatibility_flag, 4); + + /* unsigned int(48) general_constraint_indicator_flags; */ + AV_W8(p + 6, ptlc.progressive_source_flag << 7 | + ptlc.interlaced_source_flag << 6 | + ptlc.non_packed_constraint_flag << 5 | + ptlc.frame_only_constraint_flag << 4); + AV_W8(p + 7, 0); + AV_WN32(p + 8, 0); + + /* unsigned int(8) general_level_idc; */ + AV_W8(p + 12, ptlc.level_idc); + + /* + * bit(4) reserved = ‘1111’b; + * unsigned int(12) min_spatial_segmentation_idc; + */ + AV_W8(p + 13, 0xf0 | (vui.min_spatial_segmentation_idc >> 4)); + AV_W8(p + 14, vui.min_spatial_segmentation_idc & 0xff); + + /* + * bit(6) reserved = ‘111111’b; + * unsigned int(2) parallelismType; + */ + if (!vui.min_spatial_segmentation_idc) + parallelismType = 0; + else if (pps->entropy_coding_sync_enabled_flag && pps->tiles_enabled_flag) + parallelismType = 0; + else if (pps->entropy_coding_sync_enabled_flag) + parallelismType = 3; + else if (pps->tiles_enabled_flag) + parallelismType = 2; + else + parallelismType = 1; + AV_W8(p + 15, 0xfc | parallelismType); + + /* + * bit(6) reserved = ‘111111’b; + * unsigned int(2) chromaFormat; + */ + AV_W8(p + 16, sps->chroma_format_idc | 0xfc); + + /* + * bit(5) reserved = ‘11111’b; + * unsigned int(3) bitDepthLumaMinus8; + */ + AV_W8(p + 17, (sps->bit_depth - 8) | 0xfc); + + /* + * bit(5) reserved = ‘11111’b; + * unsigned int(3) bitDepthChromaMinus8; + */ + AV_W8(p + 18, (sps->bit_depth_chroma - 8) | 0xfc); + + /* bit(16) avgFrameRate; */ + AV_WB16(p + 19, 0); + + /* + * bit(2) constantFrameRate; + * bit(3) numTemporalLayers; + * bit(1) temporalIdNested; + * unsigned int(2) lengthSizeMinusOne; + */ + AV_W8(p + 21, 0 << 6 | + sps->max_sub_layers << 3 | + sps->temporal_id_nesting_flag << 2 | + 3); + + /* unsigned int(8) numOfArrays; */ + AV_W8(p + 22, 3); + + p += 23; + /* vps */ + /* + * bit(1) array_completeness; + * unsigned int(1) reserved = 0; + * unsigned int(6) NAL_unit_type; + */ + AV_W8(p, 1 << 7 | + HEVC_NAL_VPS & 0x3f); + /* unsigned int(16) numNalus; */ + AV_WB16(p + 1, 1); + /* unsigned int(16) nalUnitLength; */ + AV_WB16(p + 3, vps->data_size); + /* bit(8*nalUnitLength) nalUnit; */ + memcpy(p + 5, vps->data, vps->data_size); + p += 5 + vps->data_size; + + /* sps */ + AV_W8(p, 1 << 7 | + HEVC_NAL_SPS & 0x3f); + AV_WB16(p + 1, 1); + AV_WB16(p + 3, sps->data_size); + memcpy(p + 5, sps->data, sps->data_size); + p += 5 + sps->data_size; + + /* pps */ + AV_W8(p, 1 << 7 | + HEVC_NAL_PPS & 0x3f); + AV_WB16(p + 1, num_pps); + p += 3; + for (i = 0; i < MAX_PPS_COUNT; i++) { + if (h->ps.pps_list[i]) { + const HEVCPPS *pps = (const HEVCPPS *)h->ps.pps_list[i]->data; + AV_WB16(p, pps->data_size); + memcpy(p + 2, pps->data, pps->data_size); + p += 2 + pps->data_size; + } + } + + av_assert0(p - vt_extradata == vt_extradata_size); + + data = CFDataCreate(kCFAllocatorDefault, vt_extradata, vt_extradata_size); + av_free(vt_extradata); + return data; +} + int ff_videotoolbox_buffer_create(VTContext *vtctx, AVFrame *frame) { av_buffer_unref(&frame->buf[0]); @@ -445,6 +608,18 @@ static int videotoolbox_h264_end_frame(AVCodecContext *avctx) return videotoolbox_common_end_frame(avctx, frame); } +static int videotoolbox_hevc_end_frame(AVCodecContext *avctx) +{ + HEVCContext *h = avctx->priv_data; + AVFrame *frame = h->ref->frame; + VTContext *vtctx = avctx->internal->hwaccel_priv_data; + int ret; + + ret = videotoolbox_common_end_frame(avctx, frame); + vtctx->bitstream_size = 0; + return ret; +} + static int videotoolbox_mpeg_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) @@ -501,6 +676,11 @@ static CFDictionaryRef videotoolbox_decoder_config_create(CMVideoCodecType codec if (data) CFDictionarySetValue(avc_info, CFSTR("avcC"), data); break; + case kCMVideoCodecType_HEVC : + data = ff_videotoolbox_hvcc_extradata_create(avctx); + if (data) + CFDictionarySetValue(avc_info, CFSTR("hvcC"), data); + break; default: break; } @@ -600,6 +780,9 @@ static int videotoolbox_default_init(AVCodecContext *avctx) case AV_CODEC_ID_H264 : videotoolbox->cm_codec_type = kCMVideoCodecType_H264; break; + case AV_CODEC_ID_HEVC : + videotoolbox->cm_codec_type = kCMVideoCodecType_HEVC; + break; case AV_CODEC_ID_MPEG1VIDEO : videotoolbox->cm_codec_type = kCMVideoCodecType_MPEG1Video; break; @@ -782,6 +965,20 @@ AVHWAccel ff_h263_videotoolbox_hwaccel = { .priv_data_size = sizeof(VTContext), }; +AVHWAccel ff_hevc_videotoolbox_hwaccel = { + .name = "hevc_videotoolbox", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_HEVC, + .pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX, + .alloc_frame = ff_videotoolbox_alloc_frame, + .start_frame = ff_videotoolbox_h264_start_frame, + .decode_slice = ff_videotoolbox_h264_decode_slice, + .end_frame = videotoolbox_hevc_end_frame, + .init = videotoolbox_common_init, + .uninit = ff_videotoolbox_uninit, + .priv_data_size = sizeof(VTContext), +}; + AVHWAccel ff_h264_videotoolbox_hwaccel = { .name = "h264_videotoolbox", .type = AVMEDIA_TYPE_VIDEO, From e16ea52ed35cab948f428eac6a0cc02ca5129674 Mon Sep 17 00:00:00 2001 From: James Almer Date: Thu, 28 Sep 2017 21:34:38 -0300 Subject: [PATCH 3208/3374] configure: fix enabling SDL2 without pkg-config Regression since d81b34069e80cb04160689ef5a160b9aee858257. Signed-off-by: James Almer --- configure | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 9cf98c8cc2ac7..8e4775be8cebc 100755 --- a/configure +++ b/configure @@ -6115,8 +6115,8 @@ if enabled sdl2; then sdl2_extralibs=$("${SDL2_CONFIG}" --libs) check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) >= 0x020001" $sdl2_cflags && check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) < 0x020100" $sdl2_cflags && - check_func SDL_Init $sdl2_extralibs $sdl2_cflags || - disable sdl2 + check_func SDL_Init $sdl2_extralibs $sdl2_cflags && + enable sdl2 fi if test $target_os = "mingw32"; then sdl2_extralibs="$sdl2_extralibs -mconsole" From 792b1629a8818fa778ddea37342f4ba4eaf2ba47 Mon Sep 17 00:00:00 2001 From: Tobias Rapp Date: Thu, 28 Sep 2017 09:15:41 +0200 Subject: [PATCH 3209/3374] fate: increase fuzz for refcmp filter tests Should fix failing tests on GNU/kFreeBSD x86_32. Signed-off-by: Tobias Rapp --- tests/fate/filter-video.mak | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak index 78cd4711e6242..c19f301ff8dfc 100644 --- a/tests/fate/filter-video.mak +++ b/tests/fate/filter-video.mak @@ -750,16 +750,16 @@ fate-filter-meta-4560-rotate0: CMD = framecrc -flags +bitexact -c:a aac_fixed -i REFCMP_DEPS = FFMPEG LAVFI_INDEV TESTSRC2_FILTER AVGBLUR_FILTER METADATA_FILTER FATE_FILTER_SAMPLES-$(call ALLYES, $(REFCMP_DEPS) PSNR_FILTER) += fate-filter-refcmp-psnr-rgb -fate-filter-refcmp-psnr-rgb: CMD = refcmp_metadata psnr rgb24 +fate-filter-refcmp-psnr-rgb: CMD = refcmp_metadata psnr rgb24 0.001 FATE_FILTER_SAMPLES-$(call ALLYES, $(REFCMP_DEPS) PSNR_FILTER) += fate-filter-refcmp-psnr-yuv -fate-filter-refcmp-psnr-yuv: CMD = refcmp_metadata psnr yuv422p +fate-filter-refcmp-psnr-yuv: CMD = refcmp_metadata psnr yuv422p 0.0015 FATE_FILTER_SAMPLES-$(call ALLYES, $(REFCMP_DEPS) SSIM_FILTER) += fate-filter-refcmp-ssim-rgb -fate-filter-refcmp-ssim-rgb: CMD = refcmp_metadata ssim rgb24 +fate-filter-refcmp-ssim-rgb: CMD = refcmp_metadata ssim rgb24 0.015 FATE_FILTER_SAMPLES-$(call ALLYES, $(REFCMP_DEPS) SSIM_FILTER) += fate-filter-refcmp-ssim-yuv -fate-filter-refcmp-ssim-yuv: CMD = refcmp_metadata ssim yuv422p +fate-filter-refcmp-ssim-yuv: CMD = refcmp_metadata ssim yuv422p 0.015 FATE_SAMPLES_FFPROBE += $(FATE_METADATA_FILTER-yes) FATE_SAMPLES_FFMPEG += $(FATE_FILTER_SAMPLES-yes) From 44bdb88811a40673aaef5f82e63705857bd0bfe6 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Fri, 29 Sep 2017 18:31:18 +0200 Subject: [PATCH 3210/3374] lavf/bit: Only build the G.729 bit demuxer if requested. Fix the condition for the G.729 bit muxer. --- libavformat/bit.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavformat/bit.c b/libavformat/bit.c index c3f2fdfbe3842..c703412f1c432 100644 --- a/libavformat/bit.c +++ b/libavformat/bit.c @@ -29,6 +29,7 @@ #define BIT_0 0x7f #define BIT_1 0x81 +#if CONFIG_BIT_DEMUXER static int probe(AVProbeData *p) { int i, j; @@ -113,8 +114,9 @@ AVInputFormat ff_bit_demuxer = { .read_packet = read_packet, .extensions = "bit", }; +#endif -#if CONFIG_MUXERS +#if CONFIG_BIT_MUXER static int write_header(AVFormatContext *s) { AVCodecParameters *par = s->streams[0]->codecpar; From 6f7bd8cd90de3c970d1d73a29ac5749ffe2e2f95 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Fri, 29 Sep 2017 18:46:44 +0200 Subject: [PATCH 3211/3374] lavf/bit: Use pkt->size instead of a constant for G.729 frame size. Makes the code more readable, the muxer may support variable bit-rate in the future. --- libavformat/bit.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavformat/bit.c b/libavformat/bit.c index c703412f1c432..d742a5b3639be 100644 --- a/libavformat/bit.c +++ b/libavformat/bit.c @@ -143,10 +143,10 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR(EINVAL); avio_wl16(pb, SYNC_WORD); - avio_wl16(pb, 8 * 10); + avio_wl16(pb, 8 * pkt->size); - init_get_bits(&gb, pkt->data, 8*10); - for(i=0; i< 8 * 10; i++) + init_get_bits(&gb, pkt->data, 8 * pkt->size); + for (i = 0; i < 8 * pkt->size; i++) avio_wl16(pb, get_bits1(&gb) ? BIT_1 : BIT_0); return 0; From 72da8491ca055f0211f64b160a8e16b9fb179457 Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 29 Sep 2017 16:13:51 -0300 Subject: [PATCH 3212/3374] build: don't call install with the -T option It's not available on macOS. Should fix a regression instroduced by b25d6290c67e193b91becab12e6c88df134cee81. Signed-off-by: James Almer --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 43ce03130abbd..2c7b0d54f1750 100644 --- a/Makefile +++ b/Makefile @@ -172,7 +172,7 @@ install-data: $(DATA_FILES) $(EXAMPLES_FILES) $(EXAMPLE_MAKEFILE) $(Q)mkdir -p "$(DATADIR)/examples" $(INSTALL) -m 644 $(DATA_FILES) "$(DATADIR)" $(INSTALL) -m 644 $(EXAMPLES_FILES) "$(DATADIR)/examples" - $(INSTALL) -m 644 -T $(EXAMPLE_MAKEFILE:%=%.example) "$(DATADIR)/examples/Makefile" + $(INSTALL) -m 644 $(EXAMPLE_MAKEFILE:%=%.example) "$(DATADIR)/examples/Makefile" uninstall: uninstall-libs uninstall-headers uninstall-progs uninstall-data From 3df437c2d1950239de1e20b213e7a24b78a6825a Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 29 Sep 2017 17:42:42 -0300 Subject: [PATCH 3213/3374] build: add missing changes to ensure examples build with progs-suffix --- doc/examples/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/examples/Makefile b/doc/examples/Makefile index 9792e1f911539..fe33b1768a754 100644 --- a/doc/examples/Makefile +++ b/doc/examples/Makefile @@ -33,10 +33,10 @@ $(DOC_EXAMPLES): %$(PROGSSUF)$(EXESUF): %.o examples: $(DOC_EXAMPLES) -$(DOC_EXAMPLES:%$(EXESUF)=%.o): | doc/examples +$(DOC_EXAMPLES:%$(PROGSSUF)$(EXESUF)=%.o): | doc/examples OBJDIRS += doc/examples -DOXY_INPUT += $(DOC_EXAMPLES:%$(EXESUF)=%.c) +DOXY_INPUT += $(DOC_EXAMPLES:%$(PROGSSUF)$(EXESUF)=%.c) examplesclean: $(RM) $(ALL_DOC_EXAMPLES) $(ALL_DOC_EXAMPLES_G) From 876dada0b58b5ecc80b2a25eb5c33974a71c8eb2 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Wed, 27 Sep 2017 20:48:42 -0500 Subject: [PATCH 3214/3374] avcodec/hevc_sei: Support HEVC paired fields. Correctly set the interlaced_frame and top_field_first fields when pic_struct indicates paired fields. Signed-off-by: Michael Niedermayer --- libavcodec/hevc_sei.c | 4 ++-- tests/fate/hevc.mak | 6 +++++- tests/ref/fate/hevc-paired-fields | 16 ++++++++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 tests/ref/fate/hevc-paired-fields diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c index cd55d50212547..d0f9966a295c7 100644 --- a/libavcodec/hevc_sei.c +++ b/libavcodec/hevc_sei.c @@ -137,10 +137,10 @@ static int decode_nal_sei_pic_timing(HEVCSEIContext *s, GetBitContext *gb, const if (sps->vui.frame_field_info_present_flag) { int pic_struct = get_bits(gb, 4); h->picture_struct = AV_PICTURE_STRUCTURE_UNKNOWN; - if (pic_struct == 2) { + if (pic_struct == 2 || pic_struct == 10 || pic_struct == 12) { av_log(logctx, AV_LOG_DEBUG, "BOTTOM Field\n"); h->picture_struct = AV_PICTURE_STRUCTURE_BOTTOM_FIELD; - } else if (pic_struct == 1) { + } else if (pic_struct == 1 || pic_struct == 9 || pic_struct == 11) { av_log(logctx, AV_LOG_DEBUG, "TOP Field\n"); h->picture_struct = AV_PICTURE_STRUCTURE_TOP_FIELD; } diff --git a/tests/fate/hevc.mak b/tests/fate/hevc.mak index d23d1ba9fea9c..140fa2a72eb96 100644 --- a/tests/fate/hevc.mak +++ b/tests/fate/hevc.mak @@ -225,6 +225,9 @@ $(foreach N,$(HEVC_SAMPLES_444_12BIT),$(eval $(call FATE_HEVC_TEST_444_12BIT,$(N fate-hevc-paramchange-yuv420p-yuv420p10: CMD = framecrc -vsync 0 -i $(TARGET_SAMPLES)/hevc/paramchange_yuv420p_yuv420p10.hevc -sws_flags area+accurate_rnd+bitexact FATE_HEVC += fate-hevc-paramchange-yuv420p-yuv420p10 +fate-hevc-paired-fields: CMD = probeframes -show_entries frame=interlaced_frame,top_field_first $(TARGET_SAMPLES)/hevc/paired_fields.hevc +FATE_HEVC_FFPROBE-$(call DEMDEC, HEVC, HEVC) += fate-hevc-paired-fields + tests/data/hevc-mp4.mov: TAG = GEN tests/data/hevc-mp4.mov: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data $(M)$(TARGET_EXEC) $(TARGET_PATH)/$< \ @@ -244,5 +247,6 @@ FATE_HEVC-$(call DEMDEC, MOV, HEVC) += fate-hevc-extradata-reload fate-hevc-extradata-reload: CMD = framemd5 -i $(TARGET_SAMPLES)/hevc/extradata-reload-multi-stsd.mov -sws_flags bitexact FATE_SAMPLES_AVCONV += $(FATE_HEVC-yes) +FATE_SAMPLES_FFPROBE += $(FATE_HEVC_FFPROBE-yes) -fate-hevc: $(FATE_HEVC-yes) +fate-hevc: $(FATE_HEVC-yes) $(FATE_HEVC_FFPROBE-yes) diff --git a/tests/ref/fate/hevc-paired-fields b/tests/ref/fate/hevc-paired-fields new file mode 100644 index 0000000000000..f2223e770b6fe --- /dev/null +++ b/tests/ref/fate/hevc-paired-fields @@ -0,0 +1,16 @@ +[FRAME] +interlaced_frame=1 +top_field_first=1 +[/FRAME] +[FRAME] +interlaced_frame=1 +top_field_first=0 +[/FRAME] +[FRAME] +interlaced_frame=1 +top_field_first=1 +[/FRAME] +[FRAME] +interlaced_frame=1 +top_field_first=0 +[/FRAME] From 0275bdbd2c006ca6f4af470000188f81ea626ee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ekstr=C3=B6m?= Date: Fri, 29 Sep 2017 03:03:23 +0300 Subject: [PATCH 3215/3374] MAINTAINERS: add myself to the general developers list Signed-off-by: Michael Niedermayer --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 77f48b984bdb5..412680abacc39 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -547,6 +547,7 @@ Ganesh Ajjanagadde Henrik Gramner Ivan Uskov James Darnley +Jan Ekström Joakim Plate Kieran Kunhya Kirill Gavrilov From 450cee522ec16a4375c02d3836de4893dfff26aa Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 30 Sep 2017 01:40:08 -0300 Subject: [PATCH 3216/3374] build: fix cleaning compiled unstripped examples Signed-off-by: James Almer --- doc/examples/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/examples/Makefile b/doc/examples/Makefile index fe33b1768a754..f0c4f7969e6f3 100644 --- a/doc/examples/Makefile +++ b/doc/examples/Makefile @@ -21,8 +21,9 @@ DOC_EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac DOC_EXAMPLES-$(CONFIG_TRANSCODING_EXAMPLE) += transcoding DOC_EXAMPLES := $(DOC_EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)$(EXESUF)) +DOC_EXAMPLES_G := $(DOC_EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)_g$(EXESUF)) ALL_DOC_EXAMPLES := $(DOC_EXAMPLES) $(DOC_EXAMPLES-:%=doc/examples/%$(PROGSSUF)$(EXESUF)) -ALL_DOC_EXAMPLES_G := $(DOC_EXAMPLES) $(DOC_EXAMPLES-:%=doc/examples/%$(PROGSSUF)_g$(EXESUF)) +ALL_DOC_EXAMPLES_G := $(DOC_EXAMPLES_G) $(DOC_EXAMPLES-:%=doc/examples/%$(PROGSSUF)_g$(EXESUF)) PROGS += $(DOC_EXAMPLES) EXAMPLES_FILES := $(wildcard $(SRC_PATH)/doc/examples/*.c) $(SRC_PATH)/doc/examples/README From 148c8e88c43cfbabd6aee9f01ef30942cee9d359 Mon Sep 17 00:00:00 2001 From: Ashish Singh Date: Sat, 16 Sep 2017 02:17:58 +0530 Subject: [PATCH 3217/3374] avfilter: add vmafmotion filter Signed-off-by: Ashish Singh Signed-off-by: Ronald S. Bultje --- Changelog | 1 + doc/filters.texi | 14 ++ libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/vf_vmafmotion.c | 365 ++++++++++++++++++++++++++++++++++++ libavfilter/vmaf_motion.h | 58 ++++++ 6 files changed, 440 insertions(+) create mode 100644 libavfilter/vf_vmafmotion.c create mode 100644 libavfilter/vmaf_motion.h diff --git a/Changelog b/Changelog index c64cef4c89a7a..03686acef6978 100644 --- a/Changelog +++ b/Changelog @@ -51,6 +51,7 @@ version : - CUDA thumbnail filter - V4L2 mem2mem HW assisted codecs - Rockchip MPP hardware decoding +- vmafmotion video filter version 3.3: diff --git a/doc/filters.texi b/doc/filters.texi index b09c3a0538b7e..e87b90b31080c 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -15570,6 +15570,20 @@ vignette='PI/4+random(1)*PI/50':eval=frame @end itemize +@section vmafmotion + +Obtain the average vmaf motion score of a video. +It is one of the component filters of VMAF. + +The obtained average motion score is printed through the logging system. + +In the below example the input file @file{ref.mpg} is being processed and score +is computed. + +@example +ffmpeg -i ref.mpg -lavfi vmafmotion -f null - +@end example + @section vstack Stack input videos vertically. diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 9eeb7d218f0dd..d2f0495f37114 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -331,6 +331,7 @@ OBJS-$(CONFIG_VFLIP_FILTER) += vf_vflip.o OBJS-$(CONFIG_VIDSTABDETECT_FILTER) += vidstabutils.o vf_vidstabdetect.o OBJS-$(CONFIG_VIDSTABTRANSFORM_FILTER) += vidstabutils.o vf_vidstabtransform.o OBJS-$(CONFIG_VIGNETTE_FILTER) += vf_vignette.o +OBJS-$(CONFIG_VMAFMOTION_FILTER) += vf_vmafmotion.o framesync.o OBJS-$(CONFIG_VSTACK_FILTER) += vf_stack.o framesync.o OBJS-$(CONFIG_W3FDIF_FILTER) += vf_w3fdif.o OBJS-$(CONFIG_WAVEFORM_FILTER) += vf_waveform.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index baa84a3e729d0..9b672a7a7e73f 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -342,6 +342,7 @@ static void register_all(void) REGISTER_FILTER(VIDSTABDETECT, vidstabdetect, vf); REGISTER_FILTER(VIDSTABTRANSFORM, vidstabtransform, vf); REGISTER_FILTER(VIGNETTE, vignette, vf); + REGISTER_FILTER(VMAFMOTION, vmafmotion, vf); REGISTER_FILTER(VSTACK, vstack, vf); REGISTER_FILTER(W3FDIF, w3fdif, vf); REGISTER_FILTER(WAVEFORM, waveform, vf); diff --git a/libavfilter/vf_vmafmotion.c b/libavfilter/vf_vmafmotion.c new file mode 100644 index 0000000000000..6b6150a9316d3 --- /dev/null +++ b/libavfilter/vf_vmafmotion.c @@ -0,0 +1,365 @@ +/* + * Copyright (c) 2017 Ronald S. Bultje + * Copyright (c) 2017 Ashish Pratap Singh + * + * 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 + */ + +/** + * @file + * Calculate VMAF Motion score. + */ + +#include "libavutil/opt.h" +#include "libavutil/pixdesc.h" +#include "avfilter.h" +#include "drawutils.h" +#include "formats.h" +#include "internal.h" +#include "vmaf_motion.h" + +#define BIT_SHIFT 15 + +static const float FILTER_5[5] = { + 0.054488685, + 0.244201342, + 0.402619947, + 0.244201342, + 0.054488685 +}; + +typedef struct VMAFMotionContext { + const AVClass *class; + VMAFMotionData data; + FILE *stats_file; + char *stats_file_str; +} VMAFMotionContext; + +#define OFFSET(x) offsetof(VMAFMotionContext, x) +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM + +static const AVOption vmafmotion_options[] = { + {"stats_file", "Set file where to store per-frame difference information", OFFSET(stats_file_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(vmafmotion); + +static uint64_t image_sad(const uint16_t *img1, const uint16_t *img2, int w, + int h, ptrdiff_t _img1_stride, ptrdiff_t _img2_stride) +{ + ptrdiff_t img1_stride = _img1_stride / sizeof(*img1); + ptrdiff_t img2_stride = _img2_stride / sizeof(*img2); + uint64_t sum = 0; + int i, j; + + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + sum += abs(img1[j] - img2[j]); + } + img1 += img1_stride; + img2 += img2_stride; + } + + return sum; +} + +static void convolution_x(const uint16_t *filter, int filt_w, const uint16_t *src, + uint16_t *dst, int w, int h, ptrdiff_t _src_stride, + ptrdiff_t _dst_stride) +{ + ptrdiff_t src_stride = _src_stride / sizeof(*src); + ptrdiff_t dst_stride = _dst_stride / sizeof(*dst); + int radius = filt_w / 2; + int borders_left = radius; + int borders_right = w - (filt_w - radius); + int i, j, k; + int sum = 0; + + for (i = 0; i < h; i++) { + for (j = 0; j < borders_left; j++) { + sum = 0; + for (k = 0; k < filt_w; k++) { + int j_tap = FFABS(j - radius + k); + if (j_tap >= w) { + j_tap = w - (j_tap - w + 1); + } + sum += filter[k] * src[i * src_stride + j_tap]; + } + dst[i * dst_stride + j] = sum >> BIT_SHIFT; + } + + for (j = borders_left; j < borders_right; j++) { + int sum = 0; + for (k = 0; k < filt_w; k++) { + sum += filter[k] * src[i * src_stride + j - radius + k]; + } + dst[i * dst_stride + j] = sum >> BIT_SHIFT; + } + + for (j = borders_right; j < w; j++) { + sum = 0; + for (k = 0; k < filt_w; k++) { + int j_tap = FFABS(j - radius + k); + if (j_tap >= w) { + j_tap = w - (j_tap - w + 1); + } + sum += filter[k] * src[i * src_stride + j_tap]; + } + dst[i * dst_stride + j] = sum >> BIT_SHIFT; + } + } +} + +#define conv_y_fn(type, bits) \ +static void convolution_y_##bits##bit(const uint16_t *filter, int filt_w, \ + const uint8_t *_src, uint16_t *dst, \ + int w, int h, ptrdiff_t _src_stride, \ + ptrdiff_t _dst_stride) \ +{ \ + const type *src = (const type *) _src; \ + ptrdiff_t src_stride = _src_stride / sizeof(*src); \ + ptrdiff_t dst_stride = _dst_stride / sizeof(*dst); \ + int radius = filt_w / 2; \ + int borders_top = radius; \ + int borders_bottom = h - (filt_w - radius); \ + int i, j, k; \ + int sum = 0; \ + \ + for (i = 0; i < borders_top; i++) { \ + for (j = 0; j < w; j++) { \ + sum = 0; \ + for (k = 0; k < filt_w; k++) { \ + int i_tap = FFABS(i - radius + k); \ + if (i_tap >= h) { \ + i_tap = h - (i_tap - h + 1); \ + } \ + sum += filter[k] * src[i_tap * src_stride + j]; \ + } \ + dst[i * dst_stride + j] = sum >> bits; \ + } \ + } \ + for (i = borders_top; i < borders_bottom; i++) { \ + for (j = 0; j < w; j++) { \ + sum = 0; \ + for (k = 0; k < filt_w; k++) { \ + sum += filter[k] * src[(i - radius + k) * src_stride + j]; \ + } \ + dst[i * dst_stride + j] = sum >> bits; \ + } \ + } \ + for (i = borders_bottom; i < h; i++) { \ + for (j = 0; j < w; j++) { \ + sum = 0; \ + for (k = 0; k < filt_w; k++) { \ + int i_tap = FFABS(i - radius + k); \ + if (i_tap >= h) { \ + i_tap = h - (i_tap - h + 1); \ + } \ + sum += filter[k] * src[i_tap * src_stride + j]; \ + } \ + dst[i * dst_stride + j] = sum >> bits; \ + } \ + } \ +} + +conv_y_fn(uint8_t, 8); +conv_y_fn(uint16_t, 10); + +static void vmafmotiondsp_init(VMAFMotionDSPContext *dsp, int bpp) { + dsp->convolution_x = convolution_x; + dsp->convolution_y = bpp == 10 ? convolution_y_10bit : convolution_y_8bit; + dsp->sad = image_sad; +} + +double ff_vmafmotion_process(VMAFMotionData *s, AVFrame *ref) +{ + double score; + + s->vmafdsp.convolution_y(s->filter, 5, ref->data[0], s->temp_data, + s->width, s->height, ref->linesize[0], s->stride); + s->vmafdsp.convolution_x(s->filter, 5, s->temp_data, s->blur_data[0], + s->width, s->height, s->stride, s->stride); + + if (!s->nb_frames) { + score = 0.0; + } else { + uint64_t sad = s->vmafdsp.sad(s->blur_data[1], s->blur_data[0], + s->width, s->height, s->stride, s->stride); + // the output score is always normalized to 8 bits + score = (double) (sad * 1.0 / (s->width * s->height << (BIT_SHIFT - 8))); + } + + FFSWAP(uint16_t *, s->blur_data[0], s->blur_data[1]); + s->nb_frames++; + s->motion_sum += score; + + return score; +} + +static void set_meta(AVDictionary **metadata, const char *key, float d) +{ + char value[128]; + snprintf(value, sizeof(value), "%0.2f", d); + av_dict_set(metadata, key, value, 0); +} + +static void do_vmafmotion(AVFilterContext *ctx, AVFrame *ref) +{ + VMAFMotionContext *s = ctx->priv; + double score; + + score = ff_vmafmotion_process(&s->data, ref); + set_meta(&ref->metadata, "lavfi.vmafmotion.score", score); + if (s->stats_file) { + fprintf(s->stats_file, + "n:%"PRId64" motion:%0.2lf\n", s->data.nb_frames, score); + } +} + + +int ff_vmafmotion_init(VMAFMotionData *s, + int w, int h, enum AVPixelFormat fmt) +{ + size_t data_sz; + int i; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); + + s->width = w; + s->height = h; + s->stride = FFALIGN(w * sizeof(uint16_t), 32); + + data_sz = (size_t) s->stride * h; + if (!(s->blur_data[0] = av_malloc(data_sz)) || + !(s->blur_data[1] = av_malloc(data_sz)) || + !(s->temp_data = av_malloc(data_sz))) { + return AVERROR(ENOMEM); + } + + for (i = 0; i < 5; i++) { + s->filter[i] = lrint(FILTER_5[i] * (1 << BIT_SHIFT)); + } + + vmafmotiondsp_init(&s->vmafdsp, desc->comp[0].depth); + + return 0; +} + +static int query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pix_fmts[] = { + AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, + AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV420P10, + AV_PIX_FMT_NONE + }; + + AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); + if (!fmts_list) + return AVERROR(ENOMEM); + return ff_set_common_formats(ctx, fmts_list); +} + +static int config_input_ref(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + VMAFMotionContext *s = ctx->priv; + + return ff_vmafmotion_init(&s->data, ctx->inputs[0]->w, + ctx->inputs[0]->h, ctx->inputs[0]->format); +} + +double ff_vmafmotion_uninit(VMAFMotionData *s) +{ + av_free(s->blur_data[0]); + av_free(s->blur_data[1]); + av_free(s->temp_data); + + return s->nb_frames > 0 ? s->motion_sum / s->nb_frames : 0.0; +} + +static int filter_frame(AVFilterLink *inlink, AVFrame *ref) +{ + AVFilterContext *ctx = inlink->dst; + do_vmafmotion(ctx, ref); + return ff_filter_frame(ctx->outputs[0], ref); +} + +static av_cold int init(AVFilterContext *ctx) +{ + VMAFMotionContext *s = ctx->priv; + + if (s->stats_file_str) { + if (!strcmp(s->stats_file_str, "-")) { + s->stats_file = stdout; + } else { + s->stats_file = fopen(s->stats_file_str, "w"); + if (!s->stats_file) { + int err = AVERROR(errno); + char buf[128]; + av_strerror(err, buf, sizeof(buf)); + av_log(ctx, AV_LOG_ERROR, "Could not open stats file %s: %s\n", + s->stats_file_str, buf); + return err; + } + } + } + + return 0; +} + +static av_cold void uninit(AVFilterContext *ctx) +{ + VMAFMotionContext *s = ctx->priv; + double avg_motion = ff_vmafmotion_uninit(&s->data); + + if (s->data.nb_frames > 0) { + av_log(ctx, AV_LOG_INFO, "VMAF Motion avg: %.3f\n", avg_motion); + } + + if (s->stats_file && s->stats_file != stdout) + fclose(s->stats_file); +} + +static const AVFilterPad vmafmotion_inputs[] = { + { + .name = "reference", + .type = AVMEDIA_TYPE_VIDEO, + .filter_frame = filter_frame, + .config_props = config_input_ref, + }, + { NULL } +}; + +static const AVFilterPad vmafmotion_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + }, + { NULL } +}; + +AVFilter ff_vf_vmafmotion = { + .name = "vmafmotion", + .description = NULL_IF_CONFIG_SMALL("Calculate the VMAF Motion score."), + .init = init, + .uninit = uninit, + .query_formats = query_formats, + .priv_size = sizeof(VMAFMotionContext), + .priv_class = &vmafmotion_class, + .inputs = vmafmotion_inputs, + .outputs = vmafmotion_outputs, +}; diff --git a/libavfilter/vmaf_motion.h b/libavfilter/vmaf_motion.h new file mode 100644 index 0000000000000..0c71182f95e27 --- /dev/null +++ b/libavfilter/vmaf_motion.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017 Ronald S. Bultje + * Copyright (c) 2017 Ashish Pratap Singh + * + * 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 + */ + +#ifndef AVFILTER_VMAFMOTION_H +#define AVFILTER_VMAFMOTION_H + +#include +#include +#include "video.h" + +typedef struct VMAFMotionDSPContext { + uint64_t (*sad)(const uint16_t *img1, const uint16_t *img2, int w, int h, + ptrdiff_t img1_stride, ptrdiff_t img2_stride); + void (*convolution_x)(const uint16_t *filter, int filt_w, const uint16_t *src, + uint16_t *dst, int w, int h, ptrdiff_t src_stride, + ptrdiff_t dst_stride); + void (*convolution_y)(const uint16_t *filter, int filt_w, const uint8_t *src, + uint16_t *dst, int w, int h, ptrdiff_t src_stride, + ptrdiff_t dst_stride); +} VMAFMotionDSPContext; + +void ff_vmafmotion_init_x86(VMAFMotionDSPContext *dsp); + +typedef struct VMAFMotionData { + uint16_t filter[5]; + int width; + int height; + ptrdiff_t stride; + uint16_t *blur_data[2 /* cur, prev */]; + uint16_t *temp_data; + double motion_sum; + uint64_t nb_frames; + VMAFMotionDSPContext vmafdsp; +} VMAFMotionData; + +int ff_vmafmotion_init(VMAFMotionData *data, int w, int h, enum AVPixelFormat fmt); +double ff_vmafmotion_process(VMAFMotionData *data, AVFrame *frame); +double ff_vmafmotion_uninit(VMAFMotionData *data); + +#endif /* AVFILTER_VMAFMOTION_H */ From 67057aaeb23d84144b2b371547fd46e915be238f Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 30 Sep 2017 15:38:09 -0300 Subject: [PATCH 3218/3374] avfilter/vmaf_motion: use correct header guards Fixes fate-source Signed-off-by: James Almer --- libavfilter/vmaf_motion.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavfilter/vmaf_motion.h b/libavfilter/vmaf_motion.h index 0c71182f95e27..09984506824f6 100644 --- a/libavfilter/vmaf_motion.h +++ b/libavfilter/vmaf_motion.h @@ -19,8 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef AVFILTER_VMAFMOTION_H -#define AVFILTER_VMAFMOTION_H +#ifndef AVFILTER_VMAF_MOTION_H +#define AVFILTER_VMAF_MOTION_H #include #include @@ -55,4 +55,4 @@ int ff_vmafmotion_init(VMAFMotionData *data, int w, int h, enum AVPixelFormat fm double ff_vmafmotion_process(VMAFMotionData *data, AVFrame *frame); double ff_vmafmotion_uninit(VMAFMotionData *data); -#endif /* AVFILTER_VMAFMOTION_H */ +#endif /* AVFILTER_VMAF_MOTION_H */ From e9f9175db60ac67e906f8ad0709129843ab41d14 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Fri, 29 Sep 2017 19:10:46 +0200 Subject: [PATCH 3219/3374] lavf/bit: Fix the G.729 bit auto-detection. --- libavformat/bit.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/libavformat/bit.c b/libavformat/bit.c index d742a5b3639be..76aae2d4a10ed 100644 --- a/libavformat/bit.c +++ b/libavformat/bit.c @@ -32,20 +32,23 @@ #if CONFIG_BIT_DEMUXER static int probe(AVProbeData *p) { - int i, j; + int i = 0, j, valid = 0; - if(p->buf_size < 0x40) - return 0; - - for(i=0; i+3buf_size && i< 10*0x50; ){ - if(AV_RL16(&p->buf[0]) != SYNC_WORD) + while (2 * i + 3 < p->buf_size){ + if (AV_RL16(&p->buf[2 * i++]) != SYNC_WORD) return 0; - j=AV_RL16(&p->buf[2]); - if(j!=0x40 && j!=0x50) + j = AV_RL16(&p->buf[2 * i++]); + if (j != 0 && j != 0x10 && j != 0x40 && j != 0x50 && j != 0x76) return 0; - i+=j; + if (j) + valid++; + i += j; } - return AVPROBE_SCORE_EXTENSION; + if (valid > 10) + return AVPROBE_SCORE_MAX; + if (valid > 2) + return AVPROBE_SCORE_EXTENSION - 1; + return 0; } static int read_header(AVFormatContext *s) From 64e034da954125ef98fb8f9153f9706cdb8a96fe Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 4 Sep 2017 22:23:26 +0200 Subject: [PATCH 3220/3374] avcodec/jpeg2000: Check that codsty->log2_prec_widths/heights has been initialized Fixes: OOM Fixes: 2225/clusterfuzz-testcase-minimized-5505632079708160 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/jpeg2000.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavcodec/jpeg2000.c b/libavcodec/jpeg2000.c index 94efc94c4df44..afeb9df27c408 100644 --- a/libavcodec/jpeg2000.c +++ b/libavcodec/jpeg2000.c @@ -506,6 +506,9 @@ int ff_jpeg2000_init_component(Jpeg2000Component *comp, // update precincts size: 2^n value reslevel->log2_prec_width = codsty->log2_prec_widths[reslevelno]; reslevel->log2_prec_height = codsty->log2_prec_heights[reslevelno]; + if (!reslevel->log2_prec_width || !reslevel->log2_prec_height) { + return AVERROR_INVALIDDATA; + } /* Number of bands for each resolution level */ if (reslevelno == 0) From 4bb80133356b67f5065883d05d474d67cfee1dd8 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 29 Sep 2017 02:28:42 +0200 Subject: [PATCH 3221/3374] avcodec/v4l2_buffers: More clear return code documentation Signed-off-by: Michael Niedermayer --- libavcodec/v4l2_buffers.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libavcodec/v4l2_buffers.h b/libavcodec/v4l2_buffers.h index b16f694b98c08..e28a4a650d763 100644 --- a/libavcodec/v4l2_buffers.h +++ b/libavcodec/v4l2_buffers.h @@ -65,8 +65,8 @@ typedef struct V4L2Buffer { * @param[in] frame The AVFRame to push the information to * @param[in] buf The V4L2Buffer to get the information from * - * @returns 0 in case of success, EINVAL if the number of planes is incorrect, - * ENOMEM if the AVBufferRef cant be created. + * @returns 0 in case of success, AVERROR(EINVAL) if the number of planes is incorrect, + * AVERROR(ENOMEM) if the AVBufferRef cant be created. */ int ff_v4l2_buffer_buf_to_avframe(AVFrame *frame, V4L2Buffer *buf); @@ -76,8 +76,8 @@ int ff_v4l2_buffer_buf_to_avframe(AVFrame *frame, V4L2Buffer *buf); * @param[in] pkt The AVPacket to push the information to * @param[in] buf The V4L2Buffer to get the information from * - * @returns 0 in case of success, EINVAL if the number of planes is incorrect, - * ENOMEM if the AVBufferRef cant be created. + * @returns 0 in case of success, AVERROR(EINVAL) if the number of planes is incorrect, + * AVERROR(ENOMEM) if the AVBufferRef cant be created. * */ int ff_v4l2_buffer_buf_to_avpkt(AVPacket *pkt, V4L2Buffer *buf); @@ -88,7 +88,7 @@ int ff_v4l2_buffer_buf_to_avpkt(AVPacket *pkt, V4L2Buffer *buf); * @param[in] frame AVPacket to get the data from * @param[in] avbuf V4L2Bfuffer to push the information to * - * @returns 0 in case of success, negative otherwise + * @returns 0 in case of success, a negative AVERROR code otherwise */ int ff_v4l2_buffer_avpkt_to_buf(const AVPacket *pkt, V4L2Buffer *out); @@ -98,7 +98,7 @@ int ff_v4l2_buffer_avpkt_to_buf(const AVPacket *pkt, V4L2Buffer *out); * @param[in] frame AVFrame to get the data from * @param[in] avbuf V4L2Bfuffer to push the information to * - * @returns 0 in case of success, negative otherwise + * @returns 0 in case of success, a negative AVERROR code otherwise */ int ff_v4l2_buffer_avframe_to_buf(const AVFrame *frame, V4L2Buffer* out); @@ -108,7 +108,7 @@ int ff_v4l2_buffer_avframe_to_buf(const AVFrame *frame, V4L2Buffer* out); * @param[in] avbuf V4L2Bfuffer to initialize * @param[in] index v4l2 buffer id * - * @returns 0 in case of success, negative otherwise + * @returns 0 in case of success, a negative AVERROR code otherwise */ int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index); @@ -117,7 +117,7 @@ int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index); * * @param[in] avbuf V4L2Bfuffer to push to the driver * - * @returns 0 in case of success, negative otherwise + * @returns 0 in case of success, a negative AVERROR code otherwise */ int ff_v4l2_buffer_enqueue(V4L2Buffer* avbuf); From b81b8a76b54cf6c8e4953463117d3c8153e1b067 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 29 Sep 2017 02:28:43 +0200 Subject: [PATCH 3222/3374] avcodec/v4l2_context: Reduce spelling variations Reviewed-by: Lou Logan Signed-off-by: Michael Niedermayer --- libavcodec/v4l2_context.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c index d675c55f2bbc9..297792f871036 100644 --- a/libavcodec/v4l2_context.c +++ b/libavcodec/v4l2_context.c @@ -112,7 +112,7 @@ static inline void v4l2_save_to_context(V4L2Context* ctx, struct v4l2_format_upd } /** - * returns 1 if reinit was succesful, negative if it failed + * returns 1 if reinit was successful, negative if it failed * returns 0 if reinit was not executed */ static int v4l2_handle_event(V4L2Context *ctx) @@ -266,7 +266,7 @@ static V4L2Buffer* v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout) return NULL; } if (ret) { - /* if re-init was successfull drop the buffer (if there was one) + /* if re-init was successful drop the buffer (if there was one) * since we had to reconfigure capture (unmap all buffers) */ return NULL; From d679f3d021787014f4e188f3694393f183061278 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 29 Sep 2017 02:28:44 +0200 Subject: [PATCH 3223/3374] avfilter/vf_thumbnail_cuda: Avoid mixing declaration and statements Signed-off-by: Michael Niedermayer --- libavfilter/vf_thumbnail_cuda.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavfilter/vf_thumbnail_cuda.c b/libavfilter/vf_thumbnail_cuda.c index 4c08a85121341..09377ca7f400c 100644 --- a/libavfilter/vf_thumbnail_cuda.c +++ b/libavfilter/vf_thumbnail_cuda.c @@ -269,7 +269,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) if (hw_frames_ctx->sw_format == AV_PIX_FMT_NV12 || hw_frames_ctx->sw_format == AV_PIX_FMT_YUV420P || hw_frames_ctx->sw_format == AV_PIX_FMT_P010LE || hw_frames_ctx->sw_format == AV_PIX_FMT_P016LE) { - for (int i = 256; i < HIST_SIZE; i++) + int i; + for (i = 256; i < HIST_SIZE; i++) hist[i] = 4 * hist[i]; } From 54ce880a4646541b53921ec3720086db22643e03 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sun, 1 Oct 2017 12:57:48 -0300 Subject: [PATCH 3224/3374] Partially revert "Merge commit '71a49fe25f2e4468fbbadbebef8d073b1b3cc1a5'" Revert back to the test as done by commit af7a75cb517141f649cbbe0a9dcdb4854359b740, where it was changed to compile and not just preprocess to fix build failures on FreeBSD with gcc 4.7 Signed-off-by: James Almer --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 8e4775be8cebc..ae0eddac6cb6d 100755 --- a/configure +++ b/configure @@ -4833,7 +4833,7 @@ check_cxxflags -std=c++11 || check_cxxflags -std=c++0x # some compilers silently accept -std=c11, so we also need to check that the # version macro is defined properly -check_cpp_condition ctype.h "__STDC_VERSION__ >= 201112L" -std=c11 && +test_cflags_cc -std=c11 ctype.h "__STDC_VERSION__ >= 201112L" && add_cflags -std=c11 || check_cflags -std=c99 From 9e271e3fa3f9ccee70ca3cb21c7c1bd7e871f464 Mon Sep 17 00:00:00 2001 From: Karthick J Date: Fri, 29 Sep 2017 09:00:55 +0530 Subject: [PATCH 3225/3374] avdevice/decklink_dec: Used av_parity instead of duplicated function --- libavdevice/decklink_dec.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index 3ce2cab5f4d8b..8a140944747c7 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -106,14 +106,6 @@ static int get_vanc_line_idx(BMDDisplayMode mode) return i - 1; } -static inline uint16_t parity (uint16_t x) -{ - uint16_t i; - for (i = 4 * sizeof (x); i > 0; i /= 2) - x ^= x >> i; - return x & 1; -} - static inline void clear_parity_bits(uint16_t *buf, int len) { int i; for (i = 0; i < len; i++) @@ -126,7 +118,7 @@ static int check_vanc_parity_checksum(uint16_t *buf, int len, uint16_t checksum) for (i = 3; i < len - 1; i++) { uint16_t v = buf[i]; int np = v >> 8; - int p = parity(v & 0xff); + int p = av_parity(v & 0xff); if ((!!p ^ !!(v & 0x100)) || (np != 1 && np != 2)) { // Parity check failed return -1; From 59924d5eb11646f82f70c206be8a867468f102b9 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Sat, 30 Sep 2017 21:39:08 +0200 Subject: [PATCH 3226/3374] lavfi/vmafmotion: Allow more pix_fmts. --- libavfilter/vf_vmafmotion.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/libavfilter/vf_vmafmotion.c b/libavfilter/vf_vmafmotion.c index 6b6150a9316d3..9bcc4ff16fd9b 100644 --- a/libavfilter/vf_vmafmotion.c +++ b/libavfilter/vf_vmafmotion.c @@ -261,15 +261,19 @@ int ff_vmafmotion_init(VMAFMotionData *s, static int query_formats(AVFilterContext *ctx) { - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, - AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV420P10, - AV_PIX_FMT_NONE - }; - - AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); - if (!fmts_list) - return AVERROR(ENOMEM); + AVFilterFormats *fmts_list = NULL; + int format, ret; + + for (format = 0; av_pix_fmt_desc_get(format); format++) { + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format); + if (!(desc->flags & (AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_HWACCEL | AV_PIX_FMT_FLAG_BITSTREAM | AV_PIX_FMT_FLAG_PAL)) && + (desc->flags & AV_PIX_FMT_FLAG_PLANAR || desc->nb_components == 1) && + (!(desc->flags & AV_PIX_FMT_FLAG_BE) == !HAVE_BIGENDIAN || desc->comp[0].depth == 8) && + (desc->comp[0].depth == 8 || desc->comp[0].depth == 10) && + (ret = ff_add_format(&fmts_list, format)) < 0) + return ret; + } + return ff_set_common_formats(ctx, fmts_list); } From ac5908b13f16cbda396730c35f5f3125ca24577a Mon Sep 17 00:00:00 2001 From: Martin Vignali Date: Sun, 1 Oct 2017 21:37:15 +0200 Subject: [PATCH 3227/3374] libavcodec/exr : add x86 SIMD for predictor Signed-off-by: James Almer --- libavcodec/exr.c | 16 ++-------- libavcodec/exrdsp.c | 9 ++++++ libavcodec/exrdsp.h | 1 + libavcodec/x86/exrdsp.asm | 62 +++++++++++++++++++++++++++++++++++- libavcodec/x86/exrdsp_init.c | 13 ++++++++ tests/checkasm/exrdsp.c | 23 +++++++++++++ 6 files changed, 109 insertions(+), 15 deletions(-) diff --git a/libavcodec/exr.c b/libavcodec/exr.c index 230d5bbca8c15..0b755db3cb3e8 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -265,18 +265,6 @@ static inline uint16_t exr_halflt2uint(uint16_t v) return (v + (1 << 16)) >> (exp + 1); } -static void predictor(uint8_t *src, int size) -{ - uint8_t *t = src + 1; - uint8_t *stop = src + size; - - while (t < stop) { - int d = (int) t[-1] + (int) t[0] - 128; - t[0] = d; - ++t; - } -} - static int zip_uncompress(EXRContext *s, const uint8_t *src, int compressed_size, int uncompressed_size, EXRThreadData *td) { @@ -288,7 +276,7 @@ static int zip_uncompress(EXRContext *s, const uint8_t *src, int compressed_size av_assert1(uncompressed_size % 2 == 0); - predictor(td->tmp, uncompressed_size); + s->dsp.predictor(td->tmp, uncompressed_size); s->dsp.reorder_pixels(td->uncompressed_data, td->tmp, uncompressed_size); return 0; @@ -335,7 +323,7 @@ static int rle_uncompress(EXRContext *ctx, const uint8_t *src, int compressed_si av_assert1(uncompressed_size % 2 == 0); - predictor(td->tmp, uncompressed_size); + ctx->dsp.predictor(td->tmp, uncompressed_size); ctx->dsp.reorder_pixels(td->uncompressed_data, td->tmp, uncompressed_size); return 0; diff --git a/libavcodec/exrdsp.c b/libavcodec/exrdsp.c index 871b6f1276d28..42dbf1f54a7d0 100644 --- a/libavcodec/exrdsp.c +++ b/libavcodec/exrdsp.c @@ -38,9 +38,18 @@ static void reorder_pixels_scalar(uint8_t *dst, const uint8_t *src, ptrdiff_t si } } +static void predictor_scalar(uint8_t *src, ptrdiff_t size) +{ + ptrdiff_t i; + + for (i = 1; i < size; i++) + src[i] += src[i-1] - 128; +} + av_cold void ff_exrdsp_init(ExrDSPContext *c) { c->reorder_pixels = reorder_pixels_scalar; + c->predictor = predictor_scalar; if (ARCH_X86) ff_exrdsp_init_x86(c); diff --git a/libavcodec/exrdsp.h b/libavcodec/exrdsp.h index d8cb002efcdb2..2c4dc3af888c0 100644 --- a/libavcodec/exrdsp.h +++ b/libavcodec/exrdsp.h @@ -24,6 +24,7 @@ typedef struct ExrDSPContext { void (*reorder_pixels)(uint8_t *dst, const uint8_t *src, ptrdiff_t size); + void (*predictor)(uint8_t *src, ptrdiff_t size); } ExrDSPContext; void ff_exrdsp_init(ExrDSPContext *c); diff --git a/libavcodec/x86/exrdsp.asm b/libavcodec/x86/exrdsp.asm index 06c629e59eef9..23c9397ef8f84 100644 --- a/libavcodec/x86/exrdsp.asm +++ b/libavcodec/x86/exrdsp.asm @@ -2,9 +2,11 @@ ;* X86 Optimized functions for Open Exr Decoder ;* Copyright (c) 2006 Industrial Light & Magic, a division of Lucas Digital Ltd. LLC ;* -;* reorder_pixels based on patch by John Loy +;* reorder_pixels, predictor based on patch by John Loy ;* port to ASM by Jokyo Images support by CNC - French National Center for Cinema ;* +;* predictor AVX/AVX2 by Henrik Gramner +;* ;* This file is part of FFmpeg. ;* ;* FFmpeg is free software; you can redistribute it and/or @@ -24,6 +26,9 @@ %include "libavutil/x86/x86util.asm" +cextern pb_15 +cextern pb_80 + SECTION .text ;------------------------------------------------------------------------------ @@ -60,3 +65,58 @@ REORDER_PIXELS INIT_YMM avx2 REORDER_PIXELS %endif + + +;------------------------------------------------------------------------------ +; void ff_predictor(uint8_t *src, ptrdiff_t size); +;------------------------------------------------------------------------------ + +%macro PREDICTOR 0 +cglobal predictor, 2,2,5, src, size +%if mmsize == 32 + vbroadcasti128 m0, [pb_80] +%else + mova xm0, [pb_80] +%endif + mova xm1, [pb_15] + mova xm2, xm0 + add srcq, sizeq + neg sizeq +.loop: + pxor m3, m0, [srcq + sizeq] + pslldq m4, m3, 1 + paddb m3, m4 + pslldq m4, m3, 2 + paddb m3, m4 + pslldq m4, m3, 4 + paddb m3, m4 + pslldq m4, m3, 8 +%if mmsize == 32 + paddb m3, m4 + paddb xm2, xm3 + vextracti128 xm4, m3, 1 + mova [srcq + sizeq], xm2 + pshufb xm2, xm1 + paddb xm2, xm4 + mova [srcq + sizeq + 16], xm2 +%else + paddb m2, m3 + paddb m2, m4 + mova [srcq + sizeq], m2 +%endif + pshufb xm2, xm1 + add sizeq, mmsize + jl .loop + RET +%endmacro + +INIT_XMM ssse3 +PREDICTOR + +INIT_XMM avx +PREDICTOR + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +PREDICTOR +%endif diff --git a/libavcodec/x86/exrdsp_init.c b/libavcodec/x86/exrdsp_init.c index 5669be3d9728e..63b3480d8ff5a 100644 --- a/libavcodec/x86/exrdsp_init.c +++ b/libavcodec/x86/exrdsp_init.c @@ -26,6 +26,12 @@ void ff_reorder_pixels_sse2(uint8_t *dst, const uint8_t *src, ptrdiff_t size); void ff_reorder_pixels_avx2(uint8_t *dst, const uint8_t *src, ptrdiff_t size); +void ff_predictor_ssse3(uint8_t *src, ptrdiff_t size); + +void ff_predictor_avx(uint8_t *src, ptrdiff_t size); + +void ff_predictor_avx2(uint8_t *src, ptrdiff_t size); + av_cold void ff_exrdsp_init_x86(ExrDSPContext *dsp) { int cpu_flags = av_get_cpu_flags(); @@ -33,7 +39,14 @@ av_cold void ff_exrdsp_init_x86(ExrDSPContext *dsp) if (EXTERNAL_SSE2(cpu_flags)) { dsp->reorder_pixels = ff_reorder_pixels_sse2; } + if (EXTERNAL_SSSE3(cpu_flags)) { + dsp->predictor = ff_predictor_ssse3; + } + if (EXTERNAL_AVX(cpu_flags)) { + dsp->predictor = ff_predictor_avx; + } if (EXTERNAL_AVX2_FAST(cpu_flags)) { dsp->reorder_pixels = ff_reorder_pixels_avx2; + dsp->predictor = ff_predictor_avx2; } } diff --git a/tests/checkasm/exrdsp.c b/tests/checkasm/exrdsp.c index 6637f6fdd2e66..754a079f83450 100644 --- a/tests/checkasm/exrdsp.c +++ b/tests/checkasm/exrdsp.c @@ -55,6 +55,24 @@ static void check_reorder_pixels(void) { bench_new(dst_new, src, BUF_SIZE); } +static void check_predictor(void) { + LOCAL_ALIGNED_32(uint8_t, src, [PADDED_BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst_ref, [PADDED_BUF_SIZE]); + LOCAL_ALIGNED_32(uint8_t, dst_new, [PADDED_BUF_SIZE]); + + declare_func(void, uint8_t *src, ptrdiff_t size); + + memset(src, 0, PADDED_BUF_SIZE); + randomize_buffers(); + memcpy(dst_ref, src, PADDED_BUF_SIZE); + memcpy(dst_new, src, PADDED_BUF_SIZE); + call_ref(dst_ref, BUF_SIZE); + call_new(dst_new, BUF_SIZE); + if (memcmp(dst_ref, dst_new, BUF_SIZE)) + fail(); + bench_new(dst_new, BUF_SIZE); +} + void checkasm_check_exrdsp(void) { ExrDSPContext h; @@ -65,4 +83,9 @@ void checkasm_check_exrdsp(void) check_reorder_pixels(); report("reorder_pixels"); + + if (check_func(h.predictor, "predictor")) + check_predictor(); + + report("predictor"); } From 2f7ca0b94e49c2bfce8bda3f883766101ebd7a9b Mon Sep 17 00:00:00 2001 From: James Almer Date: Sun, 1 Oct 2017 18:19:14 -0300 Subject: [PATCH 3228/3374] tools/ismindex: remove unused header --- tools/ismindex.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/ismindex.c b/tools/ismindex.c index c16e2f2670646..0254a98ff71ec 100644 --- a/tools/ismindex.c +++ b/tools/ismindex.c @@ -47,8 +47,6 @@ #include #include -#include "cmdutils.h" - #include "libavformat/avformat.h" #include "libavformat/isom.h" #include "libavformat/os_support.h" From cf3d2d52b59ddfc2a7c65a8e66f7698c4b837e51 Mon Sep 17 00:00:00 2001 From: James Almer Date: Mon, 25 Sep 2017 17:17:12 -0300 Subject: [PATCH 3229/3374] avcodec/avpacket: deprecate av_copy_packet_side_data() It leaks memory and destroys the dst packet in case of failure, and it ultimately duplicates functionality already existing in the saner av_packet_copy_props(). Reviewed-by: wm4 Signed-off-by: James Almer --- libavcodec/avcodec.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index dd7c4b4ce5e0b..52cc5b0ca08ad 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -4632,7 +4632,10 @@ int av_copy_packet(AVPacket *dst, const AVPacket *src); * Copy packet side data * * @return 0 on success, negative AVERROR on fail + * + * @deprecated Use av_packet_copy_props */ +attribute_deprecated int av_copy_packet_side_data(AVPacket *dst, const AVPacket *src); /** From a22c6a4796ca1f2cbee6784262515da876fbec22 Mon Sep 17 00:00:00 2001 From: James Almer Date: Tue, 26 Sep 2017 00:24:29 -0300 Subject: [PATCH 3230/3374] avcodec/encode: remove usage of av_dup_packet() Reviewed-by: wm4 Signed-off-by: James Almer --- libavcodec/encode.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/libavcodec/encode.c b/libavcodec/encode.c index 525ee1f5d64b6..dd50486bcfeb8 100644 --- a/libavcodec/encode.c +++ b/libavcodec/encode.c @@ -222,10 +222,12 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, } avpkt->buf = user_pkt.buf; avpkt->data = user_pkt.data; - } else { - if (av_dup_packet(avpkt) < 0) { - ret = AVERROR(ENOMEM); - } + } else if (!avpkt->buf) { + AVPacket tmp = { 0 }; + ret = av_packet_ref(&tmp, avpkt); + if (ret < 0) + return ret; + *avpkt = tmp; } } @@ -318,10 +320,12 @@ int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, } avpkt->buf = user_pkt.buf; avpkt->data = user_pkt.data; - } else { - if (av_dup_packet(avpkt) < 0) { - ret = AVERROR(ENOMEM); - } + } else if (!avpkt->buf) { + AVPacket tmp = { 0 }; + ret = av_packet_ref(&tmp, avpkt); + if (ret < 0) + return ret; + *avpkt = tmp; } } From 0c1ffd0aa55c6cef6dffe2b736786c6cb86d8a3d Mon Sep 17 00:00:00 2001 From: James Almer Date: Sun, 1 Oct 2017 23:31:12 -0300 Subject: [PATCH 3231/3374] avdevice/decklink_dec: use av_packet_add_side_data() It uses the existing buffer instead of allocating a new one. Reviewed-by: Marton Balint Signed-off-by: James Almer --- libavdevice/decklink_dec.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index 8a140944747c7..9d12d0fed0ed5 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -390,10 +390,8 @@ uint8_t *get_metadata(AVFormatContext *avctx, uint16_t *buf, size_t width, clear_parity_bits(buf, len); data = vanc_to_cc(avctx, buf, width, data_len); if (data) { - uint8_t *pkt_cc = av_packet_new_side_data(pkt, AV_PKT_DATA_A53_CC, data_len); - if (pkt_cc) - memcpy(pkt_cc, data, data_len); - av_free(data); + if (av_packet_add_side_data(pkt, AV_PKT_DATA_A53_CC, data, data_len) < 0) + av_free(data); } } else { av_log(avctx, AV_LOG_DEBUG, "Unknown meta data DID = 0x%.2x SDID = 0x%.2x\n", From e91f0c4f8b3e81bc63838cc67370a7b13c8d9e78 Mon Sep 17 00:00:00 2001 From: James Almer Date: Mon, 2 Oct 2017 13:08:39 -0300 Subject: [PATCH 3232/3374] avdevice/decklink_dec: remove av_dup_packet() usage Reviewed-by: Marton Balint Signed-off-by: James Almer --- libavdevice/decklink_dec.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index 9d12d0fed0ed5..53ff576ec5975 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -450,22 +450,24 @@ static unsigned long long avpacket_queue_size(AVPacketQueue *q) static int avpacket_queue_put(AVPacketQueue *q, AVPacket *pkt) { AVPacketList *pkt1; + int ret; // Drop Packet if queue size is > maximum queue size if (avpacket_queue_size(q) > (uint64_t)q->max_q_size) { av_log(q->avctx, AV_LOG_WARNING, "Decklink input buffer overrun!\n"); return -1; } - /* duplicate the packet */ - if (av_dup_packet(pkt) < 0) { - return -1; - } - pkt1 = (AVPacketList *)av_malloc(sizeof(AVPacketList)); + pkt1 = (AVPacketList *)av_mallocz(sizeof(AVPacketList)); if (!pkt1) { return -1; } - pkt1->pkt = *pkt; + ret = av_packet_ref(&pkt1->pkt, pkt); + av_packet_unref(pkt); + if (ret < 0) { + av_free(pkt1); + return -1; + } pkt1->next = NULL; pthread_mutex_lock(&q->mutex); From 712ee85816ef854761f30ea57ea628997bd62e60 Mon Sep 17 00:00:00 2001 From: James Almer Date: Mon, 2 Oct 2017 18:58:39 -0300 Subject: [PATCH 3233/3374] avcodec/encode: free non-referenced packets' side data in the old encode API functions Fixes memleaks introduced by a22c6a4796ca1f2cbee6784262515da876fbec22. --- libavcodec/encode.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/encode.c b/libavcodec/encode.c index dd50486bcfeb8..c152228c920e9 100644 --- a/libavcodec/encode.c +++ b/libavcodec/encode.c @@ -227,6 +227,7 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, ret = av_packet_ref(&tmp, avpkt); if (ret < 0) return ret; + av_packet_unref(avpkt); *avpkt = tmp; } } @@ -325,6 +326,7 @@ int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, ret = av_packet_ref(&tmp, avpkt); if (ret < 0) return ret; + av_packet_unref(avpkt); *avpkt = tmp; } } From aa4fe27657462742943dfbd185a18c223ae4dca3 Mon Sep 17 00:00:00 2001 From: James Almer Date: Mon, 2 Oct 2017 21:40:59 -0300 Subject: [PATCH 3234/3374] fate: disable fate-svq3-2 The first frame changes depending on --enable-memory-poisoning being used to configure ffmpeg or not, even if requesting bitexact decoding. Disable the test until this is fixed. Signed-off-by: James Almer --- tests/fate/qt.mak | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/fate/qt.mak b/tests/fate/qt.mak index 2a7fc2e0fac48..c054129f082eb 100644 --- a/tests/fate/qt.mak +++ b/tests/fate/qt.mak @@ -52,7 +52,8 @@ fate-svq1-headerswap: CMD = framecrc -i $(TARGET_SAMPLES)/svq1/ct_ending_cut.mov FATE_SVQ3 += fate-svq3-1 fate-svq3-1: CMD = framecrc -i $(TARGET_SAMPLES)/svq3/Vertical400kbit.sorenson3.mov -t 6 -an -FATE_SVQ3 += fate-svq3-2 +#FATE_SVQ3 += fate-svq3-2 +#FIXME: first frame changes depending on --enable-memory-poisoning being used to configure or not fate-svq3-2: CMD = framecrc -flags +bitexact -ignore_editlist 1 -i $(TARGET_SAMPLES)/svq3/svq3_decoding_regression.mov -an FATE_SVQ3 += fate-svq3-watermark From 3e6829a8aa1ec687086669551aee45743ac25691 Mon Sep 17 00:00:00 2001 From: James Almer Date: Tue, 3 Oct 2017 10:55:59 -0300 Subject: [PATCH 3235/3374] build: fix compilation of tools with OpenCL enabled Signed-off-by: James Almer --- fftools/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fftools/Makefile b/fftools/Makefile index 094f6d6265a1a..c867814a71cb7 100644 --- a/fftools/Makefile +++ b/fftools/Makefile @@ -20,7 +20,6 @@ OBJS-ffmpeg-$(CONFIG_VIDEOTOOLBOX) += fftools/ffmpeg_videotoolbox.o OBJS-ffserver += fftools/ffserver_config.o define DOFFTOOL -OBJS-$(1)-$(CONFIG_OPENCL) += fftools/cmdutils_opencl.o OBJS-$(1) += fftools/cmdutils.o fftools/$(1).o $(OBJS-$(1)-yes) $(1)$(PROGSSUF)_g$(EXESUF): $$(OBJS-$(1)) $$(OBJS-$(1)): | fftools @@ -30,6 +29,7 @@ $(1)$(PROGSSUF)_g$(EXESUF): FF_EXTRALIBS += $(EXTRALIBS-$(1)) -include $$(OBJS-$(1):.o=.d) endef +$(foreach P,$(AVPROGS-yes),$(eval OBJS-$(P)-$(CONFIG_OPENCL) += fftools/cmdutils_opencl.o)) $(foreach P,$(AVPROGS-yes),$(eval $(call DOFFTOOL,$(P)))) all: $(AVPROGS) From a56ec48d426f98702e7c6f76bdb5f036df56de4b Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 12 Sep 2017 21:20:02 +0200 Subject: [PATCH 3236/3374] avformat/mxfenc: Add IEC DV25 Signed-off-by: Michael Niedermayer --- libavformat/mxfenc.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index b8d3030c40316..3da96bf91980f 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -119,6 +119,8 @@ enum ULIndex { INDEX_DV, INDEX_DV25_525_60, INDEX_DV25_625_50, + INDEX_DV25_525_60_IEC, + INDEX_DV25_625_50_IEC, INDEX_DV50_525_60, INDEX_DV50_625_50, INDEX_DV100_1080_60, @@ -231,6 +233,7 @@ static const MXFContainerEssenceEntry mxf_essence_container_uls[] = { { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x00,0x00,0x00 }, mxf_write_cdci_desc }, + // DV25 525/60 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x40,0x01 }, { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, @@ -241,7 +244,19 @@ static const MXFContainerEssenceEntry mxf_essence_container_uls[] = { { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x02,0x00 }, mxf_write_cdci_desc }, - // DV50 525/60 + + // IEC DV25 525/60 + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x01,0x01 }, + { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, + { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x01,0x00 }, + mxf_write_cdci_desc }, + // IEC DV25 625/50 + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x02,0x01 }, + { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, + { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x01,0x02,0x00 }, + mxf_write_cdci_desc }, + + // DV50 525/60 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x50,0x01 }, { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x03,0x00 }, From ef973bd98d8ee35dbbdd622b075c50d11c0d67fd Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 12 Sep 2017 22:17:12 +0200 Subject: [PATCH 3237/3374] avformat/mxfenc: Fix labels for IEC PAL DV 420 --- libavformat/mxfenc.c | 9 +++++++++ tests/ref/lavf/mxf_dv25 | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index 3da96bf91980f..035e65ed43a0b 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -48,6 +48,7 @@ #include "libavutil/time_internal.h" #include "libavcodec/bytestream.h" #include "libavcodec/dnxhddata.h" +#include "libavcodec/dv_profile.h" #include "libavcodec/h264.h" #include "libavcodec/internal.h" #include "audiointerleave.h" @@ -1812,6 +1813,7 @@ static int mxf_parse_dv_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt) MXFStreamContext *sc = st->priv_data; uint8_t *vs_pack, *vsc_pack; int i, ul_index, frame_size, stype, pal; + const AVDVProfile *profile; if (mxf->header_written) return 1; @@ -1820,6 +1822,8 @@ static int mxf_parse_dv_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt) if (pkt->size < 120000) return -1; + profile = av_dv_frame_profile(NULL, pkt->data, pkt->size); + vs_pack = pkt->data + 80*5 + 48; vsc_pack = pkt->data + 80*5 + 53; stype = vs_pack[3] & 0x1f; @@ -1854,6 +1858,11 @@ static int mxf_parse_dv_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt) frame_size = pal ? 288000 : 240000; break; default: // DV25 + if (profile && profile->pix_fmt == AV_PIX_FMT_YUV420P && pal) { + ul_index = INDEX_DV25_525_60_IEC + pal; + frame_size = pal ? 144000 : 120000; + break; + } ul_index = INDEX_DV25_525_60 + pal; frame_size = pal ? 144000 : 120000; } diff --git a/tests/ref/lavf/mxf_dv25 b/tests/ref/lavf/mxf_dv25 index adecc07e70cda..85094828d15f7 100644 --- a/tests/ref/lavf/mxf_dv25 +++ b/tests/ref/lavf/mxf_dv25 @@ -1,3 +1,3 @@ -de98603ecc27c2f3cefd192d4820d3f4 *./tests/data/lavf/lavf.mxf_dv25 +1871bd11947924116776201f24fd0adf *./tests/data/lavf/lavf.mxf_dv25 3833389 ./tests/data/lavf/lavf.mxf_dv25 ./tests/data/lavf/lavf.mxf_dv25 CRC=0xbdaf7f52 From 87e625c2633a83f62f155fcca33dab0a6e2bb5e6 Mon Sep 17 00:00:00 2001 From: James Almer Date: Tue, 3 Oct 2017 11:49:18 -0300 Subject: [PATCH 3238/3374] avcodec/encode: do proper cleanup on failure Fixes the last remaining memleaks introduced by a22c6a4796ca1f2cbee6784262515da876fbec22. Signed-off-by: James Almer --- libavcodec/encode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/encode.c b/libavcodec/encode.c index c152228c920e9..c961dbace10b5 100644 --- a/libavcodec/encode.c +++ b/libavcodec/encode.c @@ -225,9 +225,9 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, } else if (!avpkt->buf) { AVPacket tmp = { 0 }; ret = av_packet_ref(&tmp, avpkt); - if (ret < 0) - return ret; av_packet_unref(avpkt); + if (ret < 0) + goto end; *avpkt = tmp; } } @@ -324,9 +324,9 @@ int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, } else if (!avpkt->buf) { AVPacket tmp = { 0 }; ret = av_packet_ref(&tmp, avpkt); + av_packet_unref(avpkt); if (ret < 0) return ret; - av_packet_unref(avpkt); *avpkt = tmp; } } From fbdab6eca7874fbeba6aa79c269f345e4d43f5d4 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 2 Oct 2017 04:18:21 +0200 Subject: [PATCH 3239/3374] avcodec/hevcdsp_template: Fix undefined shift Fixes: runtime error: left shift of negative value -255 Fixes: 3373/clusterfuzz-testcase-minimized-5604083912146944 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/hevcdsp_template.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/hevcdsp_template.c b/libavcodec/hevcdsp_template.c index 75763ce85e6e3..e09c661759e50 100644 --- a/libavcodec/hevcdsp_template.c +++ b/libavcodec/hevcdsp_template.c @@ -1486,7 +1486,7 @@ static void FUNC(put_hevc_epel_bi_w_hv)(uint8_t *_dst, ptrdiff_t _dststride, uin for (y = 0; y < height; y++) { for (x = 0; x < width; x++) dst[x] = av_clip_pixel(((EPEL_FILTER(tmp, MAX_PB_SIZE) >> 6) * wx1 + src2[x] * wx0 + - ((ox0 + ox1 + 1) << log2Wd)) >> (log2Wd + 1)); + ((ox0 + ox1 + 1) * (1 << log2Wd))) >> (log2Wd + 1)); tmp += MAX_PB_SIZE; dst += dststride; src2 += MAX_PB_SIZE; From c37138e01a93da2f9dd2cc5d4b77e5a38581d130 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 2 Oct 2017 04:18:22 +0200 Subject: [PATCH 3240/3374] avcodec/proresdec2: SKIP_BITS() does not work with len=32 Fixes: invalid shift Fixes: 3482/clusterfuzz-testcase-minimized-5446915875405824 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/proresdec2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c index e0779080270f6..22dc70eeb454d 100644 --- a/libavcodec/proresdec2.c +++ b/libavcodec/proresdec2.c @@ -267,7 +267,7 @@ static int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, cons \ if (q > switch_bits) { /* exp golomb */ \ bits = exp_order - switch_bits + (q<<1); \ - if (bits > MIN_CACHE_BITS) \ + if (bits > FFMIN(MIN_CACHE_BITS, 31)) \ return AVERROR_INVALIDDATA; \ val = SHOW_UBITS(re, gb, bits) - (1 << exp_order) + \ ((switch_bits + 1) << rice_order); \ From 4ee77cefaed0cf19b03b4b6f4945f52301165469 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 2 Oct 2017 04:18:23 +0200 Subject: [PATCH 3241/3374] avcodec/proresdec2: Use LAST_SKIP_BITS where possible Signed-off-by: Michael Niedermayer --- libavcodec/proresdec2.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c index 22dc70eeb454d..a7cea2b3b8026 100644 --- a/libavcodec/proresdec2.c +++ b/libavcodec/proresdec2.c @@ -250,7 +250,7 @@ static int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, cons return pic_data_size; } -#define DECODE_CODEWORD(val, codebook) \ +#define DECODE_CODEWORD(val, codebook, SKIP) \ do { \ unsigned int rice_order, exp_order, switch_bits; \ unsigned int q, buf, bits; \ @@ -271,14 +271,14 @@ static int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, cons return AVERROR_INVALIDDATA; \ val = SHOW_UBITS(re, gb, bits) - (1 << exp_order) + \ ((switch_bits + 1) << rice_order); \ - SKIP_BITS(re, gb, bits); \ + SKIP(re, gb, bits); \ } else if (rice_order) { \ SKIP_BITS(re, gb, q+1); \ val = (q << rice_order) + SHOW_UBITS(re, gb, rice_order); \ - SKIP_BITS(re, gb, rice_order); \ + SKIP(re, gb, rice_order); \ } else { \ val = q; \ - SKIP_BITS(re, gb, q+1); \ + SKIP(re, gb, q+1); \ } \ } while (0) @@ -296,7 +296,7 @@ static av_always_inline int decode_dc_coeffs(GetBitContext *gb, int16_t *out, OPEN_READER(re, gb); - DECODE_CODEWORD(code, FIRST_DC_CB); + DECODE_CODEWORD(code, FIRST_DC_CB, LAST_SKIP_BITS); prev_dc = TOSIGNED(code); out[0] = prev_dc; @@ -305,7 +305,7 @@ static av_always_inline int decode_dc_coeffs(GetBitContext *gb, int16_t *out, code = 5; sign = 0; for (i = 1; i < blocks_per_slice; i++, out += 64) { - DECODE_CODEWORD(code, dc_codebook[FFMIN(code, 6U)]); + DECODE_CODEWORD(code, dc_codebook[FFMIN(code, 6U)], LAST_SKIP_BITS); if(code) sign ^= -(code & 1); else sign = 0; prev_dc += (((code + 1) >> 1) ^ sign) - sign; @@ -341,14 +341,14 @@ static av_always_inline int decode_ac_coeffs(AVCodecContext *avctx, GetBitContex if (!bits_left || (bits_left < 32 && !SHOW_UBITS(re, gb, bits_left))) break; - DECODE_CODEWORD(run, run_to_cb[FFMIN(run, 15)]); + DECODE_CODEWORD(run, run_to_cb[FFMIN(run, 15)], LAST_SKIP_BITS); pos += run + 1; if (pos >= max_coeffs) { av_log(avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", pos, max_coeffs); return AVERROR_INVALIDDATA; } - DECODE_CODEWORD(level, lev_to_cb[FFMIN(level, 9)]); + DECODE_CODEWORD(level, lev_to_cb[FFMIN(level, 9)], SKIP_BITS); level += 1; i = pos >> log2_block_count; From 9ba9c08aab9de35c9afa5497c51b9bdfd4b770be Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Sat, 30 Sep 2017 20:33:09 +0200 Subject: [PATCH 3242/3374] fate: Add a test for latm-in-dvb auto-detection, ticket #6657. --- tests/Makefile | 1 + tests/fate/mpegts.mak | 14 ++++++++++++++ tests/ref/fate/mpegts-probe-latm | 14 ++++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 tests/fate/mpegts.mak create mode 100644 tests/ref/fate/mpegts-probe-latm diff --git a/tests/Makefile b/tests/Makefile index 99f7e1730b579..278be24ccbcd4 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -156,6 +156,7 @@ include $(SRC_PATH)/tests/fate/mov.mak include $(SRC_PATH)/tests/fate/mp3.mak include $(SRC_PATH)/tests/fate/mpc.mak include $(SRC_PATH)/tests/fate/mpeg4.mak +include $(SRC_PATH)/tests/fate/mpegts.mak include $(SRC_PATH)/tests/fate/mxf.mak include $(SRC_PATH)/tests/fate/opus.mak include $(SRC_PATH)/tests/fate/pcm.mak diff --git a/tests/fate/mpegts.mak b/tests/fate/mpegts.mak new file mode 100644 index 0000000000000..bb0d9d98a7761 --- /dev/null +++ b/tests/fate/mpegts.mak @@ -0,0 +1,14 @@ +# +# Test probing MPEGTS format and codecs +# +PROBE_CODEC_NAME_COMMAND = \ + ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream=codec_name \ + -print_format default -bitexact -v 0 + +FATE_MPEGTS_PROBE-$(call DEMDEC, MPEGTS, HEVC, AAC_LATM) += fate-mpegts-probe-latm +fate-mpegts-probe-latm: SRC = $(TARGET_SAMPLES)/mpegts/loewe.ts +fate-mpegts-probe-latm: CMD = run $(PROBE_CODEC_NAME_COMMAND) -i "$(SRC)" + +FATE_SAMPLES_FFPROBE += $(FATE_MPEGTS_PROBE-yes) + +fate-mpegts: $(FATE_MPEGTS_PROBE-yes) diff --git a/tests/ref/fate/mpegts-probe-latm b/tests/ref/fate/mpegts-probe-latm new file mode 100644 index 0000000000000..13aea2bcfdc61 --- /dev/null +++ b/tests/ref/fate/mpegts-probe-latm @@ -0,0 +1,14 @@ +[PROGRAM] +[STREAM] +codec_name=hevc +[/STREAM] +[STREAM] +codec_name=aac_latm +[/STREAM] +[/PROGRAM] +[STREAM] +codec_name=hevc +[/STREAM] +[STREAM] +codec_name=aac_latm +[/STREAM] From 4590d073ccdc7c3ce0384d5b1fba56b3f6673535 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Sat, 5 Nov 2016 01:48:10 +0100 Subject: [PATCH 3243/3374] lavf/mxfdec: Search all components of material track for source package. Fixes ticket #5925. Reviewed-by: Marton --- libavformat/mxfdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 1855f95d79c19..118e3e40b44cf 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -1978,7 +1978,7 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) source_package = mxf_resolve_source_package(mxf, component->source_package_uid); if (!source_package) { av_log(mxf->fc, AV_LOG_TRACE, "material track %d: no corresponding source package found\n", material_track->track_id); - break; + continue; } for (k = 0; k < source_package->tracks_count; k++) { if (!(temp_track = mxf_resolve_strong_ref(mxf, &source_package->tracks_refs[k], Track))) { From cbbec68847ed3485900e83ec231871f71bb97d0d Mon Sep 17 00:00:00 2001 From: Martin Vignali Date: Mon, 2 Oct 2017 01:29:32 +0200 Subject: [PATCH 3244/3374] libavcodec/blockdsp : add AVX version Also modify the required alignment, to 32 instead of 16 for several codecs Signed-off-by: James Almer --- libavcodec/asv.h | 2 +- libavcodec/bink.c | 4 ++-- libavcodec/dnxhdenc.h | 2 +- libavcodec/eamad.c | 2 +- libavcodec/eatqi.c | 2 +- libavcodec/g2meet.c | 2 +- libavcodec/ituh263dec.c | 2 +- libavcodec/mdec.c | 2 +- libavcodec/mimic.c | 2 +- libavcodec/mjpegdec.h | 2 +- libavcodec/proresdec2.c | 6 +++--- libavcodec/speedhq.c | 2 +- libavcodec/wmv2.h | 2 +- libavcodec/x86/blockdsp.asm | 14 ++++++++------ libavcodec/x86/blockdsp_init.c | 6 ++++++ tests/checkasm/blockdsp.c | 4 ++-- 16 files changed, 32 insertions(+), 24 deletions(-) diff --git a/libavcodec/asv.h b/libavcodec/asv.h index e2cdc8130064e..a1366b6fe45c4 100644 --- a/libavcodec/asv.h +++ b/libavcodec/asv.h @@ -54,7 +54,7 @@ typedef struct ASV1Context { int mb_height; int mb_width2; int mb_height2; - DECLARE_ALIGNED(16, int16_t, block)[6][64]; + DECLARE_ALIGNED(32, int16_t, block)[6][64]; uint16_t intra_matrix[64]; int q_intra_matrix[64]; uint8_t *bitstream_buffer; diff --git a/libavcodec/bink.c b/libavcodec/bink.c index cc5587011451b..346b6cda9dfb6 100644 --- a/libavcodec/bink.c +++ b/libavcodec/bink.c @@ -813,7 +813,7 @@ static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, int v, col[2]; const uint8_t *scan; int xoff, yoff; - LOCAL_ALIGNED_16(int16_t, block, [64]); + LOCAL_ALIGNED_32(int16_t, block, [64]); LOCAL_ALIGNED_16(int32_t, dctblock, [64]); int coordmap[64]; int ybias = is_key ? -15 : 0; @@ -976,7 +976,7 @@ static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, uint8_t *dst, *prev, *ref_start, *ref_end; int v, col[2]; const uint8_t *scan; - LOCAL_ALIGNED_16(int16_t, block, [64]); + LOCAL_ALIGNED_32(int16_t, block, [64]); LOCAL_ALIGNED_16(uint8_t, ublock, [64]); LOCAL_ALIGNED_16(int32_t, dctblock, [64]); int coordmap[64]; diff --git a/libavcodec/dnxhdenc.h b/libavcodec/dnxhdenc.h index 26c3eec695f31..963821ac81a0a 100644 --- a/libavcodec/dnxhdenc.h +++ b/libavcodec/dnxhdenc.h @@ -74,7 +74,7 @@ typedef struct DNXHDEncContext { unsigned min_padding; int intra_quant_bias; - DECLARE_ALIGNED(16, int16_t, blocks)[12][64]; + DECLARE_ALIGNED(32, int16_t, blocks)[12][64]; DECLARE_ALIGNED(16, uint8_t, edge_buf_y)[512]; // has to hold 16x16 uint16 when depth=10 DECLARE_ALIGNED(16, uint8_t, edge_buf_uv)[2][512]; // has to hold 16x16 uint16_t when depth=10 diff --git a/libavcodec/eamad.c b/libavcodec/eamad.c index 753dee06c33ed..7f28abbafeae6 100644 --- a/libavcodec/eamad.c +++ b/libavcodec/eamad.c @@ -54,7 +54,7 @@ typedef struct MadContext { GetBitContext gb; void *bitstream_buf; unsigned int bitstream_buf_size; - DECLARE_ALIGNED(16, int16_t, block)[64]; + DECLARE_ALIGNED(32, int16_t, block)[64]; ScanTable scantable; uint16_t quant_matrix[64]; int mb_x; diff --git a/libavcodec/eatqi.c b/libavcodec/eatqi.c index 725289448a9c0..1a847a35da45b 100644 --- a/libavcodec/eatqi.c +++ b/libavcodec/eatqi.c @@ -51,7 +51,7 @@ typedef struct TqiContext { uint16_t intra_matrix[64]; int last_dc[3]; - DECLARE_ALIGNED(16, int16_t, block)[6][64]; + DECLARE_ALIGNED(32, int16_t, block)[6][64]; } TqiContext; static av_cold int tqi_decode_init(AVCodecContext *avctx) diff --git a/libavcodec/g2meet.c b/libavcodec/g2meet.c index 10b6808f813b1..842095ba3b40d 100644 --- a/libavcodec/g2meet.c +++ b/libavcodec/g2meet.c @@ -122,7 +122,7 @@ typedef struct JPGContext { VLC dc_vlc[2], ac_vlc[2]; int prev_dc[3]; - DECLARE_ALIGNED(16, int16_t, block)[6][64]; + DECLARE_ALIGNED(32, int16_t, block)[6][64]; uint8_t *buf; } JPGContext; diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c index edb68861ac639..fc95a532ce794 100644 --- a/libavcodec/ituh263dec.c +++ b/libavcodec/ituh263dec.c @@ -574,7 +574,7 @@ static int h263_decode_block(MpegEncContext * s, int16_t * block, static int h263_skip_b_part(MpegEncContext *s, int cbp) { - LOCAL_ALIGNED_16(int16_t, dblock, [64]); + LOCAL_ALIGNED_32(int16_t, dblock, [64]); int i, mbi; int bli[6]; diff --git a/libavcodec/mdec.c b/libavcodec/mdec.c index 59658b331d24a..330b7612790ec 100644 --- a/libavcodec/mdec.c +++ b/libavcodec/mdec.c @@ -48,7 +48,7 @@ typedef struct MDECContext { int mb_width; int mb_height; int mb_x, mb_y; - DECLARE_ALIGNED(16, int16_t, block)[6][64]; + DECLARE_ALIGNED(32, int16_t, block)[6][64]; DECLARE_ALIGNED(16, uint16_t, quant_matrix)[64]; uint8_t *bitstream_buffer; unsigned int bitstream_buffer_size; diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c index 02d8b30e31a97..1d463e9962c7f 100644 --- a/libavcodec/mimic.c +++ b/libavcodec/mimic.c @@ -49,7 +49,7 @@ typedef struct MimicContext { ThreadFrame frames [16]; - DECLARE_ALIGNED(16, int16_t, dct_block)[64]; + DECLARE_ALIGNED(32, int16_t, dct_block)[64]; GetBitContext gb; ScanTable scantable; diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h index 2bc69fa93066b..c84a40aa6e649 100644 --- a/libavcodec/mjpegdec.h +++ b/libavcodec/mjpegdec.h @@ -98,7 +98,7 @@ typedef struct MJpegDecodeContext { int got_picture; ///< we found a SOF and picture is valid, too. int linesize[MAX_COMPONENTS]; ///< linesize << interlaced int8_t *qscale_table; - DECLARE_ALIGNED(16, int16_t, block)[64]; + DECLARE_ALIGNED(32, int16_t, block)[64]; int16_t (*blocks[MAX_COMPONENTS])[64]; ///< intermediate sums (progressive mode) uint8_t *last_nnz[MAX_COMPONENTS]; uint64_t coefs_finished[MAX_COMPONENTS]; ///< bitmask of which coefs have been completely decoded (progressive mode) diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c index a7cea2b3b8026..0f791de97ba5f 100644 --- a/libavcodec/proresdec2.c +++ b/libavcodec/proresdec2.c @@ -368,7 +368,7 @@ static int decode_slice_luma(AVCodecContext *avctx, SliceContext *slice, const int16_t *qmat) { ProresContext *ctx = avctx->priv_data; - LOCAL_ALIGNED_16(int16_t, blocks, [8*4*64]); + LOCAL_ALIGNED_32(int16_t, blocks, [8*4*64]); int16_t *block; GetBitContext gb; int i, blocks_per_slice = slice->mb_count<<2; @@ -402,7 +402,7 @@ static int decode_slice_chroma(AVCodecContext *avctx, SliceContext *slice, const int16_t *qmat, int log2_blocks_per_mb) { ProresContext *ctx = avctx->priv_data; - LOCAL_ALIGNED_16(int16_t, blocks, [8*4*64]); + LOCAL_ALIGNED_32(int16_t, blocks, [8*4*64]); int16_t *block; GetBitContext gb; int i, j, blocks_per_slice = slice->mb_count << log2_blocks_per_mb; @@ -485,7 +485,7 @@ static void decode_slice_alpha(ProresContext *ctx, { GetBitContext gb; int i; - LOCAL_ALIGNED_16(int16_t, blocks, [8*4*64]); + LOCAL_ALIGNED_32(int16_t, blocks, [8*4*64]); int16_t *block; for (i = 0; i < blocks_per_slice<<2; i++) diff --git a/libavcodec/speedhq.c b/libavcodec/speedhq.c index 47b1e4dc7a5b0..6d3487ca19b9a 100644 --- a/libavcodec/speedhq.c +++ b/libavcodec/speedhq.c @@ -224,7 +224,7 @@ static inline int decode_dct_block(const SHQContext *s, GetBitContext *gb, int l { const int *quant_matrix = s->quant_matrix; const uint8_t *scantable = s->intra_scantable.permutated; - LOCAL_ALIGNED_16(int16_t, block, [64]); + LOCAL_ALIGNED_32(int16_t, block, [64]); int dc_offset; s->bdsp.clear_block(block); diff --git a/libavcodec/wmv2.h b/libavcodec/wmv2.h index 31593b8c38d5f..0f459ae5ae4bd 100644 --- a/libavcodec/wmv2.h +++ b/libavcodec/wmv2.h @@ -51,7 +51,7 @@ typedef struct Wmv2Context { int hshift; ScanTable abt_scantable[2]; - DECLARE_ALIGNED(16, int16_t, abt_block2)[6][64]; + DECLARE_ALIGNED(32, int16_t, abt_block2)[6][64]; } Wmv2Context; void ff_wmv2_common_init(Wmv2Context *w); diff --git a/libavcodec/x86/blockdsp.asm b/libavcodec/x86/blockdsp.asm index 7cbfa3a843b2a..2498bd40b3c69 100644 --- a/libavcodec/x86/blockdsp.asm +++ b/libavcodec/x86/blockdsp.asm @@ -4,6 +4,8 @@ ;* Copyright (c) 2008 Loren Merritt ;* Copyright (c) 2009 Fiona Glaser ;* +;* AVX version by Jokyo Images +;* ;* This file is part of FFmpeg. ;* ;* FFmpeg is free software; you can redistribute it and/or @@ -39,20 +41,18 @@ cglobal clear_block, 1, 1, %1, blocks mova [blocksq+mmsize*(1+%%i)], m0 mova [blocksq+mmsize*(2+%%i)], m0 mova [blocksq+mmsize*(3+%%i)], m0 - mova [blocksq+mmsize*(4+%%i)], m0 - mova [blocksq+mmsize*(5+%%i)], m0 - mova [blocksq+mmsize*(6+%%i)], m0 - mova [blocksq+mmsize*(7+%%i)], m0 -%assign %%i %%i+8 +%assign %%i %%i+4 %endrep RET %endmacro INIT_MMX mmx %define ZERO pxor -CLEAR_BLOCK 0, 2 +CLEAR_BLOCK 0, 4 INIT_XMM sse %define ZERO xorps +CLEAR_BLOCK 1, 2 +INIT_YMM avx CLEAR_BLOCK 1, 1 ;----------------------------------------- @@ -84,3 +84,5 @@ CLEAR_BLOCKS 0 INIT_XMM sse %define ZERO xorps CLEAR_BLOCKS 1 +INIT_YMM avx +CLEAR_BLOCKS 1 diff --git a/libavcodec/x86/blockdsp_init.c b/libavcodec/x86/blockdsp_init.c index afd25e1cbb378..8b01a447cd4f1 100644 --- a/libavcodec/x86/blockdsp_init.c +++ b/libavcodec/x86/blockdsp_init.c @@ -28,8 +28,10 @@ void ff_clear_block_mmx(int16_t *block); void ff_clear_block_sse(int16_t *block); +void ff_clear_block_avx(int16_t *block); void ff_clear_blocks_mmx(int16_t *blocks); void ff_clear_blocks_sse(int16_t *blocks); +void ff_clear_blocks_avx(int16_t *blocks); av_cold void ff_blockdsp_init_x86(BlockDSPContext *c, AVCodecContext *avctx) @@ -50,5 +52,9 @@ av_cold void ff_blockdsp_init_x86(BlockDSPContext *c, c->clear_block = ff_clear_block_sse; c->clear_blocks = ff_clear_blocks_sse; } + if (EXTERNAL_AVX_FAST(cpu_flags)) { + c->clear_block = ff_clear_block_avx; + c->clear_blocks = ff_clear_blocks_avx; + } #endif /* HAVE_X86ASM */ } diff --git a/tests/checkasm/blockdsp.c b/tests/checkasm/blockdsp.c index 153699b632763..c753506b3cc73 100644 --- a/tests/checkasm/blockdsp.c +++ b/tests/checkasm/blockdsp.c @@ -53,8 +53,8 @@ do { \ void checkasm_check_blockdsp(void) { - LOCAL_ALIGNED_16(uint16_t, buf0, [6 * 8 * 8]); - LOCAL_ALIGNED_16(uint16_t, buf1, [6 * 8 * 8]); + LOCAL_ALIGNED_32(uint16_t, buf0, [6 * 8 * 8]); + LOCAL_ALIGNED_32(uint16_t, buf1, [6 * 8 * 8]); AVCodecContext avctx = { 0 }; BlockDSPContext h; From d17a00379e7ab5601ffc7da0a53b0c9f9d48a567 Mon Sep 17 00:00:00 2001 From: Lou Logan Date: Wed, 27 Sep 2017 14:35:12 -0800 Subject: [PATCH 3245/3374] doc: Add mailing list FAQ Signed-off-by: Lou Logan Reviewed-by: Kieran O Leary Reviewed-by: Carl Eugen Hoyos --- doc/Makefile | 1 + doc/mailing-list-faq.texi | 366 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 367 insertions(+) create mode 100644 doc/mailing-list-faq.texi diff --git a/doc/Makefile b/doc/Makefile index bcde309878231..fa4996b5a306b 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -24,6 +24,7 @@ HTMLPAGES = $(AVPROGS-yes:%=doc/%.html) $(AVPROGS-yes:%=doc/%-all.html) $(COMP doc/fate.html \ doc/general.html \ doc/git-howto.html \ + doc/mailing-list-faq.html \ doc/nut.html \ doc/platform.html \ diff --git a/doc/mailing-list-faq.texi b/doc/mailing-list-faq.texi new file mode 100644 index 0000000000000..fe2171e42e875 --- /dev/null +++ b/doc/mailing-list-faq.texi @@ -0,0 +1,366 @@ +\input texinfo @c -*- texinfo -*- +@documentencoding UTF-8 + +@settitle FFmpeg Mailing List FAQ +@titlepage +@center @titlefont{FFmpeg Mailing List FAQ} +@end titlepage + +@top + +@contents + +@chapter General Questions + +@section What is a mailing list? + +A mailing list is not much different than emailing someone, but the +main difference is that your message is received by everyone who +subscribes to the list. It is somewhat like a forum but in email form. + +See the @url{https://lists.ffmpeg.org/pipermail/ffmpeg-user/, ffmpeg-user archives} +for examples. + +@section What type of questions can I ask? + +@itemize +@item +@url{https://lists.ffmpeg.org/mailman/listinfo/ffmpeg-user/, ffmpeg-user}: +For questions involving unscripted usage or compilation of the FFmpeg +command-line tools (@command{ffmpeg}, @command{ffprobe}, @command{ffplay}, +@command{ffserver}). + +@item +@url{https://lists.ffmpeg.org/mailman/listinfo/libav-user/, libav-user}: +For questions involving the FFmpeg libav* libraries (libavcodec, +libavformat, libavfilter, etc). + +@item +@url{https://lists.ffmpeg.org/mailman/listinfo/ffmpeg-devel/, ffmpeg-devel}: +For discussions involving the development of FFmpeg and for submitting +patches. User questions should be asked at ffmpeg-user or libav-user. +@end itemize + +To report a bug see @url{https://ffmpeg.org/bugreports.html}. + +We cannot provide help for scripts and/or third-party tools. + +@anchor{How do I ask a question or send a message to a mailing list?} +@section How do I ask a question or send a message to a mailing list? + +All you have to do is send an email: + +@itemize +@item +Email @email{ffmpeg-user@@ffmpeg.org} to send a message to the +ffmpeg-user mailing list. + +@item +Email @email{libav-user@@ffmpeg.org} to send a message to the +libav-user mailing list. +@end itemize + +If you are not subscribed to the mailing list then your question must be +manually approved. Approval may take several days, but the wait is +usually less. If you want the message to be sent with no delay then you +must subscribe first. See @ref{How do I subscribe?} + +Please do not send a message, subscribe, and re-send the message: this +results in duplicates, causes more work for the admins, and may lower +your chance at getting an answer. However, you may do so if you first +@ref{How do I delete my message in the moderation queue?, delete your original message from the moderation queue}. + +@chapter Subscribing / Unsubscribing + +@section What does subscribing do? + +Subscribing allows two things: + +@itemize +@item +Your messages will show up in the mailing list without waiting in the +moderation queue and needing to be manually approved by a mailing list +admin. + +@item +You will receive all messages to the mailing list including replies to +your messages. Non-subscribed users do not receive any messages. +@end itemize + +@section Do I need to subscribe? + +No. You can still send a message to the mailing list without +subscribing. See @ref{How do I ask a question or send a message to a mailing list?} + +However, your message will need to be manually approved by a mailing +list admin, and you will not receive any mailing list messages or +replies. + +You can ask to be CCd in your message, but replying users will +sometimes forget to do so. + +You may also view and reply to messages via the @ref{Where are the archives?, archives}. + +@anchor{How do I subscribe?} +@section How do I subscribe? + +Email @email{ffmpeg-user-request@@ffmpeg.org} with the subject +@emph{subscribe}. + +Or visit the @url{https://lists.ffmpeg.org/mailman/listinfo/ffmpeg-user/, ffmpeg-user mailing list info page} +and refer to the @emph{Subscribing to ffmpeg-user} section. + +The process is the same for the other mailing lists. + +@section How do I unsubscribe? + +Email @email{ffmpeg-user-request@@ffmpeg.org} with subject @emph{unsubscribe}. + +Or visit the @url{https://lists.ffmpeg.org/mailman/listinfo/ffmpeg-user/, ffmpeg-user mailing list info page}, +scroll to bottom of page, enter your email address in the box, and click +the @emph{Unsubscribe or edit options} button. + +The process is the same for the other mailing lists. + +Please avoid asking a mailing list admin to unsubscribe you unless you +are absolutely unable to do so by yourself. See @ref{Who do I contact if I have a problem with the mailing list?} + +@chapter Moderation Queue +@anchor{Why is my message awaiting moderator approval?} +@section Why is my message awaiting moderator approval? + +Some messages are automatically held in the @emph{moderation queue} and +must be manually approved by a mailing list admin: + +These are: + +@itemize +@item +Messages from users who are @strong{not} subscribed. + +@item +Messages that exceed the @ref{What is the message size limit?, message size limit}. + +@item +Messages from users whose accounts have been set with the @emph{moderation flag} +(very rarely occurs, but may if a user repeatedly ignores the rules +or is abusive towards others). +@end itemize + +@section How long does it take for my message in the moderation queue to be approved? + +The queue is usually checked once or twice a day, but on occasion +several days may pass before someone checks the queue. + +@anchor{How do I delete my message in the moderation queue?} +@section How do I delete my message in the moderation queue? + +You should have received an email with the subject @emph{Your message to ffmpeg-user awaits moderator approval}. +A link is in the message that will allow you to delete your message +unless a mailing list admin already approved or rejected it. + +@chapter Archives + +@anchor{Where are the archives?} +@section Where are the archives? + +See the @emph{Archives} section on the @url{https://ffmpeg.org/contact.html, FFmpeg Contact} +page for links to all FFmpeg mailing list archives. + +Note that the archives are split by month. Discussions that span +several months will be split into separate months in the archives. + +@section How do I reply to a message in the archives? + +Click the email link at the top of the message just under the subject +title. The link will provide the proper headers to keep the message +within the thread. + +@section How do I search the archives? + +Perform a site search using your favorite search engine. Example: + +@t{site:lists.ffmpeg.org/pipermail/ffmpeg-user/ "search term"} + +@chapter Other + +@section Is there an alternative to the mailing list? + +You can ask for help in the official @t{#ffmpeg} IRC channel on Freenode. + +Some users prefer the third-party Nabble interface which presents the +mailing lists in a typical forum layout. + +There are also numerous third-party help sites such as Super User and +r/ffmpeg on reddit. + +@anchor{What is top-posting?} +@section What is top-posting? + +See @url{https://en.wikipedia.org/wiki/Posting_style#Top-posting}. + +Instead, use trimmed interleaved/inline replies (@url{https://lists.ffmpeg.org/pipermail/ffmpeg-user/2017-April/035849.html, example}). + +@anchor{What is the message size limit?} +@section What is the message size limit? + +The message size limit is 500 kilobytes for the user lists and 1000 +kilobytes for ffmpeg-devel. Please provide links to larger files instead +of attaching them. + +@section Where can I upload sample files? + +Anywhere that is not too annoying for us to use. + +Google Drive and Dropbox are acceptable if you need a file host, and +0x0.st is good for files under 256 MiB. + +Small, short samples are preferred if possible. + +@section Will I receive spam if I send and/or subscribe to a mailing list? + +Highly unlikely. + +@itemize +@item +The list of subscribed users is not public. + +@item +Email addresses in the archives are obfuscated. + +@item +Several unique test email accounts were utilized and none have yet +received any spam. +@end itemize + +However, you may see a spam in the mailing lists on rare occasions: + +@itemize +@item +Spam in the moderation queue may be accidentally approved due to human +error. + +@item +There have been a few messages from subscribed users who had their own +email addresses hacked and spam messages from (or appearing to be from) +the hacked account were sent to their contacts (a mailing list being a +contact in these cases). + +@item +If you are subscribed to the bug tracker mailing list (ffmpeg-trac) you +may see the occasional spam as a false bug report, but we take measures +to try to prevent this. +@end itemize + +@section How do I filter mailing list messages? + +Use the @emph{List-Id}. For example, the ffmpeg-user mailing list is +@t{ffmpeg-user.ffmpeg.org}. You can view the List-Id in the raw message +or headers. + +You can then filter the mailing list messages to their own folder. + +@chapter Rules and Etiquette + +@section What are the rules and the proper etiquette? + +There may seem to be many things to remember, but we want to help and +following these guidelines will allow you to get answers more quickly +and help avoid getting ignored. + +@itemize +@item +Always show your actual, unscripted @command{ffmpeg} command and the +complete, uncut console output from your command. + +@item +Use the most simple and minimal command that still shows the issue you +are encountering. + +@item +Provide all necessary information so others can attempt to duplicate +your issue. This includes the actual command, complete uncut console +output, and any inputs that are required to duplicate the issue. + +@item +Use the latest @command{ffmpeg} build you can get. See the @url{https://ffmpeg.org/download.html, FFmpeg Download} +page for links to recent builds for Linux, macOS, and Windows. Or +compile from the current git master branch. + +@item +Avoid @url{https://en.wikipedia.org/wiki/Posting_style#Top-posting, top-posting}. +Also see @ref{What is top-posting?} + +@item +Avoid hijacking threads. Thread hijacking is replying to a message and +changing the subject line to something unrelated to the original thread. +Most email clients will still show the renamed message under the +original thread. This can be confusing and these types of messages are +often ignored. + +@item +Do not send screenshots. Copy and paste console text instead of making +screenshots of the text. + +@item +Avoid sending email disclaimers and legalese if possible as this is a +public list. + +@item +Avoid using the @code{-loglevel debug}, @code{-loglevel quiet}, and +@command{-hide_banner} options unless requested to do so. + +@item +If you attach files avoid compressing small files. Uncompressed is +preferred. + +@item +Please do not send HTML-only messages. The mailing list will ignore the +HTML component of your message. Most mail clients will automatically +include a text component: this is what the mailing list will use. + +@item +Configuring your mail client to break lines after 70 or so characters is +recommended. + +@item +Avoid sending the same message to multiple mailing lists. + +@item +Please follow our @url{https://ffmpeg.org/developer.html#Code-of-conduct, Code of Conduct}. +@end itemize + +@chapter Help + +@section Why am I not receiving any messages? + +Some email providers have blacklists or spam filters that block or mark +the mailing list messages as false positives. Unfortunately, the user is +often not aware of this and is often out of their control. + +When possible we attempt to notify the provider to be removed from the +blacklists or filters. + +@section Why are my sent messages not showing up? + +Excluding @ref{Why is my message awaiting moderator approval?, messages that are held in the moderation queue} +there are a few other reasons why your messages may fail to appear: + +@itemize +@item +HTML-only messages are ignored by the mailing lists. Most mail clients +automatically include a text component alongside HTML email: this is what +the mailing list will use. If it does not then consider your client to be +broken, because sending a text component along with the HTML component to +form a multi-part message is recommended by email standards. + +@item +Check your spam folder. +@end itemize + +@anchor{Who do I contact if I have a problem with the mailing list?} +@section Who do I contact if I have a problem with the mailing list? + +Send a message to @email{ffmpeg-user-owner@@ffmpeg.org}. + +@bye From fd7cb86468cc63b5bda203d74964584281318cda Mon Sep 17 00:00:00 2001 From: Zhong Li Date: Sat, 30 Sep 2017 11:22:57 +0800 Subject: [PATCH 3246/3374] mpegdec: fix redundant dummy frames issue of interlaced clips It is to fix https://trac.ffmpeg.org/ticket/6677. Actucally it is a regression of commit 99e07a4453732058df90885f80b3db3b4f37cb3c which always inserts a dummy frame when decode the first key field picture. Signed-off-by: Zhong Li Signed-off-by: Michael Niedermayer --- libavcodec/mpegvideo.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 82b94253aeee0..c4089972f0143 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -1283,8 +1283,7 @@ int ff_mpv_frame_start(MpegEncContext *s, AVCodecContext *avctx) s->pict_type, s->droppable); if ((!s->last_picture_ptr || !s->last_picture_ptr->f->buf[0]) && - (s->pict_type != AV_PICTURE_TYPE_I || - s->picture_structure != PICT_FRAME)) { + (s->pict_type != AV_PICTURE_TYPE_I)) { int h_chroma_shift, v_chroma_shift; av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift); @@ -1294,9 +1293,6 @@ int ff_mpv_frame_start(MpegEncContext *s, AVCodecContext *avctx) else if (s->pict_type != AV_PICTURE_TYPE_I) av_log(avctx, AV_LOG_ERROR, "warning: first frame is no keyframe\n"); - else if (s->picture_structure != PICT_FRAME) - av_log(avctx, AV_LOG_DEBUG, - "allocate dummy last picture for field based first keyframe\n"); /* Allocate a dummy frame */ i = ff_find_unused_picture(s->avctx, s->picture, 0); From dcf9bae4a93f54cb5767bc97db4a809efd396f8b Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 30 Sep 2017 18:54:05 +0200 Subject: [PATCH 3247/3374] avcodec/aacdec_template: Clear tns present flag on error Fixes: 3444/clusterfuzz-testcase-minimized-6270352105668608 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/aacdec_template.c | 44 +++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/libavcodec/aacdec_template.c b/libavcodec/aacdec_template.c index 3558f1f5504e8..082cc908d2bdf 100644 --- a/libavcodec/aacdec_template.c +++ b/libavcodec/aacdec_template.c @@ -1999,16 +1999,17 @@ static int decode_ics(AACContext *ac, SingleChannelElement *sce, global_gain = get_bits(gb, 8); if (!common_window && !scale_flag) { - if (decode_ics_info(ac, ics, gb) < 0) - return AVERROR_INVALIDDATA; + ret = decode_ics_info(ac, ics, gb); + if (ret < 0) + goto fail; } if ((ret = decode_band_types(ac, sce->band_type, sce->band_type_run_end, gb, ics)) < 0) - return ret; + goto fail; if ((ret = decode_scalefactors(ac, sce->sf, gb, global_gain, ics, sce->band_type, sce->band_type_run_end)) < 0) - return ret; + goto fail; pulse_present = 0; if (!scale_flag) { @@ -2016,37 +2017,48 @@ static int decode_ics(AACContext *ac, SingleChannelElement *sce, if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { av_log(ac->avctx, AV_LOG_ERROR, "Pulse tool not allowed in eight short sequence.\n"); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } if (decode_pulses(&pulse, gb, ics->swb_offset, ics->num_swb)) { av_log(ac->avctx, AV_LOG_ERROR, "Pulse data corrupt or invalid.\n"); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } } tns->present = get_bits1(gb); - if (tns->present && !er_syntax) - if (decode_tns(ac, tns, gb, ics) < 0) - return AVERROR_INVALIDDATA; + if (tns->present && !er_syntax) { + ret = decode_tns(ac, tns, gb, ics); + if (ret < 0) + goto fail; + } if (!eld_syntax && get_bits1(gb)) { avpriv_request_sample(ac->avctx, "SSR"); - return AVERROR_PATCHWELCOME; + ret = AVERROR_PATCHWELCOME; + goto fail; } // I see no textual basis in the spec for this occurring after SSR gain // control, but this is what both reference and real implmentations do - if (tns->present && er_syntax) - if (decode_tns(ac, tns, gb, ics) < 0) - return AVERROR_INVALIDDATA; + if (tns->present && er_syntax) { + ret = decode_tns(ac, tns, gb, ics); + if (ret < 0) + goto fail; + } } - if (decode_spectrum_and_dequant(ac, out, gb, sce->sf, pulse_present, - &pulse, ics, sce->band_type) < 0) - return AVERROR_INVALIDDATA; + ret = decode_spectrum_and_dequant(ac, out, gb, sce->sf, pulse_present, + &pulse, ics, sce->band_type); + if (ret < 0) + goto fail; if (ac->oc[1].m4ac.object_type == AOT_AAC_MAIN && !common_window) apply_prediction(ac, sce); return 0; +fail: + tns->present = 0; + return ret; } /** From 44874b4f5ec2c605c70393573b9d85540ebc2d81 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 30 Sep 2017 18:54:06 +0200 Subject: [PATCH 3248/3374] avcodec/truemotion2: Fix integer overflows in tm2_high_chroma() Fixes: runtime error: signed integer overflow: -1408475220 + -1408475220 cannot be represented in type 'int' Fixes: 3336/clusterfuzz-testcase-minimized-5656839179993088 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/truemotion2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/truemotion2.c b/libavcodec/truemotion2.c index a463a925fd497..f077f0e4bd990 100644 --- a/libavcodec/truemotion2.c +++ b/libavcodec/truemotion2.c @@ -465,7 +465,7 @@ static inline void tm2_apply_deltas(TM2Context *ctx, int* Y, int stride, int *de } } -static inline void tm2_high_chroma(int *data, int stride, int *last, int *CD, int *deltas) +static inline void tm2_high_chroma(int *data, int stride, int *last, unsigned *CD, int *deltas) { int i, j; for (j = 0; j < 2; j++) { From d662143f064636f11d92083cd9aa4f907cf97d59 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 30 Sep 2017 18:54:07 +0200 Subject: [PATCH 3249/3374] avcodec/dxv: Check for end of input in dxv_decompress_dxt5() Fixes: Timeout Fixes: 3291/clusterfuzz-testcase-4630024655208448 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/dxv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/dxv.c b/libavcodec/dxv.c index 6f3c075d06be7..529e2112589e3 100644 --- a/libavcodec/dxv.c +++ b/libavcodec/dxv.c @@ -197,6 +197,8 @@ static int dxv_decompress_dxt5(AVCodecContext *avctx) AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; } else { + if (bytestream2_get_bytes_left(gbc) < 1) + return AVERROR_INVALIDDATA; if (state == 0) { value = bytestream2_get_le32(gbc); state = 16; From 08c751309670854c73b58f234a83f4ba679370be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingo=20Br=C3=BCckl?= Date: Tue, 3 Oct 2017 15:50:37 +0200 Subject: [PATCH 3250/3374] avformat/mp3dec: Fix definition of MIDDLE_BITS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The number of bits from bit #m to #n is n - m plus 1. Signed-off-by: Ingo Brückl Signed-off-by: Michael Niedermayer --- libavformat/mp3dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c index 0924a578434df..a5c4f2ea12720 100644 --- a/libavformat/mp3dec.c +++ b/libavformat/mp3dec.c @@ -142,7 +142,7 @@ static void mp3_parse_info_tag(AVFormatContext *s, AVStream *st, MPADecodeHeader *c, uint32_t spf) { #define LAST_BITS(k, n) ((k) & ((1 << (n)) - 1)) -#define MIDDLE_BITS(k, m, n) LAST_BITS((k) >> (m), ((n) - (m))) +#define MIDDLE_BITS(k, m, n) LAST_BITS((k) >> (m), ((n) - (m) + 1)) uint16_t crc; uint32_t v; From 8be3fc88d3facec927708a8594fe26df93df5cad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Fri, 29 Sep 2017 11:05:33 +0200 Subject: [PATCH 3251/3374] build: make h264 VT encoder select the VT encoder dependency Otherwise, it's never enabled unless the user explicitely enables it. Regression since 9ef5a2f5f30bdc4ac86275ae4b4708ab4681b21d. Fixes Ticket #6702. --- configure | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 0d86c4cb2acb6..2efc79e74ddec 100755 --- a/configure +++ b/configure @@ -2934,7 +2934,8 @@ pcm_alaw_at_encoder_select="audio_frame_queue" pcm_mulaw_at_encoder_deps="audiotoolbox" pcm_mulaw_at_encoder_select="audio_frame_queue" chromaprint_muxer_deps="chromaprint" -h264_videotoolbox_encoder_deps="videotoolbox_encoder pthreads" +h264_videotoolbox_encoder_deps="pthreads" +h264_videotoolbox_encoder_select="videotoolbox_encoder" libcelt_decoder_deps="libcelt" libfdk_aac_decoder_deps="libfdk_aac" libfdk_aac_encoder_deps="libfdk_aac" From ffc58b2ce27e140b47900d1ead304663f7b385ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ekstr=C3=B6m?= Date: Sat, 30 Sep 2017 01:04:00 +0300 Subject: [PATCH 3252/3374] movenc: take packet dts shifting into mention in check_pkt This FFmpeg-specific "fuzzer fix" was never perfect, but now it stopped encoding of actual content with a big enough DTS shift. This returns the function to its original state of results before negative CTS offsets were added. I remember dealing with this function before, but somehow had forgotten about it during VDD. The test cases not tripping this over also didn't help. --- libavformat/movenc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 9c3e6437d72e4..2838286141842 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -4989,6 +4989,12 @@ static int check_pkt(AVFormatContext *s, AVPacket *pkt) } else ref = pkt->dts; // Skip tests for the first packet + if (trk->dts_shift != AV_NOPTS_VALUE) { + /* With negative CTS offsets we have set an offset to the DTS, + * reverse this for the check. */ + ref -= trk->dts_shift; + } + duration = pkt->dts - ref; if (pkt->dts < ref || duration >= INT_MAX) { av_log(s, AV_LOG_ERROR, "Application provided duration: %"PRId64" / timestamp: %"PRId64" is out of range for mov/mp4 format\n", From cbf09f23b655b672928fc8567646ac7ee3a4b280 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sat, 30 Sep 2017 23:37:01 +0200 Subject: [PATCH 3253/3374] MAINTAINERS: change the decklink maintainer to myself Signed-off-by: Marton Balint --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 412680abacc39..9027ed5846e92 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -282,7 +282,7 @@ libavdevice avfoundation.m Thilo Borgmann - decklink* Deti Fliegl + decklink* Marton Balint dshow.c Roger Pack (CC rogerdpack@gmail.com) fbdev_enc.c Lukasz Marek gdigrab.c Roger Pack (CC rogerdpack@gmail.com) From 3dc01223ef5248ec559e439fb22c38721151c894 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sat, 30 Sep 2017 23:40:45 +0200 Subject: [PATCH 3254/3374] avdevice/decklink_dec: fix multipacket op47 decoding It was disabled by mistake. Signed-off-by: Marton Balint --- libavdevice/decklink_dec.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index 53ff576ec5975..f496a580595d4 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -379,7 +379,7 @@ uint8_t *get_metadata(AVFormatContext *avctx, uint16_t *buf, size_t width, av_log(avctx, AV_LOG_WARNING, "VANC parity or checksum incorrect\n"); goto skip_packet; } - tgt = teletext_data_unit_from_ancillary_packet(buf + 3, buf + len, tgt, cctx->teletext_lines, 0); + tgt = teletext_data_unit_from_ancillary_packet(buf + 3, buf + len, tgt, cctx->teletext_lines, 1); } else if (did == 0x61 && sdid == 0x01) { unsigned int data_len; uint8_t *data; From b6782a192e18161f33fc5e943b6f33dcb97e7287 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Tue, 26 Sep 2017 12:06:20 -0400 Subject: [PATCH 3255/3374] avdevice/decklink: Fix segfault when running -list_devices on OSX The string is allocated with CFStringGetCString but was being deallocated with free(), which would intermittently result in a segmentation fault. Use the correct function for freeing the allocated CFString. Signed-off-by: Devin Heitmueller Signed-off-by: Marton Balint --- libavdevice/decklink_common.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp index ff2df959095e6..c782171f2c321 100644 --- a/libavdevice/decklink_common.cpp +++ b/libavdevice/decklink_common.cpp @@ -84,7 +84,7 @@ static char *dup_cfstring_to_utf8(CFStringRef w) } #define DECKLINK_STR const __CFString * #define DECKLINK_STRDUP dup_cfstring_to_utf8 -#define DECKLINK_FREE(s) free((void *) s) +#define DECKLINK_FREE(s) CFRelease(s) #define DECKLINK_BOOL bool #else #define DECKLINK_STR const char * From ede233a278896209cb78a1c298b5ed44d4792a23 Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 4 Oct 2017 18:55:32 -0300 Subject: [PATCH 3256/3374] configure: fix detecting libdl when dlsym requires extra linker flags Regression since 84b3f53acadced2dd31f6be95b491b25183b8c22. --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 2efc79e74ddec..391c141e7a3f0 100755 --- a/configure +++ b/configure @@ -5872,7 +5872,7 @@ enabled bzlib && check_lib bzlib bzlib.h BZ2_bzlibVersion -lbz2 enabled lzma && check_lib lzma lzma.h lzma_version_number -llzma # On some systems dynamic loading requires no extra linker flags -check_lib libdl dlfcn.h dlopen || { check_func dlsym -ldl && check_lib libdl dlfcn.h dlopen -ldl; } +check_lib libdl dlfcn.h "dlopen dlsym" || check_lib libdl dlfcn.h "dlopen dlsym" -ldl check_lib libm math.h sin -lm && LIBM="-lm" From a0d076f3ef95e971014c4333c71b384976484889 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Tue, 3 Oct 2017 20:57:14 +0100 Subject: [PATCH 3257/3374] lavc/v4l2: Remove use of lfind() This is not present in older bionic and therefore fails to build there, and the code is much simpler without it anyway. --- libavcodec/v4l2_fmt.c | 73 +++++++++------------------------------ libavcodec/v4l2_m2m_enc.c | 32 +++++++---------- 2 files changed, 28 insertions(+), 77 deletions(-) diff --git a/libavcodec/v4l2_fmt.c b/libavcodec/v4l2_fmt.c index a7ce30869623f..6df47e3f5a3c4 100644 --- a/libavcodec/v4l2_fmt.c +++ b/libavcodec/v4l2_fmt.c @@ -109,74 +109,33 @@ static const struct fmt_conversion { #endif }; -static int match_codec(const void *a, const void *b) -{ - if (*(enum AVCodecID *)a == ((struct fmt_conversion *)b)->avcodec) - return 0; - - return 1; -} - uint32_t ff_v4l2_format_avcodec_to_v4l2(enum AVCodecID avcodec) { - size_t len = FF_ARRAY_ELEMS(fmt_map); - struct fmt_conversion *item; - - item = lfind(&avcodec, fmt_map, &len, sizeof(fmt_map[0]), match_codec); - if (item) - return item->v4l2_fmt; - + int i; + for (i = 0; i < FF_ARRAY_ELEMS(fmt_map); i++) { + if (fmt_map[i].avcodec == avcodec) + return fmt_map[i].v4l2_fmt; + } return 0; } -static int match_fmt(const void *a, const void *b) -{ - if ( *(enum AVPixelFormat *)a == ((struct fmt_conversion *)b)->avfmt) - return 0; - - return 1; -} - uint32_t ff_v4l2_format_avfmt_to_v4l2(enum AVPixelFormat avfmt) { - size_t len = FF_ARRAY_ELEMS(fmt_map); - struct fmt_conversion *item; - - item = lfind(&avfmt, fmt_map, &len, sizeof(fmt_map[0]), match_fmt); - if (item) - return item->v4l2_fmt; - + int i; + for (i = 0; i < FF_ARRAY_ELEMS(fmt_map); i++) { + if (fmt_map[i].avfmt == avfmt) + return fmt_map[i].v4l2_fmt; + } return 0; } -struct v4l2fmt_avcodec_pair { - enum AVCodecID avcodec; - uint32_t v4l2_fmt; -}; - -static int match_codecfmt(const void *a, const void *b) -{ - struct v4l2fmt_avcodec_pair *key = (struct v4l2fmt_avcodec_pair *) a; - struct fmt_conversion *item = (struct fmt_conversion *) b; - - if (key->avcodec == item->avcodec && key->v4l2_fmt == item->v4l2_fmt) - return 0; - - return 1; -} - enum AVPixelFormat ff_v4l2_format_v4l2_to_avfmt(uint32_t v4l2_fmt, enum AVCodecID avcodec) { - struct v4l2fmt_avcodec_pair const key = { - .v4l2_fmt = v4l2_fmt, - .avcodec = avcodec, - }; - size_t len = FF_ARRAY_ELEMS(fmt_map); - struct fmt_conversion *item; - - item = lfind(&key, fmt_map, &len, sizeof(fmt_map[0]), match_codecfmt); - if (item) - return item->avfmt; - + int i; + for (i = 0; i < FF_ARRAY_ELEMS(fmt_map); i++) { + if (fmt_map[i].avcodec == avcodec && + fmt_map[i].v4l2_fmt == v4l2_fmt) + return fmt_map[i].avfmt; + } return AV_PIX_FMT_NONE; } diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c index e40a120b533fd..9f59be6efbf9a 100644 --- a/libavcodec/v4l2_m2m_enc.c +++ b/libavcodec/v4l2_m2m_enc.c @@ -91,20 +91,12 @@ static inline int v4l2_get_ext_ctrl(V4L2m2mContext *s, unsigned int id, signed i return 0; } -static int match_profile(const void *a, const void *b) -{ - if (*(unsigned int *)a == *(unsigned int *)b) - return 0; - - return 1; -} - static inline unsigned int v4l2_h264_profile_from_ff(int p) { struct h264_profile { unsigned int ffmpeg_val; unsigned int v4l2_val; - } *val, profile[] = { + } profile[] = { { FF_PROFILE_H264_CONSTRAINED_BASELINE, MPEG_VIDEO(H264_PROFILE_CONSTRAINED_BASELINE) }, { FF_PROFILE_H264_HIGH_444_PREDICTIVE, MPEG_VIDEO(H264_PROFILE_HIGH_444_PREDICTIVE) }, { FF_PROFILE_H264_HIGH_422_INTRA, MPEG_VIDEO(H264_PROFILE_HIGH_422_INTRA) }, @@ -117,12 +109,12 @@ static inline unsigned int v4l2_h264_profile_from_ff(int p) { FF_PROFILE_H264_MAIN, MPEG_VIDEO(H264_PROFILE_MAIN) }, { FF_PROFILE_H264_HIGH, MPEG_VIDEO(H264_PROFILE_HIGH) }, }; - size_t len = FF_ARRAY_ELEMS(profile); - - val = lfind(&p, profile, &len, sizeof(profile[0]), match_profile); - if (val) - return val->v4l2_val; + int i; + for (i = 0; i < FF_ARRAY_ELEMS(profile); i++) { + if (profile[i].ffmpeg_val == p) + return profile[i].v4l2_val; + } return AVERROR(ENOENT); } @@ -131,19 +123,19 @@ static inline int v4l2_mpeg4_profile_from_ff(int p) struct mpeg4_profile { unsigned int ffmpeg_val; unsigned int v4l2_val; - } *val, profile[] = { + } profile[] = { { FF_PROFILE_MPEG4_ADVANCED_CODING, MPEG_VIDEO(MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY) }, { FF_PROFILE_MPEG4_ADVANCED_SIMPLE, MPEG_VIDEO(MPEG4_PROFILE_ADVANCED_SIMPLE) }, { FF_PROFILE_MPEG4_SIMPLE_SCALABLE, MPEG_VIDEO(MPEG4_PROFILE_SIMPLE_SCALABLE) }, { FF_PROFILE_MPEG4_SIMPLE, MPEG_VIDEO(MPEG4_PROFILE_SIMPLE) }, { FF_PROFILE_MPEG4_CORE, MPEG_VIDEO(MPEG4_PROFILE_CORE) }, }; - size_t len = FF_ARRAY_ELEMS(profile); - - val = lfind(&p, profile, &len, sizeof(profile[0]), match_profile); - if (val) - return val->v4l2_val; + int i; + for (i = 0; i < FF_ARRAY_ELEMS(profile); i++) { + if (profile[i].ffmpeg_val == p) + return profile[i].v4l2_val; + } return AVERROR(ENOENT); } From 8da5af258423db4e24832b4a880cf6b78d410262 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Tue, 3 Oct 2017 21:02:25 +0100 Subject: [PATCH 3258/3374] lavc/v4l2: Mark static const tables as such --- libavcodec/v4l2_m2m_enc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c index 9f59be6efbf9a..b0d5a3bd15f6f 100644 --- a/libavcodec/v4l2_m2m_enc.c +++ b/libavcodec/v4l2_m2m_enc.c @@ -93,7 +93,7 @@ static inline int v4l2_get_ext_ctrl(V4L2m2mContext *s, unsigned int id, signed i static inline unsigned int v4l2_h264_profile_from_ff(int p) { - struct h264_profile { + static const struct h264_profile { unsigned int ffmpeg_val; unsigned int v4l2_val; } profile[] = { @@ -120,7 +120,7 @@ static inline unsigned int v4l2_h264_profile_from_ff(int p) static inline int v4l2_mpeg4_profile_from_ff(int p) { - struct mpeg4_profile { + static const struct mpeg4_profile { unsigned int ffmpeg_val; unsigned int v4l2_val; } profile[] = { From 44188993a1865e6a4e204908319f06cec39d5ee9 Mon Sep 17 00:00:00 2001 From: Jorge Ramirez-Ortiz Date: Wed, 4 Oct 2017 21:04:16 +0200 Subject: [PATCH 3259/3374] avcodec/v4l2: set sizeimage param for non-raw buffers [fixes #6716] Some V4L2 drivers fail to allocate buffers when sizeimage is not set to a max value. This is indeed the case for s5p-mfc [1] Most drivers should be able to calculate this value from the frame dimensions and format - or at least have their own default. However since this work around should not impact those drivers doing the "right thing" this commit just provides such a default. The calculations were extracted from the v4l2 driver used to develop the ffmpeg v4l2_m2m support [2]. See venc.c and vdec.c [1] linux.git/drivers/media/platform/s5p-mfc [2] linux.git/drivers/media/platform/qcom/venus/ --- libavcodec/v4l2_context.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c index 297792f871036..9f3b56ddabf7d 100644 --- a/libavcodec/v4l2_context.c +++ b/libavcodec/v4l2_context.c @@ -90,6 +90,20 @@ static inline int v4l2_type_supported(V4L2Context *ctx) ctx->type == V4L2_BUF_TYPE_VIDEO_OUTPUT; } +static inline int v4l2_get_framesize_compressed(V4L2Context* ctx, int width, int height) +{ + V4L2m2mContext *s = ctx_to_m2mctx(ctx); + const int SZ_4K = 0x1000; + int size; + + if (av_codec_is_decoder(s->avctx->codec)) + return ((width * height * 3 / 2) / 2) + 128; + + /* encoder */ + size = FFALIGN(height, 32) * FFALIGN(width, 32) * 3 / 2 / 2; + return FFALIGN(size, SZ_4K); +} + static inline void v4l2_save_to_context(V4L2Context* ctx, struct v4l2_format_update *fmt) { ctx->format.type = ctx->type; @@ -101,13 +115,23 @@ static inline void v4l2_save_to_context(V4L2Context* ctx, struct v4l2_format_upd /* update the sizes to handle the reconfiguration of the capture stream at runtime */ ctx->format.fmt.pix_mp.height = ctx->height; ctx->format.fmt.pix_mp.width = ctx->width; - if (fmt->update_v4l2) + if (fmt->update_v4l2) { ctx->format.fmt.pix_mp.pixelformat = fmt->v4l2_fmt; + + /* s5p-mfc requires the user to specify a buffer size */ + ctx->format.fmt.pix_mp.plane_fmt[0].sizeimage = + v4l2_get_framesize_compressed(ctx, ctx->width, ctx->height); + } } else { ctx->format.fmt.pix.height = ctx->height; ctx->format.fmt.pix.width = ctx->width; - if (fmt->update_v4l2) + if (fmt->update_v4l2) { ctx->format.fmt.pix.pixelformat = fmt->v4l2_fmt; + + /* s5p-mfc requires the user to specify a buffer size */ + ctx->format.fmt.pix.sizeimage = + v4l2_get_framesize_compressed(ctx, ctx->width, ctx->height); + } } } From df62b70de8aaa285168e72fe8f6e740843ca91fa Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 30 Sep 2017 00:20:09 +0200 Subject: [PATCH 3260/3374] avcodec/x86/lossless_videoencdsp: Fix handling of small widths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes out of array access Fixes: crash-huf.avi Regression since: 6b41b4414934cc930468ccd5db598dd6ef643987 This could also be fixed by adding checks in the C code that calls the dsp Found-by: Zhibin Hu and 连一汉 Signed-off-by: Michael Niedermayer --- libavcodec/x86/lossless_videoencdsp.asm | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/libavcodec/x86/lossless_videoencdsp.asm b/libavcodec/x86/lossless_videoencdsp.asm index 3cb7dce07fb21..a9c7a0a73c1d5 100644 --- a/libavcodec/x86/lossless_videoencdsp.asm +++ b/libavcodec/x86/lossless_videoencdsp.asm @@ -42,10 +42,11 @@ cglobal diff_bytes, 4,5,2, dst, src1, src2, w %define i t0q %endmacro -; label to jump to if w < regsize -%macro DIFF_BYTES_LOOP_PREP 1 +; labels to jump to if w < regsize and w < 0 +%macro DIFF_BYTES_LOOP_PREP 2 mov i, wq and i, -2 * regsize + js %2 jz %1 add dstq, i add src1q, i @@ -87,7 +88,7 @@ cglobal diff_bytes, 4,5,2, dst, src1, src2, w %if mmsize > 16 ; fall back to narrower xmm %define regsize mmsize / 2 - DIFF_BYTES_LOOP_PREP .setup_loop_gpr_aa + DIFF_BYTES_LOOP_PREP .setup_loop_gpr_aa, .end_aa .loop2_%1%2: DIFF_BYTES_LOOP_CORE %1, %2, xm0, xm1 add i, 2 * regsize @@ -114,7 +115,7 @@ cglobal diff_bytes, 4,5,2, dst, src1, src2, w INIT_MMX mmx DIFF_BYTES_PROLOGUE %define regsize mmsize - DIFF_BYTES_LOOP_PREP .skip_main_aa + DIFF_BYTES_LOOP_PREP .skip_main_aa, .end_aa DIFF_BYTES_BODY a, a %undef i %endif @@ -122,7 +123,7 @@ DIFF_BYTES_PROLOGUE INIT_XMM sse2 DIFF_BYTES_PROLOGUE %define regsize mmsize - DIFF_BYTES_LOOP_PREP .skip_main_aa + DIFF_BYTES_LOOP_PREP .skip_main_aa, .end_aa test dstq, regsize - 1 jnz .loop_uu test src1q, regsize - 1 @@ -138,7 +139,7 @@ DIFF_BYTES_PROLOGUE %define regsize mmsize ; Directly using unaligned SSE2 version is marginally faster than ; branching based on arguments. - DIFF_BYTES_LOOP_PREP .skip_main_uu + DIFF_BYTES_LOOP_PREP .skip_main_uu, .end_uu test dstq, regsize - 1 jnz .loop_uu test src1q, regsize - 1 From 26ea142658a8be16d13bb430ced14ef544f8afe9 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 30 Sep 2017 00:26:51 +0200 Subject: [PATCH 3261/3374] avcodec/x86/lossless_videoencdsp: Fix warning: signed dword value exceeds bounds Add () to regsize define Suggested-by: Henrik Gramner Signed-off-by: Michael Niedermayer --- libavcodec/x86/lossless_videoencdsp.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/x86/lossless_videoencdsp.asm b/libavcodec/x86/lossless_videoencdsp.asm index a9c7a0a73c1d5..4d79eee36ba1a 100644 --- a/libavcodec/x86/lossless_videoencdsp.asm +++ b/libavcodec/x86/lossless_videoencdsp.asm @@ -87,7 +87,7 @@ cglobal diff_bytes, 4,5,2, dst, src1, src2, w jz .end_%1%2 %if mmsize > 16 ; fall back to narrower xmm - %define regsize mmsize / 2 + %define regsize (mmsize / 2) DIFF_BYTES_LOOP_PREP .setup_loop_gpr_aa, .end_aa .loop2_%1%2: DIFF_BYTES_LOOP_CORE %1, %2, xm0, xm1 From 18279738f9a28fecded6c87a0608af6a8793108d Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 4 Oct 2017 23:51:17 -0300 Subject: [PATCH 3262/3374] x86/blockdsp: use three operand form for an instruction Fixes assembling with old yasm. --- libavcodec/x86/blockdsp.asm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/x86/blockdsp.asm b/libavcodec/x86/blockdsp.asm index 2498bd40b3c69..9d203df8f5217 100644 --- a/libavcodec/x86/blockdsp.asm +++ b/libavcodec/x86/blockdsp.asm @@ -34,7 +34,7 @@ SECTION .text ; %2 = number of inline store loops %macro CLEAR_BLOCK 2 cglobal clear_block, 1, 1, %1, blocks - ZERO m0, m0 + ZERO m0, m0, m0 %assign %%i 0 %rep %2 mova [blocksq+mmsize*(0+%%i)], m0 @@ -63,7 +63,7 @@ CLEAR_BLOCK 1, 1 cglobal clear_blocks, 1, 2, %1, blocks, len add blocksq, 768 mov lenq, -768 - ZERO m0, m0 + ZERO m0, m0, m0 .loop: mova [blocksq+lenq+mmsize*0], m0 mova [blocksq+lenq+mmsize*1], m0 From c941e99b7f7ba16230aa72e644d519c33004dd47 Mon Sep 17 00:00:00 2001 From: Tobias Rapp Date: Fri, 29 Sep 2017 16:28:47 +0200 Subject: [PATCH 3263/3374] avformat/wavenc: replace literal numbers with enum constants Signed-off-by: Tobias Rapp --- libavformat/wavenc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavformat/wavenc.c b/libavformat/wavenc.c index 7f3059e99a998..adb20cb215689 100644 --- a/libavformat/wavenc.c +++ b/libavformat/wavenc.c @@ -331,7 +331,7 @@ static int wav_write_header(AVFormatContext *s) ffio_fill(pb, 0, 28); } - if (wav->write_peak != 2) { + if (wav->write_peak != PEAK_ONLY) { /* format header */ fmt = ff_start_tag(pb, "fmt "); if (ff_put_wav_header(s, pb, s->streams[0]->codecpar, 0) < 0) { @@ -363,7 +363,7 @@ static int wav_write_header(AVFormatContext *s) wav->maxpts = wav->last_duration = 0; wav->minpts = INT64_MAX; - if (wav->write_peak != 2) { + if (wav->write_peak != PEAK_ONLY) { /* info header */ ff_riff_write_info(s); @@ -381,7 +381,7 @@ static int wav_write_packet(AVFormatContext *s, AVPacket *pkt) AVIOContext *pb = s->pb; WAVMuxContext *wav = s->priv_data; - if (wav->write_peak != 2) + if (wav->write_peak != PEAK_ONLY) avio_write(pb, pkt->data, pkt->size); if (wav->write_peak) { @@ -426,7 +426,7 @@ static int wav_write_trailer(AVFormatContext *s) avio_flush(pb); if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) { - if (wav->write_peak != 2 && avio_tell(pb) - wav->data < UINT32_MAX) { + if (wav->write_peak != PEAK_ONLY && avio_tell(pb) - wav->data < UINT32_MAX) { ff_end_tag(pb, wav->data); avio_flush(pb); } From e01a270762c1b79e10566e5e55a7eb4488b8a25b Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Thu, 5 Oct 2017 01:06:08 +0100 Subject: [PATCH 3264/3374] lavc/v4l2: Fix printf format for int64_t --- libavcodec/v4l2_m2m_enc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c index b0d5a3bd15f6f..f71ce5fb74af1 100644 --- a/libavcodec/v4l2_m2m_enc.c +++ b/libavcodec/v4l2_m2m_enc.c @@ -180,7 +180,7 @@ static int v4l2_prepare_encoder(V4L2m2mContext *s) av_log(avctx, AV_LOG_DEBUG, "Encoder Context: id (%d), profile (%d), frame rate(%d/%d), number b-frames (%d), " - "gop size (%d), bit rate (%ld), qmin (%d), qmax (%d)\n", + "gop size (%d), bit rate (%"PRId64"), qmin (%d), qmax (%d)\n", avctx->codec_id, avctx->profile, avctx->framerate.num, avctx->framerate.den, avctx->max_b_frames, avctx->gop_size, avctx->bit_rate, avctx->qmin, avctx->qmax); From 4f5fb7813423ae67d3a6897999cc97e02f75dee1 Mon Sep 17 00:00:00 2001 From: Tobias Rapp Date: Thu, 5 Oct 2017 10:14:26 +0200 Subject: [PATCH 3265/3374] doc/filters: align order of fps filter options to implementation Align order of "start_time" option within fps filter documentation to actual implementation. Also fix some documentation cosmetics. Signed-off-by: Tobias Rapp --- doc/filters.texi | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 601701f591b03..624e5cd01b9a8 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -8669,13 +8669,21 @@ It accepts the following parameters: @item fps The desired output frame rate. The default is @code{25}. +@item start_time +Assume the first PTS should be the given value, in seconds. This allows for +padding/trimming at the start of stream. By default, no assumption is made +about the first frame's expected PTS, so no padding or trimming is done. +For example, this could be set to 0 to pad the beginning with duplicates of +the first frame if a video stream starts after the audio stream or to trim any +frames with a negative PTS. + @item round -Rounding method. +Timestamp (PTS) rounding method. Possible values are: @table @option @item zero -zero round towards 0 +round towards 0 @item inf round away from 0 @item down @@ -8687,18 +8695,10 @@ round to nearest @end table The default is @code{near}. -@item start_time -Assume the first PTS should be the given value, in seconds. This allows for -padding/trimming at the start of stream. By default, no assumption is made -about the first frame's expected PTS, so no padding or trimming is done. -For example, this could be set to 0 to pad the beginning with duplicates of -the first frame if a video stream starts after the audio stream or to trim any -frames with a negative PTS. - @end table Alternatively, the options can be specified as a flat string: -@var{fps}[:@var{round}]. +@var{fps}[:@var{start_time}[:@var{round}]]. See also the @ref{setpts} filter. From 0a499d6a57409926011e1952fcf7ca39224663d6 Mon Sep 17 00:00:00 2001 From: Tobias Rapp Date: Thu, 5 Oct 2017 10:18:57 +0200 Subject: [PATCH 3266/3374] avfilter/vf_fps: clean-up filter options Add missing AV_OPT_FLAG_FILTERING_PARAM flag to "start_time" option. Fix indent of "round" named constants and clear unused field values. Signed-off-by: Tobias Rapp --- libavfilter/vf_fps.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c index 1e5d07e31c148..a5e51c3bbb5d8 100644 --- a/libavfilter/vf_fps.c +++ b/libavfilter/vf_fps.c @@ -65,13 +65,13 @@ typedef struct FPSContext { #define F AV_OPT_FLAG_FILTERING_PARAM static const AVOption fps_options[] = { { "fps", "A string describing desired output framerate", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, { .str = "25" }, 0, INT_MAX, V|F }, - { "start_time", "Assume the first PTS should be this value.", OFFSET(start_time), AV_OPT_TYPE_DOUBLE, { .dbl = DBL_MAX}, -DBL_MAX, DBL_MAX, V }, + { "start_time", "Assume the first PTS should be this value.", OFFSET(start_time), AV_OPT_TYPE_DOUBLE, { .dbl = DBL_MAX}, -DBL_MAX, DBL_MAX, V|F }, { "round", "set rounding method for timestamps", OFFSET(rounding), AV_OPT_TYPE_INT, { .i64 = AV_ROUND_NEAR_INF }, 0, 5, V|F, "round" }, - { "zero", "round towards 0", OFFSET(rounding), AV_OPT_TYPE_CONST, { .i64 = AV_ROUND_ZERO }, 0, 5, V|F, "round" }, - { "inf", "round away from 0", OFFSET(rounding), AV_OPT_TYPE_CONST, { .i64 = AV_ROUND_INF }, 0, 5, V|F, "round" }, - { "down", "round towards -infty", OFFSET(rounding), AV_OPT_TYPE_CONST, { .i64 = AV_ROUND_DOWN }, 0, 5, V|F, "round" }, - { "up", "round towards +infty", OFFSET(rounding), AV_OPT_TYPE_CONST, { .i64 = AV_ROUND_UP }, 0, 5, V|F, "round" }, - { "near", "round to nearest", OFFSET(rounding), AV_OPT_TYPE_CONST, { .i64 = AV_ROUND_NEAR_INF }, 0, 5, V|F, "round" }, + { "zero", "round towards 0", 0, AV_OPT_TYPE_CONST, { .i64 = AV_ROUND_ZERO }, 0, 0, V|F, "round" }, + { "inf", "round away from 0", 0, AV_OPT_TYPE_CONST, { .i64 = AV_ROUND_INF }, 0, 0, V|F, "round" }, + { "down", "round towards -infty", 0, AV_OPT_TYPE_CONST, { .i64 = AV_ROUND_DOWN }, 0, 0, V|F, "round" }, + { "up", "round towards +infty", 0, AV_OPT_TYPE_CONST, { .i64 = AV_ROUND_UP }, 0, 0, V|F, "round" }, + { "near", "round to nearest", 0, AV_OPT_TYPE_CONST, { .i64 = AV_ROUND_NEAR_INF }, 0, 0, V|F, "round" }, { NULL } }; From cafd9d66ed9e1bad4ae579a3935f7af57a567a51 Mon Sep 17 00:00:00 2001 From: James Almer Date: Thu, 5 Oct 2017 00:47:41 -0300 Subject: [PATCH 3267/3374] build: add install targets for the examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split it off from install-data. Among other things, this prevents spamming triplicate log lines during install. Reviewed-by: Clément Bœsch Signed-off-by: James Almer --- Makefile | 6 ++---- doc/examples/Makefile | 14 +++++++++++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 3007da50f765f..4a1253a052ec5 100644 --- a/Makefile +++ b/Makefile @@ -120,11 +120,9 @@ install: install-libs install-headers install-libs: install-libs-yes -install-data: $(DATA_FILES) $(EXAMPLES_FILES) $(EXAMPLE_MAKEFILE) - $(Q)mkdir -p "$(DATADIR)/examples" +install-data: $(DATA_FILES) + $(Q)mkdir -p "$(DATADIR)" $(INSTALL) -m 644 $(DATA_FILES) "$(DATADIR)" - $(INSTALL) -m 644 $(EXAMPLES_FILES) "$(DATADIR)/examples" - $(INSTALL) -m 644 $(EXAMPLE_MAKEFILE:%=%.example) "$(DATADIR)/examples/Makefile" uninstall: uninstall-libs uninstall-headers uninstall-data diff --git a/doc/examples/Makefile b/doc/examples/Makefile index af000d9ddb6a5..58afd71b85bb9 100644 --- a/doc/examples/Makefile +++ b/doc/examples/Makefile @@ -26,8 +26,8 @@ ALL_EXAMPLES := $(EXAMPLES) $(EXAMPLES-:%=doc/examples/%$(PROGSSUF)$(EXESUF)) ALL_EXAMPLES_G := $(EXAMPLES_G) $(EXAMPLES-:%=doc/examples/%$(PROGSSUF)_g$(EXESUF)) PROGS += $(EXAMPLES) -EXAMPLES_FILES := $(wildcard $(SRC_PATH)/doc/examples/*.c) $(SRC_PATH)/doc/examples/README EXAMPLE_MAKEFILE := $(SRC_PATH)/doc/examples/Makefile +EXAMPLES_FILES := $(wildcard $(SRC_PATH)/doc/examples/*.c) $(SRC_PATH)/doc/examples/README $(EXAMPLE_MAKEFILE) $(foreach P,$(EXAMPLES),$(eval OBJS-$(P:%$(PROGSSUF)$(EXESUF)=%) = $(P:%$(PROGSSUF)$(EXESUF)=%).o)) $(EXAMPLES_G): %$(PROGSSUF)_g$(EXESUF): %.o @@ -39,6 +39,18 @@ OBJDIRS += doc/examples DOXY_INPUT += $(EXAMPLES:%$(PROGSSUF)$(EXESUF)=%.c) +install: install-examples + +install-examples: $(EXAMPLES_FILES) + $(Q)mkdir -p "$(DATADIR)/examples" + $(INSTALL) -m 644 $(EXAMPLES_FILES) "$(DATADIR)/examples" + $(INSTALL) -m 644 $(EXAMPLE_MAKEFILE:%=%.example) "$(DATADIR)/examples/Makefile" + +uninstall: uninstall-examples + +uninstall-examples: + $(RM) -r "$(DATADIR)/examples" + examplesclean: $(RM) $(ALL_EXAMPLES) $(ALL_EXAMPLES_G) $(RM) $(CLEANSUFFIXES:%=doc/examples/%) From 1fd80106be3dca9fa0ea13fb364c8d221bd27c15 Mon Sep 17 00:00:00 2001 From: Lukas Stabe Date: Thu, 5 Oct 2017 03:34:19 +0200 Subject: [PATCH 3268/3374] avformat: fix id3 chapters These changes store id3 chapter data in ID3v2ExtraMeta and introduce ff_id3v2_parse_chapters to parse them into the format context if needed. Encoders using ff_id3v2_read, which previously parsed chapters into the format context automatically, were adjusted to call ff_id3v2_parse_chapters. Signed-off-by: wm4 --- libavformat/aiffdec.c | 3 +- libavformat/asfdec_f.c | 4 +- libavformat/asfdec_o.c | 4 +- libavformat/dsfdec.c | 4 +- libavformat/id3v2.c | 120 ++++++++++++++++++++++++++++++----------- libavformat/id3v2.h | 15 ++++-- libavformat/iff.c | 3 +- libavformat/omadec.c | 5 ++ libavformat/utils.c | 2 + 9 files changed, 122 insertions(+), 38 deletions(-) diff --git a/libavformat/aiffdec.c b/libavformat/aiffdec.c index 2ef9386edb84e..99e05c78ecac3 100644 --- a/libavformat/aiffdec.c +++ b/libavformat/aiffdec.c @@ -258,7 +258,8 @@ static int aiff_read_header(AVFormatContext *s) position = avio_tell(pb); ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, size); if (id3v2_extra_meta) - if ((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0) { + if ((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0 || + (ret = ff_id3v2_parse_chapters(s, &id3v2_extra_meta)) < 0) { ff_id3v2_free_extra_meta(&id3v2_extra_meta); return ret; } diff --git a/libavformat/asfdec_f.c b/libavformat/asfdec_f.c index cc648b9a2f055..64a0b9d7f2ae1 100644 --- a/libavformat/asfdec_f.c +++ b/libavformat/asfdec_f.c @@ -307,8 +307,10 @@ static void get_id3_tag(AVFormatContext *s, int len) ID3v2ExtraMeta *id3v2_extra_meta = NULL; ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, len); - if (id3v2_extra_meta) + if (id3v2_extra_meta) { ff_id3v2_parse_apic(s, &id3v2_extra_meta); + ff_id3v2_parse_chapters(s, &id3v2_extra_meta); + } ff_id3v2_free_extra_meta(&id3v2_extra_meta); } diff --git a/libavformat/asfdec_o.c b/libavformat/asfdec_o.c index 818d6f3573ae0..5122e33c78706 100644 --- a/libavformat/asfdec_o.c +++ b/libavformat/asfdec_o.c @@ -460,8 +460,10 @@ static void get_id3_tag(AVFormatContext *s, int len) ID3v2ExtraMeta *id3v2_extra_meta = NULL; ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, len); - if (id3v2_extra_meta) + if (id3v2_extra_meta) { ff_id3v2_parse_apic(s, &id3v2_extra_meta); + ff_id3v2_parse_chapters(s, &id3v2_extra_meta); + } ff_id3v2_free_extra_meta(&id3v2_extra_meta); } diff --git a/libavformat/dsfdec.c b/libavformat/dsfdec.c index 49ca336427492..41538fd83c0c1 100644 --- a/libavformat/dsfdec.c +++ b/libavformat/dsfdec.c @@ -53,8 +53,10 @@ static void read_id3(AVFormatContext *s, uint64_t id3pos) return; ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, 0); - if (id3v2_extra_meta) + if (id3v2_extra_meta) { ff_id3v2_parse_apic(s, &id3v2_extra_meta); + ff_id3v2_parse_chapters(s, &id3v2_extra_meta); + } ff_id3v2_free_extra_meta(&id3v2_extra_meta); } diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index f15cefee4799c..6c216ba7a251a 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -670,59 +670,68 @@ static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, avio_seek(pb, end, SEEK_SET); } +static void free_chapter(void *obj) +{ + ID3v2ExtraMetaCHAP *chap = obj; + av_freep(&chap->element_id); + av_dict_free(&chap->meta); + av_freep(&chap); +} + static void read_chapter(AVFormatContext *s, AVIOContext *pb, int len, const char *ttag, ID3v2ExtraMeta **extra_meta, int isv34) { - AVRational time_base = {1, 1000}; - uint32_t start, end; - AVChapter *chapter; - uint8_t *dst = NULL; int taglen; char tag[5]; + ID3v2ExtraMeta *new_extra = NULL; + ID3v2ExtraMetaCHAP *chap = NULL; - if (!s) { - /* We should probably just put the chapter data to extra_meta here - * and do the AVFormatContext-needing part in a separate - * ff_id3v2_parse_apic()-like function. */ - av_log(NULL, AV_LOG_DEBUG, "No AVFormatContext, skipped ID3 chapter data\n"); - return; - } + new_extra = av_mallocz(sizeof(*new_extra)); + chap = av_mallocz(sizeof(*chap)); + + if (!new_extra || !chap) + goto fail; + + if (decode_str(s, pb, 0, &chap->element_id, &len) < 0) + goto fail; - if (decode_str(s, pb, 0, &dst, &len) < 0) - return; if (len < 16) - return; + goto fail; - start = avio_rb32(pb); - end = avio_rb32(pb); + chap->start = avio_rb32(pb); + chap->end = avio_rb32(pb); avio_skip(pb, 8); - chapter = avpriv_new_chapter(s, s->nb_chapters + 1, time_base, start, end, dst); - if (!chapter) { - av_free(dst); - return; - } - len -= 16; while (len > 10) { if (avio_read(pb, tag, 4) < 4) - goto end; + goto fail; tag[4] = 0; taglen = avio_rb32(pb); avio_skip(pb, 2); len -= 10; if (taglen < 0 || taglen > len) - goto end; + goto fail; if (tag[0] == 'T') - read_ttag(s, pb, taglen, &chapter->metadata, tag); + read_ttag(s, pb, taglen, &chap->meta, tag); else avio_skip(pb, taglen); len -= taglen; } - ff_metadata_conv(&chapter->metadata, NULL, ff_id3v2_34_metadata_conv); - ff_metadata_conv(&chapter->metadata, NULL, ff_id3v2_4_metadata_conv); -end: - av_free(dst); + ff_metadata_conv(&chap->meta, NULL, ff_id3v2_34_metadata_conv); + ff_metadata_conv(&chap->meta, NULL, ff_id3v2_4_metadata_conv); + + new_extra->tag = "CHAP"; + new_extra->data = chap; + new_extra->next = *extra_meta; + *extra_meta = new_extra; + + return; + +fail: + if (chap) + free_chapter(chap); + av_freep(&new_extra); } static void free_priv(void *obj) @@ -782,7 +791,7 @@ typedef struct ID3v2EMFunc { static const ID3v2EMFunc id3v2_extra_meta_funcs[] = { { "GEO", "GEOB", read_geobtag, free_geobtag }, { "PIC", "APIC", read_apic, free_apic }, - { "CHAP","CHAP", read_chapter, NULL }, + { "CHAP","CHAP", read_chapter, free_chapter }, { "PRIV","PRIV", read_priv, free_priv }, { NULL } }; @@ -1164,3 +1173,54 @@ int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta **extra_meta) return 0; } + +int ff_id3v2_parse_chapters(AVFormatContext *s, ID3v2ExtraMeta **extra_meta) +{ + int ret = 0; + ID3v2ExtraMeta *cur; + AVRational time_base = {1, 1000}; + ID3v2ExtraMetaCHAP **chapters = NULL; + int num_chapters = 0; + int i; + + // since extra_meta is a linked list where elements are prepended, + // we need to reverse the order of chapters + for (cur = *extra_meta; cur; cur = cur->next) { + ID3v2ExtraMetaCHAP *chap; + + if (strcmp(cur->tag, "CHAP")) + continue; + chap = cur->data; + + if ((ret = av_dynarray_add_nofree(&chapters, &num_chapters, chap)) < 0) + goto end; + } + + for (i = 0; i < (num_chapters / 2); i++) { + ID3v2ExtraMetaCHAP *right; + int right_index; + + right_index = (num_chapters - 1) - i; + right = chapters[right_index]; + + chapters[right_index] = chapters[i]; + chapters[i] = right; + } + + for (i = 0; i < num_chapters; i++) { + ID3v2ExtraMetaCHAP *chap; + AVChapter *chapter; + + chap = chapters[i]; + chapter = avpriv_new_chapter(s, i, time_base, chap->start, chap->end, chap->element_id); + if (!chapter) + continue; + + if ((ret = av_dict_copy(&chapter->metadata, chap->meta, 0)) < 0) + goto end; + } + +end: + av_freep(&chapters); + return ret; +} diff --git a/libavformat/id3v2.h b/libavformat/id3v2.h index 6e7a8c9abfb38..5e64ead096a82 100644 --- a/libavformat/id3v2.h +++ b/libavformat/id3v2.h @@ -79,6 +79,12 @@ typedef struct ID3v2ExtraMetaPRIV { uint32_t datasize; } ID3v2ExtraMetaPRIV; +typedef struct ID3v2ExtraMetaCHAP { + uint8_t *element_id; + uint32_t start, end; + AVDictionary *meta; +} ID3v2ExtraMetaCHAP; + /** * Detect ID3v2 Header. * @param buf must be ID3v2_HEADER_SIZE byte long @@ -97,8 +103,6 @@ int ff_id3v2_tag_len(const uint8_t *buf); /** * Read an ID3v2 tag into specified dictionary and retrieve supported extra metadata. * - * Chapters are not currently read by this variant. - * * @param metadata Parsed metadata is stored here * @param extra_meta If not NULL, extra metadata is parsed into a list of * ID3v2ExtraMeta structs and *extra_meta points to the head of the list @@ -106,7 +110,7 @@ int ff_id3v2_tag_len(const uint8_t *buf); void ff_id3v2_read_dict(AVIOContext *pb, AVDictionary **metadata, const char *magic, ID3v2ExtraMeta **extra_meta); /** - * Read an ID3v2 tag, including supported extra metadata and chapters. + * Read an ID3v2 tag, including supported extra metadata. * * Data is read from and stored to AVFormatContext. * @@ -158,6 +162,11 @@ void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta); */ int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta **extra_meta); +/** + * Create chapters for all CHAP tags found in the ID3v2 header. + */ +int ff_id3v2_parse_chapters(AVFormatContext *s, ID3v2ExtraMeta **extra_meta); + extern const AVMetadataConv ff_id3v2_34_metadata_conv[]; extern const AVMetadataConv ff_id3v2_4_metadata_conv[]; diff --git a/libavformat/iff.c b/libavformat/iff.c index 6a09eb0e31631..4cf17f6e1a950 100644 --- a/libavformat/iff.c +++ b/libavformat/iff.c @@ -312,7 +312,8 @@ static int parse_dsd_prop(AVFormatContext *s, AVStream *st, uint64_t eof) id3v2_extra_meta = NULL; ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, size); if (id3v2_extra_meta) { - if ((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0) { + if ((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0 || + (ret = ff_id3v2_parse_chapters(s, &id3v2_extra_meta)) < 0) { ff_id3v2_free_extra_meta(&id3v2_extra_meta); return ret; } diff --git a/libavformat/omadec.c b/libavformat/omadec.c index fa53636f1a112..423d52b3aaf09 100644 --- a/libavformat/omadec.c +++ b/libavformat/omadec.c @@ -397,6 +397,11 @@ static int oma_read_header(AVFormatContext *s) OMAContext *oc = s->priv_data; ff_id3v2_read(s, ID3v2_EA3_MAGIC, &extra_meta, 0); + if ((ret = ff_id3v2_parse_chapters(s, &extra_meta)) < 0) { + ff_id3v2_free_extra_meta(&extra_meta); + return ret; + } + ret = avio_read(s->pb, buf, EA3_HEADER_SIZE); if (ret < EA3_HEADER_SIZE) return -1; diff --git a/libavformat/utils.c b/libavformat/utils.c index 7abca632b56ff..1a7996c4fd854 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -613,6 +613,8 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, !strcmp(s->iformat->name, "tta")) { if ((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0) goto fail; + if ((ret = ff_id3v2_parse_chapters(s, &id3v2_extra_meta)) < 0) + goto fail; } else av_log(s, AV_LOG_DEBUG, "demuxer does not support additional id3 data, skipping\n"); } From 51ebce7d7d614b15a9f27c67e419b4e2859335d7 Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Thu, 5 Oct 2017 13:15:06 +0530 Subject: [PATCH 3269/3374] avcodec/mips: Cleanup unused functions Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/h264qpel_msa.c | 746 ----------------------------- libavcodec/mips/hevc_mc_uniw_msa.c | 67 --- libavcodec/mips/hevcdsp_msa.c | 50 -- 3 files changed, 863 deletions(-) diff --git a/libavcodec/mips/h264qpel_msa.c b/libavcodec/mips/h264qpel_msa.c index 0b42bc4f727f8..afc01833122d0 100644 --- a/libavcodec/mips/h264qpel_msa.c +++ b/libavcodec/mips/h264qpel_msa.c @@ -159,300 +159,6 @@ static const uint8_t luma_mask_arr[16 * 8] = { out0_m; \ } ) -static void avc_luma_hz_4w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height) -{ - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3; - v8i16 res0, res1; - v16u8 out; - v16i8 mask0, mask1, mask2; - v16i8 vec0, vec1, vec2, vec3, vec4, vec5; - v16i8 minus5b = __msa_ldi_b(-5); - v16i8 plus20b = __msa_ldi_b(20); - - LD_SB3(&luma_mask_arr[48], 16, mask0, mask1, mask2); - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - XORI_B4_128_SB(src0, src1, src2, src3); - VSHF_B2_SB(src0, src1, src2, src3, mask0, mask0, vec0, vec1); - HADD_SB2_SH(vec0, vec1, res0, res1); - VSHF_B2_SB(src0, src1, src2, src3, mask1, mask1, vec2, vec3); - DPADD_SB2_SH(vec2, vec3, minus5b, minus5b, res0, res1); - VSHF_B2_SB(src0, src1, src2, src3, mask2, mask2, vec4, vec5); - DPADD_SB2_SH(vec4, vec5, plus20b, plus20b, res0, res1); - SRARI_H2_SH(res0, res1, 5); - SAT_SH2_SH(res0, res1, 7); - out = PCKEV_XORI128_UB(res0, res1); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); - dst += (4 * dst_stride); - } -} - -static void avc_luma_hz_8w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height) -{ - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3; - v8i16 res0, res1, res2, res3; - v16i8 mask0, mask1, mask2; - v16i8 vec0, vec1, vec2, vec3, vec4, vec5; - v16i8 vec6, vec7, vec8, vec9, vec10, vec11; - v16i8 minus5b = __msa_ldi_b(-5); - v16i8 plus20b = __msa_ldi_b(20); - v16u8 out0, out1; - - LD_SB3(&luma_mask_arr[0], 16, mask0, mask1, mask2); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - XORI_B4_128_SB(src0, src1, src2, src3); - VSHF_B2_SB(src0, src0, src1, src1, mask0, mask0, vec0, vec1); - VSHF_B2_SB(src2, src2, src3, src3, mask0, mask0, vec2, vec3); - HADD_SB4_SH(vec0, vec1, vec2, vec3, res0, res1, res2, res3); - VSHF_B2_SB(src0, src0, src1, src1, mask1, mask1, vec4, vec5); - VSHF_B2_SB(src2, src2, src3, src3, mask1, mask1, vec6, vec7); - DPADD_SB4_SH(vec4, vec5, vec6, vec7, minus5b, minus5b, minus5b, minus5b, - res0, res1, res2, res3); - VSHF_B2_SB(src0, src0, src1, src1, mask2, mask2, vec8, vec9); - VSHF_B2_SB(src2, src2, src3, src3, mask2, mask2, vec10, vec11); - DPADD_SB4_SH(vec8, vec9, vec10, vec11, plus20b, plus20b, plus20b, - plus20b, res0, res1, res2, res3); - SRARI_H4_SH(res0, res1, res2, res3, 5); - SAT_SH4_SH(res0, res1, res2, res3, 7); - out0 = PCKEV_XORI128_UB(res0, res1); - out1 = PCKEV_XORI128_UB(res2, res3); - ST8x4_UB(out0, out1, dst, dst_stride); - dst += (4 * dst_stride); - } -} - -static void avc_luma_hz_16w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height) -{ - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7; - v8i16 res0, res1, res2, res3, res4, res5, res6, res7; - v16i8 mask0, mask1, mask2; - v16i8 vec0, vec1, vec2, vec3, vec4, vec5; - v16i8 vec6, vec7, vec8, vec9, vec10, vec11; - v16i8 minus5b = __msa_ldi_b(-5); - v16i8 plus20b = __msa_ldi_b(20); - - LD_SB3(&luma_mask_arr[0], 16, mask0, mask1, mask2); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB2(src, 8, src0, src1); - src += src_stride; - LD_SB2(src, 8, src2, src3); - src += src_stride; - - XORI_B4_128_SB(src0, src1, src2, src3); - VSHF_B2_SB(src0, src0, src1, src1, mask0, mask0, vec0, vec3); - VSHF_B2_SB(src2, src2, src3, src3, mask0, mask0, vec6, vec9); - VSHF_B2_SB(src0, src0, src1, src1, mask1, mask1, vec1, vec4); - VSHF_B2_SB(src2, src2, src3, src3, mask1, mask1, vec7, vec10); - VSHF_B2_SB(src0, src0, src1, src1, mask2, mask2, vec2, vec5); - VSHF_B2_SB(src2, src2, src3, src3, mask2, mask2, vec8, vec11); - HADD_SB4_SH(vec0, vec3, vec6, vec9, res0, res1, res2, res3); - DPADD_SB4_SH(vec1, vec4, vec7, vec10, minus5b, minus5b, minus5b, - minus5b, res0, res1, res2, res3); - DPADD_SB4_SH(vec2, vec5, vec8, vec11, plus20b, plus20b, plus20b, - plus20b, res0, res1, res2, res3); - - LD_SB2(src, 8, src4, src5); - src += src_stride; - LD_SB2(src, 8, src6, src7); - src += src_stride; - - XORI_B4_128_SB(src4, src5, src6, src7); - VSHF_B2_SB(src4, src4, src5, src5, mask0, mask0, vec0, vec3); - VSHF_B2_SB(src6, src6, src7, src7, mask0, mask0, vec6, vec9); - VSHF_B2_SB(src4, src4, src5, src5, mask1, mask1, vec1, vec4); - VSHF_B2_SB(src6, src6, src7, src7, mask1, mask1, vec7, vec10); - VSHF_B2_SB(src4, src4, src5, src5, mask2, mask2, vec2, vec5); - VSHF_B2_SB(src6, src6, src7, src7, mask2, mask2, vec8, vec11); - HADD_SB4_SH(vec0, vec3, vec6, vec9, res4, res5, res6, res7); - DPADD_SB4_SH(vec1, vec4, vec7, vec10, minus5b, minus5b, minus5b, - minus5b, res4, res5, res6, res7); - DPADD_SB4_SH(vec2, vec5, vec8, vec11, plus20b, plus20b, plus20b, - plus20b, res4, res5, res6, res7); - SRARI_H4_SH(res0, res1, res2, res3, 5); - SRARI_H4_SH(res4, res5, res6, res7, 5); - SAT_SH4_SH(res0, res1, res2, res3, 7); - SAT_SH4_SH(res4, res5, res6, res7, 7); - PCKEV_B4_SB(res1, res0, res3, res2, res5, res4, res7, res6, - vec0, vec1, vec2, vec3); - XORI_B4_128_SB(vec0, vec1, vec2, vec3); - - ST_SB4(vec0, vec1, vec2, vec3, dst, dst_stride); - dst += (4 * dst_stride); - } -} - -static void avc_luma_hz_qrt_4w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height, uint8_t hor_offset) -{ - uint8_t slide; - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3; - v8i16 res0, res1; - v16i8 res, mask0, mask1, mask2; - v16i8 vec0, vec1, vec2, vec3, vec4, vec5; - v16i8 minus5b = __msa_ldi_b(-5); - v16i8 plus20b = __msa_ldi_b(20); - - LD_SB3(&luma_mask_arr[48], 16, mask0, mask1, mask2); - slide = 2 + hor_offset; - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - XORI_B4_128_SB(src0, src1, src2, src3); - VSHF_B2_SB(src0, src1, src2, src3, mask0, mask0, vec0, vec1); - HADD_SB2_SH(vec0, vec1, res0, res1); - VSHF_B2_SB(src0, src1, src2, src3, mask1, mask1, vec2, vec3); - DPADD_SB2_SH(vec2, vec3, minus5b, minus5b, res0, res1); - VSHF_B2_SB(src0, src1, src2, src3, mask2, mask2, vec4, vec5); - DPADD_SB2_SH(vec4, vec5, plus20b, plus20b, res0, res1); - SRARI_H2_SH(res0, res1, 5); - SAT_SH2_SH(res0, res1, 7); - - res = __msa_pckev_b((v16i8) res1, (v16i8) res0); - src0 = __msa_sld_b(src0, src0, slide); - src1 = __msa_sld_b(src1, src1, slide); - src2 = __msa_sld_b(src2, src2, slide); - src3 = __msa_sld_b(src3, src3, slide); - src0 = (v16i8) __msa_insve_w((v4i32) src0, 1, (v4i32) src1); - src1 = (v16i8) __msa_insve_w((v4i32) src2, 1, (v4i32) src3); - src0 = (v16i8) __msa_insve_d((v2i64) src0, 1, (v2i64) src1); - res = __msa_aver_s_b(res, src0); - res = (v16i8) __msa_xori_b((v16u8) res, 128); - - ST4x4_UB(res, res, 0, 1, 2, 3, dst, dst_stride); - dst += (4 * dst_stride); - } -} - -static void avc_luma_hz_qrt_8w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height, uint8_t hor_offset) -{ - uint8_t slide; - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3; - v16i8 tmp0, tmp1; - v8i16 res0, res1, res2, res3; - v16i8 mask0, mask1, mask2; - v16i8 vec0, vec1, vec2, vec3, vec4, vec5; - v16i8 vec6, vec7, vec8, vec9, vec10, vec11; - v16i8 minus5b = __msa_ldi_b(-5); - v16i8 plus20b = __msa_ldi_b(20); - - LD_SB3(&luma_mask_arr[0], 16, mask0, mask1, mask2); - slide = 2 + hor_offset; - - for (loop_cnt = height >> 2; loop_cnt--;) { - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - XORI_B4_128_SB(src0, src1, src2, src3); - VSHF_B2_SB(src0, src0, src1, src1, mask0, mask0, vec0, vec1); - VSHF_B2_SB(src2, src2, src3, src3, mask0, mask0, vec2, vec3); - HADD_SB4_SH(vec0, vec1, vec2, vec3, res0, res1, res2, res3); - VSHF_B2_SB(src0, src0, src1, src1, mask1, mask1, vec4, vec5); - VSHF_B2_SB(src2, src2, src3, src3, mask1, mask1, vec6, vec7); - DPADD_SB4_SH(vec4, vec5, vec6, vec7, minus5b, minus5b, minus5b, minus5b, - res0, res1, res2, res3); - VSHF_B2_SB(src0, src0, src1, src1, mask2, mask2, vec8, vec9); - VSHF_B2_SB(src2, src2, src3, src3, mask2, mask2, vec10, vec11); - DPADD_SB4_SH(vec8, vec9, vec10, vec11, plus20b, plus20b, plus20b, - plus20b, res0, res1, res2, res3); - - src0 = __msa_sld_b(src0, src0, slide); - src1 = __msa_sld_b(src1, src1, slide); - src2 = __msa_sld_b(src2, src2, slide); - src3 = __msa_sld_b(src3, src3, slide); - - SRARI_H4_SH(res0, res1, res2, res3, 5); - SAT_SH4_SH(res0, res1, res2, res3, 7); - PCKEV_B2_SB(res1, res0, res3, res2, tmp0, tmp1); - PCKEV_D2_SB(src1, src0, src3, src2, src0, src1); - - tmp0 = __msa_aver_s_b(tmp0, src0); - tmp1 = __msa_aver_s_b(tmp1, src1); - - XORI_B2_128_SB(tmp0, tmp1); - ST8x4_UB(tmp0, tmp1, dst, dst_stride); - - dst += (4 * dst_stride); - } -} - -static void avc_luma_hz_qrt_16w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height, uint8_t hor_offset) -{ - uint32_t loop_cnt; - v16i8 dst0, dst1; - v16i8 src0, src1, src2, src3; - v16i8 mask0, mask1, mask2, vshf; - v8i16 res0, res1, res2, res3; - v16i8 vec0, vec1, vec2, vec3, vec4, vec5; - v16i8 vec6, vec7, vec8, vec9, vec10, vec11; - v16i8 minus5b = __msa_ldi_b(-5); - v16i8 plus20b = __msa_ldi_b(20); - - LD_SB3(&luma_mask_arr[0], 16, mask0, mask1, mask2); - - if (hor_offset) { - vshf = LD_SB(&luma_mask_arr[16 + 96]); - } else { - vshf = LD_SB(&luma_mask_arr[96]); - } - - for (loop_cnt = height >> 1; loop_cnt--;) { - LD_SB2(src, 8, src0, src1); - src += src_stride; - LD_SB2(src, 8, src2, src3); - src += src_stride; - - XORI_B4_128_SB(src0, src1, src2, src3); - VSHF_B2_SB(src0, src0, src1, src1, mask0, mask0, vec0, vec3); - VSHF_B2_SB(src2, src2, src3, src3, mask0, mask0, vec6, vec9); - VSHF_B2_SB(src0, src0, src1, src1, mask1, mask1, vec1, vec4); - VSHF_B2_SB(src2, src2, src3, src3, mask1, mask1, vec7, vec10); - VSHF_B2_SB(src0, src0, src1, src1, mask2, mask2, vec2, vec5); - VSHF_B2_SB(src2, src2, src3, src3, mask2, mask2, vec8, vec11); - HADD_SB4_SH(vec0, vec3, vec6, vec9, res0, res1, res2, res3); - DPADD_SB4_SH(vec1, vec4, vec7, vec10, minus5b, minus5b, minus5b, - minus5b, res0, res1, res2, res3); - DPADD_SB4_SH(vec2, vec5, vec8, vec11, plus20b, plus20b, plus20b, - plus20b, res0, res1, res2, res3); - VSHF_B2_SB(src0, src1, src2, src3, vshf, vshf, src0, src2); - SRARI_H4_SH(res0, res1, res2, res3, 5); - SAT_SH4_SH(res0, res1, res2, res3, 7); - PCKEV_B2_SB(res1, res0, res3, res2, dst0, dst1); - - dst0 = __msa_aver_s_b(dst0, src0); - dst1 = __msa_aver_s_b(dst1, src2); - - XORI_B2_128_SB(dst0, dst1); - - ST_SB2(dst0, dst1, dst, dst_stride); - dst += (2 * dst_stride); - } -} - static void avc_luma_vt_4w_msa(const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, int32_t height) @@ -623,217 +329,6 @@ static void avc_luma_vt_16w_msa(const uint8_t *src, int32_t src_stride, } } -static void avc_luma_vt_qrt_4w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height, uint8_t ver_offset) -{ - int32_t loop_cnt; - int16_t filt_const0 = 0xfb01; - int16_t filt_const1 = 0x1414; - int16_t filt_const2 = 0x1fb; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8; - v16i8 src10_r, src32_r, src54_r, src76_r, src21_r, src43_r, src65_r; - v16i8 src87_r, src2110, src4332, src6554, src8776; - v8i16 out10, out32; - v16i8 filt0, filt1, filt2; - v16u8 out; - - filt0 = (v16i8) __msa_fill_h(filt_const0); - filt1 = (v16i8) __msa_fill_h(filt_const1); - filt2 = (v16i8) __msa_fill_h(filt_const2); - - LD_SB5(src, src_stride, src0, src1, src2, src3, src4); - src += (5 * src_stride); - - ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, - src10_r, src21_r, src32_r, src43_r); - ILVR_D2_SB(src21_r, src10_r, src43_r, src32_r, src2110, src4332); - XORI_B2_128_SB(src2110, src4332); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src5, src6, src7, src8); - src += (4 * src_stride); - - ILVR_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, - src54_r, src65_r, src76_r, src87_r); - ILVR_D2_SB(src65_r, src54_r, src87_r, src76_r, src6554, src8776); - XORI_B2_128_SB(src6554, src8776); - out10 = DPADD_SH3_SH(src2110, src4332, src6554, filt0, filt1, filt2); - out32 = DPADD_SH3_SH(src4332, src6554, src8776, filt0, filt1, filt2); - SRARI_H2_SH(out10, out32, 5); - SAT_SH2_SH(out10, out32, 7); - - out = PCKEV_XORI128_UB(out10, out32); - - if (ver_offset) { - src32_r = (v16i8) __msa_insve_w((v4i32) src3, 1, (v4i32) src4); - src54_r = (v16i8) __msa_insve_w((v4i32) src5, 1, (v4i32) src6); - } else { - src32_r = (v16i8) __msa_insve_w((v4i32) src2, 1, (v4i32) src3); - src54_r = (v16i8) __msa_insve_w((v4i32) src4, 1, (v4i32) src5); - } - - src32_r = (v16i8) __msa_insve_d((v2i64) src32_r, 1, (v2i64) src54_r); - out = __msa_aver_u_b(out, (v16u8) src32_r); - - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); - dst += (4 * dst_stride); - src2110 = src6554; - src4332 = src8776; - src2 = src6; - src3 = src7; - src4 = src8; - } -} - -static void avc_luma_vt_qrt_8w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height, uint8_t ver_offset) -{ - int32_t loop_cnt; - int16_t filt_const0 = 0xfb01; - int16_t filt_const1 = 0x1414; - int16_t filt_const2 = 0x1fb; - v16i8 src0, src1, src2, src3, src4, src7, src8, src9, src10; - v16i8 src10_r, src32_r, src76_r, src98_r; - v16i8 src21_r, src43_r, src87_r, src109_r; - v8i16 out0_r, out1_r, out2_r, out3_r; - v16i8 res0, res1; - v16i8 filt0, filt1, filt2; - - filt0 = (v16i8) __msa_fill_h(filt_const0); - filt1 = (v16i8) __msa_fill_h(filt_const1); - filt2 = (v16i8) __msa_fill_h(filt_const2); - - LD_SB5(src, src_stride, src0, src1, src2, src3, src4); - src += (5 * src_stride); - - XORI_B5_128_SB(src0, src1, src2, src3, src4); - ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, - src10_r, src21_r, src32_r, src43_r); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src7, src8, src9, src10); - src += (4 * src_stride); - - XORI_B4_128_SB(src7, src8, src9, src10); - ILVR_B4_SB(src7, src4, src8, src7, src9, src8, src10, src9, - src76_r, src87_r, src98_r, src109_r); - out0_r = DPADD_SH3_SH(src10_r, src32_r, src76_r, filt0, filt1, filt2); - out1_r = DPADD_SH3_SH(src21_r, src43_r, src87_r, filt0, filt1, filt2); - out2_r = DPADD_SH3_SH(src32_r, src76_r, src98_r, filt0, filt1, filt2); - out3_r = DPADD_SH3_SH(src43_r, src87_r, src109_r, filt0, filt1, filt2); - SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, 5); - SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); - PCKEV_B2_SB(out1_r, out0_r, out3_r, out2_r, res0, res1); - - if (ver_offset) { - PCKEV_D2_SB(src4, src3, src8, src7, src10_r, src32_r); - } else { - PCKEV_D2_SB(src3, src2, src7, src4, src10_r, src32_r); - } - - res0 = __msa_aver_s_b(res0, (v16i8) src10_r); - res1 = __msa_aver_s_b(res1, (v16i8) src32_r); - - XORI_B2_128_SB(res0, res1); - ST8x4_UB(res0, res1, dst, dst_stride); - - dst += (4 * dst_stride); - src10_r = src76_r; - src32_r = src98_r; - src21_r = src87_r; - src43_r = src109_r; - src2 = src8; - src3 = src9; - src4 = src10; - } -} - -static void avc_luma_vt_qrt_16w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height, uint8_t ver_offset) -{ - int32_t loop_cnt; - int16_t filt_const0 = 0xfb01; - int16_t filt_const1 = 0x1414; - int16_t filt_const2 = 0x1fb; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8; - v16i8 src10_r, src32_r, src54_r, src76_r, src21_r, src43_r, src65_r; - v16i8 src87_r, src10_l, src32_l, src54_l, src76_l, src21_l, src43_l; - v16i8 src65_l, src87_l; - v8i16 out0_r, out1_r, out2_r, out3_r, out0_l, out1_l, out2_l, out3_l; - v16u8 res0, res1, res2, res3; - v16i8 filt0, filt1, filt2; - - filt0 = (v16i8) __msa_fill_h(filt_const0); - filt1 = (v16i8) __msa_fill_h(filt_const1); - filt2 = (v16i8) __msa_fill_h(filt_const2); - - LD_SB5(src, src_stride, src0, src1, src2, src3, src4); - src += (5 * src_stride); - - XORI_B5_128_SB(src0, src1, src2, src3, src4); - ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, - src10_r, src21_r, src32_r, src43_r); - ILVL_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, - src10_l, src21_l, src32_l, src43_l); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src5, src6, src7, src8); - src += (4 * src_stride); - - XORI_B4_128_SB(src5, src6, src7, src8); - ILVR_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, - src54_r, src65_r, src76_r, src87_r); - ILVL_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, - src54_l, src65_l, src76_l, src87_l); - out0_r = DPADD_SH3_SH(src10_r, src32_r, src54_r, filt0, filt1, filt2); - out1_r = DPADD_SH3_SH(src21_r, src43_r, src65_r, filt0, filt1, filt2); - out2_r = DPADD_SH3_SH(src32_r, src54_r, src76_r, filt0, filt1, filt2); - out3_r = DPADD_SH3_SH(src43_r, src65_r, src87_r, filt0, filt1, filt2); - out0_l = DPADD_SH3_SH(src10_l, src32_l, src54_l, filt0, filt1, filt2); - out1_l = DPADD_SH3_SH(src21_l, src43_l, src65_l, filt0, filt1, filt2); - out2_l = DPADD_SH3_SH(src32_l, src54_l, src76_l, filt0, filt1, filt2); - out3_l = DPADD_SH3_SH(src43_l, src65_l, src87_l, filt0, filt1, filt2); - SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, 5); - SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); - SRARI_H4_SH(out0_l, out1_l, out2_l, out3_l, 5); - SAT_SH4_SH(out0_l, out1_l, out2_l, out3_l, 7); - PCKEV_B4_UB(out0_l, out0_r, out1_l, out1_r, out2_l, out2_r, out3_l, - out3_r, res0, res1, res2, res3); - - if (ver_offset) { - res0 = (v16u8) __msa_aver_s_b((v16i8) res0, src3); - res1 = (v16u8) __msa_aver_s_b((v16i8) res1, src4); - res2 = (v16u8) __msa_aver_s_b((v16i8) res2, src5); - res3 = (v16u8) __msa_aver_s_b((v16i8) res3, src6); - } else { - res0 = (v16u8) __msa_aver_s_b((v16i8) res0, src2); - res1 = (v16u8) __msa_aver_s_b((v16i8) res1, src3); - res2 = (v16u8) __msa_aver_s_b((v16i8) res2, src4); - res3 = (v16u8) __msa_aver_s_b((v16i8) res3, src5); - } - - XORI_B4_128_UB(res0, res1, res2, res3); - ST_UB4(res0, res1, res2, res3, dst, dst_stride); - - dst += (4 * dst_stride); - - src10_r = src54_r; - src32_r = src76_r; - src21_r = src65_r; - src43_r = src87_r; - src10_l = src54_l; - src32_l = src76_l; - src21_l = src65_l; - src43_l = src87_l; - src2 = src6; - src3 = src7; - src4 = src8; - } -} - static void avc_luma_mid_4w_msa(const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, int32_t height) @@ -2733,247 +2228,6 @@ static void avc_luma_hv_qrt_and_aver_dst_16x16_msa(const uint8_t *src_x, } } -static void copy_width8_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height) -{ - int32_t cnt; - uint64_t out0, out1, out2, out3, out4, out5, out6, out7; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - - if (0 == height % 12) { - for (cnt = (height / 12); cnt--;) { - LD_UB8(src, src_stride, - src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - - out0 = __msa_copy_u_d((v2i64) src0, 0); - out1 = __msa_copy_u_d((v2i64) src1, 0); - out2 = __msa_copy_u_d((v2i64) src2, 0); - out3 = __msa_copy_u_d((v2i64) src3, 0); - out4 = __msa_copy_u_d((v2i64) src4, 0); - out5 = __msa_copy_u_d((v2i64) src5, 0); - out6 = __msa_copy_u_d((v2i64) src6, 0); - out7 = __msa_copy_u_d((v2i64) src7, 0); - - SD4(out0, out1, out2, out3, dst, dst_stride); - dst += (4 * dst_stride); - SD4(out4, out5, out6, out7, dst, dst_stride); - dst += (4 * dst_stride); - - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - out0 = __msa_copy_u_d((v2i64) src0, 0); - out1 = __msa_copy_u_d((v2i64) src1, 0); - out2 = __msa_copy_u_d((v2i64) src2, 0); - out3 = __msa_copy_u_d((v2i64) src3, 0); - - SD4(out0, out1, out2, out3, dst, dst_stride); - dst += (4 * dst_stride); - } - } else if (0 == height % 8) { - for (cnt = height >> 3; cnt--;) { - LD_UB8(src, src_stride, - src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - - out0 = __msa_copy_u_d((v2i64) src0, 0); - out1 = __msa_copy_u_d((v2i64) src1, 0); - out2 = __msa_copy_u_d((v2i64) src2, 0); - out3 = __msa_copy_u_d((v2i64) src3, 0); - out4 = __msa_copy_u_d((v2i64) src4, 0); - out5 = __msa_copy_u_d((v2i64) src5, 0); - out6 = __msa_copy_u_d((v2i64) src6, 0); - out7 = __msa_copy_u_d((v2i64) src7, 0); - - SD4(out0, out1, out2, out3, dst, dst_stride); - dst += (4 * dst_stride); - SD4(out4, out5, out6, out7, dst, dst_stride); - dst += (4 * dst_stride); - } - } else if (0 == height % 4) { - for (cnt = (height / 4); cnt--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - out0 = __msa_copy_u_d((v2i64) src0, 0); - out1 = __msa_copy_u_d((v2i64) src1, 0); - out2 = __msa_copy_u_d((v2i64) src2, 0); - out3 = __msa_copy_u_d((v2i64) src3, 0); - - SD4(out0, out1, out2, out3, dst, dst_stride); - dst += (4 * dst_stride); - } - } else if (0 == height % 2) { - for (cnt = (height / 2); cnt--;) { - LD_UB2(src, src_stride, src0, src1); - src += (2 * src_stride); - out0 = __msa_copy_u_d((v2i64) src0, 0); - out1 = __msa_copy_u_d((v2i64) src1, 0); - - SD(out0, dst); - dst += dst_stride; - SD(out1, dst); - dst += dst_stride; - } - } -} - -static void copy_16multx8mult_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height, int32_t width) -{ - int32_t cnt, loop_cnt; - const uint8_t *src_tmp; - uint8_t *dst_tmp; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - - for (cnt = (width >> 4); cnt--;) { - src_tmp = src; - dst_tmp = dst; - - for (loop_cnt = (height >> 3); loop_cnt--;) { - LD_UB8(src_tmp, src_stride, - src0, src1, src2, src3, src4, src5, src6, src7); - src_tmp += (8 * src_stride); - - ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, - dst_tmp, dst_stride); - dst_tmp += (8 * dst_stride); - } - - src += 16; - dst += 16; - } -} - -static void copy_width16_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height) -{ - int32_t cnt; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - - if (0 == height % 12) { - for (cnt = (height / 12); cnt--;) { - LD_UB8(src, src_stride, - src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, - dst, dst_stride); - dst += (8 * dst_stride); - - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - ST_UB4(src0, src1, src2, src3, dst, dst_stride); - dst += (4 * dst_stride); - } - } else if (0 == height % 8) { - copy_16multx8mult_msa(src, src_stride, dst, dst_stride, height, 16); - } else if (0 == height % 4) { - for (cnt = (height >> 2); cnt--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - ST_UB4(src0, src1, src2, src3, dst, dst_stride); - dst += (4 * dst_stride); - } - } -} - -static void avg_width4_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height) -{ - int32_t cnt; - uint32_t out0, out1, out2, out3; - v16u8 src0, src1, src2, src3; - v16u8 dst0, dst1, dst2, dst3; - - if (0 == (height % 4)) { - for (cnt = (height / 4); cnt--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - - AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, - dst0, dst1, dst2, dst3); - - out0 = __msa_copy_u_w((v4i32) dst0, 0); - out1 = __msa_copy_u_w((v4i32) dst1, 0); - out2 = __msa_copy_u_w((v4i32) dst2, 0); - out3 = __msa_copy_u_w((v4i32) dst3, 0); - SW4(out0, out1, out2, out3, dst, dst_stride); - dst += (4 * dst_stride); - } - } else if (0 == (height % 2)) { - for (cnt = (height / 2); cnt--;) { - LD_UB2(src, src_stride, src0, src1); - src += (2 * src_stride); - - LD_UB2(dst, dst_stride, dst0, dst1); - - AVER_UB2_UB(src0, dst0, src1, dst1, dst0, dst1); - - out0 = __msa_copy_u_w((v4i32) dst0, 0); - out1 = __msa_copy_u_w((v4i32) dst1, 0); - SW(out0, dst); - dst += dst_stride; - SW(out1, dst); - dst += dst_stride; - } - } -} - -static void avg_width8_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height) -{ - int32_t cnt; - uint64_t out0, out1, out2, out3; - v16u8 src0, src1, src2, src3; - v16u8 dst0, dst1, dst2, dst3; - - for (cnt = (height / 4); cnt--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - - AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, - dst0, dst1, dst2, dst3); - - out0 = __msa_copy_u_d((v2i64) dst0, 0); - out1 = __msa_copy_u_d((v2i64) dst1, 0); - out2 = __msa_copy_u_d((v2i64) dst2, 0); - out3 = __msa_copy_u_d((v2i64) dst3, 0); - SD4(out0, out1, out2, out3, dst, dst_stride); - dst += (4 * dst_stride); - } -} - -static void avg_width16_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height) -{ - int32_t cnt; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; - - for (cnt = (height / 8); cnt--;) { - LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - LD_UB8(dst, dst_stride, dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7); - - AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, - dst0, dst1, dst2, dst3); - AVER_UB4_UB(src4, dst4, src5, dst5, src6, dst6, src7, dst7, - dst4, dst5, dst6, dst7); - ST_UB8(dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7, dst, dst_stride); - dst += (8 * dst_stride); - } -} - void ff_put_h264_qpel16_mc00_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { diff --git a/libavcodec/mips/hevc_mc_uniw_msa.c b/libavcodec/mips/hevc_mc_uniw_msa.c index d18441957f2b7..38a8844a6e11d 100644 --- a/libavcodec/mips/hevc_mc_uniw_msa.c +++ b/libavcodec/mips/hevc_mc_uniw_msa.c @@ -351,73 +351,6 @@ static void hevc_uniwgt_copy_12w_msa(uint8_t *src, } } -static void hevc_uniwgt_copy_16multx4mult_msa(uint8_t *src, - int32_t src_stride, - uint8_t *dst, - int32_t dst_stride, - int32_t height, - int32_t weight, - int32_t offset, - int32_t rnd_val, - int32_t width) -{ - uint32_t loop_cnt, cnt; - uint8_t *src_tmp; - uint8_t *dst_tmp; - v16i8 src0, src1, src2, src3; - v8i16 tmp0, tmp1, tmp2, tmp3; - v4i32 dst0_r, dst1_r, dst2_r, dst3_r, dst0_l, dst1_l, dst2_l, dst3_l; - v16i8 zero = { 0 }; - v4i32 weight_vec, offset_vec, rnd_vec; - - weight = weight & 0x0000FFFF; - weight_vec = __msa_fill_w(weight); - offset_vec = __msa_fill_w(offset); - rnd_vec = __msa_fill_w(rnd_val); - - for (cnt = width >> 4; cnt--;) { - src_tmp = src; - dst_tmp = dst; - - for (loop_cnt = height >> 2; loop_cnt--;) { - LD_SB4(src_tmp, src_stride, src0, src1, src2, src3); - src_tmp += (4 * src_stride); - ILVR_B2_SH(zero, src0, zero, src1, tmp0, tmp1); - ILVL_B2_SH(zero, src0, zero, src1, tmp2, tmp3); - - SLLI_4V(tmp0, tmp1, tmp2, tmp3, 6); - HEVC_UNIW_RND_CLIP4(tmp0, tmp1, tmp2, tmp3, - weight_vec, offset_vec, rnd_vec, - dst0_r, dst1_r, dst2_r, dst3_r, - dst0_l, dst1_l, dst2_l, dst3_l); - - HEVC_PCK_SW_SB8(dst0_l, dst0_r, dst2_l, dst2_r, - dst1_l, dst1_r, dst3_l, dst3_r, dst0_r, dst1_r); - - ST_SW2(dst0_r, dst1_r, dst_tmp, dst_stride); - dst_tmp += (2 * dst_stride); - - ILVR_B2_SH(zero, src2, zero, src3, tmp0, tmp1); - ILVL_B2_SH(zero, src2, zero, src3, tmp2, tmp3); - - SLLI_4V(tmp0, tmp1, tmp2, tmp3, 6); - HEVC_UNIW_RND_CLIP4(tmp0, tmp1, tmp2, tmp3, - weight_vec, offset_vec, rnd_vec, - dst0_r, dst1_r, dst2_r, dst3_r, - dst0_l, dst1_l, dst2_l, dst3_l); - - HEVC_PCK_SW_SB8(dst0_l, dst0_r, dst2_l, dst2_r, - dst1_l, dst1_r, dst3_l, dst3_r, dst0_r, dst1_r); - - ST_SW2(dst0_r, dst1_r, dst_tmp, dst_stride); - dst_tmp += (2 * dst_stride); - } - - src += 16; - dst += 16; - } -} - static void hevc_uniwgt_copy_16w_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, diff --git a/libavcodec/mips/hevcdsp_msa.c b/libavcodec/mips/hevcdsp_msa.c index 1a854b204ff35..73cc3ea21307c 100644 --- a/libavcodec/mips/hevcdsp_msa.c +++ b/libavcodec/mips/hevcdsp_msa.c @@ -192,56 +192,6 @@ static void hevc_copy_12w_msa(uint8_t *src, int32_t src_stride, } } -static void hevc_copy_16multx8mult_msa(uint8_t *src, - int32_t src_stride, - int16_t *dst, - int32_t dst_stride, - int32_t height, - int32_t width) -{ - uint8_t *src_tmp; - int16_t *dst_tmp; - uint32_t loop_cnt, cnt; - v16i8 zero = { 0 }; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7; - v8i16 in0_r, in1_r, in2_r, in3_r; - v8i16 in0_l, in1_l, in2_l, in3_l; - - for (cnt = (width >> 4); cnt--;) { - src_tmp = src; - dst_tmp = dst; - - for (loop_cnt = (height >> 3); loop_cnt--;) { - LD_SB8(src_tmp, src_stride, - src0, src1, src2, src3, src4, src5, src6, src7); - src_tmp += (8 * src_stride); - - ILVR_B4_SH(zero, src0, zero, src1, zero, src2, zero, src3, - in0_r, in1_r, in2_r, in3_r); - ILVL_B4_SH(zero, src0, zero, src1, zero, src2, zero, src3, - in0_l, in1_l, in2_l, in3_l); - SLLI_4V(in0_r, in1_r, in2_r, in3_r, 6); - SLLI_4V(in0_l, in1_l, in2_l, in3_l, 6); - ST_SH4(in0_r, in1_r, in2_r, in3_r, dst_tmp, dst_stride); - ST_SH4(in0_l, in1_l, in2_l, in3_l, (dst_tmp + 8), dst_stride); - dst_tmp += (4 * dst_stride); - - ILVR_B4_SH(zero, src4, zero, src5, zero, src6, zero, src7, - in0_r, in1_r, in2_r, in3_r); - ILVL_B4_SH(zero, src4, zero, src5, zero, src6, zero, src7, - in0_l, in1_l, in2_l, in3_l); - SLLI_4V(in0_r, in1_r, in2_r, in3_r, 6); - SLLI_4V(in0_l, in1_l, in2_l, in3_l, 6); - ST_SH4(in0_r, in1_r, in2_r, in3_r, dst_tmp, dst_stride); - ST_SH4(in0_l, in1_l, in2_l, in3_l, (dst_tmp + 8), dst_stride); - dst_tmp += (4 * dst_stride); - } - - src += 16; - dst += 16; - } -} - static void hevc_copy_16w_msa(uint8_t *src, int32_t src_stride, int16_t *dst, int32_t dst_stride, int32_t height) From 1e27837265702b63db65122e97178a0ca4d25e05 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Tue, 14 Mar 2017 17:44:45 +0100 Subject: [PATCH 3270/3374] rtsp: Move message parsing to a separate function Make easier to handle the polling function before we implement full threading support. (cherry picked from libav commit ca960161f087ca38267b88ce90592010c59584f1) Signed-off-by: James Almer --- libavformat/rtsp.c | 57 ++++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 375d0d9e14f20..b6da61b95e6c0 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -1918,12 +1918,39 @@ int ff_rtsp_connect(AVFormatContext *s) #endif /* CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER */ #if CONFIG_RTPDEC +static int parse_rtsp_message(AVFormatContext *s) +{ + RTSPState *rt = s->priv_data; + int ret; + + if (rt->rtsp_flags & RTSP_FLAG_LISTEN) { + if (rt->state == RTSP_STATE_STREAMING) { + if (!ff_rtsp_parse_streaming_commands(s)) + return AVERROR_EOF; + else + av_log(s, AV_LOG_WARNING, + "Unable to answer to TEARDOWN\n"); + } else + return 0; + } else { + RTSPMessageHeader reply; + ret = ff_rtsp_read_reply(s, &reply, NULL, 0, NULL); + if (ret < 0) + return ret; + /* XXX: parse message */ + if (rt->state != RTSP_STATE_STREAMING) + return 0; + } + + return 0; +} + static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, uint8_t *buf, int buf_size, int64_t wait_end) { RTSPState *rt = s->priv_data; RTSPStream *rtsp_st; - int n, i, ret, tcp_fd, timeout_cnt = 0; + int n, i, ret, timeout_cnt = 0; struct pollfd *p = rt->p; int *fds = NULL, fdsnum, fdsidx; @@ -1933,11 +1960,8 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, return AVERROR(ENOMEM); if (rt->rtsp_hd) { - tcp_fd = ffurl_get_file_handle(rt->rtsp_hd); - p[rt->max_p].fd = tcp_fd; + p[rt->max_p].fd = ffurl_get_file_handle(rt->rtsp_hd); p[rt->max_p++].events = POLLIN; - } else { - tcp_fd = -1; } for (i = 0; i < rt->nb_rtsp_streams; i++) { rtsp_st = rt->rtsp_streams[i]; @@ -1968,7 +1992,7 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, return AVERROR(EAGAIN); n = poll(p, rt->max_p, POLL_TIMEOUT_MS); if (n > 0) { - int j = 1 - (tcp_fd == -1); + int j = rt->rtsp_hd ? 1 : 0; timeout_cnt = 0; for (i = 0; i < rt->nb_rtsp_streams; i++) { rtsp_st = rt->rtsp_streams[i]; @@ -1984,25 +2008,8 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, } } #if CONFIG_RTSP_DEMUXER - if (tcp_fd != -1 && p[0].revents & POLLIN) { - if (rt->rtsp_flags & RTSP_FLAG_LISTEN) { - if (rt->state == RTSP_STATE_STREAMING) { - if (!ff_rtsp_parse_streaming_commands(s)) - return AVERROR_EOF; - else - av_log(s, AV_LOG_WARNING, - "Unable to answer to TEARDOWN\n"); - } else - return 0; - } else { - RTSPMessageHeader reply; - ret = ff_rtsp_read_reply(s, &reply, NULL, 0, NULL); - if (ret < 0) - return ret; - /* XXX: parse message */ - if (rt->state != RTSP_STATE_STREAMING) - return 0; - } + if (rt->rtsp_hd && p[0].revents & POLLIN) { + return parse_rtsp_message(s); } #endif } else if (n == 0 && ++timeout_cnt >= MAX_TIMEOUTS) { From 62bdec806ecd3539856dffc86542bdc46a1932c1 Mon Sep 17 00:00:00 2001 From: Tobias Rapp Date: Thu, 21 Sep 2017 13:40:36 +0200 Subject: [PATCH 3271/3374] avfilter/vf_fps: add eof_action filter option Allows to specify the action to be performed when reading the last frame from the internal FIFO buffer. By default the last frame is written to filter output depending on the timestamp rounding method. When using "pass" action the last frame is passed through if input duration has not been reached yet. Examples using an input file with 25Hz, 1.4sec duration: - "fps=fps=1:round=near" generates an output file of 1sec - "fps=fps=1:round=near:eof_action=pass" generates an output file of 2sec Signed-off-by: Tobias Rapp --- doc/filters.texi | 12 ++++++++++++ libavfilter/version.h | 2 +- libavfilter/vf_fps.c | 14 +++++++++++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 624e5cd01b9a8..57189c77b02e6 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -8695,6 +8695,18 @@ round to nearest @end table The default is @code{near}. +@item eof_action +Action performed when reading the last frame. + +Possible values are: +@table @option +@item round +Use same timestamp rounding method as used for other frames. +@item pass +Pass through last frame if input duration has not been reached yet. +@end table +The default is @code{round}. + @end table Alternatively, the options can be specified as a flat string: diff --git a/libavfilter/version.h b/libavfilter/version.h index fb382d4e25282..8191c59a15d83 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -31,7 +31,7 @@ #define LIBAVFILTER_VERSION_MAJOR 6 #define LIBAVFILTER_VERSION_MINOR 106 -#define LIBAVFILTER_VERSION_MICRO 100 +#define LIBAVFILTER_VERSION_MICRO 101 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ LIBAVFILTER_VERSION_MINOR, \ diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c index a5e51c3bbb5d8..dbafd2c35a66e 100644 --- a/libavfilter/vf_fps.c +++ b/libavfilter/vf_fps.c @@ -40,6 +40,12 @@ #include "internal.h" #include "video.h" +enum EOFAction { + EOF_ACTION_ROUND, + EOF_ACTION_PASS, + EOF_ACTION_NB +}; + typedef struct FPSContext { const AVClass *class; @@ -52,6 +58,7 @@ typedef struct FPSContext { AVRational framerate; ///< target framerate int rounding; ///< AVRounding method for timestamps + int eof_action; ///< action performed for last frame in FIFO /* statistics */ int frames_in; ///< number of frames on input @@ -72,6 +79,9 @@ static const AVOption fps_options[] = { { "down", "round towards -infty", 0, AV_OPT_TYPE_CONST, { .i64 = AV_ROUND_DOWN }, 0, 0, V|F, "round" }, { "up", "round towards +infty", 0, AV_OPT_TYPE_CONST, { .i64 = AV_ROUND_UP }, 0, 0, V|F, "round" }, { "near", "round to nearest", 0, AV_OPT_TYPE_CONST, { .i64 = AV_ROUND_NEAR_INF }, 0, 0, V|F, "round" }, + { "eof_action", "action performed for last frame", OFFSET(eof_action), AV_OPT_TYPE_INT, { .i64 = EOF_ACTION_ROUND }, 0, EOF_ACTION_NB-1, V|F, "eof_action" }, + { "round", "round similar to other frames", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_ROUND }, 0, 0, V|F, "eof_action" }, + { "pass", "pass through last frame", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_PASS }, 0, 0, V|F, "eof_action" }, { NULL } }; @@ -151,9 +161,11 @@ static int request_frame(AVFilterLink *outlink) /* This is the last frame, we may have to duplicate it to match * the last frame duration */ int j; + int eof_rounding = (s->eof_action == EOF_ACTION_PASS) ? AV_ROUND_UP : s->rounding; int delta = av_rescale_q_rnd(ctx->inputs[0]->current_pts - s->first_pts, ctx->inputs[0]->time_base, - outlink->time_base, s->rounding) - s->frames_out ; + outlink->time_base, eof_rounding) - s->frames_out; + av_log(ctx, AV_LOG_DEBUG, "EOF frames_out:%d delta:%d\n", s->frames_out, delta); /* if the delta is equal to 1, it means we just need to output * the last frame. Greater than 1 means we will need duplicate * delta-1 frames */ From 7d141e2cacb42a25df0c32a6deb5256fdbec4425 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Wed, 4 Oct 2017 22:55:00 +0200 Subject: [PATCH 3272/3374] avdevice/decklink_dec: fix extracting luma Signed-off-by: Marton Balint --- libavdevice/decklink_dec.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index f496a580595d4..7ac04375d9ea4 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -138,7 +138,7 @@ static int check_vanc_parity_checksum(uint16_t *buf, int len, uint16_t checksum) static void extract_luma_from_v210(uint16_t *dst, const uint8_t *src, int width) { int i; - for (i = 0; i < width / 3; i += 3) { + for (i = 0; i < width / 3; i++) { *dst++ = (src[1] >> 2) + ((src[2] & 15) << 6); *dst++ = src[4] + ((src[5] & 3) << 8); *dst++ = (src[6] >> 4) + ((src[7] & 63) << 4); From 2a31ad7d60632cca0f43986b6a5b135848088b14 Mon Sep 17 00:00:00 2001 From: Jorge Ramirez-Ortiz Date: Fri, 6 Oct 2017 09:51:43 +0200 Subject: [PATCH 3273/3374] avcodec/v4l2: fix single plane decoding --- libavcodec/v4l2_buffers.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/libavcodec/v4l2_buffers.c b/libavcodec/v4l2_buffers.c index ef7d0400322b9..ba70c5d14bcc2 100644 --- a/libavcodec/v4l2_buffers.c +++ b/libavcodec/v4l2_buffers.c @@ -244,13 +244,23 @@ static int v4l2_buf_to_bufref(V4L2Buffer *in, int plane, AVBufferRef **buf) static int v4l2_bufref_to_buf(V4L2Buffer *out, int plane, const uint8_t* data, int size, AVBufferRef* bref) { + unsigned int bytesused, length; + if (plane >= out->num_planes) return AVERROR(EINVAL); + bytesused = FFMIN(size, out->plane_info[plane].length); + length = out->plane_info[plane].length; + memcpy(out->plane_info[plane].mm_addr, data, FFMIN(size, out->plane_info[plane].length)); - out->planes[plane].bytesused = FFMIN(size, out->plane_info[plane].length); - out->planes[plane].length = out->plane_info[plane].length; + if (V4L2_TYPE_IS_MULTIPLANAR(out->buf.type)) { + out->planes[plane].bytesused = bytesused; + out->planes[plane].length = length; + } else { + out->buf.bytesused = bytesused; + out->buf.length = length; + } return 0; } From cc5b7601f7c2d42b1c874a93277915cfb8c41038 Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 6 Oct 2017 15:55:09 -0300 Subject: [PATCH 3274/3374] avformat/mp3enc: flush buffered packets if referencing fails Reviewed-by: Michael Niedermayer Signed-off-by: James Almer --- libavformat/mp3enc.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c index 826878eca179b..8479e2485bb33 100644 --- a/libavformat/mp3enc.c +++ b/libavformat/mp3enc.c @@ -515,20 +515,15 @@ static int mp3_write_packet(AVFormatContext *s, AVPacket *pkt) if (mp3->pics_to_write) { /* buffer audio packets until we get all the pictures */ AVPacketList *pktl = av_mallocz(sizeof(*pktl)); - int ret; - if (!pktl) { + + if (!pktl || av_packet_ref(&pktl->pkt, pkt) < 0) { + av_freep(&pktl); av_log(s, AV_LOG_WARNING, "Not enough memory to buffer audio. Skipping picture streams\n"); mp3->pics_to_write = 0; mp3_queue_flush(s); return mp3_write_audio_packet(s, pkt); } - ret = av_packet_ref(&pktl->pkt, pkt); - if (ret < 0) { - av_freep(&pktl); - return ret; - } - if (mp3->queue_end) mp3->queue_end->next = pktl; else From a20f64bee235042f6e35c8e7ae65ccfddbf7343b Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Mon, 2 Oct 2017 11:38:34 +0200 Subject: [PATCH 3275/3374] lavf/img2dec: Auto-detect svg images. --- libavformat/img2dec.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c index 19cae87fdbe35..ecf64eaffaed2 100644 --- a/libavformat/img2dec.c +++ b/libavformat/img2dec.c @@ -34,6 +34,7 @@ #include "internal.h" #include "img2.h" #include "libavcodec/mjpeg.h" +#include "subtitles.h" #if HAVE_GLOB /* Locally define as 0 (bitwise-OR no-op) any missing glob options that @@ -875,8 +876,17 @@ static int sunrast_probe(AVProbeData *p) static int svg_probe(AVProbeData *p) { - if (av_match_ext(p->filename, "svg") || av_match_ext(p->filename, "svgz")) - return AVPROBE_SCORE_EXTENSION + 1; + const uint8_t *b = p->buf; + const uint8_t *end = p->buf + p->buf_size; + if (memcmp(p->buf, "= end - 4) + return 0; + if (!memcmp(b, " Date: Fri, 6 Oct 2017 09:31:13 -0700 Subject: [PATCH 3276/3374] lavfi/avfilter.c: Correct guess_status_pts to account for differing link timebases. Signed-off-by: Sasi Inguva --- libavfilter/avfilter.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 58917ed44548d..f0f849b326164 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -427,19 +427,19 @@ int ff_request_frame(AVFilterLink *link) return 0; } -static int64_t guess_status_pts(AVFilterContext *ctx, int status) +static int64_t guess_status_pts(AVFilterContext *ctx, int status, AVRational link_time_base) { unsigned i; int64_t r = INT64_MAX; for (i = 0; i < ctx->nb_inputs; i++) if (ctx->inputs[i]->status_out == status) - r = FFMIN(r, ctx->inputs[i]->current_pts); + r = FFMIN(r, av_rescale_q(ctx->inputs[i]->current_pts, ctx->inputs[i]->time_base, link_time_base)); if (r < INT64_MAX) return r; av_log(ctx, AV_LOG_WARNING, "EOF timestamp not reliable\n"); for (i = 0; i < ctx->nb_inputs; i++) - r = FFMIN(r, ctx->inputs[i]->status_in_pts); + r = FFMIN(r, av_rescale_q(ctx->inputs[i]->status_in_pts, ctx->inputs[i]->time_base, link_time_base)); if (r < INT64_MAX) return r; return AV_NOPTS_VALUE; @@ -458,7 +458,7 @@ static int ff_request_frame_to_filter(AVFilterLink *link) ret = ff_request_frame(link->src->inputs[0]); if (ret < 0) { if (ret != AVERROR(EAGAIN) && ret != link->status_in) - ff_avfilter_link_set_in_status(link, ret, guess_status_pts(link->src, ret)); + ff_avfilter_link_set_in_status(link, ret, guess_status_pts(link->src, ret, link->time_base)); if (ret == AVERROR_EOF) ret = 0; } From 50462e3e5e3229ca76336b9f607d1b48134ae8d8 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Sat, 7 Oct 2017 20:41:38 +0200 Subject: [PATCH 3277/3374] lavf/sdp: Fix MIME-type for big-endian G.726. RFC 3551 defines "G726" for little-endian ("right-justified") G.726 and announces "AAL2-G726" for big-endian ("left-justified") G.726. --- libavformat/sdp.c | 2 +- libavformat/version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/sdp.c b/libavformat/sdp.c index 66e9dffbf0dd7..1f1c28e3788b8 100644 --- a/libavformat/sdp.c +++ b/libavformat/sdp.c @@ -674,7 +674,7 @@ static char *sdp_write_media_attributes(char *buff, int size, AVStream *st, int break; case AV_CODEC_ID_ADPCM_G726: { if (payload_type >= RTP_PT_PRIVATE) - av_strlcatf(buff, size, "a=rtpmap:%d G726-%d/%d\r\n", + av_strlcatf(buff, size, "a=rtpmap:%d AAL2-G726-%d/%d\r\n", payload_type, p->bits_per_coded_sample*8, p->sample_rate); diff --git a/libavformat/version.h b/libavformat/version.h index ac6edf7ea9d9d..b5ad2101e07c1 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -33,7 +33,7 @@ // Also please add any ticket numbers that you believe might be affected here #define LIBAVFORMAT_VERSION_MAJOR 57 #define LIBAVFORMAT_VERSION_MINOR 82 -#define LIBAVFORMAT_VERSION_MICRO 102 +#define LIBAVFORMAT_VERSION_MICRO 103 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ From 2386cfc1ae2982101bee6024300c0af3113c4fd8 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Sat, 7 Oct 2017 20:47:10 +0200 Subject: [PATCH 3278/3374] lavf/rtpenc: Add support for little-endian G.726. --- Changelog | 1 + libavformat/rtpenc.c | 2 ++ libavformat/sdp.c | 8 ++++++++ libavformat/version.h | 2 +- 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Changelog b/Changelog index 03686acef6978..d6ec4ad1b557a 100644 --- a/Changelog +++ b/Changelog @@ -52,6 +52,7 @@ version : - V4L2 mem2mem HW assisted codecs - Rockchip MPP hardware decoding - vmafmotion video filter +- use MIME type "G726" for little-endian G.726, "AAL2-G726" for big-endian G.726 version 3.3: diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index af631a883aa87..573593fa663fd 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -78,6 +78,7 @@ static int is_supported(enum AVCodecID id) case AV_CODEC_ID_VP9: case AV_CODEC_ID_ADPCM_G722: case AV_CODEC_ID_ADPCM_G726: + case AV_CODEC_ID_ADPCM_G726LE: case AV_CODEC_ID_ILBC: case AV_CODEC_ID_MJPEG: case AV_CODEC_ID_SPEEX: @@ -550,6 +551,7 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt) * clock. */ return rtp_send_samples(s1, pkt->data, size, 8 * st->codecpar->channels); case AV_CODEC_ID_ADPCM_G726: + case AV_CODEC_ID_ADPCM_G726LE: return rtp_send_samples(s1, pkt->data, size, st->codecpar->bits_per_coded_sample * st->codecpar->channels); case AV_CODEC_ID_MP2: diff --git a/libavformat/sdp.c b/libavformat/sdp.c index 1f1c28e3788b8..0242ca379c23e 100644 --- a/libavformat/sdp.c +++ b/libavformat/sdp.c @@ -680,6 +680,14 @@ static char *sdp_write_media_attributes(char *buff, int size, AVStream *st, int p->sample_rate); break; } + case AV_CODEC_ID_ADPCM_G726LE: { + if (payload_type >= RTP_PT_PRIVATE) + av_strlcatf(buff, size, "a=rtpmap:%d G726-%d/%d\r\n", + payload_type, + p->bits_per_coded_sample*8, + p->sample_rate); + break; + } case AV_CODEC_ID_ILBC: av_strlcatf(buff, size, "a=rtpmap:%d iLBC/%d\r\n" "a=fmtp:%d mode=%d\r\n", diff --git a/libavformat/version.h b/libavformat/version.h index b5ad2101e07c1..caf85e8538d21 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -33,7 +33,7 @@ // Also please add any ticket numbers that you believe might be affected here #define LIBAVFORMAT_VERSION_MAJOR 57 #define LIBAVFORMAT_VERSION_MINOR 82 -#define LIBAVFORMAT_VERSION_MICRO 103 +#define LIBAVFORMAT_VERSION_MICRO 104 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ From 5d3e935728c166344259e5a9bc1a223abb83d3f1 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Sat, 7 Oct 2017 15:59:22 +0200 Subject: [PATCH 3279/3374] lavfi: Rename local variables "main" as "master". Silences several warnings: main is usually a function --- libavfilter/vf_lut3d.c | 8 ++++---- libavfilter/vf_paletteuse.c | 10 +++++----- libavfilter/vf_psnr.c | 14 +++++++------- libavfilter/vf_ssim.c | 12 ++++++------ 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/libavfilter/vf_lut3d.c b/libavfilter/vf_lut3d.c index 39cd73f0de4f4..c9b72249aadb0 100644 --- a/libavfilter/vf_lut3d.c +++ b/libavfilter/vf_lut3d.c @@ -752,16 +752,16 @@ static int update_apply_clut(FFFrameSync *fs) { AVFilterContext *ctx = fs->parent; AVFilterLink *inlink = ctx->inputs[0]; - AVFrame *main, *second, *out; + AVFrame *master, *second, *out; int ret; - ret = ff_framesync_dualinput_get(fs, &main, &second); + ret = ff_framesync_dualinput_get(fs, &master, &second); if (ret < 0) return ret; if (!second) - return ff_filter_frame(ctx->outputs[0], main); + return ff_filter_frame(ctx->outputs[0], master); update_clut(ctx->priv, second); - out = apply_lut(inlink, main); + out = apply_lut(inlink, master); return ff_filter_frame(ctx->outputs[0], out); } diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c index ffd37bf1da067..79a06728919e9 100644 --- a/libavfilter/vf_paletteuse.c +++ b/libavfilter/vf_paletteuse.c @@ -967,25 +967,25 @@ static int load_apply_palette(FFFrameSync *fs) AVFilterContext *ctx = fs->parent; AVFilterLink *inlink = ctx->inputs[0]; PaletteUseContext *s = ctx->priv; - AVFrame *main, *second, *out; + AVFrame *master, *second, *out; int ret; // writable for error diffusal dithering - ret = ff_framesync_dualinput_get_writable(fs, &main, &second); + ret = ff_framesync_dualinput_get_writable(fs, &master, &second); if (ret < 0) return ret; - if (!main || !second) { + if (!master || !second) { ret = AVERROR_BUG; goto error; } if (!s->palette_loaded) { load_palette(s, second); } - out = apply_palette(inlink, main); + out = apply_palette(inlink, master); return ff_filter_frame(ctx->outputs[0], out); error: - av_frame_free(&main); + av_frame_free(&master); av_frame_free(&second); return ret; } diff --git a/libavfilter/vf_psnr.c b/libavfilter/vf_psnr.c index adf16444ff0c6..493a501a7a41e 100644 --- a/libavfilter/vf_psnr.c +++ b/libavfilter/vf_psnr.c @@ -146,21 +146,21 @@ static int do_psnr(FFFrameSync *fs) { AVFilterContext *ctx = fs->parent; PSNRContext *s = ctx->priv; - AVFrame *main, *ref; + AVFrame *master, *ref; double comp_mse[4], mse = 0; int ret, j, c; AVDictionary **metadata; - ret = ff_framesync_dualinput_get(fs, &main, &ref); + ret = ff_framesync_dualinput_get(fs, &master, &ref); if (ret < 0) return ret; if (!ref) - return ff_filter_frame(ctx->outputs[0], main); - metadata = &main->metadata; + return ff_filter_frame(ctx->outputs[0], master); + metadata = &master->metadata; - compute_images_mse(s, (const uint8_t **)main->data, main->linesize, + compute_images_mse(s, (const uint8_t **)master->data, master->linesize, (const uint8_t **)ref->data, ref->linesize, - main->width, main->height, comp_mse); + master->width, master->height, comp_mse); for (j = 0; j < s->nb_components; j++) mse += comp_mse[j] * s->planeweight[j]; @@ -222,7 +222,7 @@ static int do_psnr(FFFrameSync *fs) fprintf(s->stats_file, "\n"); } - return ff_filter_frame(ctx->outputs[0], main); + return ff_filter_frame(ctx->outputs[0], master); } static av_cold int init(AVFilterContext *ctx) diff --git a/libavfilter/vf_ssim.c b/libavfilter/vf_ssim.c index 40f09ad5aa432..4dcdc0548b11d 100644 --- a/libavfilter/vf_ssim.c +++ b/libavfilter/vf_ssim.c @@ -286,22 +286,22 @@ static int do_ssim(FFFrameSync *fs) { AVFilterContext *ctx = fs->parent; SSIMContext *s = ctx->priv; - AVFrame *main, *ref; + AVFrame *master, *ref; AVDictionary **metadata; float c[4], ssimv = 0.0; int ret, i; - ret = ff_framesync_dualinput_get(fs, &main, &ref); + ret = ff_framesync_dualinput_get(fs, &master, &ref); if (ret < 0) return ret; if (!ref) - return ff_filter_frame(ctx->outputs[0], main); - metadata = &main->metadata; + return ff_filter_frame(ctx->outputs[0], master); + metadata = &master->metadata; s->nb_frames++; for (i = 0; i < s->nb_components; i++) { - c[i] = s->ssim_plane(&s->dsp, main->data[i], main->linesize[i], + c[i] = s->ssim_plane(&s->dsp, master->data[i], master->linesize[i], ref->data[i], ref->linesize[i], s->planewidth[i], s->planeheight[i], s->temp, s->max); @@ -328,7 +328,7 @@ static int do_ssim(FFFrameSync *fs) fprintf(s->stats_file, "All:%f (%f)\n", ssimv, ssim_db(ssimv, 1.0)); } - return ff_filter_frame(ctx->outputs[0], main); + return ff_filter_frame(ctx->outputs[0], master); } static av_cold int init(AVFilterContext *ctx) From d96d65dfebdd9f1396d51817c1716f86e536245c Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Sun, 8 Oct 2017 01:13:16 +0200 Subject: [PATCH 3280/3374] lavu/utils: Use "__asm__" like everywhere else in the codebase. --- libavutil/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavutil/utils.c b/libavutil/utils.c index 8cc7a9516cae9..2c170db2e10db 100644 --- a/libavutil/utils.c +++ b/libavutil/utils.c @@ -152,7 +152,7 @@ AVRational av_get_time_base_q(void) void av_assert0_fpu(void) { #if HAVE_MMX_INLINE uint16_t state[14]; - __asm volatile ( + __asm__ volatile ( "fstenv %0 \n\t" : "+m" (state) : From 41d6d627024393c142cf7cd93eff1d5a049105f5 Mon Sep 17 00:00:00 2001 From: Michael Bradshaw Date: Wed, 4 Oct 2017 15:37:11 -0700 Subject: [PATCH 3281/3374] lavc: add support for OpenJPEG 2.3.0 Signed-off-by: Michael Bradshaw --- configure | 5 ++++- libavcodec/libopenjpegdec.c | 8 +++++--- libavcodec/libopenjpegenc.c | 10 ++++++---- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/configure b/configure index 391c141e7a3f0..77c9a18c3ca21 100755 --- a/configure +++ b/configure @@ -1930,6 +1930,7 @@ HEADERS_LIST=" machine_ioctl_meteor_h malloc_h opencv2_core_core_c_h + openjpeg_2_3_openjpeg_h openjpeg_2_2_openjpeg_h openjpeg_2_1_openjpeg_h openjpeg_2_0_openjpeg_h @@ -5950,7 +5951,9 @@ enabled libopencv && { check_header opencv2/core/core_c.h && require opencv opencv2/core/core_c.h cvCreateImageHeader -lopencv_core -lopencv_imgproc; } || require_pkg_config libopencv opencv opencv/cxcore.h cvCreateImageHeader; } enabled libopenh264 && require_pkg_config libopenh264 openh264 wels/codec_api.h WelsGetCodecVersion -enabled libopenjpeg && { { check_lib libopenjpeg openjpeg-2.2/openjpeg.h opj_version -lopenjp2 -DOPJ_STATIC && add_cppflags -DOPJ_STATIC; } || +enabled libopenjpeg && { { check_lib libopenjpeg openjpeg-2.3/openjpeg.h opj_version -lopenjp2 -DOPJ_STATIC && add_cppflags -DOPJ_STATIC; } || + check_lib libopenjpeg openjpeg-2.3/openjpeg.h opj_version -lopenjp2 || + { check_lib libopenjpeg openjpeg-2.2/openjpeg.h opj_version -lopenjp2 -DOPJ_STATIC && add_cppflags -DOPJ_STATIC; } || check_lib libopenjpeg openjpeg-2.2/openjpeg.h opj_version -lopenjp2 || { check_lib libopenjpeg openjpeg-2.1/openjpeg.h opj_version -lopenjp2 -DOPJ_STATIC && add_cppflags -DOPJ_STATIC; } || check_lib libopenjpeg openjpeg-2.1/openjpeg.h opj_version -lopenjp2 || diff --git a/libavcodec/libopenjpegdec.c b/libavcodec/libopenjpegdec.c index 1210123265fb6..67d47bd6a0aa1 100644 --- a/libavcodec/libopenjpegdec.c +++ b/libavcodec/libopenjpegdec.c @@ -34,7 +34,9 @@ #include "internal.h" #include "thread.h" -#if HAVE_OPENJPEG_2_2_OPENJPEG_H +#if HAVE_OPENJPEG_2_3_OPENJPEG_H +# include +#elif HAVE_OPENJPEG_2_2_OPENJPEG_H # include #elif HAVE_OPENJPEG_2_1_OPENJPEG_H # include @@ -46,7 +48,7 @@ # include #endif -#if HAVE_OPENJPEG_2_2_OPENJPEG_H || HAVE_OPENJPEG_2_1_OPENJPEG_H || HAVE_OPENJPEG_2_0_OPENJPEG_H +#if HAVE_OPENJPEG_2_3_OPENJPEG_H || HAVE_OPENJPEG_2_2_OPENJPEG_H || HAVE_OPENJPEG_2_1_OPENJPEG_H || HAVE_OPENJPEG_2_0_OPENJPEG_H # define OPENJPEG_MAJOR_VERSION 2 # define OPJ(x) OPJ_##x #else @@ -431,7 +433,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx, opj_stream_set_read_function(stream, stream_read); opj_stream_set_skip_function(stream, stream_skip); opj_stream_set_seek_function(stream, stream_seek); -#if HAVE_OPENJPEG_2_2_OPENJPEG_H || HAVE_OPENJPEG_2_1_OPENJPEG_H +#if HAVE_OPENJPEG_2_3_OPENJPEG_H || HAVE_OPENJPEG_2_2_OPENJPEG_H || HAVE_OPENJPEG_2_1_OPENJPEG_H opj_stream_set_user_data(stream, &reader, NULL); #elif HAVE_OPENJPEG_2_0_OPENJPEG_H opj_stream_set_user_data(stream, &reader); diff --git a/libavcodec/libopenjpegenc.c b/libavcodec/libopenjpegenc.c index b67e533d1dad1..92b4433b04759 100644 --- a/libavcodec/libopenjpegenc.c +++ b/libavcodec/libopenjpegenc.c @@ -32,7 +32,9 @@ #include "avcodec.h" #include "internal.h" -#if HAVE_OPENJPEG_2_2_OPENJPEG_H +#if HAVE_OPENJPEG_2_3_OPENJPEG_H +# include +#elif HAVE_OPENJPEG_2_2_OPENJPEG_H # include #elif HAVE_OPENJPEG_2_1_OPENJPEG_H # include @@ -44,7 +46,7 @@ # include #endif -#if HAVE_OPENJPEG_2_2_OPENJPEG_H || HAVE_OPENJPEG_2_1_OPENJPEG_H || HAVE_OPENJPEG_2_0_OPENJPEG_H +#if HAVE_OPENJPEG_2_3_OPENJPEG_H || HAVE_OPENJPEG_2_2_OPENJPEG_H || HAVE_OPENJPEG_2_1_OPENJPEG_H || HAVE_OPENJPEG_2_0_OPENJPEG_H # define OPENJPEG_MAJOR_VERSION 2 # define OPJ(x) OPJ_##x #else @@ -307,7 +309,7 @@ static av_cold int libopenjpeg_encode_init(AVCodecContext *avctx) opj_set_default_encoder_parameters(&ctx->enc_params); -#if HAVE_OPENJPEG_2_2_OPENJPEG_H || HAVE_OPENJPEG_2_1_OPENJPEG_H +#if HAVE_OPENJPEG_2_3_OPENJPEG_H || HAVE_OPENJPEG_2_2_OPENJPEG_H || HAVE_OPENJPEG_2_1_OPENJPEG_H switch (ctx->cinema_mode) { case OPJ_CINEMA2K_24: ctx->enc_params.rsiz = OPJ_PROFILE_CINEMA_2K; @@ -771,7 +773,7 @@ static int libopenjpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt, opj_stream_set_write_function(stream, stream_write); opj_stream_set_skip_function(stream, stream_skip); opj_stream_set_seek_function(stream, stream_seek); -#if HAVE_OPENJPEG_2_2_OPENJPEG_H || HAVE_OPENJPEG_2_1_OPENJPEG_H +#if HAVE_OPENJPEG_2_3_OPENJPEG_H || HAVE_OPENJPEG_2_2_OPENJPEG_H || HAVE_OPENJPEG_2_1_OPENJPEG_H opj_stream_set_user_data(stream, &writer, NULL); #elif HAVE_OPENJPEG_2_0_OPENJPEG_H opj_stream_set_user_data(stream, &writer); From 41569bbc66d8971a1c5d369e5b335b3542f9cd26 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Fri, 6 Oct 2017 21:49:09 +0200 Subject: [PATCH 3282/3374] ffmpeg: always use single threaded decoding for attached pictures Since af1761f7b5b1b72197dc40934953b775c2d951cc ffmpeg waits for a frame in each stream before writing the output header. If we are using threaded decoding for attached pictures, we have to read till EOF to be able to finally flush the decoder and output the decoded frame. This essentially makes ffmpeg buffer all non-attached picture packets, which will cause a "Too many packets buffered for output stream" eventually. By forcing single threaded decoding, we get a frame from a single packet as well and we can avoid the error. Fixes part of ticket #6375: ffmpeg -i 46564100.mp3 -acodec libmp3lame -ab 128k -ac 2 out.mp3 Reviewed-by: Hendrik Leppkes Signed-off-by: Marton Balint --- fftools/ffmpeg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 1d248bc269d80..6d64bc1043ad0 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -2909,6 +2909,9 @@ static int init_input_stream(int ist_index, char *error, int error_len) if (!av_dict_get(ist->decoder_opts, "threads", NULL, 0)) av_dict_set(&ist->decoder_opts, "threads", "auto", 0); + /* Attached pics are sparse, therefore we would not want to delay their decoding till EOF. */ + if (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC) + av_dict_set(&ist->decoder_opts, "threads", "1", 0); ret = hw_device_setup_for_decode(ist); if (ret < 0) { From f49c129dd494378b16f3f782f59f07bbabfab258 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Sun, 8 Oct 2017 22:58:33 +0200 Subject: [PATCH 3283/3374] lavd/decklink_dec: Do not claim to output transparency information. --- libavdevice/decklink_dec.cpp | 4 ++-- libavdevice/version.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index 7ac04375d9ea4..6f796e4941cae 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -965,13 +965,13 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) case bmdFormat8BitARGB: st->codecpar->codec_id = AV_CODEC_ID_RAWVIDEO; st->codecpar->codec_tag = avcodec_pix_fmt_to_codec_tag((enum AVPixelFormat)st->codecpar->format);; - st->codecpar->format = AV_PIX_FMT_ARGB; + st->codecpar->format = AV_PIX_FMT_0RGB; st->codecpar->bit_rate = av_rescale(ctx->bmd_width * ctx->bmd_height * 32, st->time_base.den, st->time_base.num); break; case bmdFormat8BitBGRA: st->codecpar->codec_id = AV_CODEC_ID_RAWVIDEO; st->codecpar->codec_tag = avcodec_pix_fmt_to_codec_tag((enum AVPixelFormat)st->codecpar->format); - st->codecpar->format = AV_PIX_FMT_BGRA; + st->codecpar->format = AV_PIX_FMT_BGR0; st->codecpar->bit_rate = av_rescale(ctx->bmd_width * ctx->bmd_height * 32, st->time_base.den, st->time_base.num); break; case bmdFormat10BitRGB: diff --git a/libavdevice/version.h b/libavdevice/version.h index 3fbd273fc3a92..14b8e2acaed42 100644 --- a/libavdevice/version.h +++ b/libavdevice/version.h @@ -29,7 +29,7 @@ #define LIBAVDEVICE_VERSION_MAJOR 57 #define LIBAVDEVICE_VERSION_MINOR 9 -#define LIBAVDEVICE_VERSION_MICRO 101 +#define LIBAVDEVICE_VERSION_MICRO 102 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ LIBAVDEVICE_VERSION_MINOR, \ From c2d155e11ee5ec732d471982f2dee43703bcd5a7 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Sun, 8 Oct 2017 23:08:09 +0200 Subject: [PATCH 3284/3374] configure: Disable -Wbool-operation. Requested-by: Ronald and Derek --- configure | 1 + 1 file changed, 1 insertion(+) diff --git a/configure b/configure index 77c9a18c3ca21..d5e96e95e1518 100755 --- a/configure +++ b/configure @@ -6291,6 +6291,7 @@ check_cflags -Wmissing-prototypes check_cflags -Wno-pointer-to-int-cast check_cflags -Wstrict-prototypes check_cflags -Wempty-body +check_cflags -Wno-bool-operation if enabled extra_warnings; then check_cflags -Wcast-qual From cd01b3cbcf3bc738dd9714fa760f6a8fec0b39d2 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Fri, 5 May 2017 01:30:19 +0200 Subject: [PATCH 3285/3374] lavu/opt: Use "&&" instead of "*" in boolean expression. Fixes the following warning: libavutil/opt.c:101:47: warning: '*' in boolean context, suggest '&&' instead --- libavutil/opt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavutil/opt.c b/libavutil/opt.c index 6f870789265a9..df88663e3f09b 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -98,7 +98,7 @@ static int write_number(void *obj, const AVOption *o, void *dst, double num, int { if (o->type != AV_OPT_TYPE_FLAGS && (!den || o->max * den < num * intnum || o->min * den > num * intnum)) { - num = den ? num * intnum / den : (num * intnum ? INFINITY : NAN); + num = den ? num * intnum / den : (num && intnum ? INFINITY : NAN); av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n", num, o->name, o->min, o->max); return AVERROR(ERANGE); From 65c3a32836f477f23763003112fa77ce321fabe5 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sun, 8 Oct 2017 18:46:21 -0300 Subject: [PATCH 3286/3374] configure: disable libxcb dependent features if libxcb is not enabled Signed-off-by: James Almer --- configure | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure b/configure index d5e96e95e1518..946124025d708 100755 --- a/configure +++ b/configure @@ -6199,7 +6199,8 @@ if enabled libcdio; then die "ERROR: No usable libcdio/cdparanoia found" fi -enabled libxcb && check_pkg_config libxcb "xcb >= 1.4" xcb/xcb.h xcb_connect +enabled libxcb && check_pkg_config libxcb "xcb >= 1.4" xcb/xcb.h xcb_connect || + disable libxcb_shm libxcb_shape libxcb_xfixes if enabled libxcb; then enabled libxcb_shm && check_pkg_config libxcb_shm xcb-shm xcb/shm.h xcb_shm_attach From 9c7a71145b88e56cb5f67c66f6d27c20c8d06165 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 1 Oct 2017 22:51:07 +0100 Subject: [PATCH 3287/3374] configure: Add config option for libva2 (VAAPI 1) --- configure | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/configure b/configure index 946124025d708..f634a83bf6ce4 100755 --- a/configure +++ b/configure @@ -2205,6 +2205,7 @@ CONFIG_EXTRA=" texturedsp texturedspenc tpeldsp + vaapi_1 vaapi_encode vc1dsp videodsp @@ -6241,6 +6242,10 @@ enabled vaapi && enabled vaapi && check_lib vaapi_x11 "va/va.h va/va_x11.h" vaGetDisplay -lva -lva-x11 -lX11 +enabled vaapi && + check_cpp_condition "va/va.h" "VA_CHECK_VERSION(1, 0, 0)" && + enable vaapi_1 + enabled vdpau && check_cpp_condition vdpau/vdpau.h "defined VDP_DECODER_PROFILE_MPEG4_PART2_ASP" || disable vdpau From bd211bb866f8bf5c372589fc44dc06d1a9509c0a Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 8 Oct 2017 14:48:24 +0100 Subject: [PATCH 3288/3374] vaapi: Remove H.264 baseline profile This has been deprecated in libva2 because hardware does not and will not support it. Therefore never consider it for decode, and for encode assume the user meant constrained baseline profile instead. --- libavcodec/vaapi_decode.c | 1 - libavcodec/vaapi_encode_h264.c | 12 ++++-------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c index cf58aae4c6f1a..4f0ff84e01a9e 100644 --- a/libavcodec/vaapi_decode.c +++ b/libavcodec/vaapi_decode.c @@ -246,7 +246,6 @@ static const struct { MAP(MPEG4, MPEG4_MAIN, MPEG4Main ), MAP(H264, H264_CONSTRAINED_BASELINE, H264ConstrainedBaseline), - MAP(H264, H264_BASELINE, H264Baseline), MAP(H264, H264_MAIN, H264Main ), MAP(H264, H264_HIGH, H264High ), #if VA_CHECK_VERSION(0, 37, 0) diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index 549867ef3f51b..efde80b08ee9c 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -1175,6 +1175,10 @@ static av_cold int vaapi_encode_h264_init(AVCodecContext *avctx) ctx->codec = &vaapi_encode_type_h264; switch (avctx->profile) { + case FF_PROFILE_H264_BASELINE: + av_log(avctx, AV_LOG_WARNING, "H.264 baseline profile is not " + "supported, using constrained baseline profile instead.\n"); + avctx->profile = FF_PROFILE_H264_CONSTRAINED_BASELINE; case FF_PROFILE_H264_CONSTRAINED_BASELINE: ctx->va_profile = VAProfileH264ConstrainedBaseline; if (avctx->max_b_frames != 0) { @@ -1183,14 +1187,6 @@ static av_cold int vaapi_encode_h264_init(AVCodecContext *avctx) "doesn't support encoding with B frames, disabling them.\n"); } break; - case FF_PROFILE_H264_BASELINE: - ctx->va_profile = VAProfileH264Baseline; - if (avctx->max_b_frames != 0) { - avctx->max_b_frames = 0; - av_log(avctx, AV_LOG_WARNING, "H.264 baseline profile " - "doesn't support encoding with B frames, disabling them.\n"); - } - break; case FF_PROFILE_H264_MAIN: ctx->va_profile = VAProfileH264Main; break; From e339411691e3671b595e556ba3411c1acb8c4692 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 1 Oct 2017 22:51:20 +0100 Subject: [PATCH 3289/3374] vaapi: Always free parameter buffers after vaEndPicture() with libva2 This is an ABI change in libva2: previously the Intel driver had this behaviour and it was implemented as a driver quirk, but now it is part of the specification so all drivers must do it. --- libavcodec/vaapi_decode.c | 4 ++-- libavcodec/vaapi_encode.c | 4 ++-- libavfilter/vf_deinterlace_vaapi.c | 2 +- libavfilter/vf_scale_vaapi.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c index 4f0ff84e01a9e..5a555b2bd3ed9 100644 --- a/libavcodec/vaapi_decode.c +++ b/libavcodec/vaapi_decode.c @@ -188,14 +188,14 @@ int ff_vaapi_decode_issue(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "Failed to end picture decode " "issue: %d (%s).\n", vas, vaErrorStr(vas)); err = AVERROR(EIO); - if (ctx->hwctx->driver_quirks & + if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS) goto fail; else goto fail_at_end; } - if (ctx->hwctx->driver_quirks & + if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS) ff_vaapi_decode_destroy_buffers(avctx, pic); diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index e13e99587dff3..590f4be4ed041 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -399,14 +399,14 @@ static int vaapi_encode_issue(AVCodecContext *avctx, err = AVERROR(EIO); // vaRenderPicture() has been called here, so we should not destroy // the parameter buffers unless separate destruction is required. - if (ctx->hwctx->driver_quirks & + if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS) goto fail; else goto fail_at_end; } - if (ctx->hwctx->driver_quirks & + if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS) { for (i = 0; i < pic->nb_param_buffers; i++) { vas = vaDestroyBuffer(ctx->hwctx->display, diff --git a/libavfilter/vf_deinterlace_vaapi.c b/libavfilter/vf_deinterlace_vaapi.c index 838eb89c90689..44c5ae7642cbd 100644 --- a/libavfilter/vf_deinterlace_vaapi.c +++ b/libavfilter/vf_deinterlace_vaapi.c @@ -539,7 +539,7 @@ static int deint_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame) goto fail_after_render; } - if (ctx->hwctx->driver_quirks & + if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS) { vas = vaDestroyBuffer(ctx->hwctx->display, params_id); if (vas != VA_STATUS_SUCCESS) { diff --git a/libavfilter/vf_scale_vaapi.c b/libavfilter/vf_scale_vaapi.c index 5f049a5d7bb96..22e928c098871 100644 --- a/libavfilter/vf_scale_vaapi.c +++ b/libavfilter/vf_scale_vaapi.c @@ -361,7 +361,7 @@ static int scale_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame) goto fail_after_render; } - if (ctx->hwctx->driver_quirks & + if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS) { vas = vaDestroyBuffer(ctx->hwctx->display, params_id); if (vas != VA_STATUS_SUCCESS) { From 5f3978866879ebaa1f1a1f678777df489d3d34f3 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 1 Oct 2017 22:51:31 +0100 Subject: [PATCH 3290/3374] hwcontext_vaapi: Factorise out common connection code This was duplicated between normal device creation and creation by derivation from a DRM device. --- libavutil/hwcontext_vaapi.c | 53 +++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index 9214dc6e50d80..2977878022fa8 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -1094,14 +1094,32 @@ static void vaapi_device_free(AVHWDeviceContext *ctx) av_freep(&priv); } +static int vaapi_device_connect(AVHWDeviceContext *ctx, + VADisplay display) +{ + AVVAAPIDeviceContext *hwctx = ctx->hwctx; + int major, minor; + VAStatus vas; + + hwctx->display = display; + + vas = vaInitialize(display, &major, &minor); + if (vas != VA_STATUS_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed to initialise VAAPI " + "connection: %d (%s).\n", vas, vaErrorStr(vas)); + return AVERROR(EIO); + } + av_log(ctx, AV_LOG_VERBOSE, "Initialised VAAPI connection: " + "version %d.%d\n", major, minor); + + return 0; +} + static int vaapi_device_create(AVHWDeviceContext *ctx, const char *device, AVDictionary *opts, int flags) { - AVVAAPIDeviceContext *hwctx = ctx->hwctx; VAAPIDevicePriv *priv; - VADisplay display = 0; - VAStatus vas; - int major, minor; + VADisplay display = NULL; priv = av_mallocz(sizeof(*priv)); if (!priv) @@ -1163,18 +1181,7 @@ static int vaapi_device_create(AVHWDeviceContext *ctx, const char *device, return AVERROR(EINVAL); } - hwctx->display = display; - - vas = vaInitialize(display, &major, &minor); - if (vas != VA_STATUS_SUCCESS) { - av_log(ctx, AV_LOG_ERROR, "Failed to initialise VAAPI " - "connection: %d (%s).\n", vas, vaErrorStr(vas)); - return AVERROR(EIO); - } - av_log(ctx, AV_LOG_VERBOSE, "Initialised VAAPI connection: " - "version %d.%d\n", major, minor); - - return 0; + return vaapi_device_connect(ctx, display); } static int vaapi_device_derive(AVHWDeviceContext *ctx, @@ -1183,11 +1190,8 @@ static int vaapi_device_derive(AVHWDeviceContext *ctx, #if CONFIG_LIBDRM if (src_ctx->type == AV_HWDEVICE_TYPE_DRM) { AVDRMDeviceContext *src_hwctx = src_ctx->hwctx; - AVVAAPIDeviceContext *hwctx = ctx->hwctx; VADisplay *display; - VAStatus vas; VAAPIDevicePriv *priv; - int major, minor; if (src_hwctx->fd < 0) { av_log(ctx, AV_LOG_ERROR, "DRM instance requires an associated " @@ -1212,16 +1216,7 @@ static int vaapi_device_derive(AVHWDeviceContext *ctx, return AVERROR(EIO); } - hwctx->display = display; - - vas = vaInitialize(display, &major, &minor); - if (vas != VA_STATUS_SUCCESS) { - av_log(ctx, AV_LOG_ERROR, "Failed to initialise VAAPI " - "connection: %d (%s).\n", vas, vaErrorStr(vas)); - return AVERROR(EIO); - } - - return 0; + return vaapi_device_connect(ctx, display); } #endif return AVERROR(ENOSYS); From f3602875b3255c533900df1c7bb4e78ef5e1ce08 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 8 Oct 2017 16:54:37 +0100 Subject: [PATCH 3291/3374] hwcontext_vaapi: Set message callbacks on internally-created devices The message callbacks are library-safe in libva2, so we can now use them. --- libavutil/hwcontext_vaapi.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index 2977878022fa8..b2f2e376d8971 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -1094,6 +1094,22 @@ static void vaapi_device_free(AVHWDeviceContext *ctx) av_freep(&priv); } +#if CONFIG_VAAPI_1 +static void vaapi_device_log_error(void *context, const char *message) +{ + AVHWDeviceContext *ctx = context; + + av_log(ctx, AV_LOG_ERROR, "libva: %s", message); +} + +static void vaapi_device_log_info(void *context, const char *message) +{ + AVHWDeviceContext *ctx = context; + + av_log(ctx, AV_LOG_VERBOSE, "libva: %s", message); +} +#endif + static int vaapi_device_connect(AVHWDeviceContext *ctx, VADisplay display) { @@ -1101,6 +1117,11 @@ static int vaapi_device_connect(AVHWDeviceContext *ctx, int major, minor; VAStatus vas; +#if CONFIG_VAAPI_1 + vaSetErrorCallback(display, &vaapi_device_log_error, ctx); + vaSetInfoCallback (display, &vaapi_device_log_info, ctx); +#endif + hwctx->display = display; vas = vaInitialize(display, &major, &minor); From 309d660775e2b47af6723a0477c4d753bc0c54f4 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 8 Oct 2017 15:19:17 +0100 Subject: [PATCH 3292/3374] hwcontext: Perform usual initialisation on derived device contexts The initialisation should be common. For libmfx, it was previously happening in the derivation function and this moves it out. For VAAPI, it fixes some failures when deriving from a DRM device because this initialisation did not run. --- libavutil/hwcontext.c | 4 ++++ libavutil/hwcontext_qsv.c | 10 ---------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/libavutil/hwcontext.c b/libavutil/hwcontext.c index 2f4ee9661ef3a..048e82126fbaa 100644 --- a/libavutil/hwcontext.c +++ b/libavutil/hwcontext.c @@ -650,6 +650,10 @@ int av_hwdevice_ctx_create_derived(AVBufferRef **dst_ref_ptr, goto fail; done: + ret = av_hwdevice_ctx_init(dst_ref); + if (ret < 0) + goto fail; + *dst_ref_ptr = dst_ref; return 0; diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c index 75057f7d52b98..f1d16d8bf92c6 100644 --- a/libavutil/hwcontext_qsv.c +++ b/libavutil/hwcontext_qsv.c @@ -1037,16 +1037,6 @@ static int qsv_device_derive_from_child(AVHWDeviceContext *ctx, goto fail; } - ret = qsv_device_init(ctx); - if (ret < 0) - goto fail; - if (s->handle_type != handle_type) { - av_log(ctx, AV_LOG_ERROR, "Error in child device handle setup: " - "type mismatch (%d != %d).\n", s->handle_type, handle_type); - err = AVERROR_UNKNOWN; - goto fail; - } - return 0; fail: From b2f256a9f5db148ab96974400ca7e170494407d0 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 8 Oct 2017 16:00:47 +0100 Subject: [PATCH 3293/3374] hwcontext_vaapi: Add support for mapping to DRM objects Uses vaExportSurfaceHandle() from libva2. --- libavutil/hwcontext_vaapi.c | 108 +++++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 2 deletions(-) diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index b2f2e376d8971..40a85d288c6a9 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -884,8 +884,8 @@ static int vaapi_transfer_data_to(AVHWFramesContext *hwfc, return err; } -static int vaapi_map_from(AVHWFramesContext *hwfc, AVFrame *dst, - const AVFrame *src, int flags) +static int vaapi_map_to_memory(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) { int err; @@ -1060,6 +1060,97 @@ static int vaapi_map_from_drm(AVHWFramesContext *src_fc, AVFrame *dst, return 0; } + +static void vaapi_unmap_to_drm(AVHWFramesContext *dst_fc, + HWMapDescriptor *hwmap) +{ + AVDRMFrameDescriptor *drm_desc = hwmap->priv; + int i; + + for (i = 0; i < drm_desc->nb_objects; i++) + close(drm_desc->objects[i].fd); + + av_freep(&drm_desc); +} + +static int vaapi_map_to_drm(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ +#if CONFIG_VAAPI_1 + AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; + VASurfaceID surface_id; + VAStatus vas; + VADRMPRIMESurfaceDescriptor va_desc; + AVDRMFrameDescriptor *drm_desc = NULL; + int err, i, j; + + surface_id = (VASurfaceID)(uintptr_t)src->data[3]; + + vas = vaExportSurfaceHandle(hwctx->display, surface_id, + VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2, + VA_EXPORT_SURFACE_READ_ONLY | + VA_EXPORT_SURFACE_SEPARATE_LAYERS, + &va_desc); + if (vas != VA_STATUS_SUCCESS) { + if (vas == VA_STATUS_ERROR_UNIMPLEMENTED) + return AVERROR(ENOSYS); + av_log(hwfc, AV_LOG_ERROR, "Failed to export surface %#x: " + "%d (%s).\n", surface_id, vas, vaErrorStr(vas)); + return AVERROR(EIO); + } + + drm_desc = av_mallocz(sizeof(*drm_desc)); + if (!drm_desc) { + err = AVERROR(ENOMEM); + goto fail; + } + + // By some bizarre coincidence, these structures are very similar... + drm_desc->nb_objects = va_desc.num_objects; + for (i = 0; i < va_desc.num_objects; i++) { + drm_desc->objects[i].fd = va_desc.objects[i].fd; + drm_desc->objects[i].size = va_desc.objects[i].size; + drm_desc->objects[i].format_modifier = + va_desc.objects[i].drm_format_modifier; + } + drm_desc->nb_layers = va_desc.num_layers; + for (i = 0; i < va_desc.num_layers; i++) { + drm_desc->layers[i].format = va_desc.layers[i].drm_format; + drm_desc->layers[i].nb_planes = va_desc.layers[i].num_planes; + for (j = 0; j < va_desc.layers[i].num_planes; j++) { + drm_desc->layers[i].planes[j].object_index = + va_desc.layers[i].object_index[j]; + drm_desc->layers[i].planes[j].offset = + va_desc.layers[i].offset[j]; + drm_desc->layers[i].planes[j].pitch = + va_desc.layers[i].pitch[j]; + } + } + + err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, + &vaapi_unmap_to_drm, drm_desc); + if (err < 0) + goto fail; + + dst->width = src->width; + dst->height = src->height; + dst->data[0] = (uint8_t*)drm_desc; + + return 0; + +fail: + for (i = 0; i < va_desc.num_objects; i++) + close(va_desc.objects[i].fd); + av_freep(&drm_desc); + return err; +#else + // Older versions without vaExportSurfaceHandle() are not supported - + // in theory this is possible with a combination of vaDeriveImage() + // and vaAcquireBufferHandle(), but it doesn't carry enough metadata + // to actually use the result in a generic way. + return AVERROR(ENOSYS); +#endif +} #endif static int vaapi_map_to(AVHWFramesContext *hwfc, AVFrame *dst, @@ -1075,6 +1166,19 @@ static int vaapi_map_to(AVHWFramesContext *hwfc, AVFrame *dst, } } +static int vaapi_map_from(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + switch (dst->format) { +#if CONFIG_LIBDRM + case AV_PIX_FMT_DRM_PRIME: + return vaapi_map_to_drm(hwfc, dst, src, flags); +#endif + default: + return vaapi_map_to_memory(hwfc, dst, src, flags); + } +} + static void vaapi_device_free(AVHWDeviceContext *ctx) { AVVAAPIDeviceContext *hwctx = ctx->hwctx; From c154c34c1b37f570ee879560903af1a1a26153e1 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Mon, 9 Oct 2017 00:53:51 +0100 Subject: [PATCH 3294/3374] Revert "configure: Disable -Wbool-operation." MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit c2d155e11ee5ec732d471982f2dee43703bcd5a7. GCC 6 incorrectly passes the configure test and then logs many warnings of the form: src/libavformat/dump.c: At top level: cc1: warning: unrecognized command line option ‘-Wno-bool-operation’ --- configure | 1 - 1 file changed, 1 deletion(-) diff --git a/configure b/configure index f634a83bf6ce4..0c75f7f5c96bf 100755 --- a/configure +++ b/configure @@ -6297,7 +6297,6 @@ check_cflags -Wmissing-prototypes check_cflags -Wno-pointer-to-int-cast check_cflags -Wstrict-prototypes check_cflags -Wempty-body -check_cflags -Wno-bool-operation if enabled extra_warnings; then check_cflags -Wcast-qual From c585b4e9f0b30b2ce60a48246f6fe656b4fb3957 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Mon, 9 Oct 2017 02:21:08 +0200 Subject: [PATCH 3295/3374] configure: Disable -Wbool-operation using check_disable_warning(). Suggested-by: James Almer --- configure | 1 + 1 file changed, 1 insertion(+) diff --git a/configure b/configure index 0c75f7f5c96bf..fc377d90fbd68 100755 --- a/configure +++ b/configure @@ -6314,6 +6314,7 @@ check_disable_warning -Wno-switch check_disable_warning -Wno-format-zero-length check_disable_warning -Wno-pointer-sign check_disable_warning -Wno-unused-const-variable +check_disable_warning -Wno-bool-operation check_disable_warning_headers(){ warning_flag=-W${1#-Wno-} From 14b15539398f5b7f72686e60c664fed1518bc20d Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Sun, 8 Oct 2017 23:41:14 +0200 Subject: [PATCH 3296/3374] lavf/adp: Fix the probe function on systems with signed char. --- libavformat/adp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/adp.c b/libavformat/adp.c index 735550307e857..3914857ad53a0 100644 --- a/libavformat/adp.c +++ b/libavformat/adp.c @@ -27,7 +27,7 @@ static int adp_probe(AVProbeData *p) { int i, changes = 0; - char last = 0; + uint8_t last = 0; if (p->buf_size < 32) return 0; From 23990950e35eff0b96f843c396a62a6429ea25ec Mon Sep 17 00:00:00 2001 From: foo86 Date: Mon, 9 Oct 2017 16:12:19 +0300 Subject: [PATCH 3297/3374] avcodec/dca_parser: revert to conservative sync distance estimation Fixes regression introduced by commit a0349ae27c127df8c72de1c30dc4090360ec7ef4 when parsing 14-bit streams with excessive frame size stored in header. Fixes ticket #6723. --- libavcodec/dca_parser.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/dca_parser.c b/libavcodec/dca_parser.c index 11ddb8f188237..80d665985e893 100644 --- a/libavcodec/dca_parser.c +++ b/libavcodec/dca_parser.c @@ -124,13 +124,13 @@ static int dca_find_frame_end(DCAParseContext *pc1, const uint8_t *buf, break; case DCA_SYNCWORD_CORE_14B_BE: if (size == 4) { - pc1->framesize = CORE_FRAMESIZE(STATE_14(state)) * 8 / 14 * 2; + pc1->framesize = CORE_FRAMESIZE(STATE_14(state)); start_found = 4; } break; case DCA_SYNCWORD_CORE_14B_LE: if (size == 4) { - pc1->framesize = CORE_FRAMESIZE(STATE_14(STATE_LE(state))) * 8 / 14 * 2; + pc1->framesize = CORE_FRAMESIZE(STATE_14(STATE_LE(state))); start_found = 4; } break; From 73789b85a759f3874112618120194e1712d7adcd Mon Sep 17 00:00:00 2001 From: foo86 Date: Mon, 9 Oct 2017 16:26:06 +0300 Subject: [PATCH 3298/3374] avcodec/dca_core: always limit frame size to data size Silences pointless error message when decoding DTS-in-WAV stream with excessive frame size stored in header. --- libavcodec/dca_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/dca_core.c b/libavcodec/dca_core.c index 6cb1f30a3c161..accc5efd51562 100644 --- a/libavcodec/dca_core.c +++ b/libavcodec/dca_core.c @@ -1816,7 +1816,7 @@ int ff_dca_core_parse(DCACoreDecoder *s, uint8_t *data, int size) return ret; // Workaround for DTS in WAV - if (s->frame_size > size && s->frame_size < size + 4) + if (s->frame_size > size) s->frame_size = size; if (ff_dca_seek_bits(&s->gb, s->frame_size * 8)) { From 1954e625b1d6bcb8de0fdc2c89f0a62f2fea7328 Mon Sep 17 00:00:00 2001 From: bnnm Date: Tue, 3 Oct 2017 23:49:00 +0200 Subject: [PATCH 3299/3374] avcodec/wmaprodec: support multichannel XMA stream configurations Signed-off-by: bnnm Now accepts any combination of 1/2ch streams, described in the RIFF chunks/extradata --- libavcodec/wmaprodec.c | 151 +++++++++++++++++++++++++++-------------- libavformat/wavdec.c | 20 ++++-- 2 files changed, 112 insertions(+), 59 deletions(-) diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index 5c99628c52d28..77a49c9db8c99 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -106,6 +106,9 @@ #define MAX_SUBFRAMES 32 ///< max number of subframes per channel #define MAX_BANDS 29 ///< max number of scale factor bands #define MAX_FRAMESIZE 32768 ///< maximum compressed frame size +#define XMA_MAX_STREAMS 8 +#define XMA_MAX_CHANNELS 8 +#define XMA_MAX_CHANNELS_STREAM 2 #define WMAPRO_BLOCK_MIN_BITS 6 ///< log2 of min block size #define WMAPRO_BLOCK_MAX_BITS 13 ///< log2 of max block size @@ -215,7 +218,7 @@ typedef struct WMAProDecodeCtx { uint8_t drc_gain; ///< gain for the DRC tool int8_t skip_frame; ///< skip output step int8_t parsed_all_subframes; ///< all subframes decoded? - uint8_t skip_packets; + uint8_t skip_packets; ///< packets to skip to find next packet in a stream (XMA1/2) /* subframe/block decode state */ int16_t subframe_len; ///< current subframe length @@ -235,11 +238,13 @@ typedef struct WMAProDecodeCtx { } WMAProDecodeCtx; typedef struct XMADecodeCtx { - WMAProDecodeCtx xma[4]; - AVFrame *frames[4]; + WMAProDecodeCtx xma[XMA_MAX_STREAMS]; + AVFrame *frames[XMA_MAX_STREAMS]; int current_stream; - float samples[8][512 * 64]; - int offset[4]; + int num_streams; + float samples[XMA_MAX_CHANNELS][512 * 64]; + int offset[XMA_MAX_STREAMS]; + int start_channel[XMA_MAX_STREAMS]; } XMADecodeCtx; /** @@ -306,7 +311,7 @@ static av_cold int get_rate(AVCodecContext *avctx) *@param avctx codec context *@return 0 on success, -1 otherwise */ -static av_cold int decode_init(WMAProDecodeCtx *s, AVCodecContext *avctx) +static av_cold int decode_init(WMAProDecodeCtx *s, AVCodecContext *avctx, int num_stream) { uint8_t *edata_ptr = avctx->extradata; unsigned int channel_mask; @@ -333,18 +338,30 @@ static av_cold int decode_init(WMAProDecodeCtx *s, AVCodecContext *avctx) for (i = 0; i < avctx->extradata_size; i++) av_log(avctx, AV_LOG_DEBUG, "[%x] ", avctx->extradata[i]); av_log(avctx, AV_LOG_DEBUG, "\n"); - if (avctx->codec_id == AV_CODEC_ID_XMA2 && (!avctx->extradata || avctx->extradata_size >= 6)) { + + if (avctx->codec_id == AV_CODEC_ID_XMA2 && avctx->extradata_size == 34) { /* XMA2WAVEFORMATEX */ + s->decode_flags = 0x10d6; + s->bits_per_sample = 16; + channel_mask = 0; //AV_RL32(edata_ptr+2); /* not always in expected order */ + if ((num_stream+1) * XMA_MAX_CHANNELS_STREAM > avctx->channels) /* stream config is 2ch + 2ch + ... + 1/2ch */ + s->nb_channels = 1; + else + s->nb_channels = 2; + } else if (avctx->codec_id == AV_CODEC_ID_XMA2) { /* XMA2WAVEFORMAT */ s->decode_flags = 0x10d6; - channel_mask = avctx->extradata ? AV_RL32(edata_ptr+2) : 0; s->bits_per_sample = 16; - } else if (avctx->codec_id == AV_CODEC_ID_XMA1) { + channel_mask = 0; /* would need to aggregate from all streams */ + s->nb_channels = edata_ptr[32 + ((edata_ptr[0]==3)?0:8) + 4*num_stream + 0]; /* nth stream config */ + } else if (avctx->codec_id == AV_CODEC_ID_XMA1) { /* XMAWAVEFORMAT */ s->decode_flags = 0x10d6; s->bits_per_sample = 16; - channel_mask = 0; - } else if (avctx->codec_id == AV_CODEC_ID_WMAPRO && avctx->extradata_size >= 18) { + channel_mask = 0; /* would need to aggregate from all streams */ + s->nb_channels = edata_ptr[8 + 20*num_stream + 17]; /* nth stream config */ + } else if (avctx->codec_id == AV_CODEC_ID_WMAPRO && avctx->extradata_size >= 18) { s->decode_flags = AV_RL16(edata_ptr+14); channel_mask = AV_RL32(edata_ptr+2); s->bits_per_sample = AV_RL16(edata_ptr); + s->nb_channels = avctx->channels; if (s->bits_per_sample > 32 || s->bits_per_sample < 1) { avpriv_request_sample(avctx, "bits per sample is %d", s->bits_per_sample); @@ -355,12 +372,6 @@ static av_cold int decode_init(WMAProDecodeCtx *s, AVCodecContext *avctx) return AVERROR_PATCHWELCOME; } - if (avctx->codec_id != AV_CODEC_ID_WMAPRO && avctx->channels > 2) { - s->nb_channels = 2; - } else { - s->nb_channels = avctx->channels; - } - /** generic init */ s->log2_frame_size = av_log2(avctx->block_align) + 4; if (s->log2_frame_size > 25) { @@ -421,6 +432,10 @@ static av_cold int decode_init(WMAProDecodeCtx *s, AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "invalid number of channels %d\n", s->nb_channels); return AVERROR_INVALIDDATA; + } else if (avctx->codec_id != AV_CODEC_ID_WMAPRO && s->nb_channels > XMA_MAX_CHANNELS_STREAM) { + av_log(avctx, AV_LOG_ERROR, "invalid number of channels per XMA stream %d\n", + s->nb_channels); + return AVERROR_INVALIDDATA; } else if (s->nb_channels > WMAPRO_MAX_CHANNELS) { avpriv_request_sample(avctx, "More than %d channels", WMAPRO_MAX_CHANNELS); @@ -566,7 +581,7 @@ static av_cold int wmapro_decode_init(AVCodecContext *avctx) { WMAProDecodeCtx *s = avctx->priv_data; - return decode_init(s, avctx); + return decode_init(s, avctx, 0); } /** @@ -1750,14 +1765,17 @@ static int xma_decode_packet(AVCodecContext *avctx, void *data, AVFrame *frame = data; int i, ret, offset = INT_MAX; + /* decode current stream packet */ ret = decode_packet(avctx, &s->xma[s->current_stream], s->frames[s->current_stream], &got_stream_frame_ptr, avpkt); + /* copy stream samples (1/2ch) to sample buffer (Nch) */ if (got_stream_frame_ptr) { - memcpy(&s->samples[s->current_stream * 2 + 0][s->offset[s->current_stream] * 512], + int start_ch = s->start_channel[s->current_stream]; + memcpy(&s->samples[start_ch + 0][s->offset[s->current_stream] * 512], s->frames[s->current_stream]->extended_data[0], 512 * 4); - if (avctx->channels > 1) - memcpy(&s->samples[s->current_stream * 2 + 1][s->offset[s->current_stream] * 512], + if (s->xma[s->current_stream].nb_channels > 1) + memcpy(&s->samples[start_ch + 1][s->offset[s->current_stream] * 512], s->frames[s->current_stream]->extended_data[1], 512 * 4); s->offset[s->current_stream]++; } else if (ret < 0) { @@ -1766,58 +1784,57 @@ static int xma_decode_packet(AVCodecContext *avctx, void *data, return ret; } + /* find next XMA packet's owner stream, and update. + * XMA streams find their packets following packet_skips + * (at start there is one packet per stream, then interleave non-linearly). */ if (s->xma[s->current_stream].packet_done || s->xma[s->current_stream].packet_loss) { - int bret; - - if (s->xma[s->current_stream].skip_packets == 0) { - ; - } else if (s->xma[0].skip_packets == 0 && avctx->channels >= 2) { - s->current_stream = 0; - } else if (s->xma[1].skip_packets == 0 && avctx->channels >= 4) { - s->current_stream = 1; - } else if (s->xma[2].skip_packets == 0 && avctx->channels >= 6) { - s->current_stream = 2; - } else if (s->xma[3].skip_packets == 0 && avctx->channels == 8) { - s->current_stream = 3; - } else { + + /* select stream with 0 skip_packets (= uses next packet) */ + if (s->xma[s->current_stream].skip_packets != 0) { int min[2]; min[0] = s->xma[0].skip_packets; min[1] = i = 0; - for (i = 1; i < avctx->channels / 2; i++) { + for (i = 1; i < s->num_streams; i++) { if (s->xma[i].skip_packets < min[0]) { - min[1] = i; min[0] = s->xma[i].skip_packets; + min[1] = i; } } s->current_stream = min[1]; } - for (i = 0; i < avctx->channels / 2; i++) { + /* all other streams skip next packet */ + for (i = 0; i < s->num_streams; i++) { s->xma[i].skip_packets = FFMAX(0, s->xma[i].skip_packets - 1); } - for (i = 0; i < (avctx->channels + 1) / 2; i++) { + /* copy samples from buffer to output if possible */ + for (i = 0; i < s->num_streams; i++) { offset = FFMIN(offset, s->offset[i]); } - if (offset > 0) { + int bret; + frame->nb_samples = 512 * offset; if ((bret = ff_get_buffer(avctx, frame, 0)) < 0) return bret; - for (i = 0; i < (avctx->channels + 1) / 2; i++) { - memcpy(frame->extended_data[i * 2 + 0], s->samples[i * 2 + 0], frame->nb_samples * 4); - if (avctx->channels > 1) - memcpy(frame->extended_data[i * 2 + 1], s->samples[i * 2 + 1], frame->nb_samples * 4); + /* copy samples buffer (Nch) to frame samples (Nch), move unconsumed samples */ + for (i = 0; i < s->num_streams; i++) { + int start_ch = s->start_channel[i]; + memcpy(frame->extended_data[start_ch + 0], s->samples[start_ch + 0], frame->nb_samples * 4); + if (s->xma[i].nb_channels > 1) + memcpy(frame->extended_data[start_ch + 1], s->samples[start_ch + 1], frame->nb_samples * 4); + s->offset[i] -= offset; if (s->offset[i]) { - memmove(s->samples[i * 2 + 0], s->samples[i * 2 + 0] + frame->nb_samples, s->offset[i] * 4 * 512); - if (avctx->channels > 1) - memmove(s->samples[i * 2 + 1], s->samples[i * 2 + 1] + frame->nb_samples, s->offset[i] * 4 * 512); + memmove(s->samples[start_ch + 0], s->samples[start_ch + 0] + frame->nb_samples, s->offset[i] * 4 * 512); + if (s->xma[i].nb_channels > 1) + memmove(s->samples[start_ch + 1], s->samples[start_ch + 1] + frame->nb_samples, s->offset[i] * 4 * 512); } } @@ -1831,13 +1848,40 @@ static int xma_decode_packet(AVCodecContext *avctx, void *data, static av_cold int xma_decode_init(AVCodecContext *avctx) { XMADecodeCtx *s = avctx->priv_data; - int i, ret; + int i, ret, start_channels = 0; - if (avctx->channels <= 0 || avctx->channels > 8) + if (avctx->channels <= 0 || avctx->extradata_size == 0) return AVERROR_INVALIDDATA; - for (i = 0; i < (avctx->channels + 1) / 2; i++) { - ret = decode_init(&s->xma[i], avctx); + /* get stream config */ + if (avctx->codec_id == AV_CODEC_ID_XMA2 && avctx->extradata_size == 34) { /* XMA2WAVEFORMATEX */ + s->num_streams = (avctx->channels + 1) / 2; + } else if (avctx->codec_id == AV_CODEC_ID_XMA2 && avctx->extradata_size >= 2) { /* XMA2WAVEFORMAT */ + s->num_streams = avctx->extradata[1]; + if (avctx->extradata_size != (32 + ((avctx->extradata[0]==3)?0:8) + 4*s->num_streams)) { + av_log(avctx, AV_LOG_ERROR, "Incorrect XMA2 extradata size\n"); + return AVERROR(EINVAL); + } + } else if (avctx->codec_id == AV_CODEC_ID_XMA1 && avctx->extradata_size >= 4) { /* XMAWAVEFORMAT */ + s->num_streams = avctx->extradata[4]; + if (avctx->extradata_size != (8 + 20*s->num_streams)) { + av_log(avctx, AV_LOG_ERROR, "Incorrect XMA1 extradata size\n"); + return AVERROR(EINVAL); + } + } else { + av_log(avctx, AV_LOG_ERROR, "Incorrect XMA config\n"); + return AVERROR(EINVAL); + } + + /* encoder supports up to 64 streams / 64*2 channels (would have to alloc arrays) */ + if (avctx->channels > XMA_MAX_CHANNELS || s->num_streams > XMA_MAX_STREAMS) { + avpriv_request_sample(avctx, "More than %d channels in %d streams", XMA_MAX_CHANNELS, s->num_streams); + return AVERROR_PATCHWELCOME; + } + + /* init all streams (several streams of 1/2ch make Nch files) */ + for (i = 0; i < s->num_streams; i++) { + ret = decode_init(&s->xma[i], avctx, i); if (ret < 0) return ret; s->frames[i] = av_frame_alloc(); @@ -1848,6 +1892,8 @@ static av_cold int xma_decode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); } + s->start_channel[i] = start_channels; + start_channels += s->xma[i].nb_channels; } return ret; @@ -1858,7 +1904,7 @@ static av_cold int xma_decode_end(AVCodecContext *avctx) XMADecodeCtx *s = avctx->priv_data; int i; - for (i = 0; i < avctx->channels / 2; i++) { + for (i = 0; i < s->num_streams; i++) { decode_end(&s->xma[i]); av_frame_free(&s->frames[i]); } @@ -1894,7 +1940,8 @@ static void xma_flush(AVCodecContext *avctx) { XMADecodeCtx *s = avctx->priv_data; int i; - for (i = 0; i < (avctx->channels + 1) / 2; i++) + + for (i = 0; i < s->num_streams; i++) flush(&s->xma[i]); memset(s->offset, 0, sizeof(s->offset)); diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c index 81dbc9f16e167..b016185a1b733 100644 --- a/libavformat/wavdec.c +++ b/libavformat/wavdec.c @@ -180,9 +180,9 @@ static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream **st) static int wav_parse_xma2_tag(AVFormatContext *s, int64_t size, AVStream **st) { AVIOContext *pb = s->pb; - int num_streams, i, channels = 0; + int version, num_streams, i, channels = 0; - if (size < 44) + if (size < 36) return AVERROR_INVALIDDATA; *st = avformat_new_stream(s, NULL); @@ -193,13 +193,17 @@ static int wav_parse_xma2_tag(AVFormatContext *s, int64_t size, AVStream **st) (*st)->codecpar->codec_id = AV_CODEC_ID_XMA2; (*st)->need_parsing = AVSTREAM_PARSE_FULL_RAW; - avio_skip(pb, 1); + version = avio_r8(pb); + if (version != 3 && version != 4) + return AVERROR_INVALIDDATA; num_streams = avio_r8(pb); - if (size < 40 + num_streams * 4) + if (size != (32 + ((version==3)?0:8) + 4*num_streams)) return AVERROR_INVALIDDATA; avio_skip(pb, 10); (*st)->codecpar->sample_rate = avio_rb32(pb); - avio_skip(pb, 12); + if (version == 4) + avio_skip(pb, 8); + avio_skip(pb, 4); (*st)->duration = avio_rb32(pb); avio_skip(pb, 8); @@ -213,9 +217,11 @@ static int wav_parse_xma2_tag(AVFormatContext *s, int64_t size, AVStream **st) return AVERROR_INVALIDDATA; avpriv_set_pts_info(*st, 64, 1, (*st)->codecpar->sample_rate); - if (ff_alloc_extradata((*st)->codecpar, 34)) + + avio_seek(pb, -size, SEEK_CUR); + av_freep(&(*st)->codecpar->extradata); + if (ff_get_extradata(s, (*st)->codecpar, pb, size) < 0) return AVERROR(ENOMEM); - memset((*st)->codecpar->extradata, 0, 34); return 0; } From 71e2ec017a1b51987d50b97d48b6a6114a58507d Mon Sep 17 00:00:00 2001 From: Jun Zhao Date: Mon, 9 Oct 2017 15:49:58 +0800 Subject: [PATCH 3300/3374] lavc: enable hwaccel_flags option Enable per-stream hwaccel_flags. Signed-off-by: Jun Zhao Signed-off-by: Mark Thompson --- libavcodec/options_table.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index 12712fb54192f..2ac37c3ff17e4 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -576,6 +576,10 @@ static const AVOption avcodec_options[] = { {"pixel_format", "set pixel format", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64=AV_PIX_FMT_NONE}, -1, INT_MAX, 0 }, {"video_size", "set video size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, {.str=NULL}, 0, INT_MAX, 0 }, {"max_pixels", "Maximum number of pixels", OFFSET(max_pixels), AV_OPT_TYPE_INT64, {.i64 = INT_MAX }, 0, INT_MAX, A|V|S|D|E }, +{"hwaccel_flags", NULL, OFFSET(hwaccel_flags), AV_OPT_TYPE_FLAGS, {.i64 = AV_HWACCEL_FLAG_IGNORE_LEVEL }, 0, UINT_MAX, V|D, "hwaccel_flags"}, +{"ignore_level", "ignore level even if the codec level used is unknown or higher than the maximum supported level reported by the hardware driver", 0, AV_OPT_TYPE_CONST, { .i64 = AV_HWACCEL_FLAG_IGNORE_LEVEL }, INT_MIN, INT_MAX, V | D, "hwaccel_flags" }, +{"allow_high_depth", "allow to output YUV pixel formats with a different chroma sampling than 4:2:0 and/or other than 8 bits per component", 0, AV_OPT_TYPE_CONST, {.i64 = AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH }, INT_MIN, INT_MAX, V | D, "hwaccel_flags"}, +{"allow_profile_mismatch", "attempt to decode anyway if HW accelerated decoder's supported profiles do not exactly match the stream", 0, AV_OPT_TYPE_CONST, {.i64 = AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH }, INT_MIN, INT_MAX, V | D, "hwaccel_flags"}, {NULL}, }; From 217a723b4e0573129c4ec9c31ca3ee666a2a64f6 Mon Sep 17 00:00:00 2001 From: Jun Zhao Date: Mon, 9 Oct 2017 15:50:19 +0800 Subject: [PATCH 3301/3374] lavc/vaapi_decode: fix profile search when profile mismatch is allowed When profile mismatch is allowed, use the highest supported profile for VAAPI decoding. Signed-off-by: Jun Zhao Signed-off-by: Mark Thompson --- libavcodec/vaapi_decode.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c index 5a555b2bd3ed9..27ef33837c18e 100644 --- a/libavcodec/vaapi_decode.c +++ b/libavcodec/vaapi_decode.c @@ -281,7 +281,7 @@ static int vaapi_decode_make_config(AVCodecContext *avctx) VAStatus vas; int err, i, j; const AVCodecDescriptor *codec_desc; - VAProfile profile, *profile_list = NULL; + VAProfile profile, va_profile, *profile_list = NULL; int profile_count, exact_match, alt_profile; const AVPixFmtDescriptor *sw_desc, *desc; @@ -328,6 +328,7 @@ static int vaapi_decode_make_config(AVCodecContext *avctx) if (exact_match) break; alt_profile = vaapi_profile_map[i].codec_profile; + va_profile = vaapi_profile_map[i].va_profile; } } av_freep(&profile_list); @@ -347,6 +348,7 @@ static int vaapi_decode_make_config(AVCodecContext *avctx) av_log(avctx, AV_LOG_WARNING, "Using possibly-" "incompatible profile %d instead.\n", alt_profile); + profile = va_profile; } else { av_log(avctx, AV_LOG_VERBOSE, "Codec %s profile %d not " "supported for hardware decode.\n", From fde3bb16f90ac456709c7305b9e230e8327d8625 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sun, 8 Oct 2017 16:54:18 -0300 Subject: [PATCH 3302/3374] build: prevent SDL2 from polluting global cflags and extralibs Remove the SDL_main define from the global cflags but not from the ffplay cflags, and the -mwindows linker option from extralibs instead of overriding it with the addition of -mconsole. Reviewed-by: wm4 Signed-off-by: James Almer --- configure | 4 ++-- ffbuild/library.mak | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/configure b/configure index fc377d90fbd68..1e2721b134bfc 100755 --- a/configure +++ b/configure @@ -6108,10 +6108,10 @@ if enabled sdl2; then enable sdl2 fi if test $target_os = "mingw32"; then - sdl2_extralibs="$sdl2_extralibs -mconsole" + sdl2_extralibs=$(filter_out '-mwindows' $sdl2_extralibs) fi fi -enabled sdl2 && add_cflags $sdl2_cflags && add_extralibs $sdl2_extralibs +enabled sdl2 && add_cflags $(filter_out '-Dmain=SDL_main' $sdl2_cflags) && add_extralibs $sdl2_extralibs if enabled decklink; then case $target_os in diff --git a/ffbuild/library.mak b/ffbuild/library.mak index ee19c3c797c78..4191edcf9ca9b 100644 --- a/ffbuild/library.mak +++ b/ffbuild/library.mak @@ -16,7 +16,6 @@ all-$(CONFIG_SHARED): $(SUBDIR)$(SLIBNAME) $(SUBDIR)lib$(FULLNAME).pc LIBOBJS := $(OBJS) $(SUBDIR)%.h.o $(TESTOBJS) $(LIBOBJS) $(LIBOBJS:.o=.s) $(LIBOBJS:.o=.i): CPPFLAGS += -DHAVE_AV_CONFIG_H -$(TESTOBJS) $(TESTOBJS:.o=.i): CFLAGS += -Umain $(SUBDIR)$(LIBNAME): $(OBJS) $(RM) $@ From 17ba9e123f1e66fad92f0ff6bd7aaa7ddfac7ff4 Mon Sep 17 00:00:00 2001 From: James Almer Date: Mon, 9 Oct 2017 22:45:36 -0300 Subject: [PATCH 3303/3374] fate: update fate-api reference files after 71e2ec017a Signed-off-by: James Almer --- tests/ref/fate/api-mjpeg-codec-param | 2 ++ tests/ref/fate/api-png-codec-param | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/ref/fate/api-mjpeg-codec-param b/tests/ref/fate/api-mjpeg-codec-param index 6a5d4d3926fae..02f656df25a0d 100644 --- a/tests/ref/fate/api-mjpeg-codec-param +++ b/tests/ref/fate/api-mjpeg-codec-param @@ -157,6 +157,7 @@ stream=0, decode=0 pixel_format=yuvj422p video_size=400x225 max_pixels=2147483647 + hwaccel_flags=0x00000001 stream=0, decode=1 b=0 ab=0 @@ -316,3 +317,4 @@ stream=0, decode=1 pixel_format=yuvj422p video_size=400x225 max_pixels=2147483647 + hwaccel_flags=0x00000001 diff --git a/tests/ref/fate/api-png-codec-param b/tests/ref/fate/api-png-codec-param index c51957e1d29ab..de86f1b25d92c 100644 --- a/tests/ref/fate/api-png-codec-param +++ b/tests/ref/fate/api-png-codec-param @@ -157,6 +157,7 @@ stream=0, decode=0 pixel_format=rgba video_size=128x128 max_pixels=2147483647 + hwaccel_flags=0x00000001 stream=0, decode=1 b=0 ab=0 @@ -316,3 +317,4 @@ stream=0, decode=1 pixel_format=rgba video_size=128x128 max_pixels=2147483647 + hwaccel_flags=0x00000001 From ff6de6b180fd7c931410f81fb404ab3dbf30d40b Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Fri, 6 Oct 2017 22:15:35 +0200 Subject: [PATCH 3304/3374] Makefile: generate stripped CLI tools directly instead of copying unstripped ones first Now works with --disable-stripping. Signed-off-by: Marton Balint --- Makefile | 4 ++++ configure | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/Makefile b/Makefile index 4a1253a052ec5..642651d4ccda5 100644 --- a/Makefile +++ b/Makefile @@ -97,8 +97,12 @@ include $(SRC_PATH)/doc/examples/Makefile libavcodec/utils.o libavformat/utils.o libavdevice/avdevice.o libavfilter/avfilter.o libavutil/utils.o libpostproc/postprocess.o libswresample/swresample.o libswscale/utils.o : libavutil/ffversion.h $(PROGS): %$(PROGSSUF)$(EXESUF): %$(PROGSSUF)_g$(EXESUF) +ifeq ($(STRIPTYPE),direct) + $(STRIP) -o $@ $< +else $(CP) $< $@ $(STRIP) $@ +endif %$(PROGSSUF)_g$(EXESUF): $(FF_DEP_LIBS) $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $(OBJS-$*) $(FF_EXTRALIBS) diff --git a/configure b/configure index 1e2721b134bfc..e9e1a4dff3b2c 100755 --- a/configure +++ b/configure @@ -3363,6 +3363,7 @@ x86asmexe_default="nasm" windres_default="windres" nvcc_default="nvcc" nvccflags_default="-gencode arch=compute_30,code=sm_30 -O2" +striptype="direct" # OS target_os_default=$(tolower $(uname -s)) @@ -5089,6 +5090,7 @@ case $target_os in ;; os/2*) strip="lxlite -CS" + striptype="" objformat="aout" add_cppflags -D_GNU_SOURCE add_ldflags -Zomf -Zbin-files -Zargs-wild -Zhigh-mem -Zmap @@ -6834,6 +6836,7 @@ fi # test "$quiet" != "yes" test -e Makefile || echo "include $source_path/Makefile" > Makefile enabled stripping || strip="echo skipping strip" +enabled stripping || striptype="" config_files="$TMPH ffbuild/config.mak doc/config.texi" @@ -6877,6 +6880,7 @@ ARFLAGS=$arflags AR_O=$ar_o RANLIB=$ranlib STRIP=$strip +STRIPTYPE=$striptype NVCC=$nvcc CP=cp -p LN_S=$ln_s From 278588cd0bf788df0194f74e62745f68559616f9 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Fri, 6 Oct 2017 08:55:43 -0400 Subject: [PATCH 3305/3374] libavdevice/decklink: add support for -sources and -sinks arguments Add support for enumerating the sources/sinks via the ffmpeg command line options, as opposed to having to create a real pipeline and use the "-list_devices" option which does exit() after dumping out the options. Note that this patch preserves the existing "-list_devices" option, but now shares common code for the actual enumeration. Updated to reflect feedback from Marton Balint . Signed-off-by: Devin Heitmueller Signed-off-by: Marton Balint --- libavdevice/decklink_common.cpp | 89 ++++++++++++++++++++++++++++++--- libavdevice/decklink_common.h | 3 +- libavdevice/decklink_dec.cpp | 8 ++- libavdevice/decklink_dec.h | 1 + libavdevice/decklink_dec_c.c | 1 + libavdevice/decklink_enc.cpp | 10 +++- libavdevice/decklink_enc.h | 1 + libavdevice/decklink_enc_c.c | 1 + 8 files changed, 104 insertions(+), 10 deletions(-) diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp index c782171f2c321..2bd63ac820c75 100644 --- a/libavdevice/decklink_common.cpp +++ b/libavdevice/decklink_common.cpp @@ -37,6 +37,7 @@ extern "C" { #include "libavutil/imgutils.h" #include "libavutil/intreadwrite.h" #include "libavutil/bswap.h" +#include "avdevice.h" } #include "decklink_common.h" @@ -261,24 +262,100 @@ int ff_decklink_set_format(AVFormatContext *avctx, decklink_direction_t directio return ff_decklink_set_format(avctx, 0, 0, 0, 0, AV_FIELD_UNKNOWN, direction, num); } -int ff_decklink_list_devices(AVFormatContext *avctx) +int ff_decklink_list_devices(AVFormatContext *avctx, + struct AVDeviceInfoList *device_list, + int show_inputs, int show_outputs) { IDeckLink *dl = NULL; IDeckLinkIterator *iter = CreateDeckLinkIteratorInstance(); + int ret = 0; + if (!iter) { av_log(avctx, AV_LOG_ERROR, "Could not create DeckLink iterator\n"); return AVERROR(EIO); } - av_log(avctx, AV_LOG_INFO, "Blackmagic DeckLink devices:\n"); - while (iter->Next(&dl) == S_OK) { + + while (ret == 0 && iter->Next(&dl) == S_OK) { + IDeckLinkOutput *output_config; + IDeckLinkInput *input_config; const char *displayName; + AVDeviceInfo *new_device = NULL; + int add = 0; + ff_decklink_get_display_name(dl, &displayName); - av_log(avctx, AV_LOG_INFO, "\t'%s'\n", displayName); - av_free((void *) displayName); + + if (show_outputs) { + if (dl->QueryInterface(IID_IDeckLinkOutput, (void **)&output_config) == S_OK) { + output_config->Release(); + add = 1; + } + } + + if (show_inputs) { + if (dl->QueryInterface(IID_IDeckLinkInput, (void **)&input_config) == S_OK) { + input_config->Release(); + add = 1; + } + } + + if (add == 1) { + new_device = (AVDeviceInfo *) av_mallocz(sizeof(AVDeviceInfo)); + if (!new_device) { + ret = AVERROR(ENOMEM); + goto next; + } + new_device->device_name = av_strdup(displayName); + if (!new_device->device_name) { + ret = AVERROR(ENOMEM); + goto next; + } + + new_device->device_description = av_strdup(displayName); + if (!new_device->device_description) { + av_freep(&new_device->device_name); + ret = AVERROR(ENOMEM); + goto next; + } + + if ((ret = av_dynarray_add_nofree(&device_list->devices, + &device_list->nb_devices, new_device)) < 0) { + av_freep(&new_device->device_name); + av_freep(&new_device->device_description); + av_freep(&new_device); + goto next; + } + } + + next: + av_freep(&displayName); dl->Release(); } iter->Release(); - return 0; + return ret; +} + +/* This is a wrapper around the ff_decklink_list_devices() which dumps the + output to av_log() and exits (for backward compatibility with the + "-list_devices" argument). */ +void ff_decklink_list_devices_legacy(AVFormatContext *avctx, + int show_inputs, int show_outputs) +{ + struct AVDeviceInfoList *device_list = NULL; + int ret; + + device_list = (struct AVDeviceInfoList *) av_mallocz(sizeof(AVDeviceInfoList)); + if (!device_list) + return; + + ret = ff_decklink_list_devices(avctx, device_list, show_inputs, show_outputs); + if (ret == 0) { + av_log(avctx, AV_LOG_INFO, "Blackmagic DeckLink %s devices:\n", + show_inputs ? "input" : "output"); + for (int i = 0; i < device_list->nb_devices; i++) { + av_log(avctx, AV_LOG_INFO, "\t'%s'\n", device_list->devices[i]->device_name); + } + } + avdevice_free_list_devices(&device_list); } int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direction) diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h index 749eb0f8b8e59..6b2525fb53691 100644 --- a/libavdevice/decklink_common.h +++ b/libavdevice/decklink_common.h @@ -135,7 +135,8 @@ static const BMDVideoConnection decklink_video_connection_map[] = { HRESULT ff_decklink_get_display_name(IDeckLink *This, const char **displayName); int ff_decklink_set_format(AVFormatContext *avctx, int width, int height, int tb_num, int tb_den, enum AVFieldOrder field_order, decklink_direction_t direction = DIRECTION_OUT, int num = 0); int ff_decklink_set_format(AVFormatContext *avctx, decklink_direction_t direction, int num); -int ff_decklink_list_devices(AVFormatContext *avctx); +int ff_decklink_list_devices(AVFormatContext *avctx, struct AVDeviceInfoList *device_list, int show_inputs, int show_outputs); +void ff_decklink_list_devices_legacy(AVFormatContext *avctx, int show_inputs, int show_outputs); int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direction = DIRECTION_OUT); void ff_decklink_cleanup(AVFormatContext *avctx); int ff_decklink_init_device(AVFormatContext *avctx, const char* name); diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index 6f796e4941cae..d9ac01ac91bd1 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -39,6 +39,7 @@ extern "C" { #include "libavutil/time.h" #include "libavutil/mathematics.h" #include "libavutil/reverse.h" +#include "avdevice.h" #if CONFIG_LIBZVBI #include #endif @@ -868,7 +869,7 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) /* List available devices. */ if (ctx->list_devices) { - ff_decklink_list_devices(avctx); + ff_decklink_list_devices_legacy(avctx, 1, 0); return AVERROR_EXIT; } @@ -1063,4 +1064,9 @@ int ff_decklink_read_packet(AVFormatContext *avctx, AVPacket *pkt) return 0; } +int ff_decklink_list_input_devices(AVFormatContext *avctx, struct AVDeviceInfoList *device_list) +{ + return ff_decklink_list_devices(avctx, device_list, 1, 0); +} + } /* extern "C" */ diff --git a/libavdevice/decklink_dec.h b/libavdevice/decklink_dec.h index 9b71870deb75c..fbfbe6280e561 100644 --- a/libavdevice/decklink_dec.h +++ b/libavdevice/decklink_dec.h @@ -29,6 +29,7 @@ extern "C" { int ff_decklink_read_header(AVFormatContext *avctx); int ff_decklink_read_packet(AVFormatContext *avctx, AVPacket *pkt); int ff_decklink_read_close(AVFormatContext *avctx); +int ff_decklink_list_input_devices(AVFormatContext *avctx, struct AVDeviceInfoList *device_list); #ifdef __cplusplus } /* extern "C" */ diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c index 8b6ff067bc9fd..1127d23adaafd 100644 --- a/libavdevice/decklink_dec_c.c +++ b/libavdevice/decklink_dec_c.c @@ -89,6 +89,7 @@ AVInputFormat ff_decklink_demuxer = { .flags = AVFMT_NOFILE, .priv_class = &decklink_demuxer_class, .priv_data_size = sizeof(struct decklink_cctx), + .get_device_list = ff_decklink_list_input_devices, .read_header = ff_decklink_read_header, .read_packet = ff_decklink_read_packet, .read_close = ff_decklink_read_close, diff --git a/libavdevice/decklink_enc.cpp b/libavdevice/decklink_enc.cpp index 25ce7d026c2c1..0776741812ef1 100644 --- a/libavdevice/decklink_enc.cpp +++ b/libavdevice/decklink_enc.cpp @@ -33,6 +33,7 @@ extern "C" { extern "C" { #include "libavformat/avformat.h" #include "libavutil/imgutils.h" +#include "avdevice.h" } #include "decklink_common.h" @@ -335,9 +336,9 @@ av_cold int ff_decklink_write_header(AVFormatContext *avctx) ctx->preroll = cctx->preroll; cctx->ctx = ctx; - /* List available devices. */ + /* List available devices and exit. */ if (ctx->list_devices) { - ff_decklink_list_devices(avctx); + ff_decklink_list_devices_legacy(avctx, 0, 1); return AVERROR_EXIT; } @@ -400,4 +401,9 @@ int ff_decklink_write_packet(AVFormatContext *avctx, AVPacket *pkt) return AVERROR(EIO); } +int ff_decklink_list_output_devices(AVFormatContext *avctx, struct AVDeviceInfoList *device_list) +{ + return ff_decklink_list_devices(avctx, device_list, 0, 1); +} + } /* extern "C" */ diff --git a/libavdevice/decklink_enc.h b/libavdevice/decklink_enc.h index 5ffc05cd686f8..39237673b4d59 100644 --- a/libavdevice/decklink_enc.h +++ b/libavdevice/decklink_enc.h @@ -29,6 +29,7 @@ extern "C" { int ff_decklink_write_header(AVFormatContext *avctx); int ff_decklink_write_packet(AVFormatContext *avctx, AVPacket *pkt); int ff_decklink_write_trailer(AVFormatContext *avctx); +int ff_decklink_list_output_devices(AVFormatContext *avctx, struct AVDeviceInfoList *device_list); #ifdef __cplusplus } /* extern "C" */ diff --git a/libavdevice/decklink_enc_c.c b/libavdevice/decklink_enc_c.c index 03734f8507b46..360535cfdaaf1 100644 --- a/libavdevice/decklink_enc_c.c +++ b/libavdevice/decklink_enc_c.c @@ -49,6 +49,7 @@ AVOutputFormat ff_decklink_muxer = { .video_codec = AV_CODEC_ID_WRAPPED_AVFRAME, .subtitle_codec = AV_CODEC_ID_NONE, .flags = AVFMT_NOFILE, + .get_device_list = ff_decklink_list_output_devices, .priv_class = &decklink_muxer_class, .priv_data_size = sizeof(struct decklink_cctx), .write_header = ff_decklink_write_header, From 77f7d710e08635407b3bda2a1505040709ef2a3c Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Fri, 6 Oct 2017 08:55:44 -0400 Subject: [PATCH 3306/3374] libavdevice/decklink: add support for 10-bit output for Decklink SDI Can be tested via the following command: ./ffmpeg -i foo.ts -f decklink -vcodec v210 'DeckLink Duo (1)' Note that the 8-bit support works as it did before, and setting the pix_fmt isn't required for 10-bit mode. The code defaults to operating in 8-bit mode when no vcodec is specified, for backward compatibility. Updated to reflect feedback from Marton Balint Signed-off-by: Devin Heitmueller Signed-off-by: Marton Balint --- libavdevice/decklink_enc.cpp | 112 ++++++++++++++++++++++++++--------- 1 file changed, 83 insertions(+), 29 deletions(-) diff --git a/libavdevice/decklink_enc.cpp b/libavdevice/decklink_enc.cpp index 0776741812ef1..81df563b3bf66 100644 --- a/libavdevice/decklink_enc.cpp +++ b/libavdevice/decklink_enc.cpp @@ -44,20 +44,45 @@ extern "C" { class decklink_frame : public IDeckLinkVideoFrame { public: - decklink_frame(struct decklink_ctx *ctx, AVFrame *avframe) : - _ctx(ctx), _avframe(avframe), _refs(1) { } - - virtual long STDMETHODCALLTYPE GetWidth (void) { return _avframe->width; } - virtual long STDMETHODCALLTYPE GetHeight (void) { return _avframe->height; } - virtual long STDMETHODCALLTYPE GetRowBytes (void) { return _avframe->linesize[0] < 0 ? -_avframe->linesize[0] : _avframe->linesize[0]; } - virtual BMDPixelFormat STDMETHODCALLTYPE GetPixelFormat(void) { return bmdFormat8BitYUV; } - virtual BMDFrameFlags STDMETHODCALLTYPE GetFlags (void) { return _avframe->linesize[0] < 0 ? bmdFrameFlagFlipVertical : bmdFrameFlagDefault; } - virtual HRESULT STDMETHODCALLTYPE GetBytes (void **buffer) + decklink_frame(struct decklink_ctx *ctx, AVFrame *avframe, AVCodecID codec_id, int height, int width) : + _ctx(ctx), _avframe(avframe), _avpacket(NULL), _codec_id(codec_id), _height(height), _width(width), _refs(1) { } + decklink_frame(struct decklink_ctx *ctx, AVPacket *avpacket, AVCodecID codec_id, int height, int width) : + _ctx(ctx), _avframe(NULL), _avpacket(avpacket), _codec_id(codec_id), _height(height), _width(width), _refs(1) { } + + virtual long STDMETHODCALLTYPE GetWidth (void) { return _width; } + virtual long STDMETHODCALLTYPE GetHeight (void) { return _height; } + virtual long STDMETHODCALLTYPE GetRowBytes (void) + { + if (_codec_id == AV_CODEC_ID_WRAPPED_AVFRAME) + return _avframe->linesize[0] < 0 ? -_avframe->linesize[0] : _avframe->linesize[0]; + else + return ((GetWidth() + 47) / 48) * 128; + } + virtual BMDPixelFormat STDMETHODCALLTYPE GetPixelFormat(void) { - if (_avframe->linesize[0] < 0) - *buffer = (void *)(_avframe->data[0] + _avframe->linesize[0] * (_avframe->height - 1)); + if (_codec_id == AV_CODEC_ID_WRAPPED_AVFRAME) + return bmdFormat8BitYUV; else - *buffer = (void *)(_avframe->data[0]); + return bmdFormat10BitYUV; + } + virtual BMDFrameFlags STDMETHODCALLTYPE GetFlags (void) + { + if (_codec_id == AV_CODEC_ID_WRAPPED_AVFRAME) + return _avframe->linesize[0] < 0 ? bmdFrameFlagFlipVertical : bmdFrameFlagDefault; + else + return bmdFrameFlagDefault; + } + + virtual HRESULT STDMETHODCALLTYPE GetBytes (void **buffer) + { + if (_codec_id == AV_CODEC_ID_WRAPPED_AVFRAME) { + if (_avframe->linesize[0] < 0) + *buffer = (void *)(_avframe->data[0] + _avframe->linesize[0] * (_avframe->height - 1)); + else + *buffer = (void *)(_avframe->data[0]); + } else { + *buffer = (void *)(_avpacket->data); + } return S_OK; } @@ -71,6 +96,7 @@ class decklink_frame : public IDeckLinkVideoFrame int ret = --_refs; if (!ret) { av_frame_free(&_avframe); + av_packet_free(&_avpacket); delete this; } return ret; @@ -78,6 +104,10 @@ class decklink_frame : public IDeckLinkVideoFrame struct decklink_ctx *_ctx; AVFrame *_avframe; + AVPacket *_avpacket; + AVCodecID _codec_id; + int _height; + int _width; private: std::atomic _refs; @@ -90,9 +120,11 @@ class decklink_output_callback : public IDeckLinkVideoOutputCallback { decklink_frame *frame = static_cast(_frame); struct decklink_ctx *ctx = frame->_ctx; - AVFrame *avframe = frame->_avframe; - av_frame_unref(avframe); + if (frame->_avframe) + av_frame_unref(frame->_avframe); + if (frame->_avpacket) + av_packet_unref(frame->_avpacket); pthread_mutex_lock(&ctx->mutex); ctx->frames_buffer_available_spots++; @@ -118,11 +150,18 @@ static int decklink_setup_video(AVFormatContext *avctx, AVStream *st) return -1; } - if (c->format != AV_PIX_FMT_UYVY422) { - av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format!" - " Only AV_PIX_FMT_UYVY422 is supported.\n"); + if (c->codec_id == AV_CODEC_ID_WRAPPED_AVFRAME) { + if (c->format != AV_PIX_FMT_UYVY422) { + av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format!" + " Only AV_PIX_FMT_UYVY422 is supported.\n"); + return -1; + } + } else if (c->codec_id != AV_CODEC_ID_V210) { + av_log(avctx, AV_LOG_ERROR, "Unsupported codec type!" + " Only V210 and wrapped frame with AV_PIX_FMT_UYVY422 are supported.\n"); return -1; } + if (ff_decklink_set_format(avctx, c->width, c->height, st->time_base.num, st->time_base.den, c->field_order)) { av_log(avctx, AV_LOG_ERROR, "Unsupported video size, framerate or field order!" @@ -230,27 +269,42 @@ static int decklink_write_video_packet(AVFormatContext *avctx, AVPacket *pkt) { struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data; struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; - AVFrame *avframe, *tmp = (AVFrame *)pkt->data; + AVStream *st = avctx->streams[pkt->stream_index]; + AVFrame *avframe = NULL, *tmp = (AVFrame *)pkt->data; + AVPacket *avpacket = NULL; decklink_frame *frame; buffercount_type buffered; HRESULT hr; - if (tmp->format != AV_PIX_FMT_UYVY422 || - tmp->width != ctx->bmd_width || - tmp->height != ctx->bmd_height) { - av_log(avctx, AV_LOG_ERROR, "Got a frame with invalid pixel format or dimension.\n"); - return AVERROR(EINVAL); - } - avframe = av_frame_clone(tmp); - if (!avframe) { - av_log(avctx, AV_LOG_ERROR, "Could not clone video frame.\n"); - return AVERROR(EIO); + if (st->codecpar->codec_id == AV_CODEC_ID_WRAPPED_AVFRAME) { + if (tmp->format != AV_PIX_FMT_UYVY422 || + tmp->width != ctx->bmd_width || + tmp->height != ctx->bmd_height) { + av_log(avctx, AV_LOG_ERROR, "Got a frame with invalid pixel format or dimension.\n"); + return AVERROR(EINVAL); + } + + avframe = av_frame_clone(tmp); + if (!avframe) { + av_log(avctx, AV_LOG_ERROR, "Could not clone video frame.\n"); + return AVERROR(EIO); + } + + frame = new decklink_frame(ctx, avframe, st->codecpar->codec_id, avframe->height, avframe->width); + } else { + avpacket = av_packet_clone(pkt); + if (!avpacket) { + av_log(avctx, AV_LOG_ERROR, "Could not clone video frame.\n"); + return AVERROR(EIO); + } + + frame = new decklink_frame(ctx, avpacket, st->codecpar->codec_id, ctx->bmd_height, ctx->bmd_width); } - frame = new decklink_frame(ctx, avframe); if (!frame) { av_log(avctx, AV_LOG_ERROR, "Could not create new frame.\n"); av_frame_free(&avframe); + av_packet_free(&avpacket); return AVERROR(EIO); } From d251effe732081c2d11bdb1198ab906827faf773 Mon Sep 17 00:00:00 2001 From: Gyan Doshi Date: Tue, 10 Oct 2017 16:05:18 +0530 Subject: [PATCH 3307/3374] doc/filters: note minimum resolution for pixscope Signed-off-by: Gyan Doshi Signed-off-by: Derek Buitenhuis --- doc/filters.texi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/filters.texi b/doc/filters.texi index 57189c77b02e6..e26dde4b1a9f4 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -11711,7 +11711,8 @@ can be used to test the monowhite pixel format descriptor definition. @section pixscope -Display sample values of color channels. Mainly useful for checking color and levels. +Display sample values of color channels. Mainly useful for checking color +and levels. Minimum supported resolution is 640x480. The filters accept the following options: From f280575a0fc96a7b288032357f664dfb552dfe12 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Tue, 10 Oct 2017 20:20:28 +0200 Subject: [PATCH 3308/3374] configure: fix decklink dependencies We don't need libdl for win32/mingw. Reviewed-by: James Almer Signed-off-by: Marton Balint --- configure | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/configure b/configure index e9e1a4dff3b2c..e2ef54fb3b213 100755 --- a/configure +++ b/configure @@ -3084,9 +3084,10 @@ avfoundation_indev_deps="avfoundation pthreads" avfoundation_indev_extralibs="-framework Foundation -framework CoreVideo -framework CoreMedia" bktr_indev_deps_any="dev_bktr_ioctl_bt848_h machine_ioctl_bt848_h dev_video_bktr_ioctl_bt848_h dev_ic_bt8xx_h" caca_outdev_deps="libcaca" -decklink_indev_deps="decklink threads libdl" +decklink_deps_any="libdl LoadLibrary" +decklink_indev_deps="decklink threads" decklink_indev_extralibs="-lstdc++" -decklink_outdev_deps="decklink threads libdl" +decklink_outdev_deps="decklink threads" decklink_outdev_extralibs="-lstdc++" libndi_newtek_indev_deps="libndi_newtek libdl" libndi_newtek_indev_extralibs="-lndi" From e38f280fece38e270a6462a02cc034f4116a7912 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 8 Oct 2017 21:41:54 +0200 Subject: [PATCH 3309/3374] avcodec/mpeg4videodec: Use 64 bit intermediates for sprite delta Fixes: runtime error: signed integer overflow: -104713 * 65536 cannot be represented in type 'int' Fixes: 3453/clusterfuzz-testcase-minimized-5555554657239040 Fixes: 3528/clusterfuzz-testcase-minimized-6283628420005888 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/mpeg4videodec.c | 79 +++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index 8f85e9362dd96..cd39131d55e92 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -179,6 +179,7 @@ static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *g int sprite_ref[4][2]; int virtual_ref[2][2]; int64_t sprite_offset[2][2]; + int64_t sprite_delta[2][2]; // only true for rectangle shapes const int vop_ref[4][2] = { { 0, 0 }, { s->width, 0 }, @@ -262,10 +263,10 @@ static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *g sprite_offset[0][1] = sprite_offset[1][0] = sprite_offset[1][1] = 0; - s->sprite_delta[0][0] = a; - s->sprite_delta[0][1] = - s->sprite_delta[1][0] = 0; - s->sprite_delta[1][1] = a; + sprite_delta[0][0] = a; + sprite_delta[0][1] = + sprite_delta[1][0] = 0; + sprite_delta[1][1] = a; ctx->sprite_shift[0] = ctx->sprite_shift[1] = 0; break; @@ -276,10 +277,10 @@ static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *g a * (vop_ref[0][0] / 2); sprite_offset[1][1] = ((sprite_ref[0][1] >> 1) | (sprite_ref[0][1] & 1)) - a * (vop_ref[0][1] / 2); - s->sprite_delta[0][0] = a; - s->sprite_delta[0][1] = - s->sprite_delta[1][0] = 0; - s->sprite_delta[1][1] = a; + sprite_delta[0][0] = a; + sprite_delta[0][1] = + sprite_delta[1][0] = 0; + sprite_delta[1][1] = a; ctx->sprite_shift[0] = ctx->sprite_shift[1] = 0; break; @@ -304,10 +305,10 @@ static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *g ((int64_t)-r * sprite_ref[0][0] + virtual_ref[0][0]) * ((int64_t)-2 * vop_ref[0][1] + 1) + 2 * w2 * r * (int64_t) sprite_ref[0][1] - 16 * w2 + (1 << (alpha + rho + 1))); - s->sprite_delta[0][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]); - s->sprite_delta[0][1] = (+r * sprite_ref[0][1] - virtual_ref[0][1]); - s->sprite_delta[1][0] = (-r * sprite_ref[0][1] + virtual_ref[0][1]); - s->sprite_delta[1][1] = (-r * sprite_ref[0][0] + virtual_ref[0][0]); + sprite_delta[0][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]); + sprite_delta[0][1] = (+r * sprite_ref[0][1] - virtual_ref[0][1]); + sprite_delta[1][0] = (-r * sprite_ref[0][1] + virtual_ref[0][1]); + sprite_delta[1][1] = (-r * sprite_ref[0][0] + virtual_ref[0][0]); ctx->sprite_shift[0] = alpha + rho; ctx->sprite_shift[1] = alpha + rho + 2; @@ -332,28 +333,28 @@ static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *g ((int64_t)-r * sprite_ref[0][1] + virtual_ref[1][1]) * w3 * (-2 * vop_ref[0][1] + 1) + (int64_t)2 * w2 * h3 * r * sprite_ref[0][1] - 16 * w2 * h3 + ((int64_t)1 << (alpha + beta + rho - min_ab + 1)); - s->sprite_delta[0][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]) * h3; - s->sprite_delta[0][1] = (-r * sprite_ref[0][0] + virtual_ref[1][0]) * w3; - s->sprite_delta[1][0] = (-r * sprite_ref[0][1] + virtual_ref[0][1]) * h3; - s->sprite_delta[1][1] = (-r * sprite_ref[0][1] + virtual_ref[1][1]) * w3; + sprite_delta[0][0] = (-r * (int64_t)sprite_ref[0][0] + virtual_ref[0][0]) * h3; + sprite_delta[0][1] = (-r * (int64_t)sprite_ref[0][0] + virtual_ref[1][0]) * w3; + sprite_delta[1][0] = (-r * (int64_t)sprite_ref[0][1] + virtual_ref[0][1]) * h3; + sprite_delta[1][1] = (-r * (int64_t)sprite_ref[0][1] + virtual_ref[1][1]) * w3; ctx->sprite_shift[0] = alpha + beta + rho - min_ab; ctx->sprite_shift[1] = alpha + beta + rho - min_ab + 2; break; } /* try to simplify the situation */ - if (s->sprite_delta[0][0] == a << ctx->sprite_shift[0] && - s->sprite_delta[0][1] == 0 && - s->sprite_delta[1][0] == 0 && - s->sprite_delta[1][1] == a << ctx->sprite_shift[0]) { + if (sprite_delta[0][0] == a << ctx->sprite_shift[0] && + sprite_delta[0][1] == 0 && + sprite_delta[1][0] == 0 && + sprite_delta[1][1] == a << ctx->sprite_shift[0]) { sprite_offset[0][0] >>= ctx->sprite_shift[0]; sprite_offset[0][1] >>= ctx->sprite_shift[0]; sprite_offset[1][0] >>= ctx->sprite_shift[1]; sprite_offset[1][1] >>= ctx->sprite_shift[1]; - s->sprite_delta[0][0] = a; - s->sprite_delta[0][1] = 0; - s->sprite_delta[1][0] = 0; - s->sprite_delta[1][1] = a; + sprite_delta[0][0] = a; + sprite_delta[0][1] = 0; + sprite_delta[1][0] = 0; + sprite_delta[1][1] = a; ctx->sprite_shift[0] = 0; ctx->sprite_shift[1] = 0; s->real_sprite_warping_points = 1; @@ -365,8 +366,8 @@ static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *g if (shift_c < 0 || shift_y < 0 || FFABS( sprite_offset[0][i]) >= INT_MAX >> shift_y || FFABS( sprite_offset[1][i]) >= INT_MAX >> shift_c || - FFABS(s->sprite_delta[0][i]) >= INT_MAX >> shift_y || - FFABS(s->sprite_delta[1][i]) >= INT_MAX >> shift_y + FFABS( sprite_delta[0][i]) >= INT_MAX >> shift_y || + FFABS( sprite_delta[1][i]) >= INT_MAX >> shift_y ) { avpriv_request_sample(s->avctx, "Too large sprite shift, delta or offset"); goto overflow; @@ -376,22 +377,22 @@ static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *g for (i = 0; i < 2; i++) { sprite_offset[0][i] *= 1 << shift_y; sprite_offset[1][i] *= 1 << shift_c; - s->sprite_delta[0][i] *= 1 << shift_y; - s->sprite_delta[1][i] *= 1 << shift_y; + sprite_delta[0][i] *= 1 << shift_y; + sprite_delta[1][i] *= 1 << shift_y; ctx->sprite_shift[i] = 16; } for (i = 0; i < 2; i++) { int64_t sd[2] = { - s->sprite_delta[i][0] - a * (1LL<<16), - s->sprite_delta[i][1] - a * (1LL<<16) + sprite_delta[i][0] - a * (1LL<<16), + sprite_delta[i][1] - a * (1LL<<16) }; - if (llabs(sprite_offset[0][i] + s->sprite_delta[i][0] * (w+16LL)) >= INT_MAX || - llabs(sprite_offset[0][i] + s->sprite_delta[i][1] * (h+16LL)) >= INT_MAX || - llabs(sprite_offset[0][i] + s->sprite_delta[i][0] * (w+16LL) + s->sprite_delta[i][1] * (h+16LL)) >= INT_MAX || - llabs(s->sprite_delta[i][0] * (w+16LL)) >= INT_MAX || - llabs(s->sprite_delta[i][1] * (w+16LL)) >= INT_MAX || + if (llabs(sprite_offset[0][i] + sprite_delta[i][0] * (w+16LL)) >= INT_MAX || + llabs(sprite_offset[0][i] + sprite_delta[i][1] * (h+16LL)) >= INT_MAX || + llabs(sprite_offset[0][i] + sprite_delta[i][0] * (w+16LL) + sprite_delta[i][1] * (h+16LL)) >= INT_MAX || + llabs(sprite_delta[i][0] * (w+16LL)) >= INT_MAX || + llabs(sprite_delta[i][1] * (w+16LL)) >= INT_MAX || llabs(sd[0]) >= INT_MAX || llabs(sd[1]) >= INT_MAX || llabs(sprite_offset[0][i] + sd[0] * (w+16LL)) >= INT_MAX || @@ -405,10 +406,10 @@ static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *g s->real_sprite_warping_points = ctx->num_sprite_warping_points; } - s->sprite_offset[0][0] = sprite_offset[0][0]; - s->sprite_offset[0][1] = sprite_offset[0][1]; - s->sprite_offset[1][0] = sprite_offset[1][0]; - s->sprite_offset[1][1] = sprite_offset[1][1]; + for (i = 0; i < 4; i++) { + s->sprite_offset[i&1][i>>1] = sprite_offset[i&1][i>>1]; + s->sprite_delta [i&1][i>>1] = sprite_delta [i&1][i>>1]; + } return 0; overflow: From 127a362630e11fe724e2e63fc871791fdcbcfa64 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 9 Oct 2017 00:32:30 +0200 Subject: [PATCH 3310/3374] avcodec/mpeg_er: Clear mcsel in mpeg_er_decode_mb() Fixes out of array read Should fix: 3516/clusterfuzz-testcase-minimized-4608518562775040 (not reprodoceable) Found-by: Insu Yun, Georgia Tech. Signed-off-by: Michael Niedermayer --- libavcodec/mpeg_er.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/mpeg_er.c b/libavcodec/mpeg_er.c index 5eca834072a04..ada1a1692f339 100644 --- a/libavcodec/mpeg_er.c +++ b/libavcodec/mpeg_er.c @@ -71,6 +71,7 @@ static void mpeg_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type, s->mb_skipped = mb_skipped; s->mb_x = mb_x; s->mb_y = mb_y; + s->mcsel = 0; memcpy(s->mv, mv, sizeof(*mv)); ff_init_block_index(s); From bdee75a4e750735ab3039f004275ac8479072048 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 9 Oct 2017 01:46:28 +0200 Subject: [PATCH 3311/3374] avcodec/dirac_dwt: Fix integer overflow in COMPOSE_53iL0() Fixes: runtime error: signed integer overflow: 2147483646 + 2 cannot be represented in type 'int' Fixes: 3485/clusterfuzz-testcase-minimized-4940429332054016 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/dirac_dwt.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/dirac_dwt.h b/libavcodec/dirac_dwt.h index 755d5e5d2def0..35ed8857e9e80 100644 --- a/libavcodec/dirac_dwt.h +++ b/libavcodec/dirac_dwt.h @@ -93,10 +93,10 @@ void ff_spatial_idwt_slice2(DWTContext *d, int y); // shared stuff for simd optimizations #define COMPOSE_53iL0(b0, b1, b2)\ - (b1 - ((b0 + b2 + 2) >> 2)) + (b1 - ((int)(b0 + (unsigned)(b2) + 2) >> 2)) #define COMPOSE_DIRAC53iH0(b0, b1, b2)\ - (b1 + ((b0 + b2 + 1) >> 1)) + (b1 + ((int)(b0 + (unsigned)(b2) + 1) >> 1)) #define COMPOSE_DD97iH0(b0, b1, b2, b3, b4)\ (b2 + ((int)(-b0 + 9U*b1 + 9U*b3 - b4 + 8) >> 4)) From c20f4fcb74da2d0432c7b54499bb98f48236b904 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 9 Oct 2017 11:49:28 +0200 Subject: [PATCH 3312/3374] avcodec/ffv1dec: Fix out of array read in slice counting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: test-201710.mp4 Found-by: 连一汉 and Zhibin Hu Signed-off-by: Michael Niedermayer --- libavcodec/ffv1dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index d2bfee784fb36..5eadb6b158648 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -717,7 +717,7 @@ static int read_header(FFV1Context *f) } else { const uint8_t *p = c->bytestream_end; for (f->slice_count = 0; - f->slice_count < MAX_SLICES && 3 < p - c->bytestream_start; + f->slice_count < MAX_SLICES && 3 + 5*!!f->ec < p - c->bytestream_start; f->slice_count++) { int trailer = 3 + 5*!!f->ec; int size = AV_RB24(p-trailer); From 56822b074b5037fa0304b55f9479ea396e67aeea Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Mon, 9 Oct 2017 11:31:20 +0530 Subject: [PATCH 3313/3374] avcodec/mips: preload data in hevc sao edge 135 degree filter msa functions Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/hevc_lpf_sao_msa.c | 194 ++++++++++++++++++++--------- 1 file changed, 132 insertions(+), 62 deletions(-) diff --git a/libavcodec/mips/hevc_lpf_sao_msa.c b/libavcodec/mips/hevc_lpf_sao_msa.c index c192265e85d8e..5b5537a264503 100644 --- a/libavcodec/mips/hevc_lpf_sao_msa.c +++ b/libavcodec/mips/hevc_lpf_sao_msa.c @@ -2226,23 +2226,24 @@ static void hevc_sao_edge_filter_135degree_4width_msa(uint8_t *dst, int32_t height) { uint8_t *src_orig; - int32_t h_cnt; uint32_t dst_val0, dst_val1; - v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 }; + v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; v16u8 const1 = (v16u8) __msa_ldi_b(1); - v16i8 zero = { 0 }; + v16i8 offset, sao_offset = LD_SB(sao_offset_val); v16i8 src_zero0, src_zero1, dst0; v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11; v16u8 src_minus10, src10, src_minus11, src11; - v8i16 offset_mask0, offset_mask1, sao_offset, src00, src01; + v8i16 offset_mask0, offset_mask1; - sao_offset = LD_SH(sao_offset_val); + sao_offset = __msa_pckev_b(sao_offset, sao_offset); src_orig = src - 1; + /* load in advance */ LD_UB2(src_orig - src_stride, src_stride, src_minus10, src_minus11); + LD_UB2(src_orig + src_stride, src_stride, src10, src11); - for (h_cnt = (height >> 1); h_cnt--;) { - LD_UB2(src_orig + src_stride, src_stride, src10, src11); + for (height -= 2; height; height -= 2) { + src_orig += (src_stride << 1); SLDI_B2_0_SB(src_minus11, src10, src_zero0, src_zero1, 1); SLDI_B2_0_UB(src_minus10, src_minus11, src_minus10, src_minus11, 2); @@ -2265,19 +2266,22 @@ static void hevc_sao_edge_filter_135degree_4width_msa(uint8_t *dst, offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); - VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0, - offset_mask0, offset_mask0, offset_mask0); - VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1, - offset_mask1, offset_mask1, offset_mask1); - ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01); - ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0, - offset_mask1); - CLIP_SH2_0_255(offset_mask0, offset_mask1); - dst0 = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); + offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); + dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); + + VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, + offset, offset); + + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); + dst0 = __msa_adds_s_b(dst0, offset); + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); src_minus10 = src10; src_minus11 = src11; + /* load in advance */ + LD_UB2(src_orig + src_stride, src_stride, src10, src11); + dst_val0 = __msa_copy_u_w((v4i32) dst0, 0); dst_val1 = __msa_copy_u_w((v4i32) dst0, 2); @@ -2286,8 +2290,46 @@ static void hevc_sao_edge_filter_135degree_4width_msa(uint8_t *dst, SW(dst_val1, dst); dst += dst_stride; - src_orig += (src_stride << 1); } + + SLDI_B2_0_SB(src_minus11, src10, src_zero0, src_zero1, 1); + SLDI_B2_0_UB(src_minus10, src_minus11, src_minus10, src_minus11, 2); + + ILVR_B2_UB(src10, src_minus10, src11, src_minus11, src_minus10, + src_minus11); + ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1, src_zero0, + src_zero1); + + cmp_minus10 = ((v16u8) src_zero0 == src_minus10); + diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); + cmp_minus10 = (src_minus10 < (v16u8) src_zero0); + diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); + + cmp_minus11 = ((v16u8) src_zero1 == src_minus11); + diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); + cmp_minus11 = (src_minus11 < (v16u8) src_zero1); + diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); + + offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); + offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); + + offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); + dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); + + VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, + offset, offset); + + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); + dst0 = __msa_adds_s_b(dst0, offset); + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); + + dst_val0 = __msa_copy_u_w((v4i32) dst0, 0); + dst_val1 = __msa_copy_u_w((v4i32) dst0, 2); + + SW(dst_val0, dst); + dst += dst_stride; + SW(dst_val1, dst); + dst += dst_stride; } static void hevc_sao_edge_filter_135degree_8width_msa(uint8_t *dst, @@ -2298,23 +2340,24 @@ static void hevc_sao_edge_filter_135degree_8width_msa(uint8_t *dst, int32_t height) { uint8_t *src_orig; - int32_t h_cnt; uint64_t dst_val0, dst_val1; - v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 }; + v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; v16u8 const1 = (v16u8) __msa_ldi_b(1); - v16i8 zero = { 0 }; - v16i8 src_zero0, src_zero1, dst0, dst1; + v16i8 offset, sao_offset = LD_SB(sao_offset_val); v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11; v16u8 src_minus10, src10, src_minus11, src11; - v8i16 sao_offset, src00, offset_mask0, src01, offset_mask1; + v16i8 src_zero0, src_zero1, dst0; + v8i16 offset_mask0, offset_mask1; - sao_offset = LD_SH(sao_offset_val); + sao_offset = __msa_pckev_b(sao_offset, sao_offset); src_orig = src - 1; + /* load in advance */ LD_UB2(src_orig - src_stride, src_stride, src_minus10, src_minus11); + LD_UB2(src_orig + src_stride, src_stride, src10, src11); - for (h_cnt = (height >> 1); h_cnt--;) { - LD_UB2(src_orig + src_stride, src_stride, src10, src11); + for (height -= 2; height; height -= 2) { + src_orig += (src_stride << 1); SLDI_B2_0_SB(src_minus11, src10, src_zero0, src_zero1, 1); SLDI_B2_0_UB(src_minus10, src_minus11, src_minus10, src_minus11, 2); @@ -2336,30 +2379,68 @@ static void hevc_sao_edge_filter_135degree_8width_msa(uint8_t *dst, offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); - VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0, - offset_mask0, offset_mask0, offset_mask0); - VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1, - offset_mask1, offset_mask1, offset_mask1); - ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01); - ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0, - offset_mask1); - CLIP_SH2_0_255(offset_mask0, offset_mask1); - PCKEV_B2_SB(offset_mask0, offset_mask0, offset_mask1, offset_mask1, - dst0, dst1); + offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); + dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); + + VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, + offset, offset); + + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); + dst0 = __msa_adds_s_b(dst0, offset); + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); src_minus10 = src10; src_minus11 = src11; + /* load in advance */ + LD_UB2(src_orig + src_stride, src_stride, src10, src11); + dst_val0 = __msa_copy_u_d((v2i64) dst0, 0); - dst_val1 = __msa_copy_u_d((v2i64) dst1, 0); + dst_val1 = __msa_copy_u_d((v2i64) dst0, 1); SD(dst_val0, dst); dst += dst_stride; SD(dst_val1, dst); dst += dst_stride; - - src_orig += (src_stride << 1); } + + SLDI_B2_0_SB(src_minus11, src10, src_zero0, src_zero1, 1); + SLDI_B2_0_UB(src_minus10, src_minus11, src_minus10, src_minus11, 2); + ILVR_B2_UB(src10, src_minus10, src11, src_minus11, src_minus10, + src_minus11); + ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1, src_zero0, + src_zero1); + + cmp_minus10 = ((v16u8) src_zero0 == src_minus10); + diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); + cmp_minus10 = (src_minus10 < (v16u8) src_zero0); + diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); + + cmp_minus11 = ((v16u8) src_zero1 == src_minus11); + diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); + cmp_minus11 = (src_minus11 < (v16u8) src_zero1); + diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); + + offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); + offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); + + offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); + dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); + + VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, + offset, offset); + + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); + dst0 = __msa_adds_s_b(dst0, offset); + dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); + + dst_val0 = __msa_copy_u_d((v2i64) dst0, 0); + dst_val1 = __msa_copy_u_d((v2i64) dst0, 1); + + SD(dst_val0, dst); + dst += dst_stride; + SD(dst_val1, dst); + dst += dst_stride; } static void hevc_sao_edge_filter_135degree_16multiple_msa(uint8_t *dst, @@ -2372,7 +2453,7 @@ static void hevc_sao_edge_filter_135degree_16multiple_msa(uint8_t *dst, int32_t height) { uint8_t *src_orig, *dst_orig; - int32_t h_cnt, v_cnt; + int32_t v_cnt; v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; v16u8 const1 = (v16u8) __msa_ldi_b(1); v16u8 dst0, dst1, dst2, dst3; @@ -2383,20 +2464,18 @@ static void hevc_sao_edge_filter_135degree_16multiple_msa(uint8_t *dst, v16u8 src_plus10, src_plus11, src_plus12, src_plus13; v16i8 src_minus12, src_minus13, src_zero0, src_zero1, src_zero2, src_zero3; v16i8 offset_mask0, offset_mask1, offset_mask2, offset_mask3, sao_offset; - v8i16 src0, src1, src2, src3, src4, src5, src6, src7; - v8i16 temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7; sao_offset = LD_SB(sao_offset_val); sao_offset = __msa_pckev_b(sao_offset, sao_offset); - for (h_cnt = (height >> 2); h_cnt--;) { + for (; height; height -= 4) { src_orig = src - 1; dst_orig = dst; - LD_UB4(src_orig, src_stride, - src_minus11, src_plus10, src_plus11, src_plus12); + LD_UB4(src_orig, src_stride, src_minus11, src_plus10, src_plus11, + src_plus12); - for (v_cnt = 0; v_cnt < (width >> 4); v_cnt++) { + for (v_cnt = 0; v_cnt < width; v_cnt += 16) { src_minus10 = LD_UB(src_orig + 2 - src_stride); LD_UB4(src_orig + 16, src_stride, src10, src11, src12, src13); src_plus13 = LD_UB(src_orig + (src_stride << 2)); @@ -2463,23 +2542,14 @@ static void hevc_sao_edge_filter_135degree_16multiple_msa(uint8_t *dst, VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask3, offset_mask3, offset_mask3, offset_mask3); - UNPCK_UB_SH(src_zero0, src0, src1); - UNPCK_SB_SH(offset_mask0, temp0, temp1); - UNPCK_UB_SH(src_zero1, src2, src3); - UNPCK_SB_SH(offset_mask1, temp2, temp3); - UNPCK_UB_SH(src_zero2, src4, src5); - UNPCK_SB_SH(offset_mask2, temp4, temp5); - UNPCK_UB_SH(src_zero3, src6, src7); - UNPCK_SB_SH(offset_mask3, temp6, temp7); - - ADD4(temp0, src0, temp1, src1, temp2, src2, temp3, src3, temp0, - temp1, temp2, temp3); - ADD4(temp4, src4, temp5, src5, temp6, src6, temp7, src7, temp4, - temp5, temp6, temp7); - CLIP_SH4_0_255(temp0, temp1, temp2, temp3); - CLIP_SH4_0_255(temp4, temp5, temp6, temp7); - PCKEV_B4_UB(temp1, temp0, temp3, temp2, temp5, temp4, temp7, temp6, - dst0, dst1, dst2, dst3); + XORI_B4_128_SB(src_zero0, src_zero1, src_zero2, src_zero3); + + dst0 = (v16u8) __msa_adds_s_b((v16i8) src_zero0, offset_mask0); + dst1 = (v16u8) __msa_adds_s_b((v16i8) src_zero1, offset_mask1); + dst2 = (v16u8) __msa_adds_s_b((v16i8) src_zero2, offset_mask2); + dst3 = (v16u8) __msa_adds_s_b((v16i8) src_zero3, offset_mask3); + + XORI_B4_128_UB(dst0, dst1, dst2, dst3); src_minus11 = src10; src_plus10 = src11; From af9433b1d6873f3cbd0870a406607f7a67f45b4f Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Mon, 9 Oct 2017 12:48:39 +0530 Subject: [PATCH 3314/3374] avcodec/mips: Improve avc bi-weighted mc msa functions Replace generic with block size specific function. Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/h264dsp_msa.c | 469 ++++++++++++++++++---------- libavutil/mips/generic_macros_msa.h | 4 + 2 files changed, 311 insertions(+), 162 deletions(-) diff --git a/libavcodec/mips/h264dsp_msa.c b/libavcodec/mips/h264dsp_msa.c index 5b06bd934b38a..e50f5ca0a4fa5 100644 --- a/libavcodec/mips/h264dsp_msa.c +++ b/libavcodec/mips/h264dsp_msa.c @@ -223,217 +223,242 @@ static void avc_wgt_8x16_msa(uint8_t *data, int32_t stride, int32_t log2_denom, } } -static void avc_biwgt_4x2_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, +static void avc_biwgt_4x2_msa(uint8_t *src, uint8_t *dst, int32_t stride, int32_t log2_denom, int32_t src_weight, int32_t dst_weight, int32_t offset_in) { - uint32_t load0, load1, out0, out1; - v16i8 src_wgt, dst_wgt, wgt; - v16i8 src0, src1, dst0, dst1; - v8i16 temp0, temp1, denom, offset, add_val; - int32_t val = 128 * (src_weight + dst_weight); + uint32_t tp0, tp1; + v16i8 src_wgt, dst_wgt, wgt, vec0; + v16u8 src0 = { 0 }, dst0 = { 0 }; + v8i16 tmp0, denom, offset, max255 = __msa_ldi_h(255); - offset_in = ((offset_in + 1) | 1) << log2_denom; + offset_in = (unsigned) ((offset_in + 1) | 1) << log2_denom; + offset_in += (128 * (src_weight + dst_weight)); src_wgt = __msa_fill_b(src_weight); dst_wgt = __msa_fill_b(dst_weight); offset = __msa_fill_h(offset_in); denom = __msa_fill_h(log2_denom + 1); - add_val = __msa_fill_h(val); - offset += add_val; wgt = __msa_ilvev_b(dst_wgt, src_wgt); - load0 = LW(src); - src += src_stride; - load1 = LW(src); - - src0 = (v16i8) __msa_fill_w(load0); - src1 = (v16i8) __msa_fill_w(load1); - - load0 = LW(dst); - load1 = LW(dst + dst_stride); - - dst0 = (v16i8) __msa_fill_w(load0); - dst1 = (v16i8) __msa_fill_w(load1); + LW2(src, stride, tp0, tp1); + INSERT_W2_UB(tp0, tp1, src0); + LW2(dst, stride, tp0, tp1); + INSERT_W2_UB(tp0, tp1, dst0); + XORI_B2_128_UB(src0, dst0); + vec0 = (v16i8) __msa_ilvr_b((v16i8) dst0, (v16i8) src0); + tmp0 = __msa_dpadd_s_h(offset, wgt, vec0); + tmp0 >>= denom; + tmp0 = __msa_maxi_s_h(tmp0, 0); + tmp0 = __msa_min_s_h(max255, tmp0); + dst0 = (v16u8) __msa_pckev_b((v16i8) tmp0, (v16i8) tmp0); + ST4x2_UB(dst0, dst, stride); +} - XORI_B4_128_SB(src0, src1, dst0, dst1); - ILVR_B2_SH(dst0, src0, dst1, src1, temp0, temp1); +static void avc_biwgt_4x4_msa(uint8_t *src, uint8_t *dst, int32_t stride, + int32_t log2_denom, int32_t src_weight, + int32_t dst_weight, int32_t offset_in) +{ + uint32_t tp0, tp1, tp2, tp3; + v16i8 src_wgt, dst_wgt, wgt, vec0, vec1; + v16u8 src0, dst0; + v8i16 tmp0, tmp1, denom, offset; - temp0 = __msa_dpadd_s_h(offset, wgt, (v16i8) temp0); - temp1 = __msa_dpadd_s_h(offset, wgt, (v16i8) temp1); + offset_in = (unsigned) ((offset_in + 1) | 1) << log2_denom; + offset_in += (128 * (src_weight + dst_weight)); - temp0 >>= denom; - temp1 >>= denom; + src_wgt = __msa_fill_b(src_weight); + dst_wgt = __msa_fill_b(dst_weight); + offset = __msa_fill_h(offset_in); + denom = __msa_fill_h(log2_denom + 1); - CLIP_SH2_0_255(temp0, temp1); - PCKEV_B2_SB(temp0, temp0, temp1, temp1, dst0, dst1); + wgt = __msa_ilvev_b(dst_wgt, src_wgt); - out0 = __msa_copy_u_w((v4i32) dst0, 0); - out1 = __msa_copy_u_w((v4i32) dst1, 0); - SW(out0, dst); - dst += dst_stride; - SW(out1, dst); + LW4(src, stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, src0); + LW4(dst, stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); + XORI_B2_128_UB(src0, dst0); + ILVRL_B2_SB(dst0, src0, vec0, vec1); + tmp0 = __msa_dpadd_s_h(offset, wgt, vec0); + tmp1 = __msa_dpadd_s_h(offset, wgt, vec1); + tmp0 >>= denom; + tmp1 >>= denom; + CLIP_SH2_0_255(tmp0, tmp1); + dst0 = (v16u8) __msa_pckev_b((v16i8) tmp1, (v16i8) tmp0); + ST4x4_UB(dst0, dst0, 0, 1, 2, 3, dst, stride); } -static void avc_biwgt_4x4multiple_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height, int32_t log2_denom, - int32_t src_weight, int32_t dst_weight, - int32_t offset_in) +static void avc_biwgt_4x8_msa(uint8_t *src, uint8_t *dst, int32_t stride, + int32_t log2_denom, int32_t src_weight, + int32_t dst_weight, int32_t offset_in) { - uint8_t cnt; - uint32_t load0, load1, load2, load3; - v16i8 src_wgt, dst_wgt, wgt; - v16i8 src0, src1, src2, src3; - v16i8 dst0, dst1, dst2, dst3; - v8i16 temp0, temp1, temp2, temp3; - v8i16 denom, offset, add_val; - int32_t val = 128 * (src_weight + dst_weight); + uint32_t tp0, tp1, tp2, tp3; + v16i8 src_wgt, dst_wgt, wgt, vec0, vec1, vec2, vec3; + v16u8 src0, src1, dst0, dst1; + v8i16 tmp0, tmp1, tmp2, tmp3, denom, offset; - offset_in = ((offset_in + 1) | 1) << log2_denom; + offset_in = (unsigned) ((offset_in + 1) | 1) << log2_denom; + offset_in += (128 * (src_weight + dst_weight)); src_wgt = __msa_fill_b(src_weight); dst_wgt = __msa_fill_b(dst_weight); offset = __msa_fill_h(offset_in); denom = __msa_fill_h(log2_denom + 1); - add_val = __msa_fill_h(val); - offset += add_val; - wgt = __msa_ilvev_b(dst_wgt, src_wgt); - for (cnt = height / 4; cnt--;) { - LW4(src, src_stride, load0, load1, load2, load3); - src += (4 * src_stride); - - src0 = (v16i8) __msa_fill_w(load0); - src1 = (v16i8) __msa_fill_w(load1); - src2 = (v16i8) __msa_fill_w(load2); - src3 = (v16i8) __msa_fill_w(load3); - - LW4(dst, dst_stride, load0, load1, load2, load3); + LW4(src, stride, tp0, tp1, tp2, tp3); + src += 4 * stride; + INSERT_W4_UB(tp0, tp1, tp2, tp3, src0); + LW4(src, stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, src1); + LW4(dst, stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); + LW4(dst + 4 * stride, stride, tp0, tp1, tp2, tp3); + INSERT_W4_UB(tp0, tp1, tp2, tp3, dst1); + XORI_B4_128_UB(src0, src1, dst0, dst1); + ILVRL_B2_SB(dst0, src0, vec0, vec1); + ILVRL_B2_SB(dst1, src1, vec2, vec3); + tmp0 = __msa_dpadd_s_h(offset, wgt, vec0); + tmp1 = __msa_dpadd_s_h(offset, wgt, vec1); + tmp2 = __msa_dpadd_s_h(offset, wgt, vec2); + tmp3 = __msa_dpadd_s_h(offset, wgt, vec3); + SRA_4V(tmp0, tmp1, tmp2, tmp3, denom); + CLIP_SH4_0_255(tmp0, tmp1, tmp2, tmp3); + PCKEV_B2_UB(tmp1, tmp0, tmp3, tmp2, dst0, dst1); + ST4x8_UB(dst0, dst1, dst, stride); +} - dst0 = (v16i8) __msa_fill_w(load0); - dst1 = (v16i8) __msa_fill_w(load1); - dst2 = (v16i8) __msa_fill_w(load2); - dst3 = (v16i8) __msa_fill_w(load3); +static void avc_biwgt_8x4_msa(uint8_t *src, uint8_t *dst, int32_t stride, + int32_t log2_denom, int32_t src_weight, + int32_t dst_weight, int32_t offset_in) +{ + uint64_t tp0, tp1, tp2, tp3; + v16i8 src_wgt, dst_wgt, wgt, vec0, vec1, vec2, vec3; + v16u8 src0, src1, dst0, dst1; + v8i16 tmp0, tmp1, tmp2, tmp3, denom, offset; - XORI_B4_128_SB(src0, src1, src2, src3); - XORI_B4_128_SB(dst0, dst1, dst2, dst3); - ILVR_B4_SH(dst0, src0, dst1, src1, dst2, src2, dst3, src3, - temp0, temp1, temp2, temp3); + offset_in = (unsigned) ((offset_in + 1) | 1) << log2_denom; + offset_in += (128 * (src_weight + dst_weight)); - temp0 = __msa_dpadd_s_h(offset, wgt, (v16i8) temp0); - temp1 = __msa_dpadd_s_h(offset, wgt, (v16i8) temp1); - temp2 = __msa_dpadd_s_h(offset, wgt, (v16i8) temp2); - temp3 = __msa_dpadd_s_h(offset, wgt, (v16i8) temp3); + src_wgt = __msa_fill_b(src_weight); + dst_wgt = __msa_fill_b(dst_weight); + offset = __msa_fill_h(offset_in); + denom = __msa_fill_h(log2_denom + 1); - SRA_4V(temp0, temp1, temp2, temp3, denom); - CLIP_SH4_0_255(temp0, temp1, temp2, temp3); - PCKEV_ST4x4_UB(temp0, temp1, temp2, temp3, dst, dst_stride); - dst += (4 * dst_stride); - } -} + wgt = __msa_ilvev_b(dst_wgt, src_wgt); -static void avc_biwgt_4width_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height, int32_t log2_denom, - int32_t src_weight, int32_t dst_weight, - int32_t offset_in) -{ - if (2 == height) { - avc_biwgt_4x2_msa(src, src_stride, dst, dst_stride, log2_denom, - src_weight, dst_weight, offset_in); - } else { - avc_biwgt_4x4multiple_msa(src, src_stride, dst, dst_stride, height, - log2_denom, src_weight, dst_weight, - offset_in); - } + LD4(src, stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, src0); + INSERT_D2_UB(tp2, tp3, src1); + LD4(dst, stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, dst0); + INSERT_D2_UB(tp2, tp3, dst1); + XORI_B4_128_UB(src0, src1, dst0, dst1); + ILVRL_B2_SB(dst0, src0, vec0, vec1); + ILVRL_B2_SB(dst1, src1, vec2, vec3); + tmp0 = __msa_dpadd_s_h(offset, wgt, vec0); + tmp1 = __msa_dpadd_s_h(offset, wgt, vec1); + tmp2 = __msa_dpadd_s_h(offset, wgt, vec2); + tmp3 = __msa_dpadd_s_h(offset, wgt, vec3); + SRA_4V(tmp0, tmp1, tmp2, tmp3, denom); + CLIP_SH4_0_255(tmp0, tmp1, tmp2, tmp3); + PCKEV_B2_UB(tmp1, tmp0, tmp3, tmp2, dst0, dst1); + ST8x4_UB(dst0, dst1, dst, stride); } -static void avc_biwgt_8width_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height, int32_t log2_denom, - int32_t src_weight, int32_t dst_weight, - int32_t offset_in) +static void avc_biwgt_8x8_msa(uint8_t *src, uint8_t *dst, int32_t stride, + int32_t log2_denom, int32_t src_weight, + int32_t dst_weight, int32_t offset_in) { - uint8_t cnt; - v16i8 src_wgt, dst_wgt, wgt; - v16i8 src0, src1, src2, src3; - v16i8 dst0, dst1, dst2, dst3; - v16i8 out0, out1; - v8i16 temp0, temp1, temp2, temp3; - v8i16 denom, offset, add_val; - int32_t val = 128 * (src_weight + dst_weight); + uint64_t tp0, tp1, tp2, tp3; + v16i8 src_wgt, dst_wgt, wgt, vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; + v16u8 src0, src1, src2, src3, dst0, dst1, dst2, dst3; + v8i16 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, denom, offset; - offset_in = ((offset_in + 1) | 1) << log2_denom; + offset_in = (unsigned) ((offset_in + 1) | 1) << log2_denom; + offset_in += (128 * (src_weight + dst_weight)); src_wgt = __msa_fill_b(src_weight); dst_wgt = __msa_fill_b(dst_weight); offset = __msa_fill_h(offset_in); denom = __msa_fill_h(log2_denom + 1); - add_val = __msa_fill_h(val); - offset += add_val; - wgt = __msa_ilvev_b(dst_wgt, src_wgt); - for (cnt = height / 4; cnt--;) { - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - LD_SB4(dst, dst_stride, dst0, dst1, dst2, dst3); - XORI_B4_128_SB(src0, src1, src2, src3); - XORI_B4_128_SB(dst0, dst1, dst2, dst3); - ILVR_B4_SH(dst0, src0, dst1, src1, dst2, src2, dst3, src3, - temp0, temp1, temp2, temp3); - - temp0 = __msa_dpadd_s_h(offset, wgt, (v16i8) temp0); - temp1 = __msa_dpadd_s_h(offset, wgt, (v16i8) temp1); - temp2 = __msa_dpadd_s_h(offset, wgt, (v16i8) temp2); - temp3 = __msa_dpadd_s_h(offset, wgt, (v16i8) temp3); - - SRA_4V(temp0, temp1, temp2, temp3, denom); - CLIP_SH4_0_255(temp0, temp1, temp2, temp3); - PCKEV_B2_SB(temp1, temp0, temp3, temp2, out0, out1); - ST8x4_UB(out0, out1, dst, dst_stride); - dst += 4 * dst_stride; - } + LD4(src, stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, src0); + INSERT_D2_UB(tp2, tp3, src1); + LD4(src + 4 * stride, stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, src2); + INSERT_D2_UB(tp2, tp3, src3); + LD4(dst, stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, dst0); + INSERT_D2_UB(tp2, tp3, dst1); + LD4(dst + 4 * stride, stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, dst2); + INSERT_D2_UB(tp2, tp3, dst3); + XORI_B8_128_UB(src0, src1, src2, src3, dst0, dst1, dst2, dst3); + ILVRL_B2_SB(dst0, src0, vec0, vec1); + ILVRL_B2_SB(dst1, src1, vec2, vec3); + ILVRL_B2_SB(dst2, src2, vec4, vec5); + ILVRL_B2_SB(dst3, src3, vec6, vec7); + tmp0 = __msa_dpadd_s_h(offset, wgt, vec0); + tmp1 = __msa_dpadd_s_h(offset, wgt, vec1); + tmp2 = __msa_dpadd_s_h(offset, wgt, vec2); + tmp3 = __msa_dpadd_s_h(offset, wgt, vec3); + tmp4 = __msa_dpadd_s_h(offset, wgt, vec4); + tmp5 = __msa_dpadd_s_h(offset, wgt, vec5); + tmp6 = __msa_dpadd_s_h(offset, wgt, vec6); + tmp7 = __msa_dpadd_s_h(offset, wgt, vec7); + SRA_4V(tmp0, tmp1, tmp2, tmp3, denom); + SRA_4V(tmp4, tmp5, tmp6, tmp7, denom); + CLIP_SH4_0_255(tmp0, tmp1, tmp2, tmp3); + CLIP_SH4_0_255(tmp4, tmp5, tmp6, tmp7); + PCKEV_B2_UB(tmp1, tmp0, tmp3, tmp2, dst0, dst1); + PCKEV_B2_UB(tmp5, tmp4, tmp7, tmp6, dst2, dst3); + ST8x8_UB(dst0, dst1, dst2, dst3, dst, stride); } -static void avc_biwgt_16width_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height, int32_t log2_denom, - int32_t src_weight, int32_t dst_weight, - int32_t offset_in) +static void avc_biwgt_8x16_msa(uint8_t *src, uint8_t *dst, int32_t stride, + int32_t log2_denom, int32_t src_weight, + int32_t dst_weight, int32_t offset_in) { uint8_t cnt; + uint64_t tp0, tp1, tp2, tp3; v16i8 src_wgt, dst_wgt, wgt; - v16i8 src0, src1, src2, src3; - v16i8 dst0, dst1, dst2, dst3; + v16u8 src0, src1, src2, src3; + v16u8 dst0, dst1, dst2, dst3; v16i8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; v8i16 temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7; - v8i16 denom, offset, add_val; - int32_t val = 128 * (src_weight + dst_weight); + v8i16 denom, offset; - offset_in = ((offset_in + 1) | 1) << log2_denom; + offset_in = (unsigned) ((offset_in + 1) | 1) << log2_denom; + offset_in += (128 * (src_weight + dst_weight)); src_wgt = __msa_fill_b(src_weight); dst_wgt = __msa_fill_b(dst_weight); offset = __msa_fill_h(offset_in); denom = __msa_fill_h(log2_denom + 1); - add_val = __msa_fill_h(val); - offset += add_val; - wgt = __msa_ilvev_b(dst_wgt, src_wgt); - for (cnt = height / 4; cnt--;) { - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - LD_SB4(dst, dst_stride, dst0, dst1, dst2, dst3); - XORI_B4_128_SB(src0, src1, src2, src3); - XORI_B4_128_SB(dst0, dst1, dst2, dst3); + for (cnt = 2; cnt--;) { + LD4(src, stride, tp0, tp1, tp2, tp3); + src += 4 * stride; + INSERT_D2_UB(tp0, tp1, src0); + INSERT_D2_UB(tp2, tp3, src1); + LD4(src, stride, tp0, tp1, tp2, tp3); + src += 4 * stride; + INSERT_D2_UB(tp0, tp1, src2); + INSERT_D2_UB(tp2, tp3, src3); + LD4(dst, stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, dst0); + INSERT_D2_UB(tp2, tp3, dst1); + LD4(dst + 4 * stride, stride, tp0, tp1, tp2, tp3); + INSERT_D2_UB(tp0, tp1, dst2); + INSERT_D2_UB(tp2, tp3, dst3); + XORI_B4_128_UB(src0, src1, src2, src3); + XORI_B4_128_UB(dst0, dst1, dst2, dst3); ILVR_B4_SB(dst0, src0, dst1, src1, dst2, src2, dst3, src3, vec0, vec2, vec4, vec6); ILVL_B4_SB(dst0, src0, dst1, src1, dst2, src2, dst3, src3, @@ -452,10 +477,10 @@ static void avc_biwgt_16width_msa(uint8_t *src, int32_t src_stride, SRA_4V(temp4, temp5, temp6, temp7, denom); CLIP_SH4_0_255(temp0, temp1, temp2, temp3); CLIP_SH4_0_255(temp4, temp5, temp6, temp7); - PCKEV_B4_SB(temp1, temp0, temp3, temp2, temp5, temp4, temp7, temp6, + PCKEV_B4_UB(temp1, temp0, temp3, temp2, temp5, temp4, temp7, temp6, dst0, dst1, dst2, dst3); - ST_SB4(dst0, dst1, dst2, dst3, dst, dst_stride); - dst += 4 * dst_stride; + ST8x8_UB(dst0, dst1, dst2, dst3, dst, stride); + dst += 8 * stride; } } @@ -2430,10 +2455,114 @@ void ff_weight_h264_pixels4_8_msa(uint8_t *src, ptrdiff_t stride, void ff_biweight_h264_pixels16_8_msa(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int height, int log2_denom, int weight_dst, - int weight_src, int offset) + int weight_src, int offset_in) { - avc_biwgt_16width_msa(src, stride, dst, stride, height, log2_denom, - weight_src, weight_dst, offset); + v16i8 src_wgt, dst_wgt, wgt; + v16u8 src0, src1, src2, src3, src4, src5, src6, src7; + v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; + v16i8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; + v16i8 vec8, vec9, vec10, vec11, vec12, vec13, vec14, vec15; + v8i16 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + v8i16 tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15; + v8i16 denom, offset; + + offset_in = (unsigned) ((offset_in + 1) | 1) << log2_denom; + offset_in += (128 * (weight_src + weight_dst)); + + src_wgt = __msa_fill_b(weight_src); + dst_wgt = __msa_fill_b(weight_dst); + offset = __msa_fill_h(offset_in); + denom = __msa_fill_h(log2_denom + 1); + + wgt = __msa_ilvev_b(dst_wgt, src_wgt); + + LD_UB8(src, stride, src0, src1, src2, src3, src4, src5, src6, src7); + src += 8 * stride; + LD_UB8(dst, stride, dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7); + XORI_B8_128_UB(src0, src1, src2, src3, src4, src5, src6, src7); + XORI_B8_128_UB(dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7); + ILVR_B4_SB(dst0, src0, dst1, src1, dst2, src2, dst3, src3, vec0, vec2, vec4, + vec6); + ILVL_B4_SB(dst0, src0, dst1, src1, dst2, src2, dst3, src3, vec1, vec3, vec5, + vec7); + ILVR_B4_SB(dst4, src4, dst5, src5, dst6, src6, dst7, src7, vec8, vec10, + vec12, vec14); + ILVL_B4_SB(dst4, src4, dst5, src5, dst6, src6, dst7, src7, vec9, vec11, + vec13, vec15); + tmp0 = __msa_dpadd_s_h(offset, wgt, vec0); + tmp1 = __msa_dpadd_s_h(offset, wgt, vec1); + tmp2 = __msa_dpadd_s_h(offset, wgt, vec2); + tmp3 = __msa_dpadd_s_h(offset, wgt, vec3); + tmp4 = __msa_dpadd_s_h(offset, wgt, vec4); + tmp5 = __msa_dpadd_s_h(offset, wgt, vec5); + tmp6 = __msa_dpadd_s_h(offset, wgt, vec6); + tmp7 = __msa_dpadd_s_h(offset, wgt, vec7); + tmp8 = __msa_dpadd_s_h(offset, wgt, vec8); + tmp9 = __msa_dpadd_s_h(offset, wgt, vec9); + tmp10 = __msa_dpadd_s_h(offset, wgt, vec10); + tmp11 = __msa_dpadd_s_h(offset, wgt, vec11); + tmp12 = __msa_dpadd_s_h(offset, wgt, vec12); + tmp13 = __msa_dpadd_s_h(offset, wgt, vec13); + tmp14 = __msa_dpadd_s_h(offset, wgt, vec14); + tmp15 = __msa_dpadd_s_h(offset, wgt, vec15); + SRA_4V(tmp0, tmp1, tmp2, tmp3, denom); + SRA_4V(tmp4, tmp5, tmp6, tmp7, denom); + SRA_4V(tmp8, tmp9, tmp10, tmp11, denom); + SRA_4V(tmp12, tmp13, tmp14, tmp15, denom); + CLIP_SH4_0_255(tmp0, tmp1, tmp2, tmp3); + CLIP_SH4_0_255(tmp4, tmp5, tmp6, tmp7); + CLIP_SH4_0_255(tmp8, tmp9, tmp10, tmp11); + CLIP_SH4_0_255(tmp12, tmp13, tmp14, tmp15); + PCKEV_B4_UB(tmp1, tmp0, tmp3, tmp2, tmp5, tmp4, tmp7, tmp6, dst0, dst1, + dst2, dst3); + PCKEV_B4_UB(tmp9, tmp8, tmp11, tmp10, tmp13, tmp12, tmp15, tmp14, dst4, + dst5, dst6, dst7); + ST_UB8(dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7, dst, stride); + dst += 8 * stride; + + if (16 == height) { + LD_UB8(src, stride, src0, src1, src2, src3, src4, src5, src6, src7); + LD_UB8(dst, stride, dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7); + XORI_B8_128_UB(src0, src1, src2, src3, src4, src5, src6, src7); + XORI_B8_128_UB(dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7); + ILVR_B4_SB(dst0, src0, dst1, src1, dst2, src2, dst3, src3, vec0, vec2, + vec4, vec6); + ILVL_B4_SB(dst0, src0, dst1, src1, dst2, src2, dst3, src3, vec1, vec3, + vec5, vec7); + ILVR_B4_SB(dst4, src4, dst5, src5, dst6, src6, dst7, src7, vec8, vec10, + vec12, vec14); + ILVL_B4_SB(dst4, src4, dst5, src5, dst6, src6, dst7, src7, vec9, vec11, + vec13, vec15); + tmp0 = __msa_dpadd_s_h(offset, wgt, vec0); + tmp1 = __msa_dpadd_s_h(offset, wgt, vec1); + tmp2 = __msa_dpadd_s_h(offset, wgt, vec2); + tmp3 = __msa_dpadd_s_h(offset, wgt, vec3); + tmp4 = __msa_dpadd_s_h(offset, wgt, vec4); + tmp5 = __msa_dpadd_s_h(offset, wgt, vec5); + tmp6 = __msa_dpadd_s_h(offset, wgt, vec6); + tmp7 = __msa_dpadd_s_h(offset, wgt, vec7); + tmp8 = __msa_dpadd_s_h(offset, wgt, vec8); + tmp9 = __msa_dpadd_s_h(offset, wgt, vec9); + tmp10 = __msa_dpadd_s_h(offset, wgt, vec10); + tmp11 = __msa_dpadd_s_h(offset, wgt, vec11); + tmp12 = __msa_dpadd_s_h(offset, wgt, vec12); + tmp13 = __msa_dpadd_s_h(offset, wgt, vec13); + tmp14 = __msa_dpadd_s_h(offset, wgt, vec14); + tmp15 = __msa_dpadd_s_h(offset, wgt, vec15); + SRA_4V(tmp0, tmp1, tmp2, tmp3, denom); + SRA_4V(tmp4, tmp5, tmp6, tmp7, denom); + SRA_4V(tmp8, tmp9, tmp10, tmp11, denom); + SRA_4V(tmp12, tmp13, tmp14, tmp15, denom); + CLIP_SH4_0_255(tmp0, tmp1, tmp2, tmp3); + CLIP_SH4_0_255(tmp4, tmp5, tmp6, tmp7); + CLIP_SH4_0_255(tmp8, tmp9, tmp10, tmp11); + CLIP_SH4_0_255(tmp12, tmp13, tmp14, tmp15); + PCKEV_B4_UB(tmp1, tmp0, tmp3, tmp2, tmp5, tmp4, tmp7, tmp6, dst0, dst1, + dst2, dst3); + PCKEV_B4_UB(tmp9, tmp8, tmp11, tmp10, tmp13, tmp12, tmp15, tmp14, dst4, + dst5, dst6, dst7); + ST_UB8(dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7, dst, stride); + } } void ff_biweight_h264_pixels8_8_msa(uint8_t *dst, uint8_t *src, @@ -2441,8 +2570,16 @@ void ff_biweight_h264_pixels8_8_msa(uint8_t *dst, uint8_t *src, int log2_denom, int weight_dst, int weight_src, int offset) { - avc_biwgt_8width_msa(src, stride, dst, stride, height, log2_denom, - weight_src, weight_dst, offset); + if (4 == height) { + avc_biwgt_8x4_msa(src, dst, stride, log2_denom, weight_src, weight_dst, + offset); + } else if (8 == height) { + avc_biwgt_8x8_msa(src, dst, stride, log2_denom, weight_src, weight_dst, + offset); + } else { + avc_biwgt_8x16_msa(src, dst, stride, log2_denom, weight_src, weight_dst, + offset); + } } void ff_biweight_h264_pixels4_8_msa(uint8_t *dst, uint8_t *src, @@ -2450,6 +2587,14 @@ void ff_biweight_h264_pixels4_8_msa(uint8_t *dst, uint8_t *src, int log2_denom, int weight_dst, int weight_src, int offset) { - avc_biwgt_4width_msa(src, stride, dst, stride, height, log2_denom, - weight_src, weight_dst, offset); + if (2 == height) { + avc_biwgt_4x2_msa(src, dst, stride, log2_denom, weight_src, weight_dst, + offset); + } else if (4 == height) { + avc_biwgt_4x4_msa(src, dst, stride, log2_denom, weight_src, weight_dst, + offset); + } else { + avc_biwgt_4x8_msa(src, dst, stride, log2_denom, weight_src, weight_dst, + offset); + } } diff --git a/libavutil/mips/generic_macros_msa.h b/libavutil/mips/generic_macros_msa.h index 7de97dd0f8117..c892529f05ac7 100644 --- a/libavutil/mips/generic_macros_msa.h +++ b/libavutil/mips/generic_macros_msa.h @@ -1252,6 +1252,7 @@ } #define INSERT_W4_UB(...) INSERT_W4(v16u8, __VA_ARGS__) #define INSERT_W4_SB(...) INSERT_W4(v16i8, __VA_ARGS__) +#define INSERT_W4_SH(...) INSERT_W4(v8i16, __VA_ARGS__) #define INSERT_W4_SW(...) INSERT_W4(v4i32, __VA_ARGS__) /* Description : Insert specified double word elements from input vectors to 1 @@ -1267,6 +1268,7 @@ } #define INSERT_D2_UB(...) INSERT_D2(v16u8, __VA_ARGS__) #define INSERT_D2_SB(...) INSERT_D2(v16i8, __VA_ARGS__) +#define INSERT_D2_SH(...) INSERT_D2(v8i16, __VA_ARGS__) #define INSERT_D2_SD(...) INSERT_D2(v2i64, __VA_ARGS__) /* Description : Interleave even byte elements from vectors @@ -1444,6 +1446,7 @@ out2 = (RTYPE) __msa_ilvr_b((v16i8) in4, (v16i8) in5); \ } #define ILVR_B3_UB(...) ILVR_B3(v16u8, __VA_ARGS__) +#define ILVR_B3_SB(...) ILVR_B3(v16i8, __VA_ARGS__) #define ILVR_B3_UH(...) ILVR_B3(v8u16, __VA_ARGS__) #define ILVR_B3_SH(...) ILVR_B3(v8i16, __VA_ARGS__) @@ -1974,6 +1977,7 @@ XORI_B4_128(RTYPE, in4, in5, in6, in7); \ } #define XORI_B8_128_SB(...) XORI_B8_128(v16i8, __VA_ARGS__) +#define XORI_B8_128_UB(...) XORI_B8_128(v16u8, __VA_ARGS__) /* Description : Addition of signed halfword elements and signed saturation Arguments : Inputs - in0, in1, in2, in3 From b59323cb72c5756433d382394c66960ad5e01753 Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Mon, 9 Oct 2017 14:15:37 +0530 Subject: [PATCH 3315/3374] avcodec/mips: Improve avc chroma hv mc msa functions Replace generic with block size specific function. Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/h264chroma_msa.c | 309 +++++++++++++++++-------------- 1 file changed, 166 insertions(+), 143 deletions(-) diff --git a/libavcodec/mips/h264chroma_msa.c b/libavcodec/mips/h264chroma_msa.c index 16e2fe4ec7a7f..b8fcf6d012f47 100644 --- a/libavcodec/mips/h264chroma_msa.c +++ b/libavcodec/mips/h264chroma_msa.c @@ -526,8 +526,7 @@ static void avc_chroma_vt_8w_msa(uint8_t *src, uint8_t *dst, int32_t stride, } } -static void avc_chroma_hv_2x2_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, +static void avc_chroma_hv_2x2_msa(uint8_t *src, uint8_t *dst, int32_t stride, uint32_t coef_hor0, uint32_t coef_hor1, uint32_t coef_ver0, uint32_t coef_ver1) { @@ -544,7 +543,7 @@ static void avc_chroma_hv_2x2_msa(uint8_t *src, int32_t src_stride, mask = LD_SB(&chroma_mask_arr[48]); - LD_UB3(src, src_stride, src0, src1, src2); + LD_UB3(src, stride, src0, src1, src2); VSHF_B2_UB(src0, src1, src1, src2, mask, mask, src0, src1); DOTP_UB2_UH(src0, src1, coeff_hz_vec, coeff_hz_vec, res_hz0, res_hz1); MUL2(res_hz0, coeff_vt_vec1, res_hz1, coeff_vt_vec0, res_vt0, res_vt1); @@ -558,12 +557,11 @@ static void avc_chroma_hv_2x2_msa(uint8_t *src, int32_t src_stride, out1 = __msa_copy_u_h(res_vert, 1); SH(out0, dst); - dst += dst_stride; + dst += stride; SH(out1, dst); } -static void avc_chroma_hv_2x4_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, +static void avc_chroma_hv_2x4_msa(uint8_t *src, uint8_t *dst, int32_t stride, uint32_t coef_hor0, uint32_t coef_hor1, uint32_t coef_ver0, uint32_t coef_ver1) { @@ -580,7 +578,7 @@ static void avc_chroma_hv_2x4_msa(uint8_t *src, int32_t src_stride, mask = LD_SB(&chroma_mask_arr[48]); - LD_UB5(src, src_stride, src0, src1, src2, src3, src4); + LD_UB5(src, stride, src0, src1, src2, src3, src4); VSHF_B2_UB(src0, src1, src2, src3, mask, mask, tmp0, tmp1); VSHF_B2_UB(src1, src2, src3, src4, mask, mask, tmp2, tmp3); @@ -588,86 +586,30 @@ static void avc_chroma_hv_2x4_msa(uint8_t *src, int32_t src_stride, DOTP_UB2_UH(src0, src1, coeff_hz_vec, coeff_hz_vec, res_hz0, res_hz1); MUL2(res_hz0, coeff_vt_vec1, res_hz1, coeff_vt_vec0, res_vt0, res_vt1); - res_vt0 += res_vt1; - res_vt0 = (v8u16) __msa_srari_h((v8i16) res_vt0, 6); - res_vt0 = __msa_sat_u_h(res_vt0, 7); - res = (v8i16) __msa_pckev_b((v16i8) res_vt0, (v16i8) res_vt0); - - ST2x4_UB(res, 0, dst, dst_stride); -} - -static void avc_chroma_hv_2x8_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - uint32_t coef_hor0, uint32_t coef_hor1, - uint32_t coef_ver0, uint32_t coef_ver1) -{ - v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8; - v16u8 tmp0, tmp1, tmp2, tmp3; - v8u16 res_hz0, res_hz1, res_vt0, res_vt1; - v8i16 res; - v16i8 mask; - v16i8 coeff_hz_vec0 = __msa_fill_b(coef_hor0); - v16i8 coeff_hz_vec1 = __msa_fill_b(coef_hor1); - v16u8 coeff_hz_vec = (v16u8) __msa_ilvr_b(coeff_hz_vec0, coeff_hz_vec1); - v8u16 coeff_vt_vec0 = (v8u16) __msa_fill_h(coef_ver0); - v8u16 coeff_vt_vec1 = (v8u16) __msa_fill_h(coef_ver1); - - mask = LD_SB(&chroma_mask_arr[48]); - - LD_UB5(src, src_stride, src0, src1, src2, src3, src4); - src += (5 * src_stride); - LD_UB4(src, src_stride, src5, src6, src7, src8); - - VSHF_B2_UB(src0, src1, src2, src3, mask, mask, tmp0, tmp1); - VSHF_B2_UB(src1, src2, src3, src4, mask, mask, tmp2, tmp3); - ILVR_D2_UB(tmp1, tmp0, tmp3, tmp2, src0, src1); - VSHF_B2_UB(src4, src5, src6, src7, mask, mask, tmp0, tmp1); - VSHF_B2_UB(src5, src6, src7, src8, mask, mask, tmp2, tmp3); - ILVR_D2_UB(tmp1, tmp0, tmp3, tmp2, src4, src5); - DOTP_UB2_UH(src0, src1, coeff_hz_vec, coeff_hz_vec, res_hz0, res_hz1); - MUL2(res_hz0, coeff_vt_vec1, res_hz1, coeff_vt_vec0, res_vt0, res_vt1); - res_vt0 += res_vt1; res_vt0 = (v8u16) __msa_srari_h((v8i16) res_vt0, 6); res_vt0 = __msa_sat_u_h(res_vt0, 7); res = (v8i16) __msa_pckev_b((v16i8) res_vt0, (v16i8) res_vt0); - ST2x4_UB(res, 0, dst, dst_stride); - dst += (4 * dst_stride); - - DOTP_UB2_UH(src4, src5, coeff_hz_vec, coeff_hz_vec, res_hz0, res_hz1); - MUL2(res_hz0, coeff_vt_vec1, res_hz1, coeff_vt_vec0, res_vt0, res_vt1); - - res_vt0 += res_vt1; - res_vt0 = (v8u16) __msa_srari_h((v8i16) res_vt0, 6); - res_vt0 = __msa_sat_u_h(res_vt0, 7); - - res = (v8i16) __msa_pckev_b((v16i8) res_vt0, (v16i8) res_vt0); - - ST2x4_UB(res, 0, dst, dst_stride); + ST2x4_UB(res, 0, dst, stride); } -static void avc_chroma_hv_2w_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, +static void avc_chroma_hv_2w_msa(uint8_t *src, uint8_t *dst, int32_t stride, uint32_t coef_hor0, uint32_t coef_hor1, uint32_t coef_ver0, uint32_t coef_ver1, int32_t height) { if (2 == height) { - avc_chroma_hv_2x2_msa(src, src_stride, dst, dst_stride, coef_hor0, - coef_hor1, coef_ver0, coef_ver1); + avc_chroma_hv_2x2_msa(src, dst, stride, coef_hor0, coef_hor1, coef_ver0, + coef_ver1); } else if (4 == height) { - avc_chroma_hv_2x4_msa(src, src_stride, dst, dst_stride, coef_hor0, - coef_hor1, coef_ver0, coef_ver1); - } else if (8 == height) { - avc_chroma_hv_2x8_msa(src, src_stride, dst, dst_stride, coef_hor0, - coef_hor1, coef_ver0, coef_ver1); + avc_chroma_hv_2x4_msa(src, dst, stride, coef_hor0, coef_hor1, coef_ver0, + coef_ver1); } } -static void avc_chroma_hv_4x2_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, +static void avc_chroma_hv_4x2_msa(uint8_t *src, uint8_t *dst, int32_t stride, uint32_t coef_hor0, uint32_t coef_hor1, uint32_t coef_ver0, uint32_t coef_ver1) { @@ -682,7 +624,7 @@ static void avc_chroma_hv_4x2_msa(uint8_t *src, int32_t src_stride, v8u16 coeff_vt_vec1 = (v8u16) __msa_fill_h(coef_ver1); mask = LD_SB(&chroma_mask_arr[0]); - LD_UB3(src, src_stride, src0, src1, src2); + LD_UB3(src, stride, src0, src1, src2); VSHF_B2_UB(src0, src1, src1, src2, mask, mask, src0, src1); DOTP_UB2_UH(src0, src1, coeff_hz_vec, coeff_hz_vec, res_hz0, res_hz1); MUL2(res_hz0, coeff_vt_vec1, res_hz1, coeff_vt_vec0, res_vt0, res_vt1); @@ -692,18 +634,13 @@ static void avc_chroma_hv_4x2_msa(uint8_t *src, int32_t src_stride, res_vt0 = __msa_sat_u_h(res_vt0, 7); res = (v4i32) __msa_pckev_b((v16i8) res_vt0, (v16i8) res_vt0); - ST4x2_UB(res, dst, dst_stride); + ST4x2_UB(res, dst, stride); } -static void avc_chroma_hv_4x4multiple_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - uint32_t coef_hor0, - uint32_t coef_hor1, - uint32_t coef_ver0, - uint32_t coef_ver1, - int32_t height) +static void avc_chroma_hv_4x4_msa(uint8_t *src, uint8_t *dst, int32_t stride, + uint32_t coef_hor0, uint32_t coef_hor1, + uint32_t coef_ver0, uint32_t coef_ver1) { - uint32_t row; v16u8 src0, src1, src2, src3, src4; v8u16 res_hz0, res_hz1, res_hz2, res_hz3; v8u16 res_vt0, res_vt1, res_vt2, res_vt3; @@ -717,55 +654,82 @@ static void avc_chroma_hv_4x4multiple_msa(uint8_t *src, int32_t src_stride, mask = LD_SB(&chroma_mask_arr[0]); - src0 = LD_UB(src); - src += src_stride; + LD_UB5(src, stride, src0, src1, src2, src3, src4); + VSHF_B2_UB(src0, src1, src1, src2, mask, mask, src0, src1); + VSHF_B2_UB(src2, src3, src3, src4, mask, mask, src2, src3); + DOTP_UB4_UH(src0, src1, src2, src3, coeff_hz_vec, coeff_hz_vec, + coeff_hz_vec, coeff_hz_vec, res_hz0, res_hz1, res_hz2, + res_hz3); + MUL4(res_hz0, coeff_vt_vec1, res_hz1, coeff_vt_vec0, res_hz2, coeff_vt_vec1, + res_hz3, coeff_vt_vec0, res_vt0, res_vt1, res_vt2, res_vt3); + ADD2(res_vt0, res_vt1, res_vt2, res_vt3, res_vt0, res_vt1); + SRARI_H2_UH(res_vt0, res_vt1, 6); + SAT_UH2_UH(res_vt0, res_vt1, 7); + PCKEV_B2_SW(res_vt0, res_vt0, res_vt1, res_vt1, res0, res1); + ST4x4_UB(res0, res1, 0, 1, 0, 1, dst, stride); +} - for (row = (height >> 2); row--;) { - LD_UB4(src, src_stride, src1, src2, src3, src4); - src += (4 * src_stride); +static void avc_chroma_hv_4x8_msa(uint8_t *src, uint8_t *dst, int32_t stride, + uint32_t coef_hor0, uint32_t coef_hor1, + uint32_t coef_ver0, uint32_t coef_ver1) +{ + v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8, res0, res1; + v8u16 res_hz0, res_hz1, res_hz2, res_hz3, res_hz4, res_hz5, res_hz6, res_hz7; + v8u16 res_vt0, res_vt1, res_vt2, res_vt3, res_vt4, res_vt5, res_vt6, res_vt7; + v16i8 mask; + v16i8 coeff_hz_vec0 = __msa_fill_b(coef_hor0); + v16i8 coeff_hz_vec1 = __msa_fill_b(coef_hor1); + v16u8 coeff_hz_vec = (v16u8) __msa_ilvr_b(coeff_hz_vec0, coeff_hz_vec1); + v8u16 coeff_vt_vec0 = (v8u16) __msa_fill_h(coef_ver0); + v8u16 coeff_vt_vec1 = (v8u16) __msa_fill_h(coef_ver1); - VSHF_B2_UB(src0, src1, src1, src2, mask, mask, src0, src1); - VSHF_B2_UB(src2, src3, src3, src4, mask, mask, src2, src3); - DOTP_UB4_UH(src0, src1, src2, src3, coeff_hz_vec, coeff_hz_vec, - coeff_hz_vec, coeff_hz_vec, res_hz0, res_hz1, res_hz2, - res_hz3); - MUL4(res_hz0, coeff_vt_vec1, res_hz1, coeff_vt_vec0, res_hz2, - coeff_vt_vec1, res_hz3, coeff_vt_vec0, res_vt0, res_vt1, res_vt2, - res_vt3); - ADD2(res_vt0, res_vt1, res_vt2, res_vt3, res_vt0, res_vt1); - SRARI_H2_UH(res_vt0, res_vt1, 6); - SAT_UH2_UH(res_vt0, res_vt1, 7); - PCKEV_B2_SW(res_vt0, res_vt0, res_vt1, res_vt1, res0, res1); + mask = LD_SB(&chroma_mask_arr[0]); - ST4x4_UB(res0, res1, 0, 1, 0, 1, dst, dst_stride); - dst += (4 * dst_stride); - src0 = src4; - } + LD_UB5(src, stride, src0, src1, src2, src3, src4); + src += (5 * stride); + LD_UB4(src, stride, src5, src6, src7, src8); + + VSHF_B2_UB(src0, src1, src1, src2, mask, mask, src0, src1); + VSHF_B2_UB(src2, src3, src3, src4, mask, mask, src2, src3); + VSHF_B2_UB(src4, src5, src5, src6, mask, mask, src4, src5); + VSHF_B2_UB(src6, src7, src7, src8, mask, mask, src6, src7); + DOTP_UB4_UH(src0, src1, src2, src3, coeff_hz_vec, coeff_hz_vec, + coeff_hz_vec, coeff_hz_vec, res_hz0, res_hz1, res_hz2, res_hz3); + DOTP_UB4_UH(src4, src5, src6, src7, coeff_hz_vec, coeff_hz_vec, + coeff_hz_vec, coeff_hz_vec, res_hz4, res_hz5, res_hz6, res_hz7); + MUL4(res_hz0, coeff_vt_vec1, res_hz1, coeff_vt_vec0, res_hz2, coeff_vt_vec1, + res_hz3, coeff_vt_vec0, res_vt0, res_vt1, res_vt2, res_vt3); + MUL4(res_hz4, coeff_vt_vec1, res_hz5, coeff_vt_vec0, res_hz6, coeff_vt_vec1, + res_hz7, coeff_vt_vec0, res_vt4, res_vt5, res_vt6, res_vt7); + ADD2(res_vt0, res_vt1, res_vt2, res_vt3, res_vt0, res_vt1); + ADD2(res_vt4, res_vt5, res_vt6, res_vt7, res_vt2, res_vt3); + SRARI_H4_UH(res_vt0, res_vt1, res_vt2, res_vt3, 6); + SAT_UH4_UH(res_vt0, res_vt1, res_vt2, res_vt3, 7); + PCKEV_B2_UB(res_vt1, res_vt0, res_vt3, res_vt2, res0, res1); + ST4x8_UB(res0, res1, dst, stride); } -static void avc_chroma_hv_4w_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, +static void avc_chroma_hv_4w_msa(uint8_t *src, uint8_t *dst, int32_t stride, uint32_t coef_hor0, uint32_t coef_hor1, uint32_t coef_ver0, uint32_t coef_ver1, int32_t height) { if (2 == height) { - avc_chroma_hv_4x2_msa(src, src_stride, dst, dst_stride, coef_hor0, - coef_hor1, coef_ver0, coef_ver1); - } else { - avc_chroma_hv_4x4multiple_msa(src, src_stride, dst, dst_stride, - coef_hor0, coef_hor1, coef_ver0, - coef_ver1, height); + avc_chroma_hv_4x2_msa(src, dst, stride, coef_hor0, coef_hor1, coef_ver0, + coef_ver1); + } else if (4 == height) { + avc_chroma_hv_4x4_msa(src, dst, stride, coef_hor0, coef_hor1, coef_ver0, + coef_ver1); + } else if (8 == height) { + avc_chroma_hv_4x8_msa(src, dst, stride, coef_hor0, coef_hor1, coef_ver0, + coef_ver1); } } -static void avc_chroma_hv_8w_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - uint32_t coef_hor0, uint32_t coef_hor1, - uint32_t coef_ver0, uint32_t coef_ver1, - int32_t height) +static void avc_chroma_hv_8x4_msa(uint8_t *src, uint8_t *dst, int32_t stride, + uint32_t coef_hor0, uint32_t coef_hor1, + uint32_t coef_ver0, uint32_t coef_ver1) { - uint32_t row; v16u8 src0, src1, src2, src3, src4, out0, out1; v8u16 res_hz0, res_hz1, res_hz2, res_hz3, res_hz4; v8u16 res_vt0, res_vt1, res_vt2, res_vt3; @@ -779,37 +743,99 @@ static void avc_chroma_hv_8w_msa(uint8_t *src, int32_t src_stride, mask = LD_SB(&chroma_mask_arr[32]); src0 = LD_UB(src); - src += src_stride; + src += stride; src0 = (v16u8) __msa_vshf_b(mask, (v16i8) src0, (v16i8) src0); res_hz0 = __msa_dotp_u_h(src0, coeff_hz_vec); - for (row = (height >> 2); row--;) { - LD_UB4(src, src_stride, src1, src2, src3, src4); - src += (4 * src_stride); + LD_UB4(src, stride, src1, src2, src3, src4); + src += (4 * stride); - VSHF_B2_UB(src1, src1, src2, src2, mask, mask, src1, src2); - VSHF_B2_UB(src3, src3, src4, src4, mask, mask, src3, src4); - DOTP_UB4_UH(src1, src2, src3, src4, coeff_hz_vec, coeff_hz_vec, - coeff_hz_vec, coeff_hz_vec, res_hz1, res_hz2, res_hz3, - res_hz4); - MUL4(res_hz1, coeff_vt_vec0, res_hz2, coeff_vt_vec0, res_hz3, - coeff_vt_vec0, res_hz4, coeff_vt_vec0, res_vt0, res_vt1, res_vt2, - res_vt3); + VSHF_B2_UB(src1, src1, src2, src2, mask, mask, src1, src2); + VSHF_B2_UB(src3, src3, src4, src4, mask, mask, src3, src4); + DOTP_UB4_UH(src1, src2, src3, src4, coeff_hz_vec, coeff_hz_vec, + coeff_hz_vec, coeff_hz_vec, res_hz1, res_hz2, res_hz3, res_hz4); + MUL4(res_hz1, coeff_vt_vec0, res_hz2, coeff_vt_vec0, res_hz3, coeff_vt_vec0, + res_hz4, coeff_vt_vec0, res_vt0, res_vt1, res_vt2, res_vt3); - res_vt0 += (res_hz0 * coeff_vt_vec1); - res_vt1 += (res_hz1 * coeff_vt_vec1); - res_vt2 += (res_hz2 * coeff_vt_vec1); - res_vt3 += (res_hz3 * coeff_vt_vec1); + res_vt0 += (res_hz0 * coeff_vt_vec1); + res_vt1 += (res_hz1 * coeff_vt_vec1); + res_vt2 += (res_hz2 * coeff_vt_vec1); + res_vt3 += (res_hz3 * coeff_vt_vec1); - SRARI_H4_UH(res_vt0, res_vt1, res_vt2, res_vt3, 6); - SAT_UH4_UH(res_vt0, res_vt1, res_vt2, res_vt3, 7); - PCKEV_B2_UB(res_vt1, res_vt0, res_vt3, res_vt2, out0, out1); - ST8x4_UB(out0, out1, dst, dst_stride); + SRARI_H4_UH(res_vt0, res_vt1, res_vt2, res_vt3, 6); + SAT_UH4_UH(res_vt0, res_vt1, res_vt2, res_vt3, 7); + PCKEV_B2_UB(res_vt1, res_vt0, res_vt3, res_vt2, out0, out1); + ST8x4_UB(out0, out1, dst, stride); +} - dst += (4 * dst_stride); +static void avc_chroma_hv_8x8_msa(uint8_t *src, uint8_t *dst, int32_t stride, + uint32_t coef_hor0, uint32_t coef_hor1, + uint32_t coef_ver0, uint32_t coef_ver1) +{ + v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8; + v16u8 out0, out1, out2, out3; + v8u16 res_hz0, res_hz1, res_hz2, res_hz3, res_hz4; + v8u16 res_hz5, res_hz6, res_hz7, res_hz8; + v8u16 res_vt0, res_vt1, res_vt2, res_vt3; + v8u16 res_vt4, res_vt5, res_vt6, res_vt7; + v16i8 mask; + v16i8 coeff_hz_vec0 = __msa_fill_b(coef_hor0); + v16i8 coeff_hz_vec1 = __msa_fill_b(coef_hor1); + v16u8 coeff_hz_vec = (v16u8) __msa_ilvr_b(coeff_hz_vec0, coeff_hz_vec1); + v8u16 coeff_vt_vec0 = (v8u16) __msa_fill_h(coef_ver0); + v8u16 coeff_vt_vec1 = (v8u16) __msa_fill_h(coef_ver1); - res_hz0 = res_hz4; + mask = LD_SB(&chroma_mask_arr[32]); + + LD_UB5(src, stride, src0, src1, src2, src3, src4); + src += (5 * stride); + LD_UB4(src, stride, src5, src6, src7, src8); + src0 = (v16u8) __msa_vshf_b(mask, (v16i8) src0, (v16i8) src0); + VSHF_B2_UB(src1, src1, src2, src2, mask, mask, src1, src2); + VSHF_B2_UB(src3, src3, src4, src4, mask, mask, src3, src4); + VSHF_B2_UB(src5, src5, src6, src6, mask, mask, src5, src6); + VSHF_B2_UB(src7, src7, src8, src8, mask, mask, src7, src8); + res_hz0 = __msa_dotp_u_h(src0, coeff_hz_vec); + DOTP_UB4_UH(src1, src2, src3, src4, coeff_hz_vec, coeff_hz_vec, + coeff_hz_vec, coeff_hz_vec, res_hz1, res_hz2, res_hz3, + res_hz4); + DOTP_UB4_UH(src5, src6, src7, src8, coeff_hz_vec, coeff_hz_vec, + coeff_hz_vec, coeff_hz_vec, res_hz5, res_hz6, res_hz7, res_hz8); + MUL4(res_hz1, coeff_vt_vec0, res_hz2, coeff_vt_vec0, res_hz3, + coeff_vt_vec0, res_hz4, coeff_vt_vec0, res_vt0, res_vt1, res_vt2, + res_vt3); + MUL4(res_hz5, coeff_vt_vec0, res_hz6, coeff_vt_vec0, res_hz7, + coeff_vt_vec0, res_hz8, coeff_vt_vec0, res_vt4, res_vt5, res_vt6, + res_vt7); + res_vt0 += (res_hz0 * coeff_vt_vec1); + res_vt1 += (res_hz1 * coeff_vt_vec1); + res_vt2 += (res_hz2 * coeff_vt_vec1); + res_vt3 += (res_hz3 * coeff_vt_vec1); + res_vt4 += (res_hz4 * coeff_vt_vec1); + res_vt5 += (res_hz5 * coeff_vt_vec1); + res_vt6 += (res_hz6 * coeff_vt_vec1); + res_vt7 += (res_hz7 * coeff_vt_vec1); + SRARI_H4_UH(res_vt0, res_vt1, res_vt2, res_vt3, 6); + SRARI_H4_UH(res_vt4, res_vt5, res_vt6, res_vt7, 6); + SAT_UH4_UH(res_vt0, res_vt1, res_vt2, res_vt3, 7); + SAT_UH4_UH(res_vt4, res_vt5, res_vt6, res_vt7, 7); + PCKEV_B2_UB(res_vt1, res_vt0, res_vt3, res_vt2, out0, out1); + PCKEV_B2_UB(res_vt5, res_vt4, res_vt7, res_vt6, out2, out3); + ST8x8_UB(out0, out1, out2, out3, dst, stride); +} + +static void avc_chroma_hv_8w_msa(uint8_t *src, uint8_t *dst, int32_t stride, + uint32_t coef_hor0, uint32_t coef_hor1, + uint32_t coef_ver0, uint32_t coef_ver1, + int32_t height) +{ + if (4 == height) { + avc_chroma_hv_8x4_msa(src, dst, stride, coef_hor0, coef_hor1, coef_ver0, + coef_ver1); + } else if (8 == height) { + avc_chroma_hv_8x8_msa(src, dst, stride, coef_hor0, coef_hor1, coef_ver0, + coef_ver1); } } @@ -1896,8 +1922,7 @@ void ff_put_h264_chroma_mc8_msa(uint8_t *dst, uint8_t *src, av_assert2(x < 8 && y < 8 && x >= 0 && y >= 0); if (x && y) { - avc_chroma_hv_8w_msa(src, stride, dst, - stride, x, (8 - x), y, (8 - y), height); + avc_chroma_hv_8w_msa(src, dst, stride, x, (8 - x), y, (8 - y), height); } else if (x) { avc_chroma_hz_8w_msa(src, dst, stride, x, (8 - x), height); } else if (y) { @@ -1915,8 +1940,7 @@ void ff_put_h264_chroma_mc4_msa(uint8_t *dst, uint8_t *src, av_assert2(x < 8 && y < 8 && x >= 0 && y >= 0); if (x && y) { - avc_chroma_hv_4w_msa(src, stride, dst, - stride, x, (8 - x), y, (8 - y), height); + avc_chroma_hv_4w_msa(src, dst, stride, x, (8 - x), y, (8 - y), height); } else if (x) { avc_chroma_hz_4w_msa(src, dst, stride, x, (8 - x), height); } else if (y) { @@ -1939,8 +1963,7 @@ void ff_put_h264_chroma_mc2_msa(uint8_t *dst, uint8_t *src, av_assert2(x < 8 && y < 8 && x >= 0 && y >= 0); if (x && y) { - avc_chroma_hv_2w_msa(src, stride, dst, - stride, x, (8 - x), y, (8 - y), height); + avc_chroma_hv_2w_msa(src, dst, stride, x, (8 - x), y, (8 - y), height); } else if (x) { avc_chroma_hz_2w_msa(src, dst, stride, x, (8 - x), height); } else if (y) { From 662234a9a22f1cd0f0ac83b8bb1ffadedca90c0a Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Mon, 9 Oct 2017 17:41:40 +0530 Subject: [PATCH 3316/3374] avcodec/mips: Improve avc put mc 21, 23 and 02 msa functions Remove loops and unroll as block sizes are known. Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/h264qpel_msa.c | 1219 +++++++++++++++++++++----------- 1 file changed, 802 insertions(+), 417 deletions(-) diff --git a/libavcodec/mips/h264qpel_msa.c b/libavcodec/mips/h264qpel_msa.c index afc01833122d0..a22a4828c6bb9 100644 --- a/libavcodec/mips/h264qpel_msa.c +++ b/libavcodec/mips/h264qpel_msa.c @@ -45,25 +45,6 @@ out0_m; \ } ) -#define AVC_HORZ_FILTER_SH(in, mask0, mask1, mask2) \ -( { \ - v8i16 out0_m, out1_m; \ - v16i8 tmp0_m, tmp1_m; \ - v16i8 minus5b = __msa_ldi_b(-5); \ - v16i8 plus20b = __msa_ldi_b(20); \ - \ - tmp0_m = __msa_vshf_b((v16i8) mask0, in, in); \ - out0_m = __msa_hadd_s_h(tmp0_m, tmp0_m); \ - \ - tmp0_m = __msa_vshf_b((v16i8) mask1, in, in); \ - out0_m = __msa_dpadd_s_h(out0_m, minus5b, tmp0_m); \ - \ - tmp1_m = __msa_vshf_b((v16i8) (mask2), in, in); \ - out1_m = __msa_dpadd_s_h(out0_m, plus20b, tmp1_m); \ - \ - out1_m; \ -} ) - static const uint8_t luma_mask_arr[16 * 8] = { /* 8 width cases */ 0, 5, 1, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, @@ -148,6 +129,25 @@ static const uint8_t luma_mask_arr[16 * 8] = { hz_out_m; \ } ) +#define AVC_HORZ_FILTER_SH(in0, in1, mask0, mask1, mask2) \ +( { \ + v8i16 out0_m; \ + v16i8 tmp0_m; \ + v16i8 minus5b = __msa_ldi_b(-5); \ + v16i8 plus20b = __msa_ldi_b(20); \ + \ + tmp0_m = __msa_vshf_b((v16i8) mask0, in1, in0); \ + out0_m = __msa_hadd_s_h(tmp0_m, tmp0_m); \ + \ + tmp0_m = __msa_vshf_b((v16i8) mask1, in1, in0); \ + out0_m = __msa_dpadd_s_h(out0_m, minus5b, tmp0_m); \ + \ + tmp0_m = __msa_vshf_b((v16i8) mask2, in1, in0); \ + out0_m = __msa_dpadd_s_h(out0_m, plus20b, tmp0_m); \ + \ + out0_m; \ +} ) + #define AVC_DOT_SH3_SH(in0, in1, in2, coeff0, coeff1, coeff2) \ ( { \ v8i16 out0_m; \ @@ -159,175 +159,17 @@ static const uint8_t luma_mask_arr[16 * 8] = { out0_m; \ } ) -static void avc_luma_vt_4w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height) -{ - int32_t loop_cnt; - int16_t filt_const0 = 0xfb01; - int16_t filt_const1 = 0x1414; - int16_t filt_const2 = 0x1fb; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8; - v16i8 src10_r, src32_r, src54_r, src76_r, src21_r, src43_r, src65_r; - v16i8 src87_r, src2110, src4332, src6554, src8776; - v16i8 filt0, filt1, filt2; - v8i16 out10, out32; - v16u8 out; - - filt0 = (v16i8) __msa_fill_h(filt_const0); - filt1 = (v16i8) __msa_fill_h(filt_const1); - filt2 = (v16i8) __msa_fill_h(filt_const2); - - LD_SB5(src, src_stride, src0, src1, src2, src3, src4); - src += (5 * src_stride); - - ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, - src10_r, src21_r, src32_r, src43_r); - ILVR_D2_SB(src21_r, src10_r, src43_r, src32_r, src2110, src4332); - XORI_B2_128_SB(src2110, src4332); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src5, src6, src7, src8); - src += (4 * src_stride); - - ILVR_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, - src54_r, src65_r, src76_r, src87_r); - ILVR_D2_SB(src65_r, src54_r, src87_r, src76_r, src6554, src8776); - XORI_B2_128_SB(src6554, src8776); - out10 = DPADD_SH3_SH(src2110, src4332, src6554, filt0, filt1, filt2); - out32 = DPADD_SH3_SH(src4332, src6554, src8776, filt0, filt1, filt2); - SRARI_H2_SH(out10, out32, 5); - SAT_SH2_SH(out10, out32, 7); - out = PCKEV_XORI128_UB(out10, out32); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); - - dst += (4 * dst_stride); - src2110 = src6554; - src4332 = src8776; - src4 = src8; - } -} - -static void avc_luma_vt_8w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height) -{ - int32_t loop_cnt; - int16_t filt_const0 = 0xfb01; - int16_t filt_const1 = 0x1414; - int16_t filt_const2 = 0x1fb; - v16i8 src0, src1, src2, src3, src4, src7, src8, src9, src10; - v16i8 src10_r, src32_r, src76_r, src98_r; - v16i8 src21_r, src43_r, src87_r, src109_r; - v8i16 out0_r, out1_r, out2_r, out3_r; - v16i8 filt0, filt1, filt2; - v16u8 out0, out1; - - filt0 = (v16i8) __msa_fill_h(filt_const0); - filt1 = (v16i8) __msa_fill_h(filt_const1); - filt2 = (v16i8) __msa_fill_h(filt_const2); - - LD_SB5(src, src_stride, src0, src1, src2, src3, src4); - src += (5 * src_stride); - - XORI_B5_128_SB(src0, src1, src2, src3, src4); - ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, - src10_r, src21_r, src32_r, src43_r); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src7, src8, src9, src10); - src += (4 * src_stride); - - XORI_B4_128_SB(src7, src8, src9, src10); - ILVR_B4_SB(src7, src4, src8, src7, src9, src8, src10, src9, - src76_r, src87_r, src98_r, src109_r); - out0_r = DPADD_SH3_SH(src10_r, src32_r, src76_r, filt0, filt1, filt2); - out1_r = DPADD_SH3_SH(src21_r, src43_r, src87_r, filt0, filt1, filt2); - out2_r = DPADD_SH3_SH(src32_r, src76_r, src98_r, filt0, filt1, filt2); - out3_r = DPADD_SH3_SH(src43_r, src87_r, src109_r, filt0, filt1, filt2); - SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, 5); - SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); - out0 = PCKEV_XORI128_UB(out0_r, out1_r); - out1 = PCKEV_XORI128_UB(out2_r, out3_r); - ST8x4_UB(out0, out1, dst, dst_stride); - dst += (4 * dst_stride); - - src10_r = src76_r; - src32_r = src98_r; - src21_r = src87_r; - src43_r = src109_r; - src4 = src10; - } -} - -static void avc_luma_vt_16w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height) -{ - int32_t loop_cnt; - int16_t filt_const0 = 0xfb01; - int16_t filt_const1 = 0x1414; - int16_t filt_const2 = 0x1fb; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8; - v16i8 src10_r, src32_r, src54_r, src76_r, src21_r, src43_r, src65_r; - v16i8 src87_r, src10_l, src32_l, src54_l, src76_l, src21_l, src43_l; - v16i8 src65_l, src87_l; - v8i16 out0_r, out1_r, out2_r, out3_r, out0_l, out1_l, out2_l, out3_l; - v16u8 res0, res1, res2, res3; - v16i8 filt0, filt1, filt2; - - filt0 = (v16i8) __msa_fill_h(filt_const0); - filt1 = (v16i8) __msa_fill_h(filt_const1); - filt2 = (v16i8) __msa_fill_h(filt_const2); - - LD_SB5(src, src_stride, src0, src1, src2, src3, src4); - src += (5 * src_stride); - - XORI_B5_128_SB(src0, src1, src2, src3, src4); - ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, - src10_r, src21_r, src32_r, src43_r); - ILVL_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, - src10_l, src21_l, src32_l, src43_l); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src5, src6, src7, src8); - src += (4 * src_stride); - - XORI_B4_128_SB(src5, src6, src7, src8); - ILVR_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, - src54_r, src65_r, src76_r, src87_r); - ILVL_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, - src54_l, src65_l, src76_l, src87_l); - out0_r = DPADD_SH3_SH(src10_r, src32_r, src54_r, filt0, filt1, filt2); - out1_r = DPADD_SH3_SH(src21_r, src43_r, src65_r, filt0, filt1, filt2); - out2_r = DPADD_SH3_SH(src32_r, src54_r, src76_r, filt0, filt1, filt2); - out3_r = DPADD_SH3_SH(src43_r, src65_r, src87_r, filt0, filt1, filt2); - out0_l = DPADD_SH3_SH(src10_l, src32_l, src54_l, filt0, filt1, filt2); - out1_l = DPADD_SH3_SH(src21_l, src43_l, src65_l, filt0, filt1, filt2); - out2_l = DPADD_SH3_SH(src32_l, src54_l, src76_l, filt0, filt1, filt2); - out3_l = DPADD_SH3_SH(src43_l, src65_l, src87_l, filt0, filt1, filt2); - SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, 5); - SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); - SRARI_H4_SH(out0_l, out1_l, out2_l, out3_l, 5); - SAT_SH4_SH(out0_l, out1_l, out2_l, out3_l, 7); - PCKEV_B4_UB(out0_l, out0_r, out1_l, out1_r, out2_l, out2_r, out3_l, - out3_r, res0, res1, res2, res3); - XORI_B4_128_UB(res0, res1, res2, res3); - - ST_UB4(res0, res1, res2, res3, dst, dst_stride); - dst += (4 * dst_stride); - - src10_r = src54_r; - src32_r = src76_r; - src21_r = src65_r; - src43_r = src87_r; - src10_l = src54_l; - src32_l = src76_l; - src21_l = src65_l; - src43_l = src87_l; - src4 = src8; - } -} +#define AVC_DOT_SW3_SW(in0, in1, in2, coeff0, coeff1, coeff2) \ +( { \ + v4i32 out0_m; \ + \ + out0_m = __msa_dotp_s_w((v8i16) in0, (v8i16) coeff0); \ + out0_m = __msa_dpadd_s_w(out0_m, (v8i16) in1, (v8i16) coeff1); \ + out0_m = __msa_dpadd_s_w(out0_m, (v8i16) in2, (v8i16) coeff2); \ + out0_m = __msa_srari_w(out0_m, 10); \ + out0_m = __msa_sat_s_w(out0_m, 7); \ + out0_m; \ +} ) static void avc_luma_mid_4w_msa(const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, @@ -353,7 +195,7 @@ static void avc_luma_mid_4w_msa(const uint8_t *src, int32_t src_stride, PCKOD_D2_SH(hz_out0, hz_out0, hz_out2, hz_out2, hz_out1, hz_out3); - hz_out4 = AVC_HORZ_FILTER_SH(src4, mask0, mask1, mask2); + hz_out4 = AVC_HORZ_FILTER_SH(src4, src4, mask0, mask1, mask2); for (loop_cnt = (height >> 2); loop_cnt--;) { LD_SB4(src, src_stride, src0, src1, src2, src3); @@ -412,21 +254,21 @@ static void avc_luma_mid_8w_msa(const uint8_t *src, int32_t src_stride, XORI_B5_128_SB(src0, src1, src2, src3, src4); src += (5 * src_stride); - hz_out0 = AVC_HORZ_FILTER_SH(src0, mask0, mask1, mask2); - hz_out1 = AVC_HORZ_FILTER_SH(src1, mask0, mask1, mask2); - hz_out2 = AVC_HORZ_FILTER_SH(src2, mask0, mask1, mask2); - hz_out3 = AVC_HORZ_FILTER_SH(src3, mask0, mask1, mask2); - hz_out4 = AVC_HORZ_FILTER_SH(src4, mask0, mask1, mask2); + hz_out0 = AVC_HORZ_FILTER_SH(src0, src0, mask0, mask1, mask2); + hz_out1 = AVC_HORZ_FILTER_SH(src1, src1, mask0, mask1, mask2); + hz_out2 = AVC_HORZ_FILTER_SH(src2, src2, mask0, mask1, mask2); + hz_out3 = AVC_HORZ_FILTER_SH(src3, src3, mask0, mask1, mask2); + hz_out4 = AVC_HORZ_FILTER_SH(src4, src4, mask0, mask1, mask2); for (loop_cnt = (height >> 2); loop_cnt--;) { LD_SB4(src, src_stride, src0, src1, src2, src3); XORI_B4_128_SB(src0, src1, src2, src3); src += (4 * src_stride); - hz_out5 = AVC_HORZ_FILTER_SH(src0, mask0, mask1, mask2); - hz_out6 = AVC_HORZ_FILTER_SH(src1, mask0, mask1, mask2); - hz_out7 = AVC_HORZ_FILTER_SH(src2, mask0, mask1, mask2); - hz_out8 = AVC_HORZ_FILTER_SH(src3, mask0, mask1, mask2); + hz_out5 = AVC_HORZ_FILTER_SH(src0, src0, mask0, mask1, mask2); + hz_out6 = AVC_HORZ_FILTER_SH(src1, src1, mask0, mask1, mask2); + hz_out7 = AVC_HORZ_FILTER_SH(src2, src2, mask0, mask1, mask2); + hz_out8 = AVC_HORZ_FILTER_SH(src3, src3, mask0, mask1, mask2); dst0 = AVC_CALC_DPADD_H_6PIX_2COEFF_SH(hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5); dst1 = AVC_CALC_DPADD_H_6PIX_2COEFF_SH(hz_out1, hz_out2, hz_out3, @@ -564,186 +406,6 @@ static void avc_luma_midh_qrt_16w_msa(const uint8_t *src, int32_t src_stride, } } -static void avc_luma_midv_qrt_4w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height, uint8_t ver_offset) -{ - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4; - v16i8 mask0, mask1, mask2; - v8i16 hz_out0, hz_out1, hz_out2, hz_out3; - v8i16 hz_out4, hz_out5, hz_out6, hz_out7, hz_out8; - v8i16 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; - - LD_SB3(&luma_mask_arr[48], 16, mask0, mask1, mask2); - LD_SB5(src, src_stride, src0, src1, src2, src3, src4); - src += (5 * src_stride); - - XORI_B5_128_SB(src0, src1, src2, src3, src4); - - hz_out0 = AVC_XOR_VSHF_B_AND_APPLY_6TAP_HORIZ_FILT_SH(src0, src1, - mask0, mask1, mask2); - hz_out2 = AVC_XOR_VSHF_B_AND_APPLY_6TAP_HORIZ_FILT_SH(src2, src3, - mask0, mask1, mask2); - - PCKOD_D2_SH(hz_out0, hz_out0, hz_out2, hz_out2, hz_out1, hz_out3); - - hz_out4 = AVC_HORZ_FILTER_SH(src4, mask0, mask1, mask2); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - XORI_B4_128_SB(src0, src1, src2, src3); - - hz_out5 = AVC_XOR_VSHF_B_AND_APPLY_6TAP_HORIZ_FILT_SH(src0, src1, - mask0, mask1, - mask2); - hz_out7 = AVC_XOR_VSHF_B_AND_APPLY_6TAP_HORIZ_FILT_SH(src2, src3, - mask0, mask1, - mask2); - - PCKOD_D2_SH(hz_out5, hz_out5, hz_out7, hz_out7, hz_out6, hz_out8); - - dst0 = AVC_CALC_DPADD_H_6PIX_2COEFF_SH(hz_out0, hz_out1, hz_out2, - hz_out3, hz_out4, hz_out5); - dst2 = AVC_CALC_DPADD_H_6PIX_2COEFF_SH(hz_out1, hz_out2, hz_out3, - hz_out4, hz_out5, hz_out6); - dst4 = AVC_CALC_DPADD_H_6PIX_2COEFF_SH(hz_out2, hz_out3, hz_out4, - hz_out5, hz_out6, hz_out7); - dst6 = AVC_CALC_DPADD_H_6PIX_2COEFF_SH(hz_out3, hz_out4, hz_out5, - hz_out6, hz_out7, hz_out8); - - if (ver_offset) { - dst1 = __msa_srari_h(hz_out3, 5); - dst3 = __msa_srari_h(hz_out4, 5); - dst5 = __msa_srari_h(hz_out5, 5); - dst7 = __msa_srari_h(hz_out6, 5); - } else { - dst1 = __msa_srari_h(hz_out2, 5); - dst3 = __msa_srari_h(hz_out3, 5); - dst5 = __msa_srari_h(hz_out4, 5); - dst7 = __msa_srari_h(hz_out5, 5); - } - - SAT_SH4_SH(dst1, dst3, dst5, dst7, 7); - - dst0 = __msa_aver_s_h(dst0, dst1); - dst1 = __msa_aver_s_h(dst2, dst3); - dst2 = __msa_aver_s_h(dst4, dst5); - dst3 = __msa_aver_s_h(dst6, dst7); - - PCKEV_B2_SB(dst1, dst0, dst3, dst2, src0, src1); - XORI_B2_128_SB(src0, src1); - - ST4x4_UB(src0, src1, 0, 2, 0, 2, dst, dst_stride); - - dst += (4 * dst_stride); - hz_out0 = hz_out4; - hz_out1 = hz_out5; - hz_out2 = hz_out6; - hz_out3 = hz_out7; - hz_out4 = hz_out8; - } -} - -static void avc_luma_midv_qrt_8w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height, uint8_t ver_offset) -{ - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4; - v16i8 mask0, mask1, mask2; - v8i16 hz_out0, hz_out1, hz_out2, hz_out3; - v8i16 hz_out4, hz_out5, hz_out6, hz_out7, hz_out8; - v8i16 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; - v16u8 out; - - LD_SB3(&luma_mask_arr[0], 16, mask0, mask1, mask2); - - LD_SB5(src, src_stride, src0, src1, src2, src3, src4); - XORI_B5_128_SB(src0, src1, src2, src3, src4); - src += (5 * src_stride); - - hz_out0 = AVC_HORZ_FILTER_SH(src0, mask0, mask1, mask2); - hz_out1 = AVC_HORZ_FILTER_SH(src1, mask0, mask1, mask2); - hz_out2 = AVC_HORZ_FILTER_SH(src2, mask0, mask1, mask2); - hz_out3 = AVC_HORZ_FILTER_SH(src3, mask0, mask1, mask2); - hz_out4 = AVC_HORZ_FILTER_SH(src4, mask0, mask1, mask2); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src0, src1, src2, src3); - XORI_B4_128_SB(src0, src1, src2, src3); - src += (4 * src_stride); - - hz_out5 = AVC_HORZ_FILTER_SH(src0, mask0, mask1, mask2); - hz_out6 = AVC_HORZ_FILTER_SH(src1, mask0, mask1, mask2); - hz_out7 = AVC_HORZ_FILTER_SH(src2, mask0, mask1, mask2); - hz_out8 = AVC_HORZ_FILTER_SH(src3, mask0, mask1, mask2); - - dst0 = AVC_CALC_DPADD_H_6PIX_2COEFF_SH(hz_out0, hz_out1, hz_out2, - hz_out3, hz_out4, hz_out5); - dst2 = AVC_CALC_DPADD_H_6PIX_2COEFF_SH(hz_out1, hz_out2, hz_out3, - hz_out4, hz_out5, hz_out6); - dst4 = AVC_CALC_DPADD_H_6PIX_2COEFF_SH(hz_out2, hz_out3, hz_out4, - hz_out5, hz_out6, hz_out7); - dst6 = AVC_CALC_DPADD_H_6PIX_2COEFF_SH(hz_out3, hz_out4, hz_out5, - hz_out6, hz_out7, hz_out8); - - if (ver_offset) { - dst1 = __msa_srari_h(hz_out3, 5); - dst3 = __msa_srari_h(hz_out4, 5); - dst5 = __msa_srari_h(hz_out5, 5); - dst7 = __msa_srari_h(hz_out6, 5); - } else { - dst1 = __msa_srari_h(hz_out2, 5); - dst3 = __msa_srari_h(hz_out3, 5); - dst5 = __msa_srari_h(hz_out4, 5); - dst7 = __msa_srari_h(hz_out5, 5); - } - - SAT_SH4_SH(dst1, dst3, dst5, dst7, 7); - - dst0 = __msa_aver_s_h(dst0, dst1); - dst1 = __msa_aver_s_h(dst2, dst3); - dst2 = __msa_aver_s_h(dst4, dst5); - dst3 = __msa_aver_s_h(dst6, dst7); - - out = PCKEV_XORI128_UB(dst0, dst0); - ST8x1_UB(out, dst); - dst += dst_stride; - out = PCKEV_XORI128_UB(dst1, dst1); - ST8x1_UB(out, dst); - dst += dst_stride; - out = PCKEV_XORI128_UB(dst2, dst2); - ST8x1_UB(out, dst); - dst += dst_stride; - out = PCKEV_XORI128_UB(dst3, dst3); - ST8x1_UB(out, dst); - dst += dst_stride; - - hz_out0 = hz_out4; - hz_out1 = hz_out5; - hz_out2 = hz_out6; - hz_out3 = hz_out7; - hz_out4 = hz_out8; - } -} - -static void avc_luma_midv_qrt_16w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height, uint8_t vert_offset) -{ - uint32_t multiple8_cnt; - - for (multiple8_cnt = 2; multiple8_cnt--;) { - avc_luma_midv_qrt_8w_msa(src, src_stride, dst, dst_stride, height, - vert_offset); - - src += 8; - dst += 8; - } -} - static void avc_luma_hv_qrt_4w_msa(const uint8_t *src_x, const uint8_t *src_y, int32_t src_stride, uint8_t *dst, int32_t dst_stride, int32_t height) @@ -852,10 +514,10 @@ static void avc_luma_hv_qrt_8w_msa(const uint8_t *src_x, const uint8_t *src_y, XORI_B4_128_SB(src_hz0, src_hz1, src_hz2, src_hz3); src_x += (4 * src_stride); - hz_out0 = AVC_HORZ_FILTER_SH(src_hz0, mask0, mask1, mask2); - hz_out1 = AVC_HORZ_FILTER_SH(src_hz1, mask0, mask1, mask2); - hz_out2 = AVC_HORZ_FILTER_SH(src_hz2, mask0, mask1, mask2); - hz_out3 = AVC_HORZ_FILTER_SH(src_hz3, mask0, mask1, mask2); + hz_out0 = AVC_HORZ_FILTER_SH(src_hz0, src_hz0, mask0, mask1, mask2); + hz_out1 = AVC_HORZ_FILTER_SH(src_hz1, src_hz1, mask0, mask1, mask2); + hz_out2 = AVC_HORZ_FILTER_SH(src_hz2, src_hz2, mask0, mask1, mask2); + hz_out3 = AVC_HORZ_FILTER_SH(src_hz3, src_hz3, mask0, mask1, mask2); SRARI_H4_SH(hz_out0, hz_out1, hz_out2, hz_out3, 5); SAT_SH4_SH(hz_out0, hz_out1, hz_out2, hz_out3, 7); @@ -1663,7 +1325,7 @@ static void avc_luma_mid_and_aver_dst_4x4_msa(const uint8_t *src, PCKOD_D2_SH(hz_out0, hz_out0, hz_out2, hz_out2, hz_out1, hz_out3); - hz_out4 = AVC_HORZ_FILTER_SH(src4, mask0, mask1, mask2); + hz_out4 = AVC_HORZ_FILTER_SH(src4, src4, mask0, mask1, mask2); LD_SB4(src, src_stride, src0, src1, src2, src3); XORI_B4_128_SB(src0, src1, src2, src3); @@ -1711,21 +1373,21 @@ static void avc_luma_mid_and_aver_dst_8w_msa(const uint8_t *src, XORI_B5_128_SB(src0, src1, src2, src3, src4); src += (5 * src_stride); - hz_out0 = AVC_HORZ_FILTER_SH(src0, mask0, mask1, mask2); - hz_out1 = AVC_HORZ_FILTER_SH(src1, mask0, mask1, mask2); - hz_out2 = AVC_HORZ_FILTER_SH(src2, mask0, mask1, mask2); - hz_out3 = AVC_HORZ_FILTER_SH(src3, mask0, mask1, mask2); - hz_out4 = AVC_HORZ_FILTER_SH(src4, mask0, mask1, mask2); + hz_out0 = AVC_HORZ_FILTER_SH(src0, src0, mask0, mask1, mask2); + hz_out1 = AVC_HORZ_FILTER_SH(src1, src1, mask0, mask1, mask2); + hz_out2 = AVC_HORZ_FILTER_SH(src2, src2, mask0, mask1, mask2); + hz_out3 = AVC_HORZ_FILTER_SH(src3, src3, mask0, mask1, mask2); + hz_out4 = AVC_HORZ_FILTER_SH(src4, src4, mask0, mask1, mask2); for (loop_cnt = (height >> 2); loop_cnt--;) { LD_SB4(src, src_stride, src0, src1, src2, src3); XORI_B4_128_SB(src0, src1, src2, src3); src += (4 * src_stride); - hz_out5 = AVC_HORZ_FILTER_SH(src0, mask0, mask1, mask2); - hz_out6 = AVC_HORZ_FILTER_SH(src1, mask0, mask1, mask2); - hz_out7 = AVC_HORZ_FILTER_SH(src2, mask0, mask1, mask2); - hz_out8 = AVC_HORZ_FILTER_SH(src3, mask0, mask1, mask2); + hz_out5 = AVC_HORZ_FILTER_SH(src0, src0, mask0, mask1, mask2); + hz_out6 = AVC_HORZ_FILTER_SH(src1, src1, mask0, mask1, mask2); + hz_out7 = AVC_HORZ_FILTER_SH(src2, src2, mask0, mask1, mask2); + hz_out8 = AVC_HORZ_FILTER_SH(src3, src3, mask0, mask1, mask2); res0 = AVC_CALC_DPADD_H_6PIX_2COEFF_SH(hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5); @@ -1909,7 +1571,7 @@ static void avc_luma_midv_qrt_and_aver_dst_4w_msa(const uint8_t *src, PCKOD_D2_SH(hz_out0, hz_out0, hz_out2, hz_out2, hz_out1, hz_out3); - hz_out4 = AVC_HORZ_FILTER_SH(src4, mask0, mask1, mask2); + hz_out4 = AVC_HORZ_FILTER_SH(src4, src4, mask0, mask1, mask2); for (loop_cnt = (height >> 1); loop_cnt--;) { LD_SB2(src, src_stride, src0, src1); @@ -1981,11 +1643,11 @@ static void avc_luma_midv_qrt_and_aver_dst_8w_msa(const uint8_t *src, XORI_B5_128_SB(src0, src1, src2, src3, src4); src += (5 * src_stride); - hz_out0 = AVC_HORZ_FILTER_SH(src0, mask0, mask1, mask2); - hz_out1 = AVC_HORZ_FILTER_SH(src1, mask0, mask1, mask2); - hz_out2 = AVC_HORZ_FILTER_SH(src2, mask0, mask1, mask2); - hz_out3 = AVC_HORZ_FILTER_SH(src3, mask0, mask1, mask2); - hz_out4 = AVC_HORZ_FILTER_SH(src4, mask0, mask1, mask2); + hz_out0 = AVC_HORZ_FILTER_SH(src0, src0, mask0, mask1, mask2); + hz_out1 = AVC_HORZ_FILTER_SH(src1, src1, mask0, mask1, mask2); + hz_out2 = AVC_HORZ_FILTER_SH(src2, src2, mask0, mask1, mask2); + hz_out3 = AVC_HORZ_FILTER_SH(src3, src3, mask0, mask1, mask2); + hz_out4 = AVC_HORZ_FILTER_SH(src4, src4, mask0, mask1, mask2); for (loop_cnt = (height >> 2); loop_cnt--;) { LD_SB4(src, src_stride, src0, src1, src2, src3); @@ -1994,10 +1656,10 @@ static void avc_luma_midv_qrt_and_aver_dst_8w_msa(const uint8_t *src, LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - hz_out5 = AVC_HORZ_FILTER_SH(src0, mask0, mask1, mask2); - hz_out6 = AVC_HORZ_FILTER_SH(src1, mask0, mask1, mask2); - hz_out7 = AVC_HORZ_FILTER_SH(src2, mask0, mask1, mask2); - hz_out8 = AVC_HORZ_FILTER_SH(src3, mask0, mask1, mask2); + hz_out5 = AVC_HORZ_FILTER_SH(src0, src0, mask0, mask1, mask2); + hz_out6 = AVC_HORZ_FILTER_SH(src1, src1, mask0, mask1, mask2); + hz_out7 = AVC_HORZ_FILTER_SH(src2, src2, mask0, mask1, mask2); + hz_out8 = AVC_HORZ_FILTER_SH(src3, src3, mask0, mask1, mask2); res0 = AVC_CALC_DPADD_H_6PIX_2COEFF_SH(hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5); @@ -2156,10 +1818,10 @@ static void avc_luma_hv_qrt_and_aver_dst_8x8_msa(const uint8_t *src_x, src_x += (4 * src_stride); LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - hz_out0 = AVC_HORZ_FILTER_SH(src_hz0, mask0, mask1, mask2); - hz_out1 = AVC_HORZ_FILTER_SH(src_hz1, mask0, mask1, mask2); - hz_out2 = AVC_HORZ_FILTER_SH(src_hz2, mask0, mask1, mask2); - hz_out3 = AVC_HORZ_FILTER_SH(src_hz3, mask0, mask1, mask2); + hz_out0 = AVC_HORZ_FILTER_SH(src_hz0, src_hz0, mask0, mask1, mask2); + hz_out1 = AVC_HORZ_FILTER_SH(src_hz1, src_hz1, mask0, mask1, mask2); + hz_out2 = AVC_HORZ_FILTER_SH(src_hz2, src_hz2, mask0, mask1, mask2); + hz_out3 = AVC_HORZ_FILTER_SH(src_hz3, src_hz3, mask0, mask1, mask2); SRARI_H4_SH(hz_out0, hz_out1, hz_out2, hz_out3, 5); SAT_SH4_SH(hz_out0, hz_out1, hz_out2, hz_out3, 7); LD_SB4(src_y, src_stride, src_vt5, src_vt6, src_vt7, src_vt8); @@ -3193,57 +2855,780 @@ void ff_put_h264_qpel4_mc33_msa(uint8_t *dst, const uint8_t *src, void ff_put_h264_qpel16_mc21_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_midv_qrt_16w_msa(src - (2 * stride) - 2, - stride, dst, stride, 16, 0); + uint8_t *dst_tmp = dst; + const uint8_t *src_tmp = src - (2 * stride) - 2; + uint32_t multiple8_cnt, loop_cnt; + const int32_t filt_const0 = 0xfffb0001; + const int32_t filt_const1 = 0x140014; + const int32_t filt_const2 = 0x1fffb; + v16u8 out0, out1; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, mask0, mask1; + v16i8 mask2; + v8i16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; + v8i16 hz_out7, hz_out8, dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; + v8i16 hz_out10_r, hz_out21_r, hz_out32_r, hz_out43_r, hz_out54_r; + v8i16 hz_out65_r, hz_out76_r, hz_out87_r, hz_out10_l, hz_out21_l; + v8i16 hz_out32_l, hz_out43_l, hz_out54_l, hz_out65_l, hz_out76_l; + v8i16 hz_out87_l, filt0, filt1, filt2; + v4i32 tmp0, tmp1; + + filt0 = (v8i16) __msa_fill_w(filt_const0); + filt1 = (v8i16) __msa_fill_w(filt_const1); + filt2 = (v8i16) __msa_fill_w(filt_const2); + + LD_SB3(&luma_mask_arr[0], 16, mask0, mask1, mask2); + + for (multiple8_cnt = 2; multiple8_cnt--;) { + dst = dst_tmp; + src = src_tmp; + + LD_SB5(src, stride, src0, src1, src2, src3, src4); + XORI_B5_128_SB(src0, src1, src2, src3, src4); + src += (5 * stride); + + hz_out0 = AVC_HORZ_FILTER_SH(src0, src0, mask0, mask1, mask2); + hz_out1 = AVC_HORZ_FILTER_SH(src1, src1, mask0, mask1, mask2); + hz_out2 = AVC_HORZ_FILTER_SH(src2, src2, mask0, mask1, mask2); + hz_out3 = AVC_HORZ_FILTER_SH(src3, src3, mask0, mask1, mask2); + hz_out4 = AVC_HORZ_FILTER_SH(src4, src4, mask0, mask1, mask2); + + for (loop_cnt = 4; loop_cnt--;) { + LD_SB4(src, stride, src5, src6, src7, src8); + src += (4 * stride); + + XORI_B4_128_SB(src5, src6, src7, src8); + + hz_out5 = AVC_HORZ_FILTER_SH(src5, src5, mask0, mask1, mask2); + hz_out6 = AVC_HORZ_FILTER_SH(src6, src6, mask0, mask1, mask2); + hz_out7 = AVC_HORZ_FILTER_SH(src7, src7, mask0, mask1, mask2); + hz_out8 = AVC_HORZ_FILTER_SH(src8, src8, mask0, mask1, mask2); + + ILVR_H4_SH(hz_out1, hz_out0, hz_out2, hz_out1, hz_out3, hz_out2, + hz_out4, hz_out3, hz_out10_r, hz_out21_r, hz_out32_r, + hz_out43_r); + ILVL_H4_SH(hz_out1, hz_out0, hz_out2, hz_out1, hz_out3, hz_out2, + hz_out4, hz_out3, hz_out10_l, hz_out21_l, hz_out32_l, + hz_out43_l); + ILVR_H4_SH(hz_out5, hz_out4, hz_out6, hz_out5, hz_out7, hz_out6, + hz_out8, hz_out7, hz_out54_r, hz_out65_r, hz_out76_r, + hz_out87_r); + ILVL_H4_SH(hz_out5, hz_out4, hz_out6, hz_out5, hz_out7, hz_out6, + hz_out8, hz_out7, hz_out54_l, hz_out65_l, hz_out76_l, + hz_out87_l); + + tmp0 = AVC_DOT_SW3_SW(hz_out10_r, hz_out32_r, hz_out54_r, filt0, + filt1, filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out10_l, hz_out32_l, hz_out54_l, filt0, + filt1, filt2); + dst0 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + tmp0 = AVC_DOT_SW3_SW(hz_out21_r, hz_out43_r, hz_out65_r, filt0, + filt1, filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out21_l, hz_out43_l, hz_out65_l, filt0, + filt1, filt2); + dst2 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + tmp0 = AVC_DOT_SW3_SW(hz_out32_r, hz_out54_r, hz_out76_r, filt0, + filt1, filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out32_l, hz_out54_l, hz_out76_l, filt0, + filt1, filt2); + dst4 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + tmp0 = AVC_DOT_SW3_SW(hz_out43_r, hz_out65_r, hz_out87_r, filt0, + filt1, filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out43_l, hz_out65_l, hz_out87_l, filt0, + filt1, filt2); + dst6 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + + dst1 = __msa_srari_h(hz_out2, 5); + dst3 = __msa_srari_h(hz_out3, 5); + dst5 = __msa_srari_h(hz_out4, 5); + dst7 = __msa_srari_h(hz_out5, 5); + SAT_SH4_SH(dst1, dst3, dst5, dst7, 7); + + dst0 = __msa_aver_s_h(dst0, dst1); + dst1 = __msa_aver_s_h(dst2, dst3); + dst2 = __msa_aver_s_h(dst4, dst5); + dst3 = __msa_aver_s_h(dst6, dst7); + + out0 = PCKEV_XORI128_UB(dst0, dst1); + out1 = PCKEV_XORI128_UB(dst2, dst3); + ST8x4_UB(out0, out1, dst, stride); + dst += (4 * stride); + + hz_out0 = hz_out4; + hz_out1 = hz_out5; + hz_out2 = hz_out6; + hz_out3 = hz_out7; + hz_out4 = hz_out8; + } + + src_tmp += 8; + dst_tmp += 8; + } } void ff_put_h264_qpel16_mc23_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_midv_qrt_16w_msa(src - (2 * stride) - 2, - stride, dst, stride, 16, 1); + uint8_t *dst_tmp = dst; + const uint8_t *src_tmp = src - (2 * stride) - 2; + uint32_t multiple8_cnt, loop_cnt; + const int32_t filt_const0 = 0xfffb0001; + const int32_t filt_const1 = 0x140014; + const int32_t filt_const2 = 0x1fffb; + v16u8 out0, out1; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, mask0, mask1; + v16i8 mask2; + v8i16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; + v8i16 hz_out7, hz_out8, dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; + v8i16 hz_out10_r, hz_out21_r, hz_out32_r, hz_out43_r, hz_out54_r; + v8i16 hz_out65_r, hz_out76_r, hz_out87_r, hz_out10_l, hz_out21_l; + v8i16 hz_out32_l, hz_out43_l, hz_out54_l, hz_out65_l, hz_out76_l; + v8i16 hz_out87_l, filt0, filt1, filt2; + v4i32 tmp0, tmp1; + + filt0 = (v8i16) __msa_fill_w(filt_const0); + filt1 = (v8i16) __msa_fill_w(filt_const1); + filt2 = (v8i16) __msa_fill_w(filt_const2); + + LD_SB3(&luma_mask_arr[0], 16, mask0, mask1, mask2); + + for (multiple8_cnt = 2; multiple8_cnt--;) { + dst = dst_tmp; + src = src_tmp; + + LD_SB5(src, stride, src0, src1, src2, src3, src4); + XORI_B5_128_SB(src0, src1, src2, src3, src4); + src += (5 * stride); + + hz_out0 = AVC_HORZ_FILTER_SH(src0, src0, mask0, mask1, mask2); + hz_out1 = AVC_HORZ_FILTER_SH(src1, src1, mask0, mask1, mask2); + hz_out2 = AVC_HORZ_FILTER_SH(src2, src2, mask0, mask1, mask2); + hz_out3 = AVC_HORZ_FILTER_SH(src3, src3, mask0, mask1, mask2); + hz_out4 = AVC_HORZ_FILTER_SH(src4, src4, mask0, mask1, mask2); + + for (loop_cnt = 4; loop_cnt--;) { + LD_SB4(src, stride, src5, src6, src7, src8); + src += (4 * stride); + + XORI_B4_128_SB(src5, src6, src7, src8); + + hz_out5 = AVC_HORZ_FILTER_SH(src5, src5, mask0, mask1, mask2); + hz_out6 = AVC_HORZ_FILTER_SH(src6, src6, mask0, mask1, mask2); + hz_out7 = AVC_HORZ_FILTER_SH(src7, src7, mask0, mask1, mask2); + hz_out8 = AVC_HORZ_FILTER_SH(src8, src8, mask0, mask1, mask2); + + ILVR_H4_SH(hz_out1, hz_out0, hz_out2, hz_out1, hz_out3, hz_out2, + hz_out4, hz_out3, hz_out10_r, hz_out21_r, hz_out32_r, + hz_out43_r); + ILVL_H4_SH(hz_out1, hz_out0, hz_out2, hz_out1, hz_out3, hz_out2, + hz_out4, hz_out3, hz_out10_l, hz_out21_l, hz_out32_l, + hz_out43_l); + ILVR_H4_SH(hz_out5, hz_out4, hz_out6, hz_out5, hz_out7, hz_out6, + hz_out8, hz_out7, hz_out54_r, hz_out65_r, hz_out76_r, + hz_out87_r); + ILVL_H4_SH(hz_out5, hz_out4, hz_out6, hz_out5, hz_out7, hz_out6, + hz_out8, hz_out7, hz_out54_l, hz_out65_l, hz_out76_l, + hz_out87_l); + + tmp0 = AVC_DOT_SW3_SW(hz_out10_r, hz_out32_r, hz_out54_r, filt0, + filt1, filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out10_l, hz_out32_l, hz_out54_l, filt0, + filt1, filt2); + dst0 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + tmp0 = AVC_DOT_SW3_SW(hz_out21_r, hz_out43_r, hz_out65_r, filt0, + filt1, filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out21_l, hz_out43_l, hz_out65_l, filt0, + filt1, filt2); + dst2 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + tmp0 = AVC_DOT_SW3_SW(hz_out32_r, hz_out54_r, hz_out76_r, filt0, + filt1, filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out32_l, hz_out54_l, hz_out76_l, filt0, + filt1, filt2); + dst4 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + tmp0 = AVC_DOT_SW3_SW(hz_out43_r, hz_out65_r, hz_out87_r, filt0, + filt1, filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out43_l, hz_out65_l, hz_out87_l, filt0, + filt1, filt2); + dst6 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + + dst1 = __msa_srari_h(hz_out3, 5); + dst3 = __msa_srari_h(hz_out4, 5); + dst5 = __msa_srari_h(hz_out5, 5); + dst7 = __msa_srari_h(hz_out6, 5); + SAT_SH4_SH(dst1, dst3, dst5, dst7, 7); + + dst0 = __msa_aver_s_h(dst0, dst1); + dst1 = __msa_aver_s_h(dst2, dst3); + dst2 = __msa_aver_s_h(dst4, dst5); + dst3 = __msa_aver_s_h(dst6, dst7); + + out0 = PCKEV_XORI128_UB(dst0, dst1); + out1 = PCKEV_XORI128_UB(dst2, dst3); + ST8x4_UB(out0, out1, dst, stride); + dst += (4 * stride); + + hz_out0 = hz_out4; + hz_out1 = hz_out5; + hz_out2 = hz_out6; + hz_out3 = hz_out7; + hz_out4 = hz_out8; + } + + src_tmp += 8; + dst_tmp += 8; + } } void ff_put_h264_qpel8_mc21_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_midv_qrt_8w_msa(src - (2 * stride) - 2, stride, dst, stride, 8, 0); + const int32_t filt_const0 = 0xfffb0001; + const int32_t filt_const1 = 0x140014; + const int32_t filt_const2 = 0x1fffb; + v16u8 out0, out1; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; + v16i8 src11, src12, mask0, mask1, mask2; + v8i16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; + v8i16 hz_out7, hz_out8, hz_out9, hz_out10, hz_out11, hz_out12; + v8i16 hz_out10_r, hz_out21_r, hz_out32_r, hz_out43_r, hz_out54_r; + v8i16 hz_out65_r, hz_out76_r, hz_out87_r, hz_out89_r, hz_out910_r; + v8i16 hz_out1110_r, hz_out1211_r, dst0, dst1, dst2, dst3; + v8i16 hz_out10_l, hz_out21_l, hz_out32_l, hz_out43_l, hz_out54_l; + v8i16 hz_out65_l, hz_out76_l, hz_out87_l, hz_out89_l, hz_out910_l; + v8i16 hz_out1110_l, hz_out1211_l, filt0, filt1, filt2; + v4i32 tmp0, tmp1; + + LD_SB3(&luma_mask_arr[0], 16, mask0, mask1, mask2); + + filt0 = (v8i16) __msa_fill_w(filt_const0); + filt1 = (v8i16) __msa_fill_w(filt_const1); + filt2 = (v8i16) __msa_fill_w(filt_const2); + + src -= ((2 * stride) + 2); + + LD_SB5(src, stride, src0, src1, src2, src3, src4); + XORI_B5_128_SB(src0, src1, src2, src3, src4); + src += (5 * stride); + + hz_out0 = AVC_HORZ_FILTER_SH(src0, src0, mask0, mask1, mask2); + hz_out1 = AVC_HORZ_FILTER_SH(src1, src1, mask0, mask1, mask2); + hz_out2 = AVC_HORZ_FILTER_SH(src2, src2, mask0, mask1, mask2); + hz_out3 = AVC_HORZ_FILTER_SH(src3, src3, mask0, mask1, mask2); + hz_out4 = AVC_HORZ_FILTER_SH(src4, src4, mask0, mask1, mask2); + + LD_SB4(src, stride, src5, src6, src7, src8); + src += (4 * stride); + XORI_B4_128_SB(src5, src6, src7, src8); + + hz_out5 = AVC_HORZ_FILTER_SH(src5, src5, mask0, mask1, mask2); + hz_out6 = AVC_HORZ_FILTER_SH(src6, src6, mask0, mask1, mask2); + hz_out7 = AVC_HORZ_FILTER_SH(src7, src7, mask0, mask1, mask2); + hz_out8 = AVC_HORZ_FILTER_SH(src8, src8, mask0, mask1, mask2); + + ILVR_H4_SH(hz_out1, hz_out0, hz_out2, hz_out1, hz_out3, hz_out2, hz_out4, + hz_out3, hz_out10_r, hz_out21_r, hz_out32_r, hz_out43_r); + ILVL_H4_SH(hz_out1, hz_out0, hz_out2, hz_out1, hz_out3, hz_out2, hz_out4, + hz_out3, hz_out10_l, hz_out21_l, hz_out32_l, hz_out43_l); + ILVR_H4_SH(hz_out5, hz_out4, hz_out6, hz_out5, hz_out7, hz_out6, hz_out8, + hz_out7, hz_out54_r, hz_out65_r, hz_out76_r, hz_out87_r); + ILVL_H4_SH(hz_out5, hz_out4, hz_out6, hz_out5, hz_out7, hz_out6, hz_out8, + hz_out7, hz_out54_l, hz_out65_l, hz_out76_l, hz_out87_l); + + tmp0 = AVC_DOT_SW3_SW(hz_out10_r, hz_out32_r, hz_out54_r, filt0, filt1, + filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out10_l, hz_out32_l, hz_out54_l, filt0, filt1, + filt2); + dst0 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + tmp0 = AVC_DOT_SW3_SW(hz_out21_r, hz_out43_r, hz_out65_r, filt0, filt1, + filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out21_l, hz_out43_l, hz_out65_l, filt0, filt1, + filt2); + dst1 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + tmp0 = AVC_DOT_SW3_SW(hz_out32_r, hz_out54_r, hz_out76_r, filt0, filt1, + filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out32_l, hz_out54_l, hz_out76_l, filt0, filt1, + filt2); + dst2 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + tmp0 = AVC_DOT_SW3_SW(hz_out43_r, hz_out65_r, hz_out87_r, filt0, filt1, + filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out43_l, hz_out65_l, hz_out87_l, filt0, filt1, + filt2); + dst3 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + + SRARI_H4_SH(hz_out2, hz_out3, hz_out4, hz_out5, 5); + SAT_SH4_SH(hz_out2, hz_out3, hz_out4, hz_out5, 7); + + dst0 = __msa_aver_s_h(dst0, hz_out2); + dst1 = __msa_aver_s_h(dst1, hz_out3); + dst2 = __msa_aver_s_h(dst2, hz_out4); + dst3 = __msa_aver_s_h(dst3, hz_out5); + + out0 = PCKEV_XORI128_UB(dst0, dst1); + out1 = PCKEV_XORI128_UB(dst2, dst3); + ST8x4_UB(out0, out1, dst, stride); + dst += (4 * stride); + + LD_SB4(src, stride, src9, src10, src11, src12); + XORI_B4_128_SB(src9, src10, src11, src12); + hz_out9 = AVC_HORZ_FILTER_SH(src9, src9, mask0, mask1, mask2); + hz_out10 = AVC_HORZ_FILTER_SH(src10, src10, mask0, mask1, mask2); + hz_out11 = AVC_HORZ_FILTER_SH(src11, src11, mask0, mask1, mask2); + hz_out12 = AVC_HORZ_FILTER_SH(src12, src12, mask0, mask1, mask2); + ILVR_H4_SH(hz_out9, hz_out8, hz_out10, hz_out9, hz_out11, hz_out10, + hz_out12, hz_out11, hz_out89_r, hz_out910_r, hz_out1110_r, + hz_out1211_r); + ILVL_H4_SH(hz_out9, hz_out8, hz_out10, hz_out9, hz_out11, hz_out10, + hz_out12, hz_out11, hz_out89_l, hz_out910_l, hz_out1110_l, + hz_out1211_l); + tmp0 = AVC_DOT_SW3_SW(hz_out54_r, hz_out76_r, hz_out89_r, filt0, filt1, + filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out54_l, hz_out76_l, hz_out89_l, filt0, filt1, + filt2); + dst0 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + tmp0 = AVC_DOT_SW3_SW(hz_out65_r, hz_out87_r, hz_out910_r, filt0, filt1, + filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out65_l, hz_out87_l, hz_out910_l, filt0, filt1, + filt2); + dst1 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + tmp0 = AVC_DOT_SW3_SW(hz_out76_r, hz_out89_r, hz_out1110_r, filt0, filt1, + filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out76_l, hz_out89_l, hz_out1110_l, filt0, filt1, + filt2); + dst2 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + tmp0 = AVC_DOT_SW3_SW(hz_out87_r, hz_out910_r, hz_out1211_r, filt0, filt1, + filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out87_l, hz_out910_l, hz_out1211_l, filt0, filt1, + filt2); + dst3 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + + SRARI_H4_SH(hz_out6, hz_out7, hz_out8, hz_out9, 5); + SAT_SH4_SH(hz_out6, hz_out7, hz_out8, hz_out9, 7); + + dst0 = __msa_aver_s_h(dst0, hz_out6); + dst1 = __msa_aver_s_h(dst1, hz_out7); + dst2 = __msa_aver_s_h(dst2, hz_out8); + dst3 = __msa_aver_s_h(dst3, hz_out9); + + out0 = PCKEV_XORI128_UB(dst0, dst1); + out1 = PCKEV_XORI128_UB(dst2, dst3); + ST8x4_UB(out0, out1, dst, stride); } void ff_put_h264_qpel8_mc23_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_midv_qrt_8w_msa(src - (2 * stride) - 2, stride, dst, stride, 8, 1); + const int32_t filt_const0 = 0xfffb0001; + const int32_t filt_const1 = 0x140014; + const int32_t filt_const2 = 0x1fffb; + v16u8 out0, out1; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; + v16i8 src11, src12, mask0, mask1, mask2; + v8i16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; + v8i16 hz_out7, hz_out8, hz_out9, hz_out10, hz_out11, hz_out12; + v8i16 hz_out10_r, hz_out21_r, hz_out32_r, hz_out43_r, hz_out54_r; + v8i16 hz_out65_r, hz_out76_r, hz_out87_r, hz_out89_r, hz_out910_r; + v8i16 hz_out1110_r, hz_out1211_r, dst0, dst1, dst2, dst3; + v8i16 hz_out10_l, hz_out21_l, hz_out32_l, hz_out43_l, hz_out54_l; + v8i16 hz_out65_l, hz_out76_l, hz_out87_l, hz_out89_l, hz_out910_l; + v8i16 hz_out1110_l, hz_out1211_l, filt0, filt1, filt2; + v4i32 tmp0, tmp1; + + LD_SB3(&luma_mask_arr[0], 16, mask0, mask1, mask2); + + filt0 = (v8i16) __msa_fill_w(filt_const0); + filt1 = (v8i16) __msa_fill_w(filt_const1); + filt2 = (v8i16) __msa_fill_w(filt_const2); + + src -= ((2 * stride) + 2); + + LD_SB5(src, stride, src0, src1, src2, src3, src4); + XORI_B5_128_SB(src0, src1, src2, src3, src4); + src += (5 * stride); + + hz_out0 = AVC_HORZ_FILTER_SH(src0, src0, mask0, mask1, mask2); + hz_out1 = AVC_HORZ_FILTER_SH(src1, src1, mask0, mask1, mask2); + hz_out2 = AVC_HORZ_FILTER_SH(src2, src2, mask0, mask1, mask2); + hz_out3 = AVC_HORZ_FILTER_SH(src3, src3, mask0, mask1, mask2); + hz_out4 = AVC_HORZ_FILTER_SH(src4, src4, mask0, mask1, mask2); + + LD_SB4(src, stride, src5, src6, src7, src8); + src += (4 * stride); + XORI_B4_128_SB(src5, src6, src7, src8); + + hz_out5 = AVC_HORZ_FILTER_SH(src5, src5, mask0, mask1, mask2); + hz_out6 = AVC_HORZ_FILTER_SH(src6, src6, mask0, mask1, mask2); + hz_out7 = AVC_HORZ_FILTER_SH(src7, src7, mask0, mask1, mask2); + hz_out8 = AVC_HORZ_FILTER_SH(src8, src8, mask0, mask1, mask2); + + ILVR_H4_SH(hz_out1, hz_out0, hz_out2, hz_out1, hz_out3, hz_out2, hz_out4, + hz_out3, hz_out10_r, hz_out21_r, hz_out32_r, hz_out43_r); + ILVL_H4_SH(hz_out1, hz_out0, hz_out2, hz_out1, hz_out3, hz_out2, hz_out4, + hz_out3, hz_out10_l, hz_out21_l, hz_out32_l, hz_out43_l); + ILVR_H4_SH(hz_out5, hz_out4, hz_out6, hz_out5, hz_out7, hz_out6, hz_out8, + hz_out7, hz_out54_r, hz_out65_r, hz_out76_r, hz_out87_r); + ILVL_H4_SH(hz_out5, hz_out4, hz_out6, hz_out5, hz_out7, hz_out6, hz_out8, + hz_out7, hz_out54_l, hz_out65_l, hz_out76_l, hz_out87_l); + + tmp0 = AVC_DOT_SW3_SW(hz_out10_r, hz_out32_r, hz_out54_r, filt0, filt1, + filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out10_l, hz_out32_l, hz_out54_l, filt0, filt1, + filt2); + dst0 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + tmp0 = AVC_DOT_SW3_SW(hz_out21_r, hz_out43_r, hz_out65_r, filt0, filt1, + filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out21_l, hz_out43_l, hz_out65_l, filt0, filt1, + filt2); + dst1 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + tmp0 = AVC_DOT_SW3_SW(hz_out32_r, hz_out54_r, hz_out76_r, filt0, filt1, + filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out32_l, hz_out54_l, hz_out76_l, filt0, filt1, + filt2); + dst2 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + tmp0 = AVC_DOT_SW3_SW(hz_out43_r, hz_out65_r, hz_out87_r, filt0, filt1, + filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out43_l, hz_out65_l, hz_out87_l, filt0, filt1, + filt2); + dst3 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + + SRARI_H4_SH(hz_out3, hz_out4, hz_out5, hz_out6, 5); + SAT_SH4_SH(hz_out3, hz_out4, hz_out5, hz_out6, 7); + + dst0 = __msa_aver_s_h(dst0, hz_out3); + dst1 = __msa_aver_s_h(dst1, hz_out4); + dst2 = __msa_aver_s_h(dst2, hz_out5); + dst3 = __msa_aver_s_h(dst3, hz_out6); + + out0 = PCKEV_XORI128_UB(dst0, dst1); + out1 = PCKEV_XORI128_UB(dst2, dst3); + ST8x4_UB(out0, out1, dst, stride); + dst += (4 * stride); + + LD_SB4(src, stride, src9, src10, src11, src12); + XORI_B4_128_SB(src9, src10, src11, src12); + hz_out9 = AVC_HORZ_FILTER_SH(src9, src9, mask0, mask1, mask2); + hz_out10 = AVC_HORZ_FILTER_SH(src10, src10, mask0, mask1, mask2); + hz_out11 = AVC_HORZ_FILTER_SH(src11, src11, mask0, mask1, mask2); + hz_out12 = AVC_HORZ_FILTER_SH(src12, src12, mask0, mask1, mask2); + ILVR_H4_SH(hz_out9, hz_out8, hz_out10, hz_out9, hz_out11, hz_out10, + hz_out12, hz_out11, hz_out89_r, hz_out910_r, hz_out1110_r, + hz_out1211_r); + ILVL_H4_SH(hz_out9, hz_out8, hz_out10, hz_out9, hz_out11, hz_out10, + hz_out12, hz_out11, hz_out89_l, hz_out910_l, hz_out1110_l, + hz_out1211_l); + tmp0 = AVC_DOT_SW3_SW(hz_out54_r, hz_out76_r, hz_out89_r, filt0, filt1, + filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out54_l, hz_out76_l, hz_out89_l, filt0, filt1, + filt2); + dst0 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + tmp0 = AVC_DOT_SW3_SW(hz_out65_r, hz_out87_r, hz_out910_r, filt0, filt1, + filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out65_l, hz_out87_l, hz_out910_l, filt0, filt1, + filt2); + dst1 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + tmp0 = AVC_DOT_SW3_SW(hz_out76_r, hz_out89_r, hz_out1110_r, filt0, filt1, + filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out76_l, hz_out89_l, hz_out1110_l, filt0, filt1, + filt2); + dst2 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + tmp0 = AVC_DOT_SW3_SW(hz_out87_r, hz_out910_r, hz_out1211_r, filt0, filt1, + filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out87_l, hz_out910_l, hz_out1211_l, filt0, filt1, + filt2); + dst3 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + + SRARI_H4_SH(hz_out7, hz_out8, hz_out9, hz_out10, 5); + SAT_SH4_SH(hz_out7, hz_out8, hz_out9, hz_out10, 7); + + dst0 = __msa_aver_s_h(dst0, hz_out7); + dst1 = __msa_aver_s_h(dst1, hz_out8); + dst2 = __msa_aver_s_h(dst2, hz_out9); + dst3 = __msa_aver_s_h(dst3, hz_out10); + + out0 = PCKEV_XORI128_UB(dst0, dst1); + out1 = PCKEV_XORI128_UB(dst2, dst3); + ST8x4_UB(out0, out1, dst, stride); } void ff_put_h264_qpel4_mc21_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_midv_qrt_4w_msa(src - (2 * stride) - 2, stride, dst, stride, 4, 0); + const int32_t filt_const0 = 0xfffb0001; + const int32_t filt_const1 = 0x140014; + const int32_t filt_const2 = 0x1fffb; + v16u8 res; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8; + v16i8 mask0, mask1, mask2; + v8i16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; + v8i16 hz_out7, hz_out8, dst0, dst1, filt0, filt1, filt2; + v8i16 hz_out10_r, hz_out21_r, hz_out32_r, hz_out43_r, hz_out54_r; + v8i16 hz_out65_r, hz_out76_r, hz_out87_r; + v4i32 tmp0, tmp1; + + LD_SB3(&luma_mask_arr[48], 16, mask0, mask1, mask2); + + filt0 = (v8i16) __msa_fill_w(filt_const0); + filt1 = (v8i16) __msa_fill_w(filt_const1); + filt2 = (v8i16) __msa_fill_w(filt_const2); + + src -= ((2 * stride) + 2); + + LD_SB5(src, stride, src0, src1, src2, src3, src4); + src += (5 * stride); + LD_SB4(src, stride, src5, src6, src7, src8); + + XORI_B5_128_SB(src0, src1, src2, src3, src4); + XORI_B4_128_SB(src5, src6, src7, src8); + + hz_out0 = AVC_HORZ_FILTER_SH(src0, src1, mask0, mask1, mask2); + hz_out2 = AVC_HORZ_FILTER_SH(src2, src3, mask0, mask1, mask2); + hz_out4 = AVC_HORZ_FILTER_SH(src4, src5, mask0, mask1, mask2); + hz_out6 = AVC_HORZ_FILTER_SH(src6, src7, mask0, mask1, mask2); + hz_out8 = AVC_HORZ_FILTER_SH(src8, src8, mask0, mask1, mask2); + PCKOD_D2_SH(hz_out0, hz_out0, hz_out2, hz_out2, hz_out1, hz_out3); + PCKOD_D2_SH(hz_out4, hz_out4, hz_out6, hz_out6, hz_out5, hz_out7); + + ILVR_H4_SH(hz_out1, hz_out0, hz_out2, hz_out1, hz_out3, hz_out2, hz_out4, + hz_out3, hz_out10_r, hz_out21_r, hz_out32_r, hz_out43_r); + ILVR_H4_SH(hz_out5, hz_out4, hz_out6, hz_out5, hz_out7, hz_out6, hz_out8, + hz_out7, hz_out54_r, hz_out65_r, hz_out76_r, hz_out87_r); + + tmp0 = AVC_DOT_SW3_SW(hz_out10_r, hz_out32_r, hz_out54_r, filt0, filt1, + filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out21_r, hz_out43_r, hz_out65_r, filt0, filt1, + filt2); + dst0 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + tmp0 = AVC_DOT_SW3_SW(hz_out32_r, hz_out54_r, hz_out76_r, filt0, filt1, + filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out43_r, hz_out65_r, hz_out87_r, filt0, filt1, + filt2); + dst1 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + + SRARI_H2_SH(hz_out2, hz_out4, 5); + SAT_SH2_SH(hz_out2, hz_out4, 7); + + dst0 = __msa_aver_s_h(dst0, hz_out2); + dst1 = __msa_aver_s_h(dst1, hz_out4); + + res = PCKEV_XORI128_UB(dst0, dst1); + ST4x4_UB(res, res, 0, 1, 2, 3, dst, stride); } void ff_put_h264_qpel4_mc23_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_midv_qrt_4w_msa(src - (2 * stride) - 2, stride, dst, stride, 4, 1); + const int32_t filt_const0 = 0xfffb0001; + const int32_t filt_const1 = 0x140014; + const int32_t filt_const2 = 0x1fffb; + v16u8 res; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8; + v16i8 mask0, mask1, mask2; + v8i16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; + v8i16 hz_out7, hz_out8, dst0, dst1, filt0, filt1, filt2; + v8i16 hz_out10_r, hz_out21_r, hz_out32_r, hz_out43_r, hz_out54_r; + v8i16 hz_out65_r, hz_out76_r, hz_out87_r; + v4i32 tmp0, tmp1; + + LD_SB3(&luma_mask_arr[48], 16, mask0, mask1, mask2); + + filt0 = (v8i16) __msa_fill_w(filt_const0); + filt1 = (v8i16) __msa_fill_w(filt_const1); + filt2 = (v8i16) __msa_fill_w(filt_const2); + + src -= ((2 * stride) + 2); + + LD_SB5(src, stride, src0, src1, src2, src3, src4); + src += (5 * stride); + LD_SB4(src, stride, src5, src6, src7, src8); + + XORI_B5_128_SB(src0, src1, src2, src3, src4); + XORI_B4_128_SB(src5, src6, src7, src8); + + hz_out0 = AVC_HORZ_FILTER_SH(src0, src1, mask0, mask1, mask2); + hz_out2 = AVC_HORZ_FILTER_SH(src2, src3, mask0, mask1, mask2); + hz_out4 = AVC_HORZ_FILTER_SH(src4, src5, mask0, mask1, mask2); + hz_out6 = AVC_HORZ_FILTER_SH(src6, src7, mask0, mask1, mask2); + hz_out8 = AVC_HORZ_FILTER_SH(src8, src8, mask0, mask1, mask2); + PCKOD_D2_SH(hz_out0, hz_out0, hz_out2, hz_out2, hz_out1, hz_out3); + PCKOD_D2_SH(hz_out4, hz_out4, hz_out6, hz_out6, hz_out5, hz_out7); + + ILVR_H4_SH(hz_out1, hz_out0, hz_out2, hz_out1, hz_out3, hz_out2, hz_out4, + hz_out3, hz_out10_r, hz_out21_r, hz_out32_r, hz_out43_r); + ILVR_H4_SH(hz_out5, hz_out4, hz_out6, hz_out5, hz_out7, hz_out6, hz_out8, + hz_out7, hz_out54_r, hz_out65_r, hz_out76_r, hz_out87_r); + + tmp0 = AVC_DOT_SW3_SW(hz_out10_r, hz_out32_r, hz_out54_r, filt0, filt1, + filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out21_r, hz_out43_r, hz_out65_r, filt0, filt1, + filt2); + dst0 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + tmp0 = AVC_DOT_SW3_SW(hz_out32_r, hz_out54_r, hz_out76_r, filt0, filt1, + filt2); + tmp1 = AVC_DOT_SW3_SW(hz_out43_r, hz_out65_r, hz_out87_r, filt0, filt1, + filt2); + dst1 = __msa_pckev_h((v8i16) tmp1, (v8i16) tmp0); + + PCKEV_D2_SH(hz_out4, hz_out3, hz_out6, hz_out5, hz_out0, hz_out1); + SRARI_H2_SH(hz_out0, hz_out1, 5); + SAT_SH2_SH(hz_out0, hz_out1, 7); + + dst0 = __msa_aver_s_h(dst0, hz_out0); + dst1 = __msa_aver_s_h(dst1, hz_out1); + + res = PCKEV_XORI128_UB(dst0, dst1); + ST4x4_UB(res, res, 0, 1, 2, 3, dst, stride); } void ff_put_h264_qpel16_mc02_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_vt_16w_msa(src - (stride * 2), stride, dst, stride, 16); + int32_t loop_cnt; + int16_t filt_const0 = 0xfb01; + int16_t filt_const1 = 0x1414; + int16_t filt_const2 = 0x1fb; + v16u8 res0, res1, res2, res3; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8; + v16i8 src10_r, src32_r, src54_r, src76_r, src21_r, src43_r, src65_r; + v16i8 src87_r, src10_l, src32_l, src54_l, src76_l, src21_l, src43_l; + v16i8 src65_l, src87_l, filt0, filt1, filt2; + v8i16 out0_r, out1_r, out2_r, out3_r, out0_l, out1_l, out2_l, out3_l; + + filt0 = (v16i8) __msa_fill_h(filt_const0); + filt1 = (v16i8) __msa_fill_h(filt_const1); + filt2 = (v16i8) __msa_fill_h(filt_const2); + src -= (stride * 2); + + LD_SB5(src, stride, src0, src1, src2, src3, src4); + src += (5 * stride); + + XORI_B5_128_SB(src0, src1, src2, src3, src4); + ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, src10_r, src21_r, + src32_r, src43_r); + ILVL_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, src10_l, src21_l, + src32_l, src43_l); + + for (loop_cnt = 4; loop_cnt--;) { + LD_SB4(src, stride, src5, src6, src7, src8); + src += (4 * stride); + + XORI_B4_128_SB(src5, src6, src7, src8); + ILVR_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, src54_r, + src65_r, src76_r, src87_r); + ILVL_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, src54_l, + src65_l, src76_l, src87_l); + out0_r = AVC_DOT_SH3_SH(src10_r, src32_r, src54_r, filt0, filt1, filt2); + out1_r = AVC_DOT_SH3_SH(src21_r, src43_r, src65_r, filt0, filt1, filt2); + out2_r = AVC_DOT_SH3_SH(src32_r, src54_r, src76_r, filt0, filt1, filt2); + out3_r = AVC_DOT_SH3_SH(src43_r, src65_r, src87_r, filt0, filt1, filt2); + out0_l = AVC_DOT_SH3_SH(src10_l, src32_l, src54_l, filt0, filt1, filt2); + out1_l = AVC_DOT_SH3_SH(src21_l, src43_l, src65_l, filt0, filt1, filt2); + out2_l = AVC_DOT_SH3_SH(src32_l, src54_l, src76_l, filt0, filt1, filt2); + out3_l = AVC_DOT_SH3_SH(src43_l, src65_l, src87_l, filt0, filt1, filt2); + SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, 5); + SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); + SRARI_H4_SH(out0_l, out1_l, out2_l, out3_l, 5); + SAT_SH4_SH(out0_l, out1_l, out2_l, out3_l, 7); + PCKEV_B4_UB(out0_l, out0_r, out1_l, out1_r, out2_l, out2_r, out3_l, + out3_r, res0, res1, res2, res3); + XORI_B4_128_UB(res0, res1, res2, res3); + ST_UB4(res0, res1, res2, res3, dst, stride); + dst += (4 * stride); + + src10_r = src54_r; + src32_r = src76_r; + src21_r = src65_r; + src43_r = src87_r; + src10_l = src54_l; + src32_l = src76_l; + src21_l = src65_l; + src43_l = src87_l; + src4 = src8; + } } void ff_put_h264_qpel8_mc02_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_vt_8w_msa(src - (stride * 2), stride, dst, stride, 8); + const int16_t filt_const0 = 0xfb01; + const int16_t filt_const1 = 0x1414; + const int16_t filt_const2 = 0x1fb; + v16u8 out0, out1, out2, out3; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; + v16i8 src11, src12, src10_r, src21_r, src32_r, src43_r, src76_r, src87_r; + v16i8 src98_r, src109_r, src89_r, src910_r, src1110_r, src1211_r; + v16i8 filt0, filt1, filt2; + v8i16 out0_r, out1_r, out2_r, out3_r, out4_r, out5_r, out6_r, out7_r; + + filt0 = (v16i8) __msa_fill_h(filt_const0); + filt1 = (v16i8) __msa_fill_h(filt_const1); + filt2 = (v16i8) __msa_fill_h(filt_const2); + + src -= (stride * 2); + + LD_SB8(src, stride, src0, src1, src2, src3, src4, src5, src6, src7); + src += (8 * stride); + LD_SB5(src, stride, src8, src9, src10, src11, src12); + ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, src10_r, src21_r, + src32_r, src43_r); + ILVR_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, src76_r, src87_r, + src98_r, src109_r); + ILVR_B4_SB(src9, src8, src10, src9, src11, src10, src12, src11, src89_r, + src910_r, src1110_r, src1211_r); + XORI_B4_128_SB(src10_r, src21_r, src32_r, src43_r); + XORI_B4_128_SB(src76_r, src87_r, src98_r, src109_r); + XORI_B4_128_SB(src89_r, src910_r, src1110_r, src1211_r); + out0_r = AVC_DOT_SH3_SH(src10_r, src32_r, src76_r, filt0, filt1, filt2); + out1_r = AVC_DOT_SH3_SH(src21_r, src43_r, src87_r, filt0, filt1, filt2); + out2_r = AVC_DOT_SH3_SH(src32_r, src76_r, src98_r, filt0, filt1, filt2); + out3_r = AVC_DOT_SH3_SH(src43_r, src87_r, src109_r, filt0, filt1, filt2); + out4_r = AVC_DOT_SH3_SH(src76_r, src98_r, src89_r, filt0, filt1, filt2); + out5_r = AVC_DOT_SH3_SH(src87_r, src109_r, src910_r, filt0, filt1, filt2); + out6_r = AVC_DOT_SH3_SH(src98_r, src89_r, src1110_r, filt0, filt1, filt2); + out7_r = AVC_DOT_SH3_SH(src109_r, src910_r, src1211_r, filt0, filt1, filt2); + SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, 5); + SRARI_H4_SH(out4_r, out5_r, out6_r, out7_r, 5); + SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); + SAT_SH4_SH(out4_r, out5_r, out6_r, out7_r, 7); + out0 = PCKEV_XORI128_UB(out0_r, out1_r); + out1 = PCKEV_XORI128_UB(out2_r, out3_r); + out2 = PCKEV_XORI128_UB(out4_r, out5_r); + out3 = PCKEV_XORI128_UB(out6_r, out7_r); + ST8x8_UB(out0, out1, out2, out3, dst, stride); } void ff_put_h264_qpel4_mc02_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { - avc_luma_vt_4w_msa(src - (stride * 2), stride, dst, stride, 4); + const int16_t filt_const0 = 0xfb01; + const int16_t filt_const1 = 0x1414; + const int16_t filt_const2 = 0x1fb; + v16u8 out; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8; + v16i8 src10_r, src32_r, src54_r, src76_r, src21_r, src43_r, src65_r; + v16i8 src87_r, src2110, src4332, src6554, src8776, filt0, filt1, filt2; + v8i16 out10, out32; + + filt0 = (v16i8) __msa_fill_h(filt_const0); + filt1 = (v16i8) __msa_fill_h(filt_const1); + filt2 = (v16i8) __msa_fill_h(filt_const2); + + src -= (stride * 2); + + LD_SB5(src, stride, src0, src1, src2, src3, src4); + src += (5 * stride); + LD_SB4(src, stride, src5, src6, src7, src8); + + ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, src10_r, src21_r, + src32_r, src43_r); + ILVR_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, src54_r, src65_r, + src76_r, src87_r); + ILVR_D4_SB(src21_r, src10_r, src43_r, src32_r, src65_r, src54_r, src87_r, + src76_r, src2110, src4332, src6554, src8776); + XORI_B4_128_SB(src2110, src4332, src6554, src8776); + out10 = AVC_DOT_SH3_SH(src2110, src4332, src6554, filt0, filt1, filt2); + out32 = AVC_DOT_SH3_SH(src4332, src6554, src8776, filt0, filt1, filt2); + SRARI_H2_SH(out10, out32, 5); + SAT_SH2_SH(out10, out32, 7); + out = PCKEV_XORI128_UB(out10, out32); + ST4x4_UB(out, out, 0, 1, 2, 3, dst, stride); } void ff_put_h264_qpel16_mc12_msa(uint8_t *dst, const uint8_t *src, From eadb911643243c9c756d5a6c3d84182ad7578261 Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Mon, 9 Oct 2017 17:47:34 +0530 Subject: [PATCH 3317/3374] avcodec/mips: Improve hevc uni-w horiz mc msa functions Load the specific destination bytes instead of MSA load and pack. Pack the data to half word before clipping. Use immediate unsigned saturation for clip to max saving one vector register. Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/hevc_macros_msa.h | 13 +- libavcodec/mips/hevc_mc_uniw_msa.c | 641 +++++++++++++++++------------ 2 files changed, 386 insertions(+), 268 deletions(-) diff --git a/libavcodec/mips/hevc_macros_msa.h b/libavcodec/mips/hevc_macros_msa.h index b06c5ad9b9d23..7dcfea03b41c9 100644 --- a/libavcodec/mips/hevc_macros_msa.h +++ b/libavcodec/mips/hevc_macros_msa.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com) + * Copyright (c) 2015 - 2017 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com) * * This file is part of FFmpeg. * @@ -58,6 +58,17 @@ out2 = (v4i32) __msa_pckev_b((v16i8) tmp5_m, (v16i8) tmp4_m); \ } +#define HEVC_FILT_8TAP_SH(in0, in1, in2, in3, \ + filt0, filt1, filt2, filt3) \ +( { \ + v8i16 out_m; \ + \ + out_m = __msa_dotp_s_h((v16i8) in0, (v16i8) filt0); \ + out_m = __msa_dpadd_s_h(out_m, (v16i8) in1, (v16i8) filt1); \ + DPADD_SB2_SH(in2, in3, filt2, filt3, out_m, out_m); \ + out_m; \ +} ) + #define HEVC_FILT_8TAP(in0, in1, in2, in3, \ filt0, filt1, filt2, filt3) \ ( { \ diff --git a/libavcodec/mips/hevc_mc_uniw_msa.c b/libavcodec/mips/hevc_mc_uniw_msa.c index 38a8844a6e11d..7c01c32d5749a 100644 --- a/libavcodec/mips/hevc_mc_uniw_msa.c +++ b/libavcodec/mips/hevc_mc_uniw_msa.c @@ -22,6 +22,13 @@ #include "libavcodec/mips/hevcdsp_mips.h" #include "libavcodec/mips/hevc_macros_msa.h" +static const uint8_t ff_hevc_mask_arr[16 * 2] __attribute__((aligned(0x40))) = { + /* 8 width cases */ + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, + /* 4 width cases */ + 0, 1, 1, 2, 2, 3, 3, 4, 16, 17, 17, 18, 18, 19, 19, 20 +}; + #define HEVC_HV_UNIW_RND_CLIP4(in0, in1, in2, in3, wgt, offset, rnd, \ out0, out1, out2, out3) \ { \ @@ -624,28 +631,35 @@ static void hevc_hz_uniwgt_8t_4w_msa(uint8_t *src, int32_t rnd_val) { uint32_t loop_cnt; + v16u8 out0, out1; v8i16 filt0, filt1, filt2, filt3; v16i8 src0, src1, src2, src3, src4, src5, src6, src7; - v16i8 mask1, mask2, mask3; - v8i16 filter_vec, const_vec; - v16i8 vec0, vec1, vec2, vec3; - v8i16 dst0, dst1, dst2, dst3; - v4i32 dst0_r, dst1_r, dst2_r, dst3_r, dst0_l, dst1_l, dst2_l, dst3_l; - v4i32 weight_vec, offset_vec, rnd_vec; - v16i8 mask0 = { 0, 1, 1, 2, 2, 3, 3, 4, 16, 17, 17, 18, 18, 19, 19, 20 }; + v16i8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, vec9, vec10; + v16i8 mask0, mask1, mask2, mask3, vec11, vec12, vec13, vec14, vec15; + v8i16 filter_vec, dst01, dst23, dst45, dst67; + v8i16 dst0, dst1, dst2, dst3, weight_vec_h, offset_vec, denom_vec; + v4i32 weight_vec, rnd_vec; src -= 3; weight = weight & 0x0000FFFF; - const_vec = __msa_ldi_h(128); - const_vec <<= 6; weight_vec = __msa_fill_w(weight); - offset_vec = __msa_fill_w(offset); rnd_vec = __msa_fill_w(rnd_val); + weight *= 128; + rnd_val -= 6; + + weight_vec_h = __msa_fill_h(weight); + offset_vec = __msa_fill_h(offset); + denom_vec = __msa_fill_h(rnd_val); + + weight_vec_h = __msa_srar_h(weight_vec_h, denom_vec); + offset_vec = __msa_adds_s_h(offset_vec, weight_vec_h); + filter_vec = LD_SH(filter); SPLATI_H4_SH(filter_vec, 0, 1, 2, 3, filt0, filt1, filt2, filt3); + mask0 = LD_SB(&ff_hevc_mask_arr[16]); mask1 = mask0 + 2; mask2 = mask0 + 4; mask3 = mask0 + 6; @@ -657,34 +671,27 @@ static void hevc_hz_uniwgt_8t_4w_msa(uint8_t *src, VSHF_B4_SB(src0, src1, mask0, mask1, mask2, mask3, vec0, vec1, vec2, vec3); - - dst0 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst0, dst0, dst0, dst0); VSHF_B4_SB(src2, src3, mask0, mask1, mask2, mask3, - vec0, vec1, vec2, vec3); - dst1 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst1, dst1, dst1, dst1); + vec4, vec5, vec6, vec7); VSHF_B4_SB(src4, src5, mask0, mask1, mask2, mask3, - vec0, vec1, vec2, vec3); - dst2 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst2, dst2, dst2, dst2); + vec8, vec9, vec10, vec11); VSHF_B4_SB(src6, src7, mask0, mask1, mask2, mask3, - vec0, vec1, vec2, vec3); - dst3 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst3, dst3, dst3, dst3); - - HEVC_UNIW_RND_CLIP4(dst0, dst1, dst2, dst3, - weight_vec, offset_vec, rnd_vec, - dst0_r, dst1_r, dst2_r, dst3_r, - dst0_l, dst1_l, dst2_l, dst3_l); + vec12, vec13, vec14, vec15); + dst01 = HEVC_FILT_8TAP_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, + filt3); + dst23 = HEVC_FILT_8TAP_SH(vec4, vec5, vec6, vec7, filt0, filt1, filt2, + filt3); + dst45 = HEVC_FILT_8TAP_SH(vec8, vec9, vec10, vec11, filt0, filt1, filt2, + filt3); + dst67 = HEVC_FILT_8TAP_SH(vec12, vec13, vec14, vec15, filt0, filt1, + filt2, filt3); + + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst01, dst23, dst45, dst67, weight_vec, + offset_vec, rnd_vec, dst0, dst1, dst2, + dst3); - HEVC_PCK_SW_SB8(dst0_l, dst0_r, dst1_l, dst1_r, - dst2_l, dst2_r, dst3_l, dst3_r, dst0_r, dst1_r); - ST4x8_UB(dst0_r, dst1_r, dst, dst_stride); + PCKEV_B2_UB(dst1, dst0, dst3, dst2, out0, out1); + ST4x8_UB(out0, out1, dst, dst_stride); dst += (8 * dst_stride); } } @@ -700,28 +707,37 @@ static void hevc_hz_uniwgt_8t_8w_msa(uint8_t *src, int32_t rnd_val) { uint32_t loop_cnt; + v16u8 out0, out1; v16i8 src0, src1, src2, src3; v8i16 filt0, filt1, filt2, filt3; - v16i8 mask1, mask2, mask3; - v8i16 filter_vec, const_vec; - v16i8 vec0, vec1, vec2, vec3; + v16i8 mask0, mask1, mask2, mask3; + v8i16 filter_vec; + v16i8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; + v16i8 vec8, vec9, vec10, vec11, vec12, vec13, vec14, vec15; v8i16 dst0, dst1, dst2, dst3; - v4i32 dst0_r, dst1_r, dst2_r, dst3_r, dst0_l, dst1_l, dst2_l, dst3_l; - v4i32 weight_vec, offset_vec, rnd_vec; - v16i8 mask0 = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8 }; + v8i16 weight_vec_h, offset_vec, denom_vec; + v4i32 weight_vec, rnd_vec; src -= 3; weight = weight & 0x0000FFFF; - const_vec = __msa_ldi_h(128); - const_vec <<= 6; weight_vec = __msa_fill_w(weight); - offset_vec = __msa_fill_w(offset); rnd_vec = __msa_fill_w(rnd_val); + weight *= 128; + rnd_val -= 6; + + weight_vec_h = __msa_fill_h(weight); + offset_vec = __msa_fill_h(offset); + denom_vec = __msa_fill_h(rnd_val); + + weight_vec_h = __msa_srar_h(weight_vec_h, denom_vec); + offset_vec = __msa_adds_s_h(offset_vec, weight_vec_h); + filter_vec = LD_SH(filter); SPLATI_H4_SH(filter_vec, 0, 1, 2, 3, filt0, filt1, filt2, filt3); + mask0 = LD_SB(&ff_hevc_mask_arr[0]); mask1 = mask0 + 2; mask2 = mask0 + 4; mask3 = mask0 + 6; @@ -733,33 +749,27 @@ static void hevc_hz_uniwgt_8t_8w_msa(uint8_t *src, VSHF_B4_SB(src0, src0, mask0, mask1, mask2, mask3, vec0, vec1, vec2, vec3); - dst0 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst0, dst0, dst0, dst0); VSHF_B4_SB(src1, src1, mask0, mask1, mask2, mask3, - vec0, vec1, vec2, vec3); - dst1 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst1, dst1, dst1, dst1); + vec4, vec5, vec6, vec7); VSHF_B4_SB(src2, src2, mask0, mask1, mask2, mask3, - vec0, vec1, vec2, vec3); - dst2 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst2, dst2, dst2, dst2); + vec8, vec9, vec10, vec11); VSHF_B4_SB(src3, src3, mask0, mask1, mask2, mask3, - vec0, vec1, vec2, vec3); - dst3 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst3, dst3, dst3, dst3); + vec12, vec13, vec14, vec15); + dst0 = HEVC_FILT_8TAP_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, + filt3); + dst1 = HEVC_FILT_8TAP_SH(vec4, vec5, vec6, vec7, filt0, filt1, filt2, + filt3); + dst2 = HEVC_FILT_8TAP_SH(vec8, vec9, vec10, vec11, filt0, filt1, filt2, + filt3); + dst3 = HEVC_FILT_8TAP_SH(vec12, vec13, vec14, vec15, filt0, filt1, + filt2, filt3); - HEVC_UNIW_RND_CLIP4(dst0, dst1, dst2, dst3, - weight_vec, offset_vec, rnd_vec, - dst0_r, dst1_r, dst2_r, dst3_r, - dst0_l, dst1_l, dst2_l, dst3_l); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst0, dst1, dst2, dst3, weight_vec, + offset_vec, rnd_vec, dst0, dst1, dst2, + dst3); - HEVC_PCK_SW_SB8(dst0_l, dst0_r, dst1_l, dst1_r, - dst2_l, dst2_r, dst3_l, dst3_r, dst0_r, dst1_r); - ST8x4_UB(dst0_r, dst1_r, dst, dst_stride); + PCKEV_B2_UB(dst1, dst0, dst3, dst2, out0, out1); + ST8x4_UB(out0, out1, dst, dst_stride); dst += (4 * dst_stride); } } @@ -774,10 +784,88 @@ static void hevc_hz_uniwgt_8t_12w_msa(uint8_t *src, int32_t offset, int32_t rnd_val) { - hevc_hz_uniwgt_8t_8w_msa(src, src_stride, dst, dst_stride, - filter, height, weight, offset, rnd_val); - hevc_hz_uniwgt_8t_4w_msa(src + 8, src_stride, dst + 8, dst_stride, - filter, height, weight, offset, rnd_val); + uint32_t loop_cnt; + v16u8 out0, out1, out2; + v8i16 filt0, filt1, filt2, filt3; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7; + v16i8 mask0, mask1, mask2, mask3, mask4, mask5, mask6, mask7; + v16i8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; + v16i8 vec8, vec9, vec10, vec11, vec12, vec13, vec14, vec15; + v8i16 filter_vec; + v8i16 dst01, dst23, dst0, dst1, dst2, dst3, dst4, dst5; + v8i16 weight_vec_h, offset_vec, denom_vec; + v4i32 weight_vec, rnd_vec; + + src -= 3; + weight = weight & 0x0000FFFF; + + weight_vec = __msa_fill_w(weight); + rnd_vec = __msa_fill_w(rnd_val); + + weight *= 128; + rnd_val -= 6; + + weight_vec_h = __msa_fill_h(weight); + offset_vec = __msa_fill_h(offset); + denom_vec = __msa_fill_h(rnd_val); + + weight_vec_h = __msa_srar_h(weight_vec_h, denom_vec); + offset_vec = __msa_adds_s_h(offset_vec, weight_vec_h); + + filter_vec = LD_SH(filter); + SPLATI_H4_SH(filter_vec, 0, 1, 2, 3, filt0, filt1, filt2, filt3); + + mask0 = LD_SB(&ff_hevc_mask_arr[0]); + mask1 = mask0 + 2; + mask2 = mask0 + 4; + mask3 = mask0 + 6; + mask4 = LD_SB(&ff_hevc_mask_arr[16]); + mask5 = mask4 + 2; + mask6 = mask4 + 4; + mask7 = mask4 + 6; + + for (loop_cnt = (height >> 2); loop_cnt--;) { + LD_SB4(src, src_stride, src0, src1, src2, src3); + LD_SB4(src + 8, src_stride, src4, src5, src6, src7); + src += (4 * src_stride); + XORI_B8_128_SB(src0, src1, src2, src3, src4, src5, src6, src7); + + VSHF_B4_SB(src0, src0, mask0, mask1, mask2, mask3, + vec0, vec1, vec2, vec3); + VSHF_B4_SB(src1, src1, mask0, mask1, mask2, mask3, + vec4, vec5, vec6, vec7); + VSHF_B4_SB(src2, src2, mask0, mask1, mask2, mask3, + vec8, vec9, vec10, vec11); + VSHF_B4_SB(src3, src3, mask0, mask1, mask2, mask3, + vec12, vec13, vec14, vec15); + dst0 = HEVC_FILT_8TAP_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, + filt3); + dst1 = HEVC_FILT_8TAP_SH(vec4, vec5, vec6, vec7, filt0, filt1, filt2, + filt3); + dst2 = HEVC_FILT_8TAP_SH(vec8, vec9, vec10, vec11, filt0, filt1, filt2, + filt3); + dst3 = HEVC_FILT_8TAP_SH(vec12, vec13, vec14, vec15, filt0, filt1, + filt2, filt3); + VSHF_B4_SB(src4, src5, mask4, mask5, mask6, mask7, + vec0, vec1, vec2, vec3); + VSHF_B4_SB(src6, src7, mask4, mask5, mask6, mask7, + vec4, vec5, vec6, vec7); + dst01 = HEVC_FILT_8TAP_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, + filt3); + dst23 = HEVC_FILT_8TAP_SH(vec4, vec5, vec6, vec7, filt0, filt1, filt2, + filt3); + + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst0, dst1, dst2, dst3, weight_vec, + offset_vec, rnd_vec, dst0, dst1, dst2, + dst3); + HEVC_UNIW_RND_CLIP2_MAX_SATU_H(dst01, dst23, weight_vec, offset_vec, + rnd_vec, dst4, dst5); + + PCKEV_B3_UB(dst1, dst0, dst3, dst2, dst5, dst4, out0, out1, out2); + ST8x4_UB(out0, out1, dst, dst_stride); + ST4x4_UB(out2, out2, 0, 1, 2, 3, dst + 8, dst_stride); + dst += (4 * dst_stride); + } } static void hevc_hz_uniwgt_8t_16w_msa(uint8_t *src, @@ -791,28 +879,36 @@ static void hevc_hz_uniwgt_8t_16w_msa(uint8_t *src, int32_t rnd_val) { uint32_t loop_cnt; + v16u8 out0, out1; v16i8 src0, src1, src2, src3; v8i16 filt0, filt1, filt2, filt3; - v16i8 mask1, mask2, mask3; - v8i16 filter_vec, const_vec; - v16i8 vec0, vec1, vec2, vec3; + v16i8 mask0, mask1, mask2, mask3; + v8i16 filter_vec; + v16i8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; + v16i8 vec8, vec9, vec10, vec11, vec12, vec13, vec14, vec15; v8i16 dst0, dst1, dst2, dst3; - v4i32 dst0_r, dst1_r, dst2_r, dst3_r, dst0_l, dst1_l, dst2_l, dst3_l; - v4i32 weight_vec, offset_vec, rnd_vec; - v16i8 mask0 = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8 }; + v8i16 weight_vec_h, offset_vec, denom_vec; + v4i32 weight_vec, rnd_vec; src -= 3; - const_vec = __msa_ldi_h(128); - const_vec <<= 6; - weight = weight & 0x0000FFFF; weight_vec = __msa_fill_w(weight); - offset_vec = __msa_fill_w(offset); rnd_vec = __msa_fill_w(rnd_val); + weight *= 128; + rnd_val -= 6; + + weight_vec_h = __msa_fill_h(weight); + offset_vec = __msa_fill_h(offset); + denom_vec = __msa_fill_h(rnd_val); + + weight_vec_h = __msa_srar_h(weight_vec_h, denom_vec); + offset_vec = __msa_adds_s_h(offset_vec, weight_vec_h); + filter_vec = LD_SH(filter); SPLATI_H4_SH(filter_vec, 0, 1, 2, 3, filt0, filt1, filt2, filt3); + mask0 = LD_SB(&ff_hevc_mask_arr[0]); mask1 = mask0 + 2; mask2 = mask0 + 4; mask3 = mask0 + 6; @@ -825,33 +921,27 @@ static void hevc_hz_uniwgt_8t_16w_msa(uint8_t *src, VSHF_B4_SB(src0, src0, mask0, mask1, mask2, mask3, vec0, vec1, vec2, vec3); - dst0 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst0, dst0, dst0, dst0); VSHF_B4_SB(src1, src1, mask0, mask1, mask2, mask3, - vec0, vec1, vec2, vec3); - dst1 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst1, dst1, dst1, dst1); + vec4, vec5, vec6, vec7); VSHF_B4_SB(src2, src2, mask0, mask1, mask2, mask3, - vec0, vec1, vec2, vec3); - dst2 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst2, dst2, dst2, dst2); + vec8, vec9, vec10, vec11); VSHF_B4_SB(src3, src3, mask0, mask1, mask2, mask3, - vec0, vec1, vec2, vec3); - dst3 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst3, dst3, dst3, dst3); + vec12, vec13, vec14, vec15); + dst0 = HEVC_FILT_8TAP_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, + filt3); + dst1 = HEVC_FILT_8TAP_SH(vec4, vec5, vec6, vec7, filt0, filt1, filt2, + filt3); + dst2 = HEVC_FILT_8TAP_SH(vec8, vec9, vec10, vec11, filt0, filt1, filt2, + filt3); + dst3 = HEVC_FILT_8TAP_SH(vec12, vec13, vec14, vec15, filt0, filt1, + filt2, filt3); - HEVC_UNIW_RND_CLIP4(dst0, dst1, dst2, dst3, - weight_vec, offset_vec, rnd_vec, - dst0_r, dst1_r, dst2_r, dst3_r, - dst0_l, dst1_l, dst2_l, dst3_l); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst0, dst1, dst2, dst3, weight_vec, + offset_vec, rnd_vec, dst0, dst1, dst2, + dst3); - HEVC_PCK_SW_SB8(dst0_l, dst0_r, dst1_l, dst1_r, - dst2_l, dst2_r, dst3_l, dst3_r, dst0_r, dst1_r); - ST_SW2(dst0_r, dst1_r, dst, dst_stride); + PCKEV_B2_UB(dst1, dst0, dst3, dst2, out0, out1); + ST_UB2(out0, out1, dst, dst_stride); dst += (2 * dst_stride); } } @@ -867,29 +957,35 @@ static void hevc_hz_uniwgt_8t_24w_msa(uint8_t *src, int32_t rnd_val) { uint32_t loop_cnt; + v16u8 out0, out1, out2; v16i8 src0, src1, src2, src3; v8i16 filt0, filt1, filt2, filt3; - v16i8 mask1, mask2, mask3, mask4, mask5, mask6, mask7; - v16i8 vec0, vec1, vec2, vec3; + v16i8 mask0, mask1, mask2, mask3, mask4, mask5, mask6, mask7; + v16i8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; + v16i8 vec8, vec9, vec10, vec11, vec12, vec13, vec14, vec15; v8i16 dst0, dst1, dst2, dst3, dst4, dst5; - v8i16 filter_vec, const_vec; - v4i32 dst0_r, dst1_r, dst2_r, dst3_r, dst4_r, dst5_r; - v4i32 dst0_l, dst1_l, dst2_l, dst3_l, dst4_l, dst5_l; - v4i32 weight_vec, offset_vec, rnd_vec; - v16i8 mask0 = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8 }; + v8i16 filter_vec, weight_vec_h, offset_vec, denom_vec; + v4i32 weight_vec, rnd_vec; src -= 3; - const_vec = __msa_ldi_h(128); - const_vec <<= 6; - weight = weight & 0x0000FFFF; weight_vec = __msa_fill_w(weight); - offset_vec = __msa_fill_w(offset); rnd_vec = __msa_fill_w(rnd_val); + weight *= 128; + rnd_val -= 6; + + weight_vec_h = __msa_fill_h(weight); + offset_vec = __msa_fill_h(offset); + denom_vec = __msa_fill_h(rnd_val); + + weight_vec_h = __msa_srar_h(weight_vec_h, denom_vec); + offset_vec = __msa_adds_s_h(offset_vec, weight_vec_h); + filter_vec = LD_SH(filter); SPLATI_H4_SH(filter_vec, 0, 1, 2, 3, filt0, filt1, filt2, filt3); + mask0 = LD_SB(&ff_hevc_mask_arr[0]); mask1 = mask0 + 2; mask2 = mask0 + 4; mask3 = mask0 + 6; @@ -898,7 +994,7 @@ static void hevc_hz_uniwgt_8t_24w_msa(uint8_t *src, mask6 = mask0 + 12; mask7 = mask0 + 14; - for (loop_cnt = (height >> 1); loop_cnt--;) { + for (loop_cnt = 16; loop_cnt--;) { LD_SB2(src, 16, src0, src1); src += src_stride; LD_SB2(src, 16, src2, src3); @@ -906,48 +1002,39 @@ static void hevc_hz_uniwgt_8t_24w_msa(uint8_t *src, XORI_B4_128_SB(src0, src1, src2, src3); VSHF_B4_SB(src0, src0, mask0, mask1, mask2, mask3, vec0, vec1, vec2, vec3); - - dst0 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst0, dst0, dst0, dst0); VSHF_B4_SB(src0, src1, mask4, mask5, mask6, mask7, - vec0, vec1, vec2, vec3); - dst1 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst1, dst1, dst1, dst1); + vec4, vec5, vec6, vec7); VSHF_B4_SB(src1, src1, mask0, mask1, mask2, mask3, - vec0, vec1, vec2, vec3); - dst2 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst2, dst2, dst2, dst2); + vec8, vec9, vec10, vec11); VSHF_B4_SB(src2, src2, mask0, mask1, mask2, mask3, - vec0, vec1, vec2, vec3); - dst3 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst3, dst3, dst3, dst3); + vec12, vec13, vec14, vec15); + dst0 = HEVC_FILT_8TAP_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, + filt3); + dst1 = HEVC_FILT_8TAP_SH(vec4, vec5, vec6, vec7, filt0, filt1, filt2, + filt3); + dst2 = HEVC_FILT_8TAP_SH(vec8, vec9, vec10, vec11, filt0, filt1, filt2, + filt3); + dst3 = HEVC_FILT_8TAP_SH(vec12, vec13, vec14, vec15, filt0, filt1, + filt2, filt3); + VSHF_B4_SB(src2, src3, mask4, mask5, mask6, mask7, vec0, vec1, vec2, vec3); - dst4 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst4, dst4, dst4, dst4); VSHF_B4_SB(src3, src3, mask0, mask1, mask2, mask3, - vec0, vec1, vec2, vec3); - dst5 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst5, dst5, dst5, dst5); + vec4, vec5, vec6, vec7); + dst4 = HEVC_FILT_8TAP_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, + filt3); + dst5 = HEVC_FILT_8TAP_SH(vec4, vec5, vec6, vec7, filt0, filt1, filt2, + filt3); - HEVC_UNIW_RND_CLIP4(dst0, dst1, dst2, dst3, - weight_vec, offset_vec, rnd_vec, - dst0_r, dst1_r, dst2_r, dst3_r, - dst0_l, dst1_l, dst2_l, dst3_l); - HEVC_UNIW_RND_CLIP2(dst4, dst5, weight_vec, offset_vec, rnd_vec, - dst4_r, dst5_r, dst4_l, dst5_l); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst0, dst1, dst2, dst3, weight_vec, + offset_vec, rnd_vec, dst0, dst1, dst2, + dst3); + HEVC_UNIW_RND_CLIP2_MAX_SATU_H(dst4, dst5, weight_vec, offset_vec, + rnd_vec, dst4, dst5); - HEVC_PCK_SW_SB8(dst0_l, dst0_r, dst1_l, dst1_r, - dst3_l, dst3_r, dst4_l, dst4_r, dst0_r, dst1_r); - HEVC_PCK_SW_SB4(dst2_l, dst2_r, dst5_l, dst5_r, dst2_r); - ST_SW2(dst0_r, dst1_r, dst, dst_stride); - ST8x2_UB(dst2_r, dst + 16, dst_stride); + PCKEV_B3_UB(dst1, dst0, dst4, dst3, dst5, dst2, out0, out1, out2); + ST_UB2(out0, out1, dst, dst_stride); + ST8x2_UB(out2, dst + 16, dst_stride); dst += (2 * dst_stride); } } @@ -963,71 +1050,93 @@ static void hevc_hz_uniwgt_8t_32w_msa(uint8_t *src, int32_t rnd_val) { uint32_t loop_cnt; - v16i8 src0, src1, src2; + v16u8 out0, out1, out2, out3; + v16i8 src0, src1, src2, src3, src4, src5, src6, src7; v8i16 filt0, filt1, filt2, filt3; - v16i8 mask1, mask2, mask3, mask4, mask5, mask6, mask7; - v16i8 vec0, vec1, vec2, vec3; - v8i16 dst0, dst1, dst2, dst3; - v8i16 filter_vec, const_vec; - v4i32 dst0_r, dst1_r, dst2_r, dst3_r, dst0_l, dst1_l, dst2_l, dst3_l; - v4i32 weight_vec, offset_vec, rnd_vec; - v16i8 mask0 = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8 }; + v16i8 mask0, mask1, mask2, mask3; + v16i8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; + v16i8 vec8, vec9, vec10, vec11, vec12, vec13, vec14, vec15; + v8i16 filter_vec; + v8i16 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; + v8i16 weight_vec_h, offset_vec, denom_vec; + v4i32 weight_vec, rnd_vec; src -= 3; - const_vec = __msa_ldi_h(128); - const_vec <<= 6; - weight = weight & 0x0000FFFF; weight_vec = __msa_fill_w(weight); - offset_vec = __msa_fill_w(offset); rnd_vec = __msa_fill_w(rnd_val); + weight *= 128; + rnd_val -= 6; + + weight_vec_h = __msa_fill_h(weight); + offset_vec = __msa_fill_h(offset); + denom_vec = __msa_fill_h(rnd_val); + + weight_vec_h = __msa_srar_h(weight_vec_h, denom_vec); + offset_vec = __msa_adds_s_h(offset_vec, weight_vec_h); + filter_vec = LD_SH(filter); SPLATI_H4_SH(filter_vec, 0, 1, 2, 3, filt0, filt1, filt2, filt3); + mask0 = LD_SB(&ff_hevc_mask_arr[0]); mask1 = mask0 + 2; mask2 = mask0 + 4; mask3 = mask0 + 6; - mask4 = mask0 + 8; - mask5 = mask0 + 10; - mask6 = mask0 + 12; - mask7 = mask0 + 14; - for (loop_cnt = height; loop_cnt--;) { - LD_SB2(src, 16, src0, src1); - src2 = LD_SB(src + 24); + for (loop_cnt = height >> 1; loop_cnt--;) { + LD_SB4(src, 8, src0, src1, src2, src3); src += src_stride; - XORI_B3_128_SB(src0, src1, src2); + LD_SB4(src, 8, src4, src5, src6, src7); + src += src_stride; + XORI_B8_128_SB(src0, src1, src2, src3, src4, src5, src6, src7); VSHF_B4_SB(src0, src0, mask0, mask1, mask2, mask3, vec0, vec1, vec2, vec3); - dst0 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst0, dst0, dst0, dst0); - VSHF_B4_SB(src0, src1, mask4, mask5, mask6, mask7, - vec0, vec1, vec2, vec3); - dst1 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst1, dst1, dst1, dst1); VSHF_B4_SB(src1, src1, mask0, mask1, mask2, mask3, - vec0, vec1, vec2, vec3); - dst2 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst2, dst2, dst2, dst2); + vec4, vec5, vec6, vec7); VSHF_B4_SB(src2, src2, mask0, mask1, mask2, mask3, + vec8, vec9, vec10, vec11); + VSHF_B4_SB(src3, src3, mask0, mask1, mask2, mask3, + vec12, vec13, vec14, vec15); + dst0 = HEVC_FILT_8TAP_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, + filt3); + dst1 = HEVC_FILT_8TAP_SH(vec4, vec5, vec6, vec7, filt0, filt1, filt2, + filt3); + dst2 = HEVC_FILT_8TAP_SH(vec8, vec9, vec10, vec11, filt0, filt1, filt2, + filt3); + dst3 = HEVC_FILT_8TAP_SH(vec12, vec13, vec14, vec15, filt0, filt1, + filt2, filt3); + + VSHF_B4_SB(src4, src4, mask0, mask1, mask2, mask3, vec0, vec1, vec2, vec3); - dst3 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst3, dst3, dst3, dst3); + VSHF_B4_SB(src5, src5, mask0, mask1, mask2, mask3, + vec4, vec5, vec6, vec7); + VSHF_B4_SB(src6, src6, mask0, mask1, mask2, mask3, + vec8, vec9, vec10, vec11); + VSHF_B4_SB(src7, src7, mask0, mask1, mask2, mask3, + vec12, vec13, vec14, vec15); + dst4 = HEVC_FILT_8TAP_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, + filt3); + dst5 = HEVC_FILT_8TAP_SH(vec4, vec5, vec6, vec7, filt0, filt1, filt2, + filt3); + dst6 = HEVC_FILT_8TAP_SH(vec8, vec9, vec10, vec11, filt0, filt1, filt2, + filt3); + dst7 = HEVC_FILT_8TAP_SH(vec12, vec13, vec14, vec15, filt0, filt1, + filt2, filt3); - HEVC_UNIW_RND_CLIP4(dst0, dst1, dst2, dst3, - weight_vec, offset_vec, rnd_vec, - dst0_r, dst1_r, dst2_r, dst3_r, - dst0_l, dst1_l, dst2_l, dst3_l); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst0, dst1, dst2, dst3, weight_vec, + offset_vec, rnd_vec, dst0, dst1, dst2, + dst3); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst4, dst5, dst6, dst7, weight_vec, + offset_vec, rnd_vec, dst4, dst5, dst6, + dst7); - HEVC_PCK_SW_SB8(dst0_l, dst0_r, dst1_l, dst1_r, - dst2_l, dst2_r, dst3_l, dst3_r, dst0_r, dst1_r); - ST_SW2(dst0_r, dst1_r, dst, 16); + PCKEV_B2_UB(dst1, dst0, dst3, dst2, out0, out1); + PCKEV_B2_UB(dst5, dst4, dst7, dst6, out2, out3); + ST_UB2(out0, out1, dst, 16); + dst += dst_stride; + ST_UB2(out2, out3, dst, 16); dst += dst_stride; } } @@ -1043,29 +1152,36 @@ static void hevc_hz_uniwgt_8t_48w_msa(uint8_t *src, int32_t rnd_val) { uint32_t loop_cnt; + v16u8 out0, out1, out2; v16i8 src0, src1, src2, src3; v8i16 filt0, filt1, filt2, filt3; - v16i8 mask1, mask2, mask3, mask4, mask5, mask6, mask7; - v16i8 vec0, vec1, vec2, vec3; + v16i8 mask0, mask1, mask2, mask3, mask4, mask5, mask6, mask7; + v16i8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; + v16i8 vec8, vec9, vec10, vec11, vec12, vec13, vec14, vec15; v8i16 dst0, dst1, dst2, dst3, dst4, dst5; - v8i16 filter_vec, const_vec; - v4i32 dst0_r, dst1_r, dst2_r, dst3_r, dst4_r, dst5_r; - v4i32 dst0_l, dst1_l, dst2_l, dst3_l, dst4_l, dst5_l; - v4i32 weight_vec, offset_vec, rnd_vec; - v16i8 mask0 = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8 }; + v8i16 filter_vec, weight_vec_h, offset_vec, denom_vec; + v4i32 weight_vec, rnd_vec; src -= 3; - const_vec = __msa_ldi_h(128); - const_vec <<= 6; weight = weight & 0x0000FFFF; weight_vec = __msa_fill_w(weight); - offset_vec = __msa_fill_w(offset); rnd_vec = __msa_fill_w(rnd_val); + weight *= 128; + rnd_val -= 6; + + weight_vec_h = __msa_fill_h(weight); + offset_vec = __msa_fill_h(offset); + denom_vec = __msa_fill_h(rnd_val); + + weight_vec_h = __msa_srar_h(weight_vec_h, denom_vec); + offset_vec = __msa_adds_s_h(offset_vec, weight_vec_h); + filter_vec = LD_SH(filter); SPLATI_H4_SH(filter_vec, 0, 1, 2, 3, filt0, filt1, filt2, filt3); + mask0 = LD_SB(&ff_hevc_mask_arr[0]); mask1 = mask0 + 2; mask2 = mask0 + 4; mask3 = mask0 + 6; @@ -1074,7 +1190,7 @@ static void hevc_hz_uniwgt_8t_48w_msa(uint8_t *src, mask6 = mask0 + 12; mask7 = mask0 + 14; - for (loop_cnt = height; loop_cnt--;) { + for (loop_cnt = 64; loop_cnt--;) { LD_SB3(src, 16, src0, src1, src2); src3 = LD_SB(src + 40); src += src_stride; @@ -1082,49 +1198,39 @@ static void hevc_hz_uniwgt_8t_48w_msa(uint8_t *src, VSHF_B4_SB(src0, src0, mask0, mask1, mask2, mask3, vec0, vec1, vec2, vec3); - dst0 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst0, dst0, dst0, dst0); VSHF_B4_SB(src0, src1, mask4, mask5, mask6, mask7, - vec0, vec1, vec2, vec3); - dst1 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst1, dst1, dst1, dst1); + vec4, vec5, vec6, vec7); VSHF_B4_SB(src1, src1, mask0, mask1, mask2, mask3, - vec0, vec1, vec2, vec3); - dst2 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst2, dst2, dst2, dst2); + vec8, vec9, vec10, vec11); VSHF_B4_SB(src1, src2, mask4, mask5, mask6, mask7, - vec0, vec1, vec2, vec3); - dst3 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst3, dst3, dst3, dst3); + vec12, vec13, vec14, vec15); + dst0 = HEVC_FILT_8TAP_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, + filt3); + dst1 = HEVC_FILT_8TAP_SH(vec4, vec5, vec6, vec7, filt0, filt1, filt2, + filt3); + dst2 = HEVC_FILT_8TAP_SH(vec8, vec9, vec10, vec11, filt0, filt1, filt2, + filt3); + dst3 = HEVC_FILT_8TAP_SH(vec12, vec13, vec14, vec15, filt0, filt1, + filt2, filt3); + VSHF_B4_SB(src2, src2, mask0, mask1, mask2, mask3, vec0, vec1, vec2, vec3); - dst4 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst4, dst4, dst4, dst4); VSHF_B4_SB(src3, src3, mask0, mask1, mask2, mask3, - vec0, vec1, vec2, vec3); - dst5 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst5, dst5, dst5, dst5); - - HEVC_UNIW_RND_CLIP4(dst0, dst1, dst2, dst3, - weight_vec, offset_vec, rnd_vec, - dst0_r, dst1_r, dst2_r, dst3_r, - dst0_l, dst1_l, dst2_l, dst3_l); + vec4, vec5, vec6, vec7); + dst4 = HEVC_FILT_8TAP_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, + filt3); + dst5 = HEVC_FILT_8TAP_SH(vec4, vec5, vec6, vec7, filt0, filt1, filt2, + filt3); - HEVC_UNIW_RND_CLIP2(dst4, dst5, weight_vec, offset_vec, rnd_vec, - dst4_r, dst5_r, dst4_l, dst5_l); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst0, dst1, dst2, dst3, weight_vec, + offset_vec, rnd_vec, dst0, dst1, dst2, + dst3); + HEVC_UNIW_RND_CLIP2_MAX_SATU_H(dst4, dst5, weight_vec, offset_vec, + rnd_vec, dst4, dst5); - HEVC_PCK_SW_SB12(dst0_l, dst0_r, dst1_l, dst1_r, - dst2_l, dst2_r, dst3_l, dst3_r, - dst4_l, dst4_r, dst5_l, dst5_r, - dst0_r, dst1_r, dst2_r); - ST_SW2(dst0_r, dst1_r, dst, 16); - ST_SW(dst2_r, dst + 32); + PCKEV_B3_UB(dst1, dst0, dst3, dst2, dst5, dst4, out0, out1, out2); + ST_UB2(out0, out1, dst, 16); + ST_UB(out2, dst + 32); dst += dst_stride; } } @@ -1142,28 +1248,35 @@ static void hevc_hz_uniwgt_8t_64w_msa(uint8_t *src, uint8_t *src_tmp; uint8_t *dst_tmp; uint32_t loop_cnt, cnt; + v16u8 out0, out1; v16i8 src0, src1, src2; v8i16 filt0, filt1, filt2, filt3; - v16i8 mask1, mask2, mask3, mask4, mask5, mask6, mask7; - v16i8 vec0, vec1, vec2, vec3; + v16i8 mask0, mask1, mask2, mask3, mask4, mask5, mask6, mask7; + v16i8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; + v16i8 vec8, vec9, vec10, vec11, vec12, vec13, vec14, vec15; v8i16 dst0, dst1, dst2, dst3; - v8i16 filter_vec, const_vec; - v4i32 dst0_r, dst1_r, dst2_r, dst3_r, dst0_l, dst1_l, dst2_l, dst3_l; - v4i32 weight_vec, offset_vec, rnd_vec; - v16i8 mask0 = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8 }; + v8i16 filter_vec, weight_vec_h, offset_vec, denom_vec; + v4i32 weight_vec, rnd_vec; src -= 3; - const_vec = __msa_ldi_h(128); - const_vec <<= 6; - weight = weight & 0x0000FFFF; weight_vec = __msa_fill_w(weight); - offset_vec = __msa_fill_w(offset); rnd_vec = __msa_fill_w(rnd_val); + weight *= 128; + rnd_val -= 6; + + weight_vec_h = __msa_fill_h(weight); + offset_vec = __msa_fill_h(offset); + denom_vec = __msa_fill_h(rnd_val); + + weight_vec_h = __msa_srar_h(weight_vec_h, denom_vec); + offset_vec = __msa_adds_s_h(offset_vec, weight_vec_h); + filter_vec = LD_SH(filter); SPLATI_H4_SH(filter_vec, 0, 1, 2, 3, filt0, filt1, filt2, filt3); + mask0 = LD_SB(&ff_hevc_mask_arr[0]); mask1 = mask0 + 2; mask2 = mask0 + 4; mask3 = mask0 + 6; @@ -1184,33 +1297,27 @@ static void hevc_hz_uniwgt_8t_64w_msa(uint8_t *src, VSHF_B4_SB(src0, src0, mask0, mask1, mask2, mask3, vec0, vec1, vec2, vec3); - dst0 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst0, dst0, dst0, dst0); VSHF_B4_SB(src0, src1, mask4, mask5, mask6, mask7, - vec0, vec1, vec2, vec3); - dst1 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst1, dst1, dst1, dst1); + vec4, vec5, vec6, vec7); VSHF_B4_SB(src1, src1, mask0, mask1, mask2, mask3, - vec0, vec1, vec2, vec3); - dst2 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst2, dst2, dst2, dst2); + vec8, vec9, vec10, vec11); VSHF_B4_SB(src2, src2, mask0, mask1, mask2, mask3, - vec0, vec1, vec2, vec3); - dst3 = const_vec; - DPADD_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt1, filt2, filt3, - dst3, dst3, dst3, dst3); + vec12, vec13, vec14, vec15); + dst0 = HEVC_FILT_8TAP_SH(vec0, vec1, vec2, vec3, filt0, filt1, + filt2, filt3); + dst1 = HEVC_FILT_8TAP_SH(vec4, vec5, vec6, vec7, filt0, filt1, + filt2, filt3); + dst2 = HEVC_FILT_8TAP_SH(vec8, vec9, vec10, vec11, filt0, filt1, + filt2, filt3); + dst3 = HEVC_FILT_8TAP_SH(vec12, vec13, vec14, vec15, filt0, filt1, + filt2, filt3); - HEVC_UNIW_RND_CLIP4(dst0, dst1, dst2, dst3, - weight_vec, offset_vec, rnd_vec, - dst0_r, dst1_r, dst2_r, dst3_r, - dst0_l, dst1_l, dst2_l, dst3_l); + HEVC_UNIW_RND_CLIP4_MAX_SATU_H(dst0, dst1, dst2, dst3, weight_vec, + offset_vec, rnd_vec, dst0, dst1, + dst2, dst3); - HEVC_PCK_SW_SB8(dst0_l, dst0_r, dst1_l, dst1_r, - dst2_l, dst2_r, dst3_l, dst3_r, dst0_r, dst1_r); - ST_SW2(dst0_r, dst1_r, dst_tmp, 16); + PCKEV_B2_UB(dst1, dst0, dst3, dst2, out0, out1); + ST_UB2(out0, out1, dst_tmp, 16); dst_tmp += 32; } From ff53f4dc2dd82df01588c12fab9068079ddb00c6 Mon Sep 17 00:00:00 2001 From: Kaustubh Raste Date: Mon, 9 Oct 2017 17:48:45 +0530 Subject: [PATCH 3318/3374] avcodec/mips: Improve avc uni copy mc msa functions Load the specific bytes instead of MSA load. Signed-off-by: Kaustubh Raste Reviewed-by: Manojkumar Bhosale Signed-off-by: Michael Niedermayer --- libavcodec/mips/hevc_mc_uni_msa.c | 245 ++++++++++++------------------ 1 file changed, 100 insertions(+), 145 deletions(-) diff --git a/libavcodec/mips/hevc_mc_uni_msa.c b/libavcodec/mips/hevc_mc_uni_msa.c index cf22e7f1a1390..eead591ff492e 100644 --- a/libavcodec/mips/hevc_mc_uni_msa.c +++ b/libavcodec/mips/hevc_mc_uni_msa.c @@ -28,83 +28,39 @@ static void copy_width8_msa(uint8_t *src, int32_t src_stride, { int32_t cnt; uint64_t out0, out1, out2, out3, out4, out5, out6, out7; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - - if (0 == height % 12) { - for (cnt = (height / 12); cnt--;) { - LD_UB8(src, src_stride, - src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - - out0 = __msa_copy_u_d((v2i64) src0, 0); - out1 = __msa_copy_u_d((v2i64) src1, 0); - out2 = __msa_copy_u_d((v2i64) src2, 0); - out3 = __msa_copy_u_d((v2i64) src3, 0); - out4 = __msa_copy_u_d((v2i64) src4, 0); - out5 = __msa_copy_u_d((v2i64) src5, 0); - out6 = __msa_copy_u_d((v2i64) src6, 0); - out7 = __msa_copy_u_d((v2i64) src7, 0); - SD4(out0, out1, out2, out3, dst, dst_stride); - dst += (4 * dst_stride); - SD4(out4, out5, out6, out7, dst, dst_stride); - dst += (4 * dst_stride); - - LD_UB4(src, src_stride, src0, src1, src2, src3); + if (2 == height) { + LD2(src, src_stride, out0, out1); + SD(out0, dst); + dst += dst_stride; + SD(out1, dst); + } else if (6 == height) { + LD4(src, src_stride, out0, out1, out2, out3); + src += (4 * src_stride); + SD4(out0, out1, out2, out3, dst, dst_stride); + dst += (4 * dst_stride); + LD2(src, src_stride, out0, out1); + SD(out0, dst); + dst += dst_stride; + SD(out1, dst); + } else if (0 == (height % 8)) { + for (cnt = (height >> 3); cnt--;) { + LD4(src, src_stride, out0, out1, out2, out3); + src += (4 * src_stride); + LD4(src, src_stride, out4, out5, out6, out7); src += (4 * src_stride); - - out0 = __msa_copy_u_d((v2i64) src0, 0); - out1 = __msa_copy_u_d((v2i64) src1, 0); - out2 = __msa_copy_u_d((v2i64) src2, 0); - out3 = __msa_copy_u_d((v2i64) src3, 0); - - SD4(out0, out1, out2, out3, dst, dst_stride); - dst += (4 * dst_stride); - } - } else if (0 == height % 8) { - for (cnt = height >> 3; cnt--;) { - LD_UB8(src, src_stride, - src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - - out0 = __msa_copy_u_d((v2i64) src0, 0); - out1 = __msa_copy_u_d((v2i64) src1, 0); - out2 = __msa_copy_u_d((v2i64) src2, 0); - out3 = __msa_copy_u_d((v2i64) src3, 0); - out4 = __msa_copy_u_d((v2i64) src4, 0); - out5 = __msa_copy_u_d((v2i64) src5, 0); - out6 = __msa_copy_u_d((v2i64) src6, 0); - out7 = __msa_copy_u_d((v2i64) src7, 0); - SD4(out0, out1, out2, out3, dst, dst_stride); dst += (4 * dst_stride); SD4(out4, out5, out6, out7, dst, dst_stride); dst += (4 * dst_stride); } - } else if (0 == height % 4) { - for (cnt = (height / 4); cnt--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); + } else if (0 == (height % 4)) { + for (cnt = (height >> 2); cnt--;) { + LD4(src, src_stride, out0, out1, out2, out3); src += (4 * src_stride); - out0 = __msa_copy_u_d((v2i64) src0, 0); - out1 = __msa_copy_u_d((v2i64) src1, 0); - out2 = __msa_copy_u_d((v2i64) src2, 0); - out3 = __msa_copy_u_d((v2i64) src3, 0); - SD4(out0, out1, out2, out3, dst, dst_stride); dst += (4 * dst_stride); } - } else if (0 == height % 2) { - for (cnt = (height / 2); cnt--;) { - LD_UB2(src, src_stride, src0, src1); - src += (2 * src_stride); - out0 = __msa_copy_u_d((v2i64) src0, 0); - out1 = __msa_copy_u_d((v2i64) src1, 0); - - SD(out0, dst); - dst += dst_stride; - SD(out1, dst); - dst += dst_stride; - } } } @@ -122,33 +78,6 @@ static void copy_width12_msa(uint8_t *src, int32_t src_stride, ST12x8_UB(src0, src1, src2, src3, src4, src5, src6, src7, dst, dst_stride); } -static void copy_16multx8mult_msa(uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height, int32_t width) -{ - int32_t cnt, loop_cnt; - uint8_t *src_tmp, *dst_tmp; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - - for (cnt = (width >> 4); cnt--;) { - src_tmp = src; - dst_tmp = dst; - - for (loop_cnt = (height >> 3); loop_cnt--;) { - LD_UB8(src_tmp, src_stride, - src0, src1, src2, src3, src4, src5, src6, src7); - src_tmp += (8 * src_stride); - - ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, - dst_tmp, dst_stride); - dst_tmp += (8 * dst_stride); - } - - src += 16; - dst += 16; - } -} - static void copy_width16_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, int32_t height) @@ -156,23 +85,25 @@ static void copy_width16_msa(uint8_t *src, int32_t src_stride, int32_t cnt; v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - if (0 == height % 12) { - for (cnt = (height / 12); cnt--;) { - LD_UB8(src, src_stride, - src0, src1, src2, src3, src4, src5, src6, src7); + if (12 == height) { + LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); + src += (8 * src_stride); + ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, dst, dst_stride); + dst += (8 * dst_stride); + LD_UB4(src, src_stride, src0, src1, src2, src3); + src += (4 * src_stride); + ST_UB4(src0, src1, src2, src3, dst, dst_stride); + dst += (4 * dst_stride); + } else if (0 == (height % 8)) { + for (cnt = (height >> 3); cnt--;) { + LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, + src7); src += (8 * src_stride); - ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, - dst, dst_stride); + ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, dst, + dst_stride); dst += (8 * dst_stride); - - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - ST_UB4(src0, src1, src2, src3, dst, dst_stride); - dst += (4 * dst_stride); } - } else if (0 == height % 8) { - copy_16multx8mult_msa(src, src_stride, dst, dst_stride, height, 16); - } else if (0 == height % 4) { + } else if (0 == (height % 4)) { for (cnt = (height >> 2); cnt--;) { LD_UB4(src, src_stride, src0, src1, src2, src3); src += (4 * src_stride); @@ -187,8 +118,23 @@ static void copy_width24_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, int32_t height) { - copy_16multx8mult_msa(src, src_stride, dst, dst_stride, height, 16); - copy_width8_msa(src + 16, src_stride, dst + 16, dst_stride, height); + int32_t cnt; + v16u8 src0, src1, src2, src3, src4, src5, src6, src7; + uint64_t out0, out1, out2, out3, out4, out5, out6, out7; + + for (cnt = 4; cnt--;) { + LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); + LD4(src + 16, src_stride, out0, out1, out2, out3); + src += (4 * src_stride); + LD4(src + 16, src_stride, out4, out5, out6, out7); + src += (4 * src_stride); + + ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, dst, dst_stride); + SD4(out0, out1, out2, out3, dst + 16, dst_stride); + dst += (4 * dst_stride); + SD4(out4, out5, out6, out7, dst + 16, dst_stride); + dst += (4 * dst_stride); + } } static void copy_width32_msa(uint8_t *src, int32_t src_stride, @@ -198,40 +144,13 @@ static void copy_width32_msa(uint8_t *src, int32_t src_stride, int32_t cnt; v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - if (0 == height % 12) { - for (cnt = (height / 12); cnt--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); - LD_UB4(src + 16, src_stride, src4, src5, src6, src7); - src += (4 * src_stride); - ST_UB4(src0, src1, src2, src3, dst, dst_stride); - ST_UB4(src4, src5, src6, src7, dst + 16, dst_stride); - dst += (4 * dst_stride); - - LD_UB4(src, src_stride, src0, src1, src2, src3); - LD_UB4(src + 16, src_stride, src4, src5, src6, src7); - src += (4 * src_stride); - ST_UB4(src0, src1, src2, src3, dst, dst_stride); - ST_UB4(src4, src5, src6, src7, dst + 16, dst_stride); - dst += (4 * dst_stride); - - LD_UB4(src, src_stride, src0, src1, src2, src3); - LD_UB4(src + 16, src_stride, src4, src5, src6, src7); - src += (4 * src_stride); - ST_UB4(src0, src1, src2, src3, dst, dst_stride); - ST_UB4(src4, src5, src6, src7, dst + 16, dst_stride); - dst += (4 * dst_stride); - } - } else if (0 == height % 8) { - copy_16multx8mult_msa(src, src_stride, dst, dst_stride, height, 32); - } else if (0 == height % 4) { - for (cnt = (height >> 2); cnt--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); - LD_UB4(src + 16, src_stride, src4, src5, src6, src7); - src += (4 * src_stride); - ST_UB4(src0, src1, src2, src3, dst, dst_stride); - ST_UB4(src4, src5, src6, src7, dst + 16, dst_stride); - dst += (4 * dst_stride); - } + for (cnt = (height >> 2); cnt--;) { + LD_UB4(src, src_stride, src0, src1, src2, src3); + LD_UB4(src + 16, src_stride, src4, src5, src6, src7); + src += (4 * src_stride); + ST_UB4(src0, src1, src2, src3, dst, dst_stride); + ST_UB4(src4, src5, src6, src7, dst + 16, dst_stride); + dst += (4 * dst_stride); } } @@ -239,14 +158,50 @@ static void copy_width48_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, int32_t height) { - copy_16multx8mult_msa(src, src_stride, dst, dst_stride, height, 48); + int32_t cnt; + v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; + v16u8 src11; + + for (cnt = (height >> 2); cnt--;) { + LD_UB4(src, src_stride, src0, src1, src2, src3); + LD_UB4(src + 16, src_stride, src4, src5, src6, src7); + LD_UB4(src + 32, src_stride, src8, src9, src10, src11); + src += (4 * src_stride); + + ST_UB4(src0, src1, src2, src3, dst, dst_stride); + ST_UB4(src4, src5, src6, src7, dst + 16, dst_stride); + ST_UB4(src8, src9, src10, src11, dst + 32, dst_stride); + dst += (4 * dst_stride); + } } static void copy_width64_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, int32_t height) { - copy_16multx8mult_msa(src, src_stride, dst, dst_stride, height, 64); + int32_t cnt; + v16u8 src0, src1, src2, src3, src4, src5, src6, src7; + v16u8 src8, src9, src10, src11, src12, src13, src14, src15; + + for (cnt = (height >> 2); cnt--;) { + LD_UB4(src, 16, src0, src1, src2, src3); + src += src_stride; + LD_UB4(src, 16, src4, src5, src6, src7); + src += src_stride; + LD_UB4(src, 16, src8, src9, src10, src11); + src += src_stride; + LD_UB4(src, 16, src12, src13, src14, src15); + src += src_stride; + + ST_UB4(src0, src1, src2, src3, dst, 16); + dst += dst_stride; + ST_UB4(src4, src5, src6, src7, dst, 16); + dst += dst_stride; + ST_UB4(src8, src9, src10, src11, dst, 16); + dst += dst_stride; + ST_UB4(src12, src13, src14, src15, dst, 16); + dst += dst_stride; + } } static const uint8_t mc_filt_mask_arr[16 * 3] = { From 832fc05a9bc79e4f176d5f93a0defc521c75bee7 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 11 Oct 2017 00:01:10 +0200 Subject: [PATCH 3319/3374] avutil/frame: Fix project name Issue introduced in: caa12027baf1180453846c58da08fc87accc0ff6 Signed-off-by: Michael Niedermayer --- libavutil/frame.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavutil/frame.h b/libavutil/frame.h index b8591a442bba2..abe4f4fd178d5 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -783,8 +783,8 @@ enum { /** * Apply the maximum possible cropping, even if it requires setting the * AVFrame.data[] entries to unaligned pointers. Passing unaligned data - * to Libav API is generally not allowed, and causes undefined behavior - * (such as crashes). You can pass unaligned data only to Libav APIs that + * to FFmpeg API is generally not allowed, and causes undefined behavior + * (such as crashes). You can pass unaligned data only to FFmpeg APIs that * are explicitly documented to accept it. Use this flag only if you * absolutely know what you are doing. */ From ed8ff608b2b4901089270d9c53bdff7d03ec01ca Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 11 Oct 2017 00:12:12 +0200 Subject: [PATCH 3320/3374] doc/APIchanges: Update Signed-off-by: Michael Niedermayer --- doc/APIchanges | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 5c6376243fb68..262ca7dbcad70 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,97 +15,97 @@ libavutil: 2015-08-28 API changes, most recent first: -2017-09-28 - xxxxxxx - lavc 57.106.104 - avcodec.h +2017-09-28 - b6cf66ae1c - lavc 57.106.104 - avcodec.h Add AV_PKT_DATA_A53_CC packet side data, to export closed captions -2017-09-27 - xxxxxxx - lavu 55.77.101 / lavu 55.31.1 - frame.h +2017-09-27 - 7aa6b8a68f - lavu 55.77.101 / lavu 55.31.1 - frame.h Allow passing the value of 0 (meaning "automatic") as the required alignment to av_frame_get_buffer(). -2017-09-27 - xxxxxxx - lavu 55.77.100 / lavu 55.31.0 - cpu.h +2017-09-27 - 522f877086 - lavu 55.77.100 / lavu 55.31.0 - cpu.h Add av_cpu_max_align() for querying maximum required data alignment. -2017-09-26 - xxxxxxx - lavc 57.106.102 - avcodec.h +2017-09-26 - b1cf151c4d - lavc 57.106.102 - avcodec.h Deprecate AVCodecContext.refcounted_frames. This was useful for deprecated API only (avcodec_decode_video2/avcodec_decode_audio4). The new decode APIs (avcodec_send_packet/avcodec_receive_frame) always work with reference counted frames. -2017-xx-xx - xxxxxxx - lavu 55.76.100 / 56.6.0 - pixdesc.h +2017-09-21 - 6f15f1cdc8 - lavu 55.76.100 / 56.6.0 - pixdesc.h Add av_color_range_from_name(), av_color_primaries_from_name(), av_color_transfer_from_name(), av_color_space_from_name(), and av_chroma_location_from_name(). -2017-09-13 - xxxxxxx - lavc 57.106.100 - avcodec.h +2017-09-13 - 82342cead1 - lavc 57.106.100 - avcodec.h Add AV_PKT_FLAG_TRUSTED. -2017-09-13 - xxxxxxx - lavu 55.75.100 - hwcontext.h hwcontext_drm.h +2017-09-13 - 9cb23cd9fe - lavu 55.75.100 - hwcontext.h hwcontext_drm.h Add AV_HWDEVICE_TYPE_DRM and implementation. -2017-09-08 - xxxxxxx - lavfi 6.103.100 - buffersrc.h +2017-09-08 - 5ba2aef6ec - lavfi 6.103.100 - buffersrc.h Add av_buffersrc_close(). -2017-09-04 - xxxxxxx - lavc 57.105.100 - avcodec.h +2017-09-04 - 6cadbb16e9 - lavc 57.105.100 - avcodec.h Add AV_HWACCEL_CODEC_CAP_EXPERIMENTAL, replacing the deprecated HWACCEL_CODEC_CAP_EXPERIMENTAL flag. -2017-09-01 - xxxxxxx - lavf 57.81.100 - avio.h +2017-09-01 - 5d76674756 - lavf 57.81.100 - avio.h Add avio_read_partial(). 2017-09-01 - xxxxxxx - lavf 57.80.100 / 57.11.0 - avio.h Add avio_context_free(). From now on it must be used for freeing AVIOContext. -2017-08-08 - xxxxxxx - lavu 55.74.100 - pixdesc.h +2017-08-08 - 1460408703 - lavu 55.74.100 - pixdesc.h Add AV_PIX_FMT_FLAG_FLOAT pixel format flag. -2017-08-08 - xxxxxxx - lavu 55.72.100 - imgutils.h +2017-08-08 - 463b81de2b - lavu 55.72.100 - imgutils.h Add av_image_fill_black(). -2017-08-08 - xxxxxxx - lavu 55.71.100 - frame.h +2017-08-08 - caa12027ba - lavu 55.71.100 - frame.h Add av_frame_apply_cropping(). 2017-07-25 - 24de4fddca - lavu 55.69.100 - frame.h Add AV_FRAME_DATA_ICC_PROFILE side data type. -2017-xx-xx - xxxxxxx - lavc 57.100.100 - avcodec.h +2017-06-27 - 70143a3954 - lavc 57.100.100 - avcodec.h DXVA2 and D3D11 hardware accelerated decoding now supports the new hwaccel API, which can create the decoder context and allocate hardware frame automatically. See AVCodecContext.hw_device_ctx and AVCodecContext.hw_frames_ctx. For D3D11, the new AV_PIX_FMT_D3D11 pixfmt must be used with the new API. -2017-xx-xx - xxxxxxx - lavu 56.67.100 - hwcontext.h +2017-06-27 - 3303511f33 - lavu 56.67.100 - hwcontext.h Add AV_HWDEVICE_TYPE_D3D11VA and AV_PIX_FMT_D3D11. -2017-06-24 - xxxxxxx - lavf 57.75.100 - avio.h +2017-06-24 - 09891c5391 - lavf 57.75.100 - avio.h Add AVIO_DATA_MARKER_FLUSH_POINT to signal preferred flush points to aviobuf. -2017-06-14 - xxxxxxx - lavu 55.66.100 - hwcontext.h +2017-06-14 - d59c6a3aeb - lavu 55.66.100 - hwcontext.h av_hwframe_ctx_create_derived() now takes some AV_HWFRAME_MAP_* combination as its flags argument (which was previously unused). -2017-06-14 - xxxxxxx - lavc 57.99.100 - avcodec.h +2017-06-14 - 49ae8a5e87 - lavc 57.99.100 - avcodec.h Add AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH. -2017-06-14 - xxxxxxx - lavu 55.65.100 - hwcontext.h +2017-06-14 - 0b1794a43e - lavu 55.65.100 - hwcontext.h Add AV_HWDEVICE_TYPE_NONE, av_hwdevice_find_type_by_name(), av_hwdevice_get_type_name() and av_hwdevice_iterate_types(). -2017-06-14 - xxxxxxx - lavu 55.64.100 - hwcontext.h +2017-06-14 - b22172f6f3 - lavu 55.64.100 - hwcontext.h Add av_hwdevice_ctx_create_derived(). -2017-05-15 - xxxxxxxxxx - lavc 57.96.100 - avcodec.h +2017-05-15 - 532b23f079 - lavc 57.96.100 - avcodec.h VideoToolbox hardware-accelerated decoding now supports the new hwaccel API, which can create the decoder context and allocate hardware frames automatically. See AVCodecContext.hw_device_ctx and AVCodecContext.hw_frames_ctx. -2017-05-15 - xxxxxxxxxx - lavu 57.63.100 - hwcontext.h +2017-05-15 - 532b23f079 - lavu 57.63.100 - hwcontext.h Add AV_HWDEVICE_TYPE_VIDEOTOOLBOX and implementation. -2017-xx-xx - xxxxxxx - lavc 57.95.100 / 57.31.0 - avcodec.h +2017-05-08 - f089e02fa2 - lavc 57.95.100 / 57.31.0 - avcodec.h Add AVCodecContext.apply_cropping to control whether cropping is handled by libavcodec or the caller. -2017-xx-xx - xxxxxxx - lavu 55.62.100 / 55.30.0 - frame.h +2017-05-08 - a47bd5d77e - lavu 55.62.100 / 55.30.0 - frame.h Add AVFrame.crop_left/right/top/bottom fields for attaching cropping information to video frames. @@ -113,7 +113,7 @@ API changes, most recent first: Change av_sha_update(), av_sha512_update() and av_md5_sum()/av_md5_update() length parameter type to size_t at next major bump. -2017-05-05 - xxxxxxxxxx - lavc 57.94.100 - avcodec.h +2017-05-05 - c0f17a905f - lavc 57.94.100 - avcodec.h The cuvid decoders now support AVCodecContext.hw_device_ctx, which removes the requirement to set an incomplete AVCodecContext.hw_frames_ctx only to set the Cuda device handle. From e1de9eab3a4345036ae7129756b04200df887be4 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 11 Oct 2017 01:21:12 +0200 Subject: [PATCH 3321/3374] Bump minor versions for branching 3.4 Signed-off-by: Michael Niedermayer --- libavcodec/version.h | 4 ++-- libavdevice/version.h | 4 ++-- libavfilter/version.h | 4 ++-- libavformat/version.h | 4 ++-- libavresample/version.h | 2 +- libavutil/version.h | 4 ++-- libpostproc/version.h | 2 +- libswresample/version.h | 2 +- libswscale/version.h | 4 ++-- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/libavcodec/version.h b/libavcodec/version.h index 7aee6f9cf30c5..10d9ac4eb3c04 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 106 -#define LIBAVCODEC_VERSION_MICRO 104 +#define LIBAVCODEC_VERSION_MINOR 107 +#define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavdevice/version.h b/libavdevice/version.h index 14b8e2acaed42..9d900877af962 100644 --- a/libavdevice/version.h +++ b/libavdevice/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVDEVICE_VERSION_MAJOR 57 -#define LIBAVDEVICE_VERSION_MINOR 9 -#define LIBAVDEVICE_VERSION_MICRO 102 +#define LIBAVDEVICE_VERSION_MINOR 10 +#define LIBAVDEVICE_VERSION_MICRO 100 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ LIBAVDEVICE_VERSION_MINOR, \ diff --git a/libavfilter/version.h b/libavfilter/version.h index 8191c59a15d83..3e67ad354c215 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,8 +30,8 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 6 -#define LIBAVFILTER_VERSION_MINOR 106 -#define LIBAVFILTER_VERSION_MICRO 101 +#define LIBAVFILTER_VERSION_MINOR 107 +#define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ LIBAVFILTER_VERSION_MINOR, \ diff --git a/libavformat/version.h b/libavformat/version.h index caf85e8538d21..878917d65ddb1 100644 --- a/libavformat/version.h +++ b/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 57 -#define LIBAVFORMAT_VERSION_MINOR 82 -#define LIBAVFORMAT_VERSION_MICRO 104 +#define LIBAVFORMAT_VERSION_MINOR 83 +#define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ diff --git a/libavresample/version.h b/libavresample/version.h index f6d99cba0836d..20c78c74d3f5a 100644 --- a/libavresample/version.h +++ b/libavresample/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVRESAMPLE_VERSION_MAJOR 3 -#define LIBAVRESAMPLE_VERSION_MINOR 6 +#define LIBAVRESAMPLE_VERSION_MINOR 7 #define LIBAVRESAMPLE_VERSION_MICRO 0 #define LIBAVRESAMPLE_VERSION_INT AV_VERSION_INT(LIBAVRESAMPLE_VERSION_MAJOR, \ diff --git a/libavutil/version.h b/libavutil/version.h index dee4f5b4c5087..f594dc069185f 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -80,8 +80,8 @@ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 77 -#define LIBAVUTIL_VERSION_MICRO 101 +#define LIBAVUTIL_VERSION_MINOR 78 +#define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ LIBAVUTIL_VERSION_MINOR, \ diff --git a/libpostproc/version.h b/libpostproc/version.h index 3d7f8ea472d74..e8f0abe81374f 100644 --- a/libpostproc/version.h +++ b/libpostproc/version.h @@ -29,7 +29,7 @@ #include "libavutil/avutil.h" #define LIBPOSTPROC_VERSION_MAJOR 54 -#define LIBPOSTPROC_VERSION_MINOR 6 +#define LIBPOSTPROC_VERSION_MINOR 7 #define LIBPOSTPROC_VERSION_MICRO 100 #define LIBPOSTPROC_VERSION_INT AV_VERSION_INT(LIBPOSTPROC_VERSION_MAJOR, \ diff --git a/libswresample/version.h b/libswresample/version.h index 379177a1f46bf..6a66173f3bd13 100644 --- a/libswresample/version.h +++ b/libswresample/version.h @@ -29,7 +29,7 @@ #include "libavutil/avutil.h" #define LIBSWRESAMPLE_VERSION_MAJOR 2 -#define LIBSWRESAMPLE_VERSION_MINOR 8 +#define LIBSWRESAMPLE_VERSION_MINOR 9 #define LIBSWRESAMPLE_VERSION_MICRO 100 #define LIBSWRESAMPLE_VERSION_INT AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \ diff --git a/libswscale/version.h b/libswscale/version.h index dcf7959b23630..474e93b2615e3 100644 --- a/libswscale/version.h +++ b/libswscale/version.h @@ -27,8 +27,8 @@ #include "libavutil/version.h" #define LIBSWSCALE_VERSION_MAJOR 4 -#define LIBSWSCALE_VERSION_MINOR 7 -#define LIBSWSCALE_VERSION_MICRO 103 +#define LIBSWSCALE_VERSION_MINOR 8 +#define LIBSWSCALE_VERSION_MICRO 100 #define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \ LIBSWSCALE_VERSION_MINOR, \ From 92ae4ab56d0d8ce2875d991e1af95970f7f7fb6c Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 11 Oct 2017 01:23:03 +0200 Subject: [PATCH 3322/3374] doc/APIchanges: Add 3.4 cut point Signed-off-by: Michael Niedermayer --- doc/APIchanges | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/APIchanges b/doc/APIchanges index 262ca7dbcad70..6803eaaea2d62 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,8 @@ libavutil: 2015-08-28 API changes, most recent first: +-------- 8< --------- FFmpeg 3.4 was cut here -------- 8< --------- + 2017-09-28 - b6cf66ae1c - lavc 57.106.104 - avcodec.h Add AV_PKT_DATA_A53_CC packet side data, to export closed captions From 74d2bbb70dbe4b05dfc4ce54a5e4f7bf1f765ee5 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 11 Oct 2017 02:13:16 +0200 Subject: [PATCH 3323/3374] avcodec/opusenc_psy: Fix mixed declaration and statement Signed-off-by: Michael Niedermayer --- libavcodec/opusenc_psy.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/opusenc_psy.c b/libavcodec/opusenc_psy.c index bb673bef68ad1..b446d41f755db 100644 --- a/libavcodec/opusenc_psy.c +++ b/libavcodec/opusenc_psy.c @@ -370,8 +370,9 @@ static int celt_search_for_tf(OpusPsyContext *s, OpusPsyStep **start, CeltFrame for (cway = 0; cway < 2; cway++) { int mag[2]; int base = f->transient ? 120 : 960; + int i; - for (int i = 0; i < 2; i++) { + for (i = 0; i < 2; i++) { int c = ff_celt_tf_select[f->size][f->transient][cway][i]; mag[i] = c < 0 ? base >> FFABS(c) : base << FFABS(c); } From 7bec3f78da2533968b7246ff222770582ab4aafb Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 11 Oct 2017 02:15:21 +0200 Subject: [PATCH 3324/3374] avcodec/rkmppdec: check wether typo Signed-off-by: Michael Niedermayer --- libavcodec/rkmppdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/rkmppdec.c b/libavcodec/rkmppdec.c index ca307c894ecf8..bdf4dc4208c3c 100644 --- a/libavcodec/rkmppdec.c +++ b/libavcodec/rkmppdec.c @@ -352,7 +352,7 @@ static int rkmpp_retrieve_frame(AVCodecContext *avctx, AVFrame *frame) } if (mppframe) { - // Check wether we have a special frame or not + // Check whether we have a special frame or not if (mpp_frame_get_info_change(mppframe)) { AVHWFramesContext *hwframes; From b1ec41a64f2def0ce7d5b2b35d9ef478a4a35d26 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 12 Apr 2017 02:26:45 +0200 Subject: [PATCH 3325/3374] add release notes based on release 3.3 Name suggestion was from Helmut K. C. Tessarek Signed-off-by: Michael Niedermayer (cherry picked from commit 07e7ebf52de9257fef1398c1dc5edb847b78ab21) Signed-off-by: Michael Niedermayer --- RELEASE_NOTES | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 RELEASE_NOTES diff --git a/RELEASE_NOTES b/RELEASE_NOTES new file mode 100644 index 0000000000000..d649c77bd5226 --- /dev/null +++ b/RELEASE_NOTES @@ -0,0 +1,15 @@ + + ┌───────────────────────────────────────┐ + │ RELEASE NOTES for FFmpeg 3.4 "Cantor" │ + └───────────────────────────────────────┘ + + The FFmpeg Project proudly presents FFmpeg 3.4 "Cantor", about 6 + months after the release of FFmpeg 3.3. + + A complete Changelog is available at the root of the project, and the + complete Git history on http://source.ffmpeg.org. + + We hope you will like this release as much as we enjoyed working on it, and + as usual, if you have any questions about it, or any FFmpeg related topic, + feel free to join us on the #ffmpeg IRC channel (on irc.freenode.net) or ask + on the mailing-lists. From c8642473e0b3d2c2d644c72eb7e4de23fa3f79fa Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Tue, 10 Oct 2017 23:30:29 +0200 Subject: [PATCH 3326/3374] configure: remove libdl dependency from libndi_newtek We are not using dynamic loading for libndi. Reviewed-by: James Almer Signed-off-by: Marton Balint (cherry picked from commit 58143b15adda6391ec07f3eb19e80ed91d801edd) --- configure | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index e2ef54fb3b213..259619cccd0b0 100755 --- a/configure +++ b/configure @@ -3089,9 +3089,9 @@ decklink_indev_deps="decklink threads" decklink_indev_extralibs="-lstdc++" decklink_outdev_deps="decklink threads" decklink_outdev_extralibs="-lstdc++" -libndi_newtek_indev_deps="libndi_newtek libdl" +libndi_newtek_indev_deps="libndi_newtek" libndi_newtek_indev_extralibs="-lndi" -libndi_newtek_outdev_deps="libndi_newtek libdl" +libndi_newtek_outdev_deps="libndi_newtek" libndi_newtek_outdev_extralibs="-lndi" dshow_indev_deps="IBaseFilter" dshow_indev_extralibs="-lpsapi -lole32 -lstrmiids -luuid -loleaut32 -lshlwapi" From 7fb85ad3607a3fdde682ea74d6f6bcefe1f582dd Mon Sep 17 00:00:00 2001 From: Ivan Kalvachev Date: Mon, 9 Oct 2017 02:40:26 +0300 Subject: [PATCH 3327/3374] Fix crash if av_vdpau_bind_context() is not used. The public functions av_alloc_vdpaucontext() and av_vdpau_alloc_context() are allocating AVVDPAUContext structure that is supposed to be placed in avctx->hwaccel_context. However the rest of libavcodec/vdpau.c uses avctx->hwaccel_context as struct VDPAUHWContext, that is bigger and does contain AVVDPAUContext as first member. The usage includes write to the new variables in the bigger stuct, without checking for block size. Fix by always allocating the bigger structure. Signed-off-by: Ivan Kalvachev (cherry picked from commit 3a6ded7cfcb33e06ade98c5791eae06453f65668) --- libavcodec/vdpau.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c index 42ebddbeeee2e..4cc51cb79ed12 100644 --- a/libavcodec/vdpau.c +++ b/libavcodec/vdpau.c @@ -816,7 +816,7 @@ do { \ AVVDPAUContext *av_vdpau_alloc_context(void) { - return av_mallocz(sizeof(AVVDPAUContext)); + return av_mallocz(sizeof(VDPAUHWContext)); } int av_vdpau_bind_context(AVCodecContext *avctx, VdpDevice device, From 7deb7e6acd4fb8dd09c8e38eb2e07c86371bf94e Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 13 Oct 2017 12:34:34 -0300 Subject: [PATCH 3328/3374] configure: force erroring out in check_disable_warning() if an option doesn't exists Should prevent some options from being added to cflags when they don't exist and the compiler only warns about it. Reviewd-by: Michael Niedermayer Signed-off-by: James Almer (cherry picked from commit ad56e8057d8af0201ed0cb65acc12e5889d4afcc) --- configure | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 259619cccd0b0..18d80ee87ac91 100755 --- a/configure +++ b/configure @@ -6309,9 +6309,14 @@ fi check_disable_warning(){ warning_flag=-W${1#-Wno-} - test_cflags $warning_flag && add_cflags $1 + test_cflags $unknown_warning_flags $warning_flag && add_cflags $1 } +test_cflags -Werror=unused-command-line-argument && + append unknown_warning_flags "-Werror=unused-command-line-argument" +test_cflags -Werror=unknown-warning-option && + append unknown_warning_flags "-Werror=unknown-warning-option" + check_disable_warning -Wno-parentheses check_disable_warning -Wno-switch check_disable_warning -Wno-format-zero-length From a11a18b284afd5ac58fd3b1835f8a3608c4ebc9f Mon Sep 17 00:00:00 2001 From: Ivan Kalvachev Date: Mon, 9 Oct 2017 01:25:00 +0300 Subject: [PATCH 3329/3374] Fix visual glitch with XvMC, caused by wrong idct permutation. In the past XvMC forced simple_idct since it was using FF_IDCT_PERM_NONE. However now we have SIMD variants of simple_idct that are using FF_IDCT_PERM_TRANSPOSE and if they are selected XvMC would get coefficients in the wrong order. The patch creates new FF_IDCT_NONE that is used only for this kind of hardware decoding and that fallbacks to the old C only simple idct. Signed-off-by: Ivan Kalvachev Signed-off-by: Michael Niedermayer (cherry picked from commit 9054439bad3307dafd9fbadc57e66c276baf22e2) Signed-off-by: Michael Niedermayer --- libavcodec/avcodec.h | 1 + libavcodec/idctdsp.c | 1 + libavcodec/mpeg12dec.c | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 52cc5b0ca08ad..18c3e3ea1ee91 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3146,6 +3146,7 @@ typedef struct AVCodecContext { #if FF_API_ARCH_ALPHA #define FF_IDCT_SIMPLEALPHA 23 #endif +#define FF_IDCT_NONE 24 /* Used by XvMC to extract IDCT coefficients with FF_IDCT_PERM_NONE */ #define FF_IDCT_SIMPLEAUTO 128 /** diff --git a/libavcodec/idctdsp.c b/libavcodec/idctdsp.c index d596aed1a9e5a..0122d29efa325 100644 --- a/libavcodec/idctdsp.c +++ b/libavcodec/idctdsp.c @@ -279,6 +279,7 @@ av_cold void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx) c->perm_type = FF_IDCT_PERM_NONE; #endif /* CONFIG_FAANIDCT */ } else { // accurate/default + /* Be sure FF_IDCT_NONE will select this one, since it uses FF_IDCT_PERM_NONE */ c->idct_put = ff_simple_idct_put_8; c->idct_add = ff_simple_idct_add_8; c->idct = ff_simple_idct_8; diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c index 22c29c1505283..4e68be27f1d26 100644 --- a/libavcodec/mpeg12dec.c +++ b/libavcodec/mpeg12dec.c @@ -1217,7 +1217,7 @@ static void setup_hwaccel_for_pixfmt(AVCodecContext *avctx) #endif ) if (avctx->idct_algo == FF_IDCT_AUTO) - avctx->idct_algo = FF_IDCT_SIMPLE; + avctx->idct_algo = FF_IDCT_NONE; if (avctx->hwaccel && avctx->pix_fmt == AV_PIX_FMT_XVMC) { Mpeg1Context *s1 = avctx->priv_data; From 8500de89ea9111e859c1ca8c51e7a3ed2ff76846 Mon Sep 17 00:00:00 2001 From: Sasi Inguva Date: Tue, 10 Oct 2017 10:36:58 -0700 Subject: [PATCH 3330/3374] ffmpeg.c: Fallback to duration_dts, when duration_pts can't be determined. This is required for FLV files, for which duration_pts comes out to be zero. Signed-off-by: Sasi Inguva Reviewed-by: Thomas Mundt Signed-off-by: Michael Niedermayer (cherry picked from commit 2b006ccf8318d84101ed83b75df4c9682a963217) Signed-off-by: Michael Niedermayer --- fftools/ffmpeg.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 6d64bc1043ad0..3ee31473dc5c4 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -2665,8 +2665,13 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo ist->next_dts = AV_NOPTS_VALUE; } - if (got_output) - ist->next_pts += av_rescale_q(duration_pts, ist->st->time_base, AV_TIME_BASE_Q); + if (got_output) { + if (duration_pts > 0) { + ist->next_pts += av_rescale_q(duration_pts, ist->st->time_base, AV_TIME_BASE_Q); + } else { + ist->next_pts += duration_dts; + } + } break; case AVMEDIA_TYPE_SUBTITLE: if (repeating) From 35e36046f1a3013f24cd2e90cff14295427dc3af Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 13 Oct 2017 03:06:53 +0200 Subject: [PATCH 3331/3374] avcodec/pafvideo: Check for bitstream end in decode_0() Fixes: Timeout Fixes: 3529/clusterfuzz-testcase-5057068371279872 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer (cherry picked from commit 9c85329cd02e9284892bf263ce6133b2fc479792) Signed-off-by: Michael Niedermayer --- libavcodec/pafvideo.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/pafvideo.c b/libavcodec/pafvideo.c index 91bfe16376be5..6980ae1b352be 100644 --- a/libavcodec/pafvideo.c +++ b/libavcodec/pafvideo.c @@ -181,6 +181,8 @@ static int decode_0(PAFVideoDecContext *c, uint8_t *pkt, uint8_t code) dend = c->frame[page] + c->frame_size; offset = (x & 0x7F) * 2; j = bytestream2_get_le16(&c->gb) + offset; + if (bytestream2_get_bytes_left(&c->gb) < (j - offset) * 16) + return AVERROR_INVALIDDATA; do { offset++; if (dst + 3 * c->width + 4 > dend) @@ -198,7 +200,8 @@ static int decode_0(PAFVideoDecContext *c, uint8_t *pkt, uint8_t code) do { set_src_position(c, &src, &send); if ((src + 3 * c->width + 4 > send) || - (dst + 3 * c->width + 4 > dend)) + (dst + 3 * c->width + 4 > dend) || + bytestream2_get_bytes_left(&c->gb) < 4) return AVERROR_INVALIDDATA; copy_block4(dst, src, c->width, c->width, 4); i++; From 46abeb1c322302ce6eba745c9efaf806f066298c Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 13 Oct 2017 03:06:54 +0200 Subject: [PATCH 3332/3374] avcodec/snowdec: Check mv_scale Fixes: runtime error: signed integer overflow: 2 * -1094995530 cannot be represented in type 'int' Fixes: 3512/clusterfuzz-testcase-minimized-4812747210489856 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer (cherry picked from commit 393d6fc7395611a38792e3c271b2be42ac45e672) Signed-off-by: Michael Niedermayer --- libavcodec/snowdec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/snowdec.c b/libavcodec/snowdec.c index b74c468ce32cf..13668c2105ee5 100644 --- a/libavcodec/snowdec.c +++ b/libavcodec/snowdec.c @@ -394,9 +394,10 @@ static int decode_header(SnowContext *s){ s->mv_scale += get_symbol(&s->c, s->header_state, 1); s->qbias += get_symbol(&s->c, s->header_state, 1); s->block_max_depth+= get_symbol(&s->c, s->header_state, 1); - if(s->block_max_depth > 1 || s->block_max_depth < 0){ + if(s->block_max_depth > 1 || s->block_max_depth < 0 || s->mv_scale > 256U){ av_log(s->avctx, AV_LOG_ERROR, "block_max_depth= %d is too large\n", s->block_max_depth); s->block_max_depth= 0; + s->mv_scale = 0; return AVERROR_INVALIDDATA; } if (FFABS(s->qbias) > 127) { From 03351cce88434f9a4ef3c7cc29e2bc5449c4646e Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 15 Oct 2017 02:30:15 +0200 Subject: [PATCH 3333/3374] Update versions for 3.4 release Signed-off-by: Michael Niedermayer --- Changelog | 2 +- RELEASE | 2 +- doc/Doxyfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Changelog b/Changelog index d6ec4ad1b557a..a8d4c29e90d2b 100644 --- a/Changelog +++ b/Changelog @@ -1,7 +1,7 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. -version : +version 3.4: - deflicker video filter - doubleweave video filter - lumakey video filter diff --git a/RELEASE b/RELEASE index 48ea63d1809a3..2f4b60750dc35 100644 --- a/RELEASE +++ b/RELEASE @@ -1 +1 @@ -3.3.git +3.4 diff --git a/doc/Doxyfile b/doc/Doxyfile index 0891899505ce1..491db00b7eef1 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = FFmpeg # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = +PROJECT_NUMBER = 3.4 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From 01e291a592452f27b3a4e811536aaaf94096e244 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sun, 15 Oct 2017 12:45:15 +0100 Subject: [PATCH 3334/3374] hwcontext_vaapi: Remove use of vaExportSurfaceHandle() It is not present in libva 2.0. --- libavutil/hwcontext_vaapi.c | 69 ------------------------------------- 1 file changed, 69 deletions(-) diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index 40a85d288c6a9..cc961f12f89dd 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -1076,80 +1076,11 @@ static void vaapi_unmap_to_drm(AVHWFramesContext *dst_fc, static int vaapi_map_to_drm(AVHWFramesContext *hwfc, AVFrame *dst, const AVFrame *src, int flags) { -#if CONFIG_VAAPI_1 - AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; - VASurfaceID surface_id; - VAStatus vas; - VADRMPRIMESurfaceDescriptor va_desc; - AVDRMFrameDescriptor *drm_desc = NULL; - int err, i, j; - - surface_id = (VASurfaceID)(uintptr_t)src->data[3]; - - vas = vaExportSurfaceHandle(hwctx->display, surface_id, - VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2, - VA_EXPORT_SURFACE_READ_ONLY | - VA_EXPORT_SURFACE_SEPARATE_LAYERS, - &va_desc); - if (vas != VA_STATUS_SUCCESS) { - if (vas == VA_STATUS_ERROR_UNIMPLEMENTED) - return AVERROR(ENOSYS); - av_log(hwfc, AV_LOG_ERROR, "Failed to export surface %#x: " - "%d (%s).\n", surface_id, vas, vaErrorStr(vas)); - return AVERROR(EIO); - } - - drm_desc = av_mallocz(sizeof(*drm_desc)); - if (!drm_desc) { - err = AVERROR(ENOMEM); - goto fail; - } - - // By some bizarre coincidence, these structures are very similar... - drm_desc->nb_objects = va_desc.num_objects; - for (i = 0; i < va_desc.num_objects; i++) { - drm_desc->objects[i].fd = va_desc.objects[i].fd; - drm_desc->objects[i].size = va_desc.objects[i].size; - drm_desc->objects[i].format_modifier = - va_desc.objects[i].drm_format_modifier; - } - drm_desc->nb_layers = va_desc.num_layers; - for (i = 0; i < va_desc.num_layers; i++) { - drm_desc->layers[i].format = va_desc.layers[i].drm_format; - drm_desc->layers[i].nb_planes = va_desc.layers[i].num_planes; - for (j = 0; j < va_desc.layers[i].num_planes; j++) { - drm_desc->layers[i].planes[j].object_index = - va_desc.layers[i].object_index[j]; - drm_desc->layers[i].planes[j].offset = - va_desc.layers[i].offset[j]; - drm_desc->layers[i].planes[j].pitch = - va_desc.layers[i].pitch[j]; - } - } - - err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, - &vaapi_unmap_to_drm, drm_desc); - if (err < 0) - goto fail; - - dst->width = src->width; - dst->height = src->height; - dst->data[0] = (uint8_t*)drm_desc; - - return 0; - -fail: - for (i = 0; i < va_desc.num_objects; i++) - close(va_desc.objects[i].fd); - av_freep(&drm_desc); - return err; -#else // Older versions without vaExportSurfaceHandle() are not supported - // in theory this is possible with a combination of vaDeriveImage() // and vaAcquireBufferHandle(), but it doesn't carry enough metadata // to actually use the result in a generic way. return AVERROR(ENOSYS); -#endif } #endif From 505905a8622d8f3b9c353a590e4967c8f4431e7b Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 1 Jul 2013 20:43:11 +0800 Subject: [PATCH 3335/3374] .gitignore: ignore DS_Store --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index dabb51762d32d..8b855d3004617 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.DS_Store *.a *.o *.o.* From e4c45ca62e7c33b66f34caea5ba25e7d4633064a Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 14 Jan 2015 17:41:59 +0800 Subject: [PATCH 3336/3374] avformat/Makefile: install avc.h and avc.o --- libavformat/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavformat/Makefile b/libavformat/Makefile index df709c29dd253..85b4d4b9268eb 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -4,6 +4,7 @@ DESC = FFmpeg container format library HEADERS = avformat.h \ avio.h \ version.h \ + avc.h \ OBJS = allformats.o \ avio.o \ @@ -23,6 +24,7 @@ OBJS = allformats.o \ sdp.o \ url.o \ utils.o \ + avc.o \ OBJS-$(HAVE_LIBC_MSVCRT) += file_open.o From ed5c5711a732a1002e7f490435966366c743d8ed Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 27 Aug 2015 17:07:14 +0800 Subject: [PATCH 3337/3374] avformat/Makefile: install url.h --- libavformat/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/Makefile b/libavformat/Makefile index 85b4d4b9268eb..57ab28e685b43 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -5,6 +5,7 @@ HEADERS = avformat.h \ avio.h \ version.h \ avc.h \ + url.h \ OBJS = allformats.o \ avio.o \ From 01c34362da9e2757f83eaaa335c095df21e8bd29 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 1 Sep 2015 17:46:28 +0800 Subject: [PATCH 3338/3374] avformat/Makefile: install internal.h --- libavformat/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/Makefile b/libavformat/Makefile index 57ab28e685b43..2d59735013228 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -6,6 +6,7 @@ HEADERS = avformat.h \ version.h \ avc.h \ url.h \ + internal.h \ OBJS = allformats.o \ avio.o \ From 22a47cda55a7a9e40294167a285ca957e3333c1a Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Sat, 10 Oct 2015 14:17:30 +0800 Subject: [PATCH 3339/3374] avutil/Makefile: install thread.h --- libavutil/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/libavutil/Makefile b/libavutil/Makefile index 65e285a70114a..9415085165411 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -76,6 +76,7 @@ HEADERS = adler32.h \ version.h \ xtea.h \ tea.h \ + thread.h \ HEADERS-$(CONFIG_LZO) += lzo.h From 7ca20612b7a30ef25d3d2ebe85a64179d34fbee4 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 3 Jul 2013 21:46:17 +0800 Subject: [PATCH 3340/3374] avformat/hls: parse #EXT-X-MEDIA-SEQUENCE only once --- libavformat/hls.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index 786934af032f3..9542ce4a72339 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -682,6 +682,7 @@ static int parse_playlist(HLSContext *c, const char *url, struct variant_info variant_info; char tmp_str[MAX_URL_SIZE]; struct segment *cur_init_section = NULL; + int start_seq_no = -1; if (!in) { #if 1 @@ -758,7 +759,11 @@ static int parse_playlist(HLSContext *c, const char *url, ret = ensure_playlist(c, &pls, url); if (ret < 0) goto fail; - pls->start_seq_no = atoi(ptr); + /* Some buggy HLS servers write #EXT-X-MEDIA-SEQUENCE more than once */ + if (start_seq_no < 0) { + start_seq_no = atoi(ptr); + pls->start_seq_no = start_seq_no; + } } else if (av_strstart(line, "#EXT-X-PLAYLIST-TYPE:", &ptr)) { ret = ensure_playlist(c, &pls, url); if (ret < 0) From db3df0017db3dacb7665342406c24ae03cc31fe4 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 3 Jul 2013 21:51:19 +0800 Subject: [PATCH 3341/3374] avformat/http: read exact bytes at end of stream to avoid being blocked --- libavformat/http.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/libavformat/http.c b/libavformat/http.c index 668cd51986680..6507d4fa9a384 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -1318,7 +1318,15 @@ static int http_buf_read(URLContext *h, uint8_t *buf, int size) uint64_t target_end = s->end_off ? s->end_off : s->filesize; if ((!s->willclose || s->chunksize == UINT64_MAX) && s->off >= target_end) return AVERROR_EOF; - len = ffurl_read(s->hd, buf, size); + + len = size; + if (s->filesize > 0 && s->filesize != UINT64_MAX && s->filesize != 2147483647) { + int64_t unread = s->filesize - s->off; + if (len > unread) + len = (int)unread; + } + if (len > 0) + len = ffurl_read(s->hd, buf, len); if (!len && (!s->willclose || s->chunksize == UINT64_MAX) && s->off < target_end) { av_log(h, AV_LOG_ERROR, "Stream ends prematurely at %"PRIu64", should be %"PRIu64"\n", From 31dfa7b1d7bf4c753251fc68a1fc40b9f73d2e49 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 4 Jul 2013 12:02:06 +0800 Subject: [PATCH 3342/3374] avformat/mov: prefer nearest sample as next sample --- libavformat/mov.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 899690d920d47..df66b99b13557 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -6384,8 +6384,13 @@ static int mov_read_header(AVFormatContext *s) static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st) { AVIndexEntry *sample = NULL; + AVIndexEntry *best_dts_sample = NULL; + AVIndexEntry *best_pos_sample = NULL; + AVStream *best_dts_stream = NULL; + AVStream *best_pos_stream = NULL; int64_t best_dts = INT64_MAX; int i; + int64_t pos = avio_tell(s->pb); for (i = 0; i < s->nb_streams; i++) { AVStream *avst = s->streams[i]; MOVStreamContext *msc = avst->priv_data; @@ -6393,17 +6398,36 @@ static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st) AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample]; int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale); av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts); - if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) || + if (!best_dts_sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < best_dts_sample->pos) || ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && - ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) || + ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < best_dts_sample->pos) || (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) { - sample = current_sample; + /* find best dts sample */ + best_dts_sample = current_sample; best_dts = dts; - *st = avst; + best_dts_stream = avst; + } + if (current_sample->pos >= pos && + (!best_pos_sample || current_sample->pos < best_pos_sample->pos)) { + /* find nearest sample to avoid seek around */ + best_pos_sample = current_sample; + best_pos_stream = avst; } } } + + if (best_dts_sample && best_dts_sample != best_pos_sample && + (!best_pos_sample || + best_dts_sample->pos < pos || + best_dts_sample->pos > pos + 1024 * 1024)) { + sample = best_dts_sample; + *st = best_dts_stream; + } else { + sample = best_pos_sample; + *st = best_pos_stream; + } + return sample; } From ce291552e5b3c4adb8a2770abbe92df2d31cf711 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 4 Jul 2013 12:12:06 +0800 Subject: [PATCH 3343/3374] avformat/http: try to fix missing Content-Range --- libavformat/http.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libavformat/http.c b/libavformat/http.c index 6507d4fa9a384..aa3c565c905de 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -1107,6 +1107,7 @@ static int http_connect(URLContext *h, const char *path, const char *local_path, char headers[HTTP_HEADERS_SIZE] = ""; char *authstr = NULL, *proxyauthstr = NULL; uint64_t off = s->off; + uint64_t filesize = s->filesize; int len = 0; const char *method; int send_expect_100 = 0; @@ -1268,6 +1269,15 @@ static int http_connect(URLContext *h, const char *path, const char *local_path, if (*new_location) s->off = off; + /* Some buggy servers may missing 'Content-Range' header for range request */ + if (off > 0 && s->off <= 0 && (off + s->filesize == filesize)) { + av_log(NULL, AV_LOG_WARNING, + "try to fix missing 'Content-Range' at server side (%"PRId64",%"PRId64") => (%"PRId64",%"PRId64")", + s->off, s->filesize, off, filesize); + s->off = off; + s->filesize = filesize; + } + err = (off == s->off) ? 0 : -1; done: av_freep(&authstr); From 9e9d67d5489be7403017b9279d33334a03835601 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 6 Aug 2013 19:09:17 +0800 Subject: [PATCH 3344/3374] avformat/hls: fix duration --- libavformat/hls.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index 9542ce4a72339..6eab6424779f2 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2,6 +2,7 @@ * Apple HTTP Live Streaming demuxer * Copyright (c) 2010 Martin Storsjo * Copyright (c) 2013 Anssi Hannula + * Copyright (c) 2011 Cedirc Fung (wolfplanet@gmail.com) * * This file is part of FFmpeg. * @@ -65,7 +66,9 @@ enum KeyType { }; struct segment { + int64_t previous_duration; int64_t duration; + int64_t start_time; int64_t url_offset; int64_t size; char *url; @@ -668,7 +671,7 @@ static int parse_playlist(HLSContext *c, const char *url, struct playlist *pls, AVIOContext *in) { int ret = 0, is_segment = 0, is_variant = 0; - int64_t duration = 0; + int64_t duration = 0, previous_duration1 = 0, previous_duration = 0, total_duration = 0; enum KeyType key_type = KEY_NONE; uint8_t iv[16] = ""; int has_iv = 0; @@ -783,6 +786,8 @@ static int parse_playlist(HLSContext *c, const char *url, } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) { if (pls) pls->finished = 1; + } else if (av_strstart(line, "#EXT-X-DISCONTINUITY", &ptr)) { + previous_duration = previous_duration1; } else if (av_strstart(line, "#EXTINF:", &ptr)) { is_segment = 1; duration = atof(ptr) * AV_TIME_BASE; @@ -815,6 +820,10 @@ static int parse_playlist(HLSContext *c, const char *url, ret = AVERROR(ENOMEM); goto fail; } + previous_duration1 += duration; + seg->previous_duration = previous_duration; + seg->start_time = total_duration; + total_duration += duration; seg->duration = duration; seg->key_type = key_type; if (has_iv) { @@ -2050,6 +2059,28 @@ static int hls_read_packet(AVFormatContext *s, AVPacket *pkt) } } + if (c->playlists[minplaylist]->finished) { + struct playlist *pls = c->playlists[minplaylist]; + int seq_no = pls->cur_seq_no - pls->start_seq_no; + if (seq_no < pls->n_segments && s->streams[pkt->stream_index]) { + struct segment *seg = pls->segments[seq_no]; + int64_t pred = av_rescale_q(seg->previous_duration, + AV_TIME_BASE_Q, + s->streams[pkt->stream_index]->time_base); + int64_t max_ts = av_rescale_q(seg->start_time + seg->duration, + AV_TIME_BASE_Q, + s->streams[pkt->stream_index]->time_base); + /* EXTINF duration is not precise enough */ + max_ts += 2 * AV_TIME_BASE; + if (s->start_time > 0) { + max_ts += av_rescale_q(s->start_time, + AV_TIME_BASE_Q, + s->streams[pkt->stream_index]->time_base); + } + if (pkt->dts != AV_NOPTS_VALUE && pkt->dts + pred < max_ts) pkt->dts += pred; + if (pkt->pts != AV_NOPTS_VALUE && pkt->pts + pred < max_ts) pkt->pts += pred; + } + } return 0; } return AVERROR_EOF; From 2facb464dc5bbab7a1545748346aa5caa5e369bd Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 12 Feb 2015 14:30:36 +0800 Subject: [PATCH 3345/3374] lavf/avformat: add support for passing options to nested input --- libavformat/avformat.h | 5 +++++ libavformat/utils.c | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/libavformat/avformat.h b/libavformat/avformat.h index b0de66ac1450a..445b38f8fe891 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -719,6 +719,11 @@ typedef struct AVInputFormat { */ int (*read_header)(struct AVFormatContext *); + /** + * Used by format which open further nested input. + */ + int (*read_header2)(struct AVFormatContext *, AVDictionary **options); + /** * Read one packet and put it in 'pkt'. pts and flags are also * set. 'avformat_new_stream' can be called only if the flag diff --git a/libavformat/utils.c b/libavformat/utils.c index 1a7996c4fd854..361b394111ff5 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -513,6 +513,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVFormatContext *s = *ps; int i, ret = 0; AVDictionary *tmp = NULL; + AVDictionary *tmp2 = NULL; ID3v2ExtraMeta *id3v2_extra_meta = NULL; if (!s && !(s = avformat_alloc_context())) @@ -591,9 +592,16 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, ff_id3v2_read_dict(s->pb, &s->internal->id3v2_meta, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta); - if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->iformat->read_header) - if ((ret = s->iformat->read_header(s)) < 0) + if (!(s->flags&AVFMT_FLAG_PRIV_OPT)) { + if (s->iformat->read_header2) { + if (options) + av_dict_copy(&tmp2, *options, 0); + + if ((ret = s->iformat->read_header2(s, &tmp2)) < 0) + goto fail; + } else if (s->iformat->read_header && (ret = s->iformat->read_header(s)) < 0) goto fail; + } if (!s->metadata) { s->metadata = s->internal->id3v2_meta; @@ -636,6 +644,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, if (options) { av_dict_free(options); *options = tmp; + av_dict_free(&tmp2); } *ps = s; return 0; @@ -643,6 +652,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, fail: ff_id3v2_free_extra_meta(&id3v2_extra_meta); av_dict_free(&tmp); + av_dict_free(&tmp2); if (s->pb && !(s->flags & AVFMT_FLAG_CUSTOM_IO)) avio_closep(&s->pb); avformat_free_context(s); From 395092390fc0f33339564d699269c81360dfa975 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 12 Feb 2015 16:27:49 +0800 Subject: [PATCH 3346/3374] lavf/concatdec: pass options to nested input --- libavformat/concatdec.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c index 0e189012adf27..a4a6cad2a34d2 100644 --- a/libavformat/concatdec.c +++ b/libavformat/concatdec.c @@ -64,6 +64,7 @@ typedef struct { ConcatMatchMode stream_match_mode; unsigned auto_convert; int segment_time_metadata; + AVDictionary *options; } ConcatContext; static int concat_probe(AVProbeData *probe) @@ -318,6 +319,7 @@ static int open_file(AVFormatContext *avf, unsigned fileno) ConcatContext *cat = avf->priv_data; ConcatFile *file = &cat->files[fileno]; int ret; + AVDictionary *tmp = NULL; if (cat->avf) avformat_close_input(&cat->avf); @@ -379,11 +381,12 @@ static int concat_read_close(AVFormatContext *avf) } if (cat->avf) avformat_close_input(&cat->avf); + av_dict_free(&cat->options); av_freep(&cat->files); return 0; } -static int concat_read_header(AVFormatContext *avf) +static int concat_read_header(AVFormatContext *avf, AVDictionary **options) { ConcatContext *cat = avf->priv_data; uint8_t buf[4096]; @@ -393,6 +396,9 @@ static int concat_read_header(AVFormatContext *avf) ConcatFile *file = NULL; int64_t time = 0; + if (options && *options) + av_dict_copy(&cat->options, *options, 0); + while (1) { if ((ret = ff_get_line(avf->pb, buf, sizeof(buf))) <= 0) break; @@ -772,7 +778,7 @@ AVInputFormat ff_concat_demuxer = { .long_name = NULL_IF_CONFIG_SMALL("Virtual concatenation script"), .priv_data_size = sizeof(ConcatContext), .read_probe = concat_probe, - .read_header = concat_read_header, + .read_header2 = concat_read_header, .read_packet = concat_read_packet, .read_close = concat_read_close, .read_seek2 = concat_seek, From 3f165db1457c25c33279bb715da6de4320403bb2 Mon Sep 17 00:00:00 2001 From: bbcallen Date: Tue, 4 Mar 2014 14:15:58 +0800 Subject: [PATCH 3347/3374] avformat/concatdec: close previous segment only after new segment is open successfully Later call to concat_read_packet could cause NULL pointer access. avformat/concatdec: fix merge conflict in open_file --- libavformat/concatdec.c | 58 ++++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c index a4a6cad2a34d2..3d8282329cbed 100644 --- a/libavformat/concatdec.c +++ b/libavformat/concatdec.c @@ -65,6 +65,7 @@ typedef struct { unsigned auto_convert; int segment_time_metadata; AVDictionary *options; + int error; } ConcatContext; static int concat_probe(AVProbeData *probe) @@ -318,28 +319,39 @@ static int open_file(AVFormatContext *avf, unsigned fileno) { ConcatContext *cat = avf->priv_data; ConcatFile *file = &cat->files[fileno]; + AVFormatContext *new_avf = NULL; int ret; AVDictionary *tmp = NULL; - if (cat->avf) - avformat_close_input(&cat->avf); - - cat->avf = avformat_alloc_context(); - if (!cat->avf) + new_avf = avformat_alloc_context(); + if (!new_avf) return AVERROR(ENOMEM); - cat->avf->flags |= avf->flags & ~AVFMT_FLAG_CUSTOM_IO; - cat->avf->interrupt_callback = avf->interrupt_callback; + new_avf->flags |= avf->flags & ~AVFMT_FLAG_CUSTOM_IO; + new_avf->interrupt_callback = avf->interrupt_callback; - if ((ret = ff_copy_whiteblacklists(cat->avf, avf)) < 0) + if ((ret = ff_copy_whiteblacklists(new_avf, avf)) < 0) return ret; - if ((ret = avformat_open_input(&cat->avf, file->url, NULL, NULL)) < 0 || - (ret = avformat_find_stream_info(cat->avf, NULL)) < 0) { + if (cat->options) + av_dict_copy(&tmp, cat->options, 0); + + ret = avformat_open_input(&new_avf, file->url, NULL, &tmp); + av_dict_free(&tmp); + if (ret < 0 || + (ret = avformat_find_stream_info(new_avf, NULL)) < 0) { av_log(avf, AV_LOG_ERROR, "Impossible to open '%s'\n", file->url); - avformat_close_input(&cat->avf); + avformat_close_input(&new_avf); return ret; } + + if (!new_avf) + return 0; + + if (cat->avf) + avformat_close_input(&cat->avf); + + cat->avf = new_avf; cat->cur_file = file; if (file->start_time == AV_NOPTS_VALUE) file->start_time = !fileno ? 0 : @@ -568,6 +580,7 @@ static int packet_after_outpoint(ConcatContext *cat, AVPacket *pkt) return 0; } +#define CONCAT_MAX_OPEN_TRY 3 static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt) { ConcatContext *cat = avf->priv_data; @@ -575,6 +588,12 @@ static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt) int64_t delta; ConcatStream *cs; AVStream *st; + int try_counter = 0; + + if (cat->error) { + ret = cat->error; + return ret; + } if (cat->eof) return AVERROR_EOF; @@ -586,7 +605,7 @@ static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt) ret = av_read_frame(cat->avf, pkt); if (ret == AVERROR_EOF) { if ((ret = open_next_file(avf)) < 0) - return ret; + goto open_fail; continue; } if (ret < 0) @@ -598,7 +617,7 @@ static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt) if (packet_after_outpoint(cat, pkt)) { av_packet_unref(pkt); if ((ret = open_next_file(avf)) < 0) - return ret; + goto open_fail; continue; } cs = &cat->cur_file->streams[pkt->stream_index]; @@ -608,6 +627,16 @@ static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt) } pkt->stream_index = cs->out_stream_index; break; +open_fail: + ++try_counter; + if (try_counter > CONCAT_MAX_OPEN_TRY) { + cat->error = ret; + if (avf->pb && ret != AVERROR_EOF) + avf->pb->error = ret; + return AVERROR_EOF; + } + + av_log(avf, AV_LOG_WARNING, "open_next_file() failed (%d)\n", try_counter); } if ((ret = filter_packet(avf, cs, pkt))) return ret; @@ -731,6 +760,9 @@ static int concat_seek(AVFormatContext *avf, int stream, AVFormatContext *cur_avf_saved = cat->avf; int ret; + /* reset error/complete state */ + cat->error = 0; + if (!cat->seekable) return AVERROR(ESPIPE); /* XXX: can we use it? */ if (flags & (AVSEEK_FLAG_BYTE | AVSEEK_FLAG_FRAME)) From 8ab489f9139c336f4f6b60d77bd02c24998d5291 Mon Sep 17 00:00:00 2001 From: Ming Hu Date: Thu, 24 Mar 2016 13:09:36 +0800 Subject: [PATCH 3348/3374] avformat/concat: expose a flag to indicate source switch Signed-off-by: xinzhengzhang --- libavcodec/avcodec.h | 1 + libavformat/concatdec.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 18c3e3ea1ee91..4a272ed43e1fc 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1723,6 +1723,7 @@ typedef struct AVPacket { * outside the packet may be followed. */ #define AV_PKT_FLAG_TRUSTED 0x0008 +#define AV_PKT_FLAG_NEW_SEG 0x8000 ///< The packet is the first packet from a source in concat enum AVSideDataParamChangeFlags { AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT = 0x0001, diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c index 3d8282329cbed..33d817ab8b266 100644 --- a/libavformat/concatdec.c +++ b/libavformat/concatdec.c @@ -589,6 +589,7 @@ static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt) ConcatStream *cs; AVStream *st; int try_counter = 0; + int is_new_st = 0; if (cat->error) { ret = cat->error; @@ -604,12 +605,17 @@ static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt) while (1) { ret = av_read_frame(cat->avf, pkt); if (ret == AVERROR_EOF) { + is_new_st = 1; if ((ret = open_next_file(avf)) < 0) goto open_fail; continue; } if (ret < 0) return ret; + if (is_new_st) { + pkt->flags |= AV_PKT_FLAG_NEW_SEG; + is_new_st = 0; + } if ((ret = match_streams(avf)) < 0) { av_packet_unref(pkt); return ret; From 9924012b46d1af4f3951470dff6c80da62951184 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 21 Apr 2015 17:47:26 +0800 Subject: [PATCH 3349/3374] Revert "Fix url_feof() for file appendings." This reverts commit 3bd624b4ee355328382295af411f5343b1329f43. avio_feof() could reset eof_reached which is not expected. --- libavformat/aviobuf.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index 636cb46161ad0..5662b3ed01d06 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -357,10 +357,6 @@ int avio_feof(AVIOContext *s) { if(!s) return 0; - if(s->eof_reached){ - s->eof_reached=0; - fill_buffer(s); - } return s->eof_reached; } From 8ae79bbce91427861816d16ee95fc14ffd54cd5f Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 13 May 2015 15:13:16 +0800 Subject: [PATCH 3350/3374] avformat/concatdec: pass out io error --- libavformat/concatdec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c index 33d817ab8b266..9d2880135fd81 100644 --- a/libavformat/concatdec.c +++ b/libavformat/concatdec.c @@ -610,8 +610,11 @@ static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt) goto open_fail; continue; } - if (ret < 0) + if (ret < 0) { + if (avf->pb && cat->avf->pb) + avf->pb->error = cat->avf->pb->error; return ret; + } if (is_new_st) { pkt->flags |= AV_PKT_FLAG_NEW_SEG; is_new_st = 0; From f17b6b55d7adc2bb47758949394b40c83ea2efca Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 31 Aug 2015 18:22:32 +0800 Subject: [PATCH 3351/3374] avformat/http: add option http-tcp-hook --- libavformat/http.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libavformat/http.c b/libavformat/http.c index aa3c565c905de..7a9f75134de1d 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -123,6 +123,7 @@ typedef struct HTTPContext { int is_multi_client; HandshakeState handshake_step; int is_connected_server; + char *tcp_hook; } HTTPContext; #define OFFSET(x) offsetof(HTTPContext, x) @@ -163,6 +164,7 @@ static const AVOption options[] = { { "listen", "listen on HTTP", OFFSET(listen), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, D | E }, { "resource", "The resource requested by a client", OFFSET(resource), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E }, { "reply_code", "The http status code to return to a client", OFFSET(reply_code), AV_OPT_TYPE_INT, { .i64 = 200}, INT_MIN, 599, E}, + { "http-tcp-hook", "hook protocol on tcp", OFFSET(tcp_hook), AV_OPT_TYPE_STRING, { .str = "tcp" }, 0, 0, D | E }, { NULL } }; @@ -191,6 +193,8 @@ static int http_open_cnx_internal(URLContext *h, AVDictionary **options) int port, use_proxy, err, location_changed = 0; HTTPContext *s = h->priv_data; + lower_proto = s->tcp_hook; + av_url_split(proto, sizeof(proto), auth, sizeof(auth), hostname, sizeof(hostname), &port, path1, sizeof(path1), s->location); @@ -1741,7 +1745,7 @@ static int http_proxy_open(URLContext *h, const char *uri, int flags) if (*path == '/') path++; - ff_url_join(lower_url, sizeof(lower_url), "tcp", NULL, hostname, port, + ff_url_join(lower_url, sizeof(lower_url), s->tcp_hook, NULL, hostname, port, NULL); redo: ret = ffurl_open_whitelist(&s->hd, lower_url, AVIO_FLAG_READ_WRITE, From 2e2fc06f1b99cececd1206f047aa11f28948162b Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 29 Dec 2015 12:10:40 +0800 Subject: [PATCH 3352/3374] avformat/concatdec: fetch bit_rate from internal format --- libavformat/concatdec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c index 9d2880135fd81..b4d7072d86e0f 100644 --- a/libavformat/concatdec.c +++ b/libavformat/concatdec.c @@ -351,6 +351,7 @@ static int open_file(AVFormatContext *avf, unsigned fileno) if (cat->avf) avformat_close_input(&cat->avf); + avf->bit_rate = new_avf->bit_rate; cat->avf = new_avf; cat->cur_file = file; if (file->start_time == AV_NOPTS_VALUE) From 8f7f145e26c45cdf926a33990f2d3669efb2d71a Mon Sep 17 00:00:00 2001 From: Xinzheng Zhang Date: Thu, 11 Aug 2016 12:41:39 +0800 Subject: [PATCH 3353/3374] avformat/ijkutils: add dummy for replacing ijk protocol --- libavformat/Makefile | 1 + libavformat/ijkutils.c | 66 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 libavformat/ijkutils.c diff --git a/libavformat/Makefile b/libavformat/Makefile index 2d59735013228..fd3f2d06789d8 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -27,6 +27,7 @@ OBJS = allformats.o \ url.o \ utils.o \ avc.o \ + ijkutils.o \ OBJS-$(HAVE_LIBC_MSVCRT) += file_open.o diff --git a/libavformat/ijkutils.c b/libavformat/ijkutils.c new file mode 100644 index 0000000000000..59aa7c6d3ad0a --- /dev/null +++ b/libavformat/ijkutils.c @@ -0,0 +1,66 @@ +/* + * utils.c + * + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2013 Zhang Rui + * + * This file is part of ijkPlayer. + * + * ijkPlayer 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. + * + * ijkPlayer 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 ijkPlayer; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "url.h" + + +#define IJK_FF_PROTOCOL(x) \ +extern URLProtocol ff_##x##_protocol; \ +int ijkav_register_##x##_protocol(URLProtocol *protocol, int protocol_size); \ +int ijkav_register_##x##_protocol(URLProtocol *protocol, int protocol_size) \ +{ \ + if (protocol_size != sizeof(URLProtocol)) { \ + av_log(NULL, AV_LOG_ERROR, "ijkav_register_##x##_protocol: ABI mismatch.\n"); \ + return -1; \ + } \ + memcpy(&ff_##x##_protocol, protocol, protocol_size); \ + return 0; \ +} + +#define IJK_DUMMY_PROTOCOL(x) \ +IJK_FF_PROTOCOL(x); \ +static const AVClass ijk_##x##_context_class = { \ + .class_name = #x, \ + .item_name = av_default_item_name, \ + .version = LIBAVUTIL_VERSION_INT, \ + }; \ + \ +URLProtocol ff_##x##_protocol = { \ + .name = #x, \ + .url_open2 = ijkdummy_open, \ + .priv_data_size = 1, \ + .priv_data_class = &ijk_##x##_context_class, \ +}; + +static int ijkdummy_open(URLContext *h, const char *arg, int flags, AVDictionary **options) +{ + return -1; +} + +IJK_FF_PROTOCOL(async); +IJK_DUMMY_PROTOCOL(ijkmediadatasource); +IJK_DUMMY_PROTOCOL(ijkhttphook); +IJK_DUMMY_PROTOCOL(ijklongurl); +IJK_DUMMY_PROTOCOL(ijksegment); +IJK_DUMMY_PROTOCOL(ijktcphook); From 80b21aee885111045a4b9eb95a4eaca53e913e8a Mon Sep 17 00:00:00 2001 From: Xinzheng Zhang Date: Thu, 11 Aug 2016 12:42:25 +0800 Subject: [PATCH 3354/3374] avformat/protocols: add stub for custom protocol --- libavformat/protocols.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavformat/protocols.c b/libavformat/protocols.c index 8d3555ed5206e..af095d24c3864 100644 --- a/libavformat/protocols.c +++ b/libavformat/protocols.c @@ -39,6 +39,11 @@ extern const URLProtocol ff_http_protocol; extern const URLProtocol ff_httpproxy_protocol; extern const URLProtocol ff_https_protocol; extern const URLProtocol ff_icecast_protocol; +extern const URLProtocol ff_ijkhttphook_protocol; +extern const URLProtocol ff_ijklongurl_protocol; +extern const URLProtocol ff_ijkmediadatasource_protocol; +extern const URLProtocol ff_ijksegment_protocol; +extern const URLProtocol ff_ijktcphook_protocol; extern const URLProtocol ff_mmsh_protocol; extern const URLProtocol ff_mmst_protocol; extern const URLProtocol ff_md5_protocol; From 9497a4224dfdb5792aec5058efc4d0bae8a66dbc Mon Sep 17 00:00:00 2001 From: xinzhengzhang Date: Thu, 24 Mar 2016 15:13:39 +0800 Subject: [PATCH 3355/3374] avutil/application: support low level event callback --- libavutil/Makefile | 2 + libavutil/application.c | 214 ++++++++++++++++++++++++++++++++++++++++ libavutil/application.h | 120 ++++++++++++++++++++++ 3 files changed, 336 insertions(+) create mode 100644 libavutil/application.c create mode 100644 libavutil/application.h diff --git a/libavutil/Makefile b/libavutil/Makefile index 9415085165411..4e3a04bff0e9c 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -4,6 +4,7 @@ DESC = FFmpeg utility library HEADERS = adler32.h \ aes.h \ aes_ctr.h \ + application.h \ attributes.h \ audio_fifo.h \ avassert.h \ @@ -93,6 +94,7 @@ BUILT_HEADERS = avconfig.h \ OBJS = adler32.o \ aes.o \ aes_ctr.o \ + application.o \ audio_fifo.o \ avstring.o \ base64.o \ diff --git a/libavutil/application.c b/libavutil/application.c new file mode 100644 index 0000000000000..2626742a0b291 --- /dev/null +++ b/libavutil/application.c @@ -0,0 +1,214 @@ +/* + * copyright (c) 2016 Zhang Rui + * + * 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 "application.h" +#include "libavformat/network.h" +#include "libavutil/avstring.h" + +void av_application_on_io_traffic(AVApplicationContext *h, AVAppIOTraffic *event); + +int av_application_alloc(AVApplicationContext **ph, void *opaque) +{ + AVApplicationContext *h = NULL; + + h = av_mallocz(sizeof(AVApplicationContext)); + if (!h) + return AVERROR(ENOMEM); + + h->opaque = opaque; + + *ph = h; + return 0; +} + +int av_application_open(AVApplicationContext **ph, void *opaque) +{ + int ret = av_application_alloc(ph, opaque); + if (ret) + return ret; + + return 0; +} + +void av_application_close(AVApplicationContext *h) +{ + av_free(h); +} + +void av_application_closep(AVApplicationContext **ph) +{ + if (!ph || !*ph) + return; + + av_application_close(*ph); + *ph = NULL; +} + +void av_application_on_http_event(AVApplicationContext *h, int event_type, AVAppHttpEvent *event) +{ + if (h && h->func_on_app_event) + h->func_on_app_event(h, event_type, (void *)event, sizeof(AVAppHttpEvent)); +} + +void av_application_will_http_open(AVApplicationContext *h, void *obj, const char *url) +{ + AVAppHttpEvent event = {0}; + + if (!h || !obj || !url) + return; + + event.obj = obj; + av_strlcpy(event.url, url, sizeof(event.url)); + + av_application_on_http_event(h, AVAPP_EVENT_WILL_HTTP_OPEN, &event); +} + +void av_application_did_http_open(AVApplicationContext *h, void *obj, const char *url, int error, int http_code) +{ + AVAppHttpEvent event = {0}; + + if (!h || !obj || !url) + return; + + event.obj = obj; + av_strlcpy(event.url, url, sizeof(event.url)); + event.error = error; + event.http_code = http_code; + + av_application_on_http_event(h, AVAPP_EVENT_DID_HTTP_OPEN, &event); +} + +void av_application_will_http_seek(AVApplicationContext *h, void *obj, const char *url, int64_t offset) +{ + AVAppHttpEvent event = {0}; + + if (!h || !obj || !url) + return; + + event.obj = obj; + event.offset = offset; + av_strlcpy(event.url, url, sizeof(event.url)); + + av_application_on_http_event(h, AVAPP_EVENT_WILL_HTTP_SEEK, &event); +} + +void av_application_did_http_seek(AVApplicationContext *h, void *obj, const char *url, int64_t offset, int error, int http_code) +{ + AVAppHttpEvent event = {0}; + + if (!h || !obj || !url) + return; + + event.obj = obj; + event.offset = offset; + av_strlcpy(event.url, url, sizeof(event.url)); + event.error = error; + event.http_code = http_code; + + av_application_on_http_event(h, AVAPP_EVENT_DID_HTTP_SEEK, &event); +} + +void av_application_on_io_traffic(AVApplicationContext *h, AVAppIOTraffic *event) +{ + if (h && h->func_on_app_event) + h->func_on_app_event(h, AVAPP_EVENT_IO_TRAFFIC, (void *)event, sizeof(AVAppIOTraffic)); +} + +int av_application_on_io_control(AVApplicationContext *h, int event_type, AVAppIOControl *control) +{ + if (h && h->func_on_app_event) + return h->func_on_app_event(h, event_type, (void *)control, sizeof(AVAppIOControl)); + return 0; +} + +int av_application_on_tcp_will_open(AVApplicationContext *h) +{ + if (h && h->func_on_app_event) { + AVAppTcpIOControl control = {0}; + return h->func_on_app_event(h, AVAPP_CTRL_WILL_TCP_OPEN, (void *)&control, sizeof(AVAppTcpIOControl)); + } + return 0; +} + +// only callback returns error +int av_application_on_tcp_did_open(AVApplicationContext *h, int error, int fd) +{ + struct sockaddr_storage so_stg; + int ret = 0; + socklen_t so_len = sizeof(so_stg); + int so_family; + AVAppTcpIOControl control = {0}; + char *so_ip_name = control.ip; + + if (!h || !h->func_on_app_event || fd <= 0) + return 0; + + ret = getpeername(fd, (struct sockaddr *)&so_stg, &so_len); + if (ret) + return 0; + control.error = error; + control.fd = fd; + + so_family = ((struct sockaddr*)&so_stg)->sa_family; + switch (so_family) { + case AF_INET: { + struct sockaddr_in* in4 = (struct sockaddr_in*)&so_stg; + if (inet_ntop(AF_INET, &(in4->sin_addr), so_ip_name, sizeof(control.ip))) { + control.family = AF_INET; + control.port = in4->sin_port; + } + break; + } + case AF_INET6: { + struct sockaddr_in6* in6 = (struct sockaddr_in6*)&so_stg; + if (inet_ntop(AF_INET6, &(in6->sin6_addr), so_ip_name, sizeof(control.ip))) { + control.family = AF_INET6; + control.port = in6->sin6_port; + } + break; + } + } + + return h->func_on_app_event(h, AVAPP_CTRL_DID_TCP_OPEN, (void *)&control, sizeof(AVAppTcpIOControl)); +} + +void av_application_on_async_statistic(AVApplicationContext *h, AVAppAsyncStatistic *statistic) +{ + if (h && h->func_on_app_event) + h->func_on_app_event(h, AVAPP_EVENT_ASYNC_STATISTIC, (void *)statistic, sizeof(AVAppAsyncStatistic)); +} + +void av_application_on_async_read_speed(AVApplicationContext *h, AVAppAsyncReadSpeed *speed) +{ + if (h && h->func_on_app_event) + h->func_on_app_event(h, AVAPP_EVENT_ASYNC_READ_SPEED, (void *)speed, sizeof(AVAppAsyncReadSpeed)); +} + +void av_application_did_io_tcp_read(AVApplicationContext *h, void *obj, int bytes) +{ + AVAppIOTraffic event = {0}; + if (!h || !obj || bytes <= 0) + return; + + event.obj = obj; + event.bytes = bytes; + + av_application_on_io_traffic(h, &event); +} diff --git a/libavutil/application.h b/libavutil/application.h new file mode 100644 index 0000000000000..a33b272fdd5c4 --- /dev/null +++ b/libavutil/application.h @@ -0,0 +1,120 @@ +/* + * copyright (c) 2016 Zhang Rui + * + * 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 + */ + +#ifndef AVUTIL_APPLICATION_H +#define AVUTIL_APPLICATION_H + +#include "libavutil/log.h" + +#define AVAPP_EVENT_WILL_HTTP_OPEN 1 //AVAppHttpEvent +#define AVAPP_EVENT_DID_HTTP_OPEN 2 //AVAppHttpEvent +#define AVAPP_EVENT_WILL_HTTP_SEEK 3 //AVAppHttpEvent +#define AVAPP_EVENT_DID_HTTP_SEEK 4 //AVAppHttpEvent + +#define AVAPP_EVENT_ASYNC_STATISTIC 0x11000 //AVAppAsyncStatistic +#define AVAPP_EVENT_ASYNC_READ_SPEED 0x11001 //AVAppAsyncReadSpeed +#define AVAPP_EVENT_IO_TRAFFIC 0x12204 //AVAppIOTraffic + +#define AVAPP_CTRL_WILL_TCP_OPEN 0x20001 //AVAppTcpIOControl +#define AVAPP_CTRL_DID_TCP_OPEN 0x20002 //AVAppTcpIOControl + +#define AVAPP_CTRL_WILL_HTTP_OPEN 0x20003 //AVAppIOControl +#define AVAPP_CTRL_WILL_LIVE_OPEN 0x20005 //AVAppIOControl + +#define AVAPP_CTRL_WILL_CONCAT_SEGMENT_OPEN 0x20007 //AVAppIOControl + +typedef struct AVAppIOControl { + size_t size; + char url[4096]; /* in, out */ + int segment_index; /* in, default = 0 */ + int retry_counter; /* in */ + + int is_handled; /* out, default = false */ + int is_url_changed; /* out, default = false */ +} AVAppIOControl; + +typedef struct AVAppTcpIOControl { + int error; + int family; + char ip[96]; + int port; + int fd; +} AVAppTcpIOControl; + +typedef struct AVAppAsyncStatistic { + size_t size; + int64_t buf_backwards; + int64_t buf_forwards; + int64_t buf_capacity; +} AVAppAsyncStatistic; + +typedef struct AVAppAsyncReadSpeed { + size_t size; + int is_full_speed; + int64_t io_bytes; + int64_t elapsed_milli; +} AVAppAsyncReadSpeed; + +typedef struct AVAppHttpEvent +{ + void *obj; + char url[4096]; + int64_t offset; + int error; + int http_code; +} AVAppHttpEvent; + +typedef struct AVAppIOTraffic +{ + void *obj; + int bytes; +} AVAppIOTraffic; + +typedef struct AVApplicationContext AVApplicationContext; +struct AVApplicationContext { + const AVClass *av_class; /**< information for av_log(). Set by av_application_open(). */ + void *opaque; /**< user data. */ + + int (*func_on_app_event)(AVApplicationContext *h, int event_type ,void *obj, size_t size); +}; + +int av_application_alloc(AVApplicationContext **ph, void *opaque); +int av_application_open(AVApplicationContext **ph, void *opaque); +void av_application_close(AVApplicationContext *h); +void av_application_closep(AVApplicationContext **ph); + +void av_application_on_http_event(AVApplicationContext *h, int event_type, AVAppHttpEvent *event); +void av_application_will_http_open(AVApplicationContext *h, void *obj, const char *url); +void av_application_did_http_open(AVApplicationContext *h, void *obj, const char *url, int error, int http_code); +void av_application_will_http_seek(AVApplicationContext *h, void *obj, const char *url, int64_t offset); +void av_application_did_http_seek(AVApplicationContext *h, void *obj, const char *url, int64_t offset, int error, int http_code); + +void av_application_did_io_tcp_read(AVApplicationContext *h, void *obj, int bytes); + +int av_application_on_io_control(AVApplicationContext *h, int event_type, AVAppIOControl *control); + +int av_application_on_tcp_will_open(AVApplicationContext *h); +int av_application_on_tcp_did_open(AVApplicationContext *h, int error, int fd); + +void av_application_on_async_statistic(AVApplicationContext *h, AVAppAsyncStatistic *statistic); +void av_application_on_async_read_speed(AVApplicationContext *h, AVAppAsyncReadSpeed *speed); + + +#endif /* AVUTIL_APPLICATION_H */ From 1bebc5a38bdd001b9861d5f4390ba8d969aac033 Mon Sep 17 00:00:00 2001 From: Xinzheng Zhang Date: Thu, 11 Aug 2016 12:46:16 +0800 Subject: [PATCH 3356/3374] avformat/tcp: apply control event in application --- libavformat/tcp.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/libavformat/tcp.c b/libavformat/tcp.c index 07b4ed9fa3a8e..f9f07e18e4c97 100644 --- a/libavformat/tcp.c +++ b/libavformat/tcp.c @@ -23,6 +23,7 @@ #include "libavutil/parseutils.h" #include "libavutil/opt.h" #include "libavutil/time.h" +#include "libavutil/application.h" #include "internal.h" #include "network.h" @@ -41,6 +42,8 @@ typedef struct TCPContext { int listen_timeout; int recv_buffer_size; int send_buffer_size; + int64_t app_ctx_intptr; + AVApplicationContext *app_ctx; } TCPContext; #define OFFSET(x) offsetof(TCPContext, x) @@ -52,6 +55,7 @@ static const AVOption options[] = { { "listen_timeout", "Connection awaiting timeout (in milliseconds)", OFFSET(listen_timeout), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_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 }, + { "ijkapplication", "AVApplicationContext", OFFSET(app_ctx_intptr), AV_OPT_TYPE_INT64, { .i64 = 0 }, INT64_MIN, INT64_MAX, .flags = D }, { NULL } }; @@ -74,6 +78,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags) char hostname[1024],proto[1024],path[1024]; char portstr[10]; s->open_timeout = 5000000; + s->app_ctx = (AVApplicationContext *)(intptr_t)s->app_ctx_intptr; av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port, path, sizeof(path), uri); @@ -161,13 +166,26 @@ 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 { + ret = av_application_on_tcp_will_open(s->app_ctx); + if (ret) { + av_log(NULL, AV_LOG_WARNING, "terminated by application in AVAPP_CTRL_WILL_TCP_OPEN"); + goto fail1; + } + 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 (av_application_on_tcp_did_open(s->app_ctx, ret, fd)) + goto fail1; if (ret == AVERROR_EXIT) goto fail1; else goto fail; + } else { + ret = av_application_on_tcp_did_open(s->app_ctx, 0, fd); + if (ret) { + av_log(NULL, AV_LOG_WARNING, "terminated by application in AVAPP_CTRL_DID_TCP_OPEN"); + goto fail1; + } } } @@ -220,6 +238,8 @@ static int tcp_read(URLContext *h, uint8_t *buf, int size) return ret; } ret = recv(s->fd, buf, size, 0); + if (ret > 0) + av_application_did_io_tcp_read(s->app_ctx, (void*)h, ret); return ret < 0 ? ff_neterrno() : ret; } From b996efcd4333c6379e28a787be767dfe83fb15a0 Mon Sep 17 00:00:00 2001 From: Xinzheng Zhang Date: Thu, 11 Aug 2016 12:47:52 +0800 Subject: [PATCH 3357/3374] avformat/http: apply control event in application --- libavformat/http.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/libavformat/http.c b/libavformat/http.c index 7a9f75134de1d..33b2c3c507e02 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -30,6 +30,7 @@ #include "libavutil/opt.h" #include "libavutil/time.h" #include "libavutil/parseutils.h" +#include "libavutil/application.h" #include "avformat.h" #include "http.h" @@ -124,6 +125,8 @@ typedef struct HTTPContext { HandshakeState handshake_step; int is_connected_server; char *tcp_hook; + int64_t app_ctx_intptr; + AVApplicationContext *app_ctx; } HTTPContext; #define OFFSET(x) offsetof(HTTPContext, x) @@ -165,6 +168,7 @@ static const AVOption options[] = { { "resource", "The resource requested by a client", OFFSET(resource), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E }, { "reply_code", "The http status code to return to a client", OFFSET(reply_code), AV_OPT_TYPE_INT, { .i64 = 200}, INT_MIN, 599, E}, { "http-tcp-hook", "hook protocol on tcp", OFFSET(tcp_hook), AV_OPT_TYPE_STRING, { .str = "tcp" }, 0, 0, D | E }, + { "ijkapplication", "AVApplicationContext", OFFSET(app_ctx_intptr), AV_OPT_TYPE_INT64, { .i64 = 0 }, INT64_MIN, INT64_MAX, .flags = D }, { NULL } }; @@ -191,6 +195,7 @@ static int http_open_cnx_internal(URLContext *h, AVDictionary **options) char path1[MAX_URL_SIZE]; char buf[1024], urlbuf[MAX_URL_SIZE]; int port, use_proxy, err, location_changed = 0; + char prev_location[4096]; HTTPContext *s = h->priv_data; lower_proto = s->tcp_hook; @@ -231,6 +236,7 @@ static int http_open_cnx_internal(URLContext *h, AVDictionary **options) ff_url_join(buf, sizeof(buf), lower_proto, NULL, hostname, port, NULL); if (!s->hd) { + av_dict_set_int(options, "ijkapplication", (int64_t)(intptr_t)s->app_ctx, 0); err = ffurl_open_whitelist(&s->hd, buf, AVIO_FLAG_READ_WRITE, &h->interrupt_callback, options, h->protocol_whitelist, h->protocol_blacklist, h); @@ -238,6 +244,7 @@ static int http_open_cnx_internal(URLContext *h, AVDictionary **options) return err; } + av_strlcpy(prev_location, s->location, sizeof(prev_location)); err = http_connect(h, path, local_path, hoststr, auth, proxyauth, &location_changed); if (err < 0) @@ -491,6 +498,8 @@ static int http_open(URLContext *h, const char *uri, int flags, HTTPContext *s = h->priv_data; int ret; + s->app_ctx = (AVApplicationContext *)(intptr_t)s->app_ctx_intptr; + if( s->seekable == 1 ) h->is_streamed = 0; else @@ -520,7 +529,9 @@ static int http_open(URLContext *h, const char *uri, int flags, if (s->listen) { return http_listen(h, uri, flags, options); } + av_application_will_http_open(s->app_ctx, (void*)h, uri); ret = http_open_cnx(h, options); + av_application_did_http_open(s->app_ctx, (void*)h, uri, ret, s->http_code); if (ret < 0) av_dict_free(&s->chained_options); return ret; @@ -1632,7 +1643,9 @@ static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int fo s->hd = NULL; /* if it fails, continue on old connection */ + av_application_will_http_seek(s->app_ctx, (void*)h, s->location, off); if ((ret = http_open_cnx(h, &options)) < 0) { + av_application_did_http_seek(s->app_ctx, (void*)h, s->location, off, ret, s->http_code); av_dict_free(&options); memcpy(s->buffer, old_buf, old_buf_size); s->buf_ptr = s->buffer; @@ -1641,6 +1654,7 @@ static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int fo s->off = old_off; return ret; } + av_application_did_http_seek(s->app_ctx, (void*)h, s->location, off, ret, s->http_code); av_dict_free(&options); ffurl_close(old_hd); return off; @@ -1733,6 +1747,8 @@ static int http_proxy_open(URLContext *h, const char *uri, int flags) char *authstr; int new_loc; + s->app_ctx = (AVApplicationContext *)(intptr_t)s->app_ctx_intptr; + if( s->seekable == 1 ) h->is_streamed = 0; else From 4fd0e3fb6fa4512fdaf921cfc4ec92735770e378 Mon Sep 17 00:00:00 2001 From: Xinzheng Zhang Date: Mon, 1 Aug 2016 10:34:16 +0800 Subject: [PATCH 3358/3374] avformat/async: remove const for ff_async_protocol --- libavformat/async.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/async.c b/libavformat/async.c index 54dbd2312a24c..bdbb42fa2b426 100644 --- a/libavformat/async.c +++ b/libavformat/async.c @@ -479,7 +479,7 @@ static const AVClass async_context_class = { .version = LIBAVUTIL_VERSION_INT, }; -const URLProtocol ff_async_protocol = { +URLProtocol ff_async_protocol = { .name = "async", .url_open2 = async_open, .url_read = async_read, From 9fe636f468bdfd642fa82af27fbcdc1191580d22 Mon Sep 17 00:00:00 2001 From: Xinzheng Zhang Date: Tue, 28 Jun 2016 20:07:11 +0800 Subject: [PATCH 3359/3374] avformat/tcp: support timeout for getaddrinfo --- libavformat/tcp.c | 230 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) diff --git a/libavformat/tcp.c b/libavformat/tcp.c index f9f07e18e4c97..60a3c75452eaa 100644 --- a/libavformat/tcp.c +++ b/libavformat/tcp.c @@ -32,6 +32,9 @@ #if HAVE_POLL_H #include #endif +#if HAVE_PTHREADS +#include +#endif typedef struct TCPContext { const AVClass *class; @@ -43,6 +46,9 @@ typedef struct TCPContext { int recv_buffer_size; int send_buffer_size; int64_t app_ctx_intptr; + + int addrinfo_timeout; + AVApplicationContext *app_ctx; } TCPContext; @@ -56,6 +62,8 @@ 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 }, { "ijkapplication", "AVApplicationContext", OFFSET(app_ctx_intptr), AV_OPT_TYPE_INT64, { .i64 = 0 }, INT64_MIN, INT64_MAX, .flags = D }, + + { "addrinfo_timeout", "set timeout (in microseconds) for getaddrinfo()", OFFSET(addrinfo_timeout), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E }, { NULL } }; @@ -66,6 +74,221 @@ static const AVClass tcp_class = { .version = LIBAVUTIL_VERSION_INT, }; +#ifdef HAVE_PTHREADS + +typedef struct TCPAddrinfoRequest +{ + AVBufferRef *buffer; + + pthread_mutex_t mutex; + pthread_cond_t cond; + + AVIOInterruptCB interrupt_callback; + + char *hostname; + char *servname; + struct addrinfo hints; + struct addrinfo *res; + + volatile int finished; + int last_error; +} TCPAddrinfoRequest; + +static void tcp_getaddrinfo_request_free(TCPAddrinfoRequest *req) +{ + av_assert0(req); + if (req->res) { + freeaddrinfo(req->res); + req->res = NULL; + } + + av_freep(&req->servname); + av_freep(&req->hostname); + pthread_cond_destroy(&req->cond); + pthread_mutex_destroy(&req->mutex); + av_freep(&req); +} + +static void tcp_getaddrinfo_request_free_buffer(void *opaque, uint8_t *data) +{ + av_assert0(opaque); + TCPAddrinfoRequest *req = (TCPAddrinfoRequest *)opaque; + tcp_getaddrinfo_request_free(req); +} + +static int tcp_getaddrinfo_request_create(TCPAddrinfoRequest **request, + const char *hostname, + const char *servname, + const struct addrinfo *hints, + const AVIOInterruptCB *int_cb) +{ + TCPAddrinfoRequest *req = (TCPAddrinfoRequest *) av_mallocz(sizeof(TCPAddrinfoRequest)); + if (!req) + return AVERROR(ENOMEM); + + if (pthread_mutex_init(&req->mutex, NULL)) { + av_freep(&req); + return AVERROR(ENOMEM); + } + + if (pthread_cond_init(&req->cond, NULL)) { + pthread_mutex_destroy(&req->mutex); + av_freep(&req); + return AVERROR(ENOMEM); + } + + if (int_cb) + req->interrupt_callback = *int_cb; + + if (hostname) { + req->hostname = av_strdup(hostname); + if (!req->hostname) + goto fail; + } + + if (servname) { + req->servname = av_strdup(servname); + if (!req->hostname) + goto fail; + } + + if (hints) { + req->hints.ai_family = hints->ai_family; + req->hints.ai_socktype = hints->ai_socktype; + req->hints.ai_protocol = hints->ai_protocol; + req->hints.ai_flags = hints->ai_flags; + } + + req->buffer = av_buffer_create(NULL, 0, tcp_getaddrinfo_request_free_buffer, req, 0); + if (!req->buffer) + goto fail; + + *request = req; + return 0; +fail: + tcp_getaddrinfo_request_free(req); + return AVERROR(ENOMEM); +} + +static void *tcp_getaddrinfo_worker(void *arg) +{ + TCPAddrinfoRequest *req = arg; + + getaddrinfo(req->hostname, req->servname, &req->hints, &req->res); + pthread_mutex_lock(&req->mutex); + req->finished = 1; + pthread_cond_signal(&req->cond); + pthread_mutex_unlock(&req->mutex); + av_buffer_unref(&req->buffer); + return NULL; +} + +static void *tcp_getaddrinfo_one_by_one_worker(void *arg) +{ + struct addrinfo *temp_addrinfo = NULL; + struct addrinfo *cur = NULL; + int ret = EAI_FAIL; + int i = 0; + int option_length = 0; + + pthread_mutex_lock(&req->mutex); + req->finished = 1; + pthread_cond_signal(&req->cond); + pthread_mutex_unlock(&req->mutex); + av_buffer_unref(&req->buffer); + return NULL; +} + +int ijk_tcp_getaddrinfo_nonblock(const char *hostname, const char *servname, + const struct addrinfo *hints, struct addrinfo **res, + int64_t timeout, + const AVIOInterruptCB *int_cb) +{ + int ret; + int64_t start; + int64_t now; + AVBufferRef *req_ref = NULL; + TCPAddrinfoRequest *req = NULL; + pthread_t work_thread; + + if (hostname && !hostname[0]) + hostname = NULL; + + if (timeout <= 0) + return getaddrinfo(hostname, servname, hints, res); + + ret = tcp_getaddrinfo_request_create(&req, hostname, servname, hints, int_cb); + if (ret) + goto fail; + + req_ref = av_buffer_ref(req->buffer); + if (req_ref == NULL) { + ret = AVERROR(ENOMEM); + goto fail; + } + + /* FIXME: using a thread pool would be better. */ + ret = pthread_create(&work_thread, NULL, tcp_getaddrinfo_worker, req); + if (ret) { + ret = AVERROR(ret); + goto fail; + } + + pthread_detach(work_thread); + + start = av_gettime(); + now = start; + + pthread_mutex_lock(&req->mutex); + while (1) { + int64_t wait_time = now + 100000; + struct timespec tv = { .tv_sec = wait_time / 1000000, + .tv_nsec = (wait_time % 1000000) * 1000 }; + + if (req->finished || (start + timeout < now)) { + if (req->res) { + ret = 0; + *res = req->res; + req->res = NULL; + } else { + ret = req->last_error ? req->last_error : AVERROR_EXIT; + } + break; + } +#if defined(__ANDROID__) && defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC) + ret = pthread_cond_timedwait_monotonic_np(&req->cond, &req->mutex, &tv); +#else + ret = pthread_cond_timedwait(&req->cond, &req->mutex, &tv); +#endif + if (ret != 0 && ret != ETIMEDOUT) { + av_log(NULL, AV_LOG_ERROR, "pthread_cond_timedwait failed: %d\n", ret); + ret = AVERROR_EXIT; + break; + } + + if (ff_check_interrupt(&req->interrupt_callback)) { + ret = AVERROR_EXIT; + break; + } + + now = av_gettime(); + } + pthread_mutex_unlock(&req->mutex); +fail: + av_buffer_unref(&req_ref); + return ret; +} + +#else +int ijk_tcp_getaddrinfo_nonblock(const char *hostname, const char *servname, + const struct addrinfo *hints, struct addrinfo **res, + int64_t timeout, + const AVIOInterruptCB *int_cb) +{ + return getaddrinfo(hostname, servname, hints, res); +} +#endif + /* return non zero if error */ static int tcp_open(URLContext *h, const char *uri, int flags) { @@ -113,10 +336,17 @@ static int tcp_open(URLContext *h, const char *uri, int flags) snprintf(portstr, sizeof(portstr), "%d", port); if (s->listen) hints.ai_flags |= AI_PASSIVE; +#ifdef HAVE_PTHREADS + ret = ijk_tcp_getaddrinfo_nonblock(hostname, portstr, &hints, &ai, s->addrinfo_timeout, &h->interrupt_callback); +#else + if (s->addrinfo_timeout > 0) + av_log(h, AV_LOG_WARNING, "Ignore addrinfo_timeout without pthreads support.\n") if (!hostname[0]) ret = getaddrinfo(NULL, portstr, &hints, &ai); else ret = getaddrinfo(hostname, portstr, &hints, &ai); +#endif + if (ret) { av_log(h, AV_LOG_ERROR, "Failed to resolve hostname %s: %s\n", From 0be2a05bf6fd1c027197bca28806ce793806a246 Mon Sep 17 00:00:00 2001 From: Xinzheng Zhang Date: Thu, 11 Aug 2016 14:48:44 +0800 Subject: [PATCH 3360/3374] avformat/tcp: add one_by_one option for getaddrinfo() --- libavformat/tcp.c | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/libavformat/tcp.c b/libavformat/tcp.c index 60a3c75452eaa..3c13864abcf01 100644 --- a/libavformat/tcp.c +++ b/libavformat/tcp.c @@ -47,6 +47,7 @@ typedef struct TCPContext { int send_buffer_size; int64_t app_ctx_intptr; + int addrinfo_one_by_one; int addrinfo_timeout; AVApplicationContext *app_ctx; @@ -63,6 +64,7 @@ static const AVOption options[] = { { "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 }, { "ijkapplication", "AVApplicationContext", OFFSET(app_ctx_intptr), AV_OPT_TYPE_INT64, { .i64 = 0 }, INT64_MIN, INT64_MAX, .flags = D }, + { "addrinfo_one_by_one", "parse addrinfo one by one in getaddrinfo()", OFFSET(addrinfo_one_by_one), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = D|E }, { "addrinfo_timeout", "set timeout (in microseconds) for getaddrinfo()", OFFSET(addrinfo_timeout), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E }, { NULL } }; @@ -191,6 +193,31 @@ static void *tcp_getaddrinfo_one_by_one_worker(void *arg) int i = 0; int option_length = 0; + TCPAddrinfoRequest *req = (TCPAddrinfoRequest *)arg; + + int family_option[2] = {AF_INET, AF_INET6}; + + option_length = sizeof(family_option) / sizeof(family_option[0]); + + for (; i < option_length; ++i) { + struct addrinfo *hint = &req->hints; + hint->ai_family = family_option[i]; + ret = getaddrinfo(req->hostname, req->servname, hint, &temp_addrinfo); + if (ret) { + req->last_error = ret; + continue; + } + pthread_mutex_lock(&req->mutex); + if (!req->res) { + req->res = temp_addrinfo; + } else { + cur = req->res; + while (cur->ai_next) + cur = cur->ai_next; + cur->ai_next = temp_addrinfo; + } + pthread_mutex_unlock(&req->mutex); + } pthread_mutex_lock(&req->mutex); req->finished = 1; pthread_cond_signal(&req->cond); @@ -202,7 +229,7 @@ static void *tcp_getaddrinfo_one_by_one_worker(void *arg) int ijk_tcp_getaddrinfo_nonblock(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res, int64_t timeout, - const AVIOInterruptCB *int_cb) + const AVIOInterruptCB *int_cb, int one_by_one) { int ret; int64_t start; @@ -228,7 +255,11 @@ int ijk_tcp_getaddrinfo_nonblock(const char *hostname, const char *servname, } /* FIXME: using a thread pool would be better. */ - ret = pthread_create(&work_thread, NULL, tcp_getaddrinfo_worker, req); + if (one_by_one) + ret = pthread_create(&work_thread, NULL, tcp_getaddrinfo_one_by_one_worker, req); + else + ret = pthread_create(&work_thread, NULL, tcp_getaddrinfo_worker, req); + if (ret) { ret = AVERROR(ret); goto fail; @@ -337,7 +368,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags) if (s->listen) hints.ai_flags |= AI_PASSIVE; #ifdef HAVE_PTHREADS - ret = ijk_tcp_getaddrinfo_nonblock(hostname, portstr, &hints, &ai, s->addrinfo_timeout, &h->interrupt_callback); + ret = ijk_tcp_getaddrinfo_nonblock(hostname, portstr, &hints, &ai, s->addrinfo_timeout, &h->interrupt_callback, s->addrinfo_one_by_one); #else if (s->addrinfo_timeout > 0) av_log(h, AV_LOG_WARNING, "Ignore addrinfo_timeout without pthreads support.\n") From 830183d68d06ecacb4cc79589215ff069309979a Mon Sep 17 00:00:00 2001 From: Xinzheng Zhang Date: Thu, 11 Aug 2016 14:49:00 +0800 Subject: [PATCH 3361/3374] avformat/tcp: export ijk_tcp_getaddrinfo_nonblock --- libavformat/tcp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavformat/tcp.c b/libavformat/tcp.c index 3c13864abcf01..a05890e10c658 100644 --- a/libavformat/tcp.c +++ b/libavformat/tcp.c @@ -76,6 +76,10 @@ static const AVClass tcp_class = { .version = LIBAVUTIL_VERSION_INT, }; +int ijk_tcp_getaddrinfo_nonblock(const char *hostname, const char *servname, + const struct addrinfo *hints, struct addrinfo **res, + int64_t timeout, + const AVIOInterruptCB *int_cb, int one_by_one); #ifdef HAVE_PTHREADS typedef struct TCPAddrinfoRequest From 28562835366d6423e3a7ff971f9bcde22654584c Mon Sep 17 00:00:00 2001 From: raymondzheng Date: Tue, 10 Jan 2017 16:53:45 +0800 Subject: [PATCH 3362/3374] avformat/hls: pass down av options --- libavformat/hls.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index 6eab6424779f2..5b8f3215a796b 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -610,6 +610,7 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, av_dict_copy(&tmp, opts, 0); av_dict_copy(&tmp, opts2, 0); + av_dict_set(&tmp, "seekable", "1", 0); if (av_strstart(url, "crypto", NULL)) { if (url[6] == '+' || url[6] == ':') @@ -1645,7 +1646,7 @@ static int hls_close(AVFormatContext *s) return 0; } -static int hls_read_header(AVFormatContext *s) +static int hls_read_header(AVFormatContext *s, AVDictionary **options) { void *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb; HLSContext *c = s->priv_data; @@ -1660,6 +1661,9 @@ static int hls_read_header(AVFormatContext *s) c->first_timestamp = AV_NOPTS_VALUE; c->cur_timestamp = AV_NOPTS_VALUE; + if (options && *options) + av_dict_copy(&c->avio_opts, *options, 0); + if (u) { // get the previous user agent & set back to null if string size is zero update_options(&c->user_agent, "user_agent", u); @@ -2209,7 +2213,7 @@ AVInputFormat ff_hls_demuxer = { .priv_class = &hls_class, .priv_data_size = sizeof(HLSContext), .read_probe = hls_probe, - .read_header = hls_read_header, + .read_header2 = hls_read_header, .read_packet = hls_read_packet, .read_close = hls_close, .read_seek = hls_read_seek, From b4d1ebc32450dd28932f8006dff3ad12dd629641 Mon Sep 17 00:00:00 2001 From: raymondzheng Date: Fri, 23 Dec 2016 12:28:56 +0800 Subject: [PATCH 3363/3374] avformat/protocols: add ijkio --- libavformat/concatdec.c | 1 + libavformat/ijkutils.c | 1 + libavformat/protocols.c | 1 + 3 files changed, 3 insertions(+) diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c index b4d7072d86e0f..97491fc78af52 100644 --- a/libavformat/concatdec.c +++ b/libavformat/concatdec.c @@ -336,6 +336,7 @@ static int open_file(AVFormatContext *avf, unsigned fileno) if (cat->options) av_dict_copy(&tmp, cat->options, 0); + av_dict_set_int(&tmp, "cur_file_no", fileno, 0); ret = avformat_open_input(&new_avf, file->url, NULL, &tmp); av_dict_free(&tmp); if (ret < 0 || diff --git a/libavformat/ijkutils.c b/libavformat/ijkutils.c index 59aa7c6d3ad0a..3b883fd6f4833 100644 --- a/libavformat/ijkutils.c +++ b/libavformat/ijkutils.c @@ -64,3 +64,4 @@ IJK_DUMMY_PROTOCOL(ijkhttphook); IJK_DUMMY_PROTOCOL(ijklongurl); IJK_DUMMY_PROTOCOL(ijksegment); IJK_DUMMY_PROTOCOL(ijktcphook); +IJK_DUMMY_PROTOCOL(ijkio); diff --git a/libavformat/protocols.c b/libavformat/protocols.c index af095d24c3864..cdcc84d7db116 100644 --- a/libavformat/protocols.c +++ b/libavformat/protocols.c @@ -44,6 +44,7 @@ extern const URLProtocol ff_ijklongurl_protocol; extern const URLProtocol ff_ijkmediadatasource_protocol; extern const URLProtocol ff_ijksegment_protocol; extern const URLProtocol ff_ijktcphook_protocol; +extern const URLProtocol ff_ijkio_protocol; extern const URLProtocol ff_mmsh_protocol; extern const URLProtocol ff_mmst_protocol; extern const URLProtocol ff_md5_protocol; From 7e37108e19dc93660f80e7a10fb6b5d29c39f2e0 Mon Sep 17 00:00:00 2001 From: raymondzheng Date: Fri, 24 Mar 2017 11:52:00 +0800 Subject: [PATCH 3364/3374] avformat/tcp: support option rw_timeout and connect_timeout --- libavformat/tcp.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/libavformat/tcp.c b/libavformat/tcp.c index a05890e10c658..12df9dab0317c 100644 --- a/libavformat/tcp.c +++ b/libavformat/tcp.c @@ -59,6 +59,7 @@ typedef struct TCPContext { static const AVOption options[] = { { "listen", "Listen for incoming connections", OFFSET(listen), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, .flags = D|E }, { "timeout", "set timeout (in microseconds) of socket I/O operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E }, + { "connect_timeout", "set connect timeout (in microseconds) of socket", OFFSET(open_timeout), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E }, { "listen_timeout", "Connection awaiting timeout (in milliseconds)", OFFSET(listen_timeout), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_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 }, @@ -335,7 +336,11 @@ static int tcp_open(URLContext *h, const char *uri, int flags) int ret; char hostname[1024],proto[1024],path[1024]; char portstr[10]; - s->open_timeout = 5000000; + + if (s->open_timeout < 0) { + s->open_timeout = 15000000; + } + s->app_ctx = (AVApplicationContext *)(intptr_t)s->app_ctx_intptr; av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), @@ -357,15 +362,18 @@ static int tcp_open(URLContext *h, const char *uri, int flags) } if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) { s->rw_timeout = strtol(buf, NULL, 10); + if (s->rw_timeout >= 0) { + s->open_timeout = s->rw_timeout; + } } if (av_find_info_tag(buf, sizeof(buf), "listen_timeout", p)) { s->listen_timeout = strtol(buf, NULL, 10); } } - if (s->rw_timeout >= 0) { - s->open_timeout = - h->rw_timeout = s->rw_timeout; + if (s->rw_timeout >= 0 ) { + h->rw_timeout = s->rw_timeout; } + hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; snprintf(portstr, sizeof(portstr), "%d", port); From fb78b38932c7be17b458535f5c10339076ab9924 Mon Sep 17 00:00:00 2001 From: raymondzheng Date: Fri, 12 May 2017 12:21:37 +0800 Subject: [PATCH 3365/3374] avformat/pipe: enable seekable --- libavformat/file.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavformat/file.c b/libavformat/file.c index 1d321c42050e3..dabecf59ca7e1 100644 --- a/libavformat/file.c +++ b/libavformat/file.c @@ -386,7 +386,7 @@ static int pipe_open(URLContext *h, const char *filename, int flags) setmode(fd, O_BINARY); #endif c->fd = fd; - h->is_streamed = 1; + h->is_streamed = 0; return 0; } @@ -395,6 +395,7 @@ const URLProtocol ff_pipe_protocol = { .url_open = pipe_open, .url_read = file_read, .url_write = file_write, + .url_seek = file_seek, .url_get_file_handle = file_get_handle, .url_check = file_check, .priv_data_size = sizeof(FileContext), From bb20db75b64d95cf241c90d64fbd1458c2399b55 Mon Sep 17 00:00:00 2001 From: raymondzheng Date: Mon, 10 Jul 2017 18:50:38 +0800 Subject: [PATCH 3366/3374] avformat/utils: support don't get real frame rate --- libavformat/concatdec.c | 11 +++++++++++ libavformat/utils.c | 14 ++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c index 97491fc78af52..41a46ef9a93c6 100644 --- a/libavformat/concatdec.c +++ b/libavformat/concatdec.c @@ -322,6 +322,8 @@ static int open_file(AVFormatContext *avf, unsigned fileno) AVFormatContext *new_avf = NULL; int ret; AVDictionary *tmp = NULL; + AVDictionaryEntry *t = NULL; + int fps_flag = 0; new_avf = avformat_alloc_context(); if (!new_avf) @@ -337,6 +339,15 @@ static int open_file(AVFormatContext *avf, unsigned fileno) av_dict_copy(&tmp, cat->options, 0); av_dict_set_int(&tmp, "cur_file_no", fileno, 0); + + t = av_dict_get(tmp, "skip-calc-frame-rate", NULL, AV_DICT_MATCH_CASE); + if (t) { + fps_flag = (int) strtol(t->value, NULL, 10); + if (fps_flag > 0) { + av_dict_set_int(&new_avf->metadata, "skip-calc-frame-rate", fps_flag, 0); + } + } + ret = avformat_open_input(&new_avf, file->url, NULL, &tmp); av_dict_free(&tmp); if (ret < 0 || diff --git a/libavformat/utils.c b/libavformat/utils.c index 361b394111ff5..b508d205dc6d2 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -3643,6 +3643,20 @@ FF_ENABLE_DEPRECATION_WARNINGS st = ic->streams[i]; if (!has_codec_parameters(st, NULL)) break; + + if (ic->metadata) { + AVDictionaryEntry *t = av_dict_get(ic->metadata, "skip-calc-frame-rate", NULL, AV_DICT_MATCH_CASE); + if (t) { + int fps_flag = (int) strtol(t->value, NULL, 10); + if (!st->r_frame_rate.num && st->avg_frame_rate.num > 0 && st->avg_frame_rate.den > 0 && fps_flag > 0) { + int avg_fps = st->avg_frame_rate.num / st->avg_frame_rate.den; + if (avg_fps > 0 && avg_fps <= 120) { + st->r_frame_rate.num = st->avg_frame_rate.num; + st->r_frame_rate.den = st->avg_frame_rate.den; + } + } + } + } /* If the timebase is coarse (like the usual millisecond precision * of mkv), we need to analyze more frames to reliably arrive at * the correct fps. */ From f42902e721d56b77628c7c5dd61b9b7eab315f2e Mon Sep 17 00:00:00 2001 From: raymondzheng Date: Fri, 11 Aug 2017 18:58:55 +0800 Subject: [PATCH 3367/3374] libavformat/tcp: support dns cache --- libavformat/tcp.c | 75 +++++++++---- libavutil/Makefile | 2 + libavutil/application.c | 23 ++-- libavutil/application.h | 2 +- libavutil/dns_cache.c | 229 ++++++++++++++++++++++++++++++++++++++++ libavutil/dns_cache.h | 38 +++++++ 6 files changed, 338 insertions(+), 31 deletions(-) create mode 100644 libavutil/dns_cache.c create mode 100644 libavutil/dns_cache.h diff --git a/libavformat/tcp.c b/libavformat/tcp.c index 12df9dab0317c..67d23cebf04dc 100644 --- a/libavformat/tcp.c +++ b/libavformat/tcp.c @@ -24,6 +24,7 @@ #include "libavutil/opt.h" #include "libavutil/time.h" #include "libavutil/application.h" +#include "libavutil/dns_cache.h" #include "internal.h" #include "network.h" @@ -49,6 +50,8 @@ typedef struct TCPContext { int addrinfo_one_by_one; int addrinfo_timeout; + int64_t dns_cache_timeout; + int dns_cache_clear; AVApplicationContext *app_ctx; } TCPContext; @@ -67,6 +70,8 @@ static const AVOption options[] = { { "addrinfo_one_by_one", "parse addrinfo one by one in getaddrinfo()", OFFSET(addrinfo_one_by_one), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = D|E }, { "addrinfo_timeout", "set timeout (in microseconds) for getaddrinfo()", OFFSET(addrinfo_timeout), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E }, + { "dns_cache_timeout", "dns cache TTL (in microseconds)", OFFSET(dns_cache_timeout), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E }, + { "dns_cache_clear", "clear dns cache", OFFSET(dns_cache_clear), AV_OPT_TYPE_INT, { .i64 = 0}, -1, INT_MAX, .flags = D|E }, { NULL } }; @@ -336,6 +341,9 @@ static int tcp_open(URLContext *h, const char *uri, int flags) int ret; char hostname[1024],proto[1024],path[1024]; char portstr[10]; + char hostname_bak[1024] = {0}; + AVAppTcpIOControl control = {0}; + DnsCacheEntry *dns_entry = NULL; if (s->open_timeout < 0) { s->open_timeout = 15000000; @@ -379,25 +387,41 @@ static int tcp_open(URLContext *h, const char *uri, int flags) snprintf(portstr, sizeof(portstr), "%d", port); if (s->listen) hints.ai_flags |= AI_PASSIVE; + + if (s->dns_cache_timeout > 0) { + memcpy(hostname_bak, hostname, 1024); + if (s->dns_cache_clear) { + av_log(NULL, AV_LOG_INFO, "will delete cache entry, hostname = %s\n", hostname); + remove_dns_cache_entry(hostname); + } else { + dns_entry = get_dns_cache_reference(hostname); + } + } + + if (!dns_entry) { #ifdef HAVE_PTHREADS - ret = ijk_tcp_getaddrinfo_nonblock(hostname, portstr, &hints, &ai, s->addrinfo_timeout, &h->interrupt_callback, s->addrinfo_one_by_one); + ret = ijk_tcp_getaddrinfo_nonblock(hostname, portstr, &hints, &ai, s->addrinfo_timeout, &h->interrupt_callback, s->addrinfo_one_by_one); #else - if (s->addrinfo_timeout > 0) - av_log(h, AV_LOG_WARNING, "Ignore addrinfo_timeout without pthreads support.\n") - if (!hostname[0]) - ret = getaddrinfo(NULL, portstr, &hints, &ai); - else - ret = getaddrinfo(hostname, portstr, &hints, &ai); + if (s->addrinfo_timeout > 0) + av_log(h, AV_LOG_WARNING, "Ignore addrinfo_timeout without pthreads support.\n"); + if (!hostname[0]) + ret = getaddrinfo(NULL, portstr, &hints, &ai); + else + ret = getaddrinfo(hostname, portstr, &hints, &ai); #endif - if (ret) { - av_log(h, AV_LOG_ERROR, - "Failed to resolve hostname %s: %s\n", - hostname, gai_strerror(ret)); - return AVERROR(EIO); - } + if (ret) { + av_log(h, AV_LOG_ERROR, + "Failed to resolve hostname %s: %s\n", + hostname, gai_strerror(ret)); + return AVERROR(EIO); + } - cur_ai = ai; + cur_ai = ai; + } else { + av_log(NULL, AV_LOG_INFO, "Hit DNS cache hostname = %s\n", hostname); + cur_ai = dns_entry->res; + } restart: #if HAVE_STRUCT_SOCKADDR_IN6 @@ -447,17 +471,20 @@ static int tcp_open(URLContext *h, const char *uri, int flags) 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 (av_application_on_tcp_did_open(s->app_ctx, ret, fd)) + if (av_application_on_tcp_did_open(s->app_ctx, ret, fd, &control)) goto fail1; if (ret == AVERROR_EXIT) goto fail1; else goto fail; } else { - ret = av_application_on_tcp_did_open(s->app_ctx, 0, fd); + ret = av_application_on_tcp_did_open(s->app_ctx, 0, fd, &control); if (ret) { av_log(NULL, AV_LOG_WARNING, "terminated by application in AVAPP_CTRL_DID_TCP_OPEN"); goto fail1; + } else if (!dns_entry && strcmp(control.ip, hostname_bak)) { + add_dns_cache_entry(hostname_bak, cur_ai, s->dns_cache_timeout); + av_log(NULL, AV_LOG_INFO, "Add dns cache hostname = %s, ip = %s\n", hostname_bak , control.ip); } } } @@ -465,7 +492,11 @@ static int tcp_open(URLContext *h, const char *uri, int flags) h->is_streamed = 1; s->fd = fd; - freeaddrinfo(ai); + if (dns_entry) { + release_dns_cache_reference(hostname_bak, &dns_entry); + } else { + freeaddrinfo(ai); + } return 0; fail: @@ -480,7 +511,15 @@ static int tcp_open(URLContext *h, const char *uri, int flags) fail1: if (fd >= 0) closesocket(fd); - freeaddrinfo(ai); + + if (dns_entry) { + av_log(NULL, AV_LOG_ERROR, "Hit dns cache but connect fail hostname = %s, ip = %s\n", hostname , control.ip); + release_dns_cache_reference(hostname_bak, &dns_entry); + remove_dns_cache_entry(hostname_bak); + } else { + freeaddrinfo(ai); + } + return ret; } diff --git a/libavutil/Makefile b/libavutil/Makefile index 4e3a04bff0e9c..8d7e84a08fb71 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -25,6 +25,7 @@ HEADERS = adler32.h \ dict.h \ display.h \ downmix_info.h \ + dns_cache.h \ error.h \ eval.h \ fifo.h \ @@ -111,6 +112,7 @@ OBJS = adler32.o \ dict.o \ display.o \ downmix_info.o \ + dns_cache.o \ error.o \ eval.o \ fifo.o \ diff --git a/libavutil/application.c b/libavutil/application.c index 2626742a0b291..3a4ec85071815 100644 --- a/libavutil/application.c +++ b/libavutil/application.c @@ -148,14 +148,13 @@ int av_application_on_tcp_will_open(AVApplicationContext *h) } // only callback returns error -int av_application_on_tcp_did_open(AVApplicationContext *h, int error, int fd) +int av_application_on_tcp_did_open(AVApplicationContext *h, int error, int fd, AVAppTcpIOControl *control) { struct sockaddr_storage so_stg; int ret = 0; socklen_t so_len = sizeof(so_stg); int so_family; - AVAppTcpIOControl control = {0}; - char *so_ip_name = control.ip; + char *so_ip_name = control->ip; if (!h || !h->func_on_app_event || fd <= 0) return 0; @@ -163,30 +162,30 @@ int av_application_on_tcp_did_open(AVApplicationContext *h, int error, int fd) ret = getpeername(fd, (struct sockaddr *)&so_stg, &so_len); if (ret) return 0; - control.error = error; - control.fd = fd; + control->error = error; + control->fd = fd; so_family = ((struct sockaddr*)&so_stg)->sa_family; switch (so_family) { case AF_INET: { struct sockaddr_in* in4 = (struct sockaddr_in*)&so_stg; - if (inet_ntop(AF_INET, &(in4->sin_addr), so_ip_name, sizeof(control.ip))) { - control.family = AF_INET; - control.port = in4->sin_port; + if (inet_ntop(AF_INET, &(in4->sin_addr), so_ip_name, sizeof(control->ip))) { + control->family = AF_INET; + control->port = in4->sin_port; } break; } case AF_INET6: { struct sockaddr_in6* in6 = (struct sockaddr_in6*)&so_stg; - if (inet_ntop(AF_INET6, &(in6->sin6_addr), so_ip_name, sizeof(control.ip))) { - control.family = AF_INET6; - control.port = in6->sin6_port; + if (inet_ntop(AF_INET6, &(in6->sin6_addr), so_ip_name, sizeof(control->ip))) { + control->family = AF_INET6; + control->port = in6->sin6_port; } break; } } - return h->func_on_app_event(h, AVAPP_CTRL_DID_TCP_OPEN, (void *)&control, sizeof(AVAppTcpIOControl)); + return h->func_on_app_event(h, AVAPP_CTRL_DID_TCP_OPEN, (void *)control, sizeof(AVAppTcpIOControl)); } void av_application_on_async_statistic(AVApplicationContext *h, AVAppAsyncStatistic *statistic) diff --git a/libavutil/application.h b/libavutil/application.h index a33b272fdd5c4..9e2c1f5b1aadb 100644 --- a/libavutil/application.h +++ b/libavutil/application.h @@ -111,7 +111,7 @@ void av_application_did_io_tcp_read(AVApplicationContext *h, void *obj, int byte int av_application_on_io_control(AVApplicationContext *h, int event_type, AVAppIOControl *control); int av_application_on_tcp_will_open(AVApplicationContext *h); -int av_application_on_tcp_did_open(AVApplicationContext *h, int error, int fd); +int av_application_on_tcp_did_open(AVApplicationContext *h, int error, int fd, AVAppTcpIOControl *control); void av_application_on_async_statistic(AVApplicationContext *h, AVAppAsyncStatistic *statistic); void av_application_on_async_read_speed(AVApplicationContext *h, AVAppAsyncReadSpeed *speed); diff --git a/libavutil/dns_cache.c b/libavutil/dns_cache.c new file mode 100644 index 0000000000000..c70540146e814 --- /dev/null +++ b/libavutil/dns_cache.c @@ -0,0 +1,229 @@ +/* + * copyright (c) 2017 Raymond Zheng + * + * 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 "libavutil/dns_cache.h" +#include "libavutil/time.h" +#include "libavformat/network.h" + +#if HAVE_PTHREADS +#include +#endif + +typedef struct DnsCacheContext DnsCacheContext; +typedef struct DnsCacheContext { + AVDictionary *dns_dictionary; + pthread_mutex_t dns_dictionary_mutex; + int initialized; +} DnsCacheContext; + +static DnsCacheContext *context = NULL; +static pthread_once_t key_once = PTHREAD_ONCE_INIT; + +static void inner_init(void) { + int ret = 0; + context = (DnsCacheContext *) av_mallocz(sizeof(DnsCacheContext)); + if (context) { + ret = pthread_mutex_init(&context->dns_dictionary_mutex, NULL); + if (!ret) { + context->initialized = 1; + } else { + av_freep(&context); + } + } +} + +static void free_private_addrinfo(struct addrinfo **p_ai) { + struct addrinfo *ai = *p_ai; + + if (ai) { + if (ai->ai_addr) { + av_freep(&ai->ai_addr); + } + av_freep(p_ai); + } +} + +static int inner_remove_dns_cache(char *hostname, DnsCacheEntry *dns_cache_entry) { + if (context && dns_cache_entry) { + if (dns_cache_entry->ref_count == 0) { + av_dict_set_int(&context->dns_dictionary, hostname, 0, 0); + free_private_addrinfo(&dns_cache_entry->res); + av_freep(&dns_cache_entry); + } else { + dns_cache_entry->delete_flag = 1; + } + } + + return 0; +} + +static DnsCacheEntry *new_dns_cache_entry(char *hostname, struct addrinfo *cur_ai, int64_t timeout) { + DnsCacheEntry *new_entry = NULL; + int64_t cur_time = av_gettime_relative(); + + if (cur_time < 0) { + goto fail; + } + + new_entry = (DnsCacheEntry *) av_mallocz(sizeof(struct DnsCacheEntry)); + if (!new_entry) { + goto fail; + } + + new_entry->res = (struct addrinfo *) av_mallocz(sizeof(struct addrinfo)); + if (!new_entry->res) { + av_freep(&new_entry); + goto fail; + } + + memcpy(new_entry->res, cur_ai, sizeof(struct addrinfo)); + + new_entry->res->ai_addr = (struct sockaddr *) av_mallocz(sizeof(struct sockaddr)); + if (!new_entry->res->ai_addr) { + av_freep(&new_entry->res); + av_freep(&new_entry); + goto fail; + } + + memcpy(new_entry->res->ai_addr, cur_ai->ai_addr, sizeof(struct sockaddr)); + new_entry->res->ai_canonname = NULL; + new_entry->res->ai_next = NULL; + new_entry->ref_count = 0; + new_entry->delete_flag = 0; + new_entry->expired_time = cur_time + timeout * 1000; + + return new_entry; + +fail: + return NULL; +} + +DnsCacheEntry *get_dns_cache_reference(char *hostname) { + AVDictionaryEntry *elem = NULL; + DnsCacheEntry *dns_cache_entry = NULL; + int64_t cur_time = av_gettime_relative(); + + if (cur_time < 0 || !hostname || strlen(hostname) == 0) { + return NULL; + } + + if (!context || !context->initialized) { +#if HAVE_PTHREADS + pthread_once(&key_once, inner_init); +#endif + } + + if (context && context->initialized) { + pthread_mutex_lock(&context->dns_dictionary_mutex); + elem = av_dict_get(context->dns_dictionary, hostname, NULL, AV_DICT_MATCH_CASE); + if (elem) { + dns_cache_entry = (DnsCacheEntry *) (intptr_t) strtoll(elem->value, NULL, 10); + if (dns_cache_entry) { + if (dns_cache_entry->expired_time < cur_time) { + inner_remove_dns_cache(hostname, dns_cache_entry); + dns_cache_entry = NULL; + } else { + dns_cache_entry->ref_count++; + } + } + } + pthread_mutex_unlock(&context->dns_dictionary_mutex); + } + + return dns_cache_entry; +} + +int release_dns_cache_reference(char *hostname, DnsCacheEntry **p_entry) { + DnsCacheEntry *entry = *p_entry; + + if (!hostname || strlen(hostname) == 0) { + return -1; + } + + if (context && context->initialized && entry) { + pthread_mutex_lock(&context->dns_dictionary_mutex); + entry->ref_count--; + if (entry->delete_flag && entry->ref_count == 0) { + inner_remove_dns_cache(hostname, entry); + entry = NULL; + } + pthread_mutex_unlock(&context->dns_dictionary_mutex); + } + return 0; +} + +int remove_dns_cache_entry(char *hostname) { + AVDictionaryEntry *elem = NULL; + DnsCacheEntry *dns_cache_entry = NULL; + + if (!hostname || strlen(hostname) == 0) { + return -1; + } + + if (context && context->initialized) { + pthread_mutex_lock(&context->dns_dictionary_mutex); + elem = av_dict_get(context->dns_dictionary, hostname, NULL, AV_DICT_MATCH_CASE); + if (elem) { + dns_cache_entry = (DnsCacheEntry *) (intptr_t) strtoll(elem->value, NULL, 10); + if (dns_cache_entry) { + inner_remove_dns_cache(hostname, dns_cache_entry); + } + } + pthread_mutex_unlock(&context->dns_dictionary_mutex); + } + + return 0; +} + +int add_dns_cache_entry(char *hostname, struct addrinfo *cur_ai, int64_t timeout) { + DnsCacheEntry *new_entry = NULL; + DnsCacheEntry *old_entry = NULL; + AVDictionaryEntry *elem = NULL; + + if (!hostname || strlen(hostname) == 0 || timeout <= 0) { + goto fail; + } + + if (cur_ai == NULL || cur_ai->ai_addr == NULL) { + goto fail; + } + + if (context && context->initialized) { + pthread_mutex_lock(&context->dns_dictionary_mutex); + elem = av_dict_get(context->dns_dictionary, hostname, NULL, AV_DICT_MATCH_CASE); + if (elem) { + old_entry = (DnsCacheEntry *) (intptr_t) strtoll(elem->value, NULL, 10); + if (old_entry) { + pthread_mutex_unlock(&context->dns_dictionary_mutex); + goto fail; + } + } + new_entry = new_dns_cache_entry(hostname, cur_ai, timeout); + if (new_entry) { + av_dict_set_int(&context->dns_dictionary, hostname, (int64_t) (intptr_t) new_entry, 0); + } + pthread_mutex_unlock(&context->dns_dictionary_mutex); + + return 0; + } + +fail: + return -1; +} diff --git a/libavutil/dns_cache.h b/libavutil/dns_cache.h new file mode 100644 index 0000000000000..a2ed92e6f54a8 --- /dev/null +++ b/libavutil/dns_cache.h @@ -0,0 +1,38 @@ +/* + * copyright (c) 2017 Raymond Zheng + * + * 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 + */ + +#ifndef AVUTIL_DNS_CACHE_H +#define AVUTIL_DNS_CACHE_H + +#include "libavutil/log.h" + +typedef struct DnsCacheEntry { + volatile int ref_count; + volatile int delete_flag; + int64_t expired_time; + struct addrinfo *res; // construct by private function, not support ai_next and ai_canonname, can only be released using free_private_addrinfo +} DnsCacheEntry; + +DnsCacheEntry *get_dns_cache_reference(char *hostname); +int release_dns_cache_reference(char *hostname, DnsCacheEntry **p_entry); +int remove_dns_cache_entry(char *hostname); +int add_dns_cache_entry(char *hostname, struct addrinfo *cur_ai, int64_t timeout); + +#endif /* AVUTIL_DNS_CACHE_H */ From 231ccbcf2c05812b20805c3a1bdb1cfae6ce4ffe Mon Sep 17 00:00:00 2001 From: raymondzheng Date: Tue, 29 Aug 2017 11:49:05 +0800 Subject: [PATCH 3368/3374] libavformat/flv: support HEVC --- libavformat/flv.h | 1 + libavformat/flvdec.c | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/libavformat/flv.h b/libavformat/flv.h index df5ce3d17f8c7..97324cca46d5a 100644 --- a/libavformat/flv.h +++ b/libavformat/flv.h @@ -109,6 +109,7 @@ enum { FLV_CODECID_H264 = 7, FLV_CODECID_REALH263= 8, FLV_CODECID_MPEG4 = 9, + FLV_CODECID_HEVC = 12, }; enum { diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 2d89bef15f25b..ec31e247a4ba2 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -291,6 +291,8 @@ static int flv_same_video_codec(AVCodecParameters *vpar, int flags) return vpar->codec_id == AV_CODEC_ID_VP6A; case FLV_CODECID_H264: return vpar->codec_id == AV_CODEC_ID_H264; + case FLV_CODECID_HEVC: + return vpar->codec_id == AV_CODEC_ID_HEVC; default: return vpar->codec_tag == flv_codecid; } @@ -331,6 +333,11 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, } ret = 1; // 1 byte body size adjustment for flv_read_packet() break; + case FLV_CODECID_HEVC: + par->codec_id = AV_CODEC_ID_HEVC; + vstream->need_parsing = AVSTREAM_PARSE_NONE; + ret = 3; // not 4, reading packet type will consume one byte + break; case FLV_CODECID_H264: par->codec_id = AV_CODEC_ID_H264; vstream->need_parsing = AVSTREAM_PARSE_HEADERS; @@ -1149,10 +1156,11 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) if (st->codecpar->codec_id == AV_CODEC_ID_AAC || st->codecpar->codec_id == AV_CODEC_ID_H264 || - st->codecpar->codec_id == AV_CODEC_ID_MPEG4) { + st->codecpar->codec_id == AV_CODEC_ID_MPEG4 || + st->codecpar->codec_id == AV_CODEC_ID_HEVC) { int type = avio_r8(s->pb); size--; - if (st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_MPEG4) { + if (st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_MPEG4 || st->codecpar->codec_id == AV_CODEC_ID_HEVC) { // sign extension int32_t cts = (avio_rb24(s->pb) + 0xff800000) ^ 0xff800000; pts = dts + cts; @@ -1168,7 +1176,7 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) } } if (type == 0 && (!st->codecpar->extradata || st->codecpar->codec_id == AV_CODEC_ID_AAC || - st->codecpar->codec_id == AV_CODEC_ID_H264)) { + st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_HEVC)) { AVDictionaryEntry *t; if (st->codecpar->extradata) { From a94b6c5a11f8692f4132e906800a63ddc7989e69 Mon Sep 17 00:00:00 2001 From: raymondzheng Date: Fri, 22 Dec 2017 18:58:45 +0800 Subject: [PATCH 3369/3374] avformat/tcp: support tcp fastopen --- libavformat/http.c | 1 + libavformat/network.c | 46 +++++++++ libavformat/network.h | 5 + libavformat/tcp.c | 222 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 274 insertions(+) diff --git a/libavformat/http.c b/libavformat/http.c index 33b2c3c507e02..4adac485b883a 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -210,6 +210,7 @@ static int http_open_cnx_internal(URLContext *h, AVDictionary **options) proxy_path && av_strstart(proxy_path, "http://", NULL); if (!strcmp(proto, "https")) { + av_dict_set_int(options, "fastopen", 0, 0); lower_proto = "tls"; use_proxy = 0; if (port < 0) diff --git a/libavformat/network.c b/libavformat/network.c index b3987a4d116cf..b187db3fbb59c 100644 --- a/libavformat/network.c +++ b/libavformat/network.c @@ -280,6 +280,52 @@ int ff_listen_connect(int fd, const struct sockaddr *addr, return ret; } +int ff_sendto(int fd, const char *msg, int msg_len, int flag, + const struct sockaddr *addr, + socklen_t addrlen, int timeout, URLContext *h, + int will_try_next) +{ + struct pollfd p = {fd, POLLOUT, 0}; + int ret; + socklen_t optlen; + + if (ff_socket_nonblock(fd, 1) < 0) + av_log(NULL, AV_LOG_INFO, "ff_socket_nonblock failed\n"); + + while ((ret = sendto(fd, msg, msg_len, flag, addr, addrlen)) < 0) { + ret = ff_neterrno(); + switch (ret) { + case AVERROR(EINTR): + if (ff_check_interrupt(&h->interrupt_callback)) + return AVERROR_EXIT; + continue; + case AVERROR(EINPROGRESS): + case AVERROR(EAGAIN): + ret = ff_poll_interrupt(&p, 1, timeout, &h->interrupt_callback); + if (ret < 0) + return ret; + optlen = sizeof(ret); + if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen)) + ret = AVUNERROR(ff_neterrno()); + if (ret != 0) { + char errbuf[100]; + ret = AVERROR(ret); + av_strerror(ret, errbuf, sizeof(errbuf)); + if (will_try_next) + av_log(h, AV_LOG_WARNING, + "Connection to %s failed (%s), trying next address\n", + h->filename, errbuf); + else + av_log(h, AV_LOG_ERROR, "Connection to %s failed: %s\n", + h->filename, errbuf); + } + default: + return ret; + } + } + return ret; +} + static int match_host_pattern(const char *pattern, const char *hostname) { int len_p, len_h; diff --git a/libavformat/network.h b/libavformat/network.h index f83c796a95a55..2621c495cef24 100644 --- a/libavformat/network.h +++ b/libavformat/network.h @@ -293,6 +293,11 @@ int ff_listen_connect(int fd, const struct sockaddr *addr, socklen_t addrlen, int timeout, URLContext *h, int will_try_next); +int ff_sendto(int fd, const char *msg, int msg_len, int flag, + const struct sockaddr *addr, + socklen_t addrlen, int timeout, URLContext *h, + int will_try_next); + int ff_http_match_no_proxy(const char *no_proxy, const char *hostname); int ff_socket(int domain, int type, int protocol); diff --git a/libavformat/tcp.c b/libavformat/tcp.c index 67d23cebf04dc..d2de7431d1b1d 100644 --- a/libavformat/tcp.c +++ b/libavformat/tcp.c @@ -54,8 +54,14 @@ typedef struct TCPContext { int dns_cache_clear; AVApplicationContext *app_ctx; + char uri[1024]; + int fastopen; + int tcp_connected; + int fastopen_success; } TCPContext; +#define FAST_OPEN_FLAG 0x20000000 + #define OFFSET(x) offsetof(TCPContext, x) #define D AV_OPT_FLAG_DECODING_PARAM #define E AV_OPT_FLAG_ENCODING_PARAM @@ -72,6 +78,7 @@ static const AVOption options[] = { { "addrinfo_timeout", "set timeout (in microseconds) for getaddrinfo()", OFFSET(addrinfo_timeout), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E }, { "dns_cache_timeout", "dns cache TTL (in microseconds)", OFFSET(dns_cache_timeout), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E }, { "dns_cache_clear", "clear dns cache", OFFSET(dns_cache_clear), AV_OPT_TYPE_INT, { .i64 = 0}, -1, INT_MAX, .flags = D|E }, + { "fastopen", "enable fastopen", OFFSET(fastopen), AV_OPT_TYPE_INT, { .i64 = 0}, 0, INT_MAX, .flags = D|E }, { NULL } }; @@ -351,6 +358,12 @@ static int tcp_open(URLContext *h, const char *uri, int flags) s->app_ctx = (AVApplicationContext *)(intptr_t)s->app_ctx_intptr; + if (s->fastopen) { + s->tcp_connected = 0; + strcpy(s->uri, uri); + return 0; + } + av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port, path, sizeof(path), uri); if (strcmp(proto, "tcp")) @@ -523,6 +536,196 @@ static int tcp_open(URLContext *h, const char *uri, int flags) return ret; } +/* return non zero if error */ +static int tcp_fast_open(URLContext *h, const char *http_request, const char *uri, int flags) +{ + struct addrinfo hints = { 0 }, *ai, *cur_ai; + int port, fd = -1; + TCPContext *s = h->priv_data; + const char *p; + char buf[256]; + int ret; + char hostname[1024],proto[1024],path[1024]; + char portstr[10]; + char hostname_bak[1024] = {0}; + AVAppTcpIOControl control = {0}; + DnsCacheEntry *dns_entry = NULL; + av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), + &port, path, sizeof(path), uri); + if (strcmp(proto, "tcp")) + return AVERROR(EINVAL); + if (port <= 0 || port >= 65536) { + av_log(h, AV_LOG_ERROR, "Port missing in uri\n"); + return AVERROR(EINVAL); + } + p = strchr(uri, '?'); + + if (p) { + if (av_find_info_tag(buf, sizeof(buf), "listen", p)) { + char *endptr = NULL; + s->listen = strtol(buf, &endptr, 10); + /* assume if no digits were found it is a request to enable it */ + if (buf == endptr) + s->listen = 1; + } + if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) { + s->rw_timeout = strtol(buf, NULL, 10); + if (s->rw_timeout >= 0) { + s->open_timeout = s->rw_timeout; + } + } + if (av_find_info_tag(buf, sizeof(buf), "listen_timeout", p)) { + s->listen_timeout = strtol(buf, NULL, 10); + } + } + if (s->rw_timeout >= 0 ) { + h->rw_timeout = s->rw_timeout; + } + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + snprintf(portstr, sizeof(portstr), "%d", port); + if (s->listen) + hints.ai_flags |= AI_PASSIVE; + + if (s->dns_cache_timeout > 0) { + memcpy(hostname_bak, hostname, 1024); + if (s->dns_cache_clear) { + av_log(NULL, AV_LOG_INFO, "will delete cache entry, hostname = %s\n", hostname); + remove_dns_cache_entry(hostname); + } else { + dns_entry = get_dns_cache_reference(hostname); + } + } + + if (!dns_entry) { +#ifdef HAVE_PTHREADS + ret = ijk_tcp_getaddrinfo_nonblock(hostname, portstr, &hints, &ai, s->addrinfo_timeout, &h->interrupt_callback, s->addrinfo_one_by_one); +#else + if (s->addrinfo_timeout > 0) + av_log(h, AV_LOG_WARNING, "Ignore addrinfo_timeout without pthreads support.\n"); + if (!hostname[0]) + ret = getaddrinfo(NULL, portstr, &hints, &ai); + else + ret = getaddrinfo(hostname, portstr, &hints, &ai); +#endif + + if (ret) { + av_log(h, AV_LOG_ERROR, + "Failed to resolve hostname %s: %s\n", + hostname, gai_strerror(ret)); + return AVERROR(EIO); + } + + cur_ai = ai; + } else { + av_log(NULL, AV_LOG_INFO, "Hit DNS cache hostname = %s\n", hostname); + cur_ai = dns_entry->res; + } + + 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){ + struct sockaddr_in6 * sockaddr_v6 = (struct sockaddr_in6 *)cur_ai->ai_addr; + if (!sockaddr_v6->sin6_port){ + sockaddr_v6->sin6_port = htons(port); + } + } +#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->listen == 2) { + // multi-client + if ((ret = ff_listen(fd, cur_ai->ai_addr, cur_ai->ai_addrlen)) < 0) + goto fail1; + } else if (s->listen == 1) { + // single client + if ((ret = ff_listen_bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen, + s->listen_timeout, h)) < 0) + goto fail1; + // Socket descriptor already closed here. Safe to overwrite to client one. + fd = ret; + } else { + ret = av_application_on_tcp_will_open(s->app_ctx); + if (ret) { + av_log(NULL, AV_LOG_WARNING, "terminated by application in AVAPP_CTRL_WILL_TCP_OPEN"); + goto fail1; + } + + if ((ret = ff_sendto(fd, http_request, strlen(http_request), FAST_OPEN_FLAG, + cur_ai->ai_addr, cur_ai->ai_addrlen, s->open_timeout / 1000, h, !!cur_ai->ai_next)) < 0) { + s->fastopen_success = 0; + if (av_application_on_tcp_did_open(s->app_ctx, ret, fd, &control)) + goto fail1; + if (ret == AVERROR_EXIT) + goto fail1; + else + goto fail; + } else { + if (ret == 0) { + s->fastopen_success = 0; + } else { + s->fastopen_success = 1; + } + ret = av_application_on_tcp_did_open(s->app_ctx, 0, fd, &control); + if (ret) { + av_log(NULL, AV_LOG_WARNING, "terminated by application in AVAPP_CTRL_DID_TCP_OPEN"); + goto fail1; + } else if (!dns_entry && strcmp(control.ip, hostname_bak)) { + add_dns_cache_entry(hostname_bak, cur_ai, s->dns_cache_timeout); + av_log(NULL, AV_LOG_INFO, "Add dns cache hostname = %s, ip = %s\n", hostname_bak , control.ip); + } + } + } + + h->is_streamed = 1; + s->fd = fd; + + if (dns_entry) { + release_dns_cache_reference(hostname_bak, &dns_entry); + } else { + 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); + + if (dns_entry) { + av_log(NULL, AV_LOG_ERROR, "Hit dns cache but connect fail hostname = %s, ip = %s\n", hostname , control.ip); + release_dns_cache_reference(hostname_bak, &dns_entry); + remove_dns_cache_entry(hostname_bak); + } else { + freeaddrinfo(ai); + } + + return ret; +} + static int tcp_accept(URLContext *s, URLContext **c) { TCPContext *sc = s->priv_data; @@ -565,6 +768,25 @@ static int tcp_write(URLContext *h, const uint8_t *buf, int size) if (ret) return ret; } + + if (s->fastopen && !s->tcp_connected && av_stristart(buf, "GET", NULL)) { + ret = tcp_fast_open(h, buf, s->uri, 0); + if (!ret) { + s->tcp_connected = 1; + if (!s->fastopen_success) { + ret = send(s->fd, buf, size, MSG_NOSIGNAL); + if (ret > 0) { + s->fastopen_success = 1; + } + return ret < 0 ? ff_neterrno() : ret; + } + return ret; + } else { + av_log(NULL, AV_LOG_WARNING, "tcp_fast_open is error ret = %d\n", ret); + return ret; + } + } + ret = send(s->fd, buf, size, MSG_NOSIGNAL); return ret < 0 ? ff_neterrno() : ret; } From 09ee574e845a477a70e2a66ffcc3383f61303927 Mon Sep 17 00:00:00 2001 From: wuzhiqiang Date: Wed, 3 Jan 2018 15:44:20 +0800 Subject: [PATCH 3370/3374] avformat/hls: fix seek accuracy problem --- libavformat/hls.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index 5b8f3215a796b..4b2755ae6c8d3 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -1951,6 +1951,7 @@ static int hls_read_packet(AVFormatContext *s, AVPacket *pkt) * stream */ if (pls->needed && !pls->pkt.data) { while (1) { + int64_t pkt_ts; int64_t ts_diff; AVRational tb; ret = av_read_frame(pls->ctx, &pls->pkt); @@ -1966,9 +1967,17 @@ static int hls_read_packet(AVFormatContext *s, AVPacket *pkt) fill_timing_for_id3_timestamped_stream(pls); } + if (pls->pkt.pts != AV_NOPTS_VALUE) + pkt_ts = pls->pkt.pts; + else if (pls->pkt.dts != AV_NOPTS_VALUE) + pkt_ts = pls->pkt.dts; + else + pkt_ts = AV_NOPTS_VALUE; + + if (c->first_timestamp == AV_NOPTS_VALUE && - pls->pkt.dts != AV_NOPTS_VALUE) - c->first_timestamp = av_rescale_q(pls->pkt.dts, + pkt_ts != AV_NOPTS_VALUE) + c->first_timestamp = av_rescale_q(pkt_ts, get_timebase(pls), AV_TIME_BASE_Q); } @@ -1978,15 +1987,16 @@ static int hls_read_packet(AVFormatContext *s, AVPacket *pkt) if (pls->seek_stream_index < 0 || pls->seek_stream_index == pls->pkt.stream_index) { - if (pls->pkt.dts == AV_NOPTS_VALUE) { + if (pkt_ts == AV_NOPTS_VALUE) { pls->seek_timestamp = AV_NOPTS_VALUE; break; } tb = get_timebase(pls); - ts_diff = av_rescale_rnd(pls->pkt.dts, AV_TIME_BASE, + ts_diff = av_rescale_rnd(pkt_ts, AV_TIME_BASE, tb.den, AV_ROUND_DOWN) - pls->seek_timestamp; + if (ts_diff >= 0 && (pls->seek_flags & AVSEEK_FLAG_ANY || pls->pkt.flags & AV_PKT_FLAG_KEY)) { pls->seek_timestamp = AV_NOPTS_VALUE; From 8504453ea28d2a417e374b0b8bb445eede618dbe Mon Sep 17 00:00:00 2001 From: wuzhiqiang Date: Wed, 3 Jan 2018 15:44:58 +0800 Subject: [PATCH 3371/3374] avformat/hls: fix seek to start time error --- libavformat/hls.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index 4b2755ae6c8d3..0e07a811a5098 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -1975,10 +1975,8 @@ static int hls_read_packet(AVFormatContext *s, AVPacket *pkt) pkt_ts = AV_NOPTS_VALUE; - if (c->first_timestamp == AV_NOPTS_VALUE && - pkt_ts != AV_NOPTS_VALUE) - c->first_timestamp = av_rescale_q(pkt_ts, - get_timebase(pls), AV_TIME_BASE_Q); + c->first_timestamp = s->start_time != AV_NOPTS_VALUE ? s->start_time : 0; + } if (pls->seek_timestamp == AV_NOPTS_VALUE) From 023d5d2e1c4563a3a701622fbbd76eb793f898e6 Mon Sep 17 00:00:00 2001 From: wuzhiqiang Date: Tue, 2 Jan 2018 10:39:33 +0800 Subject: [PATCH 3372/3374] avformat/concat: disable concat wrap control --- libavformat/concatdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c index 41a46ef9a93c6..aab81a37217b9 100644 --- a/libavformat/concatdec.c +++ b/libavformat/concatdec.c @@ -187,8 +187,8 @@ static int copy_stream_props(AVStream *st, AVStream *source_st) return ret; st->r_frame_rate = source_st->r_frame_rate; st->avg_frame_rate = source_st->avg_frame_rate; - st->time_base = source_st->time_base; st->sample_aspect_ratio = source_st->sample_aspect_ratio; + avpriv_set_pts_info(st, 64, source_st->time_base.num, source_st->time_base.den); av_dict_copy(&st->metadata, source_st->metadata, 0); return 0; From 2902e33f6e59ed77ddc1b372586c1ab8db1fb096 Mon Sep 17 00:00:00 2001 From: raymondzheng Date: Wed, 3 Jan 2018 17:39:13 +0800 Subject: [PATCH 3373/3374] avformat/http: add filesize report --- libavformat/http.c | 2 +- libavutil/application.c | 3 ++- libavutil/application.h | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libavformat/http.c b/libavformat/http.c index 4adac485b883a..05c8b9ba8fb40 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -532,7 +532,7 @@ static int http_open(URLContext *h, const char *uri, int flags, } av_application_will_http_open(s->app_ctx, (void*)h, uri); ret = http_open_cnx(h, options); - av_application_did_http_open(s->app_ctx, (void*)h, uri, ret, s->http_code); + av_application_did_http_open(s->app_ctx, (void*)h, uri, ret, s->http_code, s->filesize); if (ret < 0) av_dict_free(&s->chained_options); return ret; diff --git a/libavutil/application.c b/libavutil/application.c index 3a4ec85071815..99751876bd631 100644 --- a/libavutil/application.c +++ b/libavutil/application.c @@ -80,7 +80,7 @@ void av_application_will_http_open(AVApplicationContext *h, void *obj, const cha av_application_on_http_event(h, AVAPP_EVENT_WILL_HTTP_OPEN, &event); } -void av_application_did_http_open(AVApplicationContext *h, void *obj, const char *url, int error, int http_code) +void av_application_did_http_open(AVApplicationContext *h, void *obj, const char *url, int error, int http_code, int64_t filesize) { AVAppHttpEvent event = {0}; @@ -91,6 +91,7 @@ void av_application_did_http_open(AVApplicationContext *h, void *obj, const char av_strlcpy(event.url, url, sizeof(event.url)); event.error = error; event.http_code = http_code; + event.filesize = filesize; av_application_on_http_event(h, AVAPP_EVENT_DID_HTTP_OPEN, &event); } diff --git a/libavutil/application.h b/libavutil/application.h index 9e2c1f5b1aadb..72fe902789913 100644 --- a/libavutil/application.h +++ b/libavutil/application.h @@ -79,6 +79,7 @@ typedef struct AVAppHttpEvent int64_t offset; int error; int http_code; + int64_t filesize; } AVAppHttpEvent; typedef struct AVAppIOTraffic @@ -102,7 +103,7 @@ void av_application_closep(AVApplicationContext **ph); void av_application_on_http_event(AVApplicationContext *h, int event_type, AVAppHttpEvent *event); void av_application_will_http_open(AVApplicationContext *h, void *obj, const char *url); -void av_application_did_http_open(AVApplicationContext *h, void *obj, const char *url, int error, int http_code); +void av_application_did_http_open(AVApplicationContext *h, void *obj, const char *url, int error, int http_code, int64_t filesize); void av_application_will_http_seek(AVApplicationContext *h, void *obj, const char *url, int64_t offset); void av_application_did_http_seek(AVApplicationContext *h, void *obj, const char *url, int64_t offset, int error, int http_code); From ddd2a64c00e08d029055b0ca346adf24d9d7fb3f Mon Sep 17 00:00:00 2001 From: yangdan07 Date: Thu, 3 Sep 2020 17:23:34 +0800 Subject: [PATCH 3374/3374] feat(libavformat/makefile): add the ffmpeg interface for las demo --- libavformat/Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavformat/Makefile b/libavformat/Makefile index fd3f2d06789d8..83b1853c53109 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -7,6 +7,11 @@ HEADERS = avformat.h \ avc.h \ url.h \ internal.h \ + avio_internal.h \ + flv.h \ + id3v2.h \ + os_support.h \ + metadata.h \ OBJS = allformats.o \ avio.o \